@ar-js-org/artoolkit5-ts 0.2.0 → 0.2.2

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.
@@ -143,22 +143,23 @@ function I(e) {
143
143
  function L(e) {
144
144
  let t = [], n = e.core.getMarkerNum();
145
145
  for (let r = 0; r < n; r++) {
146
- let n = e.core.getMarkerInfo(r), i = R(e.patternMarkers, e, r, n.idPatt, n.cfPatt, "pattern", e.minConfidence.pattern);
146
+ let n = e.core.getMarkerInfo(r), i = R(e.patternMarkers, e, r, n.idPatt, n.cfPatt, "pattern", e.minConfidence.pattern, n.vertex);
147
147
  i && t.push(i);
148
- let a = R(e.barcodeMarkers, e, r, n.idMatrix, n.cfMatrix, "barcode", e.minConfidence.barcode);
148
+ let a = R(e.barcodeMarkers, e, r, n.idMatrix, n.cfMatrix, "barcode", e.minConfidence.barcode, n.vertex);
149
149
  a && t.push(a);
150
150
  }
151
151
  return t;
152
152
  }
153
- function R(e, t, n, r, i, a, o) {
153
+ function R(e, t, n, r, i, a, o, s) {
154
154
  if (r === D) return;
155
- let s = e[r];
156
- if (s && !(i < o)) return s.inCurrent = !0, B(t, n, s), {
157
- id: s.id,
155
+ let c = e[r];
156
+ if (c && !(i < o)) return c.inCurrent = !0, B(t, n, c), {
157
+ id: c.id,
158
158
  type: a,
159
159
  confidence: i,
160
- matrix: s.matrix,
161
- matrixGL: s.matrixGL
160
+ matrix: c.matrix,
161
+ matrixGL: c.matrixGL,
162
+ vertex: s
162
163
  };
163
164
  }
164
165
  function z(e) {
@@ -1 +1 @@
1
- (function(e,t){typeof exports==`object`&&typeof module<`u`?t(exports,require("@ar-js-org/artoolkit5-wasm")):typeof define==`function`&&define.amd?define([`exports`,`@ar-js-org/artoolkit5-wasm`],t):(e=typeof globalThis<`u`?globalThis:e||self,t(e.ARToolkit5TS={},e.ARToolkit5Wasm))})(this,function(e,t){Object.defineProperty(e,Symbol.toStringTag,{value:`Module`});var n=class e extends Error{constructor(t){super(t),this.name=`ARToolKitError`,Object.setPrototypeOf(this,e.prototype)}};function r(e,t){if(e.disposed)throw new n(`${t} was called on a disposed ARToolKitState. Create a new one with createARToolKitState().`)}async function i(e,n,r,i){let a=(await(0,t.createARToolKit)({locateFile:e=>i&&e.endsWith(`.wasm`)?i:e})).mod,o=new a.ARToolKitCore,s=await(0,t.loadCameraFromUrl)(a,o,r);return await o.setup(e,n,s),{mod:a,core:o,width:e,height:n,patternMarkers:{},barcodeMarkers:{},minConfidence:{pattern:0,barcode:0},disposed:!1}}function a(e){e.disposed||=(e.core.teardown(),e.core.delete(),e.patternMarkers={},e.barcodeMarkers={},!0)}var o=1028,s=1029,c=1285,l={color:0,mono:1,matrix:2,color_and_matrix:3,mono_and_matrix:4},u={"3x3":3,"3x3_PARITY65":259,"3x3_HAMMING63":515,"4x4":4,"4x4_BCH_13_9_3":772,"4x4_BCH_13_5_5":o,"5x5":5,"5x5_BCH_22_7_7":c,"5x5_BCH_22_12_5":s,"6x6":6},d={manual:0,auto_median:1,auto_otsu:2,auto_bracketing:4},f={frame:0,field:1},p={white_region:0,black_region:1};function m(e,t,r){let i=Object.prototype.hasOwnProperty.call(e,t)?e[t]:void 0;if(i===void 0){let i=Object.keys(e).join(`, `);throw new n(`Invalid value ${JSON.stringify(t)} for '${r}'. Valid values are: ${i}.`)}return i}function h(e,t){if(r(e,`configureDetector`),t.detectionMode!==void 0&&e.core.setPatternDetectionMode(m(l,t.detectionMode,`detectionMode`)),t.matrixCodeType!==void 0&&e.core.setMatrixCodeType(m(u,t.matrixCodeType,`matrixCodeType`)),t.threshold!==void 0&&e.core.setThreshold(g(t.threshold)),t.thresholdMode!==void 0&&e.core.setThresholdMode(m(d,t.thresholdMode,`thresholdMode`)),t.labelingMode!==void 0&&e.core.setLabelingMode(m(p,t.labelingMode,`labelingMode`)),t.imageProcMode!==void 0&&e.core.setImageProcMode(m(f,t.imageProcMode,`imageProcMode`)),t.patternRatio!==void 0&&e.core.setPattRatio(_(t.patternRatio)),t.minConfidence!==void 0){let{pattern:n,barcode:r}=t.minConfidence;n!==void 0&&(e.minConfidence.pattern=v(n,`minConfidence.pattern`)),r!==void 0&&(e.minConfidence.barcode=v(r,`minConfidence.barcode`))}t.nearPlane!==void 0&&e.core.setProjectionNearPlane(t.nearPlane),t.farPlane!==void 0&&e.core.setProjectionFarPlane(t.farPlane),(t.nearPlane!==void 0||t.farPlane!==void 0)&&e.core.recalculateCameraLens()}function g(e){if(!Number.isInteger(e)||e<0||e>255)throw new n(`Invalid value ${e} for 'threshold'. Must be an integer between 0 and 255 inclusive.`);return e}function _(e){if(!Number.isFinite(e)||e<=0||e>=1)throw new n(`Invalid value ${e} for 'patternRatio'. Must be a finite number greater than 0 and less than 1.`);return e}function v(e,t){if(!Number.isFinite(e)||e<0||e>1)throw new n(`Invalid value ${e} for '${t}'. Must be a finite number between 0 and 1 inclusive.`);return e}async function y(e,n){return r(e,`loadPatternMarker`),(0,t.addMarkerFromUrl)(e.mod,e.core,n)}var b=16;function x(e){return r(e,`getCameraProjectionMatrix`),e.core.getCameraLens()}function S(e,t=new Float32Array(b)){return t[0]=e[0],t[1]=e[4],t[2]=e[8],t[3]=0,t[4]=e[1],t[5]=e[5],t[6]=e[9],t[7]=0,t[8]=e[2],t[9]=e[6],t[10]=e[10],t[11]=0,t[12]=e[3],t[13]=e[7],t[14]=e[11],t[15]=1,t}function C(e,t=new Float32Array(b),n){return t[0]=e[0],t[4]=e[4],t[8]=e[8],t[12]=e[12],t[1]=-e[1],t[5]=-e[5],t[9]=-e[9],t[13]=-e[13],t[2]=-e[2],t[6]=-e[6],t[10]=-e[10],t[14]=-e[14],t[3]=0,t[7]=0,t[11]=0,t[15]=1,n!==void 0&&n!==0&&(t[12]*=n,t[13]*=n,t[14]*=n),t}var w=12,T=3,E=-1,D=[],O=!0,k=new Float32Array(16);function A(e,t,n=1){r(e,`trackMarker`),e.patternMarkers[t]=M(t,n)}function j(e,t,n=1){r(e,`trackBarcodeMarker`),e.barcodeMarkers[t]=M(t,n)}function M(e,t){return{id:e,markerWidth:t,inPrevious:!1,inCurrent:!1,matrix:new Float64Array(w),matrixGL:new Float32Array(16)}}function N(e,t){return r(e,`processFrame`),P(e,t),F(e),{detected:I(e),lost:R(e)}}function P(e,t){e.core.passVideoData(t,D,O),e.core.detectMarker()}function F(e){for(let t of[e.patternMarkers,e.barcodeMarkers])for(let e in t){let n=t[e];n.inPrevious=n.inCurrent,n.inCurrent=!1}}function I(e){let t=[],n=e.core.getMarkerNum();for(let r=0;r<n;r++){let n=e.core.getMarkerInfo(r),i=L(e.patternMarkers,e,r,n.idPatt,n.cfPatt,`pattern`,e.minConfidence.pattern);i&&t.push(i);let a=L(e.barcodeMarkers,e,r,n.idMatrix,n.cfMatrix,`barcode`,e.minConfidence.barcode);a&&t.push(a)}return t}function L(e,t,n,r,i,a,o){if(r===E)return;let s=e[r];if(s&&!(i<o))return s.inCurrent=!0,z(t,n,s),{id:s.id,type:a,confidence:i,matrix:s.matrix,matrixGL:s.matrixGL}}function R(e){let t=[],n=[[e.patternMarkers,`pattern`],[e.barcodeMarkers,`barcode`]];for(let[e,r]of n)for(let n in e){let i=e[n];i.inPrevious&&!i.inCurrent&&t.push({id:i.id,type:r})}return t}function z(e,t,n){n.inPrevious?e.core.getTransMatSquareCont(t,n.markerWidth):e.core.getTransMatSquare(t,n.markerWidth),B(e,n.matrix),S(n.matrix,k),C(k,n.matrixGL)}function B(e,t){let n=e.core.getTransform()>>T;t.set(e.mod.HEAPF64.subarray(n,n+w))}e.ARToolKitError=n,e.arglCameraViewRHf=C,e.configureDetector=h,e.createARToolKitState=i,e.disposeARToolKitState=a,e.getCameraProjectionMatrix=x,e.loadPatternMarker=y,e.processFrame=N,e.trackBarcodeMarker=j,e.trackMarker=A,e.transMatToGLMat=S});
1
+ (function(e,t){typeof exports==`object`&&typeof module<`u`?t(exports,require("@ar-js-org/artoolkit5-wasm")):typeof define==`function`&&define.amd?define([`exports`,`@ar-js-org/artoolkit5-wasm`],t):(e=typeof globalThis<`u`?globalThis:e||self,t(e.ARToolkit5TS={},e.ARToolkit5Wasm))})(this,function(e,t){Object.defineProperty(e,Symbol.toStringTag,{value:`Module`});var n=class e extends Error{constructor(t){super(t),this.name=`ARToolKitError`,Object.setPrototypeOf(this,e.prototype)}};function r(e,t){if(e.disposed)throw new n(`${t} was called on a disposed ARToolKitState. Create a new one with createARToolKitState().`)}async function i(e,n,r,i){let a=(await(0,t.createARToolKit)({locateFile:e=>i&&e.endsWith(`.wasm`)?i:e})).mod,o=new a.ARToolKitCore,s=await(0,t.loadCameraFromUrl)(a,o,r);return await o.setup(e,n,s),{mod:a,core:o,width:e,height:n,patternMarkers:{},barcodeMarkers:{},minConfidence:{pattern:0,barcode:0},disposed:!1}}function a(e){e.disposed||=(e.core.teardown(),e.core.delete(),e.patternMarkers={},e.barcodeMarkers={},!0)}var o=1028,s=1029,c=1285,l={color:0,mono:1,matrix:2,color_and_matrix:3,mono_and_matrix:4},u={"3x3":3,"3x3_PARITY65":259,"3x3_HAMMING63":515,"4x4":4,"4x4_BCH_13_9_3":772,"4x4_BCH_13_5_5":o,"5x5":5,"5x5_BCH_22_7_7":c,"5x5_BCH_22_12_5":s,"6x6":6},d={manual:0,auto_median:1,auto_otsu:2,auto_bracketing:4},f={frame:0,field:1},p={white_region:0,black_region:1};function m(e,t,r){let i=Object.prototype.hasOwnProperty.call(e,t)?e[t]:void 0;if(i===void 0){let i=Object.keys(e).join(`, `);throw new n(`Invalid value ${JSON.stringify(t)} for '${r}'. Valid values are: ${i}.`)}return i}function h(e,t){if(r(e,`configureDetector`),t.detectionMode!==void 0&&e.core.setPatternDetectionMode(m(l,t.detectionMode,`detectionMode`)),t.matrixCodeType!==void 0&&e.core.setMatrixCodeType(m(u,t.matrixCodeType,`matrixCodeType`)),t.threshold!==void 0&&e.core.setThreshold(g(t.threshold)),t.thresholdMode!==void 0&&e.core.setThresholdMode(m(d,t.thresholdMode,`thresholdMode`)),t.labelingMode!==void 0&&e.core.setLabelingMode(m(p,t.labelingMode,`labelingMode`)),t.imageProcMode!==void 0&&e.core.setImageProcMode(m(f,t.imageProcMode,`imageProcMode`)),t.patternRatio!==void 0&&e.core.setPattRatio(_(t.patternRatio)),t.minConfidence!==void 0){let{pattern:n,barcode:r}=t.minConfidence;n!==void 0&&(e.minConfidence.pattern=v(n,`minConfidence.pattern`)),r!==void 0&&(e.minConfidence.barcode=v(r,`minConfidence.barcode`))}t.nearPlane!==void 0&&e.core.setProjectionNearPlane(t.nearPlane),t.farPlane!==void 0&&e.core.setProjectionFarPlane(t.farPlane),(t.nearPlane!==void 0||t.farPlane!==void 0)&&e.core.recalculateCameraLens()}function g(e){if(!Number.isInteger(e)||e<0||e>255)throw new n(`Invalid value ${e} for 'threshold'. Must be an integer between 0 and 255 inclusive.`);return e}function _(e){if(!Number.isFinite(e)||e<=0||e>=1)throw new n(`Invalid value ${e} for 'patternRatio'. Must be a finite number greater than 0 and less than 1.`);return e}function v(e,t){if(!Number.isFinite(e)||e<0||e>1)throw new n(`Invalid value ${e} for '${t}'. Must be a finite number between 0 and 1 inclusive.`);return e}async function y(e,n){return r(e,`loadPatternMarker`),(0,t.addMarkerFromUrl)(e.mod,e.core,n)}var b=16;function x(e){return r(e,`getCameraProjectionMatrix`),e.core.getCameraLens()}function S(e,t=new Float32Array(b)){return t[0]=e[0],t[1]=e[4],t[2]=e[8],t[3]=0,t[4]=e[1],t[5]=e[5],t[6]=e[9],t[7]=0,t[8]=e[2],t[9]=e[6],t[10]=e[10],t[11]=0,t[12]=e[3],t[13]=e[7],t[14]=e[11],t[15]=1,t}function C(e,t=new Float32Array(b),n){return t[0]=e[0],t[4]=e[4],t[8]=e[8],t[12]=e[12],t[1]=-e[1],t[5]=-e[5],t[9]=-e[9],t[13]=-e[13],t[2]=-e[2],t[6]=-e[6],t[10]=-e[10],t[14]=-e[14],t[3]=0,t[7]=0,t[11]=0,t[15]=1,n!==void 0&&n!==0&&(t[12]*=n,t[13]*=n,t[14]*=n),t}var w=12,T=3,E=-1,D=[],O=!0,k=new Float32Array(16);function A(e,t,n=1){r(e,`trackMarker`),e.patternMarkers[t]=M(t,n)}function j(e,t,n=1){r(e,`trackBarcodeMarker`),e.barcodeMarkers[t]=M(t,n)}function M(e,t){return{id:e,markerWidth:t,inPrevious:!1,inCurrent:!1,matrix:new Float64Array(w),matrixGL:new Float32Array(16)}}function N(e,t){return r(e,`processFrame`),P(e,t),F(e),{detected:I(e),lost:R(e)}}function P(e,t){e.core.passVideoData(t,D,O),e.core.detectMarker()}function F(e){for(let t of[e.patternMarkers,e.barcodeMarkers])for(let e in t){let n=t[e];n.inPrevious=n.inCurrent,n.inCurrent=!1}}function I(e){let t=[],n=e.core.getMarkerNum();for(let r=0;r<n;r++){let n=e.core.getMarkerInfo(r),i=L(e.patternMarkers,e,r,n.idPatt,n.cfPatt,`pattern`,e.minConfidence.pattern,n.vertex);i&&t.push(i);let a=L(e.barcodeMarkers,e,r,n.idMatrix,n.cfMatrix,`barcode`,e.minConfidence.barcode,n.vertex);a&&t.push(a)}return t}function L(e,t,n,r,i,a,o,s){if(r===E)return;let c=e[r];if(c&&!(i<o))return c.inCurrent=!0,z(t,n,c),{id:c.id,type:a,confidence:i,matrix:c.matrix,matrixGL:c.matrixGL,vertex:s}}function R(e){let t=[],n=[[e.patternMarkers,`pattern`],[e.barcodeMarkers,`barcode`]];for(let[e,r]of n)for(let n in e){let i=e[n];i.inPrevious&&!i.inCurrent&&t.push({id:i.id,type:r})}return t}function z(e,t,n){n.inPrevious?e.core.getTransMatSquareCont(t,n.markerWidth):e.core.getTransMatSquare(t,n.markerWidth),B(e,n.matrix),S(n.matrix,k),C(k,n.matrixGL)}function B(e,t){let n=e.core.getTransform()>>T;t.set(e.mod.HEAPF64.subarray(n,n+w))}e.ARToolKitError=n,e.arglCameraViewRHf=C,e.configureDetector=h,e.createARToolKitState=i,e.disposeARToolKitState=a,e.getCameraProjectionMatrix=x,e.loadPatternMarker=y,e.processFrame=N,e.trackBarcodeMarker=j,e.trackMarker=A,e.transMatToGLMat=S});
package/dist/domain.d.ts CHANGED
@@ -57,6 +57,20 @@ export interface MarkerPose {
57
57
  * camera noise and calibration in the millimetre range.
58
58
  */
59
59
  matrixGL: Float32Array;
60
+ /**
61
+ * The four corners of the detected square, in camera image coordinates
62
+ * with the origin at top-left.
63
+ *
64
+ * Unlike `matrix` and `matrixGL`, this is **not** a view onto a reused
65
+ * buffer — the engine builds a fresh array each frame, so it is safe to
66
+ * retain without copying.
67
+ *
68
+ * Corner order depends on the marker's rotation: `vertex[(4 - dir) % 4]`
69
+ * is the top-left corner of the marker itself, with the rest proceeding
70
+ * clockwise from there. Anything that merely outlines the square can
71
+ * ignore that; anything orientation-sensitive cannot.
72
+ */
73
+ vertex: [number, number][];
60
74
  }
61
75
  /**
62
76
  * Outcome of a single call to `processFrame`.
@@ -143,6 +157,12 @@ export interface MarkerInfo {
143
157
  cfPatt: number;
144
158
  /** Matrix-code confidence, 0.0-1.0, or -1.0 when there was no match. */
145
159
  cfMatrix: number;
160
+ /**
161
+ * 2D positions of the square's four corners, in camera image coordinates
162
+ * with the origin at top-left. Populated in every detection mode, unlike
163
+ * the id and confidence fields above.
164
+ */
165
+ vertex: [number, number][];
146
166
  }
147
167
  /**
148
168
  * The C++ `ARToolKitCore` instance, narrowed to the methods this library calls.
@@ -39,9 +39,11 @@ export declare function trackBarcodeMarker(state: ARToolKitState, barcodeId: num
39
39
  * so a consumer emitting found/updated/lost events does not have to diff
40
40
  * successive results to recover information tracking already had.
41
41
  *
42
- * Called once per animation frame, so it allocates no typed arrays: every pose
43
- * is written into buffers owned by the marker's tracking state. Those buffers
44
- * are reused next frame — copy them if you need to retain values.
42
+ * Called once per animation frame, so it allocates no typed arrays: `matrix`
43
+ * and `matrixGL` are written into buffers owned by the marker's tracking
44
+ * state, and those buffers are reused next frame — copy them if you need to
45
+ * retain values. `vertex` is the exception; it is a fresh array every frame
46
+ * and can be retained as it is.
45
47
  *
46
48
  * @param videoFrame RGBA pixels matching the width and height the state was
47
49
  * created with.
package/package.json CHANGED
@@ -1,69 +1,69 @@
1
- {
2
- "name": "@ar-js-org/artoolkit5-ts",
3
- "version": "0.2.0",
4
- "private": false,
5
- "type": "module",
6
- "description": "TypeScript marker tracking for the browser, built on a WebAssembly build of ARToolkit5 (WebARKitLib). Composable and tree-shakeable: state is plain data, operations are functions.",
7
- "keywords": [
8
- "artoolkit",
9
- "artoolkit5",
10
- "augmented-reality",
11
- "ar",
12
- "webar",
13
- "marker-tracking",
14
- "barcode-marker",
15
- "webassembly",
16
- "wasm",
17
- "typescript",
18
- "ar.js",
19
- "webarkit"
20
- ],
21
- "license": "MIT",
22
- "author": {
23
- "name": "Walter Perdan",
24
- "url": "https://github.com/kalwalt"
25
- },
26
- "repository": {
27
- "type": "git",
28
- "url": "git+https://github.com/AR-js-org/artoolkit5-ts.git"
29
- },
30
- "bugs": {
31
- "url": "https://github.com/AR-js-org/artoolkit5-ts/issues"
32
- },
33
- "homepage": "https://github.com/AR-js-org/artoolkit5-ts#readme",
34
- "main": "./dist/artoolkit5-ts.umd.cjs",
35
- "module": "./dist/artoolkit5-ts.js",
36
- "types": "./dist/index.d.ts",
37
- "exports": {
38
- ".": {
39
- "types": "./dist/index.d.ts",
40
- "import": "./dist/artoolkit5-ts.js",
41
- "require": "./dist/artoolkit5-ts.umd.cjs"
42
- }
43
- },
44
- "files": [
45
- "dist",
46
- "CHANGELOG.md"
47
- ],
48
- "scripts": {
49
- "dev": "vite",
50
- "build": "vite build && tsc -p tsconfig.build.json",
51
- "preview": "vite preview",
52
- "test": "vitest run",
53
- "test:watch": "vitest",
54
- "typecheck": "tsc --noEmit -p tsconfig.json",
55
- "release-notes": "node scripts/release-notes.mjs"
56
- },
57
- "dependencies": {
58
- "@ar-js-org/artoolkit5-constants": "^0.3.0",
59
- "@ar-js-org/artoolkit5-wasm": "^0.3.0"
60
- },
61
- "devDependencies": {
62
- "@types/node": "^26.0.1",
63
- "@types/three": "^0.185.0",
64
- "three": "^0.185.0",
65
- "typescript": "^6.0.3",
66
- "vite": "^8.1.0",
67
- "vitest": "^4.1.10"
68
- }
69
- }
1
+ {
2
+ "name": "@ar-js-org/artoolkit5-ts",
3
+ "version": "0.2.2",
4
+ "private": false,
5
+ "type": "module",
6
+ "description": "TypeScript marker tracking for the browser, built on a WebAssembly build of ARToolkit5 (WebARKitLib). Composable and tree-shakeable: state is plain data, operations are functions.",
7
+ "keywords": [
8
+ "artoolkit",
9
+ "artoolkit5",
10
+ "augmented-reality",
11
+ "ar",
12
+ "webar",
13
+ "marker-tracking",
14
+ "barcode-marker",
15
+ "webassembly",
16
+ "wasm",
17
+ "typescript",
18
+ "ar.js",
19
+ "webarkit"
20
+ ],
21
+ "license": "MIT",
22
+ "author": {
23
+ "name": "Walter Perdan",
24
+ "url": "https://github.com/kalwalt"
25
+ },
26
+ "repository": {
27
+ "type": "git",
28
+ "url": "git+https://github.com/AR-js-org/artoolkit5-ts.git"
29
+ },
30
+ "bugs": {
31
+ "url": "https://github.com/AR-js-org/artoolkit5-ts/issues"
32
+ },
33
+ "homepage": "https://github.com/AR-js-org/artoolkit5-ts#readme",
34
+ "main": "./dist/artoolkit5-ts.umd.cjs",
35
+ "module": "./dist/artoolkit5-ts.js",
36
+ "types": "./dist/index.d.ts",
37
+ "exports": {
38
+ ".": {
39
+ "types": "./dist/index.d.ts",
40
+ "import": "./dist/artoolkit5-ts.js",
41
+ "require": "./dist/artoolkit5-ts.umd.cjs"
42
+ }
43
+ },
44
+ "files": [
45
+ "dist",
46
+ "CHANGELOG.md"
47
+ ],
48
+ "scripts": {
49
+ "dev": "vite",
50
+ "build": "vite build && tsc -p tsconfig.build.json",
51
+ "preview": "vite preview",
52
+ "test": "vitest run",
53
+ "test:watch": "vitest",
54
+ "typecheck": "tsc --noEmit -p tsconfig.json",
55
+ "release-notes": "node scripts/release-notes.mjs"
56
+ },
57
+ "dependencies": {
58
+ "@ar-js-org/artoolkit5-constants": "^0.3.0",
59
+ "@ar-js-org/artoolkit5-wasm": "^0.3.0"
60
+ },
61
+ "devDependencies": {
62
+ "@types/node": "^26.0.1",
63
+ "@types/three": "^0.185.0",
64
+ "three": "^0.185.0",
65
+ "typescript": "^6.0.3",
66
+ "vite": "^8.1.0",
67
+ "vitest": "^4.1.10"
68
+ }
69
+ }