From a7d17df05e5b53c5e98a56f00ecd5e5aa340e2c1 Mon Sep 17 00:00:00 2001 From: Jeff Jacobson Date: Tue, 3 Dec 2024 16:56:34 -0800 Subject: [PATCH 01/24] build: :arrow_up: upgrade dependencies in lockfile --- pnpm-lock.yaml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 7e598f9b..66d4afeb 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -900,8 +900,8 @@ packages: cpu: [x64] os: [win32] - '@esri/arcgis-html-sanitizer@4.1.0-next.4': - resolution: {integrity: sha512-CFDBFVgCLLaY6qBS70oozzIPXkTTCVkG/KFkjAZHIPYMgxgFtYPMBETRutELQQWDJa0Tv1QNK1N/7NyaKfsPvQ==} + '@esri/arcgis-html-sanitizer@4.1.0': + resolution: {integrity: sha512-einEveDJ/k1180NOp78PB/4Hje9eBy3dyOGLLtLn6bSkizpUfCwuYBIXOA7Y3F/k/BsTQXgKqUVwQ0eiscWMdA==} engines: {node: '>=18.0.0'} '@esri/calcite-colors@6.1.0': @@ -1332,8 +1332,8 @@ packages: resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} engines: {node: '>=6'} - caniuse-lite@1.0.30001685: - resolution: {integrity: sha512-e/kJN1EMyHQzgcMEEgoo+YTCO1NGCmIYHk5Qk8jT6AazWemS5QFKJ5ShCJlH3GZrNIdZofcNCEwZqbMjjKzmnA==} + caniuse-lite@1.0.30001686: + resolution: {integrity: sha512-Y7deg0Aergpa24M3qLC5xjNklnKnhsmSyR/V89dLZ1n0ucJIFNs7PgR2Yfa/Zf6W79SbBicgtGxZr2juHkEUIA==} chai@5.1.2: resolution: {integrity: sha512-aGtmf24DW6MLHHG5gCx4zaI3uBq3KRtxeVs0DjFH6Z0rDNbsvTxFASFvdj79pxjxZ8/5u3PIiN3IwEIQkiiuPw==} @@ -2465,7 +2465,7 @@ snapshots: '@arcgis/core@4.31.6(@floating-ui/utils@0.2.8)': dependencies: - '@esri/arcgis-html-sanitizer': 4.1.0-next.4 + '@esri/arcgis-html-sanitizer': 4.1.0 '@esri/calcite-colors': 6.1.0 '@esri/calcite-components': 2.13.2(@floating-ui/utils@0.2.8) '@vaadin/grid': 24.5.4 @@ -3038,7 +3038,7 @@ snapshots: '@esbuild/win32-x64@0.24.0': optional: true - '@esri/arcgis-html-sanitizer@4.1.0-next.4': + '@esri/arcgis-html-sanitizer@4.1.0': dependencies: xss: 1.0.13 @@ -3526,7 +3526,7 @@ snapshots: browserslist@4.24.2: dependencies: - caniuse-lite: 1.0.30001685 + caniuse-lite: 1.0.30001686 electron-to-chromium: 1.5.68 node-releases: 2.0.18 update-browserslist-db: 1.1.1(browserslist@4.24.2) @@ -3535,7 +3535,7 @@ snapshots: callsites@3.1.0: {} - caniuse-lite@1.0.30001685: {} + caniuse-lite@1.0.30001686: {} chai@5.1.2: dependencies: From 7be7b9a3b56494d34cdc7642cd3d54af643753e3 Mon Sep 17 00:00:00 2001 From: Jeff Jacobson Date: Tue, 3 Dec 2024 16:59:01 -0800 Subject: [PATCH 02/24] chore: :technologist: ignore pnpm lockfile in cspell config --- cspell.config.yaml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cspell.config.yaml b/cspell.config.yaml index b29b2940..663bc9ac 100644 --- a/cspell.config.yaml +++ b/cspell.config.yaml @@ -1,6 +1,7 @@ version: "0.2" useGitignore: true -ignorePaths: [] +ignorePaths: + - pnpm-lock.yaml allowCompoundWords: true features: weighted-suggestions: true From f01a461fd7ac14054cd9398279dc15643bdf268b Mon Sep 17 00:00:00 2001 From: Jeff Jacobson Date: Wed, 4 Dec 2024 17:16:16 -0800 Subject: [PATCH 03/24] refactor: :recycle: Add route segment CIM definitions --- src/layers/MilepostLayer/fields.ts | 77 +++++++++++++++++ src/layers/MilepostLayer/index.ts | 53 +----------- .../MilepostOffsetLineRenderer.ts | 3 +- .../milepost-line-layer/index.ts | 3 +- .../milepost-point-layer/index.ts | 3 +- src/layers/MilepostLayer/symbol/index.ts | 84 ++++++++++++------- .../symbol/primitiveOverrides.ts | 28 +++++++ 7 files changed, 164 insertions(+), 87 deletions(-) create mode 100644 src/layers/MilepostLayer/fields.ts create mode 100644 src/layers/MilepostLayer/symbol/primitiveOverrides.ts diff --git a/src/layers/MilepostLayer/fields.ts b/src/layers/MilepostLayer/fields.ts new file mode 100644 index 00000000..8a634f2e --- /dev/null +++ b/src/layers/MilepostLayer/fields.ts @@ -0,0 +1,77 @@ +import type { FieldProperties } from "."; +import { objectIdFieldName } from "../../elc/types"; + +/** + * Field names for the milepost layer + */ +export enum fieldNames { + Route = "Route", + Srmp = "Srmp", + Back = "Back", + Direction = "Direction", + EndSrmp = "EndSrmp", + EndBack = "EndBack", +} + +/** + * Field definitions for the milepost layer + */ +export const fields: FieldProperties[] = [ + { + name: objectIdFieldName, + type: "oid", + valueType: "unique-identifier", + }, + { + name: fieldNames.Route, + type: "string", + valueType: "name-or-title", + }, + { + name: fieldNames.Direction, + type: "string", + domain: { + type: "coded-value", + codedValues: [ + { + code: "I", + name: "Increase", + }, + { + code: "D", + name: "Decrease", + }, + ], + name: "Direction", + }, + defaultValue: "I", + valueType: "type-or-category", + }, + { + name: fieldNames.Srmp, + type: "double", + valueType: "measurement", + }, + { + name: fieldNames.Back, + type: "string", + valueType: "binary", + }, +]; + +/** + * Field definitions for the route segments layer + */ +export const segmentFields = [ + ...fields, + { + name: fieldNames.EndSrmp, + type: "double", + valueType: "measurement", + }, + { + name: fieldNames.EndBack, + type: "string", + valueType: "binary", + }, +]; diff --git a/src/layers/MilepostLayer/index.ts b/src/layers/MilepostLayer/index.ts index 60e43fe9..524580af 100644 --- a/src/layers/MilepostLayer/index.ts +++ b/src/layers/MilepostLayer/index.ts @@ -3,64 +3,13 @@ import type FeatureLayer from "@arcgis/core/layers/FeatureLayer"; import type Field from "@arcgis/core/layers/support/Field"; import FieldInfo from "@arcgis/core/popup/FieldInfo"; import ActionButton from "@arcgis/core/support/actions/ActionButton"; -import { objectIdFieldName } from "../../elc/types"; import type { MilepostExpressionInfo } from "./arcade"; import { expressions as arcadeExpressions, locationLinksContent, } from "./arcade"; -type FieldProperties = Required>[0]; - -export enum fieldNames { - Route = "Route", - Srmp = "Srmp", - Back = "Back", - Direction = "Direction", -} - -export const fields = [ - { - name: objectIdFieldName, - type: "oid", - valueType: "unique-identifier", - }, - { - name: fieldNames.Route, - type: "string", - valueType: "name-or-title", - }, - { - name: fieldNames.Direction, - type: "string", - domain: { - type: "coded-value", - codedValues: [ - { - code: "I", - name: "Increase", - }, - { - code: "D", - name: "Decrease", - }, - ], - name: "Direction", - }, - defaultValue: "I", - valueType: "type-or-category", - }, - { - name: fieldNames.Srmp, - type: "double", - valueType: "measurement", - }, - { - name: fieldNames.Back, - type: "string", - valueType: "binary", - }, -] as FieldProperties[]; +export type FieldProperties = Required>[0]; const actionButtonProperties: __esri.ActionButtonProperties[] = [ { diff --git a/src/layers/MilepostLayer/milepost-line-layer/MilepostOffsetLineRenderer.ts b/src/layers/MilepostLayer/milepost-line-layer/MilepostOffsetLineRenderer.ts index b8564844..e4158b92 100644 --- a/src/layers/MilepostLayer/milepost-line-layer/MilepostOffsetLineRenderer.ts +++ b/src/layers/MilepostLayer/milepost-line-layer/MilepostOffsetLineRenderer.ts @@ -1,6 +1,7 @@ import SimpleRenderer from "@arcgis/core/renderers/SimpleRenderer"; import CIMSymbol from "@arcgis/core/symbols/CIMSymbol"; -import { cimVectorMarker, primitiveOverrides } from "../symbol"; +import { cimVectorMarker } from "../symbol"; +import { primitiveOverrides } from "../symbol/primitiveOverrides"; const clickPointSymbolLayer: __esri.CIMVectorMarker = { type: "CIMVectorMarker", diff --git a/src/layers/MilepostLayer/milepost-line-layer/index.ts b/src/layers/MilepostLayer/milepost-line-layer/index.ts index a72aa12a..fccb770f 100644 --- a/src/layers/MilepostLayer/milepost-line-layer/index.ts +++ b/src/layers/MilepostLayer/milepost-line-layer/index.ts @@ -1,7 +1,8 @@ import FeatureLayer from "@arcgis/core/layers/FeatureLayer"; -import { createPopupTemplate, fields } from ".."; +import { createPopupTemplate } from ".."; import waExtent from "../../../WAExtent"; import { objectIdFieldName } from "../../../elc/types"; +import { fields } from "../fields"; import MilepostOffsetLineRenderer from "./MilepostOffsetLineRenderer"; /** diff --git a/src/layers/MilepostLayer/milepost-point-layer/index.ts b/src/layers/MilepostLayer/milepost-point-layer/index.ts index b1fc67af..e427a05b 100644 --- a/src/layers/MilepostLayer/milepost-point-layer/index.ts +++ b/src/layers/MilepostLayer/milepost-point-layer/index.ts @@ -1,9 +1,10 @@ import type SpatialReference from "@arcgis/core/geometry/SpatialReference"; import FeatureLayer from "@arcgis/core/layers/FeatureLayer"; import SimpleRenderer from "@arcgis/core/renderers/SimpleRenderer"; -import { createPopupTemplate, fields } from ".."; +import { createPopupTemplate } from ".."; import waExtent from "../../../WAExtent"; import { objectIdFieldName } from "../../../elc/types"; +import { fields } from "../fields"; import { milepostSymbol } from "../symbol"; /** diff --git a/src/layers/MilepostLayer/symbol/index.ts b/src/layers/MilepostLayer/symbol/index.ts index d83c728d..250cce5e 100644 --- a/src/layers/MilepostLayer/symbol/index.ts +++ b/src/layers/MilepostLayer/symbol/index.ts @@ -1,17 +1,28 @@ import CIMSymbol from "@arcgis/core/symbols/CIMSymbol"; +import { + primitiveOverrides, + routeSegmentPrimitiveOverrides, +} from "./primitiveOverrides"; -export const primitiveOverrides: __esri.PrimitiveOverride[] = [ - { - primitiveName: "milepostLabel", - propertyName: "textString", - type: "CIMPrimitiveOverride", - valueExpressionInfo: { - expression: "`${$feature.Route}\\n${$feature.SRMP}${$feature.Back}`", - type: "CIMExpressionInfo", - returnType: "String", - }, +const cimCallout: __esri.CIMBackgroundCallout = { + type: "CIMBackgroundCallout", + backgroundSymbol: { + type: "CIMPolygonSymbol", + symbolLayers: [ + { + type: "CIMSolidFill", + color: [1, 115, 92, 255], + enable: true, + }, + { + type: "CIMSolidStroke", + color: [0, 0, 0, 0], + width: 1, + enable: true, + }, + ], }, -]; +}; const cimTextSymbol: __esri.CIMTextSymbol = { type: "CIMTextSymbol", angle: 0, @@ -37,33 +48,22 @@ const cimTextSymbol: __esri.CIMTextSymbol = { symbolLayers: [{ type: "CIMSolidFill", enable: true, color: [0, 0, 0, 0] }], }, verticalAlignment: "Baseline", - callout: { - type: "CIMBackgroundCallout", - backgroundSymbol: { - type: "CIMPolygonSymbol", - symbolLayers: [ - { - type: "CIMSolidFill", - color: [1, 115, 92, 255], - enable: true, - }, - { - type: "CIMSolidStroke", - color: [0, 0, 0, 0], - width: 1, - enable: true, - }, - ], - }, - }, + callout: cimCallout, }; const cimMarkerGraphic: __esri.CIMMarkerGraphic = { type: "CIMMarkerGraphic", geometry: { x: 0, y: 0 }, primitiveName: "milepostLabel", symbol: cimTextSymbol, - textString: "000SPABCDEF\n0000.00B", + textString: "ROUTE\nMILE.POSTB", +}; + +const endpointCimMarkerGraphic: __esri.CIMMarkerGraphic = { + ...cimMarkerGraphic, + primitiveName: "endMilepostLabel", + textString: "ROUTE\nEND.MILEPOSTB", }; + export const cimVectorMarker: __esri.CIMVectorMarker = { type: "CIMVectorMarker", enable: true, @@ -74,18 +74,38 @@ export const cimVectorMarker: __esri.CIMVectorMarker = { scaleSymbolsProportionally: true, respectFrame: true, }; + +export const endpointCimVectorMarker: __esri.CIMVectorMarker = { + ...cimVectorMarker, + markerGraphics: [endpointCimMarkerGraphic], +}; + const cimPointSymbol: __esri.CIMPointSymbol = { type: "CIMPointSymbol", symbolLayers: [cimVectorMarker], scaleX: 1, angleAlignment: "Display", }; + +const endpointCimPointSymbol: __esri.CIMPointSymbol = { + ...cimPointSymbol, + symbolLayers: [endpointCimVectorMarker], +}; + export const milepostSymbol = new CIMSymbol({ data: { - primitiveOverrides, + primitiveOverrides: primitiveOverrides, type: "CIMSymbolReference", symbol: cimPointSymbol, }, }); +export const endpointMilepostSymbol = new CIMSymbol({ + data: { + primitiveOverrides: routeSegmentPrimitiveOverrides, + type: "CIMSymbolReference", + symbol: endpointCimPointSymbol, + }, +}); + export default milepostSymbol; diff --git a/src/layers/MilepostLayer/symbol/primitiveOverrides.ts b/src/layers/MilepostLayer/symbol/primitiveOverrides.ts new file mode 100644 index 00000000..d3235c18 --- /dev/null +++ b/src/layers/MilepostLayer/symbol/primitiveOverrides.ts @@ -0,0 +1,28 @@ +const beginMilepostExpressionInfo = { + expression: "`${$feature.Route}\\n${$feature.SRMP}${$feature.Back}`", + type: "CIMExpressionInfo", + returnType: "String", +} as const; +const endMilepostExpressionInfo = { + ...beginMilepostExpressionInfo, + expression: "`${$feature.Route}\\n${$feature.EndSrmp}${$feature.EndBack}`", +} as const; +const milepostLabelPrimitiveOverride: __esri.PrimitiveOverride = { + primitiveName: "milepostLabel", + propertyName: "textString", + type: "CIMPrimitiveOverride", + valueExpressionInfo: beginMilepostExpressionInfo, +} as const; +const endMilepostLabelPrimitiveOverride: __esri.PrimitiveOverride = { + ...milepostLabelPrimitiveOverride, + primitiveName: "endMilepostLabel", + valueExpressionInfo: endMilepostExpressionInfo, +}; + +export const primitiveOverrides: __esri.PrimitiveOverride[] = [ + milepostLabelPrimitiveOverride, +]; +export const routeSegmentPrimitiveOverrides = [ + milepostLabelPrimitiveOverride, + endMilepostLabelPrimitiveOverride, +]; From 1a6e2f2d8e6b7771a2549b0d845483eb2e64b5a6 Mon Sep 17 00:00:00 2001 From: Jeff Jacobson Date: Wed, 4 Dec 2024 17:20:33 -0800 Subject: [PATCH 04/24] refactor: :recycle: remove default export on layers/MilepostLayer/symbol --- src/layers/MilepostLayer/symbol/index.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/layers/MilepostLayer/symbol/index.ts b/src/layers/MilepostLayer/symbol/index.ts index 250cce5e..e0951848 100644 --- a/src/layers/MilepostLayer/symbol/index.ts +++ b/src/layers/MilepostLayer/symbol/index.ts @@ -107,5 +107,3 @@ export const endpointMilepostSymbol = new CIMSymbol({ symbol: endpointCimPointSymbol, }, }); - -export default milepostSymbol; From f655572b37c09a50df34f51311754158cf27264c Mon Sep 17 00:00:00 2001 From: Jeff Jacobson Date: Wed, 4 Dec 2024 17:41:28 -0800 Subject: [PATCH 05/24] chore: :hammer: create-cim script now adds primitive overrides --- tools/create-cim.ts | 37 ++++++++++++++++++++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) diff --git a/tools/create-cim.ts b/tools/create-cim.ts index b8f01c36..054cfe9e 100644 --- a/tools/create-cim.ts +++ b/tools/create-cim.ts @@ -1,3 +1,8 @@ +/** + * This script was used to create the milepost marker symbol, + * after which it was further modified. + */ + import TextSymbol from "@arcgis/core/symbols/TextSymbol"; import { convertToCIMSymbol } from "@arcgis/core/symbols/support/cimConversionUtils"; import { @@ -15,4 +20,34 @@ const cimSymbol = convertToCIMSymbol( simpleSymbol as unknown as __esri.SimpleMarkerSymbol, ); -console.log(JSON.stringify(cimSymbol.toJSON())); +cimSymbol.data.primitiveOverrides = [ + { + primitiveName: "milepostLabel", + propertyName: "textString", + valueExpressionInfo: { + expression: "`${$feature.Route}\\n${$feature.SRMP}${$feature.Back}`", + type: "CIMExpressionInfo", + returnType: "String", + }, + }, +]; + +if (cimSymbol.data.symbol?.symbolLayers) { + let found = false; + for (const layer of cimSymbol.data.symbol.symbolLayers.filter( + (l) => l.type === "CIMVectorMarker", + )) { + for (const markerGraphic of layer.markerGraphics.filter( + (g) => g.symbol.type === "CIMTextSymbol", + )) { + markerGraphic.primitiveName = "milepostLabel"; + found = true; + break; + } + if (found) { + break; + } + } +} + +console.log(JSON.stringify(cimSymbol.toJSON(), null, 2)); From 62a2f4e668c28a6e279e5482c582974e4ff5c296 Mon Sep 17 00:00:00 2001 From: Jeff Jacobson Date: Thu, 5 Dec 2024 10:51:45 -0800 Subject: [PATCH 06/24] refactor: :hammer: Refactor create-cim --- tools/create-cim.ts | 147 ++++++++++++++++++++++++++++++++++---------- 1 file changed, 115 insertions(+), 32 deletions(-) diff --git a/tools/create-cim.ts b/tools/create-cim.ts index 054cfe9e..6a574cf2 100644 --- a/tools/create-cim.ts +++ b/tools/create-cim.ts @@ -10,44 +10,127 @@ import { highwaySignTextColor, } from "../src/colors"; -const simpleSymbol = new TextSymbol({ - color: highwaySignTextColor, - backgroundColor: highwaySignBackgroundColor, - text: "000SPABCDEF\n0000.00B", -}); - -const cimSymbol = convertToCIMSymbol( - simpleSymbol as unknown as __esri.SimpleMarkerSymbol, -); - -cimSymbol.data.primitiveOverrides = [ - { - primitiveName: "milepostLabel", - propertyName: "textString", - valueExpressionInfo: { - expression: "`${$feature.Route}\\n${$feature.SRMP}${$feature.Back}`", - type: "CIMExpressionInfo", - returnType: "String", - }, - }, -]; - -if (cimSymbol.data.symbol?.symbolLayers) { - let found = false; - for (const layer of cimSymbol.data.symbol.symbolLayers.filter( - (l) => l.type === "CIMVectorMarker", - )) { - for (const markerGraphic of layer.markerGraphics.filter( - (g) => g.symbol.type === "CIMTextSymbol", +/** + * The name of the text symbol that will have its + * text replaced by feature attributes. + */ +const defaultPrimitiveName = "milepostLabel"; + +/** + * Type guard function to check if a CIMSymbolLayer is a CIMVectorMarker. + * @param l - The CIMSymbolLayer to check. + * @returns A boolean indicating whether the provided layer is a CIMVectorMarker. + */ +function isVectorMarker(l: __esri.CIMSymbolLayer): l is __esri.CIMVectorMarker { + return l.type === "CIMVectorMarker"; +} + +/** + * Type for a CIMMarkerGraphic that has a CIMTextSymbol. + */ +type CIMMarkerGraphicWithTextSymbol = __esri.CIMMarkerGraphic & { + symbol: __esri.CIMTextSymbol; +}; + +/** + * Type guard function to check if a {@link __esri.CIMMarkerGraphic|CIMMarkerGraphic} is a {@link __esri.CIMTextSymbol|CIMTextSymbol}. + * @param g - The {@link __esri.CIMMarkerGraphic|CIMMarkerGraphic} to check. + * @returns A boolean indicating whether the provided graphic is a {@link __esri.CIMTextSymbol|CIMTextSymbol}. + */ +function isMarkerGraphicWithTextSymbol( + g: __esri.CIMMarkerGraphic, +): g is CIMMarkerGraphicWithTextSymbol { + return g.symbol.type === "CIMTextSymbol"; +} + +/** + * Sets the primitive name of the first {@link __esri.CIMTextSymbol|CIMTextSymbol} found within the + * {@link __esri.CIMSymbol|CIMSymbol}'s vector marker layers to the specified primitive name. + * + * @param cimSymbol - The {@link __esri.CIMSymbol|CIMSymbol} object containing symbol layers to search. + * @param primitiveName - The new primitive name to assign to the first + * {@link __esri.CIMTextSymbol|CIMTextSymbol} found. + * @throws {TypeError} Will throw an error if the symbol has no symbol layers. + * @returns The modified {@link __esri.CIMMarkerGraphic|CIMMarkerGraphic} if a {@link __esri.CIMTextSymbol|CIMTextSymbol} is found, + * otherwise null. + */ +function setPrimitiveNameOfFirstTextSymbol( + cimSymbol: __esri.CIMSymbol, + primitiveName: string, +) { + const symbolLayers = cimSymbol.data.symbol?.symbolLayers; + if (!symbolLayers) { + throw new TypeError("Symbol has no symbol layers"); + } + + let textSymbol: CIMMarkerGraphicWithTextSymbol | null = null; + + // Find the text symbol and set its primitive name. + for (const layer of symbolLayers.filter(isVectorMarker)) { + const markerGraphics = layer.markerGraphics; + for (const markerGraphic of markerGraphics.filter( + isMarkerGraphicWithTextSymbol, )) { - markerGraphic.primitiveName = "milepostLabel"; - found = true; + markerGraphic.primitiveName = primitiveName; + textSymbol = markerGraphic; break; } - if (found) { + if (textSymbol) { break; } } + + return textSymbol; +} + +/** + * Creates a CIM symbol for a milepost marker. + * The symbol is a text symbol with white text on a green background. + * The text of the symbol is a placeholder that can be replaced + * with feature attributes by overriding "milepostLabel" primitive name. + * + * @returns A CIM symbol for a milepost marker. + */ +function createMilepostCimSymbol( + textSymbolProperties: __esri.TextSymbolProperties = { + color: highwaySignTextColor, + borderLineColor: highwaySignTextColor, + borderLineSize: 1, + backgroundColor: highwaySignBackgroundColor, + // cspell:disable-next-line + text: "ROUTE\nMILE.POSTB", + }, + primitiveName: string = defaultPrimitiveName, +) { + const simpleSymbol = new TextSymbol(textSymbolProperties); + + // Convert the text symbol into a CIM symbol. + const cimSymbol = convertToCIMSymbol( + // Since this function doesn't officially support TextSymbols, + // you have to pretend its one of the supported types. + simpleSymbol as unknown as __esri.SimpleMarkerSymbol, + ); + + // Set the primitive name of the first text symbol to "milepostLabel". + setPrimitiveNameOfFirstTextSymbol(cimSymbol, primitiveName); + + // Add primitive overrides to the symbol. + cimSymbol.data.primitiveOverrides = [ + { + primitiveName: primitiveName, + propertyName: "textString", + valueExpressionInfo: { + expression: "`${$feature.Route}\\n${$feature.SRMP}${$feature.Back}`", + type: "CIMExpressionInfo", + returnType: "String", + }, + }, + ]; + + return cimSymbol; } +// Create a text symbol with a background. +const cimSymbol = createMilepostCimSymbol(); + console.log(JSON.stringify(cimSymbol.toJSON(), null, 2)); From 22135cee2091ceaf9a7511731331bcfc164a5b8b Mon Sep 17 00:00:00 2001 From: Jeff Jacobson Date: Thu, 5 Dec 2024 10:54:01 -0800 Subject: [PATCH 07/24] refactor: :truck: Moved create-cim into src subfolder --- {tools => src/layers/MilepostLayer}/create-cim.ts | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) rename {tools => src/layers/MilepostLayer}/create-cim.ts (94%) diff --git a/tools/create-cim.ts b/src/layers/MilepostLayer/create-cim.ts similarity index 94% rename from tools/create-cim.ts rename to src/layers/MilepostLayer/create-cim.ts index 6a574cf2..036283f2 100644 --- a/tools/create-cim.ts +++ b/src/layers/MilepostLayer/create-cim.ts @@ -5,10 +5,7 @@ import TextSymbol from "@arcgis/core/symbols/TextSymbol"; import { convertToCIMSymbol } from "@arcgis/core/symbols/support/cimConversionUtils"; -import { - highwaySignBackgroundColor, - highwaySignTextColor, -} from "../src/colors"; +import { highwaySignBackgroundColor, highwaySignTextColor } from "../../colors"; /** * The name of the text symbol that will have its @@ -129,8 +126,3 @@ function createMilepostCimSymbol( return cimSymbol; } - -// Create a text symbol with a background. -const cimSymbol = createMilepostCimSymbol(); - -console.log(JSON.stringify(cimSymbol.toJSON(), null, 2)); From d0adfd0411ad3bf172dab40d86f4970b2d90a312 Mon Sep 17 00:00:00 2001 From: Jeff Jacobson Date: Thu, 5 Dec 2024 11:41:48 -0800 Subject: [PATCH 08/24] chore: :hammer: Restored script to create Milepost CIM The original script was moved and turned into a module. This new script calls this module, which does most of the work. --- src/layers/MilepostLayer/create-cim.ts | 2 +- tools/create-cim.ts | 17 +++++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) create mode 100644 tools/create-cim.ts diff --git a/src/layers/MilepostLayer/create-cim.ts b/src/layers/MilepostLayer/create-cim.ts index 036283f2..6a0225b2 100644 --- a/src/layers/MilepostLayer/create-cim.ts +++ b/src/layers/MilepostLayer/create-cim.ts @@ -88,7 +88,7 @@ function setPrimitiveNameOfFirstTextSymbol( * * @returns A CIM symbol for a milepost marker. */ -function createMilepostCimSymbol( +export function createMilepostCimSymbol( textSymbolProperties: __esri.TextSymbolProperties = { color: highwaySignTextColor, borderLineColor: highwaySignTextColor, diff --git a/tools/create-cim.ts b/tools/create-cim.ts new file mode 100644 index 00000000..c1cf6b00 --- /dev/null +++ b/tools/create-cim.ts @@ -0,0 +1,17 @@ +/** + * This script creates a CIM symbol for a milepost marker. + * @example + * ``` + * node --import=tsx ./tools/create-cim.ts > milepost.cim.json + * ``` + * or + * ``` + * tsx ./tools/create-cim.ts > milepost.cim.json + */ + +import { createMilepostCimSymbol } from "../src/layers/MilepostLayer/create-cim.ts"; + +// Create a text symbol with a background. +const cimSymbol = createMilepostCimSymbol(); + +console.log(JSON.stringify(cimSymbol.toJSON(), null, 2)); From b78ac67f687b9c3ec952b78c9a6fc8fcd235f975 Mon Sep 17 00:00:00 2001 From: Jeff Jacobson Date: Thu, 5 Dec 2024 11:54:30 -0800 Subject: [PATCH 09/24] refactor: :recycle: refactor milepost CIM definitions --- src/layers/MilepostLayer/symbol/index.ts | 11 ++++--- .../symbol/primitiveOverrides.ts | 33 ++++++++++++------- 2 files changed, 29 insertions(+), 15 deletions(-) diff --git a/src/layers/MilepostLayer/symbol/index.ts b/src/layers/MilepostLayer/symbol/index.ts index e0951848..94d456e0 100644 --- a/src/layers/MilepostLayer/symbol/index.ts +++ b/src/layers/MilepostLayer/symbol/index.ts @@ -1,7 +1,7 @@ import CIMSymbol from "@arcgis/core/symbols/CIMSymbol"; import { - primitiveOverrides, - routeSegmentPrimitiveOverrides, + endMilepostLabelPrimitiveOverride, + milepostLabelPrimitiveOverride, } from "./primitiveOverrides"; const cimCallout: __esri.CIMBackgroundCallout = { @@ -94,7 +94,7 @@ const endpointCimPointSymbol: __esri.CIMPointSymbol = { export const milepostSymbol = new CIMSymbol({ data: { - primitiveOverrides: primitiveOverrides, + primitiveOverrides: [milepostLabelPrimitiveOverride], type: "CIMSymbolReference", symbol: cimPointSymbol, }, @@ -102,7 +102,10 @@ export const milepostSymbol = new CIMSymbol({ export const endpointMilepostSymbol = new CIMSymbol({ data: { - primitiveOverrides: routeSegmentPrimitiveOverrides, + primitiveOverrides: [ + milepostLabelPrimitiveOverride, + endMilepostLabelPrimitiveOverride, + ], type: "CIMSymbolReference", symbol: endpointCimPointSymbol, }, diff --git a/src/layers/MilepostLayer/symbol/primitiveOverrides.ts b/src/layers/MilepostLayer/symbol/primitiveOverrides.ts index d3235c18..4733baf8 100644 --- a/src/layers/MilepostLayer/symbol/primitiveOverrides.ts +++ b/src/layers/MilepostLayer/symbol/primitiveOverrides.ts @@ -1,28 +1,39 @@ +/** + * The expression info for the primitive override for the milepost label symbol. + * This will be used on the milepost line layer. + */ const beginMilepostExpressionInfo = { expression: "`${$feature.Route}\\n${$feature.SRMP}${$feature.Back}`", type: "CIMExpressionInfo", returnType: "String", } as const; + +/** + * The expression info for the primitive override for the end milepost label symbol. + * This will be used on the route segment line layer. + */ const endMilepostExpressionInfo = { ...beginMilepostExpressionInfo, expression: "`${$feature.Route}\\n${$feature.EndSrmp}${$feature.EndBack}`", } as const; -const milepostLabelPrimitiveOverride: __esri.PrimitiveOverride = { + +/** + * The primitive override for the milepost label symbol. + * This will be used on the milepost line layer. + */ +export const milepostLabelPrimitiveOverride = { primitiveName: "milepostLabel", propertyName: "textString", type: "CIMPrimitiveOverride", valueExpressionInfo: beginMilepostExpressionInfo, } as const; -const endMilepostLabelPrimitiveOverride: __esri.PrimitiveOverride = { + +/** + * The primitive override for the end milepost label symbol. + * This will be used on the route segment line layer. + */ +export const endMilepostLabelPrimitiveOverride = { ...milepostLabelPrimitiveOverride, primitiveName: "endMilepostLabel", valueExpressionInfo: endMilepostExpressionInfo, -}; - -export const primitiveOverrides: __esri.PrimitiveOverride[] = [ - milepostLabelPrimitiveOverride, -]; -export const routeSegmentPrimitiveOverrides = [ - milepostLabelPrimitiveOverride, - endMilepostLabelPrimitiveOverride, -]; +} as const; From d39560f2adf0c1175be91618630ee700533881ad Mon Sep 17 00:00:00 2001 From: Jeff Jacobson Date: Thu, 5 Dec 2024 13:48:36 -0800 Subject: [PATCH 10/24] build: :arrow_up: upgrade vite --- package.json | 2 +- pnpm-lock.yaml | 108 ++++++++++++++++++++++++------------------------- 2 files changed, 55 insertions(+), 55 deletions(-) diff --git a/package.json b/package.json index bdac9f8a..5a31cc8e 100644 --- a/package.json +++ b/package.json @@ -50,7 +50,7 @@ "svgson": "^5.3.1", "tsx": "^4.19.2", "typescript": "^5.7.2", - "vite": "^6.0.2", + "vite": "^6.0.3", "vitest": "^2.1.8" }, "repository": { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 66d4afeb..842499dc 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -94,8 +94,8 @@ importers: specifier: ^5.7.2 version: 5.7.2 vite: - specifier: ^6.0.2 - version: 6.0.2(@types/node@22.10.1)(tsx@4.19.2)(yaml@2.6.1) + specifier: ^6.0.3 + version: 6.0.3(@types/node@22.10.1)(tsx@4.19.2)(yaml@2.6.1) vitest: specifier: ^2.1.8 version: 2.1.8(@types/node@22.10.1)(jsdom@25.0.1)(msw@2.6.6(@types/node@22.10.1)(typescript@5.7.2)) @@ -137,16 +137,16 @@ packages: resolution: {integrity: sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==} engines: {node: '>=6.9.0'} - '@babel/compat-data@7.26.2': - resolution: {integrity: sha512-Z0WgzSEa+aUcdiJuCIqgujCshpMWgUpgOxXotrYPSA53hA3qopNaqcJpyr0hVb1FeWdnqFA35/fUtXgBK8srQg==} + '@babel/compat-data@7.26.3': + resolution: {integrity: sha512-nHIxvKPniQXpmQLb0vhY3VaFb3S0YrTAwpOWJZh1wn3oJPjJk9Asva204PsBdmAE8vpzfHudT8DB0scYvy9q0g==} engines: {node: '>=6.9.0'} '@babel/core@7.26.0': resolution: {integrity: sha512-i1SLeK+DzNnQ3LL/CswPCa/E5u4lh1k6IAEphON8F+cXt0t9euTshDru0q7/IqMa1PMPz5RnHuHscF8/ZJsStg==} engines: {node: '>=6.9.0'} - '@babel/generator@7.26.2': - resolution: {integrity: sha512-zevQbhbau95nkoxSq3f/DC/SC+EEOUZd3DYqfSkMhY2/wfSeaHV1Ew4vk8e+x8lja31IbyuUa2uQ3JONqKbysw==} + '@babel/generator@7.26.3': + resolution: {integrity: sha512-6FF/urZvD0sTeO7k6/B15pMLC4CHUv1426lzr3N01aHJTl046uCAh9LXW/fzeXXjPNCJ6iABW5XaWOsIZB93aQ==} engines: {node: '>=6.9.0'} '@babel/helper-compilation-targets@7.25.9': @@ -179,8 +179,8 @@ packages: resolution: {integrity: sha512-tbhNuIxNcVb21pInl3ZSjksLCvgdZy9KwJ8brv993QtIVKJBBkYXz4q4ZbAv31GdnC+R90np23L5FbEBlthAEw==} engines: {node: '>=6.9.0'} - '@babel/parser@7.26.2': - resolution: {integrity: sha512-DWMCZH9WA4Maitz2q21SRKHo9QXZxkDsbNZoVD62gusNtNBBqDg9i7uOhASfTfIGNzW+O+r7+jAlM8dwphcJKQ==} + '@babel/parser@7.26.3': + resolution: {integrity: sha512-WJ/CvmY8Mea8iDXo6a7RK2wbmJITT5fN3BEkRuFlxVyNx8jOKIIhmC4fSkTcPcf8JyavbBwIe6OpiCOBXt/IcA==} engines: {node: '>=6.0.0'} hasBin: true @@ -188,12 +188,12 @@ packages: resolution: {integrity: sha512-9DGttpmPvIxBb/2uwpVo3dqJ+O6RooAFOS+lB+xDqoE2PVCE8nfoHMdZLpfCQRLwvohzXISPZcgxt80xLfsuwg==} engines: {node: '>=6.9.0'} - '@babel/traverse@7.25.9': - resolution: {integrity: sha512-ZCuvfwOwlz/bawvAuvcj8rrithP2/N55Tzz342AkTvq4qaWbGfmCk/tKhNaV2cthijKrPAA8SRJV5WWe7IBMJw==} + '@babel/traverse@7.26.4': + resolution: {integrity: sha512-fH+b7Y4p3yqvApJALCPJcwb0/XaOSgtK4pzV6WVjPR5GLFQBRI7pfoX2V2iM48NXvX07NUxxm1Vw98YjqTcU5w==} engines: {node: '>=6.9.0'} - '@babel/types@7.26.0': - resolution: {integrity: sha512-Z/yiTPj+lDVnF7lWeKCIJzaIkI0vYO87dMpZ4bg4TDrFe4XXLFWL1TbXU27gBP3QccxV9mZICCrnjnYlJjXHOA==} + '@babel/types@7.26.3': + resolution: {integrity: sha512-vN5p+1kl59GVKMvTHt55NzzmYVxprfJD+ql7U9NFIfKCBkYE55LYtS+WtPlaYOyzydrKI8Nezd+aZextrd+FMA==} engines: {node: '>=6.9.0'} '@bcoe/v8-coverage@0.2.3': @@ -1250,8 +1250,8 @@ packages: resolution: {tarball: https://codeload.github.com/WSDOT-GIS/wsdot-web-styles/tar.gz/3398615915f71ee72e1dfef9d6d2c1035df16b17} version: 1.0.1 - '@zip.js/zip.js@2.7.53': - resolution: {integrity: sha512-G6Bl5wN9EXXVaTUIox71vIX5Z454zEBe+akKpV4m1tUboIctT5h7ID3QXCJd/Lfy2rSvmkTmZIucf1jGRR4f5A==} + '@zip.js/zip.js@2.7.54': + resolution: {integrity: sha512-qMrJVg2hoEsZJjMJez9yI2+nZlBUxgYzGV3mqcb2B/6T1ihXp0fWBDYlVHlHquuorgNUQP5a8qSmX6HF5rFJNg==} engines: {bun: '>=0.7.0', deno: '>=1.0.0', node: '>=16.5.0'} agent-base@7.1.1: @@ -1540,8 +1540,8 @@ packages: eastasianwidth@0.2.0: resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} - electron-to-chromium@1.5.68: - resolution: {integrity: sha512-FgMdJlma0OzUYlbrtZ4AeXjKxKPk6KT8WOP8BjcqxWtlg8qyJQjRzPJzUtUn5GBg1oQ26hFs7HOOHJMYiJRnvQ==} + electron-to-chromium@1.5.71: + resolution: {integrity: sha512-dB68l59BI75W1BUGVTAEJy45CEVuEGy9qPVVQ8pnHyHMn36PLPPoE1mjLH+lo9rKulO3HC2OhbACI/8tCqJBcA==} emoji-regex@8.0.0: resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} @@ -2242,8 +2242,8 @@ packages: terser: optional: true - vite@6.0.2: - resolution: {integrity: sha512-XdQ+VsY2tJpBsKGs0wf3U/+azx8BBpYRHFAyKm5VeEZNOJZRB63q7Sc8Iup3k0TrN3KO6QgyzFf+opSbfY1y0g==} + vite@6.0.3: + resolution: {integrity: sha512-Cmuo5P0ENTN6HxLSo6IHsjCLn/81Vgrp81oaiFFMRa8gGDj5xEjIcEpf2ZymZtZR8oU0P2JX5WuUp/rlXcHkAw==} engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} hasBin: true peerDependencies: @@ -2329,8 +2329,8 @@ packages: resolution: {integrity: sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==} engines: {node: '>=18'} - whatwg-url@14.0.0: - resolution: {integrity: sha512-1lfMEm2IEr7RIV+f4lUNPOqfFL+pO+Xw3fJSqmjX9AbXcXcYOkCe1P6+9VBZB6n94af16NfZf+sSk0JCBZC9aw==} + whatwg-url@14.1.0: + resolution: {integrity: sha512-jlf/foYIKywAt3x/XWKZ/3rz8OSJPiWktjmk891alJUEjiVxKX9LEO92qH3hv4aJ0mN3MWPvGMCy8jQi95xK4w==} engines: {node: '>=18'} which@2.0.2: @@ -2469,7 +2469,7 @@ snapshots: '@esri/calcite-colors': 6.1.0 '@esri/calcite-components': 2.13.2(@floating-ui/utils@0.2.8) '@vaadin/grid': 24.5.4 - '@zip.js/zip.js': 2.7.53 + '@zip.js/zip.js': 2.7.54 luxon: 3.5.0 marked: 14.1.4 sortablejs: 1.15.6 @@ -2482,20 +2482,20 @@ snapshots: js-tokens: 4.0.0 picocolors: 1.1.1 - '@babel/compat-data@7.26.2': {} + '@babel/compat-data@7.26.3': {} '@babel/core@7.26.0': dependencies: '@ampproject/remapping': 2.3.0 '@babel/code-frame': 7.26.2 - '@babel/generator': 7.26.2 + '@babel/generator': 7.26.3 '@babel/helper-compilation-targets': 7.25.9 '@babel/helper-module-transforms': 7.26.0(@babel/core@7.26.0) '@babel/helpers': 7.26.0 - '@babel/parser': 7.26.2 + '@babel/parser': 7.26.3 '@babel/template': 7.25.9 - '@babel/traverse': 7.25.9 - '@babel/types': 7.26.0 + '@babel/traverse': 7.26.4 + '@babel/types': 7.26.3 convert-source-map: 2.0.0 debug: 4.3.7 gensync: 1.0.0-beta.2 @@ -2504,17 +2504,17 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/generator@7.26.2': + '@babel/generator@7.26.3': dependencies: - '@babel/parser': 7.26.2 - '@babel/types': 7.26.0 + '@babel/parser': 7.26.3 + '@babel/types': 7.26.3 '@jridgewell/gen-mapping': 0.3.5 '@jridgewell/trace-mapping': 0.3.25 jsesc: 3.0.2 '@babel/helper-compilation-targets@7.25.9': dependencies: - '@babel/compat-data': 7.26.2 + '@babel/compat-data': 7.26.3 '@babel/helper-validator-option': 7.25.9 browserslist: 4.24.2 lru-cache: 5.1.1 @@ -2522,8 +2522,8 @@ snapshots: '@babel/helper-module-imports@7.25.9': dependencies: - '@babel/traverse': 7.25.9 - '@babel/types': 7.26.0 + '@babel/traverse': 7.26.4 + '@babel/types': 7.26.3 transitivePeerDependencies: - supports-color @@ -2532,7 +2532,7 @@ snapshots: '@babel/core': 7.26.0 '@babel/helper-module-imports': 7.25.9 '@babel/helper-validator-identifier': 7.25.9 - '@babel/traverse': 7.25.9 + '@babel/traverse': 7.26.4 transitivePeerDependencies: - supports-color @@ -2545,31 +2545,31 @@ snapshots: '@babel/helpers@7.26.0': dependencies: '@babel/template': 7.25.9 - '@babel/types': 7.26.0 + '@babel/types': 7.26.3 - '@babel/parser@7.26.2': + '@babel/parser@7.26.3': dependencies: - '@babel/types': 7.26.0 + '@babel/types': 7.26.3 '@babel/template@7.25.9': dependencies: '@babel/code-frame': 7.26.2 - '@babel/parser': 7.26.2 - '@babel/types': 7.26.0 + '@babel/parser': 7.26.3 + '@babel/types': 7.26.3 - '@babel/traverse@7.25.9': + '@babel/traverse@7.26.4': dependencies: '@babel/code-frame': 7.26.2 - '@babel/generator': 7.26.2 - '@babel/parser': 7.26.2 + '@babel/generator': 7.26.3 + '@babel/parser': 7.26.3 '@babel/template': 7.25.9 - '@babel/types': 7.26.0 + '@babel/types': 7.26.3 debug: 4.3.7 globals: 11.12.0 transitivePeerDependencies: - supports-color - '@babel/types@7.26.0': + '@babel/types@7.26.3': dependencies: '@babel/helper-string-parser': 7.25.9 '@babel/helper-validator-identifier': 7.25.9 @@ -3464,7 +3464,7 @@ snapshots: '@fontsource/inconsolata': 5.1.0 '@fontsource/lato': 5.1.0 - '@zip.js/zip.js@2.7.53': {} + '@zip.js/zip.js@2.7.54': {} agent-base@7.1.1: dependencies: @@ -3527,7 +3527,7 @@ snapshots: browserslist@4.24.2: dependencies: caniuse-lite: 1.0.30001686 - electron-to-chromium: 1.5.68 + electron-to-chromium: 1.5.71 node-releases: 2.0.18 update-browserslist-db: 1.1.1(browserslist@4.24.2) @@ -3743,7 +3743,7 @@ snapshots: data-urls@5.0.0: dependencies: whatwg-mimetype: 4.0.0 - whatwg-url: 14.0.0 + whatwg-url: 14.1.0 dayjs@1.11.13: {} @@ -3788,7 +3788,7 @@ snapshots: eastasianwidth@0.2.0: {} - electron-to-chromium@1.5.68: {} + electron-to-chromium@1.5.71: {} emoji-regex@8.0.0: {} @@ -4028,7 +4028,7 @@ snapshots: istanbul-lib-instrument@6.0.3: dependencies: '@babel/core': 7.26.0 - '@babel/parser': 7.26.2 + '@babel/parser': 7.26.3 '@istanbuljs/schema': 0.1.3 istanbul-lib-coverage: 3.2.2 semver: 7.6.3 @@ -4082,7 +4082,7 @@ snapshots: webidl-conversions: 7.0.0 whatwg-encoding: 3.1.1 whatwg-mimetype: 4.0.0 - whatwg-url: 14.0.0 + whatwg-url: 14.1.0 ws: 8.18.0 xml-name-validator: 5.0.0 transitivePeerDependencies: @@ -4111,7 +4111,7 @@ snapshots: webidl-conversions: 7.0.0 whatwg-encoding: 3.1.1 whatwg-mimetype: 4.0.0 - whatwg-url: 14.0.0 + whatwg-url: 14.1.0 ws: 8.18.0 xml-name-validator: 5.0.0 transitivePeerDependencies: @@ -4172,8 +4172,8 @@ snapshots: magicast@0.3.5: dependencies: - '@babel/parser': 7.26.2 - '@babel/types': 7.26.0 + '@babel/parser': 7.26.3 + '@babel/types': 7.26.3 source-map-js: 1.2.1 make-dir@4.0.0: @@ -4534,7 +4534,7 @@ snapshots: '@types/node': 22.10.1 fsevents: 2.3.3 - vite@6.0.2(@types/node@22.10.1)(tsx@4.19.2)(yaml@2.6.1): + vite@6.0.3(@types/node@22.10.1)(tsx@4.19.2)(yaml@2.6.1): dependencies: esbuild: 0.24.0 postcss: 8.4.49 @@ -4597,7 +4597,7 @@ snapshots: whatwg-mimetype@4.0.0: {} - whatwg-url@14.0.0: + whatwg-url@14.1.0: dependencies: tr46: 5.0.0 webidl-conversions: 7.0.0 From 9be99bc8dba3fd226a2a4441a01231ec2601249e Mon Sep 17 00:00:00 2001 From: Jeff Jacobson Date: Mon, 9 Dec 2024 14:23:42 -0800 Subject: [PATCH 11/24] refactor: :recycle: simplify line symbol creation --- src/layers/MilepostLayer/create-cim.ts | 10 +- .../MilepostOffsetLineRenderer.ts | 132 +++++------------- src/layers/MilepostLayer/symbol/index.ts | 6 +- 3 files changed, 45 insertions(+), 103 deletions(-) diff --git a/src/layers/MilepostLayer/create-cim.ts b/src/layers/MilepostLayer/create-cim.ts index 6a0225b2..b35c250c 100644 --- a/src/layers/MilepostLayer/create-cim.ts +++ b/src/layers/MilepostLayer/create-cim.ts @@ -18,7 +18,9 @@ const defaultPrimitiveName = "milepostLabel"; * @param l - The CIMSymbolLayer to check. * @returns A boolean indicating whether the provided layer is a CIMVectorMarker. */ -function isVectorMarker(l: __esri.CIMSymbolLayer): l is __esri.CIMVectorMarker { +export function isCimVectorMarker( + l: __esri.CIMSymbolLayer, +): l is __esri.CIMVectorMarker { return l.type === "CIMVectorMarker"; } @@ -34,7 +36,7 @@ type CIMMarkerGraphicWithTextSymbol = __esri.CIMMarkerGraphic & { * @param g - The {@link __esri.CIMMarkerGraphic|CIMMarkerGraphic} to check. * @returns A boolean indicating whether the provided graphic is a {@link __esri.CIMTextSymbol|CIMTextSymbol}. */ -function isMarkerGraphicWithTextSymbol( +function isCimMarkerGraphicWithTextSymbol( g: __esri.CIMMarkerGraphic, ): g is CIMMarkerGraphicWithTextSymbol { return g.symbol.type === "CIMTextSymbol"; @@ -63,10 +65,10 @@ function setPrimitiveNameOfFirstTextSymbol( let textSymbol: CIMMarkerGraphicWithTextSymbol | null = null; // Find the text symbol and set its primitive name. - for (const layer of symbolLayers.filter(isVectorMarker)) { + for (const layer of symbolLayers.filter(isCimVectorMarker)) { const markerGraphics = layer.markerGraphics; for (const markerGraphic of markerGraphics.filter( - isMarkerGraphicWithTextSymbol, + isCimMarkerGraphicWithTextSymbol, )) { markerGraphic.primitiveName = primitiveName; textSymbol = markerGraphic; diff --git a/src/layers/MilepostLayer/milepost-line-layer/MilepostOffsetLineRenderer.ts b/src/layers/MilepostLayer/milepost-line-layer/MilepostOffsetLineRenderer.ts index e4158b92..ee35ed35 100644 --- a/src/layers/MilepostLayer/milepost-line-layer/MilepostOffsetLineRenderer.ts +++ b/src/layers/MilepostLayer/milepost-line-layer/MilepostOffsetLineRenderer.ts @@ -1,99 +1,40 @@ import SimpleRenderer from "@arcgis/core/renderers/SimpleRenderer"; import CIMSymbol from "@arcgis/core/symbols/CIMSymbol"; +import SimpleMarkerSymbol from "@arcgis/core/symbols/SimpleMarkerSymbol"; +import { convertToCIMSymbol } from "@arcgis/core/symbols/support/cimConversionUtils"; +import { isCimVectorMarker } from "../create-cim"; import { cimVectorMarker } from "../symbol"; -import { primitiveOverrides } from "../symbol/primitiveOverrides"; +import { + endMilepostLabelPrimitiveOverride, + milepostLabelPrimitiveOverride, +} from "../symbol/primitiveOverrides"; -const clickPointSymbolLayer: __esri.CIMVectorMarker = { - type: "CIMVectorMarker", - enable: true, - colorLocked: true, - anchorPointUnits: "Relative", - size: 10, - markerPlacement: { - type: "CIMMarkerPlacementAtExtremities", - angleToLine: true, - extremityPlacement: "JustBegin", - }, - frame: { - xmin: -5, - ymin: -5, - xmax: 5, - ymax: 5, - }, - markerGraphics: [ - { - type: "CIMMarkerGraphic", - geometry: { - rings: [ - [ - [0, 5], - [0.87, 4.92], - [1.71, 4.7], - [2.5, 4.33], - [3.21, 3.83], - [3.83, 3.21], - [4.33, 2.5], - [4.7, 1.71], - [4.92, 0.87], - [5, 0], - [4.92, -0.87], - [4.7, -1.71], - [4.33, -2.5], - [3.83, -3.21], - [3.21, -3.83], - [2.5, -4.33], - [1.71, -4.7], - [0.87, -4.92], - [0, -5], - [-0.87, -4.92], - [-1.71, -4.7], - [-2.5, -4.33], - [-3.21, -3.83], - [-3.83, -3.21], - [-4.33, -2.5], - [-4.7, -1.71], - [-4.92, -0.87], - [-5, 0], - [-4.92, 0.87], - [-4.7, 1.71], - [-4.33, 2.5], - [-3.83, 3.21], - [-3.21, 3.83], - [-2.5, 4.33], - [-1.71, 4.7], - [-0.87, 4.92], - [0, 5], - ], - ], - }, - symbol: { - type: "CIMPolygonSymbol", - symbolLayers: [ - { - type: "CIMSolidStroke", - enable: true, - capStyle: "Round", - joinStyle: "Round", - // lineStyle3D: "Strip", - miterLimit: 10, - width: 0, - // // height3D: 1, - // // anchor3D: "Center", - color: [110, 110, 110, 255], - }, - { - type: "CIMSolidFill", - enable: true, - color: [255, 100, 100, 255], - }, - ], - // angleAlignment: "Map", - }, +function createClickPointSymbolLayer() { + const clickPointSymbol = new SimpleMarkerSymbol({ + style: "circle", + color: [255, 100, 100, 255], + outline: { + color: "white", + width: 1, }, - ], - scaleSymbolsProportionally: true, - respectFrame: true, -}; + }); + + console.debug("clickPointSymbol", clickPointSymbol.toJSON()); + + const clickPointCimSymbol = convertToCIMSymbol(clickPointSymbol); + console.debug("cimClickPointSymbol", clickPointCimSymbol.toJSON()); + + const clickPointSymbolLayer = + clickPointCimSymbol.data.symbol?.symbolLayers?.filter(isCimVectorMarker)[0]; + + if (!clickPointSymbolLayer) { + throw new Error("clickPointSymbolLayer not found"); + } + return clickPointSymbolLayer; +} + +const clickPointSymbolLayer = createClickPointSymbolLayer(); + const strokeSymbolLayer: __esri.CIMSolidStroke = { type: "CIMSolidStroke", effects: [ @@ -102,18 +43,14 @@ const strokeSymbolLayer: __esri.CIMSolidStroke = { dashTemplate: [5, 3], lineDashEnding: "NoConstraint", offsetAlongLine: 0, - // controlPointEnding: "NoConstraint", }, ], enable: true, colorLocked: true, capStyle: "Butt", joinStyle: "Round", - // lineStyle3D: "Strip", miterLimit: 4, width: 2, - // height3D: 1, - // anchor3D: "Center", color: [255, 100, 100, 255], }; const cimLineSymbol: __esri.CIMLineSymbol = { @@ -133,7 +70,10 @@ const cimLineSymbol: __esri.CIMLineSymbol = { }; const cimSymbol = new CIMSymbol({ data: { - primitiveOverrides, + primitiveOverrides: [ + milepostLabelPrimitiveOverride, + endMilepostLabelPrimitiveOverride, + ], type: "CIMSymbolReference", symbol: cimLineSymbol, }, diff --git a/src/layers/MilepostLayer/symbol/index.ts b/src/layers/MilepostLayer/symbol/index.ts index 94d456e0..e4ff41eb 100644 --- a/src/layers/MilepostLayer/symbol/index.ts +++ b/src/layers/MilepostLayer/symbol/index.ts @@ -16,7 +16,7 @@ const cimCallout: __esri.CIMBackgroundCallout = { }, { type: "CIMSolidStroke", - color: [0, 0, 0, 0], + color: [255, 255, 255, 255], width: 1, enable: true, }, @@ -55,13 +55,13 @@ const cimMarkerGraphic: __esri.CIMMarkerGraphic = { geometry: { x: 0, y: 0 }, primitiveName: "milepostLabel", symbol: cimTextSymbol, - textString: "ROUTE\nMILE.POSTB", + textString: " ", }; const endpointCimMarkerGraphic: __esri.CIMMarkerGraphic = { ...cimMarkerGraphic, primitiveName: "endMilepostLabel", - textString: "ROUTE\nEND.MILEPOSTB", + textString: " ", }; export const cimVectorMarker: __esri.CIMVectorMarker = { From 6e690be38af4741c2ee77278ec784148d2e3e00a Mon Sep 17 00:00:00 2001 From: Jeff Jacobson Date: Mon, 9 Dec 2024 15:25:32 -0800 Subject: [PATCH 12/24] refactor: :recycle: Added end MP fields to line layer --- src/layers/MilepostLayer/fields.ts | 2 +- src/layers/MilepostLayer/milepost-line-layer/index.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/layers/MilepostLayer/fields.ts b/src/layers/MilepostLayer/fields.ts index 8a634f2e..d5094cad 100644 --- a/src/layers/MilepostLayer/fields.ts +++ b/src/layers/MilepostLayer/fields.ts @@ -62,7 +62,7 @@ export const fields: FieldProperties[] = [ /** * Field definitions for the route segments layer */ -export const segmentFields = [ +export const segmentFields: typeof fields = [ ...fields, { name: fieldNames.EndSrmp, diff --git a/src/layers/MilepostLayer/milepost-line-layer/index.ts b/src/layers/MilepostLayer/milepost-line-layer/index.ts index fccb770f..6698ac44 100644 --- a/src/layers/MilepostLayer/milepost-line-layer/index.ts +++ b/src/layers/MilepostLayer/milepost-line-layer/index.ts @@ -2,7 +2,7 @@ import FeatureLayer from "@arcgis/core/layers/FeatureLayer"; import { createPopupTemplate } from ".."; import waExtent from "../../../WAExtent"; import { objectIdFieldName } from "../../../elc/types"; -import { fields } from "../fields"; +import { segmentFields as fields } from "../fields"; import MilepostOffsetLineRenderer from "./MilepostOffsetLineRenderer"; /** From f1a7766e81212565dac0fb4b0a61a0a81c45b42a Mon Sep 17 00:00:00 2001 From: Jeff Jacobson Date: Mon, 9 Dec 2024 17:35:02 -0800 Subject: [PATCH 13/24] refactor: :recycle: add ability to read end MP --- src/elc/url.ts | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/src/elc/url.ts b/src/elc/url.ts index 051d854b..0d8b3cd7 100644 --- a/src/elc/url.ts +++ b/src/elc/url.ts @@ -29,10 +29,11 @@ import type { FindNearestRouteLocationParameters, FindRouteLocationParameters, RouteGeometry, + RouteGeometryPolyline, ValidRouteLocationForMPInput, } from "./types"; -type UrlParamMapKey = "sr" | "rrt" | "rrq" | "dir" | "mp"; +type UrlParamMapKey = "sr" | "rrt" | "rrq" | "dir" | "mp" | "endMP"; /** * Regular expression patterns to validate URL parameters. @@ -43,6 +44,7 @@ const keyRegExps = new Map([ ["rrq", /^R{1,2}Q/i], ["dir", /^D(?:IR)?/i], ["mp", /^(?:SR)?MP/i], + ["endMP", /^E(ND)MP/i], ] as const); /** @@ -65,6 +67,7 @@ const valueRegExps = new Map([ * // matches "123", "123.45", "123B", "123.45B" */ ["mp", /^(?\d+(?:\.\d+)?)(?B)?$/i], + ["endMP", /^(?\d+(?:\.\d+)?)(?B)?$/i], ] as const); type KeyValueRegExpTuple = [keyRegexp: RegExp, valueRegexp: RegExp]; @@ -281,6 +284,19 @@ export function getElcParamsFromUrl( const route = `${sr}${rrt}${rrq}`; + const emp = getUrlSearchParameter(searchParams, "endMP"); + + if (!emp) { + return { + Route: route, + Srmp: srmp, + Back: back, + Decrease: /dD/i.test(direction), + ReferenceDate: today, + ResponseDate: today, + }; + } + const { srmp: endSrmp, back: endBack } = parseSrmp(emp); return { Route: route, Srmp: srmp, @@ -288,7 +304,9 @@ export function getElcParamsFromUrl( Decrease: /dD/i.test(direction), ReferenceDate: today, ResponseDate: today, - }; + EndSrmp: endSrmp, + EndBack: endBack, + } as ValidRouteLocationForMPInput; } /** From 27503dc88c75ba78de6f94c6485bf70029b3d5c4 Mon Sep 17 00:00:00 2001 From: Jeff Jacobson Date: Tue, 10 Dec 2024 15:18:28 -0800 Subject: [PATCH 14/24] refactor: :rotating_light: Removed unneeded eslint comment --- src/elc/url.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/elc/url.ts b/src/elc/url.ts index 0d8b3cd7..6f55437e 100644 --- a/src/elc/url.ts +++ b/src/elc/url.ts @@ -163,7 +163,6 @@ export function* enumerateUrlParameters( } else if (Array.isArray(value)) { outValue = JSON.stringify(value); } else { - // eslint-disable-next-line @typescript-eslint/restrict-template-expressions outValue = `${value}`; } yield [key, outValue]; From b2e5b1f4ed27224e8e00179c30ecdde1b3b37907 Mon Sep 17 00:00:00 2001 From: Jeff Jacobson Date: Tue, 10 Dec 2024 15:44:54 -0800 Subject: [PATCH 15/24] refactor: :recycle: Modifed types --- src/elc/types.ts | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/src/elc/types.ts b/src/elc/types.ts index 98be4a10..7f4b727c 100644 --- a/src/elc/types.ts +++ b/src/elc/types.ts @@ -122,6 +122,9 @@ export interface RouteLocation { RouteGeometry?: G; Srmp?: number; LocatingError?: string | null; + EndArm?: number; + EndSrmp?: number; + EndBack?: boolean; } export type ArmRouteLocation< @@ -134,6 +137,12 @@ export type SrmpRouteLocation< G extends RouteGeometry, > = RouteLocation & Required, "Srmp" & "Back">>; +export type SrmpRouteLineLocation< + D extends DateType, + G extends RouteGeometry, +> = RouteLocation & + Required, "EndSrmp" & "EndBack">>; + export type ValidRouteLocationForMPInput< D extends DateType, G extends RouteGeometry, @@ -176,13 +185,7 @@ export interface ElcAttributes Srmp: number; } -export interface LayerFeatureAttributes - extends ElcAttributes, - AttributesObject { - "Township Subdivision": string | null; - County: string | null; - City: string | null; -} +export type LayerFeatureAttributes = ElcAttributes & AttributesObject; /** * A milepost point {@link Graphic}. From f93795e2d10f08268696c39e73bc59742d11f7c4 Mon Sep 17 00:00:00 2001 From: Jeff Jacobson Date: Tue, 10 Dec 2024 15:46:29 -0800 Subject: [PATCH 16/24] build: :wrench: Update pnpm --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 5a31cc8e..f0c7c972 100644 --- a/package.json +++ b/package.json @@ -68,5 +68,5 @@ ], "author": "Jeff Jacobson", "license": "Unlicense", - "packageManager": "pnpm@9.14.4+sha512.c8180b3fbe4e4bca02c94234717896b5529740a6cbadf19fa78254270403ea2f27d4e1d46a08a0f56c89b63dc8ebfd3ee53326da720273794e6200fcf0d184ab" + "packageManager": "pnpm@9.15.0+sha512.76e2379760a4328ec4415815bcd6628dee727af3779aaa4c914e3944156c4299921a89f976381ee107d41f12cfa4b66681ca9c718f0668fa0831ed4c6d8ba56c" } From 388517e3bbc2a776dac0d462e9929517376ef3f6 Mon Sep 17 00:00:00 2001 From: Jeff Jacobson Date: Tue, 10 Dec 2024 15:49:54 -0800 Subject: [PATCH 17/24] build: :arrow_up: upgrade dependencies --- package.json | 4 +- pnpm-lock.yaml | 493 +++++++++++++++++++++++++------------------------ 2 files changed, 251 insertions(+), 246 deletions(-) diff --git a/package.json b/package.json index f0c7c972..0d6e95f7 100644 --- a/package.json +++ b/package.json @@ -26,7 +26,7 @@ "@fontsource/inconsolata": "^5.1.0", "@fontsource/lato": "^5.1.0", "@fontsource/overpass": "^5.1.1", - "@types/geojson": "^7946.0.14", + "@types/geojson": "^7946.0.15", "@wsdot/land-use-codes": "github:WSDOT-GIS/land-use", "@wsdot/web-styles": "github:WSDOT-GIS/wsdot-web-styles", "analytics": "^0.8.14", @@ -44,7 +44,7 @@ "browserslist-to-esbuild": "^2.1.1", "cspell": "^8.16.1", "jsdom": "^25.0.1", - "msw": "^2.6.6", + "msw": "^2.6.8", "optionator": "^0.9.4", "svgo": "^3.3.2", "svgson": "^5.3.1", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 842499dc..3d541fdf 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -27,8 +27,8 @@ importers: specifier: ^5.1.1 version: 5.1.1 '@types/geojson': - specifier: ^7946.0.14 - version: 7946.0.14 + specifier: ^7946.0.15 + version: 7946.0.15 '@wsdot/land-use-codes': specifier: github:WSDOT-GIS/land-use version: https://codeload.github.com/WSDOT-GIS/land-use/tar.gz/0ed447fa99cd05a5480cec5e2e94b1b06cbd02b5(typescript@5.7.2) @@ -62,10 +62,10 @@ importers: version: 22.10.1 '@vitest/coverage-istanbul': specifier: ^2.1.8 - version: 2.1.8(vitest@2.1.8(@types/node@22.10.1)(jsdom@25.0.1)(msw@2.6.6(@types/node@22.10.1)(typescript@5.7.2))) + version: 2.1.8(vitest@2.1.8(@types/node@22.10.1)(jsdom@25.0.1)(msw@2.6.8(@types/node@22.10.1)(typescript@5.7.2))) '@vitest/coverage-v8': specifier: ^2.1.8 - version: 2.1.8(vitest@2.1.8(@types/node@22.10.1)(jsdom@25.0.1)(msw@2.6.6(@types/node@22.10.1)(typescript@5.7.2))) + version: 2.1.8(vitest@2.1.8(@types/node@22.10.1)(jsdom@25.0.1)(msw@2.6.8(@types/node@22.10.1)(typescript@5.7.2))) browserslist-to-esbuild: specifier: ^2.1.1 version: 2.1.1(browserslist@4.24.2) @@ -76,8 +76,8 @@ importers: specifier: ^25.0.1 version: 25.0.1 msw: - specifier: ^2.6.6 - version: 2.6.6(@types/node@22.10.1)(typescript@5.7.2) + specifier: ^2.6.8 + version: 2.6.8(@types/node@22.10.1)(typescript@5.7.2) optionator: specifier: ^0.9.4 version: 0.9.4 @@ -98,7 +98,7 @@ importers: version: 6.0.3(@types/node@22.10.1)(tsx@4.19.2)(yaml@2.6.1) vitest: specifier: ^2.1.8 - version: 2.1.8(@types/node@22.10.1)(jsdom@25.0.1)(msw@2.6.6(@types/node@22.10.1)(typescript@5.7.2)) + version: 2.1.8(@types/node@22.10.1)(jsdom@25.0.1)(msw@2.6.8(@types/node@22.10.1)(typescript@5.7.2)) packages: @@ -410,8 +410,8 @@ packages: '@cspell/dict-node@5.0.5': resolution: {integrity: sha512-7NbCS2E8ZZRZwlLrh2sA0vAk9n1kcTUiRp/Nia8YvKaItGXLfxYqD2rMQ3HpB1kEutal6hQLVic3N2Yi1X7AaA==} - '@cspell/dict-npm@5.1.14': - resolution: {integrity: sha512-7VV/rrRlxOwy5j0bpw6/Uci+nx/rwSgx45FJdeKq++nHsBx/nEXMFNODknm4Mi6i7t7uOVHExpifrR6w6xTWww==} + '@cspell/dict-npm@5.1.15': + resolution: {integrity: sha512-95D3A8rs9SYlUQUkK48J0F1W3jOsc63dY/vlzuNHE4nuGU2OM4jtoWvLk0ovhBMHwZikaNNTHaHoJyr+VKu+Yg==} '@cspell/dict-php@4.0.13': resolution: {integrity: sha512-P6sREMZkhElzz/HhXAjahnICYIqB/HSGp1EhZh+Y6IhvC15AzgtDP8B8VYCIsQof6rPF1SQrFwunxOv8H1e2eg==} @@ -422,8 +422,8 @@ packages: '@cspell/dict-public-licenses@2.0.11': resolution: {integrity: sha512-rR5KjRUSnVKdfs5G+gJ4oIvQvm8+NJ6cHWY2N+GE69/FSGWDOPHxulCzeGnQU/c6WWZMSimG9o49i9r//lUQyA==} - '@cspell/dict-python@4.2.12': - resolution: {integrity: sha512-U25eOFu+RE0aEcF2AsxZmq3Lic7y9zspJ9SzjrC0mfJz+yr3YmSCw4E0blMD3mZoNcf7H/vMshuKIY5AY36U+Q==} + '@cspell/dict-python@4.2.13': + resolution: {integrity: sha512-mZIcmo9qif8LkJ6N/lqTZawcOk2kVTcuWIUOSbMcjyomO0XZ7iWz15TfONyr03Ea/l7o5ULV+MZ4vx76bAUb7w==} '@cspell/dict-r@2.0.4': resolution: {integrity: sha512-cBpRsE/U0d9BRhiNRMLMH1PpWgw+N+1A2jumgt1if9nBGmQw4MUpg2u9I0xlFVhstTIdzXiLXMxP45cABuiUeQ==} @@ -437,8 +437,8 @@ packages: '@cspell/dict-scala@5.0.6': resolution: {integrity: sha512-tl0YWAfjUVb4LyyE4JIMVE8DlLzb1ecHRmIWc4eT6nkyDqQgHKzdHsnusxFEFMVLIQomgSg0Zz6hJ5S1E4W4ww==} - '@cspell/dict-software-terms@4.1.17': - resolution: {integrity: sha512-QORIk1R5DV8oOQ+oAlUWE7UomaJwUucqu2srrc2+PmkoI6R1fJwwg2uHCPBWlIb4PGDNEdXLv9BAD13H+0wytQ==} + '@cspell/dict-software-terms@4.1.18': + resolution: {integrity: sha512-QhOQ3qVFr2Y+uDw2SH15klVNU2S07ecFhG+2gpTO/K4Kuaui3INbVrzHOKW41ofP3ghv9y2TkUUtOP5KfddP8A==} '@cspell/dict-sql@2.1.8': resolution: {integrity: sha512-dJRE4JV1qmXTbbGm6WIcg1knmR6K5RXnQxF4XHs5HA3LAjc/zf77F95i5LC+guOGppVF6Hdl66S2UyxT+SAF3A==} @@ -932,14 +932,14 @@ packages: '@fontsource/overpass@5.1.1': resolution: {integrity: sha512-Zanaf61C+fKw+T6rnxacltqLmOo0MkiYTJIkAcOIPhsiD0zAubBvyyHUshmGIf/5C15MZjxK+JDeAd/dB3Zn5g==} - '@inquirer/confirm@5.0.2': - resolution: {integrity: sha512-KJLUHOaKnNCYzwVbryj3TNBxyZIrr56fR5N45v6K9IPrbT6B7DcudBMfylkV1A8PUdJE15mybkEQyp2/ZUpxUA==} + '@inquirer/confirm@5.1.0': + resolution: {integrity: sha512-osaBbIMEqVFjTX5exoqPXs6PilWQdjaLhGtMDXMXg/yxkHXNq43GlxGyTA35lK2HpzUgDN+Cjh/2AmqCN0QJpw==} engines: {node: '>=18'} peerDependencies: '@types/node': '>=18' - '@inquirer/core@10.1.0': - resolution: {integrity: sha512-I+ETk2AL+yAVbvuKx5AJpQmoaWhpiTFOg/UJb7ZkMAK4blmtG8ATh5ct+T/8xNld0CZG/2UhtkdMwpgvld92XQ==} + '@inquirer/core@10.1.1': + resolution: {integrity: sha512-rmZVXy9iZvO3ZStEe/ayuuwIJ23LSF13aPMlLMTQARX6lGUBDHGV8UB5i9MRrfy0+mZwt5/9bdy8llszSD3NQA==} engines: {node: '>=18'} '@inquirer/figures@1.0.8': @@ -1010,93 +1010,98 @@ packages: '@polymer/polymer@3.5.2': resolution: {integrity: sha512-fWwImY/UH4bb2534DVSaX+Azs2yKg8slkMBHOyGeU2kKx7Xmxp6Lee0jP8p6B3d7c1gFUPB2Z976dTUtX81pQA==} - '@rollup/rollup-android-arm-eabi@4.28.0': - resolution: {integrity: sha512-wLJuPLT6grGZsy34g4N1yRfYeouklTgPhH1gWXCYspenKYD0s3cR99ZevOGw5BexMNywkbV3UkjADisozBmpPQ==} + '@rollup/rollup-android-arm-eabi@4.28.1': + resolution: {integrity: sha512-2aZp8AES04KI2dy3Ss6/MDjXbwBzj+i0GqKtWXgw2/Ma6E4jJvujryO6gJAghIRVz7Vwr9Gtl/8na3nDUKpraQ==} cpu: [arm] os: [android] - '@rollup/rollup-android-arm64@4.28.0': - resolution: {integrity: sha512-eiNkznlo0dLmVG/6wf+Ifi/v78G4d4QxRhuUl+s8EWZpDewgk7PX3ZyECUXU0Zq/Ca+8nU8cQpNC4Xgn2gFNDA==} + '@rollup/rollup-android-arm64@4.28.1': + resolution: {integrity: sha512-EbkK285O+1YMrg57xVA+Dp0tDBRB93/BZKph9XhMjezf6F4TpYjaUSuPt5J0fZXlSag0LmZAsTmdGGqPp4pQFA==} cpu: [arm64] os: [android] - '@rollup/rollup-darwin-arm64@4.28.0': - resolution: {integrity: sha512-lmKx9yHsppblnLQZOGxdO66gT77bvdBtr/0P+TPOseowE7D9AJoBw8ZDULRasXRWf1Z86/gcOdpBrV6VDUY36Q==} + '@rollup/rollup-darwin-arm64@4.28.1': + resolution: {integrity: sha512-prduvrMKU6NzMq6nxzQw445zXgaDBbMQvmKSJaxpaZ5R1QDM8w+eGxo6Y/jhT/cLoCvnZI42oEqf9KQNYz1fqQ==} cpu: [arm64] os: [darwin] - '@rollup/rollup-darwin-x64@4.28.0': - resolution: {integrity: sha512-8hxgfReVs7k9Js1uAIhS6zq3I+wKQETInnWQtgzt8JfGx51R1N6DRVy3F4o0lQwumbErRz52YqwjfvuwRxGv1w==} + '@rollup/rollup-darwin-x64@4.28.1': + resolution: {integrity: sha512-WsvbOunsUk0wccO/TV4o7IKgloJ942hVFK1CLatwv6TJspcCZb9umQkPdvB7FihmdxgaKR5JyxDjWpCOp4uZlQ==} cpu: [x64] os: [darwin] - '@rollup/rollup-freebsd-arm64@4.28.0': - resolution: {integrity: sha512-lA1zZB3bFx5oxu9fYud4+g1mt+lYXCoch0M0V/xhqLoGatbzVse0wlSQ1UYOWKpuSu3gyN4qEc0Dxf/DII1bhQ==} + '@rollup/rollup-freebsd-arm64@4.28.1': + resolution: {integrity: sha512-HTDPdY1caUcU4qK23FeeGxCdJF64cKkqajU0iBnTVxS8F7H/7BewvYoG+va1KPSL63kQ1PGNyiwKOfReavzvNA==} cpu: [arm64] os: [freebsd] - '@rollup/rollup-freebsd-x64@4.28.0': - resolution: {integrity: sha512-aI2plavbUDjCQB/sRbeUZWX9qp12GfYkYSJOrdYTL/C5D53bsE2/nBPuoiJKoWp5SN78v2Vr8ZPnB+/VbQ2pFA==} + '@rollup/rollup-freebsd-x64@4.28.1': + resolution: {integrity: sha512-m/uYasxkUevcFTeRSM9TeLyPe2QDuqtjkeoTpP9SW0XxUWfcYrGDMkO/m2tTw+4NMAF9P2fU3Mw4ahNvo7QmsQ==} cpu: [x64] os: [freebsd] - '@rollup/rollup-linux-arm-gnueabihf@4.28.0': - resolution: {integrity: sha512-WXveUPKtfqtaNvpf0iOb0M6xC64GzUX/OowbqfiCSXTdi/jLlOmH0Ba94/OkiY2yTGTwteo4/dsHRfh5bDCZ+w==} + '@rollup/rollup-linux-arm-gnueabihf@4.28.1': + resolution: {integrity: sha512-QAg11ZIt6mcmzpNE6JZBpKfJaKkqTm1A9+y9O+frdZJEuhQxiugM05gnCWiANHj4RmbgeVJpTdmKRmH/a+0QbA==} cpu: [arm] os: [linux] - '@rollup/rollup-linux-arm-musleabihf@4.28.0': - resolution: {integrity: sha512-yLc3O2NtOQR67lI79zsSc7lk31xjwcaocvdD1twL64PK1yNaIqCeWI9L5B4MFPAVGEVjH5k1oWSGuYX1Wutxpg==} + '@rollup/rollup-linux-arm-musleabihf@4.28.1': + resolution: {integrity: sha512-dRP9PEBfolq1dmMcFqbEPSd9VlRuVWEGSmbxVEfiq2cs2jlZAl0YNxFzAQS2OrQmsLBLAATDMb3Z6MFv5vOcXg==} cpu: [arm] os: [linux] - '@rollup/rollup-linux-arm64-gnu@4.28.0': - resolution: {integrity: sha512-+P9G9hjEpHucHRXqesY+3X9hD2wh0iNnJXX/QhS/J5vTdG6VhNYMxJ2rJkQOxRUd17u5mbMLHM7yWGZdAASfcg==} + '@rollup/rollup-linux-arm64-gnu@4.28.1': + resolution: {integrity: sha512-uGr8khxO+CKT4XU8ZUH1TTEUtlktK6Kgtv0+6bIFSeiSlnGJHG1tSFSjm41uQ9sAO/5ULx9mWOz70jYLyv1QkA==} cpu: [arm64] os: [linux] - '@rollup/rollup-linux-arm64-musl@4.28.0': - resolution: {integrity: sha512-1xsm2rCKSTpKzi5/ypT5wfc+4bOGa/9yI/eaOLW0oMs7qpC542APWhl4A37AENGZ6St6GBMWhCCMM6tXgTIplw==} + '@rollup/rollup-linux-arm64-musl@4.28.1': + resolution: {integrity: sha512-QF54q8MYGAqMLrX2t7tNpi01nvq5RI59UBNx+3+37zoKX5KViPo/gk2QLhsuqok05sSCRluj0D00LzCwBikb0A==} cpu: [arm64] os: [linux] - '@rollup/rollup-linux-powerpc64le-gnu@4.28.0': - resolution: {integrity: sha512-zgWxMq8neVQeXL+ouSf6S7DoNeo6EPgi1eeqHXVKQxqPy1B2NvTbaOUWPn/7CfMKL7xvhV0/+fq/Z/J69g1WAQ==} + '@rollup/rollup-linux-loongarch64-gnu@4.28.1': + resolution: {integrity: sha512-vPul4uodvWvLhRco2w0GcyZcdyBfpfDRgNKU+p35AWEbJ/HPs1tOUrkSueVbBS0RQHAf/A+nNtDpvw95PeVKOA==} + cpu: [loong64] + os: [linux] + + '@rollup/rollup-linux-powerpc64le-gnu@4.28.1': + resolution: {integrity: sha512-pTnTdBuC2+pt1Rmm2SV7JWRqzhYpEILML4PKODqLz+C7Ou2apEV52h19CR7es+u04KlqplggmN9sqZlekg3R1A==} cpu: [ppc64] os: [linux] - '@rollup/rollup-linux-riscv64-gnu@4.28.0': - resolution: {integrity: sha512-VEdVYacLniRxbRJLNtzwGt5vwS0ycYshofI7cWAfj7Vg5asqj+pt+Q6x4n+AONSZW/kVm+5nklde0qs2EUwU2g==} + '@rollup/rollup-linux-riscv64-gnu@4.28.1': + resolution: {integrity: sha512-vWXy1Nfg7TPBSuAncfInmAI/WZDd5vOklyLJDdIRKABcZWojNDY0NJwruY2AcnCLnRJKSaBgf/GiJfauu8cQZA==} cpu: [riscv64] os: [linux] - '@rollup/rollup-linux-s390x-gnu@4.28.0': - resolution: {integrity: sha512-LQlP5t2hcDJh8HV8RELD9/xlYtEzJkm/aWGsauvdO2ulfl3QYRjqrKW+mGAIWP5kdNCBheqqqYIGElSRCaXfpw==} + '@rollup/rollup-linux-s390x-gnu@4.28.1': + resolution: {integrity: sha512-/yqC2Y53oZjb0yz8PVuGOQQNOTwxcizudunl/tFs1aLvObTclTwZ0JhXF2XcPT/zuaymemCDSuuUPXJJyqeDOg==} cpu: [s390x] os: [linux] - '@rollup/rollup-linux-x64-gnu@4.28.0': - resolution: {integrity: sha512-Nl4KIzteVEKE9BdAvYoTkW19pa7LR/RBrT6F1dJCV/3pbjwDcaOq+edkP0LXuJ9kflW/xOK414X78r+K84+msw==} + '@rollup/rollup-linux-x64-gnu@4.28.1': + resolution: {integrity: sha512-fzgeABz7rrAlKYB0y2kSEiURrI0691CSL0+KXwKwhxvj92VULEDQLpBYLHpF49MSiPG4sq5CK3qHMnb9tlCjBw==} cpu: [x64] os: [linux] - '@rollup/rollup-linux-x64-musl@4.28.0': - resolution: {integrity: sha512-eKpJr4vBDOi4goT75MvW+0dXcNUqisK4jvibY9vDdlgLx+yekxSm55StsHbxUsRxSTt3JEQvlr3cGDkzcSP8bw==} + '@rollup/rollup-linux-x64-musl@4.28.1': + resolution: {integrity: sha512-xQTDVzSGiMlSshpJCtudbWyRfLaNiVPXt1WgdWTwWz9n0U12cI2ZVtWe/Jgwyv/6wjL7b66uu61Vg0POWVfz4g==} cpu: [x64] os: [linux] - '@rollup/rollup-win32-arm64-msvc@4.28.0': - resolution: {integrity: sha512-Vi+WR62xWGsE/Oj+mD0FNAPY2MEox3cfyG0zLpotZdehPFXwz6lypkGs5y38Jd/NVSbOD02aVad6q6QYF7i8Bg==} + '@rollup/rollup-win32-arm64-msvc@4.28.1': + resolution: {integrity: sha512-wSXmDRVupJstFP7elGMgv+2HqXelQhuNf+IS4V+nUpNVi/GUiBgDmfwD0UGN3pcAnWsgKG3I52wMOBnk1VHr/A==} cpu: [arm64] os: [win32] - '@rollup/rollup-win32-ia32-msvc@4.28.0': - resolution: {integrity: sha512-kN/Vpip8emMLn/eOza+4JwqDZBL6MPNpkdaEsgUtW1NYN3DZvZqSQrbKzJcTL6hd8YNmFTn7XGWMwccOcJBL0A==} + '@rollup/rollup-win32-ia32-msvc@4.28.1': + resolution: {integrity: sha512-ZkyTJ/9vkgrE/Rk9vhMXhf8l9D+eAhbAVbsGsXKy2ohmJaWg0LPQLnIxRdRp/bKyr8tXuPlXhIoGlEB5XpJnGA==} cpu: [ia32] os: [win32] - '@rollup/rollup-win32-x64-msvc@4.28.0': - resolution: {integrity: sha512-Bvno2/aZT6usSa7lRDL2+hMjVAGjuqaymF1ApZm31JXzniR/hvr14jpU+/z4X6Gt5BPlzosscyJZGUvguXIqeQ==} + '@rollup/rollup-win32-x64-msvc@4.28.1': + resolution: {integrity: sha512-ZvK2jBafvttJjoIdKm/Q/Bh7IJ1Ose9IBOwpOXcOvW3ikGTQGmKDgxTC6oCAzW6PynbkKP8+um1du81XJHZ0JA==} cpu: [x64] os: [win32] @@ -1133,8 +1138,8 @@ packages: '@types/estree@1.0.6': resolution: {integrity: sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==} - '@types/geojson@7946.0.14': - resolution: {integrity: sha512-WCfD5Ht3ZesJUsONdhvm84dmzWOiOzOAqOncN0++w0lBw1o8OuDNJF2McvvCef/yBqb/HYRahp1BYtODFQ8bRg==} + '@types/geojson@7946.0.15': + resolution: {integrity: sha512-9oSxFzDCT2Rj6DfcHF8G++jxBKS7mBqXl5xrRW+Kbvjry6Uduya2iiwqHPhVXpasAVMBYKkEPGgKhd3+/HZ6xA==} '@types/node@22.10.1': resolution: {integrity: sha512-qKgsUwfHZV2WCWLAnVP1JqnpE6Im6h3Y0+fYgMTasNQ7V++CBX5OT1as0g0f+OyubbFqhf6XVNIsmN4IIhEgGQ==} @@ -1151,44 +1156,44 @@ packages: '@types/trusted-types@2.0.7': resolution: {integrity: sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==} - '@vaadin/a11y-base@24.5.4': - resolution: {integrity: sha512-P69sv2hewdUztVhzEhUBfcrl3r4fFCGlB+0o0W35Hp9HD5vPZNvSbvmJXlPoArx6jQ5Uo2oxb9zSekKVTG3jQw==} + '@vaadin/a11y-base@24.5.5': + resolution: {integrity: sha512-0+8jegJzRqwtvuu27nmWCCIHlmAPQea10CUu3jz/FkCewmHBsVUz0xi6BB/l2olk5WzvWkcZD+bpSypJrzQZ3Q==} - '@vaadin/checkbox@24.5.4': - resolution: {integrity: sha512-HkJ2QJohPFuc7Iq9wH41/mFSnTPxuywvEYefucHGIeSMHs7r0o47sAHq0mcllex5PmW73IsSBj9bR6yG8hUmng==} + '@vaadin/checkbox@24.5.5': + resolution: {integrity: sha512-Hzda5DmRqUOtP8A+nhmI6fERz3TvTZBd0en2suKPwvN7YHKNhsa7lDRi12liG+Rd/ux5U/H1fGYFfB3XKUjdFw==} - '@vaadin/component-base@24.5.4': - resolution: {integrity: sha512-oIF+OUzqAdibbj4pLlhPcDKHnJvux8ydEpCpkdzcMk0K52y7VSERwaWaKXGbWWJX7Xdu8Kt+J8/Q3vANi9+KeQ==} + '@vaadin/component-base@24.5.5': + resolution: {integrity: sha512-xuR5IzdYTF7kQiyjm1xtexSvJ3m9Uz3t92bany/tqZlCVOBhorMB8rc1fKo5Qw1PTuP85bnLf34YVNhXcSE8sA==} - '@vaadin/field-base@24.5.4': - resolution: {integrity: sha512-S049PyvO27NJumsymtgRDy8SmPmyiCkTtn7hjnDUjEBsW7EuCJNKMBnqcZeEMBLSgXLJXbez5F0glgLkELJLiQ==} + '@vaadin/field-base@24.5.5': + resolution: {integrity: sha512-AZybkO3yoy0A0UhidJZY00RbzpMno64Sjvm5GjTHTdudaBiHzVnrma4relOYQC3KA/kfc6roz8+efA+sgKIcrg==} - '@vaadin/grid@24.5.4': - resolution: {integrity: sha512-dt1bTci8RvUy1fLzcA/CyXbzeS1rX6lBbPvW6QyhOk7R4ME2LeGPRzYxYmfIQfIVB19EoS2fBgBlj1tWG7Qe1g==} + '@vaadin/grid@24.5.5': + resolution: {integrity: sha512-jxLfszR1wFxjXDL4zRF2ugsJedzetDt83536CYPKG68NEEXv5hNW9Ah8eCZk+CyYZA1GqwezXuKJMVU5O8HZ2g==} - '@vaadin/icon@24.5.4': - resolution: {integrity: sha512-p2wQeVWYOTlXZ66iwDQLkGMWcnHlJIZX6uVzDPnH1p8aEJS+y4sG7Fq5wYXECUq8n7GStxe6VlsCec7taiw8yQ==} + '@vaadin/icon@24.5.5': + resolution: {integrity: sha512-i3Tq1mVpWB+r3cQ2rIyDXdum5c80VP2PTAyS7vB6yD7Qraa0hwGmbfbiyvKbZdTIlDzUWBVQDFcL03UeS2Matw==} - '@vaadin/input-container@24.5.4': - resolution: {integrity: sha512-CEaZ0chod+LB7bgQZTjl/1myqsZnt5JqWVvHLzF+lI5KANH7dci5vjvj/K16tARtLpFsV+XKU+Kq3uVfOiTsJw==} + '@vaadin/input-container@24.5.5': + resolution: {integrity: sha512-4rI1IRTfp/s2+WEixP0zyIq50fdFgth4qnizGP9GW+ZL6fKTTnXwp1mA03IEuDZk0RIBkq1KlkC4sIYRKf8cTA==} - '@vaadin/lit-renderer@24.5.4': - resolution: {integrity: sha512-qfDA67McD25fzOw75a+b0P3ACf+jEi9l+5t/wxyDhXN66oQeq406pqxMdB0llkLjh/3+hLy8uu9XdpTFZEBGrQ==} + '@vaadin/lit-renderer@24.5.5': + resolution: {integrity: sha512-WCsy5Dbbgzsb5TQ4Wwwfty3m6hgLaSfEOd3sb3HjqKYMEA/Dx0aKrYNvvbBAKIIJr4zJn8KJlcoK6PefkI71Ww==} - '@vaadin/text-field@24.5.4': - resolution: {integrity: sha512-gLstfvwqhzguWecByub019sMa6m2T2uxms9PHQXnbHCRnSyZxvek9mXw6aUh0470A0ghh8F/QMRnBf8hvmCCIQ==} + '@vaadin/text-field@24.5.5': + resolution: {integrity: sha512-btmS5FlWifkUj8Wq01jQ1vCS8QQUB4dXL3T3buoS4wwZV6I6aCgSoqoBAFhYSUHTxNQUzlrA7+c/Ksn3gPhp6g==} '@vaadin/vaadin-development-mode-detector@2.0.7': resolution: {integrity: sha512-9FhVhr0ynSR3X2ao+vaIEttcNU5XfzCbxtmYOV8uIRnUCtNgbvMOIcyGBvntsX9I5kvIP2dV3cFAOG9SILJzEA==} - '@vaadin/vaadin-lumo-styles@24.5.4': - resolution: {integrity: sha512-W0o4iUv+fZ68NYHJiw2tMRFT8Syd9dcWDLFkfLIgYYlFMzxig5TlJOqhBEmATdlpj9Ba2T/cEJdV4MmUUZi9SA==} + '@vaadin/vaadin-lumo-styles@24.5.5': + resolution: {integrity: sha512-Mn77pARcsxi/vvspa1OdM9Cnn3fxxU7yMXtV9hJ+3Dk0U4HMuQLSbWL+vaJQwcXPOKQOPW07ujr9eXzpzwmvIQ==} - '@vaadin/vaadin-material-styles@24.5.4': - resolution: {integrity: sha512-csIENxieRpDzRPTS62JkqhUfoQqUix72C1yQ38gbTUhnzSWQbYkkiHD9yTzwtB2snpyBsUzyUwhFRZqpNSF6mg==} + '@vaadin/vaadin-material-styles@24.5.5': + resolution: {integrity: sha512-7D/mS8zOAswYTp/R7Rzl4Yvkh48nopLj20Z0/QPYpNlZ+IrTm1z5vh7dtIMwuOmrugrzAXHfd1zpHAgGLz4bNQ==} - '@vaadin/vaadin-themable-mixin@24.5.4': - resolution: {integrity: sha512-s0MAO9iRZYfIiX7HPZZ+vasrmNTKARhCxBBt3GiXhHFlKk5QbsvEYZxt2Ilas6ToiNMn/FbwvMeZb4w/JRx5/A==} + '@vaadin/vaadin-themable-mixin@24.5.5': + resolution: {integrity: sha512-PNka98FxocQqov5vd22OtQ3DJp+p/5+bd4RL8UqUYiNG8dOdXG3npW/1l+mG1JButbf/TPsLCLsnUVIKvchr7A==} '@vaadin/vaadin-usage-statistics@2.1.3': resolution: {integrity: sha512-8r4TNknD7OJQADe3VygeofFR7UNAXZ2/jjBFP5dgI8+2uMfnuGYgbuHivasKr9WSQ64sPej6m8rDoM1uSllXjQ==} @@ -1254,8 +1259,8 @@ packages: resolution: {integrity: sha512-qMrJVg2hoEsZJjMJez9yI2+nZlBUxgYzGV3mqcb2B/6T1ihXp0fWBDYlVHlHquuorgNUQP5a8qSmX6HF5rFJNg==} engines: {bun: '>=0.7.0', deno: '>=1.0.0', node: '>=16.5.0'} - agent-base@7.1.1: - resolution: {integrity: sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==} + agent-base@7.1.3: + resolution: {integrity: sha512-jRR5wdylq8CkOe6hei19GGZnxM6rBGwFl3Bg0YItGDimvjGtAvdZk4Pu6Cl4u4Igsws4a1fd1Vq3ezrhn4KmFw==} engines: {node: '>= 14'} analytics-utils@1.0.12: @@ -1332,8 +1337,8 @@ packages: resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} engines: {node: '>=6'} - caniuse-lite@1.0.30001686: - resolution: {integrity: sha512-Y7deg0Aergpa24M3qLC5xjNklnKnhsmSyR/V89dLZ1n0ucJIFNs7PgR2Yfa/Zf6W79SbBicgtGxZr2juHkEUIA==} + caniuse-lite@1.0.30001687: + resolution: {integrity: sha512-0S/FDhf4ZiqrTUiQ39dKeUjYRjkv7lOZU1Dgif2rIqrTzX/1wV2hfKu9TOm1IHkdSijfLswxTFzl/cvir+SLSQ==} chai@5.1.2: resolution: {integrity: sha512-aGtmf24DW6MLHHG5gCx4zaI3uBq3KRtxeVs0DjFH6Z0rDNbsvTxFASFvdj79pxjxZ8/5u3PIiN3IwEIQkiiuPw==} @@ -1491,8 +1496,8 @@ packages: dayjs@1.11.13: resolution: {integrity: sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg==} - debug@4.3.7: - resolution: {integrity: sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==} + debug@4.4.0: + resolution: {integrity: sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==} engines: {node: '>=6.0'} peerDependencies: supports-color: '*' @@ -1540,8 +1545,8 @@ packages: eastasianwidth@0.2.0: resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} - electron-to-chromium@1.5.71: - resolution: {integrity: sha512-dB68l59BI75W1BUGVTAEJy45CEVuEGy9qPVVQ8pnHyHMn36PLPPoE1mjLH+lo9rKulO3HC2OhbACI/8tCqJBcA==} + electron-to-chromium@1.5.72: + resolution: {integrity: sha512-ZpSAUOZ2Izby7qnZluSrAlGgGQzucmFbN0n64dYzocYxnxV5ufurpj3VgEe4cUp7ir9LmeLxNYo8bVnlM8bQHw==} emoji-regex@8.0.0: resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} @@ -1704,8 +1709,8 @@ packages: resolution: {integrity: sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==} engines: {node: '>= 14'} - https-proxy-agent@7.0.5: - resolution: {integrity: sha512-1e4Wqeblerz+tMKPIq2EMGiiWW1dIjZOksyHWSUm1rmuvw/how9hBHZ38lAGj5ID4Ik6EdkOw7NmWPy6LAwalw==} + https-proxy-agent@7.0.6: + resolution: {integrity: sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==} engines: {node: '>= 14'} iconv-lite@0.6.3: @@ -1842,8 +1847,8 @@ packages: resolution: {integrity: sha512-rh+Zjr6DNfUYR3bPwJEnuwDdqMbxZW7LOQfUN4B54+Cl+0o5zaU9RJ6bcidfDtC1cWCZXQ+nvX8bf6bAji37QQ==} engines: {node: '>=12'} - magic-string@0.30.14: - resolution: {integrity: sha512-5c99P1WKTed11ZC0HMJOj6CDIue6F8ySu+bJL+85q1zBEIY8IklrJ1eiKC2NDRh3Ct3FcvmJPyQHb9erXMTJNw==} + magic-string@0.30.15: + resolution: {integrity: sha512-zXeaYRgZ6ldS1RJJUrMrYgNJ4fdwnyI6tVqoiIhyCyv5IVTK9BU8Ic2l253GGETQHxI4HNUwhJ3fjDhKqEoaAw==} magicast@0.3.5: resolution: {integrity: sha512-L0WhttDl+2BOsybvEOLK7fW3UA0OQ0IQ2d6Zl2x/a6vVRs3bAY0ECOSHHeL5jD+SbOpOCUEi0y1DgHEn9Qn1AQ==} @@ -1890,8 +1895,8 @@ packages: ms@2.1.3: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} - msw@2.6.6: - resolution: {integrity: sha512-npfIIVRHKQX3Lw4aLWX4wBh+lQwpqdZNyJYB5K/+ktK8NhtkdsTxGK7WDrgknozcVyRI7TOqY6yBS9j2FTR+YQ==} + msw@2.6.8: + resolution: {integrity: sha512-nxXxnH6WALZ9a7rsQp4HU2AaD4iGAiouMmE/MY4al7pXTibgA6OZOuKhmN2WBIM6w9qMKwRtX8p2iOb45B2M/Q==} engines: {node: '>=18'} hasBin: true peerDependencies: @@ -1909,8 +1914,8 @@ packages: engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} hasBin: true - node-releases@2.0.18: - resolution: {integrity: sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==} + node-releases@2.0.19: + resolution: {integrity: sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==} nth-check@2.1.1: resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==} @@ -2012,8 +2017,8 @@ packages: resolve-pkg-maps@1.0.0: resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} - rollup@4.28.0: - resolution: {integrity: sha512-G9GOrmgWHBma4YfCcX8PjH0qhXSdH8B4HDE2o4/jaxj93S4DPCIDoLcXz99eWMji4hB29UFCEd7B2gwGJDR9cQ==} + rollup@4.28.1: + resolution: {integrity: sha512-61fXYl/qNVinKmGSTHAZ6Yy8I3YIJC/r2m9feHo6SwVAVcLT5MPwOUFe7EuURA/4m0NR8lXG4BBXuo/IZEsjMg==} engines: {node: '>=18.0.0', npm: '>=8.0.0'} hasBin: true @@ -2141,11 +2146,11 @@ packages: resolution: {integrity: sha512-n1cw8k1k0x4pgA2+9XrOkFydTerNcJ1zWCO5Nn9scWHTD+5tp8dghT2x1uduQePZTZgd3Tupf+x9BxJjeJi77Q==} engines: {node: '>=14.0.0'} - tldts-core@6.1.65: - resolution: {integrity: sha512-Uq5t0N0Oj4nQSbU8wFN1YYENvMthvwU13MQrMJRspYCGLSAZjAfoBOJki5IQpnBM/WFskxxC/gIOTwaedmHaSg==} + tldts-core@6.1.66: + resolution: {integrity: sha512-s07jJruSwndD2X8bVjwioPfqpIc1pDTzszPe9pL1Skbh4bjytL85KNQ3tolqLbCvpQHawIsGfFi9dgerWjqW4g==} - tldts@6.1.65: - resolution: {integrity: sha512-xU9gLTfAGsADQ2PcWee6Hg8RFAv0DnjMGVJmDnUmI8a9+nYmapMQix4afwrdaCtT+AqP4MaxEzu7cCrYmBPbzQ==} + tldts@6.1.66: + resolution: {integrity: sha512-l3ciXsYFel/jSRfESbyKYud1nOw7WfhrBEF9I3UiarYk/qEaOOwu3qXNECHw4fHGHGTEOuhf/VdKgoDX5M/dhQ==} hasBin: true to-regex-range@5.0.1: @@ -2468,7 +2473,7 @@ snapshots: '@esri/arcgis-html-sanitizer': 4.1.0 '@esri/calcite-colors': 6.1.0 '@esri/calcite-components': 2.13.2(@floating-ui/utils@0.2.8) - '@vaadin/grid': 24.5.4 + '@vaadin/grid': 24.5.5 '@zip.js/zip.js': 2.7.54 luxon: 3.5.0 marked: 14.1.4 @@ -2497,7 +2502,7 @@ snapshots: '@babel/traverse': 7.26.4 '@babel/types': 7.26.3 convert-source-map: 2.0.0 - debug: 4.3.7 + debug: 4.4.0 gensync: 1.0.0-beta.2 json5: 2.2.3 semver: 6.3.1 @@ -2564,7 +2569,7 @@ snapshots: '@babel/parser': 7.26.3 '@babel/template': 7.25.9 '@babel/types': 7.26.3 - debug: 4.3.7 + debug: 4.4.0 globals: 11.12.0 transitivePeerDependencies: - supports-color @@ -2665,16 +2670,16 @@ snapshots: '@cspell/dict-markdown': 2.0.7(@cspell/dict-css@4.0.16)(@cspell/dict-html-symbol-entities@4.0.3)(@cspell/dict-html@4.0.10)(@cspell/dict-typescript@3.1.11) '@cspell/dict-monkeyc': 1.0.9 '@cspell/dict-node': 5.0.5 - '@cspell/dict-npm': 5.1.14 + '@cspell/dict-npm': 5.1.15 '@cspell/dict-php': 4.0.13 '@cspell/dict-powershell': 5.0.13 '@cspell/dict-public-licenses': 2.0.11 - '@cspell/dict-python': 4.2.12 + '@cspell/dict-python': 4.2.13 '@cspell/dict-r': 2.0.4 '@cspell/dict-ruby': 5.0.7 '@cspell/dict-rust': 4.0.10 '@cspell/dict-scala': 5.0.6 - '@cspell/dict-software-terms': 4.1.17 + '@cspell/dict-software-terms': 4.1.18 '@cspell/dict-sql': 2.1.8 '@cspell/dict-svelte': 1.0.5 '@cspell/dict-swift': 2.0.4 @@ -2781,7 +2786,7 @@ snapshots: '@cspell/dict-node@5.0.5': {} - '@cspell/dict-npm@5.1.14': {} + '@cspell/dict-npm@5.1.15': {} '@cspell/dict-php@4.0.13': {} @@ -2789,7 +2794,7 @@ snapshots: '@cspell/dict-public-licenses@2.0.11': {} - '@cspell/dict-python@4.2.12': + '@cspell/dict-python@4.2.13': dependencies: '@cspell/dict-data-science': 2.0.5 @@ -2801,7 +2806,7 @@ snapshots: '@cspell/dict-scala@5.0.6': {} - '@cspell/dict-software-terms@4.1.17': {} + '@cspell/dict-software-terms@4.1.18': {} '@cspell/dict-sql@2.1.8': {} @@ -3082,13 +3087,13 @@ snapshots: '@fontsource/overpass@5.1.1': {} - '@inquirer/confirm@5.0.2(@types/node@22.10.1)': + '@inquirer/confirm@5.1.0(@types/node@22.10.1)': dependencies: - '@inquirer/core': 10.1.0(@types/node@22.10.1) + '@inquirer/core': 10.1.1(@types/node@22.10.1) '@inquirer/type': 3.0.1(@types/node@22.10.1) '@types/node': 22.10.1 - '@inquirer/core@10.1.0(@types/node@22.10.1)': + '@inquirer/core@10.1.1(@types/node@22.10.1)': dependencies: '@inquirer/figures': 1.0.8 '@inquirer/type': 3.0.1(@types/node@22.10.1) @@ -3171,58 +3176,61 @@ snapshots: dependencies: '@webcomponents/shadycss': 1.11.2 - '@rollup/rollup-android-arm-eabi@4.28.0': + '@rollup/rollup-android-arm-eabi@4.28.1': + optional: true + + '@rollup/rollup-android-arm64@4.28.1': optional: true - '@rollup/rollup-android-arm64@4.28.0': + '@rollup/rollup-darwin-arm64@4.28.1': optional: true - '@rollup/rollup-darwin-arm64@4.28.0': + '@rollup/rollup-darwin-x64@4.28.1': optional: true - '@rollup/rollup-darwin-x64@4.28.0': + '@rollup/rollup-freebsd-arm64@4.28.1': optional: true - '@rollup/rollup-freebsd-arm64@4.28.0': + '@rollup/rollup-freebsd-x64@4.28.1': optional: true - '@rollup/rollup-freebsd-x64@4.28.0': + '@rollup/rollup-linux-arm-gnueabihf@4.28.1': optional: true - '@rollup/rollup-linux-arm-gnueabihf@4.28.0': + '@rollup/rollup-linux-arm-musleabihf@4.28.1': optional: true - '@rollup/rollup-linux-arm-musleabihf@4.28.0': + '@rollup/rollup-linux-arm64-gnu@4.28.1': optional: true - '@rollup/rollup-linux-arm64-gnu@4.28.0': + '@rollup/rollup-linux-arm64-musl@4.28.1': optional: true - '@rollup/rollup-linux-arm64-musl@4.28.0': + '@rollup/rollup-linux-loongarch64-gnu@4.28.1': optional: true - '@rollup/rollup-linux-powerpc64le-gnu@4.28.0': + '@rollup/rollup-linux-powerpc64le-gnu@4.28.1': optional: true - '@rollup/rollup-linux-riscv64-gnu@4.28.0': + '@rollup/rollup-linux-riscv64-gnu@4.28.1': optional: true - '@rollup/rollup-linux-s390x-gnu@4.28.0': + '@rollup/rollup-linux-s390x-gnu@4.28.1': optional: true - '@rollup/rollup-linux-x64-gnu@4.28.0': + '@rollup/rollup-linux-x64-gnu@4.28.1': optional: true - '@rollup/rollup-linux-x64-musl@4.28.0': + '@rollup/rollup-linux-x64-musl@4.28.1': optional: true - '@rollup/rollup-win32-arm64-msvc@4.28.0': + '@rollup/rollup-win32-arm64-msvc@4.28.1': optional: true - '@rollup/rollup-win32-ia32-msvc@4.28.0': + '@rollup/rollup-win32-ia32-msvc@4.28.1': optional: true - '@rollup/rollup-win32-x64-msvc@4.28.0': + '@rollup/rollup-win32-x64-msvc@4.28.1': optional: true '@stencil/core@4.20.0': {} @@ -3249,7 +3257,7 @@ snapshots: '@types/estree@1.0.6': {} - '@types/geojson@7946.0.14': {} + '@types/geojson@7946.0.15': {} '@types/node@22.10.1': dependencies: @@ -3263,26 +3271,26 @@ snapshots: '@types/trusted-types@2.0.7': {} - '@vaadin/a11y-base@24.5.4': + '@vaadin/a11y-base@24.5.5': dependencies: '@open-wc/dedupe-mixin': 1.4.0 '@polymer/polymer': 3.5.2 - '@vaadin/component-base': 24.5.4 + '@vaadin/component-base': 24.5.5 lit: 3.2.1 - '@vaadin/checkbox@24.5.4': + '@vaadin/checkbox@24.5.5': dependencies: '@open-wc/dedupe-mixin': 1.4.0 '@polymer/polymer': 3.5.2 - '@vaadin/a11y-base': 24.5.4 - '@vaadin/component-base': 24.5.4 - '@vaadin/field-base': 24.5.4 - '@vaadin/vaadin-lumo-styles': 24.5.4 - '@vaadin/vaadin-material-styles': 24.5.4 - '@vaadin/vaadin-themable-mixin': 24.5.4 + '@vaadin/a11y-base': 24.5.5 + '@vaadin/component-base': 24.5.5 + '@vaadin/field-base': 24.5.5 + '@vaadin/vaadin-lumo-styles': 24.5.5 + '@vaadin/vaadin-material-styles': 24.5.5 + '@vaadin/vaadin-themable-mixin': 24.5.5 lit: 3.2.1 - '@vaadin/component-base@24.5.4': + '@vaadin/component-base@24.5.5': dependencies: '@open-wc/dedupe-mixin': 1.4.0 '@polymer/polymer': 3.5.2 @@ -3290,79 +3298,79 @@ snapshots: '@vaadin/vaadin-usage-statistics': 2.1.3 lit: 3.2.1 - '@vaadin/field-base@24.5.4': + '@vaadin/field-base@24.5.5': dependencies: '@open-wc/dedupe-mixin': 1.4.0 '@polymer/polymer': 3.5.2 - '@vaadin/a11y-base': 24.5.4 - '@vaadin/component-base': 24.5.4 + '@vaadin/a11y-base': 24.5.5 + '@vaadin/component-base': 24.5.5 lit: 3.2.1 - '@vaadin/grid@24.5.4': + '@vaadin/grid@24.5.5': dependencies: '@open-wc/dedupe-mixin': 1.4.0 '@polymer/polymer': 3.5.2 - '@vaadin/a11y-base': 24.5.4 - '@vaadin/checkbox': 24.5.4 - '@vaadin/component-base': 24.5.4 - '@vaadin/lit-renderer': 24.5.4 - '@vaadin/text-field': 24.5.4 - '@vaadin/vaadin-lumo-styles': 24.5.4 - '@vaadin/vaadin-material-styles': 24.5.4 - '@vaadin/vaadin-themable-mixin': 24.5.4 + '@vaadin/a11y-base': 24.5.5 + '@vaadin/checkbox': 24.5.5 + '@vaadin/component-base': 24.5.5 + '@vaadin/lit-renderer': 24.5.5 + '@vaadin/text-field': 24.5.5 + '@vaadin/vaadin-lumo-styles': 24.5.5 + '@vaadin/vaadin-material-styles': 24.5.5 + '@vaadin/vaadin-themable-mixin': 24.5.5 lit: 3.2.1 - '@vaadin/icon@24.5.4': + '@vaadin/icon@24.5.5': dependencies: '@open-wc/dedupe-mixin': 1.4.0 '@polymer/polymer': 3.5.2 - '@vaadin/component-base': 24.5.4 - '@vaadin/vaadin-lumo-styles': 24.5.4 - '@vaadin/vaadin-themable-mixin': 24.5.4 + '@vaadin/component-base': 24.5.5 + '@vaadin/vaadin-lumo-styles': 24.5.5 + '@vaadin/vaadin-themable-mixin': 24.5.5 lit: 3.2.1 - '@vaadin/input-container@24.5.4': + '@vaadin/input-container@24.5.5': dependencies: '@polymer/polymer': 3.5.2 - '@vaadin/component-base': 24.5.4 - '@vaadin/vaadin-lumo-styles': 24.5.4 - '@vaadin/vaadin-material-styles': 24.5.4 - '@vaadin/vaadin-themable-mixin': 24.5.4 + '@vaadin/component-base': 24.5.5 + '@vaadin/vaadin-lumo-styles': 24.5.5 + '@vaadin/vaadin-material-styles': 24.5.5 + '@vaadin/vaadin-themable-mixin': 24.5.5 lit: 3.2.1 - '@vaadin/lit-renderer@24.5.4': + '@vaadin/lit-renderer@24.5.5': dependencies: lit: 3.2.1 - '@vaadin/text-field@24.5.4': + '@vaadin/text-field@24.5.5': dependencies: '@open-wc/dedupe-mixin': 1.4.0 '@polymer/polymer': 3.5.2 - '@vaadin/a11y-base': 24.5.4 - '@vaadin/component-base': 24.5.4 - '@vaadin/field-base': 24.5.4 - '@vaadin/input-container': 24.5.4 - '@vaadin/vaadin-lumo-styles': 24.5.4 - '@vaadin/vaadin-material-styles': 24.5.4 - '@vaadin/vaadin-themable-mixin': 24.5.4 + '@vaadin/a11y-base': 24.5.5 + '@vaadin/component-base': 24.5.5 + '@vaadin/field-base': 24.5.5 + '@vaadin/input-container': 24.5.5 + '@vaadin/vaadin-lumo-styles': 24.5.5 + '@vaadin/vaadin-material-styles': 24.5.5 + '@vaadin/vaadin-themable-mixin': 24.5.5 lit: 3.2.1 '@vaadin/vaadin-development-mode-detector@2.0.7': {} - '@vaadin/vaadin-lumo-styles@24.5.4': + '@vaadin/vaadin-lumo-styles@24.5.5': dependencies: '@polymer/polymer': 3.5.2 - '@vaadin/component-base': 24.5.4 - '@vaadin/icon': 24.5.4 - '@vaadin/vaadin-themable-mixin': 24.5.4 + '@vaadin/component-base': 24.5.5 + '@vaadin/icon': 24.5.5 + '@vaadin/vaadin-themable-mixin': 24.5.5 - '@vaadin/vaadin-material-styles@24.5.4': + '@vaadin/vaadin-material-styles@24.5.5': dependencies: '@polymer/polymer': 3.5.2 - '@vaadin/component-base': 24.5.4 - '@vaadin/vaadin-themable-mixin': 24.5.4 + '@vaadin/component-base': 24.5.5 + '@vaadin/vaadin-themable-mixin': 24.5.5 - '@vaadin/vaadin-themable-mixin@24.5.4': + '@vaadin/vaadin-themable-mixin@24.5.5': dependencies: '@open-wc/dedupe-mixin': 1.4.0 lit: 3.2.1 @@ -3371,10 +3379,10 @@ snapshots: dependencies: '@vaadin/vaadin-development-mode-detector': 2.0.7 - '@vitest/coverage-istanbul@2.1.8(vitest@2.1.8(@types/node@22.10.1)(jsdom@25.0.1)(msw@2.6.6(@types/node@22.10.1)(typescript@5.7.2)))': + '@vitest/coverage-istanbul@2.1.8(vitest@2.1.8(@types/node@22.10.1)(jsdom@25.0.1)(msw@2.6.8(@types/node@22.10.1)(typescript@5.7.2)))': dependencies: '@istanbuljs/schema': 0.1.3 - debug: 4.3.7 + debug: 4.4.0 istanbul-lib-coverage: 3.2.2 istanbul-lib-instrument: 6.0.3 istanbul-lib-report: 3.0.1 @@ -3383,25 +3391,25 @@ snapshots: magicast: 0.3.5 test-exclude: 7.0.1 tinyrainbow: 1.2.0 - vitest: 2.1.8(@types/node@22.10.1)(jsdom@25.0.1)(msw@2.6.6(@types/node@22.10.1)(typescript@5.7.2)) + vitest: 2.1.8(@types/node@22.10.1)(jsdom@25.0.1)(msw@2.6.8(@types/node@22.10.1)(typescript@5.7.2)) transitivePeerDependencies: - supports-color - '@vitest/coverage-v8@2.1.8(vitest@2.1.8(@types/node@22.10.1)(jsdom@25.0.1)(msw@2.6.6(@types/node@22.10.1)(typescript@5.7.2)))': + '@vitest/coverage-v8@2.1.8(vitest@2.1.8(@types/node@22.10.1)(jsdom@25.0.1)(msw@2.6.8(@types/node@22.10.1)(typescript@5.7.2)))': dependencies: '@ampproject/remapping': 2.3.0 '@bcoe/v8-coverage': 0.2.3 - debug: 4.3.7 + debug: 4.4.0 istanbul-lib-coverage: 3.2.2 istanbul-lib-report: 3.0.1 istanbul-lib-source-maps: 5.0.6 istanbul-reports: 3.1.7 - magic-string: 0.30.14 + magic-string: 0.30.15 magicast: 0.3.5 std-env: 3.8.0 test-exclude: 7.0.1 tinyrainbow: 1.2.0 - vitest: 2.1.8(@types/node@22.10.1)(jsdom@25.0.1)(msw@2.6.6(@types/node@22.10.1)(typescript@5.7.2)) + vitest: 2.1.8(@types/node@22.10.1)(jsdom@25.0.1)(msw@2.6.8(@types/node@22.10.1)(typescript@5.7.2)) transitivePeerDependencies: - supports-color @@ -3412,13 +3420,13 @@ snapshots: chai: 5.1.2 tinyrainbow: 1.2.0 - '@vitest/mocker@2.1.8(msw@2.6.6(@types/node@22.10.1)(typescript@5.7.2))(vite@5.4.11(@types/node@22.10.1))': + '@vitest/mocker@2.1.8(msw@2.6.8(@types/node@22.10.1)(typescript@5.7.2))(vite@5.4.11(@types/node@22.10.1))': dependencies: '@vitest/spy': 2.1.8 estree-walker: 3.0.3 - magic-string: 0.30.14 + magic-string: 0.30.15 optionalDependencies: - msw: 2.6.6(@types/node@22.10.1)(typescript@5.7.2) + msw: 2.6.8(@types/node@22.10.1)(typescript@5.7.2) vite: 5.4.11(@types/node@22.10.1) '@vitest/pretty-format@2.1.8': @@ -3433,7 +3441,7 @@ snapshots: '@vitest/snapshot@2.1.8': dependencies: '@vitest/pretty-format': 2.1.8 - magic-string: 0.30.14 + magic-string: 0.30.15 pathe: 1.1.2 '@vitest/spy@2.1.8': @@ -3466,11 +3474,7 @@ snapshots: '@zip.js/zip.js@2.7.54': {} - agent-base@7.1.1: - dependencies: - debug: 4.3.7 - transitivePeerDependencies: - - supports-color + agent-base@7.1.3: {} analytics-utils@1.0.12(@types/dlv@1.1.5): dependencies: @@ -3526,16 +3530,16 @@ snapshots: browserslist@4.24.2: dependencies: - caniuse-lite: 1.0.30001686 - electron-to-chromium: 1.5.71 - node-releases: 2.0.18 + caniuse-lite: 1.0.30001687 + electron-to-chromium: 1.5.72 + node-releases: 2.0.19 update-browserslist-db: 1.1.1(browserslist@4.24.2) cac@6.7.14: {} callsites@3.1.0: {} - caniuse-lite@1.0.30001686: {} + caniuse-lite@1.0.30001687: {} chai@5.1.2: dependencies: @@ -3747,7 +3751,7 @@ snapshots: dayjs@1.11.13: {} - debug@4.3.7: + debug@4.4.0: dependencies: ms: 2.1.3 @@ -3788,7 +3792,7 @@ snapshots: eastasianwidth@0.2.0: {} - electron-to-chromium@1.5.71: {} + electron-to-chromium@1.5.72: {} emoji-regex@8.0.0: {} @@ -3980,15 +3984,15 @@ snapshots: http-proxy-agent@7.0.2: dependencies: - agent-base: 7.1.1 - debug: 4.3.7 + agent-base: 7.1.3 + debug: 4.4.0 transitivePeerDependencies: - supports-color - https-proxy-agent@7.0.5: + https-proxy-agent@7.0.6: dependencies: - agent-base: 7.1.1 - debug: 4.3.7 + agent-base: 7.1.3 + debug: 4.4.0 transitivePeerDependencies: - supports-color @@ -4044,7 +4048,7 @@ snapshots: istanbul-lib-source-maps@5.0.6: dependencies: '@jridgewell/trace-mapping': 0.3.25 - debug: 4.3.7 + debug: 4.4.0 istanbul-lib-coverage: 3.2.2 transitivePeerDependencies: - supports-color @@ -4070,7 +4074,7 @@ snapshots: form-data: 4.0.1 html-encoding-sniffer: 4.0.0 http-proxy-agent: 7.0.2 - https-proxy-agent: 7.0.5 + https-proxy-agent: 7.0.6 is-potential-custom-element-name: 1.0.1 nwsapi: 2.2.16 parse5: 7.2.1 @@ -4099,7 +4103,7 @@ snapshots: form-data: 4.0.1 html-encoding-sniffer: 4.0.0 http-proxy-agent: 7.0.2 - https-proxy-agent: 7.0.5 + https-proxy-agent: 7.0.6 is-potential-custom-element-name: 1.0.1 nwsapi: 2.2.16 parse5: 7.2.1 @@ -4166,7 +4170,7 @@ snapshots: luxon@3.5.0: {} - magic-string@0.30.14: + magic-string@0.30.15: dependencies: '@jridgewell/sourcemap-codec': 1.5.0 @@ -4207,12 +4211,12 @@ snapshots: ms@2.1.3: {} - msw@2.6.6(@types/node@22.10.1)(typescript@5.7.2): + msw@2.6.8(@types/node@22.10.1)(typescript@5.7.2): dependencies: '@bundled-es-modules/cookie': 2.0.1 '@bundled-es-modules/statuses': 1.0.1 '@bundled-es-modules/tough-cookie': 0.1.6 - '@inquirer/confirm': 5.0.2(@types/node@22.10.1) + '@inquirer/confirm': 5.1.0(@types/node@22.10.1) '@mswjs/interceptors': 0.37.3 '@open-draft/deferred-promise': 2.2.0 '@open-draft/until': 2.1.0 @@ -4236,7 +4240,7 @@ snapshots: nanoid@3.3.8: {} - node-releases@2.0.18: {} + node-releases@2.0.19: {} nth-check@2.1.1: dependencies: @@ -4318,28 +4322,29 @@ snapshots: resolve-pkg-maps@1.0.0: {} - rollup@4.28.0: + rollup@4.28.1: dependencies: '@types/estree': 1.0.6 optionalDependencies: - '@rollup/rollup-android-arm-eabi': 4.28.0 - '@rollup/rollup-android-arm64': 4.28.0 - '@rollup/rollup-darwin-arm64': 4.28.0 - '@rollup/rollup-darwin-x64': 4.28.0 - '@rollup/rollup-freebsd-arm64': 4.28.0 - '@rollup/rollup-freebsd-x64': 4.28.0 - '@rollup/rollup-linux-arm-gnueabihf': 4.28.0 - '@rollup/rollup-linux-arm-musleabihf': 4.28.0 - '@rollup/rollup-linux-arm64-gnu': 4.28.0 - '@rollup/rollup-linux-arm64-musl': 4.28.0 - '@rollup/rollup-linux-powerpc64le-gnu': 4.28.0 - '@rollup/rollup-linux-riscv64-gnu': 4.28.0 - '@rollup/rollup-linux-s390x-gnu': 4.28.0 - '@rollup/rollup-linux-x64-gnu': 4.28.0 - '@rollup/rollup-linux-x64-musl': 4.28.0 - '@rollup/rollup-win32-arm64-msvc': 4.28.0 - '@rollup/rollup-win32-ia32-msvc': 4.28.0 - '@rollup/rollup-win32-x64-msvc': 4.28.0 + '@rollup/rollup-android-arm-eabi': 4.28.1 + '@rollup/rollup-android-arm64': 4.28.1 + '@rollup/rollup-darwin-arm64': 4.28.1 + '@rollup/rollup-darwin-x64': 4.28.1 + '@rollup/rollup-freebsd-arm64': 4.28.1 + '@rollup/rollup-freebsd-x64': 4.28.1 + '@rollup/rollup-linux-arm-gnueabihf': 4.28.1 + '@rollup/rollup-linux-arm-musleabihf': 4.28.1 + '@rollup/rollup-linux-arm64-gnu': 4.28.1 + '@rollup/rollup-linux-arm64-musl': 4.28.1 + '@rollup/rollup-linux-loongarch64-gnu': 4.28.1 + '@rollup/rollup-linux-powerpc64le-gnu': 4.28.1 + '@rollup/rollup-linux-riscv64-gnu': 4.28.1 + '@rollup/rollup-linux-s390x-gnu': 4.28.1 + '@rollup/rollup-linux-x64-gnu': 4.28.1 + '@rollup/rollup-linux-x64-musl': 4.28.1 + '@rollup/rollup-win32-arm64-msvc': 4.28.1 + '@rollup/rollup-win32-ia32-msvc': 4.28.1 + '@rollup/rollup-win32-x64-msvc': 4.28.1 fsevents: 2.3.3 rrweb-cssom@0.7.1: {} @@ -4448,11 +4453,11 @@ snapshots: tinyspy@3.0.2: {} - tldts-core@6.1.65: {} + tldts-core@6.1.66: {} - tldts@6.1.65: + tldts@6.1.66: dependencies: - tldts-core: 6.1.65 + tldts-core: 6.1.66 to-regex-range@5.0.1: dependencies: @@ -4467,7 +4472,7 @@ snapshots: tough-cookie@5.0.0: dependencies: - tldts: 6.1.65 + tldts: 6.1.66 tr46@5.0.0: dependencies: @@ -4510,7 +4515,7 @@ snapshots: vite-node@2.1.8(@types/node@22.10.1): dependencies: cac: 6.7.14 - debug: 4.3.7 + debug: 4.4.0 es-module-lexer: 1.5.4 pathe: 1.1.2 vite: 5.4.11(@types/node@22.10.1) @@ -4529,7 +4534,7 @@ snapshots: dependencies: esbuild: 0.21.5 postcss: 8.4.49 - rollup: 4.28.0 + rollup: 4.28.1 optionalDependencies: '@types/node': 22.10.1 fsevents: 2.3.3 @@ -4538,26 +4543,26 @@ snapshots: dependencies: esbuild: 0.24.0 postcss: 8.4.49 - rollup: 4.28.0 + rollup: 4.28.1 optionalDependencies: '@types/node': 22.10.1 fsevents: 2.3.3 tsx: 4.19.2 yaml: 2.6.1 - vitest@2.1.8(@types/node@22.10.1)(jsdom@25.0.1)(msw@2.6.6(@types/node@22.10.1)(typescript@5.7.2)): + vitest@2.1.8(@types/node@22.10.1)(jsdom@25.0.1)(msw@2.6.8(@types/node@22.10.1)(typescript@5.7.2)): dependencies: '@vitest/expect': 2.1.8 - '@vitest/mocker': 2.1.8(msw@2.6.6(@types/node@22.10.1)(typescript@5.7.2))(vite@5.4.11(@types/node@22.10.1)) + '@vitest/mocker': 2.1.8(msw@2.6.8(@types/node@22.10.1)(typescript@5.7.2))(vite@5.4.11(@types/node@22.10.1)) '@vitest/pretty-format': 2.1.8 '@vitest/runner': 2.1.8 '@vitest/snapshot': 2.1.8 '@vitest/spy': 2.1.8 '@vitest/utils': 2.1.8 chai: 5.1.2 - debug: 4.3.7 + debug: 4.4.0 expect-type: 1.1.0 - magic-string: 0.30.14 + magic-string: 0.30.15 pathe: 1.1.2 std-env: 3.8.0 tinybench: 2.9.0 From 89d3e9216d75913183912440ed0f43189e013a9a Mon Sep 17 00:00:00 2001 From: Jeff Jacobson Date: Tue, 10 Dec 2024 16:29:24 -0800 Subject: [PATCH 18/24] refactor: Added end milepost controls --- index.html | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/index.html b/index.html index 2cc4da3b..bacce1e4 100644 --- a/index.html +++ b/index.html @@ -47,13 +47,25 @@ - Decrease + IncreaseDecrease + Milepost - Back + AheadBack + + + End Milepost + Ahead + Back + +
Date: Wed, 11 Dec 2024 16:57:23 -0800 Subject: [PATCH 19/24] refactor: :construction: Add handling for end milepost in URLs --- src/elc/arcgis.ts | 38 +++-- src/elc/url.ts | 148 ++++++++++-------- src/layers/MilepostLayer/arcade/County.arcade | 2 +- 3 files changed, 108 insertions(+), 80 deletions(-) diff --git a/src/elc/arcgis.ts b/src/elc/arcgis.ts index c6b3d732..69d81d42 100644 --- a/src/elc/arcgis.ts +++ b/src/elc/arcgis.ts @@ -1,6 +1,7 @@ import Graphic from "@arcgis/core/Graphic"; import Point from "@arcgis/core/geometry/Point"; -import { hasXAndY } from "../types"; +import Polyline from "@arcgis/core/geometry/Polyline"; +import { hasPaths, hasXAndY } from "../types"; import { ElcError } from "./errors"; import type { DateType, @@ -39,12 +40,23 @@ export function routeLocationToGraphic< if (routeLocation instanceof ElcError) { throw routeLocation; } - let geometry: __esri.Point | undefined; - if (routeLocation.RouteGeometry && hasXAndY(routeLocation.RouteGeometry)) { - const { x, y, spatialReference } = routeLocation.RouteGeometry; - geometry = new Point({ x, y, spatialReference }); + let geometry: __esri.Point | __esri.Polyline | undefined; + if (routeLocation.RouteGeometry) { + if (hasXAndY(routeLocation.RouteGeometry)) { + const { x, y, spatialReference } = routeLocation.RouteGeometry; + geometry = new Point({ x, y, spatialReference }); + } else if (hasPaths(routeLocation.RouteGeometry)) { + const { paths, spatialReference } = routeLocation.RouteGeometry; + geometry = new Polyline({ + paths, + spatialReference, + }); + } } else { - console.warn("Input does not have valid point geometry.", routeLocation); + console.warn( + "Input does not have valid point or polyline geometry.", + routeLocation, + ); } let attributes: | (Record & { @@ -53,17 +65,18 @@ export function routeLocationToGraphic< Direction: "D" | "I"; Srmp?: number; Back: "B" | ""; - "Township Subdivision": null; - City: null; - County: null; + EndSrmp?: number; + EndBack?: "B" | ""; }) | undefined; if (hasValidSrmpData(routeLocation)) { const { Route, + Decrease, Srmp, Back, - Decrease, + EndSrmp, + EndBack, // Angle, // Arm, // ArmCalcReturnCode, @@ -82,9 +95,8 @@ export function routeLocationToGraphic< Direction: Decrease ? "D" : "I", Srmp, Back: Back ? "B" : "", - "Township Subdivision": null, - City: null, - County: null, + EndSrmp: EndSrmp, + EndBack: EndBack ? "B" : "", }; oid++; } else { diff --git a/src/elc/url.ts b/src/elc/url.ts index 6f55437e..e1362043 100644 --- a/src/elc/url.ts +++ b/src/elc/url.ts @@ -44,9 +44,10 @@ const keyRegExps = new Map([ ["rrq", /^R{1,2}Q/i], ["dir", /^D(?:IR)?/i], ["mp", /^(?:SR)?MP/i], - ["endMP", /^E(ND)MP/i], + ["endMP", /^E(ND)?(SR)?MP/i], ] as const); +const milepostAndBackIndicatorRegex = /^(?\d+(?:\.\d+)?)(?B)?$/i; /** * Regular expression patterns to validate URL parameter values. */ @@ -66,8 +67,8 @@ const valueRegExps = new Map([ * @example * // matches "123", "123.45", "123B", "123.45B" */ - ["mp", /^(?\d+(?:\.\d+)?)(?B)?$/i], - ["endMP", /^(?\d+(?:\.\d+)?)(?B)?$/i], + ["mp", milepostAndBackIndicatorRegex], + ["endMP", milepostAndBackIndicatorRegex], ] as const); type KeyValueRegExpTuple = [keyRegexp: RegExp, valueRegexp: RegExp]; @@ -94,43 +95,49 @@ export function getUrlSearchParameter( urlParams: URLSearchParams, key: UrlParamMapKey, ) { - // Retrieve the regular expression tuple from the regExpMap based on the key. - const reTuple = regExpMap.get(key); - if (!reTuple) { - const keyList = [...regExpMap.keys()].map((k) => `"${k}"`).join(", "); - const valueReList = [...regExpMap.values()] - .map(([k]) => k.source) - .join(", "); - // If the key is not found, throw a ReferenceError with the key. - throw new ReferenceError( - `Invalid URL parameter key: ${key}. Valid values are ${keyList}. Alternative values are ${valueReList}.`, - ); - } - - const [keyRe, valueRe] = reTuple; let output: string | null = null; - // Iterate over each key-value pair in the URL search parameters. - for (const [k, v] of urlParams.entries()) { - // If the key does not match the regular expression, continue to the next iteration. - if (!keyRe.test(k)) { - continue; + /* __PURE__ */ console.group(getUrlSearchParameter.name, { urlParams, key }); + try { + // Retrieve the regular expression tuple from the regExpMap based on the key. + const reTuple = regExpMap.get(key); + if (!reTuple) { + const keyList = [...regExpMap.keys()].map((k) => `"${k}"`).join(", "); + const valueReList = [...regExpMap.values()] + .map(([k]) => k.source) + .join(", "); + // If the key is not found, throw a ReferenceError with the key. + throw new ReferenceError( + `Invalid URL parameter key: ${key}. Valid values are ${keyList}. Alternative values are ${valueReList}.`, + ); } - // Execute the value regular expression on the value. - const valueMatch = valueRe.exec(v); - - // If there is a match, assign the value to the output variable and break the loop. - if (valueMatch) { - output = valueMatch[0]; - break; + const [keyRe, valueRe] = reTuple; + + // Iterate over each key-value pair in the URL search parameters. + for (const [k, v] of urlParams.entries()) { + // If the key does not match the regular expression, continue to the next iteration. + if (!keyRe.test(k)) { + continue; + } + + // Execute the value regular expression on the value. + const valueMatch = valueRe.exec(v); + + // If there is a match, assign the value to the output variable and break the loop. + if (valueMatch) { + output = valueMatch[0]; + break; + } + // Throw error if there is no match. + throw new FormatError( + v, + valueRe, + `Invalid URL parameter value for key: ${k}: ${v}.\nValue needs to match ${valueRe}.`, + ); } - // Throw error if there is no match. - throw new FormatError( - v, - valueRe, - `Invalid URL parameter value for key: ${k}: ${v}.\nValue needs to match ${valueRe}.`, - ); + } finally { + /* __PURE__ */ console.groupEnd(); } // Return the output value. @@ -247,7 +254,7 @@ function parseSrmp(mp: string): { srmp: number; back: boolean } { */ export function getElcParamsFromUrl( url: string | URL | URLSearchParams = window.location.href, -): ValidRouteLocationForMPInput | null { +) { // If the URL is a URL object, use its search params. let searchParams: URLSearchParams; if (url instanceof URL) { @@ -285,18 +292,10 @@ export function getElcParamsFromUrl( const emp = getUrlSearchParameter(searchParams, "endMP"); - if (!emp) { - return { - Route: route, - Srmp: srmp, - Back: back, - Decrease: /dD/i.test(direction), - ReferenceDate: today, - ResponseDate: today, - }; - } - const { srmp: endSrmp, back: endBack } = parseSrmp(emp); - return { + const { srmp: endSrmp, back: endBack } = emp + ? parseSrmp(emp) + : { srmp: null, back: null }; + const output = { Route: route, Srmp: srmp, Back: back, @@ -305,7 +304,9 @@ export function getElcParamsFromUrl( ResponseDate: today, EndSrmp: endSrmp, EndBack: endBack, - } as ValidRouteLocationForMPInput; + } as ValidRouteLocationForMPInput; + /* __PURE__ */ console.debug("output", output); + return output; } /** @@ -320,27 +321,42 @@ export async function callElcFromUrl( milepostLayer: __esri.FeatureLayer, options: Pick = { outSR: 3857 }, ) { - const routeLocation = getElcParamsFromUrl(); + /* __PURE__ */ console.group(callElcFromUrl.name, { milepostLayer, options }); + try { + const routeLocation = getElcParamsFromUrl(); + /* __PURE__ */ console.debug("routeLocation", routeLocation); - if (!routeLocation) { - return null; - } + if (!routeLocation) { + return null; + } - const elcResults = await findRouteLocations({ - locations: [routeLocation], - outSR: options.outSR, - }); + const elcResults = await findRouteLocations({ + locations: [routeLocation], + outSR: options.outSR, + }); - if (elcResults.length < 1) { - return null; - } + /* __PURE__ */ console.debug("elcResults", elcResults); - const location = elcResults[0]; - if (location instanceof ElcError) { - throw location; - } + if (elcResults.length < 1) { + return null; + } - const graphic = routeLocationToGraphic(location); + const location = elcResults[0]; + if (location instanceof ElcError) { + /* __PURE__ */ console.error("ElcError", location); + throw location; + } + + const graphic = routeLocationToGraphic(location); + + /* __PURE__ */ console.debug("graphic", graphic); - return addGraphicsToLayer(milepostLayer, [graphic]); + const addedGraphics = addGraphicsToLayer(milepostLayer, [graphic]); + + /* __PURE__ */ console.debug("added graphics", addedGraphics); + + return addedGraphics; + } finally { + /* __PURE__ */ console.groupEnd(); + } } diff --git a/src/layers/MilepostLayer/arcade/County.arcade b/src/layers/MilepostLayer/arcade/County.arcade index 58aad7c2..bc82de6f 100644 --- a/src/layers/MilepostLayer/arcade/County.arcade +++ b/src/layers/MilepostLayer/arcade/County.arcade @@ -19,4 +19,4 @@ for (var f in match) { return f.JURISDICT_LABEL_NM } -return $userInput; \ No newline at end of file +// return $userInput; \ No newline at end of file From d499670094d280b6a9feb664bf36dae139c3a03a Mon Sep 17 00:00:00 2001 From: Jeff Jacobson Date: Thu, 12 Dec 2024 10:06:16 -0800 Subject: [PATCH 20/24] refactor: :construction: Milepost segments can now added from URL Need to modify renderer to show line segments with begin and end mileposts rather then ones showing where the user clicked to the milepost on the route. --- src/elc/url.ts | 12 +++++++-- src/main.ts | 67 ++++++++++++++++++++++++++------------------------ 2 files changed, 45 insertions(+), 34 deletions(-) diff --git a/src/elc/url.ts b/src/elc/url.ts index e1362043..038da091 100644 --- a/src/elc/url.ts +++ b/src/elc/url.ts @@ -319,6 +319,7 @@ export function getElcParamsFromUrl( */ export async function callElcFromUrl( milepostLayer: __esri.FeatureLayer, + lineMilepostLayer: __esri.FeatureLayer, options: Pick = { outSR: 3857 }, ) { /* __PURE__ */ console.group(callElcFromUrl.name, { milepostLayer, options }); @@ -349,9 +350,16 @@ export async function callElcFromUrl( const graphic = routeLocationToGraphic(location); - /* __PURE__ */ console.debug("graphic", graphic); + /* __PURE__ */ console.debug("graphic", graphic.toJSON()); - const addedGraphics = addGraphicsToLayer(milepostLayer, [graphic]); + const layer = + graphic.geometry.type === "polyline" ? lineMilepostLayer : milepostLayer; + + /* __PURE__ */ console.debug( + layer === lineMilepostLayer ? "line layer" : "point layer", + ); + + const addedGraphics = addGraphicsToLayer(layer, [graphic]); /* __PURE__ */ console.debug("added graphics", addedGraphics); diff --git a/src/main.ts b/src/main.ts index 57930563..337d04aa 100644 --- a/src/main.ts +++ b/src/main.ts @@ -628,39 +628,42 @@ if (!testWebGL2Support()) { }); } - // Once the milepost layerview has been created, check for ELC data from the URL - // and, if present, add the location to the map. - milepostPointLayer.on("layerview-create", () => { - /** - * Calls the ELC API to retrieve graphics from the URL and adds them to the milepost layer. - * @returns A promise that resolves when the graphics have been added to the layer and the view has been updated. - */ - const callElc = async () => { - const elcGraphics = await callElcFromUrl(milepostPointLayer); - if (elcGraphics) { - const addedFeatures = await addGraphicsToLayer( + Promise.all([milepostPointLayer.when(), milepostLineLayer.when()]).then( + () => { + /** + * Calls the ELC API to retrieve graphics from the URL and adds them to the milepost layer. + * @returns A promise that resolves when the graphics have been added to the layer and the view has been updated. + */ + const callElc = async () => { + const elcGraphics = await callElcFromUrl( milepostPointLayer, - elcGraphics, + milepostLineLayer, ); - const scale = Number.parseFloat(import.meta.env.VITE_ZOOM_SCALE); - const viewpoint = new Viewpoint({ - scale, - targetGeometry: addedFeatures.at(0)?.geometry, - }); - await view.goTo(viewpoint, { - animate: false, - }); - view - .openPopup({ - features: addedFeatures, - }) - .catch((reason: unknown) => { - console.error("Failed to open popup", reason); + if (elcGraphics) { + const addedFeatures = await addGraphicsToLayer( + milepostPointLayer, + elcGraphics, + ); + const scale = Number.parseFloat(import.meta.env.VITE_ZOOM_SCALE); + const viewpoint = new Viewpoint({ + scale, + targetGeometry: addedFeatures.at(0)?.geometry, }); - } - }; - callElc().catch((reason: unknown) => { - emitErrorEvent(reason); - }); - }); + await view.goTo(viewpoint, { + animate: false, + }); + view + .openPopup({ + features: addedFeatures, + }) + .catch((reason: unknown) => { + console.error("Failed to open popup", reason); + }); + } + }; + callElc().catch((reason: unknown) => { + emitErrorEvent(reason); + }); + }, + ); } From 29f0c4092c56d7d6415f1bb462d87bb221ea6102 Mon Sep 17 00:00:00 2001 From: Jeff Jacobson Date: Thu, 12 Dec 2024 11:19:14 -0800 Subject: [PATCH 21/24] build: :pushpin: Specify v1.0.1 tag for WSDOT-GIS/wsdot-web-styles dependency --- package.json | 2 +- pnpm-lock.yaml | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index 0d6e95f7..ecc6a7dd 100644 --- a/package.json +++ b/package.json @@ -28,7 +28,7 @@ "@fontsource/overpass": "^5.1.1", "@types/geojson": "^7946.0.15", "@wsdot/land-use-codes": "github:WSDOT-GIS/land-use", - "@wsdot/web-styles": "github:WSDOT-GIS/wsdot-web-styles", + "@wsdot/web-styles": "github:WSDOT-GIS/wsdot-web-styles#v1.0.1", "analytics": "^0.8.14", "browser-update": "^3.3.55", "dms-conversion": "^3.1.3", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 3d541fdf..7c275aca 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -33,8 +33,8 @@ importers: specifier: github:WSDOT-GIS/land-use version: https://codeload.github.com/WSDOT-GIS/land-use/tar.gz/0ed447fa99cd05a5480cec5e2e94b1b06cbd02b5(typescript@5.7.2) '@wsdot/web-styles': - specifier: github:WSDOT-GIS/wsdot-web-styles - version: https://codeload.github.com/WSDOT-GIS/wsdot-web-styles/tar.gz/3398615915f71ee72e1dfef9d6d2c1035df16b17 + specifier: github:WSDOT-GIS/wsdot-web-styles#v1.0.1 + version: https://codeload.github.com/WSDOT-GIS/wsdot-web-styles/tar.gz/7d4f6d074709d8fdd3a4c20ba85a35c707613a3b analytics: specifier: ^0.8.14 version: 0.8.14(@types/dlv@1.1.5) @@ -1251,8 +1251,8 @@ packages: peerDependencies: typescript: ^5.0.0 - '@wsdot/web-styles@https://codeload.github.com/WSDOT-GIS/wsdot-web-styles/tar.gz/3398615915f71ee72e1dfef9d6d2c1035df16b17': - resolution: {tarball: https://codeload.github.com/WSDOT-GIS/wsdot-web-styles/tar.gz/3398615915f71ee72e1dfef9d6d2c1035df16b17} + '@wsdot/web-styles@https://codeload.github.com/WSDOT-GIS/wsdot-web-styles/tar.gz/7d4f6d074709d8fdd3a4c20ba85a35c707613a3b': + resolution: {tarball: https://codeload.github.com/WSDOT-GIS/wsdot-web-styles/tar.gz/7d4f6d074709d8fdd3a4c20ba85a35c707613a3b} version: 1.0.1 '@zip.js/zip.js@2.7.54': @@ -3467,7 +3467,7 @@ snapshots: - supports-color - utf-8-validate - '@wsdot/web-styles@https://codeload.github.com/WSDOT-GIS/wsdot-web-styles/tar.gz/3398615915f71ee72e1dfef9d6d2c1035df16b17': + '@wsdot/web-styles@https://codeload.github.com/WSDOT-GIS/wsdot-web-styles/tar.gz/7d4f6d074709d8fdd3a4c20ba85a35c707613a3b': optionalDependencies: '@fontsource/inconsolata': 5.1.0 '@fontsource/lato': 5.1.0 From f02ac9b72914c12ceb310211da998efd5be28e44 Mon Sep 17 00:00:00 2001 From: Jeff Jacobson Date: Thu, 12 Dec 2024 11:41:09 -0800 Subject: [PATCH 22/24] refactor: :recycle: remove unused type import --- src/elc/url.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/elc/url.ts b/src/elc/url.ts index 038da091..87b59fd4 100644 --- a/src/elc/url.ts +++ b/src/elc/url.ts @@ -29,7 +29,6 @@ import type { FindNearestRouteLocationParameters, FindRouteLocationParameters, RouteGeometry, - RouteGeometryPolyline, ValidRouteLocationForMPInput, } from "./types"; From 4edc1bb78220159a9df132de19e47af415be0848 Mon Sep 17 00:00:00 2001 From: Jeff Jacobson Date: Thu, 12 Dec 2024 15:24:15 -0800 Subject: [PATCH 23/24] refactor: :construction: Added symbol for route segments --- index.html | 4 +- src/addGraphicsToLayer.ts | 39 ++---- src/elc/url.ts | 129 +++++++----------- .../arcade/WGS 1984 Coordinates.arcade | 8 +- .../webMercatorToWgs1984.function.arcade | 34 +++-- .../MilepostOffsetLineRenderer.ts | 44 ++++-- src/layers/MilepostLayer/symbol/index.ts | 26 +++- src/main.ts | 67 ++++++++- src/replace-title-with-tooltip.ts | 43 ++---- src/setupPopupActions.ts | 2 - 10 files changed, 234 insertions(+), 162 deletions(-) diff --git a/index.html b/index.html index bacce1e4..7e8917fd 100644 --- a/index.html +++ b/index.html @@ -57,7 +57,8 @@ AheadBack - +
g.toJSON() as unknown), - }); - try { - // Add graphics to the layer and await for the edit to complete. - const editsResult = await milepostLayer.applyEdits( - { - addFeatures: locationGraphics, - }, - {}, - ); - /* __PURE__ */ console.debug( - "editsResult", - editsResult.addFeatureResults.map((e) => ({ ...e })), - ); + // Add graphics to the layer and await for the edit to complete. + const editsResult = await milepostLayer.applyEdits( + { + addFeatures: locationGraphics, + }, + {}, + ); - // Get the added features from the edits result by querying the milepost layer - // for the features with matching object IDs. - const query = milepostLayer.createQuery(); - /* __PURE__ */ console.debug("query", query.toJSON()); - query.objectIds = editsResult.addFeatureResults.map((r) => r.objectId); - const results = await milepostLayer.queryFeatures(query); + // Get the added features from the edits result by querying the milepost layer + // for the features with matching object IDs. + const query = milepostLayer.createQuery(); + query.objectIds = editsResult.addFeatureResults.map((r) => r.objectId); + const results = await milepostLayer.queryFeatures(query); - return results.features; - } finally { - /* __PURE__ */ console.groupEnd(); - } + return results.features; } diff --git a/src/elc/url.ts b/src/elc/url.ts index 87b59fd4..f35b2cb9 100644 --- a/src/elc/url.ts +++ b/src/elc/url.ts @@ -96,47 +96,42 @@ export function getUrlSearchParameter( ) { let output: string | null = null; - /* __PURE__ */ console.group(getUrlSearchParameter.name, { urlParams, key }); - try { - // Retrieve the regular expression tuple from the regExpMap based on the key. - const reTuple = regExpMap.get(key); - if (!reTuple) { - const keyList = [...regExpMap.keys()].map((k) => `"${k}"`).join(", "); - const valueReList = [...regExpMap.values()] - .map(([k]) => k.source) - .join(", "); - // If the key is not found, throw a ReferenceError with the key. - throw new ReferenceError( - `Invalid URL parameter key: ${key}. Valid values are ${keyList}. Alternative values are ${valueReList}.`, - ); + // Retrieve the regular expression tuple from the regExpMap based on the key. + const reTuple = regExpMap.get(key); + if (!reTuple) { + const keyList = [...regExpMap.keys()].map((k) => `"${k}"`).join(", "); + const valueReList = [...regExpMap.values()] + .map(([k]) => k.source) + .join(", "); + // If the key is not found, throw a ReferenceError with the key. + throw new ReferenceError( + `Invalid URL parameter key: ${key}. Valid values are ${keyList}. Alternative values are ${valueReList}.`, + ); + } + + const [keyRe, valueRe] = reTuple; + + // Iterate over each key-value pair in the URL search parameters. + for (const [k, v] of urlParams.entries()) { + // If the key does not match the regular expression, continue to the next iteration. + if (!keyRe.test(k)) { + continue; } - const [keyRe, valueRe] = reTuple; - - // Iterate over each key-value pair in the URL search parameters. - for (const [k, v] of urlParams.entries()) { - // If the key does not match the regular expression, continue to the next iteration. - if (!keyRe.test(k)) { - continue; - } - - // Execute the value regular expression on the value. - const valueMatch = valueRe.exec(v); - - // If there is a match, assign the value to the output variable and break the loop. - if (valueMatch) { - output = valueMatch[0]; - break; - } - // Throw error if there is no match. - throw new FormatError( - v, - valueRe, - `Invalid URL parameter value for key: ${k}: ${v}.\nValue needs to match ${valueRe}.`, - ); + // Execute the value regular expression on the value. + const valueMatch = valueRe.exec(v); + + // If there is a match, assign the value to the output variable and break the loop. + if (valueMatch) { + output = valueMatch[0]; + break; } - } finally { - /* __PURE__ */ console.groupEnd(); + // Throw error if there is no match. + throw new FormatError( + v, + valueRe, + `Invalid URL parameter value for key: ${k}: ${v}.\nValue needs to match ${valueRe}.`, + ); } // Return the output value. @@ -304,7 +299,6 @@ export function getElcParamsFromUrl( EndSrmp: endSrmp, EndBack: endBack, } as ValidRouteLocationForMPInput; - /* __PURE__ */ console.debug("output", output); return output; } @@ -321,49 +315,32 @@ export async function callElcFromUrl( lineMilepostLayer: __esri.FeatureLayer, options: Pick = { outSR: 3857 }, ) { - /* __PURE__ */ console.group(callElcFromUrl.name, { milepostLayer, options }); - try { - const routeLocation = getElcParamsFromUrl(); - /* __PURE__ */ console.debug("routeLocation", routeLocation); - - if (!routeLocation) { - return null; - } - - const elcResults = await findRouteLocations({ - locations: [routeLocation], - outSR: options.outSR, - }); + const routeLocation = getElcParamsFromUrl(); - /* __PURE__ */ console.debug("elcResults", elcResults); - - if (elcResults.length < 1) { - return null; - } - - const location = elcResults[0]; - if (location instanceof ElcError) { - /* __PURE__ */ console.error("ElcError", location); - throw location; - } + if (!routeLocation) { + return null; + } - const graphic = routeLocationToGraphic(location); + const elcResults = await findRouteLocations({ + locations: [routeLocation], + outSR: options.outSR, + }); - /* __PURE__ */ console.debug("graphic", graphic.toJSON()); + if (elcResults.length < 1) { + return null; + } - const layer = - graphic.geometry.type === "polyline" ? lineMilepostLayer : milepostLayer; + const location = elcResults[0]; + if (location instanceof ElcError) { + throw location; + } - /* __PURE__ */ console.debug( - layer === lineMilepostLayer ? "line layer" : "point layer", - ); + const graphic = routeLocationToGraphic(location); - const addedGraphics = addGraphicsToLayer(layer, [graphic]); + const layer = + graphic.geometry.type === "polyline" ? lineMilepostLayer : milepostLayer; - /* __PURE__ */ console.debug("added graphics", addedGraphics); + const addedGraphics = addGraphicsToLayer(layer, [graphic]); - return addedGraphics; - } finally { - /* __PURE__ */ console.groupEnd(); - } + return addedGraphics; } diff --git a/src/layers/MilepostLayer/arcade/WGS 1984 Coordinates.arcade b/src/layers/MilepostLayer/arcade/WGS 1984 Coordinates.arcade index beac825b..71a589c9 100644 --- a/src/layers/MilepostLayer/arcade/WGS 1984 Coordinates.arcade +++ b/src/layers/MilepostLayer/arcade/WGS 1984 Coordinates.arcade @@ -1,3 +1,9 @@ // import fromWebMercatorFunction from "./parts/fromWebMercator.function.arcade" -webMercatorToWgs1984(Geometry($feature)) \ No newline at end of file +var featureGeometry = Geometry($feature); + +if (TypeOf(featureGeometry) == "Point") { + webMercatorToWgs1984(Geometry($feature)) +} else { + webMercatorToWgs1984(Point($userInput)) +} diff --git a/src/layers/MilepostLayer/arcade/parts/webMercatorToWgs1984.function.arcade b/src/layers/MilepostLayer/arcade/parts/webMercatorToWgs1984.function.arcade index 63067117..dc591280 100644 --- a/src/layers/MilepostLayer/arcade/parts/webMercatorToWgs1984.function.arcade +++ b/src/layers/MilepostLayer/arcade/parts/webMercatorToWgs1984.function.arcade @@ -1,10 +1,10 @@ -function webMercatorToWgs1984(geom) { - // Web Mercator coordinates - var xWebMercator = geom.x; - var yWebMercator = geom.y; +// Constants +var R_MAJOR = 6378137.0; + +function xyWebMercatorToWgs1984(xy) { - // Constants - var R_MAJOR = 6378137.0; + var xWebMercator = xy[0]; + var yWebMercator = xy[1]; // Convert Web Mercator (x) to longitude (WGS 1984) var lonWGS84 = (xWebMercator / R_MAJOR) * (180 / PI); @@ -13,8 +13,22 @@ function webMercatorToWgs1984(geom) { var latWGS84 = (Atan(Exp(yWebMercator / R_MAJOR)) * 2 - PI / 2) * (180 / PI); - return { - x: lonWGS84, - y: latWGS84, - }; + return [lonWGS84, latWGS84]; +} + +function webMercatorToWgs1984(geom) { + if (geom.type == "Point") { + // Web Mercator coordinates + var xWebMercator = geom.x; + var yWebMercator = geom.y; + + var wgsXY = xyWebMercatorToWgs1984([xWebMercator, yWebMercator]); + + return { + x: wgsXY[0], + y: wgsXY[1], + }; + } + + return null; } diff --git a/src/layers/MilepostLayer/milepost-line-layer/MilepostOffsetLineRenderer.ts b/src/layers/MilepostLayer/milepost-line-layer/MilepostOffsetLineRenderer.ts index ee35ed35..40aea85c 100644 --- a/src/layers/MilepostLayer/milepost-line-layer/MilepostOffsetLineRenderer.ts +++ b/src/layers/MilepostLayer/milepost-line-layer/MilepostOffsetLineRenderer.ts @@ -1,9 +1,9 @@ -import SimpleRenderer from "@arcgis/core/renderers/SimpleRenderer"; +import UniqueValueRenderer from "@arcgis/core/renderers/UniqueValueRenderer"; import CIMSymbol from "@arcgis/core/symbols/CIMSymbol"; import SimpleMarkerSymbol from "@arcgis/core/symbols/SimpleMarkerSymbol"; import { convertToCIMSymbol } from "@arcgis/core/symbols/support/cimConversionUtils"; import { isCimVectorMarker } from "../create-cim"; -import { cimVectorMarker } from "../symbol"; +import { cimVectorMarker, segmentEndpointCimVectorMarker } from "../symbol"; import { endMilepostLabelPrimitiveOverride, milepostLabelPrimitiveOverride, @@ -53,7 +53,7 @@ const strokeSymbolLayer: __esri.CIMSolidStroke = { width: 2, color: [255, 100, 100, 255], }; -const cimLineSymbol: __esri.CIMLineSymbol = { +const cimOffsetAndMilepostLineSymbol: __esri.CIMLineSymbol = { type: "CIMLineSymbol", symbolLayers: [ { @@ -68,20 +68,48 @@ const cimLineSymbol: __esri.CIMLineSymbol = { strokeSymbolLayer, ], }; -const cimSymbol = new CIMSymbol({ + +const cimLineSegmentLineSymbol: __esri.CIMLineSymbol = { + type: "CIMLineSymbol", + symbolLayers: [ + cimVectorMarker, + segmentEndpointCimVectorMarker, + strokeSymbolLayer, + ], +}; + +const offsetAndMilepostCimSymbol = new CIMSymbol({ data: { + primitiveOverrides: [milepostLabelPrimitiveOverride], + type: "CIMSymbolReference", + symbol: cimOffsetAndMilepostLineSymbol, + }, +}); + +const lineSegmentCimSymbol = new CIMSymbol({ + data: { + type: "CIMSymbolReference", primitiveOverrides: [ milepostLabelPrimitiveOverride, endMilepostLabelPrimitiveOverride, ], - type: "CIMSymbolReference", - symbol: cimLineSymbol, + symbol: cimLineSegmentLineSymbol, }, }); /** * Simple Renderer using a CIM symbol. */ -export default new SimpleRenderer({ - symbol: cimSymbol, +export default new UniqueValueRenderer({ + defaultSymbol: offsetAndMilepostCimSymbol, + defaultLabel: "Clicked Milepost", + valueExpression: "IIF($feature.EndSrmp != null, '1', '0')", + valueExpressionTitle: "Has an End Milepost", + uniqueValueInfos: [ + { + label: "Route Segment", + symbol: lineSegmentCimSymbol, + value: "1", + }, + ], }); diff --git a/src/layers/MilepostLayer/symbol/index.ts b/src/layers/MilepostLayer/symbol/index.ts index e4ff41eb..a2b6f69c 100644 --- a/src/layers/MilepostLayer/symbol/index.ts +++ b/src/layers/MilepostLayer/symbol/index.ts @@ -58,7 +58,7 @@ const cimMarkerGraphic: __esri.CIMMarkerGraphic = { textString: " ", }; -const endpointCimMarkerGraphic: __esri.CIMMarkerGraphic = { +const segmentEndpointCimMarkerGraphic: __esri.CIMMarkerGraphic = { ...cimMarkerGraphic, primitiveName: "endMilepostLabel", textString: " ", @@ -75,9 +75,22 @@ export const cimVectorMarker: __esri.CIMVectorMarker = { respectFrame: true, }; -export const endpointCimVectorMarker: __esri.CIMVectorMarker = { +export const segmentStartpointCimVectorMarker: __esri.CIMVectorMarker = { ...cimVectorMarker, - markerGraphics: [endpointCimMarkerGraphic], + markerGraphics: [cimMarkerGraphic], + markerPlacement: { + type: "CIMMarkerPlacementAtExtremities", + extremityPlacement: "JustBegin", + }, +}; + +export const segmentEndpointCimVectorMarker: __esri.CIMVectorMarker = { + ...cimVectorMarker, + markerGraphics: [segmentEndpointCimMarkerGraphic], + markerPlacement: { + type: "CIMMarkerPlacementAtExtremities", + extremityPlacement: "JustEnd", + }, }; const cimPointSymbol: __esri.CIMPointSymbol = { @@ -89,7 +102,7 @@ const cimPointSymbol: __esri.CIMPointSymbol = { const endpointCimPointSymbol: __esri.CIMPointSymbol = { ...cimPointSymbol, - symbolLayers: [endpointCimVectorMarker], + symbolLayers: [segmentEndpointCimVectorMarker], }; export const milepostSymbol = new CIMSymbol({ @@ -110,3 +123,8 @@ export const endpointMilepostSymbol = new CIMSymbol({ symbol: endpointCimPointSymbol, }, }); + +/* __PURE__ */ console.debug( + "endMilepostSymbol", + endpointMilepostSymbol.toJSON(), +); diff --git a/src/main.ts b/src/main.ts index 337d04aa..5df4a7bf 100644 --- a/src/main.ts +++ b/src/main.ts @@ -57,7 +57,6 @@ let analytics: AnalyticsInstance | null = null; import("./setupAnalytics") .then(({ default: a }) => { - /* __PURE__ */ console.debug("Tag Manager loaded", a); analytics = a; analytics?.page(); }) @@ -112,10 +111,8 @@ const updateNonProductionTitle = () => { const environment = getHostEnvironment(); // Exit if non-production environment was not detected. if (!environment) { - /* __PURE__ */ console.debug("No non-production environment detected."); return environment; } - /* __PURE__ */ console.debug(`Non production environment: ${environment}`); const suffix = ` - ${environment}`; document.title += suffix; @@ -161,9 +158,67 @@ import("@arcgis/core/kernel") import("@arcgis/core/config") .then(({ default: config }) => { config.applicationName = import.meta.env.VITE_TITLE; - config.log.level = "error"; - // TODO: Once all production environment issues have been fixed, replace above line 👆 with the one below 👇. - // config.log.level = import.meta.env.DEV ? "info" : "error"; + config.log.level = import.meta.env.DEV + ? "info" + : import.meta.env.PROD + ? "none" + : "warn"; + + if (!config.log.interceptors) { + config.log.interceptors = []; + } + + config.log.interceptors.push((level, module, ...args) => { + let logFunction: + | typeof console.log + | typeof console.error + | typeof console.warn; + switch (level) { + case "error": + logFunction = console.error; + break; + case "warn": + logFunction = console.warn; + break; + default: + logFunction = console.log; + break; + } + /* __PURE__ */ logFunction("intercepted log", { level, module, args }); + + if ( + level === "error" && + module === "esri.widgets.Feature.support.arcadeFeatureUtils" + ) { + console.group(module); + const [errorType, errorInfo] = args as [ + string, + Record & { + error: Error; + expressionInfo: __esri.ExpressionInfo; + graphic: __esri.Graphic; + }, + ]; + + const { error, expressionInfo, graphic } = errorInfo; + + const { name: expressionName, expression } = expressionInfo; + + console.error(errorType, { + ...errorInfo, + error: error.message, + errorName: error.name, + expressionName, + expression, + graphic: graphic.toJSON(), + }); + console.log(expression); + console.groupEnd(); + return true; + } + + return false; + }); }) .catch((reason: unknown) => { console.error("Failed to setup app config", reason); diff --git a/src/replace-title-with-tooltip.ts b/src/replace-title-with-tooltip.ts index b23c8f31..65c38c46 100644 --- a/src/replace-title-with-tooltip.ts +++ b/src/replace-title-with-tooltip.ts @@ -11,36 +11,23 @@ * @param parent - The parent element to search for Calcite elements. */ export function replaceTitleWithTooltip(parent = document.body) { - /* __PURE__ */ console.group("replaceTitleWithTooltip"); - try { - const elementsWithTitles = parent.querySelectorAll("[title]"); - /* __PURE__ */ console.debug( - `Found ${elementsWithTitles.length} elements with titles`, - elementsWithTitles, - ); - for (const element of elementsWithTitles) { - // Skip non-calcite elements. - if ( - !/^calcite-/i.test(element.tagName) || - element.tagName === "CALCITE-COMBOBOX" - ) { - /* __PURE__ */ console.debug( - `Skipping non calcite element: ${element.tagName}`, - element, - ); - continue; - } + const elementsWithTitles = parent.querySelectorAll("[title]"); + for (const element of elementsWithTitles) { + // Skip non-calcite elements. + if ( + !/^calcite-/i.test(element.tagName) || + element.tagName === "CALCITE-COMBOBOX" + ) { + continue; + } - const { title } = element; + const { title } = element; - const tooltip = document.createElement("calcite-tooltip"); - tooltip.referenceElement = element; - tooltip.append(title); - element.removeAttribute("title"); - parent.append(tooltip); - } - } finally { - /* __PURE__ */ console.groupEnd(); + const tooltip = document.createElement("calcite-tooltip"); + tooltip.referenceElement = element; + tooltip.append(title); + element.removeAttribute("title"); + parent.append(tooltip); } } diff --git a/src/setupPopupActions.ts b/src/setupPopupActions.ts index ef20abdd..7f788270 100644 --- a/src/setupPopupActions.ts +++ b/src/setupPopupActions.ts @@ -47,7 +47,6 @@ export function setupPopupActions(view: __esri.MapView) { navigator.clipboard .writeText([y, x].join(",")) .then(() => { - /* __PURE__ */ console.debug("Copied coordinates to clipboard."); alert.open = true; }) .catch((error: unknown) => { @@ -61,7 +60,6 @@ export function setupPopupActions(view: __esri.MapView) { const popupTriggerActionEventHandler: __esri.PopupTriggerActionEventHandler = (event) => { - /* __PURE__ */ console.debug("trigger-action", event); if (event.action.id === "copy") { const feature = view.popup.selectedFeature; if (isPoint(feature.geometry)) { From d0ce3a93142258b8cc0b04411b36e1cfaa1c2cce Mon Sep 17 00:00:00 2001 From: Jeff Jacobson Date: Thu, 12 Dec 2024 15:57:26 -0800 Subject: [PATCH 24/24] feat: :sparkles: route segement via URL User can now zoom to a line segment as defined by a RouteID, Direction, (Begin) Milepost, (Begin) Back, End Milepost and End Back values via URL. --- .../MilepostOffsetLineRenderer.ts | 8 +++- src/main.ts | 46 +++++++++++++------ 2 files changed, 39 insertions(+), 15 deletions(-) diff --git a/src/layers/MilepostLayer/milepost-line-layer/MilepostOffsetLineRenderer.ts b/src/layers/MilepostLayer/milepost-line-layer/MilepostOffsetLineRenderer.ts index 40aea85c..17e9f628 100644 --- a/src/layers/MilepostLayer/milepost-line-layer/MilepostOffsetLineRenderer.ts +++ b/src/layers/MilepostLayer/milepost-line-layer/MilepostOffsetLineRenderer.ts @@ -2,6 +2,7 @@ import UniqueValueRenderer from "@arcgis/core/renderers/UniqueValueRenderer"; import CIMSymbol from "@arcgis/core/symbols/CIMSymbol"; import SimpleMarkerSymbol from "@arcgis/core/symbols/SimpleMarkerSymbol"; import { convertToCIMSymbol } from "@arcgis/core/symbols/support/cimConversionUtils"; +import { highwaySignBackgroundColor } from "../../../colors"; import { isCimVectorMarker } from "../create-cim"; import { cimVectorMarker, segmentEndpointCimVectorMarker } from "../symbol"; import { @@ -74,7 +75,12 @@ const cimLineSegmentLineSymbol: __esri.CIMLineSymbol = { symbolLayers: [ cimVectorMarker, segmentEndpointCimVectorMarker, - strokeSymbolLayer, + { + type: "CIMSolidStroke", + color: highwaySignBackgroundColor.toJSON(), + enable: true, + width: 3, + }, ], }; diff --git a/src/main.ts b/src/main.ts index 5df4a7bf..c41d7b0e 100644 --- a/src/main.ts +++ b/src/main.ts @@ -690,23 +690,41 @@ if (!testWebGL2Support()) { * @returns A promise that resolves when the graphics have been added to the layer and the view has been updated. */ const callElc = async () => { - const elcGraphics = await callElcFromUrl( + // Call the features from the URL and add them to the layer. + const addedFeatures = await callElcFromUrl( milepostPointLayer, milepostLineLayer, ); - if (elcGraphics) { - const addedFeatures = await addGraphicsToLayer( - milepostPointLayer, - elcGraphics, - ); - const scale = Number.parseFloat(import.meta.env.VITE_ZOOM_SCALE); - const viewpoint = new Viewpoint({ - scale, - targetGeometry: addedFeatures.at(0)?.geometry, - }); - await view.goTo(viewpoint, { - animate: false, - }); + if (addedFeatures) { + // Zoom to the first feature (if any are in the array). + // Only expecting to ever be a single feature present. + const feature = addedFeatures.at(0); + if (feature) { + const targetGeometry = feature?.geometry; + + /** + * The zoom target. + * + * Geometry Type | Zoom Target + * ------------------------|----------------------------------- + * point | A viewpoint with a specified scale + * polyline (or non-point) | The feature itself. + */ + let goToTarget2D: Graphic | __esri.Viewpoint = feature; + + if (targetGeometry?.type === "point") { + const scale = Number.parseFloat(import.meta.env.VITE_ZOOM_SCALE); + goToTarget2D = new Viewpoint({ + scale, + targetGeometry: targetGeometry, + }); + } + + await view.goTo(goToTarget2D, { + animate: false, + }); + } + view .openPopup({ features: addedFeatures,