mirror of
https://github.com/Azgaar/Fantasy-Map-Generator.git
synced 2026-02-04 17:41:23 +01:00
refactor: Migrate lakes functionality to lakes.ts and update related interfaces
This commit is contained in:
parent
49e7e5c533
commit
371c775578
8 changed files with 136 additions and 110 deletions
|
|
@ -8469,7 +8469,6 @@
|
||||||
|
|
||||||
<script defer src="config/heightmap-templates.js"></script>
|
<script defer src="config/heightmap-templates.js"></script>
|
||||||
<script defer src="config/precreated-heightmaps.js"></script>
|
<script defer src="config/precreated-heightmaps.js"></script>
|
||||||
<script defer src="modules/lakes.js?v=1.99.00"></script>
|
|
||||||
<script defer src="modules/names-generator.js?v=1.106.0"></script>
|
<script defer src="modules/names-generator.js?v=1.106.0"></script>
|
||||||
<script defer src="modules/cultures-generator.js?v=1.106.0"></script>
|
<script defer src="modules/cultures-generator.js?v=1.106.0"></script>
|
||||||
<script defer src="modules/burgs-generator.js?v=1.109.5"></script>
|
<script defer src="modules/burgs-generator.js?v=1.109.5"></script>
|
||||||
|
|
|
||||||
|
|
@ -1,22 +1,27 @@
|
||||||
import { PackedGraphFeature } from "./features";
|
import { PackedGraphFeature } from "./features";
|
||||||
import { River } from "./river-generator";
|
import { River } from "./river-generator";
|
||||||
|
|
||||||
|
|
||||||
|
type TypedArray = Uint8Array | Uint16Array | Uint32Array | Int8Array | Int16Array | Float32Array | Float64Array;
|
||||||
|
|
||||||
export interface PackedGraph {
|
export interface PackedGraph {
|
||||||
cells: {
|
cells: {
|
||||||
i: number[]; // cell indices
|
i: number[]; // cell indices
|
||||||
c: number[][]; // neighboring cells
|
c: number[][]; // neighboring cells
|
||||||
v: number[][]; // neighboring vertices
|
v: number[][]; // neighboring vertices
|
||||||
|
p: [number, number][]; // cell polygon points
|
||||||
b: boolean[]; // cell is on border
|
b: boolean[]; // cell is on border
|
||||||
h: Uint8Array; // cell heights
|
h: TypedArray; // cell heights
|
||||||
t: Uint8Array; // cell terrain types
|
t: TypedArray; // cell terrain types
|
||||||
r: Uint16Array; // river id passing through cell
|
r: Uint16Array; // river id passing through cell
|
||||||
f: Uint16Array; // feature id occupying cell
|
f: Uint16Array; // feature id occupying cell
|
||||||
fl: Uint16Array | Uint8Array; // flux presence in cell
|
fl: TypedArray; // flux presence in cell
|
||||||
conf: Uint16Array | Uint8Array; // cell water confidence
|
conf: TypedArray; // cell water confidence
|
||||||
haven: Uint8Array; // cell is a haven
|
haven: TypedArray; // cell is a haven
|
||||||
g: number[]; // cell ground type
|
g: number[]; // cell ground type
|
||||||
culture: number[]; // cell culture id
|
culture: number[]; // cell culture id
|
||||||
p: [number, number][]; // cell polygon points
|
biome: TypedArray; // cell biome id
|
||||||
|
harbor: TypedArray; // cell harbour presence
|
||||||
};
|
};
|
||||||
vertices: {
|
vertices: {
|
||||||
i: number[]; // vertex indices
|
i: number[]; // vertex indices
|
||||||
|
|
@ -24,6 +29,7 @@ export interface PackedGraph {
|
||||||
v: number[][]; // neighboring vertices
|
v: number[][]; // neighboring vertices
|
||||||
x: number[]; // x coordinates
|
x: number[]; // x coordinates
|
||||||
y: number[]; // y coordinates
|
y: number[]; // y coordinates
|
||||||
|
p: [number, number][]; // vertex points
|
||||||
};
|
};
|
||||||
rivers: River[];
|
rivers: River[];
|
||||||
features: PackedGraphFeature[];
|
features: PackedGraphFeature[];
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,11 @@
|
||||||
import { range, mean } from "d3";
|
import { range, mean } from "d3";
|
||||||
import { rn } from "../utils";
|
import { rn } from "../utils";
|
||||||
|
import { PackedGraph } from "./PackedGraph";
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
var Biomes: BiomesModule;
|
var Biomes: BiomesModule;
|
||||||
|
|
||||||
var pack: any;
|
var pack: PackedGraph;
|
||||||
var grid: any;
|
var grid: any;
|
||||||
var TIME: boolean;
|
var TIME: boolean;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,15 +1,17 @@
|
||||||
import { clipPoly, connectVertices, createTypedArray, distanceSquared, isLand, isWater, rn, TYPED_ARRAY_MAX_VALUES,unique } from "../utils";
|
import { clipPoly, connectVertices, createTypedArray, distanceSquared, isLand, isWater, rn, TYPED_ARRAY_MAX_VALUES,unique } from "../utils";
|
||||||
import Alea from "alea";
|
import Alea from "alea";
|
||||||
import { polygonArea } from "d3";
|
import { polygonArea } from "d3";
|
||||||
|
import { LakesModule } from "./lakes";
|
||||||
|
import { PackedGraph } from "./PackedGraph";
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
interface Window {
|
interface Window {
|
||||||
Features: any;
|
Features: any;
|
||||||
}
|
}
|
||||||
var TIME: boolean;
|
var TIME: boolean;
|
||||||
var Lakes: any;
|
var Lakes: LakesModule;
|
||||||
var grid: any;
|
var grid: any;
|
||||||
var pack: any;
|
var pack: PackedGraph;
|
||||||
var seed: string;
|
var seed: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -30,11 +32,15 @@ export interface PackedGraphFeature {
|
||||||
temp: number;
|
temp: number;
|
||||||
flux: number;
|
flux: number;
|
||||||
evaporation: number;
|
evaporation: number;
|
||||||
inlets: number[];
|
name: string;
|
||||||
outlet: number;
|
|
||||||
river: number;
|
// River related
|
||||||
enteringFlux: number;
|
inlets?: number[];
|
||||||
closed: boolean;
|
outlet?: number;
|
||||||
|
river?: number;
|
||||||
|
enteringFlux?: number;
|
||||||
|
closed?: boolean;
|
||||||
|
outCell?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface GridFeature {
|
export interface GridFeature {
|
||||||
|
|
@ -210,7 +216,7 @@ class FeatureModule {
|
||||||
if (type === "lake") {
|
if (type === "lake") {
|
||||||
if (area > 0) feature.vertices = (feature.vertices as number[]).reverse();
|
if (area > 0) feature.vertices = (feature.vertices as number[]).reverse();
|
||||||
feature.shoreline = unique((feature.vertices as number[]).map(vertex => vertices.c[vertex].filter((index: number) => isLand(index, this.packedGraph))).flat() || []);
|
feature.shoreline = unique((feature.vertices as number[]).map(vertex => vertices.c[vertex].filter((index: number) => isLand(index, this.packedGraph))).flat() || []);
|
||||||
feature.height = Lakes.getHeight(feature);
|
feature.height = Lakes.getHeight(feature as PackedGraphFeature);
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|
@ -278,7 +284,7 @@ class FeatureModule {
|
||||||
this.packedGraph.cells.f = featureIds;
|
this.packedGraph.cells.f = featureIds;
|
||||||
this.packedGraph.cells.haven = haven;
|
this.packedGraph.cells.haven = haven;
|
||||||
this.packedGraph.cells.harbor = harbor;
|
this.packedGraph.cells.harbor = harbor;
|
||||||
this.packedGraph.features = [0, ...features];
|
this.packedGraph.features = [0 as unknown as PackedGraphFeature, ...features];
|
||||||
|
|
||||||
TIME && console.timeEnd("markupPack");
|
TIME && console.timeEnd("markupPack");
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
import "./voronoi";
|
import "./voronoi";
|
||||||
import "./heightmap-generator";
|
import "./heightmap-generator";
|
||||||
import "./features";
|
import "./features";
|
||||||
|
import "./lakes";
|
||||||
import "./ocean-layers";
|
import "./ocean-layers";
|
||||||
import "./river-generator";
|
import "./river-generator";
|
||||||
import "./biomes"
|
import "./biomes"
|
||||||
|
|
@ -1,12 +1,98 @@
|
||||||
"use strict";
|
import { PackedGraphFeature } from "./features";
|
||||||
|
import { min, mean } from "d3";
|
||||||
|
import { byId,
|
||||||
|
rn } from "../utils";
|
||||||
|
import { PackedGraph } from "./PackedGraph";
|
||||||
|
|
||||||
window.Lakes = (function () {
|
declare global {
|
||||||
const LAKE_ELEVATION_DELTA = 0.1;
|
var Lakes: LakesModule;
|
||||||
|
var pack: PackedGraph;
|
||||||
|
var Names: any;
|
||||||
|
|
||||||
|
var heightExponentInput: HTMLInputElement;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class LakesModule {
|
||||||
|
private LAKE_ELEVATION_DELTA = 0.1;
|
||||||
|
|
||||||
|
getHeight(feature: PackedGraphFeature) {
|
||||||
|
const heights = pack.cells.h;
|
||||||
|
const minShoreHeight = min(feature.shoreline.map(cellId => heights[cellId])) || 20;
|
||||||
|
return rn(minShoreHeight - this.LAKE_ELEVATION_DELTA, 2);
|
||||||
|
};
|
||||||
|
|
||||||
|
defineNames() {
|
||||||
|
pack.features.forEach((feature: PackedGraphFeature) => {
|
||||||
|
if (feature.type !== "lake") return;
|
||||||
|
feature.name = this.getName(feature);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
getName(feature: PackedGraphFeature): string {
|
||||||
|
const landCell = feature.shoreline[0];
|
||||||
|
const culture = pack.cells.culture[landCell];
|
||||||
|
return Names.getCulture(culture);
|
||||||
|
};
|
||||||
|
|
||||||
|
cleanupLakeData = function () {
|
||||||
|
for (const feature of pack.features) {
|
||||||
|
if (feature.type !== "lake") continue;
|
||||||
|
delete feature.river;
|
||||||
|
delete feature.enteringFlux;
|
||||||
|
delete feature.outCell;
|
||||||
|
delete feature.closed;
|
||||||
|
feature.height = rn(feature.height, 3);
|
||||||
|
|
||||||
|
const inlets = feature.inlets?.filter(r => pack.rivers.find(river => river.i === r));
|
||||||
|
if (!inlets || !inlets.length) delete feature.inlets;
|
||||||
|
else feature.inlets = inlets;
|
||||||
|
|
||||||
|
const outlet = feature.outlet && pack.rivers.find(river => river.i === feature.outlet);
|
||||||
|
if (!outlet) delete feature.outlet;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
defineClimateData(heights: Uint8Array) {
|
||||||
|
const {cells, features} = pack;
|
||||||
|
const lakeOutCells = new Uint16Array(cells.i.length);
|
||||||
|
|
||||||
|
const getFlux = (lake: PackedGraphFeature) => {
|
||||||
|
return lake.shoreline.reduce((acc, c) => acc + grid.cells.prec[cells.g[c]], 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
const getLakeTemp = (lake: PackedGraphFeature) => {
|
||||||
|
if (lake.cells < 6) return grid.cells.temp[cells.g[lake.firstCell]];
|
||||||
|
return rn(mean(lake.shoreline.map(c => grid.cells.temp[cells.g[c]])) as number, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
const getLakeEvaporation = (lake: PackedGraphFeature) => {
|
||||||
|
const height = (lake.height - 18) ** Number(heightExponentInput.value); // height in meters
|
||||||
|
const evaporation = ((700 * (lake.temp + 0.006 * height)) / 50 + 75) / (80 - lake.temp); // based on Penman formula, [1-11]
|
||||||
|
return rn(evaporation * lake.cells);
|
||||||
|
}
|
||||||
|
|
||||||
|
const getLowestShoreCell = (lake: PackedGraphFeature) => {
|
||||||
|
return lake.shoreline.sort((a, b) => heights[a] - heights[b])[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
features.forEach(feature => {
|
||||||
|
if (feature.type !== "lake") return;
|
||||||
|
feature.flux = getFlux(feature);
|
||||||
|
feature.temp = getLakeTemp(feature);
|
||||||
|
feature.evaporation = getLakeEvaporation(feature);
|
||||||
|
if (feature.closed) return; // no outlet for lakes in depressed areas
|
||||||
|
|
||||||
|
feature.outCell = getLowestShoreCell(feature);
|
||||||
|
lakeOutCells[feature.outCell as number] = feature.i;
|
||||||
|
});
|
||||||
|
|
||||||
|
return lakeOutCells;
|
||||||
|
};
|
||||||
|
|
||||||
// check if lake can be potentially open (not in deep depression)
|
// check if lake can be potentially open (not in deep depression)
|
||||||
const detectCloseLakes = h => {
|
detectCloseLakes(h: Uint8Array) {
|
||||||
const {cells} = pack;
|
const {cells} = pack;
|
||||||
const ELEVATION_LIMIT = +byId("lakeElevationLimitOutput").value;
|
const ELEVATION_LIMIT = +(byId("lakeElevationLimitOutput") as HTMLInputElement)?.value;
|
||||||
|
|
||||||
pack.features.forEach(feature => {
|
pack.features.forEach(feature => {
|
||||||
if (feature.type !== "lake") return;
|
if (feature.type !== "lake") return;
|
||||||
|
|
@ -25,7 +111,7 @@ window.Lakes = (function () {
|
||||||
checked[lowestShorelineCell] = true;
|
checked[lowestShorelineCell] = true;
|
||||||
|
|
||||||
while (queue.length && isDeep) {
|
while (queue.length && isDeep) {
|
||||||
const cellId = queue.pop();
|
const cellId: number = queue.pop() as number;
|
||||||
|
|
||||||
for (const neibCellId of cells.c[cellId]) {
|
for (const neibCellId of cells.c[cellId]) {
|
||||||
if (checked[neibCellId]) continue;
|
if (checked[neibCellId]) continue;
|
||||||
|
|
@ -44,80 +130,6 @@ window.Lakes = (function () {
|
||||||
feature.closed = isDeep;
|
feature.closed = isDeep;
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
}
|
||||||
|
|
||||||
const defineClimateData = function (heights) {
|
window.Lakes = new LakesModule();
|
||||||
const {cells, features} = pack;
|
|
||||||
const lakeOutCells = new Uint16Array(cells.i.length);
|
|
||||||
|
|
||||||
features.forEach(feature => {
|
|
||||||
if (feature.type !== "lake") return;
|
|
||||||
feature.flux = getFlux(feature);
|
|
||||||
feature.temp = getLakeTemp(feature);
|
|
||||||
feature.evaporation = getLakeEvaporation(feature);
|
|
||||||
if (feature.closed) return; // no outlet for lakes in depressed areas
|
|
||||||
|
|
||||||
feature.outCell = getLowestShoreCell(feature);
|
|
||||||
lakeOutCells[feature.outCell] = feature.i;
|
|
||||||
});
|
|
||||||
|
|
||||||
return lakeOutCells;
|
|
||||||
|
|
||||||
function getFlux(lake) {
|
|
||||||
return lake.shoreline.reduce((acc, c) => acc + grid.cells.prec[cells.g[c]], 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
function getLakeTemp(lake) {
|
|
||||||
if (lake.cells < 6) return grid.cells.temp[cells.g[lake.firstCell]];
|
|
||||||
return rn(d3.mean(lake.shoreline.map(c => grid.cells.temp[cells.g[c]])), 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
function getLakeEvaporation(lake) {
|
|
||||||
const height = (lake.height - 18) ** heightExponentInput.value; // height in meters
|
|
||||||
const evaporation = ((700 * (lake.temp + 0.006 * height)) / 50 + 75) / (80 - lake.temp); // based on Penman formula, [1-11]
|
|
||||||
return rn(evaporation * lake.cells);
|
|
||||||
}
|
|
||||||
|
|
||||||
function getLowestShoreCell(lake) {
|
|
||||||
return lake.shoreline.sort((a, b) => heights[a] - heights[b])[0];
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const cleanupLakeData = function () {
|
|
||||||
for (const feature of pack.features) {
|
|
||||||
if (feature.type !== "lake") continue;
|
|
||||||
delete feature.river;
|
|
||||||
delete feature.enteringFlux;
|
|
||||||
delete feature.outCell;
|
|
||||||
delete feature.closed;
|
|
||||||
feature.height = rn(feature.height, 3);
|
|
||||||
|
|
||||||
const inlets = feature.inlets?.filter(r => pack.rivers.find(river => river.i === r));
|
|
||||||
if (!inlets || !inlets.length) delete feature.inlets;
|
|
||||||
else feature.inlets = inlets;
|
|
||||||
|
|
||||||
const outlet = feature.outlet && pack.rivers.find(river => river.i === feature.outlet);
|
|
||||||
if (!outlet) delete feature.outlet;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const getHeight = function (feature) {
|
|
||||||
const heights = pack.cells.h;
|
|
||||||
const minShoreHeight = d3.min(feature.shoreline.map(cellId => heights[cellId])) || 20;
|
|
||||||
return rn(minShoreHeight - LAKE_ELEVATION_DELTA, 2);
|
|
||||||
};
|
|
||||||
|
|
||||||
const defineNames = function () {
|
|
||||||
pack.features.forEach(feature => {
|
|
||||||
if (feature.type !== "lake") return;
|
|
||||||
feature.name = getName(feature);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const getName = function (feature) {
|
|
||||||
const landCell = feature.shoreline[0];
|
|
||||||
const culture = pack.cells.culture[landCell];
|
|
||||||
return Names.getCulture(culture);
|
|
||||||
};
|
|
||||||
|
|
||||||
return {defineClimateData, cleanupLakeData, detectCloseLakes, getHeight, defineNames, getName};
|
|
||||||
})();
|
|
||||||
|
|
@ -7,6 +7,7 @@ rn,round,
|
||||||
rw} from "../utils";
|
rw} from "../utils";
|
||||||
import { PackedGraphFeature } from "./features";
|
import { PackedGraphFeature } from "./features";
|
||||||
import { PackedGraph } from "./PackedGraph";
|
import { PackedGraph } from "./PackedGraph";
|
||||||
|
import { LakesModule } from "./lakes";
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
interface Window {
|
interface Window {
|
||||||
|
|
@ -16,7 +17,7 @@ declare global {
|
||||||
var WARN: boolean;
|
var WARN: boolean;
|
||||||
var graphHeight: number;
|
var graphHeight: number;
|
||||||
var graphWidth: number;
|
var graphWidth: number;
|
||||||
var pack: any;
|
var pack: PackedGraph;
|
||||||
|
|
||||||
var rivers: Selection<SVGElement, unknown, null, undefined>;
|
var rivers: Selection<SVGElement, unknown, null, undefined>;
|
||||||
var pointsInput: HTMLInputElement;
|
var pointsInput: HTMLInputElement;
|
||||||
|
|
@ -25,7 +26,7 @@ declare global {
|
||||||
var TIME: boolean;
|
var TIME: boolean;
|
||||||
|
|
||||||
var Names: any;
|
var Names: any;
|
||||||
var Lakes: any;
|
var Lakes: LakesModule;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface River {
|
export interface River {
|
||||||
|
|
@ -114,8 +115,8 @@ class RiverModule {
|
||||||
const sameRiver = cells.c[lakeCell].some((c: number) => cells.r[c] === lake.river);
|
const sameRiver = cells.c[lakeCell].some((c: number) => cells.r[c] === lake.river);
|
||||||
|
|
||||||
if (sameRiver) {
|
if (sameRiver) {
|
||||||
cells.r[lakeCell] = lake.river;
|
cells.r[lakeCell] = lake.river as number;
|
||||||
addCellToRiver(lakeCell, lake.river);
|
addCellToRiver(lakeCell, lake.river as number);
|
||||||
} else {
|
} else {
|
||||||
cells.r[lakeCell] = riverNext;
|
cells.r[lakeCell] = riverNext;
|
||||||
addCellToRiver(lakeCell, riverNext);
|
addCellToRiver(lakeCell, riverNext);
|
||||||
|
|
@ -132,7 +133,7 @@ class RiverModule {
|
||||||
for (const lake of lakes) {
|
for (const lake of lakes) {
|
||||||
if (!Array.isArray(lake.inlets)) continue;
|
if (!Array.isArray(lake.inlets)) continue;
|
||||||
for (const inlet of lake.inlets) {
|
for (const inlet of lake.inlets) {
|
||||||
riverParents[inlet] = outlet;
|
riverParents[inlet] = outlet as number;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -199,7 +200,7 @@ class RiverModule {
|
||||||
// pour water to the water body
|
// pour water to the water body
|
||||||
const waterBody = features[cells.f[toCell]];
|
const waterBody = features[cells.f[toCell]];
|
||||||
if (waterBody.type === "lake") {
|
if (waterBody.type === "lake") {
|
||||||
if (!waterBody.river || fromFlux > waterBody.enteringFlux) {
|
if (!waterBody.river || fromFlux > (waterBody.enteringFlux as number)) {
|
||||||
waterBody.river = river;
|
waterBody.river = river;
|
||||||
waterBody.enteringFlux = fromFlux;
|
waterBody.enteringFlux = fromFlux;
|
||||||
}
|
}
|
||||||
|
|
@ -320,16 +321,16 @@ class RiverModule {
|
||||||
TIME && console.timeEnd("generateRivers");
|
TIME && console.timeEnd("generateRivers");
|
||||||
};
|
};
|
||||||
|
|
||||||
alterHeights() {
|
alterHeights(): Uint8Array {
|
||||||
const {h, c, t} = this.pack.cells as {h: Uint8Array, c: number[][], t: Uint8Array};
|
const {h, c, t} = this.pack.cells as {h: Uint8Array, c: number[][], t: Uint8Array};
|
||||||
return Array.from(h).map((h, i) => {
|
return Uint8Array.from(Array.from(h).map((h, i) => {
|
||||||
if (h < 20 || t[i] < 1) return h;
|
if (h < 20 || t[i] < 1) return h;
|
||||||
return h + t[i] / 100 + (mean(c[i].map(c => t[c])) || 0) / 10000;
|
return h + t[i] / 100 + (mean(c[i].map(c => t[c])) || 0) / 10000;
|
||||||
});
|
}));
|
||||||
};
|
};
|
||||||
|
|
||||||
// depression filling algorithm (for a correct water flux modeling)
|
// depression filling algorithm (for a correct water flux modeling)
|
||||||
resolveDepressions(h: number[]) {
|
resolveDepressions(h: Uint8Array) {
|
||||||
const {cells, features} = this.pack;
|
const {cells, features} = this.pack;
|
||||||
const maxIterations = +(document.getElementById("resolveDepressionsStepsOutput") as HTMLInputElement)?.value;
|
const maxIterations = +(document.getElementById("resolveDepressionsStepsOutput") as HTMLInputElement)?.value;
|
||||||
const checkLakeMaxIteration = maxIterations * 0.85;
|
const checkLakeMaxIteration = maxIterations * 0.85;
|
||||||
|
|
|
||||||
|
|
@ -44,7 +44,7 @@ declare global {
|
||||||
}
|
}
|
||||||
|
|
||||||
interface Array<T> {
|
interface Array<T> {
|
||||||
flat(depth?: number): T[];
|
flat(depth?: number): T;
|
||||||
at(index: number): T | undefined;
|
at(index: number): T | undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue