xl-public-utils 1.0.5 → 1.0.7

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.
package/index.js CHANGED
@@ -1,6 +1,6 @@
1
- import * as vtkUtils from './src/vtkUtils.mjs';
2
- import * as utils from './src/utils.mjs'
3
- import * as qrcode from './src/qrcode.mjs'
4
- import * as BwipJs from './src/bwip-js.mjs';
5
- import * as drcUtils from './src/drcUtils.mjs';
1
+ import * as vtkUtils from './src/vtkUtils.js';
2
+ import * as utils from './src/utils.js'
3
+ import * as qrcode from './src/qrcode.js'
4
+ import * as BwipJs from './src/bwip-js.js';
5
+ import * as drcUtils from './src/drcUtils.js';
6
6
  export { vtkUtils, utils, qrcode, BwipJs, drcUtils };
package/package.json CHANGED
@@ -1,11 +1,18 @@
1
1
  {
2
2
  "name": "xl-public-utils",
3
- "version": "1.0.5",
3
+ "version": "1.0.7",
4
4
  "description": "",
5
- "type": "module",
6
5
  "main": "index.js",
7
6
  "module": "index.js",
8
7
  "types": "index.d.ts",
8
+ "files": [
9
+ "src/",
10
+ "types/",
11
+ "index.d.ts",
12
+ "index.js",
13
+ "package.json",
14
+ "tsconfig.json"
15
+ ],
9
16
  "peerDependencies": {
10
17
  "@kitware/vtk.js": ">=25.7.2",
11
18
  "gl-matrix": ">=3.4.3"
@@ -20,13 +27,17 @@
20
27
  },
21
28
  "exports": {
22
29
  ".": "./index.js",
23
- "./qrcode": "./src/qrcode.mjs",
24
- "./vtkUtils": "./src/vtkUtils.mjs",
25
- "./utils": "./src/utils.mjs",
26
- "./bwipJs": "./src/bwip-js.mjs"
30
+ "./qrcode": "./src/qrcode.js",
31
+ "./vtkUtils": "./src/vtkUtils.js",
32
+ "./utils": "./src/utils.js",
33
+ "./bwipJs": "./src/bwip-js.js"
27
34
  },
28
35
  "scripts": {
29
- "test": "jest"
36
+ "test": "karma start",
37
+ "docs:dev": "vitepress dev docs",
38
+ "docs:build": "vitepress build docs",
39
+ "docs:preview": "vitepress preview docs",
40
+ "docs:gen": "dts2md types/*.d.ts -o docs"
30
41
  },
31
42
  "keywords": [
32
43
  "一些通用方法"
@@ -34,6 +45,20 @@
34
45
  "author": "xl",
35
46
  "license": "ISC",
36
47
  "devDependencies": {
37
- "typescript": "^5.6.3"
48
+ "@babel/core": "^7.26.0",
49
+ "@babel/preset-env": "^7.26.0",
50
+ "babel-loader": "^9.2.1",
51
+ "chai": "^5.1.2",
52
+ "karma": "^6.4.4",
53
+ "karma-chai": "^0.1.0",
54
+ "karma-chrome-launcher": "^3.2.0",
55
+ "karma-cli": "^2.0.0",
56
+ "karma-mocha": "^2.0.1",
57
+ "karma-mocha-reporter": "^2.2.5",
58
+ "karma-webpack": "^5.0.1",
59
+ "mocha": "^10.8.2",
60
+ "typescript": "^5.6.3",
61
+ "vitepress": "^1.5.0",
62
+ "webpack": "^5.96.1"
38
63
  }
39
64
  }
@@ -30,7 +30,7 @@
30
30
  //
31
31
  "use strict";
32
32
 
33
- import { bwipp_datamatrix,bwipp_qrcode,bwipp_lookup,bwipp_encode,BWIPP_VERSION } from './bwipp.mjs';
33
+ import { bwipp_datamatrix,bwipp_qrcode,bwipp_lookup,bwipp_encode,BWIPP_VERSION } from './bwipp.js';
34
34
 
35
35
  // exports.js
36
36
  const BWIPJS_VERSION = '4.5.1 (2024-08-12)';
@@ -1,6 +1,6 @@
1
1
  import { vec3 } from "gl-matrix";
2
- import { int8ArrayToBase64 } from './utils.mjs'
3
- import vtkPolyData from "@kitware/vtk.js/Common/DataModel/PolyData";
2
+ import { int8ArrayToBase64 } from './utils.js'
3
+ import vtkPolyData from "@kitware/vtk.js/Common/DataModel/PolyData.js";
4
4
  /**
5
5
  * @typedef {Object} AttrOption
6
6
  * @property {number[]} [colors] 颜色数组
@@ -1,5 +1,4 @@
1
- import vtkPolyData from "@kitware/vtk.js/Common/DataModel/PolyData";
2
- import { mat4 } from "gl-matrix";
1
+ import vtkPolyData from "@kitware/vtk.js/Common/DataModel/PolyData.js";
3
2
  var FormatTypes = {
4
3
  ASCII: 'ascii',
5
4
  BINARY: 'binary'
@@ -1,4 +1,4 @@
1
- import vtkPolyData from '@kitware/vtk.js/Common/DataModel/PolyData';
1
+ import vtkPolyData from '@kitware/vtk.js/Common/DataModel/PolyData.js';
2
2
  import { vec3 } from 'gl-matrix';
3
3
 
4
4
  /**
@@ -1,4 +1,4 @@
1
- import { qrcode, datamatrix} from './bwip-js.mjs';
1
+ import { qrcode, datamatrix} from './bwip-js.js';
2
2
 
3
3
  /**
4
4
  * @typedef {Object} QrCodeOptions
@@ -71,4 +71,14 @@ export function arrayBufferToBase64(outputBuffer) {
71
71
  const outputData = new Int8Array(outputBuffer);
72
72
 
73
73
  return int8ArrayToBase64(outputData)
74
+ }
75
+
76
+ /**
77
+ * 获取文件后缀
78
+ * @param {string} fileName 文件名,或者文件地址
79
+ * @returns 文件后缀
80
+ */
81
+ export function getFileExtension(fileName) {
82
+ const _str = fileName.split('?')[0].split('.').pop();
83
+ return _str ? _str.toLowerCase() : '';
74
84
  }
@@ -1,16 +1,20 @@
1
- import vtkRenderer from "@kitware/vtk.js/Rendering/Core/Renderer";
2
- import vtkInteractorStyleManipulator from "@kitware/vtk.js/Interaction/Style/InteractorStyleManipulator"
3
- import vtkMouseCameraTrackballPanManipulator from "@kitware/vtk.js/Interaction/Manipulators/MouseCameraTrackballPanManipulator";
4
- import vtkMouseCameraTrackballRotateManipulator from "@kitware/vtk.js/Interaction/Manipulators/MouseCameraTrackballRotateManipulator";
5
- import vtkMouseCameraTrackballZoomManipulator from "@kitware/vtk.js/Interaction/Manipulators/MouseCameraTrackballZoomManipulator";
6
- import vtkRenderWindowInteractor from "@kitware/vtk.js/Rendering/Core/RenderWindowInteractor";
7
- import vtkMatrixBuilder from "@kitware/vtk.js/Common/Core/MatrixBuilder";
1
+ import vtkRenderer from "@kitware/vtk.js/Rendering/Core/Renderer.js";
2
+ import vtkInteractorStyleManipulator from "@kitware/vtk.js/Interaction/Style/InteractorStyleManipulator.js"
3
+ import vtkMouseCameraTrackballPanManipulator from "@kitware/vtk.js/Interaction/Manipulators/MouseCameraTrackballPanManipulator.js";
4
+ import vtkMouseCameraTrackballRotateManipulator from "@kitware/vtk.js/Interaction/Manipulators/MouseCameraTrackballRotateManipulator.js";
5
+ import vtkMouseCameraTrackballZoomManipulator from "@kitware/vtk.js/Interaction/Manipulators/MouseCameraTrackballZoomManipulator.js";
6
+ import vtkRenderWindowInteractor from "@kitware/vtk.js/Rendering/Core/RenderWindowInteractor.js";
7
+ import vtkMatrixBuilder from "@kitware/vtk.js/Common/Core/MatrixBuilder.js";
8
+ import vtkPolyData from "@kitware/vtk.js/Common/DataModel/PolyData.js";
9
+ import vtkPLYReader from '@kitware/vtk.js/IO/Geometry/PLYReader';
10
+ import vtkSTLReader from '@kitware/vtk.js/IO/Geometry/STLReader';
11
+ import vtkDracoReader from '@kitware/vtk.js/IO/Geometry/DracoReader';
12
+ import vtkTriangleFilter from "@kitware/vtk.js/Filters/General/TriangleFilter";
8
13
  import { vec3, mat4, mat3 } from 'gl-matrix';
9
- import vtkPolyData from "@kitware/vtk.js/Common/DataModel/PolyData";
10
- import { exportBinarySTL } from './exportSTL.mjs';
11
- import { writePLY } from "./exportPLY.mjs";
12
- import { enCodeMesh } from './drcUtils.mjs';
13
- import { int8ArrayToBase64 } from "./utils.mjs";
14
+ import { exportBinarySTL } from './exportSTL.js';
15
+ import { writePLY } from "./exportPLY.js";
16
+ import { enCodeMesh } from './drcUtils.js';
17
+ import { getFileExtension, int8ArrayToBase64 } from "./utils.js";
14
18
 
15
19
  /**
16
20
  * 计算屏幕坐标到三维坐标
@@ -418,8 +422,6 @@ export function vecTransfromByMat4(vec, matrix) {
418
422
  * @returns {Blob} 网格的ply文件Blob
419
423
  */
420
424
  export function createPlyBlob(mesh, format = 'ascii') {
421
- // const data = deduplicatePolyData(mesh)
422
- // const deduplicateData = deduplicatePolyData(mesh);
423
425
  const fileContents = writePLY(mesh, format);
424
426
  const blob = new Blob([fileContents], { type: "application/octet-steam" });
425
427
  return blob;
@@ -472,12 +474,11 @@ export function createMeshTypeBlob(
472
474
 
473
475
 
474
476
  /**
475
- * vtkPolyData的顶点去重
476
- * 用于3倍顶点的stl和老版本的vtkMarchingCube
477
+ * vtkPolyData的顶点去重 用于3倍顶点的stl和老版本的vtkMarchingCube
477
478
  * @param {vtkPolyData} data 网格的vtkPolyData
478
479
  * @returns {vtkPolyData} 去重之后的vtkPolyData
479
480
  */
480
- export const deduplicatePolyData = (data) => {
481
+ export function deduplicatePolyData(data) {
481
482
  const OFFSET_BOUNDS = 10;
482
483
  const vMap = new Map();
483
484
  const vIndexMap = new Map();
@@ -723,7 +724,7 @@ export function enCodeMeshToBase64(mesh, matrix = undefined) {
723
724
 
724
725
  /**
725
726
  * 将一圈有序点按指定size进行平滑
726
- * @param {vce3[]} points 一圈有序点
727
+ * @param {vec3[]} points 一圈有序点
727
728
  * @param {number} smaSize=3 平滑点的数量通常值为奇数
728
729
  * @returns {vec3[]} 平滑之后的点
729
730
  */
@@ -748,7 +749,7 @@ export function smaPoint(points, smaSize = 3) {
748
749
  }
749
750
  /**
750
751
  * 将一段有序点按指定size进行平滑
751
- * @param {vce3[]} points 一段有序点
752
+ * @param {vec3[]} points 一段有序点
752
753
  * @param {number} smaSize=3 平滑点的数量通常值为奇数
753
754
  * @returns {vec3[]} 平滑之后的点
754
755
  */
@@ -804,4 +805,99 @@ export function getAxisFormMat4(matrix) {
804
805
  vec3.normalize(axis_y, axis_y);
805
806
  vec3.normalize(axis_z, axis_z);
806
807
  return { x: axis_x, y: axis_y, z: axis_z };
808
+ }
809
+
810
+ /**
811
+ * 判断一个矩阵是否是正交矩阵
812
+ * @param {mat4} matrix 矩阵
813
+ * @returns {boolean} 是否是正交矩阵
814
+ */
815
+ export function isRotationMatrix(matrix) {
816
+ // 检查左上子矩阵是否是正交矩阵
817
+ const rotationMatrix = mat3.create();
818
+ mat3.fromMat4(rotationMatrix, matrix);
819
+
820
+ const transposeMatrix = mat3.transpose(mat3.create(), rotationMatrix);
821
+ const inverseMatrix = mat3.invert(mat3.create(), rotationMatrix);
822
+
823
+ if (!mat3.equals(transposeMatrix, inverseMatrix)) {
824
+ return false;
825
+ }
826
+ // console.log('determinant', mat4.determinant(matrix));
827
+ if (Math.abs(mat4.determinant(matrix) - 1) > 0.000001) {
828
+ return false;
829
+ }
830
+ // 检查最后一个元素是否为1
831
+ if (matrix[15] !== 1) {
832
+ return false;
833
+ }
834
+ return true;
835
+ }
836
+
837
+
838
+
839
+ /**
840
+ * 将vtkPolyData进行三角化
841
+ * @param {vtkPolyData} polydata 需要三角化的vtkPolydata
842
+ * @returns {vtkPolyData} 三角化之后的vtkPolydata
843
+ */
844
+ export function trianglePolys(polydata) {
845
+ const triangleFilter = vtkTriangleFilter.newInstance();
846
+ triangleFilter.setInputData(polydata);
847
+ return triangleFilter.getOutputData();
848
+ }
849
+
850
+
851
+ /**
852
+ * 加载网格
853
+ * @param {string | File | Blob} file 文件或者文件链接
854
+ * @param {'drc' | 'stl' | 'ply'} [type] 文件类型,当file为string | File的时候可以不传根据文件后缀自动获取,drc需要先进行初始化
855
+ * @param {boolean} [process] 是否需要预先对数据进行处理,stl默认(去重)
856
+ * @returns {Promise<vtkPolyData>} vtkPolyData
857
+ */
858
+ export async function loadMeshData(file, type = undefined, process = undefined) {
859
+ let _fileBuffer;
860
+ if(typeof file === 'string') {
861
+ type = getFileExtension(file);
862
+ const _file = await fetch(file)
863
+ _fileData = _file.arrayBuffer()
864
+ } else if(file instanceof Blob && type !== undefined) {
865
+ _fileBuffer = await file.arrayBuffer();
866
+ } else if(file instanceof File) {
867
+ _fileBuffer = await file.arrayBuffer();
868
+ if(!type) {
869
+ type = getFileExtension(file.name);
870
+ }
871
+ } else {
872
+ throw('error: file type error')
873
+ }
874
+ /** @type {vtkPLYReader | vtkSTLReader | vtkDracoReader} */
875
+ let reader;
876
+ switch (type) {
877
+ case 'ply':
878
+ reader = vtkPLYReader.newInstance();
879
+ if(process === undefined) {
880
+ process = false;
881
+ }
882
+ break;
883
+ case 'stl':
884
+ reader = vtkSTLReader.newInstance();
885
+ if(process === undefined) {
886
+ process = true;
887
+ }
888
+ break;
889
+ case 'drc':
890
+ reader = vtkDracoReader.newInstance();
891
+ break;
892
+ default:
893
+ throw('error: file type error')
894
+ }
895
+ reader.parseAsArrayBuffer(_fileBuffer);
896
+ let polyData = reader.getOutputData();
897
+ if(process) {
898
+ if(type === 'stl') {
899
+ return deduplicatePolyData(polyData);
900
+ }
901
+ }
902
+ return polyData;
807
903
  }
package/tsconfig.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "allowJs": true,
4
4
  "declaration": true,
5
5
  "emitDeclarationOnly": true,
6
- "outDir": "./types" // 可选,定义.d.ts文件输出目录
6
+ "outDir": "types" // 可选,定义.d.ts文件输出目录
7
7
  },
8
- "include": ["src/*.mjs"] // 指定包含的 JavaScript 文件路径
8
+ "include": ["src/*.js", "src/vtkUtils.js",] // 指定包含的 JavaScript 文件路径
9
9
  }
@@ -58,7 +58,7 @@ declare function DrawingSVG(): {
58
58
  end(): string;
59
59
  };
60
60
  export const BWIPJS_VERSION: "4.5.1 (2024-08-12)";
61
- import { BWIPP_VERSION } from './bwipp.mjs';
61
+ import { BWIPP_VERSION } from './bwipp.js';
62
62
  declare function ToRaw(bcid: any, text: any, options: any, ...args: any[]): true | any[];
63
63
  declare function FixupOptions(opts: any): any;
64
64
  declare namespace FontLib {
@@ -126,4 +126,4 @@ export type Mesh = {
126
126
  faces: number[][];
127
127
  };
128
128
  import { vec3 } from "gl-matrix";
129
- import vtkPolyData from "@kitware/vtk.js/Common/DataModel/PolyData";
129
+ import vtkPolyData from "@kitware/vtk.js/Common/DataModel/PolyData.js";
@@ -1,4 +1,3 @@
1
- import vtkPolyData from "@kitware/vtk.js/Common/DataModel/PolyData";
2
1
  /**
3
2
  * 将polyData转换为ply文件
4
3
  * @param {vtkPolyData} polyData 需要导出的polydata
@@ -13,4 +12,5 @@ import vtkPolyData from "@kitware/vtk.js/Common/DataModel/PolyData";
13
12
  * @param {boolean} withColors=true 面使用点索引
14
13
  * @returns {string | DataView} 返回文件内容
15
14
  */
16
- export function writePLY(polyData: vtkPolyData, format: "ascii" | "binary", dataByteOrder?: 0 | 1, headerComments?: string[], textureFileName?: string, textureCoordinatesName?: ["u", "v"], withNormals?: boolean, withUVs?: boolean, withColors?: boolean, withIndices?: boolean): string | DataView;
15
+ export function writePLY(polyData: vtkPolyData, format: "ascii" | "binary", dataByteOrder?: 0 | 1, headerComments?: string[], textureFileName?: string, textureCoordinatesName?: ["u", "v"], withNormals?: boolean, withUVs?: boolean, withColors?: boolean, withIndices?: boolean): string | DataView;
16
+ import vtkPolyData from "@kitware/vtk.js/Common/DataModel/PolyData.js";
@@ -1,5 +1,3 @@
1
- import vtkPolyData from '@kitware/vtk.js/Common/DataModel/PolyData';
2
-
3
1
  /**
4
2
  * 导出stl模型的时候 需要离散点 防止被认为是同一个点 精度到e-7就够了
5
3
  * @param {number[]} points 网格点
@@ -18,3 +16,4 @@ export function exportBinarySTL(polydata: vtkPolyData, colorMagic?: boolean): Bl
18
16
  * @returns {string} 网格的asciiSTL文件内容
19
17
  */
20
18
  export function exportAsciiSTL(polydata: vtkPolyData): string;
19
+ import vtkPolyData from '@kitware/vtk.js/Common/DataModel/PolyData.js';
@@ -21,6 +21,12 @@ export function int8ArrayToBase64(int8: Int8Array): string;
21
21
  * @returns {string} base64格式的字符串
22
22
  */
23
23
  export function arrayBufferToBase64(outputBuffer: ArrayBuffer): string;
24
+ /**
25
+ * 获取文件后缀
26
+ * @param {string} fileName 文件名,或者文件地址
27
+ * @returns 文件后缀
28
+ */
29
+ export function getFileExtension(fileName: string): string;
24
30
  /**
25
31
  * 获取当前屏幕分辨率(百分制,默认100)
26
32
  * @returns {number} 当前屏幕分辨率
@@ -167,6 +167,12 @@ export function createDrcBlob(mesh: vtkPolyData): Blob;
167
167
  * @returns {Blob} 对应类型的Blob
168
168
  */
169
169
  export function createMeshTypeBlob(mesh: vtkPolyData, type: "ply" | "stl" | "drc"): Blob;
170
+ /**
171
+ * vtkPolyData的顶点去重 用于3倍顶点的stl和老版本的vtkMarchingCube
172
+ * @param {vtkPolyData} data 网格的vtkPolyData
173
+ * @returns {vtkPolyData} 去重之后的vtkPolyData
174
+ */
175
+ export function deduplicatePolyData(data: vtkPolyData): vtkPolyData;
170
176
  /**
171
177
  * 计算一组三维点的中心点
172
178
  * @param {vec3[]} points 三维点数组
@@ -237,18 +243,18 @@ export function convEular2matrixZYX(rmat: mat3, xangle: number, yangle: number,
237
243
  export function enCodeMeshToBase64(mesh: vtkPolyData, matrix?: mat4): string;
238
244
  /**
239
245
  * 将一圈有序点按指定size进行平滑
240
- * @param {vce3[]} points 一圈有序点
246
+ * @param {vec3[]} points 一圈有序点
241
247
  * @param {number} smaSize=3 平滑点的数量通常值为奇数
242
248
  * @returns {vec3[]} 平滑之后的点
243
249
  */
244
- export function smaPoint(points: vce3[], smaSize?: number): vec3[];
250
+ export function smaPoint(points: vec3[], smaSize?: number): vec3[];
245
251
  /**
246
252
  * 将一段有序点按指定size进行平滑
247
- * @param {vce3[]} points 一段有序点
253
+ * @param {vec3[]} points 一段有序点
248
254
  * @param {number} smaSize=3 平滑点的数量通常值为奇数
249
255
  * @returns {vec3[]} 平滑之后的点
250
256
  */
251
- export function smaPointNotRound(points: vce3[], smaSize?: number): vec3[];
257
+ export function smaPointNotRound(points: vec3[], smaSize?: number): vec3[];
252
258
  /**
253
259
  * 表示一个包含三个轴向的对象
254
260
  * @typedef {Object} AxisObject
@@ -262,6 +268,26 @@ export function smaPointNotRound(points: vce3[], smaSize?: number): vec3[];
262
268
  * @returns {AxisObject} 三个轴向
263
269
  */
264
270
  export function getAxisFormMat4(matrix: mat4): AxisObject;
271
+ /**
272
+ * 判断一个矩阵是否是正交矩阵
273
+ * @param {mat4} matrix 矩阵
274
+ * @returns {boolean} 是否是正交矩阵
275
+ */
276
+ export function isRotationMatrix(matrix: mat4): boolean;
277
+ /**
278
+ * 将vtkPolyData进行三角化
279
+ * @param {vtkPolyData} polydata 需要三角化的vtkPolydata
280
+ * @returns {vtkPolyData} 三角化之后的vtkPolydata
281
+ */
282
+ export function trianglePolys(polydata: vtkPolyData): vtkPolyData;
283
+ /**
284
+ * 加载网格
285
+ * @param {string | File | Blob} file 文件或者文件链接
286
+ * @param {'drc' | 'stl' | 'ply'} [type] 文件类型,当file为string | File的时候可以不传根据文件后缀自动获取,drc需要先进行初始化
287
+ * @param {boolean} [process] 是否需要预先对数据进行处理,stl默认(去重)
288
+ * @returns {Promise<vtkPolyData>} vtkPolyData
289
+ */
290
+ export function loadMeshData(file: string | File | Blob, type?: "drc" | "stl" | "ply", process?: boolean): Promise<vtkPolyData>;
265
291
  /**
266
292
  * 计算 w2l(word 2 local, word to local) 的变换矩阵
267
293
  * @param {vec3} center 中心点
@@ -280,7 +306,6 @@ export function getmatw2l(center: vec3, xaxis: vec3, yaxis: vec3, zaxis: vec3):
280
306
  * @returns { mat4 } 变换矩阵
281
307
  */
282
308
  export function getmatofl2w(center: vec3, xaxis: vec3, yaxis: vec3, zaxis: vec3): mat4;
283
- export function deduplicatePolyData(data: vtkPolyData): vtkPolyData;
284
309
  export type Position = {
285
310
  /**
286
311
  * 对应vtk坐标系的x值
@@ -312,9 +337,9 @@ export type AxisObject = {
312
337
  */
313
338
  z: vec3;
314
339
  };
315
- import vtkRenderer from "@kitware/vtk.js/Rendering/Core/Renderer";
340
+ import vtkRenderer from "@kitware/vtk.js/Rendering/Core/Renderer.js";
316
341
  import { vec3 } from 'gl-matrix';
317
342
  import { mat4 } from 'gl-matrix';
318
- import vtkRenderWindowInteractor from "@kitware/vtk.js/Rendering/Core/RenderWindowInteractor";
319
- import vtkPolyData from "@kitware/vtk.js/Common/DataModel/PolyData";
343
+ import vtkRenderWindowInteractor from "@kitware/vtk.js/Rendering/Core/RenderWindowInteractor.js";
344
+ import vtkPolyData from "@kitware/vtk.js/Common/DataModel/PolyData.js";
320
345
  import { mat3 } from 'gl-matrix';
File without changes
File without changes
File without changes