iflow-engine-base 4.0.15 → 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 (148) hide show
  1. package/dist/bim-engine-sdk.es.js +33 -13
  2. package/dist/bim-engine-sdk.umd.js +2811 -342
  3. package/dist/chunks/EngineKernel-BucDRg23.js +20761 -0
  4. package/dist/chunks/engine-2d-BjtuYZUi.js +6119 -0
  5. package/dist/chunks/{engine-3d-DAEOqkkS.js → engine-3d-DnlK2vTK.js} +19422 -18597
  6. package/dist/chunks/engine-720-DJsweyG9.js +1565 -0
  7. package/dist/chunks/engine-gaussian-DklK6vdJ.js +8127 -0
  8. package/dist/chunks/gis-tiles-vendor-DIbUOKJM.js +11781 -0
  9. package/dist/chunks/index-BtsyaVm2.js +2640 -0
  10. package/dist/chunks/index-Ct7RfnLw.js +474 -0
  11. package/dist/chunks/index-Cyv0HpPm.js +438 -0
  12. package/dist/chunks/index-DZmXdy4v.js +717 -0
  13. package/dist/chunks/{sdk-assets-Eo-SBV02.js → sdk-assets-DtcFvuth.js} +10 -10
  14. package/dist/chunks/sdk-runtime-CFM9OAcx.js +1364 -0
  15. package/dist/chunks/sdk-vendor-6wYtfmXR.js +31826 -0
  16. package/dist/chunks/three-vendor-CGmeNMm5.js +81889 -0
  17. package/dist/gis-fixtures/terrain/0/0/0.terrain +0 -0
  18. package/dist/gis-fixtures/terrain/0/1/0.terrain +0 -0
  19. package/dist/gis-fixtures/terrain/1/2/0.terrain +0 -0
  20. package/dist/gis-fixtures/terrain/1/2/1.terrain +0 -0
  21. package/dist/gis-fixtures/terrain/1/3/0.terrain +0 -0
  22. package/dist/gis-fixtures/terrain/1/3/1.terrain +0 -0
  23. package/dist/gis-fixtures/terrain/10/1694/650.terrain +0 -0
  24. package/dist/gis-fixtures/terrain/10/1694/651.terrain +0 -0
  25. package/dist/gis-fixtures/terrain/10/1694/652.terrain +0 -0
  26. package/dist/gis-fixtures/terrain/10/1695/650.terrain +0 -0
  27. package/dist/gis-fixtures/terrain/10/1695/651.terrain +0 -0
  28. package/dist/gis-fixtures/terrain/10/1695/652.terrain +0 -0
  29. package/dist/gis-fixtures/terrain/10/1696/650.terrain +0 -0
  30. package/dist/gis-fixtures/terrain/10/1696/651.terrain +0 -0
  31. package/dist/gis-fixtures/terrain/10/1696/652.terrain +0 -0
  32. package/dist/gis-fixtures/terrain/11/3390/1301.terrain +0 -0
  33. package/dist/gis-fixtures/terrain/11/3390/1302.terrain +0 -0
  34. package/dist/gis-fixtures/terrain/11/3390/1303.terrain +0 -0
  35. package/dist/gis-fixtures/terrain/11/3391/1301.terrain +0 -0
  36. package/dist/gis-fixtures/terrain/11/3391/1302.terrain +0 -0
  37. package/dist/gis-fixtures/terrain/11/3391/1303.terrain +0 -0
  38. package/dist/gis-fixtures/terrain/11/3392/1301.terrain +0 -0
  39. package/dist/gis-fixtures/terrain/11/3392/1302.terrain +0 -0
  40. package/dist/gis-fixtures/terrain/11/3392/1303.terrain +0 -0
  41. package/dist/gis-fixtures/terrain/12/6782/2604.terrain +0 -0
  42. package/dist/gis-fixtures/terrain/12/6782/2605.terrain +0 -0
  43. package/dist/gis-fixtures/terrain/12/6782/2606.terrain +0 -0
  44. package/dist/gis-fixtures/terrain/12/6783/2604.terrain +0 -0
  45. package/dist/gis-fixtures/terrain/12/6783/2605.terrain +0 -0
  46. package/dist/gis-fixtures/terrain/12/6783/2606.terrain +0 -0
  47. package/dist/gis-fixtures/terrain/12/6784/2604.terrain +0 -0
  48. package/dist/gis-fixtures/terrain/12/6784/2605.terrain +0 -0
  49. package/dist/gis-fixtures/terrain/12/6784/2606.terrain +0 -0
  50. package/dist/gis-fixtures/terrain/13/13565/5209.terrain +0 -0
  51. package/dist/gis-fixtures/terrain/13/13565/5210.terrain +0 -0
  52. package/dist/gis-fixtures/terrain/13/13565/5211.terrain +0 -0
  53. package/dist/gis-fixtures/terrain/13/13566/5209.terrain +0 -0
  54. package/dist/gis-fixtures/terrain/13/13566/5210.terrain +0 -0
  55. package/dist/gis-fixtures/terrain/13/13566/5211.terrain +0 -0
  56. package/dist/gis-fixtures/terrain/13/13567/5209.terrain +0 -0
  57. package/dist/gis-fixtures/terrain/13/13567/5210.terrain +0 -0
  58. package/dist/gis-fixtures/terrain/13/13567/5211.terrain +0 -0
  59. package/dist/gis-fixtures/terrain/14/27131/10419.terrain +0 -0
  60. package/dist/gis-fixtures/terrain/14/27131/10420.terrain +0 -0
  61. package/dist/gis-fixtures/terrain/14/27131/10421.terrain +0 -0
  62. package/dist/gis-fixtures/terrain/14/27132/10419.terrain +0 -0
  63. package/dist/gis-fixtures/terrain/14/27132/10420.terrain +0 -0
  64. package/dist/gis-fixtures/terrain/14/27132/10421.terrain +0 -0
  65. package/dist/gis-fixtures/terrain/14/27133/10419.terrain +0 -0
  66. package/dist/gis-fixtures/terrain/14/27133/10420.terrain +0 -0
  67. package/dist/gis-fixtures/terrain/14/27133/10421.terrain +0 -0
  68. package/dist/gis-fixtures/terrain/2/5/1.terrain +0 -0
  69. package/dist/gis-fixtures/terrain/2/5/2.terrain +0 -0
  70. package/dist/gis-fixtures/terrain/2/5/3.terrain +0 -0
  71. package/dist/gis-fixtures/terrain/2/6/1.terrain +0 -0
  72. package/dist/gis-fixtures/terrain/2/6/2.terrain +0 -0
  73. package/dist/gis-fixtures/terrain/2/6/3.terrain +0 -0
  74. package/dist/gis-fixtures/terrain/2/7/1.terrain +0 -0
  75. package/dist/gis-fixtures/terrain/2/7/2.terrain +0 -0
  76. package/dist/gis-fixtures/terrain/2/7/3.terrain +0 -0
  77. package/dist/gis-fixtures/terrain/3/12/4.terrain +0 -0
  78. package/dist/gis-fixtures/terrain/3/12/5.terrain +0 -0
  79. package/dist/gis-fixtures/terrain/3/12/6.terrain +0 -0
  80. package/dist/gis-fixtures/terrain/3/13/4.terrain +0 -0
  81. package/dist/gis-fixtures/terrain/3/13/5.terrain +0 -0
  82. package/dist/gis-fixtures/terrain/3/13/6.terrain +0 -0
  83. package/dist/gis-fixtures/terrain/3/14/4.terrain +0 -0
  84. package/dist/gis-fixtures/terrain/3/14/5.terrain +0 -0
  85. package/dist/gis-fixtures/terrain/3/14/6.terrain +0 -0
  86. package/dist/gis-fixtures/terrain/4/25/10.terrain +0 -0
  87. package/dist/gis-fixtures/terrain/4/25/11.terrain +0 -0
  88. package/dist/gis-fixtures/terrain/4/25/9.terrain +0 -0
  89. package/dist/gis-fixtures/terrain/4/26/10.terrain +0 -0
  90. package/dist/gis-fixtures/terrain/4/26/11.terrain +0 -0
  91. package/dist/gis-fixtures/terrain/4/26/9.terrain +0 -0
  92. package/dist/gis-fixtures/terrain/4/27/10.terrain +0 -0
  93. package/dist/gis-fixtures/terrain/4/27/11.terrain +0 -0
  94. package/dist/gis-fixtures/terrain/4/27/9.terrain +0 -0
  95. package/dist/gis-fixtures/terrain/5/51/19.terrain +0 -0
  96. package/dist/gis-fixtures/terrain/5/51/20.terrain +0 -0
  97. package/dist/gis-fixtures/terrain/5/51/21.terrain +0 -0
  98. package/dist/gis-fixtures/terrain/5/52/19.terrain +0 -0
  99. package/dist/gis-fixtures/terrain/5/52/20.terrain +0 -0
  100. package/dist/gis-fixtures/terrain/5/52/21.terrain +0 -0
  101. package/dist/gis-fixtures/terrain/5/53/19.terrain +0 -0
  102. package/dist/gis-fixtures/terrain/5/53/20.terrain +0 -0
  103. package/dist/gis-fixtures/terrain/5/53/21.terrain +0 -0
  104. package/dist/gis-fixtures/terrain/6/104/39.terrain +0 -0
  105. package/dist/gis-fixtures/terrain/6/104/40.terrain +0 -0
  106. package/dist/gis-fixtures/terrain/6/104/41.terrain +0 -0
  107. package/dist/gis-fixtures/terrain/6/105/39.terrain +0 -0
  108. package/dist/gis-fixtures/terrain/6/105/40.terrain +0 -0
  109. package/dist/gis-fixtures/terrain/6/105/41.terrain +0 -0
  110. package/dist/gis-fixtures/terrain/6/106/39.terrain +0 -0
  111. package/dist/gis-fixtures/terrain/6/106/40.terrain +0 -0
  112. package/dist/gis-fixtures/terrain/6/106/41.terrain +0 -0
  113. package/dist/gis-fixtures/terrain/7/210/80.terrain +0 -0
  114. package/dist/gis-fixtures/terrain/7/210/81.terrain +0 -0
  115. package/dist/gis-fixtures/terrain/7/210/82.terrain +0 -0
  116. package/dist/gis-fixtures/terrain/7/211/80.terrain +0 -0
  117. package/dist/gis-fixtures/terrain/7/211/81.terrain +0 -0
  118. package/dist/gis-fixtures/terrain/7/211/82.terrain +0 -0
  119. package/dist/gis-fixtures/terrain/7/212/80.terrain +0 -0
  120. package/dist/gis-fixtures/terrain/7/212/81.terrain +0 -0
  121. package/dist/gis-fixtures/terrain/7/212/82.terrain +0 -0
  122. package/dist/gis-fixtures/terrain/8/422/161.terrain +0 -0
  123. package/dist/gis-fixtures/terrain/8/422/162.terrain +0 -0
  124. package/dist/gis-fixtures/terrain/8/422/163.terrain +0 -0
  125. package/dist/gis-fixtures/terrain/8/423/161.terrain +0 -0
  126. package/dist/gis-fixtures/terrain/8/423/162.terrain +0 -0
  127. package/dist/gis-fixtures/terrain/8/423/163.terrain +0 -0
  128. package/dist/gis-fixtures/terrain/8/424/161.terrain +0 -0
  129. package/dist/gis-fixtures/terrain/8/424/162.terrain +0 -0
  130. package/dist/gis-fixtures/terrain/8/424/163.terrain +0 -0
  131. package/dist/gis-fixtures/terrain/9/846/324.terrain +0 -0
  132. package/dist/gis-fixtures/terrain/9/846/325.terrain +0 -0
  133. package/dist/gis-fixtures/terrain/9/846/326.terrain +0 -0
  134. package/dist/gis-fixtures/terrain/9/847/324.terrain +0 -0
  135. package/dist/gis-fixtures/terrain/9/847/325.terrain +0 -0
  136. package/dist/gis-fixtures/terrain/9/847/326.terrain +0 -0
  137. package/dist/gis-fixtures/terrain/9/848/324.terrain +0 -0
  138. package/dist/gis-fixtures/terrain/9/848/325.terrain +0 -0
  139. package/dist/gis-fixtures/terrain/9/848/326.terrain +0 -0
  140. package/dist/gis-fixtures/terrain/layer.json +141 -0
  141. package/dist/gis-fixtures/tilesets/xiamen-local/scene.gltf +31 -0
  142. package/dist/gis-fixtures/tilesets/xiamen-local/tileset.json +12 -0
  143. package/dist/iflow-engine-base.css +1 -1
  144. package/dist/index.d.ts +13908 -68
  145. package/package.json +8 -18
  146. package/dist/chunks/sdk-runtime-CB2jwkGL.js +0 -1177
  147. package/dist/chunks/sdk-vendor-DtYOqJWo.js +0 -23208
  148. package/dist/chunks/three-vendor-rBTtPKhu.js +0 -44788
@@ -0,0 +1,1364 @@
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
+ 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 {
203
+ /**
204
+ * 构造函数
205
+ * @param camera - Three.js 相机对象(用于投影计算)
206
+ * @param renderer - Three.js 渲染器对象(用于获取画布尺寸)
207
+ * @param scene - Three.js 场景对象(用于屏幕坐标转世界坐标时的射线检测,可选)
208
+ */
209
+ constructor(e, t, r) {
210
+ this.camera = e, this.renderer = t, this.scene = r, this.raycaster = new Te();
211
+ }
212
+ camera;
213
+ renderer;
214
+ scene;
215
+ raycaster;
216
+ /**
217
+ * 将世界坐标转换为屏幕坐标(归一化坐标,范围 -1 到 1)
218
+ * @param worldPos - 世界空间中的3D坐标点
219
+ * @returns 归一化的屏幕坐标,x 和 y 的范围都是 -1 到 1
220
+ * x: -1 表示屏幕左边缘,1 表示屏幕右边缘
221
+ * y: -1 表示屏幕下边缘,1 表示屏幕上边缘
222
+ */
223
+ worldToScreenNormalized(e) {
224
+ const t = e.clone();
225
+ return t.project(this.camera), new R(t.x, t.y);
226
+ }
227
+ /**
228
+ * 将世界坐标转换为屏幕坐标(像素坐标)
229
+ * @param worldPos - 世界空间中的3D坐标点
230
+ * @returns 屏幕像素坐标,x 和 y 表示在画布上的实际像素位置
231
+ * x: 0 表示屏幕左边缘,width 表示屏幕右边缘
232
+ * y: 0 表示屏幕上边缘,height 表示屏幕下边缘
233
+ */
234
+ worldToScreen(e) {
235
+ const t = new le();
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);
237
+ }
238
+ /**
239
+ * 将世界坐标转换为屏幕坐标,仅在点位于当前相机可见裁剪空间内时返回结果。
240
+ * 透视相机背后的点经过 project 后会翻转到屏幕异常位置,这里提前过滤。
241
+ * @param worldPos - 世界空间中的 3D 坐标点
242
+ * @returns 屏幕像素坐标;如果点不可见或投影结果无效,返回 null
243
+ */
244
+ worldToScreenIfVisible(e) {
245
+ if (this.camera.updateMatrixWorld(!0), this.camera instanceof Ae && e.clone().applyMatrix4(this.camera.matrixWorldInverse).z >= 0)
246
+ return null;
247
+ const t = e.clone().project(this.camera);
248
+ if (!Number.isFinite(t.x) || !Number.isFinite(t.y) || !Number.isFinite(t.z) || t.z < -1 || t.z > 1)
249
+ return null;
250
+ const r = this.renderer.domElement.clientWidth, i = this.renderer.domElement.clientHeight;
251
+ return new R(
252
+ t.x * r * 0.5 + r * 0.5,
253
+ -t.y * i * 0.5 + i * 0.5
254
+ );
255
+ }
256
+ /**
257
+ * 将屏幕坐标(像素坐标)转换为归一化坐标
258
+ * @param screenX - 屏幕像素 X 坐标
259
+ * @param screenY - 屏幕像素 Y 坐标
260
+ * @returns 归一化的屏幕坐标,范围 -1 到 1
261
+ */
262
+ screenToNormalized(e, t) {
263
+ const r = this.renderer.domElement.clientWidth, i = this.renderer.domElement.clientHeight, o = e / r * 2 - 1, s = -(t / i * 2 - 1);
264
+ return new R(o, s);
265
+ }
266
+ /**
267
+ * 将屏幕坐标(像素坐标)转换为世界坐标
268
+ * 使用射线检测,返回与场景中第一个相交对象的世界坐标点
269
+ * @param screenX - 屏幕像素 X 坐标
270
+ * @param screenY - 屏幕像素 Y 坐标
271
+ * @param objects - 可选,指定要检测的对象数组。如果不提供且 scene 存在,则检测场景中的所有对象
272
+ * @returns 世界坐标点,如果没有相交则返回 null
273
+ */
274
+ screenToWorld(e, t, r) {
275
+ if (!this.scene && !r)
276
+ return console.warn("WorldToScreen: 需要提供 scene 或 objects 参数才能进行屏幕坐标转世界坐标"), null;
277
+ const i = this.screenToNormalized(e, t);
278
+ this.raycaster.setFromCamera(i, this.camera);
279
+ const o = r || this.scene.children, s = this.raycaster.intersectObjects(o, !0);
280
+ return s.length > 0 ? s[0].point : null;
281
+ }
282
+ /**
283
+ * 将屏幕坐标转换为指定深度的世界坐标
284
+ * @param screenX - 屏幕像素 X 坐标
285
+ * @param screenY - 屏幕像素 Y 坐标
286
+ * @param depth - 沿射线方向的距离(世界单位)
287
+ * @returns 世界坐标点
288
+ */
289
+ screenToWorldWithDepth(e, t, r = 0) {
290
+ const i = this.screenToNormalized(e, t);
291
+ this.raycaster.setFromCamera(i, this.camera);
292
+ const o = new le();
293
+ return this.raycaster.ray.at(r, o), o;
294
+ }
295
+ /**
296
+ * 更新相机引用(当相机发生变化时调用)
297
+ * @param camera - 新的相机对象
298
+ */
299
+ updateCamera(e) {
300
+ this.camera = e;
301
+ }
302
+ /**
303
+ * 更新渲染器引用(当渲染器发生变化时调用)
304
+ * @param renderer - 新的渲染器对象
305
+ */
306
+ updateRenderer(e) {
307
+ this.renderer = e;
308
+ }
309
+ /**
310
+ * 更新场景引用(当场景发生变化时调用)
311
+ * @param scene - 新的场景对象
312
+ */
313
+ updateScene(e) {
314
+ this.scene = e;
315
+ }
316
+ }
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");
324
+ return n;
325
+ }
326
+ function U(n) {
327
+ return new TextEncoder().encode(n);
328
+ }
329
+ function I(n) {
330
+ return n.buffer.slice(n.byteOffset, n.byteOffset + n.byteLength);
331
+ }
332
+ function ue(n) {
333
+ let e = "";
334
+ return n.forEach((t) => {
335
+ e += String.fromCharCode(t);
336
+ }), btoa(e);
337
+ }
338
+ function Ie(n) {
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}`;
341
+ }
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("");
345
+ }
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)));
349
+ }
350
+ function Re(n) {
351
+ return U(
352
+ [n.appId, n.engineType, n.requestDate, String(n.timestamp), n.nonce].join("|")
353
+ );
354
+ }
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)));
552
+ return o.outputLen = s.outputLen, o.blockLen = s.blockLen, o.create = (c, ...a) => r(c, ...a), o;
553
+ }
554
+ const Fe = /* @__NO_SIDE_EFFECTS__ */ (n, e) => {
555
+ function t(r, ...i) {
556
+ if (w(r, void 0, "key"), n.nonceLength !== void 0) {
557
+ const u = i[0];
558
+ w(u, n.varSizeNonce ? void 0 : n.nonceLength, "nonce");
559
+ }
560
+ const o = n.tagLength, s = n.nonceLength !== void 0 ? 1 : 0;
561
+ if (!n.withAAD) {
562
+ for (let u = s; u < i.length; u++)
563
+ if (ne(i[u]))
564
+ throw new Error("AAD not supported");
565
+ }
566
+ n.withAAD && i[s] !== void 0 && w(i[s], void 0, "AAD");
567
+ const c = e(r, ...i), a = (u, h) => {
568
+ if (h !== void 0) {
569
+ if (u !== 2)
570
+ throw new Error("cipher output not supported");
571
+ w(h, void 0, "output");
572
+ }
573
+ };
574
+ let l = !1;
575
+ return {
576
+ encrypt(u, h) {
577
+ if (l)
578
+ throw new Error("cannot encrypt() twice with same key + nonce");
579
+ return l = !0, w(u, void 0, "data"), a(c.encrypt.length, h), c.encrypt(u, h);
580
+ },
581
+ decrypt(u, h) {
582
+ if (w(u, void 0, "data"), o && u.length < o)
583
+ throw new Error('"ciphertext" expected length >= tagLength=' + o);
584
+ return a(c.decrypt.length, h), c.decrypt(u, h);
585
+ }
586
+ };
587
+ }
588
+ return Object.assign(t, n), t;
589
+ };
590
+ function qe(n, e, t = !0) {
591
+ if (e === void 0)
592
+ return new Uint8Array(n);
593
+ if (w(e, n, "output"), t && !M(e))
594
+ throw new Error("invalid output, must be aligned");
595
+ return e;
596
+ }
597
+ function Ye(n, e, t) {
598
+ ie(n), ie(e);
599
+ const r = new Uint8Array(16), i = F(r);
600
+ return i.setBigUint64(0, BigInt(e), t), i.setBigUint64(8, BigInt(n), t), r;
601
+ }
602
+ function M(n) {
603
+ return n.byteOffset % 4 === 0;
604
+ }
605
+ function B(n) {
606
+ return Uint8Array.from(w(n));
607
+ }
608
+ const T = 16, ge = /* @__PURE__ */ new Uint8Array(16), L = /* @__PURE__ */ A(ge), Ze = 225, Ge = (n, e, t, r) => {
609
+ const i = r & 1;
610
+ return {
611
+ s3: t << 31 | r >>> 1,
612
+ s2: e << 31 | t >>> 1,
613
+ s1: n << 31 | e >>> 1,
614
+ // NIST SP 800-38D §6.3 applies `V >> 1` and XORs R on carry. In this
615
+ // 4x32-bit split, R = 0xe1 || 0^120 lives in the top byte of s0.
616
+ s0: n >>> 1 ^ Ze << 24 & -(i & 1)
617
+ // reduce % poly
618
+ };
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 {
621
+ blockLen = T;
622
+ outputLen = T;
623
+ s0 = 0;
624
+ s1 = 0;
625
+ s2 = 0;
626
+ s3 = 0;
627
+ finished = !1;
628
+ destroyed = !1;
629
+ t;
630
+ W;
631
+ windowSize;
632
+ // We select bits per window adaptively based on expectedLength
633
+ constructor(e, t) {
634
+ w(e, 16, "key"), e = B(e);
635
+ const r = F(e);
636
+ let i = r.getUint32(0, !1), o = r.getUint32(4, !1), s = r.getUint32(8, !1), c = r.getUint32(12, !1);
637
+ const a = [];
638
+ for (let f = 0; f < 128; f++)
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);
641
+ if (![1, 2, 4, 8].includes(l))
642
+ throw new Error("ghash: invalid window size, expected 2, 4 or 8");
643
+ this.W = l;
644
+ const u = 128 / l, h = this.windowSize = 2 ** l, p = [];
645
+ for (let f = 0; f < u; f++)
646
+ for (let y = 0; y < h; y++) {
647
+ let b = 0, x = 0, k = 0, C = 0;
648
+ for (let E = 0; E < l; E++) {
649
+ if (!(y >>> l - E - 1 & 1))
650
+ continue;
651
+ const { s0: Y, s1: ke, s2: Ee, s3: ve } = a[l * f + E];
652
+ b ^= Y, x ^= ke, k ^= Ee, C ^= ve;
653
+ }
654
+ p.push({ s0: b, s1: x, s2: k, s3: C });
655
+ }
656
+ this.t = p;
657
+ }
658
+ _updateBlock(e, t, r, i) {
659
+ e ^= this.s0, t ^= this.s1, r ^= this.s2, i ^= this.s3;
660
+ const { W: o, t: s, windowSize: c } = this;
661
+ let a = 0, l = 0, d = 0, u = 0;
662
+ const h = (1 << o) - 1;
663
+ let p = 0;
664
+ for (const f of [e, t, r, i])
665
+ for (let y = 0; y < 4; y++) {
666
+ const b = f >>> 8 * y & 255;
667
+ for (let x = 8 / o - 1; x >= 0; x--) {
668
+ const k = b >>> o * x & h, { s0: C, s1: E, s2: S, s3: Y } = s[p * c + k];
669
+ a ^= C, l ^= E, d ^= S, u ^= Y, p += 1;
670
+ }
671
+ }
672
+ this.s0 = a, this.s1 = l, this.s2 = d, this.s3 = u;
673
+ }
674
+ update(e) {
675
+ de(this), w(e), e = B(e);
676
+ const t = A(e), r = Math.floor(e.length / T), i = e.length % T;
677
+ for (let o = 0; o < r; o++)
678
+ this._updateBlock(m(t[o * 4 + 0]), m(t[o * 4 + 1]), m(t[o * 4 + 2]), m(t[o * 4 + 3]));
679
+ 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;
680
+ }
681
+ destroy() {
682
+ this.destroyed = !0;
683
+ const { t: e } = this;
684
+ for (const t of e)
685
+ t.s0 = 0, t.s1 = 0, t.s2 = 0, t.s3 = 0;
686
+ }
687
+ digestInto(e) {
688
+ de(this), We(e, this), this.finished = !0;
689
+ const { s0: t, s1: r, s2: i, s3: o } = this, s = A(e);
690
+ s[0] = t, s[1] = r, s[2] = i, s[3] = o, q || ce(s.subarray(0, T / 4));
691
+ }
692
+ digest() {
693
+ const e = new Uint8Array(T);
694
+ return this.digestInto(e), this.destroy(), e;
695
+ }
696
+ }
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) {
699
+ if (![16, 24, 32].includes(n.length))
700
+ throw new Error('"aes key" expected Uint8Array of length 16/24/32, got length=' + n.length);
701
+ }
702
+ function ae(n) {
703
+ return n << 1 ^ et & -(n >> 7);
704
+ }
705
+ function fe(n, e) {
706
+ let t = 0;
707
+ for (; e > 0; e >>= 1)
708
+ t ^= n & -(e & 1), n = ae(n);
709
+ return t;
710
+ }
711
+ const nt = /* @__PURE__ */ (() => {
712
+ const n = new Uint8Array(256);
713
+ for (let t = 0, r = 1; t < 256; t++, r ^= ae(r))
714
+ n[t] = r;
715
+ const e = new Uint8Array(256);
716
+ e[0] = 99;
717
+ for (let t = 0; t < 255; t++) {
718
+ let r = n[255 - t];
719
+ r |= r << 8, e[n[t]] = (r ^ r >> 4 ^ r >> 5 ^ r >> 6 ^ r >> 7 ^ 99) & 255;
720
+ }
721
+ return v(n), e;
722
+ })(), rt = (n) => n << 24 | n >>> 8, G = (n) => n << 8 | n >>> 24;
723
+ function it(n, e) {
724
+ if (n.length !== 256)
725
+ throw new Error("wrong sbox length");
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);
727
+ for (let l = 0; l < 256; l++)
728
+ for (let d = 0; d < 256; d++) {
729
+ const u = l * 256 + d;
730
+ s[u] = t[l] ^ r[d], c[u] = i[l] ^ o[d], a[u] = n[l] << 8 | n[d];
731
+ }
732
+ return { sbox: n, sbox2: a, T0: t, T1: r, T2: i, T3: o, T01: s, T23: c };
733
+ }
734
+ const we = /* @__PURE__ */ it(nt, (n) => fe(n, 3) << 24 | n << 16 | n << 8 | fe(n, 2)), ot = /* @__PURE__ */ (() => {
735
+ const n = new Uint8Array(16);
736
+ for (let e = 0, t = 1; e < 16; e++, t = ae(t))
737
+ n[e] = t;
738
+ return n;
739
+ })();
740
+ function st(n) {
741
+ w(n);
742
+ const e = n.length;
743
+ tt(n);
744
+ const { sbox2: t } = we, r = [];
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);
747
+ c.set(i);
748
+ for (let a = o; a < c.length; a++) {
749
+ let l = c[a - 1];
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;
751
+ }
752
+ return v(...r), c;
753
+ }
754
+ function $(n, e, t, r, i, o) {
755
+ return n[t << 8 & 65280 | r >>> 8 & 255] ^ e[i >>> 8 & 65280 | o >>> 24 & 255];
756
+ }
757
+ function P(n, e, t, r, i) {
758
+ return n[e & 255 | t & 65280] | n[r >>> 16 & 255 | i >>> 16 & 65280] << 16;
759
+ }
760
+ function pe(n, e, t, r, i) {
761
+ const { sbox2: o, T01: s, T23: c } = we;
762
+ let a = 0;
763
+ e ^= n[a++], t ^= n[a++], r ^= n[a++], i ^= n[a++];
764
+ const l = n.length / 4 - 2;
765
+ for (let f = 0; f < l; f++) {
766
+ 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);
767
+ e = y, t = b, r = x, i = k;
768
+ }
769
+ 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);
770
+ return { s0: d, s1: u, s2: h, s3: p };
771
+ }
772
+ function K(n, e, t, r, i) {
773
+ w(t, oe, "nonce"), w(r), i = qe(r.length, i);
774
+ const o = t, s = A(o), c = F(o), a = A(r), l = A(i), d = e ? 0 : 12, u = r.length;
775
+ let h = c.getUint32(d, e);
776
+ for (let f = 0; f + 4 <= a.length; f += 4) {
777
+ const { s0: y, s1: b, s2: x, s3: k } = pe(n, m(s[0]), m(s[1]), m(s[2]), m(s[3]));
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);
779
+ }
780
+ const p = oe * Math.floor(a.length / Je);
781
+ if (p < u) {
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);
785
+ for (let E = p, S = 0; E < u; E++, S++)
786
+ i[E] = r[E] ^ C[S];
787
+ v(k);
788
+ }
789
+ return i;
790
+ }
791
+ function ct(n, e, t, r, i) {
792
+ const o = i ? i.length : 0, s = n.create(t, r.length + o);
793
+ i && s.update(i);
794
+ const c = Ye(8 * r.length, 8 * o, e);
795
+ s.update(r), s.update(c);
796
+ const a = s.digest();
797
+ return v(c), a;
798
+ }
799
+ const W = /* @__PURE__ */ Fe({ blockSize: 16, nonceLength: 12, tagLength: 16, withAAD: !0, varSizeNonce: !0 }, function(e, t, r) {
800
+ if (t.length < 8)
801
+ throw new Error("aes/gcm: invalid nonce length");
802
+ const i = 16;
803
+ function o(c, a, l) {
804
+ const d = ct(he, !1, c, l, r);
805
+ for (let u = 0; u < a.length; u++)
806
+ d[u] ^= a[u];
807
+ return d;
808
+ }
809
+ function s() {
810
+ const c = st(e), a = _.slice(), l = _.slice();
811
+ if (K(c, !1, l, l, a), t.length === 12)
812
+ l.set(t);
813
+ else {
814
+ const u = _.slice();
815
+ F(u).setBigUint64(8, BigInt(t.length * 8), !1);
816
+ const p = he.create(a).update(t).update(u);
817
+ p.digestInto(l), p.destroy();
818
+ }
819
+ const d = K(c, !1, l, _);
820
+ return { xk: c, authKey: a, counter: l, tagMask: d };
821
+ }
822
+ return {
823
+ encrypt(c) {
824
+ const { xk: a, authKey: l, counter: d, tagMask: u } = s(), h = new Uint8Array(c.length + i), p = [a, l, d, u];
825
+ M(c) || p.push(c = B(c)), K(a, !1, d, c, h.subarray(0, c.length));
826
+ const f = o(l, u, h.subarray(0, h.length - i));
827
+ return p.push(f), h.set(f, c.length), v(...p), h;
828
+ },
829
+ decrypt(c) {
830
+ const { xk: a, authKey: l, counter: d, tagMask: u } = s(), h = [a, l, u, d];
831
+ M(c) || h.push(c = B(c));
832
+ const p = c.subarray(0, -i), f = c.subarray(-i), y = o(l, u, p);
833
+ if (h.push(y), !De(y, f))
834
+ throw v(...h), new Error("aes-gcm: invalid tag");
835
+ const b = K(a, !1, d, p);
836
+ return v(...h), b;
837
+ }
838
+ };
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);
865
+ }
866
+ return o;
867
+ } finally {
868
+ r != null && clearTimeout(r);
869
+ }
870
+ }
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));
876
+ }
877
+ function dt(n) {
878
+ let e = "";
879
+ return n.forEach((t) => {
880
+ e += String.fromCharCode(t);
881
+ }), e;
882
+ }
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;
901
+ });
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";
959
+ }
960
+ }
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;
991
+ class zt {
992
+ THREE;
993
+ text;
994
+ scene;
995
+ camera;
996
+ material;
997
+ sprites = [];
998
+ size;
999
+ viewportWidth = 0;
1000
+ viewportHeight = 0;
1001
+ constructor(e, t = xt) {
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({
1003
+ map: new e.CanvasTexture(this.createTextTexture()),
1004
+ transparent: !0,
1005
+ opacity: 0.46,
1006
+ depthTest: !1,
1007
+ depthWrite: !1,
1008
+ toneMapped: !1
1009
+ }), this.size = new e.Vector2();
1010
+ }
1011
+ /**
1012
+ * 在当前帧末尾把水印写入同一个 renderer canvas。
1013
+ */
1014
+ render(e) {
1015
+ }
1016
+ /**
1017
+ * 释放水印内部纹理和材质,跟随宿主 renderer 生命周期销毁。
1018
+ */
1019
+ dispose() {
1020
+ this.material.map?.dispose?.(), this.material.dispose?.(), this.sprites.length = 0;
1021
+ }
1022
+ createTextTexture() {
1023
+ const e = document.createElement("canvas");
1024
+ e.width = kt, e.height = Et;
1025
+ const t = e.getContext("2d");
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;
1027
+ }
1028
+ updateLayout(e, t) {
1029
+ if (e === this.viewportWidth && t === this.viewportHeight)
1030
+ return;
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();
1032
+ const r = Math.ceil(e / j) + 2, i = Math.ceil(t / J) + 2, o = r * i;
1033
+ this.ensureSpriteCount(o);
1034
+ let s = 0;
1035
+ const c = -e / 2 - j / 2, a = -t / 2 - J / 2;
1036
+ for (let l = 0; l < i; l += 1)
1037
+ for (let d = 0; d < r; d += 1) {
1038
+ const u = this.sprites[s], h = c + d * j + l % 2 * (j / 2), p = a + l * J;
1039
+ u.position.set(h, p, 0), u.visible = !0, s += 1;
1040
+ }
1041
+ for (let l = s; l < this.sprites.length; l += 1)
1042
+ this.sprites[l].visible = !1;
1043
+ }
1044
+ ensureSpriteCount(e) {
1045
+ for (; this.sprites.length < e; ) {
1046
+ const t = new this.THREE.Sprite(this.material);
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);
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);
1159
+ }
1160
+ }
1161
+ function $t() {
1162
+ return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function(n) {
1163
+ var e = Math.random() * 16 | 0, t = n == "x" ? e : e & 3 | 8;
1164
+ return t.toString(16);
1165
+ });
1166
+ }
1167
+ class g {
1168
+ /** 从 URL 加载 TTF/OTF 字体,生成 Three.js typeface.json。 */
1169
+ static async fromUrl(e, t) {
1170
+ const r = await fetch(e);
1171
+ if (!r.ok) throw new Error(`FontJsonGenerator: 无法加载 ${e} (${r.status})`);
1172
+ const i = await r.arrayBuffer();
1173
+ return g.fromArrayBuffer(i, t);
1174
+ }
1175
+ /** 从 ArrayBuffer 解析字体,生成 typeface.json。 */
1176
+ static fromArrayBuffer(e, t) {
1177
+ const r = Le(e);
1178
+ return g._convert(r, t?.chars);
1179
+ }
1180
+ /** 将 typeface.json 转为 Three.js Font 对象,可直接用于文字几何。 */
1181
+ static toThreeFont(e) {
1182
+ return new Ce().parse(e);
1183
+ }
1184
+ static _convert(e, t) {
1185
+ const r = {}, i = e.unitsPerEm, o = (u) => Math.round(u), s = (u) => {
1186
+ const h = e.charToGlyph(u);
1187
+ if (!h || h.index === 0) return;
1188
+ const p = g._commandsToTypefaceOutline(h.path.commands, o), f = h.getBoundingBox();
1189
+ r[u] = {
1190
+ x_min: f.x1,
1191
+ x_max: f.x2,
1192
+ ha: h.advanceWidth ?? 0,
1193
+ o: p.join(" ")
1194
+ };
1195
+ };
1196
+ if (t)
1197
+ for (const u of t) s(u);
1198
+ else {
1199
+ const u = e.tables.cmap?.glyphIndexMap ?? {};
1200
+ for (const h of Object.keys(u)) {
1201
+ const p = Number.parseInt(h, 10);
1202
+ p > 0 && s(String.fromCodePoint(p));
1203
+ }
1204
+ }
1205
+ if (!r[" "]) {
1206
+ const u = e.charToGlyph(" ");
1207
+ r[" "] = {
1208
+ x_min: 0,
1209
+ x_max: 0,
1210
+ ha: u?.advanceWidth ?? Math.round(i / 4),
1211
+ o: ""
1212
+ };
1213
+ }
1214
+ const c = e.names, a = (u) => c[u]?.en ?? c[u]?.zh ?? "", l = a("fontFamily") || "Custom Font", d = a("fontSubfamily") || "Regular";
1215
+ return {
1216
+ familyName: l,
1217
+ ascender: e.ascender,
1218
+ descender: e.descender,
1219
+ underlinePosition: e.tables.post?.underlinePosition ?? -100,
1220
+ underlineThickness: e.tables.post?.underlineThickness ?? 50,
1221
+ boundingBox: { yMin: e.descender, xMin: 0, yMax: e.ascender, xMax: i },
1222
+ resolution: i,
1223
+ original_font_information: { fontFamily: l, fontSubfamily: d },
1224
+ cssFontStyle: d.toLowerCase().includes("italic") ? "italic" : "normal",
1225
+ cssFontWeight: d.toLowerCase().includes("bold") ? "bold" : "normal",
1226
+ glyphs: r
1227
+ };
1228
+ }
1229
+ /** 将 opentype 命令拆为闭合轮廓,并输出为 Three 更稳定的“外轮廓 -> 孔洞”顺序。 */
1230
+ static _commandsToTypefaceOutline(e, t) {
1231
+ 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 = [];
1232
+ return o.sort((a, l) => a.index - l.index).forEach((a) => {
1233
+ 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));
1234
+ }), c;
1235
+ }
1236
+ static _createContourEntries(e) {
1237
+ return e.filter((t) => t.segments.length > 0).map((t, r) => {
1238
+ 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);
1239
+ return {
1240
+ contour: t,
1241
+ index: r,
1242
+ depth: o,
1243
+ absArea: Math.abs(g._signedArea(t.points))
1244
+ };
1245
+ });
1246
+ }
1247
+ static _findParentSolid(e, t) {
1248
+ const r = g._samplePoint(e.contour);
1249
+ return t.filter((i) => g._pointInPolygon(r, i.contour.points)).sort((i, o) => i.absArea - o.absArea)[0];
1250
+ }
1251
+ static _appendNormalizedContour(e, t, r, i) {
1252
+ const s = g._signedArea(e.points) < 0 === t ? e.segments : g._reverseSegments(e.segments);
1253
+ g._appendContour(s, r, i);
1254
+ }
1255
+ static _splitContours(e) {
1256
+ const t = [];
1257
+ let r = null, i = null;
1258
+ const o = () => {
1259
+ r && r.segments.length > 0 && t.push(r), r = null, i = null;
1260
+ };
1261
+ return e.forEach((s) => {
1262
+ if (s.type === "M") {
1263
+ o(), i = { x: s.x, y: s.y }, r = { segments: [], points: [i] };
1264
+ return;
1265
+ }
1266
+ if (!r || !i) return;
1267
+ if (s.type === "Z") {
1268
+ o();
1269
+ return;
1270
+ }
1271
+ const c = { x: s.x, y: s.y };
1272
+ 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({
1273
+ type: "C",
1274
+ start: i,
1275
+ end: c,
1276
+ x1: s.x1,
1277
+ y1: s.y1,
1278
+ x2: s.x2,
1279
+ y2: s.y2
1280
+ }), i = c, r.points.push(c);
1281
+ }), o(), t;
1282
+ }
1283
+ static _appendContour(e, t, r) {
1284
+ const i = e[0].start;
1285
+ t.push(`m ${r(i.x)} ${r(i.y)}`), e.forEach((o) => {
1286
+ 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(
1287
+ `b ${r(o.end.x)} ${r(o.end.y)} ${r(o.x1)} ${r(o.y1)} ${r(o.x2)} ${r(o.y2)}`
1288
+ );
1289
+ }), t.push("z");
1290
+ }
1291
+ static _reverseSegments(e) {
1292
+ 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 } : {
1293
+ type: "C",
1294
+ start: t.end,
1295
+ end: t.start,
1296
+ x1: t.x2,
1297
+ y1: t.y2,
1298
+ x2: t.x1,
1299
+ y2: t.y1
1300
+ });
1301
+ }
1302
+ static _signedArea(e) {
1303
+ let t = 0;
1304
+ for (let r = 0, i = e.length - 1; r < e.length; i = r++)
1305
+ t += e[i].x * e[r].y - e[r].x * e[i].y;
1306
+ return t / 2;
1307
+ }
1308
+ static _samplePoint(e) {
1309
+ return e.points[0];
1310
+ }
1311
+ static _pointInPolygon(e, t) {
1312
+ let r = !1;
1313
+ for (let i = 0, o = t.length - 1; i < t.length; o = i++) {
1314
+ const s = t[i], c = t[o];
1315
+ 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);
1316
+ }
1317
+ return r;
1318
+ }
1319
+ }
1320
+ function xe(n) {
1321
+ const e = String(n ?? "").trim().toLowerCase(), t = e.lastIndexOf(".");
1322
+ return t >= 0 ? e.slice(t) : "";
1323
+ }
1324
+ function Lt(n) {
1325
+ return Pt(n.webkitRelativePath || n.name);
1326
+ }
1327
+ function Kt(n) {
1328
+ const e = URL.createObjectURL(n);
1329
+ return {
1330
+ url: e,
1331
+ name: n.name,
1332
+ extension: xe(n.name),
1333
+ revoke: () => URL.revokeObjectURL(e)
1334
+ };
1335
+ }
1336
+ async function Ot(n, e = "package.zip") {
1337
+ const t = new ye();
1338
+ n.forEach((o) => {
1339
+ t.file(Lt(o), o);
1340
+ });
1341
+ const r = await t.generateAsync({ type: "blob" }), i = URL.createObjectURL(r);
1342
+ return {
1343
+ url: i,
1344
+ name: e,
1345
+ extension: xe(e),
1346
+ revoke: () => URL.revokeObjectURL(i)
1347
+ };
1348
+ }
1349
+ function Pt(n) {
1350
+ return String(n).replace(/\\/g, "/").replace(/^\/+/, "").replace(/\/+/g, "/");
1351
+ }
1352
+ export {
1353
+ H as B,
1354
+ zt as C,
1355
+ N as E,
1356
+ g as F,
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
1364
+ };