@h-rig/cli 0.0.6-alpha.80 → 0.0.6-alpha.81

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 (105) hide show
  1. package/dist/bin/rig.js +17034 -11249
  2. package/dist/src/app/board.js +32 -3
  3. package/dist/src/app/drone-ui.js +1 -1
  4. package/dist/src/app/theme.js +1 -0
  5. package/dist/src/app-opentui/adapters/common.d.ts +53 -0
  6. package/dist/src/app-opentui/adapters/common.js +149 -0
  7. package/dist/src/app-opentui/adapters/doctor.d.ts +11 -0
  8. package/dist/src/app-opentui/adapters/doctor.js +780 -0
  9. package/dist/src/app-opentui/adapters/fleet.d.ts +16 -0
  10. package/dist/src/app-opentui/adapters/fleet.js +874 -0
  11. package/dist/src/app-opentui/adapters/inbox.d.ts +33 -0
  12. package/dist/src/app-opentui/adapters/inbox.js +1454 -0
  13. package/dist/src/app-opentui/adapters/init.d.ts +13 -0
  14. package/dist/src/app-opentui/adapters/init.js +2357 -0
  15. package/dist/src/app-opentui/adapters/pi-attach.d.ts +16 -0
  16. package/dist/src/app-opentui/adapters/pi-attach.js +1295 -0
  17. package/dist/src/app-opentui/adapters/run-detail.d.ts +20 -0
  18. package/dist/src/app-opentui/adapters/run-detail.js +893 -0
  19. package/dist/src/app-opentui/adapters/server.d.ts +14 -0
  20. package/dist/src/app-opentui/adapters/server.js +798 -0
  21. package/dist/src/app-opentui/adapters/tasks.d.ts +55 -0
  22. package/dist/src/app-opentui/adapters/tasks.js +3472 -0
  23. package/dist/src/app-opentui/bootstrap.d.ts +16 -0
  24. package/dist/src/app-opentui/bootstrap.js +19509 -0
  25. package/dist/src/app-opentui/drone.d.ts +12 -0
  26. package/dist/src/app-opentui/drone.js +227 -0
  27. package/dist/src/app-opentui/events.d.ts +7 -0
  28. package/dist/src/app-opentui/events.js +28 -0
  29. package/dist/src/app-opentui/index.d.ts +8 -0
  30. package/dist/src/app-opentui/index.js +3477 -0
  31. package/dist/src/app-opentui/intent.d.ts +3 -0
  32. package/dist/src/app-opentui/intent.js +211 -0
  33. package/dist/src/app-opentui/layout.d.ts +15 -0
  34. package/dist/src/app-opentui/layout.js +44 -0
  35. package/dist/src/app-opentui/list-search.d.ts +8 -0
  36. package/dist/src/app-opentui/list-search.js +43 -0
  37. package/dist/src/app-opentui/pi-host-child.d.ts +2 -0
  38. package/dist/src/app-opentui/pi-host-child.js +778 -0
  39. package/dist/src/app-opentui/pi-pty-host.d.ts +64 -0
  40. package/dist/src/app-opentui/pi-pty-host.js +384 -0
  41. package/dist/src/app-opentui/registry.d.ts +4 -0
  42. package/dist/src/app-opentui/registry.js +6835 -0
  43. package/dist/src/app-opentui/render/graphics.d.ts +39 -0
  44. package/dist/src/app-opentui/render/graphics.js +537 -0
  45. package/dist/src/app-opentui/render/image-visual-layer-native-canvas.d.ts +2 -0
  46. package/dist/src/app-opentui/render/image-visual-layer-native-canvas.js +1480 -0
  47. package/dist/src/app-opentui/render/image-visual-layer-worker.d.ts +1 -0
  48. package/dist/src/app-opentui/render/image-visual-layer-worker.js +1541 -0
  49. package/dist/src/app-opentui/render/image-visual-layer.d.ts +93 -0
  50. package/dist/src/app-opentui/render/image-visual-layer.js +945 -0
  51. package/dist/src/app-opentui/render/panels.d.ts +10 -0
  52. package/dist/src/app-opentui/render/panels.js +201 -0
  53. package/dist/src/app-opentui/render/scene.d.ts +16 -0
  54. package/dist/src/app-opentui/render/scene.js +110 -0
  55. package/dist/src/app-opentui/render/text.d.ts +10 -0
  56. package/dist/src/app-opentui/render/text.js +121 -0
  57. package/dist/src/app-opentui/render/type-bar.d.ts +14 -0
  58. package/dist/src/app-opentui/render/type-bar.js +137 -0
  59. package/dist/src/app-opentui/runtime.d.ts +2 -0
  60. package/dist/src/app-opentui/runtime.js +3406 -0
  61. package/dist/src/app-opentui/scenes/doctor.d.ts +2 -0
  62. package/dist/src/app-opentui/scenes/doctor.js +91 -0
  63. package/dist/src/app-opentui/scenes/error.d.ts +2 -0
  64. package/dist/src/app-opentui/scenes/error.js +190 -0
  65. package/dist/src/app-opentui/scenes/fleet.d.ts +3 -0
  66. package/dist/src/app-opentui/scenes/fleet.js +207 -0
  67. package/dist/src/app-opentui/scenes/handoff.d.ts +2 -0
  68. package/dist/src/app-opentui/scenes/handoff.js +147 -0
  69. package/dist/src/app-opentui/scenes/help.d.ts +3 -0
  70. package/dist/src/app-opentui/scenes/help.js +138 -0
  71. package/dist/src/app-opentui/scenes/inbox.d.ts +2 -0
  72. package/dist/src/app-opentui/scenes/inbox.js +118 -0
  73. package/dist/src/app-opentui/scenes/init.d.ts +2 -0
  74. package/dist/src/app-opentui/scenes/init.js +94 -0
  75. package/dist/src/app-opentui/scenes/main.d.ts +2 -0
  76. package/dist/src/app-opentui/scenes/main.js +96 -0
  77. package/dist/src/app-opentui/scenes/run-detail.d.ts +2 -0
  78. package/dist/src/app-opentui/scenes/run-detail.js +139 -0
  79. package/dist/src/app-opentui/scenes/server.d.ts +2 -0
  80. package/dist/src/app-opentui/scenes/server.js +88 -0
  81. package/dist/src/app-opentui/scenes/tasks.d.ts +3 -0
  82. package/dist/src/app-opentui/scenes/tasks.js +230 -0
  83. package/dist/src/app-opentui/state.d.ts +4 -0
  84. package/dist/src/app-opentui/state.js +286 -0
  85. package/dist/src/app-opentui/theme.d.ts +36 -0
  86. package/dist/src/app-opentui/theme.js +88 -0
  87. package/dist/src/app-opentui/types.d.ts +188 -0
  88. package/dist/src/app-opentui/types.js +1 -0
  89. package/dist/src/commands/_async-ui.js +1 -1
  90. package/dist/src/commands/_operator-view.js +1 -1
  91. package/dist/src/commands/_pi-frontend.js +1 -1
  92. package/dist/src/commands/_spinner.js +1 -1
  93. package/dist/src/commands/browser.js +1 -1
  94. package/dist/src/commands/doctor.js +1 -1
  95. package/dist/src/commands/github.js +1 -1
  96. package/dist/src/commands/inbox.js +1 -1
  97. package/dist/src/commands/init.js +1 -1
  98. package/dist/src/commands/inspect.js +1 -1
  99. package/dist/src/commands/run.js +1 -1
  100. package/dist/src/commands/setup.js +1 -1
  101. package/dist/src/commands/stats.js +1 -1
  102. package/dist/src/commands/task.js +1 -1
  103. package/dist/src/commands.js +33 -4
  104. package/dist/src/index.js +33 -4
  105. package/package.json +11 -8
@@ -0,0 +1,1541 @@
1
+ // @bun
2
+ var __defProp = Object.defineProperty;
3
+ var __returnValue = (v) => v;
4
+ function __exportSetter(name, newValue) {
5
+ this[name] = __returnValue.bind(null, newValue);
6
+ }
7
+ var __export = (target, all) => {
8
+ for (var name in all)
9
+ __defProp(target, name, {
10
+ get: all[name],
11
+ enumerable: true,
12
+ configurable: true,
13
+ set: __exportSetter.bind(all, name)
14
+ });
15
+ };
16
+ var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
17
+
18
+ // packages/cli/src/app-opentui/render/image-visual-layer.ts
19
+ import { Worker } from "worker_threads";
20
+ import { deflateSync } from "zlib";
21
+ import { allocateImageId, deleteKittyImage, getCapabilities } from "@earendil-works/pi-tui";
22
+ function imageTransport() {
23
+ const forced = process.env.RIG_OPENTUI_IMAGE_TRANSPORT;
24
+ if (forced === "rgba-zlib")
25
+ return "rgba-zlib";
26
+ return "png";
27
+ }
28
+ function droneLayerScale() {
29
+ const raw = Number.parseFloat(process.env.RIG_OPENTUI_DRONE_SCALE ?? "");
30
+ if (Number.isFinite(raw) && raw > 0)
31
+ return Math.max(0.15, Math.min(1, raw));
32
+ return DEFAULT_DRONE_LAYER_SCALE;
33
+ }
34
+ function scaledPixelSize(size, scale, layout) {
35
+ return {
36
+ width: Math.max(layout.width, Math.floor(size.width * scale)),
37
+ height: Math.max(layout.height, Math.floor(size.height * scale))
38
+ };
39
+ }
40
+ function imageFps() {
41
+ const raw = Number.parseFloat(process.env.RIG_OPENTUI_IMAGE_FPS ?? "");
42
+ if (Number.isFinite(raw) && raw > 0)
43
+ return Math.max(10, Math.min(60, raw));
44
+ return DEFAULT_IMAGE_FPS;
45
+ }
46
+ function rgbaWord(color) {
47
+ return (color[3] << 24 | color[2] << 16 | color[1] << 8 | color[0]) >>> 0;
48
+ }
49
+ function fillRgba(data, color, word = rgbaWord(color)) {
50
+ if (data.byteOffset % 4 === 0 && data.byteLength % 4 === 0) {
51
+ new Uint32Array(data.buffer, data.byteOffset, data.byteLength / 4).fill(word);
52
+ return;
53
+ }
54
+ for (let i = 0;i < data.length; i += 4) {
55
+ data[i] = color[0];
56
+ data[i + 1] = color[1];
57
+ data[i + 2] = color[2];
58
+ data[i + 3] = color[3];
59
+ }
60
+ }
61
+ function makeCrcTable() {
62
+ const table = new Uint32Array(256);
63
+ for (let n = 0;n < 256; n += 1) {
64
+ let c = n;
65
+ for (let k = 0;k < 8; k += 1)
66
+ c = c & 1 ? 3988292384 ^ c >>> 1 : c >>> 1;
67
+ table[n] = c >>> 0;
68
+ }
69
+ return table;
70
+ }
71
+ function crc32(bytes) {
72
+ let c = 4294967295;
73
+ for (let i = 0;i < bytes.length; i += 1)
74
+ c = CRC_TABLE[(c ^ bytes[i]) & 255] ^ c >>> 8;
75
+ return (c ^ 4294967295) >>> 0;
76
+ }
77
+ function chunk(type, data) {
78
+ const out = new Uint8Array(12 + data.length);
79
+ const view = new DataView(out.buffer);
80
+ view.setUint32(0, data.length);
81
+ out[4] = type.charCodeAt(0);
82
+ out[5] = type.charCodeAt(1);
83
+ out[6] = type.charCodeAt(2);
84
+ out[7] = type.charCodeAt(3);
85
+ out.set(data, 8);
86
+ view.setUint32(8 + data.length, crc32(out.subarray(4, 8 + data.length)));
87
+ return out;
88
+ }
89
+ function encodePng(width, height, rgba) {
90
+ const ihdr = new Uint8Array(13);
91
+ const ihdrView = new DataView(ihdr.buffer);
92
+ ihdrView.setUint32(0, width);
93
+ ihdrView.setUint32(4, height);
94
+ ihdr[8] = 8;
95
+ ihdr[9] = 6;
96
+ ihdr[10] = 0;
97
+ ihdr[11] = 0;
98
+ ihdr[12] = 0;
99
+ const stride = width * 4;
100
+ const raw = new Uint8Array((stride + 1) * height);
101
+ for (let y = 0;y < height; y += 1) {
102
+ const rawOffset = y * (stride + 1);
103
+ raw[rawOffset] = 0;
104
+ raw.set(rgba.subarray(y * stride, y * stride + stride), rawOffset + 1);
105
+ }
106
+ const compressed = deflateSync(raw, { level: ZLIB_LEVEL });
107
+ return Buffer.concat([
108
+ Buffer.from(PNG_SIGNATURE),
109
+ Buffer.from(chunk("IHDR", ihdr)),
110
+ Buffer.from(chunk("IDAT", compressed)),
111
+ Buffer.from(chunk("IEND", new Uint8Array(0)))
112
+ ]);
113
+ }
114
+ function kittyImageSequence(base64, options) {
115
+ const params = [`a=T`, `f=${options.format}`, `q=2`, `C=1`, `c=${options.columns}`, `r=${options.rows}`, `i=${options.imageId}`, `z=${options.zIndex}`];
116
+ if (options.format === 32) {
117
+ params.push(`s=${options.pixelWidth ?? 1}`, `v=${options.pixelHeight ?? 1}`);
118
+ if (options.compressed)
119
+ params.push("o=z");
120
+ }
121
+ if (base64.length <= KITTY_CHUNK_SIZE)
122
+ return `\x1B_G${params.join(",")};${base64}\x1B\\`;
123
+ const chunks = [];
124
+ for (let offset = 0;offset < base64.length; offset += KITTY_CHUNK_SIZE) {
125
+ const part = base64.slice(offset, offset + KITTY_CHUNK_SIZE);
126
+ const last = offset + KITTY_CHUNK_SIZE >= base64.length;
127
+ chunks.push(`\x1B_G${offset === 0 ? `${params.join(",")},` : ""}m=${last ? 0 : 1};${part}\x1B\\`);
128
+ }
129
+ return chunks.join("");
130
+ }
131
+ function isModernImageTerminal(protocol) {
132
+ return protocol === "kitty";
133
+ }
134
+ function clampByte(value) {
135
+ return Math.max(0, Math.min(255, Math.round(value)));
136
+ }
137
+ function blendOver(data, index, color, alphaScale = 1) {
138
+ const alpha = color[3] / 255 * alphaScale;
139
+ const inv = 1 - alpha;
140
+ data[index] = clampByte(color[0] * alpha + data[index] * inv);
141
+ data[index + 1] = clampByte(color[1] * alpha + data[index + 1] * inv);
142
+ data[index + 2] = clampByte(color[2] * alpha + data[index + 2] * inv);
143
+ data[index + 3] = 255;
144
+ }
145
+ function drawDisc(data, width, height, cx, cy, radius, color, alpha = 1) {
146
+ const minX = Math.max(0, Math.floor(cx - radius));
147
+ const maxX = Math.min(width - 1, Math.ceil(cx + radius));
148
+ const minY = Math.max(0, Math.floor(cy - radius));
149
+ const maxY = Math.min(height - 1, Math.ceil(cy + radius));
150
+ for (let y = minY;y <= maxY; y += 1) {
151
+ for (let x = minX;x <= maxX; x += 1) {
152
+ const dx = x + 0.5 - cx;
153
+ const dy = y + 0.5 - cy;
154
+ const d = Math.sqrt(dx * dx + dy * dy);
155
+ if (d > radius)
156
+ continue;
157
+ const edge = Math.max(0, Math.min(1, radius - d));
158
+ blendOver(data, (y * width + x) * 4, color, alpha * Math.min(1, 0.35 + edge));
159
+ }
160
+ }
161
+ }
162
+ function drawGlow(data, width, height, cx, cy, radius, color, alpha = 0.18) {
163
+ const minX = Math.max(0, Math.floor(cx - radius));
164
+ const maxX = Math.min(width - 1, Math.ceil(cx + radius));
165
+ const minY = Math.max(0, Math.floor(cy - radius));
166
+ const maxY = Math.min(height - 1, Math.ceil(cy + radius));
167
+ for (let y = minY;y <= maxY; y += 1) {
168
+ for (let x = minX;x <= maxX; x += 1) {
169
+ const dx = x + 0.5 - cx;
170
+ const dy = y + 0.5 - cy;
171
+ const d = Math.sqrt(dx * dx + dy * dy);
172
+ if (d > radius)
173
+ continue;
174
+ const falloff = Math.pow(1 - d / Math.max(1, radius), 2.4);
175
+ blendOver(data, (y * width + x) * 4, color, alpha * falloff);
176
+ }
177
+ }
178
+ }
179
+ function drawLine(data, width, height, x0, y0, x1, y1, color, alpha = 0.5, thickness = 1.4) {
180
+ const dx = x1 - x0;
181
+ const dy = y1 - y0;
182
+ const steps = Math.max(1, Math.ceil(Math.hypot(dx, dy) * 1.2));
183
+ for (let i = 0;i <= steps; i += 1) {
184
+ const t = i / steps;
185
+ drawDisc(data, width, height, x0 + dx * t, y0 + dy * t, thickness, color, alpha);
186
+ }
187
+ }
188
+ function drawDrone(data, width, height, x, y, scale, tick, color) {
189
+ const wobble = Math.sin(tick * 0.055) * scale * 0.35;
190
+ const cy = y + wobble;
191
+ drawGlow(data, width, height, x, cy, scale * 7, color, 0.18);
192
+ drawDisc(data, width, height, x, cy, scale * 1.45, color, 0.92);
193
+ drawDisc(data, width, height, x, cy, scale * 0.55, [235, 255, 176, 255], 0.85);
194
+ const arm = scale * 4.1;
195
+ const rotor = scale * 1.6;
196
+ const arms = [[-arm, -arm * 0.72], [arm, -arm * 0.72], [-arm, arm * 0.72], [arm, arm * 0.72]];
197
+ for (const [dx, dy] of arms) {
198
+ drawLine(data, width, height, x, cy, x + dx, cy + dy, color, 0.42, Math.max(1, scale * 0.22));
199
+ drawGlow(data, width, height, x + dx, cy + dy, rotor * 2.6, color, 0.1);
200
+ drawDisc(data, width, height, x + dx, cy + dy, rotor, color, 0.34 + 0.12 * Math.sin(tick * 0.15));
201
+ }
202
+ }
203
+ function roundRectAlpha(px, py, x, y, w, h, r) {
204
+ const rx = Math.max(x + r, Math.min(px, x + w - r));
205
+ const ry = Math.max(y + r, Math.min(py, y + h - r));
206
+ const dx = px - rx;
207
+ const dy = py - ry;
208
+ const dist = Math.sqrt(dx * dx + dy * dy);
209
+ return Math.max(0, Math.min(1, r + 0.75 - dist));
210
+ }
211
+ function panelRect(layout, panel, size) {
212
+ const cellW = size.width / layout.width;
213
+ const cellH = size.height / layout.height;
214
+ const leftCells = layout.centerLeft + (panel.left ?? 0);
215
+ const topCells = layout.centerTop + panel.top;
216
+ const widthCells = panel.width ?? layout.centerWidth;
217
+ const heightCells = panel.height;
218
+ const left = Math.round(leftCells * cellW);
219
+ const top = Math.round(topCells * cellH);
220
+ const width = Math.round(widthCells * cellW);
221
+ const height = Math.round(heightCells * cellH);
222
+ return width > 8 && height > 8 ? { left, top, width, height } : null;
223
+ }
224
+ function downsampleRegion(data, canvasW, canvasH, rect, scale) {
225
+ const w = Math.max(1, Math.ceil(rect.width / scale));
226
+ const h = Math.max(1, Math.ceil(rect.height / scale));
227
+ const out = new Uint8ClampedArray(w * h * 3);
228
+ for (let y = 0;y < h; y += 1) {
229
+ for (let x = 0;x < w; x += 1) {
230
+ let r = 0, g = 0, b = 0, count = 0;
231
+ const sx0 = rect.left + x * scale;
232
+ const sy0 = rect.top + y * scale;
233
+ for (let yy = 0;yy < scale; yy += 1) {
234
+ const sy = sy0 + yy;
235
+ if (sy < 0 || sy >= canvasH)
236
+ continue;
237
+ for (let xx = 0;xx < scale; xx += 1) {
238
+ const sx = sx0 + xx;
239
+ if (sx < 0 || sx >= canvasW)
240
+ continue;
241
+ const i = (sy * canvasW + sx) * 4;
242
+ r += data[i];
243
+ g += data[i + 1];
244
+ b += data[i + 2];
245
+ count += 1;
246
+ }
247
+ }
248
+ const oi = (y * w + x) * 3;
249
+ out[oi] = count ? r / count : BG[0];
250
+ out[oi + 1] = count ? g / count : BG[1];
251
+ out[oi + 2] = count ? b / count : BG[2];
252
+ }
253
+ }
254
+ return { pixels: out, width: w, height: h };
255
+ }
256
+ function blurRgb(buffer, width, height, radius) {
257
+ const tmp = new Uint8ClampedArray(buffer.length);
258
+ const out = new Uint8ClampedArray(buffer.length);
259
+ const window = radius * 2 + 1;
260
+ for (let y = 0;y < height; y += 1) {
261
+ let r = 0, g = 0, b = 0;
262
+ for (let x = -radius;x <= radius; x += 1) {
263
+ const sx = Math.max(0, Math.min(width - 1, x));
264
+ const i = (y * width + sx) * 3;
265
+ r += buffer[i];
266
+ g += buffer[i + 1];
267
+ b += buffer[i + 2];
268
+ }
269
+ for (let x = 0;x < width; x += 1) {
270
+ const oi = (y * width + x) * 3;
271
+ tmp[oi] = r / window;
272
+ tmp[oi + 1] = g / window;
273
+ tmp[oi + 2] = b / window;
274
+ const removeX = Math.max(0, x - radius);
275
+ const addX = Math.min(width - 1, x + radius + 1);
276
+ const ri = (y * width + removeX) * 3;
277
+ const ai = (y * width + addX) * 3;
278
+ r += tmp.length ? buffer[ai] - buffer[ri] : 0;
279
+ g += tmp.length ? buffer[ai + 1] - buffer[ri + 1] : 0;
280
+ b += tmp.length ? buffer[ai + 2] - buffer[ri + 2] : 0;
281
+ }
282
+ }
283
+ for (let x = 0;x < width; x += 1) {
284
+ let r = 0, g = 0, b = 0;
285
+ for (let y = -radius;y <= radius; y += 1) {
286
+ const sy = Math.max(0, Math.min(height - 1, y));
287
+ const i = (sy * width + x) * 3;
288
+ r += tmp[i];
289
+ g += tmp[i + 1];
290
+ b += tmp[i + 2];
291
+ }
292
+ for (let y = 0;y < height; y += 1) {
293
+ const oi = (y * width + x) * 3;
294
+ out[oi] = r / window;
295
+ out[oi + 1] = g / window;
296
+ out[oi + 2] = b / window;
297
+ const removeY = Math.max(0, y - radius);
298
+ const addY = Math.min(height - 1, y + radius + 1);
299
+ const ri = (removeY * width + x) * 3;
300
+ const ai = (addY * width + x) * 3;
301
+ r += tmp[ai] - tmp[ri];
302
+ g += tmp[ai + 1] - tmp[ri + 1];
303
+ b += tmp[ai + 2] - tmp[ri + 2];
304
+ }
305
+ }
306
+ return out;
307
+ }
308
+ function panelMaskKey(width, height, rect, headerPx, blurScale) {
309
+ return `${width}x${height}:${rect.left},${rect.top},${rect.width},${rect.height}:${Math.round(headerPx * 100) / 100}:${blurScale}`;
310
+ }
311
+ function getPanelMask(width, height, rect, headerPx, blurScale) {
312
+ const key = panelMaskKey(width, height, rect, headerPx, blurScale);
313
+ const cached = panelMaskCache.get(key);
314
+ if (cached)
315
+ return cached;
316
+ const radius = Math.max(14, Math.min(34, Math.round(Math.min(rect.width, rect.height) * 0.035)));
317
+ const sampledWidth = Math.max(1, Math.ceil(rect.width / blurScale));
318
+ const sampledHeight = Math.max(1, Math.ceil(rect.height / blurScale));
319
+ const x0 = Math.max(0, rect.left);
320
+ const y0 = Math.max(0, rect.top);
321
+ const x1 = Math.min(width - 1, rect.left + rect.width - 1);
322
+ const y1 = Math.min(height - 1, rect.top + rect.height - 1);
323
+ const indices = [];
324
+ const sampleIndices = [];
325
+ const panelAlpha = [];
326
+ const edgeAlpha = [];
327
+ const headerFlags = [];
328
+ const dividerIndices = [];
329
+ for (let y = y0;y <= y1; y += 1) {
330
+ for (let x = x0;x <= x1; x += 1) {
331
+ const a = roundRectAlpha(x + 0.5, y + 0.5, rect.left, rect.top, rect.width, rect.height, radius);
332
+ if (a <= 0)
333
+ continue;
334
+ const edge = roundRectAlpha(x + 0.5, y + 0.5, rect.left + 1.2, rect.top + 1.2, rect.width - 2.4, rect.height - 2.4, Math.max(1, radius - 1.2));
335
+ const sx = Math.max(0, Math.min(sampledWidth - 1, Math.floor((x - rect.left) / blurScale)));
336
+ const sy = Math.max(0, Math.min(sampledHeight - 1, Math.floor((y - rect.top) / blurScale)));
337
+ indices.push((y * width + x) * 4);
338
+ sampleIndices.push((sy * sampledWidth + sx) * 3);
339
+ panelAlpha.push(a);
340
+ edgeAlpha.push(edge < 0.96 ? Math.min(1, (1 - edge) * 0.7) : 0);
341
+ headerFlags.push(y < rect.top + headerPx ? 1 : 0);
342
+ }
343
+ }
344
+ const dividerY = Math.round(rect.top + headerPx);
345
+ if (dividerY > y0 && dividerY < y1) {
346
+ for (let x = x0 + radius;x <= x1 - radius; x += 1) {
347
+ dividerIndices.push((dividerY * width + x) * 4);
348
+ }
349
+ }
350
+ const mask = {
351
+ key,
352
+ indices: Uint32Array.from(indices),
353
+ sampleIndices: Uint32Array.from(sampleIndices),
354
+ panelAlpha: Float32Array.from(panelAlpha),
355
+ edgeAlpha: Float32Array.from(edgeAlpha),
356
+ headerFlags: Uint8Array.from(headerFlags),
357
+ dividerIndices: Uint32Array.from(dividerIndices)
358
+ };
359
+ panelMaskCache.set(key, mask);
360
+ while (panelMaskCache.size > PANEL_MASK_CACHE_LIMIT) {
361
+ const oldest = panelMaskCache.keys().next().value;
362
+ if (!oldest)
363
+ break;
364
+ panelMaskCache.delete(oldest);
365
+ }
366
+ return mask;
367
+ }
368
+ function compositePanel(data, width, height, rect, headerPx) {
369
+ const blurScale = PANEL_BLUR_SCALE;
370
+ const sampled = downsampleRegion(data, width, height, rect, blurScale);
371
+ const blurred = blurRgb(sampled.pixels, sampled.width, sampled.height, 4);
372
+ const mask = getPanelMask(width, height, rect, headerPx, blurScale);
373
+ for (let i = 0;i < mask.indices.length; i += 1) {
374
+ const idx = mask.indices[i];
375
+ const sampleIdx = mask.sampleIndices[i];
376
+ data[idx] = blurred[sampleIdx];
377
+ data[idx + 1] = blurred[sampleIdx + 1];
378
+ data[idx + 2] = blurred[sampleIdx + 2];
379
+ data[idx + 3] = 255;
380
+ blendOver(data, idx, mask.headerFlags[i] ? PANEL_HEADER : PANEL, mask.panelAlpha[i]);
381
+ const edge = mask.edgeAlpha[i];
382
+ if (edge > 0)
383
+ blendOver(data, idx, PANEL_LINE, edge);
384
+ }
385
+ for (let i = 0;i < mask.dividerIndices.length; i += 1) {
386
+ blendOver(data, mask.dividerIndices[i], PANEL_LINE, 0.28);
387
+ }
388
+ }
389
+ function visualSceneKind(scene) {
390
+ if (scene === "tasks")
391
+ return "loop";
392
+ if (scene === "help")
393
+ return "carrier";
394
+ return "dispatch";
395
+ }
396
+ function seededUnit(seed) {
397
+ let value = seed >>> 0;
398
+ value = value * 1664525 + 1013904223 >>> 0;
399
+ return value / 4294967295;
400
+ }
401
+ function sceneCore(width, height, kind) {
402
+ if (kind === "dispatch")
403
+ return { x: width * 0.3, y: height * 0.45 };
404
+ if (kind === "carrier")
405
+ return { x: width * 0.5, y: height * 0.54 };
406
+ return { x: width * 0.09, y: height * 0.56 };
407
+ }
408
+ function dispatchLane(width, index, count) {
409
+ const a = seededUnit(28672 + index * 101);
410
+ const b = seededUnit(36864 + index * 131);
411
+ const c = seededUnit(45056 + index * 151);
412
+ const ang = (-0.9 + 1.8 * (index / Math.max(1, count - 1))) * (Math.PI * 0.5);
413
+ return { ang, len: width * (0.32 + a * 0.42), curve: (b - 0.5) * 0.7, phase: c * Math.PI * 2 };
414
+ }
415
+ function lanePoint(width, height, lane, p, kind = "dispatch") {
416
+ const core = sceneCore(width, height, kind);
417
+ const dist = lane.len * p;
418
+ const bend = Math.sin(p * Math.PI) * lane.curve * Math.min(width, height) * 0.035;
419
+ const ux = Math.cos(lane.ang);
420
+ const uy = Math.sin(lane.ang);
421
+ return { x: core.x + ux * dist + -uy * bend, y: core.y + uy * dist + ux * bend };
422
+ }
423
+ function drawMarketingRails(data, width, height, kind, tick) {
424
+ const ys = kind === "loop" ? [0.18, 0.5, 0.82] : kind === "carrier" ? [0.24, 0.54, 0.82] : [0.18, 0.58, 0.82];
425
+ ys.forEach((ratio, index) => {
426
+ const y = height * ratio + Math.sin(tick * 0.018 + index) * Math.max(2, height * 0.0025);
427
+ const color = index === 2 ? CYAN : index === 1 ? LIME : LIME_DIM;
428
+ drawLine(data, width, height, width * 0.06, y, width * 0.94, y + Math.sin(index) * height * 0.002, color, index === 1 ? 0.11 : 0.07, Math.max(0.8, height * 0.0012));
429
+ for (let p = (tick * 0.004 + index * 0.21) % 1;p < 1; p += 0.18 + index * 0.02) {
430
+ const x = width * (0.06 + 0.88 * p);
431
+ drawDisc(data, width, height, x, y, Math.max(1.2, height * (0.0017 + index * 0.0004)), color, 0.24);
432
+ drawGlow(data, width, height, x, y, Math.max(5, height * 0.006), color, 0.035);
433
+ }
434
+ });
435
+ }
436
+ function drawDispatchScene(data, width, height, tick) {
437
+ const core = sceneCore(width, height, "dispatch");
438
+ const min = Math.min(width, height);
439
+ drawGlow(data, width, height, core.x, core.y, min * 0.085, LIME, 0.12);
440
+ drawDisc(data, width, height, core.x, core.y, min * 0.0065, LIME, 0.85);
441
+ const laneCount = width < 1000 ? 7 : 12;
442
+ const lanes = Array.from({ length: laneCount }, (_, index) => dispatchLane(width, index, laneCount));
443
+ lanes.forEach((lane) => {
444
+ let prev = lanePoint(width, height, lane, 0);
445
+ for (let step = 1;step <= 32; step += 1) {
446
+ const next = lanePoint(width, height, lane, step / 32);
447
+ drawLine(data, width, height, prev.x, prev.y, next.x, next.y, lane.phase > Math.PI ? CYAN : LIME_DIM, 0.045, Math.max(0.7, min * 0.0009));
448
+ prev = next;
449
+ }
450
+ });
451
+ const packets = width < 1000 ? 70 : 150;
452
+ for (let i = 0;i < packets; i += 1) {
453
+ const lane = lanes[i % lanes.length];
454
+ const speed = 0.003 + seededUnit(12288 + i * 17) * 0.009;
455
+ const p = (seededUnit(16384 + i * 19) + tick * speed) % 1;
456
+ const pt = lanePoint(width, height, lane, p);
457
+ const wobble = (seededUnit(20480 + i * 23) - 0.5) * min * 0.012;
458
+ const fade = p < 0.1 ? p / 0.1 : p > 0.88 ? (1 - p) / 0.12 : 1;
459
+ const color = seededUnit(24576 + i * 29) < 0.22 ? CYAN : LIME_DIM;
460
+ const y = pt.y + wobble * Math.sin(p * Math.PI * 2);
461
+ drawLine(data, width, height, pt.x - min * 0.012, y - min * 0.002, pt.x, y, color, 0.08 * fade, Math.max(0.7, min * 0.0008));
462
+ drawDisc(data, width, height, pt.x, y, Math.max(1.3, min * 0.0022), color, 0.5 * fade);
463
+ drawGlow(data, width, height, pt.x, y, Math.max(4, min * 0.008), color, 0.045 * fade);
464
+ }
465
+ for (let i = 0;i < (width < 1000 ? 4 : 8); i += 1) {
466
+ const lane = lanes[i % lanes.length];
467
+ const p = (tick * 0.002 + i * 0.13) % 1;
468
+ const pt = lanePoint(width, height, lane, p);
469
+ drawDrone(data, width, height, pt.x, pt.y + Math.sin(tick * 0.04 + i) * min * 0.004, min * (0.006 + i % 2 * 0.0015), tick + i * 11, i % 3 === 0 ? CYAN : LIME_DIM);
470
+ }
471
+ }
472
+ function drawLoopScene(data, width, height, tick) {
473
+ const min = Math.min(width, height);
474
+ const y = height * 0.56;
475
+ const x0 = width * 0.09;
476
+ const x1 = width * 0.91;
477
+ drawLine(data, width, height, x0, y, x1, y, LIME_DIM, 0.12, Math.max(0.8, min * 0.001));
478
+ const gates = width < 1000 ? 4 : 5;
479
+ const active = Math.floor(tick / 16) % gates;
480
+ for (let i = 0;i < gates; i += 1) {
481
+ const x = x0 + (x1 - x0) * (i / Math.max(1, gates - 1));
482
+ const color = i === active ? LIME : i <= active ? LIME_DIM : INK_DIM;
483
+ drawLine(data, width, height, x, y - min * 0.05, x, y + min * 0.05, color, i === active ? 0.25 : 0.08, Math.max(0.8, min * 0.001));
484
+ drawDisc(data, width, height, x, y, i === active ? min * 0.006 : min * 0.0035, color, i === active ? 0.72 : 0.25);
485
+ drawGlow(data, width, height, x, y, i === active ? min * 0.018 : min * 0.01, color, i === active ? 0.1 : 0.035);
486
+ }
487
+ const packets = width < 1000 ? 36 : 84;
488
+ for (let i = 0;i < packets; i += 1) {
489
+ const p = (seededUnit(33024 + i * 13) + tick * (0.0022 + seededUnit(33280 + i * 17) * 0.004)) % 1;
490
+ const x = x0 + (x1 - x0) * p;
491
+ const segment = Math.min(gates - 1, Math.floor(p * gates));
492
+ const color = segment < active ? LIME_DIM : segment === active ? CYAN : INK_DIM;
493
+ const py = y + (seededUnit(33536 + i * 19) - 0.5) * min * 0.018 * Math.sin(p * Math.PI * 2);
494
+ drawLine(data, width, height, x - min * 0.014, py, x, py, color, 0.1, Math.max(0.7, min * 0.0008));
495
+ drawDisc(data, width, height, x, py, Math.max(1.2, min * 0.002), color, color === INK_DIM ? 0.22 : 0.58);
496
+ }
497
+ drawDrone(data, width, height, x0 + (x1 - x0) * (tick * 0.003 % 1), y - min * 0.04, min * 0.0065, tick, LIME_DIM);
498
+ drawDrone(data, width, height, x0 + (x1 - x0) * ((tick * 0.002 + 0.5) % 1), y + min * 0.036, min * 0.0055, tick + 40, MAGENTA);
499
+ }
500
+ function drawCarrierScene(data, width, height, tick) {
501
+ const min = Math.min(width, height);
502
+ const core = sceneCore(width, height, "carrier");
503
+ drawGlow(data, width, height, core.x, core.y, min * 0.075, LIME, 0.12);
504
+ drawDisc(data, width, height, core.x, core.y, min * 0.0065, LIME, 0.92);
505
+ const nodes = width < 1000 ? 5 : 7;
506
+ const rx = width * 0.36;
507
+ const ry = height * 0.22;
508
+ for (let i = 0;i < nodes; i += 1) {
509
+ const a = i / nodes * Math.PI * 2 - Math.PI / 2 + tick * 0.006;
510
+ const x = core.x + Math.cos(a) * rx;
511
+ const y = core.y + Math.sin(a) * ry;
512
+ const color = i % 2 ? CYAN : LIME_DIM;
513
+ drawLine(data, width, height, core.x, core.y, x, y, color, 0.055, Math.max(0.7, min * 0.0008));
514
+ drawGlow(data, width, height, x, y, min * 0.018, color, 0.055);
515
+ drawDisc(data, width, height, x, y, min * 0.0048, color, 0.62);
516
+ drawDrone(data, width, height, x, y - min * 0.018, min * 0.005, tick + i * 9, color);
517
+ }
518
+ const packets = width < 1000 ? 30 : 72;
519
+ for (let i = 0;i < packets; i += 1) {
520
+ const lane = i % nodes;
521
+ const a = lane / nodes * Math.PI * 2 - Math.PI / 2 + tick * 0.006;
522
+ const nx = core.x + Math.cos(a) * rx;
523
+ const ny = core.y + Math.sin(a) * ry;
524
+ const p = (seededUnit(37120 + i * 37) + tick * (0.003 + seededUnit(37376 + i * 43) * 0.009)) % 1;
525
+ const x = core.x + (nx - core.x) * p;
526
+ const y = core.y + (ny - core.y) * p;
527
+ const color = seededUnit(37632 + i * 47) < 0.35 ? CYAN : LIME_DIM;
528
+ drawDisc(data, width, height, x, y, Math.max(1.2, min * 0.002), color, 0.48);
529
+ drawGlow(data, width, height, x, y, min * 0.008, color, 0.035);
530
+ }
531
+ }
532
+ function drawBackground(data, width, height, tick, scene) {
533
+ fillRgba(data, BG, BG_WORD);
534
+ const kind = visualSceneKind(scene);
535
+ drawGlow(data, width, height, width * 0.82, height * 0.04, Math.min(width, height) * 0.22, LIME, 0.035);
536
+ drawGlow(data, width, height, width * 0.12, height * 0.18, Math.min(width, height) * 0.17, CYAN, 0.025);
537
+ drawMarketingRails(data, width, height, kind, tick);
538
+ if (kind === "loop")
539
+ drawLoopScene(data, width, height, tick);
540
+ else if (kind === "carrier")
541
+ drawCarrierScene(data, width, height, tick);
542
+ else
543
+ drawDispatchScene(data, width, height, tick);
544
+ }
545
+ function imageVisualFrameKey(input) {
546
+ const width = Math.max(1, Math.floor(input.pixelSize.width));
547
+ const height = Math.max(1, Math.floor(input.pixelSize.height));
548
+ const layer = "layer" in input ? input.layer ?? "full" : "full";
549
+ return `${layer}:${width}x${height}:${input.layout.width}x${input.layout.height}:${input.scene}:${input.tick}:${input.panels.map((panel) => `${panel.id}:${panel.top}:${panel.height}:${panel.width ?? ""}:${panel.left ?? ""}:${panel.headerHeight ?? ""}`).join("|")}`;
550
+ }
551
+ function encodeKittyFrame(width, height, data, input) {
552
+ if (input.transport === "png") {
553
+ const png = encodePng(width, height, data);
554
+ return kittyImageSequence(png.toString("base64"), { columns: input.layout.width, rows: input.layout.height, imageId: input.imageId, zIndex: input.zIndex, format: 100 });
555
+ }
556
+ const compressed = deflateSync(data, { level: ZLIB_LEVEL });
557
+ return kittyImageSequence(compressed.toString("base64"), {
558
+ columns: input.layout.width,
559
+ rows: input.layout.height,
560
+ imageId: input.imageId,
561
+ zIndex: input.zIndex,
562
+ format: 32,
563
+ pixelWidth: width,
564
+ pixelHeight: height,
565
+ compressed: true
566
+ });
567
+ }
568
+ function renderImageVisualFrame(input) {
569
+ const width = Math.max(1, Math.floor(input.pixelSize.width));
570
+ const height = Math.max(1, Math.floor(input.pixelSize.height));
571
+ const byteCount = width * height * 4;
572
+ if (byteCount > MAX_IMAGE_BYTES)
573
+ return null;
574
+ const data = new Uint8ClampedArray(byteCount);
575
+ drawBackground(data, width, height, input.tick, input.scene);
576
+ for (const panel of input.panels) {
577
+ if (panel.chrome !== "ad-terminal")
578
+ continue;
579
+ const rect = panelRect(input.layout, panel, { width, height });
580
+ if (!rect)
581
+ continue;
582
+ const cellH = height / input.layout.height;
583
+ const headerPx = Math.max(cellH * 3, (panel.headerHeight ?? 3) * cellH);
584
+ compositePanel(data, width, height, rect, headerPx);
585
+ }
586
+ return { key: imageVisualFrameKey(input), sequence: encodeKittyFrame(width, height, data, input) };
587
+ }
588
+ function createImageWorker() {
589
+ if (process.env.RIG_OPENTUI_IMAGE_WORKER === "0")
590
+ return null;
591
+ const isTypeScriptRuntime = import.meta.url.endsWith(".ts");
592
+ const workerUrl = new URL(isTypeScriptRuntime ? "./image-visual-layer-worker.ts" : "./image-visual-layer-worker.js", import.meta.url);
593
+ try {
594
+ return new Worker(workerUrl);
595
+ } catch {
596
+ if (typeof process.versions.bun === "string") {
597
+ try {
598
+ return new Worker("./src/app-opentui/render/image-visual-layer-worker.ts");
599
+ } catch {}
600
+ }
601
+ return null;
602
+ }
603
+ }
604
+ function panelFps() {
605
+ const raw = Number.parseFloat(process.env.RIG_OPENTUI_PANEL_FPS ?? "");
606
+ if (Number.isFinite(raw) && raw > 0)
607
+ return Math.max(4, Math.min(60, raw));
608
+ return DEFAULT_PANEL_FPS;
609
+ }
610
+ function panelLayerScale() {
611
+ const raw = Number.parseFloat(process.env.RIG_OPENTUI_PANEL_SCALE ?? "");
612
+ if (Number.isFinite(raw) && raw > 0)
613
+ return Math.max(0.18, Math.min(1, raw));
614
+ return DEFAULT_PANEL_LAYER_SCALE;
615
+ }
616
+ function imageOutputBacklogBytes() {
617
+ const raw = Number.parseInt(process.env.RIG_OPENTUI_IMAGE_BACKLOG_BYTES ?? "", 10);
618
+ if (Number.isFinite(raw) && raw > 0)
619
+ return Math.max(64 * 1024, Math.min(2 * 1024 * 1024, raw));
620
+ return DEFAULT_IMAGE_OUTPUT_BACKLOG_BYTES;
621
+ }
622
+ function imageOutputBytesPerSecond() {
623
+ const raw = Number.parseInt(process.env.RIG_OPENTUI_IMAGE_BYTES_PER_SECOND ?? "", 10);
624
+ if (Number.isFinite(raw) && raw > 0)
625
+ return Math.max(128 * 1024, Math.min(2 * 1024 * 1024, raw));
626
+ return DEFAULT_IMAGE_OUTPUT_BYTES_PER_SECOND;
627
+ }
628
+ function pendingLayerKey(key) {
629
+ return key.split(":", 1)[0] || "full";
630
+ }
631
+
632
+ class ImageVisualLayer {
633
+ imageId = allocateImageId();
634
+ panelImageIds = Array.from({ length: 8 }, () => allocateImageId());
635
+ panelChromeImageIds = Array.from({ length: 8 }, () => allocateImageId());
636
+ stdout;
637
+ protocol;
638
+ transport = imageTransport();
639
+ frameIntervalMs = 1000 / imageFps();
640
+ panelIntervalMs = 1000 / panelFps();
641
+ maxOutputBacklogBytes = imageOutputBacklogBytes();
642
+ outputBytesPerSecond = imageOutputBytesPerSecond();
643
+ outputBudgetBytes = imageOutputBytesPerSecond();
644
+ lastBudgetAtMs = Date.now();
645
+ motionSlot = this.createSlot();
646
+ panelSlot = this.createSlot();
647
+ chromeSlot = this.createSlot();
648
+ pendingFrames = new Map;
649
+ recentWrittenKeys = [];
650
+ requestId = 0;
651
+ lastMotionFrameIndex = -1;
652
+ lastPanelFrameIndex = -1;
653
+ lastChromeKey = "";
654
+ destroyed = false;
655
+ constructor(stdout = process.stdout) {
656
+ this.stdout = stdout;
657
+ this.protocol = getCapabilities().images;
658
+ if (this.enabled) {
659
+ this.startWorker(this.motionSlot);
660
+ this.startWorker(this.panelSlot);
661
+ this.startWorker(this.chromeSlot);
662
+ }
663
+ }
664
+ get enabled() {
665
+ return isModernImageTerminal(this.protocol);
666
+ }
667
+ clear() {
668
+ if (this.enabled) {
669
+ this.stdout.write([this.imageId, ...this.panelImageIds, ...this.panelChromeImageIds].map((id) => deleteKittyImage(id)).join("") + "\x1B[?25h");
670
+ this.pendingFrames.clear();
671
+ this.recentWrittenKeys.length = 0;
672
+ this.resetSlot(this.motionSlot);
673
+ this.resetSlot(this.panelSlot);
674
+ this.resetSlot(this.chromeSlot);
675
+ this.lastMotionFrameIndex = -1;
676
+ this.lastPanelFrameIndex = -1;
677
+ this.lastChromeKey = "";
678
+ this.outputBudgetBytes = this.outputBytesPerSecond;
679
+ this.lastBudgetAtMs = Date.now();
680
+ this.motionSlot.clearedThroughRequestId = this.requestId;
681
+ this.panelSlot.clearedThroughRequestId = this.requestId;
682
+ this.chromeSlot.clearedThroughRequestId = this.requestId;
683
+ }
684
+ }
685
+ destroy() {
686
+ if (this.destroyed)
687
+ return;
688
+ this.clear();
689
+ this.destroyed = true;
690
+ const workers = [this.motionSlot.worker, this.panelSlot.worker, this.chromeSlot.worker];
691
+ this.motionSlot.worker = null;
692
+ this.panelSlot.worker = null;
693
+ this.chromeSlot.worker = null;
694
+ for (const worker of workers)
695
+ if (worker)
696
+ worker.terminate().catch(() => {
697
+ return;
698
+ });
699
+ }
700
+ render(input) {
701
+ if (!this.enabled || this.destroyed)
702
+ return;
703
+ const width = Math.max(1, Math.floor(input.pixelSize.width));
704
+ const height = Math.max(1, Math.floor(input.pixelSize.height));
705
+ if (width * height * 4 > MAX_IMAGE_BYTES)
706
+ return;
707
+ if (this.isOutputBackedUp())
708
+ return;
709
+ this.refillOutputBudget();
710
+ const now = Date.now();
711
+ const visualTick = Math.floor(now / (1000 / 60));
712
+ const useDynamicSplit = Boolean(this.motionSlot.worker && this.panelSlot.worker && this.chromeSlot.worker && this.transport === "png" && process.env.RIG_OPENTUI_DYNAMIC_SPLIT !== "0");
713
+ if (!useDynamicSplit) {
714
+ const frameIndex = Math.floor(now / this.frameIntervalMs);
715
+ if (!input.force && frameIndex === this.lastMotionFrameIndex)
716
+ return;
717
+ this.scheduleRender(this.motionSlot, { ...input, tick: visualTick, layer: "full" }, this.imageId, -10, input.force);
718
+ this.lastMotionFrameIndex = frameIndex;
719
+ return;
720
+ }
721
+ const motionFrameIndex = Math.floor(now / this.frameIntervalMs);
722
+ if ((input.force || motionFrameIndex !== this.lastMotionFrameIndex) && this.outputBudgetBytes >= MIN_BACKGROUND_BUDGET_BYTES) {
723
+ this.scheduleRender(this.motionSlot, { ...input, pixelSize: scaledPixelSize(input.pixelSize, droneLayerScale(), input.layout), panels: [], tick: visualTick, layer: "background" }, this.imageId, -30, input.force);
724
+ this.lastMotionFrameIndex = motionFrameIndex;
725
+ }
726
+ const panelFrameIndex = Math.floor(now / this.panelIntervalMs);
727
+ if ((input.force || panelFrameIndex !== this.lastPanelFrameIndex) && this.outputBudgetBytes >= MIN_PANEL_BUDGET_BYTES) {
728
+ this.scheduleRender(this.panelSlot, { ...input, pixelSize: scaledPixelSize(input.pixelSize, panelLayerScale(), input.layout), tick: visualTick, layer: "panel-patches" }, this.imageId, -12, input.force, this.panelImageIds);
729
+ this.lastPanelFrameIndex = panelFrameIndex;
730
+ }
731
+ const chromeInput = { ...input, tick: 0, layer: "panel-chrome" };
732
+ const chromeKey = imageVisualFrameKey(chromeInput);
733
+ if (input.force || chromeKey !== this.lastChromeKey) {
734
+ this.scheduleRender(this.chromeSlot, chromeInput, this.imageId, -8, input.force, this.panelChromeImageIds);
735
+ this.lastChromeKey = chromeKey;
736
+ }
737
+ }
738
+ flush() {
739
+ if (this.pendingFrames.size === 0)
740
+ return false;
741
+ this.refillOutputBudget();
742
+ if (this.isOutputBackedUp()) {
743
+ const chrome = this.pendingFrames.get("panel-chrome");
744
+ this.pendingFrames.clear();
745
+ if (chrome)
746
+ this.pendingFrames.set("panel-chrome", chrome);
747
+ return false;
748
+ }
749
+ const framePriority = (frame) => {
750
+ const layer = pendingLayerKey(frame.key);
751
+ if (layer === "panel-chrome")
752
+ return 0;
753
+ if (layer === "background")
754
+ return 1;
755
+ if (layer === "panel-patches")
756
+ return 2;
757
+ return 2;
758
+ };
759
+ const frames = Array.from(this.pendingFrames.values()).sort((a, b) => framePriority(a) - framePriority(b));
760
+ const prefix = "\x1B[?25l\x1B7\x1B[s\x1B[H";
761
+ const suffix = "\x1B[u\x1B8";
762
+ const selected = [];
763
+ const retained = new Map;
764
+ let sequence = "";
765
+ let byteLength = Buffer.byteLength(prefix + suffix);
766
+ for (const frame of frames) {
767
+ const candidate = sequence + frame.sequence;
768
+ const candidateBytes = Buffer.byteLength(prefix + candidate + suffix);
769
+ if (candidateBytes <= this.outputBudgetBytes) {
770
+ selected.push(frame);
771
+ sequence = candidate;
772
+ byteLength = candidateBytes;
773
+ } else if (pendingLayerKey(frame.key) === "panel-chrome") {
774
+ retained.set(pendingLayerKey(frame.key), frame);
775
+ }
776
+ }
777
+ this.pendingFrames.clear();
778
+ for (const [layer, frame] of retained)
779
+ this.pendingFrames.set(layer, frame);
780
+ if (!sequence || selected.length === 0)
781
+ return false;
782
+ const payload = `${prefix}${sequence}${suffix}`;
783
+ for (const frame of selected)
784
+ this.markWritten(frame.key);
785
+ this.outputBudgetBytes -= byteLength;
786
+ this.stdout.cork?.();
787
+ const accepted = this.stdout.write(payload);
788
+ this.stdout.uncork?.();
789
+ return accepted;
790
+ }
791
+ createSlot() {
792
+ return { worker: null, busy: false, queuedRequest: null, inFlightKey: "", queuedKey: "", clearedThroughRequestId: 0 };
793
+ }
794
+ resetSlot(slot) {
795
+ slot.busy = false;
796
+ slot.queuedRequest = null;
797
+ slot.inFlightKey = "";
798
+ slot.queuedKey = "";
799
+ }
800
+ markWritten(key) {
801
+ this.recentWrittenKeys.push(key);
802
+ while (this.recentWrittenKeys.length > RECENT_WRITTEN_LIMIT)
803
+ this.recentWrittenKeys.shift();
804
+ }
805
+ refillOutputBudget() {
806
+ const now = Date.now();
807
+ const elapsedMs = Math.max(0, now - this.lastBudgetAtMs);
808
+ this.lastBudgetAtMs = now;
809
+ this.outputBudgetBytes = Math.min(this.outputBytesPerSecond, this.outputBudgetBytes + elapsedMs / 1000 * this.outputBytesPerSecond);
810
+ }
811
+ isOutputBackedUp() {
812
+ return Boolean(this.stdout.writableNeedDrain) || this.stdout.writableLength > this.maxOutputBacklogBytes;
813
+ }
814
+ stageFrame(frame) {
815
+ this.pendingFrames.set(pendingLayerKey(frame.key), frame);
816
+ }
817
+ isKnownKey(slot, key) {
818
+ return this.recentWrittenKeys.includes(key) || Array.from(this.pendingFrames.values()).some((frame) => frame.key === key) || key === slot.inFlightKey || key === slot.queuedKey;
819
+ }
820
+ scheduleRender(slot, input, imageId, zIndex, force, imageIds) {
821
+ const key = imageVisualFrameKey(input);
822
+ if (!force && this.isKnownKey(slot, key))
823
+ return;
824
+ const request = {
825
+ ...input,
826
+ imageId,
827
+ ...imageIds ? { imageIds } : {},
828
+ zIndex,
829
+ transport: this.transport,
830
+ requestId: ++this.requestId,
831
+ key
832
+ };
833
+ if (slot.worker) {
834
+ this.enqueueWorkerRender(slot, request);
835
+ return;
836
+ }
837
+ this.renderSync(slot, request);
838
+ }
839
+ startWorker(slot) {
840
+ const worker = createImageWorker();
841
+ if (!worker)
842
+ return;
843
+ slot.worker = worker;
844
+ worker.on("message", (message) => this.handleWorkerMessage(slot, message));
845
+ worker.once("error", () => this.disableWorker(slot));
846
+ worker.once("exit", () => this.disableWorker(slot));
847
+ }
848
+ disableWorker(slot) {
849
+ if (this.destroyed)
850
+ return;
851
+ slot.worker = null;
852
+ slot.busy = false;
853
+ slot.inFlightKey = "";
854
+ const queued = slot.queuedRequest;
855
+ slot.queuedRequest = null;
856
+ slot.queuedKey = "";
857
+ if (queued?.layer === "full")
858
+ this.renderSync(slot, queued);
859
+ }
860
+ enqueueWorkerRender(slot, request) {
861
+ if (!slot.worker) {
862
+ this.renderSync(slot, request);
863
+ return;
864
+ }
865
+ if (slot.busy) {
866
+ slot.queuedRequest = request;
867
+ slot.queuedKey = request.key;
868
+ return;
869
+ }
870
+ this.dispatchWorkerRender(slot, request);
871
+ }
872
+ dispatchWorkerRender(slot, request) {
873
+ if (!slot.worker) {
874
+ this.renderSync(slot, request);
875
+ return;
876
+ }
877
+ slot.busy = true;
878
+ slot.inFlightKey = request.key;
879
+ slot.worker.postMessage(request);
880
+ }
881
+ handleWorkerMessage(slot, message) {
882
+ if (this.destroyed || !message || typeof message !== "object")
883
+ return;
884
+ const response = message;
885
+ slot.busy = false;
886
+ slot.inFlightKey = "";
887
+ if (response.requestId <= slot.clearedThroughRequestId)
888
+ return;
889
+ if (response.error) {
890
+ this.disableWorker(slot);
891
+ return;
892
+ }
893
+ if (response.sequence && !this.isKnownKey(slot, response.key) && (!this.isOutputBackedUp() || pendingLayerKey(response.key) === "panel-chrome")) {
894
+ this.stageFrame({ key: response.key, sequence: response.sequence });
895
+ }
896
+ const next = slot.queuedRequest;
897
+ slot.queuedRequest = null;
898
+ slot.queuedKey = "";
899
+ if (next && !this.isKnownKey(slot, next.key))
900
+ this.dispatchWorkerRender(slot, next);
901
+ }
902
+ renderSync(slot, request) {
903
+ const result = renderImageVisualFrame(request);
904
+ if (!result || this.isKnownKey(slot, result.key) || this.isOutputBackedUp())
905
+ return;
906
+ this.stageFrame(result);
907
+ }
908
+ }
909
+ var BG, PANEL, PANEL_HEADER, PANEL_LINE, LIME, LIME_DIM, CYAN, MAGENTA, INK_DIM, PNG_SIGNATURE, CRC_TABLE, MAX_IMAGE_BYTES, KITTY_CHUNK_SIZE = 4096, PANEL_BLUR_SCALE = 5, PANEL_MASK_CACHE_LIMIT = 16, ZLIB_LEVEL = 1, DEFAULT_DRONE_LAYER_SCALE = 0.18, DEFAULT_IMAGE_FPS = 24, panelMaskCache, BG_WORD, RECENT_WRITTEN_LIMIT = 24, DEFAULT_PANEL_FPS = 24, DEFAULT_PANEL_LAYER_SCALE = 0.22, DEFAULT_IMAGE_OUTPUT_BACKLOG_BYTES, DEFAULT_IMAGE_OUTPUT_BYTES_PER_SECOND, MIN_BACKGROUND_BUDGET_BYTES, MIN_PANEL_BUDGET_BYTES;
910
+ var init_image_visual_layer = __esm(() => {
911
+ BG = [7, 8, 9, 255];
912
+ PANEL = [16, 17, 21, 184];
913
+ PANEL_HEADER = [16, 17, 21, 190];
914
+ PANEL_LINE = [255, 255, 255, 24];
915
+ LIME = [204, 255, 77, 255];
916
+ LIME_DIM = [169, 214, 63, 255];
917
+ CYAN = [86, 216, 255, 255];
918
+ MAGENTA = [255, 121, 176, 255];
919
+ INK_DIM = [108, 110, 121, 255];
920
+ PNG_SIGNATURE = new Uint8Array([137, 80, 78, 71, 13, 10, 26, 10]);
921
+ CRC_TABLE = makeCrcTable();
922
+ MAX_IMAGE_BYTES = 48 * 1024 * 1024;
923
+ panelMaskCache = new Map;
924
+ BG_WORD = rgbaWord(BG);
925
+ DEFAULT_IMAGE_OUTPUT_BACKLOG_BYTES = 256 * 1024;
926
+ DEFAULT_IMAGE_OUTPUT_BYTES_PER_SECOND = 850 * 1024;
927
+ MIN_BACKGROUND_BUDGET_BYTES = 24 * 1024;
928
+ MIN_PANEL_BUDGET_BYTES = 56 * 1024;
929
+ });
930
+
931
+ // packages/cli/src/app-opentui/render/image-visual-layer-native-canvas.ts
932
+ var exports_image_visual_layer_native_canvas = {};
933
+ __export(exports_image_visual_layer_native_canvas, {
934
+ renderNativeCanvasImageVisualFrame: () => renderNativeCanvasImageVisualFrame
935
+ });
936
+ import { mkdirSync, writeFileSync } from "fs";
937
+ import { join } from "path";
938
+ import { tmpdir } from "os";
939
+ import { clearAllCache, createCanvas } from "@napi-rs/canvas";
940
+ function droneLayerScale2() {
941
+ const raw = Number.parseFloat(process.env.RIG_OPENTUI_DRONE_SCALE ?? "");
942
+ if (Number.isFinite(raw) && raw > 0)
943
+ return Math.max(0.15, Math.min(1, raw));
944
+ return DEFAULT_DRONE_LAYER_SCALE2;
945
+ }
946
+ function kittyTransmission() {
947
+ return process.env.RIG_OPENTUI_KITTY_TRANSMISSION === "temp-file" ? "temp-file" : "direct";
948
+ }
949
+ function motionDensity() {
950
+ const raw = Number.parseFloat(process.env.RIG_OPENTUI_MOTION_DENSITY ?? "");
951
+ if (Number.isFinite(raw) && raw > 0)
952
+ return Math.max(0.2, Math.min(1.4, raw));
953
+ return DEFAULT_MOTION_DENSITY;
954
+ }
955
+ function motionSpeed() {
956
+ const raw = Number.parseFloat(process.env.RIG_OPENTUI_MOTION_SPEED ?? "");
957
+ if (Number.isFinite(raw) && raw > 0)
958
+ return Math.max(0.25, Math.min(1.5, raw));
959
+ return DEFAULT_MOTION_SPEED;
960
+ }
961
+ function resetContext(ctx, width, height) {
962
+ ctx.reset();
963
+ ctx.clearRect(0, 0, width, height);
964
+ ctx.imageSmoothingEnabled = true;
965
+ ctx.imageSmoothingQuality = "high";
966
+ }
967
+ function reusableCanvas(width, height) {
968
+ if (!frameCanvas || !frameCtx || frameCanvas.width !== width || frameCanvas.height !== height) {
969
+ frameCanvas = createCanvas(width, height);
970
+ frameCtx = frameCanvas.getContext("2d");
971
+ }
972
+ resetContext(frameCtx, width, height);
973
+ return { canvas: frameCanvas, ctx: frameCtx };
974
+ }
975
+ function reusableSceneCanvas(width, height) {
976
+ if (!sceneCanvas || !sceneCtx || sceneCanvas.width !== width || sceneCanvas.height !== height) {
977
+ sceneCanvas = createCanvas(width, height);
978
+ sceneCtx = sceneCanvas.getContext("2d");
979
+ }
980
+ resetContext(sceneCtx, width, height);
981
+ return { canvas: sceneCanvas, ctx: sceneCtx };
982
+ }
983
+ function reusablePatchCanvas(width, height) {
984
+ if (!patchCanvas || !patchCtx || patchCanvas.width !== width || patchCanvas.height !== height) {
985
+ patchCanvas = createCanvas(width, height);
986
+ patchCtx = patchCanvas.getContext("2d");
987
+ }
988
+ resetContext(patchCtx, width, height);
989
+ return { canvas: patchCanvas, ctx: patchCtx };
990
+ }
991
+ function css(color, alphaScale = 1) {
992
+ return `rgba(${color[0]},${color[1]},${color[2]},${Math.max(0, Math.min(1, color[3] / 255 * alphaScale))})`;
993
+ }
994
+ function visualSceneKind2(scene) {
995
+ if (scene === "tasks")
996
+ return "loop";
997
+ if (scene === "help")
998
+ return "carrier";
999
+ return "dispatch";
1000
+ }
1001
+ function seededUnit2(seed) {
1002
+ let value = seed >>> 0;
1003
+ value = value * 1664525 + 1013904223 >>> 0;
1004
+ return value / 4294967295;
1005
+ }
1006
+ function sceneCore2(width, height, kind) {
1007
+ if (kind === "dispatch")
1008
+ return { x: width * 0.3, y: height * 0.45 };
1009
+ if (kind === "carrier")
1010
+ return { x: width * 0.5, y: height * 0.54 };
1011
+ return { x: width * 0.09, y: height * 0.56 };
1012
+ }
1013
+ function dispatchLane2(width, index, count) {
1014
+ const a = seededUnit2(28672 + index * 101);
1015
+ const b = seededUnit2(36864 + index * 131);
1016
+ const c = seededUnit2(45056 + index * 151);
1017
+ const ang = (-0.9 + 1.8 * (index / Math.max(1, count - 1))) * (Math.PI * 0.5);
1018
+ return { ang, len: width * (0.32 + a * 0.42), curve: (b - 0.5) * 0.7, phase: c * Math.PI * 2 };
1019
+ }
1020
+ function lanePoint2(width, height, lane, p, kind = "dispatch") {
1021
+ const core = sceneCore2(width, height, kind);
1022
+ const dist = lane.len * p;
1023
+ const bend = Math.sin(p * Math.PI) * lane.curve * Math.min(width, height) * 0.035;
1024
+ const ux = Math.cos(lane.ang);
1025
+ const uy = Math.sin(lane.ang);
1026
+ return { x: core.x + ux * dist + -uy * bend, y: core.y + uy * dist + ux * bend };
1027
+ }
1028
+ function drawGlow2(ctx, cx, cy, radius, color, alpha = 0.18) {
1029
+ if (radius <= 0)
1030
+ return;
1031
+ const gradient = ctx.createRadialGradient(cx, cy, 0, cx, cy, radius);
1032
+ gradient.addColorStop(0, css(color, alpha));
1033
+ gradient.addColorStop(0.45, css(color, alpha * 0.28));
1034
+ gradient.addColorStop(1, css(color, 0));
1035
+ ctx.fillStyle = gradient;
1036
+ ctx.beginPath();
1037
+ ctx.arc(cx, cy, radius, 0, Math.PI * 2);
1038
+ ctx.fill();
1039
+ }
1040
+ function drawDisc2(ctx, cx, cy, radius, color, alpha = 1) {
1041
+ if (radius <= 0)
1042
+ return;
1043
+ ctx.fillStyle = css(color, alpha);
1044
+ ctx.beginPath();
1045
+ ctx.arc(cx, cy, radius, 0, Math.PI * 2);
1046
+ ctx.fill();
1047
+ }
1048
+ function drawLine2(ctx, x0, y0, x1, y1, color, alpha = 0.5, thickness = 1.4) {
1049
+ ctx.save();
1050
+ ctx.strokeStyle = css(color, alpha);
1051
+ ctx.lineWidth = thickness * 2;
1052
+ ctx.lineCap = "round";
1053
+ ctx.lineJoin = "round";
1054
+ ctx.beginPath();
1055
+ ctx.moveTo(x0, y0);
1056
+ ctx.lineTo(x1, y1);
1057
+ ctx.stroke();
1058
+ ctx.restore();
1059
+ }
1060
+ function drawDrone2(ctx, x, y, scale, tick, color) {
1061
+ const speed = motionSpeed();
1062
+ const wobble = Math.sin(tick * 0.055 * speed) * scale * 0.35;
1063
+ const cy = y + wobble;
1064
+ drawGlow2(ctx, x, cy, scale * 7, color, 0.18);
1065
+ drawDisc2(ctx, x, cy, scale * 1.45, color, 0.92);
1066
+ drawDisc2(ctx, x, cy, scale * 0.55, [235, 255, 176, 255], 0.85);
1067
+ const arm = scale * 4.1;
1068
+ const rotor = scale * 1.6;
1069
+ const arms = [[-arm, -arm * 0.72], [arm, -arm * 0.72], [-arm, arm * 0.72], [arm, arm * 0.72]];
1070
+ for (const [dx, dy] of arms) {
1071
+ drawLine2(ctx, x, cy, x + dx, cy + dy, color, 0.42, Math.max(1, scale * 0.22));
1072
+ drawGlow2(ctx, x + dx, cy + dy, rotor * 2.6, color, 0.1);
1073
+ drawDisc2(ctx, x + dx, cy + dy, rotor, color, 0.34 + 0.12 * Math.sin(tick * 0.15 * speed));
1074
+ }
1075
+ }
1076
+ function drawMarketingRails2(ctx, width, height, kind, tick) {
1077
+ const density = motionDensity();
1078
+ const speed = motionSpeed();
1079
+ const ys = kind === "loop" ? [0.18, 0.5, 0.82] : kind === "carrier" ? [0.24, 0.54, 0.82] : [0.18, 0.58, 0.82];
1080
+ ys.forEach((ratio, index) => {
1081
+ const y = height * ratio + Math.sin(tick * 0.018 * speed + index) * Math.max(2, height * 0.0025);
1082
+ const color = index === 2 ? CYAN2 : index === 1 ? LIME2 : LIME_DIM2;
1083
+ drawLine2(ctx, width * 0.06, y, width * 0.94, y + Math.sin(index) * height * 0.002, color, index === 1 ? 0.09 : 0.055, Math.max(0.8, height * 0.0012));
1084
+ const spacing = (0.18 + index * 0.02) / density;
1085
+ for (let p = (tick * 0.004 * speed + index * 0.21) % 1;p < 1; p += spacing) {
1086
+ const x = width * (0.06 + 0.88 * p);
1087
+ drawDisc2(ctx, x, y, Math.max(1.2, height * (0.0017 + index * 0.0004)), color, 0.18);
1088
+ drawGlow2(ctx, x, y, Math.max(5, height * 0.006), color, 0.026);
1089
+ }
1090
+ });
1091
+ }
1092
+ function drawDispatchScene2(ctx, width, height, tick) {
1093
+ const density = motionDensity();
1094
+ const speed = motionSpeed();
1095
+ const core = sceneCore2(width, height, "dispatch");
1096
+ const min = Math.min(width, height);
1097
+ drawGlow2(ctx, core.x, core.y, min * 0.085, LIME2, 0.12);
1098
+ drawDisc2(ctx, core.x, core.y, min * 0.0065, LIME2, 0.85);
1099
+ const laneCount = Math.max(4, Math.round((width < 1000 ? 7 : 12) * (0.65 + density * 0.35)));
1100
+ const lanes = Array.from({ length: laneCount }, (_, index) => dispatchLane2(width, index, laneCount));
1101
+ lanes.forEach((lane) => {
1102
+ let prev = lanePoint2(width, height, lane, 0);
1103
+ ctx.beginPath();
1104
+ ctx.moveTo(prev.x, prev.y);
1105
+ for (let step = 1;step <= 32; step += 1) {
1106
+ const next = lanePoint2(width, height, lane, step / 32);
1107
+ ctx.lineTo(next.x, next.y);
1108
+ prev = next;
1109
+ }
1110
+ ctx.strokeStyle = css(lane.phase > Math.PI ? CYAN2 : LIME_DIM2, 0.045);
1111
+ ctx.lineWidth = Math.max(0.7, min * 0.0009) * 2;
1112
+ ctx.lineCap = "round";
1113
+ ctx.stroke();
1114
+ });
1115
+ const packets = Math.max(24, Math.round((width < 1000 ? 70 : 150) * density));
1116
+ for (let i = 0;i < packets; i += 1) {
1117
+ const lane = lanes[i % lanes.length];
1118
+ const packetSpeed = (0.003 + seededUnit2(12288 + i * 17) * 0.009) * speed;
1119
+ const p = (seededUnit2(16384 + i * 19) + tick * packetSpeed) % 1;
1120
+ const pt = lanePoint2(width, height, lane, p);
1121
+ const wobble = (seededUnit2(20480 + i * 23) - 0.5) * min * 0.012;
1122
+ const fade = p < 0.1 ? p / 0.1 : p > 0.88 ? (1 - p) / 0.12 : 1;
1123
+ const color = seededUnit2(24576 + i * 29) < 0.22 ? CYAN2 : LIME_DIM2;
1124
+ const y = pt.y + wobble * Math.sin(p * Math.PI * 2);
1125
+ drawLine2(ctx, pt.x - min * 0.012, y - min * 0.002, pt.x, y, color, 0.08 * fade, Math.max(0.7, min * 0.0008));
1126
+ drawDisc2(ctx, pt.x, y, Math.max(1.3, min * 0.0022), color, 0.5 * fade);
1127
+ drawGlow2(ctx, pt.x, y, Math.max(4, min * 0.008), color, 0.045 * fade);
1128
+ }
1129
+ const droneCount = Math.max(2, Math.round((width < 1000 ? 4 : 8) * density));
1130
+ for (let i = 0;i < droneCount; i += 1) {
1131
+ const lane = lanes[i % lanes.length];
1132
+ const p = (tick * 0.002 * speed + i * 0.13) % 1;
1133
+ const pt = lanePoint2(width, height, lane, p);
1134
+ drawDrone2(ctx, pt.x, pt.y + Math.sin(tick * 0.04 * speed + i) * min * 0.004, min * (0.006 + i % 2 * 0.0015), tick + i * 11, i % 3 === 0 ? CYAN2 : LIME_DIM2);
1135
+ }
1136
+ }
1137
+ function drawLoopScene2(ctx, width, height, tick) {
1138
+ const density = motionDensity();
1139
+ const speed = motionSpeed();
1140
+ const min = Math.min(width, height);
1141
+ const y = height * 0.56;
1142
+ const x0 = width * 0.09;
1143
+ const x1 = width * 0.91;
1144
+ drawLine2(ctx, x0, y, x1, y, LIME_DIM2, 0.12, Math.max(0.8, min * 0.001));
1145
+ const gates = width < 1000 ? 4 : 5;
1146
+ const active = Math.floor(tick * speed / 20) % gates;
1147
+ for (let i = 0;i < gates; i += 1) {
1148
+ const x = x0 + (x1 - x0) * (i / Math.max(1, gates - 1));
1149
+ const color = i === active ? LIME2 : i <= active ? LIME_DIM2 : INK_DIM2;
1150
+ drawLine2(ctx, x, y - min * 0.05, x, y + min * 0.05, color, i === active ? 0.25 : 0.08, Math.max(0.8, min * 0.001));
1151
+ drawDisc2(ctx, x, y, i === active ? min * 0.006 : min * 0.0035, color, i === active ? 0.72 : 0.25);
1152
+ drawGlow2(ctx, x, y, i === active ? min * 0.018 : min * 0.01, color, i === active ? 0.1 : 0.035);
1153
+ }
1154
+ const packets = Math.max(16, Math.round((width < 1000 ? 36 : 84) * density));
1155
+ for (let i = 0;i < packets; i += 1) {
1156
+ const p = (seededUnit2(33024 + i * 13) + tick * (0.0022 + seededUnit2(33280 + i * 17) * 0.004) * speed) % 1;
1157
+ const x = x0 + (x1 - x0) * p;
1158
+ const segment = Math.min(gates - 1, Math.floor(p * gates));
1159
+ const color = segment < active ? LIME_DIM2 : segment === active ? CYAN2 : INK_DIM2;
1160
+ const py = y + (seededUnit2(33536 + i * 19) - 0.5) * min * 0.018 * Math.sin(p * Math.PI * 2);
1161
+ drawLine2(ctx, x - min * 0.014, py, x, py, color, 0.1, Math.max(0.7, min * 0.0008));
1162
+ drawDisc2(ctx, x, py, Math.max(1.2, min * 0.002), color, color === INK_DIM2 ? 0.22 : 0.58);
1163
+ }
1164
+ drawDrone2(ctx, x0 + (x1 - x0) * (tick * 0.003 * speed % 1), y - min * 0.04, min * 0.0065, tick, LIME_DIM2);
1165
+ drawDrone2(ctx, x0 + (x1 - x0) * ((tick * 0.002 * speed + 0.5) % 1), y + min * 0.036, min * 0.0055, tick + 40, MAGENTA2);
1166
+ }
1167
+ function drawCarrierScene2(ctx, width, height, tick) {
1168
+ const density = motionDensity();
1169
+ const speed = motionSpeed();
1170
+ const min = Math.min(width, height);
1171
+ const core = sceneCore2(width, height, "carrier");
1172
+ drawGlow2(ctx, core.x, core.y, min * 0.075, LIME2, 0.12);
1173
+ drawDisc2(ctx, core.x, core.y, min * 0.0065, LIME2, 0.92);
1174
+ const nodes = Math.max(4, Math.round((width < 1000 ? 5 : 7) * (0.75 + density * 0.25)));
1175
+ const rx = width * 0.36;
1176
+ const ry = height * 0.22;
1177
+ for (let i = 0;i < nodes; i += 1) {
1178
+ const a = i / nodes * Math.PI * 2 - Math.PI / 2 + tick * 0.006 * speed;
1179
+ const x = core.x + Math.cos(a) * rx;
1180
+ const y = core.y + Math.sin(a) * ry;
1181
+ const color = i % 2 ? CYAN2 : LIME_DIM2;
1182
+ drawLine2(ctx, core.x, core.y, x, y, color, 0.055, Math.max(0.7, min * 0.0008));
1183
+ drawGlow2(ctx, x, y, min * 0.018, color, 0.055);
1184
+ drawDisc2(ctx, x, y, min * 0.0048, color, 0.62);
1185
+ drawDrone2(ctx, x, y - min * 0.018, min * 0.005, tick + i * 9, color);
1186
+ }
1187
+ const packets = Math.max(14, Math.round((width < 1000 ? 30 : 72) * density));
1188
+ for (let i = 0;i < packets; i += 1) {
1189
+ const lane = i % nodes;
1190
+ const a = lane / nodes * Math.PI * 2 - Math.PI / 2 + tick * 0.006 * speed;
1191
+ const nx = core.x + Math.cos(a) * rx;
1192
+ const ny = core.y + Math.sin(a) * ry;
1193
+ const p = (seededUnit2(37120 + i * 37) + tick * (0.003 + seededUnit2(37376 + i * 43) * 0.009) * speed) % 1;
1194
+ const x = core.x + (nx - core.x) * p;
1195
+ const y = core.y + (ny - core.y) * p;
1196
+ const color = seededUnit2(37632 + i * 47) < 0.35 ? CYAN2 : LIME_DIM2;
1197
+ drawDisc2(ctx, x, y, Math.max(1.2, min * 0.002), color, 0.48);
1198
+ drawGlow2(ctx, x, y, min * 0.008, color, 0.035);
1199
+ }
1200
+ }
1201
+ function drawBackground2(ctx, width, height, tick, scene) {
1202
+ ctx.fillStyle = css(BG2);
1203
+ ctx.fillRect(0, 0, width, height);
1204
+ const kind = visualSceneKind2(scene);
1205
+ drawGlow2(ctx, width * 0.82, height * 0.04, Math.min(width, height) * 0.22, LIME2, 0.035);
1206
+ drawGlow2(ctx, width * 0.12, height * 0.18, Math.min(width, height) * 0.17, CYAN2, 0.025);
1207
+ drawMarketingRails2(ctx, width, height, kind, tick);
1208
+ if (kind === "loop")
1209
+ drawLoopScene2(ctx, width, height, tick);
1210
+ else if (kind === "carrier")
1211
+ drawCarrierScene2(ctx, width, height, tick);
1212
+ else
1213
+ drawDispatchScene2(ctx, width, height, tick);
1214
+ }
1215
+ function drawScaledDroneLayer(ctx, width, height, tick, scene) {
1216
+ const scale = droneLayerScale2();
1217
+ if (scale >= 0.99) {
1218
+ drawBackground2(ctx, width, height, tick, scene);
1219
+ return;
1220
+ }
1221
+ const sceneWidth = Math.max(1, Math.round(width * scale));
1222
+ const sceneHeight = Math.max(1, Math.round(height * scale));
1223
+ const { canvas, ctx: sceneCtx2 } = reusableSceneCanvas(sceneWidth, sceneHeight);
1224
+ drawBackground2(sceneCtx2, sceneWidth, sceneHeight, tick, scene);
1225
+ ctx.save();
1226
+ ctx.imageSmoothingEnabled = true;
1227
+ ctx.imageSmoothingQuality = "high";
1228
+ ctx.drawImage(canvas, 0, 0, sceneWidth, sceneHeight, 0, 0, width, height);
1229
+ ctx.restore();
1230
+ }
1231
+ function panelPlacement(layout, panel, size) {
1232
+ const cellW = size.width / layout.width;
1233
+ const cellH = size.height / layout.height;
1234
+ const leftCells = layout.centerLeft + (panel.left ?? 0);
1235
+ const topCells = layout.centerTop + panel.top;
1236
+ const widthCells = panel.width ?? layout.centerWidth;
1237
+ const heightCells = panel.height;
1238
+ const left = Math.round(leftCells * cellW);
1239
+ const top = Math.round(topCells * cellH);
1240
+ const width = Math.round(widthCells * cellW);
1241
+ const height = Math.round(heightCells * cellH);
1242
+ return width > 8 && height > 8 ? { left, top, width, height, leftCells, topCells, widthCells, heightCells } : null;
1243
+ }
1244
+ function panelRect2(layout, panel, size) {
1245
+ return panelPlacement(layout, panel, size);
1246
+ }
1247
+ function clipRoundRect(ctx, rect, radius) {
1248
+ ctx.beginPath();
1249
+ ctx.roundRect(rect.left, rect.top, rect.width, rect.height, radius);
1250
+ ctx.clip();
1251
+ }
1252
+ function strokeRoundRect(ctx, rect, radius) {
1253
+ ctx.beginPath();
1254
+ ctx.roundRect(rect.left + 0.75, rect.top + 0.75, rect.width - 1.5, rect.height - 1.5, Math.max(1, radius - 0.75));
1255
+ ctx.stroke();
1256
+ }
1257
+ function compositePanel2(ctx, sourceCanvas, rect, headerPx) {
1258
+ const radius = Math.max(14, Math.min(34, Math.round(Math.min(rect.width, rect.height) * 0.035)));
1259
+ const { canvas: patch, ctx: patchCtx2 } = reusablePatchCanvas(rect.width, rect.height);
1260
+ patchCtx2.drawImage(sourceCanvas, rect.left, rect.top, rect.width, rect.height, 0, 0, rect.width, rect.height);
1261
+ ctx.save();
1262
+ clipRoundRect(ctx, rect, radius);
1263
+ ctx.filter = `blur(${Math.max(10, Math.round(Math.min(rect.width, rect.height) * 0.018))}px)`;
1264
+ ctx.drawImage(patch, 0, 0, rect.width, rect.height, rect.left, rect.top, rect.width, rect.height);
1265
+ ctx.filter = "none";
1266
+ ctx.fillStyle = css(PANEL2);
1267
+ ctx.fillRect(rect.left, rect.top, rect.width, rect.height);
1268
+ ctx.fillStyle = css(PANEL_HEADER2);
1269
+ ctx.fillRect(rect.left, rect.top, rect.width, headerPx);
1270
+ ctx.restore();
1271
+ ctx.save();
1272
+ ctx.strokeStyle = css(PANEL_LINE2, 0.8);
1273
+ ctx.lineWidth = 1.5;
1274
+ strokeRoundRect(ctx, rect, radius);
1275
+ ctx.restore();
1276
+ const dividerY = Math.round(rect.top + headerPx);
1277
+ if (dividerY > rect.top && dividerY < rect.top + rect.height) {
1278
+ drawLine2(ctx, rect.left + radius, dividerY, rect.left + rect.width - radius, dividerY, PANEL_LINE2, 0.28, 0.7);
1279
+ }
1280
+ }
1281
+ function compositePanelPatch(ctx, sourceCanvas, width, height, headerPx) {
1282
+ const rect = { left: 0, top: 0, width, height };
1283
+ const radius = Math.max(14, Math.min(34, Math.round(Math.min(width, height) * 0.035)));
1284
+ ctx.save();
1285
+ clipRoundRect(ctx, rect, radius);
1286
+ ctx.filter = `blur(${Math.max(10, Math.round(Math.min(width, height) * 0.018))}px)`;
1287
+ ctx.drawImage(sourceCanvas, 0, 0, width, height);
1288
+ ctx.filter = "none";
1289
+ ctx.fillStyle = css(PANEL2);
1290
+ ctx.fillRect(0, 0, width, height);
1291
+ ctx.fillStyle = css(PANEL_HEADER2);
1292
+ ctx.fillRect(0, 0, width, headerPx);
1293
+ ctx.restore();
1294
+ }
1295
+ function compositePanelChromePatch(ctx, width, height, headerPx) {
1296
+ const radius = Math.max(14, Math.min(34, Math.round(Math.min(width, height) * 0.035)));
1297
+ ctx.clearRect(0, 0, width, height);
1298
+ const dividerY = Math.round(headerPx);
1299
+ if (dividerY > 0 && dividerY < height)
1300
+ drawLine2(ctx, radius, dividerY, width - radius, dividerY, PANEL_LINE2, 0.22, 0.65);
1301
+ }
1302
+ async function encodePanelPatch(input, placement, imageId, headerPx) {
1303
+ const { canvas: sourceCanvas, ctx: sourceCtx } = reusableSceneCanvas(placement.width, placement.height);
1304
+ sourceCtx.save();
1305
+ sourceCtx.translate(-placement.left, -placement.top);
1306
+ drawScaledDroneLayer(sourceCtx, input.pixelSize.width, input.pixelSize.height, input.tick, input.scene);
1307
+ sourceCtx.restore();
1308
+ const { canvas: patchCanvas2, ctx: patchCtx2 } = reusablePatchCanvas(placement.width, placement.height);
1309
+ compositePanelPatch(patchCtx2, sourceCanvas, placement.width, placement.height, headerPx);
1310
+ const png = await patchCanvas2.encode("png");
1311
+ const sequence = kittyPngFrameSequence(png, { columns: Math.max(1, Math.round(placement.widthCells)), rows: Math.max(1, Math.round(placement.heightCells)), imageId, zIndex: -12 });
1312
+ return `\x1B[${Math.max(1, Math.round(placement.topCells) + 1)};${Math.max(1, Math.round(placement.leftCells) + 1)}H${sequence}`;
1313
+ }
1314
+ async function encodePanelChromePatch(placement, imageId, headerPx) {
1315
+ const { canvas: patchCanvas2, ctx: patchCtx2 } = reusablePatchCanvas(placement.width, placement.height);
1316
+ compositePanelChromePatch(patchCtx2, placement.width, placement.height, headerPx);
1317
+ const png = await patchCanvas2.encode("png");
1318
+ const sequence = kittyPngFrameSequence(png, { columns: Math.max(1, Math.round(placement.widthCells)), rows: Math.max(1, Math.round(placement.heightCells)), imageId, zIndex: -8 });
1319
+ return `\x1B[${Math.max(1, Math.round(placement.topCells) + 1)};${Math.max(1, Math.round(placement.leftCells) + 1)}H${sequence}`;
1320
+ }
1321
+ function kittyImageSequence2(base64, options) {
1322
+ const params = [`a=T`, `f=100`, `q=2`, `C=1`, `c=${options.columns}`, `r=${options.rows}`, `i=${options.imageId}`, `z=${options.zIndex}`];
1323
+ if (base64.length <= KITTY_CHUNK_SIZE2)
1324
+ return `\x1B_G${params.join(",")};${base64}\x1B\\`;
1325
+ const chunks = [];
1326
+ for (let offset = 0;offset < base64.length; offset += KITTY_CHUNK_SIZE2) {
1327
+ const part = base64.slice(offset, offset + KITTY_CHUNK_SIZE2);
1328
+ const last = offset + KITTY_CHUNK_SIZE2 >= base64.length;
1329
+ chunks.push(`\x1B_G${offset === 0 ? `${params.join(",")},` : ""}m=${last ? 0 : 1};${part}\x1B\\`);
1330
+ }
1331
+ return chunks.join("");
1332
+ }
1333
+ function kittyTempFileImageSequence(png, options) {
1334
+ mkdirSync(TEMP_GRAPHICS_DIR, { recursive: true });
1335
+ const path = join(TEMP_GRAPHICS_DIR, `frame-${process.pid}-${Date.now()}-${encodedFrames}.tty-graphics-protocol.png`);
1336
+ writeFileSync(path, png);
1337
+ const payload = Buffer.from(path).toString("base64");
1338
+ const params = [`a=T`, `f=100`, `t=t`, `S=${png.byteLength}`, `q=2`, `C=1`, `c=${options.columns}`, `r=${options.rows}`, `i=${options.imageId}`, `z=${options.zIndex}`];
1339
+ return `\x1B_G${params.join(",")};${payload}\x1B\\`;
1340
+ }
1341
+ function kittyPngFrameSequence(png, options) {
1342
+ if (kittyTransmission() === "temp-file")
1343
+ return kittyTempFileImageSequence(png, options);
1344
+ return kittyImageSequence2(png.toString("base64"), options);
1345
+ }
1346
+ async function renderNativeCanvasImageVisualFrame(input) {
1347
+ if (input.transport !== "png")
1348
+ return null;
1349
+ const width = Math.max(1, Math.floor(input.pixelSize.width));
1350
+ const height = Math.max(1, Math.floor(input.pixelSize.height));
1351
+ if (width * height * 4 > MAX_IMAGE_BYTES2)
1352
+ return null;
1353
+ const layer = input.layer ?? "full";
1354
+ if (layer === "split") {
1355
+ const backgroundScale = droneLayerScale2();
1356
+ const backgroundWidth = Math.max(input.layout.width, Math.round(width * backgroundScale));
1357
+ const backgroundHeight = Math.max(input.layout.height, Math.round(height * backgroundScale));
1358
+ const { canvas: backgroundCanvas, ctx: backgroundCtx } = reusableCanvas(backgroundWidth, backgroundHeight);
1359
+ drawBackground2(backgroundCtx, backgroundWidth, backgroundHeight, input.tick, input.scene);
1360
+ const backgroundPng = await backgroundCanvas.encode("png");
1361
+ const sequences = [kittyPngFrameSequence(backgroundPng, { columns: input.layout.width, rows: input.layout.height, imageId: input.imageId, zIndex: -30 })];
1362
+ let panelIndex = 0;
1363
+ for (const panel of input.panels) {
1364
+ if (panel.chrome !== "ad-terminal")
1365
+ continue;
1366
+ const placement = panelPlacement(input.layout, panel, { width, height });
1367
+ if (!placement)
1368
+ continue;
1369
+ const imageId = input.imageIds?.[panelIndex] ?? (input.imageId + 1000 + panelIndex >>> 0 || panelIndex + 1);
1370
+ const cellH = height / input.layout.height;
1371
+ const headerPx = Math.max(cellH * 3, (panel.headerHeight ?? 3) * cellH);
1372
+ sequences.push(await encodePanelPatch(input, placement, imageId, headerPx));
1373
+ panelIndex += 1;
1374
+ }
1375
+ encodedFrames += 1;
1376
+ if (encodedFrames % SKIA_CACHE_CLEAR_INTERVAL === 0)
1377
+ clearAllCache();
1378
+ return {
1379
+ key: imageVisualFrameKey(input),
1380
+ sequence: sequences.join("")
1381
+ };
1382
+ }
1383
+ if (layer === "panel-patches") {
1384
+ const sequences = [];
1385
+ let panelIndex = 0;
1386
+ for (const panel of input.panels) {
1387
+ if (panel.chrome !== "ad-terminal")
1388
+ continue;
1389
+ const placement = panelPlacement(input.layout, panel, { width, height });
1390
+ if (!placement)
1391
+ continue;
1392
+ const imageId = input.imageIds?.[panelIndex] ?? (input.imageId + 1000 + panelIndex >>> 0 || panelIndex + 1);
1393
+ const cellH = height / input.layout.height;
1394
+ const headerPx = Math.max(cellH * 3, (panel.headerHeight ?? 3) * cellH);
1395
+ sequences.push(await encodePanelPatch(input, placement, imageId, headerPx));
1396
+ panelIndex += 1;
1397
+ }
1398
+ encodedFrames += 1;
1399
+ if (encodedFrames % SKIA_CACHE_CLEAR_INTERVAL === 0)
1400
+ clearAllCache();
1401
+ return {
1402
+ key: imageVisualFrameKey(input),
1403
+ sequence: sequences.join("")
1404
+ };
1405
+ }
1406
+ if (layer === "panel-chrome") {
1407
+ const sequences = [];
1408
+ let panelIndex = 0;
1409
+ for (const panel of input.panels) {
1410
+ if (panel.chrome !== "ad-terminal")
1411
+ continue;
1412
+ const placement = panelPlacement(input.layout, panel, { width, height });
1413
+ if (!placement)
1414
+ continue;
1415
+ const imageId = input.imageIds?.[panelIndex] ?? (input.imageId + 2000 + panelIndex >>> 0 || panelIndex + 1);
1416
+ const cellH = height / input.layout.height;
1417
+ const headerPx = Math.max(cellH * 3, (panel.headerHeight ?? 3) * cellH);
1418
+ sequences.push(await encodePanelChromePatch(placement, imageId, headerPx));
1419
+ panelIndex += 1;
1420
+ }
1421
+ encodedFrames += 1;
1422
+ if (encodedFrames % SKIA_CACHE_CLEAR_INTERVAL === 0)
1423
+ clearAllCache();
1424
+ return {
1425
+ key: imageVisualFrameKey(input),
1426
+ sequence: sequences.join("")
1427
+ };
1428
+ }
1429
+ const { canvas, ctx } = reusableCanvas(width, height);
1430
+ if (layer === "background") {
1431
+ drawBackground2(ctx, width, height, input.tick, input.scene);
1432
+ } else if (layer === "panels") {
1433
+ const { canvas: sourceCanvas, ctx: sourceCtx } = reusableSceneCanvas(width, height);
1434
+ drawScaledDroneLayer(sourceCtx, width, height, input.tick, input.scene);
1435
+ for (const panel of input.panels) {
1436
+ if (panel.chrome !== "ad-terminal")
1437
+ continue;
1438
+ const rect = panelRect2(input.layout, panel, { width, height });
1439
+ if (!rect)
1440
+ continue;
1441
+ const cellH = height / input.layout.height;
1442
+ const headerPx = Math.max(cellH * 3, (panel.headerHeight ?? 3) * cellH);
1443
+ compositePanel2(ctx, sourceCanvas, rect, headerPx);
1444
+ }
1445
+ } else {
1446
+ drawScaledDroneLayer(ctx, width, height, input.tick, input.scene);
1447
+ for (const panel of input.panels) {
1448
+ if (panel.chrome !== "ad-terminal")
1449
+ continue;
1450
+ const rect = panelRect2(input.layout, panel, { width, height });
1451
+ if (!rect)
1452
+ continue;
1453
+ const cellH = height / input.layout.height;
1454
+ const headerPx = Math.max(cellH * 3, (panel.headerHeight ?? 3) * cellH);
1455
+ compositePanel2(ctx, canvas, rect, headerPx);
1456
+ }
1457
+ }
1458
+ const png = await canvas.encode("png");
1459
+ encodedFrames += 1;
1460
+ if (encodedFrames % SKIA_CACHE_CLEAR_INTERVAL === 0)
1461
+ clearAllCache();
1462
+ return {
1463
+ key: imageVisualFrameKey(input),
1464
+ sequence: kittyPngFrameSequence(png, { columns: input.layout.width, rows: input.layout.height, imageId: input.imageId, zIndex: input.zIndex })
1465
+ };
1466
+ }
1467
+ var BG2, PANEL2, PANEL_HEADER2, PANEL_LINE2, LIME2, LIME_DIM2, CYAN2, MAGENTA2, INK_DIM2, KITTY_CHUNK_SIZE2 = 4096, MAX_IMAGE_BYTES2, SKIA_CACHE_CLEAR_INTERVAL = 240, DEFAULT_DRONE_LAYER_SCALE2 = 0.18, DEFAULT_MOTION_DENSITY = 0.42, DEFAULT_MOTION_SPEED = 0.55, TEMP_GRAPHICS_DIR, frameCanvas = null, frameCtx = null, sceneCanvas = null, sceneCtx = null, patchCanvas = null, patchCtx = null, encodedFrames = 0;
1468
+ var init_image_visual_layer_native_canvas = __esm(() => {
1469
+ init_image_visual_layer();
1470
+ BG2 = [7, 8, 9, 255];
1471
+ PANEL2 = [16, 17, 21, 184];
1472
+ PANEL_HEADER2 = [16, 17, 21, 190];
1473
+ PANEL_LINE2 = [255, 255, 255, 24];
1474
+ LIME2 = [204, 255, 77, 255];
1475
+ LIME_DIM2 = [169, 214, 63, 255];
1476
+ CYAN2 = [86, 216, 255, 255];
1477
+ MAGENTA2 = [255, 121, 176, 255];
1478
+ INK_DIM2 = [108, 110, 121, 255];
1479
+ MAX_IMAGE_BYTES2 = 48 * 1024 * 1024;
1480
+ TEMP_GRAPHICS_DIR = join(tmpdir(), "rig-tty-graphics-protocol");
1481
+ });
1482
+
1483
+ // packages/cli/src/app-opentui/render/image-visual-layer-worker.ts
1484
+ init_image_visual_layer();
1485
+ import { parentPort } from "worker_threads";
1486
+ var nativeCanvasRenderer;
1487
+ async function renderFrame(request) {
1488
+ if (process.env.RIG_OPENTUI_IMAGE_BACKEND !== "ts" && request.transport === "png") {
1489
+ if (nativeCanvasRenderer === undefined) {
1490
+ try {
1491
+ const mod = await Promise.resolve().then(() => (init_image_visual_layer_native_canvas(), exports_image_visual_layer_native_canvas));
1492
+ nativeCanvasRenderer = mod.renderNativeCanvasImageVisualFrame;
1493
+ } catch {
1494
+ nativeCanvasRenderer = null;
1495
+ }
1496
+ }
1497
+ if (nativeCanvasRenderer) {
1498
+ try {
1499
+ const native = await nativeCanvasRenderer(request);
1500
+ if (native)
1501
+ return native;
1502
+ } catch {
1503
+ nativeCanvasRenderer = null;
1504
+ }
1505
+ }
1506
+ }
1507
+ return renderImageVisualFrame(request);
1508
+ }
1509
+ function isImageVisualWorkerRequest(value) {
1510
+ if (!value || typeof value !== "object")
1511
+ return false;
1512
+ const record = value;
1513
+ return typeof record.requestId === "number" && typeof record.key === "string" && typeof record.tick === "number" && typeof record.scene === "string" && typeof record.imageId === "number" && typeof record.zIndex === "number" && (record.transport === "rgba-zlib" || record.transport === "png") && typeof record.layout === "object" && typeof record.pixelSize === "object" && Array.isArray(record.panels);
1514
+ }
1515
+ var port = parentPort;
1516
+ if (!port)
1517
+ throw new Error("image visual layer worker requires parentPort");
1518
+ port.on("message", (message) => {
1519
+ (async () => {
1520
+ try {
1521
+ if (!isImageVisualWorkerRequest(message))
1522
+ throw new Error("Invalid image visual worker request");
1523
+ const result = await renderFrame(message);
1524
+ const response = {
1525
+ requestId: message.requestId,
1526
+ key: message.key,
1527
+ sequence: result?.sequence
1528
+ };
1529
+ port.postMessage(response);
1530
+ } catch (error) {
1531
+ const requestId = isImageVisualWorkerRequest(message) ? message.requestId : -1;
1532
+ const key = isImageVisualWorkerRequest(message) ? message.key : "";
1533
+ const response = {
1534
+ requestId,
1535
+ key,
1536
+ error: error instanceof Error ? error.message : String(error)
1537
+ };
1538
+ port.postMessage(response);
1539
+ }
1540
+ })();
1541
+ });