@treeui/vue 0.13.0 → 0.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/TButton.cjs.map +1 -1
- package/dist/components/TButton.js.map +1 -1
- package/dist/components/TButton.vue.d.ts +2 -2
- package/dist/components/TButton.vue.d.ts.map +1 -1
- package/dist/components/TButton.vue_vue_type_script_setup_true_lang.cjs +1 -1
- package/dist/components/TButton.vue_vue_type_script_setup_true_lang.cjs.map +1 -1
- package/dist/components/TButton.vue_vue_type_script_setup_true_lang.js +2 -1
- package/dist/components/TButton.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/TFileUpload.cjs.map +1 -1
- package/dist/components/TFileUpload.js.map +1 -1
- package/dist/components/TFileUpload.vue.d.ts +77 -10
- package/dist/components/TFileUpload.vue.d.ts.map +1 -1
- package/dist/components/TFileUpload.vue_vue_type_script_setup_true_lang.cjs +1 -1
- package/dist/components/TFileUpload.vue_vue_type_script_setup_true_lang.cjs.map +1 -1
- package/dist/components/TFileUpload.vue_vue_type_script_setup_true_lang.js +393 -144
- package/dist/components/TFileUpload.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/TNavMenu.cjs.map +1 -1
- package/dist/components/TNavMenu.js.map +1 -1
- package/dist/components/TNavMenu.vue.d.ts +9 -0
- package/dist/components/TNavMenu.vue.d.ts.map +1 -1
- package/dist/components/TNavMenu.vue_vue_type_script_setup_true_lang.cjs +1 -1
- package/dist/components/TNavMenu.vue_vue_type_script_setup_true_lang.cjs.map +1 -1
- package/dist/components/TNavMenu.vue_vue_type_script_setup_true_lang.js +67 -55
- package/dist/components/TNavMenu.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/TPage.cjs +2 -0
- package/dist/components/TPage.cjs.map +1 -0
- package/dist/components/TPage.js +7 -0
- package/dist/components/TPage.js.map +1 -0
- package/dist/components/TPage.vue.d.ts +35 -0
- package/dist/components/TPage.vue.d.ts.map +1 -0
- package/dist/components/TPage.vue_vue_type_script_setup_true_lang.cjs +2 -0
- package/dist/components/TPage.vue_vue_type_script_setup_true_lang.cjs.map +1 -0
- package/dist/components/TPage.vue_vue_type_script_setup_true_lang.js +49 -0
- package/dist/components/TPage.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/TPageHeader.cjs +2 -0
- package/dist/components/TPageHeader.cjs.map +1 -0
- package/dist/components/TPageHeader.js +7 -0
- package/dist/components/TPageHeader.js.map +1 -0
- package/dist/components/TPageHeader.vue.d.ts +40 -0
- package/dist/components/TPageHeader.vue.d.ts.map +1 -0
- package/dist/components/TPageHeader.vue_vue_type_script_setup_true_lang.cjs +2 -0
- package/dist/components/TPageHeader.vue_vue_type_script_setup_true_lang.cjs.map +1 -0
- package/dist/components/TPageHeader.vue_vue_type_script_setup_true_lang.js +54 -0
- package/dist/components/TPageHeader.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/components/TSidebar.vue_vue_type_script_setup_true_lang.cjs +1 -1
- package/dist/components/TSidebar.vue_vue_type_script_setup_true_lang.cjs.map +1 -1
- package/dist/components/TSidebar.vue_vue_type_script_setup_true_lang.js +1 -4
- package/dist/components/TSidebar.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/components/index.d.ts +4 -1
- package/dist/components/index.d.ts.map +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.js +51 -49
- package/dist/plugin.cjs +1 -1
- package/dist/plugin.cjs.map +1 -1
- package/dist/plugin.d.ts.map +1 -1
- package/dist/plugin.js +100 -96
- package/dist/plugin.js.map +1 -1
- package/dist/style.css +1 -1
- package/package.json +2 -2
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
const e=require("./TSpinner.cjs");let t=require("vue"),n=require("@treeui/utils");var r=[`id`,`accept`,`multiple`,`disabled`],i=[`aria-busy`,`aria-controls`,`aria-describedby`,`aria-disabled`,`aria-invalid`,`tabindex`],a={key:0,class:`t-file-upload__icon`,"aria-hidden":`true`},ee={class:`t-file-upload__content`},te={class:`t-file-upload__label`},o={class:`t-file-upload__browse`},s={key:1,class:`t-file-upload__files`},c={class:`t-file-upload__files-header`},l=[`disabled`],u={class:`t-file-upload__list`},d={class:`t-file-upload__file-copy`},f={class:`t-file-upload__file-name`},p={class:`t-file-upload__file-meta`},m=[`disabled`,`aria-label`,`onClick`],h={key:2,class:`t-file-upload__actions`},g=(0,t.defineComponent)({inheritAttrs:!1,__name:`TFileUpload`,props:{modelValue:{default:()=>[]},size:{default:`md`},disabled:{type:Boolean,default:!1},loading:{type:Boolean,default:!1},invalid:{type:Boolean,default:!1},accept:{default:``},multiple:{type:Boolean,default:!0},maxFiles:{default:null},maxFileSize:{default:null},label:{default:`Drop files here`},description:{default:`Click to browse, drag and drop, or paste with Ctrl+V.`},buttonLabel:{default:`Browse files`},filesLabel:{default:`Selected files`},paste:{type:Boolean,default:!0},drop:{type:Boolean,default:!0},showFileList:{type:Boolean,default:!0}},emits:[`update:modelValue`,`files-accepted`,`files-rejected`],setup(g,{emit:_}){let ne=(0,t.useSlots)(),v=g,y=_,b=(0,t.useAttrs)(),x=(0,t.ref)(null),S=(0,t.ref)(null),C=(0,t.ref)(!1),w=(0,t.ref)(!1),T=(0,t.ref)(0),E=(0,t.ref)([]),D=(0,n.createId)(`t-file-upload`),O=`${D}-description`,k=`${D}-feedback`,A=`${D}-files`,j=(0,t.computed)(()=>v.disabled||v.loading),M=(0,t.computed)(()=>v.modelValue.length>0),N=(0,t.computed)(()=>!!ne.default),P=(0,t.computed)(()=>v.multiple?typeof v.maxFiles==`number`?Math.max(v.maxFiles,0):1/0:1),F=(0,t.computed)(()=>[`t-file-upload`,`t-file-upload--${v.size}`,{"is-disabled":j.value,"is-invalid":v.invalid,"is-loading":v.loading,"is-drag-active":C.value,"has-files":M.value},b.class]),I=(0,t.computed)(()=>b.style),L=(0,t.computed)(()=>{let{class:e,style:t,...n}=b;return n}),R=(0,t.computed)(()=>{let e=[];return v.description&&!N.value&&e.push(O),E.value.length>0&&e.push(k),v.showFileList&&M.value&&e.push(A),e.length>0?e.join(` `):void 0}),z=(0,t.computed)(()=>`${v.filesLabel} (${v.modelValue.length})`),B=e=>{if(e<1024)return`${e} B`;let t=[`KB`,`MB`,`GB`],n=e/1024,r=0;for(;n>=1024&&r<t.length-1;)n/=1024,r+=1;return`${n>=10||Number.isInteger(n)?Math.round(n):Number(n.toFixed(1))} ${t[r]}`},V=(e,t)=>`${e.name}-${e.size}-${e.lastModified}-${t}`,H=e=>{if(!v.accept.trim())return!0;let t=v.accept.split(`,`).map(e=>e.trim().toLowerCase()).filter(Boolean),n=e.name.toLowerCase(),r=e.type.toLowerCase();return t.some(e=>e.startsWith(`.`)?n.endsWith(e):e.endsWith(`/*`)?r.startsWith(e.slice(0,-1)):r===e)},U=(e,t)=>{switch(t){case`file-invalid-type`:return`${e.name} is not an accepted file type.`;case`file-too-large`:return`${e.name} exceeds the ${B(v.maxFileSize??0)} limit.`;case`too-many-files`:return`You can only add up to ${P.value} file${P.value===1?``:`s`}.`;default:return`${e.name} could not be added.`}},W=()=>{S.value&&(S.value.value=``)},G=()=>{j.value||S.value?.click()},K=(e,t,n)=>{E.value=n.map(e=>e.message),n.length>0&&y(`files-rejected`,n),t.length>0&&(y(`update:modelValue`,e),y(`files-accepted`,t))},q=e=>{if(j.value||e.length===0)return;let t=v.multiple?[...v.modelValue]:[],n=[],r=[],i=Number.isFinite(P.value)?Math.max(P.value-t.length,0):1/0;for(let a of e){if(i<=0){r.push({file:a,reason:`too-many-files`,message:U(a,`too-many-files`)});continue}if(!H(a)){r.push({file:a,reason:`file-invalid-type`,message:U(a,`file-invalid-type`)});continue}if(typeof v.maxFileSize==`number`&&v.maxFileSize>0&&a.size>v.maxFileSize){r.push({file:a,reason:`file-too-large`,message:U(a,`file-too-large`)});continue}n.push(a),t.push(a),Number.isFinite(i)&&--i}K(t,n,r)},J=e=>{j.value||(E.value=[],y(`update:modelValue`,v.modelValue.filter((t,n)=>n!==e)))},Y=()=>{j.value||!M.value||(E.value=[],y(`update:modelValue`,[]))},X=e=>e?e.files.length>0||Array.from(e.types).includes(`Files`):!1,re=e=>e?.items?Array.from(e.items).map(e=>e.getAsFile?.()??null).filter(e=>e instanceof File):[],ie=e=>{let t=e.target;q(Array.from(t.files??[])),W()},ae=e=>{!(0,n.isActivationKey)(e)||j.value||(e.preventDefault(),G())},oe=()=>{w.value=!0},se=e=>{let t=e.relatedTarget;t&&x.value?.contains(t)||(w.value=!1)},Z=e=>{if(!v.paste||j.value)return;let t=re(e.clipboardData);t.length!==0&&(e.preventDefault(),q(t))},Q=e=>{!w.value||e.defaultPrevented||Z(e)},ce=e=>{!v.drop||j.value||!X(e.dataTransfer)||(e.preventDefault(),T.value+=1,C.value=!0)},le=e=>{!v.drop||j.value||!X(e.dataTransfer)||(e.preventDefault(),e.dataTransfer&&(e.dataTransfer.dropEffect=`copy`),C.value=!0)},$=e=>{!v.drop||j.value||!X(e.dataTransfer)||(e.preventDefault(),T.value=Math.max(T.value-1,0),T.value===0&&(C.value=!1))},ue=e=>{!v.drop||j.value||!X(e.dataTransfer)||(e.preventDefault(),T.value=0,C.value=!1,q(Array.from(e.dataTransfer?.files??[])))};return(0,t.onMounted)(()=>{document.addEventListener(`paste`,Q)}),(0,t.onBeforeUnmount)(()=>{document.removeEventListener(`paste`,Q)}),(n,_)=>((0,t.openBlock)(),(0,t.createElementBlock)(`div`,(0,t.mergeProps)({ref_key:`rootRef`,ref:x},L.value,{class:F.value,style:I.value,onFocusin:oe,onFocusout:se,onPaste:Z}),[(0,t.createElementVNode)(`input`,{id:(0,t.unref)(D),ref_key:`inputRef`,ref:S,class:`t-visually-hidden`,type:`file`,accept:g.accept||void 0,multiple:g.multiple,disabled:j.value,onChange:ie},null,40,r),(0,t.createElementVNode)(`div`,{class:`t-file-upload__dropzone`,"aria-busy":g.loading||void 0,"aria-controls":g.showFileList&&M.value?A:void 0,"aria-describedby":R.value,"aria-disabled":j.value||void 0,"aria-invalid":g.invalid||void 0,role:`button`,tabindex:j.value?-1:0,onClick:G,onKeydown:ae,onDragenter:ce,onDragover:le,onDragleave:$,onDrop:ue},[n.$slots.icon||!n.$slots.default?((0,t.openBlock)(),(0,t.createElementBlock)(`div`,a,[(0,t.renderSlot)(n.$slots,`icon`,{},()=>[_[0]||=(0,t.createElementVNode)(`span`,{class:`t-file-upload__icon-mark`},`+`,-1)])])):(0,t.createCommentVNode)(``,!0),(0,t.createElementVNode)(`div`,ee,[(0,t.renderSlot)(n.$slots,`default`,{files:g.modelValue,isDragActive:C.value,openFileDialog:G,clearFiles:Y},()=>[(0,t.createElementVNode)(`p`,te,(0,t.toDisplayString)(g.label),1),g.description?((0,t.openBlock)(),(0,t.createElementBlock)(`p`,{key:0,id:O,class:`t-file-upload__description`},(0,t.toDisplayString)(g.description),1)):(0,t.createCommentVNode)(``,!0),(0,t.createElementVNode)(`span`,o,(0,t.toDisplayString)(g.buttonLabel),1)])]),g.loading?((0,t.openBlock)(),(0,t.createBlock)(e.default,{key:1,class:`t-file-upload__spinner`,size:`sm`,label:`Uploading files`})):(0,t.createCommentVNode)(``,!0)],40,i),E.value.length>0?((0,t.openBlock)(),(0,t.createElementBlock)(`ul`,{key:0,id:k,class:`t-file-upload__feedback`,"aria-live":`polite`},[((0,t.openBlock)(!0),(0,t.createElementBlock)(t.Fragment,null,(0,t.renderList)(E.value,e=>((0,t.openBlock)(),(0,t.createElementBlock)(`li`,{key:e},(0,t.toDisplayString)(e),1))),128))])):(0,t.createCommentVNode)(``,!0),g.showFileList&&M.value?((0,t.openBlock)(),(0,t.createElementBlock)(`div`,s,[(0,t.createElementVNode)(`div`,c,[(0,t.createElementVNode)(`p`,{id:A,class:`t-file-upload__files-label`},(0,t.toDisplayString)(z.value),1),(0,t.createElementVNode)(`button`,{class:`t-file-upload__clear`,type:`button`,disabled:j.value,onClick:Y},` Clear all `,8,l)]),(0,t.createElementVNode)(`ul`,u,[((0,t.openBlock)(!0),(0,t.createElementBlock)(t.Fragment,null,(0,t.renderList)(g.modelValue,(e,r)=>((0,t.openBlock)(),(0,t.createElementBlock)(`li`,{key:V(e,r),class:`t-file-upload__file`},[(0,t.renderSlot)(n.$slots,`file`,{file:e,index:r,removeFile:()=>J(r)},()=>[(0,t.createElementVNode)(`div`,d,[(0,t.createElementVNode)(`p`,f,(0,t.toDisplayString)(e.name),1),(0,t.createElementVNode)(`p`,p,(0,t.toDisplayString)(B(e.size)),1)]),(0,t.createElementVNode)(`button`,{class:`t-file-upload__remove`,type:`button`,disabled:j.value,"aria-label":`Remove ${e.name}`,onClick:e=>J(r)},` Remove `,8,m)])]))),128))])])):(0,t.createCommentVNode)(``,!0),n.$slots.actions?((0,t.openBlock)(),(0,t.createElementBlock)(`div`,h,[(0,t.renderSlot)(n.$slots,`actions`,{files:g.modelValue,openFileDialog:G,clearFiles:Y})])):(0,t.createCommentVNode)(``,!0)],16))}});exports.default=g;
|
|
1
|
+
const e=require("./TSpinner.cjs"),t=require("./TProgress.cjs");let n=require("vue"),r=require("@treeui/utils");var i=[`id`,`accept`,`multiple`,`disabled`],a=[`aria-busy`,`aria-controls`,`aria-describedby`,`aria-disabled`,`aria-invalid`,`tabindex`],o={key:0,class:`t-file-upload__icon`,"aria-hidden":`true`},s={class:`t-file-upload__content`},c={class:`t-file-upload__label`},l={class:`t-file-upload__browse`},u={class:`t-file-upload__status-log t-visually-hidden`,role:`log`,"aria-live":`polite`},d={key:1,class:`t-file-upload__files`},f={class:`t-file-upload__files-header`},p=[`disabled`],m={class:`t-file-upload__list`},h=[`aria-busy`],g={class:`t-file-upload__thumb`,"aria-hidden":`true`},_=[`src`],v={key:1,class:`t-file-upload__thumb-fallback`},y={class:`t-file-upload__file-copy`},ee={class:`t-file-upload__file-name`},te={class:`t-file-upload__file-meta`},ne={key:0,class:`t-file-upload__file-progress`},re={key:1,class:`t-file-upload__file-status`},ie={key:0,class:`t-file-upload__proof`,"aria-hidden":`true`},ae=[`id`],oe=[`data-t-retry`,`disabled`,`aria-describedby`,`onFocus`,`onBlur`,`onClick`],se=[`data-t-remove`,`disabled`,`aria-label`,`onClick`],ce={key:2,class:`t-file-upload__actions`},b=(0,n.defineComponent)({inheritAttrs:!1,__name:`TFileUpload`,props:{modelValue:{default:()=>[]},size:{default:`md`},disabled:{type:Boolean,default:!1},loading:{type:Boolean,default:!1},invalid:{type:Boolean,default:!1},accept:{default:``},multiple:{type:Boolean,default:!0},maxFiles:{default:null},maxFileSize:{default:null},label:{default:`Drop files here`},description:{default:`Click to browse, drag and drop, or paste with Ctrl+V.`},buttonLabel:{default:`Browse files`},filesLabel:{default:`Selected files`},paste:{type:Boolean,default:!0},drop:{type:Boolean,default:!0},showFileList:{type:Boolean,default:!0},uploadState:{type:[Map,Function],default:void 0},dragLabel:{default:`Release to upload`},dragRejectLabel:{default:`This file type is not accepted`},thumbnails:{type:Boolean,default:!0},maxThumbnailSize:{default:10*1024*1024},retryLabel:{default:`Retry`},resumeLabel:{type:Function,default:e=>`Resume from ${e}%`},remainingTimeFormat:{type:Function,default:e=>{if(e<5e3)return`Less than 5s left`;let t=Math.round(e/1e3);if(t<60)return`About ${t}s left`;let n=Math.round(t/60);return n<60?`About ${n} min left`:`About ${Math.round(n/60)}h left`}},statusLabels:{default:()=>({})}},emits:[`update:modelValue`,`files-accepted`,`files-rejected`,`retry`,`cancel`],setup(b,{emit:x}){let le={pending:`Waiting`,uploading:`Uploading`,paused:`Paused`,error:`Upload failed`,success:`Uploaded`},ue=(0,n.useSlots)(),S=b,C=x,w=(0,n.useAttrs)(),T=(0,n.ref)(null),E=(0,n.ref)(null),D=(0,n.ref)(!1),O=(0,n.ref)(!1),k=(0,n.ref)(!1),A=(0,n.ref)(0),j=(0,n.ref)([]),M=(0,n.ref)([]),N=0,P=(0,n.ref)(null),F=(0,n.ref)(new Map),I=(0,r.createId)(`t-file-upload`),L=`${I}-description`,R=`${I}-feedback`,z=`${I}-files`,B=(0,n.computed)(()=>S.disabled),V=(0,n.computed)(()=>S.modelValue.length>0),de=(0,n.computed)(()=>!!ue.default),fe=(0,n.computed)(()=>({...le,...S.statusLabels})),H=(0,n.computed)(()=>S.multiple?typeof S.maxFiles==`number`?Math.max(S.maxFiles,0):1/0:1),pe=(0,n.computed)(()=>[`t-file-upload`,`t-file-upload--${S.size}`,{"is-disabled":B.value,"is-invalid":S.invalid,"is-loading":S.loading,"is-drag-active":D.value,"is-drag-reject":O.value,"has-files":V.value},w.class]),me=(0,n.computed)(()=>w.style),he=(0,n.computed)(()=>{let{class:e,style:t,...n}=w;return n}),ge=(0,n.computed)(()=>{let e=[];return S.description&&!de.value&&e.push(L),j.value.length>0&&e.push(R),S.showFileList&&V.value&&e.push(z),e.length>0?e.join(` `):void 0}),_e=(0,n.computed)(()=>`${S.filesLabel} (${S.modelValue.length})`),ve=(0,n.computed)(()=>O.value?S.dragRejectLabel:D.value?S.dragLabel:S.label),U=e=>{if(e<1024)return`${e} B`;let t=[`KB`,`MB`,`GB`],n=e/1024,r=0;for(;n>=1024&&r<t.length-1;)n/=1024,r+=1;return`${n>=10||Number.isInteger(n)?Math.round(n):Number(n.toFixed(1))} ${t[r]}`},ye=e=>{let t=e.name.lastIndexOf(`.`),n=t>0&&t<e.name.length-1?e.name.slice(t+1).toUpperCase():``;if(n&&n.length<=5)return n;let r=e.type.includes(`/`)?e.type.split(`/`)[1]:``;return r?r.toUpperCase():`FILE`},W=0,be=new WeakMap,xe=e=>{let t=be.get(e);return t||(W+=1,t=`${I}-f${W}`,be.set(e,t)),t},G=(0,n.computed)(()=>S.accept.split(`,`).map(e=>e.trim().toLowerCase()).filter(Boolean)),Se=e=>{if(G.value.length===0)return!0;let t=e.name.toLowerCase(),n=e.type.toLowerCase();return G.value.some(e=>e.startsWith(`.`)?t.endsWith(e):e.endsWith(`/*`)?n.startsWith(e.slice(0,-1)):n===e)},Ce=(0,n.computed)(()=>G.value.length>0&&G.value.every(e=>e.includes(`/`))),we=e=>{let t=e.toLowerCase();return!t||G.value.some(e=>e.endsWith(`/*`)?t.startsWith(e.slice(0,-1)):t===e)},Te=e=>{if(!Ce.value||!e)return!1;let t=e.items;if(!t||t.length===0)return!1;let n=Array.from(t).filter(e=>e.kind===`file`);return n.length!==0&&n.every(e=>!we(e.type))},Ee=(e,t)=>{let n=S.uploadState;if(n)return typeof n==`function`?n(e,t):n.get(e)},K=(0,n.computed)(()=>S.modelValue.map(Ee)),De=()=>typeof window<`u`&&typeof URL<`u`&&typeof URL.createObjectURL==`function`&&typeof URL.revokeObjectURL==`function`,Oe=e=>e.type.startsWith(`image/`)&&(S.maxThumbnailSize===null||e.size<=S.maxThumbnailSize),ke=()=>{if(De())for(let e of F.value.values())URL.revokeObjectURL(e.url);F.value.clear()},q=()=>{if(!S.thumbnails||!De()){ke();return}let e=new Set(S.modelValue);for(let[t,n]of[...F.value])e.has(t)||(URL.revokeObjectURL(n.url),F.value.delete(t));for(let e of S.modelValue){if(F.value.has(e)||!Oe(e))continue;let t=URL.createObjectURL(e);F.value.set(e,{url:t,width:null,height:null});let n=new Image;n.onload=()=>{let r=F.value.get(e);!r||r.url!==t||F.value.set(e,{url:t,width:n.naturalWidth,height:n.naturalHeight})},n.src=t}},J=(e,t)=>{switch(t){case`file-invalid-type`:return`${e.name} is not an accepted file type.`;case`file-too-large`:return`${e.name} exceeds the ${U(S.maxFileSize??0)} limit.`;case`too-many-files`:return`You can only add up to ${H.value} file${H.value===1?``:`s`}.`;default:return`${e.name} could not be added.`}},Ae=()=>{E.value&&(E.value.value=``)},Y=()=>{B.value||E.value?.click()},je=(e,t,n)=>{j.value=n.map(e=>e.message),n.length>0&&C(`files-rejected`,n),t.length>0&&(C(`update:modelValue`,e),C(`files-accepted`,t))},X=e=>{if(B.value||e.length===0)return;let t=S.multiple?[...S.modelValue]:[],n=[],r=[],i=Number.isFinite(H.value)?Math.max(H.value-t.length,0):1/0;for(let a of e){if(i<=0){r.push({file:a,reason:`too-many-files`,message:J(a,`too-many-files`)});continue}if(!Se(a)){r.push({file:a,reason:`file-invalid-type`,message:J(a,`file-invalid-type`)});continue}if(typeof S.maxFileSize==`number`&&S.maxFileSize>0&&a.size>S.maxFileSize){r.push({file:a,reason:`file-too-large`,message:J(a,`file-too-large`)});continue}n.push(a),t.push(a),Number.isFinite(i)&&--i}je(t,n,r)},Me=(e,t,n)=>{let r=K.value[t];!r||r.status!==`uploading`&&r.status!==`paused`||C(`cancel`,{file:e,index:t,fileKey:xe(e),state:r,reason:n})},Ne=e=>{if(B.value)return;let t=S.modelValue[e];t&&Me(t,e,`remove`),j.value=[],C(`update:modelValue`,S.modelValue.filter((t,n)=>n!==e))},Z=()=>{B.value||!V.value||(S.modelValue.forEach((e,t)=>{Me(e,t,`clear`)}),j.value=[],C(`update:modelValue`,[]))},Pe=(0,n.computed)(()=>S.modelValue.map((e,t)=>{let n=K.value[t],r=n?.status,i=F.value.get(e),a=xe(e),o=n?.progress,s=typeof o==`number`?Math.round(o):void 0,c=n?.resumable===!0,l=!!(n&&(r===`error`||r===`paused`)&&n.retryable!==!1),u=c?`resume`:`restart`,d=U(e.size),f=ye(e),p=i&&i.width!==null&&i.height!==null?`${i.width} × ${i.height}`:void 0,m=r===`uploading`&&s!==void 0?`${s}%`:void 0,h;r===`uploading`&&(n?.remainingLabel?h=n.remainingLabel:typeof n?.remainingMs==`number`&&Number.isFinite(n.remainingMs)&&n.remainingMs>=0&&(h=S.remainingTimeFormat(n.remainingMs)));let g=(r===`error`||r===`paused`)&&typeof n?.uploadedBytes==`number`?`${U(n.uploadedBytes)} of ${d} uploaded`:void 0,_=r?fe.value[r]:void 0,v;l&&(v=c&&s!==void 0?S.resumeLabel(s):S.retryLabel);let y=r===`error`?n?.error:void 0;return{slotProps:{file:e,index:t,fileKey:a,state:n,thumbnailUrl:n?.thumbnailUrl??i?.url,sizeLabel:d,typeLabel:f,dimensionsLabel:p,progressLabel:m,remainingLabel:h,uploadedLabel:g,statusLabel:_,actionLabel:v,canRetry:l,retryMode:u,isDragActive:D.value,isDragReject:O.value,removeFile:()=>Ne(t),retryFile:()=>{!l||B.value||!n||C(`retry`,{file:e,index:t,fileKey:a,mode:u,state:n})}},rowClass:r?`is-${r}`:void 0,metaText:[f,d,p,n?.meta].filter(Boolean).join(` · `),statusText:[_,m,h,g].filter(Boolean).join(` · `),errorText:y,errorId:y?`${a}-error`:void 0,showProgress:!!(n&&(r===`uploading`||r===`paused`||r===`error`||r===`success`&&s!==void 0)),progressValue:r===`uploading`?o:o??0,progressAriaLabel:`${_??``} ${e.name}`.trim(),isBusy:r===`uploading`,isSuccess:r===`success`}})),Q=e=>e?e.files.length>0||Array.from(e.types).includes(`Files`):!1,Fe=e=>e?.items?Array.from(e.items).map(e=>e.getAsFile?.()??null).filter(e=>e instanceof File):[],Ie=e=>{let t=e.target;X(Array.from(t.files??[])),Ae()},Le=e=>{!(0,r.isActivationKey)(e)||B.value||(e.preventDefault(),Y())},Re=()=>{k.value=!0},ze=e=>{let t=e.relatedTarget;t&&T.value?.contains(t)||(k.value=!1)},Be=e=>{P.value=e},Ve=e=>{P.value===e&&(P.value=null)},He=e=>{if(!S.paste||B.value)return;let t=Fe(e.clipboardData);t.length!==0&&(e.preventDefault(),X(t))},Ue=e=>{!k.value||e.defaultPrevented||He(e)},We=e=>{!S.drop||B.value||!Q(e.dataTransfer)||(e.preventDefault(),A.value+=1,D.value=!0,O.value=Te(e.dataTransfer))},Ge=e=>{!S.drop||B.value||!Q(e.dataTransfer)||(e.preventDefault(),e.dataTransfer&&(e.dataTransfer.dropEffect=`copy`),D.value=!0,O.value=Te(e.dataTransfer))},Ke=e=>{!S.drop||B.value||!Q(e.dataTransfer)||(e.preventDefault(),A.value=Math.max(A.value-1,0),A.value===0&&(D.value=!1,O.value=!1))},qe=e=>{!S.drop||B.value||!Q(e.dataTransfer)||(e.preventDefault(),A.value=0,D.value=!1,O.value=!1,X(Array.from(e.dataTransfer?.files??[])))},$=new Map;return(0,n.watch)(K,e=>{let t=[],n=new Set;S.modelValue.forEach((r,i)=>{n.add(r);let a=e[i]?.status;if(!a)return;let o=$.get(r);o!==a&&($.set(r,a),o!==void 0&&(a===`success`?t.push(`${r.name} uploaded.`):a===`error`&&t.push(`${r.name} failed. ${e[i]?.error??``}`.trim())))});for(let e of[...$.keys()])n.has(e)||$.delete(e);t.length>0&&(N+=1,M.value=[...M.value,{id:N,text:t.join(` `)}].slice(-5))},{flush:`post`,immediate:!0}),(0,n.watch)(K,()=>{let e=P.value,t=T.value;!e||!t||document.activeElement&&document.activeElement!==document.body||t.querySelector(`[data-t-retry="${e}"]`)||(P.value=null,(t.querySelector(`[data-t-remove="${e}"]`)??t.querySelector(`.t-file-upload__dropzone`))?.focus())},{flush:`post`}),(0,n.watch)(()=>S.modelValue,q),(0,n.watch)(()=>S.thumbnails,q),(0,n.onMounted)(()=>{document.addEventListener(`paste`,Ue),q()}),(0,n.onBeforeUnmount)(()=>{document.removeEventListener(`paste`,Ue),ke()}),(r,x)=>((0,n.openBlock)(),(0,n.createElementBlock)(`div`,(0,n.mergeProps)({ref_key:`rootRef`,ref:T},he.value,{class:pe.value,style:me.value,onFocusin:Re,onFocusout:ze,onPaste:He}),[(0,n.createElementVNode)(`input`,{id:(0,n.unref)(I),ref_key:`inputRef`,ref:E,class:`t-visually-hidden`,type:`file`,accept:b.accept||void 0,multiple:b.multiple,disabled:B.value,onChange:Ie},null,40,i),(0,n.createElementVNode)(`div`,{class:`t-file-upload__dropzone`,"aria-busy":b.loading||void 0,"aria-controls":b.showFileList&&V.value?z:void 0,"aria-describedby":ge.value,"aria-disabled":B.value||void 0,"aria-invalid":b.invalid||void 0,role:`button`,tabindex:B.value?-1:0,onClick:Y,onKeydown:Le,onDragenter:We,onDragover:Ge,onDragleave:Ke,onDrop:qe},[r.$slots.icon||!r.$slots.default?((0,n.openBlock)(),(0,n.createElementBlock)(`div`,o,[(0,n.renderSlot)(r.$slots,`icon`,{},()=>[x[0]||=(0,n.createElementVNode)(`span`,{class:`t-file-upload__icon-mark`},`+`,-1)])])):(0,n.createCommentVNode)(``,!0),(0,n.createElementVNode)(`div`,s,[(0,n.renderSlot)(r.$slots,`default`,{files:b.modelValue,isDragActive:D.value,isDragReject:O.value,openFileDialog:Y,clearFiles:Z},()=>[(0,n.createElementVNode)(`p`,c,(0,n.toDisplayString)(ve.value),1),b.description?((0,n.openBlock)(),(0,n.createElementBlock)(`p`,{key:0,id:L,class:`t-file-upload__description`},(0,n.toDisplayString)(b.description),1)):(0,n.createCommentVNode)(``,!0),(0,n.createElementVNode)(`span`,l,(0,n.toDisplayString)(b.buttonLabel),1)])]),b.loading?((0,n.openBlock)(),(0,n.createBlock)(e.default,{key:1,class:`t-file-upload__spinner`,size:`sm`,label:`Uploading files`})):(0,n.createCommentVNode)(``,!0)],40,a),j.value.length>0?((0,n.openBlock)(),(0,n.createElementBlock)(`ul`,{key:0,id:R,class:`t-file-upload__feedback`,"aria-live":`polite`},[((0,n.openBlock)(!0),(0,n.createElementBlock)(n.Fragment,null,(0,n.renderList)(j.value,e=>((0,n.openBlock)(),(0,n.createElementBlock)(`li`,{key:e},(0,n.toDisplayString)(e),1))),128))])):(0,n.createCommentVNode)(``,!0),(0,n.createElementVNode)(`div`,u,[((0,n.openBlock)(!0),(0,n.createElementBlock)(n.Fragment,null,(0,n.renderList)(M.value,e=>((0,n.openBlock)(),(0,n.createElementBlock)(`p`,{key:e.id,class:`t-file-upload__status-log-entry`},(0,n.toDisplayString)(e.text),1))),128))]),b.showFileList&&V.value?((0,n.openBlock)(),(0,n.createElementBlock)(`div`,d,[(0,n.createElementVNode)(`div`,f,[(0,n.createElementVNode)(`p`,{id:z,class:`t-file-upload__files-label`},(0,n.toDisplayString)(_e.value),1),(0,n.createElementVNode)(`button`,{class:`t-file-upload__clear`,type:`button`,disabled:B.value,onClick:Z},` Clear all `,8,p)]),(0,n.createElementVNode)(`ul`,m,[((0,n.openBlock)(!0),(0,n.createElementBlock)(n.Fragment,null,(0,n.renderList)(Pe.value,e=>((0,n.openBlock)(),(0,n.createElementBlock)(`li`,{key:e.slotProps.fileKey,class:(0,n.normalizeClass)([`t-file-upload__file`,e.rowClass]),"aria-busy":e.isBusy||void 0},[(0,n.renderSlot)(r.$slots,`file`,(0,n.mergeProps)({ref_for:!0},e.slotProps),()=>[(0,n.createElementVNode)(`span`,g,[e.slotProps.thumbnailUrl?((0,n.openBlock)(),(0,n.createElementBlock)(`img`,{key:0,class:`t-file-upload__thumb-image`,src:e.slotProps.thumbnailUrl,alt:``},null,8,_)):((0,n.openBlock)(),(0,n.createElementBlock)(`span`,v,(0,n.toDisplayString)(e.slotProps.typeLabel),1))]),(0,n.createElementVNode)(`div`,y,[(0,n.createElementVNode)(`p`,ee,(0,n.toDisplayString)(e.slotProps.file.name),1),(0,n.createElementVNode)(`p`,te,(0,n.toDisplayString)(e.metaText),1),(0,n.renderSlot)(r.$slots,`file-status`,(0,n.mergeProps)({ref_for:!0},e.slotProps),()=>[e.showProgress?((0,n.openBlock)(),(0,n.createElementBlock)(`div`,ne,[(0,n.createVNode)(t.default,{size:`sm`,value:e.progressValue,label:e.progressAriaLabel},null,8,[`value`,`label`])])):(0,n.createCommentVNode)(``,!0),e.statusText?((0,n.openBlock)(),(0,n.createElementBlock)(`p`,re,[e.isSuccess?((0,n.openBlock)(),(0,n.createElementBlock)(`span`,ie,`✓`)):(0,n.createCommentVNode)(``,!0),(0,n.createTextVNode)((0,n.toDisplayString)(e.statusText),1)])):(0,n.createCommentVNode)(``,!0),e.errorText?((0,n.openBlock)(),(0,n.createElementBlock)(`p`,{key:2,id:e.errorId,class:`t-file-upload__file-error`},(0,n.toDisplayString)(e.errorText),9,ae)):(0,n.createCommentVNode)(``,!0)])]),e.slotProps.canRetry?((0,n.openBlock)(),(0,n.createElementBlock)(`button`,{key:0,class:`t-file-upload__retry`,type:`button`,"data-t-retry":e.slotProps.fileKey,disabled:B.value,"aria-describedby":e.errorId,onFocus:t=>Be(e.slotProps.fileKey),onBlur:t=>Ve(e.slotProps.fileKey),onClick:t=>e.slotProps.retryFile()},(0,n.toDisplayString)(e.slotProps.actionLabel),41,oe)):(0,n.createCommentVNode)(``,!0),(0,n.createElementVNode)(`button`,{class:`t-file-upload__remove`,type:`button`,"data-t-remove":e.slotProps.fileKey,disabled:B.value,"aria-label":`Remove ${e.slotProps.file.name}`,onClick:t=>e.slotProps.removeFile()},` Remove `,8,se)])],10,h))),128))])])):(0,n.createCommentVNode)(``,!0),r.$slots.actions?((0,n.openBlock)(),(0,n.createElementBlock)(`div`,ce,[(0,n.renderSlot)(r.$slots,`actions`,{files:b.modelValue,openFileDialog:Y,clearFiles:Z})])):(0,n.createCommentVNode)(``,!0)],16))}});exports.default=b;
|
|
2
2
|
//# sourceMappingURL=TFileUpload.vue_vue_type_script_setup_true_lang.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TFileUpload.vue_vue_type_script_setup_true_lang.cjs","names":["$slots"],"sources":["../../src/components/TFileUpload.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { createId, isActivationKey } from '@treeui/utils';\nimport { computed, onBeforeUnmount, onMounted, ref, useAttrs } from 'vue';\nimport type { TSize } from '../types/contracts';\nimport TSpinner from './TSpinner.vue';\n\ndefineOptions({\n inheritAttrs: false,\n});\n\nexport type TFileUploadRejectionReason =\n | 'file-invalid-type'\n | 'file-too-large'\n | 'too-many-files';\n\nexport interface TFileUploadRejection {\n file: File;\n reason: TFileUploadRejectionReason;\n message: string;\n}\n\nconst slots = defineSlots<{\n icon?: () => unknown;\n default?: (props: {\n files: File[];\n isDragActive: boolean;\n openFileDialog: () => void;\n clearFiles: () => void;\n }) => unknown;\n file?: (props: {\n file: File;\n index: number;\n removeFile: () => void;\n }) => unknown;\n actions?: (props: {\n files: File[];\n openFileDialog: () => void;\n clearFiles: () => void;\n }) => unknown;\n}>();\n\nconst props = withDefaults(\n defineProps<{\n modelValue?: File[];\n size?: TSize;\n disabled?: boolean;\n loading?: boolean;\n invalid?: boolean;\n accept?: string;\n multiple?: boolean;\n maxFiles?: number | null;\n maxFileSize?: number | null;\n label?: string;\n description?: string;\n buttonLabel?: string;\n filesLabel?: string;\n paste?: boolean;\n drop?: boolean;\n showFileList?: boolean;\n }>(),\n {\n modelValue: () => [],\n size: 'md',\n disabled: false,\n loading: false,\n invalid: false,\n accept: '',\n multiple: true,\n label: 'Drop files here',\n description: 'Click to browse, drag and drop, or paste with Ctrl+V.',\n buttonLabel: 'Browse files',\n filesLabel: 'Selected files',\n maxFiles: null,\n maxFileSize: null,\n paste: true,\n drop: true,\n showFileList: true,\n },\n);\n\nconst emit = defineEmits<{\n 'update:modelValue': [files: File[]];\n 'files-accepted': [files: File[]];\n 'files-rejected': [rejections: TFileUploadRejection[]];\n}>();\n\nconst attrs = useAttrs();\nconst rootRef = ref<HTMLElement | null>(null);\nconst inputRef = ref<HTMLInputElement | null>(null);\nconst isDragActive = ref(false);\nconst isFocusedWithin = ref(false);\nconst dragDepth = ref(0);\nconst feedbackMessages = ref<string[]>([]);\n\nconst uploadId = createId('t-file-upload');\nconst descriptionId = `${uploadId}-description`;\nconst feedbackId = `${uploadId}-feedback`;\nconst filesId = `${uploadId}-files`;\n\nconst isUnavailable = computed(() => props.disabled || props.loading);\nconst hasFiles = computed(() => props.modelValue.length > 0);\nconst hasCustomBody = computed(() => Boolean(slots.default));\n\nconst effectiveMaxFiles = computed(() => {\n if (!props.multiple) {\n return 1;\n }\n\n if (typeof props.maxFiles !== 'number') {\n return Number.POSITIVE_INFINITY;\n }\n\n return Math.max(props.maxFiles, 0);\n});\n\nconst rootClasses = computed(() => [\n 't-file-upload',\n `t-file-upload--${props.size}`,\n {\n 'is-disabled': isUnavailable.value,\n 'is-invalid': props.invalid,\n 'is-loading': props.loading,\n 'is-drag-active': isDragActive.value,\n 'has-files': hasFiles.value,\n },\n attrs.class,\n]);\n\nconst rootStyle = computed(() => attrs.style);\n\nconst rootAttrs = computed(() => {\n const { class: _class, style: _style, ...rest } = attrs;\n return rest;\n});\n\nconst describedBy = computed(() => {\n const ids: string[] = [];\n\n if (props.description && !hasCustomBody.value) {\n ids.push(descriptionId);\n }\n\n if (feedbackMessages.value.length > 0) {\n ids.push(feedbackId);\n }\n\n if (props.showFileList && hasFiles.value) {\n ids.push(filesId);\n }\n\n return ids.length > 0 ? ids.join(' ') : undefined;\n});\n\nconst selectedFilesLabel = computed(() => `${props.filesLabel} (${props.modelValue.length})`);\n\nconst formatFileSize = (size: number) => {\n if (size < 1024) {\n return `${size} B`;\n }\n\n const units = ['KB', 'MB', 'GB'];\n let value = size / 1024;\n let unitIndex = 0;\n\n while (value >= 1024 && unitIndex < units.length - 1) {\n value /= 1024;\n unitIndex += 1;\n }\n\n const roundedValue = value >= 10 || Number.isInteger(value)\n ? Math.round(value)\n : Number(value.toFixed(1));\n\n return `${roundedValue} ${units[unitIndex]}`;\n};\n\nconst fileKey = (file: File, index: number) =>\n `${file.name}-${file.size}-${file.lastModified}-${index}`;\n\nconst matchesAccept = (file: File) => {\n if (!props.accept.trim()) {\n return true;\n }\n\n const tokens = props.accept\n .split(',')\n .map((token) => token.trim().toLowerCase())\n .filter(Boolean);\n\n const fileName = file.name.toLowerCase();\n const fileType = file.type.toLowerCase();\n\n return tokens.some((token) => {\n if (token.startsWith('.')) {\n return fileName.endsWith(token);\n }\n\n if (token.endsWith('/*')) {\n return fileType.startsWith(token.slice(0, -1));\n }\n\n return fileType === token;\n });\n};\n\nconst buildRejectionMessage = (\n file: File,\n reason: TFileUploadRejectionReason,\n) => {\n switch (reason) {\n case 'file-invalid-type':\n return `${file.name} is not an accepted file type.`;\n case 'file-too-large':\n return `${file.name} exceeds the ${formatFileSize(props.maxFileSize ?? 0)} limit.`;\n case 'too-many-files':\n return `You can only add up to ${effectiveMaxFiles.value} file${effectiveMaxFiles.value === 1 ? '' : 's'}.`;\n default:\n return `${file.name} could not be added.`;\n }\n};\n\nconst resetInputValue = () => {\n if (inputRef.value) {\n inputRef.value.value = '';\n }\n};\n\nconst openFileDialog = () => {\n if (isUnavailable.value) {\n return;\n }\n\n inputRef.value?.click();\n};\n\nconst emitFiles = (\n nextFiles: File[],\n acceptedFiles: File[],\n rejections: TFileUploadRejection[],\n) => {\n feedbackMessages.value = rejections.map((rejection) => rejection.message);\n\n if (rejections.length > 0) {\n emit('files-rejected', rejections);\n }\n\n if (acceptedFiles.length > 0) {\n emit('update:modelValue', nextFiles);\n emit('files-accepted', acceptedFiles);\n }\n};\n\nconst processFiles = (incomingFiles: File[]) => {\n if (isUnavailable.value || incomingFiles.length === 0) {\n return;\n }\n\n const nextFiles = props.multiple ? [...props.modelValue] : [];\n const acceptedFiles: File[] = [];\n const rejections: TFileUploadRejection[] = [];\n let remainingSlots = Number.isFinite(effectiveMaxFiles.value)\n ? Math.max(effectiveMaxFiles.value - nextFiles.length, 0)\n : Number.POSITIVE_INFINITY;\n\n for (const file of incomingFiles) {\n if (remainingSlots <= 0) {\n rejections.push({\n file,\n reason: 'too-many-files',\n message: buildRejectionMessage(file, 'too-many-files'),\n });\n continue;\n }\n\n if (!matchesAccept(file)) {\n rejections.push({\n file,\n reason: 'file-invalid-type',\n message: buildRejectionMessage(file, 'file-invalid-type'),\n });\n continue;\n }\n\n if (\n typeof props.maxFileSize === 'number' &&\n props.maxFileSize > 0 &&\n file.size > props.maxFileSize\n ) {\n rejections.push({\n file,\n reason: 'file-too-large',\n message: buildRejectionMessage(file, 'file-too-large'),\n });\n continue;\n }\n\n acceptedFiles.push(file);\n nextFiles.push(file);\n\n if (Number.isFinite(remainingSlots)) {\n remainingSlots -= 1;\n }\n }\n\n emitFiles(nextFiles, acceptedFiles, rejections);\n};\n\nconst removeFile = (index: number) => {\n if (isUnavailable.value) {\n return;\n }\n\n feedbackMessages.value = [];\n emit('update:modelValue', props.modelValue.filter((_, fileIndex) => fileIndex !== index));\n};\n\nconst clearFiles = () => {\n if (isUnavailable.value || !hasFiles.value) {\n return;\n }\n\n feedbackMessages.value = [];\n emit('update:modelValue', []);\n};\n\nconst hasTransferFiles = (dataTransfer?: DataTransfer | null) => {\n if (!dataTransfer) {\n return false;\n }\n\n return dataTransfer.files.length > 0 || Array.from(dataTransfer.types).includes('Files');\n};\n\nconst getClipboardFiles = (\n clipboardData?: Pick<DataTransfer, 'items'> | null,\n) => {\n if (!clipboardData?.items) {\n return [];\n }\n\n return Array.from(clipboardData.items)\n .map((item) => item.getAsFile?.() ?? null)\n .filter((file): file is File => file instanceof File);\n};\n\nconst onInputChange = (event: Event) => {\n const target = event.target as HTMLInputElement;\n processFiles(Array.from(target.files ?? []));\n resetInputValue();\n};\n\nconst onDropzoneKeydown = (event: KeyboardEvent) => {\n if (!isActivationKey(event) || isUnavailable.value) {\n return;\n }\n\n event.preventDefault();\n openFileDialog();\n};\n\nconst onFocusIn = () => {\n isFocusedWithin.value = true;\n};\n\nconst onFocusOut = (event: FocusEvent) => {\n const nextTarget = event.relatedTarget as Node | null;\n\n if (nextTarget && rootRef.value?.contains(nextTarget)) {\n return;\n }\n\n isFocusedWithin.value = false;\n};\n\nconst onPaste = (event: ClipboardEvent) => {\n if (!props.paste || isUnavailable.value) {\n return;\n }\n\n const clipboardFiles = getClipboardFiles(event.clipboardData);\n\n if (clipboardFiles.length === 0) {\n return;\n }\n\n event.preventDefault();\n processFiles(clipboardFiles);\n};\n\nconst onDocumentPaste = (event: Event) => {\n if (!isFocusedWithin.value || event.defaultPrevented) {\n return;\n }\n\n onPaste(event as ClipboardEvent);\n};\n\nconst onDragEnter = (event: DragEvent) => {\n if (!props.drop || isUnavailable.value || !hasTransferFiles(event.dataTransfer)) {\n return;\n }\n\n event.preventDefault();\n dragDepth.value += 1;\n isDragActive.value = true;\n};\n\nconst onDragOver = (event: DragEvent) => {\n if (!props.drop || isUnavailable.value || !hasTransferFiles(event.dataTransfer)) {\n return;\n }\n\n event.preventDefault();\n\n if (event.dataTransfer) {\n event.dataTransfer.dropEffect = 'copy';\n }\n\n isDragActive.value = true;\n};\n\nconst onDragLeave = (event: DragEvent) => {\n if (!props.drop || isUnavailable.value || !hasTransferFiles(event.dataTransfer)) {\n return;\n }\n\n event.preventDefault();\n dragDepth.value = Math.max(dragDepth.value - 1, 0);\n\n if (dragDepth.value === 0) {\n isDragActive.value = false;\n }\n};\n\nconst onDrop = (event: DragEvent) => {\n if (!props.drop || isUnavailable.value || !hasTransferFiles(event.dataTransfer)) {\n return;\n }\n\n event.preventDefault();\n dragDepth.value = 0;\n isDragActive.value = false;\n processFiles(Array.from(event.dataTransfer?.files ?? []));\n};\n\nonMounted(() => {\n document.addEventListener('paste', onDocumentPaste);\n});\n\nonBeforeUnmount(() => {\n document.removeEventListener('paste', onDocumentPaste);\n});\n</script>\n\n<template>\n <div\n ref=\"rootRef\"\n v-bind=\"rootAttrs\"\n :class=\"rootClasses\"\n :style=\"rootStyle\"\n @focusin=\"onFocusIn\"\n @focusout=\"onFocusOut\"\n @paste=\"onPaste\"\n >\n <input\n :id=\"uploadId\"\n ref=\"inputRef\"\n class=\"t-visually-hidden\"\n type=\"file\"\n :accept=\"accept || undefined\"\n :multiple=\"multiple\"\n :disabled=\"isUnavailable\"\n @change=\"onInputChange\"\n >\n\n <div\n class=\"t-file-upload__dropzone\"\n :aria-busy=\"loading || undefined\"\n :aria-controls=\"showFileList && hasFiles ? filesId : undefined\"\n :aria-describedby=\"describedBy\"\n :aria-disabled=\"isUnavailable || undefined\"\n :aria-invalid=\"invalid || undefined\"\n role=\"button\"\n :tabindex=\"isUnavailable ? -1 : 0\"\n @click=\"openFileDialog\"\n @keydown=\"onDropzoneKeydown\"\n @dragenter=\"onDragEnter\"\n @dragover=\"onDragOver\"\n @dragleave=\"onDragLeave\"\n @drop=\"onDrop\"\n >\n <div\n v-if=\"$slots.icon || !$slots.default\"\n class=\"t-file-upload__icon\"\n aria-hidden=\"true\"\n >\n <slot name=\"icon\">\n <span class=\"t-file-upload__icon-mark\">+</span>\n </slot>\n </div>\n\n <div class=\"t-file-upload__content\">\n <slot\n :files=\"modelValue\"\n :is-drag-active=\"isDragActive\"\n :open-file-dialog=\"openFileDialog\"\n :clear-files=\"clearFiles\"\n >\n <p class=\"t-file-upload__label\">\n {{ label }}\n </p>\n <p\n v-if=\"description\"\n :id=\"descriptionId\"\n class=\"t-file-upload__description\"\n >\n {{ description }}\n </p>\n <span class=\"t-file-upload__browse\">\n {{ buttonLabel }}\n </span>\n </slot>\n </div>\n\n <TSpinner\n v-if=\"loading\"\n class=\"t-file-upload__spinner\"\n size=\"sm\"\n label=\"Uploading files\"\n />\n </div>\n\n <ul\n v-if=\"feedbackMessages.length > 0\"\n :id=\"feedbackId\"\n class=\"t-file-upload__feedback\"\n aria-live=\"polite\"\n >\n <li\n v-for=\"message in feedbackMessages\"\n :key=\"message\"\n >\n {{ message }}\n </li>\n </ul>\n\n <div\n v-if=\"showFileList && hasFiles\"\n class=\"t-file-upload__files\"\n >\n <div class=\"t-file-upload__files-header\">\n <p\n :id=\"filesId\"\n class=\"t-file-upload__files-label\"\n >\n {{ selectedFilesLabel }}\n </p>\n\n <button\n class=\"t-file-upload__clear\"\n type=\"button\"\n :disabled=\"isUnavailable\"\n @click=\"clearFiles\"\n >\n Clear all\n </button>\n </div>\n\n <ul class=\"t-file-upload__list\">\n <li\n v-for=\"(file, index) in modelValue\"\n :key=\"fileKey(file, index)\"\n class=\"t-file-upload__file\"\n >\n <slot\n name=\"file\"\n :file=\"file\"\n :index=\"index\"\n :remove-file=\"() => removeFile(index)\"\n >\n <div class=\"t-file-upload__file-copy\">\n <p class=\"t-file-upload__file-name\">\n {{ file.name }}\n </p>\n <p class=\"t-file-upload__file-meta\">\n {{ formatFileSize(file.size) }}\n </p>\n </div>\n\n <button\n class=\"t-file-upload__remove\"\n type=\"button\"\n :disabled=\"isUnavailable\"\n :aria-label=\"`Remove ${file.name}`\"\n @click=\"removeFile(index)\"\n >\n Remove\n </button>\n </slot>\n </li>\n </ul>\n </div>\n\n <div\n v-if=\"$slots.actions\"\n class=\"t-file-upload__actions\"\n >\n <slot\n name=\"actions\"\n :files=\"modelValue\"\n :open-file-dialog=\"openFileDialog\"\n :clear-files=\"clearFiles\"\n />\n </div>\n </div>\n</template>\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"TFileUpload.vue_vue_type_script_setup_true_lang.cjs","names":["$slots"],"sources":["../../src/components/TFileUpload.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { createId, isActivationKey } from '@treeui/utils';\nimport { computed, onBeforeUnmount, onMounted, ref, useAttrs, watch } from 'vue';\nimport type { TSize } from '../types/contracts';\nimport TProgress from './TProgress.vue';\nimport TSpinner from './TSpinner.vue';\n\ndefineOptions({\n inheritAttrs: false,\n});\n\nexport type TFileUploadRejectionReason =\n | 'file-invalid-type'\n | 'file-too-large'\n | 'too-many-files';\n\nexport interface TFileUploadRejection {\n file: File;\n reason: TFileUploadRejectionReason;\n message: string;\n}\n\nexport type TFileUploadStatus =\n | 'pending'\n | 'uploading'\n | 'paused'\n | 'error'\n | 'success';\n\nexport interface TFileUploadState {\n status: TFileUploadStatus;\n progress?: number;\n uploadedBytes?: number;\n remainingMs?: number;\n remainingLabel?: string;\n error?: string;\n resumable?: boolean;\n retryable?: boolean;\n thumbnailUrl?: string;\n meta?: string;\n}\n\nexport type TFileUploadStateSource =\n | ReadonlyMap<File, TFileUploadState>\n | ((file: File, index: number) => TFileUploadState | undefined);\n\nexport interface TFileUploadRetryPayload {\n file: File;\n index: number;\n fileKey: string;\n mode: 'resume' | 'restart';\n state: TFileUploadState;\n}\n\nexport interface TFileUploadCancelPayload {\n file: File;\n index: number;\n fileKey: string;\n state: TFileUploadState;\n reason: 'remove' | 'clear';\n}\n\nexport interface TFileUploadFileSlotProps {\n file: File;\n index: number;\n fileKey: string;\n state: TFileUploadState | undefined;\n thumbnailUrl: string | undefined;\n sizeLabel: string;\n typeLabel: string;\n dimensionsLabel: string | undefined;\n progressLabel: string | undefined;\n remainingLabel: string | undefined;\n uploadedLabel: string | undefined;\n statusLabel: string | undefined;\n actionLabel: string | undefined;\n canRetry: boolean;\n retryMode: 'resume' | 'restart';\n isDragActive: boolean;\n isDragReject: boolean;\n removeFile: () => void;\n retryFile: () => void;\n}\n\ninterface ThumbEntry {\n url: string;\n width: number | null;\n height: number | null;\n}\n\ninterface FileRow {\n slotProps: TFileUploadFileSlotProps;\n rowClass: string | undefined;\n metaText: string;\n statusText: string;\n errorText: string | undefined;\n errorId: string | undefined;\n showProgress: boolean;\n progressValue: number | undefined;\n progressAriaLabel: string;\n isBusy: boolean;\n isSuccess: boolean;\n}\n\nconst DEFAULT_STATUS_LABELS: Record<TFileUploadStatus, string> = {\n pending: 'Waiting',\n uploading: 'Uploading',\n paused: 'Paused',\n error: 'Upload failed',\n success: 'Uploaded',\n};\n\n// The status log keeps a bounded history of announcements. Old entries are\n// trimmed rather than replaced in place so that each terminal transition\n// inserts a brand new node: `aria-relevant` defaults to \"additions text\", so\n// assistive tech announces the insertion and ignores the trim.\nconst STATUS_LOG_LIMIT = 5;\n\ntype StatusLogEntry = {\n id: number;\n text: string;\n};\n\nconst slots = defineSlots<{\n icon?: () => unknown;\n default?: (props: {\n files: File[];\n isDragActive: boolean;\n isDragReject: boolean;\n openFileDialog: () => void;\n clearFiles: () => void;\n }) => unknown;\n file?: (props: TFileUploadFileSlotProps) => unknown;\n 'file-status'?: (props: TFileUploadFileSlotProps) => unknown;\n actions?: (props: {\n files: File[];\n openFileDialog: () => void;\n clearFiles: () => void;\n }) => unknown;\n}>();\n\nconst props = withDefaults(\n defineProps<{\n modelValue?: File[];\n size?: TSize;\n disabled?: boolean;\n loading?: boolean;\n invalid?: boolean;\n accept?: string;\n multiple?: boolean;\n maxFiles?: number | null;\n maxFileSize?: number | null;\n label?: string;\n description?: string;\n buttonLabel?: string;\n filesLabel?: string;\n paste?: boolean;\n drop?: boolean;\n showFileList?: boolean;\n uploadState?: TFileUploadStateSource;\n dragLabel?: string;\n dragRejectLabel?: string;\n thumbnails?: boolean;\n maxThumbnailSize?: number | null;\n retryLabel?: string;\n resumeLabel?: (percent: number) => string;\n remainingTimeFormat?: (remainingMs: number) => string;\n statusLabels?: Partial<Record<TFileUploadStatus, string>>;\n }>(),\n {\n modelValue: () => [],\n size: 'md',\n disabled: false,\n loading: false,\n invalid: false,\n accept: '',\n multiple: true,\n label: 'Drop files here',\n description: 'Click to browse, drag and drop, or paste with Ctrl+V.',\n buttonLabel: 'Browse files',\n filesLabel: 'Selected files',\n maxFiles: null,\n maxFileSize: null,\n paste: true,\n drop: true,\n showFileList: true,\n uploadState: undefined,\n dragLabel: 'Release to upload',\n dragRejectLabel: 'This file type is not accepted',\n thumbnails: true,\n maxThumbnailSize: 10 * 1024 * 1024,\n retryLabel: 'Retry',\n resumeLabel: (percent: number) => `Resume from ${percent}%`,\n remainingTimeFormat: (remainingMs: number) => {\n if (remainingMs < 5000) {\n return 'Less than 5s left';\n }\n\n const seconds = Math.round(remainingMs / 1000);\n\n if (seconds < 60) {\n return `About ${seconds}s left`;\n }\n\n const minutes = Math.round(seconds / 60);\n\n if (minutes < 60) {\n return `About ${minutes} min left`;\n }\n\n return `About ${Math.round(minutes / 60)}h left`;\n },\n statusLabels: () => ({}),\n },\n);\n\nconst emit = defineEmits<{\n 'update:modelValue': [files: File[]];\n 'files-accepted': [files: File[]];\n 'files-rejected': [rejections: TFileUploadRejection[]];\n retry: [payload: TFileUploadRetryPayload];\n cancel: [payload: TFileUploadCancelPayload];\n}>();\n\nconst attrs = useAttrs();\nconst rootRef = ref<HTMLElement | null>(null);\nconst inputRef = ref<HTMLInputElement | null>(null);\nconst isDragActive = ref(false);\nconst isDragReject = ref(false);\nconst isFocusedWithin = ref(false);\nconst dragDepth = ref(0);\nconst feedbackMessages = ref<string[]>([]);\nconst statusLog = ref<StatusLogEntry[]>([]);\nlet statusLogId = 0;\nconst retryFocusKey = ref<string | null>(null);\nconst thumbs = ref(new Map<File, ThumbEntry>());\n\nconst uploadId = createId('t-file-upload');\nconst descriptionId = `${uploadId}-description`;\nconst feedbackId = `${uploadId}-feedback`;\nconst filesId = `${uploadId}-files`;\n\nconst isDisabled = computed(() => props.disabled);\nconst hasFiles = computed(() => props.modelValue.length > 0);\nconst hasCustomBody = computed(() => Boolean(slots.default));\n\nconst resolvedStatusLabels = computed(() => ({\n ...DEFAULT_STATUS_LABELS,\n ...props.statusLabels,\n}));\n\nconst effectiveMaxFiles = computed(() => {\n if (!props.multiple) {\n return 1;\n }\n\n if (typeof props.maxFiles !== 'number') {\n return Number.POSITIVE_INFINITY;\n }\n\n return Math.max(props.maxFiles, 0);\n});\n\nconst rootClasses = computed(() => [\n 't-file-upload',\n `t-file-upload--${props.size}`,\n {\n 'is-disabled': isDisabled.value,\n 'is-invalid': props.invalid,\n 'is-loading': props.loading,\n 'is-drag-active': isDragActive.value,\n 'is-drag-reject': isDragReject.value,\n 'has-files': hasFiles.value,\n },\n attrs.class,\n]);\n\nconst rootStyle = computed(() => attrs.style);\n\nconst rootAttrs = computed(() => {\n const { class: _class, style: _style, ...rest } = attrs;\n return rest;\n});\n\nconst describedBy = computed(() => {\n const ids: string[] = [];\n\n if (props.description && !hasCustomBody.value) {\n ids.push(descriptionId);\n }\n\n if (feedbackMessages.value.length > 0) {\n ids.push(feedbackId);\n }\n\n if (props.showFileList && hasFiles.value) {\n ids.push(filesId);\n }\n\n return ids.length > 0 ? ids.join(' ') : undefined;\n});\n\nconst selectedFilesLabel = computed(() => `${props.filesLabel} (${props.modelValue.length})`);\n\nconst dropzoneLabel = computed(() => {\n if (isDragReject.value) {\n return props.dragRejectLabel;\n }\n\n return isDragActive.value ? props.dragLabel : props.label;\n});\n\nconst formatFileSize = (size: number) => {\n if (size < 1024) {\n return `${size} B`;\n }\n\n const units = ['KB', 'MB', 'GB'];\n let value = size / 1024;\n let unitIndex = 0;\n\n while (value >= 1024 && unitIndex < units.length - 1) {\n value /= 1024;\n unitIndex += 1;\n }\n\n const roundedValue = value >= 10 || Number.isInteger(value)\n ? Math.round(value)\n : Number(value.toFixed(1));\n\n return `${roundedValue} ${units[unitIndex]}`;\n};\n\nconst formatFileType = (file: File) => {\n const dotIndex = file.name.lastIndexOf('.');\n const extension = dotIndex > 0 && dotIndex < file.name.length - 1\n ? file.name.slice(dotIndex + 1).toUpperCase()\n : '';\n\n if (extension && extension.length <= 5) {\n return extension;\n }\n\n const subtype = file.type.includes('/') ? file.type.split('/')[1] : '';\n\n return subtype ? subtype.toUpperCase() : 'FILE';\n};\n\nlet keySeq = 0;\nconst keyCache = new WeakMap<File, string>();\n\nconst fileKeyFor = (file: File) => {\n let key = keyCache.get(file);\n\n if (!key) {\n keySeq += 1;\n key = `${uploadId}-f${keySeq}`;\n keyCache.set(file, key);\n }\n\n return key;\n};\n\nconst acceptTokens = computed(() =>\n props.accept\n .split(',')\n .map((token) => token.trim().toLowerCase())\n .filter(Boolean),\n);\n\nconst matchesAccept = (file: File) => {\n if (acceptTokens.value.length === 0) {\n return true;\n }\n\n const fileName = file.name.toLowerCase();\n const fileType = file.type.toLowerCase();\n\n return acceptTokens.value.some((token) => {\n if (token.startsWith('.')) {\n return fileName.endsWith(token);\n }\n\n if (token.endsWith('/*')) {\n return fileType.startsWith(token.slice(0, -1));\n }\n\n return fileType === token;\n });\n};\n\nconst canDetectDragReject = computed(() =>\n acceptTokens.value.length > 0 && acceptTokens.value.every((token) => token.includes('/')),\n);\n\nconst matchesAcceptType = (type: string) => {\n const fileType = type.toLowerCase();\n\n if (!fileType) {\n return true;\n }\n\n return acceptTokens.value.some((token) =>\n token.endsWith('/*') ? fileType.startsWith(token.slice(0, -1)) : fileType === token,\n );\n};\n\nconst detectDragReject = (dataTransfer?: DataTransfer | null) => {\n if (!canDetectDragReject.value || !dataTransfer) {\n return false;\n }\n\n const items = dataTransfer.items;\n\n if (!items || items.length === 0) {\n return false;\n }\n\n const fileItems = Array.from(items).filter((item) => item.kind === 'file');\n\n if (fileItems.length === 0) {\n return false;\n }\n\n return fileItems.every((item) => !matchesAcceptType(item.type));\n};\n\nconst resolveState = (file: File, index: number) => {\n const source = props.uploadState;\n\n if (!source) {\n return undefined;\n }\n\n return typeof source === 'function' ? source(file, index) : source.get(file);\n};\n\nconst resolvedStates = computed(() => props.modelValue.map(resolveState));\n\nconst canUseObjectUrl = () =>\n typeof window !== 'undefined' &&\n typeof URL !== 'undefined' &&\n typeof URL.createObjectURL === 'function' &&\n typeof URL.revokeObjectURL === 'function';\n\nconst isThumbnailable = (file: File) =>\n file.type.startsWith('image/') &&\n (props.maxThumbnailSize === null || file.size <= props.maxThumbnailSize);\n\nconst releaseAllThumbnails = () => {\n if (canUseObjectUrl()) {\n for (const entry of thumbs.value.values()) {\n URL.revokeObjectURL(entry.url);\n }\n }\n\n thumbs.value.clear();\n};\n\nconst syncThumbnails = () => {\n if (!props.thumbnails || !canUseObjectUrl()) {\n releaseAllThumbnails();\n return;\n }\n\n const live = new Set(props.modelValue);\n\n for (const [file, entry] of [...thumbs.value]) {\n if (!live.has(file)) {\n URL.revokeObjectURL(entry.url);\n thumbs.value.delete(file);\n }\n }\n\n for (const file of props.modelValue) {\n if (thumbs.value.has(file) || !isThumbnailable(file)) {\n continue;\n }\n\n const url = URL.createObjectURL(file);\n thumbs.value.set(file, { url, width: null, height: null });\n\n const image = new Image();\n\n image.onload = () => {\n const current = thumbs.value.get(file);\n\n if (!current || current.url !== url) {\n return;\n }\n\n thumbs.value.set(file, { url, width: image.naturalWidth, height: image.naturalHeight });\n };\n\n image.src = url;\n }\n};\n\nconst buildRejectionMessage = (\n file: File,\n reason: TFileUploadRejectionReason,\n) => {\n switch (reason) {\n case 'file-invalid-type':\n return `${file.name} is not an accepted file type.`;\n case 'file-too-large':\n return `${file.name} exceeds the ${formatFileSize(props.maxFileSize ?? 0)} limit.`;\n case 'too-many-files':\n return `You can only add up to ${effectiveMaxFiles.value} file${effectiveMaxFiles.value === 1 ? '' : 's'}.`;\n default:\n return `${file.name} could not be added.`;\n }\n};\n\nconst resetInputValue = () => {\n if (inputRef.value) {\n inputRef.value.value = '';\n }\n};\n\nconst openFileDialog = () => {\n if (isDisabled.value) {\n return;\n }\n\n inputRef.value?.click();\n};\n\nconst emitFiles = (\n nextFiles: File[],\n acceptedFiles: File[],\n rejections: TFileUploadRejection[],\n) => {\n feedbackMessages.value = rejections.map((rejection) => rejection.message);\n\n if (rejections.length > 0) {\n emit('files-rejected', rejections);\n }\n\n if (acceptedFiles.length > 0) {\n emit('update:modelValue', nextFiles);\n emit('files-accepted', acceptedFiles);\n }\n};\n\nconst processFiles = (incomingFiles: File[]) => {\n if (isDisabled.value || incomingFiles.length === 0) {\n return;\n }\n\n const nextFiles = props.multiple ? [...props.modelValue] : [];\n const acceptedFiles: File[] = [];\n const rejections: TFileUploadRejection[] = [];\n let remainingSlots = Number.isFinite(effectiveMaxFiles.value)\n ? Math.max(effectiveMaxFiles.value - nextFiles.length, 0)\n : Number.POSITIVE_INFINITY;\n\n for (const file of incomingFiles) {\n if (remainingSlots <= 0) {\n rejections.push({\n file,\n reason: 'too-many-files',\n message: buildRejectionMessage(file, 'too-many-files'),\n });\n continue;\n }\n\n if (!matchesAccept(file)) {\n rejections.push({\n file,\n reason: 'file-invalid-type',\n message: buildRejectionMessage(file, 'file-invalid-type'),\n });\n continue;\n }\n\n if (\n typeof props.maxFileSize === 'number' &&\n props.maxFileSize > 0 &&\n file.size > props.maxFileSize\n ) {\n rejections.push({\n file,\n reason: 'file-too-large',\n message: buildRejectionMessage(file, 'file-too-large'),\n });\n continue;\n }\n\n acceptedFiles.push(file);\n nextFiles.push(file);\n\n if (Number.isFinite(remainingSlots)) {\n remainingSlots -= 1;\n }\n }\n\n emitFiles(nextFiles, acceptedFiles, rejections);\n};\n\nconst emitCancel = (file: File, index: number, reason: 'remove' | 'clear') => {\n const state = resolvedStates.value[index];\n\n if (!state || (state.status !== 'uploading' && state.status !== 'paused')) {\n return;\n }\n\n emit('cancel', { file, index, fileKey: fileKeyFor(file), state, reason });\n};\n\nconst removeFile = (index: number) => {\n if (isDisabled.value) {\n return;\n }\n\n const file = props.modelValue[index];\n\n if (file) {\n emitCancel(file, index, 'remove');\n }\n\n feedbackMessages.value = [];\n emit('update:modelValue', props.modelValue.filter((_, fileIndex) => fileIndex !== index));\n};\n\nconst clearFiles = () => {\n if (isDisabled.value || !hasFiles.value) {\n return;\n }\n\n props.modelValue.forEach((file, index) => {\n emitCancel(file, index, 'clear');\n });\n\n feedbackMessages.value = [];\n emit('update:modelValue', []);\n};\n\nconst rows = computed<FileRow[]>(() =>\n props.modelValue.map((file, index) => {\n const state = resolvedStates.value[index];\n const status = state?.status;\n const thumb = thumbs.value.get(file);\n const key = fileKeyFor(file);\n\n const progress = state?.progress;\n const percent = typeof progress === 'number' ? Math.round(progress) : undefined;\n const isResumable = state?.resumable === true;\n\n const canRetry = Boolean(\n state && (status === 'error' || status === 'paused') && state.retryable !== false,\n );\n const retryMode: 'resume' | 'restart' = isResumable ? 'resume' : 'restart';\n\n const sizeLabel = formatFileSize(file.size);\n const typeLabel = formatFileType(file);\n const dimensionsLabel = thumb && thumb.width !== null && thumb.height !== null\n ? `${thumb.width} × ${thumb.height}`\n : undefined;\n\n const progressLabel = status === 'uploading' && percent !== undefined\n ? `${percent}%`\n : undefined;\n\n let remainingLabel: string | undefined;\n\n if (status === 'uploading') {\n if (state?.remainingLabel) {\n remainingLabel = state.remainingLabel;\n } else if (\n typeof state?.remainingMs === 'number' &&\n Number.isFinite(state.remainingMs) &&\n state.remainingMs >= 0\n ) {\n remainingLabel = props.remainingTimeFormat(state.remainingMs);\n }\n }\n\n const uploadedLabel = (status === 'error' || status === 'paused') &&\n typeof state?.uploadedBytes === 'number'\n ? `${formatFileSize(state.uploadedBytes)} of ${sizeLabel} uploaded`\n : undefined;\n\n const statusLabel = status ? resolvedStatusLabels.value[status] : undefined;\n\n let actionLabel: string | undefined;\n\n if (canRetry) {\n actionLabel = isResumable && percent !== undefined\n ? props.resumeLabel(percent)\n : props.retryLabel;\n }\n\n const errorText = status === 'error' ? state?.error : undefined;\n\n const slotProps: TFileUploadFileSlotProps = {\n file,\n index,\n fileKey: key,\n state,\n thumbnailUrl: state?.thumbnailUrl ?? thumb?.url,\n sizeLabel,\n typeLabel,\n dimensionsLabel,\n progressLabel,\n remainingLabel,\n uploadedLabel,\n statusLabel,\n actionLabel,\n canRetry,\n retryMode,\n isDragActive: isDragActive.value,\n isDragReject: isDragReject.value,\n removeFile: () => removeFile(index),\n retryFile: () => {\n if (!canRetry || isDisabled.value || !state) {\n return;\n }\n\n emit('retry', { file, index, fileKey: key, mode: retryMode, state });\n },\n };\n\n return {\n slotProps,\n rowClass: status ? `is-${status}` : undefined,\n metaText: [typeLabel, sizeLabel, dimensionsLabel, state?.meta].filter(Boolean).join(' · '),\n statusText: [statusLabel, progressLabel, remainingLabel, uploadedLabel]\n .filter(Boolean)\n .join(' · '),\n errorText,\n errorId: errorText ? `${key}-error` : undefined,\n showProgress: Boolean(\n state &&\n (status === 'uploading' ||\n status === 'paused' ||\n status === 'error' ||\n (status === 'success' && percent !== undefined)),\n ),\n progressValue: status === 'uploading' ? progress : (progress ?? 0),\n progressAriaLabel: `${statusLabel ?? ''} ${file.name}`.trim(),\n isBusy: status === 'uploading',\n isSuccess: status === 'success',\n };\n }),\n);\n\nconst hasTransferFiles = (dataTransfer?: DataTransfer | null) => {\n if (!dataTransfer) {\n return false;\n }\n\n return dataTransfer.files.length > 0 || Array.from(dataTransfer.types).includes('Files');\n};\n\nconst getClipboardFiles = (\n clipboardData?: Pick<DataTransfer, 'items'> | null,\n) => {\n if (!clipboardData?.items) {\n return [];\n }\n\n return Array.from(clipboardData.items)\n .map((item) => item.getAsFile?.() ?? null)\n .filter((file): file is File => file instanceof File);\n};\n\nconst onInputChange = (event: Event) => {\n const target = event.target as HTMLInputElement;\n processFiles(Array.from(target.files ?? []));\n resetInputValue();\n};\n\nconst onDropzoneKeydown = (event: KeyboardEvent) => {\n if (!isActivationKey(event) || isDisabled.value) {\n return;\n }\n\n event.preventDefault();\n openFileDialog();\n};\n\nconst onFocusIn = () => {\n isFocusedWithin.value = true;\n};\n\nconst onFocusOut = (event: FocusEvent) => {\n const nextTarget = event.relatedTarget as Node | null;\n\n if (nextTarget && rootRef.value?.contains(nextTarget)) {\n return;\n }\n\n isFocusedWithin.value = false;\n};\n\nconst onRetryFocus = (key: string) => {\n retryFocusKey.value = key;\n};\n\nconst onRetryBlur = (key: string) => {\n if (retryFocusKey.value === key) {\n retryFocusKey.value = null;\n }\n};\n\nconst onPaste = (event: ClipboardEvent) => {\n if (!props.paste || isDisabled.value) {\n return;\n }\n\n const clipboardFiles = getClipboardFiles(event.clipboardData);\n\n if (clipboardFiles.length === 0) {\n return;\n }\n\n event.preventDefault();\n processFiles(clipboardFiles);\n};\n\nconst onDocumentPaste = (event: Event) => {\n if (!isFocusedWithin.value || event.defaultPrevented) {\n return;\n }\n\n onPaste(event as ClipboardEvent);\n};\n\nconst onDragEnter = (event: DragEvent) => {\n if (!props.drop || isDisabled.value || !hasTransferFiles(event.dataTransfer)) {\n return;\n }\n\n event.preventDefault();\n dragDepth.value += 1;\n isDragActive.value = true;\n isDragReject.value = detectDragReject(event.dataTransfer);\n};\n\nconst onDragOver = (event: DragEvent) => {\n if (!props.drop || isDisabled.value || !hasTransferFiles(event.dataTransfer)) {\n return;\n }\n\n event.preventDefault();\n\n if (event.dataTransfer) {\n event.dataTransfer.dropEffect = 'copy';\n }\n\n isDragActive.value = true;\n isDragReject.value = detectDragReject(event.dataTransfer);\n};\n\nconst onDragLeave = (event: DragEvent) => {\n if (!props.drop || isDisabled.value || !hasTransferFiles(event.dataTransfer)) {\n return;\n }\n\n event.preventDefault();\n dragDepth.value = Math.max(dragDepth.value - 1, 0);\n\n if (dragDepth.value === 0) {\n isDragActive.value = false;\n isDragReject.value = false;\n }\n};\n\nconst onDrop = (event: DragEvent) => {\n if (!props.drop || isDisabled.value || !hasTransferFiles(event.dataTransfer)) {\n return;\n }\n\n event.preventDefault();\n dragDepth.value = 0;\n isDragActive.value = false;\n isDragReject.value = false;\n processFiles(Array.from(event.dataTransfer?.files ?? []));\n};\n\nconst previousStatuses = new Map<File, TFileUploadStatus>();\n\nwatch(\n resolvedStates,\n (states) => {\n const messages: string[] = [];\n const live = new Set<File>();\n\n props.modelValue.forEach((file, index) => {\n live.add(file);\n\n const status = states[index]?.status;\n\n if (!status) {\n return;\n }\n\n const previous = previousStatuses.get(file);\n\n if (previous === status) {\n return;\n }\n\n previousStatuses.set(file, status);\n\n if (previous === undefined) {\n return;\n }\n\n if (status === 'success') {\n messages.push(`${file.name} uploaded.`);\n } else if (status === 'error') {\n messages.push(`${file.name} failed. ${states[index]?.error ?? ''}`.trim());\n }\n });\n\n for (const file of [...previousStatuses.keys()]) {\n if (!live.has(file)) {\n previousStatuses.delete(file);\n }\n }\n\n if (messages.length > 0) {\n // Append instead of overwriting a single string: two identical messages\n // in a row (a retry that fails with the same error) would otherwise write\n // a byte-identical value, which `Object.is` suppresses — no DOM mutation,\n // so `aria-live` never fires and the repeat failure is announced as silence.\n statusLogId += 1;\n statusLog.value = [\n ...statusLog.value,\n { id: statusLogId, text: messages.join(' ') },\n ].slice(-STATUS_LOG_LIMIT);\n }\n },\n { flush: 'post', immediate: true },\n);\n\nwatch(\n resolvedStates,\n () => {\n const key = retryFocusKey.value;\n const root = rootRef.value;\n\n if (!key || !root) {\n return;\n }\n\n if (document.activeElement && document.activeElement !== document.body) {\n return;\n }\n\n if (root.querySelector(`[data-t-retry=\"${key}\"]`)) {\n return;\n }\n\n retryFocusKey.value = null;\n\n const fallback = root.querySelector<HTMLElement>(`[data-t-remove=\"${key}\"]`) ??\n root.querySelector<HTMLElement>('.t-file-upload__dropzone');\n\n fallback?.focus();\n },\n { flush: 'post' },\n);\n\nwatch(() => props.modelValue, syncThumbnails);\nwatch(() => props.thumbnails, syncThumbnails);\n\nonMounted(() => {\n document.addEventListener('paste', onDocumentPaste);\n syncThumbnails();\n});\n\nonBeforeUnmount(() => {\n document.removeEventListener('paste', onDocumentPaste);\n releaseAllThumbnails();\n});\n</script>\n\n<template>\n <div\n ref=\"rootRef\"\n v-bind=\"rootAttrs\"\n :class=\"rootClasses\"\n :style=\"rootStyle\"\n @focusin=\"onFocusIn\"\n @focusout=\"onFocusOut\"\n @paste=\"onPaste\"\n >\n <input\n :id=\"uploadId\"\n ref=\"inputRef\"\n class=\"t-visually-hidden\"\n type=\"file\"\n :accept=\"accept || undefined\"\n :multiple=\"multiple\"\n :disabled=\"isDisabled\"\n @change=\"onInputChange\"\n >\n\n <div\n class=\"t-file-upload__dropzone\"\n :aria-busy=\"loading || undefined\"\n :aria-controls=\"showFileList && hasFiles ? filesId : undefined\"\n :aria-describedby=\"describedBy\"\n :aria-disabled=\"isDisabled || undefined\"\n :aria-invalid=\"invalid || undefined\"\n role=\"button\"\n :tabindex=\"isDisabled ? -1 : 0\"\n @click=\"openFileDialog\"\n @keydown=\"onDropzoneKeydown\"\n @dragenter=\"onDragEnter\"\n @dragover=\"onDragOver\"\n @dragleave=\"onDragLeave\"\n @drop=\"onDrop\"\n >\n <div\n v-if=\"$slots.icon || !$slots.default\"\n class=\"t-file-upload__icon\"\n aria-hidden=\"true\"\n >\n <slot name=\"icon\">\n <span class=\"t-file-upload__icon-mark\">+</span>\n </slot>\n </div>\n\n <div class=\"t-file-upload__content\">\n <slot\n :files=\"modelValue\"\n :is-drag-active=\"isDragActive\"\n :is-drag-reject=\"isDragReject\"\n :open-file-dialog=\"openFileDialog\"\n :clear-files=\"clearFiles\"\n >\n <p class=\"t-file-upload__label\">\n {{ dropzoneLabel }}\n </p>\n <p\n v-if=\"description\"\n :id=\"descriptionId\"\n class=\"t-file-upload__description\"\n >\n {{ description }}\n </p>\n <span class=\"t-file-upload__browse\">\n {{ buttonLabel }}\n </span>\n </slot>\n </div>\n\n <TSpinner\n v-if=\"loading\"\n class=\"t-file-upload__spinner\"\n size=\"sm\"\n label=\"Uploading files\"\n />\n </div>\n\n <ul\n v-if=\"feedbackMessages.length > 0\"\n :id=\"feedbackId\"\n class=\"t-file-upload__feedback\"\n aria-live=\"polite\"\n >\n <li\n v-for=\"message in feedbackMessages\"\n :key=\"message\"\n >\n {{ message }}\n </li>\n </ul>\n\n <div\n class=\"t-file-upload__status-log t-visually-hidden\"\n role=\"log\"\n aria-live=\"polite\"\n >\n <p\n v-for=\"entry in statusLog\"\n :key=\"entry.id\"\n class=\"t-file-upload__status-log-entry\"\n >\n {{ entry.text }}\n </p>\n </div>\n\n <div\n v-if=\"showFileList && hasFiles\"\n class=\"t-file-upload__files\"\n >\n <div class=\"t-file-upload__files-header\">\n <p\n :id=\"filesId\"\n class=\"t-file-upload__files-label\"\n >\n {{ selectedFilesLabel }}\n </p>\n\n <button\n class=\"t-file-upload__clear\"\n type=\"button\"\n :disabled=\"isDisabled\"\n @click=\"clearFiles\"\n >\n Clear all\n </button>\n </div>\n\n <ul class=\"t-file-upload__list\">\n <li\n v-for=\"row in rows\"\n :key=\"row.slotProps.fileKey\"\n class=\"t-file-upload__file\"\n :class=\"row.rowClass\"\n :aria-busy=\"row.isBusy || undefined\"\n >\n <slot\n name=\"file\"\n v-bind=\"row.slotProps\"\n >\n <span\n class=\"t-file-upload__thumb\"\n aria-hidden=\"true\"\n >\n <img\n v-if=\"row.slotProps.thumbnailUrl\"\n class=\"t-file-upload__thumb-image\"\n :src=\"row.slotProps.thumbnailUrl\"\n alt=\"\"\n >\n <span\n v-else\n class=\"t-file-upload__thumb-fallback\"\n >\n {{ row.slotProps.typeLabel }}\n </span>\n </span>\n\n <div class=\"t-file-upload__file-copy\">\n <p class=\"t-file-upload__file-name\">\n {{ row.slotProps.file.name }}\n </p>\n <p class=\"t-file-upload__file-meta\">\n {{ row.metaText }}\n </p>\n\n <slot\n name=\"file-status\"\n v-bind=\"row.slotProps\"\n >\n <div\n v-if=\"row.showProgress\"\n class=\"t-file-upload__file-progress\"\n >\n <TProgress\n size=\"sm\"\n :value=\"row.progressValue\"\n :label=\"row.progressAriaLabel\"\n />\n </div>\n\n <p\n v-if=\"row.statusText\"\n class=\"t-file-upload__file-status\"\n >\n <span\n v-if=\"row.isSuccess\"\n class=\"t-file-upload__proof\"\n aria-hidden=\"true\"\n >✓</span>{{ row.statusText }}\n </p>\n\n <p\n v-if=\"row.errorText\"\n :id=\"row.errorId\"\n class=\"t-file-upload__file-error\"\n >\n {{ row.errorText }}\n </p>\n </slot>\n </div>\n\n <button\n v-if=\"row.slotProps.canRetry\"\n class=\"t-file-upload__retry\"\n type=\"button\"\n :data-t-retry=\"row.slotProps.fileKey\"\n :disabled=\"isDisabled\"\n :aria-describedby=\"row.errorId\"\n @focus=\"onRetryFocus(row.slotProps.fileKey)\"\n @blur=\"onRetryBlur(row.slotProps.fileKey)\"\n @click=\"row.slotProps.retryFile()\"\n >\n {{ row.slotProps.actionLabel }}\n </button>\n\n <button\n class=\"t-file-upload__remove\"\n type=\"button\"\n :data-t-remove=\"row.slotProps.fileKey\"\n :disabled=\"isDisabled\"\n :aria-label=\"`Remove ${row.slotProps.file.name}`\"\n @click=\"row.slotProps.removeFile()\"\n >\n Remove\n </button>\n </slot>\n </li>\n </ul>\n </div>\n\n <div\n v-if=\"$slots.actions\"\n class=\"t-file-upload__actions\"\n >\n <slot\n name=\"actions\"\n :files=\"modelValue\"\n :open-file-dialog=\"openFileDialog\"\n :clear-files=\"clearFiles\"\n />\n </div>\n </div>\n</template>\n"],"mappings":"+7EAwGA,IAAM,GAA2D,CAC/D,QAAS,UACT,UAAW,YACX,OAAQ,SACR,MAAO,gBACP,QAAS,UACX,EAaM,IAAA,EAAA,EAAA,SAAA,CAAQ,EAkBR,EAAQ,EA2ER,EAAO,EAQP,GAAA,EAAA,EAAA,SAAA,CAAiB,EACjB,GAAA,EAAA,EAAA,IAAA,CAAkC,IAAI,EACtC,GAAA,EAAA,EAAA,IAAA,CAAwC,IAAI,EAC5C,GAAA,EAAA,EAAA,IAAA,CAAmB,EAAK,EACxB,GAAA,EAAA,EAAA,IAAA,CAAmB,EAAK,EACxB,GAAA,EAAA,EAAA,IAAA,CAAsB,EAAK,EAC3B,GAAA,EAAA,EAAA,IAAA,CAAgB,CAAC,EACjB,GAAA,EAAA,EAAA,IAAA,CAAiC,CAAC,CAAC,EACnC,GAAA,EAAA,EAAA,IAAA,CAAkC,CAAC,CAAC,EACtC,EAAc,EACZ,GAAA,EAAA,EAAA,IAAA,CAAmC,IAAI,EACvC,GAAA,EAAA,EAAA,IAAA,CAAa,IAAI,GAAuB,EAExC,GAAA,EAAA,EAAA,SAAA,CAAoB,eAAe,EACnC,EAAgB,GAAG,EAAS,cAC5B,EAAa,GAAG,EAAS,WACzB,EAAU,GAAG,EAAS,QAEtB,GAAA,EAAA,EAAA,SAAA,KAA4B,EAAM,QAAQ,EAC1C,GAAA,EAAA,EAAA,SAAA,KAA0B,EAAM,WAAW,OAAS,CAAC,EACrD,IAAA,EAAA,EAAA,SAAA,KAA+B,EAAQ,GAAM,OAAQ,EAErD,IAAA,EAAA,EAAA,SAAA,MAAuC,CAC3C,GAAG,GACH,GAAG,EAAM,YACX,EAAE,EAEI,GAAA,EAAA,EAAA,SAAA,KACC,EAAM,SAIP,OAAO,EAAM,UAAa,SAIvB,KAAK,IAAI,EAAM,SAAU,CAAC,EAHxB,IAJA,CAQV,EAEK,IAAA,EAAA,EAAA,SAAA,KAA6B,CACjC,gBACA,kBAAkB,EAAM,OACxB,CACE,cAAe,EAAW,MAC1B,aAAc,EAAM,QACpB,aAAc,EAAM,QACpB,iBAAkB,EAAa,MAC/B,iBAAkB,EAAa,MAC/B,YAAa,EAAS,KACxB,EACA,EAAM,KACR,CAAC,EAEK,IAAA,EAAA,EAAA,SAAA,KAA2B,EAAM,KAAK,EAEtC,IAAA,EAAA,EAAA,SAAA,KAA2B,CAC/B,GAAM,CAAE,MAAO,EAAQ,MAAO,EAAQ,GAAG,GAAS,EAClD,OAAO,CACT,CAAC,EAEK,IAAA,EAAA,EAAA,SAAA,KAA6B,CACjC,IAAM,EAAgB,CAAC,EAcvB,OAZI,EAAM,aAAe,CAAC,GAAc,OACtC,EAAI,KAAK,CAAa,EAGpB,EAAiB,MAAM,OAAS,GAClC,EAAI,KAAK,CAAU,EAGjB,EAAM,cAAgB,EAAS,OACjC,EAAI,KAAK,CAAO,EAGX,EAAI,OAAS,EAAI,EAAI,KAAK,GAAG,EAAI,IAAA,EAC1C,CAAC,EAEK,IAAA,EAAA,EAAA,SAAA,KAAoC,GAAG,EAAM,WAAW,IAAI,EAAM,WAAW,OAAO,EAAE,EAEtF,IAAA,EAAA,EAAA,SAAA,KACA,EAAa,MACR,EAAM,gBAGR,EAAa,MAAQ,EAAM,UAAY,EAAM,KACrD,EAEK,EAAkB,GAAiB,CACvC,GAAI,EAAO,KACT,MAAO,GAAG,EAAK,IAGjB,IAAM,EAAQ,CAAC,KAAM,KAAM,IAAI,EAC3B,EAAQ,EAAO,KACf,EAAY,EAEhB,KAAO,GAAS,MAAQ,EAAY,EAAM,OAAS,GACjD,GAAS,KACT,GAAa,EAOf,MAAO,GAJc,GAAS,IAAM,OAAO,UAAU,CAAK,EACtD,KAAK,MAAM,CAAK,EAChB,OAAO,EAAM,QAAQ,CAAC,CAAC,EAEJ,GAAG,EAAM,IAClC,EAEM,GAAkB,GAAe,CACrC,IAAM,EAAW,EAAK,KAAK,YAAY,GAAG,EACpC,EAAY,EAAW,GAAK,EAAW,EAAK,KAAK,OAAS,EAC5D,EAAK,KAAK,MAAM,EAAW,CAAC,CAAC,CAAC,YAAY,EAC1C,GAEJ,GAAI,GAAa,EAAU,QAAU,EACnC,OAAO,EAGT,IAAM,EAAU,EAAK,KAAK,SAAS,GAAG,EAAI,EAAK,KAAK,MAAM,GAAG,CAAC,CAAC,GAAK,GAEpE,OAAO,EAAU,EAAQ,YAAY,EAAI,MAC3C,EAEI,EAAS,EACP,GAAW,IAAI,QAEf,GAAc,GAAe,CACjC,IAAI,EAAM,GAAS,IAAI,CAAI,EAQ3B,OANK,IACH,GAAU,EACV,EAAM,GAAG,EAAS,IAAI,IACtB,GAAS,IAAI,EAAM,CAAG,GAGjB,CACT,EAEM,GAAA,EAAA,EAAA,SAAA,KACJ,EAAM,OACH,MAAM,GAAG,CAAA,CACT,IAAK,GAAU,EAAM,KAAK,CAAC,CAAC,YAAY,CAAC,CAAA,CACzC,OAAO,OAAO,CACnB,EAEM,GAAiB,GAAe,CACpC,GAAI,EAAa,MAAM,SAAW,EAChC,MAAO,GAGT,IAAM,EAAW,EAAK,KAAK,YAAY,EACjC,EAAW,EAAK,KAAK,YAAY,EAEvC,OAAO,EAAa,MAAM,KAAM,GAC1B,EAAM,WAAW,GAAG,EACf,EAAS,SAAS,CAAK,EAG5B,EAAM,SAAS,IAAI,EACd,EAAS,WAAW,EAAM,MAAM,EAAG,EAAE,CAAC,EAGxC,IAAa,CACrB,CACH,EAEM,IAAA,EAAA,EAAA,SAAA,KACJ,EAAa,MAAM,OAAS,GAAK,EAAa,MAAM,MAAO,GAAU,EAAM,SAAS,GAAG,CAAC,CAC1F,EAEM,GAAqB,GAAiB,CAC1C,IAAM,EAAW,EAAK,YAAY,EAMlC,MAJA,CAAK,GAIE,EAAa,MAAM,KAAM,GAC9B,EAAM,SAAS,IAAI,EAAI,EAAS,WAAW,EAAM,MAAM,EAAG,EAAE,CAAC,EAAI,IAAa,CAChF,CACF,EAEM,GAAoB,GAAuC,CAC/D,GAAI,CAAC,GAAoB,OAAS,CAAC,EACjC,MAAO,GAGT,IAAM,EAAQ,EAAa,MAE3B,GAAI,CAAC,GAAS,EAAM,SAAW,EAC7B,MAAO,GAGT,IAAM,EAAY,MAAM,KAAK,CAAK,CAAC,CAAC,OAAQ,GAAS,EAAK,OAAS,MAAM,EAMzE,OAJI,EAAU,SAAW,GAIlB,EAAU,MAAO,GAAS,CAAC,GAAkB,EAAK,IAAI,CAAC,CAChE,EAEM,IAAgB,EAAY,IAAkB,CAClD,IAAM,EAAS,EAAM,YAEhB,KAIL,OAAO,OAAO,GAAW,WAAa,EAAO,EAAM,CAAK,EAAI,EAAO,IAAI,CAAI,CAC7E,EAEM,GAAA,EAAA,EAAA,SAAA,KAAgC,EAAM,WAAW,IAAI,EAAY,CAAC,EAElE,OACJ,OAAO,OAAW,KAClB,OAAO,IAAQ,KACf,OAAO,IAAI,iBAAoB,YAC/B,OAAO,IAAI,iBAAoB,WAE3B,GAAmB,GACvB,EAAK,KAAK,WAAW,QAAQ,IAC5B,EAAM,mBAAqB,MAAQ,EAAK,MAAQ,EAAM,kBAEnD,OAA6B,CACjC,GAAI,GAAgB,EAClB,IAAK,IAAM,KAAS,EAAO,MAAM,OAAO,EACtC,IAAI,gBAAgB,EAAM,GAAG,EAIjC,EAAO,MAAM,MAAM,CACrB,EAEM,MAAuB,CAC3B,GAAI,CAAC,EAAM,YAAc,CAAC,GAAgB,EAAG,CAC3C,GAAqB,EACrB,MACF,CAEA,IAAM,EAAO,IAAI,IAAI,EAAM,UAAU,EAErC,IAAK,GAAM,CAAC,EAAM,IAAU,CAAC,GAAG,EAAO,KAAK,EACrC,EAAK,IAAI,CAAI,IAChB,IAAI,gBAAgB,EAAM,GAAG,EAC7B,EAAO,MAAM,OAAO,CAAI,GAI5B,IAAK,IAAM,KAAQ,EAAM,WAAY,CACnC,GAAI,EAAO,MAAM,IAAI,CAAI,GAAK,CAAC,GAAgB,CAAI,EACjD,SAGF,IAAM,EAAM,IAAI,gBAAgB,CAAI,EACpC,EAAO,MAAM,IAAI,EAAM,CAAE,MAAK,MAAO,KAAM,OAAQ,IAAK,CAAC,EAEzD,IAAM,EAAQ,IAAI,MAElB,EAAM,WAAe,CACnB,IAAM,EAAU,EAAO,MAAM,IAAI,CAAI,EAEjC,CAAC,GAAW,EAAQ,MAAQ,GAIhC,EAAO,MAAM,IAAI,EAAM,CAAE,MAAK,MAAO,EAAM,aAAc,OAAQ,EAAM,aAAc,CAAC,CACxF,EAEA,EAAM,IAAM,CACd,CACF,EAEM,GACJ,EACA,IACG,CACH,OAAQ,EAAR,CACE,IAAK,oBACH,MAAO,GAAG,EAAK,KAAK,gCACtB,IAAK,iBACH,MAAO,GAAG,EAAK,KAAK,eAAe,EAAe,EAAM,aAAe,CAAC,EAAE,SAC5E,IAAK,iBACH,MAAO,0BAA0B,EAAkB,MAAM,OAAO,EAAkB,QAAU,EAAI,GAAK,IAAI,GAC3G,QACE,MAAO,GAAG,EAAK,KAAK,qBACxB,CACF,EAEM,OAAwB,CACxB,EAAS,QACX,EAAS,MAAM,MAAQ,GAE3B,EAEM,MAAuB,CACvB,EAAW,OAIf,EAAS,OAAO,MAAM,CACxB,EAEM,IACJ,EACA,EACA,IACG,CACH,EAAiB,MAAQ,EAAW,IAAK,GAAc,EAAU,OAAO,EAEpE,EAAW,OAAS,GACtB,EAAK,iBAAkB,CAAU,EAG/B,EAAc,OAAS,IACzB,EAAK,oBAAqB,CAAS,EACnC,EAAK,iBAAkB,CAAa,EAExC,EAEM,EAAgB,GAA0B,CAC9C,GAAI,EAAW,OAAS,EAAc,SAAW,EAC/C,OAGF,IAAM,EAAY,EAAM,SAAW,CAAC,GAAG,EAAM,UAAU,EAAI,CAAC,EACtD,EAAwB,CAAC,EACzB,EAAqC,CAAC,EACxC,EAAiB,OAAO,SAAS,EAAkB,KAAK,EACxD,KAAK,IAAI,EAAkB,MAAQ,EAAU,OAAQ,CAAC,EACtD,IAEJ,IAAK,IAAM,KAAQ,EAAe,CAChC,GAAI,GAAkB,EAAG,CACvB,EAAW,KAAK,CACd,OACA,OAAQ,iBACR,QAAS,EAAsB,EAAM,gBAAgB,CACvD,CAAC,EACD,QACF,CAEA,GAAI,CAAC,GAAc,CAAI,EAAG,CACxB,EAAW,KAAK,CACd,OACA,OAAQ,oBACR,QAAS,EAAsB,EAAM,mBAAmB,CAC1D,CAAC,EACD,QACF,CAEA,GACE,OAAO,EAAM,aAAgB,UAC7B,EAAM,YAAc,GACpB,EAAK,KAAO,EAAM,YAClB,CACA,EAAW,KAAK,CACd,OACA,OAAQ,iBACR,QAAS,EAAsB,EAAM,gBAAgB,CACvD,CAAC,EACD,QACF,CAEA,EAAc,KAAK,CAAI,EACvB,EAAU,KAAK,CAAI,EAEf,OAAO,SAAS,CAAc,GAChC,GAEJ,CAEA,GAAU,EAAW,EAAe,CAAU,CAChD,EAEM,IAAc,EAAY,EAAe,IAA+B,CAC5E,IAAM,EAAQ,EAAe,MAAM,GAE/B,CAAC,GAAU,EAAM,SAAW,aAAe,EAAM,SAAW,UAIhE,EAAK,SAAU,CAAE,OAAM,QAAO,QAAS,GAAW,CAAI,EAAG,QAAO,QAAO,CAAC,CAC1E,EAEM,GAAc,GAAkB,CACpC,GAAI,EAAW,MACb,OAGF,IAAM,EAAO,EAAM,WAAW,GAE1B,GACF,GAAW,EAAM,EAAO,QAAQ,EAGlC,EAAiB,MAAQ,CAAC,EAC1B,EAAK,oBAAqB,EAAM,WAAW,QAAQ,EAAG,IAAc,IAAc,CAAK,CAAC,CAC1F,EAEM,MAAmB,CACnB,EAAW,OAAS,CAAC,EAAS,QAIlC,EAAM,WAAW,SAAS,EAAM,IAAU,CACxC,GAAW,EAAM,EAAO,OAAO,CACjC,CAAC,EAED,EAAiB,MAAQ,CAAC,EAC1B,EAAK,oBAAqB,CAAC,CAAC,EAC9B,EAEM,IAAA,EAAA,EAAA,SAAA,KACJ,EAAM,WAAW,KAAK,EAAM,IAAU,CACpC,IAAM,EAAQ,EAAe,MAAM,GAC7B,EAAS,GAAO,OAChB,EAAQ,EAAO,MAAM,IAAI,CAAI,EAC7B,EAAM,GAAW,CAAI,EAErB,EAAW,GAAO,SAClB,EAAU,OAAO,GAAa,SAAW,KAAK,MAAM,CAAQ,EAAI,IAAA,GAChE,EAAc,GAAO,YAAc,GAEnC,EAAW,GACf,IAAU,IAAW,SAAW,IAAW,WAAa,EAAM,YAAc,IAExE,EAAkC,EAAc,SAAW,UAE3D,EAAY,EAAe,EAAK,IAAI,EACpC,EAAY,GAAe,CAAI,EAC/B,EAAkB,GAAS,EAAM,QAAU,MAAQ,EAAM,SAAW,KACtE,GAAG,EAAM,MAAM,KAAK,EAAM,SAC1B,IAAA,GAEE,EAAgB,IAAW,aAAe,IAAY,IAAA,GACxD,GAAG,EAAQ,GACX,IAAA,GAEA,EAEA,IAAW,cACT,GAAO,eACT,EAAiB,EAAM,eAEvB,OAAO,GAAO,aAAgB,UAC9B,OAAO,SAAS,EAAM,WAAW,GACjC,EAAM,aAAe,IAErB,EAAiB,EAAM,oBAAoB,EAAM,WAAW,IAIhE,IAAM,GAAiB,IAAW,SAAW,IAAW,WACtD,OAAO,GAAO,eAAkB,SAC9B,GAAG,EAAe,EAAM,aAAa,EAAE,MAAM,EAAU,WACvD,IAAA,GAEE,EAAc,EAAS,GAAqB,MAAM,GAAU,IAAA,GAE9D,EAEA,IACF,EAAc,GAAe,IAAY,IAAA,GACrC,EAAM,YAAY,CAAO,EACzB,EAAM,YAGZ,IAAM,EAAY,IAAW,QAAU,GAAO,MAAQ,IAAA,GA8BtD,MAAO,CACL,UAAA,CA5BA,OACA,QACA,QAAS,EACT,QACA,aAAc,GAAO,cAAgB,GAAO,IAC5C,YACA,YACA,kBACA,gBACA,iBACA,gBACA,cACA,cACA,WACA,YACA,aAAc,EAAa,MAC3B,aAAc,EAAa,MAC3B,eAAkB,GAAW,CAAK,EAClC,cAAiB,CACX,CAAC,GAAY,EAAW,OAAS,CAAC,GAItC,EAAK,QAAS,CAAE,OAAM,QAAO,QAAS,EAAK,KAAM,EAAW,OAAM,CAAC,CACrE,CAIA,EACA,SAAU,EAAS,MAAM,IAAW,IAAA,GACpC,SAAU,CAAC,EAAW,EAAW,EAAiB,GAAO,IAAI,CAAC,CAAC,OAAO,OAAO,CAAC,CAAC,KAAK,KAAK,EACzF,WAAY,CAAC,EAAa,EAAe,EAAgB,CAAa,CAAA,CACnE,OAAO,OAAO,CAAA,CACd,KAAK,KAAK,EACb,YACA,QAAS,EAAY,GAAG,EAAI,QAAU,IAAA,GACtC,aAAc,GACZ,IACC,IAAW,aACV,IAAW,UACX,IAAW,SACV,IAAW,WAAa,IAAY,IAAA,KAEzC,cAAe,IAAW,YAAc,EAAY,GAAY,EAChE,kBAAmB,GAAG,GAAe,GAAG,GAAG,EAAK,OAAO,KAAK,EAC5D,OAAQ,IAAW,YACnB,UAAW,IAAW,SACxB,CACF,CAAC,CACH,EAEM,EAAoB,GACnB,EAIE,EAAa,MAAM,OAAS,GAAK,MAAM,KAAK,EAAa,KAAK,CAAC,CAAC,SAAS,OAAO,EAH9E,GAML,GACJ,GAEK,GAAe,MAIb,MAAM,KAAK,EAAc,KAAK,CAAA,CAClC,IAAK,GAAS,EAAK,YAAY,GAAK,IAAI,CAAA,CACxC,OAAQ,GAAuB,aAAgB,IAAI,EAL7C,CAAC,EAQN,GAAiB,GAAiB,CACtC,IAAM,EAAS,EAAM,OACrB,EAAa,MAAM,KAAK,EAAO,OAAS,CAAC,CAAC,CAAC,EAC3C,GAAgB,CAClB,EAEM,GAAqB,GAAyB,CAC9C,EAAA,EAAA,EAAA,gBAAA,CAAiB,CAAK,GAAK,EAAW,QAI1C,EAAM,eAAe,EACrB,EAAe,EACjB,EAEM,OAAkB,CACtB,EAAgB,MAAQ,EAC1B,EAEM,GAAc,GAAsB,CACxC,IAAM,EAAa,EAAM,cAErB,GAAc,EAAQ,OAAO,SAAS,CAAU,IAIpD,EAAgB,MAAQ,GAC1B,EAEM,GAAgB,GAAgB,CACpC,EAAc,MAAQ,CACxB,EAEM,GAAe,GAAgB,CAC/B,EAAc,QAAU,IAC1B,EAAc,MAAQ,KAE1B,EAEM,GAAW,GAA0B,CACzC,GAAI,CAAC,EAAM,OAAS,EAAW,MAC7B,OAGF,IAAM,EAAiB,GAAkB,EAAM,aAAa,EAExD,EAAe,SAAW,IAI9B,EAAM,eAAe,EACrB,EAAa,CAAc,EAC7B,EAEM,GAAmB,GAAiB,CACpC,CAAC,EAAgB,OAAS,EAAM,kBAIpC,GAAQ,CAAuB,CACjC,EAEM,GAAe,GAAqB,CACpC,CAAC,EAAM,MAAQ,EAAW,OAAS,CAAC,EAAiB,EAAM,YAAY,IAI3E,EAAM,eAAe,EACrB,EAAU,OAAS,EACnB,EAAa,MAAQ,GACrB,EAAa,MAAQ,GAAiB,EAAM,YAAY,EAC1D,EAEM,GAAc,GAAqB,CACnC,CAAC,EAAM,MAAQ,EAAW,OAAS,CAAC,EAAiB,EAAM,YAAY,IAI3E,EAAM,eAAe,EAEjB,EAAM,eACR,EAAM,aAAa,WAAa,QAGlC,EAAa,MAAQ,GACrB,EAAa,MAAQ,GAAiB,EAAM,YAAY,EAC1D,EAEM,GAAe,GAAqB,CACpC,CAAC,EAAM,MAAQ,EAAW,OAAS,CAAC,EAAiB,EAAM,YAAY,IAI3E,EAAM,eAAe,EACrB,EAAU,MAAQ,KAAK,IAAI,EAAU,MAAQ,EAAG,CAAC,EAE7C,EAAU,QAAU,IACtB,EAAa,MAAQ,GACrB,EAAa,MAAQ,IAEzB,EAEM,GAAU,GAAqB,CAC/B,CAAC,EAAM,MAAQ,EAAW,OAAS,CAAC,EAAiB,EAAM,YAAY,IAI3E,EAAM,eAAe,EACrB,EAAU,MAAQ,EAClB,EAAa,MAAQ,GACrB,EAAa,MAAQ,GACrB,EAAa,MAAM,KAAK,EAAM,cAAc,OAAS,CAAC,CAAC,CAAC,EAC1D,EAEM,EAAmB,IAAI,WAE7B,EAAA,EAAA,MAAA,CACE,EACC,GAAW,CACV,IAAM,EAAqB,CAAC,EACtB,EAAO,IAAI,IAEjB,EAAM,WAAW,SAAS,EAAM,IAAU,CACxC,EAAK,IAAI,CAAI,EAEb,IAAM,EAAS,EAAO,EAAM,EAAE,OAE9B,GAAI,CAAC,EACH,OAGF,IAAM,EAAW,EAAiB,IAAI,CAAI,EAEtC,IAAa,IAIjB,EAAiB,IAAI,EAAM,CAAM,EAE7B,IAAa,IAAA,KAIb,IAAW,UACb,EAAS,KAAK,GAAG,EAAK,KAAK,WAAW,EAC7B,IAAW,SACpB,EAAS,KAAK,GAAG,EAAK,KAAK,WAAW,EAAO,EAAM,EAAE,OAAS,KAAK,KAAK,CAAC,GAE7E,CAAC,EAED,IAAK,IAAM,IAAQ,CAAC,GAAG,EAAiB,KAAK,CAAC,EACvC,EAAK,IAAI,CAAI,GAChB,EAAiB,OAAO,CAAI,EAI5B,EAAS,OAAS,IAKpB,GAAe,EACf,EAAU,MAAQ,CAChB,GAAG,EAAU,MACb,CAAE,GAAI,EAAa,KAAM,EAAS,KAAK,GAAG,CAAE,CAC9C,CAAC,CAAC,MAAM,EAAiB,EAE7B,EACA,CAAE,MAAO,OAAQ,UAAW,EAAK,CACnC,GAEA,EAAA,EAAA,MAAA,CACE,MACM,CACJ,IAAM,EAAM,EAAc,MACpB,EAAO,EAAQ,MAEjB,CAAC,GAAO,CAAC,GAIT,SAAS,eAAiB,SAAS,gBAAkB,SAAS,MAI9D,EAAK,cAAc,kBAAkB,EAAI,GAAG,IAIhD,EAAc,MAAQ,MAEL,EAAK,cAA2B,mBAAmB,EAAI,GAAG,GACzE,EAAK,cAA2B,0BAA0B,EAAA,EAElD,MAAM,EAClB,EACA,CAAE,MAAO,MAAO,CAClB,GAEA,EAAA,EAAA,MAAA,KAAY,EAAM,WAAY,CAAc,GAC5C,EAAA,EAAA,MAAA,KAAY,EAAM,WAAY,CAAc,GAE5C,EAAA,EAAA,UAAA,KAAgB,CACd,SAAS,iBAAiB,QAAS,EAAe,EAClD,EAAe,CACjB,CAAC,GAED,EAAA,EAAA,gBAAA,KAAsB,CACpB,SAAS,oBAAoB,QAAS,EAAe,EACrD,GAAqB,CACvB,CAAC,qDAsPO,OAAA,EAAA,EAAA,WAAA,CAAA,SAjPA,UAAJ,IAAI,GACI,GAAA,MAAS,CAChB,MAAO,GAAA,MACP,MAAO,GAAA,MACP,UAAS,GACT,WAAU,GACH,uCAWP,QAAA,CARE,IAAA,EAAA,EAAA,MAAA,CAAI,CAAA,UACD,WAAJ,IAAI,EACJ,MAAM,oBACN,KAAK,OACJ,OAAQ,EAAA,QAAU,IAAA,GAClB,SAAU,EAAA,SACV,SAAU,EAAA,MACV,SAAQ,wCA2DL,MAAA,CAvDJ,MAAM,0BACL,YAAW,EAAA,SAAW,IAAA,GACtB,gBAAe,EAAA,cAAgB,EAAA,MAAW,EAAU,IAAA,GACpD,mBAAkB,GAAA,MAClB,gBAAe,EAAA,OAAc,IAAA,GAC7B,eAAc,EAAA,SAAW,IAAA,GAC1B,KAAK,SACJ,SAAU,EAAA,MAAU,GAAA,EACpB,QAAO,EACP,UAAS,GACT,YAAW,GACX,WAAU,GACV,YAAW,GACL,YAGCA,EAAAA,OAAO,MAAI,CAAKA,EAAAA,OAAO,UAAA,EAAA,EAAA,UAAA,CAAA,GAAA,EAAA,EAAA,mBAAA,CAOzB,MARN,EAQM,EAAA,EAAA,EAAA,WAAA,CADG,EAAA,OAAA,OAAA,CAAA,MAAA,CAAA,AAAA,EAAA,MAAA,EAAA,EAAA,mBAAA,CAD0C,OAAA,CAAzC,MAAM,0BAA0B,EAAC,IAAC,EAAA,CAAA,CAAA,CAAA,CAAA,IAAA,EAAA,EAAA,mBAAA,CAAA,GAAA,EAAA,2BA0BtC,MAtBN,EAsBM,EAAA,EAAA,EAAA,WAAA,CADG,EAAA,OAAA,UAAA,CAnBJ,MAAO,EAAA,WACP,aAAgB,EAAA,MAChB,aAAgB,EAAA,MACE,iBACL,kBAeT,0BAXD,IAFJ,GAAA,EAAA,EAAA,gBAAA,CACK,GAAA,KAAa,EAAA,CAAA,EAGV,EAAA,cAAA,EAAA,EAAA,UAAA,CAAA,GAAA,EAAA,EAAA,mBAAA,CAKJ,IAAA,OAJD,GAAI,EACL,MAAM,oDAEH,EAAA,WAAW,EAAA,CAAA,IAAA,EAAA,EAAA,mBAAA,CAAA,GAAA,EAAA,2BAIT,OAFP,GAAA,EAAA,EAAA,gBAAA,CACK,EAAA,WAAW,EAAA,CAAA,MAMZ,EAAA,UAAA,EAAA,EAAA,UAAA,CAAA,GAAA,EAAA,EAAA,YAAA,CAIN,EAAA,QAAA,OAHA,MAAM,yBACN,KAAK,KACL,MAAM,4DAKF,EAAA,MAAiB,OAAM,IAAA,EAAA,EAAA,UAAA,CAAA,GAAA,EAAA,EAAA,mBAAA,CAW1B,KAAA,OAVF,GAAI,EACL,MAAM,0BACN,YAAU,yDAOL,EAAA,SAAA,MAAA,EAAA,EAAA,WAAA,CAJe,EAAA,MAAX,+CAIJ,KAAA,CAHF,IAAK,CAAO,GAAA,EAAA,EAAA,gBAAA,CAEV,CAAO,EAAA,CAAA,sEAgBR,MAZN,EAYM,GAAA,EAAA,EAAA,UAAA,CAAA,EAAA,GAAA,EAAA,EAAA,mBAAA,CADA,EAAA,SAAA,MAAA,EAAA,EAAA,WAAA,CALc,EAAA,MAAT,+CAKL,IAAA,CAJD,IAAK,EAAM,GACZ,MAAM,yDAEH,EAAM,IAAI,EAAA,CAAA,YAKT,EAAA,cAAgB,EAAA,QAAA,EAAA,EAAA,UAAA,CAAA,GAAA,EAAA,EAAA,mBAAA,CA0HlB,MA3HN,EA2HM,EAAA,EAAA,EAAA,mBAAA,CAvGE,MAhBN,EAgBM,EAAA,EAAA,EAAA,mBAAA,CAVA,IAAA,CAJD,GAAI,EACL,MAAM,oDAEH,GAAA,KAAkB,EAAA,CAAA,GAAA,EAAA,EAAA,mBAAA,CAUd,SAAA,CANP,MAAM,uBACN,KAAK,SACJ,SAAU,EAAA,MACV,QAAO,GACT,cAED,EAAA,CAAA,CAAA,CAAA,GAAA,EAAA,EAAA,mBAAA,CAuGG,KApGL,EAoGK,GAAA,EAAA,EAAA,UAAA,CAAA,EAAA,GAAA,EAAA,EAAA,mBAAA,CADE,EAAA,SAAA,MAAA,EAAA,EAAA,WAAA,CAjGW,GAAA,MAAP,+CAiGJ,KAAA,CAhGF,IAAK,EAAI,UAAU,QACpB,OAAA,EAAA,EAAA,eAAA,CAAK,CAAC,sBACE,EAAI,QAAQ,CAAA,EACnB,YAAW,EAAI,QAAU,IAAA,sBA4FnB,EAAA,OAAA,QAAA,EAAA,EAAA,WAAA,CAAA,CAAA,QAAA,EAAA,EAxFG,EAAI,SAAS,MAwFhB,0BAtEE,OAhBP,EAgBO,CAXG,EAAI,UAAU,eAAA,EAAA,EAAA,UAAA,CAAA,GAAA,EAAA,EAAA,mBAAA,CAIrB,MAAA,OAHC,MAAM,6BACL,IAAK,EAAI,UAAU,aACpB,IAAI,2DAOC,OALP,GAAA,EAAA,EAAA,gBAAA,CAIK,EAAI,UAAU,SAAS,EAAA,CAAA,EAAA,CAAA,2BA8CxB,MA1CN,EA0CM,0BAvCA,IAFJ,IAAA,EAAA,EAAA,gBAAA,CACK,EAAI,UAAU,KAAK,IAAI,EAAA,CAAA,2BAIxB,IAFJ,IAAA,EAAA,EAAA,gBAAA,CACK,EAAI,QAAQ,EAAA,CAAA,mBAoCV,EAAA,OAAA,eAAA,EAAA,EAAA,WAAA,CAAA,CAAA,QAAA,EAAA,EA/BG,EAAI,SAAS,MA+BhB,CA5BG,EAAI,eAAA,EAAA,EAAA,UAAA,CAAA,GAAA,EAAA,EAAA,mBAAA,CAQN,MATN,GASM,EAAA,EAAA,EAAA,YAAA,CADF,EAAA,QAAA,CAHA,KAAK,KACJ,MAAO,EAAI,cACX,MAAO,EAAI,gFAKR,EAAI,aAAA,EAAA,EAAA,UAAA,CAAA,GAAA,EAAA,EAAA,mBAAA,CAQR,IATJ,GASI,CAJM,EAAI,YAAA,EAAA,EAAA,UAAA,CAAA,GAAA,EAAA,EAAA,mBAAA,CAGH,OAJT,GAIC,GAAC,IAAA,EAAA,EAAA,mBAAA,CAAA,GAAA,EAAA,GAAA,EAAA,EAAA,gBAAA,EAAA,EAAA,EAAA,gBAAA,CAAU,EAAI,UAAU,EAAA,CAAA,CAAA,CAAA,IAAA,EAAA,EAAA,mBAAA,CAAA,GAAA,EAAA,EAIpB,EAAI,YAAA,EAAA,EAAA,UAAA,CAAA,GAAA,EAAA,EAAA,mBAAA,CAKR,IAAA,OAJD,GAAI,EAAI,QACT,MAAM,mDAEH,EAAI,SAAS,EAAA,EAAA,EAAA,IAAA,EAAA,EAAA,mBAAA,CAAA,GAAA,EAAA,MAMd,EAAI,UAAU,WAAA,EAAA,EAAA,UAAA,CAAA,GAAA,EAAA,EAAA,mBAAA,CAWb,SAAA,OAVP,MAAM,uBACN,KAAK,SACJ,eAAc,EAAI,UAAU,QAC5B,SAAU,EAAA,MACV,mBAAkB,EAAI,QACtB,QAAK,GAAE,GAAa,EAAI,UAAU,OAAO,EACzC,OAAI,GAAE,GAAY,EAAI,UAAU,OAAO,EACvC,QAAK,GAAE,EAAI,UAAU,UAAS,yBAE5B,EAAI,UAAU,WAAW,EAAA,GAAA,EAAA,IAAA,EAAA,EAAA,mBAAA,CAAA,GAAA,EAAA,2BAYrB,SAAA,CARP,MAAM,wBACN,KAAK,SACJ,gBAAe,EAAI,UAAU,QAC7B,SAAU,EAAA,MACV,aAAU,UAAY,EAAI,UAAU,KAAK,OACzC,QAAK,GAAE,EAAI,UAAU,WAAU,GACjC,WAED,EAAA,EAAA,wDAOAA,EAAAA,OAAO,UAAA,EAAA,EAAA,UAAA,CAAA,GAAA,EAAA,EAAA,mBAAA,CAST,MAVN,GAUM,EAAA,EAAA,EAAA,WAAA,CADF,EAAA,OAAA,UAAA,CAHC,MAAO,EAAA,WACW,iBACL"}
|