deio-scroll 1.0.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 (205) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +21 -0
  3. package/dist/api/server.d.ts +3 -0
  4. package/dist/api/server.d.ts.map +1 -0
  5. package/dist/api/server.js +393 -0
  6. package/dist/api/server.js.map +1 -0
  7. package/dist/artifacts/store.d.ts +24 -0
  8. package/dist/artifacts/store.d.ts.map +1 -0
  9. package/dist/artifacts/store.js +43 -0
  10. package/dist/artifacts/store.js.map +1 -0
  11. package/dist/browser/componentInteraction.d.ts +24 -0
  12. package/dist/browser/componentInteraction.d.ts.map +1 -0
  13. package/dist/browser/componentInteraction.js +328 -0
  14. package/dist/browser/componentInteraction.js.map +1 -0
  15. package/dist/browser/composition.d.ts +42 -0
  16. package/dist/browser/composition.d.ts.map +1 -0
  17. package/dist/browser/composition.js +132 -0
  18. package/dist/browser/composition.js.map +1 -0
  19. package/dist/browser/cookies.d.ts +3 -0
  20. package/dist/browser/cookies.d.ts.map +1 -0
  21. package/dist/browser/cookies.js +20 -0
  22. package/dist/browser/cookies.js.map +1 -0
  23. package/dist/browser/curves.d.ts +4 -0
  24. package/dist/browser/curves.d.ts.map +1 -0
  25. package/dist/browser/curves.js +35 -0
  26. package/dist/browser/curves.js.map +1 -0
  27. package/dist/browser/detectScrollMode.d.ts +5 -0
  28. package/dist/browser/detectScrollMode.d.ts.map +1 -0
  29. package/dist/browser/detectScrollMode.js +61 -0
  30. package/dist/browser/detectScrollMode.js.map +1 -0
  31. package/dist/browser/directionGuardrails.d.ts +22 -0
  32. package/dist/browser/directionGuardrails.d.ts.map +1 -0
  33. package/dist/browser/directionGuardrails.js +99 -0
  34. package/dist/browser/directionGuardrails.js.map +1 -0
  35. package/dist/browser/goto.d.ts +9 -0
  36. package/dist/browser/goto.d.ts.map +1 -0
  37. package/dist/browser/goto.js +62 -0
  38. package/dist/browser/goto.js.map +1 -0
  39. package/dist/browser/hydrate.d.ts +8 -0
  40. package/dist/browser/hydrate.d.ts.map +1 -0
  41. package/dist/browser/hydrate.js +73 -0
  42. package/dist/browser/hydrate.js.map +1 -0
  43. package/dist/browser/mediaClock.d.ts +9 -0
  44. package/dist/browser/mediaClock.d.ts.map +1 -0
  45. package/dist/browser/mediaClock.js +86 -0
  46. package/dist/browser/mediaClock.js.map +1 -0
  47. package/dist/browser/motion.d.ts +21 -0
  48. package/dist/browser/motion.d.ts.map +1 -0
  49. package/dist/browser/motion.js +42 -0
  50. package/dist/browser/motion.js.map +1 -0
  51. package/dist/browser/networkPolicy.d.ts +11 -0
  52. package/dist/browser/networkPolicy.d.ts.map +1 -0
  53. package/dist/browser/networkPolicy.js +119 -0
  54. package/dist/browser/networkPolicy.js.map +1 -0
  55. package/dist/browser/prime.d.ts +3 -0
  56. package/dist/browser/prime.d.ts.map +1 -0
  57. package/dist/browser/prime.js +13 -0
  58. package/dist/browser/prime.js.map +1 -0
  59. package/dist/browser/sanitize.d.ts +3 -0
  60. package/dist/browser/sanitize.d.ts.map +1 -0
  61. package/dist/browser/sanitize.js +37 -0
  62. package/dist/browser/sanitize.js.map +1 -0
  63. package/dist/browser/scroll.d.ts +29 -0
  64. package/dist/browser/scroll.d.ts.map +1 -0
  65. package/dist/browser/scroll.js +420 -0
  66. package/dist/browser/scroll.js.map +1 -0
  67. package/dist/browser/scrollEasing.d.ts +5 -0
  68. package/dist/browser/scrollEasing.d.ts.map +1 -0
  69. package/dist/browser/scrollEasing.js +40 -0
  70. package/dist/browser/scrollEasing.js.map +1 -0
  71. package/dist/browser/scrollReadiness.d.ts +25 -0
  72. package/dist/browser/scrollReadiness.d.ts.map +1 -0
  73. package/dist/browser/scrollReadiness.js +105 -0
  74. package/dist/browser/scrollReadiness.js.map +1 -0
  75. package/dist/browser/urlGuard.d.ts +4 -0
  76. package/dist/browser/urlGuard.d.ts.map +1 -0
  77. package/dist/browser/urlGuard.js +22 -0
  78. package/dist/browser/urlGuard.js.map +1 -0
  79. package/dist/browser/virtualScroll.d.ts +19 -0
  80. package/dist/browser/virtualScroll.d.ts.map +1 -0
  81. package/dist/browser/virtualScroll.js +50 -0
  82. package/dist/browser/virtualScroll.js.map +1 -0
  83. package/dist/capture/detectMargins.d.ts +6 -0
  84. package/dist/capture/detectMargins.d.ts.map +1 -0
  85. package/dist/capture/detectMargins.js +145 -0
  86. package/dist/capture/detectMargins.js.map +1 -0
  87. package/dist/capture/frameRecorder.d.ts +29 -0
  88. package/dist/capture/frameRecorder.d.ts.map +1 -0
  89. package/dist/capture/frameRecorder.js +74 -0
  90. package/dist/capture/frameRecorder.js.map +1 -0
  91. package/dist/capture/stitchFrames.d.ts +9 -0
  92. package/dist/capture/stitchFrames.d.ts.map +1 -0
  93. package/dist/capture/stitchFrames.js +62 -0
  94. package/dist/capture/stitchFrames.js.map +1 -0
  95. package/dist/cli.d.ts +3 -0
  96. package/dist/cli.d.ts.map +1 -0
  97. package/dist/cli.js +329 -0
  98. package/dist/cli.js.map +1 -0
  99. package/dist/config/browserLaunch.d.ts +13 -0
  100. package/dist/config/browserLaunch.d.ts.map +1 -0
  101. package/dist/config/browserLaunch.js +63 -0
  102. package/dist/config/browserLaunch.js.map +1 -0
  103. package/dist/config/recordingProfile.d.ts +10 -0
  104. package/dist/config/recordingProfile.d.ts.map +1 -0
  105. package/dist/config/recordingProfile.js +25 -0
  106. package/dist/config/recordingProfile.js.map +1 -0
  107. package/dist/config/runtimeMode.d.ts +2 -0
  108. package/dist/config/runtimeMode.d.ts.map +1 -0
  109. package/dist/config/runtimeMode.js +4 -0
  110. package/dist/config/runtimeMode.js.map +1 -0
  111. package/dist/config/virtualScroll.d.ts +8 -0
  112. package/dist/config/virtualScroll.d.ts.map +1 -0
  113. package/dist/config/virtualScroll.js +19 -0
  114. package/dist/config/virtualScroll.js.map +1 -0
  115. package/dist/contracts.d.ts +157 -0
  116. package/dist/contracts.d.ts.map +1 -0
  117. package/dist/contracts.js +136 -0
  118. package/dist/contracts.js.map +1 -0
  119. package/dist/editor/compileVideo.d.ts +21 -0
  120. package/dist/editor/compileVideo.d.ts.map +1 -0
  121. package/dist/editor/compileVideo.js +104 -0
  122. package/dist/editor/compileVideo.js.map +1 -0
  123. package/dist/editor/composeComparison.d.ts +30 -0
  124. package/dist/editor/composeComparison.d.ts.map +1 -0
  125. package/dist/editor/composeComparison.js +315 -0
  126. package/dist/editor/composeComparison.js.map +1 -0
  127. package/dist/editor/composeResponsiveness.d.ts +19 -0
  128. package/dist/editor/composeResponsiveness.d.ts.map +1 -0
  129. package/dist/editor/composeResponsiveness.js +198 -0
  130. package/dist/editor/composeResponsiveness.js.map +1 -0
  131. package/dist/editor/frameVideo.d.ts +11 -0
  132. package/dist/editor/frameVideo.d.ts.map +1 -0
  133. package/dist/editor/frameVideo.js +181 -0
  134. package/dist/editor/frameVideo.js.map +1 -0
  135. package/dist/index.d.ts +3 -0
  136. package/dist/index.d.ts.map +1 -0
  137. package/dist/index.js +2 -0
  138. package/dist/index.js.map +1 -0
  139. package/dist/inspection/inspectWebsite.d.ts +21 -0
  140. package/dist/inspection/inspectWebsite.d.ts.map +1 -0
  141. package/dist/inspection/inspectWebsite.js +412 -0
  142. package/dist/inspection/inspectWebsite.js.map +1 -0
  143. package/dist/jobs/manager.d.ts +123 -0
  144. package/dist/jobs/manager.d.ts.map +1 -0
  145. package/dist/jobs/manager.js +378 -0
  146. package/dist/jobs/manager.js.map +1 -0
  147. package/dist/jobs/store.d.ts +150 -0
  148. package/dist/jobs/store.d.ts.map +1 -0
  149. package/dist/jobs/store.js +446 -0
  150. package/dist/jobs/store.js.map +1 -0
  151. package/dist/jobs/thumbnail.d.ts +2 -0
  152. package/dist/jobs/thumbnail.d.ts.map +1 -0
  153. package/dist/jobs/thumbnail.js +36 -0
  154. package/dist/jobs/thumbnail.js.map +1 -0
  155. package/dist/pipeline/processRecordingRequest.d.ts +4 -0
  156. package/dist/pipeline/processRecordingRequest.d.ts.map +1 -0
  157. package/dist/pipeline/processRecordingRequest.js +17 -0
  158. package/dist/pipeline/processRecordingRequest.js.map +1 -0
  159. package/dist/pipeline/recordComparison.d.ts +4 -0
  160. package/dist/pipeline/recordComparison.d.ts.map +1 -0
  161. package/dist/pipeline/recordComparison.js +99 -0
  162. package/dist/pipeline/recordComparison.js.map +1 -0
  163. package/dist/pipeline/recordResponsiveness.d.ts +4 -0
  164. package/dist/pipeline/recordResponsiveness.d.ts.map +1 -0
  165. package/dist/pipeline/recordResponsiveness.js +122 -0
  166. package/dist/pipeline/recordResponsiveness.js.map +1 -0
  167. package/dist/pipeline/recordWebsite.d.ts +11 -0
  168. package/dist/pipeline/recordWebsite.d.ts.map +1 -0
  169. package/dist/pipeline/recordWebsite.js +446 -0
  170. package/dist/pipeline/recordWebsite.js.map +1 -0
  171. package/dist/pipeline/styleRecording.d.ts +12 -0
  172. package/dist/pipeline/styleRecording.d.ts.map +1 -0
  173. package/dist/pipeline/styleRecording.js +59 -0
  174. package/dist/pipeline/styleRecording.js.map +1 -0
  175. package/dist/transcode/ffmpeg.d.ts +4 -0
  176. package/dist/transcode/ffmpeg.d.ts.map +1 -0
  177. package/dist/transcode/ffmpeg.js +62 -0
  178. package/dist/transcode/ffmpeg.js.map +1 -0
  179. package/dist/transcode/probe.d.ts +7 -0
  180. package/dist/transcode/probe.d.ts.map +1 -0
  181. package/dist/transcode/probe.js +91 -0
  182. package/dist/transcode/probe.js.map +1 -0
  183. package/dist/transcode/quality.d.ts +8 -0
  184. package/dist/transcode/quality.d.ts.map +1 -0
  185. package/dist/transcode/quality.js +13 -0
  186. package/dist/transcode/quality.js.map +1 -0
  187. package/dist/types.d.ts +302 -0
  188. package/dist/types.d.ts.map +1 -0
  189. package/dist/types.js +2 -0
  190. package/dist/types.js.map +1 -0
  191. package/dist/worker.d.ts +3 -0
  192. package/dist/worker.d.ts.map +1 -0
  193. package/dist/worker.js +22 -0
  194. package/dist/worker.js.map +1 -0
  195. package/package.json +63 -0
  196. package/public/assets/index-C63t4P1L.css +1 -0
  197. package/public/assets/index-Sfgf7dSH.js +9 -0
  198. package/public/background_presets/gray_noise_gradient.png +0 -0
  199. package/public/background_presets/paper_blue.png +0 -0
  200. package/public/background_presets/red_blocks_gradient.png +0 -0
  201. package/public/deio-scroll-mark.svg +12 -0
  202. package/public/favicon.svg +1 -0
  203. package/public/icons.svg +24 -0
  204. package/public/index.html +16 -0
  205. package/public/scrollizard-mark.png +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"frameRecorder.js","sourceRoot":"","sources":["../../src/capture/frameRecorder.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ export interface StitchOptions {
2
+ width?: number;
3
+ height?: number;
4
+ preset?: string;
5
+ crf?: number;
6
+ signal?: AbortSignal;
7
+ }
8
+ export declare function stitchFramesToVideo(framesDir: string, outputPath: string, fps: number, options?: StitchOptions): Promise<void>;
9
+ //# sourceMappingURL=stitchFrames.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stitchFrames.d.ts","sourceRoot":"","sources":["../../src/capture/stitchFrames.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,aAAa;IAC5B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AAED,wBAAsB,mBAAmB,CACvC,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,EAClB,GAAG,EAAE,MAAM,EACX,OAAO,CAAC,EAAE,aAAa,GACtB,OAAO,CAAC,IAAI,CAAC,CAiEf"}
@@ -0,0 +1,62 @@
1
+ import { spawn } from "node:child_process";
2
+ import path from "node:path";
3
+ export async function stitchFramesToVideo(framesDir, outputPath, fps, options) {
4
+ const framePattern = path.join(framesDir, "frame-%06d.jpg");
5
+ const preset = options?.preset ?? "fast";
6
+ const crf = options?.crf ?? (preset === "fast" ? 26 : 18);
7
+ const args = [
8
+ "-y",
9
+ "-framerate",
10
+ String(fps),
11
+ "-i",
12
+ framePattern,
13
+ "-c:v",
14
+ "libx264",
15
+ "-pix_fmt",
16
+ "yuv420p",
17
+ "-preset",
18
+ preset,
19
+ "-crf",
20
+ String(crf),
21
+ ];
22
+ // Add scaling/padding filters to ensure width and height are divisible by 2 for libx264
23
+ const vfFilters = [];
24
+ if (options?.width && options?.height) {
25
+ const evenW = options.width % 2 === 0 ? options.width : options.width - 1;
26
+ const evenH = options.height % 2 === 0 ? options.height : options.height - 1;
27
+ vfFilters.push(`scale=${evenW}:${evenH}:flags=bicubic`);
28
+ }
29
+ else {
30
+ vfFilters.push("scale=trunc(iw/2)*2:trunc(ih/2)*2");
31
+ }
32
+ if (vfFilters.length > 0) {
33
+ args.push("-vf", vfFilters.join(","));
34
+ }
35
+ args.push(outputPath);
36
+ return new Promise((resolve, reject) => {
37
+ const proc = spawn("ffmpeg", args);
38
+ const abort = () => proc.kill("SIGTERM");
39
+ options?.signal?.addEventListener("abort", abort, { once: true });
40
+ let stderr = "";
41
+ proc.stderr?.on("data", (data) => {
42
+ stderr += data.toString();
43
+ });
44
+ proc.on("close", (code) => {
45
+ options?.signal?.removeEventListener("abort", abort);
46
+ if (options?.signal?.aborted) {
47
+ reject(options.signal.reason ?? new Error("Cancelled"));
48
+ }
49
+ else if (code === 0) {
50
+ resolve();
51
+ }
52
+ else {
53
+ const conciseStderr = stderr.trim().slice(-3000);
54
+ reject(new Error(`FFmpeg stitch failed with code ${code}: ${conciseStderr}`));
55
+ }
56
+ });
57
+ proc.on("error", (error) => {
58
+ reject(error);
59
+ });
60
+ });
61
+ }
62
+ //# sourceMappingURL=stitchFrames.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stitchFrames.js","sourceRoot":"","sources":["../../src/capture/stitchFrames.ts"],"names":[],"mappings":"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"}
package/dist/cli.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ import "dotenv/config";
3
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA,OAAO,eAAe,CAAC"}
package/dist/cli.js ADDED
@@ -0,0 +1,329 @@
1
+ #!/usr/bin/env node
2
+ import "dotenv/config";
3
+ import { spawn, spawnSync } from "node:child_process";
4
+ import fs from "node:fs";
5
+ import fsPromises from "node:fs/promises";
6
+ import path from "node:path";
7
+ import { createRequire } from "node:module";
8
+ import { RecordingJobManager } from "./jobs/manager.js";
9
+ const packageRequire = createRequire(import.meta.url);
10
+ const VERSION = packageRequire("../package.json").version;
11
+ const DEFAULT_PORT = 3847;
12
+ const CURVES = new Set([
13
+ "linear",
14
+ "ease-in",
15
+ "ease-out",
16
+ "ease-in-out",
17
+ "ease-in-cubic",
18
+ "ease-out-cubic",
19
+ "ease-in-out-cubic",
20
+ ]);
21
+ async function main() {
22
+ const options = parseArgs(process.argv.slice(2));
23
+ if (options.command === "help")
24
+ return printHelp();
25
+ if (options.command === "version")
26
+ return console.log(VERSION);
27
+ if (options.command === "setup")
28
+ return setup();
29
+ if (options.command === "serve")
30
+ return serve(options);
31
+ return record(options);
32
+ }
33
+ function parseArgs(args) {
34
+ const options = {
35
+ command: "serve",
36
+ curve: "ease-in-out",
37
+ speed: 1,
38
+ quality: "medium",
39
+ viewport: { width: 1440, height: 900 },
40
+ outputDir: path.resolve("deio-output"),
41
+ port: DEFAULT_PORT,
42
+ host: "127.0.0.1",
43
+ open: true,
44
+ };
45
+ const first = args[0];
46
+ if (first === "--help" || first === "-h" || first === "help") {
47
+ options.command = "help";
48
+ return options;
49
+ }
50
+ if (first === "--version" || first === "-v" || first === "version") {
51
+ options.command = "version";
52
+ return options;
53
+ }
54
+ if (first === "setup") {
55
+ options.command = "setup";
56
+ return options;
57
+ }
58
+ let index = 0;
59
+ if (first === "serve") {
60
+ options.command = "serve";
61
+ index++;
62
+ }
63
+ else if (first === "record") {
64
+ options.command = "record";
65
+ index++;
66
+ }
67
+ else if (first && !first.startsWith("-")) {
68
+ options.command = "record";
69
+ options.target = first;
70
+ index++;
71
+ }
72
+ while (index < args.length) {
73
+ const arg = args[index++];
74
+ if (arg === "--no-open")
75
+ options.open = false;
76
+ else if (arg === "--open")
77
+ options.open = true;
78
+ else if (arg === "--curve")
79
+ options.curve = parseCurve(requiredValue(args, index++, arg));
80
+ else if (arg === "--speed")
81
+ options.speed = positiveNumber(requiredValue(args, index++, arg), "speed");
82
+ else if (arg === "--quality")
83
+ options.quality = parseQuality(requiredValue(args, index++, arg));
84
+ else if (arg === "--viewport")
85
+ options.viewport = parseViewport(requiredValue(args, index++, arg));
86
+ else if (arg === "--output")
87
+ options.outputDir = path.resolve(requiredValue(args, index++, arg));
88
+ else if (arg === "--port")
89
+ options.port = integer(requiredValue(args, index++, arg), "port", 1, 65_535);
90
+ else if (arg === "--host")
91
+ options.host = requiredValue(args, index++, arg);
92
+ else if (arg === "--help" || arg === "-h")
93
+ options.command = "help";
94
+ else if (!arg.startsWith("-") && options.command === "record" && !options.target)
95
+ options.target = arg;
96
+ // Friendly shorthand: `deio <url> linear speed-1`.
97
+ else if (CURVES.has(arg))
98
+ options.curve = parseCurve(arg);
99
+ else if (/^speed-/i.test(arg))
100
+ options.speed = positiveNumber(arg.slice(6), "speed");
101
+ else
102
+ throw new Error(`Unknown option: ${arg}. Run deio --help for usage.`);
103
+ }
104
+ if (options.command === "record" && options.target?.toLowerCase().endsWith(".json")) {
105
+ options.configPath = options.target;
106
+ options.target = undefined;
107
+ }
108
+ if (options.command === "record" && !options.target && !options.configPath) {
109
+ throw new Error("Missing website URL. Run deio --help for usage.");
110
+ }
111
+ return options;
112
+ }
113
+ async function serve(options) {
114
+ const localUrl = `http://${displayHost(options.host)}:${options.port}`;
115
+ if (await isRunningDeio(localUrl)) {
116
+ console.log(`Deio is already running at ${localUrl}`);
117
+ if (options.open)
118
+ openBrowser(localUrl);
119
+ return;
120
+ }
121
+ process.env.PORT = String(options.port);
122
+ process.env.HOST = options.host;
123
+ process.env.OUTPUT_DIR = options.outputDir;
124
+ console.log(`Starting Deio at ${localUrl}`);
125
+ if (options.open) {
126
+ void waitUntilReady(localUrl).then(() => openBrowser(localUrl));
127
+ }
128
+ await import("./api/server.js");
129
+ }
130
+ async function record(options) {
131
+ await assertRuntimeReady();
132
+ const request = options.configPath
133
+ ? JSON.parse(await fsPromises.readFile(path.resolve(options.configPath), "utf8"))
134
+ : buildRequest(options);
135
+ await fsPromises.mkdir(options.outputDir, { recursive: true });
136
+ const manager = new RecordingJobManager(options.outputDir);
137
+ await manager.initialize();
138
+ const shutdown = () => void manager.shutdown().finally(() => process.exit(130));
139
+ process.once("SIGINT", shutdown);
140
+ process.once("SIGTERM", shutdown);
141
+ try {
142
+ console.log(`Recording ${request.targetUrl}`);
143
+ console.log(`curve: ${request.animationConfig?.scrollCurve?.preset ?? "ease-in-out"} · speed: ${options.speed}x · quality: ${request.videoConfig.qualityPreset ?? "medium"}`);
144
+ const queued = await manager.create(request);
145
+ console.log(`job: ${queued.jobId}`);
146
+ const job = await manager.waitForCompletion(queued.jobId);
147
+ if (job.status !== "completed" || !job.result) {
148
+ throw new Error(job.error?.message ?? `Recording ${job.status}`);
149
+ }
150
+ console.log("Recording complete");
151
+ console.log(path.join(options.outputDir, job.jobId, "output.mp4"));
152
+ }
153
+ finally {
154
+ await manager.shutdown();
155
+ }
156
+ }
157
+ function buildRequest(options) {
158
+ return {
159
+ targetUrl: normalizeUrl(options.target),
160
+ exportFormat: "mp4",
161
+ videoConfig: {
162
+ framerate: options.quality === "low" ? 30 : 60,
163
+ qualityPreset: options.quality,
164
+ viewport: {
165
+ ...options.viewport,
166
+ deviceScaleFactor: options.quality === "high" ? 2 : 1,
167
+ },
168
+ },
169
+ animationConfig: {
170
+ pixelsPerFrame: 16 * options.speed,
171
+ preRecordingDelayMs: options.quality === "low" ? 500 : 2_000,
172
+ removeOverlayElements: true,
173
+ heroHoldMs: 1_500,
174
+ scrollCurve: { preset: options.curve },
175
+ scrollMode: "auto",
176
+ fastMode: options.quality === "low",
177
+ captureMode: options.quality === "low" ? "preview" : "export",
178
+ },
179
+ backgroundPreset: "none",
180
+ addShadow: false,
181
+ roundedCorners: false,
182
+ };
183
+ }
184
+ async function setup() {
185
+ console.log("Installing Playwright Chromium…");
186
+ const packageJson = packageRequire.resolve("playwright/package.json");
187
+ const cli = path.join(path.dirname(packageJson), "cli.js");
188
+ const result = spawnSync(process.execPath, [cli, "install", "chromium"], { stdio: "inherit" });
189
+ if (result.status !== 0)
190
+ throw new Error("Chromium installation failed.");
191
+ if (hasFfmpeg()) {
192
+ console.log("ffmpeg: found");
193
+ }
194
+ else {
195
+ console.warn("ffmpeg was not found on PATH. Install it with your system package manager:");
196
+ console.warn(" Ubuntu/Debian: sudo apt install ffmpeg");
197
+ console.warn(" macOS: brew install ffmpeg");
198
+ console.warn(" Windows: winget install Gyan.FFmpeg");
199
+ }
200
+ console.log("Deio setup complete.");
201
+ }
202
+ async function assertRuntimeReady() {
203
+ if (!hasFfmpeg())
204
+ throw new Error("ffmpeg was not found on PATH. Install ffmpeg, then run `npx deio-scroll setup`.");
205
+ const { chromium } = await import("playwright");
206
+ if (!fs.existsSync(chromium.executablePath())) {
207
+ throw new Error("Playwright Chromium is not installed. Run `npx deio-scroll setup` first.");
208
+ }
209
+ }
210
+ function hasFfmpeg() {
211
+ return spawnSync("ffmpeg", ["-version"], { stdio: "ignore" }).status === 0;
212
+ }
213
+ function openBrowser(url) {
214
+ let command;
215
+ let args;
216
+ if (process.platform === "darwin")
217
+ [command, args] = ["open", [url]];
218
+ else if (process.platform === "win32")
219
+ [command, args] = ["cmd", ["/c", "start", "", url]];
220
+ else
221
+ [command, args] = ["xdg-open", [url]];
222
+ const child = spawn(command, args, { detached: true, stdio: "ignore" });
223
+ child.on("error", () => console.log(`Open ${url} in your browser.`));
224
+ child.unref();
225
+ }
226
+ async function waitUntilReady(url) {
227
+ for (let attempt = 0; attempt < 50; attempt++) {
228
+ if (await isRunningDeio(url))
229
+ return;
230
+ await new Promise((resolve) => setTimeout(resolve, 100));
231
+ }
232
+ console.log(`Open ${url} in your browser.`);
233
+ }
234
+ async function isRunningDeio(url) {
235
+ try {
236
+ const response = await fetch(`${url}/health`, { signal: AbortSignal.timeout(400) });
237
+ const body = await response.json();
238
+ return response.ok && body.ok === true;
239
+ }
240
+ catch {
241
+ return false;
242
+ }
243
+ }
244
+ function normalizeUrl(value) {
245
+ const candidate = /^[a-z][a-z\d+.-]*:\/\//i.test(value) ? value : `https://${value}`;
246
+ try {
247
+ return new URL(candidate).toString();
248
+ }
249
+ catch {
250
+ throw new Error(`Invalid website URL: ${value}`);
251
+ }
252
+ }
253
+ function parseCurve(value) {
254
+ if (!CURVES.has(value)) {
255
+ throw new Error(`Invalid curve: ${value}. Choose ${[...CURVES].join(", ")}.`);
256
+ }
257
+ return value;
258
+ }
259
+ function parseQuality(value) {
260
+ if (value !== "high" && value !== "medium" && value !== "low") {
261
+ throw new Error("Quality must be high, medium, or low.");
262
+ }
263
+ return value;
264
+ }
265
+ function parseViewport(value) {
266
+ const match = value.match(/^(\d+)x(\d+)$/i);
267
+ if (!match)
268
+ throw new Error("Viewport must look like 1440x900.");
269
+ return {
270
+ width: integer(match[1], "viewport width", 320, 7680),
271
+ height: integer(match[2], "viewport height", 240, 4320),
272
+ };
273
+ }
274
+ function positiveNumber(value, name) {
275
+ const number = Number(value);
276
+ if (!Number.isFinite(number) || number <= 0)
277
+ throw new Error(`${name} must be greater than zero.`);
278
+ return number;
279
+ }
280
+ function integer(value, name, min, max) {
281
+ const number = Number(value);
282
+ if (!Number.isInteger(number) || number < min || number > max) {
283
+ throw new Error(`${name} must be an integer from ${min} to ${max}.`);
284
+ }
285
+ return number;
286
+ }
287
+ function requiredValue(args, index, option) {
288
+ const value = args[index];
289
+ if (!value || value.startsWith("--"))
290
+ throw new Error(`${option} requires a value.`);
291
+ return value;
292
+ }
293
+ function displayHost(host) {
294
+ return host === "0.0.0.0" ? "127.0.0.1" : host;
295
+ }
296
+ function printHelp() {
297
+ console.log(`Deio — smooth-scroll website recordings
298
+
299
+ Usage:
300
+ deio Open the local web app
301
+ deio serve [options] Open the local web app
302
+ deio <website> [options] Record a website
303
+ deio record <website|config.json> [options]
304
+ deio setup Install Chromium and check ffmpeg
305
+
306
+ Recording options:
307
+ --curve <preset> linear, ease-in, ease-out, ease-in-out, or cubic variants
308
+ --speed <multiplier> Scroll speed multiplier (default: 1)
309
+ --quality <preset> low, medium, or high (default: medium)
310
+ --viewport <WxH> Browser viewport (default: 1440x900)
311
+ --output <directory> Output root (default: ./deio-output)
312
+
313
+ Server options:
314
+ --port <number> Local port (default: 3847)
315
+ --host <address> Bind address (default: 127.0.0.1)
316
+ --no-open Do not open a browser
317
+
318
+ Examples:
319
+ npx deio-scroll
320
+ npx deio-scroll example.com --curve linear --speed 1
321
+ npx deio-scroll record https://example.com --quality high --viewport 1920x1080
322
+
323
+ The shorthand \`deio example.com linear speed-1\` is also accepted.`);
324
+ }
325
+ main().catch((error) => {
326
+ console.error(`deio: ${error instanceof Error ? error.message : error}`);
327
+ process.exitCode = 1;
328
+ });
329
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ import type { AnimationConfig } from "../types.js";
2
+ export interface BrowserLaunchOptions {
3
+ headless: boolean;
4
+ args: string[];
5
+ }
6
+ /**
7
+ * WebGL scroll-scrubbing sites run their render loop at only a few fps in
8
+ * headless Chromium. Use a headed browser with real GPU for virtual-scroll.
9
+ */
10
+ export declare function resolveBrowserLaunch(animation: AnimationConfig): BrowserLaunchOptions;
11
+ export declare function launchArgsForHeadless(headless: boolean): string[];
12
+ export declare function shouldWarnHeadlessVirtualCapture(scrollStrategy: "document" | "virtual", captureHeadless: boolean): string | null;
13
+ //# sourceMappingURL=browserLaunch.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"browserLaunch.d.ts","sourceRoot":"","sources":["../../src/config/browserLaunch.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAEnD,MAAM,WAAW,oBAAoB;IACnC,QAAQ,EAAE,OAAO,CAAC;IAClB,IAAI,EAAE,MAAM,EAAE,CAAC;CAChB;AA4BD;;;GAGG;AACH,wBAAgB,oBAAoB,CAClC,SAAS,EAAE,eAAe,GACzB,oBAAoB,CA4BtB;AAED,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,OAAO,GAAG,MAAM,EAAE,CAEjE;AAED,wBAAgB,gCAAgC,CAC9C,cAAc,EAAE,UAAU,GAAG,SAAS,EACtC,eAAe,EAAE,OAAO,GACvB,MAAM,GAAG,IAAI,CAQf"}
@@ -0,0 +1,63 @@
1
+ import fs from "node:fs";
2
+ const SHARED_ARGS = [
3
+ "--disable-background-timer-throttling",
4
+ "--disable-backgrounding-occluded-windows",
5
+ "--disable-renderer-backgrounding",
6
+ ];
7
+ /** Software WebGL — fine for headless document pages, too slow for headed WebGL captures. */
8
+ const HEADLESS_ARGS = [
9
+ ...SHARED_ARGS,
10
+ "--enable-gpu",
11
+ "--use-angle=swiftshader-webgl",
12
+ "--enable-unsafe-swiftshader",
13
+ ];
14
+ /** Real GPU — required for smooth WebGL scroll-scrubbing captures. */
15
+ const HEADED_ARGS = [
16
+ ...SHARED_ARGS,
17
+ "--enable-gpu",
18
+ // Push the window completely off-screen so it doesn't appear to the user.
19
+ // --window-size must NOT be set here — Playwright controls the viewport
20
+ // via context options and any OS-level size constraint causes a mismatch
21
+ // that glitches the capture and can hang the browser on close.
22
+ "--window-position=-20000,-20000",
23
+ "--start-minimized",
24
+ ];
25
+ /**
26
+ * WebGL scroll-scrubbing sites run their render loop at only a few fps in
27
+ * headless Chromium. Use a headed browser with real GPU for virtual-scroll.
28
+ */
29
+ export function resolveBrowserLaunch(animation) {
30
+ // If running on a desktop environment but DISPLAY env variable is not inherited
31
+ // (e.g. VS Code / IDE background server process), auto-detect and restore it.
32
+ if (!process.env.DISPLAY && fs.existsSync("/tmp/.X11-unix/X0")) {
33
+ process.env.DISPLAY = ":0";
34
+ }
35
+ if (process.env.RECORD_HEADED === "1") {
36
+ return { headless: false, args: [...HEADED_ARGS] };
37
+ }
38
+ if (process.env.RECORD_HEADED === "0") {
39
+ return { headless: true, args: [...HEADLESS_ARGS] };
40
+ }
41
+ const scrollMode = animation.scrollMode ?? "auto";
42
+ if (scrollMode === "document") {
43
+ return { headless: true, args: [...HEADLESS_ARGS] };
44
+ }
45
+ if (scrollMode === "virtual") {
46
+ return { headless: false, args: [...HEADED_ARGS] };
47
+ }
48
+ return {
49
+ headless: !process.env.DISPLAY,
50
+ args: process.env.DISPLAY ? [...HEADED_ARGS] : [...HEADLESS_ARGS],
51
+ };
52
+ }
53
+ export function launchArgsForHeadless(headless) {
54
+ return headless ? [...HEADLESS_ARGS] : [...HEADED_ARGS];
55
+ }
56
+ export function shouldWarnHeadlessVirtualCapture(scrollStrategy, captureHeadless) {
57
+ if (scrollStrategy === "virtual" && captureHeadless) {
58
+ return ("Virtual scroll was captured headless; WebGL sites may look choppy. " +
59
+ "Set scrollMode to virtual, use a display (DISPLAY), or set RECORD_HEADED=1.");
60
+ }
61
+ return null;
62
+ }
63
+ //# sourceMappingURL=browserLaunch.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"browserLaunch.js","sourceRoot":"","sources":["../../src/config/browserLaunch.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAC;AAQzB,MAAM,WAAW,GAAG;IAClB,uCAAuC;IACvC,0CAA0C;IAC1C,kCAAkC;CAC1B,CAAC;AAEX,6FAA6F;AAC7F,MAAM,aAAa,GAAG;IACpB,GAAG,WAAW;IACd,cAAc;IACd,+BAA+B;IAC/B,6BAA6B;CACrB,CAAC;AAEX,sEAAsE;AACtE,MAAM,WAAW,GAAG;IAClB,GAAG,WAAW;IACd,cAAc;IACd,0EAA0E;IAC1E,wEAAwE;IACxE,yEAAyE;IACzE,+DAA+D;IAC/D,iCAAiC;IACjC,mBAAmB;CACX,CAAC;AAEX;;;GAGG;AACH,MAAM,UAAU,oBAAoB,CAClC,SAA0B;IAE1B,gFAAgF;IAChF,8EAA8E;IAC9E,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,IAAI,EAAE,CAAC,UAAU,CAAC,mBAAmB,CAAC,EAAE,CAAC;QAC/D,OAAO,CAAC,GAAG,CAAC,OAAO,GAAG,IAAI,CAAC;IAC7B,CAAC;IACD,IAAI,OAAO,CAAC,GAAG,CAAC,aAAa,KAAK,GAAG,EAAE,CAAC;QACtC,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,GAAG,WAAW,CAAC,EAAE,CAAC;IACrD,CAAC;IAED,IAAI,OAAO,CAAC,GAAG,CAAC,aAAa,KAAK,GAAG,EAAE,CAAC;QACtC,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,GAAG,aAAa,CAAC,EAAE,CAAC;IACtD,CAAC;IAED,MAAM,UAAU,GAAG,SAAS,CAAC,UAAU,IAAI,MAAM,CAAC;IAElD,IAAI,UAAU,KAAK,UAAU,EAAE,CAAC;QAC9B,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,GAAG,aAAa,CAAC,EAAE,CAAC;IACtD,CAAC;IAED,IAAI,UAAU,KAAK,SAAS,EAAE,CAAC;QAC7B,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,GAAG,WAAW,CAAC,EAAE,CAAC;IACrD,CAAC;IAED,OAAO;QACL,QAAQ,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO;QAC9B,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,aAAa,CAAC;KAClE,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,qBAAqB,CAAC,QAAiB;IACrD,OAAO,QAAQ,CAAC,CAAC,CAAC,CAAC,GAAG,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,WAAW,CAAC,CAAC;AAC1D,CAAC;AAED,MAAM,UAAU,gCAAgC,CAC9C,cAAsC,EACtC,eAAwB;IAExB,IAAI,cAAc,KAAK,SAAS,IAAI,eAAe,EAAE,CAAC;QACpD,OAAO,CACL,qEAAqE;YACrE,6EAA6E,CAC9E,CAAC;IACJ,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC"}
@@ -0,0 +1,10 @@
1
+ import type { RecordRequest } from "../types.js";
2
+ import { type EncodeSettings } from "../transcode/quality.js";
3
+ export interface RecordingProfile {
4
+ pixelsPerFrame: number;
5
+ preRecordingDelayMs: number;
6
+ encode: EncodeSettings;
7
+ hydrateFast: boolean;
8
+ }
9
+ export declare function resolveRecordingProfile(request: RecordRequest): RecordingProfile;
10
+ //# sourceMappingURL=recordingProfile.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"recordingProfile.d.ts","sourceRoot":"","sources":["../../src/config/recordingProfile.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,EAEL,KAAK,cAAc,EACpB,MAAM,yBAAyB,CAAC;AAEjC,MAAM,WAAW,gBAAgB;IAC/B,cAAc,EAAE,MAAM,CAAC;IACvB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,MAAM,EAAE,cAAc,CAAC;IACvB,WAAW,EAAE,OAAO,CAAC;CACtB;AAQD,wBAAgB,uBAAuB,CACrC,OAAO,EAAE,aAAa,GACrB,gBAAgB,CAsBlB"}
@@ -0,0 +1,25 @@
1
+ import { resolveEncodeSettings, } from "../transcode/quality.js";
2
+ const FAST_ENCODE = {
3
+ crf: 22,
4
+ preset: "fast",
5
+ deviceScaleFactor: 1,
6
+ };
7
+ export function resolveRecordingProfile(request) {
8
+ const animation = request.animationConfig ?? {};
9
+ const fastMode = animation.fastMode ?? false;
10
+ if (fastMode) {
11
+ return {
12
+ pixelsPerFrame: animation.pixelsPerFrame ?? 12,
13
+ preRecordingDelayMs: animation.preRecordingDelayMs ?? 500,
14
+ encode: FAST_ENCODE,
15
+ hydrateFast: true,
16
+ };
17
+ }
18
+ return {
19
+ pixelsPerFrame: animation.pixelsPerFrame ?? 4,
20
+ preRecordingDelayMs: animation.preRecordingDelayMs ?? 2000,
21
+ encode: resolveEncodeSettings(request.videoConfig.qualityPreset, request.videoConfig.viewport.deviceScaleFactor),
22
+ hydrateFast: false,
23
+ };
24
+ }
25
+ //# sourceMappingURL=recordingProfile.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"recordingProfile.js","sourceRoot":"","sources":["../../src/config/recordingProfile.ts"],"names":[],"mappings":"AACA,OAAO,EACL,qBAAqB,GAEtB,MAAM,yBAAyB,CAAC;AASjC,MAAM,WAAW,GAAmB;IAClC,GAAG,EAAE,EAAE;IACP,MAAM,EAAE,MAAM;IACd,iBAAiB,EAAE,CAAC;CACrB,CAAC;AAEF,MAAM,UAAU,uBAAuB,CACrC,OAAsB;IAEtB,MAAM,SAAS,GAAG,OAAO,CAAC,eAAe,IAAI,EAAE,CAAC;IAChD,MAAM,QAAQ,GAAG,SAAS,CAAC,QAAQ,IAAI,KAAK,CAAC;IAE7C,IAAI,QAAQ,EAAE,CAAC;QACb,OAAO;YACL,cAAc,EAAE,SAAS,CAAC,cAAc,IAAI,EAAE;YAC9C,mBAAmB,EAAE,SAAS,CAAC,mBAAmB,IAAI,GAAG;YACzD,MAAM,EAAE,WAAW;YACnB,WAAW,EAAE,IAAI;SAClB,CAAC;IACJ,CAAC;IAED,OAAO;QACL,cAAc,EAAE,SAAS,CAAC,cAAc,IAAI,CAAC;QAC7C,mBAAmB,EAAE,SAAS,CAAC,mBAAmB,IAAI,IAAI;QAC1D,MAAM,EAAE,qBAAqB,CAC3B,OAAO,CAAC,WAAW,CAAC,aAAa,EACjC,OAAO,CAAC,WAAW,CAAC,QAAQ,CAAC,iBAAiB,CAC/C;QACD,WAAW,EAAE,KAAK;KACnB,CAAC;AACJ,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare function embeddedWorkerEnabled(environment?: NodeJS.ProcessEnv): boolean;
2
+ //# sourceMappingURL=runtimeMode.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runtimeMode.d.ts","sourceRoot":"","sources":["../../src/config/runtimeMode.ts"],"names":[],"mappings":"AAAA,wBAAgB,qBAAqB,CACnC,WAAW,GAAE,MAAM,CAAC,UAAwB,WAG7C"}
@@ -0,0 +1,4 @@
1
+ export function embeddedWorkerEnabled(environment = process.env) {
2
+ return environment.EMBEDDED_WORKER !== "0";
3
+ }
4
+ //# sourceMappingURL=runtimeMode.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runtimeMode.js","sourceRoot":"","sources":["../../src/config/runtimeMode.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,qBAAqB,CACnC,cAAiC,OAAO,CAAC,GAAG;IAE5C,OAAO,WAAW,CAAC,eAAe,KAAK,GAAG,CAAC;AAC7C,CAAC"}
@@ -0,0 +1,8 @@
1
+ import type { AnimationConfig } from "../types.js";
2
+ export interface VirtualScrollSettings {
3
+ durationMs: number;
4
+ wheelBudget: number;
5
+ cycles: number;
6
+ }
7
+ export declare function resolveVirtualScrollSettings(animation: AnimationConfig, viewportHeight: number, _pixelsPerFrame: number, fastMode: boolean): VirtualScrollSettings;
8
+ //# sourceMappingURL=virtualScroll.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"virtualScroll.d.ts","sourceRoot":"","sources":["../../src/config/virtualScroll.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAEnD,MAAM,WAAW,qBAAqB;IACpC,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;CAChB;AAMD,wBAAgB,4BAA4B,CAC1C,SAAS,EAAE,eAAe,EAC1B,cAAc,EAAE,MAAM,EACtB,eAAe,EAAE,MAAM,EACvB,QAAQ,EAAE,OAAO,GAChB,qBAAqB,CAiBvB"}
@@ -0,0 +1,19 @@
1
+ /** Wall-clock seconds per viewport cycle for virtual scroll (not document pixelsPerFrame). */
2
+ const SECONDS_PER_CYCLE_NORMAL = 1.25;
3
+ const SECONDS_PER_CYCLE_FAST = 0.75;
4
+ export function resolveVirtualScrollSettings(animation, viewportHeight, _pixelsPerFrame, fastMode) {
5
+ const cycles = animation.virtualScrollCycles ?? (fastMode ? 6 : 8);
6
+ const wheelBudget = cycles * viewportHeight;
7
+ const secondsPerCycle = fastMode
8
+ ? SECONDS_PER_CYCLE_FAST
9
+ : SECONDS_PER_CYCLE_NORMAL;
10
+ const durationMs = animation.durationMs ??
11
+ animation.virtualScrollDurationMs ??
12
+ Math.round(cycles * secondsPerCycle * 1000);
13
+ return {
14
+ cycles,
15
+ wheelBudget,
16
+ durationMs,
17
+ };
18
+ }
19
+ //# sourceMappingURL=virtualScroll.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"virtualScroll.js","sourceRoot":"","sources":["../../src/config/virtualScroll.ts"],"names":[],"mappings":"AAQA,8FAA8F;AAC9F,MAAM,wBAAwB,GAAG,IAAI,CAAC;AACtC,MAAM,sBAAsB,GAAG,IAAI,CAAC;AAEpC,MAAM,UAAU,4BAA4B,CAC1C,SAA0B,EAC1B,cAAsB,EACtB,eAAuB,EACvB,QAAiB;IAEjB,MAAM,MAAM,GAAG,SAAS,CAAC,mBAAmB,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACnE,MAAM,WAAW,GAAG,MAAM,GAAG,cAAc,CAAC;IAC5C,MAAM,eAAe,GAAG,QAAQ;QAC9B,CAAC,CAAC,sBAAsB;QACxB,CAAC,CAAC,wBAAwB,CAAC;IAE7B,MAAM,UAAU,GACd,SAAS,CAAC,UAAU;QACpB,SAAS,CAAC,uBAAuB;QACjC,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,eAAe,GAAG,IAAI,CAAC,CAAC;IAE9C,OAAO;QACL,MAAM;QACN,WAAW;QACX,UAAU;KACX,CAAC;AACJ,CAAC"}