iflow-engine-base 4.0.16 → 4.0.18

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.
Files changed (142) hide show
  1. package/dist/bim-engine-sdk.es.js +29 -40
  2. package/dist/bim-engine-sdk.umd.js +2754 -2392
  3. package/dist/chunks/{EngineKernel-BLJsCrxR.js → EngineKernel-BucDRg23.js} +2658 -2396
  4. package/dist/chunks/{engine-2d-DneQvSOi.js → engine-2d-BjtuYZUi.js} +5 -5
  5. package/dist/chunks/{engine-3d-B0D38zLu.js → engine-3d-DnlK2vTK.js} +7215 -6460
  6. package/dist/chunks/{engine-720-OdgX2p-d.js → engine-720-DJsweyG9.js} +8 -8
  7. package/dist/chunks/{engine-gaussian-CQdrGBYh.js → engine-gaussian-DklK6vdJ.js} +227 -227
  8. package/dist/chunks/gis-tiles-vendor-DIbUOKJM.js +11781 -0
  9. package/dist/chunks/index-BtsyaVm2.js +2640 -0
  10. package/dist/chunks/{sdk-assets-Dh7PGW73.js → sdk-assets-DtcFvuth.js} +2 -2
  11. package/dist/chunks/{sdk-runtime-KslKRuwI.js → sdk-runtime-CFM9OAcx.js} +761 -762
  12. package/dist/chunks/{sdk-vendor-CVc1LiJj.js → sdk-vendor-6wYtfmXR.js} +31044 -31044
  13. package/dist/chunks/{three-vendor-Ds9cgGKb.js → three-vendor-CGmeNMm5.js} +7963 -7954
  14. package/dist/gis-fixtures/terrain/0/0/0.terrain +0 -0
  15. package/dist/gis-fixtures/terrain/0/1/0.terrain +0 -0
  16. package/dist/gis-fixtures/terrain/1/2/0.terrain +0 -0
  17. package/dist/gis-fixtures/terrain/1/2/1.terrain +0 -0
  18. package/dist/gis-fixtures/terrain/1/3/0.terrain +0 -0
  19. package/dist/gis-fixtures/terrain/1/3/1.terrain +0 -0
  20. package/dist/gis-fixtures/terrain/10/1694/650.terrain +0 -0
  21. package/dist/gis-fixtures/terrain/10/1694/651.terrain +0 -0
  22. package/dist/gis-fixtures/terrain/10/1694/652.terrain +0 -0
  23. package/dist/gis-fixtures/terrain/10/1695/650.terrain +0 -0
  24. package/dist/gis-fixtures/terrain/10/1695/651.terrain +0 -0
  25. package/dist/gis-fixtures/terrain/10/1695/652.terrain +0 -0
  26. package/dist/gis-fixtures/terrain/10/1696/650.terrain +0 -0
  27. package/dist/gis-fixtures/terrain/10/1696/651.terrain +0 -0
  28. package/dist/gis-fixtures/terrain/10/1696/652.terrain +0 -0
  29. package/dist/gis-fixtures/terrain/11/3390/1301.terrain +0 -0
  30. package/dist/gis-fixtures/terrain/11/3390/1302.terrain +0 -0
  31. package/dist/gis-fixtures/terrain/11/3390/1303.terrain +0 -0
  32. package/dist/gis-fixtures/terrain/11/3391/1301.terrain +0 -0
  33. package/dist/gis-fixtures/terrain/11/3391/1302.terrain +0 -0
  34. package/dist/gis-fixtures/terrain/11/3391/1303.terrain +0 -0
  35. package/dist/gis-fixtures/terrain/11/3392/1301.terrain +0 -0
  36. package/dist/gis-fixtures/terrain/11/3392/1302.terrain +0 -0
  37. package/dist/gis-fixtures/terrain/11/3392/1303.terrain +0 -0
  38. package/dist/gis-fixtures/terrain/12/6782/2604.terrain +0 -0
  39. package/dist/gis-fixtures/terrain/12/6782/2605.terrain +0 -0
  40. package/dist/gis-fixtures/terrain/12/6782/2606.terrain +0 -0
  41. package/dist/gis-fixtures/terrain/12/6783/2604.terrain +0 -0
  42. package/dist/gis-fixtures/terrain/12/6783/2605.terrain +0 -0
  43. package/dist/gis-fixtures/terrain/12/6783/2606.terrain +0 -0
  44. package/dist/gis-fixtures/terrain/12/6784/2604.terrain +0 -0
  45. package/dist/gis-fixtures/terrain/12/6784/2605.terrain +0 -0
  46. package/dist/gis-fixtures/terrain/12/6784/2606.terrain +0 -0
  47. package/dist/gis-fixtures/terrain/13/13565/5209.terrain +0 -0
  48. package/dist/gis-fixtures/terrain/13/13565/5210.terrain +0 -0
  49. package/dist/gis-fixtures/terrain/13/13565/5211.terrain +0 -0
  50. package/dist/gis-fixtures/terrain/13/13566/5209.terrain +0 -0
  51. package/dist/gis-fixtures/terrain/13/13566/5210.terrain +0 -0
  52. package/dist/gis-fixtures/terrain/13/13566/5211.terrain +0 -0
  53. package/dist/gis-fixtures/terrain/13/13567/5209.terrain +0 -0
  54. package/dist/gis-fixtures/terrain/13/13567/5210.terrain +0 -0
  55. package/dist/gis-fixtures/terrain/13/13567/5211.terrain +0 -0
  56. package/dist/gis-fixtures/terrain/14/27131/10419.terrain +0 -0
  57. package/dist/gis-fixtures/terrain/14/27131/10420.terrain +0 -0
  58. package/dist/gis-fixtures/terrain/14/27131/10421.terrain +0 -0
  59. package/dist/gis-fixtures/terrain/14/27132/10419.terrain +0 -0
  60. package/dist/gis-fixtures/terrain/14/27132/10420.terrain +0 -0
  61. package/dist/gis-fixtures/terrain/14/27132/10421.terrain +0 -0
  62. package/dist/gis-fixtures/terrain/14/27133/10419.terrain +0 -0
  63. package/dist/gis-fixtures/terrain/14/27133/10420.terrain +0 -0
  64. package/dist/gis-fixtures/terrain/14/27133/10421.terrain +0 -0
  65. package/dist/gis-fixtures/terrain/2/5/1.terrain +0 -0
  66. package/dist/gis-fixtures/terrain/2/5/2.terrain +0 -0
  67. package/dist/gis-fixtures/terrain/2/5/3.terrain +0 -0
  68. package/dist/gis-fixtures/terrain/2/6/1.terrain +0 -0
  69. package/dist/gis-fixtures/terrain/2/6/2.terrain +0 -0
  70. package/dist/gis-fixtures/terrain/2/6/3.terrain +0 -0
  71. package/dist/gis-fixtures/terrain/2/7/1.terrain +0 -0
  72. package/dist/gis-fixtures/terrain/2/7/2.terrain +0 -0
  73. package/dist/gis-fixtures/terrain/2/7/3.terrain +0 -0
  74. package/dist/gis-fixtures/terrain/3/12/4.terrain +0 -0
  75. package/dist/gis-fixtures/terrain/3/12/5.terrain +0 -0
  76. package/dist/gis-fixtures/terrain/3/12/6.terrain +0 -0
  77. package/dist/gis-fixtures/terrain/3/13/4.terrain +0 -0
  78. package/dist/gis-fixtures/terrain/3/13/5.terrain +0 -0
  79. package/dist/gis-fixtures/terrain/3/13/6.terrain +0 -0
  80. package/dist/gis-fixtures/terrain/3/14/4.terrain +0 -0
  81. package/dist/gis-fixtures/terrain/3/14/5.terrain +0 -0
  82. package/dist/gis-fixtures/terrain/3/14/6.terrain +0 -0
  83. package/dist/gis-fixtures/terrain/4/25/10.terrain +0 -0
  84. package/dist/gis-fixtures/terrain/4/25/11.terrain +0 -0
  85. package/dist/gis-fixtures/terrain/4/25/9.terrain +0 -0
  86. package/dist/gis-fixtures/terrain/4/26/10.terrain +0 -0
  87. package/dist/gis-fixtures/terrain/4/26/11.terrain +0 -0
  88. package/dist/gis-fixtures/terrain/4/26/9.terrain +0 -0
  89. package/dist/gis-fixtures/terrain/4/27/10.terrain +0 -0
  90. package/dist/gis-fixtures/terrain/4/27/11.terrain +0 -0
  91. package/dist/gis-fixtures/terrain/4/27/9.terrain +0 -0
  92. package/dist/gis-fixtures/terrain/5/51/19.terrain +0 -0
  93. package/dist/gis-fixtures/terrain/5/51/20.terrain +0 -0
  94. package/dist/gis-fixtures/terrain/5/51/21.terrain +0 -0
  95. package/dist/gis-fixtures/terrain/5/52/19.terrain +0 -0
  96. package/dist/gis-fixtures/terrain/5/52/20.terrain +0 -0
  97. package/dist/gis-fixtures/terrain/5/52/21.terrain +0 -0
  98. package/dist/gis-fixtures/terrain/5/53/19.terrain +0 -0
  99. package/dist/gis-fixtures/terrain/5/53/20.terrain +0 -0
  100. package/dist/gis-fixtures/terrain/5/53/21.terrain +0 -0
  101. package/dist/gis-fixtures/terrain/6/104/39.terrain +0 -0
  102. package/dist/gis-fixtures/terrain/6/104/40.terrain +0 -0
  103. package/dist/gis-fixtures/terrain/6/104/41.terrain +0 -0
  104. package/dist/gis-fixtures/terrain/6/105/39.terrain +0 -0
  105. package/dist/gis-fixtures/terrain/6/105/40.terrain +0 -0
  106. package/dist/gis-fixtures/terrain/6/105/41.terrain +0 -0
  107. package/dist/gis-fixtures/terrain/6/106/39.terrain +0 -0
  108. package/dist/gis-fixtures/terrain/6/106/40.terrain +0 -0
  109. package/dist/gis-fixtures/terrain/6/106/41.terrain +0 -0
  110. package/dist/gis-fixtures/terrain/7/210/80.terrain +0 -0
  111. package/dist/gis-fixtures/terrain/7/210/81.terrain +0 -0
  112. package/dist/gis-fixtures/terrain/7/210/82.terrain +0 -0
  113. package/dist/gis-fixtures/terrain/7/211/80.terrain +0 -0
  114. package/dist/gis-fixtures/terrain/7/211/81.terrain +0 -0
  115. package/dist/gis-fixtures/terrain/7/211/82.terrain +0 -0
  116. package/dist/gis-fixtures/terrain/7/212/80.terrain +0 -0
  117. package/dist/gis-fixtures/terrain/7/212/81.terrain +0 -0
  118. package/dist/gis-fixtures/terrain/7/212/82.terrain +0 -0
  119. package/dist/gis-fixtures/terrain/8/422/161.terrain +0 -0
  120. package/dist/gis-fixtures/terrain/8/422/162.terrain +0 -0
  121. package/dist/gis-fixtures/terrain/8/422/163.terrain +0 -0
  122. package/dist/gis-fixtures/terrain/8/423/161.terrain +0 -0
  123. package/dist/gis-fixtures/terrain/8/423/162.terrain +0 -0
  124. package/dist/gis-fixtures/terrain/8/423/163.terrain +0 -0
  125. package/dist/gis-fixtures/terrain/8/424/161.terrain +0 -0
  126. package/dist/gis-fixtures/terrain/8/424/162.terrain +0 -0
  127. package/dist/gis-fixtures/terrain/8/424/163.terrain +0 -0
  128. package/dist/gis-fixtures/terrain/9/846/324.terrain +0 -0
  129. package/dist/gis-fixtures/terrain/9/846/325.terrain +0 -0
  130. package/dist/gis-fixtures/terrain/9/846/326.terrain +0 -0
  131. package/dist/gis-fixtures/terrain/9/847/324.terrain +0 -0
  132. package/dist/gis-fixtures/terrain/9/847/325.terrain +0 -0
  133. package/dist/gis-fixtures/terrain/9/847/326.terrain +0 -0
  134. package/dist/gis-fixtures/terrain/9/848/324.terrain +0 -0
  135. package/dist/gis-fixtures/terrain/9/848/325.terrain +0 -0
  136. package/dist/gis-fixtures/terrain/9/848/326.terrain +0 -0
  137. package/dist/gis-fixtures/terrain/layer.json +141 -0
  138. package/dist/iflow-engine-base.css +1 -1
  139. package/dist/index.d.ts +915 -1706
  140. package/package.json +8 -21
  141. package/dist/chunks/gis-tiles-vendor-Dr7piDQM.js +0 -11386
  142. package/dist/chunks/index-DjNAYhvI.js +0 -5252
@@ -1,6 +1,205 @@
1
- import { f as Te, e as z, V as le, t as Ae, bf as Ce } from "./three-vendor-Ds9cgGKb.js";
2
- import { a as Se, J as ye, p as Le, l as ee } from "./sdk-vendor-CVc1LiJj.js";
1
+ import { R as Te, V as R, a as le, P as Ae, F as Ce } from "./three-vendor-CGmeNMm5.js";
2
+ import { l as ee, a as Se, J as ye, p as Le } from "./sdk-vendor-6wYtfmXR.js";
3
3
  class Mt {
4
+ container;
5
+ labelContainer;
6
+ projectCoordinate;
7
+ pickCoordinate;
8
+ emitEvent;
9
+ labels = /* @__PURE__ */ new Map();
10
+ clickCallbacks = /* @__PURE__ */ new Set();
11
+ pickResolver = null;
12
+ isPicking = !1;
13
+ constructor(e) {
14
+ this.container = e.container, this.projectCoordinate = e.projectCoordinate, this.pickCoordinate = e.pickCoordinate, this.emitEvent = e.emitEvent, this.labelContainer = document.createElement("div"), this.labelContainer.className = e.className ?? "bim-engine-label-container", this.labelContainer.style.cssText = [
15
+ "position:absolute",
16
+ "left:0",
17
+ "top:0",
18
+ "width:100%",
19
+ "height:100%",
20
+ "pointer-events:none",
21
+ "overflow:hidden",
22
+ "z-index:1200"
23
+ ].join(";"), this.container.appendChild(this.labelContainer);
24
+ }
25
+ /**
26
+ * 开启一次选点,下一次画布点击会返回当前引擎坐标。
27
+ */
28
+ pickPoint() {
29
+ return this.cancelPick(), this.isPicking = !0, this.container.style.cursor = "crosshair", this.addPickBlockers(), this.container.addEventListener("click", this.handlePickClick, !0), new Promise((e) => {
30
+ this.pickResolver = e;
31
+ });
32
+ }
33
+ /**
34
+ * 兼容回调式调用,便于旧业务页面直接绑定按钮。
35
+ */
36
+ startPickPoint(e) {
37
+ const t = this.pickPoint();
38
+ return e && t.then(e), t;
39
+ }
40
+ /**
41
+ * 创建标签,返回最终标签 id。
42
+ */
43
+ createLabel(e) {
44
+ const t = e.id ?? this.createId();
45
+ if (this.labels.has(t))
46
+ throw new Error(`LabelManager: label "${t}" already exists`);
47
+ const r = this.createElement(t), i = {
48
+ id: t,
49
+ coordinate: { ...e.coordinate },
50
+ icon: e.icon,
51
+ name: e.name,
52
+ data: e.data,
53
+ size: e.iconSize ?? e.size ?? 28,
54
+ visible: e.visible ?? !0,
55
+ element: r
56
+ };
57
+ return this.labels.set(t, i), this.labelContainer.appendChild(r), this.renderLabel(i), this.updateLabelPosition(i), this.emitEvent?.("label-created", this.toPayload(i)), t;
58
+ }
59
+ /**
60
+ * 更新标签,支持按需修改坐标、图标、名称和业务数据。
61
+ */
62
+ updateLabel(e, t) {
63
+ const r = this.labels.get(e);
64
+ return r ? (t.coordinate && (r.coordinate = { ...t.coordinate }), t.icon !== void 0 && (r.icon = t.icon), t.name !== void 0 && (r.name = t.name), t.data !== void 0 && (r.data = t.data), t.iconSize !== void 0 && (r.size = t.iconSize), t.size !== void 0 && (r.size = t.size), t.visible !== void 0 && (r.visible = t.visible), this.renderLabel(r), this.updateLabelPosition(r), this.emitEvent?.("label-updated", this.toPayload(r)), !0) : !1;
65
+ }
66
+ /**
67
+ * 删除指定标签。
68
+ */
69
+ deleteLabel(e) {
70
+ const t = this.labels.get(e);
71
+ return t ? (t.element.remove(), this.labels.delete(e), this.emitEvent?.("label-deleted", { id: e }), !0) : !1;
72
+ }
73
+ removeLabel(e) {
74
+ return this.deleteLabel(e);
75
+ }
76
+ clearLabels() {
77
+ Array.from(this.labels.keys()).forEach((e) => this.deleteLabel(e));
78
+ }
79
+ getLabel(e) {
80
+ return this.labels.get(e);
81
+ }
82
+ getLabels() {
83
+ return Array.from(this.labels.values());
84
+ }
85
+ onLabelClick(e) {
86
+ return this.clickCallbacks.add(e), () => this.offLabelClick(e);
87
+ }
88
+ offLabelClick(e) {
89
+ this.clickCallbacks.delete(e);
90
+ }
91
+ /**
92
+ * 每帧同步标签屏幕位置。
93
+ */
94
+ update() {
95
+ this.labels.forEach((e) => this.updateLabelPosition(e));
96
+ }
97
+ cancelPick() {
98
+ this.isPicking && (this.isPicking = !1, this.container.style.cursor = "", this.removePickBlockers(), this.container.removeEventListener("click", this.handlePickClick, !0), this.pickResolver?.(null), this.pickResolver = null);
99
+ }
100
+ dispose() {
101
+ this.cancelPick(), this.clearLabels(), this.clickCallbacks.clear(), this.labelContainer.remove();
102
+ }
103
+ createElement(e) {
104
+ const t = document.createElement("div");
105
+ return t.dataset.labelId = e, t.style.cssText = [
106
+ "position:absolute",
107
+ "display:flex",
108
+ "flex-direction:column",
109
+ "align-items:center",
110
+ "gap:5px",
111
+ "transform:translate(-50%, -100%)",
112
+ "pointer-events:auto",
113
+ "cursor:pointer",
114
+ "user-select:none",
115
+ "white-space:nowrap",
116
+ "font:12px/1.2 -apple-system,BlinkMacSystemFont,Segoe UI,Arial,sans-serif"
117
+ ].join(";"), t.addEventListener("click", (r) => {
118
+ r.preventDefault(), r.stopPropagation();
119
+ const i = this.labels.get(e);
120
+ if (!i) return;
121
+ const o = {
122
+ id: e,
123
+ label: i,
124
+ coordinate: i.coordinate,
125
+ originalEvent: r
126
+ };
127
+ this.clickCallbacks.forEach((s) => s(o)), this.emitEvent?.("label-click", o);
128
+ }), t;
129
+ }
130
+ renderLabel(e) {
131
+ e.element.innerHTML = "";
132
+ const t = document.createElement("img"), r = this.normalizeIconSize(e.size);
133
+ t.src = e.icon, t.alt = e.name, t.style.cssText = [
134
+ `width:${r.width}px`,
135
+ `height:${r.height}px`,
136
+ "object-fit:contain",
137
+ "display:block",
138
+ "filter:drop-shadow(0 3px 5px rgba(0,0,0,.32))"
139
+ ].join(";");
140
+ const i = document.createElement("span");
141
+ i.textContent = e.name, i.style.cssText = [
142
+ "max-width:160px",
143
+ "overflow:hidden",
144
+ "text-overflow:ellipsis",
145
+ "padding:5px 9px",
146
+ "border-radius:6px",
147
+ "background:rgba(15,23,42,.88)",
148
+ "color:#fff",
149
+ "border:1px solid rgba(255,255,255,.16)",
150
+ "box-shadow:0 3px 10px rgba(0,0,0,.24)"
151
+ ].join(";"), e.element.title = e.name, e.element.appendChild(i), e.element.appendChild(t);
152
+ }
153
+ updateLabelPosition(e) {
154
+ const t = this.projectCoordinate(e.coordinate);
155
+ if (!(e.visible && t != null && t.visible !== !1) || !t) {
156
+ e.element.style.display = "none";
157
+ return;
158
+ }
159
+ e.element.style.display = "flex", e.element.style.left = `${t.x}px`, e.element.style.top = `${t.y}px`;
160
+ }
161
+ handlePickClick = (e) => {
162
+ e.preventDefault(), e.stopImmediatePropagation();
163
+ const t = this.pickCoordinate(e);
164
+ this.isPicking = !1, this.container.style.cursor = "", this.removePickBlockers(), this.container.removeEventListener("click", this.handlePickClick, !0), this.pickResolver?.(t), this.pickResolver = null, t && this.emitEvent?.("label-pick", t);
165
+ };
166
+ toPayload(e) {
167
+ return {
168
+ id: e.id,
169
+ coordinate: e.coordinate,
170
+ icon: e.icon,
171
+ name: e.name,
172
+ data: e.data,
173
+ size: e.size,
174
+ visible: e.visible
175
+ };
176
+ }
177
+ normalizeIconSize(e) {
178
+ return typeof e == "number" ? {
179
+ width: e,
180
+ height: e
181
+ } : {
182
+ width: this.normalizeSizeValue(e.width, 28),
183
+ height: this.normalizeSizeValue(e.height, 28)
184
+ };
185
+ }
186
+ normalizeSizeValue(e, t) {
187
+ return Number.isFinite(e) && e > 0 ? e : t;
188
+ }
189
+ createId() {
190
+ return `label-${Date.now()}-${Math.random().toString(16).slice(2)}`;
191
+ }
192
+ addPickBlockers() {
193
+ this.container.addEventListener("mousedown", this.blockPickInteraction, !0), this.container.addEventListener("mouseup", this.blockPickInteraction, !0), this.container.addEventListener("touchstart", this.blockPickInteraction, !0), this.container.addEventListener("touchmove", this.blockPickInteraction, !0), this.container.addEventListener("touchend", this.blockPickInteraction, !0);
194
+ }
195
+ removePickBlockers() {
196
+ this.container.removeEventListener("mousedown", this.blockPickInteraction, !0), this.container.removeEventListener("mouseup", this.blockPickInteraction, !0), this.container.removeEventListener("touchstart", this.blockPickInteraction, !0), this.container.removeEventListener("touchmove", this.blockPickInteraction, !0), this.container.removeEventListener("touchend", this.blockPickInteraction, !0);
197
+ }
198
+ blockPickInteraction = (e) => {
199
+ e.stopImmediatePropagation();
200
+ };
201
+ }
202
+ class Bt {
4
203
  /**
5
204
  * 构造函数
6
205
  * @param camera - Three.js 相机对象(用于投影计算)
@@ -23,7 +222,7 @@ class Mt {
23
222
  */
24
223
  worldToScreenNormalized(e) {
25
224
  const t = e.clone();
26
- return t.project(this.camera), new z(t.x, t.y);
225
+ return t.project(this.camera), new R(t.x, t.y);
27
226
  }
28
227
  /**
29
228
  * 将世界坐标转换为屏幕坐标(像素坐标)
@@ -34,7 +233,7 @@ class Mt {
34
233
  */
35
234
  worldToScreen(e) {
36
235
  const t = new le();
37
- return t.copy(e).project(this.camera), t.x = t.x * this.renderer.domElement.clientWidth * 0.5, t.y = -t.y * this.renderer.domElement.clientHeight * 0.5, t.z = (t.z + 1) * 0.5, t.x += this.renderer.domElement.clientWidth * 0.5, t.y += this.renderer.domElement.clientHeight * 0.5, new z(t.x, t.y);
236
+ return t.copy(e).project(this.camera), t.x = t.x * this.renderer.domElement.clientWidth * 0.5, t.y = -t.y * this.renderer.domElement.clientHeight * 0.5, t.z = (t.z + 1) * 0.5, t.x += this.renderer.domElement.clientWidth * 0.5, t.y += this.renderer.domElement.clientHeight * 0.5, new R(t.x, t.y);
38
237
  }
39
238
  /**
40
239
  * 将世界坐标转换为屏幕坐标,仅在点位于当前相机可见裁剪空间内时返回结果。
@@ -49,7 +248,7 @@ class Mt {
49
248
  if (!Number.isFinite(t.x) || !Number.isFinite(t.y) || !Number.isFinite(t.z) || t.z < -1 || t.z > 1)
50
249
  return null;
51
250
  const r = this.renderer.domElement.clientWidth, i = this.renderer.domElement.clientHeight;
52
- return new z(
251
+ return new R(
53
252
  t.x * r * 0.5 + r * 0.5,
54
253
  -t.y * i * 0.5 + i * 0.5
55
254
  );
@@ -62,7 +261,7 @@ class Mt {
62
261
  */
63
262
  screenToNormalized(e, t) {
64
263
  const r = this.renderer.domElement.clientWidth, i = this.renderer.domElement.clientHeight, o = e / r * 2 - 1, s = -(t / i * 2 - 1);
65
- return new z(o, s);
264
+ return new R(o, s);
66
265
  }
67
266
  /**
68
267
  * 将屏幕坐标(像素坐标)转换为世界坐标
@@ -115,77 +314,244 @@ class Mt {
115
314
  this.scene = e;
116
315
  }
117
316
  }
118
- function te(n) {
119
- return n instanceof Uint8Array || ArrayBuffer.isView(n) && n.constructor.name === "Uint8Array" && "BYTES_PER_ELEMENT" in n && n.BYTES_PER_ELEMENT === 1;
120
- }
121
- const ne = (n) => n ? `"${n}" ` : "";
122
- function re(n, e = "") {
123
- if (typeof n != "number")
124
- throw new TypeError(ne(e) + "expected number, got " + typeof n);
125
- if (!Number.isSafeInteger(n) || n < 0)
126
- throw new RangeError(ne(e) + "expected integer >= 0, got " + n);
317
+ const Pe = "4.0.18", Ue = {
318
+ version: Pe
319
+ }, N = Ue.version;
320
+ function se() {
321
+ const n = globalThis.crypto?.subtle;
322
+ if (!n)
323
+ throw new Error("[BimEngine] Web Crypto API is required for secure sdkAuth credentials mode");
127
324
  return n;
128
325
  }
129
- function w(n, e, t = "") {
130
- if (te(n) && (e === void 0 || n.length === e))
131
- return n;
132
- e !== void 0 && re(e, "length");
133
- const r = te(n), i = e !== void 0 ? ` of length ${e}` : "", o = r ? `length=${n.length}` : `type=${typeof n}`, s = ne(t) + "expected Uint8Array" + i + ", got " + o;
134
- throw r ? new RangeError(s) : new TypeError(s);
135
- }
136
- function ue(n, e = !0) {
137
- if (n.destroyed)
138
- throw new Error("hash was destroyed");
139
- if (e && n.finished)
140
- throw new Error("digest() was already called");
326
+ function U(n) {
327
+ return new TextEncoder().encode(n);
141
328
  }
142
- function Pe(n, e) {
143
- w(n, void 0, "output");
144
- const t = e.outputLen;
145
- if (!(n.length >= t))
146
- throw new RangeError('"output" expected length >= ' + t);
329
+ function I(n) {
330
+ return n.buffer.slice(n.byteOffset, n.byteOffset + n.byteLength);
147
331
  }
148
- function Ue(n, e) {
149
- if (Pe(n, e), !U(n))
150
- throw new Error("invalid output, must be aligned");
332
+ function ue(n) {
333
+ let e = "";
334
+ return n.forEach((t) => {
335
+ e += String.fromCharCode(t);
336
+ }), btoa(e);
151
337
  }
152
338
  function Ie(n) {
153
- return new Uint8Array(n.buffer, n.byteOffset, n.byteLength);
154
- }
155
- function A(n) {
156
- return new Uint32Array(n.buffer, n.byteOffset, Math.floor(n.byteLength / 4));
157
- }
158
- function v(...n) {
159
- for (let e = 0; e < n.length; e++)
160
- n[e].fill(0);
161
- }
162
- function F(n) {
163
- return new DataView(n.buffer, n.byteOffset, n.byteLength);
339
+ const e = n.getUTCFullYear(), t = String(n.getUTCMonth() + 1).padStart(2, "0"), r = String(n.getUTCDate()).padStart(2, "0");
340
+ return `${e}${t}${r}`;
164
341
  }
165
- const q = new Uint8Array(new Uint32Array([287454020]).buffer)[0] === 68;
166
- function me(n) {
167
- return n << 24 & 4278190080 | n << 8 & 16711680 | n >>> 8 & 65280 | n >>> 24 & 255;
342
+ async function Me(n) {
343
+ const e = await se().digest("SHA-256", I(U(n)));
344
+ return Array.from(new Uint8Array(e)).map((t) => t.toString(16).padStart(2, "0")).join("");
168
345
  }
169
- const m = q ? (n) => n : (n) => me(n) >>> 0;
170
- function Me(n) {
171
- for (let e = 0; e < n.length; e++)
172
- n[e] = me(n[e]);
173
- return n;
346
+ async function Be(n, e) {
347
+ const t = se(), r = await t.importKey("raw", I(n), { name: "HMAC", hash: "SHA-256" }, !1, ["sign"]);
348
+ return t.sign("HMAC", r, I(U(e)));
174
349
  }
175
- const se = q ? (n) => n : Me;
176
- function Be(n, e) {
177
- if (n = w(n), e = w(e), n.length !== e.length)
178
- return !1;
179
- let t = 0;
180
- for (let r = 0; r < n.length; r++)
181
- t |= n[r] ^ e[r];
182
- return t === 0;
350
+ function Re(n) {
351
+ return U(
352
+ [n.appId, n.engineType, n.requestDate, String(n.timestamp), n.nonce].join("|")
353
+ );
183
354
  }
184
- function ze(n, e, t) {
185
- const r = e, i = t || (() => []), o = (c, a) => r(a, ...i(c)).update(c).digest(), s = r(new Uint8Array(n), ...i(new Uint8Array(0)));
355
+ async function ze(n) {
356
+ const e = se(), t = /* @__PURE__ */ new Date(), r = t.getTime(), i = Ie(t), o = globalThis.crypto.randomUUID(), s = globalThis.crypto.getRandomValues(new Uint8Array(12)), c = await Me(n.appSecret), a = await Be(U(c), i), l = await e.importKey("raw", a, "AES-GCM", !1, ["encrypt"]), d = JSON.stringify({
357
+ appKey: n.appKey,
358
+ appSecret: n.appSecret
359
+ }), u = await e.encrypt(
360
+ {
361
+ name: "AES-GCM",
362
+ iv: s,
363
+ additionalData: I(Re({
364
+ appId: n.appId,
365
+ engineType: n.engineType,
366
+ requestDate: i,
367
+ timestamp: r,
368
+ nonce: o
369
+ })),
370
+ tagLength: 128
371
+ },
372
+ l,
373
+ I(U(d))
374
+ );
375
+ return {
376
+ appId: n.appId,
377
+ engineType: n.engineType,
378
+ requestDate: i,
379
+ timestamp: r,
380
+ nonce: o,
381
+ iv: ue(s),
382
+ cipherText: ue(new Uint8Array(u)),
383
+ sdkVersion: n.sdkVersion,
384
+ origin: n.origin,
385
+ product: n.product
386
+ };
387
+ }
388
+ const Z = /* @__PURE__ */ new Map();
389
+ function V(n) {
390
+ return n.replace(/\/+$/, "");
391
+ }
392
+ function D(n) {
393
+ if (n) return n;
394
+ if (typeof window < "u" && typeof window.location?.origin == "string")
395
+ return window.location.origin;
396
+ }
397
+ function _e(n, e) {
398
+ return JSON.stringify({
399
+ endpoint: V(n.endpoint),
400
+ token: n.token ?? "",
401
+ appId: n.appId ?? "",
402
+ appKey: n.appKey ?? "",
403
+ appSecret: n.appSecret ?? "",
404
+ origin: D(n.origin) ?? "",
405
+ product: n.product ?? "",
406
+ engineType: e,
407
+ sdkVersion: N
408
+ });
409
+ }
410
+ async function te(n, e, t) {
411
+ const r = typeof AbortController < "u" ? new AbortController() : void 0, i = r ? setTimeout(() => r.abort(), t) : void 0;
412
+ try {
413
+ const o = await fetch(n, {
414
+ method: "POST",
415
+ headers: {
416
+ "Content-Type": "application/json"
417
+ },
418
+ body: JSON.stringify(e),
419
+ signal: r?.signal
420
+ }), s = await o.json().catch(() => ({}));
421
+ if (!o.ok) {
422
+ const c = s?.error?.message ?? s?.message ?? `SDK authentication failed with status ${o.status}`;
423
+ throw new Error(c);
424
+ }
425
+ return s;
426
+ } finally {
427
+ i != null && clearTimeout(i);
428
+ }
429
+ }
430
+ async function $e(n, e) {
431
+ const t = await te(`${V(n.endpoint)}/oauth/sdk-verify`, {
432
+ sdkToken: n.token,
433
+ engineType: e,
434
+ sdkVersion: N,
435
+ origin: D(n.origin),
436
+ product: n.product
437
+ }, n.timeoutMs ?? 8e3);
438
+ return t.sdkToken = n.token, t;
439
+ }
440
+ async function Ke(n, e) {
441
+ const t = await ze({
442
+ appId: n.appId,
443
+ appKey: n.appKey,
444
+ appSecret: n.appSecret,
445
+ engineType: e,
446
+ sdkVersion: N,
447
+ origin: D(n.origin),
448
+ product: n.product
449
+ }), r = await te(
450
+ `${V(n.endpoint)}/oauth/sdk-token/secure`,
451
+ t,
452
+ n.timeoutMs ?? 8e3
453
+ ), i = await te(`${V(n.endpoint)}/oauth/sdk-verify`, {
454
+ sdkToken: r.sdkToken,
455
+ engineType: e,
456
+ sdkVersion: N,
457
+ origin: D(n.origin),
458
+ product: n.product
459
+ }, n.timeoutMs ?? 8e3);
460
+ return i.sdkToken = r.sdkToken, i;
461
+ }
462
+ async function Oe(n, e) {
463
+ const t = n?.sdkAuth;
464
+ if (!t)
465
+ return null;
466
+ if (!t.endpoint)
467
+ throw new Error("[BimEngine] sdkAuth.endpoint is required");
468
+ if (!t.token && !(t.appId && t.appKey && t.appSecret))
469
+ return null;
470
+ const r = _e(t, e), i = Z.get(r);
471
+ if (i) {
472
+ const s = await i;
473
+ return n && (n.__sdkAuthSession = s), s;
474
+ }
475
+ const o = (t.token ? $e(t, e) : Ke(t, e)).then((s) => {
476
+ if (s.authorized !== !0)
477
+ throw new Error("[BimEngine] SDK authorization rejected");
478
+ return n && (n.__sdkAuthSession = s), s;
479
+ }).catch((s) => {
480
+ throw Z.delete(r), s;
481
+ });
482
+ return Z.set(r, o), o;
483
+ }
484
+ function ne(n) {
485
+ return n instanceof Uint8Array || ArrayBuffer.isView(n) && n.constructor.name === "Uint8Array" && "BYTES_PER_ELEMENT" in n && n.BYTES_PER_ELEMENT === 1;
486
+ }
487
+ const re = (n) => n ? `"${n}" ` : "";
488
+ function ie(n, e = "") {
489
+ if (typeof n != "number")
490
+ throw new TypeError(re(e) + "expected number, got " + typeof n);
491
+ if (!Number.isSafeInteger(n) || n < 0)
492
+ throw new RangeError(re(e) + "expected integer >= 0, got " + n);
493
+ return n;
494
+ }
495
+ function w(n, e, t = "") {
496
+ if (ne(n) && (e === void 0 || n.length === e))
497
+ return n;
498
+ e !== void 0 && ie(e, "length");
499
+ const r = ne(n), i = e !== void 0 ? ` of length ${e}` : "", o = r ? `length=${n.length}` : `type=${typeof n}`, s = re(t) + "expected Uint8Array" + i + ", got " + o;
500
+ throw r ? new RangeError(s) : new TypeError(s);
501
+ }
502
+ function de(n, e = !0) {
503
+ if (n.destroyed)
504
+ throw new Error("hash was destroyed");
505
+ if (e && n.finished)
506
+ throw new Error("digest() was already called");
507
+ }
508
+ function je(n, e) {
509
+ w(n, void 0, "output");
510
+ const t = e.outputLen;
511
+ if (!(n.length >= t))
512
+ throw new RangeError('"output" expected length >= ' + t);
513
+ }
514
+ function We(n, e) {
515
+ if (je(n, e), !M(n))
516
+ throw new Error("invalid output, must be aligned");
517
+ }
518
+ function Ne(n) {
519
+ return new Uint8Array(n.buffer, n.byteOffset, n.byteLength);
520
+ }
521
+ function A(n) {
522
+ return new Uint32Array(n.buffer, n.byteOffset, Math.floor(n.byteLength / 4));
523
+ }
524
+ function v(...n) {
525
+ for (let e = 0; e < n.length; e++)
526
+ n[e].fill(0);
527
+ }
528
+ function F(n) {
529
+ return new DataView(n.buffer, n.byteOffset, n.byteLength);
530
+ }
531
+ const q = new Uint8Array(new Uint32Array([287454020]).buffer)[0] === 68;
532
+ function me(n) {
533
+ return n << 24 & 4278190080 | n << 8 & 16711680 | n >>> 8 & 65280 | n >>> 24 & 255;
534
+ }
535
+ const m = q ? (n) => n : (n) => me(n) >>> 0;
536
+ function Ve(n) {
537
+ for (let e = 0; e < n.length; e++)
538
+ n[e] = me(n[e]);
539
+ return n;
540
+ }
541
+ const ce = q ? (n) => n : Ve;
542
+ function De(n, e) {
543
+ if (n = w(n), e = w(e), n.length !== e.length)
544
+ return !1;
545
+ let t = 0;
546
+ for (let r = 0; r < n.length; r++)
547
+ t |= n[r] ^ e[r];
548
+ return t === 0;
549
+ }
550
+ function He(n, e, t) {
551
+ const r = e, i = t || (() => []), o = (c, a) => r(a, ...i(c)).update(c).digest(), s = r(new Uint8Array(n), ...i(new Uint8Array(0)));
186
552
  return o.outputLen = s.outputLen, o.blockLen = s.blockLen, o.create = (c, ...a) => r(c, ...a), o;
187
553
  }
188
- const Re = /* @__NO_SIDE_EFFECTS__ */ (n, e) => {
554
+ const Fe = /* @__NO_SIDE_EFFECTS__ */ (n, e) => {
189
555
  function t(r, ...i) {
190
556
  if (w(r, void 0, "key"), n.nonceLength !== void 0) {
191
557
  const u = i[0];
@@ -194,7 +560,7 @@ const Re = /* @__NO_SIDE_EFFECTS__ */ (n, e) => {
194
560
  const o = n.tagLength, s = n.nonceLength !== void 0 ? 1 : 0;
195
561
  if (!n.withAAD) {
196
562
  for (let u = s; u < i.length; u++)
197
- if (te(i[u]))
563
+ if (ne(i[u]))
198
564
  throw new Error("AAD not supported");
199
565
  }
200
566
  n.withAAD && i[s] !== void 0 && w(i[s], void 0, "AAD");
@@ -221,25 +587,25 @@ const Re = /* @__NO_SIDE_EFFECTS__ */ (n, e) => {
221
587
  }
222
588
  return Object.assign(t, n), t;
223
589
  };
224
- function _e(n, e, t = !0) {
590
+ function qe(n, e, t = !0) {
225
591
  if (e === void 0)
226
592
  return new Uint8Array(n);
227
- if (w(e, n, "output"), t && !U(e))
593
+ if (w(e, n, "output"), t && !M(e))
228
594
  throw new Error("invalid output, must be aligned");
229
595
  return e;
230
596
  }
231
- function $e(n, e, t) {
232
- re(n), re(e);
597
+ function Ye(n, e, t) {
598
+ ie(n), ie(e);
233
599
  const r = new Uint8Array(16), i = F(r);
234
600
  return i.setBigUint64(0, BigInt(e), t), i.setBigUint64(8, BigInt(n), t), r;
235
601
  }
236
- function U(n) {
602
+ function M(n) {
237
603
  return n.byteOffset % 4 === 0;
238
604
  }
239
- function I(n) {
605
+ function B(n) {
240
606
  return Uint8Array.from(w(n));
241
607
  }
242
- const T = 16, ge = /* @__PURE__ */ new Uint8Array(16), L = /* @__PURE__ */ A(ge), Ke = 225, Oe = (n, e, t, r) => {
608
+ const T = 16, ge = /* @__PURE__ */ new Uint8Array(16), L = /* @__PURE__ */ A(ge), Ze = 225, Ge = (n, e, t, r) => {
243
609
  const i = r & 1;
244
610
  return {
245
611
  s3: t << 31 | r >>> 1,
@@ -247,11 +613,11 @@ const T = 16, ge = /* @__PURE__ */ new Uint8Array(16), L = /* @__PURE__ */ A(ge)
247
613
  s1: n << 31 | e >>> 1,
248
614
  // NIST SP 800-38D §6.3 applies `V >> 1` and XORs R on carry. In this
249
615
  // 4x32-bit split, R = 0xe1 || 0^120 lives in the top byte of s0.
250
- s0: n >>> 1 ^ Ke << 24 & -(i & 1)
616
+ s0: n >>> 1 ^ Ze << 24 & -(i & 1)
251
617
  // reduce % poly
252
618
  };
253
- }, R = (n) => (n >>> 0 & 255) << 24 | (n >>> 8 & 255) << 16 | (n >>> 16 & 255) << 8 | n >>> 24 & 255 | 0, je = (n) => n > 64 * 1024 ? 8 : n > 1024 ? 4 : 2;
254
- class We {
619
+ }, z = (n) => (n >>> 0 & 255) << 24 | (n >>> 8 & 255) << 16 | (n >>> 16 & 255) << 8 | n >>> 24 & 255 | 0, Qe = (n) => n > 64 * 1024 ? 8 : n > 1024 ? 4 : 2;
620
+ class Xe {
255
621
  blockLen = T;
256
622
  outputLen = T;
257
623
  s0 = 0;
@@ -265,13 +631,13 @@ class We {
265
631
  windowSize;
266
632
  // We select bits per window adaptively based on expectedLength
267
633
  constructor(e, t) {
268
- w(e, 16, "key"), e = I(e);
634
+ w(e, 16, "key"), e = B(e);
269
635
  const r = F(e);
270
636
  let i = r.getUint32(0, !1), o = r.getUint32(4, !1), s = r.getUint32(8, !1), c = r.getUint32(12, !1);
271
637
  const a = [];
272
638
  for (let f = 0; f < 128; f++)
273
- a.push({ s0: R(i), s1: R(o), s2: R(s), s3: R(c) }), { s0: i, s1: o, s2: s, s3: c } = Oe(i, o, s, c);
274
- const l = je(t || 1024);
639
+ a.push({ s0: z(i), s1: z(o), s2: z(s), s3: z(c) }), { s0: i, s1: o, s2: s, s3: c } = Ge(i, o, s, c);
640
+ const l = Qe(t || 1024);
275
641
  if (![1, 2, 4, 8].includes(l))
276
642
  throw new Error("ghash: invalid window size, expected 2, 4 or 8");
277
643
  this.W = l;
@@ -306,7 +672,7 @@ class We {
306
672
  this.s0 = a, this.s1 = l, this.s2 = d, this.s3 = u;
307
673
  }
308
674
  update(e) {
309
- ue(this), w(e), e = I(e);
675
+ de(this), w(e), e = B(e);
310
676
  const t = A(e), r = Math.floor(e.length / T), i = e.length % T;
311
677
  for (let o = 0; o < r; o++)
312
678
  this._updateBlock(m(t[o * 4 + 0]), m(t[o * 4 + 1]), m(t[o * 4 + 2]), m(t[o * 4 + 3]));
@@ -319,32 +685,32 @@ class We {
319
685
  t.s0 = 0, t.s1 = 0, t.s2 = 0, t.s3 = 0;
320
686
  }
321
687
  digestInto(e) {
322
- ue(this), Ue(e, this), this.finished = !0;
688
+ de(this), We(e, this), this.finished = !0;
323
689
  const { s0: t, s1: r, s2: i, s3: o } = this, s = A(e);
324
- s[0] = t, s[1] = r, s[2] = i, s[3] = o, q || se(s.subarray(0, T / 4));
690
+ s[0] = t, s[1] = r, s[2] = i, s[3] = o, q || ce(s.subarray(0, T / 4));
325
691
  }
326
692
  digest() {
327
693
  const e = new Uint8Array(T);
328
694
  return this.digestInto(e), this.destroy(), e;
329
695
  }
330
696
  }
331
- const de = /* @__PURE__ */ ze(16, (n, e) => new We(n, e), (n) => [n.length]), ie = 16, Ne = 4, _ = /* @__PURE__ */ new Uint8Array(ie), Ve = 283;
332
- function De(n) {
697
+ const he = /* @__PURE__ */ He(16, (n, e) => new Xe(n, e), (n) => [n.length]), oe = 16, Je = 4, _ = /* @__PURE__ */ new Uint8Array(oe), et = 283;
698
+ function tt(n) {
333
699
  if (![16, 24, 32].includes(n.length))
334
700
  throw new Error('"aes key" expected Uint8Array of length 16/24/32, got length=' + n.length);
335
701
  }
336
- function ce(n) {
337
- return n << 1 ^ Ve & -(n >> 7);
702
+ function ae(n) {
703
+ return n << 1 ^ et & -(n >> 7);
338
704
  }
339
- function he(n, e) {
705
+ function fe(n, e) {
340
706
  let t = 0;
341
707
  for (; e > 0; e >>= 1)
342
- t ^= n & -(e & 1), n = ce(n);
708
+ t ^= n & -(e & 1), n = ae(n);
343
709
  return t;
344
710
  }
345
- const He = /* @__PURE__ */ (() => {
711
+ const nt = /* @__PURE__ */ (() => {
346
712
  const n = new Uint8Array(256);
347
- for (let t = 0, r = 1; t < 256; t++, r ^= ce(r))
713
+ for (let t = 0, r = 1; t < 256; t++, r ^= ae(r))
348
714
  n[t] = r;
349
715
  const e = new Uint8Array(256);
350
716
  e[0] = 99;
@@ -353,11 +719,11 @@ const He = /* @__PURE__ */ (() => {
353
719
  r |= r << 8, e[n[t]] = (r ^ r >> 4 ^ r >> 5 ^ r >> 6 ^ r >> 7 ^ 99) & 255;
354
720
  }
355
721
  return v(n), e;
356
- })(), Fe = (n) => n << 24 | n >>> 8, Z = (n) => n << 8 | n >>> 24;
357
- function qe(n, e) {
722
+ })(), rt = (n) => n << 24 | n >>> 8, G = (n) => n << 8 | n >>> 24;
723
+ function it(n, e) {
358
724
  if (n.length !== 256)
359
725
  throw new Error("wrong sbox length");
360
- const t = new Uint32Array(256).map((l, d) => e(n[d])), r = t.map(Z), i = r.map(Z), o = i.map(Z), s = new Uint32Array(256 * 256), c = new Uint32Array(256 * 256), a = new Uint16Array(256 * 256);
726
+ const t = new Uint32Array(256).map((l, d) => e(n[d])), r = t.map(G), i = r.map(G), o = i.map(G), s = new Uint32Array(256 * 256), c = new Uint32Array(256 * 256), a = new Uint16Array(256 * 256);
361
727
  for (let l = 0; l < 256; l++)
362
728
  for (let d = 0; d < 256; d++) {
363
729
  const u = l * 256 + d;
@@ -365,23 +731,23 @@ function qe(n, e) {
365
731
  }
366
732
  return { sbox: n, sbox2: a, T0: t, T1: r, T2: i, T3: o, T01: s, T23: c };
367
733
  }
368
- const we = /* @__PURE__ */ qe(He, (n) => he(n, 3) << 24 | n << 16 | n << 8 | he(n, 2)), Ye = /* @__PURE__ */ (() => {
734
+ const we = /* @__PURE__ */ it(nt, (n) => fe(n, 3) << 24 | n << 16 | n << 8 | fe(n, 2)), ot = /* @__PURE__ */ (() => {
369
735
  const n = new Uint8Array(16);
370
- for (let e = 0, t = 1; e < 16; e++, t = ce(t))
736
+ for (let e = 0, t = 1; e < 16; e++, t = ae(t))
371
737
  n[e] = t;
372
738
  return n;
373
739
  })();
374
- function Ze(n) {
740
+ function st(n) {
375
741
  w(n);
376
742
  const e = n.length;
377
- De(n);
743
+ tt(n);
378
744
  const { sbox2: t } = we, r = [];
379
- (!q || !U(n)) && r.push(n = I(n));
380
- const i = se(A(n)), o = i.length, s = (a) => P(t, a, a, a, a), c = new Uint32Array(e + 28);
745
+ (!q || !M(n)) && r.push(n = B(n));
746
+ const i = ce(A(n)), o = i.length, s = (a) => P(t, a, a, a, a), c = new Uint32Array(e + 28);
381
747
  c.set(i);
382
748
  for (let a = o; a < c.length; a++) {
383
749
  let l = c[a - 1];
384
- a % o === 0 ? l = s(Fe(l)) ^ Ye[a / o - 1] : o > 6 && a % o === 4 && (l = s(l)), c[a] = c[a - o] ^ l;
750
+ a % o === 0 ? l = s(rt(l)) ^ ot[a / o - 1] : o > 6 && a % o === 4 && (l = s(l)), c[a] = c[a - o] ^ l;
385
751
  }
386
752
  return v(...r), c;
387
753
  }
@@ -391,7 +757,7 @@ function $(n, e, t, r, i, o) {
391
757
  function P(n, e, t, r, i) {
392
758
  return n[e & 255 | t & 65280] | n[r >>> 16 & 255 | i >>> 16 & 65280] << 16;
393
759
  }
394
- function fe(n, e, t, r, i) {
760
+ function pe(n, e, t, r, i) {
395
761
  const { sbox2: o, T01: s, T23: c } = we;
396
762
  let a = 0;
397
763
  e ^= n[a++], t ^= n[a++], r ^= n[a++], i ^= n[a++];
@@ -404,50 +770,50 @@ function fe(n, e, t, r, i) {
404
770
  return { s0: d, s1: u, s2: h, s3: p };
405
771
  }
406
772
  function K(n, e, t, r, i) {
407
- w(t, ie, "nonce"), w(r), i = _e(r.length, i);
773
+ w(t, oe, "nonce"), w(r), i = qe(r.length, i);
408
774
  const o = t, s = A(o), c = F(o), a = A(r), l = A(i), d = e ? 0 : 12, u = r.length;
409
775
  let h = c.getUint32(d, e);
410
776
  for (let f = 0; f + 4 <= a.length; f += 4) {
411
- const { s0: y, s1: b, s2: x, s3: k } = fe(n, m(s[0]), m(s[1]), m(s[2]), m(s[3]));
777
+ const { s0: y, s1: b, s2: x, s3: k } = pe(n, m(s[0]), m(s[1]), m(s[2]), m(s[3]));
412
778
  l[f + 0] = a[f + 0] ^ m(y), l[f + 1] = a[f + 1] ^ m(b), l[f + 2] = a[f + 2] ^ m(x), l[f + 3] = a[f + 3] ^ m(k), h = h + 1 >>> 0, c.setUint32(d, h, e);
413
779
  }
414
- const p = ie * Math.floor(a.length / Ne);
780
+ const p = oe * Math.floor(a.length / Je);
415
781
  if (p < u) {
416
- const { s0: f, s1: y, s2: b, s3: x } = fe(n, m(s[0]), m(s[1]), m(s[2]), m(s[3])), k = new Uint32Array([f, y, b, x]);
417
- se(k);
418
- const C = Ie(k);
782
+ const { s0: f, s1: y, s2: b, s3: x } = pe(n, m(s[0]), m(s[1]), m(s[2]), m(s[3])), k = new Uint32Array([f, y, b, x]);
783
+ ce(k);
784
+ const C = Ne(k);
419
785
  for (let E = p, S = 0; E < u; E++, S++)
420
786
  i[E] = r[E] ^ C[S];
421
787
  v(k);
422
788
  }
423
789
  return i;
424
790
  }
425
- function Ge(n, e, t, r, i) {
791
+ function ct(n, e, t, r, i) {
426
792
  const o = i ? i.length : 0, s = n.create(t, r.length + o);
427
793
  i && s.update(i);
428
- const c = $e(8 * r.length, 8 * o, e);
794
+ const c = Ye(8 * r.length, 8 * o, e);
429
795
  s.update(r), s.update(c);
430
796
  const a = s.digest();
431
797
  return v(c), a;
432
798
  }
433
- const W = /* @__PURE__ */ Re({ blockSize: 16, nonceLength: 12, tagLength: 16, withAAD: !0, varSizeNonce: !0 }, function(e, t, r) {
799
+ const W = /* @__PURE__ */ Fe({ blockSize: 16, nonceLength: 12, tagLength: 16, withAAD: !0, varSizeNonce: !0 }, function(e, t, r) {
434
800
  if (t.length < 8)
435
801
  throw new Error("aes/gcm: invalid nonce length");
436
802
  const i = 16;
437
803
  function o(c, a, l) {
438
- const d = Ge(de, !1, c, l, r);
804
+ const d = ct(he, !1, c, l, r);
439
805
  for (let u = 0; u < a.length; u++)
440
806
  d[u] ^= a[u];
441
807
  return d;
442
808
  }
443
809
  function s() {
444
- const c = Ze(e), a = _.slice(), l = _.slice();
810
+ const c = st(e), a = _.slice(), l = _.slice();
445
811
  if (K(c, !1, l, l, a), t.length === 12)
446
812
  l.set(t);
447
813
  else {
448
814
  const u = _.slice();
449
815
  F(u).setBigUint64(8, BigInt(t.length * 8), !1);
450
- const p = de.create(a).update(t).update(u);
816
+ const p = he.create(a).update(t).update(u);
451
817
  p.digestInto(l), p.destroy();
452
818
  }
453
819
  const d = K(c, !1, l, _);
@@ -456,132 +822,172 @@ const W = /* @__PURE__ */ Re({ blockSize: 16, nonceLength: 12, tagLength: 16, wi
456
822
  return {
457
823
  encrypt(c) {
458
824
  const { xk: a, authKey: l, counter: d, tagMask: u } = s(), h = new Uint8Array(c.length + i), p = [a, l, d, u];
459
- U(c) || p.push(c = I(c)), K(a, !1, d, c, h.subarray(0, c.length));
825
+ M(c) || p.push(c = B(c)), K(a, !1, d, c, h.subarray(0, c.length));
460
826
  const f = o(l, u, h.subarray(0, h.length - i));
461
827
  return p.push(f), h.set(f, c.length), v(...p), h;
462
828
  },
463
829
  decrypt(c) {
464
830
  const { xk: a, authKey: l, counter: d, tagMask: u } = s(), h = [a, l, u, d];
465
- U(c) || h.push(c = I(c));
831
+ M(c) || h.push(c = B(c));
466
832
  const p = c.subarray(0, -i), f = c.subarray(-i), y = o(l, u, p);
467
- if (h.push(y), !Be(y, f))
833
+ if (h.push(y), !De(y, f))
468
834
  throw v(...h), new Error("aes-gcm: invalid tag");
469
835
  const b = K(a, !1, d, p);
470
836
  return v(...h), b;
471
837
  }
472
838
  };
473
- });
474
- class N {
475
- static MAGIC = new TextEncoder().encode("BIMGCM01");
476
- /**
477
- * 检测二进制数据是否为 .pzenc 加密格式
478
- * @param data 原始二进制数据
479
- * @returns 是否为加密文件
480
- */
481
- static isEncrypted(e) {
482
- if (e.byteLength < 8) return !1;
483
- const t = new Uint8Array(e);
484
- for (let r = 0; r < 8; r++)
485
- if (t[r] !== N.MAGIC[r]) return !1;
486
- return !0;
487
- }
488
- /**
489
- * 解密 .pzenc 自定义加密格式为 zip 二进制数据
490
- *
491
- * 二进制布局:
492
- * [0-7] magic "BIMGCM01" (8 字节)
493
- * [8] version (1 字节, 当前必须为 1)
494
- * [9] nonceLen (1 字节)
495
- * [10] tagLen (1 字节)
496
- * [11..] nonce || tag || ciphertext
497
- *
498
- * @param encryptedArrayBuffer 加密的原始二进制数据
499
- * @param keyBase64 Base64 编码的 AES-256 密钥 (32 字节)
500
- * @returns 解密后的 zip 二进制数据 (Uint8Array)
501
- */
502
- static async decryptPzEnc(e, t) {
503
- const r = new Uint8Array(e), i = new TextEncoder().encode("BIMGCM01");
504
- for (let y = 0; y < i.length; y++)
505
- if (r[y] !== i[y])
506
- throw new Error("magic 不匹配: 不是有效的 pzenc 文件");
507
- const o = r[8];
508
- if (o !== 1)
509
- throw new Error(`不支持的 pzenc 版本: ${o}`);
510
- const s = r[9], c = r[10], a = 11, l = r.slice(a, a + s), d = r.slice(a + s, a + s + c), u = r.slice(a + s + c), h = Xe(u, d), p = Qe(t);
511
- if (p.length !== 32)
512
- throw new Error("AES-256 密钥必须是 32 字节");
513
- const f = r.slice(0, a);
514
- if (globalThis.crypto?.subtle) {
515
- const y = await globalThis.crypto.subtle.importKey(
516
- "raw",
517
- p.buffer,
518
- { name: "AES-GCM" },
519
- !1,
520
- ["decrypt"]
521
- ), b = await globalThis.crypto.subtle.decrypt(
522
- {
523
- name: "AES-GCM",
524
- iv: l.buffer,
525
- additionalData: f.buffer,
526
- tagLength: c * 8
527
- },
528
- y,
529
- h.buffer
530
- );
531
- return new Uint8Array(b);
839
+ }), at = "evtrsa1", Q = /* @__PURE__ */ new Map();
840
+ function be(n) {
841
+ return n.replace(/\/+$/, "");
842
+ }
843
+ function lt(n) {
844
+ return new TextEncoder().encode(n);
845
+ }
846
+ function O(n) {
847
+ let e = "";
848
+ return n.forEach((t) => {
849
+ e += String.fromCharCode(t);
850
+ }), btoa(e).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/g, "");
851
+ }
852
+ async function ut(n, e) {
853
+ const t = typeof AbortController < "u" ? new AbortController() : void 0, r = t ? setTimeout(() => t.abort(), e) : void 0;
854
+ try {
855
+ const i = await fetch(n, {
856
+ method: "GET",
857
+ headers: {
858
+ Accept: "application/json"
859
+ },
860
+ signal: t?.signal
861
+ }), o = await i.json().catch(() => ({}));
862
+ if (!i.ok) {
863
+ const s = o?.error?.message ?? o?.message ?? `ViewToken public key request failed with status ${i.status}`;
864
+ throw new Error(s);
532
865
  }
533
- return Je(p, l, f, h, c);
866
+ return o;
867
+ } finally {
868
+ r != null && clearTimeout(r);
534
869
  }
535
870
  }
536
- function Qe(n) {
537
- const e = atob(n), t = new Uint8Array(e.length);
538
- for (let r = 0; r < e.length; r++)
539
- t[r] = e.codePointAt(r);
540
- return t;
541
- }
542
- function Xe(n, e) {
543
- const t = new Uint8Array(n.length + e.length);
544
- return t.set(n, 0), t.set(e, n.length), t;
871
+ function X(n) {
872
+ const e = globalThis.crypto;
873
+ if (!e?.getRandomValues)
874
+ throw new Error("[BimEngine] crypto.getRandomValues is required to encrypt viewToken");
875
+ return e.getRandomValues(new Uint8Array(n));
545
876
  }
546
- function Je(n, e, t, r, i) {
547
- if (i !== W.tagLength)
548
- throw new Error(`当前 HTTP 回退解密仅支持 ${W.tagLength} 字节 AES-GCM tag,当前文件 tagLen: ${i}`);
549
- return W(n, e, t).decrypt(r);
877
+ function dt(n) {
878
+ let e = "";
879
+ return n.forEach((t) => {
880
+ e += String.fromCharCode(t);
881
+ }), e;
550
882
  }
551
- function Bt(n, e, t, r) {
552
- Se({
553
- method: "get",
554
- responseType: "arraybuffer",
555
- url: n
556
- }).then(async (o) => {
557
- let s = o.data;
558
- r && N.isEncrypted(o.data) && (s = await N.decryptPzEnc(o.data, r)), ye.loadAsync(s).then((c) => {
559
- for (let a in c.files) {
560
- const l = c.file(c.files[a].name);
561
- l && l.async("blob").then((d) => {
562
- i(d, "utf-8", function(u, h) {
563
- e(h);
564
- });
565
- }).catch(() => {
566
- t();
567
- });
568
- }
569
- }).catch(() => {
570
- t();
571
- });
572
- }).catch(() => {
573
- t();
883
+ function ht(n) {
884
+ const e = new Uint8Array(n.length);
885
+ for (let t = 0; t < n.length; t += 1)
886
+ e[t] = n.charCodeAt(t) & 255;
887
+ return e;
888
+ }
889
+ async function ft(n, e) {
890
+ const t = `${be(n)}/models/view-token/public-key`, r = await ut(t, e);
891
+ if (r.algorithm !== "RSA-OAEP-256" || !r.publicKey)
892
+ throw new Error("[BimEngine] OpenAPI returned an invalid viewToken public key");
893
+ return ee.pki.publicKeyFromPem(r.publicKey);
894
+ }
895
+ function pt(n, e) {
896
+ const t = be(n), r = Q.get(t);
897
+ if (r)
898
+ return r;
899
+ const i = ft(n, e).catch((o) => {
900
+ throw Q.delete(t), o;
574
901
  });
575
- function i(o, s, c) {
576
- var a = new FileReader(), l = new Blob([o]);
577
- a.onload = function(d) {
578
- c(null, d.target.result);
579
- }, a.onerror = function() {
580
- c(null, null);
581
- }, a.readAsText(l, s);
902
+ return Q.set(t, i), i;
903
+ }
904
+ async function yt(n, e, t) {
905
+ const r = await pt(n, t), i = X(32), o = X(12), s = X(16), c = JSON.stringify({
906
+ viewToken: e,
907
+ timestamp: Date.now(),
908
+ nonce: O(s)
909
+ }), a = r.encrypt(
910
+ dt(i),
911
+ "RSA-OAEP",
912
+ {
913
+ md: ee.md.sha256.create(),
914
+ mgf1: {
915
+ md: ee.md.sha256.create()
916
+ }
917
+ }
918
+ ), l = W(i, o).encrypt(lt(c));
919
+ return [
920
+ at,
921
+ O(ht(a)),
922
+ O(o),
923
+ O(l)
924
+ ].join(".");
925
+ }
926
+ function mt(n) {
927
+ return n.replace(/\/+$/, "");
928
+ }
929
+ async function gt(n, e, t) {
930
+ const r = typeof AbortController < "u" ? new AbortController() : void 0, i = r ? setTimeout(() => r.abort(), t) : void 0;
931
+ try {
932
+ const o = await fetch(n, {
933
+ method: "POST",
934
+ headers: {
935
+ "Content-Type": "application/json"
936
+ },
937
+ body: JSON.stringify(e),
938
+ signal: r?.signal
939
+ }), s = await o.json().catch(() => ({}));
940
+ if (!o.ok) {
941
+ const c = s?.error?.message ?? s?.message ?? `ViewToken resolve failed with status ${o.status}`;
942
+ throw new Error(c);
943
+ }
944
+ return s;
945
+ } finally {
946
+ i != null && clearTimeout(i);
947
+ }
948
+ }
949
+ function wt(n) {
950
+ switch (n) {
951
+ case "2d":
952
+ return "cad_model";
953
+ case "720":
954
+ return "panorama";
955
+ case "gaussian":
956
+ return "gaussian_model";
957
+ default:
958
+ return "model";
582
959
  }
583
960
  }
584
- const et = "iflowbim.cn", tt = 512, nt = 128, rt = 150, it = 38, O = 290, G = 190;
961
+ function bt(n, e) {
962
+ return {
963
+ applicationId: 0,
964
+ engineType: e,
965
+ assetCategory: wt(e),
966
+ url: n,
967
+ urls: [n]
968
+ };
969
+ }
970
+ async function Rt(n, e, t) {
971
+ const r = n?.sdkAuth;
972
+ if (!r?.endpoint)
973
+ return bt(e, t);
974
+ let i;
975
+ (r.token || r.appId && r.appKey && r.appSecret) && (i = (await Oe(n, t))?.sdkToken);
976
+ const s = {
977
+ viewToken: await yt(
978
+ r.endpoint,
979
+ e,
980
+ r.timeoutMs ?? 8e3
981
+ ),
982
+ engineType: t
983
+ };
984
+ return i && (s.sdkToken = i), gt(
985
+ `${mt(r.endpoint)}/models/view-token/resolve`,
986
+ s,
987
+ r.timeoutMs ?? 8e3
988
+ );
989
+ }
990
+ const xt = "iflowbim.cn", kt = 512, Et = 128, vt = 150, Tt = 38, j = 290, J = 190;
585
991
  class zt {
586
992
  THREE;
587
993
  text;
@@ -592,7 +998,7 @@ class zt {
592
998
  size;
593
999
  viewportWidth = 0;
594
1000
  viewportHeight = 0;
595
- constructor(e, t = et) {
1001
+ constructor(e, t = xt) {
596
1002
  this.THREE = e, this.text = t, this.scene = new e.Scene(), this.camera = new e.OrthographicCamera(0, 1, 1, 0, -10, 10), this.material = new e.SpriteMaterial({
597
1003
  map: new e.CanvasTexture(this.createTextTexture()),
598
1004
  transparent: !0,
@@ -615,7 +1021,7 @@ class zt {
615
1021
  }
616
1022
  createTextTexture() {
617
1023
  const e = document.createElement("canvas");
618
- e.width = tt, e.height = nt;
1024
+ e.width = kt, e.height = Et;
619
1025
  const t = e.getContext("2d");
620
1026
  return t && (t.clearRect(0, 0, e.width, e.height), t.textAlign = "center", t.textBaseline = "middle", t.font = "600 54px Arial, Helvetica, sans-serif", t.lineWidth = 3, t.strokeStyle = "rgba(0, 0, 0, 0.20)", t.fillStyle = "rgba(255, 255, 255, 0.24)", t.strokeText(this.text, e.width / 2, e.height / 2), t.fillText(this.text, e.width / 2, e.height / 2)), e;
621
1027
  }
@@ -623,13 +1029,13 @@ class zt {
623
1029
  if (e === this.viewportWidth && t === this.viewportHeight)
624
1030
  return;
625
1031
  this.viewportWidth = e, this.viewportHeight = t, this.camera.left = -e / 2, this.camera.right = e / 2, this.camera.top = t / 2, this.camera.bottom = -t / 2, this.camera.updateProjectionMatrix();
626
- const r = Math.ceil(e / O) + 2, i = Math.ceil(t / G) + 2, o = r * i;
1032
+ const r = Math.ceil(e / j) + 2, i = Math.ceil(t / J) + 2, o = r * i;
627
1033
  this.ensureSpriteCount(o);
628
1034
  let s = 0;
629
- const c = -e / 2 - O / 2, a = -t / 2 - G / 2;
1035
+ const c = -e / 2 - j / 2, a = -t / 2 - J / 2;
630
1036
  for (let l = 0; l < i; l += 1)
631
1037
  for (let d = 0; d < r; d += 1) {
632
- const u = this.sprites[s], h = c + d * O + l % 2 * (O / 2), p = a + l * G;
1038
+ const u = this.sprites[s], h = c + d * j + l % 2 * (j / 2), p = a + l * J;
633
1039
  u.position.set(h, p, 0), u.visible = !0, s += 1;
634
1040
  }
635
1041
  for (let l = s; l < this.sprites.length; l += 1)
@@ -638,11 +1044,121 @@ class zt {
638
1044
  ensureSpriteCount(e) {
639
1045
  for (; this.sprites.length < e; ) {
640
1046
  const t = new this.THREE.Sprite(this.material);
641
- t.scale.set(rt, it, 1), t.rotation.z = -0.32, t.renderOrder = 999999, this.scene.add(t), this.sprites.push(t);
1047
+ t.scale.set(vt, Tt, 1), t.rotation.z = -0.32, t.renderOrder = 999999, this.scene.add(t), this.sprites.push(t);
1048
+ }
1049
+ }
1050
+ }
1051
+ class H {
1052
+ static MAGIC = new TextEncoder().encode("BIMGCM01");
1053
+ /**
1054
+ * 检测二进制数据是否为 .pzenc 加密格式
1055
+ * @param data 原始二进制数据
1056
+ * @returns 是否为加密文件
1057
+ */
1058
+ static isEncrypted(e) {
1059
+ if (e.byteLength < 8) return !1;
1060
+ const t = new Uint8Array(e);
1061
+ for (let r = 0; r < 8; r++)
1062
+ if (t[r] !== H.MAGIC[r]) return !1;
1063
+ return !0;
1064
+ }
1065
+ /**
1066
+ * 解密 .pzenc 自定义加密格式为 zip 二进制数据
1067
+ *
1068
+ * 二进制布局:
1069
+ * [0-7] magic "BIMGCM01" (8 字节)
1070
+ * [8] version (1 字节, 当前必须为 1)
1071
+ * [9] nonceLen (1 字节)
1072
+ * [10] tagLen (1 字节)
1073
+ * [11..] nonce || tag || ciphertext
1074
+ *
1075
+ * @param encryptedArrayBuffer 加密的原始二进制数据
1076
+ * @param keyBase64 Base64 编码的 AES-256 密钥 (32 字节)
1077
+ * @returns 解密后的 zip 二进制数据 (Uint8Array)
1078
+ */
1079
+ static async decryptPzEnc(e, t) {
1080
+ const r = new Uint8Array(e), i = new TextEncoder().encode("BIMGCM01");
1081
+ for (let y = 0; y < i.length; y++)
1082
+ if (r[y] !== i[y])
1083
+ throw new Error("magic 不匹配: 不是有效的 pzenc 文件");
1084
+ const o = r[8];
1085
+ if (o !== 1)
1086
+ throw new Error(`不支持的 pzenc 版本: ${o}`);
1087
+ const s = r[9], c = r[10], a = 11, l = r.slice(a, a + s), d = r.slice(a + s, a + s + c), u = r.slice(a + s + c), h = Ct(u, d), p = At(t);
1088
+ if (p.length !== 32)
1089
+ throw new Error("AES-256 密钥必须是 32 字节");
1090
+ const f = r.slice(0, a);
1091
+ if (globalThis.crypto?.subtle) {
1092
+ const y = await globalThis.crypto.subtle.importKey(
1093
+ "raw",
1094
+ p.buffer,
1095
+ { name: "AES-GCM" },
1096
+ !1,
1097
+ ["decrypt"]
1098
+ ), b = await globalThis.crypto.subtle.decrypt(
1099
+ {
1100
+ name: "AES-GCM",
1101
+ iv: l.buffer,
1102
+ additionalData: f.buffer,
1103
+ tagLength: c * 8
1104
+ },
1105
+ y,
1106
+ h.buffer
1107
+ );
1108
+ return new Uint8Array(b);
642
1109
  }
1110
+ return St(p, l, f, h, c);
1111
+ }
1112
+ }
1113
+ function At(n) {
1114
+ const e = atob(n), t = new Uint8Array(e.length);
1115
+ for (let r = 0; r < e.length; r++)
1116
+ t[r] = e.codePointAt(r);
1117
+ return t;
1118
+ }
1119
+ function Ct(n, e) {
1120
+ const t = new Uint8Array(n.length + e.length);
1121
+ return t.set(n, 0), t.set(e, n.length), t;
1122
+ }
1123
+ function St(n, e, t, r, i) {
1124
+ if (i !== W.tagLength)
1125
+ throw new Error(`当前 HTTP 回退解密仅支持 ${W.tagLength} 字节 AES-GCM tag,当前文件 tagLen: ${i}`);
1126
+ return W(n, e, t).decrypt(r);
1127
+ }
1128
+ function _t(n, e, t, r) {
1129
+ Se({
1130
+ method: "get",
1131
+ responseType: "arraybuffer",
1132
+ url: n
1133
+ }).then(async (o) => {
1134
+ let s = o.data;
1135
+ r && H.isEncrypted(o.data) && (s = await H.decryptPzEnc(o.data, r)), ye.loadAsync(s).then((c) => {
1136
+ for (let a in c.files) {
1137
+ const l = c.file(c.files[a].name);
1138
+ l && l.async("blob").then((d) => {
1139
+ i(d, "utf-8", function(u, h) {
1140
+ e(h);
1141
+ });
1142
+ }).catch(() => {
1143
+ t();
1144
+ });
1145
+ }
1146
+ }).catch(() => {
1147
+ t();
1148
+ });
1149
+ }).catch(() => {
1150
+ t();
1151
+ });
1152
+ function i(o, s, c) {
1153
+ var a = new FileReader(), l = new Blob([o]);
1154
+ a.onload = function(d) {
1155
+ c(null, d.target.result);
1156
+ }, a.onerror = function() {
1157
+ c(null, null);
1158
+ }, a.readAsText(l, s);
643
1159
  }
644
1160
  }
645
- function Rt() {
1161
+ function $t() {
646
1162
  return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function(n) {
647
1163
  var e = Math.random() * 16 | 0, t = n == "x" ? e : e & 3 | 8;
648
1164
  return t.toString(16);
@@ -801,565 +1317,48 @@ class g {
801
1317
  return r;
802
1318
  }
803
1319
  }
804
- function be(n) {
1320
+ function xe(n) {
805
1321
  const e = String(n ?? "").trim().toLowerCase(), t = e.lastIndexOf(".");
806
1322
  return t >= 0 ? e.slice(t) : "";
807
1323
  }
808
- function ot(n) {
809
- return st(n.webkitRelativePath || n.name);
1324
+ function Lt(n) {
1325
+ return Pt(n.webkitRelativePath || n.name);
810
1326
  }
811
- function _t(n) {
1327
+ function Kt(n) {
812
1328
  const e = URL.createObjectURL(n);
813
1329
  return {
814
1330
  url: e,
815
1331
  name: n.name,
816
- extension: be(n.name),
1332
+ extension: xe(n.name),
817
1333
  revoke: () => URL.revokeObjectURL(e)
818
1334
  };
819
1335
  }
820
- async function $t(n, e = "package.zip") {
1336
+ async function Ot(n, e = "package.zip") {
821
1337
  const t = new ye();
822
1338
  n.forEach((o) => {
823
- t.file(ot(o), o);
1339
+ t.file(Lt(o), o);
824
1340
  });
825
1341
  const r = await t.generateAsync({ type: "blob" }), i = URL.createObjectURL(r);
826
1342
  return {
827
1343
  url: i,
828
1344
  name: e,
829
- extension: be(e),
1345
+ extension: xe(e),
830
1346
  revoke: () => URL.revokeObjectURL(i)
831
1347
  };
832
1348
  }
833
- function st(n) {
1349
+ function Pt(n) {
834
1350
  return String(n).replace(/\\/g, "/").replace(/^\/+/, "").replace(/\/+/g, "/");
835
1351
  }
836
- class Kt {
837
- container;
838
- labelContainer;
839
- projectCoordinate;
840
- pickCoordinate;
841
- emitEvent;
842
- labels = /* @__PURE__ */ new Map();
843
- clickCallbacks = /* @__PURE__ */ new Set();
844
- pickResolver = null;
845
- isPicking = !1;
846
- constructor(e) {
847
- this.container = e.container, this.projectCoordinate = e.projectCoordinate, this.pickCoordinate = e.pickCoordinate, this.emitEvent = e.emitEvent, this.labelContainer = document.createElement("div"), this.labelContainer.className = e.className ?? "bim-engine-label-container", this.labelContainer.style.cssText = [
848
- "position:absolute",
849
- "left:0",
850
- "top:0",
851
- "width:100%",
852
- "height:100%",
853
- "pointer-events:none",
854
- "overflow:hidden",
855
- "z-index:1200"
856
- ].join(";"), this.container.appendChild(this.labelContainer);
857
- }
858
- /**
859
- * 开启一次选点,下一次画布点击会返回当前引擎坐标。
860
- */
861
- pickPoint() {
862
- return this.cancelPick(), this.isPicking = !0, this.container.style.cursor = "crosshair", this.addPickBlockers(), this.container.addEventListener("click", this.handlePickClick, !0), new Promise((e) => {
863
- this.pickResolver = e;
864
- });
865
- }
866
- /**
867
- * 兼容回调式调用,便于旧业务页面直接绑定按钮。
868
- */
869
- startPickPoint(e) {
870
- const t = this.pickPoint();
871
- return e && t.then(e), t;
872
- }
873
- /**
874
- * 创建标签,返回最终标签 id。
875
- */
876
- createLabel(e) {
877
- const t = e.id ?? this.createId();
878
- if (this.labels.has(t))
879
- throw new Error(`LabelManager: label "${t}" already exists`);
880
- const r = this.createElement(t), i = {
881
- id: t,
882
- coordinate: { ...e.coordinate },
883
- icon: e.icon,
884
- name: e.name,
885
- data: e.data,
886
- size: e.iconSize ?? e.size ?? 28,
887
- visible: e.visible ?? !0,
888
- element: r
889
- };
890
- return this.labels.set(t, i), this.labelContainer.appendChild(r), this.renderLabel(i), this.updateLabelPosition(i), this.emitEvent?.("label-created", this.toPayload(i)), t;
891
- }
892
- /**
893
- * 更新标签,支持按需修改坐标、图标、名称和业务数据。
894
- */
895
- updateLabel(e, t) {
896
- const r = this.labels.get(e);
897
- return r ? (t.coordinate && (r.coordinate = { ...t.coordinate }), t.icon !== void 0 && (r.icon = t.icon), t.name !== void 0 && (r.name = t.name), t.data !== void 0 && (r.data = t.data), t.iconSize !== void 0 && (r.size = t.iconSize), t.size !== void 0 && (r.size = t.size), t.visible !== void 0 && (r.visible = t.visible), this.renderLabel(r), this.updateLabelPosition(r), this.emitEvent?.("label-updated", this.toPayload(r)), !0) : !1;
898
- }
899
- /**
900
- * 删除指定标签。
901
- */
902
- deleteLabel(e) {
903
- const t = this.labels.get(e);
904
- return t ? (t.element.remove(), this.labels.delete(e), this.emitEvent?.("label-deleted", { id: e }), !0) : !1;
905
- }
906
- removeLabel(e) {
907
- return this.deleteLabel(e);
908
- }
909
- clearLabels() {
910
- Array.from(this.labels.keys()).forEach((e) => this.deleteLabel(e));
911
- }
912
- getLabel(e) {
913
- return this.labels.get(e);
914
- }
915
- getLabels() {
916
- return Array.from(this.labels.values());
917
- }
918
- onLabelClick(e) {
919
- return this.clickCallbacks.add(e), () => this.offLabelClick(e);
920
- }
921
- offLabelClick(e) {
922
- this.clickCallbacks.delete(e);
923
- }
924
- /**
925
- * 每帧同步标签屏幕位置。
926
- */
927
- update() {
928
- this.labels.forEach((e) => this.updateLabelPosition(e));
929
- }
930
- cancelPick() {
931
- this.isPicking && (this.isPicking = !1, this.container.style.cursor = "", this.removePickBlockers(), this.container.removeEventListener("click", this.handlePickClick, !0), this.pickResolver?.(null), this.pickResolver = null);
932
- }
933
- dispose() {
934
- this.cancelPick(), this.clearLabels(), this.clickCallbacks.clear(), this.labelContainer.remove();
935
- }
936
- createElement(e) {
937
- const t = document.createElement("div");
938
- return t.dataset.labelId = e, t.style.cssText = [
939
- "position:absolute",
940
- "display:flex",
941
- "flex-direction:column",
942
- "align-items:center",
943
- "gap:5px",
944
- "transform:translate(-50%, -100%)",
945
- "pointer-events:auto",
946
- "cursor:pointer",
947
- "user-select:none",
948
- "white-space:nowrap",
949
- "font:12px/1.2 -apple-system,BlinkMacSystemFont,Segoe UI,Arial,sans-serif"
950
- ].join(";"), t.addEventListener("click", (r) => {
951
- r.preventDefault(), r.stopPropagation();
952
- const i = this.labels.get(e);
953
- if (!i) return;
954
- const o = {
955
- id: e,
956
- label: i,
957
- coordinate: i.coordinate,
958
- originalEvent: r
959
- };
960
- this.clickCallbacks.forEach((s) => s(o)), this.emitEvent?.("label-click", o);
961
- }), t;
962
- }
963
- renderLabel(e) {
964
- e.element.innerHTML = "";
965
- const t = document.createElement("img"), r = this.normalizeIconSize(e.size);
966
- t.src = e.icon, t.alt = e.name, t.style.cssText = [
967
- `width:${r.width}px`,
968
- `height:${r.height}px`,
969
- "object-fit:contain",
970
- "display:block",
971
- "filter:drop-shadow(0 3px 5px rgba(0,0,0,.32))"
972
- ].join(";");
973
- const i = document.createElement("span");
974
- i.textContent = e.name, i.style.cssText = [
975
- "max-width:160px",
976
- "overflow:hidden",
977
- "text-overflow:ellipsis",
978
- "padding:5px 9px",
979
- "border-radius:6px",
980
- "background:rgba(15,23,42,.88)",
981
- "color:#fff",
982
- "border:1px solid rgba(255,255,255,.16)",
983
- "box-shadow:0 3px 10px rgba(0,0,0,.24)"
984
- ].join(";"), e.element.title = e.name, e.element.appendChild(i), e.element.appendChild(t);
985
- }
986
- updateLabelPosition(e) {
987
- const t = this.projectCoordinate(e.coordinate);
988
- if (!(e.visible && t != null && t.visible !== !1) || !t) {
989
- e.element.style.display = "none";
990
- return;
991
- }
992
- e.element.style.display = "flex", e.element.style.left = `${t.x}px`, e.element.style.top = `${t.y}px`;
993
- }
994
- handlePickClick = (e) => {
995
- e.preventDefault(), e.stopImmediatePropagation();
996
- const t = this.pickCoordinate(e);
997
- this.isPicking = !1, this.container.style.cursor = "", this.removePickBlockers(), this.container.removeEventListener("click", this.handlePickClick, !0), this.pickResolver?.(t), this.pickResolver = null, t && this.emitEvent?.("label-pick", t);
998
- };
999
- toPayload(e) {
1000
- return {
1001
- id: e.id,
1002
- coordinate: e.coordinate,
1003
- icon: e.icon,
1004
- name: e.name,
1005
- data: e.data,
1006
- size: e.size,
1007
- visible: e.visible
1008
- };
1009
- }
1010
- normalizeIconSize(e) {
1011
- return typeof e == "number" ? {
1012
- width: e,
1013
- height: e
1014
- } : {
1015
- width: this.normalizeSizeValue(e.width, 28),
1016
- height: this.normalizeSizeValue(e.height, 28)
1017
- };
1018
- }
1019
- normalizeSizeValue(e, t) {
1020
- return Number.isFinite(e) && e > 0 ? e : t;
1021
- }
1022
- createId() {
1023
- return `label-${Date.now()}-${Math.random().toString(16).slice(2)}`;
1024
- }
1025
- addPickBlockers() {
1026
- this.container.addEventListener("mousedown", this.blockPickInteraction, !0), this.container.addEventListener("mouseup", this.blockPickInteraction, !0), this.container.addEventListener("touchstart", this.blockPickInteraction, !0), this.container.addEventListener("touchmove", this.blockPickInteraction, !0), this.container.addEventListener("touchend", this.blockPickInteraction, !0);
1027
- }
1028
- removePickBlockers() {
1029
- this.container.removeEventListener("mousedown", this.blockPickInteraction, !0), this.container.removeEventListener("mouseup", this.blockPickInteraction, !0), this.container.removeEventListener("touchstart", this.blockPickInteraction, !0), this.container.removeEventListener("touchmove", this.blockPickInteraction, !0), this.container.removeEventListener("touchend", this.blockPickInteraction, !0);
1030
- }
1031
- blockPickInteraction = (e) => {
1032
- e.stopImmediatePropagation();
1033
- };
1034
- }
1035
- const ct = "4.0.16", at = {
1036
- version: ct
1037
- }, V = at.version;
1038
- function ae() {
1039
- const n = globalThis.crypto?.subtle;
1040
- if (!n)
1041
- throw new Error("[BimEngine] Web Crypto API is required for secure sdkAuth credentials mode");
1042
- return n;
1043
- }
1044
- function M(n) {
1045
- return new TextEncoder().encode(n);
1046
- }
1047
- function B(n) {
1048
- return n.buffer.slice(n.byteOffset, n.byteOffset + n.byteLength);
1049
- }
1050
- function pe(n) {
1051
- let e = "";
1052
- return n.forEach((t) => {
1053
- e += String.fromCharCode(t);
1054
- }), btoa(e);
1055
- }
1056
- function lt(n) {
1057
- const e = n.getUTCFullYear(), t = String(n.getUTCMonth() + 1).padStart(2, "0"), r = String(n.getUTCDate()).padStart(2, "0");
1058
- return `${e}${t}${r}`;
1059
- }
1060
- async function ut(n) {
1061
- const e = await ae().digest("SHA-256", B(M(n)));
1062
- return Array.from(new Uint8Array(e)).map((t) => t.toString(16).padStart(2, "0")).join("");
1063
- }
1064
- async function dt(n, e) {
1065
- const t = ae(), r = await t.importKey("raw", B(n), { name: "HMAC", hash: "SHA-256" }, !1, ["sign"]);
1066
- return t.sign("HMAC", r, B(M(e)));
1067
- }
1068
- function ht(n) {
1069
- return M(
1070
- [n.appId, n.engineType, n.requestDate, String(n.timestamp), n.nonce].join("|")
1071
- );
1072
- }
1073
- async function ft(n) {
1074
- const e = ae(), t = /* @__PURE__ */ new Date(), r = t.getTime(), i = lt(t), o = globalThis.crypto.randomUUID(), s = globalThis.crypto.getRandomValues(new Uint8Array(12)), c = await ut(n.appSecret), a = await dt(M(c), i), l = await e.importKey("raw", a, "AES-GCM", !1, ["encrypt"]), d = JSON.stringify({
1075
- appKey: n.appKey,
1076
- appSecret: n.appSecret
1077
- }), u = await e.encrypt(
1078
- {
1079
- name: "AES-GCM",
1080
- iv: s,
1081
- additionalData: B(ht({
1082
- appId: n.appId,
1083
- engineType: n.engineType,
1084
- requestDate: i,
1085
- timestamp: r,
1086
- nonce: o
1087
- })),
1088
- tagLength: 128
1089
- },
1090
- l,
1091
- B(M(d))
1092
- );
1093
- return {
1094
- appId: n.appId,
1095
- engineType: n.engineType,
1096
- requestDate: i,
1097
- timestamp: r,
1098
- nonce: o,
1099
- iv: pe(s),
1100
- cipherText: pe(new Uint8Array(u)),
1101
- sdkVersion: n.sdkVersion,
1102
- origin: n.origin,
1103
- product: n.product
1104
- };
1105
- }
1106
- const Q = /* @__PURE__ */ new Map();
1107
- function D(n) {
1108
- return n.replace(/\/+$/, "");
1109
- }
1110
- function H(n) {
1111
- if (n) return n;
1112
- if (typeof window < "u" && typeof window.location?.origin == "string")
1113
- return window.location.origin;
1114
- }
1115
- function pt(n, e) {
1116
- return JSON.stringify({
1117
- endpoint: D(n.endpoint),
1118
- token: n.token ?? "",
1119
- appId: n.appId ?? "",
1120
- appKey: n.appKey ?? "",
1121
- appSecret: n.appSecret ?? "",
1122
- origin: H(n.origin) ?? "",
1123
- product: n.product ?? "",
1124
- engineType: e,
1125
- sdkVersion: V
1126
- });
1127
- }
1128
- async function oe(n, e, t) {
1129
- const r = typeof AbortController < "u" ? new AbortController() : void 0, i = r ? setTimeout(() => r.abort(), t) : void 0;
1130
- try {
1131
- const o = await fetch(n, {
1132
- method: "POST",
1133
- headers: {
1134
- "Content-Type": "application/json"
1135
- },
1136
- body: JSON.stringify(e),
1137
- signal: r?.signal
1138
- }), s = await o.json().catch(() => ({}));
1139
- if (!o.ok) {
1140
- const c = s?.error?.message ?? s?.message ?? `SDK authentication failed with status ${o.status}`;
1141
- throw new Error(c);
1142
- }
1143
- return s;
1144
- } finally {
1145
- i != null && clearTimeout(i);
1146
- }
1147
- }
1148
- async function yt(n, e) {
1149
- const t = await oe(`${D(n.endpoint)}/oauth/sdk-verify`, {
1150
- sdkToken: n.token,
1151
- engineType: e,
1152
- sdkVersion: V,
1153
- origin: H(n.origin),
1154
- product: n.product
1155
- }, n.timeoutMs ?? 8e3);
1156
- return t.sdkToken = n.token, t;
1157
- }
1158
- async function mt(n, e) {
1159
- const t = await ft({
1160
- appId: n.appId,
1161
- appKey: n.appKey,
1162
- appSecret: n.appSecret,
1163
- engineType: e,
1164
- sdkVersion: V,
1165
- origin: H(n.origin),
1166
- product: n.product
1167
- }), r = await oe(
1168
- `${D(n.endpoint)}/oauth/sdk-token/secure`,
1169
- t,
1170
- n.timeoutMs ?? 8e3
1171
- ), i = await oe(`${D(n.endpoint)}/oauth/sdk-verify`, {
1172
- sdkToken: r.sdkToken,
1173
- engineType: e,
1174
- sdkVersion: V,
1175
- origin: H(n.origin),
1176
- product: n.product
1177
- }, n.timeoutMs ?? 8e3);
1178
- return i.sdkToken = r.sdkToken, i;
1179
- }
1180
- async function gt(n, e) {
1181
- const t = n?.sdkAuth;
1182
- if (!t)
1183
- return null;
1184
- if (!t.endpoint)
1185
- throw new Error("[BimEngine] sdkAuth.endpoint is required");
1186
- if (!t.token && !(t.appId && t.appKey && t.appSecret))
1187
- return null;
1188
- const r = pt(t, e), i = Q.get(r);
1189
- if (i) {
1190
- const s = await i;
1191
- return n && (n.__sdkAuthSession = s), s;
1192
- }
1193
- const o = (t.token ? yt(t, e) : mt(t, e)).then((s) => {
1194
- if (s.authorized !== !0)
1195
- throw new Error("[BimEngine] SDK authorization rejected");
1196
- return n && (n.__sdkAuthSession = s), s;
1197
- }).catch((s) => {
1198
- throw Q.delete(r), s;
1199
- });
1200
- return Q.set(r, o), o;
1201
- }
1202
- const wt = "evtrsa1", X = /* @__PURE__ */ new Map();
1203
- function xe(n) {
1204
- return n.replace(/\/+$/, "");
1205
- }
1206
- function bt(n) {
1207
- return new TextEncoder().encode(n);
1208
- }
1209
- function j(n) {
1210
- let e = "";
1211
- return n.forEach((t) => {
1212
- e += String.fromCharCode(t);
1213
- }), btoa(e).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/g, "");
1214
- }
1215
- async function xt(n, e) {
1216
- const t = typeof AbortController < "u" ? new AbortController() : void 0, r = t ? setTimeout(() => t.abort(), e) : void 0;
1217
- try {
1218
- const i = await fetch(n, {
1219
- method: "GET",
1220
- headers: {
1221
- Accept: "application/json"
1222
- },
1223
- signal: t?.signal
1224
- }), o = await i.json().catch(() => ({}));
1225
- if (!i.ok) {
1226
- const s = o?.error?.message ?? o?.message ?? `ViewToken public key request failed with status ${i.status}`;
1227
- throw new Error(s);
1228
- }
1229
- return o;
1230
- } finally {
1231
- r != null && clearTimeout(r);
1232
- }
1233
- }
1234
- function J(n) {
1235
- const e = globalThis.crypto;
1236
- if (!e?.getRandomValues)
1237
- throw new Error("[BimEngine] crypto.getRandomValues is required to encrypt viewToken");
1238
- return e.getRandomValues(new Uint8Array(n));
1239
- }
1240
- function kt(n) {
1241
- let e = "";
1242
- return n.forEach((t) => {
1243
- e += String.fromCharCode(t);
1244
- }), e;
1245
- }
1246
- function Et(n) {
1247
- const e = new Uint8Array(n.length);
1248
- for (let t = 0; t < n.length; t += 1)
1249
- e[t] = n.charCodeAt(t) & 255;
1250
- return e;
1251
- }
1252
- async function vt(n, e) {
1253
- const t = `${xe(n)}/models/view-token/public-key`, r = await xt(t, e);
1254
- if (r.algorithm !== "RSA-OAEP-256" || !r.publicKey)
1255
- throw new Error("[BimEngine] OpenAPI returned an invalid viewToken public key");
1256
- return ee.pki.publicKeyFromPem(r.publicKey);
1257
- }
1258
- function Tt(n, e) {
1259
- const t = xe(n), r = X.get(t);
1260
- if (r)
1261
- return r;
1262
- const i = vt(n, e).catch((o) => {
1263
- throw X.delete(t), o;
1264
- });
1265
- return X.set(t, i), i;
1266
- }
1267
- async function At(n, e, t) {
1268
- const r = await Tt(n, t), i = J(32), o = J(12), s = J(16), c = JSON.stringify({
1269
- viewToken: e,
1270
- timestamp: Date.now(),
1271
- nonce: j(s)
1272
- }), a = r.encrypt(
1273
- kt(i),
1274
- "RSA-OAEP",
1275
- {
1276
- md: ee.md.sha256.create(),
1277
- mgf1: {
1278
- md: ee.md.sha256.create()
1279
- }
1280
- }
1281
- ), l = W(i, o).encrypt(bt(c));
1282
- return [
1283
- wt,
1284
- j(Et(a)),
1285
- j(o),
1286
- j(l)
1287
- ].join(".");
1288
- }
1289
- function Ct(n) {
1290
- return n.replace(/\/+$/, "");
1291
- }
1292
- async function St(n, e, t) {
1293
- const r = typeof AbortController < "u" ? new AbortController() : void 0, i = r ? setTimeout(() => r.abort(), t) : void 0;
1294
- try {
1295
- const o = await fetch(n, {
1296
- method: "POST",
1297
- headers: {
1298
- "Content-Type": "application/json"
1299
- },
1300
- body: JSON.stringify(e),
1301
- signal: r?.signal
1302
- }), s = await o.json().catch(() => ({}));
1303
- if (!o.ok) {
1304
- const c = s?.error?.message ?? s?.message ?? `ViewToken resolve failed with status ${o.status}`;
1305
- throw new Error(c);
1306
- }
1307
- return s;
1308
- } finally {
1309
- i != null && clearTimeout(i);
1310
- }
1311
- }
1312
- function Lt(n) {
1313
- switch (n) {
1314
- case "2d":
1315
- return "cad_model";
1316
- case "720":
1317
- return "panorama";
1318
- case "gaussian":
1319
- return "gaussian_model";
1320
- default:
1321
- return "model";
1322
- }
1323
- }
1324
- function Pt(n, e) {
1325
- return {
1326
- applicationId: 0,
1327
- engineType: e,
1328
- assetCategory: Lt(e),
1329
- url: n,
1330
- urls: [n]
1331
- };
1332
- }
1333
- async function Ot(n, e, t) {
1334
- const r = n?.sdkAuth;
1335
- if (!r?.endpoint)
1336
- return Pt(e, t);
1337
- let i;
1338
- (r.token || r.appId && r.appKey && r.appSecret) && (i = (await gt(n, t))?.sdkToken);
1339
- const s = {
1340
- viewToken: await At(
1341
- r.endpoint,
1342
- e,
1343
- r.timeoutMs ?? 8e3
1344
- ),
1345
- engineType: t
1346
- };
1347
- return i && (s.sdkToken = i), St(
1348
- `${Ct(r.endpoint)}/models/view-token/resolve`,
1349
- s,
1350
- r.timeoutMs ?? 8e3
1351
- );
1352
- }
1353
1352
  export {
1354
- N as B,
1353
+ H as B,
1355
1354
  zt as C,
1356
- V as E,
1355
+ N as E,
1357
1356
  g as F,
1358
- Bt as L,
1359
- Mt as W,
1360
- Kt as a,
1361
- $t as b,
1362
- _t as c,
1363
- Rt as g,
1364
- Ot as r
1357
+ _t as L,
1358
+ Bt as W,
1359
+ Mt as a,
1360
+ Ot as b,
1361
+ Kt as c,
1362
+ $t as g,
1363
+ Rt as r
1365
1364
  };