mesurer 0.2.2 → 0.2.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -3,6 +3,9 @@ var __defProp = Object.defineProperty;
3
3
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
4
  var __getOwnPropNames = Object.getOwnPropertyNames;
5
5
  var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __esm = (fn, res) => function __init() {
7
+ return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
8
+ };
6
9
  var __export = (target, all) => {
7
10
  for (var name in all)
8
11
  __defProp(target, name, { get: all[name], enumerable: true });
@@ -17,6 +20,440 @@ var __copyProps = (to, from, except, desc) => {
17
20
  };
18
21
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
22
 
23
+ // core/screen-recording-webm.ts
24
+ function writeWebmDuration(bytes, durationSeconds) {
25
+ if (!(durationSeconds > 0)) return false;
26
+ let timecodeScale = 1e6;
27
+ let durationOffset = -1;
28
+ let durationSize = 0;
29
+ const walk = (start, end, inInfo) => {
30
+ let cursor = start;
31
+ while (cursor + 2 < end && durationOffset < 0) {
32
+ const id = readElementId(bytes, cursor);
33
+ if (!id) return;
34
+ cursor += id.length;
35
+ const size = readElementSize(bytes, cursor);
36
+ if (!size) return;
37
+ cursor += size.length;
38
+ const dataStart = cursor;
39
+ if (id.id === CLUSTER_ID) return;
40
+ if (id.id === TIMECODE_SCALE_ID && !size.unknown && size.value > 0 && size.value <= 8) {
41
+ timecodeScale = readUint(bytes, dataStart, size.value);
42
+ }
43
+ if (id.id === DURATION_ID && inInfo && !size.unknown && (size.value === 4 || size.value === 8)) {
44
+ durationOffset = dataStart;
45
+ durationSize = size.value;
46
+ return;
47
+ }
48
+ const dataEnd = size.unknown ? end : dataStart + size.value;
49
+ if (size.unknown || MASTER_IDS.has(id.id)) {
50
+ walk(dataStart, dataEnd, inInfo || id.id === INFO_ID);
51
+ if (durationOffset >= 0) return;
52
+ }
53
+ if (size.unknown) return;
54
+ cursor = dataEnd;
55
+ }
56
+ };
57
+ walk(0, bytes.length, false);
58
+ if (durationOffset < 0 || timecodeScale <= 0) return false;
59
+ const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
60
+ const current = durationSize === 8 ? view.getFloat64(durationOffset) : view.getFloat32(durationOffset);
61
+ const next = durationSeconds * (1e9 / timecodeScale);
62
+ if (Number.isFinite(current) && current >= next - 1e9 / timecodeScale * 0.05) return false;
63
+ if (durationSize === 8) view.setFloat64(durationOffset, next);
64
+ else view.setFloat32(durationOffset, next);
65
+ return true;
66
+ }
67
+ async function correctWebmDuration(blob, durationSeconds) {
68
+ if (!(durationSeconds > 0) || !blob.type.includes("webm")) return blob;
69
+ const bytes = new Uint8Array(await blob.arrayBuffer());
70
+ if (!writeWebmDuration(bytes, durationSeconds)) return blob;
71
+ return new Blob([bytes], { type: blob.type || "video/webm" });
72
+ }
73
+ var EBML_ID, SEGMENT_ID, INFO_ID, TIMECODE_SCALE_ID, DURATION_ID, CLUSTER_ID, MASTER_IDS, readElementId, readElementSize, readUint;
74
+ var init_screen_recording_webm = __esm({
75
+ "core/screen-recording-webm.ts"() {
76
+ "use strict";
77
+ EBML_ID = 440786851;
78
+ SEGMENT_ID = 408125543;
79
+ INFO_ID = 357149030;
80
+ TIMECODE_SCALE_ID = 2807729;
81
+ DURATION_ID = 17545;
82
+ CLUSTER_ID = 524531317;
83
+ MASTER_IDS = /* @__PURE__ */ new Set([EBML_ID, SEGMENT_ID, INFO_ID]);
84
+ readElementId = (bytes, offset) => {
85
+ const first = bytes[offset];
86
+ if (first === void 0 || first === 0) return null;
87
+ let length = 1;
88
+ let mask = 128;
89
+ while (length <= 4 && (first & mask) === 0) {
90
+ mask >>= 1;
91
+ length += 1;
92
+ }
93
+ if (offset + length > bytes.length) return null;
94
+ let id = 0;
95
+ for (let index = 0; index < length; index += 1) id = id * 256 + bytes[offset + index];
96
+ return { length, id };
97
+ };
98
+ readElementSize = (bytes, offset) => {
99
+ const first = bytes[offset];
100
+ if (first === void 0 || first === 0) return null;
101
+ let length = 1;
102
+ let mask = 128;
103
+ while (length <= 8 && (first & mask) === 0) {
104
+ mask >>= 1;
105
+ length += 1;
106
+ }
107
+ if (offset + length > bytes.length) return null;
108
+ const marker = mask - 1;
109
+ let unknown = (first & marker) === marker;
110
+ let value = first & marker;
111
+ for (let index = 1; index < length; index += 1) {
112
+ const byte = bytes[offset + index];
113
+ if (byte !== 255) unknown = false;
114
+ value = value * 256 + byte;
115
+ }
116
+ return { length, value, unknown };
117
+ };
118
+ readUint = (bytes, offset, size) => {
119
+ let value = 0;
120
+ for (let index = 0; index < size; index += 1) value = value * 256 + bytes[offset + index];
121
+ return value;
122
+ };
123
+ }
124
+ });
125
+
126
+ // core/screen-recording-gif.ts
127
+ var screen_recording_gif_exports = {};
128
+ __export(screen_recording_gif_exports, {
129
+ GIF_FRAME_RATE: () => GIF_FRAME_RATE,
130
+ encodeGifClip: () => encodeGifClip,
131
+ encodeGifFrames: () => encodeGifFrames,
132
+ gifFrameTimes: () => gifFrameTimes
133
+ });
134
+ function gifFrameTimes(startTime, endTime, frameRate = GIF_FRAME_RATE) {
135
+ const frameCount = Math.max(1, Math.ceil((endTime - startTime) * frameRate));
136
+ return Array.from({ length: frameCount }, (_, index) => Math.min(endTime, startTime + index / frameRate));
137
+ }
138
+ function encodeGifFrames(width, height, frames, delay = Math.max(1, Math.round(100 / GIF_FRAME_RATE))) {
139
+ const output = startGif(width, height);
140
+ for (const pixels of frames) appendFrame(output, width, height, pixels, delay);
141
+ output.push(59);
142
+ return new Uint8Array(output);
143
+ }
144
+ async function encodeGifClip(ownerDocument, sourceUrl, startTime, endTime, scale) {
145
+ const source = ownerDocument.createElement("video");
146
+ source.muted = true;
147
+ source.playsInline = true;
148
+ source.preload = "auto";
149
+ source.src = sourceUrl;
150
+ try {
151
+ await new Promise((resolve, reject) => {
152
+ const ready = () => source.videoWidth > 0 && source.videoHeight > 0 && source.readyState >= 2;
153
+ const finish = () => ready() && resolve();
154
+ source.onloadedmetadata = finish;
155
+ source.onloadeddata = finish;
156
+ source.onresize = finish;
157
+ source.onerror = () => reject(new Error("Could not export GIF"));
158
+ if (ready()) resolve();
159
+ });
160
+ const canvas = ownerDocument.createElement("canvas");
161
+ canvas.width = Math.max(1, Math.round(source.videoWidth * scale));
162
+ canvas.height = Math.max(1, Math.round(source.videoHeight * scale));
163
+ if (canvas.width > 65535 || canvas.height > 65535) throw new Error("Could not export GIF");
164
+ const context = canvas.getContext("2d", { willReadFrequently: true });
165
+ if (!context) throw new Error("Could not export GIF");
166
+ const output = startGif(canvas.width, canvas.height);
167
+ const delay = Math.max(1, Math.round(100 / GIF_FRAME_RATE));
168
+ for (const time of gifFrameTimes(startTime, endTime)) {
169
+ await seekVideoElement(source, time);
170
+ context.drawImage(source, 0, 0, canvas.width, canvas.height);
171
+ appendFrame(output, canvas.width, canvas.height, indexPixels(context.getImageData(0, 0, canvas.width, canvas.height).data), delay);
172
+ }
173
+ output.push(59);
174
+ return new Blob([new Uint8Array(output)], { type: "image/gif" });
175
+ } finally {
176
+ source.pause();
177
+ source.removeAttribute("src");
178
+ source.load();
179
+ }
180
+ }
181
+ var GIF_FRAME_RATE, createPalette, indexPixels, encodeLzw, writeWord, writeSubBlocks, startGif, appendFrame;
182
+ var init_screen_recording_gif = __esm({
183
+ "core/screen-recording-gif.ts"() {
184
+ "use strict";
185
+ init_screen_recording_export();
186
+ GIF_FRAME_RATE = 12;
187
+ createPalette = () => {
188
+ const colors = new Uint8Array(256 * 3);
189
+ for (let index = 0; index < 256; index += 1) {
190
+ const offset = index * 3;
191
+ colors[offset] = Math.round((index >> 5 & 7) * 255 / 7);
192
+ colors[offset + 1] = Math.round((index >> 2 & 7) * 255 / 7);
193
+ colors[offset + 2] = (index & 3) * 85;
194
+ }
195
+ return colors;
196
+ };
197
+ indexPixels = (rgba) => {
198
+ const indexed = new Uint8Array(rgba.length / 4);
199
+ for (let pixel = 0; pixel < indexed.length; pixel += 1) {
200
+ const offset = pixel * 4;
201
+ indexed[pixel] = rgba[offset] & 224 | (rgba[offset + 1] & 224) >> 3 | rgba[offset + 2] >> 6;
202
+ }
203
+ return indexed;
204
+ };
205
+ encodeLzw = (pixels) => {
206
+ const minimumCodeSize = 8;
207
+ const clearCode = 1 << minimumCodeSize;
208
+ const endCode = clearCode + 1;
209
+ const bytes = [];
210
+ let currentByte = 0;
211
+ let bitCount = 0;
212
+ const codeSize = minimumCodeSize + 1;
213
+ let nextCode = endCode + 1;
214
+ let dictionary = /* @__PURE__ */ new Map();
215
+ const writeCode = (code) => {
216
+ currentByte |= code << bitCount;
217
+ bitCount += codeSize;
218
+ while (bitCount >= 8) {
219
+ bytes.push(currentByte & 255);
220
+ currentByte >>= 8;
221
+ bitCount -= 8;
222
+ }
223
+ };
224
+ const reset = () => {
225
+ dictionary = /* @__PURE__ */ new Map();
226
+ nextCode = endCode + 1;
227
+ };
228
+ writeCode(clearCode);
229
+ let prefix = pixels[0] ?? 0;
230
+ for (let index = 1; index < pixels.length; index += 1) {
231
+ const value = pixels[index];
232
+ const key = prefix << 8 | value;
233
+ const existing = dictionary.get(key);
234
+ if (existing !== void 0) {
235
+ prefix = existing;
236
+ continue;
237
+ }
238
+ writeCode(prefix);
239
+ if (nextCode < 500) {
240
+ dictionary.set(key, nextCode);
241
+ nextCode += 1;
242
+ } else {
243
+ writeCode(clearCode);
244
+ reset();
245
+ }
246
+ prefix = value;
247
+ }
248
+ writeCode(prefix);
249
+ writeCode(endCode);
250
+ if (bitCount > 0) bytes.push(currentByte & 255);
251
+ return bytes;
252
+ };
253
+ writeWord = (output, value) => {
254
+ output.push(value & 255, value >> 8 & 255);
255
+ };
256
+ writeSubBlocks = (output, bytes) => {
257
+ for (let offset = 0; offset < bytes.length; offset += 255) {
258
+ const chunk = bytes.slice(offset, offset + 255);
259
+ output.push(chunk.length, ...chunk);
260
+ }
261
+ output.push(0);
262
+ };
263
+ startGif = (width, height) => {
264
+ const output = [71, 73, 70, 56, 57, 97];
265
+ writeWord(output, width);
266
+ writeWord(output, height);
267
+ output.push(247, 0, 0, ...createPalette());
268
+ output.push(33, 255, 11, 78, 69, 84, 83, 67, 65, 80, 69, 50, 46, 48, 3, 1, 0, 0, 0);
269
+ return output;
270
+ };
271
+ appendFrame = (output, width, height, pixels, delay) => {
272
+ output.push(33, 249, 4, 0);
273
+ writeWord(output, delay);
274
+ output.push(0, 0, 44);
275
+ writeWord(output, 0);
276
+ writeWord(output, 0);
277
+ writeWord(output, width);
278
+ writeWord(output, height);
279
+ output.push(0);
280
+ output.push(8);
281
+ writeSubBlocks(output, encodeLzw(pixels));
282
+ };
283
+ }
284
+ });
285
+
286
+ // core/screen-recording-export.ts
287
+ function resolveRecordingDuration(mediaDuration, elapsedSeconds) {
288
+ const media = Number.isFinite(mediaDuration) && mediaDuration > 0 ? mediaDuration : 0;
289
+ const elapsed = Number.isFinite(elapsedSeconds) && elapsedSeconds > 0 ? elapsedSeconds : 0;
290
+ if (media <= 0 && elapsed <= 0) return 0.1;
291
+ if (media <= 0) return Math.max(elapsed, 0.1);
292
+ if (elapsed <= 0) return media;
293
+ if (media < elapsed * 0.9) return elapsed;
294
+ return Math.min(media, elapsed);
295
+ }
296
+ function isFullClipExport(startTime, endTime, duration, tolerance = 0.05) {
297
+ return startTime <= tolerance && endTime >= duration - tolerance;
298
+ }
299
+ async function readBlobVideoDuration(blob, ownerDocument) {
300
+ const url = URL.createObjectURL(blob);
301
+ const video = ownerDocument.createElement("video");
302
+ video.preload = "metadata";
303
+ video.muted = true;
304
+ try {
305
+ return await new Promise((resolve, reject) => {
306
+ video.onloadedmetadata = () => {
307
+ resolve(video.duration);
308
+ };
309
+ video.onerror = () => reject(new Error("Could not read recording"));
310
+ video.src = url;
311
+ });
312
+ } finally {
313
+ URL.revokeObjectURL(url);
314
+ video.removeAttribute("src");
315
+ }
316
+ }
317
+ async function seekVideoElement(video, time) {
318
+ const target = Math.max(0, time);
319
+ if (target <= 0 && video.readyState >= 1) {
320
+ video.currentTime = 0;
321
+ return;
322
+ }
323
+ await new Promise((resolve, reject) => {
324
+ const onSeeked = () => resolve();
325
+ const onError = () => reject(new Error("Could not seek recording"));
326
+ video.addEventListener("seeked", onSeeked, { once: true });
327
+ video.addEventListener("error", onError, { once: true });
328
+ if (video.readyState < 1) {
329
+ video.addEventListener(
330
+ "loadedmetadata",
331
+ () => {
332
+ video.currentTime = target;
333
+ },
334
+ { once: true }
335
+ );
336
+ } else {
337
+ video.currentTime = target;
338
+ }
339
+ });
340
+ }
341
+ async function requestDisplayMediaStream(ownerWindow) {
342
+ const fallback = {
343
+ audio: false,
344
+ video: true
345
+ };
346
+ const chromium = {
347
+ audio: false,
348
+ video: { displaySurface: "browser" },
349
+ preferCurrentTab: true,
350
+ selfBrowserSurface: "include"
351
+ };
352
+ try {
353
+ return await ownerWindow.navigator.mediaDevices.getDisplayMedia(chromium);
354
+ } catch (error) {
355
+ if (error instanceof DOMException && error.name === "AbortError") throw error;
356
+ return await ownerWindow.navigator.mediaDevices.getDisplayMedia(fallback);
357
+ }
358
+ }
359
+ async function reencodeVideoClip(ownerDocument, ownerWindow, sourceUrl, startTime, endTime, scale, mimeType) {
360
+ const source = ownerDocument.createElement("video");
361
+ source.muted = true;
362
+ source.playsInline = true;
363
+ source.src = sourceUrl;
364
+ source.preload = "auto";
365
+ await new Promise((resolve, reject) => {
366
+ const ready = () => source.videoWidth > 0 && source.videoHeight > 0;
367
+ const finish = () => {
368
+ if (!ready()) return;
369
+ resolve();
370
+ };
371
+ source.onloadedmetadata = finish;
372
+ source.onloadeddata = finish;
373
+ source.onresize = finish;
374
+ source.onerror = () => reject(new Error("Could not trim recording"));
375
+ if (ready()) resolve();
376
+ });
377
+ await seekVideoElement(source, startTime);
378
+ if (source.videoWidth <= 0 || source.videoHeight <= 0) {
379
+ await new Promise((resolve) => {
380
+ if (typeof source.requestVideoFrameCallback === "function") {
381
+ source.requestVideoFrameCallback(() => resolve());
382
+ return;
383
+ }
384
+ ownerWindow.requestAnimationFrame(() => resolve());
385
+ });
386
+ }
387
+ const canvas = ownerDocument.createElement("canvas");
388
+ canvas.width = Math.max(1, Math.round(source.videoWidth * scale));
389
+ canvas.height = Math.max(1, Math.round(source.videoHeight * scale));
390
+ const context = canvas.getContext("2d");
391
+ if (!context) throw new Error("Could not trim recording");
392
+ const stream = canvas.captureStream(30);
393
+ const captureTrack = stream.getVideoTracks()[0];
394
+ const requestFrame = captureTrack && "requestFrame" in captureTrack ? captureTrack.requestFrame : void 0;
395
+ const recorder = new MediaRecorder(stream, mimeType ? { mimeType } : void 0);
396
+ const chunks = [];
397
+ return await new Promise((resolve, reject) => {
398
+ let stopped = false;
399
+ const onTimeUpdate = () => {
400
+ if (source.currentTime >= endTime) finish();
401
+ };
402
+ const finish = () => {
403
+ if (stopped) return;
404
+ stopped = true;
405
+ source.removeEventListener("timeupdate", onTimeUpdate);
406
+ source.pause();
407
+ try {
408
+ recorder.stop();
409
+ } catch {
410
+ reject(new Error("Could not trim recording"));
411
+ }
412
+ };
413
+ const drawFrame = () => {
414
+ if (stopped) return;
415
+ context.drawImage(source, 0, 0, canvas.width, canvas.height);
416
+ requestFrame?.call(captureTrack);
417
+ if (source.currentTime >= endTime || source.ended) {
418
+ finish();
419
+ return;
420
+ }
421
+ if (typeof source.requestVideoFrameCallback === "function") {
422
+ source.requestVideoFrameCallback(() => drawFrame());
423
+ } else {
424
+ ownerWindow.requestAnimationFrame(drawFrame);
425
+ }
426
+ };
427
+ recorder.ondataavailable = (event) => {
428
+ if (event.data.size > 0) chunks.push(event.data);
429
+ };
430
+ recorder.onstop = () => {
431
+ const recorded = new Blob(chunks, { type: recorder.mimeType || mimeType || "video/webm" });
432
+ void correctWebmDuration(recorded, Math.max(0.1, endTime - startTime)).then(resolve, reject);
433
+ };
434
+ recorder.onerror = () => reject(new Error("Could not trim recording"));
435
+ source.addEventListener("timeupdate", onTimeUpdate);
436
+ recorder.start(100);
437
+ void source.play().then(
438
+ () => drawFrame(),
439
+ () => {
440
+ source.removeEventListener("timeupdate", onTimeUpdate);
441
+ reject(new Error("Could not trim recording"));
442
+ }
443
+ );
444
+ });
445
+ }
446
+ async function encodeGifClip2(ownerDocument, sourceUrl, startTime, endTime, scale) {
447
+ const encoder = await Promise.resolve().then(() => (init_screen_recording_gif(), screen_recording_gif_exports));
448
+ return encoder.encodeGifClip(ownerDocument, sourceUrl, startTime, endTime, scale);
449
+ }
450
+ var init_screen_recording_export = __esm({
451
+ "core/screen-recording-export.ts"() {
452
+ "use strict";
453
+ init_screen_recording_webm();
454
+ }
455
+ });
456
+
20
457
  // index.ts
21
458
  var index_exports = {};
22
459
  __export(index_exports, {
@@ -82,7 +519,7 @@ function ensureMesurerStyles(cssText, target) {
82
519
  }
83
520
 
84
521
  // styles.generated.ts
85
- var MESURER_STYLES = '/*! tailwindcss v4.2.2 | MIT License | https://tailwindcss.com */\n@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-translate-x:0;--tw-translate-y:0;--tw-translate-z:0;--tw-border-style:solid;--tw-leading:initial;--tw-font-weight:initial;--tw-ordinal:initial;--tw-slashed-zero:initial;--tw-numeric-figure:initial;--tw-numeric-spacing:initial;--tw-numeric-fraction:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-outline-style:solid;--tw-duration:initial;--tw-ease:initial}}}@layer theme{:root,:host{--msr-font-sans:ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";--msr-font-mono:ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;--msr-color-red-50:oklch(97.1% .013 17.38);--msr-color-red-200:oklch(88.5% .062 18.334);--msr-color-red-600:oklch(57.7% .245 27.325);--msr-color-red-700:oklch(50.5% .213 27.518);--msr-color-black:#000;--msr-color-white:#fff;--msr-spacing:.25rem;--msr-text-xs:.75rem;--msr-text-xs--line-height:calc(1 / .75);--msr-text-sm:.875rem;--msr-text-sm--line-height:calc(1.25 / .875);--msr-font-weight-normal:400;--msr-font-weight-medium:500;--msr-font-weight-semibold:600;--msr-radius-sm:.25rem;--msr-radius-md:.375rem;--msr-radius-lg:.5rem;--msr-radius-xl:.75rem;--msr-ease-out:cubic-bezier(0, 0, .2, 1);--msr-animate-pulse:pulse 2s cubic-bezier(.4, 0, .6, 1) infinite;--msr-aspect-video:16 / 9;--msr-default-transition-duration:.15s;--msr-default-transition-timing-function:cubic-bezier(.4, 0, .2, 1);--msr-default-font-family:var(--msr-font-sans);--msr-default-mono-font-family:var(--msr-font-mono);--msr-radius-control:5px;--msr-radius-wide-card:13px;--msr-shadow-toolbar:drop-shadow(0 0 .4px #00000038) drop-shadow(0 6px 18px #00000008) drop-shadow(0 3px 9px #0000000f) drop-shadow(0 1px 1px #0000000f);--msr-shadow-floating:0 0 0 .4px #00000038, 0 6px 18px #00000008, 0 3px 9px #0000000f, 0 1px 1px #0000000f;--msr-color-ink-50:#f8fafc;--msr-color-ink-100:#f1f5f9;--msr-color-ink-200:#e2e8f0;--msr-color-ink-300:#cbd5e1;--msr-color-ink-500:#64748b;--msr-color-ink-700:#334155;--msr-color-ink-900:#18181b}}@layer base{.mesurer-root{font-family:var(--msr-font-sans);font-size:12px;line-height:1.5}.mesurer-root button,.mesurer-root input,.mesurer-root select,.mesurer-root textarea{font-family:inherit;font-size:inherit;line-height:inherit}.mesurer-root input[type=search]::-webkit-search-cancel-button{appearance:none;display:none}.mesurer-root input[type=search]::-webkit-search-decoration{appearance:none;display:none}.mesurer-root input[type=search]::-moz-search-clear{appearance:none;display:none}.mesurer-root input[type=search]::-ms-clear{appearance:none;display:none}:where(.mesurer-root,.mesurer-root *){--tw-border-style:solid;--tw-outline-style:solid;--tw-shadow:0 0 #0000;--tw-inset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-offset-shadow:0 0 #0000;--tw-translate-x:0;--tw-translate-y:0;--tw-translate-z:0;border:0 solid}.mesurer-root button,.mesurer-root input,.mesurer-root select,.mesurer-root textarea{appearance:none;font:inherit;color:inherit;letter-spacing:inherit;background-color:#0000;padding:0}}@layer components;@layer utilities{.msr\\:pointer-events-auto{pointer-events:auto}.msr\\:pointer-events-none{pointer-events:none}.msr\\:absolute{position:absolute}.msr\\:fixed{position:fixed}.msr\\:relative{position:relative}.msr\\:inset-0{inset:calc(var(--msr-spacing) * 0)}.msr\\:inset-x-0{inset-inline:calc(var(--msr-spacing) * 0)}.msr\\:inset-y-0{inset-block:calc(var(--msr-spacing) * 0)}.msr\\:top-0{top:calc(var(--msr-spacing) * 0)}.msr\\:top-0\\.5{top:calc(var(--msr-spacing) * .5)}.msr\\:top-1\\.5{top:calc(var(--msr-spacing) * 1.5)}.msr\\:top-1\\/2{top:50%}.msr\\:top-1\\/3{top:33.3333%}.msr\\:top-2\\/3{top:66.6667%}.msr\\:top-9{top:calc(var(--msr-spacing) * 9)}.msr\\:top-\\[18px\\]{top:18px}.msr\\:top-full{top:100%}.msr\\:right-0{right:calc(var(--msr-spacing) * 0)}.msr\\:right-1{right:calc(var(--msr-spacing) * 1)}.msr\\:right-1\\.5{right:calc(var(--msr-spacing) * 1.5)}.msr\\:right-2{right:calc(var(--msr-spacing) * 2)}.msr\\:right-\\[8px\\]{right:8px}.msr\\:bottom-0{bottom:calc(var(--msr-spacing) * 0)}.msr\\:bottom-1\\.5{bottom:calc(var(--msr-spacing) * 1.5)}.msr\\:bottom-4{bottom:calc(var(--msr-spacing) * 4)}.msr\\:bottom-full{bottom:100%}.msr\\:left-0{left:calc(var(--msr-spacing) * 0)}.msr\\:left-1\\.5{left:calc(var(--msr-spacing) * 1.5)}.msr\\:left-1\\/2{left:50%}.msr\\:left-1\\/3{left:33.3333%}.msr\\:left-2\\/3{left:66.6667%}.msr\\:left-\\[8px\\]{left:8px}.msr\\:left-\\[18px\\]{left:18px}.msr\\:left-full{left:100%}.msr\\:z-10{z-index:10}.msr\\:z-20{z-index:20}.msr\\:z-30{z-index:30}.msr\\:z-40{z-index:40}.msr\\:z-50{z-index:50}.msr\\:z-80{z-index:80}.msr\\:z-100{z-index:100}.msr\\:z-\\[1\\]{z-index:1}.msr\\:z-\\[2\\]{z-index:2}.msr\\:z-\\[25\\]{z-index:25}.msr\\:z-\\[60\\]{z-index:60}.msr\\:z-\\[70\\]{z-index:70}.msr\\:z-\\[71\\]{z-index:71}.msr\\:z-\\[80\\]{z-index:80}.msr\\:z-\\[85\\]{z-index:85}.msr\\:z-\\[90\\]{z-index:90}.msr\\:z-\\[95\\]{z-index:95}.msr\\:z-\\[100\\]{z-index:100}.msr\\:z-\\[101\\]{z-index:101}.msr\\:col-span-2{grid-column:span 2/span 2}.msr\\:m-0{margin:calc(var(--msr-spacing) * 0)}.msr\\:mx-auto{margin-inline:auto}.msr\\:my-1{margin-block:calc(var(--msr-spacing) * 1)}.msr\\:mt-0\\.5{margin-top:calc(var(--msr-spacing) * .5)}.msr\\:mt-1{margin-top:calc(var(--msr-spacing) * 1)}.msr\\:mt-2{margin-top:calc(var(--msr-spacing) * 2)}.msr\\:mt-3{margin-top:calc(var(--msr-spacing) * 3)}.msr\\:mt-4{margin-top:calc(var(--msr-spacing) * 4)}.msr\\:mb-1{margin-bottom:calc(var(--msr-spacing) * 1)}.msr\\:mb-2{margin-bottom:calc(var(--msr-spacing) * 2)}.msr\\:-ml-1{margin-left:calc(var(--msr-spacing) * -1)}.msr\\:ml-1{margin-left:calc(var(--msr-spacing) * 1)}.msr\\:ml-auto{margin-left:auto}.msr\\:box-border{box-sizing:border-box}.msr\\:line-clamp-2{-webkit-line-clamp:2;-webkit-box-orient:vertical;display:-webkit-box;overflow:hidden}.msr\\:block{display:block}.msr\\:flex{display:flex}.msr\\:grid{display:grid}.msr\\:inline-flex{display:inline-flex}.msr\\:size-1\\.5{width:calc(var(--msr-spacing) * 1.5);height:calc(var(--msr-spacing) * 1.5)}.msr\\:size-2{width:calc(var(--msr-spacing) * 2);height:calc(var(--msr-spacing) * 2)}.msr\\:size-3{width:calc(var(--msr-spacing) * 3);height:calc(var(--msr-spacing) * 3)}.msr\\:size-4{width:calc(var(--msr-spacing) * 4);height:calc(var(--msr-spacing) * 4)}.msr\\:size-5{width:calc(var(--msr-spacing) * 5);height:calc(var(--msr-spacing) * 5)}.msr\\:size-6{width:calc(var(--msr-spacing) * 6);height:calc(var(--msr-spacing) * 6)}.msr\\:size-7{width:calc(var(--msr-spacing) * 7);height:calc(var(--msr-spacing) * 7)}.msr\\:size-8{width:calc(var(--msr-spacing) * 8);height:calc(var(--msr-spacing) * 8)}.msr\\:size-\\[10px\\]{width:10px;height:10px}.msr\\:size-\\[18px\\]{width:18px;height:18px}.msr\\:size-full{width:100%;height:100%}.msr\\:h-0{height:calc(var(--msr-spacing) * 0)}.msr\\:h-1\\.5{height:calc(var(--msr-spacing) * 1.5)}.msr\\:h-2{height:calc(var(--msr-spacing) * 2)}.msr\\:h-2\\.5{height:calc(var(--msr-spacing) * 2.5)}.msr\\:h-3{height:calc(var(--msr-spacing) * 3)}.msr\\:h-5{height:calc(var(--msr-spacing) * 5)}.msr\\:h-6{height:calc(var(--msr-spacing) * 6)}.msr\\:h-7{height:calc(var(--msr-spacing) * 7)}.msr\\:h-8{height:calc(var(--msr-spacing) * 8)}.msr\\:h-\\[3px\\]{height:3px}.msr\\:h-\\[14px\\]{height:14px}.msr\\:h-auto{height:auto}.msr\\:h-full{height:100%}.msr\\:h-max{height:max-content}.msr\\:h-px{height:1px}.msr\\:max-h-32{max-height:calc(var(--msr-spacing) * 32)}.msr\\:max-h-36{max-height:calc(var(--msr-spacing) * 36)}.msr\\:max-h-48{max-height:calc(var(--msr-spacing) * 48)}.msr\\:max-h-\\[28rem\\]{max-height:28rem}.msr\\:max-h-\\[120px\\]{max-height:120px}.msr\\:max-h-full{max-height:100%}.msr\\:min-h-0{min-height:calc(var(--msr-spacing) * 0)}.msr\\:min-h-6{min-height:calc(var(--msr-spacing) * 6)}.msr\\:min-h-8{min-height:calc(var(--msr-spacing) * 8)}.msr\\:min-h-\\[4\\.5rem\\]{min-height:4.5rem}.msr\\:w-0{width:calc(var(--msr-spacing) * 0)}.msr\\:w-0\\.5{width:calc(var(--msr-spacing) * .5)}.msr\\:w-4{width:calc(var(--msr-spacing) * 4)}.msr\\:w-5{width:calc(var(--msr-spacing) * 5)}.msr\\:w-6{width:calc(var(--msr-spacing) * 6)}.msr\\:w-8{width:calc(var(--msr-spacing) * 8)}.msr\\:w-9{width:calc(var(--msr-spacing) * 9)}.msr\\:w-12{width:calc(var(--msr-spacing) * 12)}.msr\\:w-32{width:calc(var(--msr-spacing) * 32)}.msr\\:w-40{width:calc(var(--msr-spacing) * 40)}.msr\\:w-44{width:calc(var(--msr-spacing) * 44)}.msr\\:w-48{width:calc(var(--msr-spacing) * 48)}.msr\\:w-52{width:calc(var(--msr-spacing) * 52)}.msr\\:w-60{width:calc(var(--msr-spacing) * 60)}.msr\\:w-64{width:calc(var(--msr-spacing) * 64)}.msr\\:w-72{width:calc(var(--msr-spacing) * 72)}.msr\\:w-\\[18px\\]{width:18px}.msr\\:w-\\[22rem\\]{width:22rem}.msr\\:w-\\[26px\\]{width:26px}.msr\\:w-\\[36rem\\]{width:36rem}.msr\\:w-\\[220px\\]{width:220px}.msr\\:w-auto{width:auto}.msr\\:w-full{width:100%}.msr\\:w-max{width:max-content}.msr\\:w-px{width:1px}.msr\\:max-w-\\[180px\\]{max-width:180px}.msr\\:max-w-\\[calc\\(100vw-16px\\)\\]{max-width:calc(100vw - 16px)}.msr\\:max-w-\\[calc\\(100vw-24px\\)\\]{max-width:calc(100vw - 24px)}.msr\\:max-w-\\[min\\(100vw-16px\\,15rem\\)\\]{max-width:min(100vw - 16px,15rem)}.msr\\:max-w-\\[min\\(200px\\,calc\\(100vw-24px\\)\\)\\]{max-width:min(200px,100vw - 24px)}.msr\\:max-w-\\[min\\(240px\\,calc\\(100vw-16px\\)\\)\\]{max-width:min(240px,100vw - 16px)}.msr\\:max-w-full{max-width:100%}.msr\\:min-w-0{min-width:calc(var(--msr-spacing) * 0)}.msr\\:min-w-32{min-width:calc(var(--msr-spacing) * 32)}.msr\\:min-w-36{min-width:calc(var(--msr-spacing) * 36)}.msr\\:min-w-44{min-width:calc(var(--msr-spacing) * 44)}.msr\\:flex-1{flex:1}.msr\\:flex-none{flex:none}.msr\\:shrink-0{flex-shrink:0}.msr\\:-translate-x-1\\/2{--tw-translate-x:calc(calc(1 / 2 * 100%) * -1);translate:var(--tw-translate-x) var(--tw-translate-y)}.msr\\:-translate-y-1\\/2{--tw-translate-y:calc(calc(1 / 2 * 100%) * -1);translate:var(--tw-translate-x) var(--tw-translate-y)}.msr\\:-translate-y-full{--tw-translate-y:-100%;translate:var(--tw-translate-x) var(--tw-translate-y)}.msr\\:-rotate-90{rotate:-90deg}.msr\\:rotate-45{rotate:45deg}.msr\\:rotate-90{rotate:90deg}.msr\\:animate-\\[mesurer-screenshot-preview_5\\.16s_ease-out_both\\]{animation:5.16s ease-out both mesurer-screenshot-preview}.msr\\:cursor-crosshair{cursor:crosshair}.msr\\:cursor-default{cursor:default}.msr\\:cursor-ew-resize{cursor:ew-resize}.msr\\:cursor-move{cursor:move}.msr\\:cursor-nesw-resize{cursor:nesw-resize}.msr\\:cursor-ns-resize{cursor:ns-resize}.msr\\:cursor-nwse-resize{cursor:nwse-resize}.msr\\:cursor-pointer{cursor:pointer}.msr\\:cursor-text{cursor:text}.msr\\:touch-none{touch-action:none}.msr\\:resize-none{resize:none}.msr\\:list-none{list-style-type:none}.msr\\:appearance-none{appearance:none}.msr\\:grid-cols-\\[44px_minmax\\(0\\,1fr\\)\\]{grid-template-columns:44px minmax(0,1fr)}.msr\\:grid-cols-\\[56px_minmax\\(0\\,1fr\\)\\]{grid-template-columns:56px minmax(0,1fr)}.msr\\:grid-cols-\\[78px_150px\\]{grid-template-columns:78px 150px}.msr\\:grid-cols-\\[78px_minmax\\(0\\,1fr\\)\\]{grid-template-columns:78px minmax(0,1fr)}.msr\\:flex-col{flex-direction:column}.msr\\:items-baseline{align-items:baseline}.msr\\:items-center{align-items:center}.msr\\:items-start{align-items:flex-start}.msr\\:items-stretch{align-items:stretch}.msr\\:justify-between{justify-content:space-between}.msr\\:justify-center{justify-content:center}.msr\\:justify-end{justify-content:flex-end}.msr\\:gap-0{gap:calc(var(--msr-spacing) * 0)}.msr\\:gap-0\\.5{gap:calc(var(--msr-spacing) * .5)}.msr\\:gap-1{gap:calc(var(--msr-spacing) * 1)}.msr\\:gap-1\\.5{gap:calc(var(--msr-spacing) * 1.5)}.msr\\:gap-2{gap:calc(var(--msr-spacing) * 2)}.msr\\:gap-\\[2px\\]{gap:2px}.msr\\:gap-px{gap:1px}.msr\\:self-center{align-self:center}.msr\\:justify-self-end{justify-self:flex-end}.msr\\:truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.msr\\:overflow-hidden{overflow:hidden}.msr\\:overflow-visible{overflow:visible}.msr\\:overflow-y-auto{overflow-y:auto}.msr\\:rounded{border-radius:.25rem}.msr\\:rounded-\\[2px\\]{border-radius:2px}.msr\\:rounded-\\[3px\\]{border-radius:3px}.msr\\:rounded-\\[4px\\]{border-radius:4px}.msr\\:rounded-\\[10px\\]{border-radius:10px}.msr\\:rounded-full{border-radius:3.40282e38px}.msr\\:rounded-lg{border-radius:var(--msr-radius-lg)}.msr\\:rounded-md{border-radius:var(--msr-radius-md)}.msr\\:rounded-none{border-radius:0}.msr\\:border{border-style:var(--tw-border-style);border-width:1px}.msr\\:border-0{border-style:var(--tw-border-style);border-width:0}.msr\\:border-2{border-style:var(--tw-border-style);border-width:2px}.msr\\:border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.msr\\:border-t-2{border-top-style:var(--tw-border-style);border-top-width:2px}.msr\\:border-r{border-right-style:var(--tw-border-style);border-right-width:1px}.msr\\:border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.msr\\:border-l{border-left-style:var(--tw-border-style);border-left-width:1px}.msr\\:border-dashed{--tw-border-style:dashed;border-style:dashed}.msr\\:border-dotted{--tw-border-style:dotted;border-style:dotted}.msr\\:border-solid{--tw-border-style:solid;border-style:solid}.msr\\:border-\\[\\#0d99ff\\]{border-color:#0d99ff}.msr\\:border-\\[\\#2563eb\\]\\/70{border-color:oklab(54.615% -.026671 -.213549/.7)}.msr\\:border-\\[var\\(--msr-danger-border\\)\\]{border-color:var(--msr-danger-border)}.msr\\:border-black\\/10{border-color:var(--msr-color-black)}@supports (color:color-mix(in lab, red, red)){.msr\\:border-black\\/10{border-color:color-mix(in oklab, var(--msr-color-black) 10%, transparent)}}.msr\\:border-ink-100{border-color:var(--msr-color-ink-100)}.msr\\:border-ink-200{border-color:var(--msr-color-ink-200)}.msr\\:border-ink-300{border-color:var(--msr-color-ink-300)}.msr\\:border-ink-500,.msr\\:border-ink-500\\/30{border-color:var(--msr-color-ink-500)}@supports (color:color-mix(in lab, red, red)){.msr\\:border-ink-500\\/30{border-color:color-mix(in oklab, var(--msr-color-ink-500) 30%, transparent)}}.msr\\:border-ink-700{border-color:var(--msr-color-ink-700)}.msr\\:border-transparent{border-color:#0000}.msr\\:border-white{border-color:var(--msr-color-white)}.msr\\:\\!bg-black\\/50{background-color:var(--msr-color-black)!important}@supports (color:color-mix(in lab, red, red)){.msr\\:\\!bg-black\\/50{background-color:color-mix(in oklab, var(--msr-color-black) 50%, transparent)!important}}.msr\\:bg-\\[\\#0d99ff\\]{background-color:#0d99ff}.msr\\:bg-\\[\\#0d99ff\\]\\/8{background-color:oklab(66.9841% -.0648249 -.170866/.08)}.msr\\:bg-\\[\\#0d99ff\\]\\/10{background-color:oklab(66.9841% -.0648249 -.170866/.1)}.msr\\:bg-\\[\\#2563eb\\]{background-color:#2563eb}.msr\\:bg-\\[var\\(--msr-danger-solid-bg\\)\\]{background-color:var(--msr-danger-solid-bg)}.msr\\:bg-black,.msr\\:bg-black\\/4{background-color:var(--msr-color-black)}@supports (color:color-mix(in lab, red, red)){.msr\\:bg-black\\/4{background-color:color-mix(in oklab, var(--msr-color-black) 4%, transparent)}}.msr\\:bg-black\\/40{background-color:var(--msr-color-black)}@supports (color:color-mix(in lab, red, red)){.msr\\:bg-black\\/40{background-color:color-mix(in oklab, var(--msr-color-black) 40%, transparent)}}.msr\\:bg-ink-50{background-color:var(--msr-color-ink-50)}.msr\\:bg-ink-100{background-color:var(--msr-color-ink-100)}.msr\\:bg-ink-200{background-color:var(--msr-color-ink-200)}.msr\\:bg-ink-300{background-color:var(--msr-color-ink-300)}.msr\\:bg-ink-500\\/50{background-color:var(--msr-color-ink-500)}@supports (color:color-mix(in lab, red, red)){.msr\\:bg-ink-500\\/50{background-color:color-mix(in oklab, var(--msr-color-ink-500) 50%, transparent)}}.msr\\:bg-ink-900,.msr\\:bg-ink-900\\/45{background-color:var(--msr-color-ink-900)}@supports (color:color-mix(in lab, red, red)){.msr\\:bg-ink-900\\/45{background-color:color-mix(in oklab, var(--msr-color-ink-900) 45%, transparent)}}.msr\\:bg-ink-900\\/90{background-color:var(--msr-color-ink-900)}@supports (color:color-mix(in lab, red, red)){.msr\\:bg-ink-900\\/90{background-color:color-mix(in oklab, var(--msr-color-ink-900) 90%, transparent)}}.msr\\:bg-transparent{background-color:#0000}.msr\\:bg-white,.msr\\:bg-white\\/5{background-color:var(--msr-color-white)}@supports (color:color-mix(in lab, red, red)){.msr\\:bg-white\\/5{background-color:color-mix(in oklab, var(--msr-color-white) 5%, transparent)}}.msr\\:object-contain{object-fit:contain}.msr\\:p-0{padding:calc(var(--msr-spacing) * 0)}.msr\\:p-1{padding:calc(var(--msr-spacing) * 1)}.msr\\:p-2{padding:calc(var(--msr-spacing) * 2)}.msr\\:p-3{padding:calc(var(--msr-spacing) * 3)}.msr\\:p-\\[2px\\]{padding:2px}.msr\\:p-px{padding:1px}.msr\\:px-0{padding-inline:calc(var(--msr-spacing) * 0)}.msr\\:px-0\\.5{padding-inline:calc(var(--msr-spacing) * .5)}.msr\\:px-1{padding-inline:calc(var(--msr-spacing) * 1)}.msr\\:px-1\\.5{padding-inline:calc(var(--msr-spacing) * 1.5)}.msr\\:px-2{padding-inline:calc(var(--msr-spacing) * 2)}.msr\\:px-3{padding-inline:calc(var(--msr-spacing) * 3)}.msr\\:py-0\\.5{padding-block:calc(var(--msr-spacing) * .5)}.msr\\:py-1{padding-block:calc(var(--msr-spacing) * 1)}.msr\\:py-1\\.5{padding-block:calc(var(--msr-spacing) * 1.5)}.msr\\:py-2{padding-block:calc(var(--msr-spacing) * 2)}.msr\\:py-6{padding-block:calc(var(--msr-spacing) * 6)}.msr\\:pt-1\\.5{padding-top:calc(var(--msr-spacing) * 1.5)}.msr\\:pt-8{padding-top:calc(var(--msr-spacing) * 8)}.msr\\:pr-1\\.5{padding-right:calc(var(--msr-spacing) * 1.5)}.msr\\:pr-2{padding-right:calc(var(--msr-spacing) * 2)}.msr\\:pr-6{padding-right:calc(var(--msr-spacing) * 6)}.msr\\:pb-1{padding-bottom:calc(var(--msr-spacing) * 1)}.msr\\:pb-2{padding-bottom:calc(var(--msr-spacing) * 2)}.msr\\:pl-1{padding-left:calc(var(--msr-spacing) * 1)}.msr\\:pl-1\\.5{padding-left:calc(var(--msr-spacing) * 1.5)}.msr\\:pl-3{padding-left:calc(var(--msr-spacing) * 3)}.msr\\:pl-6{padding-left:calc(var(--msr-spacing) * 6)}.msr\\:text-center{text-align:center}.msr\\:text-left{text-align:left}.msr\\:text-right{text-align:right}.msr\\:font-mono{font-family:var(--msr-font-mono)}.msr\\:text-\\[9px\\]{font-size:9px}.msr\\:text-\\[10px\\]{font-size:10px}.msr\\:text-\\[11px\\]{font-size:11px}.msr\\:text-\\[12px\\]{font-size:12px}.msr\\:text-\\[13px\\]{font-size:13px}.msr\\:text-\\[16px\\]{font-size:16px}.msr\\:leading-4{--tw-leading:calc(var(--msr-spacing) * 4);line-height:calc(var(--msr-spacing) * 4)}.msr\\:leading-5{--tw-leading:calc(var(--msr-spacing) * 5);line-height:calc(var(--msr-spacing) * 5)}.msr\\:leading-6{--tw-leading:calc(var(--msr-spacing) * 6);line-height:calc(var(--msr-spacing) * 6)}.msr\\:leading-none{--tw-leading:1;line-height:1}.msr\\:font-medium{--tw-font-weight:var(--msr-font-weight-medium);font-weight:var(--msr-font-weight-medium)}.msr\\:font-normal{--tw-font-weight:var(--msr-font-weight-normal);font-weight:var(--msr-font-weight-normal)}.msr\\:font-semibold{--tw-font-weight:var(--msr-font-weight-semibold);font-weight:var(--msr-font-weight-semibold)}.msr\\:text-pretty{text-wrap:pretty}.msr\\:break-words{overflow-wrap:break-word}.msr\\:whitespace-normal{white-space:normal}.msr\\:whitespace-nowrap{white-space:nowrap}.msr\\:whitespace-pre{white-space:pre}.msr\\:whitespace-pre-wrap{white-space:pre-wrap}.msr\\:text-\\[\\#64748b\\]{color:#64748b}.msr\\:text-\\[var\\(--msr-danger-solid-text\\)\\]{color:var(--msr-danger-solid-text)}.msr\\:text-\\[var\\(--msr-danger-text\\)\\]{color:var(--msr-danger-text)}.msr\\:text-ink-50{color:var(--msr-color-ink-50)}.msr\\:text-ink-500{color:var(--msr-color-ink-500)}.msr\\:text-ink-700{color:var(--msr-color-ink-700)}.msr\\:text-ink-900{color:var(--msr-color-ink-900)}.msr\\:text-red-600{color:var(--msr-color-red-600)}.msr\\:text-white,.msr\\:text-white\\/60{color:var(--msr-color-white)}@supports (color:color-mix(in lab, red, red)){.msr\\:text-white\\/60{color:color-mix(in oklab, var(--msr-color-white) 60%, transparent)}}.msr\\:tabular-nums{--tw-numeric-spacing:tabular-nums;font-variant-numeric:var(--tw-ordinal,) var(--tw-slashed-zero,) var(--tw-numeric-figure,) var(--tw-numeric-spacing,) var(--tw-numeric-fraction,)}.msr\\:underline-offset-2{text-underline-offset:2px}.msr\\:caret-\\[\\#0d99ff\\]{caret-color:#0d99ff}.msr\\:opacity-0{opacity:0}.msr\\:opacity-100{opacity:1}.msr\\:shadow-\\[0_0_0_1px_rgba\\(0\\,0\\,0\\,0\\.25\\)\\]{--tw-shadow:0 0 0 1px var(--tw-shadow-color,#00000040);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.msr\\:shadow-\\[0_1px_2px_rgb\\(0_0_0_\\/_0\\.06\\)\\]{--tw-shadow:0 1px 2px var(--tw-shadow-color,#0000000f);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.msr\\:shadow-floating{--tw-shadow:0 0 0 .4px var(--tw-shadow-color,#00000038), 0 6px 18px var(--tw-shadow-color,#00000008), 0 3px 9px var(--tw-shadow-color,#0000000f), 0 1px 1px var(--tw-shadow-color,#0000000f);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.msr\\:outline,.msr\\:outline-1{outline-style:var(--tw-outline-style);outline-width:1px}.msr\\:outline-\\[\\#0d99ff\\]{outline-color:#0d99ff}.msr\\:transition-\\[height\\]{transition-property:height;transition-timing-function:var(--tw-ease,var(--msr-default-transition-timing-function));transition-duration:var(--tw-duration,var(--msr-default-transition-duration))}.msr\\:transition-\\[left\\]{transition-property:left;transition-timing-function:var(--tw-ease,var(--msr-default-transition-timing-function));transition-duration:var(--tw-duration,var(--msr-default-transition-duration))}.msr\\:transition-\\[max-height\\]{transition-property:max-height;transition-timing-function:var(--tw-ease,var(--msr-default-transition-timing-function));transition-duration:var(--tw-duration,var(--msr-default-transition-duration))}.msr\\:transition-\\[width\\]{transition-property:width;transition-timing-function:var(--tw-ease,var(--msr-default-transition-timing-function));transition-duration:var(--tw-duration,var(--msr-default-transition-duration))}.msr\\:transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--msr-default-transition-timing-function));transition-duration:var(--tw-duration,var(--msr-default-transition-duration))}.msr\\:transition-opacity{transition-property:opacity;transition-timing-function:var(--tw-ease,var(--msr-default-transition-timing-function));transition-duration:var(--tw-duration,var(--msr-default-transition-duration))}.msr\\:transition-shadow{transition-property:box-shadow;transition-timing-function:var(--tw-ease,var(--msr-default-transition-timing-function));transition-duration:var(--tw-duration,var(--msr-default-transition-duration))}.msr\\:transition-transform{transition-property:transform,translate,scale,rotate;transition-timing-function:var(--tw-ease,var(--msr-default-transition-timing-function));transition-duration:var(--tw-duration,var(--msr-default-transition-duration))}.msr\\:transition-none{transition-property:none}.msr\\:duration-150{--tw-duration:.15s;transition-duration:.15s}.msr\\:duration-200{--tw-duration:.2s;transition-duration:.2s}.msr\\:duration-300{--tw-duration:.3s;transition-duration:.3s}.msr\\:ease-\\[cubic-bezier\\(0\\.22\\,1\\,0\\.36\\,1\\)\\]{--tw-ease:cubic-bezier(.22,1,.36,1);transition-timing-function:cubic-bezier(.22,1,.36,1)}.msr\\:ease-\\[ease\\]{--tw-ease:ease;transition-timing-function:ease}.msr\\:will-change-transform{will-change:transform}.msr\\:outline-none{--tw-outline-style:none;outline-style:none}.msr\\:select-none{-webkit-user-select:none;user-select:none}.msr\\:select-text{-webkit-user-select:text;user-select:text}@media (hover:hover){.msr\\:group-hover\\:h-3:is(:where(.msr\\:group):hover *){height:calc(var(--msr-spacing) * 3)}.msr\\:group-hover\\:opacity-100:is(:where(.msr\\:group):hover *){opacity:1}.msr\\:group-hover\\/video\\:pointer-events-auto:is(:where(.msr\\:group\\/video):hover *){pointer-events:auto}.msr\\:group-hover\\/video\\:opacity-100:is(:where(.msr\\:group\\/video):hover *){opacity:1}}.msr\\:group-focus-visible\\:h-3:is(:where(.msr\\:group):focus-visible *){height:calc(var(--msr-spacing) * 3)}.msr\\:focus-within\\:pointer-events-auto:focus-within{pointer-events:auto}.msr\\:focus-within\\:relative:focus-within{position:relative}.msr\\:focus-within\\:z-\\[1\\]:focus-within{z-index:1}.msr\\:focus-within\\:rounded-l-\\[5px\\]:focus-within{border-top-left-radius:5px;border-bottom-left-radius:5px}.msr\\:focus-within\\:rounded-r-\\[5px\\]:focus-within{border-top-right-radius:5px;border-bottom-right-radius:5px}.msr\\:focus-within\\:border-\\[\\#0d99ff\\]:focus-within{border-color:#0d99ff}.msr\\:focus-within\\:opacity-100:focus-within{opacity:1}.msr\\:focus-within\\:shadow-\\[0_0_0_1px_\\#0d99ff\\]:focus-within{--tw-shadow:0 0 0 1px var(--tw-shadow-color,#0d99ff);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}@media (hover:hover){.msr\\:hover\\:border-ink-200:hover{border-color:var(--msr-color-ink-200)}.msr\\:hover\\:\\!bg-black\\/60:hover{background-color:var(--msr-color-black)!important}@supports (color:color-mix(in lab, red, red)){.msr\\:hover\\:\\!bg-black\\/60:hover{background-color:color-mix(in oklab, var(--msr-color-black) 60%, transparent)!important}}.msr\\:hover\\:bg-\\[\\#0d99ff\\]:hover{background-color:#0d99ff}.msr\\:hover\\:bg-\\[\\#087dcc\\]:hover{background-color:#087dcc}.msr\\:hover\\:bg-\\[var\\(--msr-danger-bg\\)\\]:hover{background-color:var(--msr-danger-bg)}.msr\\:hover\\:bg-\\[var\\(--msr-danger-solid-hover\\)\\]:hover{background-color:var(--msr-danger-solid-hover)}.msr\\:hover\\:bg-black\\/4:hover{background-color:var(--msr-color-black)}@supports (color:color-mix(in lab, red, red)){.msr\\:hover\\:bg-black\\/4:hover{background-color:color-mix(in oklab, var(--msr-color-black) 4%, transparent)}}.msr\\:hover\\:bg-ink-50:hover{background-color:var(--msr-color-ink-50)}.msr\\:hover\\:bg-ink-100:hover{background-color:var(--msr-color-ink-100)}.msr\\:hover\\:bg-ink-200:hover,.msr\\:hover\\:bg-ink-200\\/50:hover{background-color:var(--msr-color-ink-200)}@supports (color:color-mix(in lab, red, red)){.msr\\:hover\\:bg-ink-200\\/50:hover{background-color:color-mix(in oklab, var(--msr-color-ink-200) 50%, transparent)}}.msr\\:hover\\:bg-red-50:hover{background-color:var(--msr-color-red-50)}.msr\\:hover\\:bg-transparent:hover{background-color:#0000}.msr\\:hover\\:text-ink-700:hover{color:var(--msr-color-ink-700)}.msr\\:hover\\:text-ink-900:hover{color:var(--msr-color-ink-900)}.msr\\:hover\\:text-white:hover{color:var(--msr-color-white)}.msr\\:hover\\:underline:hover{text-decoration-line:underline}.msr\\:hover\\:focus-within\\:border-\\[\\#0d99ff\\]:hover:focus-within{border-color:#0d99ff}}.msr\\:focus\\:border-\\[\\#0d99ff\\]:focus{border-color:#0d99ff}.msr\\:focus\\:shadow-\\[inset_0_0_0_1px_\\#0d99ff\\]:focus{--tw-shadow:inset 0 0 0 1px var(--tw-shadow-color,#0d99ff);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.msr\\:focus\\:shadow-\\[inset_0_0_0_1px_var\\(--msr-accent\\)\\]:focus{--tw-shadow:inset 0 0 0 1px var(--tw-shadow-color,var(--msr-accent));box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.msr\\:focus\\:outline-none:focus{--tw-outline-style:none;outline-style:none}.msr\\:focus-visible\\:bg-ink-100:focus-visible{background-color:var(--msr-color-ink-100)}.msr\\:focus-visible\\:opacity-100:focus-visible{opacity:1}.msr\\:focus-visible\\:shadow-\\[inset_0_0_0_1px_var\\(--color-ink-700\\)\\]:focus-visible{--tw-shadow:inset 0 0 0 1px var(--tw-shadow-color,var(--color-ink-700));box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.msr\\:focus-visible\\:shadow-\\[inset_0_0_0_1px_var\\(--msr-accent\\)\\]:focus-visible{--tw-shadow:inset 0 0 0 1px var(--tw-shadow-color,var(--msr-accent));box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.msr\\:focus-visible\\:shadow-\\[inset_0_0_0_1px_var\\(--msr-danger-text\\)\\]:focus-visible{--tw-shadow:inset 0 0 0 1px var(--tw-shadow-color,var(--msr-danger-text));box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.msr\\:focus-visible\\:ring-1:focus-visible{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.msr\\:focus-visible\\:ring-2:focus-visible{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.msr\\:focus-visible\\:ring-\\[var\\(--msr-accent\\)\\]\\/25:focus-visible{--tw-ring-color:var(--msr-accent)}@supports (color:color-mix(in lab, red, red)){.msr\\:focus-visible\\:ring-\\[var\\(--msr-accent\\)\\]\\/25:focus-visible{--tw-ring-color:color-mix(in oklab, var(--msr-accent) 25%, transparent)}}.msr\\:focus-visible\\:outline:focus-visible,.msr\\:focus-visible\\:outline-1:focus-visible{outline-style:var(--tw-outline-style);outline-width:1px}.msr\\:focus-visible\\:outline-offset-1:focus-visible{outline-offset:1px}.msr\\:focus-visible\\:outline-ink-500:focus-visible{outline-color:var(--msr-color-ink-500)}.msr\\:focus-visible\\:outline-none:focus-visible{--tw-outline-style:none;outline-style:none}.msr\\:focus-visible\\:ring-inset:focus-visible{--tw-ring-inset:inset}.msr\\:disabled\\:cursor-default:disabled{cursor:default}.msr\\:disabled\\:cursor-not-allowed:disabled{cursor:not-allowed}.msr\\:disabled\\:opacity-40:disabled{opacity:.4}@media (prefers-reduced-motion:reduce){.msr\\:motion-reduce\\:transition-none{transition-property:none}}.msr\\:rounded-control{border-radius:var(--msr-radius-control)}.msr\\:rounded-wide-card{border-radius:var(--msr-radius-wide-card)}}:root,:host{--color-ink-50:#f8fafc;--color-ink-100:#f1f5f9;--color-ink-200:#e2e8f0;--color-ink-300:#cbd5e1;--color-ink-500:#64748b;--color-ink-700:#334155;--color-ink-900:#18181b}:host{all:initial;color-scheme:light dark;color:var(--msr-color-ink-900);letter-spacing:normal;--msr-spacing:4px;direction:ltr;font-family:ui-sans-serif,system-ui,sans-serif;font-size:16px;font-weight:400;line-height:1.5;display:block}.mesurer-root{--msr-accent:#0d99ff;--msr-surface:#fff;--msr-surface-raised:#fff;--msr-surface-muted:var(--msr-color-ink-50);--msr-content:var(--msr-color-ink-900);--msr-color-white:#fff;--msr-color-black:#000;--msr-danger-bg:#fef2f2;--msr-danger-border:#fecaca;--msr-danger-text:#dc2626;--msr-danger-solid-bg:#dc2626;--msr-danger-solid-hover:#b91c1c;--msr-danger-solid-text:#fff;--msr-control-thumb:#fff;--msr-slider-track:#0f172a29;--msr-shadow-toolbar:drop-shadow(0 0 .4px #00000038) drop-shadow(0 6px 18px #00000008) drop-shadow(0 3px 9px #0000000f) drop-shadow(0 1px 1px #0000000f);--msr-shadow-floating:0 0 0 .4px #00000038, 0 6px 18px #00000008, 0 3px 9px #0000000f, 0 1px 1px #0000000f;--msr-shadow-select-menu:var(--msr-shadow-floating);--msr-comment-menu-surface:var(--msr-surface-raised);--msr-shadow-comment-menu:var(--msr-shadow-select-menu);color:var(--msr-content);color-scheme:light}.mesurer-root [class~=msr\\:bg-white]{background-color:var(--msr-surface)!important}.mesurer-root [class~="msr:bg-[#0d99ff]"],.mesurer-root [class~="msr:hover:bg-[#0d99ff]"]:hover{background-color:var(--msr-accent)!important}.mesurer-root [class~="msr:border-[#0d99ff]"]{border-color:var(--msr-accent)!important}.mesurer-root [class~="msr:bg-[#0d99ff]/8"]{background-color:var(--msr-accent)!important}@supports (color:color-mix(in lab, red, red)){.mesurer-root [class~="msr:bg-[#0d99ff]/8"]{background-color:color-mix(in srgb, var(--msr-accent) 8%, transparent)!important}}.mesurer-root [class~=msr\\:text-black]{color:var(--msr-content)!important}.mesurer-root .mesurer-control-thumb{background-color:var(--msr-control-thumb)!important}.mesurer-root button{-webkit-user-select:none;user-select:none;cursor:default!important}.mesurer-root .mesurer-settings-button-ghost{opacity:.7}.mesurer-root .mesurer-settings-button-ghost:hover,.mesurer-root .mesurer-settings-button-ghost:focus-visible{opacity:1}.mesurer-root [data-mesurer-recording-timeline] .mesurer-recording-track-rail{background-color:var(--msr-color-ink-200)}.mesurer-root [data-mesurer-recording-timeline] .mesurer-recording-track-clip{background-color:var(--msr-color-ink-300)}.mesurer-root [data-mesurer-recording-timeline] .mesurer-recording-playhead,.mesurer-root [data-mesurer-recording-timeline] .mesurer-recording-trim-bar{background-color:var(--msr-color-ink-900)}.mesurer-root .mesurer-switch-thumb[data-checked=false]{background-color:var(--msr-color-ink-200)!important}.mesurer-root [class~="msr:hover:bg-black/4"]:hover,.mesurer-root [class~="msr:hover:bg-black/5"]:hover{background-color:var(--msr-content)!important}@supports (color:color-mix(in lab, red, red)){.mesurer-root [class~="msr:hover:bg-black/4"]:hover,.mesurer-root [class~="msr:hover:bg-black/5"]:hover{background-color:color-mix(in srgb, var(--msr-content) 6%, transparent)!important}}.mesurer-root .mesurer-menu-surface,.mesurer-root .mesurer-color-picker,.mesurer-root .mesurer-comment-card,.mesurer-root .mesurer-comment-hover-card,.mesurer-root .mesurer-comment-delete-confirmation{color:var(--msr-content);background-color:var(--msr-surface-raised)!important}.mesurer-root .mesurer-section-divider{background-color:var(--msr-color-ink-200)!important}.mesurer-root .mesurer-settings-select-menu{box-shadow:var(--msr-shadow-select-menu)}.mesurer-root .mesurer-comment-overflow-menu,.mesurer-root .mesurer-comment-delete-confirmation{box-shadow:var(--msr-shadow-comment-menu);background-color:var(--msr-comment-menu-surface)!important}.mesurer-root .mesurer-comment-menu-item:hover{background-color:var(--msr-color-ink-200)!important}.mesurer-root .mesurer-comment-menu-danger{color:var(--msr-danger-text)!important}.mesurer-root .mesurer-comment-menu-danger:hover{background-color:var(--msr-danger-bg)!important}.mesurer-root .mesurer-settings-button-default{background-color:#0000}.mesurer-root .mesurer-settings-button-default:hover{background-color:var(--msr-color-ink-50)}.mesurer-root[data-theme=dark] .mesurer-control-shell{background-color:var(--msr-color-ink-100)}.mesurer-root[data-theme=dark] .mesurer-settings-panel select,.mesurer-root[data-theme=dark] .mesurer-settings-select,.mesurer-root[data-theme=dark] .mesurer-settings-select-menu{background-color:var(--msr-surface-raised)!important;border-color:var(--msr-color-ink-200)!important}.mesurer-root[data-theme=dark] .mesurer-settings-button-default:hover{background-color:var(--msr-surface)!important}@media (prefers-color-scheme:dark){.mesurer-root[data-theme=system] .mesurer-control-shell{background-color:var(--msr-color-ink-100)}.mesurer-root[data-theme=system] .mesurer-settings-panel select,.mesurer-root[data-theme=system] .mesurer-settings-select,.mesurer-root[data-theme=system] .mesurer-settings-select-menu{background-color:var(--msr-surface-raised)!important;border-color:var(--msr-color-ink-200)!important}.mesurer-root[data-theme=system] .mesurer-settings-button-default:hover{background-color:var(--msr-surface)!important}}.mesurer-root[data-theme=dark] .mesurer-switch-track[data-checked=false]{background-color:var(--msr-color-ink-100)!important}@media (prefers-color-scheme:dark){.mesurer-root[data-theme=system] .mesurer-switch-track[data-checked=false]{background-color:var(--msr-color-ink-100)!important}}.mesurer-root .mesurer-settings-panel .mesurer-control-focus :is(input,select):focus{box-shadow:none!important;outline:none!important}.mesurer-root[data-theme=dark]{--msr-accent:#0c8ce9;--msr-color-red-50:#3f2020;--msr-color-red-200:#7f3f46;--msr-color-red-600:#f87171;--msr-color-red-700:#fca5a5;--msr-danger-bg:#3f2020;--msr-danger-border:#7f3f46;--msr-danger-text:#f87171;--msr-danger-solid-bg:#c95058;--msr-danger-solid-hover:#b7424b;--msr-danger-solid-text:#f5f5f5;--msr-color-ink-50:#3a3a3a;--msr-color-ink-100:#414141;--msr-color-ink-200:#4a4a4a;--msr-color-ink-300:#5a5a5a;--msr-color-ink-500:#a0a0a0;--msr-color-ink-700:#dedede;--msr-color-ink-900:#f5f5f5;--msr-surface:#323232;--msr-surface-raised:#3a3a3a;--msr-surface-muted:#3a3a3a;--msr-color-white:#f5f5f5;--msr-color-black:#171717;--msr-control-thumb:#f4f4f5;--msr-slider-track:#f5f5f53d;--msr-shadow-toolbar:drop-shadow(0 0 .4px lch(100% 0 0/.1)) drop-shadow(0 3px 8px lch(0% 0 0/.125)) drop-shadow(0 2px 5px lch(0% 0 0/.125)) drop-shadow(0 1px 1px lch(0% 0 0/.125));--msr-shadow-floating:0 0 0 .4px lch(100% 0 0/.05), 0 4px 12px lch(0% 0 0/.12), 0 1px 3px lch(0% 0 0/.1);--msr-shadow-select-menu:0 0 0 .4px lch(100% 0 0/.14), 0 4px 12px lch(0% 0 0/.22), 0 1px 3px lch(0% 0 0/.18);--msr-comment-menu-surface:#323232;--msr-shadow-comment-menu:0 0 0 .5px lch(100% 0 0/.16), 0 5px 14px lch(0% 0 0/.26), 0 1px 3px lch(0% 0 0/.18);color-scheme:dark}@media (prefers-color-scheme:dark){.mesurer-root[data-theme=system]{--msr-accent:#0c8ce9;--msr-color-red-50:#3f2020;--msr-color-red-200:#7f3f46;--msr-color-red-600:#f87171;--msr-color-red-700:#fca5a5;--msr-danger-bg:#3f2020;--msr-danger-border:#7f3f46;--msr-danger-text:#f87171;--msr-danger-solid-bg:#c95058;--msr-danger-solid-hover:#b7424b;--msr-danger-solid-text:#f5f5f5;--msr-color-ink-50:#3a3a3a;--msr-color-ink-100:#414141;--msr-color-ink-200:#4a4a4a;--msr-color-ink-300:#5a5a5a;--msr-color-ink-500:#a0a0a0;--msr-color-ink-700:#dedede;--msr-color-ink-900:#f5f5f5;--msr-surface:#323232;--msr-surface-raised:#3a3a3a;--msr-surface-muted:#3a3a3a;--msr-color-white:#f5f5f5;--msr-color-black:#171717;--msr-control-thumb:#f4f4f5;--msr-slider-track:#f5f5f53d;--msr-shadow-toolbar:drop-shadow(0 0 .4px lch(100% 0 0/.1)) drop-shadow(0 3px 8px lch(0% 0 0/.125)) drop-shadow(0 2px 5px lch(0% 0 0/.125)) drop-shadow(0 1px 1px lch(0% 0 0/.125));--msr-shadow-floating:0 0 0 .4px lch(100% 0 0/.05), 0 4px 12px lch(0% 0 0/.12), 0 1px 3px lch(0% 0 0/.1);--msr-shadow-select-menu:0 0 0 .4px lch(100% 0 0/.14), 0 4px 12px lch(0% 0 0/.22), 0 1px 3px lch(0% 0 0/.18);--msr-comment-menu-surface:#323232;--msr-shadow-comment-menu:0 0 0 .5px lch(100% 0 0/.16), 0 5px 14px lch(0% 0 0/.26), 0 1px 3px lch(0% 0 0/.18);color-scheme:dark}}.mesurer-color-picker,.mesurer-color-picker *,.mesurer-root [data-mesurer-inspect-info-card],.mesurer-root [data-mesurer-inspect-info-card] *,[data-mesurer-overlay][data-mesurer-inspect],[data-mesurer-overlay][data-mesurer-inspect] *{cursor:default!important}.mesurer-root button[data-mesurer-resize-cursor],.mesurer-root button[data-mesurer-resize-cursor] *,[data-mesurer-overlay][data-mesurer-inspect] [data-mesurer-resize-cursor],[data-mesurer-overlay][data-mesurer-inspect] [data-mesurer-resize-cursor] *{cursor:var(--msr-resize-cursor)!important}html[data-mesurer-resize-cursor],html[data-mesurer-resize-cursor] *,html[data-mesurer-resize-cursor] [data-mesurer-overlay][data-mesurer-inspect],html[data-mesurer-resize-cursor] [data-mesurer-overlay][data-mesurer-inspect] *,.mesurer-root[data-mesurer-resize-cursor],.mesurer-root[data-mesurer-resize-cursor] *{cursor:var(--msr-resize-cursor-lock)!important}.mesurer-root,.mesurer-root *,.mesurer-root :before,.mesurer-root :after{box-sizing:border-box}.mesurer-toolbar-motion{--msr-toolbar-motion:.2s ease;z-index:0;isolation:isolate;width:max-content;max-width:100%;display:block;position:relative}.mesurer-layout-guides,.mesurer-layout-guides-layer,.mesurer-layout-guides-grid{pointer-events:none;position:absolute;inset:0}.mesurer-layout-guides{z-index:2;overflow:hidden}.mesurer-toolbar-chrome{z-index:0;background:var(--msr-surface);width:100%;filter:var(--msr-shadow-toolbar);transform-origin:0;pointer-events:none;border-radius:9px;position:absolute;inset:0 auto 0 0;overflow:visible}.mesurer-toolbar-clip{z-index:1;isolation:isolate;transform-origin:0;position:relative;overflow:visible}.mesurer-toolbar-motion[data-resizing=collapse] .mesurer-toolbar-clip{overflow:hidden}.mesurer-toolbar-motion[data-resizing] .mesurer-toolbar-tooltips{visibility:hidden!important}.mesurer-toolbar-surface{transform-origin:0;padding:0;position:relative}.mesurer-toolbar-divider{background:var(--msr-color-ink-200);flex:none;align-self:stretch;width:1px;margin:0}.mesurer-toolbar-minimize-stage{min-width:0;width:var(--msr-expanded-w,auto);flex:none;overflow:visible}.mesurer-toolbar-minimize-stage[data-minimized=true]{width:var(--msr-icon-w,auto);overflow:hidden}.mesurer-toolbar-motion[data-resizing=collapse] .mesurer-toolbar-minimize-stage{overflow:hidden}.mesurer-toolbar-minimize-stage[data-minimized=true] .mesurer-toolbar-minimize-track{transform:translateX(calc(-1 * var(--msr-expanded-w,0px)))}.mesurer-toolbar-minimize-stage:has([role=dialog]),.mesurer-toolbar-minimize-stage:has([role=menu]),.mesurer-toolbar-minimize-stage:has(.mesurer-screenshot-preview){overflow:visible}.mesurer-toolbar-minimize-track{pointer-events:none;flex:none;display:flex;transform:translate(0)}.mesurer-toolbar-minimize-slot{flex:none}.mesurer-toolbar-minimize-slot[data-slot=expanded]{width:var(--msr-expanded-w,auto)}.mesurer-toolbar-minimize-slot[data-slot=icon]{width:auto}.mesurer-toolbar-minimize-slot:not([data-open=true]){pointer-events:none}.mesurer-toolbar-minimize-slot[data-open=true]{pointer-events:auto}.mesurer-toolbar-motion:not([data-resizing=collapse]) .mesurer-toolbar-minimize-slot[data-slot=icon]:not([data-open=true]){visibility:hidden}.mesurer-toolbar-restore svg{transform:translate(-.5px,.5px)}.mesurer-toolbar-tool-stage{min-width:0;width:var(--msr-inspect-w,auto);flex:none;overflow:hidden}.mesurer-toolbar-tool-stage[data-group=annotate]{width:var(--msr-annotate-w,auto)}.mesurer-toolbar-tool-stage[data-group=annotate] .mesurer-toolbar-tool-track{transform:translateX(calc(-1 * var(--msr-inspect-w,0px)))}.mesurer-toolbar-tool-stage:has([role=menu]),.mesurer-toolbar-tool-stage:has([role=dialog]){overflow:visible}.mesurer-toolbar-motion[data-resizing=true] .mesurer-toolbar-tool-stage{overflow:hidden}.mesurer-toolbar-tool-track{flex:none;display:flex;transform:translate(0)}.mesurer-toolbar-motion[data-ready=true] .mesurer-toolbar-tool-switch-pill{transition:transform var(--msr-toolbar-motion)}.mesurer-toolbar-tool-slot{flex:none}.mesurer-toolbar-tool-slot[data-group=inspect]{width:var(--msr-inspect-w,auto)}.mesurer-toolbar-tool-slot[data-group=annotate]{width:var(--msr-annotate-w,auto)}.mesurer-toolbar-tool-slot:not([data-open=true]){pointer-events:none}.mesurer-toolbar-motion:not([data-resizing]) .mesurer-toolbar-tool-slot:not([data-open=true]){visibility:hidden}.mesurer-toolbar-tool-panel{width:max-content}.mesurer-toolbar-tooltips{z-index:110;pointer-events:none;position:fixed;inset:0;overflow:visible}.mesurer-toolbar-trailing{z-index:1;isolation:isolate;background:var(--msr-surface);border-radius:0 9px 9px 0;flex:none;position:relative}.mesurer-toolbar-tool-switch{z-index:1;isolation:isolate;background:var(--msr-surface);position:relative}.mesurer-toolbar-tool-switch-pill{z-index:0;background:var(--msr-color-ink-200);border-radius:3px;width:28px;height:28px;position:absolute;top:2px;left:2px;transform:translate(0)}.mesurer-toolbar-tool-switch[data-value=annotate] .mesurer-toolbar-tool-switch-pill{transform:translate(30px)}.mesurer-toolbar-tool-switch>:not(.mesurer-toolbar-tool-switch-pill){z-index:1;position:relative}@media (prefers-reduced-motion:reduce){.mesurer-toolbar-motion,.mesurer-toolbar-chrome,.mesurer-toolbar-tool-track,.mesurer-toolbar-minimize-track,.mesurer-toolbar-trailing,.mesurer-toolbar-motion[data-ready=true] .mesurer-toolbar-tool-switch-pill{transition:none}.mesurer-screenshot-preview{animation-name:mesurer-screenshot-preview-reduced;animation-duration:5s;animation-timing-function:linear;animation-fill-mode:both}}@keyframes mesurer-screenshot-preview{0%,3.1%{opacity:0}6.2%,96.9%{opacity:1}to{opacity:0}}@keyframes mesurer-screenshot-preview-reduced{0%,to{opacity:1}}@keyframes mesurer-comment-nudge{0%,to{transform:translate(0)}35%{transform:translate(-3px)}70%{transform:translate(3px)}}.mesurer-comment-nudge{animation:.15s ease-out mesurer-comment-nudge}@keyframes mesurer-status-ellipsis{0%,32%{content:"."}33%,65%{content:".."}66%,to{content:"..."}}.mesurer-status-ellipsis{text-align:left;width:1.5em;display:inline-block}.mesurer-status-ellipsis:after{content:"...";animation:1.2s step-end infinite mesurer-status-ellipsis}@media (prefers-reduced-motion:reduce){.mesurer-status-ellipsis:after{content:"...";animation:none}}.mesurer-thin-scrollbar{scrollbar-width:thin;scrollbar-color:var(--msr-color-ink-200) transparent}.mesurer-thin-scrollbar::-webkit-scrollbar{width:4px;height:4px}.mesurer-thin-scrollbar::-webkit-scrollbar-track{background:0 0}.mesurer-thin-scrollbar::-webkit-scrollbar-thumb{background:var(--msr-color-ink-200);border-radius:var(--msr-radius-control)}.mesurer-thin-scrollbar:hover{scrollbar-color:var(--msr-color-ink-300) transparent}.mesurer-thin-scrollbar:hover::-webkit-scrollbar-thumb{background:var(--msr-color-ink-300)}.mesurer-thin-scrollbar::-webkit-scrollbar-corner{background:0 0}.mesurer-toast-surface{box-shadow:var(--msr-shadow-floating)}.mesurer-root{--msr-spacing:4px}@property --tw-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-y{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-z{syntax:"*";inherits:false;initial-value:0}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-leading{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-ordinal{syntax:"*";inherits:false}@property --tw-slashed-zero{syntax:"*";inherits:false}@property --tw-numeric-figure{syntax:"*";inherits:false}@property --tw-numeric-spacing{syntax:"*";inherits:false}@property --tw-numeric-fraction{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"<length>";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-outline-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-duration{syntax:"*";inherits:false}@property --tw-ease{syntax:"*";inherits:false}@keyframes pulse{50%{opacity:.5}}';
522
+ var MESURER_STYLES = '/*! tailwindcss v4.2.2 | MIT License | https://tailwindcss.com */\n@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-translate-x:0;--tw-translate-y:0;--tw-translate-z:0;--tw-border-style:solid;--tw-leading:initial;--tw-font-weight:initial;--tw-ordinal:initial;--tw-slashed-zero:initial;--tw-numeric-figure:initial;--tw-numeric-spacing:initial;--tw-numeric-fraction:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-outline-style:solid;--tw-blur:initial;--tw-brightness:initial;--tw-contrast:initial;--tw-grayscale:initial;--tw-hue-rotate:initial;--tw-invert:initial;--tw-opacity:initial;--tw-saturate:initial;--tw-sepia:initial;--tw-drop-shadow:initial;--tw-drop-shadow-color:initial;--tw-drop-shadow-alpha:100%;--tw-drop-shadow-size:initial;--tw-duration:initial;--tw-ease:initial}}}@layer theme{:root,:host{--msr-font-sans:ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";--msr-font-mono:ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;--msr-color-red-50:oklch(97.1% .013 17.38);--msr-color-red-200:oklch(88.5% .062 18.334);--msr-color-red-600:oklch(57.7% .245 27.325);--msr-color-red-700:oklch(50.5% .213 27.518);--msr-color-black:#000;--msr-color-white:#fff;--msr-spacing:.25rem;--msr-text-xs:.75rem;--msr-text-xs--line-height:calc(1 / .75);--msr-text-sm:.875rem;--msr-text-sm--line-height:calc(1.25 / .875);--msr-font-weight-normal:400;--msr-font-weight-medium:500;--msr-font-weight-semibold:600;--msr-radius-sm:.25rem;--msr-radius-md:.375rem;--msr-radius-lg:.5rem;--msr-radius-xl:.75rem;--msr-ease-out:cubic-bezier(0, 0, .2, 1);--msr-animate-pulse:pulse 2s cubic-bezier(.4, 0, .6, 1) infinite;--msr-aspect-video:16 / 9;--msr-default-transition-duration:.15s;--msr-default-transition-timing-function:cubic-bezier(.4, 0, .2, 1);--msr-default-font-family:var(--msr-font-sans);--msr-default-mono-font-family:var(--msr-font-mono);--msr-radius-control:5px;--msr-radius-wide-card:13px;--msr-shadow-toolbar:drop-shadow(0 0 .4px #00000038) drop-shadow(0 6px 18px #00000008) drop-shadow(0 3px 9px #0000000f) drop-shadow(0 1px 1px #0000000f);--msr-shadow-floating:0 0 .4px #00000038, 0 6px 18px #00000008, 0 3px 9px #0000000f, 0 1px 1px #0000000f;--msr-color-ink-50:#f8fafc;--msr-color-ink-100:#f1f5f9;--msr-color-ink-200:#e2e8f0;--msr-color-ink-300:#cbd5e1;--msr-color-ink-500:#64748b;--msr-color-ink-700:#334155;--msr-color-ink-900:#18181b}}@layer base{.mesurer-root{font-family:var(--msr-font-sans);font-size:12px;line-height:1.5}.mesurer-root button,.mesurer-root input,.mesurer-root select,.mesurer-root textarea{font-family:inherit;font-size:inherit;line-height:inherit}.mesurer-root input[type=search]::-webkit-search-cancel-button{appearance:none;display:none}.mesurer-root input[type=search]::-webkit-search-decoration{appearance:none;display:none}.mesurer-root input[type=search]::-moz-search-clear{appearance:none;display:none}.mesurer-root input[type=search]::-ms-clear{appearance:none;display:none}:where(.mesurer-root,.mesurer-root *){--tw-border-style:solid;--tw-outline-style:solid;--tw-shadow:0 0 #0000;--tw-inset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-offset-shadow:0 0 #0000;--tw-translate-x:0;--tw-translate-y:0;--tw-translate-z:0;border:0 solid}.mesurer-root button,.mesurer-root input,.mesurer-root select,.mesurer-root textarea{appearance:none;font:inherit;color:inherit;letter-spacing:inherit;background-color:#0000;padding:0}}@layer components;@layer utilities{.msr\\:pointer-events-auto{pointer-events:auto}.msr\\:pointer-events-none{pointer-events:none}.msr\\:absolute{position:absolute}.msr\\:fixed{position:fixed}.msr\\:relative{position:relative}.msr\\:inset-0{inset:calc(var(--msr-spacing) * 0)}.msr\\:inset-x-0{inset-inline:calc(var(--msr-spacing) * 0)}.msr\\:inset-y-0{inset-block:calc(var(--msr-spacing) * 0)}.msr\\:top-0{top:calc(var(--msr-spacing) * 0)}.msr\\:top-0\\.5{top:calc(var(--msr-spacing) * .5)}.msr\\:top-1\\.5{top:calc(var(--msr-spacing) * 1.5)}.msr\\:top-1\\/2{top:50%}.msr\\:top-1\\/3{top:33.3333%}.msr\\:top-2\\/3{top:66.6667%}.msr\\:top-9{top:calc(var(--msr-spacing) * 9)}.msr\\:top-\\[18px\\]{top:18px}.msr\\:top-full{top:100%}.msr\\:right-0{right:calc(var(--msr-spacing) * 0)}.msr\\:right-1{right:calc(var(--msr-spacing) * 1)}.msr\\:right-1\\.5{right:calc(var(--msr-spacing) * 1.5)}.msr\\:right-2{right:calc(var(--msr-spacing) * 2)}.msr\\:right-\\[8px\\]{right:8px}.msr\\:bottom-0{bottom:calc(var(--msr-spacing) * 0)}.msr\\:bottom-1\\.5{bottom:calc(var(--msr-spacing) * 1.5)}.msr\\:bottom-4{bottom:calc(var(--msr-spacing) * 4)}.msr\\:bottom-full{bottom:100%}.msr\\:left-0{left:calc(var(--msr-spacing) * 0)}.msr\\:left-1\\.5{left:calc(var(--msr-spacing) * 1.5)}.msr\\:left-1\\/2{left:50%}.msr\\:left-1\\/3{left:33.3333%}.msr\\:left-2\\/3{left:66.6667%}.msr\\:left-\\[8px\\]{left:8px}.msr\\:left-\\[18px\\]{left:18px}.msr\\:left-full{left:100%}.msr\\:z-10{z-index:10}.msr\\:z-20{z-index:20}.msr\\:z-30{z-index:30}.msr\\:z-40{z-index:40}.msr\\:z-50{z-index:50}.msr\\:z-80{z-index:80}.msr\\:z-100{z-index:100}.msr\\:z-\\[1\\]{z-index:1}.msr\\:z-\\[2\\]{z-index:2}.msr\\:z-\\[25\\]{z-index:25}.msr\\:z-\\[60\\]{z-index:60}.msr\\:z-\\[70\\]{z-index:70}.msr\\:z-\\[71\\]{z-index:71}.msr\\:z-\\[80\\]{z-index:80}.msr\\:z-\\[85\\]{z-index:85}.msr\\:z-\\[90\\]{z-index:90}.msr\\:z-\\[100\\]{z-index:100}.msr\\:z-\\[101\\]{z-index:101}.msr\\:z-\\[120\\]{z-index:120}.msr\\:col-span-2{grid-column:span 2/span 2}.msr\\:m-0{margin:calc(var(--msr-spacing) * 0)}.msr\\:mx-auto{margin-inline:auto}.msr\\:my-1{margin-block:calc(var(--msr-spacing) * 1)}.msr\\:mt-0\\.5{margin-top:calc(var(--msr-spacing) * .5)}.msr\\:mt-1{margin-top:calc(var(--msr-spacing) * 1)}.msr\\:mt-2{margin-top:calc(var(--msr-spacing) * 2)}.msr\\:mt-3{margin-top:calc(var(--msr-spacing) * 3)}.msr\\:mt-4{margin-top:calc(var(--msr-spacing) * 4)}.msr\\:mb-1{margin-bottom:calc(var(--msr-spacing) * 1)}.msr\\:mb-2{margin-bottom:calc(var(--msr-spacing) * 2)}.msr\\:-ml-1{margin-left:calc(var(--msr-spacing) * -1)}.msr\\:ml-1{margin-left:calc(var(--msr-spacing) * 1)}.msr\\:ml-auto{margin-left:auto}.msr\\:box-border{box-sizing:border-box}.msr\\:line-clamp-2{-webkit-line-clamp:2;-webkit-box-orient:vertical;display:-webkit-box;overflow:hidden}.msr\\:block{display:block}.msr\\:flex{display:flex}.msr\\:grid{display:grid}.msr\\:inline-flex{display:inline-flex}.msr\\:size-1\\.5{width:calc(var(--msr-spacing) * 1.5);height:calc(var(--msr-spacing) * 1.5)}.msr\\:size-2{width:calc(var(--msr-spacing) * 2);height:calc(var(--msr-spacing) * 2)}.msr\\:size-3{width:calc(var(--msr-spacing) * 3);height:calc(var(--msr-spacing) * 3)}.msr\\:size-4{width:calc(var(--msr-spacing) * 4);height:calc(var(--msr-spacing) * 4)}.msr\\:size-5{width:calc(var(--msr-spacing) * 5);height:calc(var(--msr-spacing) * 5)}.msr\\:size-6{width:calc(var(--msr-spacing) * 6);height:calc(var(--msr-spacing) * 6)}.msr\\:size-7{width:calc(var(--msr-spacing) * 7);height:calc(var(--msr-spacing) * 7)}.msr\\:size-8{width:calc(var(--msr-spacing) * 8);height:calc(var(--msr-spacing) * 8)}.msr\\:size-\\[10px\\]{width:10px;height:10px}.msr\\:size-\\[18px\\]{width:18px;height:18px}.msr\\:size-full{width:100%;height:100%}.msr\\:h-0{height:calc(var(--msr-spacing) * 0)}.msr\\:h-1\\.5{height:calc(var(--msr-spacing) * 1.5)}.msr\\:h-2{height:calc(var(--msr-spacing) * 2)}.msr\\:h-2\\.5{height:calc(var(--msr-spacing) * 2.5)}.msr\\:h-3{height:calc(var(--msr-spacing) * 3)}.msr\\:h-5{height:calc(var(--msr-spacing) * 5)}.msr\\:h-6{height:calc(var(--msr-spacing) * 6)}.msr\\:h-7{height:calc(var(--msr-spacing) * 7)}.msr\\:h-8{height:calc(var(--msr-spacing) * 8)}.msr\\:h-\\[3px\\]{height:3px}.msr\\:h-\\[14px\\]{height:14px}.msr\\:h-auto{height:auto}.msr\\:h-full{height:100%}.msr\\:h-max{height:max-content}.msr\\:h-px{height:1px}.msr\\:max-h-32{max-height:calc(var(--msr-spacing) * 32)}.msr\\:max-h-36{max-height:calc(var(--msr-spacing) * 36)}.msr\\:max-h-48{max-height:calc(var(--msr-spacing) * 48)}.msr\\:max-h-\\[28rem\\]{max-height:28rem}.msr\\:max-h-\\[120px\\]{max-height:120px}.msr\\:max-h-full{max-height:100%}.msr\\:min-h-0{min-height:calc(var(--msr-spacing) * 0)}.msr\\:min-h-6{min-height:calc(var(--msr-spacing) * 6)}.msr\\:min-h-8{min-height:calc(var(--msr-spacing) * 8)}.msr\\:min-h-\\[4\\.5rem\\]{min-height:4.5rem}.msr\\:w-0{width:calc(var(--msr-spacing) * 0)}.msr\\:w-0\\.5{width:calc(var(--msr-spacing) * .5)}.msr\\:w-4{width:calc(var(--msr-spacing) * 4)}.msr\\:w-5{width:calc(var(--msr-spacing) * 5)}.msr\\:w-6{width:calc(var(--msr-spacing) * 6)}.msr\\:w-8{width:calc(var(--msr-spacing) * 8)}.msr\\:w-9{width:calc(var(--msr-spacing) * 9)}.msr\\:w-12{width:calc(var(--msr-spacing) * 12)}.msr\\:w-32{width:calc(var(--msr-spacing) * 32)}.msr\\:w-40{width:calc(var(--msr-spacing) * 40)}.msr\\:w-44{width:calc(var(--msr-spacing) * 44)}.msr\\:w-48{width:calc(var(--msr-spacing) * 48)}.msr\\:w-52{width:calc(var(--msr-spacing) * 52)}.msr\\:w-60{width:calc(var(--msr-spacing) * 60)}.msr\\:w-64{width:calc(var(--msr-spacing) * 64)}.msr\\:w-72{width:calc(var(--msr-spacing) * 72)}.msr\\:w-\\[18px\\]{width:18px}.msr\\:w-\\[22rem\\]{width:22rem}.msr\\:w-\\[26px\\]{width:26px}.msr\\:w-\\[36rem\\]{width:36rem}.msr\\:w-\\[220px\\]{width:220px}.msr\\:w-auto{width:auto}.msr\\:w-full{width:100%}.msr\\:w-max{width:max-content}.msr\\:w-px{width:1px}.msr\\:max-w-\\[180px\\]{max-width:180px}.msr\\:max-w-\\[calc\\(100vw-16px\\)\\]{max-width:calc(100vw - 16px)}.msr\\:max-w-\\[calc\\(100vw-24px\\)\\]{max-width:calc(100vw - 24px)}.msr\\:max-w-\\[min\\(100vw-16px\\,15rem\\)\\]{max-width:min(100vw - 16px,15rem)}.msr\\:max-w-\\[min\\(200px\\,calc\\(100vw-24px\\)\\)\\]{max-width:min(200px,100vw - 24px)}.msr\\:max-w-\\[min\\(240px\\,calc\\(100vw-16px\\)\\)\\]{max-width:min(240px,100vw - 16px)}.msr\\:max-w-full{max-width:100%}.msr\\:max-w-none{max-width:none}.msr\\:min-w-0{min-width:calc(var(--msr-spacing) * 0)}.msr\\:min-w-32{min-width:calc(var(--msr-spacing) * 32)}.msr\\:min-w-36{min-width:calc(var(--msr-spacing) * 36)}.msr\\:min-w-44{min-width:calc(var(--msr-spacing) * 44)}.msr\\:flex-1{flex:1}.msr\\:flex-none{flex:none}.msr\\:shrink-0{flex-shrink:0}.msr\\:-translate-x-1\\/2{--tw-translate-x:calc(calc(1 / 2 * 100%) * -1);translate:var(--tw-translate-x) var(--tw-translate-y)}.msr\\:-translate-y-1\\/2{--tw-translate-y:calc(calc(1 / 2 * 100%) * -1);translate:var(--tw-translate-x) var(--tw-translate-y)}.msr\\:-translate-y-full{--tw-translate-y:-100%;translate:var(--tw-translate-x) var(--tw-translate-y)}.msr\\:-rotate-90{rotate:-90deg}.msr\\:rotate-45{rotate:45deg}.msr\\:rotate-90{rotate:90deg}.msr\\:animate-\\[mesurer-screenshot-preview_5\\.16s_ease-out_both\\]{animation:5.16s ease-out both mesurer-screenshot-preview}.msr\\:cursor-crosshair{cursor:crosshair}.msr\\:cursor-default{cursor:default}.msr\\:cursor-ew-resize{cursor:ew-resize}.msr\\:cursor-move{cursor:move}.msr\\:cursor-nesw-resize{cursor:nesw-resize}.msr\\:cursor-ns-resize{cursor:ns-resize}.msr\\:cursor-nwse-resize{cursor:nwse-resize}.msr\\:cursor-pointer{cursor:pointer}.msr\\:cursor-text{cursor:text}.msr\\:touch-none{touch-action:none}.msr\\:resize-none{resize:none}.msr\\:list-none{list-style-type:none}.msr\\:appearance-none{appearance:none}.msr\\:grid-cols-\\[44px_minmax\\(0\\,1fr\\)\\]{grid-template-columns:44px minmax(0,1fr)}.msr\\:grid-cols-\\[56px_minmax\\(0\\,1fr\\)\\]{grid-template-columns:56px minmax(0,1fr)}.msr\\:grid-cols-\\[78px_150px\\]{grid-template-columns:78px 150px}.msr\\:grid-cols-\\[78px_minmax\\(0\\,1fr\\)\\]{grid-template-columns:78px minmax(0,1fr)}.msr\\:flex-col{flex-direction:column}.msr\\:items-baseline{align-items:baseline}.msr\\:items-center{align-items:center}.msr\\:items-start{align-items:flex-start}.msr\\:items-stretch{align-items:stretch}.msr\\:justify-between{justify-content:space-between}.msr\\:justify-center{justify-content:center}.msr\\:justify-end{justify-content:flex-end}.msr\\:gap-0{gap:calc(var(--msr-spacing) * 0)}.msr\\:gap-0\\.5{gap:calc(var(--msr-spacing) * .5)}.msr\\:gap-1{gap:calc(var(--msr-spacing) * 1)}.msr\\:gap-1\\.5{gap:calc(var(--msr-spacing) * 1.5)}.msr\\:gap-2{gap:calc(var(--msr-spacing) * 2)}.msr\\:gap-\\[2px\\]{gap:2px}.msr\\:gap-px{gap:1px}.msr\\:self-center{align-self:center}.msr\\:justify-self-end{justify-self:flex-end}.msr\\:truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.msr\\:overflow-hidden{overflow:hidden}.msr\\:overflow-visible{overflow:visible}.msr\\:overflow-y-auto{overflow-y:auto}.msr\\:rounded{border-radius:.25rem}.msr\\:rounded-\\[2px\\]{border-radius:2px}.msr\\:rounded-\\[3px\\]{border-radius:3px}.msr\\:rounded-\\[4px\\]{border-radius:4px}.msr\\:rounded-\\[10px\\]{border-radius:10px}.msr\\:rounded-full{border-radius:3.40282e38px}.msr\\:rounded-lg{border-radius:var(--msr-radius-lg)}.msr\\:rounded-md{border-radius:var(--msr-radius-md)}.msr\\:rounded-none{border-radius:0}.msr\\:border{border-style:var(--tw-border-style);border-width:1px}.msr\\:border-0{border-style:var(--tw-border-style);border-width:0}.msr\\:border-2{border-style:var(--tw-border-style);border-width:2px}.msr\\:border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.msr\\:border-t-2{border-top-style:var(--tw-border-style);border-top-width:2px}.msr\\:border-r{border-right-style:var(--tw-border-style);border-right-width:1px}.msr\\:border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.msr\\:border-l{border-left-style:var(--tw-border-style);border-left-width:1px}.msr\\:border-dashed{--tw-border-style:dashed;border-style:dashed}.msr\\:border-dotted{--tw-border-style:dotted;border-style:dotted}.msr\\:border-solid{--tw-border-style:solid;border-style:solid}.msr\\:border-\\[\\#0d99ff\\]{border-color:#0d99ff}.msr\\:border-\\[\\#2563eb\\]\\/70{border-color:oklab(54.615% -.026671 -.213549/.7)}.msr\\:border-\\[var\\(--msr-danger-border\\)\\]{border-color:var(--msr-danger-border)}.msr\\:border-black\\/10{border-color:var(--msr-color-black)}@supports (color:color-mix(in lab, red, red)){.msr\\:border-black\\/10{border-color:color-mix(in oklab, var(--msr-color-black) 10%, transparent)}}.msr\\:border-ink-100{border-color:var(--msr-color-ink-100)}.msr\\:border-ink-200{border-color:var(--msr-color-ink-200)}.msr\\:border-ink-300{border-color:var(--msr-color-ink-300)}.msr\\:border-ink-500,.msr\\:border-ink-500\\/30{border-color:var(--msr-color-ink-500)}@supports (color:color-mix(in lab, red, red)){.msr\\:border-ink-500\\/30{border-color:color-mix(in oklab, var(--msr-color-ink-500) 30%, transparent)}}.msr\\:border-ink-700{border-color:var(--msr-color-ink-700)}.msr\\:border-transparent{border-color:#0000}.msr\\:border-white{border-color:var(--msr-color-white)}.msr\\:\\!bg-black\\/50{background-color:var(--msr-color-black)!important}@supports (color:color-mix(in lab, red, red)){.msr\\:\\!bg-black\\/50{background-color:color-mix(in oklab, var(--msr-color-black) 50%, transparent)!important}}.msr\\:bg-\\[\\#0d99ff\\]{background-color:#0d99ff}.msr\\:bg-\\[\\#0d99ff\\]\\/8{background-color:oklab(66.9841% -.0648249 -.170866/.08)}.msr\\:bg-\\[\\#0d99ff\\]\\/10{background-color:oklab(66.9841% -.0648249 -.170866/.1)}.msr\\:bg-\\[\\#2563eb\\]{background-color:#2563eb}.msr\\:bg-\\[var\\(--msr-danger-solid-bg\\)\\]{background-color:var(--msr-danger-solid-bg)}.msr\\:bg-black,.msr\\:bg-black\\/4{background-color:var(--msr-color-black)}@supports (color:color-mix(in lab, red, red)){.msr\\:bg-black\\/4{background-color:color-mix(in oklab, var(--msr-color-black) 4%, transparent)}}.msr\\:bg-black\\/40{background-color:var(--msr-color-black)}@supports (color:color-mix(in lab, red, red)){.msr\\:bg-black\\/40{background-color:color-mix(in oklab, var(--msr-color-black) 40%, transparent)}}.msr\\:bg-black\\/80{background-color:var(--msr-color-black)}@supports (color:color-mix(in lab, red, red)){.msr\\:bg-black\\/80{background-color:color-mix(in oklab, var(--msr-color-black) 80%, transparent)}}.msr\\:bg-ink-50{background-color:var(--msr-color-ink-50)}.msr\\:bg-ink-100{background-color:var(--msr-color-ink-100)}.msr\\:bg-ink-200{background-color:var(--msr-color-ink-200)}.msr\\:bg-ink-300{background-color:var(--msr-color-ink-300)}.msr\\:bg-ink-500\\/50{background-color:var(--msr-color-ink-500)}@supports (color:color-mix(in lab, red, red)){.msr\\:bg-ink-500\\/50{background-color:color-mix(in oklab, var(--msr-color-ink-500) 50%, transparent)}}.msr\\:bg-ink-900,.msr\\:bg-ink-900\\/90{background-color:var(--msr-color-ink-900)}@supports (color:color-mix(in lab, red, red)){.msr\\:bg-ink-900\\/90{background-color:color-mix(in oklab, var(--msr-color-ink-900) 90%, transparent)}}.msr\\:bg-transparent{background-color:#0000}.msr\\:bg-white,.msr\\:bg-white\\/5{background-color:var(--msr-color-white)}@supports (color:color-mix(in lab, red, red)){.msr\\:bg-white\\/5{background-color:color-mix(in oklab, var(--msr-color-white) 5%, transparent)}}.msr\\:object-contain{object-fit:contain}.msr\\:p-0{padding:calc(var(--msr-spacing) * 0)}.msr\\:p-1{padding:calc(var(--msr-spacing) * 1)}.msr\\:p-2{padding:calc(var(--msr-spacing) * 2)}.msr\\:p-3{padding:calc(var(--msr-spacing) * 3)}.msr\\:p-\\[2px\\]{padding:2px}.msr\\:p-px{padding:1px}.msr\\:px-0{padding-inline:calc(var(--msr-spacing) * 0)}.msr\\:px-0\\.5{padding-inline:calc(var(--msr-spacing) * .5)}.msr\\:px-1{padding-inline:calc(var(--msr-spacing) * 1)}.msr\\:px-1\\.5{padding-inline:calc(var(--msr-spacing) * 1.5)}.msr\\:px-2{padding-inline:calc(var(--msr-spacing) * 2)}.msr\\:px-3{padding-inline:calc(var(--msr-spacing) * 3)}.msr\\:py-0\\.5{padding-block:calc(var(--msr-spacing) * .5)}.msr\\:py-1{padding-block:calc(var(--msr-spacing) * 1)}.msr\\:py-1\\.5{padding-block:calc(var(--msr-spacing) * 1.5)}.msr\\:py-2{padding-block:calc(var(--msr-spacing) * 2)}.msr\\:py-6{padding-block:calc(var(--msr-spacing) * 6)}.msr\\:pt-1\\.5{padding-top:calc(var(--msr-spacing) * 1.5)}.msr\\:pt-8{padding-top:calc(var(--msr-spacing) * 8)}.msr\\:pr-1\\.5{padding-right:calc(var(--msr-spacing) * 1.5)}.msr\\:pr-2{padding-right:calc(var(--msr-spacing) * 2)}.msr\\:pr-6{padding-right:calc(var(--msr-spacing) * 6)}.msr\\:pb-1{padding-bottom:calc(var(--msr-spacing) * 1)}.msr\\:pb-2{padding-bottom:calc(var(--msr-spacing) * 2)}.msr\\:pl-1{padding-left:calc(var(--msr-spacing) * 1)}.msr\\:pl-1\\.5{padding-left:calc(var(--msr-spacing) * 1.5)}.msr\\:pl-3{padding-left:calc(var(--msr-spacing) * 3)}.msr\\:pl-6{padding-left:calc(var(--msr-spacing) * 6)}.msr\\:text-center{text-align:center}.msr\\:text-left{text-align:left}.msr\\:text-right{text-align:right}.msr\\:font-mono{font-family:var(--msr-font-mono)}.msr\\:text-\\[9px\\]{font-size:9px}.msr\\:text-\\[10px\\]{font-size:10px}.msr\\:text-\\[11px\\]{font-size:11px}.msr\\:text-\\[12px\\]{font-size:12px}.msr\\:text-\\[13px\\]{font-size:13px}.msr\\:text-\\[16px\\]{font-size:16px}.msr\\:leading-4{--tw-leading:calc(var(--msr-spacing) * 4);line-height:calc(var(--msr-spacing) * 4)}.msr\\:leading-5{--tw-leading:calc(var(--msr-spacing) * 5);line-height:calc(var(--msr-spacing) * 5)}.msr\\:leading-6{--tw-leading:calc(var(--msr-spacing) * 6);line-height:calc(var(--msr-spacing) * 6)}.msr\\:leading-none{--tw-leading:1;line-height:1}.msr\\:font-medium{--tw-font-weight:var(--msr-font-weight-medium);font-weight:var(--msr-font-weight-medium)}.msr\\:font-normal{--tw-font-weight:var(--msr-font-weight-normal);font-weight:var(--msr-font-weight-normal)}.msr\\:font-semibold{--tw-font-weight:var(--msr-font-weight-semibold);font-weight:var(--msr-font-weight-semibold)}.msr\\:text-pretty{text-wrap:pretty}.msr\\:break-words{overflow-wrap:break-word}.msr\\:whitespace-normal{white-space:normal}.msr\\:whitespace-nowrap{white-space:nowrap}.msr\\:whitespace-pre{white-space:pre}.msr\\:whitespace-pre-wrap{white-space:pre-wrap}.msr\\:text-\\[\\#64748b\\]{color:#64748b}.msr\\:text-\\[var\\(--msr-danger-solid-text\\)\\]{color:var(--msr-danger-solid-text)}.msr\\:text-\\[var\\(--msr-danger-text\\)\\]{color:var(--msr-danger-text)}.msr\\:text-ink-50{color:var(--msr-color-ink-50)}.msr\\:text-ink-500{color:var(--msr-color-ink-500)}.msr\\:text-ink-700{color:var(--msr-color-ink-700)}.msr\\:text-ink-900{color:var(--msr-color-ink-900)}.msr\\:text-red-600{color:var(--msr-color-red-600)}.msr\\:text-white,.msr\\:text-white\\/60{color:var(--msr-color-white)}@supports (color:color-mix(in lab, red, red)){.msr\\:text-white\\/60{color:color-mix(in oklab, var(--msr-color-white) 60%, transparent)}}.msr\\:tabular-nums{--tw-numeric-spacing:tabular-nums;font-variant-numeric:var(--tw-ordinal,) var(--tw-slashed-zero,) var(--tw-numeric-figure,) var(--tw-numeric-spacing,) var(--tw-numeric-fraction,)}.msr\\:underline-offset-2{text-underline-offset:2px}.msr\\:caret-\\[\\#0d99ff\\]{caret-color:#0d99ff}.msr\\:opacity-0{opacity:0}.msr\\:opacity-100{opacity:1}.msr\\:shadow-\\[0_0_0_1px_rgba\\(0\\,0\\,0\\,0\\.25\\)\\]{--tw-shadow:0 0 0 1px var(--tw-shadow-color,#00000040);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.msr\\:shadow-\\[0_1px_2px_rgb\\(0_0_0_\\/_0\\.06\\)\\]{--tw-shadow:0 1px 2px var(--tw-shadow-color,#0000000f);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.msr\\:shadow-floating{--tw-shadow:0 0 .4px var(--tw-shadow-color,#00000038), 0 6px 18px var(--tw-shadow-color,#00000008), 0 3px 9px var(--tw-shadow-color,#0000000f), 0 1px 1px var(--tw-shadow-color,#0000000f);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.msr\\:shadow-none{--tw-shadow:0 0 #0000;box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.msr\\:outline,.msr\\:outline-1{outline-style:var(--tw-outline-style);outline-width:1px}.msr\\:outline-\\[\\#0d99ff\\]{outline-color:#0d99ff}.msr\\:drop-shadow-\\[0_1px_2px_rgba\\(0\\,0\\,0\\,0\\.8\\)\\]{--tw-drop-shadow-size:drop-shadow(0 1px 2px var(--tw-drop-shadow-color,#000c));--tw-drop-shadow:var(--tw-drop-shadow-size);filter:var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,)}.msr\\:transition-\\[height\\]{transition-property:height;transition-timing-function:var(--tw-ease,var(--msr-default-transition-timing-function));transition-duration:var(--tw-duration,var(--msr-default-transition-duration))}.msr\\:transition-\\[left\\]{transition-property:left;transition-timing-function:var(--tw-ease,var(--msr-default-transition-timing-function));transition-duration:var(--tw-duration,var(--msr-default-transition-duration))}.msr\\:transition-\\[max-height\\]{transition-property:max-height;transition-timing-function:var(--tw-ease,var(--msr-default-transition-timing-function));transition-duration:var(--tw-duration,var(--msr-default-transition-duration))}.msr\\:transition-\\[width\\]{transition-property:width;transition-timing-function:var(--tw-ease,var(--msr-default-transition-timing-function));transition-duration:var(--tw-duration,var(--msr-default-transition-duration))}.msr\\:transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--msr-default-transition-timing-function));transition-duration:var(--tw-duration,var(--msr-default-transition-duration))}.msr\\:transition-opacity{transition-property:opacity;transition-timing-function:var(--tw-ease,var(--msr-default-transition-timing-function));transition-duration:var(--tw-duration,var(--msr-default-transition-duration))}.msr\\:transition-shadow{transition-property:box-shadow;transition-timing-function:var(--tw-ease,var(--msr-default-transition-timing-function));transition-duration:var(--tw-duration,var(--msr-default-transition-duration))}.msr\\:transition-transform{transition-property:transform,translate,scale,rotate;transition-timing-function:var(--tw-ease,var(--msr-default-transition-timing-function));transition-duration:var(--tw-duration,var(--msr-default-transition-duration))}.msr\\:transition-none{transition-property:none}.msr\\:duration-150{--tw-duration:.15s;transition-duration:.15s}.msr\\:duration-200{--tw-duration:.2s;transition-duration:.2s}.msr\\:duration-300{--tw-duration:.3s;transition-duration:.3s}.msr\\:ease-\\[cubic-bezier\\(0\\.22\\,1\\,0\\.36\\,1\\)\\]{--tw-ease:cubic-bezier(.22,1,.36,1);transition-timing-function:cubic-bezier(.22,1,.36,1)}.msr\\:ease-\\[ease\\]{--tw-ease:ease;transition-timing-function:ease}.msr\\:will-change-transform{will-change:transform}.msr\\:outline-none{--tw-outline-style:none;outline-style:none}.msr\\:select-none{-webkit-user-select:none;user-select:none}.msr\\:select-text{-webkit-user-select:text;user-select:text}@media (hover:hover){.msr\\:group-hover\\:h-3:is(:where(.msr\\:group):hover *){height:calc(var(--msr-spacing) * 3)}.msr\\:group-hover\\:opacity-100:is(:where(.msr\\:group):hover *){opacity:1}.msr\\:group-hover\\/video\\:pointer-events-auto:is(:where(.msr\\:group\\/video):hover *){pointer-events:auto}.msr\\:group-hover\\/video\\:opacity-100:is(:where(.msr\\:group\\/video):hover *){opacity:1}}.msr\\:group-focus-visible\\:h-3:is(:where(.msr\\:group):focus-visible *){height:calc(var(--msr-spacing) * 3)}.msr\\:focus-within\\:pointer-events-auto:focus-within{pointer-events:auto}.msr\\:focus-within\\:relative:focus-within{position:relative}.msr\\:focus-within\\:z-\\[1\\]:focus-within{z-index:1}.msr\\:focus-within\\:rounded-l-\\[5px\\]:focus-within{border-top-left-radius:5px;border-bottom-left-radius:5px}.msr\\:focus-within\\:rounded-r-\\[5px\\]:focus-within{border-top-right-radius:5px;border-bottom-right-radius:5px}.msr\\:focus-within\\:border-\\[\\#0d99ff\\]:focus-within{border-color:#0d99ff}.msr\\:focus-within\\:opacity-100:focus-within{opacity:1}.msr\\:focus-within\\:shadow-\\[0_0_0_1px_\\#0d99ff\\]:focus-within{--tw-shadow:0 0 0 1px var(--tw-shadow-color,#0d99ff);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}@media (hover:hover){.msr\\:hover\\:border-ink-200:hover{border-color:var(--msr-color-ink-200)}.msr\\:hover\\:\\!bg-black\\/60:hover{background-color:var(--msr-color-black)!important}@supports (color:color-mix(in lab, red, red)){.msr\\:hover\\:\\!bg-black\\/60:hover{background-color:color-mix(in oklab, var(--msr-color-black) 60%, transparent)!important}}.msr\\:hover\\:bg-\\[\\#0d99ff\\]:hover{background-color:#0d99ff}.msr\\:hover\\:bg-\\[\\#087dcc\\]:hover{background-color:#087dcc}.msr\\:hover\\:bg-\\[var\\(--msr-danger-bg\\)\\]:hover{background-color:var(--msr-danger-bg)}.msr\\:hover\\:bg-\\[var\\(--msr-danger-solid-hover\\)\\]:hover{background-color:var(--msr-danger-solid-hover)}.msr\\:hover\\:bg-black\\/4:hover{background-color:var(--msr-color-black)}@supports (color:color-mix(in lab, red, red)){.msr\\:hover\\:bg-black\\/4:hover{background-color:color-mix(in oklab, var(--msr-color-black) 4%, transparent)}}.msr\\:hover\\:bg-ink-50:hover{background-color:var(--msr-color-ink-50)}.msr\\:hover\\:bg-ink-100:hover{background-color:var(--msr-color-ink-100)}.msr\\:hover\\:bg-ink-200:hover,.msr\\:hover\\:bg-ink-200\\/50:hover{background-color:var(--msr-color-ink-200)}@supports (color:color-mix(in lab, red, red)){.msr\\:hover\\:bg-ink-200\\/50:hover{background-color:color-mix(in oklab, var(--msr-color-ink-200) 50%, transparent)}}.msr\\:hover\\:bg-red-50:hover{background-color:var(--msr-color-red-50)}.msr\\:hover\\:bg-transparent:hover{background-color:#0000}.msr\\:hover\\:text-ink-700:hover{color:var(--msr-color-ink-700)}.msr\\:hover\\:text-ink-900:hover{color:var(--msr-color-ink-900)}.msr\\:hover\\:text-white:hover{color:var(--msr-color-white)}.msr\\:hover\\:underline:hover{text-decoration-line:underline}.msr\\:hover\\:focus-within\\:border-\\[\\#0d99ff\\]:hover:focus-within{border-color:#0d99ff}}.msr\\:focus\\:border-\\[\\#0d99ff\\]:focus{border-color:#0d99ff}.msr\\:focus\\:shadow-\\[inset_0_0_0_1px_\\#0d99ff\\]:focus{--tw-shadow:inset 0 0 0 1px var(--tw-shadow-color,#0d99ff);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.msr\\:focus\\:shadow-\\[inset_0_0_0_1px_var\\(--msr-accent\\)\\]:focus{--tw-shadow:inset 0 0 0 1px var(--tw-shadow-color,var(--msr-accent));box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.msr\\:focus\\:outline-none:focus{--tw-outline-style:none;outline-style:none}.msr\\:focus-visible\\:bg-ink-100:focus-visible{background-color:var(--msr-color-ink-100)}.msr\\:focus-visible\\:opacity-100:focus-visible{opacity:1}.msr\\:focus-visible\\:shadow-\\[inset_0_0_0_1px_var\\(--color-ink-700\\)\\]:focus-visible{--tw-shadow:inset 0 0 0 1px var(--tw-shadow-color,var(--color-ink-700));box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.msr\\:focus-visible\\:shadow-\\[inset_0_0_0_1px_var\\(--msr-accent\\)\\]:focus-visible{--tw-shadow:inset 0 0 0 1px var(--tw-shadow-color,var(--msr-accent));box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.msr\\:focus-visible\\:shadow-\\[inset_0_0_0_1px_var\\(--msr-danger-text\\)\\]:focus-visible{--tw-shadow:inset 0 0 0 1px var(--tw-shadow-color,var(--msr-danger-text));box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.msr\\:focus-visible\\:ring-1:focus-visible{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.msr\\:focus-visible\\:ring-2:focus-visible{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.msr\\:focus-visible\\:ring-\\[var\\(--msr-accent\\)\\]\\/25:focus-visible{--tw-ring-color:var(--msr-accent)}@supports (color:color-mix(in lab, red, red)){.msr\\:focus-visible\\:ring-\\[var\\(--msr-accent\\)\\]\\/25:focus-visible{--tw-ring-color:color-mix(in oklab, var(--msr-accent) 25%, transparent)}}.msr\\:focus-visible\\:outline:focus-visible,.msr\\:focus-visible\\:outline-1:focus-visible{outline-style:var(--tw-outline-style);outline-width:1px}.msr\\:focus-visible\\:outline-offset-1:focus-visible{outline-offset:1px}.msr\\:focus-visible\\:outline-ink-500:focus-visible{outline-color:var(--msr-color-ink-500)}.msr\\:focus-visible\\:outline-none:focus-visible{--tw-outline-style:none;outline-style:none}.msr\\:focus-visible\\:ring-inset:focus-visible{--tw-ring-inset:inset}.msr\\:disabled\\:cursor-default:disabled{cursor:default}.msr\\:disabled\\:cursor-not-allowed:disabled{cursor:not-allowed}.msr\\:disabled\\:opacity-40:disabled{opacity:.4}@media (prefers-reduced-motion:reduce){.msr\\:motion-reduce\\:transition-none{transition-property:none}}.msr\\:rounded-control{border-radius:var(--msr-radius-control)}.msr\\:rounded-wide-card{border-radius:var(--msr-radius-wide-card)}}:root,:host{--color-ink-50:#f8fafc;--color-ink-100:#f1f5f9;--color-ink-200:#e2e8f0;--color-ink-300:#cbd5e1;--color-ink-500:#64748b;--color-ink-700:#334155;--color-ink-900:#18181b}:host{all:initial;color-scheme:light dark;color:var(--msr-color-ink-900);letter-spacing:normal;--msr-spacing:4px;direction:ltr;font-family:ui-sans-serif,system-ui,sans-serif;font-size:16px;font-weight:400;line-height:1.5;display:block}.mesurer-root{--msr-accent:#0d99ff;--msr-surface:#fff;--msr-surface-raised:#fff;--msr-surface-muted:var(--msr-color-ink-50);--msr-content:var(--msr-color-ink-900);--msr-color-white:#fff;--msr-color-black:#000;--msr-danger-bg:#fef2f2;--msr-danger-border:#fecaca;--msr-danger-text:#dc2626;--msr-danger-solid-bg:#dc2626;--msr-danger-solid-hover:#b91c1c;--msr-danger-solid-text:#fff;--msr-control-thumb:#fff;--msr-slider-track:#0f172a29;--msr-shadow-toolbar:drop-shadow(0 0 .4px #00000038) drop-shadow(0 6px 18px #00000008) drop-shadow(0 3px 9px #0000000f) drop-shadow(0 1px 1px #0000000f);--msr-shadow-floating:0 0 .4px #00000038, 0 6px 18px #00000008, 0 3px 9px #0000000f, 0 1px 1px #0000000f;--msr-shadow-select-menu:var(--msr-shadow-floating);--msr-comment-menu-surface:var(--msr-surface-raised);--msr-shadow-comment-menu:var(--msr-shadow-select-menu);color:var(--msr-content);color-scheme:light}.mesurer-root [class~=msr\\:bg-white]{background-color:var(--msr-surface)!important}.mesurer-root [class~="msr:bg-[#0d99ff]"],.mesurer-root [class~="msr:hover:bg-[#0d99ff]"]:hover{background-color:var(--msr-accent)!important}.mesurer-root [class~="msr:border-[#0d99ff]"]{border-color:var(--msr-accent)!important}.mesurer-root [class~="msr:bg-[#0d99ff]/8"]{background-color:var(--msr-accent)!important}@supports (color:color-mix(in lab, red, red)){.mesurer-root [class~="msr:bg-[#0d99ff]/8"]{background-color:color-mix(in srgb, var(--msr-accent) 8%, transparent)!important}}.mesurer-root [class~=msr\\:text-black]{color:var(--msr-content)!important}.mesurer-root .mesurer-control-thumb{background-color:var(--msr-control-thumb)!important}.mesurer-root button{-webkit-user-select:none;user-select:none;cursor:default!important}.mesurer-root .mesurer-settings-button-ghost{opacity:.7}.mesurer-root .mesurer-settings-button-ghost:hover,.mesurer-root .mesurer-settings-button-ghost:focus-visible{opacity:1}.mesurer-root [data-mesurer-recording-timeline] .mesurer-recording-track-rail{background-color:var(--msr-color-ink-200)}.mesurer-root [data-mesurer-recording-timeline] .mesurer-recording-track-clip{background-color:var(--msr-color-ink-300)}.mesurer-root [data-mesurer-recording-timeline] .mesurer-recording-playhead,.mesurer-root [data-mesurer-recording-timeline] .mesurer-recording-trim-bar{background-color:var(--msr-color-ink-900)}.mesurer-root .mesurer-switch-thumb[data-checked=false]{background-color:var(--msr-color-ink-200)!important}.mesurer-root [class~="msr:hover:bg-black/4"]:hover,.mesurer-root [class~="msr:hover:bg-black/5"]:hover{background-color:var(--msr-content)!important}@supports (color:color-mix(in lab, red, red)){.mesurer-root [class~="msr:hover:bg-black/4"]:hover,.mesurer-root [class~="msr:hover:bg-black/5"]:hover{background-color:color-mix(in srgb, var(--msr-content) 6%, transparent)!important}}.mesurer-root .mesurer-menu-surface,.mesurer-root .mesurer-color-picker{border-radius:9px}.mesurer-root .mesurer-menu-surface,.mesurer-root .mesurer-color-picker,.mesurer-root .mesurer-comment-card,.mesurer-root .mesurer-comment-hover-card,.mesurer-root .mesurer-comment-delete-confirmation{color:var(--msr-content);background-color:var(--msr-surface-raised)!important}.mesurer-root .mesurer-section-divider{background-color:var(--msr-color-ink-200)!important}.mesurer-root .mesurer-settings-select-menu{box-shadow:var(--msr-shadow-select-menu)}.mesurer-root .mesurer-comment-overflow-menu,.mesurer-root .mesurer-comment-delete-confirmation{box-shadow:var(--msr-shadow-comment-menu);background-color:var(--msr-comment-menu-surface)!important}.mesurer-root .mesurer-comment-menu-item:hover{background-color:var(--msr-color-ink-200)!important}.mesurer-root .mesurer-comment-menu-danger{color:var(--msr-danger-text)!important}.mesurer-root .mesurer-comment-menu-danger:hover{background-color:var(--msr-danger-bg)!important}.mesurer-root .mesurer-settings-button-default{background-color:#0000}.mesurer-root .mesurer-settings-button-default:hover{background-color:var(--msr-color-ink-50)}.mesurer-root[data-theme=dark] .mesurer-control-shell{background-color:var(--msr-color-ink-100)}.mesurer-root[data-theme=dark] .mesurer-settings-panel select,.mesurer-root[data-theme=dark] .mesurer-settings-select,.mesurer-root[data-theme=dark] .mesurer-settings-select-menu{background-color:var(--msr-surface-raised)!important;border-color:var(--msr-color-ink-200)!important}.mesurer-root[data-theme=dark] .mesurer-settings-button-default:hover{background-color:var(--msr-surface)!important}@media (prefers-color-scheme:dark){.mesurer-root[data-theme=system] .mesurer-control-shell{background-color:var(--msr-color-ink-100)}.mesurer-root[data-theme=system] .mesurer-settings-panel select,.mesurer-root[data-theme=system] .mesurer-settings-select,.mesurer-root[data-theme=system] .mesurer-settings-select-menu{background-color:var(--msr-surface-raised)!important;border-color:var(--msr-color-ink-200)!important}.mesurer-root[data-theme=system] .mesurer-settings-button-default:hover{background-color:var(--msr-surface)!important}}.mesurer-root[data-theme=dark] .mesurer-switch-track[data-checked=false]{background-color:var(--msr-color-ink-100)!important}@media (prefers-color-scheme:dark){.mesurer-root[data-theme=system] .mesurer-switch-track[data-checked=false]{background-color:var(--msr-color-ink-100)!important}}.mesurer-root .mesurer-settings-panel .mesurer-control-focus :is(input,select):focus{box-shadow:none!important;outline:none!important}.mesurer-root[data-theme=dark]{--msr-accent:#0c8ce9;--msr-color-red-50:#3f2020;--msr-color-red-200:#7f3f46;--msr-color-red-600:#f87171;--msr-color-red-700:#fca5a5;--msr-danger-bg:#3f2020;--msr-danger-border:#7f3f46;--msr-danger-text:#f87171;--msr-danger-solid-bg:#c95058;--msr-danger-solid-hover:#b7424b;--msr-danger-solid-text:#f5f5f5;--msr-color-ink-50:#3a3a3a;--msr-color-ink-100:#414141;--msr-color-ink-200:#4a4a4a;--msr-color-ink-300:#5a5a5a;--msr-color-ink-500:#a0a0a0;--msr-color-ink-700:#dedede;--msr-color-ink-900:#f5f5f5;--msr-surface:#323232;--msr-surface-raised:#3a3a3a;--msr-surface-muted:#3a3a3a;--msr-color-white:#f5f5f5;--msr-color-black:#171717;--msr-control-thumb:#f4f4f5;--msr-slider-track:#f5f5f53d;--msr-shadow-toolbar:drop-shadow(0 0 .4px lch(100% 0 0/.1)) drop-shadow(0 3px 8px lch(0% 0 0/.125)) drop-shadow(0 2px 5px lch(0% 0 0/.125)) drop-shadow(0 1px 1px lch(0% 0 0/.125));--msr-shadow-floating:0 0 .4px lch(100% 0 0/.1), 0 3px 8px lch(0% 0 0/.125), 0 2px 5px lch(0% 0 0/.125), 0 1px 1px lch(0% 0 0/.125);--msr-shadow-select-menu:0 0 0 .4px lch(100% 0 0/.14), 0 4px 12px lch(0% 0 0/.22), 0 1px 3px lch(0% 0 0/.18);--msr-comment-menu-surface:#323232;--msr-shadow-comment-menu:0 0 0 .5px lch(100% 0 0/.16), 0 5px 14px lch(0% 0 0/.26), 0 1px 3px lch(0% 0 0/.18);color-scheme:dark}@media (prefers-color-scheme:dark){.mesurer-root[data-theme=system]{--msr-accent:#0c8ce9;--msr-color-red-50:#3f2020;--msr-color-red-200:#7f3f46;--msr-color-red-600:#f87171;--msr-color-red-700:#fca5a5;--msr-danger-bg:#3f2020;--msr-danger-border:#7f3f46;--msr-danger-text:#f87171;--msr-danger-solid-bg:#c95058;--msr-danger-solid-hover:#b7424b;--msr-danger-solid-text:#f5f5f5;--msr-color-ink-50:#3a3a3a;--msr-color-ink-100:#414141;--msr-color-ink-200:#4a4a4a;--msr-color-ink-300:#5a5a5a;--msr-color-ink-500:#a0a0a0;--msr-color-ink-700:#dedede;--msr-color-ink-900:#f5f5f5;--msr-surface:#323232;--msr-surface-raised:#3a3a3a;--msr-surface-muted:#3a3a3a;--msr-color-white:#f5f5f5;--msr-color-black:#171717;--msr-control-thumb:#f4f4f5;--msr-slider-track:#f5f5f53d;--msr-shadow-toolbar:drop-shadow(0 0 .4px lch(100% 0 0/.1)) drop-shadow(0 3px 8px lch(0% 0 0/.125)) drop-shadow(0 2px 5px lch(0% 0 0/.125)) drop-shadow(0 1px 1px lch(0% 0 0/.125));--msr-shadow-floating:0 0 .4px lch(100% 0 0/.1), 0 3px 8px lch(0% 0 0/.125), 0 2px 5px lch(0% 0 0/.125), 0 1px 1px lch(0% 0 0/.125);--msr-shadow-select-menu:0 0 0 .4px lch(100% 0 0/.14), 0 4px 12px lch(0% 0 0/.22), 0 1px 3px lch(0% 0 0/.18);--msr-comment-menu-surface:#323232;--msr-shadow-comment-menu:0 0 0 .5px lch(100% 0 0/.16), 0 5px 14px lch(0% 0 0/.26), 0 1px 3px lch(0% 0 0/.18);color-scheme:dark}}.mesurer-color-picker,.mesurer-color-picker *,.mesurer-root [data-mesurer-inspect-info-card],.mesurer-root [data-mesurer-inspect-info-card] *,[data-mesurer-overlay][data-mesurer-inspect],[data-mesurer-overlay][data-mesurer-inspect] *{cursor:default!important}.mesurer-root button[data-mesurer-resize-cursor],.mesurer-root button[data-mesurer-resize-cursor] *,[data-mesurer-overlay][data-mesurer-inspect] [data-mesurer-resize-cursor],[data-mesurer-overlay][data-mesurer-inspect] [data-mesurer-resize-cursor] *{cursor:var(--msr-resize-cursor)!important}html[data-mesurer-resize-cursor],html[data-mesurer-resize-cursor] *,html[data-mesurer-resize-cursor] [data-mesurer-overlay][data-mesurer-inspect],html[data-mesurer-resize-cursor] [data-mesurer-overlay][data-mesurer-inspect] *,.mesurer-root[data-mesurer-resize-cursor],.mesurer-root[data-mesurer-resize-cursor] *{cursor:var(--msr-resize-cursor-lock)!important}.mesurer-root,.mesurer-root *,.mesurer-root :before,.mesurer-root :after{box-sizing:border-box}.mesurer-toolbar-motion{--msr-toolbar-motion:.2s ease;z-index:0;isolation:isolate;width:max-content;max-width:100%;display:block;position:relative}.mesurer-layout-guides,.mesurer-layout-guides-layer,.mesurer-layout-guides-grid{pointer-events:none;position:absolute;inset:0}.mesurer-layout-guides{z-index:2;overflow:hidden}.mesurer-toolbar-chrome{z-index:0;background:var(--msr-surface);width:100%;filter:var(--msr-shadow-toolbar);transform-origin:0;pointer-events:none;border-radius:9px;position:absolute;inset:0 auto 0 0;overflow:visible}.mesurer-toolbar-clip{z-index:1;isolation:isolate;transform-origin:0;position:relative;overflow:visible}.mesurer-toolbar-motion[data-resizing=collapse] .mesurer-toolbar-clip{overflow:hidden}.mesurer-toolbar-motion[data-resizing] .mesurer-toolbar-tooltips{visibility:hidden!important}.mesurer-toolbar-surface{transform-origin:0;padding:0;position:relative}.mesurer-toolbar-divider{background:var(--msr-color-ink-200);flex:none;align-self:stretch;width:1px;margin:0}.mesurer-toolbar-minimize-stage{min-width:0;width:var(--msr-expanded-w,auto);flex:none;overflow:visible}.mesurer-toolbar-minimize-stage[data-minimized=true]{width:var(--msr-icon-w,auto);overflow:hidden}.mesurer-toolbar-motion[data-resizing=collapse] .mesurer-toolbar-minimize-stage{overflow:hidden}.mesurer-toolbar-minimize-stage[data-minimized=true] .mesurer-toolbar-minimize-track{transform:translateX(calc(-1 * var(--msr-expanded-w,0px)))}.mesurer-toolbar-minimize-stage:has([role=dialog]),.mesurer-toolbar-minimize-stage:has([role=menu]),.mesurer-toolbar-minimize-stage:has(.mesurer-screenshot-preview){overflow:visible}.mesurer-toolbar-minimize-track{pointer-events:none;flex:none;display:flex;transform:translate(0)}.mesurer-toolbar-minimize-slot{flex:none}.mesurer-toolbar-minimize-slot[data-slot=expanded]{width:var(--msr-expanded-w,auto)}.mesurer-toolbar-minimize-slot[data-slot=icon]{width:auto}.mesurer-toolbar-minimize-slot:not([data-open=true]){pointer-events:none}.mesurer-toolbar-minimize-slot[data-open=true]{pointer-events:auto}.mesurer-toolbar-motion:not([data-resizing=collapse]) .mesurer-toolbar-minimize-slot[data-slot=icon]:not([data-open=true]){visibility:hidden}.mesurer-toolbar-restore svg{transform:translate(-.5px,.5px)}.mesurer-toolbar-tool-stage{min-width:0;width:var(--msr-inspect-w,auto);flex:none;overflow:hidden}.mesurer-toolbar-tool-stage[data-group=annotate]{width:var(--msr-annotate-w,auto)}.mesurer-toolbar-tool-stage[data-group=annotate] .mesurer-toolbar-tool-track{transform:translateX(calc(-1 * var(--msr-inspect-w,0px)))}.mesurer-toolbar-tool-stage:has([role=menu]),.mesurer-toolbar-tool-stage:has([role=dialog]){overflow:visible}.mesurer-toolbar-motion[data-resizing=true] .mesurer-toolbar-tool-stage{overflow:hidden}.mesurer-toolbar-tool-track{flex:none;display:flex;transform:translate(0)}.mesurer-toolbar-motion[data-ready=true] .mesurer-toolbar-tool-switch-pill{transition:transform var(--msr-toolbar-motion)}.mesurer-toolbar-tool-slot{flex:none}.mesurer-toolbar-tool-slot[data-group=inspect]{width:var(--msr-inspect-w,auto)}.mesurer-toolbar-tool-slot[data-group=annotate]{width:var(--msr-annotate-w,auto)}.mesurer-toolbar-tool-slot:not([data-open=true]){pointer-events:none}.mesurer-toolbar-motion:not([data-resizing]) .mesurer-toolbar-tool-slot:not([data-open=true]){visibility:hidden}.mesurer-toolbar-tool-panel{width:max-content}.mesurer-toolbar-tooltips{z-index:110;pointer-events:none;position:fixed;inset:0;overflow:visible}.mesurer-toolbar-trailing{z-index:1;isolation:isolate;background:var(--msr-surface);border-radius:0 9px 9px 0;flex:none;position:relative}.mesurer-toolbar-tool-switch{z-index:1;isolation:isolate;background:var(--msr-surface);position:relative}.mesurer-toolbar-tool-switch-pill{z-index:0;background:var(--msr-color-ink-200);border-radius:3px;width:28px;height:28px;position:absolute;top:2px;left:2px;transform:translate(0)}.mesurer-toolbar-tool-switch[data-value=annotate] .mesurer-toolbar-tool-switch-pill{transform:translate(30px)}.mesurer-toolbar-tool-switch>:not(.mesurer-toolbar-tool-switch-pill){z-index:1;position:relative}@media (prefers-reduced-motion:reduce){.mesurer-toolbar-motion,.mesurer-toolbar-chrome,.mesurer-toolbar-tool-track,.mesurer-toolbar-minimize-track,.mesurer-toolbar-trailing,.mesurer-toolbar-motion[data-ready=true] .mesurer-toolbar-tool-switch-pill{transition:none}.mesurer-screenshot-preview{animation-name:mesurer-screenshot-preview-reduced;animation-duration:5s;animation-timing-function:linear;animation-fill-mode:both}}@keyframes mesurer-screenshot-preview{0%,3.1%{opacity:0}6.2%,96.9%{opacity:1}to{opacity:0}}@keyframes mesurer-screenshot-preview-reduced{0%,to{opacity:1}}@keyframes mesurer-comment-nudge{0%,to{transform:translate(0)}35%{transform:translate(-3px)}70%{transform:translate(3px)}}.mesurer-comment-nudge{animation:.15s ease-out mesurer-comment-nudge}@keyframes mesurer-status-ellipsis{0%,24%{content:""}25%,49%{content:"."}50%,74%{content:".."}75%,to{content:"..."}}.mesurer-status-ellipsis{text-align:left;width:1.5em;display:inline-block}.mesurer-status-ellipsis:after{content:"";animation:1.2s step-end infinite mesurer-status-ellipsis}@media (prefers-reduced-motion:reduce){.mesurer-status-ellipsis:after{content:"...";animation:none}}.mesurer-thin-scrollbar{scrollbar-width:thin;scrollbar-color:var(--msr-color-ink-200) transparent}.mesurer-thin-scrollbar::-webkit-scrollbar{width:4px;height:4px}.mesurer-thin-scrollbar::-webkit-scrollbar-track{background:0 0}.mesurer-thin-scrollbar::-webkit-scrollbar-thumb{background:var(--msr-color-ink-200);border-radius:var(--msr-radius-control)}.mesurer-thin-scrollbar:hover{scrollbar-color:var(--msr-color-ink-300) transparent}.mesurer-thin-scrollbar:hover::-webkit-scrollbar-thumb{background:var(--msr-color-ink-300)}.mesurer-thin-scrollbar::-webkit-scrollbar-corner{background:0 0}.mesurer-toast-surface{box-shadow:var(--msr-shadow-floating)}.mesurer-root{--msr-spacing:4px}@property --tw-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-y{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-z{syntax:"*";inherits:false;initial-value:0}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-leading{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-ordinal{syntax:"*";inherits:false}@property --tw-slashed-zero{syntax:"*";inherits:false}@property --tw-numeric-figure{syntax:"*";inherits:false}@property --tw-numeric-spacing{syntax:"*";inherits:false}@property --tw-numeric-fraction{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"<length>";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-outline-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-blur{syntax:"*";inherits:false}@property --tw-brightness{syntax:"*";inherits:false}@property --tw-contrast{syntax:"*";inherits:false}@property --tw-grayscale{syntax:"*";inherits:false}@property --tw-hue-rotate{syntax:"*";inherits:false}@property --tw-invert{syntax:"*";inherits:false}@property --tw-opacity{syntax:"*";inherits:false}@property --tw-saturate{syntax:"*";inherits:false}@property --tw-sepia{syntax:"*";inherits:false}@property --tw-drop-shadow{syntax:"*";inherits:false}@property --tw-drop-shadow-color{syntax:"*";inherits:false}@property --tw-drop-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-drop-shadow-size{syntax:"*";inherits:false}@property --tw-duration{syntax:"*";inherits:false}@property --tw-ease{syntax:"*";inherits:false}@keyframes pulse{50%{opacity:.5}}';
86
523
 
87
524
  // mesurer-client.tsx
88
525
  var import_react79 = require("react");
@@ -93,7 +530,7 @@ var import_react3 = require("react");
93
530
  // package.json
94
531
  var package_default = {
95
532
  name: "mesurer",
96
- version: "0.2.2",
533
+ version: "0.2.3",
97
534
  description: "Inspect, annotate, and give feedback on any live interface",
98
535
  license: "MIT",
99
536
  author: "Julien Thibeaut",
@@ -1706,7 +2143,7 @@ function SettingsPanel({
1706
2143
  color,
1707
2144
  camera,
1708
2145
  rulers,
1709
- text,
2146
+ text: text2,
1710
2147
  arrows,
1711
2148
  focusSection,
1712
2149
  general
@@ -1726,7 +2163,7 @@ function SettingsPanel({
1726
2163
  } = general;
1727
2164
  const { settings: screenshotSettings, setSettings: setScreenshotSettings } = camera;
1728
2165
  const { settings: rulerSettings, setSettings: setRulerSettings } = rulers;
1729
- const { settings: textSettings, setSettings: setTextSettings } = text;
2166
+ const { settings: textSettings, setSettings: setTextSettings } = text2;
1730
2167
  const {
1731
2168
  color: arrowColor,
1732
2169
  setColor: setArrowColor,
@@ -2878,8 +3315,8 @@ var scaledFont = (scale) => ({
2878
3315
  fontSize: `${BASE_FONT_SIZE * scale}px`,
2879
3316
  lineHeight: `${BASE_LINE_HEIGHT * scale}px`
2880
3317
  });
2881
- var scaleBox = (box, handle, pointer) => {
2882
- const { x, y, width, height, rotation, scale, boxWidth } = box;
3318
+ var scaleBox = (box2, handle, pointer) => {
3319
+ const { x, y, width, height, rotation, scale, boxWidth } = box2;
2883
3320
  const center = boxCenter(x, y, width, height);
2884
3321
  const localPointer = rotatePoint(pointer, center, -rotation);
2885
3322
  const { ax, ay } = ANCHOR[handle];
@@ -2910,8 +3347,8 @@ var scaleBox = (box, handle, pointer) => {
2910
3347
  ...typeof boxWidth === "number" ? { boxWidth: Math.max(MIN_BOX_WIDTH, boxWidth * applied) } : {}
2911
3348
  };
2912
3349
  };
2913
- var resizeWidthBox = (box, handle, pointer) => {
2914
- const { x, y, width, height, rotation } = box;
3350
+ var resizeWidthBox = (box2, handle, pointer) => {
3351
+ const { x, y, width, height, rotation } = box2;
2915
3352
  const center = boxCenter(x, y, width, height);
2916
3353
  const localPointer = rotatePoint(pointer, center, -rotation);
2917
3354
  const { ax } = ANCHOR[handle];
@@ -3364,6 +3801,8 @@ var installKeyboardGate = (view = window, {
3364
3801
  }
3365
3802
  if (event instanceof KeyboardEvent && isMesurerKeyboardBridgeKey(event.key, event)) {
3366
3803
  bridgeKey(event);
3804
+ if (event.type === "keydown") event.preventDefault();
3805
+ return;
3367
3806
  }
3368
3807
  event.preventDefault();
3369
3808
  if (isAnnotationHotkey(event)) return;
@@ -3376,6 +3815,8 @@ var installKeyboardGate = (view = window, {
3376
3815
  if (event.type === "keydown" || event.type === "keyup") {
3377
3816
  if (isolateMesurerEvents && isMesurerKeyboardBridgeKey(event.key, event)) {
3378
3817
  bridgeKey(event);
3818
+ if (event.type === "keydown") event.preventDefault();
3819
+ return;
3379
3820
  }
3380
3821
  }
3381
3822
  }
@@ -4572,21 +5013,26 @@ var MenuSurface = (0, import_react17.forwardRef)(
4572
5013
  );
4573
5014
  }
4574
5015
  );
4575
- function ToolbarMenu({ className, side, align = "left", children, ...props }) {
5016
+ var ToolbarMenu = (0, import_react17.forwardRef)(function ToolbarMenu2({ className, side, align = "left", floating = false, floatingStyle, style, children, ...props }, ref) {
4576
5017
  return /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
4577
5018
  MenuSurface,
4578
5019
  {
4579
5020
  ...props,
5021
+ ref,
5022
+ style: floating ? { ...floatingStyle, ...style } : style,
4580
5023
  className: cn(
4581
- "msr:absolute msr:z-[100] msr:flex msr:w-44 msr:flex-col msr:gap-px",
4582
- side === "bottom" ? "msr:top-full msr:mt-2" : "msr:bottom-full msr:mb-2",
4583
- align === "left" ? "msr:left-0" : "msr:right-0",
5024
+ "msr:flex msr:w-44 msr:flex-col msr:gap-px",
5025
+ floating ? "msr:pointer-events-auto msr:fixed msr:z-[120]" : cn(
5026
+ "msr:absolute msr:z-[100]",
5027
+ side === "bottom" ? "msr:top-full msr:mt-2" : "msr:bottom-full msr:mb-2",
5028
+ align === "left" ? "msr:left-0" : "msr:right-0"
5029
+ ),
4584
5030
  className
4585
5031
  ),
4586
5032
  children
4587
5033
  }
4588
5034
  );
4589
- }
5035
+ });
4590
5036
  function MenuItem({
4591
5037
  className,
4592
5038
  children,
@@ -4717,6 +5163,7 @@ function CommentsPanel({
4717
5163
  panelRef,
4718
5164
  placement,
4719
5165
  fixed = false,
5166
+ fixedZIndex = 100,
4720
5167
  statusFilter,
4721
5168
  onStatusFilterChange
4722
5169
  }) {
@@ -4792,7 +5239,7 @@ function CommentsPanel({
4792
5239
  style: {
4793
5240
  position: fixed ? "fixed" : "absolute",
4794
5241
  width: fixed ? "18rem" : void 0,
4795
- zIndex: fixed ? 100 : void 0,
5242
+ zIndex: fixed ? fixedZIndex : void 0,
4796
5243
  pointerEvents: "auto",
4797
5244
  right: placement.right,
4798
5245
  top: placement.top,
@@ -4963,7 +5410,7 @@ function CommentsPanel({
4963
5410
  "data-mesurer-comment-actions": true,
4964
5411
  "data-mesurer-comment-ui": true,
4965
5412
  className: "mesurer-comment-overflow-menu msr:pointer-events-auto msr:fixed msr:z-[100] msr:w-32 msr:-translate-y-full msr:rounded-md msr:bg-white msr:p-1 msr:shadow-floating",
4966
- style: { position: "fixed", zIndex: 100, pointerEvents: "auto", width: "8rem", top: commentMenuPosition.top, right: commentMenuPosition.right },
5413
+ style: { position: "fixed", zIndex: 120, pointerEvents: "auto", width: "8rem", top: commentMenuPosition.top, right: commentMenuPosition.right },
4967
5414
  onPointerDown: (event) => event.stopPropagation(),
4968
5415
  children: /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("button", { type: "button", role: "menuitem", className: "mesurer-comment-menu-danger msr:flex msr:w-full msr:rounded-[4px] msr:px-2 msr:py-1.5 msr:text-left msr:text-[12px] msr:text-red-600 msr:hover:bg-red-50", onClick: (event) => {
4969
5416
  event.stopPropagation();
@@ -4981,7 +5428,7 @@ function CommentsPanel({
4981
5428
  "data-mesurer-comment-actions": true,
4982
5429
  "data-mesurer-comment-ui": true,
4983
5430
  className: "mesurer-comment-overflow-menu msr:pointer-events-auto msr:fixed msr:z-[100] msr:w-40 msr:rounded-md msr:bg-white msr:p-1 msr:shadow-floating",
4984
- style: { position: "fixed", zIndex: 100, pointerEvents: "auto", width: "10rem", top: listMenuPosition.top, right: listMenuPosition.right },
5431
+ style: { position: "fixed", zIndex: 120, pointerEvents: "auto", width: "10rem", top: listMenuPosition.top, right: listMenuPosition.right },
4985
5432
  onPointerDown: (event) => event.stopPropagation(),
4986
5433
  children: [
4987
5434
  ["open", "resolved", "all"].map((filter) => /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(
@@ -5350,6 +5797,12 @@ var GUIDE_MENU_WIDTH = 176;
5350
5797
  var VIEWPORT_PADDING2 = 8;
5351
5798
  var TOOLBAR_HEIGHT = 40;
5352
5799
  var TOOLTIP_HEIGHT_WITH_GAP = 34;
5800
+ var floatingMenuStyle = (placement) => ({
5801
+ zIndex: 120,
5802
+ top: placement.top,
5803
+ bottom: placement.bottom,
5804
+ ...placement.left !== void 0 ? { left: placement.left } : { right: placement.right }
5805
+ });
5353
5806
  var getSettingsShortcut = (eventTarget) => /Mac|iPhone|iPad|iPod/.test(eventTarget.navigator.platform) ? "\u2318 ," : "Ctrl + ,";
5354
5807
  var toolGroupForMode = (mode, colorPickerActive) => {
5355
5808
  if (colorPickerActive) return "inspect";
@@ -5741,7 +6194,8 @@ function ToolbarComponent({
5741
6194
  anchorRef: settingsRef,
5742
6195
  eventTarget,
5743
6196
  open: settingsOpen,
5744
- refreshKey: `${position.x}:${position.y}`
6197
+ refreshKey: `${position.x}:${position.y}`,
6198
+ fixed: true
5745
6199
  });
5746
6200
  const { menuRef: commentsPanelRef, placement: commentsPlacement } = useSettingsMenuPlacement({
5747
6201
  anchorRef: commentButtonRef,
@@ -5751,6 +6205,33 @@ function ToolbarComponent({
5751
6205
  fixed: true
5752
6206
  });
5753
6207
  const recordingPanelOpen = Boolean(screenRecording.panel);
6208
+ const captureAnchorRef = (0, import_react21.useRef)(null);
6209
+ const colorPickerAnchorRef = (0, import_react21.useRef)(null);
6210
+ const [colorPickerShell, setColorPickerShell] = (0, import_react21.useState)(null);
6211
+ const { menuRef: guideMenuPortalRef, placement: guideMenuPortalPlacement } = useSettingsMenuPlacement({
6212
+ anchorRef: guideMenuButtonRef,
6213
+ eventTarget,
6214
+ open: recordingPanelOpen && guideMenuOpen,
6215
+ refreshKey: `${position.x}:${position.y}:${menuAlign}`,
6216
+ fixed: true,
6217
+ align: menuAlign
6218
+ });
6219
+ const { menuRef: captureMenuPortalRef, placement: captureMenuPortalPlacement } = useSettingsMenuPlacement({
6220
+ anchorRef: captureAnchorRef,
6221
+ eventTarget,
6222
+ open: recordingPanelOpen && captureMenuOpen,
6223
+ refreshKey: `${position.x}:${position.y}`,
6224
+ fixed: true,
6225
+ align: "right"
6226
+ });
6227
+ const { menuRef: commentDropdownPortalRef, placement: commentDropdownPlacement } = useSettingsMenuPlacement({
6228
+ anchorRef: commentButtonRef,
6229
+ eventTarget,
6230
+ open: recordingPanelOpen && commentMenuOpen && !commentsPanelOpen,
6231
+ refreshKey: `${position.x}:${position.y}`,
6232
+ fixed: true,
6233
+ align: "right"
6234
+ });
5754
6235
  const { menuRef: recordingPanelRef, placement: recordingPlacement } = useSettingsMenuPlacement({
5755
6236
  anchorRef: settingsRef,
5756
6237
  eventTarget,
@@ -5766,6 +6247,26 @@ function ToolbarComponent({
5766
6247
  refreshKey: `${position.x}:${position.y}`,
5767
6248
  fixed: true
5768
6249
  });
6250
+ (0, import_react21.useLayoutEffect)(() => {
6251
+ if (!recordingPanelOpen || !colorPickerActive) {
6252
+ setColorPickerShell(null);
6253
+ return;
6254
+ }
6255
+ const place = () => {
6256
+ const anchor = colorPickerAnchorRef.current;
6257
+ const tool = anchor?.querySelector("[data-tool-id='color-picker']") ?? anchor;
6258
+ if (!(tool instanceof HTMLElement)) return;
6259
+ const rect = tool.getBoundingClientRect();
6260
+ setColorPickerShell({ left: rect.left, top: rect.bottom, width: rect.width });
6261
+ };
6262
+ place();
6263
+ eventTarget.addEventListener("resize", place);
6264
+ eventTarget.addEventListener("scroll", place, true);
6265
+ return () => {
6266
+ eventTarget.removeEventListener("resize", place);
6267
+ eventTarget.removeEventListener("scroll", place, true);
6268
+ };
6269
+ }, [colorPickerActive, eventTarget, position.x, position.y, recordingPanelOpen]);
5769
6270
  const selectMode = (0, import_react21.useCallback)(() => {
5770
6271
  onCancelTransient();
5771
6272
  clearSelection();
@@ -6214,123 +6715,129 @@ function ToolbarComponent({
6214
6715
  anchorRef: guideMenuRef
6215
6716
  }
6216
6717
  ),
6217
- guideMenuOpen ? /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)(
6218
- ToolbarMenu,
6219
- {
6220
- side: menuSide,
6221
- align: menuAlign,
6222
- tabIndex: 0,
6223
- onKeyDown: (event) => {
6224
- const key = event.key.toLowerCase();
6225
- const itemCount = features.rulers ? 3 : 2;
6226
- const horizontalIndex = features.rulers ? 1 : 0;
6227
- const verticalIndex = features.rulers ? 2 : 1;
6228
- if (event.key === "ArrowDown") {
6229
- event.preventDefault();
6230
- setActiveMenuIndex((prev) => (prev + 1) % itemCount);
6231
- }
6232
- if (event.key === "ArrowUp") {
6233
- event.preventDefault();
6234
- setActiveMenuIndex((prev) => (prev - 1 + itemCount) % itemCount);
6235
- }
6236
- if (event.key === "Enter") {
6237
- event.preventDefault();
6238
- if (features.rulers && activeMenuIndex === 0) selectRulers();
6239
- else if (activeMenuIndex === horizontalIndex) selectGuideOrientation("horizontal");
6240
- else if (activeMenuIndex === verticalIndex) selectGuideOrientation("vertical");
6241
- }
6242
- if (features.rulers && key === "r") {
6243
- event.preventDefault();
6244
- selectRulers();
6245
- }
6246
- if (key === "h") {
6247
- event.preventDefault();
6248
- selectGuideOrientation("horizontal");
6249
- }
6250
- if (key === "v") {
6251
- event.preventDefault();
6252
- selectGuideOrientation("vertical");
6253
- }
6254
- if (event.key === "Escape") {
6255
- event.preventDefault();
6256
- event.stopPropagation();
6257
- setOpenMenu(null);
6258
- }
6259
- },
6260
- children: [
6261
- features.rulers ? /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)(
6262
- MenuItem,
6263
- {
6264
- className: cn(
6265
- "msr:group msr:flex msr:w-full msr:items-center msr:gap-2 msr:rounded-[4px] msr:px-2 msr:py-1 msr:text-left msr:text-[11px] msr:leading-4",
6266
- activeMenuIndex === 0 || guideControl === "rulers" ? "msr:bg-[#0d99ff] msr:text-white" : "msr:text-ink-700 msr:hover:bg-[#0d99ff] msr:hover:text-white"
6267
- ),
6268
- onClick: () => selectRulers(),
6269
- children: [
6270
- /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
6271
- CheckIcon,
6272
- {
6273
- size: 12,
6274
- className: cn(guideControl === "rulers" ? "msr:opacity-100" : "msr:opacity-0")
6275
- }
6276
- ),
6277
- /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(MeasureLIcon, { size: 12 }),
6278
- /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("span", { className: "msr:flex-1", children: "Rulers" }),
6279
- /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("span", { children: "R" })
6280
- ]
6718
+ guideMenuOpen ? (() => {
6719
+ const menu = /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)(
6720
+ ToolbarMenu,
6721
+ {
6722
+ ref: recordingPanelOpen ? guideMenuPortalRef : void 0,
6723
+ floating: recordingPanelOpen,
6724
+ floatingStyle: recordingPanelOpen ? floatingMenuStyle(guideMenuPortalPlacement) : void 0,
6725
+ side: menuSide,
6726
+ align: menuAlign,
6727
+ tabIndex: 0,
6728
+ onKeyDown: (event) => {
6729
+ const key = event.key.toLowerCase();
6730
+ const itemCount = features.rulers ? 3 : 2;
6731
+ const horizontalIndex = features.rulers ? 1 : 0;
6732
+ const verticalIndex = features.rulers ? 2 : 1;
6733
+ if (event.key === "ArrowDown") {
6734
+ event.preventDefault();
6735
+ setActiveMenuIndex((prev) => (prev + 1) % itemCount);
6281
6736
  }
6282
- ) : null,
6283
- /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)(
6284
- MenuItem,
6285
- {
6286
- className: cn(
6287
- "msr:group msr:flex msr:w-full msr:items-center msr:gap-2 msr:rounded-[4px] msr:px-2 msr:py-1 msr:text-left msr:text-[11px] msr:leading-4",
6288
- activeMenuIndex === (features.rulers ? 1 : 0) || guideControl === "guides" && guideOrientation === "horizontal" ? "msr:bg-[#0d99ff] msr:text-white" : "msr:text-ink-700 msr:hover:bg-[#0d99ff] msr:hover:text-white"
6289
- ),
6290
- onClick: () => selectGuideOrientation("horizontal"),
6291
- children: [
6292
- /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
6293
- CheckIcon,
6294
- {
6295
- size: 12,
6296
- className: cn(
6297
- guideControl === "guides" && guideOrientation === "horizontal" ? "msr:opacity-100" : "msr:opacity-0"
6298
- )
6299
- }
6300
- ),
6301
- /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(MinusIcon, { size: 12 }),
6302
- /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("span", { className: "msr:flex-1", children: "Horizontal" }),
6303
- /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("span", { children: "H" })
6304
- ]
6737
+ if (event.key === "ArrowUp") {
6738
+ event.preventDefault();
6739
+ setActiveMenuIndex((prev) => (prev - 1 + itemCount) % itemCount);
6305
6740
  }
6306
- ),
6307
- /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)(
6308
- MenuItem,
6309
- {
6310
- className: cn(
6311
- "msr:group msr:flex msr:w-full msr:items-center msr:gap-2 msr:rounded-[4px] msr:px-2 msr:py-1 msr:text-left msr:text-[11px] msr:leading-4",
6312
- activeMenuIndex === (features.rulers ? 2 : 1) || guideControl === "guides" && guideOrientation === "vertical" ? "msr:bg-[#0d99ff] msr:text-white" : "msr:text-ink-700 msr:hover:bg-[#0d99ff] msr:hover:text-white"
6313
- ),
6314
- onClick: () => selectGuideOrientation("vertical"),
6315
- children: [
6316
- /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
6317
- CheckIcon,
6318
- {
6319
- size: 12,
6320
- className: cn(
6321
- guideControl === "guides" && guideOrientation === "vertical" ? "msr:opacity-100" : "msr:opacity-0"
6322
- )
6323
- }
6324
- ),
6325
- /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(MinusIcon, { size: 12, className: "msr:rotate-90" }),
6326
- /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("span", { className: "msr:flex-1", children: "Vertical" }),
6327
- /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("span", { children: "V" })
6328
- ]
6741
+ if (event.key === "Enter") {
6742
+ event.preventDefault();
6743
+ if (features.rulers && activeMenuIndex === 0) selectRulers();
6744
+ else if (activeMenuIndex === horizontalIndex) selectGuideOrientation("horizontal");
6745
+ else if (activeMenuIndex === verticalIndex) selectGuideOrientation("vertical");
6329
6746
  }
6330
- )
6331
- ]
6332
- }
6333
- ) : null
6747
+ if (features.rulers && key === "r") {
6748
+ event.preventDefault();
6749
+ selectRulers();
6750
+ }
6751
+ if (key === "h") {
6752
+ event.preventDefault();
6753
+ selectGuideOrientation("horizontal");
6754
+ }
6755
+ if (key === "v") {
6756
+ event.preventDefault();
6757
+ selectGuideOrientation("vertical");
6758
+ }
6759
+ if (event.key === "Escape") {
6760
+ event.preventDefault();
6761
+ event.stopPropagation();
6762
+ setOpenMenu(null);
6763
+ }
6764
+ },
6765
+ children: [
6766
+ features.rulers ? /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)(
6767
+ MenuItem,
6768
+ {
6769
+ className: cn(
6770
+ "msr:group msr:flex msr:w-full msr:items-center msr:gap-2 msr:rounded-[4px] msr:px-2 msr:py-1 msr:text-left msr:text-[11px] msr:leading-4",
6771
+ activeMenuIndex === 0 || guideControl === "rulers" ? "msr:bg-[#0d99ff] msr:text-white" : "msr:text-ink-700 msr:hover:bg-[#0d99ff] msr:hover:text-white"
6772
+ ),
6773
+ onClick: () => selectRulers(),
6774
+ children: [
6775
+ /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
6776
+ CheckIcon,
6777
+ {
6778
+ size: 12,
6779
+ className: cn(guideControl === "rulers" ? "msr:opacity-100" : "msr:opacity-0")
6780
+ }
6781
+ ),
6782
+ /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(MeasureLIcon, { size: 12 }),
6783
+ /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("span", { className: "msr:flex-1", children: "Rulers" }),
6784
+ /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("span", { children: "R" })
6785
+ ]
6786
+ }
6787
+ ) : null,
6788
+ /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)(
6789
+ MenuItem,
6790
+ {
6791
+ className: cn(
6792
+ "msr:group msr:flex msr:w-full msr:items-center msr:gap-2 msr:rounded-[4px] msr:px-2 msr:py-1 msr:text-left msr:text-[11px] msr:leading-4",
6793
+ activeMenuIndex === (features.rulers ? 1 : 0) || guideControl === "guides" && guideOrientation === "horizontal" ? "msr:bg-[#0d99ff] msr:text-white" : "msr:text-ink-700 msr:hover:bg-[#0d99ff] msr:hover:text-white"
6794
+ ),
6795
+ onClick: () => selectGuideOrientation("horizontal"),
6796
+ children: [
6797
+ /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
6798
+ CheckIcon,
6799
+ {
6800
+ size: 12,
6801
+ className: cn(
6802
+ guideControl === "guides" && guideOrientation === "horizontal" ? "msr:opacity-100" : "msr:opacity-0"
6803
+ )
6804
+ }
6805
+ ),
6806
+ /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(MinusIcon, { size: 12 }),
6807
+ /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("span", { className: "msr:flex-1", children: "Horizontal" }),
6808
+ /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("span", { children: "H" })
6809
+ ]
6810
+ }
6811
+ ),
6812
+ /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)(
6813
+ MenuItem,
6814
+ {
6815
+ className: cn(
6816
+ "msr:group msr:flex msr:w-full msr:items-center msr:gap-2 msr:rounded-[4px] msr:px-2 msr:py-1 msr:text-left msr:text-[11px] msr:leading-4",
6817
+ activeMenuIndex === (features.rulers ? 2 : 1) || guideControl === "guides" && guideOrientation === "vertical" ? "msr:bg-[#0d99ff] msr:text-white" : "msr:text-ink-700 msr:hover:bg-[#0d99ff] msr:hover:text-white"
6818
+ ),
6819
+ onClick: () => selectGuideOrientation("vertical"),
6820
+ children: [
6821
+ /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
6822
+ CheckIcon,
6823
+ {
6824
+ size: 12,
6825
+ className: cn(
6826
+ guideControl === "guides" && guideOrientation === "vertical" ? "msr:opacity-100" : "msr:opacity-0"
6827
+ )
6828
+ }
6829
+ ),
6830
+ /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(MinusIcon, { size: 12, className: "msr:rotate-90" }),
6831
+ /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("span", { className: "msr:flex-1", children: "Vertical" }),
6832
+ /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("span", { children: "V" })
6833
+ ]
6834
+ }
6835
+ )
6836
+ ]
6837
+ }
6838
+ );
6839
+ return recordingPanelOpen ? (0, import_react_dom4.createPortal)(menu, commentPanelPortalTarget) : menu;
6840
+ })() : null
6334
6841
  ]
6335
6842
  }
6336
6843
  ),
@@ -6358,6 +6865,7 @@ function ToolbarComponent({
6358
6865
  ref: layoutGuidesMenuRef,
6359
6866
  className: "mesurer-menu-surface msr:pointer-events-auto msr:fixed msr:z-[100] msr:flex msr:w-60 msr:flex-col msr:overflow-hidden msr:rounded-lg msr:bg-white msr:p-0 msr:shadow-floating",
6360
6867
  style: {
6868
+ zIndex: recordingPanelOpen ? 120 : void 0,
6361
6869
  top: layoutGuidesPlacement.top,
6362
6870
  bottom: layoutGuidesPlacement.bottom,
6363
6871
  right: layoutGuidesPlacement.right,
@@ -6383,7 +6891,7 @@ function ToolbarComponent({
6383
6891
  commentPanelPortalTarget
6384
6892
  ) : null
6385
6893
  ] }),
6386
- /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("div", { className: "msr:relative msr:flex", children: [
6894
+ /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("div", { ref: colorPickerAnchorRef, className: "msr:relative msr:flex", children: [
6387
6895
  /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
6388
6896
  ToolbarButton,
6389
6897
  {
@@ -6397,7 +6905,23 @@ function ToolbarComponent({
6397
6905
  children: /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(DropperIcon, { size: 20, "aria-hidden": "true" })
6398
6906
  }
6399
6907
  ),
6400
- colorPicker.panel
6908
+ recordingPanelOpen && colorPickerActive ? (0, import_react_dom4.createPortal)(
6909
+ /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
6910
+ "div",
6911
+ {
6912
+ className: "msr:pointer-events-none msr:fixed msr:z-[120]",
6913
+ style: {
6914
+ left: colorPickerShell?.left ?? 0,
6915
+ top: colorPickerShell?.top ?? 0,
6916
+ width: colorPickerShell?.width,
6917
+ height: 0,
6918
+ visibility: colorPickerShell ? "visible" : "hidden"
6919
+ },
6920
+ children: /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("div", { className: "msr:pointer-events-auto", children: colorPicker.panel })
6921
+ }
6922
+ ),
6923
+ commentPanelPortalTarget
6924
+ ) : colorPicker.panel
6401
6925
  ] })
6402
6926
  ] }) })
6403
6927
  }
@@ -6472,7 +6996,7 @@ function ToolbarComponent({
6472
6996
  /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("div", { ref: trailingRef, className: "mesurer-toolbar-trailing msr:flex msr:items-stretch", children: [
6473
6997
  /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(ToolbarDivider, {}),
6474
6998
  /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)(ToolbarGroup, { label: "Capture and settings", className: "msr:px-1", children: [
6475
- /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("div", { className: "msr:relative msr:flex msr:flex-none", children: [
6999
+ /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("div", { ref: captureAnchorRef, className: "msr:relative msr:flex msr:flex-none", children: [
6476
7000
  features.screenshot ? /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)(import_jsx_runtime42.Fragment, { children: [
6477
7001
  /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
6478
7002
  ToolbarButton,
@@ -6516,50 +7040,56 @@ function ToolbarComponent({
6516
7040
  children: /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(CaretDownIcon, { size: 8, "aria-hidden": "true" })
6517
7041
  }
6518
7042
  ),
6519
- captureMenuOpen ? /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)(
6520
- ToolbarMenu,
6521
- {
6522
- side: menuSide,
6523
- align: "right",
6524
- onKeyDown: (event) => {
6525
- if (event.key !== "Escape") return;
6526
- event.preventDefault();
6527
- event.stopPropagation();
6528
- setOpenMenu(null);
6529
- },
6530
- children: [
6531
- /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)(
6532
- ToolbarMenuItem,
6533
- {
6534
- onClick: () => {
6535
- setOpenMenu(null);
6536
- screenshotMode();
6537
- },
6538
- children: [
6539
- /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(CameraIcon, { size: 12 }),
6540
- /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("span", { className: "msr:flex-1", children: "Screenshot" }),
6541
- /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("span", { children: "C" })
6542
- ]
6543
- }
6544
- ),
6545
- /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)(
6546
- ToolbarMenuItem,
6547
- {
6548
- onClick: () => {
6549
- setOpenMenu(null);
6550
- if (recording) onScreenRecordingStop();
6551
- else recordMode();
6552
- },
6553
- children: [
6554
- /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(RecordIcon, { size: 12 }),
6555
- /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("span", { className: "msr:flex-1", children: recording ? "Stop recording" : "Screen record" }),
6556
- /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("span", { children: "V" })
6557
- ]
6558
- }
6559
- )
6560
- ]
6561
- }
6562
- ) : null
7043
+ captureMenuOpen ? (() => {
7044
+ const menu = /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)(
7045
+ ToolbarMenu,
7046
+ {
7047
+ ref: recordingPanelOpen ? captureMenuPortalRef : void 0,
7048
+ floating: recordingPanelOpen,
7049
+ floatingStyle: recordingPanelOpen ? floatingMenuStyle(captureMenuPortalPlacement) : void 0,
7050
+ side: menuSide,
7051
+ align: "right",
7052
+ onKeyDown: (event) => {
7053
+ if (event.key !== "Escape") return;
7054
+ event.preventDefault();
7055
+ event.stopPropagation();
7056
+ setOpenMenu(null);
7057
+ },
7058
+ children: [
7059
+ /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)(
7060
+ ToolbarMenuItem,
7061
+ {
7062
+ onClick: () => {
7063
+ setOpenMenu(null);
7064
+ screenshotMode();
7065
+ },
7066
+ children: [
7067
+ /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(CameraIcon, { size: 12 }),
7068
+ /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("span", { className: "msr:flex-1", children: "Screenshot" }),
7069
+ /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("span", { children: "C" })
7070
+ ]
7071
+ }
7072
+ ),
7073
+ /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)(
7074
+ ToolbarMenuItem,
7075
+ {
7076
+ onClick: () => {
7077
+ setOpenMenu(null);
7078
+ if (recording) onScreenRecordingStop();
7079
+ else recordMode();
7080
+ },
7081
+ children: [
7082
+ /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(RecordIcon, { size: 12 }),
7083
+ /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("span", { className: "msr:flex-1", children: recording ? "Stop recording" : "Screen record" }),
7084
+ /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("span", { children: "V" })
7085
+ ]
7086
+ }
7087
+ )
7088
+ ]
7089
+ }
7090
+ );
7091
+ return recordingPanelOpen ? (0, import_react_dom4.createPortal)(menu, commentPanelPortalTarget) : menu;
7092
+ })() : null
6563
7093
  ] }),
6564
7094
  /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("div", { ref: commentMenuRef, className: "msr:relative msr:flex msr:flex-none", "data-mesurer-comment-ui": true, children: [
6565
7095
  /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
@@ -6615,9 +7145,38 @@ function ToolbarComponent({
6615
7145
  if (toolMode !== "comments") preserveToolGroupRef.current = true;
6616
7146
  onSelectComment(id);
6617
7147
  },
6618
- fixed: true
7148
+ fixed: true,
7149
+ fixedZIndex: recordingPanelOpen ? 120 : 100
6619
7150
  }
6620
- ), commentPanelPortalTarget) : /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
7151
+ ), commentPanelPortalTarget) : recordingPanelOpen ? (0, import_react_dom4.createPortal)(
7152
+ /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
7153
+ MenuSurface,
7154
+ {
7155
+ ref: commentDropdownPortalRef,
7156
+ className: "msr:pointer-events-auto msr:fixed msr:flex msr:w-44 msr:flex-col msr:gap-px",
7157
+ style: floatingMenuStyle(commentDropdownPlacement),
7158
+ "data-mesurer-comment-ui": true,
7159
+ children: /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)(import_jsx_runtime42.Fragment, { children: [
7160
+ /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(MenuItem, { disabled: commentCount === 0, onClick: openCommentsPanel, children: /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("span", { className: "msr:flex-1", children: "Show all comments" }) }),
7161
+ /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)(
7162
+ MenuItem,
7163
+ {
7164
+ disabled: commentCount === 0,
7165
+ onClick: () => {
7166
+ void onCopyComments();
7167
+ setOpenMenu(null);
7168
+ },
7169
+ children: [
7170
+ /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("span", { className: "msr:flex-1", children: "Copy comments" }),
7171
+ commentsCopied ? /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(CheckIcon, { size: 12 }) : /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("span", { children: copyCommentsShortcut })
7172
+ ]
7173
+ }
7174
+ )
7175
+ ] })
7176
+ }
7177
+ ),
7178
+ commentPanelPortalTarget
7179
+ ) : /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
6621
7180
  MenuSurface,
6622
7181
  {
6623
7182
  className: cn(
@@ -6663,29 +7222,31 @@ function ToolbarComponent({
6663
7222
  children: /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(SettingsIcon, { size: 20, "aria-hidden": "true" })
6664
7223
  }
6665
7224
  ),
6666
- settingsOpen ? /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
6667
- "div",
6668
- {
6669
- ref: settingsMenuRef,
6670
- className: cn(
6671
- "mesurer-menu-surface msr:absolute msr:z-[95] msr:flex msr:w-auto msr:max-w-[calc(100vw-16px)] msr:flex-col msr:overflow-hidden msr:rounded-lg msr:bg-white msr:p-0 msr:shadow-floating",
6672
- settingsPlacement.side === "bottom" ? "msr:top-full msr:mt-2" : "msr:bottom-full msr:mb-2"
6673
- ),
6674
- style: {
6675
- right: settingsPlacement.right,
6676
- height: settingsPlacement.height,
6677
- maxHeight: settingsPlacement.height
6678
- },
6679
- "data-mesurer-inspector-ui": "true",
6680
- "data-mesurer-settings-panel": true,
6681
- role: "dialog",
6682
- "aria-label": "Settings",
6683
- onPointerDown: (event) => event.stopPropagation(),
6684
- onPointerMove: (event) => event.stopPropagation(),
6685
- onPointerUp: (event) => event.stopPropagation(),
6686
- onClick: (event) => event.stopPropagation(),
6687
- children: settingsPanel
6688
- }
7225
+ settingsOpen ? (0, import_react_dom4.createPortal)(
7226
+ /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
7227
+ "div",
7228
+ {
7229
+ ref: settingsMenuRef,
7230
+ className: "mesurer-menu-surface msr:pointer-events-auto msr:fixed msr:z-[120] msr:flex msr:w-auto msr:max-w-[calc(100vw-16px)] msr:flex-col msr:overflow-hidden msr:rounded-lg msr:bg-white msr:p-0 msr:shadow-floating",
7231
+ style: {
7232
+ top: settingsPlacement.top,
7233
+ bottom: settingsPlacement.bottom,
7234
+ right: settingsPlacement.right,
7235
+ height: settingsPlacement.height,
7236
+ maxHeight: settingsPlacement.height
7237
+ },
7238
+ "data-mesurer-inspector-ui": "true",
7239
+ "data-mesurer-settings-panel": true,
7240
+ role: "dialog",
7241
+ "aria-label": "Settings",
7242
+ onPointerDown: (event) => event.stopPropagation(),
7243
+ onPointerMove: (event) => event.stopPropagation(),
7244
+ onPointerUp: (event) => event.stopPropagation(),
7245
+ onClick: (event) => event.stopPropagation(),
7246
+ children: settingsPanel
7247
+ }
7248
+ ),
7249
+ commentPanelPortalTarget
6689
7250
  ) : null
6690
7251
  ] }) : null
6691
7252
  ] })
@@ -6799,11 +7360,11 @@ var getDirectTextRangeAtPoint = (control, point, ownerDocument) => {
6799
7360
  const container = range.startContainer;
6800
7361
  if (container.nodeType !== Node.TEXT_NODE) return null;
6801
7362
  if (!control.contains(container)) return null;
6802
- const text = container.nodeValue ?? "";
6803
- const trimmed = text.trim();
7363
+ const text2 = container.nodeValue ?? "";
7364
+ const trimmed = text2.trim();
6804
7365
  if (!trimmed) return null;
6805
7366
  const textRange = ownerDocument.createRange();
6806
- const start = text.indexOf(trimmed);
7367
+ const start = text2.indexOf(trimmed);
6807
7368
  if (start < 0) return null;
6808
7369
  textRange.setStart(container, start);
6809
7370
  textRange.setEnd(container, start + trimmed.length);
@@ -7429,24 +7990,24 @@ var lineOrientation = (rect) => {
7429
7990
  if (rect.height < 1 && rect.width >= 1) return "horizontal";
7430
7991
  return null;
7431
7992
  };
7432
- var measureLineToBox = (line, box, orientation) => {
7433
- const boxRight = box.left + box.width;
7434
- const boxBottom = box.top + box.height;
7993
+ var measureLineToBox = (line, box2, orientation) => {
7994
+ const boxRight = box2.left + box2.width;
7995
+ const boxBottom = box2.top + box2.height;
7435
7996
  let horizontal = null;
7436
7997
  let vertical = null;
7437
7998
  const extraHorizontals = [];
7438
7999
  const extraVerticals = [];
7439
8000
  if (orientation === "vertical") {
7440
8001
  const x = line.left;
7441
- const y = box.top + box.height / 2;
7442
- if (x <= box.left) {
7443
- horizontal = { x1: x, x2: box.left, y, value: box.left - x };
8002
+ const y = box2.top + box2.height / 2;
8003
+ if (x <= box2.left) {
8004
+ horizontal = { x1: x, x2: box2.left, y, value: box2.left - x };
7444
8005
  } else if (x >= boxRight) {
7445
8006
  horizontal = { x1: boxRight, x2: x, y, value: x - boxRight };
7446
8007
  } else {
7447
- const toLeft = x - box.left;
8008
+ const toLeft = x - box2.left;
7448
8009
  const toRight = boxRight - x;
7449
- if (toLeft > 0.5) horizontal = { x1: box.left, x2: x, y, value: toLeft };
8010
+ if (toLeft > 0.5) horizontal = { x1: box2.left, x2: x, y, value: toLeft };
7450
8011
  if (toRight > 0.5) {
7451
8012
  const right = { x1: x, x2: boxRight, y, value: toRight };
7452
8013
  if (horizontal) extraHorizontals.push(right);
@@ -7455,15 +8016,15 @@ var measureLineToBox = (line, box, orientation) => {
7455
8016
  }
7456
8017
  } else {
7457
8018
  const y = line.top;
7458
- const x = box.left + box.width / 2;
7459
- if (y <= box.top) {
7460
- vertical = { y1: y, y2: box.top, x, value: box.top - y };
8019
+ const x = box2.left + box2.width / 2;
8020
+ if (y <= box2.top) {
8021
+ vertical = { y1: y, y2: box2.top, x, value: box2.top - y };
7461
8022
  } else if (y >= boxBottom) {
7462
8023
  vertical = { y1: boxBottom, y2: y, x, value: y - boxBottom };
7463
8024
  } else {
7464
- const toTop = y - box.top;
8025
+ const toTop = y - box2.top;
7465
8026
  const toBottom = boxBottom - y;
7466
- if (toTop > 0.5) vertical = { y1: box.top, y2: y, x, value: toTop };
8027
+ if (toTop > 0.5) vertical = { y1: box2.top, y2: y, x, value: toTop };
7467
8028
  if (toBottom > 0.5) {
7468
8029
  const bottom = { y1: y, y2: boxBottom, x, value: toBottom };
7469
8030
  if (vertical) extraVerticals.push(bottom);
@@ -7495,9 +8056,9 @@ var getDistanceOverlay = (rectA, rectB, elementRefA, elementRefB, ownerWindow =
7495
8056
  if (Boolean(lineA) !== Boolean(lineB)) {
7496
8057
  const orientation = lineA ?? lineB;
7497
8058
  const line = lineA ? rectA : rectB;
7498
- const box = lineA ? rectB : rectA;
8059
+ const box2 = lineA ? rectB : rectA;
7499
8060
  if (orientation) {
7500
- const measured = measureLineToBox(line, box, orientation);
8061
+ const measured = measureLineToBox(line, box2, orientation);
7501
8062
  horizontal = measured.horizontal;
7502
8063
  vertical = measured.vertical;
7503
8064
  extraHorizontals = measured.extraHorizontals.length > 0 ? measured.extraHorizontals : void 0;
@@ -8985,9 +9546,9 @@ var transformedArrowBounds = (arrow) => {
8985
9546
  return rotatedBounds(arrowBounds(arrow), arrow.rotation ?? 0);
8986
9547
  };
8987
9548
  var resizeArrow = (arrow, handle, pointer) => {
8988
- const box = arrowBounds(arrow);
9549
+ const box2 = arrowBounds(arrow);
8989
9550
  const rotation = arrow.rotation ?? 0;
8990
- const geometry = resizeGeometry(box, rotation, handle, pointer);
9551
+ const geometry = resizeGeometry(box2, rotation, handle, pointer);
8991
9552
  const points = [arrow.start, arrow.control ?? { x: (arrow.start.x + arrow.end.x) / 2, y: (arrow.start.y + arrow.end.y) / 2 }, arrow.end];
8992
9553
  const nextPoints = points.map((point) => resizePoint(point, geometry));
8993
9554
  return { ...arrow, start: nextPoints[0], control: nextPoints[1], end: nextPoints[2] };
@@ -9777,10 +10338,10 @@ function TextItem({
9777
10338
  }
9778
10339
  }, [editing, item.text]);
9779
10340
  const measureBox = () => {
9780
- const box = boxRef.current;
10341
+ const box2 = boxRef.current;
9781
10342
  return {
9782
- width: box?.offsetWidth ?? 32,
9783
- height: box?.offsetHeight ?? 24
10343
+ width: box2?.offsetWidth ?? 32,
10344
+ height: box2?.offsetHeight ?? 24
9784
10345
  };
9785
10346
  };
9786
10347
  const pointerPage = (event) => ({
@@ -9969,9 +10530,9 @@ var movePenStroke = (stroke, dx, dy) => ({
9969
10530
  points: stroke.points.map((point) => ({ x: point.x + dx, y: point.y + dy }))
9970
10531
  });
9971
10532
  var resizePenStroke = (stroke, handle, pointer) => {
9972
- const box = penBounds(stroke);
10533
+ const box2 = penBounds(stroke);
9973
10534
  const rotation = stroke.rotation ?? 0;
9974
- const geometry = resizeGeometry(box, rotation, handle, pointer);
10535
+ const geometry = resizeGeometry(box2, rotation, handle, pointer);
9975
10536
  return {
9976
10537
  ...stroke,
9977
10538
  points: stroke.points.map((point) => {
@@ -9981,8 +10542,8 @@ var resizePenStroke = (stroke, handle, pointer) => {
9981
10542
  };
9982
10543
  };
9983
10544
  var rotatePenStroke = (stroke, pointer, offset) => {
9984
- const box = penBounds(stroke);
9985
- const center = boxCenter(box.x, box.y, box.width, box.height);
10545
+ const box2 = penBounds(stroke);
10546
+ const center = boxCenter(box2.x, box2.y, box2.width, box2.height);
9986
10547
  const nextRotation = rotationFromPointer(center, pointer) - offset;
9987
10548
  return {
9988
10549
  ...stroke,
@@ -9990,8 +10551,8 @@ var rotatePenStroke = (stroke, pointer, offset) => {
9990
10551
  };
9991
10552
  };
9992
10553
  var rotatePenStrokeAround = (stroke, center, degrees) => {
9993
- const box = penBounds(stroke);
9994
- const strokeCenter = boxCenter(box.x, box.y, box.width, box.height);
10554
+ const box2 = penBounds(stroke);
10555
+ const strokeCenter = boxCenter(box2.x, box2.y, box2.width, box2.height);
9995
10556
  const rotation = stroke.rotation ?? 0;
9996
10557
  const nextCenter = rotatePoint(strokeCenter, center, degrees);
9997
10558
  const nextRotation = rotation + degrees;
@@ -10127,8 +10688,8 @@ var PenLayer = (0, import_react28.memo)(function PenLayer2({
10127
10688
  const startRotate = (stroke, event) => {
10128
10689
  event.preventDefault();
10129
10690
  event.stopPropagation();
10130
- const box = penBounds(stroke);
10131
- const center = boxCenter(box.x, box.y, box.width, box.height);
10691
+ const box2 = penBounds(stroke);
10692
+ const center = boxCenter(box2.x, box2.y, box2.width, box2.height);
10132
10693
  onChangeStart();
10133
10694
  dragRef.current = { id: stroke.id, type: "rotate", start: pointerPage(event), stroke, offset: rotationFromPointer(center, pointerPage(event)) - (stroke.rotation ?? 0) };
10134
10695
  trackDrag(event);
@@ -10153,9 +10714,9 @@ var PenLayer = (0, import_react28.memo)(function PenLayer2({
10153
10714
  preview.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime57.jsx)("path", { d: pathForPoints(translate(preview)), fill: "none", stroke: "#0d99ff", strokeWidth: 2, strokeLinecap: "round", strokeLinejoin: "round", opacity: 0.65, "data-mesurer-pen-preview": "true" }) : null
10154
10715
  ] }),
10155
10716
  selectionMode ? selectedStrokes.map((stroke) => {
10156
- const box = penBounds(stroke);
10717
+ const box2 = penBounds(stroke);
10157
10718
  const showControls = selectionCount === 1;
10158
- return /* @__PURE__ */ (0, import_jsx_runtime57.jsx)("div", { className: `msr:absolute ${showControls ? "msr:pointer-events-auto msr:cursor-move" : "msr:pointer-events-none"}`, style: { left: box.x - scrollOffset.x + (selectedIds.includes(stroke.id) ? moveOffset.x : 0), top: box.y - scrollOffset.y + (selectedIds.includes(stroke.id) ? moveOffset.y : 0), width: box.width, height: box.height, transform: `rotate(${stroke.rotation ?? 0}deg)`, transformOrigin: "center center" }, onPointerDown: showControls ? (event) => startMove(stroke, event) : void 0, children: /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(TextTransformFrame, { frameDataAttribute: "data-mesurer-pen-frame", handleDataAttribute: "data-mesurer-pen-handle", rotation: stroke.rotation ?? 0, showControls, showOutline: true, onResizeStart: (handle, event) => startResize2(stroke, handle, event), onRotateStart: (event) => startRotate(stroke, event) }) }, stroke.id);
10719
+ return /* @__PURE__ */ (0, import_jsx_runtime57.jsx)("div", { className: `msr:absolute ${showControls ? "msr:pointer-events-auto msr:cursor-move" : "msr:pointer-events-none"}`, style: { left: box2.x - scrollOffset.x + (selectedIds.includes(stroke.id) ? moveOffset.x : 0), top: box2.y - scrollOffset.y + (selectedIds.includes(stroke.id) ? moveOffset.y : 0), width: box2.width, height: box2.height, transform: `rotate(${stroke.rotation ?? 0}deg)`, transformOrigin: "center center" }, onPointerDown: showControls ? (event) => startMove(stroke, event) : void 0, children: /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(TextTransformFrame, { frameDataAttribute: "data-mesurer-pen-frame", handleDataAttribute: "data-mesurer-pen-handle", rotation: stroke.rotation ?? 0, showControls, showOutline: true, onResizeStart: (handle, event) => startResize2(stroke, handle, event), onRotateStart: (event) => startRotate(stroke, event) }) }, stroke.id);
10159
10720
  }) : null
10160
10721
  ] });
10161
10722
  });
@@ -10498,8 +11059,8 @@ function CommentComposer({
10498
11059
  // comments/export.ts
10499
11060
  var formatTarget = (comment) => {
10500
11061
  const { target } = comment;
10501
- const text = target.textSnippet ? `${target.textSnippet}` : "";
10502
- return `[<${target.tagName}>${text}</${target.tagName}> selector: \`${target.selector}\`]`;
11062
+ const text2 = target.textSnippet ? `${target.textSnippet}` : "";
11063
+ return `[<${target.tagName}>${text2}</${target.tagName}> selector: \`${target.selector}\`]`;
10503
11064
  };
10504
11065
  var formatCommentsForAgent = (comments, url = "", viewport) => {
10505
11066
  return [
@@ -11829,11 +12390,11 @@ function CommentsLayer({
11829
12390
  setMessageDeleteConfirmationId(null);
11830
12391
  },
11831
12392
  onCancelDeleteMessage: () => setMessageDeleteConfirmationId(null),
11832
- onSaveEdit: (messageId, text) => onEditMessage(selected.id, messageId, text),
12393
+ onSaveEdit: (messageId, text2) => onEditMessage(selected.id, messageId, text2),
11833
12394
  replyText,
11834
12395
  onReplyTextChange: setReplyText,
11835
- onAddMessage: (text) => {
11836
- onAddMessage(selected.id, text);
12396
+ onAddMessage: (text2) => {
12397
+ onAddMessage(selected.id, text2);
11837
12398
  setReplyText("");
11838
12399
  },
11839
12400
  onToggleResolved,
@@ -11922,7 +12483,7 @@ var MesurerOverlay = (0, import_react33.memo)(function MesurerOverlay2({
11922
12483
  distances,
11923
12484
  guides,
11924
12485
  arrows,
11925
- text,
12486
+ text: text2,
11926
12487
  pen,
11927
12488
  comments
11928
12489
  }) {
@@ -12002,7 +12563,7 @@ var MesurerOverlay = (0, import_react33.memo)(function MesurerOverlay2({
12002
12563
  }
12003
12564
  ),
12004
12565
  toolMode === "selection" && marqueeRect ? /* @__PURE__ */ (0, import_jsx_runtime65.jsx)(MarqueeRect, { rect: marqueeRect, color: outlineColor }) : null,
12005
- /* @__PURE__ */ (0, import_jsx_runtime65.jsx)(TextLayer, { ...text, selectionCount }),
12566
+ /* @__PURE__ */ (0, import_jsx_runtime65.jsx)(TextLayer, { ...text2, selectionCount }),
12006
12567
  /* @__PURE__ */ (0, import_jsx_runtime65.jsx)(PenLayer, { ...pen, selectionCount }),
12007
12568
  /* @__PURE__ */ (0, import_jsx_runtime65.jsx)(
12008
12569
  ArrowsLayer,
@@ -12742,7 +13303,7 @@ var useHotkeys = (options) => {
12742
13303
  }
12743
13304
  };
12744
13305
  const handleKeyboardBridge = (event) => {
12745
- if (event.source !== target || event.origin !== target.location.origin || !isMesurerKeyboardOwned(target)) return;
13306
+ if (event.source !== target && event.source !== null || event.origin !== target.location.origin && event.origin !== "null") return;
12746
13307
  const data = event.data;
12747
13308
  if (!isMesurerKeyboardBridge(data)) return;
12748
13309
  const signature = keyboardEventSignature(data.eventType, data);
@@ -12796,7 +13357,7 @@ var useOverlayKeyboard = ({
12796
13357
  }) => {
12797
13358
  (0, import_react39.useLayoutEffect)(() => {
12798
13359
  installKeyboardGate(eventTarget);
12799
- const claimedRef = { current: false };
13360
+ const claimedRef = { current: overlayActive };
12800
13361
  const owned = overlayActive && (claimedRef.current || isInsideMesurer(getDeepActiveElement(eventTarget)));
12801
13362
  setMesurerKeyboardOwned(eventTarget.document, owned);
12802
13363
  const onFocusIn = () => {
@@ -12807,7 +13368,7 @@ var useOverlayKeyboard = ({
12807
13368
  setMesurerKeyboardOwned(eventTarget.document, true);
12808
13369
  return;
12809
13370
  }
12810
- if (active instanceof Element && !isInsideMesurer(active)) {
13371
+ if (active instanceof Element && !isInsideMesurer(active) && isEditableElement(active)) {
12811
13372
  claimedRef.current = false;
12812
13373
  setMesurerKeyboardOwned(eventTarget.document, false);
12813
13374
  return;
@@ -12941,7 +13502,7 @@ var useInteractionLifecycle = (options) => {
12941
13502
  options.setRulersVisible(false);
12942
13503
  options.setToolMode("none");
12943
13504
  }, [clearTransientState, options]);
12944
- const keyboardOwned = options.enabled && !options.minimized && (options.toolMode !== "none" || options.toolbarActive);
13505
+ const keyboardOwned = options.enabled && !options.minimized;
12945
13506
  const overlayActive = options.enabled && (options.toolMode !== "none" || options.toolbarActive);
12946
13507
  useOverlayKeyboard({
12947
13508
  eventTarget: options.ownerWindow,
@@ -13269,7 +13830,7 @@ var normalizeStoredSettings = (value) => {
13269
13830
  ...typeof input.multiMeasureEnabled === "boolean" ? { multiMeasureEnabled: input.multiMeasureEnabled } : {},
13270
13831
  ...input.infoCardMode === "hover" || input.infoCardMode === "click" ? { infoCardMode: input.infoCardMode } : input.copySelectorOnInspect === true ? { infoCardMode: "click" } : {},
13271
13832
  ...typeof input.persistOnReload === "boolean" ? { persistOnReload: input.persistOnReload } : {},
13272
- ...typeof input.shortcutsEnabled === "boolean" ? { shortcutsEnabled: input.shortcutsEnabled } : {},
13833
+ shortcutsEnabled: typeof input.shortcutsEnabled === "boolean" ? input.shortcutsEnabled : true,
13273
13834
  ...input.theme === "system" || input.theme === "light" || input.theme === "dark" ? { theme: input.theme } : {},
13274
13835
  ...normalizeGuideStyle(input.guideStyle) ? { guideStyle: normalizeGuideStyle(input.guideStyle) } : {},
13275
13836
  ...normalizeRulerSettings(input.rulerSettings) ? { rulerSettings: normalizeRulerSettings(input.rulerSettings) } : {},
@@ -14167,7 +14728,7 @@ var useWorkspaceLifecycle = ({
14167
14728
 
14168
14729
  // hooks/use-overlay-pointer-handlers.ts
14169
14730
  var useOverlayPointerHandlers = (options) => {
14170
- const { toolMode, arrows, pen, text, comments, measure } = options;
14731
+ const { toolMode, arrows, pen, text: text2, comments, measure } = options;
14171
14732
  if (toolMode === "arrows") {
14172
14733
  return {
14173
14734
  onPointerDown: arrows.handlePointerDown,
@@ -14188,7 +14749,7 @@ var useOverlayPointerHandlers = (options) => {
14188
14749
  }
14189
14750
  if (toolMode === "text") {
14190
14751
  return {
14191
- onPointerDown: text.handlePointerDown,
14752
+ onPointerDown: text2.handlePointerDown,
14192
14753
  onPointerMove: measure.handlePointerMove,
14193
14754
  onPointerUp: measure.handlePointerUp,
14194
14755
  onPointerLeave: measure.handlePointerLeave,
@@ -14818,7 +15379,7 @@ var useMesurerHistory = ({
14818
15379
  measurements,
14819
15380
  guides,
14820
15381
  arrows,
14821
- text,
15382
+ text: text2,
14822
15383
  pen,
14823
15384
  comments,
14824
15385
  layoutGuides,
@@ -14863,7 +15424,7 @@ var useMesurerHistory = ({
14863
15424
  clearSelectionRect
14864
15425
  } = transient;
14865
15426
  const { arrows: arrowEntries, setArrows, selectedArrowIds, setSelectedArrowIds } = arrows;
14866
- const { textAnnotations, setTextAnnotations } = text;
15427
+ const { textAnnotations, setTextAnnotations } = text2;
14867
15428
  const { penStrokes, setPenStrokes, selectedPenStrokeIds, setSelectedPenStrokeIds } = pen;
14868
15429
  const { comments: commentEntries, setComments } = comments;
14869
15430
  const { layoutGuides: layoutGuideEntries, setLayoutGuides } = layoutGuides;
@@ -15566,8 +16127,8 @@ var useCommentState = (initialComments = [], onChange) => {
15566
16127
  setDraft(nextDraft);
15567
16128
  };
15568
16129
  const cancelDraft = () => setDraft(null);
15569
- const addMessage = (id, text) => {
15570
- const value = text.trim();
16130
+ const addMessage = (id, text2) => {
16131
+ const value = text2.trim();
15571
16132
  if (!value) return false;
15572
16133
  const message = {
15573
16134
  id: createCommentId(),
@@ -15582,9 +16143,9 @@ var useCommentState = (initialComments = [], onChange) => {
15582
16143
  );
15583
16144
  return true;
15584
16145
  };
15585
- const commitDraft = (text) => {
16146
+ const commitDraft = (text2) => {
15586
16147
  if (!draft) return null;
15587
- const value = text.trim();
16148
+ const value = text2.trim();
15588
16149
  if (!value) return null;
15589
16150
  const now = Date.now();
15590
16151
  const comment = {
@@ -15644,8 +16205,8 @@ var useCommentState = (initialComments = [], onChange) => {
15644
16205
  )
15645
16206
  );
15646
16207
  };
15647
- const updateMessage = (commentId, messageId, text) => {
15648
- const value = text.trim();
16208
+ const updateMessage = (commentId, messageId, text2) => {
16209
+ const value = text2.trim();
15649
16210
  if (!value) return false;
15650
16211
  updateComments(
15651
16212
  (previous) => previous.map(
@@ -15757,7 +16318,7 @@ var useMesurerWorkspaceState = ({
15757
16318
  persistedState?.penStrokes ?? initialState?.penStrokes,
15758
16319
  persistedState?.selectedPenStrokeIds ?? initialState?.selectedPenStrokeIds
15759
16320
  );
15760
- const text = useTextAnnotationState(
16321
+ const text2 = useTextAnnotationState(
15761
16322
  persistedState?.textAnnotations ?? initialState?.textAnnotations,
15762
16323
  persistedState?.selectedTextIds ?? initialState?.selectedTextIds
15763
16324
  );
@@ -15798,7 +16359,7 @@ var useMesurerWorkspaceState = ({
15798
16359
  ...guides,
15799
16360
  ...arrows,
15800
16361
  ...pen,
15801
- ...text,
16362
+ ...text2,
15802
16363
  ...comments,
15803
16364
  toolbarActive,
15804
16365
  setToolbarActive,
@@ -17834,301 +18395,178 @@ function visibleSelectionSlice(rect, viewport) {
17834
18395
  const height = bottom - top;
17835
18396
  if (width <= 0 || height <= 0) {
17836
18397
  return { dx: 0, dy: 0, dw: 0, dh: 0, visible: false };
17837
- }
17838
- return {
17839
- dx: (left - rect.left) / rect.width,
17840
- dy: (top - rect.top) / rect.height,
17841
- dw: width / rect.width,
17842
- dh: height / rect.height,
17843
- visible: true
17844
- };
17845
- }
17846
- function createRecordingCropTarget(ownerDocument, rect) {
17847
- const target = ownerDocument.createElement("div");
17848
- target.setAttribute("data-mesurer-recording-crop", "");
17849
- target.setAttribute("aria-hidden", "true");
17850
- target.style.position = "fixed";
17851
- target.style.left = `${rect.left}px`;
17852
- target.style.top = `${rect.top}px`;
17853
- target.style.width = `${rect.width}px`;
17854
- target.style.height = `${rect.height}px`;
17855
- target.style.margin = "0";
17856
- target.style.padding = "0";
17857
- target.style.border = "0";
17858
- target.style.pointerEvents = "none";
17859
- target.style.background = "transparent";
17860
- target.style.opacity = "0";
17861
- ownerDocument.body.append(target);
17862
- return target;
17863
- }
17864
- async function cropTrackToElement(track, element) {
17865
- const cropTo = track.cropTo;
17866
- const CropTarget = globalThis.CropTarget;
17867
- if (!cropTo || !CropTarget) return false;
17868
- const cropTarget = await CropTarget.fromElement(element);
17869
- await cropTo.call(track, cropTarget);
17870
- return true;
17871
- }
17872
-
17873
- // core/screen-recording-webm.ts
17874
- var EBML_ID = 440786851;
17875
- var SEGMENT_ID = 408125543;
17876
- var INFO_ID = 357149030;
17877
- var TIMECODE_SCALE_ID = 2807729;
17878
- var DURATION_ID = 17545;
17879
- var CLUSTER_ID = 524531317;
17880
- var MASTER_IDS = /* @__PURE__ */ new Set([EBML_ID, SEGMENT_ID, INFO_ID]);
17881
- var readElementId = (bytes, offset) => {
17882
- const first = bytes[offset];
17883
- if (first === void 0 || first === 0) return null;
17884
- let length = 1;
17885
- let mask = 128;
17886
- while (length <= 4 && (first & mask) === 0) {
17887
- mask >>= 1;
17888
- length += 1;
17889
- }
17890
- if (offset + length > bytes.length) return null;
17891
- let id = 0;
17892
- for (let index = 0; index < length; index += 1) id = id * 256 + bytes[offset + index];
17893
- return { length, id };
17894
- };
17895
- var readElementSize = (bytes, offset) => {
17896
- const first = bytes[offset];
17897
- if (first === void 0 || first === 0) return null;
17898
- let length = 1;
17899
- let mask = 128;
17900
- while (length <= 8 && (first & mask) === 0) {
17901
- mask >>= 1;
17902
- length += 1;
17903
- }
17904
- if (offset + length > bytes.length) return null;
17905
- const marker = mask - 1;
17906
- let unknown = (first & marker) === marker;
17907
- let value = first & marker;
17908
- for (let index = 1; index < length; index += 1) {
17909
- const byte = bytes[offset + index];
17910
- if (byte !== 255) unknown = false;
17911
- value = value * 256 + byte;
17912
- }
17913
- return { length, value, unknown };
17914
- };
17915
- var readUint = (bytes, offset, size) => {
17916
- let value = 0;
17917
- for (let index = 0; index < size; index += 1) value = value * 256 + bytes[offset + index];
17918
- return value;
17919
- };
17920
- function writeWebmDuration(bytes, durationSeconds) {
17921
- if (!(durationSeconds > 0)) return false;
17922
- let timecodeScale = 1e6;
17923
- let durationOffset = -1;
17924
- let durationSize = 0;
17925
- const walk = (start, end, inInfo) => {
17926
- let cursor = start;
17927
- while (cursor + 2 < end && durationOffset < 0) {
17928
- const id = readElementId(bytes, cursor);
17929
- if (!id) return;
17930
- cursor += id.length;
17931
- const size = readElementSize(bytes, cursor);
17932
- if (!size) return;
17933
- cursor += size.length;
17934
- const dataStart = cursor;
17935
- if (id.id === CLUSTER_ID) return;
17936
- if (id.id === TIMECODE_SCALE_ID && !size.unknown && size.value > 0 && size.value <= 8) {
17937
- timecodeScale = readUint(bytes, dataStart, size.value);
17938
- }
17939
- if (id.id === DURATION_ID && inInfo && !size.unknown && (size.value === 4 || size.value === 8)) {
17940
- durationOffset = dataStart;
17941
- durationSize = size.value;
17942
- return;
17943
- }
17944
- const dataEnd = size.unknown ? end : dataStart + size.value;
17945
- if (size.unknown || MASTER_IDS.has(id.id)) {
17946
- walk(dataStart, dataEnd, inInfo || id.id === INFO_ID);
17947
- if (durationOffset >= 0) return;
17948
- }
17949
- if (size.unknown) return;
17950
- cursor = dataEnd;
17951
- }
18398
+ }
18399
+ return {
18400
+ dx: (left - rect.left) / rect.width,
18401
+ dy: (top - rect.top) / rect.height,
18402
+ dw: width / rect.width,
18403
+ dh: height / rect.height,
18404
+ visible: true
17952
18405
  };
17953
- walk(0, bytes.length, false);
17954
- if (durationOffset < 0 || timecodeScale <= 0) return false;
17955
- const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
17956
- const current = durationSize === 8 ? view.getFloat64(durationOffset) : view.getFloat32(durationOffset);
17957
- const next = durationSeconds * (1e9 / timecodeScale);
17958
- if (Number.isFinite(current) && current >= next - 1e9 / timecodeScale * 0.05) return false;
17959
- if (durationSize === 8) view.setFloat64(durationOffset, next);
17960
- else view.setFloat32(durationOffset, next);
17961
- return true;
17962
18406
  }
17963
- async function correctWebmDuration(blob, durationSeconds) {
17964
- if (!(durationSeconds > 0) || !blob.type.includes("webm")) return blob;
17965
- const bytes = new Uint8Array(await blob.arrayBuffer());
17966
- if (!writeWebmDuration(bytes, durationSeconds)) return blob;
17967
- return new Blob([bytes], { type: blob.type || "video/webm" });
17968
- }
17969
-
17970
- // core/screen-recording-export.ts
17971
- function resolveRecordingDuration(mediaDuration, elapsedSeconds) {
17972
- const media = Number.isFinite(mediaDuration) && mediaDuration > 0 ? mediaDuration : 0;
17973
- const elapsed = Number.isFinite(elapsedSeconds) && elapsedSeconds > 0 ? elapsedSeconds : 0;
17974
- if (media <= 0 && elapsed <= 0) return 0.1;
17975
- if (media <= 0) return Math.max(elapsed, 0.1);
17976
- if (elapsed <= 0) return media;
17977
- if (media < elapsed * 0.9) return elapsed;
17978
- return Math.min(media, elapsed);
18407
+ function createRecordingCropTarget(ownerDocument, rect) {
18408
+ const target = ownerDocument.createElement("div");
18409
+ target.setAttribute("data-mesurer-recording-crop", "");
18410
+ target.setAttribute("aria-hidden", "true");
18411
+ target.style.position = "fixed";
18412
+ target.style.left = `${rect.left}px`;
18413
+ target.style.top = `${rect.top}px`;
18414
+ target.style.width = `${rect.width}px`;
18415
+ target.style.height = `${rect.height}px`;
18416
+ target.style.margin = "0";
18417
+ target.style.padding = "0";
18418
+ target.style.border = "0";
18419
+ target.style.pointerEvents = "none";
18420
+ target.style.background = "transparent";
18421
+ target.style.opacity = "0";
18422
+ ownerDocument.body.append(target);
18423
+ return target;
17979
18424
  }
17980
- function isFullClipExport(startTime, endTime, duration, tolerance = 0.05) {
17981
- return startTime <= tolerance && endTime >= duration - tolerance;
18425
+ async function cropTrackToElement(track, element) {
18426
+ const cropTo = track.cropTo;
18427
+ const CropTarget = globalThis.CropTarget;
18428
+ if (!cropTo || !CropTarget) return false;
18429
+ const cropTarget = await CropTarget.fromElement(element);
18430
+ await cropTo.call(track, cropTarget);
18431
+ return true;
17982
18432
  }
17983
- async function readBlobVideoDuration(blob, ownerDocument) {
17984
- const url = URL.createObjectURL(blob);
17985
- const video = ownerDocument.createElement("video");
17986
- video.preload = "metadata";
17987
- video.muted = true;
17988
- try {
17989
- return await new Promise((resolve, reject) => {
17990
- video.onloadedmetadata = () => {
17991
- resolve(video.duration);
17992
- };
17993
- video.onerror = () => reject(new Error("Could not read recording"));
17994
- video.src = url;
17995
- });
17996
- } finally {
17997
- URL.revokeObjectURL(url);
17998
- video.removeAttribute("src");
18433
+
18434
+ // core/screen-recording.ts
18435
+ init_screen_recording_webm();
18436
+ init_screen_recording_export();
18437
+
18438
+ // core/screen-recording-mp4.ts
18439
+ init_screen_recording_export();
18440
+
18441
+ // core/mp4-boxes.ts
18442
+ var u16 = (value) => new Uint8Array([value >> 8 & 255, value & 255]);
18443
+ var u32 = (value) => new Uint8Array([value >>> 24 & 255, value >>> 16 & 255, value >>> 8 & 255, value & 255]);
18444
+ var text = (value) => new TextEncoder().encode(value);
18445
+ var join = (...parts) => {
18446
+ const output = new Uint8Array(parts.reduce((sum, part) => sum + part.length, 0));
18447
+ let offset = 0;
18448
+ for (const part of parts) {
18449
+ output.set(part, offset);
18450
+ offset += part.length;
17999
18451
  }
18000
- }
18001
- async function seekVideoElement(video, time) {
18002
- const target = Math.max(0, time);
18003
- if (target <= 0 && video.readyState >= 1) {
18004
- video.currentTime = 0;
18005
- return;
18452
+ return output;
18453
+ };
18454
+ var box = (type, ...payload) => join(u32(8 + payload.reduce((sum, part) => sum + part.length, 0)), text(type), ...payload);
18455
+ var fullBox = (type, version, flags, ...payload) => box(type, new Uint8Array([version, flags >> 16 & 255, flags >> 8 & 255, flags & 255]), ...payload);
18456
+ var zeros = (length) => new Uint8Array(length);
18457
+ function muxH264Mp4(width, height, samples, avcConfig, timescale = 9e4) {
18458
+ const durations = samples.map((sample, index) => index + 1 < samples.length ? Math.max(1, Math.round((samples[index + 1].timestamp - sample.timestamp) * timescale / 1e6)) : Math.max(1, Math.round(timescale / 30)));
18459
+ const duration = durations.reduce((sum, value) => sum + value, 0);
18460
+ const mdatPayload = join(...samples.map((sample) => sample.data));
18461
+ const ftyp = box("ftyp", text("isom"), u32(512), text("isomiso2avc1mp41"));
18462
+ const mvhd = fullBox("mvhd", 0, 0, zeros(8), u32(timescale), u32(duration), u32(65536), u16(256), zeros(10), u32(65536), zeros(12), u32(65536), zeros(12), u32(2));
18463
+ const tkhd = fullBox("tkhd", 0, 7, zeros(8), u32(1), zeros(4), u32(duration), zeros(8), u16(0), u16(0), u16(0), u16(0), u32(65536), zeros(12), u32(65536), zeros(12), u32(width << 16), u32(height << 16));
18464
+ const mdhd = fullBox("mdhd", 0, 0, zeros(8), u32(timescale), u32(duration), u16(21956), u16(0));
18465
+ const hdlr = fullBox("hdlr", 0, 0, zeros(4), text("vide"), zeros(12), text("Mesurer Video\0"));
18466
+ const vmhd = fullBox("vmhd", 0, 1, zeros(8));
18467
+ const dref = fullBox("dref", 0, 0, u32(1), fullBox("url ", 0, 1));
18468
+ const avc1 = box("avc1", zeros(6), u16(1), zeros(16), u16(width), u16(height), u32(4718592), u32(4718592), zeros(4), u16(1), zeros(32), u16(24), u16(65535), box("avcC", avcConfig));
18469
+ const stsd = fullBox("stsd", 0, 0, u32(1), avc1);
18470
+ const runs = [];
18471
+ for (const delta of durations) {
18472
+ const last = runs[runs.length - 1];
18473
+ if (last?.delta === delta) last.count += 1;
18474
+ else runs.push({ count: 1, delta });
18006
18475
  }
18007
- await new Promise((resolve, reject) => {
18008
- const onSeeked = () => resolve();
18009
- const onError = () => reject(new Error("Could not seek recording"));
18010
- video.addEventListener("seeked", onSeeked, { once: true });
18011
- video.addEventListener("error", onError, { once: true });
18012
- if (video.readyState < 1) {
18013
- video.addEventListener(
18014
- "loadedmetadata",
18015
- () => {
18016
- video.currentTime = target;
18017
- },
18018
- { once: true }
18019
- );
18020
- } else {
18021
- video.currentTime = target;
18022
- }
18023
- });
18476
+ const stts = fullBox("stts", 0, 0, u32(runs.length), ...runs.map((run) => join(u32(run.count), u32(run.delta))));
18477
+ const stsc = fullBox("stsc", 0, 0, u32(1), u32(1), u32(samples.length), u32(1));
18478
+ const stsz = fullBox("stsz", 0, 0, u32(0), u32(samples.length), ...samples.map((sample) => u32(sample.data.length)));
18479
+ const stss = samples.some((sample) => !sample.key) ? fullBox("stss", 0, 0, u32(samples.filter((sample) => sample.key).length), ...samples.flatMap((sample, index) => sample.key ? [u32(index + 1)] : [])) : null;
18480
+ const stbl = box("stbl", stsd, stts, stsc, stsz, stss ?? new Uint8Array());
18481
+ const minf = box("minf", vmhd, box("dinf", dref), stbl);
18482
+ const trak = box("trak", tkhd, box("mdia", mdhd, hdlr, minf));
18483
+ const moov = box("moov", mvhd, trak);
18484
+ const chunkOffset = ftyp.length + moov.length + 20 + 8;
18485
+ const stco = fullBox("stco", 0, 0, u32(1), u32(chunkOffset));
18486
+ const patchedStbl = box("stbl", stsd, stts, stsc, stsz, stco, stss ?? new Uint8Array());
18487
+ const patchedMoov = box("moov", mvhd, box("trak", tkhd, box("mdia", mdhd, hdlr, box("minf", vmhd, box("dinf", dref), patchedStbl))));
18488
+ return join(ftyp, patchedMoov, box("mdat", mdatPayload));
18024
18489
  }
18025
- async function requestDisplayMediaStream(ownerWindow) {
18026
- const fallback = {
18027
- audio: false,
18028
- video: true
18029
- };
18030
- const chromium = {
18031
- audio: false,
18032
- video: { displaySurface: "browser" },
18033
- preferCurrentTab: true,
18034
- selfBrowserSurface: "include"
18035
- };
18036
- try {
18037
- return await ownerWindow.navigator.mediaDevices.getDisplayMedia(chromium);
18038
- } catch (error) {
18039
- if (error instanceof DOMException && error.name === "AbortError") throw error;
18040
- return await ownerWindow.navigator.mediaDevices.getDisplayMedia(fallback);
18490
+
18491
+ // core/screen-recording-mp4.ts
18492
+ var encoderCtor = (ownerWindow) => ownerWindow.VideoEncoder;
18493
+ var codecs = ["avc1.42001E", "avc1.42001F", "avc1.4D001F", "avc1.64001F"];
18494
+ var even = (value) => Math.max(2, Math.round(value) & ~1);
18495
+ async function supportedMp4Config(ownerWindow, width, height) {
18496
+ const Encoder = encoderCtor(ownerWindow);
18497
+ if (!Encoder) return null;
18498
+ const dimensions = { width: even(width), height: even(height) };
18499
+ for (const codec of codecs) {
18500
+ try {
18501
+ const result = await Encoder.isConfigSupported({ codec, ...dimensions, bitrate: 4e6, framerate: 30, avc: { format: "avc" } });
18502
+ if (result?.supported) return result.config;
18503
+ } catch {
18504
+ }
18041
18505
  }
18506
+ return null;
18042
18507
  }
18043
- async function reencodeVideoClip(ownerDocument, ownerWindow, sourceUrl, startTime, endTime, scale, mimeType) {
18508
+ async function supportsMp4Encoding(ownerWindow, width, height) {
18509
+ return Boolean(await supportedMp4Config(ownerWindow, width, height));
18510
+ }
18511
+ async function encodeMp4Clip(ownerDocument, ownerWindow, sourceUrl, startTime, endTime, scale) {
18044
18512
  const source = ownerDocument.createElement("video");
18045
18513
  source.muted = true;
18046
18514
  source.playsInline = true;
18047
- source.src = sourceUrl;
18048
18515
  source.preload = "auto";
18049
- await new Promise((resolve, reject) => {
18050
- const ready = () => source.videoWidth > 0 && source.videoHeight > 0;
18051
- const finish = () => {
18052
- if (!ready()) return;
18053
- resolve();
18054
- };
18055
- source.onloadedmetadata = finish;
18056
- source.onloadeddata = finish;
18057
- source.onresize = finish;
18058
- source.onerror = () => reject(new Error("Could not trim recording"));
18059
- if (ready()) resolve();
18060
- });
18061
- await seekVideoElement(source, startTime);
18062
- if (source.videoWidth <= 0 || source.videoHeight <= 0) {
18063
- await new Promise((resolve) => {
18064
- if (typeof source.requestVideoFrameCallback === "function") {
18065
- source.requestVideoFrameCallback(() => resolve());
18066
- return;
18067
- }
18068
- ownerWindow.requestAnimationFrame(() => resolve());
18516
+ source.src = sourceUrl;
18517
+ try {
18518
+ await new Promise((resolve, reject) => {
18519
+ const ready = () => source.videoWidth > 0 && source.videoHeight > 0 && source.readyState >= 2;
18520
+ const finish = () => ready() && resolve();
18521
+ source.onloadedmetadata = finish;
18522
+ source.onloadeddata = finish;
18523
+ source.onerror = () => reject(new Error("Could not export MP4"));
18524
+ if (ready()) resolve();
18069
18525
  });
18070
- }
18071
- const canvas = ownerDocument.createElement("canvas");
18072
- canvas.width = Math.max(1, Math.round(source.videoWidth * scale));
18073
- canvas.height = Math.max(1, Math.round(source.videoHeight * scale));
18074
- const context = canvas.getContext("2d");
18075
- if (!context) throw new Error("Could not trim recording");
18076
- const stream = canvas.captureStream(30);
18077
- const captureTrack = stream.getVideoTracks()[0];
18078
- const requestFrame = captureTrack && "requestFrame" in captureTrack ? captureTrack.requestFrame : void 0;
18079
- const recorder = new MediaRecorder(stream, mimeType ? { mimeType } : void 0);
18080
- const chunks = [];
18081
- return await new Promise((resolve, reject) => {
18082
- let stopped = false;
18083
- const onTimeUpdate = () => {
18084
- if (source.currentTime >= endTime) finish();
18085
- };
18086
- const finish = () => {
18087
- if (stopped) return;
18088
- stopped = true;
18089
- source.removeEventListener("timeupdate", onTimeUpdate);
18090
- source.pause();
18091
- try {
18092
- recorder.stop();
18093
- } catch {
18094
- reject(new Error("Could not trim recording"));
18095
- }
18096
- };
18097
- const drawFrame = () => {
18098
- if (stopped) return;
18526
+ const canvas = ownerDocument.createElement("canvas");
18527
+ canvas.width = even(source.videoWidth * scale);
18528
+ canvas.height = even(source.videoHeight * scale);
18529
+ const context = canvas.getContext("2d");
18530
+ const Encoder = encoderCtor(ownerWindow);
18531
+ if (!context || !Encoder) throw new Error("MP4 export is unavailable");
18532
+ const samples = [];
18533
+ let avcConfig;
18534
+ let failure;
18535
+ const config = await supportedMp4Config(ownerWindow, canvas.width, canvas.height);
18536
+ if (!config) throw new Error("MP4 export is unavailable");
18537
+ const encoder = new Encoder({ output: (chunk, metadata) => {
18538
+ const data = new Uint8Array(chunk.byteLength);
18539
+ chunk.copyTo(data);
18540
+ samples.push({ data, key: chunk.type === "key", timestamp: chunk.timestamp });
18541
+ const description = metadata?.decoderConfig?.description;
18542
+ if (description) avcConfig = new Uint8Array(description);
18543
+ }, error: (error) => {
18544
+ failure = error;
18545
+ } });
18546
+ encoder.configure(config);
18547
+ const VideoFrameCtor = ownerWindow.VideoFrame;
18548
+ if (!VideoFrameCtor) throw new Error("MP4 export is unavailable");
18549
+ let frameIndex = 0;
18550
+ for (const time of Array.from({ length: Math.max(1, Math.ceil((endTime - startTime) * 30)) }, (_, index) => startTime + index / 30)) {
18551
+ await seekVideoElement(source, Math.min(endTime, time));
18099
18552
  context.drawImage(source, 0, 0, canvas.width, canvas.height);
18100
- requestFrame?.call(captureTrack);
18101
- if (source.currentTime >= endTime || source.ended) {
18102
- finish();
18103
- return;
18104
- }
18105
- if (typeof source.requestVideoFrameCallback === "function") {
18106
- source.requestVideoFrameCallback(() => drawFrame());
18107
- } else {
18108
- ownerWindow.requestAnimationFrame(drawFrame);
18109
- }
18110
- };
18111
- recorder.ondataavailable = (event) => {
18112
- if (event.data.size > 0) chunks.push(event.data);
18113
- };
18114
- recorder.onstop = () => {
18115
- const recorded = new Blob(chunks, { type: recorder.mimeType || mimeType || "video/webm" });
18116
- void correctWebmDuration(recorded, Math.max(0.1, endTime - startTime)).then(resolve, reject);
18117
- };
18118
- recorder.onerror = () => reject(new Error("Could not trim recording"));
18119
- source.addEventListener("timeupdate", onTimeUpdate);
18120
- recorder.start(100);
18121
- void source.play().then(
18122
- () => drawFrame(),
18123
- () => {
18124
- source.removeEventListener("timeupdate", onTimeUpdate);
18125
- reject(new Error("Could not trim recording"));
18126
- }
18127
- );
18128
- });
18553
+ const frame = new VideoFrameCtor(canvas, { timestamp: Math.round(frameIndex++ * 1e6 / 30) });
18554
+ encoder.encode(frame, { keyFrame: frameIndex === 1 || frameIndex % 60 === 0 });
18555
+ frame.close();
18556
+ }
18557
+ await encoder.flush();
18558
+ encoder.close();
18559
+ if (failure || !avcConfig || samples.length === 0) throw failure ?? new Error("Could not export MP4");
18560
+ return new Blob([new Uint8Array(muxH264Mp4(canvas.width, canvas.height, samples, avcConfig))], { type: "video/mp4" });
18561
+ } finally {
18562
+ source.pause();
18563
+ source.removeAttribute("src");
18564
+ source.load();
18565
+ }
18129
18566
  }
18130
18567
 
18131
18568
  // core/screen-recording-display-capture.ts
18569
+ init_screen_recording_export();
18132
18570
  var HIDDEN_MEDIA_STYLE = "position:fixed;left:0;top:0;width:1px;height:1px;margin:0;padding:0;border:0;overflow:hidden;opacity:0;visibility:hidden;pointer-events:none";
18133
18571
  var nextPresentedVideoFrame = (video, ownerWindow) => new Promise((resolve) => {
18134
18572
  let settled = false;
@@ -18254,8 +18692,8 @@ function paintDisplayRecordingFrame(capture, rect, getViewport) {
18254
18692
  const { source, canvas, context, regionLocked, cropTarget, captureTrack } = capture;
18255
18693
  if (source.videoWidth <= 0 || source.videoHeight <= 0) return;
18256
18694
  if (regionLocked && cropTarget) {
18257
- const box = cropTarget.getBoundingClientRect();
18258
- const slice = visibleSelectionSlice(box, getViewport());
18695
+ const box2 = cropTarget.getBoundingClientRect();
18696
+ const slice = visibleSelectionSlice(box2, getViewport());
18259
18697
  if (!slice.visible) {
18260
18698
  context.fillStyle = "#000";
18261
18699
  context.fillRect(0, 0, canvas.width, canvas.height);
@@ -18318,16 +18756,12 @@ function runDisplayRecordingDrawLoop(ownerWindow, capture, rect, getViewport, dr
18318
18756
  }
18319
18757
 
18320
18758
  // hooks/screen-recording-export.ts
18321
- var mp4MimeType = () => ["video/mp4;codecs=avc1.42E01E", "video/mp4"].find((type) => MediaRecorder.isTypeSupported(type));
18322
18759
  var supportedRecordingFormats = () => {
18323
- const formats = ["webm"];
18324
- if (typeof MediaRecorder !== "undefined" && mp4MimeType()) formats.push("mp4");
18325
- return formats;
18760
+ return ["webm", "gif"];
18326
18761
  };
18327
18762
  var supportedWebmMimeType = () => ["video/webm;codecs=vp9", "video/webm;codecs=vp8", "video/webm"].find(
18328
18763
  (type) => MediaRecorder.isTypeSupported(type)
18329
18764
  );
18330
- var supportedMp4MimeType = mp4MimeType;
18331
18765
 
18332
18766
  // hooks/use-screen-recording.ts
18333
18767
  var MAX_RECORDING_MS = 6e4;
@@ -18640,8 +19074,16 @@ var useScreenRecording = ({ ownerDocument, ownerWindow, onPrepare, extensionReco
18640
19074
  const blob2 = await fetch(video.url).then((response) => response.blob());
18641
19075
  return { blob: blob2, filename };
18642
19076
  }
18643
- const mimeType = format === "mp4" ? supportedMp4MimeType() : supportedWebmMimeType();
18644
- if (format === "mp4" && !mimeType) throw new Error("MP4 export is unavailable");
19077
+ if (format === "gif") {
19078
+ return {
19079
+ blob: await encodeGifClip2(ownerDocument, video.url, startTime, endTime, scale),
19080
+ filename
19081
+ };
19082
+ }
19083
+ if (format === "mp4") {
19084
+ return { blob: await encodeMp4Clip(ownerDocument, ownerWindow, video.url, startTime, endTime, scale), filename };
19085
+ }
19086
+ const mimeType = supportedWebmMimeType();
18645
19087
  const blob = await reencodeVideoClip(
18646
19088
  ownerDocument,
18647
19089
  ownerWindow,
@@ -18699,7 +19141,8 @@ var TIMELINE_BAR_MOTION = "msr:transition-[height] msr:duration-300 msr:ease-[cu
18699
19141
  var SCALE_OPTIONS = [1, 2, 3];
18700
19142
  var FORMAT_LABEL = {
18701
19143
  webm: "WebM",
18702
- mp4: "MP4"
19144
+ mp4: "MP4",
19145
+ gif: "GIF"
18703
19146
  };
18704
19147
  var scaleLabel = (scale, size) => {
18705
19148
  if (!size) return `${scale}\xD7`;
@@ -18830,24 +19273,118 @@ function TrimHandle({
18830
19273
  }
18831
19274
  function ScreenRecordingEditor(props) {
18832
19275
  if (props.playerUrl) {
18833
- return /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(ExtensionRecordingFrame, { ...props });
19276
+ return /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(ExtensionRecordingFrame, { playerUrl: props.playerUrl, onDiscard: props.onDiscard });
18834
19277
  }
18835
19278
  return /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(StandardScreenRecordingEditor, { ...props });
18836
19279
  }
18837
- function ExtensionRecordingFrame({ playerUrl, onDiscard }) {
19280
+ var RECORDING_FRAME_WIDTH = 22 * 16;
19281
+ var RECORDING_FRAME_SHADOW = 28;
19282
+ var recordingTheme = (from) => {
19283
+ const theme = (from?.closest("[data-mesurer-root]") ?? document.querySelector("[data-mesurer-root]"))?.getAttribute("data-theme");
19284
+ return theme === "light" || theme === "dark" || theme === "system" ? theme : "system";
19285
+ };
19286
+ function ExtensionRecordingFrame({
19287
+ playerUrl,
19288
+ onDiscard
19289
+ }) {
19290
+ const hostRef = (0, import_react67.useRef)(null);
18838
19291
  const frameRef = (0, import_react67.useRef)(null);
19292
+ const [frameSize, setFrameSize] = (0, import_react67.useState)({ width: RECORDING_FRAME_WIDTH, height: 280, menuExtra: 0 });
19293
+ const [anchorSide, setAnchorSide] = (0, import_react67.useState)("top");
19294
+ const [src, setSrc] = (0, import_react67.useState)(null);
19295
+ (0, import_react67.useLayoutEffect)(() => {
19296
+ const url = new URL(playerUrl);
19297
+ url.searchParams.set("theme", recordingTheme(hostRef.current));
19298
+ setSrc(url.toString());
19299
+ }, [playerUrl]);
19300
+ const postFrameState = (0, import_react67.useCallback)(() => {
19301
+ const frame = frameRef.current;
19302
+ const panel = frame?.parentElement?.parentElement;
19303
+ const side = panel?.style.bottom ? "bottom" : "top";
19304
+ setAnchorSide(side);
19305
+ frame?.contentWindow?.postMessage({ type: "mesurer:recording-theme", theme: recordingTheme(frame ?? hostRef.current) }, "*");
19306
+ frame?.contentWindow?.postMessage({ type: "mesurer:recording-anchor", side }, "*");
19307
+ }, []);
18839
19308
  (0, import_react67.useEffect)(() => {
18840
19309
  const onMessage = (event) => {
18841
- if (event.source === frameRef.current?.contentWindow && event.data?.type === "mesurer:recording-discard") {
18842
- onDiscard();
19310
+ if (event.source !== frameRef.current?.contentWindow) return;
19311
+ if (event.data?.type === "mesurer:recording-discard") onDiscard();
19312
+ if (event.data?.type === "mesurer:recording-frame-intent" && typeof event.data.expanded === "boolean") {
19313
+ setFrameSize((current) => ({
19314
+ ...current,
19315
+ width: event.data.expanded ? 36 * 16 : RECORDING_FRAME_WIDTH,
19316
+ height: event.data.expanded ? Math.max(current.height, 520) : current.height
19317
+ }));
19318
+ }
19319
+ if (event.data?.type === "mesurer:recording-frame-size" && typeof event.data.width === "number" && typeof event.data.height === "number" && event.data.width >= 32 && event.data.height >= 32) {
19320
+ setFrameSize({
19321
+ width: event.data.width,
19322
+ height: event.data.height,
19323
+ menuExtra: typeof event.data.menuExtra === "number" ? event.data.menuExtra : 0
19324
+ });
18843
19325
  }
18844
19326
  };
18845
19327
  window.addEventListener("message", onMessage);
18846
- return () => window.removeEventListener("message", onMessage);
18847
- }, [onDiscard]);
18848
- return /* @__PURE__ */ (0, import_jsx_runtime68.jsx)("iframe", { ref: frameRef, title: "Recording preview", src: playerUrl, className: "msr:block msr:max-w-[calc(100vw-16px)] msr:border-0 msr:bg-transparent", style: { width: "calc(36rem + 24px)", height: "calc(32rem + 24px)", margin: -12 } });
19328
+ const root = (frameRef.current ?? hostRef.current)?.closest("[data-mesurer-root]");
19329
+ const panel = frameRef.current?.parentElement?.parentElement;
19330
+ const observer = new MutationObserver(postFrameState);
19331
+ if (root) observer.observe(root, { attributes: true, attributeFilter: ["data-theme"] });
19332
+ if (panel) observer.observe(panel, { attributes: true, attributeFilter: ["style"] });
19333
+ return () => {
19334
+ window.removeEventListener("message", onMessage);
19335
+ observer.disconnect();
19336
+ };
19337
+ }, [onDiscard, postFrameState, src]);
19338
+ const menuAbove = anchorSide === "bottom";
19339
+ const shadow = RECORDING_FRAME_SHADOW;
19340
+ const frameWidth = frameSize.width + shadow * 2;
19341
+ const frameHeight = frameSize.height + frameSize.menuExtra + shadow * 2;
19342
+ return /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(
19343
+ "div",
19344
+ {
19345
+ ref: hostRef,
19346
+ className: "msr:relative msr:max-w-[calc(100vw-16px)] msr:bg-transparent",
19347
+ style: {
19348
+ width: frameSize.width,
19349
+ height: frameSize.height
19350
+ },
19351
+ children: src ? /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(
19352
+ "div",
19353
+ {
19354
+ className: "msr:pointer-events-none msr:absolute",
19355
+ style: {
19356
+ width: frameWidth,
19357
+ height: frameHeight,
19358
+ left: -shadow,
19359
+ top: menuAbove ? -(frameSize.menuExtra + shadow) : -shadow,
19360
+ // The iframe is larger than the card so its shadow can paint.
19361
+ // Clip the edge that faces the toolbar; otherwise that transparent
19362
+ // strip sits on the toolbar and swallows clicks.
19363
+ clipPath: menuAbove ? `inset(0 0 ${shadow}px 0)` : `inset(${shadow}px 0 0 0)`
19364
+ },
19365
+ children: /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(
19366
+ "iframe",
19367
+ {
19368
+ ref: frameRef,
19369
+ title: "Recording preview",
19370
+ src,
19371
+ onLoad: postFrameState,
19372
+ allowTransparency: true,
19373
+ className: "msr:pointer-events-auto msr:absolute msr:inset-0 msr:size-full msr:border-0 msr:bg-transparent msr:shadow-none",
19374
+ style: {
19375
+ backgroundColor: "transparent",
19376
+ colorScheme: "light",
19377
+ border: 0,
19378
+ boxShadow: "none"
19379
+ }
19380
+ }
19381
+ )
19382
+ }
19383
+ ) : null
19384
+ }
19385
+ );
18849
19386
  }
18850
- function StandardScreenRecordingEditor({ url, duration, onDiscard, onExport, ownerDocument }) {
19387
+ function StandardScreenRecordingEditor({ url, duration, onDiscard, onExport, ownerDocument, fillFrame }) {
18851
19388
  const videoRef = (0, import_react67.useRef)(null);
18852
19389
  const trackRef = (0, import_react67.useRef)(null);
18853
19390
  const playheadRef = (0, import_react67.useRef)(null);
@@ -18866,7 +19403,8 @@ function StandardScreenRecordingEditor({ url, duration, onDiscard, onExport, own
18866
19403
  const [playing, setPlaying] = (0, import_react67.useState)(false);
18867
19404
  const [exporting, setExporting] = (0, import_react67.useState)(false);
18868
19405
  const [expanded, setExpanded] = (0, import_react67.useState)(false);
18869
- const formats = (0, import_react67.useMemo)(() => supportedRecordingFormats(), []);
19406
+ const [mp4Supported, setMp4Supported] = (0, import_react67.useState)(false);
19407
+ const formats = (0, import_react67.useMemo)(() => mp4Supported ? [...supportedRecordingFormats(), "mp4"] : supportedRecordingFormats(), [mp4Supported]);
18870
19408
  const [format, setFormat] = (0, import_react67.useState)(formats[0] ?? "webm");
18871
19409
  const [scale, setScale] = (0, import_react67.useState)(1);
18872
19410
  const [frameSize, setFrameSize] = (0, import_react67.useState)(null);
@@ -18881,6 +19419,22 @@ function StandardScreenRecordingEditor({ url, duration, onDiscard, onExport, own
18881
19419
  const [exportMenuBox, setExportMenuBox] = (0, import_react67.useState)(null);
18882
19420
  startRef.current = start;
18883
19421
  endRef.current = end;
19422
+ (0, import_react67.useEffect)(() => {
19423
+ let active = true;
19424
+ setMp4Supported(false);
19425
+ if (!frameSize || !ownerDocument.defaultView) return () => {
19426
+ active = false;
19427
+ };
19428
+ void supportsMp4Encoding(ownerDocument.defaultView, frameSize.width, frameSize.height).then((supported) => {
19429
+ if (active) setMp4Supported(supported);
19430
+ });
19431
+ return () => {
19432
+ active = false;
19433
+ };
19434
+ }, [frameSize, ownerDocument]);
19435
+ (0, import_react67.useEffect)(() => {
19436
+ if (!mp4Supported && format === "mp4") setFormat("webm");
19437
+ }, [format, mp4Supported]);
18884
19438
  (0, import_react67.useEffect)(() => {
18885
19439
  setStart(0);
18886
19440
  setEnd(duration);
@@ -18943,9 +19497,10 @@ function StandardScreenRecordingEditor({ url, duration, onDiscard, onExport, own
18943
19497
  const padding = 8;
18944
19498
  const spaceAbove = rect.top - origin.top - padding;
18945
19499
  const spaceBelow = origin.bottom - rect.bottom - padding;
18946
- const openAbove = spaceAbove >= height || spaceAbove >= spaceBelow;
19500
+ const anchorSide = ownerDocument.getElementById("root")?.getAttribute("data-anchor");
19501
+ const openAbove = anchorSide === "bottom" ? true : anchorSide === "top" ? false : spaceAbove >= height || spaceAbove >= spaceBelow;
18947
19502
  const preferredTop = openAbove ? rect.top - origin.top - height - gap : rect.bottom - origin.top + gap;
18948
- setExportMenuBox(clampOverlayPosition({
19503
+ const placed = clampOverlayPosition({
18949
19504
  left: rect.right - origin.left - width,
18950
19505
  top: preferredTop,
18951
19506
  width,
@@ -18953,13 +19508,18 @@ function StandardScreenRecordingEditor({ url, duration, onDiscard, onExport, own
18953
19508
  viewportWidth: origin.width,
18954
19509
  viewportHeight: origin.height,
18955
19510
  padding
18956
- }));
19511
+ });
19512
+ const ready = anchorSide ? openAbove ? spaceAbove >= height : spaceBelow >= height : true;
19513
+ setExportMenuBox({ left: placed.left, top: anchorSide ? preferredTop : placed.top, ready });
18957
19514
  };
18958
19515
  update();
18959
19516
  const view = ownerDocument.defaultView;
18960
19517
  view?.addEventListener("resize", update);
18961
19518
  view?.addEventListener("scroll", update, true);
19519
+ const observer = new ResizeObserver(update);
19520
+ observer.observe(overlayLayer);
18962
19521
  return () => {
19522
+ observer.disconnect();
18963
19523
  view?.removeEventListener("resize", update);
18964
19524
  view?.removeEventListener("scroll", update, true);
18965
19525
  };
@@ -19145,6 +19705,7 @@ function StandardScreenRecordingEditor({ url, duration, onDiscard, onExport, own
19145
19705
  }, [exporting, updatePlayheadPosition]);
19146
19706
  const downloadRecording = async () => {
19147
19707
  if (exporting) return;
19708
+ setExportMenuOpen(false);
19148
19709
  setExporting(true);
19149
19710
  setError(null);
19150
19711
  try {
@@ -19159,8 +19720,8 @@ function StandardScreenRecordingEditor({ url, duration, onDiscard, onExport, own
19159
19720
  link.click();
19160
19721
  link.remove();
19161
19722
  ownerDocument.defaultView?.setTimeout(() => URL.revokeObjectURL(objectUrl), 0);
19162
- } catch {
19163
- setError("Could not export the recording.");
19723
+ } catch (caught) {
19724
+ setError(caught instanceof Error && caught.message ? caught.message : "Could not export the recording.");
19164
19725
  } finally {
19165
19726
  setExporting(false);
19166
19727
  }
@@ -19181,11 +19742,12 @@ function StandardScreenRecordingEditor({ url, duration, onDiscard, onExport, own
19181
19742
  ref: cardRef,
19182
19743
  tabIndex: 0,
19183
19744
  "aria-keyshortcuts": "Space",
19745
+ "data-mesurer-recording-card": true,
19184
19746
  "data-expanded": expanded ? "true" : "false",
19185
19747
  className: cn(
19186
19748
  "mesurer-menu-surface msr:relative msr:box-border msr:overflow-visible msr:rounded-wide-card msr:bg-white msr:shadow-floating msr:outline-none",
19187
- "msr:w-[22rem] msr:max-w-[calc(100vw-24px)] msr:transition-[width] msr:duration-200 msr:ease-[ease] msr:motion-reduce:transition-none",
19188
- expanded && "msr:w-[36rem]"
19749
+ fillFrame ? "msr:w-full msr:max-w-none" : "msr:w-[22rem] msr:max-w-[calc(100vw-24px)] msr:transition-[width] msr:duration-200 msr:ease-[ease] msr:motion-reduce:transition-none",
19750
+ !fillFrame && expanded && "msr:w-[36rem]"
19189
19751
  ),
19190
19752
  "aria-label": "Screen recording editor",
19191
19753
  "aria-busy": exporting,
@@ -19270,7 +19832,7 @@ function StandardScreenRecordingEditor({ url, duration, onDiscard, onExport, own
19270
19832
  )
19271
19833
  }
19272
19834
  ),
19273
- exporting ? /* @__PURE__ */ (0, import_jsx_runtime68.jsx)("div", { className: "msr:absolute msr:inset-0 msr:z-30 msr:flex msr:items-center msr:justify-center msr:bg-ink-900/45 msr:text-[11px] msr:text-white", children: /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(StatusEllipsis, { label: "Exporting" }) }) : null,
19835
+ exporting ? /* @__PURE__ */ (0, import_jsx_runtime68.jsx)("div", { className: "msr:absolute msr:inset-0 msr:z-30 msr:flex msr:items-center msr:justify-center msr:bg-black/80 msr:text-[11px] msr:font-medium msr:text-white msr:drop-shadow-[0_1px_2px_rgba(0,0,0,0.8)]", children: /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(StatusEllipsis, { label: "Generating" }) }) : null,
19274
19836
  /* @__PURE__ */ (0, import_jsx_runtime68.jsxs)(
19275
19837
  "div",
19276
19838
  {
@@ -19411,6 +19973,7 @@ function StandardScreenRecordingEditor({ url, duration, onDiscard, onExport, own
19411
19973
  variant: "ghost",
19412
19974
  "aria-haspopup": "menu",
19413
19975
  "aria-expanded": exportMenuOpen,
19976
+ disabled: exporting,
19414
19977
  "aria-label": "Export options",
19415
19978
  className: "msr:px-1 msr:font-mono msr:text-[10px] msr:leading-none",
19416
19979
  style: { height: 20 },
@@ -19439,7 +20002,7 @@ function StandardScreenRecordingEditor({ url, duration, onDiscard, onExport, own
19439
20002
  {
19440
20003
  ref: exportMenuSurfaceRef,
19441
20004
  className: "msr:pointer-events-auto msr:absolute",
19442
- style: exportMenuBox ? { left: exportMenuBox.left, top: exportMenuBox.top } : { left: 0, top: 0, visibility: "hidden" },
20005
+ style: exportMenuBox?.ready ? { left: exportMenuBox.left, top: exportMenuBox.top } : { left: exportMenuBox?.left ?? 0, top: exportMenuBox?.top ?? 0, visibility: "hidden" },
19443
20006
  children: /* @__PURE__ */ (0, import_jsx_runtime68.jsxs)(MenuSurface, { className: "msr:w-max msr:min-w-44", children: [
19444
20007
  /* @__PURE__ */ (0, import_jsx_runtime68.jsx)("p", { className: "msr:px-2 msr:py-1 msr:text-[10px] msr:font-medium msr:text-ink-500", children: "Format" }),
19445
20008
  formats.map((item) => {
@@ -19450,7 +20013,10 @@ function StandardScreenRecordingEditor({ url, duration, onDiscard, onExport, own
19450
20013
  variant: "neutral",
19451
20014
  className: exportMenuRowClass(selected),
19452
20015
  "aria-checked": selected,
19453
- onClick: () => setFormat(item),
20016
+ onClick: () => {
20017
+ setFormat(item);
20018
+ setExportMenuOpen(false);
20019
+ },
19454
20020
  children: [
19455
20021
  /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(
19456
20022
  CheckIcon,
@@ -19474,7 +20040,10 @@ function StandardScreenRecordingEditor({ url, duration, onDiscard, onExport, own
19474
20040
  variant: "neutral",
19475
20041
  className: exportMenuRowClass(selected),
19476
20042
  "aria-checked": selected,
19477
- onClick: () => setScale(item),
20043
+ onClick: () => {
20044
+ setScale(item);
20045
+ setExportMenuOpen(false);
20046
+ },
19478
20047
  children: [
19479
20048
  /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(
19480
20049
  CheckIcon,
@@ -19511,7 +20080,13 @@ function StandardScreenRecordingEditor({ url, duration, onDiscard, onExport, own
19511
20080
  tooltipId: "recording-resize",
19512
20081
  tooltip,
19513
20082
  pressed: expanded,
19514
- onClick: () => setExpanded((current) => !current),
20083
+ onClick: () => {
20084
+ const next = !expanded;
20085
+ if (ownerDocument.defaultView && ownerDocument.defaultView.parent !== ownerDocument.defaultView) {
20086
+ ownerDocument.defaultView.parent.postMessage({ type: "mesurer:recording-frame-intent", expanded: next }, "*");
20087
+ }
20088
+ setExpanded(next);
20089
+ },
19515
20090
  children: expanded ? /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(CollapseIcon, {}) : /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(ExpandIcon, {})
19516
20091
  }
19517
20092
  )
@@ -23550,23 +24125,23 @@ var makeEdge = (document2, side, color) => {
23550
24125
  return edge;
23551
24126
  };
23552
24127
  var makeBox = (document2, fill, outline) => {
23553
- const box = document2.createElement("div");
23554
- Object.assign(box.style, {
24128
+ const box2 = document2.createElement("div");
24129
+ Object.assign(box2.style, {
23555
24130
  position: "fixed",
23556
24131
  zIndex: "0",
23557
24132
  pointerEvents: "none",
23558
24133
  backgroundColor: fill,
23559
24134
  boxSizing: "border-box"
23560
24135
  });
23561
- box.className = "mesurer-ti-box";
23562
- box.dataset.state = "hidden";
24136
+ box2.className = "mesurer-ti-box";
24137
+ box2.dataset.state = "hidden";
23563
24138
  for (const side of ["top", "right", "bottom", "left"]) {
23564
- box.appendChild(makeEdge(document2, side, outline));
24139
+ box2.appendChild(makeEdge(document2, side, outline));
23565
24140
  }
23566
- return box;
24141
+ return box2;
23567
24142
  };
23568
- var positionBox = (box, rect) => {
23569
- Object.assign(box.style, {
24143
+ var positionBox = (box2, rect) => {
24144
+ Object.assign(box2.style, {
23570
24145
  left: `${rect.left}px`,
23571
24146
  top: `${rect.top}px`,
23572
24147
  width: `${rect.width}px`,
@@ -24066,27 +24641,27 @@ var createTextInspector = (options = {}, legacy = false) => {
24066
24641
  if (pinned.length >= maxPinned) removePin(pinned[0], false, true);
24067
24642
  }
24068
24643
  const root = ensureOverlay();
24069
- const box = makeBox(document2, FILL_PINNED, OUTLINE_PINNED);
24644
+ const box2 = makeBox(document2, FILL_PINNED, OUTLINE_PINNED);
24070
24645
  const card = makeCard(document2, true);
24071
24646
  const info = typography.getFull(sourceEl);
24072
24647
  populateCard(document2, card, info, true);
24073
- root.append(box, card);
24648
+ root.append(box2, card);
24074
24649
  const pin = {
24075
24650
  sourceEl,
24076
- box,
24651
+ box: box2,
24077
24652
  card,
24078
24653
  userPlaced: state?.userPlaced ?? false,
24079
24654
  detach: () => {
24080
24655
  }
24081
24656
  };
24082
24657
  const rect = sourceEl.getBoundingClientRect();
24083
- positionBox(box, rect);
24658
+ positionBox(box2, rect);
24084
24659
  positionCard(window2, card, rect);
24085
24660
  if (state?.userPlaced) {
24086
24661
  card.style.left = `${state.left}px`;
24087
24662
  card.style.top = `${state.top}px`;
24088
24663
  }
24089
- setState(box, true);
24664
+ setState(box2, true);
24090
24665
  setState(card, true);
24091
24666
  pinned.push(pin);
24092
24667
  card.querySelector(".mesurer-ti-close")?.addEventListener(