@liiift-studio/sanity-font-manager 2.4.0 → 2.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (33) hide show
  1. package/dist/UploadModal-6LIX7XOK.js +6 -0
  2. package/dist/UploadModal-NME2W53V.mjs +6 -0
  3. package/dist/chunk-646WCBRR.mjs +7276 -0
  4. package/dist/chunk-FH4QKHOH.js +7276 -0
  5. package/dist/index.js +664 -1647
  6. package/dist/index.mjs +317 -1209
  7. package/package.json +5 -5
  8. package/src/components/BatchUploadFonts.jsx +57 -44
  9. package/src/components/BulkActions.jsx +99 -0
  10. package/src/components/ExistingDocumentResolver.jsx +152 -0
  11. package/src/components/FontReviewCard.jsx +415 -0
  12. package/src/components/SingleUploaderTool.jsx +3 -4
  13. package/src/components/UploadModal.jsx +268 -0
  14. package/src/components/UploadScriptsComponent.jsx +23 -21
  15. package/src/components/UploadStep1Settings.jsx +272 -0
  16. package/src/components/UploadStep2Review.jsx +472 -0
  17. package/src/components/UploadStep3Execute.jsx +234 -0
  18. package/src/components/UploadSummary.jsx +196 -0
  19. package/src/index.js +45 -0
  20. package/src/utils/buildUploadPlan.js +325 -0
  21. package/src/utils/executeUploadPlan.js +437 -0
  22. package/src/utils/executionReducer.js +56 -0
  23. package/src/utils/fontHelpers.js +267 -0
  24. package/src/utils/generateCssFile.js +79 -77
  25. package/src/utils/generateFontData.js +47 -94
  26. package/src/utils/getEmptyFontKit.js +19 -17
  27. package/src/utils/parseFont.js +55 -0
  28. package/src/utils/planReducer.js +517 -0
  29. package/src/utils/planTypes.js +183 -0
  30. package/src/utils/processFontFiles.js +120 -78
  31. package/src/utils/regenerateFontData.js +2 -2
  32. package/src/utils/resolveExistingFont.js +87 -0
  33. package/src/utils/uploadFontFiles.js +405 -405
package/dist/index.mjs CHANGED
@@ -1,6 +1,69 @@
1
+ import {
2
+ BulkActions,
3
+ EXECUTION_STATUS,
4
+ ExistingDocumentResolver,
5
+ FONT_STATUS,
6
+ FontReviewCard_default,
7
+ PLAN_PHASE,
8
+ PLAN_VERSION,
9
+ PriceInput_default,
10
+ RECOMMENDATION,
11
+ UploadModal,
12
+ UploadStep1Settings,
13
+ UploadStep2Review,
14
+ UploadStep3Execute,
15
+ UploadSummary,
16
+ addItalicToFontTitle,
17
+ buildUploadPlan,
18
+ createEmptyPlan,
19
+ createFontDecisions,
20
+ createFontObject,
21
+ createInitialExecutionState,
22
+ determineWeight,
23
+ escapeCssFontName,
24
+ executeUploadPlan,
25
+ executionReducer,
26
+ expandAbbreviations,
27
+ extractFontMetadata,
28
+ extractWeightFromFullName,
29
+ extractWeightName,
30
+ formatFontTitle,
31
+ generateCssFile,
32
+ generateFontData,
33
+ generateStyleKeywords,
34
+ getAllFeatureTags,
35
+ getCharacterSet,
36
+ getFamilyClass,
37
+ getFontMetadata,
38
+ getFontMetrics,
39
+ getFsSelection,
40
+ getGlyphCount,
41
+ getItalicAngle,
42
+ getMacStyle,
43
+ getNameString,
44
+ getNamedInstances,
45
+ getVariationAxes,
46
+ getWeightClass,
47
+ logFontInfo,
48
+ parseFont,
49
+ parseVariableFontInstances,
50
+ parseVariableFontInstances_default,
51
+ planReducer,
52
+ processFontFiles,
53
+ processItalicKeywords,
54
+ processSubfamilyName,
55
+ readFontFile,
56
+ removeWeightNames,
57
+ resolveExistingFont,
58
+ reverseSpellingLookup,
59
+ sanitizeForSanityId,
60
+ sortFontObjects,
61
+ updateTypefaceDocument
62
+ } from "./chunk-646WCBRR.mjs";
63
+
1
64
  // src/components/BatchUploadFonts.jsx
2
- import React4, { useCallback, useState as useState2, useMemo as useMemo2, useRef, useEffect } from "react";
3
- import { Card, Box as Box2, Flex as Flex3, Grid, Text as Text4, Label, Switch, Button as Button2, Spinner, Tooltip, Stack as Stack2 } from "@sanity/ui";
65
+ import React3, { useCallback, useState as useState2, useMemo as useMemo2, useRef, useEffect, lazy, Suspense } from "react";
66
+ import { Card, Box as Box2, Flex as Flex2, Grid, Text as Text3, Label, Switch, Button as Button2, Spinner, Tooltip, Stack as Stack2 } from "@sanity/ui";
4
67
  import { ControlsIcon, InfoOutlineIcon, TrashIcon, UploadIcon, WarningOutlineIcon } from "@sanity/icons";
5
68
  import { useFormValue as useFormValue2 } from "sanity";
6
69
 
@@ -12,908 +75,8 @@ function useSanityClient() {
12
75
  return useMemo(() => client, [client]);
13
76
  }
14
77
 
15
- // src/utils/processFontFiles.js
16
- import * as fontkit from "fontkit";
17
- import { nanoid } from "nanoid";
18
-
19
- // src/utils/generateKeywords.js
20
- var coreWeights = ["Hairline", "ExtraThin", "Thin", "Mager", "Maigre", "ExtraLight", "Light", "Chiaro", "Lite", "Leicht", "Demi", "Book", "Buch", "Regular", "Normal", "Medium", "Stark", "Thick", "Kr\xE4ftig", "Viertelfett", "Halbfett", "Dreiviertelfett", "Dark", "Bold", "Neretto", "Gras", "Fett", "Extrafett", "Black", "Nero", "Heavy", "Nerissimo", "Ultra", "Fat", "Poster"];
21
- var modifiers = ["Demi", "Semi", "Extra", "Ultra", "Super", "Plus"];
22
- var coreItalics = ["Italic", "Slant", "Oblique", "Cursive", "Rotalic", "Reverse", "Crab Claw", "Crabclaw", "South Paw", "Southpaw", "Backwards", "Backslant", "Backslanted", "Back Slant"];
23
- var alternativeSpelling = {
24
- Backslant: ["Bsl"],
25
- Backwards: ["Bck"],
26
- Black: ["Blak", "Blk"],
27
- Bold: ["Bd", "Bld"],
28
- // B omitted — too ambiguous
29
- Condensed: ["Cond", "Cnd"],
30
- Crabclaw: ["Crab", "Claw"],
31
- Cursive: ["Cur"],
32
- Dark: ["Drk"],
33
- Expanded: ["Exp"],
34
- Extra: ["Xt", "Xtra", "Xtr", "X"],
35
- // X omitted as standalone — too ambiguous
36
- ExtraBlack: ["Xblk", "XBlk", "Xblck", "XBlck"],
37
- ExtraBold: ["Xbd", "XBd", "Xbld", "XBld", "Xbold", "XBold", "ExBold", "Exbold", "Exbd", "ExBd", "Exbld", "ExBld"],
38
- ExtraCondensed: ["XCond", "Xcnd"],
39
- ExtraExpanded: ["XExp"],
40
- ExtraLight: ["Xlight", "XLight", "Xlt", "XLt", "Xlgt", "XLgt", "Xl", "XL", "Xlght", "XLght"],
41
- ExtraThin: ["Xthin", "Xthn", "Xth", "XThin", "XThn", "XTh", "XT"],
42
- Extended: ["Ext"],
43
- Hairline: ["Hl", "Hln", "Hlnn", "Hlnne", "Hlnnne"],
44
- Italic: ["Ital", "It"],
45
- Light: ["Lt", "Lght"],
46
- Medium: ["Med", "Md", "md", "med"],
47
- Oblique: ["Obl"],
48
- Plus: ["Pls"],
49
- Regular: ["Reg", "Rg"],
50
- Reverse: ["Rev"],
51
- Rotalic: ["Rot"],
52
- SemiBold: ["SmBd", "Sb", "Sbd", "Sbld", "Sbold", "Semibd", "SemiBd", "Semibld", "SemiBld", "semiBd", "semiBld"],
53
- Slant: ["Sl"],
54
- Southpaw: ["South", "Paw"],
55
- Super: ["Supr"],
56
- Thin: ["Thn"],
57
- Ultra: ["Ult", "Ultre", "Ul", "Ulta"],
58
- XX: ["XXt", "XXtra", "XXtr", "XX"],
59
- XXBlack: ["XXblk", "XXBlk", "XXblck", "XXBlck"],
60
- XXLight: ["XXlight", "XXLight", "XXlt", "XXLt", "XXlgt", "XXLgt", "XXl", "XXL", "XXlght", "XXLght"],
61
- XXX: ["XXXt", "XXXtra", "XXXtr", "XXX"],
62
- XXXLight: ["XXXlight", "XXXLight", "XXXlt", "XXXLt", "XXXlgt", "XXXLgt", "XXXl", "XXXL", "XXXlght", "XXXLght"]
63
- };
64
- function reverseSpellingLookup(str) {
65
- let exactMatch = "";
66
- Object.keys(alternativeSpelling).forEach(function(key) {
67
- alternativeSpelling[key].forEach(function(alternative) {
68
- if (str === alternative) {
69
- exactMatch = key;
70
- }
71
- });
72
- });
73
- if (exactMatch) return exactMatch;
74
- let result = "";
75
- let longestMatch = 0;
76
- Object.keys(alternativeSpelling).forEach(function(key) {
77
- alternativeSpelling[key].forEach(function(alternative) {
78
- const regex = new RegExp(`\\b${alternative}\\b`);
79
- if (regex.test(str) && alternative.length > longestMatch) {
80
- result = key;
81
- longestMatch = alternative.length;
82
- }
83
- });
84
- });
85
- return result;
86
- }
87
- function expandAbbreviations(str) {
88
- if (!str) return str;
89
- return str.split(" ").map((word) => {
90
- const expanded = reverseSpellingLookup(word);
91
- return expanded || word;
92
- }).join(" ");
93
- }
94
- function removeWeightNames(str) {
95
- if (!str) return str;
96
- return str.split(" ").map((word) => {
97
- coreWeights.forEach((weight) => {
98
- if (word === weight) word = "";
99
- modifiers.forEach((modifier) => {
100
- if (word === modifier || modifier + weight === word) word = "";
101
- });
102
- });
103
- const expanded = reverseSpellingLookup(word);
104
- if (expanded) return "";
105
- return word;
106
- }).join(" ").trim();
107
- }
108
- function generateStyleKeywords() {
109
- let weightKeywordList = [];
110
- let italicKeywordList = [];
111
- weightKeywordList = [...coreWeights];
112
- modifiers.forEach((modifier) => {
113
- coreWeights.forEach((weight) => {
114
- weightKeywordList.push(modifier + weight);
115
- });
116
- });
117
- weightKeywordList = [...weightKeywordList, ...modifiers];
118
- italicKeywordList = [...coreItalics];
119
- weightKeywordList = weightKeywordList.map(function(el) {
120
- var newEls = [];
121
- Object.keys(alternativeSpelling).forEach(function(key) {
122
- if (el.indexOf(key) !== -1) {
123
- alternativeSpelling[key].forEach(function(alternative) {
124
- let newSpelling = el.replace(key, alternative);
125
- newEls.push(newSpelling);
126
- Object.keys(alternativeSpelling).forEach(function(key2) {
127
- if (newSpelling.indexOf(key2) !== -1) {
128
- alternativeSpelling[key2].forEach(function(alternative2) {
129
- let newSpelling2 = newSpelling.replace(key2, alternative2);
130
- newEls.push(newSpelling2);
131
- Object.keys(alternativeSpelling).forEach(function(key3) {
132
- if (newSpelling2.indexOf(key3) !== -1) {
133
- alternativeSpelling[key3].forEach(function(alternative3) {
134
- newEls.push(newSpelling2.replace(key3, alternative3));
135
- });
136
- }
137
- });
138
- });
139
- }
140
- });
141
- });
142
- }
143
- });
144
- newEls.push(el);
145
- return newEls;
146
- }).reduce(function(a, b) {
147
- return a.concat(b);
148
- });
149
- italicKeywordList = italicKeywordList.map(function(el) {
150
- var newEls = [];
151
- Object.keys(alternativeSpelling).forEach(function(key) {
152
- if (el.indexOf(key) !== -1) {
153
- alternativeSpelling[key].forEach(function(alternative) {
154
- newEls.push(el.replace(key, alternative));
155
- });
156
- }
157
- });
158
- newEls.push(el);
159
- return newEls;
160
- }).reduce(function(a, b) {
161
- return a.concat(b);
162
- });
163
- weightKeywordList = weightKeywordList.sort((a, b) => b.length - a.length);
164
- italicKeywordList = italicKeywordList.sort((a, b) => b.length - a.length);
165
- weightKeywordList = weightKeywordList.filter((item, pos) => weightKeywordList.indexOf(item) === pos);
166
- italicKeywordList = italicKeywordList.filter((item, pos) => italicKeywordList.indexOf(item) === pos);
167
- return { weightKeywordList, italicKeywordList };
168
- }
169
-
170
- // src/utils/sanitizeForSanityId.js
171
- import slugify from "slugify";
172
- function sanitizeForSanityId(str) {
173
- if (!str || typeof str !== "string") {
174
- return "font-" + Date.now();
175
- }
176
- let sanitized = str.toLowerCase().trim();
177
- sanitized = sanitized.replace(/\+/g, "plus");
178
- sanitized = sanitized.replace(/&/g, "and");
179
- sanitized = sanitized.replace(/@/g, "at");
180
- sanitized = slugify(sanitized, {
181
- replacement: "-",
182
- remove: /[^\w\s-]/g,
183
- lower: true,
184
- strict: true,
185
- locale: "en",
186
- trim: true
187
- });
188
- sanitized = sanitized.replace(/[^a-z0-9\-_]/g, "-");
189
- sanitized = sanitized.replace(/-+/g, "-");
190
- sanitized = sanitized.replace(/^[-_]+|[-_]+$/g, "");
191
- if (sanitized && !/^[a-z_]/.test(sanitized)) {
192
- sanitized = "font_" + sanitized;
193
- }
194
- if (!sanitized) {
195
- sanitized = "font_" + Date.now();
196
- }
197
- if (sanitized.length > 128) {
198
- const hash = Math.random().toString(36).substring(2, 8);
199
- sanitized = sanitized.substring(0, 120) + "_" + hash;
200
- }
201
- if (!/^[a-z_][a-z0-9\-_]*$/.test(sanitized)) {
202
- console.warn(`ID sanitization produced invalid result: "${sanitized}", using fallback`);
203
- sanitized = "font_" + Date.now();
204
- }
205
- return sanitized;
206
- }
207
-
208
- // src/utils/processFontFiles.js
209
- var readFontFile = (file) => {
210
- return new Promise((resolve, reject) => {
211
- const reader = new FileReader();
212
- reader.onload = (event) => {
213
- resolve(new Uint8Array(event.target.result));
214
- };
215
- reader.onerror = (error) => {
216
- reject(error);
217
- };
218
- reader.readAsArrayBuffer(file);
219
- });
220
- };
221
- var processFontFiles = async (files, title, weightKeywordList, italicKeywordList, setStatus, preserveShortenedNames = false, preserveFileNames = false) => {
222
- let failedFiles = [];
223
- let subfamilies = {};
224
- let fontsObjects = {};
225
- let newPreferredStyle = { weight: -100, style: "Italic", _ref: "" };
226
- for (let i = 0; i < files.length; i++) {
227
- const file = files[i];
228
- const fontBuffer = await readFontFile(file);
229
- const font = fontkit.create(fontBuffer);
230
- console.log("File name: ", file.name);
231
- if (file.name.endsWith(".woff2") || file.name.endsWith(".woff")) {
232
- await handleWebfontMetadata(file, font, files);
233
- }
234
- let { weightName, subfamilyName, fontTitle, style, italicKW, variableFont } = extractFontMetadata(
235
- font,
236
- title,
237
- weightKeywordList,
238
- italicKeywordList,
239
- preserveShortenedNames
240
- );
241
- let id;
242
- let originalFilename = null;
243
- if (preserveFileNames) {
244
- originalFilename = file.name.replace(/\.(ttf|otf|woff2?|eot|svg)$/i, "");
245
- const normalizedName = originalFilename.replace(/-/g, " ").replace(/([a-z])([A-Z])/g, "$1 $2").replace(/\s+/g, " ").trim();
246
- fontTitle = normalizedName;
247
- id = sanitizeForSanityId(normalizedName);
248
- } else {
249
- id = sanitizeForSanityId(fontTitle);
250
- }
251
- logFontInfo(id, fontTitle, font, file.name, subfamilyName, style, weightName, variableFont, italicKW);
252
- subfamilies[id] = subfamilyName;
253
- if (fontsObjects[id]) {
254
- fontsObjects[id].files = [...fontsObjects[id].files, file];
255
- if (preserveFileNames && originalFilename) {
256
- fontsObjects[id].originalFilename = originalFilename;
257
- }
258
- } else {
259
- fontsObjects[id] = createFontObject(
260
- id,
261
- fontTitle,
262
- title,
263
- font,
264
- variableFont,
265
- weightName,
266
- subfamilyName,
267
- file,
268
- preserveFileNames ? originalFilename : null
269
- );
270
- }
271
- }
272
- fontsObjects = sortFontObjects(fontsObjects);
273
- const uniqueSubfamilies = [...new Set(Object.values(subfamilies))];
274
- console.log("Subfamilies:", subfamilies);
275
- console.log("Unique subfamilies:", uniqueSubfamilies, uniqueSubfamilies.length);
276
- console.log("Font objects:", fontsObjects);
277
- return { fontsObjects, subfamilies, uniqueSubfamilies, newPreferredStyle, failedFiles };
278
- };
279
- var handleWebfontMetadata = async (file, font, files) => {
280
- var _a, _b, _c, _d, _e, _f, _g;
281
- if (!((_b = (_a = font == null ? void 0 : font.name) == null ? void 0 : _a.records) == null ? void 0 : _b.fullName) || ((_d = (_c = font == null ? void 0 : font.name) == null ? void 0 : _c.records) == null ? void 0 : _d.fullName) === "" || !/^[A-Z0-9]+$/.test((_f = (_e = font == null ? void 0 : font.name) == null ? void 0 : _e.records) == null ? void 0 : _f.fullName)) {
282
- const ttfFile = files.find((f) => f.name === file.name.replace(".woff2", ".ttf").replace(".woff", ".ttf"));
283
- if (ttfFile) {
284
- const ttfFileBuffer = await readFontFile(ttfFile);
285
- const ttfFileData = fontkit.create(ttfFileBuffer);
286
- if (ttfFileData) font.name.records = (_g = ttfFileData == null ? void 0 : ttfFileData.name) == null ? void 0 : _g.records;
287
- }
288
- }
289
- };
290
- var extractFontMetadata = (font, title, weightKeywordList, italicKeywordList, preserveShortenedNames = false) => {
291
- var _a, _b, _c, _d, _e, _f;
292
- let weightName = extractWeightName(font, italicKeywordList);
293
- if (!preserveShortenedNames) {
294
- weightName = expandAbbreviations(weightName);
295
- }
296
- if ((weightName === "" || weightName.toLowerCase() === "roman") && ((_b = (_a = font == null ? void 0 : font.name) == null ? void 0 : _a.records) == null ? void 0 : _b.fullName)) {
297
- weightName = extractWeightFromFullName(font, title);
298
- if (!preserveShortenedNames) {
299
- weightName = expandAbbreviations(weightName);
300
- }
301
- }
302
- const variableFont = (font == null ? void 0 : font.variationAxes) && Object.keys(font.variationAxes).length > 0;
303
- let subfamilyName = ((_f = (_e = (_d = (_c = font == null ? void 0 : font.name) == null ? void 0 : _c.records) == null ? void 0 : _d.fullName) == null ? void 0 : _e.en) == null ? void 0 : _f.replace(title.trim(), "").trim()) || font.subfamilyName.trim().replace(title.trim(), "").trim();
304
- if (!preserveShortenedNames) {
305
- subfamilyName = expandAbbreviations(subfamilyName);
306
- }
307
- let fontTitle = font == null ? void 0 : font.fullName.trim();
308
- let style = (font == null ? void 0 : font.italicAngle) !== 0 || (font == null ? void 0 : font.fullName.toLowerCase().includes("italic")) ? "Italic" : "Regular";
309
- const italicKW = processItalicKeywords(font, fontTitle, italicKeywordList);
310
- subfamilyName = processSubfamilyName(subfamilyName, weightKeywordList, italicKW, preserveShortenedNames);
311
- fontTitle = formatFontTitle(fontTitle, preserveShortenedNames);
312
- subfamilyName = subfamilyName === "" ? "Regular" : subfamilyName.replace(/\s+/g, " ").trim();
313
- if (subfamilyName !== "") {
314
- weightName = weightName.replace(`${subfamilyName} `, "").replace(` ${subfamilyName}`, "").trim();
315
- }
316
- if (variableFont) {
317
- if (!fontTitle.toLowerCase().includes("vf")) {
318
- fontTitle = fontTitle + " VF";
319
- }
320
- subfamilyName = "";
321
- }
322
- if (!(variableFont && fontTitle.toLowerCase().includes("italic"))) {
323
- fontTitle = addItalicToFontTitle(font, fontTitle, italicKW, style, preserveShortenedNames);
324
- }
325
- return { weightName, subfamilyName, fontTitle, style, italicKW, variableFont };
326
- };
327
- var extractWeightName = (font, italicKW) => {
328
- var _a, _b, _c, _d;
329
- let weightName = ((_b = (_a = font == null ? void 0 : font.name) == null ? void 0 : _a.records) == null ? void 0 : _b.preferredSubfamily) || ((_d = (_c = font == null ? void 0 : font.name) == null ? void 0 : _c.records) == null ? void 0 : _d.fontSubfamily);
330
- if (typeof weightName === "object") {
331
- weightName = (weightName == null ? void 0 : weightName.en) || (weightName.constructor === Object ? weightName[Object.keys(weightName)[0]] : null);
332
- }
333
- if ((font == null ? void 0 : font.variationAxes) && Object.keys(font.variationAxes).length > 0) {
334
- return "Variable";
335
- }
336
- if (italicKW) {
337
- italicKW.forEach((keyword) => {
338
- const kwRegex = new RegExp(`\\b${keyword.trim()}\\b`, "i");
339
- if (kwRegex.test(weightName)) {
340
- weightName = weightName.replace(kwRegex, "").trim();
341
- }
342
- });
343
- }
344
- return weightName == null ? void 0 : weightName.toString().replace("Italic", "").replace("It", "").replace("Slanted", "").replace("Slant", "").replace("Backslant", "").trim();
345
- };
346
- var extractWeightFromFullName = (font, title) => {
347
- var _a, _b;
348
- let weightName = (_b = (_a = font == null ? void 0 : font.name) == null ? void 0 : _a.records) == null ? void 0 : _b.fullName;
349
- weightName = (weightName == null ? void 0 : weightName.en) ? weightName.en : (weightName == null ? void 0 : weightName.constructor) === Object ? weightName[Object.keys(weightName)[0]] : weightName;
350
- weightName = weightName == null ? void 0 : weightName.replace(title + " ", "").replace(title, "").trim();
351
- weightName = weightName == null ? void 0 : weightName.replace("Italic", "").replace("It", "").replace("Slanted", "").replace("Slant", "").trim();
352
- return weightName;
353
- };
354
- var processSubfamilyName = (subfamilyName, weightKeywordList, italicKeywordList, preserveShortenedNames = false) => {
355
- weightKeywordList.forEach((keyword) => {
356
- const kwRegex = new RegExp(`\\b${keyword.trim()}\\b`, "i");
357
- if (kwRegex.test(subfamilyName)) {
358
- subfamilyName = subfamilyName.replace(kwRegex, "").trim();
359
- }
360
- subfamilyName = removeWeightNames(subfamilyName) || subfamilyName;
361
- if (!preserveShortenedNames) {
362
- subfamilyName = expandAbbreviations(subfamilyName);
363
- }
364
- });
365
- italicKeywordList.forEach((keyword) => {
366
- const kwRegex = new RegExp(`\\b${keyword.trim()}\\b`, "i");
367
- if (kwRegex.test(subfamilyName)) {
368
- subfamilyName = subfamilyName.replace(kwRegex, "").trim();
369
- }
370
- });
371
- return subfamilyName;
372
- };
373
- var processItalicKeywords = (font, fontTitle, italicKeywordList) => {
374
- let italicKW = [];
375
- italicKeywordList.forEach((keyword) => {
376
- const kw = keyword.trim();
377
- const kwRegex = new RegExp(`\\b${kw}\\b`, "i");
378
- if (kwRegex.test(fontTitle)) {
379
- fontTitle = fontTitle.replace(kwRegex, "").trim();
380
- italicKW.push(kw);
381
- }
382
- if ((font == null ? void 0 : font.fullName) && typeof font.fullName === "string" && font.fullName.toLowerCase().includes(kw.toLowerCase())) {
383
- if (!italicKW.includes(kw)) italicKW.push(kw);
384
- }
385
- });
386
- return italicKW;
387
- };
388
- var formatFontTitle = (fontTitle, preserveShortenedNames = false) => {
389
- const hasItalic = fontTitle.toLowerCase().includes("italic");
390
- fontTitle = fontTitle.replace(/-/g, " ");
391
- return fontTitle.replace(/\s+/g, " ").trim().split(" ").map((word) => {
392
- if (hasItalic && word.toLowerCase() === "italic") return "Italic";
393
- let fullWord = word;
394
- if (!preserveShortenedNames) {
395
- fullWord = reverseSpellingLookup(word) || word;
396
- }
397
- return fullWord[0].toUpperCase() + fullWord.slice(1);
398
- }).join(" ");
399
- };
400
- var addItalicToFontTitle = (font, fontTitle, italicKW, style, preserveShortenedNames = false) => {
401
- const hasItalicAngle = (font == null ? void 0 : font.italicAngle) !== 0;
402
- const hasItalicInName = font == null ? void 0 : font.fullName.toLowerCase().includes("italic");
403
- if (italicKW.length > 0 || hasItalicAngle || hasItalicInName) {
404
- italicKW = [...new Set(italicKW)];
405
- if (italicKW.length === 0 && (hasItalicAngle || hasItalicInName)) {
406
- italicKW = ["Italic"];
407
- }
408
- if (!preserveShortenedNames) {
409
- italicKW = italicKW.map((item) => reverseSpellingLookup(item) || item);
410
- }
411
- italicKW = [...new Set(italicKW)];
412
- if (italicKW.length > 1 && italicKW.includes("Italic")) {
413
- italicKW = ["Italic"];
414
- }
415
- const fontTitleLower = fontTitle.toLowerCase();
416
- italicKW = italicKW.filter((keyword) => {
417
- const keywordLower = keyword.toLowerCase();
418
- const kwRegex = new RegExp(`\\b${keywordLower}\\b`);
419
- const isSubstring = fontTitleLower.split(" ").some(
420
- (word) => word.includes(keywordLower) || keywordLower.includes(word)
421
- );
422
- return !kwRegex.test(fontTitleLower) && !isSubstring;
423
- });
424
- if (italicKW.length > 0) {
425
- fontTitle = fontTitle.trim() + " " + italicKW.join(" ");
426
- }
427
- }
428
- return fontTitle;
429
- };
430
- var createFontObject = (id, fontTitle, title, font, variableFont, weightName, subfamilyName, file, originalFilename = null) => {
431
- const fontObject = {
432
- _key: nanoid(),
433
- _id: id,
434
- title: fontTitle,
435
- slug: { _type: "slug", current: id },
436
- typefaceName: title,
437
- style: (font == null ? void 0 : font.italicAngle) !== 0 || (font == null ? void 0 : font.fullName.toLowerCase().includes("italic")) ? "Italic" : "Regular",
438
- variableFont,
439
- weightName,
440
- subfamily: subfamilyName,
441
- normalWeight: true,
442
- weight: Number(determineWeight(font, weightName)),
443
- fileInput: {},
444
- files: [file],
445
- fontKit: font
446
- };
447
- if (originalFilename) {
448
- fontObject.originalFilename = originalFilename;
449
- }
450
- return fontObject;
451
- };
452
- var determineWeight = (font, weightName) => {
453
- var _a;
454
- if ((_a = font["OS/2"]) == null ? void 0 : _a.usWeightClass) {
455
- return Number(font["OS/2"].usWeightClass);
456
- }
457
- const wn = (weightName == null ? void 0 : weightName.toLowerCase()) || "";
458
- if (/hairline|extra thin|extrathin/.test(wn)) return 100;
459
- if (/thin|extra light|extralight/.test(wn)) return 200;
460
- if (/light|book/.test(wn)) return 300;
461
- if (/regular|normal/.test(wn)) return 400;
462
- if (/medium/.test(wn)) return 500;
463
- if (/semi bold|semibold/.test(wn)) return 600;
464
- if (/extra bold|extrabold/.test(wn)) return 800;
465
- if (/bold/.test(wn)) return 700;
466
- if (/black|ultra/.test(wn)) return 900;
467
- return 400;
468
- };
469
- var sortFontObjects = (fontsObjects) => {
470
- return Object.fromEntries(
471
- Object.entries(fontsObjects).sort((a, b) => {
472
- const weightA = Number(a[1].weight);
473
- const weightB = Number(b[1].weight);
474
- if (weightA === weightB) {
475
- if (a[1].style === "Regular" && b[1].style === "Italic") return -1;
476
- if (a[1].style === "Italic" && b[1].style === "Regular") return 1;
477
- return 0;
478
- }
479
- return weightA - weightB;
480
- })
481
- );
482
- };
483
- var logFontInfo = (id, fontTitle, font, fileName, subfamilyName, style, weightName, variableFont, italicKW) => {
484
- console.log("=== Font Info ====");
485
- console.log("Font id: ", id);
486
- console.log("Font title: ", fontTitle);
487
- console.log("Fontkit fullName: ", font.fullName);
488
- console.log("Fontkit family name: ", font.familyName);
489
- console.log("File name: ", fileName);
490
- console.log("Subfamily: ", subfamilyName);
491
- console.log("Style: ", style);
492
- console.log("Weight: ", weightName);
493
- console.log("Variable: ", variableFont);
494
- console.log("italicKW: ", italicKW);
495
- console.log("Font italic angle: ", (font == null ? void 0 : font.italicAngle) !== 0 || (font == null ? void 0 : font.fullName.toLowerCase().includes("italic")) ? "Italic" : "Regular");
496
- console.log("=======");
497
- };
498
-
499
- // src/utils/uploadFontFiles.js
500
- import { nanoid as nanoid3 } from "nanoid";
501
-
502
- // src/utils/generateCssFile.js
503
- import base64 from "base-64";
504
- import { Buffer } from "buffer";
505
- import * as fontkit2 from "fontkit";
506
- function _arrayBufferToBase64(buffer) {
507
- var binary = "";
508
- var bytes = new Uint8Array(buffer);
509
- var len = bytes.byteLength;
510
- for (var i = 0; i < len; i++) {
511
- binary += String.fromCharCode(bytes[i]);
512
- }
513
- return base64.encode(binary);
514
- }
515
- function buildVFDescriptors(font) {
516
- const cssAxes = {};
517
- const skipped = [];
518
- try {
519
- const va = font.variationAxes;
520
- if (!va) return { descriptors: "", skipped: [] };
521
- for (const [tag, axis] of Object.entries(va)) {
522
- const lo = Math.min(axis.min, axis.max);
523
- const hi = Math.max(axis.min, axis.max);
524
- if (lo === hi) {
525
- skipped.push(tag);
526
- continue;
527
- }
528
- if (tag === "wght") {
529
- cssAxes["font-weight"] = `${lo} ${hi}`;
530
- } else if (tag === "wdth") {
531
- cssAxes["font-stretch"] = `${lo}% ${hi}%`;
532
- } else if (tag === "slnt") {
533
- cssAxes["font-style"] = `oblique ${lo}deg ${hi}deg`;
534
- } else if (tag === "ital" && !cssAxes["font-style"]) {
535
- if (hi > 0) cssAxes["font-style"] = "italic";
536
- else skipped.push(tag);
537
- } else {
538
- skipped.push(tag);
539
- }
540
- }
541
- } catch (_) {
542
- }
543
- const descriptors = Object.entries(cssAxes).map(([k, v]) => `${k}:${v}`).join(";") + (Object.keys(cssAxes).length ? ";" : "");
544
- return { descriptors, skipped };
545
- }
546
- var FALLBACK_STACKS = {
547
- "sans-serif": "local('Arial'), local('Helvetica Neue'), local('Roboto'), local('Liberation Sans')",
548
- "serif": "local('Georgia'), local('Times New Roman'), local('Times')",
549
- "monospace": "local('Courier New'), local('Courier'), local('Menlo'), local('Monaco')",
550
- // Display and script fonts have no universally suitable system fallback; default to sans-serif
551
- "default": "local('Arial'), local('Helvetica Neue'), local('Roboto'), local('Liberation Sans')"
552
- };
553
- var FAMILY_CLASS_MAP = {
554
- 1: "serif",
555
- 2: "serif",
556
- 3: "serif",
557
- 4: "serif",
558
- 5: "serif",
559
- 7: "serif",
560
- 8: "sans-serif"
561
- };
562
- var SERIF_NAMES = /jubilat|corundum|dapifer|birra|daith/i;
563
- var SANS_NAMES = /halyard|gamay|omnes|kit/i;
564
- function detectFontCategory(font, fontName) {
565
- var _a;
566
- if (fontName && SERIF_NAMES.test(fontName)) return "serif";
567
- if (fontName && SANS_NAMES.test(fontName)) return "sans-serif";
568
- try {
569
- const familyClass = ((_a = font["OS/2"]) == null ? void 0 : _a.sFamilyClass) ?? 0;
570
- const highByte = familyClass >> 8 & 255;
571
- return FAMILY_CLASS_MAP[highByte] ?? "default";
572
- } catch {
573
- return "default";
574
- }
575
- }
576
- function calcFallbackData(arrayBuffer, fontName) {
577
- try {
578
- let font = fontkit2.create(Buffer.from(arrayBuffer));
579
- let upm = font.unitsPerEm;
580
- let category = detectFontCategory(font, fontName);
581
- return {
582
- fallbackSrc: FALLBACK_STACKS[category],
583
- ascentOverride: `${(font.ascent / upm * 100).toFixed(2)}%`,
584
- descentOverride: `${(Math.abs(font.descent) / upm * 100).toFixed(2)}%`,
585
- lineGapOverride: `${(font.lineGap / upm * 100).toFixed(2)}%`
586
- };
587
- } catch (err) {
588
- console.error("Failed to extract fallback font data:", err);
589
- return {
590
- fallbackSrc: FALLBACK_STACKS["default"],
591
- ascentOverride: "100%",
592
- descentOverride: "0%",
593
- lineGapOverride: "0%"
594
- };
595
- }
596
- }
597
- async function generateCssFile({
598
- woff2File,
599
- fileInput,
600
- language = null,
601
- fileName,
602
- fontName,
603
- variableFont,
604
- weight,
605
- style = "Normal",
606
- client
607
- }) {
608
- try {
609
- let arrayBuffer = await woff2File.arrayBuffer();
610
- let b64 = _arrayBufferToBase64(arrayBuffer);
611
- let fontkitFont = fontkit2.create(Buffer.from(arrayBuffer));
612
- let { fallbackSrc, ascentOverride, descentOverride, lineGapOverride } = calcFallbackData(arrayBuffer, fontName);
613
- let cssString;
614
- if (variableFont) {
615
- let { descriptors, skipped } = buildVFDescriptors(fontkitFont);
616
- let skipComment = skipped.length ? `/* axes present but have no @font-face descriptor: ${skipped.join(", ")}` + (skipped.includes("opsz") ? " \u2014 add font-optical-sizing:auto to your element CSS" : "") + " */" : "";
617
- cssString = `${skipComment}@font-face{font-family:'${fontName}';src:url(data:application/font-woff2;charset=utf-8;base64,${b64})format('woff2-variations');${descriptors}font-display:swap;}`;
618
- } else {
619
- let fontStyle = style === "Italic" ? "italic" : "normal";
620
- cssString = `@font-face{font-family:'${fontName}';src:url(data:application/font-woff2;charset=utf-8;base64,${b64})format('woff2');font-weight:${weight};font-style:${fontStyle};font-display:swap;}`;
621
- }
622
- let fallbackCssString = `@font-face{font-family:'${fontName} Fallback';src:${fallbackSrc};ascent-override:${ascentOverride};descent-override:${descentOverride};line-gap-override:${lineGapOverride};}`;
623
- let uploadBuffer = Buffer.from(cssString + fallbackCssString, "utf-8");
624
- let doc = await client.assets.upload("file", uploadBuffer, { filename: fileName + ".css" });
625
- let newFileInput = language == null ? {
626
- ...fileInput,
627
- css: {
628
- _type: "file",
629
- asset: {
630
- _type: "reference",
631
- _ref: doc._id
632
- }
633
- }
634
- } : {
635
- ...fileInput,
636
- [language]: {
637
- ...fileInput[language],
638
- css: {
639
- _type: "file",
640
- asset: {
641
- _type: "reference",
642
- _ref: doc._id
643
- }
644
- }
645
- }
646
- };
647
- return newFileInput;
648
- } catch (err) {
649
- console.error(err);
650
- throw err;
651
- }
652
- }
653
-
654
- // src/utils/generateFontData.js
655
- import { Buffer as Buffer2 } from "buffer";
656
- import * as fontkit3 from "fontkit";
657
- async function generateFontData({ fileInput, url, fontKit, fontId, client, commit = true }) {
658
- var _a;
659
- if (fontId.startsWith("drafts.")) {
660
- fontId = fontId.replace("drafts.", "");
661
- }
662
- console.log("generate-font-data ", fontId, commit);
663
- let srcUrl;
664
- if (!url || url == null) {
665
- srcUrl = await client.fetch(`*[_id == $id]{url}`, { id: fileInput.ttf.asset._ref });
666
- console.log("src url ", srcUrl);
667
- srcUrl = srcUrl[0].url;
668
- } else {
669
- srcUrl = url;
670
- }
671
- let font = fontKit;
672
- if (!fontKit || fontKit == null) {
673
- let buffer = await fetch(srcUrl);
674
- buffer = await buffer.arrayBuffer();
675
- buffer = Buffer2.from(buffer);
676
- font = fontkit3.create(buffer);
677
- }
678
- let variableAxes;
679
- try {
680
- variableAxes = font.variationAxes;
681
- } catch (err) {
682
- console.error("err: ", err);
683
- }
684
- let variableInstances;
685
- try {
686
- variableInstances = font.namedVariations;
687
- } catch (e) {
688
- console.log("variable instances 2 error : ", e.message);
689
- let fvar = (_a = font == null ? void 0 : font.fvar) == null ? void 0 : _a.instance;
690
- fvar == null ? void 0 : fvar.forEach((fv) => {
691
- var _a2, _b, _c, _d, _e, _f;
692
- if ((fv == null ? void 0 : fv.nameID) === 2) fv.name = (_c = (_b = (_a2 = font == null ? void 0 : font._tables) == null ? void 0 : _a2.name) == null ? void 0 : _b.records) == null ? void 0 : _c.fontSubfamily;
693
- if ((fv == null ? void 0 : fv.nameID) === 17) fv.name = (_f = (_e = (_d = font == null ? void 0 : font._tables) == null ? void 0 : _d.name) == null ? void 0 : _e.records) == null ? void 0 : _f.preferredSubfamily;
694
- });
695
- variableInstances = {};
696
- fvar.forEach((v) => {
697
- let key = v.name;
698
- if (typeof key === "object") {
699
- key = Object.values(key)[0];
700
- }
701
- let coordKeys = Object.keys(variableAxes);
702
- let coord = {};
703
- coordKeys.forEach((ck, ckIndex) => {
704
- coord[ck] = v.coord[ckIndex];
705
- });
706
- variableInstances[key] = coord;
707
- });
708
- }
709
- console.log("font : ", font);
710
- console.log("variable instances : ", variableInstances);
711
- console.log("variable axes : ", variableAxes);
712
- let opentypeFeatures = font.availableFeatures;
713
- let glyphCount = font.numGlyphs;
714
- let characterSet = font.characterSet;
715
- let metaData = {
716
- postscriptName: font.postscriptName,
717
- fullName: font.fullName,
718
- familyName: font.familyName,
719
- subfamilyName: font.subfamilyName,
720
- copyright: font.copyright,
721
- version: font.version.replaceAll("Version ", ""),
722
- genDate: (/* @__PURE__ */ new Date()).toISOString()
723
- };
724
- let metrics = {
725
- unitsPerEm: font.unitsPerEm,
726
- ascender: font.ascent,
727
- descender: font.descent,
728
- lineGap: font.lineGap,
729
- underlinePosition: font.underlinePosition,
730
- underlineThickness: font.underlineThickness,
731
- italicAngle: font.italicAngle,
732
- capHeight: font.capHeight,
733
- xHeight: font.xHeight,
734
- boundingBox: font.bbox
735
- };
736
- let variableFont = false;
737
- if (variableAxes && variableAxes != null && Object.keys(variableAxes).length > 0 && variableInstances && variableInstances != null && Object.keys(variableInstances).length > 0) {
738
- variableFont = true;
739
- }
740
- let patch = {
741
- metrics,
742
- metaData,
743
- variableFont,
744
- variableAxes: JSON.stringify(variableAxes),
745
- variableInstances: JSON.stringify(variableInstances),
746
- glyphCount,
747
- opentypeFeatures: { chars: opentypeFeatures },
748
- characterSet: { chars: characterSet }
749
- };
750
- console.log("data : ", patch);
751
- if (commit) patch = await client.patch(fontId).set(patch).commit({ autoGenerateArrayKeys: true });
752
- return patch;
753
- }
754
-
755
- // src/utils/parseVariableFontInstances.js
756
- import { nanoid as nanoid2 } from "nanoid";
757
- var parseVariableFontInstances = async (font, client) => {
758
- if (!font.variableFont || !font.variableInstances) return [];
759
- let variableInstances;
760
- try {
761
- variableInstances = JSON.parse(font.variableInstances);
762
- } catch (err) {
763
- console.error("Error parsing variable instances:", err);
764
- variableInstances = {};
765
- }
766
- if (Object.keys(variableInstances).length === 0) return [];
767
- let staticFonts;
768
- const typeface = await client.fetch(
769
- `*[_type == 'typeface' && title == $typefaceName][0]{
770
- 'fonts': styles.fonts[]-> {
771
- _id,
772
- title,
773
- subfamily,
774
- style,
775
- weight,
776
- weightName,
777
- metaData,
778
- variableFont
779
- }
780
- }`,
781
- { typefaceName: font.typefaceName }
782
- );
783
- if ((typeface == null ? void 0 : typeface.fonts) && typeface.fonts.length > 0) {
784
- staticFonts = typeface.fonts.filter((f) => !f.variableFont);
785
- console.log("Using curated typeface fonts list:", staticFonts.length, "fonts");
786
- } else {
787
- console.warn("Typeface not found or no fonts in curated list, falling back to all fonts query");
788
- staticFonts = await client.fetch(
789
- `*[_type == 'font' && typefaceName == $typefaceName && variableFont != true]{
790
- _id,
791
- title,
792
- subfamily,
793
- style,
794
- weight,
795
- weightName,
796
- metaData
797
- }`,
798
- { typefaceName: font.typefaceName }
799
- );
800
- }
801
- console.log("Variable font instances:", Object.keys(variableInstances));
802
- console.log("Available static fonts:", staticFonts.map((sf) => sf.title));
803
- const instanceMappings = [];
804
- Object.keys(variableInstances).forEach((instanceName) => {
805
- let matchingFont = null;
806
- matchingFont = staticFonts.find((sf) => sf.title === instanceName);
807
- if (!matchingFont && staticFonts.some((sf) => {
808
- var _a;
809
- return (_a = sf.metaData) == null ? void 0 : _a.fullName;
810
- })) {
811
- matchingFont = staticFonts.find((sf) => {
812
- var _a, _b, _c, _d;
813
- if (!((_a = sf.metaData) == null ? void 0 : _a.fullName)) return false;
814
- let fullName = sf.metaData.fullName;
815
- const WORDS_TO_REMOVE = ["VF", "var", "variable", "VAR", "vf"];
816
- const variableName = (_c = (_b = font.metaData) == null ? void 0 : _b.familyName) == null ? void 0 : _c.replace(new RegExp(`\\b(${WORDS_TO_REMOVE.join("|")})\\b`, "gi"), "").replace(/\s{2,}/g, " ").trim();
817
- if (variableName && fullName.startsWith(variableName)) {
818
- fullName = fullName.substring(variableName.length).trim();
819
- }
820
- if (variableName) {
821
- const words = variableName.split(/\s+/).map((w) => w.trim()).filter(Boolean);
822
- if (words.length > 0) {
823
- const regex = new RegExp(`\\b(${words.join("|")})\\b`, "gi");
824
- const stripped = fullName.replace(regex, "").replace(/\s{2,}/g, " ").trim();
825
- if (stripped !== "") fullName = stripped;
826
- }
827
- }
828
- if (fullName.startsWith(font.typefaceName)) {
829
- fullName = fullName.substring(font.typefaceName.length).trim();
830
- }
831
- if (((_d = sf.style) == null ? void 0 : _d.toLowerCase()) === "italic" && !fullName.toLowerCase().endsWith("italic") && !fullName.toLowerCase().endsWith("slanted")) {
832
- fullName = fullName + " Italic";
833
- }
834
- if (fullName.trim().toLowerCase().endsWith("regular")) {
835
- if (instanceName.trim().toLowerCase() + " regular" === fullName.trim().toLowerCase()) return true;
836
- }
837
- if (fullName.trim().toLowerCase().startsWith("regular")) {
838
- if ("regular " + instanceName.trim().toLowerCase() === fullName.trim().toLowerCase()) return true;
839
- }
840
- if (fullName.trim().toLowerCase().endsWith("italic")) {
841
- if (instanceName.trim().toLowerCase().endsWith("italic")) {
842
- const k = instanceName.trim().toLowerCase().slice(0, -6).trim() + " regular italic";
843
- if (k === fullName.trim().toLowerCase()) return true;
844
- }
845
- }
846
- return fullName.trim().toLowerCase() === instanceName.trim().toLowerCase();
847
- });
848
- }
849
- if (!matchingFont) {
850
- const expandedName = instanceName.split(" ").map((word) => expandAbbreviations(word)).join(" ");
851
- matchingFont = staticFonts.find((sf) => {
852
- const nameWithoutTypeface = sf.title.replace(font.typefaceName, "").trim();
853
- return nameWithoutTypeface === expandedName;
854
- });
855
- }
856
- if (!matchingFont) {
857
- const isItalic = instanceName.toLowerCase().includes("italic");
858
- const weightTerms = [
859
- { term: "thin", weight: "100" },
860
- { term: "extralight", weight: "200" },
861
- { term: "extra light", weight: "200" },
862
- { term: "light", weight: "300" },
863
- { term: "regular", weight: "400" },
864
- { term: "normal", weight: "400" },
865
- { term: "medium", weight: "500" },
866
- { term: "semibold", weight: "600" },
867
- { term: "semi bold", weight: "600" },
868
- { term: "bold", weight: "700" },
869
- { term: "extrabold", weight: "800" },
870
- { term: "extra bold", weight: "800" },
871
- { term: "black", weight: "900" },
872
- { term: "heavy", weight: "900" }
873
- ];
874
- let instanceWeight = "400";
875
- for (const { term, weight } of weightTerms) {
876
- if (instanceName.toLowerCase().includes(term)) {
877
- instanceWeight = weight;
878
- break;
879
- }
880
- }
881
- matchingFont = staticFonts.find(
882
- (sf) => sf.weight === instanceWeight && (isItalic && sf.style === "Italic" || !isItalic && sf.style === "Regular")
883
- );
884
- }
885
- if (!matchingFont) {
886
- matchingFont = staticFonts.find((sf) => {
887
- if (!sf.weightName) return false;
888
- const cleanInstance = instanceName.toLowerCase().replace(/italic/i, "").trim();
889
- const cleanWeight = sf.weightName.toLowerCase().replace(/italic/i, "").trim();
890
- return cleanInstance === cleanWeight;
891
- });
892
- }
893
- if (!matchingFont && staticFonts.some((sf) => {
894
- var _a;
895
- return (_a = sf.metaData) == null ? void 0 : _a.fullName;
896
- })) {
897
- matchingFont = staticFonts.find((sf) => {
898
- var _a;
899
- if (!((_a = sf.metaData) == null ? void 0 : _a.fullName)) return false;
900
- const typefacePattern = new RegExp(`^${font.typefaceName}\\s+`, "i");
901
- const stylePart = sf.metaData.fullName.replace(typefacePattern, "").trim();
902
- return instanceName.toLowerCase() === stylePart.toLowerCase();
903
- });
904
- }
905
- console.log(`Instance "${instanceName}" matched with:`, matchingFont ? matchingFont.title : "No match found");
906
- instanceMappings.push({
907
- key: instanceName,
908
- value: matchingFont ? { _type: "reference", _ref: matchingFont._id, _weak: true } : null,
909
- _key: nanoid2()
910
- });
911
- });
912
- return instanceMappings;
913
- };
914
- var parseVariableFontInstances_default = parseVariableFontInstances;
915
-
916
78
  // src/utils/uploadFontFiles.js
79
+ import { nanoid } from "nanoid";
917
80
  var uploadFontFiles = async (fontsObjects, subfamilies, client, inputPrice, stylesObject, setStatus, setError, preserveFileNames = false) => {
918
81
  let fontRefs = [];
919
82
  let variableRefs = [];
@@ -1010,7 +173,7 @@ var determineFileType = (file) => {
1010
173
  if (file.name.endsWith(".svg")) return "svg";
1011
174
  return "";
1012
175
  };
1013
- var resolveExistingFont = async (font, client) => {
176
+ var resolveExistingFont2 = async (font, client) => {
1014
177
  const result = { exact: null, candidates: [], recommendation: "create" };
1015
178
  try {
1016
179
  const idMatches = await client.fetch(
@@ -1071,7 +234,7 @@ var resolveExistingFont = async (font, client) => {
1071
234
  };
1072
235
  var createOrUpdateFontDocument = async (font, client, setError) => {
1073
236
  try {
1074
- const { exact, candidates, recommendation } = await resolveExistingFont(font, client);
237
+ const { exact, candidates, recommendation } = await resolveExistingFont2(font, client);
1075
238
  const { files, fontKit } = font;
1076
239
  delete font.files;
1077
240
  delete font.fontKit;
@@ -1093,7 +256,7 @@ var createOrUpdateFontDocument = async (font, client, setError) => {
1093
256
  fontResponse = await createNewFont(font, client);
1094
257
  }
1095
258
  return {
1096
- _key: nanoid3(),
259
+ _key: nanoid(),
1097
260
  _type: "reference",
1098
261
  _ref: fontResponse._id,
1099
262
  _weak: true
@@ -1136,7 +299,7 @@ var createNewFont = async (font, client) => {
1136
299
  console.log("Creating new font:", font._id, font.title);
1137
300
  if (font.metaData) cleanMetadataValues(font);
1138
301
  const newDocument = {
1139
- _key: nanoid3(),
302
+ _key: nanoid(),
1140
303
  _id: font._id,
1141
304
  _type: "font",
1142
305
  ...font
@@ -1173,89 +336,7 @@ var addToVariableRefs = (fontRef, font, variableRefs, stylesObject) => {
1173
336
  }
1174
337
  };
1175
338
 
1176
- // src/utils/updateTypefaceDocument.js
1177
- import { nanoid as nanoid4 } from "nanoid";
1178
- var updateTypefaceDocument = async (doc_id, fontRefs, variableRefs, subfamilies, uniqueSubfamilies, subfamiliesArray, preferredStyleRef, newPreferredStyle, stylesObject, client, setStatus, setError) => {
1179
- console.log("Updating typeface document with new fonts:", { fontRefs, variableRefs, subfamilies, uniqueSubfamilies });
1180
- setStatus("Updating typeface references...");
1181
- let patch = {
1182
- "styles.fonts": stylesObject.fonts ? [...stylesObject.fonts, ...fontRefs] : [...fontRefs],
1183
- "styles.variableFont": (stylesObject == null ? void 0 : stylesObject.variableFont) ? [...stylesObject.variableFont, ...variableRefs] : [...variableRefs]
1184
- };
1185
- setStatus("Organising font subfamilies...");
1186
- subfamiliesArray = subfamiliesArray || [];
1187
- uniqueSubfamilies.forEach((subfamilyName) => {
1188
- if (!subfamiliesArray.find((sf) => sf.title === subfamilyName)) {
1189
- subfamiliesArray.push({
1190
- title: subfamilyName,
1191
- _key: nanoid4(),
1192
- _type: "object",
1193
- fonts: []
1194
- });
1195
- }
1196
- });
1197
- if (subfamiliesArray.length > 0) {
1198
- Object.entries(subfamilies).forEach(([id, subfamilyName]) => {
1199
- if (id.toLowerCase().includes("vf")) return;
1200
- const subfamilyIndex = subfamiliesArray.findIndex((sf) => sf.title === subfamilyName);
1201
- if (subfamilyIndex !== -1) {
1202
- subfamiliesArray[subfamilyIndex].fonts.push({
1203
- _ref: id,
1204
- _key: nanoid4(),
1205
- _type: "reference",
1206
- _weak: true
1207
- });
1208
- }
1209
- });
1210
- subfamiliesArray = subfamiliesArray.map((subfamily) => ({
1211
- ...subfamily,
1212
- fonts: subfamily.fonts.filter(
1213
- (font, index, self) => index === self.findIndex((f) => f._ref === font._ref)
1214
- )
1215
- }));
1216
- }
1217
- patch["styles.subfamilies"] = subfamiliesArray;
1218
- await updatePreferredStyle(doc_id, preferredStyleRef, newPreferredStyle, patch, client);
1219
- console.log("doc_id: ", doc_id);
1220
- console.log("Typeface patch: ", patch);
1221
- console.log("New preferred style: ", newPreferredStyle);
1222
- console.log("SubfamiliesArray:", subfamiliesArray);
1223
- try {
1224
- await client.patch(doc_id).set(patch).commit();
1225
- console.log(`Updated document: ${doc_id}`);
1226
- if (doc_id.startsWith("drafts.")) {
1227
- await updatePublishedDocument(doc_id, patch, client);
1228
- }
1229
- } catch (err) {
1230
- console.error("Error updating document:", err.message);
1231
- setStatus("Error updating typeface");
1232
- setError(true);
1233
- }
1234
- };
1235
- var updatePreferredStyle = async (doc_id, preferredStyleRef, newPreferredStyle, patch, client) => {
1236
- const isCurrentlyEmpty = !(preferredStyleRef == null ? void 0 : preferredStyleRef._ref) || preferredStyleRef._ref === "" || preferredStyleRef._ref === null;
1237
- const hasCandidate = (newPreferredStyle == null ? void 0 : newPreferredStyle._ref) && newPreferredStyle._ref !== "";
1238
- if (isCurrentlyEmpty && hasCandidate) {
1239
- patch.preferredStyle = {
1240
- _type: "reference",
1241
- _ref: newPreferredStyle._ref,
1242
- _weak: true
1243
- };
1244
- }
1245
- };
1246
- var updatePublishedDocument = async (doc_id, patch, client) => {
1247
- const publishedId = doc_id.replace("drafts.", "");
1248
- const publishedDoc = await client.fetch(`*[_id == $publishedId]`, { publishedId }).then((res) => res[0]);
1249
- if (publishedDoc) {
1250
- await client.patch(publishedId).set(patch).commit();
1251
- console.log(`Updated published document: ${publishedId}`);
1252
- } else {
1253
- console.log(`No published document found for ${publishedId}, skipping`);
1254
- }
1255
- };
1256
-
1257
339
  // src/utils/regenerateFontData.js
1258
- import * as fontkit4 from "fontkit";
1259
340
  var renameFontDocuments = async ({
1260
341
  client,
1261
342
  typefaceName,
@@ -1325,7 +406,7 @@ var renameFontDocuments = async ({
1325
406
  file = await res.blob();
1326
407
  }
1327
408
  const fontBuffer = await readFontFile(file);
1328
- const font = fontkit4.create(fontBuffer);
409
+ const font = await parseFont(fontBuffer, `${fontDoc._id}.ttf`);
1329
410
  const { weightName, subfamilyName, fontTitle } = extractFontMetadata(
1330
411
  font,
1331
412
  typefaceName,
@@ -1443,24 +524,10 @@ var StatusDisplay = ({ status, error, action }) => {
1443
524
  };
1444
525
  var StatusDisplay_default = StatusDisplay;
1445
526
 
1446
- // src/components/PriceInput.jsx
1447
- import React2 from "react";
1448
- import { Flex as Flex2, Text as Text2 } from "@sanity/ui";
1449
- var PriceInput = ({ inputPrice, handleInputChange }) => /* @__PURE__ */ React2.createElement(Flex2, { align: "center", gap: 2 }, /* @__PURE__ */ React2.createElement(Text2, { size: 1, muted: true }, "Price:"), /* @__PURE__ */ React2.createElement(Text2, { size: 1, muted: true }, "$"), /* @__PURE__ */ React2.createElement(
1450
- "input",
1451
- {
1452
- value: inputPrice,
1453
- onChange: handleInputChange,
1454
- type: "number",
1455
- style: { textAlign: "end", padding: "5px", maxWidth: "75px" }
1456
- }
1457
- ), /* @__PURE__ */ React2.createElement(Text2, { size: 1, muted: true }, "per style"));
1458
- var PriceInput_default = PriceInput;
1459
-
1460
527
  // src/components/RegenerateSubfamiliesComponent.jsx
1461
- import React3, { useState } from "react";
1462
- import { nanoid as nanoid5 } from "nanoid";
1463
- import { Button, Text as Text3, Stack, Box } from "@sanity/ui";
528
+ import React2, { useState } from "react";
529
+ import { nanoid as nanoid2 } from "nanoid";
530
+ import { Button, Text as Text2, Stack, Box } from "@sanity/ui";
1464
531
  import { useFormValue } from "sanity";
1465
532
  var RegenerateSubfamiliesComponent = () => {
1466
533
  const [status, setStatus] = useState("");
@@ -1474,7 +541,7 @@ var RegenerateSubfamiliesComponent = () => {
1474
541
  const handleClick = () => {
1475
542
  regenerateSubfamilies({ title, stylesObject, slug, doc_id, client, setStatus, setReady, setError });
1476
543
  };
1477
- return /* @__PURE__ */ React3.createElement(React3.Fragment, null, status && /* @__PURE__ */ React3.createElement(Box, { padding: 3, style: { borderRadius: "4px", marginBottom: "10px" } }, /* @__PURE__ */ React3.createElement(Text3, { size: 1, style: { color: error ? "red" : "green" } }, status)), /* @__PURE__ */ React3.createElement(Button, { mode: "ghost", tone: "primary", width: "fill", padding: 3, onClick: handleClick, disabled: !ready }, /* @__PURE__ */ React3.createElement(Stack, { space: 2 }, /* @__PURE__ */ React3.createElement(Text3, { align: "center" }, "Regenerate Subfamilies"))));
544
+ return /* @__PURE__ */ React2.createElement(React2.Fragment, null, status && /* @__PURE__ */ React2.createElement(Box, { padding: 3, style: { borderRadius: "4px", marginBottom: "10px" } }, /* @__PURE__ */ React2.createElement(Text2, { size: 1, style: { color: error ? "red" : "green" } }, status)), /* @__PURE__ */ React2.createElement(Button, { mode: "ghost", tone: "primary", width: "fill", padding: 3, onClick: handleClick, disabled: !ready }, /* @__PURE__ */ React2.createElement(Stack, { space: 2 }, /* @__PURE__ */ React2.createElement(Text2, { align: "center" }, "Regenerate Subfamilies"))));
1478
545
  };
1479
546
  var regenerateSubfamilies = async ({ title, stylesObject, slug, doc_id, client, setStatus, setReady, setError }) => {
1480
547
  try {
@@ -1530,11 +597,11 @@ var groupFontsBySubfamily = (fonts) => {
1530
597
  var createSubfamiliesArray = (subfamilies) => {
1531
598
  return Object.keys(subfamilies).map((subfamilyName) => ({
1532
599
  title: subfamilyName,
1533
- _key: nanoid5(),
600
+ _key: nanoid2(),
1534
601
  _type: "object",
1535
602
  fonts: subfamilies[subfamilyName].map((font) => ({
1536
603
  _ref: font._id,
1537
- _key: nanoid5(),
604
+ _key: nanoid2(),
1538
605
  _type: "reference",
1539
606
  _weak: true
1540
607
  }))
@@ -1568,6 +635,7 @@ var updateTypefaceSubfamilies = async (doc_id, stylesObject, newSubfamiliesArray
1568
635
  };
1569
636
 
1570
637
  // src/components/BatchUploadFonts.jsx
638
+ var UploadModal2 = lazy(() => import("./UploadModal-NME2W53V.mjs"));
1571
639
  var ACCEPTED_EXTENSIONS = ["ttf", "otf", "woff", "woff2", "eot", "svg"];
1572
640
  var formatElapsed = (s) => {
1573
641
  const m = Math.floor(s / 60);
@@ -1585,6 +653,7 @@ var BatchUploadFonts = () => {
1585
653
  const [pendingFiles, setPendingFiles] = useState2([]);
1586
654
  const [isDragging, setIsDragging] = useState2(false);
1587
655
  const [elapsedSeconds, setElapsedSeconds] = useState2(0);
656
+ const [showUploadModal, setShowUploadModal] = useState2(false);
1588
657
  const fileInputRef = useRef(null);
1589
658
  const elapsedTimerRef = useRef(null);
1590
659
  const wakeLockRef = useRef(null);
@@ -1877,17 +946,17 @@ var BatchUploadFonts = () => {
1877
946
  setError(false);
1878
947
  setStatus("ready");
1879
948
  };
1880
- const renderTooltipLabel = (label, description) => /* @__PURE__ */ React4.createElement(
949
+ const renderTooltipLabel = (label, description) => /* @__PURE__ */ React3.createElement(
1881
950
  Tooltip,
1882
951
  {
1883
- content: /* @__PURE__ */ React4.createElement(Box2, { padding: 2, style: { maxWidth: 260 } }, /* @__PURE__ */ React4.createElement(Text4, { size: 1, style: { lineHeight: 1.6 } }, description)),
952
+ content: /* @__PURE__ */ React3.createElement(Box2, { padding: 2, style: { maxWidth: 260 } }, /* @__PURE__ */ React3.createElement(Text3, { size: 1, style: { lineHeight: 1.6 } }, description)),
1884
953
  placement: "top",
1885
954
  portal: true
1886
955
  },
1887
- /* @__PURE__ */ React4.createElement(Flex3, { align: "center", gap: 1, style: { cursor: "default" } }, /* @__PURE__ */ React4.createElement(Label, null, label), /* @__PURE__ */ React4.createElement(InfoOutlineIcon, { style: { opacity: 0.5, display: "block" } }))
956
+ /* @__PURE__ */ React3.createElement(Flex2, { align: "center", gap: 1, style: { cursor: "default" } }, /* @__PURE__ */ React3.createElement(Label, null, label), /* @__PURE__ */ React3.createElement(InfoOutlineIcon, { style: { opacity: 0.5, display: "block" } }))
1888
957
  );
1889
- const renderProcessing = () => /* @__PURE__ */ React4.createElement(Stack2, { space: 3, paddingY: 2 }, /* @__PURE__ */ React4.createElement(Flex3, { align: "center", gap: 3 }, /* @__PURE__ */ React4.createElement(Spinner, null), /* @__PURE__ */ React4.createElement(Text4, { size: 1, muted: true }, status)), /* @__PURE__ */ React4.createElement(Card, { tone: "caution", border: true, radius: 2, padding: 2 }, /* @__PURE__ */ React4.createElement(Flex3, { align: "center", justify: "space-between", gap: 2 }, /* @__PURE__ */ React4.createElement(Flex3, { align: "center", gap: 2 }, /* @__PURE__ */ React4.createElement(WarningOutlineIcon, { style: { flexShrink: 0 } }), /* @__PURE__ */ React4.createElement(Text4, { size: 1, weight: "semibold" }, "Do not close or reload this tab")), /* @__PURE__ */ React4.createElement(Text4, { size: 1, muted: true, style: { flexShrink: 0 } }, formatElapsed(elapsedSeconds)))));
1890
- const renderDropZone = () => /* @__PURE__ */ React4.createElement(
958
+ const renderProcessing = () => /* @__PURE__ */ React3.createElement(Stack2, { space: 3, paddingY: 2 }, /* @__PURE__ */ React3.createElement(Flex2, { align: "center", gap: 3 }, /* @__PURE__ */ React3.createElement(Spinner, null), /* @__PURE__ */ React3.createElement(Text3, { size: 1, muted: true }, status)), /* @__PURE__ */ React3.createElement(Card, { tone: "caution", border: true, radius: 2, padding: 2 }, /* @__PURE__ */ React3.createElement(Flex2, { align: "center", justify: "space-between", gap: 2 }, /* @__PURE__ */ React3.createElement(Flex2, { align: "center", gap: 2 }, /* @__PURE__ */ React3.createElement(WarningOutlineIcon, { style: { flexShrink: 0 } }), /* @__PURE__ */ React3.createElement(Text3, { size: 1, weight: "semibold" }, "Do not close or reload this tab")), /* @__PURE__ */ React3.createElement(Text3, { size: 1, muted: true, style: { flexShrink: 0 } }, formatElapsed(elapsedSeconds)))));
959
+ const renderDropZone = () => /* @__PURE__ */ React3.createElement(
1891
960
  Box2,
1892
961
  {
1893
962
  onDragEnter: handleDragEnter,
@@ -1904,7 +973,7 @@ var BatchUploadFonts = () => {
1904
973
  cursor: "default"
1905
974
  }
1906
975
  },
1907
- /* @__PURE__ */ React4.createElement(
976
+ /* @__PURE__ */ React3.createElement(
1908
977
  "input",
1909
978
  {
1910
979
  ref: fileInputRef,
@@ -1915,7 +984,7 @@ var BatchUploadFonts = () => {
1915
984
  onChange: handleFileSelect
1916
985
  }
1917
986
  ),
1918
- /* @__PURE__ */ React4.createElement(Stack2, { space: 3 }, /* @__PURE__ */ React4.createElement(Text4, { size: 1, muted: true }, isDragging ? "Release to add files" : "Drop font files here"), /* @__PURE__ */ React4.createElement(Flex3, { justify: "center" }, /* @__PURE__ */ React4.createElement(
987
+ /* @__PURE__ */ React3.createElement(Stack2, { space: 3 }, /* @__PURE__ */ React3.createElement(Text3, { size: 1, muted: true }, isDragging ? "Release to add files" : "Drop font files here"), /* @__PURE__ */ React3.createElement(Flex2, { justify: "center" }, /* @__PURE__ */ React3.createElement(
1919
988
  Button2,
1920
989
  {
1921
990
  mode: "ghost",
@@ -1932,7 +1001,7 @@ var BatchUploadFonts = () => {
1932
1001
  );
1933
1002
  const renderFileList = () => {
1934
1003
  const sorted = sortFilesByType(pendingFiles);
1935
- return /* @__PURE__ */ React4.createElement(Stack2, { space: 2 }, /* @__PURE__ */ React4.createElement(Flex3, { align: "center", justify: "space-between" }, /* @__PURE__ */ React4.createElement(Text4, { size: 1, muted: true }, pendingFiles.length, " file", pendingFiles.length === 1 ? "" : "s", " selected"), /* @__PURE__ */ React4.createElement(
1004
+ return /* @__PURE__ */ React3.createElement(Stack2, { space: 2 }, /* @__PURE__ */ React3.createElement(Flex2, { align: "center", justify: "space-between" }, /* @__PURE__ */ React3.createElement(Text3, { size: 1, muted: true }, pendingFiles.length, " file", pendingFiles.length === 1 ? "" : "s", " selected"), /* @__PURE__ */ React3.createElement(
1936
1005
  Button2,
1937
1006
  {
1938
1007
  mode: "bleed",
@@ -1942,16 +1011,16 @@ var BatchUploadFonts = () => {
1942
1011
  text: "Clear all",
1943
1012
  onClick: () => setPendingFiles([])
1944
1013
  }
1945
- )), /* @__PURE__ */ React4.createElement(Box2, { style: { maxHeight: "260px", overflowY: "auto", display: "flex", flexDirection: "column", gap: "4px" } }, sorted.map((file, i) => {
1014
+ )), /* @__PURE__ */ React3.createElement(Box2, { style: { maxHeight: "260px", overflowY: "auto", display: "flex", flexDirection: "column", gap: "4px" } }, sorted.map((file, i) => {
1946
1015
  const ext = file.name.split(".").pop().toUpperCase();
1947
- return /* @__PURE__ */ React4.createElement(Card, { key: `${file.name}-${file.size}-${i}`, border: true, radius: 1, paddingX: 2, paddingY: 2 }, /* @__PURE__ */ React4.createElement(Flex3, { justify: "space-between", align: "center", gap: 2 }, /* @__PURE__ */ React4.createElement(Flex3, { gap: 3, align: "center", style: { flex: 1, minWidth: 0 } }, /* @__PURE__ */ React4.createElement(
1948
- Text4,
1016
+ return /* @__PURE__ */ React3.createElement(Card, { key: `${file.name}-${file.size}-${i}`, border: true, radius: 1, paddingX: 2, paddingY: 2 }, /* @__PURE__ */ React3.createElement(Flex2, { justify: "space-between", align: "center", gap: 2 }, /* @__PURE__ */ React3.createElement(Flex2, { gap: 3, align: "center", style: { flex: 1, minWidth: 0 } }, /* @__PURE__ */ React3.createElement(
1017
+ Text3,
1949
1018
  {
1950
1019
  size: 0,
1951
1020
  style: { fontFamily: "monospace", minWidth: "2.5rem", flexShrink: 0 }
1952
1021
  },
1953
1022
  ext
1954
- ), /* @__PURE__ */ React4.createElement(Box2, { style: { flex: 1, minWidth: 0, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" } }, /* @__PURE__ */ React4.createElement(Text4, { size: 1 }, file.name))), /* @__PURE__ */ React4.createElement(
1023
+ ), /* @__PURE__ */ React3.createElement(Box2, { style: { flex: 1, minWidth: 0, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" } }, /* @__PURE__ */ React3.createElement(Text3, { size: 1 }, file.name))), /* @__PURE__ */ React3.createElement(
1955
1024
  Button2,
1956
1025
  {
1957
1026
  mode: "bleed",
@@ -1961,7 +1030,7 @@ var BatchUploadFonts = () => {
1961
1030
  onClick: () => handleRemoveFile(file)
1962
1031
  }
1963
1032
  )));
1964
- })), /* @__PURE__ */ React4.createElement(
1033
+ })), /* @__PURE__ */ React3.createElement(
1965
1034
  Box2,
1966
1035
  {
1967
1036
  onDragEnter: handleDragEnter,
@@ -1977,7 +1046,7 @@ var BatchUploadFonts = () => {
1977
1046
  transition: "border-color 0.12s, background 0.12s"
1978
1047
  }
1979
1048
  },
1980
- /* @__PURE__ */ React4.createElement(
1049
+ /* @__PURE__ */ React3.createElement(
1981
1050
  "input",
1982
1051
  {
1983
1052
  ref: fileInputRef,
@@ -1988,7 +1057,7 @@ var BatchUploadFonts = () => {
1988
1057
  onChange: handleFileSelect
1989
1058
  }
1990
1059
  ),
1991
- /* @__PURE__ */ React4.createElement(Flex3, { align: "center", justify: "center", gap: 2 }, /* @__PURE__ */ React4.createElement(Text4, { size: 1, muted: true }, isDragging ? "Release to add" : "Drop more files or"), /* @__PURE__ */ React4.createElement(
1060
+ /* @__PURE__ */ React3.createElement(Flex2, { align: "center", justify: "center", gap: 2 }, /* @__PURE__ */ React3.createElement(Text3, { size: 1, muted: true }, isDragging ? "Release to add" : "Drop more files or"), /* @__PURE__ */ React3.createElement(
1992
1061
  Button2,
1993
1062
  {
1994
1063
  mode: "bleed",
@@ -2002,7 +1071,7 @@ var BatchUploadFonts = () => {
2002
1071
  }
2003
1072
  }
2004
1073
  ))
2005
- ), /* @__PURE__ */ React4.createElement(
1074
+ ), /* @__PURE__ */ React3.createElement(
2006
1075
  Button2,
2007
1076
  {
2008
1077
  mode: "ghost",
@@ -2014,12 +1083,13 @@ var BatchUploadFonts = () => {
2014
1083
  }
2015
1084
  ));
2016
1085
  };
2017
- return /* @__PURE__ */ React4.createElement(React4.Fragment, null, title && title !== "" && slug && slug !== "" && /* @__PURE__ */ React4.createElement(React4.Fragment, null, /* @__PURE__ */ React4.createElement(
1086
+ const hasRequiredFields = title && title !== "" && slug && slug !== "";
1087
+ return /* @__PURE__ */ React3.createElement(React3.Fragment, null, !hasRequiredFields && /* @__PURE__ */ React3.createElement(Card, { border: true, padding: 4, radius: 2, tone: "caution" }, /* @__PURE__ */ React3.createElement(Flex2, { align: "center", gap: 3 }, /* @__PURE__ */ React3.createElement(Text3, { size: 2 }, /* @__PURE__ */ React3.createElement(WarningOutlineIcon, null)), /* @__PURE__ */ React3.createElement(Stack2, { space: 2 }, /* @__PURE__ */ React3.createElement(Text3, { size: 1, weight: "semibold" }, !title || title === "" ? "Title required to use font uploader" : "Slug required to use font uploader"), /* @__PURE__ */ React3.createElement(Text3, { size: 1, muted: true }, "Add a ", !title || title === "" ? "title" : "slug", " to this typeface document, then return to the Styles tab to upload fonts.")))), hasRequiredFields && /* @__PURE__ */ React3.createElement(React3.Fragment, null, /* @__PURE__ */ React3.createElement(
2018
1088
  StatusDisplay_default,
2019
1089
  {
2020
1090
  status,
2021
1091
  error,
2022
- action: /* @__PURE__ */ React4.createElement(
1092
+ action: /* @__PURE__ */ React3.createElement(
2023
1093
  Button2,
2024
1094
  {
2025
1095
  mode: showUtilities ? "default" : "ghost",
@@ -2032,16 +1102,31 @@ var BatchUploadFonts = () => {
2032
1102
  }
2033
1103
  )
2034
1104
  }
2035
- ), /* @__PURE__ */ React4.createElement(Card, { border: true, padding: 2, shadow: 1, radius: 2 }, showUtilities ? /* @__PURE__ */ React4.createElement(Stack2, { space: 4, marginTop: 2 }, /* @__PURE__ */ React4.createElement(Stack2, { space: 2 }, /* @__PURE__ */ React4.createElement(Text4, { size: 1, weight: "semibold", style: { lineHeight: 1.6 } }, "Regenerate Subfamilies"), /* @__PURE__ */ React4.createElement(RegenerateSubfamiliesComponent, null)), /* @__PURE__ */ React4.createElement(Stack2, { space: 3 }, /* @__PURE__ */ React4.createElement(Text4, { size: 1, weight: "semibold", style: { lineHeight: 1.6 } }, "Rename Fonts (name table, Full Name)"), /* @__PURE__ */ React4.createElement(Flex3, { align: "center", gap: 2 }, /* @__PURE__ */ React4.createElement(
2036
- Switch,
1105
+ ), /* @__PURE__ */ React3.createElement(
1106
+ Button2,
2037
1107
  {
2038
- checked: preserveShortenedNames,
2039
- onChange: (e) => setPreserveShortenedNames(e.target.checked)
1108
+ mode: "default",
1109
+ tone: "primary",
1110
+ icon: UploadIcon,
1111
+ text: "Upload Fonts",
1112
+ fontSize: 2,
1113
+ padding: 4,
1114
+ onClick: () => setShowUploadModal(true),
1115
+ style: { width: "100%" }
2040
1116
  }
2041
- ), renderTooltipLabel(
2042
- "Preserve shortened names",
2043
- 'Abbreviations in font names are kept as-is (e.g. "XNarrow" stays "XNarrow", "Bd" stays "Bd").'
2044
- )), ready === "rename" ? renderProcessing() : /* @__PURE__ */ React4.createElement(Button2, { mode: "ghost", tone: "primary", text: "Rename Existing Fonts", style: { width: "100%" }, onClick: handleRenameExistingFonts, disabled: ready !== true })), /* @__PURE__ */ React4.createElement(Stack2, { space: 3 }, /* @__PURE__ */ React4.createElement(Text4, { size: 1, weight: "semibold", style: { lineHeight: 1.6 } }, "Update Font Prices"), ready === "price" ? renderProcessing() : /* @__PURE__ */ React4.createElement(Stack2, { space: 2 }, /* @__PURE__ */ React4.createElement(PriceInput_default, { inputPrice, handleInputChange }), /* @__PURE__ */ React4.createElement(Button2, { mode: "ghost", tone: "primary", text: "Update All Font Prices", style: { width: "100%" }, onClick: handleChangeFontPrice, disabled: ready !== true }))), /* @__PURE__ */ React4.createElement(Stack2, { space: 3 }, /* @__PURE__ */ React4.createElement(Text4, { size: 1, weight: "semibold", style: { lineHeight: 1.6 } }, "Regenerate CSS"), /* @__PURE__ */ React4.createElement(Text4, { size: 1, muted: true, style: { lineHeight: 1.6 } }, "Rebuilds the CSS @font-face files for all fonts in the typeface fonts list."), ready === "css" ? renderProcessing() : /* @__PURE__ */ React4.createElement(Button2, { mode: "ghost", tone: "primary", text: "Regenerate CSS Files", style: { width: "100%" }, onClick: handleRegenerateCssFiles, disabled: ready !== true }))) : ready ? /* @__PURE__ */ React4.createElement(React4.Fragment, null, /* @__PURE__ */ React4.createElement(Grid, { columns: [2], gap: 4, marginTop: 1, marginBottom: 1 }, /* @__PURE__ */ React4.createElement(Box2, null, /* @__PURE__ */ React4.createElement(PriceInput_default, { inputPrice, handleInputChange })), /* @__PURE__ */ React4.createElement(Stack2, { space: 3 }, /* @__PURE__ */ React4.createElement(Flex3, { align: "center", gap: 2 }, /* @__PURE__ */ React4.createElement(
1117
+ ), showUploadModal && /* @__PURE__ */ React3.createElement(Suspense, { fallback: /* @__PURE__ */ React3.createElement(Spinner, null) }, /* @__PURE__ */ React3.createElement(
1118
+ UploadModal2,
1119
+ {
1120
+ open: showUploadModal,
1121
+ onClose: () => setShowUploadModal(false),
1122
+ client,
1123
+ docId: doc_id,
1124
+ typefaceTitle: title,
1125
+ stylesObject,
1126
+ preferredStyleRef,
1127
+ slug
1128
+ }
1129
+ )), showUtilities && /* @__PURE__ */ React3.createElement(Card, { border: true, padding: 3, shadow: 1, radius: 2, marginTop: 3 }, /* @__PURE__ */ React3.createElement(Stack2, { space: 4 }, /* @__PURE__ */ React3.createElement(Stack2, { space: 2 }, /* @__PURE__ */ React3.createElement(Text3, { size: 1, weight: "semibold", style: { lineHeight: 1.6 } }, "Regenerate Subfamilies"), /* @__PURE__ */ React3.createElement(RegenerateSubfamiliesComponent, null)), /* @__PURE__ */ React3.createElement(Stack2, { space: 3 }, /* @__PURE__ */ React3.createElement(Text3, { size: 1, weight: "semibold", style: { lineHeight: 1.6 } }, "Rename Fonts (name table, Full Name)"), /* @__PURE__ */ React3.createElement(Flex2, { align: "center", gap: 2 }, /* @__PURE__ */ React3.createElement(
2045
1130
  Switch,
2046
1131
  {
2047
1132
  checked: preserveShortenedNames,
@@ -2050,24 +1135,15 @@ var BatchUploadFonts = () => {
2050
1135
  ), renderTooltipLabel(
2051
1136
  "Preserve shortened names",
2052
1137
  'Abbreviations in font names are kept as-is (e.g. "XNarrow" stays "XNarrow", "Bd" stays "Bd").'
2053
- )), /* @__PURE__ */ React4.createElement(Flex3, { align: "center", gap: 2 }, /* @__PURE__ */ React4.createElement(
2054
- Switch,
2055
- {
2056
- checked: preserveFileNames,
2057
- onChange: (e) => setPreserveFileNames(e.target.checked)
2058
- }
2059
- ), renderTooltipLabel(
2060
- "Preserve file names",
2061
- "Original filename capitalisation is used for asset naming instead of the normalised font title."
2062
- )))), /* @__PURE__ */ React4.createElement(Box2, { marginTop: 3 }, pendingFiles.length === 0 ? renderDropZone() : renderFileList())) : renderProcessing())));
1138
+ )), ready === "rename" ? renderProcessing() : /* @__PURE__ */ React3.createElement(Button2, { mode: "ghost", tone: "primary", text: "Rename Existing Fonts", style: { width: "100%" }, onClick: handleRenameExistingFonts, disabled: ready !== true })), /* @__PURE__ */ React3.createElement(Stack2, { space: 3 }, /* @__PURE__ */ React3.createElement(Text3, { size: 1, weight: "semibold", style: { lineHeight: 1.6 } }, "Update Font Prices"), ready === "price" ? renderProcessing() : /* @__PURE__ */ React3.createElement(Stack2, { space: 2 }, /* @__PURE__ */ React3.createElement(PriceInput_default, { inputPrice, handleInputChange }), /* @__PURE__ */ React3.createElement(Button2, { mode: "ghost", tone: "primary", text: "Update All Font Prices", style: { width: "100%" }, onClick: handleChangeFontPrice, disabled: ready !== true }))), /* @__PURE__ */ React3.createElement(Stack2, { space: 3 }, /* @__PURE__ */ React3.createElement(Text3, { size: 1, weight: "semibold", style: { lineHeight: 1.6 } }, "Regenerate CSS"), /* @__PURE__ */ React3.createElement(Text3, { size: 1, muted: true, style: { lineHeight: 1.6 } }, "Rebuilds the CSS @font-face files for all fonts in the typeface fonts list."), ready === "css" ? renderProcessing() : /* @__PURE__ */ React3.createElement(Button2, { mode: "ghost", tone: "primary", text: "Regenerate CSS Files", style: { width: "100%" }, onClick: handleRegenerateCssFiles, disabled: ready !== true }))))));
2063
1139
  };
2064
1140
 
2065
1141
  // src/components/GenerateCollectionsPairsComponent.jsx
2066
- import React5, { useCallback as useCallback2, useState as useState3 } from "react";
2067
- import { Stack as Stack3, Grid as Grid2, Flex as Flex4, Text as Text5, Button as Button3, Card as Card2, Spinner as Spinner2 } from "@sanity/ui";
1142
+ import React4, { useCallback as useCallback2, useState as useState3 } from "react";
1143
+ import { Stack as Stack3, Grid as Grid2, Flex as Flex3, Text as Text4, Button as Button3, Card as Card2, Spinner as Spinner2 } from "@sanity/ui";
2068
1144
  import { useFormValue as useFormValue3 } from "sanity";
2069
- import slugify2 from "slugify";
2070
- import { nanoid as nanoid6 } from "nanoid";
1145
+ import slugify from "slugify";
1146
+ import { nanoid as nanoid3 } from "nanoid";
2071
1147
  var GenerateCollectionsPairsComponent = () => {
2072
1148
  const [status, setStatus] = useState3("ready");
2073
1149
  const [ready, setReady] = useState3(true);
@@ -2085,7 +1161,7 @@ var GenerateCollectionsPairsComponent = () => {
2085
1161
  const createSanityCollection = useCallback2(async (fontsList, collectionSlug, newTitle) => {
2086
1162
  const newSlug = collectionSlug.toLowerCase().trim();
2087
1163
  const fontRefs = fontsList.map((font) => ({
2088
- _key: nanoid6(),
1164
+ _key: nanoid3(),
2089
1165
  _type: "reference",
2090
1166
  _ref: font._id ?? font._ref,
2091
1167
  _weak: true
@@ -2101,7 +1177,7 @@ var GenerateCollectionsPairsComponent = () => {
2101
1177
  });
2102
1178
  const price = (collectionPrice ? Number(collectionPrice) : 0) * fontRefs.length;
2103
1179
  await client.createOrReplace({
2104
- _key: nanoid6(),
1180
+ _key: nanoid3(),
2105
1181
  _id: newSlug,
2106
1182
  _type: "collection",
2107
1183
  state: "active",
@@ -2114,18 +1190,18 @@ var GenerateCollectionsPairsComponent = () => {
2114
1190
  }).catch((err) => {
2115
1191
  console.error("Error creating collection:", err.message);
2116
1192
  });
2117
- return { _ref: newSlug, _type: "reference", _weak: true, _key: nanoid6() };
1193
+ return { _ref: newSlug, _type: "reference", _weak: true, _key: nanoid3() };
2118
1194
  }, [collectionPrice, client]);
2119
1195
  const createSanityPair = useCallback2(async (pair, pairSlug, newTitle) => {
2120
1196
  const newSlug = pairSlug.toLowerCase().trim();
2121
1197
  const fontRefs = pair.map((font) => ({
2122
- _key: nanoid6(),
1198
+ _key: nanoid3(),
2123
1199
  _type: "reference",
2124
1200
  _ref: font._id,
2125
1201
  _weak: true
2126
1202
  }));
2127
1203
  await client.createOrReplace({
2128
- _key: nanoid6(),
1204
+ _key: nanoid3(),
2129
1205
  _id: newSlug,
2130
1206
  _type: "pair",
2131
1207
  preferredStyle: { _type: "reference", _ref: fontRefs[0]._ref, _weak: true },
@@ -2136,7 +1212,7 @@ var GenerateCollectionsPairsComponent = () => {
2136
1212
  }).catch((err) => {
2137
1213
  console.error("Error creating pair:", err.message);
2138
1214
  });
2139
- return { _ref: newSlug, _type: "reference", _weak: true, _key: nanoid6() };
1215
+ return { _ref: newSlug, _type: "reference", _weak: true, _key: nanoid3() };
2140
1216
  }, [pairPrice, client]);
2141
1217
  const handleGenerateCollections = useCallback2(async () => {
2142
1218
  setStatus("Generating collections...");
@@ -2174,7 +1250,7 @@ var GenerateCollectionsPairsComponent = () => {
2174
1250
  setStatus(`[${i + 4}/${totalCollections}] Generating ${subfamilies[i].title} collection`);
2175
1251
  const ref = await createSanityCollection(
2176
1252
  subfamilies[i].fonts,
2177
- `${slug.current}-${slugify2(subfamilies[i].title)}-family`,
1253
+ `${slug.current}-${slugify(subfamilies[i].title)}-family`,
2178
1254
  `${title} ${subfamilies[i].title} Family`
2179
1255
  );
2180
1256
  if (ref) typefacePatch.push(ref);
@@ -2216,14 +1292,14 @@ var GenerateCollectionsPairsComponent = () => {
2216
1292
  let pairSlug, pairTitle;
2217
1293
  if (reg.subfamily && reg.subfamily !== "") {
2218
1294
  if (reg.subfamily === "Regular") {
2219
- pairSlug = `${slug.current}-${slugify2(reg.weightName)}s`;
1295
+ pairSlug = `${slug.current}-${slugify(reg.weightName)}s`;
2220
1296
  pairTitle = `${title} ${reg.weightName}s`;
2221
1297
  } else {
2222
- pairSlug = `${slug.current}-${slugify2(reg.subfamily)}-${slugify2(reg.weightName)}s`;
1298
+ pairSlug = `${slug.current}-${slugify(reg.subfamily)}-${slugify(reg.weightName)}s`;
2223
1299
  pairTitle = `${title} ${reg.subfamily} ${reg.weightName}s`;
2224
1300
  }
2225
1301
  } else {
2226
- pairSlug = `${slug.current}-${slugify2(reg.weightName)}s`;
1302
+ pairSlug = `${slug.current}-${slugify(reg.weightName)}s`;
2227
1303
  pairTitle = `${title} ${reg.weightName}s`;
2228
1304
  }
2229
1305
  setStatus(`[${i + 1}/${pairs.length}] Generating ${pairTitle}`);
@@ -2243,7 +1319,7 @@ var GenerateCollectionsPairsComponent = () => {
2243
1319
  setReady(true);
2244
1320
  }, [doc_id, title, slug, stylesObject, pairPrice, client, createSanityPair]);
2245
1321
  if (!title || !slug) return null;
2246
- return /* @__PURE__ */ React5.createElement(Stack3, { space: 2 }, /* @__PURE__ */ React5.createElement(StatusDisplay_default, { status, error: false }), /* @__PURE__ */ React5.createElement(Card2, { border: true, padding: 2, shadow: 1, radius: 2 }, ready ? /* @__PURE__ */ React5.createElement(Stack3, { space: 3 }, /* @__PURE__ */ React5.createElement(Grid2, { columns: [2], gap: 4, marginTop: 1, marginBottom: 1 }, /* @__PURE__ */ React5.createElement(Stack3, { space: 2 }, /* @__PURE__ */ React5.createElement(Text5, { size: 1, muted: true }, "Collection price / font"), /* @__PURE__ */ React5.createElement(Flex4, { align: "center", gap: 2 }, /* @__PURE__ */ React5.createElement(Text5, { size: 1, muted: true }, "$"), /* @__PURE__ */ React5.createElement(
1322
+ return /* @__PURE__ */ React4.createElement(Stack3, { space: 2 }, /* @__PURE__ */ React4.createElement(StatusDisplay_default, { status, error: false }), /* @__PURE__ */ React4.createElement(Card2, { border: true, padding: 2, shadow: 1, radius: 2 }, ready ? /* @__PURE__ */ React4.createElement(Stack3, { space: 3 }, /* @__PURE__ */ React4.createElement(Grid2, { columns: [2], gap: 4, marginTop: 1, marginBottom: 1 }, /* @__PURE__ */ React4.createElement(Stack3, { space: 2 }, /* @__PURE__ */ React4.createElement(Text4, { size: 1, muted: true }, "Collection price / font"), /* @__PURE__ */ React4.createElement(Flex3, { align: "center", gap: 2 }, /* @__PURE__ */ React4.createElement(Text4, { size: 1, muted: true }, "$"), /* @__PURE__ */ React4.createElement(
2247
1323
  "input",
2248
1324
  {
2249
1325
  value: collectionPrice,
@@ -2251,7 +1327,7 @@ var GenerateCollectionsPairsComponent = () => {
2251
1327
  type: "number",
2252
1328
  style: { textAlign: "end", padding: "5px", maxWidth: "75px" }
2253
1329
  }
2254
- ))), /* @__PURE__ */ React5.createElement(Stack3, { space: 2 }, /* @__PURE__ */ React5.createElement(Text5, { size: 1, muted: true }, "Pair price"), /* @__PURE__ */ React5.createElement(Flex4, { align: "center", gap: 2 }, /* @__PURE__ */ React5.createElement(Text5, { size: 1, muted: true }, "$"), /* @__PURE__ */ React5.createElement(
1330
+ ))), /* @__PURE__ */ React4.createElement(Stack3, { space: 2 }, /* @__PURE__ */ React4.createElement(Text4, { size: 1, muted: true }, "Pair price"), /* @__PURE__ */ React4.createElement(Flex3, { align: "center", gap: 2 }, /* @__PURE__ */ React4.createElement(Text4, { size: 1, muted: true }, "$"), /* @__PURE__ */ React4.createElement(
2255
1331
  "input",
2256
1332
  {
2257
1333
  value: pairPrice,
@@ -2259,12 +1335,12 @@ var GenerateCollectionsPairsComponent = () => {
2259
1335
  type: "number",
2260
1336
  style: { textAlign: "end", padding: "5px", maxWidth: "75px" }
2261
1337
  }
2262
- )))), /* @__PURE__ */ React5.createElement(Button3, { mode: "ghost", tone: "primary", text: "Generate Collections", style: { width: "100%" }, onClick: handleGenerateCollections }), /* @__PURE__ */ React5.createElement(Button3, { mode: "ghost", tone: "primary", text: "Generate Pairs", style: { width: "100%" }, onClick: handleGeneratePairs })) : /* @__PURE__ */ React5.createElement(Flex4, { align: "center", justify: "center", gap: 3, padding: 4 }, /* @__PURE__ */ React5.createElement(Spinner2, null), /* @__PURE__ */ React5.createElement(Text5, { muted: true, size: 1 }, status))));
1338
+ )))), /* @__PURE__ */ React4.createElement(Button3, { mode: "ghost", tone: "primary", text: "Generate Collections", style: { width: "100%" }, onClick: handleGenerateCollections }), /* @__PURE__ */ React4.createElement(Button3, { mode: "ghost", tone: "primary", text: "Generate Pairs", style: { width: "100%" }, onClick: handleGeneratePairs })) : /* @__PURE__ */ React4.createElement(Flex3, { align: "center", justify: "center", gap: 3, padding: 4 }, /* @__PURE__ */ React4.createElement(Spinner2, null), /* @__PURE__ */ React4.createElement(Text4, { muted: true, size: 1 }, status))));
2263
1339
  };
2264
1340
 
2265
1341
  // src/components/UpdateScriptsComponent.jsx
2266
- import React6, { useState as useState4, useCallback as useCallback3, useRef as useRef2, useEffect as useEffect2 } from "react";
2267
- import { Stack as Stack4, Text as Text6, Button as Button4 } from "@sanity/ui";
1342
+ import React5, { useState as useState4, useCallback as useCallback3, useRef as useRef2, useEffect as useEffect2 } from "react";
1343
+ import { Stack as Stack4, Text as Text5, Button as Button4 } from "@sanity/ui";
2268
1344
  import { useFormValue as useFormValue4, set } from "sanity";
2269
1345
  var UpdateScriptsComponent = (props) => {
2270
1346
  const { onChange } = props;
@@ -2306,7 +1382,7 @@ var UpdateScriptsComponent = (props) => {
2306
1382
  if (isReadyRef.current) onChange(set(newScripts));
2307
1383
  setMessage("Scripts updated");
2308
1384
  }, [onChange, fonts, client]);
2309
- return /* @__PURE__ */ React6.createElement(Stack4, { space: 3 }, /* @__PURE__ */ React6.createElement(
1385
+ return /* @__PURE__ */ React5.createElement(Stack4, { space: 3 }, /* @__PURE__ */ React5.createElement(
2310
1386
  Button4,
2311
1387
  {
2312
1388
  mode: "ghost",
@@ -2315,16 +1391,14 @@ var UpdateScriptsComponent = (props) => {
2315
1391
  text: "Update Scripts from Font Files",
2316
1392
  onClick: updateFromFonts
2317
1393
  }
2318
- ), message && /* @__PURE__ */ React6.createElement(Text6, { size: 1, style: { color: "green" } }, message), props.renderDefault(props));
1394
+ ), message && /* @__PURE__ */ React5.createElement(Text5, { size: 1, style: { color: "green" } }, message), props.renderDefault(props));
2319
1395
  };
2320
1396
 
2321
1397
  // src/components/SingleUploaderTool.jsx
2322
- import React7, { useState as useState5, useEffect as useEffect3, useCallback as useCallback4, useMemo as useMemo3 } from "react";
2323
- import { Button as Button5, Grid as Grid3, Stack as Stack5, Flex as Flex5, Box as Box3, Text as Text7, Card as Card3 } from "@sanity/ui";
1398
+ import React6, { useState as useState5, useEffect as useEffect3, useCallback as useCallback4, useMemo as useMemo3 } from "react";
1399
+ import { Button as Button5, Grid as Grid3, Stack as Stack5, Flex as Flex4, Box as Box3, Text as Text6, Card as Card3 } from "@sanity/ui";
2324
1400
  import { TrashIcon as TrashIcon2, ControlsIcon as ControlsIcon2 } from "@sanity/icons";
2325
1401
  import { useFormValue as useFormValue5, set as set2, unset } from "sanity";
2326
- import { Buffer as Buffer3 } from "buffer";
2327
- import * as fontkit5 from "fontkit";
2328
1402
 
2329
1403
  // src/utils/generateFontFile.js
2330
1404
  async function generateFontFile({
@@ -2558,7 +1632,7 @@ var SingleUploaderTool = (props) => {
2558
1632
  );
2559
1633
  if (!(ttfAsset == null ? void 0 : ttfAsset.url)) throw new Error("Could not fetch TTF file URL");
2560
1634
  const arrayBuffer = await (await fetch(ttfAsset.url)).arrayBuffer();
2561
- const font = fontkit5.create(Buffer3.from(arrayBuffer));
1635
+ const font = await parseFont(arrayBuffer, `${doc_id}.ttf`);
2562
1636
  const { weightName, subfamilyName, style, variableFont } = extractFontMetadata(
2563
1637
  font,
2564
1638
  doc_typefaceName,
@@ -2715,7 +1789,7 @@ var SingleUploaderTool = (props) => {
2715
1789
  }
2716
1790
  if (code === "ttf") {
2717
1791
  const fontBuffer = await readFontFile(file);
2718
- const font = fontkit5.create(fontBuffer);
1792
+ const font = await parseFont(fontBuffer, file.name);
2719
1793
  const { weightName, subfamilyName, style, variableFont } = extractFontMetadata(
2720
1794
  font,
2721
1795
  doc_typefaceName,
@@ -2863,26 +1937,26 @@ var SingleUploaderTool = (props) => {
2863
1937
  const formatUpper = format.toUpperCase();
2864
1938
  const hasFile = !!((_b2 = (_a2 = fileInput == null ? void 0 : fileInput[format]) == null ? void 0 : _a2.asset) == null ? void 0 : _b2._ref);
2865
1939
  const fileUrl = hasFile ? `https://cdn.sanity.io/files/${process.env.SANITY_STUDIO_PROJECT_ID}/${process.env.SANITY_STUDIO_DATASET}/${fileInput[format].asset._ref.replace("file-", "").replace("-", ".")}` : null;
2866
- return /* @__PURE__ */ React7.createElement(Card3, { border: true, radius: 1, paddingX: 2, paddingY: 3 }, /* @__PURE__ */ React7.createElement(Flex5, { justify: "space-between", align: "center", gap: 2 }, /* @__PURE__ */ React7.createElement(Flex5, { gap: 3, align: "center", style: { flex: 1, minWidth: 0 } }, /* @__PURE__ */ React7.createElement(Text7, { size: 0, style: { fontFamily: "monospace", minWidth: "2.5rem", flexShrink: 0, opacity: hasFile ? 1 : 0.5 } }, formatUpper), hasFile ? /* @__PURE__ */ React7.createElement(Box3, { style: { flex: 1, minWidth: 0, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" } }, /* @__PURE__ */ React7.createElement("a", { href: fileUrl, target: "_blank", rel: "noreferrer" }, (filenames == null ? void 0 : filenames[format]) || "File")) : /* @__PURE__ */ React7.createElement(Text7, { size: 1, muted: true }, "\u2014")), status === "ready" && /* @__PURE__ */ React7.createElement(Flex5, { gap: 1, align: "center", style: { flexShrink: 0 } }, buildSource && (fileInput == null ? void 0 : fileInput[buildSource]) && /* @__PURE__ */ React7.createElement(Button5, { mode: "ghost", tone: "primary", fontSize: 1, padding: 2, onClick: () => handleGenerateFontFile(format, fileInput[buildSource]), text: "Build" }), /* @__PURE__ */ React7.createElement(Button5, { as: "label", mode: "ghost", tone: "primary", fontSize: 1, padding: 2, style: { cursor: "pointer" } }, /* @__PURE__ */ React7.createElement(Text7, { size: 1 }, "Upload"), /* @__PURE__ */ React7.createElement("input", { ref, type: "file", hidden: true, onChange: (e) => handleUpload(e, format) })), hasFile && /* @__PURE__ */ React7.createElement(Button5, { mode: "bleed", tone: "critical", icon: TrashIcon2, padding: 2, onClick: () => handleDelete(format) }))));
1940
+ return /* @__PURE__ */ React6.createElement(Card3, { border: true, radius: 1, paddingX: 2, paddingY: 3 }, /* @__PURE__ */ React6.createElement(Flex4, { justify: "space-between", align: "center", gap: 2 }, /* @__PURE__ */ React6.createElement(Flex4, { gap: 3, align: "center", style: { flex: 1, minWidth: 0 } }, /* @__PURE__ */ React6.createElement(Text6, { size: 0, style: { fontFamily: "monospace", minWidth: "2.5rem", flexShrink: 0, opacity: hasFile ? 1 : 0.5 } }, formatUpper), hasFile ? /* @__PURE__ */ React6.createElement(Box3, { style: { flex: 1, minWidth: 0, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" } }, /* @__PURE__ */ React6.createElement("a", { href: fileUrl, target: "_blank", rel: "noreferrer" }, (filenames == null ? void 0 : filenames[format]) || "File")) : /* @__PURE__ */ React6.createElement(Text6, { size: 1, muted: true }, "\u2014")), status === "ready" && /* @__PURE__ */ React6.createElement(Flex4, { gap: 1, align: "center", style: { flexShrink: 0 } }, buildSource && (fileInput == null ? void 0 : fileInput[buildSource]) && /* @__PURE__ */ React6.createElement(Button5, { mode: "ghost", tone: "primary", fontSize: 1, padding: 2, onClick: () => handleGenerateFontFile(format, fileInput[buildSource]), text: "Build" }), /* @__PURE__ */ React6.createElement(Button5, { as: "label", mode: "ghost", tone: "primary", fontSize: 1, padding: 2, style: { cursor: "pointer" } }, /* @__PURE__ */ React6.createElement(Text6, { size: 1 }, "Upload"), /* @__PURE__ */ React6.createElement("input", { ref, type: "file", hidden: true, onChange: (e) => handleUpload(e, format) })), hasFile && /* @__PURE__ */ React6.createElement(Button5, { mode: "bleed", tone: "critical", icon: TrashIcon2, padding: 2, onClick: () => handleDelete(format) }))));
2867
1941
  };
2868
1942
  const renderTopLevelAssetSection = (label, fieldName, assetRef, filename, onBuild) => {
2869
1943
  const hasFile = !!assetRef;
2870
1944
  const fileUrl = hasFile ? `https://cdn.sanity.io/files/${process.env.SANITY_STUDIO_PROJECT_ID}/${process.env.SANITY_STUDIO_DATASET}/${assetRef.replace("file-", "").replace("-", ".")}` : null;
2871
- return /* @__PURE__ */ React7.createElement(Card3, { border: true, radius: 1, paddingX: 2, paddingY: 3 }, /* @__PURE__ */ React7.createElement(Flex5, { justify: "space-between", align: "center", gap: 2 }, /* @__PURE__ */ React7.createElement(Flex5, { gap: 3, align: "center", style: { flex: 1, minWidth: 0 } }, /* @__PURE__ */ React7.createElement(Text7, { size: 0, style: { fontFamily: "monospace", minWidth: "2.5rem", flexShrink: 0, opacity: hasFile ? 1 : 0.5 } }, label), hasFile ? /* @__PURE__ */ React7.createElement(Box3, { style: { flex: 1, minWidth: 0, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" } }, /* @__PURE__ */ React7.createElement("a", { href: fileUrl, target: "_blank", rel: "noreferrer" }, filename || "File")) : /* @__PURE__ */ React7.createElement(Text7, { size: 1, muted: true }, "\u2014")), status === "ready" && /* @__PURE__ */ React7.createElement(Flex5, { gap: 1, align: "center", style: { flexShrink: 0 } }, onBuild && (fileInput == null ? void 0 : fileInput.woff2) && /* @__PURE__ */ React7.createElement(Button5, { mode: "ghost", tone: "primary", fontSize: 1, padding: 2, onClick: onBuild, text: "Build" }), /* @__PURE__ */ React7.createElement(Button5, { as: "label", mode: "ghost", tone: "primary", fontSize: 1, padding: 2, style: { cursor: "pointer" } }, /* @__PURE__ */ React7.createElement(Text7, { size: 1 }, "Upload"), /* @__PURE__ */ React7.createElement("input", { type: "file", hidden: true, onChange: (e) => handleUploadTopLevelFile(e, fieldName) })), hasFile && /* @__PURE__ */ React7.createElement(Button5, { mode: "bleed", tone: "critical", icon: TrashIcon2, padding: 2, onClick: () => handleDeleteTopLevel(fieldName) }))));
1945
+ return /* @__PURE__ */ React6.createElement(Card3, { border: true, radius: 1, paddingX: 2, paddingY: 3 }, /* @__PURE__ */ React6.createElement(Flex4, { justify: "space-between", align: "center", gap: 2 }, /* @__PURE__ */ React6.createElement(Flex4, { gap: 3, align: "center", style: { flex: 1, minWidth: 0 } }, /* @__PURE__ */ React6.createElement(Text6, { size: 0, style: { fontFamily: "monospace", minWidth: "2.5rem", flexShrink: 0, opacity: hasFile ? 1 : 0.5 } }, label), hasFile ? /* @__PURE__ */ React6.createElement(Box3, { style: { flex: 1, minWidth: 0, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" } }, /* @__PURE__ */ React6.createElement("a", { href: fileUrl, target: "_blank", rel: "noreferrer" }, filename || "File")) : /* @__PURE__ */ React6.createElement(Text6, { size: 1, muted: true }, "\u2014")), status === "ready" && /* @__PURE__ */ React6.createElement(Flex4, { gap: 1, align: "center", style: { flexShrink: 0 } }, onBuild && (fileInput == null ? void 0 : fileInput.woff2) && /* @__PURE__ */ React6.createElement(Button5, { mode: "ghost", tone: "primary", fontSize: 1, padding: 2, onClick: onBuild, text: "Build" }), /* @__PURE__ */ React6.createElement(Button5, { as: "label", mode: "ghost", tone: "primary", fontSize: 1, padding: 2, style: { cursor: "pointer" } }, /* @__PURE__ */ React6.createElement(Text6, { size: 1 }, "Upload"), /* @__PURE__ */ React6.createElement("input", { type: "file", hidden: true, onChange: (e) => handleUploadTopLevelFile(e, fieldName) })), hasFile && /* @__PURE__ */ React6.createElement(Button5, { mode: "bleed", tone: "critical", icon: TrashIcon2, padding: 2, onClick: () => handleDeleteTopLevel(fieldName) }))));
2872
1946
  };
2873
1947
  const renderCssSection = () => {
2874
1948
  var _a2, _b2;
2875
1949
  const hasFile = !!((_b2 = (_a2 = fileInput == null ? void 0 : fileInput.css) == null ? void 0 : _a2.asset) == null ? void 0 : _b2._ref);
2876
1950
  const fileUrl = hasFile ? `https://cdn.sanity.io/files/${process.env.SANITY_STUDIO_PROJECT_ID}/${process.env.SANITY_STUDIO_DATASET}/${fileInput.css.asset._ref.replace("file-", "").replace("-", ".")}` : null;
2877
- return /* @__PURE__ */ React7.createElement(Card3, { border: true, radius: 1, paddingX: 2, paddingY: 3 }, /* @__PURE__ */ React7.createElement(Flex5, { justify: "space-between", align: "center", gap: 2 }, /* @__PURE__ */ React7.createElement(Flex5, { gap: 3, align: "center", style: { flex: 1, minWidth: 0 } }, /* @__PURE__ */ React7.createElement(Text7, { size: 0, style: { fontFamily: "monospace", minWidth: "2.5rem", flexShrink: 0, opacity: hasFile ? 1 : 0.5 } }, "CSS"), hasFile ? /* @__PURE__ */ React7.createElement(Box3, { style: { flex: 1, minWidth: 0, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" } }, /* @__PURE__ */ React7.createElement("a", { href: fileUrl, target: "_blank", rel: "noreferrer" }, (filenames == null ? void 0 : filenames.css) || "File")) : /* @__PURE__ */ React7.createElement(Text7, { size: 1, muted: true }, "\u2014")), status === "ready" && /* @__PURE__ */ React7.createElement(Flex5, { gap: 1, align: "center", style: { flexShrink: 0 } }, (fileInput == null ? void 0 : fileInput.woff2) && /* @__PURE__ */ React7.createElement(Button5, { mode: "ghost", tone: "primary", fontSize: 1, padding: 2, onClick: () => handleGenerateCssFile(), text: "Build" }), hasFile && /* @__PURE__ */ React7.createElement(Button5, { mode: "bleed", tone: "critical", icon: TrashIcon2, padding: 2, onClick: () => handleDelete("css") }))));
1951
+ return /* @__PURE__ */ React6.createElement(Card3, { border: true, radius: 1, paddingX: 2, paddingY: 3 }, /* @__PURE__ */ React6.createElement(Flex4, { justify: "space-between", align: "center", gap: 2 }, /* @__PURE__ */ React6.createElement(Flex4, { gap: 3, align: "center", style: { flex: 1, minWidth: 0 } }, /* @__PURE__ */ React6.createElement(Text6, { size: 0, style: { fontFamily: "monospace", minWidth: "2.5rem", flexShrink: 0, opacity: hasFile ? 1 : 0.5 } }, "CSS"), hasFile ? /* @__PURE__ */ React6.createElement(Box3, { style: { flex: 1, minWidth: 0, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" } }, /* @__PURE__ */ React6.createElement("a", { href: fileUrl, target: "_blank", rel: "noreferrer" }, (filenames == null ? void 0 : filenames.css) || "File")) : /* @__PURE__ */ React6.createElement(Text6, { size: 1, muted: true }, "\u2014")), status === "ready" && /* @__PURE__ */ React6.createElement(Flex4, { gap: 1, align: "center", style: { flexShrink: 0 } }, (fileInput == null ? void 0 : fileInput.woff2) && /* @__PURE__ */ React6.createElement(Button5, { mode: "ghost", tone: "primary", fontSize: 1, padding: 2, onClick: () => handleGenerateCssFile(), text: "Build" }), hasFile && /* @__PURE__ */ React6.createElement(Button5, { mode: "bleed", tone: "critical", icon: TrashIcon2, padding: 2, onClick: () => handleDelete("css") }))));
2878
1952
  };
2879
- const renderDataSection = () => /* @__PURE__ */ React7.createElement(Card3, { border: true, radius: 1, paddingX: 2, paddingY: 3 }, /* @__PURE__ */ React7.createElement(Flex5, { justify: "space-between", align: "center", gap: 2 }, /* @__PURE__ */ React7.createElement(Flex5, { gap: 3, align: "center", style: { flex: 1, minWidth: 0 } }, /* @__PURE__ */ React7.createElement(Text7, { size: 0, style: { fontFamily: "monospace", minWidth: "2.5rem", flexShrink: 0, opacity: (doc_metaData == null ? void 0 : doc_metaData.version) ? 1 : 0.5 } }, "DATA"), (doc_metaData == null ? void 0 : doc_metaData.version) ? /* @__PURE__ */ React7.createElement(Text7, { size: 1 }, "v", doc_metaData.version, " ", /* @__PURE__ */ React7.createElement(Text7, { as: "span", size: 1, muted: true }, "(", doc_metaData.genDate, ")")) : /* @__PURE__ */ React7.createElement(Text7, { size: 1, muted: true }, "\u2014")), status === "ready" && (fileInput == null ? void 0 : fileInput.ttf) && /* @__PURE__ */ React7.createElement(Flex5, { gap: 1, align: "center", style: { flexShrink: 0 } }, /* @__PURE__ */ React7.createElement(Button5, { mode: "ghost", tone: "primary", fontSize: 1, padding: 2, onClick: () => handleGenerateFontData(), text: "Build" }))));
2880
- return /* @__PURE__ */ React7.createElement(Stack5, { space: 2 }, /* @__PURE__ */ React7.createElement(
1953
+ const renderDataSection = () => /* @__PURE__ */ React6.createElement(Card3, { border: true, radius: 1, paddingX: 2, paddingY: 3 }, /* @__PURE__ */ React6.createElement(Flex4, { justify: "space-between", align: "center", gap: 2 }, /* @__PURE__ */ React6.createElement(Flex4, { gap: 3, align: "center", style: { flex: 1, minWidth: 0 } }, /* @__PURE__ */ React6.createElement(Text6, { size: 0, style: { fontFamily: "monospace", minWidth: "2.5rem", flexShrink: 0, opacity: (doc_metaData == null ? void 0 : doc_metaData.version) ? 1 : 0.5 } }, "DATA"), (doc_metaData == null ? void 0 : doc_metaData.version) ? /* @__PURE__ */ React6.createElement(Text6, { size: 1 }, "v", doc_metaData.version, " ", /* @__PURE__ */ React6.createElement(Text6, { as: "span", size: 1, muted: true }, "(", doc_metaData.genDate, ")")) : /* @__PURE__ */ React6.createElement(Text6, { size: 1, muted: true }, "\u2014")), status === "ready" && (fileInput == null ? void 0 : fileInput.ttf) && /* @__PURE__ */ React6.createElement(Flex4, { gap: 1, align: "center", style: { flexShrink: 0 } }, /* @__PURE__ */ React6.createElement(Button5, { mode: "ghost", tone: "primary", fontSize: 1, padding: 2, onClick: () => handleGenerateFontData(), text: "Build" }))));
1954
+ return /* @__PURE__ */ React6.createElement(Stack5, { space: 2 }, /* @__PURE__ */ React6.createElement(
2881
1955
  StatusDisplay_default,
2882
1956
  {
2883
1957
  status,
2884
1958
  error,
2885
- action: /* @__PURE__ */ React7.createElement(
1959
+ action: /* @__PURE__ */ React6.createElement(
2886
1960
  Button5,
2887
1961
  {
2888
1962
  mode: "bleed",
@@ -2894,7 +1968,7 @@ var SingleUploaderTool = (props) => {
2894
1968
  }
2895
1969
  )
2896
1970
  }
2897
- ), renderFontSection("ttf"), status === "ready" && (fileInput == null ? void 0 : fileInput.ttf) && /* @__PURE__ */ React7.createElement(Grid3, { columns: [1, 2], gap: 2 }, /* @__PURE__ */ React7.createElement(
1971
+ ), renderFontSection("ttf"), status === "ready" && (fileInput == null ? void 0 : fileInput.ttf) && /* @__PURE__ */ React6.createElement(Grid3, { columns: [1, 2], gap: 2 }, /* @__PURE__ */ React6.createElement(
2898
1972
  Button5,
2899
1973
  {
2900
1974
  mode: "ghost",
@@ -2903,7 +1977,7 @@ var SingleUploaderTool = (props) => {
2903
1977
  text: "Rebuild All from TTF",
2904
1978
  style: { width: "100%" }
2905
1979
  }
2906
- ), /* @__PURE__ */ React7.createElement(
1980
+ ), /* @__PURE__ */ React6.createElement(
2907
1981
  Button5,
2908
1982
  {
2909
1983
  mode: "ghost",
@@ -2923,19 +1997,18 @@ var SingleUploaderTool = (props) => {
2923
1997
  text: "Build Missing",
2924
1998
  style: { width: "100%" }
2925
1999
  }
2926
- )), renderFontSection("otf", "woff"), renderFontSection("woff", "ttf"), renderFontSection("woff2", "ttf"), showAdvanced && renderTopLevelAssetSection("WEB", "woff2_web", (_b = (_a = fileInput == null ? void 0 : fileInput.woff2_web) == null ? void 0 : _a.asset) == null ? void 0 : _b._ref, filenames == null ? void 0 : filenames.woff2_web, handleGenerateSubsetAndWeb), showAdvanced && renderTopLevelAssetSection("SUBSET", "woff2_subset", (_d = (_c = fileInput == null ? void 0 : fileInput.woff2_subset) == null ? void 0 : _c.asset) == null ? void 0 : _d._ref, filenames == null ? void 0 : filenames.woff2_subset, handleGenerateSubsetAndWeb), showAdvanced && renderFontSection("eot", "ttf"), showAdvanced && renderFontSection("svg", "ttf"), renderCssSection(), showAdvanced && renderDataSection(), status === "ready" && ((fileInput == null ? void 0 : fileInput.ttf) || (fileInput == null ? void 0 : fileInput.otf) || (fileInput == null ? void 0 : fileInput.woff) || (fileInput == null ? void 0 : fileInput.woff2)) && /* @__PURE__ */ React7.createElement(Button5, { mode: "ghost", tone: "critical", onClick: () => handleDeleteAll(), text: "Delete All", style: { width: "100%" } }));
2000
+ )), renderFontSection("otf", "woff"), renderFontSection("woff", "ttf"), renderFontSection("woff2", "ttf"), showAdvanced && renderTopLevelAssetSection("WEB", "woff2_web", (_b = (_a = fileInput == null ? void 0 : fileInput.woff2_web) == null ? void 0 : _a.asset) == null ? void 0 : _b._ref, filenames == null ? void 0 : filenames.woff2_web, handleGenerateSubsetAndWeb), showAdvanced && renderTopLevelAssetSection("SUBSET", "woff2_subset", (_d = (_c = fileInput == null ? void 0 : fileInput.woff2_subset) == null ? void 0 : _c.asset) == null ? void 0 : _d._ref, filenames == null ? void 0 : filenames.woff2_subset, handleGenerateSubsetAndWeb), showAdvanced && renderFontSection("eot", "ttf"), showAdvanced && renderFontSection("svg", "ttf"), renderCssSection(), showAdvanced && renderDataSection(), status === "ready" && ((fileInput == null ? void 0 : fileInput.ttf) || (fileInput == null ? void 0 : fileInput.otf) || (fileInput == null ? void 0 : fileInput.woff) || (fileInput == null ? void 0 : fileInput.woff2)) && /* @__PURE__ */ React6.createElement(Button5, { mode: "ghost", tone: "critical", onClick: () => handleDeleteAll(), text: "Delete All", style: { width: "100%" } }));
2927
2001
  };
2928
2002
 
2929
2003
  // src/components/UploadScriptsComponent.jsx
2930
- import React9, { useCallback as useCallback5, useEffect as useEffect4, useMemo as useMemo4, useState as useState6 } from "react";
2931
- import { Button as Button6, Flex as Flex6, Grid as Grid4, Stack as Stack6, Text as Text8, TextInput, MenuButton, Menu, MenuItem, Select } from "@sanity/ui";
2932
- import * as fontkit6 from "fontkit";
2933
- import slugify3 from "slugify";
2004
+ import React8, { useCallback as useCallback5, useEffect as useEffect4, useMemo as useMemo4, useState as useState6 } from "react";
2005
+ import { Button as Button6, Flex as Flex5, Grid as Grid4, Stack as Stack6, Text as Text7, TextInput, MenuButton, Menu, MenuItem, Select } from "@sanity/ui";
2006
+ import slugify2 from "slugify";
2934
2007
  import { useFormValue as useFormValue6 } from "sanity";
2935
- import { nanoid as nanoid7 } from "nanoid";
2008
+ import { nanoid as nanoid4 } from "nanoid";
2936
2009
 
2937
2010
  // src/utils/utils.js
2938
- import React8 from "react";
2011
+ import React7 from "react";
2939
2012
  var HtmlDescription = ({ children }) => {
2940
2013
  return children || "";
2941
2014
  };
@@ -2953,8 +2026,8 @@ var UploadScriptsComponent = (props) => {
2953
2026
  const { elementProps: { ref } } = props;
2954
2027
  const client = useSanityClient();
2955
2028
  const [selectedScript, setSelectedScript] = useState6("");
2956
- const [status, setStatus] = React9.useState("");
2957
- const [ready, setReady] = React9.useState(true);
2029
+ const [status, setStatus] = React8.useState("");
2030
+ const [ready, setReady] = React8.useState(true);
2958
2031
  let doc_id = useFormValue6(["_id"]);
2959
2032
  const title = useFormValue6(["title"]);
2960
2033
  const slug = useFormValue6(["slug"]);
@@ -2978,7 +2051,6 @@ var UploadScriptsComponent = (props) => {
2978
2051
  });
2979
2052
  };
2980
2053
  const handleUpload = useCallback5(async (event, script) => {
2981
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l;
2982
2054
  setReady(false);
2983
2055
  try {
2984
2056
  let failedFiles = [];
@@ -2995,21 +2067,22 @@ var UploadScriptsComponent = (props) => {
2995
2067
  for (var i = 0; i < event.target.files.length; i++) {
2996
2068
  const file = event.target.files[i];
2997
2069
  const fontBuffer = await readFontFile3(file);
2998
- const font = fontkit6.create(fontBuffer);
2999
- console.log("reading font : ", font.fullName + " " + file.name, font.name.records);
3000
- let weightName = ((_b = (_a = font == null ? void 0 : font.name) == null ? void 0 : _a.records) == null ? void 0 : _b.preferredSubfamily) ? (_d = (_c = font == null ? void 0 : font.name) == null ? void 0 : _c.records) == null ? void 0 : _d.preferredSubfamily : (_f = (_e = font == null ? void 0 : font.name) == null ? void 0 : _e.records) == null ? void 0 : _f.fontSubfamily;
3001
- weightName = (weightName == null ? void 0 : weightName.en) ? weightName.en : weightName.constructor == Object ? weightName[Object.keys(weightName)[0]] : weightName;
3002
- weightName = weightName == null ? void 0 : weightName.replace("Italic", "").replace("It", "").trim();
3003
- if ((weightName == "" || weightName.toLowerCase() == "roman") && ((_h = (_g = font == null ? void 0 : font.name) == null ? void 0 : _g.records) == null ? void 0 : _h.fullName)) {
3004
- weightName = (_j = (_i = font == null ? void 0 : font.name) == null ? void 0 : _i.records) == null ? void 0 : _j.fullName;
3005
- weightName = (weightName == null ? void 0 : weightName.en) ? weightName.en : weightName.constructor == Object ? weightName[Object.keys(weightName)[0]] : weightName;
3006
- weightName = weightName == null ? void 0 : weightName.replace(title + " ", "").replace(title, "").trim();
3007
- weightName = weightName == null ? void 0 : weightName.replace("Italic", "").replace("It", "").trim();
2070
+ const font = await parseFont(fontBuffer, file.name);
2071
+ const fullName = getNameString(font, 4);
2072
+ const familyName = getNameString(font, 1);
2073
+ console.log("Reading font:", fullName, file.name);
2074
+ let weightName = getNameString(font, 17) || getNameString(font, 2) || "";
2075
+ weightName = weightName.replace("Italic", "").replace("It", "").trim();
2076
+ if ((weightName == "" || weightName.toLowerCase() == "roman") && fullName) {
2077
+ weightName = fullName.replace(title + " ", "").replace(title, "").trim();
2078
+ weightName = weightName.replace("Italic", "").replace("It", "").trim();
3008
2079
  }
3009
- let variableFont = (font == null ? void 0 : font.variationAxes) && Object.keys(font.variationAxes).length > 0 ? true : false;
3010
- let subfamilyName = font.familyName.toLowerCase().trim().replace(title.toLowerCase().trim(), "").trim();
3011
- let fontTitle = font == null ? void 0 : font.fullName;
3012
- let style = (font == null ? void 0 : font.italicAngle) !== 0 || (font == null ? void 0 : font.fullName.toLowerCase().includes("italic")) ? "Italic" : "Regular";
2080
+ const axes = getVariationAxes(font);
2081
+ let variableFont = axes !== null;
2082
+ let subfamilyName = familyName.toLowerCase().trim().replace(title.toLowerCase().trim(), "").trim();
2083
+ let fontTitle = fullName;
2084
+ const italicAngle = getItalicAngle(font);
2085
+ let style = italicAngle !== 0 || fullName.toLowerCase().includes("italic") ? "Italic" : "Regular";
3013
2086
  if (fontTitle.toLowerCase().trim().includes(script)) {
3014
2087
  fontTitle = fontTitle.toLowerCase().trim().replace(script, "").trim();
3015
2088
  fontTitle = fontTitle.split(" ").map((word) => {
@@ -3048,13 +2121,13 @@ var UploadScriptsComponent = (props) => {
3048
2121
  fontTitle = fontTitle + italicKW.join(" ");
3049
2122
  style = "Italic";
3050
2123
  }
3051
- let id = slugify3(fontTitle.toLowerCase().trim());
2124
+ let id = slugify2(fontTitle.toLowerCase().trim());
3052
2125
  console.log("=== Font Info ====");
3053
2126
  console.log(" ");
3054
2127
  console.log("font id : ", id);
3055
2128
  console.log("font title : ", fontTitle);
3056
- console.log("fontkit fullName : ", font.fullName);
3057
- console.log("fontkit family name: ", font.familyName);
2129
+ console.log("Full name:", fullName);
2130
+ console.log("Family name:", familyName);
3058
2131
  console.log("file name : ", file.name);
3059
2132
  console.log("subfamily : ", subfamilyName);
3060
2133
  console.log("style : ", style);
@@ -3068,18 +2141,17 @@ var UploadScriptsComponent = (props) => {
3068
2141
  fontsObjects[id].files = [...fontsObjects[id].files, file];
3069
2142
  } else {
3070
2143
  let fontObject = {
3071
- _key: nanoid7(),
2144
+ _key: nanoid4(),
3072
2145
  _id: id,
3073
2146
  title: fontTitle,
3074
2147
  slug: { _type: "slug", current: id },
3075
2148
  typefaceName: title,
3076
2149
  // Change to match Typeface Document
3077
- style: (font == null ? void 0 : font.italicAngle) !== 0 || (font == null ? void 0 : font.fullName.toLowerCase().includes("italic")) ? "Italic" : "Regular",
2150
+ style,
3078
2151
  variableFont,
3079
2152
  weightName,
3080
2153
  normalWeight: true,
3081
- // TODO : check if weight is normal ??
3082
- weight: ((_k = font["OS/2"]) == null ? void 0 : _k.usWeightClass) ? Number((_l = font["OS/2"]) == null ? void 0 : _l.usWeightClass) : /hairline|extra thin|extrathin/.test(weightName == null ? void 0 : weightName.toLowerCase()) ? 100 : /thin|extra light|extralight/.test(weightName == null ? void 0 : weightName.toLowerCase()) ? 200 : /light|book/.test(weightName == null ? void 0 : weightName.toLowerCase()) ? 300 : /regular|normal/.test(weightName == null ? void 0 : weightName.toLowerCase()) ? 400 : /medium/.test(weightName == null ? void 0 : weightName.toLowerCase()) ? 500 : /semi bold|semibold/.test(weightName == null ? void 0 : weightName.toLowerCase()) ? 600 : /bold/.test(weightName == null ? void 0 : weightName.toLowerCase()) ? 700 : /extra bold|extrabold/.test(weightName == null ? void 0 : weightName.toLowerCase()) ? 800 : /black|ultra/.test(weightName == null ? void 0 : weightName.toLowerCase()) ? 900 : 400,
2154
+ weight: getWeightClass(font) || (/hairline|extra thin|extrathin/.test(weightName == null ? void 0 : weightName.toLowerCase()) ? 100 : /thin|extra light|extralight/.test(weightName == null ? void 0 : weightName.toLowerCase()) ? 200 : /light|book/.test(weightName == null ? void 0 : weightName.toLowerCase()) ? 300 : /regular|normal/.test(weightName == null ? void 0 : weightName.toLowerCase()) ? 400 : /medium/.test(weightName == null ? void 0 : weightName.toLowerCase()) ? 500 : /semi bold|semibold/.test(weightName == null ? void 0 : weightName.toLowerCase()) ? 600 : /bold/.test(weightName == null ? void 0 : weightName.toLowerCase()) ? 700 : /extra bold|extrabold/.test(weightName == null ? void 0 : weightName.toLowerCase()) ? 800 : /black|ultra/.test(weightName == null ? void 0 : weightName.toLowerCase()) ? 900 : 400),
3083
2155
  files: [file],
3084
2156
  fontKit: font,
3085
2157
  scriptFileInput: { [script]: {} }
@@ -3181,7 +2253,7 @@ var UploadScriptsComponent = (props) => {
3181
2253
  fontResponse = await client.patch(font._id).set({ scriptFileInput: font.scriptFileInput }).commit();
3182
2254
  } else {
3183
2255
  fontResponse = await client.createOrReplace({
3184
- _key: nanoid7(),
2256
+ _key: nanoid4(),
3185
2257
  _id: font._id,
3186
2258
  _type: "font",
3187
2259
  ...font
@@ -3194,7 +2266,7 @@ var UploadScriptsComponent = (props) => {
3194
2266
  })];
3195
2267
  continue;
3196
2268
  }
3197
- const fontRef = { _key: nanoid7(), _type: "reference", _ref: fontResponse._id, _weak: true };
2269
+ const fontRef = { _key: nanoid4(), _type: "reference", _ref: fontResponse._id, _weak: true };
3198
2270
  console.log("font response : ", fontResponse);
3199
2271
  console.log("existing styles object : ", stylesObject);
3200
2272
  if (!font.variableFont) {
@@ -3262,8 +2334,8 @@ var UploadScriptsComponent = (props) => {
3262
2334
  console.log("failed files : ", failedFiles);
3263
2335
  const names = failedFiles.map((file) => file.name);
3264
2336
  console.log("names : ", failedFiles.map((file) => {
3265
- var _a2, _b2;
3266
- return (_b2 = (_a2 = file == null ? void 0 : file.fk) == null ? void 0 : _a2.name) == null ? void 0 : _b2.records;
2337
+ var _a, _b;
2338
+ return (_b = (_a = file == null ? void 0 : file.fk) == null ? void 0 : _a.name) == null ? void 0 : _b.records;
3267
2339
  }));
3268
2340
  setStatus("fonts uploaded with errors. Failed files : " + names.join(", "));
3269
2341
  } else {
@@ -3276,26 +2348,26 @@ var UploadScriptsComponent = (props) => {
3276
2348
  }
3277
2349
  setReady(true);
3278
2350
  }, [title, slug, doc_id]);
3279
- return /* @__PURE__ */ React9.createElement(Stack6, null, !ready && /* @__PURE__ */ React9.createElement(Text8, null, /* @__PURE__ */ React9.createElement("br", null), status, /* @__PURE__ */ React9.createElement("br", null), /* @__PURE__ */ React9.createElement("br", null)), ready && /* @__PURE__ */ React9.createElement(Stack6, null, /* @__PURE__ */ React9.createElement(Grid4, { columns: !!(selectedScript && selectedScript !== "") ? 2 : 1, gap: 2 }, /* @__PURE__ */ React9.createElement(
2351
+ return /* @__PURE__ */ React8.createElement(Stack6, null, !ready && /* @__PURE__ */ React8.createElement(Text7, null, /* @__PURE__ */ React8.createElement("br", null), status, /* @__PURE__ */ React8.createElement("br", null), /* @__PURE__ */ React8.createElement("br", null)), ready && /* @__PURE__ */ React8.createElement(Stack6, null, /* @__PURE__ */ React8.createElement(Grid4, { columns: !!(selectedScript && selectedScript !== "") ? 2 : 1, gap: 2 }, /* @__PURE__ */ React8.createElement(
3280
2352
  Select,
3281
2353
  {
3282
2354
  id: "menu-button-example",
3283
2355
  onChange: (e) => setSelectedScript(e.target.value)
3284
2356
  },
3285
- /* @__PURE__ */ React9.createElement("option", { key: "script-none", value: "" }, " "),
2357
+ /* @__PURE__ */ React8.createElement("option", { key: "script-none", value: "" }, " "),
3286
2358
  SCRIPTS.map(
3287
2359
  (script, i) => {
3288
2360
  var _a;
3289
- return /* @__PURE__ */ React9.createElement("option", { key: "script-" + i, value: script }, ((_a = script[0]) == null ? void 0 : _a.toUpperCase()) + script.slice(1));
2361
+ return /* @__PURE__ */ React8.createElement("option", { key: "script-" + i, value: script }, ((_a = script[0]) == null ? void 0 : _a.toUpperCase()) + script.slice(1));
3290
2362
  }
3291
2363
  )
3292
- ), !!(selectedScript && selectedScript !== "") && /* @__PURE__ */ React9.createElement(React9.Fragment, null, /* @__PURE__ */ React9.createElement("label", { htmlFor: "upload-scripts-file" }, /* @__PURE__ */ React9.createElement(
2364
+ ), !!(selectedScript && selectedScript !== "") && /* @__PURE__ */ React8.createElement(React8.Fragment, null, /* @__PURE__ */ React8.createElement("label", { htmlFor: "upload-scripts-file" }, /* @__PURE__ */ React8.createElement(
3293
2365
  Button6,
3294
2366
  {
3295
2367
  style: { pointerEvents: "none" },
3296
2368
  text: "Upload (ttf/otf/woff/woff2/etc..)"
3297
2369
  }
3298
- )), /* @__PURE__ */ React9.createElement(
2370
+ )), /* @__PURE__ */ React8.createElement(
3299
2371
  "input",
3300
2372
  {
3301
2373
  ref,
@@ -3310,8 +2382,8 @@ var UploadScriptsComponent = (props) => {
3310
2382
  };
3311
2383
 
3312
2384
  // src/components/FontScriptUploaderComponent.jsx
3313
- import React10, { useState as useState7, useEffect as useEffect5, useCallback as useCallback6 } from "react";
3314
- import { Stack as Stack7, Flex as Flex7, Text as Text9, Button as Button7 } from "@sanity/ui";
2385
+ import React9, { useState as useState7, useEffect as useEffect5, useCallback as useCallback6 } from "react";
2386
+ import { Stack as Stack7, Flex as Flex6, Text as Text8, Button as Button7 } from "@sanity/ui";
3315
2387
  import { useFormValue as useFormValue7, set as set3, unset as unset2 } from "sanity";
3316
2388
  var FontScriptUploaderComponent = (props) => {
3317
2389
  const client = useSanityClient();
@@ -3519,17 +2591,17 @@ var FontScriptUploaderComponent = (props) => {
3519
2591
  }
3520
2592
  }
3521
2593
  }, [scriptFileInput]);
3522
- return /* @__PURE__ */ React10.createElement(Stack7, { space: 4 }, SCRIPTS && scriptFileInput && SCRIPTS.map((language, i) => {
2594
+ return /* @__PURE__ */ React9.createElement(Stack7, { space: 4 }, SCRIPTS && scriptFileInput && SCRIPTS.map((language, i) => {
3523
2595
  var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _A, _B, _C, _D, _E, _F, _G, _H, _I, _J, _K, _L, _M, _N, _O, _P, _Q, _R, _S, _T, _U, _V, _W, _X, _Y, _Z, __, _$, _aa, _ba, _ca, _da, _ea, _fa, _ga, _ha, _ia, _ja, _ka, _la, _ma, _na, _oa, _pa, _qa, _ra, _sa, _ta, _ua, _va, _wa, _xa, _ya, _za, _Aa, _Ba, _Ca, _Da, _Ea, _Fa, _Ga;
3524
- return /* @__PURE__ */ React10.createElement(Stack7, { space: 2, key: "language-" + i, style: { borderBottom: "1px solid var(--card-border-color)", paddingBottom: 8 } }, /* @__PURE__ */ React10.createElement(Flex7, { gap: 2 }, /* @__PURE__ */ React10.createElement(Text9, { weight: "semibold" }, ((_a = language[0]) == null ? void 0 : _a.toUpperCase()) + language.slice(1)), message && message[language] && message[language] !== "" && /* @__PURE__ */ React10.createElement(Text9, { style: { color: "green" } }, message[language])), expanded[language] && /* @__PURE__ */ React10.createElement(Stack7, { space: 2 }, /* @__PURE__ */ React10.createElement(Flex7, { justify: "space-between", align: "center" }, /* @__PURE__ */ React10.createElement(Text9, null, "TTF:\xA0", !((_d = (_c = (_b = scriptFileInput[language]) == null ? void 0 : _b.ttf) == null ? void 0 : _c.asset) == null ? void 0 : _d._ref) ? ((_e = filenames[language]) == null ? void 0 : _e.ttf) ? /* @__PURE__ */ React10.createElement("b", null, filenames[language].ttf) : /* @__PURE__ */ React10.createElement("b", null, "Empty") : /* @__PURE__ */ React10.createElement("a", { href: `https://cdn.sanity.io/files/${process.env.SANITY_STUDIO_PROJECT_ID}/${process.env.SANITY_STUDIO_DATASET}/${(_h = (_g = (_f = scriptFileInput[language]) == null ? void 0 : _f.ttf) == null ? void 0 : _g.asset) == null ? void 0 : _h._ref.replace("file-", "").replace("-", ".")}`, target: "_blank" }, ((_i = filenames[language]) == null ? void 0 : _i.ttf) ? /* @__PURE__ */ React10.createElement("b", null, filenames[language].ttf) : /* @__PURE__ */ React10.createElement("b", null, "File"))), status === "ready" && /* @__PURE__ */ React10.createElement(Flex7, { gap: 1 }, /* @__PURE__ */ React10.createElement("label", null, /* @__PURE__ */ React10.createElement(Button7, { as: "span", mode: "ghost" }, "Upload"), /* @__PURE__ */ React10.createElement("input", { ref, type: "file", style: { display: "none" }, onChange: (event) => handleUpload(event, language, "ttf") })), ((_j = value[language]) == null ? void 0 : _j.ttf) && /* @__PURE__ */ React10.createElement(Button7, { mode: "ghost", tone: "critical", onClick: () => handleDelete("ttf", language) }, "\xD7"))), status === "ready" && ((_k = value[language]) == null ? void 0 : _k.ttf) && /* @__PURE__ */ React10.createElement(Button7, { mode: "default", onClick: () => handleGenerateFontFile("all", value[language].ttf, language) }, "Regenerate Files from TTF"), /* @__PURE__ */ React10.createElement(Flex7, { justify: "space-between", align: "center" }, /* @__PURE__ */ React10.createElement(Text9, null, "OTF:\xA0", !((_n = (_m = (_l = scriptFileInput[language]) == null ? void 0 : _l.otf) == null ? void 0 : _m.asset) == null ? void 0 : _n._ref) ? ((_o = filenames[language]) == null ? void 0 : _o.otf) ? /* @__PURE__ */ React10.createElement("b", null, (_p = filenames[language]) == null ? void 0 : _p.otf) : /* @__PURE__ */ React10.createElement("b", null, "Empty") : /* @__PURE__ */ React10.createElement("a", { href: `https://cdn.sanity.io/files/${process.env.SANITY_STUDIO_PROJECT_ID}/${process.env.SANITY_STUDIO_DATASET}/${(_s = (_r = (_q = scriptFileInput[language]) == null ? void 0 : _q.otf) == null ? void 0 : _r.asset) == null ? void 0 : _s._ref.replace("file-", "").replace("-", ".")}`, target: "_blank" }, ((_t = filenames[language]) == null ? void 0 : _t.otf) ? /* @__PURE__ */ React10.createElement("b", null, (_u = filenames[language]) == null ? void 0 : _u.otf) : /* @__PURE__ */ React10.createElement("b", null, "File"))), status === "ready" && /* @__PURE__ */ React10.createElement(Flex7, { gap: 1 }, ((_v = value[language]) == null ? void 0 : _v.woff) && /* @__PURE__ */ React10.createElement(Button7, { mode: "default", onClick: () => handleGenerateFontFile("otf", value[language].woff, language) }, "Build"), /* @__PURE__ */ React10.createElement("label", null, /* @__PURE__ */ React10.createElement(Button7, { as: "span", mode: "ghost" }, "Upload"), /* @__PURE__ */ React10.createElement("input", { ref, type: "file", style: { display: "none" }, onChange: async (event) => handleUpload(event, language, "otf") })), ((_w = value[language]) == null ? void 0 : _w.otf) && /* @__PURE__ */ React10.createElement(Button7, { mode: "ghost", tone: "critical", onClick: () => handleDelete("otf", language) }, "\xD7"))), /* @__PURE__ */ React10.createElement(Flex7, { justify: "space-between", align: "center" }, /* @__PURE__ */ React10.createElement(Text9, null, "WOFF:\xA0", !((_z = (_y = (_x = scriptFileInput[language]) == null ? void 0 : _x.woff) == null ? void 0 : _y.asset) == null ? void 0 : _z._ref) ? ((_A = filenames[language]) == null ? void 0 : _A.woff) ? /* @__PURE__ */ React10.createElement("b", null, (_B = filenames[language]) == null ? void 0 : _B.woff) : /* @__PURE__ */ React10.createElement("b", null, "Empty") : /* @__PURE__ */ React10.createElement("a", { href: `https://cdn.sanity.io/files/${process.env.SANITY_STUDIO_PROJECT_ID}/${process.env.SANITY_STUDIO_DATASET}/${(_E = (_D = (_C = scriptFileInput[language]) == null ? void 0 : _C.woff) == null ? void 0 : _D.asset) == null ? void 0 : _E._ref.replace("file-", "").replace("-", ".")}`, target: "_blank" }, ((_F = filenames[language]) == null ? void 0 : _F.woff) ? /* @__PURE__ */ React10.createElement("b", null, (_G = filenames[language]) == null ? void 0 : _G.woff) : /* @__PURE__ */ React10.createElement("b", null, "File"))), status === "ready" && /* @__PURE__ */ React10.createElement(Flex7, { gap: 1 }, ((_H = value[language]) == null ? void 0 : _H.ttf) && /* @__PURE__ */ React10.createElement(Button7, { mode: "default", onClick: () => handleGenerateFontFile("woff", value[language].ttf, language) }, "Build"), /* @__PURE__ */ React10.createElement("label", null, /* @__PURE__ */ React10.createElement(Button7, { as: "span", mode: "ghost" }, "Upload"), /* @__PURE__ */ React10.createElement("input", { ref, type: "file", style: { display: "none" }, onChange: async (event) => handleUpload(event, language, "woff") })), ((_I = value[language]) == null ? void 0 : _I.woff) && /* @__PURE__ */ React10.createElement(Button7, { mode: "ghost", tone: "critical", onClick: () => handleDelete("woff", language) }, "\xD7"))), /* @__PURE__ */ React10.createElement(Flex7, { justify: "space-between", align: "center" }, /* @__PURE__ */ React10.createElement(Text9, null, "WOFF2:\xA0", !((_L = (_K = (_J = scriptFileInput[language]) == null ? void 0 : _J.woff2) == null ? void 0 : _K.asset) == null ? void 0 : _L._ref) ? ((_M = filenames[language]) == null ? void 0 : _M.woff2) ? /* @__PURE__ */ React10.createElement("b", null, (_N = filenames[language]) == null ? void 0 : _N.woff2) : /* @__PURE__ */ React10.createElement("b", null, "Empty") : /* @__PURE__ */ React10.createElement("a", { href: `https://cdn.sanity.io/files/${process.env.SANITY_STUDIO_PROJECT_ID}/${process.env.SANITY_STUDIO_DATASET}/${(_Q = (_P = (_O = scriptFileInput[language]) == null ? void 0 : _O.woff2) == null ? void 0 : _P.asset) == null ? void 0 : _Q._ref.replace("file-", "").replace("-", ".")}`, target: "_blank" }, ((_R = filenames[language]) == null ? void 0 : _R.woff2) ? /* @__PURE__ */ React10.createElement("b", null, (_S = filenames[language]) == null ? void 0 : _S.woff2) : /* @__PURE__ */ React10.createElement("b", null, "File"))), status === "ready" && /* @__PURE__ */ React10.createElement(Flex7, { gap: 1 }, ((_T = value[language]) == null ? void 0 : _T.ttf) && /* @__PURE__ */ React10.createElement(Button7, { mode: "default", onClick: () => handleGenerateFontFile("woff2", value[language].ttf, language) }, "Build"), /* @__PURE__ */ React10.createElement("label", null, /* @__PURE__ */ React10.createElement(Button7, { as: "span", mode: "ghost" }, "Upload"), /* @__PURE__ */ React10.createElement("input", { ref, type: "file", style: { display: "none" }, onChange: async (event) => handleUpload(event, language, "woff2") })), ((_U = value[language]) == null ? void 0 : _U.woff2) && /* @__PURE__ */ React10.createElement(Button7, { mode: "ghost", tone: "critical", onClick: () => handleDelete("woff2", language) }, "\xD7"))), /* @__PURE__ */ React10.createElement(Flex7, { justify: "space-between", align: "center" }, /* @__PURE__ */ React10.createElement(Text9, null, "EOT:\xA0", !((_X = (_W = (_V = scriptFileInput[language]) == null ? void 0 : _V.eot) == null ? void 0 : _W.asset) == null ? void 0 : _X._ref) ? ((_Y = filenames[language]) == null ? void 0 : _Y.eot) ? /* @__PURE__ */ React10.createElement("b", null, (_Z = filenames[language]) == null ? void 0 : _Z.eot) : /* @__PURE__ */ React10.createElement("b", null, "Empty") : /* @__PURE__ */ React10.createElement("a", { href: `https://cdn.sanity.io/files/${process.env.SANITY_STUDIO_PROJECT_ID}/${process.env.SANITY_STUDIO_DATASET}/${(_aa = (_$ = (__ = scriptFileInput[language]) == null ? void 0 : __.eot) == null ? void 0 : _$.asset) == null ? void 0 : _aa._ref.replace("file-", "").replace("-", ".")}`, target: "_blank" }, ((_ba = filenames[language]) == null ? void 0 : _ba.eot) ? /* @__PURE__ */ React10.createElement("b", null, (_ca = filenames[language]) == null ? void 0 : _ca.eot) : /* @__PURE__ */ React10.createElement("b", null, "File"))), status === "ready" && /* @__PURE__ */ React10.createElement(Flex7, { gap: 1 }, ((_da = value[language]) == null ? void 0 : _da.ttf) && /* @__PURE__ */ React10.createElement(Button7, { mode: "default", onClick: () => handleGenerateFontFile("eot", value[language].ttf, language) }, "Build"), /* @__PURE__ */ React10.createElement("label", null, /* @__PURE__ */ React10.createElement(Button7, { as: "span", mode: "ghost" }, "Upload"), /* @__PURE__ */ React10.createElement("input", { ref, type: "file", style: { display: "none" }, onChange: async (event) => handleUpload(event, language, "eot") })), ((_ea = value[language]) == null ? void 0 : _ea.eot) && /* @__PURE__ */ React10.createElement(Button7, { mode: "ghost", tone: "critical", onClick: () => handleDelete("eot", language) }, "\xD7"))), /* @__PURE__ */ React10.createElement(Flex7, { justify: "space-between", align: "center" }, /* @__PURE__ */ React10.createElement(Text9, null, "SVG:\xA0", !((_ha = (_ga = (_fa = scriptFileInput[language]) == null ? void 0 : _fa.svg) == null ? void 0 : _ga.asset) == null ? void 0 : _ha._ref) ? ((_ia = filenames[language]) == null ? void 0 : _ia.svg) ? /* @__PURE__ */ React10.createElement("b", null, (_ja = filenames[language]) == null ? void 0 : _ja.svg) : /* @__PURE__ */ React10.createElement("b", null, "Empty") : /* @__PURE__ */ React10.createElement("a", { href: `https://cdn.sanity.io/files/${process.env.SANITY_STUDIO_PROJECT_ID}/${process.env.SANITY_STUDIO_DATASET}/${(_ma = (_la = (_ka = scriptFileInput[language]) == null ? void 0 : _ka.svg) == null ? void 0 : _la.asset) == null ? void 0 : _ma._ref.replace("file-", "").replace("-", ".")}`, target: "_blank" }, ((_na = filenames[language]) == null ? void 0 : _na.svg) ? /* @__PURE__ */ React10.createElement("b", null, (_oa = filenames[language]) == null ? void 0 : _oa.svg) : /* @__PURE__ */ React10.createElement("b", null, "File"))), status === "ready" && /* @__PURE__ */ React10.createElement(Flex7, { gap: 1 }, ((_pa = value[language]) == null ? void 0 : _pa.ttf) && /* @__PURE__ */ React10.createElement(Button7, { mode: "default", onClick: () => handleGenerateFontFile("svg", value[language].ttf, language) }, "Build"), /* @__PURE__ */ React10.createElement("label", null, /* @__PURE__ */ React10.createElement(Button7, { as: "span", mode: "ghost" }, "Upload"), /* @__PURE__ */ React10.createElement("input", { ref, type: "file", style: { display: "none" }, onChange: async (event) => handleUpload(event, language, "svg") })), ((_qa = value[language]) == null ? void 0 : _qa.svg) && /* @__PURE__ */ React10.createElement(Button7, { mode: "ghost", tone: "critical", onClick: () => handleDelete("svg", language) }, "\xD7"))), /* @__PURE__ */ React10.createElement(Flex7, { justify: "space-between", align: "center" }, /* @__PURE__ */ React10.createElement(Text9, null, "CSS:\xA0", !((_ta = (_sa = (_ra = scriptFileInput[language]) == null ? void 0 : _ra.css) == null ? void 0 : _sa.asset) == null ? void 0 : _ta._ref) ? ((_ua = filenames[language]) == null ? void 0 : _ua.css) ? /* @__PURE__ */ React10.createElement("b", null, (_va = filenames[language]) == null ? void 0 : _va.css) : /* @__PURE__ */ React10.createElement("b", null, "Empty") : /* @__PURE__ */ React10.createElement("a", { href: `https://cdn.sanity.io/files/${process.env.SANITY_STUDIO_PROJECT_ID}/${process.env.SANITY_STUDIO_DATASET}/${(_ya = (_xa = (_wa = scriptFileInput[language]) == null ? void 0 : _wa.css) == null ? void 0 : _xa.asset) == null ? void 0 : _ya._ref.replace("file-", "").replace("-", ".")}`, target: "_blank" }, ((_za = filenames[language]) == null ? void 0 : _za.css) ? /* @__PURE__ */ React10.createElement("b", null, (_Aa = filenames[language]) == null ? void 0 : _Aa.css) : /* @__PURE__ */ React10.createElement("b", null, "File"))), status === "ready" && /* @__PURE__ */ React10.createElement(Flex7, { gap: 1 }, ((_Ba = value[language]) == null ? void 0 : _Ba.woff2) && /* @__PURE__ */ React10.createElement(Button7, { mode: "default", onClick: () => handleGenerateCssFile(language) }, "Build"), ((_Ca = value[language]) == null ? void 0 : _Ca.css) && /* @__PURE__ */ React10.createElement(Button7, { mode: "ghost", tone: "critical", onClick: () => handleDelete("css", language) }, "\xD7"))), status === "ready" && (((_Da = value[language]) == null ? void 0 : _Da.ttf) || ((_Ea = value[language]) == null ? void 0 : _Ea.otf) || ((_Fa = value[language]) == null ? void 0 : _Fa.woff) || ((_Ga = value[language]) == null ? void 0 : _Ga.woff2)) && /* @__PURE__ */ React10.createElement(Button7, { mode: "ghost", tone: "critical", onClick: () => handleDeleteAll(language), style: { width: "100%" } }, "Delete All")));
2596
+ return /* @__PURE__ */ React9.createElement(Stack7, { space: 2, key: "language-" + i, style: { borderBottom: "1px solid var(--card-border-color)", paddingBottom: 8 } }, /* @__PURE__ */ React9.createElement(Flex6, { gap: 2 }, /* @__PURE__ */ React9.createElement(Text8, { weight: "semibold" }, ((_a = language[0]) == null ? void 0 : _a.toUpperCase()) + language.slice(1)), message && message[language] && message[language] !== "" && /* @__PURE__ */ React9.createElement(Text8, { style: { color: "green" } }, message[language])), expanded[language] && /* @__PURE__ */ React9.createElement(Stack7, { space: 2 }, /* @__PURE__ */ React9.createElement(Flex6, { justify: "space-between", align: "center" }, /* @__PURE__ */ React9.createElement(Text8, null, "TTF:\xA0", !((_d = (_c = (_b = scriptFileInput[language]) == null ? void 0 : _b.ttf) == null ? void 0 : _c.asset) == null ? void 0 : _d._ref) ? ((_e = filenames[language]) == null ? void 0 : _e.ttf) ? /* @__PURE__ */ React9.createElement("b", null, filenames[language].ttf) : /* @__PURE__ */ React9.createElement("b", null, "Empty") : /* @__PURE__ */ React9.createElement("a", { href: `https://cdn.sanity.io/files/${process.env.SANITY_STUDIO_PROJECT_ID}/${process.env.SANITY_STUDIO_DATASET}/${(_h = (_g = (_f = scriptFileInput[language]) == null ? void 0 : _f.ttf) == null ? void 0 : _g.asset) == null ? void 0 : _h._ref.replace("file-", "").replace("-", ".")}`, target: "_blank" }, ((_i = filenames[language]) == null ? void 0 : _i.ttf) ? /* @__PURE__ */ React9.createElement("b", null, filenames[language].ttf) : /* @__PURE__ */ React9.createElement("b", null, "File"))), status === "ready" && /* @__PURE__ */ React9.createElement(Flex6, { gap: 1 }, /* @__PURE__ */ React9.createElement("label", null, /* @__PURE__ */ React9.createElement(Button7, { as: "span", mode: "ghost" }, "Upload"), /* @__PURE__ */ React9.createElement("input", { ref, type: "file", style: { display: "none" }, onChange: (event) => handleUpload(event, language, "ttf") })), ((_j = value[language]) == null ? void 0 : _j.ttf) && /* @__PURE__ */ React9.createElement(Button7, { mode: "ghost", tone: "critical", onClick: () => handleDelete("ttf", language) }, "\xD7"))), status === "ready" && ((_k = value[language]) == null ? void 0 : _k.ttf) && /* @__PURE__ */ React9.createElement(Button7, { mode: "default", onClick: () => handleGenerateFontFile("all", value[language].ttf, language) }, "Regenerate Files from TTF"), /* @__PURE__ */ React9.createElement(Flex6, { justify: "space-between", align: "center" }, /* @__PURE__ */ React9.createElement(Text8, null, "OTF:\xA0", !((_n = (_m = (_l = scriptFileInput[language]) == null ? void 0 : _l.otf) == null ? void 0 : _m.asset) == null ? void 0 : _n._ref) ? ((_o = filenames[language]) == null ? void 0 : _o.otf) ? /* @__PURE__ */ React9.createElement("b", null, (_p = filenames[language]) == null ? void 0 : _p.otf) : /* @__PURE__ */ React9.createElement("b", null, "Empty") : /* @__PURE__ */ React9.createElement("a", { href: `https://cdn.sanity.io/files/${process.env.SANITY_STUDIO_PROJECT_ID}/${process.env.SANITY_STUDIO_DATASET}/${(_s = (_r = (_q = scriptFileInput[language]) == null ? void 0 : _q.otf) == null ? void 0 : _r.asset) == null ? void 0 : _s._ref.replace("file-", "").replace("-", ".")}`, target: "_blank" }, ((_t = filenames[language]) == null ? void 0 : _t.otf) ? /* @__PURE__ */ React9.createElement("b", null, (_u = filenames[language]) == null ? void 0 : _u.otf) : /* @__PURE__ */ React9.createElement("b", null, "File"))), status === "ready" && /* @__PURE__ */ React9.createElement(Flex6, { gap: 1 }, ((_v = value[language]) == null ? void 0 : _v.woff) && /* @__PURE__ */ React9.createElement(Button7, { mode: "default", onClick: () => handleGenerateFontFile("otf", value[language].woff, language) }, "Build"), /* @__PURE__ */ React9.createElement("label", null, /* @__PURE__ */ React9.createElement(Button7, { as: "span", mode: "ghost" }, "Upload"), /* @__PURE__ */ React9.createElement("input", { ref, type: "file", style: { display: "none" }, onChange: async (event) => handleUpload(event, language, "otf") })), ((_w = value[language]) == null ? void 0 : _w.otf) && /* @__PURE__ */ React9.createElement(Button7, { mode: "ghost", tone: "critical", onClick: () => handleDelete("otf", language) }, "\xD7"))), /* @__PURE__ */ React9.createElement(Flex6, { justify: "space-between", align: "center" }, /* @__PURE__ */ React9.createElement(Text8, null, "WOFF:\xA0", !((_z = (_y = (_x = scriptFileInput[language]) == null ? void 0 : _x.woff) == null ? void 0 : _y.asset) == null ? void 0 : _z._ref) ? ((_A = filenames[language]) == null ? void 0 : _A.woff) ? /* @__PURE__ */ React9.createElement("b", null, (_B = filenames[language]) == null ? void 0 : _B.woff) : /* @__PURE__ */ React9.createElement("b", null, "Empty") : /* @__PURE__ */ React9.createElement("a", { href: `https://cdn.sanity.io/files/${process.env.SANITY_STUDIO_PROJECT_ID}/${process.env.SANITY_STUDIO_DATASET}/${(_E = (_D = (_C = scriptFileInput[language]) == null ? void 0 : _C.woff) == null ? void 0 : _D.asset) == null ? void 0 : _E._ref.replace("file-", "").replace("-", ".")}`, target: "_blank" }, ((_F = filenames[language]) == null ? void 0 : _F.woff) ? /* @__PURE__ */ React9.createElement("b", null, (_G = filenames[language]) == null ? void 0 : _G.woff) : /* @__PURE__ */ React9.createElement("b", null, "File"))), status === "ready" && /* @__PURE__ */ React9.createElement(Flex6, { gap: 1 }, ((_H = value[language]) == null ? void 0 : _H.ttf) && /* @__PURE__ */ React9.createElement(Button7, { mode: "default", onClick: () => handleGenerateFontFile("woff", value[language].ttf, language) }, "Build"), /* @__PURE__ */ React9.createElement("label", null, /* @__PURE__ */ React9.createElement(Button7, { as: "span", mode: "ghost" }, "Upload"), /* @__PURE__ */ React9.createElement("input", { ref, type: "file", style: { display: "none" }, onChange: async (event) => handleUpload(event, language, "woff") })), ((_I = value[language]) == null ? void 0 : _I.woff) && /* @__PURE__ */ React9.createElement(Button7, { mode: "ghost", tone: "critical", onClick: () => handleDelete("woff", language) }, "\xD7"))), /* @__PURE__ */ React9.createElement(Flex6, { justify: "space-between", align: "center" }, /* @__PURE__ */ React9.createElement(Text8, null, "WOFF2:\xA0", !((_L = (_K = (_J = scriptFileInput[language]) == null ? void 0 : _J.woff2) == null ? void 0 : _K.asset) == null ? void 0 : _L._ref) ? ((_M = filenames[language]) == null ? void 0 : _M.woff2) ? /* @__PURE__ */ React9.createElement("b", null, (_N = filenames[language]) == null ? void 0 : _N.woff2) : /* @__PURE__ */ React9.createElement("b", null, "Empty") : /* @__PURE__ */ React9.createElement("a", { href: `https://cdn.sanity.io/files/${process.env.SANITY_STUDIO_PROJECT_ID}/${process.env.SANITY_STUDIO_DATASET}/${(_Q = (_P = (_O = scriptFileInput[language]) == null ? void 0 : _O.woff2) == null ? void 0 : _P.asset) == null ? void 0 : _Q._ref.replace("file-", "").replace("-", ".")}`, target: "_blank" }, ((_R = filenames[language]) == null ? void 0 : _R.woff2) ? /* @__PURE__ */ React9.createElement("b", null, (_S = filenames[language]) == null ? void 0 : _S.woff2) : /* @__PURE__ */ React9.createElement("b", null, "File"))), status === "ready" && /* @__PURE__ */ React9.createElement(Flex6, { gap: 1 }, ((_T = value[language]) == null ? void 0 : _T.ttf) && /* @__PURE__ */ React9.createElement(Button7, { mode: "default", onClick: () => handleGenerateFontFile("woff2", value[language].ttf, language) }, "Build"), /* @__PURE__ */ React9.createElement("label", null, /* @__PURE__ */ React9.createElement(Button7, { as: "span", mode: "ghost" }, "Upload"), /* @__PURE__ */ React9.createElement("input", { ref, type: "file", style: { display: "none" }, onChange: async (event) => handleUpload(event, language, "woff2") })), ((_U = value[language]) == null ? void 0 : _U.woff2) && /* @__PURE__ */ React9.createElement(Button7, { mode: "ghost", tone: "critical", onClick: () => handleDelete("woff2", language) }, "\xD7"))), /* @__PURE__ */ React9.createElement(Flex6, { justify: "space-between", align: "center" }, /* @__PURE__ */ React9.createElement(Text8, null, "EOT:\xA0", !((_X = (_W = (_V = scriptFileInput[language]) == null ? void 0 : _V.eot) == null ? void 0 : _W.asset) == null ? void 0 : _X._ref) ? ((_Y = filenames[language]) == null ? void 0 : _Y.eot) ? /* @__PURE__ */ React9.createElement("b", null, (_Z = filenames[language]) == null ? void 0 : _Z.eot) : /* @__PURE__ */ React9.createElement("b", null, "Empty") : /* @__PURE__ */ React9.createElement("a", { href: `https://cdn.sanity.io/files/${process.env.SANITY_STUDIO_PROJECT_ID}/${process.env.SANITY_STUDIO_DATASET}/${(_aa = (_$ = (__ = scriptFileInput[language]) == null ? void 0 : __.eot) == null ? void 0 : _$.asset) == null ? void 0 : _aa._ref.replace("file-", "").replace("-", ".")}`, target: "_blank" }, ((_ba = filenames[language]) == null ? void 0 : _ba.eot) ? /* @__PURE__ */ React9.createElement("b", null, (_ca = filenames[language]) == null ? void 0 : _ca.eot) : /* @__PURE__ */ React9.createElement("b", null, "File"))), status === "ready" && /* @__PURE__ */ React9.createElement(Flex6, { gap: 1 }, ((_da = value[language]) == null ? void 0 : _da.ttf) && /* @__PURE__ */ React9.createElement(Button7, { mode: "default", onClick: () => handleGenerateFontFile("eot", value[language].ttf, language) }, "Build"), /* @__PURE__ */ React9.createElement("label", null, /* @__PURE__ */ React9.createElement(Button7, { as: "span", mode: "ghost" }, "Upload"), /* @__PURE__ */ React9.createElement("input", { ref, type: "file", style: { display: "none" }, onChange: async (event) => handleUpload(event, language, "eot") })), ((_ea = value[language]) == null ? void 0 : _ea.eot) && /* @__PURE__ */ React9.createElement(Button7, { mode: "ghost", tone: "critical", onClick: () => handleDelete("eot", language) }, "\xD7"))), /* @__PURE__ */ React9.createElement(Flex6, { justify: "space-between", align: "center" }, /* @__PURE__ */ React9.createElement(Text8, null, "SVG:\xA0", !((_ha = (_ga = (_fa = scriptFileInput[language]) == null ? void 0 : _fa.svg) == null ? void 0 : _ga.asset) == null ? void 0 : _ha._ref) ? ((_ia = filenames[language]) == null ? void 0 : _ia.svg) ? /* @__PURE__ */ React9.createElement("b", null, (_ja = filenames[language]) == null ? void 0 : _ja.svg) : /* @__PURE__ */ React9.createElement("b", null, "Empty") : /* @__PURE__ */ React9.createElement("a", { href: `https://cdn.sanity.io/files/${process.env.SANITY_STUDIO_PROJECT_ID}/${process.env.SANITY_STUDIO_DATASET}/${(_ma = (_la = (_ka = scriptFileInput[language]) == null ? void 0 : _ka.svg) == null ? void 0 : _la.asset) == null ? void 0 : _ma._ref.replace("file-", "").replace("-", ".")}`, target: "_blank" }, ((_na = filenames[language]) == null ? void 0 : _na.svg) ? /* @__PURE__ */ React9.createElement("b", null, (_oa = filenames[language]) == null ? void 0 : _oa.svg) : /* @__PURE__ */ React9.createElement("b", null, "File"))), status === "ready" && /* @__PURE__ */ React9.createElement(Flex6, { gap: 1 }, ((_pa = value[language]) == null ? void 0 : _pa.ttf) && /* @__PURE__ */ React9.createElement(Button7, { mode: "default", onClick: () => handleGenerateFontFile("svg", value[language].ttf, language) }, "Build"), /* @__PURE__ */ React9.createElement("label", null, /* @__PURE__ */ React9.createElement(Button7, { as: "span", mode: "ghost" }, "Upload"), /* @__PURE__ */ React9.createElement("input", { ref, type: "file", style: { display: "none" }, onChange: async (event) => handleUpload(event, language, "svg") })), ((_qa = value[language]) == null ? void 0 : _qa.svg) && /* @__PURE__ */ React9.createElement(Button7, { mode: "ghost", tone: "critical", onClick: () => handleDelete("svg", language) }, "\xD7"))), /* @__PURE__ */ React9.createElement(Flex6, { justify: "space-between", align: "center" }, /* @__PURE__ */ React9.createElement(Text8, null, "CSS:\xA0", !((_ta = (_sa = (_ra = scriptFileInput[language]) == null ? void 0 : _ra.css) == null ? void 0 : _sa.asset) == null ? void 0 : _ta._ref) ? ((_ua = filenames[language]) == null ? void 0 : _ua.css) ? /* @__PURE__ */ React9.createElement("b", null, (_va = filenames[language]) == null ? void 0 : _va.css) : /* @__PURE__ */ React9.createElement("b", null, "Empty") : /* @__PURE__ */ React9.createElement("a", { href: `https://cdn.sanity.io/files/${process.env.SANITY_STUDIO_PROJECT_ID}/${process.env.SANITY_STUDIO_DATASET}/${(_ya = (_xa = (_wa = scriptFileInput[language]) == null ? void 0 : _wa.css) == null ? void 0 : _xa.asset) == null ? void 0 : _ya._ref.replace("file-", "").replace("-", ".")}`, target: "_blank" }, ((_za = filenames[language]) == null ? void 0 : _za.css) ? /* @__PURE__ */ React9.createElement("b", null, (_Aa = filenames[language]) == null ? void 0 : _Aa.css) : /* @__PURE__ */ React9.createElement("b", null, "File"))), status === "ready" && /* @__PURE__ */ React9.createElement(Flex6, { gap: 1 }, ((_Ba = value[language]) == null ? void 0 : _Ba.woff2) && /* @__PURE__ */ React9.createElement(Button7, { mode: "default", onClick: () => handleGenerateCssFile(language) }, "Build"), ((_Ca = value[language]) == null ? void 0 : _Ca.css) && /* @__PURE__ */ React9.createElement(Button7, { mode: "ghost", tone: "critical", onClick: () => handleDelete("css", language) }, "\xD7"))), status === "ready" && (((_Da = value[language]) == null ? void 0 : _Da.ttf) || ((_Ea = value[language]) == null ? void 0 : _Ea.otf) || ((_Fa = value[language]) == null ? void 0 : _Fa.woff) || ((_Ga = value[language]) == null ? void 0 : _Ga.woff2)) && /* @__PURE__ */ React9.createElement(Button7, { mode: "ghost", tone: "critical", onClick: () => handleDeleteAll(language), style: { width: "100%" } }, "Delete All")));
3525
2597
  }));
3526
2598
  };
3527
2599
 
3528
2600
  // src/components/UploadButton.jsx
3529
- import React11, { forwardRef } from "react";
3530
- import { Button as Button8, Text as Text10 } from "@sanity/ui";
2601
+ import React10, { forwardRef } from "react";
2602
+ import { Button as Button8, Text as Text9 } from "@sanity/ui";
3531
2603
  var UploadButton = forwardRef(({ handleUpload }, ref) => {
3532
- return /* @__PURE__ */ React11.createElement(
2604
+ return /* @__PURE__ */ React10.createElement(
3533
2605
  Button8,
3534
2606
  {
3535
2607
  mode: "ghost",
@@ -3538,8 +2610,8 @@ var UploadButton = forwardRef(({ handleUpload }, ref) => {
3538
2610
  padding: 3,
3539
2611
  style: { position: "relative" }
3540
2612
  },
3541
- /* @__PURE__ */ React11.createElement(Text10, { align: "center" }, "Upload (ttf/otf/woff/woff2/etc...)"),
3542
- /* @__PURE__ */ React11.createElement(
2613
+ /* @__PURE__ */ React10.createElement(Text9, { align: "center" }, "Upload (ttf/otf/woff/woff2/etc...)"),
2614
+ /* @__PURE__ */ React10.createElement(
3543
2615
  "input",
3544
2616
  {
3545
2617
  ref,
@@ -3563,7 +2635,7 @@ UploadButton.displayName = "UploadButton";
3563
2635
  var UploadButton_default = UploadButton;
3564
2636
 
3565
2637
  // src/components/KeyValueInput.jsx
3566
- import React12, { useState as useState8, useCallback as useCallback7 } from "react";
2638
+ import React11, { useState as useState8, useCallback as useCallback7 } from "react";
3567
2639
  import { Button as Button9, Grid as Grid5, Stack as Stack8, TextInput as TextInput2 } from "@sanity/ui";
3568
2640
  import { AddIcon, ArrowDownIcon, ArrowUpIcon, TrashIcon as TrashIcon3 } from "@sanity/icons";
3569
2641
  import { set as set4 } from "sanity";
@@ -3599,37 +2671,37 @@ function KeyValueInput({ value = [], onChange }) {
3599
2671
  setPairs(updatedPairs);
3600
2672
  onChange(set4(updatedPairs));
3601
2673
  }, [pairs, onChange]);
3602
- return /* @__PURE__ */ React12.createElement(Stack8, { space: 3 }, pairs.map((pair, index) => /* @__PURE__ */ React12.createElement(Grid5, { className: "manualButtonWrap", columns: [2], key: index, gap: 0, style: { position: "relative" } }, /* @__PURE__ */ React12.createElement("div", { style: { position: "absolute", height: "100%", top: "0", left: "-10px", width: "min-content", transform: "translate(-100%, 0%)" } }, /* @__PURE__ */ React12.createElement("button", { className: "manualButton manualButtonUp", style: { fontSize: "15px", height: "50%" }, onClick: () => handleMoveUp(index) }, /* @__PURE__ */ React12.createElement(ArrowUpIcon, null)), /* @__PURE__ */ React12.createElement("button", { className: "manualButton manualButtonDown", style: { fontSize: "15px", height: "50%" }, onClick: () => handleMoveDown(index) }, /* @__PURE__ */ React12.createElement(ArrowDownIcon, null))), /* @__PURE__ */ React12.createElement(
2674
+ return /* @__PURE__ */ React11.createElement(Stack8, { space: 3 }, pairs.map((pair, index) => /* @__PURE__ */ React11.createElement(Grid5, { className: "manualButtonWrap", columns: [2], key: index, gap: 0, style: { position: "relative" } }, /* @__PURE__ */ React11.createElement("div", { style: { position: "absolute", height: "100%", top: "0", left: "-10px", width: "min-content", transform: "translate(-100%, 0%)" } }, /* @__PURE__ */ React11.createElement("button", { className: "manualButton manualButtonUp", style: { fontSize: "15px", height: "50%" }, onClick: () => handleMoveUp(index) }, /* @__PURE__ */ React11.createElement(ArrowUpIcon, null)), /* @__PURE__ */ React11.createElement("button", { className: "manualButton manualButtonDown", style: { fontSize: "15px", height: "50%" }, onClick: () => handleMoveDown(index) }, /* @__PURE__ */ React11.createElement(ArrowDownIcon, null))), /* @__PURE__ */ React11.createElement(
3603
2675
  TextInput2,
3604
2676
  {
3605
2677
  value: pair.key,
3606
2678
  onChange: (e) => handlePairChange(index, "key", e.target.value),
3607
2679
  placeholder: "Key"
3608
2680
  }
3609
- ), /* @__PURE__ */ React12.createElement("div", { style: { marginLeft: "-1px" } }, /* @__PURE__ */ React12.createElement(
2681
+ ), /* @__PURE__ */ React11.createElement("div", { style: { marginLeft: "-1px" } }, /* @__PURE__ */ React11.createElement(
3610
2682
  TextInput2,
3611
2683
  {
3612
2684
  value: pair.value,
3613
2685
  onChange: (e) => handlePairChange(index, "value", e.target.value),
3614
2686
  placeholder: "Value"
3615
2687
  }
3616
- )), /* @__PURE__ */ React12.createElement(
2688
+ )), /* @__PURE__ */ React11.createElement(
3617
2689
  "button",
3618
2690
  {
3619
2691
  className: "manualButton",
3620
2692
  onClick: () => handleRemovePair(index),
3621
2693
  style: { position: "absolute", top: "0", right: "-10px", transform: "translate(100%, 0%)" }
3622
2694
  },
3623
- /* @__PURE__ */ React12.createElement(TrashIcon3, null)
3624
- ))), /* @__PURE__ */ React12.createElement(Button9, { tone: "primary", onClick: handleAddPair, icon: AddIcon, text: "Add Row" }));
2695
+ /* @__PURE__ */ React11.createElement(TrashIcon3, null)
2696
+ ))), /* @__PURE__ */ React11.createElement(Button9, { tone: "primary", onClick: handleAddPair, icon: AddIcon, text: "Add Row" }));
3625
2697
  }
3626
2698
 
3627
2699
  // src/components/KeyValueReferenceInput.jsx
3628
- import React13, { useState as useState9, useCallback as useCallback8, useEffect as useEffect6 } from "react";
3629
- import { Button as Button10, Stack as Stack9, TextInput as TextInput3, Box as Box4, Card as Card4, Flex as Flex8, Text as Text11, Dialog, Menu as Menu2, MenuButton as MenuButton2, MenuItem as MenuItem2, Autocomplete } from "@sanity/ui";
2700
+ import React12, { useState as useState9, useCallback as useCallback8, useEffect as useEffect6 } from "react";
2701
+ import { Button as Button10, Stack as Stack9, TextInput as TextInput3, Box as Box4, Card as Card4, Flex as Flex7, Text as Text10, Dialog, Menu as Menu2, MenuButton as MenuButton2, MenuItem as MenuItem2, Autocomplete } from "@sanity/ui";
3630
2702
  import { AddIcon as AddIcon2, ArrowDownIcon as ArrowDownIcon2, ArrowUpIcon as ArrowUpIcon2, TrashIcon as TrashIcon4, SyncIcon, EllipsisHorizontalIcon } from "@sanity/icons";
3631
2703
  import { set as set5, useFormValue as useFormValue8 } from "sanity";
3632
- import { nanoid as nanoid8 } from "nanoid";
2704
+ import { nanoid as nanoid5 } from "nanoid";
3633
2705
  function KeyValueReferenceInput(props) {
3634
2706
  var _a, _b, _c, _d, _e, _f, _g, _h;
3635
2707
  const { value = [], onChange, schemaType, referenceType, fetchReferences, topActions } = props;
@@ -3675,7 +2747,7 @@ function KeyValueReferenceInput(props) {
3675
2747
  onChange(set5(updatedPairs));
3676
2748
  }, [pairs, onChange]);
3677
2749
  const handleAddPair = useCallback8(() => {
3678
- const updatedPairs = [...pairs, { key: "", value: null, _key: nanoid8() }];
2750
+ const updatedPairs = [...pairs, { key: "", value: null, _key: nanoid5() }];
3679
2751
  setPairs(updatedPairs);
3680
2752
  onChange(set5(updatedPairs));
3681
2753
  }, [pairs, onChange]);
@@ -3736,48 +2808,48 @@ function KeyValueReferenceInput(props) {
3736
2808
  const valueTitle = (valueField == null ? void 0 : valueField.title) || "Value";
3737
2809
  const keyPlaceholder = (keyField == null ? void 0 : keyField.placeholder) || "Enter key";
3738
2810
  const pickerLabel = referenceType || valueTitle.toLowerCase();
3739
- return /* @__PURE__ */ React13.createElement(Stack9, { space: 3 }, topActions && /* @__PURE__ */ React13.createElement(Box4, { paddingBottom: 2 }, topActions), /* @__PURE__ */ React13.createElement(Box4, null, /* @__PURE__ */ React13.createElement(Stack9, { space: 2 }, pairs.map((pair, index) => {
2811
+ return /* @__PURE__ */ React12.createElement(Stack9, { space: 3 }, topActions && /* @__PURE__ */ React12.createElement(Box4, { paddingBottom: 2 }, topActions), /* @__PURE__ */ React12.createElement(Box4, null, /* @__PURE__ */ React12.createElement(Stack9, { space: 2 }, pairs.map((pair, index) => {
3740
2812
  var _a2;
3741
- return /* @__PURE__ */ React13.createElement(Box4, { key: index, style: { position: "relative" } }, /* @__PURE__ */ React13.createElement("div", { style: { position: "absolute", height: "100%", top: "0", left: "-5px", width: "min-content", transform: "translate(-100%, 0%)" } }, /* @__PURE__ */ React13.createElement("button", { className: "manualButton manualButtonUp", style: { fontSize: "15px", height: "50%" }, onClick: () => handleMoveUp(index) }, /* @__PURE__ */ React13.createElement(ArrowUpIcon2, null)), /* @__PURE__ */ React13.createElement("button", { className: "manualButton manualButtonDown", style: { fontSize: "15px", height: "50%" }, onClick: () => handleMoveDown(index) }, /* @__PURE__ */ React13.createElement(ArrowDownIcon2, null))), /* @__PURE__ */ React13.createElement(Flex8, { gap: 2, align: "flex-start" }, /* @__PURE__ */ React13.createElement(Box4, { flex: 1 }, /* @__PURE__ */ React13.createElement(
2813
+ return /* @__PURE__ */ React12.createElement(Box4, { key: index, style: { position: "relative" } }, /* @__PURE__ */ React12.createElement("div", { style: { position: "absolute", height: "100%", top: "0", left: "-5px", width: "min-content", transform: "translate(-100%, 0%)" } }, /* @__PURE__ */ React12.createElement("button", { className: "manualButton manualButtonUp", style: { fontSize: "15px", height: "50%" }, onClick: () => handleMoveUp(index) }, /* @__PURE__ */ React12.createElement(ArrowUpIcon2, null)), /* @__PURE__ */ React12.createElement("button", { className: "manualButton manualButtonDown", style: { fontSize: "15px", height: "50%" }, onClick: () => handleMoveDown(index) }, /* @__PURE__ */ React12.createElement(ArrowDownIcon2, null))), /* @__PURE__ */ React12.createElement(Flex7, { gap: 2, align: "flex-start" }, /* @__PURE__ */ React12.createElement(Box4, { flex: 1 }, /* @__PURE__ */ React12.createElement(
3742
2814
  TextInput3,
3743
2815
  {
3744
2816
  value: pair.key,
3745
2817
  onChange: (e) => handlePairChange(index, "key", e.target.value),
3746
2818
  placeholder: keyPlaceholder
3747
2819
  }
3748
- )), /* @__PURE__ */ React13.createElement(Box4, { flex: 1, style: { minHeight: "100%" } }, ((_a2 = pair.value) == null ? void 0 : _a2._ref) ? /* @__PURE__ */ React13.createElement(Card4, { className: "referenceCard", radius: 2, tone: "primary", style: { paddingLeft: "1rem", height: "fit-content" } }, /* @__PURE__ */ React13.createElement(Flex8, { align: "center", justify: "space-between" }, /* @__PURE__ */ React13.createElement(
3749
- Text11,
2820
+ )), /* @__PURE__ */ React12.createElement(Box4, { flex: 1, style: { minHeight: "100%" } }, ((_a2 = pair.value) == null ? void 0 : _a2._ref) ? /* @__PURE__ */ React12.createElement(Card4, { className: "referenceCard", radius: 2, tone: "primary", style: { paddingLeft: "1rem", height: "fit-content" } }, /* @__PURE__ */ React12.createElement(Flex7, { align: "center", justify: "space-between" }, /* @__PURE__ */ React12.createElement(
2821
+ Text10,
3750
2822
  {
3751
2823
  size: 2,
3752
2824
  style: { whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis", maxWidth: "90%" }
3753
2825
  },
3754
2826
  referenceData[pair.value._ref] || "Loading..."
3755
- ), /* @__PURE__ */ React13.createElement(
2827
+ ), /* @__PURE__ */ React12.createElement(
3756
2828
  MenuButton2,
3757
2829
  {
3758
- button: /* @__PURE__ */ React13.createElement(Button10, { icon: EllipsisHorizontalIcon, mode: "bleed", title: "Options" }),
2830
+ button: /* @__PURE__ */ React12.createElement(Button10, { icon: EllipsisHorizontalIcon, mode: "bleed", title: "Options" }),
3759
2831
  id: `ref-options-${index}`,
3760
- menu: /* @__PURE__ */ React13.createElement(Menu2, null, /* @__PURE__ */ React13.createElement(MenuItem2, { tone: "critical", icon: TrashIcon4, text: "Remove", onClick: () => handlePairChange(index, "value", null) }), /* @__PURE__ */ React13.createElement(MenuItem2, { icon: SyncIcon, text: "Replace", onClick: () => openReferenceSelector(index) })),
2832
+ menu: /* @__PURE__ */ React12.createElement(Menu2, null, /* @__PURE__ */ React12.createElement(MenuItem2, { tone: "critical", icon: TrashIcon4, text: "Remove", onClick: () => handlePairChange(index, "value", null) }), /* @__PURE__ */ React12.createElement(MenuItem2, { icon: SyncIcon, text: "Replace", onClick: () => openReferenceSelector(index) })),
3761
2833
  popover: { portal: true, tone: "default", placement: "left" }
3762
2834
  }
3763
- ))) : /* @__PURE__ */ React13.createElement(
2835
+ ))) : /* @__PURE__ */ React12.createElement(
3764
2836
  Box4,
3765
2837
  {
3766
2838
  padding: 2,
3767
2839
  style: { minHeight: "100%", border: "1px dashed #ccc", borderRadius: "4px", display: "flex", alignItems: "center", justifyContent: "center", cursor: "pointer" },
3768
2840
  onClick: () => openReferenceSelector(index)
3769
2841
  },
3770
- /* @__PURE__ */ React13.createElement(Text11, { muted: true, size: 2 }, "Click to select a ", pickerLabel)
3771
- ))), /* @__PURE__ */ React13.createElement(
2842
+ /* @__PURE__ */ React12.createElement(Text10, { muted: true, size: 2 }, "Click to select a ", pickerLabel)
2843
+ ))), /* @__PURE__ */ React12.createElement(
3772
2844
  "button",
3773
2845
  {
3774
2846
  className: "manualButton",
3775
2847
  onClick: () => handleRemovePair(index),
3776
2848
  style: { position: "absolute", top: "0", right: "-7px", transform: "translate(100%, 0%)" }
3777
2849
  },
3778
- /* @__PURE__ */ React13.createElement(TrashIcon4, null)
2850
+ /* @__PURE__ */ React12.createElement(TrashIcon4, null)
3779
2851
  ));
3780
- }))), /* @__PURE__ */ React13.createElement(Button10, { tone: "primary", mode: "ghost", onClick: handleAddPair, icon: AddIcon2, text: `Add ${keyTitle}` }), isDialogOpen && /* @__PURE__ */ React13.createElement(
2852
+ }))), /* @__PURE__ */ React12.createElement(Button10, { tone: "primary", mode: "ghost", onClick: handleAddPair, icon: AddIcon2, text: `Add ${keyTitle}` }), isDialogOpen && /* @__PURE__ */ React12.createElement(
3781
2853
  Dialog,
3782
2854
  {
3783
2855
  header: `Select a ${pickerLabel}`,
@@ -3785,13 +2857,13 @@ function KeyValueReferenceInput(props) {
3785
2857
  onClose: closeDialog,
3786
2858
  width: 1
3787
2859
  },
3788
- /* @__PURE__ */ React13.createElement(Box4, { padding: 4 }, /* @__PURE__ */ React13.createElement(
2860
+ /* @__PURE__ */ React12.createElement(Box4, { padding: 4 }, /* @__PURE__ */ React12.createElement(
3789
2861
  Autocomplete,
3790
2862
  {
3791
2863
  id: "reference-autocomplete",
3792
2864
  options: referenceOptions,
3793
2865
  placeholder: `Search ${pickerLabel}s...`,
3794
- renderOption: (option) => /* @__PURE__ */ React13.createElement(Card4, { key: option.value, padding: 3, radius: 2, tone: "default", style: { cursor: "pointer" } }, /* @__PURE__ */ React13.createElement(Text11, { size: 2 }, option.title)),
2866
+ renderOption: (option) => /* @__PURE__ */ React12.createElement(Card4, { key: option.value, padding: 3, radius: 2, tone: "default", style: { cursor: "pointer" } }, /* @__PURE__ */ React12.createElement(Text10, { size: 2 }, option.title)),
3795
2867
  renderValue: (val) => {
3796
2868
  var _a2;
3797
2869
  return ((_a2 = referenceOptions.find((o) => o.value === val)) == null ? void 0 : _a2.title) || "";
@@ -3808,11 +2880,11 @@ function KeyValueReferenceInput(props) {
3808
2880
  }
3809
2881
 
3810
2882
  // src/components/VariableInstanceReferencesInput.jsx
3811
- import React14, { useState as useState10, useCallback as useCallback9 } from "react";
3812
- import { Button as Button11, Flex as Flex9, Dialog as Dialog2, Box as Box5, Stack as Stack10, Text as Text12 } from "@sanity/ui";
2883
+ import React13, { useState as useState10, useCallback as useCallback9 } from "react";
2884
+ import { Button as Button11, Flex as Flex8, Dialog as Dialog2, Box as Box5, Stack as Stack10, Text as Text11 } from "@sanity/ui";
3813
2885
  import { SyncIcon as SyncIcon2, DocumentTextIcon } from "@sanity/icons";
3814
2886
  import { set as set6, useFormValue as useFormValue9 } from "sanity";
3815
- import { nanoid as nanoid9 } from "nanoid";
2887
+ import { nanoid as nanoid6 } from "nanoid";
3816
2888
  function VariableInstanceReferencesInput(props) {
3817
2889
  const { value = [], onChange } = props;
3818
2890
  const [isAutofilling, setIsAutofilling] = useState10(false);
@@ -3869,7 +2941,7 @@ function VariableInstanceReferencesInput(props) {
3869
2941
  console.warn("No variable instances found in JSON");
3870
2942
  return;
3871
2943
  }
3872
- const keyOnlyPairs = keys.map((key) => ({ key, value: null, _key: nanoid9() }));
2944
+ const keyOnlyPairs = keys.map((key) => ({ key, value: null, _key: nanoid6() }));
3873
2945
  const updatedPairs = mode === "replace" ? keyOnlyPairs : [...value, ...keyOnlyPairs.filter((p) => !value.some((existing) => existing.key === p.key))];
3874
2946
  onChange(set6(updatedPairs));
3875
2947
  } catch (err) {
@@ -3905,7 +2977,7 @@ function VariableInstanceReferencesInput(props) {
3905
2977
  setPendingAction(null);
3906
2978
  }, []);
3907
2979
  const showAutofill = !!((formDocument == null ? void 0 : formDocument.variableFont) && (formDocument == null ? void 0 : formDocument.variableInstances));
3908
- const topActions = showAutofill ? /* @__PURE__ */ React14.createElement(Flex9, { gap: 2 }, /* @__PURE__ */ React14.createElement(
2980
+ const topActions = showAutofill ? /* @__PURE__ */ React13.createElement(Flex8, { gap: 2 }, /* @__PURE__ */ React13.createElement(
3909
2981
  Button11,
3910
2982
  {
3911
2983
  tone: "primary",
@@ -3916,7 +2988,7 @@ function VariableInstanceReferencesInput(props) {
3916
2988
  disabled: isAutofilling,
3917
2989
  loading: isAutofilling
3918
2990
  }
3919
- ), /* @__PURE__ */ React14.createElement(
2991
+ ), /* @__PURE__ */ React13.createElement(
3920
2992
  Button11,
3921
2993
  {
3922
2994
  tone: "default",
@@ -3928,7 +3000,7 @@ function VariableInstanceReferencesInput(props) {
3928
3000
  loading: isAutofilling
3929
3001
  }
3930
3002
  )) : null;
3931
- return /* @__PURE__ */ React14.createElement(React14.Fragment, null, /* @__PURE__ */ React14.createElement(
3003
+ return /* @__PURE__ */ React13.createElement(React13.Fragment, null, /* @__PURE__ */ React13.createElement(
3932
3004
  KeyValueReferenceInput,
3933
3005
  {
3934
3006
  ...props,
@@ -3936,7 +3008,7 @@ function VariableInstanceReferencesInput(props) {
3936
3008
  fetchReferences,
3937
3009
  topActions
3938
3010
  }
3939
- ), showConfirmDialog && /* @__PURE__ */ React14.createElement(
3011
+ ), showConfirmDialog && /* @__PURE__ */ React13.createElement(
3940
3012
  Dialog2,
3941
3013
  {
3942
3014
  header: "Existing entries found",
@@ -3944,15 +3016,15 @@ function VariableInstanceReferencesInput(props) {
3944
3016
  onClose: handleConfirmCancel,
3945
3017
  width: 1
3946
3018
  },
3947
- /* @__PURE__ */ React14.createElement(Box5, { padding: 4 }, /* @__PURE__ */ React14.createElement(Stack10, { space: 4 }, /* @__PURE__ */ React14.createElement(Text12, null, "You already have ", value.length, " ", value.length === 1 ? "entry" : "entries", ". How would you like to proceed?"), /* @__PURE__ */ React14.createElement(Flex9, { gap: 2, justify: "flex-end" }, /* @__PURE__ */ React14.createElement(Button11, { text: "Cancel", mode: "ghost", onClick: handleConfirmCancel }), /* @__PURE__ */ React14.createElement(Button11, { text: "Merge (Add New)", tone: "primary", mode: "ghost", onClick: () => handleConfirmChoice("merge") }), /* @__PURE__ */ React14.createElement(Button11, { text: "Replace All", tone: "critical", onClick: () => handleConfirmChoice("replace") }))))
3019
+ /* @__PURE__ */ React13.createElement(Box5, { padding: 4 }, /* @__PURE__ */ React13.createElement(Stack10, { space: 4 }, /* @__PURE__ */ React13.createElement(Text11, null, "You already have ", value.length, " ", value.length === 1 ? "entry" : "entries", ". How would you like to proceed?"), /* @__PURE__ */ React13.createElement(Flex8, { gap: 2, justify: "flex-end" }, /* @__PURE__ */ React13.createElement(Button11, { text: "Cancel", mode: "ghost", onClick: handleConfirmCancel }), /* @__PURE__ */ React13.createElement(Button11, { text: "Merge (Add New)", tone: "primary", mode: "ghost", onClick: () => handleConfirmChoice("merge") }), /* @__PURE__ */ React13.createElement(Button11, { text: "Replace All", tone: "critical", onClick: () => handleConfirmChoice("replace") }))))
3948
3020
  ));
3949
3021
  }
3950
3022
 
3951
3023
  // src/components/PrimaryCollectionGeneratorTypeface.jsx
3952
- import React15, { useCallback as useCallback10, useState as useState11 } from "react";
3953
- import { Stack as Stack11, Flex as Flex10, Text as Text13, Button as Button12, Card as Card5, Spinner as Spinner3 } from "@sanity/ui";
3024
+ import React14, { useCallback as useCallback10, useState as useState11 } from "react";
3025
+ import { Stack as Stack11, Flex as Flex9, Text as Text12, Button as Button12, Card as Card5, Spinner as Spinner3 } from "@sanity/ui";
3954
3026
  import { useFormValue as useFormValue10 } from "sanity";
3955
- import { nanoid as nanoid10 } from "nanoid";
3027
+ import { nanoid as nanoid7 } from "nanoid";
3956
3028
  var PrimaryCollectionGeneratorTypeface = () => {
3957
3029
  const client = useSanityClient();
3958
3030
  const [status, setStatus] = useState11("ready");
@@ -3972,7 +3044,7 @@ var PrimaryCollectionGeneratorTypeface = () => {
3972
3044
  if (!id.includes("collection")) id += "-collection";
3973
3045
  const colTitle = id.replace(/-/g, " ").replace(/\b\w/g, (l) => l.toUpperCase());
3974
3046
  const collectionDoc = {
3975
- _key: nanoid10(),
3047
+ _key: nanoid7(),
3976
3048
  _id: id,
3977
3049
  title: colTitle,
3978
3050
  slug: { _type: "slug", current: id },
@@ -3990,7 +3062,7 @@ var PrimaryCollectionGeneratorTypeface = () => {
3990
3062
  ...styles,
3991
3063
  collections: [{
3992
3064
  _type: "reference",
3993
- _key: nanoid10(),
3065
+ _key: nanoid7(),
3994
3066
  _ref: sanityCollection._id,
3995
3067
  _weak: true
3996
3068
  }, ...collections]
@@ -4004,7 +3076,7 @@ var PrimaryCollectionGeneratorTypeface = () => {
4004
3076
  setReady(true);
4005
3077
  }, [docId, fonts, price, preferredStyle, styles, title, client]);
4006
3078
  if (!title || !fonts) return null;
4007
- return /* @__PURE__ */ React15.createElement(Stack11, { space: 2 }, /* @__PURE__ */ React15.createElement(StatusDisplay_default, { status, error: false }), /* @__PURE__ */ React15.createElement(Card5, { border: true, padding: 2, shadow: 1, radius: 2 }, ready ? /* @__PURE__ */ React15.createElement(Stack11, { space: 3 }, /* @__PURE__ */ React15.createElement(Flex10, { align: "center", gap: 2, marginTop: 1, marginBottom: 1 }, /* @__PURE__ */ React15.createElement(Text13, { size: 1, muted: true }, "Price"), /* @__PURE__ */ React15.createElement(Text13, { size: 1, muted: true }, "$"), /* @__PURE__ */ React15.createElement(
3079
+ return /* @__PURE__ */ React14.createElement(Stack11, { space: 2 }, /* @__PURE__ */ React14.createElement(StatusDisplay_default, { status, error: false }), /* @__PURE__ */ React14.createElement(Card5, { border: true, padding: 2, shadow: 1, radius: 2 }, ready ? /* @__PURE__ */ React14.createElement(Stack11, { space: 3 }, /* @__PURE__ */ React14.createElement(Flex9, { align: "center", gap: 2, marginTop: 1, marginBottom: 1 }, /* @__PURE__ */ React14.createElement(Text12, { size: 1, muted: true }, "Price"), /* @__PURE__ */ React14.createElement(Text12, { size: 1, muted: true }, "$"), /* @__PURE__ */ React14.createElement(
4008
3080
  "input",
4009
3081
  {
4010
3082
  value: price,
@@ -4012,7 +3084,7 @@ var PrimaryCollectionGeneratorTypeface = () => {
4012
3084
  type: "number",
4013
3085
  style: { textAlign: "end", padding: "5px", maxWidth: "75px" }
4014
3086
  }
4015
- ), /* @__PURE__ */ React15.createElement(Text13, { size: 1, muted: true }, "per full family")), /* @__PURE__ */ React15.createElement(
3087
+ ), /* @__PURE__ */ React14.createElement(Text12, { size: 1, muted: true }, "per full family")), /* @__PURE__ */ React14.createElement(
4016
3088
  Button12,
4017
3089
  {
4018
3090
  mode: "ghost",
@@ -4021,13 +3093,13 @@ var PrimaryCollectionGeneratorTypeface = () => {
4021
3093
  onClick: generateCollection,
4022
3094
  text: "Generate Full Family Collection"
4023
3095
  }
4024
- )) : /* @__PURE__ */ React15.createElement(Flex10, { align: "center", justify: "center", gap: 3, padding: 4 }, /* @__PURE__ */ React15.createElement(Spinner3, null), /* @__PURE__ */ React15.createElement(Text13, { muted: true, size: 1 }, status))));
3096
+ )) : /* @__PURE__ */ React14.createElement(Flex9, { align: "center", justify: "center", gap: 3, padding: 4 }, /* @__PURE__ */ React14.createElement(Spinner3, null), /* @__PURE__ */ React14.createElement(Text12, { muted: true, size: 1 }, status))));
4025
3097
  };
4026
3098
 
4027
3099
  // src/components/SetOTF.jsx
4028
- import React16, { useState as useState12 } from "react";
3100
+ import React15, { useState as useState12 } from "react";
4029
3101
  import { set as set7, useFormValue as useFormValue11 } from "sanity";
4030
- import { Stack as Stack12, Button as Button13, Text as Text14 } from "@sanity/ui";
3102
+ import { Stack as Stack12, Button as Button13, Text as Text13 } from "@sanity/ui";
4031
3103
  var SetOTF = (props) => {
4032
3104
  var _a, _b;
4033
3105
  const { onChange, value = {} } = props;
@@ -4076,7 +3148,7 @@ var SetOTF = (props) => {
4076
3148
  console.error("SetOTF detect error:", err);
4077
3149
  }
4078
3150
  };
4079
- return /* @__PURE__ */ React16.createElement(Stack12, { className: "openType" }, ((_a = value == null ? void 0 : value.features) == null ? void 0 : _a.length) > 0 && /* @__PURE__ */ React16.createElement(Text14, { muted: true, size: 1, style: { marginBottom: "0.5rem" } }, "Number of features: ", value.features.length), !!((_b = stylesObject == null ? void 0 : stylesObject.fonts) == null ? void 0 : _b.length) && /* @__PURE__ */ React16.createElement(
3151
+ return /* @__PURE__ */ React15.createElement(Stack12, { className: "openType" }, ((_a = value == null ? void 0 : value.features) == null ? void 0 : _a.length) > 0 && /* @__PURE__ */ React15.createElement(Text13, { muted: true, size: 1, style: { marginBottom: "0.5rem" } }, "Number of features: ", value.features.length), !!((_b = stylesObject == null ? void 0 : stylesObject.fonts) == null ? void 0 : _b.length) && /* @__PURE__ */ React15.createElement(
4080
3152
  Button13,
4081
3153
  {
4082
3154
  text: "Detect OTF",
@@ -4084,23 +3156,23 @@ var SetOTF = (props) => {
4084
3156
  onClick: detect,
4085
3157
  style: { borderRadius: "0 3px 0 0", marginBottom: "1rem" }
4086
3158
  }
4087
- ), !!message && /* @__PURE__ */ React16.createElement(Text14, { muted: true, size: 1 }, /* @__PURE__ */ React16.createElement("br", null), message, /* @__PURE__ */ React16.createElement("br", null), /* @__PURE__ */ React16.createElement("br", null)), props.renderDefault(props));
3159
+ ), !!message && /* @__PURE__ */ React15.createElement(Text13, { muted: true, size: 1 }, /* @__PURE__ */ React15.createElement("br", null), message, /* @__PURE__ */ React15.createElement("br", null), /* @__PURE__ */ React15.createElement("br", null)), props.renderDefault(props));
4088
3160
  };
4089
3161
 
4090
3162
  // src/components/StyleCountInput.jsx
4091
- import React17 from "react";
4092
- import { Text as Text15 } from "@sanity/ui";
3163
+ import React16 from "react";
3164
+ import { Text as Text14 } from "@sanity/ui";
4093
3165
  import { useFormValue as useFormValue12 } from "sanity";
4094
3166
  var StyleCountInput = (props) => {
4095
3167
  const styles = useFormValue12(["styles", "fonts"]) || [];
4096
3168
  const vfStyles = useFormValue12(["styles", "variableFont"]) || [];
4097
3169
  const count = styles.length + vfStyles.length;
4098
- return /* @__PURE__ */ React17.createElement(Text15, { size: 1 }, count);
3170
+ return /* @__PURE__ */ React16.createElement(Text14, { size: 1 }, count);
4099
3171
  };
4100
3172
 
4101
3173
  // src/components/NestedObjectArraySelector.jsx
4102
- import React18, { useMemo as useMemo5, useState as useState14 } from "react";
4103
- import { Stack as Stack13, Card as Card6, Text as Text16, Checkbox, Box as Box6, Spinner as Spinner4, Flex as Flex11 } from "@sanity/ui";
3174
+ import React17, { useMemo as useMemo5, useState as useState14 } from "react";
3175
+ import { Stack as Stack13, Card as Card6, Text as Text15, Checkbox, Box as Box6, Spinner as Spinner4, Flex as Flex10 } from "@sanity/ui";
4104
3176
 
4105
3177
  // src/hooks/useNestedObjects.js
4106
3178
  import { useState as useState13, useEffect as useEffect7 } from "react";
@@ -4172,7 +3244,7 @@ function useNestedObjects({
4172
3244
 
4173
3245
  // src/components/NestedObjectArraySelector.jsx
4174
3246
  import { set as set8, unset as unset3 } from "sanity";
4175
- var NestedObjectArraySelector = React18.forwardRef((props, ref) => {
3247
+ var NestedObjectArraySelector = React17.forwardRef((props, ref) => {
4176
3248
  const { value = [], onChange, schemaType } = props;
4177
3249
  const options = (schemaType == null ? void 0 : schemaType.options) || {};
4178
3250
  const {
@@ -4206,18 +3278,18 @@ var NestedObjectArraySelector = React18.forwardRef((props, ref) => {
4206
3278
  }
4207
3279
  };
4208
3280
  if (!sourceType || !nestedField || !titleField || !valueField) {
4209
- return /* @__PURE__ */ React18.createElement(Card6, { padding: 3, tone: "critical", border: true }, /* @__PURE__ */ React18.createElement(Text16, { size: 1 }, "Configuration error: Missing required options (sourceType, nestedField, titleField, or valueField)"));
3281
+ return /* @__PURE__ */ React17.createElement(Card6, { padding: 3, tone: "critical", border: true }, /* @__PURE__ */ React17.createElement(Text15, { size: 1 }, "Configuration error: Missing required options (sourceType, nestedField, titleField, or valueField)"));
4210
3282
  }
4211
3283
  if (loading) {
4212
- return /* @__PURE__ */ React18.createElement(Card6, { padding: 3, border: true }, /* @__PURE__ */ React18.createElement(Flex11, { align: "center", justify: "center", padding: 4 }, /* @__PURE__ */ React18.createElement(Spinner4, null), /* @__PURE__ */ React18.createElement(Box6, { marginLeft: 3 }, /* @__PURE__ */ React18.createElement(Text16, { size: 1 }, "Loading options..."))));
3284
+ return /* @__PURE__ */ React17.createElement(Card6, { padding: 3, border: true }, /* @__PURE__ */ React17.createElement(Flex10, { align: "center", justify: "center", padding: 4 }, /* @__PURE__ */ React17.createElement(Spinner4, null), /* @__PURE__ */ React17.createElement(Box6, { marginLeft: 3 }, /* @__PURE__ */ React17.createElement(Text15, { size: 1 }, "Loading options..."))));
4213
3285
  }
4214
3286
  if (error) {
4215
- return /* @__PURE__ */ React18.createElement(Card6, { padding: 3, tone: "critical", border: true }, /* @__PURE__ */ React18.createElement(Text16, { size: 1 }, "Error loading options: ", error.message));
3287
+ return /* @__PURE__ */ React17.createElement(Card6, { padding: 3, tone: "critical", border: true }, /* @__PURE__ */ React17.createElement(Text15, { size: 1 }, "Error loading options: ", error.message));
4216
3288
  }
4217
3289
  if (objects.length === 0) {
4218
- return /* @__PURE__ */ React18.createElement(Card6, { padding: 3, tone: "transparent", border: true }, /* @__PURE__ */ React18.createElement(Text16, { size: 1, muted: true }, emptyMessage));
3290
+ return /* @__PURE__ */ React17.createElement(Card6, { padding: 3, tone: "transparent", border: true }, /* @__PURE__ */ React17.createElement(Text15, { size: 1, muted: true }, emptyMessage));
4219
3291
  }
4220
- return /* @__PURE__ */ React18.createElement(Card6, { padding: 0, border: true, ref }, objects.length > 5 && /* @__PURE__ */ React18.createElement(Box6, { padding: 3, style: { borderBottom: "1px solid var(--card-border-color)" } }, /* @__PURE__ */ React18.createElement(
3292
+ return /* @__PURE__ */ React17.createElement(Card6, { padding: 0, border: true, ref }, objects.length > 5 && /* @__PURE__ */ React17.createElement(Box6, { padding: 3, style: { borderBottom: "1px solid var(--card-border-color)" } }, /* @__PURE__ */ React17.createElement(
4221
3293
  "input",
4222
3294
  {
4223
3295
  type: "text",
@@ -4226,10 +3298,10 @@ var NestedObjectArraySelector = React18.forwardRef((props, ref) => {
4226
3298
  onChange: (e) => setSearchTerm(e.target.value),
4227
3299
  style: { width: "100%", padding: "8px 12px", border: "1px solid var(--card-border-color)", borderRadius: "4px", fontSize: "13px", fontFamily: "inherit" }
4228
3300
  }
4229
- )), /* @__PURE__ */ React18.createElement(Stack13, { space: 0 }, filteredObjects.length === 0 ? /* @__PURE__ */ React18.createElement(Box6, { padding: 3 }, /* @__PURE__ */ React18.createElement(Text16, { size: 1, muted: true }, 'No results found for "', searchTerm, '"')) : filteredObjects.map((obj, index) => {
3301
+ )), /* @__PURE__ */ React17.createElement(Stack13, { space: 0 }, filteredObjects.length === 0 ? /* @__PURE__ */ React17.createElement(Box6, { padding: 3 }, /* @__PURE__ */ React17.createElement(Text15, { size: 1, muted: true }, 'No results found for "', searchTerm, '"')) : filteredObjects.map((obj, index) => {
4230
3302
  const isSelected = value == null ? void 0 : value.includes(obj.value);
4231
3303
  const isLast = index === filteredObjects.length - 1;
4232
- return /* @__PURE__ */ React18.createElement(
3304
+ return /* @__PURE__ */ React17.createElement(
4233
3305
  Box6,
4234
3306
  {
4235
3307
  key: obj.value,
@@ -4237,28 +3309,28 @@ var NestedObjectArraySelector = React18.forwardRef((props, ref) => {
4237
3309
  style: { borderBottom: isLast ? "none" : "1px solid var(--card-border-color)", cursor: "pointer", backgroundColor: isSelected ? "var(--card-muted-fg-color)" : "transparent", transition: "background-color 0.2s" },
4238
3310
  onClick: () => handleToggle(obj.value)
4239
3311
  },
4240
- /* @__PURE__ */ React18.createElement(Flex11, { align: "center", gap: 3 }, /* @__PURE__ */ React18.createElement(Checkbox, { checked: isSelected, readOnly: true, style: { pointerEvents: "none" } }), /* @__PURE__ */ React18.createElement(Text16, { size: 1, weight: isSelected ? "semibold" : "regular" }, obj.title))
3312
+ /* @__PURE__ */ React17.createElement(Flex10, { align: "center", gap: 3 }, /* @__PURE__ */ React17.createElement(Checkbox, { checked: isSelected, readOnly: true, style: { pointerEvents: "none" } }), /* @__PURE__ */ React17.createElement(Text15, { size: 1, weight: isSelected ? "semibold" : "regular" }, obj.title))
4241
3313
  );
4242
- })), (value == null ? void 0 : value.length) > 0 && /* @__PURE__ */ React18.createElement(Box6, { padding: 2, paddingX: 3, style: { borderTop: "1px solid var(--card-border-color)", backgroundColor: "var(--card-muted-fg-color)" } }, /* @__PURE__ */ React18.createElement(Text16, { size: 1, muted: true }, value.length, " selected")));
3314
+ })), (value == null ? void 0 : value.length) > 0 && /* @__PURE__ */ React17.createElement(Box6, { padding: 2, paddingX: 3, style: { borderTop: "1px solid var(--card-border-color)", backgroundColor: "var(--card-muted-fg-color)" } }, /* @__PURE__ */ React17.createElement(Text15, { size: 1, muted: true }, value.length, " selected")));
4243
3315
  });
4244
3316
  NestedObjectArraySelector.displayName = "NestedObjectArraySelector";
4245
3317
 
4246
3318
  // src/utils/getEmptyFontKit.js
4247
- import * as fontkit7 from "fontkit";
4248
- import slugify4 from "slugify";
3319
+ import slugify3 from "slugify";
4249
3320
  async function getEmptyFontKit({ title, files, weightKeywordList, italicKeywordList }) {
4250
- var _a, _b, _c, _d, _e, _f;
4251
3321
  let fontNames = {};
4252
3322
  let subfamilies = {};
4253
3323
  for (var i = 0; i < files.length; i++) {
4254
3324
  const file = files[i];
4255
3325
  const fontBuffer = await readFontFile2(file);
4256
- const font = fontkit7.create(fontBuffer);
4257
- let weightName = ((_b = (_a = font == null ? void 0 : font.name) == null ? void 0 : _a.records) == null ? void 0 : _b.preferredSubfamily) ? (_d = (_c = font == null ? void 0 : font.name) == null ? void 0 : _c.records) == null ? void 0 : _d.preferredSubfamily : (_f = (_e = font == null ? void 0 : font.name) == null ? void 0 : _e.records) == null ? void 0 : _f.fontSubfamily;
4258
- weightName = (weightName == null ? void 0 : weightName.en) ? weightName.en : weightName.constructor == Object ? weightName[Object.keys(weightName)[0]] : weightName;
4259
- let variableFont = (font == null ? void 0 : font.variationAxes) && Object.keys(font.variationAxes).length > 0 ? true : false;
4260
- let subfamilyName = font.familyName.toLowerCase().trim().replace(title.toLowerCase().trim(), "").trim();
4261
- let fontTitle = font == null ? void 0 : font.fullName.toLowerCase().trim();
3326
+ const font = await parseFont(fontBuffer, file.name);
3327
+ let weightName = getNameString(font, 17) || getNameString(font, 2) || "";
3328
+ const axes = getVariationAxes(font);
3329
+ let variableFont = axes !== null;
3330
+ const familyName = getNameString(font, 1);
3331
+ const fullName = getNameString(font, 4);
3332
+ let subfamilyName = familyName.toLowerCase().trim().replace(title.toLowerCase().trim(), "").trim();
3333
+ let fontTitle = fullName.toLowerCase().trim();
4262
3334
  weightKeywordList.forEach((keyword) => {
4263
3335
  const kw = keyword.toLowerCase().trim();
4264
3336
  if (fontTitle.includes(kw)) {
@@ -4280,7 +3352,7 @@ async function getEmptyFontKit({ title, files, weightKeywordList, italicKeywordL
4280
3352
  fontTitle = fontTitle.trim().split(" ").map((word) => word[0].toUpperCase() + word.slice(1)).join(" ");
4281
3353
  subfamilyName = subfamilyName.trim();
4282
3354
  subfamilyName = subfamilyName == "" ? "Regular" : subfamilyName.split(" ").map((word) => word[0].toUpperCase() + word.slice(1)).join(" ");
4283
- let id = slugify4(fontTitle.toLowerCase().trim());
3355
+ let id = slugify3(fontTitle.toLowerCase().trim());
4284
3356
  if (variableFont && !id.endsWith("-vf")) {
4285
3357
  id = id + "-vf";
4286
3358
  fontTitle = fontTitle + " VF";
@@ -4293,26 +3365,26 @@ async function getEmptyFontKit({ title, files, weightKeywordList, italicKeywordL
4293
3365
  if (!fontNames[id]) {
4294
3366
  fontNames[id] = [{
4295
3367
  file: file.name,
4296
- fullName: font.fullName,
4297
- familyName: font.familyName,
3368
+ fullName,
3369
+ familyName,
4298
3370
  subFamily: subfamilyName
4299
3371
  }];
4300
3372
  } else if (fontNames[id].indexOf(file.name) == -1) {
4301
3373
  fontNames[id].push({
4302
3374
  file: file.name,
4303
- fullName: font.fullName,
4304
- familyName: font.familyName,
3375
+ fullName,
3376
+ familyName,
4305
3377
  subFamily: subfamilyName
4306
3378
  });
4307
3379
  }
4308
3380
  }
4309
- console.log("font names : ", fontNames);
3381
+ console.log("Font names:", fontNames);
4310
3382
  }
4311
3383
  var readFontFile2 = (file) => {
4312
3384
  return new Promise((resolve, reject) => {
4313
3385
  const reader = new FileReader();
4314
3386
  reader.onload = (event) => {
4315
- resolve(new Uint8Array(event.target.result));
3387
+ resolve(event.target.result);
4316
3388
  };
4317
3389
  reader.onerror = (error) => {
4318
3390
  reject(error);
@@ -6775,15 +5847,15 @@ var stylisticSetField = {
6775
5847
  };
6776
5848
 
6777
5849
  // src/schema/stylesField.js
6778
- import React19 from "react";
5850
+ import React18 from "react";
6779
5851
  import { AdvancedRefArray } from "@liiift-studio/sanity-advanced-reference-array";
6780
5852
  var typefaceParams = (doc) => ({ typefaceName: (doc == null ? void 0 : doc.title) || "" });
6781
- var FontsRefArray = (props) => React19.createElement(AdvancedRefArray, {
5853
+ var FontsRefArray = (props) => React18.createElement(AdvancedRefArray, {
6782
5854
  ...props,
6783
5855
  filterGroq: "lower(typefaceName) == lower($typefaceName)",
6784
5856
  filterParams: typefaceParams
6785
5857
  });
6786
- var VariableFontsRefArray = (props) => React19.createElement(AdvancedRefArray, {
5858
+ var VariableFontsRefArray = (props) => React18.createElement(AdvancedRefArray, {
6787
5859
  ...props,
6788
5860
  filterGroq: "lower(typefaceName) == lower($typefaceName) && variableFont == true",
6789
5861
  filterParams: typefaceParams
@@ -7010,16 +6082,24 @@ function createStylesField({
7010
6082
  }
7011
6083
  export {
7012
6084
  BatchUploadFonts,
6085
+ BulkActions,
7013
6086
  DISCOUNT_REQUIREMENT_TYPES,
7014
6087
  DISCOUNT_REQUIREMENT_TYPES_OBJECT,
6088
+ EXECUTION_STATUS,
6089
+ ExistingDocumentResolver,
6090
+ FONT_STATUS,
6091
+ FontReviewCard_default as FontReviewCard,
7015
6092
  FontScriptUploaderComponent,
7016
6093
  GenerateCollectionsPairsComponent,
7017
6094
  HtmlDescription,
7018
6095
  KeyValueInput,
7019
6096
  KeyValueReferenceInput,
7020
6097
  NestedObjectArraySelector,
6098
+ PLAN_PHASE,
6099
+ PLAN_VERSION,
7021
6100
  PriceInput_default as PriceInput,
7022
6101
  PrimaryCollectionGeneratorTypeface,
6102
+ RECOMMENDATION,
7023
6103
  RegenerateSubfamiliesComponent,
7024
6104
  SCRIPTS,
7025
6105
  SCRIPTS_OBJECT,
@@ -7029,12 +6109,24 @@ export {
7029
6109
  StyleCountInput,
7030
6110
  UpdateScriptsComponent,
7031
6111
  UploadButton_default as UploadButton,
6112
+ UploadModal,
7032
6113
  UploadScriptsComponent,
6114
+ UploadStep1Settings,
6115
+ UploadStep2Review,
6116
+ UploadStep3Execute,
6117
+ UploadSummary,
7033
6118
  VariableInstanceReferencesInput,
7034
6119
  addItalicToFontTitle,
6120
+ buildUploadPlan,
6121
+ createEmptyPlan,
6122
+ createFontDecisions,
7035
6123
  createFontObject,
6124
+ createInitialExecutionState,
7036
6125
  createStylesField,
7037
6126
  determineWeight,
6127
+ escapeCssFontName,
6128
+ executeUploadPlan,
6129
+ executionReducer,
7038
6130
  expandAbbreviations,
7039
6131
  extractFontMetadata,
7040
6132
  extractWeightFromFullName,
@@ -7045,16 +6137,32 @@ export {
7045
6137
  generateFontFile,
7046
6138
  generateStyleKeywords,
7047
6139
  generateSubset,
6140
+ getAllFeatureTags,
6141
+ getCharacterSet,
7048
6142
  getEmptyFontKit,
6143
+ getFamilyClass,
6144
+ getFontMetadata,
6145
+ getFontMetrics,
6146
+ getFsSelection,
6147
+ getGlyphCount,
6148
+ getItalicAngle,
6149
+ getMacStyle,
6150
+ getNameString,
6151
+ getNamedInstances,
6152
+ getVariationAxes,
6153
+ getWeightClass,
7049
6154
  logFontInfo,
7050
6155
  openTypeField,
6156
+ parseFont,
7051
6157
  parseVariableFontInstances_default as parseVariableFontInstances,
6158
+ planReducer,
7052
6159
  processFontFiles,
7053
6160
  processItalicKeywords,
7054
6161
  processSubfamilyName,
7055
6162
  readFontFile,
7056
6163
  removeWeightNames,
7057
6164
  renameFontDocuments,
6165
+ resolveExistingFont,
7058
6166
  reverseSpellingLookup,
7059
6167
  sanitizeForSanityId,
7060
6168
  sortFontObjects,