@nexart/codemode-sdk 1.8.3 → 1.9.0

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 (150) hide show
  1. package/CHANGELOG.md +89 -0
  2. package/README.md +121 -2
  3. package/dist/cjs/browser.cjs +3077 -0
  4. package/dist/cjs/browser.js +3042 -0
  5. package/dist/cjs/core.cjs +1998 -0
  6. package/dist/cjs/core.js +1966 -0
  7. package/dist/cjs/node.cjs +3245 -0
  8. package/dist/cjs/node.js +3208 -0
  9. package/dist/esm/browser.cjs +3077 -0
  10. package/dist/esm/browser.js +3042 -0
  11. package/dist/esm/core.cjs +1998 -0
  12. package/dist/esm/core.js +1966 -0
  13. package/dist/esm/node.cjs +3245 -0
  14. package/dist/esm/node.js +3208 -0
  15. package/dist/types/sdk/codemode/attestation.d.ts +24 -0
  16. package/dist/types/sdk/codemode/attestation.d.ts.map +1 -0
  17. package/dist/types/sdk/codemode/builder-manifest.d.ts.map +1 -0
  18. package/dist/types/sdk/codemode/canonicalJson.d.ts +16 -0
  19. package/dist/types/sdk/codemode/canonicalJson.d.ts.map +1 -0
  20. package/dist/{sdk → types/sdk}/codemode/core-index.d.ts +5 -1
  21. package/dist/types/sdk/codemode/core-index.d.ts.map +1 -0
  22. package/dist/types/sdk/codemode/engine.d.ts.map +1 -0
  23. package/dist/{sdk → types/sdk}/codemode/entry/browser.d.ts +1 -1
  24. package/dist/types/sdk/codemode/entry/browser.d.ts.map +1 -0
  25. package/dist/types/sdk/codemode/entry/node.d.ts.map +1 -0
  26. package/dist/types/sdk/codemode/execute.d.ts.map +1 -0
  27. package/dist/types/sdk/codemode/execution-sandbox.d.ts.map +1 -0
  28. package/dist/types/sdk/codemode/loop-engine.d.ts.map +1 -0
  29. package/dist/types/sdk/codemode/nodeReceipt.d.ts +65 -0
  30. package/dist/types/sdk/codemode/nodeReceipt.d.ts.map +1 -0
  31. package/dist/types/sdk/codemode/p5-runtime.d.ts.map +1 -0
  32. package/dist/{sdk → types/sdk}/codemode/runtime.d.ts +1 -1
  33. package/dist/types/sdk/codemode/runtime.d.ts.map +1 -0
  34. package/dist/types/sdk/codemode/snapshot.d.ts +72 -0
  35. package/dist/types/sdk/codemode/snapshot.d.ts.map +1 -0
  36. package/dist/types/sdk/codemode/sound-bridge.d.ts.map +1 -0
  37. package/dist/types/sdk/codemode/soundart-engine.d.ts.map +1 -0
  38. package/dist/types/sdk/codemode/soundart-sketches/chladniBloom.d.ts.map +1 -0
  39. package/dist/types/sdk/codemode/soundart-sketches/dualVortex.d.ts.map +1 -0
  40. package/dist/types/sdk/codemode/soundart-sketches/geometryIllusion.d.ts.map +1 -0
  41. package/dist/types/sdk/codemode/soundart-sketches/index.d.ts.map +1 -0
  42. package/dist/types/sdk/codemode/soundart-sketches/isoflow.d.ts.map +1 -0
  43. package/dist/types/sdk/codemode/soundart-sketches/loomWeave.d.ts.map +1 -0
  44. package/dist/types/sdk/codemode/soundart-sketches/noiseTerraces.d.ts.map +1 -0
  45. package/dist/types/sdk/codemode/soundart-sketches/orb.d.ts.map +1 -0
  46. package/dist/types/sdk/codemode/soundart-sketches/pixelGlyphs.d.ts.map +1 -0
  47. package/dist/types/sdk/codemode/soundart-sketches/prismFlowFields.d.ts.map +1 -0
  48. package/dist/types/sdk/codemode/soundart-sketches/radialBurst.d.ts.map +1 -0
  49. package/dist/types/sdk/codemode/soundart-sketches/resonantSoundBodies.d.ts.map +1 -0
  50. package/dist/types/sdk/codemode/soundart-sketches/rings.d.ts.map +1 -0
  51. package/dist/types/sdk/codemode/soundart-sketches/squares.d.ts.map +1 -0
  52. package/dist/types/sdk/codemode/soundart-sketches/waveStripes.d.ts.map +1 -0
  53. package/dist/types/sdk/codemode/static-engine.d.ts.map +1 -0
  54. package/dist/{sdk → types/sdk}/codemode/types.d.ts +96 -0
  55. package/dist/types/sdk/codemode/types.d.ts.map +1 -0
  56. package/dist/{sdk → types/sdk}/codemode/version.d.ts +2 -2
  57. package/dist/types/sdk/codemode/version.d.ts.map +1 -0
  58. package/dist/types/shared/soundSnapshot.d.ts.map +1 -0
  59. package/examples/sketch-minimal.js +27 -0
  60. package/examples/sketch-vars.js +59 -0
  61. package/examples/sketch.js +24 -0
  62. package/package.json +29 -23
  63. package/dist/sdk/codemode/builder-manifest.d.ts.map +0 -1
  64. package/dist/sdk/codemode/builder-manifest.js +0 -97
  65. package/dist/sdk/codemode/core-index.d.ts.map +0 -1
  66. package/dist/sdk/codemode/core-index.js +0 -28
  67. package/dist/sdk/codemode/engine.d.ts.map +0 -1
  68. package/dist/sdk/codemode/engine.js +0 -67
  69. package/dist/sdk/codemode/entry/browser.d.ts.map +0 -1
  70. package/dist/sdk/codemode/entry/browser.js +0 -69
  71. package/dist/sdk/codemode/entry/node.d.ts.map +0 -1
  72. package/dist/sdk/codemode/entry/node.js +0 -35
  73. package/dist/sdk/codemode/execute.d.ts.map +0 -1
  74. package/dist/sdk/codemode/execute.js +0 -283
  75. package/dist/sdk/codemode/execution-sandbox.d.ts.map +0 -1
  76. package/dist/sdk/codemode/execution-sandbox.js +0 -207
  77. package/dist/sdk/codemode/loop-engine.d.ts.map +0 -1
  78. package/dist/sdk/codemode/loop-engine.js +0 -229
  79. package/dist/sdk/codemode/p5-runtime.d.ts.map +0 -1
  80. package/dist/sdk/codemode/p5-runtime.js +0 -1033
  81. package/dist/sdk/codemode/runtime.d.ts.map +0 -1
  82. package/dist/sdk/codemode/runtime.js +0 -220
  83. package/dist/sdk/codemode/sound-bridge.d.ts.map +0 -1
  84. package/dist/sdk/codemode/sound-bridge.js +0 -128
  85. package/dist/sdk/codemode/soundart-engine.d.ts.map +0 -1
  86. package/dist/sdk/codemode/soundart-engine.js +0 -173
  87. package/dist/sdk/codemode/soundart-sketches/chladniBloom.d.ts.map +0 -1
  88. package/dist/sdk/codemode/soundart-sketches/chladniBloom.js +0 -53
  89. package/dist/sdk/codemode/soundart-sketches/dualVortex.d.ts.map +0 -1
  90. package/dist/sdk/codemode/soundart-sketches/dualVortex.js +0 -67
  91. package/dist/sdk/codemode/soundart-sketches/geometryIllusion.d.ts.map +0 -1
  92. package/dist/sdk/codemode/soundart-sketches/geometryIllusion.js +0 -89
  93. package/dist/sdk/codemode/soundart-sketches/index.d.ts.map +0 -1
  94. package/dist/sdk/codemode/soundart-sketches/index.js +0 -72
  95. package/dist/sdk/codemode/soundart-sketches/isoflow.d.ts.map +0 -1
  96. package/dist/sdk/codemode/soundart-sketches/isoflow.js +0 -60
  97. package/dist/sdk/codemode/soundart-sketches/loomWeave.d.ts.map +0 -1
  98. package/dist/sdk/codemode/soundart-sketches/loomWeave.js +0 -59
  99. package/dist/sdk/codemode/soundart-sketches/noiseTerraces.d.ts.map +0 -1
  100. package/dist/sdk/codemode/soundart-sketches/noiseTerraces.js +0 -53
  101. package/dist/sdk/codemode/soundart-sketches/orb.d.ts.map +0 -1
  102. package/dist/sdk/codemode/soundart-sketches/orb.js +0 -50
  103. package/dist/sdk/codemode/soundart-sketches/pixelGlyphs.d.ts.map +0 -1
  104. package/dist/sdk/codemode/soundart-sketches/pixelGlyphs.js +0 -72
  105. package/dist/sdk/codemode/soundart-sketches/prismFlowFields.d.ts.map +0 -1
  106. package/dist/sdk/codemode/soundart-sketches/prismFlowFields.js +0 -51
  107. package/dist/sdk/codemode/soundart-sketches/radialBurst.d.ts.map +0 -1
  108. package/dist/sdk/codemode/soundart-sketches/radialBurst.js +0 -60
  109. package/dist/sdk/codemode/soundart-sketches/resonantSoundBodies.d.ts.map +0 -1
  110. package/dist/sdk/codemode/soundart-sketches/resonantSoundBodies.js +0 -89
  111. package/dist/sdk/codemode/soundart-sketches/rings.d.ts.map +0 -1
  112. package/dist/sdk/codemode/soundart-sketches/rings.js +0 -89
  113. package/dist/sdk/codemode/soundart-sketches/squares.d.ts.map +0 -1
  114. package/dist/sdk/codemode/soundart-sketches/squares.js +0 -52
  115. package/dist/sdk/codemode/soundart-sketches/waveStripes.d.ts.map +0 -1
  116. package/dist/sdk/codemode/soundart-sketches/waveStripes.js +0 -44
  117. package/dist/sdk/codemode/static-engine.d.ts.map +0 -1
  118. package/dist/sdk/codemode/static-engine.js +0 -157
  119. package/dist/sdk/codemode/types.d.ts.map +0 -1
  120. package/dist/sdk/codemode/types.js +0 -34
  121. package/dist/sdk/codemode/version.d.ts.map +0 -1
  122. package/dist/sdk/codemode/version.js +0 -17
  123. package/dist/shared/soundSnapshot.d.ts.map +0 -1
  124. package/dist/shared/soundSnapshot.js +0 -128
  125. /package/dist/{sdk → types/sdk}/codemode/builder-manifest.d.ts +0 -0
  126. /package/dist/{sdk → types/sdk}/codemode/engine.d.ts +0 -0
  127. /package/dist/{sdk → types/sdk}/codemode/entry/node.d.ts +0 -0
  128. /package/dist/{sdk → types/sdk}/codemode/execute.d.ts +0 -0
  129. /package/dist/{sdk → types/sdk}/codemode/execution-sandbox.d.ts +0 -0
  130. /package/dist/{sdk → types/sdk}/codemode/loop-engine.d.ts +0 -0
  131. /package/dist/{sdk → types/sdk}/codemode/p5-runtime.d.ts +0 -0
  132. /package/dist/{sdk → types/sdk}/codemode/sound-bridge.d.ts +0 -0
  133. /package/dist/{sdk → types/sdk}/codemode/soundart-engine.d.ts +0 -0
  134. /package/dist/{sdk → types/sdk}/codemode/soundart-sketches/chladniBloom.d.ts +0 -0
  135. /package/dist/{sdk → types/sdk}/codemode/soundart-sketches/dualVortex.d.ts +0 -0
  136. /package/dist/{sdk → types/sdk}/codemode/soundart-sketches/geometryIllusion.d.ts +0 -0
  137. /package/dist/{sdk → types/sdk}/codemode/soundart-sketches/index.d.ts +0 -0
  138. /package/dist/{sdk → types/sdk}/codemode/soundart-sketches/isoflow.d.ts +0 -0
  139. /package/dist/{sdk → types/sdk}/codemode/soundart-sketches/loomWeave.d.ts +0 -0
  140. /package/dist/{sdk → types/sdk}/codemode/soundart-sketches/noiseTerraces.d.ts +0 -0
  141. /package/dist/{sdk → types/sdk}/codemode/soundart-sketches/orb.d.ts +0 -0
  142. /package/dist/{sdk → types/sdk}/codemode/soundart-sketches/pixelGlyphs.d.ts +0 -0
  143. /package/dist/{sdk → types/sdk}/codemode/soundart-sketches/prismFlowFields.d.ts +0 -0
  144. /package/dist/{sdk → types/sdk}/codemode/soundart-sketches/radialBurst.d.ts +0 -0
  145. /package/dist/{sdk → types/sdk}/codemode/soundart-sketches/resonantSoundBodies.d.ts +0 -0
  146. /package/dist/{sdk → types/sdk}/codemode/soundart-sketches/rings.d.ts +0 -0
  147. /package/dist/{sdk → types/sdk}/codemode/soundart-sketches/squares.d.ts +0 -0
  148. /package/dist/{sdk → types/sdk}/codemode/soundart-sketches/waveStripes.d.ts +0 -0
  149. /package/dist/{sdk → types/sdk}/codemode/static-engine.d.ts +0 -0
  150. /package/dist/{shared → types/shared}/soundSnapshot.d.ts +0 -0
@@ -1,229 +0,0 @@
1
- /**
2
- * NexArt Code Mode Runtime SDK - Loop Engine
3
- * Protocol: v1.2.0 (Phase 3) — HARD ENFORCEMENT
4
- *
5
- * Loop mode renderer: frame-authoritative, stateless execution.
6
- * - Executes setup() once
7
- * - Executes draw() once per frame
8
- * - Clears canvas before each frame (transparent)
9
- * - Resets blend mode to NORMAL before each frame
10
- * - Injects normalized time variables
11
- * - No canvas persistence between frames
12
- *
13
- * Determinism Guarantee:
14
- * Same code + same seed + same VARs = identical frame sequence
15
- *
16
- * Security:
17
- * All external entropy sources are blocked at runtime via execution sandbox.
18
- */
19
- import { DEFAULT_CONFIG } from './types';
20
- import { createP5Runtime, injectProtocolVariables } from './p5-runtime';
21
- import { FORBIDDEN_APIS, createSafeMath } from './execution-sandbox';
22
- let isCancelled = false;
23
- export function cancelLoopMode() {
24
- isCancelled = true;
25
- }
26
- export async function runLoopMode(config, options) {
27
- const { code, seed, vars, onPreview, onProgress, onComplete, onError } = options;
28
- const width = config.width ?? DEFAULT_CONFIG.width;
29
- const height = config.height ?? DEFAULT_CONFIG.height;
30
- const duration = Math.max(DEFAULT_CONFIG.minDuration, Math.min(DEFAULT_CONFIG.maxDuration, config.duration ?? DEFAULT_CONFIG.duration));
31
- const fps = config.fps ?? DEFAULT_CONFIG.fps;
32
- const totalFrames = Math.floor(duration * fps);
33
- isCancelled = false;
34
- try {
35
- onProgress?.({
36
- phase: 'setup',
37
- percent: 0,
38
- message: 'Initializing canvas...',
39
- });
40
- // Create canvas
41
- const canvas = document.createElement('canvas');
42
- canvas.width = width;
43
- canvas.height = height;
44
- // Create p5 runtime with optional seed for determinism
45
- const p = createP5Runtime(canvas, width, height, { seed });
46
- // Inject protocol variables (VAR[0..9])
47
- injectProtocolVariables(p, vars);
48
- // Validate code
49
- const hasDrawFunction = /function\s+draw\s*\(\s*\)/.test(code);
50
- if (!hasDrawFunction) {
51
- throw new Error('Loop Mode requires a draw() function.');
52
- }
53
- const forbiddenPatterns = [
54
- { pattern: /noLoop\s*\(\s*\)/, name: 'noLoop()' },
55
- { pattern: /setTimeout\s*\(/, name: 'setTimeout' },
56
- { pattern: /setInterval\s*\(/, name: 'setInterval' },
57
- { pattern: /requestAnimationFrame\s*\(/, name: 'requestAnimationFrame' },
58
- ];
59
- for (const { pattern, name } of forbiddenPatterns) {
60
- if (pattern.test(code)) {
61
- throw new Error(`Forbidden function in Loop Mode: ${name}`);
62
- }
63
- }
64
- onProgress?.({
65
- phase: 'setup',
66
- percent: 5,
67
- message: 'Parsing code...',
68
- });
69
- // Extract setup() and draw() functions
70
- const setupMatch = code.match(/function\s+setup\s*\(\s*\)\s*\{([\s\S]*?)\}(?=\s*function|\s*$)/);
71
- const drawMatch = code.match(/function\s+draw\s*\(\s*\)\s*\{([\s\S]*?)\}(?=\s*function|\s*$)/);
72
- const setupCode = setupMatch ? setupMatch[1].trim() : '';
73
- const drawCode = drawMatch ? drawMatch[1].trim() : '';
74
- if (!drawCode) {
75
- throw new Error('Loop Mode requires a draw() function with content.');
76
- }
77
- // Inject totalFrames into runtime
78
- p.totalFrames = totalFrames;
79
- // Create sandboxed execution context
80
- // All forbidden APIs are injected as parameters to override globals
81
- const safeMath = createSafeMath();
82
- const forbiddenKeys = Object.keys(FORBIDDEN_APIS);
83
- // Create wrapped functions with p5 context, time variables, VAR, totalFrames, and blocked globals
84
- const wrappedSetup = new Function('p', 'frameCount', 't', 'time', 'tGlobal', 'VAR', 'totalFrames', 'Math', ...forbiddenKeys, `with(p) { ${setupCode} }`);
85
- const wrappedDraw = new Function('p', 'frameCount', 't', 'time', 'tGlobal', 'VAR', 'totalFrames', 'Math', ...forbiddenKeys, `with(p) { ${drawCode} }`);
86
- // Get forbidden values array for execution
87
- const forbiddenValues = forbiddenKeys.map(k => FORBIDDEN_APIS[k]);
88
- onProgress?.({
89
- phase: 'setup',
90
- percent: 10,
91
- message: 'Executing setup()...',
92
- });
93
- // Execute setup() once with time = 0, VAR, totalFrames, and sandboxed context
94
- wrappedSetup(p, 0, 0, 0, 0, p.VAR, totalFrames, safeMath, ...forbiddenValues);
95
- // Capture frames
96
- const frames = [];
97
- onProgress?.({
98
- phase: 'rendering',
99
- frame: 0,
100
- totalFrames,
101
- percent: 10,
102
- message: `Rendering frames (0/${totalFrames})...`,
103
- });
104
- for (let frame = 0; frame < totalFrames; frame++) {
105
- if (isCancelled) {
106
- throw new Error('Rendering cancelled');
107
- }
108
- // Calculate normalized time variables
109
- // t = frame / totalFrames (range [0, 1))
110
- const t = frame / totalFrames;
111
- const time = t * duration;
112
- // Update p5 runtime frameCount
113
- p.frameCount = frame;
114
- // CRITICAL: Reset canvas state before each draw() call
115
- // This enforces stateless, frame-authoritative rendering
116
- // 1. Clear canvas (transparent)
117
- p.clear();
118
- // 2. Reset blend mode to NORMAL (Protocol v1.1 requirement)
119
- // Prevents blend mode state from persisting across frames
120
- p.blendMode('NORMAL');
121
- // Execute draw() with time variables, VAR, totalFrames, and sandboxed context
122
- wrappedDraw(p, frame, t, time, t, p.VAR, totalFrames, safeMath, ...forbiddenValues);
123
- // Capture frame as PNG blob
124
- const blob = await new Promise((resolve, reject) => {
125
- canvas.toBlob((b) => b ? resolve(b) : reject(new Error(`Failed to capture frame ${frame}`)), 'image/png');
126
- });
127
- frames.push(blob);
128
- // Provide preview on first frame
129
- if (frame === 0) {
130
- onPreview?.(canvas);
131
- }
132
- // Update progress
133
- const percent = 10 + Math.floor((frame / totalFrames) * 60);
134
- onProgress?.({
135
- phase: 'rendering',
136
- frame: frame + 1,
137
- totalFrames,
138
- percent,
139
- message: `Rendering frames (${frame + 1}/${totalFrames})...`,
140
- });
141
- // Yield to prevent blocking UI
142
- if (frame % 10 === 0) {
143
- await new Promise(resolve => setTimeout(resolve, 0));
144
- }
145
- }
146
- onProgress?.({
147
- phase: 'encoding',
148
- frame: totalFrames,
149
- totalFrames,
150
- percent: 70,
151
- message: 'Encoding video...',
152
- });
153
- // Encode to video (MP4)
154
- const videoBlob = await encodeFramesToMP4(frames, fps, width, height, (progress) => {
155
- const percent = 70 + Math.floor(progress * 30);
156
- onProgress?.({
157
- phase: 'encoding',
158
- frame: totalFrames,
159
- totalFrames,
160
- percent,
161
- message: `Encoding video (${Math.floor(progress * 100)}%)...`,
162
- });
163
- });
164
- onProgress?.({
165
- phase: 'complete',
166
- frame: totalFrames,
167
- totalFrames,
168
- percent: 100,
169
- message: 'Complete',
170
- });
171
- const result = {
172
- type: 'video',
173
- blob: videoBlob,
174
- frames: totalFrames,
175
- duration,
176
- };
177
- onComplete(result);
178
- }
179
- catch (error) {
180
- const err = error instanceof Error ? error : new Error(String(error));
181
- onError?.(err);
182
- }
183
- }
184
- /**
185
- * Encode frames to MP4 video
186
- * Uses server-side encoding endpoint for cross-browser reliability
187
- */
188
- async function encodeFramesToMP4(frames, fps, width, height, onProgress) {
189
- // Convert frames to base64 for server transport
190
- const frameDataUrls = [];
191
- for (let i = 0; i < frames.length; i++) {
192
- const reader = new FileReader();
193
- const dataUrl = await new Promise((resolve, reject) => {
194
- reader.onload = () => resolve(reader.result);
195
- reader.onerror = reject;
196
- reader.readAsDataURL(frames[i]);
197
- });
198
- frameDataUrls.push(dataUrl);
199
- onProgress?.(i / frames.length * 0.3);
200
- }
201
- // Send to server for encoding
202
- const response = await fetch('/api/encode-loop', {
203
- method: 'POST',
204
- headers: { 'Content-Type': 'application/json' },
205
- body: JSON.stringify({
206
- frames: frameDataUrls,
207
- fps,
208
- width,
209
- height,
210
- }),
211
- });
212
- if (!response.ok) {
213
- const errorText = await response.text();
214
- throw new Error(`Video encoding failed: ${errorText}`);
215
- }
216
- onProgress?.(0.8);
217
- const data = await response.json();
218
- if (!data.video) {
219
- throw new Error('No video data returned from encoder');
220
- }
221
- // Convert base64 to blob
222
- const binaryString = atob(data.video.split(',')[1] || data.video);
223
- const bytes = new Uint8Array(binaryString.length);
224
- for (let i = 0; i < binaryString.length; i++) {
225
- bytes[i] = binaryString.charCodeAt(i);
226
- }
227
- onProgress?.(1);
228
- return new Blob([bytes], { type: 'video/mp4' });
229
- }
@@ -1 +0,0 @@
1
- {"version":3,"file":"p5-runtime.d.ts","sourceRoot":"","sources":["../../../p5-runtime.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAG7C;;;;GAIG;AACH,eAAO,MAAM,0BAA0B,UAAmB,CAAC;AAC3D,eAAO,MAAM,wBAAwB,IAAiB,CAAC;AACvD,eAAO,MAAM,qBAAqB,EAAG,MAAe,CAAC;AAErD,MAAM,WAAW,SAAS;IACxB,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;CACpB;AAmED,MAAM,WAAW,eAAe;IAC9B,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,KAAK,aAAa,GAAG,iBAAiB,CAAC;AAEvC,wBAAgB,eAAe,CAC7B,MAAM,EAAE,aAAa,EACrB,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EACd,MAAM,CAAC,EAAE,eAAe,GACvB,SAAS,CAs8BX;AAED,wBAAgB,mBAAmB,CAAC,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,aAAa,GAAG,IAAI,CAM3E;AAED;;;GAGG;AACH,eAAO,MAAM,SAAS,KAAK,CAAC;AAC5B,eAAO,MAAM,OAAO,IAAI,CAAC;AACzB,eAAO,MAAM,OAAO,MAAM,CAAC;AAE3B;;;;;;;;;GASG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,GAAG,SAAS,MAAM,EAAE,CAmCpE;AAED,wBAAgB,uBAAuB,CAAC,CAAC,EAAE,SAAS,EAAE,IAAI,CAAC,EAAE,MAAM,EAAE,GAAG,IAAI,CAE3E"}