reze-engine 0.2.18 → 0.2.19

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/README.md CHANGED
@@ -12,7 +12,7 @@ A lightweight engine built with WebGPU and TypeScript for real-time 3D anime cha
12
12
  - Outlines
13
13
  - MSAA 4x anti-aliasing
14
14
  - GPU-accelerated skinning
15
- - Bone rotation api
15
+ - Bone and morph api
16
16
  - VMD animation
17
17
 
18
18
  ## Usage
package/dist/engine.d.ts CHANGED
@@ -83,6 +83,7 @@ export declare class Engine {
83
83
  private physics;
84
84
  private materialSampler;
85
85
  private textureCache;
86
+ private vertexBufferNeedsUpdate;
86
87
  private opaqueDraws;
87
88
  private eyeDraws;
88
89
  private hairDrawsOverEyes;
@@ -131,6 +132,8 @@ export declare class Engine {
131
132
  dispose(): void;
132
133
  loadModel(path: string): Promise<void>;
133
134
  rotateBones(bones: string[], rotations: Quat[], durationMs?: number): void;
135
+ setMorphWeight(name: string, weight: number, durationMs?: number): void;
136
+ private updateVertexBuffer;
134
137
  private setupModelBuffers;
135
138
  private setupMaterials;
136
139
  private createTextureFromPath;
@@ -1 +1 @@
1
- {"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../src/engine.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../src/engine.ts"],"names":[],"mappings":"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"}
package/dist/engine.js CHANGED
@@ -26,6 +26,7 @@ export class Engine {
26
26
  this.modelDir = "";
27
27
  this.physics = null;
28
28
  this.textureCache = new Map();
29
+ this.vertexBufferNeedsUpdate = false;
29
30
  // Draw lists
30
31
  this.opaqueDraws = [];
31
32
  this.eyeDraws = [];
@@ -1368,6 +1369,22 @@ export class Engine {
1368
1369
  rotateBones(bones, rotations, durationMs) {
1369
1370
  this.currentModel?.rotateBones(bones, rotations, durationMs);
1370
1371
  }
1372
+ setMorphWeight(name, weight, durationMs) {
1373
+ if (!this.currentModel)
1374
+ return;
1375
+ this.currentModel.setMorphWeight(name, weight, durationMs);
1376
+ if (!durationMs || durationMs === 0) {
1377
+ this.vertexBufferNeedsUpdate = true;
1378
+ }
1379
+ }
1380
+ updateVertexBuffer() {
1381
+ if (!this.currentModel || !this.vertexBuffer)
1382
+ return;
1383
+ const vertices = this.currentModel.getVertices();
1384
+ if (!vertices || vertices.length === 0)
1385
+ return;
1386
+ this.device.queue.writeBuffer(this.vertexBuffer, 0, vertices);
1387
+ }
1371
1388
  // Step 7: Create vertex, index, and joint buffers
1372
1389
  async setupModelBuffers(model) {
1373
1390
  this.currentModel = model;
@@ -1728,6 +1745,19 @@ export class Engine {
1728
1745
  this.lastFrameTime = currentTime;
1729
1746
  this.updateCameraUniforms();
1730
1747
  this.updateRenderTarget();
1748
+ // Update model pose first (this may update morph weights via tweens)
1749
+ // We need to do this before creating the encoder to ensure vertex buffer is ready
1750
+ if (this.currentModel) {
1751
+ const hasActiveMorphTweens = this.currentModel.evaluatePose();
1752
+ if (hasActiveMorphTweens) {
1753
+ this.vertexBufferNeedsUpdate = true;
1754
+ }
1755
+ }
1756
+ // Update vertex buffer if morphs changed
1757
+ if (this.vertexBufferNeedsUpdate) {
1758
+ this.updateVertexBuffer();
1759
+ this.vertexBufferNeedsUpdate = false;
1760
+ }
1731
1761
  // Use single encoder for both compute and render (reduces sync points)
1732
1762
  const encoder = this.device.createCommandEncoder();
1733
1763
  this.updateModelPose(deltaTime, encoder);
@@ -1877,7 +1907,8 @@ export class Engine {
1877
1907
  }
1878
1908
  }
1879
1909
  updateModelPose(deltaTime, encoder) {
1880
- this.currentModel.evaluatePose();
1910
+ // Note: evaluatePose is called earlier in render() to update vertex buffer before encoder creation
1911
+ // Here we just get the matrices and update physics/compute
1881
1912
  const worldMats = this.currentModel.getBoneWorldMatrices();
1882
1913
  if (this.physics) {
1883
1914
  this.physics.step(deltaTime, worldMats, this.currentModel.getBoneInverseBindMatrices());
package/dist/model.d.ts CHANGED
@@ -41,6 +41,24 @@ export interface Skinning {
41
41
  joints: Uint16Array;
42
42
  weights: Uint8Array;
43
43
  }
44
+ export interface VertexMorphOffset {
45
+ vertexIndex: number;
46
+ positionOffset: [number, number, number];
47
+ }
48
+ export interface GroupMorphReference {
49
+ morphIndex: number;
50
+ ratio: number;
51
+ }
52
+ export interface Morph {
53
+ name: string;
54
+ type: number;
55
+ vertexOffsets: VertexMorphOffset[];
56
+ groupReferences?: GroupMorphReference[];
57
+ }
58
+ export interface Morphing {
59
+ morphs: Morph[];
60
+ offsetsBuffer: Float32Array;
61
+ }
44
62
  export interface SkeletonRuntime {
45
63
  nameIndex: Record<string, number>;
46
64
  localRotations: Float32Array;
@@ -48,24 +66,35 @@ export interface SkeletonRuntime {
48
66
  worldMatrices: Float32Array;
49
67
  computedBones: boolean[];
50
68
  }
69
+ export interface MorphRuntime {
70
+ nameIndex: Record<string, number>;
71
+ weights: Float32Array;
72
+ }
51
73
  export declare class Model {
52
74
  private vertexData;
75
+ private baseVertexData;
53
76
  private vertexCount;
54
77
  private indexData;
55
78
  private textures;
56
79
  private materials;
57
80
  private skeleton;
58
81
  private skinning;
82
+ private morphing;
59
83
  private rigidbodies;
60
84
  private joints;
61
85
  private runtimeSkeleton;
86
+ private runtimeMorph;
62
87
  private cachedIdentityMat1;
63
88
  private cachedIdentityMat2;
64
89
  private rotTweenState;
65
- constructor(vertexData: Float32Array<ArrayBuffer>, indexData: Uint32Array<ArrayBuffer>, textures: Texture[], materials: Material[], skeleton: Skeleton, skinning: Skinning, rigidbodies?: Rigidbody[], joints?: Joint[]);
90
+ private morphTweenState;
91
+ constructor(vertexData: Float32Array<ArrayBuffer>, indexData: Uint32Array<ArrayBuffer>, textures: Texture[], materials: Material[], skeleton: Skeleton, skinning: Skinning, morphing: Morphing, rigidbodies?: Rigidbody[], joints?: Joint[]);
66
92
  private initializeRuntimeSkeleton;
67
93
  private initializeRotTweenBuffers;
94
+ private initializeMorphTweenBuffers;
95
+ private initializeRuntimeMorph;
68
96
  private updateRotationTweens;
97
+ private updateMorphWeightTweens;
69
98
  getVertices(): Float32Array<ArrayBuffer>;
70
99
  getTextures(): Texture[];
71
100
  getMaterials(): Material[];
@@ -75,11 +104,16 @@ export declare class Model {
75
104
  getSkinning(): Skinning;
76
105
  getRigidbodies(): Rigidbody[];
77
106
  getJoints(): Joint[];
107
+ getMorphing(): Morphing;
108
+ getMorphWeights(): Float32Array;
78
109
  getBoneNames(): string[];
79
110
  rotateBones(names: string[], quats: Quat[], durationMs?: number): void;
80
111
  getBoneWorldMatrices(): Float32Array;
81
112
  getBoneInverseBindMatrices(): Float32Array;
82
- evaluatePose(): void;
113
+ getMorphNames(): string[];
114
+ setMorphWeight(name: string, weight: number, durationMs?: number): void;
115
+ private applyMorphs;
116
+ evaluatePose(): boolean;
83
117
  private computeWorldMatrices;
84
118
  }
85
119
  //# sourceMappingURL=model.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"model.d.ts","sourceRoot":"","sources":["../src/model.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"model.d.ts","sourceRoot":"","sources":["../src/model.ts"],"names":[],"mappings":"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"}
package/dist/model.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import { Mat4, Quat, easeInOut } from "./math";
2
2
  const VERTEX_STRIDE = 8;
3
3
  export class Model {
4
- constructor(vertexData, indexData, textures, materials, skeleton, skinning, rigidbodies = [], joints = []) {
4
+ constructor(vertexData, indexData, textures, materials, skeleton, skinning, morphing, rigidbodies = [], joints = []) {
5
5
  this.textures = [];
6
6
  this.materials = [];
7
7
  // Physics data from PMX
@@ -10,6 +10,8 @@ export class Model {
10
10
  // Cached identity matrices to avoid allocations in computeWorldMatrices
11
11
  this.cachedIdentityMat1 = Mat4.identity();
12
12
  this.cachedIdentityMat2 = Mat4.identity();
13
+ // Store base vertex data (original positions before morphing)
14
+ this.baseVertexData = new Float32Array(vertexData);
13
15
  this.vertexData = vertexData;
14
16
  this.vertexCount = vertexData.length / VERTEX_STRIDE;
15
17
  this.indexData = indexData;
@@ -17,6 +19,7 @@ export class Model {
17
19
  this.materials = materials;
18
20
  this.skeleton = skeleton;
19
21
  this.skinning = skinning;
22
+ this.morphing = morphing;
20
23
  this.rigidbodies = rigidbodies;
21
24
  this.joints = joints;
22
25
  if (this.skeleton.bones.length == 0) {
@@ -24,6 +27,9 @@ export class Model {
24
27
  }
25
28
  this.initializeRuntimeSkeleton();
26
29
  this.initializeRotTweenBuffers();
30
+ this.initializeRuntimeMorph();
31
+ this.initializeMorphTweenBuffers();
32
+ this.applyMorphs(); // Apply initial morphs (all weights are 0, so no change)
27
33
  }
28
34
  initializeRuntimeSkeleton() {
29
35
  const boneCount = this.skeleton.bones.length;
@@ -58,6 +64,26 @@ export class Model {
58
64
  durationMs: new Float32Array(n),
59
65
  };
60
66
  }
67
+ initializeMorphTweenBuffers() {
68
+ const n = this.morphing.morphs.length;
69
+ this.morphTweenState = {
70
+ active: new Uint8Array(n),
71
+ startWeight: new Float32Array(n),
72
+ targetWeight: new Float32Array(n),
73
+ startTimeMs: new Float32Array(n),
74
+ durationMs: new Float32Array(n),
75
+ };
76
+ }
77
+ initializeRuntimeMorph() {
78
+ const morphCount = this.morphing.morphs.length;
79
+ this.runtimeMorph = {
80
+ nameIndex: this.morphing.morphs.reduce((acc, morph, index) => {
81
+ acc[morph.name] = index;
82
+ return acc;
83
+ }, {}),
84
+ weights: new Float32Array(morphCount),
85
+ };
86
+ }
61
87
  updateRotationTweens() {
62
88
  const state = this.rotTweenState;
63
89
  const now = performance.now();
@@ -82,6 +108,28 @@ export class Model {
82
108
  state.active[i] = 0;
83
109
  }
84
110
  }
111
+ updateMorphWeightTweens() {
112
+ const state = this.morphTweenState;
113
+ const now = performance.now();
114
+ const weights = this.runtimeMorph.weights;
115
+ const morphCount = this.morphing.morphs.length;
116
+ let hasActiveTweens = false;
117
+ for (let i = 0; i < morphCount; i++) {
118
+ if (state.active[i] !== 1)
119
+ continue;
120
+ hasActiveTweens = true;
121
+ const startMs = state.startTimeMs[i];
122
+ const durMs = Math.max(1, state.durationMs[i]);
123
+ const t = Math.max(0, Math.min(1, (now - startMs) / durMs));
124
+ const e = easeInOut(t);
125
+ weights[i] = state.startWeight[i] + (state.targetWeight[i] - state.startWeight[i]) * e;
126
+ if (t >= 1) {
127
+ weights[i] = state.targetWeight[i];
128
+ state.active[i] = 0;
129
+ }
130
+ }
131
+ return hasActiveTweens;
132
+ }
85
133
  // Get interleaved vertex data for GPU upload
86
134
  // Format: [x,y,z, nx,ny,nz, u,v, x,y,z, nx,ny,nz, u,v, ...]
87
135
  getVertices() {
@@ -117,6 +165,13 @@ export class Model {
117
165
  getJoints() {
118
166
  return this.joints;
119
167
  }
168
+ // Accessors for morphing
169
+ getMorphing() {
170
+ return this.morphing;
171
+ }
172
+ getMorphWeights() {
173
+ return this.runtimeMorph.weights;
174
+ }
120
175
  // ------- Bone helpers (public API) -------
121
176
  getBoneNames() {
122
177
  return this.skeleton.bones.map((b) => b.name);
@@ -182,9 +237,109 @@ export class Model {
182
237
  getBoneInverseBindMatrices() {
183
238
  return this.skeleton.inverseBindMatrices;
184
239
  }
240
+ getMorphNames() {
241
+ return this.morphing.morphs.map((m) => m.name);
242
+ }
243
+ setMorphWeight(name, weight, durationMs) {
244
+ const idx = this.runtimeMorph.nameIndex[name] ?? -1;
245
+ if (idx < 0 || idx >= this.runtimeMorph.weights.length)
246
+ return;
247
+ const clampedWeight = Math.max(0, Math.min(1, weight));
248
+ const dur = durationMs && durationMs > 0 ? durationMs : 0;
249
+ if (dur === 0) {
250
+ // Instant change
251
+ this.runtimeMorph.weights[idx] = clampedWeight;
252
+ this.morphTweenState.active[idx] = 0;
253
+ this.applyMorphs();
254
+ return;
255
+ }
256
+ // Animated change
257
+ const state = this.morphTweenState;
258
+ const now = performance.now();
259
+ const currentWeight = this.runtimeMorph.weights[idx];
260
+ // If already tweening, start from current interpolated value
261
+ let startWeight = currentWeight;
262
+ if (state.active[idx] === 1) {
263
+ const startMs = state.startTimeMs[idx];
264
+ const prevDur = Math.max(1, state.durationMs[idx]);
265
+ const t = Math.max(0, Math.min(1, (now - startMs) / prevDur));
266
+ const e = easeInOut(t);
267
+ startWeight = state.startWeight[idx] + (state.targetWeight[idx] - state.startWeight[idx]) * e;
268
+ }
269
+ state.startWeight[idx] = startWeight;
270
+ state.targetWeight[idx] = clampedWeight;
271
+ state.startTimeMs[idx] = now;
272
+ state.durationMs[idx] = dur;
273
+ state.active[idx] = 1;
274
+ // Immediately apply morphs with current weight
275
+ this.runtimeMorph.weights[idx] = startWeight;
276
+ this.applyMorphs();
277
+ }
278
+ applyMorphs() {
279
+ // Reset vertex data to base positions
280
+ this.vertexData.set(this.baseVertexData);
281
+ const vertexCount = this.vertexCount;
282
+ const morphCount = this.morphing.morphs.length;
283
+ const weights = this.runtimeMorph.weights;
284
+ // First pass: Compute effective weights for all morphs (handling group morphs)
285
+ const effectiveWeights = new Float32Array(morphCount);
286
+ effectiveWeights.set(weights); // Start with direct weights
287
+ // Apply group morphs: group morph weight * ratio affects referenced morphs
288
+ for (let morphIdx = 0; morphIdx < morphCount; morphIdx++) {
289
+ const morph = this.morphing.morphs[morphIdx];
290
+ if (morph.type === 0 && morph.groupReferences) {
291
+ const groupWeight = weights[morphIdx];
292
+ if (groupWeight > 0.0001) {
293
+ for (const ref of morph.groupReferences) {
294
+ if (ref.morphIndex >= 0 && ref.morphIndex < morphCount) {
295
+ // Add group morph's contribution to the referenced morph
296
+ effectiveWeights[ref.morphIndex] += groupWeight * ref.ratio;
297
+ }
298
+ }
299
+ }
300
+ }
301
+ }
302
+ // Clamp effective weights to [0, 1]
303
+ for (let i = 0; i < morphCount; i++) {
304
+ effectiveWeights[i] = Math.max(0, Math.min(1, effectiveWeights[i]));
305
+ }
306
+ // Second pass: Apply vertex morphs with their effective weights
307
+ for (let morphIdx = 0; morphIdx < morphCount; morphIdx++) {
308
+ const effectiveWeight = effectiveWeights[morphIdx];
309
+ if (effectiveWeight === 0 || effectiveWeight < 0.0001)
310
+ continue;
311
+ const morph = this.morphing.morphs[morphIdx];
312
+ if (morph.type !== 1)
313
+ continue; // Only process vertex morphs
314
+ // For vertex morphs, iterate through vertices that have offsets
315
+ for (const vertexOffset of morph.vertexOffsets) {
316
+ const vIdx = vertexOffset.vertexIndex;
317
+ if (vIdx < 0 || vIdx >= vertexCount)
318
+ continue;
319
+ // Get morph offset for this vertex
320
+ const offsetX = vertexOffset.positionOffset[0];
321
+ const offsetY = vertexOffset.positionOffset[1];
322
+ const offsetZ = vertexOffset.positionOffset[2];
323
+ // Skip if offset is zero
324
+ if (Math.abs(offsetX) < 0.0001 && Math.abs(offsetY) < 0.0001 && Math.abs(offsetZ) < 0.0001) {
325
+ continue;
326
+ }
327
+ // Apply weighted offset to vertex position (positions are at stride 0, 8, 16, ...)
328
+ const vertexIdx = vIdx * VERTEX_STRIDE;
329
+ this.vertexData[vertexIdx] += offsetX * effectiveWeight;
330
+ this.vertexData[vertexIdx + 1] += offsetY * effectiveWeight;
331
+ this.vertexData[vertexIdx + 2] += offsetZ * effectiveWeight;
332
+ }
333
+ }
334
+ }
185
335
  evaluatePose() {
186
336
  this.updateRotationTweens();
337
+ const hasActiveMorphTweens = this.updateMorphWeightTweens();
338
+ if (hasActiveMorphTweens) {
339
+ this.applyMorphs();
340
+ }
187
341
  this.computeWorldMatrices();
342
+ return hasActiveMorphTweens;
188
343
  }
189
344
  computeWorldMatrices() {
190
345
  const bones = this.skeleton.bones;
@@ -17,6 +17,8 @@ export declare class PmxLoader {
17
17
  private inverseBindMatrices;
18
18
  private joints0;
19
19
  private weights0;
20
+ private morphs;
21
+ private vertexCount;
20
22
  private rigidbodies;
21
23
  private joints;
22
24
  private constructor();
@@ -28,7 +30,7 @@ export declare class PmxLoader {
28
30
  private parseTextures;
29
31
  private parseMaterials;
30
32
  private parseBones;
31
- private skipMorphs;
33
+ private parseMorphs;
32
34
  private skipDisplayFrames;
33
35
  private parseRigidbodies;
34
36
  private parseJoints;
@@ -1 +1 @@
1
- {"version":3,"file":"pmx-loader.d.ts","sourceRoot":"","sources":["../src/pmx-loader.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAA+C,MAAM,SAAS,CAAA;AAI5E,qBAAa,SAAS;IACpB,OAAO,CAAC,IAAI,CAAU;IACtB,OAAO,CAAC,MAAM,CAAI;IAClB,OAAO,CAAC,OAAO,CAAc;IAC7B,OAAO,CAAC,QAAQ,CAAI;IACpB,OAAO,CAAC,mBAAmB,CAAI;IAC/B,OAAO,CAAC,eAAe,CAAI;IAC3B,OAAO,CAAC,gBAAgB,CAAI;IAC5B,OAAO,CAAC,iBAAiB,CAAI;IAC7B,OAAO,CAAC,aAAa,CAAI;IACzB,OAAO,CAAC,cAAc,CAAI;IAC1B,OAAO,CAAC,kBAAkB,CAAI;IAC9B,OAAO,CAAC,QAAQ,CAAgB;IAChC,OAAO,CAAC,SAAS,CAAiB;IAClC,OAAO,CAAC,KAAK,CAAa;IAC1B,OAAO,CAAC,mBAAmB,CAA4B;IACvD,OAAO,CAAC,OAAO,CAA2B;IAC1C,OAAO,CAAC,QAAQ,CAA0B;IAC1C,OAAO,CAAC,WAAW,CAAkB;IACrC,OAAO,CAAC,MAAM,CAAc;IAE5B,OAAO;WAIM,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC;IAK9C,OAAO,CAAC,KAAK;IAgBb,OAAO,CAAC,WAAW;IA+CnB,OAAO,CAAC,aAAa;IA+FrB,OAAO,CAAC,YAAY;IAWpB,OAAO,CAAC,aAAa;IAkBrB,OAAO,CAAC,cAAc;IAyFtB,OAAO,CAAC,UAAU;IA2IlB,OAAO,CAAC,UAAU;IAyGlB,OAAO,CAAC,iBAAiB;IAgDzB,OAAO,CAAC,gBAAgB;IAyFxB,OAAO,CAAC,WAAW;IAmGnB,OAAO,CAAC,kBAAkB;IAmC1B,OAAO,CAAC,OAAO;IA2If,OAAO,CAAC,QAAQ;IAOhB,OAAO,CAAC,SAAS;IAUjB,OAAO,CAAC,cAAc;IAWtB,OAAO,CAAC,iBAAiB;IAczB,OAAO,CAAC,QAAQ;IAShB,OAAO,CAAC,UAAU;IASlB,OAAO,CAAC,SAAS;IAMjB,OAAO,CAAC,OAAO;IAmBf,OAAO,CAAC,QAAQ;CAIjB"}
1
+ {"version":3,"file":"pmx-loader.d.ts","sourceRoot":"","sources":["../src/pmx-loader.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,EAUN,MAAM,SAAS,CAAA;AAIhB,qBAAa,SAAS;IACpB,OAAO,CAAC,IAAI,CAAU;IACtB,OAAO,CAAC,MAAM,CAAI;IAClB,OAAO,CAAC,OAAO,CAAc;IAC7B,OAAO,CAAC,QAAQ,CAAI;IACpB,OAAO,CAAC,mBAAmB,CAAI;IAC/B,OAAO,CAAC,eAAe,CAAI;IAC3B,OAAO,CAAC,gBAAgB,CAAI;IAC5B,OAAO,CAAC,iBAAiB,CAAI;IAC7B,OAAO,CAAC,aAAa,CAAI;IACzB,OAAO,CAAC,cAAc,CAAI;IAC1B,OAAO,CAAC,kBAAkB,CAAI;IAC9B,OAAO,CAAC,QAAQ,CAAgB;IAChC,OAAO,CAAC,SAAS,CAAiB;IAClC,OAAO,CAAC,KAAK,CAAa;IAC1B,OAAO,CAAC,mBAAmB,CAA4B;IACvD,OAAO,CAAC,OAAO,CAA2B;IAC1C,OAAO,CAAC,QAAQ,CAA0B;IAC1C,OAAO,CAAC,MAAM,CAAc;IAC5B,OAAO,CAAC,WAAW,CAAY;IAC/B,OAAO,CAAC,WAAW,CAAkB;IACrC,OAAO,CAAC,MAAM,CAAc;IAE5B,OAAO;WAIM,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC;IAK9C,OAAO,CAAC,KAAK;IAiBb,OAAO,CAAC,WAAW;IA+CnB,OAAO,CAAC,aAAa;IA+FrB,OAAO,CAAC,YAAY;IAWpB,OAAO,CAAC,aAAa;IAkBrB,OAAO,CAAC,cAAc;IAyFtB,OAAO,CAAC,UAAU;IA2IlB,OAAO,CAAC,WAAW;IA+InB,OAAO,CAAC,iBAAiB;IAgDzB,OAAO,CAAC,gBAAgB;IAyFxB,OAAO,CAAC,WAAW;IAmGnB,OAAO,CAAC,kBAAkB;IAmC1B,OAAO,CAAC,OAAO;IAkLf,OAAO,CAAC,QAAQ;IAOhB,OAAO,CAAC,SAAS;IAUjB,OAAO,CAAC,cAAc;IAWtB,OAAO,CAAC,iBAAiB;IAczB,OAAO,CAAC,QAAQ;IAShB,OAAO,CAAC,UAAU;IASlB,OAAO,CAAC,SAAS;IAMjB,OAAO,CAAC,OAAO;IAmBf,OAAO,CAAC,QAAQ;CAIjB"}