@noaa-gsl/wizard-graphics 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wizard-graphics.umd.js","names":["swap","intersects","createNode","pointInTriangle","u","bc","ca","ab","bct","cat","abt","u","_8","_8b","_16","fin","fin2","bc","ab","_8","_16","_48","fin","swap"],"sources":["../src/utilities/graphicsUtilities.js","../../node_modules/quickselect/index.js","../../node_modules/rbush/index.js","../src/utilities/deckUtilities.js","../src/layers/contourLayer/contourLabels.js","../src/maps/legend/legendHelperFunctions.js","../src/layers/pathLayer/vertex.js","../src/layers/pathLayer/WizardPathLayer.js","../node_modules/earcut/src/earcut.js","../../node_modules/robust-predicates/esm/util.js","../../node_modules/robust-predicates/esm/orient2d.js","../../node_modules/robust-predicates/esm/orient3d.js","../../node_modules/robust-predicates/esm/incircle.js","../../node_modules/robust-predicates/esm/insphere.js","../../node_modules/delaunator/index.js","../src/layers/shadedLayer/TriangulateGrid.js","../src/layers/contourLayer/triangleContours.js","../src/layers/contourLayer/raster-marching-squares.js","../src/layers/contourLayer/contourLayer.js","../src/layers/shadedLayer/polygon.ts","../src/layers/shadedLayer/polygon-tesselator.ts","../src/layers/shadedLayer/solid-polygon-layer-uniforms.ts","../src/layers/shadedLayer/solid-polygon-layer-vertex-main.glsl.ts","../src/layers/shadedLayer/solid-polygon-layer-vertex-top.glsl.ts","../src/layers/shadedLayer/solid-polygon-layer-vertex-side.glsl.ts","../src/layers/shadedLayer/solid-polygon-layer-fragment.glsl.ts","../src/layers/shadedLayer/solid-polygon-layer.ts","../src/layers/vectorLayer/barbs-new.png?url","../src/layers/vectorLayer/vectorLayer.js","../src/layers/particleLayer/particle-layer-update-transform.vs.glsl.js","../src/layers/particleLayer/particle-layer.ts","../../node_modules/kdbush/index.js","../../node_modules/supercluster/index.js","../src/layers/iconClusterLayer/iconClusterLayer.ts","../src/layers/citiesLayer/computeProgressiveDisclosure.js","../src/layers/citiesLayer/citiesLayer.js","../src/layers/geojsonLayer/sub-layer-map.ts","../src/layers/geojsonLayer/geojson-layer.ts","../src/layers/canned/spotLayer.jsx","../src/layers/canned/icons/FireIcon.svg","../src/layers/canned/nifcLayer.jsx","../src/layers/canned/cpcLayer.jsx","../src/layers/canned/spcLayer.jsx","../src/layers/canned/wpcLayer.jsx","../src/layers/canned/wwaLayer.jsx","../src/maps/custom-maps/darkGray.json","../src/maps/custom-maps/lightGray.json","../src/maps/maps.js","../src/maps/deckGLOverlay.jsx","../src/maps/readout/Readout.jsx","../src/maps/readout/readoutFunctions.js","../src/maps/legend/LegendDynamicItems.jsx","../src/maps/legend/LegendStaticItems.jsx","../src/maps/legend/LegendStaticBar.jsx","../src/maps/legend/Legend.jsx","../src/utilities/Projection.js","../src/conf/configFieldsDefault.js","../src/conf/configFields.json","../src/conf/index.js"],"sourcesContent":["const weekdaynames = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];\nexport const weekdaynamesshort = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];\nconst monthnames = [\n 'January',\n 'February',\n 'March',\n 'April',\n 'May',\n 'June',\n 'July',\n 'August',\n 'September',\n 'October',\n 'November',\n 'December',\n];\nconst monthnamesshort = [\n 'Jan',\n 'Feb',\n 'Mar',\n 'Apr',\n 'May',\n 'Jun',\n 'Jul',\n 'Aug',\n 'Sep',\n 'Oct',\n 'Nov',\n 'Dec',\n];\n\nexport default class gUtilities {\n static ijToIdx(i, j, width, height, size = 1) {\n if (i < 0 || i >= width || j < 0 || j >= height) return NaN;\n return (j * width + i) * size;\n }\n\n static ijkToIdx(i, j, k, width, height) {\n return k * (width * height) + j * width + i;\n }\n\n static uvToDirection(u, v) {\n return 180 + (180 / Math.PI) * Math.atan2(u, v);\n }\n\n static uvToMagnitude(u, v) {\n return Math.sqrt(u * u + v * v);\n }\n\n static DirectionToUV(dir, mag) {\n const rad = (dir * Math.PI) / 180;\n const u = -mag * Math.sin(rad);\n const v = -mag * Math.cos(rad);\n return [u, v];\n }\n\n static getreadoutvalue(lat, lon, proj, data, units, interpolate = true) {\n const [i, j] = proj.LonLatToij(lon, lat, false, true);\n\n // Get floor/ceil points\n const iFloor = Math.floor(i);\n const iCeiling = Math.ceil(i);\n const jFloor = Math.floor(j);\n const jCeiling = Math.ceil(j);\n\n // Get weights\n const iWeight = 1 - (i - iFloor);\n const iWeight2 = 1 - iWeight;\n const jWeight = 1 - (j - jFloor);\n const jWeight2 = 1 - jWeight;\n\n // Get data points\n // p3-----p4\n // |------|\n // p1-----p2\n const dims = [proj.lonlatGrid.length, proj.lonlatGrid[0].length];\n const p1 = data?.[gUtilities.ijToIdx(iFloor, jCeiling, dims[1], dims[0])];\n const p2 = data?.[gUtilities.ijToIdx(iCeiling, jCeiling, dims[1], dims[0])];\n const p3 = data?.[gUtilities.ijToIdx(iFloor, jFloor, dims[1], dims[0])];\n const p4 = data?.[gUtilities.ijToIdx(iCeiling, jFloor, dims[1], dims[0])];\n\n function interpolateData(point1, point2, point3, point4) {\n let value;\n const values = [point3, point1, point4, point2];\n if (interpolate) {\n value =\n point3 * iWeight * jWeight +\n point1 * iWeight * jWeight2 +\n point4 * iWeight2 * jWeight +\n point2 * iWeight2 * jWeight2;\n } else {\n const weights = [\n iWeight * jWeight,\n iWeight * jWeight2,\n iWeight2 * jWeight,\n iWeight2 * jWeight2,\n ];\n const max = Math.max(...weights);\n const index = weights.indexOf(max);\n value = values[index];\n }\n\n // Check for missing value or NaN\n value = values.some((val) => Number.isNaN(val)) ? NaN : value;\n\n return value;\n }\n\n let value;\n if (units === '°') {\n const [p1u, p1v] = this.DirectionToUV(p1, 1);\n const [p2u, p2v] = this.DirectionToUV(p2, 1);\n const [p3u, p3v] = this.DirectionToUV(p3, 1);\n const [p4u, p4v] = this.DirectionToUV(p4, 1);\n const uValue = interpolateData(p1u, p2u, p3u, p4u);\n const vValue = interpolateData(p1v, p2v, p3v, p4v);\n value = this.uvToDirection(uValue, vValue);\n } else {\n value = interpolateData(p1, p2, p3, p4);\n }\n\n return value;\n }\n\n static roundto(value, digits) {\n const roundto = 10 ** digits;\n return Math.round(value * roundto) / roundto;\n }\n\n static string_to_rgb(rgbString) {\n const rgb = rgbString\n .replace(/[^\\d,.]/g, '')\n .split(',')\n .map(Number);\n if (rgb.length === 3) {\n rgb.push(255);\n } else {\n rgb[3] = Math.round(rgb[3] * 255);\n }\n return rgb;\n }\n\n static rgb_to_string(arr) {\n if (arr.length === 4) {\n return `rgba(${arr[0]},${arr[1]},${arr[2]},${arr[3]})`;\n }\n if (arr.length === 3) {\n return `rgb(${arr[0]},${arr[1]},${arr[2]})`;\n }\n return null;\n }\n\n static hexToRgb(hex) {\n // Remove the hash at the start if it's there\n const hexNoHash = hex.replace(/^#/, '');\n\n // Parse the r, g, b values\n const bigint = parseInt(hexNoHash, 16);\n const r = Math.floor(bigint / (256 * 256)) % 256;\n const g = Math.floor(bigint / 256) % 256;\n const b = bigint % 256;\n\n return [r, g, b];\n }\n\n static closestceilvalue(inArr, val) {\n // convert arr to numbers\n const arr = inArr.map(Number);\n let idx = Math.min.apply(\n null,\n arr.filter((v) => v >= val),\n );\n // If we come up with -Infinity, take the last value in the array\n if (idx === Infinity) {\n idx = arr[arr.length - 1];\n }\n return idx;\n }\n\n static closestfloorvalue(inArr, val) {\n // convert arr to numbers\n const arr = inArr.map(Number);\n let idx = Math.max.apply(\n null,\n arr.filter((v) => v <= val),\n );\n // If we come up with -Infinity, take the first value in the array\n if (idx === -Infinity) {\n [idx] = arr;\n }\n return idx;\n }\n\n static normalize(values, clevels, ctype) {\n // Get max and min color values from color config file\n // to normalize data\n // const t0 = performance.now();\n const max = Math.max(...clevels);\n const min = Math.min(...clevels);\n\n // Loop over values and store normalized values in nvalues\n const nvalues = new Float32Array(values.length);\n for (let i = 0; i < nvalues.length; i += 1) {\n nvalues[i] = gUtilities.normalize1D(values[i], max, min, clevels, ctype);\n }\n // console.log('Done', performance.now() - t0);\n\n return nvalues;\n }\n\n static formatValidTime(currentLayer) {\n const date = new Date();\n const options = { year: 'numeric', month: 'long', day: 'numeric' };\n\n const outlookDays = {\n day1outlook: 0,\n day2outlook: 1,\n day3outlook: 2,\n day4outlook: 3,\n day5outlook: 4,\n };\n\n if (Object.keys(outlookDays).includes(currentLayer.dataType)) {\n const offset = outlookDays[currentLayer.dataType];\n const start = this.getCurrentDayAndHour(offset, offset !== 0);\n const endDate = new Date(date.setUTCDate(date.getUTCDate() + offset));\n endDate.setUTCHours(12);\n const end = this.formatSpcDate(endDate);\n return `${start} - ${end}`;\n }\n\n if (currentLayer.layerType === 'prcp' || currentLayer.layerType === 'temp') {\n const rangeOffset = currentLayer.range === '6-10' ? [6, 10] : [8, 14];\n const [startOffset, endOffset] = rangeOffset;\n const startDate = new Date(date.setUTCDate(date.getUTCDate() + startOffset));\n const endDate = new Date(date.setUTCDate(date.getUTCDate() + endOffset - startOffset));\n return `${startDate.toLocaleDateString('en-US', options)} - ${endDate.toLocaleDateString('en-US', options)}`;\n }\n\n return '';\n }\n\n static formatSpcDate(dateUTC) {\n // Ensure the input is a valid Date object\n if (!(dateUTC instanceof Date) || Number.isNaN(dateUTC)) {\n throw new Error('Input must be a valid Date object.');\n }\n\n // Add one day to the input date\n const nextDay = new Date(dateUTC);\n nextDay.setUTCDate(nextDay.getUTCDate() + 1);\n\n // Format the output as DD/1200Z\n const day = String(nextDay.getUTCDate()).padStart(2, '0'); // Ensure two digits\n const formattedOutput = `${day}/12Z`;\n\n return formattedOutput;\n }\n\n static getCurrentDayAndHour = (offset = 0, isStartAt12Z = false) => {\n const date = new Date();\n const adjustedDate = new Date(date);\n if (isStartAt12Z) {\n adjustedDate.setUTCDate(date.getUTCDate() + offset);\n adjustedDate.setUTCHours(12); // Set to 12Z for days 2 and 3\n } else {\n adjustedDate.setUTCDate(date.getUTCDate() + offset);\n }\n return `${String(adjustedDate.getUTCDate()).padStart(2, '0')}/${String(adjustedDate.getUTCHours()).padStart(2, '0')}Z`;\n };\n\n static normalize1D(value, max, min, clevels, ctype) {\n // Not sure if this top info is relevant anymore\n // For webGL if you have 3 colors, they change as followed\n // color: Color1 Color2 Color3\n // value: 0 - 0.33 0.33-0.66 0.66-1\n\n // We don't have trouble interpolating to colors above the highest\n // and below the lowest clevels anymore. This is becuase we linear\n // interpolate from the lowest two (or upper two) point in clevels.\n // Additionally, we don't cap the nvalues at 0 or 1. That said,\n // if the scale is not linear, there could be problems interpolating\n // to points above the highest and below the lowest clevels. I am not\n // really sure though\n\n // There is always one more color than there are levels\n // clevels [-2,2] would have [color1,color2,color3]\n\n if (Number.isNaN(value)) return NaN;\n\n let idx;\n // Get the closest two points\n if (value < min) {\n idx = 0;\n } else if (value >= max) {\n idx = clevels.length - 2;\n } else {\n idx = clevels.findIndex((d) => d > value) - 1;\n }\n\n const lnvalue = idx / (clevels.length - 1);\n const lvalue = clevels[idx];\n const unvalue = (idx + 1) / (clevels.length - 1);\n const uvalue = clevels[idx + 1];\n\n const fractionBetween = (value - lvalue) / (uvalue - lvalue);\n // fractionBetween = fractionBetween > 1 ? 1 : fractionBetween < 0 ? 0 : fractionBetween\n\n // Now we have a value between 0 and 1\n let nvalue = (1 - fractionBetween) * lnvalue + fractionBetween * unvalue;\n\n // When you are right on the threshold values, weird lines appear, these if() blocks prevent that\n // This shows up in precip but also difference fields of precip. High threshold value give a\n // blocky look. FMost fields have a value of 0.0. Really this only needs to be applied when going\n // from no shaded area (think precip) to a shaded area. For now, it is applied to all levels\n if (ctype === 'threshold') {\n const threshold = 0.01;\n if (threshold > 0) {\n if (Math.abs(nvalue - lnvalue) < threshold) {\n nvalue += threshold;\n }\n if (Math.abs(nvalue - unvalue) < threshold) {\n nvalue -= threshold;\n }\n }\n }\n\n // But we need to sqeeze this between the range of the lowest and upper most color values\n let lowestColorValue;\n if (ctype === 'linear') {\n lowestColorValue = 1 / clevels.length / 2;\n } else {\n lowestColorValue = 1 / (clevels.length + 1);\n }\n const range = 1 - lowestColorValue * 2;\n\n nvalue = lowestColorValue + range * nvalue;\n\n // Don't cap the upper and lower value, this will help with interpolation\n // done in the fragment shader\n // However, values > 1 && < 0 are transparent in the fragment shader\n // So you have to cap!\n if (nvalue >= 0.999) {\n // value of 1 has weird lines using linear colorbar\n nvalue = 0.999;\n }\n if (nvalue <= 0.001) {\n // value of 0 has weird lines using linear colorbar\n nvalue = 0.001;\n }\n\n return nvalue;\n\n /*\n //Threshold colorbars\n let len=clevels.length+1\n\n let idx\n //Get the closest two points\n if ( value < min ){\n idx = 0\n }\n else if ( value >= max ){\n idx = clevels.length-2\n }\n else {\n idx = clevels.findIndex(d => d > value) - 1 \n }\n\n let lnvalue=(idx+1)/len\n let lvalue=clevels[idx]\n let unvalue=(idx+2)/len\n let uvalue=clevels[idx+1]\n\n let local_normalized_value = (value-lvalue)/(uvalue-lvalue)\n\n //let adj = \n let nvalue = lnvalue + local_normalized_value * (unvalue-lnvalue)\n\n //When you are right on the threshold values, weird lines appear, these if() blocks prevent that\n //This shows up in precip but also difference fields of precip. High threshold value give a \n //blocky look. FMost fields have a value of 0.0. \n let threshold = dic_fields[field]['plots']['normalizingAdjustment']\n if ( threshold > 0 ){\n if ( Math.abs(nvalue - lnvalue) < threshold ){\n nvalue += threshold\n }\n if ( Math.abs(nvalue - unvalue) < threshold ){\n nvalue -= threshold\n }\n }\n\n //Don't cap the upper and lower value, this will help with interpolation\n //done in the fragment shader\n // However, values > 1 && < 0 are transparent in the fragment shader\n if ( nvalue > 1 ){nvalue=1}\n if ( nvalue < 0 ){nvalue=0}\n //nvalue = Math.round(nvalue*1000)/1000\n \n return nvalue\n */\n }\n\n //* note: date should be a date object\n static formatdate(date, style, settings = undefined) {\n const timezoneoption = settings?.timeZone || 'local';\n const hourFormat = settings?.hourFormat || 12;\n\n // timezoneoption can be local or UTC\n\n let datex = new Date(date.getTime());\n if (timezoneoption === 'UTC')\n datex = new Date(date.toLocaleString('en-US', { timeZone: 'UTC' }));\n const month = datex.getMonth();\n const day = datex.getDate();\n const dayofweek = datex.getDay();\n const year = datex.getFullYear();\n let hours = datex.getHours();\n let minutes = datex.getMinutes();\n let zone = datex\n .toLocaleDateString('en-US', { day: '2-digit', timeZoneName: 'short' })\n .substring(4);\n if (timezoneoption !== 'local') zone = 'UTC';\n let ampm;\n // adding space to end of ampm to allow for correct spacing before zone, eg: 18 UTC or 6pm MST\n if (hourFormat === 12) {\n ampm = hours >= 12 ? 'pm ' : 'am ';\n hours %= 12;\n hours = hours || 12;\n } else {\n ampm = ' ';\n }\n const hoursshort = hours;\n hours = hours < 10 ? `0${hours}` : hours;\n minutes = minutes < 10 ? `0${minutes}` : minutes;\n\n let descriptiveTime = '';\n if (hoursshort < 12) {\n descriptiveTime = `${weekdaynames[dayofweek]} Morning`;\n } else if (hoursshort < 18) {\n descriptiveTime = `${weekdaynames[dayofweek]} Afternoon`;\n } else {\n descriptiveTime = `${weekdaynames[dayofweek]} Evening`;\n }\n\n let datetext;\n // Format the datetext\n if (style === 'short') {\n datetext = `${weekdaynamesshort[dayofweek]} ${hours} ${ampm}${zone}`;\n } else if (style === 'YYYYMMDDHHMM') {\n datetext =\n String(year).padStart(4, '0') +\n String(month + 1).padStart(2, '0') +\n String(day).padStart(2, '0') +\n String(hours).padStart(2, '0') +\n String(minutes).padStart(2, '0');\n } else if (style === 'YYYYMMDD HH') {\n datetext = `${\n String(year).padStart(4, '0') +\n String(month + 1).padStart(2, '0') +\n String(day).padStart(2, '0')\n } ${String(hours).padStart(2, '0')}`;\n } else if (style === 'shorter') {\n datetext = `${weekdaynamesshort[dayofweek]} ${hours}:${minutes} ${ampm} ${zone}, ${monthnamesshort[month]} ${day}`;\n } else if (style === 'selectbox') {\n datetext = `${String(datex.getUTCHours()).padStart(2, '0')}Z ${\n monthnames[datex.getUTCMonth()]\n } ${datex.getUTCDate()}, ${datex.getUTCFullYear()}`;\n } else if (style === 'graphics') {\n datetext = `${weekdaynamesshort[dayofweek]}, ${monthnamesshort[month]} ${day}, ${year}, ${hoursshort} ${ampm}${zone}`;\n } else if (style === 'descriptiveTime') {\n datetext = `${descriptiveTime}, ${monthnamesshort[month]} ${day}`;\n } else if (style === 'timing') {\n // only have time zone if UTC\n datetext = `${weekdaynamesshort[dayofweek]} ${hoursshort}${ampm} ${zone === 'UTC' ? zone : ''}`;\n } else if (style === 'timezone') {\n datetext = zone;\n } else {\n datetext = `${weekdaynames[dayofweek]} ${hours} ${ampm}${zone}, ${monthnames[month]} ${day}, ${year}`;\n }\n\n // Remove any extra spaces\n datetext = datetext.replace(/\\s+/g, ' ').trim();\n\n return datetext;\n }\n}\n","\n/**\n * Rearranges items so that all items in the [left, k] are the smallest.\n * The k-th element will have the (k - left + 1)-th smallest value in [left, right].\n *\n * @template T\n * @param {T[]} arr the array to partially sort (in place)\n * @param {number} k middle index for partial sorting (as defined above)\n * @param {number} [left=0] left index of the range to sort\n * @param {number} [right=arr.length-1] right index\n * @param {(a: T, b: T) => number} [compare = (a, b) => a - b] compare function\n */\nexport default function quickselect(arr, k, left = 0, right = arr.length - 1, compare = defaultCompare) {\n\n while (right > left) {\n if (right - left > 600) {\n const n = right - left + 1;\n const m = k - left + 1;\n const z = Math.log(n);\n const s = 0.5 * Math.exp(2 * z / 3);\n const sd = 0.5 * Math.sqrt(z * s * (n - s) / n) * (m - n / 2 < 0 ? -1 : 1);\n const newLeft = Math.max(left, Math.floor(k - m * s / n + sd));\n const newRight = Math.min(right, Math.floor(k + (n - m) * s / n + sd));\n quickselect(arr, k, newLeft, newRight, compare);\n }\n\n const t = arr[k];\n let i = left;\n /** @type {number} */\n let j = right;\n\n swap(arr, left, k);\n if (compare(arr[right], t) > 0) swap(arr, left, right);\n\n while (i < j) {\n swap(arr, i, j);\n i++;\n j--;\n while (compare(arr[i], t) < 0) i++;\n while (compare(arr[j], t) > 0) j--;\n }\n\n if (compare(arr[left], t) === 0) swap(arr, left, j);\n else {\n j++;\n swap(arr, j, right);\n }\n\n if (j <= k) left = j + 1;\n if (k <= j) right = j - 1;\n }\n}\n\n/**\n * @template T\n * @param {T[]} arr\n * @param {number} i\n * @param {number} j\n */\nfunction swap(arr, i, j) {\n const tmp = arr[i];\n arr[i] = arr[j];\n arr[j] = tmp;\n}\n\n/**\n * @template T\n * @param {T} a\n * @param {T} b\n * @returns {number}\n */\nfunction defaultCompare(a, b) {\n return a < b ? -1 : a > b ? 1 : 0;\n}\n","import quickselect from 'quickselect';\n\nexport default class RBush {\n constructor(maxEntries = 9) {\n // max entries in a node is 9 by default; min node fill is 40% for best performance\n this._maxEntries = Math.max(4, maxEntries);\n this._minEntries = Math.max(2, Math.ceil(this._maxEntries * 0.4));\n this.clear();\n }\n\n all() {\n return this._all(this.data, []);\n }\n\n search(bbox) {\n let node = this.data;\n const result = [];\n\n if (!intersects(bbox, node)) return result;\n\n const toBBox = this.toBBox;\n const nodesToSearch = [];\n\n while (node) {\n for (let i = 0; i < node.children.length; i++) {\n const child = node.children[i];\n const childBBox = node.leaf ? toBBox(child) : child;\n\n if (intersects(bbox, childBBox)) {\n if (node.leaf) result.push(child);\n else if (contains(bbox, childBBox)) this._all(child, result);\n else nodesToSearch.push(child);\n }\n }\n node = nodesToSearch.pop();\n }\n\n return result;\n }\n\n collides(bbox) {\n let node = this.data;\n\n if (!intersects(bbox, node)) return false;\n\n const nodesToSearch = [];\n while (node) {\n for (let i = 0; i < node.children.length; i++) {\n const child = node.children[i];\n const childBBox = node.leaf ? this.toBBox(child) : child;\n\n if (intersects(bbox, childBBox)) {\n if (node.leaf || contains(bbox, childBBox)) return true;\n nodesToSearch.push(child);\n }\n }\n node = nodesToSearch.pop();\n }\n\n return false;\n }\n\n load(data) {\n if (!(data && data.length)) return this;\n\n if (data.length < this._minEntries) {\n for (let i = 0; i < data.length; i++) {\n this.insert(data[i]);\n }\n return this;\n }\n\n // recursively build the tree with the given data from scratch using OMT algorithm\n let node = this._build(data.slice(), 0, data.length - 1, 0);\n\n if (!this.data.children.length) {\n // save as is if tree is empty\n this.data = node;\n\n } else if (this.data.height === node.height) {\n // split root if trees have the same height\n this._splitRoot(this.data, node);\n\n } else {\n if (this.data.height < node.height) {\n // swap trees if inserted one is bigger\n const tmpNode = this.data;\n this.data = node;\n node = tmpNode;\n }\n\n // insert the small tree into the large tree at appropriate level\n this._insert(node, this.data.height - node.height - 1, true);\n }\n\n return this;\n }\n\n insert(item) {\n if (item) this._insert(item, this.data.height - 1);\n return this;\n }\n\n clear() {\n this.data = createNode([]);\n return this;\n }\n\n remove(item, equalsFn) {\n if (!item) return this;\n\n let node = this.data;\n const bbox = this.toBBox(item);\n const path = [];\n const indexes = [];\n let i, parent, goingUp;\n\n // depth-first iterative tree traversal\n while (node || path.length) {\n\n if (!node) { // go up\n node = path.pop();\n parent = path[path.length - 1];\n i = indexes.pop();\n goingUp = true;\n }\n\n if (node.leaf) { // check current node\n const index = findItem(item, node.children, equalsFn);\n\n if (index !== -1) {\n // item found, remove the item and condense tree upwards\n node.children.splice(index, 1);\n path.push(node);\n this._condense(path);\n return this;\n }\n }\n\n if (!goingUp && !node.leaf && contains(node, bbox)) { // go down\n path.push(node);\n indexes.push(i);\n i = 0;\n parent = node;\n node = node.children[0];\n\n } else if (parent) { // go right\n i++;\n node = parent.children[i];\n goingUp = false;\n\n } else node = null; // nothing found\n }\n\n return this;\n }\n\n toBBox(item) { return item; }\n\n compareMinX(a, b) { return a.minX - b.minX; }\n compareMinY(a, b) { return a.minY - b.minY; }\n\n toJSON() { return this.data; }\n\n fromJSON(data) {\n this.data = data;\n return this;\n }\n\n _all(node, result) {\n const nodesToSearch = [];\n while (node) {\n if (node.leaf) result.push(...node.children);\n else nodesToSearch.push(...node.children);\n\n node = nodesToSearch.pop();\n }\n return result;\n }\n\n _build(items, left, right, height) {\n\n const N = right - left + 1;\n let M = this._maxEntries;\n let node;\n\n if (N <= M) {\n // reached leaf level; return leaf\n node = createNode(items.slice(left, right + 1));\n calcBBox(node, this.toBBox);\n return node;\n }\n\n if (!height) {\n // target height of the bulk-loaded tree\n height = Math.ceil(Math.log(N) / Math.log(M));\n\n // target number of root entries to maximize storage utilization\n M = Math.ceil(N / Math.pow(M, height - 1));\n }\n\n node = createNode([]);\n node.leaf = false;\n node.height = height;\n\n // split the items into M mostly square tiles\n\n const N2 = Math.ceil(N / M);\n const N1 = N2 * Math.ceil(Math.sqrt(M));\n\n multiSelect(items, left, right, N1, this.compareMinX);\n\n for (let i = left; i <= right; i += N1) {\n\n const right2 = Math.min(i + N1 - 1, right);\n\n multiSelect(items, i, right2, N2, this.compareMinY);\n\n for (let j = i; j <= right2; j += N2) {\n\n const right3 = Math.min(j + N2 - 1, right2);\n\n // pack each entry recursively\n node.children.push(this._build(items, j, right3, height - 1));\n }\n }\n\n calcBBox(node, this.toBBox);\n\n return node;\n }\n\n _chooseSubtree(bbox, node, level, path) {\n while (true) {\n path.push(node);\n\n if (node.leaf || path.length - 1 === level) break;\n\n let minArea = Infinity;\n let minEnlargement = Infinity;\n let targetNode;\n\n for (let i = 0; i < node.children.length; i++) {\n const child = node.children[i];\n const area = bboxArea(child);\n const enlargement = enlargedArea(bbox, child) - area;\n\n // choose entry with the least area enlargement\n if (enlargement < minEnlargement) {\n minEnlargement = enlargement;\n minArea = area < minArea ? area : minArea;\n targetNode = child;\n\n } else if (enlargement === minEnlargement) {\n // otherwise choose one with the smallest area\n if (area < minArea) {\n minArea = area;\n targetNode = child;\n }\n }\n }\n\n node = targetNode || node.children[0];\n }\n\n return node;\n }\n\n _insert(item, level, isNode) {\n const bbox = isNode ? item : this.toBBox(item);\n const insertPath = [];\n\n // find the best node for accommodating the item, saving all nodes along the path too\n const node = this._chooseSubtree(bbox, this.data, level, insertPath);\n\n // put the item into the node\n node.children.push(item);\n extend(node, bbox);\n\n // split on node overflow; propagate upwards if necessary\n while (level >= 0) {\n if (insertPath[level].children.length > this._maxEntries) {\n this._split(insertPath, level);\n level--;\n } else break;\n }\n\n // adjust bboxes along the insertion path\n this._adjustParentBBoxes(bbox, insertPath, level);\n }\n\n // split overflowed node into two\n _split(insertPath, level) {\n const node = insertPath[level];\n const M = node.children.length;\n const m = this._minEntries;\n\n this._chooseSplitAxis(node, m, M);\n\n const splitIndex = this._chooseSplitIndex(node, m, M);\n\n const newNode = createNode(node.children.splice(splitIndex, node.children.length - splitIndex));\n newNode.height = node.height;\n newNode.leaf = node.leaf;\n\n calcBBox(node, this.toBBox);\n calcBBox(newNode, this.toBBox);\n\n if (level) insertPath[level - 1].children.push(newNode);\n else this._splitRoot(node, newNode);\n }\n\n _splitRoot(node, newNode) {\n // split root node\n this.data = createNode([node, newNode]);\n this.data.height = node.height + 1;\n this.data.leaf = false;\n calcBBox(this.data, this.toBBox);\n }\n\n _chooseSplitIndex(node, m, M) {\n let index;\n let minOverlap = Infinity;\n let minArea = Infinity;\n\n for (let i = m; i <= M - m; i++) {\n const bbox1 = distBBox(node, 0, i, this.toBBox);\n const bbox2 = distBBox(node, i, M, this.toBBox);\n\n const overlap = intersectionArea(bbox1, bbox2);\n const area = bboxArea(bbox1) + bboxArea(bbox2);\n\n // choose distribution with minimum overlap\n if (overlap < minOverlap) {\n minOverlap = overlap;\n index = i;\n\n minArea = area < minArea ? area : minArea;\n\n } else if (overlap === minOverlap) {\n // otherwise choose distribution with minimum area\n if (area < minArea) {\n minArea = area;\n index = i;\n }\n }\n }\n\n return index || M - m;\n }\n\n // sorts node children by the best axis for split\n _chooseSplitAxis(node, m, M) {\n const compareMinX = node.leaf ? this.compareMinX : compareNodeMinX;\n const compareMinY = node.leaf ? this.compareMinY : compareNodeMinY;\n const xMargin = this._allDistMargin(node, m, M, compareMinX);\n const yMargin = this._allDistMargin(node, m, M, compareMinY);\n\n // if total distributions margin value is minimal for x, sort by minX,\n // otherwise it's already sorted by minY\n if (xMargin < yMargin) node.children.sort(compareMinX);\n }\n\n // total margin of all possible split distributions where each node is at least m full\n _allDistMargin(node, m, M, compare) {\n node.children.sort(compare);\n\n const toBBox = this.toBBox;\n const leftBBox = distBBox(node, 0, m, toBBox);\n const rightBBox = distBBox(node, M - m, M, toBBox);\n let margin = bboxMargin(leftBBox) + bboxMargin(rightBBox);\n\n for (let i = m; i < M - m; i++) {\n const child = node.children[i];\n extend(leftBBox, node.leaf ? toBBox(child) : child);\n margin += bboxMargin(leftBBox);\n }\n\n for (let i = M - m - 1; i >= m; i--) {\n const child = node.children[i];\n extend(rightBBox, node.leaf ? toBBox(child) : child);\n margin += bboxMargin(rightBBox);\n }\n\n return margin;\n }\n\n _adjustParentBBoxes(bbox, path, level) {\n // adjust bboxes along the given tree path\n for (let i = level; i >= 0; i--) {\n extend(path[i], bbox);\n }\n }\n\n _condense(path) {\n // go through the path, removing empty nodes and updating bboxes\n for (let i = path.length - 1, siblings; i >= 0; i--) {\n if (path[i].children.length === 0) {\n if (i > 0) {\n siblings = path[i - 1].children;\n siblings.splice(siblings.indexOf(path[i]), 1);\n\n } else this.clear();\n\n } else calcBBox(path[i], this.toBBox);\n }\n }\n}\n\nfunction findItem(item, items, equalsFn) {\n if (!equalsFn) return items.indexOf(item);\n\n for (let i = 0; i < items.length; i++) {\n if (equalsFn(item, items[i])) return i;\n }\n return -1;\n}\n\n// calculate node's bbox from bboxes of its children\nfunction calcBBox(node, toBBox) {\n distBBox(node, 0, node.children.length, toBBox, node);\n}\n\n// min bounding rectangle of node children from k to p-1\nfunction distBBox(node, k, p, toBBox, destNode) {\n if (!destNode) destNode = createNode(null);\n destNode.minX = Infinity;\n destNode.minY = Infinity;\n destNode.maxX = -Infinity;\n destNode.maxY = -Infinity;\n\n for (let i = k; i < p; i++) {\n const child = node.children[i];\n extend(destNode, node.leaf ? toBBox(child) : child);\n }\n\n return destNode;\n}\n\nfunction extend(a, b) {\n a.minX = Math.min(a.minX, b.minX);\n a.minY = Math.min(a.minY, b.minY);\n a.maxX = Math.max(a.maxX, b.maxX);\n a.maxY = Math.max(a.maxY, b.maxY);\n return a;\n}\n\nfunction compareNodeMinX(a, b) { return a.minX - b.minX; }\nfunction compareNodeMinY(a, b) { return a.minY - b.minY; }\n\nfunction bboxArea(a) { return (a.maxX - a.minX) * (a.maxY - a.minY); }\nfunction bboxMargin(a) { return (a.maxX - a.minX) + (a.maxY - a.minY); }\n\nfunction enlargedArea(a, b) {\n return (Math.max(b.maxX, a.maxX) - Math.min(b.minX, a.minX)) *\n (Math.max(b.maxY, a.maxY) - Math.min(b.minY, a.minY));\n}\n\nfunction intersectionArea(a, b) {\n const minX = Math.max(a.minX, b.minX);\n const minY = Math.max(a.minY, b.minY);\n const maxX = Math.min(a.maxX, b.maxX);\n const maxY = Math.min(a.maxY, b.maxY);\n\n return Math.max(0, maxX - minX) *\n Math.max(0, maxY - minY);\n}\n\nfunction contains(a, b) {\n return a.minX <= b.minX &&\n a.minY <= b.minY &&\n b.maxX <= a.maxX &&\n b.maxY <= a.maxY;\n}\n\nfunction intersects(a, b) {\n return b.minX <= a.maxX &&\n b.minY <= a.maxY &&\n b.maxX >= a.minX &&\n b.maxY >= a.minY;\n}\n\nfunction createNode(children) {\n return {\n children,\n height: 1,\n leaf: true,\n minX: Infinity,\n minY: Infinity,\n maxX: -Infinity,\n maxY: -Infinity\n };\n}\n\n// sort an array so that items come in groups of n unsorted items, with groups sorted between each other;\n// combines selection algorithm with binary divide & conquer approach\n\nfunction multiSelect(arr, left, right, n, compare) {\n const stack = [left, right];\n\n while (stack.length) {\n right = stack.pop();\n left = stack.pop();\n\n if (right - left <= n) continue;\n\n const mid = left + Math.ceil((right - left) / n / 2) * n;\n quickselect(arr, mid, left, right, compare);\n\n stack.push(left, mid, mid, right);\n }\n}\n","import { WebMercatorViewport, _GlobeViewport } from '@deck.gl/core';\nimport gUtilities from './graphicsUtilities';\n\nexport default class deckUtilities {\n static getLatLonPerPixel(viewport) {\n // Always calculate the resLevel for a pitch of 0. We don't want the resolution changing\n // if a user tilts the maps\n const { width, height, latitude, longitude, zoom } = viewport;\n // Globeview bearing is undefined, so grab it this way\n const bearing = viewport.bearing || 0;\n let viewportNoPitch;\n if (viewport.id.includes('geojson3D')) {\n viewportNoPitch = new _GlobeViewport({\n width,\n height,\n latitude,\n longitude,\n zoom,\n bearing,\n pitch: 0,\n });\n } else {\n viewportNoPitch = new WebMercatorViewport({\n width,\n height,\n latitude,\n longitude,\n zoom,\n bearing,\n pitch: 0,\n });\n }\n\n const { unproject } = viewportNoPitch;\n\n const corners = [\n unproject([0, 0]),\n unproject([width / 2, 0]),\n unproject([width, 0]),\n unproject([width, height / 2]),\n unproject([width, height]),\n unproject([width / 2, height]),\n unproject([0, height]),\n ];\n\n const lons = corners.map((x) => x[0]);\n const lats = corners.map((x) => x[1]);\n\n const lonDiff = this.degreeDiff(Math.max(...lons), Math.min(...lons));\n const latDiff = this.degreeDiff(Math.max(...lats), Math.min(...lats));\n\n const latPerPixel = latDiff / height;\n const lonPerPixel = lonDiff / width;\n\n return { latPerPixel, lonPerPixel };\n }\n\n static getViewport(ref, displayNum = 0) {\n // mapboxOverlay vs deck\n return (\n ref.current?._deck?.viewManager?.getViewports()?.[displayNum] ||\n ref?.current?.deck?.viewManager?.getViewports()?.[displayNum]\n );\n }\n\n static getViewportBounds(viewport, proj = undefined) {\n // Get bounds does not work correctly with globe viewport, becuase of this doing the alternative below\n // let [xMin, yMin, xMax, yMax] = viewport.getBounds();\n const { unproject, width, height } = viewport;\n const screenValues = [0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0];\n\n const xValues = [];\n const yValues = [];\n for (const x of screenValues) {\n for (const y of screenValues) {\n const [lon, lat] = unproject([width * x, height * y]);\n // console.log('yes', lon, lat, proj);\n if (proj) {\n const [i, j] = proj.LonLatToij(lon, lat);\n yValues.push(j);\n xValues.push(i);\n } else {\n yValues.push(lat);\n xValues.push(lon);\n }\n }\n }\n\n // Takes about 0.2 ms\n // console.log('done', performance.now() - t0);\n const yMin = Math.min(...yValues);\n const yMax = Math.max(...yValues);\n const xMin = Math.min(...xValues);\n const xMax = Math.max(...xValues);\n\n return { yMin, yMax, xMin, xMax };\n }\n\n static getCities(viewport, tree, dys, cityBaseScale, cityPadding) {\n const FontsizeInPixels = 16;\n const { unproject } = viewport;\n if (!unproject) return undefined;\n\n const { yMin, yMax, xMin, xMax } = this.getViewportBounds(viewport);\n\n const { latPerPixel } = deckUtilities.getLatLonPerPixel(viewport);\n // Adjust this value to make the city density larger or smaller\n const padding = cityPadding * cityBaseScale * 0.3;\n const dyRaw = ((latPerPixel * FontsizeInPixels) / 2) * padding;\n const dysCopy = [...dys];\n dysCopy.sort();\n const dy = gUtilities.closestfloorvalue(dysCopy, dyRaw);\n // The search here is quick.\n return tree[dy].search({\n minX: xMin,\n maxX: xMax,\n minY: yMin,\n maxY: yMax,\n });\n }\n\n static degreeDiff(d1, degree2) {\n let degree1 = d1;\n if (degree1 < degree2) degree1 += 360;\n const diff = Math.abs(degree1 - degree2);\n\n return diff;\n }\n\n // The following two functions are hacks to get billboarding to work properly on\n // globe projection, and hide text behind the globe. See this for more details:\n // https://github.com/visgl/deck.gl/issues/9554#issuecomment-2785192798\n\n // Tune this mapping to match your renderer behavior\n static zoomToFOV(zoom) {\n const clamped = Math.max(Math.min(zoom, 20), 1);\n // At zoom 1 → full hemisphere (≈130° FOV), at zoom 20 → tight 0° FOV\n return 130 * (1 - (clamped - 1) / 19); // Range: 130 → 0 degrees\n }\n\n // Helper function to determine if a feature is visible from a camera's pov on globe projection\n static isFeatureVisibleOnGlobe(cameraLat, cameraLon, featureLat, featureLon, zoom) {\n // check for valid numbers to prevent errors from 'undefined' values\n if (\n [cameraLat, cameraLon, featureLat, featureLon, zoom].some(\n (v) => typeof v !== 'number' || Number.isNaN(v),\n )\n ) {\n return false;\n }\n\n const toRad = (deg) => (deg * Math.PI) / 180;\n\n // Convert lat/lon to radians\n const camLatRad = toRad(cameraLat);\n const camLonRad = toRad(cameraLon);\n const featLatRad = toRad(featureLat);\n const featLonRad = toRad(featureLon);\n\n // Convert to unit vectors\n const toVec3 = (lat, lon) => [\n Math.cos(lat) * Math.cos(lon),\n Math.sin(lat),\n Math.cos(lat) * Math.sin(lon),\n ];\n\n const camVec = toVec3(camLatRad, camLonRad);\n const featVec = toVec3(featLatRad, featLonRad);\n\n // Compute dot product\n const dot = camVec[0] * featVec[0] + camVec[1] * featVec[1] + camVec[2] * featVec[2];\n\n // Convert zoom level to a tighter FOV threshold\n const fovDegrees = this.zoomToFOV(zoom); // field of view in degrees\n const halfFovCos = Math.cos(toRad(fovDegrees / 2));\n\n // If the angle between the vectors is within the cone, dot ≥ cos(halfFOV)\n return dot >= halfFovCos;\n }\n}\n","/* eslint-disable max-len */\nimport { CompositeLayer } from '@deck.gl/core';\nimport RBush from 'rbush';\nimport { TextLayer } from '@deck.gl/layers';\nimport deckUtilities from '../../utilities/deckUtilities';\n\nconst defaultProps = {\n getColor: (x) => x.color || [245, 245, 245],\n getBackgroundColor: [255, 255, 255, 150],\n getSize: 12,\n getAngle: 0,\n billboard: true,\n background: false,\n backgroundPadding: [4, 1],\n getTextAnchor: 'middle',\n fontFamily: 'Helvetica',\n getAlignmentBaseline: 'center',\n parameters: {\n depthCompare: 'always',\n cullMode: 'none',\n },\n fontSettings: {\n sdf: true,\n radius: 12,\n cutoff: 0.25,\n buffer: 10,\n smoothing: 0.2, // only applies if sdf is true\n },\n outlineWidth: 4,\n fontWeight: '700',\n outlineColor: [0, 0, 0, 255],\n getLabel: (x) => x.label,\n getWeight: (x) => x.weight || 1,\n getPosition: (x) => x.position,\n};\n\nfunction fillTree(tree, points, text, padding) {\n for (const point of points) {\n const { lat, lon } = point;\n const obj = {\n text,\n lat,\n lon,\n minX: lon - padding,\n minY: lat - padding,\n maxX: lon + padding,\n maxY: lat + padding,\n };\n if (!tree.collides(obj)) {\n tree.insert(obj);\n }\n }\n return tree;\n}\n\nexport default class ContourLabels extends CompositeLayer {\n initializeState() {\n this.state = {\n // Cached tags per zoom level\n zoom: 9999,\n };\n }\n\n // eslint-disable-next-line class-methods-use-this\n shouldUpdateState({ changeFlags }) {\n return changeFlags.somethingChanged;\n }\n\n updateState({ props, oldProps, changeFlags }) {\n super.updateState({ props, oldProps, changeFlags });\n const { viewport } = this.context;\n const { zoom } = viewport;\n\n // Only update the layer if propsOrDataChanged or\n // if zoom has changed by 0.5 or more\n if (!changeFlags.propsOrDataChanged) {\n if (!zoom || Math.abs(zoom - this.state.zoom) < 0.5) return;\n }\n\n // Font size of the labels\n const FontsizeInPixels = 14;\n // Tuning variable for spacing between labels on same line\n const spacingOnLine = 50;\n // Tuning variable for spacing between labels on different lines but same value lines (50F contour and another 50F contour)\n const spacingBetweenLinesSameValue = 25;\n // Tuning variable for spacing between labels between lines\n const spacingBetweenLines = 1;\n\n const { latPerPixel } = deckUtilities.getLatLonPerPixel(viewport);\n const dy = FontsizeInPixels * latPerPixel;\n\n const { lines } = props;\n // Sort arrays be lengths, so the longest polygon is first\n for (const d of lines.features) {\n if (d.geometry.coordinates !== 0) {\n d.geometry.coordinates.sort((a, b) => b.length - a.length);\n }\n }\n\n //\n // There are two trees here, one for all the lines (tree)\n // and another just for the line being processed (treeLocal)\n // - These trees have different paddings\n const tree = new RBush();\n const padding = (dy * spacingBetweenLines) / 2;\n const paddingRegional = (dy * spacingBetweenLinesSameValue) / 2;\n const paddingLocal = (dy * spacingOnLine) / 2;\n for (const feature of lines.features) {\n const text = feature.properties[0].value.toString();\n const treeRegional = new RBush();\n for (const polygon of feature.geometry?.coordinates || []) {\n const treeLocal = new RBush();\n //\n // Loop over all points in the contour and get the slope\n // - we average the slope over numPoints. This allows us\n // to capture big/ridges troughs and not just local areas\n // where the slope is zero\n const points = [];\n // average over 10% of the line length to detect areas where\n // the slope is nearest zero\n const numPoints = Math.round(polygon.length * 0.1);\n for (let i = numPoints; i < polygon.length - 1 - numPoints; i += 1) {\n const lon = polygon[i][0];\n const lat = polygon[i][1];\n // grab slope\n const x1 = polygon[i - numPoints][0];\n const y1 = polygon[i - numPoints][1];\n const x2 = polygon[i + numPoints][0];\n const y2 = polygon[i + numPoints][1];\n let slope = (y2 - y1) / (x2 - x1) || 0;\n slope = Math.abs(slope);\n points.push({ lat, lon, slope });\n // Never put a label on a slope greater than 30 degrees\n // if ( slope < 0.3 ){\n // points.push({lat,lon,slope})\n // }\n }\n\n // Sort the points by slope and try to add to treeLocal\n points.sort((a, b) => a.slope - b.slope);\n\n // - This adds the labels that have slopes closest to 0 first\n fillTree(treeLocal, points, text, paddingLocal);\n fillTree(treeRegional, treeLocal.all(), text, paddingRegional);\n }\n\n fillTree(tree, treeRegional.all(), text, padding);\n }\n\n const labels = tree.all();\n this.setState({ zoom, labels });\n }\n\n renderLayers() {\n const { labels } = this.state;\n\n // access the camera position\n const { viewport } = this.context;\n const { zoom } = viewport;\n const cameraLat = viewport.latitude;\n const cameraLon = viewport.longitude;\n\n const textlayer = new TextLayer(this.props, {\n id: `${this.props.id}-text`,\n // filter out labels that are not visible on the globe\n data: labels.filter((label) =>\n deckUtilities.isFeatureVisibleOnGlobe(\n cameraLat,\n cameraLon,\n label.lat,\n label.lon,\n zoom,\n ),\n ),\n getPosition: (d) => [Number(d.lon), Number(d.lat), this.props.elevation],\n getText: (d) => d.text,\n });\n\n return textlayer;\n }\n}\n\nContourLabels.layerName = 'ContourLabels';\nContourLabels.defaultProps = defaultProps;\n\nexport { ContourLabels };\n","import { scaleLinear, scaleThreshold } from 'd3';\n\n// setting up canvas outside of function to prevent repeated creation\nconst canvas = document.createElement('canvas');\nconst context = canvas.getContext('2d');\n\n/**\n * Measures the dimensions of a given text string using a canvas context.\n *\n * @param {string} text - The text to measure.\n * @param {string} font - The CSS font property string, e.g. '400 16px Open Sans'.\n * Should be in the format: '[font-weight] [font-size] [font-family]'.\n * Font weight can be omitted, a number (e.g., 400, 700) or a keyword (e.g., 'bold').\n * @param {number} [rotate=0] - Degrees to rotate the text before measuring (not commonly used).\n * @returns {TextMetrics} The TextMetrics object containing width and other properties.\n *\n * @example\n * const metrics = getTextDimensions('Legend', '700 14px Arial');\n * console.log(metrics.width);\n */\nexport function getTextDimensions(text, font, rotate = 0) {\n context.save();\n context.font = font;\n const metrics = context.measureText(text);\n const { width } = metrics;\n const height = metrics.fontBoundingBoxAscent + metrics.fontBoundingBoxDescent;\n // now we need to calculate the rotated width and height\n const radians = (rotate * Math.PI) / 180;\n const rotatedWidth = Math.abs(width * Math.cos(radians)) + Math.abs(height * Math.sin(radians));\n const rotatedHeight =\n Math.abs(width * Math.sin(radians)) + Math.abs(height * Math.cos(radians));\n context.restore();\n return { width: rotatedWidth, height: rotatedHeight };\n}\n\n// takes in an array of labels with a name property and a font, '700 14px Arial'\nexport function getMaxTextDimensions(textArray, font, rotate = 0) {\n // variable to store the maximum label width\n let maxLabelWidth = 0;\n let maxLabelHeight = 0;\n\n // Iterate over all the labels to find the maximum width\n textArray.forEach((item) => {\n const { width: labelWidth, height: labelHeight } = getTextDimensions(item, font, rotate);\n if (labelWidth > maxLabelWidth) {\n maxLabelWidth = Math.ceil(labelWidth);\n }\n if (labelHeight > maxLabelHeight) {\n maxLabelHeight = Math.ceil(labelHeight);\n }\n });\n\n return { width: maxLabelWidth, height: maxLabelHeight };\n}\n\nexport function getTransformProps(isHorizontal, anchorPoint, tickLength, tickAngle = 0) {\n // guard against string input\n const tickAngleNumber = Number(tickAngle);\n const isNegativeTick = tickLength < 0;\n\n let transform = '';\n let textAnchor = '';\n let dominantBaseline = '';\n\n if (isHorizontal) {\n if (tickAngleNumber > 0) {\n textAnchor = isNegativeTick ? 'end' : 'start';\n dominantBaseline = 'middle';\n transform = `rotate(${tickAngleNumber}, 0, ${anchorPoint})`;\n } else if (tickAngleNumber < 0) {\n textAnchor = isNegativeTick ? 'start' : 'end';\n dominantBaseline = 'middle';\n transform = `rotate(${tickAngleNumber}, 0, ${anchorPoint})`;\n } else {\n // tickAngleNumber === 0\n textAnchor = 'middle';\n dominantBaseline = isNegativeTick ? 'alphabetic' : 'hanging';\n }\n } else if (!isHorizontal) {\n if (tickAngleNumber === 90) {\n textAnchor = 'middle';\n dominantBaseline = isNegativeTick ? 'hanging' : 'alphabetic';\n transform = `rotate(90, ${anchorPoint}, 0)`;\n } else if (tickAngleNumber === -90) {\n textAnchor = 'middle';\n dominantBaseline = isNegativeTick ? 'alphabetic' : 'hanging';\n transform = `rotate(-90, ${anchorPoint}, 0)`;\n } else if (tickAngleNumber !== 0) {\n textAnchor = isNegativeTick ? 'end' : 'start';\n dominantBaseline = 'middle';\n transform = `rotate(${tickAngleNumber}, ${anchorPoint}, 0)`;\n } else {\n // tickAngleNumber === 0\n textAnchor = isNegativeTick ? 'end' : 'start';\n dominantBaseline = 'middle';\n }\n }\n return { transform, textAnchor, dominantBaseline };\n}\n\nexport function getTitleProps({ isHorizontal, titleJustify, titleDimensions, barLength }) {\n let transform = '';\n let textAnchor = '';\n let dominantBaseline = '';\n let x = 0;\n let y = 0;\n\n if (isHorizontal) {\n if (titleJustify === 'left') {\n x = 0;\n textAnchor = 'start';\n } else if (titleJustify === 'center') {\n x = barLength / 2;\n textAnchor = 'middle';\n } else if (titleJustify === 'right') {\n x = barLength;\n textAnchor = 'end';\n }\n y = titleDimensions.height / 2;\n dominantBaseline = 'central';\n } else if (!isHorizontal) {\n if (titleJustify === 'left') {\n y = barLength;\n textAnchor = 'start';\n } else if (titleJustify === 'center') {\n y = barLength / 2;\n textAnchor = 'middle';\n } else if (titleJustify === 'right') {\n y = 0;\n textAnchor = 'end';\n }\n x = titleDimensions.width / 2;\n dominantBaseline = 'central';\n transform = `rotate(-90, ${x}, ${y})`;\n }\n\n return { transform, textAnchor, dominantBaseline, x, y };\n}\n\nexport function getColors(colorLevels, colors, colorType) {\n const singleColor =\n typeof colors === 'string'\n ? colors\n : Array.isArray(colors) && colors.length === 1\n ? colors[0]\n : null;\n\n if (singleColor) {\n return () => singleColor;\n }\n\n if (!Array.isArray(colors) || !Array.isArray(colorLevels)) {\n console.log('ERROR: colors and colorLevels must be arrays when using multi-color scales');\n return () => 'rgba(0,0,0,0)';\n }\n\n const clen = colors.length;\n const llen = colorLevels.length;\n if (colorType === 'scaleThreshold') {\n if (llen + 1 !== clen) {\n console.log(\n `ERROR: When using the threshold colorbar the number of colors must be one greater than the number of levels.` +\n `\\nColors Length: ${clen}\\nLevels Length: ${llen}\n \\nLevels: ${colorLevels}\n \\nColors: ${colors}`,\n );\n }\n } else if (colorType === 'scaleLinear') {\n if (llen !== clen) {\n console.log(\n `ERROR: When using the linear colorbar the number of colors and levels must be equal` +\n `\\nColors Length: ${clen}\\nLevels Length: ${llen}\n \\nLevels: ${colorLevels}\n \\nColors: ${colors}`,\n );\n }\n } else {\n console.log('ERROR: Colorbar of type', colorType, 'not found');\n }\n\n const colorScale = colorType === 'scaleLinear' ? scaleLinear() : scaleThreshold();\n\n colorScale.domain(colorLevels).range(colors);\n return colorScale;\n}\n","// deck.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nexport default `\\\n#version 300 es\n#define SHADER_NAME path-layer-vertex-shader\n\nin vec2 positions;\n\nin float instanceTypes;\nin vec3 instanceStartPositions;\nin vec3 instanceEndPositions;\nin vec3 instanceLeftPositions;\nin vec3 instanceRightPositions;\nin vec3 instanceLeftPositions64Low;\nin vec3 instanceStartPositions64Low;\nin vec3 instanceEndPositions64Low;\nin vec3 instanceRightPositions64Low;\nin float instanceStrokeWidths;\nin vec4 instanceColors;\nin vec3 instancePickingColors;\n\nuniform float opacity;\n\nout vec4 vColor;\nout vec2 vCornerOffset;\nout float vMiterLength;\nout vec2 vPathPosition;\nout float vPathLength;\nout float vJointType;\n\nconst float EPSILON = 0.001;\nconst vec3 ZERO_OFFSET = vec3(0.0);\n\nfloat flipIfTrue(bool flag) {\n return -(float(flag) * 2. - 1.);\n}\n\n// calculate line join positions\nvec3 getLineJoinOffset(\n vec3 prevPoint, vec3 currPoint, vec3 nextPoint,\n vec2 width\n) {\n bool isEnd = positions.x > 0.0;\n // side of the segment - -1: left, 0: center, 1: right\n float sideOfPath = positions.y;\n float isJoint = float(sideOfPath == 0.0);\n\n vec3 deltaA3 = (currPoint - prevPoint);\n vec3 deltaB3 = (nextPoint - currPoint);\n\n mat3 rotationMatrix;\n bool needsRotation = !path.billboard && project_needs_rotation(currPoint, rotationMatrix);\n if (needsRotation) {\n deltaA3 = deltaA3 * rotationMatrix;\n deltaB3 = deltaB3 * rotationMatrix;\n }\n vec2 deltaA = deltaA3.xy / width;\n vec2 deltaB = deltaB3.xy / width;\n\n float lenA = length(deltaA);\n float lenB = length(deltaB);\n\n vec2 dirA = lenA > 0. ? normalize(deltaA) : vec2(0.0, 0.0);\n vec2 dirB = lenB > 0. ? normalize(deltaB) : vec2(0.0, 0.0);\n\n vec2 perpA = vec2(-dirA.y, dirA.x);\n vec2 perpB = vec2(-dirB.y, dirB.x);\n\n // tangent of the corner\n vec2 tangent = dirA + dirB;\n tangent = length(tangent) > 0. ? normalize(tangent) : perpA;\n // direction of the corner\n vec2 miterVec = vec2(-tangent.y, tangent.x);\n // direction of the segment\n vec2 dir = isEnd ? dirA : dirB;\n // direction of the extrusion\n vec2 perp = isEnd ? perpA : perpB;\n // length of the segment\n float L = isEnd ? lenA : lenB;\n\n // A = angle of the corner\n float sinHalfA = abs(dot(miterVec, perp));\n float cosHalfA = abs(dot(dirA, miterVec));\n\n // -1: right, 1: left\n float turnDirection = flipIfTrue(dirA.x * dirB.y >= dirA.y * dirB.x);\n\n // relative position to the corner:\n // -1: inside (smaller side of the angle)\n // 0: center\n // 1: outside (bigger side of the angle)\n float cornerPosition = sideOfPath * turnDirection;\n\n float miterSize = 1.0 / max(sinHalfA, EPSILON);\n // trim if inside corner extends further than the line segment\n miterSize = mix(\n min(miterSize, max(lenA, lenB) / max(cosHalfA, EPSILON)),\n miterSize,\n step(0.0, cornerPosition)\n );\n\n // vec2 offsetVec = mix(miterVec * miterSize, perp, step(0.5, cornerPosition))\n vec2 offsetVec = mix(perp, miterVec * miterSize, step(0.5, isJoint))\n * (sideOfPath + isJoint * turnDirection);\n\n // special treatment for start cap and end cap\n bool isStartCap = lenA == 0.0 || (!isEnd && (instanceTypes == 1.0 || instanceTypes == 3.0));\n bool isEndCap = lenB == 0.0 || (isEnd && (instanceTypes == 2.0 || instanceTypes == 3.0));\n bool isCap = isStartCap || isEndCap;\n\n // extend out a triangle to envelope the round cap\n if (isCap) {\n offsetVec = mix(perp * sideOfPath, dir * path.capType * 4.0 * flipIfTrue(isStartCap), isJoint);\n vJointType = path.capType;\n } else {\n vJointType = path.jointType;\n }\n\n // Generate variables for fragment shader\n vPathLength = L;\n vCornerOffset = offsetVec;\n vMiterLength = dot(vCornerOffset, miterVec * turnDirection);\n vMiterLength = isCap ? isJoint : vMiterLength;\n\n vec2 offsetFromStartOfPath = vCornerOffset + deltaA * float(isEnd);\n vPathPosition = vec2(\n dot(offsetFromStartOfPath, perp),\n dot(offsetFromStartOfPath, dir)\n );\n geometry.uv = vPathPosition;\n\n float isValid = step(instanceTypes, 3.5);\n vec3 offset = vec3(offsetVec * width * isValid, 0.0);\n\n if (needsRotation) {\n offset = rotationMatrix * offset;\n }\n return offset;\n}\n\n// In clipspace extrusion, if a line extends behind the camera, clip it to avoid visual artifacts\nvoid clipLine(inout vec4 position, vec4 refPosition) {\n if (position.w < EPSILON) {\n float r = (EPSILON - refPosition.w) / (position.w - refPosition.w);\n position = refPosition + (position - refPosition) * r;\n }\n}\n\nvoid main() {\n geometry.pickingColor = instancePickingColors;\n\n vColor = vec4(instanceColors.rgb, instanceColors.a * layer.opacity);\n\n float isEnd = positions.x;\n\n vec3 prevPosition = mix(instanceLeftPositions, instanceStartPositions, isEnd);\n vec3 prevPosition64Low = mix(instanceLeftPositions64Low, instanceStartPositions64Low, isEnd);\n\n vec3 currPosition = mix(instanceStartPositions, instanceEndPositions, isEnd);\n vec3 currPosition64Low = mix(instanceStartPositions64Low, instanceEndPositions64Low, isEnd);\n\n vec3 nextPosition = mix(instanceEndPositions, instanceRightPositions, isEnd);\n vec3 nextPosition64Low = mix(instanceEndPositions64Low, instanceRightPositions64Low, isEnd);\n\n geometry.worldPosition = currPosition;\n vec2 widthPixels = vec2(clamp(\n project_size_to_pixel(instanceStrokeWidths * path.widthScale, path.widthUnits),\n path.widthMinPixels, path.widthMaxPixels) / 2.0);\n vec3 width;\n\n if (path.billboard) {\n // Extrude in clipspace\n vec4 prevPositionScreen = project_position_to_clipspace(prevPosition, prevPosition64Low, ZERO_OFFSET);\n vec4 currPositionScreen = project_position_to_clipspace(currPosition, currPosition64Low, ZERO_OFFSET, geometry.position);\n vec4 nextPositionScreen = project_position_to_clipspace(nextPosition, nextPosition64Low, ZERO_OFFSET);\n\n clipLine(prevPositionScreen, currPositionScreen);\n clipLine(nextPositionScreen, currPositionScreen);\n clipLine(currPositionScreen, mix(nextPositionScreen, prevPositionScreen, isEnd));\n\n width = vec3(widthPixels, 0.0);\n DECKGL_FILTER_SIZE(width, geometry);\n\n vec3 offset = getLineJoinOffset(\n prevPositionScreen.xyz / prevPositionScreen.w,\n currPositionScreen.xyz / currPositionScreen.w,\n nextPositionScreen.xyz / nextPositionScreen.w,\n project_pixel_size_to_clipspace(width.xy)\n );\n\n DECKGL_FILTER_GL_POSITION(currPositionScreen, geometry);\n gl_Position = vec4(currPositionScreen.xyz + offset * currPositionScreen.w, currPositionScreen.w);\n } else {\n // Extrude in commonspace\n prevPosition = project_position(prevPosition, prevPosition64Low);\n currPosition = project_position(currPosition, currPosition64Low);\n nextPosition = project_position(nextPosition, nextPosition64Low);\n\n width = vec3(project_pixel_size(widthPixels), 0.0);\n DECKGL_FILTER_SIZE(width, geometry);\n\n vec3 offset = getLineJoinOffset(prevPosition, currPosition, nextPosition, width.xy);\n geometry.position = vec4(currPosition + offset, 1.0);\n gl_Position = project_common_position_to_clipspace(geometry.position);\n DECKGL_FILTER_GL_POSITION(gl_Position, geometry);\n }\n DECKGL_FILTER_COLOR(vColor, geometry);\n}\n`;\n","// my-point-cloud-layer.js\n// Example to add per-point size to point cloud layer\nimport { PathLayer } from 'deck.gl';\nimport vertexShader from './vertex';\n\nexport default class WizardPathLayer extends PathLayer {\n initializeState() {\n super.initializeState();\n }\n\n getShaders() {\n return { ...super.getShaders(), vs: vertexShader };\n }\n}\n\nWizardPathLayer.layerName = 'WizardPathLayer';\n","\nexport default function earcut(data, holeIndices, dim = 2) {\n\n const hasHoles = holeIndices && holeIndices.length;\n const outerLen = hasHoles ? holeIndices[0] * dim : data.length;\n let outerNode = linkedList(data, 0, outerLen, dim, true);\n const triangles = [];\n\n if (!outerNode || outerNode.next === outerNode.prev) return triangles;\n\n let minX, minY, invSize;\n\n if (hasHoles) outerNode = eliminateHoles(data, holeIndices, outerNode, dim);\n\n // if the shape is not too simple, we'll use z-order curve hash later; calculate polygon bbox\n if (data.length > 80 * dim) {\n minX = data[0];\n minY = data[1];\n let maxX = minX;\n let maxY = minY;\n\n for (let i = dim; i < outerLen; i += dim) {\n const x = data[i];\n const y = data[i + 1];\n if (x < minX) minX = x;\n if (y < minY) minY = y;\n if (x > maxX) maxX = x;\n if (y > maxY) maxY = y;\n }\n\n // minX, minY and invSize are later used to transform coords into integers for z-order calculation\n invSize = Math.max(maxX - minX, maxY - minY);\n invSize = invSize !== 0 ? 32767 / invSize : 0;\n }\n\n earcutLinked(outerNode, triangles, dim, minX, minY, invSize, 0);\n\n return triangles;\n}\n\n// create a circular doubly linked list from polygon points in the specified winding order\nfunction linkedList(data, start, end, dim, clockwise) {\n let last;\n\n if (clockwise === (signedArea(data, start, end, dim) > 0)) {\n for (let i = start; i < end; i += dim) last = insertNode(i / dim | 0, data[i], data[i + 1], last);\n } else {\n for (let i = end - dim; i >= start; i -= dim) last = insertNode(i / dim | 0, data[i], data[i + 1], last);\n }\n\n if (last && equals(last, last.next)) {\n removeNode(last);\n last = last.next;\n }\n\n return last;\n}\n\n// eliminate colinear or duplicate points\nfunction filterPoints(start, end) {\n if (!start) return start;\n if (!end) end = start;\n\n let p = start,\n again;\n do {\n again = false;\n\n if (!p.steiner && (equals(p, p.next) || area(p.prev, p, p.next) === 0)) {\n removeNode(p);\n p = end = p.prev;\n if (p === p.next) break;\n again = true;\n\n } else {\n p = p.next;\n }\n } while (again || p !== end);\n\n return end;\n}\n\n// main ear slicing loop which triangulates a polygon (given as a linked list)\nfunction earcutLinked(ear, triangles, dim, minX, minY, invSize, pass) {\n if (!ear) return;\n\n // interlink polygon nodes in z-order\n if (!pass && invSize) indexCurve(ear, minX, minY, invSize);\n\n let stop = ear;\n\n // iterate through ears, slicing them one by one\n while (ear.prev !== ear.next) {\n const prev = ear.prev;\n const next = ear.next;\n\n if (invSize ? isEarHashed(ear, minX, minY, invSize) : isEar(ear)) {\n triangles.push(prev.i, ear.i, next.i); // cut off the triangle\n\n removeNode(ear);\n\n // skipping the next vertex leads to less sliver triangles\n ear = next.next;\n stop = next.next;\n\n continue;\n }\n\n ear = next;\n\n // if we looped through the whole remaining polygon and can't find any more ears\n if (ear === stop) {\n // try filtering points and slicing again\n if (!pass) {\n earcutLinked(filterPoints(ear), triangles, dim, minX, minY, invSize, 1);\n\n // if this didn't work, try curing all small self-intersections locally\n } else if (pass === 1) {\n ear = cureLocalIntersections(filterPoints(ear), triangles);\n earcutLinked(ear, triangles, dim, minX, minY, invSize, 2);\n\n // as a last resort, try splitting the remaining polygon into two\n } else if (pass === 2) {\n splitEarcut(ear, triangles, dim, minX, minY, invSize);\n }\n\n break;\n }\n }\n}\n\n// check whether a polygon node forms a valid ear with adjacent nodes\nfunction isEar(ear) {\n const a = ear.prev,\n b = ear,\n c = ear.next;\n\n if (area(a, b, c) >= 0) return false; // reflex, can't be an ear\n\n // now make sure we don't have other points inside the potential ear\n const ax = a.x, bx = b.x, cx = c.x, ay = a.y, by = b.y, cy = c.y;\n\n // triangle bbox\n const x0 = Math.min(ax, bx, cx),\n y0 = Math.min(ay, by, cy),\n x1 = Math.max(ax, bx, cx),\n y1 = Math.max(ay, by, cy);\n\n let p = c.next;\n while (p !== a) {\n if (p.x >= x0 && p.x <= x1 && p.y >= y0 && p.y <= y1 &&\n pointInTriangleExceptFirst(ax, ay, bx, by, cx, cy, p.x, p.y) &&\n area(p.prev, p, p.next) >= 0) return false;\n p = p.next;\n }\n\n return true;\n}\n\nfunction isEarHashed(ear, minX, minY, invSize) {\n const a = ear.prev,\n b = ear,\n c = ear.next;\n\n if (area(a, b, c) >= 0) return false; // reflex, can't be an ear\n\n const ax = a.x, bx = b.x, cx = c.x, ay = a.y, by = b.y, cy = c.y;\n\n // triangle bbox\n const x0 = Math.min(ax, bx, cx),\n y0 = Math.min(ay, by, cy),\n x1 = Math.max(ax, bx, cx),\n y1 = Math.max(ay, by, cy);\n\n // z-order range for the current triangle bbox;\n const minZ = zOrder(x0, y0, minX, minY, invSize),\n maxZ = zOrder(x1, y1, minX, minY, invSize);\n\n let p = ear.prevZ,\n n = ear.nextZ;\n\n // look for points inside the triangle in both directions\n while (p && p.z >= minZ && n && n.z <= maxZ) {\n if (p.x >= x0 && p.x <= x1 && p.y >= y0 && p.y <= y1 && p !== a && p !== c &&\n pointInTriangleExceptFirst(ax, ay, bx, by, cx, cy, p.x, p.y) && area(p.prev, p, p.next) >= 0) return false;\n p = p.prevZ;\n\n if (n.x >= x0 && n.x <= x1 && n.y >= y0 && n.y <= y1 && n !== a && n !== c &&\n pointInTriangleExceptFirst(ax, ay, bx, by, cx, cy, n.x, n.y) && area(n.prev, n, n.next) >= 0) return false;\n n = n.nextZ;\n }\n\n // look for remaining points in decreasing z-order\n while (p && p.z >= minZ) {\n if (p.x >= x0 && p.x <= x1 && p.y >= y0 && p.y <= y1 && p !== a && p !== c &&\n pointInTriangleExceptFirst(ax, ay, bx, by, cx, cy, p.x, p.y) && area(p.prev, p, p.next) >= 0) return false;\n p = p.prevZ;\n }\n\n // look for remaining points in increasing z-order\n while (n && n.z <= maxZ) {\n if (n.x >= x0 && n.x <= x1 && n.y >= y0 && n.y <= y1 && n !== a && n !== c &&\n pointInTriangleExceptFirst(ax, ay, bx, by, cx, cy, n.x, n.y) && area(n.prev, n, n.next) >= 0) return false;\n n = n.nextZ;\n }\n\n return true;\n}\n\n// go through all polygon nodes and cure small local self-intersections\nfunction cureLocalIntersections(start, triangles) {\n let p = start;\n do {\n const a = p.prev,\n b = p.next.next;\n\n if (!equals(a, b) && intersects(a, p, p.next, b) && locallyInside(a, b) && locallyInside(b, a)) {\n\n triangles.push(a.i, p.i, b.i);\n\n // remove two nodes involved\n removeNode(p);\n removeNode(p.next);\n\n p = start = b;\n }\n p = p.next;\n } while (p !== start);\n\n return filterPoints(p);\n}\n\n// try splitting polygon into two and triangulate them independently\nfunction splitEarcut(start, triangles, dim, minX, minY, invSize) {\n // look for a valid diagonal that divides the polygon into two\n let a = start;\n do {\n let b = a.next.next;\n while (b !== a.prev) {\n if (a.i !== b.i && isValidDiagonal(a, b)) {\n // split the polygon in two by the diagonal\n let c = splitPolygon(a, b);\n\n // filter colinear points around the cuts\n a = filterPoints(a, a.next);\n c = filterPoints(c, c.next);\n\n // run earcut on each half\n earcutLinked(a, triangles, dim, minX, minY, invSize, 0);\n earcutLinked(c, triangles, dim, minX, minY, invSize, 0);\n return;\n }\n b = b.next;\n }\n a = a.next;\n } while (a !== start);\n}\n\n// link every hole into the outer loop, producing a single-ring polygon without holes\nfunction eliminateHoles(data, holeIndices, outerNode, dim) {\n const queue = [];\n\n for (let i = 0, len = holeIndices.length; i < len; i++) {\n const start = holeIndices[i] * dim;\n const end = i < len - 1 ? holeIndices[i + 1] * dim : data.length;\n const list = linkedList(data, start, end, dim, false);\n if (list === list.next) list.steiner = true;\n queue.push(getLeftmost(list));\n }\n\n queue.sort(compareXYSlope);\n\n // process holes from left to right\n for (let i = 0; i < queue.length; i++) {\n outerNode = eliminateHole(queue[i], outerNode);\n }\n\n return outerNode;\n}\n\nfunction compareXYSlope(a, b) {\n let result = a.x - b.x;\n // when the left-most point of 2 holes meet at a vertex, sort the holes counterclockwise so that when we find\n // the bridge to the outer shell is always the point that they meet at.\n if (result === 0) {\n result = a.y - b.y;\n if (result === 0) {\n const aSlope = (a.next.y - a.y) / (a.next.x - a.x);\n const bSlope = (b.next.y - b.y) / (b.next.x - b.x);\n result = aSlope - bSlope;\n }\n }\n return result;\n}\n\n// find a bridge between vertices that connects hole with an outer ring and link it\nfunction eliminateHole(hole, outerNode) {\n const bridge = findHoleBridge(hole, outerNode);\n if (!bridge) {\n return outerNode;\n }\n\n const bridgeReverse = splitPolygon(bridge, hole);\n\n // filter collinear points around the cuts\n filterPoints(bridgeReverse, bridgeReverse.next);\n return filterPoints(bridge, bridge.next);\n}\n\n// David Eberly's algorithm for finding a bridge between hole and outer polygon\nfunction findHoleBridge(hole, outerNode) {\n let p = outerNode;\n const hx = hole.x;\n const hy = hole.y;\n let qx = -Infinity;\n let m;\n\n // find a segment intersected by a ray from the hole's leftmost point to the left;\n // segment's endpoint with lesser x will be potential connection point\n // unless they intersect at a vertex, then choose the vertex\n if (equals(hole, p)) return p;\n do {\n if (equals(hole, p.next)) return p.next;\n else if (hy <= p.y && hy >= p.next.y && p.next.y !== p.y) {\n const x = p.x + (hy - p.y) * (p.next.x - p.x) / (p.next.y - p.y);\n if (x <= hx && x > qx) {\n qx = x;\n m = p.x < p.next.x ? p : p.next;\n if (x === hx) return m; // hole touches outer segment; pick leftmost endpoint\n }\n }\n p = p.next;\n } while (p !== outerNode);\n\n if (!m) return null;\n\n // look for points inside the triangle of hole point, segment intersection and endpoint;\n // if there are no points found, we have a valid connection;\n // otherwise choose the point of the minimum angle with the ray as connection point\n\n const stop = m;\n const mx = m.x;\n const my = m.y;\n let tanMin = Infinity;\n\n p = m;\n\n do {\n if (hx >= p.x && p.x >= mx && hx !== p.x &&\n pointInTriangle(hy < my ? hx : qx, hy, mx, my, hy < my ? qx : hx, hy, p.x, p.y)) {\n\n const tan = Math.abs(hy - p.y) / (hx - p.x); // tangential\n\n if (locallyInside(p, hole) &&\n (tan < tanMin || (tan === tanMin && (p.x > m.x || (p.x === m.x && sectorContainsSector(m, p)))))) {\n m = p;\n tanMin = tan;\n }\n }\n\n p = p.next;\n } while (p !== stop);\n\n return m;\n}\n\n// whether sector in vertex m contains sector in vertex p in the same coordinates\nfunction sectorContainsSector(m, p) {\n return area(m.prev, m, p.prev) < 0 && area(p.next, m, m.next) < 0;\n}\n\n// interlink polygon nodes in z-order\nfunction indexCurve(start, minX, minY, invSize) {\n let p = start;\n do {\n if (p.z === 0) p.z = zOrder(p.x, p.y, minX, minY, invSize);\n p.prevZ = p.prev;\n p.nextZ = p.next;\n p = p.next;\n } while (p !== start);\n\n p.prevZ.nextZ = null;\n p.prevZ = null;\n\n sortLinked(p);\n}\n\n// Simon Tatham's linked list merge sort algorithm\n// http://www.chiark.greenend.org.uk/~sgtatham/algorithms/listsort.html\nfunction sortLinked(list) {\n let numMerges;\n let inSize = 1;\n\n do {\n let p = list;\n let e;\n list = null;\n let tail = null;\n numMerges = 0;\n\n while (p) {\n numMerges++;\n let q = p;\n let pSize = 0;\n for (let i = 0; i < inSize; i++) {\n pSize++;\n q = q.nextZ;\n if (!q) break;\n }\n let qSize = inSize;\n\n while (pSize > 0 || (qSize > 0 && q)) {\n\n if (pSize !== 0 && (qSize === 0 || !q || p.z <= q.z)) {\n e = p;\n p = p.nextZ;\n pSize--;\n } else {\n e = q;\n q = q.nextZ;\n qSize--;\n }\n\n if (tail) tail.nextZ = e;\n else list = e;\n\n e.prevZ = tail;\n tail = e;\n }\n\n p = q;\n }\n\n tail.nextZ = null;\n inSize *= 2;\n\n } while (numMerges > 1);\n\n return list;\n}\n\n// z-order of a point given coords and inverse of the longer side of data bbox\nfunction zOrder(x, y, minX, minY, invSize) {\n // coords are transformed into non-negative 15-bit integer range\n x = (x - minX) * invSize | 0;\n y = (y - minY) * invSize | 0;\n\n x = (x | (x << 8)) & 0x00FF00FF;\n x = (x | (x << 4)) & 0x0F0F0F0F;\n x = (x | (x << 2)) & 0x33333333;\n x = (x | (x << 1)) & 0x55555555;\n\n y = (y | (y << 8)) & 0x00FF00FF;\n y = (y | (y << 4)) & 0x0F0F0F0F;\n y = (y | (y << 2)) & 0x33333333;\n y = (y | (y << 1)) & 0x55555555;\n\n return x | (y << 1);\n}\n\n// find the leftmost node of a polygon ring\nfunction getLeftmost(start) {\n let p = start,\n leftmost = start;\n do {\n if (p.x < leftmost.x || (p.x === leftmost.x && p.y < leftmost.y)) leftmost = p;\n p = p.next;\n } while (p !== start);\n\n return leftmost;\n}\n\n// check if a point lies within a convex triangle\nfunction pointInTriangle(ax, ay, bx, by, cx, cy, px, py) {\n return (cx - px) * (ay - py) >= (ax - px) * (cy - py) &&\n (ax - px) * (by - py) >= (bx - px) * (ay - py) &&\n (bx - px) * (cy - py) >= (cx - px) * (by - py);\n}\n\n// check if a point lies within a convex triangle but false if its equal to the first point of the triangle\nfunction pointInTriangleExceptFirst(ax, ay, bx, by, cx, cy, px, py) {\n return !(ax === px && ay === py) && pointInTriangle(ax, ay, bx, by, cx, cy, px, py);\n}\n\n// check if a diagonal between two polygon nodes is valid (lies in polygon interior)\nfunction isValidDiagonal(a, b) {\n return a.next.i !== b.i && a.prev.i !== b.i && !intersectsPolygon(a, b) && // doesn't intersect other edges\n (locallyInside(a, b) && locallyInside(b, a) && middleInside(a, b) && // locally visible\n (area(a.prev, a, b.prev) || area(a, b.prev, b)) || // does not create opposite-facing sectors\n equals(a, b) && area(a.prev, a, a.next) > 0 && area(b.prev, b, b.next) > 0); // special zero-length case\n}\n\n// signed area of a triangle\nfunction area(p, q, r) {\n return (q.y - p.y) * (r.x - q.x) - (q.x - p.x) * (r.y - q.y);\n}\n\n// check if two points are equal\nfunction equals(p1, p2) {\n return p1.x === p2.x && p1.y === p2.y;\n}\n\n// check if two segments intersect\nfunction intersects(p1, q1, p2, q2) {\n const o1 = sign(area(p1, q1, p2));\n const o2 = sign(area(p1, q1, q2));\n const o3 = sign(area(p2, q2, p1));\n const o4 = sign(area(p2, q2, q1));\n\n if (o1 !== o2 && o3 !== o4) return true; // general case\n\n if (o1 === 0 && onSegment(p1, p2, q1)) return true; // p1, q1 and p2 are collinear and p2 lies on p1q1\n if (o2 === 0 && onSegment(p1, q2, q1)) return true; // p1, q1 and q2 are collinear and q2 lies on p1q1\n if (o3 === 0 && onSegment(p2, p1, q2)) return true; // p2, q2 and p1 are collinear and p1 lies on p2q2\n if (o4 === 0 && onSegment(p2, q1, q2)) return true; // p2, q2 and q1 are collinear and q1 lies on p2q2\n\n return false;\n}\n\n// for collinear points p, q, r, check if point q lies on segment pr\nfunction onSegment(p, q, r) {\n return q.x <= Math.max(p.x, r.x) && q.x >= Math.min(p.x, r.x) && q.y <= Math.max(p.y, r.y) && q.y >= Math.min(p.y, r.y);\n}\n\nfunction sign(num) {\n return num > 0 ? 1 : num < 0 ? -1 : 0;\n}\n\n// check if a polygon diagonal intersects any polygon segments\nfunction intersectsPolygon(a, b) {\n let p = a;\n do {\n if (p.i !== a.i && p.next.i !== a.i && p.i !== b.i && p.next.i !== b.i &&\n intersects(p, p.next, a, b)) return true;\n p = p.next;\n } while (p !== a);\n\n return false;\n}\n\n// check if a polygon diagonal is locally inside the polygon\nfunction locallyInside(a, b) {\n return area(a.prev, a, a.next) < 0 ?\n area(a, b, a.next) >= 0 && area(a, a.prev, b) >= 0 :\n area(a, b, a.prev) < 0 || area(a, a.next, b) < 0;\n}\n\n// check if the middle point of a polygon diagonal is inside the polygon\nfunction middleInside(a, b) {\n let p = a;\n let inside = false;\n const px = (a.x + b.x) / 2;\n const py = (a.y + b.y) / 2;\n do {\n if (((p.y > py) !== (p.next.y > py)) && p.next.y !== p.y &&\n (px < (p.next.x - p.x) * (py - p.y) / (p.next.y - p.y) + p.x))\n inside = !inside;\n p = p.next;\n } while (p !== a);\n\n return inside;\n}\n\n// link two polygon vertices with a bridge; if the vertices belong to the same ring, it splits polygon into two;\n// if one belongs to the outer ring and another to a hole, it merges it into a single ring\nfunction splitPolygon(a, b) {\n const a2 = createNode(a.i, a.x, a.y),\n b2 = createNode(b.i, b.x, b.y),\n an = a.next,\n bp = b.prev;\n\n a.next = b;\n b.prev = a;\n\n a2.next = an;\n an.prev = a2;\n\n b2.next = a2;\n a2.prev = b2;\n\n bp.next = b2;\n b2.prev = bp;\n\n return b2;\n}\n\n// create a node and optionally link it with previous one (in a circular doubly linked list)\nfunction insertNode(i, x, y, last) {\n const p = createNode(i, x, y);\n\n if (!last) {\n p.prev = p;\n p.next = p;\n\n } else {\n p.next = last.next;\n p.prev = last;\n last.next.prev = p;\n last.next = p;\n }\n return p;\n}\n\nfunction removeNode(p) {\n p.next.prev = p.prev;\n p.prev.next = p.next;\n\n if (p.prevZ) p.prevZ.nextZ = p.nextZ;\n if (p.nextZ) p.nextZ.prevZ = p.prevZ;\n}\n\nfunction createNode(i, x, y) {\n return {\n i, // vertex index in coordinates array\n x, y, // vertex coordinates\n prev: null, // previous and next vertex nodes in a polygon ring\n next: null,\n z: 0, // z-order curve value\n prevZ: null, // previous and next nodes in z-order\n nextZ: null,\n steiner: false // indicates whether this is a steiner point\n };\n}\n\n// return a percentage difference between the polygon area and its triangulation area;\n// used to verify correctness of triangulation\nexport function deviation(data, holeIndices, dim, triangles) {\n const hasHoles = holeIndices && holeIndices.length;\n const outerLen = hasHoles ? holeIndices[0] * dim : data.length;\n\n let polygonArea = Math.abs(signedArea(data, 0, outerLen, dim));\n if (hasHoles) {\n for (let i = 0, len = holeIndices.length; i < len; i++) {\n const start = holeIndices[i] * dim;\n const end = i < len - 1 ? holeIndices[i + 1] * dim : data.length;\n polygonArea -= Math.abs(signedArea(data, start, end, dim));\n }\n }\n\n let trianglesArea = 0;\n for (let i = 0; i < triangles.length; i += 3) {\n const a = triangles[i] * dim;\n const b = triangles[i + 1] * dim;\n const c = triangles[i + 2] * dim;\n trianglesArea += Math.abs(\n (data[a] - data[c]) * (data[b + 1] - data[a + 1]) -\n (data[a] - data[b]) * (data[c + 1] - data[a + 1]));\n }\n\n return polygonArea === 0 && trianglesArea === 0 ? 0 :\n Math.abs((trianglesArea - polygonArea) / polygonArea);\n}\n\nfunction signedArea(data, start, end, dim) {\n let sum = 0;\n for (let i = start, j = end - dim; i < end; i += dim) {\n sum += (data[j] - data[i]) * (data[i + 1] + data[j + 1]);\n j = i;\n }\n return sum;\n}\n\n// turn a polygon in a multi-dimensional array form (e.g. as in GeoJSON) into a form Earcut accepts\nexport function flatten(data) {\n const vertices = [];\n const holes = [];\n const dimensions = data[0][0].length;\n let holeIndex = 0;\n let prevLen = 0;\n\n for (const ring of data) {\n for (const p of ring) {\n for (let d = 0; d < dimensions; d++) vertices.push(p[d]);\n }\n if (prevLen) {\n holeIndex += prevLen;\n holes.push(holeIndex);\n }\n prevLen = ring.length;\n }\n return {vertices, holes, dimensions};\n}\n","export const epsilon = 1.1102230246251565e-16;\nexport const splitter = 134217729;\nexport const resulterrbound = (3 + 8 * epsilon) * epsilon;\n\n// fast_expansion_sum_zeroelim routine from original code\nexport function sum(elen, e, flen, f, h) {\n let Q, Qnew, hh, bvirt;\n let enow = e[0];\n let fnow = f[0];\n let eindex = 0;\n let findex = 0;\n if ((fnow > enow) === (fnow > -enow)) {\n Q = enow;\n enow = e[++eindex];\n } else {\n Q = fnow;\n fnow = f[++findex];\n }\n let hindex = 0;\n if (eindex < elen && findex < flen) {\n if ((fnow > enow) === (fnow > -enow)) {\n Qnew = enow + Q;\n hh = Q - (Qnew - enow);\n enow = e[++eindex];\n } else {\n Qnew = fnow + Q;\n hh = Q - (Qnew - fnow);\n fnow = f[++findex];\n }\n Q = Qnew;\n if (hh !== 0) {\n h[hindex++] = hh;\n }\n while (eindex < elen && findex < flen) {\n if ((fnow > enow) === (fnow > -enow)) {\n Qnew = Q + enow;\n bvirt = Qnew - Q;\n hh = Q - (Qnew - bvirt) + (enow - bvirt);\n enow = e[++eindex];\n } else {\n Qnew = Q + fnow;\n bvirt = Qnew - Q;\n hh = Q - (Qnew - bvirt) + (fnow - bvirt);\n fnow = f[++findex];\n }\n Q = Qnew;\n if (hh !== 0) {\n h[hindex++] = hh;\n }\n }\n }\n while (eindex < elen) {\n Qnew = Q + enow;\n bvirt = Qnew - Q;\n hh = Q - (Qnew - bvirt) + (enow - bvirt);\n enow = e[++eindex];\n Q = Qnew;\n if (hh !== 0) {\n h[hindex++] = hh;\n }\n }\n while (findex < flen) {\n Qnew = Q + fnow;\n bvirt = Qnew - Q;\n hh = Q - (Qnew - bvirt) + (fnow - bvirt);\n fnow = f[++findex];\n Q = Qnew;\n if (hh !== 0) {\n h[hindex++] = hh;\n }\n }\n if (Q !== 0 || hindex === 0) {\n h[hindex++] = Q;\n }\n return hindex;\n}\n\nexport function sum_three(alen, a, blen, b, clen, c, tmp, out) {\n return sum(sum(alen, a, blen, b, tmp), tmp, clen, c, out);\n}\n\n// scale_expansion_zeroelim routine from oritinal code\nexport function scale(elen, e, b, h) {\n let Q, sum, hh, product1, product0;\n let bvirt, c, ahi, alo, bhi, blo;\n\n c = splitter * b;\n bhi = c - (c - b);\n blo = b - bhi;\n let enow = e[0];\n Q = enow * b;\n c = splitter * enow;\n ahi = c - (c - enow);\n alo = enow - ahi;\n hh = alo * blo - (Q - ahi * bhi - alo * bhi - ahi * blo);\n let hindex = 0;\n if (hh !== 0) {\n h[hindex++] = hh;\n }\n for (let i = 1; i < elen; i++) {\n enow = e[i];\n product1 = enow * b;\n c = splitter * enow;\n ahi = c - (c - enow);\n alo = enow - ahi;\n product0 = alo * blo - (product1 - ahi * bhi - alo * bhi - ahi * blo);\n sum = Q + product0;\n bvirt = sum - Q;\n hh = Q - (sum - bvirt) + (product0 - bvirt);\n if (hh !== 0) {\n h[hindex++] = hh;\n }\n Q = product1 + sum;\n hh = sum - (Q - product1);\n if (hh !== 0) {\n h[hindex++] = hh;\n }\n }\n if (Q !== 0 || hindex === 0) {\n h[hindex++] = Q;\n }\n return hindex;\n}\n\nexport function negate(elen, e) {\n for (let i = 0; i < elen; i++) e[i] = -e[i];\n return elen;\n}\n\nexport function estimate(elen, e) {\n let Q = e[0];\n for (let i = 1; i < elen; i++) Q += e[i];\n return Q;\n}\n\nexport function vec(n) {\n return new Float64Array(n);\n}\n","import {epsilon, splitter, resulterrbound, estimate, vec, sum} from './util.js';\n\nconst ccwerrboundA = (3 + 16 * epsilon) * epsilon;\nconst ccwerrboundB = (2 + 12 * epsilon) * epsilon;\nconst ccwerrboundC = (9 + 64 * epsilon) * epsilon * epsilon;\n\nconst B = vec(4);\nconst C1 = vec(8);\nconst C2 = vec(12);\nconst D = vec(16);\nconst u = vec(4);\n\nfunction orient2dadapt(ax, ay, bx, by, cx, cy, detsum) {\n let acxtail, acytail, bcxtail, bcytail;\n let bvirt, c, ahi, alo, bhi, blo, _i, _j, _0, s1, s0, t1, t0, u3;\n\n const acx = ax - cx;\n const bcx = bx - cx;\n const acy = ay - cy;\n const bcy = by - cy;\n\n s1 = acx * bcy;\n c = splitter * acx;\n ahi = c - (c - acx);\n alo = acx - ahi;\n c = splitter * bcy;\n bhi = c - (c - bcy);\n blo = bcy - bhi;\n s0 = alo * blo - (s1 - ahi * bhi - alo * bhi - ahi * blo);\n t1 = acy * bcx;\n c = splitter * acy;\n ahi = c - (c - acy);\n alo = acy - ahi;\n c = splitter * bcx;\n bhi = c - (c - bcx);\n blo = bcx - bhi;\n t0 = alo * blo - (t1 - ahi * bhi - alo * bhi - ahi * blo);\n _i = s0 - t0;\n bvirt = s0 - _i;\n B[0] = s0 - (_i + bvirt) + (bvirt - t0);\n _j = s1 + _i;\n bvirt = _j - s1;\n _0 = s1 - (_j - bvirt) + (_i - bvirt);\n _i = _0 - t1;\n bvirt = _0 - _i;\n B[1] = _0 - (_i + bvirt) + (bvirt - t1);\n u3 = _j + _i;\n bvirt = u3 - _j;\n B[2] = _j - (u3 - bvirt) + (_i - bvirt);\n B[3] = u3;\n\n let det = estimate(4, B);\n let errbound = ccwerrboundB * detsum;\n if (det >= errbound || -det >= errbound) {\n return det;\n }\n\n bvirt = ax - acx;\n acxtail = ax - (acx + bvirt) + (bvirt - cx);\n bvirt = bx - bcx;\n bcxtail = bx - (bcx + bvirt) + (bvirt - cx);\n bvirt = ay - acy;\n acytail = ay - (acy + bvirt) + (bvirt - cy);\n bvirt = by - bcy;\n bcytail = by - (bcy + bvirt) + (bvirt - cy);\n\n if (acxtail === 0 && acytail === 0 && bcxtail === 0 && bcytail === 0) {\n return det;\n }\n\n errbound = ccwerrboundC * detsum + resulterrbound * Math.abs(det);\n det += (acx * bcytail + bcy * acxtail) - (acy * bcxtail + bcx * acytail);\n if (det >= errbound || -det >= errbound) return det;\n\n s1 = acxtail * bcy;\n c = splitter * acxtail;\n ahi = c - (c - acxtail);\n alo = acxtail - ahi;\n c = splitter * bcy;\n bhi = c - (c - bcy);\n blo = bcy - bhi;\n s0 = alo * blo - (s1 - ahi * bhi - alo * bhi - ahi * blo);\n t1 = acytail * bcx;\n c = splitter * acytail;\n ahi = c - (c - acytail);\n alo = acytail - ahi;\n c = splitter * bcx;\n bhi = c - (c - bcx);\n blo = bcx - bhi;\n t0 = alo * blo - (t1 - ahi * bhi - alo * bhi - ahi * blo);\n _i = s0 - t0;\n bvirt = s0 - _i;\n u[0] = s0 - (_i + bvirt) + (bvirt - t0);\n _j = s1 + _i;\n bvirt = _j - s1;\n _0 = s1 - (_j - bvirt) + (_i - bvirt);\n _i = _0 - t1;\n bvirt = _0 - _i;\n u[1] = _0 - (_i + bvirt) + (bvirt - t1);\n u3 = _j + _i;\n bvirt = u3 - _j;\n u[2] = _j - (u3 - bvirt) + (_i - bvirt);\n u[3] = u3;\n const C1len = sum(4, B, 4, u, C1);\n\n s1 = acx * bcytail;\n c = splitter * acx;\n ahi = c - (c - acx);\n alo = acx - ahi;\n c = splitter * bcytail;\n bhi = c - (c - bcytail);\n blo = bcytail - bhi;\n s0 = alo * blo - (s1 - ahi * bhi - alo * bhi - ahi * blo);\n t1 = acy * bcxtail;\n c = splitter * acy;\n ahi = c - (c - acy);\n alo = acy - ahi;\n c = splitter * bcxtail;\n bhi = c - (c - bcxtail);\n blo = bcxtail - bhi;\n t0 = alo * blo - (t1 - ahi * bhi - alo * bhi - ahi * blo);\n _i = s0 - t0;\n bvirt = s0 - _i;\n u[0] = s0 - (_i + bvirt) + (bvirt - t0);\n _j = s1 + _i;\n bvirt = _j - s1;\n _0 = s1 - (_j - bvirt) + (_i - bvirt);\n _i = _0 - t1;\n bvirt = _0 - _i;\n u[1] = _0 - (_i + bvirt) + (bvirt - t1);\n u3 = _j + _i;\n bvirt = u3 - _j;\n u[2] = _j - (u3 - bvirt) + (_i - bvirt);\n u[3] = u3;\n const C2len = sum(C1len, C1, 4, u, C2);\n\n s1 = acxtail * bcytail;\n c = splitter * acxtail;\n ahi = c - (c - acxtail);\n alo = acxtail - ahi;\n c = splitter * bcytail;\n bhi = c - (c - bcytail);\n blo = bcytail - bhi;\n s0 = alo * blo - (s1 - ahi * bhi - alo * bhi - ahi * blo);\n t1 = acytail * bcxtail;\n c = splitter * acytail;\n ahi = c - (c - acytail);\n alo = acytail - ahi;\n c = splitter * bcxtail;\n bhi = c - (c - bcxtail);\n blo = bcxtail - bhi;\n t0 = alo * blo - (t1 - ahi * bhi - alo * bhi - ahi * blo);\n _i = s0 - t0;\n bvirt = s0 - _i;\n u[0] = s0 - (_i + bvirt) + (bvirt - t0);\n _j = s1 + _i;\n bvirt = _j - s1;\n _0 = s1 - (_j - bvirt) + (_i - bvirt);\n _i = _0 - t1;\n bvirt = _0 - _i;\n u[1] = _0 - (_i + bvirt) + (bvirt - t1);\n u3 = _j + _i;\n bvirt = u3 - _j;\n u[2] = _j - (u3 - bvirt) + (_i - bvirt);\n u[3] = u3;\n const Dlen = sum(C2len, C2, 4, u, D);\n\n return D[Dlen - 1];\n}\n\nexport function orient2d(ax, ay, bx, by, cx, cy) {\n const detleft = (ay - cy) * (bx - cx);\n const detright = (ax - cx) * (by - cy);\n const det = detleft - detright;\n\n const detsum = Math.abs(detleft + detright);\n if (Math.abs(det) >= ccwerrboundA * detsum) return det;\n\n return -orient2dadapt(ax, ay, bx, by, cx, cy, detsum);\n}\n\nexport function orient2dfast(ax, ay, bx, by, cx, cy) {\n return (ay - cy) * (bx - cx) - (ax - cx) * (by - cy);\n}\n","import {epsilon, splitter, resulterrbound, estimate, vec, sum, scale} from './util.js';\n\nconst o3derrboundA = (7 + 56 * epsilon) * epsilon;\nconst o3derrboundB = (3 + 28 * epsilon) * epsilon;\nconst o3derrboundC = (26 + 288 * epsilon) * epsilon * epsilon;\n\nconst bc = vec(4);\nconst ca = vec(4);\nconst ab = vec(4);\nconst at_b = vec(4);\nconst at_c = vec(4);\nconst bt_c = vec(4);\nconst bt_a = vec(4);\nconst ct_a = vec(4);\nconst ct_b = vec(4);\nconst bct = vec(8);\nconst cat = vec(8);\nconst abt = vec(8);\nconst u = vec(4);\n\nconst _8 = vec(8);\nconst _8b = vec(8);\nconst _16 = vec(16);\nconst _12 = vec(12);\n\nlet fin = vec(192);\nlet fin2 = vec(192);\n\nfunction finadd(finlen, alen, a) {\n finlen = sum(finlen, fin, alen, a, fin2);\n const tmp = fin; fin = fin2; fin2 = tmp;\n return finlen;\n}\n\nfunction tailinit(xtail, ytail, ax, ay, bx, by, a, b) {\n let bvirt, c, ahi, alo, bhi, blo, _i, _j, _k, _0, s1, s0, t1, t0, u3, negate;\n if (xtail === 0) {\n if (ytail === 0) {\n a[0] = 0;\n b[0] = 0;\n return 1;\n }\n negate = -ytail;\n s1 = negate * ax;\n c = splitter * negate;\n ahi = c - (c - negate);\n alo = negate - ahi;\n c = splitter * ax;\n bhi = c - (c - ax);\n blo = ax - bhi;\n a[0] = alo * blo - (s1 - ahi * bhi - alo * bhi - ahi * blo);\n a[1] = s1;\n s1 = ytail * bx;\n c = splitter * ytail;\n ahi = c - (c - ytail);\n alo = ytail - ahi;\n c = splitter * bx;\n bhi = c - (c - bx);\n blo = bx - bhi;\n b[0] = alo * blo - (s1 - ahi * bhi - alo * bhi - ahi * blo);\n b[1] = s1;\n return 2;\n }\n if (ytail === 0) {\n s1 = xtail * ay;\n c = splitter * xtail;\n ahi = c - (c - xtail);\n alo = xtail - ahi;\n c = splitter * ay;\n bhi = c - (c - ay);\n blo = ay - bhi;\n a[0] = alo * blo - (s1 - ahi * bhi - alo * bhi - ahi * blo);\n a[1] = s1;\n negate = -xtail;\n s1 = negate * by;\n c = splitter * negate;\n ahi = c - (c - negate);\n alo = negate - ahi;\n c = splitter * by;\n bhi = c - (c - by);\n blo = by - bhi;\n b[0] = alo * blo - (s1 - ahi * bhi - alo * bhi - ahi * blo);\n b[1] = s1;\n return 2;\n }\n s1 = xtail * ay;\n c = splitter * xtail;\n ahi = c - (c - xtail);\n alo = xtail - ahi;\n c = splitter * ay;\n bhi = c - (c - ay);\n blo = ay - bhi;\n s0 = alo * blo - (s1 - ahi * bhi - alo * bhi - ahi * blo);\n t1 = ytail * ax;\n c = splitter * ytail;\n ahi = c - (c - ytail);\n alo = ytail - ahi;\n c = splitter * ax;\n bhi = c - (c - ax);\n blo = ax - bhi;\n t0 = alo * blo - (t1 - ahi * bhi - alo * bhi - ahi * blo);\n _i = s0 - t0;\n bvirt = s0 - _i;\n a[0] = s0 - (_i + bvirt) + (bvirt - t0);\n _j = s1 + _i;\n bvirt = _j - s1;\n _0 = s1 - (_j - bvirt) + (_i - bvirt);\n _i = _0 - t1;\n bvirt = _0 - _i;\n a[1] = _0 - (_i + bvirt) + (bvirt - t1);\n u3 = _j + _i;\n bvirt = u3 - _j;\n a[2] = _j - (u3 - bvirt) + (_i - bvirt);\n a[3] = u3;\n s1 = ytail * bx;\n c = splitter * ytail;\n ahi = c - (c - ytail);\n alo = ytail - ahi;\n c = splitter * bx;\n bhi = c - (c - bx);\n blo = bx - bhi;\n s0 = alo * blo - (s1 - ahi * bhi - alo * bhi - ahi * blo);\n t1 = xtail * by;\n c = splitter * xtail;\n ahi = c - (c - xtail);\n alo = xtail - ahi;\n c = splitter * by;\n bhi = c - (c - by);\n blo = by - bhi;\n t0 = alo * blo - (t1 - ahi * bhi - alo * bhi - ahi * blo);\n _i = s0 - t0;\n bvirt = s0 - _i;\n b[0] = s0 - (_i + bvirt) + (bvirt - t0);\n _j = s1 + _i;\n bvirt = _j - s1;\n _0 = s1 - (_j - bvirt) + (_i - bvirt);\n _i = _0 - t1;\n bvirt = _0 - _i;\n b[1] = _0 - (_i + bvirt) + (bvirt - t1);\n u3 = _j + _i;\n bvirt = u3 - _j;\n b[2] = _j - (u3 - bvirt) + (_i - bvirt);\n b[3] = u3;\n return 4;\n}\n\nfunction tailadd(finlen, a, b, k, z) {\n let bvirt, c, ahi, alo, bhi, blo, _i, _j, _k, _0, s1, s0, u3;\n s1 = a * b;\n c = splitter * a;\n ahi = c - (c - a);\n alo = a - ahi;\n c = splitter * b;\n bhi = c - (c - b);\n blo = b - bhi;\n s0 = alo * blo - (s1 - ahi * bhi - alo * bhi - ahi * blo);\n c = splitter * k;\n bhi = c - (c - k);\n blo = k - bhi;\n _i = s0 * k;\n c = splitter * s0;\n ahi = c - (c - s0);\n alo = s0 - ahi;\n u[0] = alo * blo - (_i - ahi * bhi - alo * bhi - ahi * blo);\n _j = s1 * k;\n c = splitter * s1;\n ahi = c - (c - s1);\n alo = s1 - ahi;\n _0 = alo * blo - (_j - ahi * bhi - alo * bhi - ahi * blo);\n _k = _i + _0;\n bvirt = _k - _i;\n u[1] = _i - (_k - bvirt) + (_0 - bvirt);\n u3 = _j + _k;\n u[2] = _k - (u3 - _j);\n u[3] = u3;\n finlen = finadd(finlen, 4, u);\n if (z !== 0) {\n c = splitter * z;\n bhi = c - (c - z);\n blo = z - bhi;\n _i = s0 * z;\n c = splitter * s0;\n ahi = c - (c - s0);\n alo = s0 - ahi;\n u[0] = alo * blo - (_i - ahi * bhi - alo * bhi - ahi * blo);\n _j = s1 * z;\n c = splitter * s1;\n ahi = c - (c - s1);\n alo = s1 - ahi;\n _0 = alo * blo - (_j - ahi * bhi - alo * bhi - ahi * blo);\n _k = _i + _0;\n bvirt = _k - _i;\n u[1] = _i - (_k - bvirt) + (_0 - bvirt);\n u3 = _j + _k;\n u[2] = _k - (u3 - _j);\n u[3] = u3;\n finlen = finadd(finlen, 4, u);\n }\n return finlen;\n}\n\nfunction orient3dadapt(ax, ay, az, bx, by, bz, cx, cy, cz, dx, dy, dz, permanent) {\n let finlen;\n let adxtail, bdxtail, cdxtail;\n let adytail, bdytail, cdytail;\n let adztail, bdztail, cdztail;\n let bvirt, c, ahi, alo, bhi, blo, _i, _j, _k, _0, s1, s0, t1, t0, u3;\n\n const adx = ax - dx;\n const bdx = bx - dx;\n const cdx = cx - dx;\n const ady = ay - dy;\n const bdy = by - dy;\n const cdy = cy - dy;\n const adz = az - dz;\n const bdz = bz - dz;\n const cdz = cz - dz;\n\n s1 = bdx * cdy;\n c = splitter * bdx;\n ahi = c - (c - bdx);\n alo = bdx - ahi;\n c = splitter * cdy;\n bhi = c - (c - cdy);\n blo = cdy - bhi;\n s0 = alo * blo - (s1 - ahi * bhi - alo * bhi - ahi * blo);\n t1 = cdx * bdy;\n c = splitter * cdx;\n ahi = c - (c - cdx);\n alo = cdx - ahi;\n c = splitter * bdy;\n bhi = c - (c - bdy);\n blo = bdy - bhi;\n t0 = alo * blo - (t1 - ahi * bhi - alo * bhi - ahi * blo);\n _i = s0 - t0;\n bvirt = s0 - _i;\n bc[0] = s0 - (_i + bvirt) + (bvirt - t0);\n _j = s1 + _i;\n bvirt = _j - s1;\n _0 = s1 - (_j - bvirt) + (_i - bvirt);\n _i = _0 - t1;\n bvirt = _0 - _i;\n bc[1] = _0 - (_i + bvirt) + (bvirt - t1);\n u3 = _j + _i;\n bvirt = u3 - _j;\n bc[2] = _j - (u3 - bvirt) + (_i - bvirt);\n bc[3] = u3;\n s1 = cdx * ady;\n c = splitter * cdx;\n ahi = c - (c - cdx);\n alo = cdx - ahi;\n c = splitter * ady;\n bhi = c - (c - ady);\n blo = ady - bhi;\n s0 = alo * blo - (s1 - ahi * bhi - alo * bhi - ahi * blo);\n t1 = adx * cdy;\n c = splitter * adx;\n ahi = c - (c - adx);\n alo = adx - ahi;\n c = splitter * cdy;\n bhi = c - (c - cdy);\n blo = cdy - bhi;\n t0 = alo * blo - (t1 - ahi * bhi - alo * bhi - ahi * blo);\n _i = s0 - t0;\n bvirt = s0 - _i;\n ca[0] = s0 - (_i + bvirt) + (bvirt - t0);\n _j = s1 + _i;\n bvirt = _j - s1;\n _0 = s1 - (_j - bvirt) + (_i - bvirt);\n _i = _0 - t1;\n bvirt = _0 - _i;\n ca[1] = _0 - (_i + bvirt) + (bvirt - t1);\n u3 = _j + _i;\n bvirt = u3 - _j;\n ca[2] = _j - (u3 - bvirt) + (_i - bvirt);\n ca[3] = u3;\n s1 = adx * bdy;\n c = splitter * adx;\n ahi = c - (c - adx);\n alo = adx - ahi;\n c = splitter * bdy;\n bhi = c - (c - bdy);\n blo = bdy - bhi;\n s0 = alo * blo - (s1 - ahi * bhi - alo * bhi - ahi * blo);\n t1 = bdx * ady;\n c = splitter * bdx;\n ahi = c - (c - bdx);\n alo = bdx - ahi;\n c = splitter * ady;\n bhi = c - (c - ady);\n blo = ady - bhi;\n t0 = alo * blo - (t1 - ahi * bhi - alo * bhi - ahi * blo);\n _i = s0 - t0;\n bvirt = s0 - _i;\n ab[0] = s0 - (_i + bvirt) + (bvirt - t0);\n _j = s1 + _i;\n bvirt = _j - s1;\n _0 = s1 - (_j - bvirt) + (_i - bvirt);\n _i = _0 - t1;\n bvirt = _0 - _i;\n ab[1] = _0 - (_i + bvirt) + (bvirt - t1);\n u3 = _j + _i;\n bvirt = u3 - _j;\n ab[2] = _j - (u3 - bvirt) + (_i - bvirt);\n ab[3] = u3;\n\n finlen = sum(\n sum(\n scale(4, bc, adz, _8), _8,\n scale(4, ca, bdz, _8b), _8b, _16), _16,\n scale(4, ab, cdz, _8), _8, fin);\n\n let det = estimate(finlen, fin);\n let errbound = o3derrboundB * permanent;\n if (det >= errbound || -det >= errbound) {\n return det;\n }\n\n bvirt = ax - adx;\n adxtail = ax - (adx + bvirt) + (bvirt - dx);\n bvirt = bx - bdx;\n bdxtail = bx - (bdx + bvirt) + (bvirt - dx);\n bvirt = cx - cdx;\n cdxtail = cx - (cdx + bvirt) + (bvirt - dx);\n bvirt = ay - ady;\n adytail = ay - (ady + bvirt) + (bvirt - dy);\n bvirt = by - bdy;\n bdytail = by - (bdy + bvirt) + (bvirt - dy);\n bvirt = cy - cdy;\n cdytail = cy - (cdy + bvirt) + (bvirt - dy);\n bvirt = az - adz;\n adztail = az - (adz + bvirt) + (bvirt - dz);\n bvirt = bz - bdz;\n bdztail = bz - (bdz + bvirt) + (bvirt - dz);\n bvirt = cz - cdz;\n cdztail = cz - (cdz + bvirt) + (bvirt - dz);\n\n if (adxtail === 0 && bdxtail === 0 && cdxtail === 0 &&\n adytail === 0 && bdytail === 0 && cdytail === 0 &&\n adztail === 0 && bdztail === 0 && cdztail === 0) {\n return det;\n }\n\n errbound = o3derrboundC * permanent + resulterrbound * Math.abs(det);\n det +=\n adz * (bdx * cdytail + cdy * bdxtail - (bdy * cdxtail + cdx * bdytail)) + adztail * (bdx * cdy - bdy * cdx) +\n bdz * (cdx * adytail + ady * cdxtail - (cdy * adxtail + adx * cdytail)) + bdztail * (cdx * ady - cdy * adx) +\n cdz * (adx * bdytail + bdy * adxtail - (ady * bdxtail + bdx * adytail)) + cdztail * (adx * bdy - ady * bdx);\n if (det >= errbound || -det >= errbound) {\n return det;\n }\n\n const at_len = tailinit(adxtail, adytail, bdx, bdy, cdx, cdy, at_b, at_c);\n const bt_len = tailinit(bdxtail, bdytail, cdx, cdy, adx, ady, bt_c, bt_a);\n const ct_len = tailinit(cdxtail, cdytail, adx, ady, bdx, bdy, ct_a, ct_b);\n\n const bctlen = sum(bt_len, bt_c, ct_len, ct_b, bct);\n finlen = finadd(finlen, scale(bctlen, bct, adz, _16), _16);\n\n const catlen = sum(ct_len, ct_a, at_len, at_c, cat);\n finlen = finadd(finlen, scale(catlen, cat, bdz, _16), _16);\n\n const abtlen = sum(at_len, at_b, bt_len, bt_a, abt);\n finlen = finadd(finlen, scale(abtlen, abt, cdz, _16), _16);\n\n if (adztail !== 0) {\n finlen = finadd(finlen, scale(4, bc, adztail, _12), _12);\n finlen = finadd(finlen, scale(bctlen, bct, adztail, _16), _16);\n }\n if (bdztail !== 0) {\n finlen = finadd(finlen, scale(4, ca, bdztail, _12), _12);\n finlen = finadd(finlen, scale(catlen, cat, bdztail, _16), _16);\n }\n if (cdztail !== 0) {\n finlen = finadd(finlen, scale(4, ab, cdztail, _12), _12);\n finlen = finadd(finlen, scale(abtlen, abt, cdztail, _16), _16);\n }\n\n if (adxtail !== 0) {\n if (bdytail !== 0) {\n finlen = tailadd(finlen, adxtail, bdytail, cdz, cdztail);\n }\n if (cdytail !== 0) {\n finlen = tailadd(finlen, -adxtail, cdytail, bdz, bdztail);\n }\n }\n if (bdxtail !== 0) {\n if (cdytail !== 0) {\n finlen = tailadd(finlen, bdxtail, cdytail, adz, adztail);\n }\n if (adytail !== 0) {\n finlen = tailadd(finlen, -bdxtail, adytail, cdz, cdztail);\n }\n }\n if (cdxtail !== 0) {\n if (adytail !== 0) {\n finlen = tailadd(finlen, cdxtail, adytail, bdz, bdztail);\n }\n if (bdytail !== 0) {\n finlen = tailadd(finlen, -cdxtail, bdytail, adz, adztail);\n }\n }\n\n return fin[finlen - 1];\n}\n\nexport function orient3d(ax, ay, az, bx, by, bz, cx, cy, cz, dx, dy, dz) {\n const adx = ax - dx;\n const bdx = bx - dx;\n const cdx = cx - dx;\n const ady = ay - dy;\n const bdy = by - dy;\n const cdy = cy - dy;\n const adz = az - dz;\n const bdz = bz - dz;\n const cdz = cz - dz;\n\n const bdxcdy = bdx * cdy;\n const cdxbdy = cdx * bdy;\n\n const cdxady = cdx * ady;\n const adxcdy = adx * cdy;\n\n const adxbdy = adx * bdy;\n const bdxady = bdx * ady;\n\n const det =\n adz * (bdxcdy - cdxbdy) +\n bdz * (cdxady - adxcdy) +\n cdz * (adxbdy - bdxady);\n\n const permanent =\n (Math.abs(bdxcdy) + Math.abs(cdxbdy)) * Math.abs(adz) +\n (Math.abs(cdxady) + Math.abs(adxcdy)) * Math.abs(bdz) +\n (Math.abs(adxbdy) + Math.abs(bdxady)) * Math.abs(cdz);\n\n const errbound = o3derrboundA * permanent;\n if (det > errbound || -det > errbound) {\n return det;\n }\n\n return orient3dadapt(ax, ay, az, bx, by, bz, cx, cy, cz, dx, dy, dz, permanent);\n}\n\nexport function orient3dfast(ax, ay, az, bx, by, bz, cx, cy, cz, dx, dy, dz) {\n const adx = ax - dx;\n const bdx = bx - dx;\n const cdx = cx - dx;\n const ady = ay - dy;\n const bdy = by - dy;\n const cdy = cy - dy;\n const adz = az - dz;\n const bdz = bz - dz;\n const cdz = cz - dz;\n\n return adx * (bdy * cdz - bdz * cdy) +\n bdx * (cdy * adz - cdz * ady) +\n cdx * (ady * bdz - adz * bdy);\n}\n","import {epsilon, splitter, resulterrbound, estimate, vec, sum, sum_three, scale} from './util.js';\n\nconst iccerrboundA = (10 + 96 * epsilon) * epsilon;\nconst iccerrboundB = (4 + 48 * epsilon) * epsilon;\nconst iccerrboundC = (44 + 576 * epsilon) * epsilon * epsilon;\n\nconst bc = vec(4);\nconst ca = vec(4);\nconst ab = vec(4);\nconst aa = vec(4);\nconst bb = vec(4);\nconst cc = vec(4);\nconst u = vec(4);\nconst v = vec(4);\nconst axtbc = vec(8);\nconst aytbc = vec(8);\nconst bxtca = vec(8);\nconst bytca = vec(8);\nconst cxtab = vec(8);\nconst cytab = vec(8);\nconst abt = vec(8);\nconst bct = vec(8);\nconst cat = vec(8);\nconst abtt = vec(4);\nconst bctt = vec(4);\nconst catt = vec(4);\n\nconst _8 = vec(8);\nconst _16 = vec(16);\nconst _16b = vec(16);\nconst _16c = vec(16);\nconst _32 = vec(32);\nconst _32b = vec(32);\nconst _48 = vec(48);\nconst _64 = vec(64);\n\nlet fin = vec(1152);\nlet fin2 = vec(1152);\n\nfunction finadd(finlen, a, alen) {\n finlen = sum(finlen, fin, a, alen, fin2);\n const tmp = fin; fin = fin2; fin2 = tmp;\n return finlen;\n}\n\nfunction incircleadapt(ax, ay, bx, by, cx, cy, dx, dy, permanent) {\n let finlen;\n let adxtail, bdxtail, cdxtail, adytail, bdytail, cdytail;\n let axtbclen, aytbclen, bxtcalen, bytcalen, cxtablen, cytablen;\n let abtlen, bctlen, catlen;\n let abttlen, bcttlen, cattlen;\n let n1, n0;\n\n let bvirt, c, ahi, alo, bhi, blo, _i, _j, _0, s1, s0, t1, t0, u3;\n\n const adx = ax - dx;\n const bdx = bx - dx;\n const cdx = cx - dx;\n const ady = ay - dy;\n const bdy = by - dy;\n const cdy = cy - dy;\n\n s1 = bdx * cdy;\n c = splitter * bdx;\n ahi = c - (c - bdx);\n alo = bdx - ahi;\n c = splitter * cdy;\n bhi = c - (c - cdy);\n blo = cdy - bhi;\n s0 = alo * blo - (s1 - ahi * bhi - alo * bhi - ahi * blo);\n t1 = cdx * bdy;\n c = splitter * cdx;\n ahi = c - (c - cdx);\n alo = cdx - ahi;\n c = splitter * bdy;\n bhi = c - (c - bdy);\n blo = bdy - bhi;\n t0 = alo * blo - (t1 - ahi * bhi - alo * bhi - ahi * blo);\n _i = s0 - t0;\n bvirt = s0 - _i;\n bc[0] = s0 - (_i + bvirt) + (bvirt - t0);\n _j = s1 + _i;\n bvirt = _j - s1;\n _0 = s1 - (_j - bvirt) + (_i - bvirt);\n _i = _0 - t1;\n bvirt = _0 - _i;\n bc[1] = _0 - (_i + bvirt) + (bvirt - t1);\n u3 = _j + _i;\n bvirt = u3 - _j;\n bc[2] = _j - (u3 - bvirt) + (_i - bvirt);\n bc[3] = u3;\n s1 = cdx * ady;\n c = splitter * cdx;\n ahi = c - (c - cdx);\n alo = cdx - ahi;\n c = splitter * ady;\n bhi = c - (c - ady);\n blo = ady - bhi;\n s0 = alo * blo - (s1 - ahi * bhi - alo * bhi - ahi * blo);\n t1 = adx * cdy;\n c = splitter * adx;\n ahi = c - (c - adx);\n alo = adx - ahi;\n c = splitter * cdy;\n bhi = c - (c - cdy);\n blo = cdy - bhi;\n t0 = alo * blo - (t1 - ahi * bhi - alo * bhi - ahi * blo);\n _i = s0 - t0;\n bvirt = s0 - _i;\n ca[0] = s0 - (_i + bvirt) + (bvirt - t0);\n _j = s1 + _i;\n bvirt = _j - s1;\n _0 = s1 - (_j - bvirt) + (_i - bvirt);\n _i = _0 - t1;\n bvirt = _0 - _i;\n ca[1] = _0 - (_i + bvirt) + (bvirt - t1);\n u3 = _j + _i;\n bvirt = u3 - _j;\n ca[2] = _j - (u3 - bvirt) + (_i - bvirt);\n ca[3] = u3;\n s1 = adx * bdy;\n c = splitter * adx;\n ahi = c - (c - adx);\n alo = adx - ahi;\n c = splitter * bdy;\n bhi = c - (c - bdy);\n blo = bdy - bhi;\n s0 = alo * blo - (s1 - ahi * bhi - alo * bhi - ahi * blo);\n t1 = bdx * ady;\n c = splitter * bdx;\n ahi = c - (c - bdx);\n alo = bdx - ahi;\n c = splitter * ady;\n bhi = c - (c - ady);\n blo = ady - bhi;\n t0 = alo * blo - (t1 - ahi * bhi - alo * bhi - ahi * blo);\n _i = s0 - t0;\n bvirt = s0 - _i;\n ab[0] = s0 - (_i + bvirt) + (bvirt - t0);\n _j = s1 + _i;\n bvirt = _j - s1;\n _0 = s1 - (_j - bvirt) + (_i - bvirt);\n _i = _0 - t1;\n bvirt = _0 - _i;\n ab[1] = _0 - (_i + bvirt) + (bvirt - t1);\n u3 = _j + _i;\n bvirt = u3 - _j;\n ab[2] = _j - (u3 - bvirt) + (_i - bvirt);\n ab[3] = u3;\n\n finlen = sum(\n sum(\n sum(\n scale(scale(4, bc, adx, _8), _8, adx, _16), _16,\n scale(scale(4, bc, ady, _8), _8, ady, _16b), _16b, _32), _32,\n sum(\n scale(scale(4, ca, bdx, _8), _8, bdx, _16), _16,\n scale(scale(4, ca, bdy, _8), _8, bdy, _16b), _16b, _32b), _32b, _64), _64,\n sum(\n scale(scale(4, ab, cdx, _8), _8, cdx, _16), _16,\n scale(scale(4, ab, cdy, _8), _8, cdy, _16b), _16b, _32), _32, fin);\n\n let det = estimate(finlen, fin);\n let errbound = iccerrboundB * permanent;\n if (det >= errbound || -det >= errbound) {\n return det;\n }\n\n bvirt = ax - adx;\n adxtail = ax - (adx + bvirt) + (bvirt - dx);\n bvirt = ay - ady;\n adytail = ay - (ady + bvirt) + (bvirt - dy);\n bvirt = bx - bdx;\n bdxtail = bx - (bdx + bvirt) + (bvirt - dx);\n bvirt = by - bdy;\n bdytail = by - (bdy + bvirt) + (bvirt - dy);\n bvirt = cx - cdx;\n cdxtail = cx - (cdx + bvirt) + (bvirt - dx);\n bvirt = cy - cdy;\n cdytail = cy - (cdy + bvirt) + (bvirt - dy);\n if (adxtail === 0 && bdxtail === 0 && cdxtail === 0 && adytail === 0 && bdytail === 0 && cdytail === 0) {\n return det;\n }\n\n errbound = iccerrboundC * permanent + resulterrbound * Math.abs(det);\n det += ((adx * adx + ady * ady) * ((bdx * cdytail + cdy * bdxtail) - (bdy * cdxtail + cdx * bdytail)) +\n 2 * (adx * adxtail + ady * adytail) * (bdx * cdy - bdy * cdx)) +\n ((bdx * bdx + bdy * bdy) * ((cdx * adytail + ady * cdxtail) - (cdy * adxtail + adx * cdytail)) +\n 2 * (bdx * bdxtail + bdy * bdytail) * (cdx * ady - cdy * adx)) +\n ((cdx * cdx + cdy * cdy) * ((adx * bdytail + bdy * adxtail) - (ady * bdxtail + bdx * adytail)) +\n 2 * (cdx * cdxtail + cdy * cdytail) * (adx * bdy - ady * bdx));\n\n if (det >= errbound || -det >= errbound) {\n return det;\n }\n\n if (bdxtail !== 0 || bdytail !== 0 || cdxtail !== 0 || cdytail !== 0) {\n s1 = adx * adx;\n c = splitter * adx;\n ahi = c - (c - adx);\n alo = adx - ahi;\n s0 = alo * alo - (s1 - ahi * ahi - (ahi + ahi) * alo);\n t1 = ady * ady;\n c = splitter * ady;\n ahi = c - (c - ady);\n alo = ady - ahi;\n t0 = alo * alo - (t1 - ahi * ahi - (ahi + ahi) * alo);\n _i = s0 + t0;\n bvirt = _i - s0;\n aa[0] = s0 - (_i - bvirt) + (t0 - bvirt);\n _j = s1 + _i;\n bvirt = _j - s1;\n _0 = s1 - (_j - bvirt) + (_i - bvirt);\n _i = _0 + t1;\n bvirt = _i - _0;\n aa[1] = _0 - (_i - bvirt) + (t1 - bvirt);\n u3 = _j + _i;\n bvirt = u3 - _j;\n aa[2] = _j - (u3 - bvirt) + (_i - bvirt);\n aa[3] = u3;\n }\n if (cdxtail !== 0 || cdytail !== 0 || adxtail !== 0 || adytail !== 0) {\n s1 = bdx * bdx;\n c = splitter * bdx;\n ahi = c - (c - bdx);\n alo = bdx - ahi;\n s0 = alo * alo - (s1 - ahi * ahi - (ahi + ahi) * alo);\n t1 = bdy * bdy;\n c = splitter * bdy;\n ahi = c - (c - bdy);\n alo = bdy - ahi;\n t0 = alo * alo - (t1 - ahi * ahi - (ahi + ahi) * alo);\n _i = s0 + t0;\n bvirt = _i - s0;\n bb[0] = s0 - (_i - bvirt) + (t0 - bvirt);\n _j = s1 + _i;\n bvirt = _j - s1;\n _0 = s1 - (_j - bvirt) + (_i - bvirt);\n _i = _0 + t1;\n bvirt = _i - _0;\n bb[1] = _0 - (_i - bvirt) + (t1 - bvirt);\n u3 = _j + _i;\n bvirt = u3 - _j;\n bb[2] = _j - (u3 - bvirt) + (_i - bvirt);\n bb[3] = u3;\n }\n if (adxtail !== 0 || adytail !== 0 || bdxtail !== 0 || bdytail !== 0) {\n s1 = cdx * cdx;\n c = splitter * cdx;\n ahi = c - (c - cdx);\n alo = cdx - ahi;\n s0 = alo * alo - (s1 - ahi * ahi - (ahi + ahi) * alo);\n t1 = cdy * cdy;\n c = splitter * cdy;\n ahi = c - (c - cdy);\n alo = cdy - ahi;\n t0 = alo * alo - (t1 - ahi * ahi - (ahi + ahi) * alo);\n _i = s0 + t0;\n bvirt = _i - s0;\n cc[0] = s0 - (_i - bvirt) + (t0 - bvirt);\n _j = s1 + _i;\n bvirt = _j - s1;\n _0 = s1 - (_j - bvirt) + (_i - bvirt);\n _i = _0 + t1;\n bvirt = _i - _0;\n cc[1] = _0 - (_i - bvirt) + (t1 - bvirt);\n u3 = _j + _i;\n bvirt = u3 - _j;\n cc[2] = _j - (u3 - bvirt) + (_i - bvirt);\n cc[3] = u3;\n }\n\n if (adxtail !== 0) {\n axtbclen = scale(4, bc, adxtail, axtbc);\n finlen = finadd(finlen, sum_three(\n scale(axtbclen, axtbc, 2 * adx, _16), _16,\n scale(scale(4, cc, adxtail, _8), _8, bdy, _16b), _16b,\n scale(scale(4, bb, adxtail, _8), _8, -cdy, _16c), _16c, _32, _48), _48);\n }\n if (adytail !== 0) {\n aytbclen = scale(4, bc, adytail, aytbc);\n finlen = finadd(finlen, sum_three(\n scale(aytbclen, aytbc, 2 * ady, _16), _16,\n scale(scale(4, bb, adytail, _8), _8, cdx, _16b), _16b,\n scale(scale(4, cc, adytail, _8), _8, -bdx, _16c), _16c, _32, _48), _48);\n }\n if (bdxtail !== 0) {\n bxtcalen = scale(4, ca, bdxtail, bxtca);\n finlen = finadd(finlen, sum_three(\n scale(bxtcalen, bxtca, 2 * bdx, _16), _16,\n scale(scale(4, aa, bdxtail, _8), _8, cdy, _16b), _16b,\n scale(scale(4, cc, bdxtail, _8), _8, -ady, _16c), _16c, _32, _48), _48);\n }\n if (bdytail !== 0) {\n bytcalen = scale(4, ca, bdytail, bytca);\n finlen = finadd(finlen, sum_three(\n scale(bytcalen, bytca, 2 * bdy, _16), _16,\n scale(scale(4, cc, bdytail, _8), _8, adx, _16b), _16b,\n scale(scale(4, aa, bdytail, _8), _8, -cdx, _16c), _16c, _32, _48), _48);\n }\n if (cdxtail !== 0) {\n cxtablen = scale(4, ab, cdxtail, cxtab);\n finlen = finadd(finlen, sum_three(\n scale(cxtablen, cxtab, 2 * cdx, _16), _16,\n scale(scale(4, bb, cdxtail, _8), _8, ady, _16b), _16b,\n scale(scale(4, aa, cdxtail, _8), _8, -bdy, _16c), _16c, _32, _48), _48);\n }\n if (cdytail !== 0) {\n cytablen = scale(4, ab, cdytail, cytab);\n finlen = finadd(finlen, sum_three(\n scale(cytablen, cytab, 2 * cdy, _16), _16,\n scale(scale(4, aa, cdytail, _8), _8, bdx, _16b), _16b,\n scale(scale(4, bb, cdytail, _8), _8, -adx, _16c), _16c, _32, _48), _48);\n }\n\n if (adxtail !== 0 || adytail !== 0) {\n if (bdxtail !== 0 || bdytail !== 0 || cdxtail !== 0 || cdytail !== 0) {\n s1 = bdxtail * cdy;\n c = splitter * bdxtail;\n ahi = c - (c - bdxtail);\n alo = bdxtail - ahi;\n c = splitter * cdy;\n bhi = c - (c - cdy);\n blo = cdy - bhi;\n s0 = alo * blo - (s1 - ahi * bhi - alo * bhi - ahi * blo);\n t1 = bdx * cdytail;\n c = splitter * bdx;\n ahi = c - (c - bdx);\n alo = bdx - ahi;\n c = splitter * cdytail;\n bhi = c - (c - cdytail);\n blo = cdytail - bhi;\n t0 = alo * blo - (t1 - ahi * bhi - alo * bhi - ahi * blo);\n _i = s0 + t0;\n bvirt = _i - s0;\n u[0] = s0 - (_i - bvirt) + (t0 - bvirt);\n _j = s1 + _i;\n bvirt = _j - s1;\n _0 = s1 - (_j - bvirt) + (_i - bvirt);\n _i = _0 + t1;\n bvirt = _i - _0;\n u[1] = _0 - (_i - bvirt) + (t1 - bvirt);\n u3 = _j + _i;\n bvirt = u3 - _j;\n u[2] = _j - (u3 - bvirt) + (_i - bvirt);\n u[3] = u3;\n s1 = cdxtail * -bdy;\n c = splitter * cdxtail;\n ahi = c - (c - cdxtail);\n alo = cdxtail - ahi;\n c = splitter * -bdy;\n bhi = c - (c - -bdy);\n blo = -bdy - bhi;\n s0 = alo * blo - (s1 - ahi * bhi - alo * bhi - ahi * blo);\n t1 = cdx * -bdytail;\n c = splitter * cdx;\n ahi = c - (c - cdx);\n alo = cdx - ahi;\n c = splitter * -bdytail;\n bhi = c - (c - -bdytail);\n blo = -bdytail - bhi;\n t0 = alo * blo - (t1 - ahi * bhi - alo * bhi - ahi * blo);\n _i = s0 + t0;\n bvirt = _i - s0;\n v[0] = s0 - (_i - bvirt) + (t0 - bvirt);\n _j = s1 + _i;\n bvirt = _j - s1;\n _0 = s1 - (_j - bvirt) + (_i - bvirt);\n _i = _0 + t1;\n bvirt = _i - _0;\n v[1] = _0 - (_i - bvirt) + (t1 - bvirt);\n u3 = _j + _i;\n bvirt = u3 - _j;\n v[2] = _j - (u3 - bvirt) + (_i - bvirt);\n v[3] = u3;\n bctlen = sum(4, u, 4, v, bct);\n s1 = bdxtail * cdytail;\n c = splitter * bdxtail;\n ahi = c - (c - bdxtail);\n alo = bdxtail - ahi;\n c = splitter * cdytail;\n bhi = c - (c - cdytail);\n blo = cdytail - bhi;\n s0 = alo * blo - (s1 - ahi * bhi - alo * bhi - ahi * blo);\n t1 = cdxtail * bdytail;\n c = splitter * cdxtail;\n ahi = c - (c - cdxtail);\n alo = cdxtail - ahi;\n c = splitter * bdytail;\n bhi = c - (c - bdytail);\n blo = bdytail - bhi;\n t0 = alo * blo - (t1 - ahi * bhi - alo * bhi - ahi * blo);\n _i = s0 - t0;\n bvirt = s0 - _i;\n bctt[0] = s0 - (_i + bvirt) + (bvirt - t0);\n _j = s1 + _i;\n bvirt = _j - s1;\n _0 = s1 - (_j - bvirt) + (_i - bvirt);\n _i = _0 - t1;\n bvirt = _0 - _i;\n bctt[1] = _0 - (_i + bvirt) + (bvirt - t1);\n u3 = _j + _i;\n bvirt = u3 - _j;\n bctt[2] = _j - (u3 - bvirt) + (_i - bvirt);\n bctt[3] = u3;\n bcttlen = 4;\n } else {\n bct[0] = 0;\n bctlen = 1;\n bctt[0] = 0;\n bcttlen = 1;\n }\n if (adxtail !== 0) {\n const len = scale(bctlen, bct, adxtail, _16c);\n finlen = finadd(finlen, sum(\n scale(axtbclen, axtbc, adxtail, _16), _16,\n scale(len, _16c, 2 * adx, _32), _32, _48), _48);\n\n const len2 = scale(bcttlen, bctt, adxtail, _8);\n finlen = finadd(finlen, sum_three(\n scale(len2, _8, 2 * adx, _16), _16,\n scale(len2, _8, adxtail, _16b), _16b,\n scale(len, _16c, adxtail, _32), _32, _32b, _64), _64);\n\n if (bdytail !== 0) {\n finlen = finadd(finlen, scale(scale(4, cc, adxtail, _8), _8, bdytail, _16), _16);\n }\n if (cdytail !== 0) {\n finlen = finadd(finlen, scale(scale(4, bb, -adxtail, _8), _8, cdytail, _16), _16);\n }\n }\n if (adytail !== 0) {\n const len = scale(bctlen, bct, adytail, _16c);\n finlen = finadd(finlen, sum(\n scale(aytbclen, aytbc, adytail, _16), _16,\n scale(len, _16c, 2 * ady, _32), _32, _48), _48);\n\n const len2 = scale(bcttlen, bctt, adytail, _8);\n finlen = finadd(finlen, sum_three(\n scale(len2, _8, 2 * ady, _16), _16,\n scale(len2, _8, adytail, _16b), _16b,\n scale(len, _16c, adytail, _32), _32, _32b, _64), _64);\n }\n }\n if (bdxtail !== 0 || bdytail !== 0) {\n if (cdxtail !== 0 || cdytail !== 0 || adxtail !== 0 || adytail !== 0) {\n s1 = cdxtail * ady;\n c = splitter * cdxtail;\n ahi = c - (c - cdxtail);\n alo = cdxtail - ahi;\n c = splitter * ady;\n bhi = c - (c - ady);\n blo = ady - bhi;\n s0 = alo * blo - (s1 - ahi * bhi - alo * bhi - ahi * blo);\n t1 = cdx * adytail;\n c = splitter * cdx;\n ahi = c - (c - cdx);\n alo = cdx - ahi;\n c = splitter * adytail;\n bhi = c - (c - adytail);\n blo = adytail - bhi;\n t0 = alo * blo - (t1 - ahi * bhi - alo * bhi - ahi * blo);\n _i = s0 + t0;\n bvirt = _i - s0;\n u[0] = s0 - (_i - bvirt) + (t0 - bvirt);\n _j = s1 + _i;\n bvirt = _j - s1;\n _0 = s1 - (_j - bvirt) + (_i - bvirt);\n _i = _0 + t1;\n bvirt = _i - _0;\n u[1] = _0 - (_i - bvirt) + (t1 - bvirt);\n u3 = _j + _i;\n bvirt = u3 - _j;\n u[2] = _j - (u3 - bvirt) + (_i - bvirt);\n u[3] = u3;\n n1 = -cdy;\n n0 = -cdytail;\n s1 = adxtail * n1;\n c = splitter * adxtail;\n ahi = c - (c - adxtail);\n alo = adxtail - ahi;\n c = splitter * n1;\n bhi = c - (c - n1);\n blo = n1 - bhi;\n s0 = alo * blo - (s1 - ahi * bhi - alo * bhi - ahi * blo);\n t1 = adx * n0;\n c = splitter * adx;\n ahi = c - (c - adx);\n alo = adx - ahi;\n c = splitter * n0;\n bhi = c - (c - n0);\n blo = n0 - bhi;\n t0 = alo * blo - (t1 - ahi * bhi - alo * bhi - ahi * blo);\n _i = s0 + t0;\n bvirt = _i - s0;\n v[0] = s0 - (_i - bvirt) + (t0 - bvirt);\n _j = s1 + _i;\n bvirt = _j - s1;\n _0 = s1 - (_j - bvirt) + (_i - bvirt);\n _i = _0 + t1;\n bvirt = _i - _0;\n v[1] = _0 - (_i - bvirt) + (t1 - bvirt);\n u3 = _j + _i;\n bvirt = u3 - _j;\n v[2] = _j - (u3 - bvirt) + (_i - bvirt);\n v[3] = u3;\n catlen = sum(4, u, 4, v, cat);\n s1 = cdxtail * adytail;\n c = splitter * cdxtail;\n ahi = c - (c - cdxtail);\n alo = cdxtail - ahi;\n c = splitter * adytail;\n bhi = c - (c - adytail);\n blo = adytail - bhi;\n s0 = alo * blo - (s1 - ahi * bhi - alo * bhi - ahi * blo);\n t1 = adxtail * cdytail;\n c = splitter * adxtail;\n ahi = c - (c - adxtail);\n alo = adxtail - ahi;\n c = splitter * cdytail;\n bhi = c - (c - cdytail);\n blo = cdytail - bhi;\n t0 = alo * blo - (t1 - ahi * bhi - alo * bhi - ahi * blo);\n _i = s0 - t0;\n bvirt = s0 - _i;\n catt[0] = s0 - (_i + bvirt) + (bvirt - t0);\n _j = s1 + _i;\n bvirt = _j - s1;\n _0 = s1 - (_j - bvirt) + (_i - bvirt);\n _i = _0 - t1;\n bvirt = _0 - _i;\n catt[1] = _0 - (_i + bvirt) + (bvirt - t1);\n u3 = _j + _i;\n bvirt = u3 - _j;\n catt[2] = _j - (u3 - bvirt) + (_i - bvirt);\n catt[3] = u3;\n cattlen = 4;\n } else {\n cat[0] = 0;\n catlen = 1;\n catt[0] = 0;\n cattlen = 1;\n }\n if (bdxtail !== 0) {\n const len = scale(catlen, cat, bdxtail, _16c);\n finlen = finadd(finlen, sum(\n scale(bxtcalen, bxtca, bdxtail, _16), _16,\n scale(len, _16c, 2 * bdx, _32), _32, _48), _48);\n\n const len2 = scale(cattlen, catt, bdxtail, _8);\n finlen = finadd(finlen, sum_three(\n scale(len2, _8, 2 * bdx, _16), _16,\n scale(len2, _8, bdxtail, _16b), _16b,\n scale(len, _16c, bdxtail, _32), _32, _32b, _64), _64);\n\n if (cdytail !== 0) {\n finlen = finadd(finlen, scale(scale(4, aa, bdxtail, _8), _8, cdytail, _16), _16);\n }\n if (adytail !== 0) {\n finlen = finadd(finlen, scale(scale(4, cc, -bdxtail, _8), _8, adytail, _16), _16);\n }\n }\n if (bdytail !== 0) {\n const len = scale(catlen, cat, bdytail, _16c);\n finlen = finadd(finlen, sum(\n scale(bytcalen, bytca, bdytail, _16), _16,\n scale(len, _16c, 2 * bdy, _32), _32, _48), _48);\n\n const len2 = scale(cattlen, catt, bdytail, _8);\n finlen = finadd(finlen, sum_three(\n scale(len2, _8, 2 * bdy, _16), _16,\n scale(len2, _8, bdytail, _16b), _16b,\n scale(len, _16c, bdytail, _32), _32, _32b, _64), _64);\n }\n }\n if (cdxtail !== 0 || cdytail !== 0) {\n if (adxtail !== 0 || adytail !== 0 || bdxtail !== 0 || bdytail !== 0) {\n s1 = adxtail * bdy;\n c = splitter * adxtail;\n ahi = c - (c - adxtail);\n alo = adxtail - ahi;\n c = splitter * bdy;\n bhi = c - (c - bdy);\n blo = bdy - bhi;\n s0 = alo * blo - (s1 - ahi * bhi - alo * bhi - ahi * blo);\n t1 = adx * bdytail;\n c = splitter * adx;\n ahi = c - (c - adx);\n alo = adx - ahi;\n c = splitter * bdytail;\n bhi = c - (c - bdytail);\n blo = bdytail - bhi;\n t0 = alo * blo - (t1 - ahi * bhi - alo * bhi - ahi * blo);\n _i = s0 + t0;\n bvirt = _i - s0;\n u[0] = s0 - (_i - bvirt) + (t0 - bvirt);\n _j = s1 + _i;\n bvirt = _j - s1;\n _0 = s1 - (_j - bvirt) + (_i - bvirt);\n _i = _0 + t1;\n bvirt = _i - _0;\n u[1] = _0 - (_i - bvirt) + (t1 - bvirt);\n u3 = _j + _i;\n bvirt = u3 - _j;\n u[2] = _j - (u3 - bvirt) + (_i - bvirt);\n u[3] = u3;\n n1 = -ady;\n n0 = -adytail;\n s1 = bdxtail * n1;\n c = splitter * bdxtail;\n ahi = c - (c - bdxtail);\n alo = bdxtail - ahi;\n c = splitter * n1;\n bhi = c - (c - n1);\n blo = n1 - bhi;\n s0 = alo * blo - (s1 - ahi * bhi - alo * bhi - ahi * blo);\n t1 = bdx * n0;\n c = splitter * bdx;\n ahi = c - (c - bdx);\n alo = bdx - ahi;\n c = splitter * n0;\n bhi = c - (c - n0);\n blo = n0 - bhi;\n t0 = alo * blo - (t1 - ahi * bhi - alo * bhi - ahi * blo);\n _i = s0 + t0;\n bvirt = _i - s0;\n v[0] = s0 - (_i - bvirt) + (t0 - bvirt);\n _j = s1 + _i;\n bvirt = _j - s1;\n _0 = s1 - (_j - bvirt) + (_i - bvirt);\n _i = _0 + t1;\n bvirt = _i - _0;\n v[1] = _0 - (_i - bvirt) + (t1 - bvirt);\n u3 = _j + _i;\n bvirt = u3 - _j;\n v[2] = _j - (u3 - bvirt) + (_i - bvirt);\n v[3] = u3;\n abtlen = sum(4, u, 4, v, abt);\n s1 = adxtail * bdytail;\n c = splitter * adxtail;\n ahi = c - (c - adxtail);\n alo = adxtail - ahi;\n c = splitter * bdytail;\n bhi = c - (c - bdytail);\n blo = bdytail - bhi;\n s0 = alo * blo - (s1 - ahi * bhi - alo * bhi - ahi * blo);\n t1 = bdxtail * adytail;\n c = splitter * bdxtail;\n ahi = c - (c - bdxtail);\n alo = bdxtail - ahi;\n c = splitter * adytail;\n bhi = c - (c - adytail);\n blo = adytail - bhi;\n t0 = alo * blo - (t1 - ahi * bhi - alo * bhi - ahi * blo);\n _i = s0 - t0;\n bvirt = s0 - _i;\n abtt[0] = s0 - (_i + bvirt) + (bvirt - t0);\n _j = s1 + _i;\n bvirt = _j - s1;\n _0 = s1 - (_j - bvirt) + (_i - bvirt);\n _i = _0 - t1;\n bvirt = _0 - _i;\n abtt[1] = _0 - (_i + bvirt) + (bvirt - t1);\n u3 = _j + _i;\n bvirt = u3 - _j;\n abtt[2] = _j - (u3 - bvirt) + (_i - bvirt);\n abtt[3] = u3;\n abttlen = 4;\n } else {\n abt[0] = 0;\n abtlen = 1;\n abtt[0] = 0;\n abttlen = 1;\n }\n if (cdxtail !== 0) {\n const len = scale(abtlen, abt, cdxtail, _16c);\n finlen = finadd(finlen, sum(\n scale(cxtablen, cxtab, cdxtail, _16), _16,\n scale(len, _16c, 2 * cdx, _32), _32, _48), _48);\n\n const len2 = scale(abttlen, abtt, cdxtail, _8);\n finlen = finadd(finlen, sum_three(\n scale(len2, _8, 2 * cdx, _16), _16,\n scale(len2, _8, cdxtail, _16b), _16b,\n scale(len, _16c, cdxtail, _32), _32, _32b, _64), _64);\n\n if (adytail !== 0) {\n finlen = finadd(finlen, scale(scale(4, bb, cdxtail, _8), _8, adytail, _16), _16);\n }\n if (bdytail !== 0) {\n finlen = finadd(finlen, scale(scale(4, aa, -cdxtail, _8), _8, bdytail, _16), _16);\n }\n }\n if (cdytail !== 0) {\n const len = scale(abtlen, abt, cdytail, _16c);\n finlen = finadd(finlen, sum(\n scale(cytablen, cytab, cdytail, _16), _16,\n scale(len, _16c, 2 * cdy, _32), _32, _48), _48);\n\n const len2 = scale(abttlen, abtt, cdytail, _8);\n finlen = finadd(finlen, sum_three(\n scale(len2, _8, 2 * cdy, _16), _16,\n scale(len2, _8, cdytail, _16b), _16b,\n scale(len, _16c, cdytail, _32), _32, _32b, _64), _64);\n }\n }\n\n return fin[finlen - 1];\n}\n\nexport function incircle(ax, ay, bx, by, cx, cy, dx, dy) {\n const adx = ax - dx;\n const bdx = bx - dx;\n const cdx = cx - dx;\n const ady = ay - dy;\n const bdy = by - dy;\n const cdy = cy - dy;\n\n const bdxcdy = bdx * cdy;\n const cdxbdy = cdx * bdy;\n const alift = adx * adx + ady * ady;\n\n const cdxady = cdx * ady;\n const adxcdy = adx * cdy;\n const blift = bdx * bdx + bdy * bdy;\n\n const adxbdy = adx * bdy;\n const bdxady = bdx * ady;\n const clift = cdx * cdx + cdy * cdy;\n\n const det =\n alift * (bdxcdy - cdxbdy) +\n blift * (cdxady - adxcdy) +\n clift * (adxbdy - bdxady);\n\n const permanent =\n (Math.abs(bdxcdy) + Math.abs(cdxbdy)) * alift +\n (Math.abs(cdxady) + Math.abs(adxcdy)) * blift +\n (Math.abs(adxbdy) + Math.abs(bdxady)) * clift;\n\n const errbound = iccerrboundA * permanent;\n\n if (det > errbound || -det > errbound) {\n return det;\n }\n return incircleadapt(ax, ay, bx, by, cx, cy, dx, dy, permanent);\n}\n\nexport function incirclefast(ax, ay, bx, by, cx, cy, dx, dy) {\n const adx = ax - dx;\n const ady = ay - dy;\n const bdx = bx - dx;\n const bdy = by - dy;\n const cdx = cx - dx;\n const cdy = cy - dy;\n\n const abdet = adx * bdy - bdx * ady;\n const bcdet = bdx * cdy - cdx * bdy;\n const cadet = cdx * ady - adx * cdy;\n const alift = adx * adx + ady * ady;\n const blift = bdx * bdx + bdy * bdy;\n const clift = cdx * cdx + cdy * cdy;\n\n return alift * bcdet + blift * cadet + clift * abdet;\n}\n","import {epsilon, splitter, resulterrbound, estimate, vec, sum, sum_three, scale, negate} from './util.js';\n\nconst isperrboundA = (16 + 224 * epsilon) * epsilon;\nconst isperrboundB = (5 + 72 * epsilon) * epsilon;\nconst isperrboundC = (71 + 1408 * epsilon) * epsilon * epsilon;\n\nconst ab = vec(4);\nconst bc = vec(4);\nconst cd = vec(4);\nconst de = vec(4);\nconst ea = vec(4);\nconst ac = vec(4);\nconst bd = vec(4);\nconst ce = vec(4);\nconst da = vec(4);\nconst eb = vec(4);\n\nconst abc = vec(24);\nconst bcd = vec(24);\nconst cde = vec(24);\nconst dea = vec(24);\nconst eab = vec(24);\nconst abd = vec(24);\nconst bce = vec(24);\nconst cda = vec(24);\nconst deb = vec(24);\nconst eac = vec(24);\n\nconst adet = vec(1152);\nconst bdet = vec(1152);\nconst cdet = vec(1152);\nconst ddet = vec(1152);\nconst edet = vec(1152);\nconst abdet = vec(2304);\nconst cddet = vec(2304);\nconst cdedet = vec(3456);\nconst deter = vec(5760);\n\nconst _8 = vec(8);\nconst _8b = vec(8);\nconst _8c = vec(8);\nconst _16 = vec(16);\nconst _24 = vec(24);\nconst _48 = vec(48);\nconst _48b = vec(48);\nconst _96 = vec(96);\nconst _192 = vec(192);\nconst _384x = vec(384);\nconst _384y = vec(384);\nconst _384z = vec(384);\nconst _768 = vec(768);\n\nfunction sum_three_scale(a, b, c, az, bz, cz, out) {\n return sum_three(\n scale(4, a, az, _8), _8,\n scale(4, b, bz, _8b), _8b,\n scale(4, c, cz, _8c), _8c, _16, out);\n}\n\nfunction liftexact(alen, a, blen, b, clen, c, dlen, d, x, y, z, out) {\n const len = sum(\n sum(alen, a, blen, b, _48), _48,\n negate(sum(clen, c, dlen, d, _48b), _48b), _48b, _96);\n\n return sum_three(\n scale(scale(len, _96, x, _192), _192, x, _384x), _384x,\n scale(scale(len, _96, y, _192), _192, y, _384y), _384y,\n scale(scale(len, _96, z, _192), _192, z, _384z), _384z, _768, out);\n}\n\nfunction insphereexact(ax, ay, az, bx, by, bz, cx, cy, cz, dx, dy, dz, ex, ey, ez) {\n let bvirt, c, ahi, alo, bhi, blo, _i, _j, _0, s1, s0, t1, t0, u3;\n\n s1 = ax * by;\n c = splitter * ax;\n ahi = c - (c - ax);\n alo = ax - ahi;\n c = splitter * by;\n bhi = c - (c - by);\n blo = by - bhi;\n s0 = alo * blo - (s1 - ahi * bhi - alo * bhi - ahi * blo);\n t1 = bx * ay;\n c = splitter * bx;\n ahi = c - (c - bx);\n alo = bx - ahi;\n c = splitter * ay;\n bhi = c - (c - ay);\n blo = ay - bhi;\n t0 = alo * blo - (t1 - ahi * bhi - alo * bhi - ahi * blo);\n _i = s0 - t0;\n bvirt = s0 - _i;\n ab[0] = s0 - (_i + bvirt) + (bvirt - t0);\n _j = s1 + _i;\n bvirt = _j - s1;\n _0 = s1 - (_j - bvirt) + (_i - bvirt);\n _i = _0 - t1;\n bvirt = _0 - _i;\n ab[1] = _0 - (_i + bvirt) + (bvirt - t1);\n u3 = _j + _i;\n bvirt = u3 - _j;\n ab[2] = _j - (u3 - bvirt) + (_i - bvirt);\n ab[3] = u3;\n s1 = bx * cy;\n c = splitter * bx;\n ahi = c - (c - bx);\n alo = bx - ahi;\n c = splitter * cy;\n bhi = c - (c - cy);\n blo = cy - bhi;\n s0 = alo * blo - (s1 - ahi * bhi - alo * bhi - ahi * blo);\n t1 = cx * by;\n c = splitter * cx;\n ahi = c - (c - cx);\n alo = cx - ahi;\n c = splitter * by;\n bhi = c - (c - by);\n blo = by - bhi;\n t0 = alo * blo - (t1 - ahi * bhi - alo * bhi - ahi * blo);\n _i = s0 - t0;\n bvirt = s0 - _i;\n bc[0] = s0 - (_i + bvirt) + (bvirt - t0);\n _j = s1 + _i;\n bvirt = _j - s1;\n _0 = s1 - (_j - bvirt) + (_i - bvirt);\n _i = _0 - t1;\n bvirt = _0 - _i;\n bc[1] = _0 - (_i + bvirt) + (bvirt - t1);\n u3 = _j + _i;\n bvirt = u3 - _j;\n bc[2] = _j - (u3 - bvirt) + (_i - bvirt);\n bc[3] = u3;\n s1 = cx * dy;\n c = splitter * cx;\n ahi = c - (c - cx);\n alo = cx - ahi;\n c = splitter * dy;\n bhi = c - (c - dy);\n blo = dy - bhi;\n s0 = alo * blo - (s1 - ahi * bhi - alo * bhi - ahi * blo);\n t1 = dx * cy;\n c = splitter * dx;\n ahi = c - (c - dx);\n alo = dx - ahi;\n c = splitter * cy;\n bhi = c - (c - cy);\n blo = cy - bhi;\n t0 = alo * blo - (t1 - ahi * bhi - alo * bhi - ahi * blo);\n _i = s0 - t0;\n bvirt = s0 - _i;\n cd[0] = s0 - (_i + bvirt) + (bvirt - t0);\n _j = s1 + _i;\n bvirt = _j - s1;\n _0 = s1 - (_j - bvirt) + (_i - bvirt);\n _i = _0 - t1;\n bvirt = _0 - _i;\n cd[1] = _0 - (_i + bvirt) + (bvirt - t1);\n u3 = _j + _i;\n bvirt = u3 - _j;\n cd[2] = _j - (u3 - bvirt) + (_i - bvirt);\n cd[3] = u3;\n s1 = dx * ey;\n c = splitter * dx;\n ahi = c - (c - dx);\n alo = dx - ahi;\n c = splitter * ey;\n bhi = c - (c - ey);\n blo = ey - bhi;\n s0 = alo * blo - (s1 - ahi * bhi - alo * bhi - ahi * blo);\n t1 = ex * dy;\n c = splitter * ex;\n ahi = c - (c - ex);\n alo = ex - ahi;\n c = splitter * dy;\n bhi = c - (c - dy);\n blo = dy - bhi;\n t0 = alo * blo - (t1 - ahi * bhi - alo * bhi - ahi * blo);\n _i = s0 - t0;\n bvirt = s0 - _i;\n de[0] = s0 - (_i + bvirt) + (bvirt - t0);\n _j = s1 + _i;\n bvirt = _j - s1;\n _0 = s1 - (_j - bvirt) + (_i - bvirt);\n _i = _0 - t1;\n bvirt = _0 - _i;\n de[1] = _0 - (_i + bvirt) + (bvirt - t1);\n u3 = _j + _i;\n bvirt = u3 - _j;\n de[2] = _j - (u3 - bvirt) + (_i - bvirt);\n de[3] = u3;\n s1 = ex * ay;\n c = splitter * ex;\n ahi = c - (c - ex);\n alo = ex - ahi;\n c = splitter * ay;\n bhi = c - (c - ay);\n blo = ay - bhi;\n s0 = alo * blo - (s1 - ahi * bhi - alo * bhi - ahi * blo);\n t1 = ax * ey;\n c = splitter * ax;\n ahi = c - (c - ax);\n alo = ax - ahi;\n c = splitter * ey;\n bhi = c - (c - ey);\n blo = ey - bhi;\n t0 = alo * blo - (t1 - ahi * bhi - alo * bhi - ahi * blo);\n _i = s0 - t0;\n bvirt = s0 - _i;\n ea[0] = s0 - (_i + bvirt) + (bvirt - t0);\n _j = s1 + _i;\n bvirt = _j - s1;\n _0 = s1 - (_j - bvirt) + (_i - bvirt);\n _i = _0 - t1;\n bvirt = _0 - _i;\n ea[1] = _0 - (_i + bvirt) + (bvirt - t1);\n u3 = _j + _i;\n bvirt = u3 - _j;\n ea[2] = _j - (u3 - bvirt) + (_i - bvirt);\n ea[3] = u3;\n s1 = ax * cy;\n c = splitter * ax;\n ahi = c - (c - ax);\n alo = ax - ahi;\n c = splitter * cy;\n bhi = c - (c - cy);\n blo = cy - bhi;\n s0 = alo * blo - (s1 - ahi * bhi - alo * bhi - ahi * blo);\n t1 = cx * ay;\n c = splitter * cx;\n ahi = c - (c - cx);\n alo = cx - ahi;\n c = splitter * ay;\n bhi = c - (c - ay);\n blo = ay - bhi;\n t0 = alo * blo - (t1 - ahi * bhi - alo * bhi - ahi * blo);\n _i = s0 - t0;\n bvirt = s0 - _i;\n ac[0] = s0 - (_i + bvirt) + (bvirt - t0);\n _j = s1 + _i;\n bvirt = _j - s1;\n _0 = s1 - (_j - bvirt) + (_i - bvirt);\n _i = _0 - t1;\n bvirt = _0 - _i;\n ac[1] = _0 - (_i + bvirt) + (bvirt - t1);\n u3 = _j + _i;\n bvirt = u3 - _j;\n ac[2] = _j - (u3 - bvirt) + (_i - bvirt);\n ac[3] = u3;\n s1 = bx * dy;\n c = splitter * bx;\n ahi = c - (c - bx);\n alo = bx - ahi;\n c = splitter * dy;\n bhi = c - (c - dy);\n blo = dy - bhi;\n s0 = alo * blo - (s1 - ahi * bhi - alo * bhi - ahi * blo);\n t1 = dx * by;\n c = splitter * dx;\n ahi = c - (c - dx);\n alo = dx - ahi;\n c = splitter * by;\n bhi = c - (c - by);\n blo = by - bhi;\n t0 = alo * blo - (t1 - ahi * bhi - alo * bhi - ahi * blo);\n _i = s0 - t0;\n bvirt = s0 - _i;\n bd[0] = s0 - (_i + bvirt) + (bvirt - t0);\n _j = s1 + _i;\n bvirt = _j - s1;\n _0 = s1 - (_j - bvirt) + (_i - bvirt);\n _i = _0 - t1;\n bvirt = _0 - _i;\n bd[1] = _0 - (_i + bvirt) + (bvirt - t1);\n u3 = _j + _i;\n bvirt = u3 - _j;\n bd[2] = _j - (u3 - bvirt) + (_i - bvirt);\n bd[3] = u3;\n s1 = cx * ey;\n c = splitter * cx;\n ahi = c - (c - cx);\n alo = cx - ahi;\n c = splitter * ey;\n bhi = c - (c - ey);\n blo = ey - bhi;\n s0 = alo * blo - (s1 - ahi * bhi - alo * bhi - ahi * blo);\n t1 = ex * cy;\n c = splitter * ex;\n ahi = c - (c - ex);\n alo = ex - ahi;\n c = splitter * cy;\n bhi = c - (c - cy);\n blo = cy - bhi;\n t0 = alo * blo - (t1 - ahi * bhi - alo * bhi - ahi * blo);\n _i = s0 - t0;\n bvirt = s0 - _i;\n ce[0] = s0 - (_i + bvirt) + (bvirt - t0);\n _j = s1 + _i;\n bvirt = _j - s1;\n _0 = s1 - (_j - bvirt) + (_i - bvirt);\n _i = _0 - t1;\n bvirt = _0 - _i;\n ce[1] = _0 - (_i + bvirt) + (bvirt - t1);\n u3 = _j + _i;\n bvirt = u3 - _j;\n ce[2] = _j - (u3 - bvirt) + (_i - bvirt);\n ce[3] = u3;\n s1 = dx * ay;\n c = splitter * dx;\n ahi = c - (c - dx);\n alo = dx - ahi;\n c = splitter * ay;\n bhi = c - (c - ay);\n blo = ay - bhi;\n s0 = alo * blo - (s1 - ahi * bhi - alo * bhi - ahi * blo);\n t1 = ax * dy;\n c = splitter * ax;\n ahi = c - (c - ax);\n alo = ax - ahi;\n c = splitter * dy;\n bhi = c - (c - dy);\n blo = dy - bhi;\n t0 = alo * blo - (t1 - ahi * bhi - alo * bhi - ahi * blo);\n _i = s0 - t0;\n bvirt = s0 - _i;\n da[0] = s0 - (_i + bvirt) + (bvirt - t0);\n _j = s1 + _i;\n bvirt = _j - s1;\n _0 = s1 - (_j - bvirt) + (_i - bvirt);\n _i = _0 - t1;\n bvirt = _0 - _i;\n da[1] = _0 - (_i + bvirt) + (bvirt - t1);\n u3 = _j + _i;\n bvirt = u3 - _j;\n da[2] = _j - (u3 - bvirt) + (_i - bvirt);\n da[3] = u3;\n s1 = ex * by;\n c = splitter * ex;\n ahi = c - (c - ex);\n alo = ex - ahi;\n c = splitter * by;\n bhi = c - (c - by);\n blo = by - bhi;\n s0 = alo * blo - (s1 - ahi * bhi - alo * bhi - ahi * blo);\n t1 = bx * ey;\n c = splitter * bx;\n ahi = c - (c - bx);\n alo = bx - ahi;\n c = splitter * ey;\n bhi = c - (c - ey);\n blo = ey - bhi;\n t0 = alo * blo - (t1 - ahi * bhi - alo * bhi - ahi * blo);\n _i = s0 - t0;\n bvirt = s0 - _i;\n eb[0] = s0 - (_i + bvirt) + (bvirt - t0);\n _j = s1 + _i;\n bvirt = _j - s1;\n _0 = s1 - (_j - bvirt) + (_i - bvirt);\n _i = _0 - t1;\n bvirt = _0 - _i;\n eb[1] = _0 - (_i + bvirt) + (bvirt - t1);\n u3 = _j + _i;\n bvirt = u3 - _j;\n eb[2] = _j - (u3 - bvirt) + (_i - bvirt);\n eb[3] = u3;\n\n const abclen = sum_three_scale(ab, bc, ac, cz, az, -bz, abc);\n const bcdlen = sum_three_scale(bc, cd, bd, dz, bz, -cz, bcd);\n const cdelen = sum_three_scale(cd, de, ce, ez, cz, -dz, cde);\n const dealen = sum_three_scale(de, ea, da, az, dz, -ez, dea);\n const eablen = sum_three_scale(ea, ab, eb, bz, ez, -az, eab);\n const abdlen = sum_three_scale(ab, bd, da, dz, az, bz, abd);\n const bcelen = sum_three_scale(bc, ce, eb, ez, bz, cz, bce);\n const cdalen = sum_three_scale(cd, da, ac, az, cz, dz, cda);\n const deblen = sum_three_scale(de, eb, bd, bz, dz, ez, deb);\n const eaclen = sum_three_scale(ea, ac, ce, cz, ez, az, eac);\n\n const deterlen = sum_three(\n liftexact(cdelen, cde, bcelen, bce, deblen, deb, bcdlen, bcd, ax, ay, az, adet), adet,\n liftexact(dealen, dea, cdalen, cda, eaclen, eac, cdelen, cde, bx, by, bz, bdet), bdet,\n sum_three(\n liftexact(eablen, eab, deblen, deb, abdlen, abd, dealen, dea, cx, cy, cz, cdet), cdet,\n liftexact(abclen, abc, eaclen, eac, bcelen, bce, eablen, eab, dx, dy, dz, ddet), ddet,\n liftexact(bcdlen, bcd, abdlen, abd, cdalen, cda, abclen, abc, ex, ey, ez, edet), edet, cddet, cdedet), cdedet, abdet, deter);\n\n return deter[deterlen - 1];\n}\n\nconst xdet = vec(96);\nconst ydet = vec(96);\nconst zdet = vec(96);\nconst fin = vec(1152);\n\nfunction liftadapt(a, b, c, az, bz, cz, x, y, z, out) {\n const len = sum_three_scale(a, b, c, az, bz, cz, _24);\n return sum_three(\n scale(scale(len, _24, x, _48), _48, x, xdet), xdet,\n scale(scale(len, _24, y, _48), _48, y, ydet), ydet,\n scale(scale(len, _24, z, _48), _48, z, zdet), zdet, _192, out);\n}\n\nfunction insphereadapt(ax, ay, az, bx, by, bz, cx, cy, cz, dx, dy, dz, ex, ey, ez, permanent) {\n let ab3, bc3, cd3, da3, ac3, bd3;\n\n let aextail, bextail, cextail, dextail;\n let aeytail, beytail, ceytail, deytail;\n let aeztail, beztail, ceztail, deztail;\n\n let bvirt, c, ahi, alo, bhi, blo, _i, _j, _0, s1, s0, t1, t0;\n\n const aex = ax - ex;\n const bex = bx - ex;\n const cex = cx - ex;\n const dex = dx - ex;\n const aey = ay - ey;\n const bey = by - ey;\n const cey = cy - ey;\n const dey = dy - ey;\n const aez = az - ez;\n const bez = bz - ez;\n const cez = cz - ez;\n const dez = dz - ez;\n\n s1 = aex * bey;\n c = splitter * aex;\n ahi = c - (c - aex);\n alo = aex - ahi;\n c = splitter * bey;\n bhi = c - (c - bey);\n blo = bey - bhi;\n s0 = alo * blo - (s1 - ahi * bhi - alo * bhi - ahi * blo);\n t1 = bex * aey;\n c = splitter * bex;\n ahi = c - (c - bex);\n alo = bex - ahi;\n c = splitter * aey;\n bhi = c - (c - aey);\n blo = aey - bhi;\n t0 = alo * blo - (t1 - ahi * bhi - alo * bhi - ahi * blo);\n _i = s0 - t0;\n bvirt = s0 - _i;\n ab[0] = s0 - (_i + bvirt) + (bvirt - t0);\n _j = s1 + _i;\n bvirt = _j - s1;\n _0 = s1 - (_j - bvirt) + (_i - bvirt);\n _i = _0 - t1;\n bvirt = _0 - _i;\n ab[1] = _0 - (_i + bvirt) + (bvirt - t1);\n ab3 = _j + _i;\n bvirt = ab3 - _j;\n ab[2] = _j - (ab3 - bvirt) + (_i - bvirt);\n ab[3] = ab3;\n s1 = bex * cey;\n c = splitter * bex;\n ahi = c - (c - bex);\n alo = bex - ahi;\n c = splitter * cey;\n bhi = c - (c - cey);\n blo = cey - bhi;\n s0 = alo * blo - (s1 - ahi * bhi - alo * bhi - ahi * blo);\n t1 = cex * bey;\n c = splitter * cex;\n ahi = c - (c - cex);\n alo = cex - ahi;\n c = splitter * bey;\n bhi = c - (c - bey);\n blo = bey - bhi;\n t0 = alo * blo - (t1 - ahi * bhi - alo * bhi - ahi * blo);\n _i = s0 - t0;\n bvirt = s0 - _i;\n bc[0] = s0 - (_i + bvirt) + (bvirt - t0);\n _j = s1 + _i;\n bvirt = _j - s1;\n _0 = s1 - (_j - bvirt) + (_i - bvirt);\n _i = _0 - t1;\n bvirt = _0 - _i;\n bc[1] = _0 - (_i + bvirt) + (bvirt - t1);\n bc3 = _j + _i;\n bvirt = bc3 - _j;\n bc[2] = _j - (bc3 - bvirt) + (_i - bvirt);\n bc[3] = bc3;\n s1 = cex * dey;\n c = splitter * cex;\n ahi = c - (c - cex);\n alo = cex - ahi;\n c = splitter * dey;\n bhi = c - (c - dey);\n blo = dey - bhi;\n s0 = alo * blo - (s1 - ahi * bhi - alo * bhi - ahi * blo);\n t1 = dex * cey;\n c = splitter * dex;\n ahi = c - (c - dex);\n alo = dex - ahi;\n c = splitter * cey;\n bhi = c - (c - cey);\n blo = cey - bhi;\n t0 = alo * blo - (t1 - ahi * bhi - alo * bhi - ahi * blo);\n _i = s0 - t0;\n bvirt = s0 - _i;\n cd[0] = s0 - (_i + bvirt) + (bvirt - t0);\n _j = s1 + _i;\n bvirt = _j - s1;\n _0 = s1 - (_j - bvirt) + (_i - bvirt);\n _i = _0 - t1;\n bvirt = _0 - _i;\n cd[1] = _0 - (_i + bvirt) + (bvirt - t1);\n cd3 = _j + _i;\n bvirt = cd3 - _j;\n cd[2] = _j - (cd3 - bvirt) + (_i - bvirt);\n cd[3] = cd3;\n s1 = dex * aey;\n c = splitter * dex;\n ahi = c - (c - dex);\n alo = dex - ahi;\n c = splitter * aey;\n bhi = c - (c - aey);\n blo = aey - bhi;\n s0 = alo * blo - (s1 - ahi * bhi - alo * bhi - ahi * blo);\n t1 = aex * dey;\n c = splitter * aex;\n ahi = c - (c - aex);\n alo = aex - ahi;\n c = splitter * dey;\n bhi = c - (c - dey);\n blo = dey - bhi;\n t0 = alo * blo - (t1 - ahi * bhi - alo * bhi - ahi * blo);\n _i = s0 - t0;\n bvirt = s0 - _i;\n da[0] = s0 - (_i + bvirt) + (bvirt - t0);\n _j = s1 + _i;\n bvirt = _j - s1;\n _0 = s1 - (_j - bvirt) + (_i - bvirt);\n _i = _0 - t1;\n bvirt = _0 - _i;\n da[1] = _0 - (_i + bvirt) + (bvirt - t1);\n da3 = _j + _i;\n bvirt = da3 - _j;\n da[2] = _j - (da3 - bvirt) + (_i - bvirt);\n da[3] = da3;\n s1 = aex * cey;\n c = splitter * aex;\n ahi = c - (c - aex);\n alo = aex - ahi;\n c = splitter * cey;\n bhi = c - (c - cey);\n blo = cey - bhi;\n s0 = alo * blo - (s1 - ahi * bhi - alo * bhi - ahi * blo);\n t1 = cex * aey;\n c = splitter * cex;\n ahi = c - (c - cex);\n alo = cex - ahi;\n c = splitter * aey;\n bhi = c - (c - aey);\n blo = aey - bhi;\n t0 = alo * blo - (t1 - ahi * bhi - alo * bhi - ahi * blo);\n _i = s0 - t0;\n bvirt = s0 - _i;\n ac[0] = s0 - (_i + bvirt) + (bvirt - t0);\n _j = s1 + _i;\n bvirt = _j - s1;\n _0 = s1 - (_j - bvirt) + (_i - bvirt);\n _i = _0 - t1;\n bvirt = _0 - _i;\n ac[1] = _0 - (_i + bvirt) + (bvirt - t1);\n ac3 = _j + _i;\n bvirt = ac3 - _j;\n ac[2] = _j - (ac3 - bvirt) + (_i - bvirt);\n ac[3] = ac3;\n s1 = bex * dey;\n c = splitter * bex;\n ahi = c - (c - bex);\n alo = bex - ahi;\n c = splitter * dey;\n bhi = c - (c - dey);\n blo = dey - bhi;\n s0 = alo * blo - (s1 - ahi * bhi - alo * bhi - ahi * blo);\n t1 = dex * bey;\n c = splitter * dex;\n ahi = c - (c - dex);\n alo = dex - ahi;\n c = splitter * bey;\n bhi = c - (c - bey);\n blo = bey - bhi;\n t0 = alo * blo - (t1 - ahi * bhi - alo * bhi - ahi * blo);\n _i = s0 - t0;\n bvirt = s0 - _i;\n bd[0] = s0 - (_i + bvirt) + (bvirt - t0);\n _j = s1 + _i;\n bvirt = _j - s1;\n _0 = s1 - (_j - bvirt) + (_i - bvirt);\n _i = _0 - t1;\n bvirt = _0 - _i;\n bd[1] = _0 - (_i + bvirt) + (bvirt - t1);\n bd3 = _j + _i;\n bvirt = bd3 - _j;\n bd[2] = _j - (bd3 - bvirt) + (_i - bvirt);\n bd[3] = bd3;\n\n const finlen = sum(\n sum(\n negate(liftadapt(bc, cd, bd, dez, bez, -cez, aex, aey, aez, adet), adet), adet,\n liftadapt(cd, da, ac, aez, cez, dez, bex, bey, bez, bdet), bdet, abdet), abdet,\n sum(\n negate(liftadapt(da, ab, bd, bez, dez, aez, cex, cey, cez, cdet), cdet), cdet,\n liftadapt(ab, bc, ac, cez, aez, -bez, dex, dey, dez, ddet), ddet, cddet), cddet, fin);\n\n let det = estimate(finlen, fin);\n let errbound = isperrboundB * permanent;\n if (det >= errbound || -det >= errbound) {\n return det;\n }\n\n bvirt = ax - aex;\n aextail = ax - (aex + bvirt) + (bvirt - ex);\n bvirt = ay - aey;\n aeytail = ay - (aey + bvirt) + (bvirt - ey);\n bvirt = az - aez;\n aeztail = az - (aez + bvirt) + (bvirt - ez);\n bvirt = bx - bex;\n bextail = bx - (bex + bvirt) + (bvirt - ex);\n bvirt = by - bey;\n beytail = by - (bey + bvirt) + (bvirt - ey);\n bvirt = bz - bez;\n beztail = bz - (bez + bvirt) + (bvirt - ez);\n bvirt = cx - cex;\n cextail = cx - (cex + bvirt) + (bvirt - ex);\n bvirt = cy - cey;\n ceytail = cy - (cey + bvirt) + (bvirt - ey);\n bvirt = cz - cez;\n ceztail = cz - (cez + bvirt) + (bvirt - ez);\n bvirt = dx - dex;\n dextail = dx - (dex + bvirt) + (bvirt - ex);\n bvirt = dy - dey;\n deytail = dy - (dey + bvirt) + (bvirt - ey);\n bvirt = dz - dez;\n deztail = dz - (dez + bvirt) + (bvirt - ez);\n if (aextail === 0 && aeytail === 0 && aeztail === 0 &&\n bextail === 0 && beytail === 0 && beztail === 0 &&\n cextail === 0 && ceytail === 0 && ceztail === 0 &&\n dextail === 0 && deytail === 0 && deztail === 0) {\n return det;\n }\n\n errbound = isperrboundC * permanent + resulterrbound * Math.abs(det);\n\n const abeps = (aex * beytail + bey * aextail) - (aey * bextail + bex * aeytail);\n const bceps = (bex * ceytail + cey * bextail) - (bey * cextail + cex * beytail);\n const cdeps = (cex * deytail + dey * cextail) - (cey * dextail + dex * ceytail);\n const daeps = (dex * aeytail + aey * dextail) - (dey * aextail + aex * deytail);\n const aceps = (aex * ceytail + cey * aextail) - (aey * cextail + cex * aeytail);\n const bdeps = (bex * deytail + dey * bextail) - (bey * dextail + dex * beytail);\n det +=\n (((bex * bex + bey * bey + bez * bez) * ((cez * daeps + dez * aceps + aez * cdeps) +\n (ceztail * da3 + deztail * ac3 + aeztail * cd3)) + (dex * dex + dey * dey + dez * dez) *\n ((aez * bceps - bez * aceps + cez * abeps) + (aeztail * bc3 - beztail * ac3 + ceztail * ab3))) -\n ((aex * aex + aey * aey + aez * aez) * ((bez * cdeps - cez * bdeps + dez * bceps) +\n (beztail * cd3 - ceztail * bd3 + deztail * bc3)) + (cex * cex + cey * cey + cez * cez) *\n ((dez * abeps + aez * bdeps + bez * daeps) + (deztail * ab3 + aeztail * bd3 + beztail * da3)))) +\n 2 * (((bex * bextail + bey * beytail + bez * beztail) * (cez * da3 + dez * ac3 + aez * cd3) +\n (dex * dextail + dey * deytail + dez * deztail) * (aez * bc3 - bez * ac3 + cez * ab3)) -\n ((aex * aextail + aey * aeytail + aez * aeztail) * (bez * cd3 - cez * bd3 + dez * bc3) +\n (cex * cextail + cey * ceytail + cez * ceztail) * (dez * ab3 + aez * bd3 + bez * da3)));\n\n if (det >= errbound || -det >= errbound) {\n return det;\n }\n\n return insphereexact(ax, ay, az, bx, by, bz, cx, cy, cz, dx, dy, dz, ex, ey, ez);\n}\n\nexport function insphere(ax, ay, az, bx, by, bz, cx, cy, cz, dx, dy, dz, ex, ey, ez) {\n const aex = ax - ex;\n const bex = bx - ex;\n const cex = cx - ex;\n const dex = dx - ex;\n const aey = ay - ey;\n const bey = by - ey;\n const cey = cy - ey;\n const dey = dy - ey;\n const aez = az - ez;\n const bez = bz - ez;\n const cez = cz - ez;\n const dez = dz - ez;\n\n const aexbey = aex * bey;\n const bexaey = bex * aey;\n const ab = aexbey - bexaey;\n const bexcey = bex * cey;\n const cexbey = cex * bey;\n const bc = bexcey - cexbey;\n const cexdey = cex * dey;\n const dexcey = dex * cey;\n const cd = cexdey - dexcey;\n const dexaey = dex * aey;\n const aexdey = aex * dey;\n const da = dexaey - aexdey;\n const aexcey = aex * cey;\n const cexaey = cex * aey;\n const ac = aexcey - cexaey;\n const bexdey = bex * dey;\n const dexbey = dex * bey;\n const bd = bexdey - dexbey;\n\n const alift = aex * aex + aey * aey + aez * aez;\n const blift = bex * bex + bey * bey + bez * bez;\n const clift = cex * cex + cey * cey + cez * cez;\n const dlift = dex * dex + dey * dey + dez * dez;\n\n const det =\n (clift * (dez * ab + aez * bd + bez * da) - dlift * (aez * bc - bez * ac + cez * ab)) +\n (alift * (bez * cd - cez * bd + dez * bc) - blift * (cez * da + dez * ac + aez * cd));\n\n const aezplus = Math.abs(aez);\n const bezplus = Math.abs(bez);\n const cezplus = Math.abs(cez);\n const dezplus = Math.abs(dez);\n const aexbeyplus = Math.abs(aexbey) + Math.abs(bexaey);\n const bexceyplus = Math.abs(bexcey) + Math.abs(cexbey);\n const cexdeyplus = Math.abs(cexdey) + Math.abs(dexcey);\n const dexaeyplus = Math.abs(dexaey) + Math.abs(aexdey);\n const aexceyplus = Math.abs(aexcey) + Math.abs(cexaey);\n const bexdeyplus = Math.abs(bexdey) + Math.abs(dexbey);\n const permanent =\n (cexdeyplus * bezplus + bexdeyplus * cezplus + bexceyplus * dezplus) * alift +\n (dexaeyplus * cezplus + aexceyplus * dezplus + cexdeyplus * aezplus) * blift +\n (aexbeyplus * dezplus + bexdeyplus * aezplus + dexaeyplus * bezplus) * clift +\n (bexceyplus * aezplus + aexceyplus * bezplus + aexbeyplus * cezplus) * dlift;\n\n const errbound = isperrboundA * permanent;\n if (det > errbound || -det > errbound) {\n return det;\n }\n return -insphereadapt(ax, ay, az, bx, by, bz, cx, cy, cz, dx, dy, dz, ex, ey, ez, permanent);\n}\n\nexport function inspherefast(ax, ay, az, bx, by, bz, cx, cy, cz, dx, dy, dz, ex, ey, ez) {\n const aex = ax - ex;\n const bex = bx - ex;\n const cex = cx - ex;\n const dex = dx - ex;\n const aey = ay - ey;\n const bey = by - ey;\n const cey = cy - ey;\n const dey = dy - ey;\n const aez = az - ez;\n const bez = bz - ez;\n const cez = cz - ez;\n const dez = dz - ez;\n\n const ab = aex * bey - bex * aey;\n const bc = bex * cey - cex * bey;\n const cd = cex * dey - dex * cey;\n const da = dex * aey - aex * dey;\n const ac = aex * cey - cex * aey;\n const bd = bex * dey - dex * bey;\n\n const abc = aez * bc - bez * ac + cez * ab;\n const bcd = bez * cd - cez * bd + dez * bc;\n const cda = cez * da + dez * ac + aez * cd;\n const dab = dez * ab + aez * bd + bez * da;\n\n const alift = aex * aex + aey * aey + aez * aez;\n const blift = bex * bex + bey * bey + bez * bez;\n const clift = cex * cex + cey * cey + cez * cez;\n const dlift = dex * dex + dey * dey + dez * dez;\n\n return (clift * dab - dlift * abc) + (alift * bcd - blift * cda);\n}\n","\nconst EPSILON = Math.pow(2, -52);\nconst EDGE_STACK = new Uint32Array(512);\n\nimport {orient2d} from 'robust-predicates';\n\n/** @template {ArrayLike<number>} T */\nexport default class Delaunator {\n\n /**\n * Constructs a delaunay triangulation object given an array of points (`[x, y]` by default).\n * `getX` and `getY` are optional functions of the form `(point) => value` for custom point formats.\n *\n * @template P\n * @param {P[]} points\n * @param {(p: P) => number} [getX]\n * @param {(p: P) => number} [getY]\n */\n // @ts-expect-error TS2322\n static from(points, getX = defaultGetX, getY = defaultGetY) {\n const n = points.length;\n const coords = new Float64Array(n * 2);\n\n for (let i = 0; i < n; i++) {\n const p = points[i];\n coords[2 * i] = getX(p);\n coords[2 * i + 1] = getY(p);\n }\n\n return new Delaunator(coords);\n }\n\n /**\n * Constructs a delaunay triangulation object given an array of point coordinates of the form:\n * `[x0, y0, x1, y1, ...]` (use a typed array for best performance). Duplicate points are skipped.\n *\n * @param {T} coords\n */\n constructor(coords) {\n const n = coords.length >> 1;\n if (n > 0 && typeof coords[0] !== 'number') throw new Error('Expected coords to contain numbers.');\n\n this.coords = coords;\n\n // arrays that will store the triangulation graph\n const maxTriangles = Math.max(2 * n - 5, 0);\n /** @private */ this._triangles = new Uint32Array(maxTriangles * 3);\n /** @private */ this._halfedges = new Int32Array(maxTriangles * 3);\n\n // temporary arrays for tracking the edges of the advancing convex hull\n /** @private */ this._hashSize = Math.ceil(Math.sqrt(n));\n /** @private */ this._hullPrev = new Uint32Array(n); // edge to prev edge\n /** @private */ this._hullNext = new Uint32Array(n); // edge to next edge\n /** @private */ this._hullTri = new Uint32Array(n); // edge to adjacent triangle\n /** @private */ this._hullHash = new Int32Array(this._hashSize); // angular edge hash\n\n // temporary arrays for sorting points\n /** @private */ this._ids = new Uint32Array(n);\n /** @private */ this._dists = new Float64Array(n);\n\n /** @private */ this.trianglesLen = 0;\n /** @private */ this._cx = 0;\n /** @private */ this._cy = 0;\n /** @private */ this._hullStart = 0;\n\n\n /** A `Uint32Array` array of indices that reference points on the convex hull of the input data, counter-clockwise. */\n this.hull = this._triangles;\n /** A `Uint32Array` array of triangle vertex indices (each group of three numbers forms a triangle). All triangles are directed counterclockwise. */\n this.triangles = this._triangles;\n /**\n * A `Int32Array` array of triangle half-edge indices that allows you to traverse the triangulation.\n * `i`-th half-edge in the array corresponds to vertex `triangles[i]` the half-edge is coming from.\n * `halfedges[i]` is the index of a twin half-edge in an adjacent triangle (or `-1` for outer half-edges on the convex hull).\n */\n this.halfedges = this._halfedges;\n\n this.update();\n }\n\n /**\n * Updates the triangulation if you modified `delaunay.coords` values in place, avoiding expensive memory allocations.\n * Useful for iterative relaxation algorithms such as Lloyd's.\n */\n update() {\n const {coords, _hullPrev: hullPrev, _hullNext: hullNext, _hullTri: hullTri, _hullHash: hullHash} = this;\n const n = coords.length >> 1;\n\n // populate an array of point indices; calculate input data bbox\n let minX = Infinity;\n let minY = Infinity;\n let maxX = -Infinity;\n let maxY = -Infinity;\n\n for (let i = 0; i < n; i++) {\n const x = coords[2 * i];\n const y = coords[2 * i + 1];\n if (x < minX) minX = x;\n if (y < minY) minY = y;\n if (x > maxX) maxX = x;\n if (y > maxY) maxY = y;\n this._ids[i] = i;\n }\n const cx = (minX + maxX) / 2;\n const cy = (minY + maxY) / 2;\n\n let i0 = 0, i1 = 0, i2 = 0;\n\n // pick a seed point close to the center\n for (let i = 0, minDist = Infinity; i < n; i++) {\n const d = dist(cx, cy, coords[2 * i], coords[2 * i + 1]);\n if (d < minDist) {\n i0 = i;\n minDist = d;\n }\n }\n const i0x = coords[2 * i0];\n const i0y = coords[2 * i0 + 1];\n\n // find the point closest to the seed\n for (let i = 0, minDist = Infinity; i < n; i++) {\n if (i === i0) continue;\n const d = dist(i0x, i0y, coords[2 * i], coords[2 * i + 1]);\n if (d < minDist && d > 0) {\n i1 = i;\n minDist = d;\n }\n }\n let i1x = coords[2 * i1];\n let i1y = coords[2 * i1 + 1];\n\n let minRadius = Infinity;\n\n // find the third point which forms the smallest circumcircle with the first two\n for (let i = 0; i < n; i++) {\n if (i === i0 || i === i1) continue;\n const r = circumradius(i0x, i0y, i1x, i1y, coords[2 * i], coords[2 * i + 1]);\n if (r < minRadius) {\n i2 = i;\n minRadius = r;\n }\n }\n let i2x = coords[2 * i2];\n let i2y = coords[2 * i2 + 1];\n\n if (minRadius === Infinity) {\n // order collinear points by dx (or dy if all x are identical)\n // and return the list as a hull\n for (let i = 0; i < n; i++) {\n this._dists[i] = (coords[2 * i] - coords[0]) || (coords[2 * i + 1] - coords[1]);\n }\n quicksort(this._ids, this._dists, 0, n - 1);\n const hull = new Uint32Array(n);\n let j = 0;\n for (let i = 0, d0 = -Infinity; i < n; i++) {\n const id = this._ids[i];\n const d = this._dists[id];\n if (d > d0) {\n hull[j++] = id;\n d0 = d;\n }\n }\n this.hull = hull.subarray(0, j);\n this.triangles = new Uint32Array(0);\n this.halfedges = new Int32Array(0);\n return;\n }\n\n // swap the order of the seed points for counter-clockwise orientation\n if (orient2d(i0x, i0y, i1x, i1y, i2x, i2y) < 0) {\n const i = i1;\n const x = i1x;\n const y = i1y;\n i1 = i2;\n i1x = i2x;\n i1y = i2y;\n i2 = i;\n i2x = x;\n i2y = y;\n }\n\n const center = circumcenter(i0x, i0y, i1x, i1y, i2x, i2y);\n this._cx = center.x;\n this._cy = center.y;\n\n for (let i = 0; i < n; i++) {\n this._dists[i] = dist(coords[2 * i], coords[2 * i + 1], center.x, center.y);\n }\n\n // sort the points by distance from the seed triangle circumcenter\n quicksort(this._ids, this._dists, 0, n - 1);\n\n // set up the seed triangle as the starting hull\n this._hullStart = i0;\n let hullSize = 3;\n\n hullNext[i0] = hullPrev[i2] = i1;\n hullNext[i1] = hullPrev[i0] = i2;\n hullNext[i2] = hullPrev[i1] = i0;\n\n hullTri[i0] = 0;\n hullTri[i1] = 1;\n hullTri[i2] = 2;\n\n hullHash.fill(-1);\n hullHash[this._hashKey(i0x, i0y)] = i0;\n hullHash[this._hashKey(i1x, i1y)] = i1;\n hullHash[this._hashKey(i2x, i2y)] = i2;\n\n this.trianglesLen = 0;\n this._addTriangle(i0, i1, i2, -1, -1, -1);\n\n for (let k = 0, xp = 0, yp = 0; k < this._ids.length; k++) {\n const i = this._ids[k];\n const x = coords[2 * i];\n const y = coords[2 * i + 1];\n\n // skip near-duplicate points\n if (k > 0 && Math.abs(x - xp) <= EPSILON && Math.abs(y - yp) <= EPSILON) continue;\n xp = x;\n yp = y;\n\n // skip seed triangle points\n if (i === i0 || i === i1 || i === i2) continue;\n\n // find a visible edge on the convex hull using edge hash\n let start = 0;\n for (let j = 0, key = this._hashKey(x, y); j < this._hashSize; j++) {\n start = hullHash[(key + j) % this._hashSize];\n if (start !== -1 && start !== hullNext[start]) break;\n }\n\n start = hullPrev[start];\n let e = start, q;\n while (q = hullNext[e], orient2d(x, y, coords[2 * e], coords[2 * e + 1], coords[2 * q], coords[2 * q + 1]) >= 0) {\n e = q;\n if (e === start) {\n e = -1;\n break;\n }\n }\n if (e === -1) continue; // likely a near-duplicate point; skip it\n\n // add the first triangle from the point\n let t = this._addTriangle(e, i, hullNext[e], -1, -1, hullTri[e]);\n\n // recursively flip triangles from the point until they satisfy the Delaunay condition\n hullTri[i] = this._legalize(t + 2);\n hullTri[e] = t; // keep track of boundary triangles on the hull\n hullSize++;\n\n // walk forward through the hull, adding more triangles and flipping recursively\n let n = hullNext[e];\n while (q = hullNext[n], orient2d(x, y, coords[2 * n], coords[2 * n + 1], coords[2 * q], coords[2 * q + 1]) < 0) {\n t = this._addTriangle(n, i, q, hullTri[i], -1, hullTri[n]);\n hullTri[i] = this._legalize(t + 2);\n hullNext[n] = n; // mark as removed\n hullSize--;\n n = q;\n }\n\n // walk backward from the other side, adding more triangles and flipping\n if (e === start) {\n while (q = hullPrev[e], orient2d(x, y, coords[2 * q], coords[2 * q + 1], coords[2 * e], coords[2 * e + 1]) < 0) {\n t = this._addTriangle(q, i, e, -1, hullTri[e], hullTri[q]);\n this._legalize(t + 2);\n hullTri[q] = t;\n hullNext[e] = e; // mark as removed\n hullSize--;\n e = q;\n }\n }\n\n // update the hull indices\n this._hullStart = hullPrev[i] = e;\n hullNext[e] = hullPrev[n] = i;\n hullNext[i] = n;\n\n // save the two new edges in the hash table\n hullHash[this._hashKey(x, y)] = i;\n hullHash[this._hashKey(coords[2 * e], coords[2 * e + 1])] = e;\n }\n\n this.hull = new Uint32Array(hullSize);\n for (let i = 0, e = this._hullStart; i < hullSize; i++) {\n this.hull[i] = e;\n e = hullNext[e];\n }\n\n // trim typed triangle mesh arrays\n this.triangles = this._triangles.subarray(0, this.trianglesLen);\n this.halfedges = this._halfedges.subarray(0, this.trianglesLen);\n }\n\n /**\n * Calculate an angle-based key for the edge hash used for advancing convex hull.\n *\n * @param {number} x\n * @param {number} y\n * @private\n */\n _hashKey(x, y) {\n return Math.floor(pseudoAngle(x - this._cx, y - this._cy) * this._hashSize) % this._hashSize;\n }\n\n /**\n * Flip an edge in a pair of triangles if it doesn't satisfy the Delaunay condition.\n *\n * @param {number} a\n * @private\n */\n _legalize(a) {\n const {_triangles: triangles, _halfedges: halfedges, coords} = this;\n\n let i = 0;\n let ar = 0;\n\n // recursion eliminated with a fixed-size stack\n while (true) {\n const b = halfedges[a];\n\n /* if the pair of triangles doesn't satisfy the Delaunay condition\n * (p1 is inside the circumcircle of [p0, pl, pr]), flip them,\n * then do the same check/flip recursively for the new pair of triangles\n *\n * pl pl\n * /||\\ / \\\n * al/ || \\bl al/ \\a\n * / || \\ / \\\n * / a||b \\ flip /___ar___\\\n * p0\\ || /p1 => p0\\---bl---/p1\n * \\ || / \\ /\n * ar\\ || /br b\\ /br\n * \\||/ \\ /\n * pr pr\n */\n const a0 = a - a % 3;\n ar = a0 + (a + 2) % 3;\n\n if (b === -1) { // convex hull edge\n if (i === 0) break;\n a = EDGE_STACK[--i];\n continue;\n }\n\n const b0 = b - b % 3;\n const al = a0 + (a + 1) % 3;\n const bl = b0 + (b + 2) % 3;\n\n const p0 = triangles[ar];\n const pr = triangles[a];\n const pl = triangles[al];\n const p1 = triangles[bl];\n\n const illegal = inCircle(\n coords[2 * p0], coords[2 * p0 + 1],\n coords[2 * pr], coords[2 * pr + 1],\n coords[2 * pl], coords[2 * pl + 1],\n coords[2 * p1], coords[2 * p1 + 1]);\n\n if (illegal) {\n triangles[a] = p1;\n triangles[b] = p0;\n\n const hbl = halfedges[bl];\n\n // edge swapped on the other side of the hull (rare); fix the half-edge reference\n if (hbl === -1) {\n let e = this._hullStart;\n do {\n if (this._hullTri[e] === bl) {\n this._hullTri[e] = a;\n break;\n }\n e = this._hullPrev[e];\n } while (e !== this._hullStart);\n }\n this._link(a, hbl);\n this._link(b, halfedges[ar]);\n this._link(ar, bl);\n\n const br = b0 + (b + 1) % 3;\n\n // don't worry about hitting the cap: it can only happen on extremely degenerate input\n if (i < EDGE_STACK.length) {\n EDGE_STACK[i++] = br;\n }\n } else {\n if (i === 0) break;\n a = EDGE_STACK[--i];\n }\n }\n\n return ar;\n }\n\n /**\n * Link two half-edges to each other.\n * @param {number} a\n * @param {number} b\n * @private\n */\n _link(a, b) {\n this._halfedges[a] = b;\n if (b !== -1) this._halfedges[b] = a;\n }\n\n /**\n * Add a new triangle given vertex indices and adjacent half-edge ids.\n *\n * @param {number} i0\n * @param {number} i1\n * @param {number} i2\n * @param {number} a\n * @param {number} b\n * @param {number} c\n * @private\n */\n _addTriangle(i0, i1, i2, a, b, c) {\n const t = this.trianglesLen;\n\n this._triangles[t] = i0;\n this._triangles[t + 1] = i1;\n this._triangles[t + 2] = i2;\n\n this._link(t, a);\n this._link(t + 1, b);\n this._link(t + 2, c);\n\n this.trianglesLen += 3;\n\n return t;\n }\n}\n\n/**\n * Monotonically increases with real angle, but doesn't need expensive trigonometry.\n *\n * @param {number} dx\n * @param {number} dy\n */\nfunction pseudoAngle(dx, dy) {\n const p = dx / (Math.abs(dx) + Math.abs(dy));\n return (dy > 0 ? 3 - p : 1 + p) / 4; // [0..1]\n}\n\n/**\n * Squared distance between two points.\n *\n * @param {number} ax\n * @param {number} ay\n * @param {number} bx\n * @param {number} by\n */\nfunction dist(ax, ay, bx, by) {\n const dx = ax - bx;\n const dy = ay - by;\n return dx * dx + dy * dy;\n}\n\n/**\n * Check whether point P is inside a circle formed by points A, B, C.\n *\n * @param {number} ax\n * @param {number} ay\n * @param {number} bx\n * @param {number} by\n * @param {number} cx\n * @param {number} cy\n * @param {number} px\n * @param {number} py\n */\nfunction inCircle(ax, ay, bx, by, cx, cy, px, py) {\n const dx = ax - px;\n const dy = ay - py;\n const ex = bx - px;\n const ey = by - py;\n const fx = cx - px;\n const fy = cy - py;\n\n const ap = dx * dx + dy * dy;\n const bp = ex * ex + ey * ey;\n const cp = fx * fx + fy * fy;\n\n return dx * (ey * cp - bp * fy) -\n dy * (ex * cp - bp * fx) +\n ap * (ex * fy - ey * fx) < 0;\n}\n\n/**\n * Squared radius of the circle formed by points A, B, C.\n *\n * @param {number} ax\n * @param {number} ay\n * @param {number} bx\n * @param {number} by\n * @param {number} cx\n * @param {number} cy\n */\nfunction circumradius(ax, ay, bx, by, cx, cy) {\n const dx = bx - ax;\n const dy = by - ay;\n const ex = cx - ax;\n const ey = cy - ay;\n\n const bl = dx * dx + dy * dy;\n const cl = ex * ex + ey * ey;\n const d = 0.5 / (dx * ey - dy * ex);\n\n const x = (ey * bl - dy * cl) * d;\n const y = (dx * cl - ex * bl) * d;\n\n return x * x + y * y;\n}\n\n/**\n * Get coordinates of a circumcenter for points A, B, C.\n *\n * @param {number} ax\n * @param {number} ay\n * @param {number} bx\n * @param {number} by\n * @param {number} cx\n * @param {number} cy\n */\nfunction circumcenter(ax, ay, bx, by, cx, cy) {\n const dx = bx - ax;\n const dy = by - ay;\n const ex = cx - ax;\n const ey = cy - ay;\n\n const bl = dx * dx + dy * dy;\n const cl = ex * ex + ey * ey;\n const d = 0.5 / (dx * ey - dy * ex);\n\n const x = ax + (ey * bl - dy * cl) * d;\n const y = ay + (dx * cl - ex * bl) * d;\n\n return {x, y};\n}\n\n/**\n * Sort points by distance via an array of point indices and an array of calculated distances.\n *\n * @param {Uint32Array} ids\n * @param {Float64Array} dists\n * @param {number} left\n * @param {number} right\n */\nfunction quicksort(ids, dists, left, right) {\n if (right - left <= 20) {\n for (let i = left + 1; i <= right; i++) {\n const temp = ids[i];\n const tempDist = dists[temp];\n let j = i - 1;\n while (j >= left && dists[ids[j]] > tempDist) ids[j + 1] = ids[j--];\n ids[j + 1] = temp;\n }\n } else {\n const median = (left + right) >> 1;\n let i = left + 1;\n let j = right;\n swap(ids, median, i);\n if (dists[ids[left]] > dists[ids[right]]) swap(ids, left, right);\n if (dists[ids[i]] > dists[ids[right]]) swap(ids, i, right);\n if (dists[ids[left]] > dists[ids[i]]) swap(ids, left, i);\n\n const temp = ids[i];\n const tempDist = dists[temp];\n while (true) {\n do i++; while (dists[ids[i]] < tempDist);\n do j--; while (dists[ids[j]] > tempDist);\n if (j < i) break;\n swap(ids, i, j);\n }\n ids[left + 1] = ids[j];\n ids[j] = temp;\n\n if (right - i + 1 >= j - left) {\n quicksort(ids, dists, i, right);\n quicksort(ids, dists, left, j - 1);\n } else {\n quicksort(ids, dists, left, j - 1);\n quicksort(ids, dists, i, right);\n }\n }\n}\n\n/**\n * @param {Uint32Array} arr\n * @param {number} i\n * @param {number} j\n */\nfunction swap(arr, i, j) {\n const tmp = arr[i];\n arr[i] = arr[j];\n arr[j] = tmp;\n}\n\n/** @param {[number, number]} p */\nfunction defaultGetX(p) {\n return p[0];\n}\n/** @param {[number, number]} p */\nfunction defaultGetY(p) {\n return p[1];\n}\n","import earcut from 'earcut';\n// eslint-disable-next-line import/no-extraneous-dependencies\nimport Delaunator from 'delaunator';\n\nexport default class TriangulateGrid {\n static inferRadarDims(points) {\n if (!Array.isArray(points) || points.length < 64) {\n return null;\n }\n\n const distances = [];\n for (let i = 1; i < points.length; i += 1) {\n const a = points[i - 1];\n const b = points[i];\n if (\n Array.isArray(a) &&\n Array.isArray(b) &&\n Number.isFinite(a[0]) &&\n Number.isFinite(a[1]) &&\n Number.isFinite(b[0]) &&\n Number.isFinite(b[1])\n ) {\n const dx = b[0] - a[0];\n const dy = b[1] - a[1];\n const d = Math.sqrt(dx * dx + dy * dy);\n if (Number.isFinite(d) && d > 0) {\n distances.push(d);\n }\n }\n }\n\n if (distances.length < 16) {\n return null;\n }\n\n const sorted = distances.slice().sort((a, b) => a - b);\n const median = sorted[Math.floor(sorted.length * 0.5)] || 0;\n if (!(median > 0)) {\n return null;\n }\n\n const jumpThreshold = median * 8;\n const rowStarts = [0];\n for (let i = 1; i < points.length; i += 1) {\n const a = points[i - 1];\n const b = points[i];\n if (\n Array.isArray(a) &&\n Array.isArray(b) &&\n Number.isFinite(a[0]) &&\n Number.isFinite(a[1]) &&\n Number.isFinite(b[0]) &&\n Number.isFinite(b[1])\n ) {\n const dx = b[0] - a[0];\n const dy = b[1] - a[1];\n const d = Math.sqrt(dx * dx + dy * dy);\n if (d > jumpThreshold) {\n rowStarts.push(i);\n }\n }\n }\n\n if (rowStarts.length < 8) {\n return null;\n }\n\n let minCols = Infinity;\n for (let r = 0; r < rowStarts.length; r += 1) {\n const start = rowStarts[r];\n const end = r + 1 < rowStarts.length ? rowStarts[r + 1] : points.length;\n const len = end - start;\n if (len < minCols) {\n minCols = len;\n }\n }\n\n if (!(minCols >= 8)) {\n return null;\n }\n\n return [rowStarts.length, minCols];\n }\n\n static buildRadarCellGeometry(points, dims, size = 3, elevation = 0) {\n const [rows, cols] = dims;\n const pointCount = rows * cols;\n if (rows < 2 || cols < 2 || !Array.isArray(points) || points.length < pointCount) {\n return null;\n }\n\n const cellCount = rows * (cols - 1);\n const verticesPerCell = 4;\n const vertices = new Float32Array(cellCount * verticesPerCell * size);\n const indices = new Uint32Array(cellCount * 6);\n\n let vw = 0;\n let iw = 0;\n let baseVertex = 0;\n\n for (let r = 0; r < rows; r += 1) {\n const rNext = (r + 1) % rows;\n for (let c = 0; c < cols; c += 1) {\n if (c >= cols - 1) {\n continue;\n }\n const i00 = r * cols + c;\n const i01 = i00 + 1;\n const i10 = rNext * cols + c;\n const i11 = i10 + 1;\n\n const p00 = points[i00];\n const p01 = points[i01];\n const p10 = points[i10];\n const p11 = points[i11];\n\n const sw = Array.isArray(p00) ? p00 : [0, 0];\n const se = Array.isArray(p01) ? p01 : [0, 0];\n const nw = Array.isArray(p10) ? p10 : [0, 0];\n const ne = Array.isArray(p11) ? p11 : [0, 0];\n\n // lower-left\n vertices[vw] = Number.isFinite(sw[0]) ? sw[0] : 0;\n vertices[vw + 1] = Number.isFinite(sw[1]) ? sw[1] : 0;\n vertices[vw + 2] = elevation;\n // lower-right\n vertices[vw + 3] = Number.isFinite(se[0]) ? se[0] : 0;\n vertices[vw + 4] = Number.isFinite(se[1]) ? se[1] : 0;\n vertices[vw + 5] = elevation;\n // upper-right\n vertices[vw + 6] = Number.isFinite(ne[0]) ? ne[0] : 0;\n vertices[vw + 7] = Number.isFinite(ne[1]) ? ne[1] : 0;\n vertices[vw + 8] = elevation;\n // upper-left\n vertices[vw + 9] = Number.isFinite(nw[0]) ? nw[0] : 0;\n vertices[vw + 10] = Number.isFinite(nw[1]) ? nw[1] : 0;\n vertices[vw + 11] = elevation;\n\n indices[iw] = baseVertex;\n indices[iw + 1] = baseVertex + 2;\n indices[iw + 2] = baseVertex + 1;\n indices[iw + 3] = baseVertex;\n indices[iw + 4] = baseVertex + 3;\n indices[iw + 5] = baseVertex + 2;\n\n vw += verticesPerCell * size;\n iw += 6;\n baseVertex += verticesPerCell;\n }\n }\n\n return [vertices, indices];\n }\n\n static buildSphericalQuadCenterGeometry(points, dims, size = 3, elevation = 0) {\n const [rows, cols] = dims;\n const pointCount = rows * cols;\n if (rows < 2 || cols < 2 || !Array.isArray(points) || points.length < pointCount) {\n return null;\n }\n\n const centerCount = rows * (cols - 1);\n const vertices = new Float32Array((pointCount + centerCount) * size);\n const indices = new Uint32Array(centerCount * 12);\n\n for (let i = 0; i < pointCount; i += 1) {\n const idx = i * size;\n const point = points[i];\n const lon = Array.isArray(point) && Number.isFinite(point[0]) ? point[0] : 0;\n const lat = Array.isArray(point) && Number.isFinite(point[1]) ? point[1] : 0;\n vertices[idx] = lon;\n vertices[idx + 1] = lat;\n vertices[idx + 2] = elevation;\n }\n\n let centerVertex = pointCount;\n let w = 0;\n for (let r = 0; r < rows; r += 1) {\n const rNext = (r + 1) % rows;\n for (let c = 0; c < cols - 1; c += 1) {\n const i00 = r * cols + c;\n const i10 = i00 + 1;\n const i01 = rNext * cols + c;\n const i11 = i01 + 1;\n\n const p00 = points[i00];\n const p10 = points[i10];\n const p01 = points[i01];\n const p11 = points[i11];\n\n const cidx = centerVertex * size;\n const lon00 = Array.isArray(p00) && Number.isFinite(p00[0]) ? p00[0] : 0;\n const lat00 = Array.isArray(p00) && Number.isFinite(p00[1]) ? p00[1] : 0;\n const lon10 = Array.isArray(p10) && Number.isFinite(p10[0]) ? p10[0] : 0;\n const lat10 = Array.isArray(p10) && Number.isFinite(p10[1]) ? p10[1] : 0;\n const lon01 = Array.isArray(p01) && Number.isFinite(p01[0]) ? p01[0] : 0;\n const lat01 = Array.isArray(p01) && Number.isFinite(p01[1]) ? p01[1] : 0;\n const lon11 = Array.isArray(p11) && Number.isFinite(p11[0]) ? p11[0] : 0;\n const lat11 = Array.isArray(p11) && Number.isFinite(p11[1]) ? p11[1] : 0;\n\n vertices[cidx] = (lon00 + lon10 + lon01 + lon11) * 0.25;\n vertices[cidx + 1] = (lat00 + lat10 + lat01 + lat11) * 0.25;\n vertices[cidx + 2] = elevation;\n\n indices[w] = i00;\n indices[w + 1] = centerVertex;\n indices[w + 2] = i10;\n indices[w + 3] = i10;\n indices[w + 4] = centerVertex;\n indices[w + 5] = i11;\n indices[w + 6] = i11;\n indices[w + 7] = centerVertex;\n indices[w + 8] = i01;\n indices[w + 9] = i01;\n indices[w + 10] = centerVertex;\n indices[w + 11] = i00;\n\n w += 12;\n centerVertex += 1;\n }\n }\n\n return [vertices, indices];\n }\n\n static compute1dBoundaries(centers) {\n const n = centers.length;\n const bounds = new Float64Array(n + 1);\n\n if (n === 0) {\n return bounds;\n }\n\n if (n === 1) {\n bounds[0] = centers[0] - 0.5;\n bounds[1] = centers[0] + 0.5;\n return bounds;\n }\n\n bounds[0] = centers[0] - (centers[1] - centers[0]) * 0.5;\n for (let i = 1; i < n; i += 1) {\n bounds[i] = (centers[i - 1] + centers[i]) * 0.5;\n }\n bounds[n] = centers[n - 1] + (centers[n - 1] - centers[n - 2]) * 0.5;\n\n return bounds;\n }\n\n static midpointBoundary(prev, curr, next) {\n if (prev != null && next != null) {\n return [(prev + curr) * 0.5, (curr + next) * 0.5];\n }\n if (next != null) {\n const halfStep = (next - curr) * 0.5;\n return [curr - halfStep, curr + halfStep];\n }\n if (prev != null) {\n const halfStep = (curr - prev) * 0.5;\n return [curr - halfStep, curr + halfStep];\n }\n return [curr - 0.5, curr + 0.5];\n }\n\n static buildGridCellGeometry(points, dims, size = 3, elevation = 0) {\n const [rows, cols] = dims;\n const cellCount = rows * cols;\n const verticesPerCell = 4;\n\n const getPoint = (r, c) => {\n if (r < 0 || r >= rows || c < 0 || c >= cols) return null;\n return points[r * cols + c];\n };\n\n const averagePoints = (plist) => {\n let lonSum = 0;\n let latSum = 0;\n let count = 0;\n for (let i = 0; i < plist.length; i += 1) {\n const p = plist[i];\n if (!Array.isArray(p)) continue;\n const lon = p[0];\n const lat = p[1];\n if (!Number.isFinite(lon) || !Number.isFinite(lat)) continue;\n lonSum += lon;\n latSum += lat;\n count += 1;\n }\n if (count === 0) return [0, 0];\n return [lonSum / count, latSum / count];\n };\n\n const vertices = new Float32Array(cellCount * verticesPerCell * size);\n const indices = new Uint32Array(cellCount * 6);\n\n let vw = 0;\n let iw = 0;\n let baseVertex = 0;\n\n for (let r = 0; r < rows; r += 1) {\n for (let c = 0; c < cols; c += 1) {\n const center = getPoint(r, c);\n\n // Build each corner from the center and its quadrant neighbors.\n // Adjacent cells reuse the same point set for shared corners/walls.\n const [swLon, swLat] = averagePoints([\n center,\n getPoint(r, c - 1),\n getPoint(r - 1, c),\n getPoint(r - 1, c - 1),\n ]);\n const [seLon, seLat] = averagePoints([\n center,\n getPoint(r, c + 1),\n getPoint(r - 1, c),\n getPoint(r - 1, c + 1),\n ]);\n const [neLon, neLat] = averagePoints([\n center,\n getPoint(r, c + 1),\n getPoint(r + 1, c),\n getPoint(r + 1, c + 1),\n ]);\n const [nwLon, nwLat] = averagePoints([\n center,\n getPoint(r, c - 1),\n getPoint(r + 1, c),\n getPoint(r + 1, c - 1),\n ]);\n\n // lower-left\n vertices[vw] = swLon;\n vertices[vw + 1] = swLat;\n vertices[vw + 2] = elevation;\n // lower-right\n vertices[vw + 3] = seLon;\n vertices[vw + 4] = seLat;\n vertices[vw + 5] = elevation;\n // upper-right\n vertices[vw + 6] = neLon;\n vertices[vw + 7] = neLat;\n vertices[vw + 8] = elevation;\n // upper-left\n vertices[vw + 9] = nwLon;\n vertices[vw + 10] = nwLat;\n vertices[vw + 11] = elevation;\n\n // Two triangles per cell.\n indices[iw] = baseVertex;\n indices[iw + 1] = baseVertex + 1;\n indices[iw + 2] = baseVertex + 2;\n indices[iw + 3] = baseVertex;\n indices[iw + 4] = baseVertex + 2;\n indices[iw + 5] = baseVertex + 3;\n\n vw += verticesPerCell * size;\n iw += 6;\n baseVertex += verticesPerCell;\n }\n }\n\n return [vertices, indices];\n }\n\n static flattenStructuredPoints(grid, dims) {\n if (!dims || !Array.isArray(grid[0]) || !Array.isArray(grid[0][0])) {\n return grid;\n }\n\n const [rows, cols] = dims;\n const points = new Array(rows * cols);\n let k = 0;\n for (let r = 0; r < rows; r += 1) {\n for (let c = 0; c < cols; c += 1) {\n points[k] = grid[r][c];\n k += 1;\n }\n }\n return points;\n }\n\n static flattenStructuredValues(grid, dims) {\n if (!dims || !Array.isArray(grid[0])) {\n return grid;\n }\n\n const [rows, cols] = dims;\n const values = new Float32Array(rows * cols);\n let k = 0;\n for (let r = 0; r < rows; r += 1) {\n for (let c = 0; c < cols; c += 1) {\n values[k] = grid[r][c];\n k += 1;\n }\n }\n return values;\n }\n\n static triangulate(\n grid,\n type,\n dims,\n size = 1,\n elevation = 0,\n scale = 1,\n triangulationMode = 'delaunay',\n ) {\n switch (type) {\n case 'data': {\n const values = Array.isArray(dims)\n ? TriangulateGrid.flattenStructuredValues(grid, dims)\n : grid;\n\n if (triangulationMode === 'spherical-cells' && Array.isArray(dims)) {\n const [rows, cols] = dims;\n const cellCount = rows * cols;\n const verticesPerCell = 4;\n const arr = new Float32Array(cellCount * verticesPerCell * size);\n let w = 0;\n for (let r = 0; r < rows; r += 1) {\n for (let c = 0; c < cols; c += 1) {\n const i00 = r * cols + c;\n const value = Number.isFinite(values[i00]) ? values[i00] : NaN;\n const scaledValue = value * scale;\n arr[w] = scaledValue;\n arr[w + 1] = scaledValue;\n arr[w + 2] = scaledValue;\n arr[w + 3] = scaledValue;\n w += verticesPerCell;\n }\n }\n return arr;\n }\n\n if (triangulationMode === 'spherical' && Array.isArray(dims)) {\n const [rows, cols] = dims;\n const pointCount = rows * cols;\n const centerCount = rows * (cols - 1);\n const arr = new Float32Array((pointCount + centerCount) * size);\n\n for (let i = 0; i < pointCount; i += 1) {\n const value = Number.isFinite(values[i]) ? values[i] : NaN;\n arr[i] = value * scale;\n }\n\n let centerIndex = pointCount;\n for (let r = 0; r < rows; r += 1) {\n const rNext = (r + 1) % rows;\n for (let c = 0; c < cols - 1; c += 1) {\n const i00 = r * cols + c;\n const i10 = i00 + 1;\n const i01 = rNext * cols + c;\n const i11 = i01 + 1;\n\n const v00 = values[i00];\n const v10 = values[i10];\n const v01 = values[i01];\n const v11 = values[i11];\n\n let sum = 0;\n let count = 0;\n if (Number.isFinite(v00)) {\n sum += v00;\n count += 1;\n }\n if (Number.isFinite(v10)) {\n sum += v10;\n count += 1;\n }\n if (Number.isFinite(v01)) {\n sum += v01;\n count += 1;\n }\n if (Number.isFinite(v11)) {\n sum += v11;\n count += 1;\n }\n\n arr[centerIndex] = count > 0 ? (sum / count) * scale : NaN;\n centerIndex += 1;\n }\n }\n\n return arr;\n }\n\n if (triangulationMode === 'quadkey-cells' && Array.isArray(dims)) {\n const verticesPerCell = 4;\n const arr = new Float32Array(values.length * verticesPerCell * size);\n let w = 0;\n for (let i = 0; i < values.length; i += 1) {\n const scaledValue = values[i] * scale;\n arr[w] = scaledValue;\n arr[w + 1] = scaledValue;\n arr[w + 2] = scaledValue;\n arr[w + 3] = scaledValue;\n w += verticesPerCell;\n }\n return arr;\n }\n\n if (triangulationMode === 'quadkey' && Array.isArray(dims)) {\n const [rows, cols] = dims;\n const baseCount = rows * cols;\n const centerCount = Math.max(0, (rows - 1) * (cols - 1));\n const arr = new Float32Array((baseCount + centerCount) * size);\n\n for (let i = 0; i < baseCount; i += 1) {\n arr[i] = values[i] * scale;\n }\n\n let centerIndex = baseCount;\n for (let r = 0; r < rows - 1; r += 1) {\n for (let c = 0; c < cols - 1; c += 1) {\n const i00 = r * cols + c;\n const i10 = i00 + 1;\n const i01 = (r + 1) * cols + c;\n const i11 = i01 + 1;\n\n arr[centerIndex] =\n (values[i00] + values[i10] + values[i01] + values[i11]) *\n 0.25 *\n scale;\n centerIndex += 1;\n }\n }\n\n return arr;\n }\n\n const arr = new Float32Array(values.length * size);\n for (let i = 0; i < values.length; i += 1) {\n arr[i] = values[i] * scale;\n }\n return arr;\n }\n\n case 'positions': {\n const points = Array.isArray(dims)\n ? TriangulateGrid.flattenStructuredPoints(grid, dims)\n : grid;\n\n if (triangulationMode === 'spherical-cells' && Array.isArray(dims)) {\n const radarGeometry = TriangulateGrid.buildGridCellGeometry(\n points,\n dims,\n size,\n elevation,\n );\n if (radarGeometry) {\n const [vertices, baseIndices] = radarGeometry;\n const indices = new Uint32Array(baseIndices.length);\n for (let i = 0; i < baseIndices.length; i += 3) {\n indices[i] = baseIndices[i];\n indices[i + 1] = baseIndices[i + 2];\n indices[i + 2] = baseIndices[i + 1];\n }\n return [vertices, indices];\n }\n }\n\n if (triangulationMode === 'spherical' && Array.isArray(dims)) {\n const sphericalGeometry = TriangulateGrid.buildSphericalQuadCenterGeometry(\n points,\n dims,\n size,\n elevation,\n );\n if (sphericalGeometry) {\n return sphericalGeometry;\n }\n }\n\n if (triangulationMode === 'quadkey-cells' && Array.isArray(dims)) {\n return TriangulateGrid.buildGridCellGeometry(points, dims, size, elevation);\n }\n\n const baseCount = points.length;\n const hasStructuredDims = Array.isArray(dims);\n const [rows, cols] = hasStructuredDims ? dims : [0, 0];\n const centerCount =\n triangulationMode === 'quadkey' && hasStructuredDims\n ? Math.max(0, (rows - 1) * (cols - 1))\n : 0;\n\n const arr = new Float32Array((baseCount + centerCount) * size);\n const flat = new Float32Array(baseCount * 2);\n\n for (let i = 0; i < points.length; i += 1) {\n const idx = i * size;\n const xy = i * 2;\n const lon = points[i][0];\n const lat = points[i][1];\n arr[idx] = lon;\n arr[idx + 1] = lat;\n arr[idx + 2] = elevation;\n flat[xy] = lon;\n flat[xy + 1] = lat;\n }\n\n if (triangulationMode === 'quadkey' && hasStructuredDims) {\n const indices = new Uint32Array((rows - 1) * (cols - 1) * 12);\n let w = 0;\n let centerVertex = rows * cols;\n\n for (let r = 0; r < rows - 1; r += 1) {\n for (let c = 0; c < cols - 1; c += 1) {\n const i00 = r * cols + c;\n const i10 = i00 + 1;\n const i01 = (r + 1) * cols + c;\n const i11 = i01 + 1;\n\n const p00 = points[i00];\n const p10 = points[i10];\n const p01 = points[i01];\n const p11 = points[i11];\n\n const cidx = centerVertex * size;\n arr[cidx] = (p00[0] + p10[0] + p01[0] + p11[0]) * 0.25;\n arr[cidx + 1] = (p00[1] + p10[1] + p01[1] + p11[1]) * 0.25;\n arr[cidx + 2] = elevation;\n\n indices[w] = i00;\n indices[w + 1] = i10;\n indices[w + 2] = centerVertex;\n indices[w + 3] = i10;\n indices[w + 4] = i11;\n indices[w + 5] = centerVertex;\n indices[w + 6] = i11;\n indices[w + 7] = i01;\n indices[w + 8] = centerVertex;\n indices[w + 9] = i01;\n indices[w + 10] = i00;\n indices[w + 11] = centerVertex;\n\n w += 12;\n centerVertex += 1;\n }\n }\n\n return [arr, indices];\n }\n\n const useDelaunay =\n triangulationMode === 'unstructured' ||\n triangulationMode === 'spherical' ||\n triangulationMode === 'spherical-cells' ||\n triangulationMode === 'delaunay';\n\n const triangleIndices = useDelaunay\n ? (() => {\n const { triangles } = Delaunator.from(points);\n const indices = new Uint32Array(triangles.length);\n for (let i = 0; i < triangles.length; i += 3) {\n // Deck/luma front-face setup here expects the opposite winding.\n indices[i] = triangles[i];\n indices[i + 1] = triangles[i + 2];\n indices[i + 2] = triangles[i + 1];\n }\n return indices;\n })()\n : new Uint32Array(earcut(flat));\n return [arr, triangleIndices];\n }\n\n default:\n throw new Error(`Unsupported triangulation type: ${type}`);\n }\n }\n}\n","import TriangulateGrid from '../shadedLayer/TriangulateGrid';\n\nfunction computeBounds(points) {\n let minX = Infinity;\n let maxX = -Infinity;\n let minY = Infinity;\n let maxY = -Infinity;\n\n for (let i = 0; i < points.length; i += 1) {\n const p = points[i];\n if (p && Number.isFinite(p[0]) && Number.isFinite(p[1])) {\n const [x, y] = p;\n if (x < minX) minX = x;\n if (x > maxX) maxX = x;\n if (y < minY) minY = y;\n if (y > maxY) maxY = y;\n }\n }\n\n if (\n !Number.isFinite(minX) ||\n !Number.isFinite(maxX) ||\n !Number.isFinite(minY) ||\n !Number.isFinite(maxY)\n ) {\n return null;\n }\n\n return { minX, maxX, minY, maxY };\n}\n\nfunction pointKey(point, tolX, tolY) {\n const qx = Math.round(point[0] / tolX);\n const qy = Math.round(point[1] / tolY);\n return `${qx}:${qy}`;\n}\n\nfunction interpolateEdge(a, b, va, vb, level) {\n if (!Number.isFinite(va) || !Number.isFinite(vb)) {\n return null;\n }\n\n if ((va < level && vb < level) || (va > level && vb > level)) {\n return null;\n }\n\n const dv = vb - va;\n if (Math.abs(dv) < 1e-15) {\n return null;\n }\n\n const t = (level - va) / dv;\n if (t < 0 || t > 1) {\n return null;\n }\n\n return [a[0] + t * (b[0] - a[0]), a[1] + t * (b[1] - a[1])];\n}\n\nfunction uniquePoints(points) {\n const out = [];\n const eps = 1e-12;\n\n for (let i = 0; i < points.length; i += 1) {\n const p = points[i];\n let exists = false;\n for (let j = 0; j < out.length; j += 1) {\n const q = out[j];\n if (Math.abs(p[0] - q[0]) <= eps && Math.abs(p[1] - q[1]) <= eps) {\n exists = true;\n break;\n }\n }\n if (!exists) {\n out.push(p);\n }\n }\n\n return out;\n}\n\nfunction stitchSegments(segments, bounds) {\n if (!segments || segments.length === 0) {\n return [];\n }\n\n const dx = Math.max(1e-12, bounds.maxX - bounds.minX);\n const dy = Math.max(1e-12, bounds.maxY - bounds.minY);\n const tolX = dx * 1e-6;\n const tolY = dy * 1e-6;\n\n const nodes = new Map();\n const edges = [];\n\n function getNode(key, point) {\n let node = nodes.get(key);\n if (!node) {\n node = { point, edges: [] };\n nodes.set(key, node);\n }\n return node;\n }\n\n for (let i = 0; i < segments.length; i += 1) {\n const [a, b] = segments[i];\n const aKey = pointKey(a, tolX, tolY);\n const bKey = pointKey(b, tolX, tolY);\n\n if (aKey !== bKey) {\n const edgeId = edges.length;\n edges.push({ aKey, bKey, used: false });\n getNode(aKey, a).edges.push(edgeId);\n getNode(bKey, b).edges.push(edgeId);\n }\n }\n\n function otherKey(edge, key) {\n return edge.aKey === key ? edge.bKey : edge.aKey;\n }\n\n function trace(startKey, firstEdgeId) {\n const line = [nodes.get(startKey).point];\n let currentKey = startKey;\n let edgeId = firstEdgeId;\n\n while (edgeId != null) {\n const edge = edges[edgeId];\n if (edge.used) {\n break;\n }\n edge.used = true;\n\n const nextKey = otherKey(edge, currentKey);\n line.push(nodes.get(nextKey).point);\n\n const nextNode = nodes.get(nextKey);\n let nextEdgeId = null;\n for (let i = 0; i < nextNode.edges.length; i += 1) {\n const candidate = nextNode.edges[i];\n if (!edges[candidate].used) {\n nextEdgeId = candidate;\n break;\n }\n }\n\n currentKey = nextKey;\n edgeId = nextEdgeId;\n }\n\n return line;\n }\n\n const lines = [];\n for (const [key, node] of nodes.entries()) {\n if (node.edges.length !== 2) {\n for (let i = 0; i < node.edges.length; i += 1) {\n const edgeId = node.edges[i];\n if (!edges[edgeId].used) {\n lines.push(trace(key, edgeId));\n }\n }\n }\n }\n\n for (const [key, node] of nodes.entries()) {\n for (let i = 0; i < node.edges.length; i += 1) {\n const edgeId = node.edges[i];\n if (!edges[edgeId].used) {\n lines.push(trace(key, edgeId));\n }\n }\n }\n\n return lines.filter((line) => line.length > 1);\n}\n\nexport default function triangleContours(lonlatGrid, values, levels, shape = null) {\n const points = lonlatGrid;\n const flattenedValues = values;\n\n const pairCount = Math.min(points.length, flattenedValues.length);\n const validPoints = [];\n const validValues = [];\n for (let i = 0; i < pairCount; i += 1) {\n const point = points[i];\n if (point && Number.isFinite(point[0]) && Number.isFinite(point[1])) {\n validPoints.push(point);\n validValues.push(flattenedValues[i]);\n }\n }\n\n const count = validPoints.length;\n\n if (count < 3) {\n return { type: 'FeatureCollection', features: [] };\n }\n\n const levelsArray = (levels || []).filter((level) => Number.isFinite(level));\n if (levelsArray.length === 0) {\n return { type: 'FeatureCollection', features: [] };\n }\n\n const [vertices, indices] = TriangulateGrid.triangulate(\n validPoints,\n 'positions',\n null,\n 3,\n 0,\n 1,\n 'delaunay',\n );\n\n if (!indices || indices.length < 3) {\n return { type: 'FeatureCollection', features: [] };\n }\n\n const coords = new Array(vertices.length / 3);\n for (let i = 0; i < coords.length; i += 1) {\n const base = i * 3;\n coords[i] = [vertices[base], vertices[base + 1]];\n }\n\n const bounds = computeBounds(validPoints);\n if (!bounds) {\n return { type: 'FeatureCollection', features: [] };\n }\n\n const features = [];\n\n for (let li = 0; li < levelsArray.length; li += 1) {\n const level = levelsArray[li];\n const segments = [];\n\n for (let i = 0; i < indices.length; i += 3) {\n const ia = indices[i];\n const ib = indices[i + 1];\n const ic = indices[i + 2];\n\n if (ia < count && ib < count && ic < count) {\n const va = validValues[ia];\n const vb = validValues[ib];\n const vc = validValues[ic];\n\n if (Number.isFinite(va) && Number.isFinite(vb) && Number.isFinite(vc)) {\n const a = coords[ia];\n const b = coords[ib];\n const c = coords[ic];\n\n const intersections = uniquePoints(\n [\n interpolateEdge(a, b, va, vb, level),\n interpolateEdge(b, c, vb, vc, level),\n interpolateEdge(c, a, vc, va, level),\n ].filter(Boolean),\n );\n\n if (intersections.length >= 2) {\n segments.push([intersections[0], intersections[1]]);\n }\n }\n }\n }\n\n const lines = stitchSegments(segments, bounds);\n if (lines.length > 0) {\n features.push({\n type: 'Feature',\n geometry: {\n type: 'MultiLineString',\n coordinates: lines,\n },\n properties: [{ value: level }],\n });\n }\n }\n\n return {\n type: 'FeatureCollection',\n features,\n };\n}\n","// https://github.com/rveciana/raster-marching-squares#readme Version 0.1.2. Copyright 2019 Roger Veciana i Rovira.\n// Modified by travis.wilson@noaa.gov to work with deck.gl and DESI\n\nexport const isobands = function (data, lonlatGrid, geotransform, intervals) {\n const bands = { type: 'FeatureCollection', features: [] };\n for (let i = 1; i < intervals.length; i++) {\n const lowerValue = intervals[i - 1];\n const upperValue = intervals[i];\n var coords = projectedIsoband(\n data,\n lonlatGrid,\n geotransform,\n lowerValue,\n upperValue - lowerValue,\n );\n // Change clockwise\n Object.keys(coords).forEach((element) => {\n for (let j = 0; j < coords[element].length; j++) coords[element][j].reverse();\n });\n // for(var j=0; j< coords.length; j++)\n // coords[j].reverse();\n\n bands.features.push({\n type: 'Feature',\n geometry: {\n type: 'Polygon',\n coordinates: coords,\n },\n properties: [{ lowerValue, upperValue }],\n });\n }\n\n return bands;\n};\n\nexport const projectedIsoband = function (data, lonlatGrid, geotransform, minV, bandwidth) {\n const coords = isoband(data, minV, bandwidth);\n Object.keys(coords).forEach((element) => {\n for (let i = 0; i < coords[element].length; i++) {\n for (let j = 0; j < coords[element][i].length; j++) {\n const coordsGeo = applyGeoTransform(\n coords[element][i][j][0],\n coords[element][i][j][1],\n lonlatGrid,\n geotransform,\n );\n coords[element][i][j][0] = coordsGeo[0];\n coords[element][i][j][1] = coordsGeo[1];\n }\n }\n });\n\n return coords;\n};\n\n/**\n Xgeo = GT(0) + Xpixel*GT(1) + Yline*GT(2)\n Ygeo = GT(3) + Xpixel*GT(4) + Yline*GT(5)\n*/\nconst applyGeoTransform = function (i, j, lonlatGrid, geotransform) {\n if (geotransform) {\n var xgeo = geotransform[0] + i * geotransform[1] + j * geotransform[2];\n var ygeo = geotransform[3] + i * geotransform[4] + j * geotransform[5];\n } else {\n const i_f = Math.floor(i);\n const i_c = Math.ceil(i);\n const j_f = Math.floor(j);\n const j_c = Math.ceil(j);\n\n // p3-----p4\n // |------|\n // p1-----p2\n\n const p1 = lonlatGrid[j_c][i_f];\n const p2 = lonlatGrid[j_c][i_c];\n const p3 = lonlatGrid[j_f][i_f];\n const p4 = lonlatGrid[j_f][i_c];\n\n const i_w = 1 - (i - i_f);\n const i_w2 = 1 - i_w;\n const j_w = 1 - (j - j_f);\n const j_w2 = 1 - j_w;\n\n var xgeo =\n p3[0] * i_w * j_w + p1[0] * i_w * j_w2 + p4[0] * i_w2 * j_w + p2[0] * i_w2 * j_w2;\n\n var ygeo =\n p3[1] * i_w * j_w + p1[1] * i_w * j_w2 + p4[1] * i_w2 * j_w + p2[1] * i_w2 * j_w2;\n }\n\n // var xgeo = geoTransform[0] + x*geoTransform[1] + y*geoTransform[2];\n // var ygeo = geoTransform[3] + x*geoTransform[4] + y*geoTransform[5];\n return [xgeo, ygeo];\n};\n\n/*\n Compute isobands(s) of a scalar 2D field given a certain\n threshold and a bandwidth by applying the Marching Squares\n Algorithm. The function returns a list of path coordinates\n either for individual polygons within each grid cell, or the\n outline of connected polygons.\n*/\nexport const isoband = function (data, minV, bandwidth, options) {\n const settings = {};\n const defaultSettings = {\n successCallback: null,\n progressCallback: null,\n verbose: false,\n };\n\n /* process options */\n options = options || {};\n\n const optionKeys = Object.keys(defaultSettings);\n\n for (let i = 0; i < optionKeys.length; i++) {\n const key = optionKeys[i];\n let val = options[key];\n val = typeof val !== 'undefined' && val !== null ? val : defaultSettings[key];\n\n settings[key] = val;\n }\n\n if (settings.verbose) console.log(`computing isobands for [${minV}:${minV + bandwidth}]`);\n\n const grid = computeBandGrid(data, minV, bandwidth);\n\n const ret = BandGrid2AreaPaths(grid);\n\n return ret;\n};\n\n/*\n Thats all for the public interface, below follows the actual\n implementation\n*/\n\n/* Some private variables */\nconst Node0 = 64;\nconst Node1 = 16;\nconst Node2 = 4;\nconst Node3 = 1;\n\n/* For isoBands, each square is defined by the three states\n of its corner points. However, since computers use power-2\n values, we use 2bits per trit, i.e.:\n\n 00 ... below minV\n 01 ... between minV and maxV\n 10 ... above maxV\n\n Hence we map the 4-trit configurations as follows:\n\n 0000 => 0\n 0001 => 1\n 0002 => 2\n 0010 => 4\n 0011 => 5\n 0012 => 6\n 0020 => 8\n 0021 => 9\n 0022 => 10\n 0100 => 16\n 0101 => 17\n 0102 => 18\n 0110 => 20\n 0111 => 21\n 0112 => 22\n 0120 => 24\n 0121 => 25\n 0122 => 26\n 0200 => 32\n 0201 => 33\n 0202 => 34\n 0210 => 36\n 0211 => 37\n 0212 => 38\n 0220 => 40\n 0221 => 41\n 0222 => 42\n 1000 => 64\n 1001 => 65\n 1002 => 66\n 1010 => 68\n 1011 => 69\n 1012 => 70\n 1020 => 72\n 1021 => 73\n 1022 => 74\n 1100 => 80\n 1101 => 81\n 1102 => 82\n 1110 => 84\n 1111 => 85\n 1112 => 86\n 1120 => 88\n 1121 => 89\n 1122 => 90\n 1200 => 96\n 1201 => 97\n 1202 => 98\n 1210 => 100\n 1211 => 101\n 1212 => 102\n 1220 => 104\n 1221 => 105\n 1222 => 106\n 2000 => 128\n 2001 => 129\n 2002 => 130\n 2010 => 132\n 2011 => 133\n 2012 => 134\n 2020 => 136\n 2021 => 137\n 2022 => 138\n 2100 => 144\n 2101 => 145\n 2102 => 146\n 2110 => 148\n 2111 => 149\n 2112 => 150\n 2120 => 152\n 2121 => 153\n 2122 => 154\n 2200 => 160\n 2201 => 161\n 2202 => 162\n 2210 => 164\n 2211 => 165\n 2212 => 166\n 2220 => 168\n 2221 => 169\n 2222 => 170\n*/\n\n/*\n The look-up tables for tracing back the contour path\n of isoBands\n*/\n\nconst isoBandNextXTL = [];\nconst isoBandNextYTL = [];\nconst isoBandNextOTL = [];\n\nconst isoBandNextXTR = [];\nconst isoBandNextYTR = [];\nconst isoBandNextOTR = [];\n\nconst isoBandNextXRT = [];\nconst isoBandNextYRT = [];\nconst isoBandNextORT = [];\n\nconst isoBandNextXRB = [];\nconst isoBandNextYRB = [];\nconst isoBandNextORB = [];\n\nconst isoBandNextXBL = [];\nconst isoBandNextYBL = [];\nconst isoBandNextOBL = [];\n\nconst isoBandNextXBR = [];\nconst isoBandNextYBR = [];\nconst isoBandNextOBR = [];\n\nconst isoBandNextXLT = [];\nconst isoBandNextYLT = [];\nconst isoBandNextOLT = [];\n\nconst isoBandNextXLB = [];\nconst isoBandNextYLB = [];\nconst isoBandNextOLB = [];\n\nisoBandNextXRT[85] = isoBandNextXRB[85] = -1;\nisoBandNextYRT[85] = isoBandNextYRB[85] = 0;\nisoBandNextORT[85] = isoBandNextORB[85] = 1;\nisoBandNextXLT[85] = isoBandNextXLB[85] = 1;\nisoBandNextYLT[85] = isoBandNextYLB[85] = 0;\nisoBandNextOLT[85] = isoBandNextOLB[85] = 1;\n\nisoBandNextXTL[85] = isoBandNextXTR[85] = 0;\nisoBandNextYTL[85] = isoBandNextYTR[85] = -1;\nisoBandNextOTL[85] = isoBandNextOBL[85] = 0;\nisoBandNextXBR[85] = isoBandNextXBL[85] = 0;\nisoBandNextYBR[85] = isoBandNextYBL[85] = 1;\nisoBandNextOTR[85] = isoBandNextOBR[85] = 1;\n\n/* triangle cases */\nisoBandNextXLB[1] = isoBandNextXLB[169] = 0;\nisoBandNextYLB[1] = isoBandNextYLB[169] = -1;\nisoBandNextOLB[1] = isoBandNextOLB[169] = 0;\nisoBandNextXBL[1] = isoBandNextXBL[169] = -1;\nisoBandNextYBL[1] = isoBandNextYBL[169] = 0;\nisoBandNextOBL[1] = isoBandNextOBL[169] = 0;\n\nisoBandNextXRB[4] = isoBandNextXRB[166] = 0;\nisoBandNextYRB[4] = isoBandNextYRB[166] = -1;\nisoBandNextORB[4] = isoBandNextORB[166] = 1;\nisoBandNextXBR[4] = isoBandNextXBR[166] = 1;\nisoBandNextYBR[4] = isoBandNextYBR[166] = 0;\nisoBandNextOBR[4] = isoBandNextOBR[166] = 0;\n\nisoBandNextXRT[16] = isoBandNextXRT[154] = 0;\nisoBandNextYRT[16] = isoBandNextYRT[154] = 1;\nisoBandNextORT[16] = isoBandNextORT[154] = 1;\nisoBandNextXTR[16] = isoBandNextXTR[154] = 1;\nisoBandNextYTR[16] = isoBandNextYTR[154] = 0;\nisoBandNextOTR[16] = isoBandNextOTR[154] = 1;\n\nisoBandNextXLT[64] = isoBandNextXLT[106] = 0;\nisoBandNextYLT[64] = isoBandNextYLT[106] = 1;\nisoBandNextOLT[64] = isoBandNextOLT[106] = 0;\nisoBandNextXTL[64] = isoBandNextXTL[106] = -1;\nisoBandNextYTL[64] = isoBandNextYTL[106] = 0;\nisoBandNextOTL[64] = isoBandNextOTL[106] = 1;\n\n/* single trapezoid cases */\nisoBandNextXLT[2] = isoBandNextXLT[168] = 0;\nisoBandNextYLT[2] = isoBandNextYLT[168] = -1;\nisoBandNextOLT[2] = isoBandNextOLT[168] = 1;\nisoBandNextXLB[2] = isoBandNextXLB[168] = 0;\nisoBandNextYLB[2] = isoBandNextYLB[168] = -1;\nisoBandNextOLB[2] = isoBandNextOLB[168] = 0;\nisoBandNextXBL[2] = isoBandNextXBL[168] = -1;\nisoBandNextYBL[2] = isoBandNextYBL[168] = 0;\nisoBandNextOBL[2] = isoBandNextOBL[168] = 0;\nisoBandNextXBR[2] = isoBandNextXBR[168] = -1;\nisoBandNextYBR[2] = isoBandNextYBR[168] = 0;\nisoBandNextOBR[2] = isoBandNextOBR[168] = 1;\n\nisoBandNextXRT[8] = isoBandNextXRT[162] = 0;\nisoBandNextYRT[8] = isoBandNextYRT[162] = -1;\nisoBandNextORT[8] = isoBandNextORT[162] = 0;\nisoBandNextXRB[8] = isoBandNextXRB[162] = 0;\nisoBandNextYRB[8] = isoBandNextYRB[162] = -1;\nisoBandNextORB[8] = isoBandNextORB[162] = 1;\nisoBandNextXBL[8] = isoBandNextXBL[162] = 1;\nisoBandNextYBL[8] = isoBandNextYBL[162] = 0;\nisoBandNextOBL[8] = isoBandNextOBL[162] = 1;\nisoBandNextXBR[8] = isoBandNextXBR[162] = 1;\nisoBandNextYBR[8] = isoBandNextYBR[162] = 0;\nisoBandNextOBR[8] = isoBandNextOBR[162] = 0;\n\nisoBandNextXRT[32] = isoBandNextXRT[138] = 0;\nisoBandNextYRT[32] = isoBandNextYRT[138] = 1;\nisoBandNextORT[32] = isoBandNextORT[138] = 1;\nisoBandNextXRB[32] = isoBandNextXRB[138] = 0;\nisoBandNextYRB[32] = isoBandNextYRB[138] = 1;\nisoBandNextORB[32] = isoBandNextORB[138] = 0;\nisoBandNextXTL[32] = isoBandNextXTL[138] = 1;\nisoBandNextYTL[32] = isoBandNextYTL[138] = 0;\nisoBandNextOTL[32] = isoBandNextOTL[138] = 0;\nisoBandNextXTR[32] = isoBandNextXTR[138] = 1;\nisoBandNextYTR[32] = isoBandNextYTR[138] = 0;\nisoBandNextOTR[32] = isoBandNextOTR[138] = 1;\n\nisoBandNextXLB[128] = isoBandNextXLB[42] = 0;\nisoBandNextYLB[128] = isoBandNextYLB[42] = 1;\nisoBandNextOLB[128] = isoBandNextOLB[42] = 1;\nisoBandNextXLT[128] = isoBandNextXLT[42] = 0;\nisoBandNextYLT[128] = isoBandNextYLT[42] = 1;\nisoBandNextOLT[128] = isoBandNextOLT[42] = 0;\nisoBandNextXTL[128] = isoBandNextXTL[42] = -1;\nisoBandNextYTL[128] = isoBandNextYTL[42] = 0;\nisoBandNextOTL[128] = isoBandNextOTL[42] = 1;\nisoBandNextXTR[128] = isoBandNextXTR[42] = -1;\nisoBandNextYTR[128] = isoBandNextYTR[42] = 0;\nisoBandNextOTR[128] = isoBandNextOTR[42] = 0;\n\n/* single rectangle cases */\nisoBandNextXRB[5] = isoBandNextXRB[165] = -1;\nisoBandNextYRB[5] = isoBandNextYRB[165] = 0;\nisoBandNextORB[5] = isoBandNextORB[165] = 0;\nisoBandNextXLB[5] = isoBandNextXLB[165] = 1;\nisoBandNextYLB[5] = isoBandNextYLB[165] = 0;\nisoBandNextOLB[5] = isoBandNextOLB[165] = 0;\n\nisoBandNextXBR[20] = isoBandNextXBR[150] = 0;\nisoBandNextYBR[20] = isoBandNextYBR[150] = 1;\nisoBandNextOBR[20] = isoBandNextOBR[150] = 1;\nisoBandNextXTR[20] = isoBandNextXTR[150] = 0;\nisoBandNextYTR[20] = isoBandNextYTR[150] = -1;\nisoBandNextOTR[20] = isoBandNextOTR[150] = 1;\n\nisoBandNextXRT[80] = isoBandNextXRT[90] = -1;\nisoBandNextYRT[80] = isoBandNextYRT[90] = 0;\nisoBandNextORT[80] = isoBandNextORT[90] = 1;\nisoBandNextXLT[80] = isoBandNextXLT[90] = 1;\nisoBandNextYLT[80] = isoBandNextYLT[90] = 0;\nisoBandNextOLT[80] = isoBandNextOLT[90] = 1;\n\nisoBandNextXBL[65] = isoBandNextXBL[105] = 0;\nisoBandNextYBL[65] = isoBandNextYBL[105] = 1;\nisoBandNextOBL[65] = isoBandNextOBL[105] = 0;\nisoBandNextXTL[65] = isoBandNextXTL[105] = 0;\nisoBandNextYTL[65] = isoBandNextYTL[105] = -1;\nisoBandNextOTL[65] = isoBandNextOTL[105] = 0;\n\nisoBandNextXRT[160] = isoBandNextXRT[10] = -1;\nisoBandNextYRT[160] = isoBandNextYRT[10] = 0;\nisoBandNextORT[160] = isoBandNextORT[10] = 1;\nisoBandNextXRB[160] = isoBandNextXRB[10] = -1;\nisoBandNextYRB[160] = isoBandNextYRB[10] = 0;\nisoBandNextORB[160] = isoBandNextORB[10] = 0;\nisoBandNextXLB[160] = isoBandNextXLB[10] = 1;\nisoBandNextYLB[160] = isoBandNextYLB[10] = 0;\nisoBandNextOLB[160] = isoBandNextOLB[10] = 0;\nisoBandNextXLT[160] = isoBandNextXLT[10] = 1;\nisoBandNextYLT[160] = isoBandNextYLT[10] = 0;\nisoBandNextOLT[160] = isoBandNextOLT[10] = 1;\n\nisoBandNextXBR[130] = isoBandNextXBR[40] = 0;\nisoBandNextYBR[130] = isoBandNextYBR[40] = 1;\nisoBandNextOBR[130] = isoBandNextOBR[40] = 1;\nisoBandNextXBL[130] = isoBandNextXBL[40] = 0;\nisoBandNextYBL[130] = isoBandNextYBL[40] = 1;\nisoBandNextOBL[130] = isoBandNextOBL[40] = 0;\nisoBandNextXTL[130] = isoBandNextXTL[40] = 0;\nisoBandNextYTL[130] = isoBandNextYTL[40] = -1;\nisoBandNextOTL[130] = isoBandNextOTL[40] = 0;\nisoBandNextXTR[130] = isoBandNextXTR[40] = 0;\nisoBandNextYTR[130] = isoBandNextYTR[40] = -1;\nisoBandNextOTR[130] = isoBandNextOTR[40] = 1;\n\n/* single hexagon cases */\nisoBandNextXRB[37] = isoBandNextXRB[133] = 0;\nisoBandNextYRB[37] = isoBandNextYRB[133] = 1;\nisoBandNextORB[37] = isoBandNextORB[133] = 1;\nisoBandNextXLB[37] = isoBandNextXLB[133] = 0;\nisoBandNextYLB[37] = isoBandNextYLB[133] = 1;\nisoBandNextOLB[37] = isoBandNextOLB[133] = 0;\nisoBandNextXTL[37] = isoBandNextXTL[133] = -1;\nisoBandNextYTL[37] = isoBandNextYTL[133] = 0;\nisoBandNextOTL[37] = isoBandNextOTL[133] = 0;\nisoBandNextXTR[37] = isoBandNextXTR[133] = 1;\nisoBandNextYTR[37] = isoBandNextYTR[133] = 0;\nisoBandNextOTR[37] = isoBandNextOTR[133] = 0;\n\nisoBandNextXBR[148] = isoBandNextXBR[22] = -1;\nisoBandNextYBR[148] = isoBandNextYBR[22] = 0;\nisoBandNextOBR[148] = isoBandNextOBR[22] = 0;\nisoBandNextXLB[148] = isoBandNextXLB[22] = 0;\nisoBandNextYLB[148] = isoBandNextYLB[22] = -1;\nisoBandNextOLB[148] = isoBandNextOLB[22] = 1;\nisoBandNextXLT[148] = isoBandNextXLT[22] = 0;\nisoBandNextYLT[148] = isoBandNextYLT[22] = 1;\nisoBandNextOLT[148] = isoBandNextOLT[22] = 1;\nisoBandNextXTR[148] = isoBandNextXTR[22] = -1;\nisoBandNextYTR[148] = isoBandNextYTR[22] = 0;\nisoBandNextOTR[148] = isoBandNextOTR[22] = 1;\n\nisoBandNextXRT[82] = isoBandNextXRT[88] = 0;\nisoBandNextYRT[82] = isoBandNextYRT[88] = -1;\nisoBandNextORT[82] = isoBandNextORT[88] = 1;\nisoBandNextXBR[82] = isoBandNextXBR[88] = 1;\nisoBandNextYBR[82] = isoBandNextYBR[88] = 0;\nisoBandNextOBR[82] = isoBandNextOBR[88] = 1;\nisoBandNextXBL[82] = isoBandNextXBL[88] = -1;\nisoBandNextYBL[82] = isoBandNextYBL[88] = 0;\nisoBandNextOBL[82] = isoBandNextOBL[88] = 1;\nisoBandNextXLT[82] = isoBandNextXLT[88] = 0;\nisoBandNextYLT[82] = isoBandNextYLT[88] = -1;\nisoBandNextOLT[82] = isoBandNextOLT[88] = 0;\n\nisoBandNextXRT[73] = isoBandNextXRT[97] = 0;\nisoBandNextYRT[73] = isoBandNextYRT[97] = 1;\nisoBandNextORT[73] = isoBandNextORT[97] = 0;\nisoBandNextXRB[73] = isoBandNextXRB[97] = 0;\nisoBandNextYRB[73] = isoBandNextYRB[97] = -1;\nisoBandNextORB[73] = isoBandNextORB[97] = 0;\nisoBandNextXBL[73] = isoBandNextXBL[97] = 1;\nisoBandNextYBL[73] = isoBandNextYBL[97] = 0;\nisoBandNextOBL[73] = isoBandNextOBL[97] = 0;\nisoBandNextXTL[73] = isoBandNextXTL[97] = 1;\nisoBandNextYTL[73] = isoBandNextYTL[97] = 0;\nisoBandNextOTL[73] = isoBandNextOTL[97] = 1;\n\nisoBandNextXRT[145] = isoBandNextXRT[25] = 0;\nisoBandNextYRT[145] = isoBandNextYRT[25] = -1;\nisoBandNextORT[145] = isoBandNextORT[25] = 0;\nisoBandNextXBL[145] = isoBandNextXBL[25] = 1;\nisoBandNextYBL[145] = isoBandNextYBL[25] = 0;\nisoBandNextOBL[145] = isoBandNextOBL[25] = 1;\nisoBandNextXLB[145] = isoBandNextXLB[25] = 0;\nisoBandNextYLB[145] = isoBandNextYLB[25] = 1;\nisoBandNextOLB[145] = isoBandNextOLB[25] = 1;\nisoBandNextXTR[145] = isoBandNextXTR[25] = -1;\nisoBandNextYTR[145] = isoBandNextYTR[25] = 0;\nisoBandNextOTR[145] = isoBandNextOTR[25] = 0;\n\nisoBandNextXRB[70] = isoBandNextXRB[100] = 0;\nisoBandNextYRB[70] = isoBandNextYRB[100] = 1;\nisoBandNextORB[70] = isoBandNextORB[100] = 0;\nisoBandNextXBR[70] = isoBandNextXBR[100] = -1;\nisoBandNextYBR[70] = isoBandNextYBR[100] = 0;\nisoBandNextOBR[70] = isoBandNextOBR[100] = 1;\nisoBandNextXLT[70] = isoBandNextXLT[100] = 0;\nisoBandNextYLT[70] = isoBandNextYLT[100] = -1;\nisoBandNextOLT[70] = isoBandNextOLT[100] = 1;\nisoBandNextXTL[70] = isoBandNextXTL[100] = 1;\nisoBandNextYTL[70] = isoBandNextYTL[100] = 0;\nisoBandNextOTL[70] = isoBandNextOTL[100] = 0;\n\n/* single pentagon cases */\nisoBandNextXRB[101] = isoBandNextXRB[69] = 0;\nisoBandNextYRB[101] = isoBandNextYRB[69] = 1;\nisoBandNextORB[101] = isoBandNextORB[69] = 0;\nisoBandNextXTL[101] = isoBandNextXTL[69] = 1;\nisoBandNextYTL[101] = isoBandNextYTL[69] = 0;\nisoBandNextOTL[101] = isoBandNextOTL[69] = 0;\n\nisoBandNextXLB[149] = isoBandNextXLB[21] = 0;\nisoBandNextYLB[149] = isoBandNextYLB[21] = 1;\nisoBandNextOLB[149] = isoBandNextOLB[21] = 1;\nisoBandNextXTR[149] = isoBandNextXTR[21] = -1;\nisoBandNextYTR[149] = isoBandNextYTR[21] = 0;\nisoBandNextOTR[149] = isoBandNextOTR[21] = 0;\n\nisoBandNextXBR[86] = isoBandNextXBR[84] = -1;\nisoBandNextYBR[86] = isoBandNextYBR[84] = 0;\nisoBandNextOBR[86] = isoBandNextOBR[84] = 1;\nisoBandNextXLT[86] = isoBandNextXLT[84] = 0;\nisoBandNextYLT[86] = isoBandNextYLT[84] = -1;\nisoBandNextOLT[86] = isoBandNextOLT[84] = 1;\n\nisoBandNextXRT[89] = isoBandNextXRT[81] = 0;\nisoBandNextYRT[89] = isoBandNextYRT[81] = -1;\nisoBandNextORT[89] = isoBandNextORT[81] = 0;\nisoBandNextXBL[89] = isoBandNextXBL[81] = 1;\nisoBandNextYBL[89] = isoBandNextYBL[81] = 0;\nisoBandNextOBL[89] = isoBandNextOBL[81] = 1;\n\nisoBandNextXRT[96] = isoBandNextXRT[74] = 0;\nisoBandNextYRT[96] = isoBandNextYRT[74] = 1;\nisoBandNextORT[96] = isoBandNextORT[74] = 0;\nisoBandNextXRB[96] = isoBandNextXRB[74] = -1;\nisoBandNextYRB[96] = isoBandNextYRB[74] = 0;\nisoBandNextORB[96] = isoBandNextORB[74] = 1;\nisoBandNextXLT[96] = isoBandNextXLT[74] = 1;\nisoBandNextYLT[96] = isoBandNextYLT[74] = 0;\nisoBandNextOLT[96] = isoBandNextOLT[74] = 0;\nisoBandNextXTL[96] = isoBandNextXTL[74] = 1;\nisoBandNextYTL[96] = isoBandNextYTL[74] = 0;\nisoBandNextOTL[96] = isoBandNextOTL[74] = 1;\n\nisoBandNextXRT[24] = isoBandNextXRT[146] = 0;\nisoBandNextYRT[24] = isoBandNextYRT[146] = -1;\nisoBandNextORT[24] = isoBandNextORT[146] = 1;\nisoBandNextXBR[24] = isoBandNextXBR[146] = 1;\nisoBandNextYBR[24] = isoBandNextYBR[146] = 0;\nisoBandNextOBR[24] = isoBandNextOBR[146] = 1;\nisoBandNextXBL[24] = isoBandNextXBL[146] = 0;\nisoBandNextYBL[24] = isoBandNextYBL[146] = 1;\nisoBandNextOBL[24] = isoBandNextOBL[146] = 1;\nisoBandNextXTR[24] = isoBandNextXTR[146] = 0;\nisoBandNextYTR[24] = isoBandNextYTR[146] = -1;\nisoBandNextOTR[24] = isoBandNextOTR[146] = 0;\n\nisoBandNextXRB[6] = isoBandNextXRB[164] = -1;\nisoBandNextYRB[6] = isoBandNextYRB[164] = 0;\nisoBandNextORB[6] = isoBandNextORB[164] = 1;\nisoBandNextXBR[6] = isoBandNextXBR[164] = -1;\nisoBandNextYBR[6] = isoBandNextYBR[164] = 0;\nisoBandNextOBR[6] = isoBandNextOBR[164] = 0;\nisoBandNextXLB[6] = isoBandNextXLB[164] = 0;\nisoBandNextYLB[6] = isoBandNextYLB[164] = -1;\nisoBandNextOLB[6] = isoBandNextOLB[164] = 1;\nisoBandNextXLT[6] = isoBandNextXLT[164] = 1;\nisoBandNextYLT[6] = isoBandNextYLT[164] = 0;\nisoBandNextOLT[6] = isoBandNextOLT[164] = 0;\n\nisoBandNextXBL[129] = isoBandNextXBL[41] = 0;\nisoBandNextYBL[129] = isoBandNextYBL[41] = 1;\nisoBandNextOBL[129] = isoBandNextOBL[41] = 1;\nisoBandNextXLB[129] = isoBandNextXLB[41] = 0;\nisoBandNextYLB[129] = isoBandNextYLB[41] = 1;\nisoBandNextOLB[129] = isoBandNextOLB[41] = 0;\nisoBandNextXTL[129] = isoBandNextXTL[41] = -1;\nisoBandNextYTL[129] = isoBandNextYTL[41] = 0;\nisoBandNextOTL[129] = isoBandNextOTL[41] = 0;\nisoBandNextXTR[129] = isoBandNextXTR[41] = 0;\nisoBandNextYTR[129] = isoBandNextYTR[41] = -1;\nisoBandNextOTR[129] = isoBandNextOTR[41] = 0;\n\nisoBandNextXBR[66] = isoBandNextXBR[104] = 0;\nisoBandNextYBR[66] = isoBandNextYBR[104] = 1;\nisoBandNextOBR[66] = isoBandNextOBR[104] = 0;\nisoBandNextXBL[66] = isoBandNextXBL[104] = -1;\nisoBandNextYBL[66] = isoBandNextYBL[104] = 0;\nisoBandNextOBL[66] = isoBandNextOBL[104] = 1;\nisoBandNextXLT[66] = isoBandNextXLT[104] = 0;\nisoBandNextYLT[66] = isoBandNextYLT[104] = -1;\nisoBandNextOLT[66] = isoBandNextOLT[104] = 0;\nisoBandNextXTL[66] = isoBandNextXTL[104] = 0;\nisoBandNextYTL[66] = isoBandNextYTL[104] = -1;\nisoBandNextOTL[66] = isoBandNextOTL[104] = 1;\n\nisoBandNextXRT[144] = isoBandNextXRT[26] = -1;\nisoBandNextYRT[144] = isoBandNextYRT[26] = 0;\nisoBandNextORT[144] = isoBandNextORT[26] = 0;\nisoBandNextXLB[144] = isoBandNextXLB[26] = 1;\nisoBandNextYLB[144] = isoBandNextYLB[26] = 0;\nisoBandNextOLB[144] = isoBandNextOLB[26] = 1;\nisoBandNextXLT[144] = isoBandNextXLT[26] = 0;\nisoBandNextYLT[144] = isoBandNextYLT[26] = 1;\nisoBandNextOLT[144] = isoBandNextOLT[26] = 1;\nisoBandNextXTR[144] = isoBandNextXTR[26] = -1;\nisoBandNextYTR[144] = isoBandNextYTR[26] = 0;\nisoBandNextOTR[144] = isoBandNextOTR[26] = 1;\n\nisoBandNextXRB[36] = isoBandNextXRB[134] = 0;\nisoBandNextYRB[36] = isoBandNextYRB[134] = 1;\nisoBandNextORB[36] = isoBandNextORB[134] = 1;\nisoBandNextXBR[36] = isoBandNextXBR[134] = 0;\nisoBandNextYBR[36] = isoBandNextYBR[134] = 1;\nisoBandNextOBR[36] = isoBandNextOBR[134] = 0;\nisoBandNextXTL[36] = isoBandNextXTL[134] = 0;\nisoBandNextYTL[36] = isoBandNextYTL[134] = -1;\nisoBandNextOTL[36] = isoBandNextOTL[134] = 1;\nisoBandNextXTR[36] = isoBandNextXTR[134] = 1;\nisoBandNextYTR[36] = isoBandNextYTR[134] = 0;\nisoBandNextOTR[36] = isoBandNextOTR[134] = 0;\n\nisoBandNextXRT[9] = isoBandNextXRT[161] = -1;\nisoBandNextYRT[9] = isoBandNextYRT[161] = 0;\nisoBandNextORT[9] = isoBandNextORT[161] = 0;\nisoBandNextXRB[9] = isoBandNextXRB[161] = 0;\nisoBandNextYRB[9] = isoBandNextYRB[161] = -1;\nisoBandNextORB[9] = isoBandNextORB[161] = 0;\nisoBandNextXBL[9] = isoBandNextXBL[161] = 1;\nisoBandNextYBL[9] = isoBandNextYBL[161] = 0;\nisoBandNextOBL[9] = isoBandNextOBL[161] = 0;\nisoBandNextXLB[9] = isoBandNextXLB[161] = 1;\nisoBandNextYLB[9] = isoBandNextYLB[161] = 0;\nisoBandNextOLB[9] = isoBandNextOLB[161] = 1;\n\n/* 8-sided cases */\nisoBandNextXRT[136] = 0;\nisoBandNextYRT[136] = 1;\nisoBandNextORT[136] = 1;\nisoBandNextXRB[136] = 0;\nisoBandNextYRB[136] = 1;\nisoBandNextORB[136] = 0;\nisoBandNextXBR[136] = -1;\nisoBandNextYBR[136] = 0;\nisoBandNextOBR[136] = 1;\nisoBandNextXBL[136] = -1;\nisoBandNextYBL[136] = 0;\nisoBandNextOBL[136] = 0;\nisoBandNextXLB[136] = 0;\nisoBandNextYLB[136] = -1;\nisoBandNextOLB[136] = 0;\nisoBandNextXLT[136] = 0;\nisoBandNextYLT[136] = -1;\nisoBandNextOLT[136] = 1;\nisoBandNextXTL[136] = 1;\nisoBandNextYTL[136] = 0;\nisoBandNextOTL[136] = 0;\nisoBandNextXTR[136] = 1;\nisoBandNextYTR[136] = 0;\nisoBandNextOTR[136] = 1;\n\nisoBandNextXRT[34] = 0;\nisoBandNextYRT[34] = -1;\nisoBandNextORT[34] = 0;\nisoBandNextXRB[34] = 0;\nisoBandNextYRB[34] = -1;\nisoBandNextORB[34] = 1;\nisoBandNextXBR[34] = 1;\nisoBandNextYBR[34] = 0;\nisoBandNextOBR[34] = 0;\nisoBandNextXBL[34] = 1;\nisoBandNextYBL[34] = 0;\nisoBandNextOBL[34] = 1;\nisoBandNextXLB[34] = 0;\nisoBandNextYLB[34] = 1;\nisoBandNextOLB[34] = 1;\nisoBandNextXLT[34] = 0;\nisoBandNextYLT[34] = 1;\nisoBandNextOLT[34] = 0;\nisoBandNextXTL[34] = -1;\nisoBandNextYTL[34] = 0;\nisoBandNextOTL[34] = 1;\nisoBandNextXTR[34] = -1;\nisoBandNextYTR[34] = 0;\nisoBandNextOTR[34] = 0;\n\nisoBandNextXRT[35] = 0;\nisoBandNextYRT[35] = 1;\nisoBandNextORT[35] = 1;\nisoBandNextXRB[35] = 0;\nisoBandNextYRB[35] = -1;\nisoBandNextORB[35] = 1;\nisoBandNextXBR[35] = 1;\nisoBandNextYBR[35] = 0;\nisoBandNextOBR[35] = 0;\nisoBandNextXBL[35] = -1;\nisoBandNextYBL[35] = 0;\nisoBandNextOBL[35] = 0;\nisoBandNextXLB[35] = 0;\nisoBandNextYLB[35] = -1;\nisoBandNextOLB[35] = 0;\nisoBandNextXLT[35] = 0;\nisoBandNextYLT[35] = 1;\nisoBandNextOLT[35] = 0;\nisoBandNextXTL[35] = -1;\nisoBandNextYTL[35] = 0;\nisoBandNextOTL[35] = 1;\nisoBandNextXTR[35] = 1;\nisoBandNextYTR[35] = 0;\nisoBandNextOTR[35] = 1;\n\n/* 6-sided cases */\nisoBandNextXRT[153] = 0;\nisoBandNextYRT[153] = 1;\nisoBandNextORT[153] = 1;\nisoBandNextXBL[153] = -1;\nisoBandNextYBL[153] = 0;\nisoBandNextOBL[153] = 0;\nisoBandNextXLB[153] = 0;\nisoBandNextYLB[153] = -1;\nisoBandNextOLB[153] = 0;\nisoBandNextXTR[153] = 1;\nisoBandNextYTR[153] = 0;\nisoBandNextOTR[153] = 1;\n\nisoBandNextXRB[102] = 0;\nisoBandNextYRB[102] = -1;\nisoBandNextORB[102] = 1;\nisoBandNextXBR[102] = 1;\nisoBandNextYBR[102] = 0;\nisoBandNextOBR[102] = 0;\nisoBandNextXLT[102] = 0;\nisoBandNextYLT[102] = 1;\nisoBandNextOLT[102] = 0;\nisoBandNextXTL[102] = -1;\nisoBandNextYTL[102] = 0;\nisoBandNextOTL[102] = 1;\n\nisoBandNextXRT[155] = 0;\nisoBandNextYRT[155] = -1;\nisoBandNextORT[155] = 0;\nisoBandNextXBL[155] = 1;\nisoBandNextYBL[155] = 0;\nisoBandNextOBL[155] = 1;\nisoBandNextXLB[155] = 0;\nisoBandNextYLB[155] = 1;\nisoBandNextOLB[155] = 1;\nisoBandNextXTR[155] = -1;\nisoBandNextYTR[155] = 0;\nisoBandNextOTR[155] = 0;\n\nisoBandNextXRB[103] = 0;\nisoBandNextYRB[103] = 1;\nisoBandNextORB[103] = 0;\nisoBandNextXBR[103] = -1;\nisoBandNextYBR[103] = 0;\nisoBandNextOBR[103] = 1;\nisoBandNextXLT[103] = 0;\nisoBandNextYLT[103] = -1;\nisoBandNextOLT[103] = 1;\nisoBandNextXTL[103] = 1;\nisoBandNextYTL[103] = 0;\nisoBandNextOTL[103] = 0;\n\n/* 7-sided cases */\nisoBandNextXRT[152] = 0;\nisoBandNextYRT[152] = 1;\nisoBandNextORT[152] = 1;\nisoBandNextXBR[152] = -1;\nisoBandNextYBR[152] = 0;\nisoBandNextOBR[152] = 1;\nisoBandNextXBL[152] = -1;\nisoBandNextYBL[152] = 0;\nisoBandNextOBL[152] = 0;\nisoBandNextXLB[152] = 0;\nisoBandNextYLB[152] = -1;\nisoBandNextOLB[152] = 0;\nisoBandNextXLT[152] = 0;\nisoBandNextYLT[152] = -1;\nisoBandNextOLT[152] = 1;\nisoBandNextXTR[152] = 1;\nisoBandNextYTR[152] = 0;\nisoBandNextOTR[152] = 1;\n\nisoBandNextXRT[156] = 0;\nisoBandNextYRT[156] = -1;\nisoBandNextORT[156] = 1;\nisoBandNextXBR[156] = 1;\nisoBandNextYBR[156] = 0;\nisoBandNextOBR[156] = 1;\nisoBandNextXBL[156] = -1;\nisoBandNextYBL[156] = 0;\nisoBandNextOBL[156] = 0;\nisoBandNextXLB[156] = 0;\nisoBandNextYLB[156] = -1;\nisoBandNextOLB[156] = 0;\nisoBandNextXLT[156] = 0;\nisoBandNextYLT[156] = 1;\nisoBandNextOLT[156] = 1;\nisoBandNextXTR[156] = -1;\nisoBandNextYTR[156] = 0;\nisoBandNextOTR[156] = 1;\n\nisoBandNextXRT[137] = 0;\nisoBandNextYRT[137] = 1;\nisoBandNextORT[137] = 1;\nisoBandNextXRB[137] = 0;\nisoBandNextYRB[137] = 1;\nisoBandNextORB[137] = 0;\nisoBandNextXBL[137] = -1;\nisoBandNextYBL[137] = 0;\nisoBandNextOBL[137] = 0;\nisoBandNextXLB[137] = 0;\nisoBandNextYLB[137] = -1;\nisoBandNextOLB[137] = 0;\nisoBandNextXTL[137] = 1;\nisoBandNextYTL[137] = 0;\nisoBandNextOTL[137] = 0;\nisoBandNextXTR[137] = 1;\nisoBandNextYTR[137] = 0;\nisoBandNextOTR[137] = 1;\n\nisoBandNextXRT[139] = 0;\nisoBandNextYRT[139] = 1;\nisoBandNextORT[139] = 1;\nisoBandNextXRB[139] = 0;\nisoBandNextYRB[139] = -1;\nisoBandNextORB[139] = 0;\nisoBandNextXBL[139] = 1;\nisoBandNextYBL[139] = 0;\nisoBandNextOBL[139] = 0;\nisoBandNextXLB[139] = 0;\nisoBandNextYLB[139] = 1;\nisoBandNextOLB[139] = 0;\nisoBandNextXTL[139] = -1;\nisoBandNextYTL[139] = 0;\nisoBandNextOTL[139] = 0;\nisoBandNextXTR[139] = 1;\nisoBandNextYTR[139] = 0;\nisoBandNextOTR[139] = 1;\n\nisoBandNextXRT[98] = 0;\nisoBandNextYRT[98] = -1;\nisoBandNextORT[98] = 0;\nisoBandNextXRB[98] = 0;\nisoBandNextYRB[98] = -1;\nisoBandNextORB[98] = 1;\nisoBandNextXBR[98] = 1;\nisoBandNextYBR[98] = 0;\nisoBandNextOBR[98] = 0;\nisoBandNextXBL[98] = 1;\nisoBandNextYBL[98] = 0;\nisoBandNextOBL[98] = 1;\nisoBandNextXLT[98] = 0;\nisoBandNextYLT[98] = 1;\nisoBandNextOLT[98] = 0;\nisoBandNextXTL[98] = -1;\nisoBandNextYTL[98] = 0;\nisoBandNextOTL[98] = 1;\n\nisoBandNextXRT[99] = 0;\nisoBandNextYRT[99] = 1;\nisoBandNextORT[99] = 0;\nisoBandNextXRB[99] = 0;\nisoBandNextYRB[99] = -1;\nisoBandNextORB[99] = 1;\nisoBandNextXBR[99] = 1;\nisoBandNextYBR[99] = 0;\nisoBandNextOBR[99] = 0;\nisoBandNextXBL[99] = -1;\nisoBandNextYBL[99] = 0;\nisoBandNextOBL[99] = 1;\nisoBandNextXLT[99] = 0;\nisoBandNextYLT[99] = -1;\nisoBandNextOLT[99] = 0;\nisoBandNextXTL[99] = 1;\nisoBandNextYTL[99] = 0;\nisoBandNextOTL[99] = 1;\n\nisoBandNextXRB[38] = 0;\nisoBandNextYRB[38] = -1;\nisoBandNextORB[38] = 1;\nisoBandNextXBR[38] = 1;\nisoBandNextYBR[38] = 0;\nisoBandNextOBR[38] = 0;\nisoBandNextXLB[38] = 0;\nisoBandNextYLB[38] = 1;\nisoBandNextOLB[38] = 1;\nisoBandNextXLT[38] = 0;\nisoBandNextYLT[38] = 1;\nisoBandNextOLT[38] = 0;\nisoBandNextXTL[38] = -1;\nisoBandNextYTL[38] = 0;\nisoBandNextOTL[38] = 1;\nisoBandNextXTR[38] = -1;\nisoBandNextYTR[38] = 0;\nisoBandNextOTR[38] = 0;\n\nisoBandNextXRB[39] = 0;\nisoBandNextYRB[39] = 1;\nisoBandNextORB[39] = 1;\nisoBandNextXBR[39] = -1;\nisoBandNextYBR[39] = 0;\nisoBandNextOBR[39] = 0;\nisoBandNextXLB[39] = 0;\nisoBandNextYLB[39] = -1;\nisoBandNextOLB[39] = 1;\nisoBandNextXLT[39] = 0;\nisoBandNextYLT[39] = 1;\nisoBandNextOLT[39] = 0;\nisoBandNextXTL[39] = -1;\nisoBandNextYTL[39] = 0;\nisoBandNextOTL[39] = 1;\nisoBandNextXTR[39] = 1;\nisoBandNextYTR[39] = 0;\nisoBandNextOTR[39] = 0;\n\n/*\n The lookup tables for edge number given the polygon\n is entered at a specific location\n*/\n\nconst isoBandEdgeRT = [];\nconst isoBandEdgeRB = [];\nconst isoBandEdgeBR = [];\nconst isoBandEdgeBL = [];\nconst isoBandEdgeLB = [];\nconst isoBandEdgeLT = [];\nconst isoBandEdgeTL = [];\nconst isoBandEdgeTR = [];\n\n/* triangle cases */\nisoBandEdgeBL[1] = isoBandEdgeLB[1] = 18;\nisoBandEdgeBL[169] = isoBandEdgeLB[169] = 18;\nisoBandEdgeBR[4] = isoBandEdgeRB[4] = 12;\nisoBandEdgeBR[166] = isoBandEdgeRB[166] = 12;\nisoBandEdgeRT[16] = isoBandEdgeTR[16] = 4;\nisoBandEdgeRT[154] = isoBandEdgeTR[154] = 4;\nisoBandEdgeLT[64] = isoBandEdgeTL[64] = 22;\nisoBandEdgeLT[106] = isoBandEdgeTL[106] = 22;\n\n/* trapezoid cases */\nisoBandEdgeBR[2] = isoBandEdgeLT[2] = 17;\nisoBandEdgeBL[2] = isoBandEdgeLB[2] = 18;\nisoBandEdgeBR[168] = isoBandEdgeLT[168] = 17;\nisoBandEdgeBL[168] = isoBandEdgeLB[168] = 18;\nisoBandEdgeRT[8] = isoBandEdgeBL[8] = 9;\nisoBandEdgeRB[8] = isoBandEdgeBR[8] = 12;\nisoBandEdgeRT[162] = isoBandEdgeBL[162] = 9;\nisoBandEdgeRB[162] = isoBandEdgeBR[162] = 12;\nisoBandEdgeRT[32] = isoBandEdgeTR[32] = 4;\nisoBandEdgeRB[32] = isoBandEdgeTL[32] = 1;\nisoBandEdgeRT[138] = isoBandEdgeTR[138] = 4;\nisoBandEdgeRB[138] = isoBandEdgeTL[138] = 1;\nisoBandEdgeLB[128] = isoBandEdgeTR[128] = 21;\nisoBandEdgeLT[128] = isoBandEdgeTL[128] = 22;\nisoBandEdgeLB[42] = isoBandEdgeTR[42] = 21;\nisoBandEdgeLT[42] = isoBandEdgeTL[42] = 22;\n\n/* rectangle cases */\nisoBandEdgeRB[5] = isoBandEdgeLB[5] = 14;\nisoBandEdgeRB[165] = isoBandEdgeLB[165] = 14;\nisoBandEdgeBR[20] = isoBandEdgeTR[20] = 6;\nisoBandEdgeBR[150] = isoBandEdgeTR[150] = 6;\nisoBandEdgeRT[80] = isoBandEdgeLT[80] = 11;\nisoBandEdgeRT[90] = isoBandEdgeLT[90] = 11;\nisoBandEdgeBL[65] = isoBandEdgeTL[65] = 3;\nisoBandEdgeBL[105] = isoBandEdgeTL[105] = 3;\nisoBandEdgeRT[160] = isoBandEdgeLT[160] = 11;\nisoBandEdgeRB[160] = isoBandEdgeLB[160] = 14;\nisoBandEdgeRT[10] = isoBandEdgeLT[10] = 11;\nisoBandEdgeRB[10] = isoBandEdgeLB[10] = 14;\nisoBandEdgeBR[130] = isoBandEdgeTR[130] = 6;\nisoBandEdgeBL[130] = isoBandEdgeTL[130] = 3;\nisoBandEdgeBR[40] = isoBandEdgeTR[40] = 6;\nisoBandEdgeBL[40] = isoBandEdgeTL[40] = 3;\n\n/* pentagon cases */\nisoBandEdgeRB[101] = isoBandEdgeTL[101] = 1;\nisoBandEdgeRB[69] = isoBandEdgeTL[69] = 1;\nisoBandEdgeLB[149] = isoBandEdgeTR[149] = 21;\nisoBandEdgeLB[21] = isoBandEdgeTR[21] = 21;\nisoBandEdgeBR[86] = isoBandEdgeLT[86] = 17;\nisoBandEdgeBR[84] = isoBandEdgeLT[84] = 17;\nisoBandEdgeRT[89] = isoBandEdgeBL[89] = 9;\nisoBandEdgeRT[81] = isoBandEdgeBL[81] = 9;\nisoBandEdgeRT[96] = isoBandEdgeTL[96] = 0;\nisoBandEdgeRB[96] = isoBandEdgeLT[96] = 15;\nisoBandEdgeRT[74] = isoBandEdgeTL[74] = 0;\nisoBandEdgeRB[74] = isoBandEdgeLT[74] = 15;\nisoBandEdgeRT[24] = isoBandEdgeBR[24] = 8;\nisoBandEdgeBL[24] = isoBandEdgeTR[24] = 7;\nisoBandEdgeRT[146] = isoBandEdgeBR[146] = 8;\nisoBandEdgeBL[146] = isoBandEdgeTR[146] = 7;\nisoBandEdgeRB[6] = isoBandEdgeLT[6] = 15;\nisoBandEdgeBR[6] = isoBandEdgeLB[6] = 16;\nisoBandEdgeRB[164] = isoBandEdgeLT[164] = 15;\nisoBandEdgeBR[164] = isoBandEdgeLB[164] = 16;\nisoBandEdgeBL[129] = isoBandEdgeTR[129] = 7;\nisoBandEdgeLB[129] = isoBandEdgeTL[129] = 20;\nisoBandEdgeBL[41] = isoBandEdgeTR[41] = 7;\nisoBandEdgeLB[41] = isoBandEdgeTL[41] = 20;\nisoBandEdgeBR[66] = isoBandEdgeTL[66] = 2;\nisoBandEdgeBL[66] = isoBandEdgeLT[66] = 19;\nisoBandEdgeBR[104] = isoBandEdgeTL[104] = 2;\nisoBandEdgeBL[104] = isoBandEdgeLT[104] = 19;\nisoBandEdgeRT[144] = isoBandEdgeLB[144] = 10;\nisoBandEdgeLT[144] = isoBandEdgeTR[144] = 23;\nisoBandEdgeRT[26] = isoBandEdgeLB[26] = 10;\nisoBandEdgeLT[26] = isoBandEdgeTR[26] = 23;\nisoBandEdgeRB[36] = isoBandEdgeTR[36] = 5;\nisoBandEdgeBR[36] = isoBandEdgeTL[36] = 2;\nisoBandEdgeRB[134] = isoBandEdgeTR[134] = 5;\nisoBandEdgeBR[134] = isoBandEdgeTL[134] = 2;\nisoBandEdgeRT[9] = isoBandEdgeLB[9] = 10;\nisoBandEdgeRB[9] = isoBandEdgeBL[9] = 13;\nisoBandEdgeRT[161] = isoBandEdgeLB[161] = 10;\nisoBandEdgeRB[161] = isoBandEdgeBL[161] = 13;\n\n/* hexagon cases */\nisoBandEdgeRB[37] = isoBandEdgeTR[37] = 5;\nisoBandEdgeLB[37] = isoBandEdgeTL[37] = 20;\nisoBandEdgeRB[133] = isoBandEdgeTR[133] = 5;\nisoBandEdgeLB[133] = isoBandEdgeTL[133] = 20;\nisoBandEdgeBR[148] = isoBandEdgeLB[148] = 16;\nisoBandEdgeLT[148] = isoBandEdgeTR[148] = 23;\nisoBandEdgeBR[22] = isoBandEdgeLB[22] = 16;\nisoBandEdgeLT[22] = isoBandEdgeTR[22] = 23;\nisoBandEdgeRT[82] = isoBandEdgeBR[82] = 8;\nisoBandEdgeBL[82] = isoBandEdgeLT[82] = 19;\nisoBandEdgeRT[88] = isoBandEdgeBR[88] = 8;\nisoBandEdgeBL[88] = isoBandEdgeLT[88] = 19;\nisoBandEdgeRT[73] = isoBandEdgeTL[73] = 0;\nisoBandEdgeRB[73] = isoBandEdgeBL[73] = 13;\nisoBandEdgeRT[97] = isoBandEdgeTL[97] = 0;\nisoBandEdgeRB[97] = isoBandEdgeBL[97] = 13;\nisoBandEdgeRT[145] = isoBandEdgeBL[145] = 9;\nisoBandEdgeLB[145] = isoBandEdgeTR[145] = 21;\nisoBandEdgeRT[25] = isoBandEdgeBL[25] = 9;\nisoBandEdgeLB[25] = isoBandEdgeTR[25] = 21;\nisoBandEdgeRB[70] = isoBandEdgeTL[70] = 1;\nisoBandEdgeBR[70] = isoBandEdgeLT[70] = 17;\nisoBandEdgeRB[100] = isoBandEdgeTL[100] = 1;\nisoBandEdgeBR[100] = isoBandEdgeLT[100] = 17;\n\n/* 8-sided cases */\nisoBandEdgeRT[34] = isoBandEdgeBL[34] = 9;\nisoBandEdgeRB[34] = isoBandEdgeBR[34] = 12;\nisoBandEdgeLB[34] = isoBandEdgeTR[34] = 21;\nisoBandEdgeLT[34] = isoBandEdgeTL[34] = 22;\nisoBandEdgeRT[136] = isoBandEdgeTR[136] = 4;\nisoBandEdgeRB[136] = isoBandEdgeTL[136] = 1;\nisoBandEdgeBR[136] = isoBandEdgeLT[136] = 17;\nisoBandEdgeBL[136] = isoBandEdgeLB[136] = 18;\nisoBandEdgeRT[35] = isoBandEdgeTR[35] = 4;\nisoBandEdgeRB[35] = isoBandEdgeBR[35] = 12;\nisoBandEdgeBL[35] = isoBandEdgeLB[35] = 18;\nisoBandEdgeLT[35] = isoBandEdgeTL[35] = 22;\n\n/* 6-sided cases */\nisoBandEdgeRT[153] = isoBandEdgeTR[153] = 4;\nisoBandEdgeBL[153] = isoBandEdgeLB[153] = 18;\nisoBandEdgeRB[102] = isoBandEdgeBR[102] = 12;\nisoBandEdgeLT[102] = isoBandEdgeTL[102] = 22;\nisoBandEdgeRT[155] = isoBandEdgeBL[155] = 9;\nisoBandEdgeLB[155] = isoBandEdgeTR[155] = 23;\nisoBandEdgeRB[103] = isoBandEdgeTL[103] = 1;\nisoBandEdgeBR[103] = isoBandEdgeLT[103] = 17;\n\n/* 7-sided cases */\nisoBandEdgeRT[152] = isoBandEdgeTR[152] = 4;\nisoBandEdgeBR[152] = isoBandEdgeLT[152] = 17;\nisoBandEdgeBL[152] = isoBandEdgeLB[152] = 18;\nisoBandEdgeRT[156] = isoBandEdgeBR[156] = 8;\nisoBandEdgeBL[156] = isoBandEdgeLB[156] = 18;\nisoBandEdgeLT[156] = isoBandEdgeTR[156] = 23;\nisoBandEdgeRT[137] = isoBandEdgeTR[137] = 4;\nisoBandEdgeRB[137] = isoBandEdgeTL[137] = 1;\nisoBandEdgeBL[137] = isoBandEdgeLB[137] = 18;\nisoBandEdgeRT[139] = isoBandEdgeTR[139] = 4;\nisoBandEdgeRB[139] = isoBandEdgeBL[139] = 13;\nisoBandEdgeLB[139] = isoBandEdgeTL[139] = 20;\nisoBandEdgeRT[98] = isoBandEdgeBL[98] = 9;\nisoBandEdgeRB[98] = isoBandEdgeBR[98] = 12;\nisoBandEdgeLT[98] = isoBandEdgeTL[98] = 22;\nisoBandEdgeRT[99] = isoBandEdgeTL[99] = 0;\nisoBandEdgeRB[99] = isoBandEdgeBR[99] = 12;\nisoBandEdgeBL[99] = isoBandEdgeLT[99] = 19;\nisoBandEdgeRB[38] = isoBandEdgeBR[38] = 12;\nisoBandEdgeLB[38] = isoBandEdgeTR[38] = 21;\nisoBandEdgeLT[38] = isoBandEdgeTL[38] = 22;\nisoBandEdgeRB[39] = isoBandEdgeTR[39] = 5;\nisoBandEdgeBR[39] = isoBandEdgeLB[39] = 16;\nisoBandEdgeLT[39] = isoBandEdgeTL[39] = 22;\n\n/*\n The lookup tables for all different polygons that\n may appear within a grid cell\n*/\n\nconst polygon_table = [];\n\n/* triangle cases */\npolygon_table[1] = polygon_table[169] = p00; /* 2221 || 0001 */\npolygon_table[4] = polygon_table[166] = p01; /* 2212 || 0010 */\npolygon_table[16] = polygon_table[154] = p02; /* 2122 || 0100 */\npolygon_table[64] = polygon_table[106] = p03; /* 1222 || 1000 */\n\n/* trapezoid cases */\npolygon_table[168] = polygon_table[2] = p04; /* 2220 || 0002 */\npolygon_table[162] = polygon_table[8] = p05; /* 2202 || 0020 */\npolygon_table[138] = polygon_table[32] = p06; /* 2022 || 0200 */\npolygon_table[42] = polygon_table[128] = p07; /* 0222 || 2000 */\n\n/* rectangle cases */\npolygon_table[5] = polygon_table[165] = p08; /* 0011 || 2211 */\npolygon_table[20] = polygon_table[150] = p09; /* 0110 || 2112 */\npolygon_table[80] = polygon_table[90] = p10; /* 1100 || 1122 */\npolygon_table[65] = polygon_table[105] = p11; /* 1001 || 1221 */\npolygon_table[160] = polygon_table[10] = p12; /* 2200 || 0022 */\npolygon_table[130] = polygon_table[40] = p13; /* 2002 || 0220 */\n\n/* square case */\npolygon_table[85] = p14; /* 1111 */\n\n/* pentagon cases */\npolygon_table[101] = polygon_table[69] = p15; /* 1211 || 1011 */\npolygon_table[149] = polygon_table[21] = p16; /* 2111 || 0111 */\npolygon_table[86] = polygon_table[84] = p17; /* 1112 || 1110 */\npolygon_table[89] = polygon_table[81] = p18; /* 1121 || 1101 */\npolygon_table[96] = polygon_table[74] = p19; /* 1200 || 1022 */\npolygon_table[24] = polygon_table[146] = p20; /* 0120 || 2102 */\npolygon_table[6] = polygon_table[164] = p21; /* 0012 || 2210 */\npolygon_table[129] = polygon_table[41] = p22; /* 2001 || 0221 */\npolygon_table[66] = polygon_table[104] = p23; /* 1002 || 1220 */\npolygon_table[144] = polygon_table[26] = p24; /* 2100 || 0122 */\npolygon_table[36] = polygon_table[134] = p25; /* 0210 || 2012 */\npolygon_table[9] = polygon_table[161] = p26; /* 0021 || 2201 */\n\n/* hexagon cases */\npolygon_table[37] = polygon_table[133] = p27; /* 0211 || 2011 */\npolygon_table[148] = polygon_table[22] = p28; /* 2110 || 0112 */\npolygon_table[82] = polygon_table[88] = p29; /* 1102 || 1120 */\npolygon_table[73] = polygon_table[97] = p30; /* 1021 || 1201 */\npolygon_table[145] = polygon_table[25] = p31; /* 2101 || 0121 */\npolygon_table[70] = polygon_table[100] = p32; /* 1012 || 1210 */\n\n/* 8-sided cases */\npolygon_table[34] = function (c) {\n return [p07(c), p05(c)];\n}; /* 0202 || 2020 with flipped == 0 */\npolygon_table[35] = p33; /* flipped == 1 state for 0202 and 2020 */\npolygon_table[136] = function (c) {\n return [p06(c), p04(c)];\n}; /* 2020 || 0202 with flipped == 0 */\n\n/* 6-sided cases */\npolygon_table[153] = function (c) {\n return [p02(c), p00(c)];\n}; /* 0101 with flipped == 0 || 2121 with flipped == 2 */\npolygon_table[102] = function (c) {\n return [p01(c), p03(c)];\n}; /* 1010 with flipped == 0 || 1212 with flipped == 2 */\npolygon_table[155] = p34; /* 0101 with flipped == 1 || 2121 with flipped == 1 */\npolygon_table[103] = p35; /* 1010 with flipped == 1 || 1212 with flipped == 1 */\n\n/* 7-sided cases */\npolygon_table[152] = function (c) {\n return [p02(c), p04(c)];\n}; /* 2120 with flipped == 2 || 0102 with flipped == 0 */\npolygon_table[156] = p36; /* 2120 with flipped == 1 || 0102 with flipped == 1 */\npolygon_table[137] = function (c) {\n return [p06(c), p00(c)];\n}; /* 2021 with flipped == 2 || 0201 with flipped == 0 */\npolygon_table[139] = p37; /* 2021 with flipped == 1 || 0201 with flipped == 1 */\npolygon_table[98] = function (c) {\n return [p05(c), p03(c)];\n}; /* 1202 with flipped == 2 || 1020 with flipped == 0 */\npolygon_table[99] = p38; /* 1202 with flipped == 1 || 1020 with flipped == 1 */\npolygon_table[38] = function (c) {\n return [p01(c), p07(c)];\n}; /* 0212 with flipped == 2 || 2010 with flipped == 0 */\npolygon_table[39] = p39; /* 0212 with flipped == 1 || 2010 with flipped == 1 */\n\n/*\n The helper functions for the above polygon_table\n*/\n\n/* triangle cases */\nvar p00 = function (cell) {\n return [\n [cell.bottomleft, 0],\n [0, 0],\n [0, cell.leftbottom],\n ];\n};\nvar p01 = function (cell) {\n return [\n [1, cell.rightbottom],\n [1, 0],\n [cell.bottomright, 0],\n ];\n};\nvar p02 = function (cell) {\n return [\n [cell.topright, 1],\n [1, 1],\n [1, cell.righttop],\n ];\n};\nvar p03 = function (cell) {\n return [\n [0, cell.lefttop],\n [0, 1],\n [cell.topleft, 1],\n ];\n};\n/* trapezoid cases */\nvar p04 = function (cell) {\n return [\n [cell.bottomright, 0],\n [cell.bottomleft, 0],\n [0, cell.leftbottom],\n [0, cell.lefttop],\n ];\n};\nvar p05 = function (cell) {\n return [\n [cell.bottomright, 0],\n [cell.bottomleft, 0],\n [1, cell.righttop],\n [1, cell.rightbottom],\n ];\n};\nvar p06 = function (cell) {\n return [\n [1, cell.righttop],\n [1, cell.rightbottom],\n [cell.topleft, 1],\n [cell.topright, 1],\n ];\n};\nvar p07 = function (cell) {\n return [\n [0, cell.leftbottom],\n [0, cell.lefttop],\n [cell.topleft, 1],\n [cell.topright, 1],\n ];\n};\n/* rectangle cases */\nvar p08 = function (cell) {\n return [\n [0, 0],\n [0, cell.leftbottom],\n [1, cell.rightbottom],\n [1, 0],\n ];\n};\nvar p09 = function (cell) {\n return [\n [1, 0],\n [cell.bottomright, 0],\n [cell.topright, 1],\n [1, 1],\n ];\n};\nvar p10 = function (cell) {\n return [\n [1, 1],\n [1, cell.righttop],\n [0, cell.lefttop],\n [0, 1],\n ];\n};\nvar p11 = function (cell) {\n return [\n [cell.bottomleft, 0],\n [0, 0],\n [0, 1],\n [cell.topleft, 1],\n ];\n};\nvar p12 = function (cell) {\n return [\n [1, cell.righttop],\n [1, cell.rightbottom],\n [0, cell.leftbottom],\n [0, cell.lefttop],\n ];\n};\nvar p13 = function (cell) {\n return [\n [cell.topleft, 1],\n [cell.topright, 1],\n [cell.bottomright, 0],\n [cell.bottomleft, 0],\n ];\n};\n/* square case */\nvar p14 = function (cell) {\n return [\n [0, 0],\n [0, 1],\n [1, 1],\n [1, 0],\n ];\n};\n/* pentagon cases */\nvar p15 = function (cell) {\n return [\n [1, cell.rightbottom],\n [1, 0],\n [0, 0],\n [0, 1],\n [cell.topleft, 1],\n ];\n}; /* 1211 || 1011 */\nvar p16 = function (cell) {\n return [\n [cell.topright, 1],\n [1, 1],\n [1, 0],\n [0, 0],\n [0, cell.leftbottom],\n ];\n}; /* 2111 || 0111 */\nvar p17 = function (cell) {\n return [\n [1, 0],\n [cell.bottomright, 0],\n [0, cell.lefttop],\n [0, 1],\n [1, 1],\n ];\n}; /* 1112 || 1110 */\nvar p18 = function (cell) {\n return [\n [1, 1],\n [1, cell.righttop],\n [cell.bottomleft, 0],\n [0, 0],\n [0, 1],\n ];\n}; /* 1121 || 1101 */\nvar p19 = function (cell) {\n return [\n [1, cell.righttop],\n [1, cell.rightbottom],\n [0, cell.lefttop],\n [0, 1],\n [cell.topleft, 1],\n ];\n}; /* 1200 || 1022 */\nvar p20 = function (cell) {\n return [\n [1, 1],\n [1, cell.righttop],\n [cell.bottomright, 0],\n [cell.bottomleft, 0],\n [cell.topright, 1],\n ];\n}; /* 0120 || 2102 */\nvar p21 = function (cell) {\n return [\n [1, cell.rightbottom],\n [1, 0],\n [cell.bottomright, 0],\n [0, cell.leftbottom],\n [0, cell.lefttop],\n ];\n}; /* 0012 || 2210 */\nvar p22 = function (cell) {\n return [\n [cell.topright, 1],\n [cell.bottomleft, 0],\n [0, 0],\n [0, cell.leftbottom],\n [cell.topleft, 1],\n ];\n}; /* 2001 || 0221 */\nvar p23 = function (cell) {\n return [\n [cell.bottomright, 0],\n [cell.bottomleft, 0],\n [0, cell.lefttop],\n [0, 1],\n [cell.topleft, 1],\n ];\n}; /* 1002 || 1220 */\nvar p24 = function (cell) {\n return [\n [1, 1],\n [1, cell.righttop],\n [0, cell.leftbottom],\n [0, cell.lefttop],\n [cell.topright, 1],\n ];\n}; /* 2100 || 0122 */\nvar p25 = function (cell) {\n return [\n [1, cell.rightbottom],\n [1, 0],\n [cell.bottomright, 0],\n [cell.topleft, 1],\n [cell.topright, 1],\n ];\n}; /* 0210 || 2012 */\nvar p26 = function (cell) {\n return [\n [1, cell.righttop],\n [1, cell.rightbottom],\n [cell.bottomleft, 0],\n [0, 0],\n [0, cell.leftbottom],\n ];\n}; /* 0021 || 2201 */\n/* hexagon cases */\nvar p27 = function (cell) {\n return [\n [1, cell.rightbottom],\n [1, 0],\n [0, 0],\n [0, cell.leftbottom],\n [cell.topleft, 1],\n [cell.topright, 1],\n ];\n}; /* 0211 || 2011 */\nvar p28 = function (cell) {\n return [\n [1, 1],\n [1, 0],\n [cell.bottomright, 0],\n [0, cell.leftbottom],\n [0, cell.lefttop],\n [cell.topright, 1],\n ];\n}; /* 2110 || 0112 */\nvar p29 = function (cell) {\n return [\n [1, 1],\n [1, cell.righttop],\n [cell.bottomright, 0],\n [cell.bottomleft, 0],\n [0, cell.lefttop],\n [0, 1],\n ];\n}; /* 1102 || 1120 */\nvar p30 = function (cell) {\n return [\n [1, cell.righttop],\n [1, cell.rightbottom],\n [cell.bottomleft, 0],\n [0, 0],\n [0, 1],\n [cell.topleft, 1],\n ];\n}; /* 1021 || 1201 */\nvar p31 = function (cell) {\n return [\n [1, 1],\n [1, cell.righttop],\n [cell.bottomleft, 0],\n [0, 0],\n [0, cell.leftbottom],\n [cell.topright, 1],\n ];\n}; /* 2101 || 0121 */\nvar p32 = function (cell) {\n return [\n [1, cell.rightbottom],\n [1, 0],\n [cell.bottomright, 0],\n [0, cell.lefttop],\n [0, 1],\n [cell.topleft, 1],\n ];\n}; /* 1012 || 1210 */\n/* 8-sided cases */\nvar p33 = function (cell) {\n return [\n [1, cell.righttop],\n [1, cell.rightbottom],\n [cell.bottomright, 0],\n [cell.bottomleft, 0],\n [0, cell.leftbottom],\n [0, cell.lefttop],\n [cell.topleft, 1],\n [cell.topright, 1],\n ];\n}; /* flipped == 1 state for 0202 and 2020 */\n/* 6-sided cases */\nvar p34 = function (cell) {\n return [\n [1, 1],\n [1, cell.righttop],\n [cell.bottomleft, 0],\n [0, 0],\n [0, cell.leftbottom],\n [cell.topright, 1],\n ];\n}; /* 0101 with flipped == 1 || 2121 with flipped == 1 */\nvar p35 = function (cell) {\n return [\n [1, cell.rightbottom],\n [1, 0],\n [cell.bottomright, 0],\n [0, cell.lefttop],\n [0, 1],\n [cell.topleft, 1],\n ];\n}; /* 1010 with flipped == 1 || 1212 with flipped == 1 */\n/* 7-sided cases */\nvar p36 = function (cell) {\n return [\n [1, 1],\n [1, cell.righttop],\n [cell.bottomright, 0],\n [cell.bottomleft, 0],\n [0, cell.leftbottom],\n [0, cell.lefttop],\n [cell.topright, 1],\n ];\n}; /* 2120 with flipped == 1 || 0102 with flipped == 1 */\nvar p37 = function (cell) {\n return [\n [1, cell.righttop],\n [1, cell.rightbottom],\n [cell.bottomleft, 0],\n [0, 0],\n [0, cell.leftbottom],\n [cell.topleft, 1],\n [cell.topright, 1],\n ];\n}; /* 2021 with flipped == 1 || 0201 with flipped == 1 */\nvar p38 = function (cell) {\n return [\n [1, cell.righttop],\n [1, cell.rightbottom],\n [cell.bottomright, 0],\n [cell.bottomleft, 0],\n [0, cell.lefttop],\n [0, 1],\n [cell.topleft, 1],\n ];\n}; /* 1202 with flipped == 1 || 1020 with flipped == 1 */\nvar p39 = function (cell) {\n return [\n [1, cell.rightbottom],\n [1, 0],\n [cell.bottomright, 0],\n [0, cell.leftbottom],\n [0, cell.lefttop],\n [cell.topleft, 1],\n [cell.topright, 1],\n ];\n}; /* 0212 with flipped == 1 || 2010 with flipped == 1 */\n\n/*\n####################################\nSome small helper functions\n####################################\n*/\n\n/* assume that x1 == 1 && x0 == 0 */\nfunction interpolateX(y, y0, y1) {\n return (y - y0) / (y1 - y0);\n}\n\n/*\n####################################\nBelow is the actual Marching Squares implementation\n####################################\n*/\n\nvar computeBandGrid = function (data, minV, bandwidth) {\n const rows = data.length - 1;\n const cols = data[0].length - 1;\n const BandGrid = { rows, cols, cells: [] };\n\n const maxV = minV + Math.abs(bandwidth);\n\n for (let j = 0; j < rows; ++j) {\n BandGrid.cells[j] = [];\n for (let i = 0; i < cols; ++i) {\n /* compose the 4-trit corner representation */\n let cval = 0;\n\n const tl = data[j + 1][i];\n const tr = data[j + 1][i + 1];\n const br = data[j][i + 1];\n const bl = data[j][i];\n\n if (isNaN(tl) || isNaN(tr) || isNaN(br) || isNaN(bl)) {\n continue;\n }\n\n cval |= tl < minV ? 0 : tl > maxV ? 128 : 64;\n cval |= tr < minV ? 0 : tr > maxV ? 32 : 16;\n cval |= br < minV ? 0 : br > maxV ? 8 : 4;\n cval |= bl < minV ? 0 : bl > maxV ? 2 : 1;\n\n const cval_real = +cval;\n\n /* resolve ambiguity via averaging */\n let flipped = 0;\n if (\n cval == 17 /* 0101 */ ||\n cval == 18 /* 0102 */ ||\n cval == 33 /* 0201 */ ||\n cval == 34 /* 0202 */ ||\n cval == 38 /* 0212 */ ||\n cval == 68 /* 1010 */ ||\n cval == 72 /* 1020 */ ||\n cval == 98 /* 1202 */ ||\n cval == 102 /* 1212 */ ||\n cval == 132 /* 2010 */ ||\n cval == 136 /* 2020 */ ||\n cval == 137 /* 2021 */ ||\n cval == 152 /* 2120 */ ||\n cval == 153 /* 2121 */\n ) {\n const average = (tl + tr + br + bl) / 4;\n /* set flipped state */\n flipped = average > maxV ? 2 : average < minV ? 0 : 1;\n\n /* adjust cval for flipped cases */\n\n /* 8-sided cases */\n if (cval === 34) {\n if (flipped === 1) {\n cval = 35;\n } else if (flipped === 0) {\n cval = 136;\n }\n } else if (cval === 136) {\n if (flipped === 1) {\n cval = 35;\n flipped = 4;\n } else if (flipped === 0) {\n cval = 34;\n }\n } else if (cval === 17) {\n /* 6-sided polygon cases */\n if (flipped === 1) {\n cval = 155;\n flipped = 4;\n } else if (flipped === 0) {\n cval = 153;\n }\n } else if (cval === 68) {\n if (flipped === 1) {\n cval = 103;\n flipped = 4;\n } else if (flipped === 0) {\n cval = 102;\n }\n } else if (cval === 153) {\n if (flipped === 1) cval = 155;\n } else if (cval === 102) {\n if (flipped === 1) cval = 103;\n } else if (cval === 152) {\n /* 7-sided polygon cases */\n if (flipped < 2) {\n cval = 156;\n flipped = 1;\n }\n } else if (cval === 137) {\n if (flipped < 2) {\n cval = 139;\n flipped = 1;\n }\n } else if (cval === 98) {\n if (flipped < 2) {\n cval = 99;\n flipped = 1;\n }\n } else if (cval === 38) {\n if (flipped < 2) {\n cval = 39;\n flipped = 1;\n }\n } else if (cval === 18) {\n if (flipped > 0) {\n cval = 156;\n flipped = 4;\n } else {\n cval = 152;\n }\n } else if (cval === 33) {\n if (flipped > 0) {\n cval = 139;\n flipped = 4;\n } else {\n cval = 137;\n }\n } else if (cval === 72) {\n if (flipped > 0) {\n cval = 99;\n flipped = 4;\n } else {\n cval = 98;\n }\n } else if (cval === 132) {\n if (flipped > 0) {\n cval = 39;\n flipped = 4;\n } else {\n cval = 38;\n }\n }\n }\n\n /* add cell to BandGrid if it contains at least one polygon-side */\n if (cval != 0 && cval != 170) {\n var topleft;\n var topright;\n var bottomleft;\n var bottomright;\n var righttop;\n var rightbottom;\n var lefttop;\n var leftbottom;\n\n topleft =\n topright =\n bottomleft =\n bottomright =\n righttop =\n rightbottom =\n lefttop =\n leftbottom =\n 0.5;\n\n const edges = [];\n\n /* do interpolation here */\n /* 1st Triangles */\n if (cval === 1) {\n /* 0001 */\n bottomleft = 1 - interpolateX(minV, br, bl);\n leftbottom = 1 - interpolateX(minV, tl, bl);\n edges.push(isoBandEdgeBL[cval]);\n } else if (cval === 169) {\n /* 2221 */\n bottomleft = interpolateX(maxV, bl, br);\n leftbottom = interpolateX(maxV, bl, tl);\n edges.push(isoBandEdgeBL[cval]);\n } else if (cval === 4) {\n /* 0010 */\n rightbottom = 1 - interpolateX(minV, tr, br);\n bottomright = interpolateX(minV, bl, br);\n edges.push(isoBandEdgeRB[cval]);\n } else if (cval === 166) {\n /* 2212 */\n rightbottom = interpolateX(maxV, br, tr);\n bottomright = 1 - interpolateX(maxV, br, bl);\n edges.push(isoBandEdgeRB[cval]);\n } else if (cval === 16) {\n /* 0100 */\n righttop = interpolateX(minV, br, tr);\n topright = interpolateX(minV, tl, tr);\n edges.push(isoBandEdgeRT[cval]);\n } else if (cval === 154) {\n /* 2122 */\n righttop = 1 - interpolateX(maxV, tr, br);\n topright = 1 - interpolateX(maxV, tr, tl);\n edges.push(isoBandEdgeRT[cval]);\n } else if (cval === 64) {\n /* 1000 */\n lefttop = interpolateX(minV, bl, tl);\n topleft = 1 - interpolateX(minV, tr, tl);\n edges.push(isoBandEdgeLT[cval]);\n } else if (cval === 106) {\n /* 1222 */\n lefttop = 1 - interpolateX(maxV, tl, bl);\n topleft = interpolateX(maxV, tl, tr);\n edges.push(isoBandEdgeLT[cval]);\n } else if (cval === 168) {\n /* 2nd Trapezoids */\n /* 2220 */\n bottomright = interpolateX(maxV, bl, br);\n bottomleft = interpolateX(minV, bl, br);\n leftbottom = interpolateX(minV, bl, tl);\n lefttop = interpolateX(maxV, bl, tl);\n edges.push(isoBandEdgeBR[cval]);\n edges.push(isoBandEdgeBL[cval]);\n } else if (cval === 2) {\n /* 0002 */\n bottomright = 1 - interpolateX(minV, br, bl);\n bottomleft = 1 - interpolateX(maxV, br, bl);\n leftbottom = 1 - interpolateX(maxV, tl, bl);\n lefttop = 1 - interpolateX(minV, tl, bl);\n edges.push(isoBandEdgeBR[cval]);\n edges.push(isoBandEdgeBL[cval]);\n } else if (cval === 162) {\n /* 2202 */\n righttop = interpolateX(maxV, br, tr);\n rightbottom = interpolateX(minV, br, tr);\n bottomright = 1 - interpolateX(minV, br, bl);\n bottomleft = 1 - interpolateX(maxV, br, bl);\n edges.push(isoBandEdgeBR[cval]);\n edges.push(isoBandEdgeBL[cval]);\n } else if (cval === 8) {\n /* 0020 */\n righttop = 1 - interpolateX(minV, tr, br);\n rightbottom = 1 - interpolateX(maxV, tr, br);\n bottomright = interpolateX(maxV, bl, br);\n bottomleft = interpolateX(minV, bl, br);\n edges.push(isoBandEdgeRT[cval]);\n edges.push(isoBandEdgeRB[cval]);\n } else if (cval === 138) {\n /* 2022 */\n righttop = 1 - interpolateX(minV, tr, br);\n rightbottom = 1 - interpolateX(maxV, tr, br);\n topleft = 1 - interpolateX(maxV, tr, tl);\n topright = 1 - interpolateX(minV, tr, tl);\n edges.push(isoBandEdgeRT[cval]);\n edges.push(isoBandEdgeRB[cval]);\n } else if (cval === 32) {\n /* 0200 */\n righttop = interpolateX(maxV, br, tr);\n rightbottom = interpolateX(minV, br, tr);\n topleft = interpolateX(minV, tl, tr);\n topright = interpolateX(maxV, tl, tr);\n edges.push(isoBandEdgeRT[cval]);\n edges.push(isoBandEdgeRB[cval]);\n } else if (cval === 42) {\n /* 0222 */\n leftbottom = 1 - interpolateX(maxV, tl, bl);\n lefttop = 1 - interpolateX(minV, tl, bl);\n topleft = interpolateX(minV, tl, tr);\n topright = interpolateX(maxV, tl, tr);\n edges.push(isoBandEdgeLB[cval]);\n edges.push(isoBandEdgeLT[cval]);\n } else if (cval === 128) {\n /* 2000 */\n leftbottom = interpolateX(minV, bl, tl);\n lefttop = interpolateX(maxV, bl, tl);\n topleft = 1 - interpolateX(maxV, tr, tl);\n topright = 1 - interpolateX(minV, tr, tl);\n edges.push(isoBandEdgeLB[cval]);\n edges.push(isoBandEdgeLT[cval]);\n }\n\n /* 3rd rectangle cases */\n if (cval === 5) {\n /* 0011 */\n rightbottom = 1 - interpolateX(minV, tr, br);\n leftbottom = 1 - interpolateX(minV, tl, bl);\n edges.push(isoBandEdgeRB[cval]);\n } else if (cval === 165) {\n /* 2211 */\n rightbottom = interpolateX(maxV, br, tr);\n leftbottom = interpolateX(maxV, bl, tl);\n edges.push(isoBandEdgeRB[cval]);\n } else if (cval === 20) {\n /* 0110 */\n bottomright = interpolateX(minV, bl, br);\n topright = interpolateX(minV, tl, tr);\n edges.push(isoBandEdgeBR[cval]);\n } else if (cval === 150) {\n /* 2112 */\n bottomright = 1 - interpolateX(maxV, br, bl);\n topright = 1 - interpolateX(maxV, tr, tl);\n edges.push(isoBandEdgeBR[cval]);\n } else if (cval === 80) {\n /* 1100 */\n righttop = interpolateX(minV, br, tr);\n lefttop = interpolateX(minV, bl, tl);\n edges.push(isoBandEdgeRT[cval]);\n } else if (cval === 90) {\n /* 1122 */\n righttop = 1 - interpolateX(maxV, tr, br);\n lefttop = 1 - interpolateX(maxV, tl, bl);\n edges.push(isoBandEdgeRT[cval]);\n } else if (cval === 65) {\n /* 1001 */\n bottomleft = 1 - interpolateX(minV, br, bl);\n topleft = 1 - interpolateX(minV, tr, tl);\n edges.push(isoBandEdgeBL[cval]);\n } else if (cval === 105) {\n /* 1221 */\n bottomleft = interpolateX(maxV, bl, br);\n topleft = interpolateX(maxV, tl, tr);\n edges.push(isoBandEdgeBL[cval]);\n } else if (cval === 160) {\n /* 2200 */\n righttop = interpolateX(maxV, br, tr);\n rightbottom = interpolateX(minV, br, tr);\n leftbottom = interpolateX(minV, bl, tl);\n lefttop = interpolateX(maxV, bl, tl);\n edges.push(isoBandEdgeRT[cval]);\n edges.push(isoBandEdgeRB[cval]);\n } else if (cval === 10) {\n /* 0022 */\n righttop = 1 - interpolateX(minV, tr, br);\n rightbottom = 1 - interpolateX(maxV, tr, br);\n leftbottom = 1 - interpolateX(maxV, tl, bl);\n lefttop = 1 - interpolateX(minV, tl, bl);\n edges.push(isoBandEdgeRT[cval]);\n edges.push(isoBandEdgeRB[cval]);\n } else if (cval === 130) {\n /* 2002 */\n bottomright = 1 - interpolateX(minV, br, bl);\n bottomleft = 1 - interpolateX(maxV, br, bl);\n topleft = 1 - interpolateX(maxV, tr, tl);\n topright = 1 - interpolateX(minV, tr, tl);\n edges.push(isoBandEdgeBR[cval]);\n edges.push(isoBandEdgeBL[cval]);\n } else if (cval === 40) {\n /* 0220 */\n bottomright = interpolateX(maxV, bl, br);\n bottomleft = interpolateX(minV, bl, br);\n topleft = interpolateX(minV, tl, tr);\n topright = interpolateX(maxV, tl, tr);\n edges.push(isoBandEdgeBR[cval]);\n edges.push(isoBandEdgeBL[cval]);\n } else if (cval === 101) {\n /* 4th single pentagon cases */\n /* 1211 */\n rightbottom = interpolateX(maxV, br, tr);\n topleft = interpolateX(maxV, tl, tr);\n edges.push(isoBandEdgeRB[cval]);\n } else if (cval === 69) {\n /* 1011 */\n rightbottom = 1 - interpolateX(minV, tr, br);\n topleft = 1 - interpolateX(minV, tr, tl);\n edges.push(isoBandEdgeRB[cval]);\n } else if (cval === 149) {\n /* 2111 */\n leftbottom = interpolateX(maxV, bl, tl);\n topright = 1 - interpolateX(maxV, tr, tl);\n edges.push(isoBandEdgeLB[cval]);\n } else if (cval === 21) {\n /* 0111 */\n leftbottom = 1 - interpolateX(minV, tl, bl);\n topright = interpolateX(minV, tl, tr);\n edges.push(isoBandEdgeLB[cval]);\n } else if (cval === 86) {\n /* 1112 */\n bottomright = 1 - interpolateX(maxV, br, bl);\n lefttop = 1 - interpolateX(maxV, tl, bl);\n edges.push(isoBandEdgeBR[cval]);\n } else if (cval === 84) {\n /* 1110 */\n bottomright = interpolateX(minV, bl, br);\n lefttop = interpolateX(minV, bl, tl);\n edges.push(isoBandEdgeBR[cval]);\n } else if (cval === 89) {\n /* 1121 */\n righttop = 1 - interpolateX(maxV, tr, br);\n bottomleft = interpolateX(maxV, bl, br);\n edges.push(isoBandEdgeBL[cval]);\n } else if (cval === 81) {\n /* 1101 */\n righttop = interpolateX(minV, br, tr);\n bottomleft = 1 - interpolateX(minV, br, bl);\n edges.push(isoBandEdgeBL[cval]);\n } else if (cval === 96) {\n /* 1200 */\n righttop = interpolateX(maxV, br, tr);\n rightbottom = interpolateX(minV, br, tr);\n lefttop = interpolateX(minV, bl, tl);\n topleft = interpolateX(maxV, tl, tr);\n edges.push(isoBandEdgeRT[cval]);\n edges.push(isoBandEdgeRB[cval]);\n } else if (cval === 74) {\n /* 1022 */\n righttop = 1 - interpolateX(minV, tr, br);\n rightbottom = 1 - interpolateX(maxV, tr, br);\n lefttop = 1 - interpolateX(maxV, tl, bl);\n topleft = 1 - interpolateX(minV, tr, tl);\n edges.push(isoBandEdgeRT[cval]);\n edges.push(isoBandEdgeRB[cval]);\n } else if (cval === 24) {\n /* 0120 */\n righttop = 1 - interpolateX(maxV, tr, br);\n bottomright = interpolateX(maxV, bl, br);\n bottomleft = interpolateX(minV, bl, br);\n topright = interpolateX(minV, tl, tr);\n edges.push(isoBandEdgeRT[cval]);\n edges.push(isoBandEdgeBL[cval]);\n } else if (cval === 146) {\n /* 2102 */\n righttop = interpolateX(minV, br, tr);\n bottomright = 1 - interpolateX(minV, br, bl);\n bottomleft = 1 - interpolateX(maxV, br, bl);\n topright = 1 - interpolateX(maxV, tr, tl);\n edges.push(isoBandEdgeRT[cval]);\n edges.push(isoBandEdgeBL[cval]);\n } else if (cval === 6) {\n /* 0012 */\n rightbottom = 1 - interpolateX(minV, tr, br);\n bottomright = 1 - interpolateX(maxV, br, bl);\n leftbottom = 1 - interpolateX(maxV, tl, bl);\n lefttop = 1 - interpolateX(minV, tl, bl);\n edges.push(isoBandEdgeRB[cval]);\n edges.push(isoBandEdgeBR[cval]);\n } else if (cval === 164) {\n /* 2210 */\n rightbottom = interpolateX(maxV, br, tr);\n bottomright = interpolateX(minV, bl, br);\n leftbottom = interpolateX(minV, bl, tl);\n lefttop = interpolateX(maxV, bl, tl);\n edges.push(isoBandEdgeRB[cval]);\n edges.push(isoBandEdgeBR[cval]);\n } else if (cval === 129) {\n /* 2001 */\n bottomleft = 1 - interpolateX(minV, br, bl);\n leftbottom = interpolateX(maxV, bl, tl);\n topleft = 1 - interpolateX(maxV, tr, tl);\n topright = 1 - interpolateX(minV, tr, tl);\n edges.push(isoBandEdgeBL[cval]);\n edges.push(isoBandEdgeLB[cval]);\n } else if (cval === 41) {\n /* 0221 */\n bottomleft = interpolateX(maxV, bl, br);\n leftbottom = 1 - interpolateX(minV, tl, bl);\n topleft = interpolateX(minV, tl, tr);\n topright = interpolateX(maxV, tl, tr);\n edges.push(isoBandEdgeBL[cval]);\n edges.push(isoBandEdgeLB[cval]);\n } else if (cval === 66) {\n /* 1002 */\n bottomright = 1 - interpolateX(minV, br, bl);\n bottomleft = 1 - interpolateX(maxV, br, bl);\n lefttop = 1 - interpolateX(maxV, tl, bl);\n topleft = 1 - interpolateX(minV, tr, tl);\n edges.push(isoBandEdgeBR[cval]);\n edges.push(isoBandEdgeBL[cval]);\n } else if (cval === 104) {\n /* 1220 */\n bottomright = interpolateX(maxV, bl, br);\n bottomleft = interpolateX(minV, bl, br);\n lefttop = interpolateX(minV, bl, tl);\n topleft = interpolateX(maxV, tl, tr);\n edges.push(isoBandEdgeBL[cval]);\n edges.push(isoBandEdgeTL[cval]);\n } else if (cval === 144) {\n /* 2100 */\n righttop = interpolateX(minV, br, tr);\n leftbottom = interpolateX(minV, bl, tl);\n lefttop = interpolateX(maxV, bl, tl);\n topright = 1 - interpolateX(maxV, tr, tl);\n edges.push(isoBandEdgeRT[cval]);\n edges.push(isoBandEdgeLT[cval]);\n } else if (cval === 26) {\n /* 0122 */\n righttop = 1 - interpolateX(maxV, tr, br);\n leftbottom = 1 - interpolateX(maxV, tl, bl);\n lefttop = 1 - interpolateX(minV, tl, bl);\n topright = interpolateX(minV, tl, tr);\n edges.push(isoBandEdgeRT[cval]);\n edges.push(isoBandEdgeLT[cval]);\n } else if (cval === 36) {\n /* 0210 */\n rightbottom = interpolateX(maxV, br, tr);\n bottomright = interpolateX(minV, bl, br);\n topleft = interpolateX(minV, tl, tr);\n topright = interpolateX(maxV, tl, tr);\n edges.push(isoBandEdgeRB[cval]);\n edges.push(isoBandEdgeBR[cval]);\n } else if (cval === 134) {\n /* 2012 */\n rightbottom = 1 - interpolateX(minV, tr, br);\n bottomright = 1 - interpolateX(maxV, br, bl);\n topleft = 1 - interpolateX(maxV, tr, tl);\n topright = 1 - interpolateX(minV, tr, tl);\n edges.push(isoBandEdgeRB[cval]);\n edges.push(isoBandEdgeBR[cval]);\n } else if (cval === 9) {\n /* 0021 */\n righttop = 1 - interpolateX(minV, tr, br);\n rightbottom = 1 - interpolateX(maxV, tr, br);\n bottomleft = interpolateX(maxV, bl, br);\n leftbottom = 1 - interpolateX(minV, tl, bl);\n edges.push(isoBandEdgeRT[cval]);\n edges.push(isoBandEdgeRB[cval]);\n } else if (cval === 161) {\n /* 2201 */\n righttop = interpolateX(maxV, br, tr);\n rightbottom = interpolateX(minV, br, tr);\n bottomleft = 1 - interpolateX(minV, br, bl);\n leftbottom = interpolateX(maxV, bl, tl);\n edges.push(isoBandEdgeRT[cval]);\n edges.push(isoBandEdgeRB[cval]);\n } else if (cval === 37) {\n /* 5th single hexagon cases */\n /* 0211 */\n rightbottom = interpolateX(maxV, br, tr);\n leftbottom = 1 - interpolateX(minV, tl, bl);\n topleft = interpolateX(minV, tl, tr);\n topright = interpolateX(maxV, tl, tr);\n edges.push(isoBandEdgeRB[cval]);\n edges.push(isoBandEdgeLB[cval]);\n } else if (cval === 133) {\n /* 2011 */\n rightbottom = 1 - interpolateX(minV, tr, br);\n leftbottom = interpolateX(maxV, bl, tl);\n topleft = 1 - interpolateX(maxV, tr, tl);\n topright = 1 - interpolateX(minV, tr, tl);\n edges.push(isoBandEdgeRB[cval]);\n edges.push(isoBandEdgeLB[cval]);\n } else if (cval === 148) {\n /* 2110 */\n bottomright = interpolateX(minV, bl, br);\n leftbottom = interpolateX(minV, bl, tl);\n lefttop = interpolateX(maxV, bl, tl);\n topright = 1 - interpolateX(maxV, tr, tl);\n edges.push(isoBandEdgeBR[cval]);\n edges.push(isoBandEdgeLT[cval]);\n } else if (cval === 22) {\n /* 0112 */\n bottomright = 1 - interpolateX(maxV, br, bl);\n leftbottom = 1 - interpolateX(maxV, tl, bl);\n lefttop = 1 - interpolateX(minV, tl, bl);\n topright = interpolateX(minV, tl, tr);\n edges.push(isoBandEdgeBR[cval]);\n edges.push(isoBandEdgeLT[cval]);\n } else if (cval === 82) {\n /* 1102 */\n righttop = interpolateX(minV, br, tr);\n bottomright = 1 - interpolateX(minV, br, bl);\n bottomleft = 1 - interpolateX(maxV, br, bl);\n lefttop = 1 - interpolateX(maxV, tl, bl);\n edges.push(isoBandEdgeRT[cval]);\n edges.push(isoBandEdgeBL[cval]);\n } else if (cval === 88) {\n /* 1120 */\n righttop = 1 - interpolateX(maxV, tr, br);\n bottomright = interpolateX(maxV, bl, br);\n bottomleft = interpolateX(minV, bl, br);\n lefttop = interpolateX(minV, bl, tl);\n edges.push(isoBandEdgeRT[cval]);\n edges.push(isoBandEdgeBL[cval]);\n } else if (cval === 73) {\n /* 1021 */\n righttop = 1 - interpolateX(minV, tr, br);\n rightbottom = 1 - interpolateX(maxV, tr, br);\n bottomleft = interpolateX(maxV, bl, br);\n topleft = 1 - interpolateX(minV, tr, tl);\n edges.push(isoBandEdgeRT[cval]);\n edges.push(isoBandEdgeRB[cval]);\n } else if (cval === 97) {\n /* 1201 */\n righttop = interpolateX(maxV, br, tr);\n rightbottom = interpolateX(minV, br, tr);\n bottomleft = 1 - interpolateX(minV, br, bl);\n topleft = interpolateX(maxV, tl, tr);\n edges.push(isoBandEdgeRT[cval]);\n edges.push(isoBandEdgeRB[cval]);\n } else if (cval === 145) {\n /* 2101 */\n righttop = interpolateX(minV, br, tr);\n bottomleft = 1 - interpolateX(minV, br, bl);\n leftbottom = interpolateX(maxV, bl, tl);\n topright = 1 - interpolateX(maxV, tr, tl);\n edges.push(isoBandEdgeRT[cval]);\n edges.push(isoBandEdgeLB[cval]);\n } else if (cval === 25) {\n /* 0121 */\n righttop = 1 - interpolateX(maxV, tr, br);\n bottomleft = interpolateX(maxV, bl, br);\n leftbottom = 1 - interpolateX(minV, tl, bl);\n topright = interpolateX(minV, tl, tr);\n edges.push(isoBandEdgeRT[cval]);\n edges.push(isoBandEdgeLB[cval]);\n } else if (cval === 70) {\n /* 1012 */\n rightbottom = 1 - interpolateX(minV, tr, br);\n bottomright = 1 - interpolateX(maxV, br, bl);\n lefttop = 1 - interpolateX(maxV, tl, bl);\n topleft = 1 - interpolateX(minV, tr, tl);\n edges.push(isoBandEdgeRB[cval]);\n edges.push(isoBandEdgeBR[cval]);\n } else if (cval === 100) {\n /* 1210 */\n rightbottom = interpolateX(maxV, br, tr);\n bottomright = interpolateX(minV, bl, br);\n lefttop = interpolateX(minV, bl, tl);\n topleft = interpolateX(maxV, tl, tr);\n edges.push(isoBandEdgeRB[cval]);\n edges.push(isoBandEdgeBR[cval]);\n } else if (cval === 34) {\n /* 8-sided cases */\n /* 0202 || 2020 with flipped == 0 */\n if (flipped === 0) {\n righttop = 1 - interpolateX(minV, tr, br);\n rightbottom = 1 - interpolateX(maxV, tr, br);\n bottomright = interpolateX(maxV, bl, br);\n bottomleft = interpolateX(minV, bl, br);\n leftbottom = interpolateX(minV, bl, tl);\n lefttop = interpolateX(maxV, bl, tl);\n topleft = 1 - interpolateX(maxV, tr, tl);\n topright = 1 - interpolateX(minV, tr, tl);\n } else {\n righttop = interpolateX(maxV, br, tr);\n rightbottom = interpolateX(minV, br, tr);\n bottomright = 1 - interpolateX(minV, br, bl);\n bottomleft = 1 - interpolateX(maxV, br, bl);\n leftbottom = 1 - interpolateX(maxV, tl, bl);\n lefttop = 1 - interpolateX(minV, tl, bl);\n topleft = interpolateX(minV, tl, tr);\n topright = interpolateX(maxV, tl, tr);\n }\n edges.push(isoBandEdgeRT[cval]);\n edges.push(isoBandEdgeRB[cval]);\n edges.push(isoBandEdgeLB[cval]);\n edges.push(isoBandEdgeLT[cval]);\n } else if (cval === 35) {\n /* flipped == 1 state for 0202, and 2020 with flipped == 4 */\n if (flipped === 4) {\n righttop = 1 - interpolateX(minV, tr, br);\n rightbottom = 1 - interpolateX(maxV, tr, br);\n bottomright = interpolateX(maxV, bl, br);\n bottomleft = interpolateX(minV, bl, br);\n leftbottom = interpolateX(minV, bl, tl);\n lefttop = interpolateX(maxV, bl, tl);\n topleft = 1 - interpolateX(maxV, tr, tl);\n topright = 1 - interpolateX(minV, tr, tl);\n } else {\n righttop = interpolateX(maxV, br, tr);\n rightbottom = interpolateX(minV, br, tr);\n bottomright = 1 - interpolateX(minV, br, bl);\n bottomleft = 1 - interpolateX(maxV, br, bl);\n leftbottom = 1 - interpolateX(maxV, tl, bl);\n lefttop = 1 - interpolateX(minV, tl, bl);\n topleft = interpolateX(minV, tl, tr);\n topright = interpolateX(maxV, tl, tr);\n }\n edges.push(isoBandEdgeRT[cval]);\n edges.push(isoBandEdgeRB[cval]);\n edges.push(isoBandEdgeBL[cval]);\n edges.push(isoBandEdgeLT[cval]);\n } else if (cval === 136) {\n /* 2020 || 0202 with flipped == 0 */\n if (flipped === 0) {\n righttop = interpolateX(maxV, br, tr);\n rightbottom = interpolateX(minV, br, tr);\n bottomright = 1 - interpolateX(minV, br, bl);\n bottomleft = 1 - interpolateX(maxV, br, bl);\n leftbottom = 1 - interpolateX(maxV, tl, bl);\n lefttop = 1 - interpolateX(minV, tl, bl);\n topleft = interpolateX(minV, tl, tr);\n topright = interpolateX(maxV, tl, tr);\n } else {\n righttop = 1 - interpolateX(minV, tr, br);\n rightbottom = 1 - interpolateX(maxV, tr, br);\n bottomright = interpolateX(maxV, bl, br);\n bottomleft = interpolateX(minV, bl, br);\n leftbottom = interpolateX(minV, bl, tl);\n lefttop = interpolateX(maxV, bl, tl);\n topleft = 1 - interpolateX(maxV, tr, tl);\n topright = 1 - interpolateX(minV, tr, tl);\n }\n edges.push(isoBandEdgeRT[cval]);\n edges.push(isoBandEdgeRB[cval]);\n edges.push(isoBandEdgeLB[cval]);\n edges.push(isoBandEdgeLT[cval]);\n } else if (cval === 153) {\n /* 6-sided polygon cases */\n /* 0101 with flipped == 0 || 2121 with flipped == 2 */\n if (flipped === 0) {\n righttop = interpolateX(minV, br, tr);\n bottomleft = 1 - interpolateX(minV, br, bl);\n leftbottom = 1 - interpolateX(minV, tl, bl);\n topright = interpolateX(minV, tl, tr);\n } else {\n righttop = 1 - interpolateX(maxV, tr, br);\n bottomleft = interpolateX(maxV, bl, br);\n leftbottom = interpolateX(maxV, bl, tl);\n topright = 1 - interpolateX(maxV, tr, tl);\n }\n edges.push(isoBandEdgeRT[cval]);\n edges.push(isoBandEdgeBL[cval]);\n } else if (cval === 102) {\n /* 1010 with flipped == 0 || 1212 with flipped == 2 */\n if (flipped === 0) {\n rightbottom = 1 - interpolateX(minV, tr, br);\n bottomright = interpolateX(minV, bl, br);\n lefttop = interpolateX(minV, bl, tl);\n topleft = 1 - interpolateX(minV, tr, tl);\n } else {\n rightbottom = interpolateX(maxV, br, tr);\n bottomright = 1 - interpolateX(maxV, br, bl);\n lefttop = 1 - interpolateX(maxV, tl, bl);\n topleft = interpolateX(maxV, tl, tr);\n }\n edges.push(isoBandEdgeRB[cval]);\n edges.push(isoBandEdgeLT[cval]);\n } else if (cval === 155) {\n /* 0101 with flipped == 4 || 2121 with flipped == 1 */\n if (flipped === 4) {\n righttop = interpolateX(minV, br, tr);\n bottomleft = 1 - interpolateX(minV, br, bl);\n leftbottom = 1 - interpolateX(minV, tl, bl);\n topright = interpolateX(minV, tl, tr);\n } else {\n righttop = 1 - interpolateX(maxV, tr, br);\n bottomleft = interpolateX(maxV, bl, br);\n leftbottom = interpolateX(maxV, bl, tl);\n topright = 1 - interpolateX(maxV, tr, tl);\n }\n edges.push(isoBandEdgeRT[cval]);\n edges.push(isoBandEdgeLB[cval]);\n } else if (cval === 103) {\n /* 1010 with flipped == 4 || 1212 with flipped == 1 */\n if (flipped === 4) {\n rightbottom = 1 - interpolateX(minV, tr, br);\n bottomright = interpolateX(minV, bl, br);\n lefttop = interpolateX(minV, bl, tl);\n topleft = 1 - interpolateX(minV, tr, tl);\n } else {\n rightbottom = interpolateX(maxV, br, tr);\n bottomright = 1 - interpolateX(maxV, br, bl);\n lefttop = 1 - interpolateX(maxV, tl, bl);\n topleft = interpolateX(maxV, tl, tr);\n }\n edges.push(isoBandEdgeRB[cval]);\n edges.push(isoBandEdgeBR[cval]);\n } else if (cval === 152) {\n /* 7-sided polygon cases */\n /* 2120 with flipped == 2 || 0102 with flipped == 0 */\n if (flipped === 0) {\n righttop = interpolateX(minV, br, tr);\n bottomright = 1 - interpolateX(minV, br, bl);\n bottomleft = 1 - interpolateX(maxV, br, bl);\n leftbottom = 1 - interpolateX(maxV, tl, bl);\n lefttop = 1 - interpolateX(minV, tl, bl);\n topright = interpolateX(minV, tl, tr);\n } else {\n righttop = 1 - interpolateX(maxV, tr, br);\n bottomright = interpolateX(maxV, bl, br);\n bottomleft = interpolateX(minV, bl, br);\n leftbottom = interpolateX(minV, bl, tl);\n lefttop = interpolateX(maxV, bl, tl);\n topright = 1 - interpolateX(maxV, tr, tl);\n }\n edges.push(isoBandEdgeRT[cval]);\n edges.push(isoBandEdgeBR[cval]);\n edges.push(isoBandEdgeBL[cval]);\n } else if (cval === 156) {\n /* 2120 with flipped == 1 || 0102 with flipped == 4 */\n if (flipped === 4) {\n righttop = interpolateX(minV, br, tr);\n bottomright = 1 - interpolateX(minV, br, bl);\n bottomleft = 1 - interpolateX(maxV, br, bl);\n leftbottom = 1 - interpolateX(maxV, tl, bl);\n lefttop = 1 - interpolateX(minV, tl, bl);\n topright = interpolateX(minV, tl, tr);\n } else {\n righttop = 1 - interpolateX(maxV, tr, br);\n bottomright = interpolateX(maxV, bl, br);\n bottomleft = interpolateX(minV, bl, br);\n leftbottom = interpolateX(minV, bl, tl);\n lefttop = interpolateX(maxV, bl, tl);\n topright = 1 - interpolateX(maxV, tr, tl);\n }\n edges.push(isoBandEdgeRT[cval]);\n edges.push(isoBandEdgeBL[cval]);\n edges.push(isoBandEdgeLT[cval]);\n } else if (cval === 137) {\n /* 2021 with flipped == 2 || 0201 with flipped == 0 */\n if (flipped === 0) {\n righttop = interpolateX(maxV, br, tr);\n rightbottom = interpolateX(minV, br, tr);\n bottomleft = 1 - interpolateX(minV, br, bl);\n leftbottom = 1 - interpolateX(minV, tl, bl);\n topleft = interpolateX(minV, tl, tr);\n topright = interpolateX(maxV, tl, tr);\n } else {\n righttop = 1 - interpolateX(minV, tr, br);\n rightbottom = 1 - interpolateX(maxV, tr, br);\n bottomleft = interpolateX(maxV, bl, br);\n leftbottom = interpolateX(maxV, bl, tl);\n topleft = 1 - interpolateX(maxV, tr, tl);\n topright = 1 - interpolateX(minV, tr, tl);\n }\n edges.push(isoBandEdgeRT[cval]);\n edges.push(isoBandEdgeRB[cval]);\n edges.push(isoBandEdgeBL[cval]);\n } else if (cval === 139) {\n /* 2021 with flipped == 1 || 0201 with flipped == 4 */\n if (flipped === 4) {\n righttop = interpolateX(maxV, br, tr);\n rightbottom = interpolateX(minV, br, tr);\n bottomleft = 1 - interpolateX(minV, br, bl);\n leftbottom = 1 - interpolateX(minV, tl, bl);\n topleft = interpolateX(minV, tl, tr);\n topright = interpolateX(maxV, tl, tr);\n } else {\n righttop = 1 - interpolateX(minV, tr, br);\n rightbottom = 1 - interpolateX(maxV, tr, br);\n bottomleft = interpolateX(maxV, bl, br);\n leftbottom = interpolateX(maxV, bl, tl);\n topleft = 1 - interpolateX(maxV, tr, tl);\n topright = 1 - interpolateX(minV, tr, tl);\n }\n edges.push(isoBandEdgeRT[cval]);\n edges.push(isoBandEdgeRB[cval]);\n edges.push(isoBandEdgeLB[cval]);\n } else if (cval === 98) {\n /* 1202 with flipped == 2 || 1020 with flipped == 0 */\n if (flipped === 0) {\n righttop = 1 - interpolateX(minV, tr, br);\n rightbottom = 1 - interpolateX(maxV, tr, br);\n bottomright = interpolateX(maxV, bl, br);\n bottomleft = interpolateX(minV, bl, br);\n lefttop = interpolateX(minV, bl, tl);\n topleft = 1 - interpolateX(minV, tr, tl);\n } else {\n righttop = interpolateX(maxV, br, tr);\n rightbottom = interpolateX(minV, br, tr);\n bottomright = 1 - interpolateX(minV, br, bl);\n bottomleft = 1 - interpolateX(maxV, br, bl);\n lefttop = 1 - interpolateX(maxV, tl, bl);\n topleft = interpolateX(maxV, tl, tr);\n }\n edges.push(isoBandEdgeRT[cval]);\n edges.push(isoBandEdgeRB[cval]);\n edges.push(isoBandEdgeLT[cval]);\n } else if (cval === 99) {\n /* 1202 with flipped == 1 || 1020 with flipped == 4 */\n if (flipped === 4) {\n righttop = 1 - interpolateX(minV, tr, br);\n rightbottom = 1 - interpolateX(maxV, tr, br);\n bottomright = interpolateX(maxV, bl, br);\n bottomleft = interpolateX(minV, bl, br);\n lefttop = interpolateX(minV, bl, tl);\n topleft = 1 - interpolateX(minV, tr, tl);\n } else {\n righttop = interpolateX(maxV, br, tr);\n rightbottom = interpolateX(minV, br, tr);\n bottomright = 1 - interpolateX(minV, br, bl);\n bottomleft = 1 - interpolateX(maxV, br, bl);\n lefttop = 1 - interpolateX(maxV, tl, bl);\n topleft = interpolateX(maxV, tl, tr);\n }\n edges.push(isoBandEdgeRT[cval]);\n edges.push(isoBandEdgeRB[cval]);\n edges.push(isoBandEdgeBL[cval]);\n } else if (cval === 38) {\n /* 0212 with flipped == 2 || 2010 with flipped == 0 */\n if (flipped === 0) {\n rightbottom = 1 - interpolateX(minV, tr, br);\n bottomright = interpolateX(minV, bl, br);\n leftbottom = interpolateX(minV, bl, tl);\n lefttop = interpolateX(maxV, bl, tl);\n topleft = 1 - interpolateX(maxV, tr, tl);\n topright = 1 - interpolateX(minV, tr, tl);\n } else {\n rightbottom = interpolateX(maxV, br, tr);\n bottomright = 1 - interpolateX(maxV, br, bl);\n leftbottom = 1 - interpolateX(maxV, tl, bl);\n lefttop = 1 - interpolateX(minV, tl, bl);\n topleft = interpolateX(minV, tl, tr);\n topright = interpolateX(maxV, tl, tr);\n }\n edges.push(isoBandEdgeRB[cval]);\n edges.push(isoBandEdgeLB[cval]);\n edges.push(isoBandEdgeLT[cval]);\n } else if (cval === 39) {\n /* 0212 with flipped == 1 || 2010 with flipped == 4 */\n if (flipped === 4) {\n rightbottom = 1 - interpolateX(minV, tr, br);\n bottomright = interpolateX(minV, bl, br);\n leftbottom = interpolateX(minV, bl, tl);\n lefttop = interpolateX(maxV, bl, tl);\n topleft = 1 - interpolateX(maxV, tr, tl);\n topright = 1 - interpolateX(minV, tr, tl);\n } else {\n rightbottom = interpolateX(maxV, br, tr);\n bottomright = 1 - interpolateX(maxV, br, bl);\n leftbottom = 1 - interpolateX(maxV, tl, bl);\n lefttop = 1 - interpolateX(minV, tl, bl);\n topleft = interpolateX(minV, tl, tr);\n topright = interpolateX(maxV, tl, tr);\n }\n edges.push(isoBandEdgeRB[cval]);\n edges.push(isoBandEdgeBR[cval]);\n edges.push(isoBandEdgeLT[cval]);\n } else if (cval === 85) {\n righttop = 1;\n rightbottom = 0;\n bottomright = 1;\n bottomleft = 0;\n leftbottom = 0;\n lefttop = 1;\n topleft = 0;\n topright = 1;\n }\n\n if (\n topleft < 0 ||\n topleft > 1 ||\n topright < 0 ||\n topright > 1 ||\n righttop < 0 ||\n righttop > 1 ||\n bottomright < 0 ||\n bottomright > 1 ||\n leftbottom < 0 ||\n leftbottom > 1 ||\n lefttop < 0 ||\n lefttop > 1\n ) {\n console.log(\n `${cval} ${cval_real} ${tl},${tr},${br},${bl} ${flipped} ${topleft} ${topright} ${righttop} ${rightbottom} ${bottomright} ${bottomleft} ${leftbottom} ${lefttop}`,\n );\n }\n\n BandGrid.cells[j][i] = {\n cval,\n cval_real,\n flipped,\n topleft,\n topright,\n righttop,\n rightbottom,\n bottomright,\n bottomleft,\n leftbottom,\n lefttop,\n edges,\n };\n }\n }\n }\n\n return BandGrid;\n};\n\nfunction BandGrid2AreaPaths(grid) {\n const areas = [];\n const { rows } = grid;\n const { cols } = grid;\n let currentPolygon = [];\n const holes = [];\n let count = 0;\n\n for (let j = 0; j < rows; j++) {\n for (let i = 0; i < cols; i++) {\n if (typeof grid.cells[j][i] !== 'undefined' && grid.cells[j][i].edges.length > 0) {\n const cell = grid.cells[j][i];\n /* get start coordinates */\n const { cval } = cell;\n\n let prev = getStartXY(cell);\n let next = null;\n let p = i;\n let q = j;\n\n if (prev !== null) {\n currentPolygon.push([prev.p[0] + p, prev.p[1] + q]);\n // console.log(cell);\n // console.log(\"coords: \" + (prev.p[0] + p) + \" \" + (prev.p[1] + q));\n }\n do {\n if (count > rows * cols) {\n console.log(\n 'Infinite loop dectected in Marching Squares. Breaking out',\n count,\n i,\n j,\n );\n return [];\n }\n count += 1;\n // console.log(p + \",\" + q);\n // console.log(grid.cells[q][p]);\n // console.log(grid.cells[q][p].edges);\n\n next = getExitXY(grid.cells[q][p], prev.x, prev.y, prev.o);\n\n if (next !== null) {\n // console.log(\"coords: \" + (next.p[0] + p) + \" \" + (next.p[1] + q));\n currentPolygon.push([next.p[0] + p, next.p[1] + q]);\n p += next.x;\n q += next.y;\n prev = next;\n } else {\n // console.log(\"getExitXY() returned null!\");\n break;\n }\n // console.log(\"to : \" + next.x + \" \" + next.y + \" \" + next.o);\n /* special case, where we've reached the grid boundaries */\n if (\n q < 0 ||\n q >= rows ||\n p < 0 ||\n p >= cols ||\n typeof grid.cells[q][p] === 'undefined'\n ) {\n /* to create a closed path, we need to trace our way\n arround the missing data, until we find an entry\n point again\n */\n\n /* set back coordinates of current cell */\n p -= next.x;\n q -= next.y;\n\n // console.log(\"reached boundary at \" + p + \" \" + q);\n\n const missing = traceOutOfGridPath(grid, p, q, next.x, next.y, next.o);\n if (missing !== null) {\n missing.path.forEach((pp) => {\n // console.log(\"coords: \" + (pp[0]) + \" \" + (pp[1]));\n currentPolygon.push(pp);\n });\n p = missing.i;\n q = missing.j;\n prev = missing;\n } else {\n break;\n }\n // console.log(grid.cells[q][p]);\n }\n } while (\n typeof grid.cells[q][p] !== 'undefined' &&\n grid.cells[q][p].edges.length > 0\n );\n\n if (isClockwise(currentPolygon)) {\n areas.push(currentPolygon);\n } else {\n holes.push(currentPolygon);\n }\n // console.log(currentPolygon);\n // console.log(polygonArea([...currentPolygon]));\n // console.log(\" \")\n currentPolygon = [];\n if (grid.cells[j][i].edges.length > 0) i--;\n }\n }\n }\n\n function isClockwise(poly) {\n let sum = 0;\n for (let i = 0; i < poly.length - 1; i++) {\n const cur = poly[i];\n const next = poly[i + 1];\n sum += (next[0] - cur[0]) * (next[1] + cur[1]);\n }\n return sum > 0;\n }\n\n const polygons = [];\n areas.forEach((area, j) => {\n const p = [];\n p.push(area);\n\n for (let i = holes.length - 1; i >= 0; i--) {\n const hole = holes[i];\n if (insidepolygon(hole[0], area)) {\n // if ( insidePolygonExact.insidepolygon(hole[0], area) <= 0 ){\n p.push(hole);\n // Since we found a spot for this hole remove it\n holes.splice(i, 1);\n }\n }\n /*\n holes.forEach(hole => {\n // check to see if the first point of the hole (hole[0])\n // is in the polygon, if so, add it. \n if ( insidepolygon(hole[0], area)){ // true\n //if ( insidePolygonExact.insidepolygon(hole[0], area) <= 0 ){\n p.push(hole)\n }\n });\n */\n\n polygons.push(p);\n });\n\n const holes_cp = [...holes];\n // Now if there are any leftover holes, check to see if they fit in each other, if they don't, it must be a parent polygon\n holes_cp.forEach((area) => {\n const p = [];\n for (let i = holes.length - 1; i >= 0; i--) {\n const hole = holes[i];\n // if this hole is idential to the one we are testing against, skip\n if (JSON.stringify(area) === JSON.stringify(hole)) {\n continue;\n }\n if (insidepolygon(hole[0], area)) {\n p.push(hole);\n holes.splice(i, 1);\n }\n }\n if (p.length > 0) {\n polygons.push(p);\n }\n });\n\n // Any leftover holes must be true areas\n // 3d array\n\n if (holes.length > 0) {\n const p = [];\n if (holes[0] && holes[0][0] && holes[0][0][0]) {\n holes.forEach((area) => {\n p.push(area);\n });\n }\n // 2d array\n else {\n p.push(holes);\n }\n polygons.push(p);\n }\n\n return polygons;\n}\n\nfunction insidepolygon(point, vs) {\n // ray-casting algorithm based on\n // https://wrf.ecse.rpi.edu/Research/Short_Notes/pnpoly.html/pnpoly.html\n\n const x = point[0];\n const y = point[1];\n\n let inside = false;\n for (let i = 0, j = vs.length - 1; i < vs.length; j = i++) {\n const xi = vs[i][0];\n const yi = vs[i][1];\n const xj = vs[j][0];\n const yj = vs[j][1];\n\n const intersect = yi > y != yj > y && x < ((xj - xi) * (y - yi)) / (yj - yi) + xi;\n if (intersect) inside = !inside;\n }\n\n return inside;\n}\n\nfunction traceOutOfGridPath(grid, i, j, d_x, d_y, d_o) {\n let cell = grid.cells[j][i];\n let cval = cell.cval_real;\n let p = i + d_x;\n let q = j + d_y;\n const path = [];\n const { rows } = grid;\n const { cols } = grid;\n let closed = false;\n\n while (!closed) {\n // console.log(\"processing cell \" + p + \",\" + q + \" \" + d_x + \" \" + d_y + \" \" + d_o);\n if (typeof grid.cells[q] === 'undefined' || typeof grid.cells[q][p] === 'undefined') {\n // console.log(\"which is undefined\");\n /* we can't move on, so we have to change direction to proceed further */\n\n /* go back to previous cell */\n q -= d_y;\n p -= d_x;\n cell = grid.cells[q][p];\n cval = cell.cval_real;\n\n /* check where we've left defined cells of the grid... */\n if (d_y === -1) {\n /* we came from top */\n if (d_o === 0) {\n /* exit left */\n if (cval & Node3) {\n /* lower left node is within range, so we move left */\n path.push([p, q]);\n d_x = -1;\n d_y = 0;\n d_o = 0;\n } else if (cval & Node2) {\n /* lower right node is within range, so we move right */\n path.push([p + 1, q]);\n d_x = 1;\n d_y = 0;\n d_o = 0;\n } else {\n /* close the path */\n path.push([p + cell.bottomright, q]);\n d_x = 0;\n d_y = 1;\n d_o = 1;\n closed = true;\n break;\n }\n } else if (cval & Node3) {\n path.push([p, q]);\n d_x = -1;\n d_y = 0;\n d_o = 0;\n } else if (cval & Node2) {\n path.push([p + cell.bottomright, q]);\n d_x = 0;\n d_y = 1;\n d_o = 1;\n closed = true;\n break;\n } else {\n path.push([p + cell.bottomleft, q]);\n d_x = 0;\n d_y = 1;\n d_o = 0;\n closed = true;\n break;\n }\n } else if (d_y === 1) {\n /* we came from bottom */\n // console.log(\"we came from bottom and hit a non-existing cell \" + (p + d_x) + \",\" + (q + d_y) + \"!\");\n if (d_o === 0) {\n /* exit left */\n if (cval & Node1) {\n /* top right node is within range, so we move right */\n path.push([p + 1, q + 1]);\n d_x = 1;\n d_y = 0;\n d_o = 1;\n } else if (!(cval & Node0)) {\n /* found entry within same cell */\n path.push([p + cell.topright, q + 1]);\n d_x = 0;\n d_y = -1;\n d_o = 1;\n closed = true;\n // console.log(\"found entry from bottom at \" + p + \",\" + q);\n break;\n } else {\n path.push([p + cell.topleft, q + 1]);\n d_x = 0;\n d_y = -1;\n d_o = 0;\n closed = true;\n break;\n }\n } else if (cval & Node1) {\n path.push([p + 1, q + 1]);\n d_x = 1;\n d_y = 0;\n d_o = 1;\n } else {\n /* move right */\n path.push([p + 1, q + 1]);\n d_x = 1;\n d_y = 0;\n d_o = 1;\n // console.log(\"wtf\");\n // break;\n }\n } else if (d_x === -1) {\n /* we came from right */\n // console.log(\"we came from right and hit a non-existing cell at \" + (p + d_x) + \",\" + (q + d_y) + \"!\");\n if (d_o === 0) {\n // console.log(\"continue at bottom\");\n if (cval & Node0) {\n path.push([p, q + 1]);\n d_x = 0;\n d_y = 1;\n d_o = 0;\n // console.log(\"moving upwards to \" + (p + d_x) + \",\" + (q + d_y) + \"!\");\n } else if (!(cval & Node3)) {\n /* there has to be an entry into the regular grid again! */\n // console.log(\"exiting top\");\n path.push([p, q + cell.lefttop]);\n d_x = 1;\n d_y = 0;\n d_o = 1;\n closed = true;\n break;\n } else {\n // console.log(\"exiting bottom\");\n path.push([p, q + cell.leftbottom]);\n d_x = 1;\n d_y = 0;\n d_o = 0;\n closed = true;\n break;\n }\n } else {\n // console.log(\"continue at top\");\n if (cval & Node0) {\n path.push([p, q + 1]);\n d_x = 0;\n d_y = 1;\n d_o = 0;\n // console.log(\"moving upwards to \" + (p + d_x) + \",\" + (q + d_y) + \"!\");\n } else {\n /* */\n console.log('wtf');\n break;\n }\n }\n } else if (d_x === 1) {\n /* we came from left */\n // console.log(\"we came from left and hit a non-existing cell \" + (p + d_x) + \",\" + (q + d_y) + \"!\");\n if (d_o === 0) {\n /* exit bottom */\n if (cval & Node2) {\n path.push([p + 1, q]);\n d_x = 0;\n d_y = -1;\n d_o = 1;\n } else {\n path.push([p + 1, q + cell.rightbottom]);\n d_x = -1;\n d_y = 0;\n d_o = 0;\n closed = true;\n break;\n }\n } else {\n /* exit top */\n if (cval & Node2) {\n path.push([p + 1, q]);\n d_x = 0;\n d_y = -1;\n d_o = 1;\n } else if (!(cval & Node1)) {\n path.push([p + 1, q + cell.rightbottom]);\n d_x = -1;\n d_y = 0;\n d_o = 0;\n closed = true;\n break;\n } else {\n path.push([p + 1, q + cell.righttop]);\n d_x = -1;\n d_y = 0;\n d_o = 1;\n break;\n }\n }\n } else {\n /* we came from the same cell */\n console.log('we came from nowhere!');\n break;\n }\n } else {\n /* try to find an entry into the regular grid again! */\n cell = grid.cells[q][p];\n cval = cell.cval_real;\n // console.log(\"which is defined\");\n\n if (d_x === -1) {\n if (d_o === 0) {\n /* try to go downwards */\n if (\n typeof grid.cells[q - 1] !== 'undefined' &&\n typeof grid.cells[q - 1][p] !== 'undefined'\n ) {\n d_x = 0;\n d_y = -1;\n d_o = 1;\n } else if (cval & Node3) {\n /* proceed searching in x-direction */\n // console.log(\"proceeding in x-direction!\");\n path.push([p, q]);\n } else {\n /* we must have found an entry into the regular grid */\n path.push([p + cell.bottomright, q]);\n d_x = 0;\n d_y = 1;\n d_o = 1;\n closed = true;\n // console.log(\"found entry from bottom at \" + p + \",\" + q);\n break;\n }\n } else if (cval & Node0) {\n /* proceed searchin in x-direction */\n console.log('proceeding in x-direction!');\n } else {\n /* we must have found an entry into the regular grid */\n console.log(`found entry from top at ${p},${q}`);\n break;\n }\n } else if (d_x === 1) {\n if (d_o === 0) {\n console.log('wtf');\n break;\n } else {\n /* try to go upwards */\n if (\n typeof grid.cells[q + 1] !== 'undefined' &&\n typeof grid.cells[q + 1][p] !== 'undefined'\n ) {\n d_x = 0;\n d_y = 1;\n d_o = 0;\n } else if (cval & Node1) {\n path.push([p + 1, q + 1]);\n d_x = 1;\n d_y = 0;\n d_o = 1;\n } else {\n /* found an entry point into regular grid! */\n path.push([p + cell.topleft, q + 1]);\n d_x = 0;\n d_y = -1;\n d_o = 0;\n closed = true;\n // console.log(\"found entry from bottom at \" + p + \",\" + q);\n break;\n }\n }\n } else if (d_y === -1) {\n if (d_o === 1) {\n /* try to go right */\n if (typeof grid.cells[q][p + 1] !== 'undefined') {\n d_x = 1;\n d_y = 0;\n d_o = 1;\n } else if (cval & Node2) {\n path.push([p + 1, q]);\n d_x = 0;\n d_y = -1;\n d_o = 1;\n } else {\n /* found entry into regular grid! */\n path.push([p + 1, q + cell.righttop]);\n d_x = -1;\n d_y = 0;\n d_o = 1;\n closed = true;\n // console.log(\"found entry from top at \" + p + \",\" + q);\n break;\n }\n } else {\n console.log('wtf');\n break;\n }\n } else if (d_y === 1) {\n if (d_o === 0) {\n // console.log(\"we came from bottom left and proceed to the left\");\n /* try to go left */\n if (typeof grid.cells[q][p - 1] !== 'undefined') {\n d_x = -1;\n d_y = 0;\n d_o = 0;\n } else if (cval & Node0) {\n path.push([p, q + 1]);\n d_x = 0;\n d_y = 1;\n d_o = 0;\n } else {\n /* found an entry point into regular grid! */\n path.push([p, q + cell.leftbottom]);\n d_x = 1;\n d_y = 0;\n d_o = 0;\n closed = true;\n // console.log(\"found entry from bottom at \" + p + \",\" + q);\n break;\n }\n } else {\n // console.log(\"we came from bottom right and proceed to the right\");\n console.log('wtf');\n break;\n }\n } else {\n console.log('where did we came from???');\n break;\n }\n }\n\n p += d_x;\n q += d_y;\n // console.log(\"going on to \" + p + \",\" + q + \" via \" + d_x + \" \" + d_y + \" \" + d_o);\n\n if (p === i && q === j) {\n /* bail out, once we've closed a circle path */\n break;\n }\n }\n\n // console.log(\"exit with \" + p + \",\" + q + \" \" + d_x + \" \" + d_y + \" \" + d_o);\n return { path, i: p, j: q, x: d_x, y: d_y, o: d_o };\n}\n\nfunction deleteEdge(cell, edgeIdx) {\n delete cell.edges[edgeIdx];\n for (let k = edgeIdx + 1; k < cell.edges.length; k++) {\n cell.edges[k - 1] = cell.edges[k];\n }\n cell.edges.pop();\n}\n\nfunction getStartXY(cell) {\n if (cell.edges.length > 0) {\n const e = cell.edges[cell.edges.length - 1];\n // console.log(\"starting with edge \" + e);\n const cval = cell.cval_real;\n switch (e) {\n case 0:\n if (cval & Node1) {\n /* node 1 within range */\n return { p: [1, cell.righttop], x: -1, y: 0, o: 1 };\n }\n /* node 1 below or above threshold */\n return { p: [cell.topleft, 1], x: 0, y: -1, o: 0 };\n\n case 1:\n if (cval & Node2) {\n return { p: [cell.topleft, 1], x: 0, y: -1, o: 0 };\n }\n return { p: [1, cell.rightbottom], x: -1, y: 0, o: 0 };\n\n case 2:\n if (cval & Node2) {\n return { p: [cell.bottomright, 0], x: 0, y: 1, o: 1 };\n }\n return { p: [cell.topleft, 1], x: 0, y: -1, o: 0 };\n\n case 3:\n if (cval & Node3) {\n return { p: [cell.topleft, 1], x: 0, y: -1, o: 0 };\n }\n return { p: [cell.bottomleft, 0], x: 0, y: 1, o: 0 };\n\n case 4:\n if (cval & Node1) {\n return { p: [1, cell.righttop], x: -1, y: 0, o: 1 };\n }\n return { p: [cell.topright, 1], x: 0, y: -1, o: 1 };\n\n case 5:\n if (cval & Node2) {\n return { p: [cell.topright, 1], x: 0, y: -1, o: 1 };\n }\n return { p: [1, cell.rightbottom], x: -1, y: 0, o: 0 };\n\n case 6:\n if (cval & Node2) {\n return { p: [cell.bottomright, 0], x: 0, y: 1, o: 1 };\n }\n return { p: [cell.topright, 1], x: 0, y: -1, o: 1 };\n\n case 7:\n if (cval & Node3) {\n return { p: [cell.topright, 1], x: 0, y: -1, o: 1 };\n }\n return { p: [cell.bottomleft, 0], x: 0, y: 1, o: 0 };\n\n case 8:\n if (cval & Node2) {\n return { p: [cell.bottomright], x: 0, y: 1, o: 1 };\n }\n return { p: [1, cell.righttop], x: -1, y: 0, o: 1 };\n\n case 9:\n if (cval & Node3) {\n return { p: [1, cell.righttop], x: -1, y: 0, o: 1 };\n }\n return { p: [cell.bottomleft, 0], x: 0, y: 1, o: 0 };\n\n case 10:\n if (cval & Node3) {\n return { p: [0, cell.leftbottom], x: 1, y: 0, o: 0 };\n }\n return { p: [1, cell.righttop], x: -1, y: 0, o: 1 };\n\n case 11:\n if (cval & Node0) {\n return { p: [1, cell.righttop], x: -1, y: 0, o: 1 };\n }\n return { p: [0, cell.lefttop], x: 1, y: 0, o: 1 };\n\n case 12:\n if (cval & Node2) {\n return { p: [cell.bottomright, 0], x: 0, y: 1, o: 1 };\n }\n return { p: [1, cell.rightbottom], x: -1, y: 0, o: 0 };\n\n case 13:\n if (cval & Node3) {\n return { p: [1, cell.rightbottom], x: -1, y: 0, o: 0 };\n }\n return { p: [cell.bottomleft, 0], x: 0, y: 1, o: 0 };\n\n case 14:\n if (cval & Node3) {\n return { p: [0, cell.leftbottom], x: 1, y: 0, o: 0 };\n }\n return { p: [1, cell.rightbottom], x: -1, y: 0, o: 0 };\n\n case 15:\n if (cval & Node0) {\n return { p: [1, cell.rightbottom], x: -1, y: 0, o: 0 };\n }\n return { p: [0, cell.lefttop], x: 1, y: 0, o: 1 };\n\n case 16:\n if (cval & Node2) {\n return { p: [cell.bottomright, 0], x: 0, y: 1, o: 1 };\n }\n return { p: [0, cell.leftbottom], x: 1, y: 0, o: 0 };\n\n case 17:\n if (cval & Node0) {\n return { p: [cell.bottomright, 0], x: 0, y: 1, o: 1 };\n }\n return { p: [0, cell.lefttop], x: 1, y: 0, o: 1 };\n\n case 18:\n if (cval & Node3) {\n return { p: [0, cell.leftbottom], x: 1, y: 0, o: 0 };\n }\n return { p: [cell.bottomleft, 0], x: 0, y: 1, o: 0 };\n\n case 19:\n if (cval & Node0) {\n return { p: [cell.bottomleft, 0], x: 0, y: 1, o: 0 };\n }\n return { p: [0, cell.lefttop], x: 1, y: 0, o: 1 };\n\n case 20:\n if (cval & Node0) {\n return { p: [cell.topleft, 1], x: 0, y: -1, o: 0 };\n }\n return { p: [0, cell.leftbottom], x: 1, y: 0, o: 0 };\n\n case 21:\n if (cval & Node1) {\n return { p: [0, cell.leftbottom], x: 1, y: 0, o: 0 };\n }\n return { p: [cell.topright, 1], x: 0, y: -1, o: 1 };\n\n case 22:\n if (cval & Node0) {\n return { p: [cell.topleft, 1], x: 0, y: -1, o: 0 };\n }\n return { p: [0, cell.lefttop], x: 1, y: 0, o: 1 };\n\n case 23:\n if (cval & Node1) {\n return { p: [0, cell.lefttop], x: 1, y: 0, o: 1 };\n }\n return { p: [cell.topright, 1], x: 0, y: -1, o: 1 };\n\n default:\n console.log('edge index out of range!');\n console.log(cell);\n break;\n }\n }\n\n return null;\n}\n\nfunction getExitXY(cell, x, y, o) {\n let e;\n let id_x;\n var x;\n var y;\n let d_x;\n let d_y;\n let { cval } = cell;\n let d_o;\n\n switch (x) {\n case -1:\n switch (o) {\n case 0:\n e = isoBandEdgeRB[cval];\n d_x = isoBandNextXRB[cval];\n d_y = isoBandNextYRB[cval];\n d_o = isoBandNextORB[cval];\n break;\n default:\n e = isoBandEdgeRT[cval];\n d_x = isoBandNextXRT[cval];\n d_y = isoBandNextYRT[cval];\n d_o = isoBandNextORT[cval];\n break;\n }\n break;\n case 1:\n switch (o) {\n case 0:\n e = isoBandEdgeLB[cval];\n d_x = isoBandNextXLB[cval];\n d_y = isoBandNextYLB[cval];\n d_o = isoBandNextOLB[cval];\n break;\n default:\n e = isoBandEdgeLT[cval];\n d_x = isoBandNextXLT[cval];\n d_y = isoBandNextYLT[cval];\n d_o = isoBandNextOLT[cval];\n break;\n }\n break;\n default:\n switch (y) {\n case -1:\n switch (o) {\n case 0:\n e = isoBandEdgeTL[cval];\n d_x = isoBandNextXTL[cval];\n d_y = isoBandNextYTL[cval];\n d_o = isoBandNextOTL[cval];\n break;\n default:\n e = isoBandEdgeTR[cval];\n d_x = isoBandNextXTR[cval];\n d_y = isoBandNextYTR[cval];\n d_o = isoBandNextOTR[cval];\n break;\n }\n break;\n case 1:\n switch (o) {\n case 0:\n e = isoBandEdgeBL[cval];\n d_x = isoBandNextXBL[cval];\n d_y = isoBandNextYBL[cval];\n d_o = isoBandNextOBL[cval];\n break;\n default:\n e = isoBandEdgeBR[cval];\n d_x = isoBandNextXBR[cval];\n d_y = isoBandNextYBR[cval];\n d_o = isoBandNextOBR[cval];\n break;\n }\n break;\n default:\n break;\n }\n break;\n }\n\n id_x = cell.edges.indexOf(e);\n if (typeof cell.edges[id_x] !== 'undefined') {\n deleteEdge(cell, id_x);\n } else {\n // console.log(\"wrong edges...\");\n // console.log(x + \" \" + y + \" \" + o);\n // console.log(cell);\n return null;\n }\n\n cval = cell.cval_real;\n\n switch (e) {\n case 0:\n if (cval & Node1) {\n /* node 1 within range */\n x = cell.topleft;\n y = 1;\n } else {\n /* node 1 below or above threshold */\n x = 1;\n y = cell.righttop;\n }\n break;\n case 1:\n if (cval & Node2) {\n x = 1;\n y = cell.rightbottom;\n } else {\n x = cell.topleft;\n y = 1;\n }\n break;\n case 2:\n if (cval & Node2) {\n x = cell.topleft;\n y = 1;\n } else {\n x = cell.bottomright;\n y = 0;\n }\n break;\n case 3:\n if (cval & Node3) {\n x = cell.bottomleft;\n y = 0;\n } else {\n x = cell.topleft;\n y = 1;\n }\n break;\n case 4:\n if (cval & Node1) {\n x = cell.topright;\n y = 1;\n } else {\n x = 1;\n y = cell.righttop;\n }\n break;\n case 5:\n if (cval & Node2) {\n x = 1;\n y = cell.rightbottom;\n } else {\n x = cell.topright;\n y = 1;\n }\n break;\n case 6:\n if (cval & Node2) {\n x = cell.topright;\n y = 1;\n } else {\n x = cell.bottomright;\n y = 0;\n }\n break;\n case 7:\n if (cval & Node3) {\n x = cell.bottomleft;\n y = 0;\n } else {\n x = cell.topright;\n y = 1;\n }\n break;\n case 8:\n if (cval & Node2) {\n x = 1;\n y = cell.righttop;\n } else {\n x = cell.bottomright;\n y = 0;\n }\n break;\n case 9:\n if (cval & Node3) {\n x = cell.bottomleft;\n y = 0;\n } else {\n x = 1;\n y = cell.righttop;\n }\n break;\n case 10:\n if (cval & Node3) {\n x = 1;\n y = cell.righttop;\n } else {\n x = 0;\n y = cell.leftbottom;\n }\n break;\n case 11:\n if (cval & Node0) {\n x = 0;\n y = cell.lefttop;\n } else {\n x = 1;\n y = cell.righttop;\n }\n break;\n case 12:\n if (cval & Node2) {\n x = 1;\n y = cell.rightbottom;\n } else {\n x = cell.bottomright;\n y = 0;\n }\n break;\n case 13:\n if (cval & Node3) {\n x = cell.bottomleft;\n y = 0;\n } else {\n x = 1;\n y = cell.rightbottom;\n }\n break;\n case 14:\n if (cval & Node3) {\n x = 1;\n y = cell.rightbottom;\n } else {\n x = 0;\n y = cell.leftbottom;\n }\n break;\n case 15:\n if (cval & Node0) {\n x = 0;\n y = cell.lefttop;\n } else {\n x = 1;\n y = cell.rightbottom;\n }\n break;\n case 16:\n if (cval & Node2) {\n x = 0;\n y = cell.leftbottom;\n } else {\n x = cell.bottomright;\n y = 0;\n }\n break;\n case 17:\n if (cval & Node0) {\n x = 0;\n y = cell.lefttop;\n } else {\n x = cell.bottomright;\n y = 0;\n }\n break;\n case 18:\n if (cval & Node3) {\n x = cell.bottomleft;\n y = 0;\n } else {\n x = 0;\n y = cell.leftbottom;\n }\n break;\n case 19:\n if (cval & Node0) {\n x = 0;\n y = cell.lefttop;\n } else {\n x = cell.bottomleft;\n y = 0;\n }\n break;\n case 20:\n if (cval & Node0) {\n x = 0;\n y = cell.leftbottom;\n } else {\n x = cell.topleft;\n y = 1;\n }\n break;\n case 21:\n if (cval & Node1) {\n x = cell.topright;\n y = 1;\n } else {\n x = 0;\n y = cell.leftbottom;\n }\n break;\n case 22:\n if (cval & Node0) {\n x = 0;\n y = cell.lefttop;\n } else {\n x = cell.topleft;\n y = 1;\n }\n break;\n case 23:\n if (cval & Node1) {\n x = cell.topright;\n y = 1;\n } else {\n x = 0;\n y = cell.lefttop;\n }\n break;\n default:\n console.log('edge index out of range!');\n console.log(cell);\n return null;\n }\n\n if (\n typeof x === 'undefined' ||\n typeof y === 'undefined' ||\n typeof d_x === 'undefined' ||\n typeof d_y === 'undefined' ||\n typeof d_o === 'undefined'\n ) {\n console.log('undefined value!');\n console.log(cell);\n console.log(`${x} ${y} ${d_x} ${d_y} ${d_o}`);\n }\n return { p: [x, y], x: d_x, y: d_y, o: d_o };\n}\n\n/*\nfunction BandGrid2Areas(grid){\n var areas = [];\n var area_idx = 0;\n var rows = grid.rows;\n var cols = grid.cols;\n\n grid.cells.forEach(function(g, j){\n g.forEach(function(gg, i){\n if(typeof gg !== 'undefined'){\n var a = polygon_table[gg.cval](gg);\n if((typeof a === 'object') && isArray(a)){\n if((typeof a[0] === 'object') && isArray(a[0])){\n if((typeof a[0][0] === 'object') && isArray(a[0][0])){\n a.forEach(function(aa,k){\n aa.forEach(function(aaa){\n aaa[0] += i;\n aaa[1] += j;\n });\n areas[area_idx++] = aa;\n });\n } else {\n\n a.forEach(function(aa,k){\n aa[0] += i;\n aa[1] += j;\n });\n areas[area_idx++] = a;\n }\n } else {\n console.log(\"bandcell polygon with malformed coordinates\");\n }\n } else {\n console.log(\"bandcell polygon with null coordinates\");\n }\n }\n });\n });\n\n return areas;\n} */\n\nexport const isolines = function (data, lonlatGrid, geotransform, intervals, shape = null) {\n const lines = { type: 'FeatureCollection', features: [] };\n for (let i = 0; i < intervals.length; i++) {\n const value = intervals[i];\n const coords = projectedIsoline(data, lonlatGrid, geotransform, value, shape);\n\n lines.features.push({\n type: 'Feature',\n geometry: {\n type: 'MultiLineString',\n coordinates: coords,\n },\n properties: [{ value }],\n });\n }\n\n return lines;\n};\n\nfunction resolveDims(shape, lonlatGrid) {\n if (\n Array.isArray(shape) &&\n Number.isFinite(shape[0]) &&\n Number.isFinite(shape[1]) &&\n shape[0] > 1 &&\n shape[1] > 1\n ) {\n return [Math.floor(shape[0]), Math.floor(shape[1])];\n }\n\n if (\n Array.isArray(lonlatGrid) &&\n lonlatGrid.length > 1 &&\n Array.isArray(lonlatGrid[0]) &&\n Array.isArray(lonlatGrid[0][0]) &&\n lonlatGrid[0].length > 1\n ) {\n return [lonlatGrid.length, lonlatGrid[0].length];\n }\n\n return null;\n}\n\nexport const projectedIsoline = function (data, lonlatGrid, geotransform, value, shape = null) {\n const dims = resolveDims(shape, lonlatGrid);\n if (!dims) {\n return [];\n }\n\n const expectedLength = dims[0] * dims[1];\n if (!data || data.length < expectedLength || !lonlatGrid || lonlatGrid.length < expectedLength) {\n return [];\n }\n\n const coords = isoline(data, value, dims);\n for (let i = 0; i < coords.length; i++) {\n for (let j = 0; j < coords[i].length; j++) {\n const coordsGeo = applyGeoTransform$1(\n coords[i][j][0],\n coords[i][j][1],\n lonlatGrid,\n geotransform,\n dims,\n );\n coords[i][j][0] = coordsGeo[0];\n coords[i][j][1] = coordsGeo[1];\n }\n }\n\n return coords;\n};\n\n/**\n Xgeo = GT(0) + Xpixel*GT(1) + Yline*GT(2)\n Ygeo = GT(3) + Xpixel*GT(4) + Yline*GT(5)\n*/\nfunction getLonLatAt(lonlatGrid, dims, row, col) {\n const [rows, cols] = dims;\n if (row < 0 || row >= rows || col < 0 || col >= cols) {\n return null;\n }\n\n if (\n Array.isArray(lonlatGrid) &&\n lonlatGrid.length > 0 &&\n Array.isArray(lonlatGrid[0]) &&\n Array.isArray(lonlatGrid[0][0])\n ) {\n return lonlatGrid[row]?.[col] || null;\n }\n\n const idx = row * cols + col;\n return lonlatGrid?.[idx] || null;\n}\n\nvar applyGeoTransform$1 = function (i, j, lonlatGrid, geotransform, dims) {\n if (geotransform) {\n var xgeo = geotransform[0] + i * geotransform[1] + j * geotransform[2];\n var ygeo = geotransform[3] + i * geotransform[4] + j * geotransform[5];\n } else {\n if (!dims) {\n return [NaN, NaN];\n }\n\n const [rows, cols] = dims;\n const i_f = Math.floor(i);\n const i_c = Math.ceil(i);\n const j_f = Math.floor(j);\n const j_c = Math.ceil(j);\n\n const i_f_c = Math.max(0, Math.min(cols - 1, i_f));\n const i_c_c = Math.max(0, Math.min(cols - 1, i_c));\n const j_f_c = Math.max(0, Math.min(rows - 1, j_f));\n const j_c_c = Math.max(0, Math.min(rows - 1, j_c));\n\n // p3-----p4\n // |------|\n // p1-----p2\n\n const p1 = getLonLatAt(lonlatGrid, dims, j_c_c, i_f_c);\n const p2 = getLonLatAt(lonlatGrid, dims, j_c_c, i_c_c);\n const p3 = getLonLatAt(lonlatGrid, dims, j_f_c, i_f_c);\n const p4 = getLonLatAt(lonlatGrid, dims, j_f_c, i_c_c);\n\n if (\n !p1 ||\n !p2 ||\n !p3 ||\n !p4 ||\n !Number.isFinite(p1[0]) ||\n !Number.isFinite(p1[1]) ||\n !Number.isFinite(p2[0]) ||\n !Number.isFinite(p2[1]) ||\n !Number.isFinite(p3[0]) ||\n !Number.isFinite(p3[1]) ||\n !Number.isFinite(p4[0]) ||\n !Number.isFinite(p4[1])\n ) {\n return [NaN, NaN];\n }\n\n const i_w = 1 - (i - i_f);\n const i_w2 = 1 - i_w;\n const j_w = 1 - (j - j_f);\n const j_w2 = 1 - j_w;\n\n var xgeo =\n p3[0] * i_w * j_w + p1[0] * i_w * j_w2 + p4[0] * i_w2 * j_w + p2[0] * i_w2 * j_w2;\n\n var ygeo =\n p3[1] * i_w * j_w + p1[1] * i_w * j_w2 + p4[1] * i_w2 * j_w + p2[1] * i_w2 * j_w2;\n }\n\n return [xgeo, ygeo];\n};\n\nexport const isoline = function (data, threshold, dims, options) {\n const defaultSettings = {\n successCallback: null,\n progressCallback: null,\n verbose: false,\n };\n\n const settings = {};\n\n /* process options */\n options = options || {};\n\n const optionKeys = Object.keys(defaultSettings);\n\n for (let i = 0; i < optionKeys.length; i++) {\n const key = optionKeys[i];\n let val = options[key];\n val = typeof val !== 'undefined' && val !== null ? val : defaultSettings[key];\n\n settings[key] = val;\n }\n\n if (settings.verbose) console.log(`computing isocontour for ${threshold}`);\n const ret = ContourGrid2Paths(computeContourGrid(data, threshold, dims));\n // console.log(\"RET\",ret,threshold,data)\n\n if (typeof settings.successCallback === 'function') settings.successCallback(ret);\n\n return ret;\n};\n\n/*\n Thats all for the public interface, below follows the actual\n implementation\n*/\n\n/*\n################################\nIsocontour implementation below\n################################\n*/\n\n/* assume that x1 == 1 && x0 == 0 */\nfunction interpolateX$1(y, y0, y1) {\n return (y - y0) / (y1 - y0);\n}\n\nfunction ijToIdx(i, j, width) {\n return j * width + i;\n}\n\n/* compute the isocontour 4-bit grid */\nfunction computeContourGrid(data, threshold, dims) {\n const rows = dims[0] - 1;\n const cols = dims[1] - 1;\n const ContourGrid = { rows, cols, cells: [] };\n\n for (let j = 0; j < rows; ++j) {\n ContourGrid.cells[j] = [];\n for (let i = 0; i < cols; ++i) {\n /* compose the 4-bit corner representation */\n let cval = 0;\n\n const tl = data[ijToIdx(i, j + 1, dims[1])];\n const tr = data[ijToIdx(i + 1, j + 1, dims[1])];\n const br = data[ijToIdx(i + 1, j, dims[1])];\n const bl = data[ijToIdx(i, j, dims[1])];\n\n if (isNaN(tl) || isNaN(tr) || isNaN(br) || isNaN(bl)) {\n continue;\n }\n cval |= tl >= threshold ? 8 : 0;\n cval |= tr >= threshold ? 4 : 0;\n cval |= br >= threshold ? 2 : 0;\n cval |= bl >= threshold ? 1 : 0;\n\n /* resolve ambiguity for cval == 5 || 10 via averaging */\n let flipped = false;\n if (cval == 5 || cval == 10) {\n const average = (tl + tr + br + bl) / 4;\n if (cval == 5 && average < threshold) {\n cval = 10;\n flipped = true;\n } else if (cval == 10 && average < threshold) {\n cval = 5;\n flipped = true;\n }\n }\n\n /* add cell to ContourGrid if it contains edges */\n if (cval !== 0 && cval !== 15) {\n var top;\n var bottom;\n var left;\n var right;\n top = bottom = left = right = 0.5;\n /* interpolate edges of cell */\n if (cval == 1) {\n left = 1 - interpolateX$1(threshold, tl, bl);\n bottom = 1 - interpolateX$1(threshold, br, bl);\n } else if (cval == 2) {\n bottom = interpolateX$1(threshold, bl, br);\n right = 1 - interpolateX$1(threshold, tr, br);\n } else if (cval == 3) {\n left = 1 - interpolateX$1(threshold, tl, bl);\n right = 1 - interpolateX$1(threshold, tr, br);\n } else if (cval == 4) {\n top = interpolateX$1(threshold, tl, tr);\n right = interpolateX$1(threshold, br, tr);\n } else if (cval == 5) {\n top = interpolateX$1(threshold, tl, tr);\n right = interpolateX$1(threshold, br, tr);\n bottom = 1 - interpolateX$1(threshold, br, bl);\n left = 1 - interpolateX$1(threshold, tl, bl);\n } else if (cval == 6) {\n bottom = interpolateX$1(threshold, bl, br);\n top = interpolateX$1(threshold, tl, tr);\n } else if (cval == 7) {\n left = 1 - interpolateX$1(threshold, tl, bl);\n top = interpolateX$1(threshold, tl, tr);\n } else if (cval == 8) {\n left = interpolateX$1(threshold, bl, tl);\n top = 1 - interpolateX$1(threshold, tr, tl);\n } else if (cval == 9) {\n bottom = 1 - interpolateX$1(threshold, br, bl);\n top = 1 - interpolateX$1(threshold, tr, tl);\n } else if (cval == 10) {\n top = 1 - interpolateX$1(threshold, tr, tl);\n right = 1 - interpolateX$1(threshold, tr, br);\n bottom = interpolateX$1(threshold, bl, br);\n left = interpolateX$1(threshold, bl, tl);\n } else if (cval == 11) {\n top = 1 - interpolateX$1(threshold, tr, tl);\n right = 1 - interpolateX$1(threshold, tr, br);\n } else if (cval == 12) {\n left = interpolateX$1(threshold, bl, tl);\n right = interpolateX$1(threshold, br, tr);\n } else if (cval == 13) {\n bottom = 1 - interpolateX$1(threshold, br, bl);\n right = interpolateX$1(threshold, br, tr);\n } else if (cval == 14) {\n left = interpolateX$1(threshold, bl, tl);\n bottom = interpolateX$1(threshold, bl, br);\n } else {\n console.log(`Illegal cval detected: ${cval}`);\n }\n ContourGrid.cells[j][i] = {\n cval,\n flipped,\n top,\n right,\n bottom,\n left,\n };\n }\n }\n }\n\n return ContourGrid;\n}\n\nfunction isSaddle(cell) {\n return cell.cval == 5 || cell.cval == 10;\n}\n\nfunction isTrivial(cell) {\n return cell.cval === 0 || cell.cval == 15;\n}\n\nfunction clearCell(cell) {\n if (!isTrivial(cell) && cell.cval != 5 && cell.cval != 10) {\n cell.cval = 15;\n }\n}\n\nfunction getXY(cell, edge) {\n if (edge === 'top') {\n return [cell.top, 1.0];\n }\n if (edge === 'bottom') {\n return [cell.bottom, 0.0];\n }\n if (edge === 'right') {\n return [1.0, cell.right];\n }\n if (edge === 'left') {\n return [0.0, cell.left];\n }\n}\n\nfunction ContourGrid2Paths(grid) {\n const paths = [];\n let path_idx = 0;\n const { rows } = grid;\n const { cols } = grid;\n const epsilon = 1e-7;\n\n grid.cells.forEach((g, j) => {\n g.forEach((gg, i) => {\n if (typeof gg !== 'undefined' && !isSaddle(gg) && !isTrivial(gg)) {\n const p = tracePath(grid.cells, j, i, rows, cols);\n let merged = false;\n /* we may try to merge paths at this point */\n if (p.info == 'mergeable') {\n /*\n search backwards through the path array to find an entry\n that starts with where the current path ends...\n */\n const x = p.path[p.path.length - 1][0];\n const y = p.path[p.path.length - 1][1];\n\n for (let k = path_idx - 1; k >= 0; k--) {\n if (\n Math.abs(paths[k][0][0] - x) <= epsilon &&\n Math.abs(paths[k][0][1] - y) <= epsilon\n ) {\n for (let l = p.path.length - 2; l >= 0; --l) {\n paths[k].unshift(p.path[l]);\n }\n merged = true;\n break;\n }\n }\n }\n if (!merged) paths[path_idx++] = p.path;\n }\n });\n });\n\n return paths;\n}\n\n/*\n construct consecutive line segments from starting cell by\n walking arround the enclosed area clock-wise\n */\nfunction tracePath(grid, j, i, rows, cols) {\n const maxj = grid.length;\n const maxi = grid[0].length;\n const p = [];\n const dxContour = [0, 0, 1, 1, 0, 0, 0, 0, -1, 0, 1, 1, -1, 0, -1, 0];\n const dyContour = [0, -1, 0, 0, 1, 1, 1, 1, 0, -1, 0, 0, 0, -1, 0, 0];\n let dx;\n let dy;\n const startEdge = [\n 'none',\n 'left',\n 'bottom',\n 'left',\n 'right',\n 'none',\n 'bottom',\n 'left',\n 'top',\n 'top',\n 'none',\n 'top',\n 'right',\n 'right',\n 'bottom',\n 'none',\n ];\n const nextEdge = [\n 'none',\n 'bottom',\n 'right',\n 'right',\n 'top',\n 'top',\n 'top',\n 'top',\n 'left',\n 'bottom',\n 'right',\n 'right',\n 'left',\n 'bottom',\n 'left',\n 'none',\n ];\n\n const startCell = grid[j][i];\n let currentCell = grid[j][i];\n\n let { cval } = currentCell;\n let edge = startEdge[cval];\n\n let pt = getXY(currentCell, edge);\n\n /* push initial segment */\n p.push([i + pt[0], j + pt[1]]);\n edge = nextEdge[cval];\n pt = getXY(currentCell, edge);\n p.push([i + pt[0], j + pt[1]]);\n clearCell(currentCell);\n\n /* now walk arround the enclosed area in clockwise-direction */\n let k = i + dxContour[cval];\n let l = j + dyContour[cval];\n let prev_cval = cval;\n\n let count = 0;\n while (k >= 0 && l >= 0 && l < maxj && (k != i || l != j)) {\n currentCell = grid[l][k];\n if (typeof currentCell === 'undefined') {\n /* path ends here */\n // console.log(k + \" \" + l + \" is undefined, stopping path!\");\n break;\n }\n // Added by THW to prevent infinite loops\n if (count > rows * cols) {\n console.log('Infinite loop dectected in Marching Squares. Breaking out', count);\n break;\n }\n cval = currentCell.cval;\n if (cval === 0 || cval === 15) {\n return { path: p, info: 'mergeable' };\n }\n edge = nextEdge[cval];\n dx = dxContour[cval];\n dy = dyContour[cval];\n if (cval == 5 || cval == 10) {\n /* select upper or lower band, depending on previous cells cval */\n if (cval == 5) {\n if (currentCell.flipped) {\n /* this is actually a flipped case 10 */\n if (dyContour[prev_cval] == -1) {\n edge = 'left';\n dx = -1;\n dy = 0;\n } else {\n edge = 'right';\n dx = 1;\n dy = 0;\n }\n } else {\n /* real case 5 */\n if (dxContour[prev_cval] == -1) {\n edge = 'bottom';\n dx = 0;\n dy = -1;\n }\n }\n } else if (cval == 10) {\n if (currentCell.flipped) {\n /* this is actually a flipped case 5 */\n if (dxContour[prev_cval] == -1) {\n edge = 'top';\n dx = 0;\n dy = 1;\n } else {\n edge = 'bottom';\n dx = 0;\n dy = -1;\n }\n } else {\n /* real case 10 */\n if (dyContour[prev_cval] == 1) {\n edge = 'left';\n dx = -1;\n dy = 0;\n }\n }\n }\n }\n pt = getXY(currentCell, edge);\n p.push([k + pt[0], l + pt[1]]);\n clearCell(currentCell);\n k += dx;\n l += dy;\n prev_cval = cval;\n count += 1;\n }\n\n return { path: p, info: 'closed' };\n}\n","/* eslint-disable max-len */\nimport { CompositeLayer } from '@deck.gl/core';\nimport gUtilities from '../../utilities/graphicsUtilities';\nimport { ContourLabels } from './contourLabels';\nimport { getColors } from '../../maps/legend/legendHelperFunctions';\nimport PathLayer from '../pathLayer/WizardPathLayer';\nimport triangleContours from './triangleContours';\nimport { isolines } from './raster-marching-squares';\n\nconst defaultProps = {\n algorithm: 'marchingTriangles',\n elevation: 0,\n pickable: false, // Major performance hit when pickable is true, keep pickable options in the base layer\n widthScale: 30,\n widthMinPixels: 2,\n getWidth: 10,\n // properties to make globe projection work without bleed\n parameters: {\n depthCompare: 'always',\n cullMode: 'back',\n },\n};\n\nfunction normalizeContourColors(colors) {\n if (Array.isArray(colors) && colors.length === 1) {\n return colors[0];\n }\n return colors;\n}\n\nfunction flattenLonLatGrid(lonlatGrid) {\n if (\n Array.isArray(lonlatGrid) &&\n lonlatGrid.length > 0 &&\n Array.isArray(lonlatGrid[0]) &&\n Array.isArray(lonlatGrid[0][0])\n ) {\n const points = [];\n for (let r = 0; r < lonlatGrid.length; r += 1) {\n for (let c = 0; c < lonlatGrid[r].length; c += 1) {\n points.push(lonlatGrid[r][c]);\n }\n }\n return points;\n }\n return lonlatGrid || [];\n}\n\nfunction contourLines(lonlatGrid, values, levels, algorithm, shape) {\n const points = flattenLonLatGrid(lonlatGrid);\n const contourLevels = (levels || []).filter((level) => Number.isFinite(level));\n if (points.length < 3 || contourLevels.length === 0) {\n return { type: 'FeatureCollection', features: [] };\n }\n\n if (algorithm === 'marchingSquares') {\n console.log('ContourLayer method: marchingSquares');\n return isolines(values, lonlatGrid, undefined, contourLevels, shape);\n }\n\n console.log('ContourLayer method: marchingTriangles (delaunay)');\n return triangleContours(lonlatGrid, values, contourLevels, shape);\n}\n\nexport default class ContourLayer extends CompositeLayer {\n initializeState() {\n this.state = {};\n }\n\n // eslint-disable-next-line class-methods-use-this\n shouldUpdateState({ changeFlags }) {\n return changeFlags.propsOrDataChanged;\n }\n\n // { props, oldProps, changeFlags }\n updateState({ props }) {\n // Get colors, set contour Levels\n const isoLines = [];\n const colorscale = getColors(\n props.colorLevels,\n normalizeContourColors(props.colors),\n props.colorType,\n );\n const contourLevels = props.contourLevels || props.colorLevels;\n const t0 = performance.now();\n\n // Get isolines\n let { lines } = props;\n if (!lines) {\n const lonlatGrid = props.lonlatGrid || props.projection?.lonlatGrid;\n lines = contourLines(\n lonlatGrid,\n props.data,\n contourLevels,\n props.algorithm,\n props.shape,\n );\n }\n\n // Color isolines\n lines.features.forEach((d, i) => {\n const polygons = d.geometry.coordinates;\n if (polygons.length === 0) {\n return;\n } // there is nothing to plot, continue to next band\n const contourValue = d?.properties?.[0]?.value;\n const colorValue = Number.isFinite(contourValue) ? contourValue : contourLevels[i];\n const color = gUtilities.string_to_rgb(colorscale(colorValue));\n\n const p = new Array(polygons.length);\n for (let j = 0; j < polygons.length; j += 1) {\n p[j] = new Array(polygons[j].length);\n for (let k = 0; k < polygons[j].length; k += 1) {\n p[j][k] = [polygons[j][k][0], polygons[j][k][1], props.elevation];\n }\n }\n for (const polygon of p) {\n isoLines.push({\n polygon,\n color,\n });\n }\n });\n\n console.log('contour layer: isolines calculated in ', performance.now() - t0, 'ms');\n\n this.setState({\n lines,\n isoLines,\n });\n }\n\n renderLayers() {\n const { isoLines, lines } = this.state;\n\n const contourLayer = new PathLayer(this.props, {\n positionFormat: 'XYZ',\n getPath: (d) => d.polygon,\n getColor: (d) => d.color,\n id: `${this.props.id}-path`,\n data: isoLines,\n });\n\n let contourLabels;\n if (this.props.labels?.enabled) {\n contourLabels = new ContourLabels({\n ...this.props.labels,\n id: `${this.props.id}-labels`,\n lines,\n });\n }\n\n return [contourLayer, contourLabels];\n }\n}\n\nContourLayer.layerName = 'ContourLayer';\nContourLayer.defaultProps = defaultProps;\n\nexport { ContourLayer };\n","// deck.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\n/* eslint-disable max-params */\nimport earcut from 'earcut';\nimport {modifyPolygonWindingDirection, WINDING} from '@math.gl/polygon';\n\nimport type {Position} from '@deck.gl/core';\nimport type {NumericArray} from '@math.gl/core';\n\nconst OUTER_POLYGON_WINDING = WINDING.CLOCKWISE;\nconst HOLE_POLYGON_WINDING = WINDING.COUNTER_CLOCKWISE;\n\ntype WindingOptions = {\n start?: number;\n end?: number;\n size?: number;\n isClosed?: boolean;\n};\n\n/** A scratch object for sending winding options */\nconst windingOptions: WindingOptions = {\n isClosed: true\n};\n\n// 4 data formats are supported:\n\n/** Simple Polygon: an array of points */\nexport type NestedSimplePolygonGeometry = Position[];\n/** Complex Polygon: an array of array of points (array of rings)\n * with the first ring representing the outer hull and other rings representing holes\n */\nexport type NestedComplexPolygonGeometry = Position[][];\n/** An array of numbers (flattened \"simple polygon\") */\nexport type FlatSimplePolygonGeometry = NumericArray;\n/** Flattened \"complex polygon\" */\nexport type FlatComplexPolygonGeometry = {positions: NumericArray; holeIndices: NumericArray};\n\nexport type PolygonGeometry =\n | NestedSimplePolygonGeometry\n | NestedComplexPolygonGeometry\n | FlatSimplePolygonGeometry\n | FlatComplexPolygonGeometry;\n\nexport type NormalizedPolygonGeometry = FlatSimplePolygonGeometry | FlatComplexPolygonGeometry;\n\n/**\n * Ensure a polygon is valid format\n */\nfunction validate(polygon: PolygonGeometry): void {\n polygon = (polygon && (polygon as FlatComplexPolygonGeometry).positions) || polygon;\n if (!Array.isArray(polygon) && !ArrayBuffer.isView(polygon)) {\n throw new Error('invalid polygon');\n }\n}\n\n/** Get the positions from a normalized polygon */\nexport function getPositions(polygon: NormalizedPolygonGeometry): NumericArray {\n return 'positions' in polygon ? polygon.positions : polygon;\n}\n\n/** Get the hole indices from a normalized polygon */\nexport function getHoleIndices(polygon: NormalizedPolygonGeometry): NumericArray | null {\n return 'holeIndices' in polygon ? polygon.holeIndices : null;\n}\n\n/**\n * Check if a polygon is nested or flat\n * Returns true if the polygon is a flat polygon (i.e. not an array of polygons)\n */\nfunction isNested(\n polygon: PolygonGeometry\n): polygon is NestedSimplePolygonGeometry | NestedComplexPolygonGeometry {\n return Array.isArray(polygon[0]);\n}\n\n/**\n * Check if a polygon is simple or complex\n * Returns true if the polygon is a simple polygon (i.e. not an array of polygons)\n */\nfunction isSimple(\n polygon: NestedSimplePolygonGeometry | NestedComplexPolygonGeometry\n): polygon is NestedSimplePolygonGeometry {\n return polygon.length >= 1 && polygon[0].length >= 2 && Number.isFinite(polygon[0][0]);\n}\n\n/**\n * Check if a simple polygon is a closed ring\n * Returns true if the simple polygon is a closed ring\n */\nfunction isNestedRingClosed(simplePolygon: NestedSimplePolygonGeometry): boolean {\n // check if first and last vertex are the same\n const p0 = simplePolygon[0];\n const p1 = simplePolygon[simplePolygon.length - 1];\n\n return p0[0] === p1[0] && p0[1] === p1[1] && p0[2] === p1[2];\n}\n\n/**\n * Check if a simple flat array is a closed ring\n * Returns true if the simple flat array is a closed ring\n */\nfunction isFlatRingClosed(\n positions: FlatSimplePolygonGeometry,\n /** size of a position, 2 (xy) or 3 (xyz) */\n size: number,\n /** start index of the path in the positions array */\n startIndex: number,\n /** end index of the path in the positions array */\n endIndex: number\n): boolean {\n for (let i = 0; i < size; i++) {\n if (positions[startIndex + i] !== positions[endIndex - size + i]) {\n return false;\n }\n }\n return true;\n}\n\n/**\n * Copy a simple polygon coordinates into a flat array, closes the ring if needed.\n * Returns the index of the write head in the destination\n */\nfunction copyNestedRing(\n /** destination */\n target: NumericArray,\n /** index in the destination to start copying into */\n targetStartIndex: number,\n /** the source polygon */\n simplePolygon: NestedSimplePolygonGeometry,\n /** size of a position, 2 (xy) or 3 (xyz) */\n size: number,\n /** modify polygon to be of the specified winding direction */\n windingDirection: number\n): number {\n let targetIndex = targetStartIndex;\n const len = simplePolygon.length;\n for (let i = 0; i < len; i++) {\n for (let j = 0; j < size; j++) {\n target[targetIndex++] = simplePolygon[i][j] || 0;\n }\n }\n\n if (!isNestedRingClosed(simplePolygon)) {\n for (let j = 0; j < size; j++) {\n target[targetIndex++] = simplePolygon[0][j] || 0;\n }\n }\n\n windingOptions.start = targetStartIndex;\n windingOptions.end = targetIndex;\n windingOptions.size = size;\n modifyPolygonWindingDirection(target, windingDirection, windingOptions);\n\n return targetIndex;\n}\n\n/**\n * Copy a simple flat array into another flat array, closes the ring if needed.\n * Returns the index of the write head in the destination\n */\nfunction copyFlatRing(\n /** destination */\n target: NumericArray,\n /** index in the destination to start copying into */\n targetStartIndex: number,\n /** the source polygon */\n positions: FlatSimplePolygonGeometry,\n /** size of a position, 2 (xy) or 3 (xyz) */\n size: number,\n /** start index of the path in the positions array */\n srcStartIndex: number = 0,\n /** end index of the path in the positions array */\n srcEndIndex: number,\n windingDirection: number\n): number {\n srcEndIndex = srcEndIndex || positions.length;\n const srcLength = srcEndIndex - srcStartIndex;\n if (srcLength <= 0) {\n return targetStartIndex;\n }\n let targetIndex = targetStartIndex;\n\n for (let i = 0; i < srcLength; i++) {\n target[targetIndex++] = positions[srcStartIndex + i];\n }\n\n if (!isFlatRingClosed(positions, size, srcStartIndex, srcEndIndex)) {\n for (let i = 0; i < size; i++) {\n target[targetIndex++] = positions[srcStartIndex + i];\n }\n }\n\n windingOptions.start = targetStartIndex;\n windingOptions.end = targetIndex;\n windingOptions.size = size;\n modifyPolygonWindingDirection(target, windingDirection, windingOptions);\n\n return targetIndex;\n}\n\n/**\n * Normalize any polygon representation into the \"complex flat\" format\n */\n/* eslint-disable max-statements */\nexport function normalize(\n polygon: PolygonGeometry,\n positionSize: number\n): NormalizedPolygonGeometry {\n validate(polygon);\n\n const positions: number[] = [];\n const holeIndices: number[] = [];\n\n if ('positions' in polygon) {\n // complex flat\n const {positions: srcPositions, holeIndices: srcHoleIndices} = polygon;\n\n if (srcHoleIndices) {\n let targetIndex = 0;\n // split the positions array into `holeIndices.length + 1` rings\n // holeIndices[-1] falls back to 0\n // holeIndices[holeIndices.length] falls back to positions.length\n for (let i = 0; i <= srcHoleIndices.length; i++) {\n targetIndex = copyFlatRing(\n positions,\n targetIndex,\n srcPositions,\n positionSize,\n srcHoleIndices[i - 1],\n srcHoleIndices[i],\n i === 0 ? OUTER_POLYGON_WINDING : HOLE_POLYGON_WINDING\n );\n holeIndices.push(targetIndex);\n }\n // The last one is not a starting index of a hole, remove\n holeIndices.pop();\n\n return {positions, holeIndices};\n }\n polygon = srcPositions;\n }\n if (!isNested(polygon)) {\n // simple flat\n copyFlatRing(positions, 0, polygon, positionSize, 0, positions.length, OUTER_POLYGON_WINDING);\n return positions;\n }\n if (!isSimple(polygon)) {\n // complex polygon\n let targetIndex = 0;\n\n for (const [polygonIndex, simplePolygon] of polygon.entries()) {\n targetIndex = copyNestedRing(\n positions,\n targetIndex,\n simplePolygon,\n positionSize,\n polygonIndex === 0 ? OUTER_POLYGON_WINDING : HOLE_POLYGON_WINDING\n );\n holeIndices.push(targetIndex);\n }\n // The last one is not a starting index of a hole, remove\n holeIndices.pop();\n // last index points to the end of the array, remove it\n return {positions, holeIndices};\n }\n // simple polygon\n copyNestedRing(positions, 0, polygon, positionSize, OUTER_POLYGON_WINDING);\n return positions;\n}\n/* eslint-enable max-statements */\n\n/*\n * Calculate the area of a single plane of the polygon\n */\nfunction getPlaneArea(positions: NumericArray, xIndex: number, yIndex: number): number {\n const numVerts = positions.length / 3;\n let area = 0;\n for (let i = 0; i < numVerts; i++) {\n const j = (i + 1) % numVerts;\n area += positions[i * 3 + xIndex] * positions[j * 3 + yIndex];\n area -= positions[j * 3 + xIndex] * positions[i * 3 + yIndex];\n }\n return Math.abs(area / 2);\n}\n\nfunction permutePositions(positions: NumericArray, xIndex: number, yIndex: number, zIndex: number) {\n const numVerts = positions.length / 3;\n for (let i = 0; i < numVerts; i++) {\n const o = i * 3;\n\n const x = positions[o + 0];\n const y = positions[o + 1];\n const z = positions[o + 2];\n\n positions[o + xIndex] = x;\n positions[o + yIndex] = y;\n positions[o + zIndex] = z;\n }\n}\n\n/**\n * Get vertex indices for drawing polygon mesh (triangulation)\n */\n// eslint-disable-next-line complexity, max-statements\nexport function getSurfaceIndices(\n polygon: NormalizedPolygonGeometry,\n positionSize: number,\n preproject?: (xy: number[]) => number[],\n full3d?: boolean\n): number[] {\n let holeIndices = getHoleIndices(polygon);\n if (holeIndices) {\n holeIndices = holeIndices.map(positionIndex => positionIndex / positionSize);\n }\n\n let positions = getPositions(polygon);\n\n const is3d = full3d && positionSize === 3;\n\n if (preproject) {\n // When tesselating lnglat coordinates, project them to the common space for accuracy\n const n = positions.length;\n\n // Clone the array\n positions = positions.slice();\n\n const p: number[] = [];\n for (let i = 0; i < n; i += positionSize) {\n p[0] = positions[i];\n p[1] = positions[i + 1];\n\n if (is3d) {\n p[2] = positions[i + 2];\n }\n\n const xy = preproject(p);\n\n positions[i] = xy[0];\n positions[i + 1] = xy[1];\n\n if (is3d) {\n positions[i + 2] = xy[2];\n }\n }\n }\n\n if (is3d) {\n // calculate plane with largest area\n const xyArea = getPlaneArea(positions, 0, 1);\n const xzArea = getPlaneArea(positions, 0, 2);\n const yzArea = getPlaneArea(positions, 1, 2);\n\n if (!xyArea && !xzArea && !yzArea) {\n return []; // no planes have area, nothing we can do\n }\n\n // permute positions to make the largest plane xy for earcut\n if (xyArea > xzArea && xyArea > yzArea) {\n // xy plane largest, nothing to do\n } else if (xzArea > yzArea) {\n // xz plane largest, permute to make xyz -> xzy\n if (!preproject) {\n positions = positions.slice();\n }\n permutePositions(positions, 0, 2, 1);\n } else {\n // yz plane largest, permute to make xyz -> yzx\n if (!preproject) {\n positions = positions.slice();\n }\n permutePositions(positions, 2, 0, 1);\n }\n }\n\n // Let earcut triangulate the polygon\n return earcut(positions, holeIndices, positionSize);\n}\n","// deck.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\n// Handles tesselation of polygons with holes\n// - 2D surfaces\n// - 2D outlines\n// - 3D surfaces (top and sides only)\n// - 3D wireframes (not yet)\nimport * as Polygon from './polygon';\nimport { Tesselator } from '@deck.gl/core';\nimport { cutPolygonByGrid, cutPolygonByMercatorBounds } from '@math.gl/polygon';\n\nimport type {\n PolygonGeometry,\n NormalizedPolygonGeometry,\n FlatComplexPolygonGeometry,\n} from './polygon';\nimport type { TypedArray } from '@math.gl/core';\n\ntype GeometryUpdateContext = {\n vertexStart: number;\n indexStart: number;\n geometrySize: number;\n geometryIndex: number;\n};\n\ntype CutPolygon = FlatComplexPolygonGeometry & {\n edgeTypes: number[];\n};\n\n// This class is set up to allow querying one attribute at a time\n// the way the AttributeManager expects it\nexport default class PolygonTesselator extends Tesselator<\n PolygonGeometry,\n NormalizedPolygonGeometry | CutPolygon[],\n {\n fp64?: boolean;\n IndexType?: Uint32ArrayConstructor | Uint16ArrayConstructor;\n resolution?: number;\n wrapLongitude?: boolean;\n preproject?: (xy: number[]) => number[];\n full3d?: boolean;\n }\n> {\n constructor(opts) {\n const { fp64, IndexType = Uint32Array } = opts;\n super({\n ...opts,\n attributes: {\n positions: { size: 3, type: fp64 ? Float64Array : Float32Array },\n vertexValid: { type: Uint16Array, size: 1 },\n indices: { type: IndexType, size: 1 },\n },\n });\n }\n\n /** Get attribute by name */\n get(attributeName: string): TypedArray | null {\n const { attributes } = this;\n if (attributeName === 'indices') {\n return attributes.indices && attributes.indices.subarray(0, this.vertexCount);\n }\n\n return attributes[attributeName];\n }\n\n /** Override base Tesselator method */\n updateGeometry(opts) {\n super.updateGeometry(opts);\n\n const externalIndices = this.buffers.indices;\n if (externalIndices) {\n // @ts-ignore (2339) value is not defined on TypedArray (fall through)\n this.vertexCount = (externalIndices.value || externalIndices).length;\n } else if (this.data && !this.getGeometry) {\n throw new Error('missing indices buffer');\n }\n }\n\n /** Implement base Tesselator interface */\n protected normalizeGeometry(\n polygon: PolygonGeometry,\n ): NormalizedPolygonGeometry | CutPolygon[] {\n if (this.normalize) {\n const normalizedPolygon = Polygon.normalize(polygon, this.positionSize);\n if (this.opts.resolution) {\n return cutPolygonByGrid(\n Polygon.getPositions(normalizedPolygon),\n Polygon.getHoleIndices(normalizedPolygon),\n {\n size: this.positionSize,\n gridResolution: this.opts.resolution,\n edgeTypes: true,\n },\n ) as CutPolygon[];\n }\n if (this.opts.wrapLongitude) {\n return cutPolygonByMercatorBounds(\n Polygon.getPositions(normalizedPolygon),\n Polygon.getHoleIndices(normalizedPolygon),\n {\n size: this.positionSize,\n maxLatitude: 86,\n edgeTypes: true,\n },\n ) as CutPolygon[];\n }\n return normalizedPolygon;\n }\n // normalize is explicitly set to false, assume that user passed in already normalized polygons\n return polygon as NormalizedPolygonGeometry;\n }\n\n /** Implement base Tesselator interface */\n protected getGeometrySize(polygon: NormalizedPolygonGeometry | CutPolygon[]): number {\n if (isCut(polygon)) {\n let size = 0;\n for (const subPolygon of polygon) {\n size += this.getGeometrySize(subPolygon);\n }\n return size;\n }\n return Polygon.getPositions(polygon).length / this.positionSize;\n }\n\n /** Override base Tesselator method */\n protected getGeometryFromBuffer(buffer) {\n if (this.normalize || !this.buffers.indices) {\n return super.getGeometryFromBuffer(buffer);\n }\n // we don't need to read the positions if no normalization/tesselation\n return null;\n }\n\n /** Implement base Tesselator interface */\n protected updateGeometryAttributes(\n polygon: NormalizedPolygonGeometry | CutPolygon[] | null,\n context: GeometryUpdateContext,\n ) {\n if (polygon && isCut(polygon)) {\n for (const subPolygon of polygon) {\n const geometrySize = this.getGeometrySize(subPolygon);\n context.geometrySize = geometrySize;\n this.updateGeometryAttributes(subPolygon, context);\n context.vertexStart += geometrySize;\n context.indexStart = this.indexStarts[context.geometryIndex + 1];\n }\n } else {\n const normalizedPolygon = polygon as NormalizedPolygonGeometry;\n this._updateIndices(normalizedPolygon, context);\n this._updatePositions(normalizedPolygon, context);\n this._updateVertexValid(normalizedPolygon, context);\n }\n }\n\n // Flatten the indices array\n private _updateIndices(\n polygon: NormalizedPolygonGeometry | null,\n { geometryIndex, vertexStart: offset, indexStart }: GeometryUpdateContext,\n ) {\n const { attributes, indexStarts, typedArrayManager } = this;\n\n let target = attributes.indices;\n if (!target || !polygon) {\n return;\n }\n let i = indexStart;\n const trianglesIndices = this.data.attributes?.getTriangleIndices;\n\n // If indices are provided\n if (trianglesIndices) {\n indexStarts[geometryIndex + 1] = indexStart + trianglesIndices.value.length; // triangleLength;\n attributes.indices = trianglesIndices.value;\n } else {\n // 1. get triangulated indices for the internal areas\n const indices = Polygon.getSurfaceIndices(\n polygon,\n this.positionSize,\n this.opts.preproject,\n this.opts.full3d,\n );\n\n // make sure the buffer is large enough\n target = typedArrayManager.allocate(target, indexStart + indices.length, {\n copy: true,\n });\n\n // 2. offset each index by the number of indices in previous polygons\n for (let j = 0; j < indices.length; j++) {\n target[i++] = indices[j] + offset;\n }\n\n indexStarts[geometryIndex + 1] = indexStart + indices.length;\n attributes.indices = target;\n }\n }\n\n // Flatten out all the vertices of all the sub subPolygons\n private _updatePositions(\n polygon: NormalizedPolygonGeometry | null,\n { vertexStart, geometrySize }: GeometryUpdateContext,\n ) {\n const {\n attributes: { positions },\n positionSize,\n } = this;\n if (!positions || !polygon) {\n return;\n }\n const polygonPositions = Polygon.getPositions(polygon);\n\n for (let i = vertexStart, j = 0; j < geometrySize; i++, j++) {\n const x = polygonPositions[j * positionSize];\n const y = polygonPositions[j * positionSize + 1];\n const z = positionSize > 2 ? polygonPositions[j * positionSize + 2] : 0;\n\n positions[i * 3] = x;\n positions[i * 3 + 1] = y;\n positions[i * 3 + 2] = z;\n }\n }\n\n private _updateVertexValid(\n polygon: NormalizedPolygonGeometry | null,\n { vertexStart, geometrySize }: GeometryUpdateContext,\n ) {\n const { positionSize } = this;\n const vertexValid = this.attributes.vertexValid as TypedArray;\n const holeIndices = polygon && Polygon.getHoleIndices(polygon);\n /* We are reusing the some buffer for `nextPositions` by offseting one vertex\n * to the left. As a result,\n * the last vertex of each ring overlaps with the first vertex of the next ring.\n * `vertexValid` is used to mark the end of each ring so we don't draw these\n * segments:\n positions A0 A1 A2 A3 A4 B0 B1 B2 C0 ...\n nextPositions A1 A2 A3 A4 B0 B1 B2 C0 C1 ...\n vertexValid 1 1 1 1 0 1 1 0 1 ...\n */\n if (polygon && (polygon as CutPolygon).edgeTypes) {\n vertexValid.set((polygon as CutPolygon).edgeTypes, vertexStart);\n } else {\n vertexValid.fill(1, vertexStart, vertexStart + geometrySize);\n }\n if (holeIndices) {\n for (let j = 0; j < holeIndices.length; j++) {\n vertexValid[vertexStart + holeIndices[j] / positionSize - 1] = 0;\n }\n }\n vertexValid[vertexStart + geometrySize - 1] = 0;\n }\n}\n\nfunction isCut(polygon: NormalizedPolygonGeometry | CutPolygon[]): polygon is CutPolygon[] {\n return Array.isArray(polygon) && polygon.length > 0 && !Number.isFinite(polygon[0]);\n}\n","// deck.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport type { ShaderModule } from '@luma.gl/shadertools';\n\n// Order matters here, keep everything in order for all variables\n// - If not in same order, variables will not work correctly\n// - THW lost 3 hours of his life to this\nconst uniformBlock = `\\\nuniform solidPolygonUniforms {\n bool extruded;\n bool isWireframe;\n float elevationScale;\n bool hasTexture;\n} solidPolygon;\n`;\n\nexport type SolidPolygonProps = {\n extruded: boolean;\n isWireframe: boolean;\n elevationScale: number;\n hasTexture: boolean;\n};\n\nexport const solidPolygonUniforms = {\n name: 'solidPolygon',\n vs: uniformBlock,\n fs: uniformBlock,\n uniformTypes: {\n extruded: 'f32',\n isWireframe: 'f32',\n elevationScale: 'f32',\n hasTexture: 'f32',\n },\n} as const satisfies ShaderModule<SolidPolygonProps>;\n","// deck.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nexport default `\\\n\nin vec4 fillColors;\nin vec4 lineColors;\nin vec3 pickingColors;\n\nout vec4 vColor;\nout float pdata;\nout float odata;\nout float v1;\nout float v2;\nout float v3;\n\nstruct PolygonProps {\n vec3 positions;\n vec3 positions64Low;\n vec3 normal;\n float elevations;\n float vertex1;\n float vertex2;\n float vertex3;\n float polygondata;\n float opacitydata;\n};\n\nvec3 project_offset_normal(vec3 vector) {\n if (project.coordinateSystem == COORDINATE_SYSTEM_LNGLAT ||\n project.coordinateSystem == COORDINATE_SYSTEM_LNGLAT_OFFSETS) {\n // normals generated by the polygon tesselator are in lnglat offsets instead of meters\n return normalize(vector * project.commonUnitsPerWorldUnit);\n }\n return project_normal(vector);\n}\n\nvoid calculatePosition(PolygonProps props) {\n vec3 pos = props.positions;\n vec3 pos64Low = props.positions64Low;\n vec3 normal = props.normal;\n vec4 colors = solidPolygon.isWireframe ? lineColors : fillColors;\n pdata = props.polygondata;\n odata = props.opacitydata;\n v1 = props.vertex1;\n v2 = props.vertex2;\n v3 = props.vertex3;\n\n\n geometry.worldPosition = props.positions;\n geometry.pickingColor = pickingColors;\n\n if (solidPolygon.extruded) {\n pos.z += props.elevations * solidPolygon.elevationScale;\n }\n gl_Position = project_position_to_clipspace(pos, pos64Low, vec3(0.), geometry.position);\n\n DECKGL_FILTER_GL_POSITION(gl_Position, geometry);\n\n if (solidPolygon.extruded) {\n #ifdef IS_SIDE_VERTEX\n normal = project_offset_normal(normal);\n #else\n normal = project_normal(normal);\n #endif\n geometry.normal = normal;\n vec3 lightColor = lighting_getLightColor(colors.rgb, project.cameraPosition, geometry.position.xyz, geometry.normal);\n vColor = vec4(lightColor, colors.a * layer.opacity);\n } else {\n vColor = vec4(colors.rgb, colors.a * layer.opacity);\n }\n DECKGL_FILTER_COLOR(vColor, geometry);\n}\n`;\n","// deck.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport main from './solid-polygon-layer-vertex-main.glsl';\n\nexport default `\\\n#version 300 es\n#define SHADER_NAME solid-polygon-layer-vertex-shader\n\nin vec3 vertexPositions;\nin vec3 vertexPositions64Low;\nin float elevations;\nin float vertex1;\nin float vertex2;\nin float vertex3;\nin float polygondata;\nin float opacitydata;\n\n${main}\n\nvoid main(void) {\n PolygonProps props;\n\n props.positions = vertexPositions;\n props.positions64Low = vertexPositions64Low;\n props.elevations = elevations;\n props.vertex1 = vertex1;\n props.vertex2 = vertex2;\n props.vertex3 = vertex3;\n props.polygondata = polygondata;\n props.opacitydata = opacitydata;\n props.normal = vec3(0.0, 0.0, 1.0);\n\n calculatePosition(props);\n}\n`;\n","// deck.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport main from './solid-polygon-layer-vertex-main.glsl';\n\nexport default `\\\n#version 300 es\n#define SHADER_NAME solid-polygon-layer-vertex-shader-side\n#define IS_SIDE_VERTEX\n\nin vec2 positions;\n\nin vec3 vertexPositions;\nin vec3 nextVertexPositions;\nin vec3 vertexPositions64Low;\nin vec3 nextVertexPositions64Low;\nin float elevations;\nin float vertex1;\nin float vertex2;\nin float vertex3;\nin float polygondata;\nin float opacitydata;\nin float instanceVertexValid;\n\n${main}\n\nvoid main(void) {\n if(instanceVertexValid < 0.5){\n gl_Position = vec4(0.);\n return;\n }\n\n PolygonProps props;\n\n vec3 pos;\n vec3 pos64Low;\n vec3 nextPos;\n vec3 nextPos64Low;\n\n #if RING_WINDING_ORDER_CW == 1\n pos = vertexPositions;\n pos64Low = vertexPositions64Low;\n nextPos = nextVertexPositions;\n nextPos64Low = nextVertexPositions64Low;\n #else\n pos = nextVertexPositions;\n pos64Low = nextVertexPositions64Low;\n nextPos = vertexPositions;\n nextPos64Low = vertexPositions64Low;\n #endif\n\n props.positions = mix(pos, nextPos, positions.x);\n props.positions64Low = mix(pos64Low, nextPos64Low, positions.x);\n\n props.normal = vec3(\n pos.y - nextPos.y + (pos64Low.y - nextPos64Low.y),\n nextPos.x - pos.x + (nextPos64Low.x - pos64Low.x),\n 0.0);\n\n props.elevations = elevations * positions.y;\n\n calculatePosition(props);\n}\n`;\n","// deck.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nexport default `\\\n#version 300 es\n#define SHADER_NAME solid-polygon-layer-fragment-shader\n\nprecision highp float;\n\nin vec4 vColor;\nin float pdata;\nin float odata;\nin float v1;\nin float v2;\nin float v3;\n\nuniform sampler2D sampler;\nout vec4 fragColor;\n\nvoid main(void) {\n fragColor = ( pdata >= 0.0 && pdata <= 1.0 ) ? texture(sampler, vec2(pdata, 0.5)) : vec4(0,0,0,0);\n\n if (odata >= 0.0 && odata <= 1.0) {\n fragColor = vec4(fragColor.rgb, fragColor.a * layer.opacity * odata );\n }\n else {\n fragColor = vec4(fragColor.rgb, fragColor.a * layer.opacity );\n }\n\n\n // Fails to compile on some Android devices if geometry is never assigned (#8411)\n geometry.uv = vec2(0.);\n\n DECKGL_FILTER_COLOR(fragColor, geometry);\n}\n`;\n","// deck.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\n// THW modified deck.gl\n// In the future compare tag v9.1.13 with whatever version you are trying to upgrade\n// - 7/15/2025: updated to deck.gl v9.1.13\n// - ?/?/2024: updated to deck.gl v9.0.33\n\nimport { Layer, project32, picking, COORDINATE_SYSTEM } from '@deck.gl/core';\nimport { Model, Geometry } from '@luma.gl/engine';\nimport { gouraudMaterial } from '@luma.gl/shadertools';\nimport { Texture } from '@luma.gl/core';\n\n// Polygon geometry generation is managed by the polygon tesselator\nimport PolygonTesselator from './polygon-tesselator';\n\nimport { solidPolygonUniforms, SolidPolygonProps } from './solid-polygon-layer-uniforms';\nimport vsTop from './solid-polygon-layer-vertex-top.glsl';\nimport vsSide from './solid-polygon-layer-vertex-side.glsl';\nimport fs from './solid-polygon-layer-fragment.glsl';\n\nimport type {\n LayerProps,\n LayerDataSource,\n Color,\n Material,\n Accessor,\n AccessorFunction,\n UpdateParameters,\n GetPickingInfoParams,\n PickingInfo,\n DefaultProps,\n TextureSource,\n} from '@deck.gl/core';\nimport type { PolygonGeometry } from './polygon';\nimport gUtilities from '../../utilities/graphicsUtilities';\nimport TriangulateGrid from './TriangulateGrid';\n\n// Where all the verticies, indicies, rgbValues, and startIndicies\n// are stored so we only have to caluclate once per model\nconst positions = {};\n\ntype _ShadedLayerProps<DataT> = {\n data: LayerDataSource<DataT>;\n /** Whether to fill the polygons\n * @default true\n */\n filled?: boolean;\n /** Whether to extrude the polygons\n * @default false\n */\n extruded?: boolean;\n /** Whether to generate a line wireframe of the polygon.\n * @default false\n */\n wireframe?: boolean;\n /**\n * (Experimental) If `false`, will skip normalizing the coordinates returned by `getPolygon`.\n * @default false\n */\n _normalize?: boolean;\n /**\n * (Experimental) This prop is only effective with `_normalize: false`.\n * It specifies the winding order of rings in the polygon data, one of 'CW' (clockwise) and 'CCW' (counter-clockwise)\n */\n _windingOrder?: 'CW' | 'CCW';\n\n /**\n * (Experimental) This prop is only effective with `XYZ` data.\n * When true, polygon tesselation will be performed on the plane with the largest area, instead of the xy plane.\n * @default false\n */\n _full3d?: boolean;\n\n /** Elevation multiplier.\n * @default 1\n */\n elevationScale?: number;\n\n /** Polygon geometry accessor. */\n getPolygon?: AccessorFunction<DataT, PolygonGeometry>;\n /** Extrusion height accessor.\n * @default 1000\n */\n getElevation?: Accessor<DataT, number>;\n /** Fill color accessor.\n * @default [0, 0, 0, 255]\n */\n getFillColor?: Accessor<DataT, Color>;\n /** Stroke color accessor.\n * @default [0, 0, 0, 255]\n */\n getLineColor?: Accessor<DataT, Color>;\n\n /** Extrusion height accessor.\n * @default 1\n */\n getPolygonData?: Accessor<DataT, number>;\n /** Extrusion height accessor.\n * @default 1\n */\n getVertex1?: Accessor<DataT, number>;\n /** Extrusion height accessor.\n * @default 1\n */\n getVertex2?: Accessor<DataT, number>;\n /** Extrusion height accessor.\n * @default 1\n */\n getVertex3?: Accessor<DataT, number>;\n /** Extrusion height accessor.\n * @default 1\n */\n getOpacity?: Accessor<DataT, number>;\n texture?: string | TextureSource | Promise<TextureSource>;\n triangulationMode?:\n | 'unstructured'\n | 'quadkey'\n | 'quadkey-cells'\n | 'spherical'\n | 'spherical-cells';\n shape?: [number, number];\n /**\n * Material settings for lighting effect. Applies if `extruded: true`\n *\n * @default true\n * @see https://deck.gl/docs/developer-guide/using-lighting\n */\n material?: Material;\n};\n\n/** Render filled and/or extruded polygons. */\nexport type SolidPolygonLayerProps<DataT = unknown> = _ShadedLayerProps<DataT> & LayerProps;\n\nconst DEFAULT_COLOR: [number, number, number, number] = [0, 0, 0, 255];\n\nconst defaultProps: DefaultProps<SolidPolygonLayerProps> = {\n filled: true,\n extruded: false,\n wireframe: false,\n _normalize: false,\n _windingOrder: 'CW',\n _full3d: false,\n triangulationMode: 'unstructured',\n\n parameters: { depthCompare: 'always', cullMode: 'back' },\n\n elevationScale: { type: 'number', min: 0, value: 1 },\n\n getPolygon: { type: 'accessor', value: (f: any) => f.polygon },\n getElevation: { type: 'accessor', value: 0 },\n\n // THW ADD\n getVertex1: { type: 'accessor', value: -1 },\n getVertex2: { type: 'accessor', value: -1 },\n getVertex3: { type: 'accessor', value: -1 },\n getPolygonData: { type: 'accessor', value: 1000 },\n texture: {\n type: 'image',\n value: null,\n async: true,\n },\n // Optional opacity layer\n getOpacity: { type: 'accessor', value: -1 },\n // THW Done\n\n // Accessor for colors\n getFillColor: { type: 'accessor', value: DEFAULT_COLOR },\n getLineColor: { type: 'accessor', value: DEFAULT_COLOR },\n\n material: true,\n};\n\nconst ATTRIBUTE_TRANSITION = {\n enter: (value, chunk) => {\n return chunk.length ? chunk.subarray(chunk.length - value.length) : value;\n },\n};\n\nexport default class ShadedLayer<DataT = any, ExtraPropsT extends {} = {}> extends Layer<\n ExtraPropsT & Required<_ShadedLayerProps<DataT>>\n> {\n static defaultProps = defaultProps;\n static layerName = 'ShadedLayer';\n\n state!: {\n topModel?: Model;\n sideModel?: Model;\n wireframeModel?: Model;\n model?: Model;\n texture?: Texture;\n emptyTexture: Texture;\n models?: Model[];\n numInstances: number;\n polygonTesselator: PolygonTesselator;\n };\n\n getShaders(type) {\n return super.getShaders({\n vs: type === 'top' ? vsTop : vsSide,\n fs,\n defines: {\n RING_WINDING_ORDER_CW:\n !this.props._normalize && this.props._windingOrder === 'CCW' ? 0 : 1,\n },\n modules: [project32, gouraudMaterial, picking, solidPolygonUniforms],\n });\n }\n\n get wrapLongitude(): boolean {\n return false;\n }\n\n getBounds(): [number[], number[]] | null {\n return this.getAttributeManager()?.getBounds(['vertexPositions']);\n }\n\n initializeState() {\n const { viewport } = this.context;\n let { coordinateSystem } = this.props;\n const { _full3d } = this.props;\n if (viewport.isGeospatial && coordinateSystem === COORDINATE_SYSTEM.DEFAULT) {\n coordinateSystem = COORDINATE_SYSTEM.LNGLAT;\n }\n\n let preproject: ((xy: number[]) => number[]) | undefined;\n\n if (coordinateSystem === COORDINATE_SYSTEM.LNGLAT) {\n if (_full3d) {\n preproject = viewport.projectPosition.bind(viewport);\n } else {\n preproject = viewport.projectFlat.bind(viewport);\n }\n }\n\n this.setState({\n numInstances: 0,\n emptyTexture: this.context.device.createTexture({\n data: new Uint8Array(4),\n width: 1,\n height: 1,\n }),\n polygonTesselator: new PolygonTesselator({\n // Lnglat coordinates are usually projected non-linearly, which affects tesselation results\n // Provide a preproject function if the coordinates are in lnglat\n preproject,\n fp64: this.use64bitPositions(),\n IndexType: Uint32Array,\n }),\n });\n\n const attributeManager = this.getAttributeManager()!;\n const noAlloc = true;\n\n attributeManager.remove(['instancePickingColors']);\n\n /* eslint-disable max-len */\n attributeManager.add({\n indices: {\n size: 1,\n isIndexed: true,\n // eslint-disable-next-line @typescript-eslint/unbound-method\n update: this.calculateIndices,\n noAlloc,\n },\n vertexPositions: {\n size: 3,\n type: 'float64',\n stepMode: 'dynamic',\n fp64: this.use64bitPositions(),\n transition: ATTRIBUTE_TRANSITION,\n accessor: 'getPolygon',\n // eslint-disable-next-line @typescript-eslint/unbound-method\n update: this.calculatePositions,\n noAlloc,\n shaderAttributes: {\n nextVertexPositions: {\n vertexOffset: 1,\n },\n },\n },\n instanceVertexValid: {\n size: 1,\n type: 'uint16',\n stepMode: 'instance',\n // eslint-disable-next-line @typescript-eslint/unbound-method\n update: this.calculateVertexValid,\n noAlloc,\n },\n // THW ADD\n polygondata: {\n size: 1,\n stepMode: 'dynamic',\n transition: ATTRIBUTE_TRANSITION,\n accessor: 'getPolygonData',\n },\n opacitydata: {\n size: 1,\n stepMode: 'dynamic',\n transition: ATTRIBUTE_TRANSITION,\n accessor: 'getOpacity',\n },\n vertex1: {\n size: 1,\n stepMode: 'dynamic',\n transition: ATTRIBUTE_TRANSITION,\n accessor: 'getVertex1',\n },\n vertex2: {\n size: 1,\n stepMode: 'dynamic',\n transition: ATTRIBUTE_TRANSITION,\n accessor: 'getVertex2',\n },\n vertex3: {\n size: 1,\n stepMode: 'dynamic',\n transition: ATTRIBUTE_TRANSITION,\n accessor: 'getVertex3',\n },\n\n elevations: {\n size: 1,\n stepMode: 'dynamic',\n transition: ATTRIBUTE_TRANSITION,\n accessor: 'getElevation',\n },\n fillColors: {\n size: this.props.colorFormat.length,\n type: 'unorm8',\n stepMode: 'dynamic',\n transition: ATTRIBUTE_TRANSITION,\n accessor: 'getFillColor',\n defaultValue: DEFAULT_COLOR,\n },\n lineColors: {\n size: this.props.colorFormat.length,\n type: 'unorm8',\n stepMode: 'dynamic',\n transition: ATTRIBUTE_TRANSITION,\n accessor: 'getLineColor',\n defaultValue: DEFAULT_COLOR,\n },\n pickingColors: {\n size: 4,\n type: 'uint8',\n stepMode: 'dynamic',\n accessor: (object, { index, target: value }) =>\n this.encodePickingColor(\n object && object.__source ? object.__source.index : index,\n value,\n ),\n },\n });\n /* eslint-enable max-len */\n }\n\n getPickingInfo(params: GetPickingInfoParams): PickingInfo {\n const info = super.getPickingInfo(params);\n const { index } = info;\n const data = this.props.data as any[];\n\n // Check if data comes from a composite layer, wrapped with getSubLayerRow\n if (data[0] && data[0].__source) {\n // index decoded from picking color refers to the source index\n info.object = data.find((d) => d.__source.index === index);\n }\n return info;\n }\n\n disablePickingIndex(objectIndex: number) {\n const data = this.props.data as any[];\n\n // Check if data comes from a composite layer, wrapped with getSubLayerRow\n if (data[0] && data[0].__source) {\n // index decoded from picking color refers to the source index\n for (let i = 0; i < data.length; i++) {\n if (data[i].__source.index === objectIndex) {\n this._disablePickingIndex(i);\n }\n }\n } else {\n super.disablePickingIndex(objectIndex);\n }\n }\n\n draw({ uniforms }) {\n const { extruded, filled, wireframe, elevationScale } = this.props;\n const { topModel, sideModel, wireframeModel, polygonTesselator } = this.state;\n\n const renderUniforms: SolidPolygonProps = {\n extruded: Boolean(extruded),\n elevationScale,\n isWireframe: false,\n hasTexture: true,\n };\n\n // Note - the order is important\n if (wireframeModel && wireframe) {\n wireframeModel.setInstanceCount(polygonTesselator.instanceCount - 1);\n wireframeModel.shaderInputs.setProps({\n solidPolygon: { ...renderUniforms, isWireframe: true },\n });\n wireframeModel.draw(this.context.renderPass);\n }\n\n if (sideModel && filled) {\n sideModel.setInstanceCount(polygonTesselator.instanceCount - 1);\n sideModel.shaderInputs.setProps({ solidPolygon: renderUniforms });\n sideModel.draw(this.context.renderPass);\n }\n\n if (topModel && filled) {\n topModel.setVertexCount(polygonTesselator.vertexCount);\n topModel.shaderInputs.setProps({ solidPolygon: renderUniforms });\n topModel.draw(this.context.renderPass);\n }\n }\n\n updateState(updateParams: UpdateParameters<this>) {\n super.updateState(updateParams);\n const { props, oldProps, changeFlags } = updateParams;\n\n const colorsChanged =\n props.colors !== oldProps.colors ||\n props.colorLevels !== oldProps.colorLevels ||\n props.colorType !== oldProps.colorType;\n\n if (props.data !== oldProps.data || colorsChanged) {\n console.log('Updating Buffers!');\n this.setBuffers();\n }\n\n if (props.lonlatGrid !== oldProps.lonlatGrid) {\n console.log('Updating geometry!');\n this.updateGeometry(updateParams);\n }\n\n const attributeManager = this.getAttributeManager();\n\n const regenerateModels =\n changeFlags.extensionsChanged ||\n props.filled !== oldProps.filled ||\n props.extruded !== oldProps.extruded;\n\n if (regenerateModels) {\n this.state.models?.forEach((model) => model.destroy());\n\n this.setState(this._getModels());\n attributeManager!.invalidateAll();\n }\n\n if (colorsChanged) {\n console.log('Updating Texture!');\n this.setTexture();\n }\n }\n\n private setBuffers() {\n // THW ADD\n\n const { lonlatGrid } = this.props;\n const triDims = this.props.shape;\n const effectiveTriangulationMode = this.props.triangulationMode;\n\n // Get cashing key for grid, 4 points is all that is needed to figure out\n // if this is a new grid or not\n const flatLonlatGrid = lonlatGrid.flat();\n const key = `${flatLonlatGrid[0]}-${flatLonlatGrid[1]}-${flatLonlatGrid[2]}-${flatLonlatGrid[flatLonlatGrid.length - 1]}-${lonlatGrid.length}-${effectiveTriangulationMode}`;\n\n // Make normalized data if it doesn't exist\n const ndata =\n this.props.ndata ||\n gUtilities.normalize(this.props.data, this.props.colorLevels, this.props.colorType);\n\n //\n // Typical shaded layer where data is interpolated between point\n //\n const dataValues = TriangulateGrid.triangulate(\n ndata,\n 'data',\n triDims,\n 1,\n 0,\n 1,\n effectiveTriangulationMode,\n );\n if (!positions?.[key]?.vertices) {\n const t0 = performance.now();\n positions[key] = {};\n [positions[key].vertices, positions[key].triangleIndices] = TriangulateGrid.triangulate(\n lonlatGrid,\n 'positions',\n triDims,\n 3,\n this.props.elevation,\n 1,\n effectiveTriangulationMode,\n );\n console.log('Triangulate Time:', performance.now() - t0);\n positions[key].startIndices = new Uint32Array([0]);\n }\n\n const data = {\n length: positions[key].startIndices.length,\n // startIndices should be [0] for a triangle and an array of start positions for a polygon\n startIndices: positions[key].startIndices,\n attributes: {\n getPolygon: { value: positions[key].vertices, size: 3 },\n // When supplying Triangle Indicies, the polygon is assumed to be a triangle\n getTriangleIndices: {\n value: positions[key].triangleIndices,\n size: 1,\n },\n getPolygonData: { value: dataValues, size: 1 },\n },\n };\n\n // If opacity data (or normalized opacity data) is supplied, add it\n if (this.props.odata || this.props.nodata) {\n const nodata = this.props.nodata || gUtilities.normalize(this.props.odata, [0, 100], 'linear');\n data.attributes.getOpacity = TriangulateGrid.triangulate(\n nodata,\n 'data',\n triDims,\n 1,\n 1,\n 0.01,\n effectiveTriangulationMode,\n );\n }\n\n // Assign new props\n Object.assign(this.props, {\n data,\n });\n // THW DONE ADD\n }\n\n private setTexture(): void {\n const { emptyTexture, topModel } = this.state;\n\n // Get colors\n const colors = [];\n this.props.colors.forEach((c) => {\n colors.push(...gUtilities.string_to_rgb(c));\n });\n const ctype = this.props.colorType === 'scaleLinear' ? 'linear' : 'nearest';\n const texture = this.context.device.createTexture({\n width: colors.length / 4,\n height: 1,\n data: new Uint8Array(colors),\n sampler: {\n minFilter: ctype,\n magFilter: ctype,\n addressModeU: 'clamp-to-edge',\n addressModeV: 'clamp-to-edge',\n },\n //format: GL.RGBA,\n //pixelStore: {\n // [GL.UNPACK_FLIP_Y_WEBGL]: true,\n //},\n //mipmaps: false,\n });\n // props.mesh may not be ready at this time.\n // The sampler will be set when `getModel` is called\n if (topModel) {\n topModel.setBindings({\n sampler: texture || emptyTexture,\n });\n topModel.shaderInputs.setProps({\n // Looks like we need to provide a `ShaderModule` to get rid of the\n // TypeScript error? Maybe revisit this later\n // https://luma.gl/docs/api-reference/engine/shader-inputs/#shadermoduleinputs\n solidPolygon: {\n hasTexture: Boolean(texture),\n },\n });\n }\n }\n\n protected updateGeometry({ props, oldProps, changeFlags }: UpdateParameters<this>) {\n const geometryConfigChanged =\n changeFlags.dataChanged ||\n (changeFlags.updateTriggersChanged &&\n (changeFlags.updateTriggersChanged.all ||\n changeFlags.updateTriggersChanged.getPolygon));\n\n // When the geometry config or the data is changed,\n // tessellator needs to be invoked\n if (geometryConfigChanged) {\n const { polygonTesselator } = this.state;\n const buffers = (props.data as any).attributes || {};\n polygonTesselator.updateGeometry({\n data: props.data,\n normalize: props._normalize,\n geometryBuffer: buffers.getPolygon,\n buffers,\n getGeometry: props.getPolygon,\n positionFormat: props.positionFormat,\n wrapLongitude: props.wrapLongitude,\n // TODO - move the flag out of the viewport\n resolution: this.context.viewport.resolution,\n fp64: this.use64bitPositions(),\n dataChanged: changeFlags.dataChanged,\n full3d: props._full3d,\n });\n\n this.setState({\n numInstances: polygonTesselator.instanceCount,\n startIndices: polygonTesselator.vertexStarts,\n });\n\n if (!changeFlags.dataChanged) {\n // Base `layer.updateState` only invalidates all attributes on data change\n // Cover the rest of the scenarios here\n this.getAttributeManager()!.invalidateAll();\n }\n }\n }\n\n protected _getModels() {\n const { id, filled, extruded } = this.props;\n\n let topModel;\n let sideModel;\n let wireframeModel;\n\n if (filled) {\n const shaders = this.getShaders('top');\n shaders.defines.NON_INSTANCED_MODEL = 1;\n const bufferLayout = this.getAttributeManager()!.getBufferLayouts({\n isInstanced: false,\n });\n\n topModel = new Model(this.context.device, {\n ...shaders,\n id: `${id}-top`,\n topology: 'triangle-list',\n bufferLayout,\n isIndexed: true,\n userData: {\n excludeAttributes: { instanceVertexValid: true },\n },\n });\n }\n if (extruded) {\n const bufferLayout = this.getAttributeManager()!.getBufferLayouts({\n isInstanced: true,\n });\n\n sideModel = new Model(this.context.device, {\n ...this.getShaders('side'),\n id: `${id}-side`,\n bufferLayout,\n geometry: new Geometry({\n topology: 'triangle-strip',\n attributes: {\n // top right - top left - bottom right - bottom left\n positions: {\n size: 2,\n value: new Float32Array([1, 0, 0, 0, 1, 1, 0, 1]),\n },\n },\n }),\n isInstanced: true,\n userData: {\n excludeAttributes: { indices: true },\n },\n });\n\n wireframeModel = new Model(this.context.device, {\n ...this.getShaders('side'),\n id: `${id}-wireframe`,\n bufferLayout,\n geometry: new Geometry({\n topology: 'line-strip',\n attributes: {\n // top right - top left - bottom left - bottom right\n positions: {\n size: 2,\n value: new Float32Array([1, 0, 0, 0, 0, 1, 1, 1]),\n },\n },\n }),\n isInstanced: true,\n userData: {\n excludeAttributes: { indices: true },\n },\n });\n }\n\n return {\n models: [sideModel, wireframeModel, topModel].filter(Boolean),\n topModel,\n sideModel,\n wireframeModel,\n };\n }\n\n protected calculateIndices(attribute) {\n const { polygonTesselator } = this.state;\n attribute.startIndices = polygonTesselator.indexStarts;\n attribute.value = polygonTesselator.get('indices');\n }\n\n protected calculatePositions(attribute) {\n const { polygonTesselator } = this.state;\n attribute.startIndices = polygonTesselator.vertexStarts;\n attribute.value = polygonTesselator.get('positions');\n }\n\n protected calculateVertexValid(attribute) {\n attribute.value = this.state.polygonTesselator.get('vertexValid');\n }\n}\n","export default \"data:image/png;base64,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\"","/* eslint-disable max-len */\nimport { CompositeLayer } from '@deck.gl/core';\nimport { IconLayer } from '@deck.gl/layers';\nimport { CollisionFilterExtension } from '@deck.gl/extensions';\nimport barbsPNG from './barbs-new.png?url';\nimport deckUtilities from '../../utilities/deckUtilities';\nimport gUtilities from '../../utilities/graphicsUtilities';\n\n//\n// Constants for Korri's wind barbs\nconst clampNum = (x) => `barb${Math.floor(x / 5) * 5}`;\nconst ICON_MAPPING = {};\nconst IconRow = (x) => 4 - 1 - Math.floor((x + 2.5) / 50);\nconst IconCol = (x) => Math.floor(((x + 2.5) % 50.0) / 5.0);\n\nfor (let barbidx = 0; barbidx <= 175; barbidx += 5) {\n ICON_MAPPING[`barb${barbidx}`] = {\n x: IconCol(barbidx) * 100,\n y: IconRow(barbidx) * 100,\n width: 100,\n anchorY: 11,\n anchorX: 67,\n height: 100,\n mask: true,\n };\n}\n\nconst defaultProps = {\n sizeScale: 25,\n elevation: 0,\n angleOffset: 0,\n billboard: false,\n getColor: (x) => x.color || [0, 0, 0, 255],\n getLabel: (x) => x.label,\n getWeight: (x) => x.weight || 1,\n getPosition: (x) => x.position,\n parameters: { depthCompare: 'always', cullMode: 'front' },\n // Sampling mode for vector rendering: 'quadkey' | 'unstructured' | 'spherical'\n triangulationMode: 'quadkey',\n // For gridded datasets, pass the shape as [rows, cols]\n shape: null,\n // Multiplier for barb spacing — larger values spread barbs further apart\n spacingScale: 1,\n};\n\nexport default class VectorLayer extends CompositeLayer {\n initializeState() {\n this.state = {\n // Cached tags per zoom level\n zoom: 9999,\n data: [],\n bounds: null,\n };\n }\n\n // eslint-disable-next-line class-methods-use-this\n shouldUpdateState({ changeFlags }) {\n return changeFlags.somethingChanged;\n }\n\n updateState({ props, oldProps, changeFlags }) {\n super.updateState({ props, oldProps, changeFlags });\n const { viewport } = this.context;\n const { zoom } = viewport;\n const t0 = performance.now();\n\n const { yMin, yMax, xMin, xMax } = deckUtilities.getViewportBounds(viewport);\n const yRange = yMax - yMin;\n const xRange = xMax - xMin;\n const yBuffer = yRange * 0.3;\n const xBuffer = xRange * 0.3;\n\n // Only update the layer if propsOrDataChanged,\n // if zoom has changed by 0.5 or more,\n // or if the viewport has panned to the edge of the previously buffered render area.\n if (!changeFlags.propsOrDataChanged) {\n const prevBounds = this.state.bounds;\n const hitBufferEdge = prevBounds && (\n yMin < prevBounds.yMin ||\n yMax > prevBounds.yMax ||\n xMin < prevBounds.xMin ||\n xMax > prevBounds.xMax\n );\n if (!zoom || (Math.abs(zoom - this.state.zoom) < 0.5 && !hitBufferEdge)) return;\n }\n\n function wrapLongitude(lon) {\n return ((((lon + 180) % 360) + 360) % 360) - 180;\n }\n\n const { lonlatGrid, dataDir, dataMag, triangulationMode, shape } = props;\n // console.log('viewport bounds', { yMin, yMax, xMin, xMax });\n // console.log('ybuffer, xbuffer', { yBuffer, xBuffer });\n\n const sizeScale = props.sizeScale * zoom ** 0.25;\n const results = [];\n const mode = triangulationMode || 'quadkey';\n // Fast sampling for gridded data (quadkey / spherical) when shape is provided\n if (mode === 'quadkey' && Array.isArray(shape) && shape.length === 2) {\n const [ny, nx] = shape;\n\n const { latPerPixel, lonPerPixel } = deckUtilities.getLatLonPerPixel(viewport);\n\n // Use center of grid to estimate per-grid-degree spacing robustly\n const jlen = ny;\n const ilen = nx;\n const j0 = Math.floor(ny / 2);\n const i0 = Math.floor(nx / 2);\n const centerIdx = j0 * nx + i0;\n\n let latStep = NaN;\n let lonStep = NaN;\n const centerPt = lonlatGrid[centerIdx];\n if (centerPt && Array.isArray(centerPt)) {\n // Try to take neighbor differences around the center\n if (j0 < ny - 1) {\n const down = lonlatGrid[(j0 + 1) * nx + i0];\n if (down && Array.isArray(down)) latStep = Math.abs(down[1] - centerPt[1]);\n }\n if (!Number.isFinite(latStep) && j0 > 0) {\n const up = lonlatGrid[(j0 - 1) * nx + i0];\n if (up && Array.isArray(up)) latStep = Math.abs(centerPt[1] - up[1]);\n }\n\n if (i0 < nx - 1) {\n const right = lonlatGrid[j0 * nx + (i0 + 1)];\n if (right && Array.isArray(right)) lonStep = Math.abs(right[0] - centerPt[0]);\n }\n if (!Number.isFinite(lonStep) && i0 > 0) {\n const left = lonlatGrid[j0 * nx + (i0 - 1)];\n if (left && Array.isArray(left)) lonStep = Math.abs(centerPt[0] - left[0]);\n }\n }\n\n // Fallback to total extent if neighbor diffs failed or are zero\n if (!Number.isFinite(latStep) || latStep === 0) {\n const top = lonlatGrid[0];\n const bottom = lonlatGrid[(ny - 1) * nx + 0];\n if (top && bottom) latStep = Math.abs(bottom[1] - top[1]) / ny;\n }\n if (!Number.isFinite(lonStep) || lonStep === 0) {\n const leftmost = lonlatGrid[0];\n const rightmost = lonlatGrid[0 * nx + (nx - 1)];\n if (leftmost && rightmost) lonStep = Math.abs(rightmost[0] - leftmost[0]) / nx;\n }\n\n // Now compute barbs per degree (grid points per degree)\n const barbsPerLat = 1 / latStep;\n const barbsPerLon = 1 / lonStep;\n\n // Ideal spacing between barbs is 1.5 the length of a barb, scaled by spacingScale\n const idealSpacingPixelPerBarb = props.sizeScale * 1.5 * props.spacingScale;\n const xpixelPerBarb = 1 / (barbsPerLat * latPerPixel);\n const ypixelPerBarb = 1 / (barbsPerLon * lonPerPixel);\n const xInterval = Math.max(Math.round(idealSpacingPixelPerBarb / xpixelPerBarb), 1);\n const yInterval = Math.max(Math.round(idealSpacingPixelPerBarb / ypixelPerBarb), 1);\n\n const numy = Math.ceil(jlen / yInterval);\n const numx = Math.ceil(ilen / xInterval);\n for (let j = 0; j < jlen; j += yInterval) {\n for (let i = 0; i < ilen; i += xInterval) {\n const idx = j * nx + i;\n const p = lonlatGrid[idx];\n const lon = p[0];\n const lat = p[1];\n\n const speed = dataMag[idx];\n const direction = dataDir[idx];\n if (\n lat < yMin - yBuffer ||\n lat > yMax + yBuffer ||\n lon < xMin - xBuffer ||\n lon > xMax + xBuffer\n ) {\n continue;\n }\n if (\n !Number.isFinite(lon) ||\n !Number.isFinite(lat) ||\n !Number.isFinite(speed) ||\n !Number.isFinite(direction)\n )\n continue;\n results.push({\n position: [lon, lat, props.elevation],\n speed,\n angle: -direction + 180 + props.angleOffset,\n });\n }\n }\n } else {\n // Base pixel spacing. Use inverse scaling so spacing decreases when zooming in\n // (prevents sparser symbols at higher zooms).\n const paddingPx = 24 * props.spacingScale;\n const DEFAULT_ICON_SCALE = 25;\n const minPixelSpacing = Math.max(1, paddingPx * (DEFAULT_ICON_SCALE / sizeScale));\n // screen buffer (pixels) to avoid clipping at edges while zooming\n const bufferPx = Math.ceil(minPixelSpacing * 1.5);\n\n // Unstructured or fallback: project points and use a screen-space spatial hash to avoid collisions\n const cellSize = Math.max(1, minPixelSpacing);\n const cells = new Map();\n\n for (let idx = 0; idx < lonlatGrid.length; idx += 1) {\n const p = lonlatGrid[idx];\n if (!p || !Array.isArray(p) || p.length < 2) continue;\n const lon = p[0];\n const lat = p[1];\n const speed = dataMag[idx];\n const direction = dataDir[idx];\n\n if (\n !Number.isFinite(lon) ||\n !Number.isFinite(lat) ||\n !Number.isFinite(speed) ||\n !Number.isFinite(direction)\n )\n continue;\n const wrappedLon = wrapLongitude(lon);\n const projected = viewport.project([wrappedLon, lat]);\n const px = projected[0];\n const py = projected[1];\n // console.log('projected', { lon, lat, wrappedLon, px, py });\n\n if (\n px < -bufferPx ||\n py < -bufferPx ||\n px > viewport.width + bufferPx ||\n py > viewport.height + bufferPx\n )\n continue;\n\n const cellX = Math.floor(px / cellSize);\n const cellY = Math.floor(py / cellSize);\n let foundNearby = false;\n for (let dx = -1; dx <= 1 && !foundNearby; dx += 1) {\n for (let dy = -1; dy <= 1 && !foundNearby; dy += 1) {\n const key = `${cellX + dx}_${cellY + dy}`;\n if (cells.has(key)) {\n const existing = cells.get(key);\n const dist = Math.hypot(existing[0] - px, existing[1] - py);\n if (dist < minPixelSpacing) {\n foundNearby = true;\n }\n }\n }\n }\n if (!foundNearby) {\n cells.set(`${cellX}_${cellY}`, [px, py]);\n results.push({\n position: [lon, lat, props.elevation],\n speed,\n angle: -direction + 180 + props.angleOffset,\n });\n }\n }\n }\n\n console.log('vector layer: processed data in ', performance.now() - t0, 'ms');\n // console.log('lonlatGrid', lonlatGrid);\n // console.log('Number of barbs', results.length);\n // console.log('reulsts', results);\n this.setState({\n zoom,\n data: results,\n sizeScale,\n bounds: { yMin: yMin - yBuffer, yMax: yMax + yBuffer, xMin: xMin - xBuffer, xMax: xMax + xBuffer },\n });\n }\n\n renderLayers() {\n const { data, sizeScale } = this.state;\n\n if (!data.length) return;\n const vectorLayer = new IconLayer(this.props, {\n id: `${this.props.id}-icon`,\n data,\n // getSize: () => this.state.sizeScale,\n getIcon: (d) => clampNum(d.speed),\n getAngle: (d) => d.angle,\n getPosition: (d) => d.position,\n // false switches wind direction in globe view\n // true makes the wind barbs follow you, making them change directions\n iconAtlas: barbsPNG,\n iconMapping: ICON_MAPPING,\n // extensions: [new CollisionFilterExtension()],\n collisionEnabled: false,\n // alphaCutoff: -100,\n // getCollisionPriority: () => 0,\n sizeScale: sizeScale,\n pickable: false,\n collisionTestProps: {\n sizeScale: sizeScale,\n },\n });\n\n // eslint-disable-next-line consistent-return\n return vectorLayer;\n }\n}\n\nVectorLayer.layerName = 'VectorLayer';\nVectorLayer.defaultProps = defaultProps;\n\nexport { VectorLayer };\n","export default `#version 300 es\n#define SHADER_NAME particle_layer_update_transform_vertex_shader\n\nprecision highp float;\n\nin vec3 sourcePosition;\nout vec3 targetPosition;\n\nuniform sampler2D bitmapTexture;\nuniform sampler2D noiseTexture;\n\nconst vec2 DROP_POSITION = vec2(0.0);\nconst float PI = 3.141592653589793;\nconst float DEG2RAD = 0.017453292519943295;\nconst float RAD2DEG = 57.29577951308232;\nconst float R_EARTH = 6370972.0;\nconst float NOISE_TEX_SIZE = 256.0;\nconst float PARTICLE_ELEVATION = 100.0; // meters \n\n// Optimized hash functions using pre-computed noise texture\n// Much faster than computing sin() per particle\nfloat hash1D(float n) { \n vec2 uv = vec2(fract(n * 0.00390625), fract(n * 0.015625));\n return texture(noiseTexture, uv).r;\n}\n\nfloat hash(vec2 p) {\n vec2 uv = fract(p * 0.00390625);\n return texture(noiseTexture, uv).g;\n}\n\nvec2 noise2D(vec2 p) { \n vec2 uv = fract(p * 0.00390625);\n vec4 n = texture(noiseTexture, uv);\n return n.rg * 2.0 - 1.0;\n}\n\nfloat rad(float d) { return d * DEG2RAD; }\nfloat deg(float r) { return r * RAD2DEG; }\n\nvec3 llToNormal(vec2 llDeg) {\n float lon = rad(llDeg.x);\n float lat = rad(llDeg.y);\n float cl = cos(lat);\n return vec3(cl * cos(lon), cl * sin(lon), sin(lat));\n}\n\nfloat greatCircleDistance(vec2 pos1, vec2 pos2) {\n float lat1 = rad(pos1.y), lon1 = rad(pos1.x);\n float lat2 = rad(pos2.y), lon2 = rad(pos2.x);\n float dLat = lat2 - lat1;\n float dLon = lon2 - lon1;\n if (abs(dLon) > PI) dLon = dLon > 0.0 ? dLon - 2.0 * PI : dLon + 2.0 * PI;\n float a = sin(dLat * 0.5); a *= a;\n float b = sin(dLon * 0.5); b *= b;\n float c = 2.0 * atan(sqrt(a + cos(lat1) * cos(lat2) * b), sqrt(1.0 - a - cos(lat1) * cos(lat2) * b));\n return deg(c);\n}\n\nfloat hemisphereVisibility(vec2 llDeg, vec2 centerLLDeg) {\n float d = dot(llToNormal(llDeg), llToNormal(centerLLDeg));\n // Smooth fade from ~110° back side\n return smoothstep(-0.342, 0.0, d); // -0.342 ≈ cos(110°)\n}\n\nbool isGlobalData(vec4 b) {\n float lonSpan = b.z - b.x;\n float latSpan = b.w - b.y;\n return lonSpan >= 350.0 && latSpan >= 170.0;\n}\n\nfloat wrapLongitude(float lng) {\n return mod(lng + 180.0, 360.0) - 180.0;\n}\n\n// Adapts longitude to the bounds domain (handles 0-360 vs -180/180)\nfloat adjustLon(float lon, vec4 b) {\n if (b.z > 180.0 && lon < 0.0) {\n return lon + 360.0;\n }\n return lon;\n}\n\nbool isInDataBounds(vec2 pos, vec4 b) {\n if (pos.y < b.y || pos.y > b.w) return false;\n if (isGlobalData(b)) return true;\n \n float px = adjustLon(pos.x, b);\n return px >= b.x && px <= b.z;\n}\n\nbool isInViewportBounds(vec2 pos, vec4 vb) {\n if (pos.y < vb.y || pos.y > vb.w) return false;\n\n float lng = mod(pos.x + 180.0, 360.0) - 180.0;\n float minLng = mod(vb.x + 180.0, 360.0) - 180.0;\n float maxLng = mod(vb.z + 180.0, 360.0) - 180.0;\n\n // If viewport crosses dateline\n return (minLng <= maxLng) ? (lng >= minLng && lng <= maxLng) : (lng >= minLng || lng <= maxLng);\n}\n\nvec2 getUV(vec2 pos, vec4 b) {\n float v = clamp((pos.y - b.w) / (b.y - b.w), 0.0, 1.0);\n float u;\n if (isGlobalData(b)) {\n float minLon = b.x;\n float offsetLon = pos.x - minLon;\n float lon360 = mod(offsetLon, 360.0);\n if (lon360 < 0.0) lon360 += 360.0;\n u = clamp(lon360 / 360.0, 0.0, 1.0);\n } else {\n float px = adjustLon(pos.x, b);\n float lonSpan = max(1e-6, b.z - b.x);\n u = clamp((px - b.x) / lonSpan, 0.0, 1.0);\n }\n return vec2(u, v);\n}\n\nvec2 destinationPoint(vec2 fromLL, float distMeters, float bearingDegrees) {\n float d = distMeters / R_EARTH;\n float r = rad(bearingDegrees);\n float y1 = rad(fromLL.y);\n float x1 = rad(fromLL.x);\n\n float siny2 = sin(y1) * cos(d) + cos(y1) * sin(d) * cos(r);\n float y2 = asin(siny2);\n float y = sin(r) * sin(d) * cos(y1);\n float x = cos(d) - sin(y1) * siny2;\n float x2 = x1 + atan(y, x);\n\n return vec2(deg(x2), deg(y2));\n}\n\nvec2 spawnOnGlobeRadius(float particleIndex) {\n float phase = sin(bitmap.time * 0.15 + particleIndex * 0.0073) * 0.5 + 0.5;\n\n vec2 rnd = vec2(\n hash1D(particleIndex * 0.013 + phase * 2.1),\n hash1D(particleIndex * 0.017 + phase * 3.7)\n );\n\n float rMeters = sqrt(max(1e-6, rnd.x)) * max(0.0, bitmap.viewportGlobeRadius);\n float bearing = rnd.y * 360.0;\n\n vec2 pos = destinationPoint(bitmap.viewportCenter, rMeters, bearing);\n\n pos += noise2D(vec2(particleIndex * 0.031, bitmap.time * 0.001)) * 0.25;\n pos.y = clamp(pos.y, bitmap.bounds.y, bitmap.bounds.w);\n pos.x = isGlobalData(bitmap.bounds) ? wrapLongitude(pos.x) : clamp(pos.x, bitmap.bounds.x, bitmap.bounds.z);\n\n return pos;\n}\n\nbool hasWindDataAt(vec2 pos) {\n vec2 uv = getUV(pos, bitmap.bounds);\n return texture(bitmapTexture, uv).a >= 0.5;\n}\n\nbool onFrontHemisphere(vec2 llDeg, vec2 centerLLDeg, float threshold) {\n return dot(llToNormal(llDeg), llToNormal(centerLLDeg)) >= threshold;\n}\n\nvec2 advectOnGlobe(vec2 currentPos, vec2 speed, float particleIndex, float dt) {\n float latRad = rad(clamp(currentPos.y, -89.9, 89.9));\n float cosLat = max(1e-6, cos(latRad));\n\n float sig = hash1D(particleIndex * 0.0239);\n float speedVar = 0.7 + 0.6 * hash1D(particleIndex * 0.019 + 4.5);\n float temporalVar = 0.9 + 0.2 * sin(bitmap.time * 0.05 * (1.0 + sig * 0.5) + sig * 6.28318);\n\n float dLat = speed.y * bitmap.speedFactor * dt * speedVar * temporalVar;\n float dLon = speed.x * bitmap.speedFactor * dt * speedVar * temporalVar / cosLat;\n\n vec2 turb = noise2D(vec2(currentPos.x * 0.1 + bitmap.time * 0.01, currentPos.y * 0.1 + particleIndex * 0.001)) * 0.02;\n float speedMag = length(speed);\n if (speedMag > 0.001) {\n turb *= min(1.0, speedMag * 10.0);\n turb *= cosLat;\n }\n dLat += turb.y * bitmap.speedFactor * dt;\n dLon += turb.x * bitmap.speedFactor * dt / cosLat;\n\n vec2 randomWalk = noise2D(vec2(particleIndex * 0.027, bitmap.time * 0.003)) * 0.001;\n dLat += randomWalk.y;\n dLon += randomWalk.x;\n\n vec2 newPos = vec2(currentPos.x + dLon, currentPos.y + dLat);\n\n if (newPos.y > 90.0) { newPos.y = 180.0 - newPos.y; newPos.x += 180.0; }\n else if (newPos.y < -90.0) { newPos.y = -180.0 - newPos.y; newPos.x += 180.0; }\n\n newPos.x = wrapLongitude(newPos.x);\n return newPos;\n}\n\nbool shouldDropParticle(float particleIndex, float particleAge, vec2 currentPos, vec2 centerLL) {\n float lifeVar = hash1D(particleIndex * 0.01 + 0.5) * 0.4 + 0.8;\n float adjustedMaxAge = bitmap.maxAge * lifeVar;\n\n float cycleLength = adjustedMaxAge + 3.0 + hash1D(particleIndex * 0.017 + 1.3) * 5.0;\n float timeOffset = hash1D(particleIndex * 0.023 + 2.7) * cycleLength;\n bool ageCycle = abs(mod(particleIndex + timeOffset, cycleLength) - mod(bitmap.time * 0.5, cycleLength)) < 0.5;\n\n bool drop = ageCycle;\n\n if (bitmap.isGlobe == 1) {\n if (bitmap.cullBackside == 1) {\n float cullProbability = 1.0 - hemisphereVisibility(currentPos, centerLL);\n if (hash1D(particleIndex * 0.013 + bitmap.time * 0.002) < cullProbability) drop = true;\n }\n if (!isInDataBounds(currentPos, bitmap.bounds)) drop = true;\n if (greatCircleDistance(currentPos, centerLL) > 90.0) drop = true;\n } else {\n bool boundsCull = !isInViewportBounds(currentPos, bitmap.viewportBounds) ||\n !isInDataBounds(currentPos, bitmap.bounds);\n if (boundsCull) drop = true;\n }\n return drop;\n}\n\nvoid main() {\n float particleIndex = mod(float(gl_VertexID), bitmap.numParticles);\n float particleAge = floor(float(gl_VertexID) / bitmap.numParticles);\n\n if (particleAge > 0.0) { return; }\n\n bool isNewParticle = (sourcePosition.xy == DROP_POSITION);\n\n if (isNewParticle) {\n vec2 position = DROP_POSITION;\n if (bitmap.isGlobe == 1) {\n bool found = false;\n for (int attempt = 0; attempt < 6; attempt++) {\n float offset = float(attempt) * bitmap.numParticles;\n vec2 candidate = spawnOnGlobeRadius(particleIndex + offset);\n bool visible = bitmap.cullBackside == 0 ||\n onFrontHemisphere(candidate, bitmap.viewportCenter, -0.1);\n if (visible && hasWindDataAt(candidate)) {\n position = candidate;\n found = true;\n break;\n }\n }\n if (!found) {\n targetPosition.xy = DROP_POSITION;\n targetPosition.z = 0.0;\n return;\n }\n } else {\n bool found = false;\n // Prefer keeping particles inside the current viewport to preserve on-screen density.\n for (int attempt = 0; attempt < 10; attempt++) {\n float a = float(attempt);\n vec2 rnd = vec2(\n hash1D(particleIndex * 0.041 + 0.73 + a * 13.17 + bitmap.time * 0.001),\n hash1D(particleIndex * 0.053 + 1.91 + a * 17.39 + bitmap.time * 0.001)\n );\n vec2 candidate = mix(bitmap.bounds.xy, bitmap.bounds.zw, rnd);\n if (isInViewportBounds(candidate, bitmap.viewportBounds) && hasWindDataAt(candidate)) {\n position = candidate;\n found = true;\n break;\n }\n }\n // Fallback: still spawn in data mesh even if viewport intersection is tiny.\n if (!found) {\n for (int attempt = 0; attempt < 6; attempt++) {\n float a = float(attempt + 10);\n vec2 rnd = vec2(\n hash1D(particleIndex * 0.041 + 0.73 + a * 13.17 + bitmap.time * 0.001),\n hash1D(particleIndex * 0.053 + 1.91 + a * 17.39 + bitmap.time * 0.001)\n );\n vec2 candidate = mix(bitmap.bounds.xy, bitmap.bounds.zw, rnd);\n if (hasWindDataAt(candidate)) {\n position = candidate;\n found = true;\n break;\n }\n }\n }\n if (!found) {\n targetPosition = vec3(DROP_POSITION, 0.0);\n return;\n }\n }\n targetPosition = vec3(position, PARTICLE_ELEVATION);\n return;\n }\n\n if (shouldDropParticle(particleIndex, particleAge, sourcePosition.xy, bitmap.viewportCenter)) {\n targetPosition = vec3(DROP_POSITION, 0.0); // Keep dropped particles at z=0 for detection\n return;\n }\n\n vec2 currentPos = sourcePosition.xy;\n\n vec2 uvPos = currentPos;\n if (isGlobalData(bitmap.bounds)) {\n float lon360 = mod(uvPos.x, 360.0);\n if (lon360 < 0.0) lon360 += 360.0;\n uvPos.x = lon360;\n }\n\n vec2 uv = getUV(uvPos, bitmap.bounds);\n vec4 wind = texture(bitmapTexture, uv);\n\n // Drop particles with no data\n if (wind.a < 0.5) {\n targetPosition = vec3(DROP_POSITION, 0.0);\n return;\n }\n\n vec2 newPos;\n if (bitmap.isGlobe == 1) {\n newPos = advectOnGlobe(currentPos, wind.xy, particleIndex, 1.0);\n if (bitmap.cullBackside == 1 && hemisphereVisibility(newPos, bitmap.viewportCenter) < 0.1) {\n targetPosition = vec3(DROP_POSITION, 0.0);\n return;\n }\n } else {\n float lat = clamp(currentPos.y, -85.0, 85.0);\n float cosLat = cos(rad(lat));\n\n float sig = hash1D(particleIndex * 0.0239);\n float speedVar = 0.7 + 0.6 * hash1D(particleIndex * 0.019 + 4.5);\n float temporalVar = 0.9 + 0.2 * sin(bitmap.time * 0.05 * (1.0 + sig * 0.5) + sig * 6.28318);\n vec2 speed = wind.xy * (speedVar * temporalVar);\n\n vec2 turb = noise2D(vec2(currentPos.x * 0.1 + bitmap.time * 0.01, currentPos.y * 0.1 + particleIndex * 0.001)) * 0.02;\n float sMag = length(speed);\n if (sMag > 0.001) turb *= min(1.0, sMag * 10.0);\n speed += turb;\n\n vec2 randomWalk = noise2D(vec2(particleIndex * 0.027, bitmap.time * 0.003)) * 0.0001;\n\n newPos = currentPos + vec2(\n (speed.x + randomWalk.x) * bitmap.speedFactor / cosLat,\n (speed.y + randomWalk.y) * bitmap.speedFactor\n );\n }\n\n if (isGlobalData(bitmap.bounds)) {\n newPos.x = wrapLongitude(newPos.x);\n newPos.y = clamp(newPos.y, bitmap.bounds.y, bitmap.bounds.w);\n } else {\n if (!isInDataBounds(newPos, bitmap.bounds)) {\n targetPosition = vec3(DROP_POSITION, 0.0);\n return;\n }\n newPos.x = clamp(newPos.x, bitmap.bounds.x, bitmap.bounds.z);\n newPos.y = clamp(newPos.y, bitmap.bounds.y, bitmap.bounds.w);\n }\n\n if (!hasWindDataAt(newPos)) {\n targetPosition = vec3(DROP_POSITION, 0.0);\n return;\n }\n\n targetPosition = vec3(newPos, PARTICLE_ELEVATION);\n}\n`;","import {\n Color,\n DefaultProps,\n LayerContext,\n UpdateParameters,\n COORDINATE_SYSTEM,\n} from '@deck.gl/core';\nimport { LineLayer, LineLayerProps } from '@deck.gl/layers';\nimport { Buffer, Texture } from '@luma.gl/core';\nimport { Model, BufferTransform } from '@luma.gl/engine';\nimport { ShaderModule } from '@luma.gl/shadertools';\nimport earcut from 'earcut';\nimport shader from './particle-layer-update-transform.vs.glsl.js';\n\ntype LonLatPoint = [number, number];\ntype GridShape = [number, number];\n\ntype ResolvedGrid = {\n points: LonLatPoint[];\n rows: number;\n cols: number;\n gridKey: string;\n};\n\ntype TriangleIndices = [number, number, number];\n\ntype GlobeViewportLike = {\n longitude: number;\n latitude: number;\n width: number;\n height: number;\n unproject: (coords: [number, number]) => GeoJSON.Position;\n};\n\nexport type UniformProps = {\n numParticles: number;\n maxAge: number;\n speedFactor: number;\n time: number;\n seed: number;\n viewportBounds: [number, number, number, number];\n viewportZoomChangeFactor: number;\n bounds: [number, number, number, number];\n bitmapTexture: Texture;\n noiseTexture: Texture;\n isGlobe: number;\n viewportCenter: [number, number];\n cullBackside: number;\n viewportGlobeRadius: number;\n minWindSpeed: number;\n ringBufferIndex: number;\n};\n\nconst uniformBlock = `\\\nuniform bitmapUniforms {\n float numParticles;\n float maxAge;\n float speedFactor;\n float time;\n float seed;\n vec4 viewportBounds;\n float viewportZoomChangeFactor;\n vec4 bounds;\n vec2 viewportCenter;\n int cullBackside;\n int isGlobe;\n float viewportGlobeRadius;\n float minWindSpeed;\n int ringBufferIndex;\n} bitmap;\n`;\n\nexport const bitmapUniforms = {\n name: 'bitmap',\n vs: uniformBlock,\n uniformTypes: {\n numParticles: 'f32',\n maxAge: 'f32',\n speedFactor: 'f32',\n time: 'f32',\n seed: 'f32',\n viewportBounds: 'vec4<f32>',\n viewportZoomChangeFactor: 'f32',\n bounds: 'vec4<f32>',\n viewportCenter: 'vec2<f32>',\n cullBackside: 'i32',\n isGlobe: 'i32',\n viewportGlobeRadius: 'f32',\n minWindSpeed: 'f32',\n ringBufferIndex: 'i32',\n },\n} as const satisfies ShaderModule<UniformProps>;\n\nconst positionsCache = new Map<string, any>();\nconst MAX_CACHE_SIZE = 50; // Increased to support multi-panel setups\nconst DEFAULT_RADIUS = 6370972;\n\n// Shared noise texture data - computed once, reused by all particle layers\nlet sharedNoiseData: Float32Array | null = null;\nfunction getSharedNoiseData(): Float32Array {\n if (!sharedNoiseData) {\n const noiseSize = 256;\n sharedNoiseData = new Float32Array(noiseSize * noiseSize * 4);\n for (let i = 0; i < noiseSize * noiseSize; i++) {\n const o = i * 4;\n const x = i % noiseSize;\n const y = Math.floor(i / noiseSize);\n sharedNoiseData[o] = Math.abs(Math.sin(x * 12.9898 + y * 78.233) * 43758.5453) % 1;\n sharedNoiseData[o + 1] = Math.abs(Math.sin(x * 93.9898 + y * 67.345) * 24634.6345) % 1;\n sharedNoiseData[o + 2] = Math.abs(Math.sin(x * 45.164 + y * 23.789) * 65432.1234) % 1;\n sharedNoiseData[o + 3] = Math.abs(Math.sin(x * 78.456 + y * 12.567) * 87654.3456) % 1;\n }\n }\n return sharedNoiseData;\n}\n\n// Simple hash function for objects/strings\nfunction simpleHash(obj: any): string {\n let str = typeof obj === 'string' ? obj : JSON.stringify(obj);\n let hash = 0,\n i,\n chr;\n if (str.length === 0) return hash.toString();\n for (i = 0; i < str.length; i++) {\n chr = str.charCodeAt(i);\n hash = (hash << 5) - hash + chr;\n hash |= 0; // Convert to 32bit integer\n }\n return hash.toString();\n}\n\nfunction addToCache(key: string, value: any) {\n if (positionsCache.size >= MAX_CACHE_SIZE) {\n const firstKey = positionsCache.keys().next().value;\n if (firstKey) {\n positionsCache.delete(firstKey);\n }\n }\n positionsCache.set(key, value);\n}\n\nfunction isGlobalData(bounds: number[]): boolean {\n if (!bounds || bounds.length !== 4) return false;\n const [west, south, east, north] = bounds;\n const lonSpan = east - west;\n const latSpan = north - south;\n return lonSpan >= 350 && latSpan >= 170;\n}\n\nfunction toRadians(value: number): number {\n return (value / 180) * Math.PI;\n}\n\nfunction directionToUV(direction: number, magnitude: number): [number, number] {\n const rad = (direction * Math.PI) / 180;\n return [-magnitude * Math.sin(rad), -magnitude * Math.cos(rad)];\n}\n\nfunction normalizeLonDelta(fromLon: number, toLon: number): number {\n let delta = toLon - fromLon;\n while (delta > 180) delta -= 360;\n while (delta < -180) delta += 360;\n return delta;\n}\n\nfunction clamp(value: number, minValue: number, maxValue: number): number {\n return Math.min(maxValue, Math.max(minValue, value));\n}\n\nexport function distance(\n start: GeoJSON.Position,\n destination: GeoJSON.Position,\n radius: number = DEFAULT_RADIUS,\n): number {\n const R = radius;\n const φ1 = toRadians(start[1]);\n const λ1 = toRadians(start[0]);\n const φ2 = toRadians(destination[1]);\n const λ2 = toRadians(destination[0]);\n\n const Δφ = φ2 - φ1;\n let Δλ = λ2 - λ1;\n\n // Handle longitude difference across date line\n if (Math.abs(Δλ) > Math.PI) {\n Δλ = Δλ > 0 ? Δλ - 2 * Math.PI : Δλ + 2 * Math.PI;\n }\n\n const a =\n Math.sin(Δφ / 2) * Math.sin(Δφ / 2) +\n Math.cos(φ1) * Math.cos(φ2) * Math.sin(Δλ / 2) * Math.sin(Δλ / 2);\n const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));\n const d = R * c;\n\n return d;\n}\n\nfunction getViewportBounds(viewport: any): number[] {\n const [west, south, east, north] = viewport.getBounds();\n const lonMargin = (east - west) * 0.2;\n const latMargin = (north - south) * 0.2;\n\n let adjustedWest = west - lonMargin;\n let adjustedEast = east + lonMargin;\n const adjustedSouth = Math.max(south - latMargin, -90);\n const adjustedNorth = Math.min(north + latMargin, 90);\n\n // Handle date line crossing\n if (adjustedEast - adjustedWest > 360) {\n // If the span is greater than 360°, just use global bounds\n return [-180, adjustedSouth, 180, adjustedNorth];\n }\n\n // Normalize longitudes to [-180, 180] range\n adjustedWest = ((adjustedWest + 180) % 360) - 180;\n adjustedEast = ((adjustedEast + 180) % 360) - 180;\n // Normalize longitudes to [-180, 180] range (handle negative modulo correctly)\n //adjustedWest = ((((adjustedWest + 180) % 360) + 360) % 360) - 180;\n //adjustedEast = ((((adjustedEast + 180) % 360) + 360) % 360) - 180;\n\n return [adjustedWest, adjustedSouth, adjustedEast, adjustedNorth];\n}\n\nexport function getViewportGlobeRadius(viewport: GlobeViewportLike): number {\n const viewportGlobeCenter = [viewport.longitude, viewport.latitude];\n\n const distances = [\n distance(viewportGlobeCenter, viewport.unproject([viewport.width / 2, 0])),\n distance(viewportGlobeCenter, viewport.unproject([0, viewport.height / 2])),\n ];\n\n if (viewport.width > viewport.height) {\n distances.push(\n distance(\n viewportGlobeCenter,\n viewport.unproject([viewport.width / 4, viewport.height / 2]),\n ),\n distance(\n viewportGlobeCenter,\n viewport.unproject([(viewport.width * 3) / 4, viewport.height / 2]),\n ),\n distance(\n viewportGlobeCenter,\n viewport.unproject([viewport.width, viewport.height / 2]),\n ),\n );\n } else {\n distances.push(\n distance(\n viewportGlobeCenter,\n viewport.unproject([viewport.width / 2, viewport.height / 4]),\n ),\n distance(\n viewportGlobeCenter,\n viewport.unproject([viewport.width / 2, (viewport.height * 3) / 4]),\n ),\n distance(\n viewportGlobeCenter,\n viewport.unproject([viewport.width / 2, viewport.height]),\n ),\n );\n }\n const viewportGlobeRadius = Math.max(...distances);\n return viewportGlobeRadius;\n}\n\nconst DEFAULT_COLOR: [number, number, number, number] = [255, 255, 255, 255];\n\nexport type Bbox = [number, number, number, number];\n\nexport type ParticleLayerProps<D = unknown> = LineLayerProps<D> & {\n image: string | Texture | null;\n bounds?: Bbox;\n numParticles: number;\n maxAge: number;\n speedFactor: number;\n color: Color;\n width: number;\n animate?: boolean;\n wrapLongitude: boolean;\n dataDir?: ArrayLike<number>;\n dataMag?: ArrayLike<number>;\n lonlatGrid: LonLatPoint[] | LonLatPoint[][];\n shape?: GridShape | null;\n trailLength?: number;\n fadeTrails?: boolean;\n};\n\nconst defaultProps: DefaultProps<ParticleLayerProps> = {\n ...LineLayer.defaultProps,\n\n image: { type: 'image', value: null, async: true },\n\n numParticles: { type: 'number', min: 1, max: 100000, value: 10000 },\n maxAge: { type: 'number', min: 1, max: 255, value: 50 },\n speedFactor: { type: 'number', min: 0, max: 255, value: 3 },\n\n color: { type: 'color', value: DEFAULT_COLOR },\n width: { type: 'number', value: 1.2 },\n animate: { type: 'boolean', value: true },\n\n bounds: undefined,\n coordinateSystem: COORDINATE_SYSTEM.LNGLAT,\n wrapLongitude: true,\n\n trailLength: { type: 'number', min: 2, max: 100, value: 22 },\n fadeTrails: { type: 'boolean', value: true },\n\n parameters: { depthCompare: 'always', depthWriteEnabled: true, cullMode: 'none' },\n};\n\nexport default class ParticleLayer<D = any, ExtraPropsT = ParticleLayerProps<D>> extends LineLayer<\n D,\n ExtraPropsT & ParticleLayerProps<D>\n> {\n private boundsCache: { key: string; bounds: number[] } | null = null;\n\n declare state: {\n model?: Model;\n\n initialized: boolean;\n numInstances: number;\n numAgedInstances: number;\n numTrailSegments: number;\n\n sourcePositions: Buffer;\n targetPositions: Buffer;\n\n colors: Buffer;\n\n transform: BufferTransform;\n texture: Texture;\n noiseTexture: Texture; // Pre-computed noise for hash lookups\n\n previousViewportZoom: number;\n previousTime: number;\n\n stepRequested: boolean;\n bounds: number[];\n trailLines: any[];\n isGlobalData: boolean;\n\n needsAttributeBind: boolean;\n uniformHolder: { bitmap?: any } | null;\n zeroPositions?: Float32Array;\n ringBufferIndex: number; // Current write slot for ring buffer\n };\n\n private _sourcePositions64Low = new Float32Array([0, 0, 0]);\n private _targetPositions64Low = new Float32Array([0, 0, 0]);\n private _pickingColors = new Float32Array([0, 0, 0]);\n private _widths = new Float32Array([1]);\n\n getShaders() {\n const oldShaders = super.getShaders();\n const { numParticles, trailLength = 22, maxAge } = this.props;\n const effectiveTrailLength = Math.min(trailLength, maxAge);\n\n return {\n ...oldShaders,\n inject: {\n 'vs:#decl': `\n out float drop;\n out float trailAge;\n out float particleVariation;\n const vec2 DROP_POSITION = vec2(0);\n\n float hash(float n) {\n return fract(sin(n) * 43758.5453123);\n }\n `,\n 'vs:#main-start': `\n // Check for dropped particles (at origin) or invalid segments\n bool isDropped = (length(instanceSourcePositions.xy) < 0.001) ||\n (length(instanceTargetPositions.xy) < 0.001);\n\n // Check for unreasonably long segments (data edge artifacts)\n // Handle dateline wraparound: if longitude difference > 180, wrap it\n vec2 diff = instanceTargetPositions.xy - instanceSourcePositions.xy;\n if (abs(diff.x) > 180.0) {\n diff.x = diff.x > 0.0 ? diff.x - 360.0 : diff.x + 360.0;\n }\n float segmentLength = length(diff);\n bool isTooLong = segmentLength > 20.0; // Keep tails while filtering obvious artifacts\n\n drop = float(isDropped || isTooLong);\n\n // For instanced rendering: gl_InstanceID gives us which trail segment\n // instances 0..numParticles-1 = age 0 segments (connecting age 0 to age 1)\n // instances numParticles..2*numParticles-1 = age 1 segments, etc.\n float particleIndex = mod(float(gl_InstanceID), ${numParticles}.0);\n float ageIndex = floor(float(gl_InstanceID) / ${numParticles}.0);\n trailAge = ageIndex / ${Math.max(1, effectiveTrailLength - 1)}.0;\n\n particleVariation = hash(particleIndex);\n `,\n 'fs:#decl': `\n in float drop;\n in float trailAge;\n in float particleVariation;\n `,\n 'fs:#main-end': `\n if (drop > 0.5) discard;\n\n ${\n this.props.fadeTrails\n ? `\n // Age-based fade: head (trailAge=0) is opaque, tail (trailAge=1) fades out\n float fadeVariation = 0.8 + particleVariation * 0.4;\n float trailFade = 1.0 - smoothstep(0.0, fadeVariation, trailAge);\n fragColor.a = max(0.35, trailFade * trailFade);\n `\n : ''\n }\n `,\n },\n };\n }\n\n shouldResetParticles(viewport: any, previousViewport: any) {\n if (!previousViewport) return false;\n const zoomDiff = Math.abs(viewport.zoom - previousViewport.zoom);\n const isGlobe = viewport.projection?.mode === 'globe';\n return !isGlobe && zoomDiff > 3;\n }\n\n // Override to return trail segment count (not full age buffer)\n getNumInstances(): number {\n if (this.state?.numTrailSegments) {\n return this.state.numTrailSegments;\n }\n // Fallback before state is initialized\n const { numParticles, trailLength = 22, maxAge } = this.props;\n const effectiveTrailLength = Math.min(trailLength, maxAge);\n return numParticles * (effectiveTrailLength - 1);\n }\n\n initializeState() {\n super.initializeState();\n\n const attributeManager = this.getAttributeManager();\n attributeManager!.remove([\n 'instanceSourcePositions',\n 'instanceTargetPositions',\n 'instanceColors',\n 'instanceWidths',\n ]);\n\n attributeManager!.addInstanced({\n instanceSourcePositions: { size: 3, type: 'float32', noAlloc: true },\n instanceTargetPositions: { size: 3, type: 'float32', noAlloc: true },\n instanceColors: {\n size: 4,\n type: 'uint8',\n // @ts-ignore\n normalized: true,\n noAlloc: true,\n defaultValue: [...this.props.color.map((c) => c / 255)],\n },\n });\n\n this._setupState();\n }\n\n _toLonLatPoint(value: any): LonLatPoint {\n if (!Array.isArray(value) || value.length < 2) return [NaN, NaN];\n return [Number(value[0]), Number(value[1])];\n }\n\n _getGridCacheKey(points: LonLatPoint[], rows: number, cols: number): string {\n if (!points.length) return `${rows}x${cols}-empty`;\n const first = points[0];\n const mid = points[Math.floor(points.length / 2)] || first;\n const last = points[points.length - 1] || first;\n return simpleHash(`${rows}x${cols}-${first.join(',')}-${mid.join(',')}-${last.join(',')}`);\n }\n\n _resolveGrid(): ResolvedGrid | null {\n const lonlatGrid = this.props.lonlatGrid;\n if (!Array.isArray(lonlatGrid) || lonlatGrid.length === 0) {\n return null;\n }\n\n const first = lonlatGrid[0] as any;\n const hasNestedRows =\n Array.isArray(first) && first.length > 0 && Array.isArray((first as any[])[0]);\n\n let points: LonLatPoint[] = [];\n let rows = 0;\n let cols = 0;\n\n if (hasNestedRows) {\n rows = lonlatGrid.length;\n cols = Array.isArray(lonlatGrid[0]) ? (lonlatGrid[0] as any[]).length : 0;\n if (rows <= 0 || cols <= 0) return null;\n\n points = new Array(rows * cols);\n let ptr = 0;\n for (let r = 0; r < rows; r++) {\n const row = lonlatGrid[r] as any[];\n if (!Array.isArray(row) || row.length < cols) return null;\n for (let c = 0; c < cols; c++) {\n points[ptr++] = this._toLonLatPoint(row[c]);\n }\n }\n } else {\n points = (lonlatGrid as any[]).map((point) => this._toLonLatPoint(point));\n\n if (\n Array.isArray(this.props.shape) &&\n Number.isFinite(this.props.shape[0]) &&\n Number.isFinite(this.props.shape[1])\n ) {\n rows = Math.max(1, Math.floor(this.props.shape[0]));\n cols = Math.max(1, Math.floor(this.props.shape[1]));\n } else {\n rows = 1;\n cols = points.length;\n }\n\n const expectedLength = rows * cols;\n if (expectedLength <= 0 || points.length < expectedLength) return null;\n if (points.length !== expectedLength) {\n points = points.slice(0, expectedLength);\n }\n }\n\n return {\n points,\n rows,\n cols,\n gridKey: this._getGridCacheKey(points, rows, cols),\n };\n }\n\n _isFinitePoint(point: LonLatPoint | undefined): boolean {\n return (\n Array.isArray(point) &&\n point.length >= 2 &&\n Number.isFinite(point[0]) &&\n Number.isFinite(point[1])\n );\n }\n\n _adjustLonForBounds(lon: number, minLng: number, maxLng: number): number {\n if (!Number.isFinite(lon)) return lon;\n if (maxLng > 180 && lon < 0) {\n return lon + 360;\n }\n if (minLng < -180 && lon > 180) {\n return lon - 360;\n }\n return lon;\n }\n\n _buildMeshTriangles(grid: ResolvedGrid): TriangleIndices[] {\n const cacheKey = `${grid.gridKey}-triangles`;\n const cached = positionsCache.get(cacheKey);\n if (cached?.triangles) {\n return cached.triangles as TriangleIndices[];\n }\n\n const { points, rows, cols } = grid;\n const triangles: TriangleIndices[] = [];\n\n if (rows > 1 && cols > 1) {\n for (let r = 0; r < rows - 1; r++) {\n for (let c = 0; c < cols - 1; c++) {\n const i00 = r * cols + c;\n const i10 = i00 + 1;\n const i01 = (r + 1) * cols + c;\n const i11 = i01 + 1;\n\n if (\n !this._isFinitePoint(points[i00]) ||\n !this._isFinitePoint(points[i10]) ||\n !this._isFinitePoint(points[i01]) ||\n !this._isFinitePoint(points[i11])\n ) {\n continue;\n }\n\n const p00 = points[i00];\n const p10 = points[i10];\n const p01 = points[i01];\n const p11 = points[i11];\n\n const topLonStep = Math.abs(normalizeLonDelta(p00[0], p10[0]));\n const bottomLonStep = Math.abs(normalizeLonDelta(p01[0], p11[0]));\n if (topLonStep > 120 || bottomLonStep > 120) {\n continue;\n }\n\n triangles.push([i00, i10, i01]);\n triangles.push([i10, i11, i01]);\n }\n }\n } else if (points.length >= 3) {\n const flatPolygon: number[] = [];\n let hasInvalidPoint = false;\n for (const point of points) {\n if (!this._isFinitePoint(point)) {\n hasInvalidPoint = true;\n break;\n }\n flatPolygon.push(point[0], point[1]);\n }\n\n if (!hasInvalidPoint) {\n const earcutIndices = earcut(flatPolygon);\n for (let i = 0; i + 2 < earcutIndices.length; i += 3) {\n triangles.push([\n earcutIndices[i],\n earcutIndices[i + 1],\n earcutIndices[i + 2],\n ]);\n }\n }\n }\n\n addToCache(cacheKey, { triangles });\n return triangles;\n }\n\n _getWindTextureSize(\n rows: number,\n cols: number,\n pointCount: number,\n lonSpan: number,\n latSpan: number,\n ): { width: number; height: number } {\n if (rows > 1 && cols > 1) {\n return {\n width: clamp(Math.round(cols), 64, 2048),\n height: clamp(Math.round(rows), 64, 2048),\n };\n }\n\n const base = clamp(Math.round(Math.sqrt(Math.max(1, pointCount)) * 8), 64, 1024);\n const aspect = lonSpan > 0 && latSpan > 0 ? lonSpan / latSpan : 1;\n const width = clamp(Math.round(base * Math.sqrt(aspect)), 64, 2048);\n const height = clamp(Math.round(base / Math.sqrt(aspect)), 64, 2048);\n return { width, height };\n }\n\n _createTrailLines() {\n const { numParticles, maxAge = 50, trailLength = 22 } = this.props;\n const effectiveTrailLength = Math.min(trailLength, maxAge);\n const trailLines = [];\n\n for (let particleId = 0; particleId < numParticles; particleId++) {\n for (let age = 0; age < effectiveTrailLength - 1; age++) {\n const sourceIndex = particleId + age * numParticles;\n const targetIndex = particleId + (age + 1) * numParticles;\n\n trailLines.push({\n sourcePosition: [0, 0, 0],\n targetPosition: [0, 0, 0],\n sourceIndex,\n targetIndex,\n age,\n particleId,\n });\n }\n }\n\n return trailLines;\n }\n\n _getDataFingerprint(dataDir: any, dataMag: any): string {\n // Create a fingerprint by hashing sampled values from both arrays\n // Samples start, middle, end to detect changes without expensive full-array hashing\n const sampleArray = (arr: any) => {\n if (!arr?.length) return '0';\n const len = arr.length;\n return `${len}-${arr[0]}-${arr[Math.floor(len / 2)]}-${arr[len - 1]}`;\n };\n\n const sample = `${sampleArray(dataDir)}|${sampleArray(dataMag)}`;\n let hash = 0;\n for (let i = 0; i < sample.length; i++) {\n hash = (hash << 5) - hash + sample.charCodeAt(i);\n hash |= 0;\n }\n return hash.toString();\n }\n\n _createWindTexture() {\n const { dataDir, dataMag } = this.props;\n const grid = this._resolveGrid();\n if (!grid) {\n return null;\n }\n\n const { points, rows, cols, gridKey } = grid;\n\n // Include data fingerprint in cache key to distinguish different datasets with same grid\n const dataFingerprint = this._getDataFingerprint(dataDir, dataMag);\n const textureKey = `${gridKey}-${dataFingerprint}-texture`;\n const cachedTexture = positionsCache.get(textureKey);\n\n if (cachedTexture?.texture) {\n return cachedTexture.texture as Texture;\n }\n\n const bounds = this._getBoundsFromGrid(points, gridKey);\n const { minLng, minLat, maxLng, maxLat } = bounds;\n const lonSpan = Math.max(1e-6, maxLng - minLng);\n const latSpan = Math.max(1e-6, maxLat - minLat);\n const { width, height } = this._getWindTextureSize(\n rows,\n cols,\n points.length,\n lonSpan,\n latSpan,\n );\n\n const scratchKey = `scratch-${width}x${height}`;\n let uvData: Float32Array =\n positionsCache.get(scratchKey)?.uvData || new Float32Array(width * height * 4);\n if (!positionsCache.has(scratchKey)) {\n addToCache(scratchKey, { uvData });\n }\n uvData.fill(0);\n\n const noiseScale = 0.02;\n\n const globalData = isGlobalData([minLng, minLat, maxLng, maxLat]);\n\n const texNoise = (x: number, y: number) =>\n (Math.sin(x * 12.9898 + y * 78.233) * 43758.5453) % 1;\n\n const triangles = this._buildMeshTriangles(grid);\n\n // Project mesh vertices into texture pixel space and keep per-vertex wind vectors.\n const pointX = new Float32Array(points.length);\n const pointY = new Float32Array(points.length);\n const windU = new Float32Array(points.length);\n const windV = new Float32Array(points.length);\n const pointValid = new Uint8Array(points.length);\n\n for (let i = 0; i < points.length; i++) {\n const point = points[i];\n if (!this._isFinitePoint(point)) {\n pointX[i] = NaN;\n pointY[i] = NaN;\n continue;\n }\n\n const lon = this._adjustLonForBounds(point[0], minLng, maxLng);\n const lat = point[1];\n pointX[i] = ((lon - minLng) / lonSpan) * (width - 1);\n pointY[i] = ((maxLat - lat) / latSpan) * (height - 1);\n\n const wdirection = Number(dataDir?.[i]);\n const wmagnitude = Number(dataMag?.[i]);\n if (Number.isFinite(wdirection) && Number.isFinite(wmagnitude) && wmagnitude >= 0) {\n const [u, v] = directionToUV(wdirection, wmagnitude);\n windU[i] = u;\n windV[i] = v;\n pointValid[i] = 1;\n }\n }\n\n const baryEpsilon = 1e-4;\n for (let t = 0; t < triangles.length; t++) {\n const [i0, i1, i2] = triangles[t];\n if (!pointValid[i0] || !pointValid[i1] || !pointValid[i2]) {\n continue;\n }\n\n const x0 = pointX[i0];\n const y0 = pointY[i0];\n const x1 = pointX[i1];\n const y1 = pointY[i1];\n const x2 = pointX[i2];\n const y2 = pointY[i2];\n\n if (\n !Number.isFinite(x0) ||\n !Number.isFinite(y0) ||\n !Number.isFinite(x1) ||\n !Number.isFinite(y1) ||\n !Number.isFinite(x2) ||\n !Number.isFinite(y2)\n ) {\n continue;\n }\n\n const denom = (y1 - y2) * (x0 - x2) + (x2 - x1) * (y0 - y2);\n if (!Number.isFinite(denom) || Math.abs(denom) < 1e-8) {\n continue;\n }\n\n const minX = clamp(Math.floor(Math.min(x0, x1, x2)), 0, width - 1);\n const maxX = clamp(Math.ceil(Math.max(x0, x1, x2)), 0, width - 1);\n const minY = clamp(Math.floor(Math.min(y0, y1, y2)), 0, height - 1);\n const maxY = clamp(Math.ceil(Math.max(y0, y1, y2)), 0, height - 1);\n\n for (let y = minY; y <= maxY; y++) {\n for (let x = minX; x <= maxX; x++) {\n const px = x + 0.5;\n const py = y + 0.5;\n\n const w0 = ((y1 - y2) * (px - x2) + (x2 - x1) * (py - y2)) / denom;\n const w1 = ((y2 - y0) * (px - x2) + (x0 - x2) * (py - y2)) / denom;\n const w2 = 1 - w0 - w1;\n\n if (w0 < -baryEpsilon || w1 < -baryEpsilon || w2 < -baryEpsilon) {\n continue;\n }\n\n const o = (y * width + x) * 4;\n uvData[o] = w0 * windU[i0] + w1 * windU[i1] + w2 * windU[i2];\n uvData[o + 1] = w0 * windV[i0] + w1 * windV[i1] + w2 * windV[i2];\n uvData[o + 2] = 0;\n uvData[o + 3] = 1;\n }\n }\n }\n\n // Add subtle deterministic turbulence only where the mesh has valid data coverage.\n for (let y = 0; y < height; y++) {\n for (let x = 0; x < width; x++) {\n const o = (y * width + x) * 4;\n if (uvData[o + 3] < 0.5) {\n continue;\n }\n uvData[o] += (texNoise(x * 0.1, y * 0.1) - 0.5) * noiseScale;\n uvData[o + 1] += (texNoise(x * 0.1 + 100, y * 0.1 + 100) - 0.5) * noiseScale;\n }\n }\n\n const texture = this.context.device.createTexture({\n width,\n height,\n data: uvData,\n format: 'rgba32float',\n sampler: {\n minFilter: 'linear',\n magFilter: 'linear',\n addressModeU: globalData ? 'repeat' : 'clamp-to-edge',\n addressModeV: 'clamp-to-edge',\n },\n });\n\n addToCache(textureKey, { texture });\n return texture;\n }\n\n _getBoundsFromGrid(points: LonLatPoint[], gridKey: string) {\n const cacheKey = `${gridKey}-bounds`;\n const cached = positionsCache.get(cacheKey);\n if (cached?.bounds) return cached.bounds;\n\n let maxLng = -Infinity,\n minLng = Infinity,\n maxLat = -Infinity,\n minLat = Infinity;\n\n for (const pair of points) {\n const [longitude, latitude] = pair;\n if (!Number.isFinite(longitude) || !Number.isFinite(latitude)) {\n continue;\n }\n if (longitude > maxLng) maxLng = longitude;\n if (longitude < minLng) minLng = longitude;\n if (latitude > maxLat) maxLat = latitude;\n if (latitude < minLat) minLat = latitude;\n }\n\n if (\n !Number.isFinite(minLng) ||\n !Number.isFinite(maxLng) ||\n !Number.isFinite(minLat) ||\n !Number.isFinite(maxLat)\n ) {\n minLng = -180;\n maxLng = 180;\n minLat = -90;\n maxLat = 90;\n }\n\n const bounds = { maxLng, minLng, maxLat, minLat };\n addToCache(cacheKey, { bounds });\n return bounds;\n }\n\n _setupState() {\n const grid = this._resolveGrid();\n const { minLng, minLat, maxLng, maxLat } = grid\n ? this._getBoundsFromGrid(grid.points, grid.gridKey)\n : { minLng: -180, minLat: -90, maxLng: 180, maxLat: 90 };\n\n let calculatedBounds = [minLng, minLat, maxLng, maxLat];\n\n if (isNaN(minLng) || isNaN(maxLng) || isNaN(minLat) || isNaN(maxLat)) {\n calculatedBounds = [-180, -90, 180, 90];\n }\n\n const globalData = isGlobalData(calculatedBounds);\n\n this.setState({\n bounds: calculatedBounds,\n trailLines: this._createTrailLines(),\n isGlobalData: globalData,\n });\n\n this._setupTransformFeedback();\n }\n\n updateState(params: UpdateParameters<this>) {\n super.updateState(params);\n const { props, oldProps } = params;\n\n // Check if color changed (only after initialization to avoid spurious rebuilds)\n const colorChanged =\n this.state.initialized &&\n oldProps.color &&\n (props.color[0] !== oldProps.color[0] ||\n props.color[1] !== oldProps.color[1] ||\n props.color[2] !== oldProps.color[2] ||\n props.color[3] !== oldProps.color[3]);\n\n // Structure changes require full buffer recreation\n const structureChanged =\n props.numParticles !== oldProps.numParticles ||\n props.maxAge !== oldProps.maxAge ||\n props.width !== oldProps.width ||\n props.trailLength !== oldProps.trailLength ||\n colorChanged;\n\n // Data changes only need texture update - preserve particle positions!\n const dataChanged =\n props.image !== oldProps.image ||\n props.dataDir !== oldProps.dataDir ||\n props.dataMag !== oldProps.dataMag ||\n props.lonlatGrid !== oldProps.lonlatGrid ||\n props.shape !== oldProps.shape;\n\n if (structureChanged) {\n this._setupState();\n } else if (dataChanged && this.state.initialized) {\n this._updateWindTexture();\n }\n }\n\n finalizeState(context: LayerContext) {\n this._deleteTransformFeedback();\n super.finalizeState(context);\n }\n\n _updateWindTexture() {\n const { dataDir, dataMag } = this.props;\n const grid = this._resolveGrid();\n if (!grid) {\n return;\n }\n\n const { points, gridKey } = grid;\n\n const { minLng, minLat, maxLng, maxLat } = this._getBoundsFromGrid(points, gridKey);\n let calculatedBounds = [minLng, minLat, maxLng, maxLat];\n if (isNaN(minLng) || isNaN(maxLng) || isNaN(minLat) || isNaN(maxLat)) {\n calculatedBounds = [-180, -90, 180, 90];\n }\n const globalData = isGlobalData(calculatedBounds);\n\n // Clear the cached texture so _createWindTexture builds a fresh one with new data\n const dataFingerprint = this._getDataFingerprint(dataDir, dataMag);\n const textureKey = `${gridKey}-${dataFingerprint}-texture`;\n const cachedEntry = positionsCache.get(textureKey);\n if (cachedEntry?.texture) {\n cachedEntry.texture.destroy();\n positionsCache.delete(textureKey);\n }\n\n const oldTexture = this.state.texture;\n if (oldTexture && oldTexture !== this.props.image && oldTexture !== cachedEntry?.texture) {\n oldTexture.destroy();\n }\n\n // Create new wind texture from updated data\n const newTexture = this.props.image || this._createWindTexture();\n if (newTexture && typeof newTexture !== 'string') {\n this.setState({\n texture: newTexture,\n bounds: calculatedBounds,\n isGlobalData: globalData,\n });\n }\n }\n\n _getEffectiveBounds() {\n const cacheKey = this.props.bounds?.join('-') || 'state';\n if (this.boundsCache?.key === cacheKey) {\n return this.boundsCache.bounds;\n }\n\n let bounds: number[];\n if (this.state?.bounds) {\n bounds = this.state.bounds;\n } else if (this.props.bounds && this.props.bounds.length === 4) {\n bounds = this.props.bounds;\n } else {\n bounds = [-180, -90, 180, 90];\n }\n\n this.boundsCache = { key: cacheKey, bounds };\n return bounds;\n }\n\n private _lastStepFrame = -1;\n\n draw({ uniforms }: { uniforms: any }) {\n if (!this.state.initialized) return;\n\n const { model, sourcePositions, targetPositions, colors, needsAttributeBind } = this.state;\n\n // Verify buffers exist before drawing (prevents errors during layer transitions)\n if (!sourcePositions || !targetPositions || !colors) return;\n\n // Only step once per frame (prevents multiple updates in multi-panel setups)\n const currentFrame = Math.floor(performance.now());\n if (this.props.animate && currentFrame !== this._lastStepFrame) {\n this._lastStepFrame = currentFrame;\n this.step();\n }\n\n if (model && needsAttributeBind) {\n if (this._widths[0] !== this.props.width) {\n this._widths[0] = this.props.width;\n }\n\n // Trail segments connect consecutive ages:\n // - sourcePositions contains: [age0, age1, age2, ...]\n // - targetPositions contains: [age1, age2, age3, ...] (copied in _runTransformFeedback)\n // This creates line segments: age0→age1, age1→age2, etc.\n model.setAttributes?.({\n instanceSourcePositions: sourcePositions,\n instanceTargetPositions: targetPositions,\n instanceColors: colors,\n });\n model.setConstantAttributes?.({\n instanceSourcePositions64Low: this._sourcePositions64Low,\n instanceTargetPositions64Low: this._targetPositions64Low,\n instancePickingColors: this._pickingColors,\n instanceWidths: this._widths,\n });\n\n this.state.needsAttributeBind = false;\n }\n\n super.draw({ uniforms });\n }\n\n _setupTransformFeedback() {\n if (this.state.initialized) {\n this._deleteTransformFeedback();\n }\n\n const { numParticles, color, maxAge, trailLength = 22 } = this.props;\n\n const texture = this.props.image || this._createWindTexture();\n if (!texture || typeof texture === 'string') {\n return;\n }\n\n const numInstances = numParticles * maxAge;\n const numAgedInstances = numParticles * (maxAge - 1);\n const effectiveTrailLength = Math.min(trailLength, maxAge);\n const numTrailSegments = numParticles * (effectiveTrailLength - 1);\n\n const sourcePositions = this.context.device.createBuffer(\n new Float32Array(numInstances * 3),\n );\n const targetPositions = this.context.device.createBuffer(\n new Float32Array(numInstances * 3),\n );\n\n // Create offset buffer for target positions - starts at age 1 (one row offset)\n // This allows trail segments to connect age N to age N+1 from the same buffer\n const targetPositionsOffset = this.context.device.createBuffer({\n byteLength: (numInstances - numParticles) * 3 * 4,\n });\n\n // Create noise texture using shared data (computed once, reused by all layers)\n const noiseSize = 256;\n const noiseTexture = this.context.device.createTexture({\n width: noiseSize,\n height: noiseSize,\n data: getSharedNoiseData(),\n format: 'rgba32float',\n sampler: {\n minFilter: 'linear',\n magFilter: 'linear',\n addressModeU: 'repeat',\n addressModeV: 'repeat',\n },\n });\n\n // Create color buffer with uniform alpha - the shader handles age-based fading\n const colorsArr = new Uint8Array(numInstances * 4);\n const r = color[0] as number;\n const g = color[1] as number;\n const b = color[2] as number;\n const baseAlpha = (color[3] ?? 255) as number;\n for (let i = 0; i < numInstances; i++) {\n const o = i * 4;\n colorsArr[o] = r;\n colorsArr[o + 1] = g;\n colorsArr[o + 2] = b;\n colorsArr[o + 3] = baseAlpha; // Uniform alpha, shader applies age fade\n }\n const colorBuffer = this.context.device.createBuffer({ data: colorsArr });\n\n const transform = new BufferTransform(this.context.device, {\n attributes: { sourcePosition: sourcePositions },\n bufferLayout: [{ name: 'sourcePosition', format: 'float32x3' }],\n feedbackBuffers: { targetPosition: targetPositions },\n vs: shader,\n varyings: ['targetPosition'],\n modules: [bitmapUniforms],\n vertexCount: numParticles,\n });\n\n const zeroPositions = new Float32Array(numInstances * 3);\n\n this.setState({\n initialized: true,\n numInstances,\n numAgedInstances,\n numTrailSegments,\n sourcePositions,\n targetPositions,\n colors: colorBuffer,\n transform,\n texture,\n noiseTexture,\n previousViewportZoom: 0,\n previousTime: 0,\n needsAttributeBind: true,\n uniformHolder: { bitmap: {} },\n zeroPositions,\n ringBufferIndex: 0,\n });\n\n // Bind attributes immediately to avoid \"no buffer bound\" error on first draw\n const { model } = this.state;\n if (model) {\n model.setAttributes?.({\n instanceSourcePositions: sourcePositions,\n instanceTargetPositions: targetPositions,\n instanceColors: colorBuffer,\n });\n model.setConstantAttributes?.({\n instanceSourcePositions64Low: this._sourcePositions64Low,\n instanceTargetPositions64Low: this._targetPositions64Low,\n instancePickingColors: this._pickingColors,\n instanceWidths: this._widths,\n });\n }\n }\n\n _runTransformFeedback() {\n if (!this.state.initialized) return;\n\n const { transform, sourcePositions, targetPositions, texture, noiseTexture } = this.state;\n // Verify resources exist before running transform\n if (!transform || !sourcePositions || !targetPositions || !texture || !noiseTexture) return;\n\n const { viewport } = this.context as any;\n const { numParticles, speedFactor, maxAge } = this.props;\n const { previousTime, previousViewportZoom, numAgedInstances, ringBufferIndex } =\n this.state;\n\n // Use performance.now() instead of timeline.getTime() for continuous animation\n // timeline.getTime() only advances when deck.gl animations are active\n const currentTime = performance.now();\n\n if (currentTime === previousTime) return;\n\n const isGlobe = viewport?.projection?.mode === 'globe' ? 1 : 0;\n const bounds = this._getEffectiveBounds();\n\n let viewportCenter: [number, number];\n let viewportZoomChangeFactor: number;\n let cullBackside = 0;\n\n const lng = viewport?.longitude ?? 0;\n const lat = viewport?.latitude ?? 0;\n\n // Proper modulo handling for negative numbers\n const normalizedLng = ((((lng + 180) % 360) + 360) % 360) - 180;\n viewportCenter = [normalizedLng, lat];\n\n const viewportGlobeRadius = getViewportGlobeRadius(viewport);\n const viewportBounds = getViewportBounds(viewport);\n\n viewportZoomChangeFactor = Math.max(\n 1.0,\n Math.pow(2, (previousViewportZoom - viewport.zoom) * 1.5),\n );\n\n cullBackside = isGlobe > 0 ? 1 : 0;\n\n const speedVariation = 0.95 + 0.1 * Math.sin(currentTime * 0.001);\n let currentSpeedFactor: number;\n currentSpeedFactor = (speedFactor * speedVariation) / (700 + Math.pow(1.9, viewport.zoom +6));\n \n\n const seed = Math.sin(currentTime * 0.0001) * 999 + Math.cos(currentTime * 0.00013) * 777;\n\n const u = (this.state.uniformHolder!.bitmap ||= {});\n u.bitmapTexture = texture;\n u.noiseTexture = noiseTexture;\n u.viewportBounds = viewportBounds;\n u.viewportZoomChangeFactor = viewportZoomChangeFactor;\n u.bounds = bounds;\n u.viewportCenter = viewportCenter;\n u.cullBackside = cullBackside;\n u.numParticles = numParticles;\n u.maxAge = maxAge;\n u.speedFactor = currentSpeedFactor;\n u.time = currentTime;\n u.seed = Math.abs(seed);\n u.isGlobe = isGlobe;\n u.viewportGlobeRadius = viewportGlobeRadius;\n u.minWindSpeed = 1.5; // 3 knots ≈ 1.54 m/s, drop particles in calm areas\n u.ringBufferIndex = ringBufferIndex;\n\n if (!transform?.model) return;\n\n try {\n transform.model.shaderInputs?.setProps?.({ bitmap: u });\n\n transform.run({\n clearColor: false,\n clearDepth: false,\n clearStencil: false,\n depthReadOnly: true,\n stencilReadOnly: true,\n });\n } catch (e) {\n console.warn('ParticleLayer transform error:', e);\n return;\n }\n\n try {\n // Shift aged positions down by one \"age row\"\n const encoder = this.context.device.createCommandEncoder();\n encoder.copyBufferToBuffer({\n sourceBuffer: sourcePositions,\n sourceOffset: 0,\n destinationBuffer: targetPositions,\n destinationOffset: numParticles * 4 * 3,\n size: numAgedInstances * 4 * 3,\n });\n const commandBuffer = encoder.finish();\n this.context.device.submit(commandBuffer);\n encoder.destroy();\n\n // Swap\n this.state.sourcePositions = targetPositions;\n this.state.targetPositions = sourcePositions;\n transform.model.setAttributes({ sourcePosition: targetPositions });\n transform.transformFeedback.setBuffers({ targetPosition: sourcePositions });\n\n // After swap, sourcePositions (was targetPositions) contains: [age0, age1, age2, ...]\n // For trail rendering, we need targetPositions to contain: [age1, age2, age3, ...]\n // Copy age-1-and-later from sourcePositions into targetPositions at offset 0\n const { numTrailSegments } = this.state;\n const encoder2 = this.context.device.createCommandEncoder();\n encoder2.copyBufferToBuffer({\n sourceBuffer: this.state.sourcePositions,\n sourceOffset: numParticles * 3 * 4, // Start at age 1\n destinationBuffer: this.state.targetPositions,\n destinationOffset: 0,\n size: numTrailSegments * 3 * 4, // Copy enough for trail segments\n });\n const commandBuffer2 = encoder2.finish();\n this.context.device.submit(commandBuffer2);\n encoder2.destroy();\n } catch (e) {\n console.warn('ParticleLayer buffer copy error:', e);\n return;\n }\n\n // Mark bindings dirty for draw()\n this.state.needsAttributeBind = true;\n\n this.state.previousViewportZoom = viewport.zoom;\n this.state.previousTime = currentTime;\n }\n\n _resetTransformFeedback() {\n if (!this.state.initialized) return;\n const { sourcePositions, targetPositions, zeroPositions } = this.state;\n if (zeroPositions) {\n sourcePositions.write(zeroPositions);\n targetPositions.write(zeroPositions);\n this.state.needsAttributeBind = true;\n }\n }\n\n _deleteTransformFeedback() {\n if (!this.state.initialized) return;\n\n // Clear initialized first to prevent draw() from using deleted resources\n this.setState({ initialized: false });\n\n const { sourcePositions, targetPositions, colors, transform, texture, noiseTexture } =\n this.state;\n sourcePositions?.destroy();\n targetPositions?.destroy();\n colors?.destroy();\n transform?.destroy();\n noiseTexture?.destroy();\n\n if (texture && texture !== this.props.image) {\n // Only destroy texture if it's NOT in the cache (other layers may be using it)\n let isInCache = false;\n for (const [key, value] of positionsCache.entries()) {\n if (value.texture === texture) {\n isInCache = true;\n break;\n }\n }\n if (!isInCache) {\n texture.destroy();\n }\n }\n\n // Clear references to destroyed resources (but NOT model - it's managed by parent LineLayer)\n this.setState({\n sourcePositions: null,\n targetPositions: null,\n colors: null,\n transform: null,\n noiseTexture: null,\n });\n }\n\n step() {\n this._runTransformFeedback();\n this.setNeedsRedraw();\n }\n\n clear() {\n this._resetTransformFeedback();\n this.setNeedsRedraw();\n }\n}\n\nParticleLayer.layerName = 'ParticleLayer';\nParticleLayer.defaultProps = defaultProps;\n","\nconst ARRAY_TYPES = [\n Int8Array, Uint8Array, Uint8ClampedArray, Int16Array, Uint16Array,\n Int32Array, Uint32Array, Float32Array, Float64Array\n];\n\n/** @typedef {Int8ArrayConstructor | Uint8ArrayConstructor | Uint8ClampedArrayConstructor | Int16ArrayConstructor | Uint16ArrayConstructor | Int32ArrayConstructor | Uint32ArrayConstructor | Float32ArrayConstructor | Float64ArrayConstructor} TypedArrayConstructor */\n/** @typedef {Int8Array | Uint8Array | Uint8ClampedArray | Int16Array | Uint16Array | Int32Array | Uint32Array | Float32Array | Float64Array} TypedArray */\n\nconst VERSION = 1; // serialized format version\nconst HEADER_SIZE = 8;\n\n// Shared scratch stack for iterative DFS in range/within. Sized for the worst case:\n// 3 ints per frame * (treeHeight + 1), with treeHeight ≤ ceil(log2(2^32 / 3)) ≈ 31.\nconst STACK = new Uint32Array(96);\n\nexport default class KDBush {\n\n /**\n * Creates an index from raw `ArrayBuffer` data.\n * @param {ArrayBufferLike} data\n */\n static from(data) {\n // @ts-expect-error duck typing array buffers\n if (!data || data.byteLength === undefined || data.buffer) {\n throw new Error('Data must be an instance of ArrayBuffer or SharedArrayBuffer.');\n }\n const [magic, versionAndType] = new Uint8Array(data, 0, 2);\n if (magic !== 0xdb) {\n throw new Error('Data does not appear to be in a KDBush format.');\n }\n const version = versionAndType >> 4;\n if (version !== VERSION) {\n throw new Error(`Got v${version} data when expected v${VERSION}.`);\n }\n const ArrayType = ARRAY_TYPES[versionAndType & 0x0f];\n if (!ArrayType) {\n throw new Error('Unrecognized array type.');\n }\n const [nodeSize] = new Uint16Array(data, 2, 1);\n const [numItems] = new Uint32Array(data, 4, 1);\n\n return new KDBush(numItems, nodeSize, ArrayType, undefined, data);\n }\n\n /**\n * Creates an index that will hold a given number of items.\n * @param {number} numItems\n * @param {number} [nodeSize=64] Size of the KD-tree node (64 by default).\n * @param {TypedArrayConstructor} [ArrayType=Float64Array] The array type used for coordinates storage (`Float64Array` by default).\n * @param {ArrayBufferConstructor | SharedArrayBufferConstructor} [ArrayBufferType=ArrayBuffer] The array buffer type used for storage (`ArrayBuffer` by default).\n * @param {ArrayBufferLike} [data] (For internal use only)\n */\n constructor(numItems, nodeSize = 64, ArrayType = Float64Array, ArrayBufferType = ArrayBuffer, data) {\n if (isNaN(numItems) || numItems < 0) throw new Error(`Unexpected numItems value: ${numItems}.`);\n\n this.numItems = +numItems;\n this.nodeSize = Math.min(Math.max(+nodeSize, 2), 65535);\n this.ArrayType = ArrayType;\n this.IndexArrayType = numItems < 65536 ? Uint16Array : Uint32Array;\n\n const arrayTypeIndex = ARRAY_TYPES.indexOf(this.ArrayType);\n const coordsByteSize = numItems * 2 * this.ArrayType.BYTES_PER_ELEMENT;\n const idsByteSize = numItems * this.IndexArrayType.BYTES_PER_ELEMENT;\n const padCoords = (8 - idsByteSize % 8) % 8;\n\n if (arrayTypeIndex < 0) {\n throw new Error(`Unexpected typed array class: ${ArrayType}.`);\n }\n\n if (data) { // reconstruct an index from a buffer\n this.data = data;\n // @ts-expect-error TS can't handle SharedArrayBuffer overloads\n this.ids = new this.IndexArrayType(data, HEADER_SIZE, numItems);\n // @ts-expect-error TS can't handle SharedArrayBuffer overloads\n this.coords = new ArrayType(data, HEADER_SIZE + idsByteSize + padCoords, numItems * 2);\n this._pos = numItems * 2;\n this._finished = true;\n\n } else { // initialize a new index\n const data = this.data = new ArrayBufferType(HEADER_SIZE + coordsByteSize + idsByteSize + padCoords);\n // @ts-expect-error TS can't handle SharedArrayBuffer overloads\n this.ids = new this.IndexArrayType(data, HEADER_SIZE, numItems);\n // @ts-expect-error TS can't handle SharedArrayBuffer overloads\n this.coords = new ArrayType(data, HEADER_SIZE + idsByteSize + padCoords, numItems * 2);\n this._pos = 0;\n this._finished = false;\n\n // set header\n new Uint8Array(data, 0, 2).set([0xdb, (VERSION << 4) + arrayTypeIndex]);\n new Uint16Array(data, 2, 1)[0] = nodeSize;\n new Uint32Array(data, 4, 1)[0] = numItems;\n }\n }\n\n /**\n * Add a point to the index.\n * @param {number} x\n * @param {number} y\n * @returns {number} An incremental index associated with the added item (starting from `0`).\n */\n add(x, y) {\n const index = this._pos >> 1;\n this.ids[index] = index;\n this.coords[this._pos++] = x;\n this.coords[this._pos++] = y;\n return index;\n }\n\n /**\n * Perform indexing of the added points.\n */\n finish() {\n const numAdded = this._pos >> 1;\n if (numAdded !== this.numItems) {\n throw new Error(`Added ${numAdded} items when expected ${this.numItems}.`);\n }\n // kd-sort both arrays for efficient search\n sort(this.ids, this.coords, this.nodeSize, 0, this.numItems - 1, 0);\n\n this._finished = true;\n return this;\n }\n\n /**\n * Search the index for items within a given bounding box.\n * @param {number} minX\n * @param {number} minY\n * @param {number} maxX\n * @param {number} maxY\n * @returns {number[]} An array of indices correponding to the found items.\n */\n range(minX, minY, maxX, maxY) {\n if (!this._finished) throw new Error('Data not yet indexed - call index.finish().');\n\n const {ids, coords, nodeSize} = this;\n STACK[0] = 0;\n STACK[1] = ids.length - 1;\n STACK[2] = 0;\n let sp = 3;\n const result = [];\n\n // recursively search for items in range in the kd-sorted arrays\n while (sp > 0) {\n const axis = STACK[--sp];\n const right = STACK[--sp];\n const left = STACK[--sp];\n\n // if we reached \"tree node\", search linearly\n if (right - left <= nodeSize) {\n for (let i = left; i <= right; i++) {\n const x = coords[2 * i];\n const y = coords[2 * i + 1];\n if (x >= minX && x <= maxX && y >= minY && y <= maxY) result.push(ids[i]);\n }\n continue;\n }\n\n // otherwise find the middle index\n const m = (left + right) >> 1;\n\n // include the middle item if it's in range\n const x = coords[2 * m];\n const y = coords[2 * m + 1];\n if (x >= minX && x <= maxX && y >= minY && y <= maxY) result.push(ids[m]);\n\n // queue search in halves that intersect the query\n if (axis === 0 ? minX <= x : minY <= y) {\n STACK[sp++] = left;\n STACK[sp++] = m - 1;\n STACK[sp++] = 1 - axis;\n }\n if (axis === 0 ? maxX >= x : maxY >= y) {\n STACK[sp++] = m + 1;\n STACK[sp++] = right;\n STACK[sp++] = 1 - axis;\n }\n }\n\n return result;\n }\n\n /**\n * Search the index for items within a given radius.\n * @param {number} qx\n * @param {number} qy\n * @param {number} r Query radius.\n * @returns {number[]} An array of indices correponding to the found items.\n */\n within(qx, qy, r) {\n const result = /** @type {number[]} */ ([]);\n this.withinInto(qx, qy, r, result);\n return result;\n }\n\n /**\n * Search the index for items within a given radius, writing matching ids into `out`\n * via indexed assignment (`out[i] = id`). Accepts any indexed-writable container —\n * a typed array sized to the expected upper bound (allocation-free, fast) or a plain\n * `Array` (which will grow as needed). Returns the number of matches written.\n * @param {number} qx\n * @param {number} qy\n * @param {number} r Query radius.\n * @param {number[] | TypedArray} out Container to write matching ids into.\n * @returns {number} The number of matches written to `out`.\n */\n withinInto(qx, qy, r, out) {\n if (!this._finished) throw new Error('Data not yet indexed - call index.finish().');\n\n const {ids, coords, nodeSize} = this;\n STACK[0] = 0;\n STACK[1] = ids.length - 1;\n STACK[2] = 0;\n let sp = 3;\n let count = 0;\n const r2 = r * r;\n\n // recursively search for items within radius in the kd-sorted arrays\n while (sp > 0) {\n const axis = STACK[--sp];\n const right = STACK[--sp];\n const left = STACK[--sp];\n\n // if we reached \"tree node\", search linearly\n if (right - left <= nodeSize) {\n for (let i = left; i <= right; i++) {\n if (sqDist(coords[2 * i], coords[2 * i + 1], qx, qy) <= r2) out[count++] = ids[i];\n }\n continue;\n }\n\n // otherwise find the middle index\n const m = (left + right) >> 1;\n\n // include the middle item if it's in range\n const x = coords[2 * m];\n const y = coords[2 * m + 1];\n if (sqDist(x, y, qx, qy) <= r2) out[count++] = ids[m];\n\n // queue search in halves that intersect the query\n if (axis === 0 ? qx - r <= x : qy - r <= y) {\n STACK[sp++] = left;\n STACK[sp++] = m - 1;\n STACK[sp++] = 1 - axis;\n }\n if (axis === 0 ? qx + r >= x : qy + r >= y) {\n STACK[sp++] = m + 1;\n STACK[sp++] = right;\n STACK[sp++] = 1 - axis;\n }\n }\n\n return count;\n }\n}\n\n/**\n * @param {Uint16Array | Uint32Array} ids\n * @param {TypedArray} coords\n * @param {number} nodeSize\n * @param {number} left\n * @param {number} right\n * @param {number} axis\n */\nfunction sort(ids, coords, nodeSize, left, right, axis) {\n if (right - left <= nodeSize) return;\n\n const m = (left + right) >> 1; // middle index\n\n // sort ids and coords around the middle index so that the halves lie\n // either left/right or top/bottom correspondingly (taking turns)\n select(ids, coords, m, left, right, axis);\n\n // recursively kd-sort first half and second half on the opposite axis\n sort(ids, coords, nodeSize, left, m - 1, 1 - axis);\n sort(ids, coords, nodeSize, m + 1, right, 1 - axis);\n}\n\n/**\n * Custom Floyd-Rivest selection algorithm: sort ids and coords so that\n * [left..k-1] items are smaller than k-th item (on either x or y axis)\n * @param {Uint16Array | Uint32Array} ids\n * @param {TypedArray} coords\n * @param {number} k\n * @param {number} left\n * @param {number} right\n * @param {number} axis\n */\nfunction select(ids, coords, k, left, right, axis) {\n\n while (right > left) {\n if (right - left > 600) {\n const n = right - left + 1;\n const m = k - left + 1;\n const z = Math.log(n);\n const s = 0.5 * Math.exp(2 * z / 3);\n const sd = 0.5 * Math.sqrt(z * s * (n - s) / n) * (m - n / 2 < 0 ? -1 : 1);\n const newLeft = Math.max(left, Math.floor(k - m * s / n + sd));\n const newRight = Math.min(right, Math.floor(k + (n - m) * s / n + sd));\n select(ids, coords, k, newLeft, newRight, axis);\n }\n\n const t = coords[2 * k + axis];\n let i = left;\n let j = right;\n\n swapItem(ids, coords, left, k);\n if (coords[2 * right + axis] > t) swapItem(ids, coords, left, right);\n\n while (i < j) {\n swapItem(ids, coords, i, j);\n i++;\n j--;\n while (coords[2 * i + axis] < t) i++;\n while (coords[2 * j + axis] > t) j--;\n }\n\n if (coords[2 * left + axis] === t) swapItem(ids, coords, left, j);\n else {\n j++;\n swapItem(ids, coords, j, right);\n }\n\n if (j <= k) left = j + 1;\n if (k <= j) right = j - 1;\n }\n}\n\n/**\n * @param {Uint16Array | Uint32Array} ids\n * @param {TypedArray} coords\n * @param {number} i\n * @param {number} j\n */\nfunction swapItem(ids, coords, i, j) {\n swap(ids, i, j);\n swap(coords, 2 * i, 2 * j);\n swap(coords, 2 * i + 1, 2 * j + 1);\n}\n\n/**\n * @param {TypedArray} arr\n * @param {number} i\n * @param {number} j\n */\nfunction swap(arr, i, j) {\n const tmp = arr[i];\n arr[i] = arr[j];\n arr[j] = tmp;\n}\n\n/**\n * @param {number} ax\n * @param {number} ay\n * @param {number} bx\n * @param {number} by\n */\nfunction sqDist(ax, ay, bx, by) {\n const dx = ax - bx;\n const dy = ay - by;\n return dx * dx + dy * dy;\n}\n","\nimport KDBush from 'kdbush';\n\nconst defaultOptions = {\n minZoom: 0, // min zoom to generate clusters on\n maxZoom: 16, // max zoom level to cluster the points on\n minPoints: 2, // minimum points to form a cluster\n radius: 40, // cluster radius in pixels\n extent: 512, // tile extent (radius is calculated relative to it)\n nodeSize: 64, // size of the KD-tree leaf node, affects performance\n log: false, // whether to log timing info\n\n // whether to generate numeric ids for input features (in vector tiles)\n generateId: false,\n\n // a reduce function for calculating custom cluster properties\n reduce: null, // (accumulated, props) => { accumulated.sum += props.sum; }\n\n // properties to use for individual points when running the reducer\n map: props => props // props => ({sum: props.my_value})\n};\n\nconst fround = Math.fround || (tmp => ((x) => { tmp[0] = +x; return tmp[0]; }))(new Float32Array(1));\n\nconst OFFSET_ZOOM = 2;\nconst OFFSET_ID = 3;\nconst OFFSET_PARENT = 4;\nconst OFFSET_NUM = 5;\nconst OFFSET_PROP = 6;\n\nexport default class Supercluster {\n constructor(options) {\n this.options = Object.assign(Object.create(defaultOptions), options);\n this.trees = new Array(this.options.maxZoom + 1);\n this.stride = this.options.reduce ? 7 : 6;\n this.clusterProps = [];\n }\n\n load(points) {\n const {log, minZoom, maxZoom} = this.options;\n\n if (log) console.time('total time');\n\n const timerId = `prepare ${ points.length } points`;\n if (log) console.time(timerId);\n\n this.points = points;\n\n // generate a cluster object for each point and index input points into a KD-tree\n const data = [];\n\n for (let i = 0; i < points.length; i++) {\n const p = points[i];\n if (!p.geometry) continue;\n\n const [lng, lat] = p.geometry.coordinates;\n const x = fround(lngX(lng));\n const y = fround(latY(lat));\n // store internal point/cluster data in flat numeric arrays for performance\n data.push(\n x, y, // projected point coordinates\n Infinity, // the last zoom the point was processed at\n i, // index of the source feature in the original input array\n -1, // parent cluster id\n 1 // number of points in a cluster\n );\n if (this.options.reduce) data.push(0); // noop\n }\n let tree = this.trees[maxZoom + 1] = this._createTree(data);\n\n if (log) console.timeEnd(timerId);\n\n // cluster points on max zoom, then cluster the results on previous zoom, etc.;\n // results in a cluster hierarchy across zoom levels\n for (let z = maxZoom; z >= minZoom; z--) {\n const now = +Date.now();\n\n // create a new set of clusters for the zoom and index them with a KD-tree\n tree = this.trees[z] = this._createTree(this._cluster(tree, z));\n\n if (log) console.log('z%d: %d clusters in %dms', z, tree.numItems, +Date.now() - now);\n }\n\n if (log) console.timeEnd('total time');\n\n return this;\n }\n\n getClusters(bbox, zoom) {\n let minLng = ((bbox[0] + 180) % 360 + 360) % 360 - 180;\n const minLat = Math.max(-90, Math.min(90, bbox[1]));\n let maxLng = bbox[2] === 180 ? 180 : ((bbox[2] + 180) % 360 + 360) % 360 - 180;\n const maxLat = Math.max(-90, Math.min(90, bbox[3]));\n\n if (bbox[2] - bbox[0] >= 360) {\n minLng = -180;\n maxLng = 180;\n } else if (minLng > maxLng) {\n const easternHem = this.getClusters([minLng, minLat, 180, maxLat], zoom);\n const westernHem = this.getClusters([-180, minLat, maxLng, maxLat], zoom);\n return easternHem.concat(westernHem);\n }\n\n const tree = this.trees[this._limitZoom(zoom)];\n const ids = tree.range(lngX(minLng), latY(maxLat), lngX(maxLng), latY(minLat));\n const data = tree.data;\n const clusters = [];\n for (const id of ids) {\n const k = this.stride * id;\n clusters.push(data[k + OFFSET_NUM] > 1 ? getClusterJSON(data, k, this.clusterProps) : this.points[data[k + OFFSET_ID]]);\n }\n return clusters;\n }\n\n getChildren(clusterId) {\n const originId = this._getOriginId(clusterId);\n const originZoom = this._getOriginZoom(clusterId);\n const errorMsg = 'No cluster with the specified id.';\n\n const tree = this.trees[originZoom];\n if (!tree) throw new Error(errorMsg);\n\n const data = tree.data;\n if (originId * this.stride >= data.length) throw new Error(errorMsg);\n\n const r = this.options.radius / (this.options.extent * Math.pow(2, originZoom - 1));\n const x = data[originId * this.stride];\n const y = data[originId * this.stride + 1];\n const ids = tree.within(x, y, r);\n const children = [];\n for (const id of ids) {\n const k = id * this.stride;\n if (data[k + OFFSET_PARENT] === clusterId) {\n children.push(data[k + OFFSET_NUM] > 1 ? getClusterJSON(data, k, this.clusterProps) : this.points[data[k + OFFSET_ID]]);\n }\n }\n\n if (children.length === 0) throw new Error(errorMsg);\n\n return children;\n }\n\n getLeaves(clusterId, limit, offset) {\n limit = limit || 10;\n offset = offset || 0;\n\n const leaves = [];\n this._appendLeaves(leaves, clusterId, limit, offset, 0);\n\n return leaves;\n }\n\n getTile(z, x, y) {\n const tree = this.trees[this._limitZoom(z)];\n const z2 = Math.pow(2, z);\n const {extent, radius} = this.options;\n const p = radius / extent;\n const top = (y - p) / z2;\n const bottom = (y + 1 + p) / z2;\n\n const tile = {\n features: []\n };\n\n this._addTileFeatures(\n tree.range((x - p) / z2, top, (x + 1 + p) / z2, bottom),\n tree.data, x, y, z2, tile);\n\n if (x === 0) {\n this._addTileFeatures(\n tree.range(1 - p / z2, top, 1, bottom),\n tree.data, z2, y, z2, tile);\n }\n if (x === z2 - 1) {\n this._addTileFeatures(\n tree.range(0, top, p / z2, bottom),\n tree.data, -1, y, z2, tile);\n }\n\n return tile.features.length ? tile : null;\n }\n\n getClusterExpansionZoom(clusterId) {\n let expansionZoom = this._getOriginZoom(clusterId) - 1;\n while (expansionZoom <= this.options.maxZoom) {\n const children = this.getChildren(clusterId);\n expansionZoom++;\n if (children.length !== 1) break;\n clusterId = children[0].properties.cluster_id;\n }\n return expansionZoom;\n }\n\n _appendLeaves(result, clusterId, limit, offset, skipped) {\n const children = this.getChildren(clusterId);\n\n for (const child of children) {\n const props = child.properties;\n\n if (props && props.cluster) {\n if (skipped + props.point_count <= offset) {\n // skip the whole cluster\n skipped += props.point_count;\n } else {\n // enter the cluster\n skipped = this._appendLeaves(result, props.cluster_id, limit, offset, skipped);\n // exit the cluster\n }\n } else if (skipped < offset) {\n // skip a single point\n skipped++;\n } else {\n // add a single point\n result.push(child);\n }\n if (result.length === limit) break;\n }\n\n return skipped;\n }\n\n _createTree(data) {\n const tree = new KDBush(data.length / this.stride | 0, this.options.nodeSize, Float32Array);\n for (let i = 0; i < data.length; i += this.stride) tree.add(data[i], data[i + 1]);\n tree.finish();\n tree.data = data;\n return tree;\n }\n\n _addTileFeatures(ids, data, x, y, z2, tile) {\n for (const i of ids) {\n const k = i * this.stride;\n const isCluster = data[k + OFFSET_NUM] > 1;\n\n let tags, px, py;\n if (isCluster) {\n tags = getClusterProperties(data, k, this.clusterProps);\n px = data[k];\n py = data[k + 1];\n } else {\n const p = this.points[data[k + OFFSET_ID]];\n tags = p.properties;\n const [lng, lat] = p.geometry.coordinates;\n px = lngX(lng);\n py = latY(lat);\n }\n\n const f = {\n type: 1,\n geometry: [[\n Math.round(this.options.extent * (px * z2 - x)),\n Math.round(this.options.extent * (py * z2 - y))\n ]],\n tags\n };\n\n // assign id\n let id;\n if (isCluster || this.options.generateId) {\n // optionally generate id for points\n id = data[k + OFFSET_ID];\n } else {\n // keep id if already assigned\n id = this.points[data[k + OFFSET_ID]].id;\n }\n\n if (id !== undefined) f.id = id;\n\n tile.features.push(f);\n }\n }\n\n _limitZoom(z) {\n return Math.max(this.options.minZoom, Math.min(Math.floor(+z), this.options.maxZoom + 1));\n }\n\n _cluster(tree, zoom) {\n const {radius, extent, reduce, minPoints} = this.options;\n const r = radius / (extent * Math.pow(2, zoom));\n const data = tree.data;\n const nextData = [];\n const stride = this.stride;\n\n // loop through each point\n for (let i = 0; i < data.length; i += stride) {\n // if we've already visited the point at this zoom level, skip it\n if (data[i + OFFSET_ZOOM] <= zoom) continue;\n data[i + OFFSET_ZOOM] = zoom;\n\n // find all nearby points\n const x = data[i];\n const y = data[i + 1];\n const neighborIds = tree.within(data[i], data[i + 1], r);\n\n const numPointsOrigin = data[i + OFFSET_NUM];\n let numPoints = numPointsOrigin;\n\n // count the number of points in a potential cluster\n for (const neighborId of neighborIds) {\n const k = neighborId * stride;\n // filter out neighbors that are already processed\n if (data[k + OFFSET_ZOOM] > zoom) numPoints += data[k + OFFSET_NUM];\n }\n\n // if there were neighbors to merge, and there are enough points to form a cluster\n if (numPoints > numPointsOrigin && numPoints >= minPoints) {\n let wx = x * numPointsOrigin;\n let wy = y * numPointsOrigin;\n\n let clusterProperties;\n let clusterPropIndex = -1;\n\n // encode both zoom and point index on which the cluster originated -- offset by total length of features\n const id = ((i / stride | 0) << 5) + (zoom + 1) + this.points.length;\n\n for (const neighborId of neighborIds) {\n const k = neighborId * stride;\n\n if (data[k + OFFSET_ZOOM] <= zoom) continue;\n data[k + OFFSET_ZOOM] = zoom; // save the zoom (so it doesn't get processed twice)\n\n const numPoints2 = data[k + OFFSET_NUM];\n wx += data[k] * numPoints2; // accumulate coordinates for calculating weighted center\n wy += data[k + 1] * numPoints2;\n\n data[k + OFFSET_PARENT] = id;\n\n if (reduce) {\n if (!clusterProperties) {\n clusterProperties = this._map(data, i, true);\n clusterPropIndex = this.clusterProps.length;\n this.clusterProps.push(clusterProperties);\n }\n reduce(clusterProperties, this._map(data, k));\n }\n }\n\n data[i + OFFSET_PARENT] = id;\n nextData.push(wx / numPoints, wy / numPoints, Infinity, id, -1, numPoints);\n if (reduce) nextData.push(clusterPropIndex);\n\n } else { // left points as unclustered\n for (let j = 0; j < stride; j++) nextData.push(data[i + j]);\n\n if (numPoints > 1) {\n for (const neighborId of neighborIds) {\n const k = neighborId * stride;\n if (data[k + OFFSET_ZOOM] <= zoom) continue;\n data[k + OFFSET_ZOOM] = zoom;\n for (let j = 0; j < stride; j++) nextData.push(data[k + j]);\n }\n }\n }\n }\n\n return nextData;\n }\n\n // get index of the point from which the cluster originated\n _getOriginId(clusterId) {\n return (clusterId - this.points.length) >> 5;\n }\n\n // get zoom of the point from which the cluster originated\n _getOriginZoom(clusterId) {\n return (clusterId - this.points.length) % 32;\n }\n\n _map(data, i, clone) {\n if (data[i + OFFSET_NUM] > 1) {\n const props = this.clusterProps[data[i + OFFSET_PROP]];\n return clone ? Object.assign({}, props) : props;\n }\n const original = this.points[data[i + OFFSET_ID]].properties;\n const result = this.options.map(original);\n return clone && result === original ? Object.assign({}, result) : result;\n }\n}\n\nfunction getClusterJSON(data, i, clusterProps) {\n return {\n type: 'Feature',\n id: data[i + OFFSET_ID],\n properties: getClusterProperties(data, i, clusterProps),\n geometry: {\n type: 'Point',\n coordinates: [xLng(data[i]), yLat(data[i + 1])]\n }\n };\n}\n\nfunction getClusterProperties(data, i, clusterProps) {\n const count = data[i + OFFSET_NUM];\n const abbrev =\n count >= 10000 ? `${Math.round(count / 1000) }k` :\n count >= 1000 ? `${Math.round(count / 100) / 10 }k` : count;\n const propIndex = data[i + OFFSET_PROP];\n const properties = propIndex === -1 ? {} : Object.assign({}, clusterProps[propIndex]);\n return Object.assign(properties, {\n cluster: true,\n cluster_id: data[i + OFFSET_ID],\n point_count: count,\n point_count_abbreviated: abbrev\n });\n}\n\n// longitude/latitude to spherical mercator in [0..1] range\nfunction lngX(lng) {\n return lng / 360 + 0.5;\n}\nfunction latY(lat) {\n const sin = Math.sin(lat * Math.PI / 180);\n const y = (0.5 - 0.25 * Math.log((1 + sin) / (1 - sin)) / Math.PI);\n return y < 0 ? 0 : y > 1 ? 1 : y;\n}\n\n// spherical mercator to longitude/latitude\nfunction xLng(x) {\n return (x - 0.5) * 360;\n}\nfunction yLat(y) {\n const y2 = (180 - y * 360) * Math.PI / 180;\n return 360 * Math.atan(Math.exp(y2)) / Math.PI - 90;\n}\n","import { CompositeLayer } from '@deck.gl/core';\nimport { IconLayer, IconLayerProps } from '@deck.gl/layers';\nimport Supercluster from 'supercluster';\n\nimport type { PointFeature, ClusterFeature, ClusterProperties } from 'supercluster';\nimport type { UpdateParameters, PickingInfo } from '@deck.gl/core';\n\nexport type IconClusterLayerPickingInfo<DataT> = PickingInfo<\n DataT | (DataT & ClusterProperties),\n { objects?: DataT[] }\n>;\n\nfunction getIconName(size: number): string {\n if (size === 0) {\n return '';\n }\n if (size < 10) {\n return `marker-${size}`;\n }\n if (size < 100) {\n return `marker-${Math.floor(size / 10)}0`;\n }\n return 'marker-100';\n}\n\nfunction getIconSize(size: number): number {\n return Math.min(100, size) / 200 + 1;\n}\n\nexport default class IconClusterLayer<\n DataT extends { [key: string]: any } = any,\n ExtraProps extends {} = {},\n> extends CompositeLayer<Required<IconLayerProps<DataT>> & ExtraProps> {\n state!: {\n data: (PointFeature<DataT> | ClusterFeature<DataT>)[];\n index: Supercluster<DataT, DataT>;\n z: number;\n };\n\n shouldUpdateState({ changeFlags }: UpdateParameters<this>) {\n return changeFlags.somethingChanged;\n }\n\n updateState({ props, oldProps, changeFlags }: UpdateParameters<this>) {\n const rebuildIndex = changeFlags.dataChanged || props.sizeScale !== oldProps.sizeScale;\n\n if (rebuildIndex) {\n const index = new Supercluster<DataT, DataT>({\n maxZoom: 16,\n radius: props.sizeScale * Math.sqrt(2),\n });\n index.load(\n // @ts-ignore Supercluster expects proper GeoJSON feature\n (props.data as DataT[]).map((d) => ({\n geometry: {\n coordinates: (props.getPosition as Function)(d),\n },\n properties: d,\n })),\n );\n this.setState({ index });\n }\n\n const z = Math.floor(this.context.viewport.zoom);\n if (rebuildIndex || z !== this.state.z) {\n this.setState({\n data: this.state.index.getClusters([-180, -85, 180, 85], z),\n z,\n });\n }\n }\n\n getPickingInfo({\n info,\n mode,\n }: {\n info: PickingInfo<PointFeature<DataT> | ClusterFeature<DataT>>;\n mode: string;\n }): IconClusterLayerPickingInfo<DataT> {\n const pickedObject = info.object?.properties;\n if (pickedObject) {\n let objects: DataT[] | undefined;\n if (pickedObject.cluster && mode !== 'hover') {\n objects = this.state.index\n .getLeaves(pickedObject.cluster_id, 25)\n .map((f) => f.properties);\n }\n return { ...info, object: pickedObject, objects };\n }\n return { ...info, object: undefined };\n }\n\n renderLayers() {\n const { data } = this.state;\n const { iconAtlas, iconMapping, sizeScale } = this.props;\n\n return new IconLayer<PointFeature<DataT> | ClusterFeature<DataT>>(\n {\n data,\n iconAtlas,\n iconMapping,\n sizeScale,\n getPosition: (d) => d.geometry.coordinates as [number, number],\n getIcon: (d) => getIconName(d.properties.cluster ? d.properties.point_count : 1),\n getSize: (d) => getIconSize(d.properties.cluster ? d.properties.point_count : 1),\n },\n this.getSubLayerProps({\n id: 'icon',\n }),\n );\n }\n}\n","import RBush from 'rbush';\n\nexport const dys = [\n 5, 4, 3, 2, 1, 0.9, 0.8, 0.7, 0.6, 0.5, 0.4, 0.3, 0.2, 0.1, 0.05, 0.025, 0.01, 0,\n];\nconst population_limit = [\n 2000000, 1000000, 800000, 600000, 400000, 200000, 100000, 50000, 25000, 10000, 5000, 4000, 3000,\n 2000, 500, 0,\n];\n\nexport function computeProgressiveDisclosure(citylist, debug = false) {\n // Compute the progresive disclosure\n const t0 = performance.now();\n const bushes = {};\n const lastInsert = [];\n const citylistTmp = [...citylist];\n for (const i in dys) {\n const dy = parseFloat(dys[i]);\n const limitPopulation = population_limit[i];\n\n bushes[dy] = new RBush();\n\n // Now try to add new cities using the new dy\n bushes[dy] = tryTOAddCitiesToDomain(\n bushes[dy],\n citylistTmp,\n dy,\n limitPopulation,\n lastInsert,\n );\n\n if (debug) {\n const list = bushes[dy].all();\n console.log(\n 'citylist:',\n dy,\n list.length,\n citylistTmp.length,\n Math.round(performance.now() - t0),\n );\n }\n }\n\n // Make the index file\n const indexes = {};\n for (const dy of dys) {\n indexes[dy] = [];\n const list = bushes[dy].all();\n for (const obj of list) {\n indexes[dy].push(obj.idx);\n }\n }\n\n // If a city pops up at one dy (say 2), then disappears (say 1), this is becuase a higher\n // ranked city is replacing it. To avoid this, we remove cities that are in a higher order\n // rank but no in the lower order rank\n for (const i in dys) {\n if (i == 0) continue;\n const idx1 = indexes[dys[i - 1]];\n const idx2 = indexes[dys[i]];\n // Find the differences between the two\n const diffArray = idx1.filter((num) => !idx2.includes(num));\n // Now remove these difference values from ALL higher order dy\n for (let j = i - 1; j >= 0; j--) {\n indexes[dys[j]] = indexes[dys[j]].filter((num) => !diffArray.includes(num));\n }\n }\n\n //\n // Build City trees with RBush(), takes about 50 ms\n const tree = {};\n const t1 = performance.now();\n for (let dy in indexes) {\n const items = [];\n dy = parseFloat(dy);\n for (const i of indexes[dy]) {\n const { name } = citylist[i];\n const dx = (name.length * dy) / 2;\n items.push({\n minX: parseFloat(citylist[i].lon) - dx,\n maxX: parseFloat(citylist[i].lon) + dx,\n minY: parseFloat(citylist[i].lat) - dy,\n maxY: parseFloat(citylist[i].lat) + dy,\n ...citylist[i],\n });\n }\n tree[dy] = new RBush();\n tree[dy].load(items);\n }\n\n console.log('Progressive Disclosure Creation Time:', performance.now() - t0);\n\n return tree;\n}\n\nfunction tryTOAddCitiesToDomain(t, citylist, dy, limitPopulation) {\n // Insert one by one\n for (let i = 0; i < citylist.length; i++) {\n let { name, population, lon, lat } = citylist[i];\n const ignorePopulation = citylist[i].ignorePopulation ?? false;\n lon = parseFloat(lon);\n lat = parseFloat(lat);\n population = parseFloat(population);\n if (!ignorePopulation && population < limitPopulation) {\n continue;\n }\n\n const dx = (name.length * dy) / 2;\n const item = {\n minX: lon - dx,\n maxX: lon + dx,\n minY: lat - dy,\n maxY: lat + dy,\n idx: i,\n };\n\n if (!t.collides(item)) {\n t.insert(item);\n }\n }\n return t;\n}\n","/* eslint-disable max-len */\nimport { CompositeLayer } from '@deck.gl/core';\nimport { TextLayer } from '@deck.gl/layers';\nimport gUtilities from '../../utilities/graphicsUtilities';\nimport deckUtilities from '../../utilities/deckUtilities';\nimport { computeProgressiveDisclosure, dys } from './computeProgressiveDisclosure';\n\nconst defaultProps = {\n elevation: 0,\n cityBaseScale: 14,\n cityPadding: 1,\n fontFamily: 'Open Sans, sans-serif',\n billboard: true,\n backgroundPadding: [4, 1],\n getTextAnchor: 'middle',\n getAlignmentBaseline: 'bottom', // was 'center' but descenders were cut off\n getPixelOffset: [0, 10], // prevent descenders from being cut off\n characterSet: 'auto',\n fontSettings: {\n sdf: true,\n radius: 12,\n cutoff: 0.25,\n buffer: 10,\n smoothing: 0.2, // only applies if sdf is true\n },\n outlineWidth: 4, // was 3.59\n outlineColor: [0, 0, 0, 255],\n fontWeight: '700', // was 500\n getColor: (x) => x.color || [255, 255, 255, 255],\n getLabel: (x) => x.label,\n getWeight: (x) => x.weight || 1,\n getPosition: (x) => x.position,\n parameters: { depthCompare: 'always', cullMode: 'none' },\n};\n\nconst findPopulationScale = (d) => {\n const { population } = d;\n let populationScale = 0.85;\n if (population > 1000000) populationScale = 1.1;\n else if (population > 100000) populationScale = 1.0;\n else if (population > 50000) populationScale = 0.9;\n else if (population > 0) populationScale = 0.85;\n return populationScale;\n};\n\nconst throttle = 500;\nlet tree;\nlet cityLengthLast;\n\nexport default class CitiesLayer extends CompositeLayer {\n initializeState() {\n this.state = {\n // Cached tags per zoom level\n tagsCache: {},\n tags: [],\n lastTimeout: undefined,\n lastTrigger: performance.now(),\n };\n }\n\n // eslint-disable-next-line class-methods-use-this\n shouldUpdateState({ changeFlags }) {\n return changeFlags.somethingChanged;\n }\n\n updateState({ props, oldProps, changeFlags }) {\n if (!changeFlags.viewportChanged && !changeFlags.propsOrDataChanged) return;\n\n super.updateState({ props, oldProps, changeFlags });\n\n let wait = 0;\n if (changeFlags.viewportChanged) {\n wait = performance.now() - this.state.lastTrigger;\n wait = wait < throttle ? throttle - wait : 0;\n }\n\n clearTimeout(this.state?.lastTimeout);\n this.state.lastTimeout = setTimeout(() => {\n const lastTrigger = performance.now();\n\n // Get RBUSH tree\n const { cityList, dataLabels } = props;\n const cityLength = cityList?.length;\n if (!tree || cityLength !== cityLengthLast) {\n tree = computeProgressiveDisclosure(props.cityList);\n }\n cityLengthLast = cityLength;\n\n const { viewport } = this.context;\n // Globeview bearing is undefined, so grab it this way\n const bearing = viewport.bearing || 0;\n\n const { latPerPixel } = deckUtilities.getLatLonPerPixel(viewport);\n // added cityBaseScale to make padding dynamic based on city fontsize when running graphicUtilities.js\n const citiesInDomain = deckUtilities.getCities(\n viewport,\n tree,\n dys,\n props.cityBaseScale,\n props.cityPadding,\n );\n\n const cityData = [];\n for (const i in citiesInDomain) {\n const lat = Number(citiesInDomain[i].lat);\n const lon = Number(citiesInDomain[i].lon);\n const { name } = citiesInDomain[i];\n const { population } = citiesInDomain[i];\n let value;\n let fvalue = '';\n if (dataLabels) {\n const {\n data,\n decimals = 0,\n units = '',\n interpolate = true,\n valueFormatter,\n readoutFunction,\n readoutOptions,\n } = dataLabels;\n\n if (typeof readoutFunction === 'function') {\n value = readoutFunction(lat, lon, data, {\n ...readoutOptions,\n interpolate: readoutOptions?.interpolate ?? interpolate,\n units,\n });\n }\n\n if (props.isTiming && Number.isFinite(value)) {\n const initDate = new Date(props.initDate);\n initDate.setHours(initDate.getHours() + Number(value));\n fvalue = gUtilities.formatdate(initDate, 'timing', props.settings);\n } else if (typeof valueFormatter === 'function') {\n const formattedValue = valueFormatter(value, {\n lat,\n lon,\n data,\n decimals,\n units,\n interpolate,\n readoutOptions,\n });\n fvalue = formattedValue == null ? '' : `${formattedValue}`;\n } else if (typeof value === 'string') {\n fvalue = value;\n } else if (value !== undefined && value !== null && !Number.isNaN(value)) {\n fvalue = `${gUtilities.roundto(value, decimals)}${units}`;\n }\n }\n\n cityData.push({\n value: fvalue,\n lat,\n lon,\n name,\n population,\n });\n }\n\n // zoom scale\n // zoom: 1, scale 0.85\n // zoom: 3, scale 1.0\n const x1 = 1;\n const y1 = 0.85;\n const x2 = 3;\n const y2 = 1.0;\n let zoomScale;\n if (viewport.zoom > x2) zoomScale = y2;\n else if (viewport.zoom <= x1) zoomScale = y1;\n else {\n // y = mx+b\n const m = (y2 - y1) / (x2 - x1);\n const b = y1 - m * x1;\n zoomScale = m * viewport.zoom + b;\n }\n this.setState({\n cityData,\n zoomScale,\n latPerPixel,\n bearing,\n lastTrigger,\n });\n }, wait);\n }\n\n renderLayers() {\n const { cityData, zoomScale, latPerPixel, bearing } = this.state;\n const { elevation } = this.props;\n const baseScale = this.props.cityBaseScale;\n const readoutScale = 1.5; // was 1.2\n\n // access the camera position\n const { viewport } = this.context;\n const { zoom } = viewport;\n const cameraLat = viewport.latitude;\n const cameraLon = viewport.longitude;\n\n const layers = [\n new TextLayer(this.props, {\n id: `${this.props.id}-tagmap-layer`,\n // hack to prevent labels on the opposite side of the globe from being visible\n data:\n cityData?.filter((d) =>\n deckUtilities.isFeatureVisibleOnGlobe(\n cameraLat,\n cameraLon,\n d.lat,\n d.lon,\n zoom,\n ),\n ) || false,\n getText: (d) => d.name,\n getPosition: (d) => [Number(d.lon), Number(d.lat), elevation],\n getSize: (d) => {\n const populationScale = findPopulationScale(d);\n return baseScale * populationScale * zoomScale;\n },\n }),\n ];\n\n if (this.props.dataLabels) {\n layers.push(\n new TextLayer(this.props, {\n id: `${this.props.id}-tagmap-dataLabels`,\n // hack to prevent labels on the opposite side of the globe from being visible\n data: cityData?.filter(\n (d) =>\n deckUtilities.isFeatureVisibleOnGlobe(\n cameraLat,\n cameraLon,\n d.lat,\n d.lon,\n zoom,\n ) || false,\n ),\n fontWeight: '700',\n outlineWidth: 3,\n getText: (d) => d.value,\n // Always make sure the value is above the city, no matter the bearing\n getPosition: (d) => {\n // padding between readout and city name is based on scale and a small padding multiplier\n const padding = 1; // shrank this because now setting alignment to bottom\n const rad = (bearing * Math.PI) / 180;\n const populationScale = findPopulationScale(d);\n const displace = latPerPixel * baseScale * populationScale * padding;\n return [\n Number(d.lon) + Math.sin(rad) * displace,\n Number(d.lat) + Math.cos(rad) * displace,\n elevation,\n ];\n },\n getSize: (d) => {\n const populationScale = findPopulationScale(d);\n return baseScale * populationScale * zoomScale * readoutScale;\n },\n }),\n );\n }\n\n return layers;\n }\n}\n\nCitiesLayer.layerName = 'CitiesLayer';\nCitiesLayer.defaultProps = defaultProps;\n\nexport { CitiesLayer };\n","// deck.gl\n// SPDX-License-Identifier: MIT\n// Copyright (c) vis.gl contributors\n\nimport { CompositeLayer } from '@deck.gl/core';\nimport PathLayer from '../pathLayer/WizardPathLayer.js';\n\nexport const LINE_LAYER = {\n type: PathLayer,\n props: {\n lineWidthUnits: 'widthUnits',\n lineWidthScale: 'widthScale',\n lineWidthMinPixels: 'widthMinPixels',\n lineWidthMaxPixels: 'widthMaxPixels',\n lineJointRounded: 'jointRounded',\n lineCapRounded: 'capRounded',\n lineMiterLimit: 'miterLimit',\n lineBillboard: 'billboard',\n\n getLineColor: 'getColor',\n getLineWidth: 'getWidth',\n },\n};\n\nexport function forwardProps(\n layer: CompositeLayer,\n mapping: Record<string, string>,\n): Record<string, any> {\n const { transitions, updateTriggers } = layer.props;\n const result: Record<string, any> = {\n updateTriggers: {},\n transitions: transitions && {\n getPosition: transitions.geometry,\n },\n };\n\n for (const sourceKey in mapping) {\n const targetKey = mapping[sourceKey];\n let value = layer.props[sourceKey];\n if (sourceKey.startsWith('get')) {\n // isAccessor\n value = (layer as any).getSubLayerAccessor(value);\n result.updateTriggers[targetKey] = updateTriggers[sourceKey];\n if (transitions) {\n result.transitions[targetKey] = transitions[sourceKey];\n }\n }\n result[targetKey] = value;\n }\n return result;\n}\n","// my-point-cloud-layer.js\n// Example to add per-point size to point cloud layer\nimport { GeoJsonLayer, GeoJsonLayerProps } from 'deck.gl';\nimport { LINE_LAYER, forwardProps } from './sub-layer-map';\nimport { DefaultProps, Layer } from '@deck.gl/core';\n\nexport default class WizardGeoJsonLayer extends GeoJsonLayer {\n static defaultProps: any = {\n ...GeoJsonLayer.defaultProps,\n parameters: {\n depthCompare: 'always',\n cullMode: 'back',\n },\n };\n\n initializeState() {\n super.initializeState();\n }\n protected _renderLineLayers(): (Layer | false)[] | null {\n const { extruded, stroked } = this.props;\n const { layerProps } = this.state;\n const polygonStrokeLayerId = 'polygons-stroke';\n const lineStringsLayerId = 'linestrings';\n\n const PolygonStrokeLayer =\n !extruded &&\n stroked &&\n this.shouldRenderSubLayer(polygonStrokeLayerId, layerProps.polygonsOutline?.data) &&\n this.getSubLayerClass(polygonStrokeLayerId, LINE_LAYER.type);\n const LineStringsLayer =\n this.shouldRenderSubLayer(lineStringsLayerId, layerProps.lines?.data) &&\n this.getSubLayerClass(lineStringsLayerId, LINE_LAYER.type);\n\n if (PolygonStrokeLayer || LineStringsLayer) {\n const forwardedProps = forwardProps(this, LINE_LAYER.props);\n return [\n PolygonStrokeLayer &&\n new PolygonStrokeLayer(\n forwardedProps,\n this.getSubLayerProps({\n id: polygonStrokeLayerId,\n updateTriggers: forwardedProps.updateTriggers,\n }),\n layerProps.polygonsOutline,\n ),\n\n LineStringsLayer &&\n new LineStringsLayer(\n forwardedProps,\n this.getSubLayerProps({\n id: lineStringsLayerId,\n updateTriggers: forwardedProps.updateTriggers,\n }),\n layerProps.lines,\n ),\n ];\n }\n return null;\n }\n}\n\nWizardGeoJsonLayer.layerName = 'WizardGeoJsonLayer';\n","import { CompositeLayer, GeoJsonLayer } from 'deck.gl';\n\n// Define a function to set color and label based on `tid` and `stat` based on NWS GIS arcgis online\nfunction getSymbolInfo(tid, stat) {\n const uniqueValueMap = {\n '0,P': { color: [255, 193, 7, 150], cirtext: 'W', label: 'Wildfire Pending' },\n '0,C': { color: [25, 135, 84, 150], cirtext: 'W', label: 'Wildfire Completed' },\n '1,P': { color: [255, 193, 7, 150], cirtext: 'P', label: 'Prescribed Pending' },\n '1,C': { color: [25, 135, 84, 150], cirtext: 'P', label: 'Prescribed Completed' },\n '2,P': { color: [255, 193, 7, 150], cirtext: 'M', label: 'Marine Pending' },\n '2,C': { color: [25, 135, 84, 150], cirtext: 'M', label: 'Marine Completed' },\n '3,P': { color: [255, 193, 7, 150], cirtext: 'H', label: 'Hazmat Pending' },\n '4,P': { color: [255, 193, 7, 150], cirtext: 'H', label: 'Hazmat Pending' },\n '8,P': { color: [255, 193, 7, 150], cirtext: 'H', label: 'Hazmat Pending' },\n '3,C': { color: [25, 135, 84, 150], cirtext: 'H', label: 'Hazmat Completed' },\n '4,C': { color: [25, 135, 84, 150], cirtext: 'H', label: 'Hazmat Completed' },\n '8,C': { color: [25, 135, 84, 150], cirtext: 'H', label: 'Hazmat Completed' },\n '5,P': { color: [255, 193, 7, 150], cirtext: 'S', label: 'SAR Pending' },\n '6,P': { color: [255, 193, 7, 150], cirtext: 'S', label: 'SAR Pending' },\n '9,P': { color: [255, 193, 7, 150], cirtext: 'S', label: 'SAR Pending' },\n '5,C': { color: [25, 135, 84, 150], cirtext: 'S', label: 'SAR Completed' },\n '6,C': { color: [25, 135, 84, 150], cirtext: 'S', label: 'SAR Completed' },\n '9,C': { color: [25, 135, 84, 150], cirtext: 'S', label: 'SAR Completed' },\n '7,P': { color: [255, 193, 7, 150], cirtext: 'O', label: 'Other Pending' },\n '7,C': { color: [25, 135, 84, 150], cirtext: 'O', label: 'Other Completed' },\n };\n\n return uniqueValueMap[`${tid},${stat}`] || { color: [0, 0, 0, 150], label: 'N/A' };\n}\n\nconst defaultProps = {\n data: 'https://mapservices.weather.noaa.gov/vector/rest/services/fire_weather/nws_fire_weather_spot/MapServer/0/query?outFields=*&where=1%3D1&orderByFields=rfill%20ASC&geometryPrecision=3&f=geojson',\n pointType: 'circle+text',\n getText: (d) => {\n const { cirtext } = getSymbolInfo(d.properties.tid, d.properties.stat);\n return cirtext;\n },\n getSize: 60,\n getPointRadius: 20,\n pointRadiusUnits: 'pixels',\n radiusScale: 6,\n getColor: [0, 0, 0, 255],\n getTextAnchor: 'middle',\n getAlignmentBaseline: 'center',\n getTextColor: [0, 0, 0, 255],\n getFillColor: (d) => {\n const { color } = getSymbolInfo(d.properties.tid, d.properties.stat);\n return color;\n },\n textFontFamily: 'Open Sans, sans-serif',\n textFontWeight: '700',\n getTextSize: 20,\n textSizeUnits: 'pixels',\n getTextBorderColor: [0, 0, 0, 255],\n getTextBorderWidth: 4,\n getElevation: 0,\n elevationScale: 1,\n parameters: { depthTest:true, depthCompare: 'always', cullMode: 'none' },\n // Add click handler prop\n onSpotClick: null,\n pickingFunction: (d) => {\n if (d.object) {\n const { tid, stat, name, type, rmade, rfill, deliverdtg, wfo, snumunum } =\n d.object.properties;\n\n // Initialize an array to store available rows\n const readout = [];\n\n // Conditionally add each variable to the tooltip\n if (name)\n readout.push(\n <div key=\"name\">\n <strong>Name:</strong> {name}\n <br />\n </div>,\n );\n\n if (tid && stat) {\n const { label, color } = getSymbolInfo(tid, stat);\n readout.push(\n <div key=\"type\">\n <strong>Type:</strong>\n <span style={{ color: `rgb(${color[0]},${color[1]},${color[2]})` }}>\n {' '}\n {label}\n </span>\n <br />\n </div>,\n );\n }\n\n if (rmade)\n readout.push(\n <div key=\"request\">\n <strong>Request Made:</strong> {rmade}\n <br />\n </div>,\n );\n if (deliverdtg)\n readout.push(\n <div key=\"deliver\">\n <strong>Deliver Time:</strong> {deliverdtg}\n <br />\n </div>,\n );\n if (wfo)\n readout.push(\n <div key=\"office\">\n <strong>Forecast Office:</strong> {wfo}\n <br />\n </div>,\n );\n\n // Add the spot forecast link\n if (snumunum) {\n const spoturl = `https://spot.weather.gov/forecasts/${snumunum}`;\n readout.push(\n <div key=\"spot-link\" className=\"spot-forecast-link\">\n <strong>Link:</strong>{' '}\n <a \n href={spoturl} \n target=\"_blank\" \n rel=\"noopener noreferrer\"\n onClick={(e) => {\n e.stopPropagation();\n // Link will open normally\n }}\n >\n Spot Forecast\n </a>\n <br />\n </div>,\n );\n }\n\n // Return readout with additional metadata for persistent tooltips\n return { \n readout, \n coordinates: [d.coordinate[0], d.coordinate[1]],\n object: d.object,\n isPersistent: d.type === 'click' // Will be true for clicks\n };\n }\n return { readout: null };\n },\n};\n\nclass SpotLayer extends CompositeLayer {\n renderLayers() {\n return new GeoJsonLayer(this.props, {\n id: `${this.props.id}-geojson`,\n onClick: this.props.onClick, // Pass through click handler\n });\n }\n}\n\nSpotLayer.defaultProps = defaultProps;\nSpotLayer.layerName = 'SpotLayer';\nexport default SpotLayer;","export default \"data:image/svg+xml,%3c?xml%20version='1.0'%20encoding='UTF-8'?%3e%3csvg%20xmlns='http://www.w3.org/2000/svg'%20xmlns:xlink='http://www.w3.org/1999/xlink'%20width='100px'%20height='136px'%20viewBox='0%200%20100%20135'%20version='1.1'%3e%3cg%20id='surface1'%3e%3cpath%20style='%20stroke:none;fill-rule:nonzero;fill:rgb(90.588235%25,22.352941%25,0%25);fill-opacity:1;'%20d='M%2055.019531%201.535156%20C%2055.199219%202.085938%2055.167969%202.484375%2055.066406%203.050781%20C%2055.039062%203.226562%2055.011719%203.398438%2054.980469%203.574219%20C%2054.917969%203.925781%2054.859375%204.277344%2054.796875%204.628906%20C%2054.230469%208.03125%2054.128906%2011.449219%2054.140625%2014.890625%20C%2054.140625%2015.089844%2054.140625%2015.289062%2054.140625%2015.496094%20C%2054.152344%2018.804688%2054.277344%2022.066406%2054.6875%2025.347656%20C%2054.703125%2025.464844%2054.71875%2025.578125%2054.730469%2025.695312%20C%2055.917969%2035.320312%2058.238281%2044.777344%2061.464844%2053.925781%20C%2061.816406%2053.402344%2062.070312%2052.863281%2062.332031%2052.296875%20C%2062.441406%2052.0625%2062.546875%2051.828125%2062.65625%2051.597656%20C%2062.714844%2051.472656%2062.769531%2051.351562%2062.828125%2051.226562%20C%2063.972656%2048.769531%2065.191406%2046.398438%2066.589844%2044.070312%20C%2066.742188%2043.816406%2066.894531%2043.558594%2067.046875%2043.300781%20C%2069.035156%2039.96875%2071.367188%2036.863281%2073.863281%2033.890625%20C%2074%2033.722656%2074.140625%2033.558594%2074.285156%2033.386719%20C%2075.464844%2031.988281%2076.710938%2030.679688%2078.015625%2029.394531%20C%2078.335938%2029.074219%2078.660156%2028.753906%2078.980469%2028.433594%20C%2080.027344%2027.390625%2081.078125%2026.394531%2082.246094%2025.484375%20C%2082.617188%2025.191406%2082.964844%2024.878906%2083.316406%2024.558594%20C%2086.722656%2021.539062%2090.792969%2019.097656%2094.765625%2016.882812%20C%2095.046875%2016.722656%2095.328125%2016.558594%2095.609375%2016.394531%20C%2095.742188%2016.316406%2095.875%2016.238281%2096.011719%2016.160156%20C%2096.125%2016.089844%2096.242188%2016.023438%2096.363281%2015.953125%20C%2096.671875%2015.824219%2096.671875%2015.824219%2097.167969%2015.988281%20C%2097.042969%2016.113281%2097.042969%2016.113281%2096.914062%2016.238281%20C%2096.527344%2016.621094%2096.140625%2017.003906%2095.753906%2017.382812%20C%2095.621094%2017.515625%2095.488281%2017.644531%2095.351562%2017.777344%20C%2094.542969%2018.578125%2093.777344%2019.398438%2093.035156%2020.257812%20C%2092.882812%2020.429688%2092.730469%2020.601562%2092.578125%2020.773438%20C%2090.496094%2023.128906%2088.605469%2025.65625%2086.921875%2028.304688%20C%2086.859375%2028.398438%2086.800781%2028.492188%2086.738281%2028.589844%20C%2082.332031%2035.519531%2079.726562%2043.261719%2079.761719%2051.484375%20C%2079.761719%2051.628906%2079.761719%2051.777344%2079.761719%2051.929688%20C%2079.769531%2054.21875%2079.878906%2056.4375%2080.308594%2058.6875%20C%2080.335938%2058.84375%2080.367188%2059%2080.394531%2059.160156%20C%2081.59375%2065.671875%2084.15625%2071.628906%2086.855469%2077.636719%20C%2087.441406%2078.9375%2088.007812%2080.242188%2088.5625%2081.558594%20C%2088.640625%2081.738281%2088.71875%2081.917969%2088.796875%2082.101562%20C%2089.5625%2083.941406%2090.074219%2085.835938%2090.339844%2087.808594%20C%2090.359375%2087.941406%2090.378906%2088.074219%2090.398438%2088.207031%20C%2090.457031%2088.605469%2090.507812%2089.003906%2090.558594%2089.402344%20C%2090.574219%2089.515625%2090.589844%2089.632812%2090.605469%2089.753906%20C%2091.660156%2098.429688%2089.808594%20108.707031%2084.339844%20115.71875%20C%2082.507812%20118.011719%2080.503906%20120.136719%2078.160156%20121.917969%20C%2078.050781%20122.003906%2077.941406%20122.085938%2077.828125%20122.171875%20C%2074.722656%20124.546875%2071.398438%20126.402344%2067.914062%20128.160156%20C%2067.792969%20128.21875%2067.671875%20128.28125%2067.546875%20128.34375%20C%2066.144531%20129.054688%2064.726562%20129.738281%2063.304688%20130.417969%20C%2063.148438%20130.492188%2062.992188%20130.570312%2062.828125%20130.648438%20C%2062.085938%20131%2061.34375%20131.332031%2060.578125%20131.628906%20C%2059.996094%20131.855469%2059.496094%20132.105469%2058.988281%20132.472656%20C%2058.355469%20132.921875%2058.355469%20132.921875%2057.996094%20132.921875%20C%2057.941406%20133.03125%2057.886719%20133.140625%2057.828125%20133.25%20C%2057.160156%20133.164062%2056.789062%20132.976562%2056.269531%20132.554688%20C%2056.089844%20132.410156%2056.089844%20132.410156%2055.910156%20132.261719%20C%2055.617188%20132.019531%2055.328125%20131.773438%2055.039062%20131.523438%20C%2053.289062%20130.140625%2050.949219%20129.566406%2048.832031%20128.980469%20C%2048.316406%20128.835938%2047.804688%20128.6875%2047.292969%20128.535156%20C%2043.160156%20127.328125%2038.953125%20126.695312%2034.695312%20126.105469%20C%2027.628906%20125.125%2027.628906%20125.125%2024.359375%20124.085938%20C%2024.179688%20124.027344%2024.003906%20123.972656%2023.820312%20123.917969%20C%2020.761719%20122.929688%2018.183594%20121.507812%2015.847656%20119.292969%20C%2015.738281%20119.195312%2015.625%20119.101562%2015.511719%20119.003906%20C%2014.320312%20117.929688%2013.539062%20116.539062%2012.707031%20115.183594%20C%2012.621094%20115.050781%2012.539062%20114.914062%2012.453125%20114.777344%20C%208.5625%20108.476562%205.246094%20101.691406%204.109375%2094.328125%20C%204.078125%2094.121094%204.078125%2094.121094%204.046875%2093.910156%20C%202.847656%2085.726562%205.261719%2077.785156%207.570312%2070.019531%20C%2011.027344%2058.394531%2013.136719%2046.890625%2012.582031%2034.710938%20C%2012.574219%2034.558594%2012.566406%2034.40625%2012.5625%2034.25%20C%2012.429688%2031.386719%2012.15625%2028.550781%2011.824219%2025.707031%20C%2011.691406%2024.550781%2011.613281%2023.390625%2011.546875%2022.230469%20C%2012.046875%2022.710938%2012.492188%2023.175781%2012.878906%2023.75%20C%2012.964844%2023.878906%2013.054688%2024.007812%2013.144531%2024.140625%20C%2013.234375%2024.273438%2013.324219%2024.410156%2013.417969%2024.546875%20C%2013.609375%2024.832031%2013.800781%2025.113281%2013.996094%2025.398438%20C%2014.085938%2025.53125%2014.179688%2025.667969%2014.273438%2025.804688%20C%2014.570312%2026.238281%2014.878906%2026.65625%2015.195312%2027.074219%20C%2017.640625%2030.386719%2019.660156%2034.0625%2021.632812%2037.667969%20C%2021.769531%2037.917969%2021.769531%2037.917969%2021.910156%2038.175781%20C%2023.390625%2040.871094%2024.800781%2043.585938%2026.09375%2046.371094%20C%2026.179688%2046.550781%2026.261719%2046.730469%2026.347656%2046.917969%20C%2028.78125%2052.179688%2030.945312%2057.550781%2033.070312%2062.941406%20C%2033.320312%2063.578125%2033.574219%2064.210938%2033.835938%2064.84375%20C%2033.878906%2064.960938%2033.925781%2065.074219%2033.976562%2065.191406%20C%2034.101562%2065.496094%2034.226562%2065.796875%2034.351562%2066.101562%20C%2034.523438%2066.570312%2034.523438%2066.570312%2034.523438%2067.066406%20C%2034.632812%2067.066406%2034.742188%2067.066406%2034.855469%2067.066406%20C%2034.859375%2066.964844%2034.863281%2066.867188%2034.867188%2066.761719%20C%2034.984375%2064.960938%2035.332031%2063.203125%2035.660156%2061.429688%20C%2035.691406%2061.25%2035.726562%2061.074219%2035.757812%2060.890625%20C%2038.773438%2044.445312%2042.28125%2027.65625%2055.019531%201.535156%20Z%20M%2055.019531%201.535156%20'/%3e%3cpath%20style='%20stroke:none;fill-rule:nonzero;fill:rgb(90.588235%25,87.843137%25,0%25);fill-opacity:1;'%20d='M%2047.914062%2063.945312%20C%2047.964844%2063.945312%2048.019531%2063.945312%2048.078125%2063.945312%20C%2048.066406%2064.054688%2048.054688%2064.167969%2048.042969%2064.28125%20C%2047.6875%2068.070312%2047.746094%2071.882812%2048.574219%2075.605469%20C%2048.609375%2075.777344%2048.648438%2075.945312%2048.6875%2076.121094%20C%2050.164062%2082.699219%2053.597656%2094.394531%2058.492188%2099.253906%20C%2058.582031%2098.949219%2058.675781%2098.644531%2058.765625%2098.335938%20C%2058.855469%2098.050781%2058.941406%2097.765625%2059.027344%2097.480469%20C%2059.296875%2096.59375%2059.558594%2095.707031%2059.820312%2094.816406%20C%2064.261719%2079.753906%2064.261719%2079.753906%2069.234375%2076.917969%20C%2069.480469%2076.835938%2069.480469%2076.835938%2069.730469%2076.753906%20C%2069.496094%2077.242188%2069.222656%2077.6875%2068.925781%2078.140625%20C%2067.855469%2079.929688%2067.636719%2081.703125%2067.675781%2083.753906%20C%2067.675781%2083.871094%2067.675781%2083.984375%2067.679688%2084.105469%20C%2067.757812%2090.925781%2070.570312%2097.472656%2073.078125%20103.738281%20C%2073.628906%20105.113281%2074.160156%20106.496094%2074.65625%20107.894531%20C%2074.703125%20108.023438%2074.746094%20108.15625%2074.796875%20108.289062%20C%2075.796875%20111.164062%2076.078125%20113.488281%2074.695312%20116.332031%20C%2073.164062%20119.332031%2071.007812%20121.867188%2068.742188%20124.34375%20C%2068.449219%20124.664062%2068.164062%20124.996094%2067.882812%20125.328125%20C%2065.839844%20127.632812%2063.605469%20129.492188%2060.949219%20131.058594%20C%2060.796875%20131.167969%2060.796875%20131.167969%2060.640625%20131.28125%20C%2060.640625%20131.386719%2060.640625%20131.496094%2060.640625%20131.609375%20C%2060.527344%20131.664062%2060.417969%20131.714844%2060.300781%20131.769531%20C%2060.152344%20131.84375%2060.007812%20131.914062%2059.855469%20131.988281%20C%2059.636719%20132.09375%2059.636719%20132.09375%2059.414062%20132.203125%20C%2058.984375%20132.417969%2058.984375%20132.417969%2058.621094%20132.703125%20C%2058.324219%20132.921875%2058.324219%20132.921875%2057.996094%20132.921875%20C%2057.941406%20133.03125%2057.886719%20133.140625%2057.828125%20133.25%20C%2057.164062%20133.160156%2056.78125%20132.976562%2056.257812%20132.5625%20C%2056.078125%20132.421875%2056.078125%20132.421875%2055.894531%20132.277344%20C%2055.515625%20131.9375%2055.515625%20131.9375%2055.191406%20131.480469%20C%2054.507812%20130.648438%2053.449219%20130.234375%2052.5%20129.761719%20C%2052.390625%20129.707031%2052.277344%20129.648438%2052.167969%20129.59375%20C%2049.492188%20128.238281%2046.742188%20127.070312%2043.988281%20125.886719%20C%2042.027344%20125.042969%2040.089844%20124.148438%2038.160156%20123.234375%20C%2038.007812%20123.160156%2037.851562%20123.085938%2037.695312%20123.011719%20C%2034.445312%20121.46875%2031.410156%20119.765625%2028.902344%20117.15625%20C%2028.769531%20117.023438%2028.636719%20116.890625%2028.5%20116.753906%20C%2028.359375%20116.617188%2028.222656%20116.476562%2028.078125%20116.335938%20C%2027.9375%20116.203125%2027.9375%20116.203125%2027.789062%20116.066406%20C%2024.269531%20112.714844%2021.671875%20107.890625%2021.53125%20102.996094%20C%2021.515625%2099.28125%2022.265625%2095.769531%2023.195312%2092.191406%20C%2024.53125%2087.035156%2025.308594%2081.898438%2025.597656%2076.589844%20C%2025.878906%2077.007812%2026.015625%2077.285156%2026.167969%2077.746094%20C%2026.210938%2077.878906%2026.257812%2078.007812%2026.300781%2078.144531%20C%2026.347656%2078.285156%2026.398438%2078.425781%2026.445312%2078.570312%20C%2028.183594%2083.59375%2030.945312%2087.773438%2034.523438%2091.699219%20C%2034.601562%2091.785156%2034.679688%2091.871094%2034.761719%2091.960938%20C%2035.441406%2092.710938%2036.132812%2093.449219%2036.828125%2094.1875%20C%2037.6875%2095.105469%2038.539062%2096.035156%2039.367188%2096.984375%20C%2039.445312%2097.074219%2039.523438%2097.160156%2039.601562%2097.25%20C%2040.078125%2097.800781%2040.503906%2098.371094%2040.917969%2098.960938%20C%2041.019531%2099.109375%2041.125%2099.257812%2041.230469%2099.410156%20C%2041.308594%2099.519531%2041.386719%2099.632812%2041.464844%2099.746094%20C%2041.472656%2099.648438%2041.476562%2099.550781%2041.484375%2099.445312%20C%2043.15625%2069.152344%2043.15625%2069.152344%2047.914062%2063.945312%20Z%20M%2047.914062%2063.945312%20'/%3e%3cpath%20style='%20stroke:none;fill-rule:nonzero;fill:rgb(90.588235%25,54.509804%25,0%25);fill-opacity:1;'%20d='M%2050.722656%2025.347656%20C%2050.777344%2025.347656%2050.832031%2025.347656%2050.886719%2025.347656%20C%2050.917969%2026.402344%2050.851562%2027.421875%2050.726562%2028.46875%20C%2050.121094%2033.535156%2050.03125%2038.636719%2050.019531%2043.734375%20C%2050.019531%2043.929688%2050.019531%2044.125%2050.015625%2044.328125%20C%2049.992188%2051.167969%2050.574219%2058.226562%2052.707031%2064.765625%20C%2052.75%2064.902344%2052.792969%2065.039062%2052.839844%2065.179688%20C%2054.351562%2069.816406%2056.574219%2074.777344%2060.144531%2078.234375%20C%2060.164062%2078.0625%2060.1875%2077.894531%2060.207031%2077.722656%20C%2060.363281%2076.734375%2060.6875%2075.804688%2061%2074.855469%20C%2061.035156%2074.746094%2061.074219%2074.636719%2061.109375%2074.523438%20C%2064.253906%2064.929688%2067.953125%2053.804688%2075.847656%2047.027344%20C%2075.847656%2047.597656%2075.660156%2047.976562%2075.425781%2048.488281%20C%2074.847656%2049.773438%2074.355469%2051.0625%2073.976562%2052.417969%20C%2073.9375%2052.546875%2073.898438%2052.675781%2073.859375%2052.808594%20C%2073.121094%2055.558594%2072.953125%2058.398438%2072.972656%2061.230469%20C%2072.972656%2061.714844%2072.972656%2062.203125%2072.96875%2062.6875%20C%2072.964844%2064.949219%2073.191406%2067.132812%2073.53125%2069.363281%20C%2073.5625%2069.566406%2073.589844%2069.769531%2073.617188%2069.980469%20C%2073.980469%2072.550781%2074.535156%2075.0625%2075.183594%2077.574219%20C%2075.222656%2077.71875%2075.257812%2077.863281%2075.296875%2078.011719%20C%2076.09375%2081.128906%2077.054688%2084.1875%2078.066406%2087.242188%20C%2078.265625%2087.839844%2078.464844%2088.441406%2078.664062%2089.042969%20C%2079.230469%2090.769531%2079.800781%2092.496094%2080.390625%2094.214844%20C%2081.265625%2096.796875%2081.992188%2099.328125%2082.292969%20102.046875%20C%2082.308594%20102.183594%2082.324219%20102.324219%2082.339844%20102.464844%20C%2082.902344%20107.792969%2082.632812%20113.660156%2079.152344%20118.027344%20C%2078.878906%20118.34375%2078.605469%20118.65625%2078.324219%20118.960938%20C%2078.230469%20119.066406%2078.136719%20119.171875%2078.039062%20119.277344%20C%2077.71875%20119.625%2077.398438%20119.972656%2077.074219%20120.316406%20C%2076.972656%20120.425781%2076.871094%20120.535156%2076.769531%20120.648438%20C%2076.148438%20121.300781%2075.503906%20121.902344%2074.816406%20122.488281%20C%2074.476562%20122.78125%2074.148438%20123.089844%2073.820312%20123.398438%20C%2071.65625%20125.332031%2069.230469%20126.945312%2066.75%20128.449219%20C%2066.332031%20128.710938%2065.925781%20128.984375%2065.515625%20129.257812%20C%2064.703125%20129.773438%2063.851562%20130.1875%2062.984375%20130.601562%20C%2062.851562%20130.667969%2062.714844%20130.730469%2062.578125%20130.796875%20C%2061.875%20131.125%2061.253906%20131.367188%2060.472656%20131.445312%20C%2061.015625%20130.855469%2061.632812%20130.445312%2062.300781%20130.015625%20C%2064.953125%20128.289062%2067.171875%20126.109375%2069.234375%20123.726562%20C%2069.382812%20123.554688%2069.53125%20123.386719%2069.679688%20123.214844%20C%2072.464844%20119.996094%2075.898438%20115.921875%2075.558594%20111.421875%20C%2075.410156%20110.222656%2074.945312%20109.085938%2074.523438%20107.957031%20C%2074.484375%20107.855469%2074.445312%20107.75%2074.40625%20107.644531%20C%2073.566406%20105.390625%2072.707031%20103.148438%2071.832031%20100.910156%20C%2070.996094%2098.769531%2070.203125%2096.617188%2069.492188%2094.429688%20C%2069.425781%2094.226562%2069.359375%2094.023438%2069.292969%2093.8125%20C%2068.261719%2090.59375%2067.546875%2087.511719%2067.503906%2084.121094%20C%2067.5%2083.894531%2067.496094%2083.667969%2067.492188%2083.441406%20C%2067.441406%2081.101562%2067.96875%2079.132812%2069.398438%2077.246094%20C%2069.453125%2077.140625%2069.507812%2077.03125%2069.566406%2076.917969%20C%2069.335938%2077.070312%2069.101562%2077.21875%2068.871094%2077.371094%20C%2068.746094%2077.453125%2068.617188%2077.539062%2068.484375%2077.625%20C%2067.660156%2078.191406%2067.039062%2078.769531%2066.464844%2079.585938%20C%2066.394531%2079.6875%2066.324219%2079.789062%2066.25%2079.894531%20C%2062.761719%2084.929688%2061%2091.019531%2059.429688%2096.867188%20C%2059.265625%2097.476562%2059.089844%2098.082031%2058.914062%2098.691406%20C%2058.863281%2098.867188%2058.8125%2099.042969%2058.761719%2099.222656%20C%2058.726562%2099.34375%2058.691406%2099.460938%2058.65625%2099.582031%20C%2058.144531%2098.984375%2057.746094%2098.359375%2057.378906%2097.664062%20C%2057.324219%2097.558594%2057.265625%2097.453125%2057.207031%2097.347656%20C%2057.023438%2097.003906%2056.84375%2096.660156%2056.664062%2096.320312%20C%2056.597656%2096.199219%2056.535156%2096.082031%2056.472656%2095.960938%20C%2052.898438%2089.222656%2049.890625%2082.242188%2048.242188%2074.785156%20C%2048.191406%2074.554688%2048.191406%2074.554688%2048.140625%2074.324219%20C%2047.433594%2071.074219%2047.53125%2067.402344%2047.914062%2064.109375%20C%2041.558594%2073.902344%2042.164062%2088.839844%2041.632812%20100.074219%20C%2041.277344%2099.640625%2040.929688%2099.203125%2040.589844%2098.757812%20C%2039.5%2097.339844%2038.316406%2096.042969%2037.082031%2094.75%20C%2036.703125%2094.347656%2036.34375%2093.933594%2035.984375%2093.519531%20C%2035.652344%2093.144531%2035.3125%2092.78125%2034.96875%2092.417969%20C%2034.003906%2091.390625%2033.082031%2090.34375%2032.210938%2089.234375%20C%2032.132812%2089.140625%2032.054688%2089.042969%2031.976562%2088.941406%20C%2029.140625%2085.328125%2027.199219%2081.429688%2025.761719%2077.082031%20C%2025.746094%2077.3125%2025.746094%2077.3125%2025.726562%2077.546875%20C%2025.300781%2083.097656%2024.273438%2088.355469%2022.976562%2093.765625%20C%2021.476562%20100.054688%2020.96875%20106.039062%2024.503906%20111.78125%20C%2025.695312%20113.621094%2027.117188%20115.21875%2028.675781%20116.761719%20C%2028.914062%20117.003906%2029.152344%20117.246094%2029.382812%20117.496094%20C%2031.265625%20119.5%2033.757812%20120.824219%2036.175781%20122.082031%20C%2036.304688%20122.152344%2036.433594%20122.21875%2036.566406%20122.289062%20C%2039.777344%20123.960938%2043.117188%20125.363281%2046.433594%20126.808594%20C%2048.621094%20127.761719%2050.789062%20128.742188%2052.914062%20129.832031%20C%2053.089844%20129.921875%2053.265625%20130.015625%2053.449219%20130.109375%20C%2054.667969%20130.746094%2054.667969%20130.746094%2054.855469%20131.117188%20C%2054.246094%20130.9375%2053.695312%20130.707031%2053.128906%20130.429688%20C%2050.515625%20129.242188%2047.617188%20128.640625%2044.84375%20127.933594%20C%2044.699219%20127.898438%2044.558594%20127.859375%2044.410156%20127.824219%20C%2043.996094%20127.71875%2043.582031%20127.613281%2043.167969%20127.507812%20C%2043.046875%20127.476562%2042.921875%20127.445312%2042.792969%20127.414062%20C%2042.132812%20127.25%2041.480469%20127.109375%2040.804688%20127.011719%20C%2040.804688%20126.902344%2040.804688%20126.792969%2040.804688%20126.679688%20C%2040.503906%20126.660156%2040.503906%20126.660156%2040.199219%20126.636719%20C%2039.136719%20126.519531%2038.128906%20126.21875%2037.105469%20125.921875%20C%2036.902344%20125.863281%2036.695312%20125.804688%2036.484375%20125.742188%20C%2029.792969%20123.785156%2025.03125%20120.792969%2020.640625%20115.347656%20C%2020.496094%20115.179688%2020.347656%20115.007812%2020.203125%20114.839844%20C%2015.679688%20109.609375%2012.914062%20103.800781%2013.410156%2096.8125%20C%2013.480469%2096.304688%2013.582031%2095.8125%2013.699219%2095.3125%20C%2013.746094%2095.101562%2013.792969%2094.890625%2013.839844%2094.671875%20C%2014.644531%2091.269531%2016.007812%2087.988281%2017.230469%2084.71875%20C%2017.484375%2084.035156%2017.742188%2083.351562%2017.996094%2082.667969%20C%2018.039062%2082.546875%2018.085938%2082.425781%2018.128906%2082.304688%20C%2018.875%2080.285156%2019.339844%2078.191406%2019.8125%2076.097656%20C%2019.839844%2075.972656%2019.871094%2075.847656%2019.898438%2075.71875%20C%2021.296875%2069.460938%2021.089844%2062.273438%2019.722656%2056.035156%20C%2019.648438%2055.570312%2019.648438%2055.570312%2019.8125%2055.074219%20C%2019.886719%2055.21875%2019.957031%2055.363281%2020.035156%2055.515625%20C%2020.785156%2057.011719%2021.542969%2058.511719%2022.300781%2060.007812%20C%2023.046875%2061.488281%2023.796875%2062.96875%2024.542969%2064.449219%20C%2025.039062%2065.433594%2025.539062%2066.421875%2026.039062%2067.410156%20C%2028.234375%2071.75%2030.40625%2076.085938%2032.375%2080.53125%20C%2032.503906%2080.816406%2032.632812%2081.105469%2032.761719%2081.390625%20C%2033.046875%2082.03125%2033.332031%2082.671875%2033.613281%2083.3125%20C%2033.660156%2083.421875%2033.707031%2083.527344%2033.757812%2083.636719%20C%2035.742188%2088.15625%2035.742188%2088.15625%2036.011719%2089.402344%20C%2036.035156%2089.242188%2036.058594%2089.085938%2036.085938%2088.925781%20C%2036.753906%2084.660156%2037.46875%2080.398438%2038.253906%2076.148438%20C%2038.332031%2075.722656%2038.414062%2075.296875%2038.492188%2074.867188%20C%2039.492188%2069.410156%2040.621094%2063.984375%2041.839844%2058.570312%20C%2042.011719%2057.8125%2042.179688%2057.054688%2042.351562%2056.292969%20C%2042.550781%2055.394531%2042.753906%2054.496094%2042.953125%2053.597656%20C%2042.984375%2053.464844%2043.015625%2053.328125%2043.042969%2053.191406%20C%2043.730469%2050.125%2044.460938%2047.074219%2045.226562%2044.03125%20C%2045.265625%2043.878906%2045.304688%2043.726562%2045.34375%2043.570312%20C%2046.886719%2037.441406%2048.519531%2031.28125%2050.722656%2025.347656%20Z%20M%2050.722656%2025.347656%20'/%3e%3cpath%20style='%20stroke:none;fill-rule:nonzero;fill:rgb(99.607843%25,99.607843%25,61.568627%25);fill-opacity:1;'%20d='M%2026.425781%2091.699219%20C%2027.089844%2092.320312%2027.648438%2093.003906%2028.21875%2093.714844%20C%2029.796875%2095.699219%2031.449219%2097.632812%2033.164062%2099.503906%20C%2033.472656%2099.847656%2033.777344%20100.191406%2034.082031%20100.539062%20C%2036.058594%20102.785156%2038.136719%20105.058594%2040.433594%20106.992188%20C%2040.746094%20107.253906%2041.054688%20107.519531%2041.359375%20107.785156%20C%2042.589844%20108.859375%2043.839844%20109.886719%2045.148438%20110.863281%20C%2045.742188%20111.3125%2046.332031%20111.773438%2046.921875%20112.230469%20C%2046.949219%20111.945312%2046.949219%20111.945312%2046.980469%20111.660156%20C%2047.488281%20106.898438%2048.132812%20102.242188%2049.398438%2097.613281%20C%2049.453125%2097.613281%2049.507812%2097.613281%2049.566406%2097.613281%20C%2049.589844%2097.753906%2049.617188%2097.898438%2049.644531%2098.046875%20C%2050.960938%20104.9375%2053.917969%20111.40625%2058.160156%20116.992188%20C%2058.636719%20115.535156%2058.820312%20114.074219%2059%20112.558594%20C%2059.683594%20106.847656%2061.195312%20102.160156%2065.929688%2098.433594%20C%2066.09375%2098.378906%2066.257812%2098.324219%2066.425781%2098.269531%20C%2066.390625%2098.367188%2066.351562%2098.464844%2066.316406%2098.566406%20C%2065.449219%20101.363281%2065.851562%20104.359375%2066.589844%20107.136719%20C%2066.636719%20107.320312%2066.683594%20107.5%2066.730469%20107.6875%20C%2067.09375%20109.082031%2067.515625%20110.449219%2067.96875%20111.8125%20C%2070.175781%20118.445312%2070.175781%20118.445312%2068.738281%20121.589844%20C%2067.980469%20123.050781%2066.902344%20124.195312%2065.761719%20125.367188%20C%2065.609375%20125.539062%2065.609375%20125.539062%2065.453125%20125.714844%20C%2063.980469%20127.300781%2062.023438%20128.488281%2060.121094%20129.492188%20C%2060.007812%20129.554688%2059.894531%20129.613281%2059.78125%20129.675781%20C%2059.464844%20129.835938%2059.144531%20129.984375%2058.820312%20130.128906%20C%2058.640625%20130.214844%2058.460938%20130.296875%2058.273438%20130.382812%20C%2057.339844%20130.5%2056.699219%20130.109375%2055.878906%20129.699219%20C%2055.566406%20129.550781%2055.253906%20129.402344%2054.945312%20129.25%20C%2054.792969%20129.179688%2054.640625%20129.105469%2054.480469%20129.027344%20C%2053.914062%20128.761719%2053.332031%20128.535156%2052.746094%20128.308594%20C%2052.234375%20128.105469%2051.75%20127.863281%2051.257812%20127.617188%20C%2051.03125%20127.5%2050.804688%20127.386719%2050.582031%20127.273438%20C%2050.449219%20127.207031%2050.320312%20127.144531%2050.1875%20127.074219%20C%2049.320312%20126.640625%2048.449219%20126.210938%2047.582031%20125.777344%20C%2047.25%20125.613281%2046.921875%20125.449219%2046.589844%20125.285156%20C%2045.292969%20124.640625%2045.292969%20124.640625%2043.992188%20124%20C%2030.625%20117.46875%2030.625%20117.46875%2028.699219%20111.90625%20C%2028.316406%20110.386719%2028.207031%20108.976562%2028.246094%20107.414062%20C%2028.253906%20106.988281%2028.257812%20106.5625%2028.265625%20106.136719%20C%2028.265625%20106.027344%2028.269531%20105.917969%2028.269531%20105.808594%20C%2028.328125%20101.957031%2028.375%2098.21875%2027.25%2094.492188%20C%2027.207031%2094.347656%2027.167969%2094.207031%2027.121094%2094.058594%20C%2026.957031%2093.503906%2026.777344%2092.960938%2026.570312%2092.421875%20C%2026.425781%2092.027344%2026.425781%2092.027344%2026.425781%2091.699219%20Z%20M%2026.425781%2091.699219%20'/%3e%3c/g%3e%3c/svg%3e\"","import { CompositeLayer, GeoJsonLayer } from 'deck.gl';\nimport FireIcon from './icons/FireIcon.svg';\n\nconst getIconSize = (d) => {\n const { IncidentSize } = d.properties;\n let scale = 25;\n if (IncidentSize > 100000) scale = 50;\n else if (IncidentSize > 10000) scale = 40;\n else if (IncidentSize > 5000) scale = 30;\n else if (IncidentSize > 0) scale = 25;\n return scale;\n};\n\nfunction numberWithCommas(x) {\n return x.toString().replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');\n}\n\nconst formatNumber = (value) =>\n Number.isNaN(parseInt(value, 10)) ? null : numberWithCommas(parseInt(value, 10));\n\nconst defaultProps = {\n incidents: 'active',\n pointType: 'icon+text',\n iconAtlas: FireIcon,\n iconMapping: {\n marker: { x: 0, y: 0, width: 100, height: 136, anchorY: 0 },\n },\n getIconSize,\n getIcon: () => 'marker',\n parameters: { depthTest:false, depthCompare: 'always', cullMode: 'front' },\n pickingFunction: (d) => {\n if (d.object) {\n const {\n IncidentName,\n IncidentSize,\n IncidentTypeCategory,\n PercentContained,\n EstimatedCostToDate,\n TotalIncidentPersonnel,\n } = d.object.properties;\n\n // Initialize an array to store available rows\n const readout = [];\n\n // Conditionally add each variable to the tooltip\n if (IncidentName)\n readout.push(\n <div key=\"name\">\n <strong>Incident Name:</strong> {IncidentName}\n <br />\n </div>,\n );\n const incidentSize = formatNumber(IncidentSize);\n if (incidentSize)\n readout.push(\n <div key=\"size\">\n <strong>Incident Size:</strong> {incidentSize} acres\n <br />\n </div>,\n );\n\n const percentContained = formatNumber(PercentContained);\n if (percentContained)\n readout.push(\n <div key=\"contained\">\n <strong>Percent Contained:</strong> {percentContained}\n <br />\n </div>,\n );\n\n if (IncidentTypeCategory)\n readout.push(\n <div key=\"type\">\n <strong>Incident Type:</strong> {IncidentTypeCategory}\n <br />\n </div>,\n );\n\n const incidentCost = formatNumber(EstimatedCostToDate);\n if (incidentCost)\n readout.push(\n <div key=\"cost\">\n <strong>Estimated Cost:</strong> {incidentCost}\n <br />\n </div>,\n );\n\n const totalPersonnel = formatNumber(TotalIncidentPersonnel);\n if (totalPersonnel)\n readout.push(\n <div key=\"personnel\">\n <strong>Total Personnel:</strong> {totalPersonnel}\n <br />\n </div>,\n );\n\n return { readout };\n }\n return { readout: null };\n },\n};\n\nclass NIFCLayer extends CompositeLayer {\n renderLayers() {\n return new GeoJsonLayer(this.props, {\n id: `${this.props.id}-geojson`,\n });\n }\n}\nNIFCLayer.defaultProps = defaultProps;\nNIFCLayer.layerName = 'NIFCLayer';\nexport default NIFCLayer;\n","import { GeoJsonLayer } from '@deck.gl/layers';\nimport { CompositeLayer } from 'deck.gl';\n\n// Helper function to get color based on category and probability\nconst getFillColor = (idpSource, category, probability) => {\n const colorMaps = {\n precipitation: {\n Above: [\n [40, 85, 23, 255],\n [40, 85, 61, 255],\n [0, 142, 64, 255],\n [58, 123, 95, 255],\n [72, 174, 56, 255],\n [148, 205, 126, 255],\n [179, 217, 171, 255],\n [255, 255, 255, 0],\n ],\n Below: [\n [79, 47, 47, 255],\n [128, 64, 0, 255],\n [147, 70, 57, 255],\n [155, 80, 49, 255],\n [187, 109, 51, 255],\n [216, 167, 80, 255],\n [240, 212, 147, 255],\n [255, 255, 255, 0],\n ],\n },\n temperature: {\n Above: [\n [98, 34, 40, 255],\n [138, 47, 56, 255],\n [204, 48, 71, 255],\n [199, 46, 40, 255],\n [220, 86, 47, 255],\n [227, 139, 74, 255],\n [231, 177, 104, 255],\n [255, 255, 255, 0],\n ],\n Below: [\n [28, 19, 66, 255],\n [34, 24, 82, 255],\n [47, 64, 111, 255],\n [0, 92, 161, 255],\n [56, 159, 219, 255],\n [119, 181, 226, 255],\n [160, 192, 223, 255],\n [255, 255, 255, 0],\n ],\n },\n };\n let colorTemplate;\n if (idpSource.includes('temp')) colorTemplate = 'temperature';\n if (idpSource.includes('prcp')) colorTemplate = 'precipitation';\n if (!colorTemplate) console.log('Unknown color template:', idpSource);\n\n const colorMap = colorMaps[colorTemplate] || {};\n\n const thresholds = [90, 80, 70, 60, 50, 40, 33];\n\n if (category === 'Above' || category === 'Below') {\n const colors = colorMap[category] || [];\n for (let i = 0; i < thresholds.length; i += 1) {\n if (probability >= thresholds[i]) {\n return colors[i] || [255, 255, 255, 0]; // Default color if not found\n }\n }\n return colors[colors.length - 1] || [255, 255, 255, 0]; // Default color for the lowest probability\n }\n\n return [0, 0, 0, 0];\n};\n\nconst defaultProps = {\n getFillColor: (f) =>\n getFillColor(this.legend.layerType, f.properties.cat, f.properties.prob, f),\n getLineColor: [0, 0, 0],\n parameters: { depthTest:false, depthCompare: 'always', cullMode: 'back' },\n pickingFunction: (d) => {\n const threshold = 1704070800 * 1000; // Convert to milliseconds\n if (d.object) {\n const { properties } = d.object;\n const start = new Date(properties.start_date);\n const end = new Date(properties.end_date);\n\n // Format date function to include day of the week in UTC\n const formatDateUTC = (date) => {\n if (date instanceof Date && !Number.isNaN(date)) {\n const options = {\n weekday: 'short',\n year: 'numeric',\n month: 'short',\n day: 'numeric',\n timeZone: 'UTC', // Use UTC\n };\n return date.toLocaleString('en-US', options);\n }\n return 'Not available';\n };\n\n // Check if start and end dates are greater than the threshold\n const startInfo = start.getTime() > threshold ? formatDateUTC(start) : 'Not available';\n const endInfo = end.getTime() > threshold ? formatDateUTC(end) : 'Not available';\n\n const readout = (\n <>\n <strong>Category:</strong> {properties.cat || 'Not available'}\n <br />\n <strong>Probability:</strong> {`${properties.prob}%` || 'Not available'}\n <br />\n <strong>Valid:</strong> {startInfo} - {endInfo}\n </>\n );\n return { readout };\n }\n return { readout: null };\n },\n};\nclass CPCLayer extends CompositeLayer {\n renderLayers() {\n return new GeoJsonLayer(this.props, {\n id: `${this.props.id}-geojson`,\n getFillColor: (f) => getFillColor(this.props.legend.layerType, f.properties.cat, f.properties.prob),\n });\n }\n}\nCPCLayer.defaultProps = defaultProps;\nCPCLayer.layerName = 'CPCLayer';\nexport default CPCLayer;\n","import { CompositeLayer, GeoJsonLayer } from 'deck.gl';\n\n// Define the color mapping function\nconst getFillColor = (f) => {\n const colorMapping = {\n 2: [192, 232, 192],\n 3: [127, 197, 127],\n 4: [246, 246, 127],\n 5: [230, 194, 127],\n 6: [230, 127, 127],\n 8: [255, 127, 255],\n };\n return colorMapping[f.properties.dn] || [255, 255, 255];\n};\n\nfunction parseAndFormatDay(input) {\n if (input === 'Not available' || !input) {\n return 'Day Not Available'; // Return a more meaningful message\n }\n const dayPart = input.split('_')[0]; // Get the first part\n const dayNumber = dayPart.replace(/\\D/g, ''); // Extract numeric part\n return `Day ${dayNumber || 'Not Available'}`; // Handle empty numeric part\n}\n\nfunction formatDateTime(input) {\n if (!input || input === 'Not available') return 'Not available'; // Handle empty or \"Not available\" input\n\n // Ensure the input length is correct for date parsing\n if (input.length !== 12) return 'Not available'; // Return if the format is not as expected\n\n const year = input.slice(0, 4);\n const month = input.slice(4, 6);\n const day = input.slice(6, 8);\n const time = `${input.slice(8, 10)}:${input.slice(10, 12)}`;\n\n const date = new Date(`${year}-${month}-${day}T${time}:00Z`);\n\n if (Number.isNaN(date.getTime())) return 'Not available'; // Check for invalid date\n\n const options = { weekday: 'short' };\n const dayOfWeek = new Intl.DateTimeFormat('en-US', options).format(date);\n return `${time}Z ${dayOfWeek} ${month}/${day}`;\n}\n\nconst defaultProps = {\n getFillColor,\n getLineColor: [0, 0, 0],\n parameters: { depthTest:false, depthCompare: 'always', cullMode: 'back' },\n pickingFunction: (d) => {\n if (d.object) {\n const dnMapping = {\n 2: 'General Thunderstorm',\n 3: 'Marginal',\n 4: 'Slight',\n 5: 'Enhanced',\n 6: 'Moderate',\n 8: 'High',\n };\n const dnValue = d.object.properties.dn;\n const category = dnMapping[dnValue] || 'Not available';\n const idpSource = d.object.properties.idp_source || 'Not available';\n const valid = d.object.properties.valid || 'Not available';\n const expire = d.object.properties.expire || 'Not available';\n\n const readout = (\n <>\n <strong>{parseAndFormatDay(idpSource)} Categorical Outlook</strong>\n <br />\n <strong>Valid:</strong> {formatDateTime(valid)} - {formatDateTime(expire)}\n <br />\n <strong>Category:</strong> {category}\n <br />\n </>\n );\n return { readout };\n }\n return { readout: null };\n },\n};\nclass SPCLayer extends CompositeLayer {\n renderLayers() {\n return new GeoJsonLayer(this.props, {\n id: `${this.props.id}-geojson`,\n });\n }\n}\nSPCLayer.defaultProps = defaultProps;\nSPCLayer.layerName = 'SPCLayer';\nexport default SPCLayer;\n","import { CompositeLayer, GeoJsonLayer } from 'deck.gl';\n\nconst defaultProps = {\n getFillColor: (f) => {\n const colorMap = {\n 1: [0, 205, 0],\n 2: [238, 238, 0],\n 3: [255, 0, 0],\n 4: [255, 0, 255],\n };\n return colorMap[f.properties.dn] || [255, 255, 255];\n },\n getLineColor: [0, 0, 0],\n parameters: { depthTest:false, depthCompare: 'always', cullMode: 'back' },\n pickingFunction: (d) => {\n if (d.object) {\n const dnMapping = {\n 1: 'Marginal (At Least 5%)',\n 2: 'Slight (At Least 15%)',\n 3: 'Moderate (At Least 40%)',\n 4: 'High (At Least 70%)',\n };\n const dnValue = d.object.properties.dn;\n const category = dnMapping[dnValue] || 'Not available';\n const readout = (\n <>\n <strong>Outlook:</strong> {d.object.properties.product || 'Not available'}\n <br />\n <strong>Category:</strong> {category || 'Not available'}\n <br />\n <strong>Valid Time:</strong> {d.object.properties.valid_time || 'Not available'}\n </>\n );\n return { readout };\n }\n return { readout: null };\n },\n};\nclass WPCLayer extends CompositeLayer {\n renderLayers() {\n return new GeoJsonLayer(this.props, {\n id: `${this.props.id}-geojson`,\n });\n }\n}\nWPCLayer.defaultProps = defaultProps;\nWPCLayer.layerName = 'WPCLayer';\nexport default WPCLayer;\n","import { CompositeLayer, GeoJsonLayer } from 'deck.gl';\nimport gUtilities from '../../utilities/graphicsUtilities';\n// Map to track features by coordinates\nconst seenFeaturesMap = new Map();\n\nfunction getFeatureKey(f) {\n const coords = JSON.stringify(f.geometry.coordinates);\n const type = f.properties.phenomenon;\n const sig = f.properties.significance;\n return {\n key: `${coords}-${type}-${sig}`, // Unique key combining coordinates, phenomenon, and significance\n coordinates: coords, // Stringified coordinates\n phenomenon: type, // Phenomenon property\n significance: sig, // Significance property\n };\n}\nfunction getColor(f) {\n return f.properties.color ? gUtilities.hexToRgb(f.properties.color) : [255, 0, 0];\n}\n\nfunction getFillColor(f) {\n const coordinatesStr = JSON.stringify(f.geometry.coordinates);\n const featureInfo = getFeatureKey(f);\n\n if (seenFeaturesMap.has(coordinatesStr)) {\n const existingFeature = seenFeaturesMap.get(coordinatesStr);\n\n // Check if the existing feature has the same phenomenon and significance\n if (\n existingFeature.phenomenon !== featureInfo.phenomenon ||\n existingFeature.significance !== featureInfo.significance\n ) {\n // Properties differ, return semi-transparent fill\n return [...getColor(f), 128]; // Semi-transparent fill\n }\n // Same properties, use original color\n return getColor(f);\n }\n\n // Store the new feature\n seenFeaturesMap.set(coordinatesStr, {\n phenomenon: featureInfo.phenomenon,\n significance: featureInfo.significance,\n });\n return getColor(f); // First time seeing this feature\n}\n\nconst defaultProps = {\n filled: true,\n lineWidthMinPixels: 1,\n getFillColor,\n getLineColor: (f) =>\n f.properties.color ? gUtilities.hexToRgb(f.properties.color) : [255, 255, 255],\n getLineWidth: 2,\n stroked: true,\n opacity: 0.5,\n parameters: { depthTest:false, depthCompare: 'always', cullMode: 'back' },\n pickingFunction: (d) => {\n const threshold = 1704070800 * 1000; // Convert to milliseconds\n\n if (d.object) {\n const { properties } = d.object;\n const issued = new Date(properties.issuance * 1000);\n const end = new Date(properties.end * 1000);\n\n // Check if issued and end dates are greater than the threshold\n const issuedInfo =\n issued.getTime() > threshold ? issued.toLocaleString() : 'Not available';\n const endInfo = end.getTime() > threshold ? end.toLocaleString() : 'Not available';\n\n const readout = (\n <>\n <strong>Type:</strong> {properties.phenomenon || 'Not available'}\n <br />\n <strong>Significance:</strong> {properties.significance || 'Not available'}\n <br />\n <strong>Issued:</strong> {issuedInfo}\n <br />\n <strong>Expiration:</strong> {endInfo}\n </>\n );\n const dynamicLegend = {\n color: gUtilities.rgb_to_string(getColor(d.object)),\n text: `${properties.phenomenon} ${properties.significance}`,\n };\n return { readout, dynamicLegend };\n }\n return { readout: null };\n },\n};\n\nclass WWALayer extends CompositeLayer {\n renderLayers() {\n return new GeoJsonLayer(this.props, {\n id: `${this.props.id}-geojson`,\n });\n }\n}\nWWALayer.defaultProps = defaultProps;\nWWALayer.layerName = 'WWALayer';\nexport default WWALayer;\n","{\n \"version\": 8,\n \"glyphs\": \"https://basemaps.arcgis.com/arcgis/rest/services/World_Basemap_v2/VectorTileServer/resources/fonts/{fontstack}/{range}.pbf?token=\",\n \"sources\": {\n \"esri\": {\n \"type\": \"vector\",\n \"url\": \"https://basemaps.arcgis.com/arcgis/rest/services/World_Basemap_v2/VectorTileServer\",\n \"tiles\": [\n \"https://basemaps.arcgis.com/arcgis/rest/services/World_Basemap_v2/VectorTileServer/tile/{z}/{y}/{x}.pbf?token=\"\n ]\n }\n },\n \"layers\": [\n {\n \"id\": \"Land/Not ice\",\n \"type\": \"fill\",\n \"source\": \"esri\",\n \"source-layer\": \"Land\",\n \"filter\": [\"==\", \"_symbol\", 0],\n \"layout\": {},\n \"paint\": {\n \"fill-color\": \"#4e5155\"\n }\n },\n {\n \"id\": \"Land/Coastline\",\n \"type\": \"line\",\n \"source\": \"esri\",\n \"source-layer\": \"Land\",\n \"layout\": {\n \"line-cap\": \"round\",\n \"line-join\": \"round\",\n \"visibility\": \"none\"\n },\n \"paint\": {\n \"line-color\": \"#9e9ba8\",\n \"line-width\": {\n \"stops\": [\n [0, 2],\n [9, 2]\n ]\n }\n }\n },\n {\n \"id\": \"Land/Ice\",\n \"type\": \"fill\",\n \"source\": \"esri\",\n \"source-layer\": \"Land\",\n \"filter\": [\"==\", \"_symbol\", 1],\n \"layout\": {},\n \"paint\": {\n \"fill-color\": \"#4e5155\"\n }\n },\n {\n \"id\": \"Land/Ice/Coastline\",\n \"type\": \"line\",\n \"source\": \"esri\",\n \"source-layer\": \"Land\",\n \"filter\": [\"==\", \"_symbol\", 1],\n \"layout\": {\n \"line-cap\": \"round\",\n \"line-join\": \"round\",\n \"visibility\": \"none\"\n },\n \"paint\": {\n \"line-color\": \"#9e9ba8\",\n \"line-width\": {\n \"stops\": [\n [0, 2],\n [9, 2]\n ]\n }\n }\n },\n {\n \"id\": \"Airport/Airport property\",\n \"type\": \"fill\",\n \"source\": \"esri\",\n \"source-layer\": \"Airport\",\n \"filter\": [\"==\", \"_symbol\", 1],\n \"minzoom\": 9,\n \"layout\": {},\n \"paint\": {\n \"fill-color\": \"#2d3947\",\n \"fill-opacity\": 0.15\n }\n },\n {\n \"id\": \"Airport/Airport runway\",\n \"type\": \"fill\",\n \"source\": \"esri\",\n \"source-layer\": \"Airport\",\n \"filter\": [\"==\", \"_symbol\", 0],\n \"minzoom\": 11,\n \"layout\": {},\n \"paint\": {\n \"fill-color\": \"#2d3947\"\n }\n },\n {\n \"id\": \"Water line small scale\",\n \"type\": \"line\",\n \"source\": \"esri\",\n \"source-layer\": \"Water line small scale\",\n \"minzoom\": 1,\n \"maxzoom\": 5,\n \"layout\": {\n \"line-join\": \"round\"\n },\n \"paint\": {\n \"line-color\": \"#292f3d\",\n \"line-width\": 0.5\n }\n },\n {\n \"id\": \"Water line medium scale\",\n \"type\": \"line\",\n \"source\": \"esri\",\n \"source-layer\": \"Water line medium scale\",\n \"minzoom\": 5,\n \"maxzoom\": 7,\n \"layout\": {\n \"line-join\": \"round\"\n },\n \"paint\": {\n \"line-color\": \"#292f3d\",\n \"line-width\": {\n \"base\": 1.2,\n \"stops\": [\n [5, 0.5],\n [7, 0.7]\n ]\n }\n }\n },\n {\n \"id\": \"Water line large scale\",\n \"type\": \"line\",\n \"source\": \"esri\",\n \"source-layer\": \"Water line large scale\",\n \"minzoom\": 7,\n \"maxzoom\": 11,\n \"layout\": {\n \"line-cap\": \"round\",\n \"line-join\": \"round\"\n },\n \"paint\": {\n \"line-color\": \"#292f3d\",\n \"line-width\": 0.7\n }\n },\n {\n \"id\": \"Water line/Stream or river\",\n \"type\": \"line\",\n \"source\": \"esri\",\n \"source-layer\": \"Water line\",\n \"filter\": [\"==\", \"_symbol\", 0],\n \"minzoom\": 11,\n \"layout\": {\n \"line-cap\": \"round\"\n },\n \"paint\": {\n \"line-color\": \"#292f3d\",\n \"line-width\": {\n \"base\": 1.2,\n \"stops\": [\n [11, 0.7],\n [14, 0.7],\n [17, 2]\n ]\n }\n }\n },\n {\n \"id\": \"Marine area/detail\",\n \"type\": \"fill\",\n \"source\": \"esri\",\n \"source-layer\": \"Marine area\",\n \"layout\": {},\n \"paint\": {\n \"fill-color\": \"#292f3d\"\n }\n },\n {\n \"id\": \"Water area small scale\",\n \"type\": \"fill\",\n \"source\": \"esri\",\n \"source-layer\": \"Water area small scale\",\n \"minzoom\": 1,\n \"maxzoom\": 5,\n \"layout\": {},\n \"paint\": {\n \"fill-color\": \"#292f3d\"\n }\n },\n {\n \"id\": \"Water area medium scale/Lake or river\",\n \"type\": \"fill\",\n \"source\": \"esri\",\n \"source-layer\": \"Water area medium scale\",\n \"filter\": [\"==\", \"_symbol\", 0],\n \"minzoom\": 5,\n \"maxzoom\": 7,\n \"layout\": {},\n \"paint\": {\n \"fill-color\": \"#292f3d\"\n }\n },\n {\n \"id\": \"Water area large scale/Lake or river\",\n \"type\": \"fill\",\n \"source\": \"esri\",\n \"source-layer\": \"Water area large scale\",\n \"filter\": [\"==\", \"_symbol\", 0],\n \"minzoom\": 7,\n \"maxzoom\": 11,\n \"layout\": {},\n \"paint\": {\n \"fill-color\": \"#292f3d\"\n }\n },\n {\n \"id\": \"Water area/Lake, river or bay\",\n \"type\": \"fill\",\n \"source\": \"esri\",\n \"source-layer\": \"Water area\",\n \"filter\": [\"==\", \"_symbol\", 7],\n \"minzoom\": 11,\n \"layout\": {},\n \"paint\": {\n \"fill-color\": \"#292f3d\"\n }\n },\n {\n \"id\": \"Water area/Dam or weir\",\n \"type\": \"fill\",\n \"source\": \"esri\",\n \"source-layer\": \"Water area\",\n \"filter\": [\"==\", \"_symbol\", 5],\n \"minzoom\": 11,\n \"layout\": {},\n \"paint\": {\n \"fill-color\": \"#292f3d\",\n \"fill-outline-color\": \"#292f3d\"\n }\n },\n {\n \"id\": \"Boundary line/Disputed admin2/0\",\n \"type\": \"line\",\n \"source\": \"esri\",\n \"source-layer\": \"Boundary line\",\n \"filter\": [\"all\", [\"==\", \"_symbol\", 8], [\"!in\", \"Viz\", 3]],\n \"minzoom\": 8,\n \"layout\": {\n \"line-join\": \"round\",\n \"visibility\": \"none\"\n },\n \"paint\": {\n \"line-color\": \"#e9ebec\",\n \"line-opacity\": 0.5,\n \"line-dasharray\": [2, 3],\n \"line-width\": 1.5\n },\n \"showProperties\": false\n },\n {\n \"id\": \"Boundary line/Disputed admin1/1\",\n \"type\": \"line\",\n \"source\": \"esri\",\n \"source-layer\": \"Boundary line\",\n \"minzoom\": 4,\n \"filter\": [\"all\", [\"==\", \"_symbol\", 7], [\"!in\", \"Viz\", 3]],\n \"layout\": {\n \"line-join\": \"round\"\n },\n \"paint\": {\n \"line-color\": \"#e9ebec\",\n \"line-opacity\": 0.5,\n \"line-width\": {\n \"base\": 1,\n \"stops\": [\n [4, 2],\n [6, 3.5],\n [14, 7],\n [17, 7]\n ]\n }\n },\n \"showProperties\": false\n },\n {\n \"id\": \"Boundary line/Disputed admin0/1\",\n \"type\": \"line\",\n \"source\": \"esri\",\n \"source-layer\": \"Boundary line\",\n \"filter\": [\n \"all\",\n [\"==\", \"_symbol\", 6],\n [\"!in\", \"Viz\", 3],\n [\"!in\", \"DisputeID\", 8, 16, 90, 96, 0]\n ],\n \"minzoom\": 4,\n \"layout\": {\n \"line-join\": \"round\"\n },\n \"paint\": {\n \"line-color\": \"#e9ebec\",\n \"line-opacity\": 0.5,\n \"line-width\": {\n \"base\": 1.2,\n \"stops\": [\n [6, 5],\n [8, 7.5],\n [14, 10],\n [17, 10]\n ]\n }\n },\n \"showProperties\": false\n },\n {\n \"id\": \"Boundary line/Disputed admin0/0\",\n \"type\": \"line\",\n \"source\": \"esri\",\n \"source-layer\": \"Boundary line\",\n \"filter\": [\n \"all\",\n [\"==\", \"_symbol\", 6],\n [\"!in\", \"Viz\", 3],\n [\"!in\", \"DisputeID\", 8, 16, 90, 96, 0]\n ],\n \"minzoom\": 4,\n \"layout\": {\n \"line-join\": \"round\",\n \"visibility\": \"none\"\n },\n \"paint\": {\n \"line-width\": {\n \"base\": 1.2,\n \"stops\": [\n [4, 1.2],\n [17, 9]\n ]\n },\n \"line-color\": \"#e9ebec\",\n \"line-opacity\": 0.7,\n \"line-dasharray\": [10, 4]\n },\n \"showProperties\": false\n },\n {\n \"id\": \"Boundary line/Disputed admin0/0 small\",\n \"type\": \"line\",\n \"source\": \"esri\",\n \"source-layer\": \"Boundary line\",\n \"filter\": [\n \"all\",\n [\"==\", \"_symbol\", 6],\n [\"!in\", \"Viz\", 3],\n [\"!in\", \"DisputeID\", 8, 16, 90, 96, 0]\n ],\n \"minzoom\": 1,\n \"maxzoom\": 4,\n \"layout\": {\n \"line-join\": \"round\",\n \"visibility\": \"none\"\n },\n \"paint\": {\n \"line-width\": 0.75,\n \"line-color\": \"#e9ebec\",\n \"line-dasharray\": [4, 3]\n },\n \"showProperties\": false\n },\n {\n \"id\": \"Boundary line/Admin1/1\",\n \"type\": \"line\",\n \"source\": \"esri\",\n \"source-layer\": \"Boundary line\",\n \"filter\": [\"all\", [\"==\", \"_symbol\", 1], [\"!in\", \"Viz\", 3]],\n \"minzoom\": 3,\n \"layout\": {\n \"line-cap\": \"round\",\n \"line-join\": \"round\"\n },\n \"paint\": {\n \"line-color\": \"#e9ebec\",\n \"line-width\": {\n \"base\": 1,\n \"stops\": [\n [3, 0.75],\n [6, 3.5],\n [14, 7],\n [17, 7]\n ]\n }\n },\n \"showProperties\": false\n },\n {\n \"id\": \"Boundary line/Admin0/1\",\n \"type\": \"line\",\n \"source\": \"esri\",\n \"source-layer\": \"Boundary line\",\n \"filter\": [\"all\", [\"==\", \"_symbol\", 0], [\"!in\", \"Viz\", 3]],\n \"minzoom\": 4,\n \"layout\": {\n \"line-cap\": \"round\",\n \"line-join\": \"round\"\n },\n \"paint\": {\n \"line-color\": \"#e9ebec\",\n \"line-width\": {\n \"base\": 1.2,\n \"stops\": [\n [6, 4],\n [8, 6.5],\n [14, 8],\n [17, 8]\n ]\n }\n },\n \"showProperties\": false\n },\n {\n \"id\": \"Boundary line/Admin2/0\",\n \"type\": \"line\",\n \"source\": \"esri\",\n \"source-layer\": \"Boundary line\",\n \"filter\": [\"all\", [\"==\", \"_symbol\", 2], [\"!in\", \"Viz\", 3]],\n \"minzoom\": 6,\n \"layout\": {\n \"visibility\": \"none\",\n \"line-join\": \"round\"\n },\n \"paint\": {\n \"line-color\": \"#e9ebec\",\n \"line-width\": 1.2,\n \"line-dasharray\": [2, 3]\n },\n \"showProperties\": false\n },\n {\n \"id\": \"Boundary line/Admin0/0\",\n \"type\": \"line\",\n \"source\": \"esri\",\n \"source-layer\": \"Boundary line\",\n \"filter\": [\"all\", [\"==\", \"_symbol\", 0], [\"!in\", \"Viz\", 3]],\n \"minzoom\": 4,\n \"layout\": {\n \"line-cap\": \"round\",\n \"line-join\": \"round\",\n \"visibility\": \"none\"\n },\n \"paint\": {\n \"line-color\": \"#e9ebec\",\n \"line-width\": {\n \"base\": 1.2,\n \"stops\": [\n [4, 1.5],\n [14, 2.5],\n [17, 2.5]\n ]\n },\n \"line-dasharray\": [8, 3]\n },\n \"showProperties\": false\n },\n {\n \"id\": \"Boundary line/Admin0/0/Small\",\n \"type\": \"line\",\n \"source\": \"esri\",\n \"source-layer\": \"Boundary line\",\n \"filter\": [\"all\", [\"==\", \"_symbol\", 0], [\"!in\", \"Viz\", 3]],\n \"layout\": {\n \"line-cap\": \"round\",\n \"line-join\": \"round\"\n },\n \"paint\": {\n \"line-color\": \"#e9ebec\"\n },\n \"maxzoom\": 4,\n \"minzoom\": 1,\n \"showProperties\": false\n },\n {\n \"id\": \"Trail or path\",\n \"type\": \"line\",\n \"source\": \"esri\",\n \"source-layer\": \"Trail or path\",\n \"minzoom\": 15,\n \"layout\": {\n \"line-cap\": \"round\",\n \"line-join\": \"round\"\n },\n \"paint\": {\n \"line-width\": 1.6,\n \"line-color\": \"#fd9a94\"\n }\n },\n {\n \"id\": \"Road/Pedestrian\",\n \"type\": \"line\",\n \"source\": \"esri\",\n \"source-layer\": \"Road\",\n \"filter\": [\"all\", [\"==\", \"_symbol\", 9], [\"!in\", \"Viz\", 3]],\n \"minzoom\": 15,\n \"layout\": {\n \"line-cap\": \"round\",\n \"line-join\": \"round\"\n },\n \"paint\": {\n \"line-width\": 1.22,\n \"line-color\": \"#dd7d78\"\n }\n },\n {\n \"id\": \"Railroad\",\n \"type\": \"line\",\n \"source\": \"esri\",\n \"source-layer\": \"Railroad\",\n \"layout\": {\n \"line-join\": \"round\"\n },\n \"paint\": {\n \"line-color\": \"#f3908a\",\n \"line-width\": 1.2\n },\n \"minzoom\": 15\n },\n {\n \"id\": \"Ferry/Rail ferry\",\n \"type\": \"line\",\n \"source\": \"esri\",\n \"source-layer\": \"Ferry\",\n \"filter\": [\"all\", [\"==\", \"_symbol\", 1], [\"!in\", \"Viz\", 3]],\n \"minzoom\": 15,\n \"layout\": {\n \"line-join\": \"round\"\n },\n \"paint\": {\n \"line-color\": \"#393f4e\",\n \"line-width\": 1.2\n }\n },\n {\n \"id\": \"Road/4WD/1\",\n \"type\": \"line\",\n \"source\": \"esri\",\n \"source-layer\": \"Road\",\n \"filter\": [\"all\", [\"==\", \"_symbol\", 10], [\"!in\", \"Viz\", 3]],\n \"minzoom\": 13,\n \"layout\": {\n \"line-join\": \"round\"\n },\n \"paint\": {\n \"line-width\": {\n \"base\": 1.2,\n \"stops\": [\n [14, 2.22],\n [17, 3.32]\n ]\n },\n \"line-dasharray\": [6, 3],\n \"line-color\": \"#a84f4c\"\n }\n },\n {\n \"id\": \"Road/Service/1\",\n \"type\": \"line\",\n \"source\": \"esri\",\n \"source-layer\": \"Road\",\n \"filter\": [\"all\", [\"==\", \"_symbol\", 8], [\"!in\", \"Viz\", 3]],\n \"minzoom\": 14,\n \"layout\": {\n \"line-cap\": \"round\",\n \"line-join\": \"round\"\n },\n \"paint\": {\n \"line-color\": \"#a84f4c\",\n \"line-width\": {\n \"base\": 1.2,\n \"stops\": [\n [14, 2.22],\n [17, 3.32]\n ]\n }\n }\n },\n {\n \"id\": \"Road/Local/1\",\n \"type\": \"line\",\n \"source\": \"esri\",\n \"source-layer\": \"Road\",\n \"filter\": [\"all\", [\"==\", \"_symbol\", 7], [\"!in\", \"Viz\", 3]],\n \"minzoom\": 13,\n \"layout\": {\n \"line-cap\": \"round\",\n \"line-join\": \"round\"\n },\n \"paint\": {\n \"line-color\": \"#a84f4c\",\n \"line-width\": {\n \"base\": 1.4,\n \"stops\": [\n [13, 2.22],\n [14, 3.58],\n [17, 6.64]\n ]\n }\n }\n },\n {\n \"id\": \"Road/Minor, ramp or traffic circle/1\",\n \"type\": \"line\",\n \"source\": \"esri\",\n \"source-layer\": \"Road\",\n \"filter\": [\"all\", [\"==\", \"_symbol\", 6], [\"!in\", \"Viz\", 3]],\n \"minzoom\": 13,\n \"layout\": {\n \"line-cap\": \"round\",\n \"line-join\": \"round\"\n },\n \"paint\": {\n \"line-color\": \"#a84f4c\",\n \"line-width\": {\n \"base\": 1.2,\n \"stops\": [\n [13, 2.22],\n [15, 3.58],\n [17, 5.87]\n ]\n }\n }\n },\n {\n \"id\": \"Road/Minor/1\",\n \"type\": \"line\",\n \"source\": \"esri\",\n \"source-layer\": \"Road\",\n \"filter\": [\"all\", [\"==\", \"_symbol\", 5], [\"!in\", \"Viz\", 3]],\n \"minzoom\": 12,\n \"layout\": {\n \"line-cap\": \"round\",\n \"line-join\": \"round\"\n },\n \"paint\": {\n \"line-color\": \"#a84f4c\",\n \"line-width\": {\n \"base\": 1.2,\n \"stops\": [\n [12, 2.22],\n [14, 3.58],\n [17, 6.64]\n ]\n }\n }\n },\n {\n \"id\": \"Road/Major, ramp or traffic circle/1\",\n \"type\": \"line\",\n \"source\": \"esri\",\n \"source-layer\": \"Road\",\n \"filter\": [\"all\", [\"==\", \"_symbol\", 4], [\"!in\", \"Viz\", 3]],\n \"minzoom\": 10,\n \"layout\": {\n \"line-cap\": \"round\",\n \"line-join\": \"round\"\n },\n \"paint\": {\n \"line-color\": \"#a84f4c\",\n \"line-width\": {\n \"base\": 1.2,\n \"stops\": [\n [13, 2.22],\n [15, 3.58],\n [17, 5.87]\n ]\n }\n }\n },\n {\n \"id\": \"Road/Major/1\",\n \"type\": \"line\",\n \"source\": \"esri\",\n \"source-layer\": \"Road\",\n \"filter\": [\"all\", [\"==\", \"_symbol\", 3], [\"!in\", \"Viz\", 3]],\n \"minzoom\": 10,\n \"layout\": {\n \"line-cap\": \"round\",\n \"line-join\": \"round\"\n },\n \"paint\": {\n \"line-color\": \"#a84f4c\",\n \"line-width\": {\n \"base\": 1.2,\n \"stops\": [\n [10, 2.22],\n [14, 5.61],\n [17, 10.97]\n ]\n }\n }\n },\n {\n \"id\": \"Road/Freeway Motorway, ramp or traffic circle/1\",\n \"type\": \"line\",\n \"source\": \"esri\",\n \"source-layer\": \"Road\",\n \"filter\": [\"all\", [\"==\", \"_symbol\", 2], [\"!in\", \"Viz\", 3]],\n \"minzoom\": 5,\n \"layout\": {\n \"line-cap\": \"round\",\n \"line-join\": \"round\"\n },\n \"paint\": {\n \"line-color\": \"#a84f4c\",\n \"line-width\": {\n \"base\": 1.2,\n \"stops\": [\n [10, 2.22],\n [14, 3.58],\n [17, 6.64]\n ]\n }\n }\n },\n {\n \"id\": \"Road/Freeway Motorway/1\",\n \"type\": \"line\",\n \"source\": \"esri\",\n \"source-layer\": \"Road\",\n \"filter\": [\"all\", [\"==\", \"_symbol\", 0], [\"!in\", \"Viz\", 3]],\n \"minzoom\": 5,\n \"layout\": {\n \"line-join\": \"round\"\n },\n \"paint\": {\n \"line-color\": \"#a84f4c\",\n \"line-width\": {\n \"base\": 1.2,\n \"stops\": [\n [8, 2.68],\n [14, 5.61],\n [17, 10.97]\n ]\n }\n }\n },\n {\n \"id\": \"Road/4WD/0\",\n \"type\": \"line\",\n \"source\": \"esri\",\n \"source-layer\": \"Road\",\n \"filter\": [\"all\", [\"==\", \"_symbol\", 10], [\"!in\", \"Viz\", 3]],\n \"minzoom\": 13,\n \"layout\": {\n \"line-join\": \"round\"\n },\n \"paint\": {\n \"line-width\": {\n \"base\": 1.2,\n \"stops\": [\n [14, 0.77],\n [17, 1.53]\n ]\n },\n \"line-color\": \"#dd7d78\"\n }\n },\n {\n \"id\": \"Road/Service/0\",\n \"type\": \"line\",\n \"source\": \"esri\",\n \"source-layer\": \"Road\",\n \"filter\": [\"all\", [\"==\", \"_symbol\", 8], [\"!in\", \"Viz\", 3]],\n \"minzoom\": 13,\n \"layout\": {\n \"line-cap\": \"round\",\n \"line-join\": \"round\"\n },\n \"paint\": {\n \"line-width\": {\n \"base\": 1.2,\n \"stops\": [\n [14, 0.77],\n [17, 1.79]\n ]\n },\n \"line-color\": \"#dd7d78\"\n }\n },\n {\n \"id\": \"Road/Local/0\",\n \"type\": \"line\",\n \"source\": \"esri\",\n \"source-layer\": \"Road\",\n \"filter\": [\"all\", [\"==\", \"_symbol\", 7], [\"!in\", \"Viz\", 3]],\n \"minzoom\": 13,\n \"layout\": {\n \"line-cap\": \"round\",\n \"line-join\": \"round\"\n },\n \"paint\": {\n \"line-width\": {\n \"base\": 1.2,\n \"stops\": [\n [13, 1.15],\n [14, 2.05],\n [17, 3.58]\n ]\n },\n \"line-color\": \"#dd7d78\"\n }\n },\n {\n \"id\": \"Road/Minor, ramp or traffic circle/0\",\n \"type\": \"line\",\n \"source\": \"esri\",\n \"source-layer\": \"Road\",\n \"filter\": [\"all\", [\"==\", \"_symbol\", 6], [\"!in\", \"Viz\", 3]],\n \"minzoom\": 13,\n \"layout\": {\n \"line-cap\": \"round\",\n \"line-join\": \"round\"\n },\n \"paint\": {\n \"line-width\": {\n \"base\": 1.2,\n \"stops\": [\n [13, 0.77],\n [14, 2.05],\n [17, 3.58]\n ]\n },\n \"line-color\": \"#dd7d78\"\n }\n },\n {\n \"id\": \"Road/Minor/0\",\n \"type\": \"line\",\n \"source\": \"esri\",\n \"source-layer\": \"Road\",\n \"filter\": [\"all\", [\"==\", \"_symbol\", 5], [\"!in\", \"Viz\", 3]],\n \"minzoom\": 12,\n \"layout\": {\n \"line-cap\": \"round\",\n \"line-join\": \"round\"\n },\n \"paint\": {\n \"line-width\": {\n \"base\": 1.2,\n \"stops\": [\n [12, 0.77],\n [14, 2.05],\n [17, 3.58]\n ]\n },\n \"line-color\": \"#dd7d78\"\n }\n },\n {\n \"id\": \"Road/Major, ramp or traffic circle/0\",\n \"type\": \"line\",\n \"source\": \"esri\",\n \"source-layer\": \"Road\",\n \"filter\": [\"all\", [\"==\", \"_symbol\", 4], [\"!in\", \"Viz\", 3]],\n \"minzoom\": 10,\n \"layout\": {\n \"line-cap\": \"round\",\n \"line-join\": \"round\"\n },\n \"paint\": {\n \"line-width\": {\n \"base\": 1.2,\n \"stops\": [\n [13, 0.77],\n [14, 2.05],\n [17, 3.58]\n ]\n },\n \"line-color\": \"#dd7d78\"\n }\n },\n {\n \"id\": \"Road/Major/0\",\n \"type\": \"line\",\n \"source\": \"esri\",\n \"source-layer\": \"Road\",\n \"filter\": [\"all\", [\"==\", \"_symbol\", 3], [\"!in\", \"Viz\", 3]],\n \"minzoom\": 10,\n \"layout\": {\n \"line-cap\": \"round\",\n \"line-join\": \"round\"\n },\n \"paint\": {\n \"line-width\": {\n \"base\": 1.2,\n \"stops\": [\n [10, 0.77],\n [14, 4.08],\n [17, 7.91]\n ]\n },\n \"line-color\": \"#dd7d78\"\n }\n },\n {\n \"id\": \"Road/Freeway Motorway, ramp or traffic circle/0\",\n \"type\": \"line\",\n \"source\": \"esri\",\n \"source-layer\": \"Road\",\n \"filter\": [\"all\", [\"==\", \"_symbol\", 2], [\"!in\", \"Viz\", 3]],\n \"minzoom\": 5,\n \"layout\": {\n \"line-cap\": \"round\",\n \"line-join\": \"round\"\n },\n \"paint\": {\n \"line-color\": \"#dd7d78\",\n \"line-width\": {\n \"base\": 1.2,\n \"stops\": [\n [10, 0.77],\n [14, 2.05],\n [17, 3.58]\n ]\n }\n }\n },\n {\n \"id\": \"Road/Highway/0\",\n \"type\": \"line\",\n \"source\": \"esri\",\n \"source-layer\": \"Road\",\n \"filter\": [\"all\", [\"==\", \"_symbol\", 1], [\"!in\", \"Viz\", 3]],\n \"minzoom\": 7,\n \"layout\": {\n \"line-join\": \"round\"\n },\n \"paint\": {\n \"line-color\": \"#dd7d78\",\n \"line-width\": {\n \"base\": 1.2,\n \"stops\": [\n [8, 0.77],\n [14, 4.08],\n [17, 7.91]\n ]\n }\n }\n },\n {\n \"id\": \"Road/Freeway Motorway/0\",\n \"type\": \"line\",\n \"source\": \"esri\",\n \"source-layer\": \"Road\",\n \"filter\": [\"all\", [\"==\", \"_symbol\", 0], [\"!in\", \"Viz\", 3]],\n \"minzoom\": 5,\n \"layout\": {\n \"line-join\": \"round\"\n },\n \"paint\": {\n \"line-color\": \"#dd7d78\",\n \"line-width\": {\n \"base\": 1.2,\n \"stops\": [\n [8, 0.77],\n [14, 4.08],\n [17, 7.91]\n ]\n }\n }\n },\n {\n \"id\": \"Road tunnel/4WD/1\",\n \"type\": \"line\",\n \"source\": \"esri\",\n \"source-layer\": \"Road tunnel\",\n \"filter\": [\"all\", [\"==\", \"_symbol\", 10], [\"!in\", \"Viz\", 3]],\n \"minzoom\": 13,\n \"layout\": {\n \"line-join\": \"round\"\n },\n \"paint\": {\n \"line-width\": {\n \"base\": 1.2,\n \"stops\": [\n [14, 2.9],\n [17, 4.33]\n ]\n },\n \"line-dasharray\": [6, 3],\n \"line-opacity\": 0.5,\n \"line-color\": \"#a84f4c\"\n }\n },\n {\n \"id\": \"Road tunnel/Service/1\",\n \"type\": \"line\",\n \"source\": \"esri\",\n \"source-layer\": \"Road tunnel\",\n \"filter\": [\"all\", [\"==\", \"_symbol\", 8], [\"!in\", \"Viz\", 3]],\n \"minzoom\": 13,\n \"layout\": {\n \"line-cap\": \"round\",\n \"line-join\": \"round\"\n },\n \"paint\": {\n \"line-color\": \"#a84f4c\",\n \"line-opacity\": 0.5,\n \"line-width\": {\n \"base\": 1.2,\n \"stops\": [\n [14, 2.9],\n [17, 4.33]\n ]\n }\n }\n },\n {\n \"id\": \"Road tunnel/Local/1\",\n \"type\": \"line\",\n \"source\": \"esri\",\n \"source-layer\": \"Road tunnel\",\n \"filter\": [\"all\", [\"==\", \"_symbol\", 7], [\"!in\", \"Viz\", 3]],\n \"minzoom\": 13,\n \"layout\": {\n \"line-cap\": \"round\",\n \"line-join\": \"round\"\n },\n \"paint\": {\n \"line-color\": \"#a84f4c\",\n \"line-opacity\": 0.5,\n \"line-width\": {\n \"base\": 1.4,\n \"stops\": [\n [13, 2.9],\n [14, 4.67],\n [17, 8.67]\n ]\n }\n }\n },\n {\n \"id\": \"Road tunnel/Minor, ramp or traffic circle/1\",\n \"type\": \"line\",\n \"source\": \"esri\",\n \"source-layer\": \"Road tunnel\",\n \"filter\": [\"all\", [\"==\", \"_symbol\", 6], [\"!in\", \"Viz\", 3]],\n \"minzoom\": 12,\n \"layout\": {\n \"line-cap\": \"round\",\n \"line-join\": \"round\"\n },\n \"paint\": {\n \"line-color\": \"#a84f4c\",\n \"line-opacity\": 0.5,\n \"line-width\": {\n \"base\": 1.2,\n \"stops\": [\n [13, 2.9],\n [15, 4.67],\n [17, 7.67]\n ]\n }\n }\n },\n {\n \"id\": \"Road tunnel/Minor/1\",\n \"type\": \"line\",\n \"source\": \"esri\",\n \"source-layer\": \"Road tunnel\",\n \"filter\": [\"all\", [\"==\", \"_symbol\", 5], [\"!in\", \"Viz\", 3]],\n \"minzoom\": 12,\n \"layout\": {\n \"line-cap\": \"round\",\n \"line-join\": \"round\"\n },\n \"paint\": {\n \"line-color\": \"#a84f4c\",\n \"line-opacity\": 0.5,\n \"line-width\": {\n \"base\": 1.2,\n \"stops\": [\n [12, 2.9],\n [14, 4.67],\n [17, 8.67]\n ]\n }\n }\n },\n {\n \"id\": \"Road tunnel/Major, ramp or traffic circle/1\",\n \"type\": \"line\",\n \"source\": \"esri\",\n \"source-layer\": \"Road tunnel\",\n \"filter\": [\"all\", [\"==\", \"_symbol\", 4], [\"!in\", \"Viz\", 3]],\n \"minzoom\": 13,\n \"layout\": {\n \"line-cap\": \"round\",\n \"line-join\": \"round\"\n },\n \"paint\": {\n \"line-color\": \"#a84f4c\",\n \"line-opacity\": 0.5,\n \"line-width\": {\n \"base\": 1.2,\n \"stops\": [\n [13, 2.9],\n [15, 4.67],\n [17, 7.67]\n ]\n }\n }\n },\n {\n \"id\": \"Road tunnel/Major/1\",\n \"type\": \"line\",\n \"source\": \"esri\",\n \"source-layer\": \"Road tunnel\",\n \"filter\": [\"all\", [\"==\", \"_symbol\", 3], [\"!in\", \"Viz\", 3]],\n \"minzoom\": 10,\n \"layout\": {\n \"line-cap\": \"round\",\n \"line-join\": \"round\"\n },\n \"paint\": {\n \"line-color\": \"#a84f4c\",\n \"line-opacity\": 0.5,\n \"line-width\": {\n \"base\": 1.2,\n \"stops\": [\n [10, 2.9],\n [14, 7.33],\n [17, 14.33]\n ]\n }\n }\n },\n {\n \"id\": \"Road tunnel/Freeway Motorway, ramp or traffic circle/1\",\n \"type\": \"line\",\n \"source\": \"esri\",\n \"source-layer\": \"Road tunnel\",\n \"filter\": [\"all\", [\"==\", \"_symbol\", 2], [\"!in\", \"Viz\", 3]],\n \"minzoom\": 5,\n \"layout\": {\n \"line-cap\": \"round\",\n \"line-join\": \"round\"\n },\n \"paint\": {\n \"line-opacity\": 0.5,\n \"line-color\": \"#a84f4c\",\n \"line-width\": {\n \"base\": 1.2,\n \"stops\": [\n [10, 2.9],\n [14, 4.67],\n [17, 8.67]\n ]\n }\n }\n },\n {\n \"id\": \"Road tunnel/Freeway Motorway/1\",\n \"type\": \"line\",\n \"source\": \"esri\",\n \"source-layer\": \"Road tunnel\",\n \"filter\": [\"all\", [\"==\", \"_symbol\", 0], [\"!in\", \"Viz\", 3]],\n \"minzoom\": 5,\n \"layout\": {\n \"line-join\": \"round\"\n },\n \"paint\": {\n \"line-opacity\": 0.5,\n \"line-color\": \"#a84f4c\",\n \"line-width\": {\n \"base\": 1.2,\n \"stops\": [\n [8, 3.5],\n [14, 7.33],\n [17, 14.33]\n ]\n }\n }\n },\n {\n \"id\": \"Road tunnel/4WD/0\",\n \"type\": \"line\",\n \"source\": \"esri\",\n \"source-layer\": \"Road tunnel\",\n \"filter\": [\"all\", [\"==\", \"_symbol\", 10], [\"!in\", \"Viz\", 3]],\n \"minzoom\": 13,\n \"layout\": {\n \"line-join\": \"round\"\n },\n \"paint\": {\n \"line-opacity\": 0.7,\n \"line-width\": {\n \"base\": 1.2,\n \"stops\": [\n [14, 1],\n [17, 2]\n ]\n },\n \"line-color\": \"#dd7d78\"\n }\n },\n {\n \"id\": \"Road tunnel/Service/0\",\n \"type\": \"line\",\n \"source\": \"esri\",\n \"source-layer\": \"Road tunnel\",\n \"filter\": [\"all\", [\"==\", \"_symbol\", 8], [\"!in\", \"Viz\", 3]],\n \"minzoom\": 13,\n \"layout\": {\n \"line-cap\": \"round\",\n \"line-join\": \"round\"\n },\n \"paint\": {\n \"line-opacity\": 0.7,\n \"line-width\": {\n \"base\": 1.2,\n \"stops\": [\n [14, 1],\n [17, 2.33]\n ]\n },\n \"line-color\": \"#dd7d78\"\n }\n },\n {\n \"id\": \"Road tunnel/Local/0\",\n \"type\": \"line\",\n \"source\": \"esri\",\n \"source-layer\": \"Road tunnel\",\n \"filter\": [\"all\", [\"==\", \"_symbol\", 7], [\"!in\", \"Viz\", 3]],\n \"minzoom\": 13,\n \"layout\": {\n \"line-cap\": \"round\",\n \"line-join\": \"round\"\n },\n \"paint\": {\n \"line-opacity\": 0.7,\n \"line-width\": {\n \"base\": 1.2,\n \"stops\": [\n [13, 1.5],\n [14, 2.67],\n [17, 4.67]\n ]\n },\n \"line-color\": \"#dd7d78\"\n }\n },\n {\n \"id\": \"Road tunnel/Minor, ramp or traffic circle/0\",\n \"type\": \"line\",\n \"source\": \"esri\",\n \"source-layer\": \"Road tunnel\",\n \"filter\": [\"all\", [\"==\", \"_symbol\", 6], [\"!in\", \"Viz\", 3]],\n \"minzoom\": 12,\n \"layout\": {\n \"line-cap\": \"round\",\n \"line-join\": \"round\"\n },\n \"paint\": {\n \"line-opacity\": 0.7,\n \"line-width\": {\n \"base\": 1.2,\n \"stops\": [\n [13, 1],\n [14, 2.67],\n [17, 4.67]\n ]\n },\n \"line-color\": \"#dd7d78\"\n }\n },\n {\n \"id\": \"Road tunnel/Minor/0\",\n \"type\": \"line\",\n \"source\": \"esri\",\n \"source-layer\": \"Road tunnel\",\n \"filter\": [\"all\", [\"==\", \"_symbol\", 5], [\"!in\", \"Viz\", 3]],\n \"minzoom\": 12,\n \"layout\": {\n \"line-cap\": \"round\",\n \"line-join\": \"round\"\n },\n \"paint\": {\n \"line-opacity\": 0.7,\n \"line-width\": {\n \"base\": 1.2,\n \"stops\": [\n [12, 1],\n [14, 2.67],\n [17, 4.67]\n ]\n },\n \"line-color\": \"#dd7d78\"\n }\n },\n {\n \"id\": \"Road tunnel/Major, ramp or traffic circle/0\",\n \"type\": \"line\",\n \"source\": \"esri\",\n \"source-layer\": \"Road tunnel\",\n \"filter\": [\"all\", [\"==\", \"_symbol\", 4], [\"!in\", \"Viz\", 3]],\n \"minzoom\": 13,\n \"layout\": {\n \"line-cap\": \"round\",\n \"line-join\": \"round\"\n },\n \"paint\": {\n \"line-opacity\": 0.7,\n \"line-width\": {\n \"base\": 1.2,\n \"stops\": [\n [13, 1],\n [14, 2.67],\n [17, 4.67]\n ]\n },\n \"line-color\": \"#dd7d78\"\n }\n },\n {\n \"id\": \"Road tunnel/Major/0\",\n \"type\": \"line\",\n \"source\": \"esri\",\n \"source-layer\": \"Road tunnel\",\n \"filter\": [\"all\", [\"==\", \"_symbol\", 3], [\"!in\", \"Viz\", 3]],\n \"minzoom\": 10,\n \"layout\": {\n \"line-cap\": \"round\",\n \"line-join\": \"round\"\n },\n \"paint\": {\n \"line-opacity\": 0.7,\n \"line-width\": {\n \"base\": 1.2,\n \"stops\": [\n [10, 1],\n [14, 5.33],\n [17, 10.33]\n ]\n },\n \"line-color\": \"#dd7d78\"\n }\n },\n {\n \"id\": \"Road tunnel/Freeway Motorway, ramp or traffic circle/0\",\n \"type\": \"line\",\n \"source\": \"esri\",\n \"source-layer\": \"Road tunnel\",\n \"filter\": [\"all\", [\"==\", \"_symbol\", 2], [\"!in\", \"Viz\", 3]],\n \"minzoom\": 13,\n \"layout\": {\n \"line-join\": \"round\",\n \"line-cap\": \"round\"\n },\n \"paint\": {\n \"line-opacity\": 0.7,\n \"line-width\": {\n \"base\": 1.2,\n \"stops\": [\n [10, 1],\n [14, 2.67],\n [17, 4.67]\n ]\n },\n \"line-color\": \"#dd7d78\"\n }\n },\n {\n \"id\": \"Road tunnel/Highway/0\",\n \"type\": \"line\",\n \"source\": \"esri\",\n \"source-layer\": \"Road tunnel\",\n \"filter\": [\"all\", [\"==\", \"_symbol\", 1], [\"!in\", \"Viz\", 3]],\n \"minzoom\": 7,\n \"layout\": {\n \"line-join\": \"round\"\n },\n \"paint\": {\n \"line-opacity\": 0.7,\n \"line-color\": \"#dd7d78\",\n \"line-width\": {\n \"base\": 1.2,\n \"stops\": [\n [8, 1],\n [14, 5.33],\n [17, 10.33]\n ]\n }\n }\n },\n {\n \"id\": \"Road tunnel/Freeway Motorway/0\",\n \"type\": \"line\",\n \"source\": \"esri\",\n \"source-layer\": \"Road tunnel\",\n \"filter\": [\"all\", [\"==\", \"_symbol\", 0], [\"!in\", \"Viz\", 3]],\n \"minzoom\": 8,\n \"layout\": {\n \"line-join\": \"round\"\n },\n \"paint\": {\n \"line-opacity\": 0.7,\n \"line-width\": {\n \"base\": 1.2,\n \"stops\": [\n [8, 1],\n [14, 5.33],\n [17, 10.33]\n ]\n },\n \"line-color\": \"#dd7d78\"\n }\n },\n {\n \"id\": \"Road/label/Rectangle white black (Alt)\",\n \"type\": \"symbol\",\n \"source\": \"esri\",\n \"source-layer\": \"Road/label\",\n \"filter\": [\n \"all\",\n [\n \"in\",\n \"_label_class\",\n 8,\n 10,\n 12,\n 14,\n 16,\n 20,\n 22,\n 24,\n 26,\n 28,\n 30,\n 32,\n 34,\n 36,\n 38,\n 40,\n 42,\n 44,\n 46,\n 48,\n 50,\n 52,\n 54,\n 56,\n 58,\n 60,\n 62,\n 64,\n 66,\n 68,\n 70,\n 72,\n 74\n ],\n [\"!in\", \"Viz\", 3]\n ],\n \"minzoom\": 14,\n \"layout\": {\n \"symbol-placement\": \"line\",\n \"symbol-spacing\": 800,\n \"text-max-angle\": 25,\n \"symbol-avoid-edges\": true,\n \"text-font\": [\"Arial Regular\"],\n \"text-size\": 8.5,\n \"text-max-width\": 8,\n \"text-field\": \"{_name}\",\n \"icon-image\": \"Road/Rectangle white black (Alt)/{_len}\",\n \"icon-rotation-alignment\": \"viewport\",\n \"text-rotation-alignment\": \"viewport\",\n \"text-offset\": [0, 0.2],\n \"text-padding\": 20\n },\n \"paint\": {\n \"text-color\": \"#fedad4\",\n \"text-halo-color\": \"#8d4543\"\n }\n },\n {\n \"id\": \"Road/label/Rectangle white black\",\n \"type\": \"symbol\",\n \"source\": \"esri\",\n \"source-layer\": \"Road/label\",\n \"filter\": [\n \"all\",\n [\n \"in\",\n \"_label_class\",\n 7,\n 9,\n 11,\n 13,\n 15,\n 17,\n 19,\n 21,\n 23,\n 25,\n 27,\n 29,\n 31,\n 33,\n 35,\n 37,\n 39,\n 41,\n 43,\n 45,\n 47,\n 49,\n 51,\n 53,\n 55,\n 57,\n 59,\n 61,\n 63,\n 65,\n 67,\n 69,\n 71,\n 73\n ],\n [\"!in\", \"Viz\", 3]\n ],\n \"minzoom\": 14,\n \"layout\": {\n \"symbol-placement\": \"line\",\n \"symbol-spacing\": 800,\n \"text-max-angle\": 25,\n \"symbol-avoid-edges\": true,\n \"text-font\": [\"Arial Regular\"],\n \"text-size\": 8.5,\n \"text-max-width\": 8,\n \"text-field\": \"{_name}\",\n \"icon-image\": \"Road/Rectangle white black/{_len}\",\n \"icon-rotation-alignment\": \"viewport\",\n \"text-rotation-alignment\": \"viewport\",\n \"text-offset\": [0, 0.2],\n \"text-padding\": 20\n },\n \"paint\": {\n \"text-color\": \"#fedad4\",\n \"text-halo-color\": \"#8d4543\"\n }\n }\n ],\n \"metadata\": {\n \"arcgisStyleUrl\": \"https://www.arcgis.com/sharing/rest/content/items/b8ef81cfe2094e83b5da44957b315a48/resources/styles/root.json\",\n \"arcgisOriginalItemTitle\": \"GG 2nd Attempt\",\n \"arcgisSpriteData\": {\n \"spriteImage\": {\n \"__zone_symbol__loadfalse\": [\n {\n \"type\": \"eventTask\",\n \"state\": \"scheduled\",\n \"source\": \"HTMLImageElement.addEventListener:load\",\n \"zone\": \"angular\",\n \"runCount\": 2\n }\n ]\n },\n \"spriteJson\": {\n \"Water area/Inundated area\": {\n \"x\": 0,\n \"y\": 0,\n \"width\": 64,\n \"height\": 64,\n \"pixelRatio\": 1,\n \"sdf\": false\n },\n \"Water area/Lake or river intermittent\": {\n \"x\": 64,\n \"y\": 0,\n \"width\": 64,\n \"height\": 64,\n \"pixelRatio\": 1,\n \"sdf\": false\n },\n \"Water area/Swamp or marsh\": {\n \"x\": 128,\n \"y\": 0,\n \"width\": 64,\n \"height\": 64,\n \"pixelRatio\": 1,\n \"sdf\": false\n },\n \"Special area of interest/Sand\": {\n \"x\": 0,\n \"y\": 64,\n \"width\": 32,\n \"height\": 32,\n \"pixelRatio\": 1,\n \"sdf\": false\n },\n \"Special area of interest/Groundcover\": {\n \"x\": 32,\n \"y\": 64,\n \"width\": 32,\n \"height\": 32,\n \"pixelRatio\": 1,\n \"sdf\": false\n },\n \"Special area of interest/Rock or gravel\": {\n \"x\": 32,\n \"y\": 64,\n \"width\": 32,\n \"height\": 32,\n \"pixelRatio\": 1,\n \"sdf\": false\n },\n \"Water area/Playa\": {\n \"x\": 32,\n \"y\": 64,\n \"width\": 32,\n \"height\": 32,\n \"pixelRatio\": 1,\n \"sdf\": false\n },\n \"Road/Rectangle white black (Alt)/1\": {\n \"x\": 64,\n \"y\": 64,\n \"width\": 16,\n \"height\": 16,\n \"pixelRatio\": 1,\n \"sdf\": false\n },\n \"Road/Rectangle white black/1\": {\n \"x\": 80,\n \"y\": 64,\n \"width\": 16,\n \"height\": 16,\n \"pixelRatio\": 1,\n \"sdf\": false\n },\n \"Road/Rectangle white black (Alt)/7\": {\n \"x\": 96,\n \"y\": 64,\n \"width\": 38,\n \"height\": 16,\n \"pixelRatio\": 1,\n \"sdf\": false\n },\n \"Road/Rectangle white black/7\": {\n \"x\": 134,\n \"y\": 64,\n \"width\": 38,\n \"height\": 16,\n \"pixelRatio\": 1,\n \"sdf\": false\n },\n \"Road/Rectangle white black (Alt)/6\": {\n \"x\": 0,\n \"y\": 96,\n \"width\": 34,\n \"height\": 16,\n \"pixelRatio\": 1,\n \"sdf\": false\n },\n \"Road/Rectangle white black/6\": {\n \"x\": 34,\n \"y\": 96,\n \"width\": 34,\n \"height\": 16,\n \"pixelRatio\": 1,\n \"sdf\": false\n },\n \"Road/Rectangle white black (Alt)/5\": {\n \"x\": 68,\n \"y\": 96,\n \"width\": 30,\n \"height\": 16,\n \"pixelRatio\": 1,\n \"sdf\": false\n },\n \"Road/Rectangle white black/5\": {\n \"x\": 98,\n \"y\": 96,\n \"width\": 30,\n \"height\": 16,\n \"pixelRatio\": 1,\n \"sdf\": false\n },\n \"Road/Rectangle white black (Alt)/4\": {\n \"x\": 128,\n \"y\": 96,\n \"width\": 26,\n \"height\": 16,\n \"pixelRatio\": 1,\n \"sdf\": false\n },\n \"Road/Rectangle white black/4\": {\n \"x\": 154,\n \"y\": 96,\n \"width\": 26,\n \"height\": 16,\n \"pixelRatio\": 1,\n \"sdf\": false\n },\n \"Road/Rectangle white black (Alt)/3\": {\n \"x\": 0,\n \"y\": 112,\n \"width\": 24,\n \"height\": 16,\n \"pixelRatio\": 1,\n \"sdf\": false\n },\n \"Road/Rectangle white black/3\": {\n \"x\": 24,\n \"y\": 112,\n \"width\": 24,\n \"height\": 16,\n \"pixelRatio\": 1,\n \"sdf\": false\n },\n \"Road/Rectangle white black (Alt)/2\": {\n \"x\": 48,\n \"y\": 112,\n \"width\": 20,\n \"height\": 16,\n \"pixelRatio\": 1,\n \"sdf\": false\n },\n \"Road/Rectangle white black/2\": {\n \"x\": 68,\n \"y\": 112,\n \"width\": 20,\n \"height\": 16,\n \"pixelRatio\": 1,\n \"sdf\": false\n },\n \"Water line/Levee/0\": {\n \"x\": 88,\n \"y\": 112,\n \"width\": 10,\n \"height\": 12,\n \"pixelRatio\": 1,\n \"sdf\": false\n }\n },\n \"spriteImage2x\": {\n \"__zone_symbol__loadfalse\": [\n {\n \"type\": \"eventTask\",\n \"state\": \"scheduled\",\n \"source\": \"HTMLImageElement.addEventListener:load\",\n \"zone\": \"angular\",\n \"runCount\": 2\n }\n ]\n },\n \"spriteJson2x\": {\n \"Water area/Inundated area\": {\n \"x\": 0,\n \"y\": 0,\n \"width\": 128,\n \"height\": 128,\n \"pixelRatio\": 2,\n \"sdf\": false\n },\n \"Water area/Lake or river intermittent\": {\n \"x\": 128,\n \"y\": 0,\n \"width\": 128,\n \"height\": 128,\n \"pixelRatio\": 2,\n \"sdf\": false\n },\n \"Water area/Swamp or marsh\": {\n \"x\": 256,\n \"y\": 0,\n \"width\": 128,\n \"height\": 128,\n \"pixelRatio\": 2,\n \"sdf\": false\n },\n \"Special area of interest/Sand\": {\n \"x\": 0,\n \"y\": 128,\n \"width\": 64,\n \"height\": 64,\n \"pixelRatio\": 2,\n \"sdf\": false\n },\n \"Special area of interest/Groundcover\": {\n \"x\": 64,\n \"y\": 128,\n \"width\": 64,\n \"height\": 64,\n \"pixelRatio\": 2,\n \"sdf\": false\n },\n \"Special area of interest/Rock or gravel\": {\n \"x\": 64,\n \"y\": 128,\n \"width\": 64,\n \"height\": 64,\n \"pixelRatio\": 2,\n \"sdf\": false\n },\n \"Water area/Playa\": {\n \"x\": 64,\n \"y\": 128,\n \"width\": 64,\n \"height\": 64,\n \"pixelRatio\": 2,\n \"sdf\": false\n },\n \"Road/Rectangle white black (Alt)/1\": {\n \"x\": 128,\n \"y\": 128,\n \"width\": 28,\n \"height\": 30,\n \"pixelRatio\": 2,\n \"sdf\": false\n },\n \"Road/Rectangle white black/1\": {\n \"x\": 156,\n \"y\": 128,\n \"width\": 28,\n \"height\": 30,\n \"pixelRatio\": 2,\n \"sdf\": false\n },\n \"Road/Rectangle white black (Alt)/7\": {\n \"x\": 184,\n \"y\": 128,\n \"width\": 74,\n \"height\": 30,\n \"pixelRatio\": 2,\n \"sdf\": false\n },\n \"Road/Rectangle white black/7\": {\n \"x\": 258,\n \"y\": 128,\n \"width\": 74,\n \"height\": 30,\n \"pixelRatio\": 2,\n \"sdf\": false\n },\n \"Road/Rectangle white black (Alt)/6\": {\n \"x\": 0,\n \"y\": 192,\n \"width\": 66,\n \"height\": 30,\n \"pixelRatio\": 2,\n \"sdf\": false\n },\n \"Road/Rectangle white black/6\": {\n \"x\": 66,\n \"y\": 192,\n \"width\": 66,\n \"height\": 30,\n \"pixelRatio\": 2,\n \"sdf\": false\n },\n \"Road/Rectangle white black (Alt)/5\": {\n \"x\": 132,\n \"y\": 192,\n \"width\": 58,\n \"height\": 30,\n \"pixelRatio\": 2,\n \"sdf\": false\n },\n \"Road/Rectangle white black/5\": {\n \"x\": 190,\n \"y\": 192,\n \"width\": 58,\n \"height\": 30,\n \"pixelRatio\": 2,\n \"sdf\": false\n },\n \"Road/Rectangle white black (Alt)/4\": {\n \"x\": 248,\n \"y\": 192,\n \"width\": 50,\n \"height\": 30,\n \"pixelRatio\": 2,\n \"sdf\": false\n },\n \"Road/Rectangle white black/4\": {\n \"x\": 298,\n \"y\": 192,\n \"width\": 50,\n \"height\": 30,\n \"pixelRatio\": 2,\n \"sdf\": false\n },\n \"Road/Rectangle white black (Alt)/3\": {\n \"x\": 0,\n \"y\": 222,\n \"width\": 44,\n \"height\": 30,\n \"pixelRatio\": 2,\n \"sdf\": false\n },\n \"Road/Rectangle white black/3\": {\n \"x\": 44,\n \"y\": 222,\n \"width\": 44,\n \"height\": 30,\n \"pixelRatio\": 2,\n \"sdf\": false\n },\n \"Road/Rectangle white black (Alt)/2\": {\n \"x\": 88,\n \"y\": 222,\n \"width\": 36,\n \"height\": 30,\n \"pixelRatio\": 2,\n \"sdf\": false\n },\n \"Road/Rectangle white black/2\": {\n \"x\": 124,\n \"y\": 222,\n \"width\": 36,\n \"height\": 30,\n \"pixelRatio\": 2,\n \"sdf\": false\n },\n \"Water line/Levee/0\": {\n \"x\": 160,\n \"y\": 222,\n \"width\": 16,\n \"height\": 22,\n \"pixelRatio\": 2,\n \"sdf\": false\n }\n },\n \"spriteList\": [\n {\n \"x\": 128,\n \"y\": 128,\n \"width\": 28,\n \"height\": 30,\n \"pixelRatio\": 2,\n \"sdf\": false,\n \"id\": \"Road/Rectangle white black (Alt)/1\",\n \"centerColor\": {\n \"0\": 140,\n \"1\": 70,\n \"2\": 68,\n \"3\": 255\n },\n \"imageData\": \"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABwAAAAeCAYAAAA/xX6fAAAAAXNSR0IArs4c6QAAAIJJREFUSEtjZKAzYATZ1+PmaMzAwHyGlnb//c8oXb579zOwhX1ubr7/GP5toqWFTAxMfkW7dm0etZBqoTwapFQLSphBo0E6GqQkh8BooiE5yAhpGA1SQiFEsvxokJIcZIQ0jAYpoRAiWX6EBWmnq6sUM+P/pySHEwkaUJr6JOijWCkAOS3FHy7KEKAAAAAASUVORK5CYII=\",\n \"style\": {\n \"background-image\": \"url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABwAAAAeCAYAAAA/xX6fAAAAAXNSR0IArs4c6QAAAIJJREFUSEtjZKAzYATZ1+PmaMzAwHyGlnb//c8oXb579zOwhX1ubr7/GP5toqWFTAxMfkW7dm0etZBqoTwapFQLSphBo0E6GqQkh8BooiE5yAhpGA1SQiFEsvxokJIcZIQ0jAYpoRAiWX6EBWmnq6sUM+P/pySHEwkaUJr6JOijWCkAOS3FHy7KEKAAAAAASUVORK5CYII=)\",\n \"background-size\": \"14px 15px\"\n }\n },\n {\n \"x\": 88,\n \"y\": 222,\n \"width\": 36,\n \"height\": 30,\n \"pixelRatio\": 2,\n \"sdf\": false,\n \"id\": \"Road/Rectangle white black (Alt)/2\",\n \"centerColor\": {\n \"0\": 140,\n \"1\": 70,\n \"2\": 68,\n \"3\": 255\n },\n \"imageData\": \"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACQAAAAeCAYAAABE4bxTAAAAAXNSR0IArs4c6QAAAIVJREFUWEdjZBhkgBHknk5XVylmxv9PB9JtJbv2gN0CJnrcHI0ZGJjPDKSDGBj+mpTs2n921EG4Y2E0hAil0NEQGg0hQiFASH40DY2GEKEQICQ/moZGQ4hQCBCSH01DoyFEKAQIyY+modEQIhQChOQHcxoaDF3pv/8Zpct3734G7rkOJgAAF2OpH67+++AAAAAASUVORK5CYII=\",\n \"style\": {\n \"background-image\": \"url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACQAAAAeCAYAAABE4bxTAAAAAXNSR0IArs4c6QAAAIVJREFUWEdjZBhkgBHknk5XVylmxv9PB9JtJbv2gN0CJnrcHI0ZGJjPDKSDGBj+mpTs2n921EG4Y2E0hAil0NEQGg0hQiFASH40DY2GEKEQICQ/moZGQ4hQCBCSH01DoyFEKAQIyY+modEQIhQChOQHcxoaDF3pv/8Zpct3734G7rkOJgAAF2OpH67+++AAAAAASUVORK5CYII=)\",\n \"background-size\": \"18px 15px\"\n }\n },\n {\n \"x\": 0,\n \"y\": 222,\n \"width\": 44,\n \"height\": 30,\n \"pixelRatio\": 2,\n \"sdf\": false,\n \"id\": \"Road/Rectangle white black (Alt)/3\",\n \"centerColor\": {\n \"0\": 140,\n \"1\": 70,\n \"2\": 68,\n \"3\": 255\n },\n \"imageData\": \"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACwAAAAeCAYAAABXNvynAAAAAXNSR0IArs4c6QAAAH5JREFUWEdjZBhigBHk3k5XVylmxv9PB7PbS3btAbt1yDj4739G6fLdu5+NOphWyWo0hGkVsjBzR0N4NITRQmA0SYwmidEkQes0MBrCoyGMPwRGy2Fap5DREB4N4dFymNZpYDSER0OYhJoOpLTHzeU/nQONJOtQhqpI0jnAigHcf9kfB5MDLQAAAABJRU5ErkJggg==\",\n \"style\": {\n \"background-image\": \"url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACwAAAAeCAYAAABXNvynAAAAAXNSR0IArs4c6QAAAH5JREFUWEdjZBhigBHk3k5XVylmxv9PB7PbS3btAbt1yDj4739G6fLdu5+NOphWyWo0hGkVsjBzR0N4NITRQmA0SYwmidEkQes0MBrCoyGMPwRGy2Fap5DREB4N4dFymNZpYDSER0OYhJoOpLTHzeU/nQONJOtQhqpI0jnAigHcf9kfB5MDLQAAAABJRU5ErkJggg==)\",\n \"background-size\": \"22px 15px\"\n }\n },\n {\n \"x\": 248,\n \"y\": 192,\n \"width\": 50,\n \"height\": 30,\n \"pixelRatio\": 2,\n \"sdf\": false,\n \"id\": \"Road/Rectangle white black (Alt)/4\",\n \"centerColor\": {\n \"0\": 140,\n \"1\": 70,\n \"2\": 68,\n \"3\": 255\n },\n \"imageData\": \"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAeCAYAAABuUU38AAAAAXNSR0IArs4c6QAAAHdJREFUWEftktEJgDAQxbzdxIk6hhNJd7P0xwEeRKrE/xe8pLX95Kt5x3ns95fvaVcvD1mpoEVWqjH/xSIWgQz4tCCxMdYisTpoaBFIbIy1SKwOGloEEhtjLRKrg4YWgcTGWIvE6qChRSCxMdYisTpo+BSB+K9iB7sOcB+Yn4bIAAAAAElFTkSuQmCC\",\n \"style\": {\n \"background-image\": \"url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAeCAYAAABuUU38AAAAAXNSR0IArs4c6QAAAHdJREFUWEftktEJgDAQxbzdxIk6hhNJd7P0xwEeRKrE/xe8pLX95Kt5x3ns95fvaVcvD1mpoEVWqjH/xSIWgQz4tCCxMdYisTpoaBFIbIy1SKwOGloEEhtjLRKrg4YWgcTGWIvE6qChRSCxMdYisTpo+BSB+K9iB7sOcB+Yn4bIAAAAAElFTkSuQmCC)\",\n \"background-size\": \"25px 15px\"\n }\n },\n {\n \"x\": 132,\n \"y\": 192,\n \"width\": 58,\n \"height\": 30,\n \"pixelRatio\": 2,\n \"sdf\": false,\n \"id\": \"Road/Rectangle white black (Alt)/5\",\n \"centerColor\": {\n \"0\": 140,\n \"1\": 70,\n \"2\": 68,\n \"3\": 255\n },\n \"imageData\": \"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADoAAAAeCAYAAAB9hg0IAAAAAXNSR0IArs4c6QAAAGpJREFUWEft1MENgEAMA0HSG6IiyqAidL2B7sMLCnCYVBB7V67lJ1cz57GtV+e8+zlK0E6EEe1Ec2ZBFNHQBqgbCu7zbUQRDW2AuqHgjBF1qRvaAHVDwVld6lI3tAHqhoKzuo+63Qi+5bkBTstwHzqs1nYAAAAASUVORK5CYII=\",\n \"style\": {\n \"background-image\": \"url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADoAAAAeCAYAAAB9hg0IAAAAAXNSR0IArs4c6QAAAGpJREFUWEft1MENgEAMA0HSG6IiyqAidL2B7sMLCnCYVBB7V67lJ1cz57GtV+e8+zlK0E6EEe1Ec2ZBFNHQBqgbCu7zbUQRDW2AuqHgjBF1qRvaAHVDwVld6lI3tAHqhoKzuo+63Qi+5bkBTstwHzqs1nYAAAAASUVORK5CYII=)\",\n \"background-size\": \"29px 15px\"\n }\n },\n {\n \"x\": 0,\n \"y\": 192,\n \"width\": 66,\n \"height\": 30,\n \"pixelRatio\": 2,\n \"sdf\": false,\n \"id\": \"Road/Rectangle white black (Alt)/6\",\n \"centerColor\": {\n \"0\": 140,\n \"1\": 70,\n \"2\": 68,\n \"3\": 255\n },\n \"imageData\": \"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEIAAAAeCAYAAACYGMhkAAAAAXNSR0IArs4c6QAAAHZJREFUaEPt2LEJgDAQBdC73cSJHMOJJLsZIjaKyNX6UqRK9bn/SJJhHQnk2NZ52v+cx7K1FERECOKsgSAEcRXRRJgIE/F4S1AN1VAN1Xh7QjCCEYxgBCMKHy2whCUsYQlLWBYSgCUsYQnLAhVulncsC6F9/kgH4nlwHzTeD0oAAAAASUVORK5CYII=\",\n \"style\": {\n \"background-image\": \"url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEIAAAAeCAYAAACYGMhkAAAAAXNSR0IArs4c6QAAAHZJREFUaEPt2LEJgDAQBdC73cSJHMOJJLsZIjaKyNX6UqRK9bn/SJJhHQnk2NZ52v+cx7K1FERECOKsgSAEcRXRRJgIE/F4S1AN1VAN1Xh7QjCCEYxgBCMKHy2whCUsYQlLWBYSgCUsYQnLAhVulncsC6F9/kgH4nlwHzTeD0oAAAAASUVORK5CYII=)\",\n \"background-size\": \"33px 15px\"\n }\n },\n {\n \"x\": 184,\n \"y\": 128,\n \"width\": 74,\n \"height\": 30,\n \"pixelRatio\": 2,\n \"sdf\": false,\n \"id\": \"Road/Rectangle white black (Alt)/7\",\n \"centerColor\": {\n \"0\": 140,\n \"1\": 70,\n \"2\": 68,\n \"3\": 255\n },\n \"imageData\": \"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEoAAAAeCAYAAACLz4iQAAAAAXNSR0IArs4c6QAAAIJJREFUaEPt0rENgDAQBEHcG6IiyqAiRG8gdzDE3o83mr+xdSQwZnUd+0v1otF5PyMoeH5QgDSToIJCAcxaVFAogFmLCgoFMGtRQaEAZi0qKBTArEUFhQKYtaigUACzFhUUCmDWooJCAcxaVFAogFmLCgoFMGtRQaEAZi3qLxT2S2cfdjZwH0cx5/YAAAAASUVORK5CYII=\",\n \"style\": {\n \"background-image\": \"url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEoAAAAeCAYAAACLz4iQAAAAAXNSR0IArs4c6QAAAIJJREFUaEPt0rENgDAQBEHcG6IiyqAiRG8gdzDE3o83mr+xdSQwZnUd+0v1otF5PyMoeH5QgDSToIJCAcxaVFAogFmLCgoFMGtRQaEAZi0qKBTArEUFhQKYtaigUACzFhUUCmDWooJCAcxaVFAogFmLCgoFMGtRQaEAZi3qLxT2S2cfdjZwH0cx5/YAAAAASUVORK5CYII=)\",\n \"background-size\": \"37px 15px\"\n }\n },\n {\n \"x\": 156,\n \"y\": 128,\n \"width\": 28,\n \"height\": 30,\n \"pixelRatio\": 2,\n \"sdf\": false,\n \"id\": \"Road/Rectangle white black/1\",\n \"centerColor\": {\n \"0\": 140,\n \"1\": 70,\n \"2\": 68,\n \"3\": 255\n },\n \"imageData\": \"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABwAAAAeCAYAAAA/xX6fAAAAAXNSR0IArs4c6QAAAIJJREFUSEtjZKAzYATZ1+PmaMzAwHyGlnb//c8oXb579zOwhX1ubr7/GP5toqWFTAxMfkW7dm0etZBqoTwapFQLSphBo0E6GqQkh8BooiE5yAhpGA1SQiFEsvxokJIcZIQ0jAYpoRAiWX6EBWmnq6sUM+P/pySHEwkaUJr6JOijWCkAOS3FHy7KEKAAAAAASUVORK5CYII=\",\n \"style\": {\n \"background-image\": \"url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABwAAAAeCAYAAAA/xX6fAAAAAXNSR0IArs4c6QAAAIJJREFUSEtjZKAzYATZ1+PmaMzAwHyGlnb//c8oXb579zOwhX1ubr7/GP5toqWFTAxMfkW7dm0etZBqoTwapFQLSphBo0E6GqQkh8BooiE5yAhpGA1SQiFEsvxokJIcZIQ0jAYpoRAiWX6EBWmnq6sUM+P/pySHEwkaUJr6JOijWCkAOS3FHy7KEKAAAAAASUVORK5CYII=)\",\n \"background-size\": \"14px 15px\"\n }\n },\n {\n \"x\": 124,\n \"y\": 222,\n \"width\": 36,\n \"height\": 30,\n \"pixelRatio\": 2,\n \"sdf\": false,\n \"id\": \"Road/Rectangle white black/2\",\n \"centerColor\": {\n \"0\": 140,\n \"1\": 70,\n \"2\": 68,\n \"3\": 255\n },\n \"imageData\": \"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACQAAAAeCAYAAABE4bxTAAAAAXNSR0IArs4c6QAAAIVJREFUWEdjZBhkgBHknk5XVylmxv9PB9JtJbv2gN0CJnrcHI0ZGJjPDKSDGBj+mpTs2n921EG4Y2E0hAil0NEQGg0hQiFASH40DY2GEKEQICQ/moZGQ4hQCBCSH01DoyFEKAQIyY+modEQIhQChOQHcxoaDF3pv/8Zpct3734G7rkOJgAAF2OpH67+++AAAAAASUVORK5CYII=\",\n \"style\": {\n \"background-image\": \"url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACQAAAAeCAYAAABE4bxTAAAAAXNSR0IArs4c6QAAAIVJREFUWEdjZBhkgBHknk5XVylmxv9PB9JtJbv2gN0CJnrcHI0ZGJjPDKSDGBj+mpTs2n921EG4Y2E0hAil0NEQGg0hQiFASH40DY2GEKEQICQ/moZGQ4hQCBCSH01DoyFEKAQIyY+modEQIhQChOQHcxoaDF3pv/8Zpct3734G7rkOJgAAF2OpH67+++AAAAAASUVORK5CYII=)\",\n \"background-size\": \"18px 15px\"\n }\n },\n {\n \"x\": 44,\n \"y\": 222,\n \"width\": 44,\n \"height\": 30,\n \"pixelRatio\": 2,\n \"sdf\": false,\n \"id\": \"Road/Rectangle white black/3\",\n \"centerColor\": {\n \"0\": 140,\n \"1\": 70,\n \"2\": 68,\n \"3\": 255\n },\n \"imageData\": \"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACwAAAAeCAYAAABXNvynAAAAAXNSR0IArs4c6QAAAH5JREFUWEdjZBhigBHk3k5XVylmxv9PB7PbS3btAbt1yDj4739G6fLdu5+NOphWyWo0hGkVsjBzR0N4NITRQmA0SYwmidEkQes0MBrCoyGMPwRGy2Fap5DREB4N4dFymNZpYDSER0OYhJoOpLTHzeU/nQONJOtQhqpI0jnAigHcf9kfB5MDLQAAAABJRU5ErkJggg==\",\n \"style\": {\n \"background-image\": \"url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACwAAAAeCAYAAABXNvynAAAAAXNSR0IArs4c6QAAAH5JREFUWEdjZBhigBHk3k5XVylmxv9PB7PbS3btAbt1yDj4739G6fLdu5+NOphWyWo0hGkVsjBzR0N4NITRQmA0SYwmidEkQes0MBrCoyGMPwRGy2Fap5DREB4N4dFymNZpYDSER0OYhJoOpLTHzeU/nQONJOtQhqpI0jnAigHcf9kfB5MDLQAAAABJRU5ErkJggg==)\",\n \"background-size\": \"22px 15px\"\n }\n },\n {\n \"x\": 298,\n \"y\": 192,\n \"width\": 50,\n \"height\": 30,\n \"pixelRatio\": 2,\n \"sdf\": false,\n \"id\": \"Road/Rectangle white black/4\",\n \"centerColor\": {\n \"0\": 140,\n \"1\": 70,\n \"2\": 68,\n \"3\": 255\n },\n \"imageData\": \"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAeCAYAAABuUU38AAAAAXNSR0IArs4c6QAAAHdJREFUWEftktEJgDAQxbzdxIk6hhNJd7P0xwEeRKrE/xe8pLX95Kt5x3ns95fvaVcvD1mpoEVWqjH/xSIWgQz4tCCxMdYisTpoaBFIbIy1SKwOGloEEhtjLRKrg4YWgcTGWIvE6qChRSCxMdYisTpo+BSB+K9iB7sOcB+Yn4bIAAAAAElFTkSuQmCC\",\n \"style\": {\n \"background-image\": \"url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAeCAYAAABuUU38AAAAAXNSR0IArs4c6QAAAHdJREFUWEftktEJgDAQxbzdxIk6hhNJd7P0xwEeRKrE/xe8pLX95Kt5x3ns95fvaVcvD1mpoEVWqjH/xSIWgQz4tCCxMdYisTpoaBFIbIy1SKwOGloEEhtjLRKrg4YWgcTGWIvE6qChRSCxMdYisTpo+BSB+K9iB7sOcB+Yn4bIAAAAAElFTkSuQmCC)\",\n \"background-size\": \"25px 15px\"\n }\n },\n {\n \"x\": 190,\n \"y\": 192,\n \"width\": 58,\n \"height\": 30,\n \"pixelRatio\": 2,\n \"sdf\": false,\n \"id\": \"Road/Rectangle white black/5\",\n \"centerColor\": {\n \"0\": 140,\n \"1\": 70,\n \"2\": 68,\n \"3\": 255\n },\n \"imageData\": \"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADoAAAAeCAYAAAB9hg0IAAAAAXNSR0IArs4c6QAAAGpJREFUWEft1MENgEAMA0HSG6IiyqAidL2B7sMLCnCYVBB7V67lJ1cz57GtV+e8+zlK0E6EEe1Ec2ZBFNHQBqgbCu7zbUQRDW2AuqHgjBF1qRvaAHVDwVld6lI3tAHqhoKzuo+63Qi+5bkBTstwHzqs1nYAAAAASUVORK5CYII=\",\n \"style\": {\n \"background-image\": \"url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADoAAAAeCAYAAAB9hg0IAAAAAXNSR0IArs4c6QAAAGpJREFUWEft1MENgEAMA0HSG6IiyqAidL2B7sMLCnCYVBB7V67lJ1cz57GtV+e8+zlK0E6EEe1Ec2ZBFNHQBqgbCu7zbUQRDW2AuqHgjBF1qRvaAHVDwVld6lI3tAHqhoKzuo+63Qi+5bkBTstwHzqs1nYAAAAASUVORK5CYII=)\",\n \"background-size\": \"29px 15px\"\n }\n },\n {\n \"x\": 66,\n \"y\": 192,\n \"width\": 66,\n \"height\": 30,\n \"pixelRatio\": 2,\n \"sdf\": false,\n \"id\": \"Road/Rectangle white black/6\",\n \"centerColor\": {\n \"0\": 140,\n \"1\": 70,\n \"2\": 68,\n \"3\": 255\n },\n \"imageData\": \"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEIAAAAeCAYAAACYGMhkAAAAAXNSR0IArs4c6QAAAHZJREFUaEPt2LEJgDAQBdC73cSJHMOJJLsZIjaKyNX6UqRK9bn/SJJhHQnk2NZ52v+cx7K1FERECOKsgSAEcRXRRJgIE/F4S1AN1VAN1Xh7QjCCEYxgBCMKHy2whCUsYQlLWBYSgCUsYQnLAhVulncsC6F9/kgH4nlwHzTeD0oAAAAASUVORK5CYII=\",\n \"style\": {\n \"background-image\": \"url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEIAAAAeCAYAAACYGMhkAAAAAXNSR0IArs4c6QAAAHZJREFUaEPt2LEJgDAQBdC73cSJHMOJJLsZIjaKyNX6UqRK9bn/SJJhHQnk2NZ52v+cx7K1FERECOKsgSAEcRXRRJgIE/F4S1AN1VAN1Xh7QjCCEYxgBCMKHy2whCUsYQlLWBYSgCUsYQnLAhVulncsC6F9/kgH4nlwHzTeD0oAAAAASUVORK5CYII=)\",\n \"background-size\": \"33px 15px\"\n }\n },\n {\n \"x\": 258,\n \"y\": 128,\n \"width\": 74,\n \"height\": 30,\n \"pixelRatio\": 2,\n \"sdf\": false,\n \"id\": \"Road/Rectangle white black/7\",\n \"centerColor\": {\n \"0\": 140,\n \"1\": 70,\n \"2\": 68,\n \"3\": 255\n },\n \"imageData\": \"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEoAAAAeCAYAAACLz4iQAAAAAXNSR0IArs4c6QAAAIhJREFUaEPt1TESQDAARUG5m3Eix3Ai425MGvVTW/WrNj8yFl8SGLM6tvVO9U+j/bwGqHD4oALSTECBigIxsyhQUeBD5tULWK5eQPLqRSRQoD4IxNQ/ClQUiJlFgYoCMbMoUFEgZhYFKgrEzKJARYGYWRSoKBAziwIVBWJmUaCiQMzeRcX+19kDed5uNGK5/SYAAAAASUVORK5CYII=\",\n \"style\": {\n \"background-image\": \"url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEoAAAAeCAYAAACLz4iQAAAAAXNSR0IArs4c6QAAAIhJREFUaEPt1TESQDAARUG5m3Eix3Ai425MGvVTW/WrNj8yFl8SGLM6tvVO9U+j/bwGqHD4oALSTECBigIxsyhQUeBD5tULWK5eQPLqRSRQoD4IxNQ/ClQUiJlFgYoCMbMoUFEgZhYFKgrEzKJARYGYWRSoKBAziwIVBWJmUaCiQMzeRcX+19kDed5uNGK5/SYAAAAASUVORK5CYII=)\",\n \"background-size\": \"37px 15px\"\n }\n },\n {\n \"x\": 64,\n \"y\": 128,\n \"width\": 64,\n \"height\": 64,\n \"pixelRatio\": 2,\n \"sdf\": false,\n \"id\": \"Special area of interest/Groundcover\",\n \"centerColor\": {\n \"0\": 0,\n \"1\": 0,\n \"2\": 0,\n \"3\": 0\n },\n \"imageData\": \"data:image/png;base64,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\",\n \"style\": {\n \"background-image\": \"url(data:image/png;base64,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)\",\n \"background-size\": \"32px 32px\"\n }\n },\n {\n \"x\": 64,\n \"y\": 128,\n \"width\": 64,\n \"height\": 64,\n \"pixelRatio\": 2,\n \"sdf\": false,\n \"id\": \"Special area of interest/Rock or gravel\",\n \"centerColor\": {\n \"0\": 0,\n \"1\": 0,\n \"2\": 0,\n \"3\": 0\n },\n \"imageData\": \"data:image/png;base64,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\",\n \"style\": {\n \"background-image\": \"url(data:image/png;base64,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)\",\n \"background-size\": \"32px 32px\"\n }\n },\n {\n \"x\": 0,\n \"y\": 128,\n \"width\": 64,\n \"height\": 64,\n \"pixelRatio\": 2,\n \"sdf\": false,\n \"id\": \"Special area of interest/Sand\",\n \"centerColor\": {\n \"0\": 50,\n \"1\": 51,\n \"2\": 51,\n \"3\": 255\n },\n \"imageData\": \"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAAAXNSR0IArs4c6QAABRhJREFUeF7tm+lSG0EMhBnMaXMZDA8SrmAqxLz/m3CYw+a+UlHxbbEyKmmI/8QDf7bs2dWanh51Szubfmxvv019+FteXpZPNzc3cnx9ff04PLWwsCCfHx4e5Pj2Vru8du7fDykl+W5paUmOt7e3cnx5eamdOz8/X4s7Ekh9MTMzI98sLi7KcTAY1M7gvsS9v7//NGT6BkAxwEN+fX1dTrm6uvp0Jr3r9Tgz1el0ZKjf748l7vT0tMQh7tnZmXzWjB5hgPcPTBwAv3s9WcR6DXlAWOMbGxsyNBwOs9a0FQ+GbG5uyinn5+djYcjq6qrEScUDsLe/Lwx4fn6uTUKr1ZLPj4+Pcnx6egqRYnZ2tjZDes2RtfkeNfGCWyqhVcZSLx0fFUnFA6BlEKSYKXRe62ij0ZBTybZRhsAsGHB3d1ebHOJp5ng5Av9C7tHXwyAYzf9lqkDxAHhrkpkEWfRbX8ca9Rwj16EiMI417f0ejyH4gYuLCzmVnJftA7jRxADQPTwUFWANnZ6efhXs2nV4f7Lt5eVlKC65RdcKXIwRQz2iDLGYmIoHYGd3VxgA8jqbM4Os9SjixAN57TOIx7hVrWnaeD6j2WzKJeQcrTIjOap4ACwfAFIgzoyhsxrJ3HoemYUB9AmIy/cwSTPISigeA/AZrg8oFoBc3SZHoN+oSNTJWTMJQzhaPiMkLR9OWllZqV0y4gOKBYCZRGetDoqFuOXhySEgz0xGnaF1v7m5ORnCb0QZwgRXuYYkWDwAIOJlcywwTiyanVnLVvVH9sZneAxBHWCYVa1yX0u9RnJAcQBYDRFr7a2trckQuk19zfmel9dxyR3kiOvrazlFq0hunwBmUOPoHFE51eIB6B0f17rC3trzdHdra0tOoe6Odoo8ddFd4WjuseLCuFQ8AFYtQFZGb6P1PHJqzVC73ZZJIdvrHGLNmJVb0HXiku2jcc2OUPEAMJNkX42oN+55fOLpzg9Pn2FQdK2j9/gTrSI8CYJ5bk/Q+we98f8OgFz9ZokABPqt63kYZPX4NFA4TdTD8hnMcFS18AMwhLhVDigWgJ8HB+IDcHgnJyee1IfGWcvj7jZTrVJTeD0/78em4gHAB3j1PHU3Ds9DlnErLvFYw9Fus3df4pIjdK9RX1/lgOIB8Lw4a9rq3qLDHuLcB4eJk9P7BKjmGI86O+JyH32djus+G4QZEwvA9s6OqEBUTzVTor253HoeRhGfXWlWPyHahca/8HtS8QCgAnq/HohH156VQ1hzVGvj8hkwA/+S28WuHOs3AGqnqLUXWNfd7CuMdnxggvX0mWoNnxFd05aFhyE4UfYXmj6AgeIAyG2KkkXx4Fo9qObo03tVYFRmvV3femZhBtdpf1L5geIB+HV0JD7A8uK5D0up1ogX3Qnq9QLJ9tazxVyfUXWFiwfA6gpTVYGs7vh4VZk1zj4CGBLdG+Tdj+cR/M5oXLMWKB4AZh7krXeHOC9aBZJ96cpqFcEPEO9ffQY5jLj62aPJgGIA2N3bExWguxvN2hgmENa9OXSYY7Sm0G+XaebBIJgTfW5AXH4n/iQVD8BBtysMwMFF99p4WRnEmTGrl5jbjke/YYbe+ZHrW1LxAHg7RaNVlccI6wkQtcW4dqnn+gy3J1g8AN47uKxh1jw6G+0xWh6euNTzdKi8uJ7P0HuJXQYUB4D39vhI3f3+FnfrfZ++rhm+OpMwgxnT2b7xft+m8fa4lZP0y2DZb49PGgB/AFWursjFdg4fAAAAAElFTkSuQmCC\",\n \"style\": {\n \"background-image\": \"url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAAAXNSR0IArs4c6QAABRhJREFUeF7tm+lSG0EMhBnMaXMZDA8SrmAqxLz/m3CYw+a+UlHxbbEyKmmI/8QDf7bs2dWanh51Szubfmxvv019+FteXpZPNzc3cnx9ff04PLWwsCCfHx4e5Pj2Vru8du7fDykl+W5paUmOt7e3cnx5eamdOz8/X4s7Ekh9MTMzI98sLi7KcTAY1M7gvsS9v7//NGT6BkAxwEN+fX1dTrm6uvp0Jr3r9Tgz1el0ZKjf748l7vT0tMQh7tnZmXzWjB5hgPcPTBwAv3s9WcR6DXlAWOMbGxsyNBwOs9a0FQ+GbG5uyinn5+djYcjq6qrEScUDsLe/Lwx4fn6uTUKr1ZLPj4+Pcnx6egqRYnZ2tjZDes2RtfkeNfGCWyqhVcZSLx0fFUnFA6BlEKSYKXRe62ij0ZBTybZRhsAsGHB3d1ebHOJp5ng5Av9C7tHXwyAYzf9lqkDxAHhrkpkEWfRbX8ca9Rwj16EiMI417f0ejyH4gYuLCzmVnJftA7jRxADQPTwUFWANnZ6efhXs2nV4f7Lt5eVlKC65RdcKXIwRQz2iDLGYmIoHYGd3VxgA8jqbM4Os9SjixAN57TOIx7hVrWnaeD6j2WzKJeQcrTIjOap4ACwfAFIgzoyhsxrJ3HoemYUB9AmIy/cwSTPISigeA/AZrg8oFoBc3SZHoN+oSNTJWTMJQzhaPiMkLR9OWllZqV0y4gOKBYCZRGetDoqFuOXhySEgz0xGnaF1v7m5ORnCb0QZwgRXuYYkWDwAIOJlcywwTiyanVnLVvVH9sZneAxBHWCYVa1yX0u9RnJAcQBYDRFr7a2trckQuk19zfmel9dxyR3kiOvrazlFq0hunwBmUOPoHFE51eIB6B0f17rC3trzdHdra0tOoe6Odoo8ddFd4WjuseLCuFQ8AFYtQFZGb6P1PHJqzVC73ZZJIdvrHGLNmJVb0HXiku2jcc2OUPEAMJNkX42oN+55fOLpzg9Pn2FQdK2j9/gTrSI8CYJ5bk/Q+we98f8OgFz9ZokABPqt63kYZPX4NFA4TdTD8hnMcFS18AMwhLhVDigWgJ8HB+IDcHgnJyee1IfGWcvj7jZTrVJTeD0/78em4gHAB3j1PHU3Ds9DlnErLvFYw9Fus3df4pIjdK9RX1/lgOIB8Lw4a9rq3qLDHuLcB4eJk9P7BKjmGI86O+JyH32djus+G4QZEwvA9s6OqEBUTzVTor253HoeRhGfXWlWPyHahca/8HtS8QCgAnq/HohH156VQ1hzVGvj8hkwA/+S28WuHOs3AGqnqLUXWNfd7CuMdnxggvX0mWoNnxFd05aFhyE4UfYXmj6AgeIAyG2KkkXx4Fo9qObo03tVYFRmvV3femZhBtdpf1L5geIB+HV0JD7A8uK5D0up1ogX3Qnq9QLJ9tazxVyfUXWFiwfA6gpTVYGs7vh4VZk1zj4CGBLdG+Tdj+cR/M5oXLMWKB4AZh7krXeHOC9aBZJ96cpqFcEPEO9ffQY5jLj62aPJgGIA2N3bExWguxvN2hgmENa9OXSYY7Sm0G+XaebBIJgTfW5AXH4n/iQVD8BBtysMwMFF99p4WRnEmTGrl5jbjke/YYbe+ZHrW1LxAHg7RaNVlccI6wkQtcW4dqnn+gy3J1g8AN47uKxh1jw6G+0xWh6euNTzdKi8uJ7P0HuJXQYUB4D39vhI3f3+FnfrfZ++rhm+OpMwgxnT2b7xft+m8fa4lZP0y2DZb49PGgB/AFWursjFdg4fAAAAAElFTkSuQmCC)\",\n \"background-size\": \"32px 32px\"\n }\n },\n {\n \"x\": 0,\n \"y\": 0,\n \"width\": 128,\n \"height\": 128,\n \"pixelRatio\": 2,\n \"sdf\": false,\n \"id\": \"Water area/Inundated area\",\n \"centerColor\": {\n \"0\": 29,\n \"1\": 34,\n \"2\": 36,\n \"3\": 211\n },\n \"imageData\": \"data:image/png;base64,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\",\n \"style\": {\n \"background-image\": \"url(data:image/png;base64,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)\",\n \"background-size\": \"64px 64px\"\n }\n },\n {\n \"x\": 128,\n \"y\": 0,\n \"width\": 128,\n \"height\": 128,\n \"pixelRatio\": 2,\n \"sdf\": false,\n \"id\": \"Water area/Lake or river intermittent\",\n \"centerColor\": {\n \"0\": 46,\n \"1\": 48,\n \"2\": 48,\n \"3\": 255\n },\n \"imageData\": \"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIAAAACACAYAAADDPmHLAAAAAXNSR0IArs4c6QAAB/JJREFUeF7tXdlWGzkQtcxutvzAkJlgSDIEY5P//6cBjFkMZk4kXZ202kovdrelrsuLMQcRp+ve2lWlRuPxR6/X6/338Pjrpffxod+6L2W/Oz0+1N/tbG/r1/fFQr/e2XN4nznc6/VODgf6R3u7O/p1Yf8+zr29v/tH9Pujg339erC/l/lcd9OZfj9/e1t6bmB//9Cexy/dP5pzL6/zpefw+Y4H5vMq+x9/fHrW72fPL0vP7drncXKEc+bgk/39qT3vH97e2tI/wnPt238Qnw+f1z/X7/f1jz5ZeWzZ969z8zzup1aO3kFl/z7O4d9XBIB5UmIBcHZ+oSlP5stiPjSvIgCMaZKm+h0A/voyzBh96TYfNhs23LfBbdt82Hj4CqvafAgePpgiALKqXywAyHzj7UthPqIxpwEIAKEAOLM+gNQ4X4rKD+Z5CAAZzA8C4PrmRkcBK2f4FiaYuLOZqNgzfOKZb8MbRQDEkeJtKtwrSvGr258/NXVr5/bJfM2lurn9pgSPOB/ePvIZcPZPjkxthwDwMj1dS/QUAuBmMtEaoHJVTwrzX4yJmM6Ms+h/pcr83R1T1VUEgBFpkPldB8Dfw8uMD+AjPFfPL8v8ga3n72Xr+fe2nv/aUj1firdf1uaD+fD5FAFgVGFbDR2bdvpyAPCLQdAAtTt5yPylvkJsgkd4mKsGEgDW6VtzK1cyACDzu+ntw+aD+Qvb05nTAASAUABQ8O0IHt3M8NqzPdi/upFNrs7v3vU7eYoSPL6z5zPfZQbhBBIAQgFwdT3SIKzctx+Jtx9b337I2YuN+U4DEAAyme8AgGrgqjd22s7wkflGhKjqlbX5fpjvqoEEgHk06y7uxKr64fOp8e1tphpYtZOnLvMf7F2958Tv6qVm831nnwCwOlEa8+H0q38uvmoN0BbzW7+lW7acaztk+n0Thxfd0k2d+e5eAAFgr2lLBUCoGhi6n1/X5pP57Wb4yhb1gtVAAsAMlPC/uqL6g5dDKXgZgg9eDycAhAKAgpcl+Fw1kAAQCoDvVz90HsCfxkVv30zj8idzxJ7arVrVVQSATObnqoGYEkbmx8X8yje2Ks5hdNVAAsBwIrY4v3EATGw1kMyXxXz4fIoAkMl8B4Dzy286Cmjrrl7tTh4hVb2mVb4f7SkCQKbqh88XLAb5U7cxRPxh1vLUbTLf9P6teeo6fD4CwBu7vqlET9uqPwiAtpmP6WSndeftR9LIUTSMKdS9uynBw+fLaQACoNrCBZRVkwcABS9L8LlqIAEgFABf/73SeQDs2Gna26fNN0CLZceSIgC6zfyiJVu/FYOMVWgqzifz42I+TD4B4LX9Fg1oSMXbL2K+A8Dk1swKjpb5NlFTdq9eU+XcrgkePp8iAIwKkMZ8B4Dht+9aA6x7o+bKNj8R5qe6aQXRniIA/nxlq0j1Jw+A0N1AdJeiCgVfqaieT+bH6e2HdikHq4EEgIxl2jkAUPAyBA+fjwCwa9zLVvVStfkw4f41fQcAMl8W83PVQAJAKAAQBtLbz07tlbJK1+UBCAChAEAq2A6p7jHON9axa86eP+rGjYkjAGQy3wEAs4JTYf7r/E2D+d7uKK46b7+rqd1QmBdi/vFgYIpgBICtBtonJUX1OwCgJWz2vHyJciy5fTLfINRv3q3NfBvmuJ5AAsAsUwbgay/Trjigwb+sWbaTJ1TcqVrWDxaDyPyKVb2yG1UP7EbV/exG1bYFD5+PALCNJyszvysA6Mr69Na8/UQFD5Of0wAEgAzVnwMABd+u4GOZyeQ0AAEgFAAYEZP6+vTobH4iexXdjCACYOFnTfX73GiWsk5fKgDAmDhcjHiyGcFpIuvTyfwdDVSX2rUZvqLaDky+mxNIAGQVQNeZ7wCAYhCZbwAgRfDO5BMAMpnvAIBx8eu2+f2+GcD4yRvDlkxVr2POXijMd/sCCADTIOEWLkgBQOhuYN1VqmS+maQa/exlG+0Fq4EEgMkMBlfqJhLnF2V4cwCg4GUIHiafANg1iZSFEJvvh/sOAGS+LOYj+CUAhDLfAQDr49EOXXYaF739tLz9UJivCACZqt9pgLHdGiaG+Su2bcfSyQMBFoV5RQk+RQC8L+0DSH6XcsmyvrsahgsFGCHiP5XkbT6Zr0XqR3sEgId0KcyH06+urkf6gi2Zv/zGTpHNx9UuAAd48ocx+RoVRae6nTzrauEjAKxk6jI/eQCEqoG0+X+O86MRfNm9ioHZy8FqIAEgFACbEnyse/V8290284O3tFdkPnyUnAYgAOJifmsAoODjEnwww7cm5ueqgQSAUAB8Hl7qPEDb3bu0+ctnMrXFfKcBCACZzHcAuJlMtAbAtq2m+/ZTZf7GNqqWtfk1t6grAsAMniwK9zoLAFwNI/MNBPw4v6uCd8UgAiDLfXEA+DG6MdXAhmbv0uY3NIG1ps0H8+HzKQIgMtVfspPndF0AOPsy1Bpg3VO3yfy4mT9/M86vIgDMyFb0A2zM6WuZ+Q4Afj9A0RLluwfTRr3Ak7I+FHbskPkNMb+hXcq5aiABYDKDVaduFw1limX4NpgPIjsA4F4AvER0j+J6NJlfbxpXrIKHz0cA2CfxMJPFfAeAz+cX+nsyf740Jdz5hZoEQDnmd3av4mg81hqANj+rADrPfLsoUhEAQlU/AIBiUNn16aE4HzN7F4uSQ5dbvqtXNcHTWZVvBY8OMHc3kAAwJkCK6gcA/gcX1PO6W1Uk1AAAAABJRU5ErkJggg==\",\n \"style\": {\n \"background-image\": \"url(data:image/png;base64,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)\",\n \"background-size\": \"64px 64px\"\n }\n },\n {\n \"x\": 64,\n \"y\": 128,\n \"width\": 64,\n \"height\": 64,\n \"pixelRatio\": 2,\n \"sdf\": false,\n \"id\": \"Water area/Playa\",\n \"centerColor\": {\n \"0\": 0,\n \"1\": 0,\n \"2\": 0,\n \"3\": 0\n },\n \"imageData\": \"data:image/png;base64,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\",\n \"style\": {\n \"background-image\": \"url(data:image/png;base64,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)\",\n \"background-size\": \"32px 32px\"\n }\n },\n {\n \"x\": 256,\n \"y\": 0,\n \"width\": 128,\n \"height\": 128,\n \"pixelRatio\": 2,\n \"sdf\": false,\n \"id\": \"Water area/Swamp or marsh\",\n \"centerColor\": {\n \"0\": 77,\n \"1\": 79,\n \"2\": 79,\n \"3\": 181\n },\n \"imageData\": \"data:image/png;base64,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\",\n \"style\": {\n \"background-image\": \"url(data:image/png;base64,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)\",\n \"background-size\": \"64px 64px\"\n }\n },\n {\n \"x\": 160,\n \"y\": 222,\n \"width\": 16,\n \"height\": 22,\n \"pixelRatio\": 2,\n \"sdf\": false,\n \"id\": \"Water line/Levee/0\",\n \"centerColor\": {\n \"0\": 0,\n \"1\": 0,\n \"2\": 0,\n \"3\": 0\n },\n \"imageData\": \"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAWCAYAAADJqhx8AAAAAXNSR0IArs4c6QAAAK1JREFUOE9jZKAQMFKon2HUAIbRMGAYtGGgrKa58j/Df2v0ZP6fgWHa/Vs32pDFsSZlJXV1E4b/jKeQvfifgeHtX3ZW1UeXL78naABIgZKaxnwGBoYEmOL/DIw5929dn4ruKpyZSUFLS4Lpz79bDAwMvAwMDFfv3bqhz8DA8JdoA8CuUNcsZ/j/v4PhP6PrvdvX92DL+nizs5aWFtuPP//a7926UYyr3BgtDxgYAKveLhcPM+OgAAAAAElFTkSuQmCC\",\n \"style\": {\n \"background-image\": \"url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAWCAYAAADJqhx8AAAAAXNSR0IArs4c6QAAAK1JREFUOE9jZKAQMFKon2HUAIbRMGAYtGGgrKa58j/Df2v0ZP6fgWHa/Vs32pDFsSZlJXV1E4b/jKeQvfifgeHtX3ZW1UeXL78naABIgZKaxnwGBoYEmOL/DIw5929dn4ruKpyZSUFLS4Lpz79bDAwMvAwMDFfv3bqhz8DA8JdoA8CuUNcsZ/j/v4PhP6PrvdvX92DL+nizs5aWFtuPP//a7926UYyr3BgtDxgYAKveLhcPM+OgAAAAAElFTkSuQmCC)\",\n \"background-size\": \"8px 11px\"\n }\n }\n ]\n },\n \"arcgisQuickEditor\": {\n \"land\": \"#6c6f75\",\n \"labelTextColor\": \"#ffffff\",\n \"labelHaloColor\": \"#000000\",\n \"baseColor\": \"#7c838d\",\n \"spriteProcessing\": true,\n \"labelContrast\": 4.5,\n \"labelColorMode\": \"LABELS_MAP_COLORS\",\n \"colorMode\": \"CUSTOM\",\n \"colors\": {\n \"water\": \"#3f495c\",\n \"land\": \"#6c6f75\",\n \"building\": \"#474b52\",\n \"road\": \"#dd7d78\",\n \"boundaries\": \"#edeff0\"\n },\n \"road\": \"#dd7d78\",\n \"water\": \"#3f495c\",\n \"boundaries\": \"#edeff0\"\n },\n \"arcgisQuickEditorWarning\": true,\n \"arcgisEditorExtents\": [\n {\n \"spatialReference\": {\n \"wkid\": 102100\n },\n \"xmin\": -13291652.777350293,\n \"ymin\": 3143561.5776870735,\n \"xmax\": -8989165.329235436,\n \"ymax\": 5276460.414956065\n },\n {\n \"spatialReference\": {\n \"latestWkid\": 3857,\n \"wkid\": 102100\n },\n \"xmin\": -371197.9381234135,\n \"ymin\": 6496985.075827017,\n \"xmax\": 343029.6541730836,\n \"ymax\": 6905464.554982891\n },\n {\n \"spatialReference\": {\n \"latestWkid\": 3857,\n \"wkid\": 102100\n },\n \"xmin\": -8597472.051695079,\n \"ymin\": 4692615.939336582,\n \"xmax\": -8552832.827176519,\n \"ymax\": 4718145.906783841\n },\n {\n \"spatialReference\": {\n \"latestWkid\": 3857,\n \"wkid\": 102100\n },\n \"xmin\": 16831588.19989802,\n \"ymin\": -4011777.2067113556,\n \"xmax\": 16832983.17566426,\n \"ymax\": -4010979.3952286085\n }\n ],\n \"arcgisMinimapVisibility\": true\n }\n}\n","{\n \"version\": 8,\n \"glyphs\": \"https://basemaps.arcgis.com/arcgis/rest/services/World_Basemap_v2/VectorTileServer/resources/fonts/{fontstack}/{range}.pbf?token=\",\n \"sources\": {\n \"esri\": {\n \"type\": \"vector\",\n \"url\": \"https://basemaps.arcgis.com/arcgis/rest/services/World_Basemap_v2/VectorTileServer\",\n \"tiles\": [\n \"https://basemaps.arcgis.com/arcgis/rest/services/World_Basemap_v2/VectorTileServer/tile/{z}/{y}/{x}.pbf?token=\"\n ]\n }\n },\n \"layers\": [\n {\n \"id\": \"Land/Not ice\",\n \"type\": \"fill\",\n \"source\": \"esri\",\n \"source-layer\": \"Land\",\n \"filter\": [\"==\", \"_symbol\", 0],\n \"layout\": {},\n \"paint\": {\n \"fill-color\": \"#e4e7eb\",\n \"fill-opacity\": 1\n }\n },\n {\n \"id\": \"Land/Coastline\",\n \"type\": \"line\",\n \"source\": \"esri\",\n \"source-layer\": \"Land\",\n \"layout\": {\n \"line-cap\": \"round\",\n \"line-join\": \"round\",\n \"visibility\": \"none\"\n },\n \"paint\": {\n \"line-color\": \"#9e9ba8\",\n \"line-width\": {\n \"stops\": [\n [0, 2],\n [9, 2]\n ]\n }\n }\n },\n {\n \"id\": \"Land/Ice\",\n \"type\": \"fill\",\n \"source\": \"esri\",\n \"source-layer\": \"Land\",\n \"filter\": [\"==\", \"_symbol\", 1],\n \"layout\": {},\n \"paint\": {\n \"fill-color\": \"#e4e7eb\",\n \"fill-opacity\": 1\n }\n },\n {\n \"id\": \"Land/Ice/Coastline\",\n \"type\": \"line\",\n \"source\": \"esri\",\n \"source-layer\": \"Land\",\n \"filter\": [\"==\", \"_symbol\", 1],\n \"layout\": {\n \"line-cap\": \"round\",\n \"line-join\": \"round\",\n \"visibility\": \"none\"\n },\n \"paint\": {\n \"line-color\": \"#9e9ba8\",\n \"line-width\": {\n \"stops\": [\n [0, 2],\n [9, 2]\n ]\n }\n }\n },\n {\n \"id\": \"Airport/Airport property\",\n \"type\": \"fill\",\n \"source\": \"esri\",\n \"source-layer\": \"Airport\",\n \"filter\": [\"==\", \"_symbol\", 1],\n \"minzoom\": 9,\n \"layout\": {},\n \"paint\": {\n \"fill-color\": \"#bdcada\",\n \"fill-opacity\": 0.15\n }\n },\n {\n \"id\": \"Airport/Airport runway\",\n \"type\": \"fill\",\n \"source\": \"esri\",\n \"source-layer\": \"Airport\",\n \"filter\": [\"==\", \"_symbol\", 0],\n \"minzoom\": 11,\n \"layout\": {},\n \"paint\": {\n \"fill-color\": \"#bdcada\"\n }\n },\n {\n \"id\": \"Water line small scale\",\n \"type\": \"line\",\n \"source\": \"esri\",\n \"source-layer\": \"Water line small scale\",\n \"minzoom\": 1,\n \"maxzoom\": 5,\n \"layout\": {\n \"line-join\": \"round\"\n },\n \"paint\": {\n \"line-color\": \"#8fabd9\",\n \"line-width\": 0.5\n }\n },\n {\n \"id\": \"Water line medium scale\",\n \"type\": \"line\",\n \"source\": \"esri\",\n \"source-layer\": \"Water line medium scale\",\n \"minzoom\": 5,\n \"maxzoom\": 7,\n \"layout\": {\n \"line-join\": \"round\"\n },\n \"paint\": {\n \"line-color\": \"#8fabd9\",\n \"line-width\": {\n \"base\": 1.2,\n \"stops\": [\n [5, 0.5],\n [7, 0.7]\n ]\n }\n }\n },\n {\n \"id\": \"Water line large scale\",\n \"type\": \"line\",\n \"source\": \"esri\",\n \"source-layer\": \"Water line large scale\",\n \"minzoom\": 7,\n \"maxzoom\": 11,\n \"layout\": {\n \"line-cap\": \"round\",\n \"line-join\": \"round\"\n },\n \"paint\": {\n \"line-color\": \"#8fabd9\",\n \"line-width\": 0.7\n }\n },\n {\n \"id\": \"Water line/Stream or river\",\n \"type\": \"line\",\n \"source\": \"esri\",\n \"source-layer\": \"Water line\",\n \"filter\": [\"==\", \"_symbol\", 0],\n \"minzoom\": 11,\n \"layout\": {\n \"line-cap\": \"round\"\n },\n \"paint\": {\n \"line-color\": \"#8fabd9\",\n \"line-width\": {\n \"base\": 1.2,\n \"stops\": [\n [11, 0.7],\n [14, 0.7],\n [17, 2]\n ]\n }\n }\n },\n {\n \"id\": \"Marine area/detail\",\n \"type\": \"fill\",\n \"source\": \"esri\",\n \"source-layer\": \"Marine area\",\n \"layout\": {},\n \"paint\": {\n \"fill-color\": \"#8fabd9\"\n }\n },\n {\n \"id\": \"Water area small scale\",\n \"type\": \"fill\",\n \"source\": \"esri\",\n \"source-layer\": \"Water area small scale\",\n \"minzoom\": 1,\n \"maxzoom\": 5,\n \"layout\": {},\n \"paint\": {\n \"fill-color\": \"#8fabd9\"\n }\n },\n {\n \"id\": \"Water area medium scale/Lake or river\",\n \"type\": \"fill\",\n \"source\": \"esri\",\n \"source-layer\": \"Water area medium scale\",\n \"filter\": [\"==\", \"_symbol\", 0],\n \"minzoom\": 5,\n \"maxzoom\": 7,\n \"layout\": {},\n \"paint\": {\n \"fill-color\": \"#8fabd9\"\n }\n },\n {\n \"id\": \"Water area large scale/Lake or river\",\n \"type\": \"fill\",\n \"source\": \"esri\",\n \"source-layer\": \"Water area large scale\",\n \"filter\": [\"==\", \"_symbol\", 0],\n \"minzoom\": 7,\n \"maxzoom\": 11,\n \"layout\": {},\n \"paint\": {\n \"fill-color\": \"#8fabd9\"\n }\n },\n {\n \"id\": \"Water area/Lake, river or bay\",\n \"type\": \"fill\",\n \"source\": \"esri\",\n \"source-layer\": \"Water area\",\n \"filter\": [\"==\", \"_symbol\", 7],\n \"minzoom\": 11,\n \"layout\": {},\n \"paint\": {\n \"fill-color\": \"#8fabd9\"\n }\n },\n {\n \"id\": \"Water area/Dam or weir\",\n \"type\": \"fill\",\n \"source\": \"esri\",\n \"source-layer\": \"Water area\",\n \"filter\": [\"==\", \"_symbol\", 5],\n \"minzoom\": 11,\n \"layout\": {},\n \"paint\": {\n \"fill-color\": \"#8fabd9\",\n \"fill-outline-color\": \"#8fabd9\"\n }\n },\n {\n \"id\": \"Boundary line/Disputed admin2/0\",\n \"type\": \"line\",\n \"source\": \"esri\",\n \"source-layer\": \"Boundary line\",\n \"filter\": [\"all\", [\"==\", \"_symbol\", 8], [\"!in\", \"Viz\", 3]],\n \"minzoom\": 8,\n \"layout\": {\n \"line-join\": \"round\"\n },\n \"paint\": {\n \"line-color\": \"#595959\",\n \"line-opacity\": 0.5,\n \"line-dasharray\": [2, 3],\n \"line-width\": 1.5\n },\n \"showProperties\": false\n },\n {\n \"id\": \"Boundary line/Disputed admin1/1\",\n \"type\": \"line\",\n \"source\": \"esri\",\n \"source-layer\": \"Boundary line\",\n \"minzoom\": 4,\n \"filter\": [\"all\", [\"==\", \"_symbol\", 7], [\"!in\", \"Viz\", 3]],\n \"layout\": {\n \"line-join\": \"round\"\n },\n \"paint\": {\n \"line-color\": \"#303030\",\n \"line-opacity\": 0.5,\n \"line-width\": {\n \"base\": 1,\n \"stops\": [\n [4, 2],\n [6, 3.5],\n [14, 7],\n [17, 7]\n ]\n }\n },\n \"showProperties\": false\n },\n {\n \"id\": \"Boundary line/Disputed admin0/1\",\n \"type\": \"line\",\n \"source\": \"esri\",\n \"source-layer\": \"Boundary line\",\n \"filter\": [\n \"all\",\n [\"==\", \"_symbol\", 6],\n [\"!in\", \"Viz\", 3],\n [\"!in\", \"DisputeID\", 8, 16, 90, 96, 0]\n ],\n \"minzoom\": 4,\n \"layout\": {\n \"line-join\": \"round\"\n },\n \"paint\": {\n \"line-color\": \"#303030\",\n \"line-opacity\": 0.5,\n \"line-width\": {\n \"base\": 1.2,\n \"stops\": [\n [6, 5],\n [8, 7.5],\n [14, 10],\n [17, 10]\n ]\n }\n },\n \"showProperties\": false\n },\n {\n \"id\": \"Boundary line/Disputed admin0/0\",\n \"type\": \"line\",\n \"source\": \"esri\",\n \"source-layer\": \"Boundary line\",\n \"filter\": [\n \"all\",\n [\"==\", \"_symbol\", 6],\n [\"!in\", \"Viz\", 3],\n [\"!in\", \"DisputeID\", 8, 16, 90, 96, 0]\n ],\n \"minzoom\": 4,\n \"layout\": {\n \"line-join\": \"round\",\n \"visibility\": \"none\"\n },\n \"paint\": {\n \"line-width\": {\n \"base\": 1.2,\n \"stops\": [\n [4, 1.2],\n [17, 9]\n ]\n },\n \"line-color\": \"#595959\",\n \"line-opacity\": 0.7,\n \"line-dasharray\": [10, 4]\n },\n \"showProperties\": false\n },\n {\n \"id\": \"Boundary line/Disputed admin0/0 small\",\n \"type\": \"line\",\n \"source\": \"esri\",\n \"source-layer\": \"Boundary line\",\n \"filter\": [\n \"all\",\n [\"==\", \"_symbol\", 6],\n [\"!in\", \"Viz\", 3],\n [\"!in\", \"DisputeID\", 8, 16, 90, 96, 0]\n ],\n \"minzoom\": 1,\n \"maxzoom\": 4,\n \"layout\": {\n \"line-join\": \"round\",\n \"visibility\": \"none\"\n },\n \"paint\": {\n \"line-width\": 0.75,\n \"line-color\": \"#595959\",\n \"line-dasharray\": [4, 3]\n },\n \"showProperties\": false\n },\n {\n \"id\": \"Boundary line/Admin1/1\",\n \"type\": \"line\",\n \"source\": \"esri\",\n \"source-layer\": \"Boundary line\",\n \"filter\": [\"all\", [\"==\", \"_symbol\", 1], [\"!in\", \"Viz\", 3]],\n \"minzoom\": 3,\n \"layout\": {\n \"line-cap\": \"round\",\n \"line-join\": \"round\"\n },\n \"paint\": {\n \"line-color\": \"#303030\",\n \"line-width\": {\n \"base\": 1,\n \"stops\": [\n [3, 0.75],\n [6, 3.5],\n [14, 7],\n [17, 7]\n ]\n }\n },\n \"showProperties\": false\n },\n {\n \"id\": \"Boundary line/Admin0/1\",\n \"type\": \"line\",\n \"source\": \"esri\",\n \"source-layer\": \"Boundary line\",\n \"filter\": [\"all\", [\"==\", \"_symbol\", 0], [\"!in\", \"Viz\", 3]],\n \"minzoom\": 4,\n \"layout\": {\n \"line-cap\": \"round\",\n \"line-join\": \"round\"\n },\n \"paint\": {\n \"line-color\": \"#303030\",\n \"line-width\": {\n \"base\": 1.2,\n \"stops\": [\n [6, 4],\n [8, 6.5],\n [14, 8],\n [17, 8]\n ]\n }\n },\n \"showProperties\": false\n },\n {\n \"id\": \"Boundary line/Admin2/0\",\n \"type\": \"line\",\n \"source\": \"esri\",\n \"source-layer\": \"Boundary line\",\n \"filter\": [\"all\", [\"==\", \"_symbol\", 2], [\"!in\", \"Viz\", 3]],\n \"minzoom\": 6,\n \"layout\": {\n \"visibility\": \"none\",\n \"line-join\": \"round\"\n },\n \"paint\": {\n \"line-color\": \"#595959\",\n \"line-width\": 1.2,\n \"line-dasharray\": [2, 3]\n },\n \"showProperties\": false\n },\n {\n \"id\": \"Boundary line/Admin0/0\",\n \"type\": \"line\",\n \"source\": \"esri\",\n \"source-layer\": \"Boundary line\",\n \"filter\": [\"all\", [\"==\", \"_symbol\", 0], [\"!in\", \"Viz\", 3]],\n \"minzoom\": 4,\n \"layout\": {\n \"line-cap\": \"round\",\n \"line-join\": \"round\",\n \"visibility\": \"none\"\n },\n \"paint\": {\n \"line-color\": \"#595959\",\n \"line-width\": {\n \"base\": 1.2,\n \"stops\": [\n [4, 1.5],\n [14, 2.5],\n [17, 2.5]\n ]\n },\n \"line-dasharray\": [8, 3]\n },\n \"showProperties\": false\n },\n {\n \"id\": \"Boundary line/Admin0/0/Small\",\n \"type\": \"line\",\n \"source\": \"esri\",\n \"source-layer\": \"Boundary line\",\n \"filter\": [\"all\", [\"==\", \"_symbol\", 0], [\"!in\", \"Viz\", 3]],\n \"layout\": {\n \"line-cap\": \"round\",\n \"line-join\": \"round\"\n },\n \"paint\": {\n \"line-color\": \"#595959\"\n },\n \"maxzoom\": 4,\n \"minzoom\": 1,\n \"showProperties\": false\n },\n {\n \"id\": \"Trail or path\",\n \"type\": \"line\",\n \"source\": \"esri\",\n \"source-layer\": \"Trail or path\",\n \"minzoom\": 15,\n \"layout\": {\n \"line-cap\": \"round\",\n \"line-join\": \"round\"\n },\n \"paint\": {\n \"line-width\": 1.6,\n \"line-color\": \"#fd9a94\"\n }\n },\n {\n \"id\": \"Road/Pedestrian\",\n \"type\": \"line\",\n \"source\": \"esri\",\n \"source-layer\": \"Road\",\n \"filter\": [\"all\", [\"==\", \"_symbol\", 9], [\"!in\", \"Viz\", 3]],\n \"minzoom\": 15,\n \"layout\": {\n \"line-cap\": \"round\",\n \"line-join\": \"round\"\n },\n \"paint\": {\n \"line-width\": 1.22,\n \"line-color\": \"#dd7d78\"\n }\n },\n {\n \"id\": \"Railroad\",\n \"type\": \"line\",\n \"source\": \"esri\",\n \"source-layer\": \"Railroad\",\n \"layout\": {\n \"line-join\": \"round\"\n },\n \"paint\": {\n \"line-color\": \"#f3908a\",\n \"line-width\": 1.2\n },\n \"minzoom\": 15\n },\n {\n \"id\": \"Ferry/Rail ferry\",\n \"type\": \"line\",\n \"source\": \"esri\",\n \"source-layer\": \"Ferry\",\n \"filter\": [\"all\", [\"==\", \"_symbol\", 1], [\"!in\", \"Viz\", 3]],\n \"minzoom\": 15,\n \"layout\": {\n \"line-join\": \"round\"\n },\n \"paint\": {\n \"line-color\": \"#a3bfed\",\n \"line-width\": 1.2\n }\n },\n {\n \"id\": \"Road/4WD/1\",\n \"type\": \"line\",\n \"source\": \"esri\",\n \"source-layer\": \"Road\",\n \"filter\": [\"all\", [\"==\", \"_symbol\", 10], [\"!in\", \"Viz\", 3]],\n \"minzoom\": 13,\n \"layout\": {\n \"line-join\": \"round\"\n },\n \"paint\": {\n \"line-width\": {\n \"base\": 1.2,\n \"stops\": [\n [14, 2.22],\n [17, 3.32]\n ]\n },\n \"line-dasharray\": [6, 3],\n \"line-color\": \"#a84f4c\"\n }\n },\n {\n \"id\": \"Road/Service/1\",\n \"type\": \"line\",\n \"source\": \"esri\",\n \"source-layer\": \"Road\",\n \"filter\": [\"all\", [\"==\", \"_symbol\", 8], [\"!in\", \"Viz\", 3]],\n \"minzoom\": 14,\n \"layout\": {\n \"line-cap\": \"round\",\n \"line-join\": \"round\"\n },\n \"paint\": {\n \"line-color\": \"#a84f4c\",\n \"line-width\": {\n \"base\": 1.2,\n \"stops\": [\n [14, 2.22],\n [17, 3.32]\n ]\n }\n }\n },\n {\n \"id\": \"Road/Local/1\",\n \"type\": \"line\",\n \"source\": \"esri\",\n \"source-layer\": \"Road\",\n \"filter\": [\"all\", [\"==\", \"_symbol\", 7], [\"!in\", \"Viz\", 3]],\n \"minzoom\": 13,\n \"layout\": {\n \"line-cap\": \"round\",\n \"line-join\": \"round\"\n },\n \"paint\": {\n \"line-color\": \"#a84f4c\",\n \"line-width\": {\n \"base\": 1.4,\n \"stops\": [\n [13, 2.22],\n [14, 3.58],\n [17, 6.64]\n ]\n }\n }\n },\n {\n \"id\": \"Road/Minor, ramp or traffic circle/1\",\n \"type\": \"line\",\n \"source\": \"esri\",\n \"source-layer\": \"Road\",\n \"filter\": [\"all\", [\"==\", \"_symbol\", 6], [\"!in\", \"Viz\", 3]],\n \"minzoom\": 13,\n \"layout\": {\n \"line-cap\": \"round\",\n \"line-join\": \"round\"\n },\n \"paint\": {\n \"line-color\": \"#a84f4c\",\n \"line-width\": {\n \"base\": 1.2,\n \"stops\": [\n [13, 2.22],\n [15, 3.58],\n [17, 5.87]\n ]\n }\n }\n },\n {\n \"id\": \"Road/Minor/1\",\n \"type\": \"line\",\n \"source\": \"esri\",\n \"source-layer\": \"Road\",\n \"filter\": [\"all\", [\"==\", \"_symbol\", 5], [\"!in\", \"Viz\", 3]],\n \"minzoom\": 12,\n \"layout\": {\n \"line-cap\": \"round\",\n \"line-join\": \"round\"\n },\n \"paint\": {\n \"line-color\": \"#a84f4c\",\n \"line-width\": {\n \"base\": 1.2,\n \"stops\": [\n [12, 2.22],\n [14, 3.58],\n [17, 6.64]\n ]\n }\n }\n },\n {\n \"id\": \"Road/Major, ramp or traffic circle/1\",\n \"type\": \"line\",\n \"source\": \"esri\",\n \"source-layer\": \"Road\",\n \"filter\": [\"all\", [\"==\", \"_symbol\", 4], [\"!in\", \"Viz\", 3]],\n \"minzoom\": 10,\n \"layout\": {\n \"line-cap\": \"round\",\n \"line-join\": \"round\"\n },\n \"paint\": {\n \"line-color\": \"#a84f4c\",\n \"line-width\": {\n \"base\": 1.2,\n \"stops\": [\n [13, 2.22],\n [15, 3.58],\n [17, 5.87]\n ]\n }\n }\n },\n {\n \"id\": \"Road/Major/1\",\n \"type\": \"line\",\n \"source\": \"esri\",\n \"source-layer\": \"Road\",\n \"filter\": [\"all\", [\"==\", \"_symbol\", 3], [\"!in\", \"Viz\", 3]],\n \"minzoom\": 10,\n \"layout\": {\n \"line-cap\": \"round\",\n \"line-join\": \"round\"\n },\n \"paint\": {\n \"line-color\": \"#a84f4c\",\n \"line-width\": {\n \"base\": 1.2,\n \"stops\": [\n [10, 2.22],\n [14, 5.61],\n [17, 10.97]\n ]\n }\n }\n },\n {\n \"id\": \"Road/Freeway Motorway, ramp or traffic circle/1\",\n \"type\": \"line\",\n \"source\": \"esri\",\n \"source-layer\": \"Road\",\n \"filter\": [\"all\", [\"==\", \"_symbol\", 2], [\"!in\", \"Viz\", 3]],\n \"minzoom\": 5,\n \"layout\": {\n \"line-cap\": \"round\",\n \"line-join\": \"round\"\n },\n \"paint\": {\n \"line-color\": \"#a84f4c\",\n \"line-width\": {\n \"base\": 1.2,\n \"stops\": [\n [10, 2.22],\n [14, 3.58],\n [17, 6.64]\n ]\n }\n }\n },\n {\n \"id\": \"Road/Freeway Motorway/1\",\n \"type\": \"line\",\n \"source\": \"esri\",\n \"source-layer\": \"Road\",\n \"filter\": [\"all\", [\"==\", \"_symbol\", 0], [\"!in\", \"Viz\", 3]],\n \"minzoom\": 5,\n \"layout\": {\n \"line-join\": \"round\"\n },\n \"paint\": {\n \"line-color\": \"#a84f4c\",\n \"line-width\": {\n \"base\": 1.2,\n \"stops\": [\n [8, 2.68],\n [14, 5.61],\n [17, 10.97]\n ]\n }\n }\n },\n {\n \"id\": \"Road/4WD/0\",\n \"type\": \"line\",\n \"source\": \"esri\",\n \"source-layer\": \"Road\",\n \"filter\": [\"all\", [\"==\", \"_symbol\", 10], [\"!in\", \"Viz\", 3]],\n \"minzoom\": 13,\n \"layout\": {\n \"line-join\": \"round\"\n },\n \"paint\": {\n \"line-width\": {\n \"base\": 1.2,\n \"stops\": [\n [14, 0.77],\n [17, 1.53]\n ]\n },\n \"line-color\": \"#dd7d78\"\n }\n },\n {\n \"id\": \"Road/Service/0\",\n \"type\": \"line\",\n \"source\": \"esri\",\n \"source-layer\": \"Road\",\n \"filter\": [\"all\", [\"==\", \"_symbol\", 8], [\"!in\", \"Viz\", 3]],\n \"minzoom\": 13,\n \"layout\": {\n \"line-cap\": \"round\",\n \"line-join\": \"round\"\n },\n \"paint\": {\n \"line-width\": {\n \"base\": 1.2,\n \"stops\": [\n [14, 0.77],\n [17, 1.79]\n ]\n },\n \"line-color\": \"#dd7d78\"\n }\n },\n {\n \"id\": \"Road/Local/0\",\n \"type\": \"line\",\n \"source\": \"esri\",\n \"source-layer\": \"Road\",\n \"filter\": [\"all\", [\"==\", \"_symbol\", 7], [\"!in\", \"Viz\", 3]],\n \"minzoom\": 13,\n \"layout\": {\n \"line-cap\": \"round\",\n \"line-join\": \"round\"\n },\n \"paint\": {\n \"line-width\": {\n \"base\": 1.2,\n \"stops\": [\n [13, 1.15],\n [14, 2.05],\n [17, 3.58]\n ]\n },\n \"line-color\": \"#dd7d78\"\n }\n },\n {\n \"id\": \"Road/Minor, ramp or traffic circle/0\",\n \"type\": \"line\",\n \"source\": \"esri\",\n \"source-layer\": \"Road\",\n \"filter\": [\"all\", [\"==\", \"_symbol\", 6], [\"!in\", \"Viz\", 3]],\n \"minzoom\": 13,\n \"layout\": {\n \"line-cap\": \"round\",\n \"line-join\": \"round\"\n },\n \"paint\": {\n \"line-width\": {\n \"base\": 1.2,\n \"stops\": [\n [13, 0.77],\n [14, 2.05],\n [17, 3.58]\n ]\n },\n \"line-color\": \"#dd7d78\"\n }\n },\n {\n \"id\": \"Road/Minor/0\",\n \"type\": \"line\",\n \"source\": \"esri\",\n \"source-layer\": \"Road\",\n \"filter\": [\"all\", [\"==\", \"_symbol\", 5], [\"!in\", \"Viz\", 3]],\n \"minzoom\": 12,\n \"layout\": {\n \"line-cap\": \"round\",\n \"line-join\": \"round\"\n },\n \"paint\": {\n \"line-width\": {\n \"base\": 1.2,\n \"stops\": [\n [12, 0.77],\n [14, 2.05],\n [17, 3.58]\n ]\n },\n \"line-color\": \"#dd7d78\"\n }\n },\n {\n \"id\": \"Road/Major, ramp or traffic circle/0\",\n \"type\": \"line\",\n \"source\": \"esri\",\n \"source-layer\": \"Road\",\n \"filter\": [\"all\", [\"==\", \"_symbol\", 4], [\"!in\", \"Viz\", 3]],\n \"minzoom\": 10,\n \"layout\": {\n \"line-cap\": \"round\",\n \"line-join\": \"round\"\n },\n \"paint\": {\n \"line-width\": {\n \"base\": 1.2,\n \"stops\": [\n [13, 0.77],\n [14, 2.05],\n [17, 3.58]\n ]\n },\n \"line-color\": \"#dd7d78\"\n }\n },\n {\n \"id\": \"Road/Major/0\",\n \"type\": \"line\",\n \"source\": \"esri\",\n \"source-layer\": \"Road\",\n \"filter\": [\"all\", [\"==\", \"_symbol\", 3], [\"!in\", \"Viz\", 3]],\n \"minzoom\": 10,\n \"layout\": {\n \"line-cap\": \"round\",\n \"line-join\": \"round\"\n },\n \"paint\": {\n \"line-width\": {\n \"base\": 1.2,\n \"stops\": [\n [10, 0.77],\n [14, 4.08],\n [17, 7.91]\n ]\n },\n \"line-color\": \"#dd7d78\"\n }\n },\n {\n \"id\": \"Road/Freeway Motorway, ramp or traffic circle/0\",\n \"type\": \"line\",\n \"source\": \"esri\",\n \"source-layer\": \"Road\",\n \"filter\": [\"all\", [\"==\", \"_symbol\", 2], [\"!in\", \"Viz\", 3]],\n \"minzoom\": 5,\n \"layout\": {\n \"line-cap\": \"round\",\n \"line-join\": \"round\"\n },\n \"paint\": {\n \"line-color\": \"#dd7d78\",\n \"line-width\": {\n \"base\": 1.2,\n \"stops\": [\n [10, 0.77],\n [14, 2.05],\n [17, 3.58]\n ]\n }\n }\n },\n {\n \"id\": \"Road/Highway/0\",\n \"type\": \"line\",\n \"source\": \"esri\",\n \"source-layer\": \"Road\",\n \"filter\": [\"all\", [\"==\", \"_symbol\", 1], [\"!in\", \"Viz\", 3]],\n \"minzoom\": 7,\n \"layout\": {\n \"line-join\": \"round\"\n },\n \"paint\": {\n \"line-color\": \"#dd7d78\",\n \"line-width\": {\n \"base\": 1.2,\n \"stops\": [\n [8, 0.77],\n [14, 4.08],\n [17, 7.91]\n ]\n }\n }\n },\n {\n \"id\": \"Road/Freeway Motorway/0\",\n \"type\": \"line\",\n \"source\": \"esri\",\n \"source-layer\": \"Road\",\n \"filter\": [\"all\", [\"==\", \"_symbol\", 0], [\"!in\", \"Viz\", 3]],\n \"minzoom\": 5,\n \"layout\": {\n \"line-join\": \"round\"\n },\n \"paint\": {\n \"line-color\": \"#dd7d78\",\n \"line-width\": {\n \"base\": 1.2,\n \"stops\": [\n [8, 0.77],\n [14, 4.08],\n [17, 7.91]\n ]\n }\n }\n },\n {\n \"id\": \"Road tunnel/4WD/1\",\n \"type\": \"line\",\n \"source\": \"esri\",\n \"source-layer\": \"Road tunnel\",\n \"filter\": [\"all\", [\"==\", \"_symbol\", 10], [\"!in\", \"Viz\", 3]],\n \"minzoom\": 13,\n \"layout\": {\n \"line-join\": \"round\"\n },\n \"paint\": {\n \"line-width\": {\n \"base\": 1.2,\n \"stops\": [\n [14, 2.9],\n [17, 4.33]\n ]\n },\n \"line-dasharray\": [6, 3],\n \"line-opacity\": 0.5,\n \"line-color\": \"#a84f4c\"\n }\n },\n {\n \"id\": \"Road tunnel/Service/1\",\n \"type\": \"line\",\n \"source\": \"esri\",\n \"source-layer\": \"Road tunnel\",\n \"filter\": [\"all\", [\"==\", \"_symbol\", 8], [\"!in\", \"Viz\", 3]],\n \"minzoom\": 13,\n \"layout\": {\n \"line-cap\": \"round\",\n \"line-join\": \"round\"\n },\n \"paint\": {\n \"line-color\": \"#a84f4c\",\n \"line-opacity\": 0.5,\n \"line-width\": {\n \"base\": 1.2,\n \"stops\": [\n [14, 2.9],\n [17, 4.33]\n ]\n }\n }\n },\n {\n \"id\": \"Road tunnel/Local/1\",\n \"type\": \"line\",\n \"source\": \"esri\",\n \"source-layer\": \"Road tunnel\",\n \"filter\": [\"all\", [\"==\", \"_symbol\", 7], [\"!in\", \"Viz\", 3]],\n \"minzoom\": 13,\n \"layout\": {\n \"line-cap\": \"round\",\n \"line-join\": \"round\"\n },\n \"paint\": {\n \"line-color\": \"#a84f4c\",\n \"line-opacity\": 0.5,\n \"line-width\": {\n \"base\": 1.4,\n \"stops\": [\n [13, 2.9],\n [14, 4.67],\n [17, 8.67]\n ]\n }\n }\n },\n {\n \"id\": \"Road tunnel/Minor, ramp or traffic circle/1\",\n \"type\": \"line\",\n \"source\": \"esri\",\n \"source-layer\": \"Road tunnel\",\n \"filter\": [\"all\", [\"==\", \"_symbol\", 6], [\"!in\", \"Viz\", 3]],\n \"minzoom\": 12,\n \"layout\": {\n \"line-cap\": \"round\",\n \"line-join\": \"round\"\n },\n \"paint\": {\n \"line-color\": \"#a84f4c\",\n \"line-opacity\": 0.5,\n \"line-width\": {\n \"base\": 1.2,\n \"stops\": [\n [13, 2.9],\n [15, 4.67],\n [17, 7.67]\n ]\n }\n }\n },\n {\n \"id\": \"Road tunnel/Minor/1\",\n \"type\": \"line\",\n \"source\": \"esri\",\n \"source-layer\": \"Road tunnel\",\n \"filter\": [\"all\", [\"==\", \"_symbol\", 5], [\"!in\", \"Viz\", 3]],\n \"minzoom\": 12,\n \"layout\": {\n \"line-cap\": \"round\",\n \"line-join\": \"round\"\n },\n \"paint\": {\n \"line-color\": \"#a84f4c\",\n \"line-opacity\": 0.5,\n \"line-width\": {\n \"base\": 1.2,\n \"stops\": [\n [12, 2.9],\n [14, 4.67],\n [17, 8.67]\n ]\n }\n }\n },\n {\n \"id\": \"Road tunnel/Major, ramp or traffic circle/1\",\n \"type\": \"line\",\n \"source\": \"esri\",\n \"source-layer\": \"Road tunnel\",\n \"filter\": [\"all\", [\"==\", \"_symbol\", 4], [\"!in\", \"Viz\", 3]],\n \"minzoom\": 13,\n \"layout\": {\n \"line-cap\": \"round\",\n \"line-join\": \"round\"\n },\n \"paint\": {\n \"line-color\": \"#a84f4c\",\n \"line-opacity\": 0.5,\n \"line-width\": {\n \"base\": 1.2,\n \"stops\": [\n [13, 2.9],\n [15, 4.67],\n [17, 7.67]\n ]\n }\n }\n },\n {\n \"id\": \"Road tunnel/Major/1\",\n \"type\": \"line\",\n \"source\": \"esri\",\n \"source-layer\": \"Road tunnel\",\n \"filter\": [\"all\", [\"==\", \"_symbol\", 3], [\"!in\", \"Viz\", 3]],\n \"minzoom\": 10,\n \"layout\": {\n \"line-cap\": \"round\",\n \"line-join\": \"round\"\n },\n \"paint\": {\n \"line-color\": \"#a84f4c\",\n \"line-opacity\": 0.5,\n \"line-width\": {\n \"base\": 1.2,\n \"stops\": [\n [10, 2.9],\n [14, 7.33],\n [17, 14.33]\n ]\n }\n }\n },\n {\n \"id\": \"Road tunnel/Freeway Motorway, ramp or traffic circle/1\",\n \"type\": \"line\",\n \"source\": \"esri\",\n \"source-layer\": \"Road tunnel\",\n \"filter\": [\"all\", [\"==\", \"_symbol\", 2], [\"!in\", \"Viz\", 3]],\n \"minzoom\": 5,\n \"layout\": {\n \"line-cap\": \"round\",\n \"line-join\": \"round\"\n },\n \"paint\": {\n \"line-opacity\": 0.5,\n \"line-color\": \"#a84f4c\",\n \"line-width\": {\n \"base\": 1.2,\n \"stops\": [\n [10, 2.9],\n [14, 4.67],\n [17, 8.67]\n ]\n }\n }\n },\n {\n \"id\": \"Road tunnel/Freeway Motorway/1\",\n \"type\": \"line\",\n \"source\": \"esri\",\n \"source-layer\": \"Road tunnel\",\n \"filter\": [\"all\", [\"==\", \"_symbol\", 0], [\"!in\", \"Viz\", 3]],\n \"minzoom\": 5,\n \"layout\": {\n \"line-join\": \"round\"\n },\n \"paint\": {\n \"line-opacity\": 0.5,\n \"line-color\": \"#a84f4c\",\n \"line-width\": {\n \"base\": 1.2,\n \"stops\": [\n [8, 3.5],\n [14, 7.33],\n [17, 14.33]\n ]\n }\n }\n },\n {\n \"id\": \"Road tunnel/4WD/0\",\n \"type\": \"line\",\n \"source\": \"esri\",\n \"source-layer\": \"Road tunnel\",\n \"filter\": [\"all\", [\"==\", \"_symbol\", 10], [\"!in\", \"Viz\", 3]],\n \"minzoom\": 13,\n \"layout\": {\n \"line-join\": \"round\"\n },\n \"paint\": {\n \"line-opacity\": 0.7,\n \"line-width\": {\n \"base\": 1.2,\n \"stops\": [\n [14, 1],\n [17, 2]\n ]\n },\n \"line-color\": \"#dd7d78\"\n }\n },\n {\n \"id\": \"Road tunnel/Service/0\",\n \"type\": \"line\",\n \"source\": \"esri\",\n \"source-layer\": \"Road tunnel\",\n \"filter\": [\"all\", [\"==\", \"_symbol\", 8], [\"!in\", \"Viz\", 3]],\n \"minzoom\": 13,\n \"layout\": {\n \"line-cap\": \"round\",\n \"line-join\": \"round\"\n },\n \"paint\": {\n \"line-opacity\": 0.7,\n \"line-width\": {\n \"base\": 1.2,\n \"stops\": [\n [14, 1],\n [17, 2.33]\n ]\n },\n \"line-color\": \"#dd7d78\"\n }\n },\n {\n \"id\": \"Road tunnel/Local/0\",\n \"type\": \"line\",\n \"source\": \"esri\",\n \"source-layer\": \"Road tunnel\",\n \"filter\": [\"all\", [\"==\", \"_symbol\", 7], [\"!in\", \"Viz\", 3]],\n \"minzoom\": 13,\n \"layout\": {\n \"line-cap\": \"round\",\n \"line-join\": \"round\"\n },\n \"paint\": {\n \"line-opacity\": 0.7,\n \"line-width\": {\n \"base\": 1.2,\n \"stops\": [\n [13, 1.5],\n [14, 2.67],\n [17, 4.67]\n ]\n },\n \"line-color\": \"#dd7d78\"\n }\n },\n {\n \"id\": \"Road tunnel/Minor, ramp or traffic circle/0\",\n \"type\": \"line\",\n \"source\": \"esri\",\n \"source-layer\": \"Road tunnel\",\n \"filter\": [\"all\", [\"==\", \"_symbol\", 6], [\"!in\", \"Viz\", 3]],\n \"minzoom\": 12,\n \"layout\": {\n \"line-cap\": \"round\",\n \"line-join\": \"round\"\n },\n \"paint\": {\n \"line-opacity\": 0.7,\n \"line-width\": {\n \"base\": 1.2,\n \"stops\": [\n [13, 1],\n [14, 2.67],\n [17, 4.67]\n ]\n },\n \"line-color\": \"#dd7d78\"\n }\n },\n {\n \"id\": \"Road tunnel/Minor/0\",\n \"type\": \"line\",\n \"source\": \"esri\",\n \"source-layer\": \"Road tunnel\",\n \"filter\": [\"all\", [\"==\", \"_symbol\", 5], [\"!in\", \"Viz\", 3]],\n \"minzoom\": 12,\n \"layout\": {\n \"line-cap\": \"round\",\n \"line-join\": \"round\"\n },\n \"paint\": {\n \"line-opacity\": 0.7,\n \"line-width\": {\n \"base\": 1.2,\n \"stops\": [\n [12, 1],\n [14, 2.67],\n [17, 4.67]\n ]\n },\n \"line-color\": \"#dd7d78\"\n }\n },\n {\n \"id\": \"Road tunnel/Major, ramp or traffic circle/0\",\n \"type\": \"line\",\n \"source\": \"esri\",\n \"source-layer\": \"Road tunnel\",\n \"filter\": [\"all\", [\"==\", \"_symbol\", 4], [\"!in\", \"Viz\", 3]],\n \"minzoom\": 13,\n \"layout\": {\n \"line-cap\": \"round\",\n \"line-join\": \"round\"\n },\n \"paint\": {\n \"line-opacity\": 0.7,\n \"line-width\": {\n \"base\": 1.2,\n \"stops\": [\n [13, 1],\n [14, 2.67],\n [17, 4.67]\n ]\n },\n \"line-color\": \"#dd7d78\"\n }\n },\n {\n \"id\": \"Road tunnel/Major/0\",\n \"type\": \"line\",\n \"source\": \"esri\",\n \"source-layer\": \"Road tunnel\",\n \"filter\": [\"all\", [\"==\", \"_symbol\", 3], [\"!in\", \"Viz\", 3]],\n \"minzoom\": 10,\n \"layout\": {\n \"line-cap\": \"round\",\n \"line-join\": \"round\"\n },\n \"paint\": {\n \"line-opacity\": 0.7,\n \"line-width\": {\n \"base\": 1.2,\n \"stops\": [\n [10, 1],\n [14, 5.33],\n [17, 10.33]\n ]\n },\n \"line-color\": \"#dd7d78\"\n }\n },\n {\n \"id\": \"Road tunnel/Freeway Motorway, ramp or traffic circle/0\",\n \"type\": \"line\",\n \"source\": \"esri\",\n \"source-layer\": \"Road tunnel\",\n \"filter\": [\"all\", [\"==\", \"_symbol\", 2], [\"!in\", \"Viz\", 3]],\n \"minzoom\": 13,\n \"layout\": {\n \"line-join\": \"round\",\n \"line-cap\": \"round\"\n },\n \"paint\": {\n \"line-opacity\": 0.7,\n \"line-width\": {\n \"base\": 1.2,\n \"stops\": [\n [10, 1],\n [14, 2.67],\n [17, 4.67]\n ]\n },\n \"line-color\": \"#dd7d78\"\n }\n },\n {\n \"id\": \"Road tunnel/Highway/0\",\n \"type\": \"line\",\n \"source\": \"esri\",\n \"source-layer\": \"Road tunnel\",\n \"filter\": [\"all\", [\"==\", \"_symbol\", 1], [\"!in\", \"Viz\", 3]],\n \"minzoom\": 7,\n \"layout\": {\n \"line-join\": \"round\"\n },\n \"paint\": {\n \"line-opacity\": 0.7,\n \"line-color\": \"#dd7d78\",\n \"line-width\": {\n \"base\": 1.2,\n \"stops\": [\n [8, 1],\n [14, 5.33],\n [17, 10.33]\n ]\n }\n }\n },\n {\n \"id\": \"Road tunnel/Freeway Motorway/0\",\n \"type\": \"line\",\n \"source\": \"esri\",\n \"source-layer\": \"Road tunnel\",\n \"filter\": [\"all\", [\"==\", \"_symbol\", 0], [\"!in\", \"Viz\", 3]],\n \"minzoom\": 8,\n \"layout\": {\n \"line-join\": \"round\"\n },\n \"paint\": {\n \"line-opacity\": 0.7,\n \"line-width\": {\n \"base\": 1.2,\n \"stops\": [\n [8, 1],\n [14, 5.33],\n [17, 10.33]\n ]\n },\n \"line-color\": \"#dd7d78\"\n }\n },\n {\n \"id\": \"Road/label/Rectangle white black (Alt)\",\n \"type\": \"symbol\",\n \"source\": \"esri\",\n \"source-layer\": \"Road/label\",\n \"filter\": [\n \"all\",\n [\n \"in\",\n \"_label_class\",\n 8,\n 10,\n 12,\n 14,\n 16,\n 20,\n 22,\n 24,\n 26,\n 28,\n 30,\n 32,\n 34,\n 36,\n 38,\n 40,\n 42,\n 44,\n 46,\n 48,\n 50,\n 52,\n 54,\n 56,\n 58,\n 60,\n 62,\n 64,\n 66,\n 68,\n 70,\n 72,\n 74\n ],\n [\"!in\", \"Viz\", 3]\n ],\n \"minzoom\": 14,\n \"layout\": {\n \"symbol-placement\": \"line\",\n \"symbol-spacing\": 800,\n \"text-max-angle\": 25,\n \"symbol-avoid-edges\": true,\n \"text-font\": [\"Arial Regular\"],\n \"text-size\": 8.5,\n \"text-max-width\": 8,\n \"text-field\": \"{_name}\",\n \"icon-image\": \"Road/Rectangle white black (Alt)/{_len}\",\n \"icon-rotation-alignment\": \"viewport\",\n \"text-rotation-alignment\": \"viewport\",\n \"text-offset\": [0, 0.2],\n \"text-padding\": 20\n },\n \"paint\": {\n \"text-color\": \"#fedad4\",\n \"text-halo-color\": \"#8d4543\"\n }\n },\n {\n \"id\": \"Road/label/Rectangle white black\",\n \"type\": \"symbol\",\n \"source\": \"esri\",\n \"source-layer\": \"Road/label\",\n \"filter\": [\n \"all\",\n [\n \"in\",\n \"_label_class\",\n 7,\n 9,\n 11,\n 13,\n 15,\n 17,\n 19,\n 21,\n 23,\n 25,\n 27,\n 29,\n 31,\n 33,\n 35,\n 37,\n 39,\n 41,\n 43,\n 45,\n 47,\n 49,\n 51,\n 53,\n 55,\n 57,\n 59,\n 61,\n 63,\n 65,\n 67,\n 69,\n 71,\n 73\n ],\n [\"!in\", \"Viz\", 3]\n ],\n \"minzoom\": 14,\n \"layout\": {\n \"symbol-placement\": \"line\",\n \"symbol-spacing\": 800,\n \"text-max-angle\": 25,\n \"symbol-avoid-edges\": true,\n \"text-font\": [\"Arial Regular\"],\n \"text-size\": 8.5,\n \"text-max-width\": 8,\n \"text-field\": \"{_name}\",\n \"icon-image\": \"Road/Rectangle white black/{_len}\",\n \"icon-rotation-alignment\": \"viewport\",\n \"text-rotation-alignment\": \"viewport\",\n \"text-offset\": [0, 0.2],\n \"text-padding\": 20\n },\n \"paint\": {\n \"text-color\": \"#fedad4\",\n \"text-halo-color\": \"#8d4543\"\n }\n }\n ],\n \"metadata\": {\n \"arcgisStyleUrl\": \"https://www.arcgis.com/sharing/rest/content/items/29f3edfacb6147509f0db16829e7b382/resources/styles/root.json\",\n \"arcgisOriginalItemTitle\": \"GG Light\",\n \"arcgisQuickEditor\": {\n \"land\": \"#ebeae6\",\n \"labelTextColor\": \"#ffffff\",\n \"labelHaloColor\": \"#000000\",\n \"baseColor\": \"#7c838d\",\n \"spriteProcessing\": true,\n \"labelContrast\": 4.5,\n \"labelColorMode\": \"LABELS_MAP_COLORS\",\n \"colorMode\": \"CUSTOM\",\n \"colors\": {\n \"water\": \"#7096d4\",\n \"land\": \"#ebeae6\",\n \"building\": \"#474b52\",\n \"road\": \"#b5b5b5\",\n \"boundaries\": \"#595959\"\n },\n \"road\": \"#b5b5b5\",\n \"water\": \"#7096d4\",\n \"boundaries\": \"#595959\"\n },\n \"arcgisQuickEditorWarning\": true,\n \"arcgisEditorExtents\": [\n {\n \"spatialReference\": {\n \"wkid\": 102100\n },\n \"xmin\": -12652118.493631177,\n \"ymin\": 3410479.680458824,\n \"xmax\": -8349631.04551632,\n \"ymax\": 5543378.517727816\n },\n {\n \"spatialReference\": {\n \"latestWkid\": 3857,\n \"wkid\": 102100\n },\n \"xmin\": -371197.9381234135,\n \"ymin\": 6496985.075827017,\n \"xmax\": 343029.6541730836,\n \"ymax\": 6905464.554982891\n },\n {\n \"spatialReference\": {\n \"latestWkid\": 3857,\n \"wkid\": 102100\n },\n \"xmin\": -8597472.05169507,\n \"ymin\": 4692615.939336582,\n \"xmax\": -8552832.82717651,\n \"ymax\": 4718145.906783841\n },\n {\n \"spatialReference\": {\n \"latestWkid\": 3857,\n \"wkid\": 102100\n },\n \"xmin\": 16831588.19989804,\n \"ymin\": -4011777.2067113556,\n \"xmax\": 16832983.175664283,\n \"ymax\": -4010979.3952286085\n }\n ],\n \"arcgisMinimapVisibility\": true,\n \"arcgisSpriteData\": {\n \"spriteImage\": {\n \"__zone_symbol__loadfalse\": [\n {\n \"type\": \"eventTask\",\n \"state\": \"scheduled\",\n \"source\": \"HTMLImageElement.addEventListener:load\",\n \"zone\": \"angular\",\n \"runCount\": 2\n }\n ]\n },\n \"spriteJson\": {\n \"Water area/Inundated area\": {\n \"x\": 0,\n \"y\": 0,\n \"width\": 64,\n \"height\": 64,\n \"pixelRatio\": 1,\n \"sdf\": false\n },\n \"Water area/Lake or river intermittent\": {\n \"x\": 64,\n \"y\": 0,\n \"width\": 64,\n \"height\": 64,\n \"pixelRatio\": 1,\n \"sdf\": false\n },\n \"Water area/Swamp or marsh\": {\n \"x\": 128,\n \"y\": 0,\n \"width\": 64,\n \"height\": 64,\n \"pixelRatio\": 1,\n \"sdf\": false\n },\n \"Special area of interest/Sand\": {\n \"x\": 0,\n \"y\": 64,\n \"width\": 32,\n \"height\": 32,\n \"pixelRatio\": 1,\n \"sdf\": false\n },\n \"Special area of interest/Groundcover\": {\n \"x\": 32,\n \"y\": 64,\n \"width\": 32,\n \"height\": 32,\n \"pixelRatio\": 1,\n \"sdf\": false\n },\n \"Special area of interest/Rock or gravel\": {\n \"x\": 32,\n \"y\": 64,\n \"width\": 32,\n \"height\": 32,\n \"pixelRatio\": 1,\n \"sdf\": false\n },\n \"Water area/Playa\": {\n \"x\": 32,\n \"y\": 64,\n \"width\": 32,\n \"height\": 32,\n \"pixelRatio\": 1,\n \"sdf\": false\n },\n \"Road/Rectangle white black (Alt)/1\": {\n \"x\": 64,\n \"y\": 64,\n \"width\": 16,\n \"height\": 16,\n \"pixelRatio\": 1,\n \"sdf\": false\n },\n \"Road/Rectangle white black/1\": {\n \"x\": 80,\n \"y\": 64,\n \"width\": 16,\n \"height\": 16,\n \"pixelRatio\": 1,\n \"sdf\": false\n },\n \"Road/Rectangle white black (Alt)/7\": {\n \"x\": 96,\n \"y\": 64,\n \"width\": 38,\n \"height\": 16,\n \"pixelRatio\": 1,\n \"sdf\": false\n },\n \"Road/Rectangle white black/7\": {\n \"x\": 134,\n \"y\": 64,\n \"width\": 38,\n \"height\": 16,\n \"pixelRatio\": 1,\n \"sdf\": false\n },\n \"Road/Rectangle white black (Alt)/6\": {\n \"x\": 0,\n \"y\": 96,\n \"width\": 34,\n \"height\": 16,\n \"pixelRatio\": 1,\n \"sdf\": false\n },\n \"Road/Rectangle white black/6\": {\n \"x\": 34,\n \"y\": 96,\n \"width\": 34,\n \"height\": 16,\n \"pixelRatio\": 1,\n \"sdf\": false\n },\n \"Road/Rectangle white black (Alt)/5\": {\n \"x\": 68,\n \"y\": 96,\n \"width\": 30,\n \"height\": 16,\n \"pixelRatio\": 1,\n \"sdf\": false\n },\n \"Road/Rectangle white black/5\": {\n \"x\": 98,\n \"y\": 96,\n \"width\": 30,\n \"height\": 16,\n \"pixelRatio\": 1,\n \"sdf\": false\n },\n \"Road/Rectangle white black (Alt)/4\": {\n \"x\": 128,\n \"y\": 96,\n \"width\": 26,\n \"height\": 16,\n \"pixelRatio\": 1,\n \"sdf\": false\n },\n \"Road/Rectangle white black/4\": {\n \"x\": 154,\n \"y\": 96,\n \"width\": 26,\n \"height\": 16,\n \"pixelRatio\": 1,\n \"sdf\": false\n },\n \"Road/Rectangle white black (Alt)/3\": {\n \"x\": 0,\n \"y\": 112,\n \"width\": 24,\n \"height\": 16,\n \"pixelRatio\": 1,\n \"sdf\": false\n },\n \"Road/Rectangle white black/3\": {\n \"x\": 24,\n \"y\": 112,\n \"width\": 24,\n \"height\": 16,\n \"pixelRatio\": 1,\n \"sdf\": false\n },\n \"Road/Rectangle white black (Alt)/2\": {\n \"x\": 48,\n \"y\": 112,\n \"width\": 20,\n \"height\": 16,\n \"pixelRatio\": 1,\n \"sdf\": false\n },\n \"Road/Rectangle white black/2\": {\n \"x\": 68,\n \"y\": 112,\n \"width\": 20,\n \"height\": 16,\n \"pixelRatio\": 1,\n \"sdf\": false\n },\n \"Water line/Levee/0\": {\n \"x\": 88,\n \"y\": 112,\n \"width\": 10,\n \"height\": 12,\n \"pixelRatio\": 1,\n \"sdf\": false\n }\n },\n \"spriteImage2x\": {\n \"__zone_symbol__loadfalse\": [\n {\n \"type\": \"eventTask\",\n \"state\": \"scheduled\",\n \"source\": \"HTMLImageElement.addEventListener:load\",\n \"zone\": \"angular\",\n \"runCount\": 2\n }\n ]\n },\n \"spriteJson2x\": {\n \"Water area/Inundated area\": {\n \"x\": 0,\n \"y\": 0,\n \"width\": 128,\n \"height\": 128,\n \"pixelRatio\": 2,\n \"sdf\": false\n },\n \"Water area/Lake or river intermittent\": {\n \"x\": 128,\n \"y\": 0,\n \"width\": 128,\n \"height\": 128,\n \"pixelRatio\": 2,\n \"sdf\": false\n },\n \"Water area/Swamp or marsh\": {\n \"x\": 256,\n \"y\": 0,\n \"width\": 128,\n \"height\": 128,\n \"pixelRatio\": 2,\n \"sdf\": false\n },\n \"Special area of interest/Sand\": {\n \"x\": 0,\n \"y\": 128,\n \"width\": 64,\n \"height\": 64,\n \"pixelRatio\": 2,\n \"sdf\": false\n },\n \"Special area of interest/Groundcover\": {\n \"x\": 64,\n \"y\": 128,\n \"width\": 64,\n \"height\": 64,\n \"pixelRatio\": 2,\n \"sdf\": false\n },\n \"Special area of interest/Rock or gravel\": {\n \"x\": 64,\n \"y\": 128,\n \"width\": 64,\n \"height\": 64,\n \"pixelRatio\": 2,\n \"sdf\": false\n },\n \"Water area/Playa\": {\n \"x\": 64,\n \"y\": 128,\n \"width\": 64,\n \"height\": 64,\n \"pixelRatio\": 2,\n \"sdf\": false\n },\n \"Road/Rectangle white black (Alt)/1\": {\n \"x\": 128,\n \"y\": 128,\n \"width\": 28,\n \"height\": 30,\n \"pixelRatio\": 2,\n \"sdf\": false\n },\n \"Road/Rectangle white black/1\": {\n \"x\": 156,\n \"y\": 128,\n \"width\": 28,\n \"height\": 30,\n \"pixelRatio\": 2,\n \"sdf\": false\n },\n \"Road/Rectangle white black (Alt)/7\": {\n \"x\": 184,\n \"y\": 128,\n \"width\": 74,\n \"height\": 30,\n \"pixelRatio\": 2,\n \"sdf\": false\n },\n \"Road/Rectangle white black/7\": {\n \"x\": 258,\n \"y\": 128,\n \"width\": 74,\n \"height\": 30,\n \"pixelRatio\": 2,\n \"sdf\": false\n },\n \"Road/Rectangle white black (Alt)/6\": {\n \"x\": 0,\n \"y\": 192,\n \"width\": 66,\n \"height\": 30,\n \"pixelRatio\": 2,\n \"sdf\": false\n },\n \"Road/Rectangle white black/6\": {\n \"x\": 66,\n \"y\": 192,\n \"width\": 66,\n \"height\": 30,\n \"pixelRatio\": 2,\n \"sdf\": false\n },\n \"Road/Rectangle white black (Alt)/5\": {\n \"x\": 132,\n \"y\": 192,\n \"width\": 58,\n \"height\": 30,\n \"pixelRatio\": 2,\n \"sdf\": false\n },\n \"Road/Rectangle white black/5\": {\n \"x\": 190,\n \"y\": 192,\n \"width\": 58,\n \"height\": 30,\n \"pixelRatio\": 2,\n \"sdf\": false\n },\n \"Road/Rectangle white black (Alt)/4\": {\n \"x\": 248,\n \"y\": 192,\n \"width\": 50,\n \"height\": 30,\n \"pixelRatio\": 2,\n \"sdf\": false\n },\n \"Road/Rectangle white black/4\": {\n \"x\": 298,\n \"y\": 192,\n \"width\": 50,\n \"height\": 30,\n \"pixelRatio\": 2,\n \"sdf\": false\n },\n \"Road/Rectangle white black (Alt)/3\": {\n \"x\": 0,\n \"y\": 222,\n \"width\": 44,\n \"height\": 30,\n \"pixelRatio\": 2,\n \"sdf\": false\n },\n \"Road/Rectangle white black/3\": {\n \"x\": 44,\n \"y\": 222,\n \"width\": 44,\n \"height\": 30,\n \"pixelRatio\": 2,\n \"sdf\": false\n },\n \"Road/Rectangle white black (Alt)/2\": {\n \"x\": 88,\n \"y\": 222,\n \"width\": 36,\n \"height\": 30,\n \"pixelRatio\": 2,\n \"sdf\": false\n },\n \"Road/Rectangle white black/2\": {\n \"x\": 124,\n \"y\": 222,\n \"width\": 36,\n \"height\": 30,\n \"pixelRatio\": 2,\n \"sdf\": false\n },\n \"Water line/Levee/0\": {\n \"x\": 160,\n \"y\": 222,\n \"width\": 16,\n \"height\": 22,\n \"pixelRatio\": 2,\n \"sdf\": false\n }\n },\n \"spriteList\": [\n {\n \"x\": 128,\n \"y\": 128,\n \"width\": 28,\n \"height\": 30,\n \"pixelRatio\": 2,\n \"sdf\": false,\n \"id\": \"Road/Rectangle white black (Alt)/1\",\n \"centerColor\": {\n \"0\": 115,\n \"1\": 115,\n \"2\": 115,\n \"3\": 255\n },\n \"imageData\": \"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABwAAAAeCAYAAAA/xX6fAAAAAXNSR0IArs4c6QAAAIJJREFUSEtjZKAzYATZV1xcbMzAwHCGlnb//PlTesqUKc/AFpaUlPj+//9/Ey0tZGRk9Ovp6dk8aiHVQnk0SKkWlDCDRoN0NEhJDoHRRENykBHSMBqkhEKIZPnRICU5yAhpGA1SQiFEsvwIC9KcnBwpdnb2pySHEwkaUJr6JOijWCkAHfHgH/Hy6xkAAAAASUVORK5CYII=\",\n \"style\": {\n \"background-image\": \"url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABwAAAAeCAYAAAA/xX6fAAAAAXNSR0IArs4c6QAAAIJJREFUSEtjZKAzYATZV1xcbMzAwHCGlnb//PlTesqUKc/AFpaUlPj+//9/Ey0tZGRk9Ovp6dk8aiHVQnk0SKkWlDCDRoN0NEhJDoHRRENykBHSMBqkhEKIZPnRICU5yAhpGA1SQiFEsvwIC9KcnBwpdnb2pySHEwkaUJr6JOijWCkAHfHgH/Hy6xkAAAAASUVORK5CYII=)\",\n \"background-size\": \"14px 15px\"\n }\n },\n {\n \"x\": 88,\n \"y\": 222,\n \"width\": 36,\n \"height\": 30,\n \"pixelRatio\": 2,\n \"sdf\": false,\n \"id\": \"Road/Rectangle white black (Alt)/2\",\n \"centerColor\": {\n \"0\": 115,\n \"1\": 115,\n \"2\": 115,\n \"3\": 255\n },\n \"imageData\": \"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACQAAAAeCAYAAABE4bxTAAAAAXNSR0IArs4c6QAAAH1JREFUWEftl6EVgDAMRK+qO8AYMFZd54jLWDAG7BDXRwfgZCMuIubMvZ9vUpBsytentbbVWp+V3cxsdpmr934AuFYWAnCa2a1CP1cQIaaoCIkQI8ByOSRCjADL5ZAIMQIsl0MixAiwXA6JECPA8sQOZXilI2J393d+rplmAOgzjh/ko8LTAAAAAElFTkSuQmCC\",\n \"style\": {\n \"background-image\": \"url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACQAAAAeCAYAAABE4bxTAAAAAXNSR0IArs4c6QAAAH1JREFUWEftl6EVgDAMRK+qO8AYMFZd54jLWDAG7BDXRwfgZCMuIubMvZ9vUpBsytentbbVWp+V3cxsdpmr934AuFYWAnCa2a1CP1cQIaaoCIkQI8ByOSRCjADL5ZAIMQIsl0MixAiwXA6JECPA8sQOZXilI2J393d+rplmAOgzjh/ko8LTAAAAAElFTkSuQmCC)\",\n \"background-size\": \"18px 15px\"\n }\n },\n {\n \"x\": 0,\n \"y\": 222,\n \"width\": 44,\n \"height\": 30,\n \"pixelRatio\": 2,\n \"sdf\": false,\n \"id\": \"Road/Rectangle white black (Alt)/3\",\n \"centerColor\": {\n \"0\": 115,\n \"1\": 115,\n \"2\": 115,\n \"3\": 255\n },\n \"imageData\": \"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACwAAAAeCAYAAABXNvynAAAAAXNSR0IArs4c6QAAAH5JREFUWEdjZBhigBHk3pycHCl2dvang9ntvb29YLcOGQf//PlTesqUKc9GHUyrZDUawrQKWZi5oyE8GsJoITCaJEaTxGiSoHUaGA3h0RDGHwKj5TCtU8hoCI+G8Gg5TOs0MBrCoyFMQk0HUlpcXPyfzoFGknUoQ1Uk6RxgxQBVwtgfOnR74AAAAABJRU5ErkJggg==\",\n \"style\": {\n \"background-image\": \"url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACwAAAAeCAYAAABXNvynAAAAAXNSR0IArs4c6QAAAH5JREFUWEdjZBhigBHk3pycHCl2dvang9ntvb29YLcOGQf//PlTesqUKc9GHUyrZDUawrQKWZi5oyE8GsJoITCaJEaTxGiSoHUaGA3h0RDGHwKj5TCtU8hoCI+G8Gg5TOs0MBrCoyFMQk0HUlpcXPyfzoFGknUoQ1Uk6RxgxQBVwtgfOnR74AAAAABJRU5ErkJggg==)\",\n \"background-size\": \"22px 15px\"\n }\n },\n {\n \"x\": 248,\n \"y\": 192,\n \"width\": 50,\n \"height\": 30,\n \"pixelRatio\": 2,\n \"sdf\": false,\n \"id\": \"Road/Rectangle white black (Alt)/4\",\n \"centerColor\": {\n \"0\": 115,\n \"1\": 115,\n \"2\": 115,\n \"3\": 255\n },\n \"imageData\": \"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAeCAYAAABuUU38AAAAAXNSR0IArs4c6QAAAHJJREFUWEftksENgDAMxMjMmSMzg/rpACcZFWT+ZxG7df3kq3VHd99fvmdmykNOKmiRk2qsf7GIRSADPi1IbIy1SKwOGloEEhtjLRKrg4YWgcTGWIvE6qChRSCxMdYisTpoaBFIbIy1SKwOGu4iEP9V7AM6aHAfcyCAfgAAAABJRU5ErkJggg==\",\n \"style\": {\n \"background-image\": \"url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAeCAYAAABuUU38AAAAAXNSR0IArs4c6QAAAHJJREFUWEftksENgDAMxMjMmSMzg/rpACcZFWT+ZxG7df3kq3VHd99fvmdmykNOKmiRk2qsf7GIRSADPi1IbIy1SKwOGloEEhtjLRKrg4YWgcTGWIvE6qChRSCxMdYisTpoaBFIbIy1SKwOGu4iEP9V7AM6aHAfcyCAfgAAAABJRU5ErkJggg==)\",\n \"background-size\": \"25px 15px\"\n }\n },\n {\n \"x\": 132,\n \"y\": 192,\n \"width\": 58,\n \"height\": 30,\n \"pixelRatio\": 2,\n \"sdf\": false,\n \"id\": \"Road/Rectangle white black (Alt)/5\",\n \"centerColor\": {\n \"0\": 115,\n \"1\": 115,\n \"2\": 115,\n \"3\": 255\n },\n \"imageData\": \"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADoAAAAeCAYAAAB9hg0IAAAAAXNSR0IArs4c6QAAAGJJREFUWEftlMERACAIw2Rm5mBmPT++dIBgmIA2ucb45GLnzMzZOW9VhUE7EZZoJ5o7i0QlCm1AdaHgnm9LVKLQBlQXCs4xUl3VhTagulBwrq7qqi60AdWFgnN1j7rdCN7yLLilcB/F3y8LAAAAAElFTkSuQmCC\",\n \"style\": {\n \"background-image\": \"url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADoAAAAeCAYAAAB9hg0IAAAAAXNSR0IArs4c6QAAAGJJREFUWEftlMERACAIw2Rm5mBmPT++dIBgmIA2ucb45GLnzMzZOW9VhUE7EZZoJ5o7i0QlCm1AdaHgnm9LVKLQBlQXCs4xUl3VhTagulBwrq7qqi60AdWFgnN1j7rdCN7yLLilcB/F3y8LAAAAAElFTkSuQmCC)\",\n \"background-size\": \"29px 15px\"\n }\n },\n {\n \"x\": 0,\n \"y\": 192,\n \"width\": 66,\n \"height\": 30,\n \"pixelRatio\": 2,\n \"sdf\": false,\n \"id\": \"Road/Rectangle white black (Alt)/6\",\n \"centerColor\": {\n \"0\": 115,\n \"1\": 115,\n \"2\": 115,\n \"3\": 255\n },\n \"imageData\": \"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEIAAAAeCAYAAACYGMhkAAAAAXNSR0IArs4c6QAAAHBJREFUaEPt2LENgDAMBEB7Zs/hmUFENCCEXMOlSJXq5T8lybBWAnlsVbX9OY/uTkFEhCDOGghCEFcRTYSJMBGPtwTVUA3VUI23JwQjGMEIRjBi8NECS1jCEpawhOUgAVjCEpawHFDhZnnHchDa54/sNvFwH8IvT74AAAAASUVORK5CYII=\",\n \"style\": {\n \"background-image\": \"url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEIAAAAeCAYAAACYGMhkAAAAAXNSR0IArs4c6QAAAHBJREFUaEPt2LENgDAMBEB7Zs/hmUFENCCEXMOlSJXq5T8lybBWAnlsVbX9OY/uTkFEhCDOGghCEFcRTYSJMBGPtwTVUA3VUI23JwQjGMEIRjBi8NECS1jCEpawhOUgAVjCEpawHFDhZnnHchDa54/sNvFwH8IvT74AAAAASUVORK5CYII=)\",\n \"background-size\": \"33px 15px\"\n }\n },\n {\n \"x\": 184,\n \"y\": 128,\n \"width\": 74,\n \"height\": 30,\n \"pixelRatio\": 2,\n \"sdf\": false,\n \"id\": \"Road/Rectangle white black (Alt)/7\",\n \"centerColor\": {\n \"0\": 115,\n \"1\": 115,\n \"2\": 115,\n \"3\": 255\n },\n \"imageData\": \"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEoAAAAeCAYAAACLz4iQAAAAAXNSR0IArs4c6QAAAH1JREFUaEPt0rERwDAMxLB4Zs+hmZPzBkhtqmYF/Xo6Elin2nu/VF8azcwKCp4fFCCdJKigUACzFhUUCmDWooJCAcxaVFAogFmLCgoFMGtRQaEAZi0qKBTArEUFhQKYtaigUACzFhUUCmDWooJCAcxaVFAogFmL+guF/dXZB7UucB8GV1vKAAAAAElFTkSuQmCC\",\n \"style\": {\n \"background-image\": \"url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEoAAAAeCAYAAACLz4iQAAAAAXNSR0IArs4c6QAAAH1JREFUaEPt0rERwDAMxLB4Zs+hmZPzBkhtqmYF/Xo6Elin2nu/VF8azcwKCp4fFCCdJKigUACzFhUUCmDWooJCAcxaVFAogFmLCgoFMGtRQaEAZi0qKBTArEUFhQKYtaigUACzFhUUCmDWooJCAcxaVFAogFmL+guF/dXZB7UucB8GV1vKAAAAAElFTkSuQmCC)\",\n \"background-size\": \"37px 15px\"\n }\n },\n {\n \"x\": 156,\n \"y\": 128,\n \"width\": 28,\n \"height\": 30,\n \"pixelRatio\": 2,\n \"sdf\": false,\n \"id\": \"Road/Rectangle white black/1\",\n \"centerColor\": {\n \"0\": 115,\n \"1\": 115,\n \"2\": 115,\n \"3\": 255\n },\n \"imageData\": \"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABwAAAAeCAYAAAA/xX6fAAAAAXNSR0IArs4c6QAAAIJJREFUSEtjZKAzYATZV1xcbMzAwHCGlnb//PlTesqUKc/AFpaUlPj+//9/Ey0tZGRk9Ovp6dk8aiHVQnk0SKkWlDCDRoN0NEhJDoHRRENykBHSMBqkhEKIZPnRICU5yAhpGA1SQiFEsvwIC9KcnBwpdnb2pySHEwkaUJr6JOijWCkAHfHgH/Hy6xkAAAAASUVORK5CYII=\",\n \"style\": {\n \"background-image\": \"url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABwAAAAeCAYAAAA/xX6fAAAAAXNSR0IArs4c6QAAAIJJREFUSEtjZKAzYATZV1xcbMzAwHCGlnb//PlTesqUKc/AFpaUlPj+//9/Ey0tZGRk9Ovp6dk8aiHVQnk0SKkWlDCDRoN0NEhJDoHRRENykBHSMBqkhEKIZPnRICU5yAhpGA1SQiFEsvwIC9KcnBwpdnb2pySHEwkaUJr6JOijWCkAHfHgH/Hy6xkAAAAASUVORK5CYII=)\",\n \"background-size\": \"14px 15px\"\n }\n },\n {\n \"x\": 124,\n \"y\": 222,\n \"width\": 36,\n \"height\": 30,\n \"pixelRatio\": 2,\n \"sdf\": false,\n \"id\": \"Road/Rectangle white black/2\",\n \"centerColor\": {\n \"0\": 115,\n \"1\": 115,\n \"2\": 115,\n \"3\": 255\n },\n \"imageData\": \"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACQAAAAeCAYAAABE4bxTAAAAAXNSR0IArs4c6QAAAH1JREFUWEftl6EVgDAMRK+qO8AYMFZd54jLWDAG7BDXRwfgZCMuIubMvZ9vUpBsytentbbVWp+V3cxsdpmr934AuFYWAnCa2a1CP1cQIaaoCIkQI8ByOSRCjADL5ZAIMQIsl0MixAiwXA6JECPA8sQOZXilI2J393d+rplmAOgzjh/ko8LTAAAAAElFTkSuQmCC\",\n \"style\": {\n \"background-image\": \"url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACQAAAAeCAYAAABE4bxTAAAAAXNSR0IArs4c6QAAAH1JREFUWEftl6EVgDAMRK+qO8AYMFZd54jLWDAG7BDXRwfgZCMuIubMvZ9vUpBsytentbbVWp+V3cxsdpmr934AuFYWAnCa2a1CP1cQIaaoCIkQI8ByOSRCjADL5ZAIMQIsl0MixAiwXA6JECPA8sQOZXilI2J393d+rplmAOgzjh/ko8LTAAAAAElFTkSuQmCC)\",\n \"background-size\": \"18px 15px\"\n }\n },\n {\n \"x\": 44,\n \"y\": 222,\n \"width\": 44,\n \"height\": 30,\n \"pixelRatio\": 2,\n \"sdf\": false,\n \"id\": \"Road/Rectangle white black/3\",\n \"centerColor\": {\n \"0\": 115,\n \"1\": 115,\n \"2\": 115,\n \"3\": 255\n },\n \"imageData\": \"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACwAAAAeCAYAAABXNvynAAAAAXNSR0IArs4c6QAAAH5JREFUWEdjZBhigBHk3pycHCl2dvang9ntvb29YLcOGQf//PlTesqUKc9GHUyrZDUawrQKWZi5oyE8GsJoITCaJEaTxGiSoHUaGA3h0RDGHwKj5TCtU8hoCI+G8Gg5TOs0MBrCoyFMQk0HUlpcXPyfzoFGknUoQ1Uk6RxgxQBVwtgfOnR74AAAAABJRU5ErkJggg==\",\n \"style\": {\n \"background-image\": \"url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACwAAAAeCAYAAABXNvynAAAAAXNSR0IArs4c6QAAAH5JREFUWEdjZBhigBHk3pycHCl2dvang9ntvb29YLcOGQf//PlTesqUKc9GHUyrZDUawrQKWZi5oyE8GsJoITCaJEaTxGiSoHUaGA3h0RDGHwKj5TCtU8hoCI+G8Gg5TOs0MBrCoyFMQk0HUlpcXPyfzoFGknUoQ1Uk6RxgxQBVwtgfOnR74AAAAABJRU5ErkJggg==)\",\n \"background-size\": \"22px 15px\"\n }\n },\n {\n \"x\": 298,\n \"y\": 192,\n \"width\": 50,\n \"height\": 30,\n \"pixelRatio\": 2,\n \"sdf\": false,\n \"id\": \"Road/Rectangle white black/4\",\n \"centerColor\": {\n \"0\": 115,\n \"1\": 115,\n \"2\": 115,\n \"3\": 255\n },\n \"imageData\": \"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAeCAYAAABuUU38AAAAAXNSR0IArs4c6QAAAHJJREFUWEftksENgDAMxMjMmSMzg/rpACcZFWT+ZxG7df3kq3VHd99fvmdmykNOKmiRk2qsf7GIRSADPi1IbIy1SKwOGloEEhtjLRKrg4YWgcTGWIvE6qChRSCxMdYisTpoaBFIbIy1SKwOGu4iEP9V7AM6aHAfcyCAfgAAAABJRU5ErkJggg==\",\n \"style\": {\n \"background-image\": \"url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAeCAYAAABuUU38AAAAAXNSR0IArs4c6QAAAHJJREFUWEftksENgDAMxMjMmSMzg/rpACcZFWT+ZxG7df3kq3VHd99fvmdmykNOKmiRk2qsf7GIRSADPi1IbIy1SKwOGloEEhtjLRKrg4YWgcTGWIvE6qChRSCxMdYisTpoaBFIbIy1SKwOGu4iEP9V7AM6aHAfcyCAfgAAAABJRU5ErkJggg==)\",\n \"background-size\": \"25px 15px\"\n }\n },\n {\n \"x\": 190,\n \"y\": 192,\n \"width\": 58,\n \"height\": 30,\n \"pixelRatio\": 2,\n \"sdf\": false,\n \"id\": \"Road/Rectangle white black/5\",\n \"centerColor\": {\n \"0\": 115,\n \"1\": 115,\n \"2\": 115,\n \"3\": 255\n },\n \"imageData\": \"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADoAAAAeCAYAAAB9hg0IAAAAAXNSR0IArs4c6QAAAGJJREFUWEftlMERACAIw2Rm5mBmPT++dIBgmIA2ucb45GLnzMzZOW9VhUE7EZZoJ5o7i0QlCm1AdaHgnm9LVKLQBlQXCs4xUl3VhTagulBwrq7qqi60AdWFgnN1j7rdCN7yLLilcB/F3y8LAAAAAElFTkSuQmCC\",\n \"style\": {\n \"background-image\": \"url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADoAAAAeCAYAAAB9hg0IAAAAAXNSR0IArs4c6QAAAGJJREFUWEftlMERACAIw2Rm5mBmPT++dIBgmIA2ucb45GLnzMzZOW9VhUE7EZZoJ5o7i0QlCm1AdaHgnm9LVKLQBlQXCs4xUl3VhTagulBwrq7qqi60AdWFgnN1j7rdCN7yLLilcB/F3y8LAAAAAElFTkSuQmCC)\",\n \"background-size\": \"29px 15px\"\n }\n },\n {\n \"x\": 66,\n \"y\": 192,\n \"width\": 66,\n \"height\": 30,\n \"pixelRatio\": 2,\n \"sdf\": false,\n \"id\": \"Road/Rectangle white black/6\",\n \"centerColor\": {\n \"0\": 115,\n \"1\": 115,\n \"2\": 115,\n \"3\": 255\n },\n \"imageData\": \"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEIAAAAeCAYAAACYGMhkAAAAAXNSR0IArs4c6QAAAHBJREFUaEPt2LENgDAMBEB7Zs/hmUFENCCEXMOlSJXq5T8lybBWAnlsVbX9OY/uTkFEhCDOGghCEFcRTYSJMBGPtwTVUA3VUI23JwQjGMEIRjBi8NECS1jCEpawhOUgAVjCEpawHFDhZnnHchDa54/sNvFwH8IvT74AAAAASUVORK5CYII=\",\n \"style\": {\n \"background-image\": \"url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEIAAAAeCAYAAACYGMhkAAAAAXNSR0IArs4c6QAAAHBJREFUaEPt2LENgDAMBEB7Zs/hmUFENCCEXMOlSJXq5T8lybBWAnlsVbX9OY/uTkFEhCDOGghCEFcRTYSJMBGPtwTVUA3VUI23JwQjGMEIRjBi8NECS1jCEpawhOUgAVjCEpawHFDhZnnHchDa54/sNvFwH8IvT74AAAAASUVORK5CYII=)\",\n \"background-size\": \"33px 15px\"\n }\n },\n {\n \"x\": 258,\n \"y\": 128,\n \"width\": 74,\n \"height\": 30,\n \"pixelRatio\": 2,\n \"sdf\": false,\n \"id\": \"Road/Rectangle white black/7\",\n \"centerColor\": {\n \"0\": 115,\n \"1\": 115,\n \"2\": 115,\n \"3\": 255\n },\n \"imageData\": \"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEoAAAAeCAYAAACLz4iQAAAAAXNSR0IArs4c6QAAAIJJREFUaEPt1bERgCAABEGpmTqoWYfEeIk544uWR8bTRwJjV3POl+pLo7XWCAoOPyhA2klQQaEAZi0qKBQ4yHr1AKurB0i9eogUVFAHApj2jwoKBTBrUUGhAGYtKigUwKxFBYUCmLWooFAAsxYVFApg1qKCQgHMWlRQKIDZvyjsr84+Z9Jud34cvyIAAAAASUVORK5CYII=\",\n \"style\": {\n \"background-image\": \"url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEoAAAAeCAYAAACLz4iQAAAAAXNSR0IArs4c6QAAAIJJREFUaEPt1bERgCAABEGpmTqoWYfEeIk544uWR8bTRwJjV3POl+pLo7XWCAoOPyhA2klQQaEAZi0qKBQ4yHr1AKurB0i9eogUVFAHApj2jwoKBTBrUUGhAGYtKigUwKxFBYUCmLWooFAAsxYVFApg1qKCQgHMWlRQKIDZvyjsr84+Z9Jud34cvyIAAAAASUVORK5CYII=)\",\n \"background-size\": \"37px 15px\"\n }\n },\n {\n \"x\": 64,\n \"y\": 128,\n \"width\": 64,\n \"height\": 64,\n \"pixelRatio\": 2,\n \"sdf\": false,\n \"id\": \"Special area of interest/Groundcover\",\n \"centerColor\": {\n \"0\": 0,\n \"1\": 0,\n \"2\": 0,\n \"3\": 0\n },\n \"imageData\": \"data:image/png;base64,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\",\n \"style\": {\n \"background-image\": \"url(data:image/png;base64,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)\",\n \"background-size\": \"32px 32px\"\n }\n },\n {\n \"x\": 64,\n \"y\": 128,\n \"width\": 64,\n \"height\": 64,\n \"pixelRatio\": 2,\n \"sdf\": false,\n \"id\": \"Special area of interest/Rock or gravel\",\n \"centerColor\": {\n \"0\": 0,\n \"1\": 0,\n \"2\": 0,\n \"3\": 0\n },\n \"imageData\": \"data:image/png;base64,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\",\n \"style\": {\n \"background-image\": \"url(data:image/png;base64,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)\",\n \"background-size\": \"32px 32px\"\n }\n },\n {\n \"x\": 0,\n \"y\": 128,\n \"width\": 64,\n \"height\": 64,\n \"pixelRatio\": 2,\n \"sdf\": false,\n \"id\": \"Special area of interest/Sand\",\n \"centerColor\": {\n \"0\": 50,\n \"1\": 51,\n \"2\": 51,\n \"3\": 255\n },\n \"imageData\": \"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAAAXNSR0IArs4c6QAABRhJREFUeF7tm+lSG0EMhBnMaXMZDA8SrmAqxLz/m3CYw+a+UlHxbbEyKmmI/8QDf7bs2dWanh51Szubfmxvv019+FteXpZPNzc3cnx9ff04PLWwsCCfHx4e5Pj2Vru8du7fDykl+W5paUmOt7e3cnx5eamdOz8/X4s7Ekh9MTMzI98sLi7KcTAY1M7gvsS9v7//NGT6BkAxwEN+fX1dTrm6uvp0Jr3r9Tgz1el0ZKjf748l7vT0tMQh7tnZmXzWjB5hgPcPTBwAv3s9WcR6DXlAWOMbGxsyNBwOs9a0FQ+GbG5uyinn5+djYcjq6qrEScUDsLe/Lwx4fn6uTUKr1ZLPj4+Pcnx6egqRYnZ2tjZDes2RtfkeNfGCWyqhVcZSLx0fFUnFA6BlEKSYKXRe62ij0ZBTybZRhsAsGHB3d1ebHOJp5ng5Av9C7tHXwyAYzf9lqkDxAHhrkpkEWfRbX8ca9Rwj16EiMI417f0ejyH4gYuLCzmVnJftA7jRxADQPTwUFWANnZ6efhXs2nV4f7Lt5eVlKC65RdcKXIwRQz2iDLGYmIoHYGd3VxgA8jqbM4Os9SjixAN57TOIx7hVrWnaeD6j2WzKJeQcrTIjOap4ACwfAFIgzoyhsxrJ3HoemYUB9AmIy/cwSTPISigeA/AZrg8oFoBc3SZHoN+oSNTJWTMJQzhaPiMkLR9OWllZqV0y4gOKBYCZRGetDoqFuOXhySEgz0xGnaF1v7m5ORnCb0QZwgRXuYYkWDwAIOJlcywwTiyanVnLVvVH9sZneAxBHWCYVa1yX0u9RnJAcQBYDRFr7a2trckQuk19zfmel9dxyR3kiOvrazlFq0hunwBmUOPoHFE51eIB6B0f17rC3trzdHdra0tOoe6Odoo8ddFd4WjuseLCuFQ8AFYtQFZGb6P1PHJqzVC73ZZJIdvrHGLNmJVb0HXiku2jcc2OUPEAMJNkX42oN+55fOLpzg9Pn2FQdK2j9/gTrSI8CYJ5bk/Q+we98f8OgFz9ZokABPqt63kYZPX4NFA4TdTD8hnMcFS18AMwhLhVDigWgJ8HB+IDcHgnJyee1IfGWcvj7jZTrVJTeD0/78em4gHAB3j1PHU3Ds9DlnErLvFYw9Fus3df4pIjdK9RX1/lgOIB8Lw4a9rq3qLDHuLcB4eJk9P7BKjmGI86O+JyH32djus+G4QZEwvA9s6OqEBUTzVTor253HoeRhGfXWlWPyHahca/8HtS8QCgAnq/HohH156VQ1hzVGvj8hkwA/+S28WuHOs3AGqnqLUXWNfd7CuMdnxggvX0mWoNnxFd05aFhyE4UfYXmj6AgeIAyG2KkkXx4Fo9qObo03tVYFRmvV3femZhBtdpf1L5geIB+HV0JD7A8uK5D0up1ogX3Qnq9QLJ9tazxVyfUXWFiwfA6gpTVYGs7vh4VZk1zj4CGBLdG+Tdj+cR/M5oXLMWKB4AZh7krXeHOC9aBZJ96cpqFcEPEO9ffQY5jLj62aPJgGIA2N3bExWguxvN2hgmENa9OXSYY7Sm0G+XaebBIJgTfW5AXH4n/iQVD8BBtysMwMFF99p4WRnEmTGrl5jbjke/YYbe+ZHrW1LxAHg7RaNVlccI6wkQtcW4dqnn+gy3J1g8AN47uKxh1jw6G+0xWh6euNTzdKi8uJ7P0HuJXQYUB4D39vhI3f3+FnfrfZ++rhm+OpMwgxnT2b7xft+m8fa4lZP0y2DZb49PGgB/AFWursjFdg4fAAAAAElFTkSuQmCC\",\n \"style\": {\n \"background-image\": \"url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAAAXNSR0IArs4c6QAABRhJREFUeF7tm+lSG0EMhBnMaXMZDA8SrmAqxLz/m3CYw+a+UlHxbbEyKmmI/8QDf7bs2dWanh51Szubfmxvv019+FteXpZPNzc3cnx9ff04PLWwsCCfHx4e5Pj2Vru8du7fDykl+W5paUmOt7e3cnx5eamdOz8/X4s7Ekh9MTMzI98sLi7KcTAY1M7gvsS9v7//NGT6BkAxwEN+fX1dTrm6uvp0Jr3r9Tgz1el0ZKjf748l7vT0tMQh7tnZmXzWjB5hgPcPTBwAv3s9WcR6DXlAWOMbGxsyNBwOs9a0FQ+GbG5uyinn5+djYcjq6qrEScUDsLe/Lwx4fn6uTUKr1ZLPj4+Pcnx6egqRYnZ2tjZDes2RtfkeNfGCWyqhVcZSLx0fFUnFA6BlEKSYKXRe62ij0ZBTybZRhsAsGHB3d1ebHOJp5ng5Av9C7tHXwyAYzf9lqkDxAHhrkpkEWfRbX8ca9Rwj16EiMI417f0ejyH4gYuLCzmVnJftA7jRxADQPTwUFWANnZ6efhXs2nV4f7Lt5eVlKC65RdcKXIwRQz2iDLGYmIoHYGd3VxgA8jqbM4Os9SjixAN57TOIx7hVrWnaeD6j2WzKJeQcrTIjOap4ACwfAFIgzoyhsxrJ3HoemYUB9AmIy/cwSTPISigeA/AZrg8oFoBc3SZHoN+oSNTJWTMJQzhaPiMkLR9OWllZqV0y4gOKBYCZRGetDoqFuOXhySEgz0xGnaF1v7m5ORnCb0QZwgRXuYYkWDwAIOJlcywwTiyanVnLVvVH9sZneAxBHWCYVa1yX0u9RnJAcQBYDRFr7a2trckQuk19zfmel9dxyR3kiOvrazlFq0hunwBmUOPoHFE51eIB6B0f17rC3trzdHdra0tOoe6Odoo8ddFd4WjuseLCuFQ8AFYtQFZGb6P1PHJqzVC73ZZJIdvrHGLNmJVb0HXiku2jcc2OUPEAMJNkX42oN+55fOLpzg9Pn2FQdK2j9/gTrSI8CYJ5bk/Q+we98f8OgFz9ZokABPqt63kYZPX4NFA4TdTD8hnMcFS18AMwhLhVDigWgJ8HB+IDcHgnJyee1IfGWcvj7jZTrVJTeD0/78em4gHAB3j1PHU3Ds9DlnErLvFYw9Fus3df4pIjdK9RX1/lgOIB8Lw4a9rq3qLDHuLcB4eJk9P7BKjmGI86O+JyH32djus+G4QZEwvA9s6OqEBUTzVTor253HoeRhGfXWlWPyHahca/8HtS8QCgAnq/HohH156VQ1hzVGvj8hkwA/+S28WuHOs3AGqnqLUXWNfd7CuMdnxggvX0mWoNnxFd05aFhyE4UfYXmj6AgeIAyG2KkkXx4Fo9qObo03tVYFRmvV3femZhBtdpf1L5geIB+HV0JD7A8uK5D0up1ogX3Qnq9QLJ9tazxVyfUXWFiwfA6gpTVYGs7vh4VZk1zj4CGBLdG+Tdj+cR/M5oXLMWKB4AZh7krXeHOC9aBZJ96cpqFcEPEO9ffQY5jLj62aPJgGIA2N3bExWguxvN2hgmENa9OXSYY7Sm0G+XaebBIJgTfW5AXH4n/iQVD8BBtysMwMFF99p4WRnEmTGrl5jbjke/YYbe+ZHrW1LxAHg7RaNVlccI6wkQtcW4dqnn+gy3J1g8AN47uKxh1jw6G+0xWh6euNTzdKi8uJ7P0HuJXQYUB4D39vhI3f3+FnfrfZ++rhm+OpMwgxnT2b7xft+m8fa4lZP0y2DZb49PGgB/AFWursjFdg4fAAAAAElFTkSuQmCC)\",\n \"background-size\": \"32px 32px\"\n }\n },\n {\n \"x\": 0,\n \"y\": 0,\n \"width\": 128,\n \"height\": 128,\n \"pixelRatio\": 2,\n \"sdf\": false,\n \"id\": \"Water area/Inundated area\",\n \"centerColor\": {\n \"0\": 29,\n \"1\": 34,\n \"2\": 36,\n \"3\": 211\n },\n \"imageData\": \"data:image/png;base64,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\",\n \"style\": {\n \"background-image\": \"url(data:image/png;base64,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)\",\n \"background-size\": \"64px 64px\"\n }\n },\n {\n \"x\": 128,\n \"y\": 0,\n \"width\": 128,\n \"height\": 128,\n \"pixelRatio\": 2,\n \"sdf\": false,\n \"id\": \"Water area/Lake or river intermittent\",\n \"centerColor\": {\n \"0\": 46,\n \"1\": 48,\n \"2\": 48,\n \"3\": 255\n },\n \"imageData\": \"data:image/png;base64,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\",\n \"style\": {\n \"background-image\": \"url(data:image/png;base64,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)\",\n \"background-size\": \"64px 64px\"\n }\n },\n {\n \"x\": 64,\n \"y\": 128,\n \"width\": 64,\n \"height\": 64,\n \"pixelRatio\": 2,\n \"sdf\": false,\n \"id\": \"Water area/Playa\",\n \"centerColor\": {\n \"0\": 0,\n \"1\": 0,\n \"2\": 0,\n \"3\": 0\n },\n \"imageData\": \"data:image/png;base64,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\",\n \"style\": {\n \"background-image\": \"url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAAAXNSR0IArs4c6QAACnFJREFUeF7tW2lsG1sV9p2x09jpFugLfVTwCoRFAQrC6JU0iTNz7xghxCoQq0CIVUJsYl+E2Pf1ISRAYt9B7Lvw3PHESRsKBEGBsBXoewXKUrUlLcR27Bk4n+eEybzYYxp+Me/+yPHMvXPsfOfMved891yRi5plWaP00TTNN5Nst9tvILm4uPi3aIggadv2E0iGYfg1kr7vX2Id28np6elb0f3S7t1vxHPd7ptIep53Y1yvlPKRdB0Ewdcjvc1Bei3Lui9+b6HwVJKXLlx4NsmVlZUNktPT00WSu0qlh0Kf1p8nOTU1lSe5urraIYl/ilrmARiENvVNTk7uInnd4cPfI9kKw0eTXNL61/Fnedzp06dbaTqpv1wul0iOj4//gWS3250mWa/XfzWMXsuyYFHf92FRblLKQ7CwYUBPq9mcwu9dWrop8oSRLR6Q9mP/bwFQSr2b/nmt9fPSQBimXyn1SxoXBMErIkt+cZjn+o2xLGs/9Zn5/J/hIZ3O3SKLn9mJXqXUl+ABmQfAtu17RZb6SRxRVa2+HJbsdI5H/QvDIG7b9jyNC8Pw55Glzsefs2376bCoaeK+67qwRFqzbftRkV6M53eeZ/uxsbF30v1ms4lVht/1fnrnlDoCD8g8AP0Qsm37mUA8n18D4rXaJ+NjZ2dn70jXIyMjB0h6nvf9NCtSv63Ua0gaudyfSGqtPxB/bmZm5rZ0XSgULkSWHhgPbMYZpdINkQe8hOTx48ehn5uU8uH0+fz5898leerUqX/AA24BAMZAIIR10ff9gYgzYDxH5MLwYbCk616fANOk6+npaehdXl5eH8ZDlFI/o3FBLofVo671q+LPTU1NQV+xWAxJcuTXT/eRI0fGqO+aiQlEnhvttk2y0Wj8lD0g2wBIKRHbC8N4S2RJvINDNFi4XC4DwKQlHMd5G90Phbg79NZqDxxCJ+Uad6VxZ8+exTqfjCiV4/wAeoT4cqQXOUZa44hzZWXln/GxIvMAHDt2bIIQGR0dnSTped6JOEJzUt6HrncZxkNIuq776jS0qb9Sqdy5ZyiBSG5hYaFnuahJKR8cfdwdfe9nhtFrWdb9aFy73f4dyRMnTvw1/pxS6sV0HYYhVi/P894/SK/IPABpqDPipmn2ZnutX5p4pjeJKoV33Nf621F/d5BuKeWzIg9BNqi1fmt8PL+ze/fuvQPdr9friCzTmlLq+dEYrPPJOOOoUreBh+RyW/mAfoozBwDH1sOu25Zl3ZvAM/P5H5LsdjqH4Qm+j/z+ahvnDIZpPgOWdN3y1eqKP6eU+giuDQMeerNIMLMAxCy5SMg019exHidj6n5W4Mk0OStLKREhCiE+TPLSpUszJFdWVv6eYlHEGZOTk2B8kvGAlFJCr2G8PvKQY8N4yPVK3ZrGFZrN9hYPyDwAHGMfPHgQLKrneV+IEEXMzU0p9Ur63M7lvkpyUetTg5BnsjWfzyPidF0XnkDTBf2xLAvZpCgUXkZy7cKF1w7jIVLKO9G4MAzhUfV6/ePx3zGr1F3oelcuB/5Ba40skb+Xx27OAZkFgPl13/cxi6c15TiIwTth+B6SC1rXt0N+SevfRPe3eFBSP88dxWLxgzBPt/tkkr7vb2GS5ubmrqX7i4uL59J+I/XPKzVH0hQCOclNZ86AqeK5ZDNSzTwAqlr9KCFzZW3tOSRPnjyJGHqbJXKgJWO0+RVYstOpRpb0h7FYvzHMEI0Wi+Dz20GAVWXR8360E738f4vMA9APRSnlC9FnGHiXPNfF6pDWbNtG/l+v11ejsew5WNeV49QiD0Hs7/v+d9J0Uj9zkEtLS8gCucX2DTAXdcIQuUBybtrmO7AA9OUEMw+AZVn36DmAAb7A8zwvjiLzBPkwPBhZ/FvDWJKzwE6no2l8o9H4xRaLVqtPouuw3Ub2l+QRkt/By/e1hw49DZ61sfG5yLN4FUG2qqrVT0X974j6ser19YDMAFAulwuExNjYGLK4RqPB6/dAgzqO86JowD1Juq77xPgDnM+PjY0h/240Gr8fxkNiO1I/3s6zLMsCc7W+vg4mKLZq9VMPIzuOg52jjSDAvsCC54G3EJkHIJZVoeJDuy44up02pdTjoSOKxLTrDss2D/xqZoVFLoecwnXd9+3ktxIrzGllNgHobdMhK4OFkkzOvFKo2MgLgSxNuy4ivLTGr9aePXswByT1xvYNLkNvrQb9QzTEE73NI7QtEaqU8nXRffANnue9fZBOmiAyDwAjui2LW6lUbkcIFgqFx8JSN2dv99H9/fv3PyXqx2yb1qSU94cZhejtSWr9jfgzTMYahrE3siRm77RmWdYDaIwQAtVi9Xod8QY39mgjCMYxjjLGqDObAPD++vLyMvbj+ZWIvWMDQZ9XCnNCnrm5Wg07N7F3E+vwzMwM8vlhOUbbtsELGKYJT9Gu+5iEh4ArNAwDc4zneX9M8w7q5/ilK0SPico8AIxaLKvCrmy300Hlpu/77jDI9htjWdYs9Zn5PN5h7bp7Br1yw34XzyHCML5Jz7RbLaxiscrWoVTFK0W5HC2bAPC7b9s23rVmswnuj3eIyuVyb7YfH0dW2AlD7O0taL2cAjWW2XmlwN4uaI19B26VSgW5RGFkBCx0u9WCx6RZkrPAAwcOgB1OZpXzSqESJC/EeyPPA0+RbPFsED80cwBwvVwavx+jzcEdrq+vIxaPrR4A13Ec7B53u114ULLmN2kB3heI7RuAbWb+nrfqisUiPDMIAtQRpNUyMYM0Ojr6CBrvui7YYW48N4nMA+A4Dio+kpUfbPF9+/YhUBp2t1g5DipMumHY4/y0/koc+f+2mrxSqaA+oFAowKNarRbe7aWlpYtxvVwdHgTBXyIP2VI9nvQ85Tgfonsi8wAkkeFrWymcGDGEAOenXRex/k6bUgpMz79JKLyTWmtwdVfb+LyAGVW0doXAXmCysrWf/v6VolkHYHZ29vaE2sjICJKkZKzNjE8YhtdE/Th3kNa4mnxtbQ2ewHUCzB/sGx//LN3vhiH0JeOGfvo5e8zlctDLqwSvIqVSCWxxq9VC/MLV5H09IDMAMMuaM03sAyRn7X6ISynBDwSmiVpcv1bD7i43rvgUQlwXeUhaPo/VRkqJio92uw2uL1n3L6VEJciGENiDTItfNiPcahXnCDaCALM/n3UStwCg1IMIEfM/nB8qQ3faVLXaOycYhrCY57pWXCdXjhiGgdNdnuf9dpjvVI7zMXieENj5qddqL0joBavt+z7XBDN3uK16YWUdgDTUN/NuIRCjnzt3DmdtVldXUWU1REOSlWSYYucNMCv/D/cNcPYpDAKwwZ7nfWLQb+y7CvBDmQfg6NGjYGVLpRLminq9/uk4ojzbG6aJs0DdTgdneX3fxyzdr3GuMTExgbPFvu/jXCC3zSqvyPOuXL6MU2Npe4Gc5XU6Hewub5MzoO7BMAzsG6R6QJYAABiqWsX6G3a72GFJY1vnlMKZ3BEhnkvyxjNnwBdwNRZbclSId9H9ixcvPo5kWqUoZ3eGYeBEq+u6XKWOyHTzew2jV0tcq3GV+MAqdatahYcS6ZX0gEwC8C9qksFEHMJ2VQAAAABJRU5ErkJggg==)\",\n \"background-size\": \"32px 32px\"\n }\n },\n {\n \"x\": 256,\n \"y\": 0,\n \"width\": 128,\n \"height\": 128,\n \"pixelRatio\": 2,\n \"sdf\": false,\n \"id\": \"Water area/Swamp or marsh\",\n \"centerColor\": {\n \"0\": 77,\n \"1\": 79,\n \"2\": 79,\n \"3\": 181\n },\n \"imageData\": \"data:image/png;base64,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\",\n \"style\": {\n \"background-image\": \"url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIAAAACACAYAAADDPmHLAAAAAXNSR0IArs4c6QAADGxJREFUeF7tXWtsHFcVnteu13WcQNsYnKhAcYvAvGVUNQoqRmni2DtzZ4UQAgFtobwfQogf0Kq8JJ4CxB+oBAi1EqpA5bUzsxsrJoXlEahAASEkHqItCBqgbgtJXK+9j5mLzuc7qRM53dn1jndm584Pf571nTv3O+e7Z2bHc+5Rbdv+tKIoiuM4HyNktu0Quo5jEiqKotKP2dlZnbBWq7XF570C+pufnx9H56p6GWG9Xn9C9L8qOuY9ngD9K4qC46enp/OEU1NTdxF6nvdGwoWFhRcT6rnc5/C54xQF/29jPKur7yI8ceLEWdGfJjDocVw47BBjzyAs+P6U6GdE2AG819fX/3LRebs63ezsrCHsCD+ZpnkteOr6rYSO43yEsMjYzTivFEDGBcAY+yIpwfd9zHzNMF4rZsQHoaBS6VOElXL5jn7MgKNHjz6H+snlchYhV9U9UCLnLTGOY4THjh37Q1fSF43n5uYup1/z+TxmtOd53yJkjKHfer3+BszAQmFa8AW/c2fO2ITje/Z4gv+rMVNKpXdjnM3mD8W4/tPLuMJjDh8+vE+c/0WEgeBPQ6P9Rr3+C8JNkaer01mW9XzRL/hVXfcH4G/b9xO6jnO9sMf7YHcpAEMKAEpQ1f8Jqa1AQUEApWuatp/QcZwvdyXFATe2bfurmFGNxhcIc7kcrn2c86rg2wBqGj5vc/5ZtFPVNxO2Wq2PEuq6/hnC8N5hwLQinz68l3t0efn1dNDeiYmfEDYbDezn83lEwvMRQAogowKwbXtjZijKxjXJ978vZv5rRCT4JmGlUqlFll8CGjLGcI1TNA132YqiPA2K5/y/mPHt9h8JDcN4O/ZVFddeg/O9gjcioKrr+BbhlstfSgCtyEOwbPsbaBwE3xV2gD2CdhuRXNO068BPCiDjAigWi5j5mqbdQNhqtXC3nC8UbkFk8P2vEHqe91hk+SWg4QJj4GMoyksIfd//8+ZhtVotfN8eGRmZFTMe3/e5puE5gqGqV4njfk9YrVZ/ngBakYdgmiaed3DO/4aDcrnnEqwHwY8IC77/PEQAKYCMCyCypGTDobRA+Nh0KMlJUp0tIAXQ2UZD3UIKYKjd25mcFEBnGw11CymAoXZvZ3JSAJ1tNNQtpACG2r2dyUkBdLbRULeQAhhq93YmN0gBXPDuXuehDl2LRPCXAhicrrItgPC/VZVK5Z7B+WBwZ04K/4FFgKQYYFASSAr/OAWAPAL6V/xWRmaM4W1d13XxDt4WWyJC5DYEkgr+UgDb8HCHQ7MtgE0h7jtbRQJWKt2HCFAuHxZ/R8bNzMxMjnDfvn03Enqetxifj+LrOS38Y4sAaTFAXBJIC//YBGBZ1tXCuPNiJt+52di2bR+n/Waz+SbCxcXFRwnDl1TX1tbw7WBpaemfcTkpzn7Twl8KICYVZF4AoV3D99P/9fDD76HPTp06hRxAxhhy8BqKghxEvr7+b8KR0VHkIXiOgwyWfm2WZb2K+tI0DblzdKrNfbdVFePSfB/5Ap7n/bQf504K/0txiS0CSAFsWCBzArAs61liBv2D0DRN5NkrinKaflQqFcz88/cAnCMzSdO0F4oZiPx2z/PuJiwWi3ifvVqtPrSdGbmwsPAyOl7XdeTlB7p+BfaDYJSQc471Cdqq+lvCRdf9XS/nSyr/HYsASTWAFMDWElAty0IGkKqq64S+7yNPXVEUzLhqtYprIk2aKDOCMYZrd0tRcPducN4U/b+T0HXdtxEy2/4VOvX9D2Dma9qHMAPbbaRr67r+bJxP17GSiFcuY+WOpG9J4R8+T5mcnMRKKIHIdDJUNYx4BfhFCqC/kkqdAIqMIQtY4xwzPAgCINf1NcJjrntCmCjSmj0HDx7EjL3iyiuxMkW71cKzfiOXQ3666zgvEBEAOXd+u/1WTHTDQPv66ipy+S4bG0OO4vra2hHCpaWlcO2g/nqsz71dzL+xvn4TnWKkUPhxB/5YgaS+uooZ2wf+WNPIsiw8UQ2zo0O6XPhblQLorwJSJ4D+0n+yN2bbuAcYyedx191oNv8qZgCu7bZt/5JQ07QSIkUQ/Ilw5exZrEiye88e3Hu4joNvAWnb0sI/tucAaTFAXMJKC//YBBBeWsJVqkzTxIoUlUrl14TzjL2cMPy+vcDYUdp/5PRp/Jfwmfv349pfdV2s6ZO2LS38pQBiUlbmBRCTXWW3fbZAbBGgz+OU3cVkASmAmAyblm6lANLiqZjGKQUQk2HT0q0UQFo8FdM4pQBiMmxaupUCSIunYhqnFEBMhk1Lt1IAafFUTOOUAojJsGnpVgogLZ6KaZyZFUCYuNFoNJbJtml546hfOgj/OysFkHUBzDF2DanquOs+0C91paGfMFOIc44qY5VKBe/kZWWzbRsZWaoUQMYFYJom6veFGTvhDAjrz62srPydPqvVasgbSMsWJqi022283RxmH2/i90r6XdM05Aw6joMKquE2OzuLGkP67t3IIbzPdR9JC3caZ7FYnBH88K6l53lhvgdoWJb1fkQAKYCMC6BYKr2DlFAtl79OGCp/fHwcGTye56GyaLebZVmvg8JU9QCO1bTdwCBAFS4qSyQ+37gRDQLU8VM0bSOTiHPkAficIwI9ce4cxler1ZDDF2FDv6xU+jihWy5/YvMxCwsLr6D9XC73FkLHcd67+e8mYziu4rqfjHCu803C2r27du2C/TRNw3kUVR0TuMGbc+RAqiLjiosMKkVkaKmKghpGvshWrlQq4B81Q+vAgQPIALp8YgLX+qrjoP5huJmMoVqaKgWQcQFYlvVhUoLneZ8ntCwLivd9/3uEvdbwDauOHzlyBNXBm80mZuT4+Dgyj1ZWVrbMNVxeXsbnExMTwFqtFq4yFikz6eLZapomaiGrqnpO8FwiDKuHG7nc7bTvOg4qaRaLRWTSGIaBfAbHcb52cZ9p2meM3UbjbbVa9xIuLi4+SGiaJjKWKDdQCiDLAhhA+fi4J9AF6wtOT0/jmjs1NXWXiACopxdGAD23s+Xjw3uE0dHRp9M42u02VkUzDAMrlKytraGGc61Wa/diqLD/8HjTNK+lfnRdv1VENKzHUGTsZkQAKYCMC2Cny8dblmWKazJyAmlJwAuUrmmncE0ul3EXHvWuN+xjbm4OT/by+XxRzHisSMoYQ7ZxvV7Htb5QKEwTasbOlo8vlkpYFc3g/KWEnHNEgnBTVfU3Yqb2dO8RPr8JVBX8wswsZtv3w66Oc72wB2oJn68e7vu+IwyCmybPcfD1wSyVsGBDpVy+oxeHXODcjZtMKYAkCkCWj89o+fjwEiAFkFEByPLxGS8fLwWQcQHI8vEZLx8vBZBxAVz8NU3uZ8sCmX0nMFtuvjRbKYCMK0EKQAog4xbIOH0ZAaQAMm6BjNOXEUAKIOMWyDh9GQGkAAZmgbTXBt6u4RLBf5ARIBEG2K4Xt3F8IvgPTABJKZ++DQdu69Ck8JcC2JYbez84CwJIRfn03l3Y8chU8I8zAqTCAB3d2HuDVPCPTQBpKZ/eu3+f+si08JcCiEkBmRdAWsqnx+R/SoC5WvQ9T+h53p2bz3W+dnKziUyhcAWT8CXdtbW1e+jzpaUlVF+La4stAqTFAHEZNi38YxNAaNiklE8/dOgQqoWPjo7eQMgNAyt2qO02KmxyTcPKIxrnPxMz9rF+iCMp/C/FRQpACqAfOn+yj6SWjw/XPhobG0NtXkXX9yICBMFGNW1NO0N45vHHEQFOnjy50otlksp/xyJAUg0gBbC1BGT5+F6m+VMck7ry8ZZl3YJQKJYn830/XFDwIfq8Wq2iiHPUhRqSYoA++zVyd0nhPzMzg6VnJicncckLVPUqQkNVNy55nBfgd1k+PrJvIzVMXfl4KYBIfo3cKHUCiMysy4ZpKZ/eJa3IzdPCP7bnAGkxQGSPdtkwLfxjE0Bayqd36dfIzdPCXwogsku7a5h5AXRnLtl6UBaILQIMipA8b3cWkALozl5D11oKYOhc2h0hKYDu7DV0raUAhs6l3RGSAujOXkPXWgpg6FzaHSEpgO7sNXStpQCGzqXdEZIC6M5eQ9daCmDoXNodocwKIEzcaGS9fHx3ehme1lIA5nXkTVk+nme8fPwcY9eQEo677gPDM787M7EsC2XjedYFIMvHZ7x8vBRAxgUgy8dnvHy8FEDGBSDLx+dup5tB13FQU7hYLN5IaBjGFKHjOD3V8O18G7ozLRhjt9GZWq3WvYSLi4sPEpqmeRO+BkoBZFsA/wc+Bs6Jl6wd9wAAAABJRU5ErkJggg==)\",\n \"background-size\": \"64px 64px\"\n }\n },\n {\n \"x\": 160,\n \"y\": 222,\n \"width\": 16,\n \"height\": 22,\n \"pixelRatio\": 2,\n \"sdf\": false,\n \"id\": \"Water line/Levee/0\",\n \"centerColor\": {\n \"0\": 0,\n \"1\": 0,\n \"2\": 0,\n \"3\": 0\n },\n \"imageData\": \"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAWCAYAAADJqhx8AAAAAXNSR0IArs4c6QAAAK1JREFUOE9jZKAQMFKon2HUAIbRMGAYtGGgrKa58j/Df2v0ZP6fgWHa/Vs32pDFsSZlJXV1E4b/jKeQvfifgeHtX3ZW1UeXL78naABIgZKaxnwGBoYEmOL/DIw5929dn4ruKpyZSUFLS4Lpz79bDAwMvAwMDFfv3bqhz8DA8JdoA8CuUNcsZ/j/v4PhP6PrvdvX92DL+nizs5aWFtuPP//a7926UYyr3BgtDxgYAKveLhcPM+OgAAAAAElFTkSuQmCC\",\n \"style\": {\n \"background-image\": \"url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAWCAYAAADJqhx8AAAAAXNSR0IArs4c6QAAAK1JREFUOE9jZKAQMFKon2HUAIbRMGAYtGGgrKa58j/Df2v0ZP6fgWHa/Vs32pDFsSZlJXV1E4b/jKeQvfifgeHtX3ZW1UeXL78naABIgZKaxnwGBoYEmOL/DIw5929dn4ruKpyZSUFLS4Lpz79bDAwMvAwMDFfv3bqhz8DA8JdoA8CuUNcsZ/j/v4PhP6PrvdvX92DL+nizs5aWFtuPP//a7926UYyr3BgtDxgYAKveLhcPM+OgAAAAAElFTkSuQmCC)\",\n \"background-size\": \"8px 11px\"\n }\n }\n ]\n }\n }\n}\n","import darkGrayStyle from './custom-maps/darkGray.json';\nimport lightGrayStyle from './custom-maps/lightGray.json';\n// Basemap layers\n// List of basemaps can be found here: https://developers.arcgis.com/documentation/mapping-apis-and-services/maps/services/basemap-layer-service/\n\nexport const mapStyles = {\n Classic: {\n isJson: false,\n url: 'arcgis/navigation',\n beforeId: 'Ferry/Ferry',\n beforeIdLines: 'Water point/Sea or ocean',\n },\n Charcoal: {\n isJson: true,\n url: darkGrayStyle,\n beforeId: 'Water area/Dam or weir',\n beforeIdLines: 'Water area/Dam or weir',\n },\n Dark: {\n isJson: false,\n url: 'arcgis/dark-gray',\n beforeId: 'Railroad/2',\n beforeIdLines: 'Water point/Sea or ocean',\n },\n 'Dark (streets)': {\n isJson: false,\n url: 'arcgis/streets-night',\n beforeId: 'Ferry/Ferry',\n beforeIdLines: 'Ferry/label/Ferry',\n },\n Light: {\n isJson: false,\n url: 'arcgis/light-gray',\n beforeId: 'Railroad/2',\n beforeIdLines: 'Water point/Sea or ocean',\n },\n Platinum: {\n isJson: true,\n url: lightGrayStyle,\n beforeId: 'Water area/Dam or weir',\n beforeIdLines: 'Water area/Dam or weir',\n },\n Satellite: {\n isJson: false,\n url: 'arcgis/imagery',\n beforeId: 'Railroad/casing',\n beforeIdLines: 'Water point/Stream or river',\n },\n Topography: {\n isJson: false,\n url: 'arcgis/topographic',\n beforeId: 'Ferry/Ferry',\n beforeIdLines: 'Tree/Elm',\n },\n};\n\nfunction updateToken(item, mapToken) {\n if (typeof item === 'string' && item.includes('token=')) {\n if (!item.includes(mapToken)) {\n return item + mapToken;\n }\n } else if (Array.isArray(item)) {\n return item.map((subItem) => updateToken(subItem, mapToken));\n } else if (typeof item === 'object' && item !== null) {\n for (const key in item) {\n // eslint-disable-next-line no-param-reassign\n item[key] = updateToken(item[key], mapToken);\n }\n }\n return item;\n}\n\nexport class Maps {\n constructor(styles, mapToken) {\n this.mapStyles = styles;\n this.mapToken = mapToken;\n }\n\n static loadMapStyle(style, mapToken) {\n if (mapStyles[style].isJson) {\n // it's actually a regular js object since it is being imported\n const jsonStyle = mapStyles[style].url;\n\n // find instances of `token=` in jsonStyle and append the correct API token\n // Recursive function to update token in strings\n if (jsonStyle.glyphs) {\n jsonStyle.glyphs = updateToken(jsonStyle.glyphs, mapToken);\n }\n\n if (jsonStyle.sources) {\n jsonStyle.sources = updateToken(jsonStyle.sources, mapToken);\n }\n\n return jsonStyle;\n }\n return `https://basemapstyles-api.arcgis.com/arcgis/rest/services/styles/v2/styles/${\n mapStyles[style].url\n }?type=style&token=${mapToken}&worldview=unitedStatesOfAmerica`;\n }\n\n static getBeforeID(plottype) {\n if (getMaptype(chartOptions) == 'Mapbox') {\n const beforeID =\n MapBoxLayers[chartOptions.x4dMaps.mapboxBasemap.value][\n plotorder[plottype].beforeId\n ];\n const mapLayers = mapRef?.current?.getStyle()?.layers ?? [];\n for (let layer of mapLayers) {\n if (layer.id == beforeID) {\n return beforeID;\n }\n }\n console.log(\n `\\n\\nWarning: Could not find beforeID ${beforeID} in mapbox layers. Please set correct beforeID.\\n\\n`,\n );\n return undefined;\n } else {\n return undefined;\n }\n }\n}\n","import { useControl } from 'react-map-gl/maplibre';\nimport { MapboxOverlay } from '@deck.gl/mapbox';\n\nexport default function DeckGLOverlay(props) {\n const { overlayRef } = props;\n const overlay = useControl(() => new MapboxOverlay(props));\n if (overlayRef) {\n overlayRef.current = overlay;\n overlayRef.current.setProps(props);\n } else {\n overlay.setProps(props);\n }\n return null;\n}\n","/* eslint-disable no-underscore-dangle */\nimport { useCallback, useEffect, useRef, useState } from 'react';\nimport { some } from 'lodash';\nimport './Readout.css';\n\nconst MOUSE_OFFSET = { x: 10, y: 10 };\nconst CIRCLE_RADIUS = 5;\n\n// note about `views` prop:\n// this is only used for the length of the array to match the readout with the correct viewport\nexport default function Readout({ mapContainer, overlayRef, title, views = ['placeholder'] }) {\n const [readoutDivDisplay, setReadoutDivDisplay] = useState('none');\n const [rightClickMenu, setRightClickMenu] = useState({\n isOpen: false,\n readoutChecked: true,\n readoutLatLonChecked: false,\n top: '0px',\n left: '0px',\n });\n\n // position & picking results that drive what we render\n const [position, setPosition] = useState({ x: 0, y: 0, lon: 0, lat: 0 });\n const [pickResults, setPickResults] = useState([]); // results from pickMultipleObjects\n\n // Refs for stable access inside handler\n const rafRef = useRef(null);\n const lastMouseRef = useRef({ x: null, y: null });\n\n const buildGriddedReadout = (lon, lat, displayNum, layers) => {\n if (lon == null || lat == null || !layers) return [];\n const readoutArray = [];\n for (const layer of layers) {\n const { readout, displaynum } = layer.props || {};\n if (\n readout &&\n // if displaynum is empty array or undefined, show on all displays\n (!displaynum || displaynum.includes(displayNum))\n ) {\n for (const i in readout) {\n // added value formatter to allow custom formatting (ie timing/paintball)\n const {\n data,\n readoutFunction,\n readoutOptions,\n } = readout[i];\n\n let value;\n if (typeof readoutFunction === 'function') {\n value = readoutFunction(lat, lon, data, {\n ...readoutOptions,\n });\n } else {\n continue;\n }\n\n if (!readoutArray.includes(value)) {\n readoutArray.push(value);\n }\n }\n }\n }\n readoutArray.sort();\n return readoutArray;\n };\n\n // Single stable mouse handler using raf to throttle\n const handleMouseMove = useCallback(\n (evt) => {\n // schedule a single rAF; if already scheduled, update lastMouseRef and exit\n lastMouseRef.current = evt;\n if (rafRef.current) return;\n\n rafRef.current = requestAnimationFrame(() => {\n rafRef.current = null;\n const event = lastMouseRef.current;\n if (!event) return;\n\n // if right-click menu open, skip updates\n if (rightClickMenu.current?.isOpen) return;\n\n const overlay = overlayRef?.current;\n const deck =\n overlay?._deck || overlay?._deckInstance || overlay?._deckGL || overlay?.deck;\n if (!deck) return;\n\n // canvas rect and mouse in CSS pixels\n const canvas = deck.canvas || deck._canvas;\n if (!canvas) return;\n const rect = canvas.getBoundingClientRect();\n const mouseX = event.clientX - rect.left;\n const mouseY = event.clientY - rect.top;\n\n // Ask Deck for viewports and use viewManager.getViewports if available.\n const { viewManager } = deck;\n let viewports = [];\n if (viewManager?.getViewports) {\n viewports = viewManager.getViewports();\n } else if (deck.getViewports) {\n viewports = deck.getViewports();\n }\n\n if (!viewports || viewports.length === 0) return;\n\n // find the viewport under the mouse. Prefer containsPoint if available.\n const vp = viewports.find((v) =>\n typeof v.containsPoint === 'function'\n ? v.containsPoint([mouseX, mouseY])\n : mouseX >= v.x &&\n mouseX < v.x + v.width &&\n mouseY >= v.y &&\n mouseY < v.y + v.height,\n );\n if (!vp) return;\n\n // compute lon/lat from viewport-local coords\n const localX = mouseX - vp.x;\n const localY = mouseY - vp.y;\n const [lon, lat] = vp.unproject([localX, localY]);\n\n // pick objects only when needed\n let picks = [];\n try {\n // pickMultipleObjects expects pixel coords relative to deck canvas (CSS px)\n // call on overlay (MapboxOverlay) if available, else call deck.pickMultipleObjects\n if (typeof overlay.pickMultipleObjects === 'function') {\n picks = overlay.pickMultipleObjects({ x: mouseX, y: mouseY }) || [];\n } else if (typeof deck.pickMultipleObjects === 'function') {\n picks = deck.pickMultipleObjects({ x: mouseX, y: mouseY }) || [];\n }\n } catch (err) {\n picks = [];\n }\n\n // transform picks into readout strings via pickingFunction\n const pickingArr = [];\n for (const object of picks) {\n const pickingFunction = object?.sourceLayer?.props?.pickingFunction;\n if (typeof pickingFunction === 'function') {\n const { readout } = pickingFunction(object, { lon, lat }) || {};\n // Don't allow duplicates\n if (readout && !some(pickingArr, readout)) {\n pickingArr.push(readout);\n }\n }\n }\n\n // update state once per frame\n setPosition({\n x: localX + MOUSE_OFFSET.x,\n y: localY + MOUSE_OFFSET.y,\n lon,\n lat,\n });\n setPickResults(pickingArr);\n setReadoutDivDisplay('block');\n });\n },\n [overlayRef, rightClickMenu],\n );\n\n const stopMouseMovePropagation = (event) => {\n event.stopPropagation();\n };\n\n useEffect(() => {\n const overlayElement = mapContainer?.current;\n if (!overlayElement) return;\n\n // Right click and hold vs. right click menu logic\n let rightClickTimer = null;\n let rightClickStart = null;\n let rightClickMoved = false;\n const RIGHT_CLICK_HOLD_MS = 250;\n const MOVE_THRESHOLD = 5;\n\n // Open right-click menu only if not a drag/hold\n const rightClickMenuOpen = (event) => {\n const rect = overlayElement.getBoundingClientRect();\n const left = event.clientX - rect.left;\n const top = event.clientY - rect.top;\n setRightClickMenu((prev) => ({\n ...prev,\n isOpen: true,\n top: `${top + MOUSE_OFFSET.y}px`,\n left: `${left + MOUSE_OFFSET.x}px`,\n }));\n event.preventDefault();\n event.stopPropagation();\n };\n\n const onMouseDown = (event) => {\n if (event.button === 2) {\n // right mouse button\n rightClickStart = { x: event.clientX, y: event.clientY };\n rightClickMoved = false;\n rightClickTimer = setTimeout(() => {\n rightClickTimer = null; // timer expired\n }, RIGHT_CLICK_HOLD_MS);\n }\n };\n\n const onMouseMove = (event) => {\n if (rightClickStart) {\n const dx = event.clientX - rightClickStart.x;\n const dy = event.clientY - rightClickStart.y;\n if (Math.sqrt(dx * dx + dy * dy) > MOVE_THRESHOLD) {\n rightClickMoved = true;\n if (rightClickTimer) {\n clearTimeout(rightClickTimer);\n rightClickTimer = null;\n }\n }\n }\n };\n\n const onMouseUp = (event) => {\n if (event.button === 2 && rightClickStart) {\n if (rightClickTimer && !rightClickMoved) {\n // treat as right click (open menu)\n rightClickMenuOpen(event);\n }\n if (rightClickTimer) {\n clearTimeout(rightClickTimer);\n rightClickTimer = null;\n }\n rightClickStart = null;\n rightClickMoved = false;\n }\n };\n\n // Prevent default context menu if you handle it yourself\n const onContextMenu = (event) => {\n event.preventDefault();\n };\n\n const hideReadout = () => {\n setReadoutDivDisplay('none');\n setPickResults([]);\n if (rafRef.current) {\n cancelAnimationFrame(rafRef.current);\n rafRef.current = null;\n }\n };\n\n // Allow checkbox clicks to complete before closing the menu\n const handleOverlayClick = () => {\n setTimeout(() => {\n setRightClickMenu((prev) => ({ ...prev, isOpen: false }));\n }, 100);\n };\n\n // Lightweight document-level pointermove that determines if pointer is over overlay\n // If pointer is over the overlay, forward the event to existing handler.\n // Otherwise hide the readout immediately.\n const documentPointerMove = (evt) => {\n // use client coords\n const x = evt.clientX;\n const y = evt.clientY;\n\n // quick rect test first\n const rect = overlayElement.getBoundingClientRect();\n const inRect = x >= rect.left && x <= rect.right && y >= rect.top && y <= rect.bottom;\n\n if (!inRect) {\n // pointer outside overlay\n hideReadout();\n return;\n }\n\n // More robust check: elementFromPoint (handles overlapping siblings/children)\n const el = document.elementFromPoint(x, y);\n if (el && overlayElement.contains(el)) {\n // Pointer is inside overlay. Let existing move handler schedule the rAF work\n try {\n handleMouseMove(evt);\n } catch (err) {\n console.warn('handleMouseMove failed', err);\n }\n return;\n }\n\n // not inside overlay\n hideReadout();\n };\n\n // overlay-local handlers\n overlayElement.addEventListener('mousedown', onMouseDown, false);\n overlayElement.addEventListener('mousemove', onMouseMove, false);\n overlayElement.addEventListener('mouseup', onMouseUp, false);\n overlayElement.addEventListener('contextmenu', onContextMenu, false);\n overlayElement.addEventListener('click', handleOverlayClick, false);\n overlayElement.addEventListener('mousemove', handleMouseMove, false);\n\n // using pointerleave + mouseleave for broader browser coverage\n overlayElement.addEventListener('pointerleave', hideReadout, false);\n overlayElement.addEventListener('mouseleave', hideReadout, false);\n\n // global listener that runs everywhere and decides if pointer is in overlay\n // capture true so it runs early\n document.addEventListener('pointermove', documentPointerMove, true);\n\n // eslint-disable-next-line consistent-return\n return () => {\n overlayElement.removeEventListener('mousedown', onMouseDown, false);\n overlayElement.removeEventListener('mousemove', onMouseMove, false);\n overlayElement.removeEventListener('mouseup', onMouseUp, false);\n overlayElement.removeEventListener('contextmenu', onContextMenu, false);\n overlayElement.removeEventListener('click', handleOverlayClick);\n overlayElement.removeEventListener('mousemove', handleMouseMove);\n document.removeEventListener('pointermove', documentPointerMove, true);\n\n overlayElement.removeEventListener('pointerleave', hideReadout);\n overlayElement.removeEventListener('mouseleave', hideReadout);\n\n if (rafRef.current) {\n cancelAnimationFrame(rafRef.current);\n rafRef.current = null;\n }\n };\n }, [handleMouseMove, mapContainer, overlayRef]);\n\n // Render the readout. For offsets, match viewport by view.id to views array\n // get latest deck for offsets when rendering\n const overlay = overlayRef?.current;\n const deck = overlay?._deck || overlay?.deck;\n // Without the try catch the readout was causing DESI to crash when switch from simple to mapbox\n // while scrubbing the mouse over the display (to activate the readout)\n let viewports;\n try {\n viewports = deck?.viewManager?.getViewports?.() || deck?.getViewports?.() || [];\n } catch (e) {\n viewports = [];\n }\n // build mapping from view id -> viewport\n const vpById = new Map(viewports.map((v) => [v.id, v]));\n\n const makeReadout = (displayNum) => {\n const { lon, lat } = position;\n if (lon == null || lat == null) return null;\n\n // build gridded readout using current layers from overlay props\n const layers =\n overlayRef?.current?._props?.layers || overlayRef?.current?.deck?.props?.layers || [];\n const gridded = buildGriddedReadout(lon, lat, displayNum, layers);\n\n return (\n <div className=\"x4d-readout\" style={{ display: readoutDivDisplay }}>\n {views.length > 1 && (\n <span\n className=\"x4d-readout-circle\"\n style={{\n top: `${-MOUSE_OFFSET.y - CIRCLE_RADIUS}px`,\n left: `${-MOUSE_OFFSET.x - CIRCLE_RADIUS}px`,\n height: `${CIRCLE_RADIUS * 2}px`,\n width: `${CIRCLE_RADIUS * 2}px`,\n }}\n />\n )}\n {title}\n {title && <hr />}\n <table>\n <tbody>\n {gridded.map((d, i) => (\n <tr key={i}>\n <td>{d}</td>\n </tr>\n ))}\n </tbody>\n </table>\n\n {pickResults.map((item, i) => (\n <div key={i}>\n <div>{item}</div>\n {i < pickResults.length - 1 && <br />}\n </div>\n ))}\n\n {rightClickMenu.readoutLatLonChecked && (\n <>\n <hr />\n <table>\n <tbody>\n <tr>\n <td>{`Lat/Lon: ${lat.toFixed(2)}, ${lon.toFixed(2)}`}</td>\n </tr>\n </tbody>\n </table>\n </>\n )}\n </div>\n );\n };\n\n return (\n <div onMouseMove={stopMouseMovePropagation}>\n {rightClickMenu.isOpen && (\n <div\n id=\"x4d-right-click-menu\"\n style={{\n position: 'absolute',\n top: rightClickMenu.top,\n left: rightClickMenu.left,\n display: 'block',\n minWidth: '150px',\n }}\n >\n {/* right click content (unchanged) */}\n <div className=\"x4d-right-click-menu-div\">\n <label className=\"x4d-right-click-menu-label\" htmlFor=\"x4d_data_readout\">\n <input\n type=\"checkbox\"\n id=\"x4d_data_readout\"\n onChange={() =>\n setRightClickMenu((prev) => ({\n ...prev,\n readoutChecked: !prev.readoutChecked,\n }))\n }\n checked={rightClickMenu.readoutChecked}\n />\n Sample\n </label>\n </div>\n <div className=\"x4d-right-click-menu-div\">\n <label className=\"x4d-right-click-menu-label\" htmlFor=\"x4d_latlon_readout\">\n <input\n type=\"checkbox\"\n id=\"x4d_latlon_readout\"\n onChange={() =>\n setRightClickMenu((prev) => ({\n ...prev,\n readoutLatLonChecked: !prev.readoutLatLonChecked,\n }))\n }\n checked={rightClickMenu.readoutLatLonChecked}\n />\n Lat/Lon Readout\n </label>\n </div>\n </div>\n )}\n\n {!rightClickMenu.isOpen && rightClickMenu.readoutChecked && (\n <>\n {views.map((view, index) => {\n const vp = vpById.get(view.id) || viewports[index] || { x: 0, y: 0 };\n const offsetX = vp.x || 0;\n const offsetY = vp.y || 0;\n return (\n <div\n key={view.id || index}\n style={{\n position: 'absolute',\n top: position.y + offsetY,\n left: position.x + offsetX,\n pointerEvents: 'none',\n }}\n >\n {/* {views.length > 1 && (\n <span\n className=\"x4d-readout-circle\"\n style={{\n top: `${-MOUSE_OFFSET.y - CIRCLE_RADIUS}px`,\n left: `${-MOUSE_OFFSET.x - CIRCLE_RADIUS}px`,\n height: `${CIRCLE_RADIUS * 2}px`,\n width: `${CIRCLE_RADIUS * 2}px`,\n }}\n />\n )} */}\n\n {makeReadout(index)}\n </div>\n );\n })}\n </>\n )}\n </div>\n );\n}\n","import gUtilities from \"../../utilities/graphicsUtilities\";\n\nfunction findNearestIndexFlat(lon, lat, lonlatGrid) {\n if (!Array.isArray(lonlatGrid) || lonlatGrid.length === 0) return -1;\n\n let bestIndex = -1;\n let bestD2 = Infinity;\n for (let i = 0; i < lonlatGrid.length; i++) {\n const p = lonlatGrid[i];\n if (!Array.isArray(p) || p.length < 2) continue;\n const dLon = p[0] - lon;\n const dLat = p[1] - lat;\n const d2 = dLon * dLon + dLat * dLat;\n if (d2 < bestD2) {\n bestD2 = d2;\n bestIndex = i;\n }\n }\n\n return bestIndex;\n}\n\nfunction getStructuredPoint(lonlatGrid, rows, cols, r, c, wrapRows = false) {\n if (!Array.isArray(lonlatGrid) || lonlatGrid.length < rows * cols) return null;\n if (c < 0 || c >= cols) return null;\n\n let row = r;\n if (wrapRows) {\n row %= rows;\n if (row < 0) row += rows;\n }\n\n if (row < 0 || row >= rows) return null;\n return lonlatGrid[row * cols + c];\n}\n\nfunction averagePoints(points) {\n let lonSum = 0;\n let latSum = 0;\n let count = 0;\n\n for (let i = 0; i < points.length; i += 1) {\n const p = points[i];\n if (!Array.isArray(p) || p.length < 2) continue;\n const lon = p[0];\n const lat = p[1];\n if (!Number.isFinite(lon) || !Number.isFinite(lat)) continue;\n lonSum += lon;\n latSum += lat;\n count += 1;\n }\n\n if (count === 0) return null;\n return [lonSum / count, latSum / count];\n}\n\nfunction pointInTriangle(px, py, a, b, c) {\n const v0x = c[0] - a[0];\n const v0y = c[1] - a[1];\n const v1x = b[0] - a[0];\n const v1y = b[1] - a[1];\n const v2x = px - a[0];\n const v2y = py - a[1];\n\n const dot00 = v0x * v0x + v0y * v0y;\n const dot01 = v0x * v1x + v0y * v1y;\n const dot02 = v0x * v2x + v0y * v2y;\n const dot11 = v1x * v1x + v1y * v1y;\n const dot12 = v1x * v2x + v1y * v2y;\n\n const denom = dot00 * dot11 - dot01 * dot01;\n if (Math.abs(denom) < 1e-15) return false;\n\n const invDenom = 1 / denom;\n const u = (dot11 * dot02 - dot01 * dot12) * invDenom;\n const v = (dot00 * dot12 - dot01 * dot02) * invDenom;\n return u >= -1e-9 && v >= -1e-9 && u + v <= 1 + 1e-9;\n}\n\nfunction barycentricInterpolate(px, py, a, b, c, va, vb, vc) {\n const det = (b[1] - c[1]) * (a[0] - c[0]) + (c[0] - b[0]) * (a[1] - c[1]);\n if (Math.abs(det) < 1e-15) return NaN;\n\n const w1 = ((b[1] - c[1]) * (px - c[0]) + (c[0] - b[0]) * (py - c[1])) / det;\n const w2 = ((c[1] - a[1]) * (px - c[0]) + (a[0] - c[0]) * (py - c[1])) / det;\n const w3 = 1 - w1 - w2;\n\n return w1 * va + w2 * vb + w3 * vc;\n}\n\nfunction interpolateCorners(p1, p2, p3, p4, iWeight, iWeight2, jWeight, jWeight2, interpolate) {\n const values = [p3, p1, p4, p2];\n\n if (values.some((v) => Number.isNaN(v) || v == null)) {\n return NaN;\n }\n\n if (interpolate) {\n return (\n p3 * iWeight * jWeight +\n p1 * iWeight * jWeight2 +\n p4 * iWeight2 * jWeight +\n p2 * iWeight2 * jWeight2\n );\n }\n\n const weights = [\n iWeight * jWeight,\n iWeight * jWeight2,\n iWeight2 * jWeight,\n iWeight2 * jWeight2,\n ];\n const maxWeight = Math.max(...weights);\n const maxIndex = weights.indexOf(maxWeight);\n return values[maxIndex];\n}\n\nfunction directionToUV(dir, mag) {\n const rad = (dir * Math.PI) / 180;\n const u = -mag * Math.sin(rad);\n const v = -mag * Math.cos(rad);\n return [u, v];\n}\n\nfunction uvToDirection(u, v) {\n return 180 + (180 / Math.PI) * Math.atan2(u, v);\n}\n\nexport default function readoutFunction(lat,lon,data,options = {}){\n let value;\n if (options.readoutType === 'gridded') value = griddedReadout(lat, lon, data, options);\n else if (options.readoutType === 'spherical') value = sphericalReadout(lat, lon, data, options);\n else if (options.readoutType === 'unstructured') value = unstructuredReadout(lat, lon, data, options);\n\n if ( Number.isNaN(value) )\n value = 'NaN';\n else\n value = gUtilities.roundto(value, options.decimals);\n \n value = `${options.prependText}: ${value}${options.units}`;\n return value\n}\n\nexport function griddedReadout(lat, lon, data, options = {}) {\n const { projection, dataType = 'scalar', interpolate = true } = options;\n if (!projection || !data) return NaN;\n\n const [i, j] = projection.LonLatToij(lon, lat, false, true);\n\n const iFloor = Math.floor(i);\n const iCeiling = Math.ceil(i);\n const jFloor = Math.floor(j);\n const jCeiling = Math.ceil(j);\n\n const iWeight = 1 - (i - iFloor);\n const iWeight2 = 1 - iWeight;\n const jWeight = 1 - (j - jFloor);\n const jWeight2 = 1 - jWeight;\n\n const dims = [projection.lonlatGrid.length, projection.lonlatGrid[0].length];\n const width = dims[1];\n const height = dims[0];\n\n const idx = (ii, jj) => {\n if (ii < 0 || ii >= width || jj < 0 || jj >= height) return NaN;\n return jj * width + ii;\n };\n\n const p1 = data[idx(iFloor, jCeiling)];\n const p2 = data[idx(iCeiling, jCeiling)];\n const p3 = data[idx(iFloor, jFloor)];\n const p4 = data[idx(iCeiling, jFloor)];\n\n if (dataType === 'vector') {\n const [p1u, p1v] = directionToUV(p1, 1);\n const [p2u, p2v] = directionToUV(p2, 1);\n const [p3u, p3v] = directionToUV(p3, 1);\n const [p4u, p4v] = directionToUV(p4, 1);\n\n const uValue = interpolateCorners(\n p1u,\n p2u,\n p3u,\n p4u,\n iWeight,\n iWeight2,\n jWeight,\n jWeight2,\n interpolate,\n );\n const vValue = interpolateCorners(\n p1v,\n p2v,\n p3v,\n p4v,\n iWeight,\n iWeight2,\n jWeight,\n jWeight2,\n interpolate,\n );\n\n return Number.isNaN(uValue) || Number.isNaN(vValue) ? NaN : uvToDirection(uValue, vValue);\n }\n\n return interpolateCorners(p1, p2, p3, p4, iWeight, iWeight2, jWeight, jWeight2, interpolate);\n}\n\nexport function sphericalReadout(lat, lon, data, options = {}) {\n const { lonlatGrid, shape, triangulationMode, interpolate = true } = options;\n if (!data || !lonlatGrid) return NaN;\n\n const dims =\n Array.isArray(shape) && Number.isFinite(shape[0]) && Number.isFinite(shape[1])\n ? [Math.floor(shape[0]), Math.floor(shape[1])]\n : null;\n\n if (!dims || dims[0] < 2 || dims[1] < 2) {\n const idx = findNearestIndexFlat(lon, lat, lonlatGrid);\n return idx >= 0 ? data[idx] : NaN;\n }\n\n const [rows, cols] = dims;\n\n // Cell mode: value is one per center point/cell. Prefer exact cell hit test.\n if (triangulationMode === 'spherical-cells') {\n for (let r = 0; r < rows; r += 1) {\n for (let c = 0; c < cols; c += 1) {\n const center = getStructuredPoint(lonlatGrid, rows, cols, r, c, false);\n const sw = averagePoints([\n center,\n getStructuredPoint(lonlatGrid, rows, cols, r, c - 1, false),\n getStructuredPoint(lonlatGrid, rows, cols, r - 1, c, false),\n getStructuredPoint(lonlatGrid, rows, cols, r - 1, c - 1, false),\n ]);\n const se = averagePoints([\n center,\n getStructuredPoint(lonlatGrid, rows, cols, r, c + 1, false),\n getStructuredPoint(lonlatGrid, rows, cols, r - 1, c, false),\n getStructuredPoint(lonlatGrid, rows, cols, r - 1, c + 1, false),\n ]);\n const ne = averagePoints([\n center,\n getStructuredPoint(lonlatGrid, rows, cols, r, c + 1, false),\n getStructuredPoint(lonlatGrid, rows, cols, r + 1, c, false),\n getStructuredPoint(lonlatGrid, rows, cols, r + 1, c + 1, false),\n ]);\n const nw = averagePoints([\n center,\n getStructuredPoint(lonlatGrid, rows, cols, r, c - 1, false),\n getStructuredPoint(lonlatGrid, rows, cols, r + 1, c, false),\n getStructuredPoint(lonlatGrid, rows, cols, r + 1, c - 1, false),\n ]);\n\n if (!sw || !se || !ne || !nw) continue;\n\n const inside =\n pointInTriangle(lon, lat, sw, se, ne) || pointInTriangle(lon, lat, sw, ne, nw);\n if (inside) {\n const idx = r * cols + c;\n return idx >= 0 && idx < data.length ? data[idx] : NaN;\n }\n }\n }\n\n const fallback = findNearestIndexFlat(lon, lat, lonlatGrid);\n return fallback >= 0 ? data[fallback] : NaN;\n }\n\n // Spherical mode: rows wrap azimuthally; cells are between c and c+1.\n // If interpolation is requested, mimic center-split triangle interpolation.\n for (let r = 0; r < rows; r += 1) {\n const rNext = (r + 1) % rows;\n for (let c = 0; c < cols - 1; c += 1) {\n const i00 = r * cols + c;\n const i10 = i00 + 1;\n const i01 = rNext * cols + c;\n const i11 = i01 + 1;\n\n const p00 = lonlatGrid[i00];\n const p10 = lonlatGrid[i10];\n const p01 = lonlatGrid[i01];\n const p11 = lonlatGrid[i11];\n if (!p00 || !p10 || !p01 || !p11) continue;\n\n const inside =\n pointInTriangle(lon, lat, p00, p10, p11) ||\n pointInTriangle(lon, lat, p00, p11, p01);\n if (!inside) continue;\n\n const v00 = data[i00];\n const v10 = data[i10];\n const v01 = data[i01];\n const v11 = data[i11];\n\n if (!interpolate) {\n const corners = [p00, p10, p11, p01];\n const values = [v00, v10, v11, v01];\n let bestIdx = -1;\n let bestD2 = Infinity;\n for (let k = 0; k < corners.length; k += 1) {\n const dLon = corners[k][0] - lon;\n const dLat = corners[k][1] - lat;\n const d2 = dLon * dLon + dLat * dLat;\n if (d2 < bestD2) {\n bestD2 = d2;\n bestIdx = k;\n }\n }\n return values[bestIdx];\n }\n\n const center = averagePoints([p00, p10, p01, p11]);\n if (!center) return NaN;\n\n let sum = 0;\n let count = 0;\n const cornerValues = [v00, v10, v01, v11];\n for (let k = 0; k < cornerValues.length; k += 1) {\n if (Number.isFinite(cornerValues[k])) {\n sum += cornerValues[k];\n count += 1;\n }\n }\n const vc = count > 0 ? sum / count : NaN;\n if (!Number.isFinite(vc)) return NaN;\n\n const triangles = [\n [p00, center, p10, v00, vc, v10],\n [p10, center, p11, v10, vc, v11],\n [p11, center, p01, v11, vc, v01],\n [p01, center, p00, v01, vc, v00],\n ];\n\n for (let t = 0; t < triangles.length; t += 1) {\n const [a, b, cpt, va, vb, vcTri] = triangles[t];\n if (pointInTriangle(lon, lat, a, b, cpt)) {\n if (!Number.isFinite(va) || !Number.isFinite(vb) || !Number.isFinite(vcTri)) {\n return NaN;\n }\n return barycentricInterpolate(lon, lat, a, b, cpt, va, vb, vcTri);\n }\n }\n\n return vc;\n }\n }\n\n const idx = findNearestIndexFlat(lon, lat, lonlatGrid);\n return idx >= 0 ? data[idx] : NaN;\n}\n\nexport function unstructuredReadout(lat, lon, data, options = {}) {\n const { lonlatGrid } = options;\n if (!data || !lonlatGrid) return NaN;\n\n const idx = findNearestIndexFlat(lon, lat, lonlatGrid);\n return idx >= 0 ? data[idx] : NaN;\n}\n","import { debounce, some } from 'lodash';\nimport { useEffect, useRef, useState } from 'react';\n\n// Legend types\n// 'staticBar', 'staticItems', 'dynamicItems'\n\nexport default function LegendDynamicItems({ mapRef, viewState, overlayRef, options }) {\n const [dynamicLegendItems, setDynamicLegendItems] = useState([]);\n\n // TODO: need to add some logic to allow flexible positioning of the legend\n // const legendPosition = options.position || 'left';\n\n // Debounce for dynamicItems\n const debouncedEffect = useRef(\n debounce(() => {\n if (overlayRef?.current) {\n // eslint-disable-next-line no-underscore-dangle\n const { width, height } = overlayRef.current._deck;\n if (!width || !height) return;\n // Pick all pickable objects (20-50 ms, ouch!)\n const objects = overlayRef.current.pickObjects({ x: 0, y: 0, width, height });\n\n // Load legend items into array\n const arr = [];\n for (const i in objects) {\n const object = objects[i];\n const pickingFunction = object.sourceLayer.props?.pickingFunction;\n if (pickingFunction) {\n const { dynamicLegend } = pickingFunction(object);\n // Don't allow duplicates\n if (dynamicLegend && !some(arr, dynamicLegend)) {\n arr.push(dynamicLegend);\n }\n }\n }\n setDynamicLegendItems(arr);\n }\n }, 300), // Adjust the debounce delay as needed\n ).current;\n\n useEffect(() => {\n debouncedEffect();\n // Cleanup function to cancel the debounce on unmount\n return () => {\n debouncedEffect.cancel();\n };\n }, [mapRef, viewState, overlayRef, debouncedEffect]);\n\n return (\n <>\n <div className=\"dynamic-legend-title\">{options.title}</div>\n {dynamicLegendItems.map((item, index) => (\n <div key={index} className=\"dynamic-legend-items\">\n <div\n className=\"dynamic-legend-items-color\"\n style={{ backgroundColor: item.color }}\n />\n <div>{item.text}</div>\n </div>\n ))}\n </>\n );\n}\n","import gUtilities from '../../utilities/graphicsUtilities';\n\nexport default function LegendStaticItems({ options }) {\n const validTimes = gUtilities.formatValidTime(options);\n if (options.colors.length !== options.labels.length) {\n console.error('Colors and labels must have the same length.');\n // return;\n }\n\n let legendItems = [];\n if (options.layerType === 'temp') {\n legendItems = options.colors.temp.map((color, index) => ({\n label: options.labels.labels[index],\n color,\n }));\n } else if (options.layerType === 'prcp') {\n legendItems = options.colors.prcp.map((color, index) => ({\n label: options.labels.labels[index],\n color,\n }));\n } else {\n legendItems =\n options.colors.map((color, index) => ({\n label: options.labels[index],\n color,\n })) || [];\n }\n\n return (\n <div>\n {options.title && validTimes ? (\n <div className=\"static-legend-title\">\n <div>{options.title}</div>\n <div>{validTimes}</div>\n </div>\n ) : null}\n <div className=\"static-legend-container\">\n {legendItems.map((item, index) => (\n <div key={index} className=\"static-legend-items\">\n {/* Don't want to render the color if showing `Near Normal` */}\n {item.label !== 'Near Normal' ? (\n <div\n className=\"static-legend-items-color\"\n style={{\n backgroundColor: item.color,\n border: '1px solid transparent',\n }}\n />\n ) : (\n <div\n className=\"static-legend-items-color\"\n style={{ backgroundColor: item.color, border: '1px solid #000' }}\n />\n )}\n <div>{item.label}</div>\n </div>\n ))}\n </div>\n </div>\n );\n}\n","import { useId } from 'react';\nimport { scaleLinear, range, format } from 'd3';\nimport {\n getTextDimensions,\n getColors,\n getMaxTextDimensions,\n getTransformProps,\n getTitleProps,\n} from './legendHelperFunctions';\n\nexport default function LegendStaticBar({ options }) {\n // destructuring `options` with default values\n const {\n // required variables\n colors, // array of color strings\n colorLevels, // array of numbers\n colorType, // scaleLinear, scaleThreshold\n // optional variables\n // animationSpeed = 1000, // removed animations for now\n ticks: tickStyle = 'linear', // 'linear', 'byColorLevels'\n orient = 'vertical', // vertical or horizontal\n barLength = 600, // how long is the bar\n thickness = 10, // how thick is the bar\n title = '', // title on legend\n units = '', // units on legend\n // styling options and additions\n containerClassName = 'wizard-default-legend-container',\n containerSx = {},\n titleClassName = 'wizard-default-legend-title',\n titleSx = {},\n titleJustify = 'center', // left, center, right\n // space between the title and the bar, this is a multiplier of the title height/width\n titlePaddingMultiplier = 1.2,\n tickClassName = 'wizard-default-legend-tick',\n tickLength = 5, // length of the tick lines\n tickAngle = 0, // angle of the tick-text values. ticks must be 'byColorLevels' or tickValues must be defined\n tickValues = null, // specific tick values for the colorbar\n tickPadding = 2, // extra padding between ticks and labels\n tickStrokeWidth = 1, // stroke width of the tick lines\n // hide the first and last ticks, will not affect end caps ticks since those are already hidden\n hideOuterTicks = false,\n // set the axis line stroke width\n axisStrokeWidth = 1,\n // font props\n titleFontFamily = 'sans-serif',\n titleFontSize = 12,\n titleFontWeight = 400,\n titleFontColor = 'currentColor',\n tickFontFamily = 'sans-serif',\n tickFontSize = 10,\n tickFontWeight = 400,\n tickFontColor = 'currentColor',\n } = options;\n\n // scaleLinear should always have isLeftCap and isRightCap set to false\n // otherwise, use the options provided\n const isLeftCap = colorType === 'scaleLinear' ? false : options.isLeftCap;\n const isRightCap = colorType === 'scaleLinear' ? false : options.isRightCap;\n\n // we need to generate a unique id for the legend bar gradient\n const gradientId = useId();\n\n // End caps can introduce ticks that are outside the original values\n // This function will prevent those ticks from showing up\n const filterTicks = (domain, ticksToFilter) => {\n const min = domain[0];\n const max = domain[domain.length - 1];\n return ticksToFilter.filter((tick) => tick >= min && tick <= max);\n };\n\n const isHorizontal = orient === 'horizontal';\n const titleRotate = isHorizontal ? 0 : -90;\n\n // do all the tick calculations\n // Grab the color scale\n const colorScale = getColors(colorLevels, colors, colorType);\n\n // Make the fillLegendScale\n const domain = colorScale.domain();\n // If left or right cap, just add another value to the array\n if (isRightCap) domain.push(domain[domain.length - 1] + 1);\n if (isLeftCap) domain.unshift(domain[0] - 1);\n const fillLegendScale = scaleLinear().domain(domain);\n\n // the legendRange determines where the colors are placed along the bar\n const legendRange = range(0, barLength, barLength / (fillLegendScale.domain().length - 1));\n if (legendRange[legendRange.length - 1] !== barLength) {\n legendRange.push(barLength);\n }\n // Vertical should go bottom to top, horizontal from left to right.\n if (orient === 'vertical') {\n legendRange.reverse();\n }\n fillLegendScale.range(legendRange);\n\n // Compute tick values and labels\n let finalTickValues = [];\n let finalTickLabels = [];\n // limit number of ticks based on the bar length\n const maxTicks = barLength * 0.025;\n\n if (tickStyle === 'byColorLevels' && tickValues) {\n // Use provided tick values and labels\n finalTickValues = fillLegendScale.domain();\n finalTickValues = filterTicks(colorScale.domain(), finalTickValues);\n finalTickLabels = tickValues;\n } else if (tickStyle === 'byColorLevels') {\n // Use color levels, but limit number of ticks\n finalTickValues = fillLegendScale.domain();\n finalTickValues = filterTicks(colorScale.domain(), finalTickValues);\n if (finalTickValues.length > maxTicks) {\n // Downsample ticks\n const step = Math.ceil(finalTickValues.length / maxTicks);\n finalTickValues = finalTickValues.filter((_, i) => i % step === 0);\n }\n finalTickLabels = finalTickValues.map((d) => format(',.2~f')(d));\n } else {\n // Default: use scale ticks\n finalTickValues = fillLegendScale.ticks\n ? fillLegendScale.ticks()\n : fillLegendScale.domain();\n finalTickValues = filterTicks(colorScale.domain(), finalTickValues);\n finalTickLabels = finalTickValues.map((d) => format(',.2~f')(d));\n }\n\n // perform some logic to hide outer ticks if specified\n // this will only be applied if isLeftCap or isRightCap is false\n if (hideOuterTicks) {\n if (!isLeftCap) {\n finalTickValues = finalTickValues.slice(1);\n finalTickLabels = finalTickLabels.slice(1);\n }\n if (!isRightCap) {\n finalTickValues = finalTickValues.slice(0, finalTickValues.length - 1);\n finalTickLabels = finalTickLabels.slice(0, finalTickLabels.length - 1);\n }\n }\n\n // don't include the () when no units are provided\n // using .trim() because sometimes we get a space in the empty string\n const trimmedUnits = units.trim();\n const titleText = `${title} ${trimmedUnits ? `(${trimmedUnits})` : ''}`.trim();\n\n const titleDimensions = getTextDimensions(\n titleText,\n `${titleFontWeight} ${titleFontSize}px ${titleFontFamily}`,\n titleRotate,\n );\n\n let titleSize = 0;\n if (titleText.length > 0) {\n titleSize = isHorizontal\n ? titleDimensions.height * titlePaddingMultiplier\n : titleDimensions.width * titlePaddingMultiplier;\n }\n\n const maxTickDimensions = getMaxTextDimensions(\n finalTickLabels,\n `${tickFontWeight} ${tickFontSize}px ${tickFontFamily}`,\n tickAngle,\n );\n\n // we have to adjust the tickPadding based on a negative tickLength\n const adjustedTickPadding = tickLength < 0 ? tickPadding * -1 : tickPadding;\n let tickSize = isHorizontal\n ? maxTickDimensions.height + tickLength + adjustedTickPadding + axisStrokeWidth / 2\n : maxTickDimensions.width + tickLength + adjustedTickPadding + axisStrokeWidth / 2;\n // if ticks are inside the bar, don't add to size (just the axis line)\n if (tickLength < 0) tickSize = axisStrokeWidth / 2;\n\n // The logic below is used to add space for the first and last tick labels.\n // Without this, it's possible for the first and last labels to be cut off\n let labelSizeStart = 0;\n let labelSizeEnd = 0;\n if (finalTickValues[0] === domain[0]) {\n const labelDimensionsStart = getTextDimensions(\n finalTickLabels[0],\n `${tickFontWeight} ${tickFontSize}px ${tickFontFamily}`,\n tickAngle,\n );\n labelSizeStart = isHorizontal ? labelDimensionsStart.width : labelDimensionsStart.height;\n }\n if (finalTickValues[finalTickValues.length - 1] === domain[domain.length - 1]) {\n const labelDimensionsEnd = getTextDimensions(\n finalTickLabels[finalTickLabels.length - 1],\n `${tickFontWeight} ${tickFontSize}px ${tickFontFamily}`,\n tickAngle,\n );\n labelSizeEnd = isHorizontal ? labelDimensionsEnd.width : labelDimensionsEnd.height;\n }\n // divide the label size by 2 when the tick angle is 0 or 90 because the text is centered on the tick\n if (tickAngle === 90 || tickAngle === -90 || tickAngle === 0) {\n labelSizeStart /= 2;\n labelSizeEnd /= 2;\n }\n const svgWidth = isHorizontal\n ? barLength + labelSizeStart + labelSizeEnd\n : thickness + titleSize + tickSize;\n const svgHeight = isHorizontal\n ? thickness + titleSize + tickSize\n : barLength + labelSizeStart + labelSizeEnd;\n\n const titleProps = getTitleProps({\n isHorizontal,\n titleJustify,\n barLength,\n svgWidth,\n svgHeight,\n titleDimensions,\n });\n\n // Compute segment positions\n const stops = fillLegendScale.domain();\n const segments = [];\n for (let i = 0; i < stops.length - 1; i += 1) {\n segments.push({\n start: fillLegendScale(stops[i]),\n end: fillLegendScale(stops[i + 1]),\n color: colorScale(stops[i]),\n });\n }\n\n return (\n <svg\n width={svgWidth}\n height={svgHeight}\n className={containerClassName}\n style={{\n display: 'block',\n ...containerSx,\n }}\n >\n {/* SVG defs for gradient */}\n {colorType === 'scaleLinear' && (\n <defs>\n <linearGradient\n id={gradientId}\n x1=\"0%\"\n y1=\"100%\"\n x2={isHorizontal ? '100%' : '0%'}\n y2={isHorizontal ? '100%' : '0%'}\n >\n {fillLegendScale.domain().map((d, i) => {\n let offset;\n if (isHorizontal) {\n offset = (fillLegendScale(d) / barLength) * 100;\n } else {\n // For vertical, flip the offset so 0% is at the bottom\n offset = 100 - (fillLegendScale(d) / barLength) * 100;\n }\n return <stop key={i} offset={`${offset}%`} stopColor={colorScale(d)} />;\n })}\n </linearGradient>\n </defs>\n )}\n\n {/* adjust position of entire legend based on extra spacing necessary for start/end labels */}\n <g\n transform={`translate(${isHorizontal ? labelSizeStart : 0}, ${isHorizontal ? 0 : labelSizeEnd})`}\n >\n {/* title */}\n <text\n transform={titleProps.transform}\n x={titleProps.x}\n y={titleProps.y}\n textAnchor={titleProps.textAnchor}\n dominantBaseline=\"central\"\n className={titleClassName}\n style={{\n fill: titleFontColor,\n fontFamily: titleFontFamily,\n fontSize: titleFontSize,\n fontWeight: titleFontWeight,\n color: titleFontColor,\n ...titleSx,\n }}\n >\n {titleText}\n </text>\n {/* legend bar */}\n <g\n transform={\n isHorizontal ? `translate(0, ${titleSize})` : `translate(${titleSize}, 0)`\n }\n >\n {/* if scaleLinear, we use a single rect with the gradient */}\n {colorType === 'scaleLinear' ? (\n <rect\n x={0}\n y={0}\n width={isHorizontal ? barLength : thickness}\n height={isHorizontal ? thickness : barLength}\n fill={`url(#${gradientId})`}\n />\n ) : (\n // if scaleThreshold, we use multiple rects for each color segment\n segments.map((seg, i) => (\n <rect\n key={i}\n x={isHorizontal ? seg.start : 0}\n y={isHorizontal ? 0 : seg.end}\n width={isHorizontal ? seg.end - seg.start : thickness}\n height={isHorizontal ? thickness : seg.start - seg.end}\n fill={seg.color}\n />\n ))\n )}\n </g>\n {/* legend ticks */}\n <g\n transform={\n isHorizontal ? `translate(0, ${titleSize})` : `translate(${titleSize}, 0)`\n }\n >\n {/* axis line */}\n <line\n x1={isHorizontal ? 0 : thickness}\n y1={isHorizontal ? thickness : 0}\n x2={isHorizontal ? barLength : thickness}\n y2={isHorizontal ? thickness : barLength}\n stroke={tickFontColor}\n strokeWidth={axisStrokeWidth}\n />\n {finalTickValues.map((tickValue, i) => {\n const pos = fillLegendScale(tickValue);\n const anchorPoint =\n thickness + tickLength + adjustedTickPadding + axisStrokeWidth / 2;\n const transformProps = getTransformProps(\n isHorizontal,\n anchorPoint,\n tickLength,\n tickAngle,\n );\n return (\n <g\n key={tickValue}\n // The offset of axisStrokeWidth is for the axis line of 1px thickness\n transform={\n isHorizontal\n ? `translate(${pos},${(axisStrokeWidth / 2) * (tickLength < 0 ? -1 : 1)})`\n : `translate(${(axisStrokeWidth / 2) * (tickLength < 0 ? -1 : 1)},${pos})`\n }\n >\n <line\n x1={isHorizontal ? 0 : thickness}\n y1={isHorizontal ? thickness : 0}\n x2={isHorizontal ? 0 : thickness + tickLength}\n y2={isHorizontal ? thickness + tickLength : 0}\n stroke={tickFontColor}\n strokeWidth={tickStrokeWidth}\n />\n <text\n x={isHorizontal ? 0 : anchorPoint}\n y={isHorizontal ? anchorPoint : 0}\n className={tickClassName}\n transform={transformProps.transform}\n textAnchor={transformProps.textAnchor}\n dominantBaseline={transformProps.dominantBaseline}\n style={{\n fill: tickFontColor,\n fontFamily: tickFontFamily,\n fontSize: `${tickFontSize}px`,\n fontWeight: tickFontWeight,\n color: tickFontColor,\n }}\n >\n {finalTickLabels[i]}\n </text>\n </g>\n );\n })}\n </g>\n </g>\n </svg>\n );\n}\n","/* eslint-disable no-underscore-dangle */\nimport { some } from 'lodash';\nimport LegendDynamicItems from './LegendDynamicItems';\nimport LegendStaticItems from './LegendStaticItems';\nimport LegendStaticBar from './LegendStaticBar';\nimport './Legend.css';\n\n/**\n * This will render legend items based on the layer.props.legend properties. The properties are\n * `type`, `title`, `units`, `position`, `colors`, `labels`, `layerType`, and `range`.\n * @param {import('react').Ref} mapRef - Reference to the MapLibre GL JS map instance\n * @param {object} viewState - view state of the map\n * @param {import('react').Ref} overlayRef - Reference to the Deck.gl overlay layer\n * @returns The requested legend components ('staticBar', 'staticItems', 'dynamicItems')\n */\nfunction Legend({ mapRef, viewState, overlayRef }) {\n const layers = overlayRef?.current?._props?.layers;\n\n const dynamicItems = [];\n const staticItems = [];\n const staticBars = [];\n\n if (layers) {\n for (const layer of layers) {\n const legend = layer.props?.legend;\n if (legend) {\n if (legend.type === 'dynamicItems') {\n if (legend && !some(dynamicItems, legend)) dynamicItems.push(legend);\n }\n if (legend.type === 'staticBar') {\n const { colors, colorLevels, colorType } = layer.props;\n const obj = { colors, colorLevels, colorType, ...legend };\n if (obj && !some(staticBars, obj)) staticBars.push(obj);\n }\n if (legend.type === 'staticItems') {\n staticItems.push(legend);\n }\n }\n }\n }\n\n return (\n <>\n <div id=\"legendContainer\">\n {/* Add static bar legends */}\n {staticBars.map((item, index) => (\n <LegendStaticBar key={index} options={item} />\n ))}\n </div>\n {/* Only render dynamic or static legends if they contain items */}\n {dynamicItems.length > 0 ? (\n <div id=\"dynamicLegendItems\">\n {/* Add dynamic item legends */}\n {dynamicItems.map((item, index) => (\n <LegendDynamicItems\n key={index}\n mapRef={mapRef}\n viewState={viewState}\n overlayRef={overlayRef}\n options={item}\n />\n ))}\n </div>\n ) : null}\n {staticItems.length > 0 ? (\n <div id=\"staticLegendItems\">\n {/* Add static item legends */}\n {staticItems.map((item, index) => (\n <LegendStaticItems\n key={index}\n mapRef={mapRef}\n viewState={viewState}\n overlayRef={overlayRef}\n options={item}\n />\n ))}\n </div>\n ) : null}\n </>\n );\n}\n\nexport default Legend;\n","import proj4 from 'proj4';\nimport { WebMercatorViewport, _GlobeViewport } from '@deck.gl/core';\nimport gUtilities from './graphicsUtilities';\nimport deckUtilities from './deckUtilities';\n\nexport default class Projection {\n constructor(\n { nx, ny, dx, dy, firstLat, firstLon, proj, rotate, rotation, wrapLongitude, datelineFix },\n resLevel = 1,\n ) {\n this.nx = Math.ceil(nx / resLevel);\n this.ny = Math.ceil(ny / resLevel);\n this.dx = dx * resLevel;\n this.dy = dy * resLevel;\n this.firstLat = firstLat;\n this.firstLon = firstLon;\n this.proj = proj;\n this.resLevel = resLevel;\n this.wrapLongitude = wrapLongitude || false;\n this.datelineFix = datelineFix || false;\n this.rotate = rotate || false;\n this.rotation = rotation || {\n longitudeOfSouthernPoleInDegrees: 0,\n latitudeOfSouthernPoleInDegrees: 0,\n angleOfRotationInDegrees: 0,\n };\n this.i0 = NaN;\n this.i1 = NaN;\n this.j0 = NaN;\n this.j1 = NaN;\n // Example proj\n //\n // I try to follow this, but I fail\n // x,y - common space (similar to lat/lon but can go far beyond -360 to 360)\n // i,j - model grid space\n // lat,lon - world space\n /*\n \"projDict\" : {\n \"nx\": number of x point, \n \"ny\": number of y points, \n \"dx\": resolution in m or degrees, \n \"dy\": resolution in m or degrees,\n \"firstLat\" : first lat,\n \"firstLon\" : first lon,\n \"proj\": projection, e.g. \"+proj=lcc +a=6371200.0 +b=6371200.0 +lon_0=265.0 +lat_0=25.0 +lat_1=25.0 +lat_2=25.0\"\n\n // Items added after constructor\n \"projection\": proj4 projection\n\n // Items added after calcLocalDomain\n \"i0\": first i location of local domain\n \"i1\": last i location of local domain\n \"j0\": first j location of local domain\n \"j1\": last j location of local domain\n\n // Items added after \n },\n */\n\n // Get temporary projection to get x and y values\n this.projection = proj4(this.proj);\n const [x, y] = this.projection.forward([this.firstLon, this.firstLat]);\n // Get final projection\n this.xMin = -x;\n this.yMin = -y;\n this.projection = proj4(`${this.proj} +x_0=${-x} +y_0=${-y}`);\n }\n\n getCorners(localDomain = true, reverse = true) {\n const { nx, ny } = this.getNxNY(localDomain);\n const path = [];\n\n // Get the first column\n for (let y = 0; y < ny; y += 1) {\n path.push(this.ijToLonLat(0, y, localDomain));\n }\n // Get the first row\n for (let x = 0; x < nx; x += 1) {\n path.push(this.ijToLonLat(x, ny - 1, localDomain));\n }\n // Get the last column in reverse\n for (let y = ny - 1; y >= 0; y -= 1) {\n path.push(this.ijToLonLat(nx - 1, y, localDomain));\n }\n // Get last row in reverse\n for (let x = nx - 1; x >= 0; x -= 1) {\n path.push(this.ijToLonLat(x, 0, localDomain));\n }\n\n for (let i = 0; i < path.length; i += 1) {\n if (reverse) {\n path[i].reverse();\n }\n }\n\n return path;\n }\n\n getNxNY(localDomain) {\n let nx;\n let ny;\n if (localDomain && !Number.isNaN(this.i0)) {\n ny = this.j1 - this.j0;\n nx = this.i1 - this.i0;\n } else {\n ny = this.ny;\n nx = this.nx;\n }\n return { nx, ny };\n }\n\n makeLonLatGrid(localDomain = true) {\n // Make the LonLatGrid\n const { nx, ny } = this.getNxNY(localDomain);\n const lonlatGrid = new Array(ny);\n for (let y = 0; y < ny; y += 1) {\n lonlatGrid[y] = new Array(nx);\n for (let x = 0; x < nx; x += 1) {\n lonlatGrid[y][x] = this.ijToLonLat(x, y, localDomain);\n }\n }\n this.lonlatGrid = lonlatGrid;\n }\n\n qcPoints() {\n // Make sure i0...j0 points don't go outside of domain\n this.j0 = Math.max(this.j0, 0);\n this.j1 = Math.min(this.j1, this.ny);\n this.i1 = Math.min(this.i1, this.nx);\n if (this.wrapLongitude) {\n // wrapLongitude can allow points -nx to +nx\n this.i0 = Math.max(this.i0, -this.nx);\n // -1 is important for creating no seams in the globe\n const correction = this.i1 - this.i0 - this.nx - 1;\n if (correction > 0) {\n this.i0 += Math.ceil(correction / 2);\n this.i1 -= Math.floor(correction / 2);\n }\n } else {\n this.i0 = Math.max(this.i0, 0);\n }\n }\n\n makeresponse() {\n return {\n i0: this.i0,\n j0: this.j0,\n i1: this.i1,\n j1: this.j1,\n nx: this.nx,\n ny: this.ny,\n resLevel: this.resLevel,\n };\n }\n\n //\n // Adds i0, i1, j0, j1 of the local domain to this.projDict\n // nx and ny will remain the nx and ny of the origional domain\n calcLocalDomain(lat, lon, ny, nx) {\n const [i, j] = this.LonLatToij(lon, lat, true, true);\n this.i0 = i - Math.floor(nx / 2);\n this.i1 = i + Math.floor(nx / 2);\n this.j0 = j - Math.floor(ny / 2);\n this.j1 = j + Math.floor(ny / 2);\n\n this.qcPoints();\n\n return this.makeresponse();\n }\n\n calcLocalDomainFromViewport(x4dDisplay, viewState, tiling, mapType = 'Mapbox') {\n const { i0, i1, j0, j1 } = this.getViewportBoundsIJ(x4dDisplay, viewState, mapType, tiling);\n\n this.i0 = i0;\n this.i1 = i1;\n this.j0 = j0;\n this.j1 = j1;\n\n this.qcPoints();\n\n return this.makeresponse();\n }\n\n getViewportBoundsIJ(x4dDisplay, viewState, mapType, tiling = undefined) {\n const { clientWidth, clientHeight } = x4dDisplay.current;\n\n // Step 1 - Get the viewport (can't use displayRef since that is not loaded the first time around)\n let viewport;\n\n if (['Mapbox', 'geojson'].includes(mapType)) {\n viewport = new WebMercatorViewport({\n ...viewState,\n width: clientWidth,\n height: clientHeight,\n });\n } else {\n viewport = new _GlobeViewport({\n ...viewState,\n width: clientWidth,\n height: clientHeight,\n });\n }\n\n // Step 2) Made a grid of relative screen points to be sampled\n let {\n yMin: j0,\n yMax: j1,\n xMin: i0,\n xMax: i1,\n } = deckUtilities.getViewportBounds(viewport, this);\n\n // Step 3) adjust i0,i1,j0,j1 so they align with tiles\n // chunks and tiles don't have to align but they should for the best performance\n if (tiling) {\n i0 = Math.floor(i0 / tiling.x) * tiling.x;\n i1 = Math.ceil(i1 / tiling.x) * tiling.x;\n j0 = Math.floor(j0 / tiling.y) * tiling.y;\n j1 = Math.ceil(j1 / tiling.y) * tiling.y;\n }\n\n return { i0, i1, j0, j1 };\n }\n\n //\n // Looks at the viewport and determins what resolution we should use\n calcResLevel(x4dDisplay, viewState, tilingConfig, mapType = 'Mapbox') {\n // Step 1 - Get viewport boundsIJ\n // let the points go outside of the domain (i.e. i0 can be <0 and i1 can be > nx)\n // This ensures that the resolution won't change if we are just clipping a domain\n\n // Always calculate the resLevel for a pitch of 0. We don't want the resolution changing\n // if a user tilts the maps\n const altViewState = { ...viewState };\n altViewState.pitch = 0;\n const { i0, i1, j0, j1 } = this.getViewportBoundsIJ(x4dDisplay, altViewState, mapType);\n\n // Step 2 - Determine the best resolution\n const { resLevels, targetNx, targetNy } = tilingConfig;\n const di = i1 - i0;\n const dj = j1 - j0;\n\n // Find the cloest resLevel to the calculated value\n const resLevelI = gUtilities.closestceilvalue(resLevels, di / targetNx);\n const resLevelJ = gUtilities.closestceilvalue(resLevels, dj / targetNy);\n const resLevel = Math.max(resLevelI, resLevelJ);\n\n return resLevel;\n }\n\n rotateCoordinate(lon, lat, option) {\n lon = (lon * Math.PI) / 180; // Convert degrees to radians\n lat = (lat * Math.PI) / 180;\n\n const { longitudeOfSouthernPoleInDegrees, latitudeOfSouthernPoleInDegrees } = this.rotation;\n let theta = 90 + latitudeOfSouthernPoleInDegrees; // Rotation around y-axis\n let phi = longitudeOfSouthernPoleInDegrees; // Rotation around z-axis\n\n phi = (phi * Math.PI) / 180; // Convert degrees to radians\n theta = (theta * Math.PI) / 180;\n\n const x = Math.cos(lon) * Math.cos(lat); // Convert from spherical to cartesian coordinates\n const y = Math.sin(lon) * Math.cos(lat);\n const z = Math.sin(lat);\n\n let x_new;\n let y_new;\n let z_new;\n if (option === 1) {\n // Regular -> Rotated\n\n x_new =\n Math.cos(theta) * Math.cos(phi) * x +\n Math.cos(theta) * Math.sin(phi) * y +\n Math.sin(theta) * z;\n y_new = -Math.sin(phi) * x + Math.cos(phi) * y;\n z_new =\n -Math.sin(theta) * Math.cos(phi) * x -\n Math.sin(theta) * Math.sin(phi) * y +\n Math.cos(theta) * z;\n }\n if (option === 2) {\n // Rotated -> Regular\n\n phi = -phi;\n theta = -theta;\n\n x_new =\n Math.cos(theta) * Math.cos(phi) * x +\n Math.sin(phi) * y +\n Math.sin(theta) * Math.cos(phi) * z;\n y_new =\n -Math.cos(theta) * Math.sin(phi) * x +\n Math.cos(phi) * y -\n Math.sin(theta) * Math.sin(phi) * z;\n z_new = -Math.sin(theta) * x + Math.cos(theta) * z;\n }\n\n let lon_new = Math.atan2(y_new, x_new); // Convert cartesian back to spherical coordinates\n let lat_new = Math.asin(z_new);\n\n lon_new = (lon_new * 180) / Math.PI; // Convert radians back to degrees\n lat_new = (lat_new * 180) / Math.PI;\n\n return [lon_new, lat_new]; // Return the new coordinates\n }\n\n LonLatToij(longitude, latitude, round, localDomain = true, commonCoordinates = false) {\n let lat = latitude;\n let lon = longitude;\n // Do we need to rotate coordinates?\n if (this.rotate) {\n [lon, lat] = this.rotateCoordinate(lon, lat, 1);\n }\n\n // Make sure the lon is within the bounds of the data\n if (!commonCoordinates) {\n const diff = lon - this.firstLon;\n lon = this.firstLon + (((diff % 360) + 360) % 360);\n }\n\n let i;\n let j;\n // x_0 and y_0 don't impact longlat grids, need to add them back in\n if (this.proj.includes('longlat')) {\n i = (lon - this.firstLon) / this.dx;\n j = (lat - this.firstLat) / this.dy;\n } else {\n [i, j] = this.projection.forward([lon, lat]);\n i /= this.dx;\n j /= this.dy;\n }\n\n if (localDomain && !Number.isNaN(this.i0) && !Number.isNaN(this.j0)) {\n i -= this.i0;\n j -= this.j0;\n }\n\n if (round) {\n i = Math.round(i);\n j = Math.round(j);\n }\n\n return [i, j];\n }\n\n // localDomain is the smaller subset of the original domain.\n // so i,j can be the i,j of the original domain or local domain\n ijToLonLat(iorg, jorg, localDomain = true) {\n let i = iorg;\n let j = jorg;\n // Add i0 and j0 to i,j if available\n if (localDomain && !Number.isNaN(this.i0) && !Number.isNaN(this.j0)) {\n i += this.i0;\n j += this.j0;\n }\n\n let [lon, lat] = this.projection.inverse([i * this.dx, j * this.dy]);\n\n // x_0 and y_0 don't impact longlat grids, need to add them back in\n if (this.proj.includes('longlat')) {\n lon += this.firstLon;\n lat += this.firstLat;\n }\n\n // Do we need to rotate grid?\n if (this.rotate) {\n [lon, lat] = this.rotateCoordinate(lon, lat, 2);\n }\n\n // Needed for HREF Alaska\n if (this.firstLon > 0 && lon < 0) lon += 360;\n if (this.firstLon < 0 && lon > 0) lon -= 360;\n\n return [lon, lat];\n }\n}\n","const defaults = {\n // The default configuration\n defaults: 'default',\n // Colorbars\n colorBars: {\n // Default colorbar\n default: {\n // Colors in rgb or rgba\n colors: [\n 'rgb(0,0,255)',\n 'rgb(50,0,205)',\n 'rgb(100,0,155)',\n 'rgb(150,0,105)',\n 'rgb(200,0,55)',\n 'rgb(255,0,0)',\n ],\n // Color values corresponding to the colors\n colorLevels: [20, 40, 60, 80, 100],\n // Color scale type, 'scaleLinear' or 'scaleThreshold'\n colorType: 'scaleThreshold',\n // Contour values\n contourLevels: [0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100],\n // Cap on the left/bottom side of legend\n isLeftCap: true,\n // Cap on the right/top side of legend\n isRightCap: true,\n // tick placement on legend, 'linear'=linear or 'byColorLevels'=by color values\n ticks: 'linear',\n },\n // Difference colorbar\n difference: {\n colors: [\n 'rgb(0,0,70)',\n 'rgb(36,56,119)',\n 'rgb(68,106,161)',\n 'rgb(100,152,195)',\n 'rgb(132,185,216)',\n 'rgb(164,207,228)',\n 'rgba(194,227,239,200)',\n 'rgba(255,255,255,0)',\n 'rgba(254,195,118,200)',\n 'rgb(252,163,95)',\n 'rgb(247,128,76)',\n 'rgb(234,93,59)',\n 'rgb(199,61,41)',\n 'rgb(148,29,24)',\n 'rgb(84,0,0)',\n ],\n colorLevels: [-14, -12, -10, -8, -6, -4, -2, 2, 4, 6, 8, 10, 12, 14],\n colorType: 'scaleThreshold',\n contourLevels: [-14, -12, -10, -8, -6, -4, -2, 2, 4, 6, 8, 10, 12, 14],\n isLeftCap: true,\n isRightCap: true,\n ticks: 'byColorLevels',\n },\n // Spread colorbar\n spread: {\n colors: [\n 'rgba(0,0,0,0)',\n 'rgba(0,0,0,0)',\n 'rgba(255,239,3,0.5)',\n 'rgb(255,195,3)',\n 'rgb(255,87,51)',\n 'rgb(190,0,0)',\n 'rgb(88,24,70)',\n ],\n colorLevels: [0, 2, 4, 6, 8, 10],\n colorType: 'scaleThreshold',\n contourLevels: [0, 2, 4, 6, 8, 10],\n isLeftCap: false,\n isRightCap: true,\n ticks: 'byColorLevels',\n },\n // Climatology colorbar\n climo: {\n colors: [\n 'rgb(3, 10, 60)', // 0.0000–0.0032 (extreme low tail)\n 'rgb(13, 30, 80)', // 0.0032–0.023 (-4.0σ to -3.5σ)\n 'rgb(23, 50, 99)', // 0.023–0.135 (-3.5σ to -3.0σ)\n 'rgb(33, 70, 119)', // 0.135–0.621 (-3.0σ to -2.5σ)\n 'rgb(43, 91, 138)', // 0.621–2.275 (-2.5σ to -2.0σ)\n 'rgb(53, 111, 158)', // 2.275–6.681 (-2.0σ to -1.5σ)\n 'rgb(63, 131, 177)', // 6.681–15.866 (-1.5σ to -1.0σ)\n 'rgb(73,151,197)', // 15.866–30.854 (-1.0σ to -0.5σ)\n 'rgba(0,0,0,0)', // 30.854–50.000 (transparent)\n 'rgba(0,0,0,0)', // 50.000–69.146 (transparent)\n 'rgb(241,158,124)', // 69.146–84.134 (+0.5σ to +1.0σ)\n 'rgb(228,128,102)', // 84.134–93.319 (+1.0σ to +1.5σ)\n 'rgb(216,101,81)', // 93.319–97.725 (+1.5σ to +2.0σ)\n 'rgb(201,70,65)', // 97.725–99.379 (+2.0σ to +2.5σ)\n 'rgb(185,39,50)', // 99.379–99.865 (+2.5σ to +3.0σ)\n 'rgb(164,19,40)', // 99.865–99.977 (+3.0σ to +3.5σ)\n 'rgb(131,9,34)', // 99.977–99.9968 (+3.5σ to +4.0σ)\n 'rgb(100,5,25)', // 99.9968–100.000 (extreme high tail)\n ],\n colorLevels: [\n 0.01, 0.5, 1, 3, 5, 10, 15, 30, 50.0, 70, 85, 90, 95, 97, 99, 99.5, 99.99,\n ],\n colorType: 'scaleThreshold',\n contourLevels: [\n 0.01, 0.5, 1, 3, 5, 10, 15, 30, 50.0, 70, 85, 90, 95, 97, 99, 99.5, 99.99,\n ],\n isLeftCap: true,\n isRightCap: true,\n ticks: 'byColorLevels',\n },\n // When making a consolidated config, we probably need to add these fields for ptype refc colorbar\n prain: {\n colors: [\n 'rgba(150,150,150,0)',\n 'rgba(127,255,0,1)',\n 'rgb(127,255,0)',\n 'rgb(85,195,0)',\n 'rgb(42,136,0)',\n 'rgb(0,76,0)',\n 'rgb(0,76,0)',\n ],\n colorLevels: [1, 5, 15, 25, 35, 50],\n colorType: 'scaleThreshold',\n contourLevels: [1, 5, 15, 25, 35, 50],\n isLeftCap: false,\n isRightCap: false,\n ticks: 'byColorLevels',\n // unfortunately we can't put the legend name in here, ie `nameLegend: \"Rain Reflectivity\"`\n },\n\n // Timing colorbar\n timing: {\n colors: ['rgba(0,0,0,0)', 'rgb(16, 89, 140)', 'rgb(250, 247, 179)'],\n colorLevels: undefined, // Defined in X4D.jsx\n colorType: 'scaleThreshold',\n contourLevels: undefined, // Defined in X4D.jsx\n isLeftCap: false,\n isRightCap: true,\n ticks: 'byColorLevels',\n },\n // Percentage colorbar\n percentage: {\n colors: [\n 'rgba(0,0,0,0)',\n 'rgb(10,5,30)',\n 'rgb(30,14,80)',\n 'rgb(50,32,150)',\n 'rgb(174,48,91)',\n 'rgb(218,78,59)',\n 'rgb(241,114,29)',\n 'rgb(251,158,7',\n 'rgb(250,187,33)',\n 'rgb(248,224,55)',\n 'rgb(255,255,150)',\n 'rgb(255,255,150)',\n ],\n colorLevels: [5, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100],\n colorType: 'scaleThreshold',\n contourLevels: [5, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100],\n isLeftCap: true,\n isRightCap: false,\n ticks: 'byColorLevels',\n },\n // Paintball colorbar\n paintball: {\n // If we want to support more than 14 members in paintball, update colors here\n colors: [\n 'rgb(229,153,255)',\n 'rgb(131,71,153)',\n 'rgb(165,191,229)',\n 'rgb(32,62,153)',\n 'rgb(239,138,139)',\n 'rgb(205,61,50)',\n 'rgb(164,239,165)',\n 'rgb(67,128,7)',\n 'rgb(255,255,0)',\n 'rgb(150,150,0)',\n 'rgb(255,161,0)',\n 'rgb(255,204,118)',\n 'rgb(1,255,190)',\n 'rgb(0,117,87)',\n ],\n colorLevels: [], // levels & contours set dynamically in X4d.jsx\n colorType: 'scaleThreshold',\n contourLevels: [], // levels & contours set dynamically in X4d.jsx\n isLeftCap: true,\n isRightCap: false,\n ticks: 'byColorLevels',\n },\n },\n colorPrimary: 'rgb(0,0,255)',\n isZeroLowerBound: false,\n nameLegend: 'Default Name',\n namePublic: 'Default Name',\n nameShort: 'Default Name',\n roundto: 1,\n roundtoReadout: 1,\n units: '',\n};\n\nexport default defaults;\n","{\n \"aeroOptThick\": {\n \"defaults\": \"default\",\n \"colorBars\": {\n \"default\": {\n \"colorLevels\": [0, 0.2, 1],\n \"colors\": [\"rgba(255,255,255,0)\", \"rgba(255,254,224,0.7)\", \"rgba(105,37,6,1)\"],\n \"colorType\": \"scaleLinear\",\n \"contourLevels\": [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1],\n \"ticks\": \"linear\"\n },\n \"difference\": {\n \"colorLevels\": [\n -0.7, -0.6, -0.5, -0.4, -0.3, -0.2, -0.1, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7\n ]\n }\n },\n \"colorPrimary\": \"var(--graphcolorlight)\",\n \"isZeroLowerBound\": true,\n \"nameLegend\": \"Aerosol Optical Thickness\",\n \"namePublic\": \"Aerosol Optical Thickness\",\n \"nameShort\": \"AOT\",\n \"roundto\": 2,\n \"units\": \"\"\n },\n \"aqi\": {\n \"defaults\": \"default\",\n \"colorBars\": {\n \"default\": {\n \"colorType\": \"scaleThreshold\",\n \"ticks\": \"byColorLevels\"\n }\n }\n },\n \"bposelay\": {\n \"defaults\": \"default\",\n \"colorBars\": {\n \"default\": {\n \"colorLevels\": [0, 100, 300, 600, 900, 1200],\n \"colors\": [\n \"rgba(0,0,0,0)\",\n \"rgb(255,255,0)\",\n \"rgb(255,165,0)\",\n \"rgb(255,0,0)\",\n \"rgb(178,34,34)\",\n \"rgb(140,1,1)\"\n ],\n \"colorType\": \"scaleLinear\",\n \"contourLevels\": [0, 100, 200, 300, 400, 500, 600, 700, 800, 900, 1000],\n \"isLeftCap\": false,\n \"ticks\": \"linear\"\n },\n \"difference\": {\n \"colorLevels\": [\n -350, -300, -250, -200, -150, -100, -50, 50, 100, 150, 200, 250, 300, 350\n ]\n },\n \"spread\": {\n \"colorLevels\": [0, 100, 200, 300, 400, 500]\n }\n },\n \"colorPrimary\": \"rgb(200,50,0)\",\n \"nameLegend\": \"Positive Warm Nose Aloft\",\n \"namePublic\": \"Bourgouin Pos\",\n \"nameShort\": \"Bourgouin Pos\",\n \"roundto\": 0,\n \"units\": \"J/kg\"\n },\n \"bnegelay\": {\n \"defaults\": \"default\",\n \"colorBars\": {\n \"default\": {\n \"colorLevels\": [-500, -200, -50, 0],\n \"colors\": [\"rgb(173,0,255)\", \"rgb(0,50,255)\", \"rgb(135,233,255)\", \"rgba(0,0,0,0)\"],\n \"colorType\": \"scaleLinear\",\n \"contourLevels\": [-500, -400, -300, -200, -100, 0],\n \"ticks\": \"linear\"\n },\n \"difference\": {\n \"colorLevels\": [\n -350, -300, -250, -200, -150, -100, -50, 50, 100, 150, 200, 250, 300, 350\n ]\n },\n \"spread\": {\n \"colorLevels\": [0, 100, 200, 300, 400, 500]\n }\n },\n \"colorPrimary\": \"rgb(200,50,0)\",\n \"nameLegend\": \"Negative Near Surface Cold Layer\",\n \"namePublic\": \"Bourgouin Neg\",\n \"nameShort\": \"Bourgouin Neg\",\n \"roundto\": 0,\n \"units\": \"J/kg\"\n },\n \"ceilingAGL\": {\n \"defaults\": \"default\",\n \"colorBars\": {\n \"default\": {\n \"colorLevels\": [0.1, 0.2, 0.3, 0.4, 0.5, 0.7, 1, 1.5, 2, 2.5, 3, 5, 10, 15, 20, 30],\n \"colors\": [\n \"rgb(164,43,163)\",\n \"rgb(164,43,163)\",\n \"rgb(190,80,190)\",\n \"rgb(220,120,210)\",\n \"rgb(255,153,255)\",\n \"rgb(220,75,125)\",\n \"rgb(200,0,0)\",\n \"rgb(220,180,10)\",\n \"rgb(255,255,0)\",\n \"rgb(255,255,100)\",\n \"rgb(255,255,200)\",\n \"rgb(100,100,100)\",\n \"rgb(150,150,150)\",\n \"rgb(175,175,175)\",\n \"rgb(200,200,200)\",\n \"rgb(225,225,225)\",\n \"rgba(0,0,0,0)\"\n ],\n \"colorType\": \"scaleThreshold\",\n \"contourLevels\": [0.1, 0.2, 0.3, 0.4, 0.5, 0.7, 1, 1.5, 2, 2.5, 3, 5, 10, 15, 30],\n \"isLeftCap\": true,\n \"ticks\": \"byColorLevels\"\n }\n },\n \"colorPrimary\": \"rgb(140,140,160)\",\n \"nameLegend\": \"Ceiling Height\",\n \"namePublic\": \"Ceiling Height\",\n \"nameShort\": \"Ceil\",\n \"roundto\": 1,\n \"units\": \"kft\"\n },\n \"ceilingMSL\": {\n \"defaults\": \"ceilingAGL\",\n \"nameLegend\": \"Ceiling Height MSL\",\n \"namePublic\": \"Ceiling Height MSL\",\n \"nameShort\": \"Ceil\"\n },\n \"dustFineSfc\": {\n \"defaults\": \"default\",\n \"colorBars\": {\n \"default\": {\n \"colorLevels\": [0, 1, 25, 100, 200, 250],\n \"colors\": [\n \"rgba(0,0,0,0)\",\n \"rgba(0,0,0,0)\",\n \"rgb(255, 240, 204)\",\n \"rgb(252, 229, 184)\",\n \"rgb(172, 120, 0)\",\n \"rgb(78, 49, 14)\"\n ],\n \"colorType\": \"scaleLinear\",\n \"contourLevels\": [5, 25, 50, 100, 150, 200, 250],\n \"isLeftCap\": false,\n \"ticks\": \"linear\"\n }\n },\n \"colorPrimary\": \"rgb(200,153,100)\",\n \"nameLegend\": \"Near Surface Fine Dust\",\n \"namePublic\": \"Near Surface Fine Dust\",\n \"nameShort\": \"Fine Dust\",\n \"roundto\": 0,\n \"units\": \"µg/m^3\"\n },\n \"dustFineVI\": {\n \"defaults\": \"dustFineSfc\",\n \"colorPrimary\": \"rgb(135,90,50)\",\n \"nameLegend\": \"Vertically Integrated Fine Dust\",\n \"namePublic\": \"Vertically Integrated Fine Dust\",\n \"nameShort\": \"Fine Dust VI\",\n \"units\": \"mg/m^2\"\n },\n \"dustCoarseSfc\": {\n \"defaults\": \"dustFineSfc\",\n \"colorPrimary\": \"rgb(200,153,100)\",\n \"nameLegend\": \"Near Surface Coarse Dust\",\n \"namePublic\": \"Near Surface Coarse Dust\",\n \"nameShort\": \"Coarse Dust\",\n \"units\": \"µg/m^3\"\n },\n \"dustCoarseVI\": {\n \"defaults\": \"dustFineSfc\",\n \"colorPrimary\": \"rgb(135,90,50)\",\n \"nameLegend\": \"Vertically Integrated Coarse Dust\",\n \"namePublic\": \"Vertically Integrated Coarse Dust\",\n \"nameShort\": \"Coarse Dust\",\n \"units\": \"mg/m^2\"\n },\n \"lcl\": {\n \"defaults\": \"default\",\n \"colorBars\": {\n \"default\": {\n \"colorLevels\": [0.1, 0.2, 0.3, 0.4, 0.5, 0.7, 1, 1.5, 2, 3, 4, 5, 6, 8, 10, 12, 14],\n \"colors\": [\n \"rgb(164,43,163)\",\n \"rgb(164,43,163)\",\n \"rgb(190,80,190)\",\n \"rgb(220,120,210)\",\n \"rgb(255,153,255)\",\n \"rgb(220,75,125)\",\n \"rgb(200,0,0)\",\n \"rgb(220,180,10)\",\n \"rgb(255,255,0)\",\n \"rgb(255,255,100)\",\n \"rgb(255,255,200)\",\n \"rgb(75,75,75)\",\n \"rgb(100,100,100)\",\n \"rgb(150,150,150)\",\n \"rgb(200,200,200)\",\n \"rgb(225,225,225)\",\n \"rgb(245,245,245)\",\n \"rgba(255,255,255,0.75)\"\n ],\n \"colorType\": \"scaleThreshold\",\n \"contourLevels\": [\n 0.1, 0.2, 0.3, 0.4, 0.5, 0.7, 1, 1.5, 2, 3, 4, 5, 6, 8, 10, 12, 14\n ],\n \"isLeftCap\": true,\n \"ticks\": \"byColorLevels\"\n }\n },\n \"colorPrimary\": \"rgb(140,140,160)\",\n \"nameLegend\": \"LCL\",\n \"namePublic\": \"LCL\",\n \"nameShort\": \"LCL\",\n \"roundto\": 1,\n \"units\": \"kft\"\n },\n \"cloudBase\": {\n \"defaults\": \"ceilingAGL\",\n \"colorPrimary\": \"rgb(210,210,210)\",\n \"nameLegend\": \"Lowest Cloud Base\",\n \"namePublic\": \"Lowest Cloud Base\"\n },\n \"CWASP\": {\n \"defaults\": \"default\",\n \"colorBars\": {\n \"default\": {\n \"colorLevels\": [0, 20, 40, 60, 80, 100],\n \"colors\": [\n \"rgb(0,0,0,0)\",\n \"rgb(94,197,83)\",\n \"rgb(255,247,0)\",\n \"rgb(255,14,22)\",\n \"rgb(149,0,149)\",\n \"rgb(180,160,255)\"\n ],\n \"colorType\": \"scaleLinear\",\n \"contourLevels\": [0, 20, 40, 60, 80, 100],\n \"isLeftCap\": false,\n \"ticks\": \"linear\"\n }\n },\n \"colorPrimary\": \"rgb(200,0,200)\",\n \"nameLegend\": \"CWASP\",\n \"namePublic\": \"CWASP\",\n \"nameShort\": \"CWASP\",\n \"roundto\": 0,\n \"units\": \"%\"\n },\n \"cape\": {\n \"defaults\": \"default\",\n \"colorBars\": {\n \"default\": {\n \"colorLevels\": [0, 10, 100, 500, 1000, 2000, 3000, 5000],\n \"colors\": [\n \"rgba(150,150,150,0)\",\n \"rgba(191,191,191,200)\",\n \"rgb(244,242,168)\",\n \"rgb(224,119,48)\",\n \"rgb(192,0,0)\",\n \"rgb(120,34,150)\",\n \"rgb(212,105,182)\",\n \"rgb(255,255,255)\"\n ],\n \"colorType\": \"scaleLinear\",\n \"contourLevels\": [0, 10, 100, 500, 1000, 2000, 3000, 5000],\n \"isLeftCap\": false,\n \"ticks\": \"byColorLevels\"\n },\n \"difference\": {\n \"colorLevels\": [\n -2000, -1500, -1000, -800, -600, -400, -200, 200, 400, 600, 800, 1000, 1500,\n 2000\n ]\n },\n \"spread\": {\n \"colorLevels\": [0, 100, 200, 300, 400, 500]\n }\n },\n \"colorPrimary\": \"rgb(255,150,0)\",\n \"nameLegend\": \"Surface CAPE\",\n \"namePublic\": \"CAPE\",\n \"nameShort\": \"CAPE\",\n \"roundto\": 0,\n \"units\": \"J/kg\"\n },\n \"mucape\": {\n \"defaults\": \"cape\",\n \"nameLegend\": \"Most Unstable CAPE\",\n \"namePublic\": \"MUCAPE\",\n \"nameShort\": \"MUCAPE\"\n },\n \"cin\": {\n \"defaults\": \"default\",\n \"colorBars\": {\n \"default\": {\n \"colorLevels\": [-500, -300, -200, -100, -50, -20],\n \"colors\": [\n \"rgb(212,105,182)\",\n \"rgb(120,34,150)\",\n \"rgb(192,0,0)\",\n \"rgb(224,119,48)\",\n \"rgb(244,242,168)\",\n \"rgba(0,0,0,0)\"\n ],\n \"colorType\": \"scaleLinear\",\n \"contourLevels\": [-500, -300, -200, -100, -50],\n \"isRightCap\": false,\n \"ticks\": \"byColorLevels\"\n },\n \"difference\": {\n \"colorLevels\": [\n -600, -500, -400, -300, -200, -100, -500, 50, 100, 200, 300, 400, 500, 600\n ]\n },\n \"spread\": {\n \"colorLevels\": [0, 100, 200, 300, 400, 500]\n }\n },\n \"colorPrimary\": \"rgb(255,255,0)\",\n \"nameLegend\": \"Surface CIN\",\n \"namePublic\": \"CIN\",\n \"nameShort\": \"CIN\",\n \"roundto\": 0,\n \"units\": \"J/kg\"\n },\n \"mucin\": {\n \"defaults\": \"cin\",\n \"nameLegend\": \"Most Unstable CIN\",\n \"namePublic\": \"MUCIN\",\n \"nameShort\": \"MUCIN\"\n },\n \"ellrod\": {\n \"defaults\": \"default\",\n \"colorBars\": {\n \"default\": {\n \"colorLevels\": [1, 2, 3, 4],\n \"colors\": [\n \"rgb(150,150,150,0.0)\",\n \"rgb(255,255,0)\",\n \"rgb(253,160,0)\",\n \"rgb(243,70,0)\",\n \"rgb(220,44,2)\"\n ],\n \"colorType\": \"scaleThreshold\",\n \"contourLevels\": [1, 2, 3, 4, 5],\n \"isLeftCap\": true,\n \"ticks\": \"byColorLevels\"\n }\n },\n \"colorPrimary\": \"rgb(255,255,0)\",\n \"nameLegend\": \"Ellrod Index\",\n \"namePublic\": \"Ellrod Index\",\n \"nameShort\": \"Ellrod\",\n \"roundto\": 0,\n \"units\": \"\"\n },\n \"fosberg\": {\n \"defaults\": \"default\",\n \"colorBars\": {\n \"default\": {\n \"colorLevels\": [0, 25, 50, 75, 100],\n \"colors\": [\n \"rgba(255,233,255,0)\",\n \"rgb(255,233,255)\",\n \"rgb(248,111,85)\",\n \"rgb(253,158,0)\",\n \"rgb(255,255,0)\"\n ],\n \"colorType\": \"scaleLinear\",\n \"contourLevels\": [25, 50, 75, 100],\n \"isLeftCap\": false,\n \"ticks\": \"linear\"\n }\n },\n \"colorPrimary\": \"rgb(201,114,93)\",\n \"nameLegend\": \"Fosberg Index\",\n \"namePublic\": \"Fosberg Index\",\n \"nameShort\": \"Fosberg\",\n \"roundto\": 0,\n \"units\": \"\"\n },\n \"frzr1\": {\n \"defaults\": \"default\",\n \"colorBars\": {\n \"default\": {\n \"colorLevels\": [0, 0.001, 0.05, 0.1, 0.15, 0.2, 0.25, 0.3],\n \"colors\": [\n \"rgba(150,150,150,0)\",\n \"rgba(150,150,150,0)\",\n \"rgb(243,234,59)\",\n \"rgb(255,192,0)\",\n \"rgb(255,0,0)\",\n \"rgb(192,0,0)\",\n \"rgb(153,102,255)\",\n \"rgb(114,10,200)\",\n \"rgb(36,5,91)\"\n ],\n \"colorType\": \"scaleThreshold\",\n \"contourLevels\": [0.01, 0.05, 0.1, 0.15, 0.2, 0.25, 0.3],\n \"isLeftCap\": false,\n \"ticks\": \"byColorLevels\"\n },\n \"spread\": {\n \"colorLevels\": [0, 0.01, 0.05, 0.1, 0.15, 0.2]\n }\n },\n \"colorPrimary\": \"rgb(255, 100, 255)\",\n \"nameLegend\": \"1 Hour Freezing Rain (1:1 ratio)\",\n \"namePublic\": \"1 Hour Freezing Rain (1:1 ratio)\",\n \"nameShort\": \"Frzr\",\n \"roundto\": 2,\n \"units\": \"in\"\n },\n \"fram1\": {\n \"defaults\": \"frzr1\",\n \"nameLegend\": \"1 Hour Freezing Rain (FRAM)\",\n \"namePublic\": \"1 Hour Freezing Rain (FRAM)\",\n \"nameShort\": \"Fram\"\n },\n \"frzr6\": {\n \"defaults\": \"frzr1\",\n \"colorBars\": {\n \"default\": {\n \"colorLevels\": [0, 0.001, 0.05, 0.1, 0.15, 0.2, 0.25, 0.5],\n \"contourLevels\": [0.01, 0.05, 0.1, 0.15, 0.2, 0.25, 0.5]\n },\n \"spread\": {\n \"colorLevels\": [0, 0.01, 0.05, 0.1, 0.15, 0.2]\n }\n },\n \"nameLegend\": \"6 Hour Freezing Rain (1:1 ratio)\",\n \"namePublic\": \"6 Hour Freezing Rain (1:1 ratio)\"\n },\n \"fram6\": {\n \"defaults\": \"frzr6\",\n \"nameLegend\": \"6 Hour Freezing Rain (FRAM)\",\n \"namePublic\": \"6 Hour Freezing Rain (FRAM)\",\n \"nameShort\": \"Fram6\"\n },\n \"frzr24\": {\n \"defaults\": \"frzr1\",\n \"colorBars\": {\n \"default\": {\n \"colorLevels\": [0, 0.01, 0.1, 0.25, 0.5, 0.75, 1, 2],\n \"contourLevels\": [0.01, 0.1, 0.25, 0.5, 0.75, 1, 2]\n },\n \"spread\": {\n \"colorLevels\": [0, 0.05, 0.1, 0.25, 0.5, 1]\n }\n },\n \"nameLegend\": \"24 Hour Freezing Rain (1:1 ratio)\",\n \"namePublic\": \"24 Hour Freezing Rain (1:1 ratio)\"\n },\n \"fram24\": {\n \"defaults\": \"frzr24\",\n \"nameLegend\": \"24 Hour Freezing Rain (FRAM)\",\n \"namePublic\": \"24 Hour Freezing Rain (FRAM)\",\n \"nameShort\": \"Fram24\"\n },\n \"frzr48\": {\n \"defaults\": \"frzr24\",\n \"nameLegend\": \"48 Hour Freezing Rain\",\n \"namePublic\": \"48 Hour Freezing Rain\"\n },\n \"frzr72\": {\n \"defaults\": \"frzr24\",\n \"nameLegend\": \"72 Hour Freezing Rain\",\n \"namePublic\": \"72 Hour Freezing Rain\"\n },\n \"frzrtotal\": {\n \"defaults\": \"frzr24\",\n \"nameLegend\": \"Accumulated Freezing Rain (1:1 ratio)\",\n \"namePublic\": \"Accumulated Freezing Rain (1:1 ratio)\"\n },\n \"framtotal\": {\n \"defaults\": \"fram24\",\n \"nameLegend\": \"Accumulated Freezing Rain (FRAM)\",\n \"namePublic\": \"Accumulated Freezing Rain (FRAM)\",\n \"nameShort\": \"Framtotal\"\n },\n \"frzrSpray\": {\n \"defaults\": \"default\",\n \"colorBars\": {\n \"default\": {\n \"colorLevels\": [0, 1, 2, 3, 4],\n \"colors\": [\n \"rgba(150,150,150,0)\",\n \"rgba(150,150,150,0)\",\n \"rgb(64,202,52)\",\n \"rgb(246,247,41)\",\n \"rgb(244,172,42)\",\n \"rgb(255,0,0)\"\n ],\n \"colorType\": \"scaleThreshold\",\n \"contourLevels\": [1, 2, 3, 4],\n \"isLeftCap\": false,\n \"ticks\": \"linear\"\n }\n },\n \"colorPrimary\": \"rgb(247,255,59)\",\n \"isZeroLowerBound\": true,\n \"nameLegend\": \"Freezing Spray\",\n \"namePublic\": \"Freezing Spray\",\n \"nameShort\": \"Frzr Spray\",\n \"roundto\": 0,\n \"units\": \"\"\n },\n \"front700\": {\n \"defaults\": \"default\",\n \"colorBars\": {\n \"default\": {\n \"colorLevels\": [\n -6.5, -5.5, -4.5, -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5\n ],\n \"colors\": [\n \"rgb(0,0,70)\",\n \"rgb(36,56,119)\",\n \"rgb(68,106,161)\",\n \"rgb(100,152,195)\",\n \"rgb(132,185,216)\",\n \"rgb(164,207,228)\",\n \"rgba(194,227,239,200)\",\n \"rgba(255,255,255,0)\",\n \"rgba(254,195,118,200)\",\n \"rgb(252,163,95)\",\n \"rgb(247,128,76)\",\n \"rgb(234,93,59)\",\n \"rgb(199,61,41)\",\n \"rgb(148,29,24)\",\n \"rgb(84,0,0)\"\n ],\n \"colorType\": \"scaleThreshold\",\n \"contourLevels\": [-5, -4, -3, -2, -1, 1, 2, 3, 4, 5],\n \"ticks\": \"linear\"\n }\n },\n \"colorPrimary\": \"var(--fontcolor)\",\n \"nameLegend\": \"700 mb Frontogenesis\",\n \"namePublic\": \"700 mb Frontogenesis\",\n \"nameShort\": \"700mb fgen\",\n \"roundto\": 1,\n \"units\": \"K/100km/3h\"\n },\n \"front850\": {\n \"defaults\": \"front700\",\n \"nameLegend\": \"850 mb Frontogenesis\",\n \"namePublic\": \"850 mb Frontogenesis\",\n \"nameShort\": \"850mb fgen\"\n },\n \"vort500\": {\n \"defaults\": \"default\",\n \"colorBars\": {\n \"default\": {\n \"colorLevels\": [0, 10, 25, 50],\n \"colors\": [\n \"rgba(150,150,150,0)\",\n \"rgb(255,255,42)\",\n \"rgb(255,80,0)\",\n \"rgb(88,0,0)\"\n ],\n \"colorType\": \"scaleLinear\",\n \"contourLevels\": [10, 20, 30, 40, 50],\n \"isLeftCap\": false,\n \"ticks\": \"linear\"\n }\n },\n \"colorPrimary\": \"var(--fontcolor)\",\n \"nameLegend\": \"500 mb Vorticity\",\n \"namePublic\": \"500 mb Vorticity\",\n \"nameShort\": \"500mb Vort\",\n \"roundto\": 0,\n \"units\": \"1/s\"\n },\n \"gh250\": {\n \"defaults\": \"default\",\n \"colorBars\": {\n \"default\": {\n \"colorLevels\": [996, 1044, 1092, 1140],\n \"colors\": [\"rgb(93,40,134)\", \"rgb(0,112,192)\", \"rgb(253,255,153)\", \"rgb(192,0,0)\"],\n \"colorType\": \"scaleLinear\",\n \"contourLevels\": [\n 996, 1008, 1020, 1032, 1044, 1056, 1068, 1080, 1092, 1104, 1116, 1128, 1140\n ],\n \"ticks\": \"linear\"\n },\n \"difference\": {\n \"colorLevels\": [-28, -24, -20, -16, -12, -8, -4, 4, 8, 12, 16, 20, 24, 28]\n }\n },\n \"colorPrimary\": \"var(--fontcolor)\",\n \"nameLegend\": \"250 mb Height\",\n \"namePublic\": \"250 mb Height\",\n \"nameShort\": \"250mb Hgt\",\n \"roundto\": 1,\n \"roundtoReadout\": 0,\n \"units\": \"dam\"\n },\n \"gh300\": {\n \"defaults\": \"default\",\n \"colorBars\": {\n \"default\": {\n \"colorLevels\": [880, 920, 960, 980],\n \"colors\": [\"rgb(93,40,134)\", \"rgb(0,112,192)\", \"rgb(253,255,153)\", \"rgb(192,0,0)\"],\n \"colorType\": \"scaleLinear\",\n \"contourLevels\": [880, 920, 980],\n \"ticks\": \"linear\"\n },\n \"difference\": {\n \"colorLevels\": [-20, -15, -10, -8, -6, -4, -2, 2, 4, 6, 8, 10, 15, 20]\n }\n },\n \"colorPrimary\": \"var(--fontcolor)\",\n \"nameLegend\": \"300 mb Height\",\n \"namePublic\": \"300 mb Height\",\n \"nameShort\": \"300mb Hgt\",\n \"roundto\": 1,\n \"roundtoReadout\": 0,\n \"units\": \"dam\"\n },\n \"gh500\": {\n \"defaults\": \"gh300\",\n \"colorBars\": {\n \"default\": {\n \"colorLevels\": [500, 540, 580, 600],\n \"contourLevels\": [\n 498, 504, 510, 516, 522, 528, 534, 540, 546, 552, 558, 564, 570, 576, 582, 588,\n 594, 600, 606, 612, 618, 624\n ]\n }\n },\n \"nameLegend\": \"500 mb Height\",\n \"namePublic\": \"500 mb Height\",\n \"nameShort\": \"500 mb Hgt\"\n },\n \"gh500Climo\": {\n \"defaults\": \"gh300\",\n \"colorBars\": {\n \"default\": {\n \"colorLevels\": [\n 0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90, 95,\n 100\n ],\n \"colors\": [\n \"rgb(7,21,81)\",\n \"rgb(5,47,96)\",\n \"rgb(16,69,126)\",\n \"rgb(28,92,158)\",\n \"rgb(41,113,178)\",\n \"rgb(55,131,186)\",\n \"rgb(73,151,197)\",\n \"rgb(107,172,208)\",\n \"rgba(138,192,219)\",\n \"rgba(167,207,228)\",\n \"rgba(0, 0, 0, 0)\",\n \"rgb(0,0,0,0)\",\n \"rgb(253,224,207)\",\n \"rgb(250,204,180)\",\n \"rgb(247,183,153)\",\n \"rgb(241,158,124)\",\n \"rgb(228,128,102)\",\n \"rgb(216,101,81)\",\n \"rgb(201,70,65)\",\n \"rgb(185,39,50)\",\n \"rgb(164,19,40)\",\n \"rgb(131,9,34)\"\n ],\n \"colorType\": \"scaleThreshold\",\n \"contourLevels\": [\n 0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90, 95,\n 100\n ],\n \"isLeftCap\": true,\n \"isRightCap\": false,\n \"ticks\": \"byColorLevels\"\n }\n },\n \"nameLegend\": \"500 mb Height Climatology\",\n \"namePublic\": \"500 mb Height Climatology\",\n \"nameShort\": \"500 mb Hgt Climo\",\n \"roundto-readout_percentage\": 0,\n \"units\": \"percentile\"\n },\n \"gh1000-gh500\": {\n \"defaults\": \"gh300\",\n \"colorBars\": {\n \"default\": {\n \"colorLevels\": [\n 490, 500, 510, 520, 530, 540, 545, 550, 555, 560, 565, 570, 575, 580, 585, 590,\n 600, 605\n ],\n \"colors\": [\n \"rgb(48, 18, 59)\",\n \"rgb(63, 59, 152)\",\n \"rgb(70, 98, 215)\",\n \"rgb(70, 134, 250)\",\n \"rgb(53, 170, 249)\",\n \"rgb(30, 203, 219)\",\n \"rgb(26, 228, 182)\",\n \"rgb(60, 245, 141)\",\n \"rgb(114, 254, 94)\",\n \"rgb(163, 253, 60)\",\n \"rgb(200, 239, 52)\",\n \"rgb(231, 215, 57)\",\n \"rgb(250, 186, 57)\",\n \"rgb(254, 149, 43)\",\n \"rgb(246, 107, 25)\",\n \"rgb(228, 70, 11)\",\n \"rgb(202, 42, 4)\",\n \"rgb(167, 20, 1)\",\n \"rgb(122, 4, 3)\"\n ],\n \"colorType\": \"scaleThreshold\",\n \"contourLevels\": [\n 490, 500, 510, 520, 530, 540, 545, 550, 555, 560, 565, 570, 575, 580, 585, 590,\n 600, 605\n ],\n \"ticks\": \"byColorLevels\"\n }\n },\n \"nameLegend\": \"1000-500 mb Thickness\",\n \"namePublic\": \"1000-500 mb Thickness\",\n \"nameShort\": \"1000-500 mb Tkns\"\n },\n \"gh700-gh500_lr\": {\n \"defaults\": \"gh300\",\n \"colorBars\": {\n \"default\": {\n \"colorLevels\": [4, 5, 6, 6.5, 7, 7.5, 8, 8.5, 9],\n \"colors\": [\n \"rgb(5,48,97)\",\n \"rgb(33,102,172)\",\n \"rgb(67,147,195)\",\n \"rgb(146,197,222)\",\n \"rgb(209,229,240)\",\n \"rgb(253,219,199)\",\n \"rgb(244,165,130)\",\n \"rgb(214,96,77)\",\n \"rgb(178,24,43)\",\n \"rgb(103,0,31)\"\n ],\n \"colorType\": \"scaleThreshold\",\n \"contourLevels\": [4, 5, 6, 6.5, 7, 7.5, 8, 8.5, 9],\n \"ticks\": \"byColorLevels\"\n },\n \"spread\": {\n \"colorLevels\": [0, 0.5, 1, 1.5, 2, 2.5, 3]\n }\n },\n \"nameLegend\": \"700-500 mb Lapse Rate\",\n \"namePublic\": \"700-500 mb Lapse Rate\",\n \"nameShort\": \"700-500 mb LR\",\n \"roundto\": 2,\n \"roundtoReadout\": 1,\n \"units\": \"C/km\"\n },\n \"thte850\": {\n \"defaults\": \"gh300\",\n \"colorBars\": {\n \"default\": {\n \"colorLevels\": [\n 276, 279, 282, 285, 288, 291, 294, 297, 300, 303, 306, 309, 312, 315, 318, 321,\n 324, 327, 330, 333, 336, 339, 342, 345, 348, 351, 354, 357\n ],\n \"colors\": [\n \"rgb(218,218,235)\",\n \"rgb(201,199,224)\",\n \"rgb(185,183,217)\",\n \"rgb(173,159,204)\",\n \"rgb(119,159,200)\",\n \"rgb(133,177,214)\",\n \"rgb(151,195,223)\",\n \"rgb(173,210,232)\",\n \"rgb(201, 225, 238)\",\n \"rgb(223,235,246)\",\n \"rgb(134,191,153)\",\n \"rgb(150,208,166)\",\n \"rgb(178,222,179)\",\n \"rgb(204,234,201)\",\n \"rgb(224,242,220)\",\n \"rgb(240,249,238)\",\n \"rgb(254,241,228)\",\n \"rgb(253,229,204)\",\n \"rgb(253, 210, 173)\",\n \"rgb(253, 192, 148)\",\n \"rgb(252,173,155)\",\n \"rgb(246,147,139)\",\n \"rgb(226,128,131)\",\n \"rgb(206,123,126)\",\n \"rgb(185, 183, 217)\",\n \"rgb(201,199,224)\",\n \"rgb(218,218,235)\",\n \"rgb(234,234,244)\",\n \"rgb(246, 245, 249)\"\n ],\n \"colorType\": \"scaleThreshold\",\n \"contourLevels\": [\n 273, 276, 279, 282, 285, 288, 291, 294, 297, 300, 303, 306, 309, 312, 315, 318,\n 321, 324, 327, 330, 333, 336, 339, 342, 345, 348, 351, 354, 357\n ],\n \"ticks\": \"byColorLevels\"\n },\n \"spread\": {\n \"colorLevels\": [0, 5, 10, 15, 20, 25, 30]\n }\n },\n \"nameLegend\": \"850 mb Equivalent Potential Temperature\",\n \"namePublic\": \"850 mb Equivalent Potential Temperature\",\n \"nameShort\": \"850 mb Theta-E\",\n \"units\": \"K\"\n },\n \"thte925\": {\n \"defaults\": \"gh300\",\n \"colorBars\": {\n \"default\": {\n \"colorLevels\": [\n 276, 279, 282, 285, 288, 291, 294, 297, 300, 303, 306, 309, 312, 315, 318, 321,\n 324, 327, 330, 333, 336, 339, 342, 345, 348, 351, 354, 357\n ],\n \"colors\": [\n \"rgb(218,218,235)\",\n \"rgb(201,199,224)\",\n \"rgb(185,183,217)\",\n \"rgb(173,159,204)\",\n \"rgb(119,159,200)\",\n \"rgb(133,177,214)\",\n \"rgb(151,195,223)\",\n \"rgb(173,210,232)\",\n \"rgb(201,225,238)\",\n \"rgb(223,235,246)\",\n \"rgb(134,191,153)\",\n \"rgb(150,208,166)\",\n \"rgb(178,222,179)\",\n \"rgb(204,234,201)\",\n \"rgb(224,242,220)\",\n \"rgb(240,249,238)\",\n \"rgb(254,241,228)\",\n \"rgb(253,229,204)\",\n \"rgb(253,210,173)\",\n \"rgb(253,192,148)\",\n \"rgb(252,173,155)\",\n \"rgb(246,147,139)\",\n \"rgb(226,128,131)\",\n \"rgb(206,123,126)\",\n \"rgb(185,183,217)\",\n \"rgb(201,199,224)\",\n \"rgb(218,218,235)\",\n \"rgb(234,234,244)\",\n \"rgb(246,245,249)\"\n ],\n \"colorType\": \"scaleThreshold\",\n \"contourLevels\": [\n 276, 279, 282, 285, 288, 291, 294, 297, 300, 303, 306, 309, 312, 315, 318, 321,\n 324, 327, 330, 333, 336, 339, 342, 345, 348, 351, 354, 357\n ],\n \"ticks\": \"byColorLevels\"\n },\n \"spread\": {\n \"colorLevels\": [0, 5, 10, 15, 20, 25, 30]\n }\n },\n \"nameLegend\": \"925 mb Equivalent Potential Temperature\",\n \"namePublic\": \"925 mb Equivalent Potential Temperature\",\n \"nameShort\": \"925 mb Theta-E\",\n \"units\": \"K\"\n },\n \"thte2\": {\n \"defaults\": \"gh300\",\n \"colorBars\": {\n \"default\": {\n \"colorLevels\": [\n 276, 279, 282, 285, 288, 291, 294, 297, 300, 303, 306, 309, 312, 315, 318, 321,\n 324, 327, 330, 333, 336, 339, 342, 345, 348, 351, 354, 357\n ],\n \"colors\": [\n \"rgb(218,218,235)\",\n \"rgb(201,199,224)\",\n \"rgb(185,183,217)\",\n \"rgb(173,159,204)\",\n \"rgb(119,159,200)\",\n \"rgb(133,177,214)\",\n \"rgb(151,195,223)\",\n \"rgb(173,210,232)\",\n \"rgb(201,225,238)\",\n \"rgb(223,235,246)\",\n \"rgb(134,191,153)\",\n \"rgb(150,208,166)\",\n \"rgb(178,222,179)\",\n \"rgb(204,234,201)\",\n \"rgb(224,242,220)\",\n \"rgb(240,249,238)\",\n \"rgb(254,241,228)\",\n \"rgb(253,229,204)\",\n \"rgb(253,210,173)\",\n \"rgb(253,192,148)\",\n \"rgb(252,173,155)\",\n \"rgb(246,147,139)\",\n \"rgb(226,128,131)\",\n \"rgb(206,123,126)\",\n \"rgb(185,183,217)\",\n \"rgb(201,199,224)\",\n \"rgb(218,218,235)\",\n \"rgb(234,234,244)\",\n \"rgb(246,245,249)\"\n ],\n \"colorType\": \"scaleThreshold\",\n \"contourLevels\": [\n 276, 279, 282, 285, 288, 291, 294, 297, 300, 303, 306, 309, 312, 315, 318, 321,\n 324, 327, 330, 333, 336, 339, 342, 345, 348, 351, 354, 357\n ],\n \"ticks\": \"byColorLevels\"\n },\n \"spread\": {\n \"colorLevels\": [0, 5, 10, 15, 20, 25, 30]\n }\n },\n \"nameLegend\": \"Surface Equivalent Potential Temperature\",\n \"namePublic\": \"Surface Equivalent Potential Temperature\",\n \"nameShort\": \"Surface Theta-E\",\n \"units\": \"K\"\n },\n \"gh700\": {\n \"defaults\": \"gh300\",\n \"colorBars\": {\n \"default\": {\n \"colorLevels\": [260, 280, 310, 330],\n \"contourLevels\": [\n 261, 264, 267, 270, 273, 276, 279, 282, 285, 288, 291, 294, 297, 300, 303, 306,\n 309, 312, 315, 318, 321, 324, 327, 330\n ]\n }\n },\n \"nameLegend\": \"700 mb Height\",\n \"namePublic\": \"700 mb Height\",\n \"nameShort\": \"700mb Hgt\"\n },\n \"gh850\": {\n \"defaults\": \"gh300\",\n \"colorBars\": {\n \"default\": {\n \"colorLevels\": [120, 132, 147, 165],\n \"contourLevels\": [\n 120, 123, 126, 129, 132, 135, 138, 141, 144, 147, 150, 153, 156, 159, 162, 165\n ]\n }\n },\n \"nameLegend\": \"850 mb Height\",\n \"namePublic\": \"850 mb Height\",\n \"nameShort\": \"850mb Hgt\"\n },\n \"gh925\": {\n \"defaults\": \"gh300\",\n \"colorBars\": {\n \"default\": {\n \"colorLevels\": [45, 63, 78, 87],\n \"contourLevels\": [\n 33, 36, 39, 42, 45, 48, 51, 54, 57, 60, 63, 66, 69, 72, 75, 78, 81, 84, 87, 90,\n 93, 96, 99\n ]\n }\n },\n \"nameLegend\": \"925 mb Height\",\n \"namePublic\": \"925 mb Height\",\n \"nameShort\": \"925mb Hgt\"\n },\n \"gh_isobaric\": {\n \"defaults\": \"gh500\",\n \"nameLegend\": \"Isobaric Height\",\n \"namePublic\": \"Isobaric Height\",\n \"nameShort\": \"Isobaric Height\"\n },\n \"haines06\": {\n \"defaults\": \"default\",\n \"colorBars\": {\n \"default\": {\n \"colorLevels\": [0, 1, 2, 3, 4, 5, 6, 7],\n \"colors\": [\n \"rgba(150,150,150,0)\",\n \"rgba(150,150,150,0)\",\n \"rgb(64,202,52)\",\n \"rgb(246,247,41)\",\n \"rgb(244,172,42)\",\n \"rgb(255,0,0)\",\n \"rgb(150,0,0)\",\n \"rgb(200,0,200)\",\n \"rgb(255,255,255)\"\n ],\n \"colorType\": \"scaleThreshold\",\n \"contourLevels\": [1, 2, 3, 4],\n \"isLeftCap\": false,\n \"ticks\": \"linear\"\n }\n },\n \"colorPrimary\": \"rgb(247,135,59)\",\n \"isZeroLowerBound\": true,\n \"nameLegend\": \"Haines\",\n \"namePublic\": \"Haines\",\n \"nameShort\": \"Haines\",\n \"roundto\": 0,\n \"units\": \"\"\n },\n \"srh0-1km\": {\n \"defaults\": \"default\",\n \"colorBars\": {\n \"default\": {\n \"colorLevels\": [\n 25, 30, 35, 40, 45, 50, 60, 70, 80, 90, 100, 120, 140, 160, 180, 200, 240, 280,\n 320, 360, 400, 450, 500, 600, 700, 800\n ],\n \"colors\": [\n \"rgba(150,150,150,0)\",\n \"rgb(204,204,204)\",\n \"rgb(178,178,178)\",\n \"rgb(153,153,153)\",\n \"rgb(127,127,127)\",\n \"rgb(102,102,102)\",\n \"rgb(127,178,255)\",\n \"rgb(102,146,235)\",\n \"rgb(76,114,216)\",\n \"rgb(50,82,197)\",\n \"rgb(25,51,178)\",\n \"rgb(127,255,127)\",\n \"rgb(98,216,98)\",\n \"rgb(70,178,70)\",\n \"rgb(41,140,41)\",\n \"rgb(12,102,12)\",\n \"rgb(255,255,102)\",\n \"rgb(232,197,76)\",\n \"rgb(210,140,51)\",\n \"rgb(188,82,25)\",\n \"rgb(165,25,0)\",\n \"rgb(255,153,255)\",\n \"rgb(224,123,224)\",\n \"rgb(193,94,193)\",\n \"rgb(132,36,132)\",\n \"rgb(102,7,102)\",\n \"rgb(102,7,102)\"\n ],\n \"colorType\": \"scaleThreshold\",\n \"contourLevels\": [25, 50, 100, 200, 400, 800],\n \"isLeftCap\": false,\n \"ticks\": \"linear\"\n },\n \"difference\": {\n \"colorLevels\": [\n -175, -150, -125, -100, -75, -50, -25, 25, 50, 75, 100, 125, 150, 175\n ]\n },\n \"spread\": {\n \"colorLevels\": [0, 25, 50, 100, 150, 200]\n }\n },\n \"colorPrimary\": \"rgb(250,0,140)\",\n \"nameLegend\": \"0-1km SRH\",\n \"namePublic\": \"0-1km SRH\",\n \"nameShort\": \"0-1km SRH\",\n \"roundto\": 0,\n \"units\": \"m^2/s^2\"\n },\n \"srh0-3km\": {\n \"defaults\": \"srh0-1km\",\n \"colorPrimary\": \"rgb(200,0,100)\",\n \"nameLegend\": \"0-3km SRH\",\n \"namePublic\": \"0-3km SRH\",\n \"nameShort\": \"0-3km SRH\"\n },\n \"stp\": {\n \"defaults\": \"default\",\n \"colorBars\": {\n \"default\": {\n \"colorLevels\": [\n 0.1, 0.2, 0.4, 0.6, 0.8, 1, 1.2, 1.4, 1.6, 1.8, 2, 2.4, 2.8, 3.2, 3.6, 4, 4.4,\n 4.8, 5.2, 5.6, 6, 6.4, 6.8, 7.2, 7.6, 8\n ],\n \"colors\": [\n \"rgba(150,150,150,0)\",\n \"rgb(204,204,204)\",\n \"rgb(178,178,178)\",\n \"rgb(153,153,153)\",\n \"rgb(127,127,127)\",\n \"rgb(102,102,102)\",\n \"rgb(127,178,255)\",\n \"rgb(102,146,235)\",\n \"rgb(76,114,216)\",\n \"rgb(50,82,197)\",\n \"rgb(25,51,178)\",\n \"rgb(127,255,127)\",\n \"rgb(98,216,98)\",\n \"rgb(70,178,70)\",\n \"rgb(41,140,41)\",\n \"rgb(12,102,12)\",\n \"rgb(255,255,102)\",\n \"rgb(232,197,76)\",\n \"rgb(210,140,51)\",\n \"rgb(188,82,25)\",\n \"rgb(165,25,0)\",\n \"rgb(255,153,255)\",\n \"rgb(224,123,224)\",\n \"rgb(193,94,193)\",\n \"rgb(132,36,132)\",\n \"rgb(102,7,102)\",\n \"rgb(102,7,102)\"\n ],\n \"colorType\": \"scaleThreshold\",\n \"contourLevels\": [0.1, 0.2, 0.3, 0.4, 0.5, 1, 2, 3, 4, 5, 6, 7, 8],\n \"isLeftCap\": false,\n \"ticks\": \"linear\"\n },\n \"difference\": {\n \"colorLevels\": [\n -1.4, -1.2, -1, -0.8, -0.6, -0.4, -0.2, 0.2, 0.4, 0.6, 0.8, 1, 1.2, 1.4\n ]\n },\n \"spread\": {\n \"colorLevels\": [0, 0.2, 0.4, 0.6, 0.8, 1]\n }\n },\n \"colorPrimary\": \"rgb(250,0,0)\",\n \"nameLegend\": \"STP (fixed layer)\",\n \"namePublic\": \"STP (fixed layer)\",\n \"nameShort\": \"STP\",\n \"roundto\": 1,\n \"units\": \"\"\n },\n \"ltng\": {\n \"defaults\": \"default\",\n \"colorBars\": {\n \"default\": {\n \"colorLevels\": [0.01, 0.02, 0.5, 1, 2, 4, 5],\n \"colors\": [\n \"rgba(150,150,150,0)\",\n \"rgb(255,255,255)\",\n \"rgb(255,200,100)\",\n \"rgb(255, 195, 0)\",\n \"rgb(199, 0, 57)\",\n \"rgb(200, 0, 200)\",\n \"rgb(100, 0, 100)\"\n ],\n \"colorType\": \"scaleLinear\",\n \"contourLevels\": [0.01, 0.02, 0.5, 1, 2, 4, 5, 10],\n \"isLeftCap\": false,\n \"ticks\": \"byColorLevels\"\n },\n \"difference\": {\n \"colorLevels\": [-6, -5, -4, -3, -2, -1, -0.5, 0.5, 1, 2, 3, 4, 5, 6]\n }\n },\n \"colorPrimary\": \"rgb(255,144,0)\",\n \"nameLegend\": \"Lightning\",\n \"namePublic\": \"Lightning\",\n \"nameShort\": \"Lightning\",\n \"roundto\": 2,\n \"units\": \"flashes / km^2 / 5 min\"\n },\n \"mixingHgt\": {\n \"defaults\": \"default\",\n \"colorBars\": {\n \"default\": {\n \"colorLevels\": [0, 1, 3, 5, 7, 10, 15],\n \"colors\": [\n \"rgba(150,150,150,0)\",\n \"rgb(150,150,150)\",\n \"rgb(0,190,255)\",\n \"rgb(255,255,0)\",\n \"rgb(255,0,0)\",\n \"rgb(255,0,255)\",\n \"rgb(100,0,100)\"\n ],\n \"colorType\": \"scaleLinear\",\n \"contourLevels\": [1, 2, 3, 4, 5, 7, 10, 15],\n \"isLeftCap\": false,\n \"ticks\": \"linear\"\n }\n },\n \"colorPrimary\": \"rgb(200,200,200)\",\n \"nameLegend\": \"Mixing Height\",\n \"namePublic\": \"Mixing Height\",\n \"nameShort\": \"Mix Hgt\",\n \"roundto\": 1,\n \"units\": \"kft\"\n },\n \"mslp\": {\n \"defaults\": \"default\",\n \"colorBars\": {\n \"default\": {\n \"colorLevels\": [970, 1000, 1030],\n \"colors\": [\"rgb(49,54,149)\", \"rgb(255,255,191)\", \"rgb(165,0,38)\"],\n \"colorType\": \"scaleLinear\",\n \"contourLevels\": [\n 904, 908, 912, 916, 920, 924, 928, 932, 936, 940, 944, 948, 952, 956, 960, 964,\n 968, 972, 976, 980, 984, 988, 992, 996, 1000, 1004, 1008, 1012, 1016, 1020,\n 1024, 1028, 1032, 1036, 1040, 1044\n ],\n \"ticks\": \"linear\"\n }\n },\n \"colorPrimary\": \"rgb(200,200,200)\",\n \"nameLegend\": \"MSLP\",\n \"namePublic\": \"Mean Sea Level Pressure\",\n \"nameShort\": \"MSLP\",\n \"roundto\": 1,\n \"roundtoReadout\": 0,\n \"units\": \"mb\"\n },\n \"orog\": {\n \"defaults\": \"default\",\n \"colorBars\": {\n \"default\": {\n \"colorLevels\": [700, 800, 900, 1000, 1030],\n \"colors\": [\n \"rgb(165,0,38)\",\n \"rgb(255,255,191)\",\n \"rgb(49,54,149)\",\n \"rgb(49, 142, 149)\",\n \"rgb(97,97,97)\"\n ],\n \"colorType\": \"scaleLinear\",\n \"contourLevels\": [0, 1000, 2000, 3000, 4000],\n \"isLeftCap\": false,\n \"ticks\": \"linear\"\n }\n },\n \"colorPrimary\": \"rgb(200,200,200)\",\n \"nameLegend\": \"Terrain Height\",\n \"namePublic\": \"Terrain Height\",\n \"nameShort\": \"Terrain hgt\",\n \"roundto\": 0,\n \"units\": \"m\"\n },\n \"sp\": {\n \"defaults\": \"default\",\n \"colorBars\": {\n \"default\": {\n \"colorLevels\": [700, 800, 900, 1000, 1030],\n \"colors\": [\n \"rgb(97,97,97)\",\n \"rgb(49, 142, 149)\",\n \"rgb(49,54,149)\",\n \"rgb(255,255,191)\",\n \"rgb(165,0,38)\"\n ],\n \"colorType\": \"scaleLinear\",\n \"contourLevels\": [\n 904, 908, 912, 916, 920, 924, 928, 932, 936, 940, 944, 948, 952, 956, 960, 964,\n 968, 972, 976, 980, 984, 988, 992, 996, 1000, 1004, 1008, 1012, 1016, 1020,\n 1024, 1028, 1032, 1036, 1040, 1044\n ],\n \"ticks\": \"linear\"\n }\n },\n \"colorPrimary\": \"rgb(200,200,200)\",\n \"nameLegend\": \"Surface Pressure\",\n \"namePublic\": \"Surface Pressure\",\n \"nameShort\": \"sfc pres\",\n \"roundto\": 0,\n \"units\": \"mb\"\n },\n \"psnow\": {\n \"defaults\": \"default\",\n \"colorBars\": {\n \"default\": {\n \"colorLevels\": [0, 1],\n \"colors\": [\"rgba(150,150,150,0)\", \"rgb(0,0,255)\"],\n \"colorType\": \"scaleLinear\",\n \"contourLevels\": [0.1, 0.25, 0.5, 0.75, 1],\n \"isLeftCap\": false,\n \"isRightCap\": false,\n \"ticks\": \"linear\"\n },\n \"spread\": {\n \"colorLevels\": [0, 0.25, 0.5, 1]\n }\n },\n \"colorPrimary\": \"rgba(0, 130, 255, 1)\",\n \"nameLegend\": \"Probabilistic Snowfall\",\n \"namePublic\": \"Probabilistic Snowfall\",\n \"nameShort\": \"pSnow\",\n \"roundto\": 0,\n \"units\": \"%\"\n },\n \"csnow\": {\n \"defaults\": \"psnow\",\n \"nameLegend\": \"Conditional Snowfall\",\n \"namePublic\": \"Conditional Snowfall\",\n \"nameShort\": \"cSnow\"\n },\n \"prain\": {\n \"defaults\": \"default\",\n \"colorBars\": {\n \"default\": {\n \"colorLevels\": [0, 1],\n \"colors\": [\"rgba(150,150,150,0)\", \"rgb(0,255,0)\"],\n \"colorType\": \"scaleLinear\",\n \"contourLevels\": [0.1, 0.25, 0.5, 0.75, 1],\n \"isLeftCap\": false,\n \"isRightCap\": false,\n \"ticks\": \"linear\"\n },\n \"spread\": {\n \"colorLevels\": [0, 0.25, 0.5, 1]\n }\n },\n \"colorPrimary\": \"rgb(35,187,118)\",\n \"nameLegend\": \"Probabilistic Rain\",\n \"namePublic\": \"Probabilistic Rain\",\n \"nameShort\": \"pRain\",\n \"roundto\": 0,\n \"units\": \"%\"\n },\n \"crain\": {\n \"defaults\": \"prain\",\n \"nameLegend\": \"Conditional Rain\",\n \"namePublic\": \"Conditional Rain\",\n \"nameShort\": \"cRain\"\n },\n \"picep\": {\n \"defaults\": \"default\",\n \"colorBars\": {\n \"default\": {\n \"colorLevels\": [0, 1],\n \"colors\": [\"rgba(150,150,150,0)\", \"rgb(255,0,255)\"],\n \"colorType\": \"scaleLinear\",\n \"contourLevels\": [0.1, 0.25, 0.5, 0.75, 1],\n \"isLeftCap\": false,\n \"isRightCap\": false,\n \"ticks\": \"linear\"\n },\n \"spread\": {\n \"colorLevels\": [0, 0.25, 0.5, 1]\n }\n },\n \"colorPrimary\": \"rgb(102, 0, 204)\",\n \"nameLegend\": \"Probabilistic Sleet\",\n \"namePublic\": \"Probabilistic Sleet\",\n \"nameShort\": \"pSleet\",\n \"roundto\": 0,\n \"units\": \"%\"\n },\n \"cicep\": {\n \"defaults\": \"picep\",\n \"nameLegend\": \"Conditional Sleet\",\n \"namePublic\": \"Conditional Sleet\",\n \"nameShort\": \"cSleet\"\n },\n \"pfrzr\": {\n \"defaults\": \"default\",\n \"colorBars\": {\n \"default\": {\n \"colorLevels\": [0, 1],\n \"colors\": [\"rgba(150,150,150,0)\", \"rgb(255,50,0)\"],\n \"colorType\": \"scaleLinear\",\n \"contourLevels\": [0.1, 0.25, 0.5, 0.75, 1],\n \"isLeftCap\": false,\n \"isRightCap\": false,\n \"ticks\": \"linear\"\n },\n \"spread\": {\n \"colorLevels\": [0, 0.25, 0.5, 1]\n }\n },\n \"colorPrimary\": \"rgb(255, 100, 255)\",\n \"nameLegend\": \"Probabilistic Freezing Rain\",\n \"namePublic\": \"Probabilistic Freezing Rain\",\n \"nameShort\": \"pFrzr\",\n \"roundto\": 0,\n \"units\": \"%\"\n },\n \"cfrzr\": {\n \"defaults\": \"pfrzr\",\n \"nameLegend\": \"Conditional Freezing Rain\",\n \"namePublic\": \"Conditional Freezing Rain\",\n \"nameShort\": \"cFrzr\"\n },\n \"prmsl\": {\n \"defaults\": \"default\",\n \"roundto\": 0,\n \"units\": \"hPa\"\n },\n \"pw\": {\n \"defaults\": \"default\",\n \"colorBars\": {\n \"default\": {\n \"colorLevels\": [0, 0.5, 1, 1.5, 2, 2.5, 3],\n \"colors\": [\n \"rgb(100, 54, 2)\",\n \"rgb(171, 93, 3)\",\n \"rgb(255, 255, 255)\",\n \"rgb(42, 137, 129)\",\n \"rgb(41, 100, 144)\",\n \"rgb(40, 66, 157)\",\n \"rgb(6, 19, 68)\"\n ],\n \"colorType\": \"scaleLinear\",\n \"contourLevels\": [\n 0.25, 0.5, 0.75, 1, 1.25, 1.5, 1.75, 2, 2.25, 2.5, 2.75, 3, 3.25, 3.5\n ],\n \"isLeftCap\": false,\n \"ticks\": \"linear\"\n },\n \"difference\": {\n \"colorLevels\": [\n -2, -1, -0.75, -0.5, -0.25, -0.1, -0.05, 0.05, 0.1, 0.25, 0.5, 0.75, 1, 2\n ]\n },\n \"spread\": {\n \"colorLevels\": [0, 0.1, 0.25, 0.5, 0.75, 1]\n }\n },\n \"colorPrimary\": \"rgb(0,200,0)\",\n \"nameLegend\": \"Precipitable Water\",\n \"namePublic\": \"Precipitable Water\",\n \"nameShort\": \"PW\",\n \"roundto\": 2,\n \"units\": \"in\"\n },\n \"p1\": {\n \"defaults\": \"default\",\n \"colorBars\": {\n \"default\": {\n \"colorLevels\": [\n 0, 0.01, 0.05, 0.1, 0.15, 0.2, 0.25, 0.5, 0.75, 1, 1.5, 2, 2.5, 3, 3.5, 4, 5\n ],\n \"colors\": [\n \"rgba(150,150,150,0)\",\n \"rgba(150,150,150,0)\",\n \"rgb(199,233,192)\",\n \"rgb(161,217,155)\",\n \"rgb(116,196,118)\",\n \"rgb(49,163,83)\",\n \"rgb(0,109,44)\",\n \"rgb(255,250,138)\",\n \"rgb(255,204,79)\",\n \"rgb(254,141,60)\",\n \"rgb(252,78,42)\",\n \"rgb(214,26,28)\",\n \"rgb(173,0,38)\",\n \"rgb(112,0,38)\",\n \"rgb(59,0,48)\",\n \"rgb(76,0,115)\",\n \"rgb(100,100,255)\",\n \"rgb(175,175,255)\"\n ],\n \"colorType\": \"scaleThreshold\",\n \"contourLevels\": [\n 0.01, 0.05, 0.1, 0.15, 0.2, 0.25, 0.5, 0.75, 1, 1.5, 2, 2.5, 3, 3.5, 4, 5\n ],\n \"isLeftCap\": false,\n \"ticks\": \"byColorLevels\"\n },\n \"difference\": {\n \"colorLevels\": [\n -0.5, -0.25, -0.2, -0.15, -0.1, -0.05, -0.01, 0.01, 0.05, 0.1, 0.15, 0.2, 0.25,\n 0.5\n ]\n },\n \"spread\": {\n \"colorLevels\": [0, 0.05, 0.1, 0.25, 0.5, 1]\n }\n },\n \"colorPrimary\": \"rgb(50,255,50)\",\n \"nameLegend\": \"1 hr Precipitation\",\n \"namePublic\": \"1 hr Precipitation\",\n \"nameShort\": \"1hr Precip\",\n \"roundto\": 2,\n \"units\": \"in\"\n },\n \"p2\": {\n \"defaults\": \"p1\",\n \"nameLegend\": \"2 hr Precipitation\",\n \"namePublic\": \"2 hr Precipitation\",\n \"nameShort\": \"2hr Precip\"\n },\n \"p3\": {\n \"defaults\": \"p1\",\n \"colorBars\": {\n \"default\": {\n \"colorLevels\": [0, 0.01, 0.1, 0.25, 0.5, 0.75, 1, 1.5, 2, 3, 4, 5, 6, 7, 8, 10, 15],\n \"contourLevels\": [0.01, 0.1, 0.25, 0.5, 0.75, 1, 1.5, 2, 3, 4, 5, 6, 7, 8, 10, 15]\n },\n \"difference\": {\n \"colorLevels\": [\n -2, -1, -0.75, -0.5, -0.25, -0.1, -0.01, 0.01, 0.1, 0.25, 0.5, 0.75, 1, 2\n ]\n },\n \"spread\": {\n \"colorLevels\": [0, 0.05, 0.1, 0.25, 0.5, 1]\n }\n },\n \"nameLegend\": \"3 hr Precipitation\",\n \"namePublic\": \"3 hr Precipitation\",\n \"nameShort\": \"3hr Precip\"\n },\n \"p6\": {\n \"defaults\": \"p1\",\n \"colorBars\": {\n \"default\": {\n \"colorLevels\": [0, 0.01, 0.1, 0.25, 0.5, 0.75, 1, 1.5, 2, 3, 4, 5, 6, 7, 8, 10, 15],\n \"contourLevels\": [0.01, 0.1, 0.25, 0.5, 0.75, 1, 1.5, 2, 3, 4, 5, 6, 7, 8, 10, 15]\n },\n \"difference\": {\n \"colorLevels\": [\n -2, -1, -0.75, -0.5, -0.25, -0.1, -0.01, 0.01, 0.1, 0.25, 0.5, 0.75, 1, 2\n ]\n },\n \"spread\": {\n \"colorLevels\": [0, 0.05, 0.1, 0.25, 0.5, 1]\n }\n },\n \"nameLegend\": \"6 hr Precipitation\",\n \"namePublic\": \"6 hr Precipitation\",\n \"nameShort\": \"6hr Precip\"\n },\n \"p6qmd\": {\n \"defaults\": \"p6\",\n \"nameLegend\": \"QMD 6 hr Precipitation\",\n \"namePublic\": \"6 hr Precipitation\",\n \"nameShort\": \"QMD 6hr Precip\"\n },\n \"p6Det\": {\n \"defaults\": \"p6\"\n },\n \"p6_ari\": {\n \"defaults\": \"default\",\n \"colorBars\": {\n \"default\": {\n \"colorLevels\": [\n 0, 1, 2, 3, 4, 6, 8, 10, 20, 30, 40, 50, 75, 100, 150, 250, 500, 750, 1000\n ],\n \"colors\": [\n \"rgba(94, 79, 162, 0)\",\n \"rgba(94, 79, 162, 0)\",\n \"rgba(63, 120, 181, 1)\",\n \"rgba(72, 161, 179, 1)\",\n \"rgba(112, 198, 165, 1)\",\n \"rgba(161, 217, 164, 1)\",\n \"rgba(205, 235, 157, 1)\",\n \"rgba(237, 248, 163, 1)\",\n \"rgba(255, 255, 191, 1)\",\n \"rgba(254, 233, 154, 1)\",\n \"rgba(254, 203, 121, 1)\",\n \"rgba(252, 165, 93, 1)\",\n \"rgba(245, 118, 71, 1)\",\n \"rgba(226, 82, 74, 1)\",\n \"rgba(197, 45, 75, 1)\",\n \"rgba(158, 1, 66, 1)\",\n \"rgba(120, 0, 120, 1)\",\n \"rgba(77, 0, 153,1)\",\n \"rgba(50, 0, 100, 1)\",\n \"rgba(0, 0, 0, 1)\"\n ],\n \"colorType\": \"scaleThreshold\",\n \"contourLevels\": [\n 0, 1, 2, 3, 4, 6, 8, 10, 20, 30, 40, 50, 75, 100, 150, 250, 500, 750, 1000\n ],\n \"isLeftCap\": false,\n \"ticks\": \"byColorLevels\"\n },\n \"difference\": {\n \"colorLevels\": [-50, -40, -30, -20, -10, -5, -1, 1, 5, 10, 20, 30, 40, 50]\n },\n \"spread\": {\n \"colorLevels\": [0, 1, 5, 10, 25, 50]\n }\n },\n \"colorPrimary\": \"rgb(50,255,50)\",\n \"nameLegend\": \"6 hr Precip ARI\",\n \"namePublic\": \"6 hr Precipitation ARI\",\n \"nameShort\": \"6hr Precip ARI\",\n \"roundto\": 0,\n \"units\": \"yr\"\n },\n \"p6Det_ari\": {\n \"defaults\": \"p6_ari\"\n },\n \"p12\": {\n \"defaults\": \"p6\",\n \"nameLegend\": \"12 hr Precipitation\",\n \"namePublic\": \"12 hr Precipitation\",\n \"nameShort\": \"12hr Precip\"\n },\n \"p12Det\": {\n \"defaults\": \"p12\"\n },\n \"p24\": {\n \"defaults\": \"p6\",\n \"colorBars\": {\n \"default\": {\n \"colorLevels\": [\n 0, 0.01, 0.1, 0.25, 0.5, 0.75, 1, 1.5, 2, 3, 4, 5, 6, 8, 10, 15, 20\n ],\n \"contourLevels\": [0.01, 0.1, 0.25, 0.5, 0.75, 1, 1.5, 2, 3, 4, 5, 6, 8, 10, 15, 20]\n },\n \"difference\": {\n \"colorLevels\": [\n -2, -1, -0.75, -0.5, -0.25, -0.1, -0.01, 0.01, 0.1, 0.25, 0.5, 0.75, 1, 2\n ]\n },\n \"spread\": {\n \"colorLevels\": [0, 0.1, 0.25, 0.5, 1, 2]\n }\n },\n \"nameLegend\": \"24 hr Precipitation\",\n \"namePublic\": \"24 hr Precipitation\",\n \"nameShort\": \"24hr Precip\"\n },\n \"p24qmd\": {\n \"defaults\": \"p24\",\n \"nameLegend\": \"QMD 24 hr Precipitation\",\n \"namePublic\": \"24 hr Precipitation\",\n \"nameShort\": \"QMD 24hr Precip\"\n },\n \"p24_ari\": {\n \"defaults\": \"p6_ari\",\n \"nameLegend\": \"24 hr Precip ARI\",\n \"namePublic\": \"24 hr Precipitation ARI\",\n \"nameShort\": \"24hr Precip ARI\"\n },\n \"ptotal\": {\n \"defaults\": \"p24\",\n \"colorBars\": {\n \"default\": {\n \"colorLevels\": [0, 0.01, 0.1, 0.25, 0.5, 1, 1.5, 2, 3, 4, 6, 8, 10, 15, 20, 30, 50],\n \"contourLevels\": [0.01, 0.1, 0.25, 0.5, 1, 1.5, 2, 3, 4, 6, 8, 10, 15, 20, 30, 50]\n },\n \"difference\": {\n \"colorLevels\": [-8, -4, -2, -1, -0.5, -0.25, -0.1, 0.1, 0.25, 0.5, 1, 2, 4, 8]\n },\n \"spread\": {\n \"colorLevels\": [0, 0.25, 0.5, 1, 2, 3]\n }\n },\n \"nameLegend\": \"Accumulated Precipitation\",\n \"namePublic\": \"Accumulated Precipitation\",\n \"nameShort\": \"Acc Precip\",\n \"roundto\": 2\n },\n \"ptotalDet\": {\n \"defaults\": \"ptotal\"\n },\n \"p48\": {\n \"defaults\": \"ptotal\",\n \"nameLegend\": \"48 hr Precipitation\",\n \"namePublic\": \"48 hr Precipitation\",\n \"nameShort\": \"48hr Precip\"\n },\n \"p48_ari\": {\n \"defaults\": \"p6_ari\",\n \"nameLegend\": \"48 hr Precip ARI\",\n \"namePublic\": \"48 hr Precipitation ARI\",\n \"nameShort\": \"48hr Precip ARI\"\n },\n \"p72\": {\n \"defaults\": \"ptotal\",\n \"nameLegend\": \"72 hr Precipitation\",\n \"namePublic\": \"72 hr Precipitation\",\n \"nameShort\": \"72hr Precip\"\n },\n \"p72_ari\": {\n \"defaults\": \"p6_ari\",\n \"nameLegend\": \"72 hr Precip ARI\",\n \"namePublic\": \"72 hr Precipitation ARI\",\n \"nameShort\": \"72hr Precip ARI\"\n },\n \"PSSF\": {\n \"defaults\": \"default\",\n \"colorBars\": {\n \"default\": {\n \"colorLevels\": [0.5, 2.5, 3.5, 4.5, 5.5],\n \"colors\": [\n \"rgb(150,150,150,0)\",\n \"rgb(0,113,254)\",\n \"rgb(255,255,0)\",\n \"rgb(255,170,1)\",\n \"rgb(254,0,0)\",\n \"rgb(254,0,0)\"\n ],\n \"colorType\": \"scaleThreshold\",\n \"contourLevels\": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 15, 18, 21],\n \"isLeftCap\": false,\n \"tickAngle\": -90,\n \"ticks\": \"byColorLevels\",\n \"tickValues\": [\"< 3 feet\", \"> 3 feet\", \"> 6 feet\", \"> 9 feet\"]\n }\n },\n \"colorPrimary\": \"rgb(255,0,0)\",\n \"comment\": \"Values found here https://www.nhc.noaa.gov/gis/inundation/potential_storm_surge_flooding_downloads_guide.pdf\",\n \"nameLegend\": \"Storm Surge\",\n \"namePublic\": \"Storm Surge\",\n \"nameShort\": \"Storm Surge\",\n \"roundto\": 1,\n \"units\": \"class\"\n },\n \"refc\": {\n \"defaults\": \"default\",\n \"colorBars\": {\n \"default\": {\n \"colorLevels\": [1, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70],\n \"colors\": [\n \"rgba(150,150,150,0)\",\n \"rgba(0,255,255,0.2)\",\n \"rgba(0,233,231,0.5)\",\n \"rgb(5,158,244)\",\n \"rgb(11,0,244)\",\n \"rgb(16,253,3)\",\n \"rgb(8,197,2)\",\n \"rgb(0,142,1)\",\n \"rgb(253,248,4)\",\n \"rgb(230,188,14)\",\n \"rgb(253,138,2)\",\n \"rgb(253,2,3)\",\n \"rgb(212,1,6)\",\n \"rgb(188,1,0)\",\n \"rgb(248,3,254)\",\n \"rgb(230,230,230)\"\n ],\n \"colorType\": \"scaleThreshold\",\n \"contourLevels\": [1, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70],\n \"isLeftCap\": true,\n \"ticks\": \"byColorLevels\"\n },\n \"difference\": {\n \"colorLevels\": [-40, -30, -25, -20, -15, -10, -5, 5, 10, 15, 20, 25, 30, 40]\n }\n },\n \"colorPrimary\": \"rgb(0,220,150)\",\n \"nameLegend\": \"Composite Reflectivity\",\n \"namePublic\": \"Composite Reflectivity\",\n \"nameShort\": \"Ref\",\n \"roundto\": 0,\n \"units\": \"dBZ\"\n },\n \"refcMax\": {\n \"defaults\": \"refc\",\n \"nameLegend\": \"Max 1 hr Reflectivity\",\n \"namePublic\": \"Max 1 hr Reflectivity\",\n \"nameShort\": \"Refc\"\n },\n \"retop\": {\n \"defaults\": \"default\",\n \"colorBars\": {\n \"default\": {\n \"colorLevels\": [1, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70],\n \"colors\": [\n \"rgba(150,150,150,0)\",\n \"rgba(0,255,255,0.2)\",\n \"rgba(0,233,231,0.5)\",\n \"rgb(5,158,244)\",\n \"rgb(11,0,244)\",\n \"rgb(16,253,3)\",\n \"rgb(8,197,2)\",\n \"rgb(0,142,1)\",\n \"rgb(253,248,4)\",\n \"rgb(230,188,14)\",\n \"rgb(253,138,2)\",\n \"rgb(253,2,3)\",\n \"rgb(212,1,6)\",\n \"rgb(188,1,0)\",\n \"rgb(248,3,254)\",\n \"rgb(230,230,230)\"\n ],\n \"colorType\": \"scaleThreshold\",\n \"contourLevels\": [1, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70],\n \"isLeftCap\": true,\n \"ticks\": \"byColorLevels\"\n },\n \"difference\": {\n \"colorLevels\": [-40, -30, -25, -20, -15, -10, -5, 5, 10, 15, 20, 25, 30, 40]\n }\n },\n \"colorPrimary\": \"rgb(0,220,220)\",\n \"nameLegend\": \"18 dBZ Echo Top\",\n \"namePublic\": \"18 dBZ Echo Top\",\n \"nameShort\": \"Echo Top\",\n \"roundto\": 0,\n \"units\": \"kft\"\n },\n \"rh2\": {\n \"defaults\": \"default\",\n \"colorBars\": {\n \"default\": {\n \"colorLevels\": [\n 5, 7.5, 10, 12.5, 15, 17.5, 20, 22.5, 25, 27.5, 30, 32.5, 35, 37.5, 40, 50, 60,\n 70, 80, 90\n ],\n \"colors\": [\n \"rgb(171,115,122)\",\n \"rgb(205,123,126)\",\n \"rgb(227,128,131)\",\n \"rgb(240,146,139)\",\n \"rgb(243,172,154)\",\n \"rgb(244,172,125)\",\n \"rgb(247,192,148)\",\n \"rgb(249,210,173)\",\n \"rgb(252,229,204)\",\n \"rgb(179,179,179)\",\n \"rgb(198,198,198)\",\n \"rgb(218,218,218)\",\n \"rgb(234,234,234)\",\n \"rgb(246,246,246)\",\n \"rgb(255,255,255)\",\n \"rgb(236,244,250)\",\n \"rgb(223,235,246)\",\n \"rgb(202,225,238)\",\n \"rgb(174,210,232)\",\n \"rgb(152,195,223)\",\n \"rgb(133,177,214)\"\n ],\n \"colorType\": \"scaleThreshold\",\n \"contourLevels\": [0, 5, 10, 15, 20, 25, 30, 40, 50, 60, 70, 80, 90, 100],\n \"ticks\": \"linear\"\n },\n \"difference\": {\n \"colorLevels\": [-40, -30, -25, -20, -15, -10, -5, 5, 10, 15, 20, 25, 30, 40]\n },\n \"spread\": {\n \"colorLevels\": [0, 5, 10, 15, 20, 25]\n }\n },\n \"colorPrimary\": \"rgb(252,98,3)\",\n \"isZeroLowerBound\": true,\n \"nameLegend\": \"2m Relative Humidity\",\n \"namePublic\": \"Relative Humidity\",\n \"nameShort\": \"RH\",\n \"roundto\": 0,\n \"units\": \"%\"\n },\n \"r_isobaric\": {\n \"defaults\": \"rh2\",\n \"nameLegend\": \"Isobaric RH\",\n \"namePublic\": \"Isobaric RH\",\n \"nameShort\": \"Isobaric RH\"\n },\n \"rh2Max\": {\n \"defaults\": \"rh2\",\n \"colorPrimary\": \"rgb(255,193,7)\",\n \"nameLegend\": \"Relative Humidity\",\n \"namePublic\": \"Max Relative Humidity\",\n \"nameShort\": \"Max RH\"\n },\n \"rhll\": {\n \"defaults\": \"rh2\",\n \"colorPrimary\": \"rgb(255,193,7)\",\n \"nameLegend\": \"Lowest Layer Relative Humidity\",\n \"namePublic\": \"Lowest Layer Relative Humidity\",\n \"nameShort\": \"LL RH\"\n },\n \"rh2Min\": {\n \"defaults\": \"rh2\",\n \"colorPrimary\": \"rgb(240,240,0)\",\n \"nameLegend\": \"Relative Humidity\",\n \"namePublic\": \"Min Relative Humidity\",\n \"nameShort\": \"Min RH\"\n },\n \"r250\": {\n \"defaults\": \"rh2\",\n \"colorBars\": {\n \"spread\": {\n \"colorLevels\": [0, 10, 20, 30, 40, 50]\n }\n },\n \"nameLegend\": \"250 mb RH\",\n \"namePublic\": \"250 mb RH\",\n \"nameShort\": \"250mb RH\"\n },\n \"r500\": {\n \"defaults\": \"rh2\",\n \"colorBars\": {\n \"spread\": {\n \"colorLevels\": [0, 10, 20, 30, 40, 50]\n }\n },\n \"nameLegend\": \"500 mb RH\",\n \"namePublic\": \"500 mb RH\",\n \"nameShort\": \"500mb RH\"\n },\n \"r700\": {\n \"defaults\": \"rh2\",\n \"colorBars\": {\n \"spread\": {\n \"colorLevels\": [0, 10, 20, 30, 40, 50]\n }\n },\n \"nameLegend\": \"700 mb RH\",\n \"namePublic\": \"700 mb RH\",\n \"nameShort\": \"700mb RH\"\n },\n \"r850\": {\n \"defaults\": \"rh2\",\n \"colorBars\": {\n \"spread\": {\n \"colorLevels\": [0, 10, 20, 30, 40, 50]\n }\n },\n \"nameLegend\": \"850 mb RH\",\n \"namePublic\": \"850 mb RH\",\n \"nameShort\": \"850mb RH\"\n },\n \"r925\": {\n \"defaults\": \"rh2\",\n \"colorBars\": {\n \"spread\": {\n \"colorLevels\": [0, 10, 20, 30, 40, 50]\n }\n },\n \"nameLegend\": \"925 mb RH\",\n \"namePublic\": \"925 mb RH\",\n \"nameShort\": \"925mb RH\"\n },\n \"smokesfc\": {\n \"defaults\": \"default\",\n \"colorBars\": {\n \"default\": {\n \"colorLevels\": [0, 1, 25, 50, 100, 150, 200, 250],\n \"colors\": [\n \"rgba(0,0,0,0)\",\n \"rgba(0,0,0,0)\",\n \"rgb(201, 201, 201)\",\n \"rgb(236, 186, 79)\",\n \"rgb(238, 159, 67)\",\n \"rgb(200, 93, 30)\",\n \"rgb(147, 63, 17)\",\n \"rgb(93, 33, 4)\"\n ],\n \"colorType\": \"scaleLinear\",\n \"contourLevels\": [1, 25, 50, 100, 150, 200, 250],\n \"isLeftCap\": false,\n \"ticks\": \"linear\"\n }\n },\n \"colorPrimary\": \"rgb(250,0,0)\",\n \"nameLegend\": \"Near Surface Smoke\",\n \"namePublic\": \"Near Surface Smoke\",\n \"nameShort\": \"Smoke\",\n \"roundto\": 1,\n \"roundtoReadout\": 0,\n \"units\": \"µg/m^3\"\n },\n \"smoke\": {\n \"defaults\": \"smokesfc\",\n \"nameLegend\": \"Smoke\",\n \"namePublic\": \"Smoke\",\n \"nameShort\": \"Smoke\"\n },\n \"smokeVI\": {\n \"defaults\": \"default\",\n \"colorBars\": {\n \"default\": {\n \"colorLevels\": [0, 1, 25, 50, 100, 150, 250],\n \"colors\": [\n \"rgba(0,0,0,0)\",\n \"rgba(0,0,0,0)\",\n \"rgb(201, 201, 201)\",\n \"rgb(236, 186, 79)\",\n \"rgb(238, 159, 67)\",\n \"rgb(200, 93, 30)\",\n \"rgb(93, 33, 4)\"\n ],\n \"colorType\": \"scaleLinear\",\n \"contourLevels\": [1, 25, 50, 100, 150, 200, 250],\n \"isLeftCap\": false,\n \"ticks\": \"linear\"\n }\n },\n \"colorPrimary\": \"rgb(255,0,200)\",\n \"nameLegend\": \"Vertically Integrated Smoke\",\n \"namePublic\": \"Vertically Integrated Smoke\",\n \"nameShort\": \"Smoke\",\n \"roundto\": 1,\n \"roundtoReadout\": 0,\n \"units\": \"mg/m^2\"\n },\n \"swe1\": {\n \"defaults\": \"default\",\n \"colorBars\": {\n \"default\": {\n \"colorLevels\": [0, 0.1, 0.2, 0.3, 0.5, 0.75, 1, 1.25, 1.5, 1.75, 2, 2.5, 3],\n \"colors\": [\n \"rgba(150,150,150,0)\",\n \"rgba(150,150,150,0)\",\n \"rgb(189,215,231)\",\n \"rgb(107,174,214)\",\n \"rgb(49,130,189)\",\n \"rgb(8,81,156)\",\n \"rgb(23,60,148)\",\n \"rgb(255,255,150)\",\n \"rgb(255,196,0)\",\n \"rgb(255,135,0)\",\n \"rgb(219,20,0)\",\n \"rgb(158,0,0)\",\n \"rgb(105,0,0)\",\n \"rgb(50,0,0)\"\n ],\n \"colorType\": \"scaleThreshold\",\n \"contourLevels\": [0.1, 0.2, 0.3, 0.5, 0.75, 1, 1.25, 1.5, 1.75, 2, 2.5, 3],\n \"isLeftCap\": false,\n \"ticks\": \"byColorLevels\"\n },\n \"spread\": {\n \"colorLevels\": [0, 0.25, 0.5, 1, 1.5, 2]\n }\n },\n \"colorPrimary\": \"rgb(0,150,235)\",\n \"nameLegend\": \"1 Hour Snowfall (10:1)\",\n \"namePublic\": \"1 Hour Snowfall (10:1)\",\n \"nameShort\": \"Snow\",\n \"roundto\": 1,\n \"roundtoReadout\": 1,\n \"units\": \"in10\"\n },\n \"snow1\": {\n \"defaults\": \"swe1\",\n \"nameLegend\": \"1 Hour Snowfall\",\n \"namePublic\": \"1 Hour Snowfall\",\n \"units\": \"in\"\n },\n \"snow1MaxTAloft\": {\n \"defaults\": \"swe1\",\n \"nameLegend\": \"1 Hour Snowfall (maxTAloft)\",\n \"units\": \"in\"\n },\n \"swe3\": {\n \"defaults\": \"swe1\",\n \"colorBars\": {\n \"default\": {\n \"colorLevels\": [0, 0.1, 0.5, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10],\n \"contourLevels\": [0.1, 0.5, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]\n }\n },\n \"colorPrimary\": \"rgb(0,150,235)\",\n \"nameLegend\": \"3 Hour Snowfall (10:1)\",\n \"namePublic\": \"3 Hour Snowfall (10:1)\",\n \"roundto\": 1,\n \"roundtoReadout\": 0\n },\n \"snow3MaxTAloft\": {\n \"defaults\": \"swe1\",\n \"nameLegend\": \"3 Hour Snowfall (maxTAloft)\",\n \"units\": \"in\"\n },\n \"swe6\": {\n \"defaults\": \"swe1\",\n \"colorBars\": {\n \"default\": {\n \"colorLevels\": [0, 0.1, 0.5, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10],\n \"contourLevels\": [0.1, 0.5, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]\n }\n },\n \"colorPrimary\": \"rgb(0,150,235)\",\n \"nameLegend\": \"6 Hour Snowfall (10:1)\",\n \"namePublic\": \"6 Hour Snowfall (10:1)\",\n \"roundto\": 1,\n \"roundtoReadout\": 0\n },\n \"snow6\": {\n \"defaults\": \"swe6\",\n \"nameLegend\": \"6 hr Snowfall\",\n \"namePublic\": \"6 hr Snowfall\",\n \"units\": \"in\"\n },\n \"snow6MaxTAloft\": {\n \"defaults\": \"swe6\",\n \"nameLegend\": \"6 Hour Snowfall (maxTAloft)\",\n \"units\": \"in\"\n },\n \"swe24\": {\n \"defaults\": \"swe6\",\n \"colorBars\": {\n \"default\": {\n \"colorLevels\": [0, 0.1, 1, 2, 3, 4, 6, 8, 12, 18, 24, 30, 36],\n \"contourLevels\": [0.1, 1, 2, 3, 4, 6, 8, 12, 18, 24, 30, 36]\n },\n \"spread\": {\n \"colorLevels\": [1, 2, 3, 4, 5, 6]\n }\n },\n \"nameLegend\": \"24 Hour Snowfall (10:1)\",\n \"namePublic\": \"24 Hour Snowfall (10:1)\",\n \"nameShort\": \"Snow\"\n },\n \"snow24\": {\n \"defaults\": \"swe24\",\n \"nameLegend\": \"24 Hour Snowfall\",\n \"namePublic\": \"24 Hour Snowfall\",\n \"units\": \"in\"\n },\n \"snow24MaxTAloft\": {\n \"defaults\": \"swe24\",\n \"nameLegend\": \"24 Hour Snowfall (maxTAloft)\",\n \"units\": \"in\"\n },\n \"snow48\": {\n \"defaults\": \"swe24\",\n \"nameLegend\": \"48 Hour Snowfall\",\n \"namePublic\": \"48 Hour Snowfall\",\n \"units\": \"in\"\n },\n \"snow72\": {\n \"defaults\": \"swe24\",\n \"nameLegend\": \"72 Hour Snowfall\",\n \"namePublic\": \"72 Hour Snowfall\",\n \"units\": \"in\"\n },\n \"swetotal\": {\n \"defaults\": \"swe24\",\n \"colorPrimary\": \"rgb(0,0,200)\",\n \"nameLegend\": \"Accumulated Snowfall (10:1)\",\n \"namePublic\": \"Accumulated Snowfall (10:1)\",\n \"nameShort\": \"Snow\"\n },\n \"snowTotal\": {\n \"defaults\": \"swetotal\",\n \"nameLegend\": \"Accumulated Snowfall\",\n \"namePublic\": \"Accumulated Snowfall\",\n \"units\": \"in\"\n },\n \"snowTotalMaxTAloft\": {\n \"defaults\": \"swetotal\",\n \"nameLegend\": \"Accumulated Snowfall (maxTAloft)\",\n \"units\": \"in\"\n },\n \"snowlvl\": {\n \"defaults\": \"default\",\n \"colorBars\": {\n \"default\": {\n \"colorLevels\": [0, 1, 2, 3, 4, 6, 8, 10, 15],\n \"colors\": [\n \"rgb(243,203,254)\",\n \"rgb(255,0,0)\",\n \"rgb(255,150,0)\",\n \"rgb(255,255,0)\",\n \"rgb(100,200,120)\",\n \"rgb(70,118,196)\",\n \"rgb(91,205,240)\",\n \"rgb(205,205,240)\",\n \"rgb(255,255,255)\"\n ],\n \"colorType\": \"scaleLinear\",\n \"contourLevels\": [0, 1, 2, 3, 4, 6, 8, 10, 15],\n \"isLeftCap\": false,\n \"ticks\": \"byColorLevels\"\n },\n \"spread\": {\n \"colorLevels\": [0, 0.5, 1, 2, 3, 4]\n }\n },\n \"colorPrimary\": \"rgb(200,200,255)\",\n \"nameLegend\": \"Snow Level\",\n \"namePublic\": \"Snow Level\",\n \"nameShort\": \"Snow Level\",\n \"roundto\": 1,\n \"units\": \"kft\"\n },\n \"snowlr\": {\n \"defaults\": \"default\",\n \"colorBars\": {\n \"default\": {\n \"colorLevels\": [0, 5, 10, 15, 20, 25, 30],\n \"colors\": [\n \"rgb(0,0,50)\",\n \"rgb(50,106,154)\",\n \"rgb(177,246,249)\",\n \"rgb(229,225,227)\",\n \"rgb(238,153,204)\",\n \"rgb(204,110,139)\",\n \"rgb(155,79,81)\"\n ],\n \"colorType\": \"scaleLinear\",\n \"contourLevels\": [1, 5, 10, 15, 20, 25, 30],\n \"isLeftCap\": false,\n \"ticks\": \"byColorLevels\"\n }\n },\n \"colorPrimary\": \"rgb(200,150,255)\",\n \"nameLegend\": \"Snow Liquid Ratio\",\n \"namePublic\": \"Snow Liquid Ratio\",\n \"nameShort\": \"SLR\",\n \"roundto\": 0,\n \"units\": \"\"\n },\n \"slrMaxTAloft\": {\n \"defaults\": \"snowlr\",\n \"nameLegend\": \"Snow Liquid Ratio (MaxTAloft)\",\n \"namePublic\": \"Snow Liquid Ratio\",\n \"nameShort\": \"SLR\"\n },\n \"solarRad\": {\n \"defaults\": \"default\",\n \"colorBars\": {\n \"default\": {\n \"colorLevels\": [0, 300, 600, 900, 1200],\n \"colors\": [\n \"rgba(0,0,0,0)\",\n \"rgb(255,255,0)\",\n \"rgb(255,155,0)\",\n \"rgb(255,0,0)\",\n \"rgb(100,0,0)\"\n ],\n \"colorType\": \"scaleLinear\",\n \"contourLevels\": [100, 300, 500, 1000, 1500],\n \"isLeftCap\": false,\n \"ticks\": \"linear\"\n }\n },\n \"colorPrimary\": \"rgb(200,0,0)\",\n \"nameLegend\": \"Solar Radiation\",\n \"namePublic\": \"Solar Radiation\",\n \"nameShort\": \"Solar Rad\",\n \"roundto\": 0,\n \"units\": \"W/m^2\"\n },\n \"sigWave\": {\n \"defaults\": \"default\",\n \"colorBars\": {\n \"default\": {\n \"colorLevels\": [0, 5, 10, 15, 20, 30, 40, 50],\n \"colors\": [\n \"rgba(0,0,0,0)\",\n \"rgb(0,0,200)\",\n \"rgb(220,220,0)\",\n \"rgb(255,131,0)\",\n \"rgb(255,0,0)\",\n \"rgb(100,0,100)\",\n \"rgb(200,0,200)\",\n \"rgb(255,255,255)\"\n ],\n \"colorType\": \"scaleLinear\",\n \"contourLevels\": [5, 10, 15, 20, 25, 30, 35, 40, 45, 50],\n \"isLeftCap\": false,\n \"ticks\": \"linear\"\n }\n },\n \"colorPrimary\": \"rgba(0,0,255,1)\",\n \"nameLegend\": \"Significant Wave Height\",\n \"namePublic\": \"Significant Wave Height\",\n \"nameShort\": \"Wave Hgt\",\n \"roundto\": 0,\n \"units\": \"ft\"\n },\n \"waveHgt\": {\n \"defaults\": \"sigWave\",\n \"colorBars\": {\n \"default\": {\n \"colorLevels\": [0, 3, 6, 10, 15, 20, 25, 30],\n \"contourLevels\": [3, 6, 10, 15, 20, 25, 30]\n }\n },\n \"nameLegend\": \"Wave Height\",\n \"namePublic\": \"Wave Height\"\n },\n \"SOVI_SCORE\": {\n \"defaults\": \"default\",\n \"colorBars\": {\n \"default\": {\n \"colorLevels\": [0, 50, 100],\n \"colors\": [\"rgb(255,255,229)\", \"rgb(161,219,226)\", \"rgb(100,125,212)\"],\n \"colorType\": \"scaleLinear\",\n \"isLeftCap\": false,\n \"ticks\": \"linear\"\n }\n },\n \"nameLegend\": \"Social Vulnerability Index\",\n \"namePublic\": \"Social Vulnerability Index\",\n \"nameShort\": \"SVI\",\n \"roundto\": 0,\n \"units\": \"\"\n },\n \"POPDENS\": {\n \"defaults\": \"default\",\n \"colorBars\": {\n \"default\": {\n \"colorLevels\": [0, 1500, 3000],\n \"colors\": [\"rgb(255,255,229)\", \"rgb(161,219,226)\", \"rgb(100,125,212)\"],\n \"colorType\": \"scaleLinear\",\n \"ticks\": \"linear\"\n }\n },\n \"nameLegend\": \"Population\",\n \"namePublic\": \"Population\",\n \"nameShort\": \"Pop. density\",\n \"roundto\": 0,\n \"units\": \"\"\n },\n \"EP_MOBILE\": {\n \"defaults\": \"default\",\n \"colorBars\": {\n \"default\": {\n \"colorLevels\": [0, 25, 50],\n \"colors\": [\"rgb(255,255,229)\", \"rgb(161,219,226)\", \"rgb(100,125,212)\"],\n \"colorType\": \"scaleLinear\",\n \"ticks\": \"linear\"\n }\n },\n \"nameLegend\": \"Mobile Homes\",\n \"namePublic\": \"Mobile Homes\",\n \"nameShort\": \"Mobile homes\",\n \"roundto\": 0,\n \"units\": \"\"\n },\n \"EP_LIMENG\": {\n \"defaults\": \"default\",\n \"colorBars\": {\n \"default\": {\n \"colorLevels\": [0, 10, 20],\n \"colors\": [\"rgb(255,255,229)\", \"rgb(161,219,226)\", \"rgb(100,125,212)\"],\n \"colorType\": \"scaleLinear\",\n \"ticks\": \"linear\"\n }\n },\n \"nameLegend\": \"Limited English Speakers\",\n \"namePublic\": \"Limited English Speakers\",\n \"nameShort\": \"Limited english\",\n \"roundto\": 0,\n \"units\": \"\"\n },\n \"EP_NOVEH\": {\n \"defaults\": \"default\",\n \"colorBars\": {\n \"default\": {\n \"colorLevels\": [0, 15, 30],\n \"colors\": [\"rgb(255,255,229)\", \"rgb(161,219,226)\", \"rgb(100,125,212)\"],\n \"colorType\": \"scaleLinear\",\n \"ticks\": \"linear\"\n }\n },\n \"nameLegend\": \"Households with no vehicle available\",\n \"namePublic\": \"Households with no vehicle available\",\n \"nameShort\": \"No vehicle\",\n \"roundto\": 0,\n \"units\": \"\"\n },\n \"EP_NOINT\": {\n \"defaults\": \"default\",\n \"colorBars\": {\n \"default\": {\n \"colorLevels\": [0, 30, 60],\n \"colors\": [\"rgb(255,255,229)\", \"rgb(161,219,226)\", \"rgb(100,125,212)\"],\n \"colorType\": \"scaleLinear\",\n \"ticks\": \"linear\"\n }\n },\n \"nameLegend\": \"Households without a broadband internet subscription\",\n \"namePublic\": \"Households w/o broadband internet\",\n \"nameShort\": \"No internet\",\n \"roundto\": 0,\n \"units\": \"\"\n },\n \"d2\": {\n \"defaults\": \"default\",\n \"colorBars\": {\n \"default\": {\n \"colorLevels\": [0, 10, 20, 30, 40, 45, 50, 55, 60, 65, 70, 75, 80],\n \"colors\": [\n \"rgb(59,34,4)\",\n \"rgb(84,48,5)\",\n \"rgb(140,82,10)\",\n \"rgb(191,129,45)\",\n \"rgb(204,168,84)\",\n \"rgb(223,194,125)\",\n \"rgb(230,217,181)\",\n \"rgb(211,235,231)\",\n \"rgb(169,219,211)\",\n \"rgb(114,184,173)\",\n \"rgb(49,140,133)\",\n \"rgb(1,102,95)\",\n \"rgb(0,60,48)\",\n \"rgb(0,41,33)\"\n ],\n \"colorType\": \"scaleThreshold\",\n \"contourLevels\": [0, 10, 20, 30, 40, 45, 50, 55, 60, 65, 70, 75, 80],\n \"ticks\": \"linear\"\n },\n \"difference\": {\n \"colorLevels\": [-14, -12, -10, -8, -6, -4, -2, 2, 4, 6, 8, 10, 12, 14]\n }\n },\n \"colorPrimary\": \"var(--graphcolorlight)\",\n \"isZeroLowerBound\": true,\n \"nameLegend\": \"2m Dew Point\",\n \"namePublic\": \"Dew Point\",\n \"nameShort\": \"2m Dpt\",\n \"roundto\": 1,\n \"roundtoReadout\": 0,\n \"units\": \"F\"\n },\n \"dpt_isobaric\": {\n \"defaults\": \"d2\",\n \"nameLegend\": \"Isobaric Dew Point\",\n \"namePublic\": \"Isobaric Dew Point\",\n \"nameShort\": \"Isobaric Dew Point\"\n },\n \"t2\": {\n \"defaults\": \"d2\",\n \"colorBars\": {\n \"default\": {\n \"colorLevels\": [\n -60, -55, -50, -45, -40, -35, -30, -25, -20, -15, -10, -5, 0, 5, 10, 15, 20, 25,\n 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90, 95, 100, 105, 110, 115, 120\n ],\n \"colors\": [\n \"rgb(145,0,63)\",\n \"rgb(206,18,86)\",\n \"rgb(231,41,138)\",\n \"rgb(223,101,176)\",\n \"rgb(255,115,223)\",\n \"rgb(255,190,232)\",\n \"rgb(250,250,250)\",\n \"rgb(218,218,235)\",\n \"rgb(188,189,220)\",\n \"rgb(158,154,200)\",\n \"rgb(117,107,177)\",\n \"rgb(84,39,143)\",\n \"rgb(13,0,125)\",\n \"rgb(13,61,156)\",\n \"rgb(0,102,194)\",\n \"rgb(41,158,255)\",\n \"rgb(74,199,255)\",\n \"rgb(115,215,255)\",\n \"rgb(173,255,255)\",\n \"rgb(48,207,194)\",\n \"rgb(0,153,150)\",\n \"rgb(18,87,87)\",\n \"rgb(6,109,44)\",\n \"rgb(49,163,84)\",\n \"rgb(116,196,118)\",\n \"rgb(161,217,155)\",\n \"rgb(211,255,190)\",\n \"rgb(255,255,179)\",\n \"rgb(255,237,160)\",\n \"rgb(254,209,118)\",\n \"rgb(254,174,42)\",\n \"rgb(253,141,60)\",\n \"rgb(252,78,42)\",\n \"rgb(227,26,28)\",\n \"rgb(177,0,38)\",\n \"rgb(128,0,38)\",\n \"rgb(89,0,66)\",\n \"rgb(40,0,40)\"\n ],\n \"contourLevels\": [\n -60, -55, -50, -45, -40, -35, -30, -25, -20, -15, -10, -5, 0, 5, 10, 15, 20, 25,\n 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90, 95, 100, 105, 110, 115, 120\n ]\n }\n },\n \"colorPrimary\": \"rgb(255,0,0)\",\n \"nameLegend\": \"2m Temperature\",\n \"namePublic\": \"Temperature\",\n \"nameShort\": \"2m Temp\"\n },\n \"t500\": {\n \"defaults\": \"t2\",\n \"colorBars\": {\n \"default\": {\n \"colorLevels\": [\n -66, -63, -60, -57, -54, -51, -48, -45, -42, -39, -36, -33, -30, -27, -24, -21,\n -18, -15, -12, -9, -6, -3, 0, 3, 6, 9, 12, 15, 18, 21, 24, 27, 30, 33, 36, 39,\n 42\n ],\n \"contourLevels\": [\n -66, -63, -60, -57, -54, -51, -48, -45, -42, -39, -36, -33, -30, -27, -24, -21,\n -18, -15, -12, -9, -6, -3, 0, 3, 6, 9, 12, 15, 18, 21, 24, 27, 30, 33, 36, 39,\n 42\n ]\n }\n },\n \"nameLegend\": \"500 mb Temp\",\n \"namePublic\": \"500 mb Temperature\",\n \"nameShort\": \"500 mb Temp\",\n \"units\": \"C\"\n },\n \"t700\": {\n \"defaults\": \"t2\",\n \"colorBars\": {\n \"default\": {\n \"colorLevels\": [\n -66, -63, -60, -57, -54, -51, -48, -45, -42, -39, -36, -33, -30, -27, -24, -21,\n -18, -15, -12, -9, -6, -3, 0, 3, 6, 9, 12, 15, 18, 21, 24, 27, 30, 33, 36, 39,\n 42\n ],\n \"contourLevels\": [\n -66, -63, -60, -57, -54, -51, -48, -45, -42, -39, -36, -33, -30, -27, -24, -21,\n -18, -15, -12, -9, -6, -3, 0, 3, 6, 9, 12, 15, 18, 21, 24, 27, 30, 33, 36, 39,\n 42\n ]\n },\n \"difference\": {\n \"colorLevels\": [-14, -12, -10, -8, -6, -4, -2, 2, 4, 6, 8, 10, 12, 14]\n }\n },\n \"nameLegend\": \"700 mb Temp\",\n \"namePublic\": \"700 mb Temperature\",\n \"nameShort\": \"700 mb Temp\",\n \"units\": \"C\"\n },\n \"t850\": {\n \"defaults\": \"t2\",\n \"colorBars\": {\n \"default\": {\n \"colorLevels\": [\n -66, -63, -60, -57, -54, -51, -48, -45, -42, -39, -36, -33, -30, -27, -24, -21,\n -18, -15, -12, -9, -6, -3, 0, 3, 6, 9, 12, 15, 18, 21, 24, 27, 30, 33, 36, 39,\n 42\n ],\n \"contourLevels\": [\n -66, -63, -60, -57, -54, -51, -48, -45, -42, -39, -36, -33, -30, -27, -24, -21,\n -18, -15, -12, -9, -6, -3, 0, 3, 6, 9, 12, 15, 18, 21, 24, 27, 30, 33, 36, 39,\n 42\n ]\n },\n \"difference\": {\n \"colorLevels\": [-14, -12, -10, -8, -6, -4, -2, 2, 4, 6, 8, 10, 12, 14]\n }\n },\n \"nameLegend\": \"850 mb Temp\",\n \"namePublic\": \"850 mb Temperature\",\n \"nameShort\": \"850 mb Temp\",\n \"units\": \"C\"\n },\n \"t925\": {\n \"defaults\": \"t2\",\n \"colorBars\": {\n \"default\": {\n \"colorLevels\": [\n -66, -63, -60, -57, -54, -51, -48, -45, -42, -39, -36, -33, -30, -27, -24, -21,\n -18, -15, -12, -9, -6, -3, 0, 3, 6, 9, 12, 15, 18, 21, 24, 27, 30, 33, 36, 39,\n 42\n ],\n \"contourLevels\": [\n -66, -63, -60, -57, -54, -51, -48, -45, -42, -39, -36, -33, -30, -27, -24, -21,\n -18, -15, -12, -9, -6, -3, 0, 3, 6, 9, 12, 15, 18, 21, 24, 27, 30, 33, 36, 39,\n 42\n ]\n },\n \"difference\": {\n \"colorLevels\": [-14, -12, -10, -8, -6, -4, -2, 2, 4, 6, 8, 10, 12, 14]\n }\n },\n \"nameLegend\": \"925 mb Temp\",\n \"namePublic\": \"925 mb Temperature\",\n \"nameShort\": \"925 mb Temp\",\n \"units\": \"C\"\n },\n \"td850\": {\n \"defaults\": \"d2\",\n \"colorBars\": {\n \"default\": {\n \"colorLevels\": [-24, -20, -16, -12, -8, -4, 0, 4, 8, 12, 16, 20, 24],\n \"colors\": [\n \"rgb(59,34,4)\",\n \"rgb(84,48,5)\",\n \"rgb(140,82,10)\",\n \"rgb(191,129,45)\",\n \"rgb(204,168,84)\",\n \"rgb(223,194,125)\",\n \"rgb(230,217,181)\",\n \"rgb(211,235,231)\",\n \"rgb(169,219,211)\",\n \"rgb(114,184,173)\",\n \"rgb(49,140,133)\",\n \"rgb(1,102,95)\",\n \"rgb(0,60,48)\",\n \"rgb(0,41,33)\"\n ],\n \"contourLevels\": [-24, -20, -16, -12, -8, -4, 0, 4, 8, 12, 16, 20, 24]\n },\n \"difference\": {\n \"colorLevels\": [-14, -12, -10, -8, -6, -4, -2, 2, 4, 6, 8, 10, 12, 14]\n }\n },\n \"nameLegend\": \"850 mb Dew Pt\",\n \"namePublic\": \"850 mb Dew Point\",\n \"nameShort\": \"850 mb Dew Pt\",\n \"units\": \"C\"\n },\n \"td925\": {\n \"defaults\": \"d2\",\n \"colorBars\": {\n \"default\": {\n \"colorLevels\": [-24, -20, -16, -12, -8, -4, 0, 4, 8, 12, 16, 20, 24],\n \"colors\": [\n \"rgb(59,34,4)\",\n \"rgb(84,48,5)\",\n \"rgb(140,82,10)\",\n \"rgb(191,129,45)\",\n \"rgb(204,168,84)\",\n \"rgb(223,194,125)\",\n \"rgb(230,217,181)\",\n \"rgb(211,235,231)\",\n \"rgb(169,219,211)\",\n \"rgb(114,184,173)\",\n \"rgb(49,140,133)\",\n \"rgb(1,102,95)\",\n \"rgb(0,60,48)\",\n \"rgb(0,41,33)\"\n ],\n \"contourLevels\": [-24, -20, -16, -12, -8, -4, 0, 4, 8, 12, 16, 20, 24]\n },\n \"difference\": {\n \"colorLevels\": [-14, -12, -10, -8, -6, -4, -2, 2, 4, 6, 8, 10, 12, 14]\n }\n },\n \"nameLegend\": \"925 mb Dew Pt\",\n \"namePublic\": \"925 mb Dew Point\",\n \"nameShort\": \"925 mb Dew Pt\",\n \"units\": \"C\"\n },\n \"t_isobaric\": {\n \"defaults\": \"t2\",\n \"nameLegend\": \"Isobaric Temperature\",\n \"namePublic\": \"Isobaric Temperature\",\n \"nameShort\": \"Isobaric Temperature\"\n },\n \"mx2t12\": {\n \"defaults\": \"t2\",\n \"nameLegend\": \"Max Temperature\",\n \"namePublic\": \"Max Temperature\",\n \"nameShort\": \"Max Temp\"\n },\n \"mx2t18\": {\n \"defaults\": \"mx2t12\"\n },\n \"mxmn2t18\": {\n \"defaults\": \"mx2t12\"\n },\n \"mx2t6\": {\n \"defaults\": \"mx2t12\"\n },\n \"mn2t12\": {\n \"defaults\": \"mx2t12\",\n \"colorPrimary\": \"rgb(100,100,255)\",\n \"nameLegend\": \"Min Temperature\",\n \"namePublic\": \"Min Temperature\",\n \"nameShort\": \"Min Temp\"\n },\n \"mn2t18\": {\n \"defaults\": \"mn2t12\"\n },\n \"mn2t6\": {\n \"defaults\": \"mn2t12\"\n },\n \"tw2\": {\n \"defaults\": \"t2\",\n \"colorPrimary\": \"rgb(200,200,200)\",\n \"nameLegend\": \"2m Wet Bulb\",\n \"namePublic\": \"Wet Bulb Temperature\",\n \"nameShort\": \"2m Tw Temp\"\n },\n \"twgt2\": {\n \"defaults\": \"t2\",\n \"colorPrimary\": \"rgb(200,200,200)\",\n \"nameLegend\": \"2m Wet Bulb Globe Temperature\",\n \"namePublic\": \"Wet Bulb Globe Temperature\",\n \"nameShort\": \"2m Globe Temp\"\n },\n \"ta2\": {\n \"defaults\": \"t2\",\n \"nameLegend\": \"2m Apparent Temperature\",\n \"namePublic\": \"Apparent Temperature\",\n \"nameShort\": \"2m Ta Temp\"\n },\n \"tadv700\": {\n \"defaults\": \"default\",\n \"colorBars\": {\n \"default\": {\n \"colorLevels\": [-3.5, -3, -2.5, -2, -1.5, -1, -0.5, 0.5, 1, 1.5, 2, 2.5, 3, 3.5],\n \"colors\": [\n \"rgb(0,0,70)\",\n \"rgb(36,56,119)\",\n \"rgb(68,106,161)\",\n \"rgb(100,152,195)\",\n \"rgb(132,185,216)\",\n \"rgb(164,207,228)\",\n \"rgba(194,227,239,200)\",\n \"rgba(255,255,255,0)\",\n \"rgba(254,195,118,200)\",\n \"rgb(252,163,95)\",\n \"rgb(247,128,76)\",\n \"rgb(234,93,59)\",\n \"rgb(199,61,41)\",\n \"rgb(148,29,24)\",\n \"rgb(84,0,0)\"\n ],\n \"colorType\": \"scaleThreshold\",\n \"contourLevels\": [-7, -6, -5, -4, -3, -2, -1, 1, 2, 3, 4, 5, 6, 7]\n },\n \"difference\": {\n \"colorLevels\": [-3.5, -3, -2.5, -2, -1.5, -1, -0.5, 0.5, 1, 1.5, 2, 2.5, 3, 3.5]\n },\n \"spread\": {\n \"colorLevels\": [0, 0.5, 1, 1.5, 2, 2.5]\n }\n },\n \"colorPrimary\": \"rgb(255,100,1000)\",\n \"isZeroLowerBound\": true,\n \"nameLegend\": \"700mb T-Advection\",\n \"namePublic\": \"700mb T-Advection\",\n \"nameShort\": \"700mb T-Adv\",\n \"roundto\": 1,\n \"units\": \"K/hr\"\n },\n \"tadv850\": {\n \"defaults\": \"tadv700\",\n \"nameLegend\": \"850mb T-Advection\",\n \"namePublic\": \"850mb T-Advection\",\n \"nameShort\": \"850mb T-Adv\"\n },\n \"t_cloudTop\": {\n \"defaults\": \"default\",\n \"colorBars\": {\n \"default\": {\n \"colorLevels\": [-90, -80, -70, -60, -50, -40, -30, -20, 0],\n \"colors\": [\n \"rgb(179,15,145)\",\n \"rgb(225,226,228)\",\n \"rgb(0,0,0)\",\n \"rgb(255,0,0)\",\n \"rgb(255,246,0)\",\n \"rgb(0,253,0)\",\n \"rgb(0,24,133)\",\n \"rgb(0,254,255)\",\n \"rgb(10,10,10)\"\n ],\n \"colorType\": \"scaleLinear\",\n \"contourLevels\": [-90, -80, -70, -60, -50, -40, -30, -20],\n \"ticks\": \"linear\"\n },\n \"difference\": {\n \"colorLevels\": [-35, -30, -25, -20, -15, -10, -5, 5, 10, 15, 20, 25, 30, 35]\n },\n \"spread\": {\n \"colorLevels\": [0, 5, 10, 15, 20, 25]\n }\n },\n \"colorPrimary\": \"rgb(255,0,255)\",\n \"isZeroLowerBound\": true,\n \"nameLegend\": \"Cloud Top Temperature\",\n \"namePublic\": \"Cloud Top Temperature\",\n \"nameShort\": \"CloudTop Temp\",\n \"roundto\": 0,\n \"units\": \"C\"\n },\n \"probthunder\": {\n \"defaults\": \"default\",\n \"colorBars\": {\n \"default\": {\n \"colorLevels\": [0, 25, 50, 75, 100],\n \"colors\": [\n \"rgba(0,0,0,0)\",\n \"rgb(255,255,0)\",\n \"rgb(255,0,0)\",\n \"rgb(255,0,255)\",\n \"rgb(255,255,255)\"\n ],\n \"colorType\": \"scaleLinear\",\n \"contourLevels\": [30, 60, 90, 100],\n \"isLeftCap\": false,\n \"isRightCap\": false,\n \"ticks\": \"linear\"\n },\n \"difference\": {\n \"colorLevels\": [-75, -50, -40, -30, -20, -10, -5, 5, 10, 20, 30, 40, 50, 75]\n },\n \"spread\": {\n \"colorLevels\": [0, 15, 30, 45, 60, 75]\n }\n },\n \"colorPrimary\": \"rgb(255,255,0)\",\n \"isZeroLowerBound\": true,\n \"nameLegend\": \"Prob Thunder\",\n \"namePublic\": \"Probability of Thunder\",\n \"nameShort\": \"Thunder\",\n \"roundto\": 0,\n \"units\": \"%\"\n },\n \"turb\": {\n \"defaults\": \"default\",\n \"colorBars\": {\n \"default\": {\n \"colorLevels\": [0, 1, 2, 3, 4],\n \"colors\": [\n \"rgba(150,150,150,0)\",\n \"rgba(150,150,150,0)\",\n \"rgb(64,202,52)\",\n \"rgb(246,247,41)\",\n \"rgb(244,172,42)\",\n \"rgb(220,79,44)\"\n ],\n \"colorType\": \"scaleThreshold\",\n \"contourLevels\": [1, 2, 3, 4],\n \"isLeftCap\": false,\n \"ticks\": \"linear\"\n }\n },\n \"colorPrimary\": \"rgb(255,255,50)\",\n \"isZeroLowerBound\": true,\n \"nameLegend\": \"Turbulence\",\n \"namePublic\": \"Turbulence\",\n \"nameShort\": \"Turb\",\n \"roundto\": 0,\n \"units\": \"\"\n },\n \"tcc\": {\n \"defaults\": \"default\",\n \"colorBars\": {\n \"default\": {\n \"colorLevels\": [0, 50, 75, 100],\n \"colors\": [\n \"rgb(68,114,196)\",\n \"rgb(166,166,166)\",\n \"rgb(127,127,127)\",\n \"rgb(50,50,50)\"\n ],\n \"colorType\": \"scaleLinear\",\n \"contourLevels\": [20, 40, 60, 80, 100],\n \"isLeftCap\": false,\n \"isRightCap\": false,\n \"ticks\": \"linear\"\n },\n \"difference\": {\n \"colorLevels\": [-75, -50, -40, -30, -20, -10, -5, 5, 10, 20, 30, 40, 50, 75]\n },\n \"spread\": {\n \"colorLevels\": [0, 15, 30, 45, 60, 75]\n }\n },\n \"colorPrimary\": \"var(--fontcolor)\",\n \"nameLegend\": \"Total Cloud Cover\",\n \"namePublic\": \"Cloud Cover\",\n \"nameShort\": \"Cloud\",\n \"roundto\": 0,\n \"units\": \"%\"\n },\n \"lcc\": {\n \"defaults\": \"default\",\n \"colorBars\": {\n \"default\": {\n \"colorLevels\": [0, 100],\n \"colors\": [\"rgba(40,68,165,0)\", \"rgb(40,68,255)\"],\n \"colorType\": \"scaleLinear\",\n \"contourLevels\": [20, 40, 60, 80, 100],\n \"isLeftCap\": false,\n \"isRightCap\": false,\n \"ticks\": \"linear\"\n },\n \"difference\": {\n \"colorLevels\": [-75, -50, -40, -30, -20, -10, -5, 5, 10, 20, 30, 40, 50, 75]\n },\n \"spread\": {\n \"colorLevels\": [0, 15, 30, 45, 60, 75]\n }\n },\n \"colorPrimary\": \"rgb(60,88,185)\",\n \"nameLegend\": \"Low Cloud Cover (<5 kft MSL)\",\n \"namePublic\": \"Low Cloud Cover (<5 kft MSL)\",\n \"nameShort\": \"Low Cloud\",\n \"roundto\": 0,\n \"units\": \"%\"\n },\n \"mcc\": {\n \"defaults\": \"default\",\n \"colorBars\": {\n \"default\": {\n \"colorLevels\": [0, 100],\n \"colors\": [\"rgba(66,128,28,0)\", \"rgb(66,255,28)\"],\n \"colorType\": \"scaleLinear\",\n \"contourLevels\": [20, 40, 60, 80, 100],\n \"isLeftCap\": false,\n \"isRightCap\": false,\n \"ticks\": \"linear\"\n },\n \"difference\": {\n \"colorLevels\": [-75, -50, -40, -30, -20, -10, -5, 5, 10, 20, 30, 40, 50, 75]\n },\n \"spread\": {\n \"colorLevels\": [0, 15, 30, 45, 60, 75]\n }\n },\n \"colorPrimary\": \"rgb(66,128,28)\",\n \"nameLegend\": \"Mid Cloud Cover (5-25 kft MSL)\",\n \"namePublic\": \"Mid Cloud Cover (5-25 kft MSL)\",\n \"nameShort\": \"Mid Cloud\",\n \"roundto\": 0,\n \"units\": \"%\"\n },\n \"hcc\": {\n \"defaults\": \"default\",\n \"colorBars\": {\n \"default\": {\n \"colorLevels\": [0, 100],\n \"colors\": [\"rgba(154,43,85,0)\", \"rgb(255,43,85)\"],\n \"colorType\": \"scaleLinear\",\n \"contourLevels\": [20, 40, 60, 80, 100],\n \"isLeftCap\": false,\n \"isRightCap\": false,\n \"ticks\": \"linear\"\n },\n \"difference\": {\n \"colorLevels\": [-75, -50, -40, -30, -20, -10, -5, 5, 10, 20, 30, 40, 50, 75]\n },\n \"spread\": {\n \"colorLevels\": [0, 15, 30, 45, 60, 75]\n }\n },\n \"colorPrimary\": \"rgb(154,43,28)\",\n \"nameLegend\": \"High Cloud Cover (>25 kft MSL)\",\n \"namePublic\": \"High Cloud Cover (>25 kft MSL)\",\n \"nameShort\": \"High Cloud\",\n \"roundto\": 0,\n \"units\": \"%\"\n },\n \"maxuvv\": {\n \"defaults\": \"default\",\n \"colorBars\": {\n \"default\": {\n \"colorType\": \"scaleThreshold\",\n \"ticks\": \"linear\"\n }\n }\n },\n \"maxdvv\": {\n \"defaults\": \"default\",\n \"colorBars\": {\n \"default\": {\n \"colorType\": \"scaleThreshold\",\n \"ticks\": \"linear\"\n }\n }\n },\n \"mxUpHel2to5\": {\n \"defaults\": \"default\",\n \"colorBars\": {\n \"default\": {\n \"colorLevels\": [\n 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 90, 105, 120, 135, 150, 180, 210,\n 240, 270, 300, 340, 380, 420, 460, 500\n ],\n \"colors\": [\n \"rgba(150,150,150,0)\",\n \"rgb(204,204,204)\",\n \"rgb(178,178,178)\",\n \"rgb(153,153,153)\",\n \"rgb(127,127,127)\",\n \"rgb(102,102,102)\",\n \"rgb(127,178,255)\",\n \"rgb(102,146,235)\",\n \"rgb(76,114,216)\",\n \"rgb(50,82,197)\",\n \"rgb(25,51,178)\",\n \"rgb(127,255,127)\",\n \"rgb(98,216,98)\",\n \"rgb(70,178,70)\",\n \"rgb(41,140,41)\",\n \"rgb(12,102,12)\",\n \"rgb(255,255,102)\",\n \"rgb(232,197,76)\",\n \"rgb(210,140,51)\",\n \"rgb(188,82,25)\",\n \"rgb(165,25,0)\",\n \"rgb(255,153,255)\",\n \"rgb(224,123,224)\",\n \"rgb(193,94,193)\",\n \"rgb(132,36,132)\",\n \"rgb(102,7,102)\",\n \"rgb(102,7,102)\"\n ],\n \"colorType\": \"scaleThreshold\",\n \"contourLevels\": [25, 50, 75, 100, 150, 300, 500],\n \"isLeftCap\": false,\n \"ticks\": \"linear\"\n },\n \"difference\": {\n \"colorLevels\": [\n -175, -150, -125, -100, -75, -50, -25, 25, 50, 75, 100, 125, 150, 175\n ]\n },\n \"spread\": {\n \"colorLevels\": [0, 25, 50, 100, 150, 200]\n }\n },\n \"colorPrimary\": \"rgb(255,0,255)\",\n \"nameLegend\": \"2-5km Max Updraft Helicity\",\n \"namePublic\": \"2-5km Max Updraft Helicity\",\n \"nameShort\": \"2-5km Max Up. Hel.\",\n \"roundto\": 0,\n \"units\": \"m^2/s^2\"\n },\n \"mxUpHel0to3\": {\n \"defaults\": \"mxUpHel2to5\",\n \"nameLegend\": \"0-3km Max Updraft Helicity\",\n \"namePublic\": \"0-3km Max Updraft Helicity\",\n \"nameShort\": \"0-3km Max Up. Hel.\"\n },\n \"mnUpHel2to5\": {\n \"defaults\": \"default\",\n \"colorBars\": {\n \"default\": {\n \"colorLevels\": [-250, -200, -150, -125, -100, -75, -50, -25, -15],\n \"colors\": [\n \"rgb(229,229,229)\",\n \"rgb(197,197,197)\",\n \"rgb(165,165,165)\",\n \"rgb(133,133,133)\",\n \"rgb(102,102,102)\",\n \"rgb(25,51,178)\",\n \"rgb(51,82,197)\",\n \"rgb(76,114,216)\",\n \"rgb(127,178,255)\",\n \"rgba(150,150,150,0)\"\n ],\n \"colorType\": \"scaleThreshold\",\n \"contourLevels\": [-250, -200, -150, -125, -100, -75, -50, -25],\n \"ticks\": \"byColorLevels\"\n },\n \"difference\": {\n \"colorLevels\": [\n -175, -150, -125, -100, -75, -50, -25, 25, 50, 75, 100, 125, 150, 175\n ]\n },\n \"spread\": {\n \"colorLevels\": [0, 25, 50, 100, 150, 200]\n }\n },\n \"colorPrimary\": \"rgb(255,0,255)\",\n \"nameLegend\": \"2-5km Min Updraft Helicity\",\n \"namePublic\": \"2-5km Min Updraft Helicity\",\n \"nameShort\": \"2-5km Min Up. Hel.\",\n \"roundto\": 0,\n \"units\": \"m^2/s^2\"\n },\n \"mnUpHel0to3\": {\n \"defaults\": \"mnUpHel2to5\",\n \"nameLegend\": \"0-3km Min Updraft Helicity\",\n \"namePublic\": \"0-3km Min Updraft Helicity\",\n \"nameShort\": \"0-3km Min Up. Hel.\"\n },\n \"u10\": {\n \"defaults\": \"default\",\n \"roundto\": 0,\n \"units\": \"mph\"\n },\n \"u_isobaric\": {\n \"defaults\": \"u10\",\n \"nameLegend\": \"Isobaric U-Wind\",\n \"namePublic\": \"Isobaric U-Wind\",\n \"nameShort\": \"Isobaric U-Wind\"\n },\n \"v10\": {\n \"defaults\": \"default\",\n \"roundto\": 0,\n \"units\": \"mph\"\n },\n \"v_isobaric\": {\n \"defaults\": \"v10\",\n \"nameLegend\": \"Isobaric V-Wind\",\n \"namePublic\": \"Isobaric V-Wind\",\n \"nameShort\": \"Isobaric V-Wind\"\n },\n \"w_isobaric\": {\n \"defaults\": \"v10\",\n \"nameLegend\": \"Isobaric Vertical Velocity\",\n \"namePublic\": \"Isobaric Vertical Velocity\",\n \"nameShort\": \"Isobaric Vertical Velocity\"\n },\n \"wd_isobaric\": {\n \"defaults\": \"v10\",\n \"nameLegend\": \"Isobaric Wind Direction\",\n \"namePublic\": \"Isobaric Wind Direction\",\n \"nameShort\": \"Isobaric Wind Direction\"\n },\n \"ws_isobaric\": {\n \"defaults\": \"v10\",\n \"nameLegend\": \"Isobaric Wind Speed\",\n \"namePublic\": \"Isobaric Wind Speed\",\n \"nameShort\": \"Isobaric Wind Speed\"\n },\n \"vis\": {\n \"defaults\": \"default\",\n \"colorBars\": {\n \"default\": {\n \"colorLevels\": [0, 0.1, 0.25, 0.5, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10],\n \"colors\": [\n \"rgb(0, 0, 0)\",\n \"rgb(0, 0, 0)\",\n \"rgb(65, 10, 30)\",\n \"rgb(88, 24, 69)\",\n \"rgb(150, 30, 150)\",\n \"rgb(225, 0, 0)\",\n \"rgb(255, 100, 100)\",\n \"rgb(255, 255, 0)\",\n \"rgb(255, 255, 150)\",\n \"rgb(100,100,100)\",\n \"rgba(140,140,140,0.8)\",\n \"rgba(180,180,180,0.6)\",\n \"rgba(210,210,210,0.4)\",\n \"rgba(255,255,255,0.2)\",\n \"rgba(255,255,255,0)\"\n ],\n \"colorType\": \"scaleThreshold\",\n \"contourLevels\": [0, 0.1, 0.25, 0.5, 1, 2, 3, 5, 10],\n \"isLeftCap\": false,\n \"ticks\": \"byColorLevels\"\n },\n \"difference\": {\n \"colorLevels\": [-6, -5, -4, -3, -2, -1, -0.5, 0.5, 1, 2, 3, 4, 5, 6]\n }\n },\n \"colorPrimary\": \"rgb(200,200,200)\",\n \"comment\": \"Capping at 15 for the HREF\",\n \"isZeroLowerBound\": true,\n \"nameLegend\": \"Visibility\",\n \"namePublic\": \"Visibility\",\n \"nameShort\": \"Vis\",\n \"roundto\": 1,\n \"units\": \"mi\"\n },\n \"vil\": {\n \"defaults\": \"default\",\n \"colorBars\": {\n \"default\": {\n \"colorLevels\": [0, 0.01, 0.1, 0.5, 1, 2, 2.5],\n \"colors\": [\n \"rgba(0,100,255,0)\",\n \"rgb(0,0,200)\",\n \"rgb(0,0,100)\",\n \"rgb(0,255,0)\",\n \"rgb(255,255,0)\",\n \"rgb(255,0,0)\",\n \"rgb(150,0,150)\"\n ],\n \"colorType\": \"scaleLinear\",\n \"contourLevels\": [0, 0.01, 0.1, 0.25, 0.5, 0.75, 1, 1.25, 1.5, 2, 2.5],\n \"isLeftCap\": false,\n \"ticks\": \"byColorLevels\"\n }\n },\n \"colorPrimary\": \"rgb(200,200,0)\",\n \"nameLegend\": \"Vertically Integrated Liquid\",\n \"namePublic\": \"Vertically Integrated Liquid\",\n \"nameShort\": \"VIL\",\n \"roundto\": 2,\n \"units\": \"in\"\n },\n \"vrate\": {\n \"defaults\": \"default\",\n \"colorBars\": {\n \"default\": {\n \"colorLevels\": [0, 2, 5, 10, 20, 30, 50],\n \"colors\": [\n \"rgba(150,150,150,0)\",\n \"rgb(150,150,150)\",\n \"rgb(0,190,255)\",\n \"rgb(255,255,0)\",\n \"rgb(255,0,0)\",\n \"rgb(255,0,255)\",\n \"rgb(100,0,100)\"\n ],\n \"colorType\": \"scaleLinear\",\n \"contourLevels\": [1, 3, 5, 7, 10, 15],\n \"isLeftCap\": false,\n \"ticks\": \"linear\"\n }\n },\n \"colorPrimary\": \"rgb(200,200,255)\",\n \"nameLegend\": \"Ventiliation Rate\",\n \"namePublic\": \"Ventiliation Rate\",\n \"nameShort\": \"Vent Rate\",\n \"roundto\": 1,\n \"units\": \"1000*m^2/s\"\n },\n \"wfirepot\": {\n \"defaults\": \"default\",\n \"colorBars\": {\n \"default\": {\n \"colorLevels\": [0, 25, 50, 75, 100],\n \"colors\": [\n \"rgba(0,0,0,0)\",\n \"rgba(100, 0, 0,1)\",\n \"rgb(228, 15, 0)\",\n \"rgb(255, 251, 98)\",\n \"rgb(255, 255, 255)\"\n ],\n \"colorType\": \"scaleLinear\",\n \"contourLevels\": [10, 25, 50, 75, 100],\n \"isLeftCap\": false,\n \"ticks\": \"linear\"\n }\n },\n \"colorPrimary\": \"rgb(255,90,90)\",\n \"nameLegend\": \"Hourly Wildfire Potential\",\n \"namePublic\": \"Hourly Wildfire Potential\",\n \"nameShort\": \"HWP\",\n \"roundto\": 1,\n \"roundtoReadout\": 0,\n \"units\": \"\"\n },\n \"large-fire-potential\": {\n \"defaults\": \"default\",\n \"colorBars\": {\n \"default\": {\n \"colorLevels\": [0, 25, 50, 75, 100, 125, 150, 175],\n \"colors\": [\n \"rgba(0,0,0,0)\",\n \"rgba(100, 0, 0,1)\",\n \"rgb(228, 15, 0)\",\n \"rgb(255, 251, 98)\",\n \"rgb(255, 255, 255)\",\n \"rgb(224, 203, 229)\",\n \"rgb(116, 41, 157)\",\n \"rgb(75, 0, 100)\"\n ],\n \"colorType\": \"scaleLinear\",\n \"contourLevels\": [10, 25, 50, 75, 100, 125, 150, 175],\n \"isLeftCap\": false,\n \"ticks\": \"linear\"\n }\n },\n \"colorPrimary\": \"rgb(255,150,150)\",\n \"nameLegend\": \"Large Fire Potential (wx component)\",\n \"namePublic\": \"Large Fire Potential (wx component)\",\n \"nameShort\": \"LFP (wx)\",\n \"roundto\": 1,\n \"roundtoReadout\": 0,\n \"units\": \"°F*m^2/s^2\"\n },\n \"ws\": {\n \"defaults\": \"default\",\n \"colorBars\": {\n \"default\": {\n \"colorLevels\": [0, 5, 10, 15, 20, 25, 30, 40, 50, 60, 70, 80, 90, 100],\n \"colors\": [\n \"rgba(0,0,0,0)\",\n \"rgba(0,0,0,0)\",\n \"rgb(207,225,230)\",\n \"rgb(144,185,213)\",\n \"rgb(98,164,171)\",\n \"rgb(71,120,129)\",\n \"rgb(255,249,129)\",\n \"rgb(249,209,11)\",\n \"rgb(236,152,28)\",\n \"rgb(212,71,68)\",\n \"rgb(166,41,38)\",\n \"rgb(103,16,54)\",\n \"rgb(97,21,57)\",\n \"rgb(57,25,80)\",\n \"rgb(186,89,255)\"\n ],\n \"colorType\": \"scaleThreshold\",\n \"contourLevels\": [5, 10, 15, 20, 25, 30, 40, 50, 60, 70, 80, 90, 100],\n \"isLeftCap\": false,\n \"ticks\": \"byColorLevels\"\n },\n \"difference\": {\n \"colorLevels\": [-30, -24, -20, -16, -12, -8, -4, 4, 8, 12, 16, 20, 24, 30]\n },\n \"spread\": {\n \"colorLevels\": [0, 4, 8, 12, 16, 20]\n }\n },\n \"colorPrimary\": \"rgb(0,255,50)\",\n \"nameLegend\": \"Wind Speed\",\n \"namePublic\": \"Wind Speed\",\n \"nameShort\": \"Wind\",\n \"roundto\": 0,\n \"units\": \"mph\"\n },\n \"ws2\": {\n \"//\": \"This is a temp fix for wind ninja, which needs more detail at low wind speeds\",\n \"defaults\": \"ws\",\n \"colorBars\": {\n \"default\": {\n \"colorLevels\": [0, 2, 4, 6, 8, 10, 15, 20, 25, 30, 40, 50, 60],\n \"colors\": [\n \"rgba(193, 251, 248, 1)\",\n \"rgba(193, 251, 248, 1)\",\n \"rgba(159, 217, 235, 1)\",\n \"rgba(124, 184, 222, 1)\",\n \"rgba(90, 150, 208, 1)\",\n \"rgba(55, 116, 195, 1)\",\n \"rgba(126, 237, 174, 1)\",\n \"rgba(70, 184, 138, 1)\",\n \"rgba(13, 130, 101, 1)\",\n \"rgba(224, 218, 30, 1)\",\n \"rgba(212, 140, 35, 1)\",\n \"rgba(214, 91, 43, 1)\",\n \"rgba(200, 60, 91, 1)\",\n \"rgba(143, 35, 215, 1)\"\n ],\n \"colorType\": \"scaleThreshold\",\n \"contourLevels\": [0, 2, 4, 6, 8, 10, 15, 20, 25, 30, 40, 50, 60],\n \"ticks\": \"byColorLevels\"\n }\n }\n },\n \"ws-cumulative\": {\n \"defaults\": \"ws\",\n \"nameLegend\": \"Cumulative Wind Speed\",\n \"namePublic\": \"Cumulative Wind Speed\",\n \"nameShort\": \"Cumulative Wind\"\n },\n \"ws250\": {\n \"defaults\": \"ws\",\n \"colorBars\": {\n \"default\": {\n \"colorLevels\": [0, 20, 40, 60, 80, 100, 120, 140, 160, 180, 200, 220, 240, 260],\n \"contourLevels\": [20, 40, 60, 80, 100, 120, 140, 160, 180, 200, 220, 240, 260]\n },\n \"difference\": {\n \"colorLevels\": [-48, -40, -32, -24, -16, -8, 8, 16, 24, 32, 40, 48]\n },\n \"spread\": {\n \"colorLevels\": [0, 8, 16, 24, 32, 40]\n }\n },\n \"nameLegend\": \"250 mb Wind Speed\",\n \"namePublic\": \"250 mb Wind Speed\",\n \"nameShort\": \"250 mb Wind\",\n \"units\": \"kts\"\n },\n \"ws500\": {\n \"defaults\": \"ws\",\n \"colorBars\": {\n \"default\": {\n \"colorLevels\": [0, 10, 20, 30, 40, 50, 60, 80, 100, 120, 140, 160, 180, 200],\n \"contourLevels\": [10, 20, 30, 40, 50, 60, 80, 100, 120, 140, 160, 180, 200]\n },\n \"difference\": {\n \"colorLevels\": [-48, -40, -32, -24, -16, -8, -4, 4, 8, 16, 24, 32, 40, 48]\n },\n \"spread\": {\n \"colorLevels\": [0, 8, 16, 24, 32, 40]\n }\n },\n \"nameLegend\": \"500 mb Wind Speed\",\n \"namePublic\": \"500 mb Wind Speed\",\n \"nameShort\": \"500 mb Wind\",\n \"units\": \"kts\"\n },\n \"ws700\": {\n \"defaults\": \"ws\",\n \"colorBars\": {\n \"default\": {\n \"colorLevels\": [0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 120, 140, 160],\n \"contourLevels\": [10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 120, 140, 160]\n },\n \"difference\": {\n \"colorLevels\": [-48, -40, -32, -24, -16, -8, 8, 16, 24, 32, 40, 48]\n },\n \"spread\": {\n \"colorLevels\": [0, 8, 16, 24, 32, 40]\n }\n },\n \"nameLegend\": \"700 mb Wind Speed\",\n \"namePublic\": \"700 mb Wind Speed\",\n \"nameShort\": \"700 mb Wind\",\n \"units\": \"kts\"\n },\n \"ws850\": {\n \"defaults\": \"ws\",\n \"colorBars\": {\n \"default\": {\n \"colorLevels\": [0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 120, 140, 160],\n \"contourLevels\": [10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 120, 140, 160]\n },\n \"difference\": {\n \"colorLevels\": [-30, -25, -20, -15, -10, -5, 5, 10, 15, 20, 25, 30]\n },\n \"spread\": {\n \"colorLevels\": [0, 5, 10, 15, 20, 25]\n }\n },\n \"nameLegend\": \"850 mb Wind Speed\",\n \"namePublic\": \"850 mb Wind Speed\",\n \"nameShort\": \"850 mb Wind\",\n \"units\": \"kts\"\n },\n \"ws925\": {\n \"defaults\": \"ws\",\n \"colorBars\": {\n \"default\": {\n \"colorLevels\": [0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 120, 140, 160],\n \"contourLevels\": [10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 120, 140, 160]\n },\n \"difference\": {\n \"colorLevels\": [-30, -25, -20, -15, -10, -5, 5, 10, 15, 20, 25, 30]\n },\n \"spread\": {\n \"colorLevels\": [0, 5, 10, 15, 20, 25]\n }\n },\n \"nameLegend\": \"925 mb Wind Speed\",\n \"namePublic\": \"925 mb Wind Speed\",\n \"nameShort\": \"925 mb Wind\",\n \"units\": \"kts\"\n },\n \"wg\": {\n \"defaults\": \"ws\",\n \"colorPrimary\": \"rgb(255,255,0)\",\n \"nameLegend\": \"Wind Gust\",\n \"namePublic\": \"Wind Gust\",\n \"nameShort\": \"Gust\"\n },\n \"wg-cumulative\": {\n \"defaults\": \"ws\",\n \"nameLegend\": \"Cumulative Wind Gust\",\n \"namePublic\": \"Cumulative Wind Gust\",\n \"nameShort\": \"Cumulative Wind Gust\"\n },\n \"mxws24\": {\n \"defaults\": \"ws\",\n \"nameLegend\": \"24 hr Max Wind\",\n \"namePublic\": \"24 hr Max Wind\",\n \"nameShort\": \"24hr Max Wind\"\n },\n \"mxwg24\": {\n \"defaults\": \"wg\",\n \"nameLegend\": \"24 hr Max Gust\",\n \"namePublic\": \"24 hr Max Gust\",\n \"nameShort\": \"24hr Max Gust\"\n },\n \"ws_trans\": {\n \"defaults\": \"ws\",\n \"colorPrimary\": \"rgb(150,255,0)\",\n \"nameLegend\": \"Transport Winds\",\n \"namePublic\": \"Transport Winds\",\n \"nameShort\": \"Trans Winds\"\n },\n \"ws30\": {\n \"defaults\": \"ws\",\n \"colorPrimary\": \"rgb(255, 255, 0)\",\n \"nameLegend\": \"30 m Winds\",\n \"namePublic\": \"30 m Winds\",\n \"nameShort\": \"30m Winds\"\n },\n \"ws80\": {\n \"defaults\": \"ws\",\n \"colorPrimary\": \"rgb(170, 170, 170)\",\n \"nameLegend\": \"80 m Winds\",\n \"namePublic\": \"80 m Winds\",\n \"nameShort\": \"80m Winds\"\n },\n \"wshr0-500mb\": {\n \"defaults\": \"ws\",\n \"colorPrimary\": \"rgb(170, 170, 170)\",\n \"nameLegend\": \"0-500mb Wind Shear\",\n \"namePublic\": \"0-500mb Wind Shear\",\n \"nameShort\": \"0-500mb Wind Shear\",\n \"units\": \"kts\"\n },\n \"ushr0-500mb\": {\n \"defaults\": \"wshr0-500mb\",\n \"nameLegend\": \"0-500mb u-Wind Shear\",\n \"namePublic\": \"0-500mb u-Wind Shear\",\n \"nameShort\": \"0-500mb u-Wind Shear\"\n },\n \"vshr0-500mb\": {\n \"defaults\": \"wshr0-500mb\",\n \"nameLegend\": \"0-500mb v-Wind Shear\",\n \"namePublic\": \"0-500mb v-Wind Shear\",\n \"nameShort\": \"0-500mb v-Wind Shear\"\n },\n \"wshr0-6km\": {\n \"defaults\": \"ws\",\n \"colorPrimary\": \"rgb(170, 170, 170)\",\n \"nameLegend\": \"0-6km Wind Shear\",\n \"namePublic\": \"0-6km Wind Shear\",\n \"nameShort\": \"0-6km Wind Shear\",\n \"units\": \"kts\"\n },\n \"ushr0-6km\": {\n \"defaults\": \"wshr0-6km\",\n \"nameLegend\": \"0-6km u-Wind Shear\",\n \"namePublic\": \"0-6km u-Wind Shear\",\n \"nameShort\": \"0-6km u-Wind Shear\"\n },\n \"vshr0-6km\": {\n \"defaults\": \"wshr0-6km\",\n \"nameLegend\": \"0-6km v-Wind Shear\",\n \"namePublic\": \"0-6km v-Wind Shear\",\n \"nameShort\": \"0-6km v-Wind Shear\"\n },\n \"wd\": {\n \"defaults\": \"default\",\n \"colorBars\": {\n \"default\": {\n \"colorLevels\": [0, 90, 180, 270, 360],\n \"colors\": [\n \"rgba(20,80,181)\",\n \"rgba(100,227,100)\",\n \"rgba(242,205,88)\",\n \"rgba(190,10,10)\",\n \"rgba(20,80,181)\"\n ],\n \"colorType\": \"scaleLinear\",\n \"contourLevels\": [0, 45, 90, 180, 225, 270, 360],\n \"isLeftCap\": false,\n \"isRightCap\": false,\n \"ticks\": \"byColorLevels\"\n },\n \"difference\": {\n \"colorLevels\": [-135, -90, -60, -30, -20, -10, -5, 5, 10, 20, 30, 60, 90, 135]\n },\n \"standardDeviation\": {\n \"colorLevels\": [30, 60, 90, 120],\n \"colors\": [\n \"rgba(150,150,150,0)\",\n \"rgb(0,230,255)\",\n \"rgb(255,255,100)\",\n \"rgb(255,100,100)\",\n \"rgb(255,100,100)\",\n \"rgb(255,100,100)\"\n ],\n \"colorType\": \"scaleThreshold\",\n \"ticks\": \"byColorLevels\"\n }\n },\n \"colorPrimary\": \"rgb(220,220,8)\",\n \"isZeroLowerBound\": true,\n \"nameLegend\": \"Wind Direction\",\n \"namePublic\": \"Wind Direction\",\n \"nameShort\": \"Dir\",\n \"roundto\": 0,\n \"units\": \"°\"\n },\n \"wshrd0-500mb\": {\n \"defaults\": \"wd\",\n \"colorPrimary\": \"rgb(170, 170, 170)\",\n \"nameLegend\": \"0-500mb Wind Shear Direction\",\n \"namePublic\": \"0-500mb Wind Shear Direction\",\n \"nameShort\": \"0-500mb Wind Shear Dir\"\n },\n \"wshrd0-6km\": {\n \"defaults\": \"wd\",\n \"colorPrimary\": \"rgb(170, 170, 170)\",\n \"nameLegend\": \"0-6km Wind Shear Direction\",\n \"namePublic\": \"0-6km Wind Shear Direction\",\n \"nameShort\": \"0-6km Wind Shear Dir\"\n },\n \"wd_trans\": {\n \"defaults\": \"wd\",\n \"colorPrimary\": \"rgb(150,255,0)\",\n \"nameLegend\": \"Transport Wind Dir\",\n \"namePublic\": \"Transport Wind Dir\",\n \"nameShort\": \"Trans Wind Dir\"\n },\n \"wd250\": {\n \"defaults\": \"wd\",\n \"nameLegend\": \"250 mb Wind Direction\",\n \"namePublic\": \"250 mb Wind Direction\",\n \"nameShort\": \"250 mb Dir\"\n },\n \"wd500\": {\n \"defaults\": \"wd\",\n \"nameLegend\": \"500 mb Wind Direction\",\n \"namePublic\": \"500 mb Wind Direction\",\n \"nameShort\": \"500 mb Dir\"\n },\n \"wd700\": {\n \"defaults\": \"wd\",\n \"nameLegend\": \"700 mb Wind Direction\",\n \"namePublic\": \"700 mb Wind Direction\",\n \"nameShort\": \"700 mb Dir\"\n },\n \"wd850\": {\n \"defaults\": \"wd\",\n \"nameLegend\": \"850 mb Wind Direction\",\n \"namePublic\": \"850 mb Wind Direction\",\n \"nameShort\": \"850 mb Dir\"\n },\n \"wd925\": {\n \"defaults\": \"wd\",\n \"nameLegend\": \"925 mb Wind Direction\",\n \"namePublic\": \"925 mb Wind Direction\",\n \"nameShort\": \"925 mb Dir\"\n },\n \"cpcLayer\": {\n \"defaults\": \"default\",\n \"colors\": {\n \"temp\": [\n \"rgb(28, 19, 66)\",\n \"rgb(34, 24, 82)\",\n \"rgb(47, 64, 111)\",\n \"rgb(0, 92, 161)\",\n \"rgb(56, 159, 219)\",\n \"rgb(119, 181, 226)\",\n \"rgb(160, 192, 223)\",\n \"rgb(0, 0, 0, 0)\",\n \"rgb(231, 177, 104)\",\n \"rgb(227, 139, 74)\",\n \"rgb(220, 86, 47)\",\n \"rgb(199, 46, 40)\",\n \"rgb(204, 48, 71)\",\n \"rgb(138, 47, 56)\",\n \"rgb(98, 34, 40)\"\n ],\n \"prcp\": [\n \"rgb(79, 47, 47)\",\n \"rgb(128, 64, 0)\",\n \"rgb(147, 70, 57)\",\n \"rgb(155, 80, 49)\",\n \"rgb(187, 109, 51)\",\n \"rgb(216, 167, 80)\",\n \"rgb(240, 212, 147)\",\n \"rgb(0, 0, 0, 0)\",\n \"rgb(179, 217, 171)\",\n \"rgb(148, 205, 126)\",\n \"rgb(72, 174, 56)\",\n \"rgb(58, 123, 95)\",\n \"rgb(0, 142, 64)\",\n \"rgb(40, 85, 61)\",\n \"rgb(40, 85, 23)\"\n ]\n },\n \"labels\": {\n \"labels\": [\n \"90-100%\",\n \"80-90%\",\n \"70-80%\",\n \"60-70%\",\n \"50-60%\",\n \"40-50%\",\n \"33-40%\",\n \"Near Normal\",\n \"33-40%\",\n \"40-50%\",\n \"50-60%\",\n \"60-70%\",\n \"70-80%\",\n \"80-90%\",\n \"90-100%\"\n ]\n }\n },\n \"spcLayer\": {\n \"defaults\": \"default\",\n \"colors\": [\n \"rgb(192, 232, 192)\",\n \"rgb(127, 197, 127)\",\n \"rgb(246, 246, 127)\",\n \"rgb(230, 194, 127)\",\n \"rgb(230, 127, 127)\",\n \"rgb(255, 127, 255)\"\n ],\n \"labels\": [\"General Thunderstorms\", \"Marginal\", \"Slight\", \"Enhanced\", \"Moderate\", \"High\"]\n },\n \"wpcLayer\": {\n \"defaults\": \"default\",\n \"colors\": [\"rgb(0, 205, 0)\", \"rgb(238, 238, 0)\", \"rgb(255, 0, 0)\", \"rgb(255, 0, 255)\"],\n \"labels\": [\n \"Marginal (At Least 5%)\",\n \"Slight (At Least 15%)\",\n \"Moderate (At Least 40%)\",\n \"High (At Least 70%)\"\n ]\n }\n}\n","import { mergeWith, cloneDeep } from 'lodash';\nimport defaults from './configFieldsDefault';\nimport configFields from './configFields.json';\n\n// Don't merge arrays, just use source value\nfunction customizer(objValue, srcValue) {\n if (Array.isArray(objValue)) {\n return srcValue;\n }\n return undefined;\n}\n\nfor (const field in configFields) {\n // If 'mergeWith' key available, merge with another field\n const mergeField = configFields[field].defaults;\n const mergeWithDict = mergeField === 'default' ? defaults : configFields[mergeField];\n configFields[field] = mergeWith(cloneDeep(mergeWithDict), configFields[field], customizer);\n}\n\nexport { configFields, defaults as configFieldsDefaults };\n"],"x_google_ignoreList":[1,2,8,9,10,11,12,13,14,31,32],"mappings":"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M,EAAe,KAAO,EAC3C,EAAe,IAAM,EAAe,KAAO,EAC3C,EAAe,IAAM,EAAe,KAAO,EAC3C,EAAe,IAAM,EAAe,KAAO,EAC3C,EAAe,IAAM,EAAe,KAAO,GAC3C,EAAe,IAAM,EAAe,KAAO,EAC3C,EAAe,IAAM,EAAe,KAAO,EAC3C,EAAe,IAAM,EAAe,KAAO,EAC3C,EAAe,IAAM,EAAe,KAAO,EAC3C,EAAe,IAAM,EAAe,KAAO,EAE3C,EAAe,KAAO,EAAe,IAAM,GAC3C,EAAe,KAAO,EAAe,IAAM,EAC3C,EAAe,KAAO,EAAe,IAAM,EAC3C,EAAe,KAAO,EAAe,IAAM,EAC3C,EAAe,KAAO,EAAe,IAAM,GAC3C,EAAe,KAAO,EAAe,IAAM,EAC3C,EAAe,KAAO,EAAe,IAAM,EAC3C,EAAe,KAAO,EAAe,IAAM,EAC3C,EAAe,KAAO,EAAe,IAAM,EAC3C,EAAe,KAAO,EAAe,IAAM,GAC3C,EAAe,KAAO,EAAe,IAAM,EAC3C,EAAe,KAAO,EAAe,IAAM,EAE3C,EAAe,IAAM,EAAe,IAAM,EAC1C,EAAe,IAAM,EAAe,IAAM,GAC1C,EAAe,IAAM,EAAe,IAAM,EAC1C,EAAe,IAAM,EAAe,IAAM,EAC1C,EAAe,IAAM,EAAe,IAAM,EAC1C,EAAe,IAAM,EAAe,IAAM,EAC1C,EAAe,IAAM,EAAe,IAAM,GAC1C,EAAe,IAAM,EAAe,IAAM,EAC1C,EAAe,IAAM,EAAe,IAAM,EAC1C,EAAe,IAAM,EAAe,IAAM,EAC1C,EAAe,IAAM,EAAe,IAAM,GAC1C,EAAe,IAAM,EAAe,IAAM,EAE1C,EAAe,IAAM,EAAe,IAAM,EAC1C,EAAe,IAAM,EAAe,IAAM,EAC1C,EAAe,IAAM,EAAe,IAAM,EAC1C,EAAe,IAAM,EAAe,IAAM,EAC1C,EAAe,IAAM,EAAe,IAAM,GAC1C,EAAe,IAAM,EAAe,IAAM,EAC1C,EAAe,IAAM,EAAe,IAAM,EAC1C,EAAe,IAAM,EAAe,IAAM,EAC1C,EAAe,IAAM,EAAe,IAAM,EAC1C,EAAe,IAAM,EAAe,IAAM,EAC1C,EAAe,IAAM,EAAe,IAAM,EAC1C,EAAe,IAAM,EAAe,IAAM,EAE1C,EAAe,KAAO,EAAe,IAAM,EAC3C,EAAe,KAAO,EAAe,IAAM,GAC3C,EAAe,KAAO,EAAe,IAAM,EAC3C,EAAe,KAAO,EAAe,IAAM,EAC3C,EAAe,KAAO,EAAe,IAAM,EAC3C,EAAe,KAAO,EAAe,IAAM,EAC3C,EAAe,KAAO,EAAe,IAAM,EAC3C,EAAe,KAAO,EAAe,IAAM,EAC3C,EAAe,KAAO,EAAe,IAAM,EAC3C,EAAe,KAAO,EAAe,IAAM,GAC3C,EAAe,KAAO,EAAe,IAAM,EAC3C,EAAe,KAAO,EAAe,IAAM,EAE3C,EAAe,IAAM,EAAe,KAAO,EAC3C,EAAe,IAAM,EAAe,KAAO,EAC3C,EAAe,IAAM,EAAe,KAAO,EAC3C,EAAe,IAAM,EAAe,KAAO,GAC3C,EAAe,IAAM,EAAe,KAAO,EAC3C,EAAe,IAAM,EAAe,KAAO,EAC3C,EAAe,IAAM,EAAe,KAAO,EAC3C,EAAe,IAAM,EAAe,KAAO,GAC3C,EAAe,IAAM,EAAe,KAAO,EAC3C,EAAe,IAAM,EAAe,KAAO,EAC3C,EAAe,IAAM,EAAe,KAAO,EAC3C,EAAe,IAAM,EAAe,KAAO,EAG3C,EAAe,KAAO,EAAe,IAAM,EAC3C,EAAe,KAAO,EAAe,IAAM,EAC3C,EAAe,KAAO,EAAe,IAAM,EAC3C,EAAe,KAAO,EAAe,IAAM,EAC3C,EAAe,KAAO,EAAe,IAAM,EAC3C,EAAe,KAAO,EAAe,IAAM,EAE3C,EAAe,KAAO,EAAe,IAAM,EAC3C,EAAe,KAAO,EAAe,IAAM,EAC3C,EAAe,KAAO,EAAe,IAAM,EAC3C,EAAe,KAAO,EAAe,IAAM,GAC3C,EAAe,KAAO,EAAe,IAAM,EAC3C,EAAe,KAAO,EAAe,IAAM,EAE3C,EAAe,IAAM,EAAe,IAAM,GAC1C,EAAe,IAAM,EAAe,IAAM,EAC1C,EAAe,IAAM,EAAe,IAAM,EAC1C,EAAe,IAAM,EAAe,IAAM,EAC1C,EAAe,IAAM,EAAe,IAAM,GAC1C,EAAe,IAAM,EAAe,IAAM,EAE1C,EAAe,IAAM,EAAe,IAAM,EAC1C,EAAe,IAAM,EAAe,IAAM,GAC1C,EAAe,IAAM,EAAe,IAAM,EAC1C,EAAe,IAAM,EAAe,IAAM,EAC1C,EAAe,IAAM,EAAe,IAAM,EAC1C,EAAe,IAAM,EAAe,IAAM,EAE1C,EAAe,IAAM,EAAe,IAAM,EAC1C,EAAe,IAAM,EAAe,IAAM,EAC1C,EAAe,IAAM,EAAe,IAAM,EAC1C,EAAe,IAAM,EAAe,IAAM,GAC1C,EAAe,IAAM,EAAe,IAAM,EAC1C,EAAe,IAAM,EAAe,IAAM,EAC1C,EAAe,IAAM,EAAe,IAAM,EAC1C,EAAe,IAAM,EAAe,IAAM,EAC1C,EAAe,IAAM,EAAe,IAAM,EAC1C,EAAe,IAAM,EAAe,IAAM,EAC1C,EAAe,IAAM,EAAe,IAAM,EAC1C,EAAe,IAAM,EAAe,IAAM,EAE1C,EAAe,IAAM,EAAe,KAAO,EAC3C,EAAe,IAAM,EAAe,KAAO,GAC3C,EAAe,IAAM,EAAe,KAAO,EAC3C,EAAe,IAAM,EAAe,KAAO,EAC3C,EAAe,IAAM,EAAe,KAAO,EAC3C,EAAe,IAAM,EAAe,KAAO,EAC3C,EAAe,IAAM,EAAe,KAAO,EAC3C,EAAe,IAAM,EAAe,KAAO,EAC3C,EAAe,IAAM,EAAe,KAAO,EAC3C,EAAe,IAAM,EAAe,KAAO,EAC3C,EAAe,IAAM,EAAe,KAAO,GAC3C,EAAe,IAAM,EAAe,KAAO,EAE3C,EAAe,GAAK,EAAe,KAAO,GAC1C,EAAe,GAAK,EAAe,KAAO,EAC1C,EAAe,GAAK,EAAe,KAAO,EAC1C,EAAe,GAAK,EAAe,KAAO,GAC1C,EAAe,GAAK,EAAe,KAAO,EAC1C,EAAe,GAAK,EAAe,KAAO,EAC1C,EAAe,GAAK,EAAe,KAAO,EAC1C,EAAe,GAAK,EAAe,KAAO,GAC1C,EAAe,GAAK,EAAe,KAAO,EAC1C,EAAe,GAAK,EAAe,KAAO,EAC1C,EAAe,GAAK,EAAe,KAAO,EAC1C,EAAe,GAAK,EAAe,KAAO,EAE1C,EAAe,KAAO,EAAe,IAAM,EAC3C,EAAe,KAAO,EAAe,IAAM,EAC3C,EAAe,KAAO,EAAe,IAAM,EAC3C,EAAe,KAAO,EAAe,IAAM,EAC3C,EAAe,KAAO,EAAe,IAAM,EAC3C,EAAe,KAAO,EAAe,IAAM,EAC3C,EAAe,KAAO,EAAe,IAAM,GAC3C,EAAe,KAAO,EAAe,IAAM,EAC3C,EAAe,KAAO,EAAe,IAAM,EAC3C,EAAe,KAAO,EAAe,IAAM,EAC3C,EAAe,KAAO,EAAe,IAAM,GAC3C,EAAe,KAAO,EAAe,IAAM,EAE3C,EAAe,IAAM,EAAe,KAAO,EAC3C,EAAe,IAAM,EAAe,KAAO,EAC3C,EAAe,IAAM,EAAe,KAAO,EAC3C,EAAe,IAAM,EAAe,KAAO,GAC3C,EAAe,IAAM,EAAe,KAAO,EAC3C,EAAe,IAAM,EAAe,KAAO,EAC3C,EAAe,IAAM,EAAe,KAAO,EAC3C,EAAe,IAAM,EAAe,KAAO,GAC3C,EAAe,IAAM,EAAe,KAAO,EAC3C,EAAe,IAAM,EAAe,KAAO,EAC3C,EAAe,IAAM,EAAe,KAAO,GAC3C,EAAe,IAAM,EAAe,KAAO,EAE3C,EAAe,KAAO,EAAe,IAAM,GAC3C,EAAe,KAAO,EAAe,IAAM,EAC3C,EAAe,KAAO,EAAe,IAAM,EAC3C,EAAe,KAAO,EAAe,IAAM,EAC3C,EAAe,KAAO,EAAe,IAAM,EAC3C,EAAe,KAAO,EAAe,IAAM,EAC3C,EAAe,KAAO,EAAe,IAAM,EAC3C,EAAe,KAAO,EAAe,IAAM,EAC3C,EAAe,KAAO,EAAe,IAAM,EAC3C,EAAe,KAAO,EAAe,IAAM,GAC3C,EAAe,KAAO,EAAe,IAAM,EAC3C,EAAe,KAAO,EAAe,IAAM,EAE3C,EAAe,IAAM,EAAe,KAAO,EAC3C,EAAe,IAAM,EAAe,KAAO,EAC3C,EAAe,IAAM,EAAe,KAAO,EAC3C,EAAe,IAAM,EAAe,KAAO,EAC3C,EAAe,IAAM,EAAe,KAAO,EAC3C,EAAe,IAAM,EAAe,KAAO,EAC3C,EAAe,IAAM,EAAe,KAAO,EAC3C,EAAe,IAAM,EAAe,KAAO,GAC3C,EAAe,IAAM,EAAe,KAAO,EAC3C,EAAe,IAAM,EAAe,KAAO,EAC3C,EAAe,IAAM,EAAe,KAAO,EAC3C,EAAe,IAAM,EAAe,KAAO,EAE3C,EAAe,GAAK,EAAe,KAAO,GAC1C,EAAe,GAAK,EAAe,KAAO,EAC1C,EAAe,GAAK,EAAe,KAAO,EAC1C,EAAe,GAAK,EAAe,KAAO,EAC1C,EAAe,GAAK,EAAe,KAAO,GAC1C,EAAe,GAAK,EAAe,KAAO,EAC1C,EAAe,GAAK,EAAe,KAAO,EAC1C,EAAe,GAAK,EAAe,KAAO,EAC1C,EAAe,GAAK,EAAe,KAAO,EAC1C,EAAe,GAAK,EAAe,KAAO,EAC1C,EAAe,GAAK,EAAe,KAAO,EAC1C,EAAe,GAAK,EAAe,KAAO,EAG1C,EAAe,KAAO,EACtB,EAAe,KAAO,EACtB,EAAe,KAAO,EACtB,EAAe,KAAO,EACtB,EAAe,KAAO,EACtB,EAAe,KAAO,EACtB,EAAe,KAAO,GACtB,EAAe,KAAO,EACtB,EAAe,KAAO,EACtB,EAAe,KAAO,GACtB,EAAe,KAAO,EACtB,EAAe,KAAO,EACtB,EAAe,KAAO,EACtB,EAAe,KAAO,GACtB,EAAe,KAAO,EACtB,EAAe,KAAO,EACtB,EAAe,KAAO,GACtB,EAAe,KAAO,EACtB,EAAe,KAAO,EACtB,EAAe,KAAO,EACtB,EAAe,KAAO,EACtB,EAAe,KAAO,EACtB,EAAe,KAAO,EACtB,EAAe,KAAO,EAEtB,EAAe,IAAM,EACrB,EAAe,IAAM,GACrB,EAAe,IAAM,EACrB,EAAe,IAAM,EACrB,EAAe,IAAM,GACrB,EAAe,IAAM,EACrB,EAAe,IAAM,EACrB,EAAe,IAAM,EACrB,EAAe,IAAM,EACrB,EAAe,IAAM,EACrB,EAAe,IAAM,EACrB,EAAe,IAAM,EACrB,EAAe,IAAM,EACrB,EAAe,IAAM,EACrB,EAAe,IAAM,EACrB,EAAe,IAAM,EACrB,EAAe,IAAM,EACrB,EAAe,IAAM,EACrB,EAAe,IAAM,GACrB,EAAe,IAAM,EACrB,EAAe,IAAM,EACrB,EAAe,IAAM,GACrB,EAAe,IAAM,EACrB,EAAe,IAAM,EAErB,EAAe,IAAM,EACrB,EAAe,IAAM,EACrB,EAAe,IAAM,EACrB,EAAe,IAAM,EACrB,EAAe,IAAM,GACrB,EAAe,IAAM,EACrB,EAAe,IAAM,EACrB,EAAe,IAAM,EACrB,EAAe,IAAM,EACrB,EAAe,IAAM,GACrB,EAAe,IAAM,EACrB,EAAe,IAAM,EACrB,EAAe,IAAM,EACrB,EAAe,IAAM,GACrB,EAAe,IAAM,EACrB,EAAe,IAAM,EACrB,EAAe,IAAM,EACrB,EAAe,IAAM,EACrB,EAAe,IAAM,GACrB,EAAe,IAAM,EACrB,EAAe,IAAM,EACrB,EAAe,IAAM,EACrB,EAAe,IAAM,EACrB,EAAe,IAAM,EAGrB,EAAe,KAAO,EACtB,EAAe,KAAO,EACtB,EAAe,KAAO,EACtB,EAAe,KAAO,GACtB,EAAe,KAAO,EACtB,EAAe,KAAO,EACtB,EAAe,KAAO,EACtB,EAAe,KAAO,GACtB,EAAe,KAAO,EACtB,EAAe,KAAO,EACtB,EAAe,KAAO,EACtB,EAAe,KAAO,EAEtB,EAAe,KAAO,EACtB,EAAe,KAAO,GACtB,EAAe,KAAO,EACtB,EAAe,KAAO,EACtB,EAAe,KAAO,EACtB,EAAe,KAAO,EACtB,EAAe,KAAO,EACtB,EAAe,KAAO,EACtB,EAAe,KAAO,EACtB,EAAe,KAAO,GACtB,EAAe,KAAO,EACtB,EAAe,KAAO,EAEtB,EAAe,KAAO,EACtB,EAAe,KAAO,GACtB,EAAe,KAAO,EACtB,EAAe,KAAO,EACtB,EAAe,KAAO,EACtB,EAAe,KAAO,EACtB,EAAe,KAAO,EACtB,EAAe,KAAO,EACtB,EAAe,KAAO,EACtB,EAAe,KAAO,GACtB,EAAe,KAAO,EACtB,EAAe,KAAO,EAEtB,EAAe,KAAO,EACtB,EAAe,KAAO,EACtB,EAAe,KAAO,EACtB,EAAe,KAAO,GACtB,EAAe,KAAO,EACtB,EAAe,KAAO,EACtB,EAAe,KAAO,EACtB,EAAe,KAAO,GACtB,EAAe,KAAO,EACtB,EAAe,KAAO,EACtB,EAAe,KAAO,EACtB,EAAe,KAAO,EAGtB,EAAe,KAAO,EACtB,EAAe,KAAO,EACtB,EAAe,KAAO,EACtB,EAAe,KAAO,GACtB,EAAe,KAAO,EACtB,EAAe,KAAO,EACtB,EAAe,KAAO,GACtB,EAAe,KAAO,EACtB,EAAe,KAAO,EACtB,EAAe,KAAO,EACtB,EAAe,KAAO,GACtB,EAAe,KAAO,EACtB,EAAe,KAAO,EACtB,EAAe,KAAO,GACtB,EAAe,KAAO,EACtB,EAAe,KAAO,EACtB,EAAe,KAAO,EACtB,EAAe,KAAO,EAEtB,EAAe,KAAO,EACtB,EAAe,KAAO,GACtB,EAAe,KAAO,EACtB,EAAe,KAAO,EACtB,EAAe,KAAO,EACtB,EAAe,KAAO,EACtB,EAAe,KAAO,GACtB,EAAe,KAAO,EACtB,EAAe,KAAO,EACtB,EAAe,KAAO,EACtB,EAAe,KAAO,GACtB,EAAe,KAAO,EACtB,EAAe,KAAO,EACtB,EAAe,KAAO,EACtB,EAAe,KAAO,EACtB,EAAe,KAAO,GACtB,EAAe,KAAO,EACtB,EAAe,KAAO,EAEtB,EAAe,KAAO,EACtB,EAAe,KAAO,EACtB,EAAe,KAAO,EACtB,EAAe,KAAO,EACtB,EAAe,KAAO,EACtB,EAAe,KAAO,EACtB,EAAe,KAAO,GACtB,EAAe,KAAO,EACtB,EAAe,KAAO,EACtB,EAAe,KAAO,EACtB,EAAe,KAAO,GACtB,EAAe,KAAO,EACtB,EAAe,KAAO,EACtB,EAAe,KAAO,EACtB,EAAe,KAAO,EACtB,EAAe,KAAO,EACtB,EAAe,KAAO,EACtB,EAAe,KAAO,EAEtB,EAAe,KAAO,EACtB,EAAe,KAAO,EACtB,EAAe,KAAO,EACtB,EAAe,KAAO,EACtB,EAAe,KAAO,GACtB,EAAe,KAAO,EACtB,EAAe,KAAO,EACtB,EAAe,KAAO,EACtB,EAAe,KAAO,EACtB,EAAe,KAAO,EACtB,EAAe,KAAO,EACtB,EAAe,KAAO,EACtB,EAAe,KAAO,GACtB,EAAe,KAAO,EACtB,EAAe,KAAO,EACtB,EAAe,KAAO,EACtB,EAAe,KAAO,EACtB,EAAe,KAAO,EAEtB,EAAe,IAAM,EACrB,EAAe,IAAM,GACrB,EAAe,IAAM,EACrB,EAAe,IAAM,EACrB,EAAe,IAAM,GACrB,EAAe,IAAM,EACrB,EAAe,IAAM,EACrB,EAAe,IAAM,EACrB,EAAe,IAAM,EACrB,EAAe,IAAM,EACrB,EAAe,IAAM,EACrB,EAAe,IAAM,EACrB,EAAe,IAAM,EACrB,EAAe,IAAM,EACrB,EAAe,IAAM,EACrB,EAAe,IAAM,GACrB,EAAe,IAAM,EACrB,EAAe,IAAM,EAErB,EAAe,IAAM,EACrB,EAAe,IAAM,EACrB,EAAe,IAAM,EACrB,EAAe,IAAM,EACrB,EAAe,IAAM,GACrB,EAAe,IAAM,EACrB,EAAe,IAAM,EA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"}