@opendfieldmap/sdk 0.2.0-beta → 0.2.2-beta

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -17,9 +17,10 @@ const widget = await createOEMWidget('#map', {
17
17
  markerTypes: ['crate_i', 'aurylene'],
18
18
  labels: true,
19
19
  markerClustering: true,
20
+ boundarySource: 'oem',
20
21
  customPoints: [{
21
22
  id: 'route-start',
22
- position: { regionId: 'Valley_4', x: 400, y: 600, floorId: 'M' },
23
+ position: { regionId: 'Valley_4', x: 400, z: -600, floorId: 'M' },
23
24
  style: 'framed',
24
25
  icon: '/icons/route-start.webp',
25
26
  }],
@@ -32,7 +33,7 @@ widget.destroy();
32
33
 
33
34
  The host element must have an explicit height. Region, floor, and scale controls are enabled by default. Import `@opendfieldmap/sdk/style.css` once in the host application.
34
35
 
35
- Coordinates in `customPoints` are normalized map coordinates, with published pixels divided by `2 ** maxNativeZoom`. Atlos `markTool` uses map `[z, x]` values; `gameXZToOEMPosition()` applies the selected Atlos region transform and returns the normalized `{ x, y }` shape directly usable by a custom point.
36
+ Coordinates in `customPoints` are normalized map coordinates, with published pixels divided by `2 ** maxNativeZoom`. Atlos `markTool` uses map `[z, x]` values; `gameXZToOEMPosition()` applies the selected Atlos region transform and returns the normalized `{ x, z }` shape directly usable by a custom point.
36
37
 
37
38
  For a large point collection, host the same JSON array separately and load it by URL:
38
39
 
@@ -49,6 +50,10 @@ await widget.loadCustomPoints('/data/another-set.json');
49
50
 
50
51
  Host-defined points support only the Atlos `framed` (`32 × 32`, anchor `[16, 32]`) and `no-frame` (`50 × 50`, anchor `[25, 25]`) compositions. Supply the image URL through `icon`; custom point size, color, and label fields are not supported. The map click event exposes the normalized map position and the recovered game `x/z` coordinates.
51
52
 
53
+ Call `widget.setClickPointMode({ mode: 'multiple' | 'single', style, icon })` to create custom markers automatically from map clicks. Multiple mode keeps every click; single mode replaces the previous click-created marker. Pass `null` to disable click creation and use `widget.clearClickPoints()` to remove only click-created markers.
54
+
55
+ All map positions use horizontal `{ x, z }` coordinates. Game positions use `{ x, y, z }`, where `y` is height; a 2D map position only recovers game `x/z`. Set `boundarySource` to `'oem'` for Atlos-drawn boundaries or `'game'` for official game level-grid boundaries.
56
+
52
57
  The package uses named, typed options and is safe to import during SSR. Widget creation must run in a browser. Tiles and map data are selected through a schema v1 release manifest and loaded from the configured static origin.
53
58
 
54
59
  See the repository documentation for the complete API, resource protocol, localized guides, and release workflow.
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  export { createOEMWidget } from './widget';
2
2
  export { parseOEMUrlState } from './state';
3
3
  export { gameToOEMPosition, gameXZToOEMPosition, mapToGameXZPosition, oemToGamePosition, toOEMMapPosition, fromOEMMapPosition, toOEMLeafletMapPosition } from '@opendfieldmap/core';
4
- export type { OEMGamePosition, OEMGameTransform, OEMGameXZPosition, OEMMapPosition, OEMPoint, OEMPosition, OEMRegion } from '@opendfieldmap/core';
5
- export type { OEMCustomPoint, OEMMapClick } from '@opendfieldmap/map';
4
+ export type { OEMBoundarySource, OEMGamePosition, OEMGameTransform, OEMGameXZPosition, OEMMapOffset, OEMMapPosition, OEMPoint, OEMPosition, OEMRegion } from '@opendfieldmap/core';
5
+ export type { OEMClickPointOptions, OEMCustomPoint, OEMMapClick } from '@opendfieldmap/map';
6
6
  export type * from './types';
package/dist/index.js CHANGED
@@ -233,7 +233,7 @@ var createRegionControl = (context) => {
233
233
  regionButton.append(icon);
234
234
  const selectRegion = () => {
235
235
  const target = region.initialView;
236
- apply({ region: region.id, subregion: null, floor: "M", center: { x: target.x, y: target.y }, zoom: target.zoom });
236
+ apply({ region: region.id, subregion: null, floor: "M", center: { x: target.x, z: target.z }, zoom: target.zoom });
237
237
  };
238
238
  regionButton.addEventListener("click", selectRegion);
239
239
  regionButton.addEventListener("keydown", (event) => {
@@ -259,14 +259,14 @@ var createRegionControl = (context) => {
259
259
  subregionButton.addEventListener("click", () => {
260
260
  context.panels.collapse(regionButton);
261
261
  const [[x1, y1], [x2, y2]] = subregion.bounds ?? [
262
- [region.initialView.x, region.initialView.y],
263
- [region.initialView.x, region.initialView.y]
262
+ [region.initialView.x, region.initialView.z],
263
+ [region.initialView.x, region.initialView.z]
264
264
  ];
265
265
  apply({
266
266
  region: region.id,
267
267
  subregion: subregion.id,
268
268
  floor: "M",
269
- center: { x: (x1 + x2) / 2, y: (y1 + y2) / 2 },
269
+ center: { x: (x1 + x2) / 2, z: (y1 + y2) / 2 },
270
270
  zoom: Math.max(region.minZoom, Math.min(region.maxZoom, 1))
271
271
  });
272
272
  });
@@ -456,9 +456,9 @@ var mountControls = (root, visibility, context) => {
456
456
  import { resolveOEMAsset } from "@opendfieldmap/core";
457
457
  var FONT_FAMILIES = /* @__PURE__ */ new Set([
458
458
  "HMSans_EN",
459
- "Novecento Bold",
460
- "Novecento DemiBold",
461
- "Novecento Medium",
459
+ "Novecento Wide Bold",
460
+ "Novecento Wide DemiBold",
461
+ "Novecento Wide Medium",
462
462
  "Novecento Cyrillic DemiBold",
463
463
  "Novecento Cyrillic Medium",
464
464
  "Novecento Vietnamese DemiBold",
@@ -513,17 +513,22 @@ var normalizeMarkerTypes = (value) => {
513
513
  if (!value || !Array.isArray(value)) return [];
514
514
  return [...new Set(value.map((entry) => entry.trim()).filter(Boolean))];
515
515
  };
516
+ var normalizeBoundarySource = (value) => {
517
+ if (value === void 0 || value === "oem") return "oem";
518
+ if (value === "game") return "game";
519
+ throw new Error(`Unknown OEM boundary source: ${value}`);
520
+ };
516
521
  var getPreset = (region, subregion) => {
517
522
  if (!subregion?.bounds) {
518
523
  return {
519
- center: { x: region.initialView.x, y: region.initialView.y },
524
+ center: { x: region.initialView.x, z: region.initialView.z },
520
525
  zoom: region.initialView.zoom
521
526
  };
522
527
  }
523
528
  return {
524
529
  center: {
525
530
  x: (subregion.bounds[0][0] + subregion.bounds[1][0]) / 2,
526
- y: (subregion.bounds[0][1] + subregion.bounds[1][1]) / 2
531
+ z: (subregion.bounds[0][1] + subregion.bounds[1][1]) / 2
527
532
  },
528
533
  zoom: Math.max(region.minZoom, Math.min(region.maxZoom, 1))
529
534
  };
@@ -546,7 +551,7 @@ var normalizeState = (input, manifest) => {
546
551
  throw new Error(`Unknown OEM floor ${floorId} in ${regionId}`);
547
552
  }
548
553
  const requestedCenter = input.center;
549
- if (requestedCenter && (!Number.isFinite(requestedCenter.x) || !Number.isFinite(requestedCenter.y))) {
554
+ if (requestedCenter && (!Number.isFinite(requestedCenter.x) || !Number.isFinite(requestedCenter.z))) {
550
555
  throw new Error("OEM Widget center coordinates must be finite");
551
556
  }
552
557
  const preset = getPreset(region, subregion);
@@ -559,11 +564,12 @@ var normalizeState = (input, manifest) => {
559
564
  markerTypes: normalizeMarkerTypes(input.markerTypes),
560
565
  labels: input.labels ?? true,
561
566
  boundaries: input.boundaries ?? false,
567
+ boundarySource: normalizeBoundarySource(input.boundarySource),
562
568
  markerClustering: input.markerClustering ?? true,
563
569
  zoom: Math.max(region.minZoom, Math.min(region.maxZoom, input.zoom ?? preset.zoom)),
564
570
  center: {
565
571
  x: requestedCenter?.x ?? preset.center.x,
566
- y: requestedCenter?.y ?? preset.center.y
572
+ z: requestedCenter?.z ?? preset.center.z
567
573
  }
568
574
  };
569
575
  };
@@ -575,12 +581,13 @@ var toConfig = (state) => ({
575
581
  markerTypes: state.markerTypes,
576
582
  labels: state.labels,
577
583
  boundaries: state.boundaries,
584
+ boundarySource: state.boundarySource,
578
585
  markerClustering: state.markerClustering,
579
586
  zoom: state.zoom,
580
587
  center: { ...state.center }
581
588
  });
582
589
  var sameMarkers = (left, right) => left === right || left !== "*" && right !== "*" && left.length === right.length && left.every((marker, index) => marker === right[index]);
583
- var sameState = (left, right) => left.regionId === right.regionId && left.subregionId === right.subregionId && left.floorId === right.floorId && left.locale === right.locale && sameMarkers(left.markerTypes, right.markerTypes) && left.labels === right.labels && left.boundaries === right.boundaries && left.markerClustering === right.markerClustering && left.zoom === right.zoom && left.center.x === right.center.x && left.center.y === right.center.y;
590
+ var sameState = (left, right) => left.regionId === right.regionId && left.subregionId === right.subregionId && left.floorId === right.floorId && left.locale === right.locale && sameMarkers(left.markerTypes, right.markerTypes) && left.labels === right.labels && left.boundaries === right.boundaries && left.boundarySource === right.boundarySource && left.markerClustering === right.markerClustering && left.zoom === right.zoom && left.center.x === right.center.x && left.center.z === right.center.z;
584
591
  var hasMarkers = (state) => state.markerTypes === "*" || state.markerTypes.length > 0;
585
592
  var Widget = class {
586
593
  constructor(host, root, core, manifest, options, state) {
@@ -639,7 +646,7 @@ var Widget = class {
639
646
  regionId: view.regionId,
640
647
  floorId: view.floorId ?? "M",
641
648
  locale: this.core.getLocale().resolved,
642
- center: { x: view.x, y: view.y },
649
+ center: { x: view.x, z: view.z },
643
650
  zoom: view.zoom
644
651
  };
645
652
  this.controls.sync(this.state);
@@ -654,6 +661,14 @@ var Widget = class {
654
661
  this.core.setCustomPoints(points);
655
662
  this.customPointsUrl = void 0;
656
663
  }
664
+ setClickPointMode(options) {
665
+ this.assertAlive();
666
+ this.core.setClickPointMode(options);
667
+ }
668
+ clearClickPoints() {
669
+ this.assertAlive();
670
+ this.core.clearClickPoints();
671
+ }
657
672
  async loadCustomPoints(url) {
658
673
  this.assertAlive();
659
674
  await this.core.loadCustomPoints(url);
@@ -717,7 +732,7 @@ var Widget = class {
717
732
  if (sameState(previous, next) && !customPointsChanged) return;
718
733
  const regionChanged = next.regionId !== previous.regionId;
719
734
  const filterChanged = next.subregionId !== previous.subregionId || !sameMarkers(next.markerTypes, previous.markerTypes);
720
- const viewChanged = regionChanged || next.floorId !== previous.floorId || next.zoom !== previous.zoom || next.center.x !== previous.center.x || next.center.y !== previous.center.y;
735
+ const viewChanged = regionChanged || next.floorId !== previous.floorId || next.zoom !== previous.zoom || next.center.x !== previous.center.x || next.center.z !== previous.center.z;
721
736
  const previousMarkers = hasMarkers(previous);
722
737
  const nextMarkers = hasMarkers(next);
723
738
  this.applying = true;
@@ -743,11 +758,12 @@ var Widget = class {
743
758
  if (next.markerClustering !== previous.markerClustering) {
744
759
  this.core.setMarkerClustering(next.markerClustering);
745
760
  }
746
- if (nextMarkers !== previousMarkers || next.labels !== previous.labels || next.boundaries !== previous.boundaries) {
761
+ if (nextMarkers !== previousMarkers || next.labels !== previous.labels || next.boundaries !== previous.boundaries || next.boundarySource !== previous.boundarySource) {
747
762
  await this.core.setFeatures({
748
763
  points: nextMarkers,
749
764
  labels: next.labels,
750
- boundaries: next.boundaries
765
+ boundaries: next.boundaries,
766
+ boundarySource: next.boundarySource
751
767
  });
752
768
  }
753
769
  if (viewChanged) {
@@ -755,7 +771,7 @@ var Widget = class {
755
771
  regionId: next.regionId,
756
772
  floorId: next.floorId,
757
773
  x: next.center.x,
758
- y: next.center.y,
774
+ z: next.center.z,
759
775
  zoom: next.zoom
760
776
  });
761
777
  }
@@ -763,7 +779,7 @@ var Widget = class {
763
779
  this.state = {
764
780
  ...next,
765
781
  locale: this.core.getLocale().resolved,
766
- center: { x: view.x, y: view.y },
782
+ center: { x: view.x, z: view.z },
767
783
  zoom: view.zoom
768
784
  };
769
785
  this.controls.sync(this.state);
@@ -825,13 +841,14 @@ async function createOEMWidget(container, options = {}) {
825
841
  regionId: state.regionId,
826
842
  floorId: state.floorId,
827
843
  x: state.center.x,
828
- y: state.center.y,
844
+ z: state.center.z,
829
845
  zoom: state.zoom
830
846
  },
831
847
  features: {
832
848
  points: hasMarkers(state),
833
849
  labels: state.labels,
834
- boundaries: state.boundaries
850
+ boundaries: state.boundaries,
851
+ boundarySource: state.boundarySource
835
852
  },
836
853
  markerClustering: state.markerClustering,
837
854
  customPoints: options.customPoints,
@@ -876,6 +893,7 @@ var parseList = (value) => {
876
893
  if (value === null) return void 0;
877
894
  return [...new Set(value.split(",").map((entry) => entry.trim()).filter(Boolean))];
878
895
  };
896
+ var parseBoundarySource = (value) => value === "oem" || value === "game" ? value : void 0;
879
897
  var toSearchParams = (source) => {
880
898
  const trimmed = source.trim();
881
899
  if (/^[a-z][a-z\d+.-]*:\/\//i.test(trimmed)) return new URL(trimmed).searchParams;
@@ -885,8 +903,8 @@ var toSearchParams = (source) => {
885
903
  function parseOEMUrlState(source) {
886
904
  const params = typeof source === "string" ? toSearchParams(source) : source;
887
905
  const filter = params.get("f");
888
- const x = parseNumber(params.get("x"));
889
- const y = parseNumber(params.get("y"));
906
+ const centerX = parseNumber(params.get("cx"));
907
+ const centerZ = parseNumber(params.get("cz") ?? params.get("centerZ"));
890
908
  return {
891
909
  region: params.get("r") ?? void 0,
892
910
  subregion: params.get("s"),
@@ -895,9 +913,10 @@ function parseOEMUrlState(source) {
895
913
  markerTypes: filter === "*" ? "*" : filter === null ? void 0 : parseList(filter) ?? false,
896
914
  labels: parseBoolean(params.get("labels") ?? params.get("names")),
897
915
  boundaries: parseBoolean(params.get("boundaries") ?? params.get("boundary")),
916
+ boundarySource: parseBoundarySource(params.get("boundarySource")),
898
917
  markerClustering: parseBoolean(params.get("cluster")),
899
918
  zoom: parseNumber(params.get("z")),
900
- center: x === void 0 || y === void 0 ? void 0 : { x, y }
919
+ center: centerX === void 0 || centerZ === void 0 ? void 0 : { x: centerX, z: centerZ }
901
920
  };
902
921
  }
903
922
 
package/dist/index.js.map CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/widget.ts", "../src/components/scale.ts", "../src/components/types.ts", "../src/components/switches.ts", "../src/assets/Valley_4.svg", "../src/assets/Wuling.svg", "../src/assets/Dijiang.svg", "../src/assets/Weekraid_1.svg", "../src/assets/layer.svg", "../src/icons.ts", "../src/components/index.ts", "../src/fonts.ts", "../src/state.ts", "../src/index.ts"],
4
- "sourcesContent": ["import {\n defaultOEMResources,\n getOEMRegion,\n loadOEMManifest,\n normalizeOEMLocale,\n validateOEMManifest,\n} from '@opendfieldmap/core';\nimport type { OEMManifest, OEMRegion, OEMResources, OEMSubregion } from '@opendfieldmap/core';\nimport { createOEM } from '@opendfieldmap/map';\nimport type { OEM, OEMCustomPoint, OEMMapClick } from '@opendfieldmap/map';\nimport { mountControls } from './components';\nimport type { Control } from './components/types';\nimport { installFonts } from './fonts';\nimport type {\n OEMFloorId,\n OEMLocale,\n OEMRegionId,\n OEMWidget,\n OEMWidgetConfig,\n OEMWidgetEvents,\n OEMWidgetOptions,\n OEMWidgetState,\n} from './types';\n\nconst REGION_ALIASES: Readonly<Record<string, string>> = Object.freeze({\n VL: 'Valley_4',\n WL: 'Wuling',\n DJ: 'Dijiang',\n ES: 'Weekraid_1',\n});\n\nconst mounted = new WeakSet<HTMLElement>();\n\nconst cloneState = (state: OEMWidgetState): OEMWidgetState => ({\n ...state,\n markerTypes: state.markerTypes === '*' ? '*' : [...state.markerTypes],\n center: { ...state.center },\n});\n\nconst cloneConfig = (config: OEMWidgetConfig): OEMWidgetConfig => ({\n ...config,\n markerTypes: Array.isArray(config.markerTypes) ? [...config.markerTypes] : config.markerTypes,\n customPoints: config.customPoints?.map((point) => ({ ...point, position: { ...point.position } })),\n center: config.center ? { ...config.center } : config.center,\n});\n\nconst resolveContainer = (container: string | HTMLElement): HTMLElement => {\n const element = typeof container === 'string' ? document.querySelector<HTMLElement>(container) : container;\n if (!element) throw new Error(`OEM Widget container not found: ${container}`);\n return element;\n};\n\nconst resolveRegionId = (manifest: OEMManifest, value?: string): OEMRegionId => {\n const requested = value ? REGION_ALIASES[value.toUpperCase()] ?? value : manifest.defaultRegionId;\n return getOEMRegion(manifest, requested).id as OEMRegionId;\n};\n\nconst normalizeMarkerTypes = (value: OEMWidgetConfig['markerTypes']): string[] | '*' => {\n if (value === '*') return '*';\n if (!value || !Array.isArray(value)) return [];\n return [...new Set(value.map((entry) => entry.trim()).filter(Boolean))];\n};\n\nconst getPreset = (region: OEMRegion, subregion?: OEMSubregion) => {\n if (!subregion?.bounds) {\n return {\n center: { x: region.initialView.x, y: region.initialView.y },\n zoom: region.initialView.zoom,\n };\n }\n return {\n center: {\n x: (subregion.bounds[0][0] + subregion.bounds[1][0]) / 2,\n y: (subregion.bounds[0][1] + subregion.bounds[1][1]) / 2,\n },\n zoom: Math.max(region.minZoom, Math.min(region.maxZoom, 1)),\n };\n};\n\nconst normalizeState = (input: OEMWidgetConfig, manifest: OEMManifest): OEMWidgetState => {\n let regionId = resolveRegionId(manifest, input.region);\n const subregionId = input.subregion?.trim() || null;\n if (subregionId) {\n const owner = manifest.regions.find((region) => region.subregions.some((subregion) => subregion.id === subregionId));\n if (!owner) throw new Error(`Unknown OEM subregion: ${subregionId}`);\n if (input.region && owner.id !== regionId) {\n throw new Error(`OEM subregion ${subregionId} does not belong to ${regionId}`);\n }\n regionId = owner.id as OEMRegionId;\n }\n\n const region = getOEMRegion(manifest, regionId);\n const subregion = subregionId\n ? region.subregions.find((entry) => entry.id === subregionId)\n : undefined;\n const floorId = (input.floor ?? 'M') as OEMFloorId;\n if (!region.floors.some((floor) => floor.id === floorId)) {\n throw new Error(`Unknown OEM floor ${floorId} in ${regionId}`);\n }\n\n const requestedCenter = input.center;\n if (requestedCenter && (!Number.isFinite(requestedCenter.x) || !Number.isFinite(requestedCenter.y))) {\n throw new Error('OEM Widget center coordinates must be finite');\n }\n const preset = getPreset(region, subregion);\n const requestedLocale = input.locale ?? (typeof navigator === 'undefined' ? manifest.fallbackLocale : navigator.language);\n\n return {\n regionId,\n subregionId,\n floorId,\n locale: normalizeOEMLocale(requestedLocale, Object.keys(manifest.locales), manifest.fallbackLocale) as OEMLocale,\n markerTypes: normalizeMarkerTypes(input.markerTypes),\n labels: input.labels ?? true,\n boundaries: input.boundaries ?? false,\n markerClustering: input.markerClustering ?? true,\n zoom: Math.max(region.minZoom, Math.min(region.maxZoom, input.zoom ?? preset.zoom)),\n center: {\n x: requestedCenter?.x ?? preset.center.x,\n y: requestedCenter?.y ?? preset.center.y,\n },\n };\n};\n\nconst toConfig = (state: OEMWidgetState): OEMWidgetConfig => ({\n region: state.regionId,\n subregion: state.subregionId,\n floor: state.floorId,\n locale: state.locale,\n markerTypes: state.markerTypes,\n labels: state.labels,\n boundaries: state.boundaries,\n markerClustering: state.markerClustering,\n zoom: state.zoom,\n center: { ...state.center },\n});\n\nconst sameMarkers = (left: OEMWidgetState['markerTypes'], right: OEMWidgetState['markerTypes']): boolean =>\n left === right || (left !== '*' && right !== '*' && left.length === right.length &&\n left.every((marker, index) => marker === right[index]));\n\nconst sameState = (left: OEMWidgetState, right: OEMWidgetState): boolean =>\n left.regionId === right.regionId &&\n left.subregionId === right.subregionId &&\n left.floorId === right.floorId &&\n left.locale === right.locale &&\n sameMarkers(left.markerTypes, right.markerTypes) &&\n left.labels === right.labels &&\n left.boundaries === right.boundaries &&\n left.markerClustering === right.markerClustering &&\n left.zoom === right.zoom &&\n left.center.x === right.center.x &&\n left.center.y === right.center.y;\n\nconst hasMarkers = (state: OEMWidgetState): boolean =>\n state.markerTypes === '*' || state.markerTypes.length > 0;\n\nclass Widget implements OEMWidget {\n destroyed = false;\n private applying = false;\n private updates = Promise.resolve();\n private customPointsUrl?: string;\n private controls: Control;\n private unsubscribeView: () => void;\n private unsubscribeClick: () => void;\n private listeners = new Map<keyof OEMWidgetEvents, Set<(payload: never) => void>>();\n\n constructor(\n private host: HTMLElement,\n private root: HTMLElement,\n private core: OEM,\n private manifest: OEMManifest,\n private options: OEMWidgetOptions,\n private state: OEMWidgetState,\n ) {\n this.customPointsUrl = options.customPointsUrl;\n this.controls = mountControls(root, {\n regionSelector: options.showRegionSelector ?? true,\n floorSelector: options.showFloorSelector ?? true,\n scaleBar: options.showScaleBar ?? true,\n }, {\n manifest,\n zoomLocked: options.lockZoom ?? false,\n apply: (update) => {\n void this.setOptions(update).catch((error: unknown) => this.report(error));\n },\n zoomTo: (zoom, zoomOptions) => core.setZoom(zoom, zoomOptions),\n });\n this.controls.sync(state);\n this.unsubscribeView = core.on('viewchange', this.syncView);\n this.unsubscribeClick = core.on('click', this.forwardClick);\n options.signal?.addEventListener('abort', this.destroy, { once: true });\n }\n\n private assertAlive(): void {\n if (this.destroyed) throw new Error('OEM Widget has been destroyed');\n }\n\n private report(error: unknown): void {\n this.options.onError?.(error instanceof Error ? error : new Error(String(error)));\n }\n\n private notify(): void {\n this.options.onStateChange?.(cloneState(this.state));\n }\n\n private emit<Event extends keyof OEMWidgetEvents>(event: Event, payload: OEMWidgetEvents[Event]): void {\n this.listeners.get(event)?.forEach((handler) => handler(payload as never));\n }\n\n private forwardClick = (payload: OEMMapClick): void => {\n if (!this.destroyed) this.emit('click', payload);\n };\n\n private syncView = (): void => {\n if (this.destroyed || this.applying) return;\n const view = this.core.getView();\n this.state = {\n ...this.state,\n regionId: view.regionId as OEMRegionId,\n floorId: (view.floorId ?? 'M') as OEMFloorId,\n locale: this.core.getLocale().resolved as OEMLocale,\n center: { x: view.x, y: view.y },\n zoom: view.zoom,\n };\n this.controls.sync(this.state);\n this.notify();\n };\n\n getState(): OEMWidgetState {\n this.assertAlive();\n return cloneState(this.state);\n }\n\n setCustomPoints(points: readonly OEMCustomPoint[]): void {\n this.assertAlive();\n this.core.setCustomPoints(points);\n this.customPointsUrl = undefined;\n }\n\n async loadCustomPoints(url: string): Promise<void> {\n this.assertAlive();\n await this.core.loadCustomPoints(url);\n this.customPointsUrl = url;\n }\n\n clearCustomPoints(): void {\n this.assertAlive();\n this.core.clearCustomPoints();\n }\n\n getPoint(pointId: string) {\n this.assertAlive();\n return this.core.getPoint(pointId);\n }\n\n loadPoint(pointId: string) {\n this.assertAlive();\n return this.core.loadPoint(pointId);\n }\n\n on<Event extends keyof OEMWidgetEvents>(event: Event, handler: (payload: OEMWidgetEvents[Event]) => void): () => void {\n this.assertAlive();\n const handlers = this.listeners.get(event) ?? new Set();\n handlers.add(handler as (payload: never) => void);\n this.listeners.set(event, handlers);\n return () => { handlers.delete(handler as (payload: never) => void); };\n }\n\n setOptions(update: OEMWidgetConfig): Promise<void> {\n this.assertAlive();\n const snapshot = cloneConfig(update);\n const operation = this.updates.then(() => this.applyOptions(snapshot));\n this.updates = operation.catch(() => undefined);\n return operation;\n }\n\n private async applyOptions(update: OEMWidgetConfig): Promise<void> {\n this.assertAlive();\n const changes = Object.fromEntries(\n Object.entries(update).filter(([, value]) => value !== undefined),\n ) as OEMWidgetConfig;\n const merged: OEMWidgetConfig = { ...toConfig(this.state), ...changes };\n const nextRegionId = resolveRegionId(this.manifest, changes.region ?? this.state.regionId);\n\n if (nextRegionId !== this.state.regionId) {\n const preset = getPreset(getOEMRegion(this.manifest, nextRegionId));\n if (changes.floor === undefined) merged.floor = 'M';\n if (changes.subregion === undefined) merged.subregion = null;\n if (changes.center === undefined) merged.center = preset.center;\n if (changes.zoom === undefined) merged.zoom = preset.zoom;\n }\n\n if (changes.subregion !== undefined && changes.subregion !== this.state.subregionId) {\n const region = getOEMRegion(this.manifest, nextRegionId);\n const subregion = changes.subregion\n ? region.subregions.find((entry) => entry.id === changes.subregion)\n : undefined;\n const preset = getPreset(region, subregion);\n if (changes.center === undefined) merged.center = preset.center;\n if (changes.zoom === undefined) merged.zoom = preset.zoom;\n }\n\n const previous = this.state;\n const next = normalizeState(merged, this.manifest);\n if (changes.customPoints !== undefined && changes.customPointsUrl !== undefined) {\n throw new Error('Pass either customPoints or customPointsUrl, not both');\n }\n const customPointsChanged = changes.customPoints !== undefined || changes.customPointsUrl !== undefined;\n if (sameState(previous, next) && !customPointsChanged) return;\n\n const regionChanged = next.regionId !== previous.regionId;\n const filterChanged = next.subregionId !== previous.subregionId ||\n !sameMarkers(next.markerTypes, previous.markerTypes);\n const viewChanged = regionChanged ||\n next.floorId !== previous.floorId ||\n next.zoom !== previous.zoom ||\n next.center.x !== previous.center.x ||\n next.center.y !== previous.center.y;\n const previousMarkers = hasMarkers(previous);\n const nextMarkers = hasMarkers(next);\n\n this.applying = true;\n this.root.classList.add('loading');\n try {\n if (changes.customPoints !== undefined) {\n this.core.setCustomPoints(changes.customPoints);\n this.customPointsUrl = undefined;\n } else if (changes.customPointsUrl !== undefined) {\n await this.core.loadCustomPoints(changes.customPointsUrl);\n this.customPointsUrl = changes.customPointsUrl;\n }\n if (previousMarkers && !nextMarkers) await this.core.setFeatures({ points: false });\n if (filterChanged) {\n this.core.setPointFilter({\n types: next.markerTypes === '*' ? undefined : next.markerTypes,\n subregions: next.subregionId ? [next.subregionId] : undefined,\n });\n }\n if (regionChanged) await this.core.setRegion(next.regionId);\n if (next.locale !== previous.locale) await this.core.setLocale(next.locale);\n if (next.floorId !== previous.floorId) this.core.setFloor(next.floorId);\n if (next.markerClustering !== previous.markerClustering) {\n this.core.setMarkerClustering(next.markerClustering);\n }\n if (nextMarkers !== previousMarkers ||\n next.labels !== previous.labels ||\n next.boundaries !== previous.boundaries) {\n await this.core.setFeatures({\n points: nextMarkers,\n labels: next.labels,\n boundaries: next.boundaries,\n });\n }\n if (viewChanged) {\n this.core.setView({\n regionId: next.regionId,\n floorId: next.floorId,\n x: next.center.x,\n y: next.center.y,\n zoom: next.zoom,\n });\n }\n const view = this.core.getView();\n this.state = {\n ...next,\n locale: this.core.getLocale().resolved as OEMLocale,\n center: { x: view.x, y: view.y },\n zoom: view.zoom,\n };\n this.controls.sync(this.state);\n } finally {\n this.applying = false;\n this.root.classList.remove('loading');\n }\n this.notify();\n }\n\n resize(): void {\n this.assertAlive();\n this.core.resize();\n }\n\n destroy = (): void => {\n if (this.destroyed) return;\n this.destroyed = true;\n this.unsubscribeView();\n this.unsubscribeClick();\n this.listeners.clear();\n this.controls.destroy?.();\n this.options.signal?.removeEventListener('abort', this.destroy);\n this.core.destroy();\n this.root.remove();\n mounted.delete(this.host);\n };\n}\n\n/** Creates an embeddable Open Endfield Map Widget. */\nexport async function createOEMWidget(\n container: string | HTMLElement,\n options: OEMWidgetOptions = {},\n): Promise<OEMWidget> {\n if (typeof document === 'undefined') throw new Error('createOEMWidget must run in a browser');\n if (options.customPoints !== undefined && options.customPointsUrl !== undefined) {\n throw new Error('Pass either customPoints or customPointsUrl, not both');\n }\n options.signal?.throwIfAborted();\n const host = resolveContainer(container);\n if (mounted.has(host)) throw new Error('This container already hosts an OEM Widget');\n\n const root = document.createElement('div');\n root.className = 'oemWidget loading';\n if (options.className) root.classList.add(...options.className.split(/\\s+/).filter(Boolean));\n root.dataset.theme = options.theme ?? 'light';\n const mapHost = document.createElement('div');\n mapHost.className = 'mapHost';\n root.append(mapHost);\n host.append(root);\n mounted.add(host);\n\n let core: OEM | undefined;\n let widget: Widget | undefined;\n try {\n const resources: OEMResources = options.resources ?? defaultOEMResources;\n const manifest = options.manifest\n ? validateOEMManifest(options.manifest)\n : await loadOEMManifest(resources, options.signal);\n installFonts(root, manifest, resources);\n const state = normalizeState(options, manifest);\n core = await createOEM(mapHost, {\n resources,\n manifest,\n regionId: state.regionId,\n floorId: state.floorId,\n locale: state.locale,\n theme: options.theme,\n view: {\n regionId: state.regionId,\n floorId: state.floorId,\n x: state.center.x,\n y: state.center.y,\n zoom: state.zoom,\n },\n features: {\n points: hasMarkers(state),\n labels: state.labels,\n boundaries: state.boundaries,\n },\n markerClustering: state.markerClustering,\n customPoints: options.customPoints,\n customPointsUrl: options.customPointsUrl,\n pointFilter: {\n types: state.markerTypes === '*' ? undefined : state.markerTypes,\n subregions: state.subregionId ? [state.subregionId] : undefined,\n },\n lockDrag: options.lockDrag ?? false,\n lockZoom: options.lockZoom ?? false,\n signal: options.signal,\n onError: options.onError,\n });\n widget = new Widget(host, root, core, manifest, options, state);\n root.classList.remove('loading');\n options.onReady?.(widget);\n return widget;\n } catch (error) {\n if (widget) widget.destroy();\n else {\n core?.destroy();\n root.remove();\n mounted.delete(host);\n }\n throw error;\n }\n}\n", "import { getOEMRegion } from '@opendfieldmap/core';\nimport type { OEMWidgetState } from '../types';\nimport { createButton, getMessages, setLabel } from './types';\nimport type { Control, ControlContext } from './types';\n\nconst ZOOM_STEP = 0.5;\nconst clamp = (value: number, minimum: number, maximum: number): number =>\n Math.max(minimum, Math.min(maximum, value));\n\n/** Creates the Atlos desktop click scale and compact touch-drag scale. */\nexport const createScaleControl = (context: ControlContext): Control & { element: HTMLElement } => {\n const { manifest, zoomLocked } = context;\n const element = document.createElement('div');\n element.className = 'scaleControl';\n element.classList.toggle('locked', zoomLocked);\n const decorationTop = document.createElement('div');\n decorationTop.className = 'scaleDecoration scaleDecorationTop';\n const decorationBottom = document.createElement('div');\n decorationBottom.className = 'scaleDecoration scaleDecorationBottom';\n const zoomInFrame = document.createElement('div');\n zoomInFrame.className = 'scaleFrame zoomInFrame';\n const zoomIn = createButton('zoomButton zoomIn');\n zoomIn.textContent = '+';\n zoomInFrame.append(zoomIn);\n const track = document.createElement('div');\n track.className = 'scaleTrack';\n const fill = document.createElement('div');\n fill.className = 'scaleFill';\n track.append(fill);\n const zoomOutFrame = document.createElement('div');\n zoomOutFrame.className = 'scaleFrame zoomOutFrame';\n const zoomOut = createButton('zoomButton zoomOut');\n zoomOut.textContent = '-';\n zoomOutFrame.append(zoomOut);\n element.append(decorationTop, zoomInFrame, track, zoomOutFrame, decorationBottom);\n\n let currentState: OEMWidgetState;\n let targetZoom: number | null = null;\n let scaleFrame: number | null = null;\n let zoomFrame: number | null = null;\n let dragPointerId: number | null = null;\n let dragStartY: number | null = null;\n let dragStartZoom: number | null = null;\n let currentLocale = '';\n\n const isCompact = () => (element.closest('.oemWidget')?.clientWidth ?? Number.POSITIVE_INFINITY) < 480;\n const scaleFor = (zoom: number, minimum: number, maximum: number) =>\n maximum === minimum ? 0 : clamp((zoom - minimum) / (maximum - minimum), 0, 1);\n const updateScale = (zoom: number, minimum: number, maximum: number) => {\n if (scaleFrame !== null) cancelAnimationFrame(scaleFrame);\n scaleFrame = requestAnimationFrame(() => {\n track.style.setProperty('--scale', String(scaleFor(zoom, minimum, maximum)));\n scaleFrame = null;\n });\n };\n const applyZoom = (zoom: number, animate: boolean) => {\n const region = getOEMRegion(manifest, currentState.regionId);\n const nextZoom = clamp(zoom, region.minZoom, region.maxZoom);\n if (targetZoom === nextZoom) return;\n targetZoom = nextZoom;\n updateScale(nextZoom, region.minZoom, region.maxZoom);\n context.zoomTo(nextZoom, { animate });\n };\n const scheduleDragZoom = (zoom: number) => {\n targetZoom = zoom;\n if (zoomFrame !== null) return;\n zoomFrame = requestAnimationFrame(() => {\n zoomFrame = null;\n if (targetZoom !== null) context.zoomTo(targetZoom, { animate: false });\n });\n };\n\n zoomIn.addEventListener('click', () => {\n if (!zoomLocked) applyZoom((targetZoom ?? currentState.zoom) + ZOOM_STEP, true);\n });\n zoomOut.addEventListener('click', () => {\n if (!zoomLocked) applyZoom((targetZoom ?? currentState.zoom) - ZOOM_STEP, true);\n });\n track.addEventListener('click', (event) => {\n if (zoomLocked || isCompact()) return;\n const region = getOEMRegion(manifest, currentState.regionId);\n const bounds = track.getBoundingClientRect();\n const ratio = 1 - (event.clientY - bounds.top) / bounds.height;\n applyZoom(region.minZoom + clamp(ratio, 0, 1) * (region.maxZoom - region.minZoom), true);\n });\n track.addEventListener('pointerdown', (event) => {\n if (zoomLocked || !isCompact()) return;\n event.preventDefault();\n event.stopPropagation();\n track.setPointerCapture(event.pointerId);\n dragPointerId = event.pointerId;\n dragStartY = event.clientY;\n dragStartZoom = targetZoom ?? currentState.zoom;\n element.classList.add('dragging');\n });\n track.addEventListener('pointermove', (event) => {\n if (dragPointerId !== event.pointerId || dragStartY === null || dragStartZoom === null) return;\n event.preventDefault();\n const region = getOEMRegion(manifest, currentState.regionId);\n const delta = ((dragStartY - event.clientY) / Math.max(1, track.getBoundingClientRect().height)) *\n (region.maxZoom - region.minZoom);\n const nextZoom = clamp(dragStartZoom + delta, region.minZoom, region.maxZoom);\n updateScale(nextZoom, region.minZoom, region.maxZoom);\n scheduleDragZoom(nextZoom);\n });\n const finishDrag = (event: PointerEvent) => {\n if (dragPointerId !== event.pointerId) return;\n if (track.hasPointerCapture(event.pointerId)) track.releasePointerCapture(event.pointerId);\n dragPointerId = null;\n dragStartY = null;\n dragStartZoom = null;\n element.classList.remove('dragging');\n };\n track.addEventListener('pointerup', finishDrag);\n track.addEventListener('pointercancel', finishDrag);\n track.addEventListener('lostpointercapture', finishDrag);\n\n return {\n element,\n sync(state: OEMWidgetState) {\n currentState = state;\n targetZoom = state.zoom;\n const region = getOEMRegion(manifest, state.regionId);\n updateScale(state.zoom, region.minZoom, region.maxZoom);\n if (currentLocale !== state.locale) {\n currentLocale = state.locale;\n const messages = getMessages(manifest, state.locale);\n setLabel(zoomIn, messages.zoomIn);\n setLabel(zoomOut, messages.zoomOut);\n }\n zoomIn.disabled = zoomLocked || state.zoom >= region.maxZoom;\n zoomOut.disabled = zoomLocked || state.zoom <= region.minZoom;\n },\n destroy() {\n if (scaleFrame !== null) cancelAnimationFrame(scaleFrame);\n if (zoomFrame !== null) cancelAnimationFrame(zoomFrame);\n element.classList.remove('dragging');\n },\n };\n};\n", "import type { OEMControlMessages, OEMManifest } from '@opendfieldmap/core';\nimport type { OEMWidgetConfig, OEMWidgetState } from '../types';\n\n/** Lifecycle contract shared by built-in controls. */\nexport interface Control {\n sync(state: OEMWidgetState): void;\n destroy?(): void;\n}\n\n/** Coordinates the one persistent flyout allowed across all switch controls. */\nexport interface Panels {\n expand(owner: HTMLElement): void;\n collapse(owner: HTMLElement): void;\n collapseAll(): void;\n}\n\n/** Dependencies supplied by the Widget coordinator to built-in controls. */\nexport interface ControlContext {\n manifest: OEMManifest;\n zoomLocked: boolean;\n apply(update: OEMWidgetConfig): void;\n zoomTo(zoom: number, options: { animate: boolean }): void;\n panels: Panels;\n}\n\n/** Creates a reset, keyboard-accessible button for a control component. */\nexport const createButton = (className: string): HTMLButtonElement => {\n const element = document.createElement('button');\n element.type = 'button';\n element.className = className;\n return element;\n};\n\n/** Applies a localized accessible name to a control without embedding UI copy. */\nexport const setLabel = (\n element: HTMLElement,\n label: string,\n): void => {\n element.title = label;\n element.setAttribute('aria-label', label);\n};\n\n/** Resolves a control message bundle through the manifest locale fallback. */\nexport const getMessages = (\n manifest: OEMManifest,\n locale: string,\n): OEMControlMessages => {\n const messages =\n manifest.controls[locale] ?? manifest.controls[manifest.fallbackLocale];\n if (!messages) throw new Error('Missing OEM control messages');\n return messages;\n};\n", "import { getOEMRegion } from '@opendfieldmap/core';\nimport type { OEMRegion, OEMSubregion } from '@opendfieldmap/core';\nimport { LAYER_ICON, REGION_ICONS } from '../icons';\nimport type { OEMFloorId, OEMRegionSelector, OEMWidgetState } from '../types';\nimport { createButton, getMessages, setLabel } from './types';\nimport type { Control, ControlContext } from './types';\n\nconst FLOOR_ORDER = ['L4', 'L3', 'L2', 'L1', 'M', 'B1', 'B2', 'B3', 'B4'];\n\n/** Creates the nested, keyboard-operable action shape used by Atlos switch items. */\nconst createSwitchAction = (className: string): HTMLDivElement => {\n const element = document.createElement('div');\n element.className = className;\n element.tabIndex = 0;\n element.setAttribute('role', 'button');\n return element;\n};\n\n/** Keeps touch and keyboard flyouts exclusive without affecting pointer hover. */\nconst bindPersistentPanel = (owner: HTMLElement, context: ControlContext): void => {\n owner.addEventListener('pointerenter', (event) => {\n if (event.pointerType === 'mouse') context.panels.collapseAll();\n });\n owner.addEventListener('pointerdown', (event) => {\n if (event.pointerType === 'touch' || event.pointerType === 'pen') context.panels.expand(owner);\n });\n owner.addEventListener('focusin', () => {\n if (owner.matches(':focus-visible') || owner.querySelector(':focus-visible')) context.panels.expand(owner);\n });\n owner.addEventListener('focusout', (event) => {\n if (!(event.relatedTarget instanceof Node) || !owner.contains(event.relatedTarget)) context.panels.collapse(owner);\n });\n};\n\n/** Moves an Atlos indicator by transform so transitions stay on the compositor. */\nconst positionIndicator = (indicator: HTMLElement, target: HTMLElement): void => {\n indicator.style.transform = `translateY(calc(${target.offsetTop + target.offsetHeight / 2}px - 50%))`;\n};\n\n/** Creates the RGN control and its hover/focus subregion rail. */\nexport const createRegionControl = (context: ControlContext): Control & { element: HTMLElement } => {\n const { manifest, apply } = context;\n const element = document.createElement('div');\n element.className = 'switch regionSwitch';\n const label = document.createElement('div');\n label.className = 'switchLabel regionLabel';\n label.setAttribute('aria-hidden', 'true');\n const indicator = document.createElement('div');\n indicator.className = 'switchIndicator';\n element.append(label, indicator);\n\n const controls = new Map<string, {\n region: OEMRegion;\n button: HTMLDivElement;\n subregions: Map<string, { data: OEMSubregion; button: HTMLButtonElement }>;\n subregionIndicator?: HTMLDivElement;\n }>();\n\n for (const region of manifest.regions) {\n const regionButton = createSwitchAction('switchItem regionEntry');\n regionButton.dataset.region = region.id;\n if (region.subregions.length > 1) bindPersistentPanel(regionButton, context);\n const icon = document.createElement('span');\n icon.className = 'switchIcon';\n const markup = REGION_ICONS[region.id];\n if (!markup) throw new Error(`Missing Atlos region icon: ${region.id}`);\n icon.innerHTML = markup;\n regionButton.append(icon);\n const selectRegion = () => {\n const target = region.initialView;\n apply({ region: region.id as OEMRegionSelector, subregion: null, floor: 'M', center: { x: target.x, y: target.y }, zoom: target.zoom });\n };\n regionButton.addEventListener('click', selectRegion);\n regionButton.addEventListener('keydown', (event) => {\n if (event.target !== regionButton) return;\n if (event.key !== 'Enter' && event.key !== ' ') return;\n event.preventDefault();\n selectRegion();\n });\n const subregionControls = new Map<string, { data: OEMSubregion; button: HTMLButtonElement }>();\n let subregionIndicator: HTMLDivElement | undefined;\n if (region.subregions.length > 1) {\n const panel = document.createElement('div');\n panel.className = 'subregionPanel';\n panel.addEventListener('click', (event) => event.stopPropagation());\n const list = document.createElement('div');\n list.className = 'subregionList';\n subregionIndicator = document.createElement('div');\n subregionIndicator.className = 'switchIndicator';\n list.append(subregionIndicator);\n for (const subregion of region.subregions) {\n const subregionButton = createButton('selectionItem subregionItem');\n subregionButton.dataset.subregion = subregion.id;\n subregionButton.addEventListener('click', () => {\n context.panels.collapse(regionButton);\n const [[x1, y1], [x2, y2]] = subregion.bounds ?? [\n [region.initialView.x, region.initialView.y],\n [region.initialView.x, region.initialView.y],\n ];\n apply({\n region: region.id as OEMRegionSelector,\n subregion: subregion.id,\n floor: 'M',\n center: { x: (x1 + x2) / 2, y: (y1 + y2) / 2 },\n zoom: Math.max(region.minZoom, Math.min(region.maxZoom, 1)),\n });\n });\n subregionControls.set(subregion.id, { data: subregion, button: subregionButton });\n list.append(subregionButton);\n }\n panel.append(list);\n regionButton.append(panel);\n }\n controls.set(region.id, { region, button: regionButton, subregions: subregionControls, subregionIndicator });\n element.append(regionButton);\n }\n\n let stateKey = '';\n return {\n element,\n sync(state: OEMWidgetState) {\n const nextKey = `${state.locale}\\0${state.regionId}\\0${state.subregionId ?? ''}`;\n if (nextKey !== stateKey) {\n stateKey = nextKey;\n for (const [regionId, control] of controls) {\n const regionName = control.region.locales[state.locale] ?? control.region.locales[manifest.fallbackLocale] ?? control.region.name;\n control.button.classList.toggle('selected', regionId === state.regionId);\n setLabel(control.button, regionName);\n for (const [subregionId, subregion] of control.subregions) {\n const localized = subregion.data.locales?.[state.locale] ?? subregion.data.locales?.[manifest.fallbackLocale];\n subregion.button.textContent = localized?.short ?? subregion.data.key;\n setLabel(subregion.button, localized?.name ?? subregion.data.key);\n subregion.button.classList.toggle('selected', subregionId === state.subregionId);\n }\n }\n }\n for (const control of controls.values()) {\n const selectedSubregion = state.subregionId ? control.subregions.get(state.subregionId) : undefined;\n if (control.subregionIndicator) {\n control.subregionIndicator.classList.toggle('hidden', !selectedSubregion);\n if (selectedSubregion) positionIndicator(control.subregionIndicator, selectedSubregion.button);\n }\n }\n const selectedControl = controls.get(state.regionId);\n if (selectedControl) positionIndicator(indicator, selectedControl.button);\n },\n };\n};\n\n/** Creates the Atlos LYR control and its floor selection rail. */\nexport const createLayerControl = (context: ControlContext): Control & { element: HTMLElement } => {\n const { manifest, apply } = context;\n const element = document.createElement('div');\n element.className = 'switch layerSwitch';\n const label = document.createElement('div');\n label.className = 'switchLabel layerLabel';\n label.setAttribute('aria-hidden', 'true');\n const mainButton = createSwitchAction('switchItem');\n bindPersistentPanel(mainButton, context);\n const icon = document.createElement('span');\n icon.className = 'switchIcon';\n icon.innerHTML = LAYER_ICON;\n const panel = document.createElement('div');\n panel.className = 'floorPanel';\n panel.addEventListener('click', (event) => event.stopPropagation());\n const list = document.createElement('div');\n list.className = 'floorList';\n panel.append(list);\n mainButton.append(icon, panel);\n element.append(label, mainButton);\n mainButton.addEventListener('keydown', (event) => {\n if (event.target !== mainButton || (event.key !== 'Enter' && event.key !== ' ')) return;\n event.preventDefault();\n mainButton.click();\n });\n const indicator = document.createElement('div');\n indicator.className = 'switchIndicator';\n const floorButtons = new Map<string, HTMLButtonElement>();\n let currentRegion = '';\n let currentLocale = '';\n let currentFloor = 'M';\n mainButton.addEventListener('click', () => {\n if (currentFloor !== 'M') apply({ floor: 'M' });\n });\n\n return {\n element,\n sync(state: OEMWidgetState) {\n const region = getOEMRegion(manifest, state.regionId);\n if (currentRegion !== region.id) {\n currentRegion = region.id;\n floorButtons.clear();\n list.replaceChildren(indicator);\n const floors = [...region.floors].sort((left, right) => FLOOR_ORDER.indexOf(left.id) - FLOOR_ORDER.indexOf(right.id));\n element.hidden = floors.length <= 1;\n for (const floor of floors) {\n const button = createButton('selectionItem floorItem');\n button.textContent = floor.id;\n button.addEventListener('click', () => {\n context.panels.collapse(mainButton);\n apply({ floor: floor.id as OEMFloorId });\n });\n floorButtons.set(floor.id, button);\n list.append(button);\n }\n currentLocale = '';\n }\n if (currentLocale !== state.locale) {\n currentLocale = state.locale;\n const messages = getMessages(manifest, state.locale);\n setLabel(mainButton, messages.layerSelect);\n for (const [floorId, button] of floorButtons) setLabel(button, `${messages.layerSelect}: ${floorId}`);\n }\n if (currentFloor !== state.floorId) floorButtons.get(currentFloor)?.classList.remove('selected');\n currentFloor = state.floorId;\n mainButton.classList.toggle('selected', currentFloor !== 'M');\n const selectedButton = floorButtons.get(currentFloor);\n selectedButton?.classList.add('selected');\n if (selectedButton) positionIndicator(indicator, selectedButton);\n },\n };\n};\n", "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 425.67 170.68\">\n <g>\n <path class=\"cls-1\" d=\"M15.21,170.68h410.46s-43.67-106.46-205.23-106.45c-160.59,0-205.23,106.45-205.23,106.45Z\"/>\n <path class=\"cls-1\" d=\"M0,63.31h244.09S218.12,0,122.04,0C26.54,0,0,63.31,0,63.31Z\"/>\n </g>\n</svg>", "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 374.53 309.73\">\n <g>\n <rect x=\"80.63\" y=\"20.44\" width=\"58.29\" height=\"117.86\" rx=\"1\" ry=\"1\"/>\n <path d=\"M237.6,223.35c-.53-.03-.94-.47-.94-.99v-89.26c0-.55-.45-1-1-1h-56.3c-.55,0-1,.45-1,1v87.86c0,.55-.44.99-.99.99-12.89.14-25.44.56-37.51,1.23-.53.03-.94.47-.94,1v45.23c0,.55-.45,1-1,1h-56.3c-.55,0-1-.45-1-1v-39.11c0-.61-.55-1.08-1.16-.99C31.4,236.85,0,249.69,0,265.81c0,27.25,83.84,43.92,187.26,43.92s187.26-16.67,187.26-43.92c0-21.91-57.95-37.74-136.93-42.46Z\"/>\n <path d=\"M81.77,228.97c17.21-2.61,36.48-4.55,57.16-5.73v-70.69h-58.29v75.43c0,.61.53,1.07,1.14.98Z\"/>\n <rect x=\"178.37\" width=\"58.29\" height=\"117.86\" rx=\"1\" ry=\"1\"/>\n <path d=\"M249.61,156.62l57.93-49.76c.22-.19.35-.47.35-.76v-51.73c0-.85-1-1.31-1.64-.76l-57.93,49.76c-.22.19-.35.47-.35.76v51.73c0,.85,1,1.31,1.64.76Z\"/>\n </g>\n</svg>", "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 320.87 332.32\">\n <path d=\"M306.45,266.64L241.82,0h-32.6l39.82,266.64h-26.81l-6.22-26.53h8.95v-47.7h-20.14L159.7,0l-45.13,192.41h-20.14v47.7h8.95l-6.22,26.53h-26.34L110.64,0h-32.6L13.4,266.64H0v65.68h320.87v-65.68h-14.42ZM70.81,312.22v-30.76h22.87l-7.21,30.76h-15.65ZM248.58,312.22h-15.65l-7.21-30.76h22.87v30.76Z\"/>\n</svg>", "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 148.547 130.941\">\n <polygon points=\"28.102 0 6.153 0 19.116 21.175 41.065 21.175 28.102 0\"/>\n <polygon points=\"19.116 21.175 0 21.175 26.446 65.471 0 109.766 19.116 109.766 45.562 65.471 19.116 21.175\"/>\n <polygon points=\"142.394 0 120.444 0 107.481 21.175 129.431 21.175 142.394 0\"/>\n <polygon points=\"6.153 130.941 28.102 130.941 41.065 109.766 19.116 109.766 6.153 130.941\"/>\n <path d=\"M109.749,94.194l-16.583-28.723,16.583-28.723h-11.259l8.991-15.573H41.065l8.991,15.573h-11.259l16.583,28.723-16.583,28.723h11.259l-8.991,15.573h66.416l-8.991-15.573h11.259ZM87.106,47.921l-10.132,17.549,10.132,17.549h-7.029l7.029,12.174h-25.665l7.029-12.174h-7.029l10.132-17.549-10.132-17.549h7.029l-7.029-12.174h25.665l-7.029,12.174h7.029Z\"/>\n <polygon points=\"120.444 130.941 142.394 130.941 129.431 109.766 107.481 109.766 120.444 130.941\"/>\n <polygon points=\"122.1 65.471 148.547 21.175 129.431 21.175 102.985 65.471 129.431 109.766 148.547 109.766 122.1 65.471\"/>\n</svg>", "<svg width=\"40\" height=\"37\" viewBox=\"0 0 40 37\" xmlns=\"http://www.w3.org/2000/svg\">\n<path d=\"M20 0L39.2453 10.477L20 20.954L0.7547 10.477L20 0Z\"/>\n<path d=\"M20.9333 24.9496L20 25.4576L19.0667 24.9496L10.6011 20.3409L0 26.1121L20 37L40 26.1121L29.3989 20.3409L20.9333 24.9496Z\"/>\n</svg>\n", "import Valley4 from './assets/Valley_4.svg';\nimport Wuling from './assets/Wuling.svg';\nimport Dijiang from './assets/Dijiang.svg';\nimport Weekraid1 from './assets/Weekraid_1.svg';\nimport Layer from './assets/layer.svg';\n\nconst clean = (svg: string): string => svg.replace(/<\\?xml[^>]*>\\s*/, '');\n\nexport const REGION_ICONS: Readonly<Record<string, string>> = Object.freeze({\n Valley_4: clean(Valley4),\n Wuling: clean(Wuling),\n Dijiang: clean(Dijiang),\n Weekraid_1: clean(Weekraid1),\n});\n\nexport const LAYER_ICON = clean(Layer);\n", "import type { OEMWidgetState } from '../types';\nimport { createScaleControl } from './scale';\nimport { createLayerControl, createRegionControl } from './switches';\nimport type { Control, ControlContext, Panels } from './types';\n\nexport const mountControls = (\n root: HTMLElement,\n visibility: { regionSelector: boolean; floorSelector: boolean; scaleBar: boolean },\n context: Omit<ControlContext, 'panels'>,\n): Control => {\n const hasSwitches = visibility.regionSelector || visibility.floorSelector;\n if (!hasSwitches && !visibility.scaleBar) return { sync: () => {} };\n\n const overlay = document.createElement('div');\n overlay.className = 'controlOverlay';\n root.append(overlay);\n const components: Control[] = [];\n let expandedPanel: HTMLElement | null = null;\n const panels: Panels = {\n expand(owner) {\n if (expandedPanel === owner) return;\n expandedPanel?.classList.remove('expanded');\n expandedPanel = owner;\n expandedPanel.classList.add('expanded');\n },\n collapse(owner) {\n owner.classList.remove('expanded');\n if (expandedPanel === owner) expandedPanel = null;\n },\n collapseAll() {\n expandedPanel?.classList.remove('expanded');\n expandedPanel = null;\n },\n };\n const controlContext: ControlContext = { ...context, panels };\n let currentState: OEMWidgetState | null = null;\n const handleOutsidePointer = (event: PointerEvent) => {\n if (expandedPanel && event.target instanceof Node && !expandedPanel.contains(event.target)) panels.collapseAll();\n };\n if (hasSwitches) document.addEventListener('pointerdown', handleOutsidePointer, true);\n const observer = !hasSwitches || typeof ResizeObserver === 'undefined' ? null : new ResizeObserver(() => {\n if (currentState) for (const component of components) component.sync(currentState);\n });\n observer?.observe(root);\n\n if (hasSwitches) {\n const switchArea = document.createElement('div');\n switchArea.className = 'switchArea';\n if (visibility.regionSelector) {\n const region = createRegionControl(controlContext);\n components.push(region);\n switchArea.append(region.element);\n }\n if (visibility.floorSelector) {\n const layer = createLayerControl(controlContext);\n components.push(layer);\n switchArea.append(layer.element);\n }\n overlay.append(switchArea);\n }\n\n if (visibility.scaleBar) {\n const scale = createScaleControl(controlContext);\n components.push(scale);\n overlay.append(scale.element);\n }\n\n return {\n sync(state: OEMWidgetState) {\n currentState = state;\n for (const component of components) component.sync(state);\n },\n destroy() {\n if (hasSwitches) document.removeEventListener('pointerdown', handleOutsidePointer, true);\n observer?.disconnect();\n panels.collapseAll();\n for (const component of components) component.destroy?.();\n },\n };\n};\n", "import { resolveOEMAsset } from '@opendfieldmap/core';\nimport type { OEMManifest, OEMResources } from '@opendfieldmap/core';\n\nconst FONT_FAMILIES = new Set([\n 'HMSans_EN',\n 'Novecento Bold',\n 'Novecento DemiBold',\n 'Novecento Medium',\n 'Novecento Cyrillic DemiBold',\n 'Novecento Cyrillic Medium',\n 'Novecento Vietnamese DemiBold',\n 'Novecento Vietnamese Medium',\n]);\n\nexport const installFonts = (root: HTMLElement, manifest: OEMManifest, resources: OEMResources): void => {\n if (!manifest.fonts?.length) return;\n const rules = manifest.fonts.map((font) => {\n if (!FONT_FAMILIES.has(font.family) || !Number.isFinite(font.weight) ||\n (font.weightRange && (!Number.isFinite(font.weightRange[0]) || !Number.isFinite(font.weightRange[1]) ||\n font.weightRange[0] > font.weightRange[1]))) {\n throw new Error(`Unsupported OEM font: ${font.family}`);\n }\n const url = resolveOEMAsset(resources.baseUrl, font.path);\n const weight = font.weightRange ? `${font.weightRange[0]} ${font.weightRange[1]}` : String(font.weight);\n return `@font-face{font-family:${JSON.stringify(font.family)};src:url(${JSON.stringify(url)}) format(\"woff2\");font-style:${font.style};font-weight:${weight};font-display:swap;}`;\n });\n const style = document.createElement('style');\n style.dataset.oemFonts = manifest.releaseId;\n style.textContent = rules.join('');\n root.append(style);\n};\n", "import type { OEMFloorId, OEMLocale, OEMRegionSelector, OEMWidgetConfig } from './types';\n\nconst parseBoolean = (value: string | null): boolean | undefined => {\n if (value === null) return undefined;\n if (['1', 'true', 'on', 'yes'].includes(value.toLowerCase())) return true;\n if (['0', 'false', 'off', 'no'].includes(value.toLowerCase())) return false;\n return undefined;\n};\n\nconst parseNumber = (value: string | null): number | undefined => {\n if (value === null || value.trim() === '') return undefined;\n const number = Number(value);\n return Number.isFinite(number) ? number : undefined;\n};\n\nconst parseList = (value: string | null): string[] | undefined => {\n if (value === null) return undefined;\n return [...new Set(value.split(',').map((entry) => entry.trim()).filter(Boolean))];\n};\n\nconst toSearchParams = (source: string): URLSearchParams => {\n const trimmed = source.trim();\n if (/^[a-z][a-z\\d+.-]*:\\/\\//i.test(trimmed)) return new URL(trimmed).searchParams;\n const query = trimmed.includes('?') ? trimmed.slice(trimmed.indexOf('?') + 1) : trimmed;\n return new URLSearchParams(query.replace(/^\\?/, ''));\n};\n\n/**\n * Adapts legacy OEM URL-state keys to the typed Widget configuration.\n *\n * This helper is optional; createOEMWidget accepts normal named properties.\n */\nexport function parseOEMUrlState(source: string | URLSearchParams): OEMWidgetConfig {\n const params = typeof source === 'string' ? toSearchParams(source) : source;\n const filter = params.get('f');\n const x = parseNumber(params.get('x'));\n const y = parseNumber(params.get('y'));\n return {\n region: (params.get('r') ?? undefined) as OEMRegionSelector | undefined,\n subregion: params.get('s'),\n floor: (params.get('layer') ?? undefined) as OEMFloorId | undefined,\n locale: (params.get('l') ?? undefined) as OEMLocale | undefined,\n markerTypes: filter === '*' ? '*' : filter === null ? undefined : parseList(filter) ?? false,\n labels: parseBoolean(params.get('labels') ?? params.get('names')),\n boundaries: parseBoolean(params.get('boundaries') ?? params.get('boundary')),\n markerClustering: parseBoolean(params.get('cluster')),\n zoom: parseNumber(params.get('z')),\n center: x === undefined || y === undefined ? undefined : { x, y },\n };\n}\n", "export { createOEMWidget } from './widget';\nexport { parseOEMUrlState } from './state';\nexport { gameToOEMPosition, gameXZToOEMPosition, mapToGameXZPosition, oemToGamePosition, toOEMMapPosition, fromOEMMapPosition, toOEMLeafletMapPosition } from '@opendfieldmap/core';\nexport type { OEMGamePosition, OEMGameTransform, OEMGameXZPosition, OEMMapPosition, OEMPoint, OEMPosition, OEMRegion } from '@opendfieldmap/core';\nexport type { OEMCustomPoint, OEMMapClick } from '@opendfieldmap/map';\nexport type * from './types';\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import {\n defaultOEMResources,\n getOEMRegion,\n loadOEMManifest,\n normalizeOEMLocale,\n validateOEMManifest,\n} from '@opendfieldmap/core';\nimport type { OEMManifest, OEMRegion, OEMResources, OEMSubregion } from '@opendfieldmap/core';\nimport { createOEM } from '@opendfieldmap/map';\nimport type { OEM, OEMClickPointOptions, OEMCustomPoint, OEMMapClick } from '@opendfieldmap/map';\nimport { mountControls } from './components';\nimport type { Control } from './components/types';\nimport { installFonts } from './fonts';\nimport type {\n OEMFloorId,\n OEMLocale,\n OEMRegionId,\n OEMWidget,\n OEMWidgetConfig,\n OEMWidgetEvents,\n OEMWidgetOptions,\n OEMWidgetState,\n} from './types';\n\nconst REGION_ALIASES: Readonly<Record<string, string>> = Object.freeze({\n VL: 'Valley_4',\n WL: 'Wuling',\n DJ: 'Dijiang',\n ES: 'Weekraid_1',\n});\n\nconst mounted = new WeakSet<HTMLElement>();\n\nconst cloneState = (state: OEMWidgetState): OEMWidgetState => ({\n ...state,\n markerTypes: state.markerTypes === '*' ? '*' : [...state.markerTypes],\n center: { ...state.center },\n});\n\nconst cloneConfig = (config: OEMWidgetConfig): OEMWidgetConfig => ({\n ...config,\n markerTypes: Array.isArray(config.markerTypes) ? [...config.markerTypes] : config.markerTypes,\n customPoints: config.customPoints?.map((point) => ({ ...point, position: { ...point.position } })),\n center: config.center ? { ...config.center } : config.center,\n});\n\nconst resolveContainer = (container: string | HTMLElement): HTMLElement => {\n const element = typeof container === 'string' ? document.querySelector<HTMLElement>(container) : container;\n if (!element) throw new Error(`OEM Widget container not found: ${container}`);\n return element;\n};\n\nconst resolveRegionId = (manifest: OEMManifest, value?: string): OEMRegionId => {\n const requested = value ? REGION_ALIASES[value.toUpperCase()] ?? value : manifest.defaultRegionId;\n return getOEMRegion(manifest, requested).id as OEMRegionId;\n};\n\nconst normalizeMarkerTypes = (value: OEMWidgetConfig['markerTypes']): string[] | '*' => {\n if (value === '*') return '*';\n if (!value || !Array.isArray(value)) return [];\n return [...new Set(value.map((entry) => entry.trim()).filter(Boolean))];\n};\n\nconst normalizeBoundarySource = (value: OEMWidgetConfig['boundarySource']): OEMWidgetState['boundarySource'] => {\n if (value === undefined || value === 'oem') return 'oem';\n if (value === 'game') return 'game';\n throw new Error(`Unknown OEM boundary source: ${value}`);\n};\n\nconst getPreset = (region: OEMRegion, subregion?: OEMSubregion) => {\n if (!subregion?.bounds) {\n return {\n center: { x: region.initialView.x, z: region.initialView.z },\n zoom: region.initialView.zoom,\n };\n }\n return {\n center: {\n x: (subregion.bounds[0][0] + subregion.bounds[1][0]) / 2,\n z: (subregion.bounds[0][1] + subregion.bounds[1][1]) / 2,\n },\n zoom: Math.max(region.minZoom, Math.min(region.maxZoom, 1)),\n };\n};\n\nconst normalizeState = (input: OEMWidgetConfig, manifest: OEMManifest): OEMWidgetState => {\n let regionId = resolveRegionId(manifest, input.region);\n const subregionId = input.subregion?.trim() || null;\n if (subregionId) {\n const owner = manifest.regions.find((region) => region.subregions.some((subregion) => subregion.id === subregionId));\n if (!owner) throw new Error(`Unknown OEM subregion: ${subregionId}`);\n if (input.region && owner.id !== regionId) {\n throw new Error(`OEM subregion ${subregionId} does not belong to ${regionId}`);\n }\n regionId = owner.id as OEMRegionId;\n }\n\n const region = getOEMRegion(manifest, regionId);\n const subregion = subregionId\n ? region.subregions.find((entry) => entry.id === subregionId)\n : undefined;\n const floorId = (input.floor ?? 'M') as OEMFloorId;\n if (!region.floors.some((floor) => floor.id === floorId)) {\n throw new Error(`Unknown OEM floor ${floorId} in ${regionId}`);\n }\n\n const requestedCenter = input.center;\n if (requestedCenter && (!Number.isFinite(requestedCenter.x) || !Number.isFinite(requestedCenter.z))) {\n throw new Error('OEM Widget center coordinates must be finite');\n }\n const preset = getPreset(region, subregion);\n const requestedLocale = input.locale ?? (typeof navigator === 'undefined' ? manifest.fallbackLocale : navigator.language);\n\n return {\n regionId,\n subregionId,\n floorId,\n locale: normalizeOEMLocale(requestedLocale, Object.keys(manifest.locales), manifest.fallbackLocale) as OEMLocale,\n markerTypes: normalizeMarkerTypes(input.markerTypes),\n labels: input.labels ?? true,\n boundaries: input.boundaries ?? false,\n boundarySource: normalizeBoundarySource(input.boundarySource),\n markerClustering: input.markerClustering ?? true,\n zoom: Math.max(region.minZoom, Math.min(region.maxZoom, input.zoom ?? preset.zoom)),\n center: {\n x: requestedCenter?.x ?? preset.center.x,\n z: requestedCenter?.z ?? preset.center.z,\n },\n };\n};\n\nconst toConfig = (state: OEMWidgetState): OEMWidgetConfig => ({\n region: state.regionId,\n subregion: state.subregionId,\n floor: state.floorId,\n locale: state.locale,\n markerTypes: state.markerTypes,\n labels: state.labels,\n boundaries: state.boundaries,\n boundarySource: state.boundarySource,\n markerClustering: state.markerClustering,\n zoom: state.zoom,\n center: { ...state.center },\n});\n\nconst sameMarkers = (left: OEMWidgetState['markerTypes'], right: OEMWidgetState['markerTypes']): boolean =>\n left === right || (left !== '*' && right !== '*' && left.length === right.length &&\n left.every((marker, index) => marker === right[index]));\n\nconst sameState = (left: OEMWidgetState, right: OEMWidgetState): boolean =>\n left.regionId === right.regionId &&\n left.subregionId === right.subregionId &&\n left.floorId === right.floorId &&\n left.locale === right.locale &&\n sameMarkers(left.markerTypes, right.markerTypes) &&\n left.labels === right.labels &&\n left.boundaries === right.boundaries &&\n left.boundarySource === right.boundarySource &&\n left.markerClustering === right.markerClustering &&\n left.zoom === right.zoom &&\n left.center.x === right.center.x &&\n left.center.z === right.center.z;\n\nconst hasMarkers = (state: OEMWidgetState): boolean =>\n state.markerTypes === '*' || state.markerTypes.length > 0;\n\nclass Widget implements OEMWidget {\n destroyed = false;\n private applying = false;\n private updates = Promise.resolve();\n private customPointsUrl?: string;\n private controls: Control;\n private unsubscribeView: () => void;\n private unsubscribeClick: () => void;\n private listeners = new Map<keyof OEMWidgetEvents, Set<(payload: never) => void>>();\n\n constructor(\n private host: HTMLElement,\n private root: HTMLElement,\n private core: OEM,\n private manifest: OEMManifest,\n private options: OEMWidgetOptions,\n private state: OEMWidgetState,\n ) {\n this.customPointsUrl = options.customPointsUrl;\n this.controls = mountControls(root, {\n regionSelector: options.showRegionSelector ?? true,\n floorSelector: options.showFloorSelector ?? true,\n scaleBar: options.showScaleBar ?? true,\n }, {\n manifest,\n zoomLocked: options.lockZoom ?? false,\n apply: (update) => {\n void this.setOptions(update).catch((error: unknown) => this.report(error));\n },\n zoomTo: (zoom, zoomOptions) => core.setZoom(zoom, zoomOptions),\n });\n this.controls.sync(state);\n this.unsubscribeView = core.on('viewchange', this.syncView);\n this.unsubscribeClick = core.on('click', this.forwardClick);\n options.signal?.addEventListener('abort', this.destroy, { once: true });\n }\n\n private assertAlive(): void {\n if (this.destroyed) throw new Error('OEM Widget has been destroyed');\n }\n\n private report(error: unknown): void {\n this.options.onError?.(error instanceof Error ? error : new Error(String(error)));\n }\n\n private notify(): void {\n this.options.onStateChange?.(cloneState(this.state));\n }\n\n private emit<Event extends keyof OEMWidgetEvents>(event: Event, payload: OEMWidgetEvents[Event]): void {\n this.listeners.get(event)?.forEach((handler) => handler(payload as never));\n }\n\n private forwardClick = (payload: OEMMapClick): void => {\n if (!this.destroyed) this.emit('click', payload);\n };\n\n private syncView = (): void => {\n if (this.destroyed || this.applying) return;\n const view = this.core.getView();\n this.state = {\n ...this.state,\n regionId: view.regionId as OEMRegionId,\n floorId: (view.floorId ?? 'M') as OEMFloorId,\n locale: this.core.getLocale().resolved as OEMLocale,\n center: { x: view.x, z: view.z },\n zoom: view.zoom,\n };\n this.controls.sync(this.state);\n this.notify();\n };\n\n getState(): OEMWidgetState {\n this.assertAlive();\n return cloneState(this.state);\n }\n\n setCustomPoints(points: readonly OEMCustomPoint[]): void {\n this.assertAlive();\n this.core.setCustomPoints(points);\n this.customPointsUrl = undefined;\n }\n\n setClickPointMode(options?: OEMClickPointOptions | null): void {\n this.assertAlive();\n this.core.setClickPointMode(options);\n }\n\n clearClickPoints(): void {\n this.assertAlive();\n this.core.clearClickPoints();\n }\n\n async loadCustomPoints(url: string): Promise<void> {\n this.assertAlive();\n await this.core.loadCustomPoints(url);\n this.customPointsUrl = url;\n }\n\n clearCustomPoints(): void {\n this.assertAlive();\n this.core.clearCustomPoints();\n }\n\n getPoint(pointId: string) {\n this.assertAlive();\n return this.core.getPoint(pointId);\n }\n\n loadPoint(pointId: string) {\n this.assertAlive();\n return this.core.loadPoint(pointId);\n }\n\n on<Event extends keyof OEMWidgetEvents>(event: Event, handler: (payload: OEMWidgetEvents[Event]) => void): () => void {\n this.assertAlive();\n const handlers = this.listeners.get(event) ?? new Set();\n handlers.add(handler as (payload: never) => void);\n this.listeners.set(event, handlers);\n return () => { handlers.delete(handler as (payload: never) => void); };\n }\n\n setOptions(update: OEMWidgetConfig): Promise<void> {\n this.assertAlive();\n const snapshot = cloneConfig(update);\n const operation = this.updates.then(() => this.applyOptions(snapshot));\n this.updates = operation.catch(() => undefined);\n return operation;\n }\n\n private async applyOptions(update: OEMWidgetConfig): Promise<void> {\n this.assertAlive();\n const changes = Object.fromEntries(\n Object.entries(update).filter(([, value]) => value !== undefined),\n ) as OEMWidgetConfig;\n const merged: OEMWidgetConfig = { ...toConfig(this.state), ...changes };\n const nextRegionId = resolveRegionId(this.manifest, changes.region ?? this.state.regionId);\n\n if (nextRegionId !== this.state.regionId) {\n const preset = getPreset(getOEMRegion(this.manifest, nextRegionId));\n if (changes.floor === undefined) merged.floor = 'M';\n if (changes.subregion === undefined) merged.subregion = null;\n if (changes.center === undefined) merged.center = preset.center;\n if (changes.zoom === undefined) merged.zoom = preset.zoom;\n }\n\n if (changes.subregion !== undefined && changes.subregion !== this.state.subregionId) {\n const region = getOEMRegion(this.manifest, nextRegionId);\n const subregion = changes.subregion\n ? region.subregions.find((entry) => entry.id === changes.subregion)\n : undefined;\n const preset = getPreset(region, subregion);\n if (changes.center === undefined) merged.center = preset.center;\n if (changes.zoom === undefined) merged.zoom = preset.zoom;\n }\n\n const previous = this.state;\n const next = normalizeState(merged, this.manifest);\n if (changes.customPoints !== undefined && changes.customPointsUrl !== undefined) {\n throw new Error('Pass either customPoints or customPointsUrl, not both');\n }\n const customPointsChanged = changes.customPoints !== undefined || changes.customPointsUrl !== undefined;\n if (sameState(previous, next) && !customPointsChanged) return;\n\n const regionChanged = next.regionId !== previous.regionId;\n const filterChanged = next.subregionId !== previous.subregionId ||\n !sameMarkers(next.markerTypes, previous.markerTypes);\n const viewChanged = regionChanged ||\n next.floorId !== previous.floorId ||\n next.zoom !== previous.zoom ||\n next.center.x !== previous.center.x ||\n next.center.z !== previous.center.z;\n const previousMarkers = hasMarkers(previous);\n const nextMarkers = hasMarkers(next);\n\n this.applying = true;\n this.root.classList.add('loading');\n try {\n if (changes.customPoints !== undefined) {\n this.core.setCustomPoints(changes.customPoints);\n this.customPointsUrl = undefined;\n } else if (changes.customPointsUrl !== undefined) {\n await this.core.loadCustomPoints(changes.customPointsUrl);\n this.customPointsUrl = changes.customPointsUrl;\n }\n if (previousMarkers && !nextMarkers) await this.core.setFeatures({ points: false });\n if (filterChanged) {\n this.core.setPointFilter({\n types: next.markerTypes === '*' ? undefined : next.markerTypes,\n subregions: next.subregionId ? [next.subregionId] : undefined,\n });\n }\n if (regionChanged) await this.core.setRegion(next.regionId);\n if (next.locale !== previous.locale) await this.core.setLocale(next.locale);\n if (next.floorId !== previous.floorId) this.core.setFloor(next.floorId);\n if (next.markerClustering !== previous.markerClustering) {\n this.core.setMarkerClustering(next.markerClustering);\n }\n if (nextMarkers !== previousMarkers ||\n next.labels !== previous.labels ||\n next.boundaries !== previous.boundaries ||\n next.boundarySource !== previous.boundarySource) {\n await this.core.setFeatures({\n points: nextMarkers,\n labels: next.labels,\n boundaries: next.boundaries,\n boundarySource: next.boundarySource,\n });\n }\n if (viewChanged) {\n this.core.setView({\n regionId: next.regionId,\n floorId: next.floorId,\n x: next.center.x,\n z: next.center.z,\n zoom: next.zoom,\n });\n }\n const view = this.core.getView();\n this.state = {\n ...next,\n locale: this.core.getLocale().resolved as OEMLocale,\n center: { x: view.x, z: view.z },\n zoom: view.zoom,\n };\n this.controls.sync(this.state);\n } finally {\n this.applying = false;\n this.root.classList.remove('loading');\n }\n this.notify();\n }\n\n resize(): void {\n this.assertAlive();\n this.core.resize();\n }\n\n destroy = (): void => {\n if (this.destroyed) return;\n this.destroyed = true;\n this.unsubscribeView();\n this.unsubscribeClick();\n this.listeners.clear();\n this.controls.destroy?.();\n this.options.signal?.removeEventListener('abort', this.destroy);\n this.core.destroy();\n this.root.remove();\n mounted.delete(this.host);\n };\n}\n\n/** Creates an embeddable Open Endfield Map Widget. */\nexport async function createOEMWidget(\n container: string | HTMLElement,\n options: OEMWidgetOptions = {},\n): Promise<OEMWidget> {\n if (typeof document === 'undefined') throw new Error('createOEMWidget must run in a browser');\n if (options.customPoints !== undefined && options.customPointsUrl !== undefined) {\n throw new Error('Pass either customPoints or customPointsUrl, not both');\n }\n options.signal?.throwIfAborted();\n const host = resolveContainer(container);\n if (mounted.has(host)) throw new Error('This container already hosts an OEM Widget');\n\n const root = document.createElement('div');\n root.className = 'oemWidget loading';\n if (options.className) root.classList.add(...options.className.split(/\\s+/).filter(Boolean));\n root.dataset.theme = options.theme ?? 'light';\n const mapHost = document.createElement('div');\n mapHost.className = 'mapHost';\n root.append(mapHost);\n host.append(root);\n mounted.add(host);\n\n let core: OEM | undefined;\n let widget: Widget | undefined;\n try {\n const resources: OEMResources = options.resources ?? defaultOEMResources;\n const manifest = options.manifest\n ? validateOEMManifest(options.manifest)\n : await loadOEMManifest(resources, options.signal);\n installFonts(root, manifest, resources);\n const state = normalizeState(options, manifest);\n core = await createOEM(mapHost, {\n resources,\n manifest,\n regionId: state.regionId,\n floorId: state.floorId,\n locale: state.locale,\n theme: options.theme,\n view: {\n regionId: state.regionId,\n floorId: state.floorId,\n x: state.center.x,\n z: state.center.z,\n zoom: state.zoom,\n },\n features: {\n points: hasMarkers(state),\n labels: state.labels,\n boundaries: state.boundaries,\n boundarySource: state.boundarySource,\n },\n markerClustering: state.markerClustering,\n customPoints: options.customPoints,\n customPointsUrl: options.customPointsUrl,\n pointFilter: {\n types: state.markerTypes === '*' ? undefined : state.markerTypes,\n subregions: state.subregionId ? [state.subregionId] : undefined,\n },\n lockDrag: options.lockDrag ?? false,\n lockZoom: options.lockZoom ?? false,\n signal: options.signal,\n onError: options.onError,\n });\n widget = new Widget(host, root, core, manifest, options, state);\n root.classList.remove('loading');\n options.onReady?.(widget);\n return widget;\n } catch (error) {\n if (widget) widget.destroy();\n else {\n core?.destroy();\n root.remove();\n mounted.delete(host);\n }\n throw error;\n }\n}\n", "import { getOEMRegion } from '@opendfieldmap/core';\nimport type { OEMWidgetState } from '../types';\nimport { createButton, getMessages, setLabel } from './types';\nimport type { Control, ControlContext } from './types';\n\nconst ZOOM_STEP = 0.5;\nconst clamp = (value: number, minimum: number, maximum: number): number =>\n Math.max(minimum, Math.min(maximum, value));\n\n/** Creates the Atlos desktop click scale and compact touch-drag scale. */\nexport const createScaleControl = (context: ControlContext): Control & { element: HTMLElement } => {\n const { manifest, zoomLocked } = context;\n const element = document.createElement('div');\n element.className = 'scaleControl';\n element.classList.toggle('locked', zoomLocked);\n const decorationTop = document.createElement('div');\n decorationTop.className = 'scaleDecoration scaleDecorationTop';\n const decorationBottom = document.createElement('div');\n decorationBottom.className = 'scaleDecoration scaleDecorationBottom';\n const zoomInFrame = document.createElement('div');\n zoomInFrame.className = 'scaleFrame zoomInFrame';\n const zoomIn = createButton('zoomButton zoomIn');\n zoomIn.textContent = '+';\n zoomInFrame.append(zoomIn);\n const track = document.createElement('div');\n track.className = 'scaleTrack';\n const fill = document.createElement('div');\n fill.className = 'scaleFill';\n track.append(fill);\n const zoomOutFrame = document.createElement('div');\n zoomOutFrame.className = 'scaleFrame zoomOutFrame';\n const zoomOut = createButton('zoomButton zoomOut');\n zoomOut.textContent = '-';\n zoomOutFrame.append(zoomOut);\n element.append(decorationTop, zoomInFrame, track, zoomOutFrame, decorationBottom);\n\n let currentState: OEMWidgetState;\n let targetZoom: number | null = null;\n let scaleFrame: number | null = null;\n let zoomFrame: number | null = null;\n let dragPointerId: number | null = null;\n let dragStartY: number | null = null;\n let dragStartZoom: number | null = null;\n let currentLocale = '';\n\n const isCompact = () => (element.closest('.oemWidget')?.clientWidth ?? Number.POSITIVE_INFINITY) < 480;\n const scaleFor = (zoom: number, minimum: number, maximum: number) =>\n maximum === minimum ? 0 : clamp((zoom - minimum) / (maximum - minimum), 0, 1);\n const updateScale = (zoom: number, minimum: number, maximum: number) => {\n if (scaleFrame !== null) cancelAnimationFrame(scaleFrame);\n scaleFrame = requestAnimationFrame(() => {\n track.style.setProperty('--scale', String(scaleFor(zoom, minimum, maximum)));\n scaleFrame = null;\n });\n };\n const applyZoom = (zoom: number, animate: boolean) => {\n const region = getOEMRegion(manifest, currentState.regionId);\n const nextZoom = clamp(zoom, region.minZoom, region.maxZoom);\n if (targetZoom === nextZoom) return;\n targetZoom = nextZoom;\n updateScale(nextZoom, region.minZoom, region.maxZoom);\n context.zoomTo(nextZoom, { animate });\n };\n const scheduleDragZoom = (zoom: number) => {\n targetZoom = zoom;\n if (zoomFrame !== null) return;\n zoomFrame = requestAnimationFrame(() => {\n zoomFrame = null;\n if (targetZoom !== null) context.zoomTo(targetZoom, { animate: false });\n });\n };\n\n zoomIn.addEventListener('click', () => {\n if (!zoomLocked) applyZoom((targetZoom ?? currentState.zoom) + ZOOM_STEP, true);\n });\n zoomOut.addEventListener('click', () => {\n if (!zoomLocked) applyZoom((targetZoom ?? currentState.zoom) - ZOOM_STEP, true);\n });\n track.addEventListener('click', (event) => {\n if (zoomLocked || isCompact()) return;\n const region = getOEMRegion(manifest, currentState.regionId);\n const bounds = track.getBoundingClientRect();\n const ratio = 1 - (event.clientY - bounds.top) / bounds.height;\n applyZoom(region.minZoom + clamp(ratio, 0, 1) * (region.maxZoom - region.minZoom), true);\n });\n track.addEventListener('pointerdown', (event) => {\n if (zoomLocked || !isCompact()) return;\n event.preventDefault();\n event.stopPropagation();\n track.setPointerCapture(event.pointerId);\n dragPointerId = event.pointerId;\n dragStartY = event.clientY;\n dragStartZoom = targetZoom ?? currentState.zoom;\n element.classList.add('dragging');\n });\n track.addEventListener('pointermove', (event) => {\n if (dragPointerId !== event.pointerId || dragStartY === null || dragStartZoom === null) return;\n event.preventDefault();\n const region = getOEMRegion(manifest, currentState.regionId);\n const delta = ((dragStartY - event.clientY) / Math.max(1, track.getBoundingClientRect().height)) *\n (region.maxZoom - region.minZoom);\n const nextZoom = clamp(dragStartZoom + delta, region.minZoom, region.maxZoom);\n updateScale(nextZoom, region.minZoom, region.maxZoom);\n scheduleDragZoom(nextZoom);\n });\n const finishDrag = (event: PointerEvent) => {\n if (dragPointerId !== event.pointerId) return;\n if (track.hasPointerCapture(event.pointerId)) track.releasePointerCapture(event.pointerId);\n dragPointerId = null;\n dragStartY = null;\n dragStartZoom = null;\n element.classList.remove('dragging');\n };\n track.addEventListener('pointerup', finishDrag);\n track.addEventListener('pointercancel', finishDrag);\n track.addEventListener('lostpointercapture', finishDrag);\n\n return {\n element,\n sync(state: OEMWidgetState) {\n currentState = state;\n targetZoom = state.zoom;\n const region = getOEMRegion(manifest, state.regionId);\n updateScale(state.zoom, region.minZoom, region.maxZoom);\n if (currentLocale !== state.locale) {\n currentLocale = state.locale;\n const messages = getMessages(manifest, state.locale);\n setLabel(zoomIn, messages.zoomIn);\n setLabel(zoomOut, messages.zoomOut);\n }\n zoomIn.disabled = zoomLocked || state.zoom >= region.maxZoom;\n zoomOut.disabled = zoomLocked || state.zoom <= region.minZoom;\n },\n destroy() {\n if (scaleFrame !== null) cancelAnimationFrame(scaleFrame);\n if (zoomFrame !== null) cancelAnimationFrame(zoomFrame);\n element.classList.remove('dragging');\n },\n };\n};\n", "import type { OEMControlMessages, OEMManifest } from '@opendfieldmap/core';\nimport type { OEMWidgetConfig, OEMWidgetState } from '../types';\n\n/** Lifecycle contract shared by built-in controls. */\nexport interface Control {\n sync(state: OEMWidgetState): void;\n destroy?(): void;\n}\n\n/** Coordinates the one persistent flyout allowed across all switch controls. */\nexport interface Panels {\n expand(owner: HTMLElement): void;\n collapse(owner: HTMLElement): void;\n collapseAll(): void;\n}\n\n/** Dependencies supplied by the Widget coordinator to built-in controls. */\nexport interface ControlContext {\n manifest: OEMManifest;\n zoomLocked: boolean;\n apply(update: OEMWidgetConfig): void;\n zoomTo(zoom: number, options: { animate: boolean }): void;\n panels: Panels;\n}\n\n/** Creates a reset, keyboard-accessible button for a control component. */\nexport const createButton = (className: string): HTMLButtonElement => {\n const element = document.createElement('button');\n element.type = 'button';\n element.className = className;\n return element;\n};\n\n/** Applies a localized accessible name to a control without embedding UI copy. */\nexport const setLabel = (\n element: HTMLElement,\n label: string,\n): void => {\n element.title = label;\n element.setAttribute('aria-label', label);\n};\n\n/** Resolves a control message bundle through the manifest locale fallback. */\nexport const getMessages = (\n manifest: OEMManifest,\n locale: string,\n): OEMControlMessages => {\n const messages =\n manifest.controls[locale] ?? manifest.controls[manifest.fallbackLocale];\n if (!messages) throw new Error('Missing OEM control messages');\n return messages;\n};\n", "import { getOEMRegion } from '@opendfieldmap/core';\nimport type { OEMRegion, OEMSubregion } from '@opendfieldmap/core';\nimport { LAYER_ICON, REGION_ICONS } from '../icons';\nimport type { OEMFloorId, OEMRegionSelector, OEMWidgetState } from '../types';\nimport { createButton, getMessages, setLabel } from './types';\nimport type { Control, ControlContext } from './types';\n\nconst FLOOR_ORDER = ['L4', 'L3', 'L2', 'L1', 'M', 'B1', 'B2', 'B3', 'B4'];\n\n/** Creates the nested, keyboard-operable action shape used by Atlos switch items. */\nconst createSwitchAction = (className: string): HTMLDivElement => {\n const element = document.createElement('div');\n element.className = className;\n element.tabIndex = 0;\n element.setAttribute('role', 'button');\n return element;\n};\n\n/** Keeps touch and keyboard flyouts exclusive without affecting pointer hover. */\nconst bindPersistentPanel = (owner: HTMLElement, context: ControlContext): void => {\n owner.addEventListener('pointerenter', (event) => {\n if (event.pointerType === 'mouse') context.panels.collapseAll();\n });\n owner.addEventListener('pointerdown', (event) => {\n if (event.pointerType === 'touch' || event.pointerType === 'pen') context.panels.expand(owner);\n });\n owner.addEventListener('focusin', () => {\n if (owner.matches(':focus-visible') || owner.querySelector(':focus-visible')) context.panels.expand(owner);\n });\n owner.addEventListener('focusout', (event) => {\n if (!(event.relatedTarget instanceof Node) || !owner.contains(event.relatedTarget)) context.panels.collapse(owner);\n });\n};\n\n/** Moves an Atlos indicator by transform so transitions stay on the compositor. */\nconst positionIndicator = (indicator: HTMLElement, target: HTMLElement): void => {\n indicator.style.transform = `translateY(calc(${target.offsetTop + target.offsetHeight / 2}px - 50%))`;\n};\n\n/** Creates the RGN control and its hover/focus subregion rail. */\nexport const createRegionControl = (context: ControlContext): Control & { element: HTMLElement } => {\n const { manifest, apply } = context;\n const element = document.createElement('div');\n element.className = 'switch regionSwitch';\n const label = document.createElement('div');\n label.className = 'switchLabel regionLabel';\n label.setAttribute('aria-hidden', 'true');\n const indicator = document.createElement('div');\n indicator.className = 'switchIndicator';\n element.append(label, indicator);\n\n const controls = new Map<string, {\n region: OEMRegion;\n button: HTMLDivElement;\n subregions: Map<string, { data: OEMSubregion; button: HTMLButtonElement }>;\n subregionIndicator?: HTMLDivElement;\n }>();\n\n for (const region of manifest.regions) {\n const regionButton = createSwitchAction('switchItem regionEntry');\n regionButton.dataset.region = region.id;\n if (region.subregions.length > 1) bindPersistentPanel(regionButton, context);\n const icon = document.createElement('span');\n icon.className = 'switchIcon';\n const markup = REGION_ICONS[region.id];\n if (!markup) throw new Error(`Missing Atlos region icon: ${region.id}`);\n icon.innerHTML = markup;\n regionButton.append(icon);\n const selectRegion = () => {\n const target = region.initialView;\n apply({ region: region.id as OEMRegionSelector, subregion: null, floor: 'M', center: { x: target.x, z: target.z }, zoom: target.zoom });\n };\n regionButton.addEventListener('click', selectRegion);\n regionButton.addEventListener('keydown', (event) => {\n if (event.target !== regionButton) return;\n if (event.key !== 'Enter' && event.key !== ' ') return;\n event.preventDefault();\n selectRegion();\n });\n const subregionControls = new Map<string, { data: OEMSubregion; button: HTMLButtonElement }>();\n let subregionIndicator: HTMLDivElement | undefined;\n if (region.subregions.length > 1) {\n const panel = document.createElement('div');\n panel.className = 'subregionPanel';\n panel.addEventListener('click', (event) => event.stopPropagation());\n const list = document.createElement('div');\n list.className = 'subregionList';\n subregionIndicator = document.createElement('div');\n subregionIndicator.className = 'switchIndicator';\n list.append(subregionIndicator);\n for (const subregion of region.subregions) {\n const subregionButton = createButton('selectionItem subregionItem');\n subregionButton.dataset.subregion = subregion.id;\n subregionButton.addEventListener('click', () => {\n context.panels.collapse(regionButton);\n const [[x1, y1], [x2, y2]] = subregion.bounds ?? [\n [region.initialView.x, region.initialView.z],\n [region.initialView.x, region.initialView.z],\n ];\n apply({\n region: region.id as OEMRegionSelector,\n subregion: subregion.id,\n floor: 'M',\n center: { x: (x1 + x2) / 2, z: (y1 + y2) / 2 },\n zoom: Math.max(region.minZoom, Math.min(region.maxZoom, 1)),\n });\n });\n subregionControls.set(subregion.id, { data: subregion, button: subregionButton });\n list.append(subregionButton);\n }\n panel.append(list);\n regionButton.append(panel);\n }\n controls.set(region.id, { region, button: regionButton, subregions: subregionControls, subregionIndicator });\n element.append(regionButton);\n }\n\n let stateKey = '';\n return {\n element,\n sync(state: OEMWidgetState) {\n const nextKey = `${state.locale}\\0${state.regionId}\\0${state.subregionId ?? ''}`;\n if (nextKey !== stateKey) {\n stateKey = nextKey;\n for (const [regionId, control] of controls) {\n const regionName = control.region.locales[state.locale] ?? control.region.locales[manifest.fallbackLocale] ?? control.region.name;\n control.button.classList.toggle('selected', regionId === state.regionId);\n setLabel(control.button, regionName);\n for (const [subregionId, subregion] of control.subregions) {\n const localized = subregion.data.locales?.[state.locale] ?? subregion.data.locales?.[manifest.fallbackLocale];\n subregion.button.textContent = localized?.short ?? subregion.data.key;\n setLabel(subregion.button, localized?.name ?? subregion.data.key);\n subregion.button.classList.toggle('selected', subregionId === state.subregionId);\n }\n }\n }\n for (const control of controls.values()) {\n const selectedSubregion = state.subregionId ? control.subregions.get(state.subregionId) : undefined;\n if (control.subregionIndicator) {\n control.subregionIndicator.classList.toggle('hidden', !selectedSubregion);\n if (selectedSubregion) positionIndicator(control.subregionIndicator, selectedSubregion.button);\n }\n }\n const selectedControl = controls.get(state.regionId);\n if (selectedControl) positionIndicator(indicator, selectedControl.button);\n },\n };\n};\n\n/** Creates the Atlos LYR control and its floor selection rail. */\nexport const createLayerControl = (context: ControlContext): Control & { element: HTMLElement } => {\n const { manifest, apply } = context;\n const element = document.createElement('div');\n element.className = 'switch layerSwitch';\n const label = document.createElement('div');\n label.className = 'switchLabel layerLabel';\n label.setAttribute('aria-hidden', 'true');\n const mainButton = createSwitchAction('switchItem');\n bindPersistentPanel(mainButton, context);\n const icon = document.createElement('span');\n icon.className = 'switchIcon';\n icon.innerHTML = LAYER_ICON;\n const panel = document.createElement('div');\n panel.className = 'floorPanel';\n panel.addEventListener('click', (event) => event.stopPropagation());\n const list = document.createElement('div');\n list.className = 'floorList';\n panel.append(list);\n mainButton.append(icon, panel);\n element.append(label, mainButton);\n mainButton.addEventListener('keydown', (event) => {\n if (event.target !== mainButton || (event.key !== 'Enter' && event.key !== ' ')) return;\n event.preventDefault();\n mainButton.click();\n });\n const indicator = document.createElement('div');\n indicator.className = 'switchIndicator';\n const floorButtons = new Map<string, HTMLButtonElement>();\n let currentRegion = '';\n let currentLocale = '';\n let currentFloor = 'M';\n mainButton.addEventListener('click', () => {\n if (currentFloor !== 'M') apply({ floor: 'M' });\n });\n\n return {\n element,\n sync(state: OEMWidgetState) {\n const region = getOEMRegion(manifest, state.regionId);\n if (currentRegion !== region.id) {\n currentRegion = region.id;\n floorButtons.clear();\n list.replaceChildren(indicator);\n const floors = [...region.floors].sort((left, right) => FLOOR_ORDER.indexOf(left.id) - FLOOR_ORDER.indexOf(right.id));\n element.hidden = floors.length <= 1;\n for (const floor of floors) {\n const button = createButton('selectionItem floorItem');\n button.textContent = floor.id;\n button.addEventListener('click', () => {\n context.panels.collapse(mainButton);\n apply({ floor: floor.id as OEMFloorId });\n });\n floorButtons.set(floor.id, button);\n list.append(button);\n }\n currentLocale = '';\n }\n if (currentLocale !== state.locale) {\n currentLocale = state.locale;\n const messages = getMessages(manifest, state.locale);\n setLabel(mainButton, messages.layerSelect);\n for (const [floorId, button] of floorButtons) setLabel(button, `${messages.layerSelect}: ${floorId}`);\n }\n if (currentFloor !== state.floorId) floorButtons.get(currentFloor)?.classList.remove('selected');\n currentFloor = state.floorId;\n mainButton.classList.toggle('selected', currentFloor !== 'M');\n const selectedButton = floorButtons.get(currentFloor);\n selectedButton?.classList.add('selected');\n if (selectedButton) positionIndicator(indicator, selectedButton);\n },\n };\n};\n", "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 425.67 170.68\">\n <g>\n <path class=\"cls-1\" d=\"M15.21,170.68h410.46s-43.67-106.46-205.23-106.45c-160.59,0-205.23,106.45-205.23,106.45Z\"/>\n <path class=\"cls-1\" d=\"M0,63.31h244.09S218.12,0,122.04,0C26.54,0,0,63.31,0,63.31Z\"/>\n </g>\n</svg>", "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 374.53 309.73\">\n <g>\n <rect x=\"80.63\" y=\"20.44\" width=\"58.29\" height=\"117.86\" rx=\"1\" ry=\"1\"/>\n <path d=\"M237.6,223.35c-.53-.03-.94-.47-.94-.99v-89.26c0-.55-.45-1-1-1h-56.3c-.55,0-1,.45-1,1v87.86c0,.55-.44.99-.99.99-12.89.14-25.44.56-37.51,1.23-.53.03-.94.47-.94,1v45.23c0,.55-.45,1-1,1h-56.3c-.55,0-1-.45-1-1v-39.11c0-.61-.55-1.08-1.16-.99C31.4,236.85,0,249.69,0,265.81c0,27.25,83.84,43.92,187.26,43.92s187.26-16.67,187.26-43.92c0-21.91-57.95-37.74-136.93-42.46Z\"/>\n <path d=\"M81.77,228.97c17.21-2.61,36.48-4.55,57.16-5.73v-70.69h-58.29v75.43c0,.61.53,1.07,1.14.98Z\"/>\n <rect x=\"178.37\" width=\"58.29\" height=\"117.86\" rx=\"1\" ry=\"1\"/>\n <path d=\"M249.61,156.62l57.93-49.76c.22-.19.35-.47.35-.76v-51.73c0-.85-1-1.31-1.64-.76l-57.93,49.76c-.22.19-.35.47-.35.76v51.73c0,.85,1,1.31,1.64.76Z\"/>\n </g>\n</svg>", "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 320.87 332.32\">\n <path d=\"M306.45,266.64L241.82,0h-32.6l39.82,266.64h-26.81l-6.22-26.53h8.95v-47.7h-20.14L159.7,0l-45.13,192.41h-20.14v47.7h8.95l-6.22,26.53h-26.34L110.64,0h-32.6L13.4,266.64H0v65.68h320.87v-65.68h-14.42ZM70.81,312.22v-30.76h22.87l-7.21,30.76h-15.65ZM248.58,312.22h-15.65l-7.21-30.76h22.87v30.76Z\"/>\n</svg>", "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 148.547 130.941\">\n <polygon points=\"28.102 0 6.153 0 19.116 21.175 41.065 21.175 28.102 0\"/>\n <polygon points=\"19.116 21.175 0 21.175 26.446 65.471 0 109.766 19.116 109.766 45.562 65.471 19.116 21.175\"/>\n <polygon points=\"142.394 0 120.444 0 107.481 21.175 129.431 21.175 142.394 0\"/>\n <polygon points=\"6.153 130.941 28.102 130.941 41.065 109.766 19.116 109.766 6.153 130.941\"/>\n <path d=\"M109.749,94.194l-16.583-28.723,16.583-28.723h-11.259l8.991-15.573H41.065l8.991,15.573h-11.259l16.583,28.723-16.583,28.723h11.259l-8.991,15.573h66.416l-8.991-15.573h11.259ZM87.106,47.921l-10.132,17.549,10.132,17.549h-7.029l7.029,12.174h-25.665l7.029-12.174h-7.029l10.132-17.549-10.132-17.549h7.029l-7.029-12.174h25.665l-7.029,12.174h7.029Z\"/>\n <polygon points=\"120.444 130.941 142.394 130.941 129.431 109.766 107.481 109.766 120.444 130.941\"/>\n <polygon points=\"122.1 65.471 148.547 21.175 129.431 21.175 102.985 65.471 129.431 109.766 148.547 109.766 122.1 65.471\"/>\n</svg>", "<svg width=\"40\" height=\"37\" viewBox=\"0 0 40 37\" xmlns=\"http://www.w3.org/2000/svg\">\n<path d=\"M20 0L39.2453 10.477L20 20.954L0.7547 10.477L20 0Z\"/>\n<path d=\"M20.9333 24.9496L20 25.4576L19.0667 24.9496L10.6011 20.3409L0 26.1121L20 37L40 26.1121L29.3989 20.3409L20.9333 24.9496Z\"/>\n</svg>\n", "import Valley4 from './assets/Valley_4.svg';\nimport Wuling from './assets/Wuling.svg';\nimport Dijiang from './assets/Dijiang.svg';\nimport Weekraid1 from './assets/Weekraid_1.svg';\nimport Layer from './assets/layer.svg';\n\nconst clean = (svg: string): string => svg.replace(/<\\?xml[^>]*>\\s*/, '');\n\nexport const REGION_ICONS: Readonly<Record<string, string>> = Object.freeze({\n Valley_4: clean(Valley4),\n Wuling: clean(Wuling),\n Dijiang: clean(Dijiang),\n Weekraid_1: clean(Weekraid1),\n});\n\nexport const LAYER_ICON = clean(Layer);\n", "import type { OEMWidgetState } from '../types';\nimport { createScaleControl } from './scale';\nimport { createLayerControl, createRegionControl } from './switches';\nimport type { Control, ControlContext, Panels } from './types';\n\nexport const mountControls = (\n root: HTMLElement,\n visibility: { regionSelector: boolean; floorSelector: boolean; scaleBar: boolean },\n context: Omit<ControlContext, 'panels'>,\n): Control => {\n const hasSwitches = visibility.regionSelector || visibility.floorSelector;\n if (!hasSwitches && !visibility.scaleBar) return { sync: () => {} };\n\n const overlay = document.createElement('div');\n overlay.className = 'controlOverlay';\n root.append(overlay);\n const components: Control[] = [];\n let expandedPanel: HTMLElement | null = null;\n const panels: Panels = {\n expand(owner) {\n if (expandedPanel === owner) return;\n expandedPanel?.classList.remove('expanded');\n expandedPanel = owner;\n expandedPanel.classList.add('expanded');\n },\n collapse(owner) {\n owner.classList.remove('expanded');\n if (expandedPanel === owner) expandedPanel = null;\n },\n collapseAll() {\n expandedPanel?.classList.remove('expanded');\n expandedPanel = null;\n },\n };\n const controlContext: ControlContext = { ...context, panels };\n let currentState: OEMWidgetState | null = null;\n const handleOutsidePointer = (event: PointerEvent) => {\n if (expandedPanel && event.target instanceof Node && !expandedPanel.contains(event.target)) panels.collapseAll();\n };\n if (hasSwitches) document.addEventListener('pointerdown', handleOutsidePointer, true);\n const observer = !hasSwitches || typeof ResizeObserver === 'undefined' ? null : new ResizeObserver(() => {\n if (currentState) for (const component of components) component.sync(currentState);\n });\n observer?.observe(root);\n\n if (hasSwitches) {\n const switchArea = document.createElement('div');\n switchArea.className = 'switchArea';\n if (visibility.regionSelector) {\n const region = createRegionControl(controlContext);\n components.push(region);\n switchArea.append(region.element);\n }\n if (visibility.floorSelector) {\n const layer = createLayerControl(controlContext);\n components.push(layer);\n switchArea.append(layer.element);\n }\n overlay.append(switchArea);\n }\n\n if (visibility.scaleBar) {\n const scale = createScaleControl(controlContext);\n components.push(scale);\n overlay.append(scale.element);\n }\n\n return {\n sync(state: OEMWidgetState) {\n currentState = state;\n for (const component of components) component.sync(state);\n },\n destroy() {\n if (hasSwitches) document.removeEventListener('pointerdown', handleOutsidePointer, true);\n observer?.disconnect();\n panels.collapseAll();\n for (const component of components) component.destroy?.();\n },\n };\n};\n", "import { resolveOEMAsset } from '@opendfieldmap/core';\nimport type { OEMManifest, OEMResources } from '@opendfieldmap/core';\n\nconst FONT_FAMILIES = new Set([\n 'HMSans_EN',\n 'Novecento Wide Bold',\n 'Novecento Wide DemiBold',\n 'Novecento Wide Medium',\n 'Novecento Cyrillic DemiBold',\n 'Novecento Cyrillic Medium',\n 'Novecento Vietnamese DemiBold',\n 'Novecento Vietnamese Medium',\n]);\n\nexport const installFonts = (root: HTMLElement, manifest: OEMManifest, resources: OEMResources): void => {\n if (!manifest.fonts?.length) return;\n const rules = manifest.fonts.map((font) => {\n if (!FONT_FAMILIES.has(font.family) || !Number.isFinite(font.weight) ||\n (font.weightRange && (!Number.isFinite(font.weightRange[0]) || !Number.isFinite(font.weightRange[1]) ||\n font.weightRange[0] > font.weightRange[1]))) {\n throw new Error(`Unsupported OEM font: ${font.family}`);\n }\n const url = resolveOEMAsset(resources.baseUrl, font.path);\n const weight = font.weightRange ? `${font.weightRange[0]} ${font.weightRange[1]}` : String(font.weight);\n return `@font-face{font-family:${JSON.stringify(font.family)};src:url(${JSON.stringify(url)}) format(\"woff2\");font-style:${font.style};font-weight:${weight};font-display:swap;}`;\n });\n const style = document.createElement('style');\n style.dataset.oemFonts = manifest.releaseId;\n style.textContent = rules.join('');\n root.append(style);\n};\n", "import type { OEMBoundarySource, OEMFloorId, OEMLocale, OEMRegionSelector, OEMWidgetConfig } from './types';\n\nconst parseBoolean = (value: string | null): boolean | undefined => {\n if (value === null) return undefined;\n if (['1', 'true', 'on', 'yes'].includes(value.toLowerCase())) return true;\n if (['0', 'false', 'off', 'no'].includes(value.toLowerCase())) return false;\n return undefined;\n};\n\nconst parseNumber = (value: string | null): number | undefined => {\n if (value === null || value.trim() === '') return undefined;\n const number = Number(value);\n return Number.isFinite(number) ? number : undefined;\n};\n\nconst parseList = (value: string | null): string[] | undefined => {\n if (value === null) return undefined;\n return [...new Set(value.split(',').map((entry) => entry.trim()).filter(Boolean))];\n};\n\nconst parseBoundarySource = (value: string | null): OEMBoundarySource | undefined =>\n value === 'oem' || value === 'game' ? value : undefined;\n\nconst toSearchParams = (source: string): URLSearchParams => {\n const trimmed = source.trim();\n if (/^[a-z][a-z\\d+.-]*:\\/\\//i.test(trimmed)) return new URL(trimmed).searchParams;\n const query = trimmed.includes('?') ? trimmed.slice(trimmed.indexOf('?') + 1) : trimmed;\n return new URLSearchParams(query.replace(/^\\?/, ''));\n};\n\n/**\n * Adapts compact OEM URL-state keys to the typed Widget configuration.\n *\n * This helper is optional; createOEMWidget accepts normal named properties.\n */\nexport function parseOEMUrlState(source: string | URLSearchParams): OEMWidgetConfig {\n const params = typeof source === 'string' ? toSearchParams(source) : source;\n const filter = params.get('f');\n const centerX = parseNumber(params.get('cx'));\n const centerZ = parseNumber(params.get('cz') ?? params.get('centerZ'));\n return {\n region: (params.get('r') ?? undefined) as OEMRegionSelector | undefined,\n subregion: params.get('s'),\n floor: (params.get('layer') ?? undefined) as OEMFloorId | undefined,\n locale: (params.get('l') ?? undefined) as OEMLocale | undefined,\n markerTypes: filter === '*' ? '*' : filter === null ? undefined : parseList(filter) ?? false,\n labels: parseBoolean(params.get('labels') ?? params.get('names')),\n boundaries: parseBoolean(params.get('boundaries') ?? params.get('boundary')),\n boundarySource: parseBoundarySource(params.get('boundarySource')),\n markerClustering: parseBoolean(params.get('cluster')),\n zoom: parseNumber(params.get('z')),\n center: centerX === undefined || centerZ === undefined ? undefined : { x: centerX, z: centerZ },\n };\n}\n", "export { createOEMWidget } from './widget';\nexport { parseOEMUrlState } from './state';\nexport { gameToOEMPosition, gameXZToOEMPosition, mapToGameXZPosition, oemToGamePosition, toOEMMapPosition, fromOEMMapPosition, toOEMLeafletMapPosition } from '@opendfieldmap/core';\nexport type { OEMBoundarySource, OEMGamePosition, OEMGameTransform, OEMGameXZPosition, OEMMapOffset, OEMMapPosition, OEMPoint, OEMPosition, OEMRegion } from '@opendfieldmap/core';\nexport type { OEMClickPointOptions, OEMCustomPoint, OEMMapClick } from '@opendfieldmap/map';\nexport type * from './types';\n"],
5
+ "mappings": ";AAAA;AAAA,EACE;AAAA,EACA,gBAAAA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAEP,SAAS,iBAAiB;;;ACR1B,SAAS,oBAAoB;;;AC0BtB,IAAM,eAAe,CAAC,cAAyC;AACpE,QAAM,UAAU,SAAS,cAAc,QAAQ;AAC/C,UAAQ,OAAO;AACf,UAAQ,YAAY;AACpB,SAAO;AACT;AAGO,IAAM,WAAW,CACtB,SACA,UACS;AACT,UAAQ,QAAQ;AAChB,UAAQ,aAAa,cAAc,KAAK;AAC1C;AAGO,IAAM,cAAc,CACzB,UACA,WACuB;AACvB,QAAM,WACJ,SAAS,SAAS,MAAM,KAAK,SAAS,SAAS,SAAS,cAAc;AACxE,MAAI,CAAC,SAAU,OAAM,IAAI,MAAM,8BAA8B;AAC7D,SAAO;AACT;;;AD9CA,IAAM,YAAY;AAClB,IAAM,QAAQ,CAAC,OAAe,SAAiB,YAC7C,KAAK,IAAI,SAAS,KAAK,IAAI,SAAS,KAAK,CAAC;AAGrC,IAAM,qBAAqB,CAAC,YAAgE;AACjG,QAAM,EAAE,UAAU,WAAW,IAAI;AACjC,QAAM,UAAU,SAAS,cAAc,KAAK;AAC5C,UAAQ,YAAY;AACpB,UAAQ,UAAU,OAAO,UAAU,UAAU;AAC7C,QAAM,gBAAgB,SAAS,cAAc,KAAK;AAClD,gBAAc,YAAY;AAC1B,QAAM,mBAAmB,SAAS,cAAc,KAAK;AACrD,mBAAiB,YAAY;AAC7B,QAAM,cAAc,SAAS,cAAc,KAAK;AAChD,cAAY,YAAY;AACxB,QAAM,SAAS,aAAa,mBAAmB;AAC/C,SAAO,cAAc;AACrB,cAAY,OAAO,MAAM;AACzB,QAAM,QAAQ,SAAS,cAAc,KAAK;AAC1C,QAAM,YAAY;AAClB,QAAM,OAAO,SAAS,cAAc,KAAK;AACzC,OAAK,YAAY;AACjB,QAAM,OAAO,IAAI;AACjB,QAAM,eAAe,SAAS,cAAc,KAAK;AACjD,eAAa,YAAY;AACzB,QAAM,UAAU,aAAa,oBAAoB;AACjD,UAAQ,cAAc;AACtB,eAAa,OAAO,OAAO;AAC3B,UAAQ,OAAO,eAAe,aAAa,OAAO,cAAc,gBAAgB;AAEhF,MAAI;AACJ,MAAI,aAA4B;AAChC,MAAI,aAA4B;AAChC,MAAI,YAA2B;AAC/B,MAAI,gBAA+B;AACnC,MAAI,aAA4B;AAChC,MAAI,gBAA+B;AACnC,MAAI,gBAAgB;AAEpB,QAAM,YAAY,OAAO,QAAQ,QAAQ,YAAY,GAAG,eAAe,OAAO,qBAAqB;AACnG,QAAM,WAAW,CAAC,MAAc,SAAiB,YAC/C,YAAY,UAAU,IAAI,OAAO,OAAO,YAAY,UAAU,UAAU,GAAG,CAAC;AAC9E,QAAM,cAAc,CAAC,MAAc,SAAiB,YAAoB;AACtE,QAAI,eAAe,KAAM,sBAAqB,UAAU;AACxD,iBAAa,sBAAsB,MAAM;AACvC,YAAM,MAAM,YAAY,WAAW,OAAO,SAAS,MAAM,SAAS,OAAO,CAAC,CAAC;AAC3E,mBAAa;AAAA,IACf,CAAC;AAAA,EACH;AACA,QAAM,YAAY,CAAC,MAAc,YAAqB;AACpD,UAAM,SAAS,aAAa,UAAU,aAAa,QAAQ;AAC3D,UAAM,WAAW,MAAM,MAAM,OAAO,SAAS,OAAO,OAAO;AAC3D,QAAI,eAAe,SAAU;AAC7B,iBAAa;AACb,gBAAY,UAAU,OAAO,SAAS,OAAO,OAAO;AACpD,YAAQ,OAAO,UAAU,EAAE,QAAQ,CAAC;AAAA,EACtC;AACA,QAAM,mBAAmB,CAAC,SAAiB;AACzC,iBAAa;AACb,QAAI,cAAc,KAAM;AACxB,gBAAY,sBAAsB,MAAM;AACtC,kBAAY;AACZ,UAAI,eAAe,KAAM,SAAQ,OAAO,YAAY,EAAE,SAAS,MAAM,CAAC;AAAA,IACxE,CAAC;AAAA,EACH;AAEA,SAAO,iBAAiB,SAAS,MAAM;AACrC,QAAI,CAAC,WAAY,YAAW,cAAc,aAAa,QAAQ,WAAW,IAAI;AAAA,EAChF,CAAC;AACD,UAAQ,iBAAiB,SAAS,MAAM;AACtC,QAAI,CAAC,WAAY,YAAW,cAAc,aAAa,QAAQ,WAAW,IAAI;AAAA,EAChF,CAAC;AACD,QAAM,iBAAiB,SAAS,CAAC,UAAU;AACzC,QAAI,cAAc,UAAU,EAAG;AAC/B,UAAM,SAAS,aAAa,UAAU,aAAa,QAAQ;AAC3D,UAAM,SAAS,MAAM,sBAAsB;AAC3C,UAAM,QAAQ,KAAK,MAAM,UAAU,OAAO,OAAO,OAAO;AACxD,cAAU,OAAO,UAAU,MAAM,OAAO,GAAG,CAAC,KAAK,OAAO,UAAU,OAAO,UAAU,IAAI;AAAA,EACzF,CAAC;AACD,QAAM,iBAAiB,eAAe,CAAC,UAAU;AAC/C,QAAI,cAAc,CAAC,UAAU,EAAG;AAChC,UAAM,eAAe;AACrB,UAAM,gBAAgB;AACtB,UAAM,kBAAkB,MAAM,SAAS;AACvC,oBAAgB,MAAM;AACtB,iBAAa,MAAM;AACnB,oBAAgB,cAAc,aAAa;AAC3C,YAAQ,UAAU,IAAI,UAAU;AAAA,EAClC,CAAC;AACD,QAAM,iBAAiB,eAAe,CAAC,UAAU;AAC/C,QAAI,kBAAkB,MAAM,aAAa,eAAe,QAAQ,kBAAkB,KAAM;AACxF,UAAM,eAAe;AACrB,UAAM,SAAS,aAAa,UAAU,aAAa,QAAQ;AAC3D,UAAM,SAAU,aAAa,MAAM,WAAW,KAAK,IAAI,GAAG,MAAM,sBAAsB,EAAE,MAAM,KAC3F,OAAO,UAAU,OAAO;AAC3B,UAAM,WAAW,MAAM,gBAAgB,OAAO,OAAO,SAAS,OAAO,OAAO;AAC5E,gBAAY,UAAU,OAAO,SAAS,OAAO,OAAO;AACpD,qBAAiB,QAAQ;AAAA,EAC3B,CAAC;AACD,QAAM,aAAa,CAAC,UAAwB;AAC1C,QAAI,kBAAkB,MAAM,UAAW;AACvC,QAAI,MAAM,kBAAkB,MAAM,SAAS,EAAG,OAAM,sBAAsB,MAAM,SAAS;AACzF,oBAAgB;AAChB,iBAAa;AACb,oBAAgB;AAChB,YAAQ,UAAU,OAAO,UAAU;AAAA,EACrC;AACA,QAAM,iBAAiB,aAAa,UAAU;AAC9C,QAAM,iBAAiB,iBAAiB,UAAU;AAClD,QAAM,iBAAiB,sBAAsB,UAAU;AAEvD,SAAO;AAAA,IACL;AAAA,IACA,KAAK,OAAuB;AAC1B,qBAAe;AACf,mBAAa,MAAM;AACnB,YAAM,SAAS,aAAa,UAAU,MAAM,QAAQ;AACpD,kBAAY,MAAM,MAAM,OAAO,SAAS,OAAO,OAAO;AACtD,UAAI,kBAAkB,MAAM,QAAQ;AAClC,wBAAgB,MAAM;AACtB,cAAM,WAAW,YAAY,UAAU,MAAM,MAAM;AACnD,iBAAS,QAAQ,SAAS,MAAM;AAChC,iBAAS,SAAS,SAAS,OAAO;AAAA,MACpC;AACA,aAAO,WAAW,cAAc,MAAM,QAAQ,OAAO;AACrD,cAAQ,WAAW,cAAc,MAAM,QAAQ,OAAO;AAAA,IACxD;AAAA,IACA,UAAU;AACR,UAAI,eAAe,KAAM,sBAAqB,UAAU;AACxD,UAAI,cAAc,KAAM,sBAAqB,SAAS;AACtD,cAAQ,UAAU,OAAO,UAAU;AAAA,IACrC;AAAA,EACF;AACF;;;AE3IA,SAAS,gBAAAC,qBAAoB;;;ACA7B;;;ACAA;;;ACAA;;;ACAA;;;ACAA;;;ACMA,IAAM,QAAQ,CAAC,QAAwB,IAAI,QAAQ,mBAAmB,EAAE;AAEjE,IAAM,eAAiD,OAAO,OAAO;AAAA,EAC1E,UAAU,MAAM,gBAAO;AAAA,EACvB,QAAQ,MAAM,cAAM;AAAA,EACpB,SAAS,MAAM,eAAO;AAAA,EACtB,YAAY,MAAM,kBAAS;AAC7B,CAAC;AAEM,IAAM,aAAa,MAAM,aAAK;;;ANRrC,IAAM,cAAc,CAAC,MAAM,MAAM,MAAM,MAAM,KAAK,MAAM,MAAM,MAAM,IAAI;AAGxE,IAAM,qBAAqB,CAAC,cAAsC;AAChE,QAAM,UAAU,SAAS,cAAc,KAAK;AAC5C,UAAQ,YAAY;AACpB,UAAQ,WAAW;AACnB,UAAQ,aAAa,QAAQ,QAAQ;AACrC,SAAO;AACT;AAGA,IAAM,sBAAsB,CAAC,OAAoB,YAAkC;AACjF,QAAM,iBAAiB,gBAAgB,CAAC,UAAU;AAChD,QAAI,MAAM,gBAAgB,QAAS,SAAQ,OAAO,YAAY;AAAA,EAChE,CAAC;AACD,QAAM,iBAAiB,eAAe,CAAC,UAAU;AAC/C,QAAI,MAAM,gBAAgB,WAAW,MAAM,gBAAgB,MAAO,SAAQ,OAAO,OAAO,KAAK;AAAA,EAC/F,CAAC;AACD,QAAM,iBAAiB,WAAW,MAAM;AACtC,QAAI,MAAM,QAAQ,gBAAgB,KAAK,MAAM,cAAc,gBAAgB,EAAG,SAAQ,OAAO,OAAO,KAAK;AAAA,EAC3G,CAAC;AACD,QAAM,iBAAiB,YAAY,CAAC,UAAU;AAC5C,QAAI,EAAE,MAAM,yBAAyB,SAAS,CAAC,MAAM,SAAS,MAAM,aAAa,EAAG,SAAQ,OAAO,SAAS,KAAK;AAAA,EACnH,CAAC;AACH;AAGA,IAAM,oBAAoB,CAAC,WAAwB,WAA8B;AAC/E,YAAU,MAAM,YAAY,mBAAmB,OAAO,YAAY,OAAO,eAAe,CAAC;AAC3F;AAGO,IAAM,sBAAsB,CAAC,YAAgE;AAClG,QAAM,EAAE,UAAU,MAAM,IAAI;AAC5B,QAAM,UAAU,SAAS,cAAc,KAAK;AAC5C,UAAQ,YAAY;AACpB,QAAM,QAAQ,SAAS,cAAc,KAAK;AAC1C,QAAM,YAAY;AAClB,QAAM,aAAa,eAAe,MAAM;AACxC,QAAM,YAAY,SAAS,cAAc,KAAK;AAC9C,YAAU,YAAY;AACtB,UAAQ,OAAO,OAAO,SAAS;AAE/B,QAAM,WAAW,oBAAI,IAKlB;AAEH,aAAW,UAAU,SAAS,SAAS;AACrC,UAAM,eAAe,mBAAmB,wBAAwB;AAChE,iBAAa,QAAQ,SAAS,OAAO;AACrC,QAAI,OAAO,WAAW,SAAS,EAAG,qBAAoB,cAAc,OAAO;AAC3E,UAAM,OAAO,SAAS,cAAc,MAAM;AAC1C,SAAK,YAAY;AACjB,UAAM,SAAS,aAAa,OAAO,EAAE;AACrC,QAAI,CAAC,OAAQ,OAAM,IAAI,MAAM,8BAA8B,OAAO,EAAE,EAAE;AACtE,SAAK,YAAY;AACjB,iBAAa,OAAO,IAAI;AACxB,UAAM,eAAe,MAAM;AACzB,YAAM,SAAS,OAAO;AACtB,YAAM,EAAE,QAAQ,OAAO,IAAyB,WAAW,MAAM,OAAO,KAAK,QAAQ,EAAE,GAAG,OAAO,GAAG,GAAG,OAAO,EAAE,GAAG,MAAM,OAAO,KAAK,CAAC;AAAA,IACxI;AACA,iBAAa,iBAAiB,SAAS,YAAY;AACnD,iBAAa,iBAAiB,WAAW,CAAC,UAAU;AAClD,UAAI,MAAM,WAAW,aAAc;AACnC,UAAI,MAAM,QAAQ,WAAW,MAAM,QAAQ,IAAK;AAChD,YAAM,eAAe;AACrB,mBAAa;AAAA,IACf,CAAC;AACD,UAAM,oBAAoB,oBAAI,IAA+D;AAC7F,QAAI;AACJ,QAAI,OAAO,WAAW,SAAS,GAAG;AAChC,YAAM,QAAQ,SAAS,cAAc,KAAK;AAC1C,YAAM,YAAY;AAClB,YAAM,iBAAiB,SAAS,CAAC,UAAU,MAAM,gBAAgB,CAAC;AAClE,YAAM,OAAO,SAAS,cAAc,KAAK;AACzC,WAAK,YAAY;AACjB,2BAAqB,SAAS,cAAc,KAAK;AACjD,yBAAmB,YAAY;AAC/B,WAAK,OAAO,kBAAkB;AAC9B,iBAAW,aAAa,OAAO,YAAY;AACzC,cAAM,kBAAkB,aAAa,6BAA6B;AAClE,wBAAgB,QAAQ,YAAY,UAAU;AAC9C,wBAAgB,iBAAiB,SAAS,MAAM;AAC9C,kBAAQ,OAAO,SAAS,YAAY;AACpC,gBAAM,CAAC,CAAC,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,CAAC,IAAI,UAAU,UAAU;AAAA,YAC/C,CAAC,OAAO,YAAY,GAAG,OAAO,YAAY,CAAC;AAAA,YAC3C,CAAC,OAAO,YAAY,GAAG,OAAO,YAAY,CAAC;AAAA,UAC7C;AACA,gBAAM;AAAA,YACJ,QAAQ,OAAO;AAAA,YACf,WAAW,UAAU;AAAA,YACrB,OAAO;AAAA,YACP,QAAQ,EAAE,IAAI,KAAK,MAAM,GAAG,IAAI,KAAK,MAAM,EAAE;AAAA,YAC7C,MAAM,KAAK,IAAI,OAAO,SAAS,KAAK,IAAI,OAAO,SAAS,CAAC,CAAC;AAAA,UAC5D,CAAC;AAAA,QACH,CAAC;AACD,0BAAkB,IAAI,UAAU,IAAI,EAAE,MAAM,WAAW,QAAQ,gBAAgB,CAAC;AAChF,aAAK,OAAO,eAAe;AAAA,MAC7B;AACA,YAAM,OAAO,IAAI;AACjB,mBAAa,OAAO,KAAK;AAAA,IAC3B;AACA,aAAS,IAAI,OAAO,IAAI,EAAE,QAAQ,QAAQ,cAAc,YAAY,mBAAmB,mBAAmB,CAAC;AAC3G,YAAQ,OAAO,YAAY;AAAA,EAC7B;AAEA,MAAI,WAAW;AACf,SAAO;AAAA,IACL;AAAA,IACA,KAAK,OAAuB;AAC1B,YAAM,UAAU,GAAG,MAAM,MAAM,KAAK,MAAM,QAAQ,KAAK,MAAM,eAAe,EAAE;AAC9E,UAAI,YAAY,UAAU;AACxB,mBAAW;AACX,mBAAW,CAAC,UAAU,OAAO,KAAK,UAAU;AAC1C,gBAAM,aAAa,QAAQ,OAAO,QAAQ,MAAM,MAAM,KAAK,QAAQ,OAAO,QAAQ,SAAS,cAAc,KAAK,QAAQ,OAAO;AAC7H,kBAAQ,OAAO,UAAU,OAAO,YAAY,aAAa,MAAM,QAAQ;AACvE,mBAAS,QAAQ,QAAQ,UAAU;AACnC,qBAAW,CAAC,aAAa,SAAS,KAAK,QAAQ,YAAY;AACzD,kBAAM,YAAY,UAAU,KAAK,UAAU,MAAM,MAAM,KAAK,UAAU,KAAK,UAAU,SAAS,cAAc;AAC5G,sBAAU,OAAO,cAAc,WAAW,SAAS,UAAU,KAAK;AAClE,qBAAS,UAAU,QAAQ,WAAW,QAAQ,UAAU,KAAK,GAAG;AAChE,sBAAU,OAAO,UAAU,OAAO,YAAY,gBAAgB,MAAM,WAAW;AAAA,UACjF;AAAA,QACF;AAAA,MACF;AACA,iBAAW,WAAW,SAAS,OAAO,GAAG;AACvC,cAAM,oBAAoB,MAAM,cAAc,QAAQ,WAAW,IAAI,MAAM,WAAW,IAAI;AAC1F,YAAI,QAAQ,oBAAoB;AAC9B,kBAAQ,mBAAmB,UAAU,OAAO,UAAU,CAAC,iBAAiB;AACxE,cAAI,kBAAmB,mBAAkB,QAAQ,oBAAoB,kBAAkB,MAAM;AAAA,QAC/F;AAAA,MACF;AACA,YAAM,kBAAkB,SAAS,IAAI,MAAM,QAAQ;AACnD,UAAI,gBAAiB,mBAAkB,WAAW,gBAAgB,MAAM;AAAA,IAC1E;AAAA,EACF;AACF;AAGO,IAAM,qBAAqB,CAAC,YAAgE;AACjG,QAAM,EAAE,UAAU,MAAM,IAAI;AAC5B,QAAM,UAAU,SAAS,cAAc,KAAK;AAC5C,UAAQ,YAAY;AACpB,QAAM,QAAQ,SAAS,cAAc,KAAK;AAC1C,QAAM,YAAY;AAClB,QAAM,aAAa,eAAe,MAAM;AACxC,QAAM,aAAa,mBAAmB,YAAY;AAClD,sBAAoB,YAAY,OAAO;AACvC,QAAM,OAAO,SAAS,cAAc,MAAM;AAC1C,OAAK,YAAY;AACjB,OAAK,YAAY;AACjB,QAAM,QAAQ,SAAS,cAAc,KAAK;AAC1C,QAAM,YAAY;AAClB,QAAM,iBAAiB,SAAS,CAAC,UAAU,MAAM,gBAAgB,CAAC;AAClE,QAAM,OAAO,SAAS,cAAc,KAAK;AACzC,OAAK,YAAY;AACjB,QAAM,OAAO,IAAI;AACjB,aAAW,OAAO,MAAM,KAAK;AAC7B,UAAQ,OAAO,OAAO,UAAU;AAChC,aAAW,iBAAiB,WAAW,CAAC,UAAU;AAChD,QAAI,MAAM,WAAW,cAAe,MAAM,QAAQ,WAAW,MAAM,QAAQ,IAAM;AACjF,UAAM,eAAe;AACrB,eAAW,MAAM;AAAA,EACnB,CAAC;AACD,QAAM,YAAY,SAAS,cAAc,KAAK;AAC9C,YAAU,YAAY;AACtB,QAAM,eAAe,oBAAI,IAA+B;AACxD,MAAI,gBAAgB;AACpB,MAAI,gBAAgB;AACpB,MAAI,eAAe;AACnB,aAAW,iBAAiB,SAAS,MAAM;AACzC,QAAI,iBAAiB,IAAK,OAAM,EAAE,OAAO,IAAI,CAAC;AAAA,EAChD,CAAC;AAED,SAAO;AAAA,IACL;AAAA,IACA,KAAK,OAAuB;AAC1B,YAAM,SAASC,cAAa,UAAU,MAAM,QAAQ;AACpD,UAAI,kBAAkB,OAAO,IAAI;AAC/B,wBAAgB,OAAO;AACvB,qBAAa,MAAM;AACnB,aAAK,gBAAgB,SAAS;AAC9B,cAAM,SAAS,CAAC,GAAG,OAAO,MAAM,EAAE,KAAK,CAAC,MAAM,UAAU,YAAY,QAAQ,KAAK,EAAE,IAAI,YAAY,QAAQ,MAAM,EAAE,CAAC;AACpH,gBAAQ,SAAS,OAAO,UAAU;AAClC,mBAAW,SAAS,QAAQ;AAC1B,gBAAM,SAAS,aAAa,yBAAyB;AACrD,iBAAO,cAAc,MAAM;AAC3B,iBAAO,iBAAiB,SAAS,MAAM;AACrC,oBAAQ,OAAO,SAAS,UAAU;AAClC,kBAAM,EAAE,OAAO,MAAM,GAAiB,CAAC;AAAA,UACzC,CAAC;AACD,uBAAa,IAAI,MAAM,IAAI,MAAM;AACjC,eAAK,OAAO,MAAM;AAAA,QACpB;AACA,wBAAgB;AAAA,MAClB;AACA,UAAI,kBAAkB,MAAM,QAAQ;AAClC,wBAAgB,MAAM;AACtB,cAAM,WAAW,YAAY,UAAU,MAAM,MAAM;AACnD,iBAAS,YAAY,SAAS,WAAW;AACzC,mBAAW,CAAC,SAAS,MAAM,KAAK,aAAc,UAAS,QAAQ,GAAG,SAAS,WAAW,KAAK,OAAO,EAAE;AAAA,MACtG;AACA,UAAI,iBAAiB,MAAM,QAAS,cAAa,IAAI,YAAY,GAAG,UAAU,OAAO,UAAU;AAC/F,qBAAe,MAAM;AACrB,iBAAW,UAAU,OAAO,YAAY,iBAAiB,GAAG;AAC5D,YAAM,iBAAiB,aAAa,IAAI,YAAY;AACpD,sBAAgB,UAAU,IAAI,UAAU;AACxC,UAAI,eAAgB,mBAAkB,WAAW,cAAc;AAAA,IACjE;AAAA,EACF;AACF;;;AOxNO,IAAM,gBAAgB,CAC3B,MACA,YACA,YACY;AACZ,QAAM,cAAc,WAAW,kBAAkB,WAAW;AAC5D,MAAI,CAAC,eAAe,CAAC,WAAW,SAAU,QAAO,EAAE,MAAM,MAAM;AAAA,EAAC,EAAE;AAElE,QAAM,UAAU,SAAS,cAAc,KAAK;AAC5C,UAAQ,YAAY;AACpB,OAAK,OAAO,OAAO;AACnB,QAAM,aAAwB,CAAC;AAC/B,MAAI,gBAAoC;AACxC,QAAM,SAAiB;AAAA,IACrB,OAAO,OAAO;AACZ,UAAI,kBAAkB,MAAO;AAC7B,qBAAe,UAAU,OAAO,UAAU;AAC1C,sBAAgB;AAChB,oBAAc,UAAU,IAAI,UAAU;AAAA,IACxC;AAAA,IACA,SAAS,OAAO;AACd,YAAM,UAAU,OAAO,UAAU;AACjC,UAAI,kBAAkB,MAAO,iBAAgB;AAAA,IAC/C;AAAA,IACA,cAAc;AACZ,qBAAe,UAAU,OAAO,UAAU;AAC1C,sBAAgB;AAAA,IAClB;AAAA,EACF;AACA,QAAM,iBAAiC,EAAE,GAAG,SAAS,OAAO;AAC5D,MAAI,eAAsC;AAC1C,QAAM,uBAAuB,CAAC,UAAwB;AACpD,QAAI,iBAAiB,MAAM,kBAAkB,QAAQ,CAAC,cAAc,SAAS,MAAM,MAAM,EAAG,QAAO,YAAY;AAAA,EACjH;AACA,MAAI,YAAa,UAAS,iBAAiB,eAAe,sBAAsB,IAAI;AACpF,QAAM,WAAW,CAAC,eAAe,OAAO,mBAAmB,cAAc,OAAO,IAAI,eAAe,MAAM;AACvG,QAAI,aAAc,YAAW,aAAa,WAAY,WAAU,KAAK,YAAY;AAAA,EACnF,CAAC;AACD,YAAU,QAAQ,IAAI;AAEtB,MAAI,aAAa;AACf,UAAM,aAAa,SAAS,cAAc,KAAK;AAC/C,eAAW,YAAY;AACvB,QAAI,WAAW,gBAAgB;AAC7B,YAAM,SAAS,oBAAoB,cAAc;AACjD,iBAAW,KAAK,MAAM;AACtB,iBAAW,OAAO,OAAO,OAAO;AAAA,IAClC;AACA,QAAI,WAAW,eAAe;AAC5B,YAAM,QAAQ,mBAAmB,cAAc;AAC/C,iBAAW,KAAK,KAAK;AACrB,iBAAW,OAAO,MAAM,OAAO;AAAA,IACjC;AACA,YAAQ,OAAO,UAAU;AAAA,EAC3B;AAEA,MAAI,WAAW,UAAU;AACvB,UAAM,QAAQ,mBAAmB,cAAc;AAC/C,eAAW,KAAK,KAAK;AACrB,YAAQ,OAAO,MAAM,OAAO;AAAA,EAC9B;AAEA,SAAO;AAAA,IACL,KAAK,OAAuB;AAC1B,qBAAe;AACf,iBAAW,aAAa,WAAY,WAAU,KAAK,KAAK;AAAA,IAC1D;AAAA,IACA,UAAU;AACR,UAAI,YAAa,UAAS,oBAAoB,eAAe,sBAAsB,IAAI;AACvF,gBAAU,WAAW;AACrB,aAAO,YAAY;AACnB,iBAAW,aAAa,WAAY,WAAU,UAAU;AAAA,IAC1D;AAAA,EACF;AACF;;;AC/EA,SAAS,uBAAuB;AAGhC,IAAM,gBAAgB,oBAAI,IAAI;AAAA,EAC5B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAEM,IAAM,eAAe,CAAC,MAAmB,UAAuB,cAAkC;AACvG,MAAI,CAAC,SAAS,OAAO,OAAQ;AAC7B,QAAM,QAAQ,SAAS,MAAM,IAAI,CAAC,SAAS;AACzC,QAAI,CAAC,cAAc,IAAI,KAAK,MAAM,KAAK,CAAC,OAAO,SAAS,KAAK,MAAM,KAChE,KAAK,gBAAgB,CAAC,OAAO,SAAS,KAAK,YAAY,CAAC,CAAC,KAAK,CAAC,OAAO,SAAS,KAAK,YAAY,CAAC,CAAC,KACjG,KAAK,YAAY,CAAC,IAAI,KAAK,YAAY,CAAC,IAAK;AAC/C,YAAM,IAAI,MAAM,yBAAyB,KAAK,MAAM,EAAE;AAAA,IACxD;AACA,UAAM,MAAM,gBAAgB,UAAU,SAAS,KAAK,IAAI;AACxD,UAAM,SAAS,KAAK,cAAc,GAAG,KAAK,YAAY,CAAC,CAAC,IAAI,KAAK,YAAY,CAAC,CAAC,KAAK,OAAO,KAAK,MAAM;AACtG,WAAO,0BAA0B,KAAK,UAAU,KAAK,MAAM,CAAC,YAAY,KAAK,UAAU,GAAG,CAAC,gCAAgC,KAAK,KAAK,gBAAgB,MAAM;AAAA,EAC7J,CAAC;AACD,QAAM,QAAQ,SAAS,cAAc,OAAO;AAC5C,QAAM,QAAQ,WAAW,SAAS;AAClC,QAAM,cAAc,MAAM,KAAK,EAAE;AACjC,OAAK,OAAO,KAAK;AACnB;;;AXNA,IAAM,iBAAmD,OAAO,OAAO;AAAA,EACrE,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AACN,CAAC;AAED,IAAM,UAAU,oBAAI,QAAqB;AAEzC,IAAM,aAAa,CAAC,WAA2C;AAAA,EAC7D,GAAG;AAAA,EACH,aAAa,MAAM,gBAAgB,MAAM,MAAM,CAAC,GAAG,MAAM,WAAW;AAAA,EACpE,QAAQ,EAAE,GAAG,MAAM,OAAO;AAC5B;AAEA,IAAM,cAAc,CAAC,YAA8C;AAAA,EACjE,GAAG;AAAA,EACH,aAAa,MAAM,QAAQ,OAAO,WAAW,IAAI,CAAC,GAAG,OAAO,WAAW,IAAI,OAAO;AAAA,EAClF,cAAc,OAAO,cAAc,IAAI,CAAC,WAAW,EAAE,GAAG,OAAO,UAAU,EAAE,GAAG,MAAM,SAAS,EAAE,EAAE;AAAA,EACjG,QAAQ,OAAO,SAAS,EAAE,GAAG,OAAO,OAAO,IAAI,OAAO;AACxD;AAEA,IAAM,mBAAmB,CAAC,cAAiD;AACzE,QAAM,UAAU,OAAO,cAAc,WAAW,SAAS,cAA2B,SAAS,IAAI;AACjG,MAAI,CAAC,QAAS,OAAM,IAAI,MAAM,mCAAmC,SAAS,EAAE;AAC5E,SAAO;AACT;AAEA,IAAM,kBAAkB,CAAC,UAAuB,UAAgC;AAC9E,QAAM,YAAY,QAAQ,eAAe,MAAM,YAAY,CAAC,KAAK,QAAQ,SAAS;AAClF,SAAOC,cAAa,UAAU,SAAS,EAAE;AAC3C;AAEA,IAAM,uBAAuB,CAAC,UAA0D;AACtF,MAAI,UAAU,IAAK,QAAO;AAC1B,MAAI,CAAC,SAAS,CAAC,MAAM,QAAQ,KAAK,EAAG,QAAO,CAAC;AAC7C,SAAO,CAAC,GAAG,IAAI,IAAI,MAAM,IAAI,CAAC,UAAU,MAAM,KAAK,CAAC,EAAE,OAAO,OAAO,CAAC,CAAC;AACxE;AAEA,IAAM,0BAA0B,CAAC,UAA+E;AAC9G,MAAI,UAAU,UAAa,UAAU,MAAO,QAAO;AACnD,MAAI,UAAU,OAAQ,QAAO;AAC7B,QAAM,IAAI,MAAM,gCAAgC,KAAK,EAAE;AACzD;AAEA,IAAM,YAAY,CAAC,QAAmB,cAA6B;AACjE,MAAI,CAAC,WAAW,QAAQ;AACtB,WAAO;AAAA,MACL,QAAQ,EAAE,GAAG,OAAO,YAAY,GAAG,GAAG,OAAO,YAAY,EAAE;AAAA,MAC3D,MAAM,OAAO,YAAY;AAAA,IAC3B;AAAA,EACF;AACA,SAAO;AAAA,IACL,QAAQ;AAAA,MACN,IAAI,UAAU,OAAO,CAAC,EAAE,CAAC,IAAI,UAAU,OAAO,CAAC,EAAE,CAAC,KAAK;AAAA,MACvD,IAAI,UAAU,OAAO,CAAC,EAAE,CAAC,IAAI,UAAU,OAAO,CAAC,EAAE,CAAC,KAAK;AAAA,IACzD;AAAA,IACA,MAAM,KAAK,IAAI,OAAO,SAAS,KAAK,IAAI,OAAO,SAAS,CAAC,CAAC;AAAA,EAC5D;AACF;AAEA,IAAM,iBAAiB,CAAC,OAAwB,aAA0C;AACxF,MAAI,WAAW,gBAAgB,UAAU,MAAM,MAAM;AACrD,QAAM,cAAc,MAAM,WAAW,KAAK,KAAK;AAC/C,MAAI,aAAa;AACf,UAAM,QAAQ,SAAS,QAAQ,KAAK,CAACC,YAAWA,QAAO,WAAW,KAAK,CAACC,eAAcA,WAAU,OAAO,WAAW,CAAC;AACnH,QAAI,CAAC,MAAO,OAAM,IAAI,MAAM,0BAA0B,WAAW,EAAE;AACnE,QAAI,MAAM,UAAU,MAAM,OAAO,UAAU;AACzC,YAAM,IAAI,MAAM,iBAAiB,WAAW,uBAAuB,QAAQ,EAAE;AAAA,IAC/E;AACA,eAAW,MAAM;AAAA,EACnB;AAEA,QAAM,SAASF,cAAa,UAAU,QAAQ;AAC9C,QAAM,YAAY,cACd,OAAO,WAAW,KAAK,CAAC,UAAU,MAAM,OAAO,WAAW,IAC1D;AACJ,QAAM,UAAW,MAAM,SAAS;AAChC,MAAI,CAAC,OAAO,OAAO,KAAK,CAAC,UAAU,MAAM,OAAO,OAAO,GAAG;AACxD,UAAM,IAAI,MAAM,qBAAqB,OAAO,OAAO,QAAQ,EAAE;AAAA,EAC/D;AAEA,QAAM,kBAAkB,MAAM;AAC9B,MAAI,oBAAoB,CAAC,OAAO,SAAS,gBAAgB,CAAC,KAAK,CAAC,OAAO,SAAS,gBAAgB,CAAC,IAAI;AACnG,UAAM,IAAI,MAAM,8CAA8C;AAAA,EAChE;AACA,QAAM,SAAS,UAAU,QAAQ,SAAS;AAC1C,QAAM,kBAAkB,MAAM,WAAW,OAAO,cAAc,cAAc,SAAS,iBAAiB,UAAU;AAEhH,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA,QAAQ,mBAAmB,iBAAiB,OAAO,KAAK,SAAS,OAAO,GAAG,SAAS,cAAc;AAAA,IAClG,aAAa,qBAAqB,MAAM,WAAW;AAAA,IACnD,QAAQ,MAAM,UAAU;AAAA,IACxB,YAAY,MAAM,cAAc;AAAA,IAChC,gBAAgB,wBAAwB,MAAM,cAAc;AAAA,IAC5D,kBAAkB,MAAM,oBAAoB;AAAA,IAC5C,MAAM,KAAK,IAAI,OAAO,SAAS,KAAK,IAAI,OAAO,SAAS,MAAM,QAAQ,OAAO,IAAI,CAAC;AAAA,IAClF,QAAQ;AAAA,MACN,GAAG,iBAAiB,KAAK,OAAO,OAAO;AAAA,MACvC,GAAG,iBAAiB,KAAK,OAAO,OAAO;AAAA,IACzC;AAAA,EACF;AACF;AAEA,IAAM,WAAW,CAAC,WAA4C;AAAA,EAC5D,QAAQ,MAAM;AAAA,EACd,WAAW,MAAM;AAAA,EACjB,OAAO,MAAM;AAAA,EACb,QAAQ,MAAM;AAAA,EACd,aAAa,MAAM;AAAA,EACnB,QAAQ,MAAM;AAAA,EACd,YAAY,MAAM;AAAA,EAClB,gBAAgB,MAAM;AAAA,EACtB,kBAAkB,MAAM;AAAA,EACxB,MAAM,MAAM;AAAA,EACZ,QAAQ,EAAE,GAAG,MAAM,OAAO;AAC5B;AAEA,IAAM,cAAc,CAAC,MAAqC,UACxD,SAAS,SAAU,SAAS,OAAO,UAAU,OAAO,KAAK,WAAW,MAAM,UACxE,KAAK,MAAM,CAAC,QAAQ,UAAU,WAAW,MAAM,KAAK,CAAC;AAEzD,IAAM,YAAY,CAAC,MAAsB,UACvC,KAAK,aAAa,MAAM,YACxB,KAAK,gBAAgB,MAAM,eAC3B,KAAK,YAAY,MAAM,WACvB,KAAK,WAAW,MAAM,UACtB,YAAY,KAAK,aAAa,MAAM,WAAW,KAC/C,KAAK,WAAW,MAAM,UACtB,KAAK,eAAe,MAAM,cAC1B,KAAK,mBAAmB,MAAM,kBAC9B,KAAK,qBAAqB,MAAM,oBAChC,KAAK,SAAS,MAAM,QACpB,KAAK,OAAO,MAAM,MAAM,OAAO,KAC/B,KAAK,OAAO,MAAM,MAAM,OAAO;AAEjC,IAAM,aAAa,CAAC,UAClB,MAAM,gBAAgB,OAAO,MAAM,YAAY,SAAS;AAE1D,IAAM,SAAN,MAAkC;AAAA,EAUhC,YACU,MACA,MACA,MACA,UACA,SACA,OACR;AANQ;AACA;AACA;AACA;AACA;AACA;AAER,SAAK,kBAAkB,QAAQ;AAC/B,SAAK,WAAW,cAAc,MAAM;AAAA,MAClC,gBAAgB,QAAQ,sBAAsB;AAAA,MAC9C,eAAe,QAAQ,qBAAqB;AAAA,MAC5C,UAAU,QAAQ,gBAAgB;AAAA,IACpC,GAAG;AAAA,MACD;AAAA,MACA,YAAY,QAAQ,YAAY;AAAA,MAChC,OAAO,CAAC,WAAW;AACjB,aAAK,KAAK,WAAW,MAAM,EAAE,MAAM,CAAC,UAAmB,KAAK,OAAO,KAAK,CAAC;AAAA,MAC3E;AAAA,MACA,QAAQ,CAAC,MAAM,gBAAgB,KAAK,QAAQ,MAAM,WAAW;AAAA,IAC/D,CAAC;AACD,SAAK,SAAS,KAAK,KAAK;AACxB,SAAK,kBAAkB,KAAK,GAAG,cAAc,KAAK,QAAQ;AAC1D,SAAK,mBAAmB,KAAK,GAAG,SAAS,KAAK,YAAY;AAC1D,YAAQ,QAAQ,iBAAiB,SAAS,KAAK,SAAS,EAAE,MAAM,KAAK,CAAC;AAAA,EACxE;AAAA,EAlCA,YAAY;AAAA,EACJ,WAAW;AAAA,EACX,UAAU,QAAQ,QAAQ;AAAA,EAC1B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,YAAY,oBAAI,IAA0D;AAAA,EA6B1E,cAAoB;AAC1B,QAAI,KAAK,UAAW,OAAM,IAAI,MAAM,+BAA+B;AAAA,EACrE;AAAA,EAEQ,OAAO,OAAsB;AACnC,SAAK,QAAQ,UAAU,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,OAAO,KAAK,CAAC,CAAC;AAAA,EAClF;AAAA,EAEQ,SAAe;AACrB,SAAK,QAAQ,gBAAgB,WAAW,KAAK,KAAK,CAAC;AAAA,EACrD;AAAA,EAEQ,KAA0C,OAAc,SAAuC;AACrG,SAAK,UAAU,IAAI,KAAK,GAAG,QAAQ,CAAC,YAAY,QAAQ,OAAgB,CAAC;AAAA,EAC3E;AAAA,EAEQ,eAAe,CAAC,YAA+B;AACrD,QAAI,CAAC,KAAK,UAAW,MAAK,KAAK,SAAS,OAAO;AAAA,EACjD;AAAA,EAEQ,WAAW,MAAY;AAC7B,QAAI,KAAK,aAAa,KAAK,SAAU;AACrC,UAAM,OAAO,KAAK,KAAK,QAAQ;AAC/B,SAAK,QAAQ;AAAA,MACX,GAAG,KAAK;AAAA,MACR,UAAU,KAAK;AAAA,MACf,SAAU,KAAK,WAAW;AAAA,MAC1B,QAAQ,KAAK,KAAK,UAAU,EAAE;AAAA,MAC9B,QAAQ,EAAE,GAAG,KAAK,GAAG,GAAG,KAAK,EAAE;AAAA,MAC/B,MAAM,KAAK;AAAA,IACb;AACA,SAAK,SAAS,KAAK,KAAK,KAAK;AAC7B,SAAK,OAAO;AAAA,EACd;AAAA,EAEA,WAA2B;AACzB,SAAK,YAAY;AACjB,WAAO,WAAW,KAAK,KAAK;AAAA,EAC9B;AAAA,EAEA,gBAAgB,QAAyC;AACvD,SAAK,YAAY;AACjB,SAAK,KAAK,gBAAgB,MAAM;AAChC,SAAK,kBAAkB;AAAA,EACzB;AAAA,EAEA,kBAAkB,SAA6C;AAC7D,SAAK,YAAY;AACjB,SAAK,KAAK,kBAAkB,OAAO;AAAA,EACrC;AAAA,EAEA,mBAAyB;AACvB,SAAK,YAAY;AACjB,SAAK,KAAK,iBAAiB;AAAA,EAC7B;AAAA,EAEA,MAAM,iBAAiB,KAA4B;AACjD,SAAK,YAAY;AACjB,UAAM,KAAK,KAAK,iBAAiB,GAAG;AACpC,SAAK,kBAAkB;AAAA,EACzB;AAAA,EAEA,oBAA0B;AACxB,SAAK,YAAY;AACjB,SAAK,KAAK,kBAAkB;AAAA,EAC9B;AAAA,EAEA,SAAS,SAAiB;AACxB,SAAK,YAAY;AACjB,WAAO,KAAK,KAAK,SAAS,OAAO;AAAA,EACnC;AAAA,EAEA,UAAU,SAAiB;AACzB,SAAK,YAAY;AACjB,WAAO,KAAK,KAAK,UAAU,OAAO;AAAA,EACpC;AAAA,EAEA,GAAwC,OAAc,SAAgE;AACpH,SAAK,YAAY;AACjB,UAAM,WAAW,KAAK,UAAU,IAAI,KAAK,KAAK,oBAAI,IAAI;AACtD,aAAS,IAAI,OAAmC;AAChD,SAAK,UAAU,IAAI,OAAO,QAAQ;AAClC,WAAO,MAAM;AAAE,eAAS,OAAO,OAAmC;AAAA,IAAG;AAAA,EACvE;AAAA,EAEA,WAAW,QAAwC;AACjD,SAAK,YAAY;AACjB,UAAM,WAAW,YAAY,MAAM;AACnC,UAAM,YAAY,KAAK,QAAQ,KAAK,MAAM,KAAK,aAAa,QAAQ,CAAC;AACrE,SAAK,UAAU,UAAU,MAAM,MAAM,MAAS;AAC9C,WAAO;AAAA,EACT;AAAA,EAEA,MAAc,aAAa,QAAwC;AACjE,SAAK,YAAY;AACjB,UAAM,UAAU,OAAO;AAAA,MACrB,OAAO,QAAQ,MAAM,EAAE,OAAO,CAAC,CAAC,EAAE,KAAK,MAAM,UAAU,MAAS;AAAA,IAClE;AACA,UAAM,SAA0B,EAAE,GAAG,SAAS,KAAK,KAAK,GAAG,GAAG,QAAQ;AACtE,UAAM,eAAe,gBAAgB,KAAK,UAAU,QAAQ,UAAU,KAAK,MAAM,QAAQ;AAEzF,QAAI,iBAAiB,KAAK,MAAM,UAAU;AACxC,YAAM,SAAS,UAAUA,cAAa,KAAK,UAAU,YAAY,CAAC;AAClE,UAAI,QAAQ,UAAU,OAAW,QAAO,QAAQ;AAChD,UAAI,QAAQ,cAAc,OAAW,QAAO,YAAY;AACxD,UAAI,QAAQ,WAAW,OAAW,QAAO,SAAS,OAAO;AACzD,UAAI,QAAQ,SAAS,OAAW,QAAO,OAAO,OAAO;AAAA,IACvD;AAEA,QAAI,QAAQ,cAAc,UAAa,QAAQ,cAAc,KAAK,MAAM,aAAa;AACnF,YAAM,SAASA,cAAa,KAAK,UAAU,YAAY;AACvD,YAAM,YAAY,QAAQ,YACtB,OAAO,WAAW,KAAK,CAAC,UAAU,MAAM,OAAO,QAAQ,SAAS,IAChE;AACJ,YAAM,SAAS,UAAU,QAAQ,SAAS;AAC1C,UAAI,QAAQ,WAAW,OAAW,QAAO,SAAS,OAAO;AACzD,UAAI,QAAQ,SAAS,OAAW,QAAO,OAAO,OAAO;AAAA,IACvD;AAEA,UAAM,WAAW,KAAK;AACtB,UAAM,OAAO,eAAe,QAAQ,KAAK,QAAQ;AACjD,QAAI,QAAQ,iBAAiB,UAAa,QAAQ,oBAAoB,QAAW;AAC/E,YAAM,IAAI,MAAM,uDAAuD;AAAA,IACzE;AACA,UAAM,sBAAsB,QAAQ,iBAAiB,UAAa,QAAQ,oBAAoB;AAC9F,QAAI,UAAU,UAAU,IAAI,KAAK,CAAC,oBAAqB;AAEvD,UAAM,gBAAgB,KAAK,aAAa,SAAS;AACjD,UAAM,gBAAgB,KAAK,gBAAgB,SAAS,eAClD,CAAC,YAAY,KAAK,aAAa,SAAS,WAAW;AACrD,UAAM,cAAc,iBAClB,KAAK,YAAY,SAAS,WAC1B,KAAK,SAAS,SAAS,QACvB,KAAK,OAAO,MAAM,SAAS,OAAO,KAClC,KAAK,OAAO,MAAM,SAAS,OAAO;AACpC,UAAM,kBAAkB,WAAW,QAAQ;AAC3C,UAAM,cAAc,WAAW,IAAI;AAEnC,SAAK,WAAW;AAChB,SAAK,KAAK,UAAU,IAAI,SAAS;AACjC,QAAI;AACF,UAAI,QAAQ,iBAAiB,QAAW;AACtC,aAAK,KAAK,gBAAgB,QAAQ,YAAY;AAC9C,aAAK,kBAAkB;AAAA,MACzB,WAAW,QAAQ,oBAAoB,QAAW;AAChD,cAAM,KAAK,KAAK,iBAAiB,QAAQ,eAAe;AACxD,aAAK,kBAAkB,QAAQ;AAAA,MACjC;AACA,UAAI,mBAAmB,CAAC,YAAa,OAAM,KAAK,KAAK,YAAY,EAAE,QAAQ,MAAM,CAAC;AAClF,UAAI,eAAe;AACjB,aAAK,KAAK,eAAe;AAAA,UACvB,OAAO,KAAK,gBAAgB,MAAM,SAAY,KAAK;AAAA,UACnD,YAAY,KAAK,cAAc,CAAC,KAAK,WAAW,IAAI;AAAA,QACtD,CAAC;AAAA,MACH;AACA,UAAI,cAAe,OAAM,KAAK,KAAK,UAAU,KAAK,QAAQ;AAC1D,UAAI,KAAK,WAAW,SAAS,OAAQ,OAAM,KAAK,KAAK,UAAU,KAAK,MAAM;AAC1E,UAAI,KAAK,YAAY,SAAS,QAAS,MAAK,KAAK,SAAS,KAAK,OAAO;AACtE,UAAI,KAAK,qBAAqB,SAAS,kBAAkB;AACvD,aAAK,KAAK,oBAAoB,KAAK,gBAAgB;AAAA,MACrD;AACA,UAAI,gBAAgB,mBAClB,KAAK,WAAW,SAAS,UACzB,KAAK,eAAe,SAAS,cAC7B,KAAK,mBAAmB,SAAS,gBAAgB;AACjD,cAAM,KAAK,KAAK,YAAY;AAAA,UAC1B,QAAQ;AAAA,UACR,QAAQ,KAAK;AAAA,UACb,YAAY,KAAK;AAAA,UACjB,gBAAgB,KAAK;AAAA,QACvB,CAAC;AAAA,MACH;AACA,UAAI,aAAa;AACf,aAAK,KAAK,QAAQ;AAAA,UAChB,UAAU,KAAK;AAAA,UACf,SAAS,KAAK;AAAA,UACd,GAAG,KAAK,OAAO;AAAA,UACf,GAAG,KAAK,OAAO;AAAA,UACf,MAAM,KAAK;AAAA,QACb,CAAC;AAAA,MACH;AACA,YAAM,OAAO,KAAK,KAAK,QAAQ;AAC/B,WAAK,QAAQ;AAAA,QACX,GAAG;AAAA,QACH,QAAQ,KAAK,KAAK,UAAU,EAAE;AAAA,QAC9B,QAAQ,EAAE,GAAG,KAAK,GAAG,GAAG,KAAK,EAAE;AAAA,QAC/B,MAAM,KAAK;AAAA,MACb;AACA,WAAK,SAAS,KAAK,KAAK,KAAK;AAAA,IAC/B,UAAE;AACA,WAAK,WAAW;AAChB,WAAK,KAAK,UAAU,OAAO,SAAS;AAAA,IACtC;AACA,SAAK,OAAO;AAAA,EACd;AAAA,EAEA,SAAe;AACb,SAAK,YAAY;AACjB,SAAK,KAAK,OAAO;AAAA,EACnB;AAAA,EAEA,UAAU,MAAY;AACpB,QAAI,KAAK,UAAW;AACpB,SAAK,YAAY;AACjB,SAAK,gBAAgB;AACrB,SAAK,iBAAiB;AACtB,SAAK,UAAU,MAAM;AACrB,SAAK,SAAS,UAAU;AACxB,SAAK,QAAQ,QAAQ,oBAAoB,SAAS,KAAK,OAAO;AAC9D,SAAK,KAAK,QAAQ;AAClB,SAAK,KAAK,OAAO;AACjB,YAAQ,OAAO,KAAK,IAAI;AAAA,EAC1B;AACF;AAGA,eAAsB,gBACpB,WACA,UAA4B,CAAC,GACT;AACpB,MAAI,OAAO,aAAa,YAAa,OAAM,IAAI,MAAM,uCAAuC;AAC5F,MAAI,QAAQ,iBAAiB,UAAa,QAAQ,oBAAoB,QAAW;AAC/E,UAAM,IAAI,MAAM,uDAAuD;AAAA,EACzE;AACA,UAAQ,QAAQ,eAAe;AAC/B,QAAM,OAAO,iBAAiB,SAAS;AACvC,MAAI,QAAQ,IAAI,IAAI,EAAG,OAAM,IAAI,MAAM,4CAA4C;AAEnF,QAAM,OAAO,SAAS,cAAc,KAAK;AACzC,OAAK,YAAY;AACjB,MAAI,QAAQ,UAAW,MAAK,UAAU,IAAI,GAAG,QAAQ,UAAU,MAAM,KAAK,EAAE,OAAO,OAAO,CAAC;AAC3F,OAAK,QAAQ,QAAQ,QAAQ,SAAS;AACtC,QAAM,UAAU,SAAS,cAAc,KAAK;AAC5C,UAAQ,YAAY;AACpB,OAAK,OAAO,OAAO;AACnB,OAAK,OAAO,IAAI;AAChB,UAAQ,IAAI,IAAI;AAEhB,MAAI;AACJ,MAAI;AACJ,MAAI;AACF,UAAM,YAA0B,QAAQ,aAAa;AACrD,UAAM,WAAW,QAAQ,WACrB,oBAAoB,QAAQ,QAAQ,IACpC,MAAM,gBAAgB,WAAW,QAAQ,MAAM;AACnD,iBAAa,MAAM,UAAU,SAAS;AACtC,UAAM,QAAQ,eAAe,SAAS,QAAQ;AAC9C,WAAO,MAAM,UAAU,SAAS;AAAA,MAC9B;AAAA,MACA;AAAA,MACA,UAAU,MAAM;AAAA,MAChB,SAAS,MAAM;AAAA,MACf,QAAQ,MAAM;AAAA,MACd,OAAO,QAAQ;AAAA,MACf,MAAM;AAAA,QACJ,UAAU,MAAM;AAAA,QAChB,SAAS,MAAM;AAAA,QACf,GAAG,MAAM,OAAO;AAAA,QAChB,GAAG,MAAM,OAAO;AAAA,QAChB,MAAM,MAAM;AAAA,MACd;AAAA,MACE,UAAU;AAAA,QACR,QAAQ,WAAW,KAAK;AAAA,QACxB,QAAQ,MAAM;AAAA,QACd,YAAY,MAAM;AAAA,QAClB,gBAAgB,MAAM;AAAA,MACxB;AAAA,MACF,kBAAkB,MAAM;AAAA,MACxB,cAAc,QAAQ;AAAA,MACtB,iBAAiB,QAAQ;AAAA,MACzB,aAAa;AAAA,QACX,OAAO,MAAM,gBAAgB,MAAM,SAAY,MAAM;AAAA,QACrD,YAAY,MAAM,cAAc,CAAC,MAAM,WAAW,IAAI;AAAA,MACxD;AAAA,MACA,UAAU,QAAQ,YAAY;AAAA,MAC9B,UAAU,QAAQ,YAAY;AAAA,MAC9B,QAAQ,QAAQ;AAAA,MAChB,SAAS,QAAQ;AAAA,IACnB,CAAC;AACD,aAAS,IAAI,OAAO,MAAM,MAAM,MAAM,UAAU,SAAS,KAAK;AAC9D,SAAK,UAAU,OAAO,SAAS;AAC/B,YAAQ,UAAU,MAAM;AACxB,WAAO;AAAA,EACT,SAAS,OAAO;AACd,QAAI,OAAQ,QAAO,QAAQ;AAAA,SACtB;AACH,YAAM,QAAQ;AACd,WAAK,OAAO;AACZ,cAAQ,OAAO,IAAI;AAAA,IACrB;AACA,UAAM;AAAA,EACR;AACF;;;AY7eA,IAAM,eAAe,CAAC,UAA8C;AAClE,MAAI,UAAU,KAAM,QAAO;AAC3B,MAAI,CAAC,KAAK,QAAQ,MAAM,KAAK,EAAE,SAAS,MAAM,YAAY,CAAC,EAAG,QAAO;AACrE,MAAI,CAAC,KAAK,SAAS,OAAO,IAAI,EAAE,SAAS,MAAM,YAAY,CAAC,EAAG,QAAO;AACtE,SAAO;AACT;AAEA,IAAM,cAAc,CAAC,UAA6C;AAChE,MAAI,UAAU,QAAQ,MAAM,KAAK,MAAM,GAAI,QAAO;AAClD,QAAM,SAAS,OAAO,KAAK;AAC3B,SAAO,OAAO,SAAS,MAAM,IAAI,SAAS;AAC5C;AAEA,IAAM,YAAY,CAAC,UAA+C;AAChE,MAAI,UAAU,KAAM,QAAO;AAC3B,SAAO,CAAC,GAAG,IAAI,IAAI,MAAM,MAAM,GAAG,EAAE,IAAI,CAAC,UAAU,MAAM,KAAK,CAAC,EAAE,OAAO,OAAO,CAAC,CAAC;AACnF;AAEA,IAAM,sBAAsB,CAAC,UAC3B,UAAU,SAAS,UAAU,SAAS,QAAQ;AAEhD,IAAM,iBAAiB,CAAC,WAAoC;AAC1D,QAAM,UAAU,OAAO,KAAK;AAC5B,MAAI,0BAA0B,KAAK,OAAO,EAAG,QAAO,IAAI,IAAI,OAAO,EAAE;AACrE,QAAM,QAAQ,QAAQ,SAAS,GAAG,IAAI,QAAQ,MAAM,QAAQ,QAAQ,GAAG,IAAI,CAAC,IAAI;AAChF,SAAO,IAAI,gBAAgB,MAAM,QAAQ,OAAO,EAAE,CAAC;AACrD;AAOO,SAAS,iBAAiB,QAAmD;AAClF,QAAM,SAAS,OAAO,WAAW,WAAW,eAAe,MAAM,IAAI;AACrE,QAAM,SAAS,OAAO,IAAI,GAAG;AAC7B,QAAM,UAAU,YAAY,OAAO,IAAI,IAAI,CAAC;AAC5C,QAAM,UAAU,YAAY,OAAO,IAAI,IAAI,KAAK,OAAO,IAAI,SAAS,CAAC;AACrE,SAAO;AAAA,IACL,QAAS,OAAO,IAAI,GAAG,KAAK;AAAA,IAC5B,WAAW,OAAO,IAAI,GAAG;AAAA,IACzB,OAAQ,OAAO,IAAI,OAAO,KAAK;AAAA,IAC/B,QAAS,OAAO,IAAI,GAAG,KAAK;AAAA,IAC5B,aAAa,WAAW,MAAM,MAAM,WAAW,OAAO,SAAY,UAAU,MAAM,KAAK;AAAA,IACvF,QAAQ,aAAa,OAAO,IAAI,QAAQ,KAAK,OAAO,IAAI,OAAO,CAAC;AAAA,IAChE,YAAY,aAAa,OAAO,IAAI,YAAY,KAAK,OAAO,IAAI,UAAU,CAAC;AAAA,IAC3E,gBAAgB,oBAAoB,OAAO,IAAI,gBAAgB,CAAC;AAAA,IAChE,kBAAkB,aAAa,OAAO,IAAI,SAAS,CAAC;AAAA,IACpD,MAAM,YAAY,OAAO,IAAI,GAAG,CAAC;AAAA,IACjC,QAAQ,YAAY,UAAa,YAAY,SAAY,SAAY,EAAE,GAAG,SAAS,GAAG,QAAQ;AAAA,EAChG;AACF;;;ACnDA,SAAS,mBAAmB,qBAAqB,qBAAqB,mBAAmB,kBAAkB,oBAAoB,+BAA+B;",
6
6
  "names": ["getOEMRegion", "getOEMRegion", "getOEMRegion", "getOEMRegion", "region", "subregion"]
7
7
  }
package/dist/state.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import type { OEMWidgetConfig } from './types';
2
2
  /**
3
- * Adapts legacy OEM URL-state keys to the typed Widget configuration.
3
+ * Adapts compact OEM URL-state keys to the typed Widget configuration.
4
4
  *
5
5
  * This helper is optional; createOEMWidget accepts normal named properties.
6
6
  */
package/dist/style.css CHANGED
@@ -793,7 +793,7 @@ svg.leaflet-image-layer.leaflet-interactive path {
793
793
  padding: 0 3px;
794
794
  border-radius: 0.5rem;
795
795
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.6);
796
- font-family: "Novecento Medium", "Novecento Cyrillic Medium", "Novecento Vietnamese Medium", "HMSans_EN", "Geist", system-ui, sans-serif;
796
+ font-family: "Novecento Wide Medium", "Novecento Cyrillic Medium", "Novecento Vietnamese Medium", "HMSans_EN", "Geist", system-ui, sans-serif;
797
797
  font-size: 0.6875rem;
798
798
  font-weight: 700;
799
799
  line-height: 1rem;
@@ -1062,7 +1062,7 @@ svg.leaflet-image-layer.leaflet-interactive path {
1062
1062
  right: -0.5rem;
1063
1063
  background-color: rgb(255, 196, 40);
1064
1064
  color: rgb(51, 51, 51);
1065
- font-family: "Novecento Medium", "Novecento Cyrillic Medium", "Novecento Vietnamese Medium", "HMSans_EN", "Geist", system-ui, sans-serif;
1065
+ font-family: "Novecento Wide Medium", "Novecento Cyrillic Medium", "Novecento Vietnamese Medium", "HMSans_EN", "Geist", system-ui, sans-serif;
1066
1066
  font-size: 0.75rem;
1067
1067
  font-weight: 700;
1068
1068
  min-width: 18px;
@@ -1122,12 +1122,12 @@ svg.leaflet-image-layer.leaflet-interactive path {
1122
1122
  transform: translate(-50%, -50%);
1123
1123
  user-select: none;
1124
1124
  text-shadow: 1px 1px 1px var(--labelShadowPrimary), 0 0 1px var(--labelShadowSecondary), -0.5px -0.5px 2px var(--labelShadowSecondary);
1125
- font-family: "Novecento Medium", "Novecento Cyrillic Medium", "Novecento Vietnamese Medium", "HMSans_EN", "Geist", system-ui, sans-serif;
1125
+ font-family: "Novecento Wide Medium", "Novecento Cyrillic Medium", "Novecento Vietnamese Medium", "HMSans_EN", "Geist", system-ui, sans-serif;
1126
1126
  animation: mapFadeIn 0.3s ease-in-out;
1127
1127
  }
1128
1128
 
1129
1129
  .mapRoot .innerSub {
1130
- font-family: "Novecento DemiBold", "Novecento Cyrillic DemiBold", "Novecento Vietnamese DemiBold", "HMSans_EN", "Geist", system-ui, sans-serif;
1130
+ font-family: "Novecento Wide DemiBold", "Novecento Cyrillic DemiBold", "Novecento Vietnamese DemiBold", "HMSans_EN", "Geist", system-ui, sans-serif;
1131
1131
  text-transform: capitalize;
1132
1132
  letter-spacing: -0.2px;
1133
1133
  font-size: 18px;
@@ -1431,7 +1431,7 @@ svg.leaflet-image-layer.leaflet-interactive path {
1431
1431
  flex-direction: column;
1432
1432
  gap: 0.5rem;
1433
1433
  pointer-events: auto;
1434
- font-family: "Novecento Medium", "Novecento Cyrillic Medium", "Novecento Vietnamese Medium", "HMSans_EN", "Geist", system-ui, sans-serif;
1434
+ font-family: "Novecento Wide Medium", "Novecento Cyrillic Medium", "Novecento Vietnamese Medium", "HMSans_EN", "Geist", system-ui, sans-serif;
1435
1435
  font-variant-numeric: lining-nums;
1436
1436
  font-feature-settings: "lnum" 1, "onum" 0, "case" 1;
1437
1437
  }
@@ -1475,7 +1475,7 @@ svg.leaflet-image-layer.leaflet-interactive path {
1475
1475
  border-radius: 2px;
1476
1476
  background: var(--switchItem);
1477
1477
  filter: drop-shadow(0 0 2px rgba(0, 0, 0, 0.6));
1478
- font-family: "Novecento Medium", "Novecento Cyrillic Medium", "Novecento Vietnamese Medium", "HMSans_EN", "Geist", system-ui, sans-serif;
1478
+ font-family: "Novecento Wide Medium", "Novecento Cyrillic Medium", "Novecento Vietnamese Medium", "HMSans_EN", "Geist", system-ui, sans-serif;
1479
1479
  line-height: 1;
1480
1480
  }
1481
1481
 
@@ -1622,7 +1622,7 @@ svg.leaflet-image-layer.leaflet-interactive path {
1622
1622
 
1623
1623
  .oemWidget .floorItem,.oemWidget
1624
1624
  .subregionItem {
1625
- font-family: "Novecento Bold", "Novecento Cyrillic DemiBold", "Novecento Vietnamese DemiBold", "HMSans_EN", "Geist", system-ui, sans-serif;
1625
+ font-family: "Novecento Wide Bold", "Novecento Cyrillic DemiBold", "Novecento Vietnamese DemiBold", "HMSans_EN", "Geist", system-ui, sans-serif;
1626
1626
  font-size: 1.1rem;
1627
1627
  font-weight: 700;
1628
1628
  }
@@ -1683,7 +1683,7 @@ svg.leaflet-image-layer.leaflet-interactive path {
1683
1683
  color: rgb(248, 248, 248);
1684
1684
  background: rgb(51, 51, 51);
1685
1685
  box-shadow: 0 0 2px 1px rgba(0, 0, 0, 0.4);
1686
- font-family: "Novecento Medium", "Novecento Cyrillic Medium", "Novecento Vietnamese Medium", "HMSans_EN", "Geist", system-ui, sans-serif;
1686
+ font-family: "Novecento Wide Medium", "Novecento Cyrillic Medium", "Novecento Vietnamese Medium", "HMSans_EN", "Geist", system-ui, sans-serif;
1687
1687
  font-size: 18px;
1688
1688
  line-height: 0;
1689
1689
  cursor: pointer;
package/dist/types.d.ts CHANGED
@@ -1,5 +1,6 @@
1
- import type { OEMManifest, OEMPoint, OEMResources } from '@opendfieldmap/core';
2
- import type { OEMCustomPoint, OEMMapClick } from '@opendfieldmap/map';
1
+ import type { OEMBoundarySource, OEMManifest, OEMPoint, OEMResources } from '@opendfieldmap/core';
2
+ export type { OEMBoundarySource } from '@opendfieldmap/core';
3
+ import type { OEMClickPointOptions, OEMCustomPoint, OEMMapClick } from '@opendfieldmap/map';
3
4
  /** Stable top-level region identifiers published by OEM. */
4
5
  export type OEMRegionId = 'Valley_4' | 'Wuling' | 'Dijiang' | 'Weekraid_1';
5
6
  /** Short region aliases accepted for parity with existing OEM links. */
@@ -13,7 +14,7 @@ export type OEMLocale = 'en-US' | 'zh-CN' | 'zh-HK' | 'ja-JP' | 'ko-KR' | 'ru-RU
13
14
  /** Center coordinates in the selected region's max-native-zoom pixel space. */
14
15
  export interface OEMWidgetCenter {
15
16
  x: number;
16
- y: number;
17
+ z: number;
17
18
  }
18
19
  /**
19
20
  * Declarative content and initial-view configuration.
@@ -35,6 +36,8 @@ export interface OEMWidgetConfig {
35
36
  labels?: boolean;
36
37
  /** Whether subregion boundaries are loaded and displayed. Defaults to false. */
37
38
  boundaries?: boolean;
39
+ /** Boundary data source. Defaults to Atlos/OEM boundaries. */
40
+ boundarySource?: OEMBoundarySource;
38
41
  /** Whether nearby markers are grouped by point type. Defaults to true. */
39
42
  markerClustering?: boolean;
40
43
  /** Host-defined points rendered above the static map data. */
@@ -81,6 +84,7 @@ export interface OEMWidgetState {
81
84
  markerTypes: string[] | '*';
82
85
  labels: boolean;
83
86
  boundaries: boolean;
87
+ boundarySource: OEMBoundarySource;
84
88
  markerClustering: boolean;
85
89
  zoom: number;
86
90
  center: OEMWidgetCenter;
@@ -99,6 +103,8 @@ export interface OEMWidget {
99
103
  getState(): OEMWidgetState;
100
104
  setOptions(options: OEMWidgetConfig): Promise<void>;
101
105
  setCustomPoints(points: readonly OEMCustomPoint[]): void;
106
+ setClickPointMode(options?: OEMClickPointOptions | null): void;
107
+ clearClickPoints(): void;
102
108
  loadCustomPoints(url: string): Promise<void>;
103
109
  clearCustomPoints(): void;
104
110
  getPoint(pointId: string): OEMPoint | undefined;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@opendfieldmap/sdk",
3
- "version": "0.2.0-beta",
3
+ "version": "0.2.2-beta",
4
4
  "description": "Embeddable Open Endfield Map widget",
5
5
  "type": "module",
6
6
  "license": "AGPL-3.0-only",
@@ -20,8 +20,8 @@
20
20
  "./style.css": "./dist/style.css"
21
21
  },
22
22
  "dependencies": {
23
- "@opendfieldmap/core": "^0.2.0-beta",
24
- "@opendfieldmap/map": "^0.2.0-beta"
23
+ "@opendfieldmap/core": "^0.2.2-beta",
24
+ "@opendfieldmap/map": "^0.2.2-beta"
25
25
  },
26
26
  "publishConfig": {
27
27
  "access": "public"