@needle-tools/engine 5.1.0-experimental.03e8105 → 5.1.0-experimental.08fa2ef

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 (54) hide show
  1. package/dist/{needle-engine.bundle-DF6ovbwD.min.js → needle-engine.bundle-6jp9Udrr.min.js} +2 -2
  2. package/dist/{needle-engine.bundle-BNqUjnSQ.js → needle-engine.bundle-CB0g67az.js} +9 -9
  3. package/dist/{needle-engine.bundle-Bt8ULD7E.umd.cjs → needle-engine.bundle-D5db5ZP1.umd.cjs} +3 -3
  4. package/dist/needle-engine.d.ts +6 -6
  5. package/dist/needle-engine.js +368 -368
  6. package/dist/needle-engine.min.js +1 -1
  7. package/dist/needle-engine.umd.cjs +1 -1
  8. package/lib/engine/api.d.ts +1 -1
  9. package/lib/engine/api.js +1 -1
  10. package/lib/engine/api.js.map +1 -1
  11. package/lib/engine/engine_init.js +2 -2
  12. package/lib/engine/engine_init.js.map +1 -1
  13. package/lib/engine/engine_license.d.ts +7 -7
  14. package/lib/engine/engine_license.js +70 -70
  15. package/lib/engine/engine_license.js.map +1 -1
  16. package/lib/engine/engine_networking_blob.js +3 -3
  17. package/lib/engine/engine_networking_blob.js.map +1 -1
  18. package/lib/engine/engine_utils_qrcode.js +2 -2
  19. package/lib/engine/engine_utils_qrcode.js.map +1 -1
  20. package/lib/engine/webcomponents/needle menu/needle-menu-spatial.js +2 -2
  21. package/lib/engine/webcomponents/needle menu/needle-menu-spatial.js.map +1 -1
  22. package/lib/engine/webcomponents/needle menu/needle-menu.js +5 -5
  23. package/lib/engine/webcomponents/needle menu/needle-menu.js.map +1 -1
  24. package/lib/engine/webcomponents/needle-engine.js +2 -2
  25. package/lib/engine/webcomponents/needle-engine.js.map +1 -1
  26. package/lib/engine/webcomponents/needle-engine.loading.js +2 -2
  27. package/lib/engine/webcomponents/needle-engine.loading.js.map +1 -1
  28. package/lib/engine/xr/TempXRContext.js +2 -2
  29. package/lib/engine/xr/TempXRContext.js.map +1 -1
  30. package/lib/engine-components/export/usdz/USDZExporter.js +4 -4
  31. package/lib/engine-components/export/usdz/USDZExporter.js.map +1 -1
  32. package/package.json +1 -1
  33. package/plugins/common/license.js +4 -4
  34. package/plugins/dts-generator/dts.codegen.js +334 -0
  35. package/plugins/dts-generator/dts.scan.js +99 -0
  36. package/plugins/dts-generator/dts.writer.js +59 -0
  37. package/plugins/dts-generator/glb.discovery.js +279 -0
  38. package/plugins/dts-generator/glb.extractor.js +215 -0
  39. package/plugins/dts-generator/glb.reader.js +167 -0
  40. package/plugins/dts-generator/index.js +36 -0
  41. package/plugins/dts-generator/manifest.types.js +174 -0
  42. package/plugins/gltf-packer.mjs +1 -0
  43. package/plugins/vite/license.js +5 -9
  44. package/src/engine/api.ts +1 -1
  45. package/src/engine/engine_init.ts +2 -2
  46. package/src/engine/engine_license.ts +68 -68
  47. package/src/engine/engine_networking_blob.ts +3 -3
  48. package/src/engine/engine_utils_qrcode.ts +2 -2
  49. package/src/engine/webcomponents/needle menu/needle-menu-spatial.ts +2 -2
  50. package/src/engine/webcomponents/needle menu/needle-menu.ts +5 -5
  51. package/src/engine/webcomponents/needle-engine.loading.ts +6 -6
  52. package/src/engine/webcomponents/needle-engine.ts +2 -2
  53. package/src/engine/xr/TempXRContext.ts +2 -2
  54. package/src/engine-components/export/usdz/USDZExporter.ts +4 -4
@@ -0,0 +1,36 @@
1
+ // @ts-check
2
+ /**
3
+ * Needle Engine — HTML binding DTS generator
4
+ *
5
+ * Scans all GLB/glTF files in the project's assets directory, extracts
6
+ * NEEDLE_components data, and emits a `needle-bindings.d.ts` virtual-module
7
+ * declaration so that TypeScript can type-check HTML ↔ 3D component bindings.
8
+ *
9
+ * Typical generated output:
10
+ *
11
+ * declare module "needle-bindings" {
12
+ * interface SceneData {
13
+ * Sphere: {
14
+ * MyBall: { speed: number; label: string; };
15
+ * };
16
+ * }
17
+ * }
18
+ *
19
+ * How component field types are resolved:
20
+ * - For built-in Needle Engine components, types are read from
21
+ * `components.needle.json` which lists only @serializable fields with
22
+ * their proper TypeScript types.
23
+ * - For user-defined components (not in the manifest), types are inferred
24
+ * from the JSON value in the GLB (number/string/boolean → typed, else → unknown).
25
+ * - Known Three.js types (Color, Vector3, Object3D, …) are emitted as
26
+ * `import("three").TypeName` and known Needle types (RGBAColor, AssetReference, …)
27
+ * as `import("@needle-tools/engine").TypeName`.
28
+ * - Truly unknown types fall back to `unknown`.
29
+ */
30
+
31
+ export { resolveEntrypointGlbs, collectSceneFiles } from './glb.discovery.js';
32
+ export { readGlbJsonChunk, readGltfJsonFile, readRemoteGlbJsonChunk } from './glb.reader.js';
33
+ export { extractComponentBindings, sanitizeNodeName, inferNodeThreeType, inferTsType } from './glb.extractor.js';
34
+ export { scanBindings } from './dts.scan.js';
35
+ export { generateDts, generateHtmlCustomData } from './dts.codegen.js';
36
+ export { generateBindingsDts } from './dts.writer.js';
@@ -0,0 +1,174 @@
1
+ // @ts-check
2
+ /**
3
+ * Type tables and components.needle.json manifest loader.
4
+ *
5
+ * Knows about primitive TS types, known Three.js types, known Needle Engine
6
+ * types, and how to resolve field types from the manifest.
7
+ */
8
+
9
+ import { existsSync, readFileSync } from 'fs';
10
+ import { join, dirname } from 'path';
11
+ import { fileURLToPath } from 'url';
12
+
13
+ const __filename = fileURLToPath(import.meta.url);
14
+ const __dirname = dirname(__filename);
15
+
16
+ /** Primitive TS type strings that can safely appear in an ambient declaration. */
17
+ export const PRIMITIVE_TYPES = new Set(["number", "string", "boolean"]);
18
+
19
+ /**
20
+ * Known Three.js types → import("three").TypeName
21
+ * @type {Record<string, string>}
22
+ */
23
+ export const THREE_TYPES = {
24
+ Color: `import("three").Color`,
25
+ ColorRepresentation: `import("three").ColorRepresentation`,
26
+ Euler: `import("three").Euler`,
27
+ Texture: `import("three").Texture`,
28
+ // Materials
29
+ Material: `import("three").Material`,
30
+ MeshStandardMaterial: `import("three").MeshStandardMaterial`,
31
+ // Objects
32
+ Object3D: `import("three").Object3D`,
33
+ Mesh: `import("three").Mesh`,
34
+ SkinnedMesh: `import("three").SkinnedMesh`,
35
+ // Other
36
+ Vector2: `import("three").Vector2`,
37
+ Vector3: `import("three").Vector3`,
38
+ Vector4: `import("three").Vector4`,
39
+ Matrix3: `import("three").Matrix3`,
40
+ Matrix4: `import("three").Matrix4`,
41
+ Quaternion: `import("three").Quaternion`,
42
+ // Animation
43
+ AnimationClip: `import("three").AnimationClip`,
44
+ AnimationMixer: `import("three").AnimationMixer`,
45
+ };
46
+
47
+ /**
48
+ * Known Needle Engine types → import("@needle-tools/engine").TypeName
49
+ * @type {Record<string, string>}
50
+ */
51
+ export const NEEDLE_TYPES = {
52
+ AssetReference: `import("@needle-tools/engine").AssetReference`,
53
+ EventList: `import("@needle-tools/engine").EventList`,
54
+ GameObject: `import("@needle-tools/engine").GameObject`,
55
+ LookAtConstraint: `import("@needle-tools/engine").LookAtConstraint`,
56
+ RGBAColor: `import("@needle-tools/engine").RGBAColor`,
57
+ RenderTexture: `import("@needle-tools/engine").RenderTexture`,
58
+ Renderer: `import("@needle-tools/engine").Renderer`,
59
+ Rigidbody: `import("@needle-tools/engine").Rigidbody`,
60
+ Sprite: `import("@needle-tools/engine").Sprite`,
61
+ Vec2: `import("@needle-tools/engine").Vec2`,
62
+ };
63
+
64
+ /**
65
+ * Map a single non-array, non-primitive type token to its TS representation.
66
+ * Returns null if unknown.
67
+ * @param {string} token
68
+ * @returns {string | null}
69
+ */
70
+ function mapKnownType(token) {
71
+ if (token in THREE_TYPES) return THREE_TYPES[token];
72
+ if (token in NEEDLE_TYPES) return NEEDLE_TYPES[token];
73
+ return null;
74
+ }
75
+
76
+ /**
77
+ * Convert a manifest type string to a safe ambient TS type.
78
+ * Primitives and known Three.js/Needle types are resolved precisely.
79
+ * For unknown types on a manifest component, falls back to
80
+ * `import("@needle-tools/engine").ComponentName["fieldName"]`.
81
+ * Truly unresolvable types → "unknown".
82
+ *
83
+ * @param {string} typeStr
84
+ * @param {string} [componentName] The manifest component class name (enables indexed-access fallback)
85
+ * @param {string} [fieldName] The field name on that component
86
+ * @returns {string}
87
+ */
88
+ export function manifestTypeToTs(typeStr, componentName, fieldName) {
89
+ const parts = typeStr.split(" | ").map(p => p.trim());
90
+ const safeParts = parts.map(p => {
91
+ if (p === "undefined" || p === "null") return p;
92
+ const arrayMatch = p.match(/^(number|string|boolean)\[\]$/);
93
+ if (arrayMatch) return p;
94
+ if (PRIMITIVE_TYPES.has(p)) return p;
95
+ const arrayTypeMatch = p.match(/^(\w+)\[\]$/);
96
+ if (arrayTypeMatch) {
97
+ const base = arrayTypeMatch[1];
98
+ const mapped = mapKnownType(base);
99
+ if (mapped) return `${mapped}[]`;
100
+ }
101
+ const known = mapKnownType(p);
102
+ if (known) return known;
103
+ return null;
104
+ });
105
+ if (safeParts.every(p => p !== null)) {
106
+ return /** @type {string[]} */ (safeParts).join(" | ");
107
+ }
108
+ if (componentName && fieldName) {
109
+ return `import("@needle-tools/engine").${componentName}["${fieldName}"]`;
110
+ }
111
+ return "unknown";
112
+ }
113
+
114
+ /**
115
+ * Load components.needle.json and build a lookup:
116
+ * componentName → Map<fieldName, tsType>
117
+ * Inherited fields are flattened (inheritedFrom chain is resolved).
118
+ *
119
+ * @returns {Map<string, Map<string, string>>}
120
+ */
121
+ export function loadComponentsManifest() {
122
+ /** @type {Map<string, Map<string, string>>} */
123
+ const manifest = new Map();
124
+ const manifestPath = join(__dirname, "../../components.needle.json");
125
+ if (!existsSync(manifestPath)) return manifest;
126
+ try {
127
+ /** @type {Array<{name: string, inheritedFrom?: string, children?: Array<{name: string, kind: string, type: string}>}>} */
128
+ const entries = JSON.parse(readFileSync(manifestPath, "utf8"));
129
+
130
+ /** @type {Map<string, Map<string, string>>} */
131
+ const ownFields = new Map();
132
+ /** @type {Map<string, string>} */
133
+ const inheritedFrom = new Map();
134
+ for (const entry of entries) {
135
+ if (!entry.name) continue;
136
+ inheritedFrom.set(entry.name, entry.inheritedFrom || "");
137
+ /** @type {Map<string, string>} */
138
+ const fields = new Map();
139
+ if (Array.isArray(entry.children)) {
140
+ for (const child of entry.children) {
141
+ if (child.kind === "property" && child.name && child.type) {
142
+ fields.set(child.name, manifestTypeToTs(child.type, entry.name, child.name));
143
+ }
144
+ }
145
+ }
146
+ ownFields.set(entry.name, fields);
147
+ }
148
+
149
+ /** @param {string} name @returns {Map<string, string>} */
150
+ function resolveFields(name) {
151
+ if (manifest.has(name)) return /** @type {Map<string, string>} */ (manifest.get(name));
152
+ const own = ownFields.get(name) ?? new Map();
153
+ const parent = inheritedFrom.get(name);
154
+ if (parent && ownFields.has(parent)) {
155
+ const parentFields = resolveFields(parent);
156
+ const merged = new Map([...parentFields, ...own]);
157
+ manifest.set(name, merged);
158
+ return merged;
159
+ }
160
+ manifest.set(name, own);
161
+ return own;
162
+ }
163
+
164
+ for (const name of ownFields.keys()) {
165
+ resolveFields(name);
166
+ }
167
+ } catch (e) {
168
+ console.warn("[needle:dts-generator] Failed to load components.needle.json:", (/** @type {any} */ (e))?.message ?? e);
169
+ }
170
+ return manifest;
171
+ }
172
+
173
+ /** @type {Map<string, Map<string, string>>} */
174
+ export const componentsManifest = loadComponentsManifest();
@@ -0,0 +1 @@
1
+ console.error('ERR: this is an old version of the gltf packer, please update gltf-pack in your package.json. The pack-gltf script should now look something like this: "npm run pack-gltf --prefix node_modules/@needle-tools/engine" \nSee the ExportInfo component for more info.');
@@ -33,10 +33,6 @@ export function needleLicense(command, config, userSettings) {
33
33
 
34
34
  },
35
35
  async transform(src, id) {
36
- if (appliedLicense === true) {
37
- return;
38
- }
39
-
40
36
  // Vite 4 and 8 handling:
41
37
  const isNeedleEngineFile = id.includes("engine/engine_license")
42
38
  || id.includes("needle-tools_engine")
@@ -53,12 +49,12 @@ export function needleLicense(command, config, userSettings) {
53
49
  let modified = false;
54
50
 
55
51
  // Replace license type
56
- const index = src.indexOf("_PQYikbj");
52
+ const index = src.indexOf("_TqYlV");
57
53
  if (index >= 0) {
58
54
  const end = src.indexOf(";", index);
59
55
  if (end >= 0) {
60
56
  const line = src.substring(index, end);
61
- const replaced = "_PQYikbj = \"" + licenseResult.type + "\"";
57
+ const replaced = "_TqYlV = \"" + licenseResult.type + "\"";
62
58
  src = src.replace(line, replaced);
63
59
  modified = true;
64
60
  }
@@ -66,13 +62,14 @@ export function needleLicense(command, config, userSettings) {
66
62
 
67
63
  // Replace license JWT (same pattern)
68
64
  if (licenseResult.jwt) {
69
- const jwtIndex = src.indexOf("_$QHon");
65
+ const jwtIndex = src.indexOf("_GYfnW");
70
66
  if (jwtIndex >= 0) {
71
67
  const jwtEnd = src.indexOf(";", jwtIndex);
72
68
  if (jwtEnd >= 0) {
73
69
  const jwtLine = src.substring(jwtIndex, jwtEnd);
74
- const jwtReplaced = "_$QHon = \"" + licenseResult.jwt + "\"";
70
+ const jwtReplaced = "_GYfnW = \"" + licenseResult.jwt + "\"";
75
71
  src = src.replace(jwtLine, jwtReplaced);
72
+ modified = true;
76
73
  }
77
74
  }
78
75
  }
@@ -81,7 +78,6 @@ export function needleLicense(command, config, userSettings) {
81
78
  appliedLicense = true;
82
79
  return { code: src, map: null }
83
80
  }
84
- // @TODO: detect local needle engine dev setup and log error if not found
85
81
  }
86
82
  },
87
83
  buildEnd() {
package/src/engine/api.ts CHANGED
@@ -230,7 +230,7 @@ export * from "./engine_input.js";
230
230
  export { InstancingUtil } from "./engine_instancing.js";
231
231
 
232
232
  /** License checking utilities */
233
- export { _BGpnKD, __tFkl, UFadk } from "./engine_license.js";
233
+ export { _$MQoX, $JOB, _DTayQW } from "./engine_license.js";
234
234
 
235
235
 
236
236
  // ============================================================================
@@ -8,7 +8,7 @@ import { initBuiltinTypes } from "./codegen/register_types.js";
8
8
  import { initSpatialConsole } from "./debug/debug_spatial_console.js";
9
9
  import { initAddressableSerializers } from "./engine_addressables.js";
10
10
  import { ensureAudioContextIsResumed } from "./engine_audio.js";
11
- import { rFPJwMWf } from "./engine_license.js";
11
+ import { _$PUXWQ } from "./engine_license.js";
12
12
  import { initNeedleLoader } from "./engine_loaders.js";
13
13
  import { initPhysics } from "./engine_physics_rapier.js";
14
14
  import { initBuiltinSerializers } from "./engine_serialization_builtin_serializer.js";
@@ -59,5 +59,5 @@ export function initEngine() {
59
59
  initPhysics();
60
60
  initXR();
61
61
  initSpatialConsole();
62
- rFPJwMWf();
62
+ _$PUXWQ();
63
63
  }
@@ -9,19 +9,19 @@ import { getParam } from "./engine_utils.js";
9
9
 
10
10
  const debug = getParam("__debuglic__");
11
11
 
12
- const dXgxU: ((result: boolean) => void)[] = [];
12
+ const $jvc: ((result: boolean) => void)[] = [];
13
13
 
14
14
  // These are modified by a bundler (e.g. vite)
15
15
  // Do not edit manually
16
- let _PQYikbj: string = "basic";
16
+ let _TqYlV: string = "basic";
17
17
  // eslint-disable-next-line prefer-const -- value is replaced by the bundler at build time
18
- let _$QHon: string = "";
18
+ let _GYfnW: string = "";
19
19
  if (debug) {
20
- console.log("License Type: " + _PQYikbj);
21
- if (_$QHon) {
22
- console.log("License JWT: " + _$QHon);
20
+ console.log("License Type: " + _TqYlV);
21
+ if (_GYfnW) {
22
+ console.log("License JWT: " + _GYfnW);
23
23
  try {
24
- const payload = JSON.parse(atob(_$QHon.split(".")[1].replace(/-/g, '+').replace(/_/g, '/')));
24
+ const payload = JSON.parse(atob(_GYfnW.split(".")[1].replace(/-/g, '+').replace(/_/g, '/')));
25
25
  console.log("License JWT payload:", payload);
26
26
  }
27
27
  catch { console.log("License JWT payload: (failed to decode)"); }
@@ -32,8 +32,8 @@ if (debug) {
32
32
  }
33
33
 
34
34
  /** @internal */
35
- export function UFadk() {
36
- switch (_PQYikbj) {
35
+ export function _DTayQW() {
36
+ switch (_TqYlV) {
37
37
  case "pro":
38
38
  case "enterprise":
39
39
  return true;
@@ -42,8 +42,8 @@ export function UFadk() {
42
42
  }
43
43
 
44
44
  /** @internal */
45
- export function __tFkl() {
46
- switch (_PQYikbj) {
45
+ export function $JOB() {
46
+ switch (_TqYlV) {
47
47
  case "indie":
48
48
  return true;
49
49
  }
@@ -51,8 +51,8 @@ export function __tFkl() {
51
51
  }
52
52
 
53
53
  /** @internal */
54
- export function rxRjHuj() {
55
- switch (_PQYikbj) {
54
+ export function __eNCB() {
55
+ switch (_TqYlV) {
56
56
  case "edu":
57
57
  return true;
58
58
  }
@@ -60,20 +60,20 @@ export function rxRjHuj() {
60
60
  }
61
61
 
62
62
  /** @internal */
63
- export function _BGpnKD() {
64
- return UFadk() || __tFkl() || rxRjHuj();
63
+ export function _$MQoX() {
64
+ return _DTayQW() || $JOB() || __eNCB();
65
65
  }
66
66
 
67
67
 
68
68
  /** @internal */
69
- export function __pLOnb(cb: (result: boolean) => void) {
70
- if (UFadk() || __tFkl() || rxRjHuj())
69
+ export function _HMnTDWqR(cb: (result: boolean) => void) {
70
+ if (_DTayQW() || $JOB() || __eNCB())
71
71
  return cb(true);
72
- dXgxU.push(cb);
72
+ $jvc.push(cb);
73
73
  }
74
74
 
75
- function _csklVr(result: boolean) {
76
- for (const cb of dXgxU) {
75
+ function wUuS(result: boolean) {
76
+ for (const cb of $jvc) {
77
77
  try {
78
78
  cb(result);
79
79
  }
@@ -88,7 +88,7 @@ function _csklVr(result: boolean) {
88
88
 
89
89
  // ECDSA P-256 public key for verifying license JWTs (verification-only, safe to ship)
90
90
  /* eslint-disable no-secrets/no-secrets -- public key, not a secret */
91
- const _$OYBbo = {
91
+ const $dnAvsc = {
92
92
  kty: "EC",
93
93
  crv: "P-256",
94
94
  x: "A34nyKMjhQYVgzeE4tyLUYdx34TAKogDa7v7PRaO9Lg",
@@ -112,7 +112,7 @@ function base64urlDecode(str: string): Uint8Array {
112
112
  * Verify a JWT license token and return the `type` claim if valid.
113
113
  * Returns null if the JWT is missing, malformed, or has an invalid signature.
114
114
  */
115
- async function GTeeZaHi(jwt: string): Promise<string | null> {
115
+ async function __YUuTdC(jwt: string): Promise<string | null> {
116
116
  if (!jwt) return null;
117
117
  try {
118
118
  const parts = jwt.split(".");
@@ -122,7 +122,7 @@ async function GTeeZaHi(jwt: string): Promise<string | null> {
122
122
 
123
123
  const key = await crypto.subtle.importKey(
124
124
  "jwk",
125
- _$OYBbo,
125
+ $dnAvsc,
126
126
  { name: "ECDSA", namedCurve: "P-256" },
127
127
  false,
128
128
  ["verify"]
@@ -182,23 +182,23 @@ async function GTeeZaHi(jwt: string): Promise<string | null> {
182
182
  }
183
183
 
184
184
  /** Verify the injected JWT and update the license type if valid.
185
- * The engine ONLY trusts the JWT — the plain _PQYikbj string is ignored. */
185
+ * The engine ONLY trusts the JWT — the plain _TqYlV string is ignored. */
186
186
  let _jwtVerificationPromise: Promise<void> | undefined = undefined;
187
- async function $sATIKYrT(): Promise<void> {
188
- if (!_$QHon) {
189
- // No JWT present: license stays "basic" regardless of what _PQYikbj says
190
- _PQYikbj = "basic";
187
+ async function _$tvXXHlah(): Promise<void> {
188
+ if (!_GYfnW) {
189
+ // No JWT present: license stays "basic" regardless of what _TqYlV says
190
+ _TqYlV = "basic";
191
191
  return;
192
192
  }
193
- const verifiedType = await GTeeZaHi(_$QHon);
193
+ const verifiedType = await __YUuTdC(_GYfnW);
194
194
  if (verifiedType) {
195
- _PQYikbj = verifiedType;
195
+ _TqYlV = verifiedType;
196
196
  if (debug) console.log("License type set from verified JWT: " + verifiedType);
197
- _csklVr(_BGpnKD());
197
+ wUuS(_$MQoX());
198
198
  }
199
199
  else {
200
200
  // JWT present but invalid: reset to basic
201
- _PQYikbj = "basic";
201
+ _TqYlV = "basic";
202
202
  if (debug) console.warn("JWT verification failed — license reset to basic");
203
203
  }
204
204
  }
@@ -270,7 +270,7 @@ export namespace Telemetry {
270
270
 
271
271
  const attribute = domElement?.getAttribute("no-telemetry");
272
272
  if (attribute === "" || attribute === "true" || attribute === "1") {
273
- if (_PQYikbj === "pro" || _PQYikbj === "enterprise") {
273
+ if (_TqYlV === "pro" || _TqYlV === "enterprise") {
274
274
  if (debug) console.debug("Telemetry is disabled via no-telemetry attribute");
275
275
  return false;
276
276
  }
@@ -377,29 +377,29 @@ export namespace Telemetry {
377
377
  }
378
378
 
379
379
 
380
- export function rFPJwMWf() {
380
+ export function _$PUXWQ() {
381
381
  // Start JWT verification — must be here (not top-level) to avoid tree-shaking
382
- _jwtVerificationPromise = $sATIKYrT();
382
+ _jwtVerificationPromise = _$tvXXHlah();
383
383
 
384
384
  Telemetry.init();
385
385
  ContextRegistry.registerCallback(ContextEvent.ContextRegistered, evt => {
386
- __loEAQjNJ(evt.context);
387
- __msk(evt.context);
388
- setTimeout(() => $tlH(evt.context), 2000);
386
+ $lHQle(evt.context);
387
+ _$dIKVrNJ(evt.context);
388
+ setTimeout(() => _mRKmGB(evt.context), 2000);
389
389
  });
390
390
  }
391
391
 
392
- export let _$YsQVksF: Promise<void> | undefined = undefined;
392
+ export let _$vBFuyQsS: Promise<void> | undefined = undefined;
393
393
  let applicationIsForbidden = false;
394
394
  let applicationForbiddenText = "";
395
- async function _fYB() {
395
+ async function _xWdntM() {
396
396
  // Only perform the runtime license check once
397
- if (_$YsQVksF) return _$YsQVksF;
397
+ if (_$vBFuyQsS) return _$vBFuyQsS;
398
398
  // Wait for JWT verification to complete first (if running)
399
399
  if (_jwtVerificationPromise) {
400
400
  await _jwtVerificationPromise;
401
401
  }
402
- if (_PQYikbj === "basic") {
402
+ if (_TqYlV === "basic") {
403
403
  try {
404
404
  const licenseUrl = "https://needle.tools/api/v1/needle-engine/check?location=" + encodeURIComponent(window.location.href) + "&version=" + VERSION + "&generator=" + encodeURIComponent(GENERATOR);
405
405
  const res = await fetch(licenseUrl, {
@@ -411,29 +411,29 @@ async function _fYB() {
411
411
  if (res?.status === 200) {
412
412
  applicationIsForbidden = false;
413
413
  if (debug) console.log("License check succeeded");
414
- _PQYikbj = "pro";
415
- _csklVr(true);
414
+ _TqYlV = "pro";
415
+ wUuS(true);
416
416
  }
417
417
  else if (res?.status === 403) {
418
- _csklVr(false);
418
+ wUuS(false);
419
419
  applicationIsForbidden = true;
420
420
  applicationForbiddenText = await res.text();
421
421
  }
422
422
  else {
423
- _csklVr(false);
423
+ wUuS(false);
424
424
  if (debug) console.log("License check failed with status " + res?.status);
425
425
  }
426
426
  }
427
427
  catch (err) {
428
- _csklVr(false);
428
+ wUuS(false);
429
429
  if (debug) console.error("License check failed", err);
430
430
  }
431
431
  }
432
- else if (debug) console.log("Runtime license check is skipped because license is already applied as \"" + _PQYikbj + "\"");
432
+ else if (debug) console.log("Runtime license check is skipped because license is already applied as \"" + _TqYlV + "\"");
433
433
  }
434
- _$YsQVksF = _fYB();
434
+ _$vBFuyQsS = _xWdntM();
435
435
 
436
- async function __msk(ctx: IContext) {
436
+ async function _$dIKVrNJ(ctx: IContext) {
437
437
  function createForbiddenElement() {
438
438
  const div = document.createElement("div");
439
439
  div.className = "needle-forbidden";
@@ -498,40 +498,40 @@ async function __msk(ctx: IContext) {
498
498
  }, 500)
499
499
  }
500
500
 
501
- async function __loEAQjNJ(ctx: IContext) {
501
+ async function $lHQle(ctx: IContext) {
502
502
  try {
503
- if (!UFadk() && !__tFkl()) {
504
- return __pJSUSLs(ctx);
503
+ if (!_DTayQW() && !$JOB()) {
504
+ return LkcJKXX(ctx);
505
505
  }
506
506
  }
507
507
  catch (err) {
508
508
  if (debug) console.log("License check failed", err)
509
- return __pJSUSLs(ctx)
509
+ return LkcJKXX(ctx)
510
510
  }
511
- if (debug) __pJSUSLs(ctx)
511
+ if (debug) LkcJKXX(ctx)
512
512
  }
513
513
 
514
514
 
515
515
 
516
- async function __pJSUSLs(ctx: IContext) {
516
+ async function LkcJKXX(ctx: IContext) {
517
517
 
518
518
  // if the engine loads faster than the license check, we need to capture the ready event here
519
519
  let isReady = false;
520
520
  ctx.domElement.addEventListener("ready", () => isReady = true);
521
521
 
522
- await _$YsQVksF?.catch(() => { });
522
+ await _$vBFuyQsS?.catch(() => { });
523
523
 
524
524
 
525
- if (UFadk() || __tFkl()) return;
526
- if (_BGpnKD() === false) _ArTbiTUU();
525
+ if (_DTayQW() || $JOB()) return;
526
+ if (_$MQoX() === false) __Dnv();
527
527
 
528
528
  // check if the engine is already ready (meaning has finished loading)
529
529
  if (isReady) {
530
- _$gRXdD(ctx);
530
+ $ThBU(ctx);
531
531
  }
532
532
  else {
533
533
  ctx.domElement.addEventListener("ready", () => {
534
- _$gRXdD(ctx);
534
+ $ThBU(ctx);
535
535
  });
536
536
  }
537
537
  }
@@ -539,7 +539,7 @@ async function __pJSUSLs(ctx: IContext) {
539
539
  // const licenseElementIdentifier = "needle-license-element";
540
540
  // const licenseDuration = 10000;
541
541
  // const licenseDelay = 1200;
542
- function _$gRXdD(ctx: IContext) {
542
+ function $ThBU(ctx: IContext) {
543
543
 
544
544
  const style = `
545
545
  position: relative;
@@ -552,7 +552,7 @@ function _$gRXdD(ctx: IContext) {
552
552
  padding: 10px;
553
553
  padding-left: 30px;
554
554
  `;
555
- if (_PQYikbj === "edu") {
555
+ if (_TqYlV === "edu") {
556
556
  if (navigator.webdriver) {
557
557
  console.log("This project is supported by Needle for Education – https://needle.tools");
558
558
  }
@@ -609,7 +609,7 @@ function _$gRXdD(ctx: IContext) {
609
609
  }
610
610
  }, 1000);
611
611
 
612
- if (rxRjHuj()) {
612
+ if (__eNCB()) {
613
613
  const removeDelay = 20_000;
614
614
  setTimeout(() => {
615
615
  clearInterval(interval);
@@ -618,7 +618,7 @@ function _$gRXdD(ctx: IContext) {
618
618
  const intervalInMinutes = 5;
619
619
  setTimeout(() => {
620
620
  if (ctx.domElement.parentNode)
621
- _$gRXdD(ctx);
621
+ $ThBU(ctx);
622
622
  }, 1000 * 60 * intervalInMinutes)
623
623
  }, removeDelay);
624
624
  }
@@ -629,7 +629,7 @@ function _$gRXdD(ctx: IContext) {
629
629
  const base64Logo = "data:image/webp;base64,UklGRrABAABXRUJQVlA4WAoAAAAQAAAAHwAAHwAAQUxQSKEAAAARN6CmbSM4WR7vdARON11EBDq3fLiNbVtVzpMCPlKAEzsx0Y/x+Ovuv4dn0EFE/ydAvz6YggXzgh5sVgXM/zOC/4sii7qgGvB5N7hmuQYwkvazWAu1JPW41FXSHq6pnaQWvqYH18Fc0j1hO/BFTtIeSBlJi5w6qIIO7IOrwhFsB2Yxukif0FTRLpXswHR8MxbslKe9VZsn/Ub5C7YFOpqSTABWUDgg6AAAAFAGAJ0BKiAAIAA+7VyoTqmkpCI3+qgBMB2JbACdMt69DwMIQBLhkTO6XwY00UEDK6cNIDnuNibPf0EgAP7Y1myuiQHLDsF/0h5unrGh6WAbv7aegg2ZMd3uRKfT/3SJztcaujYfTvMXspfCTmYcoO6a+vhC3ss4M8uM58t4siiu59I4aOl59e9Sr6xoxYlHf2v+NnBNpJYeJf8jABQAId/PXuBkLEFkiCucgSGEcfhvajql/j3reCGl0M5/9gQWy7ayNPs+wlvIxFnNfSlfuND4CZOCyxOHhRqOmHN4ULHo3tCSrUNvgAA=";
630
630
 
631
631
  let lastLogTime = 0;
632
- async function _ArTbiTUU(_logo?: string) {
632
+ async function __Dnv(_logo?: string) {
633
633
  const now = Date.now();
634
634
  if (now - lastLogTime < 2000) return;
635
635
  lastLogTime = now;
@@ -662,7 +662,7 @@ async function _ArTbiTUU(_logo?: string) {
662
662
  }
663
663
 
664
664
 
665
- async function $tlH(context: IContext) {
665
+ async function _mRKmGB(context: IContext) {
666
666
  // We can't send beacons from cross-origin isolated pages
667
667
  if (window.crossOriginIsolated) return;
668
668
 
@@ -677,7 +677,7 @@ async function $tlH(context: IContext) {
677
677
 
678
678
  // current url without query parameters
679
679
  const currentUrl = window.location.href.split("?")[0];
680
- const license = _PQYikbj;
680
+ const license = _TqYlV;
681
681
 
682
682
  const beaconData = {
683
683
  license,
@@ -1,7 +1,7 @@
1
1
  import { FileLoader } from "three";
2
2
 
3
3
  import { showBalloonWarning } from "./debug/index.js";
4
- import { _BGpnKD } from "./engine_license.js";
4
+ import { _$MQoX } from "./engine_license.js";
5
5
  import { delay } from "./engine_utils.js";
6
6
  import { md5AsBytes, md5Hex, sha256Base64 } from "./engine_utils_hash.js";
7
7
 
@@ -45,7 +45,7 @@ export namespace BlobStorage {
45
45
  */
46
46
  export function canUpload(info: { filesize: number }) {
47
47
  const sizeInMB = info.filesize / 1024 / 1024;
48
- if (_BGpnKD()) {
48
+ if (_$MQoX()) {
49
49
  return sizeInMB < maxSizeInMB;
50
50
  }
51
51
  return sizeInMB < maxFreeSizeInMB;
@@ -100,7 +100,7 @@ export namespace BlobStorage {
100
100
  console.warn(`Your file is too large for uploading (${filesizeInMB.toFixed(1)}MB). Max allowed size is ${maxSizeInMB}MB`);
101
101
  return null;
102
102
  }
103
- else if (!_BGpnKD() && filesizeInMB > maxFreeSizeInMB) {
103
+ else if (!_$MQoX() && filesizeInMB > maxFreeSizeInMB) {
104
104
  if (opts?.silent !== true) showBalloonWarning(`File is too large for uploading. Please get a <a href=\"https://needle.tools/pricing\" target=\"_blank\">commercial license</a> to upload files larger than 5MB`);
105
105
  console.warn(`Your file is too large for uploading (${filesizeInMB.toFixed(1)}MB). Max size is 5MB for non-commercial users. Please get a commercial license at https://needle.tools/pricing for larger files (up to 50MB)`);
106
106
  return null;