@vishu1301/script-writing 1.5.8 → 1.5.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -1,13 +1,13 @@
1
1
  'use strict';
2
2
 
3
- var react = require('react');
3
+ var React4 = require('react');
4
4
  var lucideReact = require('lucide-react');
5
5
  var jsxRuntime = require('react/jsx-runtime');
6
6
  var pdfjs = require('pdfjs-dist');
7
7
  var jsPDF = require('jspdf');
8
8
  var html2canvas = require('html2canvas-pro');
9
- var Yup = require('yup');
10
9
  var formik = require('formik');
10
+ var Yup = require('yup');
11
11
 
12
12
  function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
13
13
 
@@ -29,6 +29,7 @@ function _interopNamespace(e) {
29
29
  return Object.freeze(n);
30
30
  }
31
31
 
32
+ var React4__default = /*#__PURE__*/_interopDefault(React4);
32
33
  var pdfjs__namespace = /*#__PURE__*/_interopNamespace(pdfjs);
33
34
  var jsPDF__default = /*#__PURE__*/_interopDefault(jsPDF);
34
35
  var html2canvas__default = /*#__PURE__*/_interopDefault(html2canvas);
@@ -817,9 +818,9 @@ function PhoneticSuggestions({
817
818
  }
818
819
  pdfjs__namespace.GlobalWorkerOptions.workerSrc = `//unpkg.com/pdfjs-dist@${pdfjs__namespace.version}/build/pdf.worker.min.mjs`;
819
820
  function PdfImporter({ onScriptImported, disabled, children }) {
820
- const [isProcessing, setIsProcessing] = react.useState(false);
821
- const [error, setError] = react.useState(null);
822
- const fileInputRef = react.useRef(null);
821
+ const [isProcessing, setIsProcessing] = React4.useState(false);
822
+ const [error, setError] = React4.useState(null);
823
+ const fileInputRef = React4.useRef(null);
823
824
  const handleFileChange = async (event) => {
824
825
  var _a;
825
826
  const file = (_a = event.target.files) == null ? void 0 : _a[0];
@@ -975,12 +976,12 @@ function PhoneticGuide({
975
976
  isOpen,
976
977
  onClose
977
978
  }) {
978
- const [activeTab, setActiveTab] = react.useState("vowels");
979
- const [searchQuery, setSearchQuery] = react.useState("");
979
+ const [activeTab, setActiveTab] = React4.useState("vowels");
980
+ const [searchQuery, setSearchQuery] = React4.useState("");
980
981
  const script = language.includes("Hindi") ? "Hindi" : "Gujarati";
981
982
  const vowelsData = VOWEL_FORMS[script] || {};
982
983
  const config = LANGUAGE_CONFIGS[language];
983
- const consonants = react.useMemo(() => {
984
+ const consonants = React4.useMemo(() => {
984
985
  if (!config || language === "English") return [];
985
986
  return Object.entries(config.mapping).filter(([_, val]) => {
986
987
  const isVowelMatra = Object.values(vowelsData).some(
@@ -994,7 +995,7 @@ function PhoneticGuide({
994
995
  shiftChar: val.shift
995
996
  }));
996
997
  }, [language, vowelsData, config]);
997
- const symbols = react.useMemo(() => {
998
+ const symbols = React4.useMemo(() => {
998
999
  if (!config || language === "English") return [];
999
1000
  return Object.entries(config.mapping).filter(([_, val]) => /[.,/;:'"\[\]{}\\=`\-_]/.test(val.default)).map(([key, val]) => ({
1000
1001
  key: key.replace("Key", "").toLowerCase(),
@@ -1286,13 +1287,13 @@ function ScreenplayEditorView({
1286
1287
  phoneticSuggestions,
1287
1288
  handleSelectPhoneticSuggestion
1288
1289
  }) {
1289
- const [isRulesOpen, setIsRulesOpen] = react.useState(false);
1290
- const [isLanguageOpen, setIsLanguageOpen] = react.useState(false);
1291
- const [isPhoneticGuideOpen, setIsPhoneticGuideOpen] = react.useState(false);
1292
- const rulesRef = react.useRef(null);
1293
- const languageRef = react.useRef(null);
1290
+ const [isRulesOpen, setIsRulesOpen] = React4.useState(false);
1291
+ const [isLanguageOpen, setIsLanguageOpen] = React4.useState(false);
1292
+ const [isPhoneticGuideOpen, setIsPhoneticGuideOpen] = React4.useState(false);
1293
+ const rulesRef = React4.useRef(null);
1294
+ const languageRef = React4.useRef(null);
1294
1295
  const COURIER_STACK = "'Courier Prime', 'Courier', monospace";
1295
- react.useEffect(() => {
1296
+ React4.useEffect(() => {
1296
1297
  const handleClickOutside = (event) => {
1297
1298
  if (rulesRef.current && !rulesRef.current.contains(event.target)) {
1298
1299
  setIsRulesOpen(false);
@@ -1308,7 +1309,7 @@ function ScreenplayEditorView({
1308
1309
  document.removeEventListener("mousedown", handleClickOutside);
1309
1310
  };
1310
1311
  }, [isRulesOpen, isLanguageOpen]);
1311
- react.useEffect(() => {
1312
+ React4.useEffect(() => {
1312
1313
  const fontId = "google-font-courier-prime";
1313
1314
  const styleId = "screenplay-editor-force-v4";
1314
1315
  if (!document.getElementById(fontId)) {
@@ -2223,49 +2224,49 @@ function createRangeFromGlobalOffset(element, startOffset, endOffset) {
2223
2224
  return null;
2224
2225
  }
2225
2226
  function useScreenplayEditor(options) {
2226
- const [blocks, setBlocks] = react.useState(initialBlocks);
2227
- const refs = react.useRef({});
2228
- const [focusedBlockId, setFocusedBlockId] = react.useState(
2227
+ const [blocks, setBlocks] = React4.useState(initialBlocks);
2228
+ const refs = React4.useRef({});
2229
+ const [focusedBlockId, setFocusedBlockId] = React4.useState(
2229
2230
  initialBlocks[0].id
2230
2231
  );
2231
- const [newBlockId, setNewBlockId] = react.useState(null);
2232
- const [showSuggestions, setShowSuggestions] = react.useState(false);
2233
- const [showExtensionSuggestions, setShowExtensionSuggestions] = react.useState(false);
2234
- const [isLoading, setIsLoading] = react.useState(!!(options == null ? void 0 : options.initialUrl));
2235
- const [enhancingBlockId, setEnhancingBlockId] = react.useState(null);
2236
- const [enhancementSuggestion, setEnhancementSuggestion] = react.useState(null);
2237
- const [isEnhancing, setIsEnhancing] = react.useState(false);
2238
- const [hasUnsavedChanges, setHasUnsavedChanges] = react.useState(false);
2239
- const [showUnsavedPopover, setShowUnsavedPopover] = react.useState(false);
2240
- const popoverTimeoutRef = react.useRef(null);
2241
- const blurTimeout = react.useRef(null);
2242
- const isInitialLoadRef = react.useRef(true);
2243
- const loadedUrlRef = react.useRef(null);
2244
- const lastSavedContent = react.useRef(null);
2245
- const onSaveRef = react.useRef(options == null ? void 0 : options.onSave);
2246
- const onSyncWithCloudRef = react.useRef(options == null ? void 0 : options.onSyncWithCloud);
2247
- const [currentLanguage, setCurrentLanguage] = react.useState("English");
2248
- const [lastPhoneticAction, setLastPhoneticAction] = react.useState(null);
2249
- const [phoneticSuggestions, setPhoneticSuggestions] = react.useState([]);
2250
- react.useEffect(() => {
2232
+ const [newBlockId, setNewBlockId] = React4.useState(null);
2233
+ const [showSuggestions, setShowSuggestions] = React4.useState(false);
2234
+ const [showExtensionSuggestions, setShowExtensionSuggestions] = React4.useState(false);
2235
+ const [isLoading, setIsLoading] = React4.useState(!!(options == null ? void 0 : options.initialUrl));
2236
+ const [enhancingBlockId, setEnhancingBlockId] = React4.useState(null);
2237
+ const [enhancementSuggestion, setEnhancementSuggestion] = React4.useState(null);
2238
+ const [isEnhancing, setIsEnhancing] = React4.useState(false);
2239
+ const [hasUnsavedChanges, setHasUnsavedChanges] = React4.useState(false);
2240
+ const [showUnsavedPopover, setShowUnsavedPopover] = React4.useState(false);
2241
+ const popoverTimeoutRef = React4.useRef(null);
2242
+ const blurTimeout = React4.useRef(null);
2243
+ const isInitialLoadRef = React4.useRef(true);
2244
+ const loadedUrlRef = React4.useRef(null);
2245
+ const lastSavedContent = React4.useRef(null);
2246
+ const onSaveRef = React4.useRef(options == null ? void 0 : options.onSave);
2247
+ const onSyncWithCloudRef = React4.useRef(options == null ? void 0 : options.onSyncWithCloud);
2248
+ const [currentLanguage, setCurrentLanguage] = React4.useState("English");
2249
+ const [lastPhoneticAction, setLastPhoneticAction] = React4.useState(null);
2250
+ const [phoneticSuggestions, setPhoneticSuggestions] = React4.useState([]);
2251
+ React4.useEffect(() => {
2251
2252
  setLastPhoneticAction(null);
2252
2253
  setPhoneticSuggestions([]);
2253
2254
  }, [currentLanguage]);
2254
- const phoneticEngine = react.useMemo(() => {
2255
+ const phoneticEngine = React4.useMemo(() => {
2255
2256
  if (currentLanguage.includes("Phonetic")) {
2256
2257
  return new PhoneticEngine(currentLanguage);
2257
2258
  }
2258
2259
  return null;
2259
2260
  }, [currentLanguage]);
2260
- react.useEffect(() => {
2261
+ React4.useEffect(() => {
2261
2262
  onSaveRef.current = options == null ? void 0 : options.onSave;
2262
2263
  onSyncWithCloudRef.current = options == null ? void 0 : options.onSyncWithCloud;
2263
2264
  }, [options == null ? void 0 : options.onSave, options == null ? void 0 : options.onSyncWithCloud]);
2264
- const characterExtensions = react.useMemo(
2265
+ const characterExtensions = React4.useMemo(
2265
2266
  () => ["(V.O.)", "(O.S.)", "(O.C.)", "(SUBTITLE)", "(CONT'D)"],
2266
2267
  []
2267
2268
  );
2268
- const handleSceneNumberChange = react.useCallback(
2269
+ const handleSceneNumberChange = React4.useCallback(
2269
2270
  (id, newNumber) => {
2270
2271
  setBlocks(
2271
2272
  (prevBlocks) => prevBlocks.map(
@@ -2275,11 +2276,11 @@ function useScreenplayEditor(options) {
2275
2276
  },
2276
2277
  []
2277
2278
  );
2278
- const locations = react.useMemo(() => {
2279
+ const locations = React4.useMemo(() => {
2279
2280
  const locs = blocks.filter((b) => b.type === "SCENE_HEADING" && b.text.trim() !== "").map((b) => b.text.trim().toUpperCase());
2280
2281
  return [...new Set(locs)];
2281
2282
  }, [blocks]);
2282
- const characters = react.useMemo(() => {
2283
+ const characters = React4.useMemo(() => {
2283
2284
  const chars = blocks.filter((b) => b.type === "CHARACTER" && b.text.trim() !== "").map((b) => {
2284
2285
  const text = b.text.trim().toUpperCase();
2285
2286
  const parenIndex = text.indexOf("(");
@@ -2290,7 +2291,7 @@ function useScreenplayEditor(options) {
2290
2291
  }).filter(Boolean);
2291
2292
  return [...new Set(chars)];
2292
2293
  }, [blocks]);
2293
- const sceneNumbers = react.useMemo(() => {
2294
+ const sceneNumbers = React4.useMemo(() => {
2294
2295
  const map = {};
2295
2296
  let fallbackCount = 0;
2296
2297
  blocks.forEach((block) => {
@@ -2307,7 +2308,7 @@ function useScreenplayEditor(options) {
2307
2308
  });
2308
2309
  return map;
2309
2310
  }, [blocks]);
2310
- react.useEffect(() => {
2311
+ React4.useEffect(() => {
2311
2312
  if (newBlockId && refs.current[newBlockId]) {
2312
2313
  const block = blocks.find((b) => b.id === newBlockId);
2313
2314
  const el = refs.current[newBlockId];
@@ -2324,7 +2325,7 @@ function useScreenplayEditor(options) {
2324
2325
  setNewBlockId(null);
2325
2326
  }
2326
2327
  }, [newBlockId, blocks]);
2327
- react.useEffect(() => {
2328
+ React4.useEffect(() => {
2328
2329
  blocks.forEach((block) => {
2329
2330
  const element = refs.current[block.id];
2330
2331
  if (element) {
@@ -2334,7 +2335,7 @@ function useScreenplayEditor(options) {
2334
2335
  }
2335
2336
  });
2336
2337
  }, [blocks]);
2337
- react.useEffect(() => {
2338
+ React4.useEffect(() => {
2338
2339
  const handleClickOutside = (e) => {
2339
2340
  const target = e.target;
2340
2341
  const isInsideBlock = target.closest("[data-block-id]");
@@ -2352,7 +2353,7 @@ function useScreenplayEditor(options) {
2352
2353
  document.removeEventListener("mousedown", handleClickOutside);
2353
2354
  };
2354
2355
  }, []);
2355
- const handleBlockTextChange = react.useCallback(
2356
+ const handleBlockTextChange = React4.useCallback(
2356
2357
  (id, text) => {
2357
2358
  const block = blocks.find((b) => b.id === id);
2358
2359
  if (!block) return;
@@ -2395,7 +2396,7 @@ function useScreenplayEditor(options) {
2395
2396
  },
2396
2397
  [blocks, showExtensionSuggestions]
2397
2398
  );
2398
- const handleSceneTypeChange = react.useCallback(
2399
+ const handleSceneTypeChange = React4.useCallback(
2399
2400
  (id, sceneType) => {
2400
2401
  setBlocks(
2401
2402
  (bs) => updateBlock(bs, id, "sceneType", sceneType)
@@ -2408,7 +2409,7 @@ function useScreenplayEditor(options) {
2408
2409
  },
2409
2410
  []
2410
2411
  );
2411
- const handleTimeOfDayChange = react.useCallback((id, time) => {
2412
+ const handleTimeOfDayChange = React4.useCallback((id, time) => {
2412
2413
  setBlocks((bs) => updateBlock(bs, id, "timeOfDay", time));
2413
2414
  setTimeout(() => {
2414
2415
  var _a;
@@ -2416,7 +2417,7 @@ function useScreenplayEditor(options) {
2416
2417
  setFocusedBlockId(id);
2417
2418
  }, 10);
2418
2419
  }, []);
2419
- const handleBlockTypeChange = react.useCallback(
2420
+ const handleBlockTypeChange = React4.useCallback(
2420
2421
  (newType) => {
2421
2422
  if (!focusedBlockId) return;
2422
2423
  setBlocks(
@@ -2442,7 +2443,7 @@ function useScreenplayEditor(options) {
2442
2443
  },
2443
2444
  [focusedBlockId, blocks]
2444
2445
  );
2445
- const handleSelectCharacterExtension = react.useCallback(
2446
+ const handleSelectCharacterExtension = React4.useCallback(
2446
2447
  (extension) => {
2447
2448
  if (!focusedBlockId) return;
2448
2449
  setBlocks((currentBlocks) => {
@@ -2511,7 +2512,7 @@ function useScreenplayEditor(options) {
2511
2512
  }
2512
2513
  }, 10);
2513
2514
  };
2514
- const handleKeyDown = react.useCallback(
2515
+ const handleKeyDown = React4.useCallback(
2515
2516
  (e, id, text) => {
2516
2517
  var _a;
2517
2518
  if (currentLanguage !== "English") {
@@ -2720,7 +2721,7 @@ function useScreenplayEditor(options) {
2720
2721
  lastPhoneticAction
2721
2722
  ]
2722
2723
  );
2723
- const handleScriptImport = react.useCallback(
2724
+ const handleScriptImport = React4.useCallback(
2724
2725
  (title, content, preParsedBlocks, isInitialLoad) => {
2725
2726
  let parsedBlocks = [];
2726
2727
  if (preParsedBlocks && preParsedBlocks.length > 0) {
@@ -2773,7 +2774,7 @@ function useScreenplayEditor(options) {
2773
2774
  },
2774
2775
  [refs]
2775
2776
  );
2776
- const handleSelectPhoneticSuggestion = react.useCallback(
2777
+ const handleSelectPhoneticSuggestion = React4.useCallback(
2777
2778
  (suggestion) => {
2778
2779
  if (!focusedBlockId) return;
2779
2780
  const el = refs.current[focusedBlockId];
@@ -2793,7 +2794,7 @@ function useScreenplayEditor(options) {
2793
2794
  },
2794
2795
  [focusedBlockId, handleBlockTextChange]
2795
2796
  );
2796
- const handleFocus = react.useCallback(
2797
+ const handleFocus = React4.useCallback(
2797
2798
  (id) => {
2798
2799
  if (blurTimeout.current) {
2799
2800
  clearTimeout(blurTimeout.current);
@@ -2818,14 +2819,14 @@ function useScreenplayEditor(options) {
2818
2819
  },
2819
2820
  [blocks]
2820
2821
  );
2821
- const handleBlur = react.useCallback((id) => {
2822
+ const handleBlur = React4.useCallback((id) => {
2822
2823
  if (document.activeElement === refs.current[id]) return;
2823
2824
  blurTimeout.current = setTimeout(() => {
2824
2825
  setShowSuggestions(false);
2825
2826
  setShowExtensionSuggestions(false);
2826
2827
  }, 200);
2827
2828
  }, []);
2828
- const syncScreenplay = react.useCallback(() => {
2829
+ const syncScreenplay = React4.useCallback(() => {
2829
2830
  if (!onSyncWithCloudRef.current) return;
2830
2831
  onSyncWithCloudRef.current(blocks, sceneNumbers);
2831
2832
  lastSavedContent.current = serializeToSbx(blocks);
@@ -2833,11 +2834,11 @@ function useScreenplayEditor(options) {
2833
2834
  setShowUnsavedPopover(false);
2834
2835
  if (popoverTimeoutRef.current) clearTimeout(popoverTimeoutRef.current);
2835
2836
  }, [blocks, sceneNumbers]);
2836
- const ignoreChanges = react.useCallback(() => {
2837
+ const ignoreChanges = React4.useCallback(() => {
2837
2838
  setShowUnsavedPopover(false);
2838
2839
  if (popoverTimeoutRef.current) clearTimeout(popoverTimeoutRef.current);
2839
2840
  }, []);
2840
- const loadFromUrl = react.useCallback(
2841
+ const loadFromUrl = React4.useCallback(
2841
2842
  async (url, fetchOptions = {}, isInitialLoad) => {
2842
2843
  var _a;
2843
2844
  setIsLoading(true);
@@ -2923,7 +2924,7 @@ function useScreenplayEditor(options) {
2923
2924
  },
2924
2925
  [handleScriptImport]
2925
2926
  );
2926
- react.useEffect(() => {
2927
+ React4.useEffect(() => {
2927
2928
  if (isLoading) {
2928
2929
  isInitialLoadRef.current = true;
2929
2930
  return;
@@ -2953,7 +2954,7 @@ function useScreenplayEditor(options) {
2953
2954
  if (popoverTimeoutRef.current) clearTimeout(popoverTimeoutRef.current);
2954
2955
  };
2955
2956
  }, [blocks, isLoading]);
2956
- react.useEffect(() => {
2957
+ React4.useEffect(() => {
2957
2958
  if ((options == null ? void 0 : options.initialUrl) && options.initialUrl !== loadedUrlRef.current) {
2958
2959
  loadedUrlRef.current = options.initialUrl;
2959
2960
  loadFromUrl(options.initialUrl, options.fetchOptions, true);
@@ -3325,6 +3326,368 @@ var SummarizeButton = ({
3325
3326
  );
3326
3327
  };
3327
3328
  var summarize_button_default = SummarizeButton;
3329
+
3330
+ // data/crowd-data.ts
3331
+ var crowdAgeOption = [
3332
+ { name: "Adult" },
3333
+ { name: "Old" },
3334
+ { name: "Teenage" },
3335
+ { name: "Kid" }
3336
+ ];
3337
+ var crowdTypeOption = [{ name: "Male" }, { name: "Female" }];
3338
+ var FormikSelect = ({
3339
+ label,
3340
+ name,
3341
+ selectedOption,
3342
+ optionData,
3343
+ value,
3344
+ disable,
3345
+ divClasses,
3346
+ valueProperty = "name",
3347
+ labelProperty = "name",
3348
+ label2propery,
3349
+ brackets,
3350
+ className,
3351
+ enableRedAsterick = false,
3352
+ disableOptionProperty = "disable",
3353
+ disabledOptionText = "",
3354
+ onChange
3355
+ }) => {
3356
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `w-full ${divClasses}`, children: [
3357
+ label && /* @__PURE__ */ jsxRuntime.jsxs(
3358
+ "label",
3359
+ {
3360
+ className: `mb-1.5 text-sm font-medium text-slate-700 capitalize flex`,
3361
+ children: [
3362
+ label,
3363
+ enableRedAsterick && /* @__PURE__ */ jsxRuntime.jsx(lucideReact.AsteriskIcon, { className: "size-3 text-red-500" })
3364
+ ]
3365
+ }
3366
+ ),
3367
+ /* @__PURE__ */ jsxRuntime.jsxs(
3368
+ formik.Field,
3369
+ {
3370
+ name,
3371
+ as: "select",
3372
+ value,
3373
+ disabled: disable,
3374
+ onChange,
3375
+ className: `${className} rounded-[2.5rem] block w-full px-3 py-2.5 text-slate-700 placeholder-slate-400 placeholder:capitalize bg-white border border-slate-300/80 focus:border-blumine-500 focus:ring-2 focus:ring-blumine-500/50 focus:outline-none transition-all`,
3376
+ children: [
3377
+ /* @__PURE__ */ jsxRuntime.jsx("option", { selected: true, value: "", disabled: true, className: "capitalize", children: selectedOption }),
3378
+ optionData == null ? void 0 : optionData.map((option, index) => /* @__PURE__ */ jsxRuntime.jsxs(
3379
+ "option",
3380
+ {
3381
+ value: option[valueProperty],
3382
+ disabled: option[disableOptionProperty],
3383
+ children: [
3384
+ option[labelProperty],
3385
+ label2propery ? brackets ? ` (${option[label2propery]})` : option[label2propery] : "",
3386
+ " ",
3387
+ option[disableOptionProperty] && `(${disabledOptionText})`
3388
+ ]
3389
+ },
3390
+ index
3391
+ ))
3392
+ ]
3393
+ }
3394
+ ),
3395
+ /* @__PURE__ */ jsxRuntime.jsx(
3396
+ formik.ErrorMessage,
3397
+ {
3398
+ name,
3399
+ className: "text-red-500 text-sm mt-1",
3400
+ component: "div"
3401
+ }
3402
+ )
3403
+ ] });
3404
+ };
3405
+ var FormikInput = (_a) => {
3406
+ var _b = _a, {
3407
+ label,
3408
+ name,
3409
+ type,
3410
+ placeholder,
3411
+ className,
3412
+ labelClassName,
3413
+ readOnly,
3414
+ divClasses,
3415
+ length,
3416
+ disable,
3417
+ min = 0,
3418
+ max,
3419
+ convertToText = false,
3420
+ enableRedAsterick = false,
3421
+ case_sensitivity = "normal"
3422
+ } = _b, props = __objRest(_b, [
3423
+ "label",
3424
+ "name",
3425
+ "type",
3426
+ "placeholder",
3427
+ "className",
3428
+ "labelClassName",
3429
+ "readOnly",
3430
+ "divClasses",
3431
+ "length",
3432
+ "disable",
3433
+ "min",
3434
+ "max",
3435
+ "convertToText",
3436
+ "enableRedAsterick",
3437
+ "case_sensitivity"
3438
+ ]);
3439
+ const { setFieldValue } = formik.useFormikContext();
3440
+ const handleCaseChange = (e) => {
3441
+ let value = e.target.value;
3442
+ if (type === "number" && min !== void 0) {
3443
+ if (value !== "" && Number(value) < min) return;
3444
+ }
3445
+ switch (case_sensitivity) {
3446
+ case "lowercase":
3447
+ value = value.toLowerCase();
3448
+ break;
3449
+ case "uppercase":
3450
+ value = value.toUpperCase();
3451
+ break;
3452
+ }
3453
+ setFieldValue(name, value);
3454
+ };
3455
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `w-full ${divClasses}`, children: [
3456
+ /* @__PURE__ */ jsxRuntime.jsxs(
3457
+ "label",
3458
+ {
3459
+ className: `${labelClassName} mb-1.5 text-sm font-medium text-slate-700 capitalize flex`,
3460
+ children: [
3461
+ label,
3462
+ enableRedAsterick && /* @__PURE__ */ jsxRuntime.jsx(lucideReact.AsteriskIcon, { className: "size-3 text-red-500" })
3463
+ ]
3464
+ }
3465
+ ),
3466
+ /* @__PURE__ */ jsxRuntime.jsx(
3467
+ formik.Field,
3468
+ __spreadProps(__spreadValues({
3469
+ name,
3470
+ placeholder,
3471
+ readOnly,
3472
+ type,
3473
+ maxLength: length,
3474
+ disabled: disable,
3475
+ max,
3476
+ min,
3477
+ onChange: handleCaseChange
3478
+ }, props), {
3479
+ className: `${className} rounded-[2.5rem] block w-full px-3 py-2.5 text-slate-700 placeholder-slate-400 placeholder:capitalize bg-white border border-slate-300/80 focus:border-blumine-500 focus:ring-2 focus:ring-blumine-500/50 focus:outline-none transition-all disabled:opacity-70`
3480
+ })
3481
+ ),
3482
+ /* @__PURE__ */ jsxRuntime.jsx(
3483
+ formik.ErrorMessage,
3484
+ {
3485
+ name,
3486
+ className: "text-red-500 text-sm mt-1",
3487
+ component: "div"
3488
+ }
3489
+ )
3490
+ ] });
3491
+ };
3492
+ var FormikTextarea = ({
3493
+ label,
3494
+ name,
3495
+ placeholder,
3496
+ readOnly,
3497
+ divClasses = "",
3498
+ className = "",
3499
+ length,
3500
+ disable,
3501
+ min,
3502
+ max,
3503
+ enableRedAsterick = false
3504
+ }) => {
3505
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `w-full ${divClasses}`, children: [
3506
+ /* @__PURE__ */ jsxRuntime.jsxs(
3507
+ "label",
3508
+ {
3509
+ className: `mb-1.5 text-sm font-medium text-slate-700 capitalize flex`,
3510
+ children: [
3511
+ label,
3512
+ enableRedAsterick && /* @__PURE__ */ jsxRuntime.jsx(lucideReact.AsteriskIcon, { className: "size-3 text-red-500" })
3513
+ ]
3514
+ }
3515
+ ),
3516
+ /* @__PURE__ */ jsxRuntime.jsx(
3517
+ formik.Field,
3518
+ {
3519
+ as: "textarea",
3520
+ name,
3521
+ placeholder,
3522
+ readOnly,
3523
+ maxLength: length,
3524
+ disabled: disable,
3525
+ max,
3526
+ min,
3527
+ className: `${className} block w-full px-4 py-3 text-slate-700 placeholder-slate-400 placeholder:capitalize bg-white border border-slate-300/80 rounded-2xl focus:border-blumine-500 focus:ring-2 focus:ring-blumine-500/50 focus:outline-none transition-all disabled:opacity-70`
3528
+ }
3529
+ ),
3530
+ /* @__PURE__ */ jsxRuntime.jsx(
3531
+ formik.ErrorMessage,
3532
+ {
3533
+ name,
3534
+ className: "text-red-500 text-sm mt-1",
3535
+ component: "div"
3536
+ }
3537
+ )
3538
+ ] });
3539
+ };
3540
+ var Switch = ({
3541
+ isOn,
3542
+ handleToggle,
3543
+ activeColor = "bg-green-500",
3544
+ inactiveColor = "bg-gray-300",
3545
+ size = "medium",
3546
+ onLabel,
3547
+ offLabel,
3548
+ label,
3549
+ divClasses,
3550
+ labelClasses,
3551
+ disable = false
3552
+ }) => {
3553
+ const sizeClasses = {
3554
+ small: { width: 28, height: 18, handle: 12, labelSize: 12, gap: 4 },
3555
+ medium: { width: 48, height: 28, handle: 20, labelSize: 16, gap: 6 },
3556
+ large: { width: 64, height: 36, handle: 28, labelSize: 20, gap: 10 }
3557
+ };
3558
+ const selectedSize = sizeClasses[size] || sizeClasses.medium;
3559
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `w-full ${divClasses}`, children: [
3560
+ label && /* @__PURE__ */ jsxRuntime.jsx(
3561
+ "label",
3562
+ {
3563
+ className: `block mb-2 text-sm text-gray-600 ${disable && "text-gray-400!"} ${labelClasses}`,
3564
+ children: label
3565
+ }
3566
+ ),
3567
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { gap: selectedSize.gap }, className: "flex items-center", children: [
3568
+ /* @__PURE__ */ jsxRuntime.jsx(
3569
+ "div",
3570
+ {
3571
+ className: `flex items-center rounded-full cursor-pointer relative ${isOn ? activeColor : inactiveColor} ${disable && "opacity-50 cursor-not-allowed"}`,
3572
+ onClick: disable ? () => {
3573
+ } : handleToggle,
3574
+ role: "button",
3575
+ "aria-pressed": isOn,
3576
+ style: {
3577
+ width: selectedSize.width,
3578
+ height: selectedSize.height
3579
+ },
3580
+ children: /* @__PURE__ */ jsxRuntime.jsx(
3581
+ "div",
3582
+ {
3583
+ className: "bg-white rounded-full shadow-sm ease-in duration-200",
3584
+ style: {
3585
+ width: selectedSize.handle,
3586
+ height: selectedSize.handle,
3587
+ transform: `translateX(${isOn ? selectedSize.width - selectedSize.handle - 3 : 3}px)`,
3588
+ transition: "transform 0.2s ease-in-out"
3589
+ }
3590
+ }
3591
+ )
3592
+ }
3593
+ ),
3594
+ onLabel && offLabel && /* @__PURE__ */ jsxRuntime.jsx("span", { style: { fontSize: selectedSize.labelSize }, children: isOn ? onLabel : offLabel })
3595
+ ] })
3596
+ ] });
3597
+ };
3598
+ var MultiSelect = ({
3599
+ label,
3600
+ options,
3601
+ value,
3602
+ onChange,
3603
+ placeholder = "Select options...",
3604
+ valueProperty = "name",
3605
+ labelProperty = "name",
3606
+ divClasses = "",
3607
+ returnObjects = false
3608
+ }) => {
3609
+ const [isOpen, setIsOpen] = React4__default.default.useState(false);
3610
+ const containerRef = React4__default.default.useRef(null);
3611
+ const isSelected = (optionValue) => {
3612
+ return value.some(
3613
+ (v) => typeof v === "object" && v !== null ? v[valueProperty] === optionValue : v === optionValue
3614
+ );
3615
+ };
3616
+ const toggleOption = (optionValue) => {
3617
+ let newValues;
3618
+ if (isSelected(optionValue)) {
3619
+ newValues = value.filter(
3620
+ (v) => typeof v === "object" && v !== null ? v[valueProperty] !== optionValue : v !== optionValue
3621
+ );
3622
+ } else {
3623
+ const newValue = returnObjects ? options.find((opt) => opt[valueProperty] === optionValue) : optionValue;
3624
+ newValues = [...value, newValue];
3625
+ }
3626
+ onChange(newValues);
3627
+ };
3628
+ const removeOption = (e, optionValue) => {
3629
+ e.stopPropagation();
3630
+ const newValues = value.filter(
3631
+ (v) => typeof v === "object" && v !== null ? v[valueProperty] !== optionValue : v !== optionValue
3632
+ );
3633
+ onChange(newValues);
3634
+ };
3635
+ React4__default.default.useEffect(() => {
3636
+ const handleClickOutside = (event) => {
3637
+ if (containerRef.current && !containerRef.current.contains(event.target)) {
3638
+ setIsOpen(false);
3639
+ }
3640
+ };
3641
+ document.addEventListener("mousedown", handleClickOutside);
3642
+ return () => document.removeEventListener("mousedown", handleClickOutside);
3643
+ }, []);
3644
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `w-full relative ${divClasses}`, ref: containerRef, children: [
3645
+ label && /* @__PURE__ */ jsxRuntime.jsx("label", { className: "mb-1.5 text-xs font-bold text-slate-600 ml-1 uppercase tracking-wider", children: label }),
3646
+ /* @__PURE__ */ jsxRuntime.jsx(
3647
+ "div",
3648
+ {
3649
+ onClick: () => setIsOpen(!isOpen),
3650
+ className: `min-h-[40px] w-full px-3 py-1.5 bg-slate-50/50 border border-slate-200/80 rounded-xl transition-all cursor-pointer flex flex-wrap gap-1.5 items-center ${isOpen ? "border-blumine-500 bg-white shadow-sm ring-2 ring-blumine-500/10" : "hover:border-slate-300"}`,
3651
+ children: value.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-slate-400 text-[13px] ml-1", children: placeholder }) : value.map((val) => {
3652
+ const actualValue = typeof val === "object" && val !== null ? val[valueProperty] : val;
3653
+ const option = options.find(
3654
+ (opt) => opt[valueProperty] === actualValue
3655
+ );
3656
+ return /* @__PURE__ */ jsxRuntime.jsxs(
3657
+ "div",
3658
+ {
3659
+ className: "flex items-center gap-1 bg-white text-slate-700 px-2 py-0.5 rounded-lg border border-slate-200 text-[11px] font-bold shadow-sm animate-in zoom-in-95 duration-150",
3660
+ children: [
3661
+ option ? option[labelProperty] : actualValue,
3662
+ /* @__PURE__ */ jsxRuntime.jsx(
3663
+ "button",
3664
+ {
3665
+ type: "button",
3666
+ onClick: (e) => removeOption(e, actualValue),
3667
+ className: "hover:text-red-500 transition-colors ml-0.5",
3668
+ children: "\xD7"
3669
+ }
3670
+ )
3671
+ ]
3672
+ },
3673
+ actualValue
3674
+ );
3675
+ })
3676
+ }
3677
+ ),
3678
+ isOpen && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute z-[110] w-full mt-1.5 bg-white border border-slate-200 rounded-xl shadow-xl max-h-48 overflow-y-auto animate-in fade-in slide-in-from-top-1 duration-200 custom-scrollbar", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-1", children: options.filter((opt) => !isSelected(opt[valueProperty])).length > 0 ? options.filter((opt) => !isSelected(opt[valueProperty])).map((option, index) => {
3679
+ return /* @__PURE__ */ jsxRuntime.jsx(
3680
+ "div",
3681
+ {
3682
+ onClick: () => toggleOption(option[valueProperty]),
3683
+ className: "px-3 py-2 text-[12px] rounded-lg cursor-pointer transition-colors flex items-center justify-between text-slate-600 hover:bg-slate-50",
3684
+ children: option[labelProperty]
3685
+ },
3686
+ index
3687
+ );
3688
+ }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-3 py-3 text-[10px] text-slate-400 text-center font-bold uppercase tracking-wider", children: "All selected" }) }) })
3689
+ ] });
3690
+ };
3328
3691
  function ScriptBreakdownSceneView({
3329
3692
  blocks,
3330
3693
  characters,
@@ -3346,16 +3709,16 @@ function ScriptBreakdownSceneView({
3346
3709
  aiSummarized = false,
3347
3710
  onUpdateBrief
3348
3711
  }) {
3349
- const [expandedCategories, setExpandedCategories] = react.useState({});
3350
- const [editingTagData, setEditingTagData] = react.useState(null);
3351
- const [tagForm, setTagForm] = react.useState({ quantity: 1, look: "", age: "" });
3352
- const [popupPlacement, setPopupPlacement] = react.useState({
3712
+ const [expandedCategories, setExpandedCategories] = React4.useState({});
3713
+ const [editingTagData, setEditingTagData] = React4.useState(null);
3714
+ const [tagForm, setTagForm] = React4.useState({ quantity: 1, look: "", age: "", age_range: [], crowd_type: [] });
3715
+ const [popupPlacement, setPopupPlacement] = React4.useState({
3353
3716
  alignRight: false,
3354
3717
  alignBottom: false
3355
3718
  });
3356
- const [isSidebarOpen, setIsSidebarOpen] = react.useState(false);
3719
+ const [isSidebarOpen, setIsSidebarOpen] = React4.useState(false);
3357
3720
  const COURIER_STACK = "'Courier Prime', 'Courier', monospace";
3358
- react.useEffect(() => {
3721
+ React4.useEffect(() => {
3359
3722
  const fontId = "google-font-courier-prime";
3360
3723
  const styleId = "screenplay-editor-force-v4";
3361
3724
  if (!document.getElementById(fontId)) {
@@ -3709,7 +4072,7 @@ function ScriptBreakdownSceneView({
3709
4072
  title: tag.name,
3710
4073
  onClick: (e) => {
3711
4074
  e.stopPropagation();
3712
- if (cat.id !== "PROP" && cat.id !== "SET_PROP" && cat.id !== "CAST")
4075
+ if (cat.id !== "PROP" && cat.id !== "SET_PROP" && cat.id !== "CAST" && cat.id !== "EXTRA")
3713
4076
  return;
3714
4077
  if ((editingTagData == null ? void 0 : editingTagData.tag.id) === tag.id) {
3715
4078
  setEditingTagData(null);
@@ -3722,7 +4085,9 @@ function ScriptBreakdownSceneView({
3722
4085
  setTagForm({
3723
4086
  quantity: tag.quantity || 1,
3724
4087
  look: tag.look || "",
3725
- age: tag.age || ""
4088
+ age: tag.age || "",
4089
+ age_range: tag.age_range || [],
4090
+ crowd_type: tag.crowd_type || []
3726
4091
  });
3727
4092
  setEditingTagData({
3728
4093
  tag,
@@ -3732,7 +4097,7 @@ function ScriptBreakdownSceneView({
3732
4097
  });
3733
4098
  }
3734
4099
  },
3735
- className: `inline-block max-w-full truncate text-[11px] font-semibold px-3 py-1.5 rounded-full border backdrop-blur-md transition-all duration-300 ${cat.id === "PROP" || cat.id === "SET_PROP" || cat.id === "CAST" ? "cursor-pointer hover:scale-105 shadow-sm" : ""}`,
4100
+ className: `inline-block max-w-full truncate text-[11px] font-semibold px-3 py-1.5 rounded-full border backdrop-blur-md transition-all duration-300 cursor-pointer! ${cat.id === "PROP" || cat.id === "SET_PROP" || cat.id === "CAST" ? "cursor-pointer hover:scale-105 shadow-sm" : ""}`,
3736
4101
  style: {
3737
4102
  color: cat.color,
3738
4103
  background: `linear-gradient(145deg, ${cat.color}18, rgba(255,255,255,0.88))`,
@@ -3856,13 +4221,38 @@ function ScriptBreakdownSceneView({
3856
4221
  )
3857
4222
  ] })
3858
4223
  ] }),
4224
+ editingTagData.catId === "EXTRA" && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-3", children: [
4225
+ /* @__PURE__ */ jsxRuntime.jsx(
4226
+ MultiSelect,
4227
+ {
4228
+ label: "Age Range",
4229
+ options: crowdAgeOption,
4230
+ value: tagForm.age_range,
4231
+ returnObjects: true,
4232
+ onChange: (val) => setTagForm((prev) => __spreadProps(__spreadValues({}, prev), { age_range: val }))
4233
+ }
4234
+ ),
4235
+ /* @__PURE__ */ jsxRuntime.jsx(
4236
+ MultiSelect,
4237
+ {
4238
+ label: "Crowd Type",
4239
+ options: crowdTypeOption,
4240
+ value: tagForm.crowd_type,
4241
+ returnObjects: true,
4242
+ onChange: (val) => setTagForm((prev) => __spreadProps(__spreadValues({}, prev), { crowd_type: val }))
4243
+ }
4244
+ )
4245
+ ] }),
3859
4246
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-4", children: /* @__PURE__ */ jsxRuntime.jsx(
3860
4247
  "button",
3861
4248
  {
3862
4249
  onClick: (e) => {
3863
4250
  e.stopPropagation();
3864
4251
  if (editingTagData.tag.id) {
3865
- updateTag == null ? void 0 : updateTag(editingTagData.tag.id, editingTagData.catId, __spreadValues(__spreadValues({}, editingTagData.catId === "PROP" || editingTagData.catId === "SET_PROP" ? { quantity: tagForm.quantity } : {}), editingTagData.catId === "CAST" ? { look: tagForm.look, age: tagForm.age } : {}));
4252
+ updateTag == null ? void 0 : updateTag(editingTagData.tag.id, editingTagData.catId, __spreadValues(__spreadValues(__spreadValues({}, editingTagData.catId === "PROP" || editingTagData.catId === "SET_PROP" ? { quantity: tagForm.quantity } : {}), editingTagData.catId === "CAST" ? { look: tagForm.look, age: tagForm.age } : {}), editingTagData.catId === "EXTRA" ? {
4253
+ age_range: tagForm.age_range,
4254
+ crowd_type: tagForm.crowd_type
4255
+ } : {}));
3866
4256
  }
3867
4257
  setEditingTagData(null);
3868
4258
  },
@@ -3877,17 +4267,17 @@ function ScriptBreakdownSceneView({
3877
4267
  ] });
3878
4268
  }
3879
4269
  function useScriptBreakdownScene(options) {
3880
- const [tags, setTags] = react.useState(options.preLoadedTags || []);
3881
- const [selectionMenu, setSelectionMenu] = react.useState(null);
3882
- const autoTaggedSceneRef = react.useRef(null);
3883
- const [scene, setScene] = react.useState(null);
3884
- const [menuPlacement, setMenuPlacement] = react.useState("top");
3885
- const [sceneBrief, setSceneBrief] = react.useState("");
3886
- const [isSummarizing, setIsSummarizing] = react.useState(false);
3887
- const [isLoading, setIsLoading] = react.useState(true);
3888
- const [error, setError] = react.useState(false);
3889
- const menuRef = react.useRef(null);
3890
- react.useEffect(() => {
4270
+ const [tags, setTags] = React4.useState(options.preLoadedTags || []);
4271
+ const [selectionMenu, setSelectionMenu] = React4.useState(null);
4272
+ const autoTaggedSceneRef = React4.useRef(null);
4273
+ const [scene, setScene] = React4.useState(null);
4274
+ const [menuPlacement, setMenuPlacement] = React4.useState("top");
4275
+ const [sceneBrief, setSceneBrief] = React4.useState("");
4276
+ const [isSummarizing, setIsSummarizing] = React4.useState(false);
4277
+ const [isLoading, setIsLoading] = React4.useState(true);
4278
+ const [error, setError] = React4.useState(false);
4279
+ const menuRef = React4.useRef(null);
4280
+ React4.useEffect(() => {
3891
4281
  setIsLoading(true);
3892
4282
  const fetchScene = async () => {
3893
4283
  try {
@@ -3908,7 +4298,7 @@ function useScriptBreakdownScene(options) {
3908
4298
  };
3909
4299
  fetchScene();
3910
4300
  }, []);
3911
- const blocks = react.useMemo(() => {
4301
+ const blocks = React4.useMemo(() => {
3912
4302
  if (!scene || !scene.content) return [];
3913
4303
  const parser = new DOMParser();
3914
4304
  const doc = parser.parseFromString(scene.content, "text/html");
@@ -3939,7 +4329,7 @@ function useScriptBreakdownScene(options) {
3939
4329
  });
3940
4330
  return parsedBlocks;
3941
4331
  }, [scene]);
3942
- const characters = react.useMemo(() => {
4332
+ const characters = React4.useMemo(() => {
3943
4333
  const chars = blocks.filter((b) => b.type === "CHARACTER").map((b) => {
3944
4334
  const text = b.text.trim().toUpperCase();
3945
4335
  const parenIndex = text.indexOf("(");
@@ -4017,7 +4407,7 @@ function useScriptBreakdownScene(options) {
4017
4407
  console.error("Failed to summarize scene:", res);
4018
4408
  }
4019
4409
  };
4020
- const bulkCreateTags = react.useCallback(async () => {
4410
+ const bulkCreateTags = React4.useCallback(async () => {
4021
4411
  if (blocks.length === 0) return;
4022
4412
  const newTags = [];
4023
4413
  const seenCharacters = /* @__PURE__ */ new Set();
@@ -4125,11 +4515,11 @@ function useScriptBreakdownScene(options) {
4125
4515
  }
4126
4516
  }
4127
4517
  }, [blocks, tags, options.onTagsBulkAdded]);
4128
- react.useEffect(() => {
4518
+ React4.useEffect(() => {
4129
4519
  setSceneBrief("");
4130
4520
  autoTaggedSceneRef.current = null;
4131
4521
  }, [options.scene_url]);
4132
- react.useEffect(() => {
4522
+ React4.useEffect(() => {
4133
4523
  if (options.preLoadedTags && options.preLoadedTags.length > 0) {
4134
4524
  setTags((prev) => {
4135
4525
  if (JSON.stringify(prev) === JSON.stringify(options.preLoadedTags)) {
@@ -4139,7 +4529,7 @@ function useScriptBreakdownScene(options) {
4139
4529
  });
4140
4530
  }
4141
4531
  }, [options.preLoadedTags]);
4142
- react.useEffect(() => {
4532
+ React4.useEffect(() => {
4143
4533
  const doBulkCreate = async () => {
4144
4534
  if (blocks.length === 0) return;
4145
4535
  if (options.preLoadedTagsLoading) return;
@@ -4156,17 +4546,17 @@ function useScriptBreakdownScene(options) {
4156
4546
  options.preLoadedTags,
4157
4547
  options.preLoadedTagsLoading
4158
4548
  ]);
4159
- const clearSelection = react.useCallback(() => {
4549
+ const clearSelection = React4.useCallback(() => {
4160
4550
  var _a;
4161
4551
  setSelectionMenu(null);
4162
4552
  (_a = window.getSelection()) == null ? void 0 : _a.removeAllRanges();
4163
4553
  }, []);
4164
- react.useEffect(() => {
4554
+ React4.useEffect(() => {
4165
4555
  if (!selectionMenu) {
4166
4556
  setMenuPlacement("top");
4167
4557
  }
4168
4558
  }, [selectionMenu]);
4169
- react.useEffect(() => {
4559
+ React4.useEffect(() => {
4170
4560
  if (selectionMenu && menuRef.current) {
4171
4561
  const rect = menuRef.current.getBoundingClientRect();
4172
4562
  if (menuPlacement === "top" && rect.top < 100) {
@@ -4176,7 +4566,7 @@ function useScriptBreakdownScene(options) {
4176
4566
  }
4177
4567
  }
4178
4568
  }, [selectionMenu, menuPlacement]);
4179
- react.useEffect(() => {
4569
+ React4.useEffect(() => {
4180
4570
  const handleClickOutside = (e) => {
4181
4571
  if (selectionMenu && !e.target.closest(".tag-menu")) {
4182
4572
  clearSelection();
@@ -4347,7 +4737,7 @@ function ModalLayout({
4347
4737
  maxWidth = "max-w-4xl",
4348
4738
  menuRef
4349
4739
  }) {
4350
- react.useEffect(() => {
4740
+ React4.useEffect(() => {
4351
4741
  document.body.style.overflow = "hidden";
4352
4742
  return () => {
4353
4743
  document.body.style.overflow = "";
@@ -4403,196 +4793,6 @@ function ModalLayout({
4403
4793
  );
4404
4794
  }
4405
4795
  var modal_layout_default = ModalLayout;
4406
- var FormikSelect = ({
4407
- label,
4408
- name,
4409
- selectedOption,
4410
- optionData,
4411
- value,
4412
- disable,
4413
- divClasses,
4414
- valueProperty = "name",
4415
- labelProperty = "name",
4416
- label2propery,
4417
- brackets,
4418
- className,
4419
- enableRedAsterick = false,
4420
- disableOptionProperty = "disable",
4421
- disabledOptionText = "",
4422
- onChange
4423
- }) => {
4424
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `w-full ${divClasses}`, children: [
4425
- label && /* @__PURE__ */ jsxRuntime.jsxs("label", { className: `mb-1.5 text-sm font-medium text-slate-700 capitalize flex`, children: [
4426
- label,
4427
- enableRedAsterick && /* @__PURE__ */ jsxRuntime.jsx(lucideReact.AsteriskIcon, { className: "size-3 text-red-500" })
4428
- ] }),
4429
- /* @__PURE__ */ jsxRuntime.jsxs(
4430
- formik.Field,
4431
- {
4432
- name,
4433
- as: "select",
4434
- value,
4435
- disabled: disable,
4436
- onChange,
4437
- className: `${className} rounded-[2.5rem] block w-full px-3 py-2.5 text-slate-700 placeholder-slate-400 placeholder:capitalize bg-white border border-slate-300/80 focus:border-blumine-500 focus:ring-2 focus:ring-blumine-500/50 focus:outline-none transition-all`,
4438
- children: [
4439
- /* @__PURE__ */ jsxRuntime.jsx("option", { selected: true, value: "", disabled: true, className: "capitalize", children: selectedOption }),
4440
- optionData == null ? void 0 : optionData.map((option, index) => /* @__PURE__ */ jsxRuntime.jsxs(
4441
- "option",
4442
- {
4443
- value: option[valueProperty],
4444
- disabled: option[disableOptionProperty],
4445
- children: [
4446
- option[labelProperty],
4447
- label2propery ? brackets ? ` (${option[label2propery]})` : option[label2propery] : "",
4448
- " ",
4449
- option[disableOptionProperty] && `(${disabledOptionText})`
4450
- ]
4451
- },
4452
- index
4453
- ))
4454
- ]
4455
- }
4456
- ),
4457
- /* @__PURE__ */ jsxRuntime.jsx(
4458
- formik.ErrorMessage,
4459
- {
4460
- name,
4461
- className: "text-red-500 text-sm mt-1",
4462
- component: "div"
4463
- }
4464
- )
4465
- ] });
4466
- };
4467
- var FormikInput = (_a) => {
4468
- var _b = _a, {
4469
- label,
4470
- name,
4471
- type,
4472
- placeholder,
4473
- className,
4474
- labelClassName,
4475
- readOnly,
4476
- divClasses,
4477
- length,
4478
- disable,
4479
- min = 0,
4480
- max,
4481
- convertToText = false,
4482
- enableRedAsterick = false,
4483
- case_sensitivity = "normal"
4484
- } = _b, props = __objRest(_b, [
4485
- "label",
4486
- "name",
4487
- "type",
4488
- "placeholder",
4489
- "className",
4490
- "labelClassName",
4491
- "readOnly",
4492
- "divClasses",
4493
- "length",
4494
- "disable",
4495
- "min",
4496
- "max",
4497
- "convertToText",
4498
- "enableRedAsterick",
4499
- "case_sensitivity"
4500
- ]);
4501
- const { setFieldValue } = formik.useFormikContext();
4502
- const handleCaseChange = (e) => {
4503
- let value = e.target.value;
4504
- if (type === "number" && min !== void 0) {
4505
- if (value !== "" && Number(value) < min) return;
4506
- }
4507
- switch (case_sensitivity) {
4508
- case "lowercase":
4509
- value = value.toLowerCase();
4510
- break;
4511
- case "uppercase":
4512
- value = value.toUpperCase();
4513
- break;
4514
- }
4515
- setFieldValue(name, value);
4516
- };
4517
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `w-full ${divClasses}`, children: [
4518
- /* @__PURE__ */ jsxRuntime.jsxs(
4519
- "label",
4520
- {
4521
- className: `${labelClassName} mb-1.5 text-sm font-medium text-slate-700 capitalize flex`,
4522
- children: [
4523
- label,
4524
- enableRedAsterick && /* @__PURE__ */ jsxRuntime.jsx(lucideReact.AsteriskIcon, { className: "size-3 text-red-500" })
4525
- ]
4526
- }
4527
- ),
4528
- /* @__PURE__ */ jsxRuntime.jsx(
4529
- formik.Field,
4530
- __spreadProps(__spreadValues({
4531
- name,
4532
- placeholder,
4533
- readOnly,
4534
- type,
4535
- maxLength: length,
4536
- disabled: disable,
4537
- max,
4538
- min,
4539
- onChange: handleCaseChange
4540
- }, props), {
4541
- className: `${className} rounded-[2.5rem] block w-full px-3 py-2.5 text-slate-700 placeholder-slate-400 placeholder:capitalize bg-white border border-slate-300/80 focus:border-blumine-500 focus:ring-2 focus:ring-blumine-500/50 focus:outline-none transition-all disabled:opacity-70`
4542
- })
4543
- ),
4544
- /* @__PURE__ */ jsxRuntime.jsx(
4545
- formik.ErrorMessage,
4546
- {
4547
- name,
4548
- className: "text-red-500 text-sm mt-1",
4549
- component: "div"
4550
- }
4551
- )
4552
- ] });
4553
- };
4554
- var FormikTextarea = ({
4555
- label,
4556
- name,
4557
- placeholder,
4558
- readOnly,
4559
- divClasses = "",
4560
- className = "",
4561
- length,
4562
- disable,
4563
- min,
4564
- max,
4565
- enableRedAsterick = false
4566
- }) => {
4567
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `w-full ${divClasses}`, children: [
4568
- /* @__PURE__ */ jsxRuntime.jsxs("label", { className: `mb-1.5 text-sm font-medium text-slate-700 capitalize flex`, children: [
4569
- label,
4570
- enableRedAsterick && /* @__PURE__ */ jsxRuntime.jsx(lucideReact.AsteriskIcon, { className: "size-3 text-red-500" })
4571
- ] }),
4572
- /* @__PURE__ */ jsxRuntime.jsx(
4573
- formik.Field,
4574
- {
4575
- as: "textarea",
4576
- name,
4577
- placeholder,
4578
- readOnly,
4579
- maxLength: length,
4580
- disabled: disable,
4581
- max,
4582
- min,
4583
- className: `${className} block w-full px-4 py-3 text-slate-700 placeholder-slate-400 placeholder:capitalize bg-white border border-slate-300/80 rounded-2xl focus:border-blumine-500 focus:ring-2 focus:ring-blumine-500/50 focus:outline-none transition-all disabled:opacity-70`
4584
- }
4585
- ),
4586
- /* @__PURE__ */ jsxRuntime.jsx(
4587
- formik.ErrorMessage,
4588
- {
4589
- name,
4590
- className: "text-red-500 text-sm mt-1",
4591
- component: "div"
4592
- }
4593
- )
4594
- ] });
4595
- };
4596
4796
 
4597
4797
  // data/shot-data.ts
4598
4798
  var shot_types = [
@@ -4863,8 +5063,8 @@ var AddShotForm = ({
4863
5063
  duration_seconds: Yup__namespace.number().min(0).required("Required"),
4864
5064
  camera_name: Yup__namespace.string().required("Required")
4865
5065
  });
4866
- const [step, setStep] = react.useState(1);
4867
- const [highestStep, setHighestStep] = react.useState(1);
5066
+ const [step, setStep] = React4.useState(1);
5067
+ const [highestStep, setHighestStep] = React4.useState(1);
4868
5068
  return /* @__PURE__ */ jsxRuntime.jsx(
4869
5069
  formik.Formik,
4870
5070
  {
@@ -5353,22 +5553,32 @@ var ProductionSetupModal = ({
5353
5553
  initialValues
5354
5554
  }) => {
5355
5555
  return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "min-h-[80vh] flex items-center justify-center px-6", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "w-full max-w-lg", children: [
5356
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mb-8 text-center", children: [
5556
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "my-8 text-center", children: [
5357
5557
  /* @__PURE__ */ jsxRuntime.jsx("h1", { className: "text-2xl md:text-3xl font-semibold text-slate-900 tracking-tight", children: "Production Setup for this Scene" }),
5358
5558
  /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-slate-500 mt-2", children: "Configure your scene and camera setup to get started" })
5359
5559
  ] }),
5360
5560
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-6 md:p-8", children: /* @__PURE__ */ jsxRuntime.jsx(
5361
5561
  formik.Formik,
5362
5562
  {
5363
- initialValues: initialValues || { numCameras: 1, scene_type: "" },
5563
+ initialValues: initialValues || {
5564
+ numCameras: 1,
5565
+ scene_type: "",
5566
+ dance_choreographer_required: false,
5567
+ action_sequence_required: false
5568
+ },
5364
5569
  validationSchema: Yup__namespace.object({
5365
5570
  numCameras: Yup__namespace.number().min(1, "Must be at least 1").max(20, "Cannot add more than 20 cameras").required("Number of cameras is required"),
5366
5571
  scene_type: Yup__namespace.string().required("Scene type is required")
5367
5572
  }),
5368
5573
  onSubmit: async (values) => {
5369
- await initializeProduction(values.numCameras, values.scene_type);
5574
+ await initializeProduction(
5575
+ values.numCameras,
5576
+ values.scene_type,
5577
+ values.dance_choreographer_required,
5578
+ values.action_sequence_required
5579
+ );
5370
5580
  },
5371
- children: ({ isSubmitting, setFieldValue }) => /* @__PURE__ */ jsxRuntime.jsxs(formik.Form, { className: "flex flex-col gap-6", children: [
5581
+ children: ({ isSubmitting, setFieldValue, values }) => /* @__PURE__ */ jsxRuntime.jsxs(formik.Form, { className: "flex flex-col gap-6", children: [
5372
5582
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid gap-5", children: [
5373
5583
  /* @__PURE__ */ jsxRuntime.jsx(
5374
5584
  FormikSelect,
@@ -5391,7 +5601,65 @@ var ProductionSetupModal = ({
5391
5601
  max: 20,
5392
5602
  enableRedAsterick: true
5393
5603
  }
5394
- )
5604
+ ),
5605
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-4", children: [
5606
+ /* @__PURE__ */ jsxRuntime.jsx(
5607
+ "div",
5608
+ {
5609
+ className: `relative p-5 rounded-3xl border transition-all duration-300 flex flex-col gap-4 group cursor-pointer ${values.dance_choreographer_required ? "bg-blumine-50/30 border-blumine-200 shadow-sm" : "bg-slate-50/50 border-slate-100 hover:border-slate-200"}`,
5610
+ onClick: () => setFieldValue(
5611
+ "dance_choreographer_required",
5612
+ !values.dance_choreographer_required
5613
+ ),
5614
+ children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between w-full", children: [
5615
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
5616
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-[15px] font-bold text-slate-800", children: "Dance Sequence" }),
5617
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-[11px] text-slate-500 font-medium mt-0.5", children: "Choreography needed" })
5618
+ ] }),
5619
+ /* @__PURE__ */ jsxRuntime.jsx(
5620
+ Switch,
5621
+ {
5622
+ isOn: values.dance_choreographer_required || false,
5623
+ handleToggle: () => setFieldValue(
5624
+ "dance_choreographer_required",
5625
+ !values.dance_choreographer_required
5626
+ ),
5627
+ activeColor: "bg-blumine-600",
5628
+ divClasses: "w-fit!"
5629
+ }
5630
+ )
5631
+ ] })
5632
+ }
5633
+ ),
5634
+ /* @__PURE__ */ jsxRuntime.jsx(
5635
+ "div",
5636
+ {
5637
+ className: `relative p-5 rounded-3xl border transition-all duration-300 flex flex-col gap-4 group cursor-pointer ${values.action_sequence_required ? "bg-rose-50/30 border-rose-200 shadow-sm" : "bg-slate-50/50 border-slate-100 hover:border-slate-200"}`,
5638
+ onClick: () => setFieldValue(
5639
+ "action_sequence_required",
5640
+ !values.action_sequence_required
5641
+ ),
5642
+ children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between w-full", children: [
5643
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
5644
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-[15px] font-bold text-slate-800", children: "Action Sequence" }),
5645
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-[11px] text-slate-500 font-medium mt-0.5", children: "Stunt & combat logic" })
5646
+ ] }),
5647
+ /* @__PURE__ */ jsxRuntime.jsx(
5648
+ Switch,
5649
+ {
5650
+ isOn: values.action_sequence_required || false,
5651
+ handleToggle: () => setFieldValue(
5652
+ "action_sequence_required",
5653
+ !values.action_sequence_required
5654
+ ),
5655
+ activeColor: "bg-rose-500",
5656
+ divClasses: "w-fit!"
5657
+ }
5658
+ )
5659
+ ] })
5660
+ }
5661
+ )
5662
+ ] })
5395
5663
  ] }),
5396
5664
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-3 bg-slate-50 border border-slate-100 p-4 rounded-xl", children: [
5397
5665
  /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Info, { className: "w-5 h-5 text-slate-400 shrink-0 mt-0.5" }),
@@ -5625,18 +5893,18 @@ function ShotBreakdownView({
5625
5893
  }) {
5626
5894
  var _a, _b, _c;
5627
5895
  const COURIER_STACK = "'Courier Prime', 'Courier', monospace";
5628
- const containerRef = react.useRef(null);
5629
- const [isSidebarOpen, setIsSidebarOpen] = react.useState(false);
5630
- const [toggledShotId, setToggledShotId] = react.useState(
5896
+ const containerRef = React4.useRef(null);
5897
+ const [isSidebarOpen, setIsSidebarOpen] = React4.useState(false);
5898
+ const [toggledShotId, setToggledShotId] = React4.useState(
5631
5899
  null
5632
5900
  );
5633
- const [viewingShotId, setViewingShotId] = react.useState(
5901
+ const [viewingShotId, setViewingShotId] = React4.useState(
5634
5902
  null
5635
5903
  );
5636
- const [updatingShotId, setUpdatingShotId] = react.useState(
5904
+ const [updatingShotId, setUpdatingShotId] = React4.useState(
5637
5905
  null
5638
5906
  );
5639
- const [isInitModalOpen, setIsInitModalOpen] = react.useState(false);
5907
+ const [isInitModalOpen, setIsInitModalOpen] = React4.useState(false);
5640
5908
  const handleCloseModal = () => {
5641
5909
  clearSelection();
5642
5910
  };
@@ -5687,7 +5955,7 @@ function ShotBreakdownView({
5687
5955
  }
5688
5956
  return nodes;
5689
5957
  };
5690
- react.useEffect(() => {
5958
+ React4.useEffect(() => {
5691
5959
  const fontId = "google-font-courier-prime";
5692
5960
  const styleId = "screenplay-editor-force-v4";
5693
5961
  if (!document.getElementById(fontId)) {
@@ -5933,14 +6201,21 @@ function ShotBreakdownView({
5933
6201
  children: /* @__PURE__ */ jsxRuntime.jsx(
5934
6202
  production_setup_modal_default,
5935
6203
  {
5936
- initializeProduction: (count, type) => {
5937
- initializeProduction(count, type).then(() => {
6204
+ initializeProduction: (count, type, dance_choreographer_required, action_sequence_required) => {
6205
+ initializeProduction(
6206
+ count,
6207
+ type,
6208
+ dance_choreographer_required,
6209
+ action_sequence_required
6210
+ ).then(() => {
5938
6211
  setIsInitModalOpen(false);
5939
6212
  });
5940
6213
  },
5941
6214
  initialValues: {
5942
6215
  numCameras: cameras.length || 1,
5943
- scene_type: sceneType
6216
+ scene_type: sceneType,
6217
+ dance_choreographer_required: false,
6218
+ action_sequence_required: false
5944
6219
  }
5945
6220
  }
5946
6221
  )
@@ -5983,20 +6258,20 @@ function ShotBreakdownView({
5983
6258
  );
5984
6259
  }
5985
6260
  function useShotBreakdownScene(options) {
5986
- const [shots, setShots] = react.useState(options.preloadedShots || []);
5987
- const [cameras, setCameras] = react.useState(
6261
+ const [shots, setShots] = React4.useState(options.preloadedShots || []);
6262
+ const [cameras, setCameras] = React4.useState(
5988
6263
  options.preloadedCameras || []
5989
6264
  );
5990
- const [sceneType, setSceneType] = react.useState(
6265
+ const [sceneType, setSceneType] = React4.useState(
5991
6266
  options.preloadedSceneType || ""
5992
6267
  );
5993
- const [scene, setScene] = react.useState(null);
5994
- const [isLoading, setIsLoading] = react.useState(true);
5995
- const [isSummarizing, setIsSummarizing] = react.useState(false);
5996
- const [error, setError] = react.useState(false);
5997
- const [selectionMenu, setSelectionMenu] = react.useState(null);
5998
- const menuRef = react.useRef(null);
5999
- react.useEffect(() => {
6268
+ const [scene, setScene] = React4.useState(null);
6269
+ const [isLoading, setIsLoading] = React4.useState(true);
6270
+ const [isSummarizing, setIsSummarizing] = React4.useState(false);
6271
+ const [error, setError] = React4.useState(false);
6272
+ const [selectionMenu, setSelectionMenu] = React4.useState(null);
6273
+ const menuRef = React4.useRef(null);
6274
+ React4.useEffect(() => {
6000
6275
  if (options.preloadedShots && options.preloadedShots.length > 0) {
6001
6276
  setShots((prev) => {
6002
6277
  if (JSON.stringify(prev) === JSON.stringify(options.preloadedShots)) {
@@ -6006,7 +6281,7 @@ function useShotBreakdownScene(options) {
6006
6281
  });
6007
6282
  }
6008
6283
  }, [options.preloadedShots]);
6009
- react.useEffect(() => {
6284
+ React4.useEffect(() => {
6010
6285
  if (options.preloadedCameras && options.preloadedCameras.length > 0) {
6011
6286
  setCameras((prev) => {
6012
6287
  if (JSON.stringify(prev) === JSON.stringify(options.preloadedCameras)) {
@@ -6016,7 +6291,7 @@ function useShotBreakdownScene(options) {
6016
6291
  });
6017
6292
  }
6018
6293
  }, [options.preloadedCameras]);
6019
- react.useEffect(() => {
6294
+ React4.useEffect(() => {
6020
6295
  if (options.preloadedSceneType) {
6021
6296
  setSceneType((prev) => {
6022
6297
  if (prev === options.preloadedSceneType) return prev;
@@ -6024,7 +6299,7 @@ function useShotBreakdownScene(options) {
6024
6299
  });
6025
6300
  }
6026
6301
  }, [options.preloadedSceneType]);
6027
- react.useEffect(() => {
6302
+ React4.useEffect(() => {
6028
6303
  setIsLoading(true);
6029
6304
  const fetchScene = async () => {
6030
6305
  try {
@@ -6045,7 +6320,7 @@ function useShotBreakdownScene(options) {
6045
6320
  };
6046
6321
  fetchScene();
6047
6322
  }, []);
6048
- const blocks = react.useMemo(() => {
6323
+ const blocks = React4.useMemo(() => {
6049
6324
  if (!scene || !scene.content) return [];
6050
6325
  const parser = new DOMParser();
6051
6326
  const doc = parser.parseFromString(scene.content, "text/html");
@@ -6081,7 +6356,7 @@ function useShotBreakdownScene(options) {
6081
6356
  setSelectionMenu(null);
6082
6357
  (_a = window.getSelection()) == null ? void 0 : _a.removeAllRanges();
6083
6358
  };
6084
- react.useEffect(() => {
6359
+ React4.useEffect(() => {
6085
6360
  const handleClickOutside = (e) => {
6086
6361
  if (menuRef.current && !menuRef.current.contains(e.target)) {
6087
6362
  clearSelection();
@@ -6156,13 +6431,19 @@ function useShotBreakdownScene(options) {
6156
6431
  });
6157
6432
  }
6158
6433
  };
6159
- const initializeProduction = async (count, type) => {
6434
+ const initializeProduction = async (count, type, dance_choreographer_required, action_sequence_required) => {
6160
6435
  var _a;
6161
6436
  const newCameras = [];
6162
6437
  for (let i = 1; i <= count; i++) {
6163
6438
  newCameras.push({ name: `Camera ${String.fromCharCode(64 + i)}` });
6164
6439
  }
6165
- const result = (_a = options.onProductionInitialized) == null ? void 0 : _a.call(options, newCameras, type);
6440
+ const result = (_a = options.onProductionInitialized) == null ? void 0 : _a.call(
6441
+ options,
6442
+ newCameras,
6443
+ type,
6444
+ dance_choreographer_required,
6445
+ action_sequence_required
6446
+ );
6166
6447
  if (result instanceof Promise) {
6167
6448
  setCameras(newCameras);
6168
6449
  setSceneType(type);
@@ -6293,7 +6574,7 @@ function SceneScriptView({
6293
6574
  title
6294
6575
  }) {
6295
6576
  const COURIER_STACK = "'Courier Prime', 'Courier', monospace";
6296
- react.useEffect(() => {
6577
+ React4.useEffect(() => {
6297
6578
  const fontId = "google-font-courier-prime";
6298
6579
  const styleId = "screenplay-editor-force-v4";
6299
6580
  if (!document.getElementById(fontId)) {
@@ -6359,10 +6640,10 @@ function SceneScriptView({
6359
6640
  );
6360
6641
  }
6361
6642
  function useSceneScript(options) {
6362
- const [sceneContent, setSceneContent] = react.useState(null);
6363
- const [isLoading, setIsLoading] = react.useState(true);
6364
- const [error, setError] = react.useState(null);
6365
- react.useEffect(() => {
6643
+ const [sceneContent, setSceneContent] = React4.useState(null);
6644
+ const [isLoading, setIsLoading] = React4.useState(true);
6645
+ const [error, setError] = React4.useState(null);
6646
+ React4.useEffect(() => {
6366
6647
  let isMounted = true;
6367
6648
  setIsLoading(true);
6368
6649
  setError(null);
@@ -6394,7 +6675,7 @@ function useSceneScript(options) {
6394
6675
  isMounted = false;
6395
6676
  };
6396
6677
  }, [options.scene_url]);
6397
- const blocks = react.useMemo(() => {
6678
+ const blocks = React4.useMemo(() => {
6398
6679
  if (!sceneContent) return [];
6399
6680
  const parser = new DOMParser();
6400
6681
  const doc = parser.parseFromString(sceneContent, "text/html");