1!function(){try{var e="u">typeof window?window:"u">typeof global?global:"u">typeof globalThis?globalThis:"u">typeof self?self:{},t=(new e.Error).stack;t&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[t]="a250ef1c-6c83-4c85-bc66-7bdc797b48a6",e._sentryDebugIdIdentifier="sentry-dbid-a250ef1c-6c83-4c85-bc66-7bdc797b48a6")}catch(e){}}();"use strict";(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[2701],{12458:(e,t,l)=>{l.r(t),l.d(t,{generateId:()=>o,isValidObjectIdString:()=>a});var r=l(46821);let o=()=>(0,r.d_)("0123456789abcdef",24)(),a=e=>/^[0-9a-fA-F]{24}$/.test(e)},32701:(e,t,l)=>{l.r(t),l.d(t,{checkProjectHandlePermissions:()=>B,deleteFileBlob:()=>A,deleteFileBlobsForProject:()=>I,deleteFileHandle:()=>u,deleteFileHandlesForProject:()=>b,discardDeadBlobUrl:()=>i,getFileBlobRecord:()=>y,getFileHandleRecord:()=>c,getFileHandlesForProject:()=>f,getOrRebuildBlobUrl:()=>U,isBlobUrlValid:()=>_,isFileSystemAccessSupported:()=>F,loadLocalAssetBlobForUpload:()=>g,openFilePicker:()=>P,queryHandlePermission:()=>j,rehydrateLocalProjectMedia:()=>L,requestHandlePermission:()=>v,requestPermissionsForHandles:()=>$,resolveBlobIdToBlobUrl:()=>w,resolveHandleToBlobUrl:()=>D,resolveLocalBlobUrl:()=>h,revokeAllBlobUrlsForProject:()=>n,revokeBlobUrl:()=>s,storeFileBlob:()=>p,storeFileHandle:()=>d,storeLocalAudioBlob:()=>m});var r=l(41870),o=l(12458);let a=new Map;function s(e){let t=a.get(e);t&&(URL.revokeObjectURL(t),a.delete(e),console.log(`[localAssets] Revoked blob URL for handle: ${e}`))}function i(e){if(e&&e.startsWith("blob:"))for(let[t,l]of Array.from(a))l===e&&(a.delete(t),console.log(`[localAssets] Discarded dead blob URL for: ${t}`))}async function n(e){for(let t of(await r.E.fileHandles.where("projectId").equals(e).toArray()))s(t.id)}async function d(e,t){let l=await t.getFile(),a=(0,o.generateId)(),s=Date.now(),i={id:a,projectId:e,handle:t,filename:l.name,size:l.size,lastModified:l.lastModified,mimeType:l.type||"application/octet-stream",createdAt:s};return await r.E.fileHandles.put(i),console.log(`[localAssets] Stored file handle: ${l.name} (${a})`),{id:a,projectId:e,filename:l.name,size:l.size,lastModified:l.lastModified,mimeType:l.type||"application/octet-stream"}}async function c(e){return await r.E.fileHandles.get(e)||null}async function f(e){return r.E.fileHandles.where("projectId").equals(e).toArray()}async function u(e){s(e),await r.E.fileHandles.delete(e),console.log(`[localAssets] Deleted file handle: ${e}`)}async function b(e){await n(e),await r.E.fileHandles.where("projectId").equals(e).delete(),console.log(`[localAssets] Deleted all file handles for project: ${e}`)}async function p(e,t){let l=(0,o.generateId)(),a=Date.now(),s={id:l,projectId:e,blob:t,filename:t.name,size:t.size,lastModified:t.lastModified,mimeType:t.type||"application/octet-stream",createdAt:a};return await r.E.fileBlobs.put(s),console.log(`[localAssets] Stored file blob: ${t.name} (${l})`),{id:l,projectId:e,filename:t.name,size:t.size,lastModified:t.lastModified,mimeType:t.type||"application/octet-stream"}}async function m(e,t,l){let a=(0,o.generateId)(),s=Date.now(),i=`voiceover-${l}.mp3`,n={id:a,projectId:e,blob:t,filename:i,size:t.size,lastModified:s,mimeType:t.type||"audio/mpeg",createdAt:s};return await r.E.fileBlobs.put(n),console.log(`[localAssets] Stored local audio blob: ${i} (${a}), size: ${t.size}`),{localUrl:`localBlob://${a}`,blobId:a}}async function h(e){if(!e.startsWith("localBlob://"))throw Error(`Invalid local blob URL: ${e}`);return w(e.replace("localBlob://",""))}async function g(e){var t;let l=e.assetRef??null;if(l?.type==="blob"&&"string"==typeof l.blobId&&l.blobId.trim().length>0)try{let e=await y(l.blobId.trim());if(!e)return{blob:null,source:"asset_ref_blob",error:`Blob asset ${l.blobId.trim()} was not found in IndexedDB`};if(!(e.blob.size>0))return{blob:null,source:"asset_ref_blob",error:`Blob asset ${l.blobId.trim()} is empty`};return{blob:e.blob,source:"asset_ref_blob"}}catch(e){return{blob:null,source:"asset_ref_blob",error:e instanceof Error?e.message:"Failed reading blob asset from IndexedDB"}}if(l?.type==="handle"&&"string"==typeof l.handleId&&l.handleId.trim().length>0)try{let e=l.handleId.trim(),t=await c(e);if(!t)return{blob:null,source:"asset_ref_handle",error:`File handle ${e} was not found in IndexedDB`};let r=await t.handle.queryPermission({mode:"read"});if("granted"!==r)return{blob:null,source:"asset_ref_handle",error:`File handle ${e} does not have read permission (${r})`};let o=await t.handle.getFile();if(!(o.size>0))return{blob:null,source:"asset_ref_handle",error:`File handle ${e} resolved to an empty file`};return{blob:o,source:"asset_ref_handle"}}catch(e){return{blob:null,source:"asset_ref_handle",error:e instanceof Error?e.message:"Failed reading file handle bytes"}}let r="string"==typeof(t=e.localUrl)&&t.startsWith("localBlob://")&&t.replace("localBlob://","").trim()||null;if(r)try{let t=await y(r);if(!t)return{blob:null,source:"local_blob_url",error:`Local blob URL ${e.localUrl} was not found in IndexedDB`};if(!(t.blob.size>0))return{blob:null,source:"local_blob_url",error:`Local blob URL ${e.localUrl} resolved to empty bytes`};return{blob:t.blob,source:"local_blob_url"}}catch(e){return{blob:null,source:"local_blob_url",error:e instanceof Error?e.message:"Failed reading local blob URL bytes"}}return{blob:null,source:null,error:"No supported local asset reference was available for direct byte loading"}}async function y(e){return await r.E.fileBlobs.get(e)||null}async function w(e){let t=a.get(e);if(t)return t;let l=await y(e);if(!l)throw Error(`File blob not found: ${e}`);let r=URL.createObjectURL(l.blob);return a.set(e,r),console.log(`[localAssets] Created blob URL for ${l.filename}: ${r.substring(0,50)}...`),r}async function A(e){s(e),await r.E.fileBlobs.delete(e),console.log(`[localAssets] Deleted file blob: ${e}`)}async function I(e){for(let t of(await r.E.fileBlobs.where("projectId").equals(e).toArray()))s(t.id);await r.E.fileBlobs.where("projectId").equals(e).delete(),console.log(`[localAssets] Deleted all file blobs for project: ${e}`)}async function j(e){let t=await c(e);if(!t)return{handleId:e,filename:"Unknown",permission:"denied",error:"Handle not found in database"};try{let l=await t.handle.queryPermission({mode:"read"});return{handleId:e,filename:t.filename,permission:l}}catch(l){return console.error(`[localAssets] Error querying permission for ${e}:`,l),{handleId:e,filename:t.filename,permission:"denied",error:l instanceof Error?l.message:"Unknown error"}}}async function v(e){let t=await c(e);if(!t)return{handleId:e,filename:"Unknown",permission:"denied",error:"Handle not found in database"};try{let l=await t.handle.queryPermission({mode:"read"});if("granted"===l)return{handleId:e,filename:t.filename,permission:"granted"};let r=await t.handle.requestPermission({mode:"read"});return{handleId:e,filename:t.filename,permission:r}}catch(l){return console.error(`[localAssets] Error requesting permission for ${e}:`,l),{handleId:e,filename:t.filename,permission:"denied",error:l instanceof Error?l.message:"Unknown error"}}}async function B(e){let t=await f(e),l=[];for(let e of t){let t=await j(e.id);l.push(t)}return l}async function $(e){return Promise.all(Array.from(new Set(e.filter(Boolean))).map(e=>v(e)))}async function D(e){let t=a.get(e);if(t)return t;let l=await c(e);if(!l)throw Error(`File handle not found: ${e}`);if("granted"!==await l.handle.queryPermission({mode:"read"}))throw Error(`Permission not granted for file: ${l.filename}`);let r=await l.handle.getFile(),o=URL.createObjectURL(r);return a.set(e,o),console.log(`[localAssets] Created blob URL for ${l.filename}: ${o.substring(0,50)}...`),o}function F(){return"showOpenFilePicker"in window&&"function"==typeof window.showOpenFilePicker}async function P(e){if(!F())throw Error("File System Access API is not supported in this browser");try{return await window.showOpenFilePicker({multiple:e?.multiple??!0,types:e?.types??[{description:"Media files",accept:{"video/*":[".mp4",".webm",".mov",".avi",".mkv"],"image/*":[".jpg",".jpeg",".png",".gif",".webp"]}}]})}catch(e){if(e instanceof Error&&"AbortError"===e.name)return[];throw e}}function _(e){if(!e||!e.startsWith("blob:"))return!1;for(let[,t]of a)if(t===e)return!0;return!1}async function U(e){let t=a.get(e);if(t)return t;try{return await D(e)}catch(t){return console.warn(`[localAssets] Failed to rebuild blob URL for handle ${e}:`,t),null}}async function L(e){if("local"!==e.mode||!e.scenes)return{project:e,scenesNeedingPermission:[]};let t=[],l=0;for(let r of(console.log(`[localAssets] Rehydrating media for ${e.scenes.length} scenes...`),e.scenes)){let e=r.media?.assetRef;if(e?.type==="blob"&&e.blobId){let t=r.media?.url;
1if(t?.startsWith("blob:")&&_(t)){console.log(`[localAssets] Scene ${r.id.substring(0,8)}: Blob URL still valid (blob asset)`);continue}try{let t=await w(e.blobId);r.media&&(r.media.url=t,l++,console.log(`[localAssets] Scene ${r.id.substring(0,8)}: Rehydrated blob asset`))}catch(e){console.warn(`[localAssets] Scene ${r.id.substring(0,8)}: Failed to rehydrate blob:`,e)}continue}if(e?.type!=="handle"||!e.handleId){!r.media?.url?.startsWith("blob:")||e?.handleId||e?.blobId||console.error(`[localAssets] TRIPWIRE: Scene ${r.id} has blob URL without proper asset ref!`);continue}let o=e.handleId,a=r.media?.url;if(a?.startsWith("blob:")&&_(a)){console.log(`[localAssets] Scene ${r.id.substring(0,8)}: Blob URL still valid`);continue}let s=await c(o);if(!s){console.warn(`[localAssets] Scene ${r.id.substring(0,8)}: Handle not found in Dexie`);continue}try{let a=await s.handle.queryPermission({mode:"read"});if("granted"===a){let e=await D(o);r.media&&(r.media.url=e,l++,console.log(`[localAssets] Scene ${r.id.substring(0,8)}: Rehydrated with new blob URL`))}else t.push({sceneId:r.id,handleId:o,filename:e.filename||s.filename}),console.log(`[localAssets] Scene ${r.id.substring(0,8)}: Needs permission`)}catch(l){console.error(`[localAssets] Scene ${r.id.substring(0,8)}: Error checking permission:`,l),t.push({sceneId:r.id,handleId:o,filename:e.filename||"Unknown"})}}return console.log(`[localAssets] Rehydration complete: ${l} rebuilt, ${t.length} need permission`),{project:e,scenesNeedingPermission:t}}},41870:(e,t,l)=>{l.d(t,{E:()=>a});var r=l(45571);class o extends r.Ay{constructor(){super("AutoShortsLocalDB"),this.version(1).stores({projects:"id, updatedAt, title"}),this.version(2).stores({projects:"id, updatedAt, title",fileHandles:"id, projectId, filename"}),this.version(3).stores({projects:"id, updatedAt, title",fileHandles:"id, projectId, filename",fileBlobs:"id, projectId, filename"}),this.version(4).stores({projects:"id, updatedAt, title",fileHandles:"id, projectId, filename",fileBlobs:"id, projectId, filename",facelessDrafts:"id, updatedAt, templateId"}),this.version(5).stores({projects:"id, updatedAt, title",fileHandles:"id, projectId, filename",fileBlobs:"id, projectId, filename",facelessDrafts:"id, updatedAt, templateId",mediaCache:"storageKey, lastAccessed"}),this.version(6).stores({projects:"id, updatedAt, title",fileHandles:"id, projectId, filename",fileBlobs:"id, projectId, filename",facelessDrafts:"id, updatedAt, templateId",mediaCache:"storageKey, lastAccessed",cloudProjectSaveOutbox:"id, ownerId, projectId, updatedAt"})}async createProject(e){let t=Date.now(),l={...e,mode:"local",use_webgl2:e.use_webgl2??!0,showLetterboxing:e.showLetterboxing??!1,createdAt:e.createdAt||t,updatedAt:t,lastModified:t},r={id:l.id,title:l.title,data:JSON.stringify(l),createdAt:l.createdAt,updatedAt:l.updatedAt};return await this.projects.put(r),console.log("[LocalDB] Created local project:",l.id,l.title),l}async getProject(e){let t=await this.projects.get(e);if(!t)return console.log("[LocalDB] Project not found:",e),null;try{let e=JSON.parse(t.data);return e.mode="local",void 0===e.use_webgl2&&(e.use_webgl2=!0),void 0===e.showLetterboxing&&(e.showLetterboxing=!1),e}catch(t){return console.error("[LocalDB] Failed to parse project data:",e,t),null}}async saveProject(e){let t=Date.now(),l={...e,mode:"local",updatedAt:t,lastModified:t},r={id:l.id,title:l.title,data:JSON.stringify(l),createdAt:l.createdAt,updatedAt:l.updatedAt};await this.projects.put(r),console.log("[LocalDB] Saved local project:",l.id)}async deleteProject(e){await this.projects.delete(e),console.log("[LocalDB] Deleted local project:",e)}async listProjects(){return(await this.projects.orderBy("updatedAt").reverse().toArray()).map(e=>{let t=0,l=0;try{let r=JSON.parse(e.data);t=r.scenes?.length||0,l=(r.audio?.length||0)+(r.voiceovers?.length||0)}catch{}return{id:e.id,title:e.title,createdAt:e.createdAt,updatedAt:e.updatedAt,mode:"local",scenesCount:t,audioCount:l}})}async projectExists(e){return await this.projects.where("id").equals(e).count()>0}async deleteAllProjects(){await this.projects.clear(),console.log("[LocalDB] Deleted all local projects")}async saveFacelessDraft(e){let t=await this.facelessDrafts.get(e.id);await this.facelessDrafts.put({...e,createdAt:t?.createdAt??e.createdAt,convertedProjectId:e.convertedProjectId??t?.convertedProjectId??null})}async getFacelessDraft(e){return await this.facelessDrafts.get(e)??null}async deleteFacelessDraft(e){await this.facelessDrafts.delete(e)}async listFacelessDrafts(){return(await this.facelessDrafts.orderBy("updatedAt").reverse().toArray()).filter(e=>!e.convertedProjectId).map(e=>{let t=!1,l=0;try{let r=JSON.parse(e.data);t=!!r.plan,l=r.plan?.scenes?.length??0}catch{}return{id:e.id,title:e.title,templateId:e.templateId,createdAt:e.createdAt,updatedAt:e.updatedAt,hasStoryboard:t,sceneCount:l,convertedProjectId:e.convertedProjectId}})}async markDraftConverted(e,t){await this.facelessDrafts.update(e,{convertedProjectId:t})}}let a=new o}}]);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.