3dviewer-sdk 1.0.12 → 1.0.13

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/dist/index.mjs CHANGED
@@ -121,6 +121,8 @@ var NodeModule = class {
121
121
  // src/modules/files.module.ts
122
122
  var DEFAULT_API_BASE_URL = "https://dev.3dviewer.anybim.vn";
123
123
  var DEFAULT_VIEWER_ORIGIN = "http://localhost:3000";
124
+ var SDK_VIEWER_PATH = "/mainviewer-sdk";
125
+ var LEGACY_VIEWER_PATH = "/mainviewer";
124
126
  var FilesModule = class {
125
127
  constructor(viewer) {
126
128
  this.viewer = viewer;
@@ -270,12 +272,7 @@ var FilesModule = class {
270
272
  const raw = this.config.baseUrl || this.viewer.getOptions().baseUrl || DEFAULT_API_BASE_URL;
271
273
  return this.normalizeBaseUrl(raw);
272
274
  }
273
- // Resolve conversion API base URL with legacy baseUrl fallback.
274
- resolveConversionBaseUrl() {
275
- const raw = this.config.conversionBaseUrl || this.viewer.getOptions().conversionBaseUrl;
276
- return (raw == null ? void 0 : raw.trim()) ? this.normalizeBaseUrl(raw) : this.resolveBaseUrl();
277
- }
278
- // Resolve viewer route path (e.g. /mainviewer).
275
+ // Resolve viewer route path for all SDK flows.
279
276
  resolveViewerPath() {
280
277
  const configuredPath = this.config.viewerPath || this.viewer.getOptions().viewerPath;
281
278
  if (!configuredPath) {
@@ -283,36 +280,46 @@ var FilesModule = class {
283
280
  if (viewerUrl) {
284
281
  try {
285
282
  const pathname = new URL(viewerUrl, window.location.href).pathname;
286
- if (pathname && pathname !== "/") return pathname;
283
+ if (pathname && pathname !== "/") return this.normalizeSdkViewerPath(pathname);
287
284
  } catch {
288
285
  }
289
286
  }
290
287
  }
291
- const p = (configuredPath || "/mainviewer").trim();
292
- if (!p) return "/mainviewer";
293
- return p.startsWith("/") ? p : `/${p}`;
288
+ return this.normalizeSdkViewerPath(configuredPath || SDK_VIEWER_PATH);
289
+ }
290
+ normalizeSdkViewerPath(path) {
291
+ const p = path.trim();
292
+ if (!p || p === LEGACY_VIEWER_PATH) return SDK_VIEWER_PATH;
293
+ const normalized = p.startsWith("/") ? p : `/${p}`;
294
+ return normalized === LEGACY_VIEWER_PATH ? SDK_VIEWER_PATH : normalized;
294
295
  }
295
296
  // Viewer host used to open iframe after conversion completes.
296
297
  resolveViewerOrigin() {
297
- const configuredBaseUrl = this.config.baseUrl || this.viewer.getOptions().baseUrl;
298
- if (configuredBaseUrl) {
298
+ const viewerUrl = this.viewer.getOptions().url;
299
+ if (viewerUrl) {
299
300
  try {
300
- return this.normalizeBaseUrl(new URL(configuredBaseUrl, window.location.href).origin);
301
+ return this.normalizeBaseUrl(new URL(viewerUrl, window.location.href).origin);
301
302
  } catch {
302
303
  }
303
304
  }
304
- const viewerUrl = this.viewer.getOptions().url;
305
- if (viewerUrl) {
305
+ const configuredBaseUrl = this.config.baseUrl || this.viewer.getOptions().baseUrl;
306
+ if (configuredBaseUrl) {
306
307
  try {
307
- return this.normalizeBaseUrl(new URL(viewerUrl, window.location.href).origin);
308
+ return this.normalizeBaseUrl(new URL(configuredBaseUrl, window.location.href).origin);
308
309
  } catch {
309
310
  }
310
311
  }
311
312
  return this.normalizeBaseUrl(DEFAULT_VIEWER_ORIGIN);
312
313
  }
313
- // Use the configured conversion API root as-is.
314
+ // Build conversion service root from API base URL.
314
315
  resolveHostConversion() {
315
- return this.resolveConversionBaseUrl();
316
+ const baseUrl = this.resolveBaseUrl();
317
+ try {
318
+ const parsed = new URL(baseUrl, window.location.href);
319
+ if (parsed.hostname.includes("conversion")) return baseUrl;
320
+ } catch {
321
+ }
322
+ return baseUrl.endsWith("/service/conversion") ? baseUrl : `${baseUrl}/service/conversion`;
316
323
  }
317
324
  // Resolve upload path sent to conversion APIs.
318
325
  getUploadPath() {
@@ -464,16 +471,16 @@ var FilesModule = class {
464
471
  }
465
472
  // Submit conversion request to the newer downloadUrl-based endpoint.
466
473
  async cacheFileV2(options) {
474
+ var _a;
467
475
  const hostConversion = await this.resolveHostConversion();
468
476
  const params = new URLSearchParams();
469
- if (typeof options.overwrite === "boolean") {
470
- params.set("overwrite", String(options.overwrite));
471
- }
477
+ params.set("overwrite", String((_a = options.overwrite) != null ? _a : true));
478
+ params.set("ignore_line_weight", "1");
472
479
  if (options.project) {
473
480
  params.set("project", options.project);
474
481
  }
475
482
  const query = params.toString();
476
- const url = `${hostConversion}/api/StreamFile/convert${query ? `?${query}` : ""}`;
483
+ const url = `${hostConversion}/api/StreamFile${query ? `?${query}` : ""}`;
477
484
  const payload = this.buildConvertV2Payload(options);
478
485
  const response = await fetch(url, {
479
486
  method: "POST",
@@ -561,8 +568,8 @@ var FilesModule = class {
561
568
  };
562
569
 
563
570
  // src/modules/toolbar.module.ts
564
- function createRequestId() {
565
- return `sheets_${Date.now()}_${Math.random().toString(36).slice(2, 10)}`;
571
+ function createRequestId(prefix) {
572
+ return `${prefix}_${Date.now()}_${Math.random().toString(36).slice(2, 10)}`;
566
573
  }
567
574
  var ALL_3D_TOOLBAR_OPERATORS = [
568
575
  "home",
@@ -648,90 +655,78 @@ var ToolbarModule = class {
648
655
  enableAllPdf() {
649
656
  this.clearDisabledPdf();
650
657
  }
651
- hideToolbar() {
652
- this.setToolbarVisible(false);
653
- }
654
- showToolbar() {
655
- this.setToolbarVisible(true);
656
- }
657
- setToolbarVisible(visible, target = "all") {
658
- this.postToolbarVisibility({ visible, target });
659
- }
660
- hideLeftToolbar() {
661
- this.setToolbarVisible(false, "left");
658
+ useToolbar(target = "all") {
659
+ this.postToolbarUse({ target });
662
660
  }
663
- showLeftToolbar() {
664
- this.setToolbarVisible(true, "left");
661
+ useLeftToolbar() {
662
+ this.useToolbar("left");
665
663
  }
666
- hideCenterToolbar() {
667
- this.setToolbarVisible(false, "center");
664
+ useCenterToolbar() {
665
+ this.useToolbar("center");
668
666
  }
669
- showCenterToolbar() {
670
- this.setToolbarVisible(true, "center");
667
+ useRightToolbar() {
668
+ this.useToolbar("right");
671
669
  }
672
- hideRightToolbar() {
673
- this.setToolbarVisible(false, "right");
674
- }
675
- showRightToolbar() {
676
- this.setToolbarVisible(true, "right");
670
+ usePanel(panel, format) {
671
+ this.postPanelOpen({ panel, format });
677
672
  }
678
673
  openClippingPlanes() {
679
- this.postPanelOpen({ panel: "clipping-commands", format: "3d" });
674
+ this.usePanel("clipping-commands", "3d");
680
675
  }
681
676
  closeClippingPlanes() {
682
677
  this.postPanelClose({ panel: "clipping-commands", format: "3d" });
683
678
  }
684
679
  openSetting() {
685
- this.postPanelOpen({ panel: "setting" });
680
+ this.usePanel("setting");
686
681
  }
687
682
  closeSetting() {
688
683
  this.postPanelClose({ panel: "setting" });
689
684
  }
690
685
  openSetting3D() {
691
- this.postPanelOpen({ panel: "setting", format: "3d" });
686
+ this.usePanel("setting", "3d");
692
687
  }
693
688
  closeSetting3D() {
694
689
  this.postPanelClose({ panel: "setting", format: "3d" });
695
690
  }
696
691
  openSettingPdf() {
697
- this.postPanelOpen({ panel: "setting", format: "pdf" });
692
+ this.usePanel("setting", "pdf");
698
693
  }
699
694
  closeSettingPdf() {
700
695
  this.postPanelClose({ panel: "setting", format: "pdf" });
701
696
  }
702
697
  openStatesObjects() {
703
- this.postPanelOpen({ panel: "statesObjects", format: "3d" });
698
+ this.usePanel("statesObjects", "3d");
704
699
  }
705
700
  closeStatesObjects() {
706
701
  this.postPanelClose({ panel: "statesObjects", format: "3d" });
707
702
  }
708
703
  openLinkedObjects() {
709
- this.postPanelOpen({ panel: "linkedObjects", format: "3d" });
704
+ this.usePanel("linkedObjects", "3d");
710
705
  }
711
706
  closeLinkedObjects() {
712
707
  this.postPanelClose({ panel: "linkedObjects", format: "3d" });
713
708
  }
714
709
  openModelTree() {
715
- this.postPanelOpen({ panel: "model-tree", format: "3d" });
710
+ this.usePanel("model-tree", "3d");
716
711
  }
717
712
  closeModelTree() {
718
713
  this.postPanelClose({ panel: "model-tree", format: "3d" });
719
714
  }
720
715
  openObjectProperties() {
721
- this.postPanelOpen({ panel: "object-properties", format: "3d" });
716
+ this.usePanel("object-properties", "3d");
722
717
  }
723
718
  closeObjectProperties() {
724
719
  this.postPanelClose({ panel: "object-properties", format: "3d" });
725
720
  }
726
721
  openSheets() {
727
- this.postPanelOpen({ panel: "sheets", format: "3d" });
722
+ this.usePanel("sheets", "3d");
728
723
  }
729
724
  closeSheets() {
730
725
  this.postPanelClose({ panel: "sheets", format: "3d" });
731
726
  }
732
727
  getSheets(options) {
733
728
  var _a;
734
- const requestId = createRequestId();
729
+ const requestId = createRequestId("sheets");
735
730
  const timeoutMs = Math.max(1e3, (_a = options == null ? void 0 : options.timeoutMs) != null ? _a : 1e4);
736
731
  return new Promise((resolve, reject) => {
737
732
  const timer = setTimeout(() => {
@@ -747,6 +742,60 @@ var ToolbarModule = class {
747
742
  this.postSheetsGetList({ requestId });
748
743
  });
749
744
  }
745
+ getObjectProperties(options) {
746
+ var _a;
747
+ const requestId = createRequestId("object_properties");
748
+ const timeoutMs = Math.max(1e3, (_a = options == null ? void 0 : options.timeoutMs) != null ? _a : 1e4);
749
+ return new Promise((resolve, reject) => {
750
+ const timer = setTimeout(() => {
751
+ off();
752
+ reject(new Error("Timeout while getting object properties list from viewer"));
753
+ }, timeoutMs);
754
+ const off = this.viewer._on("object-properties:list", (payload) => {
755
+ if (payload.requestId !== requestId) return;
756
+ clearTimeout(timer);
757
+ off();
758
+ resolve(payload.properties);
759
+ });
760
+ this.postObjectPropertiesGetList({ requestId });
761
+ });
762
+ }
763
+ getLinkedObjects(options) {
764
+ var _a;
765
+ const requestId = createRequestId("linked_objects");
766
+ const timeoutMs = Math.max(1e3, (_a = options == null ? void 0 : options.timeoutMs) != null ? _a : 1e4);
767
+ return new Promise((resolve, reject) => {
768
+ const timer = setTimeout(() => {
769
+ off();
770
+ reject(new Error("Timeout while getting linked objects list from viewer"));
771
+ }, timeoutMs);
772
+ const off = this.viewer._on("linked-objects:list", (payload) => {
773
+ if (payload.requestId !== requestId) return;
774
+ clearTimeout(timer);
775
+ off();
776
+ resolve(payload.linkedObjects);
777
+ });
778
+ this.postLinkedObjectsGetList({ requestId });
779
+ });
780
+ }
781
+ getStatesObjects(options) {
782
+ var _a;
783
+ const requestId = createRequestId("states_objects");
784
+ const timeoutMs = Math.max(1e3, (_a = options == null ? void 0 : options.timeoutMs) != null ? _a : 1e4);
785
+ return new Promise((resolve, reject) => {
786
+ const timer = setTimeout(() => {
787
+ off();
788
+ reject(new Error("Timeout while getting states objects list from viewer"));
789
+ }, timeoutMs);
790
+ const off = this.viewer._on("states-objects:list", (payload) => {
791
+ if (payload.requestId !== requestId) return;
792
+ clearTimeout(timer);
793
+ off();
794
+ resolve(payload.statesObjects);
795
+ });
796
+ this.postStatesObjectsGetList({ requestId });
797
+ });
798
+ }
750
799
  applySheet(sheetId) {
751
800
  this.postSheetsApply({ sheetId });
752
801
  }
@@ -789,8 +838,8 @@ var ToolbarModule = class {
789
838
  postConfig(payload) {
790
839
  this.viewer.postToViewer("viewer-toolbar-config" /* TOOLBAR_CONFIG */, payload);
791
840
  }
792
- postToolbarVisibility(payload) {
793
- this.viewer.postToViewer("viewer-toolbar-visibility" /* TOOLBAR_VISIBILITY */, payload);
841
+ postToolbarUse(payload) {
842
+ this.viewer.postToViewer("viewer-toolbar-use" /* TOOLBAR_USE */, payload);
794
843
  }
795
844
  postPanelOpen(payload) {
796
845
  this.viewer.postToViewer("viewer-panel-open" /* PANEL_OPEN */, payload);
@@ -807,6 +856,15 @@ var ToolbarModule = class {
807
856
  postSheetsApply(payload) {
808
857
  this.viewer.postToViewer("viewer-sheets-apply" /* SHEETS_APPLY */, payload);
809
858
  }
859
+ postObjectPropertiesGetList(payload) {
860
+ this.viewer.postToViewer("viewer-object-properties-get-list" /* OBJECT_PROPERTIES_GET_LIST */, payload);
861
+ }
862
+ postLinkedObjectsGetList(payload) {
863
+ this.viewer.postToViewer("viewer-linked-objects-get-list" /* LINKED_OBJECTS_GET_LIST */, payload);
864
+ }
865
+ postStatesObjectsGetList(payload) {
866
+ this.viewer.postToViewer("viewer-states-objects-get-list" /* STATES_OBJECTS_GET_LIST */, payload);
867
+ }
810
868
  };
811
869
 
812
870
  // src/modules/model-tree.module.ts
@@ -963,6 +1021,8 @@ var LanguageModule = class {
963
1021
  };
964
1022
 
965
1023
  // src/viewer.ts
1024
+ var SDK_VIEWER_PATH2 = "/mainviewer-sdk";
1025
+ var LEGACY_VIEWER_PATH2 = "/mainviewer";
966
1026
  var Viewer3D = class {
967
1027
  constructor(options) {
968
1028
  this.options = options;
@@ -1067,6 +1127,54 @@ var Viewer3D = class {
1067
1127
  });
1068
1128
  break;
1069
1129
  }
1130
+ case "viewer-object-properties-list" /* OBJECT_PROPERTIES_LIST */: {
1131
+ const payload = data.payload;
1132
+ if (!payload || !payload.requestId || !Array.isArray(payload.properties)) break;
1133
+ this._emit("object-properties:list", {
1134
+ requestId: String(payload.requestId),
1135
+ properties: payload.properties.filter((item) => item && typeof item === "object").map((item) => ({ ...item })),
1136
+ timestamp: Number(payload.timestamp) || Date.now()
1137
+ });
1138
+ break;
1139
+ }
1140
+ case "viewer-linked-objects-list" /* LINKED_OBJECTS_LIST */: {
1141
+ const payload = data.payload;
1142
+ if (!payload || !payload.requestId || !Array.isArray(payload.linkedObjects)) break;
1143
+ this._emit("linked-objects:list", {
1144
+ requestId: String(payload.requestId),
1145
+ linkedObjects: payload.linkedObjects.filter((item) => item && typeof item === "object").map((item) => ({ ...item })),
1146
+ timestamp: Number(payload.timestamp) || Date.now()
1147
+ });
1148
+ break;
1149
+ }
1150
+ case "viewer-states-objects-list" /* STATES_OBJECTS_LIST */: {
1151
+ const payload = data.payload;
1152
+ if (!payload || !payload.requestId || !Array.isArray(payload.statesObjects)) break;
1153
+ this._emit("states-objects:list", {
1154
+ requestId: String(payload.requestId),
1155
+ statesObjects: payload.statesObjects.map((item) => {
1156
+ var _a2, _b2, _c2, _d2, _e, _f, _g;
1157
+ return {
1158
+ id: String((_a2 = item.id) != null ? _a2 : ""),
1159
+ name: String((_b2 = item.name) != null ? _b2 : ""),
1160
+ char: String((_c2 = item.char) != null ? _c2 : ""),
1161
+ object: Array.isArray(item.object) ? item.object.map((objectItem) => {
1162
+ var _a3;
1163
+ return {
1164
+ name: String((_a3 = objectItem == null ? void 0 : objectItem.name) != null ? _a3 : ""),
1165
+ id: Number(objectItem == null ? void 0 : objectItem.id) || 0
1166
+ };
1167
+ }) : [],
1168
+ states: {
1169
+ color: String((_e = (_d2 = item.states) == null ? void 0 : _d2.color) != null ? _e : ""),
1170
+ type: String((_g = (_f = item.states) == null ? void 0 : _f.type) != null ? _g : "")
1171
+ }
1172
+ };
1173
+ }),
1174
+ timestamp: Number(payload.timestamp) || Date.now()
1175
+ });
1176
+ break;
1177
+ }
1070
1178
  case "viewer-markup-list" /* MARKUP_LIST */: {
1071
1179
  const payload = data.payload;
1072
1180
  if (!payload || !payload.requestId || !Array.isArray(payload.markups)) break;
@@ -1186,18 +1294,39 @@ var Viewer3D = class {
1186
1294
  if (!this.initialized) throw new Error("Call viewer.init() before using viewer");
1187
1295
  }
1188
1296
  withInitialOptions(url) {
1189
- if (!this.options.initialToolbarVisibility) return url;
1190
1297
  try {
1191
1298
  const parsedUrl = new URL(url, window.location.href);
1192
- parsedUrl.searchParams.set(
1193
- "toolbarVisibility",
1194
- JSON.stringify(this.options.initialToolbarVisibility)
1195
- );
1299
+ if (parsedUrl.pathname === LEGACY_VIEWER_PATH2) {
1300
+ parsedUrl.pathname = SDK_VIEWER_PATH2;
1301
+ }
1302
+ const initialToolbar = this.normalizeInitialToolbar();
1303
+ if (initialToolbar) {
1304
+ parsedUrl.searchParams.set("useToolbar", JSON.stringify(initialToolbar));
1305
+ }
1196
1306
  return parsedUrl.toString();
1197
1307
  } catch {
1198
1308
  return url;
1199
1309
  }
1200
1310
  }
1311
+ normalizeInitialToolbar() {
1312
+ const initialToolbar = this.options.initialToolbar;
1313
+ if (!initialToolbar) return null;
1314
+ if (typeof initialToolbar === "string") {
1315
+ return { [initialToolbar]: true };
1316
+ }
1317
+ if (Array.isArray(initialToolbar)) {
1318
+ return initialToolbar.reduce((result, target) => {
1319
+ result[target] = true;
1320
+ return result;
1321
+ }, {});
1322
+ }
1323
+ const entries = Object.entries(initialToolbar).filter(([, enabled]) => enabled === true);
1324
+ if (entries.length === 0) return null;
1325
+ return entries.reduce((result, [target]) => {
1326
+ result[target] = true;
1327
+ return result;
1328
+ }, {});
1329
+ }
1201
1330
  // ===== typed internal events used by modules =====
1202
1331
  _on(event, cb) {
1203
1332
  return this.emitter.on(event, cb);
package/package.json CHANGED
@@ -1,16 +1,21 @@
1
1
  {
2
2
  "name": "3dviewer-sdk",
3
- "version": "1.0.12",
3
+ "version": "1.0.13",
4
4
  "main": "dist/index.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "files": [
7
7
  "dist"
8
8
  ],
9
9
  "scripts": {
10
- "build": "tsup src/index.ts --format cjs,esm --dts --no-splitting"
10
+ "build": "tsup src/index.ts --format cjs,esm --dts --no-splitting",
11
+ "test": "vitest run tests",
12
+ "test:watch": "vitest tests"
11
13
  },
12
14
  "devDependencies": {
15
+ "@vitest/coverage-v8": "^4.1.4",
16
+ "jsdom": "^29.0.2",
13
17
  "tsup": "^8.5.1",
14
- "typescript": "^5.9.3"
18
+ "typescript": "^5.9.3",
19
+ "vitest": "^4.1.4"
15
20
  }
16
21
  }
@@ -1,97 +0,0 @@
1
- import type { MarkupListItem, MarkupOperationResultPayload, PdfCurrentPagePayload, PdfModeEventPayload, PdfToolbarActionEventPayload } from "./messages";
2
- export declare type ViewerEventMap = {
3
- "camera:home": {
4
- timestamp: number;
5
- };
6
- "node:select": {
7
- nodeId: string;
8
- timestamp: number;
9
- };
10
- "interaction:pan-change": {
11
- enabled: boolean;
12
- };
13
- "toolbar:pdf-plan-mode": PdfModeEventPayload;
14
- "toolbar:pdf-document-mode": PdfModeEventPayload;
15
- "toolbar:pdf-first-page": PdfToolbarActionEventPayload;
16
- "toolbar:pdf-previous-page": PdfToolbarActionEventPayload;
17
- "toolbar:pdf-next-page": PdfToolbarActionEventPayload;
18
- "toolbar:pdf-last-page": PdfToolbarActionEventPayload;
19
- "toolbar:pdf-current-page": PdfCurrentPagePayload;
20
- "modelTree:node-ids": {
21
- requestId: string;
22
- nodeIds: string[];
23
- timestamp: number;
24
- };
25
- "sheets:list": {
26
- requestId: string;
27
- sheets: {
28
- id: string | number;
29
- name: string;
30
- is3D?: boolean;
31
- viewId?: string;
32
- }[];
33
- activeSheetId?: string | number | null;
34
- timestamp: number;
35
- };
36
- "markup:list": {
37
- requestId: string;
38
- markups: MarkupListItem[];
39
- timestamp: number;
40
- };
41
- "markup:save": MarkupOperationResultPayload;
42
- "markup:cancel": MarkupOperationResultPayload;
43
- };
44
- export declare type LoadStage = "idle" | "uploading" | "converting" | "rendering" | "completed" | "error";
45
- export declare type LoadStatePayload = {
46
- isLoading: boolean;
47
- stage: LoadStage;
48
- message?: string;
49
- elapsedMs?: number;
50
- };
51
- export declare type PreparedViewerData = {
52
- baseFileId: string;
53
- baseMajorRev: number;
54
- baseMinorRev: number;
55
- fileName: string;
56
- query: string;
57
- url: string;
58
- };
59
- export declare type FilesEventMap = {
60
- "files:state": LoadStatePayload;
61
- "files:upload:start": {
62
- fileName: string;
63
- };
64
- "files:upload:success": {
65
- fileName: string;
66
- baseFileId: string;
67
- };
68
- "files:upload:error": {
69
- fileName: string;
70
- error: string;
71
- };
72
- "files:conversion:start": {
73
- fileName: string;
74
- };
75
- "files:conversion:success": PreparedViewerData;
76
- "files:conversion:error": {
77
- fileName: string;
78
- error: string;
79
- };
80
- "files:render:start": {
81
- url: string;
82
- };
83
- "files:render:success": {
84
- url: string;
85
- };
86
- "files:render:error": {
87
- url?: string;
88
- error: string;
89
- };
90
- "files:load:success": PreparedViewerData;
91
- "files:load:error": {
92
- error: string;
93
- };
94
- };
95
- export declare type SdkEventMap = ViewerEventMap & FilesEventMap;
96
- export declare type SdkEventKey = keyof SdkEventMap;
97
- export declare type SdkEventPayload<K extends SdkEventKey> = SdkEventMap[K];
@@ -1 +0,0 @@
1
- export {};