u-space 0.0.0-alpha.1

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 (96) hide show
  1. package/README.md +21 -0
  2. package/dist/index.cjs +1 -0
  3. package/dist/index.js +1374 -0
  4. package/dist/plugins/atmosphere/Atmosphere.d.ts +9 -0
  5. package/dist/plugins/atmosphere/index.cjs +1 -0
  6. package/dist/plugins/atmosphere/index.d.ts +1 -0
  7. package/dist/plugins/atmosphere/index.js +15 -0
  8. package/dist/plugins/curve-movement/CurveMovement.d.ts +78 -0
  9. package/dist/plugins/curve-movement/CurveMovementCamera.d.ts +8 -0
  10. package/dist/plugins/curve-movement/CurveMovementObject.d.ts +14 -0
  11. package/dist/plugins/curve-movement/index.cjs +1 -0
  12. package/dist/plugins/curve-movement/index.d.ts +3 -0
  13. package/dist/plugins/curve-movement/index.js +153 -0
  14. package/dist/plugins/keyboard-controls/KeyboardControls.d.ts +31 -0
  15. package/dist/plugins/keyboard-controls/index.cjs +1 -0
  16. package/dist/plugins/keyboard-controls/index.d.ts +1 -0
  17. package/dist/plugins/keyboard-controls/index.js +67 -0
  18. package/dist/plugins/minimap/Minimap.d.ts +22 -0
  19. package/dist/plugins/minimap/index.cjs +1 -0
  20. package/dist/plugins/minimap/index.d.ts +1 -0
  21. package/dist/plugins/minimap/index.js +67 -0
  22. package/dist/plugins/tiles/ArcgisTilesRenderer.d.ts +14 -0
  23. package/dist/plugins/tiles/Globe.d.ts +22 -0
  24. package/dist/plugins/tiles/index.cjs +1 -0
  25. package/dist/plugins/tiles/index.d.ts +2 -0
  26. package/dist/plugins/tiles/index.js +179 -0
  27. package/dist/plugins/tiles/plugins/TileMaterialReplacementPlugin.d.ts +11 -0
  28. package/dist/plugins/tiles/plugins/fade/FadeMaterialManager.d.ts +17 -0
  29. package/dist/plugins/tiles/plugins/fade/TilesFadePlugin.d.ts +5 -0
  30. package/dist/plugins/tiles/plugins/fade/wrapFadeNodeMaterial.d.ts +3 -0
  31. package/dist/plugins/tracking-controls/TrackingControls.d.ts +13 -0
  32. package/dist/plugins/tracking-controls/index.cjs +1 -0
  33. package/dist/plugins/tracking-controls/index.d.ts +1 -0
  34. package/dist/plugins/tracking-controls/index.js +23 -0
  35. package/dist/plugins/u-manager/Watermarker.d.ts +12 -0
  36. package/dist/plugins/u-manager/constants.d.ts +5 -0
  37. package/dist/plugins/u-manager/index.cjs +86 -0
  38. package/dist/plugins/u-manager/index.d.ts +6 -0
  39. package/dist/plugins/u-manager/index.js +20877 -0
  40. package/dist/plugins/u-manager/license/decryptUtils.d.ts +5 -0
  41. package/dist/plugins/u-manager/loaders/AnimationsLoader.d.ts +59 -0
  42. package/dist/plugins/u-manager/loaders/BaseFileLoader.d.ts +5 -0
  43. package/dist/plugins/u-manager/loaders/PropertiesLoader.d.ts +12 -0
  44. package/dist/plugins/u-manager/loaders/SceneLoader.d.ts +15 -0
  45. package/dist/plugins/u-manager/loaders/TopologiesLoader.d.ts +10 -0
  46. package/dist/plugins/u-manager/loaders/VisionsLoader.d.ts +26 -0
  47. package/dist/plugins/u-manager/types.d.ts +84 -0
  48. package/dist/src/animations/Tween.d.ts +20 -0
  49. package/dist/src/animations/index.d.ts +1 -0
  50. package/dist/src/effects/MaterialEffects.d.ts +10 -0
  51. package/dist/src/effects/TSLEffects.d.ts +24 -0
  52. package/dist/src/effects/index.d.ts +2 -0
  53. package/dist/src/index.d.ts +9 -0
  54. package/dist/src/interactions/InteractionEvent.d.ts +39 -0
  55. package/dist/src/interactions/InteractionManager.d.ts +55 -0
  56. package/dist/src/interactions/index.d.ts +2 -0
  57. package/dist/src/interfaces/base.d.ts +11 -0
  58. package/dist/src/interfaces/index.d.ts +1 -0
  59. package/dist/src/loaders/ModelLoaderManager.d.ts +40 -0
  60. package/dist/src/loaders/SBMLoader.d.ts +6 -0
  61. package/dist/src/loaders/SBMUtils.d.ts +5 -0
  62. package/dist/src/loaders/SBMXLoader.d.ts +6 -0
  63. package/dist/src/loaders/TextureLoaderManager.d.ts +11 -0
  64. package/dist/src/loaders/index.d.ts +4 -0
  65. package/dist/src/managers/ObjectManager.d.ts +60 -0
  66. package/dist/src/managers/index.d.ts +1 -0
  67. package/dist/src/objects/BaseGroup.d.ts +8 -0
  68. package/dist/src/objects/BaseMesh.d.ts +8 -0
  69. package/dist/src/objects/BaseSprite.d.ts +8 -0
  70. package/dist/src/objects/CircleMesh.d.ts +17 -0
  71. package/dist/src/objects/ExtrudeMesh.d.ts +17 -0
  72. package/dist/src/objects/Model.d.ts +17 -0
  73. package/dist/src/objects/ObjectUtils.d.ts +4 -0
  74. package/dist/src/objects/PlaneMesh.d.ts +17 -0
  75. package/dist/src/objects/Poi.d.ts +38 -0
  76. package/dist/src/objects/ShapeMesh.d.ts +17 -0
  77. package/dist/src/objects/SphereMesh.d.ts +20 -0
  78. package/dist/src/objects/Topology.d.ts +64 -0
  79. package/dist/src/objects/TubeMesh.d.ts +18 -0
  80. package/dist/src/objects/index.d.ts +13 -0
  81. package/dist/src/types.d.ts +1 -0
  82. package/dist/src/viewers/CameraControls.d.ts +19 -0
  83. package/dist/src/viewers/Info.d.ts +18 -0
  84. package/dist/src/viewers/RenderPipeline.d.ts +17 -0
  85. package/dist/src/viewers/RoomEnvironment.d.ts +11 -0
  86. package/dist/src/viewers/Viewer.d.ts +59 -0
  87. package/dist/src/viewers/ViewerHelper.d.ts +12 -0
  88. package/dist/src/viewers/index.d.ts +3 -0
  89. package/docs/api-interactions.md +64 -0
  90. package/docs/api-managers.md +54 -0
  91. package/docs/api-objects.md +65 -0
  92. package/docs/api-plugins.md +103 -0
  93. package/docs/api-viewer.md +84 -0
  94. package/docs/examples-guide.md +48 -0
  95. package/docs/getting-started.md +126 -0
  96. package/package.json +60 -0
package/dist/index.js ADDED
@@ -0,0 +1,1374 @@
1
+ import { Raycaster as ue, Vector2 as P, RenderPipeline as Be, Sphere as me, Box3 as ge, Spherical as C, Matrix4 as Re, Quaternion as _e, Vector4 as Ae, Vector3 as we, MathUtils as Ne, PMREMGenerator as Ue, OrthographicCamera as F, TimestampQuery as De, Cache as je, EventDispatcher as ke, Timer as Ge, PerspectiveCamera as W, WebGPURenderer as Fe, PCFShadowMap as He, AgXToneMapping as ze, Scene as $e, Color as J, MeshStandardNodeMaterial as I, Loader as We, LoaderUtils as L, FileLoader as fe, TextureLoader as ye, Group as z, SRGBColorSpace as ve, RepeatWrapping as se, BufferGeometry as Qe, BufferAttribute as ne, Mesh as j, FrontSide as Ke, BackSide as Xe, DoubleSide as qe, REVISION as ie, CubeTextureLoader as Ye, EquirectangularReflectionMapping as Je, Sprite as Ze, SphereGeometry as Ve, TubeGeometry as et, LineCurve3 as tt, CatmullRomCurve3 as st, SpriteNodeMaterial as nt, CanvasTexture as it, ShapeGeometry as rt, Shape as be, ExtrudeGeometry as at, PlaneGeometry as ot, CircleGeometry as ct } from "three/webgpu";
2
+ import { pass as q, blendColor as ht, color as A, uv as re, time as Q, pow as K, sin as ae, mix as X, mx_noise_float as oe, Fn as Te, userData as D, materialColor as ce, select as Y, materialOpacity as lt, vec3 as dt } from "three/tsl";
3
+ import Ce from "camera-controls";
4
+ import { RoomEnvironment as pt } from "three/addons/environments/RoomEnvironment.js";
5
+ import { ViewHelper as ut } from "three/addons/helpers/ViewHelper.js";
6
+ import { GLTFLoader as Me } from "three/addons/loaders/GLTFLoader.js";
7
+ import { FBXLoader as mt } from "three/addons/loaders/FBXLoader.js";
8
+ import { OBJLoader as gt } from "three/addons/loaders/OBJLoader.js";
9
+ import { STLLoader as wt } from "three/addons/loaders/STLLoader.js";
10
+ import { DRACOLoader as ft } from "three/addons/loaders/DRACOLoader.js";
11
+ import { KTX2Loader as yt } from "three/addons/loaders/KTX2Loader.js";
12
+ import { MeshoptDecoder as he } from "three/addons/libs/meshopt_decoder.module.js";
13
+ import { HDRLoader as vt } from "three/addons/loaders/HDRLoader.js";
14
+ import { clone as bt } from "three/addons/utils/SkeletonUtils.js";
15
+ import { Color as N } from "three";
16
+ import { Easing as d, Tween as Tt } from "three/addons/libs/tween.module.js";
17
+ class Ct {
18
+ /** The type of event (e.g., 'click', 'pointerdown'). */
19
+ type;
20
+ /** The original 3D object that triggered the event. */
21
+ target;
22
+ /** The current 3D object during the bubbling phase. */
23
+ currentTarget;
24
+ /** The intersection data from raycasting, or null if not applicable. */
25
+ intersect;
26
+ /** The original DOM event, or undefined if not applicable. */
27
+ originalEvent;
28
+ _propagationStopped = !1;
29
+ constructor(e) {
30
+ this.type = e.type, this.target = e.target, this.currentTarget = e.target, this.intersect = e.intersect, this.originalEvent = e.originalEvent;
31
+ }
32
+ /**
33
+ * Stops the event from bubbling up the parent chain.
34
+ */
35
+ stopPropagation() {
36
+ this._propagationStopped = !0;
37
+ }
38
+ /**
39
+ * Returns true if `stopPropagation()` has been called.
40
+ */
41
+ get propagationStopped() {
42
+ return this._propagationStopped;
43
+ }
44
+ }
45
+ class Mt {
46
+ domElement;
47
+ scene;
48
+ camera;
49
+ raycaster = new ue();
50
+ pointer = new P();
51
+ hoveredObject = null;
52
+ pointerDownTime = 0;
53
+ pointerDownPos = new P();
54
+ clickTimer = null;
55
+ longPressThreshold = 500;
56
+ moveThreshold = 0.01;
57
+ /**
58
+ * The objects to check for intersections.
59
+ * If not set, it defaults to the children of the scene.
60
+ */
61
+ targetObjects = null;
62
+ /**
63
+ * Whether to enable pointer move events (pointermove, pointerenter, pointerleave).
64
+ * Disabled by default for performance optimization.
65
+ */
66
+ pointerMoveEventsEnabled = !1;
67
+ constructor(e, t, s) {
68
+ this.domElement = e, this.scene = t, this.camera = s, this.raycaster.params.Points.threshold = 0.1, this.raycaster.params.Line.threshold = 0.1, this._bindEvents();
69
+ }
70
+ /**
71
+ * Updates the camera reference (useful when switching cameras).
72
+ */
73
+ setCamera(e) {
74
+ this.camera = e;
75
+ }
76
+ _bindEvents() {
77
+ this.domElement.addEventListener("click", this._onClick), this.domElement.addEventListener("dblclick", this._onDblClick), this.domElement.addEventListener("contextmenu", this._onContextMenu), this.domElement.addEventListener("pointerdown", this._onPointerDown), this.domElement.addEventListener("pointerup", this._onPointerUp), this.domElement.addEventListener("pointermove", this._onPointerMove);
78
+ }
79
+ _updatePointer(e) {
80
+ const t = this.domElement.getBoundingClientRect();
81
+ this.pointer.x = (e.clientX - t.left) / t.width * 2 - 1, this.pointer.y = -((e.clientY - t.top) / t.height) * 2 + 1;
82
+ }
83
+ _getIntersects() {
84
+ this.raycaster.setFromCamera(this.pointer, this.camera);
85
+ const e = this.targetObjects || this.scene.children;
86
+ return this.raycaster.intersectObjects(e, !0);
87
+ }
88
+ /**
89
+ * Dispatches an event to the target object and bubbles up the parent chain.
90
+ */
91
+ _dispatchToTarget(e, t, s, n) {
92
+ const i = new Ct({
93
+ type: e,
94
+ target: t,
95
+ intersect: s,
96
+ originalEvent: n
97
+ });
98
+ let a = t;
99
+ for (; a && !i.propagationStopped; )
100
+ i.currentTarget = a, a.dispatchEvent({ type: e, event: i }), a = a.parent;
101
+ }
102
+ /**
103
+ * Handles a DOM event by raycasting and dispatching to the first intersected object.
104
+ */
105
+ _handleEvent(e, t) {
106
+ this._updatePointer(t);
107
+ const s = this._getIntersects();
108
+ if (s.length === 0) return;
109
+ const n = s[0];
110
+ this._dispatchToTarget(e, n.object, n, t);
111
+ }
112
+ _onClick = (e) => {
113
+ const t = Date.now() - this.pointerDownTime, s = this.pointer.distanceTo(this.pointerDownPos);
114
+ if (!(t > this.longPressThreshold || s > this.moveThreshold)) {
115
+ if (this.clickTimer) {
116
+ clearTimeout(this.clickTimer), this.clickTimer = null;
117
+ return;
118
+ }
119
+ this.clickTimer = setTimeout(() => {
120
+ this._handleEvent("click", e), this.clickTimer = null;
121
+ }, 200);
122
+ }
123
+ };
124
+ _onDblClick = (e) => {
125
+ this.clickTimer && (clearTimeout(this.clickTimer), this.clickTimer = null), this._handleEvent("dblclick", e);
126
+ };
127
+ _onContextMenu = (e) => {
128
+ e.preventDefault(), this._handleEvent("contextmenu", e);
129
+ };
130
+ _onPointerDown = (e) => {
131
+ this.pointerDownTime = Date.now(), this._updatePointer(e), this.pointerDownPos.copy(this.pointer), this._handleEvent("pointerdown", e);
132
+ };
133
+ _onPointerUp = (e) => this._handleEvent("pointerup", e);
134
+ _onPointerMove = (e) => {
135
+ if (!this.pointerMoveEventsEnabled) return;
136
+ this._updatePointer(e);
137
+ const t = this._getIntersects(), s = t.length > 0 ? t[0].object : null, n = t.length > 0 ? t[0] : null;
138
+ this.hoveredObject !== s && (this.hoveredObject && this._dispatchToTarget("pointerleave", this.hoveredObject, null, e), this.hoveredObject = s, s && n && this._dispatchToTarget("pointerenter", s, n, e)), s && n && this._dispatchToTarget("pointermove", s, n, e);
139
+ };
140
+ /**
141
+ * Cleans up event listeners.
142
+ */
143
+ dispose() {
144
+ this.domElement.removeEventListener("click", this._onClick), this.domElement.removeEventListener("dblclick", this._onDblClick), this.domElement.removeEventListener("contextmenu", this._onContextMenu), this.domElement.removeEventListener("pointerdown", this._onPointerDown), this.domElement.removeEventListener("pointerup", this._onPointerUp), this.domElement.removeEventListener("pointermove", this._onPointerMove), this.hoveredObject = null;
145
+ }
146
+ }
147
+ class xt {
148
+ idMap = /* @__PURE__ */ new Map();
149
+ nameMap = /* @__PURE__ */ new Map();
150
+ typeMap = /* @__PURE__ */ new Map();
151
+ objectIds = /* @__PURE__ */ new Map();
152
+ allObjects = /* @__PURE__ */ new Set();
153
+ /**
154
+ * Add an object with a custom id.
155
+ * One object can have multiple ids.
156
+ */
157
+ add(e, t) {
158
+ if (this.idMap.has(e)) {
159
+ console.warn(`ObjectManager: Object with id ${e} already exists.`);
160
+ return;
161
+ }
162
+ this.idMap.set(e, t), this.allObjects.add(t), this.objectIds.has(t) || this.objectIds.set(t, /* @__PURE__ */ new Set()), this.objectIds.get(t).add(e), t.name && (this.nameMap.has(t.name) || this.nameMap.set(t.name, /* @__PURE__ */ new Set()), this.nameMap.get(t.name).add(t)), t.type && (this.typeMap.has(t.type) || this.typeMap.set(t.type, /* @__PURE__ */ new Set()), this.typeMap.get(t.type).add(t));
163
+ }
164
+ /**
165
+ * Get an object by its custom id.
166
+ */
167
+ getById(e) {
168
+ return this.idMap.get(e);
169
+ }
170
+ /**
171
+ * Get all objects with a given name.
172
+ */
173
+ getByName(e) {
174
+ return this.nameMap.get(e) || /* @__PURE__ */ new Set();
175
+ }
176
+ /**
177
+ * Get all objects with a given type.
178
+ */
179
+ getByType(e) {
180
+ return this.typeMap.get(e) || /* @__PURE__ */ new Set();
181
+ }
182
+ /**
183
+ * Get all ids associated with an object.
184
+ */
185
+ getObjectIds(e) {
186
+ return this.objectIds.get(e) || /* @__PURE__ */ new Set();
187
+ }
188
+ /**
189
+ * Remove an object and all its associated ids.
190
+ */
191
+ remove(e) {
192
+ const t = this.objectIds.get(e);
193
+ if (t) {
194
+ for (const s of t)
195
+ this.idMap.delete(s);
196
+ this.objectIds.delete(e);
197
+ }
198
+ if (e.name && this.nameMap.has(e.name)) {
199
+ const s = this.nameMap.get(e.name);
200
+ s.delete(e), s.size === 0 && this.nameMap.delete(e.name);
201
+ }
202
+ if (e.type && this.typeMap.has(e.type)) {
203
+ const s = this.typeMap.get(e.type);
204
+ s.delete(e), s.size === 0 && this.typeMap.delete(e.type);
205
+ }
206
+ this.allObjects.delete(e);
207
+ }
208
+ /**
209
+ * Remove an object by its id.
210
+ */
211
+ removeById(e) {
212
+ const t = this.idMap.get(e);
213
+ t && this.remove(t);
214
+ }
215
+ /**
216
+ * Remove all objects with a given name.
217
+ */
218
+ removeByName(e) {
219
+ const t = this.getByName(e);
220
+ for (const s of t)
221
+ this.remove(s);
222
+ }
223
+ /**
224
+ * Remove all objects with a given type.
225
+ */
226
+ removeByType(e) {
227
+ const t = this.getByType(e);
228
+ for (const s of t)
229
+ this.remove(s);
230
+ }
231
+ /**
232
+ * Clear all cached objects.
233
+ */
234
+ clear() {
235
+ this.idMap.clear(), this.nameMap.clear(), this.typeMap.clear(), this.objectIds.clear(), this.allObjects.clear();
236
+ }
237
+ /**
238
+ * Get all cached objects as a Set.
239
+ */
240
+ getAll() {
241
+ return this.allObjects;
242
+ }
243
+ /**
244
+ * Get the number of unique cached objects.
245
+ */
246
+ get size() {
247
+ return this.allObjects.size;
248
+ }
249
+ }
250
+ class Et extends Be {
251
+ scene;
252
+ camera;
253
+ currentOutputNode;
254
+ needsUpdateOutputNode;
255
+ #e;
256
+ constructor(...e) {
257
+ const [t, s, n] = e;
258
+ super(t), this.scene = s, this.camera = n, this.currentOutputNode = q(s, n), this.needsUpdateOutputNode = !0, this.#e = /* @__PURE__ */ new Set();
259
+ }
260
+ addOverlayPass(e) {
261
+ this.#e.add(e), this.needsUpdateOutputNode = !0;
262
+ }
263
+ removeOverlayPass(e) {
264
+ this.#e.delete(e), this.needsUpdateOutputNode = !0;
265
+ }
266
+ setCamera(e) {
267
+ this.camera = e, this.needsUpdateOutputNode = !0;
268
+ }
269
+ setCurrentOutputNode(e) {
270
+ this.currentOutputNode.dispose(), this.currentOutputNode = e, this.needsUpdateOutputNode = !0;
271
+ }
272
+ resetCurrentOutputNode() {
273
+ this.currentOutputNode.dispose(), this.currentOutputNode = q(this.scene, this.camera), this.needsUpdateOutputNode = !0;
274
+ }
275
+ #t() {
276
+ let e = this.currentOutputNode;
277
+ this.#e.size > 0 && this.#e.forEach((t) => {
278
+ e = ht(e, t);
279
+ }), this.outputNode = e, this.needsUpdate = !0;
280
+ }
281
+ render() {
282
+ this.needsUpdateOutputNode && (this.#t(), this.needsUpdateOutputNode = !1), super.render();
283
+ }
284
+ }
285
+ const Ot = {
286
+ Vector2: P,
287
+ Vector3: we,
288
+ Vector4: Ae,
289
+ Quaternion: _e,
290
+ Matrix4: Re,
291
+ Spherical: C,
292
+ Box3: ge,
293
+ Sphere: me,
294
+ Raycaster: ue
295
+ };
296
+ Ce.install({ THREE: Ot });
297
+ class Pt extends Ce {
298
+ constructor(...e) {
299
+ super(...e), this.minDistance = 0.2, this.smoothTime = 0.2, this.dollySpeed = 0.2;
300
+ }
301
+ /**
302
+ * Set absolute angle for azimuth to avoid spinning
303
+ */
304
+ absoluteRotations() {
305
+ this.azimuthAngle = St(this.azimuthAngle, 0);
306
+ }
307
+ async flyToBox(e, t = {}) {
308
+ if (e.isEmpty())
309
+ return console.warn("CameraControls.flyToBox: The provided Box3 is empty."), !1;
310
+ this.absoluteRotations();
311
+ const { viewpoint: s = "frontTop", enableTransition: n = !0, padding: i = 0.1, cover: a = !1 } = t, c = [];
312
+ if (s !== "current") {
313
+ const r = le[s.toUpperCase()] ?? le.FRONTTOP, h = r.theta, l = r.phi;
314
+ c.push(
315
+ this.fitToBox(e, n, {
316
+ paddingLeft: i,
317
+ paddingRight: i,
318
+ paddingTop: i,
319
+ paddingBottom: i,
320
+ cover: a
321
+ })
322
+ ), c.push(this.rotateTo(h, l, n));
323
+ } else {
324
+ const r = new me();
325
+ e.getBoundingSphere(r), r.radius += i, c.push(this.fitToSphere(r, n));
326
+ }
327
+ return await Promise.all(c), !0;
328
+ }
329
+ async flyToObject(e, t = {}) {
330
+ const s = new ge().setFromObject(e);
331
+ return this.flyToBox(s, t);
332
+ }
333
+ }
334
+ const le = {
335
+ LEFT: new C(0, Math.PI / 2, -Math.PI / 2),
336
+ RIGHT: new C(0, Math.PI / 2, Math.PI / 2),
337
+ FRONT: new C(0, Math.PI / 2, 0),
338
+ BACK: new C(0, Math.PI / 2, Math.PI),
339
+ TOP: new C(0, 0, 0),
340
+ BOTTOM: new C(0, Math.PI, 0),
341
+ FRONTTOP: new C(0, Math.PI / 4, 0),
342
+ BACKTOP: new C(0, Math.PI / 4, Math.PI),
343
+ LEFTTOP: new C(0, Math.PI / 4, -Math.PI / 2),
344
+ RIGHTTOP: new C(0, Math.PI / 4, Math.PI / 2),
345
+ LEFTFRONTTOP: new C(0, Math.PI / 4, -Math.PI / 4),
346
+ RIGHTFRONTTOP: new C(0, Math.PI / 4, Math.PI / 4),
347
+ LEFTBACKTOP: new C(0, Math.PI / 4, -Math.PI / 4 * 3),
348
+ RIGHTBACKTOP: new C(0, Math.PI / 4, Math.PI / 4 * 3)
349
+ };
350
+ function St(o, e) {
351
+ const t = o - e;
352
+ return Ne.euclideanModulo(t + Math.PI, Math.PI * 2) - Math.PI;
353
+ }
354
+ class Lt {
355
+ environment = new pt();
356
+ renderer;
357
+ pmremGenerator;
358
+ envMap = null;
359
+ constructor(e) {
360
+ this.renderer = e, this.pmremGenerator = new Ue(e);
361
+ }
362
+ update() {
363
+ this.envMap || (this.envMap = this.pmremGenerator.fromScene(this.environment).texture);
364
+ }
365
+ dispose() {
366
+ this.pmremGenerator.dispose(), this.envMap?.dispose();
367
+ }
368
+ }
369
+ const G = 128;
370
+ class It extends ut {
371
+ viewer;
372
+ overlayPass;
373
+ constructor(e) {
374
+ super(e.camera, e.el), this.viewer = e;
375
+ const t = new F(-2, 2, 2, -2, 0, 4);
376
+ t.position.set(0, 0, 2), this.overlayPass = q(this, t), this.setLabels("x", "y", "z");
377
+ }
378
+ _update = () => {
379
+ this.quaternion.copy(this.viewer.camera.quaternion).invert();
380
+ const e = this.location;
381
+ let t, s;
382
+ e.left !== null ? t = e.left : t = this.viewer.el.offsetWidth - G - e.right, e.top !== null ? s = e.top : s = this.viewer.el.offsetHeight - G - e.bottom, this.overlayPass.setViewport(t, s, G, G);
383
+ };
384
+ enable() {
385
+ return this.viewer.renderPipeline.addOverlayPass(this.overlayPass), this.viewer.addEventListener("beforeRender", this._update), this.viewer.render(), this;
386
+ }
387
+ disable() {
388
+ return this.viewer.renderPipeline.removeOverlayPass(this.overlayPass), this.viewer.removeEventListener("beforeRender", this._update), this.viewer.render(), this;
389
+ }
390
+ }
391
+ class Bt {
392
+ el;
393
+ renderer;
394
+ container;
395
+ drawCallsText;
396
+ frameCallsText;
397
+ trianglesText;
398
+ pointsText;
399
+ linesText;
400
+ timestampText;
401
+ _enabled = !1;
402
+ constructor(e, t) {
403
+ this.el = e, this.renderer = t;
404
+ const s = document.createElement("div");
405
+ s.style.position = "absolute", s.style.left = "12px", s.style.bottom = "12px", s.style.fontSize = "12px", s.style.color = "#fff", s.style.pointerEvents = "none", this.container = s;
406
+ function n(a, c = !0) {
407
+ const r = document.createElement("span");
408
+ return c && (r.style.marginLeft = "6px"), r.innerText = a, r;
409
+ }
410
+ function i() {
411
+ return document.createElement("br");
412
+ }
413
+ this.drawCallsText = n("0"), this.frameCallsText = n("0"), this.trianglesText = n("0"), this.linesText = n("0"), this.pointsText = n("0"), this.timestampText = n("0"), this.container.appendChild(n("draw calls", !1)), this.container.appendChild(this.drawCallsText), this.container.appendChild(i()), this.container.appendChild(n("frame calls", !1)), this.container.appendChild(this.frameCallsText), this.container.appendChild(i()), this.container.appendChild(n("triangles", !1)), this.container.appendChild(this.trianglesText), this.container.appendChild(i()), this.container.appendChild(n("points", !1)), this.container.appendChild(this.pointsText), this.container.appendChild(i()), this.container.appendChild(n("lines", !1)), this.container.appendChild(this.linesText), this.container.appendChild(i()), this.container.appendChild(n("timestamp", !1)), this.container.appendChild(this.timestampText), this.container.appendChild(i());
414
+ }
415
+ update() {
416
+ if (this._enabled) {
417
+ const { render: e } = this.renderer.info;
418
+ this.drawCallsText.innerText = e.drawCalls.toString(), this.frameCallsText.innerText = e.frameCalls.toString(), this.trianglesText.innerText = e.triangles.toString(), this.pointsText.innerText = e.points.toString(), this.linesText.innerText = e.lines.toString(), this.renderer.resolveTimestampsAsync(De.RENDER).then((t) => {
419
+ this.timestampText.innerText = t?.toFixed(2) ?? "0";
420
+ });
421
+ }
422
+ }
423
+ enable() {
424
+ this._enabled = !0, this.el.appendChild(this.container);
425
+ }
426
+ disable() {
427
+ this._enabled = !1, this.container.remove();
428
+ }
429
+ dispose() {
430
+ this.disable();
431
+ }
432
+ }
433
+ je.enabled = !0;
434
+ class ys extends ke {
435
+ el;
436
+ renderer;
437
+ scene;
438
+ camera;
439
+ info;
440
+ controls;
441
+ renderPipeline;
442
+ timer;
443
+ roomEnvironment;
444
+ interactionManager;
445
+ objectManager;
446
+ viewerHelper;
447
+ frameCount = 1;
448
+ frameloop = "demand";
449
+ constructor({ el: e, rendererOptions: t }) {
450
+ super(), this.el = e, this.renderer = this._initRenderer(t), this.scene = this.createScene(), this.camera = this.createPerspectiveCamera(), this.info = new Bt(this.el, this.renderer), this.controls = new Pt(this.camera, this.renderer.domElement), this.renderPipeline = new Et(this.renderer, this.scene, this.camera), this.timer = new Ge(), this.roomEnvironment = new Lt(this.renderer), this.interactionManager = new Mt(this.renderer.domElement, this.scene, this.camera), this.objectManager = new xt(), this.viewerHelper = new It(this), window.addEventListener("resize", this.onWindowResize);
451
+ }
452
+ onWindowResize = () => {
453
+ const e = this.el.clientWidth, t = this.el.clientHeight;
454
+ this.camera instanceof W ? (this.camera.aspect = e / t, this.camera.updateProjectionMatrix()) : this.camera instanceof F && (this.camera.left = -e / 2, this.camera.right = e / 2, this.camera.top = t / 2, this.camera.bottom = -t / 2, this.camera.updateProjectionMatrix()), this.renderer.setSize(e, t), this.render();
455
+ };
456
+ async init() {
457
+ await this.renderer.init(), this.roomEnvironment.update(), this.scene.environment = this.roomEnvironment.envMap;
458
+ }
459
+ setCamera(e) {
460
+ this.camera = e, this.controls.camera = e, this.interactionManager.setCamera(e), this.renderPipeline.setCamera(e), this.onWindowResize(), this.dispatchEvent({ type: "cameraChange", camera: e });
461
+ }
462
+ setCameraByType(e) {
463
+ e === "perspective" && !(this.camera instanceof W) ? this.setCamera(this.createPerspectiveCamera()) : e === "orthographic" && !(this.camera instanceof F) && this.setCamera(this.createOrthographicCamera());
464
+ }
465
+ render(e = 1) {
466
+ return this.frameCount += e, new Promise((t) => {
467
+ const s = () => {
468
+ this.removeEventListener("afterRender", s), t();
469
+ };
470
+ this.addEventListener("afterRender", s);
471
+ });
472
+ }
473
+ animate = (e) => {
474
+ this.timer.update(e), this.dispatchEvent({ type: "beforeControlsUpdate", time: e });
475
+ let t = this.controls.update(this.timer.getDelta());
476
+ this.dispatchEvent({ type: "afterControlsUpdate", time: e }), this.frameCount > 0 && (this.frameCount--, t = !0), this.frameloop === "always" && (t = !0), t && (this.dispatchEvent({ type: "beforeRender", time: e }), this.renderer.info.reset(), this.renderPipeline.render(), this.info.update(), this.dispatchEvent({ type: "afterRender", time: e }));
477
+ };
478
+ _initRenderer(e) {
479
+ const t = new Fe({
480
+ logarithmicDepthBuffer: !0,
481
+ antialias: !1,
482
+ depth: !1,
483
+ trackTimestamp: !0,
484
+ ...e
485
+ });
486
+ return t.setSize(this.el.clientWidth, this.el.clientHeight), t.shadowMap.enabled = !0, t.shadowMap.type = He, t.toneMapping = ze, t.toneMappingExposure = 1, t.info.autoReset = !1, t.setPixelRatio(window.devicePixelRatio), t.setAnimationLoop(this.animate), this.el.appendChild(t.domElement), t;
487
+ }
488
+ createScene() {
489
+ const e = new $e();
490
+ return e.background = new J(0), e;
491
+ }
492
+ createPerspectiveCamera() {
493
+ const e = new W(50, this.el.clientWidth / this.el.clientHeight, 0.1, 1e5);
494
+ return e.position.setScalar(5), e;
495
+ }
496
+ createOrthographicCamera() {
497
+ const e = new F(
498
+ -this.el.clientWidth / 2,
499
+ this.el.clientWidth / 2,
500
+ this.el.clientHeight / 2,
501
+ -this.el.clientHeight / 2,
502
+ 0.1,
503
+ 1e5
504
+ );
505
+ return e.position.setScalar(5), e;
506
+ }
507
+ dispose() {
508
+ this.el.removeChild(this.renderer.domElement), window.removeEventListener("resize", this.onWindowResize), this.info.dispose(), this.interactionManager.dispose(), this.roomEnvironment.dispose(), this.renderPipeline.dispose(), this.renderer.dispose();
509
+ }
510
+ }
511
+ class Rt extends Me {
512
+ constructor(e) {
513
+ super(e);
514
+ }
515
+ parse(e, t, s, n) {
516
+ if (_t(e.slice(0, 8)) === "SBMG----") {
517
+ const a = At(e.slice(8));
518
+ return super.parse(a, t, s, n);
519
+ } else
520
+ return super.parse(e, t, s, n);
521
+ }
522
+ }
523
+ function _t(o) {
524
+ return new TextDecoder().decode(new Uint8Array(o));
525
+ }
526
+ function At(o) {
527
+ const e = new DataView(o);
528
+ for (let t = 0; t < e.byteLength; t++) {
529
+ const s = e.getUint8(t), n = (s >> 4 & 15) + (s << 4 & 240);
530
+ e.setUint8(t, n);
531
+ }
532
+ return e.buffer;
533
+ }
534
+ const Nt = 8, Ut = 130, de = 66, Dt = "SBK-----", jt = "SBM-----", xe = new TextDecoder(), kt = new TextEncoder();
535
+ function Gt(o) {
536
+ let e = Nt;
537
+ const t = new Uint8Array(o, 0, e);
538
+ if (xe.decode(t) !== Dt)
539
+ return o;
540
+ e += Ut;
541
+ const n = new Uint8Array(o, 0, e);
542
+ if (n[40] === 1) {
543
+ const a = kt.encode(jt), c = new Uint8Array([n[41]]), r = Ft(n), h = Ht(r);
544
+ let l = de % h.length;
545
+ const u = e + de, f = new Uint8Array(o, u), p = new Uint8Array(f.length);
546
+ for (let w = 0; w < f.length; w++)
547
+ p[w] = f[w] ^ h[l], l = (l + 1) % h.length;
548
+ const g = new Uint8Array(a.length + c.length + p.length);
549
+ return g.set(a), g.set(c, a.length), g.set(p, a.length + c.length), g.buffer;
550
+ }
551
+ }
552
+ function Ft(o) {
553
+ const e = new Uint8Array(128);
554
+ return e.set(o.slice(42, 74), 0), e.set(o.slice(74, 138), 32), e.set(o.slice(8, 40), 96), e;
555
+ }
556
+ function Ht(o) {
557
+ const e = new Uint8Array(64);
558
+ return e.set(o.slice(0, 8), 0), e.set(o.slice(24, 32), 8), e.set(o.slice(40, 56), 16), e.set(o.slice(64, 88), 32), e.set(o.slice(96, 104), 56), e;
559
+ }
560
+ const zt = (o, e, t) => {
561
+ const s = o.buffer.slice(t, t + e);
562
+ let n = xe.decode(s);
563
+ return n = n.replace("\\", "/"), n.startsWith("Maps/") || (n = `Maps/${n}`), n;
564
+ }, $t = (o, e, t) => {
565
+ const [s, n, i, a, c] = e, r = t || a < 1;
566
+ return new I({
567
+ name: o,
568
+ color: new J(s, n, i),
569
+ opacity: a,
570
+ transparent: r,
571
+ alphaTest: 0.01,
572
+ side: c
573
+ });
574
+ }, Wt = (o) => o?.toLowerCase().endsWith(".png") ?? !1;
575
+ class Qt {
576
+ data;
577
+ options;
578
+ textureLoader;
579
+ littleEndian = !0;
580
+ materials = /* @__PURE__ */ new Map();
581
+ constructor(e, t) {
582
+ this.data = e, this.options = t, this.textureLoader = new ye(t.manager), this.textureLoader.setCrossOrigin(t.crossOrigin), this.textureLoader.setRequestHeader(t.requestHeader);
583
+ }
584
+ parse(e, t) {
585
+ let s = this.data;
586
+ const n = Gt(this.data);
587
+ n && (s = n);
588
+ const i = new DataView(s);
589
+ let a = 8;
590
+ const c = i.getUint8(a);
591
+ a += 1, c === 1 ? this._parseV2(i, a, e) : c === 2 ? this._parseV2(i, a, e) : c === 3 ? this._parseV3(i, a, e) : t?.(new Error(`SBMLoader: Unsupported SBM version: ${c}`));
592
+ }
593
+ _parseV2(e, t, s) {
594
+ const n = new z(), i = e.getUint16(t, this.littleEndian);
595
+ t += 2;
596
+ const a = e.getUint16(t, this.littleEndian);
597
+ t += 2;
598
+ for (let c = 0; c < i; ++c) {
599
+ const r = e.getUint16(t, this.littleEndian).toString();
600
+ t += 2, t += 4, t += 4, t += 4, t += 4;
601
+ const h = e.getFloat32(t, this.littleEndian);
602
+ t += 4;
603
+ const l = e.getFloat32(t, this.littleEndian);
604
+ t += 4;
605
+ const u = e.getFloat32(t, this.littleEndian);
606
+ t += 4;
607
+ const f = e.getFloat32(t, this.littleEndian);
608
+ t += 4, t += 4, t += 4, t += 4, t += 4;
609
+ let p = e.getUint8(t);
610
+ t += 1, p === 0 ? p = Ke : p === 1 ? p = Xe : p === 2 && (p = qe);
611
+ const g = e.getUint16(t, this.littleEndian);
612
+ t += 2;
613
+ const w = g > 0 ? zt(e, g, t) : "";
614
+ if (t += g, !this.materials.has(r)) {
615
+ const v = $t(r, [h, l, u, f, p], Wt(w));
616
+ this.materials.set(r, v), w && this.options.path && this.textureLoader.load(L.resolveURL(w, this.options.path), (b) => {
617
+ b.colorSpace = ve, b.wrapS = se, b.wrapT = se, b.flipY = !1, b.anisotropy = 16, v.map = b;
618
+ });
619
+ }
620
+ }
621
+ for (let c = 0; c < a; ++c) {
622
+ const r = e.getUint16(t, this.littleEndian).toString();
623
+ t += 2;
624
+ const h = e.getUint16(t, this.littleEndian).toString();
625
+ t += 2;
626
+ const l = [], u = [], f = [], p = [], g = e.getUint16(t, this.littleEndian);
627
+ if (t += 2, g > 0)
628
+ for (let m = 0; m < g; m++) {
629
+ const y = new we();
630
+ y.setX(e.getFloat32(t, this.littleEndian)), t += 4, y.setY(e.getFloat32(t, this.littleEndian)), t += 4, y.setZ(e.getFloat32(t, this.littleEndian)), t += 4, l.push(y);
631
+ }
632
+ const w = e.getUint16(t, this.littleEndian);
633
+ if (t += 2, w > 0)
634
+ for (let m = 0; m < w; m++)
635
+ t += 4, t += 4, t += 4;
636
+ const T = e.getUint16(t, this.littleEndian);
637
+ if (t += 2, T > 0)
638
+ for (let m = 0; m < T; m++) {
639
+ const y = new P();
640
+ y.setX(e.getFloat32(t, this.littleEndian)), t += 4, y.setY(e.getFloat32(t, this.littleEndian)), t += 4, u.push(y);
641
+ }
642
+ const v = e.getUint16(t, this.littleEndian);
643
+ if (t += 2, v > 0)
644
+ for (let m = 0; m < v; m++) {
645
+ const y = e.getUint16(t, this.littleEndian);
646
+ t += 2;
647
+ const B = e.getUint16(t, this.littleEndian);
648
+ t += 2;
649
+ const _ = e.getUint16(t, this.littleEndian);
650
+ t += 2;
651
+ const O = [y, B, _];
652
+ f.push(O), u.length > 0 && p.push([u[O[0]], u[O[1]], u[O[2]]]);
653
+ }
654
+ const b = [], M = [];
655
+ for (let m = 0; m < f.length; m++) {
656
+ const y = f[m], B = l[y[0]], _ = l[y[1]], O = l[y[2]];
657
+ b.push(...B.toArray(), ..._.toArray(), ...O.toArray());
658
+ let V = new P(), ee = new P(), te = new P();
659
+ const k = p[m];
660
+ k !== void 0 && (V = k[0], ee = k[1], te = k[2]), M.push(...V.toArray(), ...ee.toArray(), ...te.toArray());
661
+ }
662
+ const x = new Float32Array(b), E = new Float32Array(M), S = new Qe();
663
+ if (x.length > 0 && S.setAttribute("position", new ne(x, 3)), E.length > 0 && S.setAttribute("uv", new ne(E, 2)), S.computeVertexNormals(), this.materials.has(h)) {
664
+ const m = new j(S, this.materials.get(h));
665
+ m.name = r, m.castShadow = !0, m.receiveShadow = !0, n.add(m);
666
+ }
667
+ }
668
+ s(n);
669
+ }
670
+ _parseV3(e, t, s) {
671
+ const n = new z();
672
+ console.warn("SBMLoader: SBM version 3 is not supported yet."), s(n);
673
+ }
674
+ }
675
+ class Kt extends We {
676
+ load(e, t, s, n) {
677
+ let i;
678
+ if (this.resourcePath !== "")
679
+ i = this.resourcePath;
680
+ else if (this.path !== "") {
681
+ const r = L.extractUrlBase(e);
682
+ i = L.resolveURL(r, this.path);
683
+ } else
684
+ i = L.extractUrlBase(e);
685
+ this.manager.itemStart(e);
686
+ const a = (r) => {
687
+ n ? n(r) : console.error(r), this.manager.itemError(e), this.manager.itemEnd(e);
688
+ }, c = new fe(this.manager);
689
+ c.setPath(this.path), c.setResponseType("arraybuffer"), c.setRequestHeader(this.requestHeader), c.setWithCredentials(this.withCredentials), c.load(
690
+ e,
691
+ (r) => {
692
+ try {
693
+ this.parse(
694
+ r,
695
+ i,
696
+ (h) => {
697
+ t(h), this.manager.itemEnd(e);
698
+ },
699
+ a
700
+ );
701
+ } catch (h) {
702
+ a(h);
703
+ }
704
+ },
705
+ s,
706
+ a
707
+ );
708
+ }
709
+ parse(e, t, s, n) {
710
+ const i = new TextDecoder().decode(e.slice(0, 8));
711
+ if (i !== "SBK-----" && i !== "SBM-----") {
712
+ n?.(new Error(`SBMLoader: Invalid SBM format: ${i}`));
713
+ return;
714
+ }
715
+ new Qt(e, {
716
+ path: t,
717
+ crossOrigin: this.crossOrigin,
718
+ requestHeader: this.requestHeader,
719
+ manager: this.manager
720
+ }).parse(s, n);
721
+ }
722
+ parseAsync(e, t) {
723
+ return new Promise((s, n) => {
724
+ this.parse(
725
+ e,
726
+ t,
727
+ (i) => {
728
+ s(i);
729
+ },
730
+ (i) => {
731
+ n(i);
732
+ }
733
+ );
734
+ });
735
+ }
736
+ }
737
+ class R {
738
+ static CACHE_NAME = "u-space-model-loader-cache";
739
+ static fileLoader = new fe().setResponseType("arraybuffer");
740
+ static dracoLoader = new ft().setDecoderPath(
741
+ `https://cdn.jsdelivr.net/npm/three@0.${ie}.0/examples/jsm/libs/draco/`
742
+ );
743
+ static ktx2Loader = new yt().setTranscoderPath(
744
+ `https://cdn.jsdelivr.net/npm/three@0.${ie}.0/examples/jsm/libs/basis/`
745
+ );
746
+ static gltfLoader = new Me().setDRACOLoader(R.dracoLoader).setKTX2Loader(R.ktx2Loader).setMeshoptDecoder(he);
747
+ static sbmxLoader = new Rt().setDRACOLoader(R.dracoLoader).setKTX2Loader(R.ktx2Loader).setMeshoptDecoder(he);
748
+ static sbmLoader = new Kt();
749
+ static fbxLoader = new mt();
750
+ static objLoader = new gt();
751
+ static stlLoader = new wt();
752
+ static setLoadingManager(e) {
753
+ this.fileLoader.manager = e, this.dracoLoader.manager = e, this.ktx2Loader.manager = e, this.gltfLoader.manager = e, this.sbmxLoader.manager = e, this.sbmLoader.manager = e, this.fbxLoader.manager = e, this.objLoader.manager = e, this.stlLoader.manager = e;
754
+ }
755
+ /**
756
+ * Set the renderer to enable KTX2 support and other renderer-dependent features.
757
+ */
758
+ static async setRenderer(e) {
759
+ await e.init(), this.ktx2Loader.detectSupport(e);
760
+ }
761
+ /**
762
+ * Configure Draco decoder path.
763
+ */
764
+ static setDracoPath(e) {
765
+ this.dracoLoader.setDecoderPath(e);
766
+ }
767
+ /**
768
+ * Configure KTX2 transcoder path.
769
+ */
770
+ static setKTX2Path(e) {
771
+ this.ktx2Loader.setTranscoderPath(e);
772
+ }
773
+ static async loadAsync(e, t = { persistent: !0 }) {
774
+ const s = e.split(".").pop()?.split("?")[0].toLowerCase();
775
+ let n;
776
+ switch (t.persistent && typeof caches < "u" ? n = await this.getPersistentData(e) : n = await this.fileLoader.loadAsync(e), s) {
777
+ case "gltf":
778
+ case "glb":
779
+ return (await this.gltfLoader.parseAsync(n, L.extractUrlBase(e))).scene;
780
+ case "sbmx":
781
+ return (await this.sbmxLoader.parseAsync(n, L.extractUrlBase(e))).scene;
782
+ case "sbm":
783
+ return await this.sbmLoader.parseAsync(n, L.extractUrlBase(e));
784
+ case "fbx":
785
+ return this.fbxLoader.parse(n, L.extractUrlBase(e));
786
+ case "obj":
787
+ const h = new TextDecoder().decode(n);
788
+ return this.objLoader.parse(h);
789
+ case "stl":
790
+ const u = this.stlLoader.parse(n);
791
+ return new j(u, new I());
792
+ default:
793
+ throw new Error(`Unsupported model format: ${s}`);
794
+ }
795
+ }
796
+ static async getPersistentData(e) {
797
+ try {
798
+ const t = await caches.open(this.CACHE_NAME), s = await t.match(e);
799
+ if (s)
800
+ return await s.arrayBuffer();
801
+ const n = await this.fileLoader.loadAsync(e), i = new Response(n);
802
+ return await t.put(e, i), n;
803
+ } catch (t) {
804
+ return console.warn(`[LoaderManager] Failed to use Cache API for ${e}:`, t), await this.fileLoader.loadAsync(e);
805
+ }
806
+ }
807
+ }
808
+ class vs {
809
+ static textureLoader = new ye();
810
+ static hdrLoader = new vt();
811
+ static cubeTextureLoader = new Ye();
812
+ static setLoadingManager(e) {
813
+ this.textureLoader.manager = e, this.hdrLoader.manager = e, this.cubeTextureLoader.manager = e;
814
+ }
815
+ static async loadAsyncTexture(e) {
816
+ return await this.textureLoader.loadAsync(e);
817
+ }
818
+ static async loadAsyncHDR(e) {
819
+ const t = await this.hdrLoader.loadAsync(e);
820
+ return t.mapping = Je, t;
821
+ }
822
+ static async loadAsyncCubeTexture(e, t) {
823
+ return this.cubeTextureLoader.setPath(e), await this.cubeTextureLoader.loadAsync(t);
824
+ }
825
+ }
826
+ class U extends j {
827
+ isBaseMesh = !0;
828
+ type = "BaseMesh";
829
+ ignoreInvisibleWhenRaycast = !0;
830
+ constructor(...e) {
831
+ super(...e);
832
+ }
833
+ raycast(e, t) {
834
+ return this.visible === !1 && this.ignoreInvisibleWhenRaycast === !0 ? !1 : super.raycast(e, t);
835
+ }
836
+ }
837
+ class Ee extends z {
838
+ isBaseGroup = !0;
839
+ type = "BaseGroup";
840
+ ignoreInvisibleWhenRaycast = !0;
841
+ constructor(...e) {
842
+ super(...e);
843
+ }
844
+ raycast(e, t) {
845
+ return this.visible === !1 && this.ignoreInvisibleWhenRaycast === !0 ? !1 : super.raycast(e, t);
846
+ }
847
+ }
848
+ class Xt extends Ze {
849
+ isBaseSprite = !0;
850
+ type = "BaseSprite";
851
+ ignoreInvisibleWhenRaycast = !0;
852
+ constructor(...e) {
853
+ super(...e);
854
+ }
855
+ raycast(e, t) {
856
+ return this.visible === !1 && this.ignoreInvisibleWhenRaycast === !0 ? !1 : super.raycast(e, t);
857
+ }
858
+ }
859
+ class H extends Ee {
860
+ isModel = !0;
861
+ type = "Model";
862
+ static memoryCache = /* @__PURE__ */ new Map();
863
+ constructor() {
864
+ super();
865
+ }
866
+ async loadAsync(e) {
867
+ const { url: t, cache: s = !0, persistent: n = !0 } = e;
868
+ try {
869
+ let i;
870
+ s ? H.memoryCache.has(t) ? i = H.memoryCache.get(t) : (i = R.loadAsync(t, { persistent: n }), H.memoryCache.set(t, i)) : i = R.loadAsync(t, { persistent: n });
871
+ const a = await i, c = bt(a);
872
+ return this.add(c), c;
873
+ } catch (i) {
874
+ return console.error(`[Model] Failed to load model from ${t}:`, i), null;
875
+ }
876
+ }
877
+ static clearMemoryCache() {
878
+ this.memoryCache.clear();
879
+ }
880
+ static async clearPersistentCache() {
881
+ typeof caches < "u" && await caches.delete("u-space-loader-cache");
882
+ }
883
+ }
884
+ class qt extends U {
885
+ isSphereMesh = !0;
886
+ type = "SphereMesh";
887
+ constructor({ geometryParameters: e, materialParameters: t } = {}) {
888
+ super(), this.geometry = new Ve(
889
+ e?.radius,
890
+ e?.widthSegments,
891
+ e?.heightSegments,
892
+ e?.phiStart,
893
+ e?.phiLength,
894
+ e?.thetaStart,
895
+ e?.thetaLength
896
+ ), this.material = new I(t);
897
+ }
898
+ }
899
+ class pe extends U {
900
+ isTubeMesh = !0;
901
+ type = "TubeMesh";
902
+ constructor({ geometryParameters: e, materialParameters: t } = {}) {
903
+ super(), this.geometry = new et(
904
+ e?.path,
905
+ e?.tubularSegments,
906
+ e?.radius,
907
+ e?.radialSegments,
908
+ e?.closed
909
+ ), this.material = new I(t);
910
+ }
911
+ }
912
+ class bs extends Ee {
913
+ isTopology = !0;
914
+ type = "Topology";
915
+ // Visuals
916
+ parameters = {
917
+ nodeColor: 255,
918
+ nodeRadius: 0.5,
919
+ edgeColor: 65280,
920
+ edgeRadius: 0.1,
921
+ pathColor: 16711935,
922
+ pathRadius: 0.2
923
+ };
924
+ nodes = /* @__PURE__ */ new Map();
925
+ adjacencyMap = /* @__PURE__ */ new Map();
926
+ graphGroup = null;
927
+ pathMeshes = [];
928
+ constructor(e) {
929
+ super(), e && Object.assign(this.parameters, e);
930
+ }
931
+ /**
932
+ * Add a node to the topology graph.
933
+ * @param id Unique identifier for the node
934
+ * @param position 3D position of the node
935
+ */
936
+ addNode(e, t) {
937
+ this.nodes.has(e) && console.warn(`[Topology] Node ${e} already exists. Overwriting.`), this.nodes.set(e, t), this.adjacencyMap.has(e) || this.adjacencyMap.set(e, /* @__PURE__ */ new Map());
938
+ }
939
+ /**
940
+ * Remove a node from the topology graph.
941
+ * @param id Unique identifier for the node
942
+ */
943
+ removeNode(e) {
944
+ if (!this.nodes.has(e)) {
945
+ console.warn(`[Topology] Node ${e} does not exist.`);
946
+ return;
947
+ }
948
+ this.nodes.delete(e), this.adjacencyMap.delete(e);
949
+ }
950
+ /**
951
+ * Add an edge between two nodes.
952
+ * @param from Node ID
953
+ * @param to Node ID
954
+ * @param weight Cost of the edge. Defaults to Euclidean distance.
955
+ * @param bidirectional If true, adds the reverse edge as well. Default true.
956
+ */
957
+ addEdge(e, t, s, n = !0) {
958
+ const i = this.nodes.get(e), a = this.nodes.get(t);
959
+ if (!i || !a) {
960
+ console.error(`[Topology] Cannot add edge. One or both nodes not found: ${e}, ${t}`);
961
+ return;
962
+ }
963
+ const c = s ?? i.distanceTo(a);
964
+ this.getNeighbors(e)?.set(t, c), n && this.getNeighbors(t)?.set(e, c);
965
+ }
966
+ /**
967
+ * Remove an edge between two nodes.
968
+ * @param from Node ID
969
+ * @param to Node ID
970
+ * @param bidirectional If true, removes the reverse edge as well. Default true.
971
+ */
972
+ removeEdge(e, t, s = !0) {
973
+ this.getNeighbors(e)?.delete(t), s && this.getNeighbors(t)?.delete(e);
974
+ }
975
+ /**
976
+ * Find the shortest path between start and end nodes using Dijkstra's algorithm.
977
+ */
978
+ getShortestPath(e, t) {
979
+ if (!this.nodes.has(e) || !this.nodes.has(t))
980
+ return console.warn("[Topology] Start or End node not found."), [];
981
+ const s = /* @__PURE__ */ new Map(), n = /* @__PURE__ */ new Map(), i = /* @__PURE__ */ new Set();
982
+ for (const [r] of this.nodes)
983
+ s.set(r, 1 / 0), n.set(r, null), i.add(r);
984
+ for (s.set(e, 0); i.size > 0; ) {
985
+ let r = null, h = 1 / 0;
986
+ for (const u of i) {
987
+ const f = s.get(u);
988
+ f < h && (h = f, r = u);
989
+ }
990
+ if (r === null || r === t || h === 1 / 0)
991
+ break;
992
+ i.delete(r);
993
+ const l = this.adjacencyMap?.get(r);
994
+ if (l)
995
+ for (const [u, f] of l) {
996
+ if (!i.has(u)) continue;
997
+ const p = s.get(r) + f;
998
+ p < s.get(u) && (s.set(u, p), n.set(u, r));
999
+ }
1000
+ }
1001
+ const a = [];
1002
+ let c = t;
1003
+ if (n.get(t) === null && e !== t)
1004
+ return [];
1005
+ for (; c !== null; ) {
1006
+ const r = this.nodes.get(c);
1007
+ r && a.unshift(r), c = n.get(c) || null;
1008
+ }
1009
+ return a;
1010
+ }
1011
+ /**
1012
+ * Renders the entire topology graph structure using TubeGeometry and Spheres.
1013
+ */
1014
+ renderGraph() {
1015
+ this.clearGraph(), this.graphGroup = new z();
1016
+ const e = new qt({
1017
+ geometryParameters: {
1018
+ radius: this.parameters.nodeRadius,
1019
+ widthSegments: 16,
1020
+ heightSegments: 16
1021
+ },
1022
+ materialParameters: {
1023
+ color: this.parameters.nodeColor
1024
+ }
1025
+ });
1026
+ this.nodes.forEach((s, n) => {
1027
+ const i = e.clone();
1028
+ i.position.copy(s), Object.assign(i.userData, { id: n, type: "node" }), this.graphGroup.add(i);
1029
+ });
1030
+ const t = /* @__PURE__ */ new Set();
1031
+ this.adjacencyMap.forEach((s, n) => {
1032
+ s.forEach((i, a) => {
1033
+ const c = [n, a].sort().join("-");
1034
+ if (t.has(c)) return;
1035
+ t.add(c);
1036
+ const r = this.nodes.get(n), h = this.nodes.get(a);
1037
+ if (r && h) {
1038
+ const l = new tt(r, h), u = new pe({
1039
+ geometryParameters: {
1040
+ path: l,
1041
+ tubularSegments: 1,
1042
+ radius: this.parameters.edgeRadius,
1043
+ radialSegments: 8,
1044
+ closed: !1
1045
+ },
1046
+ materialParameters: {
1047
+ color: this.parameters.edgeColor
1048
+ }
1049
+ });
1050
+ Object.assign(u.userData, { from: n, to: a, weight: i, type: "edge" }), this.graphGroup.add(u);
1051
+ }
1052
+ });
1053
+ }), this.add(this.graphGroup);
1054
+ }
1055
+ clearGraph() {
1056
+ this.graphGroup && (this.remove(this.graphGroup), this.graphGroup.traverse((e) => {
1057
+ e instanceof j && (e.geometry.dispose(), e.material.dispose());
1058
+ }), this.graphGroup = null);
1059
+ }
1060
+ /**
1061
+ * Visualizes a path using TubeGeometry (CatmullRomCurve3).
1062
+ */
1063
+ renderPath(e, t = this.parameters.pathColor) {
1064
+ if (e.length < 2) return;
1065
+ const s = new st(e, !1, "catmullrom", 0), n = new pe({
1066
+ geometryParameters: {
1067
+ path: s,
1068
+ tubularSegments: e.length * 10,
1069
+ radius: this.parameters.pathRadius,
1070
+ closed: !1
1071
+ },
1072
+ materialParameters: {
1073
+ color: t
1074
+ }
1075
+ });
1076
+ return this.add(n), this.pathMeshes.push(n), n;
1077
+ }
1078
+ clearPaths() {
1079
+ this.pathMeshes.forEach((e) => {
1080
+ this.remove(e), e.geometry.dispose(), e.material.dispose();
1081
+ }), this.pathMeshes = [];
1082
+ }
1083
+ dispose() {
1084
+ this.clearGraph(), this.clearPaths();
1085
+ }
1086
+ getNeighbors(e) {
1087
+ return this.adjacencyMap.get(e);
1088
+ }
1089
+ }
1090
+ class Ts extends Xt {
1091
+ isPoi = !0;
1092
+ type = "Poi";
1093
+ parameters = {
1094
+ img: "",
1095
+ text: "",
1096
+ fontSize: 32,
1097
+ fontFamily: "Arial",
1098
+ color: "#ffffff",
1099
+ iconSize: 64,
1100
+ padding: 10,
1101
+ backgroundColor: "rgba(0, 0, 0, 0.5)",
1102
+ borderRadius: 8,
1103
+ textPosition: "right"
1104
+ };
1105
+ constructor(e = {}) {
1106
+ super(new nt()), Object.assign(this.parameters, e);
1107
+ }
1108
+ /**
1109
+ * Update the POI with new parameters
1110
+ * @param parameters Partial POI parameters
1111
+ */
1112
+ async updateAsync(e = {}) {
1113
+ Object.assign(this.parameters, e);
1114
+ const t = document.createElement("canvas"), s = t.getContext("2d");
1115
+ if (!s) return;
1116
+ s.font = `${this.parameters.fontSize}px ${this.parameters.fontFamily}`;
1117
+ let n = null;
1118
+ this.parameters.img && (n = await this._loadImage(this.parameters.img));
1119
+ const { text: i, fontSize: a, color: c, iconSize: r, padding: h, backgroundColor: l, borderRadius: u, textPosition: f } = this.parameters, p = s.measureText(i), g = i ? p.width : 0, w = i ? a : 0;
1120
+ let T = 0, v = 0, b = 0, M = 0, x = 0, E = 0;
1121
+ const S = !!n, m = !!i;
1122
+ if (S && m)
1123
+ switch (f) {
1124
+ case "top":
1125
+ T = Math.max(r, g), v = r + h + w, x = (T - g) / 2, E = w / 2, b = (T - r) / 2, M = w + h;
1126
+ break;
1127
+ case "bottom":
1128
+ T = Math.max(r, g), v = r + h + w, b = (T - r) / 2, M = 0, x = (T - g) / 2, E = r + h + w / 2;
1129
+ break;
1130
+ case "left":
1131
+ T = r + h + g, v = Math.max(r, w), x = 0, E = v / 2, b = g + h, M = (v - r) / 2;
1132
+ break;
1133
+ default:
1134
+ T = r + h + g, v = Math.max(r, w), b = 0, M = (v - r) / 2, x = r + h, E = v / 2;
1135
+ break;
1136
+ }
1137
+ else S ? (T = r, v = r, b = 0, M = 0) : m && (T = g, v = w, x = 0, E = w / 2);
1138
+ const y = T + h * 2, B = v + h * 2;
1139
+ t.width = y, t.height = B, s.font = `${a}px ${this.parameters.fontFamily}`, s.textBaseline = "middle", l && (s.fillStyle = l, this._drawRoundedRect(s, 0, 0, y, B, u), s.fill()), S && s.drawImage(n, b + h, M + h, r, r), m && (s.fillStyle = c, s.fillText(i, x + h, E + h)), this.material.map?.dispose();
1140
+ const _ = new it(t);
1141
+ _.colorSpace = ve, this.material.map = _;
1142
+ const O = 0.01;
1143
+ this.scale.set(y * O, B * O, 1);
1144
+ }
1145
+ _loadImage(e) {
1146
+ return new Promise((t, s) => {
1147
+ if (typeof e == "string") {
1148
+ const n = new Image();
1149
+ n.crossOrigin = "Anonymous", n.onload = () => t(n), n.onerror = (i) => s(i), n.src = e;
1150
+ } else
1151
+ t(e);
1152
+ });
1153
+ }
1154
+ _drawRoundedRect(e, t, s, n, i, a) {
1155
+ e.beginPath(), e.moveTo(t + a, s), e.lineTo(t + n - a, s), e.quadraticCurveTo(t + n, s, t + n, s + a), e.lineTo(t + n, s + i - a), e.quadraticCurveTo(t + n, s + i, t + n - a, s + i), e.lineTo(t + a, s + i), e.quadraticCurveTo(t, s + i, t, s + i - a), e.lineTo(t, s + a), e.quadraticCurveTo(t, s, t + a, s), e.closePath();
1156
+ }
1157
+ dispose() {
1158
+ this.material.map?.dispose(), this.material.dispose();
1159
+ }
1160
+ }
1161
+ class Oe extends U {
1162
+ isShapeMesh = !0;
1163
+ type = "ShapeMesh";
1164
+ constructor({ geometryParameters: e, materialParameters: t } = {}) {
1165
+ super(), this.geometry = new rt(e?.shape, e?.curveSegments), this.material = new I(t), this.geometry.rotateX(-Math.PI / 2);
1166
+ }
1167
+ static createFromPoints(e, t = {}) {
1168
+ return new Oe({
1169
+ ...t,
1170
+ geometryParameters: {
1171
+ ...t.geometryParameters,
1172
+ shape: new be(e.map((s) => new P(s.x, -s.z)))
1173
+ }
1174
+ });
1175
+ }
1176
+ }
1177
+ class Pe extends U {
1178
+ isExtrudeMesh = !0;
1179
+ type = "ExtrudeMesh";
1180
+ constructor({ geometryParameters: e, materialParameters: t } = {}) {
1181
+ super(), this.geometry = new at(e?.shape, e?.options), this.material = new I(t), this.geometry.rotateX(-Math.PI / 2);
1182
+ }
1183
+ static createFromPoints(e, t = {}) {
1184
+ return new Pe({
1185
+ ...t,
1186
+ geometryParameters: {
1187
+ ...t.geometryParameters,
1188
+ shape: new be(e.map((s) => new P(s.x, -s.z)))
1189
+ }
1190
+ });
1191
+ }
1192
+ }
1193
+ class Cs extends U {
1194
+ isPlaneMesh = !0;
1195
+ type = "PlaneMesh";
1196
+ constructor({ geometryParameters: e, materialParameters: t } = {}) {
1197
+ super(), this.geometry = new ot(
1198
+ e?.width,
1199
+ e?.height,
1200
+ e?.widthSegments,
1201
+ e?.heightSegments
1202
+ ), this.material = new I(t);
1203
+ }
1204
+ }
1205
+ class Ms extends U {
1206
+ isCircleMesh = !0;
1207
+ type = "CircleMesh";
1208
+ constructor({ geometryParameters: e, materialParameters: t } = {}) {
1209
+ super(
1210
+ new ct(
1211
+ e?.radius,
1212
+ e?.segments,
1213
+ e?.thetaStart,
1214
+ e?.thetaLength
1215
+ ),
1216
+ new I(t)
1217
+ ), this.geometry.rotateX(-Math.PI / 2);
1218
+ }
1219
+ }
1220
+ class Yt {
1221
+ static traverseMeshes(e, t) {
1222
+ e.traverse((s) => {
1223
+ s instanceof j && t(s);
1224
+ });
1225
+ }
1226
+ }
1227
+ class xs {
1228
+ static flow(e = {}) {
1229
+ const { baseColor: t = 16777215, flowColor: s = 65280, speed: n = 1, scale: i = 3, intensity: a = 4 } = e, c = A(new N(t)), r = A(new N(s)), h = re().x.mul(i).sub(Q.mul(n)), l = K(ae(h).add(1).mul(0.5), a);
1230
+ return X(c, r, l);
1231
+ }
1232
+ static breathe(e = {}) {
1233
+ const { baseColor: t = 16777215, breathColor: s = 65280, speed: n = 1, intensity: i = 2 } = e, a = A(new N(t)), c = A(new N(s)), r = ae(Q.mul(n)).add(1).mul(0.5), h = K(r, i);
1234
+ return X(a, c, h);
1235
+ }
1236
+ static fluid(e = {}) {
1237
+ const {
1238
+ baseColor: t = 16777215,
1239
+ flowColor: s = 255,
1240
+ speed: n = 1,
1241
+ scale: i = 1,
1242
+ intensity: a = 1,
1243
+ distortion: c = 0.5
1244
+ } = e, r = A(new N(t)), h = A(new N(s)), l = re().mul(i), u = Q.mul(n), f = oe(l.add(u), 1, 0), p = l.add(f.mul(c)), g = oe(p, 1, 0).add(1).mul(0.5), w = K(g, a);
1245
+ return X(r, h, w);
1246
+ }
1247
+ }
1248
+ function Es(o) {
1249
+ }
1250
+ const $ = "uSpaceHighlight", Z = `${$}/enabled`, Se = `${$}/opacity`, Le = `${$}/color`, Ie = `${$}/overwrite`, Jt = Te(() => {
1251
+ const o = D(Z, "uint"), e = D(Le, "uint"), t = D(Ie, "uint"), s = Vt(e), n = ce.mul(s), i = Y(t.greaterThan(0), s, n);
1252
+ return Y(o.greaterThan(0), i, ce);
1253
+ })(), Zt = Te(() => {
1254
+ const o = D(Z, "uint"), e = D(Se, "float");
1255
+ return Y(o.greaterThan(0), e, lt);
1256
+ })();
1257
+ class Os {
1258
+ static highlight(e, t = {}) {
1259
+ const s = Object.assign(
1260
+ {
1261
+ enabled: !0,
1262
+ opacity: 0.5,
1263
+ color: 16711680,
1264
+ overwrite: !1
1265
+ },
1266
+ t
1267
+ );
1268
+ s.color = new J(s.color).getHex(), Yt.traverseMeshes(e, (n) => {
1269
+ n.userData[Z] = s.enabled ? 1 : 0, n.userData[Se] = s.opacity, n.userData[Le] = s.color, n.userData[Ie] = s.overwrite ? 1 : 0;
1270
+ const i = n.material;
1271
+ i && !Array.isArray(i) && (i.transparent = !0, i.colorNode = Jt, i.opacityNode = Zt, i.needsUpdate = !0);
1272
+ });
1273
+ }
1274
+ }
1275
+ const Vt = (o) => {
1276
+ const e = o.shiftRight(16).bitAnd(255).toFloat().div(255), t = o.shiftRight(8).bitAnd(255).toFloat().div(255), s = o.bitAnd(255).toFloat().div(255);
1277
+ return dt(e, t, s);
1278
+ };
1279
+ class es extends Tt {
1280
+ viewer;
1281
+ constructor(e, t) {
1282
+ super(t), this.viewer = e;
1283
+ }
1284
+ _update = ({ time: e }) => {
1285
+ this.update(e) && this.viewer.render();
1286
+ };
1287
+ easingByMode(e) {
1288
+ const t = ts[e];
1289
+ return super.easing(t);
1290
+ }
1291
+ start(e, t) {
1292
+ return this.viewer.addEventListener("afterControlsUpdate", this._update), super.start(e, t);
1293
+ }
1294
+ stop() {
1295
+ return this.viewer.removeEventListener("afterControlsUpdate", this._update), super.stop();
1296
+ }
1297
+ }
1298
+ function Ps(o, e, t, s = {}, n, i) {
1299
+ return new Promise((a, c) => {
1300
+ const { duration: r = 1e3, delay: h = 0, repeat: l = !1, mode: u = "Linear.None", yoyo: f = !1 } = s, p = new es(o, e).to(t, r).easingByMode(u).delay(h).onUpdate((g) => {
1301
+ n?.(g, p);
1302
+ }).onComplete(() => {
1303
+ a();
1304
+ }).onStop(() => {
1305
+ c("animation stop");
1306
+ }).onStart(() => {
1307
+ i?.(p);
1308
+ });
1309
+ typeof l == "number" ? p.repeat(l) : typeof l == "boolean" && l && p.repeat(1 / 0), f && p.repeatDelay(20), p.yoyo(f), p.start();
1310
+ });
1311
+ }
1312
+ const ts = {
1313
+ "Linear.None": d.Linear.None,
1314
+ "Quadratic.In": d.Quadratic.In,
1315
+ "Quadratic.Out": d.Quadratic.Out,
1316
+ "Quadratic.InOut": d.Quadratic.InOut,
1317
+ "Cubic.In": d.Cubic.In,
1318
+ "Cubic.Out": d.Cubic.Out,
1319
+ "Cubic.InOut": d.Cubic.InOut,
1320
+ "Quartic.In": d.Quartic.In,
1321
+ "Quartic.Out": d.Quartic.Out,
1322
+ "Quartic.InOut": d.Quartic.InOut,
1323
+ "Quintic.In": d.Quintic.In,
1324
+ "Quintic.Out": d.Quintic.Out,
1325
+ "Quintic.InOut": d.Quintic.InOut,
1326
+ "Sinusoidal.In": d.Sinusoidal.In,
1327
+ "Sinusoidal.Out": d.Sinusoidal.Out,
1328
+ "Sinusoidal.InOut": d.Sinusoidal.InOut,
1329
+ "Exponential.In": d.Exponential.In,
1330
+ "Exponential.Out": d.Exponential.Out,
1331
+ "Exponential.InOut": d.Exponential.InOut,
1332
+ "Circular.In": d.Circular.In,
1333
+ "Circular.Out": d.Circular.Out,
1334
+ "Circular.InOut": d.Circular.InOut,
1335
+ "Elastic.In": d.Elastic.In,
1336
+ "Elastic.Out": d.Elastic.Out,
1337
+ "Elastic.InOut": d.Elastic.InOut,
1338
+ "Back.In": d.Back.In,
1339
+ "Back.Out": d.Back.Out,
1340
+ "Back.InOut": d.Back.InOut,
1341
+ "Bounce.In": d.Bounce.In,
1342
+ "Bounce.Out": d.Bounce.Out,
1343
+ "Bounce.InOut": d.Bounce.InOut
1344
+ };
1345
+ export {
1346
+ Ee as BaseGroup,
1347
+ U as BaseMesh,
1348
+ Xt as BaseSprite,
1349
+ Pt as CameraControls,
1350
+ Ms as CircleMesh,
1351
+ Pe as ExtrudeMesh,
1352
+ Ct as InteractionEvent,
1353
+ Mt as InteractionManager,
1354
+ Os as MaterialEffects,
1355
+ H as Model,
1356
+ R as ModelLoaderManager,
1357
+ xt as ObjectManager,
1358
+ Yt as ObjectUtils,
1359
+ Cs as PlaneMesh,
1360
+ Ts as Poi,
1361
+ Lt as RoomEnvironment,
1362
+ Kt as SBMLoader,
1363
+ Rt as SBMXLoader,
1364
+ Oe as ShapeMesh,
1365
+ qt as SphereMesh,
1366
+ xs as TSLEffects,
1367
+ vs as TextureLoaderManager,
1368
+ bs as Topology,
1369
+ pe as TubeMesh,
1370
+ es as Tween,
1371
+ ys as Viewer,
1372
+ Es as reinterpretType,
1373
+ Ps as tweenAnimation
1374
+ };