iflow-engine-base 4.0.15 → 4.0.16

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.
@@ -0,0 +1,1365 @@
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";
3
+ class Mt {
4
+ /**
5
+ * 构造函数
6
+ * @param camera - Three.js 相机对象(用于投影计算)
7
+ * @param renderer - Three.js 渲染器对象(用于获取画布尺寸)
8
+ * @param scene - Three.js 场景对象(用于屏幕坐标转世界坐标时的射线检测,可选)
9
+ */
10
+ constructor(e, t, r) {
11
+ this.camera = e, this.renderer = t, this.scene = r, this.raycaster = new Te();
12
+ }
13
+ camera;
14
+ renderer;
15
+ scene;
16
+ raycaster;
17
+ /**
18
+ * 将世界坐标转换为屏幕坐标(归一化坐标,范围 -1 到 1)
19
+ * @param worldPos - 世界空间中的3D坐标点
20
+ * @returns 归一化的屏幕坐标,x 和 y 的范围都是 -1 到 1
21
+ * x: -1 表示屏幕左边缘,1 表示屏幕右边缘
22
+ * y: -1 表示屏幕下边缘,1 表示屏幕上边缘
23
+ */
24
+ worldToScreenNormalized(e) {
25
+ const t = e.clone();
26
+ return t.project(this.camera), new z(t.x, t.y);
27
+ }
28
+ /**
29
+ * 将世界坐标转换为屏幕坐标(像素坐标)
30
+ * @param worldPos - 世界空间中的3D坐标点
31
+ * @returns 屏幕像素坐标,x 和 y 表示在画布上的实际像素位置
32
+ * x: 0 表示屏幕左边缘,width 表示屏幕右边缘
33
+ * y: 0 表示屏幕上边缘,height 表示屏幕下边缘
34
+ */
35
+ worldToScreen(e) {
36
+ 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);
38
+ }
39
+ /**
40
+ * 将世界坐标转换为屏幕坐标,仅在点位于当前相机可见裁剪空间内时返回结果。
41
+ * 透视相机背后的点经过 project 后会翻转到屏幕异常位置,这里提前过滤。
42
+ * @param worldPos - 世界空间中的 3D 坐标点
43
+ * @returns 屏幕像素坐标;如果点不可见或投影结果无效,返回 null
44
+ */
45
+ worldToScreenIfVisible(e) {
46
+ if (this.camera.updateMatrixWorld(!0), this.camera instanceof Ae && e.clone().applyMatrix4(this.camera.matrixWorldInverse).z >= 0)
47
+ return null;
48
+ const t = e.clone().project(this.camera);
49
+ if (!Number.isFinite(t.x) || !Number.isFinite(t.y) || !Number.isFinite(t.z) || t.z < -1 || t.z > 1)
50
+ return null;
51
+ const r = this.renderer.domElement.clientWidth, i = this.renderer.domElement.clientHeight;
52
+ return new z(
53
+ t.x * r * 0.5 + r * 0.5,
54
+ -t.y * i * 0.5 + i * 0.5
55
+ );
56
+ }
57
+ /**
58
+ * 将屏幕坐标(像素坐标)转换为归一化坐标
59
+ * @param screenX - 屏幕像素 X 坐标
60
+ * @param screenY - 屏幕像素 Y 坐标
61
+ * @returns 归一化的屏幕坐标,范围 -1 到 1
62
+ */
63
+ screenToNormalized(e, t) {
64
+ 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);
66
+ }
67
+ /**
68
+ * 将屏幕坐标(像素坐标)转换为世界坐标
69
+ * 使用射线检测,返回与场景中第一个相交对象的世界坐标点
70
+ * @param screenX - 屏幕像素 X 坐标
71
+ * @param screenY - 屏幕像素 Y 坐标
72
+ * @param objects - 可选,指定要检测的对象数组。如果不提供且 scene 存在,则检测场景中的所有对象
73
+ * @returns 世界坐标点,如果没有相交则返回 null
74
+ */
75
+ screenToWorld(e, t, r) {
76
+ if (!this.scene && !r)
77
+ return console.warn("WorldToScreen: 需要提供 scene 或 objects 参数才能进行屏幕坐标转世界坐标"), null;
78
+ const i = this.screenToNormalized(e, t);
79
+ this.raycaster.setFromCamera(i, this.camera);
80
+ const o = r || this.scene.children, s = this.raycaster.intersectObjects(o, !0);
81
+ return s.length > 0 ? s[0].point : null;
82
+ }
83
+ /**
84
+ * 将屏幕坐标转换为指定深度的世界坐标
85
+ * @param screenX - 屏幕像素 X 坐标
86
+ * @param screenY - 屏幕像素 Y 坐标
87
+ * @param depth - 沿射线方向的距离(世界单位)
88
+ * @returns 世界坐标点
89
+ */
90
+ screenToWorldWithDepth(e, t, r = 0) {
91
+ const i = this.screenToNormalized(e, t);
92
+ this.raycaster.setFromCamera(i, this.camera);
93
+ const o = new le();
94
+ return this.raycaster.ray.at(r, o), o;
95
+ }
96
+ /**
97
+ * 更新相机引用(当相机发生变化时调用)
98
+ * @param camera - 新的相机对象
99
+ */
100
+ updateCamera(e) {
101
+ this.camera = e;
102
+ }
103
+ /**
104
+ * 更新渲染器引用(当渲染器发生变化时调用)
105
+ * @param renderer - 新的渲染器对象
106
+ */
107
+ updateRenderer(e) {
108
+ this.renderer = e;
109
+ }
110
+ /**
111
+ * 更新场景引用(当场景发生变化时调用)
112
+ * @param scene - 新的场景对象
113
+ */
114
+ updateScene(e) {
115
+ this.scene = e;
116
+ }
117
+ }
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);
127
+ return n;
128
+ }
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");
141
+ }
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);
147
+ }
148
+ function Ue(n, e) {
149
+ if (Pe(n, e), !U(n))
150
+ throw new Error("invalid output, must be aligned");
151
+ }
152
+ 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);
164
+ }
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;
168
+ }
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;
174
+ }
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;
183
+ }
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)));
186
+ return o.outputLen = s.outputLen, o.blockLen = s.blockLen, o.create = (c, ...a) => r(c, ...a), o;
187
+ }
188
+ const Re = /* @__NO_SIDE_EFFECTS__ */ (n, e) => {
189
+ function t(r, ...i) {
190
+ if (w(r, void 0, "key"), n.nonceLength !== void 0) {
191
+ const u = i[0];
192
+ w(u, n.varSizeNonce ? void 0 : n.nonceLength, "nonce");
193
+ }
194
+ const o = n.tagLength, s = n.nonceLength !== void 0 ? 1 : 0;
195
+ if (!n.withAAD) {
196
+ for (let u = s; u < i.length; u++)
197
+ if (te(i[u]))
198
+ throw new Error("AAD not supported");
199
+ }
200
+ n.withAAD && i[s] !== void 0 && w(i[s], void 0, "AAD");
201
+ const c = e(r, ...i), a = (u, h) => {
202
+ if (h !== void 0) {
203
+ if (u !== 2)
204
+ throw new Error("cipher output not supported");
205
+ w(h, void 0, "output");
206
+ }
207
+ };
208
+ let l = !1;
209
+ return {
210
+ encrypt(u, h) {
211
+ if (l)
212
+ throw new Error("cannot encrypt() twice with same key + nonce");
213
+ return l = !0, w(u, void 0, "data"), a(c.encrypt.length, h), c.encrypt(u, h);
214
+ },
215
+ decrypt(u, h) {
216
+ if (w(u, void 0, "data"), o && u.length < o)
217
+ throw new Error('"ciphertext" expected length >= tagLength=' + o);
218
+ return a(c.decrypt.length, h), c.decrypt(u, h);
219
+ }
220
+ };
221
+ }
222
+ return Object.assign(t, n), t;
223
+ };
224
+ function _e(n, e, t = !0) {
225
+ if (e === void 0)
226
+ return new Uint8Array(n);
227
+ if (w(e, n, "output"), t && !U(e))
228
+ throw new Error("invalid output, must be aligned");
229
+ return e;
230
+ }
231
+ function $e(n, e, t) {
232
+ re(n), re(e);
233
+ const r = new Uint8Array(16), i = F(r);
234
+ return i.setBigUint64(0, BigInt(e), t), i.setBigUint64(8, BigInt(n), t), r;
235
+ }
236
+ function U(n) {
237
+ return n.byteOffset % 4 === 0;
238
+ }
239
+ function I(n) {
240
+ return Uint8Array.from(w(n));
241
+ }
242
+ const T = 16, ge = /* @__PURE__ */ new Uint8Array(16), L = /* @__PURE__ */ A(ge), Ke = 225, Oe = (n, e, t, r) => {
243
+ const i = r & 1;
244
+ return {
245
+ s3: t << 31 | r >>> 1,
246
+ s2: e << 31 | t >>> 1,
247
+ s1: n << 31 | e >>> 1,
248
+ // NIST SP 800-38D §6.3 applies `V >> 1` and XORs R on carry. In this
249
+ // 4x32-bit split, R = 0xe1 || 0^120 lives in the top byte of s0.
250
+ s0: n >>> 1 ^ Ke << 24 & -(i & 1)
251
+ // reduce % poly
252
+ };
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 {
255
+ blockLen = T;
256
+ outputLen = T;
257
+ s0 = 0;
258
+ s1 = 0;
259
+ s2 = 0;
260
+ s3 = 0;
261
+ finished = !1;
262
+ destroyed = !1;
263
+ t;
264
+ W;
265
+ windowSize;
266
+ // We select bits per window adaptively based on expectedLength
267
+ constructor(e, t) {
268
+ w(e, 16, "key"), e = I(e);
269
+ const r = F(e);
270
+ let i = r.getUint32(0, !1), o = r.getUint32(4, !1), s = r.getUint32(8, !1), c = r.getUint32(12, !1);
271
+ const a = [];
272
+ 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);
275
+ if (![1, 2, 4, 8].includes(l))
276
+ throw new Error("ghash: invalid window size, expected 2, 4 or 8");
277
+ this.W = l;
278
+ const u = 128 / l, h = this.windowSize = 2 ** l, p = [];
279
+ for (let f = 0; f < u; f++)
280
+ for (let y = 0; y < h; y++) {
281
+ let b = 0, x = 0, k = 0, C = 0;
282
+ for (let E = 0; E < l; E++) {
283
+ if (!(y >>> l - E - 1 & 1))
284
+ continue;
285
+ const { s0: Y, s1: ke, s2: Ee, s3: ve } = a[l * f + E];
286
+ b ^= Y, x ^= ke, k ^= Ee, C ^= ve;
287
+ }
288
+ p.push({ s0: b, s1: x, s2: k, s3: C });
289
+ }
290
+ this.t = p;
291
+ }
292
+ _updateBlock(e, t, r, i) {
293
+ e ^= this.s0, t ^= this.s1, r ^= this.s2, i ^= this.s3;
294
+ const { W: o, t: s, windowSize: c } = this;
295
+ let a = 0, l = 0, d = 0, u = 0;
296
+ const h = (1 << o) - 1;
297
+ let p = 0;
298
+ for (const f of [e, t, r, i])
299
+ for (let y = 0; y < 4; y++) {
300
+ const b = f >>> 8 * y & 255;
301
+ for (let x = 8 / o - 1; x >= 0; x--) {
302
+ const k = b >>> o * x & h, { s0: C, s1: E, s2: S, s3: Y } = s[p * c + k];
303
+ a ^= C, l ^= E, d ^= S, u ^= Y, p += 1;
304
+ }
305
+ }
306
+ this.s0 = a, this.s1 = l, this.s2 = d, this.s3 = u;
307
+ }
308
+ update(e) {
309
+ ue(this), w(e), e = I(e);
310
+ const t = A(e), r = Math.floor(e.length / T), i = e.length % T;
311
+ for (let o = 0; o < r; o++)
312
+ this._updateBlock(m(t[o * 4 + 0]), m(t[o * 4 + 1]), m(t[o * 4 + 2]), m(t[o * 4 + 3]));
313
+ return i && (ge.set(e.subarray(r * T)), this._updateBlock(m(L[0]), m(L[1]), m(L[2]), m(L[3])), v(L)), this;
314
+ }
315
+ destroy() {
316
+ this.destroyed = !0;
317
+ const { t: e } = this;
318
+ for (const t of e)
319
+ t.s0 = 0, t.s1 = 0, t.s2 = 0, t.s3 = 0;
320
+ }
321
+ digestInto(e) {
322
+ ue(this), Ue(e, this), this.finished = !0;
323
+ 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));
325
+ }
326
+ digest() {
327
+ const e = new Uint8Array(T);
328
+ return this.digestInto(e), this.destroy(), e;
329
+ }
330
+ }
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) {
333
+ if (![16, 24, 32].includes(n.length))
334
+ throw new Error('"aes key" expected Uint8Array of length 16/24/32, got length=' + n.length);
335
+ }
336
+ function ce(n) {
337
+ return n << 1 ^ Ve & -(n >> 7);
338
+ }
339
+ function he(n, e) {
340
+ let t = 0;
341
+ for (; e > 0; e >>= 1)
342
+ t ^= n & -(e & 1), n = ce(n);
343
+ return t;
344
+ }
345
+ const He = /* @__PURE__ */ (() => {
346
+ const n = new Uint8Array(256);
347
+ for (let t = 0, r = 1; t < 256; t++, r ^= ce(r))
348
+ n[t] = r;
349
+ const e = new Uint8Array(256);
350
+ e[0] = 99;
351
+ for (let t = 0; t < 255; t++) {
352
+ let r = n[255 - t];
353
+ r |= r << 8, e[n[t]] = (r ^ r >> 4 ^ r >> 5 ^ r >> 6 ^ r >> 7 ^ 99) & 255;
354
+ }
355
+ return v(n), e;
356
+ })(), Fe = (n) => n << 24 | n >>> 8, Z = (n) => n << 8 | n >>> 24;
357
+ function qe(n, e) {
358
+ if (n.length !== 256)
359
+ 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);
361
+ for (let l = 0; l < 256; l++)
362
+ for (let d = 0; d < 256; d++) {
363
+ const u = l * 256 + d;
364
+ s[u] = t[l] ^ r[d], c[u] = i[l] ^ o[d], a[u] = n[l] << 8 | n[d];
365
+ }
366
+ return { sbox: n, sbox2: a, T0: t, T1: r, T2: i, T3: o, T01: s, T23: c };
367
+ }
368
+ const we = /* @__PURE__ */ qe(He, (n) => he(n, 3) << 24 | n << 16 | n << 8 | he(n, 2)), Ye = /* @__PURE__ */ (() => {
369
+ const n = new Uint8Array(16);
370
+ for (let e = 0, t = 1; e < 16; e++, t = ce(t))
371
+ n[e] = t;
372
+ return n;
373
+ })();
374
+ function Ze(n) {
375
+ w(n);
376
+ const e = n.length;
377
+ De(n);
378
+ 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);
381
+ c.set(i);
382
+ for (let a = o; a < c.length; a++) {
383
+ 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;
385
+ }
386
+ return v(...r), c;
387
+ }
388
+ function $(n, e, t, r, i, o) {
389
+ return n[t << 8 & 65280 | r >>> 8 & 255] ^ e[i >>> 8 & 65280 | o >>> 24 & 255];
390
+ }
391
+ function P(n, e, t, r, i) {
392
+ return n[e & 255 | t & 65280] | n[r >>> 16 & 255 | i >>> 16 & 65280] << 16;
393
+ }
394
+ function fe(n, e, t, r, i) {
395
+ const { sbox2: o, T01: s, T23: c } = we;
396
+ let a = 0;
397
+ e ^= n[a++], t ^= n[a++], r ^= n[a++], i ^= n[a++];
398
+ const l = n.length / 4 - 2;
399
+ for (let f = 0; f < l; f++) {
400
+ const y = n[a++] ^ $(s, c, e, t, r, i), b = n[a++] ^ $(s, c, t, r, i, e), x = n[a++] ^ $(s, c, r, i, e, t), k = n[a++] ^ $(s, c, i, e, t, r);
401
+ e = y, t = b, r = x, i = k;
402
+ }
403
+ const d = n[a++] ^ P(o, e, t, r, i), u = n[a++] ^ P(o, t, r, i, e), h = n[a++] ^ P(o, r, i, e, t), p = n[a++] ^ P(o, i, e, t, r);
404
+ return { s0: d, s1: u, s2: h, s3: p };
405
+ }
406
+ function K(n, e, t, r, i) {
407
+ w(t, ie, "nonce"), w(r), i = _e(r.length, i);
408
+ const o = t, s = A(o), c = F(o), a = A(r), l = A(i), d = e ? 0 : 12, u = r.length;
409
+ let h = c.getUint32(d, e);
410
+ 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]));
412
+ 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
+ }
414
+ const p = ie * Math.floor(a.length / Ne);
415
+ 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);
419
+ for (let E = p, S = 0; E < u; E++, S++)
420
+ i[E] = r[E] ^ C[S];
421
+ v(k);
422
+ }
423
+ return i;
424
+ }
425
+ function Ge(n, e, t, r, i) {
426
+ const o = i ? i.length : 0, s = n.create(t, r.length + o);
427
+ i && s.update(i);
428
+ const c = $e(8 * r.length, 8 * o, e);
429
+ s.update(r), s.update(c);
430
+ const a = s.digest();
431
+ return v(c), a;
432
+ }
433
+ const W = /* @__PURE__ */ Re({ blockSize: 16, nonceLength: 12, tagLength: 16, withAAD: !0, varSizeNonce: !0 }, function(e, t, r) {
434
+ if (t.length < 8)
435
+ throw new Error("aes/gcm: invalid nonce length");
436
+ const i = 16;
437
+ function o(c, a, l) {
438
+ const d = Ge(de, !1, c, l, r);
439
+ for (let u = 0; u < a.length; u++)
440
+ d[u] ^= a[u];
441
+ return d;
442
+ }
443
+ function s() {
444
+ const c = Ze(e), a = _.slice(), l = _.slice();
445
+ if (K(c, !1, l, l, a), t.length === 12)
446
+ l.set(t);
447
+ else {
448
+ const u = _.slice();
449
+ F(u).setBigUint64(8, BigInt(t.length * 8), !1);
450
+ const p = de.create(a).update(t).update(u);
451
+ p.digestInto(l), p.destroy();
452
+ }
453
+ const d = K(c, !1, l, _);
454
+ return { xk: c, authKey: a, counter: l, tagMask: d };
455
+ }
456
+ return {
457
+ encrypt(c) {
458
+ 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));
460
+ const f = o(l, u, h.subarray(0, h.length - i));
461
+ return p.push(f), h.set(f, c.length), v(...p), h;
462
+ },
463
+ decrypt(c) {
464
+ const { xk: a, authKey: l, counter: d, tagMask: u } = s(), h = [a, l, u, d];
465
+ U(c) || h.push(c = I(c));
466
+ const p = c.subarray(0, -i), f = c.subarray(-i), y = o(l, u, p);
467
+ if (h.push(y), !Be(y, f))
468
+ throw v(...h), new Error("aes-gcm: invalid tag");
469
+ const b = K(a, !1, d, p);
470
+ return v(...h), b;
471
+ }
472
+ };
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);
532
+ }
533
+ return Je(p, l, f, h, c);
534
+ }
535
+ }
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;
545
+ }
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);
550
+ }
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();
574
+ });
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);
582
+ }
583
+ }
584
+ const et = "iflowbim.cn", tt = 512, nt = 128, rt = 150, it = 38, O = 290, G = 190;
585
+ class zt {
586
+ THREE;
587
+ text;
588
+ scene;
589
+ camera;
590
+ material;
591
+ sprites = [];
592
+ size;
593
+ viewportWidth = 0;
594
+ viewportHeight = 0;
595
+ constructor(e, t = et) {
596
+ 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
+ map: new e.CanvasTexture(this.createTextTexture()),
598
+ transparent: !0,
599
+ opacity: 0.46,
600
+ depthTest: !1,
601
+ depthWrite: !1,
602
+ toneMapped: !1
603
+ }), this.size = new e.Vector2();
604
+ }
605
+ /**
606
+ * 在当前帧末尾把水印写入同一个 renderer canvas。
607
+ */
608
+ render(e) {
609
+ }
610
+ /**
611
+ * 释放水印内部纹理和材质,跟随宿主 renderer 生命周期销毁。
612
+ */
613
+ dispose() {
614
+ this.material.map?.dispose?.(), this.material.dispose?.(), this.sprites.length = 0;
615
+ }
616
+ createTextTexture() {
617
+ const e = document.createElement("canvas");
618
+ e.width = tt, e.height = nt;
619
+ const t = e.getContext("2d");
620
+ 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
+ }
622
+ updateLayout(e, t) {
623
+ if (e === this.viewportWidth && t === this.viewportHeight)
624
+ return;
625
+ 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;
627
+ this.ensureSpriteCount(o);
628
+ let s = 0;
629
+ const c = -e / 2 - O / 2, a = -t / 2 - G / 2;
630
+ for (let l = 0; l < i; l += 1)
631
+ 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;
633
+ u.position.set(h, p, 0), u.visible = !0, s += 1;
634
+ }
635
+ for (let l = s; l < this.sprites.length; l += 1)
636
+ this.sprites[l].visible = !1;
637
+ }
638
+ ensureSpriteCount(e) {
639
+ for (; this.sprites.length < e; ) {
640
+ 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);
642
+ }
643
+ }
644
+ }
645
+ function Rt() {
646
+ return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function(n) {
647
+ var e = Math.random() * 16 | 0, t = n == "x" ? e : e & 3 | 8;
648
+ return t.toString(16);
649
+ });
650
+ }
651
+ class g {
652
+ /** 从 URL 加载 TTF/OTF 字体,生成 Three.js typeface.json。 */
653
+ static async fromUrl(e, t) {
654
+ const r = await fetch(e);
655
+ if (!r.ok) throw new Error(`FontJsonGenerator: 无法加载 ${e} (${r.status})`);
656
+ const i = await r.arrayBuffer();
657
+ return g.fromArrayBuffer(i, t);
658
+ }
659
+ /** 从 ArrayBuffer 解析字体,生成 typeface.json。 */
660
+ static fromArrayBuffer(e, t) {
661
+ const r = Le(e);
662
+ return g._convert(r, t?.chars);
663
+ }
664
+ /** 将 typeface.json 转为 Three.js Font 对象,可直接用于文字几何。 */
665
+ static toThreeFont(e) {
666
+ return new Ce().parse(e);
667
+ }
668
+ static _convert(e, t) {
669
+ const r = {}, i = e.unitsPerEm, o = (u) => Math.round(u), s = (u) => {
670
+ const h = e.charToGlyph(u);
671
+ if (!h || h.index === 0) return;
672
+ const p = g._commandsToTypefaceOutline(h.path.commands, o), f = h.getBoundingBox();
673
+ r[u] = {
674
+ x_min: f.x1,
675
+ x_max: f.x2,
676
+ ha: h.advanceWidth ?? 0,
677
+ o: p.join(" ")
678
+ };
679
+ };
680
+ if (t)
681
+ for (const u of t) s(u);
682
+ else {
683
+ const u = e.tables.cmap?.glyphIndexMap ?? {};
684
+ for (const h of Object.keys(u)) {
685
+ const p = Number.parseInt(h, 10);
686
+ p > 0 && s(String.fromCodePoint(p));
687
+ }
688
+ }
689
+ if (!r[" "]) {
690
+ const u = e.charToGlyph(" ");
691
+ r[" "] = {
692
+ x_min: 0,
693
+ x_max: 0,
694
+ ha: u?.advanceWidth ?? Math.round(i / 4),
695
+ o: ""
696
+ };
697
+ }
698
+ const c = e.names, a = (u) => c[u]?.en ?? c[u]?.zh ?? "", l = a("fontFamily") || "Custom Font", d = a("fontSubfamily") || "Regular";
699
+ return {
700
+ familyName: l,
701
+ ascender: e.ascender,
702
+ descender: e.descender,
703
+ underlinePosition: e.tables.post?.underlinePosition ?? -100,
704
+ underlineThickness: e.tables.post?.underlineThickness ?? 50,
705
+ boundingBox: { yMin: e.descender, xMin: 0, yMax: e.ascender, xMax: i },
706
+ resolution: i,
707
+ original_font_information: { fontFamily: l, fontSubfamily: d },
708
+ cssFontStyle: d.toLowerCase().includes("italic") ? "italic" : "normal",
709
+ cssFontWeight: d.toLowerCase().includes("bold") ? "bold" : "normal",
710
+ glyphs: r
711
+ };
712
+ }
713
+ /** 将 opentype 命令拆为闭合轮廓,并输出为 Three 更稳定的“外轮廓 -> 孔洞”顺序。 */
714
+ static _commandsToTypefaceOutline(e, t) {
715
+ const r = g._splitContours(e), i = g._createContourEntries(r), o = i.filter((a) => a.depth % 2 === 0), s = i.filter((a) => a.depth % 2 === 1), c = [];
716
+ return o.sort((a, l) => a.index - l.index).forEach((a) => {
717
+ g._appendNormalizedContour(a.contour, !0, c, t), s.filter((l) => g._findParentSolid(l, o) === a).sort((l, d) => l.index - d.index).forEach((l) => g._appendNormalizedContour(l.contour, !1, c, t));
718
+ }), c;
719
+ }
720
+ static _createContourEntries(e) {
721
+ return e.filter((t) => t.segments.length > 0).map((t, r) => {
722
+ const i = g._samplePoint(t), o = e.reduce((s, c) => c === t || c.points.length < 3 ? s : g._pointInPolygon(i, c.points) ? s + 1 : s, 0);
723
+ return {
724
+ contour: t,
725
+ index: r,
726
+ depth: o,
727
+ absArea: Math.abs(g._signedArea(t.points))
728
+ };
729
+ });
730
+ }
731
+ static _findParentSolid(e, t) {
732
+ const r = g._samplePoint(e.contour);
733
+ return t.filter((i) => g._pointInPolygon(r, i.contour.points)).sort((i, o) => i.absArea - o.absArea)[0];
734
+ }
735
+ static _appendNormalizedContour(e, t, r, i) {
736
+ const s = g._signedArea(e.points) < 0 === t ? e.segments : g._reverseSegments(e.segments);
737
+ g._appendContour(s, r, i);
738
+ }
739
+ static _splitContours(e) {
740
+ const t = [];
741
+ let r = null, i = null;
742
+ const o = () => {
743
+ r && r.segments.length > 0 && t.push(r), r = null, i = null;
744
+ };
745
+ return e.forEach((s) => {
746
+ if (s.type === "M") {
747
+ o(), i = { x: s.x, y: s.y }, r = { segments: [], points: [i] };
748
+ return;
749
+ }
750
+ if (!r || !i) return;
751
+ if (s.type === "Z") {
752
+ o();
753
+ return;
754
+ }
755
+ const c = { x: s.x, y: s.y };
756
+ s.type === "L" ? r.segments.push({ type: "L", start: i, end: c }) : s.type === "Q" ? r.segments.push({ type: "Q", start: i, end: c, x1: s.x1, y1: s.y1 }) : s.type === "C" && r.segments.push({
757
+ type: "C",
758
+ start: i,
759
+ end: c,
760
+ x1: s.x1,
761
+ y1: s.y1,
762
+ x2: s.x2,
763
+ y2: s.y2
764
+ }), i = c, r.points.push(c);
765
+ }), o(), t;
766
+ }
767
+ static _appendContour(e, t, r) {
768
+ const i = e[0].start;
769
+ t.push(`m ${r(i.x)} ${r(i.y)}`), e.forEach((o) => {
770
+ o.type === "L" ? t.push(`l ${r(o.end.x)} ${r(o.end.y)}`) : o.type === "Q" ? t.push(`q ${r(o.end.x)} ${r(o.end.y)} ${r(o.x1)} ${r(o.y1)}`) : t.push(
771
+ `b ${r(o.end.x)} ${r(o.end.y)} ${r(o.x1)} ${r(o.y1)} ${r(o.x2)} ${r(o.y2)}`
772
+ );
773
+ }), t.push("z");
774
+ }
775
+ static _reverseSegments(e) {
776
+ return e.slice().reverse().map((t) => t.type === "L" ? { type: "L", start: t.end, end: t.start } : t.type === "Q" ? { type: "Q", start: t.end, end: t.start, x1: t.x1, y1: t.y1 } : {
777
+ type: "C",
778
+ start: t.end,
779
+ end: t.start,
780
+ x1: t.x2,
781
+ y1: t.y2,
782
+ x2: t.x1,
783
+ y2: t.y1
784
+ });
785
+ }
786
+ static _signedArea(e) {
787
+ let t = 0;
788
+ for (let r = 0, i = e.length - 1; r < e.length; i = r++)
789
+ t += e[i].x * e[r].y - e[r].x * e[i].y;
790
+ return t / 2;
791
+ }
792
+ static _samplePoint(e) {
793
+ return e.points[0];
794
+ }
795
+ static _pointInPolygon(e, t) {
796
+ let r = !1;
797
+ for (let i = 0, o = t.length - 1; i < t.length; o = i++) {
798
+ const s = t[i], c = t[o];
799
+ s.y > e.y != c.y > e.y && e.x < (c.x - s.x) * (e.y - s.y) / (c.y - s.y) + s.x && (r = !r);
800
+ }
801
+ return r;
802
+ }
803
+ }
804
+ function be(n) {
805
+ const e = String(n ?? "").trim().toLowerCase(), t = e.lastIndexOf(".");
806
+ return t >= 0 ? e.slice(t) : "";
807
+ }
808
+ function ot(n) {
809
+ return st(n.webkitRelativePath || n.name);
810
+ }
811
+ function _t(n) {
812
+ const e = URL.createObjectURL(n);
813
+ return {
814
+ url: e,
815
+ name: n.name,
816
+ extension: be(n.name),
817
+ revoke: () => URL.revokeObjectURL(e)
818
+ };
819
+ }
820
+ async function $t(n, e = "package.zip") {
821
+ const t = new ye();
822
+ n.forEach((o) => {
823
+ t.file(ot(o), o);
824
+ });
825
+ const r = await t.generateAsync({ type: "blob" }), i = URL.createObjectURL(r);
826
+ return {
827
+ url: i,
828
+ name: e,
829
+ extension: be(e),
830
+ revoke: () => URL.revokeObjectURL(i)
831
+ };
832
+ }
833
+ function st(n) {
834
+ return String(n).replace(/\\/g, "/").replace(/^\/+/, "").replace(/\/+/g, "/");
835
+ }
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
+ export {
1354
+ N as B,
1355
+ zt as C,
1356
+ V as E,
1357
+ 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
1365
+ };