@gallop.software/studio 0.1.93 → 0.1.94

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.
@@ -1107,13 +1107,385 @@ function R2SetupModal({ isOpen, onClose }) {
1107
1107
  ] }) });
1108
1108
  }
1109
1109
 
1110
+ // src/components/AddNewModal.tsx
1111
+
1112
+
1113
+
1114
+ var fadeIn3 = _react3.keyframes`
1115
+ from { opacity: 0; }
1116
+ to { opacity: 1; }
1117
+ `;
1118
+ var slideIn3 = _react3.keyframes`
1119
+ from {
1120
+ opacity: 0;
1121
+ transform: translateY(-8px) scale(0.98);
1122
+ }
1123
+ to {
1124
+ opacity: 1;
1125
+ transform: translateY(0) scale(1);
1126
+ }
1127
+ `;
1128
+ var styles4 = {
1129
+ overlay: _react3.css`
1130
+ position: fixed;
1131
+ inset: 0;
1132
+ background-color: rgba(26, 31, 54, 0.4);
1133
+ backdrop-filter: blur(4px);
1134
+ display: flex;
1135
+ align-items: center;
1136
+ justify-content: center;
1137
+ z-index: 10000;
1138
+ animation: ${fadeIn3} 0.15s ease-out;
1139
+ font-family: ${_chunkUFCWGUAGjs.fontStack};
1140
+ `,
1141
+ modal: _react3.css`
1142
+ ${_chunkUFCWGUAGjs.baseReset}
1143
+ background-color: ${_chunkUFCWGUAGjs.colors.surface};
1144
+ border-radius: 12px;
1145
+ box-shadow: 0 30px 60px -12px rgba(50, 50, 93, 0.25), 0 18px 36px -18px rgba(0, 0, 0, 0.3);
1146
+ max-width: 520px;
1147
+ width: 90%;
1148
+ animation: ${slideIn3} 0.2s ease-out;
1149
+ overflow: hidden;
1150
+ `,
1151
+ header: _react3.css`
1152
+ padding: 24px 24px 0;
1153
+ `,
1154
+ title: _react3.css`
1155
+ font-size: ${_chunkUFCWGUAGjs.fontSize.lg};
1156
+ font-weight: 600;
1157
+ color: ${_chunkUFCWGUAGjs.colors.text};
1158
+ margin: 0;
1159
+ letter-spacing: -0.02em;
1160
+ `,
1161
+ tabs: _react3.css`
1162
+ display: flex;
1163
+ gap: 0;
1164
+ margin-top: 16px;
1165
+ border-bottom: 1px solid ${_chunkUFCWGUAGjs.colors.border};
1166
+ `,
1167
+ tab: _react3.css`
1168
+ padding: 12px 20px;
1169
+ font-size: ${_chunkUFCWGUAGjs.fontSize.base};
1170
+ font-weight: 500;
1171
+ color: ${_chunkUFCWGUAGjs.colors.textSecondary};
1172
+ background: none;
1173
+ border: none;
1174
+ cursor: pointer;
1175
+ position: relative;
1176
+ transition: color 0.15s;
1177
+
1178
+ &:hover {
1179
+ color: ${_chunkUFCWGUAGjs.colors.text};
1180
+ }
1181
+ `,
1182
+ tabActive: _react3.css`
1183
+ color: ${_chunkUFCWGUAGjs.colors.primary};
1184
+
1185
+ &::after {
1186
+ content: '';
1187
+ position: absolute;
1188
+ bottom: -1px;
1189
+ left: 0;
1190
+ right: 0;
1191
+ height: 2px;
1192
+ background-color: ${_chunkUFCWGUAGjs.colors.primary};
1193
+ }
1194
+ `,
1195
+ body: _react3.css`
1196
+ padding: 24px;
1197
+ min-height: 200px;
1198
+ `,
1199
+ dropzone: _react3.css`
1200
+ border: 2px dashed ${_chunkUFCWGUAGjs.colors.border};
1201
+ border-radius: 8px;
1202
+ padding: 40px 24px;
1203
+ text-align: center;
1204
+ cursor: pointer;
1205
+ transition: all 0.15s;
1206
+
1207
+ &:hover {
1208
+ border-color: ${_chunkUFCWGUAGjs.colors.primary};
1209
+ background-color: ${_chunkUFCWGUAGjs.colors.primaryLight};
1210
+ }
1211
+ `,
1212
+ dropzoneActive: _react3.css`
1213
+ border-color: ${_chunkUFCWGUAGjs.colors.primary};
1214
+ background-color: ${_chunkUFCWGUAGjs.colors.primaryLight};
1215
+ `,
1216
+ dropzoneIcon: _react3.css`
1217
+ width: 48px;
1218
+ height: 48px;
1219
+ margin: 0 auto 16px;
1220
+ color: ${_chunkUFCWGUAGjs.colors.textMuted};
1221
+ `,
1222
+ dropzoneText: _react3.css`
1223
+ font-size: ${_chunkUFCWGUAGjs.fontSize.base};
1224
+ color: ${_chunkUFCWGUAGjs.colors.text};
1225
+ margin: 0 0 4px;
1226
+ `,
1227
+ dropzoneHint: _react3.css`
1228
+ font-size: ${_chunkUFCWGUAGjs.fontSize.sm};
1229
+ color: ${_chunkUFCWGUAGjs.colors.textSecondary};
1230
+ margin: 0;
1231
+ `,
1232
+ textarea: _react3.css`
1233
+ width: 100%;
1234
+ min-height: 150px;
1235
+ padding: 12px;
1236
+ font-size: ${_chunkUFCWGUAGjs.fontSize.sm};
1237
+ font-family: ui-monospace, SFMono-Regular, 'SF Mono', Menlo, Consolas, monospace;
1238
+ border: 1px solid ${_chunkUFCWGUAGjs.colors.border};
1239
+ border-radius: 8px;
1240
+ resize: vertical;
1241
+
1242
+ &:focus {
1243
+ outline: none;
1244
+ border-color: ${_chunkUFCWGUAGjs.colors.primary};
1245
+ box-shadow: 0 0 0 3px ${_chunkUFCWGUAGjs.colors.primaryLight};
1246
+ }
1247
+
1248
+ &::placeholder {
1249
+ color: ${_chunkUFCWGUAGjs.colors.textMuted};
1250
+ }
1251
+ `,
1252
+ textareaLabel: _react3.css`
1253
+ font-size: ${_chunkUFCWGUAGjs.fontSize.sm};
1254
+ color: ${_chunkUFCWGUAGjs.colors.textSecondary};
1255
+ margin: 0 0 8px;
1256
+ `,
1257
+ footer: _react3.css`
1258
+ display: flex;
1259
+ justify-content: flex-end;
1260
+ gap: 12px;
1261
+ padding: 16px 24px;
1262
+ border-top: 1px solid ${_chunkUFCWGUAGjs.colors.border};
1263
+ background-color: ${_chunkUFCWGUAGjs.colors.background};
1264
+ `,
1265
+ btn: _react3.css`
1266
+ padding: 10px 18px;
1267
+ font-size: ${_chunkUFCWGUAGjs.fontSize.base};
1268
+ font-weight: 500;
1269
+ border-radius: 6px;
1270
+ cursor: pointer;
1271
+ transition: all 0.15s ease;
1272
+ letter-spacing: -0.01em;
1273
+ `,
1274
+ btnCancel: _react3.css`
1275
+ background-color: ${_chunkUFCWGUAGjs.colors.surface};
1276
+ border: 1px solid ${_chunkUFCWGUAGjs.colors.border};
1277
+ color: ${_chunkUFCWGUAGjs.colors.text};
1278
+
1279
+ &:hover {
1280
+ background-color: ${_chunkUFCWGUAGjs.colors.surfaceHover};
1281
+ border-color: ${_chunkUFCWGUAGjs.colors.borderHover};
1282
+ }
1283
+ `,
1284
+ btnConfirm: _react3.css`
1285
+ background-color: ${_chunkUFCWGUAGjs.colors.primary};
1286
+ border: 1px solid ${_chunkUFCWGUAGjs.colors.primary};
1287
+ color: white;
1288
+
1289
+ &:hover:not(:disabled) {
1290
+ background-color: ${_chunkUFCWGUAGjs.colors.primaryHover};
1291
+ border-color: ${_chunkUFCWGUAGjs.colors.primaryHover};
1292
+ }
1293
+
1294
+ &:disabled {
1295
+ opacity: 0.6;
1296
+ cursor: not-allowed;
1297
+ }
1298
+ `,
1299
+ fileInput: _react3.css`
1300
+ display: none;
1301
+ `,
1302
+ selectedFiles: _react3.css`
1303
+ margin-top: 16px;
1304
+ padding: 12px;
1305
+ background-color: ${_chunkUFCWGUAGjs.colors.background};
1306
+ border-radius: 6px;
1307
+ font-size: ${_chunkUFCWGUAGjs.fontSize.sm};
1308
+ color: ${_chunkUFCWGUAGjs.colors.text};
1309
+ `
1310
+ };
1311
+ function AddNewModal({ currentPath, onClose, onUploadComplete }) {
1312
+ const [activeTab, setActiveTab] = _react.useState.call(void 0, "upload");
1313
+ const [selectedFiles, setSelectedFiles] = _react.useState.call(void 0, []);
1314
+ const [urlInput, setUrlInput] = _react.useState.call(void 0, "");
1315
+ const [isDragging, setIsDragging] = _react.useState.call(void 0, false);
1316
+ const [uploading, setUploading] = _react.useState.call(void 0, false);
1317
+ const [importing, setImporting] = _react.useState.call(void 0, false);
1318
+ const fileInputRef = _react.useRef.call(void 0, null);
1319
+ const handleFileSelect = _react.useCallback.call(void 0, (files) => {
1320
+ if (files) {
1321
+ setSelectedFiles(Array.from(files));
1322
+ }
1323
+ }, []);
1324
+ const handleDrop = _react.useCallback.call(void 0, (e) => {
1325
+ e.preventDefault();
1326
+ setIsDragging(false);
1327
+ handleFileSelect(e.dataTransfer.files);
1328
+ }, [handleFileSelect]);
1329
+ const handleUpload = _react.useCallback.call(void 0, async () => {
1330
+ if (selectedFiles.length === 0) return;
1331
+ setUploading(true);
1332
+ try {
1333
+ for (const file of selectedFiles) {
1334
+ const formData = new FormData();
1335
+ formData.append("file", file);
1336
+ formData.append("path", currentPath);
1337
+ await fetch("/api/studio/upload", {
1338
+ method: "POST",
1339
+ body: formData
1340
+ });
1341
+ }
1342
+ onUploadComplete();
1343
+ onClose();
1344
+ } catch (error) {
1345
+ console.error("Upload failed:", error);
1346
+ } finally {
1347
+ setUploading(false);
1348
+ }
1349
+ }, [selectedFiles, currentPath, onUploadComplete, onClose]);
1350
+ const handleImport = _react.useCallback.call(void 0, async () => {
1351
+ const urls = urlInput.split("\n").map((url) => url.trim()).filter((url) => url.length > 0);
1352
+ if (urls.length === 0) return;
1353
+ setImporting(true);
1354
+ try {
1355
+ const response = await fetch("/api/studio/import", {
1356
+ method: "POST",
1357
+ headers: { "Content-Type": "application/json" },
1358
+ body: JSON.stringify({ urls })
1359
+ });
1360
+ const reader = _optionalChain([response, 'access', _2 => _2.body, 'optionalAccess', _3 => _3.getReader, 'call', _4 => _4()]);
1361
+ if (!reader) throw new Error("No reader");
1362
+ const decoder = new TextDecoder();
1363
+ while (true) {
1364
+ const { done, value } = await reader.read();
1365
+ if (done) break;
1366
+ const text = decoder.decode(value);
1367
+ const lines = text.split("\n\n").filter((line) => line.startsWith("data: "));
1368
+ for (const line of lines) {
1369
+ const data = JSON.parse(line.replace("data: ", ""));
1370
+ if (data.type === "complete") {
1371
+ onUploadComplete();
1372
+ onClose();
1373
+ }
1374
+ }
1375
+ }
1376
+ } catch (error) {
1377
+ console.error("Import failed:", error);
1378
+ } finally {
1379
+ setImporting(false);
1380
+ }
1381
+ }, [urlInput, onUploadComplete, onClose]);
1382
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles4.overlay, onClick: onClose, children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles4.modal, onClick: (e) => e.stopPropagation(), children: [
1383
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles4.header, children: [
1384
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h3", { css: styles4.title, children: "Add New" }),
1385
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles4.tabs, children: [
1386
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1387
+ "button",
1388
+ {
1389
+ css: [styles4.tab, activeTab === "upload" && styles4.tabActive],
1390
+ onClick: () => setActiveTab("upload"),
1391
+ children: "Upload Files"
1392
+ }
1393
+ ),
1394
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1395
+ "button",
1396
+ {
1397
+ css: [styles4.tab, activeTab === "import" && styles4.tabActive],
1398
+ onClick: () => setActiveTab("import"),
1399
+ children: "Import URLs"
1400
+ }
1401
+ )
1402
+ ] })
1403
+ ] }),
1404
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles4.body, children: activeTab === "upload" ? /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _jsxruntime.Fragment, { children: [
1405
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
1406
+ "div",
1407
+ {
1408
+ css: [styles4.dropzone, isDragging && styles4.dropzoneActive],
1409
+ onClick: () => _optionalChain([fileInputRef, 'access', _5 => _5.current, 'optionalAccess', _6 => _6.click, 'call', _7 => _7()]),
1410
+ onDragOver: (e) => {
1411
+ e.preventDefault();
1412
+ setIsDragging(true);
1413
+ },
1414
+ onDragLeave: () => setIsDragging(false),
1415
+ onDrop: handleDrop,
1416
+ children: [
1417
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles4.dropzoneIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 1.5, d: "M7 16a4 4 0 01-.88-7.903A5 5 0 1115.9 6L16 6a5 5 0 011 9.9M15 13l-3-3m0 0l-3 3m3-3v12" }) }),
1418
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { css: styles4.dropzoneText, children: "Drop files here or click to browse" }),
1419
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { css: styles4.dropzoneHint, children: "Supports images and other media files" })
1420
+ ]
1421
+ }
1422
+ ),
1423
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1424
+ "input",
1425
+ {
1426
+ ref: fileInputRef,
1427
+ type: "file",
1428
+ multiple: true,
1429
+ css: styles4.fileInput,
1430
+ onChange: (e) => handleFileSelect(e.target.files)
1431
+ }
1432
+ ),
1433
+ selectedFiles.length > 0 && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles4.selectedFiles, children: [
1434
+ selectedFiles.length,
1435
+ " file",
1436
+ selectedFiles.length !== 1 ? "s" : "",
1437
+ " selected"
1438
+ ] })
1439
+ ] }) : /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _jsxruntime.Fragment, { children: [
1440
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { css: styles4.textareaLabel, children: "Paste image URLs (one per line)" }),
1441
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1442
+ "textarea",
1443
+ {
1444
+ css: styles4.textarea,
1445
+ value: urlInput,
1446
+ onChange: (e) => setUrlInput(e.target.value),
1447
+ placeholder: `https://cdn.example.com/photos/image1.jpg
1448
+ https://cdn.example.com/photos/image2.jpg`
1449
+ }
1450
+ )
1451
+ ] }) }),
1452
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles4.footer, children: [
1453
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1454
+ "button",
1455
+ {
1456
+ css: [styles4.btn, styles4.btnCancel],
1457
+ onClick: onClose,
1458
+ children: "Cancel"
1459
+ }
1460
+ ),
1461
+ activeTab === "upload" ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1462
+ "button",
1463
+ {
1464
+ css: [styles4.btn, styles4.btnConfirm],
1465
+ onClick: handleUpload,
1466
+ disabled: selectedFiles.length === 0 || uploading,
1467
+ children: uploading ? "Uploading..." : "Upload"
1468
+ }
1469
+ ) : /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1470
+ "button",
1471
+ {
1472
+ css: [styles4.btn, styles4.btnConfirm],
1473
+ onClick: handleImport,
1474
+ disabled: !urlInput.trim() || importing,
1475
+ children: importing ? "Importing..." : "Import"
1476
+ }
1477
+ )
1478
+ ] })
1479
+ ] }) });
1480
+ }
1481
+
1110
1482
  // src/components/StudioToolbar.tsx
1111
1483
 
1112
1484
  var btnHeight = "36px";
1113
1485
  var spin = _react3.keyframes`
1114
1486
  to { transform: rotate(360deg); }
1115
1487
  `;
1116
- var styles4 = {
1488
+ var styles5 = {
1117
1489
  toolbar: _react3.css`
1118
1490
  display: flex;
1119
1491
  flex-wrap: nowrap;
@@ -1312,6 +1684,7 @@ function StudioToolbar() {
1312
1684
  const { selectedItems, viewMode, setViewMode, clearSelection, currentPath, triggerRefresh, focusedItem, scanRequested, clearScanRequest } = useStudio();
1313
1685
  const fileInputRef = _react.useRef.call(void 0, null);
1314
1686
  const abortControllerRef = _react.useRef.call(void 0, null);
1687
+ const [showAddNewModal, setShowAddNewModal] = _react.useState.call(void 0, false);
1315
1688
  const [uploading, setUploading] = _react.useState.call(void 0, false);
1316
1689
  const [scanning, setScanning] = _react.useState.call(void 0, false);
1317
1690
  const [processing, setProcessing] = _react.useState.call(void 0, false);
@@ -1338,7 +1711,7 @@ function StudioToolbar() {
1338
1711
  const [pushing, setPushing] = _react.useState.call(void 0, false);
1339
1712
  const isInImagesFolder = currentPath === "public/images" || currentPath.startsWith("public/images/");
1340
1713
  const handleUpload = _react.useCallback.call(void 0, () => {
1341
- _optionalChain([fileInputRef, 'access', _2 => _2.current, 'optionalAccess', _3 => _3.click, 'call', _4 => _4()]);
1714
+ _optionalChain([fileInputRef, 'access', _8 => _8.current, 'optionalAccess', _9 => _9.click, 'call', _10 => _10()]);
1342
1715
  }, []);
1343
1716
  const handleScan = _react.useCallback.call(void 0, async () => {
1344
1717
  setScanning(true);
@@ -1353,7 +1726,7 @@ function StudioToolbar() {
1353
1726
  });
1354
1727
  try {
1355
1728
  const response = await fetch("/api/studio/scan", { method: "POST" });
1356
- const reader = _optionalChain([response, 'access', _5 => _5.body, 'optionalAccess', _6 => _6.getReader, 'call', _7 => _7()]);
1729
+ const reader = _optionalChain([response, 'access', _11 => _11.body, 'optionalAccess', _12 => _12.getReader, 'call', _13 => _13()]);
1357
1730
  if (!reader) throw new Error("No reader");
1358
1731
  const decoder = new TextDecoder();
1359
1732
  let buffer = "";
@@ -1527,7 +1900,7 @@ function StudioToolbar() {
1527
1900
  const selectedPaths2 = Array.from(selectedItems);
1528
1901
  const imageExtensions = ["jpg", "jpeg", "png", "gif", "webp", "svg", "ico", "bmp", "tiff", "tif"];
1529
1902
  const selectedImagePaths = selectedPaths2.filter((p) => {
1530
- const ext = _optionalChain([p, 'access', _8 => _8.split, 'call', _9 => _9("."), 'access', _10 => _10.pop, 'call', _11 => _11(), 'optionalAccess', _12 => _12.toLowerCase, 'call', _13 => _13()]) || "";
1903
+ const ext = _optionalChain([p, 'access', _14 => _14.split, 'call', _15 => _15("."), 'access', _16 => _16.pop, 'call', _17 => _17(), 'optionalAccess', _18 => _18.toLowerCase, 'call', _19 => _19()]) || "";
1531
1904
  return imageExtensions.includes(ext);
1532
1905
  });
1533
1906
  const selectedFolders = selectedPaths2.filter((p) => !p.includes(".") || p.endsWith("/"));
@@ -1690,12 +2063,12 @@ function StudioToolbar() {
1690
2063
  const data = await response.json();
1691
2064
  if (response.ok) {
1692
2065
  setProgressState({
1693
- current: _optionalChain([data, 'access', _14 => _14.processed, 'optionalAccess', _15 => _15.length]) || 0,
1694
- total: _optionalChain([data, 'access', _16 => _16.processed, 'optionalAccess', _17 => _17.length]) || 0,
2066
+ current: _optionalChain([data, 'access', _20 => _20.processed, 'optionalAccess', _21 => _21.length]) || 0,
2067
+ total: _optionalChain([data, 'access', _22 => _22.processed, 'optionalAccess', _23 => _23.length]) || 0,
1695
2068
  percent: 100,
1696
2069
  status: "complete",
1697
- processed: _optionalChain([data, 'access', _18 => _18.processed, 'optionalAccess', _19 => _19.length]) || 0,
1698
- errors: _optionalChain([data, 'access', _20 => _20.errors, 'optionalAccess', _21 => _21.length]) || 0
2070
+ processed: _optionalChain([data, 'access', _24 => _24.processed, 'optionalAccess', _25 => _25.length]) || 0,
2071
+ errors: _optionalChain([data, 'access', _26 => _26.errors, 'optionalAccess', _27 => _27.length]) || 0
1699
2072
  });
1700
2073
  clearSelection();
1701
2074
  triggerRefresh();
@@ -1772,7 +2145,7 @@ function StudioToolbar() {
1772
2145
  const selectedPaths2 = Array.from(selectedItems);
1773
2146
  const imageExtensions = ["jpg", "jpeg", "png", "gif", "webp", "svg", "ico", "bmp", "tiff", "tif"];
1774
2147
  const selectedImagePaths = selectedPaths2.filter((p) => {
1775
- const ext = _optionalChain([p, 'access', _22 => _22.split, 'call', _23 => _23("."), 'access', _24 => _24.pop, 'call', _25 => _25(), 'optionalAccess', _26 => _26.toLowerCase, 'call', _27 => _27()]) || "";
2148
+ const ext = _optionalChain([p, 'access', _28 => _28.split, 'call', _29 => _29("."), 'access', _30 => _30.pop, 'call', _31 => _31(), 'optionalAccess', _32 => _32.toLowerCase, 'call', _33 => _33()]) || "";
1776
2149
  return imageExtensions.includes(ext);
1777
2150
  });
1778
2151
  const selectedFolders = selectedPaths2.filter((p) => !p.includes(".") || p.endsWith("/"));
@@ -1807,7 +2180,7 @@ function StudioToolbar() {
1807
2180
  const selectedPaths2 = Array.from(selectedItems);
1808
2181
  const imageExtensions = ["jpg", "jpeg", "png", "gif", "webp", "svg", "ico", "bmp", "tiff", "tif"];
1809
2182
  const selectedImagePaths = selectedPaths2.filter((p) => {
1810
- const ext = _optionalChain([p, 'access', _28 => _28.split, 'call', _29 => _29("."), 'access', _30 => _30.pop, 'call', _31 => _31(), 'optionalAccess', _32 => _32.toLowerCase, 'call', _33 => _33()]) || "";
2183
+ const ext = _optionalChain([p, 'access', _34 => _34.split, 'call', _35 => _35("."), 'access', _36 => _36.pop, 'call', _37 => _37(), 'optionalAccess', _38 => _38.toLowerCase, 'call', _39 => _39()]) || "";
1811
2184
  return imageExtensions.includes(ext);
1812
2185
  });
1813
2186
  const selectedFolders = selectedPaths2.filter((p) => !p.includes(".") || p.endsWith("/"));
@@ -1858,16 +2231,16 @@ function StudioToolbar() {
1858
2231
  });
1859
2232
  const data = await response.json();
1860
2233
  if (!response.ok) {
1861
- if (_optionalChain([data, 'access', _34 => _34.error, 'optionalAccess', _35 => _35.includes, 'call', _36 => _36("R2 not configured")]) || _optionalChain([data, 'access', _37 => _37.error, 'optionalAccess', _38 => _38.includes, 'call', _39 => _39("CLOUDFLARE_R2")])) {
2234
+ if (_optionalChain([data, 'access', _40 => _40.error, 'optionalAccess', _41 => _41.includes, 'call', _42 => _42("R2 not configured")]) || _optionalChain([data, 'access', _43 => _43.error, 'optionalAccess', _44 => _44.includes, 'call', _45 => _45("CLOUDFLARE_R2")])) {
1862
2235
  setShowProgress(false);
1863
2236
  setShowR2SetupModal(true);
1864
2237
  return;
1865
2238
  }
1866
2239
  errors++;
1867
2240
  errorMessages.push(data.error || `Failed: ${imageKey}`);
1868
- } else if (_optionalChain([data, 'access', _40 => _40.pushed, 'optionalAccess', _41 => _41.length]) > 0) {
2241
+ } else if (_optionalChain([data, 'access', _46 => _46.pushed, 'optionalAccess', _47 => _47.length]) > 0) {
1869
2242
  pushed++;
1870
- } else if (_optionalChain([data, 'access', _42 => _42.errors, 'optionalAccess', _43 => _43.length]) > 0) {
2243
+ } else if (_optionalChain([data, 'access', _48 => _48.errors, 'optionalAccess', _49 => _49.length]) > 0) {
1871
2244
  errors++;
1872
2245
  for (const errMsg of data.errors) {
1873
2246
  errorMessages.push(errMsg);
@@ -2095,7 +2468,18 @@ function StudioToolbar() {
2095
2468
  onClose: () => setShowR2SetupModal(false)
2096
2469
  }
2097
2470
  ),
2098
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles4.toolbar, children: [
2471
+ showAddNewModal && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2472
+ AddNewModal,
2473
+ {
2474
+ currentPath,
2475
+ onClose: () => setShowAddNewModal(false),
2476
+ onUploadComplete: () => {
2477
+ setShowAddNewModal(false);
2478
+ triggerRefresh();
2479
+ }
2480
+ }
2481
+ ),
2482
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles5.toolbar, children: [
2099
2483
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2100
2484
  "input",
2101
2485
  {
@@ -2107,23 +2491,23 @@ function StudioToolbar() {
2107
2491
  style: { display: "none" }
2108
2492
  }
2109
2493
  ),
2110
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles4.left, children: [
2494
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles5.left, children: [
2111
2495
  /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
2112
2496
  "button",
2113
2497
  {
2114
- css: [styles4.btn, styles4.btnPrimary],
2115
- onClick: handleUpload,
2498
+ css: [styles5.btn, styles5.btnPrimary],
2499
+ onClick: () => setShowAddNewModal(true),
2116
2500
  disabled: uploading || isInImagesFolder,
2117
2501
  children: [
2118
2502
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, UploadIcon, {}),
2119
- uploading ? "Uploading..." : "Upload"
2503
+ "Add New"
2120
2504
  ]
2121
2505
  }
2122
2506
  ),
2123
2507
  /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
2124
2508
  "button",
2125
2509
  {
2126
- css: styles4.btn,
2510
+ css: styles5.btn,
2127
2511
  onClick: () => singleFolderSelected ? setShowRenameFolderModal(true) : setShowNewFolderModal(true),
2128
2512
  disabled: isInImagesFolder && !singleFolderSelected,
2129
2513
  title: isInImagesFolder && !singleFolderSelected ? "Cannot create folders in protected images folder" : void 0,
@@ -2133,11 +2517,11 @@ function StudioToolbar() {
2133
2517
  ]
2134
2518
  }
2135
2519
  ),
2136
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles4.divider }),
2520
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles5.divider }),
2137
2521
  /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
2138
2522
  "button",
2139
2523
  {
2140
- css: styles4.btn,
2524
+ css: styles5.btn,
2141
2525
  onClick: handleProcessImages,
2142
2526
  disabled: processing || isInImagesFolder,
2143
2527
  title: isInImagesFolder ? "Cannot process images folder" : void 0,
@@ -2150,7 +2534,7 @@ function StudioToolbar() {
2150
2534
  /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
2151
2535
  "button",
2152
2536
  {
2153
- css: [styles4.btn, styles4.btnDanger],
2537
+ css: [styles5.btn, styles5.btnDanger],
2154
2538
  onClick: handleDeleteClick,
2155
2539
  disabled: !hasSelection,
2156
2540
  children: [
@@ -2162,7 +2546,7 @@ function StudioToolbar() {
2162
2546
  /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
2163
2547
  "button",
2164
2548
  {
2165
- css: styles4.btn,
2549
+ css: styles5.btn,
2166
2550
  onClick: handleMoveClick,
2167
2551
  disabled: !hasSelection,
2168
2552
  children: [
@@ -2174,7 +2558,7 @@ function StudioToolbar() {
2174
2558
  /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
2175
2559
  "button",
2176
2560
  {
2177
- css: styles4.btn,
2561
+ css: styles5.btn,
2178
2562
  onClick: handleSyncClick,
2179
2563
  disabled: !hasSelection,
2180
2564
  children: [
@@ -2183,11 +2567,11 @@ function StudioToolbar() {
2183
2567
  ]
2184
2568
  }
2185
2569
  ),
2186
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles4.searchWrapper, children: [
2570
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles5.searchWrapper, children: [
2187
2571
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2188
2572
  "input",
2189
2573
  {
2190
- css: styles4.searchInput,
2574
+ css: styles5.searchInput,
2191
2575
  type: "text",
2192
2576
  placeholder: "Search images...",
2193
2577
  value: searchQuery,
@@ -2198,7 +2582,7 @@ function StudioToolbar() {
2198
2582
  searchQuery && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2199
2583
  "button",
2200
2584
  {
2201
- css: styles4.searchClearBtn,
2585
+ css: styles5.searchClearBtn,
2202
2586
  onClick: () => setSearchQuery(""),
2203
2587
  title: "Clear search",
2204
2588
  children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { width: "14", height: "14", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M6 18L18 6M6 6l12 12" }) })
@@ -2206,16 +2590,16 @@ function StudioToolbar() {
2206
2590
  )
2207
2591
  ] })
2208
2592
  ] }),
2209
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles4.right, children: [
2210
- hasSelection && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "span", { css: styles4.selectionCount, children: [
2593
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles5.right, children: [
2594
+ hasSelection && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "span", { css: styles5.selectionCount, children: [
2211
2595
  selectedItems.size,
2212
2596
  " selected",
2213
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "button", { css: styles4.clearBtn, onClick: clearSelection, children: "Clear" })
2597
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "button", { css: styles5.clearBtn, onClick: clearSelection, children: "Clear" })
2214
2598
  ] }),
2215
2599
  /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
2216
2600
  "button",
2217
2601
  {
2218
- css: styles4.btn,
2602
+ css: styles5.btn,
2219
2603
  onClick: handleScan,
2220
2604
  disabled: scanning,
2221
2605
  children: [
@@ -2224,11 +2608,11 @@ function StudioToolbar() {
2224
2608
  ]
2225
2609
  }
2226
2610
  ),
2227
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles4.viewToggle, children: [
2611
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles5.viewToggle, children: [
2228
2612
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2229
2613
  "button",
2230
2614
  {
2231
- css: [styles4.viewBtn, viewMode === "grid" && styles4.viewBtnActive],
2615
+ css: [styles5.viewBtn, viewMode === "grid" && styles5.viewBtnActive],
2232
2616
  onClick: () => setViewMode("grid"),
2233
2617
  "aria-label": "Grid view",
2234
2618
  children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, GridIcon, {})
@@ -2237,7 +2621,7 @@ function StudioToolbar() {
2237
2621
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2238
2622
  "button",
2239
2623
  {
2240
- css: [styles4.viewBtn, viewMode === "list" && styles4.viewBtnActive],
2624
+ css: [styles5.viewBtn, viewMode === "list" && styles5.viewBtnActive],
2241
2625
  onClick: () => setViewMode("list"),
2242
2626
  "aria-label": "List view",
2243
2627
  children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, ListIcon, {})
@@ -2249,34 +2633,34 @@ function StudioToolbar() {
2249
2633
  ] });
2250
2634
  }
2251
2635
  function UploadIcon() {
2252
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles4.icon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-8l-4-4m0 0L8 8m4-4v12" }) });
2636
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles5.icon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-8l-4-4m0 0L8 8m4-4v12" }) });
2253
2637
  }
2254
2638
  function ScanIcon({ spinning }) {
2255
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: [styles4.icon, spinning && styles4.iconSpin], fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15" }) });
2639
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: [styles5.icon, spinning && styles5.iconSpin], fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15" }) });
2256
2640
  }
2257
2641
  function TrashIcon() {
2258
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles4.icon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16" }) });
2642
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles5.icon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16" }) });
2259
2643
  }
2260
2644
  function FolderPlusIcon() {
2261
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles4.icon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M9 13h6m-3-3v6m-9 1V7a2 2 0 012-2h6l2 2h6a2 2 0 012 2v8a2 2 0 01-2 2H5a2 2 0 01-2-2z" }) });
2645
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles5.icon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M9 13h6m-3-3v6m-9 1V7a2 2 0 012-2h6l2 2h6a2 2 0 012 2v8a2 2 0 01-2 2H5a2 2 0 01-2-2z" }) });
2262
2646
  }
2263
2647
  function RenameIcon() {
2264
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles4.icon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.414-9.414a2 2 0 112.828 2.828L11.828 15H9v-2.828l8.586-8.586z" }) });
2648
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles5.icon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.414-9.414a2 2 0 112.828 2.828L11.828 15H9v-2.828l8.586-8.586z" }) });
2265
2649
  }
2266
2650
  function MoveIcon() {
2267
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles4.icon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M8 7h12m0 0l-4-4m4 4l-4 4m0 6H4m0 0l4 4m-4-4l4-4" }) });
2651
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles5.icon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M8 7h12m0 0l-4-4m4 4l-4 4m0 6H4m0 0l4 4m-4-4l4-4" }) });
2268
2652
  }
2269
2653
  function CloudIcon() {
2270
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles4.icon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M7 16a4 4 0 01-.88-7.903A5 5 0 1115.9 6L16 6a5 5 0 011 9.9M15 13l-3-3m0 0l-3 3m3-3v12" }) });
2654
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles5.icon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M7 16a4 4 0 01-.88-7.903A5 5 0 1115.9 6L16 6a5 5 0 011 9.9M15 13l-3-3m0 0l-3 3m3-3v12" }) });
2271
2655
  }
2272
2656
  function GridIcon() {
2273
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles4.icon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M4 6a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2H6a2 2 0 01-2-2V6zM14 6a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2h-2a2 2 0 01-2-2V6zM4 16a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2H6a2 2 0 01-2-2v-2zM14 16a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2h-2a2 2 0 01-2-2v-2z" }) });
2657
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles5.icon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M4 6a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2H6a2 2 0 01-2-2V6zM14 6a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2h-2a2 2 0 01-2-2V6zM4 16a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2H6a2 2 0 01-2-2v-2zM14 16a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2h-2a2 2 0 01-2-2v-2z" }) });
2274
2658
  }
2275
2659
  function ListIcon() {
2276
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles4.icon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M4 6h16M4 10h16M4 14h16M4 18h16" }) });
2660
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles5.icon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M4 6h16M4 10h16M4 14h16M4 18h16" }) });
2277
2661
  }
2278
2662
  function ImageStackIcon() {
2279
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles4.icon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z" }) });
2663
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles5.icon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z" }) });
2280
2664
  }
2281
2665
 
2282
2666
  // src/components/StudioFileGrid.tsx
@@ -2480,7 +2864,7 @@ function useFileList() {
2480
2864
  var spin2 = _react3.keyframes`
2481
2865
  to { transform: rotate(360deg); }
2482
2866
  `;
2483
- var styles5 = {
2867
+ var styles6 = {
2484
2868
  loading: _react3.css`
2485
2869
  display: flex;
2486
2870
  align-items: center;
@@ -2838,17 +3222,17 @@ function StudioFileGrid() {
2838
3222
  triggerScan
2839
3223
  } = useFileList();
2840
3224
  if (loading) {
2841
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles5.loading, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles5.spinner }) });
3225
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles6.loading, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles6.spinner }) });
2842
3226
  }
2843
3227
  if (metaEmpty && isAtRoot) {
2844
- return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles5.empty, children: [
2845
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles5.emptyIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 1.5, d: "M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" }) }),
2846
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { css: styles5.emptyText, children: "No files tracked yet" }),
2847
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { css: styles5.emptyText, children: "Click Scan to discover files in your public folder" }),
3228
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles6.empty, children: [
3229
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles6.emptyIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 1.5, d: "M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" }) }),
3230
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { css: styles6.emptyText, children: "No files tracked yet" }),
3231
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { css: styles6.emptyText, children: "Click Scan to discover files in your public folder" }),
2848
3232
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2849
3233
  "button",
2850
3234
  {
2851
- css: styles5.scanButton,
3235
+ css: styles6.scanButton,
2852
3236
  onClick: triggerScan,
2853
3237
  children: "Scan for Files"
2854
3238
  }
@@ -2856,19 +3240,19 @@ function StudioFileGrid() {
2856
3240
  ] });
2857
3241
  }
2858
3242
  if (sortedItems.length === 0 && isAtRoot) {
2859
- return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles5.empty, children: [
2860
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles5.emptyIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 1.5, d: "M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z" }) }),
2861
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { css: styles5.emptyText, children: "No files in this folder" }),
2862
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { css: styles5.emptyText, children: "Upload images or click Scan in the toolbar" })
3243
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles6.empty, children: [
3244
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles6.emptyIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 1.5, d: "M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z" }) }),
3245
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { css: styles6.emptyText, children: "No files in this folder" }),
3246
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { css: styles6.emptyText, children: "Upload images or click Scan in the toolbar" })
2863
3247
  ] });
2864
3248
  }
2865
3249
  return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { children: [
2866
- sortedItems.length > 0 && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles5.selectAllRow, children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "label", { css: styles5.selectAllLabel, children: [
3250
+ sortedItems.length > 0 && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles6.selectAllRow, children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "label", { css: styles6.selectAllLabel, children: [
2867
3251
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2868
3252
  "input",
2869
3253
  {
2870
3254
  type: "checkbox",
2871
- css: styles5.selectAllCheckbox,
3255
+ css: styles6.selectAllCheckbox,
2872
3256
  checked: allItemsSelected,
2873
3257
  ref: (el) => {
2874
3258
  if (el) el.indeterminate = someItemsSelected && !allItemsSelected;
@@ -2880,17 +3264,17 @@ function StudioFileGrid() {
2880
3264
  sortedItems.length,
2881
3265
  ")"
2882
3266
  ] }) }),
2883
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles5.grid, children: [
3267
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles6.grid, children: [
2884
3268
  !isAtRoot && !isSearching && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
2885
3269
  "div",
2886
3270
  {
2887
- css: [styles5.item, styles5.parentItem],
3271
+ css: [styles6.item, styles6.parentItem],
2888
3272
  onClick: navigateUp,
2889
3273
  children: [
2890
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles5.content, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles5.parentIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 1.5, d: "M3 10h10a8 8 0 018 8v2M3 10l6 6m-6-6l6-6" }) }) }),
2891
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles5.label, children: [
2892
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { css: styles5.name, children: ".." }),
2893
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { css: styles5.size, children: "Parent folder" })
3274
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles6.content, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles6.parentIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 1.5, d: "M3 10h10a8 8 0 018 8v2M3 10l6 6m-6-6l6-6" }) }) }),
3275
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles6.label, children: [
3276
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { css: styles6.name, children: ".." }),
3277
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { css: styles6.size, children: "Parent folder" })
2894
3278
  ] })
2895
3279
  ]
2896
3280
  }
@@ -2924,43 +3308,43 @@ function GridItem({ item, isSelected, onClick, onOpen, onGenerateThumbnail }) {
2924
3308
  return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
2925
3309
  "div",
2926
3310
  {
2927
- css: [styles5.item, isSelected && styles5.itemSelected],
3311
+ css: [styles6.item, isSelected && styles6.itemSelected],
2928
3312
  onClick,
2929
3313
  children: [
2930
3314
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2931
3315
  "div",
2932
3316
  {
2933
- css: styles5.checkboxWrapper,
3317
+ css: styles6.checkboxWrapper,
2934
3318
  onClick: (e) => e.stopPropagation(),
2935
3319
  children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2936
3320
  "input",
2937
3321
  {
2938
3322
  type: "checkbox",
2939
- css: styles5.checkbox,
3323
+ css: styles6.checkbox,
2940
3324
  checked: isSelected,
2941
3325
  onChange: () => onClick({})
2942
3326
  }
2943
3327
  )
2944
3328
  }
2945
3329
  ),
2946
- item.cdnPushed && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css: styles5.cdnBadge, children: "CDN" }),
2947
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles5.content, children: [
3330
+ item.cdnPushed && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css: styles6.cdnBadge, children: "CDN" }),
3331
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles6.content, children: [
2948
3332
  /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
2949
3333
  "button",
2950
3334
  {
2951
- css: styles5.copyBtn,
3335
+ css: styles6.copyBtn,
2952
3336
  onClick: handleCopyPath,
2953
3337
  title: "Copy file path",
2954
3338
  children: [
2955
- showCopied && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css: styles5.tooltip, children: "Copied!" }),
2956
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles5.copyIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2" }) })
3339
+ showCopied && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css: styles6.tooltip, children: "Copied!" }),
3340
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles6.copyIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2" }) })
2957
3341
  ]
2958
3342
  }
2959
3343
  ),
2960
3344
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2961
3345
  "button",
2962
3346
  {
2963
- css: styles5.openBtn,
3347
+ css: styles6.openBtn,
2964
3348
  onClick: (e) => {
2965
3349
  e.stopPropagation();
2966
3350
  onOpen();
@@ -2968,13 +3352,13 @@ function GridItem({ item, isSelected, onClick, onOpen, onGenerateThumbnail }) {
2968
3352
  children: "Open"
2969
3353
  }
2970
3354
  ),
2971
- isFolder ? isImagesFolder ? /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles5.imagesFolderWrapper, children: [
2972
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles5.imagesFolderIcon, fill: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { d: "M10 4H4a2 2 0 00-2 2v12a2 2 0 002 2h16a2 2 0 002-2V8a2 2 0 00-2-2h-8l-2-2z" }) }),
2973
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles5.lockIcon, fill: "currentColor", viewBox: "0 0 20 20", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { fillRule: "evenodd", d: "M5 9V7a5 5 0 0110 0v2a2 2 0 012 2v5a2 2 0 01-2 2H5a2 2 0 01-2-2v-5a2 2 0 012-2zm8-2v2H7V7a3 3 0 016 0z", clipRule: "evenodd" }) })
2974
- ] }) : /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles5.folderIcon, fill: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { d: "M10 4H4a2 2 0 00-2 2v12a2 2 0 002 2h16a2 2 0 002-2V8a2 2 0 00-2-2h-8l-2-2z" }) }) : isImage && item.hasThumbnail ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
3355
+ isFolder ? isImagesFolder ? /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles6.imagesFolderWrapper, children: [
3356
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles6.imagesFolderIcon, fill: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { d: "M10 4H4a2 2 0 00-2 2v12a2 2 0 002 2h16a2 2 0 002-2V8a2 2 0 00-2-2h-8l-2-2z" }) }),
3357
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles6.lockIcon, fill: "currentColor", viewBox: "0 0 20 20", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { fillRule: "evenodd", d: "M5 9V7a5 5 0 0110 0v2a2 2 0 012 2v5a2 2 0 01-2 2H5a2 2 0 01-2-2v-5a2 2 0 012-2zm8-2v2H7V7a3 3 0 016 0z", clipRule: "evenodd" }) })
3358
+ ] }) : /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles6.folderIcon, fill: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { d: "M10 4H4a2 2 0 00-2 2v12a2 2 0 002 2h16a2 2 0 002-2V8a2 2 0 00-2-2h-8l-2-2z" }) }) : isImage && item.hasThumbnail ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2975
3359
  "img",
2976
3360
  {
2977
- css: styles5.image,
3361
+ css: styles6.image,
2978
3362
  src: item.thumbnail,
2979
3363
  alt: item.name,
2980
3364
  loading: "lazy"
@@ -2982,26 +3366,26 @@ function GridItem({ item, isSelected, onClick, onOpen, onGenerateThumbnail }) {
2982
3366
  ) : isImage && !item.hasThumbnail ? /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
2983
3367
  "button",
2984
3368
  {
2985
- css: styles5.noThumbnail,
3369
+ css: styles6.noThumbnail,
2986
3370
  onClick: (e) => {
2987
3371
  e.stopPropagation();
2988
3372
  onGenerateThumbnail();
2989
3373
  },
2990
3374
  title: "Generate thumbnail",
2991
3375
  children: [
2992
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles5.noThumbnailIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 1.5, d: "M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z" }) }),
2993
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css: styles5.noThumbnailText, children: "Generate" })
3376
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles6.noThumbnailIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 1.5, d: "M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z" }) }),
3377
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css: styles6.noThumbnailText, children: "Generate" })
2994
3378
  ]
2995
3379
  }
2996
- ) : /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles5.fileIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 1.5, d: "M7 21h10a2 2 0 002-2V9.414a1 1 0 00-.293-.707l-5.414-5.414A1 1 0 0012.586 3H7a2 2 0 00-2 2v14a2 2 0 002 2z" }) })
3380
+ ) : /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles6.fileIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 1.5, d: "M7 21h10a2 2 0 002-2V9.414a1 1 0 00-.293-.707l-5.414-5.414A1 1 0 0012.586 3H7a2 2 0 00-2 2v14a2 2 0 002 2z" }) })
2997
3381
  ] }),
2998
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles5.label, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles5.labelRow, children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles5.labelText, children: [
2999
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { css: styles5.name, title: item.name, children: truncateMiddle(item.name) }),
3000
- isFolder ? /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "p", { css: styles5.size, children: [
3382
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles6.label, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles6.labelRow, children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles6.labelText, children: [
3383
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { css: styles6.name, title: item.name, children: truncateMiddle(item.name) }),
3384
+ isFolder ? /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "p", { css: styles6.size, children: [
3001
3385
  item.fileCount !== void 0 ? `${item.fileCount} files` : "",
3002
3386
  item.fileCount !== void 0 && item.totalSize !== void 0 ? " \xB7 " : "",
3003
3387
  item.totalSize !== void 0 ? formatFileSize(item.totalSize) : ""
3004
- ] }) : item.size !== void 0 && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { css: styles5.size, children: formatFileSize(item.size) })
3388
+ ] }) : item.size !== void 0 && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { css: styles6.size, children: formatFileSize(item.size) })
3005
3389
  ] }) }) })
3006
3390
  ]
3007
3391
  }
@@ -3033,7 +3417,7 @@ function truncateMiddle(str, maxLength = 24) {
3033
3417
  var spin3 = _react3.keyframes`
3034
3418
  to { transform: rotate(360deg); }
3035
3419
  `;
3036
- var styles6 = {
3420
+ var styles7 = {
3037
3421
  loading: _react3.css`
3038
3422
  display: flex;
3039
3423
  align-items: center;
@@ -3384,16 +3768,16 @@ function StudioFileList() {
3384
3768
  triggerScan
3385
3769
  } = useFileList();
3386
3770
  if (loading) {
3387
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles6.loading, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles6.spinner }) });
3771
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles7.loading, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles7.spinner }) });
3388
3772
  }
3389
3773
  if (metaEmpty && isAtRoot) {
3390
- return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles6.empty, children: [
3774
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles7.empty, children: [
3391
3775
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { children: "No files tracked yet" }),
3392
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { css: styles6.emptyHint, children: "Click Scan to discover files in your public folder" }),
3776
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { css: styles7.emptyHint, children: "Click Scan to discover files in your public folder" }),
3393
3777
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
3394
3778
  "button",
3395
3779
  {
3396
- css: styles6.scanButton,
3780
+ css: styles7.scanButton,
3397
3781
  onClick: triggerScan,
3398
3782
  children: "Scan for Files"
3399
3783
  }
@@ -3401,18 +3785,18 @@ function StudioFileList() {
3401
3785
  ] });
3402
3786
  }
3403
3787
  if (sortedItems.length === 0 && isAtRoot) {
3404
- return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles6.empty, children: [
3788
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles7.empty, children: [
3405
3789
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { children: "No files in this folder" }),
3406
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { css: styles6.emptyHint, children: "Upload images or click Scan in the toolbar" })
3790
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { css: styles7.emptyHint, children: "Upload images or click Scan in the toolbar" })
3407
3791
  ] });
3408
3792
  }
3409
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles6.tableWrapper, children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "table", { css: styles6.table, children: [
3793
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles7.tableWrapper, children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "table", { css: styles7.table, children: [
3410
3794
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "thead", { children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "tr", { children: [
3411
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "th", { css: [styles6.th, styles6.thCheckbox], children: sortedItems.length > 0 && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
3795
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "th", { css: [styles7.th, styles7.thCheckbox], children: sortedItems.length > 0 && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
3412
3796
  "input",
3413
3797
  {
3414
3798
  type: "checkbox",
3415
- css: styles6.checkbox,
3799
+ css: styles7.checkbox,
3416
3800
  checked: allItemsSelected,
3417
3801
  ref: (el) => {
3418
3802
  if (el) el.indeterminate = someItemsSelected && !allItemsSelected;
@@ -3420,21 +3804,21 @@ function StudioFileList() {
3420
3804
  onChange: handleSelectAll
3421
3805
  }
3422
3806
  ) }),
3423
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "th", { css: styles6.th, children: "Name" }),
3424
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "th", { css: [styles6.th, styles6.thSize], children: "Size" }),
3425
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "th", { css: [styles6.th, styles6.thDimensions], children: "Dimensions" }),
3426
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "th", { css: [styles6.th, styles6.thCdn], children: "CDN" })
3807
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "th", { css: styles7.th, children: "Name" }),
3808
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "th", { css: [styles7.th, styles7.thSize], children: "Size" }),
3809
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "th", { css: [styles7.th, styles7.thDimensions], children: "Dimensions" }),
3810
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "th", { css: [styles7.th, styles7.thCdn], children: "CDN" })
3427
3811
  ] }) }),
3428
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "tbody", { css: styles6.tbody, children: [
3429
- !isAtRoot && !isSearching && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "tr", { css: styles6.parentRow, onClick: navigateUp, children: [
3430
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "td", { css: styles6.td }),
3431
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "td", { css: styles6.td, children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles6.nameCell, children: [
3432
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles6.parentIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 1.5, d: "M3 10h10a8 8 0 018 8v2M3 10l6 6m-6-6l6-6" }) }),
3433
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css: styles6.name, children: ".." })
3812
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "tbody", { css: styles7.tbody, children: [
3813
+ !isAtRoot && !isSearching && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "tr", { css: styles7.parentRow, onClick: navigateUp, children: [
3814
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "td", { css: styles7.td }),
3815
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "td", { css: styles7.td, children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles7.nameCell, children: [
3816
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles7.parentIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 1.5, d: "M3 10h10a8 8 0 018 8v2M3 10l6 6m-6-6l6-6" }) }),
3817
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css: styles7.name, children: ".." })
3434
3818
  ] }) }),
3435
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "td", { css: [styles6.td, styles6.meta], children: "--" }),
3436
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "td", { css: [styles6.td, styles6.meta], children: "Parent folder" }),
3437
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "td", { css: styles6.td, children: "--" })
3819
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "td", { css: [styles7.td, styles7.meta], children: "--" }),
3820
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "td", { css: [styles7.td, styles7.meta], children: "Parent folder" }),
3821
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "td", { css: styles7.td, children: "--" })
3438
3822
  ] }),
3439
3823
  sortedItems.map((item) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
3440
3824
  ListRow,
@@ -3465,59 +3849,59 @@ function ListRow({ item, isSelected, onClick, onOpen, onGenerateThumbnail }) {
3465
3849
  return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
3466
3850
  "tr",
3467
3851
  {
3468
- css: [styles6.row, isSelected && styles6.rowSelected],
3852
+ css: [styles7.row, isSelected && styles7.rowSelected],
3469
3853
  onClick,
3470
3854
  children: [
3471
3855
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
3472
3856
  "td",
3473
3857
  {
3474
- css: [styles6.td, styles6.checkboxCell],
3858
+ css: [styles7.td, styles7.checkboxCell],
3475
3859
  onClick: (e) => e.stopPropagation(),
3476
3860
  children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
3477
3861
  "input",
3478
3862
  {
3479
3863
  type: "checkbox",
3480
- css: styles6.checkbox,
3864
+ css: styles7.checkbox,
3481
3865
  checked: isSelected,
3482
3866
  onChange: () => onClick({})
3483
3867
  }
3484
3868
  )
3485
3869
  }
3486
3870
  ),
3487
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "td", { css: styles6.td, children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles6.nameCell, children: [
3488
- isFolder ? isImagesFolder ? /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles6.imagesFolderWrapper, children: [
3489
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles6.imagesFolderIcon, fill: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { d: "M10 4H4a2 2 0 00-2 2v12a2 2 0 002 2h16a2 2 0 002-2V8a2 2 0 00-2-2h-8l-2-2z" }) }),
3490
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles6.lockIcon, fill: "currentColor", viewBox: "0 0 20 20", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { fillRule: "evenodd", d: "M5 9V7a5 5 0 0110 0v2a2 2 0 012 2v5a2 2 0 01-2 2H5a2 2 0 01-2-2v-5a2 2 0 012-2zm8-2v2H7V7a3 3 0 016 0z", clipRule: "evenodd" }) })
3491
- ] }) : /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles6.folderIconWrapper, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles6.folderIcon, fill: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { d: "M10 4H4a2 2 0 00-2 2v12a2 2 0 002 2h16a2 2 0 002-2V8a2 2 0 00-2-2h-8l-2-2z" }) }) }) : isImage && item.hasThumbnail ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles6.thumbnailWrapper, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "img", { css: styles6.thumbnail, src: item.thumbnail, alt: item.name, loading: "lazy" }) }) : isImage && !item.hasThumbnail ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles6.thumbnailWrapper, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
3871
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "td", { css: styles7.td, children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles7.nameCell, children: [
3872
+ isFolder ? isImagesFolder ? /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles7.imagesFolderWrapper, children: [
3873
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles7.imagesFolderIcon, fill: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { d: "M10 4H4a2 2 0 00-2 2v12a2 2 0 002 2h16a2 2 0 002-2V8a2 2 0 00-2-2h-8l-2-2z" }) }),
3874
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles7.lockIcon, fill: "currentColor", viewBox: "0 0 20 20", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { fillRule: "evenodd", d: "M5 9V7a5 5 0 0110 0v2a2 2 0 012 2v5a2 2 0 01-2 2H5a2 2 0 01-2-2v-5a2 2 0 012-2zm8-2v2H7V7a3 3 0 016 0z", clipRule: "evenodd" }) })
3875
+ ] }) : /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles7.folderIconWrapper, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles7.folderIcon, fill: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { d: "M10 4H4a2 2 0 00-2 2v12a2 2 0 002 2h16a2 2 0 002-2V8a2 2 0 00-2-2h-8l-2-2z" }) }) }) : isImage && item.hasThumbnail ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles7.thumbnailWrapper, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "img", { css: styles7.thumbnail, src: item.thumbnail, alt: item.name, loading: "lazy" }) }) : isImage && !item.hasThumbnail ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles7.thumbnailWrapper, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
3492
3876
  "button",
3493
3877
  {
3494
- css: styles6.noThumbnail,
3878
+ css: styles7.noThumbnail,
3495
3879
  onClick: (e) => {
3496
3880
  e.stopPropagation();
3497
3881
  onGenerateThumbnail();
3498
3882
  },
3499
3883
  title: "Generate thumbnail",
3500
- children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles6.noThumbnailIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z" }) })
3884
+ children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles7.noThumbnailIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z" }) })
3501
3885
  }
3502
- ) }) : /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles6.thumbnailWrapper, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles6.fileIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 1.5, d: "M7 21h10a2 2 0 002-2V9.414a1 1 0 00-.293-.707l-5.414-5.414A1 1 0 0012.586 3H7a2 2 0 00-2 2v14a2 2 0 002 2z" }) }) }),
3503
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css: styles6.name, title: item.name, children: truncateMiddle2(item.name) }),
3504
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles6.actionsCell, children: [
3886
+ ) }) : /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles7.thumbnailWrapper, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles7.fileIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 1.5, d: "M7 21h10a2 2 0 002-2V9.414a1 1 0 00-.293-.707l-5.414-5.414A1 1 0 0012.586 3H7a2 2 0 00-2 2v14a2 2 0 002 2z" }) }) }),
3887
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css: styles7.name, title: item.name, children: truncateMiddle2(item.name) }),
3888
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles7.actionsCell, children: [
3505
3889
  /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
3506
3890
  "button",
3507
3891
  {
3508
- css: styles6.copyBtn,
3892
+ css: styles7.copyBtn,
3509
3893
  onClick: handleCopyPath,
3510
3894
  title: "Copy file path",
3511
3895
  children: [
3512
- showCopied && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css: styles6.tooltip, children: "Copied!" }),
3513
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles6.copyIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2" }) })
3896
+ showCopied && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css: styles7.tooltip, children: "Copied!" }),
3897
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles7.copyIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2" }) })
3514
3898
  ]
3515
3899
  }
3516
3900
  ),
3517
3901
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
3518
3902
  "button",
3519
3903
  {
3520
- css: styles6.openBtn,
3904
+ css: styles7.openBtn,
3521
3905
  onClick: (e) => {
3522
3906
  e.stopPropagation();
3523
3907
  onOpen();
@@ -3527,12 +3911,12 @@ function ListRow({ item, isSelected, onClick, onOpen, onGenerateThumbnail }) {
3527
3911
  )
3528
3912
  ] })
3529
3913
  ] }) }),
3530
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "td", { css: [styles6.td, styles6.meta], children: isFolder ? item.fileCount !== void 0 ? `${item.fileCount} files` : "--" : item.size !== void 0 ? formatFileSize2(item.size) : "--" }),
3531
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "td", { css: [styles6.td, styles6.meta], children: isFolder ? item.totalSize !== void 0 ? formatFileSize2(item.totalSize) : "--" : item.dimensions ? `${item.dimensions.width}x${item.dimensions.height}` : "--" }),
3532
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "td", { css: styles6.td, children: item.cdnPushed ? /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "span", { css: styles6.cdnBadge, children: [
3533
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles6.cdnIcon, fill: "currentColor", viewBox: "0 0 20 20", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { fillRule: "evenodd", d: "M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z", clipRule: "evenodd" }) }),
3914
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "td", { css: [styles7.td, styles7.meta], children: isFolder ? item.fileCount !== void 0 ? `${item.fileCount} files` : "--" : item.size !== void 0 ? formatFileSize2(item.size) : "--" }),
3915
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "td", { css: [styles7.td, styles7.meta], children: isFolder ? item.totalSize !== void 0 ? formatFileSize2(item.totalSize) : "--" : item.dimensions ? `${item.dimensions.width}x${item.dimensions.height}` : "--" }),
3916
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "td", { css: styles7.td, children: item.cdnPushed ? /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "span", { css: styles7.cdnBadge, children: [
3917
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles7.cdnIcon, fill: "currentColor", viewBox: "0 0 20 20", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { fillRule: "evenodd", d: "M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z", clipRule: "evenodd" }) }),
3534
3918
  "Synced"
3535
- ] }) : /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css: styles6.cdnEmpty, children: "--" }) })
3919
+ ] }) : /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css: styles7.cdnEmpty, children: "--" }) })
3536
3920
  ]
3537
3921
  }
3538
3922
  );
@@ -3570,7 +3954,7 @@ function isVideoFile(filename) {
3570
3954
  const ext = filename.toLowerCase().substring(filename.lastIndexOf("."));
3571
3955
  return VIDEO_EXTENSIONS.includes(ext);
3572
3956
  }
3573
- var styles7 = {
3957
+ var styles8 = {
3574
3958
  overlay: _react3.css`
3575
3959
  position: absolute;
3576
3960
  top: 0;
@@ -3914,7 +4298,7 @@ function StudioDetailView() {
3914
4298
  });
3915
4299
  triggerRefresh();
3916
4300
  } else {
3917
- if (_optionalChain([data, 'access', _44 => _44.error, 'optionalAccess', _45 => _45.includes, 'call', _46 => _46("R2 not configured")]) || _optionalChain([data, 'access', _47 => _47.error, 'optionalAccess', _48 => _48.includes, 'call', _49 => _49("CLOUDFLARE_R2")])) {
4301
+ if (_optionalChain([data, 'access', _50 => _50.error, 'optionalAccess', _51 => _51.includes, 'call', _52 => _52("R2 not configured")]) || _optionalChain([data, 'access', _53 => _53.error, 'optionalAccess', _54 => _54.includes, 'call', _55 => _55("CLOUDFLARE_R2")])) {
3918
4302
  setShowR2SetupModal(true);
3919
4303
  } else {
3920
4304
  setAlertMessage({
@@ -3953,7 +4337,7 @@ function StudioDetailView() {
3953
4337
  if (!response.ok) {
3954
4338
  throw new Error("Processing failed");
3955
4339
  }
3956
- const reader = _optionalChain([response, 'access', _50 => _50.body, 'optionalAccess', _51 => _51.getReader, 'call', _52 => _52()]);
4340
+ const reader = _optionalChain([response, 'access', _56 => _56.body, 'optionalAccess', _57 => _57.getReader, 'call', _58 => _58()]);
3957
4341
  if (!reader) {
3958
4342
  throw new Error("No response body");
3959
4343
  }
@@ -3989,14 +4373,14 @@ function StudioDetailView() {
3989
4373
  };
3990
4374
  const renderMedia = () => {
3991
4375
  if (isImage) {
3992
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "img", { css: styles7.image, src: imageSrc, alt: focusedItem.name });
4376
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "img", { css: styles8.image, src: imageSrc, alt: focusedItem.name });
3993
4377
  }
3994
4378
  if (isVideo) {
3995
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "video", { css: styles7.video, src: imageSrc, controls: true });
4379
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "video", { css: styles8.video, src: imageSrc, controls: true });
3996
4380
  }
3997
- return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles7.filePlaceholder, children: [
3998
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles7.fileIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 1.5, d: "M7 21h10a2 2 0 002-2V9.414a1 1 0 00-.293-.707l-5.414-5.414A1 1 0 0012.586 3H7a2 2 0 00-2 2v14a2 2 0 002 2z" }) }),
3999
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { css: styles7.fileName, children: focusedItem.name })
4381
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles8.filePlaceholder, children: [
4382
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles8.fileIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 1.5, d: "M7 21h10a2 2 0 002-2V9.414a1 1 0 00-.293-.707l-5.414-5.414A1 1 0 0012.586 3H7a2 2 0 00-2 2v14a2 2 0 002 2z" }) }),
4383
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { css: styles8.fileName, children: focusedItem.name })
4000
4384
  ] });
4001
4385
  };
4002
4386
  return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _jsxruntime.Fragment, { children: [
@@ -4056,61 +4440,61 @@ function StudioDetailView() {
4056
4440
  onClose: () => setProcessProgress(null)
4057
4441
  }
4058
4442
  ),
4059
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles7.overlay, onClick: handleClose, children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles7.container, onClick: (e) => e.stopPropagation(), children: [
4060
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles7.main, children: [
4061
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles7.headerButtons, children: [
4062
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "button", { css: styles7.copyBtn, onClick: handleCopyPath, title: "Copy file path", children: [
4063
- showCopied && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css: styles7.tooltip, children: "Copied!" }),
4064
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles7.copyIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2" }) })
4443
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles8.overlay, onClick: handleClose, children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles8.container, onClick: (e) => e.stopPropagation(), children: [
4444
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles8.main, children: [
4445
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles8.headerButtons, children: [
4446
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "button", { css: styles8.copyBtn, onClick: handleCopyPath, title: "Copy file path", children: [
4447
+ showCopied && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css: styles8.tooltip, children: "Copied!" }),
4448
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles8.copyIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2" }) })
4065
4449
  ] }),
4066
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "button", { css: styles7.mainCloseBtn, onClick: handleClose, "aria-label": "Close", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles7.mainCloseIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M6 18L18 6M6 6l12 12" }) }) })
4450
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "button", { css: styles8.mainCloseBtn, onClick: handleClose, "aria-label": "Close", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles8.mainCloseIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M6 18L18 6M6 6l12 12" }) }) })
4067
4451
  ] }),
4068
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles7.mediaWrapper, children: renderMedia() })
4452
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles8.mediaWrapper, children: renderMedia() })
4069
4453
  ] }),
4070
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles7.sidebar, children: [
4071
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles7.sidebarHeader, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h3", { css: styles7.sidebarTitle, children: "Details" }) }),
4072
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles7.sidebarContent, children: [
4073
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles7.info, children: [
4074
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles7.infoRow, children: [
4075
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css: styles7.infoLabel, children: "Name" }),
4076
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css: styles7.infoValueWrap, children: focusedItem.name })
4454
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles8.sidebar, children: [
4455
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles8.sidebarHeader, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h3", { css: styles8.sidebarTitle, children: "Details" }) }),
4456
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles8.sidebarContent, children: [
4457
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles8.info, children: [
4458
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles8.infoRow, children: [
4459
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css: styles8.infoLabel, children: "Name" }),
4460
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css: styles8.infoValueWrap, children: focusedItem.name })
4077
4461
  ] }),
4078
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles7.infoRow, children: [
4079
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css: styles7.infoLabel, children: "Path" }),
4080
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css: styles7.infoValueWrap, children: focusedItem.path.replace(/^public\//, "") })
4462
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles8.infoRow, children: [
4463
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css: styles8.infoLabel, children: "Path" }),
4464
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css: styles8.infoValueWrap, children: focusedItem.path.replace(/^public\//, "") })
4081
4465
  ] }),
4082
- focusedItem.size !== void 0 && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles7.infoRow, children: [
4083
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css: styles7.infoLabel, children: "Size" }),
4084
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css: styles7.infoValue, children: formatFileSize3(focusedItem.size) })
4466
+ focusedItem.size !== void 0 && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles8.infoRow, children: [
4467
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css: styles8.infoLabel, children: "Size" }),
4468
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css: styles8.infoValue, children: formatFileSize3(focusedItem.size) })
4085
4469
  ] }),
4086
- focusedItem.dimensions && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles7.infoRow, children: [
4087
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css: styles7.infoLabel, children: "Dimensions" }),
4088
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "span", { css: styles7.infoValue, children: [
4470
+ focusedItem.dimensions && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles8.infoRow, children: [
4471
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css: styles8.infoLabel, children: "Dimensions" }),
4472
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "span", { css: styles8.infoValue, children: [
4089
4473
  focusedItem.dimensions.width,
4090
4474
  " \xD7 ",
4091
4475
  focusedItem.dimensions.height
4092
4476
  ] })
4093
4477
  ] }),
4094
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles7.infoRow, children: [
4095
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css: styles7.infoLabel, children: "CDN Status" }),
4096
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css: styles7.infoValue, children: focusedItem.cdnPushed ? "Pushed" : "Not pushed" })
4478
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles8.infoRow, children: [
4479
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css: styles8.infoLabel, children: "CDN Status" }),
4480
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css: styles8.infoValue, children: focusedItem.cdnPushed ? "Pushed" : "Not pushed" })
4097
4481
  ] })
4098
4482
  ] }),
4099
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles7.actions, children: [
4100
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "button", { css: styles7.actionBtn, onClick: () => setShowRenameModal(true), children: [
4101
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles7.actionIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.414-9.414a2 2 0 112.828 2.828L11.828 15H9v-2.828l8.586-8.586z" }) }),
4483
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles8.actions, children: [
4484
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "button", { css: styles8.actionBtn, onClick: () => setShowRenameModal(true), children: [
4485
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles8.actionIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.414-9.414a2 2 0 112.828 2.828L11.828 15H9v-2.828l8.586-8.586z" }) }),
4102
4486
  "Rename"
4103
4487
  ] }),
4104
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "button", { css: styles7.actionBtn, onClick: handleSync, disabled: pushing, children: [
4105
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles7.actionIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M7 16a4 4 0 01-.88-7.903A5 5 0 1115.9 6L16 6a5 5 0 011 9.9M15 13l-3-3m0 0l-3 3m3-3v12" }) }),
4488
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "button", { css: styles8.actionBtn, onClick: handleSync, disabled: pushing, children: [
4489
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles8.actionIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M7 16a4 4 0 01-.88-7.903A5 5 0 1115.9 6L16 6a5 5 0 011 9.9M15 13l-3-3m0 0l-3 3m3-3v12" }) }),
4106
4490
  syncing ? "Pushing..." : "Push to CDN"
4107
4491
  ] }),
4108
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "button", { css: styles7.actionBtn, onClick: () => setShowProcessConfirm(true), children: [
4109
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles7.actionIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z" }) }),
4492
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "button", { css: styles8.actionBtn, onClick: () => setShowProcessConfirm(true), children: [
4493
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles8.actionIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z" }) }),
4110
4494
  "Process Image"
4111
4495
  ] }),
4112
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "button", { css: [styles7.actionBtn, styles7.actionBtnDanger], onClick: () => setShowDeleteConfirm(true), children: [
4113
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles7.actionIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16" }) }),
4496
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "button", { css: [styles8.actionBtn, styles8.actionBtnDanger], onClick: () => setShowDeleteConfirm(true), children: [
4497
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles8.actionIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16" }) }),
4114
4498
  "Delete"
4115
4499
  ] })
4116
4500
  ] })
@@ -4130,7 +4514,7 @@ function formatFileSize3(bytes) {
4130
4514
 
4131
4515
 
4132
4516
  var btnHeight2 = "36px";
4133
- var styles8 = {
4517
+ var styles9 = {
4134
4518
  btn: _react3.css`
4135
4519
  height: ${btnHeight2};
4136
4520
  padding: 0 12px;
@@ -4363,15 +4747,94 @@ var styles8 = {
4363
4747
  background-color: ${_chunkUFCWGUAGjs.colors.primaryHover};
4364
4748
  border-color: ${_chunkUFCWGUAGjs.colors.primaryHover};
4365
4749
  }
4750
+
4751
+ &:disabled {
4752
+ opacity: 0.6;
4753
+ cursor: not-allowed;
4754
+ }
4755
+ `,
4756
+ cdnList: _react3.css`
4757
+ display: flex;
4758
+ flex-direction: column;
4759
+ gap: 8px;
4760
+ `,
4761
+ cdnRow: _react3.css`
4762
+ display: flex;
4763
+ gap: 8px;
4764
+ align-items: center;
4765
+ `,
4766
+ cdnInput: _react3.css`
4767
+ flex: 1;
4768
+ padding: 8px 12px;
4769
+ border: 1px solid ${_chunkUFCWGUAGjs.colors.border};
4770
+ border-radius: 6px;
4771
+ font-size: ${_chunkUFCWGUAGjs.fontSize.sm};
4772
+ color: ${_chunkUFCWGUAGjs.colors.text};
4773
+ background: ${_chunkUFCWGUAGjs.colors.surface};
4774
+ transition: all 0.15s ease;
4775
+
4776
+ &:focus {
4777
+ outline: none;
4778
+ border-color: ${_chunkUFCWGUAGjs.colors.primary};
4779
+ box-shadow: 0 0 0 3px ${_chunkUFCWGUAGjs.colors.primaryLight};
4780
+ }
4781
+ `,
4782
+ cdnIndex: _react3.css`
4783
+ font-size: ${_chunkUFCWGUAGjs.fontSize.xs};
4784
+ color: ${_chunkUFCWGUAGjs.colors.textMuted};
4785
+ width: 24px;
4786
+ text-align: center;
4787
+ flex-shrink: 0;
4788
+ `,
4789
+ cdnDeleteBtn: _react3.css`
4790
+ padding: 6px;
4791
+ background: none;
4792
+ border: none;
4793
+ cursor: pointer;
4794
+ color: ${_chunkUFCWGUAGjs.colors.textMuted};
4795
+ transition: color 0.15s;
4796
+ flex-shrink: 0;
4797
+
4798
+ &:hover {
4799
+ color: ${_chunkUFCWGUAGjs.colors.danger};
4800
+ }
4801
+ `,
4802
+ cdnAddBtn: _react3.css`
4803
+ padding: 8px 12px;
4804
+ font-size: ${_chunkUFCWGUAGjs.fontSize.sm};
4805
+ font-weight: 500;
4806
+ color: ${_chunkUFCWGUAGjs.colors.primary};
4807
+ background: ${_chunkUFCWGUAGjs.colors.primaryLight};
4808
+ border: 1px dashed ${_chunkUFCWGUAGjs.colors.primary};
4809
+ border-radius: 6px;
4810
+ cursor: pointer;
4811
+ transition: all 0.15s ease;
4812
+ display: flex;
4813
+ align-items: center;
4814
+ justify-content: center;
4815
+ gap: 6px;
4816
+ margin-top: 8px;
4817
+
4818
+ &:hover {
4819
+ background: ${_chunkUFCWGUAGjs.colors.surface};
4820
+ }
4821
+ `,
4822
+ warning: _react3.css`
4823
+ font-size: ${_chunkUFCWGUAGjs.fontSize.xs};
4824
+ color: ${_chunkUFCWGUAGjs.colors.danger};
4825
+ margin-top: 8px;
4826
+ padding: 8px 12px;
4827
+ background: ${_chunkUFCWGUAGjs.colors.dangerLight};
4828
+ border-radius: 6px;
4366
4829
  `
4367
4830
  };
4368
4831
  function StudioSettings() {
4369
4832
  const [isOpen, setIsOpen] = _react.useState.call(void 0, false);
4370
4833
  return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _jsxruntime.Fragment, { children: [
4371
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "button", { css: styles8.btn, onClick: () => setIsOpen(true), "aria-label": "Settings", children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
4834
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "button", { css: styles9.btn, onClick: () => setIsOpen(true), "aria-label": "Settings", children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
4372
4835
  "svg",
4373
4836
  {
4374
- css: styles8.icon,
4837
+ css: styles9.icon,
4375
4838
  xmlns: "http://www.w3.org/2000/svg",
4376
4839
  viewBox: "0 0 24 24",
4377
4840
  fill: "none",
@@ -4394,56 +4857,143 @@ CLOUDFLARE_R2_SECRET_ACCESS_KEY=your_secret_access_key_here
4394
4857
  CLOUDFLARE_R2_BUCKET_NAME=my-images-bucket
4395
4858
  CLOUDFLARE_R2_PUBLIC_URL=https://cdn.yourdomain.com`;
4396
4859
  function SettingsPanel({ onClose }) {
4860
+ const { triggerRefresh } = useStudio();
4397
4861
  const [copied, setCopied] = _react.useState.call(void 0, false);
4862
+ const [cdnUrls, setCdnUrls] = _react.useState.call(void 0, []);
4863
+ const [loading, setLoading] = _react.useState.call(void 0, true);
4864
+ const [saving, setSaving] = _react.useState.call(void 0, false);
4865
+ const [hasChanges, setHasChanges] = _react.useState.call(void 0, false);
4866
+ _react.useEffect.call(void 0, () => {
4867
+ async function loadCdns() {
4868
+ try {
4869
+ const response = await fetch("/api/studio/cdns");
4870
+ const data = await response.json();
4871
+ setCdnUrls(data.cdns || []);
4872
+ } catch (error) {
4873
+ console.error("Failed to load CDN URLs:", error);
4874
+ } finally {
4875
+ setLoading(false);
4876
+ }
4877
+ }
4878
+ loadCdns();
4879
+ }, []);
4398
4880
  const handleCopy = () => {
4399
4881
  navigator.clipboard.writeText(envTemplate);
4400
4882
  setCopied(true);
4401
4883
  setTimeout(() => setCopied(false), 2e3);
4402
4884
  };
4403
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles8.overlay, onClick: onClose, children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles8.panel, onClick: (e) => e.stopPropagation(), children: [
4404
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles8.header, children: [
4405
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h2", { css: styles8.title, children: "Settings" }),
4406
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "button", { css: styles8.closeBtn, onClick: onClose, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles8.icon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M6 18L18 6M6 6l12 12" }) }) })
4885
+ const handleCdnChange = _react.useCallback.call(void 0, (index, value) => {
4886
+ setCdnUrls((prev) => {
4887
+ const updated = [...prev];
4888
+ updated[index] = value;
4889
+ return updated;
4890
+ });
4891
+ setHasChanges(true);
4892
+ }, []);
4893
+ const handleAddCdn = _react.useCallback.call(void 0, () => {
4894
+ setCdnUrls((prev) => [...prev, ""]);
4895
+ setHasChanges(true);
4896
+ }, []);
4897
+ const handleDeleteCdn = _react.useCallback.call(void 0, (index) => {
4898
+ setCdnUrls((prev) => prev.filter((_, i) => i !== index));
4899
+ setHasChanges(true);
4900
+ }, []);
4901
+ const handleSave = _react.useCallback.call(void 0, async () => {
4902
+ setSaving(true);
4903
+ try {
4904
+ const response = await fetch("/api/studio/cdns", {
4905
+ method: "POST",
4906
+ headers: { "Content-Type": "application/json" },
4907
+ body: JSON.stringify({ cdns: cdnUrls.filter((url) => url.trim()) })
4908
+ });
4909
+ if (response.ok) {
4910
+ setHasChanges(false);
4911
+ triggerRefresh();
4912
+ onClose();
4913
+ }
4914
+ } catch (error) {
4915
+ console.error("Failed to save CDN URLs:", error);
4916
+ } finally {
4917
+ setSaving(false);
4918
+ }
4919
+ }, [cdnUrls, triggerRefresh, onClose]);
4920
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles9.overlay, onClick: onClose, children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles9.panel, onClick: (e) => e.stopPropagation(), children: [
4921
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles9.header, children: [
4922
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h2", { css: styles9.title, children: "Settings" }),
4923
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "button", { css: styles9.closeBtn, onClick: onClose, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles9.icon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M6 18L18 6M6 6l12 12" }) }) })
4407
4924
  ] }),
4408
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles8.sections, children: [
4925
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles9.sections, children: [
4409
4926
  /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "section", { children: [
4410
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h3", { css: styles8.sectionTitle, children: "Cloudflare R2" }),
4411
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { css: styles8.description, children: "Configure in .env.local file:" }),
4412
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles8.codeWrapper, children: [
4413
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "button", { css: styles8.copyBtn, onClick: handleCopy, title: "Copy to clipboard", children: [
4414
- copied && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css: styles8.tooltip, children: "Copied!" }),
4415
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles8.copyIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2" }) })
4927
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h3", { css: styles9.sectionTitle, children: "CDN URLs" }),
4928
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { css: styles9.description, children: "Manage CDN base URLs used by your images:" }),
4929
+ loading ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { css: styles9.description, children: "Loading..." }) : /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _jsxruntime.Fragment, { children: [
4930
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles9.cdnList, children: cdnUrls.map((url, index) => /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles9.cdnRow, children: [
4931
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css: styles9.cdnIndex, children: index }),
4932
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
4933
+ "input",
4934
+ {
4935
+ css: styles9.cdnInput,
4936
+ type: "text",
4937
+ value: url,
4938
+ onChange: (e) => handleCdnChange(index, e.target.value),
4939
+ placeholder: "https://cdn.example.com"
4940
+ }
4941
+ ),
4942
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
4943
+ "button",
4944
+ {
4945
+ css: styles9.cdnDeleteBtn,
4946
+ onClick: () => handleDeleteCdn(index),
4947
+ title: "Delete CDN URL",
4948
+ children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { width: "16", height: "16", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16" }) })
4949
+ }
4950
+ )
4951
+ ] }, index)) }),
4952
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "button", { css: styles9.cdnAddBtn, onClick: handleAddCdn, children: [
4953
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { width: "14", height: "14", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M12 4v16m8-8H4" }) }),
4954
+ "Add CDN URL"
4955
+ ] }),
4956
+ cdnUrls.length > 0 && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { css: styles9.warning, children: "Warning: Changing CDN URLs may break image references. The index numbers correspond to image `c` values." })
4957
+ ] })
4958
+ ] }),
4959
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "section", { children: [
4960
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h3", { css: styles9.sectionTitle, children: "Cloudflare R2 Credentials" }),
4961
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { css: styles9.description, children: "Configure in .env.local file:" }),
4962
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles9.codeWrapper, children: [
4963
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "button", { css: styles9.copyBtn, onClick: handleCopy, title: "Copy to clipboard", children: [
4964
+ copied && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css: styles9.tooltip, children: "Copied!" }),
4965
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles9.copyIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2" }) })
4416
4966
  ] }),
4417
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles8.code, children: [
4418
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { css: styles8.codeLine, children: "CLOUDFLARE_R2_ACCOUNT_ID=abc123def456ghi789" }),
4419
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { css: styles8.codeLine, children: "CLOUDFLARE_R2_ACCESS_KEY_ID=your_access_key_id_here" }),
4420
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { css: styles8.codeLine, children: "CLOUDFLARE_R2_SECRET_ACCESS_KEY=your_secret_access_key_here" }),
4421
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { css: styles8.codeLine, children: "CLOUDFLARE_R2_BUCKET_NAME=my-images-bucket" }),
4422
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { css: styles8.codeLine, children: "CLOUDFLARE_R2_PUBLIC_URL=https://cdn.yourdomain.com" })
4967
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles9.code, children: [
4968
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { css: styles9.codeLine, children: "CLOUDFLARE_R2_ACCOUNT_ID=abc123def456ghi789" }),
4969
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { css: styles9.codeLine, children: "CLOUDFLARE_R2_ACCESS_KEY_ID=your_access_key_id_here" }),
4970
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { css: styles9.codeLine, children: "CLOUDFLARE_R2_SECRET_ACCESS_KEY=your_secret_access_key_here" }),
4971
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { css: styles9.codeLine, children: "CLOUDFLARE_R2_BUCKET_NAME=my-images-bucket" }),
4972
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { css: styles9.codeLine, children: "CLOUDFLARE_R2_PUBLIC_URL=https://cdn.yourdomain.com" })
4423
4973
  ] })
4424
4974
  ] })
4425
4975
  ] }),
4426
4976
  /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "section", { children: [
4427
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h3", { css: styles8.sectionTitle, children: "Thumbnail Sizes" }),
4428
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles8.grid, children: [
4977
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h3", { css: styles9.sectionTitle, children: "Thumbnail Sizes" }),
4978
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles9.grid, children: [
4429
4979
  /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { children: [
4430
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "label", { css: styles8.label, children: "Small" }),
4431
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "input", { css: styles8.input, type: "number", defaultValue: 300 })
4980
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "label", { css: styles9.label, children: "Small" }),
4981
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "input", { css: styles9.input, type: "number", defaultValue: 300 })
4432
4982
  ] }),
4433
4983
  /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { children: [
4434
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "label", { css: styles8.label, children: "Medium" }),
4435
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "input", { css: styles8.input, type: "number", defaultValue: 700 })
4984
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "label", { css: styles9.label, children: "Medium" }),
4985
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "input", { css: styles9.input, type: "number", defaultValue: 700 })
4436
4986
  ] }),
4437
4987
  /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { children: [
4438
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "label", { css: styles8.label, children: "Large" }),
4439
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "input", { css: styles8.input, type: "number", defaultValue: 1400 })
4988
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "label", { css: styles9.label, children: "Large" }),
4989
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "input", { css: styles9.input, type: "number", defaultValue: 1400 })
4440
4990
  ] })
4441
4991
  ] })
4442
4992
  ] })
4443
4993
  ] }),
4444
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles8.footer, children: [
4445
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "button", { css: styles8.cancelBtn, onClick: onClose, children: "Cancel" }),
4446
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "button", { css: styles8.saveBtn, children: "Save Changes" })
4994
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles9.footer, children: [
4995
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "button", { css: styles9.cancelBtn, onClick: onClose, children: "Cancel" }),
4996
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "button", { css: styles9.saveBtn, onClick: handleSave, disabled: saving || !hasChanges, children: saving ? "Saving..." : "Save Changes" })
4447
4997
  ] })
4448
4998
  ] }) });
4449
4999
  }
@@ -4451,7 +5001,7 @@ function SettingsPanel({ onClose }) {
4451
5001
  // src/components/ErrorModal.tsx
4452
5002
 
4453
5003
 
4454
- var styles9 = {
5004
+ var styles10 = {
4455
5005
  overlay: _react3.css`
4456
5006
  position: fixed;
4457
5007
  inset: 0;
@@ -4513,20 +5063,20 @@ var styles9 = {
4513
5063
  function ErrorModal() {
4514
5064
  const { error, clearError } = useStudio();
4515
5065
  if (!error) return null;
4516
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles9.overlay, onClick: clearError, children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles9.modal, onClick: (e) => e.stopPropagation(), children: [
4517
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles9.header, children: [
4518
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles9.icon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z" }) }),
4519
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h3", { css: styles9.title, children: error.title })
5066
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles10.overlay, onClick: clearError, children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles10.modal, onClick: (e) => e.stopPropagation(), children: [
5067
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles10.header, children: [
5068
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles10.icon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z" }) }),
5069
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h3", { css: styles10.title, children: error.title })
4520
5070
  ] }),
4521
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { css: styles9.message, children: error.message }),
4522
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "button", { css: styles9.button, onClick: clearError, children: "OK" })
5071
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { css: styles10.message, children: error.message }),
5072
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "button", { css: styles10.button, onClick: clearError, children: "OK" })
4523
5073
  ] }) });
4524
5074
  }
4525
5075
 
4526
5076
  // src/components/StudioUI.tsx
4527
5077
 
4528
5078
  var btnHeight3 = "36px";
4529
- var styles10 = {
5079
+ var styles11 = {
4530
5080
  container: _react3.css`
4531
5081
  ${_chunkUFCWGUAGjs.baseReset}
4532
5082
  display: flex;
@@ -4832,16 +5382,16 @@ function StudioUI({ onClose, isVisible = true }) {
4832
5382
  showError,
4833
5383
  clearError
4834
5384
  };
4835
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, StudioContext.Provider, { value: contextValue, children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles10.container, children: [
4836
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles10.header, children: [
4837
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles10.headerLeft, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h1", { css: styles10.title, children: "Studio" }) }),
4838
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles10.headerCenter, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, Breadcrumbs, { currentPath, onNavigate: setCurrentPath }) }),
4839
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles10.headerActions, children: [
5385
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, StudioContext.Provider, { value: contextValue, children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles11.container, children: [
5386
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles11.header, children: [
5387
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles11.headerLeft, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h1", { css: styles11.title, children: "Studio" }) }),
5388
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles11.headerCenter, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, Breadcrumbs, { currentPath, onNavigate: setCurrentPath }) }),
5389
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles11.headerActions, children: [
4840
5390
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, StudioSettings, {}),
4841
5391
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
4842
5392
  "button",
4843
5393
  {
4844
- css: styles10.headerBtn,
5394
+ css: styles11.headerBtn,
4845
5395
  onClick: onClose,
4846
5396
  "aria-label": "Close Studio",
4847
5397
  children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, CloseIcon, {})
@@ -4853,16 +5403,16 @@ function StudioUI({ onClose, isVisible = true }) {
4853
5403
  /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
4854
5404
  "div",
4855
5405
  {
4856
- css: styles10.content,
5406
+ css: styles11.content,
4857
5407
  onDragOver: handleDragOver,
4858
5408
  onDragLeave: handleDragLeave,
4859
5409
  onDrop: handleDrop,
4860
5410
  children: [
4861
- isDragging && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles10.dropOverlay, children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles10.dropMessage, children: [
4862
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles10.dropIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-8l-4-4m0 0L8 8m4-4v12" }) }),
5411
+ isDragging && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles11.dropOverlay, children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles11.dropMessage, children: [
5412
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles11.dropIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-8l-4-4m0 0L8 8m4-4v12" }) }),
4863
5413
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { children: "Drop files to upload" })
4864
5414
  ] }) }),
4865
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles10.fileBrowser, children: viewMode === "grid" ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, StudioFileGrid, {}) : /* @__PURE__ */ _jsxruntime.jsx.call(void 0, StudioFileList, {}) })
5415
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles11.fileBrowser, children: viewMode === "grid" ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, StudioFileGrid, {}) : /* @__PURE__ */ _jsxruntime.jsx.call(void 0, StudioFileList, {}) })
4866
5416
  ]
4867
5417
  }
4868
5418
  ),
@@ -4876,12 +5426,12 @@ function Breadcrumbs({ currentPath, onNavigate }) {
4876
5426
  name: part,
4877
5427
  path: parts.slice(0, index + 1).join("/")
4878
5428
  }));
4879
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles10.breadcrumbs, children: breadcrumbs.map((crumb, index) => /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "span", { style: { display: "flex", alignItems: "center", gap: 6 }, children: [
4880
- index > 0 && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css: styles10.breadcrumbSeparator, children: "/" }),
4881
- index === breadcrumbs.length - 1 ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css: styles10.breadcrumbCurrent, children: crumb.name }) : /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
5429
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles11.breadcrumbs, children: breadcrumbs.map((crumb, index) => /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "span", { style: { display: "flex", alignItems: "center", gap: 6 }, children: [
5430
+ index > 0 && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css: styles11.breadcrumbSeparator, children: "/" }),
5431
+ index === breadcrumbs.length - 1 ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css: styles11.breadcrumbCurrent, children: crumb.name }) : /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
4882
5432
  "span",
4883
5433
  {
4884
- css: styles10.breadcrumbItem,
5434
+ css: styles11.breadcrumbItem,
4885
5435
  onClick: () => onNavigate(crumb.path),
4886
5436
  children: crumb.name
4887
5437
  }
@@ -4892,7 +5442,7 @@ function CloseIcon() {
4892
5442
  return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
4893
5443
  "svg",
4894
5444
  {
4895
- css: styles10.headerIcon,
5445
+ css: styles11.headerIcon,
4896
5446
  xmlns: "http://www.w3.org/2000/svg",
4897
5447
  viewBox: "0 0 24 24",
4898
5448
  fill: "none",
@@ -4912,4 +5462,4 @@ var StudioUI_default = StudioUI;
4912
5462
 
4913
5463
 
4914
5464
  exports.StudioUI = StudioUI; exports.default = StudioUI_default;
4915
- //# sourceMappingURL=StudioUI-77EWSAVJ.js.map
5465
+ //# sourceMappingURL=StudioUI-QBIGDYYL.js.map