@vishu1301/script-writing 1.4.0 → 1.4.2

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
@@ -1589,7 +1589,12 @@ function useScreenplayEditor(options) {
1589
1589
  }
1590
1590
  }
1591
1591
  const filename = ((_a = url.split("/").pop()) == null ? void 0 : _a.replace(/\.sbx$/i, "")) || "Imported from URL";
1592
- handleScriptImport(filename, scriptContent, preParsedBlocks, isInitialLoad);
1592
+ handleScriptImport(
1593
+ filename,
1594
+ scriptContent,
1595
+ preParsedBlocks,
1596
+ isInitialLoad
1597
+ );
1593
1598
  } catch (error) {
1594
1599
  console.error(
1595
1600
  "[useScreenplayEditor] Error loading script from URL:",
@@ -2823,9 +2828,7 @@ function useScriptBreakdownScene(options) {
2823
2828
  await ((_d = options.onTagUpdated) == null ? void 0 : _d.call(options, id, categoryId || null, details));
2824
2829
  } catch (error2) {
2825
2830
  console.error("Failed to update tag:", error2);
2826
- setTags(
2827
- (prev) => prev.map((t) => t.id === id ? tagToUpdate : t)
2828
- );
2831
+ setTags((prev) => prev.map((t) => t.id === id ? tagToUpdate : t));
2829
2832
  }
2830
2833
  };
2831
2834
  return {
@@ -3251,17 +3254,17 @@ var vfx_types = [
3251
3254
  { name: "CG Lighting / Light Wrap" }
3252
3255
  ];
3253
3256
  var fps_options = [
3254
- { value: "23.98", label: "23.98 fps" },
3255
- { value: "24", label: "24 fps" },
3256
- { value: "25", label: "25 fps" },
3257
- { value: "29.97", label: "29.97 fps" },
3258
- { value: "30", label: "30 fps" },
3259
- { value: "48", label: "48 fps" },
3260
- { value: "50", label: "50 fps" },
3261
- { value: "59.94", label: "59.94 fps" },
3262
- { value: "60", label: "60 fps" },
3263
- { value: "120", label: "120 fps (Slow Motion)" },
3264
- { value: "240", label: "240 fps (High Speed)" }
3257
+ { value: 23.98, label: "23.98 fps" },
3258
+ { value: 24, label: "24 fps" },
3259
+ { value: 25, label: "25 fps" },
3260
+ { value: 29.97, label: "29.97 fps" },
3261
+ { value: 30, label: "30 fps" },
3262
+ { value: 48, label: "48 fps" },
3263
+ { value: 50, label: "50 fps" },
3264
+ { value: 59.94, label: "59.94 fps" },
3265
+ { value: 60, label: "60 fps" },
3266
+ { value: 120, label: "120 fps (Slow Motion)" },
3267
+ { value: 240, label: "240 fps (High Speed)" }
3265
3268
  ];
3266
3269
  var scene_types = [
3267
3270
  { name: "Action / Adventure" },
@@ -3347,7 +3350,7 @@ var AddShotForm = ({
3347
3350
  lens_mm: "",
3348
3351
  lens_feel: "",
3349
3352
  aperture: "T2.8",
3350
- fps: "24",
3353
+ fps: 24,
3351
3354
  depth_of_field: "",
3352
3355
  subject: "",
3353
3356
  action_blocking: "",
@@ -4127,7 +4130,10 @@ function ShotBreakdownView({
4127
4130
  menuRef,
4128
4131
  cameras,
4129
4132
  sceneType,
4130
- initializeProduction
4133
+ initializeProduction,
4134
+ handleAISummarize,
4135
+ isSummarizing,
4136
+ aiSummarized = false
4131
4137
  }) {
4132
4138
  var _a, _b, _c;
4133
4139
  const COURIER_STACK = "'Courier Prime', 'Courier', monospace";
@@ -4281,115 +4287,132 @@ function ShotBreakdownView({
4281
4287
  "div",
4282
4288
  {
4283
4289
  className: `fixed xl:absolute top-0 right-0 z-50 h-full w-72 transform transition-transform duration-300 ease-[cubic-bezier(0.22,1,0.36,1)] xl:translate-x-0 ${isSidebarOpen ? "translate-x-0 shadow-[0_0_40px_rgba(0,0,0,0.1)]" : "translate-x-full"}`,
4284
- children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "sticky top-0 flex h-[100dvh] max-h-screen w-full flex-col border-l border-l-[#eefafd] bg-white p-3 py-5", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative flex flex-col gap-3 py-5 my-5 flex-1 overflow-hidden", children: [
4285
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative flex items-center justify-between mb-2 shrink-0 px-1", children: [
4286
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2.5", children: [
4287
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex h-7 w-7 items-center justify-center rounded-md border border-slate-200 bg-slate-50 shadow-sm", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Video, { className: "h-3.5 w-3.5 text-slate-700" }) }),
4288
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col", children: [
4289
- /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-[11px] font-bold uppercase tracking-widest text-slate-800", children: "Shots" }),
4290
- sceneType && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[9px] font-bold text-[#15607b] uppercase tracking-tighter opacity-80 mt-0.5", children: sceneType })
4290
+ children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "sticky top-0 flex h-[100dvh] max-h-screen w-full flex-col border-l border-l-[#eefafd] bg-white p-3 py-5", children: [
4291
+ !aiSummarized && /* @__PURE__ */ jsxRuntime.jsx(
4292
+ summarize_button_default,
4293
+ {
4294
+ onSummarize: handleAISummarize,
4295
+ isSummarizing
4296
+ }
4297
+ ),
4298
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative flex flex-col gap-3 py-5 my-5 border-t border-t-[#eefafd] flex-1 overflow-hidden", children: [
4299
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative flex items-center justify-between mb-6 shrink-0 px-1", children: [
4300
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3", children: [
4301
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "relative flex h-8 w-8 items-center justify-center rounded-[10px] border border-[#15607b]/20 bg-white shadow-sm", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Video, { className: "h-4 w-4 text-[#15607b]" }) }),
4302
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col", children: [
4303
+ /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-[12px] font-semibold uppercase tracking-[0.28em] text-[#134a61]", children: "Shots" }),
4304
+ sceneType && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[9px] font-bold text-[#15607b] uppercase tracking-tighter opacity-80 mt-0.5", children: sceneType })
4305
+ ] })
4306
+ ] }),
4307
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
4308
+ cameras.length === 0 && /* @__PURE__ */ jsxRuntime.jsx(
4309
+ "button",
4310
+ {
4311
+ onClick: () => setIsInitModalOpen(true),
4312
+ className: "flex h-7 w-7 items-center justify-center rounded-md border border-slate-200 bg-white shadow-sm transition-colors hover:bg-slate-50",
4313
+ title: "Project Setup",
4314
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Settings2, { className: "h-3.5 w-3.5 text-slate-600" })
4315
+ }
4316
+ ),
4317
+ shots.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "rounded-md border border-slate-200 bg-white px-2 py-0.5 text-[10px] font-semibold text-slate-600 shadow-sm", children: shots.length })
4291
4318
  ] })
4292
4319
  ] }),
4293
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
4294
- cameras.length === 0 && /* @__PURE__ */ jsxRuntime.jsx(
4295
- "button",
4320
+ shots.length === 0 ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-center justify-center py-10 px-4 text-center", children: [
4321
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex h-10 w-10 items-center justify-center rounded-full bg-slate-50 border border-slate-100 mb-3", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Video, { className: "h-4 w-4 text-slate-300" }) }),
4322
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs font-semibold text-slate-700", children: "No shots created" }),
4323
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-[11px] text-slate-500 mt-1 max-w-[160px] leading-relaxed", children: "Highlight text in the screenplay to add your first shot." })
4324
+ ] }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col gap-2.5 overflow-y-auto overflow-x-hidden pb-4 pr-2 custom-scrollbar", children: shots.map((shot) => {
4325
+ const isActive = toggledShotId === shot.id;
4326
+ return /* @__PURE__ */ jsxRuntime.jsxs(
4327
+ "div",
4296
4328
  {
4297
- onClick: () => setIsInitModalOpen(true),
4298
- className: "flex h-7 w-7 items-center justify-center rounded-md border border-slate-200 bg-white shadow-sm transition-colors hover:bg-slate-50",
4299
- title: "Project Setup",
4300
- children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Settings2, { className: "h-3.5 w-3.5 text-slate-600" })
4301
- }
4302
- ),
4303
- shots.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "rounded-md border border-slate-200 bg-white px-2 py-0.5 text-[10px] font-semibold text-slate-600 shadow-sm", children: shots.length })
4304
- ] })
4305
- ] }),
4306
- cameras.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-wrap gap-1.5 px-1 mb-6 mt-2", children: /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "inline-flex items-center gap-1.5 text-[9px] font-bold uppercase tracking-widest bg-slate-100 text-slate-500 px-2 py-1 rounded-md border border-slate-200/50", children: [
4307
- cameras.length,
4308
- " Multi-Cam Setup"
4309
- ] }) }),
4310
- shots.length === 0 ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-center justify-center py-10 px-4 text-center", children: [
4311
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex h-10 w-10 items-center justify-center rounded-full bg-slate-50 border border-slate-100 mb-3", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Video, { className: "h-4 w-4 text-slate-300" }) }),
4312
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs font-semibold text-slate-700", children: "No shots created" }),
4313
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-[11px] text-slate-500 mt-1 max-w-[160px] leading-relaxed", children: "Highlight text in the screenplay to add your first shot." })
4314
- ] }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col gap-2.5 overflow-y-auto overflow-x-hidden pb-4 pr-2 custom-scrollbar", children: shots.map((shot) => {
4315
- const isActive = toggledShotId === shot.id;
4316
- return /* @__PURE__ */ jsxRuntime.jsxs(
4317
- "div",
4318
- {
4319
- onClick: () => {
4320
- var _a2;
4321
- return setToggledShotId(isActive ? null : (_a2 = shot.id) != null ? _a2 : null);
4322
- },
4323
- className: `group relative flex flex-col cursor-pointer gap-2 overflow-hidden rounded-lg border px-3.5 py-3 transition-colors duration-200 ${isActive ? "border-slate-800 bg-slate-50 shadow-[0_2px_8px_rgba(0,0,0,0.04)]" : "border-slate-200 bg-white hover:border-slate-300 hover:bg-slate-50/50"}`,
4324
- children: [
4325
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between", children: [
4326
- /* @__PURE__ */ jsxRuntime.jsxs(
4327
- "span",
4328
- {
4329
- className: `text-xs font-semibold ${isActive ? "text-slate-900" : "text-slate-700"}`,
4330
- children: [
4331
- "Shot ",
4332
- shot.shot_number
4333
- ]
4334
- }
4335
- ),
4329
+ onClick: () => {
4330
+ var _a2;
4331
+ return setToggledShotId(isActive ? null : (_a2 = shot.id) != null ? _a2 : null);
4332
+ },
4333
+ className: `group relative cursor-pointer rounded-xl border transition-all duration-300 overflow-hidden ${isActive ? "border-slate-900 bg-slate-50 shadow-[0_6px_20px_rgba(0,0,0,0.06)]" : "border-slate-200 bg-white hover:border-slate-300 hover:shadow-[0_4px_14px_rgba(0,0,0,0.05)]"}`,
4334
+ children: [
4336
4335
  /* @__PURE__ */ jsxRuntime.jsx(
4337
- "span",
4336
+ "div",
4338
4337
  {
4339
- className: `rounded-md px-1.5 py-0.5 text-[9px] font-bold uppercase tracking-wider ${isActive ? "bg-slate-200 text-slate-800" : "bg-slate-100 text-slate-500"}`,
4340
- children: shot.shot_type
4338
+ className: `absolute left-0 top-0 h-full w-[3px] transition-all duration-300
4339
+ ${isActive ? "bg-slate-900" : "bg-transparent group-hover:bg-slate-300"}`
4341
4340
  }
4342
- )
4343
- ] }),
4344
- /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-[11px] font-medium text-slate-500 truncate", children: [
4345
- shot.camera_name,
4346
- " \u2022 ",
4347
- shot.lens_mm
4348
- ] }),
4349
- /* @__PURE__ */ jsxRuntime.jsx(
4350
- "div",
4351
- {
4352
- className: `grid grid-rows-[0fr] transition-all duration-300 ease-in-out ${isActive ? "grid-rows-[1fr] mt-0.5" : ""}`,
4353
- children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 pt-2 border-t border-slate-200/60 mt-1", children: [
4354
- /* @__PURE__ */ jsxRuntime.jsxs(
4355
- "button",
4356
- {
4357
- onClick: (e) => {
4358
- var _a2;
4359
- e.stopPropagation();
4360
- setViewingShotId((_a2 = shot.id) != null ? _a2 : null);
4361
- },
4362
- className: "flex flex-1 items-center justify-center gap-1.5 rounded-md border border-slate-200 bg-white py-1.5 text-[10px] font-bold text-slate-700 shadow-sm transition-colors hover:bg-slate-50 hover:text-slate-900",
4363
- children: [
4364
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Eye, { className: "h-3 w-3" }),
4365
- "View"
4366
- ]
4367
- }
4368
- ),
4369
- /* @__PURE__ */ jsxRuntime.jsxs(
4370
- "button",
4341
+ ),
4342
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-2 px-4 py-3.5", children: [
4343
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start justify-between", children: [
4344
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col", children: [
4345
+ /* @__PURE__ */ jsxRuntime.jsxs(
4346
+ "span",
4347
+ {
4348
+ className: `text-[11px] font-semibold tracking-wide uppercase
4349
+ ${isActive ? "text-slate-900" : "text-slate-500"}`,
4350
+ children: [
4351
+ "Shot ",
4352
+ shot.shot_number
4353
+ ]
4354
+ }
4355
+ ),
4356
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm font-semibold text-slate-800 leading-tight", children: shot.camera_name || "Unknown Camera" })
4357
+ ] }),
4358
+ /* @__PURE__ */ jsxRuntime.jsx(
4359
+ "span",
4371
4360
  {
4372
- onClick: (e) => {
4373
- var _a2;
4374
- e.stopPropagation();
4375
- setUpdatingShotId((_a2 = shot.id) != null ? _a2 : null);
4376
- },
4377
- className: "flex flex-1 items-center justify-center gap-1.5 rounded-md bg-slate-900 py-1.5 text-[10px] font-bold text-white shadow-sm transition-colors hover:bg-slate-800",
4378
- children: [
4379
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Pencil, { className: "h-3 w-3" }),
4380
- "Edit"
4381
- ]
4361
+ className: `rounded-md px-2 py-0.5 text-[9px] font-bold uppercase tracking-wider ${isActive ? "bg-slate-900 text-white" : "bg-slate-100 text-slate-500 group-hover:bg-slate-200"}`,
4362
+ children: shot.shot_type
4382
4363
  }
4383
4364
  )
4384
- ] }) })
4385
- }
4386
- )
4387
- ]
4388
- },
4389
- shot.id
4390
- );
4391
- }) })
4392
- ] }) })
4365
+ ] }),
4366
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between text-[11px] text-slate-500", children: [
4367
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: shot.lens_mm ? `${shot.lens_mm}mm Lens` : "\u2014" }),
4368
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "opacity-60", children: "Tap to expand" })
4369
+ ] }),
4370
+ /* @__PURE__ */ jsxRuntime.jsx(
4371
+ "div",
4372
+ {
4373
+ className: `grid transition-all duration-300 ease-in-out ${isActive ? "grid-rows-[2fr] mt-2" : "grid-rows-[0fr]"}`,
4374
+ children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "py-3 pb-4 border-t border-slate-200/70 flex gap-2", children: [
4375
+ /* @__PURE__ */ jsxRuntime.jsxs(
4376
+ "button",
4377
+ {
4378
+ onClick: (e) => {
4379
+ var _a2;
4380
+ e.stopPropagation();
4381
+ setViewingShotId((_a2 = shot.id) != null ? _a2 : null);
4382
+ },
4383
+ className: "flex flex-1 items-center justify-center gap-1.5 rounded-md border border-slate-200 bg-white py-2 text-[11px] font-semibold text-slate-700 transition-all hover:bg-slate-50 hover:text-slate-900",
4384
+ children: [
4385
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Eye, { className: "h-3.5 w-3.5" }),
4386
+ "View"
4387
+ ]
4388
+ }
4389
+ ),
4390
+ /* @__PURE__ */ jsxRuntime.jsxs(
4391
+ "button",
4392
+ {
4393
+ onClick: (e) => {
4394
+ var _a2;
4395
+ e.stopPropagation();
4396
+ setUpdatingShotId((_a2 = shot.id) != null ? _a2 : null);
4397
+ },
4398
+ className: "flex flex-1 items-center justify-center gap-1.5 rounded-md bg-slate-900 py-2 text-[11px] font-semibold text-white transition-all hover:bg-slate-800",
4399
+ children: [
4400
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Pencil, { className: "h-3.5 w-3.5" }),
4401
+ "Edit"
4402
+ ]
4403
+ }
4404
+ )
4405
+ ] }) })
4406
+ }
4407
+ )
4408
+ ] })
4409
+ ]
4410
+ },
4411
+ shot.id
4412
+ );
4413
+ }) })
4414
+ ] })
4415
+ ] })
4393
4416
  }
4394
4417
  ),
4395
4418
  selectionMenu && /* @__PURE__ */ jsxRuntime.jsx(
@@ -4472,7 +4495,7 @@ function ShotBreakdownView({
4472
4495
  );
4473
4496
  }
4474
4497
  function useShotBreakdownScene(options) {
4475
- const [shots, setShots] = react.useState(options.preLoadedShots || []);
4498
+ const [shots, setShots] = react.useState(options.preloadedShots || []);
4476
4499
  const [cameras, setCameras] = react.useState(
4477
4500
  options.preloadedCameras || []
4478
4501
  );
@@ -4481,9 +4504,38 @@ function useShotBreakdownScene(options) {
4481
4504
  );
4482
4505
  const [scene, setScene] = react.useState(null);
4483
4506
  const [isLoading, setIsLoading] = react.useState(true);
4507
+ const [isSummarizing, setIsSummarizing] = react.useState(false);
4484
4508
  const [error, setError] = react.useState(false);
4485
4509
  const [selectionMenu, setSelectionMenu] = react.useState(null);
4486
4510
  const menuRef = react.useRef(null);
4511
+ react.useEffect(() => {
4512
+ if (options.preloadedShots && options.preloadedShots.length > 0) {
4513
+ setShots((prev) => {
4514
+ if (JSON.stringify(prev) === JSON.stringify(options.preloadedShots)) {
4515
+ return prev;
4516
+ }
4517
+ return options.preloadedShots || [];
4518
+ });
4519
+ }
4520
+ }, [options.preloadedShots]);
4521
+ react.useEffect(() => {
4522
+ if (options.preloadedCameras && options.preloadedCameras.length > 0) {
4523
+ setCameras((prev) => {
4524
+ if (JSON.stringify(prev) === JSON.stringify(options.preloadedCameras)) {
4525
+ return prev;
4526
+ }
4527
+ return options.preloadedCameras || [];
4528
+ });
4529
+ }
4530
+ }, [options.preloadedCameras]);
4531
+ react.useEffect(() => {
4532
+ if (options.preloadedSceneType) {
4533
+ setSceneType((prev) => {
4534
+ if (prev === options.preloadedSceneType) return prev;
4535
+ return options.preloadedSceneType || "";
4536
+ });
4537
+ }
4538
+ }, [options.preloadedSceneType]);
4487
4539
  react.useEffect(() => {
4488
4540
  setIsLoading(true);
4489
4541
  const fetchScene = async () => {
@@ -4669,6 +4721,66 @@ function useShotBreakdownScene(options) {
4669
4721
  return result;
4670
4722
  }
4671
4723
  };
4724
+ const handleAISummarize = async () => {
4725
+ var _a;
4726
+ if (!scene || !scene.content || !options.onAISummarize) return;
4727
+ setIsSummarizing(true);
4728
+ try {
4729
+ const res = await ((_a = options.onAISummarize) == null ? void 0 : _a.call(options, scene.content));
4730
+ if (res && res.ok) {
4731
+ const data = await res.json();
4732
+ setIsSummarizing(false);
4733
+ console.log(data);
4734
+ const newShots = [];
4735
+ data.data.forEach((aiShot) => {
4736
+ var _a2;
4737
+ const newShot = {
4738
+ id: aiShot.id || uuid(),
4739
+ shot_number: (shots.length || 0) + newShots.length + 1,
4740
+ priority: aiShot.priority || "Essential",
4741
+ shot_type: aiShot.shot_type || "Medium Shot (MS)",
4742
+ framing: aiShot.framing || "Eye Level",
4743
+ camera_angle: aiShot.camera_angle || "Eye Level",
4744
+ camera_movement: aiShot.camera_movement || "Static (Locked-Off)",
4745
+ camera_support: aiShot.camera_support || "Tripod",
4746
+ lens_mm: aiShot.lens_mm || "35",
4747
+ lens_feel: aiShot.lens_feel || "Standard",
4748
+ aperture: aiShot.aperture || "T2.8",
4749
+ depth_of_field: aiShot.depth_of_field || "Deep",
4750
+ subject: aiShot.subject || "",
4751
+ action_blocking: aiShot.action_blocking || "",
4752
+ emotional_purpose: aiShot.emotional_purpose || "",
4753
+ lighting: aiShot.lighting || "",
4754
+ sound: aiShot.sound || "",
4755
+ duration_seconds: aiShot.duration_seconds || 5,
4756
+ edit_purpose: aiShot.edit_purpose || "",
4757
+ reason: aiShot.reason || "",
4758
+ vfx: aiShot.vfx || "None",
4759
+ camera_name: aiShot.camera_name || ((_a2 = cameras[0]) == null ? void 0 : _a2.name) || "Camera A",
4760
+ fps: aiShot.fps || 24,
4761
+ parts: aiShot.parts.map((part) => ({
4762
+ block_id: part.block_id.startsWith("par") ? part.block_id.substring(3) : part.block_id || uuid(),
4763
+ start_index: part.start_index,
4764
+ end_index: part.end_index,
4765
+ text: part.text
4766
+ })) || []
4767
+ };
4768
+ newShots.push(newShot);
4769
+ });
4770
+ if (newShots.length > 0) {
4771
+ setShots((prev) => [...prev, ...newShots]);
4772
+ if (options.onShotsBulkAdded) {
4773
+ await options.onShotsBulkAdded(newShots);
4774
+ }
4775
+ }
4776
+ } else {
4777
+ setIsSummarizing(false);
4778
+ }
4779
+ } catch (error2) {
4780
+ setIsSummarizing(false);
4781
+ console.error("Error in AI summarization:", error2);
4782
+ }
4783
+ };
4672
4784
  return {
4673
4785
  blocks,
4674
4786
  isLoading,
@@ -4682,6 +4794,8 @@ function useShotBreakdownScene(options) {
4682
4794
  addShot,
4683
4795
  updateShot,
4684
4796
  clearSelection,
4797
+ handleAISummarize,
4798
+ isSummarizing,
4685
4799
  menuRef
4686
4800
  };
4687
4801
  }