@gallop.software/studio 0.1.33 → 0.1.35
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{StudioUI-ENXMD4OM.js → StudioUI-S4BI6WKX.js} +128 -24
- package/dist/StudioUI-S4BI6WKX.js.map +1 -0
- package/dist/{StudioUI-IIVOARWK.mjs → StudioUI-Y4BA3RW5.mjs} +128 -24
- package/dist/StudioUI-Y4BA3RW5.mjs.map +1 -0
- package/dist/handlers.d.mts +1 -1
- package/dist/handlers.d.ts +1 -1
- package/dist/handlers.js +38 -20
- package/dist/handlers.js.map +1 -1
- package/dist/handlers.mjs +24 -6
- package/dist/handlers.mjs.map +1 -1
- package/dist/index.d.mts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1 -1
- package/dist/index.mjs +1 -1
- package/dist/{types-lg2VkHIb.d.mts → types-1m_7EjJU.d.mts} +1 -0
- package/dist/{types-lg2VkHIb.d.ts → types-1m_7EjJU.d.ts} +1 -0
- package/package.json +1 -1
- package/dist/StudioUI-ENXMD4OM.js.map +0 -1
- package/dist/StudioUI-IIVOARWK.mjs.map +0 -1
|
@@ -1100,6 +1100,36 @@ var styles3 = {
|
|
|
1100
1100
|
object-fit: contain;
|
|
1101
1101
|
border-radius: 4px;
|
|
1102
1102
|
`,
|
|
1103
|
+
noThumbnail: css3`
|
|
1104
|
+
display: flex;
|
|
1105
|
+
flex-direction: column;
|
|
1106
|
+
align-items: center;
|
|
1107
|
+
justify-content: center;
|
|
1108
|
+
gap: 8px;
|
|
1109
|
+
padding: 16px;
|
|
1110
|
+
background: ${colors.background};
|
|
1111
|
+
border: 2px dashed ${colors.border};
|
|
1112
|
+
border-radius: 8px;
|
|
1113
|
+
cursor: pointer;
|
|
1114
|
+
transition: all 0.15s ease;
|
|
1115
|
+
width: 80%;
|
|
1116
|
+
height: 60%;
|
|
1117
|
+
|
|
1118
|
+
&:hover {
|
|
1119
|
+
border-color: ${colors.primary};
|
|
1120
|
+
background: ${colors.surfaceHover};
|
|
1121
|
+
}
|
|
1122
|
+
`,
|
|
1123
|
+
noThumbnailIcon: css3`
|
|
1124
|
+
width: 32px;
|
|
1125
|
+
height: 32px;
|
|
1126
|
+
color: ${colors.textMuted};
|
|
1127
|
+
`,
|
|
1128
|
+
noThumbnailText: css3`
|
|
1129
|
+
font-size: ${fontSize.xs};
|
|
1130
|
+
color: ${colors.textMuted};
|
|
1131
|
+
text-align: center;
|
|
1132
|
+
`,
|
|
1103
1133
|
label: css3`
|
|
1104
1134
|
padding: 10px 12px;
|
|
1105
1135
|
background-color: ${colors.surface};
|
|
@@ -1179,7 +1209,7 @@ var styles3 = {
|
|
|
1179
1209
|
`
|
|
1180
1210
|
};
|
|
1181
1211
|
function StudioFileGrid() {
|
|
1182
|
-
const { currentPath, setCurrentPath, navigateUp, selectedItems, toggleSelection, selectRange, lastSelectedPath, selectAll, clearSelection, refreshKey, setFocusedItem } = useStudio();
|
|
1212
|
+
const { currentPath, setCurrentPath, navigateUp, selectedItems, toggleSelection, selectRange, lastSelectedPath, selectAll, clearSelection, refreshKey, setFocusedItem, triggerRefresh } = useStudio();
|
|
1183
1213
|
const [items, setItems] = useState2([]);
|
|
1184
1214
|
const [loading, setLoading] = useState2(true);
|
|
1185
1215
|
const isInitialLoad = useRef2(true);
|
|
@@ -1235,6 +1265,19 @@ function StudioFileGrid() {
|
|
|
1235
1265
|
setFocusedItem(item);
|
|
1236
1266
|
}
|
|
1237
1267
|
};
|
|
1268
|
+
const handleGenerateThumbnail = async (item) => {
|
|
1269
|
+
try {
|
|
1270
|
+
const imageKey = item.path.replace(/^public\//, "");
|
|
1271
|
+
await fetch("/api/studio/reprocess", {
|
|
1272
|
+
method: "POST",
|
|
1273
|
+
headers: { "Content-Type": "application/json" },
|
|
1274
|
+
body: JSON.stringify({ imageKeys: [imageKey] })
|
|
1275
|
+
});
|
|
1276
|
+
triggerRefresh();
|
|
1277
|
+
} catch (error) {
|
|
1278
|
+
console.error("Failed to generate thumbnail:", error);
|
|
1279
|
+
}
|
|
1280
|
+
};
|
|
1238
1281
|
const allItemsSelected = sortedItems.length > 0 && sortedItems.every((item) => selectedItems.has(item.path));
|
|
1239
1282
|
const someItemsSelected = sortedItems.some((item) => selectedItems.has(item.path));
|
|
1240
1283
|
const handleSelectAll = () => {
|
|
@@ -1271,7 +1314,7 @@ function StudioFileGrid() {
|
|
|
1271
1314
|
children: [
|
|
1272
1315
|
/* @__PURE__ */ jsx3("div", { css: styles3.content, children: /* @__PURE__ */ jsx3("svg", { css: styles3.parentIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx3("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 1.5, d: "M3 10h10a8 8 0 018 8v2M3 10l6 6m-6-6l6-6" }) }) }),
|
|
1273
1316
|
/* @__PURE__ */ jsxs3("div", { css: styles3.label, children: [
|
|
1274
|
-
/* @__PURE__ */ jsx3("p", { css: styles3.name, children:
|
|
1317
|
+
/* @__PURE__ */ jsx3("p", { css: styles3.name, children: ".." }),
|
|
1275
1318
|
/* @__PURE__ */ jsx3("p", { css: styles3.size, children: "Parent folder" })
|
|
1276
1319
|
] })
|
|
1277
1320
|
]
|
|
@@ -1283,15 +1326,17 @@ function StudioFileGrid() {
|
|
|
1283
1326
|
item,
|
|
1284
1327
|
isSelected: selectedItems.has(item.path),
|
|
1285
1328
|
onClick: (e) => handleItemClick(item, e),
|
|
1286
|
-
onOpen: () => handleOpen(item)
|
|
1329
|
+
onOpen: () => handleOpen(item),
|
|
1330
|
+
onGenerateThumbnail: () => handleGenerateThumbnail(item)
|
|
1287
1331
|
},
|
|
1288
1332
|
item.path
|
|
1289
1333
|
))
|
|
1290
1334
|
] })
|
|
1291
1335
|
] });
|
|
1292
1336
|
}
|
|
1293
|
-
function GridItem({ item, isSelected, onClick, onOpen }) {
|
|
1337
|
+
function GridItem({ item, isSelected, onClick, onOpen, onGenerateThumbnail }) {
|
|
1294
1338
|
const isFolder = item.type === "folder";
|
|
1339
|
+
const isImage = !isFolder && item.thumbnail !== void 0;
|
|
1295
1340
|
return /* @__PURE__ */ jsxs3(
|
|
1296
1341
|
"div",
|
|
1297
1342
|
{
|
|
@@ -1315,7 +1360,7 @@ function GridItem({ item, isSelected, onClick, onOpen }) {
|
|
|
1315
1360
|
}
|
|
1316
1361
|
),
|
|
1317
1362
|
item.cdnSynced && /* @__PURE__ */ jsx3("span", { css: styles3.cdnBadge, children: "CDN" }),
|
|
1318
|
-
/* @__PURE__ */ jsx3("div", { css: styles3.content, children: isFolder ? /* @__PURE__ */ jsx3("svg", { css: styles3.folderIcon, fill: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx3("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" }) }) : item.
|
|
1363
|
+
/* @__PURE__ */ jsx3("div", { css: styles3.content, children: isFolder ? /* @__PURE__ */ jsx3("svg", { css: styles3.folderIcon, fill: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx3("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__ */ jsx3(
|
|
1319
1364
|
"img",
|
|
1320
1365
|
{
|
|
1321
1366
|
css: styles3.image,
|
|
@@ -1323,6 +1368,20 @@ function GridItem({ item, isSelected, onClick, onOpen }) {
|
|
|
1323
1368
|
alt: item.name,
|
|
1324
1369
|
loading: "lazy"
|
|
1325
1370
|
}
|
|
1371
|
+
) : isImage && !item.hasThumbnail ? /* @__PURE__ */ jsxs3(
|
|
1372
|
+
"button",
|
|
1373
|
+
{
|
|
1374
|
+
css: styles3.noThumbnail,
|
|
1375
|
+
onClick: (e) => {
|
|
1376
|
+
e.stopPropagation();
|
|
1377
|
+
onGenerateThumbnail();
|
|
1378
|
+
},
|
|
1379
|
+
title: "Generate thumbnail",
|
|
1380
|
+
children: [
|
|
1381
|
+
/* @__PURE__ */ jsx3("svg", { css: styles3.noThumbnailIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx3("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" }) }),
|
|
1382
|
+
/* @__PURE__ */ jsx3("span", { css: styles3.noThumbnailText, children: "Generate" })
|
|
1383
|
+
]
|
|
1384
|
+
}
|
|
1326
1385
|
) : /* @__PURE__ */ jsx3("svg", { css: styles3.fileIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx3("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" }) }) }),
|
|
1327
1386
|
/* @__PURE__ */ jsx3("div", { css: styles3.label, children: /* @__PURE__ */ jsxs3("div", { css: styles3.labelRow, children: [
|
|
1328
1387
|
/* @__PURE__ */ jsxs3("div", { css: styles3.labelText, children: [
|
|
@@ -1354,11 +1413,6 @@ function formatFileSize(bytes) {
|
|
|
1354
1413
|
if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;
|
|
1355
1414
|
return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
|
|
1356
1415
|
}
|
|
1357
|
-
function getParentPath(path) {
|
|
1358
|
-
const parts = path.split("/");
|
|
1359
|
-
parts.pop();
|
|
1360
|
-
return parts.join("/") + "/";
|
|
1361
|
-
}
|
|
1362
1416
|
function truncateMiddle(str, maxLength = 24) {
|
|
1363
1417
|
if (str.length <= maxLength) return str;
|
|
1364
1418
|
const lastDot = str.lastIndexOf(".");
|
|
@@ -1501,12 +1555,37 @@ var styles4 = {
|
|
|
1501
1555
|
flex-shrink: 0;
|
|
1502
1556
|
`,
|
|
1503
1557
|
thumbnail: css4`
|
|
1558
|
+
max-width: 48px;
|
|
1559
|
+
max-height: 36px;
|
|
1560
|
+
width: auto;
|
|
1561
|
+
height: auto;
|
|
1562
|
+
object-fit: contain;
|
|
1563
|
+
border-radius: 4px;
|
|
1564
|
+
flex-shrink: 0;
|
|
1565
|
+
border: 1px solid ${colors.borderLight};
|
|
1566
|
+
`,
|
|
1567
|
+
noThumbnail: css4`
|
|
1504
1568
|
width: 36px;
|
|
1505
1569
|
height: 36px;
|
|
1506
|
-
|
|
1507
|
-
|
|
1570
|
+
display: flex;
|
|
1571
|
+
align-items: center;
|
|
1572
|
+
justify-content: center;
|
|
1573
|
+
background: ${colors.background};
|
|
1574
|
+
border: 1px dashed ${colors.border};
|
|
1575
|
+
border-radius: 4px;
|
|
1508
1576
|
flex-shrink: 0;
|
|
1509
|
-
|
|
1577
|
+
cursor: pointer;
|
|
1578
|
+
transition: all 0.15s ease;
|
|
1579
|
+
|
|
1580
|
+
&:hover {
|
|
1581
|
+
border-color: ${colors.primary};
|
|
1582
|
+
background: ${colors.surfaceHover};
|
|
1583
|
+
}
|
|
1584
|
+
`,
|
|
1585
|
+
noThumbnailIcon: css4`
|
|
1586
|
+
width: 16px;
|
|
1587
|
+
height: 16px;
|
|
1588
|
+
color: ${colors.textMuted};
|
|
1510
1589
|
`,
|
|
1511
1590
|
name: css4`
|
|
1512
1591
|
font-size: ${fontSize.base};
|
|
@@ -1556,7 +1635,7 @@ var styles4 = {
|
|
|
1556
1635
|
`
|
|
1557
1636
|
};
|
|
1558
1637
|
function StudioFileList() {
|
|
1559
|
-
const { currentPath, setCurrentPath, navigateUp, selectedItems, toggleSelection, selectRange, lastSelectedPath, selectAll, clearSelection, refreshKey, setFocusedItem } = useStudio();
|
|
1638
|
+
const { currentPath, setCurrentPath, navigateUp, selectedItems, toggleSelection, selectRange, lastSelectedPath, selectAll, clearSelection, refreshKey, setFocusedItem, triggerRefresh } = useStudio();
|
|
1560
1639
|
const [items, setItems] = useState3([]);
|
|
1561
1640
|
const [loading, setLoading] = useState3(true);
|
|
1562
1641
|
const isInitialLoad = useRef3(true);
|
|
@@ -1608,6 +1687,19 @@ function StudioFileList() {
|
|
|
1608
1687
|
setFocusedItem(item);
|
|
1609
1688
|
}
|
|
1610
1689
|
};
|
|
1690
|
+
const handleGenerateThumbnail = async (item) => {
|
|
1691
|
+
try {
|
|
1692
|
+
const imageKey = item.path.replace(/^public\//, "");
|
|
1693
|
+
await fetch("/api/studio/reprocess", {
|
|
1694
|
+
method: "POST",
|
|
1695
|
+
headers: { "Content-Type": "application/json" },
|
|
1696
|
+
body: JSON.stringify({ imageKeys: [imageKey] })
|
|
1697
|
+
});
|
|
1698
|
+
triggerRefresh();
|
|
1699
|
+
} catch (error) {
|
|
1700
|
+
console.error("Failed to generate thumbnail:", error);
|
|
1701
|
+
}
|
|
1702
|
+
};
|
|
1611
1703
|
const allItemsSelected = sortedItems.length > 0 && sortedItems.every((item) => selectedItems.has(item.path));
|
|
1612
1704
|
const someItemsSelected = sortedItems.some((item) => selectedItems.has(item.path));
|
|
1613
1705
|
const handleSelectAll = () => {
|
|
@@ -1641,7 +1733,7 @@ function StudioFileList() {
|
|
|
1641
1733
|
/* @__PURE__ */ jsx4("td", { css: styles4.td }),
|
|
1642
1734
|
/* @__PURE__ */ jsx4("td", { css: styles4.td, children: /* @__PURE__ */ jsxs4("div", { css: styles4.nameCell, children: [
|
|
1643
1735
|
/* @__PURE__ */ jsx4("svg", { css: styles4.parentIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx4("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 1.5, d: "M3 10h10a8 8 0 018 8v2M3 10l6 6m-6-6l6-6" }) }),
|
|
1644
|
-
/* @__PURE__ */ jsx4("span", { css: styles4.name, children:
|
|
1736
|
+
/* @__PURE__ */ jsx4("span", { css: styles4.name, children: ".." })
|
|
1645
1737
|
] }) }),
|
|
1646
1738
|
/* @__PURE__ */ jsx4("td", { css: [styles4.td, styles4.meta], children: "--" }),
|
|
1647
1739
|
/* @__PURE__ */ jsx4("td", { css: [styles4.td, styles4.meta], children: "Parent folder" }),
|
|
@@ -1653,15 +1745,17 @@ function StudioFileList() {
|
|
|
1653
1745
|
item,
|
|
1654
1746
|
isSelected: selectedItems.has(item.path),
|
|
1655
1747
|
onClick: (e) => handleItemClick(item, e),
|
|
1656
|
-
onOpen: () => handleOpen(item)
|
|
1748
|
+
onOpen: () => handleOpen(item),
|
|
1749
|
+
onGenerateThumbnail: () => handleGenerateThumbnail(item)
|
|
1657
1750
|
},
|
|
1658
1751
|
item.path
|
|
1659
1752
|
))
|
|
1660
1753
|
] })
|
|
1661
1754
|
] }) });
|
|
1662
1755
|
}
|
|
1663
|
-
function ListRow({ item, isSelected, onClick, onOpen }) {
|
|
1756
|
+
function ListRow({ item, isSelected, onClick, onOpen, onGenerateThumbnail }) {
|
|
1664
1757
|
const isFolder = item.type === "folder";
|
|
1758
|
+
const isImage = !isFolder && item.thumbnail !== void 0;
|
|
1665
1759
|
return /* @__PURE__ */ jsxs4(
|
|
1666
1760
|
"tr",
|
|
1667
1761
|
{
|
|
@@ -1685,7 +1779,18 @@ function ListRow({ item, isSelected, onClick, onOpen }) {
|
|
|
1685
1779
|
}
|
|
1686
1780
|
),
|
|
1687
1781
|
/* @__PURE__ */ jsx4("td", { css: styles4.td, children: /* @__PURE__ */ jsxs4("div", { css: styles4.nameCell, children: [
|
|
1688
|
-
isFolder ? /* @__PURE__ */ jsx4("svg", { css: styles4.folderIcon, fill: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx4("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" }) }) : item.
|
|
1782
|
+
isFolder ? /* @__PURE__ */ jsx4("svg", { css: styles4.folderIcon, fill: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx4("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__ */ jsx4("img", { css: styles4.thumbnail, src: item.thumbnail, alt: item.name, loading: "lazy" }) : isImage && !item.hasThumbnail ? /* @__PURE__ */ jsx4(
|
|
1783
|
+
"button",
|
|
1784
|
+
{
|
|
1785
|
+
css: styles4.noThumbnail,
|
|
1786
|
+
onClick: (e) => {
|
|
1787
|
+
e.stopPropagation();
|
|
1788
|
+
onGenerateThumbnail();
|
|
1789
|
+
},
|
|
1790
|
+
title: "Generate thumbnail",
|
|
1791
|
+
children: /* @__PURE__ */ jsx4("svg", { css: styles4.noThumbnailIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx4("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" }) })
|
|
1792
|
+
}
|
|
1793
|
+
) : /* @__PURE__ */ jsx4("svg", { css: styles4.fileIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx4("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" }) }),
|
|
1689
1794
|
/* @__PURE__ */ jsx4("span", { css: styles4.name, title: item.name, children: truncateMiddle2(item.name) }),
|
|
1690
1795
|
/* @__PURE__ */ jsx4(
|
|
1691
1796
|
"button",
|
|
@@ -1714,11 +1819,6 @@ function formatFileSize2(bytes) {
|
|
|
1714
1819
|
if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;
|
|
1715
1820
|
return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
|
|
1716
1821
|
}
|
|
1717
|
-
function getParentPath2(path) {
|
|
1718
|
-
const parts = path.split("/");
|
|
1719
|
-
parts.pop();
|
|
1720
|
-
return parts.join("/") + "/";
|
|
1721
|
-
}
|
|
1722
1822
|
function truncateMiddle2(str, maxLength = 32) {
|
|
1723
1823
|
if (str.length <= maxLength) return str;
|
|
1724
1824
|
const lastDot = str.lastIndexOf(".");
|
|
@@ -2021,6 +2121,10 @@ function StudioDetailView() {
|
|
|
2021
2121
|
/* @__PURE__ */ jsx5("span", { css: styles5.infoLabel, children: "Name" }),
|
|
2022
2122
|
/* @__PURE__ */ jsx5("span", { css: styles5.infoValueWrap, children: focusedItem.name })
|
|
2023
2123
|
] }),
|
|
2124
|
+
/* @__PURE__ */ jsxs5("div", { css: styles5.infoRow, children: [
|
|
2125
|
+
/* @__PURE__ */ jsx5("span", { css: styles5.infoLabel, children: "Path" }),
|
|
2126
|
+
/* @__PURE__ */ jsx5("span", { css: styles5.infoValueWrap, children: focusedItem.path.replace(/^public\//, "") })
|
|
2127
|
+
] }),
|
|
2024
2128
|
focusedItem.size !== void 0 && /* @__PURE__ */ jsxs5("div", { css: styles5.infoRow, children: [
|
|
2025
2129
|
/* @__PURE__ */ jsx5("span", { css: styles5.infoLabel, children: "Size" }),
|
|
2026
2130
|
/* @__PURE__ */ jsx5("span", { css: styles5.infoValue, children: formatFileSize3(focusedItem.size) })
|
|
@@ -2537,4 +2641,4 @@ export {
|
|
|
2537
2641
|
StudioUI,
|
|
2538
2642
|
StudioUI_default as default
|
|
2539
2643
|
};
|
|
2540
|
-
//# sourceMappingURL=StudioUI-
|
|
2644
|
+
//# sourceMappingURL=StudioUI-Y4BA3RW5.mjs.map
|