@scaleflex/uploader 0.2.3 → 0.2.5

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.
@@ -1,7 +1,7 @@
1
- "use strict";const s=require("lit"),p=require("lit/decorators.js"),U=require("lit/directives/unsafe-svg.js"),D=require("lit/directives/unsafe-html.js");class Se{constructor(e){this.listeners=new Set,this._notifying=!1,this._pendingState=null,this.state=e}getState(){return this.state}setState(e){if(this._notifying){this._pendingState={...this._pendingState||{},...e};return}const t=this.state;this.state={...t,...e},this._notifying=!0;try{this.listeners.forEach(i=>i(this.state,t))}finally{this._notifying=!1}if(this._pendingState){const i=this._pendingState;this._pendingState=null,this.setState(i)}}subscribe(e){return this.listeners.add(e),()=>this.listeners.delete(e)}destroy(){this.listeners.clear()}}function S(n,e,t){const i=n.getState().files,r=i.get(e);if(!r)return;const o=new Map(i);o.set(e,{...r,...t}),n.setState({files:o})}function M(n,e){const t=new Map(n.getState().files);t.set(e.id,e),n.setState({files:t})}function be(n,e){const t=n.getState().files;if(!t.has(e))return;const i=new Map(t);i.delete(e),n.setState({files:i})}function Ee(){return new Se({files:new Map,queueConfig:{concurrency:3,autoProceed:!1,retryConfig:{maxRetries:0,baseDelay:1e3,maxDelay:3e4,backoffFactor:2}},isPaused:!1,restrictions:{maxFileSize:null,maxTotalFilesSize:null,maxNumberOfFiles:null,minNumberOfFiles:null,allowedFileTypes:null,blockedFileTypes:null},targetFolder:"/",totalProgress:0,totalSpeed:0,totalBytesUploaded:0,totalBytes:0,isUploading:!1})}class Fe{constructor(e,t){this.host=e,this.store=t,e.addController(this)}get state(){return this.store.getState()}setState(e){this.store.setState(e)}hostConnected(){this.unsubscribe=this.store.subscribe(()=>{this.host.requestUpdate()})}hostDisconnected(){var e;(e=this.unsubscribe)==null||e.call(this)}}function Oe(n,e){const t=new XMLHttpRequest;let i=!1;const o=`${e.apiBase.replace(/\/+$/,"")}/v4/files?folder=${encodeURIComponent(e.folder)}`;t.open("POST",o);for(const[l,d]of Object.entries(e.authHeaders))t.setRequestHeader(l,d);t.upload.addEventListener("progress",l=>{l.lengthComputable&&!i&&e.onProgress(l.loaded,l.total)}),t.addEventListener("load",()=>{if(i)return;let l;try{l=JSON.parse(t.responseText)}catch{e.onError(new Error(`Invalid JSON response (HTTP ${t.status})`));return}t.status>=200&&t.status<300&&l.status==="success"?e.onComplete(l):e.onError(new Error(l.hint||l.msg||`Upload failed (HTTP ${t.status})`))}),t.addEventListener("error",()=>{i||e.onError(new Error("Network error — check your connection"))}),t.addEventListener("timeout",()=>{i||e.onError(new Error("Upload timed out"))});const a=new FormData;if(n.file){const l={name:n.name,type:n.type};Object.keys(n.meta).length>0&&(l.meta=n.meta),n.tags.length>0&&(l.tags=n.tags),a.append("info[files[]]",JSON.stringify(l)),a.append("files[]",n.file,n.name)}return t.timeout=6e4,t.send(a),{abort(){i=!0,t.abort()}}}function Te(n,e){const t=new XMLHttpRequest;let i=!1;const o=`${e.apiBase.replace(/\/+$/,"")}/v4/files/upload_url`;t.open("POST",o);for(const[l,d]of Object.entries(e.authHeaders))t.setRequestHeader(l,d);if(t.setRequestHeader("Content-Type","application/json"),t.addEventListener("load",()=>{if(i)return;let l;try{l=JSON.parse(t.responseText)}catch{e.onError(new Error(`Invalid JSON response (HTTP ${t.status})`));return}t.status>=200&&t.status<300&&l.status==="success"?e.onComplete(l):e.onError(new Error(l.hint||l.msg||`Upload failed (HTTP ${t.status})`))}),t.addEventListener("error",()=>{i||e.onError(new Error("Network error — check your connection"))}),t.addEventListener("timeout",()=>{i||e.onError(new Error("Upload timed out"))}),!n.remoteUrl)return e.onError(new Error("Remote URL is required for URL upload")),{abort(){}};const a={files_urls:[{url:n.remoteUrl,name:n.name}],dir:e.folder};return t.timeout=6e4,t.send(JSON.stringify(a)),{abort(){i=!0,t.abort()}}}function Q(n){return{Accept:"application/json","Content-Type":"application/json","uppy-auth-token":n}}function H(n){return n.replace(/\/+$/,"")}const je={"google-drive":"drive",dropbox:"dropbox",onedrive:"onedrive",box:"box",instagram:"instagram",facebook:"facebook",unsplash:"unsplash"};function Y(n){return je[n]??n}function Le(n,e){const t=H(n),i=btoa(JSON.stringify({origin:window.location.origin})),r=Y(e);return`${t}/${r}/connect?state=${encodeURIComponent(i)}`}async function Me(n,e,t,i=""){const r=H(n),o=i?`/${i}`:"",a=Y(e),l=await fetch(`${r}/${a}/list${o}`,{method:"GET",headers:Q(t),credentials:"same-origin"});if(l.status===401)throw new ee;if(!l.ok){const d=await l.json().catch(()=>null);throw new Error((d==null?void 0:d.message)||`Companion list failed (HTTP ${l.status})`)}return l.json()}async function Be(n,e,t){const i=H(n),r=await fetch(`${i}/${t}`,{method:"GET",headers:Q(e),credentials:"same-origin"});if(r.status===401)throw new ee;if(!r.ok){const o=await r.json().catch(()=>null);throw new Error((o==null?void 0:o.message)||`Companion list failed (HTTP ${r.status})`)}return r.json()}async function Re(n,e,t,i){const r=H(n),o=Y(e),a=i?`q=${encodeURIComponent(t)}&${i}`:`q=${encodeURIComponent(t)}`,l=await fetch(`${r}/search/${o}/list?${a}`,{method:"GET",headers:{Accept:"application/json","Content-Type":"application/json"},credentials:"same-origin"});if(!l.ok){const d=await l.json().catch(()=>null);throw new Error((d==null?void 0:d.message)||`Search failed (HTTP ${l.status})`)}return l.json()}async function Ae(n,e,t,i,r,o=!1){const a=H(n),l=Y(e),d=o?`${a}/search/${l}/get/${i}`:`${a}/${l}/get/${i}`,c=o?{Accept:"application/json","Content-Type":"application/json"}:Q(t),h=await fetch(d,{method:"POST",headers:c,credentials:"same-origin",body:JSON.stringify({...r,httpMethod:r.httpMethod??"POST",useFormData:r.useFormData??!0,fieldname:r.fieldname??"files[]"})});if(h.status===401)throw new ee;if(!h.ok){const x=await h.json().catch(()=>null);throw new Error((x==null?void 0:x.message)||`Companion upload failed (HTTP ${h.status})`)}return h.json()}async function Ie(n,e,t){const i=H(n),r=Y(e),o=await fetch(`${i}/${r}/logout`,{method:"GET",headers:Q(t),credentials:"same-origin"});return o.ok?o.json():{ok:!1,revoked:!1}}function He(n){var r;const t=((r=/^(?:https?:\/\/|\/\/)?(?:[^@\n]+@)?(?:www\.)?([^\n]+)/i.exec(n))==null?void 0:r[1])??n;return`${location.protocol==="https:"?"wss":"ws"}://${t}`}class ee extends Error{constructor(){super("Authentication expired"),this.name="AuthExpiredError"}}function qe(n,e){const t=n.remoteInfo;if(!t)return e.onError(new Error("remoteInfo is required for companion upload")),{abort(){}};let i=!1,r=null;const a=`${e.apiBase.replace(/\/+$/,"")}/v4/files?folder=${encodeURIComponent(e.folder)}`,l={};n.meta&&Object.keys(n.meta).length>0&&Object.assign(l,n.meta),n.tags&&n.tags.length>0&&(l.tags=n.tags);const d=!t.token;return Ae(t.companionUrl,t.provider,t.token,t.requestPath,{fileId:t.fileId,endpoint:a,headers:e.authHeaders,size:t.size,metadata:Object.keys(l).length>0?l:void 0},d).then(c=>{if(i)return;const x=`${He(t.companionUrl)}/api/${c.token}`;try{r=new WebSocket(x)}catch{e.onError(new Error("Failed to connect to upload progress channel"));return}r.onmessage=u=>{var f,v,w;if(!i)try{const m=JSON.parse(u.data);switch(m.action){case"progress":{const b=m.payload,y=b.bytesUploaded??0,E=b.bytesTotal??(t.size||1);e.onProgress(y,E);break}case"success":{const b=m.payload;if(r==null||r.close(),(f=b.response)!=null&&f.responseText)try{const y=JSON.parse(b.response.responseText);if(y.status==="success"){e.onComplete(y);return}e.onError(new Error(y.msg||"Upload failed"));return}catch{}e.onError(new Error("Upload completed but no valid response received"));break}case"error":{r==null||r.close();const b=m.payload;let y=((v=b.error)==null?void 0:v.message)||"Upload failed";if((w=b.response)!=null&&w.responseText)try{const E=JSON.parse(b.response.responseText);y=E.hint||E.msg||E.message||y}catch{}e.onError(new Error(y));break}}}catch{}},r.onerror=()=>{i||e.onError(new Error("Upload progress connection failed"))},r.onclose=()=>{r=null}}).catch(c=>{i||e.onError(c instanceof Error?c:new Error(String(c)))}),{abort(){if(i=!0,r){try{r.send(JSON.stringify({action:"cancel",payload:{}}))}catch{}r.close(),r=null}}}}class Ue{constructor(e,t){this.activeUploads=new Map,this.retryTimers=new Map,this.unsubscribe=null,this.store=e,this.config=t}start(){this.unsubscribe||(this.unsubscribe=this.store.subscribe(()=>this.processQueue()),this.processQueue())}uploadAll(){const{files:e}=this.store.getState();let t=!1;for(const i of e.values())i.status==="idle"?(S(this.store,i.id,{status:"queued"}),t=!0):i.status==="queued"&&(t=!0);t&&(this.store.setState({isUploading:!0}),this.processQueue())}retryFile(e){const t=this.store.getState().files.get(e);!t||t.status!=="error"&&t.status!=="failed"||(S(this.store,e,{status:"queued",error:null,progress:0,bytesUploaded:0,speed:0}),this.processQueue())}retryAll(){const{files:e}=this.store.getState();for(const t of e.values())(t.status==="error"||t.status==="failed")&&S(this.store,t.id,{status:"queued",error:null,progress:0,bytesUploaded:0,speed:0});this.processQueue()}cancelFile(e){const t=this.store.getState().files.get(e);!t||!we(t.status)||(this.abortUpload(e),S(this.store,e,{status:"cancelled"}))}cancelAll(){const{files:e}=this.store.getState();for(const t of e.values())we(t.status)&&(this.abortUpload(t.id),S(this.store,t.id,{status:"cancelled"}));this.store.setState({isUploading:!1})}updateConfig(e){Object.assign(this.config,e)}destroy(){var e;for(const t of this.activeUploads.keys())this.abortUpload(t);for(const t of this.retryTimers.values())clearTimeout(t);this.retryTimers.clear(),(e=this.unsubscribe)==null||e.call(this),this.unsubscribe=null}processQueue(){const e=this.store.getState();if(e.isPaused)return;const{concurrency:t}=e.queueConfig,i=this.activeUploads.size,r=t-i;if(r<=0)return;const a=[...e.files.values()].filter(l=>l.status==="queued").sort((l,d)=>l.retryCount!==d.retryCount?d.retryCount-l.retryCount:l.addedAt-d.addedAt).slice(0,r);for(const l of a)this.startUpload(l)}startUpload(e){S(this.store,e.id,{status:"uploading",error:null});let t=0,i=Date.now(),r=0;const o={apiBase:this.config.apiBase,authHeaders:this.config.authHeaders,folder:this.store.getState().targetFolder,onComplete:d=>this.handleComplete(e.id,d),onError:d=>this.handleError(e.id,d)},a=(d,c)=>{const h=Date.now(),x=(h-i)/1e3;if(x>0){const f=(d-t)/x;r=r===0?f:.3*f+.7*r}t=d,i=h;const u=c>0?Math.min(d/c*100,100):0;S(this.store,e.id,{progress:u,bytesUploaded:d,speed:r}),this.updateTotalProgress()};let l;e.remoteInfo?l=qe(e,{...o,onProgress:a}):e.remoteUrl?l=Te(e,o):l=Oe(e,{...o,onProgress:a}),this.activeUploads.set(e.id,l)}handleComplete(e,t){this.activeUploads.delete(e),S(this.store,e,{status:"complete",progress:100,response:t}),this.updateTotalProgress(),this.checkAllComplete(),this.processQueue()}handleError(e,t){this.activeUploads.delete(e);const i=this.store.getState().files.get(e);if(!i)return;const{retryConfig:r}=this.store.getState().queueConfig,o=i.retryCount+1;if(o<=r.maxRetries){const a=Math.min(r.baseDelay*Math.pow(r.backoffFactor,i.retryCount),r.maxDelay);S(this.store,e,{status:"retrying",error:t.message,retryCount:o});const l=setTimeout(()=>{this.retryTimers.delete(e),S(this.store,e,{status:"queued"}),this.processQueue()},a);this.retryTimers.set(e,l)}else S(this.store,e,{status:"failed",error:t.message}),this.checkAllComplete(),this.processQueue()}abortUpload(e){var i;(i=this.activeUploads.get(e))==null||i.abort(),this.activeUploads.delete(e);const t=this.retryTimers.get(e);t&&(clearTimeout(t),this.retryTimers.delete(e))}updateTotalProgress(){const{files:e}=this.store.getState();let t=0,i=0,r=0;for(const o of e.values())(o.status==="queued"||o.status==="uploading"||o.status==="retrying"||o.status==="complete"||o.status==="failed")&&(t+=o.size,i+=o.status==="complete"?o.size:o.bytesUploaded),o.status==="uploading"&&(r+=o.speed);this.store.setState({totalBytes:t,totalBytesUploaded:i,totalSpeed:r,totalProgress:t>0?Math.min(i/t*100,100):0})}checkAllComplete(){const{files:e}=this.store.getState();![...e.values()].some(i=>i.status==="queued"||i.status==="uploading"||i.status==="retrying")&&this.store.getState().isUploading&&this.store.setState({isUploading:!1})}}function we(n){return n==="queued"||n==="uploading"||n==="retrying"}function te(n){return`https://api.filerobot.com/${n}`}async function ze(n,e){const t=`${te(n)}/key/${encodeURIComponent(e)}`,i=new AbortController,r=setTimeout(()=>i.abort(),3e4);try{const o=await fetch(t,{signal:i.signal});if(clearTimeout(r),!o.ok)throw new Error(`SASS key exchange failed (HTTP ${o.status})`);const a=await o.json();if(a.status==="error")throw new Error(`SASS key exchange failed: ${a.msg||"Unknown error"}`);return a.key}catch(o){throw clearTimeout(r),o instanceof DOMException&&o.name==="AbortError"?new Error("SASS key exchange timed out"):o}}function K(n,e){const t={};switch(n.mode){case"security-template":if(!e)throw new Error("[sfx-uploader] Cannot build auth headers for security-template mode: SASS key exchange has not been performed. Call resolveAuth() first or use sass-key mode with a pre-resolved key.");t["X-Filerobot-Key"]=e;break;case"sass-key":t["X-Filerobot-Key"]=n.sassKey;break}return n.airboxPuid&&(t["X-Filerobot-Airbox-Puid"]=n.airboxPuid),t}async function Pe(n){const e=te(n.container);if(n.mode==="security-template"){const t=await ze(n.container,n.securityTemplateId);return{apiBase:e,headers:K(n,t),sassKey:t}}return{apiBase:e,headers:K(n)}}const g={FILE_ADDED:"sfx-file-added",FILE_REMOVED:"sfx-file-removed",FILE_REJECTED:"sfx-file-rejected",UPLOAD_STARTED:"sfx-upload-started",UPLOAD_PROGRESS:"sfx-upload-progress",UPLOAD_COMPLETE:"sfx-upload-complete",UPLOAD_ERROR:"sfx-upload-error",UPLOAD_RETRY:"sfx-upload-retry",ALL_COMPLETE:"sfx-all-complete",TOTAL_PROGRESS:"sfx-total-progress",BEFORE_UPLOAD:"sfx-before-upload",OPEN:"sfx-open",CLOSE:"sfx-close",CANCEL:"sfx-cancel",COMPLETE_ACTION:"sfx-complete-action",FILE_PREVIEW:"sfx-file-preview",FILL_METADATA:"sfx-fill-metadata"};let Ye=0;function B(){return`file-${Date.now()}-${++Ye}`}function R(n){if(n<=0)return"0 B";const e=["B","KB","MB","GB"],t=Math.min(Math.floor(Math.log(n)/Math.log(1024)),e.length-1),i=n/Math.pow(1024,t);return`${t===0?i:i.toFixed(1)} ${e[t]}`}function ie(n){if(!isFinite(n)||n<=0)return"0s";const e=Math.round(n);if(e<60)return`${e}s`;const t=Math.floor(e/60),i=e%60;return i>0?`${t}m ${i}s`:`${t}m`}function q(n){var t;const e=((t=n.name.split(".").pop())==null?void 0:t.toLowerCase())??"";return n.type.startsWith("image/")?"image":n.type.startsWith("video/")||["mp4","mov","avi","webm","mkv"].includes(e)?"vid":n.type==="application/pdf"||e==="pdf"?"pdf":["doc","docx","xls","xlsx","ppt","pptx","txt","rtf","odt"].includes(e)?"doc":["zip","rar","7z","tar","gz","bz2"].includes(e)?"zip":"gen"}function Ve(n){const e=n.lastIndexOf(".");return e>=0?n.slice(e+1).toUpperCase():""}const Ne={jpg:"image/jpeg",jpeg:"image/jpeg",png:"image/png",gif:"image/gif",webp:"image/webp",svg:"image/svg+xml",bmp:"image/bmp",ico:"image/x-icon",mp4:"video/mp4",mov:"video/quicktime",avi:"video/x-msvideo",webm:"video/webm",pdf:"application/pdf",zip:"application/zip",doc:"application/msword",docx:"application/vnd.openxmlformats-officedocument.wordprocessingml.document"};function Xe(n){var t;const e=((t=n.split(".").pop())==null?void 0:t.toLowerCase())??"";return Ne[e]||""}function We(n){return new Promise(e=>{const t=document.createElement("video");t.preload="metadata",t.muted=!0,t.playsInline=!0;const i=URL.createObjectURL(n);let r=!1;const o=()=>{r||(r=!0,e(null)),t.removeAttribute("src"),t.load(),URL.revokeObjectURL(i)};t.addEventListener("seeked",()=>{try{const a=document.createElement("canvas");a.width=t.videoWidth||320,a.height=t.videoHeight||240;const l=a.getContext("2d");if(l){l.drawImage(t,0,0,a.width,a.height),a.toBlob(d=>{r||(r=!0,e(d?URL.createObjectURL(d):null),t.removeAttribute("src"),t.load(),URL.revokeObjectURL(i))},"image/jpeg",.7);return}}catch{}o()},{once:!0}),t.addEventListener("error",()=>o(),{once:!0}),setTimeout(()=>o(),5e3),t.src=i,t.addEventListener("loadeddata",()=>{t.currentTime=.1},{once:!0})})}function oe(n,e,t){var i,r;if(e.maxFileSize!=null&&n.size>0&&n.size>e.maxFileSize)return`File exceeds ${(e.maxFileSize/1048576).toFixed(1)} MB limit`;if(e.maxTotalFilesSize!=null&&n.size>0){let o=n.size;for(const a of t.values())a.status!=="rejected"&&a.status!=="cancelled"&&(o+=a.size);if(o>e.maxTotalFilesSize)return"Total file size limit exceeded"}if(e.maxNumberOfFiles!=null){let o=0;for(const a of t.values())a.status!=="rejected"&&a.status!=="cancelled"&&o++;if(o>=e.maxNumberOfFiles)return`Maximum ${e.maxNumberOfFiles} files allowed`}if(e.allowedFileTypes!=null){const o=e.allowedFileTypes,a="."+(((i=n.name.split(".").pop())==null?void 0:i.toLowerCase())??"");if(!o.some(d=>d.startsWith(".")?a===d.toLowerCase():d.endsWith("/*")?n.type.startsWith(d.slice(0,-1)):n.type===d))return"File type not allowed"}if(e.blockedFileTypes!=null){const o=e.blockedFileTypes,a="."+(((r=n.name.split(".").pop())==null?void 0:r.toLowerCase())??"");if(o.some(d=>d.startsWith(".")?a===d.toLowerCase():d.endsWith("/*")?n.type.startsWith(d.slice(0,-1)):n.type===d))return"File type is blocked"}return null}function Ge(n,e,t){return oe(n,e,t)}function ye(n){return n.allowedFileTypes?n.allowedFileTypes.join(","):""}const _e={"google-drive":{id:"google-drive",label:"Google Drive",fillIcon:!0,icon:"",brandHtml:'<span class="brand-ico" style="background:transparent"><svg width="16" height="16" viewBox="0 0 87.3 78"><path d="M6.6 66.85l3.85 6.65c.8 1.4 1.95 2.5 3.3 3.3L27.5 53H0c0 1.55.4 3.1 1.2 4.5z" fill="#0066da"/><path d="M43.65 25L29.9 1.2C28.55 2 27.4 3.1 26.6 4.5L1.2 48.5C.4 49.9 0 51.45 0 53h27.5z" fill="#00ac47"/><path d="M73.55 76.8c1.35-.8 2.5-1.9 3.3-3.3l1.6-2.75 7.65-13.25c.8-1.4 1.2-2.95 1.2-4.5H59.8l5.65 10.85z" fill="#ea4335"/><path d="M43.65 25L57.4 1.2C56.05.4 54.5 0 52.9 0H34.4c-1.6 0-3.15.45-4.5 1.2z" fill="#00832d"/><path d="M59.8 53H27.5L13.75 76.8c1.35.8 2.9 1.2 4.5 1.2h50.8c1.6 0 3.15-.45 4.5-1.2z" fill="#2684fc"/><path d="M73.4 26.5l-12.7-22c-.8-1.4-1.95-2.5-3.3-3.3L43.65 25 59.8 53h27.45c0-1.55-.4-3.1-1.2-4.5z" fill="#ffba00"/></svg></span>'},dropbox:{id:"dropbox",label:"Dropbox",fillIcon:!0,icon:"",brandHtml:'<span class="brand-ico" style="background:#0061ff"><svg width="11" height="11" viewBox="0 0 528 512" fill="white"><path d="M264.4 116.3l-132 84.3 132 84.3-132 84.3L0 284.1l132.3-84.3L0 116.3 132.3 32l132.1 84.3zm-132 284.5l132-84.3 132 84.3-132 84.4-132-84.4zm132-116.6l132.3-84.3-132.3-83.9 131.6-84.3L528 116.3l-132.3 84.1L528 284.7l-132.4 83.9-131.2-84.4z"/></svg></span>'},onedrive:{id:"onedrive",label:"OneDrive",fillIcon:!0,icon:"",brandHtml:'<span class="brand-ico" style="background:#0078d4"><svg width="11" height="11" viewBox="0 0 24 24" fill="white"><path d="M10.5 13.5C10.5 11.57 12.07 10 14 10h6.5c.17 0 .34.01.5.02A6 6 0 009.01 11.6 4 4 0 0010.5 13.5zM12 14.5a5 5 0 00-5-5 5 5 0 00-5 5 3 3 0 003 3h9.5A3.5 3.5 0 0018 14c0-.18-.01-.35-.03-.52A5.48 5.48 0 0112 14.5z"/></svg></span>'},box:{id:"box",label:"Box",fillIcon:!0,icon:"",brandHtml:'<span class="brand-ico" style="background:#0e50a0;font-size:9px;font-weight:800;color:#fff">box</span>'},instagram:{id:"instagram",label:"Instagram",fillIcon:!0,icon:"",brandHtml:'<span class="brand-ico" style="background:linear-gradient(45deg,#f09433,#e6683c,#dc2743,#cc2366,#bc1888)"><svg width="12" height="12" viewBox="0 0 24 24" fill="white"><path d="M12 2.16c2.94 0 3.29.01 4.45.06 1.07.05 1.8.22 2.43.46.66.25 1.21.6 1.77 1.16.55.55.9 1.1 1.16 1.77.25.64.41 1.37.46 2.43.05 1.16.06 1.51.06 4.45s-.01 3.29-.06 4.45c-.05 1.07-.22 1.8-.46 2.43a4.9 4.9 0 01-1.16 1.77c-.55.55-1.1.9-1.77 1.16-.64.25-1.37.41-2.43.46-1.16.05-1.51.06-4.45.06s-3.29-.01-4.45-.06c-1.07-.05-1.8-.22-2.43-.46a4.9 4.9 0 01-1.77-1.16 4.9 4.9 0 01-1.16-1.77c-.25-.64-.41-1.37-.46-2.43C2.17 15.29 2.16 14.94 2.16 12s.01-3.29.06-4.45c.05-1.07.22-1.8.46-2.43a4.9 4.9 0 011.16-1.77A4.9 4.9 0 015.61 2.2c.64-.25 1.37-.41 2.43-.46C9.21 2.17 9.56 2.16 12 2.16zM12 16a4 4 0 110-8 4 4 0 010 8zm6.4-9.85a1.44 1.44 0 100 2.88 1.44 1.44 0 000-2.88z"/></svg></span>'},facebook:{id:"facebook",label:"Facebook",fillIcon:!0,icon:"",brandHtml:'<span class="brand-ico" style="background:#1877f2"><svg width="12" height="12" viewBox="0 0 24 24" fill="white"><path d="M24 12.07C24 5.41 18.63 0 12 0S0 5.41 0 12.07c0 6.02 4.39 11.02 10.12 11.93v-8.44H7.08v-3.49h3.04V9.41c0-3.02 1.79-4.69 4.53-4.69 1.31 0 2.68.24 2.68.24v2.97h-1.51c-1.49 0-1.95.93-1.95 1.89v2.26h3.33l-.53 3.49h-2.8v8.44C19.61 23.09 24 18.09 24 12.07z"/></svg></span>'},unsplash:{id:"unsplash",label:"Unsplash",fillIcon:!0,icon:"",brandHtml:'<span class="brand-ico" style="background:#111"><svg width="12" height="12" viewBox="0 0 24 24" fill="white"><path d="M8.5 11.5v5h7v-5h5.5V21h-18v-9.5h5.5zm7-8v5h-7v-5h7z"/></svg></span>'}};function De(n){return n.filter(e=>e in _e).map(e=>_e[e])}var Ke=Object.defineProperty,Ze=(n,e,t,i)=>{for(var r=void 0,o=n.length-1,a;o>=0;o--)(a=n[o])&&(r=a(e,t,r)||r);return r&&Ke(e,t,r),r};const Je='<rect x="2" y="3" width="20" height="14" rx="2"/><line x1="8" y1="21" x2="16" y2="21"/><line x1="12" y1="17" x2="12" y2="21"/>',Qe='<path d="M10 13a5 5 0 007.54.54l3-3a5 5 0 00-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 00-7.54-.54l-3 3a5 5 0 007.07 7.07l1.71-1.71"/>',et='<path d="M23 19a2 2 0 01-2 2H3a2 2 0 01-2-2V8a2 2 0 012-2h4l2-3h6l2 3h4a2 2 0 012 2z"/><circle cx="12" cy="13" r="4"/>',tt='<rect x="2" y="3" width="20" height="14" rx="2"/><circle cx="12" cy="10" r="1"/><path d="M7 21l5-5 5 5"/>',A=[{id:"device",label:"My Device",icon:Je,iconColor:"#2563eb"},{id:"url",label:"URL link",icon:Qe,iconColor:"#16a34a"},{id:"camera",label:"Camera",icon:et,iconColor:"#7c3aed"},{id:"screen-cast",label:"Screen capture",icon:tt,iconColor:"#ea580c"}],le=class le extends s.LitElement{constructor(){super(...arguments),this.sources=A}_handleClick(e){this.dispatchEvent(new CustomEvent("source-click",{detail:{source:e.id},bubbles:!0,composed:!0}))}render(){return s.html`
1
+ "use strict";const s=require("lit"),c=require("lit/decorators.js"),z=require("lit/directives/unsafe-svg.js"),O=require("lit/directives/unsafe-html.js");class Se{constructor(e){this.listeners=new Set,this._notifying=!1,this._pendingState=null,this.state=e}getState(){return this.state}setState(e){if(this._notifying){this._pendingState={...this._pendingState||{},...e};return}const t=this.state;this.state={...t,...e},this._notifying=!0;try{this.listeners.forEach(o=>o(this.state,t))}finally{this._notifying=!1}if(this._pendingState){const o=this._pendingState;this._pendingState=null,this.setState(o)}}subscribe(e){return this.listeners.add(e),()=>this.listeners.delete(e)}destroy(){this.listeners.clear()}}function S(n,e,t){const o=n.getState().files,r=o.get(e);if(!r)return;const i=new Map(o);i.set(e,{...r,...t}),n.setState({files:i})}function L(n,e){const t=new Map(n.getState().files);t.set(e.id,e),n.setState({files:t})}function me(n,e){const t=n.getState().files;if(!t.has(e))return;const o=new Map(t);o.delete(e),n.setState({files:o})}function Ee(){return new Se({files:new Map,queueConfig:{concurrency:3,autoProceed:!1,retryConfig:{maxRetries:0,baseDelay:1e3,maxDelay:3e4,backoffFactor:2}},isPaused:!1,restrictions:{maxFileSize:null,maxTotalFilesSize:null,maxNumberOfFiles:null,minNumberOfFiles:null,allowedFileTypes:null,blockedFileTypes:null},targetFolder:"/",totalProgress:0,totalSpeed:0,totalBytesUploaded:0,totalBytes:0,isUploading:!1})}class Fe{constructor(e,t){this.host=e,this.store=t,e.addController(this)}get state(){return this.store.getState()}setState(e){this.store.setState(e)}hostConnected(){this.unsubscribe=this.store.subscribe(()=>{this.host.requestUpdate()})}hostDisconnected(){var e;(e=this.unsubscribe)==null||e.call(this)}}function je(n,e){const t=new XMLHttpRequest;let o=!1;const i=`${e.apiBase.replace(/\/+$/,"")}/v4/files?folder=${encodeURIComponent(e.folder)}`;t.open("POST",i);for(const[l,d]of Object.entries(e.authHeaders))t.setRequestHeader(l,d);t.upload.addEventListener("progress",l=>{l.lengthComputable&&!o&&e.onProgress(l.loaded,l.total)}),t.addEventListener("load",()=>{if(o)return;let l;try{l=JSON.parse(t.responseText)}catch{e.onError(new Error(`Invalid JSON response (HTTP ${t.status})`));return}t.status>=200&&t.status<300&&l.status==="success"?e.onComplete(l):e.onError(new Error(l.hint||l.msg||`Upload failed (HTTP ${t.status})`))}),t.addEventListener("error",()=>{o||e.onError(new Error("Network error — check your connection"))}),t.addEventListener("timeout",()=>{o||e.onError(new Error("Upload timed out"))});const a=new FormData;if(n.file){const l={name:n.name,type:n.type};Object.keys(n.meta).length>0&&(l.meta=n.meta),n.tags.length>0&&(l.tags=n.tags),a.append("info[files[]]",JSON.stringify(l)),a.append("files[]",n.file,n.name)}return t.timeout=6e4,t.send(a),{abort(){o=!0,t.abort()}}}function Oe(n,e){const t=new XMLHttpRequest;let o=!1;const i=`${e.apiBase.replace(/\/+$/,"")}/v4/files/upload_url`;t.open("POST",i);for(const[l,d]of Object.entries(e.authHeaders))t.setRequestHeader(l,d);if(t.setRequestHeader("Content-Type","application/json"),t.addEventListener("load",()=>{if(o)return;let l;try{l=JSON.parse(t.responseText)}catch{e.onError(new Error(`Invalid JSON response (HTTP ${t.status})`));return}t.status>=200&&t.status<300&&l.status==="success"?e.onComplete(l):e.onError(new Error(l.hint||l.msg||`Upload failed (HTTP ${t.status})`))}),t.addEventListener("error",()=>{o||e.onError(new Error("Network error — check your connection"))}),t.addEventListener("timeout",()=>{o||e.onError(new Error("Upload timed out"))}),!n.remoteUrl)return e.onError(new Error("Remote URL is required for URL upload")),{abort(){}};const a={files_urls:[{url:n.remoteUrl,name:n.name}],dir:e.folder};return t.timeout=6e4,t.send(JSON.stringify(a)),{abort(){o=!0,t.abort()}}}function Q(n){return{Accept:"application/json","Content-Type":"application/json","uppy-auth-token":n}}function H(n){return n.replace(/\/+$/,"")}const Me={"google-drive":"drive",dropbox:"dropbox",onedrive:"onedrive",box:"box",instagram:"instagram",facebook:"facebook",unsplash:"unsplash"};function Y(n){return Me[n]??n}function Re(n,e){const t=H(n),o=btoa(JSON.stringify({origin:window.location.origin})),r=Y(e);return`${t}/${r}/connect?state=${encodeURIComponent(o)}`}async function Le(n,e,t,o=""){const r=H(n),i=o?`/${o}`:"",a=Y(e),l=await fetch(`${r}/${a}/list${i}`,{method:"GET",headers:Q(t),credentials:"same-origin"});if(l.status===401)throw new ee;if(!l.ok){const d=await l.json().catch(()=>null);throw new Error((d==null?void 0:d.message)||`Companion list failed (HTTP ${l.status})`)}return l.json()}async function Te(n,e,t){const o=H(n),r=await fetch(`${o}/${t}`,{method:"GET",headers:Q(e),credentials:"same-origin"});if(r.status===401)throw new ee;if(!r.ok){const i=await r.json().catch(()=>null);throw new Error((i==null?void 0:i.message)||`Companion list failed (HTTP ${r.status})`)}return r.json()}async function Be(n,e,t,o){const r=H(n),i=Y(e),a=o?`q=${encodeURIComponent(t)}&${o}`:`q=${encodeURIComponent(t)}`,l=await fetch(`${r}/search/${i}/list?${a}`,{method:"GET",headers:{Accept:"application/json","Content-Type":"application/json"},credentials:"same-origin"});if(!l.ok){const d=await l.json().catch(()=>null);throw new Error((d==null?void 0:d.message)||`Search failed (HTTP ${l.status})`)}return l.json()}async function Ae(n,e,t,o,r,i=!1){const a=H(n),l=Y(e),d=i?`${a}/search/${l}/get/${o}`:`${a}/${l}/get/${o}`,p=i?{Accept:"application/json","Content-Type":"application/json"}:Q(t),h=await fetch(d,{method:"POST",headers:p,credentials:"same-origin",body:JSON.stringify({...r,httpMethod:r.httpMethod??"POST",useFormData:r.useFormData??!0,fieldname:r.fieldname??"files[]"})});if(h.status===401)throw new ee;if(!h.ok){const u=await h.json().catch(()=>null);throw new Error((u==null?void 0:u.message)||`Companion upload failed (HTTP ${h.status})`)}return h.json()}async function Ie(n,e,t){const o=H(n),r=Y(e),i=await fetch(`${o}/${r}/logout`,{method:"GET",headers:Q(t),credentials:"same-origin"});return i.ok?i.json():{ok:!1,revoked:!1}}function He(n){var r;const t=((r=/^(?:https?:\/\/|\/\/)?(?:[^@\n]+@)?(?:www\.)?([^\n]+)/i.exec(n))==null?void 0:r[1])??n;return`${location.protocol==="https:"?"wss":"ws"}://${t}`}class ee extends Error{constructor(){super("Authentication expired"),this.name="AuthExpiredError"}}function qe(n,e){const t=n.remoteInfo;if(!t)return e.onError(new Error("remoteInfo is required for companion upload")),{abort(){}};let o=!1,r=null;const a=`${e.apiBase.replace(/\/+$/,"")}/v4/files?folder=${encodeURIComponent(e.folder)}`,l={};n.meta&&Object.keys(n.meta).length>0&&Object.assign(l,n.meta),n.tags&&n.tags.length>0&&(l.tags=n.tags);const d=!t.token;return Ae(t.companionUrl,t.provider,t.token,t.requestPath,{fileId:t.fileId,endpoint:a,headers:e.authHeaders,size:t.size,metadata:Object.keys(l).length>0?l:void 0},d).then(p=>{if(o)return;const u=`${He(t.companionUrl)}/api/${p.token}`;try{r=new WebSocket(u)}catch{e.onError(new Error("Failed to connect to upload progress channel"));return}r.onmessage=x=>{var f,v,w;if(!o)try{const b=JSON.parse(x.data);switch(b.action){case"progress":{const m=b.payload,_=m.bytesUploaded??0,E=m.bytesTotal??(t.size||1);e.onProgress(_,E);break}case"success":{const m=b.payload;if(r==null||r.close(),(f=m.response)!=null&&f.responseText)try{const _=JSON.parse(m.response.responseText);if(_.status==="success"){e.onComplete(_);return}e.onError(new Error(_.msg||"Upload failed"));return}catch{}e.onError(new Error("Upload completed but no valid response received"));break}case"error":{r==null||r.close();const m=b.payload;let _=((v=m.error)==null?void 0:v.message)||"Upload failed";if((w=m.response)!=null&&w.responseText)try{const E=JSON.parse(m.response.responseText);_=E.hint||E.msg||E.message||_}catch{}e.onError(new Error(_));break}}}catch{}},r.onerror=()=>{o||e.onError(new Error("Upload progress connection failed"))},r.onclose=()=>{r=null}}).catch(p=>{o||e.onError(p instanceof Error?p:new Error(String(p)))}),{abort(){if(o=!0,r){try{r.send(JSON.stringify({action:"cancel",payload:{}}))}catch{}r.close(),r=null}}}}class Pe{constructor(e,t){this.activeUploads=new Map,this.retryTimers=new Map,this.unsubscribe=null,this.store=e,this.config=t}start(){this.unsubscribe||(this.unsubscribe=this.store.subscribe(()=>this.processQueue()),this.processQueue())}uploadAll(){const{files:e}=this.store.getState();let t=!1;for(const o of e.values())o.status==="idle"?(S(this.store,o.id,{status:"queued"}),t=!0):o.status==="queued"&&(t=!0);t&&(this.store.setState({isUploading:!0}),this.processQueue())}retryFile(e){const t=this.store.getState().files.get(e);!t||t.status!=="error"&&t.status!=="failed"||(S(this.store,e,{status:"queued",error:null,progress:0,bytesUploaded:0,speed:0}),this.processQueue())}retryAll(){const{files:e}=this.store.getState();for(const t of e.values())(t.status==="error"||t.status==="failed")&&S(this.store,t.id,{status:"queued",error:null,progress:0,bytesUploaded:0,speed:0});this.processQueue()}cancelFile(e){const t=this.store.getState().files.get(e);!t||!we(t.status)||(this.abortUpload(e),S(this.store,e,{status:"cancelled"}))}cancelAll(){const{files:e}=this.store.getState();for(const t of e.values())we(t.status)&&(this.abortUpload(t.id),S(this.store,t.id,{status:"cancelled"}));this.store.setState({isUploading:!1})}updateConfig(e){Object.assign(this.config,e)}destroy(){var e;for(const t of this.activeUploads.keys())this.abortUpload(t);for(const t of this.retryTimers.values())clearTimeout(t);this.retryTimers.clear(),(e=this.unsubscribe)==null||e.call(this),this.unsubscribe=null}processQueue(){const e=this.store.getState();if(e.isPaused)return;const{concurrency:t}=e.queueConfig,o=this.activeUploads.size,r=t-o;if(r<=0)return;const a=[...e.files.values()].filter(l=>l.status==="queued").sort((l,d)=>l.retryCount!==d.retryCount?d.retryCount-l.retryCount:l.addedAt-d.addedAt).slice(0,r);for(const l of a)this.startUpload(l)}startUpload(e){S(this.store,e.id,{status:"uploading",error:null});let t=0,o=Date.now(),r=0;const i={apiBase:this.config.apiBase,authHeaders:this.config.authHeaders,folder:this.store.getState().targetFolder,onComplete:d=>this.handleComplete(e.id,d),onError:d=>this.handleError(e.id,d)},a=(d,p)=>{const h=Date.now(),u=(h-o)/1e3;if(u>0){const f=(d-t)/u;r=r===0?f:.3*f+.7*r}t=d,o=h;const x=p>0?Math.min(d/p*100,100):0;S(this.store,e.id,{progress:x,bytesUploaded:d,speed:r}),this.updateTotalProgress()};let l;e.remoteInfo?l=qe(e,{...i,onProgress:a}):e.remoteUrl?l=Oe(e,i):l=je(e,{...i,onProgress:a}),this.activeUploads.set(e.id,l)}handleComplete(e,t){this.activeUploads.delete(e),S(this.store,e,{status:"complete",progress:100,response:t}),this.updateTotalProgress(),this.checkAllComplete(),this.processQueue()}handleError(e,t){this.activeUploads.delete(e);const o=this.store.getState().files.get(e);if(!o)return;const{retryConfig:r}=this.store.getState().queueConfig,i=o.retryCount+1;if(i<=r.maxRetries){const a=Math.min(r.baseDelay*Math.pow(r.backoffFactor,o.retryCount),r.maxDelay);S(this.store,e,{status:"retrying",error:t.message,retryCount:i});const l=setTimeout(()=>{this.retryTimers.delete(e),S(this.store,e,{status:"queued"}),this.processQueue()},a);this.retryTimers.set(e,l)}else S(this.store,e,{status:"failed",error:t.message}),this.checkAllComplete(),this.processQueue()}abortUpload(e){var o;(o=this.activeUploads.get(e))==null||o.abort(),this.activeUploads.delete(e);const t=this.retryTimers.get(e);t&&(clearTimeout(t),this.retryTimers.delete(e))}updateTotalProgress(){const{files:e}=this.store.getState();let t=0,o=0,r=0;for(const i of e.values())(i.status==="queued"||i.status==="uploading"||i.status==="retrying"||i.status==="complete"||i.status==="failed")&&(t+=i.size,o+=i.status==="complete"?i.size:i.bytesUploaded),i.status==="uploading"&&(r+=i.speed);this.store.setState({totalBytes:t,totalBytesUploaded:o,totalSpeed:r,totalProgress:t>0?Math.min(o/t*100,100):0})}checkAllComplete(){const{files:e}=this.store.getState();![...e.values()].some(o=>o.status==="queued"||o.status==="uploading"||o.status==="retrying")&&this.store.getState().isUploading&&this.store.setState({isUploading:!1})}}function we(n){return n==="queued"||n==="uploading"||n==="retrying"}function te(n){return`https://api.filerobot.com/${n}`}async function Ue(n,e){const t=`${te(n)}/key/${encodeURIComponent(e)}`,o=new AbortController,r=setTimeout(()=>o.abort(),3e4);try{const i=await fetch(t,{signal:o.signal});if(clearTimeout(r),!i.ok)throw new Error(`SASS key exchange failed (HTTP ${i.status})`);const a=await i.json();if(a.status==="error")throw new Error(`SASS key exchange failed: ${a.msg||"Unknown error"}`);return a.key}catch(i){throw clearTimeout(r),i instanceof DOMException&&i.name==="AbortError"?new Error("SASS key exchange timed out"):i}}function K(n,e){const t={};switch(n.mode){case"security-template":if(!e)throw new Error("[sfx-uploader] Cannot build auth headers for security-template mode: SASS key exchange has not been performed. Call resolveAuth() first or use sass-key mode with a pre-resolved key.");t["X-Filerobot-Key"]=e;break;case"sass-key":t["X-Filerobot-Key"]=n.sassKey;break}return n.airboxPuid&&(t["X-Filerobot-Airbox-Puid"]=n.airboxPuid),t}async function ze(n){const e=te(n.container);if(n.mode==="security-template"){const t=await Ue(n.container,n.securityTemplateId);return{apiBase:e,headers:K(n,t),sassKey:t}}return{apiBase:e,headers:K(n)}}const g={FILE_ADDED:"sfx-file-added",FILE_REMOVED:"sfx-file-removed",FILE_REJECTED:"sfx-file-rejected",UPLOAD_STARTED:"sfx-upload-started",UPLOAD_PROGRESS:"sfx-upload-progress",UPLOAD_COMPLETE:"sfx-upload-complete",UPLOAD_ERROR:"sfx-upload-error",UPLOAD_RETRY:"sfx-upload-retry",ALL_COMPLETE:"sfx-all-complete",TOTAL_PROGRESS:"sfx-total-progress",BEFORE_UPLOAD:"sfx-before-upload",OPEN:"sfx-open",CLOSE:"sfx-close",CANCEL:"sfx-cancel",COMPLETE_ACTION:"sfx-complete-action",FILE_PREVIEW:"sfx-file-preview",FILL_METADATA:"sfx-fill-metadata"};let Ye=0;function T(){return`file-${Date.now()}-${++Ye}`}function B(n){if(n<=0)return"0 B";const e=["B","KB","MB","GB"],t=Math.min(Math.floor(Math.log(n)/Math.log(1024)),e.length-1),o=n/Math.pow(1024,t);return`${t===0?o:o.toFixed(1)} ${e[t]}`}function oe(n){if(!isFinite(n)||n<=0)return"0s";const e=Math.round(n);if(e<60)return`${e}s`;const t=Math.floor(e/60),o=e%60;return o>0?`${t}m ${o}s`:`${t}m`}function q(n){var t;const e=((t=n.name.split(".").pop())==null?void 0:t.toLowerCase())??"";return n.type.startsWith("image/")?"image":n.type.startsWith("video/")||["mp4","mov","avi","webm","mkv"].includes(e)?"vid":n.type==="application/pdf"||e==="pdf"?"pdf":["doc","docx","xls","xlsx","ppt","pptx","txt","rtf","odt"].includes(e)?"doc":["zip","rar","7z","tar","gz","bz2"].includes(e)?"zip":"gen"}function Ve(n){const e=n.lastIndexOf(".");return e>=0?n.slice(e+1).toUpperCase():""}const Ne={jpg:"image/jpeg",jpeg:"image/jpeg",png:"image/png",gif:"image/gif",webp:"image/webp",svg:"image/svg+xml",bmp:"image/bmp",ico:"image/x-icon",mp4:"video/mp4",mov:"video/quicktime",avi:"video/x-msvideo",webm:"video/webm",pdf:"application/pdf",zip:"application/zip",doc:"application/msword",docx:"application/vnd.openxmlformats-officedocument.wordprocessingml.document"};function Xe(n){var t;const e=((t=n.split(".").pop())==null?void 0:t.toLowerCase())??"";return Ne[e]||""}function We(n){return new Promise(e=>{const t=document.createElement("video");t.preload="metadata",t.muted=!0,t.playsInline=!0;const o=URL.createObjectURL(n);let r=!1;const i=()=>{r||(r=!0,e(null)),t.removeAttribute("src"),t.load(),URL.revokeObjectURL(o)};t.addEventListener("seeked",()=>{try{const a=document.createElement("canvas");a.width=t.videoWidth||320,a.height=t.videoHeight||240;const l=a.getContext("2d");if(l){l.drawImage(t,0,0,a.width,a.height),a.toBlob(d=>{r||(r=!0,e(d?URL.createObjectURL(d):null),t.removeAttribute("src"),t.load(),URL.revokeObjectURL(o))},"image/jpeg",.7);return}}catch{}i()},{once:!0}),t.addEventListener("error",()=>i(),{once:!0}),setTimeout(()=>i(),5e3),t.src=o,t.addEventListener("loadeddata",()=>{t.currentTime=.1},{once:!0})})}function ie(n,e,t){var o,r;if(e.maxFileSize!=null&&n.size>0&&n.size>e.maxFileSize)return`File exceeds ${(e.maxFileSize/1048576).toFixed(1)} MB limit`;if(e.maxTotalFilesSize!=null&&n.size>0){let i=n.size;for(const a of t.values())a.status!=="rejected"&&a.status!=="cancelled"&&(i+=a.size);if(i>e.maxTotalFilesSize)return"Total file size limit exceeded"}if(e.maxNumberOfFiles!=null){let i=0;for(const a of t.values())a.status!=="rejected"&&a.status!=="cancelled"&&i++;if(i>=e.maxNumberOfFiles)return`Maximum ${e.maxNumberOfFiles} files allowed`}if(e.allowedFileTypes!=null){const i=e.allowedFileTypes,a="."+(((o=n.name.split(".").pop())==null?void 0:o.toLowerCase())??"");if(!i.some(d=>d.startsWith(".")?a===d.toLowerCase():d.endsWith("/*")?n.type.startsWith(d.slice(0,-1)):n.type===d))return"File type not allowed"}if(e.blockedFileTypes!=null){const i=e.blockedFileTypes,a="."+(((r=n.name.split(".").pop())==null?void 0:r.toLowerCase())??"");if(i.some(d=>d.startsWith(".")?a===d.toLowerCase():d.endsWith("/*")?n.type.startsWith(d.slice(0,-1)):n.type===d))return"File type is blocked"}return null}function Ge(n,e,t){return ie(n,e,t)}function ye(n){return n.allowedFileTypes?n.allowedFileTypes.join(","):""}const _e={"google-drive":{id:"google-drive",label:"Google Drive",fillIcon:!0,icon:"",brandHtml:'<span class="brand-ico" style="background:transparent"><svg width="16" height="16" viewBox="0 0 87.3 78"><path d="M6.6 66.85l3.85 6.65c.8 1.4 1.95 2.5 3.3 3.3L27.5 53H0c0 1.55.4 3.1 1.2 4.5z" fill="#0066da"/><path d="M43.65 25L29.9 1.2C28.55 2 27.4 3.1 26.6 4.5L1.2 48.5C.4 49.9 0 51.45 0 53h27.5z" fill="#00ac47"/><path d="M73.55 76.8c1.35-.8 2.5-1.9 3.3-3.3l1.6-2.75 7.65-13.25c.8-1.4 1.2-2.95 1.2-4.5H59.8l5.65 10.85z" fill="#ea4335"/><path d="M43.65 25L57.4 1.2C56.05.4 54.5 0 52.9 0H34.4c-1.6 0-3.15.45-4.5 1.2z" fill="#00832d"/><path d="M59.8 53H27.5L13.75 76.8c1.35.8 2.9 1.2 4.5 1.2h50.8c1.6 0 3.15-.45 4.5-1.2z" fill="#2684fc"/><path d="M73.4 26.5l-12.7-22c-.8-1.4-1.95-2.5-3.3-3.3L43.65 25 59.8 53h27.45c0-1.55-.4-3.1-1.2-4.5z" fill="#ffba00"/></svg></span>'},dropbox:{id:"dropbox",label:"Dropbox",fillIcon:!0,icon:"",brandHtml:'<span class="brand-ico" style="background:#0061ff"><svg width="11" height="11" viewBox="0 0 528 512" fill="white"><path d="M264.4 116.3l-132 84.3 132 84.3-132 84.3L0 284.1l132.3-84.3L0 116.3 132.3 32l132.1 84.3zm-132 284.5l132-84.3 132 84.3-132 84.4-132-84.4zm132-116.6l132.3-84.3-132.3-83.9 131.6-84.3L528 116.3l-132.3 84.1L528 284.7l-132.4 83.9-131.2-84.4z"/></svg></span>'},onedrive:{id:"onedrive",label:"OneDrive",fillIcon:!0,icon:"",brandHtml:'<span class="brand-ico" style="background:#0078d4"><svg width="11" height="11" viewBox="0 0 24 24" fill="white"><path d="M10.5 13.5C10.5 11.57 12.07 10 14 10h6.5c.17 0 .34.01.5.02A6 6 0 009.01 11.6 4 4 0 0010.5 13.5zM12 14.5a5 5 0 00-5-5 5 5 0 00-5 5 3 3 0 003 3h9.5A3.5 3.5 0 0018 14c0-.18-.01-.35-.03-.52A5.48 5.48 0 0112 14.5z"/></svg></span>'},box:{id:"box",label:"Box",fillIcon:!0,icon:"",brandHtml:'<span class="brand-ico" style="background:#0e50a0;font-size:9px;font-weight:800;color:#fff">box</span>'},instagram:{id:"instagram",label:"Instagram",fillIcon:!0,icon:"",brandHtml:'<span class="brand-ico" style="background:linear-gradient(45deg,#f09433,#e6683c,#dc2743,#cc2366,#bc1888)"><svg width="12" height="12" viewBox="0 0 24 24" fill="white"><path d="M12 2.16c2.94 0 3.29.01 4.45.06 1.07.05 1.8.22 2.43.46.66.25 1.21.6 1.77 1.16.55.55.9 1.1 1.16 1.77.25.64.41 1.37.46 2.43.05 1.16.06 1.51.06 4.45s-.01 3.29-.06 4.45c-.05 1.07-.22 1.8-.46 2.43a4.9 4.9 0 01-1.16 1.77c-.55.55-1.1.9-1.77 1.16-.64.25-1.37.41-2.43.46-1.16.05-1.51.06-4.45.06s-3.29-.01-4.45-.06c-1.07-.05-1.8-.22-2.43-.46a4.9 4.9 0 01-1.77-1.16 4.9 4.9 0 01-1.16-1.77c-.25-.64-.41-1.37-.46-2.43C2.17 15.29 2.16 14.94 2.16 12s.01-3.29.06-4.45c.05-1.07.22-1.8.46-2.43a4.9 4.9 0 011.16-1.77A4.9 4.9 0 015.61 2.2c.64-.25 1.37-.41 2.43-.46C9.21 2.17 9.56 2.16 12 2.16zM12 16a4 4 0 110-8 4 4 0 010 8zm6.4-9.85a1.44 1.44 0 100 2.88 1.44 1.44 0 000-2.88z"/></svg></span>'},facebook:{id:"facebook",label:"Facebook",fillIcon:!0,icon:"",brandHtml:'<span class="brand-ico" style="background:#1877f2"><svg width="12" height="12" viewBox="0 0 24 24" fill="white"><path d="M24 12.07C24 5.41 18.63 0 12 0S0 5.41 0 12.07c0 6.02 4.39 11.02 10.12 11.93v-8.44H7.08v-3.49h3.04V9.41c0-3.02 1.79-4.69 4.53-4.69 1.31 0 2.68.24 2.68.24v2.97h-1.51c-1.49 0-1.95.93-1.95 1.89v2.26h3.33l-.53 3.49h-2.8v8.44C19.61 23.09 24 18.09 24 12.07z"/></svg></span>'},unsplash:{id:"unsplash",label:"Unsplash",fillIcon:!0,icon:"",brandHtml:'<span class="brand-ico" style="background:#111"><svg width="12" height="12" viewBox="0 0 24 24" fill="white"><path d="M8.5 11.5v5h7v-5h5.5V21h-18v-9.5h5.5zm7-8v5h-7v-5h7z"/></svg></span>'}};function De(n){return n.filter(e=>e in _e).map(e=>_e[e])}var Ke=Object.defineProperty,Ze=(n,e,t,o)=>{for(var r=void 0,i=n.length-1,a;i>=0;i--)(a=n[i])&&(r=a(e,t,r)||r);return r&&Ke(e,t,r),r};const Je='<rect x="2" y="3" width="20" height="14" rx="2"/><line x1="8" y1="21" x2="16" y2="21"/><line x1="12" y1="17" x2="12" y2="21"/>',Qe='<path d="M10 13a5 5 0 007.54.54l3-3a5 5 0 00-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 00-7.54-.54l-3 3a5 5 0 007.07 7.07l1.71-1.71"/>',et='<path d="M23 19a2 2 0 01-2 2H3a2 2 0 01-2-2V8a2 2 0 012-2h4l2-3h6l2 3h4a2 2 0 012 2z"/><circle cx="12" cy="13" r="4"/>',tt='<rect x="2" y="3" width="20" height="14" rx="2"/><circle cx="12" cy="10" r="1"/><path d="M7 21l5-5 5 5"/>',A=[{id:"device",label:"My Device",icon:Je,iconColor:"#2563eb"},{id:"url",label:"URL link",icon:Qe,iconColor:"#16a34a"},{id:"camera",label:"Camera",icon:et,iconColor:"#7c3aed"},{id:"screen-cast",label:"Screen capture",icon:tt,iconColor:"#ea580c"}],le=class le extends s.LitElement{constructor(){super(...arguments),this.sources=A}_handleClick(e){this.dispatchEvent(new CustomEvent("source-click",{detail:{source:e.id},bubbles:!0,composed:!0}))}render(){return s.html`
2
2
  ${this.sources.map(e=>s.html`
3
3
  <button @click=${()=>this._handleClick(e)}>
4
- ${e.brandHtml?D.unsafeHTML(e.brandHtml):s.svg`<svg viewBox="0 0 24 24" class=${e.fillIcon?"fill-icon":""}>${U.unsafeSVG(e.icon)}</svg>`}
4
+ ${e.brandHtml?O.unsafeHTML(e.brandHtml):s.svg`<svg viewBox="0 0 24 24" class=${e.fillIcon?"fill-icon":""}>${z.unsafeSVG(e.icon)}</svg>`}
5
5
  ${e.label}
6
6
  </button>
7
7
  `)}
@@ -77,13 +77,33 @@
77
77
  stroke: none;
78
78
  stroke-width: 0;
79
79
  }
80
- `;let Z=le;Ze([p.property({type:Array})],Z.prototype,"sources");var rt=Object.defineProperty,P=(n,e,t,i)=>{for(var r=void 0,o=n.length-1,a;o>=0;o--)(a=n[o])&&(r=a(e,t,r)||r);return r&&rt(e,t,r),r};const ke=3,de=class de extends s.LitElement{constructor(){super(...arguments),this.compact=!1,this.externalDragOver=!1,this.accept="",this.sources=[],this.sourcesLayout="pills",this._dragOver=!1,this._moreOpen=!1,this._visiblePills=ke,this._dragCounter=0,this._onDragEnter=e=>{e.preventDefault(),this._dragCounter++,this._dragCounter===1&&(this._dragOver=!0)},this._onDragOver=e=>{e.preventDefault()},this._onDragLeave=e=>{e.preventDefault(),this._dragCounter--,this._dragCounter<=0&&(this._dragCounter=0,this._dragOver=!1)},this._onDrop=e=>{var i;e.preventDefault(),e.stopPropagation(),this._dragCounter=0,this._dragOver=!1;const t=Array.from(((i=e.dataTransfer)==null?void 0:i.files)??[]);t.length>0&&this._emitFiles(t)},this._onClick=e=>{const t=this.shadowRoot.querySelector(".drop-zone");if(t&&this._rippleEl){const i=t.getBoundingClientRect();this._rippleEl.style.left=`${e.clientX-i.left}px`,this._rippleEl.style.top=`${e.clientY-i.top}px`,this._rippleEl.classList.remove("go"),this._rippleEl.offsetWidth,this._rippleEl.classList.add("go")}this.browse()},this._onKeyDown=e=>{(e.key==="Enter"||e.key===" ")&&(e.preventDefault(),this.browse())},this._onFileChange=e=>{const t=e.target,i=Array.from(t.files??[]);i.length>0&&this._emitFiles(i),t.value=""},this._onPaste=e=>{var r;if(!this.isConnected||this.offsetWidth===0)return;const t=(r=e.clipboardData)==null?void 0:r.items;if(!t)return;const i=[];for(const o of t)if(o.kind==="file"){const a=o.getAsFile();a&&i.push(a)}i.length>0&&(e.preventDefault(),this._emitFiles(i))},this._onDocClick=()=>{this._moreOpen&&(this._moreOpen=!1)},this._onDocKeyDown=e=>{e.key==="Escape"&&this._moreOpen&&(this._moreOpen=!1)},this._resizeTimer=null,this._onScrollOrResize=()=>{this._moreOpen&&this._positionDropdown(),this._resizeTimer&&clearTimeout(this._resizeTimer),this._resizeTimer=setTimeout(()=>this._updateVisiblePills(),100)}}browse(){var e;(e=this.fileInput)==null||e.click()}_onSourceIconClick(e){this.dispatchEvent(new CustomEvent("source-click",{detail:{source:e.id},bubbles:!0,composed:!0}))}_emitFiles(e){this.dispatchEvent(new CustomEvent("files-selected",{detail:{files:e},bubbles:!0,composed:!0}))}_toggleMore(e){e.stopPropagation(),this._moreOpen=!this._moreOpen,this._moreOpen&&requestAnimationFrame(()=>this._positionDropdown())}_positionDropdown(){var x,u;const e=(x=this.shadowRoot)==null?void 0:x.querySelector(".more-wrap > button"),t=(u=this.shadowRoot)==null?void 0:u.querySelector(".more-dropdown");if(!e||!t)return;const i=e.getBoundingClientRect(),r=8,o=t.scrollHeight,a=t.offsetWidth,l=i.top,d=window.innerHeight-i.bottom;l>=o+r||l>d?(t.classList.add("above"),t.classList.remove("below"),t.style.top=`${i.top-o-r}px`):(t.classList.add("below"),t.classList.remove("above"),t.style.top=`${i.bottom+r}px`);let h=i.right-a;h=Math.max(8,Math.min(h,window.innerWidth-a-8)),t.style.left=`${h}px`}_onMoreItemClick(e,t){t.stopPropagation(),this._moreOpen=!1,this._onSourceIconClick(e)}_updateVisiblePills(){const e=window.innerWidth;this.sourcesLayout==="cards"?e<=480?this._visiblePills=2:e<=768?this._visiblePills=3:this._visiblePills=5:e<=480?this._visiblePills=1:e<=768?this._visiblePills=2:this._visiblePills=ke}connectedCallback(){super.connectedCallback(),document.addEventListener("paste",this._onPaste),document.addEventListener("click",this._onDocClick),document.addEventListener("keydown",this._onDocKeyDown),window.addEventListener("scroll",this._onScrollOrResize,!0),window.addEventListener("resize",this._onScrollOrResize),this._updateVisiblePills()}updated(e){e.has("sourcesLayout")&&this._updateVisiblePills()}disconnectedCallback(){super.disconnectedCallback(),document.removeEventListener("paste",this._onPaste),document.removeEventListener("click",this._onDocClick),document.removeEventListener("keydown",this._onDocKeyDown),window.removeEventListener("scroll",this._onScrollOrResize,!0),window.removeEventListener("resize",this._onScrollOrResize),this._resizeTimer&&clearTimeout(this._resizeTimer)}_renderPill(e){return s.html`
80
+ `;let Z=le;Ze([c.property({type:Array})],Z.prototype,"sources");var rt=Object.defineProperty,U=(n,e,t,o)=>{for(var r=void 0,i=n.length-1,a;i>=0;i--)(a=n[i])&&(r=a(e,t,r)||r);return r&&rt(e,t,r),r};const ke=3,de=class de extends s.LitElement{constructor(){super(...arguments),this.compact=!1,this.externalDragOver=!1,this.accept="",this.sources=[],this.sourcesLayout="pills",this._dragOver=!1,this._moreOpen=!1,this._visiblePills=ke,this._dragCounter=0,this._onDragEnter=e=>{e.preventDefault(),this._dragCounter++,this._dragCounter===1&&(this._dragOver=!0)},this._onDragOver=e=>{e.preventDefault()},this._onDragLeave=e=>{e.preventDefault(),this._dragCounter--,this._dragCounter<=0&&(this._dragCounter=0,this._dragOver=!1)},this._onDrop=e=>{var o;e.preventDefault(),e.stopPropagation(),this._dragCounter=0,this._dragOver=!1;const t=Array.from(((o=e.dataTransfer)==null?void 0:o.files)??[]);t.length>0&&this._emitFiles(t)},this._onClick=e=>{const t=this.shadowRoot.querySelector(".drop-zone");if(t&&this._rippleEl){const o=t.getBoundingClientRect();this._rippleEl.style.left=`${e.clientX-o.left}px`,this._rippleEl.style.top=`${e.clientY-o.top}px`,this._rippleEl.classList.remove("go"),this._rippleEl.offsetWidth,this._rippleEl.classList.add("go")}this.browse()},this._onKeyDown=e=>{(e.key==="Enter"||e.key===" ")&&(e.preventDefault(),this.browse())},this._onFileChange=e=>{const t=e.target,o=Array.from(t.files??[]);o.length>0&&this._emitFiles(o),t.value=""},this._onPaste=e=>{var r;if(!this.isConnected||this.offsetWidth===0)return;const t=(r=e.clipboardData)==null?void 0:r.items;if(!t)return;const o=[];for(const i of t)if(i.kind==="file"){const a=i.getAsFile();a&&o.push(a)}o.length>0&&(e.preventDefault(),this._emitFiles(o))},this._portalContainer=null,this._onDocClick=e=>{var t;this._moreOpen&&((t=this._portalContainer)!=null&&t.contains(e.target)||(this._moreOpen=!1,this._updateDropdownPortal()))},this._onDocKeyDown=e=>{e.key==="Escape"&&this._moreOpen&&(this._moreOpen=!1,this._updateDropdownPortal())},this._resizeTimer=null,this._onScrollOrResize=()=>{this._moreOpen&&this._positionDropdown(),this._resizeTimer&&clearTimeout(this._resizeTimer),this._resizeTimer=setTimeout(()=>this._updateVisiblePills(),100)}}browse(){var e;(e=this.fileInput)==null||e.click()}_onSourceIconClick(e){this.dispatchEvent(new CustomEvent("source-click",{detail:{source:e.id},bubbles:!0,composed:!0}))}_emitFiles(e){this.dispatchEvent(new CustomEvent("files-selected",{detail:{files:e},bubbles:!0,composed:!0}))}_toggleMore(e){e.stopPropagation(),this._moreOpen=!this._moreOpen,this._updateDropdownPortal()}_updateDropdownPortal(){if(this._moreOpen){const e=this.sources.slice(this._visiblePills);this._portalContainer||(this._portalContainer=document.createElement("div"),this._portalContainer.setAttribute("data-sfx-more-dropdown",""),this._injectDropdownStyles(),document.body.appendChild(this._portalContainer)),s.render(s.html`<div class="sfx-more-dropdown open">
81
+ ${e.map(t=>s.html`
82
+ <button class="sfx-more-item" @click=${o=>this._onMoreItemClick(t,o)}>
83
+ <div class="sfx-more-item-ico">
84
+ ${t.brandHtml?O.unsafeHTML(t.brandHtml):t.iconColor?s.html`<svg viewBox="0 0 24 24" style="color:${t.iconColor}">${z.unsafeSVG(t.icon)}</svg>`:s.svg`<svg viewBox="0 0 24 24">${z.unsafeSVG(t.icon)}</svg>`}
85
+ </div>
86
+ ${t.label}
87
+ </button>
88
+ `)}
89
+ </div>`,this._portalContainer),requestAnimationFrame(()=>this._positionDropdown())}else this._portalContainer&&(s.render(s.nothing,this._portalContainer),this._portalContainer.remove(),this._portalContainer=null)}_injectDropdownStyles(){if(document.querySelector("style[data-sfx-more-dropdown-styles]"))return;const e=document.createElement("style");e.setAttribute("data-sfx-more-dropdown-styles",""),e.textContent=`
90
+ [data-sfx-more-dropdown] .sfx-more-dropdown { position:fixed; background:#fff; border-radius:12px; box-shadow:0 12px 40px rgba(0,0,0,0.14),0 2px 8px rgba(0,0,0,0.06); border:1px solid #e8edf5; padding:6px; min-width:210px; max-height:340px; overflow-y:auto; z-index:99999; opacity:0; visibility:hidden; pointer-events:none; transition:opacity .18s ease,visibility .18s ease,transform .18s ease; font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,sans-serif; }
91
+ [data-sfx-more-dropdown] .sfx-more-dropdown.open { opacity:1; visibility:visible; pointer-events:all; }
92
+ [data-sfx-more-dropdown] .sfx-more-item { display:flex; align-items:center; gap:10px; padding:10px 14px; border-radius:6px; border:none; background:none; width:100%; font-size:13px; font-weight:500; color:#1e293b; cursor:pointer; transition:background .15s; font-family:inherit; white-space:nowrap; }
93
+ [data-sfx-more-dropdown] .sfx-more-item:hover { background:#f5f7fa; }
94
+ [data-sfx-more-dropdown] .sfx-more-item-ico { width:32px; height:32px; border-radius:8px; background:#f8fafc; display:flex; align-items:center; justify-content:center; flex-shrink:0; }
95
+ [data-sfx-more-dropdown] .sfx-more-item-ico svg { width:16px; height:16px; fill:none; stroke:currentColor; stroke-width:2; stroke-linecap:round; }
96
+ [data-sfx-more-dropdown] .sfx-more-item .brand-ico { width:20px; height:20px; border-radius:5px; display:flex; align-items:center; justify-content:center; flex-shrink:0; }
97
+ [data-sfx-more-dropdown] .sfx-more-item .brand-ico svg { fill:white; stroke:none; stroke-width:0; }
98
+ [data-sfx-more-dropdown] .sfx-more-item .canva-ico { width:22px; height:22px; }
99
+ [data-sfx-more-dropdown] .sfx-more-item .canva-ico svg { width:22px; height:22px; }
100
+ `,document.head.appendChild(e)}_positionDropdown(){var u,x;const e=(u=this.shadowRoot)==null?void 0:u.querySelector(".more-wrap > button"),t=(x=this._portalContainer)==null?void 0:x.querySelector(".sfx-more-dropdown");if(!e||!t)return;const o=e.getBoundingClientRect(),r=8,i=t.scrollHeight,a=t.offsetWidth,l=o.top,d=window.innerHeight-o.bottom;l>=i+r||l>d?t.style.top=`${o.top-i-r}px`:t.style.top=`${o.bottom+r}px`;let h=o.right-a;h=Math.max(8,Math.min(h,window.innerWidth-a-8)),t.style.left=`${h}px`}_onMoreItemClick(e,t){t.stopPropagation(),this._moreOpen=!1,this._onSourceIconClick(e)}_updateVisiblePills(){const e=window.innerWidth;this.sourcesLayout==="cards"?e<=480?this._visiblePills=2:e<=768?this._visiblePills=3:this._visiblePills=5:e<=480?this._visiblePills=1:e<=768?this._visiblePills=2:this._visiblePills=ke}connectedCallback(){super.connectedCallback(),document.addEventListener("paste",this._onPaste),document.addEventListener("click",this._onDocClick),document.addEventListener("keydown",this._onDocKeyDown),window.addEventListener("scroll",this._onScrollOrResize,!0),window.addEventListener("resize",this._onScrollOrResize),this._updateVisiblePills()}updated(e){e.has("sourcesLayout")&&this._updateVisiblePills()}disconnectedCallback(){super.disconnectedCallback(),document.removeEventListener("paste",this._onPaste),document.removeEventListener("click",this._onDocClick),document.removeEventListener("keydown",this._onDocKeyDown),window.removeEventListener("scroll",this._onScrollOrResize,!0),window.removeEventListener("resize",this._onScrollOrResize),this._resizeTimer&&clearTimeout(this._resizeTimer),this._portalContainer&&(s.render(s.nothing,this._portalContainer),this._portalContainer.remove(),this._portalContainer=null)}_renderPill(e){return s.html`
81
101
  <button
82
102
  class="src-pill"
83
103
  @click=${t=>{t.stopPropagation(),this._onSourceIconClick(e)}}
84
104
  >
85
- ${e.brandHtml?D.unsafeHTML(e.brandHtml):s.html`<span class="pill-ico" style=${e.iconColor?`color:${e.iconColor}`:""}>
86
- ${s.svg`<svg viewBox="0 0 24 24" class=${e.fillIcon?"fill-icon":""}>${U.unsafeSVG(e.icon)}</svg>`}
105
+ ${e.brandHtml?O.unsafeHTML(e.brandHtml):s.html`<span class="pill-ico" style=${e.iconColor?`color:${e.iconColor}`:""}>
106
+ ${s.svg`<svg viewBox="0 0 24 24" class=${e.fillIcon?"fill-icon":""}>${z.unsafeSVG(e.icon)}</svg>`}
87
107
  </span>`}
88
108
  ${e.label}
89
109
  </button>
@@ -93,14 +113,14 @@
93
113
  aria-label=${e.label}
94
114
  @click=${t=>{t.stopPropagation(),this._onSourceIconClick(e)}}
95
115
  >
96
- ${e.brandHtml?s.html`<span class="card-ico">${D.unsafeHTML(e.brandHtml)}</span>`:s.html`<span class="card-ico" style=${e.iconColor?`color:${e.iconColor}`:""}>
97
- ${s.svg`<svg viewBox="0 0 24 24" class=${e.fillIcon?"fill-icon":""}>${U.unsafeSVG(e.icon)}</svg>`}
116
+ ${e.brandHtml?s.html`<span class="card-ico">${O.unsafeHTML(e.brandHtml)}</span>`:s.html`<span class="card-ico" style=${e.iconColor?`color:${e.iconColor}`:""}>
117
+ ${s.svg`<svg viewBox="0 0 24 24" class=${e.fillIcon?"fill-icon":""}>${z.unsafeSVG(e.icon)}</svg>`}
98
118
  </span>`}
99
119
  <span class="card-label">${e.label}</span>
100
120
  </button>
101
- `}_renderMoreCard(e){return s.html`
121
+ `}_renderMoreCard(){return s.html`
102
122
  <div class="more-wrap ${this._moreOpen?"open":""}">
103
- <button class="src-card" @click=${t=>this._toggleMore(t)}>
123
+ <button class="src-card" @click=${e=>this._toggleMore(e)}>
104
124
  <span class="card-ico" style="color: var(--sfx-up-text-muted, #94a3b8)">
105
125
  <svg viewBox="0 0 24 24" style="fill: currentColor; stroke: none">
106
126
  <circle cx="5" cy="12" r="2.5"/>
@@ -110,35 +130,15 @@
110
130
  </span>
111
131
  <span class="card-label">More</span>
112
132
  </button>
113
- <div class="more-dropdown">
114
- ${e.map(t=>s.html`
115
- <button class="more-item" @click=${i=>this._onMoreItemClick(t,i)}>
116
- <div class="more-item-ico">
117
- ${t.brandHtml?D.unsafeHTML(t.brandHtml):t.iconColor?s.html`<svg viewBox="0 0 24 24" style="color:${t.iconColor}">${U.unsafeSVG(t.icon)}</svg>`:s.svg`<svg viewBox="0 0 24 24">${U.unsafeSVG(t.icon)}</svg>`}
118
- </div>
119
- ${t.label}
120
- </button>
121
- `)}
122
- </div>
123
133
  </div>
124
- `}_renderMoreDropdown(e){return s.html`
134
+ `}_renderMoreDropdown(){return s.html`
125
135
  <div class="more-wrap ${this._moreOpen?"open":""}">
126
- <button class="more-pill" @click=${t=>this._toggleMore(t)}>
136
+ <button class="more-pill" @click=${e=>this._toggleMore(e)}>
127
137
  More
128
138
  <svg class="more-chevron" viewBox="0 0 24 24"><polyline points="6 9 12 15 18 9"/></svg>
129
139
  </button>
130
- <div class="more-dropdown">
131
- ${e.map(t=>s.html`
132
- <button class="more-item" @click=${i=>this._onMoreItemClick(t,i)}>
133
- <div class="more-item-ico">
134
- ${t.brandHtml?D.unsafeHTML(t.brandHtml):t.iconColor?s.html`<svg viewBox="0 0 24 24" style="color:${t.iconColor}">${U.unsafeSVG(t.icon)}</svg>`:s.svg`<svg viewBox="0 0 24 24">${U.unsafeSVG(t.icon)}</svg>`}
135
- </div>
136
- ${t.label}
137
- </button>
138
- `)}
139
- </div>
140
140
  </div>
141
- `}render(){const e=["drop-zone",this._dragOver||this.externalDragOver?"drag-over":"",this.compact?"compact":""].filter(Boolean).join(" "),t=this.sources.slice(0,this._visiblePills),i=this.sources.slice(this._visiblePills);return s.html`
141
+ `}render(){const e=["drop-zone",this._dragOver||this.externalDragOver?"drag-over":"",this.compact?"compact":""].filter(Boolean).join(" "),t=this.sources.slice(0,this._visiblePills),o=this.sources.slice(this._visiblePills);return s.html`
142
142
  <div
143
143
  class=${e}
144
144
  role="button"
@@ -174,12 +174,12 @@
174
174
  ${this.sourcesLayout==="cards"?s.html`
175
175
  <div class="sources-cards">
176
176
  ${t.map(r=>this._renderCard(r))}
177
- ${i.length>0?this._renderMoreCard(i):s.nothing}
177
+ ${o.length>0?this._renderMoreCard():s.nothing}
178
178
  </div>
179
179
  `:s.html`
180
180
  <div class="sources-grid">
181
181
  ${t.map(r=>this._renderPill(r))}
182
- ${i.length>0?this._renderMoreDropdown(i):s.nothing}
182
+ ${o.length>0?this._renderMoreDropdown():s.nothing}
183
183
  </div>
184
184
  `}
185
185
  `:s.nothing}
@@ -192,9 +192,9 @@
192
192
  style=${r.iconColor&&!r.brandHtml?`color:${r.iconColor}`:""}
193
193
  data-tip=${r.label}
194
194
  aria-label=${r.label}
195
- @click=${o=>{o.stopPropagation(),this._onSourceIconClick(r)}}
195
+ @click=${i=>{i.stopPropagation(),this._onSourceIconClick(r)}}
196
196
  >
197
- ${r.brandHtml?D.unsafeHTML(r.brandHtml):s.svg`<svg viewBox="0 0 24 24" class=${r.fillIcon?"fill-icon":""}>${U.unsafeSVG(r.icon)}</svg>`}
197
+ ${r.brandHtml?O.unsafeHTML(r.brandHtml):s.svg`<svg viewBox="0 0 24 24" class=${r.fillIcon?"fill-icon":""}>${z.unsafeSVG(r.icon)}</svg>`}
198
198
  </button>
199
199
  `)}
200
200
  </div>
@@ -990,11 +990,11 @@
990
990
  animation: none;
991
991
  }
992
992
  }
993
- `;let C=de;P([p.property({type:Boolean,reflect:!0})],C.prototype,"compact");P([p.property({type:Boolean,attribute:"external-drag-over"})],C.prototype,"externalDragOver");P([p.property({type:String})],C.prototype,"accept");P([p.property({type:Array})],C.prototype,"sources");P([p.property({type:String,attribute:"sources-layout"})],C.prototype,"sourcesLayout");P([p.state()],C.prototype,"_dragOver");P([p.state()],C.prototype,"_moreOpen");P([p.state()],C.prototype,"_visiblePills");P([p.query(".ripple")],C.prototype,"_rippleEl");P([p.query('input[type="file"]')],C.prototype,"fileInput");const ce=class ce extends s.LitElement{render(){return s.html`
993
+ `;let C=de;U([c.property({type:Boolean,reflect:!0})],C.prototype,"compact");U([c.property({type:Boolean,attribute:"external-drag-over"})],C.prototype,"externalDragOver");U([c.property({type:String})],C.prototype,"accept");U([c.property({type:Array})],C.prototype,"sources");U([c.property({type:String,attribute:"sources-layout"})],C.prototype,"sourcesLayout");U([c.state()],C.prototype,"_dragOver");U([c.state()],C.prototype,"_moreOpen");U([c.state()],C.prototype,"_visiblePills");U([c.query(".ripple")],C.prototype,"_rippleEl");U([c.query('input[type="file"]')],C.prototype,"fileInput");const pe=class pe extends s.LitElement{render(){return s.html`
994
994
  <div class="line"></div>
995
995
  <div class="label">or import from</div>
996
996
  <div class="line"></div>
997
- `}};ce.styles=s.css`
997
+ `}};pe.styles=s.css`
998
998
  :host {
999
999
  display: flex;
1000
1000
  align-items: center;
@@ -1016,7 +1016,31 @@
1016
1016
  letter-spacing: 1px;
1017
1017
  white-space: nowrap;
1018
1018
  }
1019
- `;let se=ce;var it=Object.defineProperty,V=(n,e,t,i)=>{for(var r=void 0,o=n.length-1,a;o>=0;o--)(a=n[o])&&(r=a(e,t,r)||r);return r&&it(e,t,r),r};const pe=class pe extends s.LitElement{constructor(){super(...arguments),this.files=[],this.showDropTile=!1,this.sources=[],this.accept="",this._moreOpen=!1,this._outsideClickHandler=e=>{const t=e.composedPath(),i=this.renderRoot.querySelector(".drop-tile-more-wrap");i&&!t.includes(i)&&(this._moreOpen=!1,document.removeEventListener("click",this._outsideClickHandler,!0))}}_onDropTileClick(){const e=this.renderRoot.querySelector('input[type="file"]');e==null||e.click()}_onFileInput(e){const t=e.target,i=Array.from(t.files??[]);i.length>0&&this.dispatchEvent(new CustomEvent("files-selected",{detail:{files:i},bubbles:!0,composed:!0})),t.value=""}_onSourceClick(e,t){if(e.stopPropagation(),t.id==="device"){const i=this.renderRoot.querySelector('input[type="file"]');i==null||i.click();return}this.dispatchEvent(new CustomEvent("source-click",{detail:{source:t},bubbles:!0,composed:!0}))}_toggleMore(e){e.stopPropagation(),this._moreOpen=!this._moreOpen,this._moreOpen?requestAnimationFrame(()=>document.addEventListener("click",this._outsideClickHandler,!0)):document.removeEventListener("click",this._outsideClickHandler,!0)}disconnectedCallback(){super.disconnectedCallback(),this._moreOpen=!1,document.removeEventListener("click",this._outsideClickHandler,!0)}_onMoreSourceClick(e,t){this._moreOpen=!1,document.removeEventListener("click",this._outsideClickHandler,!0),this._onSourceClick(e,t)}_renderDropTile(){const t=this.sources.slice(0,3),i=this.sources.slice(3);return s.html`
1019
+ `;let se=pe;var ot=Object.defineProperty,V=(n,e,t,o)=>{for(var r=void 0,i=n.length-1,a;i>=0;i--)(a=n[i])&&(r=a(e,t,r)||r);return r&&ot(e,t,r),r};const ce=class ce extends s.LitElement{constructor(){super(...arguments),this.files=[],this.showDropTile=!1,this.sources=[],this.accept="",this._moreOpen=!1,this._portalContainer=null,this._outsideClickHandler=e=>{var r;if((r=this._portalContainer)!=null&&r.contains(e.target))return;const t=this.renderRoot.querySelector(".drop-tile-more-wrap"),o=e.composedPath();t&&o.includes(t)||(this._moreOpen=!1,this._closePortal(),document.removeEventListener("click",this._outsideClickHandler,!0))},this._onScrollOrResize=()=>{this._moreOpen&&this._positionPortal()},this._onKeyDown=e=>{e.key==="Escape"&&this._moreOpen&&(this._moreOpen=!1,this._closePortal(),this._removeGlobalListeners())}}_onDropTileClick(){const e=this.renderRoot.querySelector('input[type="file"]');e==null||e.click()}_onFileInput(e){const t=e.target,o=Array.from(t.files??[]);o.length>0&&this.dispatchEvent(new CustomEvent("files-selected",{detail:{files:o},bubbles:!0,composed:!0})),t.value=""}_onSourceClick(e,t){if(e.stopPropagation(),t.id==="device"){const o=this.renderRoot.querySelector('input[type="file"]');o==null||o.click();return}this.dispatchEvent(new CustomEvent("source-click",{detail:{source:t},bubbles:!0,composed:!0}))}_addGlobalListeners(){requestAnimationFrame(()=>document.addEventListener("click",this._outsideClickHandler,!0)),document.addEventListener("keydown",this._onKeyDown),window.addEventListener("scroll",this._onScrollOrResize,!0),window.addEventListener("resize",this._onScrollOrResize)}_removeGlobalListeners(){document.removeEventListener("click",this._outsideClickHandler,!0),document.removeEventListener("keydown",this._onKeyDown),window.removeEventListener("scroll",this._onScrollOrResize,!0),window.removeEventListener("resize",this._onScrollOrResize)}_toggleMore(e){e.stopPropagation(),this._moreOpen=!this._moreOpen,this._moreOpen?(this._openPortal(),this._addGlobalListeners()):(this._closePortal(),this._removeGlobalListeners())}_openPortal(){const e=this.sources.slice(3);this._portalContainer||(this._portalContainer=document.createElement("div"),this._portalContainer.setAttribute("data-sfx-tile-dropdown",""),this._injectTileDropdownStyles(),document.body.appendChild(this._portalContainer)),s.render(s.html`<div class="sfx-tile-dropdown">
1020
+ ${e.map(t=>s.html`
1021
+ <button
1022
+ class="sfx-tile-dropdown-item"
1023
+ @click=${o=>this._onMoreSourceClick(o,t)}
1024
+ >
1025
+ <span class="sfx-tile-dropdown-ico" style=${t.iconColor&&!t.brandHtml?`color:${t.iconColor}`:""}>
1026
+ ${t.brandHtml?O.unsafeHTML(t.brandHtml):s.svg`<svg viewBox="0 0 24 24" class=${t.fillIcon?"fill-icon":""}>${z.unsafeSVG(t.icon)}</svg>`}
1027
+ </span>
1028
+ ${t.label}
1029
+ </button>
1030
+ `)}
1031
+ </div>`,this._portalContainer),requestAnimationFrame(()=>this._positionPortal())}_positionPortal(){var u;const e=this.renderRoot.querySelector(".drop-tile-more"),t=(u=this._portalContainer)==null?void 0:u.querySelector(".sfx-tile-dropdown");if(!e||!t)return;const o=e.getBoundingClientRect(),r=6,i=t.scrollHeight,a=t.offsetWidth,l=o.top,d=window.innerHeight-o.bottom;l>=i+r||l>d?t.style.top=`${o.top-i-r}px`:t.style.top=`${o.bottom+r}px`;let h=o.right-a;h=Math.max(8,Math.min(h,window.innerWidth-a-8)),t.style.left=`${h}px`}_closePortal(){this._portalContainer&&(s.render(s.nothing,this._portalContainer),this._portalContainer.remove(),this._portalContainer=null)}_injectTileDropdownStyles(){if(document.querySelector("style[data-sfx-tile-dropdown-styles]"))return;const e=document.createElement("style");e.setAttribute("data-sfx-tile-dropdown-styles",""),e.textContent=`
1032
+ [data-sfx-tile-dropdown] .sfx-tile-dropdown { position:fixed; background:#fff; border:1px solid #e2e8f0; border-radius:10px; box-shadow:0 4px 20px rgba(0,0,0,0.12); padding:6px; z-index:99999; min-width:180px; font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,sans-serif; animation:sfxTileDropIn .15s ease; }
1033
+ [data-sfx-tile-dropdown] .sfx-tile-dropdown-item { display:flex; align-items:center; gap:10px; width:100%; padding:8px 12px; border:none; background:none; border-radius:6px; cursor:pointer; font-size:13px; font-weight:500; color:#1e293b; white-space:nowrap; transition:background .15s; font-family:inherit; }
1034
+ [data-sfx-tile-dropdown] .sfx-tile-dropdown-item:hover { background:#f5f7fa; }
1035
+ [data-sfx-tile-dropdown] .sfx-tile-dropdown-ico { width:32px; height:32px; border-radius:8px; background:#f8fafc; display:flex; align-items:center; justify-content:center; flex-shrink:0; }
1036
+ [data-sfx-tile-dropdown] .sfx-tile-dropdown-ico svg { width:16px; height:16px; fill:none; stroke:currentColor; stroke-width:2; stroke-linecap:round; stroke-linejoin:round; }
1037
+ [data-sfx-tile-dropdown] .sfx-tile-dropdown-ico svg.fill-icon { fill:currentColor; stroke:none; }
1038
+ [data-sfx-tile-dropdown] .sfx-tile-dropdown-ico .brand-ico { width:20px; height:20px; border-radius:5px; display:flex; align-items:center; justify-content:center; }
1039
+ [data-sfx-tile-dropdown] .sfx-tile-dropdown-ico .brand-ico svg { fill:white; stroke:none; stroke-width:0; }
1040
+ [data-sfx-tile-dropdown] .sfx-tile-dropdown-ico .canva-ico { width:22px; height:22px; }
1041
+ [data-sfx-tile-dropdown] .sfx-tile-dropdown-ico .canva-ico svg { width:22px; height:22px; }
1042
+ @keyframes sfxTileDropIn { from{opacity:0;transform:translateY(-4px)} to{opacity:1;transform:translateY(0)} }
1043
+ `,document.head.appendChild(e)}disconnectedCallback(){super.disconnectedCallback(),this._moreOpen=!1,this._closePortal(),this._removeGlobalListeners()}_onMoreSourceClick(e,t){this._moreOpen=!1,this._closePortal(),this._removeGlobalListeners(),this._onSourceClick(e,t)}_renderDropTile(){const t=this.sources.slice(0,3),o=this.sources.slice(3);return s.html`
1020
1044
  <div class="drop-tile" @click=${this._onDropTileClick}>
1021
1045
  <div class="drop-tile-rings">
1022
1046
  <div class="drop-tile-ring"></div>
@@ -1037,29 +1061,14 @@
1037
1061
  class="drop-tile-src"
1038
1062
  style=${r.iconColor&&!r.brandHtml?`color:${r.iconColor}`:""}
1039
1063
  title=${r.label}
1040
- @click=${o=>this._onSourceClick(o,r)}
1064
+ @click=${i=>this._onSourceClick(i,r)}
1041
1065
  >
1042
- ${r.brandHtml?D.unsafeHTML(r.brandHtml):s.svg`<svg viewBox="0 0 24 24" class=${r.fillIcon?"fill-icon":""}>${U.unsafeSVG(r.icon)}</svg>`}
1066
+ ${r.brandHtml?O.unsafeHTML(r.brandHtml):s.svg`<svg viewBox="0 0 24 24" class=${r.fillIcon?"fill-icon":""}>${z.unsafeSVG(r.icon)}</svg>`}
1043
1067
  </button>
1044
1068
  `)}
1045
- ${i.length>0?s.html`
1069
+ ${o.length>0?s.html`
1046
1070
  <div class="drop-tile-more-wrap">
1047
1071
  <button class="drop-tile-more" title="More sources" @click=${r=>this._toggleMore(r)}>···</button>
1048
- ${this._moreOpen?s.html`
1049
- <div class="more-dropdown">
1050
- ${i.map(r=>s.html`
1051
- <button
1052
- class="more-dropdown-item"
1053
- @click=${o=>this._onMoreSourceClick(o,r)}
1054
- >
1055
- <span class="more-dropdown-ico" style=${r.iconColor&&!r.brandHtml?`color:${r.iconColor}`:""}>
1056
- ${r.brandHtml?D.unsafeHTML(r.brandHtml):s.svg`<svg viewBox="0 0 24 24" class=${r.fillIcon?"fill-icon":""}>${U.unsafeSVG(r.icon)}</svg>`}
1057
- </span>
1058
- ${r.label}
1059
- </button>
1060
- `)}
1061
- </div>
1062
- `:s.nothing}
1063
1072
  </div>
1064
1073
  `:s.nothing}
1065
1074
  </div>
@@ -1071,7 +1080,7 @@
1071
1080
  ${this.showDropTile?this._renderDropTile():s.nothing}
1072
1081
  ${this.files.map((e,t)=>s.html`<sfx-file-item .file=${e} style="--tile-index:${t}"></sfx-file-item>`)}
1073
1082
  </div>
1074
- `}};pe.styles=s.css`
1083
+ `}};ce.styles=s.css`
1075
1084
  :host {
1076
1085
  display: block;
1077
1086
  flex: 1;
@@ -1104,7 +1113,7 @@
1104
1113
  display: grid;
1105
1114
  grid-template-columns: repeat(auto-fill, minmax(var(--sfx-up-grid-min, max(24%, 140px)), 1fr));
1106
1115
  gap: 12px;
1107
- padding: 2px 12px 16px 16px;
1116
+ padding: 0 12px 16px 16px;
1108
1117
  }
1109
1118
 
1110
1119
  @media (max-width: 480px) {
@@ -1123,10 +1132,10 @@
1123
1132
  flex-direction: column;
1124
1133
  align-items: center;
1125
1134
  justify-content: center;
1126
- gap: 8px;
1135
+ gap: 6px;
1127
1136
  cursor: pointer;
1128
1137
  transition: all 0.18s ease;
1129
- padding: 16px 12px;
1138
+ padding: 12px 10px;
1130
1139
  position: relative;
1131
1140
  z-index: 1;
1132
1141
  min-height: 0;
@@ -1139,8 +1148,8 @@
1139
1148
  }
1140
1149
 
1141
1150
  .drop-tile-rings {
1142
- width: clamp(48px, 8vw, 72px);
1143
- height: clamp(48px, 8vw, 72px);
1151
+ width: clamp(40px, 6vw, 60px);
1152
+ height: clamp(40px, 6vw, 60px);
1144
1153
  position: relative;
1145
1154
  display: flex;
1146
1155
  align-items: center;
@@ -1169,8 +1178,8 @@
1169
1178
  }
1170
1179
 
1171
1180
  .drop-tile-core {
1172
- width: clamp(28px, 5vw, 40px);
1173
- height: clamp(28px, 5vw, 40px);
1181
+ width: clamp(24px, 4vw, 34px);
1182
+ height: clamp(24px, 4vw, 34px);
1174
1183
  border-radius: 50%;
1175
1184
  background: var(--sfx-up-primary-bg, #eff6ff);
1176
1185
  color: var(--sfx-up-primary, #2563eb);
@@ -1188,16 +1197,16 @@
1188
1197
  }
1189
1198
 
1190
1199
  .drop-tile-core svg {
1191
- width: 20px;
1192
- height: 20px;
1200
+ width: 16px;
1201
+ height: 16px;
1193
1202
  }
1194
1203
 
1195
1204
  .drop-tile-text {
1196
- font-size: 12px;
1205
+ font-size: 11px;
1197
1206
  font-weight: 500;
1198
1207
  color: var(--sfx-up-text-secondary, #475569);
1199
1208
  text-align: center;
1200
- line-height: 1.4;
1209
+ line-height: 1.3;
1201
1210
  }
1202
1211
 
1203
1212
  .drop-tile-text span {
@@ -1207,8 +1216,8 @@
1207
1216
 
1208
1217
  .drop-tile-sources {
1209
1218
  display: flex;
1210
- gap: 4px;
1211
- margin-top: 4px;
1219
+ gap: 3px;
1220
+ margin-top: 2px;
1212
1221
  }
1213
1222
 
1214
1223
  .drop-tile-src {
@@ -1372,7 +1381,7 @@
1372
1381
  input[type="file"] {
1373
1382
  display: none;
1374
1383
  }
1375
- `;let F=pe;V([p.property({attribute:!1})],F.prototype,"files");V([p.property({type:Boolean})],F.prototype,"showDropTile");V([p.property({attribute:!1})],F.prototype,"sources");V([p.property({type:String})],F.prototype,"accept");V([p.state()],F.prototype,"_moreOpen");var ot=Object.defineProperty,st=(n,e,t,i)=>{for(var r=void 0,o=n.length-1,a;o>=0;o--)(a=n[o])&&(r=a(e,t,r)||r);return r&&ot(e,t,r),r};const fe=class fe extends s.LitElement{_remove(){this.dispatchEvent(new CustomEvent("file-remove",{detail:{fileId:this.file.id},bubbles:!0,composed:!0}))}_retry(){this.dispatchEvent(new CustomEvent("file-retry",{detail:{fileId:this.file.id},bubbles:!0,composed:!0}))}_preview(e){e.stopPropagation(),this.dispatchEvent(new CustomEvent("file-preview",{detail:{fileId:this.file.id},bubbles:!0,composed:!0}))}render(){const e=this.file;if(!e)return s.nothing;const t=q(e),i=e.status==="complete",r=e.status==="uploading",o=e.status==="error"||e.status==="failed",a=e.status==="rejected",l=Ve(e.name),d=["tile",i?"done":"",r?"uploading":"",a?"rejected":""].filter(Boolean).join(" ");return s.html`
1384
+ `;let D=ce;V([c.property({attribute:!1})],D.prototype,"files");V([c.property({type:Boolean})],D.prototype,"showDropTile");V([c.property({attribute:!1})],D.prototype,"sources");V([c.property({type:String})],D.prototype,"accept");V([c.state()],D.prototype,"_moreOpen");var it=Object.defineProperty,st=(n,e,t,o)=>{for(var r=void 0,i=n.length-1,a;i>=0;i--)(a=n[i])&&(r=a(e,t,r)||r);return r&&it(e,t,r),r};const fe=class fe extends s.LitElement{_remove(){this.dispatchEvent(new CustomEvent("file-remove",{detail:{fileId:this.file.id},bubbles:!0,composed:!0}))}_retry(){this.dispatchEvent(new CustomEvent("file-retry",{detail:{fileId:this.file.id},bubbles:!0,composed:!0}))}_preview(e){e.stopPropagation(),this.dispatchEvent(new CustomEvent("file-preview",{detail:{fileId:this.file.id},bubbles:!0,composed:!0}))}render(){const e=this.file;if(!e)return s.nothing;const t=q(e),o=e.status==="complete",r=e.status==="uploading",i=e.status==="error"||e.status==="failed",a=e.status==="rejected",l=Ve(e.name),d=["tile",o?"done":"",r?"uploading":"",a?"rejected":""].filter(Boolean).join(" ");return s.html`
1376
1385
  <div class=${d} tabindex="0">
1377
1386
  <!-- Preview area -->
1378
1387
  <div class="preview">
@@ -1387,7 +1396,7 @@
1387
1396
  `}
1388
1397
 
1389
1398
  <!-- Preview button -->
1390
- ${!i&&!r&&!o&&e.status!=="rejected"?s.html`
1399
+ ${!o&&!r&&!i&&e.status!=="rejected"?s.html`
1391
1400
  <button class="preview-btn" @click=${this._preview} aria-label="Preview file">
1392
1401
  <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round">
1393
1402
  <path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"/>
@@ -1403,7 +1412,7 @@
1403
1412
  </div>
1404
1413
 
1405
1414
  <!-- Done badge -->
1406
- ${i?s.html`<div class="done-badge">
1415
+ ${o?s.html`<div class="done-badge">
1407
1416
  <svg viewBox="0 0 24 24" fill="none" stroke="#fff" stroke-width="3" stroke-linecap="round">
1408
1417
  <polyline points="20 6 9 17 4 12" />
1409
1418
  </svg>
@@ -1417,15 +1426,15 @@
1417
1426
  `:s.nothing}
1418
1427
 
1419
1428
  <!-- Error / rejected badge -->
1420
- ${(o||a)&&e.error?s.html`<div class="error-badge" title=${e.error}>${e.error}</div>`:s.nothing}
1429
+ ${(i||a)&&e.error?s.html`<div class="error-badge" title=${e.error}>${e.error}</div>`:s.nothing}
1421
1430
 
1422
1431
  <!-- Video duration badge (hidden when error badge is shown to avoid overlap) -->
1423
- ${!(o||a)&&e.duration!=null&&e.duration>0?s.html`<div class="duration-badge">${this._formatDuration(e.duration)}</div>`:s.nothing}
1432
+ ${!(i||a)&&e.duration!=null&&e.duration>0?s.html`<div class="duration-badge">${this._formatDuration(e.duration)}</div>`:s.nothing}
1424
1433
  </div>
1425
1434
 
1426
1435
  <!-- Action buttons -->
1427
1436
  <div class="actions">
1428
- ${o?s.html`
1437
+ ${i?s.html`
1429
1438
  <button class="act-btn retry" @click=${this._retry} title="Retry" aria-label="Retry upload">
1430
1439
  <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round">
1431
1440
  <polyline points="23 4 23 10 17 10" />
@@ -1447,10 +1456,10 @@
1447
1456
  <!-- Info bar -->
1448
1457
  <div class="info">
1449
1458
  <div class="name" title=${e.name}>${e.name}</div>
1450
- <div class="meta">${l||""}${e.size?` · ${R(e.size)}`:""}</div>
1459
+ <div class="meta">${l||""}${e.size?` · ${B(e.size)}`:""}</div>
1451
1460
  </div>
1452
1461
  </div>
1453
- `}_formatDuration(e){const t=Math.floor(e/60),i=Math.floor(e%60);return`${t}:${i.toString().padStart(2,"0")}`}_renderTypeIcon(e){switch(e){case"pdf":return s.html`<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><path d="M14 2H6a2 2 0 00-2 2v16a2 2 0 002 2h12a2 2 0 002-2V8z"/><polyline points="14 2 14 8 20 8"/></svg>`;case"doc":return s.html`<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><path d="M14 2H6a2 2 0 00-2 2v16a2 2 0 002 2h12a2 2 0 002-2V8z"/><polyline points="14 2 14 8 20 8"/><line x1="16" y1="13" x2="8" y2="13"/><line x1="16" y1="17" x2="8" y2="17"/></svg>`;case"vid":return s.html`<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><polygon points="23 7 16 12 23 17 23 7"/><rect x="1" y="5" width="15" height="14" rx="2"/></svg>`;case"zip":return s.html`<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><path d="M21 8v13H3V8"/><path d="M1 3h22v5H1z"/><path d="M10 12h4"/></svg>`;default:return s.html`<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><path d="M13 2H6a2 2 0 00-2 2v16a2 2 0 002 2h12a2 2 0 002-2V9z"/><polyline points="13 2 13 9 20 9"/></svg>`}}};fe.styles=s.css`
1462
+ `}_formatDuration(e){const t=Math.floor(e/60),o=Math.floor(e%60);return`${t}:${o.toString().padStart(2,"0")}`}_renderTypeIcon(e){switch(e){case"pdf":return s.html`<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><path d="M14 2H6a2 2 0 00-2 2v16a2 2 0 002 2h12a2 2 0 002-2V8z"/><polyline points="14 2 14 8 20 8"/></svg>`;case"doc":return s.html`<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><path d="M14 2H6a2 2 0 00-2 2v16a2 2 0 002 2h12a2 2 0 002-2V8z"/><polyline points="14 2 14 8 20 8"/><line x1="16" y1="13" x2="8" y2="13"/><line x1="16" y1="17" x2="8" y2="17"/></svg>`;case"vid":return s.html`<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><polygon points="23 7 16 12 23 17 23 7"/><rect x="1" y="5" width="15" height="14" rx="2"/></svg>`;case"zip":return s.html`<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><path d="M21 8v13H3V8"/><path d="M1 3h22v5H1z"/><path d="M10 12h4"/></svg>`;default:return s.html`<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><path d="M13 2H6a2 2 0 00-2 2v16a2 2 0 002 2h12a2 2 0 002-2V9z"/><polyline points="13 2 13 9 20 9"/></svg>`}}};fe.styles=s.css`
1454
1463
  :host {
1455
1464
  display: block;
1456
1465
  }
@@ -1480,15 +1489,23 @@
1480
1489
  aspect-ratio: 16 / 10;
1481
1490
  overflow: hidden;
1482
1491
  flex-shrink: 0;
1483
- background: var(--sfx-up-border-light, #f3f4f6);
1492
+ background-color: var(--sfx-up-checker-bg, #fff);
1493
+ background-image:
1494
+ linear-gradient(45deg, var(--sfx-up-checker-tile, #f0f0f0) 25%, transparent 25%),
1495
+ linear-gradient(-45deg, var(--sfx-up-checker-tile, #f0f0f0) 25%, transparent 25%),
1496
+ linear-gradient(45deg, transparent 75%, var(--sfx-up-checker-tile, #f0f0f0) 75%),
1497
+ linear-gradient(-45deg, transparent 75%, var(--sfx-up-checker-tile, #f0f0f0) 75%);
1498
+ background-size: 16px 16px;
1499
+ background-position: 0 0, 0 8px, 8px -8px, -8px 0;
1484
1500
  border-radius: 10px 10px 0 0;
1485
1501
  }
1486
1502
 
1487
1503
  .preview-bg {
1488
1504
  position: absolute;
1489
1505
  inset: 0;
1490
- background-size: cover;
1506
+ background-size: contain;
1491
1507
  background-position: center;
1508
+ background-repeat: no-repeat;
1492
1509
  transition: transform 0.4s ease;
1493
1510
  }
1494
1511
 
@@ -1823,7 +1840,7 @@
1823
1840
  .tile { animation: none; }
1824
1841
  .spin-ring { animation: none; }
1825
1842
  }
1826
- `;let J=fe;st([p.property({attribute:!1})],J.prototype,"file");const N=s.css`
1843
+ `;let J=fe;st([c.property({attribute:!1})],J.prototype,"file");const N=s.css`
1827
1844
  .btn,
1828
1845
  .btn-ghost,
1829
1846
  .btn-primary,
@@ -1897,10 +1914,13 @@
1897
1914
  outline: 2px solid var(--sfx-up-ring, oklch(0.578 0.198 268.129 / 0.7));
1898
1915
  outline-offset: 2px;
1899
1916
  }
1900
- `;var at=Object.defineProperty,W=(n,e,t,i)=>{for(var r=void 0,o=n.length-1,a;o>=0;o--)(a=n[o])&&(r=a(e,t,r)||r);return r&&at(e,t,r),r};const Ce=7,he=class he extends s.LitElement{constructor(){super(...arguments),this.fileCount=0,this.totalSize=0,this.thumbnails=[],this.primaryLabel="Done",this.failedFiles=[]}_uploadMore(){this.dispatchEvent(new CustomEvent("upload-more",{bubbles:!0,composed:!0}))}_primaryAction(){this.dispatchEvent(new CustomEvent("primary-action",{bubbles:!0,composed:!0}))}render(){const e=this.thumbnails.slice(0,Ce),t=this.thumbnails.length-Ce,i=this.fileCount>0,r=this.failedFiles.length>0,o=r&&!i;return s.html`
1917
+ `;var at=Object.defineProperty,W=(n,e,t,o)=>{for(var r=void 0,i=n.length-1,a;i>=0;i--)(a=n[i])&&(r=a(e,t,r)||r);return r&&at(e,t,r),r};const Ce=7,he=class he extends s.LitElement{constructor(){super(...arguments),this.fileCount=0,this.totalSize=0,this.thumbnails=[],this.primaryLabel="Done",this.failedFiles=[]}_uploadMore(){this.dispatchEvent(new CustomEvent("upload-more",{bubbles:!0,composed:!0}))}_primaryAction(){this.dispatchEvent(new CustomEvent("primary-action",{bubbles:!0,composed:!0}))}_retryFile(e){this.dispatchEvent(new CustomEvent("file-retry",{bubbles:!0,composed:!0,detail:{fileId:e}}))}_retryAll(){this.dispatchEvent(new CustomEvent("retry-all",{bubbles:!0,composed:!0}))}_close(){this.dispatchEvent(new CustomEvent("close-uploader",{bubbles:!0,composed:!0}))}render(){const e=this.thumbnails.slice(0,Ce),t=this.thumbnails.length-Ce,o=this.fileCount>0,r=this.failedFiles.length>0,i=r&&!o;return s.html`
1918
+ <button class="close-btn" title="Close" @click=${this._close}>
1919
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg>
1920
+ </button>
1901
1921
  <div class="card" role="status" aria-live="polite">
1902
- <div class="icon ${o?"error":r?"warning":""}">
1903
- ${o?s.html`<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
1922
+ <div class="icon ${i?"error":r?"warning":""}">
1923
+ ${i?s.html`<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
1904
1924
  <circle cx="12" cy="12" r="10"/><line x1="12" y1="8" x2="12" y2="12"/><line x1="12" y1="16" x2="12.01" y2="16"/>
1905
1925
  </svg>`:r?s.html`<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
1906
1926
  <path d="M10.29 3.86L1.82 18a2 2 0 001.71 3h16.94a2 2 0 001.71-3L13.71 3.86a2 2 0 00-3.42 0z"/><line x1="12" y1="9" x2="12" y2="13"/><line x1="12" y1="17" x2="12.01" y2="17"/>
@@ -1908,8 +1928,8 @@
1908
1928
  <polyline points="20 6 9 17 4 12" />
1909
1929
  </svg>`}
1910
1930
  </div>
1911
- <div class="title">${o?"Upload failed":r?"Partially uploaded":"Uploaded successfully!"}</div>
1912
- <div class="subtitle">${o?`${this.failedFiles.length===1?"File":"Files"} could not be uploaded`:r?`${this.fileCount} ${this.fileCount===1?"file":"files"} uploaded, ${this.failedFiles.length} failed`:"All files are ready for use"}</div>
1931
+ <div class="title">${i?"Upload failed":r?"Partially uploaded":"Uploaded successfully!"}</div>
1932
+ <div class="subtitle">${i?`${this.failedFiles.length===1?"File":"Files"} could not be uploaded`:r?`${this.fileCount} ${this.fileCount===1?"file":"files"} uploaded, ${this.failedFiles.length} failed`:"All files are ready for use"}</div>
1913
1933
 
1914
1934
  ${e.length>0?s.html`
1915
1935
  <div class="thumbs">
@@ -1918,7 +1938,7 @@
1918
1938
  </div>
1919
1939
  `:s.nothing}
1920
1940
 
1921
- ${i?s.html`<div class="summary">${this.fileCount} ${this.fileCount===1?"file":"files"} · ${R(this.totalSize)} uploaded</div>`:s.nothing}
1941
+ ${o?s.html`<div class="summary">${this.fileCount} ${this.fileCount===1?"file":"files"} · ${B(this.totalSize)} uploaded</div>`:s.nothing}
1922
1942
 
1923
1943
  ${r?s.html`
1924
1944
  <div class="failed-list">
@@ -1929,6 +1949,9 @@
1929
1949
  <div class="failed-name">${a.name}</div>
1930
1950
  <div class="failed-reason">${a.error}</div>
1931
1951
  </div>
1952
+ <button class="failed-retry" title="Retry" @click=${()=>this._retryFile(a.id)}>
1953
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 2v6h-6"/><path d="M3 12a9 9 0 0 1 15-6.7L21 8"/><path d="M3 22v-6h6"/><path d="M21 12a9 9 0 0 1-15 6.7L3 16"/></svg>
1954
+ </button>
1932
1955
  </div>
1933
1956
  `)}
1934
1957
  </div>
@@ -1936,6 +1959,7 @@
1936
1959
 
1937
1960
  <div class="actions">
1938
1961
  <button class="btn-ghost" @click=${this._uploadMore}>Upload more</button>
1962
+ ${r?s.html`<button class="btn-retry-all" @click=${this._retryAll}>Retry all (${this.failedFiles.length})</button>`:s.nothing}
1939
1963
  <button class="btn-primary" @click=${this._primaryAction}>${this.primaryLabel}</button>
1940
1964
  </div>
1941
1965
  </div>
@@ -1945,7 +1969,9 @@
1945
1969
  flex: 1;
1946
1970
  justify-content: center;
1947
1971
  align-items: center;
1948
- padding-bottom: 24px;
1972
+ padding: 24px 0;
1973
+ position: relative;
1974
+ overflow-y: auto;
1949
1975
  }
1950
1976
 
1951
1977
  .card {
@@ -2060,20 +2086,43 @@
2060
2086
  /* --- Failed files list --- */
2061
2087
  .failed-list {
2062
2088
  width: 100%;
2063
- max-width: 360px;
2089
+ max-width: 400px;
2090
+ max-height: 200px;
2064
2091
  margin-bottom: 20px;
2065
2092
  border-radius: 8px;
2066
2093
  border: 1px solid var(--sfx-up-border, #e8eaed);
2067
- overflow: hidden;
2094
+ overflow-y: auto;
2095
+ overflow-x: hidden;
2096
+ scrollbar-width: thin;
2097
+ scrollbar-color: rgba(0,0,0,0.15) transparent;
2098
+ }
2099
+
2100
+ .failed-list::-webkit-scrollbar {
2101
+ width: 6px;
2102
+ }
2103
+
2104
+ .failed-list::-webkit-scrollbar-track {
2105
+ background: transparent;
2106
+ margin: 6px 0;
2107
+ }
2108
+
2109
+ .failed-list::-webkit-scrollbar-thumb {
2110
+ background: rgba(0,0,0,0.15);
2111
+ border-radius: 3px;
2112
+ }
2113
+
2114
+ .failed-list::-webkit-scrollbar-thumb:hover {
2115
+ background: rgba(0,0,0,0.25);
2068
2116
  }
2069
2117
 
2070
2118
  .failed-item {
2071
2119
  display: flex;
2072
- align-items: flex-start;
2120
+ align-items: center;
2073
2121
  gap: 8px;
2074
2122
  padding: 8px 12px;
2075
- border-bottom: 1px solid var(--sfx-up-border, #f1f5f9);
2076
2123
  text-align: left;
2124
+ border-bottom: 1px solid var(--sfx-up-border, #f1f5f9);
2125
+ margin-right: 8px;
2077
2126
  }
2078
2127
 
2079
2128
  .failed-item:last-child {
@@ -2108,6 +2157,62 @@
2108
2157
  line-height: 1.4;
2109
2158
  }
2110
2159
 
2160
+ .failed-retry {
2161
+ width: 24px;
2162
+ height: 24px;
2163
+ border: none;
2164
+ background: none;
2165
+ color: var(--sfx-up-primary, #2563eb);
2166
+ cursor: pointer;
2167
+ padding: 4px;
2168
+ flex-shrink: 0;
2169
+ display: flex;
2170
+ align-items: center;
2171
+ justify-content: center;
2172
+ border-radius: 4px;
2173
+ margin-top: -2px;
2174
+ }
2175
+
2176
+ .failed-retry svg { width: 14px; height: 14px; }
2177
+
2178
+ .failed-retry:hover { background: var(--sfx-up-surface, #f8fafc); color: var(--sfx-up-primary-hover, #1d4ed8); }
2179
+
2180
+ .close-btn {
2181
+ position: absolute;
2182
+ top: 12px;
2183
+ right: 12px;
2184
+ width: 28px;
2185
+ height: 28px;
2186
+ border: none;
2187
+ background: none;
2188
+ color: var(--sfx-up-text-muted, #94a3b8);
2189
+ cursor: pointer;
2190
+ display: flex;
2191
+ align-items: center;
2192
+ justify-content: center;
2193
+ border-radius: 6px;
2194
+ padding: 0;
2195
+ }
2196
+
2197
+ .close-btn svg { width: 16px; height: 16px; }
2198
+
2199
+ .close-btn:hover { background: var(--sfx-up-surface, #f8fafc); color: var(--sfx-up-text, #1e293b); }
2200
+
2201
+ .btn-retry-all {
2202
+ padding: 8px 18px;
2203
+ border-radius: 8px;
2204
+ font-size: 13px;
2205
+ font-weight: 500;
2206
+ border: 1px solid var(--sfx-up-primary, #2563eb);
2207
+ background: #fff;
2208
+ color: var(--sfx-up-primary, #2563eb);
2209
+ cursor: pointer;
2210
+ }
2211
+
2212
+ .btn-retry-all:hover {
2213
+ background: var(--sfx-up-primary-bg, #eff6ff);
2214
+ }
2215
+
2111
2216
  @keyframes fadeUp {
2112
2217
  from {
2113
2218
  opacity: 0;
@@ -2137,7 +2242,7 @@
2137
2242
  .card { animation: none; }
2138
2243
  .icon { animation: none; }
2139
2244
  }
2140
- `];let O=he;W([p.property({type:Number})],O.prototype,"fileCount");W([p.property({type:Number})],O.prototype,"totalSize");W([p.property({type:Array})],O.prototype,"thumbnails");W([p.property({type:String})],O.prototype,"primaryLabel");W([p.property({type:Array})],O.prototype,"failedFiles");var nt=Object.defineProperty,L=(n,e,t,i)=>{for(var r=void 0,o=n.length-1,a;o>=0;o--)(a=n[o])&&(r=a(e,t,r)||r);return r&&nt(e,t,r),r};const ue=class ue extends s.LitElement{constructor(){super(...arguments),this.uploadState="idle",this.fileCount=0,this.totalSize=0,this.failedCount=0,this.showFillMetadata=!1,this.completedCount=0,this.uploadProgress=0}_clear(){this.dispatchEvent(new CustomEvent("clear-all",{bubbles:!0,composed:!0}))}_addMore(){this.dispatchEvent(new CustomEvent("add-more",{bubbles:!0,composed:!0}))}_fillMetadata(){this.dispatchEvent(new CustomEvent("fill-metadata",{bubbles:!0,composed:!0}))}_upload(){this.dispatchEvent(new CustomEvent("upload-start",{bubbles:!0,composed:!0}))}_retryAll(){this.dispatchEvent(new CustomEvent("retry-all",{bubbles:!0,composed:!0}))}render(){const e=this.uploadState==="uploading";return s.html`
2245
+ `];let F=he;W([c.property({type:Number})],F.prototype,"fileCount");W([c.property({type:Number})],F.prototype,"totalSize");W([c.property({type:Array})],F.prototype,"thumbnails");W([c.property({type:String})],F.prototype,"primaryLabel");W([c.property({type:Array})],F.prototype,"failedFiles");var nt=Object.defineProperty,R=(n,e,t,o)=>{for(var r=void 0,i=n.length-1,a;i>=0;i--)(a=n[i])&&(r=a(e,t,r)||r);return r&&nt(e,t,r),r};const ue=class ue extends s.LitElement{constructor(){super(...arguments),this.uploadState="idle",this.fileCount=0,this.totalSize=0,this.failedCount=0,this.showFillMetadata=!1,this.completedCount=0,this.uploadProgress=0}_clear(){this.dispatchEvent(new CustomEvent("clear-all",{bubbles:!0,composed:!0}))}_addMore(){this.dispatchEvent(new CustomEvent("add-more",{bubbles:!0,composed:!0}))}_fillMetadata(){this.dispatchEvent(new CustomEvent("fill-metadata",{bubbles:!0,composed:!0}))}_upload(){this.dispatchEvent(new CustomEvent("upload-start",{bubbles:!0,composed:!0}))}_retryAll(){this.dispatchEvent(new CustomEvent("retry-all",{bubbles:!0,composed:!0}))}render(){const e=this.uploadState==="uploading";return s.html`
2141
2246
  ${e?s.html`
2142
2247
  <div class="progress-row">
2143
2248
  <div class="progress-track" role="progressbar" aria-valuenow=${Math.round(this.uploadProgress)} aria-valuemin="0" aria-valuemax="100" aria-label="Upload progress">
@@ -2191,9 +2296,9 @@
2191
2296
  ${this._renderUploadButton()}
2192
2297
  </div>
2193
2298
  </div>
2194
- `}_renderUploadButton(){const e=this.uploadState==="uploading",t=this.uploadState==="done",i=["btn-primary",t?"done-state":""].filter(Boolean).join(" ");return s.html`
2299
+ `}_renderUploadButton(){const e=this.uploadState==="uploading",t=this.uploadState==="done",o=["btn-primary",t?"done-state":""].filter(Boolean).join(" ");return s.html`
2195
2300
  <button
2196
- class=${i}
2301
+ class=${o}
2197
2302
  @click=${this._upload}
2198
2303
  ?disabled=${e}
2199
2304
  >
@@ -2359,7 +2464,7 @@
2359
2464
  :host { animation: none; }
2360
2465
  .btn-spin { animation: none; }
2361
2466
  }
2362
- `];let z=ue;L([p.property({type:String})],z.prototype,"uploadState");L([p.property({type:Number})],z.prototype,"fileCount");L([p.property({type:Number})],z.prototype,"totalSize");L([p.property({type:Number})],z.prototype,"failedCount");L([p.property({type:Boolean})],z.prototype,"showFillMetadata");L([p.property({type:Number})],z.prototype,"completedCount");L([p.property({type:Number})],z.prototype,"uploadProgress");const lt='button:not([disabled]), [href], input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"])';function ae(n,e){return t=>{if(t.key!=="Tab")return;const i=n();if(!i)return;const r=i.querySelector(e);if(!r)return;const o=Array.from(r.querySelectorAll(lt));if(o.length===0)return;const a=o[0],l=o[o.length-1],d=i.activeElement;t.shiftKey?(d===a||!r.contains(d))&&(t.preventDefault(),l.focus()):(d===l||!r.contains(d))&&(t.preventDefault(),a.focus())}}var dt=Object.defineProperty,ne=(n,e,t,i)=>{for(var r=void 0,o=n.length-1,a;o>=0;o--)(a=n[o])&&(r=a(e,t,r)||r);return r&&dt(e,t,r),r};const xe=class xe extends s.LitElement{constructor(){super(...arguments),this._url="",this._name="",this._error="",this._onBackdropClick=e=>{e.target===e.currentTarget&&this._cancel()},this._onUrlInput=e=>{this._url=e.target.value,this._error="",this._autoName()},this._onNameInput=e=>{this._name=e.target.value},this._focusTrap=ae(()=>this.shadowRoot,".card"),this._onKeyDown=e=>{var t;e.key==="Escape"&&this._cancel(),e.key==="Enter"&&((t=e.target)==null?void 0:t.tagName)==="INPUT"&&this._submit(),this._focusTrap(e)}}_autoName(){var e;if(!this._name)try{const t=new URL(this._url).pathname.split("/"),i=t[t.length-1];if(i){const r=(e=this.shadowRoot)==null?void 0:e.querySelector("#nameInput");r&&(r.placeholder=i)}}catch{}}_cancel(){this.dispatchEvent(new CustomEvent("url-cancel",{bubbles:!0,composed:!0}))}_submit(){const e=this._url.trim();if(!e){this._error="Please enter a URL";return}try{new URL(e)}catch{this._error="Please enter a valid URL";return}this._error="";let t=this._name.trim();if(!t)try{const i=new URL(e).pathname.split("/");t=i[i.length-1]||"imported-file"}catch{t="imported-file"}this.dispatchEvent(new CustomEvent("url-submit",{detail:{url:e,name:t},bubbles:!0,composed:!0}))}connectedCallback(){super.connectedCallback(),this.updateComplete.then(()=>{var e,t;(t=(e=this.shadowRoot)==null?void 0:e.querySelector("#urlInput"))==null||t.focus()})}render(){return s.html`
2467
+ `];let P=ue;R([c.property({type:String})],P.prototype,"uploadState");R([c.property({type:Number})],P.prototype,"fileCount");R([c.property({type:Number})],P.prototype,"totalSize");R([c.property({type:Number})],P.prototype,"failedCount");R([c.property({type:Boolean})],P.prototype,"showFillMetadata");R([c.property({type:Number})],P.prototype,"completedCount");R([c.property({type:Number})],P.prototype,"uploadProgress");const lt='button:not([disabled]), [href], input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"])';function ae(n,e){return t=>{if(t.key!=="Tab")return;const o=n();if(!o)return;const r=o.querySelector(e);if(!r)return;const i=Array.from(r.querySelectorAll(lt));if(i.length===0)return;const a=i[0],l=i[i.length-1],d=o.activeElement;t.shiftKey?(d===a||!r.contains(d))&&(t.preventDefault(),l.focus()):(d===l||!r.contains(d))&&(t.preventDefault(),a.focus())}}var dt=Object.defineProperty,ne=(n,e,t,o)=>{for(var r=void 0,i=n.length-1,a;i>=0;i--)(a=n[i])&&(r=a(e,t,r)||r);return r&&dt(e,t,r),r};const xe=class xe extends s.LitElement{constructor(){super(...arguments),this._url="",this._name="",this._error="",this._onBackdropClick=e=>{e.target===e.currentTarget&&this._cancel()},this._onUrlInput=e=>{this._url=e.target.value,this._error="",this._autoName()},this._onNameInput=e=>{this._name=e.target.value},this._focusTrap=ae(()=>this.shadowRoot,".card"),this._onKeyDown=e=>{var t;e.key==="Escape"&&this._cancel(),e.key==="Enter"&&((t=e.target)==null?void 0:t.tagName)==="INPUT"&&this._submit(),this._focusTrap(e)}}_autoName(){var e;if(!this._name)try{const t=new URL(this._url).pathname.split("/"),o=t[t.length-1];if(o){const r=(e=this.shadowRoot)==null?void 0:e.querySelector("#nameInput");r&&(r.placeholder=o)}}catch{}}_cancel(){this.dispatchEvent(new CustomEvent("url-cancel",{bubbles:!0,composed:!0}))}_submit(){const e=this._url.trim();if(!e){this._error="Please enter a URL";return}try{new URL(e)}catch{this._error="Please enter a valid URL";return}this._error="";let t=this._name.trim();if(!t)try{const o=new URL(e).pathname.split("/");t=o[o.length-1]||"imported-file"}catch{t="imported-file"}this.dispatchEvent(new CustomEvent("url-submit",{detail:{url:e,name:t},bubbles:!0,composed:!0}))}connectedCallback(){super.connectedCallback(),this.updateComplete.then(()=>{var e,t;(t=(e=this.shadowRoot)==null?void 0:e.querySelector("#urlInput"))==null||t.focus()})}render(){return s.html`
2363
2468
  <div class="backdrop" @click=${this._onBackdropClick} @keydown=${this._onKeyDown}>
2364
2469
  <div class="card">
2365
2470
  <div class="head">
@@ -2576,7 +2681,7 @@
2576
2681
  outline: none;
2577
2682
  }
2578
2683
 
2579
- `];let I=xe;ne([p.state()],I.prototype,"_url");ne([p.state()],I.prototype,"_name");ne([p.state()],I.prototype,"_error");var ct=Object.defineProperty,re=(n,e,t,i)=>{for(var r=void 0,o=n.length-1,a;o>=0;o--)(a=n[o])&&(r=a(e,t,r)||r);return r&&ct(e,t,r),r};const ge=class ge extends s.LitElement{constructor(){super(...arguments),this._stream=null,this._error="",this._captured=null,this._previewUrl="",this._onBackdropClick=e=>{e.target===e.currentTarget&&this._cancel()},this._focusTrap=ae(()=>this.shadowRoot,".card"),this._onKeyDown=e=>{e.key==="Escape"&&this._cancel(),this._focusTrap(e)},this._capture=()=>{var r,o;const e=(r=this.shadowRoot)==null?void 0:r.querySelector("video"),t=(o=this.shadowRoot)==null?void 0:o.querySelector("canvas");if(!e||!t)return;t.width=e.videoWidth,t.height=e.videoHeight,t.getContext("2d").drawImage(e,0,0),t.toBlob(a=>{a&&(this._captured=a,this._previewUrl=URL.createObjectURL(a),this._stopStream())},"image/jpeg",.92)},this._retake=()=>{this._previewUrl&&URL.revokeObjectURL(this._previewUrl),this._captured=null,this._previewUrl="",this._startCamera()},this._usePhoto=()=>{if(!this._captured)return;const e=new Date().toISOString().replace(/[:.]/g,"-").slice(0,19),t=new File([this._captured],`camera-${e}.jpg`,{type:"image/jpeg"});this.dispatchEvent(new CustomEvent("camera-capture",{detail:{file:t},bubbles:!0,composed:!0}))}}connectedCallback(){super.connectedCallback(),this._startCamera()}disconnectedCallback(){super.disconnectedCallback(),this._stopStream(),this._previewUrl&&URL.revokeObjectURL(this._previewUrl)}async _startCamera(){var e;try{this._stream=await navigator.mediaDevices.getUserMedia({video:!0,audio:!1}),await this.updateComplete;const t=(e=this.shadowRoot)==null?void 0:e.querySelector("video");t&&(t.srcObject=this._stream)}catch{this._error="Could not access camera. Please check your permissions."}}_stopStream(){var e;(e=this._stream)==null||e.getTracks().forEach(t=>t.stop()),this._stream=null}_cancel(){this._stopStream(),this.dispatchEvent(new CustomEvent("camera-cancel",{bubbles:!0,composed:!0}))}render(){return s.html`
2684
+ `];let I=xe;ne([c.state()],I.prototype,"_url");ne([c.state()],I.prototype,"_name");ne([c.state()],I.prototype,"_error");var pt=Object.defineProperty,re=(n,e,t,o)=>{for(var r=void 0,i=n.length-1,a;i>=0;i--)(a=n[i])&&(r=a(e,t,r)||r);return r&&pt(e,t,r),r};const ge=class ge extends s.LitElement{constructor(){super(...arguments),this._stream=null,this._error="",this._captured=null,this._previewUrl="",this._onBackdropClick=e=>{e.target===e.currentTarget&&this._cancel()},this._focusTrap=ae(()=>this.shadowRoot,".card"),this._onKeyDown=e=>{e.key==="Escape"&&this._cancel(),this._focusTrap(e)},this._capture=()=>{var r,i;const e=(r=this.shadowRoot)==null?void 0:r.querySelector("video"),t=(i=this.shadowRoot)==null?void 0:i.querySelector("canvas");if(!e||!t)return;t.width=e.videoWidth,t.height=e.videoHeight,t.getContext("2d").drawImage(e,0,0),t.toBlob(a=>{a&&(this._captured=a,this._previewUrl=URL.createObjectURL(a),this._stopStream())},"image/jpeg",.92)},this._retake=()=>{this._previewUrl&&URL.revokeObjectURL(this._previewUrl),this._captured=null,this._previewUrl="",this._startCamera()},this._usePhoto=()=>{if(!this._captured)return;const e=new Date().toISOString().replace(/[:.]/g,"-").slice(0,19),t=new File([this._captured],`camera-${e}.jpg`,{type:"image/jpeg"});this.dispatchEvent(new CustomEvent("camera-capture",{detail:{file:t},bubbles:!0,composed:!0}))}}connectedCallback(){super.connectedCallback(),this._startCamera()}disconnectedCallback(){super.disconnectedCallback(),this._stopStream(),this._previewUrl&&URL.revokeObjectURL(this._previewUrl)}async _startCamera(){var e;try{this._stream=await navigator.mediaDevices.getUserMedia({video:!0,audio:!1}),await this.updateComplete;const t=(e=this.shadowRoot)==null?void 0:e.querySelector("video");t&&(t.srcObject=this._stream)}catch{this._error="Could not access camera. Please check your permissions."}}_stopStream(){var e;(e=this._stream)==null||e.getTracks().forEach(t=>t.stop()),this._stream=null}_cancel(){this._stopStream(),this.dispatchEvent(new CustomEvent("camera-cancel",{bubbles:!0,composed:!0}))}render(){return s.html`
2580
2685
  <div class="backdrop" @click=${this._onBackdropClick} @keydown=${this._onKeyDown}>
2581
2686
  <div class="card">
2582
2687
  <div class="head">
@@ -2686,7 +2791,7 @@
2686
2791
 
2687
2792
  @keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }
2688
2793
  @keyframes slideUp { from { transform: translateY(18px) scale(0.97); } to { transform: translateY(0) scale(1); } }
2689
- `];let j=ge;re([p.state()],j.prototype,"_stream");re([p.state()],j.prototype,"_error");re([p.state()],j.prototype,"_captured");re([p.state()],j.prototype,"_previewUrl");var pt=Object.defineProperty,G=(n,e,t,i)=>{for(var r=void 0,o=n.length-1,a;o>=0;o--)(a=n[o])&&(r=a(e,t,r)||r);return r&&pt(e,t,r),r};const ve=class ve extends s.LitElement{constructor(){super(...arguments),this._stream=null,this._recording=!1,this._error="",this._recordedBlob=null,this._previewUrl="",this._recorder=null,this._chunks=[],this._onBackdropClick=e=>{e.target===e.currentTarget&&this._cancel()},this._focusTrap=ae(()=>this.shadowRoot,".card"),this._onKeyDown=e=>{e.key==="Escape"&&this._cancel(),this._focusTrap(e)},this._startRecording=async()=>{var e;try{this._stream=await navigator.mediaDevices.getDisplayMedia({video:{width:1280,height:720,frameRate:5},audio:!0}),this._stream.getVideoTracks()[0].addEventListener("ended",()=>{this._stopRecording()}),this._recording=!0,await this.updateComplete;const t=(e=this.shadowRoot)==null?void 0:e.querySelector("video");t&&(t.srcObject=this._stream),this._chunks=[];const i=MediaRecorder.isTypeSupported("video/webm;codecs=vp9")?"video/webm;codecs=vp9":"video/webm";this._recorder=new MediaRecorder(this._stream,{mimeType:i}),this._recorder.ondataavailable=r=>{r.data.size>0&&this._chunks.push(r.data)},this._recorder.onstop=()=>{var o;const r=new Blob(this._chunks,{type:"video/webm"});this._recordedBlob=r,this._previewUrl=URL.createObjectURL(r),(o=this._stream)==null||o.getTracks().forEach(a=>a.stop()),this._stream=null},this._recorder.start()}catch{this._error="Could not start screen capture. Please check your permissions."}},this._stopRecording=()=>{var e;this._recording=!1,((e=this._recorder)==null?void 0:e.state)==="recording"&&this._recorder.stop(),this._recorder=null},this._useRecording=()=>{if(!this._recordedBlob)return;const e=new Date().toISOString().replace(/[:.]/g,"-").slice(0,19),t=new File([this._recordedBlob],`screencap-${e}.webm`,{type:"video/webm"});this.dispatchEvent(new CustomEvent("screencast-capture",{detail:{file:t},bubbles:!0,composed:!0}))},this._discard=()=>{this._previewUrl&&URL.revokeObjectURL(this._previewUrl),this._recordedBlob=null,this._previewUrl=""}}disconnectedCallback(){super.disconnectedCallback(),this._stopAll(),this._previewUrl&&URL.revokeObjectURL(this._previewUrl)}_stopAll(){var e,t;(e=this._recorder)==null||e.stop(),this._recorder=null,(t=this._stream)==null||t.getTracks().forEach(i=>i.stop()),this._stream=null}_cancel(){this._stopAll(),this.dispatchEvent(new CustomEvent("screencast-cancel",{bubbles:!0,composed:!0}))}render(){return s.html`
2794
+ `];let M=ge;re([c.state()],M.prototype,"_stream");re([c.state()],M.prototype,"_error");re([c.state()],M.prototype,"_captured");re([c.state()],M.prototype,"_previewUrl");var ct=Object.defineProperty,G=(n,e,t,o)=>{for(var r=void 0,i=n.length-1,a;i>=0;i--)(a=n[i])&&(r=a(e,t,r)||r);return r&&ct(e,t,r),r};const ve=class ve extends s.LitElement{constructor(){super(...arguments),this._stream=null,this._recording=!1,this._error="",this._recordedBlob=null,this._previewUrl="",this._recorder=null,this._chunks=[],this._onBackdropClick=e=>{e.target===e.currentTarget&&this._cancel()},this._focusTrap=ae(()=>this.shadowRoot,".card"),this._onKeyDown=e=>{e.key==="Escape"&&this._cancel(),this._focusTrap(e)},this._startRecording=async()=>{var e;try{this._stream=await navigator.mediaDevices.getDisplayMedia({video:{width:1280,height:720,frameRate:5},audio:!0}),this._stream.getVideoTracks()[0].addEventListener("ended",()=>{this._stopRecording()}),this._recording=!0,await this.updateComplete;const t=(e=this.shadowRoot)==null?void 0:e.querySelector("video");t&&(t.srcObject=this._stream),this._chunks=[];const o=MediaRecorder.isTypeSupported("video/webm;codecs=vp9")?"video/webm;codecs=vp9":"video/webm";this._recorder=new MediaRecorder(this._stream,{mimeType:o}),this._recorder.ondataavailable=r=>{r.data.size>0&&this._chunks.push(r.data)},this._recorder.onstop=()=>{var i;const r=new Blob(this._chunks,{type:"video/webm"});this._recordedBlob=r,this._previewUrl=URL.createObjectURL(r),(i=this._stream)==null||i.getTracks().forEach(a=>a.stop()),this._stream=null},this._recorder.start()}catch{this._error="Could not start screen capture. Please check your permissions."}},this._stopRecording=()=>{var e;this._recording=!1,((e=this._recorder)==null?void 0:e.state)==="recording"&&this._recorder.stop(),this._recorder=null},this._useRecording=()=>{if(!this._recordedBlob)return;const e=new Date().toISOString().replace(/[:.]/g,"-").slice(0,19),t=new File([this._recordedBlob],`screencap-${e}.webm`,{type:"video/webm"});this.dispatchEvent(new CustomEvent("screencast-capture",{detail:{file:t},bubbles:!0,composed:!0}))},this._discard=()=>{this._previewUrl&&URL.revokeObjectURL(this._previewUrl),this._recordedBlob=null,this._previewUrl=""}}disconnectedCallback(){super.disconnectedCallback(),this._stopAll(),this._previewUrl&&URL.revokeObjectURL(this._previewUrl)}_stopAll(){var e,t;(e=this._recorder)==null||e.stop(),this._recorder=null,(t=this._stream)==null||t.getTracks().forEach(o=>o.stop()),this._stream=null}_cancel(){this._stopAll(),this.dispatchEvent(new CustomEvent("screencast-cancel",{bubbles:!0,composed:!0}))}render(){return s.html`
2690
2795
  <div class="backdrop" @click=${this._onBackdropClick} @keydown=${this._onKeyDown}>
2691
2796
  <div class="card">
2692
2797
  <div class="head">
@@ -2830,14 +2935,15 @@
2830
2935
  @keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }
2831
2936
  @keyframes slideUp { from { transform: translateY(18px) scale(0.97); } to { transform: translateY(0) scale(1); } }
2832
2937
  @keyframes pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.3; } }
2833
- `];let T=ve;G([p.state()],T.prototype,"_stream");G([p.state()],T.prototype,"_recording");G([p.state()],T.prototype,"_error");G([p.state()],T.prototype,"_recordedBlob");G([p.state()],T.prototype,"_previewUrl");var ft=Object.defineProperty,k=(n,e,t,i)=>{for(var r=void 0,o=n.length-1,a;o>=0;o--)(a=n[o])&&(r=a(e,t,r)||r);return r&&ft(e,t,r),r};const $e=new Set(["unsplash"]);var $;const _=($=class extends s.LitElement{constructor(){super(),this.config=null,this._isOpen=!1,this._activeConnector=null,this._showUrlDialog=!1,this._showCameraDialog=!1,this._showScreenCastDialog=!1,this._previewFileId=null,this._previewDims="—",this._fullscreenPreviewUrl=null,this._fullscreenVideoFile=null,this._fullscreenZoomed=!1,this._fsPanX=0,this._fsPanY=0,this._fsDragging=!1,this._fsDragStartX=0,this._fsDragStartY=0,this._fsPanStartX=0,this._fsPanStartY=0,this._bodyDragOver=!1,this._isMinimized=!1,this._isPillExpanded=!1,this._bodyDragCounter=0,this._videoBlobUrls=new Map,this._engine=null,this._cachedSources=A,this._cachedSourcesConfig=void 0,this._rejectedTimers=new Map,this._closeOnCompleteTimer=null,this._apiBase=null,this._authHeaders=null,this._authResolveId=0,this._prevStoreState=null,this._unsubStoreEvents=null,this._portalContainer=null,this._onFilesSelected=e=>{this._processIncomingFiles(e.detail.files)},this._onDropTileSourceClick=e=>{this._handleSourceActivation(e.detail.source.id)},this._onSourceClick=async e=>{this._handleSourceActivation(e.detail.source)},this._handleSourceActivation=async e=>{var r,o;const t=this._mergedSources.find(a=>a.id===e);if(t!=null&&t.onActivate){try{t.onActivate(this)}catch(a){console.error(`[sfx-uploader] onActivate for custom source "${e}" threw:`,a)}return}if(e==="device"){const a=this.shadowRoot.querySelector("sfx-drop-zone");a==null||a.browse();return}if(e==="url"){this._showUrlDialog=!0;return}if(e==="camera"){this._showCameraDialog=!0;return}if(e==="screen-cast"){this._showScreenCastDialog=!0;return}if((((o=(r=this.config)==null?void 0:r.connectors)==null?void 0:o.providers)??[]).includes(e)){if($e.has(e)){if(!customElements.get("sfx-search-provider-browser")){const{SfxSearchProviderBrowser:l}=await Promise.resolve().then(()=>require("./search-provider-browser-KQs6JI8u.cjs"));customElements.define("sfx-search-provider-browser",l)}}else if(!customElements.get("sfx-provider-browser")){const{SfxProviderBrowser:l}=await Promise.resolve().then(()=>require("./provider-browser-DbjyF_Ou.cjs"));customElements.define("sfx-provider-browser",l)}this._activeConnector=e}},this._onUrlSubmit=e=>{var h,x,u;this._showUrlDialog=!1;const{url:t,name:i}=e.detail,r=(h=this.config)==null?void 0:h.callbacks,o=Xe(i),a=o.startsWith("image/"),l=this._store.getState(),d=oe({name:i,size:0,type:o},l.restrictions,l.files);if(d){const f={id:B(),status:"rejected",file:null,remoteUrl:t,name:i,size:0,type:o,previewUrl:null,duration:null,progress:0,speed:0,bytesUploaded:0,error:d,retryCount:0,response:null,addedAt:Date.now(),meta:{},tags:[],remoteInfo:null};M(this._store,f),this._dispatchPublic(g.FILE_REJECTED,{file:f,reason:d}),(x=r==null?void 0:r.onFileRejected)==null||x.call(r,f,d);return}const c={id:B(),status:"idle",file:null,remoteUrl:t,name:i,size:0,type:o,previewUrl:a?t:null,duration:null,progress:0,speed:0,bytesUploaded:0,error:null,retryCount:0,response:null,addedAt:Date.now(),meta:{},tags:[],remoteInfo:null};M(this._store,c),this._dispatchPublic(g.FILE_ADDED,{file:c}),(u=r==null?void 0:r.onFileAdded)==null||u.call(r,c),this._store.getState().queueConfig.autoProceed&&this.upload()},this._onUrlCancel=()=>{this._showUrlDialog=!1},this._onCameraCapture=e=>{this._showCameraDialog=!1,this._processIncomingFiles([e.detail.file])},this._onCameraCancel=()=>{this._showCameraDialog=!1},this._onScreenCastCapture=e=>{this._showScreenCastDialog=!1,this._processIncomingFiles([e.detail.file])},this._onScreenCastCancel=()=>{this._showScreenCastDialog=!1},this._onFileRemove=e=>{this._removeFile(e.detail.fileId)},this._onFilePreview=e=>{var i,r,o;const t=this._store.getState().files.get(e.detail.fileId);t&&(this._previewFileId=t.id,this._dispatchPublic(g.FILE_PREVIEW,{file:t}),(o=(r=(i=this.config)==null?void 0:i.callbacks)==null?void 0:r.onFilePreview)==null||o.call(r,t))},this._onFillMetadata=()=>{var t,i,r;const e=[...this._store.getState().files.values()].filter(o=>$._MODIFIABLE_STATUSES.has(o.status));this._dispatchPublic(g.FILL_METADATA,{files:e}),(r=(i=(t=this.config)==null?void 0:t.callbacks)==null?void 0:i.onFillMetadata)==null||r.call(i,e)},this._onFileRetry=e=>{var t;this._ensureEngine(),(t=this._engine)==null||t.retryFile(e.detail.fileId)},this._onRetryAll=()=>{var e;this._ensureEngine(),(e=this._engine)==null||e.retryAll()},this._onClearAll=()=>{var i,r,o;const e=(i=this.config)==null?void 0:i.callbacks;this._closeOnCompleteTimer&&(clearTimeout(this._closeOnCompleteTimer),this._closeOnCompleteTimer=null),(r=this._engine)==null||r.cancelAll();const t=[...this._store.getState().files.values()];for(const a of t)a.previewUrl&&URL.revokeObjectURL(a.previewUrl),this._dispatchPublic(g.FILE_REMOVED,{file:a}),(o=e==null?void 0:e.onFileRemoved)==null||o.call(e,a);this._revokeVideoBlobUrls();for(const a of this._rejectedTimers.values())clearTimeout(a);this._rejectedTimers.clear(),this._dimCache.clear(),this._previewFileId=null,this._fullscreenPreviewUrl=null,this._fullscreenVideoFile=null,this._store.setState({files:new Map,isUploading:!1,totalProgress:0,totalSpeed:0,totalBytesUploaded:0,totalBytes:0})},this._onAddMore=()=>{var r;const e=this.shadowRoot.querySelector("sfx-drop-zone");if(e){e.browse();return}const t=this.shadowRoot.querySelector("sfx-file-list"),i=(r=t==null?void 0:t.shadowRoot)==null?void 0:r.querySelector('input[type="file"]');i==null||i.click()},this._onUploadStart=()=>{var e;if(this._phase==="complete"){((e=this.config)==null?void 0:e.clearOnComplete)!==!1&&this._onClearAll();return}this.upload()},this._onUploadMore=()=>{this._onClearAll()},this._onConnectorFilesSelected=e=>{var i,r,o;const t=(i=this.config)==null?void 0:i.callbacks;for(const a of e.detail.files){const l=this._store.getState(),d=oe({name:a.name,size:a.size,type:a.mimeType},l.restrictions,l.files);if(d){const h={id:B(),status:"rejected",file:null,remoteUrl:null,name:a.name,size:a.size,type:a.mimeType,previewUrl:a.thumbnail,duration:null,progress:0,speed:0,bytesUploaded:0,error:d,retryCount:0,response:null,addedAt:Date.now(),meta:{},tags:[],remoteInfo:a};M(this._store,h),this._dispatchPublic(g.FILE_REJECTED,{file:h,reason:d}),(r=t==null?void 0:t.onFileRejected)==null||r.call(t,h,d);continue}const c={id:B(),status:"idle",file:null,remoteUrl:null,name:a.name,size:a.size,type:a.mimeType,previewUrl:a.thumbnail,duration:null,progress:0,speed:0,bytesUploaded:0,error:null,retryCount:0,response:null,addedAt:Date.now(),meta:{},tags:[],remoteInfo:a};M(this._store,c),this._dispatchPublic(g.FILE_ADDED,{file:c}),(o=t==null?void 0:t.onFileAdded)==null||o.call(t,c)}this._activeConnector=null,this._store.getState().queueConfig.autoProceed&&this.upload()},this._onConnectorClose=()=>{this._activeConnector=null},this._onConnectorBackdropClick=e=>{e.target===e.currentTarget&&(this._activeConnector=null)},this._onPrimaryAction=()=>{var e,t,i,r,o;this._dispatchPublic(g.COMPLETE_ACTION,{}),(i=(t=(e=this.config)==null?void 0:e.callbacks)==null?void 0:t.onCompleteAction)==null||i.call(t),((r=this.config)==null?void 0:r.mode)==="modal"?this.close():((o=this.config)==null?void 0:o.clearOnComplete)!==!1&&this._onClearAll()},this._onInlineDismiss=()=>{var e,t,i;(i=(t=(e=this.config)==null?void 0:e.callbacks)==null?void 0:t.onCancel)==null||i.call(t),this._dispatchPublic(g.CANCEL,{})},this._onModalDismiss=()=>{var e,t,i;(i=(t=(e=this.config)==null?void 0:e.callbacks)==null?void 0:t.onCancel)==null||i.call(t),this._dispatchPublic(g.CANCEL,{}),this.close()},this._onMinimize=()=>{this._isMinimized=!0,this._isPillExpanded=!0,this.requestUpdate()},this._onPillClick=()=>{this._isPillExpanded=!this._isPillExpanded,this.requestUpdate()},this._onPillDismiss=()=>{this._isMinimized=!1,this._isPillExpanded=!1,this._isOpen=!0,this.requestUpdate()},this._onModalBackdropClick=e=>{e.target===e.currentTarget&&this._onModalDismiss()},this._onBodyDragEnter=e=>{e.preventDefault(),this._bodyDragCounter++,this._bodyDragCounter===1&&(this._bodyDragOver=!0)},this._onBodyDragOver=e=>{e.preventDefault()},this._onBodyDragLeave=e=>{e.preventDefault(),this._bodyDragCounter--,this._bodyDragCounter<=0&&(this._bodyDragCounter=0,this._bodyDragOver=!1)},this._onBodyDrop=e=>{var i;e.preventDefault(),this._bodyDragCounter=0,this._bodyDragOver=!1;const t=Array.from(((i=e.dataTransfer)==null?void 0:i.files)??[]);t.length>0&&this._onFilesSelected(new CustomEvent("files-selected",{detail:{files:t}}))},this._onKeyDown=e=>{var t,i;if(e.key==="Escape"){if(this._fullscreenPreviewUrl||this._fullscreenVideoFile){this._onFsClose();return}this._isOpen&&((t=this.config)==null?void 0:t.mode)==="modal"&&(((i=this.config)==null?void 0:i.headerButton)??"close")!=="none"&&this._onModalDismiss()}},this._dimCache=new Map,this._onFsToggleZoom=e=>{e==null||e.stopPropagation(),this._fullscreenZoomed=!this._fullscreenZoomed,this._fullscreenZoomed||(this._fsPanX=0,this._fsPanY=0)},this._onFsOverlayClick=e=>{this._fsDragDidMove||this._onFsToggleZoom(e)},this._fsDragDidMove=!1,this._onFsPanStart=e=>{this._fullscreenZoomed&&(this._fsDragging=!0,this._fsDragDidMove=!1,this._fsDragStartX=e.clientX,this._fsDragStartY=e.clientY,this._fsPanStartX=this._fsPanX,this._fsPanStartY=this._fsPanY,e.preventDefault())},this._onFsPanMove=e=>{if(!this._fsDragging)return;const t=e.clientX-this._fsDragStartX,i=e.clientY-this._fsDragStartY;(Math.abs(t)>3||Math.abs(i)>3)&&(this._fsDragDidMove=!0),this._fsPanX=this._fsPanStartX+t,this._fsPanY=this._fsPanStartY+i,this.requestUpdate()},this._onFsPanEnd=()=>{this._fsDragging=!1,requestAnimationFrame(()=>{this._fsDragDidMove=!1})},this._onFsTouchStart=e=>{if(!this._fullscreenZoomed||e.touches.length!==1)return;const t=e.touches[0];this._fsDragging=!0,this._fsDragDidMove=!1,this._fsDragStartX=t.clientX,this._fsDragStartY=t.clientY,this._fsPanStartX=this._fsPanX,this._fsPanStartY=this._fsPanY},this._onFsTouchMove=e=>{if(!this._fsDragging||e.touches.length!==1)return;const t=e.touches[0],i=t.clientX-this._fsDragStartX,r=t.clientY-this._fsDragStartY;(Math.abs(i)>3||Math.abs(r)>3)&&(this._fsDragDidMove=!0),this._fsPanX=this._fsPanStartX+i,this._fsPanY=this._fsPanStartY+r,this.requestUpdate(),e.preventDefault()},this._onFsClose=e=>{e==null||e.stopPropagation(),this._fullscreenPreviewUrl=null,this._fullscreenVideoFile=null,this._fullscreenZoomed=!1,this._fsPanX=0,this._fsPanY=0},this._store=Ee(),this._storeCtrl=new Fe(this,this._store)}open(){var e,t,i;this._isMinimized&&(this._isMinimized=!1,this._isPillExpanded=!1),!this._isOpen&&(this._isOpen=!0,(i=(t=(e=this.config)==null?void 0:e.callbacks)==null?void 0:t.onOpen)==null||i.call(t),this._dispatchPublic(g.OPEN,{}),this.requestUpdate())}close(){var e,t,i,r;this._isOpen&&(this._isOpen=!1,this._closeOnCompleteTimer&&(clearTimeout(this._closeOnCompleteTimer),this._closeOnCompleteTimer=null),((e=this.config)==null?void 0:e.clearOnClose)!==!1&&this._onClearAll(),this._previewFileId=null,(r=(i=(t=this.config)==null?void 0:t.callbacks)==null?void 0:i.onClose)==null||r.call(i),this._dispatchPublic(g.CLOSE,{}),this.requestUpdate())}upload(){var r,o,a,l,d;if(this._ensureEngine(),!this._engine){console.warn("[sfx-uploader] Cannot upload: auth not resolved yet");return}const e=[...this._store.getState().files.values()].filter(c=>c.status==="idle"||c.status==="queued");if((o=(r=this.config)==null?void 0:r.callbacks)!=null&&o.onBeforeUpload&&this.config.callbacks.onBeforeUpload(e)===!1)return;const t=new CustomEvent(g.BEFORE_UPLOAD,{bubbles:!0,composed:!0,cancelable:!0,detail:{files:e}});this.dispatchEvent(t)&&(this._dispatchPublic(g.UPLOAD_STARTED,{files:e}),(d=(l=(a=this.config)==null?void 0:a.callbacks)==null?void 0:l.onUploadStarted)==null||d.call(l,e),this._engine.uploadAll())}addFiles(e){this._processIncomingFiles(e)}resumeUpload(e){var t;if(e&&e.length>0){const i=this._store.getState().files,r=new Map(i);let o=!1;for(const a of e){const l=i.get(a.id);l&&(r.set(a.id,{...l,...a}),o=!0)}o&&this._store.setState({files:r})}this._ensureEngine(),(t=this._engine)==null||t.uploadAll()}cancelUpload(){var e;(e=this._engine)==null||e.cancelAll()}getFiles(){return[...this._store.getState().files.values()]}getFile(e){return this._store.getState().files.get(e)}updateFileMeta(e,t,i){const r=this._store.getState().files,o=r.get(e);if(!o||!$._MODIFIABLE_STATUSES.has(o.status))return;const a=new Map(r);a.set(e,{...o,meta:t!=null?{...o.meta,...t}:o.meta,tags:i??o.tags}),this._store.setState({files:a})}updateFilesMeta(e){const t=this._store.getState().files,i=new Map(t);let r=!1;for(const{fileId:o,meta:a,tags:l}of e){const d=t.get(o);!d||!$._MODIFIABLE_STATUSES.has(d.status)||(i.set(o,{...d,meta:a!=null?{...d.meta,...a}:d.meta,tags:l??d.tags}),r=!0)}r&&this._store.setState({files:i})}updated(e){if(e.has("config")&&this.config&&this._applyConfig(this.config),e.has("_previewFileId")&&this._previewFileId){const t=this._previewFileId,i=this._store.getState().files.get(t);i?this._getImageDimensions(i).then(r=>{this._previewFileId===t&&(this._previewDims=r?`${r.w} × ${r.h}`:"—")}):this._previewDims="—"}this._updateFloatingPortal()}_injectFloatStyles(){if(document.querySelector("style[data-sfx-upload-float-styles]"))return;const e=document.createElement("style");e.setAttribute("data-sfx-upload-float-styles",""),e.textContent=`
2834
- [data-sfx-upload-float] .upload-float { position:fixed; bottom:24px; right:24px; z-index:10000; width:320px; border-radius:12px; background:#fff; box-shadow:0 8px 32px rgba(0,0,0,0.12),0 2px 8px rgba(0,0,0,0.06); overflow:hidden; font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,sans-serif; animation:sfxFloatIn .3s ease both; }
2938
+ `];let j=ve;G([c.state()],j.prototype,"_stream");G([c.state()],j.prototype,"_recording");G([c.state()],j.prototype,"_error");G([c.state()],j.prototype,"_recordedBlob");G([c.state()],j.prototype,"_previewUrl");var ft=Object.defineProperty,k=(n,e,t,o)=>{for(var r=void 0,i=n.length-1,a;i>=0;i--)(a=n[i])&&(r=a(e,t,r)||r);return r&&ft(e,t,r),r};const $e=new Set(["unsplash"]);var $;const y=($=class extends s.LitElement{constructor(){super(),this.config=null,this._isOpen=!1,this._activeConnector=null,this._showUrlDialog=!1,this._showCameraDialog=!1,this._showScreenCastDialog=!1,this._previewFileId=null,this._previewDims="—",this._splitPct=68,this._isResizing=!1,this._splitRafId=0,this._fullscreenPreviewUrl=null,this._fullscreenVideoFile=null,this._fullscreenZoomed=!1,this._fsPanX=0,this._fsPanY=0,this._fsDragging=!1,this._fsDragStartX=0,this._fsDragStartY=0,this._fsPanStartX=0,this._fsPanStartY=0,this._bodyDragOver=!1,this._isMinimized=!1,this._isPillExpanded=!1,this._bodyDragCounter=0,this._videoBlobUrls=new Map,this._engine=null,this._cachedSources=A,this._cachedSourcesConfig=void 0,this._rejectedTimers=new Map,this._closeOnCompleteTimer=null,this._apiBase=null,this._authHeaders=null,this._authResolveId=0,this._prevStoreState=null,this._unsubStoreEvents=null,this._portalContainer=null,this._onFilesSelected=e=>{this._processIncomingFiles(e.detail.files)},this._onDropTileSourceClick=e=>{this._handleSourceActivation(e.detail.source.id)},this._onSourceClick=async e=>{this._handleSourceActivation(e.detail.source)},this._handleSourceActivation=async e=>{var r,i;const t=this._mergedSources.find(a=>a.id===e);if(t!=null&&t.onActivate){try{t.onActivate(this)}catch(a){console.error(`[sfx-uploader] onActivate for custom source "${e}" threw:`,a)}return}if(e==="device"){const a=this.shadowRoot.querySelector("sfx-drop-zone");a==null||a.browse();return}if(e==="url"){this._showUrlDialog=!0;return}if(e==="camera"){this._showCameraDialog=!0;return}if(e==="screen-cast"){this._showScreenCastDialog=!0;return}if((((i=(r=this.config)==null?void 0:r.connectors)==null?void 0:i.providers)??[]).includes(e)){if($e.has(e)){if(!customElements.get("sfx-search-provider-browser")){const{SfxSearchProviderBrowser:l}=await Promise.resolve().then(()=>require("./search-provider-browser-CCknibp_.cjs"));customElements.define("sfx-search-provider-browser",l)}}else if(!customElements.get("sfx-provider-browser")){const{SfxProviderBrowser:l}=await Promise.resolve().then(()=>require("./provider-browser-B_4n6_hA.cjs"));customElements.define("sfx-provider-browser",l)}this._activeConnector=e}},this._onUrlSubmit=e=>{var h,u,x;this._showUrlDialog=!1;const{url:t,name:o}=e.detail,r=(h=this.config)==null?void 0:h.callbacks,i=Xe(o),a=i.startsWith("image/"),l=this._store.getState(),d=ie({name:o,size:0,type:i},l.restrictions,l.files);if(d){const f={id:T(),status:"rejected",file:null,remoteUrl:t,name:o,size:0,type:i,previewUrl:null,duration:null,progress:0,speed:0,bytesUploaded:0,error:d,retryCount:0,response:null,addedAt:Date.now(),meta:{},tags:[],remoteInfo:null};L(this._store,f),this._dispatchPublic(g.FILE_REJECTED,{file:f,reason:d}),(u=r==null?void 0:r.onFileRejected)==null||u.call(r,f,d);return}const p={id:T(),status:"idle",file:null,remoteUrl:t,name:o,size:0,type:i,previewUrl:a?t:null,duration:null,progress:0,speed:0,bytesUploaded:0,error:null,retryCount:0,response:null,addedAt:Date.now(),meta:{},tags:[],remoteInfo:null};L(this._store,p),this._dispatchPublic(g.FILE_ADDED,{file:p}),(x=r==null?void 0:r.onFileAdded)==null||x.call(r,p),this._store.getState().queueConfig.autoProceed&&this.upload()},this._onUrlCancel=()=>{this._showUrlDialog=!1},this._onCameraCapture=e=>{this._showCameraDialog=!1,this._processIncomingFiles([e.detail.file])},this._onCameraCancel=()=>{this._showCameraDialog=!1},this._onScreenCastCapture=e=>{this._showScreenCastDialog=!1,this._processIncomingFiles([e.detail.file])},this._onScreenCastCancel=()=>{this._showScreenCastDialog=!1},this._onFileRemove=e=>{this._removeFile(e.detail.fileId)},this._onFilePreview=e=>{var o,r,i;const t=this._store.getState().files.get(e.detail.fileId);t&&(this._previewFileId=t.id,this._dispatchPublic(g.FILE_PREVIEW,{file:t}),(i=(r=(o=this.config)==null?void 0:o.callbacks)==null?void 0:r.onFilePreview)==null||i.call(r,t))},this._onFillMetadata=()=>{var t,o,r;const e=[...this._store.getState().files.values()].filter(i=>$._MODIFIABLE_STATUSES.has(i.status));this._dispatchPublic(g.FILL_METADATA,{files:e}),(r=(o=(t=this.config)==null?void 0:t.callbacks)==null?void 0:o.onFillMetadata)==null||r.call(o,e)},this._onFileRetry=e=>{var t;this._ensureEngine(),(t=this._engine)==null||t.retryFile(e.detail.fileId)},this._onRetryAll=()=>{var e;this._ensureEngine(),(e=this._engine)==null||e.retryAll()},this._onClearAll=()=>{var o,r,i;const e=(o=this.config)==null?void 0:o.callbacks;this._closeOnCompleteTimer&&(clearTimeout(this._closeOnCompleteTimer),this._closeOnCompleteTimer=null),(r=this._engine)==null||r.cancelAll();const t=[...this._store.getState().files.values()];for(const a of t)a.previewUrl&&URL.revokeObjectURL(a.previewUrl),this._dispatchPublic(g.FILE_REMOVED,{file:a}),(i=e==null?void 0:e.onFileRemoved)==null||i.call(e,a);this._revokeVideoBlobUrls();for(const a of this._rejectedTimers.values())clearTimeout(a);this._rejectedTimers.clear(),this._dimCache.clear(),this._previewFileId=null,this._fullscreenPreviewUrl=null,this._fullscreenVideoFile=null,this._store.setState({files:new Map,isUploading:!1,totalProgress:0,totalSpeed:0,totalBytesUploaded:0,totalBytes:0})},this._onAddMore=()=>{var r;const e=this.shadowRoot.querySelector("sfx-drop-zone");if(e){e.browse();return}const t=this.shadowRoot.querySelector("sfx-file-list"),o=(r=t==null?void 0:t.shadowRoot)==null?void 0:r.querySelector('input[type="file"]');o==null||o.click()},this._onUploadStart=()=>{var e;if(this._phase==="complete"){((e=this.config)==null?void 0:e.clearOnComplete)!==!1&&this._onClearAll();return}this.upload()},this._onUploadMore=()=>{this._onClearAll()},this._onConnectorFilesSelected=e=>{var o,r,i;const t=(o=this.config)==null?void 0:o.callbacks;for(const a of e.detail.files){const l=this._store.getState(),d=ie({name:a.name,size:a.size,type:a.mimeType},l.restrictions,l.files);if(d){const h={id:T(),status:"rejected",file:null,remoteUrl:null,name:a.name,size:a.size,type:a.mimeType,previewUrl:a.thumbnail,duration:null,progress:0,speed:0,bytesUploaded:0,error:d,retryCount:0,response:null,addedAt:Date.now(),meta:{},tags:[],remoteInfo:a};L(this._store,h),this._dispatchPublic(g.FILE_REJECTED,{file:h,reason:d}),(r=t==null?void 0:t.onFileRejected)==null||r.call(t,h,d);continue}const p={id:T(),status:"idle",file:null,remoteUrl:null,name:a.name,size:a.size,type:a.mimeType,previewUrl:a.thumbnail,duration:null,progress:0,speed:0,bytesUploaded:0,error:null,retryCount:0,response:null,addedAt:Date.now(),meta:{},tags:[],remoteInfo:a};L(this._store,p),this._dispatchPublic(g.FILE_ADDED,{file:p}),(i=t==null?void 0:t.onFileAdded)==null||i.call(t,p)}this._activeConnector=null,this._store.getState().queueConfig.autoProceed&&this.upload()},this._onConnectorClose=()=>{this._activeConnector=null},this._onConnectorBackdropClick=e=>{e.target===e.currentTarget&&(this._activeConnector=null)},this._onPrimaryAction=()=>{var e,t,o,r,i;this._dispatchPublic(g.COMPLETE_ACTION,{}),(o=(t=(e=this.config)==null?void 0:e.callbacks)==null?void 0:t.onCompleteAction)==null||o.call(t),((r=this.config)==null?void 0:r.mode)==="modal"?this.close():((i=this.config)==null?void 0:i.clearOnComplete)!==!1&&this._onClearAll()},this._onInlineDismiss=()=>{var e,t,o;(o=(t=(e=this.config)==null?void 0:e.callbacks)==null?void 0:t.onCancel)==null||o.call(t),this._dispatchPublic(g.CANCEL,{})},this._onSuccessCardClose=()=>{var e,t,o,r;((e=this.config)==null?void 0:e.mode)==="inline"?(this._dispatchPublic(g.COMPLETE_ACTION,{}),(r=(o=(t=this.config)==null?void 0:t.callbacks)==null?void 0:o.onCompleteAction)==null||r.call(o),this._onClearAll()):this._onModalDismiss()},this._onModalDismiss=()=>{var e,t,o,r;this._phase==="uploading"&&((e=this._engine)==null||e.cancelAll()),(r=(o=(t=this.config)==null?void 0:t.callbacks)==null?void 0:o.onCancel)==null||r.call(o),this._dispatchPublic(g.CANCEL,{}),this.close()},this._onMinimize=()=>{this._isMinimized=!0,this._isPillExpanded=!0,this.requestUpdate()},this._onPillClick=()=>{this._isPillExpanded=!this._isPillExpanded,this.requestUpdate()},this._onPillExpand=()=>{this._isMinimized=!1,this._isPillExpanded=!1,this._isOpen=!0,this.requestUpdate()},this._onPillDismiss=()=>{var e,t,o,r;this._isMinimized=!1,this._isPillExpanded=!1,this._phase==="uploading"&&((e=this._engine)==null||e.cancelAll()),(r=(o=(t=this.config)==null?void 0:t.callbacks)==null?void 0:o.onCancel)==null||r.call(o),this._dispatchPublic(g.CANCEL,{}),this.close()},this._onModalBackdropClick=e=>{e.target===e.currentTarget&&this._onModalDismiss()},this._onBodyDragEnter=e=>{e.preventDefault(),this._bodyDragCounter++,this._bodyDragCounter===1&&(this._bodyDragOver=!0)},this._onBodyDragOver=e=>{e.preventDefault()},this._onBodyDragLeave=e=>{e.preventDefault(),this._bodyDragCounter--,this._bodyDragCounter<=0&&(this._bodyDragCounter=0,this._bodyDragOver=!1)},this._onBodyDrop=e=>{var o;e.preventDefault(),this._bodyDragCounter=0,this._bodyDragOver=!1;const t=Array.from(((o=e.dataTransfer)==null?void 0:o.files)??[]);t.length>0&&this._onFilesSelected(new CustomEvent("files-selected",{detail:{files:t}}))},this._onKeyDown=e=>{var t,o;if(e.key==="Escape"){if(this._fullscreenPreviewUrl||this._fullscreenVideoFile){this._onFsClose();return}this._isOpen&&((t=this.config)==null?void 0:t.mode)==="modal"&&(((o=this.config)==null?void 0:o.headerButton)??"close")!=="none"&&this._onModalDismiss()}},this._dimCache=new Map,this._onSplitPointerDown=e=>{var o;e.preventDefault(),this._isResizing=!0;const t=(o=this.shadowRoot)==null?void 0:o.querySelector(".preview-layout");t==null||t.classList.add("resizing"),e.target.setPointerCapture(e.pointerId)},this._onSplitPointerMove=e=>{if(!this._isResizing||this._splitRafId)return;const t=e.clientX;this._splitRafId=requestAnimationFrame(()=>{var a;this._splitRafId=0;const o=(a=this.shadowRoot)==null?void 0:a.querySelector(".preview-layout");if(!o)return;const r=o.getBoundingClientRect(),i=(t-r.left)/r.width*100;this._splitPct=Math.max(25,Math.min(75,i))})},this._onSplitPointerUp=()=>{var t;this._isResizing=!1,this._splitRafId&&(cancelAnimationFrame(this._splitRafId),this._splitRafId=0);const e=(t=this.shadowRoot)==null?void 0:t.querySelector(".preview-layout");e==null||e.classList.remove("resizing")},this._onFsToggleZoom=e=>{e==null||e.stopPropagation(),this._fullscreenZoomed=!this._fullscreenZoomed,this._fullscreenZoomed||(this._fsPanX=0,this._fsPanY=0)},this._onFsOverlayClick=e=>{this._fsDragDidMove||this._onFsToggleZoom(e)},this._fsDragDidMove=!1,this._onFsPanStart=e=>{this._fullscreenZoomed&&(this._fsDragging=!0,this._fsDragDidMove=!1,this._fsDragStartX=e.clientX,this._fsDragStartY=e.clientY,this._fsPanStartX=this._fsPanX,this._fsPanStartY=this._fsPanY,e.preventDefault())},this._onFsPanMove=e=>{if(!this._fsDragging)return;const t=e.clientX-this._fsDragStartX,o=e.clientY-this._fsDragStartY;(Math.abs(t)>3||Math.abs(o)>3)&&(this._fsDragDidMove=!0),this._fsPanX=this._fsPanStartX+t,this._fsPanY=this._fsPanStartY+o,this.requestUpdate()},this._onFsPanEnd=()=>{this._fsDragging=!1,requestAnimationFrame(()=>{this._fsDragDidMove=!1})},this._onFsTouchStart=e=>{if(!this._fullscreenZoomed||e.touches.length!==1)return;const t=e.touches[0];this._fsDragging=!0,this._fsDragDidMove=!1,this._fsDragStartX=t.clientX,this._fsDragStartY=t.clientY,this._fsPanStartX=this._fsPanX,this._fsPanStartY=this._fsPanY},this._onFsTouchMove=e=>{if(!this._fsDragging||e.touches.length!==1)return;const t=e.touches[0],o=t.clientX-this._fsDragStartX,r=t.clientY-this._fsDragStartY;(Math.abs(o)>3||Math.abs(r)>3)&&(this._fsDragDidMove=!0),this._fsPanX=this._fsPanStartX+o,this._fsPanY=this._fsPanStartY+r,this.requestUpdate(),e.preventDefault()},this._onFsClose=e=>{e==null||e.stopPropagation(),this._fullscreenPreviewUrl=null,this._fullscreenVideoFile=null,this._fullscreenZoomed=!1,this._fsPanX=0,this._fsPanY=0},this._store=Ee(),this._storeCtrl=new Fe(this,this._store)}open(){var e,t,o;this._isMinimized&&(this._isMinimized=!1,this._isPillExpanded=!1),!this._isOpen&&(this._isOpen=!0,(o=(t=(e=this.config)==null?void 0:e.callbacks)==null?void 0:t.onOpen)==null||o.call(t),this._dispatchPublic(g.OPEN,{}),this.requestUpdate())}close(){var e,t,o,r;this._isOpen&&(this._isOpen=!1,this._closeOnCompleteTimer&&(clearTimeout(this._closeOnCompleteTimer),this._closeOnCompleteTimer=null),((e=this.config)==null?void 0:e.clearOnClose)!==!1&&this._onClearAll(),this._previewFileId=null,(r=(o=(t=this.config)==null?void 0:t.callbacks)==null?void 0:o.onClose)==null||r.call(o),this._dispatchPublic(g.CLOSE,{}),this.requestUpdate())}upload(){var r,i,a,l,d,p,h;if(this._ensureEngine(),!this._engine){console.warn("[sfx-uploader] Cannot upload: auth not resolved yet");return}const e=[...this._store.getState().files.values()].filter(u=>u.status==="idle"||u.status==="queued");if((i=(r=this.config)==null?void 0:r.callbacks)!=null&&i.onBeforeUpload&&this.config.callbacks.onBeforeUpload(e)===!1)return;const t=new CustomEvent(g.BEFORE_UPLOAD,{bubbles:!0,composed:!0,cancelable:!0,detail:{files:e}});this.dispatchEvent(t)&&(this._dispatchPublic(g.UPLOAD_STARTED,{files:e}),(d=(l=(a=this.config)==null?void 0:a.callbacks)==null?void 0:l.onUploadStarted)==null||d.call(l,e),this._engine.uploadAll(),(p=this.config)!=null&&p.minimizeOnUpload&&((h=this.config)==null?void 0:h.mode)!=="inline"&&(this._isMinimized=!0,this._isPillExpanded=!0,this.requestUpdate()))}addFiles(e){this._processIncomingFiles(e)}resumeUpload(e){var t;if(e&&e.length>0){const o=this._store.getState().files,r=new Map(o);let i=!1;for(const a of e){const l=o.get(a.id);l&&(r.set(a.id,{...l,...a}),i=!0)}i&&this._store.setState({files:r})}this._ensureEngine(),(t=this._engine)==null||t.uploadAll()}cancelUpload(){var e;(e=this._engine)==null||e.cancelAll()}getFiles(){return[...this._store.getState().files.values()]}getFile(e){return this._store.getState().files.get(e)}updateFileMeta(e,t,o){const r=this._store.getState().files,i=r.get(e);if(!i||!$._MODIFIABLE_STATUSES.has(i.status))return;const a=new Map(r);a.set(e,{...i,meta:t!=null?{...i.meta,...t}:i.meta,tags:o??i.tags}),this._store.setState({files:a})}updateFilesMeta(e){const t=this._store.getState().files,o=new Map(t);let r=!1;for(const{fileId:i,meta:a,tags:l}of e){const d=t.get(i);!d||!$._MODIFIABLE_STATUSES.has(d.status)||(o.set(i,{...d,meta:a!=null?{...d.meta,...a}:d.meta,tags:l??d.tags}),r=!0)}r&&this._store.setState({files:o})}updated(e){if(e.has("config")&&this.config&&this._applyConfig(this.config),e.has("_previewFileId")&&this._previewFileId){const t=this._previewFileId,o=this._store.getState().files.get(t);o?this._getImageDimensions(o).then(r=>{this._previewFileId===t&&(this._previewDims=r?`${r.w} × ${r.h}`:"—")}):this._previewDims="—"}this._updateFloatingPortal()}_injectFloatStyles(){if(document.querySelector("style[data-sfx-upload-float-styles]"))return;const e=document.createElement("style");e.setAttribute("data-sfx-upload-float-styles",""),e.textContent=`
2939
+ [data-sfx-upload-float] .upload-float { position:fixed; bottom:24px; right:24px; z-index:10000; width:470px; border-radius:12px; background:#fff; box-shadow:0 8px 32px rgba(0,0,0,0.12),0 2px 8px rgba(0,0,0,0.06); overflow:hidden; font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,sans-serif; animation:sfxFloatIn .3s ease both; }
2835
2940
  [data-sfx-upload-float] .float-header { display:flex; align-items:center; justify-content:space-between; padding:10px 14px; border-bottom:1px solid #e8edf5; }
2836
2941
  [data-sfx-upload-float] .float-header-left { display:flex; align-items:center; gap:8px; }
2837
2942
  [data-sfx-upload-float] .float-icon { width:28px; height:28px; border-radius:6px; background:#eff6ff; color:#2563eb; display:flex; align-items:center; justify-content:center; flex-shrink:0; }
2838
2943
  [data-sfx-upload-float] .float-icon svg { width:14px; height:14px; }
2839
2944
  [data-sfx-upload-float] .float-icon.done { background:#f0fdf4; color:#22c55e; }
2840
2945
  [data-sfx-upload-float] .float-icon.warn { background:#fffbeb; color:#f59e0b; }
2946
+ [data-sfx-upload-float] .float-icon.error { background:#fef2f2; color:#ef4444; }
2841
2947
  [data-sfx-upload-float] .float-title { font-size:13px; font-weight:600; color:#1e293b; }
2842
2948
  [data-sfx-upload-float] .float-subtitle { font-size:11px; color:#94a3b8; }
2843
2949
  [data-sfx-upload-float] .float-actions { display:flex; gap:4px; }
@@ -2850,29 +2956,39 @@
2850
2956
  [data-sfx-upload-float] .float-progress-pct { font-size:12px; font-weight:600; color:#2563eb; }
2851
2957
  [data-sfx-upload-float] .float-progress-pct.done { color:#22c55e; }
2852
2958
  [data-sfx-upload-float] .float-progress-pct.warn { color:#f59e0b; }
2959
+ [data-sfx-upload-float] .float-progress-pct.error { color:#ef4444; }
2853
2960
  [data-sfx-upload-float] .float-bar { height:4px; background:#e8edf5; border-radius:2px; overflow:hidden; }
2854
2961
  [data-sfx-upload-float] .float-bar-fill { height:100%; background:#2563eb; border-radius:2px; transition:width .3s ease; }
2855
2962
  [data-sfx-upload-float] .float-bar-fill.done { background:#22c55e; }
2856
2963
  [data-sfx-upload-float] .float-bar-fill.warn { background:#f59e0b; }
2964
+ [data-sfx-upload-float] .float-bar-fill.error { background:#ef4444; }
2857
2965
  [data-sfx-upload-float] .float-items { max-height:200px; overflow-y:auto; }
2858
- [data-sfx-upload-float] .float-item { display:flex; align-items:center; gap:10px; padding:8px 14px; border-bottom:1px solid #f1f5f9; }
2966
+ [data-sfx-upload-float] .float-item { display:flex; align-items:center; gap:10px; padding:8px 14px; border-bottom:1px solid #f1f5f9; overflow:hidden; }
2859
2967
  [data-sfx-upload-float] .float-item:last-child { border-bottom:none; }
2860
2968
  [data-sfx-upload-float] .float-item-thumb { width:32px; height:32px; border-radius:6px; background:#f8fafc; display:flex; align-items:center; justify-content:center; color:#94a3b8; flex-shrink:0; }
2861
2969
  [data-sfx-upload-float] .float-item-thumb svg { width:16px; height:16px; }
2862
- [data-sfx-upload-float] .float-item-info { flex:1; min-width:0; }
2970
+ [data-sfx-upload-float] .float-item-info { flex:1; min-width:0; overflow:hidden; }
2863
2971
  [data-sfx-upload-float] .float-item-name { font-size:12px; font-weight:500; color:#1e293b; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
2864
2972
  [data-sfx-upload-float] .float-item-size { font-size:11px; color:#94a3b8; }
2865
2973
  [data-sfx-upload-float] .float-item-done { width:18px; height:18px; border-radius:50%; background:#f0fdf4; color:#22c55e; display:flex; align-items:center; justify-content:center; flex-shrink:0; }
2866
2974
  [data-sfx-upload-float] .float-item-done svg { width:12px; height:12px; }
2867
2975
  [data-sfx-upload-float] .float-item-spinner { width:16px; height:16px; border:2px solid #e8edf5; border-top-color:#2563eb; border-radius:50%; animation:sfxSpin .8s linear infinite; flex-shrink:0; }
2868
- [data-sfx-upload-float] .float-item-error { color:#ef4444; width:16px; height:16px; flex-shrink:0; cursor:help; }
2869
- [data-sfx-upload-float] .float-collapsed { display:flex; align-items:center; justify-content:space-between; padding:10px 14px; width:320px; border-radius:12px; }
2976
+ [data-sfx-upload-float] .float-item-status { display:flex; flex-direction:row; align-items:center; gap:4px; flex-shrink:0; }
2977
+ [data-sfx-upload-float] .float-item-error-wrap { position:relative; display:flex; align-items:center; flex-shrink:0; }
2978
+ [data-sfx-upload-float] .float-item-error-icon { width:16px; height:16px; color:#ef4444; flex-shrink:0; cursor:pointer; }
2979
+ [data-sfx-upload-float] .float-item-tooltip { display:none; position:absolute; right:calc(100% + 8px); top:50%; transform:translateY(-50%); background:#fff; color:#1e293b; font-size:11px; padding:6px 10px; border-radius:6px; white-space:nowrap; pointer-events:none; z-index:10; box-shadow:0 2px 12px rgba(0,0,0,0.12),0 1px 4px rgba(0,0,0,0.08); }
2980
+ [data-sfx-upload-float] .float-item-error-wrap:hover .float-item-tooltip { display:block; }
2981
+ [data-sfx-upload-float] .float-item-retry { width:24px; height:24px; border:none; background:none; color:#2563eb; cursor:pointer; padding:4px; flex-shrink:0; display:flex; align-items:center; justify-content:center; border-radius:4px; }
2982
+ [data-sfx-upload-float] .float-item-retry svg { width:14px; height:14px; }
2983
+ [data-sfx-upload-float] .float-item-retry:hover { background:#f1f5f9; color:#1d4ed8; }
2984
+ [data-sfx-upload-float] .float-collapsed { display:flex; align-items:center; justify-content:space-between; padding:10px 14px; width:470px; border-radius:12px; }
2870
2985
  [data-sfx-upload-float] .float-collapsed-left { display:flex; align-items:center; gap:8px; }
2871
2986
  [data-sfx-upload-float] .float-collapsed-spinner { width:18px; height:18px; border:2.5px solid #e8edf5; border-top-color:#2563eb; border-radius:50%; animation:sfxSpin .8s linear infinite; flex-shrink:0; }
2872
2987
  [data-sfx-upload-float] .float-collapsed-icon { width:18px; height:18px; flex-shrink:0; }
2873
2988
  [data-sfx-upload-float] .float-collapsed-icon svg { width:18px; height:18px; }
2874
2989
  [data-sfx-upload-float] .float-collapsed-icon.done { color:#22c55e; }
2875
2990
  [data-sfx-upload-float] .float-collapsed-icon.warn { color:#f59e0b; }
2991
+ [data-sfx-upload-float] .float-collapsed-icon.error { color:#ef4444; }
2876
2992
  [data-sfx-upload-float] .float-collapsed-text { font-size:13px; font-weight:500; color:#1e293b; white-space:nowrap; }
2877
2993
  [data-sfx-upload-float] .float-collapsed-pct { font-size:13px; font-weight:600; color:#2563eb; }
2878
2994
  [data-sfx-upload-float] .float-collapsed-actions { display:flex; gap:4px; }
@@ -2881,7 +2997,7 @@
2881
2997
  [data-sfx-upload-float] .float-collapsed-actions button svg { width:14px; height:14px; }
2882
2998
  @keyframes sfxFloatIn { from{opacity:0;transform:translateY(20px)} to{opacity:1;transform:translateY(0)} }
2883
2999
  @keyframes sfxSpin { to{transform:rotate(360deg)} }
2884
- `,document.head.appendChild(e)}_updateFloatingPortal(){const e=[...this._storeCtrl.state.files.values()];this._isMinimized&&e.length>0?(this._injectFloatStyles(),this._portalContainer||(this._portalContainer=document.createElement("div"),this._portalContainer.setAttribute("data-sfx-upload-float",""),document.body.appendChild(this._portalContainer)),s.render(this._renderFloatingPill(e),this._portalContainer)):this._portalContainer&&(s.render(s.nothing,this._portalContainer),this._portalContainer.remove(),this._portalContainer=null)}connectedCallback(){super.connectedCallback(),document.addEventListener("keydown",this._onKeyDown),this._prevStoreState=this._store.getState(),this._unsubStoreEvents=this._store.subscribe(()=>this._onStoreChange())}disconnectedCallback(){var e,t,i,r;super.disconnectedCallback(),document.removeEventListener("keydown",this._onKeyDown),(e=this._unsubStoreEvents)==null||e.call(this),this._unsubStoreEvents=null,this._prevStoreState=null,(t=this._portalContainer)==null||t.remove(),this._portalContainer=null,document.querySelector("[data-sfx-upload-float]")||(i=document.querySelector("style[data-sfx-upload-float-styles]"))==null||i.remove(),this._revokeVideoBlobUrls();for(const o of this._rejectedTimers.values())clearTimeout(o);this._rejectedTimers.clear(),this._closeOnCompleteTimer&&(clearTimeout(this._closeOnCompleteTimer),this._closeOnCompleteTimer=null);for(const o of this._store.getState().files.values())o.previewUrl&&URL.revokeObjectURL(o.previewUrl);(r=this._engine)==null||r.destroy(),this._engine=null}_applyConfig(e){const t={};if(e.targetFolder&&(t.targetFolder=e.targetFolder),e.restrictions&&(t.restrictions={...this._store.getState().restrictions,...e.restrictions}),e.concurrency!=null){const i=this._store.getState().queueConfig;t.queueConfig={...i,concurrency:e.concurrency}}if(e.autoProceed!=null){const i=t.queueConfig??this._store.getState().queueConfig;t.queueConfig={...i,autoProceed:e.autoProceed}}Object.keys(t).length>0&&this._store.setState(t),this._resolveAuthAndEngine(e),(e.mode==="inline"||!e.mode)&&(this._isOpen=!0)}async _resolveAuthAndEngine(e){var r,o;const t=e.auth;if(t.mode==="sass-key"){this._apiBase=te(t.container),this._authHeaders=K(t),this._ensureEngine(),(r=this._engine)==null||r.updateConfig({apiBase:this._apiBase,authHeaders:this._authHeaders});return}const i=++this._authResolveId;try{const a=await Pe(t);if(i!==this._authResolveId)return;this._apiBase=a.apiBase,this._authHeaders=a.headers,this._ensureEngine(),(o=this._engine)==null||o.updateConfig({apiBase:this._apiBase,authHeaders:this._authHeaders})}catch(a){if(i!==this._authResolveId)return;console.error("[sfx-uploader] Auth resolution failed:",a)}}_ensureEngine(){!this._engine&&this._apiBase&&this._authHeaders&&(this._engine=new Ue(this._store,{apiBase:this._apiBase,authHeaders:this._authHeaders}),this._engine.start())}_dispatchPublic(e,t){this.dispatchEvent(new CustomEvent(e,{bubbles:!0,composed:!0,detail:t}))}_onStoreChange(){var r,o,a,l,d,c,h,x;const e=this._store.getState(),t=this._prevStoreState;if(this._prevStoreState=e,!t)return;const i=(r=this.config)==null?void 0:r.callbacks;for(const[u,f]of e.files){const v=t.files.get(u);if(v){if(v.status!==f.status)switch(f.status){case"uploading":break;case"complete":f.response&&(this._dispatchPublic(g.UPLOAD_COMPLETE,{file:f,response:f.response}),(o=i==null?void 0:i.onUploadComplete)==null||o.call(i,f,f.response));break;case"error":case"failed":{const w=new Error(f.error??"Upload failed");this._dispatchPublic(g.UPLOAD_ERROR,{file:f,error:w}),(a=i==null?void 0:i.onUploadError)==null||a.call(i,f,w);break}case"retrying":this._dispatchPublic(g.UPLOAD_RETRY,{file:f,attempt:f.retryCount}),(l=i==null?void 0:i.onUploadRetry)==null||l.call(i,f,f.retryCount);break}f.status==="uploading"&&v.progress!==f.progress&&(this._dispatchPublic(g.UPLOAD_PROGRESS,{file:f,progress:f.progress,speed:f.speed}),(d=i==null?void 0:i.onUploadProgress)==null||d.call(i,f,f.progress,f.speed))}}if(e.totalProgress!==t.totalProgress||e.totalSpeed!==t.totalSpeed){const u=e.totalSpeed>0?(e.totalBytes-e.totalBytesUploaded)/e.totalSpeed:0;this._dispatchPublic(g.TOTAL_PROGRESS,{percentage:e.totalProgress,speed:e.totalSpeed,eta:u}),(c=i==null?void 0:i.onTotalProgress)==null||c.call(i,e.totalProgress,e.totalSpeed,u)}if(t.isUploading&&!e.isUploading){const u=[...e.files.values()];if(!u.some(v=>v.status==="cancelled")){const v=u.filter(b=>b.status==="complete"),w=u.filter(b=>b.status==="failed"||b.status==="error");this._dispatchPublic(g.ALL_COMPLETE,{successful:v,failed:w}),(h=i==null?void 0:i.onAllComplete)==null||h.call(i,v,w);const m=(x=this.config)==null?void 0:x.closeOnComplete;if(m){const b=typeof m=="number"?m:1500;this._closeOnCompleteTimer=setTimeout(()=>{var y,E,me;this._closeOnCompleteTimer=null,this._phase==="complete"&&(this._dispatchPublic(g.COMPLETE_ACTION,{}),(me=(E=(y=this.config)==null?void 0:y.callbacks)==null?void 0:E.onCompleteAction)==null||me.call(E),this.close())},b)}}}}get _mergedSources(){var d;const e=(d=this.config)==null?void 0:d.connectors;if(e===this._cachedSourcesConfig)return this._cachedSources;if(this._cachedSourcesConfig=e,!e)return this._cachedSources=A,this._cachedSources;const t=e.providers.length>0?De(e.providers):[],i=e.customSources??[],r=A.filter(c=>c.id==="device"||c.id==="url"),o=A.filter(c=>c.id!=="device"&&c.id!=="url"),a=new Set,l=[];for(const c of[...r,...t,...o,...i])if(!a.has(c.id)){if($._RESERVED_IDS.has(c.id)&&c.onActivate){console.warn(`[sfx-uploader] Custom source id "${c.id}" conflicts with a built-in source and was skipped.`);continue}a.add(c.id),l.push(c)}return this._cachedSources=l,this._cachedSources}get _phase(){const e=this._storeCtrl.state,t=[...e.files.values()];if(t.length===0)return"empty";if(e.isUploading)return"uploading";const i=new Set(["complete","rejected","cancelled","failed"]);return t.every(r=>i.has(r.status))&&t.some(r=>r.status==="complete"||r.status==="failed")?"complete":"ready"}_processIncomingFiles(e){var i,r,o,a;const t=(i=this.config)==null?void 0:i.callbacks;for(const l of e){const d=this._store.getState(),c=Ge(l,d.restrictions,d.files);if(c){const u=l.type.startsWith("image/")?URL.createObjectURL(l):null,f={id:B(),status:"rejected",file:l,remoteUrl:null,name:l.name,size:l.size,type:l.type,previewUrl:u,duration:null,progress:0,speed:0,bytesUploaded:0,error:c,retryCount:0,response:null,addedAt:Date.now(),meta:{},tags:[],remoteInfo:null};M(this._store,f),this._dispatchPublic(g.FILE_REJECTED,{file:f,reason:c}),(r=t==null?void 0:t.onFileRejected)==null||r.call(t,f,c);const v=(o=this.config)==null?void 0:o.rejectedFileAutoRemoveDelay,w=v===!1||v===0||v===void 0?0:v;if(w>0){const m=f.id,b=setTimeout(()=>{this._rejectedTimers.delete(m);const y=this._store.getState().files.get(m);y&&y.status==="rejected"&&be(this._store,m)},w);this._rejectedTimers.set(m,b)}continue}let h=null;l.type.startsWith("image/")&&(h=URL.createObjectURL(l));const x={id:B(),status:"idle",file:l,remoteUrl:null,name:l.name,size:l.size,type:l.type,previewUrl:h,duration:null,progress:0,speed:0,bytesUploaded:0,error:null,retryCount:0,response:null,addedAt:Date.now(),meta:{},tags:[],remoteInfo:null};if(M(this._store,x),this._dispatchPublic(g.FILE_ADDED,{file:x}),(a=t==null?void 0:t.onFileAdded)==null||a.call(t,x),l.type.startsWith("video/")){We(l).then(f=>{if(!f)return;const v=this._store.getState(),w=v.files.get(x.id);if(w){const m=new Map(v.files);m.set(x.id,{...w,previewUrl:f}),this._store.setState({files:m})}else URL.revokeObjectURL(f)});const u=document.createElement("video");u.preload="metadata",u.src=URL.createObjectURL(l),u.onerror=()=>{URL.revokeObjectURL(u.src)},u.onloadedmetadata=()=>{const f=u.duration;if(URL.revokeObjectURL(u.src),!isFinite(f))return;const v=this._store.getState(),w=v.files.get(x.id);if(w){const m=new Map(v.files);m.set(x.id,{...w,duration:f}),this._store.setState({files:m})}}}}this._store.getState().queueConfig.autoProceed&&this.upload()}_removeFile(e){var o,a,l,d;const t=this._store.getState().files.get(e);if(!t)return;const i={...t};if((this._fullscreenPreviewUrl&&this._fullscreenPreviewUrl===t.previewUrl||this._fullscreenVideoFile&&this._fullscreenVideoFile===t.file)&&(this._fullscreenPreviewUrl=null,this._fullscreenVideoFile=null),t.previewUrl&&URL.revokeObjectURL(t.previewUrl),t.file){const c=this._videoBlobUrls.get(t.file);c&&(URL.revokeObjectURL(c),this._videoBlobUrls.delete(t.file))}(t.status==="uploading"||t.status==="queued"||t.status==="retrying")&&((o=this._engine)==null||o.cancelFile(e)),be(this._store,e),this._dimCache.delete(e);const r=this._rejectedTimers.get(e);if(r&&(clearTimeout(r),this._rejectedTimers.delete(e)),this._previewFileId===e){const c=[...this._store.getState().files.values()];this._previewFileId=c.length>0?c[0].id:null}this._dispatchPublic(g.FILE_REMOVED,{file:i}),(d=(l=(a=this.config)==null?void 0:a.callbacks)==null?void 0:l.onFileRemoved)==null||d.call(l,i)}render(){var t;const e=((t=this.config)==null?void 0:t.mode)??"modal";return[...this._storeCtrl.state.files.values()],e==="modal"?s.html`
3000
+ `,document.head.appendChild(e)}_updateFloatingPortal(){const e=[...this._storeCtrl.state.files.values()];this._isMinimized&&e.length>0?(this._injectFloatStyles(),this._portalContainer||(this._portalContainer=document.createElement("div"),this._portalContainer.setAttribute("data-sfx-upload-float",""),document.body.appendChild(this._portalContainer)),s.render(this._renderFloatingPill(e),this._portalContainer)):this._portalContainer&&(s.render(s.nothing,this._portalContainer),this._portalContainer.remove(),this._portalContainer=null)}connectedCallback(){super.connectedCallback(),document.addEventListener("keydown",this._onKeyDown),this._prevStoreState=this._store.getState(),this._unsubStoreEvents=this._store.subscribe(()=>this._onStoreChange())}disconnectedCallback(){var e,t,o,r;super.disconnectedCallback(),document.removeEventListener("keydown",this._onKeyDown),(e=this._unsubStoreEvents)==null||e.call(this),this._unsubStoreEvents=null,this._prevStoreState=null,(t=this._portalContainer)==null||t.remove(),this._portalContainer=null,document.querySelector("[data-sfx-upload-float]")||(o=document.querySelector("style[data-sfx-upload-float-styles]"))==null||o.remove(),this._revokeVideoBlobUrls();for(const i of this._rejectedTimers.values())clearTimeout(i);this._rejectedTimers.clear(),this._closeOnCompleteTimer&&(clearTimeout(this._closeOnCompleteTimer),this._closeOnCompleteTimer=null);for(const i of this._store.getState().files.values())i.previewUrl&&URL.revokeObjectURL(i.previewUrl);(r=this._engine)==null||r.destroy(),this._engine=null}_applyConfig(e){const t={};if(e.targetFolder&&(t.targetFolder=e.targetFolder),e.restrictions&&(t.restrictions={...this._store.getState().restrictions,...e.restrictions}),e.concurrency!=null){const o=this._store.getState().queueConfig;t.queueConfig={...o,concurrency:e.concurrency}}if(e.autoProceed!=null){const o=t.queueConfig??this._store.getState().queueConfig;t.queueConfig={...o,autoProceed:e.autoProceed}}Object.keys(t).length>0&&this._store.setState(t),this._resolveAuthAndEngine(e),(e.mode==="inline"||!e.mode)&&(this._isOpen=!0)}async _resolveAuthAndEngine(e){var r,i;const t=e.auth;if(t.mode==="sass-key"){this._apiBase=te(t.container),this._authHeaders=K(t),this._ensureEngine(),(r=this._engine)==null||r.updateConfig({apiBase:this._apiBase,authHeaders:this._authHeaders});return}const o=++this._authResolveId;try{const a=await ze(t);if(o!==this._authResolveId)return;this._apiBase=a.apiBase,this._authHeaders=a.headers,this._ensureEngine(),(i=this._engine)==null||i.updateConfig({apiBase:this._apiBase,authHeaders:this._authHeaders})}catch(a){if(o!==this._authResolveId)return;console.error("[sfx-uploader] Auth resolution failed:",a)}}_ensureEngine(){!this._engine&&this._apiBase&&this._authHeaders&&(this._engine=new Pe(this._store,{apiBase:this._apiBase,authHeaders:this._authHeaders}),this._engine.start())}_dispatchPublic(e,t){this.dispatchEvent(new CustomEvent(e,{bubbles:!0,composed:!0,detail:t}))}_onStoreChange(){var r,i,a,l,d,p,h,u;const e=this._store.getState(),t=this._prevStoreState;if(this._prevStoreState=e,!t)return;const o=(r=this.config)==null?void 0:r.callbacks;for(const[x,f]of e.files){const v=t.files.get(x);if(v){if(v.status!==f.status)switch(f.status){case"uploading":break;case"complete":f.response&&(this._dispatchPublic(g.UPLOAD_COMPLETE,{file:f,response:f.response}),(i=o==null?void 0:o.onUploadComplete)==null||i.call(o,f,f.response));break;case"error":case"failed":{const w=new Error(f.error??"Upload failed");this._dispatchPublic(g.UPLOAD_ERROR,{file:f,error:w}),(a=o==null?void 0:o.onUploadError)==null||a.call(o,f,w);break}case"retrying":this._dispatchPublic(g.UPLOAD_RETRY,{file:f,attempt:f.retryCount}),(l=o==null?void 0:o.onUploadRetry)==null||l.call(o,f,f.retryCount);break}f.status==="uploading"&&v.progress!==f.progress&&(this._dispatchPublic(g.UPLOAD_PROGRESS,{file:f,progress:f.progress,speed:f.speed}),(d=o==null?void 0:o.onUploadProgress)==null||d.call(o,f,f.progress,f.speed))}}if(e.totalProgress!==t.totalProgress||e.totalSpeed!==t.totalSpeed){const x=e.totalSpeed>0?(e.totalBytes-e.totalBytesUploaded)/e.totalSpeed:0;this._dispatchPublic(g.TOTAL_PROGRESS,{percentage:e.totalProgress,speed:e.totalSpeed,eta:x}),(p=o==null?void 0:o.onTotalProgress)==null||p.call(o,e.totalProgress,e.totalSpeed,x)}if(t.isUploading&&!e.isUploading){const x=[...e.files.values()];if(!x.some(v=>v.status==="cancelled")){const v=x.filter(m=>m.status==="complete"),w=x.filter(m=>m.status==="failed"||m.status==="error");this._dispatchPublic(g.ALL_COMPLETE,{successful:v,failed:w}),(h=o==null?void 0:o.onAllComplete)==null||h.call(o,v,w);const b=(u=this.config)==null?void 0:u.closeOnComplete;if(b){const m=typeof b=="number"?b:1500;this._closeOnCompleteTimer=setTimeout(()=>{var _,E,be;this._closeOnCompleteTimer=null,this._phase==="complete"&&(this._dispatchPublic(g.COMPLETE_ACTION,{}),(be=(E=(_=this.config)==null?void 0:_.callbacks)==null?void 0:E.onCompleteAction)==null||be.call(E),this.close())},m)}}}}get _mergedSources(){var d;const e=(d=this.config)==null?void 0:d.connectors;if(e===this._cachedSourcesConfig)return this._cachedSources;if(this._cachedSourcesConfig=e,!e)return this._cachedSources=A,this._cachedSources;const t=e.providers.length>0?De(e.providers):[],o=e.customSources??[],r=A.filter(p=>p.id==="device"||p.id==="url"),i=A.filter(p=>p.id!=="device"&&p.id!=="url"),a=new Set,l=[];for(const p of[...r,...t,...i,...o])if(!a.has(p.id)){if($._RESERVED_IDS.has(p.id)&&p.onActivate){console.warn(`[sfx-uploader] Custom source id "${p.id}" conflicts with a built-in source and was skipped.`);continue}a.add(p.id),l.push(p)}return this._cachedSources=l,this._cachedSources}get _phase(){const e=this._storeCtrl.state,t=[...e.files.values()];if(t.length===0)return"empty";if(e.isUploading)return"uploading";const o=new Set(["complete","rejected","cancelled","failed"]);return t.every(r=>o.has(r.status))&&t.some(r=>r.status==="complete"||r.status==="failed")?"complete":"ready"}_processIncomingFiles(e){var o,r,i,a;const t=(o=this.config)==null?void 0:o.callbacks;for(const l of e){const d=this._store.getState(),p=Ge(l,d.restrictions,d.files);if(p){const x=l.type.startsWith("image/")?URL.createObjectURL(l):null,f={id:T(),status:"rejected",file:l,remoteUrl:null,name:l.name,size:l.size,type:l.type,previewUrl:x,duration:null,progress:0,speed:0,bytesUploaded:0,error:p,retryCount:0,response:null,addedAt:Date.now(),meta:{},tags:[],remoteInfo:null};L(this._store,f),this._dispatchPublic(g.FILE_REJECTED,{file:f,reason:p}),(r=t==null?void 0:t.onFileRejected)==null||r.call(t,f,p);const v=(i=this.config)==null?void 0:i.rejectedFileAutoRemoveDelay,w=v===!1||v===0||v===void 0?0:v;if(w>0){const b=f.id,m=setTimeout(()=>{this._rejectedTimers.delete(b);const _=this._store.getState().files.get(b);_&&_.status==="rejected"&&me(this._store,b)},w);this._rejectedTimers.set(b,m)}continue}let h=null;l.type.startsWith("image/")&&(h=URL.createObjectURL(l));const u={id:T(),status:"idle",file:l,remoteUrl:null,name:l.name,size:l.size,type:l.type,previewUrl:h,duration:null,progress:0,speed:0,bytesUploaded:0,error:null,retryCount:0,response:null,addedAt:Date.now(),meta:{},tags:[],remoteInfo:null};if(L(this._store,u),this._dispatchPublic(g.FILE_ADDED,{file:u}),(a=t==null?void 0:t.onFileAdded)==null||a.call(t,u),l.type.startsWith("video/")){We(l).then(f=>{if(!f)return;const v=this._store.getState(),w=v.files.get(u.id);if(w){const b=new Map(v.files);b.set(u.id,{...w,previewUrl:f}),this._store.setState({files:b})}else URL.revokeObjectURL(f)});const x=document.createElement("video");x.preload="metadata",x.src=URL.createObjectURL(l),x.onerror=()=>{URL.revokeObjectURL(x.src)},x.onloadedmetadata=()=>{const f=x.duration;if(URL.revokeObjectURL(x.src),!isFinite(f))return;const v=this._store.getState(),w=v.files.get(u.id);if(w){const b=new Map(v.files);b.set(u.id,{...w,duration:f}),this._store.setState({files:b})}}}}this._store.getState().queueConfig.autoProceed&&this.upload()}_removeFile(e){var i,a,l,d;const t=this._store.getState().files.get(e);if(!t)return;const o={...t};if((this._fullscreenPreviewUrl&&this._fullscreenPreviewUrl===t.previewUrl||this._fullscreenVideoFile&&this._fullscreenVideoFile===t.file)&&(this._fullscreenPreviewUrl=null,this._fullscreenVideoFile=null),t.previewUrl&&URL.revokeObjectURL(t.previewUrl),t.file){const p=this._videoBlobUrls.get(t.file);p&&(URL.revokeObjectURL(p),this._videoBlobUrls.delete(t.file))}(t.status==="uploading"||t.status==="queued"||t.status==="retrying")&&((i=this._engine)==null||i.cancelFile(e)),me(this._store,e),this._dimCache.delete(e);const r=this._rejectedTimers.get(e);if(r&&(clearTimeout(r),this._rejectedTimers.delete(e)),this._previewFileId===e){const p=[...this._store.getState().files.values()];this._previewFileId=p.length>0?p[0].id:null}this._dispatchPublic(g.FILE_REMOVED,{file:o}),(d=(l=(a=this.config)==null?void 0:a.callbacks)==null?void 0:l.onFileRemoved)==null||d.call(l,o)}render(){var t;const e=((t=this.config)==null?void 0:t.mode)??"modal";return[...this._storeCtrl.state.files.values()],e==="modal"?s.html`
2885
3001
  ${this._isOpen&&!this._isMinimized?s.html`
2886
3002
  <div class="modal-backdrop" @click=${this._onModalBackdropClick}>
2887
3003
  <div class="modal-card">
@@ -2895,23 +3011,23 @@
2895
3011
  ${this._renderHeader()}
2896
3012
  ${this._renderBody()}
2897
3013
  </div>
2898
- `}_renderHeader(){var a,l;if(this._phase==="complete")return s.nothing;if(this._phase==="uploading"){const d=this._storeCtrl.state,c=[...d.files.values()],h=c.filter(u=>u.status==="complete").length,x=d.totalSpeed>0?(d.totalBytes-d.totalBytesUploaded)/d.totalSpeed:0;return s.html`
3014
+ `}_renderHeader(){var a,l;if(this._phase==="complete")return s.nothing;if(this._phase==="uploading"){const d=this._storeCtrl.state,p=[...d.files.values()],h=p.filter(x=>x.status==="complete").length,u=d.totalSpeed>0?(d.totalBytes-d.totalBytesUploaded)/d.totalSpeed:0;return s.html`
2899
3015
  <div class="header upload-header">
2900
3016
  <div class="float-header-left">
2901
3017
  <div class="float-icon">
2902
3018
  <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round"><polyline points="16 16 12 12 8 16"/><line x1="12" y1="12" x2="12" y2="21"/><path d="M20.39 18.39A5 5 0 0018 9h-1.26A8 8 0 103 16.3"/></svg>
2903
3019
  </div>
2904
3020
  <div>
2905
- <div class="float-title">Uploading ${c.length} ${c.length===1?"file":"files"}</div>
2906
- <div class="float-subtitle">${h} of ${c.length}${x>0?` · ~${ie(x)} left`:""}</div>
3021
+ <div class="float-title">Uploading ${p.length} ${p.length===1?"file":"files"}</div>
3022
+ <div class="float-subtitle">${h} of ${p.length}${u>0?` · ~${oe(u)} left`:""}</div>
2907
3023
  </div>
2908
3024
  </div>
2909
3025
  </div>
2910
- `}const e=((a=this.config)==null?void 0:a.mode)??"modal",t=((l=this.config)==null?void 0:l.headerButton)??(e==="modal"?"close":"none"),i=e==="modal"?this._onModalDismiss:this._onInlineDismiss,r=t==="back"?s.html`<button class="header-btn header-btn-back" aria-label="Back to Asset Picker" @click=${i}>
3026
+ `}const e=((a=this.config)==null?void 0:a.mode)??"modal",t=((l=this.config)==null?void 0:l.headerButton)??(e==="modal"?"close":"none"),o=e==="modal"?this._onModalDismiss:this._onInlineDismiss,r=t==="back"?s.html`<button class="header-btn header-btn-back" aria-label="Back to Asset Picker" @click=${o}>
2911
3027
  <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
2912
3028
  <polyline points="15 18 9 12 15 6"/>
2913
3029
  </svg>
2914
- </button>`:s.nothing,o=t==="close"?s.html`<button class="header-btn header-btn-close" aria-label="Close" @click=${i}>
3030
+ </button>`:s.nothing,i=t==="close"?s.html`<button class="header-btn header-btn-close" aria-label="Close" @click=${o}>
2915
3031
  <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round">
2916
3032
  <line x1="18" y1="6" x2="6" y2="18" />
2917
3033
  <line x1="6" y1="6" x2="18" y2="18" />
@@ -2928,31 +3044,34 @@
2928
3044
  </svg>
2929
3045
  </div>`:s.nothing}
2930
3046
  <div class="header-title">Upload Files</div>
2931
- ${o}
3047
+ ${i}
2932
3048
  </div>
2933
- `}_getImageDimensions(e){return e.previewUrl?this._dimCache.has(e.id)?Promise.resolve(this._dimCache.get(e.id)):new Promise(t=>{const i=new Image;i.onload=()=>{const r={w:i.naturalWidth,h:i.naturalHeight};this._dimCache.set(e.id,r),t(r)},i.onerror=()=>{this._dimCache.set(e.id,null),t(null)},i.src=e.previewUrl}):Promise.resolve(null)}_renderUploadOverlay(e){var a;const t=this._storeCtrl.state,i=Math.round(t.totalProgress??0),r=e.filter(l=>l.status==="complete").length,o=t.totalSpeed>0?(t.totalBytes-t.totalBytesUploaded)/t.totalSpeed:0;return s.html`
3049
+ `}_getImageDimensions(e){return e.previewUrl?this._dimCache.has(e.id)?Promise.resolve(this._dimCache.get(e.id)):new Promise(t=>{const o=new Image;o.onload=()=>{const r={w:o.naturalWidth,h:o.naturalHeight};this._dimCache.set(e.id,r),t(r)},o.onerror=()=>{this._dimCache.set(e.id,null),t(null)},o.src=e.previewUrl}):Promise.resolve(null)}_renderUploadOverlay(e){var a;const t=this._storeCtrl.state,o=Math.round(t.totalProgress??0),r=e.filter(l=>l.status==="complete").length,i=t.totalSpeed>0?(t.totalBytes-t.totalBytesUploaded)/t.totalSpeed:0;return s.html`
2934
3050
  <div class="upload-overlay">
2935
3051
  <div class="upload-overlay-spinner"></div>
2936
- <div class="upload-overlay-percent">${i}%</div>
3052
+ <div class="upload-overlay-percent">${o}%</div>
2937
3053
  <div class="upload-overlay-title">Uploading ${e.length} ${e.length===1?"file":"files"}</div>
2938
- <div class="upload-overlay-subtitle">${r} of ${e.length} complete${o>0?s.html` · ~${ie(o)} left`:s.nothing}</div>
3054
+ <div class="upload-overlay-subtitle">${r} of ${e.length} complete${i>0?s.html` · ~${oe(i)} left`:s.nothing}</div>
2939
3055
  <div class="upload-overlay-bar">
2940
- <div class="upload-overlay-bar-fill" style="width:${i}%"></div>
3056
+ <div class="upload-overlay-bar-fill" style="width:${o}%"></div>
2941
3057
  </div>
2942
3058
  ${(a=this.config)!=null&&a.minimizeOnUpload?s.html`<button class="upload-overlay-minimize" @click=${this._onMinimize}>Minimize & continue in background</button>`:s.nothing}
2943
3059
  </div>
2944
- `}_renderFloatingPill(e){const t=this._storeCtrl.state,i=Math.round(t.totalProgress??0),r=this._phase==="complete",o=e.filter(d=>d.status==="complete").length,a=e.filter(d=>d.status==="failed").length,l=t.totalSpeed>0?(t.totalBytes-t.totalBytesUploaded)/t.totalSpeed:0;return this._isPillExpanded===!1?s.html`
3060
+ `}_renderFloatingPill(e){const t=this._storeCtrl.state,o=Math.round(t.totalProgress??0),r=this._phase==="complete",i=e.filter(d=>d.status==="complete").length,a=e.filter(d=>d.status==="failed").length,l=t.totalSpeed>0?(t.totalBytes-t.totalBytesUploaded)/t.totalSpeed:0;return this._isPillExpanded===!1?s.html`
2945
3061
  <div class="upload-float float-collapsed">
2946
3062
  <div class="float-collapsed-left">
2947
- ${r?a>0?s.html`<div class="float-collapsed-icon warn"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M10.29 3.86L1.82 18a2 2 0 001.71 3h16.94a2 2 0 001.71-3L13.71 3.86a2 2 0 00-3.42 0z"/><line x1="12" y1="9" x2="12" y2="13"/><line x1="12" y1="17" x2="12.01" y2="17"/></svg></div>`:s.html`<div class="float-collapsed-icon done"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round"><polyline points="20 6 9 17 4 12"/></svg></div>`:s.html`<div class="float-collapsed-spinner"></div>`}
2948
- <span class="float-collapsed-text">${r?a>0?`${a} ${a===1?"file":"files"} not uploaded`:"Upload complete":`Uploading ${e.length} ${e.length===1?"file":"files"}`}</span>
2949
- ${r?s.nothing:s.html`<span class="float-collapsed-pct">${i}%</span>`}
3063
+ ${r?a>0?i>0?s.html`<div class="float-collapsed-icon warn"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M10.29 3.86L1.82 18a2 2 0 001.71 3h16.94a2 2 0 001.71-3L13.71 3.86a2 2 0 00-3.42 0z"/><line x1="12" y1="9" x2="12" y2="13"/><line x1="12" y1="17" x2="12.01" y2="17"/></svg></div>`:s.html`<div class="float-collapsed-icon error"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><line x1="12" y1="8" x2="12" y2="12"/><line x1="12" y1="16" x2="12.01" y2="16"/></svg></div>`:s.html`<div class="float-collapsed-icon done"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round"><polyline points="20 6 9 17 4 12"/></svg></div>`:s.html`<div class="float-collapsed-spinner"></div>`}
3064
+ <span class="float-collapsed-text">${r?a>0?i>0?"Partially uploaded":"Upload failed":"Upload complete":`Uploading ${e.length} ${e.length===1?"file":"files"}`}</span>
3065
+ ${r?s.nothing:s.html`<span class="float-collapsed-pct">${o}%</span>`}
2950
3066
  </div>
2951
3067
  <div class="float-collapsed-actions">
3068
+ <button title="Open uploader" @click=${this._onPillExpand}>
3069
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="15 3 21 3 21 9"/><polyline points="9 21 3 21 3 15"/><line x1="21" y1="3" x2="14" y2="10"/><line x1="3" y1="21" x2="10" y2="14"/></svg>
3070
+ </button>
2952
3071
  <button title="Expand" @click=${this._onPillClick}>
2953
3072
  <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round"><polyline points="18 15 12 9 6 15"/></svg>
2954
3073
  </button>
2955
- <button title="Dismiss" @click=${this._onPillDismiss}>
3074
+ <button title="Close" @click=${this._onPillDismiss}>
2956
3075
  <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg>
2957
3076
  </button>
2958
3077
  </div>
@@ -2961,19 +3080,22 @@
2961
3080
  <div class="upload-float">
2962
3081
  <div class="float-header">
2963
3082
  <div class="float-header-left">
2964
- <div class="float-icon ${r?a>0?"warn":"done":""}">
2965
- ${r?a>0?s.html`<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M10.29 3.86L1.82 18a2 2 0 001.71 3h16.94a2 2 0 001.71-3L13.71 3.86a2 2 0 00-3.42 0z"/><line x1="12" y1="9" x2="12" y2="13"/><line x1="12" y1="17" x2="12.01" y2="17"/></svg>`:s.html`<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round"><polyline points="20 6 9 17 4 12"/></svg>`:s.html`<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round"><polyline points="16 16 12 12 8 16"/><line x1="12" y1="12" x2="12" y2="21"/><path d="M20.39 18.39A5 5 0 0018 9h-1.26A8 8 0 103 16.3"/></svg>`}
3083
+ <div class="float-icon ${r?a>0?i>0?"warn":"error":"done":""}">
3084
+ ${r?a>0?i>0?s.html`<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M10.29 3.86L1.82 18a2 2 0 001.71 3h16.94a2 2 0 001.71-3L13.71 3.86a2 2 0 00-3.42 0z"/><line x1="12" y1="9" x2="12" y2="13"/><line x1="12" y1="17" x2="12.01" y2="17"/></svg>`:s.html`<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><line x1="12" y1="8" x2="12" y2="12"/><line x1="12" y1="16" x2="12.01" y2="16"/></svg>`:s.html`<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round"><polyline points="20 6 9 17 4 12"/></svg>`:s.html`<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round"><polyline points="16 16 12 12 8 16"/><line x1="12" y1="12" x2="12" y2="21"/><path d="M20.39 18.39A5 5 0 0018 9h-1.26A8 8 0 103 16.3"/></svg>`}
2966
3085
  </div>
2967
3086
  <div>
2968
- <div class="float-title">${r?a>0?`${a} ${a===1?"file":"files"} not uploaded`:"Upload complete":`Uploading ${e.length} ${e.length===1?"file":"files"}`}</div>
2969
- <div class="float-subtitle">${r?`${o} ${o===1?"file":"files"} uploaded${a>0?`, ${a} failed`:""}`:`${o} of ${e.length}${l>0?` · ~${ie(l)} left`:""}`}</div>
3087
+ <div class="float-title">${r?a>0?i>0?"Partially uploaded":"Upload failed":"Upload complete":`Uploading ${e.length} ${e.length===1?"file":"files"}`}</div>
3088
+ <div class="float-subtitle">${r?`${i} ${i===1?"file":"files"} uploaded${a>0?`, ${a} failed`:""}`:`${i} of ${e.length}${l>0?` · ~${oe(l)} left`:""}`}</div>
2970
3089
  </div>
2971
3090
  </div>
2972
3091
  <div class="float-actions">
3092
+ <button title="Expand" @click=${this._onPillExpand}>
3093
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="15 3 21 3 21 9"/><polyline points="9 21 3 21 3 15"/><line x1="21" y1="3" x2="14" y2="10"/><line x1="3" y1="21" x2="10" y2="14"/></svg>
3094
+ </button>
2973
3095
  <button title="Collapse" @click=${this._onPillClick}>
2974
3096
  <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round"><polyline points="6 9 12 15 18 9"/></svg>
2975
3097
  </button>
2976
- <button title="Dismiss" @click=${this._onPillDismiss}>
3098
+ <button title="Close" @click=${this._onPillDismiss}>
2977
3099
  <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg>
2978
3100
  </button>
2979
3101
  </div>
@@ -2981,33 +3103,40 @@
2981
3103
  <div class="float-progress">
2982
3104
  <div class="float-progress-top">
2983
3105
  <span class="float-progress-label">Overall progress</span>
2984
- <span class="float-progress-pct ${r?a>0?"warn":"done":""}">${r?"Done":`${i}%`}</span>
3106
+ <span class="float-progress-pct ${r?a>0?i>0?"warn":"error":"done":""}">${r?"Done":`${o}%`}</span>
2985
3107
  </div>
2986
- <div class="float-bar"><div class="float-bar-fill ${r?a>0?"warn":"done":""}" style="width:${r?100:i}%"></div></div>
3108
+ <div class="float-bar"><div class="float-bar-fill ${r?a>0?i>0?"warn":"error":"done":""}" style="width:${r?100:o}%"></div></div>
2987
3109
  </div>
2988
3110
  <div class="float-items">
2989
- ${e.map(d=>s.html`
3111
+ ${e.map(d=>{const p=d.status==="failed"||d.status==="error";return s.html`
2990
3112
  <div class="float-item">
2991
- <div class="float-item-thumb">
2992
- <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5"><rect x="3" y="3" width="18" height="18" rx="2"/><circle cx="8.5" cy="8.5" r="1.5"/><path d="m21 15-3.086-3.086a2 2 0 0 0-2.828 0L6 21"/></svg>
3113
+ <div class="float-item-thumb" style=${d.previewUrl?`background-image:url(${d.previewUrl});background-size:cover;background-position:center`:""}>
3114
+ ${d.previewUrl?s.nothing:s.html`<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5"><rect x="3" y="3" width="18" height="18" rx="2"/><circle cx="8.5" cy="8.5" r="1.5"/><path d="m21 15-3.086-3.086a2 2 0 0 0-2.828 0L6 21"/></svg>`}
2993
3115
  </div>
2994
3116
  <div class="float-item-info">
2995
3117
  <div class="float-item-name">${d.name}</div>
2996
- <div class="float-item-size">${R(d.size)}</div>
3118
+ <div class="float-item-size">${B(d.size)}</div>
2997
3119
  </div>
2998
3120
  <div class="float-item-status">
2999
- ${d.status==="complete"?s.html`<div class="float-item-done"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round"><polyline points="20 6 9 17 4 12"/></svg></div>`:d.status==="failed"||d.status==="error"?s.html`<svg class="float-item-error" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><title>${d.error||"Upload failed"}</title><circle cx="12" cy="12" r="10"/><line x1="12" y1="8" x2="12" y2="12"/><line x1="12" y1="16" x2="12.01" y2="16"/></svg>`:s.html`<div class="float-item-spinner"></div>`}
3121
+ ${d.status==="complete"?s.html`<div class="float-item-done"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round"><polyline points="20 6 9 17 4 12"/></svg></div>`:p?s.html`
3122
+ <div class="float-item-error-wrap">
3123
+ <svg class="float-item-error-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><line x1="12" y1="8" x2="12" y2="12"/><line x1="12" y1="16" x2="12.01" y2="16"/></svg>
3124
+ <span class="float-item-tooltip">${d.error||"Upload failed"}</span>
3125
+ </div>
3126
+ <button class="float-item-retry" @click=${()=>{var h;this._ensureEngine(),(h=this._engine)==null||h.retryFile(d.id)}}>
3127
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 2v6h-6"/><path d="M3 12a9 9 0 0 1 15-6.7L21 8"/><path d="M3 22v-6h6"/><path d="M21 12a9 9 0 0 1-15 6.7L3 16"/></svg>
3128
+ </button>`:s.html`<div class="float-item-spinner"></div>`}
3000
3129
  </div>
3001
3130
  </div>
3002
- `)}
3131
+ `})}
3003
3132
  </div>
3004
3133
  </div>
3005
- `}_renderPreviewLayout(e){var l;if(e.length===0)return s.nothing;const t=e.find(d=>d.id===this._previewFileId)??e[0],i=((l=t.name.split(".").pop())==null?void 0:l.toUpperCase())||"",r=new Date(t.addedAt).toLocaleDateString("en-US",{month:"short",day:"numeric",year:"numeric"}),o=this._store.getState().targetFolder,a=e.reduce((d,c)=>d+(c.size||0),0);return s.html`
3134
+ `}_renderPreviewLayout(e){var l;if(e.length===0)return s.nothing;const t=e.find(d=>d.id===this._previewFileId)??e[0],o=((l=t.name.split(".").pop())==null?void 0:l.toUpperCase())||"",r=new Date(t.addedAt).toLocaleDateString("en-US",{month:"short",day:"numeric",year:"numeric"}),i=this._store.getState().targetFolder,a=e.reduce((d,p)=>d+(p.size||0),0);return s.html`
3006
3135
  <div class="preview-topbar"></div>
3007
3136
  <div class="preview-layout">
3008
- <div class="file-grid-side">
3137
+ <div class="file-grid-side" style="flex:${this._splitPct}">
3009
3138
  <div class="file-grid-header">
3010
- <span class="file-grid-header-text">${e.length} ${e.length===1?"asset":"assets"} · ${R(a)}</span>
3139
+ <span class="file-grid-header-text">${e.length} ${e.length===1?"asset":"assets"} · ${B(a)}</span>
3011
3140
  </div>
3012
3141
  <sfx-file-list
3013
3142
  .files=${e}
@@ -3017,8 +3146,13 @@
3017
3146
  @source-click=${this._onDropTileSourceClick}
3018
3147
  ></sfx-file-list>
3019
3148
  </div>
3020
- <div class="preview-divider"></div>
3021
- <div class="preview-panel">
3149
+ <div class="preview-divider"
3150
+ @pointerdown=${this._onSplitPointerDown}
3151
+ @pointermove=${this._onSplitPointerMove}
3152
+ @pointerup=${this._onSplitPointerUp}
3153
+ @lostpointercapture=${this._onSplitPointerUp}
3154
+ ></div>
3155
+ <div class="preview-panel" style="flex:${100-this._splitPct}">
3022
3156
  <div class="preview-panel-header">
3023
3157
  <span class="preview-panel-filename" title=${t.name}>${t.name}</span>
3024
3158
  <div class="preview-header-actions">
@@ -3064,7 +3198,7 @@
3064
3198
  <div class="preview-doc-wrap ${q(t)}">
3065
3199
  <div class="preview-doc-icon ${q(t)}">
3066
3200
  ${this._renderDocTypeIcon(q(t))}
3067
- <span class="preview-doc-ext ${q(t)}">${i}</span>
3201
+ <span class="preview-doc-ext ${q(t)}">${o}</span>
3068
3202
  </div>
3069
3203
  <button class="preview-nav prev" ?disabled=${e.indexOf(t)===0} @click=${()=>this._navigatePreview(e,-1)}>
3070
3204
  <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round"><polyline points="15 18 9 12 15 6"/></svg>
@@ -3077,11 +3211,11 @@
3077
3211
  <div class="preview-meta-list">
3078
3212
  <div class="preview-meta-row">
3079
3213
  <span class="preview-meta-label">Type</span>
3080
- <span class="preview-meta-value">${i}</span>
3214
+ <span class="preview-meta-value">${o}</span>
3081
3215
  </div>
3082
3216
  <div class="preview-meta-row">
3083
3217
  <span class="preview-meta-label">Size</span>
3084
- <span class="preview-meta-value">${R(t.size)}</span>
3218
+ <span class="preview-meta-value">${B(t.size)}</span>
3085
3219
  </div>
3086
3220
  <div class="preview-meta-row">
3087
3221
  <span class="preview-meta-label">Dimensions</span>
@@ -3091,10 +3225,10 @@
3091
3225
  <span class="preview-meta-label">Name</span>
3092
3226
  <span class="preview-meta-value truncate" title=${t.name}>${t.name}</span>
3093
3227
  </div>
3094
- ${o?s.html`
3228
+ ${i?s.html`
3095
3229
  <div class="preview-meta-row">
3096
3230
  <span class="preview-meta-label">Folder</span>
3097
- <span class="preview-meta-value">${o}</span>
3231
+ <span class="preview-meta-value">${i}</span>
3098
3232
  </div>`:s.html`
3099
3233
  <div class="preview-meta-row">
3100
3234
  <span class="preview-meta-label">Added</span>
@@ -3103,7 +3237,7 @@
3103
3237
  </div>
3104
3238
  </div>
3105
3239
  </div>
3106
- `}_renderDocTypeIcon(e){switch(e){case"pdf":return s.html`<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"><path d="M14 2H6a2 2 0 00-2 2v16a2 2 0 002 2h12a2 2 0 002-2V8z"/><polyline points="14 2 14 8 20 8"/></svg>`;case"doc":return s.html`<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"><path d="M14 2H6a2 2 0 00-2 2v16a2 2 0 002 2h12a2 2 0 002-2V8z"/><polyline points="14 2 14 8 20 8"/><line x1="16" y1="13" x2="8" y2="13"/><line x1="16" y1="17" x2="8" y2="17"/></svg>`;case"vid":return s.html`<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"><polygon points="23 7 16 12 23 17 23 7"/><rect x="1" y="5" width="15" height="14" rx="2"/></svg>`;case"zip":return s.html`<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"><path d="M21 8v13H3V8"/><path d="M1 3h22v5H1z"/><path d="M10 12h4"/></svg>`;default:return s.html`<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"><path d="M13 2H6a2 2 0 00-2 2v16a2 2 0 002 2h12a2 2 0 002-2V9z"/><polyline points="13 2 13 9 20 9"/></svg>`}}_navigatePreview(e,t){var o;const r=e.findIndex(a=>a.id===this._previewFileId)+t;if(r>=0&&r<e.length){const a=(o=this.shadowRoot)==null?void 0:o.querySelector(".preview-image[controls]");a&&(a.pause(),a.removeAttribute("src"),a.load()),this._previewFileId=e[r].id}}_renderBody(){var a,l,d;const e=this._storeCtrl.state,t=[...e.files.values()],i=this._phase,r=ye(e.restrictions),o=t.length>0;return s.html`
3240
+ `}_renderDocTypeIcon(e){switch(e){case"pdf":return s.html`<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"><path d="M14 2H6a2 2 0 00-2 2v16a2 2 0 002 2h12a2 2 0 002-2V8z"/><polyline points="14 2 14 8 20 8"/></svg>`;case"doc":return s.html`<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"><path d="M14 2H6a2 2 0 00-2 2v16a2 2 0 002 2h12a2 2 0 002-2V8z"/><polyline points="14 2 14 8 20 8"/><line x1="16" y1="13" x2="8" y2="13"/><line x1="16" y1="17" x2="8" y2="17"/></svg>`;case"vid":return s.html`<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"><polygon points="23 7 16 12 23 17 23 7"/><rect x="1" y="5" width="15" height="14" rx="2"/></svg>`;case"zip":return s.html`<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"><path d="M21 8v13H3V8"/><path d="M1 3h22v5H1z"/><path d="M10 12h4"/></svg>`;default:return s.html`<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"><path d="M13 2H6a2 2 0 00-2 2v16a2 2 0 002 2h12a2 2 0 002-2V9z"/><polyline points="13 2 13 9 20 9"/></svg>`}}_navigatePreview(e,t){var i;const r=e.findIndex(a=>a.id===this._previewFileId)+t;if(r>=0&&r<e.length){const a=(i=this.shadowRoot)==null?void 0:i.querySelector(".preview-image[controls]");a&&(a.pause(),a.removeAttribute("src"),a.load()),this._previewFileId=e[r].id}}_renderBody(){var a,l,d;const e=this._storeCtrl.state,t=[...e.files.values()],o=this._phase,r=ye(e.restrictions),i=t.length>0;return s.html`
3107
3241
  <div class="content"
3108
3242
  @files-selected=${this._onFilesSelected}
3109
3243
  @source-click=${this._onSourceClick}
@@ -3127,30 +3261,33 @@
3127
3261
  @screencast-cancel=${this._onScreenCastCancel}
3128
3262
  >
3129
3263
  <div
3130
- class="body ${o?"has-files":""} ${this._bodyDragOver?"body-drag-over":""}"
3131
- @dragenter=${o?this._onBodyDragEnter:s.nothing}
3132
- @dragover=${o?this._onBodyDragOver:s.nothing}
3133
- @dragleave=${o?this._onBodyDragLeave:s.nothing}
3134
- @drop=${o?this._onBodyDrop:s.nothing}
3264
+ class="body ${i?"has-files":""} ${this._bodyDragOver?"body-drag-over":""}"
3265
+ @dragenter=${i?this._onBodyDragEnter:s.nothing}
3266
+ @dragover=${i?this._onBodyDragOver:s.nothing}
3267
+ @dragleave=${i?this._onBodyDragLeave:s.nothing}
3268
+ @drop=${i?this._onBodyDrop:s.nothing}
3135
3269
  >
3136
- ${i==="complete"?s.html`
3270
+ ${o==="complete"?s.html`
3137
3271
  <sfx-success-card
3138
- .fileCount=${t.filter(c=>c.status==="complete").length}
3139
- .totalSize=${t.filter(c=>c.status==="complete").reduce((c,h)=>c+(h.size||0),0)}
3140
- .thumbnails=${t.filter(c=>c.status==="complete"&&c.previewUrl).map(c=>c.previewUrl)}
3141
- .failedFiles=${t.filter(c=>c.status==="failed").map(c=>({name:c.name,error:c.error||"Upload failed"}))}
3272
+ .fileCount=${t.filter(p=>p.status==="complete").length}
3273
+ .totalSize=${t.filter(p=>p.status==="complete").reduce((p,h)=>p+(h.size||0),0)}
3274
+ .thumbnails=${t.filter(p=>p.status==="complete"&&p.previewUrl).map(p=>p.previewUrl)}
3275
+ .failedFiles=${t.filter(p=>p.status==="failed").map(p=>({id:p.id,name:p.name,error:p.error||"Upload failed"}))}
3276
+ @close-uploader=${this._onSuccessCardClose}
3277
+ @file-retry=${this._onFileRetry}
3278
+ @retry-all=${this._onRetryAll}
3142
3279
  ></sfx-success-card>
3143
- `:i==="uploading"?this._renderUploadOverlay(t):s.html`
3144
- ${o?s.nothing:s.html`<sfx-drop-zone
3145
- .compact=${o}
3280
+ `:o==="uploading"?this._renderUploadOverlay(t):s.html`
3281
+ ${i?s.nothing:s.html`<sfx-drop-zone
3282
+ .compact=${i}
3146
3283
  .externalDragOver=${this._bodyDragOver}
3147
3284
  .accept=${r}
3148
3285
  .sources=${this._mergedSources}
3149
3286
  .sourcesLayout=${((a=this.config)==null?void 0:a.sourcesLayout)??"pills"}
3150
3287
  ></sfx-drop-zone>`}
3151
3288
 
3152
- ${o?this._previewFileId?this._renderPreviewLayout(t):s.html`
3153
- <div class="asset-count">${t.length} ${t.length===1?"file":"files"} · ${R(t.reduce((c,h)=>c+(h.size||0),0))}</div>
3289
+ ${i?this._previewFileId?this._renderPreviewLayout(t):s.html`
3290
+ <div class="asset-count">${t.length} ${t.length===1?"file":"files"} · ${B(t.reduce((p,h)=>p+(h.size||0),0))}</div>
3154
3291
  <sfx-file-list
3155
3292
  .files=${t}
3156
3293
  .showDropTile=${!0}
@@ -3162,13 +3299,13 @@
3162
3299
  `}
3163
3300
  </div>
3164
3301
 
3165
- ${o&&i!=="complete"&&i!=="uploading"?s.html`
3302
+ ${i&&o!=="complete"&&o!=="uploading"?s.html`
3166
3303
  <sfx-actions-bar
3167
3304
  .uploadState=${"idle"}
3168
3305
  .fileCount=${t.length}
3169
- .totalSize=${t.reduce((c,h)=>c+(h.size||0),0)}
3170
- .failedCount=${t.filter(c=>c.status==="failed"||c.status==="error").length}
3171
- .completedCount=${t.filter(c=>c.status==="complete").length}
3306
+ .totalSize=${t.reduce((p,h)=>p+(h.size||0),0)}
3307
+ .failedCount=${t.filter(p=>p.status==="failed"||p.status==="error").length}
3308
+ .completedCount=${t.filter(p=>p.status==="complete").length}
3172
3309
  .uploadProgress=${e.totalProgress??0}
3173
3310
  .showFillMetadata=${!!((l=this.config)!=null&&l.showFillMetadata)}
3174
3311
  ></sfx-actions-bar>
@@ -3207,7 +3344,7 @@
3207
3344
  @touchmove=${this._onFsTouchMove}
3208
3345
  @touchend=${this._onFsPanEnd}
3209
3346
  >
3210
- <div class="fs-toolbar" @click=${c=>c.stopPropagation()}>
3347
+ <div class="fs-toolbar" @click=${p=>p.stopPropagation()}>
3211
3348
  <button class="fs-btn" @click=${this._onFsToggleZoom} title="${this._fullscreenZoomed?"Zoom out":"Zoom in"}">
3212
3349
  ${this._fullscreenZoomed?s.html`<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><circle cx="11" cy="11" r="8"/><line x1="21" y1="21" x2="16.65" y2="16.65"/><line x1="8" y1="11" x2="14" y2="11"/></svg>`:s.html`<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><circle cx="11" cy="11" r="8"/><line x1="21" y1="21" x2="16.65" y2="16.65"/><line x1="11" y1="8" x2="11" y2="14"/><line x1="8" y1="11" x2="14" y2="11"/></svg>`}
3213
3350
  </button>
@@ -3222,7 +3359,7 @@
3222
3359
  src=${this._getVideoBlobUrl(this._fullscreenVideoFile)}
3223
3360
  controls playsinline
3224
3361
  draggable="false"
3225
- @click=${c=>c.stopPropagation()}
3362
+ @click=${p=>p.stopPropagation()}
3226
3363
  ></video>`:s.html`<img
3227
3364
  class="fs-img"
3228
3365
  src=${this._fullscreenPreviewUrl}
@@ -3230,16 +3367,16 @@
3230
3367
  style=${this._fullscreenZoomed?`transform: scale(2) translate(${this._fsPanX}px, ${this._fsPanY}px)`:""}
3231
3368
  draggable="false"
3232
3369
  />`}
3233
- <button class="fs-nav prev" @click=${c=>{c.stopPropagation(),this._navigateFs(-1)}}>
3370
+ <button class="fs-nav prev" @click=${p=>{p.stopPropagation(),this._navigateFs(-1)}}>
3234
3371
  <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round"><polyline points="15 18 9 12 15 6"/></svg>
3235
3372
  </button>
3236
- <button class="fs-nav next" @click=${c=>{c.stopPropagation(),this._navigateFs(1)}}>
3373
+ <button class="fs-nav next" @click=${p=>{p.stopPropagation(),this._navigateFs(1)}}>
3237
3374
  <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round"><polyline points="9 6 15 12 9 18"/></svg>
3238
3375
  </button>
3239
3376
  </div>
3240
3377
  `:s.nothing}
3241
3378
  </div>
3242
- `}_navigateFs(e){const t=[...this._store.getState().files.values()].filter(o=>o.previewUrl||o.type.startsWith("video/")&&o.file),i=t.findIndex(o=>o.id===this._previewFileId);if(i===-1)return;const r=i+e;if(r>=0&&r<t.length){const o=t[r];this._fullscreenPreviewUrl=o.previewUrl,this._fullscreenVideoFile=o.type.startsWith("video/")&&o.file?o.file:null,this._previewFileId=o.id,this._fullscreenZoomed=!1,this._fsPanX=0,this._fsPanY=0}}_getVideoBlobUrl(e){let t=this._videoBlobUrls.get(e);return t||(t=URL.createObjectURL(e),this._videoBlobUrls.set(e,t)),t}_revokeVideoBlobUrls(){for(const e of this._videoBlobUrls.values())URL.revokeObjectURL(e);this._videoBlobUrls.clear()}},$.styles=s.css`
3379
+ `}_navigateFs(e){const t=[...this._store.getState().files.values()].filter(i=>i.previewUrl||i.type.startsWith("video/")&&i.file),o=t.findIndex(i=>i.id===this._previewFileId);if(o===-1)return;const r=o+e;if(r>=0&&r<t.length){const i=t[r];this._fullscreenPreviewUrl=i.previewUrl,this._fullscreenVideoFile=i.type.startsWith("video/")&&i.file?i.file:null,this._previewFileId=i.id,this._fullscreenZoomed=!1,this._fsPanX=0,this._fsPanY=0}}_getVideoBlobUrl(e){let t=this._videoBlobUrls.get(e);return t||(t=URL.createObjectURL(e),this._videoBlobUrls.set(e,t)),t}_revokeVideoBlobUrls(){for(const e of this._videoBlobUrls.values())URL.revokeObjectURL(e);this._videoBlobUrls.clear()}},$.styles=s.css`
3243
3380
  :host {
3244
3381
  display: block;
3245
3382
  font-family: var(--sfx-up-font, 'Inter', system-ui, -apple-system, sans-serif);
@@ -3265,6 +3402,8 @@
3265
3402
  --sfx-up-backdrop: rgba(0, 0, 0, 0.45);
3266
3403
  --sfx-up-ring: var(--ring, oklch(0.578 0.198 268.129 / 0.7));
3267
3404
  --sfx-up-max-height: 88vh;
3405
+ --sfx-up-checker-bg: #fff;
3406
+ --sfx-up-checker-tile: #f0f0f0;
3268
3407
  }
3269
3408
 
3270
3409
  /* --- Modal overlay --- */
@@ -3525,30 +3664,22 @@
3525
3664
  }
3526
3665
 
3527
3666
  .preview-layout .file-grid-side {
3528
- flex: 54;
3667
+ flex: 68;
3529
3668
  min-width: 0;
3530
3669
  min-height: 100%;
3531
3670
  overflow: hidden;
3532
3671
  display: flex;
3533
3672
  flex-direction: column;
3534
3673
  position: relative;
3535
- --sfx-up-grid-min: max(48%, 140px);
3674
+ --sfx-up-grid-min: max(30%, 140px);
3536
3675
  }
3537
3676
 
3538
3677
  .preview-layout .file-grid-side::after {
3539
- content: '';
3540
- position: absolute;
3541
- top: 0;
3542
- bottom: 0;
3543
- right: 14px;
3544
- width: 1px;
3545
- background: var(--sfx-up-border, #e8edf5);
3546
- pointer-events: none;
3547
- z-index: 3;
3678
+ display: none;
3548
3679
  }
3549
3680
 
3550
3681
  .preview-layout sfx-file-list {
3551
- padding-right: 16px;
3682
+ padding-right: 6px;
3552
3683
  --sfx-scrollbar-w: 14px;
3553
3684
  --sfx-scrollbar-inset-left: 2px;
3554
3685
  --sfx-scrollbar-inset-right: 6px;
@@ -3586,21 +3717,59 @@
3586
3717
  }
3587
3718
 
3588
3719
  .preview-divider {
3589
- width: 1px;
3590
- background: var(--sfx-up-border, #e8edf5);
3720
+ width: 9px;
3591
3721
  flex-shrink: 0;
3592
3722
  position: relative;
3593
3723
  display: flex;
3594
3724
  align-items: center;
3595
3725
  justify-content: center;
3726
+ cursor: col-resize;
3727
+ user-select: none;
3728
+ -webkit-user-select: none;
3729
+ }
3730
+
3731
+ .preview-divider::before {
3732
+ content: '';
3733
+ position: absolute;
3734
+ top: 0;
3735
+ bottom: 0;
3736
+ left: 4px;
3737
+ width: 1px;
3738
+ background: var(--sfx-up-border, #e8edf5);
3596
3739
  }
3597
3740
 
3598
3741
  .preview-divider::after {
3599
- display: none;
3742
+ content: '';
3743
+ width: 3px;
3744
+ height: 28px;
3745
+ border-radius: 2px;
3746
+ background: var(--sfx-up-border, #d0d7e2);
3747
+ opacity: 0;
3748
+ transition: opacity 0.15s;
3749
+ z-index: 1;
3750
+ }
3751
+
3752
+ .preview-divider:hover::after,
3753
+ .preview-layout.resizing .preview-divider::after {
3754
+ opacity: 1;
3755
+ }
3756
+
3757
+ .preview-layout.resizing {
3758
+ cursor: col-resize;
3759
+ user-select: none;
3760
+ -webkit-user-select: none;
3761
+ }
3762
+
3763
+ .preview-layout.resizing * {
3764
+ pointer-events: none;
3765
+ }
3766
+
3767
+ .preview-layout.resizing .preview-divider {
3768
+ pointer-events: auto;
3600
3769
  }
3601
3770
 
3602
3771
  .preview-panel {
3603
- flex: 46;
3772
+ flex: 32;
3604
3773
  min-width: 0;
3605
3774
  display: flex;
3606
3775
  flex-direction: column;
@@ -3735,7 +3904,14 @@
3735
3904
  position: relative;
3736
3905
  flex: 1;
3737
3906
  min-height: 0;
3738
- background: var(--sfx-up-surface, #f1f5f9);
3907
+ background-color: var(--sfx-up-checker-bg);
3908
+ background-image:
3909
+ linear-gradient(45deg, var(--sfx-up-checker-tile) 25%, transparent 25%),
3910
+ linear-gradient(-45deg, var(--sfx-up-checker-tile) 25%, transparent 25%),
3911
+ linear-gradient(45deg, transparent 75%, var(--sfx-up-checker-tile) 75%),
3912
+ linear-gradient(-45deg, transparent 75%, var(--sfx-up-checker-tile) 75%);
3913
+ background-size: 16px 16px;
3914
+ background-position: 0 0, 0 8px, 8px -8px, -8px 0;
3739
3915
  }
3740
3916
 
3741
3917
  .preview-image {
@@ -3839,6 +4015,7 @@
3839
4015
  flex: 1;
3840
4016
  gap: 8px;
3841
4017
  padding: 32px 24px;
4018
+ position: relative;
3842
4019
  animation: fadeUp 0.3s ease both;
3843
4020
  }
3844
4021
 
@@ -3943,7 +4120,7 @@
3943
4120
  bottom: 24px;
3944
4121
  right: 24px;
3945
4122
  z-index: 10000;
3946
- width: 320px;
4123
+ width: 470px;
3947
4124
  border-radius: 12px;
3948
4125
  background: var(--sfx-up-bg, #fff);
3949
4126
  box-shadow: 0 8px 32px rgba(0,0,0,0.12), 0 2px 8px rgba(0,0,0,0.06);
@@ -3985,6 +4162,11 @@
3985
4162
  color: #22c55e;
3986
4163
  }
3987
4164
 
4165
+ .float-icon.error {
4166
+ background: #fef2f2;
4167
+ color: #ef4444;
4168
+ }
4169
+
3988
4170
  .float-title {
3989
4171
  font-size: 13px;
3990
4172
  font-weight: 600;
@@ -4046,9 +4228,9 @@
4046
4228
  color: var(--sfx-up-primary, #2563eb);
4047
4229
  }
4048
4230
 
4049
- .float-progress-pct.done {
4050
- color: #22c55e;
4051
- }
4231
+ .float-progress-pct.done { color: #22c55e; }
4232
+ .float-progress-pct.warn { color: #f59e0b; }
4233
+ .float-progress-pct.error { color: #ef4444; }
4052
4234
 
4053
4235
  .float-bar {
4054
4236
  height: 4px;
@@ -4064,13 +4246,14 @@
4064
4246
  transition: width 0.3s ease;
4065
4247
  }
4066
4248
 
4067
- .float-bar-fill.done {
4068
- background: #22c55e;
4069
- }
4249
+ .float-bar-fill.done { background: #22c55e; }
4250
+ .float-bar-fill.warn { background: #f59e0b; }
4251
+ .float-bar-fill.error { background: #ef4444; }
4070
4252
 
4071
4253
  .float-items {
4072
4254
  max-height: 200px;
4073
4255
  overflow-y: auto;
4256
+ overflow-x: hidden;
4074
4257
  scrollbar-width: thin;
4075
4258
  scrollbar-color: rgba(0,0,0,0.1) transparent;
4076
4259
  }
@@ -4081,6 +4264,7 @@
4081
4264
  gap: 10px;
4082
4265
  padding: 8px 14px;
4083
4266
  border-bottom: 1px solid #f1f5f9;
4267
+ overflow: hidden;
4084
4268
  }
4085
4269
 
4086
4270
  .float-item:last-child { border-bottom: none; }
@@ -4099,7 +4283,7 @@
4099
4283
 
4100
4284
  .float-item-thumb svg { width: 16px; height: 16px; }
4101
4285
 
4102
- .float-item-info { flex: 1; min-width: 0; }
4286
+ .float-item-info { flex: 1; min-width: 0; overflow: hidden; }
4103
4287
 
4104
4288
  .float-item-name {
4105
4289
  font-size: 12px;
@@ -4139,13 +4323,69 @@
4139
4323
  flex-shrink: 0;
4140
4324
  }
4141
4325
 
4142
- .float-item-error {
4143
- color: #ef4444;
4326
+ .float-item-error-wrap {
4327
+ position: relative;
4328
+ display: flex;
4329
+ align-items: center;
4330
+ flex-shrink: 0;
4331
+ }
4332
+
4333
+ .float-item-error-icon {
4144
4334
  width: 16px;
4145
4335
  height: 16px;
4336
+ color: #ef4444;
4337
+ flex-shrink: 0;
4338
+ cursor: pointer;
4339
+ }
4340
+
4341
+ .float-item-tooltip {
4342
+ display: none;
4343
+ position: absolute;
4344
+ right: calc(100% + 8px);
4345
+ top: 50%;
4346
+ transform: translateY(-50%);
4347
+ background: #fff;
4348
+ color: #1e293b;
4349
+ font-size: 11px;
4350
+ padding: 6px 10px;
4351
+ border-radius: 6px;
4352
+ white-space: nowrap;
4353
+ pointer-events: none;
4354
+ z-index: 10;
4355
+ box-shadow: 0 2px 12px rgba(0,0,0,0.12), 0 1px 4px rgba(0,0,0,0.08);
4356
+ }
4357
+
4358
+ .float-item-error-wrap:hover .float-item-tooltip {
4359
+ display: block;
4360
+ }
4361
+
4362
+ .float-item-status {
4363
+ display: flex;
4364
+ flex-direction: row;
4365
+ align-items: center;
4366
+ gap: 4px;
4146
4367
  flex-shrink: 0;
4147
4368
  }
4148
4369
 
4370
+ .float-item-retry {
4371
+ width: 24px;
4372
+ height: 24px;
4373
+ border: none;
4374
+ background: none;
4375
+ color: var(--sfx-up-primary, #2563eb);
4376
+ cursor: pointer;
4377
+ padding: 4px;
4378
+ flex-shrink: 0;
4379
+ display: flex;
4380
+ align-items: center;
4381
+ justify-content: center;
4382
+ border-radius: 4px;
4383
+ }
4384
+
4385
+ .float-item-retry svg { width: 16px; height: 16px; }
4386
+
4387
+ .float-item-retry:hover { background: var(--sfx-up-surface, #f8fafc); color: var(--sfx-up-primary-hover, #1d4ed8); }
4388
+
4149
4389
  @keyframes floatSlideIn {
4150
4390
  from { opacity: 0; transform: translateY(20px); }
4151
4391
  to { opacity: 1; transform: translateY(0); }
@@ -4404,4 +4644,4 @@
4404
4644
  .modal-card { min-height: auto; }
4405
4645
  .inline { min-height: auto; }
4406
4646
  }
4407
- `,$._MODIFIABLE_STATUSES=new Set(["idle","queued","rejected"]),$._RESERVED_IDS=new Set(["device","camera","url","screen-cast"]),$);k([p.property({attribute:!1})],_.prototype,"config");k([p.state()],_.prototype,"_isOpen");k([p.state()],_.prototype,"_activeConnector");k([p.state()],_.prototype,"_showUrlDialog");k([p.state()],_.prototype,"_showCameraDialog");k([p.state()],_.prototype,"_showScreenCastDialog");k([p.state()],_.prototype,"_previewFileId");k([p.state()],_.prototype,"_previewDims");k([p.state()],_.prototype,"_fullscreenPreviewUrl");k([p.state()],_.prototype,"_fullscreenVideoFile");k([p.state()],_.prototype,"_fullscreenZoomed");k([p.state()],_.prototype,"_bodyDragOver");k([p.state()],_.prototype,"_isMinimized");k([p.state()],_.prototype,"_isPillExpanded");let ht=_;exports.AuthExpiredError=ee;exports.CORE_SOURCES=A;exports.PublicEvents=g;exports.SfxActionsBar=z;exports.SfxCameraDialog=j;exports.SfxDropZone=C;exports.SfxFileItem=J;exports.SfxFileList=F;exports.SfxImportDivider=se;exports.SfxScreenCastDialog=T;exports.SfxSourcePills=Z;exports.SfxSuccessCard=O;exports.SfxUploader=ht;exports.SfxUrlDialog=I;exports.Store=Se;exports.UploadEngine=Ue;exports.buildAuthHeaders=K;exports.createStore=Ee;exports.exchangeSassKey=ze;exports.getApiBase=te;exports.getAuthUrl=Le;exports.getProviderSources=De;exports.listFiles=Me;exports.listNextPage=Be;exports.logout=Ie;exports.resolveAuth=Pe;exports.searchProvider=Re;
4647
+ `,$._MODIFIABLE_STATUSES=new Set(["idle","queued","rejected"]),$._RESERVED_IDS=new Set(["device","camera","url","screen-cast"]),$);k([c.property({attribute:!1})],y.prototype,"config");k([c.state()],y.prototype,"_isOpen");k([c.state()],y.prototype,"_activeConnector");k([c.state()],y.prototype,"_showUrlDialog");k([c.state()],y.prototype,"_showCameraDialog");k([c.state()],y.prototype,"_showScreenCastDialog");k([c.state()],y.prototype,"_previewFileId");k([c.state()],y.prototype,"_previewDims");k([c.state()],y.prototype,"_splitPct");k([c.state()],y.prototype,"_fullscreenPreviewUrl");k([c.state()],y.prototype,"_fullscreenVideoFile");k([c.state()],y.prototype,"_fullscreenZoomed");k([c.state()],y.prototype,"_bodyDragOver");k([c.state()],y.prototype,"_isMinimized");k([c.state()],y.prototype,"_isPillExpanded");let ht=y;exports.AuthExpiredError=ee;exports.CORE_SOURCES=A;exports.PublicEvents=g;exports.SfxActionsBar=P;exports.SfxCameraDialog=M;exports.SfxDropZone=C;exports.SfxFileItem=J;exports.SfxFileList=D;exports.SfxImportDivider=se;exports.SfxScreenCastDialog=j;exports.SfxSourcePills=Z;exports.SfxSuccessCard=F;exports.SfxUploader=ht;exports.SfxUrlDialog=I;exports.Store=Se;exports.UploadEngine=Pe;exports.buildAuthHeaders=K;exports.createStore=Ee;exports.exchangeSassKey=Ue;exports.getApiBase=te;exports.getAuthUrl=Re;exports.getProviderSources=De;exports.listFiles=Le;exports.listNextPage=Te;exports.logout=Ie;exports.resolveAuth=ze;exports.searchProvider=Be;