@opendfieldmap/sdk 0.1.0-alpha.0 → 0.2.1-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 +29 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +115 -25
- package/dist/index.js.map +3 -3
- package/dist/state.d.ts +1 -1
- package/dist/types.d.ts +23 -2
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -17,14 +17,43 @@ const widget = await createOEMWidget('#map', {
|
|
|
17
17
|
markerTypes: ['crate_i', 'aurylene'],
|
|
18
18
|
labels: true,
|
|
19
19
|
markerClustering: true,
|
|
20
|
+
boundarySource: 'oem',
|
|
21
|
+
customPoints: [{
|
|
22
|
+
id: 'route-start',
|
|
23
|
+
position: { regionId: 'Valley_4', x: 400, z: -600, floorId: 'M' },
|
|
24
|
+
style: 'framed',
|
|
25
|
+
icon: '/icons/route-start.webp',
|
|
26
|
+
}],
|
|
20
27
|
});
|
|
21
28
|
|
|
22
29
|
await widget.setOptions({ boundaries: true });
|
|
30
|
+
const point = await widget.loadPoint('2100500004');
|
|
23
31
|
widget.destroy();
|
|
24
32
|
```
|
|
25
33
|
|
|
26
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.
|
|
27
35
|
|
|
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.
|
|
37
|
+
|
|
38
|
+
For a large point collection, host the same JSON array separately and load it by URL:
|
|
39
|
+
|
|
40
|
+
```ts
|
|
41
|
+
const widget = await createOEMWidget('#map', {
|
|
42
|
+
region: 'WL',
|
|
43
|
+
customPointsUrl: '/data/custom-points.json',
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
await widget.loadCustomPoints('/data/another-set.json');
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
`customPoints` and `customPointsUrl` are mutually exclusive. Relative icon URLs in the JSON file resolve against that file's URL.
|
|
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.
|
|
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
|
+
|
|
28
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.
|
|
29
58
|
|
|
30
59
|
See the repository documentation for the complete API, resource protocol, localized guides, and release workflow.
|
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
1
|
export { createOEMWidget } from './widget';
|
|
2
2
|
export { parseOEMUrlState } from './state';
|
|
3
|
+
export { gameToOEMPosition, gameXZToOEMPosition, mapToGameXZPosition, oemToGamePosition, toOEMMapPosition, fromOEMMapPosition, toOEMLeafletMapPosition } from '@opendfieldmap/core';
|
|
4
|
+
export type { OEMBoundarySource, OEMGamePosition, OEMGameTransform, OEMGameXZPosition, OEMMapOffset, OEMMapPosition, OEMPoint, OEMPosition, OEMRegion } from '@opendfieldmap/core';
|
|
5
|
+
export type { OEMClickPointOptions, OEMCustomPoint, OEMMapClick } from '@opendfieldmap/map';
|
|
3
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,
|
|
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.
|
|
263
|
-
[region.initialView.x, region.initialView.
|
|
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,
|
|
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
|
});
|
|
@@ -496,6 +496,7 @@ var cloneState = (state) => ({
|
|
|
496
496
|
var cloneConfig = (config) => ({
|
|
497
497
|
...config,
|
|
498
498
|
markerTypes: Array.isArray(config.markerTypes) ? [...config.markerTypes] : config.markerTypes,
|
|
499
|
+
customPoints: config.customPoints?.map((point) => ({ ...point, position: { ...point.position } })),
|
|
499
500
|
center: config.center ? { ...config.center } : config.center
|
|
500
501
|
});
|
|
501
502
|
var resolveContainer = (container) => {
|
|
@@ -512,17 +513,22 @@ var normalizeMarkerTypes = (value) => {
|
|
|
512
513
|
if (!value || !Array.isArray(value)) return [];
|
|
513
514
|
return [...new Set(value.map((entry) => entry.trim()).filter(Boolean))];
|
|
514
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
|
+
};
|
|
515
521
|
var getPreset = (region, subregion) => {
|
|
516
522
|
if (!subregion?.bounds) {
|
|
517
523
|
return {
|
|
518
|
-
center: { x: region.initialView.x,
|
|
524
|
+
center: { x: region.initialView.x, z: region.initialView.z },
|
|
519
525
|
zoom: region.initialView.zoom
|
|
520
526
|
};
|
|
521
527
|
}
|
|
522
528
|
return {
|
|
523
529
|
center: {
|
|
524
530
|
x: (subregion.bounds[0][0] + subregion.bounds[1][0]) / 2,
|
|
525
|
-
|
|
531
|
+
z: (subregion.bounds[0][1] + subregion.bounds[1][1]) / 2
|
|
526
532
|
},
|
|
527
533
|
zoom: Math.max(region.minZoom, Math.min(region.maxZoom, 1))
|
|
528
534
|
};
|
|
@@ -545,7 +551,7 @@ var normalizeState = (input, manifest) => {
|
|
|
545
551
|
throw new Error(`Unknown OEM floor ${floorId} in ${regionId}`);
|
|
546
552
|
}
|
|
547
553
|
const requestedCenter = input.center;
|
|
548
|
-
if (requestedCenter && (!Number.isFinite(requestedCenter.x) || !Number.isFinite(requestedCenter.
|
|
554
|
+
if (requestedCenter && (!Number.isFinite(requestedCenter.x) || !Number.isFinite(requestedCenter.z))) {
|
|
549
555
|
throw new Error("OEM Widget center coordinates must be finite");
|
|
550
556
|
}
|
|
551
557
|
const preset = getPreset(region, subregion);
|
|
@@ -558,11 +564,12 @@ var normalizeState = (input, manifest) => {
|
|
|
558
564
|
markerTypes: normalizeMarkerTypes(input.markerTypes),
|
|
559
565
|
labels: input.labels ?? true,
|
|
560
566
|
boundaries: input.boundaries ?? false,
|
|
567
|
+
boundarySource: normalizeBoundarySource(input.boundarySource),
|
|
561
568
|
markerClustering: input.markerClustering ?? true,
|
|
562
569
|
zoom: Math.max(region.minZoom, Math.min(region.maxZoom, input.zoom ?? preset.zoom)),
|
|
563
570
|
center: {
|
|
564
571
|
x: requestedCenter?.x ?? preset.center.x,
|
|
565
|
-
|
|
572
|
+
z: requestedCenter?.z ?? preset.center.z
|
|
566
573
|
}
|
|
567
574
|
};
|
|
568
575
|
};
|
|
@@ -574,12 +581,13 @@ var toConfig = (state) => ({
|
|
|
574
581
|
markerTypes: state.markerTypes,
|
|
575
582
|
labels: state.labels,
|
|
576
583
|
boundaries: state.boundaries,
|
|
584
|
+
boundarySource: state.boundarySource,
|
|
577
585
|
markerClustering: state.markerClustering,
|
|
578
586
|
zoom: state.zoom,
|
|
579
587
|
center: { ...state.center }
|
|
580
588
|
});
|
|
581
589
|
var sameMarkers = (left, right) => left === right || left !== "*" && right !== "*" && left.length === right.length && left.every((marker, index) => marker === right[index]);
|
|
582
|
-
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.
|
|
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;
|
|
583
591
|
var hasMarkers = (state) => state.markerTypes === "*" || state.markerTypes.length > 0;
|
|
584
592
|
var Widget = class {
|
|
585
593
|
constructor(host, root, core, manifest, options, state) {
|
|
@@ -589,6 +597,7 @@ var Widget = class {
|
|
|
589
597
|
this.manifest = manifest;
|
|
590
598
|
this.options = options;
|
|
591
599
|
this.state = state;
|
|
600
|
+
this.customPointsUrl = options.customPointsUrl;
|
|
592
601
|
this.controls = mountControls(root, {
|
|
593
602
|
regionSelector: options.showRegionSelector ?? true,
|
|
594
603
|
floorSelector: options.showFloorSelector ?? true,
|
|
@@ -602,14 +611,18 @@ var Widget = class {
|
|
|
602
611
|
zoomTo: (zoom, zoomOptions) => core.setZoom(zoom, zoomOptions)
|
|
603
612
|
});
|
|
604
613
|
this.controls.sync(state);
|
|
605
|
-
this.
|
|
614
|
+
this.unsubscribeView = core.on("viewchange", this.syncView);
|
|
615
|
+
this.unsubscribeClick = core.on("click", this.forwardClick);
|
|
606
616
|
options.signal?.addEventListener("abort", this.destroy, { once: true });
|
|
607
617
|
}
|
|
608
618
|
destroyed = false;
|
|
609
619
|
applying = false;
|
|
610
620
|
updates = Promise.resolve();
|
|
621
|
+
customPointsUrl;
|
|
611
622
|
controls;
|
|
612
|
-
|
|
623
|
+
unsubscribeView;
|
|
624
|
+
unsubscribeClick;
|
|
625
|
+
listeners = /* @__PURE__ */ new Map();
|
|
613
626
|
assertAlive() {
|
|
614
627
|
if (this.destroyed) throw new Error("OEM Widget has been destroyed");
|
|
615
628
|
}
|
|
@@ -619,6 +632,12 @@ var Widget = class {
|
|
|
619
632
|
notify() {
|
|
620
633
|
this.options.onStateChange?.(cloneState(this.state));
|
|
621
634
|
}
|
|
635
|
+
emit(event, payload) {
|
|
636
|
+
this.listeners.get(event)?.forEach((handler) => handler(payload));
|
|
637
|
+
}
|
|
638
|
+
forwardClick = (payload) => {
|
|
639
|
+
if (!this.destroyed) this.emit("click", payload);
|
|
640
|
+
};
|
|
622
641
|
syncView = () => {
|
|
623
642
|
if (this.destroyed || this.applying) return;
|
|
624
643
|
const view = this.core.getView();
|
|
@@ -627,7 +646,7 @@ var Widget = class {
|
|
|
627
646
|
regionId: view.regionId,
|
|
628
647
|
floorId: view.floorId ?? "M",
|
|
629
648
|
locale: this.core.getLocale().resolved,
|
|
630
|
-
center: { x: view.x,
|
|
649
|
+
center: { x: view.x, z: view.z },
|
|
631
650
|
zoom: view.zoom
|
|
632
651
|
};
|
|
633
652
|
this.controls.sync(this.state);
|
|
@@ -637,6 +656,45 @@ var Widget = class {
|
|
|
637
656
|
this.assertAlive();
|
|
638
657
|
return cloneState(this.state);
|
|
639
658
|
}
|
|
659
|
+
setCustomPoints(points) {
|
|
660
|
+
this.assertAlive();
|
|
661
|
+
this.core.setCustomPoints(points);
|
|
662
|
+
this.customPointsUrl = void 0;
|
|
663
|
+
}
|
|
664
|
+
setClickPointMode(options) {
|
|
665
|
+
this.assertAlive();
|
|
666
|
+
this.core.setClickPointMode(options);
|
|
667
|
+
}
|
|
668
|
+
clearClickPoints() {
|
|
669
|
+
this.assertAlive();
|
|
670
|
+
this.core.clearClickPoints();
|
|
671
|
+
}
|
|
672
|
+
async loadCustomPoints(url) {
|
|
673
|
+
this.assertAlive();
|
|
674
|
+
await this.core.loadCustomPoints(url);
|
|
675
|
+
this.customPointsUrl = url;
|
|
676
|
+
}
|
|
677
|
+
clearCustomPoints() {
|
|
678
|
+
this.assertAlive();
|
|
679
|
+
this.core.clearCustomPoints();
|
|
680
|
+
}
|
|
681
|
+
getPoint(pointId) {
|
|
682
|
+
this.assertAlive();
|
|
683
|
+
return this.core.getPoint(pointId);
|
|
684
|
+
}
|
|
685
|
+
loadPoint(pointId) {
|
|
686
|
+
this.assertAlive();
|
|
687
|
+
return this.core.loadPoint(pointId);
|
|
688
|
+
}
|
|
689
|
+
on(event, handler) {
|
|
690
|
+
this.assertAlive();
|
|
691
|
+
const handlers = this.listeners.get(event) ?? /* @__PURE__ */ new Set();
|
|
692
|
+
handlers.add(handler);
|
|
693
|
+
this.listeners.set(event, handlers);
|
|
694
|
+
return () => {
|
|
695
|
+
handlers.delete(handler);
|
|
696
|
+
};
|
|
697
|
+
}
|
|
640
698
|
setOptions(update) {
|
|
641
699
|
this.assertAlive();
|
|
642
700
|
const snapshot = cloneConfig(update);
|
|
@@ -667,15 +725,26 @@ var Widget = class {
|
|
|
667
725
|
}
|
|
668
726
|
const previous = this.state;
|
|
669
727
|
const next = normalizeState(merged, this.manifest);
|
|
670
|
-
if (
|
|
728
|
+
if (changes.customPoints !== void 0 && changes.customPointsUrl !== void 0) {
|
|
729
|
+
throw new Error("Pass either customPoints or customPointsUrl, not both");
|
|
730
|
+
}
|
|
731
|
+
const customPointsChanged = changes.customPoints !== void 0 || changes.customPointsUrl !== void 0;
|
|
732
|
+
if (sameState(previous, next) && !customPointsChanged) return;
|
|
671
733
|
const regionChanged = next.regionId !== previous.regionId;
|
|
672
734
|
const filterChanged = next.subregionId !== previous.subregionId || !sameMarkers(next.markerTypes, previous.markerTypes);
|
|
673
|
-
const viewChanged = regionChanged || next.floorId !== previous.floorId || next.zoom !== previous.zoom || next.center.x !== previous.center.x || next.center.
|
|
735
|
+
const viewChanged = regionChanged || next.floorId !== previous.floorId || next.zoom !== previous.zoom || next.center.x !== previous.center.x || next.center.z !== previous.center.z;
|
|
674
736
|
const previousMarkers = hasMarkers(previous);
|
|
675
737
|
const nextMarkers = hasMarkers(next);
|
|
676
738
|
this.applying = true;
|
|
677
739
|
this.root.classList.add("loading");
|
|
678
740
|
try {
|
|
741
|
+
if (changes.customPoints !== void 0) {
|
|
742
|
+
this.core.setCustomPoints(changes.customPoints);
|
|
743
|
+
this.customPointsUrl = void 0;
|
|
744
|
+
} else if (changes.customPointsUrl !== void 0) {
|
|
745
|
+
await this.core.loadCustomPoints(changes.customPointsUrl);
|
|
746
|
+
this.customPointsUrl = changes.customPointsUrl;
|
|
747
|
+
}
|
|
679
748
|
if (previousMarkers && !nextMarkers) await this.core.setFeatures({ points: false });
|
|
680
749
|
if (filterChanged) {
|
|
681
750
|
this.core.setPointFilter({
|
|
@@ -689,11 +758,12 @@ var Widget = class {
|
|
|
689
758
|
if (next.markerClustering !== previous.markerClustering) {
|
|
690
759
|
this.core.setMarkerClustering(next.markerClustering);
|
|
691
760
|
}
|
|
692
|
-
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) {
|
|
693
762
|
await this.core.setFeatures({
|
|
694
763
|
points: nextMarkers,
|
|
695
764
|
labels: next.labels,
|
|
696
|
-
boundaries: next.boundaries
|
|
765
|
+
boundaries: next.boundaries,
|
|
766
|
+
boundarySource: next.boundarySource
|
|
697
767
|
});
|
|
698
768
|
}
|
|
699
769
|
if (viewChanged) {
|
|
@@ -701,7 +771,7 @@ var Widget = class {
|
|
|
701
771
|
regionId: next.regionId,
|
|
702
772
|
floorId: next.floorId,
|
|
703
773
|
x: next.center.x,
|
|
704
|
-
|
|
774
|
+
z: next.center.z,
|
|
705
775
|
zoom: next.zoom
|
|
706
776
|
});
|
|
707
777
|
}
|
|
@@ -709,7 +779,7 @@ var Widget = class {
|
|
|
709
779
|
this.state = {
|
|
710
780
|
...next,
|
|
711
781
|
locale: this.core.getLocale().resolved,
|
|
712
|
-
center: { x: view.x,
|
|
782
|
+
center: { x: view.x, z: view.z },
|
|
713
783
|
zoom: view.zoom
|
|
714
784
|
};
|
|
715
785
|
this.controls.sync(this.state);
|
|
@@ -726,7 +796,9 @@ var Widget = class {
|
|
|
726
796
|
destroy = () => {
|
|
727
797
|
if (this.destroyed) return;
|
|
728
798
|
this.destroyed = true;
|
|
729
|
-
this.
|
|
799
|
+
this.unsubscribeView();
|
|
800
|
+
this.unsubscribeClick();
|
|
801
|
+
this.listeners.clear();
|
|
730
802
|
this.controls.destroy?.();
|
|
731
803
|
this.options.signal?.removeEventListener("abort", this.destroy);
|
|
732
804
|
this.core.destroy();
|
|
@@ -736,6 +808,9 @@ var Widget = class {
|
|
|
736
808
|
};
|
|
737
809
|
async function createOEMWidget(container, options = {}) {
|
|
738
810
|
if (typeof document === "undefined") throw new Error("createOEMWidget must run in a browser");
|
|
811
|
+
if (options.customPoints !== void 0 && options.customPointsUrl !== void 0) {
|
|
812
|
+
throw new Error("Pass either customPoints or customPointsUrl, not both");
|
|
813
|
+
}
|
|
739
814
|
options.signal?.throwIfAborted();
|
|
740
815
|
const host = resolveContainer(container);
|
|
741
816
|
if (mounted.has(host)) throw new Error("This container already hosts an OEM Widget");
|
|
@@ -766,15 +841,18 @@ async function createOEMWidget(container, options = {}) {
|
|
|
766
841
|
regionId: state.regionId,
|
|
767
842
|
floorId: state.floorId,
|
|
768
843
|
x: state.center.x,
|
|
769
|
-
|
|
844
|
+
z: state.center.z,
|
|
770
845
|
zoom: state.zoom
|
|
771
846
|
},
|
|
772
847
|
features: {
|
|
773
848
|
points: hasMarkers(state),
|
|
774
849
|
labels: state.labels,
|
|
775
|
-
boundaries: state.boundaries
|
|
850
|
+
boundaries: state.boundaries,
|
|
851
|
+
boundarySource: state.boundarySource
|
|
776
852
|
},
|
|
777
853
|
markerClustering: state.markerClustering,
|
|
854
|
+
customPoints: options.customPoints,
|
|
855
|
+
customPointsUrl: options.customPointsUrl,
|
|
778
856
|
pointFilter: {
|
|
779
857
|
types: state.markerTypes === "*" ? void 0 : state.markerTypes,
|
|
780
858
|
subregions: state.subregionId ? [state.subregionId] : void 0
|
|
@@ -815,6 +893,7 @@ var parseList = (value) => {
|
|
|
815
893
|
if (value === null) return void 0;
|
|
816
894
|
return [...new Set(value.split(",").map((entry) => entry.trim()).filter(Boolean))];
|
|
817
895
|
};
|
|
896
|
+
var parseBoundarySource = (value) => value === "oem" || value === "game" ? value : void 0;
|
|
818
897
|
var toSearchParams = (source) => {
|
|
819
898
|
const trimmed = source.trim();
|
|
820
899
|
if (/^[a-z][a-z\d+.-]*:\/\//i.test(trimmed)) return new URL(trimmed).searchParams;
|
|
@@ -824,8 +903,8 @@ var toSearchParams = (source) => {
|
|
|
824
903
|
function parseOEMUrlState(source) {
|
|
825
904
|
const params = typeof source === "string" ? toSearchParams(source) : source;
|
|
826
905
|
const filter = params.get("f");
|
|
827
|
-
const
|
|
828
|
-
const
|
|
906
|
+
const centerX = parseNumber(params.get("cx"));
|
|
907
|
+
const centerZ = parseNumber(params.get("cz") ?? params.get("centerZ"));
|
|
829
908
|
return {
|
|
830
909
|
region: params.get("r") ?? void 0,
|
|
831
910
|
subregion: params.get("s"),
|
|
@@ -834,13 +913,24 @@ function parseOEMUrlState(source) {
|
|
|
834
913
|
markerTypes: filter === "*" ? "*" : filter === null ? void 0 : parseList(filter) ?? false,
|
|
835
914
|
labels: parseBoolean(params.get("labels") ?? params.get("names")),
|
|
836
915
|
boundaries: parseBoolean(params.get("boundaries") ?? params.get("boundary")),
|
|
916
|
+
boundarySource: parseBoundarySource(params.get("boundarySource")),
|
|
837
917
|
markerClustering: parseBoolean(params.get("cluster")),
|
|
838
918
|
zoom: parseNumber(params.get("z")),
|
|
839
|
-
center:
|
|
919
|
+
center: centerX === void 0 || centerZ === void 0 ? void 0 : { x: centerX, z: centerZ }
|
|
840
920
|
};
|
|
841
921
|
}
|
|
922
|
+
|
|
923
|
+
// packages/sdk/src/index.ts
|
|
924
|
+
import { gameToOEMPosition, gameXZToOEMPosition, mapToGameXZPosition, oemToGamePosition, toOEMMapPosition, fromOEMMapPosition, toOEMLeafletMapPosition } from "@opendfieldmap/core";
|
|
842
925
|
export {
|
|
843
926
|
createOEMWidget,
|
|
844
|
-
|
|
927
|
+
fromOEMMapPosition,
|
|
928
|
+
gameToOEMPosition,
|
|
929
|
+
gameXZToOEMPosition,
|
|
930
|
+
mapToGameXZPosition,
|
|
931
|
+
oemToGamePosition,
|
|
932
|
+
parseOEMUrlState,
|
|
933
|
+
toOEMLeafletMapPosition,
|
|
934
|
+
toOEMMapPosition
|
|
845
935
|
};
|
|
846
936
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 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"],
|
|
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 } 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 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 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 controls: Control;\n private unsubscribe: () => 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.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.unsubscribe = core.on('viewchange', this.syncView);\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 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 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 (sameState(previous, next)) 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 (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.unsubscribe();\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 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 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"],
|
|
5
|
-
"mappings": "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",
|
|
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, 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 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 { 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": "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",
|
|
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
|
|
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/types.d.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import type { OEMManifest, OEMResources } from '@opendfieldmap/core';
|
|
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';
|
|
2
4
|
/** Stable top-level region identifiers published by OEM. */
|
|
3
5
|
export type OEMRegionId = 'Valley_4' | 'Wuling' | 'Dijiang' | 'Weekraid_1';
|
|
4
6
|
/** Short region aliases accepted for parity with existing OEM links. */
|
|
@@ -12,7 +14,7 @@ export type OEMLocale = 'en-US' | 'zh-CN' | 'zh-HK' | 'ja-JP' | 'ko-KR' | 'ru-RU
|
|
|
12
14
|
/** Center coordinates in the selected region's max-native-zoom pixel space. */
|
|
13
15
|
export interface OEMWidgetCenter {
|
|
14
16
|
x: number;
|
|
15
|
-
|
|
17
|
+
z: number;
|
|
16
18
|
}
|
|
17
19
|
/**
|
|
18
20
|
* Declarative content and initial-view configuration.
|
|
@@ -34,8 +36,14 @@ export interface OEMWidgetConfig {
|
|
|
34
36
|
labels?: boolean;
|
|
35
37
|
/** Whether subregion boundaries are loaded and displayed. Defaults to false. */
|
|
36
38
|
boundaries?: boolean;
|
|
39
|
+
/** Boundary data source. Defaults to Atlos/OEM boundaries. */
|
|
40
|
+
boundarySource?: OEMBoundarySource;
|
|
37
41
|
/** Whether nearby markers are grouped by point type. Defaults to true. */
|
|
38
42
|
markerClustering?: boolean;
|
|
43
|
+
/** Host-defined points rendered above the static map data. */
|
|
44
|
+
customPoints?: readonly OEMCustomPoint[];
|
|
45
|
+
/** URL of a JSON array of host-defined points. It replaces customPoints. */
|
|
46
|
+
customPointsUrl?: string;
|
|
39
47
|
/** Initial zoom, clamped to the selected region's supported range. Defaults to the region preset. */
|
|
40
48
|
zoom?: number;
|
|
41
49
|
/** Initial map center. Defaults to the selected region or subregion preset. */
|
|
@@ -76,10 +84,15 @@ export interface OEMWidgetState {
|
|
|
76
84
|
markerTypes: string[] | '*';
|
|
77
85
|
labels: boolean;
|
|
78
86
|
boundaries: boolean;
|
|
87
|
+
boundarySource: OEMBoundarySource;
|
|
79
88
|
markerClustering: boolean;
|
|
80
89
|
zoom: number;
|
|
81
90
|
center: OEMWidgetCenter;
|
|
82
91
|
}
|
|
92
|
+
/** Events exposed by the embeddable Widget. */
|
|
93
|
+
export interface OEMWidgetEvents {
|
|
94
|
+
click: OEMMapClick;
|
|
95
|
+
}
|
|
83
96
|
/**
|
|
84
97
|
* Restricted Widget handle exposed to host applications.
|
|
85
98
|
*
|
|
@@ -89,6 +102,14 @@ export interface OEMWidget {
|
|
|
89
102
|
readonly destroyed: boolean;
|
|
90
103
|
getState(): OEMWidgetState;
|
|
91
104
|
setOptions(options: OEMWidgetConfig): Promise<void>;
|
|
105
|
+
setCustomPoints(points: readonly OEMCustomPoint[]): void;
|
|
106
|
+
setClickPointMode(options?: OEMClickPointOptions | null): void;
|
|
107
|
+
clearClickPoints(): void;
|
|
108
|
+
loadCustomPoints(url: string): Promise<void>;
|
|
109
|
+
clearCustomPoints(): void;
|
|
110
|
+
getPoint(pointId: string): OEMPoint | undefined;
|
|
111
|
+
loadPoint(pointId: string): Promise<OEMPoint | undefined>;
|
|
112
|
+
on<Event extends keyof OEMWidgetEvents>(event: Event, handler: (payload: OEMWidgetEvents[Event]) => void): () => void;
|
|
92
113
|
resize(): void;
|
|
93
114
|
destroy(): void;
|
|
94
115
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@opendfieldmap/sdk",
|
|
3
|
-
"version": "0.1
|
|
3
|
+
"version": "0.2.1-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.1
|
|
24
|
-
"@opendfieldmap/map": "^0.1
|
|
23
|
+
"@opendfieldmap/core": "^0.2.1-beta",
|
|
24
|
+
"@opendfieldmap/map": "^0.2.1-beta"
|
|
25
25
|
},
|
|
26
26
|
"publishConfig": {
|
|
27
27
|
"access": "public"
|