diff --git a/README.md b/README.md index e94afe7e..34e126fd 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@
logo -

🗂️Open-source file hosting solution, supporting Docker and serverless deployment, supporting multiple storage channels such as Telegram, Discord, Cloudflare R2, S3, Huggingface, etc., supporting WebDAV protocol and various RESTful APIs.

+

🗂️Open-source file hosting solution, supporting Docker and serverless deployment, supporting multiple storage channels such as Telegram, Discord, Cloudflare R2, S3, Huggingface, WebDAV, etc., supporting WebDAV protocol and various RESTful APIs.

简体中文 | English | Official Website @@ -188,6 +188,25 @@ Provides detailed deployment documentation, feature docs, development plans, upd # 4. Tips +- **WebDAV storage channel**: Besides the built-in `/dav` WebDAV server, this project can also use a third-party WebDAV server as an upload storage channel. Configure a fixed channel with `WEBDAV_BASE_URL`; optional variables are `WEBDAV_USERNAME`, `WEBDAV_PASSWORD`, `WEBDAV_PUBLIC_URL`, `WEBDAV_HEADERS` (JSON object string), and `WEBDAV_CREATE_DIRECTORY=false`. Runtime channel config uses: + ```json + { + "webdav": { + "loadBalance": { "enabled": false }, + "channels": [{ + "name": "dav-main", + "type": "webdav", + "baseUrl": "https://dav.example.com/remote.php/dav/files/user/imgbed/", + "username": "user", + "password": "pass", + "publicUrl": "https://cdn.example.com/imgbed/", + "enabled": true + }] + } + } + ``` + The implementation uses Fetch/Web APIs only, so it is compatible with Cloudflare Pages Functions and Workers deployments. Basic authentication and no-auth WebDAV endpoints are supported; Digest-only providers are not supported. WebDAV chunked uploads are intentionally disabled, so large uploads must stay within your Cloudflare request body limits. + - Frontend is open source, see [MarSeventh/Sanyue-ImgHub](https://github.com/MarSeventh/Sanyue-ImgHub). - Desktop software is open source, see [MarSeventh/satellite](https://github.com/MarSeventh/satellite). diff --git a/README_zh.md b/README_zh.md index f6f73b6d..bff56a5c 100644 --- a/README_zh.md +++ b/README_zh.md @@ -1,6 +1,6 @@

logo -

🗂️开源文件托管解决方案,支持 Docker 和无服务器部署,支持 Telegram、Discord、Cloudflare R2、S3、Huggingface 等多种存储渠道,支持 WebDAV 协议和多种 RESTful API

+

🗂️开源文件托管解决方案,支持 Docker 和无服务器部署,支持 Telegram、Discord、Cloudflare R2、S3、Huggingface、WebDAV 等多种存储渠道,支持 WebDAV 协议和多种 RESTful API

简体中文 | English | 官方网站

@@ -200,6 +200,25 @@ # 4. Tips +- **WebDAV 存储渠道**:除了内置 `/dav` WebDAV 服务外,本项目也可以把第三方 WebDAV 服务作为上传存储渠道使用。固定环境变量渠道可配置 `WEBDAV_BASE_URL`;可选变量包括 `WEBDAV_USERNAME`、`WEBDAV_PASSWORD`、`WEBDAV_PUBLIC_URL`、`WEBDAV_HEADERS`(JSON 对象字符串)和 `WEBDAV_CREATE_DIRECTORY=false`。运行时渠道配置结构如下: + ```json + { + "webdav": { + "loadBalance": { "enabled": false }, + "channels": [{ + "name": "dav-main", + "type": "webdav", + "baseUrl": "https://dav.example.com/remote.php/dav/files/user/imgbed/", + "username": "user", + "password": "pass", + "publicUrl": "https://cdn.example.com/imgbed/", + "enabled": true + }] + } + } + ``` + 实现仅使用 Fetch/Web API,因此可用于 Cloudflare Pages Functions 和 Workers 部署。支持 Basic 认证或无认证 WebDAV 端点;暂不支持仅 Digest 认证的服务。WebDAV 分片上传已明确禁用,大文件需在 Cloudflare 请求体限制范围内直接上传。 + - **前端开源**:参见[MarSeventh/Sanyue-ImgHub](https://github.com/MarSeventh/Sanyue-ImgHub)项目。 - **桌面端开源**:参见[MarSeventh/satellite](https://github.com/MarSeventh/satellite)项目。 diff --git a/deploy/worker/wrangler.toml b/deploy/worker/wrangler.toml index 61020138..d229bd12 100644 --- a/deploy/worker/wrangler.toml +++ b/deploy/worker/wrangler.toml @@ -23,6 +23,13 @@ not_found_handling = "single-page-application" [vars] # TG_BOT_TOKEN = "" # TG_CHAT_ID = "" +# Optional third-party WebDAV storage channel: +# WEBDAV_BASE_URL = "https://dav.example.com/remote.php/dav/files/user/imgbed/" +# WEBDAV_USERNAME = "" +# WEBDAV_PASSWORD = "" +# WEBDAV_PUBLIC_URL = "" +# WEBDAV_HEADERS = "{\"X-Example\":\"value\"}" +# WEBDAV_CREATE_DIRECTORY = "true" # [[d1_databases]] # binding = "img_d1" diff --git a/frontend-dist/js/577.2c9dad30.js b/frontend-dist/js/577.2c9dad30.js index a1b54472..39ac8d4c 100644 --- a/frontend-dist/js/577.2c9dad30.js +++ b/frontend-dist/js/577.2c9dad30.js @@ -1,2 +1,2 @@ -(self["webpackChunksanyue_imghub"]=self["webpackChunksanyue_imghub"]||[]).push([[577],{213:function(e,t,o){"use strict";o(85331),o(19104)},2893:function(e,t,o){"use strict";o(85331)},4885:function(e,t,o){"use strict";o(85331)},10456:function(e,t,o){"use strict";o(85331)},11393:function(e,t,o){o(16573),o(78100),o(77936),o(79577),o(41549),o(49797),o(49631),o(35623),o(64979),o(14603),o(47566),o(98721),function(t,o){e.exports=o()}(0,function(){return function(e){var t={};function o(s){if(t[s])return t[s].exports;var l=t[s]={i:s,l:!1,exports:{}};return e[s].call(l.exports,l,l.exports,o),l.l=!0,l.exports}return o.m=e,o.c=t,o.d=function(e,t,s){o.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:s})},o.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},o.t=function(e,t){if(1&t&&(e=o(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var s=Object.create(null);if(o.r(s),Object.defineProperty(s,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var l in e)o.d(s,l,function(t){return e[t]}.bind(null,l));return s},o.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return o.d(t,"a",t),t},o.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},o.p="",o(o.s=0)}([function(e,t,o){"use strict";var s;function l(e){return["image/png","image/jpeg","image/gif"].some(t=>t===e)}o.r(t),o.d(t,"canvastoDataURL",function(){return a}),o.d(t,"canvastoFile",function(){return n}),o.d(t,"dataURLtoFile",function(){return d}),o.d(t,"dataURLtoImage",function(){return c}),o.d(t,"downloadFile",function(){return u}),o.d(t,"filetoDataURL",function(){return p}),o.d(t,"imagetoCanvas",function(){return m}),o.d(t,"urltoBlob",function(){return g}),o.d(t,"urltoImage",function(){return f}),o.d(t,"compress",function(){return b}),o.d(t,"compressAccurately",function(){return v}),o.d(t,"EImageType",function(){return s}),function(e){e.PNG="image/png",e.JPEG="image/jpeg",e.GIF="image/gif"}(s||(s={}));var i=function(e,t,o,s){return new(o||(o=Promise))(function(l,i){function a(e){try{r(s.next(e))}catch(e){i(e)}}function n(e){try{r(s.throw(e))}catch(e){i(e)}}function r(e){var t;e.done?l(e.value):(t=e.value,t instanceof o?t:new o(function(e){e(t)})).then(a,n)}r((s=s.apply(e,t||[])).next())})};function a(e,t=.92,o=s.JPEG){return i(this,void 0,void 0,function*(){return l(o)||(o=s.JPEG),e.toDataURL(o,t)})}function n(e,t=.92,o=s.JPEG){return new Promise(s=>e.toBlob(e=>s(e),o,t))}var r=function(e,t,o,s){return new(o||(o=Promise))(function(l,i){function a(e){try{r(s.next(e))}catch(e){i(e)}}function n(e){try{r(s.throw(e))}catch(e){i(e)}}function r(e){var t;e.done?l(e.value):(t=e.value,t instanceof o?t:new o(function(e){e(t)})).then(a,n)}r((s=s.apply(e,t||[])).next())})};function d(e,t){return r(this,void 0,void 0,function*(){const o=e.split(",");let s=o[0].match(/:(.*?);/)[1];const i=atob(o[1]);let a=i.length;const n=new Uint8Array(a);for(;a--;)n[a]=i.charCodeAt(a);return l(t)&&(s=t),new Blob([n],{type:s})})}function c(e){return new Promise((t,o)=>{const s=new Image;s.onload=()=>t(s),s.onerror=()=>o(new Error("dataURLtoImage(): dataURL is illegal")),s.src=e})}function u(e,t){const o=document.createElement("a");o.href=window.URL.createObjectURL(e),o.download=t||Date.now().toString(36),document.body.appendChild(o);const s=document.createEvent("MouseEvents");s.initEvent("click",!1,!1),o.dispatchEvent(s),document.body.removeChild(o)}function p(e){return new Promise(t=>{const o=new FileReader;o.onloadend=e=>t(e.target.result),o.readAsDataURL(e)})}var h=function(e,t,o,s){return new(o||(o=Promise))(function(l,i){function a(e){try{r(s.next(e))}catch(e){i(e)}}function n(e){try{r(s.throw(e))}catch(e){i(e)}}function r(e){var t;e.done?l(e.value):(t=e.value,t instanceof o?t:new o(function(e){e(t)})).then(a,n)}r((s=s.apply(e,t||[])).next())})};function m(e,t={}){return h(this,void 0,void 0,function*(){const o=Object.assign({},t),s=document.createElement("canvas"),l=s.getContext("2d");let i,a;for(const e in o)Object.prototype.hasOwnProperty.call(o,e)&&(o[e]=Number(o[e]));if(o.scale){const t=o.scale>0&&o.scale<10?o.scale:1;a=e.width*t,i=e.height*t}else a=o.width||o.height*e.width/e.height||e.width,i=o.height||o.width*e.height/e.width||e.height;switch([5,6,7,8].some(e=>e===o.orientation)?(s.height=a,s.width=i):(s.height=i,s.width=a),o.orientation){case 3:l.rotate(180*Math.PI/180),l.drawImage(e,-s.width,-s.height,s.width,s.height);break;case 6:l.rotate(90*Math.PI/180),l.drawImage(e,0,-s.width,s.height,s.width);break;case 8:l.rotate(270*Math.PI/180),l.drawImage(e,-s.height,0,s.height,s.width);break;case 2:l.translate(s.width,0),l.scale(-1,1),l.drawImage(e,0,0,s.width,s.height);break;case 4:l.translate(s.width,0),l.scale(-1,1),l.rotate(180*Math.PI/180),l.drawImage(e,-s.width,-s.height,s.width,s.height);break;case 5:l.translate(s.width,0),l.scale(-1,1),l.rotate(90*Math.PI/180),l.drawImage(e,0,-s.width,s.height,s.width);break;case 7:l.translate(s.width,0),l.scale(-1,1),l.rotate(270*Math.PI/180),l.drawImage(e,-s.height,0,s.height,s.width);break;default:l.drawImage(e,0,0,s.width,s.height)}return s})}function g(e){return fetch(e).then(e=>e.blob())}function f(e){return new Promise((t,o)=>{const s=new Image;s.onload=()=>t(s),s.onerror=()=>o(new Error("urltoImage(): Image failed to load, please check the image URL")),s.src=e})}var y=function(e,t,o,s){return new(o||(o=Promise))(function(l,i){function a(e){try{r(s.next(e))}catch(e){i(e)}}function n(e){try{r(s.throw(e))}catch(e){i(e)}}function r(e){var t;e.done?l(e.value):(t=e.value,t instanceof o?t:new o(function(e){e(t)})).then(a,n)}r((s=s.apply(e,t||[])).next())})};function b(e,t={}){return y(this,void 0,void 0,function*(){if(!(e instanceof Blob))throw new Error("compress(): First arg must be a Blob object or a File object.");if("object"!=typeof t&&(t=Object.assign({quality:t})),t.quality=Number(t.quality),Number.isNaN(t.quality))return e;const o=yield p(e);let i=o.split(",")[0].match(/:(.*?);/)[1],n=s.JPEG;l(t.type)&&(n=t.type,i=t.type);const r=yield c(o),u=yield m(r,Object.assign({},t)),h=yield a(u,t.quality,n),g=yield d(h,i);return g.size>e.size?e:g})}function v(e,t={}){return y(this,void 0,void 0,function*(){if(!(e instanceof Blob))throw new Error("compressAccurately(): First arg must be a Blob object or a File object.");if("object"!=typeof t&&(t=Object.assign({size:t})),t.size=Number(t.size),Number.isNaN(t.size))return e;if(1024*t.size>e.size)return e;t.accuracy=Number(t.accuracy),(!t.accuracy||t.accuracy<.8||t.accuracy>.99)&&(t.accuracy=.95);const o=t.size*(2-t.accuracy)*1024,i=1024*t.size,n=t.size*t.accuracy*1024,r=yield p(e);let u=r.split(",")[0].match(/:(.*?);/)[1],h=s.JPEG;l(t.type)&&(h=t.type,u=t.type);const g=yield c(r),f=yield m(g,Object.assign({},t));let y,b=.5;const v=[null,null];for(let e=1;e<=7;e++){y=yield a(f,b,h);const t=.75*y.length;if(7===e){(ot)&&(y=[y,...v].filter(e=>e).sort((e,t)=>Math.abs(.75*e.length-i)-Math.abs(.75*t.length-i))[0]);break}if(ot))break;v[0]=y,b+=Math.pow(.5,e+1)}}const C=yield d(y,u);return C.size>e.size?e:C})}}])})},13378:function(e,t,o){"use strict";o(85331),o(38736),o(79899)},15616:function(e,t,o){"use strict";o(85331),o(97197)},18785:function(e,t,o){"use strict";o(85331)},19104:function(e,t,o){"use strict";o(85331)},23597:function(e,t,o){"use strict";o(85331)},30694:function(e,t,o){"use strict";o(85331)},33892:function(e,t,o){"use strict";o.d(t,{A:function(){return $}});var s=o(99114),l=(o(85331),o(30694),o(49385)),i=(o(37952),o(30650)),a=(o(19104),o(31802)),n=(o(13378),o(80047)),r=(o(99648),o(56768)),d=o(45130),c=o(24232);const u={class:"directory-tree-picker"},p={class:"tree-container"},h={key:0,class:"error-state"},m={class:"error-text"},g={class:"node-label"},f={class:"tree-container"},y={key:0,class:"error-state"},b={class:"error-text"},v={class:"node-label"};function C(e,t,o,C,k,w){const F=(0,r.g2)("font-awesome-icon"),L=n.S2,U=a.qk,$=i.Vc,S=l.pw,T=s.A;return(0,r.uX)(),(0,r.CE)("div",u,[w.isDesktop?((0,r.uX)(),(0,r.Wv)($,{key:0,visible:k.popoverVisible,"onUpdate:visible":t[1]||(t[1]=e=>k.popoverVisible=e),placement:"bottom-start",width:320,trigger:"click","popper-class":"directory-tree-popover","show-arrow":!0,"hide-after":0,"show-after":50,transition:"el-zoom-in-top"},{reference:(0,r.k6)(()=>[(0,r.Lk)("span",{class:"popover-trigger-wrapper",onClick:t[0]||(t[0]=(0,d.D$)(()=>{},["stop"]))},[(0,r.RG)(e.$slots,"trigger",{},void 0,!0)])]),default:(0,r.k6)(()=>[(0,r.bo)(((0,r.uX)(),(0,r.CE)("div",p,[k.error?((0,r.uX)(),(0,r.CE)("div",h,[(0,r.bF)(F,{icon:"exclamation-circle",class:"error-icon"}),(0,r.Lk)("span",m,(0,c.v_)(k.error),1),(0,r.bF)(L,{type:"primary",size:"small",onClick:w.fetchDirectoryTree},{default:(0,r.k6)(()=>[(0,r.eW)((0,c.v_)(e.$t("directoryTree.retry")),1)]),_:1},8,["onClick"])])):((0,r.uX)(),(0,r.Wv)(U,{key:1,ref:"treeRef",data:k.treeData,props:k.treeProps,"node-key":"path","default-expand-all":!1,"expand-on-click-node":!1,"highlight-current":!0,"current-node-key":o.currentDirectory,class:"directory-tree",onNodeClick:w.handleNodeClick},{default:(0,r.k6)(({node:e,data:t})=>[(0,r.Lk)("span",{class:(0,c.C4)(["tree-node",{"is-current":t.path===o.currentDirectory}])},[(0,r.bF)(F,{icon:e.expanded?"folder-open":"folder",class:"folder-icon"},null,8,["icon"]),(0,r.Lk)("span",g,(0,c.v_)(t.name),1)],2)]),_:1},8,["data","props","current-node-key","onNodeClick"]))])),[[T,k.loading]])]),_:3},8,["visible"])):((0,r.uX)(),(0,r.CE)(r.FK,{key:1},[(0,r.Lk)("span",{class:"drawer-trigger-wrapper",onClick:t[2]||(t[2]=(...e)=>w.openDrawer&&w.openDrawer(...e))},[(0,r.RG)(e.$slots,"trigger",{},void 0,!0)]),(0,r.bF)(S,{modelValue:k.drawerVisible,"onUpdate:modelValue":t[3]||(t[3]=e=>k.drawerVisible=e),direction:"btt",size:"60%","show-close":!0,"with-header":!0,"z-index":3e3,title:e.$t("directoryTree.selectDirectory"),class:"directory-tree-drawer"},{default:(0,r.k6)(()=>[(0,r.bo)(((0,r.uX)(),(0,r.CE)("div",f,[k.error?((0,r.uX)(),(0,r.CE)("div",y,[(0,r.bF)(F,{icon:"exclamation-circle",class:"error-icon"}),(0,r.Lk)("span",b,(0,c.v_)(k.error),1),(0,r.bF)(L,{type:"primary",size:"small",onClick:w.fetchDirectoryTree},{default:(0,r.k6)(()=>[(0,r.eW)((0,c.v_)(e.$t("directoryTree.retry")),1)]),_:1},8,["onClick"])])):((0,r.uX)(),(0,r.Wv)(U,{key:1,ref:"treeRefMobile",data:k.treeData,props:k.treeProps,"node-key":"path","default-expand-all":!1,"expand-on-click-node":!1,"highlight-current":!0,"current-node-key":o.currentDirectory,class:"directory-tree mobile-tree",onNodeClick:w.handleNodeClick},{default:(0,r.k6)(({node:e,data:t})=>[(0,r.Lk)("span",{class:(0,c.C4)(["tree-node",{"is-current":t.path===o.currentDirectory}])},[(0,r.bF)(F,{icon:e.expanded?"folder-open":"folder",class:"folder-icon"},null,8,["icon"]),(0,r.Lk)("span",v,(0,c.v_)(t.name),1)],2)]),_:1},8,["data","props","current-node-key","onNodeClick"]))])),[[T,k.loading]])]),_:1},8,["modelValue","title"])],64))])}var k=o(457),w=o(70797),F={name:"DirectoryTreePicker",props:{currentDirectory:{type:String,default:""},source:{type:String,default:"upload",validator:e=>["upload","admin"].includes(e)}},data(){return{popoverVisible:!1,drawerVisible:!1,treeData:[],loading:!1,error:"",treeProps:{children:"children",label:"name"},windowWidth:window.innerWidth}},computed:{isDesktop(){return this.windowWidth>=769}},watch:{popoverVisible(e){e?this.fetchDirectoryTree():setTimeout(()=>{if(!this.popoverVisible&&this.$refs.treeRef){const e=this.$refs.treeRef.store;for(const t in e.nodesMap)e.nodesMap[t].expanded=!1}},200)},drawerVisible(e){e?this.fetchDirectoryTree():setTimeout(()=>{if(!this.drawerVisible&&this.$refs.treeRefMobile){const e=this.$refs.treeRefMobile.store;for(const t in e.nodesMap)e.nodesMap[t].expanded=!1}},300)},currentDirectory(e){this.$nextTick(()=>{this.$refs.treeRef&&e&&this.$refs.treeRef.setCurrentKey(e),this.$refs.treeRefMobile&&e&&this.$refs.treeRefMobile.setCurrentKey(e)})}},mounted(){window.addEventListener("resize",this.handleResize)},beforeUnmount(){window.removeEventListener("resize",this.handleResize)},methods:{handleResize(){this.windowWidth=window.innerWidth},openDrawer(){this.drawerVisible=!0},async fetchDirectoryTree(){this.loading=!0,this.error="";try{let e;if("admin"===this.source){const t=await(0,w.A)("/api/directoryTree",{method:"GET"});if(!t.ok)return void(401===t.status?this.error=this.$t("directoryTree.authFailed"):this.error=this.$t("directoryTree.serverError"));e=await t.json()}else{const t=await k.A.get("/api/directoryTree",{withAuthCode:!0});e=t.data}e.tree?this.treeData=[e.tree]:this.treeData=[]}catch(e){console.error("Failed to fetch directory tree:",e),401===e.response?.status?this.error=this.$t("directoryTree.authFailed"):this.error=this.$t("directoryTree.loadFailed")}finally{this.loading=!1}},handleNodeClick(e){let t=e.path;t&&!t.startsWith("/")?t="/"+t:t||(t="/"),this.$emit("select",t),this.popoverVisible=!1,this.drawerVisible=!1}}},L=o(71241);const U=(0,L.A)(F,[["render",C],["__scopeId","data-v-62eab69a"]]);var $=U},34396:function(e,t,o){"use strict";o(85331),o(4885)},37952:function(e,t,o){"use strict";o(85331),o(97197)},38736:function(e,t,o){"use strict";o(85331)},40670:function(e,t,o){"use strict";o(85331),o(99648),o(19104),o(85970)},50333:function(e,t,o){"use strict";o(85331),o(29092)},62388:function(e,t,o){"use strict";o.d(t,{G:function(){return l}});var s=o(46638);function l(e,{strict:t=!0}={}){if(!e||""===e.trim())return{valid:!0};if("/"===e)return{valid:!0};if(!e.startsWith("/"))return{valid:!1,error:s.Ay.global.t("validation.pathMustStartWithSlash")};if(/(?:^|\/)\.\.(\/|$)/.test(e)||e.includes(".."))return{valid:!1,error:s.Ay.global.t("validation.pathTraversalNotAllowed")};const o=t?/\/\.(\/|$)/:/\/\.\//;if(o.test(e))return{valid:!1,error:s.Ay.global.t("validation.singleDotNotAllowed")};if(e.includes("//"))return{valid:!1,error:s.Ay.global.t("validation.consecutiveSlashNotAllowed")};const l=/[\\:\*\?"'<>\| \(\)\[\]\{\}#%\^`~;@&=\+\$,]/;return l.test(e)?{valid:!1,error:s.Ay.global.t("validation.invalidCharacters")}:{valid:!0}}},67819:function(e,t,o){"use strict";o(85331)},70797:function(e,t,o){"use strict";o.d(t,{A:function(){return a}});o(44114);var s=o(25507),l=o(16915);let i=!1;async function a(e,t={}){t.credentials="include",t.headers={...t.headers};const o=await fetch(e,t);return 401!==o.status||i||(i=!0,s.A.commit("setAdminLoggedIn",!1),l.A.push("/adminLogin").finally(()=>{i=!1})),o}},76334:function(e,t,o){e.exports=o(11393)},79899:function(e,t,o){"use strict";o(85331)},85970:function(e,t,o){"use strict";o(85331)},88830:function(e,t,o){"use strict";o(85331)},95385:function(e,t,o){"use strict";o(85331)},96682:function(e,t,o){"use strict";e.exports=o.p+"img/404.8ed11fb3.png"},96808:function(e,t,o){"use strict";o(85331),o(18785),o(67819),o(85970),o(19104)},99761:function(e,t,o){"use strict";o.r(t),o.d(t,{default:function(){return $o}});var s=o(78507),l=(o(85331),o(213),o(80047)),i=(o(99648),o(56768)),a=o(24232);const n={class:"history-header"},r={class:"header-left"},d={class:"record-count"},c={class:"header-right"},u={class:"timeline-header"},p={class:"date-label"},h={key:0,class:"grid-view"},m={class:"grid-preview"},g=["src"],f=["src"],y={key:2,class:"file-icon-wrapper"},b={class:"grid-overlay"},v={class:"grid-actions"},C={class:"grid-info"},k=["title"],w={class:"upload-time"},F={key:1,class:"list-view"},L={class:"list-preview"},U=["src"],$=["src"],S={key:2,class:"file-icon-wrapper-small"},T={class:"list-info"},_=["title"],x=["title"],M={class:"list-meta"},R={class:"upload-time"},A={class:"list-actions"},E={key:0,class:"load-more-container"},D={key:0,class:"loading-indicator"},I={key:1,class:"load-more-hint"},N={key:1,class:"no-more-hint"},P={key:1,class:"empty-state"};function V(e,t,o,V,W,z){const B=(0,i.g2)("font-awesome-icon"),H=l.S2,X=s.R7;return(0,i.uX)(),(0,i.CE)("div",{class:(0,a.C4)(["history-container",{active:o.show}])},[(0,i.Lk)("div",n,[(0,i.Lk)("div",r,[(0,i.Lk)("h2",null,(0,a.v_)(e.$t("uploadHistory.title")),1),(0,i.Lk)("span",d,(0,a.v_)(e.$t("uploadHistory.totalRecords",{count:W.totalCount})),1)]),(0,i.Lk)("div",c,[(0,i.bF)(X,{content:e.$t("uploadHistory.switchView"),placement:"bottom"},{default:(0,i.k6)(()=>[(0,i.bF)(H,{circle:"",onClick:z.toggleViewMode},{default:(0,i.k6)(()=>[(0,i.bF)(B,{icon:"grid"===W.viewMode?"list":"th-large"},null,8,["icon"])]),_:1},8,["onClick"])]),_:1},8,["content"]),(0,i.bF)(X,{content:e.$t("uploadHistory.clearRecords"),placement:"bottom"},{default:(0,i.k6)(()=>[(0,i.bF)(H,{circle:"",type:"danger",onClick:z.clearHistory},{default:(0,i.k6)(()=>[(0,i.bF)(B,{icon:"trash-alt"})]),_:1},8,["onClick"])]),_:1},8,["content"]),(0,i.bF)(H,{circle:"",onClick:t[0]||(t[0]=t=>e.$emit("close"))},{default:(0,i.k6)(()=>[(0,i.bF)(B,{icon:"times"})]),_:1})])]),W.historyList.length>0?((0,i.uX)(),(0,i.CE)("div",{key:0,class:"history-content",ref:"historyContent",onScroll:t[3]||(t[3]=(...e)=>z.handleScroll&&z.handleScroll(...e))},[((0,i.uX)(!0),(0,i.CE)(i.FK,null,(0,i.pI)(z.groupedHistory,e=>((0,i.uX)(),(0,i.CE)("div",{key:e.date,class:"history-group"},[(0,i.Lk)("div",u,[t[4]||(t[4]=(0,i.Lk)("div",{class:"timeline-dot"},null,-1)),(0,i.Lk)("span",p,(0,a.v_)(e.date),1)]),"grid"===W.viewMode?((0,i.uX)(),(0,i.CE)("div",h,[((0,i.uX)(!0),(0,i.CE)(i.FK,null,(0,i.pI)(e.items,e=>((0,i.uX)(),(0,i.CE)("div",{key:e.time,class:"grid-item"},[(0,i.Lk)("div",m,[z.isImage(e.name)?((0,i.uX)(),(0,i.CE)("img",{key:0,src:e.url,loading:"lazy",onError:t[1]||(t[1]=(...e)=>z.handleImageError&&z.handleImageError(...e))},null,40,g)):z.isVideo(e.name)?((0,i.uX)(),(0,i.CE)("video",{key:1,src:e.url,muted:""},null,8,f)):((0,i.uX)(),(0,i.CE)("div",y,[(0,i.bF)(B,{icon:"file",class:"file-icon"})])),(0,i.Lk)("div",b,[(0,i.Lk)("div",v,[(0,i.bF)(H,{circle:"",size:"default",type:"primary",onClick:t=>z.copyLink(e.url)},{default:(0,i.k6)(()=>[(0,i.bF)(B,{icon:"copy"})]),_:1},8,["onClick"]),(0,i.bF)(H,{circle:"",size:"default",class:"action-btn-view",onClick:t=>z.openLink(e.url)},{default:(0,i.k6)(()=>[(0,i.bF)(B,{icon:"external-link-alt"})]),_:1},8,["onClick"]),(0,i.bF)(H,{circle:"",size:"default",type:"danger",onClick:t=>z.deleteItem(e)},{default:(0,i.k6)(()=>[(0,i.bF)(B,{icon:"trash-alt"})]),_:1},8,["onClick"])])])]),(0,i.Lk)("div",C,[(0,i.Lk)("div",{class:"file-name",title:e.name},(0,a.v_)(e.name),9,k),(0,i.Lk)("div",w,(0,a.v_)(z.formatTime(e.time)),1)])]))),128))])):((0,i.uX)(),(0,i.CE)("div",F,[((0,i.uX)(!0),(0,i.CE)(i.FK,null,(0,i.pI)(e.items,e=>((0,i.uX)(),(0,i.CE)("div",{key:e.time,class:"list-item"},[(0,i.Lk)("div",L,[z.isImage(e.name)?((0,i.uX)(),(0,i.CE)("img",{key:0,src:e.url,loading:"lazy",onError:t[2]||(t[2]=(...e)=>z.handleImageError&&z.handleImageError(...e))},null,40,U)):z.isVideo(e.name)?((0,i.uX)(),(0,i.CE)("video",{key:1,src:e.url,muted:""},null,8,$)):((0,i.uX)(),(0,i.CE)("div",S,[(0,i.bF)(B,{icon:"file"})]))]),(0,i.Lk)("div",T,[(0,i.Lk)("div",{class:"file-name",title:e.name},(0,a.v_)(e.name),9,_),(0,i.Lk)("div",{class:"file-url",title:e.url},(0,a.v_)(e.url),9,x)]),(0,i.Lk)("div",M,[(0,i.Lk)("div",R,(0,a.v_)(z.formatTime(e.time)),1)]),(0,i.Lk)("div",A,[(0,i.bF)(H,{circle:"",size:"small",type:"primary",onClick:t=>z.copyLink(e.url)},{default:(0,i.k6)(()=>[(0,i.bF)(B,{icon:"copy"})]),_:1},8,["onClick"]),(0,i.bF)(H,{circle:"",size:"small",class:"action-btn-view",onClick:t=>z.openLink(e.url)},{default:(0,i.k6)(()=>[(0,i.bF)(B,{icon:"external-link-alt"})]),_:1},8,["onClick"]),(0,i.bF)(H,{circle:"",size:"small",type:"danger",onClick:t=>z.deleteItem(e)},{default:(0,i.k6)(()=>[(0,i.bF)(B,{icon:"trash-alt"})]),_:1},8,["onClick"])])]))),128))]))]))),128)),z.hasMore?((0,i.uX)(),(0,i.CE)("div",E,[W.loadingMore?((0,i.uX)(),(0,i.CE)("div",D,[(0,i.bF)(B,{icon:"spinner",spin:""}),(0,i.Lk)("span",null,(0,a.v_)(e.$t("uploadHistory.loading")),1)])):((0,i.uX)(),(0,i.CE)("div",I,(0,a.v_)(e.$t("uploadHistory.pullToLoadMore")),1))])):W.historyList.length>0?((0,i.uX)(),(0,i.CE)("div",N,(0,a.v_)(e.$t("uploadHistory.noMoreRecords")),1)):(0,i.Q3)("",!0)],544)):((0,i.uX)(),(0,i.CE)("div",P,[(0,i.bF)(B,{icon:"history",class:"empty-icon"}),(0,i.Lk)("p",null,(0,a.v_)(e.$t("uploadHistory.emptyHistory")),1)]))],2)}o(44114),o(18111),o(22489),o(7588),o(61701),o(33110),o(58335);var W={name:"UploadHistory",props:{show:{type:Boolean,default:!1}},data(){return{historyList:[],allHistory:[],viewMode:"grid",pageSize:30,currentPage:0,loadingMore:!1,totalCount:0}},watch:{show(e){e&&this.resetAndLoad()}},computed:{hasMore(){return this.historyList.length{const o=new Date(t.time),s=`${o.getFullYear()}-${String(o.getMonth()+1).padStart(2,"0")}-${String(o.getDate()).padStart(2,"0")}`;e[s]||(e[s]=[]),e[s].push(t)}),Object.keys(e).sort((e,t)=>new Date(t)-new Date(e)).map(t=>({date:t,items:e[t]}))}},mounted(){const e=localStorage.getItem("historyViewMode");e&&(this.viewMode=e)},methods:{resetAndLoad(){this.historyList=[],this.currentPage=0,this.loadAllHistory(),this.loadMore()},loadAllHistory(){try{const e=JSON.parse(localStorage.getItem("uploadHistory")||"[]");this.allHistory=e.sort((e,t)=>t.time-e.time),this.totalCount=this.allHistory.length}catch(e){console.error("Failed to load history",e),this.allHistory=[],this.totalCount=0}},loadMore(){!this.loadingMore&&this.hasMore&&(this.loadingMore=!0,setTimeout(()=>{const e=this.currentPage*this.pageSize,t=e+this.pageSize,o=this.allHistory.slice(e,t);this.historyList=[...this.historyList,...o],this.currentPage++,this.loadingMore=!1},50))},handleScroll(e){const t=e.target,o=t.scrollTop,s=t.scrollHeight,l=t.clientHeight;s-o-l<100&&this.loadMore()},toggleViewMode(){this.viewMode="grid"===this.viewMode?"list":"grid",localStorage.setItem("historyViewMode",this.viewMode)},clearHistory(){this.$confirm(this.$t("uploadHistory.clearConfirmMessage"),this.$t("uploadHistory.clearConfirmTitle"),{confirmButtonText:this.$t("uploadHistory.clearConfirmOk"),cancelButtonText:this.$t("uploadHistory.clearConfirmCancel"),type:"warning"}).then(()=>{this.historyList=[],this.allHistory=[],this.totalCount=0,this.currentPage=0,localStorage.removeItem("uploadHistory"),this.$message.success(this.$t("uploadHistory.recordsCleared"))}).catch(()=>{})},deleteItem(e){this.$confirm(this.$t("uploadHistory.deleteConfirmMessage"),this.$t("uploadHistory.clearConfirmTitle"),{confirmButtonText:this.$t("uploadHistory.clearConfirmOk"),cancelButtonText:this.$t("uploadHistory.clearConfirmCancel"),type:"warning"}).then(()=>{this.historyList=this.historyList.filter(t=>t.time!==e.time),this.allHistory=this.allHistory.filter(t=>t.time!==e.time),this.totalCount=this.allHistory.length;try{localStorage.setItem("uploadHistory",JSON.stringify(this.allHistory)),this.$message.success(this.$t("uploadHistory.recordDeleted"))}catch(t){console.error("Failed to update history",t)}}).catch(()=>{})},isImage(e){const t=["jpg","jpeg","png","gif","bmp","webp","svg","tiff","ico","avif","heic","jfif","pjpeg","pjp"],o=e?e.split(".").pop().toLowerCase():"";return t.includes(o)},isVideo(e){const t=["mp4","webm","ogg","mkv"],o=e?e.split(".").pop().toLowerCase():"";return t.includes(o)},formatTime(e){const t=new Date(e),o=t.getFullYear(),s=String(t.getMonth()+1).padStart(2,"0"),l=String(t.getDate()).padStart(2,"0"),i=String(t.getHours()).padStart(2,"0"),a=String(t.getMinutes()).padStart(2,"0"),n=String(t.getSeconds()).padStart(2,"0");return`${o}-${s}-${l} ${i}:${a}:${n}`},copyLink(e){navigator.clipboard.writeText(e).then(()=>{this.$message.success(this.$t("uploadHistory.linkCopied"))}).catch(()=>{this.$message.error(this.$t("uploadHistory.copyFailed"))})},openLink(e){window.open(e,"_blank")},handleImageError(e){e.target.src=o(96682)}}},z=o(71241);const B=(0,z.A)(W,[["render",V],["__scopeId","data-v-550797ce"]]);var H=B,X=o(86975),O=o(9267),Q=(o(15616),o(81418)),j=(o(50333),o(74757)),q=o(55558),G=(o(10456),o(39623)),K=(o(29092),o(76018)),J=(o(96808),o(67819),o(66810));o(34396),o(4885);const Y={class:"dialog-section"},Z={class:"section-header"},ee={class:"section-title"},te={class:"section-content"},oe={class:"setting-item"},se={class:"setting-label"},le={key:0,class:"setting-item"},ie={class:"setting-label"},ae={class:"setting-item"},ne={class:"setting-label"},re={class:"setting-item"},de={class:"setting-label"},ce={class:"dialog-section"},ue={class:"section-header"},pe={class:"section-title"},he={class:"section-content"},me={class:"dialog-section"},ge={class:"section-header"},fe={class:"section-title"},ye={class:"section-content"},be={class:"setting-item"},ve={class:"setting-label"},Ce={class:"setting-item"},ke={class:"setting-label"},we={key:0,class:"setting-item slider-item"},Fe={class:"setting-label"},Le={class:"slider-wrapper"},Ue={class:"slider-input-wrapper"},$e={key:1,class:"setting-item slider-item"},Se={class:"setting-label"},Te={class:"slider-wrapper"},_e={class:"slider-input-wrapper"},xe={key:0,class:"dialog-section"},Me={class:"section-header"},Re={class:"section-title"},Ae={class:"section-content"},Ee={class:"setting-item"},De={class:"setting-label"},Ie={class:"dialog-action"};function Ne(e,t,o,n,r,d){const c=(0,i.g2)("font-awesome-icon"),u=J.ll,p=J.MQ,h=s.R7,m=K.P9,g=K.AV,f=G.WK,y=q.qi,b=j.B8,v=Q.lq,C=l.S2,k=O.kZ;return(0,i.uX)(),(0,i.Wv)(k,{title:e.$t("uploadSettings.title"),modelValue:d.visible,"onUpdate:modelValue":t[12]||(t[12]=e=>d.visible=e),width:d.dialogWidth,"show-close":!1,class:"settings-dialog"},{default:(0,i.k6)(()=>[(0,i.Lk)("div",Y,[(0,i.Lk)("div",Z,[(0,i.Lk)("span",ee,(0,a.v_)(e.$t("uploadSettings.uploadChannel")),1)]),(0,i.Lk)("div",te,[(0,i.Lk)("div",oe,[(0,i.Lk)("span",se,(0,a.v_)(e.$t("uploadSettings.channelType")),1),(0,i.bF)(p,{"model-value":o.uploadChannel,"onUpdate:modelValue":t[0]||(t[0]=t=>e.$emit("update:uploadChannel",t)),class:"radio-card-group compact"},{default:(0,i.k6)(()=>[(0,i.bF)(u,{label:"telegram",class:"radio-card"},{default:(0,i.k6)(()=>[(0,i.bF)(c,{icon:"paper-plane",class:"channel-icon"}),t[13]||(t[13]=(0,i.Lk)("span",null,"TG",-1))]),_:1}),(0,i.bF)(u,{label:"cfr2",class:"radio-card"},{default:(0,i.k6)(()=>[(0,i.bF)(c,{icon:"cloud",class:"channel-icon"}),t[14]||(t[14]=(0,i.Lk)("span",null,"R2",-1))]),_:1}),(0,i.bF)(u,{label:"s3",class:"radio-card"},{default:(0,i.k6)(()=>[(0,i.bF)(c,{icon:"database",class:"channel-icon"}),t[15]||(t[15]=(0,i.Lk)("span",null,"S3",-1))]),_:1}),(0,i.bF)(u,{label:"discord",class:"radio-card"},{default:(0,i.k6)(()=>[(0,i.bF)(c,{icon:"comments",class:"channel-icon"}),t[16]||(t[16]=(0,i.Lk)("span",null,"DC",-1))]),_:1}),(0,i.bF)(u,{label:"huggingface",class:"radio-card"},{default:(0,i.k6)(()=>[(0,i.bF)(c,{icon:"robot",class:"channel-icon"}),t[17]||(t[17]=(0,i.Lk)("span",null,"HF",-1))]),_:1})]),_:1},8,["model-value"])]),o.currentChannelList.length>1?((0,i.uX)(),(0,i.CE)("div",le,[(0,i.Lk)("span",ie,[(0,i.eW)((0,a.v_)(e.$t("uploadSettings.channelName"))+" ",1),(0,i.bF)(h,{content:e.$t("uploadSettings.channelNameTooltip"),placement:"top"},{default:(0,i.k6)(()=>[(0,i.bF)(c,{icon:"question-circle",class:"inline-help-icon"})]),_:1},8,["content"])]),(0,i.bF)(g,{"model-value":o.channelName,"onUpdate:modelValue":t[1]||(t[1]=t=>e.$emit("update:channelName",t)),placeholder:e.$t("uploadSettings.autoSelect"),clearable:"",class:"setting-input"},{default:(0,i.k6)(()=>[((0,i.uX)(!0),(0,i.CE)(i.FK,null,(0,i.pI)(o.currentChannelList,e=>((0,i.uX)(),(0,i.Wv)(m,{key:e.name,label:e.name,value:e.name},null,8,["label","value"]))),128))]),_:1},8,["model-value","placeholder"])])):(0,i.Q3)("",!0),(0,i.Lk)("div",ae,[(0,i.Lk)("span",ne,(0,a.v_)(e.$t("uploadSettings.uploadDirectory")),1),(0,i.bF)(f,{"model-value":o.uploadFolder,"onUpdate:modelValue":d.handleUploadFolderInput,placeholder:e.$t("uploadSettings.uploadDirectoryPlaceholder"),class:"setting-input"},null,8,["model-value","onUpdate:modelValue","placeholder"])]),(0,i.Lk)("div",re,[(0,i.Lk)("span",de,[(0,i.eW)((0,a.v_)(e.$t("uploadSettings.autoSwitch"))+" ",1),(0,i.bF)(h,{content:e.$t("uploadSettings.autoSwitchTooltip"),placement:"top"},{default:(0,i.k6)(()=>[(0,i.bF)(c,{icon:"question-circle",class:"inline-help-icon"})]),_:1},8,["content"])]),(0,i.bF)(y,{"model-value":o.autoRetry,"onUpdate:modelValue":t[2]||(t[2]=t=>e.$emit("update:autoRetry",t))},null,8,["model-value"])])])]),(0,i.Lk)("div",ce,[(0,i.Lk)("div",ue,[(0,i.Lk)("span",pe,(0,a.v_)(e.$t("uploadSettings.fileNaming")),1)]),(0,i.Lk)("div",he,[(0,i.bF)(p,{"model-value":o.uploadNameType,"onUpdate:modelValue":t[3]||(t[3]=t=>e.$emit("update:uploadNameType",t)),class:"radio-card-group grid-2x2"},{default:(0,i.k6)(()=>[(0,i.bF)(u,{label:"default",class:"radio-card"},{default:(0,i.k6)(()=>[(0,i.bF)(c,{icon:"cog",class:"radio-icon"}),(0,i.Lk)("span",null,(0,a.v_)(e.$t("uploadSettings.namingDefault")),1)]),_:1}),(0,i.bF)(u,{label:"index",class:"radio-card"},{default:(0,i.k6)(()=>[(0,i.bF)(c,{icon:"hashtag",class:"radio-icon"}),(0,i.Lk)("span",null,(0,a.v_)(e.$t("uploadSettings.namingIndex")),1)]),_:1}),(0,i.bF)(u,{label:"origin",class:"radio-card"},{default:(0,i.k6)(()=>[(0,i.bF)(c,{icon:"file-signature",class:"radio-icon"}),(0,i.Lk)("span",null,(0,a.v_)(e.$t("uploadSettings.namingOrigin")),1)]),_:1}),(0,i.bF)(u,{label:"short",class:"radio-card"},{default:(0,i.k6)(()=>[(0,i.bF)(c,{icon:"compress-alt",class:"radio-icon"}),(0,i.Lk)("span",null,(0,a.v_)(e.$t("uploadSettings.namingShort")),1)]),_:1})]),_:1},8,["model-value"])])]),(0,i.Lk)("div",me,[(0,i.Lk)("div",ge,[(0,i.Lk)("span",fe,(0,a.v_)(e.$t("uploadSettings.filePreprocess")),1),(0,i.bF)(h,{content:e.$t("uploadSettings.filePreprocessTooltip"),placement:"top"},{default:(0,i.k6)(()=>[(0,i.bF)(c,{icon:"question-circle",class:"section-help-icon"})]),_:1},8,["content"])]),(0,i.Lk)("div",ye,[(0,i.Lk)("div",be,[(0,i.Lk)("span",ve,[(0,i.eW)((0,a.v_)(e.$t("uploadSettings.convertToWebp"))+" ",1),(0,i.bF)(h,{content:e.$t("uploadSettings.convertToWebpTooltip"),placement:"top"},{default:(0,i.k6)(()=>[(0,i.bF)(c,{icon:"question-circle",class:"inline-help-icon"})]),_:1},8,["content"])]),(0,i.bF)(y,{"model-value":o.convertToWebp,"onUpdate:modelValue":t[4]||(t[4]=t=>e.$emit("update:convertToWebp",t))},null,8,["model-value"])]),(0,i.Lk)("div",Ce,[(0,i.Lk)("span",ke,(0,a.v_)(e.$t("uploadSettings.fileCompress")),1),(0,i.bF)(y,{"model-value":o.customerCompress,"onUpdate:modelValue":t[5]||(t[5]=t=>e.$emit("update:customerCompress",t))},null,8,["model-value"])]),o.customerCompress?((0,i.uX)(),(0,i.CE)("div",we,[(0,i.Lk)("span",Fe,[(0,i.eW)((0,a.v_)(e.$t("uploadSettings.compressThreshold"))+" ",1),(0,i.bF)(h,{content:e.$t("uploadSettings.compressThresholdTooltip"),placement:"top"},{default:(0,i.k6)(()=>[(0,i.bF)(c,{icon:"question-circle",class:"inline-help-icon"})]),_:1},8,["content"])]),(0,i.Lk)("div",Le,[(0,i.bF)(b,{"model-value":o.compressBar,"onUpdate:modelValue":t[6]||(t[6]=t=>e.$emit("update:compressBar",t)),min:1,max:20,"format-tooltip":e=>`${e} MB`},null,8,["model-value","format-tooltip"]),(0,i.Lk)("div",Ue,[(0,i.bF)(v,{"model-value":o.compressBar,"onUpdate:modelValue":t[7]||(t[7]=t=>e.$emit("update:compressBar",t)),min:1,max:20,step:1,"value-on-clear":1,class:"slider-input","controls-position":"right"},null,8,["model-value"]),t[18]||(t[18]=(0,i.Lk)("span",{class:"slider-unit"},"MB",-1))])])])):(0,i.Q3)("",!0),o.customerCompress?((0,i.uX)(),(0,i.CE)("div",$e,[(0,i.Lk)("span",Se,[(0,i.eW)((0,a.v_)(e.$t("uploadSettings.expectedSize"))+" ",1),(0,i.bF)(h,{content:e.$t("uploadSettings.expectedSizeTooltip"),placement:"top"},{default:(0,i.k6)(()=>[(0,i.bF)(c,{icon:"question-circle",class:"inline-help-icon"})]),_:1},8,["content"])]),(0,i.Lk)("div",Te,[(0,i.bF)(b,{"model-value":o.compressQuality,"onUpdate:modelValue":t[8]||(t[8]=t=>e.$emit("update:compressQuality",t)),min:.5,max:o.compressBar,step:.1,"format-tooltip":e=>`${e} MB`},null,8,["model-value","max","format-tooltip"]),(0,i.Lk)("div",_e,[(0,i.bF)(v,{"model-value":o.compressQuality,"onUpdate:modelValue":t[9]||(t[9]=t=>e.$emit("update:compressQuality",t)),min:.5,max:o.compressBar,step:.1,precision:1,"value-on-clear":.5,class:"slider-input","controls-position":"right"},null,8,["model-value","max"]),t[19]||(t[19]=(0,i.Lk)("span",{class:"slider-unit"},"MB",-1))])])])):(0,i.Q3)("",!0)])]),"telegram"===o.uploadChannel?((0,i.uX)(),(0,i.CE)("div",xe,[(0,i.Lk)("div",Me,[(0,i.Lk)("span",Re,(0,a.v_)(e.$t("uploadSettings.serverCompress")),1),(0,i.bF)(h,{content:e.$t("uploadSettings.serverCompressTooltip"),placement:"top","raw-content":""},{default:(0,i.k6)(()=>[(0,i.bF)(c,{icon:"question-circle",class:"section-help-icon"})]),_:1},8,["content"])]),(0,i.Lk)("div",Ae,[(0,i.Lk)("div",Ee,[(0,i.Lk)("span",De,(0,a.v_)(e.$t("uploadSettings.enableCompress")),1),(0,i.bF)(y,{"model-value":o.serverCompress,"onUpdate:modelValue":t[10]||(t[10]=t=>e.$emit("update:serverCompress",t))},null,8,["model-value"])])])])):(0,i.Q3)("",!0),(0,i.Lk)("div",Ie,[(0,i.bF)(C,{type:"primary",onClick:t[11]||(t[11]=e=>d.visible=!1),class:"confirm-btn"},{default:(0,i.k6)(()=>[(0,i.eW)((0,a.v_)(e.$t("uploadSettings.confirm")),1)]),_:1})])]),_:1},8,["title","modelValue","width"])}var Pe={name:"UploadSettingsDialog",methods:{handleUploadFolderInput(e){e&&!e.startsWith("/")&&(e="/"+e),this.$emit("update:uploadFolder",e)}},props:{modelValue:{type:Boolean,default:!1},uploadChannel:{type:String,default:"telegram"},channelName:{type:String,default:""},currentChannelList:{type:Array,default:()=>[]},uploadFolder:{type:String,default:""},autoRetry:{type:Boolean,default:!0},uploadNameType:{type:String,default:"default"},convertToWebp:{type:Boolean,default:!1},customerCompress:{type:Boolean,default:!0},compressBar:{type:Number,default:5},compressQuality:{type:Number,default:4},serverCompress:{type:Boolean,default:!0}},emits:["update:modelValue","update:uploadChannel","update:channelName","update:uploadFolder","update:autoRetry","update:uploadNameType","update:convertToWebp","update:customerCompress","update:compressBar","update:compressQuality","update:serverCompress"],computed:{visible:{get(){return this.modelValue},set(e){this.$emit("update:modelValue",e)}},dialogWidth(){return window.innerWidth>768?"50%":"90%"}}};const Ve=(0,z.A)(Pe,[["render",Ne]]);var We=Ve,ze=o(88559),Be=(o(85970),o(813)),He=(o(34896),o(69655)),Xe=(o(2893),o(74253));o(79899);const Oe={class:"upload-list-item"},Qe=["href"],je={key:0,style:{width:"10vw","border-radius":"12px"},autoplay:"",muted:"",playsinline:"",loop:""},qe=["src"],Ge=["src"],Ke={key:2,style:{width:"10vw","border-radius":"12px"}},Je={class:"upload-list-item-content"},Ye={class:"upload-list-item-name-wrapper"},Ze={key:0,class:"upload-list-item-url"},et={class:"upload-list-item-url-row"},tt={class:"upload-list-item-url-row"},ot={key:1,class:"upload-list-item-progress"},st={class:"upload-list-item-action"};function lt(e,t,o,s,l,n){const r=(0,i.g2)("font-awesome-icon"),d=Xe.$g,c=G.WK,u=He.ve,p=(0,i.g2)("Link"),h=Be.tk,m=(0,i.g2)("Delete");return(0,i.uX)(),(0,i.CE)("div",Oe,[(0,i.Lk)("a",{href:o.file.url,target:"_blank",class:"upload-list-item-preview"},[n.isVideo(o.file.name)?((0,i.uX)(),(0,i.CE)("video",je,[(0,i.Lk)("source",{src:o.file.url,type:"video/mp4"},null,8,qe),t[7]||(t[7]=(0,i.eW)(" Your browser does not support the video tag. ",-1))])):n.isImage(o.file.name)?((0,i.uX)(),(0,i.CE)("img",{key:1,style:{width:"10vw","border-radius":"12px"},src:o.file.url,onError:t[0]||(t[0]=t=>e.$emit("preview-error",o.file))},null,40,Ge)):((0,i.uX)(),(0,i.CE)("div",Ke,[(0,i.bF)(r,{icon:"file",class:"file-icon"})]))],8,Qe),(0,i.Lk)("div",Je,[(0,i.Lk)("div",Ye,[(0,i.bF)(d,{class:"upload-list-item-name",truncated:""},{default:(0,i.k6)(()=>[(0,i.eW)((0,a.v_)(n.truncateFilename(o.file.name)),1)]),_:1})]),"done"===o.file.status?((0,i.uX)(),(0,i.CE)("div",Ze,[(0,i.Lk)("div",et,[(0,i.bF)(c,{modelValue:o.file.finalURL,"onUpdate:modelValue":t[1]||(t[1]=e=>o.file.finalURL=e),readonly:"",onClick:n.selectAllText,size:n.urlSize},{prepend:(0,i.k6)(()=>[...t[8]||(t[8]=[(0,i.eW)("URL",-1)])]),_:1},8,["modelValue","onClick","size"]),(0,i.bF)(c,{modelValue:o.file.mdURL,"onUpdate:modelValue":t[2]||(t[2]=e=>o.file.mdURL=e),readonly:"",onClick:n.selectAllText,size:n.urlSize},{prepend:(0,i.k6)(()=>[...t[9]||(t[9]=[(0,i.eW)("MarkDown",-1)])]),_:1},8,["modelValue","onClick","size"])]),(0,i.Lk)("div",tt,[(0,i.bF)(c,{modelValue:o.file.htmlURL,"onUpdate:modelValue":t[3]||(t[3]=e=>o.file.htmlURL=e),readonly:"",onClick:n.selectAllText,size:n.urlSize},{prepend:(0,i.k6)(()=>[...t[10]||(t[10]=[(0,i.eW)("HTML",-1)])]),_:1},8,["modelValue","onClick","size"]),(0,i.bF)(c,{modelValue:o.file.ubbURL,"onUpdate:modelValue":t[4]||(t[4]=e=>o.file.ubbURL=e),readonly:"",onClick:n.selectAllText,size:n.urlSize},{prepend:(0,i.k6)(()=>[...t[11]||(t[11]=[(0,i.eW)("BBCode",-1)])]),_:1},8,["modelValue","onClick","size"])])])):((0,i.uX)(),(0,i.CE)("div",ot,[(0,i.bF)(u,{percentage:o.file.progreess,status:o.file.status,"show-text":!1},null,8,["percentage","status"])]))]),(0,i.Lk)("div",st,[(0,i.Lk)("button",{class:"modern-file-action-btn modern-file-action-btn-primary",onClick:t[5]||(t[5]=t=>e.$emit("copy",o.file))},[(0,i.bF)(h,null,{default:(0,i.k6)(()=>[(0,i.bF)(p)]),_:1})]),(0,i.Lk)("button",{class:"modern-file-action-btn modern-file-action-btn-danger",onClick:t[6]||(t[6]=t=>e.$emit("remove",o.file))},[(0,i.bF)(h,null,{default:(0,i.k6)(()=>[(0,i.bF)(m)]),_:1})])])])}var it=o(57477);const at=["jpg","jpeg","png","gif","bmp","webp","svg","tiff","ico","avif","heic","jfif","pjpeg","pjp","raw","cr2","nef","dng","eps","ai","emf","wmf"],nt=["mp4","webm","ogg","mkv"];var rt={name:"UploadFileItem",components:{Link:it.Link,Delete:it.Delete},props:{file:{type:Object,required:!0}},emits:["copy","remove","preview-error"],computed:{urlSize(){return window.innerWidth<768?"small":"default"}},methods:{isImage(e){const t=e.split(".").pop().toLowerCase();return at.includes(t)},isVideo(e){const t=e.split(".").pop().toLowerCase();return nt.includes(t)},truncateFilename(e,t=20){if(!e||e.length<=t)return e;const o=e.lastIndexOf(".");let s,l;o>0?(s=e.substring(0,o),l=e.substring(o)):(s=e,l="");const i=l.length+4,a=t-i-3;return a<=0?e.substring(0,t-3)+"...":s.substring(0,a)+"..."+s.slice(-4)+l},selectAllText(e){navigator.clipboard.writeText(e.target.value).then(()=>{this.$message({type:"success",message:this.$t("uploadForm.copySuccess")})}).catch(()=>{this.$message({type:"error",message:this.$t("uploadForm.copyFailed")})})}}};const dt=(0,z.A)(rt,[["render",lt],["__scopeId","data-v-4848c2b0"]]);var ct=dt,ut=o(62086),pt=(o(40670),o(88830),o(23597),o(70683)),ht=(o(95385),o(47358));const mt={class:"upload-form"},gt={class:"upload-card-glow",ref:"uploadCardGlow"},ft=["innerHTML"],yt={key:0,class:"upload-card"},bt={class:"paste-card-actions"},vt={class:"upload-list-dashboard-action"},Ct={class:"modern-action-group"},kt={class:"modern-dropdown-item-content"},wt={class:"modern-action-btn modern-action-btn-danger"};function Ft(e,t,n,r,d,c){const u=(0,i.g2)("CameraFilled"),p=Be.tk,h=ht.j5,m=G.WK,g=l.S2,f=J.Zh,y=J.MQ,b=pt.Ik,v=(0,i.g2)("List"),C=(0,i.g2)("Checked"),k=(0,i.g2)("Failed"),w=Xe.$g,F=(0,i.g2)("font-awesome-icon"),L=s.R7,U=q.qi,$=ut.c6,S=ut.Iy,T=ut.dW,_=ct,x=ze.kA;return(0,i.uX)(),(0,i.CE)("div",mt,[(0,i.Lk)("div",{class:"upload-card-wrapper",onMousemove:t[0]||(t[0]=(...e)=>c.handleUploadCardMouseMove&&c.handleUploadCardMouseMove(...e)),onMouseleave:t[1]||(t[1]=(...e)=>c.handleUploadCardMouseLeave&&c.handleUploadCardMouseLeave(...e))},[(0,i.Lk)("div",gt,null,512),"default"===n.uploadMethod?((0,i.uX)(),(0,i.Wv)(h,{key:0,class:(0,a.C4)(["upload-card",{"is-uploading":d.uploading,"upload-card-busy":d.fileList.length}]),drag:"",multiple:"","http-request":c.uploadFile,onSuccess:c.handleSuccess,"on-error":c.handleError,"before-upload":c.beforeUpload,"on-progress":c.handleProgress,"file-list":d.fileList,"show-file-list":!1},{default:(0,i.k6)(()=>[(0,i.bF)(p,{class:(0,a.C4)(["el-icon--upload",{"upload-list-busy":d.fileList.length}])},{default:(0,i.k6)(()=>[(0,i.bF)(u)]),_:1},8,["class"]),(0,i.Lk)("div",{class:(0,a.C4)(["el-upload__text",{"upload-list-busy":d.fileList.length}]),innerHTML:e.$t("upload.dragUploadText")},null,10,ft)]),_:1},8,["class","http-request","onSuccess","on-error","before-upload","on-progress","file-list"])):(0,i.Q3)("",!0)],32),"paste"===n.uploadMethod?((0,i.uX)(),(0,i.CE)("div",yt,[(0,i.bF)(b,{class:(0,a.C4)(["paste-card",{"is-uploading":d.uploading,"upload-card-busy":d.fileList.length}])},{default:(0,i.k6)(()=>[(0,i.bF)(m,{modelValue:d.pastedUrls,"onUpdate:modelValue":t[2]||(t[2]=e=>d.pastedUrls=e),class:"upload-card-textarea",placeholder:e.$t("upload.pasteUrlPlaceholder"),type:"textarea",rows:d.fileList.length?4:14},null,8,["modelValue","placeholder","rows"]),(0,i.Lk)("div",bt,[(0,i.bF)(g,{class:"paste-card-upload-button",type:"primary",size:c.pasteCardMethodButtonSize,onClick:c.handleUploadPasteUrls},{default:(0,i.k6)(()=>[(0,i.eW)((0,a.v_)(e.$t("upload.pasteUploadBtn")),1)]),_:1},8,["size","onClick"]),(0,i.bF)(y,{modelValue:d.pasteUploadMethod,"onUpdate:modelValue":t[3]||(t[3]=e=>d.pasteUploadMethod=e),class:"paste-card-method-group",size:c.pasteCardMethodButtonSize},{default:(0,i.k6)(()=>[(0,i.bF)(f,{label:"save"},{default:(0,i.k6)(()=>[(0,i.eW)((0,a.v_)(e.$t("upload.pasteSave")),1)]),_:1}),(0,i.bF)(f,{label:"external"},{default:(0,i.k6)(()=>[(0,i.eW)((0,a.v_)(e.$t("upload.pasteExternal")),1)]),_:1})]),_:1},8,["modelValue","size"])])]),_:1},8,["class"])])):(0,i.Q3)("",!0),(0,i.bF)(b,{class:(0,a.C4)(["upload-list-card",{"upload-list-busy":d.fileList.length,"is-uploading":d.uploading}])},{default:(0,i.k6)(()=>[(0,i.Lk)("div",{class:(0,a.C4)(["upload-list-container",{"upload-list-busy":d.fileList.length}])},[(0,i.bF)(x,{onScroll:c.handleScroll,ref:"scrollContainer"},{default:(0,i.k6)(()=>[(0,i.Lk)("div",{class:(0,a.C4)(["upload-list-dashboard",{"list-scrolled":d.listScrolled}])},[(0,i.bF)(w,{class:"upload-list-dashboard-title"},{default:(0,i.k6)(()=>[(0,i.bF)(p,null,{default:(0,i.k6)(()=>[(0,i.bF)(v)]),_:1}),(0,i.eW)((0,a.v_)(c.uploadingCount+c.waitingCount)+" ",1),(0,i.bF)(p,null,{default:(0,i.k6)(()=>[(0,i.bF)(C)]),_:1}),(0,i.eW)((0,a.v_)(c.uploadSuccessCount)+" ",1),(0,i.bF)(p,null,{default:(0,i.k6)(()=>[(0,i.bF)(k)]),_:1}),(0,i.eW)((0,a.v_)(c.uploadErrorCount),1)]),_:1}),(0,i.Lk)("div",vt,[(0,i.Lk)("div",Ct,[(0,i.bF)(L,{disabled:c.disableTooltip,content:e.$t("upload.copyAll"),placement:"top"},{default:(0,i.k6)(()=>[(0,i.Lk)("button",{class:"modern-action-btn",onClick:t[4]||(t[4]=(...e)=>c.copyAll&&c.copyAll(...e))},[(0,i.bF)(F,{icon:"copy"})])]),_:1},8,["disabled","content"]),(0,i.bF)(L,{disabled:c.disableTooltip,content:e.$t("upload.retryFailed"),placement:"top"},{default:(0,i.k6)(()=>[(0,i.bF)(T,null,{dropdown:(0,i.k6)(()=>[(0,i.bF)(S,{class:"modern-dropdown-menu"},{default:(0,i.k6)(()=>[(0,i.bF)($,null,{default:(0,i.k6)(()=>[(0,i.Lk)("div",kt,[(0,i.Lk)("span",null,(0,a.v_)(e.$t("uploadForm.autoRetry")),1),(0,i.bF)(U,{modelValue:d.autoReUpload,"onUpdate:modelValue":t[6]||(t[6]=e=>d.autoReUpload=e),onChange:c.handleAutoRetryChange,size:"small"},null,8,["modelValue","onChange"])])]),_:1})]),_:1})]),default:(0,i.k6)(()=>[(0,i.Lk)("button",{class:"modern-action-btn",onClick:t[5]||(t[5]=(...e)=>c.retryError&&c.retryError(...e))},[(0,i.bF)(F,{icon:"redo"})])]),_:1})]),_:1},8,["disabled","content"]),(0,i.bF)(L,{disabled:c.disableTooltip,content:e.$t("upload.clearList"),placement:"top"},{default:(0,i.k6)(()=>[(0,i.bF)(T,null,{dropdown:(0,i.k6)(()=>[(0,i.bF)(S,{class:"modern-dropdown-menu"},{default:(0,i.k6)(()=>[(0,i.bF)($,{onClick:c.clearFileList},{default:(0,i.k6)(()=>[(0,i.eW)((0,a.v_)(e.$t("upload.clearAll")),1)]),_:1},8,["onClick"]),(0,i.bF)($,{onClick:c.clearSuccessList},{default:(0,i.k6)(()=>[(0,i.eW)((0,a.v_)(e.$t("upload.clearUploaded")),1)]),_:1},8,["onClick"])]),_:1})]),default:(0,i.k6)(()=>[(0,i.Lk)("button",wt,[(0,i.bF)(F,{icon:"trash-alt"})])]),_:1})]),_:1},8,["disabled","content"])])])],2),((0,i.uX)(!0),(0,i.CE)(i.FK,null,(0,i.pI)(d.fileList.slice().reverse(),e=>((0,i.uX)(),(0,i.Wv)(_,{key:e.name,file:e,onCopy:c.handleCopy,onRemove:c.handleRemove,onPreviewError:t[7]||(t[7]=e=>e.url=o(96682))},null,8,["file","onCopy","onRemove"]))),128))]),_:1},8,["onScroll"])],2)]),_:1},8,["class"])])}o(16573),o(78100),o(77936),o(20116),o(18237),o(79577),o(41549),o(49797),o(49631),o(35623),o(64979),o(14603),o(47566),o(98721);var Lt=o(457),Ut=o(76334),$t=o(60782);function St(e,t,o){const s=o+e;return{finalURL:s,mdURL:`![${t}](${s})`,htmlURL:`${t}`,ubbURL:`[img]${s}[/img]`}}function Tt(e,t){const o={url:e.finalURL,md:e.mdURL,html:e.htmlURL,ubb:e.ubbURL};return o[t]||e.finalURL}function _t(e,t){e.forEach(e=>{if("external"===e.uploadChannel)return;const o=St(e.srcID,e.name,t);Object.assign(e,o)})}const xt=new Uint32Array([1116352408,1899447441,3049323471,3921009573,961987163,1508970993,2453635748,2870763221,3624381080,310598401,607225278,1426881987,1925078388,2162078206,2614888103,3248222580,3835390401,4022224774,264347078,604807628,770255983,1249150122,1555081692,1996064986,2554220882,2821834349,2952996808,3210313671,3336571891,3584528711,113926993,338241895,666307205,773529912,1294757372,1396182291,1695183700,1986661051,2177026350,2456956037,2730485921,2820302411,3259730800,3345764771,3516065817,3600352804,4094571909,275423344,430227734,506948616,659060556,883997877,958139571,1322822218,1537002063,1747873779,1955562222,2024104815,2227730452,2361852424,2428436474,2756734187,3204031479,3329325298]),Mt=(e,t)=>e>>>t|e<<32-t;function Rt(e,t){const o=new Uint32Array(64);for(let u=0;u<16;u++)o[u]=e[4*u]<<24|e[4*u+1]<<16|e[4*u+2]<<8|e[4*u+3];for(let u=16;u<64;u++){const e=Mt(o[u-15],7)^Mt(o[u-15],18)^o[u-15]>>>3,t=Mt(o[u-2],17)^Mt(o[u-2],19)^o[u-2]>>>10;o[u]=o[u-16]+e+o[u-7]+t>>>0}let[s,l,i,a,n,r,d,c]=t;for(let u=0;u<64;u++){const e=Mt(n,6)^Mt(n,11)^Mt(n,25),t=n&r^~n&d,p=c+e+t+xt[u]+o[u]>>>0,h=Mt(s,2)^Mt(s,13)^Mt(s,22),m=s&l^s&i^l&i,g=h+m>>>0;c=d,d=r,r=n,n=a+p>>>0,a=i,i=l,l=s,s=p+g>>>0}t[0]=t[0]+s>>>0,t[1]=t[1]+l>>>0,t[2]=t[2]+i>>>0,t[3]=t[3]+a>>>0,t[4]=t[4]+n>>>0,t[5]=t[5]+r>>>0,t[6]=t[6]+d>>>0,t[7]=t[7]+c>>>0}function At(){let e=new Uint32Array([1779033703,3144134277,1013904242,2773480762,1359893119,2600822924,528734635,1541459225]),t=new Uint8Array(64),o=0,s=0;return{update(l){s+=l.length;let i=0;if(o>0){const s=64-o,a=Math.min(s,l.length);t.set(l.subarray(0,a),o),o+=a,i=a,64===o&&(Rt(t,e),o=0)}while(i+64<=l.length)Rt(l.subarray(i,i+64),e),i+=64;i56&&(t.fill(0,o,64),Rt(t,e),o=0),t.fill(0,o,56);const i=new DataView(t.buffer);i.setUint32(56,Math.floor(l/4294967296),!1),i.setUint32(60,l>>>0,!1),Rt(t,e);let a="";for(let t=0;t<8;t++)a+=e[t].toString(16).padStart(8,"0");return a}}}async function Et(e){const t=At(),o=4194304;let s=0;while(sthis.fileListLength&&this.$nextTick(()=>{setTimeout(()=>{this.$refs.scrollContainer&&this.$refs.scrollContainer.setScrollTop(0)},100)}),this.fileListLength=this.fileList.length},deep:!0},useCustomUrl:{handler(){_t(this.fileList,this.rootUrl)},immediate:!0},customUrlPrefix:{handler(){"true"===this.useCustomUrl&&_t(this.fileList,this.rootUrl)},immediate:!0},autoReUpload(e){this.$store.commit("setStoreAutoReUpload",e)}},computed:{...(0,$t.L8)(["storeAutoReUpload"]),uploadSuccessCount(){return this.fileList.filter(e=>"done"===e.status||"success"===e.status).length},uploadErrorCount(){return this.fileList.filter(e=>"exception"===e.status).length},uploadingCount(){return this.fileList.filter(e=>"uploading"===e.status).length},waitingCount(){return this.uploadQueue.length},urlSize(){return window.innerWidth<768?"small":"default"},disableTooltip(){return window.innerWidth<768},rootUrl(){return"true"===this.useCustomUrl?this.customUrlPrefix:this.urlPrefix||`${window.location.protocol}//${window.location.host}/file/`},pasteCardMethodButtonSize(){return this.fileList.length||window.innerWidth<768?"small":"medium"}},mounted(){document.addEventListener("paste",this.handlePaste),this.autoReUpload=this.storeAutoReUpload},beforeUnmount(){document.removeEventListener("paste",this.handlePaste),this.uploadQueue=[],this.fileList=[],this.activeUploads=0},methods:{truncateFilename(e,t=20){if(!e||e.length<=t)return e;const o=e.lastIndexOf(".");let s,l;o>0?(s=e.substring(0,o),l=e.substring(o)):(s=e,l="");const i=l.length+4,a=t-i-3;return a<=0?e.substring(0,t-3)+"...":s.substring(0,a)+"..."+s.slice(-4)+l},uploadFile(e){if(!this.fileList.find(t=>t.uid===e.file.uid))return;if(this.activeUploads>=this.maxConcurrentUploads){this.uploadQueue.push(e);const t=this.fileList.find(t=>t.uid===e.file.uid);return void(t&&(t.status="waiting"))}this.activeUploads++;const t=this.fileList.find(t=>t.uid===e.file.uid);t&&(t.status="uploading");const o=this.fileList.find(t=>t.uid===e.file.uid),s=o?.uploadChannel||this.uploadChannel;if("external"===s)return void this.uploadSingleFile(e);if("huggingface"===s){const t=20971520;return void(e.file.size>=t?this.uploadToHuggingFaceDirect(e):this.uploadSingleFile(e))}if("discord"===s){const t=9437184;return void(e.file.size>t?this.uploadFileInChunks(e):this.uploadSingleFile(e))}const l=20971520;e.file.size>l?this.uploadFileInChunks(e):this.uploadSingleFile(e)},processUploadQueue(){if(0===this.uploadQueue.length||this.activeUploads>=this.maxConcurrentUploads)return;const e=this.uploadQueue.shift();e&&this.fileList.find(t=>t.uid===e.file.uid)?this.uploadFile(e):this.processUploadQueue()},onUploadComplete(){this.activeUploads=Math.max(0,this.activeUploads-1),this.processUploadQueue(),0===this.activeUploads&&0===this.uploadQueue.length&&(this.uploading=!1)},async uploadSingleFile(e){const t=this.fileList.find(t=>t.uid===e.file.uid);if(!t)return;const o=t.serverCompress,s=t.uploadChannel||this.uploadChannel,l=this.autoRetry&&"external"!==s,i="external"===s?"default":this.uploadNameType,a=new AbortController;this.abortControllers.set(e.file.uid,a);const n=new FormData;if(n.append("file",e.file),"external"===s&&n.append("url",e.file.url),"huggingface"===s)try{console.log("Computing SHA256 for HuggingFace upload...");const t=await Et(e.file);n.append("sha256",t),console.log("SHA256 computed:",t)}catch(r){console.error("Failed to compute SHA256:",r)}(0,Lt.A)({url:"/upload?serverCompress="+o+"&uploadChannel="+s+(this.channelName?"&channelName="+encodeURIComponent(this.channelName):"")+"&uploadNameType="+i+"&autoRetry="+l+"&uploadFolder="+encodeURIComponent(this.uploadFolder),method:"post",data:n,withAuthCode:!0,signal:a.signal,onUploadProgress:t=>{const o=Math.round(t.loaded/t.total*100);e.onProgress({percent:o,file:e.file})}}).then(t=>{e.onSuccess(t,e.file)}).catch(t=>{"CanceledError"!==t.name&&"ERR_CANCELED"!==t.code?t.response&&401!==t.response.status?(this.exceptionList.push(e),e.onError(t,e.file)):t.response||(this.exceptionList.push(e),e.onError(t,e.file)):console.log("上传已取消:",e.file.name)}).finally(()=>{this.abortControllers.delete(e.file.uid),this.onUploadComplete()})},async uploadFileInChunks(e){const t=this.fileList.find(t=>t.uid===e.file.uid);if(!t)return;const o=t.uploadChannel||this.uploadChannel,s=new AbortController;this.abortControllers.set(e.file.uid,s);const l="discord"===o?9437184:16777216,i=e.file.size,a=Math.ceil(i/l),n=t.serverCompress,r=this.autoRetry&&"external"!==o,d="external"===o?"default":this.uploadNameType;let c=null;if("huggingface"===o)try{console.log("Computing SHA256 for HuggingFace chunked upload..."),c=await Et(e.file),console.log("SHA256 computed:",c)}catch(u){console.error("Failed to compute SHA256:",u)}try{const t=new FormData;t.append("originalFileName",e.file.name),t.append("originalFileType",e.file.type),t.append("totalChunks",a.toString());const p=await(0,Lt.A)({url:"/upload?serverCompress="+n+"&uploadChannel="+o+(this.channelName?"&channelName="+encodeURIComponent(this.channelName):"")+"&uploadNameType="+d+"&autoRetry="+r+"&uploadFolder="+encodeURIComponent(this.uploadFolder)+"&initChunked=true",method:"post",data:t,withAuthCode:!0});if(!p.data.success)throw new Error(this.$t("uploadForm.chunkInitFailed")+": "+p.data.message);const h=p.data.uploadId;console.log("分块上传初始化成功,uploadId:",h);const m=this.fileList.find(t=>t.uid===e.file.uid);m&&(m.totalChunks=a,m.uploadId=h);const g=3,f=new Array(a).fill(0);let y=0,b=!1,v="",C=!1;const k=async t=>{if(b||C)return;const c=t*l,p=Math.min(c+l,i),m=e.file.slice(c,p),g=new FormData;g.append("file",m,`${e.file.name}.part${t.toString().padStart(3,"0")}`),g.append("chunkIndex",t.toString()),g.append("totalChunks",a.toString()),g.append("uploadId",h),g.append("originalFileName",e.file.name),g.append("originalFileType",e.file.type);let y=0;const k=3;while(y{if(b||C)return;const s=Math.round(o.loaded/o.total*100);f[t]=s;const l=Math.round(f.reduce((e,t)=>e+t,0)/a);e.onProgress({percent:l,file:e.file})}})}catch(u){if("CanceledError"===u.name||"ERR_CANCELED"===u.code)return C=!0,void console.log("分块上传已取消:",e.file.name);if(y++,console.warn(`分块 ${t+1}/${a} 上传失败 (重试 ${y}/${k}):`,u),y>=k)throw b=!0,v=`分块 ${t+1}/${a} 上传失败: ${u.message}`,new Error(v);await new Promise(e=>setTimeout(e,2e3*y))}}},w=[];for(let e=0;e{while(yt.uid===e.file.uid);t&&t.uploadId&&this.cleanupUploadResources(t.uploadId,t.totalChunks).then(()=>{console.log(`已清理分块上传失败的资源: ${t.uploadId}`)}).catch(e=>{console.warn("清理分块上传失败资源时出错:",e)}),u.response&&401!==u.response.status?(this.exceptionList.push(e),e.onError(u,e.file)):u.response||(this.exceptionList.push(e),e.onError(u,e.file))}finally{this.abortControllers.delete(e.file.uid),this.onUploadComplete()}},handleRemove(e){this.abortControllers.has(e.uid)&&(this.abortControllers.get(e.uid).abort(),this.abortControllers.delete(e.uid)),this.uploadQueue=this.uploadQueue.filter(t=>t.file.uid!==e.uid),this.fileList=this.fileList.filter(t=>t.uid!==e.uid),this.$message({type:"info",message:this.$t("uploadForm.deleted",{name:this.truncateFilename(e.name)})})},async cleanupUploadResources(e,t=0){try{await(0,Lt.A)({url:`/upload?cleanup=true&uploadId=${e}&totalChunks=${t}`,method:"get",withAuthCode:!0,timeout:5e3}),console.log(`清理上传资源成功: ${e}`)}catch(o){console.warn("清理上传资源失败:",o)}},handleSuccess(e,t){const o=this.fileList.find(e=>e.uid===t.uid);if(o)try{const s=o.uploadChannel||this.uploadChannel;if("external"!==s){const s=e.data[0].src.replace("/file/","");o.url=`${window.location.protocol}//${window.location.host}/file/`+s;const l=St(s,t.name,this.rootUrl);Object.assign(o,l),o.srcID=s}o.progreess=100,o.status="success",this.saveToHistory(o),this.$message({type:"success",message:this.$t("uploadForm.uploadSuccess",{name:this.truncateFilename(t.name)})}),setTimeout(()=>{const e=this.fileList.find(e=>e.uid===t.uid);e&&(e.status="done")},1e3)}catch(s){this.$message.error(this.$t("uploadForm.uploadFailed",{name:this.truncateFilename(t.name)})),o.status="exception"}},saveToHistory(e){try{const t=JSON.parse(localStorage.getItem("uploadHistory")||"[]"),o={name:e.name,url:e.finalURL,time:Date.now(),type:e.name.split(".").pop().toLowerCase()};t.push(o),localStorage.setItem("uploadHistory",JSON.stringify(t))}catch(t){console.error("Failed to save history",t)}},handleError(e,t){const o=this.fileList.find(e=>e.uid===t.uid);o&&(this.$message.error(this.$t("uploadForm.uploadFailed",{name:this.truncateFilename(t.name)})),o.status="exception",this.autoReUpload&&this.scheduleAutoRetry())},handleCopy(e){const t=this.fileList.find(t=>t.uid===e.uid).status;"done"===t||"success"===t?(navigator.clipboard.writeText(Tt(e,this.selectedUrlForm)),this.$message({type:"success",message:this.$t("uploadForm.copySuccess")})):this.$message({type:"warning",message:this.$t("uploadForm.fileNotUploaded")})},beforeUpload(e){return new Promise(async(t,o)=>{let s=e;const l=this.convertToWebp&&e.type.includes("image")&&!e.type.includes("webp")&&!e.type.includes("gif")&&!e.type.includes("svg");if(l)try{const t=await this.convertImageToWebp(e);t&&(s=t,console.log(`WebP转换成功: ${e.name} -> ${t.name}, 大小: ${(e.size/1024).toFixed(1)}KB -> ${(t.size/1024).toFixed(1)}KB`))}catch(r){console.warn("WebP转换失败,使用原文件:",r)}const i=s.type.includes("image")&&this.customerCompress&&s.size/1024/1024>this.compressBar,a=s.size/1024/1024<=1024||"telegram"!==this.uploadChannel,n=(e,o)=>{const s=URL.createObjectURL(e);this.fileList.push({uid:e.uid,name:e.name,url:s,finalURL:"",mdURL:"",htmlURL:"",ubbURL:"",srcID:"",status:"uploading",progreess:0,serverCompress:o,retryCount:0}),t(e)};if(i)Ut.compressAccurately(s,1024*this.compressQuality).then(t=>{t.size/1024/1024>1024&&"telegram"===this.uploadChannel&&(this.$message.error(this.$t("uploadForm.compressedFileTooLarge",{name:s.name})),o(this.$t("uploadForm.fileSizeTooLarge"))),this.uploading=!0;const l=new File([t],s.name,{type:t.type});l.uid=e.uid;const i=this.uploadCount++,a=this.serverCompress&&l.size/1024/1024<10&&"telegram"===this.uploadChannel;0===i?n(l,a):setTimeout(()=>{n(l,a),this.uploadCount--},300*i)}).catch(e=>{this.$message.error(this.$t("uploadForm.compressFailedCannotUpload",{name:s.name})),o(e)});else if(a){this.uploading=!0;const e=this.uploadCount++,t="telegram"===this.uploadChannel&&this.serverCompress&&(!s.type.includes("image")||s.size/1024/1024<10);0===e?n(s,t):setTimeout(()=>{n(s,t),this.uploadCount--},300*e)}else this.$message.error(this.$t("uploadForm.fileTooLarge",{name:s.name})),o(this.$t("uploadForm.fileSizeTooLarge"))})},handleProgress(e){const t=this.fileList.find(t=>t.uid===e.file.uid);t&&(t.progreess=e.percent)},copyAll(){const e=this.fileList.filter(e=>"done"===e.status||"success"===e.status).map(e=>Tt(e,this.selectedUrlForm)).join("\n");navigator.clipboard.writeText(e),this.$message({type:"success",message:this.$t("uploadForm.copyAllSuccess")})},clearFileList(){this.fileList.length>0?(this.abortControllers.forEach((e,t)=>{e.abort()}),this.abortControllers.clear(),this.uploadQueue=[],this.fileList=[],this.$message({type:"success",message:this.$t("uploadForm.fileListCleared")})):this.$message({type:"info",message:this.$t("uploadForm.fileListEmpty")})},clearSuccessList(){this.uploadSuccessCount>0?(this.fileList=this.fileList.filter(e=>"done"!==e.status&&"success"!==e.status),this.$message({type:"success",message:this.$t("uploadForm.successFilesCleared")})):this.$message({type:"info",message:this.$t("uploadForm.successFilesEmpty")})},handlePaste(e){if("INPUT"===e.target.tagName||"TEXTAREA"===e.target.tagName)return;const t=e.clipboardData.items;t.length>0&&this.uploadFromUrl(t)},handleUploadPasteUrls(){const e=this.pastedUrls.split("\n"),t=e.map(e=>e.trim()).filter(e=>""!==e).filter(e=>/^(https?:\/\/[^\s$.?#].[^\s]*)$/.test(e));if("save"===this.pasteUploadMethod)this.uploadFromUrl(t.map(e=>({kind:"string",getAsString:t=>{t(e)}})));else if("external"===this.pasteUploadMethod)for(let o=0;o`,a=`[img]${e}[/img]`,n=new File([],e.split("/").pop(),{type:"text/plain"});n.uid=Date.now()+o,n.url=e,this.fileList.push({uid:n.uid,name:n.name,url:e,finalURL:e,mdURL:l,htmlURL:i,ubbURL:a,srcID:e,status:"uploading",progreess:0,serverCompress:!1,uploadChannel:"external",retryCount:0}),this.uploadFile({file:n,onProgress:e=>this.handleProgress(e),onSuccess:(e,t)=>this.handleSuccess(e,t),onError:(e,t)=>this.handleError(e,t)})}},uploadFromUrl(e){for(let t=0;t{e instanceof File&&this.uploadFile({file:e,onProgress:e=>this.handleProgress(e),onSuccess:(e,t)=>this.handleSuccess(e,t),onError:(e,t)=>this.handleError(e,t)})}).catch(e=>{console.log(e)})}else"string"===e[t].kind&&e[t].getAsString(e=>{const o=/^(https?:\/\/[^\s$.?#].[^\s]*)$/;let s="";o.test(e)&&Lt.A.post("/api/fetchRes",{url:e},{responseType:"blob",withAuthCode:!0}).then(o=>{o.headers["content-type"];if(200!=o.status)throw new Error("URL地址请求失败");{const i=o.headers["content-disposition"];if(i){const e=/filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/,t=/filename\*\s*=\s*UTF-8''([^;\n]*)/;let o=e.exec(i);if(null!=o&&o[1]){s=o[1].replace(/['"]/g,"");try{s=decodeURIComponent(s)}catch(l){s=""}}""===s&&(o=t.exec(i),null!=o&&o[1]&&(s=decodeURIComponent(o[1])))}if(""===s){const t=new URL(e);s=t.pathname.split("/").pop()}if(""===s){const o=new URL(e);let l=o.pathname.split(".").pop();(!l||""===l||l.length>10)&&(l="bin"),s="PastedFile"+Date.now()+t+"."+l}const a=o.data,n=new File([a],s,{type:a.type});n.uid=Date.now()+t;const r=this.beforeUpload(n);r instanceof Promise&&r.then(e=>{e instanceof File&&this.uploadFile({file:e,onProgress:e=>this.handleProgress(e),onSuccess:(e,t)=>this.handleSuccess(e,t),onError:(e,t)=>this.handleError(e,t)})}).catch(e=>{console.log(e)})}}).catch(e=>{this.$message({type:"warning",message:this.$t("uploadForm.urlRequestFailed")})})})},handleScroll(e){this.listScrolled=e.scrollTop>0&&this.fileList.length>0},retryError(){this.exceptionList.length>0?(this.retryFailedFiles(this.exceptionList),this.exceptionList=[]):this.$message({type:"info",message:this.$t("uploadForm.noFailedFiles")})},handleAutoRetryChange(e){this.$message({type:e?"success":"info",message:e?this.$t("uploadForm.autoRetryOn"):this.$t("uploadForm.autoRetryOff")}),e&&this.exceptionList.length>0&&this.scheduleAutoRetry()},retryFailedFiles(e){e.forEach(e=>{const t=e.retryCount||0;tthis.handleProgress(e),onSuccess:(e,t)=>this.handleSuccess(e,t),onError:(e,t)=>this.handleError(e,t)})):this.$message({type:"warning",message:this.$t("uploadForm.maxRetryReached",{name:e.name,max:this.maxRetryCount})})})},scheduleAutoRetry(){this.retryTimer&&clearTimeout(this.retryTimer),this.retryTimer=setTimeout(()=>{if(this.autoReUpload&&this.exceptionList.length>0){const e=[...this.exceptionList];this.exceptionList=[],this.retryFailedFiles(e)}},this.retryDelay)},async uploadToHuggingFaceDirect(e){const t=this.fileList.find(t=>t.uid===e.file.uid);if(!t)return;const o=new AbortController;this.abortControllers.set(e.file.uid,o);try{console.log("=== HuggingFace Direct Upload ==="),console.log("File:",e.file.name,"Size:",e.file.size),e.onProgress({percent:5,file:e.file}),console.log("Computing SHA256...");const t=await Et(e.file);if(console.log("SHA256:",t),o.signal.aborted)return void console.log("HuggingFace 上传已取消:",e.file.name);const s=new Uint8Array(await e.file.slice(0,512).arrayBuffer()),l=btoa(String.fromCharCode(...s));e.onProgress({percent:10,file:e.file}),console.log("Getting LFS upload URL...");const i=await(0,Lt.A)({url:"/upload/huggingface/getUploadUrl",method:"post",data:{fileSize:e.file.size,fileName:e.file.name,fileType:e.file.type,sha256:t,fileSample:l,channelName:this.channelName,uploadNameType:this.uploadNameType,uploadFolder:this.uploadFolder},withAuthCode:!0,signal:o.signal});if(!i.data.success)throw new Error(i.data.error||"Failed to get upload URL");const a=i.data;if(console.log("Upload info:",a),a.alreadyExists)console.log("File already exists in LFS, skipping upload"),e.onProgress({percent:90,file:e.file});else if(a.needsLfs&&a.uploadAction){const{href:t,header:s}=a.uploadAction;if(s?.chunk_size)await this.uploadToHuggingFaceMultipart(e,a,o);else{console.log("Uploading to S3 (basic)...");const l=await fetch(t,{method:"PUT",headers:s||{},body:e.file,signal:o.signal});if(!l.ok){const e=await l.text();throw new Error(`S3 upload failed: ${l.status} - ${e}`)}console.log("S3 upload complete")}}if(o.signal.aborted)return void console.log("HuggingFace 上传已取消:",e.file.name);e.onProgress({percent:95,file:e.file}),console.log("Committing file...");const n=await(0,Lt.A)({url:"/upload/huggingface/commitUpload",method:"post",data:{fullId:a.fullId,filePath:a.filePath,sha256:t,fileSize:e.file.size,fileName:e.file.name,fileType:e.file.type,channelName:a.channelName},withAuthCode:!0,signal:o.signal});if(!n.data.success)throw new Error(n.data.error||"Failed to commit file");console.log("Upload complete:",n.data);const r={data:[{src:n.data.src}]};e.onSuccess(r,e.file)}catch(s){if("CanceledError"===s.name||"ERR_CANCELED"===s.code||"AbortError"===s.name)return void console.log("HuggingFace 上传已取消:",e.file.name);console.error("HuggingFace direct upload error:",s),this.exceptionList.push(e),e.onError(s,e.file)}finally{this.abortControllers.delete(e.file.uid),this.onUploadComplete()}},async uploadToHuggingFaceMultipart(e,t,o){const{uploadAction:s}=t,{href:l,header:i}=s,a=parseInt(i.chunk_size),n=Object.keys(i).filter(e=>/^[0-9]+$/.test(e));console.log(`Multipart upload: ${n.length} parts, chunk size: ${a}`);const r=[],d=n.length;for(const u of n){if(o&&o.signal.aborted)throw console.log("HuggingFace 分片上传已取消"),new DOMException("Upload cancelled","AbortError");const t=parseInt(u)-1,s=t*a,l=Math.min(s+a,e.file.size),n=e.file.slice(s,l);console.log(`Uploading part ${u}/${d}`);const c=await fetch(i[u],{method:"PUT",body:n,signal:o?o.signal:void 0});if(!c.ok)throw new Error(`Failed to upload part ${u}: ${c.status}`);const p=c.headers.get("ETag");if(!p)throw new Error(`No ETag for part ${u}`);r.push({partNumber:parseInt(u),etag:p});const h=10+Math.round(parseInt(u)/d*80);e.onProgress({percent:h,file:e.file})}if(o&&o.signal.aborted)throw console.log("HuggingFace 分片上传已取消"),new DOMException("Upload cancelled","AbortError");console.log("Completing multipart upload...");const c=await fetch(l,{method:"POST",headers:{Accept:"application/vnd.git-lfs+json","Content-Type":"application/vnd.git-lfs+json"},body:JSON.stringify({oid:t.oid,parts:r}),signal:o?o.signal:void 0});if(!c.ok){const e=await c.text();throw new Error(`Multipart complete failed: ${c.status} - ${e}`)}console.log("Multipart upload complete")},async convertImageToWebp(e){return new Promise((t,o)=>{if(e.type.includes("gif")||e.type.includes("svg")||e.type.includes("webp"))return void t(null);const s=new Image,l=document.createElement("canvas"),i=l.getContext("2d");s.onload=()=>{l.width=s.width,l.height=s.height,i.drawImage(s,0,0),l.toBlob(l=>{if(l){const o=e.name,s=o.lastIndexOf("."),i=s>0?o.substring(0,s)+".webp":o+".webp",a=new File([l],i,{type:"image/webp"});a.uid=e.uid,t(a)}else o(new Error("WebP 转换失败"));URL.revokeObjectURL(s.src)},"image/webp",.92)},s.onerror=()=>{URL.revokeObjectURL(s.src),o(new Error(this.$t("uploadForm.imageLoadFailed")))},s.src=URL.createObjectURL(e)})},handleUploadCardMouseMove(e){const t=this.$refs.uploadCardGlow;if(!t)return;const o=e.currentTarget.getBoundingClientRect(),s=e.clientX-o.left,l=e.clientY-o.top;t.style.opacity="1",t.style.left=s+"px",t.style.top=l+"px"},handleUploadCardMouseLeave(){const e=this.$refs.uploadCardGlow;e&&(e.style.opacity="0")}},beforeDestroy(){this.retryTimer&&clearTimeout(this.retryTimer)}};const It=(0,z.A)(Dt,[["render",Ft],["__scopeId","data-v-37f80c81"]]);var Nt=It,Pt=o(732),Vt=o(33892),Wt=o(45130);const zt={class:"directory-suggestion-input",ref:"wrapperRef"},Bt={class:"suggestion-dropdown"},Ht={class:"suggestion-list"},Xt=["title","onMousedown"];function Ot(e,t,o,s,l,n){const r=G.WK;return(0,i.uX)(),(0,i.CE)("div",zt,[(0,i.bF)(r,{ref:"inputRef",modelValue:n.inputValue,"onUpdate:modelValue":t[0]||(t[0]=e=>n.inputValue=e),placeholder:o.placeholder,onFocus:n.handleFocus,onBlur:n.handleBlur,onInput:n.handleInput},null,8,["modelValue","placeholder","onFocus","onBlur","onInput"]),(0,i.bo)((0,i.Lk)("div",Bt,[(0,i.Lk)("ul",Ht,[((0,i.uX)(!0),(0,i.CE)(i.FK,null,(0,i.pI)(l.suggestions,(e,t)=>((0,i.uX)(),(0,i.CE)("li",{key:t,class:"suggestion-item",title:e.value,onMousedown:(0,Wt.D$)(t=>n.selectItem(e),["prevent"])},(0,a.v_)(e.value),41,Xt))),128))])],512),[[Wt.aG,l.dropdownVisible&&l.suggestions.length>0]])],512)}var Qt={name:"DirectorySuggestionInput",props:{modelValue:{type:String,default:""},placeholder:{type:String,default:""}},emits:["update:modelValue","focus","blur","select"],data(){return{directoryTreeRoot:null,directoryTreeLoaded:!1,directoryTreeLoading:!1,directoryChildrenMap:{},focusTime:null,dropdownVisible:!1,isFocused:!1,suggestions:[]}},computed:{inputValue:{get(){return this.modelValue},set(e){this.$emit("update:modelValue",e)}}},watch:{modelValue(){this.isFocused&&this.refreshSuggestions()}},methods:{handleFocus(){this.isFocused=!0,this.focusTime=Date.now(),this.ensureDirectoryTreeLoaded(),this.$emit("focus"),setTimeout(()=>{this.isFocused&&(this.refreshSuggestions(),this.dropdownVisible=!0)},500)},handleBlur(){this.isFocused=!1,this.dropdownVisible=!1,this.$emit("blur")},handleInput(e){this.$nextTick(()=>{this.refreshSuggestions(),this.isFocused&&(this.dropdownVisible=!0)})},selectItem(e){const t=e.value;this.inputValue=t,this.$emit("select",t);const o=this.normalizeDirectoryPath(t),s=this.directoryChildrenMap[o];s&&s.length>0?this.$nextTick(()=>{this.refreshSuggestions(),this.dropdownVisible=!0,this.$refs.inputRef?.focus()}):this.dropdownVisible=!1},refreshSuggestions(){this.suggestions=this.getDirectorySuggestions(this.modelValue||"")},normalizeDirectoryPath(e){if(!e)return"/";let t=e;return t.startsWith("/")||(t="/"+t),"/"===t||t.endsWith("/")||(t+="/"),t},buildDirectoryChildrenMap(e){const t={},o=e=>{const s=this.normalizeDirectoryPath(e.path),l=Array.isArray(e.children)?e.children:[];t[s]=l.map(e=>({name:e.name,path:this.normalizeDirectoryPath(e.path)})),l.forEach(o)};o(e),this.directoryChildrenMap=t},async ensureDirectoryTreeLoaded(){if(!this.directoryTreeLoaded&&!this.directoryTreeLoading){this.directoryTreeLoading=!0;try{const e=await Lt.A.get("/api/directoryTree",{withAuthCode:!0}),t=e?.data?.tree;t&&(this.directoryTreeRoot=t,this.buildDirectoryChildrenMap(t),this.directoryTreeLoaded=!0)}catch(e){console.error("Failed to load directory tree for autocomplete:",e)}finally{this.directoryTreeLoading=!1}}},parseDirectoryQuery(e){const t=e&&e.startsWith("/")?e:`/${e||""}`,o=t.slice(1),s=o.split("/"),l=s[s.length-1]||"",i=s.slice(0,-1).filter(Boolean),a=i.length>0?`/${i.join("/")}/`:"/";return{segmentInput:l,parentPath:a}},getDirectorySuggestions(e){const{segmentInput:t,parentPath:o}=this.parseDirectoryQuery(e),s=this.directoryChildrenMap[o]||[];if(!t)return s.slice(0,10).map(e=>({value:e.path}));const l=t.toLowerCase();return s.filter(e=>e.name.toLowerCase().startsWith(l)).slice(0,10).map(e=>({value:e.path}))}}};const jt=(0,z.A)(Qt,[["render",Ot],["__scopeId","data-v-0ff63416"]]);var qt=jt,Gt=o(6834);const Kt={class:"container"},Jt={class:"upload-home"},Yt={class:"toolbar-manage"},Zt={class:"toolbar"},eo={class:"header"},to={class:"title"},oo={class:"main-title",href:"https://github.com/MarSeventh/CloudFlare-ImgBed",target:"_blank"},so={class:"dialog-section"},lo={class:"section-header"},io={class:"section-title"},ao={class:"section-content"},no={class:"dialog-section"},ro={class:"section-header"},co={class:"section-title"},uo={class:"section-content"},po={class:"setting-item"},ho={class:"setting-label"},mo={key:0,class:"setting-item"},go={class:"setting-label"},fo={class:"dialog-action"},yo=["innerHTML"],bo={class:"dialog-footer"};function vo(e,t,o,n,r,d){const c=Gt.A,u=(0,i.g2)("font-awesome-icon"),p=l.S2,h=ut.c6,m=ut.Iy,g=ut.dW,f=qt,y=G.WK,b=Vt.A,v=s.R7,C=Pt.A,k=Nt,w=J.ll,F=J.MQ,L=q.qi,U=O.kZ,$=We,S=X.A,T=H;return(0,i.uX)(),(0,i.CE)("div",Kt,[(0,i.Lk)("div",Jt,[(0,i.bF)(c,{class:"toggle-dark-button desktop-only"}),(0,i.bF)(g,{class:"more-dropdown desktop-only",trigger:"click",onCommand:d.handleDesktopMenuCommand},{dropdown:(0,i.k6)(()=>[(0,i.bF)(m,null,{default:(0,i.k6)(()=>[(0,i.bF)(h,{command:"showHistory"},{default:(0,i.k6)(()=>[(0,i.bF)(u,{icon:"history",style:{width:"16px","margin-right":"8px","text-align":"center"}}),(0,i.eW)(" "+(0,a.v_)(e.$t("upload.history")),1)]),_:1}),(0,i.bF)(h,{command:"showAnnouncement",disabled:!d.announcementAvailable},{default:(0,i.k6)(()=>[(0,i.bF)(u,{icon:"bullhorn",style:{width:"16px","margin-right":"8px","text-align":"center"}}),(0,i.eW)(" "+(0,a.v_)(e.$t("upload.announcement")),1)]),_:1},8,["disabled"]),(0,i.bF)(h,{command:"toggleLanguage"},{default:(0,i.k6)(()=>[(0,i.bF)(u,{icon:"globe",style:{width:"16px","margin-right":"8px","text-align":"center"}}),(0,i.eW)(" "+(0,a.v_)("zh-CN"===e.$i18n.locale?"English":"简体中文"),1)]),_:1}),(0,i.bF)(h,{command:"viewDocs"},{default:(0,i.k6)(()=>[(0,i.bF)(u,{icon:"book",style:{width:"16px","margin-right":"8px","text-align":"center"}}),(0,i.eW)(" "+(0,a.v_)(e.$t("upload.viewDocs")),1)]),_:1})]),_:1})]),default:(0,i.k6)(()=>[(0,i.bF)(p,{class:"more-button"},{default:(0,i.k6)(()=>[(0,i.bF)(u,{icon:"ellipsis-v",size:"lg"})]),_:1})]),_:1},8,["onCommand"]),(0,i.Lk)("div",{class:(0,a.C4)(["upload-folder-container",{"no-announcement":!d.announcementAvailable}])},[(0,i.Lk)("div",{class:(0,a.C4)(["upload-folder",{active:r.isFolderInputActive}])},[d.showDirectorySuggestions?((0,i.uX)(),(0,i.Wv)(f,{key:0,modelValue:r.uploadFolder,"onUpdate:modelValue":t[0]||(t[0]=e=>r.uploadFolder=e),class:"inner-folder-input",placeholder:e.$t("upload.folderPlaceholder"),onFocus:d.handleFolderInputFocus,onBlur:d.handleFolderInputBlur,onSelect:d.handleDirectorySelect},null,8,["modelValue","placeholder","onFocus","onBlur","onSelect"])):((0,i.uX)(),(0,i.Wv)(y,{key:1,class:"inner-folder-input",modelValue:r.uploadFolder,"onUpdate:modelValue":t[1]||(t[1]=e=>r.uploadFolder=e),placeholder:e.$t("upload.folderPlaceholder"),onFocus:d.handleFolderInputFocus,onBlur:d.handleFolderInputBlur},null,8,["modelValue","placeholder","onFocus","onBlur"]))],2),d.showDirectorySuggestions?((0,i.uX)(),(0,i.Wv)(b,{key:0,"current-directory":r.uploadFolder,source:"upload",onSelect:d.handleDirectorySelect},{trigger:(0,i.k6)(()=>[(0,i.bF)(p,{class:"directory-tree-trigger"},{default:(0,i.k6)(()=>[(0,i.bF)(u,{icon:"folder-tree"})]),_:1})]),_:1},8,["current-directory","onSelect"])):(0,i.Q3)("",!0)],2),(0,i.bF)(v,{content:e.$t("upload.switchUploadMethod"),placement:"bottom",disabled:d.disableTooltip},{default:(0,i.k6)(()=>[(0,i.bF)(p,{class:"upload-method-button desktop-only",onClick:d.handleChangeUploadMethod},{default:(0,i.k6)(()=>["default"===r.uploadMethod?((0,i.uX)(),(0,i.Wv)(u,{key:0,icon:"folder-open",class:"upload-method-icon",size:"lg"})):"paste"===r.uploadMethod?((0,i.uX)(),(0,i.Wv)(u,{key:1,icon:"paste",class:"upload-method-icon",size:"lg"})):(0,i.Q3)("",!0)]),_:1},8,["onClick"])]),_:1},8,["content","disabled"]),(0,i.bF)(g,{class:"mobile-more-dropdown mobile-only",trigger:"click",onCommand:d.handleMobileMenuCommand},{dropdown:(0,i.k6)(()=>[(0,i.bF)(m,null,{default:(0,i.k6)(()=>[(0,i.bF)(h,{command:"toggleTheme"},{default:(0,i.k6)(()=>[(0,i.bF)(u,{icon:d.getThemeIcon(),style:{width:"16px","margin-right":"8px","text-align":"center"}},null,8,["icon"]),(0,i.eW)(" "+(0,a.v_)(d.getThemeText()),1)]),_:1}),(0,i.bF)(h,{command:"toggleUploadMethod"},{default:(0,i.k6)(()=>[(0,i.bF)(u,{icon:"default"===r.uploadMethod?"paste":"folder-open",style:{width:"16px","margin-right":"8px","text-align":"center"}},null,8,["icon"]),(0,i.eW)(" "+(0,a.v_)("default"===r.uploadMethod?e.$t("upload.pasteUpload"):e.$t("upload.fileUpload")),1)]),_:1}),(0,i.bF)(h,{command:"showHistory"},{default:(0,i.k6)(()=>[(0,i.bF)(u,{icon:"history",style:{width:"16px","margin-right":"8px","text-align":"center"}}),(0,i.eW)(" "+(0,a.v_)(e.$t("upload.history")),1)]),_:1}),(0,i.bF)(h,{command:"showAnnouncement",disabled:!d.announcementAvailable},{default:(0,i.k6)(()=>[(0,i.bF)(u,{icon:"bullhorn",style:{width:"16px","margin-right":"8px","text-align":"center"}}),(0,i.eW)(" "+(0,a.v_)(e.$t("upload.announcement")),1)]),_:1},8,["disabled"]),(0,i.bF)(h,{command:"toggleLanguage"},{default:(0,i.k6)(()=>[(0,i.bF)(u,{icon:"globe",style:{width:"16px","margin-right":"8px","text-align":"center"}}),(0,i.eW)(" "+(0,a.v_)("zh-CN"===e.$i18n.locale?"English":"简体中文"),1)]),_:1}),(0,i.bF)(h,{command:"viewDocs"},{default:(0,i.k6)(()=>[(0,i.bF)(u,{icon:"book",style:{width:"16px","margin-right":"8px","text-align":"center"}}),(0,i.eW)(" "+(0,a.v_)(e.$t("upload.viewDocs")),1)]),_:1})]),_:1})]),default:(0,i.k6)(()=>[(0,i.bF)(p,{class:"mobile-more-button"},{default:(0,i.k6)(()=>[(0,i.bF)(u,{icon:"ellipsis-v",size:"lg"})]),_:1})]),_:1},8,["onCommand"]),(0,i.Lk)("div",Yt,[(0,i.bF)(p,{class:(0,a.C4)(["toolbar-manage-button",{active:r.isToolBarOpen}]),size:"large",onClick:d.handleOpenToolbar,circle:""},{default:(0,i.k6)(()=>[r.isToolBarOpen?((0,i.uX)(),(0,i.Wv)(u,{key:1,icon:"times",class:"manage-icon",size:"lg"})):((0,i.uX)(),(0,i.Wv)(u,{key:0,icon:"bars",class:"manage-icon",size:"lg"}))]),_:1},8,["class","onClick"])]),(0,i.Lk)("div",Zt,[(0,i.bF)(v,{disabled:d.disableTooltip,content:e.$t("upload.settings"),placement:"top"},{default:(0,i.k6)(()=>[(0,i.bF)(p,{class:(0,a.C4)(["toolbar-button compress-button",{active:r.isToolBarOpen}]),size:"large",onClick:d.openCompressDialog,circle:""},{default:(0,i.k6)(()=>[(0,i.bF)(u,{icon:"cloud-upload",class:"compress-icon",size:"lg"})]),_:1},8,["class","onClick"])]),_:1},8,["disabled","content"]),(0,i.bF)(v,{disabled:d.disableTooltip,content:e.$t("upload.linkFormat"),placement:"left"},{default:(0,i.k6)(()=>[(0,i.bF)(p,{class:(0,a.C4)(["toolbar-button link-button",{active:r.isToolBarOpen}]),size:"large",onClick:d.openUrlDialog,circle:""},{default:(0,i.k6)(()=>[(0,i.bF)(u,{icon:"link",class:"link-icon",size:"lg"})]),_:1},8,["class","onClick"])]),_:1},8,["disabled","content"]),(0,i.bF)(v,{disabled:d.disableTooltip,content:e.$t("upload.manage"),placement:"left"},{default:(0,i.k6)(()=>[(0,i.bF)(p,{class:(0,a.C4)(["toolbar-button config-button",{active:r.isToolBarOpen}]),size:"large",onClick:d.handleManage,circle:""},{default:(0,i.k6)(()=>[(0,i.bF)(u,{icon:"cog",class:"config-icon",size:"lg"})]),_:1},8,["class","onClick"])]),_:1},8,["disabled","content"]),(0,i.bF)(v,{disabled:d.disableTooltip,content:e.$t("upload.logout"),placement:"left"},{default:(0,i.k6)(()=>[(0,i.bF)(p,{class:(0,a.C4)(["toolbar-button sign-out-button",{active:r.isToolBarOpen}]),size:"large",onClick:d.handleLogout,circle:""},{default:(0,i.k6)(()=>[(0,i.bF)(u,{icon:"sign-out-alt",class:"sign-out-icon",size:"lg"})]),_:1},8,["class","onClick"])]),_:1},8,["disabled","content"])]),(0,i.bF)(C,{useConfigLink:!0}),(0,i.Lk)("div",eo,[(0,i.Lk)("h1",to,[(0,i.Lk)("a",oo,(0,a.v_)(d.ownerName),1),t[21]||(t[21]=(0,i.eW)(" ImgHub",-1))])]),(0,i.bF)(k,{selectedUrlForm:r.selectedUrlForm,customerCompress:r.customerCompress,compressQuality:r.compressQuality,compressBar:r.compressBar,serverCompress:r.serverCompress,uploadChannel:r.uploadChannel,channelName:r.channelName,uploadNameType:r.uploadNameType,useCustomUrl:r.useCustomUrl,customUrlPrefix:r.customUrlPrefix,autoRetry:r.autoRetry,urlPrefix:d.urlPrefix,uploadMethod:r.uploadMethod,uploadFolder:r.uploadFolder,convertToWebp:r.convertToWebp,class:"upload"},null,8,["selectedUrlForm","customerCompress","compressQuality","compressBar","serverCompress","uploadChannel","channelName","uploadNameType","useCustomUrl","customUrlPrefix","autoRetry","urlPrefix","uploadMethod","uploadFolder","convertToWebp"]),(0,i.bF)(U,{title:e.$t("settings.linkFormatTitle"),modelValue:r.showUrlDialog,"onUpdate:modelValue":t[6]||(t[6]=e=>r.showUrlDialog=e),width:d.dialogWidth,"show-close":!1,class:"settings-dialog"},{default:(0,i.k6)(()=>[(0,i.Lk)("div",so,[(0,i.Lk)("div",lo,[(0,i.Lk)("span",io,(0,a.v_)(e.$t("settings.defaultCopyLink")),1)]),(0,i.Lk)("div",ao,[(0,i.bF)(F,{modelValue:r.selectedUrlForm,"onUpdate:modelValue":t[2]||(t[2]=e=>r.selectedUrlForm=e),onChange:d.changeUrlForm,class:"radio-card-group grid-2x2"},{default:(0,i.k6)(()=>[(0,i.bF)(w,{value:"url",class:"radio-card"},{default:(0,i.k6)(()=>[(0,i.bF)(u,{icon:"link",class:"radio-icon"}),(0,i.Lk)("span",null,(0,a.v_)(e.$t("settings.rawLink")),1)]),_:1}),(0,i.bF)(w,{value:"md",class:"radio-card"},{default:(0,i.k6)(()=>[(0,i.bF)(u,{icon:"code",class:"radio-icon"}),t[22]||(t[22]=(0,i.Lk)("span",null,"MarkDown",-1))]),_:1}),(0,i.bF)(w,{value:"html",class:"radio-card"},{default:(0,i.k6)(()=>[(0,i.bF)(u,{icon:"code-branch",class:"radio-icon"}),t[23]||(t[23]=(0,i.Lk)("span",null,"HTML",-1))]),_:1}),(0,i.bF)(w,{value:"ubb",class:"radio-card"},{default:(0,i.k6)(()=>[(0,i.bF)(u,{icon:"quote-right",class:"radio-icon"}),t[24]||(t[24]=(0,i.Lk)("span",null,"BBCode",-1))]),_:1})]),_:1},8,["modelValue","onChange"])])]),(0,i.Lk)("div",no,[(0,i.Lk)("div",ro,[(0,i.Lk)("span",co,(0,a.v_)(e.$t("settings.customLink")),1),(0,i.bF)(v,{content:e.$t("settings.customLinkTooltip"),placement:"top","raw-content":""},{default:(0,i.k6)(()=>[(0,i.bF)(u,{icon:"question-circle",class:"section-help-icon"})]),_:1},8,["content"])]),(0,i.Lk)("div",uo,[(0,i.Lk)("div",po,[(0,i.Lk)("span",ho,(0,a.v_)(e.$t("settings.enableCustom")),1),(0,i.bF)(L,{modelValue:r.useCustomUrl,"onUpdate:modelValue":t[3]||(t[3]=e=>r.useCustomUrl=e),"active-value":"true","inactive-value":"false"},null,8,["modelValue"])]),"true"===r.useCustomUrl?((0,i.uX)(),(0,i.CE)("div",mo,[(0,i.Lk)("span",go,(0,a.v_)(e.$t("settings.customPrefix")),1),(0,i.bF)(y,{modelValue:r.customUrlPrefix,"onUpdate:modelValue":t[4]||(t[4]=e=>r.customUrlPrefix=e),placeholder:e.$t("settings.customPrefixPlaceholder"),class:"setting-input"},null,8,["modelValue","placeholder"])])):(0,i.Q3)("",!0)])]),(0,i.Lk)("div",fo,[(0,i.bF)(p,{type:"primary",onClick:t[5]||(t[5]=e=>r.showUrlDialog=!1),class:"confirm-btn"},{default:(0,i.k6)(()=>[(0,i.eW)((0,a.v_)(e.$t("settings.confirm")),1)]),_:1})])]),_:1},8,["title","modelValue","width"]),(0,i.bF)($,{modelValue:r.showCompressDialog,"onUpdate:modelValue":t[7]||(t[7]=e=>r.showCompressDialog=e),uploadChannel:r.uploadChannel,"onUpdate:uploadChannel":t[8]||(t[8]=e=>r.uploadChannel=e),channelName:r.channelName,"onUpdate:channelName":t[9]||(t[9]=e=>r.channelName=e),currentChannelList:d.currentChannelList,uploadFolder:r.uploadFolder,"onUpdate:uploadFolder":t[10]||(t[10]=e=>r.uploadFolder=e),autoRetry:r.autoRetry,"onUpdate:autoRetry":t[11]||(t[11]=e=>r.autoRetry=e),uploadNameType:r.uploadNameType,"onUpdate:uploadNameType":t[12]||(t[12]=e=>r.uploadNameType=e),convertToWebp:r.convertToWebp,"onUpdate:convertToWebp":t[13]||(t[13]=e=>r.convertToWebp=e),customerCompress:r.customerCompress,"onUpdate:customerCompress":t[14]||(t[14]=e=>r.customerCompress=e),compressBar:r.compressBar,"onUpdate:compressBar":t[15]||(t[15]=e=>r.compressBar=e),compressQuality:r.compressQuality,"onUpdate:compressQuality":t[16]||(t[16]=e=>r.compressQuality=e),serverCompress:r.serverCompress,"onUpdate:serverCompress":t[17]||(t[17]=e=>r.serverCompress=e)},null,8,["modelValue","uploadChannel","channelName","currentChannelList","uploadFolder","autoRetry","uploadNameType","convertToWebp","customerCompress","compressBar","compressQuality","serverCompress"])]),(0,i.bF)(S,{class:"footer"}),(0,i.bF)(U,{title:e.$t("upload.announcementTitle"),modelValue:r.showAnnouncementDialog,"onUpdate:modelValue":t[19]||(t[19]=e=>r.showAnnouncementDialog=e),width:d.dialogWidth,"show-close":!1,"close-on-click-modal":!1,"close-on-press-escape":!1,center:""},{footer:(0,i.k6)(()=>[(0,i.Lk)("span",bo,[(0,i.bF)(p,{type:"primary",onClick:t[18]||(t[18]=e=>r.showAnnouncementDialog=!1)},{default:(0,i.k6)(()=>[(0,i.eW)((0,a.v_)(e.$t("upload.announcementAck")),1)]),_:1})])]),default:(0,i.k6)(()=>[(0,i.Lk)("div",{innerHTML:r.announcementContent},null,8,yo)]),_:1},8,["title","modelValue","width"]),(0,i.bF)(T,{show:r.showHistory,onClose:t[20]||(t[20]=e=>r.showHistory=!1)},null,8,["show"])])}o(13579);var Co=o(46638),ko=o(48903),wo=o(90144),Fo=o(62388),Lo={name:"UploadHome",mixins:[ko.A],data(){return{selectedUrlForm:(0,wo.KR)(""),showUrlDialog:!1,showCompressDialog:!1,customerCompress:!0,compressQuality:4,compressBar:5,convertToWebp:!1,serverCompress:!0,uploadChannel:"",channelName:"",availableChannels:{},uploadNameType:"",customUrlPrefix:"",useCustomUrl:"false",autoRetry:!0,useDefaultWallPaper:!1,isToolBarOpen:!1,uploadMethod:"default",uploadFolder:"",isFolderInputActive:!1,showAnnouncementDialog:!1,announcementContent:"",showHistory:!1,themeMode:"auto"}},watch:{customerCompress(e){this.updateCompressConfig("customerCompress",e)},compressQuality(e){this.updateCompressConfig("compressQuality",e)},compressBar(e){null===e||void 0===e||e<1?this.compressBar=1:(this.compressQuality>e&&(this.compressQuality=e),this.updateCompressConfig("compressBar",e))},serverCompress(e){this.updateCompressConfig("serverCompress",e)},convertToWebp(e){this.updateCompressConfig("convertToWebp",e)},uploadChannel(e){this.updateStoreUploadChannel(e);const t=this.availableChannels[e]||[],o=this.storeChannelName;o&&t.some(e=>e.name===o)?this.channelName=o:this.channelName=""},channelName(e){this.$store.commit("setStoreChannelName",e||"")},uploadNameType(e){this.updateStoreUploadNameType(e)},customUrlPrefix(e){this.$store.commit("setCustomUrlSettings",{key:"customUrlPrefix",value:e})},useCustomUrl(e){this.$store.commit("setCustomUrlSettings",{key:"useCustomUrl",value:e})},autoRetry(e){this.$store.commit("setStoreAutoRetry",e)},uploadFolder(e){if(this.validateUploadFolder(e,!1)){const t=(0,Fo.G)(e,{strict:!0});t.valid&&this.$store.commit("setStoreUploadFolder",e)}else this.$nextTick(()=>{this.uploadFolder=this.storeUploadFolder})}},computed:{...(0,$t.L8)(["userConfig","uploadCopyUrlForm","compressConfig","storeUploadChannel","storeChannelName","storeUploadNameType","customUrlSettings","storeAutoRetry","storeUploadMethod","storeUploadFolder"]),ownerName(){return this.userConfig?.ownerName||"Sanyue"},dialogWidth(){return window.innerWidth>768?"50%":"90%"},disableTooltip(){return window.innerWidth<768},urlPrefix(){return this.userConfig?.urlPrefix||`${window.location.protocol}//${window.location.host}/file/`},announcementAvailable(){return!!this.userConfig?.announcement},showDirectorySuggestions(){return this.userConfig?.showDirectorySuggestions??!1},currentChannelList(){return this.availableChannels[this.uploadChannel]||[]}},mounted(){this.initializeBackground("uploadBkImg",".container",!1,!0),this.selectedUrlForm=this.uploadCopyUrlForm||"url",this.customerCompress=this.compressConfig.customerCompress??this.parseBoolean(this.userConfig?.defaultCustomerCompress,!0),this.compressQuality=this.compressConfig.compressQuality??this.parseNumber(this.userConfig?.defaultCompressQuality,4),this.compressBar=this.compressConfig.compressBar??this.parseNumber(this.userConfig?.defaultCompressBar,5),this.serverCompress=this.compressConfig.serverCompress??!0,this.convertToWebp=this.compressConfig.convertToWebp??this.parseBoolean(this.userConfig?.defaultConvertToWebp,!1),this.uploadChannel=this.storeUploadChannel||this.userConfig?.defaultUploadChannel||"telegram",this.autoRetry=this.storeAutoRetry,this.uploadNameType=this.storeUploadNameType||this.userConfig?.defaultUploadNameType||"default",this.customUrlPrefix=this.customUrlSettings.customUrlPrefix,this.useCustomUrl=this.customUrlSettings.useCustomUrl,this.uploadMethod=this.storeUploadMethod,this.fetchAvailableChannels(),this.uploadFolder=this.storeUploadFolder||this.userConfig?.defaultUploadFolder||"";const e=this.$store.getters.cusDarkMode,t=this.$store.getters.useDarkMode;this.themeMode=e?t?"dark":"light":"auto";const o=localStorage.getItem("visitedUploadHome"),s=this.userConfig?.announcement;!o&&s&&(this.announcementContent=s,this.showAnnouncementDialog=!0,localStorage.setItem("visitedUploadHome","true"))},components:{UploadForm:Nt,Footer:X.A,ToggleDark:Gt.A,Logo:Pt.A,UploadHistory:H,UploadSettingsDialog:We,DirectoryTreePicker:Vt.A,DirectorySuggestionInput:qt},methods:{async fetchAvailableChannels(){try{const e=await Lt.A.get("/api/channels",{withAuthCode:!0});if(e.data){this.availableChannels=e.data;const t=this.storeChannelName,o=this.userConfig?.defaultChannelName,s=this.availableChannels[this.uploadChannel]||[];t&&s.some(e=>e.name===t)?this.channelName=t:""!==t&&null!==t&&void 0!==t||""!==t&&o&&s.some(e=>e.name===o)&&(this.channelName=o)}}catch(e){console.error("Failed to fetch available channels:",e)}},validateUploadFolder(e,t=!0){e&&!e.startsWith("/")&&(e="/"+e,this.uploadFolder=e);const o=(0,Fo.G)(e,{strict:t});return!!o.valid||(this.$message.error(o.error),!1)},handleFolderInputFocus(){this.isFolderInputActive=!0},handleFolderInputBlur(){this.isFolderInputActive=!1,this.uploadFolder&&!this.uploadFolder.startsWith("/")&&(this.uploadFolder="/"+this.uploadFolder),this.validateUploadFolder(this.uploadFolder,!0)||this.$nextTick(()=>{this.uploadFolder=this.storeUploadFolder})},handleManage(){this.$router.push("/dashboard")},parseBoolean(e,t){return void 0===e||null===e?t:"boolean"===typeof e?e:"string"===typeof e?"true"===e:t},parseNumber(e,t){if(void 0===e||null===e)return t;const o=parseFloat(e);return isNaN(o)?t:o},openUrlDialog(){this.showUrlDialog=!0},handleLogout(){Lt.A.post("/api/auth/logout",{authType:"user"},{withCredentials:!0}).finally(()=>{this.$store.commit("setUserLoggedIn",!1),this.$router.push("/login"),this.$message.success(this.$t("upload.logoutSuccess"))})},changeUrlForm(){this.$store.commit("setUploadCopyUrlForm",this.selectedUrlForm)},openCompressDialog(){this.showCompressDialog=!0},updateCompressConfig(e,t){this.$store.commit("setCompressConfig",{key:e,value:t})},updateStoreUploadChannel(e){this.$store.commit("setStoreUploadChannel",e)},updateStoreUploadNameType(e){this.$store.commit("setStoreUploadNameType",e)},handleOpenToolbar(){this.isToolBarOpen=!this.isToolBarOpen,setTimeout(()=>{const e=document.querySelectorAll(".toolbar-button");e.forEach(e=>{e.style.pointerEvents=this.isToolBarOpen?"auto":"none"})},300)},handleChangeUploadMethod(){this.uploadMethod="default"===this.uploadMethod?"paste":"default",this.$store.commit("setUploadMethod",this.uploadMethod)},handleMobileMenuCommand(e){if("toggleTheme"===e)"auto"===this.themeMode?(this.themeMode="light",this.$store.commit("setCusDarkMode",!0),this.$store.commit("setUseDarkMode",!1)):"light"===this.themeMode?(this.themeMode="dark",this.$store.commit("setCusDarkMode",!0),this.$store.commit("setUseDarkMode",!0)):(this.themeMode="auto",this.$store.commit("setCusDarkMode",!1));else if("toggleUploadMethod"===e)this.handleChangeUploadMethod();else if("viewDocs"===e)window.open("https://cfbed.sanyue.de/qa/","_blank");else if("showHistory"===e)this.showHistory=!0;else if("showAnnouncement"===e)this.handleShowAnnouncement();else if("toggleLanguage"===e){const e="zh-CN"===this.$i18n.locale?"en":"zh-CN";(0,Co.xS)(e)}},handleDesktopMenuCommand(e){if("viewDocs"===e)window.open("https://cfbed.sanyue.de/qa/","_blank");else if("showHistory"===e)this.showHistory=!0;else if("showAnnouncement"===e)this.handleShowAnnouncement();else if("toggleLanguage"===e){const e="zh-CN"===this.$i18n.locale?"en":"zh-CN";(0,Co.xS)(e)}},getThemeIcon(){return"auto"===this.themeMode?"sun":"light"===this.themeMode?"moon":"adjust"},getThemeText(){return"auto"===this.themeMode?this.$t("theme.lightMode"):"light"===this.themeMode?this.$t("theme.darkMode"):this.$t("theme.autoMode")},handleShowAnnouncement(){const e=this.userConfig?.announcement;e?(this.announcementContent=e,this.showAnnouncementDialog=!0):this.$message.info(this.$t("upload.noAnnouncement"))},handleDirectorySelect(e){this.uploadFolder=e,this.validateUploadFolder(e,!0)&&this.$store.commit("setStoreUploadFolder",e)}}};const Uo=(0,z.A)(Lo,[["render",vo],["__scopeId","data-v-f50dcc42"]]);var $o=Uo}}]); +(self["webpackChunksanyue_imghub"]=self["webpackChunksanyue_imghub"]||[]).push([[577],{213:function(e,t,o){"use strict";o(85331),o(19104)},2893:function(e,t,o){"use strict";o(85331)},4885:function(e,t,o){"use strict";o(85331)},10456:function(e,t,o){"use strict";o(85331)},11393:function(e,t,o){o(16573),o(78100),o(77936),o(79577),o(41549),o(49797),o(49631),o(35623),o(64979),o(14603),o(47566),o(98721),function(t,o){e.exports=o()}(0,function(){return function(e){var t={};function o(s){if(t[s])return t[s].exports;var l=t[s]={i:s,l:!1,exports:{}};return e[s].call(l.exports,l,l.exports,o),l.l=!0,l.exports}return o.m=e,o.c=t,o.d=function(e,t,s){o.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:s})},o.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},o.t=function(e,t){if(1&t&&(e=o(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var s=Object.create(null);if(o.r(s),Object.defineProperty(s,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var l in e)o.d(s,l,function(t){return e[t]}.bind(null,l));return s},o.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return o.d(t,"a",t),t},o.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},o.p="",o(o.s=0)}([function(e,t,o){"use strict";var s;function l(e){return["image/png","image/jpeg","image/gif"].some(t=>t===e)}o.r(t),o.d(t,"canvastoDataURL",function(){return a}),o.d(t,"canvastoFile",function(){return n}),o.d(t,"dataURLtoFile",function(){return d}),o.d(t,"dataURLtoImage",function(){return c}),o.d(t,"downloadFile",function(){return u}),o.d(t,"filetoDataURL",function(){return p}),o.d(t,"imagetoCanvas",function(){return m}),o.d(t,"urltoBlob",function(){return g}),o.d(t,"urltoImage",function(){return f}),o.d(t,"compress",function(){return b}),o.d(t,"compressAccurately",function(){return v}),o.d(t,"EImageType",function(){return s}),function(e){e.PNG="image/png",e.JPEG="image/jpeg",e.GIF="image/gif"}(s||(s={}));var i=function(e,t,o,s){return new(o||(o=Promise))(function(l,i){function a(e){try{r(s.next(e))}catch(e){i(e)}}function n(e){try{r(s.throw(e))}catch(e){i(e)}}function r(e){var t;e.done?l(e.value):(t=e.value,t instanceof o?t:new o(function(e){e(t)})).then(a,n)}r((s=s.apply(e,t||[])).next())})};function a(e,t=.92,o=s.JPEG){return i(this,void 0,void 0,function*(){return l(o)||(o=s.JPEG),e.toDataURL(o,t)})}function n(e,t=.92,o=s.JPEG){return new Promise(s=>e.toBlob(e=>s(e),o,t))}var r=function(e,t,o,s){return new(o||(o=Promise))(function(l,i){function a(e){try{r(s.next(e))}catch(e){i(e)}}function n(e){try{r(s.throw(e))}catch(e){i(e)}}function r(e){var t;e.done?l(e.value):(t=e.value,t instanceof o?t:new o(function(e){e(t)})).then(a,n)}r((s=s.apply(e,t||[])).next())})};function d(e,t){return r(this,void 0,void 0,function*(){const o=e.split(",");let s=o[0].match(/:(.*?);/)[1];const i=atob(o[1]);let a=i.length;const n=new Uint8Array(a);for(;a--;)n[a]=i.charCodeAt(a);return l(t)&&(s=t),new Blob([n],{type:s})})}function c(e){return new Promise((t,o)=>{const s=new Image;s.onload=()=>t(s),s.onerror=()=>o(new Error("dataURLtoImage(): dataURL is illegal")),s.src=e})}function u(e,t){const o=document.createElement("a");o.href=window.URL.createObjectURL(e),o.download=t||Date.now().toString(36),document.body.appendChild(o);const s=document.createEvent("MouseEvents");s.initEvent("click",!1,!1),o.dispatchEvent(s),document.body.removeChild(o)}function p(e){return new Promise(t=>{const o=new FileReader;o.onloadend=e=>t(e.target.result),o.readAsDataURL(e)})}var h=function(e,t,o,s){return new(o||(o=Promise))(function(l,i){function a(e){try{r(s.next(e))}catch(e){i(e)}}function n(e){try{r(s.throw(e))}catch(e){i(e)}}function r(e){var t;e.done?l(e.value):(t=e.value,t instanceof o?t:new o(function(e){e(t)})).then(a,n)}r((s=s.apply(e,t||[])).next())})};function m(e,t={}){return h(this,void 0,void 0,function*(){const o=Object.assign({},t),s=document.createElement("canvas"),l=s.getContext("2d");let i,a;for(const e in o)Object.prototype.hasOwnProperty.call(o,e)&&(o[e]=Number(o[e]));if(o.scale){const t=o.scale>0&&o.scale<10?o.scale:1;a=e.width*t,i=e.height*t}else a=o.width||o.height*e.width/e.height||e.width,i=o.height||o.width*e.height/e.width||e.height;switch([5,6,7,8].some(e=>e===o.orientation)?(s.height=a,s.width=i):(s.height=i,s.width=a),o.orientation){case 3:l.rotate(180*Math.PI/180),l.drawImage(e,-s.width,-s.height,s.width,s.height);break;case 6:l.rotate(90*Math.PI/180),l.drawImage(e,0,-s.width,s.height,s.width);break;case 8:l.rotate(270*Math.PI/180),l.drawImage(e,-s.height,0,s.height,s.width);break;case 2:l.translate(s.width,0),l.scale(-1,1),l.drawImage(e,0,0,s.width,s.height);break;case 4:l.translate(s.width,0),l.scale(-1,1),l.rotate(180*Math.PI/180),l.drawImage(e,-s.width,-s.height,s.width,s.height);break;case 5:l.translate(s.width,0),l.scale(-1,1),l.rotate(90*Math.PI/180),l.drawImage(e,0,-s.width,s.height,s.width);break;case 7:l.translate(s.width,0),l.scale(-1,1),l.rotate(270*Math.PI/180),l.drawImage(e,-s.height,0,s.height,s.width);break;default:l.drawImage(e,0,0,s.width,s.height)}return s})}function g(e){return fetch(e).then(e=>e.blob())}function f(e){return new Promise((t,o)=>{const s=new Image;s.onload=()=>t(s),s.onerror=()=>o(new Error("urltoImage(): Image failed to load, please check the image URL")),s.src=e})}var y=function(e,t,o,s){return new(o||(o=Promise))(function(l,i){function a(e){try{r(s.next(e))}catch(e){i(e)}}function n(e){try{r(s.throw(e))}catch(e){i(e)}}function r(e){var t;e.done?l(e.value):(t=e.value,t instanceof o?t:new o(function(e){e(t)})).then(a,n)}r((s=s.apply(e,t||[])).next())})};function b(e,t={}){return y(this,void 0,void 0,function*(){if(!(e instanceof Blob))throw new Error("compress(): First arg must be a Blob object or a File object.");if("object"!=typeof t&&(t=Object.assign({quality:t})),t.quality=Number(t.quality),Number.isNaN(t.quality))return e;const o=yield p(e);let i=o.split(",")[0].match(/:(.*?);/)[1],n=s.JPEG;l(t.type)&&(n=t.type,i=t.type);const r=yield c(o),u=yield m(r,Object.assign({},t)),h=yield a(u,t.quality,n),g=yield d(h,i);return g.size>e.size?e:g})}function v(e,t={}){return y(this,void 0,void 0,function*(){if(!(e instanceof Blob))throw new Error("compressAccurately(): First arg must be a Blob object or a File object.");if("object"!=typeof t&&(t=Object.assign({size:t})),t.size=Number(t.size),Number.isNaN(t.size))return e;if(1024*t.size>e.size)return e;t.accuracy=Number(t.accuracy),(!t.accuracy||t.accuracy<.8||t.accuracy>.99)&&(t.accuracy=.95);const o=t.size*(2-t.accuracy)*1024,i=1024*t.size,n=t.size*t.accuracy*1024,r=yield p(e);let u=r.split(",")[0].match(/:(.*?);/)[1],h=s.JPEG;l(t.type)&&(h=t.type,u=t.type);const g=yield c(r),f=yield m(g,Object.assign({},t));let y,b=.5;const v=[null,null];for(let e=1;e<=7;e++){y=yield a(f,b,h);const t=.75*y.length;if(7===e){(ot)&&(y=[y,...v].filter(e=>e).sort((e,t)=>Math.abs(.75*e.length-i)-Math.abs(.75*t.length-i))[0]);break}if(ot))break;v[0]=y,b+=Math.pow(.5,e+1)}}const C=yield d(y,u);return C.size>e.size?e:C})}}])})},13378:function(e,t,o){"use strict";o(85331),o(38736),o(79899)},15616:function(e,t,o){"use strict";o(85331),o(97197)},18785:function(e,t,o){"use strict";o(85331)},19104:function(e,t,o){"use strict";o(85331)},23597:function(e,t,o){"use strict";o(85331)},30694:function(e,t,o){"use strict";o(85331)},33892:function(e,t,o){"use strict";o.d(t,{A:function(){return $}});var s=o(99114),l=(o(85331),o(30694),o(49385)),i=(o(37952),o(30650)),a=(o(19104),o(31802)),n=(o(13378),o(80047)),r=(o(99648),o(56768)),d=o(45130),c=o(24232);const u={class:"directory-tree-picker"},p={class:"tree-container"},h={key:0,class:"error-state"},m={class:"error-text"},g={class:"node-label"},f={class:"tree-container"},y={key:0,class:"error-state"},b={class:"error-text"},v={class:"node-label"};function C(e,t,o,C,k,w){const F=(0,r.g2)("font-awesome-icon"),L=n.S2,U=a.qk,$=i.Vc,S=l.pw,T=s.A;return(0,r.uX)(),(0,r.CE)("div",u,[w.isDesktop?((0,r.uX)(),(0,r.Wv)($,{key:0,visible:k.popoverVisible,"onUpdate:visible":t[1]||(t[1]=e=>k.popoverVisible=e),placement:"bottom-start",width:320,trigger:"click","popper-class":"directory-tree-popover","show-arrow":!0,"hide-after":0,"show-after":50,transition:"el-zoom-in-top"},{reference:(0,r.k6)(()=>[(0,r.Lk)("span",{class:"popover-trigger-wrapper",onClick:t[0]||(t[0]=(0,d.D$)(()=>{},["stop"]))},[(0,r.RG)(e.$slots,"trigger",{},void 0,!0)])]),default:(0,r.k6)(()=>[(0,r.bo)(((0,r.uX)(),(0,r.CE)("div",p,[k.error?((0,r.uX)(),(0,r.CE)("div",h,[(0,r.bF)(F,{icon:"exclamation-circle",class:"error-icon"}),(0,r.Lk)("span",m,(0,c.v_)(k.error),1),(0,r.bF)(L,{type:"primary",size:"small",onClick:w.fetchDirectoryTree},{default:(0,r.k6)(()=>[(0,r.eW)((0,c.v_)(e.$t("directoryTree.retry")),1)]),_:1},8,["onClick"])])):((0,r.uX)(),(0,r.Wv)(U,{key:1,ref:"treeRef",data:k.treeData,props:k.treeProps,"node-key":"path","default-expand-all":!1,"expand-on-click-node":!1,"highlight-current":!0,"current-node-key":o.currentDirectory,class:"directory-tree",onNodeClick:w.handleNodeClick},{default:(0,r.k6)(({node:e,data:t})=>[(0,r.Lk)("span",{class:(0,c.C4)(["tree-node",{"is-current":t.path===o.currentDirectory}])},[(0,r.bF)(F,{icon:e.expanded?"folder-open":"folder",class:"folder-icon"},null,8,["icon"]),(0,r.Lk)("span",g,(0,c.v_)(t.name),1)],2)]),_:1},8,["data","props","current-node-key","onNodeClick"]))])),[[T,k.loading]])]),_:3},8,["visible"])):((0,r.uX)(),(0,r.CE)(r.FK,{key:1},[(0,r.Lk)("span",{class:"drawer-trigger-wrapper",onClick:t[2]||(t[2]=(...e)=>w.openDrawer&&w.openDrawer(...e))},[(0,r.RG)(e.$slots,"trigger",{},void 0,!0)]),(0,r.bF)(S,{modelValue:k.drawerVisible,"onUpdate:modelValue":t[3]||(t[3]=e=>k.drawerVisible=e),direction:"btt",size:"60%","show-close":!0,"with-header":!0,"z-index":3e3,title:e.$t("directoryTree.selectDirectory"),class:"directory-tree-drawer"},{default:(0,r.k6)(()=>[(0,r.bo)(((0,r.uX)(),(0,r.CE)("div",f,[k.error?((0,r.uX)(),(0,r.CE)("div",y,[(0,r.bF)(F,{icon:"exclamation-circle",class:"error-icon"}),(0,r.Lk)("span",b,(0,c.v_)(k.error),1),(0,r.bF)(L,{type:"primary",size:"small",onClick:w.fetchDirectoryTree},{default:(0,r.k6)(()=>[(0,r.eW)((0,c.v_)(e.$t("directoryTree.retry")),1)]),_:1},8,["onClick"])])):((0,r.uX)(),(0,r.Wv)(U,{key:1,ref:"treeRefMobile",data:k.treeData,props:k.treeProps,"node-key":"path","default-expand-all":!1,"expand-on-click-node":!1,"highlight-current":!0,"current-node-key":o.currentDirectory,class:"directory-tree mobile-tree",onNodeClick:w.handleNodeClick},{default:(0,r.k6)(({node:e,data:t})=>[(0,r.Lk)("span",{class:(0,c.C4)(["tree-node",{"is-current":t.path===o.currentDirectory}])},[(0,r.bF)(F,{icon:e.expanded?"folder-open":"folder",class:"folder-icon"},null,8,["icon"]),(0,r.Lk)("span",v,(0,c.v_)(t.name),1)],2)]),_:1},8,["data","props","current-node-key","onNodeClick"]))])),[[T,k.loading]])]),_:1},8,["modelValue","title"])],64))])}var k=o(457),w=o(70797),F={name:"DirectoryTreePicker",props:{currentDirectory:{type:String,default:""},source:{type:String,default:"upload",validator:e=>["upload","admin"].includes(e)}},data(){return{popoverVisible:!1,drawerVisible:!1,treeData:[],loading:!1,error:"",treeProps:{children:"children",label:"name"},windowWidth:window.innerWidth}},computed:{isDesktop(){return this.windowWidth>=769}},watch:{popoverVisible(e){e?this.fetchDirectoryTree():setTimeout(()=>{if(!this.popoverVisible&&this.$refs.treeRef){const e=this.$refs.treeRef.store;for(const t in e.nodesMap)e.nodesMap[t].expanded=!1}},200)},drawerVisible(e){e?this.fetchDirectoryTree():setTimeout(()=>{if(!this.drawerVisible&&this.$refs.treeRefMobile){const e=this.$refs.treeRefMobile.store;for(const t in e.nodesMap)e.nodesMap[t].expanded=!1}},300)},currentDirectory(e){this.$nextTick(()=>{this.$refs.treeRef&&e&&this.$refs.treeRef.setCurrentKey(e),this.$refs.treeRefMobile&&e&&this.$refs.treeRefMobile.setCurrentKey(e)})}},mounted(){window.addEventListener("resize",this.handleResize)},beforeUnmount(){window.removeEventListener("resize",this.handleResize)},methods:{handleResize(){this.windowWidth=window.innerWidth},openDrawer(){this.drawerVisible=!0},async fetchDirectoryTree(){this.loading=!0,this.error="";try{let e;if("admin"===this.source){const t=await(0,w.A)("/api/directoryTree",{method:"GET"});if(!t.ok)return void(401===t.status?this.error=this.$t("directoryTree.authFailed"):this.error=this.$t("directoryTree.serverError"));e=await t.json()}else{const t=await k.A.get("/api/directoryTree",{withAuthCode:!0});e=t.data}e.tree?this.treeData=[e.tree]:this.treeData=[]}catch(e){console.error("Failed to fetch directory tree:",e),401===e.response?.status?this.error=this.$t("directoryTree.authFailed"):this.error=this.$t("directoryTree.loadFailed")}finally{this.loading=!1}},handleNodeClick(e){let t=e.path;t&&!t.startsWith("/")?t="/"+t:t||(t="/"),this.$emit("select",t),this.popoverVisible=!1,this.drawerVisible=!1}}},L=o(71241);const U=(0,L.A)(F,[["render",C],["__scopeId","data-v-62eab69a"]]);var $=U},34396:function(e,t,o){"use strict";o(85331),o(4885)},37952:function(e,t,o){"use strict";o(85331),o(97197)},38736:function(e,t,o){"use strict";o(85331)},40670:function(e,t,o){"use strict";o(85331),o(99648),o(19104),o(85970)},50333:function(e,t,o){"use strict";o(85331),o(29092)},62388:function(e,t,o){"use strict";o.d(t,{G:function(){return l}});var s=o(46638);function l(e,{strict:t=!0}={}){if(!e||""===e.trim())return{valid:!0};if("/"===e)return{valid:!0};if(!e.startsWith("/"))return{valid:!1,error:s.Ay.global.t("validation.pathMustStartWithSlash")};if(/(?:^|\/)\.\.(\/|$)/.test(e)||e.includes(".."))return{valid:!1,error:s.Ay.global.t("validation.pathTraversalNotAllowed")};const o=t?/\/\.(\/|$)/:/\/\.\//;if(o.test(e))return{valid:!1,error:s.Ay.global.t("validation.singleDotNotAllowed")};if(e.includes("//"))return{valid:!1,error:s.Ay.global.t("validation.consecutiveSlashNotAllowed")};const l=/[\\:\*\?"'<>\| \(\)\[\]\{\}#%\^`~;@&=\+\$,]/;return l.test(e)?{valid:!1,error:s.Ay.global.t("validation.invalidCharacters")}:{valid:!0}}},67819:function(e,t,o){"use strict";o(85331)},70797:function(e,t,o){"use strict";o.d(t,{A:function(){return a}});o(44114);var s=o(25507),l=o(16915);let i=!1;async function a(e,t={}){t.credentials="include",t.headers={...t.headers};const o=await fetch(e,t);return 401!==o.status||i||(i=!0,s.A.commit("setAdminLoggedIn",!1),l.A.push("/adminLogin").finally(()=>{i=!1})),o}},76334:function(e,t,o){e.exports=o(11393)},79899:function(e,t,o){"use strict";o(85331)},85970:function(e,t,o){"use strict";o(85331)},88830:function(e,t,o){"use strict";o(85331)},95385:function(e,t,o){"use strict";o(85331)},96682:function(e,t,o){"use strict";e.exports=o.p+"img/404.8ed11fb3.png"},96808:function(e,t,o){"use strict";o(85331),o(18785),o(67819),o(85970),o(19104)},99761:function(e,t,o){"use strict";o.r(t),o.d(t,{default:function(){return $o}});var s=o(78507),l=(o(85331),o(213),o(80047)),i=(o(99648),o(56768)),a=o(24232);const n={class:"history-header"},r={class:"header-left"},d={class:"record-count"},c={class:"header-right"},u={class:"timeline-header"},p={class:"date-label"},h={key:0,class:"grid-view"},m={class:"grid-preview"},g=["src"],f=["src"],y={key:2,class:"file-icon-wrapper"},b={class:"grid-overlay"},v={class:"grid-actions"},C={class:"grid-info"},k=["title"],w={class:"upload-time"},F={key:1,class:"list-view"},L={class:"list-preview"},U=["src"],$=["src"],S={key:2,class:"file-icon-wrapper-small"},T={class:"list-info"},_=["title"],x=["title"],M={class:"list-meta"},R={class:"upload-time"},A={class:"list-actions"},E={key:0,class:"load-more-container"},D={key:0,class:"loading-indicator"},I={key:1,class:"load-more-hint"},N={key:1,class:"no-more-hint"},P={key:1,class:"empty-state"};function V(e,t,o,V,W,z){const B=(0,i.g2)("font-awesome-icon"),H=l.S2,X=s.R7;return(0,i.uX)(),(0,i.CE)("div",{class:(0,a.C4)(["history-container",{active:o.show}])},[(0,i.Lk)("div",n,[(0,i.Lk)("div",r,[(0,i.Lk)("h2",null,(0,a.v_)(e.$t("uploadHistory.title")),1),(0,i.Lk)("span",d,(0,a.v_)(e.$t("uploadHistory.totalRecords",{count:W.totalCount})),1)]),(0,i.Lk)("div",c,[(0,i.bF)(X,{content:e.$t("uploadHistory.switchView"),placement:"bottom"},{default:(0,i.k6)(()=>[(0,i.bF)(H,{circle:"",onClick:z.toggleViewMode},{default:(0,i.k6)(()=>[(0,i.bF)(B,{icon:"grid"===W.viewMode?"list":"th-large"},null,8,["icon"])]),_:1},8,["onClick"])]),_:1},8,["content"]),(0,i.bF)(X,{content:e.$t("uploadHistory.clearRecords"),placement:"bottom"},{default:(0,i.k6)(()=>[(0,i.bF)(H,{circle:"",type:"danger",onClick:z.clearHistory},{default:(0,i.k6)(()=>[(0,i.bF)(B,{icon:"trash-alt"})]),_:1},8,["onClick"])]),_:1},8,["content"]),(0,i.bF)(H,{circle:"",onClick:t[0]||(t[0]=t=>e.$emit("close"))},{default:(0,i.k6)(()=>[(0,i.bF)(B,{icon:"times"})]),_:1})])]),W.historyList.length>0?((0,i.uX)(),(0,i.CE)("div",{key:0,class:"history-content",ref:"historyContent",onScroll:t[3]||(t[3]=(...e)=>z.handleScroll&&z.handleScroll(...e))},[((0,i.uX)(!0),(0,i.CE)(i.FK,null,(0,i.pI)(z.groupedHistory,e=>((0,i.uX)(),(0,i.CE)("div",{key:e.date,class:"history-group"},[(0,i.Lk)("div",u,[t[4]||(t[4]=(0,i.Lk)("div",{class:"timeline-dot"},null,-1)),(0,i.Lk)("span",p,(0,a.v_)(e.date),1)]),"grid"===W.viewMode?((0,i.uX)(),(0,i.CE)("div",h,[((0,i.uX)(!0),(0,i.CE)(i.FK,null,(0,i.pI)(e.items,e=>((0,i.uX)(),(0,i.CE)("div",{key:e.time,class:"grid-item"},[(0,i.Lk)("div",m,[z.isImage(e.name)?((0,i.uX)(),(0,i.CE)("img",{key:0,src:e.url,loading:"lazy",onError:t[1]||(t[1]=(...e)=>z.handleImageError&&z.handleImageError(...e))},null,40,g)):z.isVideo(e.name)?((0,i.uX)(),(0,i.CE)("video",{key:1,src:e.url,muted:""},null,8,f)):((0,i.uX)(),(0,i.CE)("div",y,[(0,i.bF)(B,{icon:"file",class:"file-icon"})])),(0,i.Lk)("div",b,[(0,i.Lk)("div",v,[(0,i.bF)(H,{circle:"",size:"default",type:"primary",onClick:t=>z.copyLink(e.url)},{default:(0,i.k6)(()=>[(0,i.bF)(B,{icon:"copy"})]),_:1},8,["onClick"]),(0,i.bF)(H,{circle:"",size:"default",class:"action-btn-view",onClick:t=>z.openLink(e.url)},{default:(0,i.k6)(()=>[(0,i.bF)(B,{icon:"external-link-alt"})]),_:1},8,["onClick"]),(0,i.bF)(H,{circle:"",size:"default",type:"danger",onClick:t=>z.deleteItem(e)},{default:(0,i.k6)(()=>[(0,i.bF)(B,{icon:"trash-alt"})]),_:1},8,["onClick"])])])]),(0,i.Lk)("div",C,[(0,i.Lk)("div",{class:"file-name",title:e.name},(0,a.v_)(e.name),9,k),(0,i.Lk)("div",w,(0,a.v_)(z.formatTime(e.time)),1)])]))),128))])):((0,i.uX)(),(0,i.CE)("div",F,[((0,i.uX)(!0),(0,i.CE)(i.FK,null,(0,i.pI)(e.items,e=>((0,i.uX)(),(0,i.CE)("div",{key:e.time,class:"list-item"},[(0,i.Lk)("div",L,[z.isImage(e.name)?((0,i.uX)(),(0,i.CE)("img",{key:0,src:e.url,loading:"lazy",onError:t[2]||(t[2]=(...e)=>z.handleImageError&&z.handleImageError(...e))},null,40,U)):z.isVideo(e.name)?((0,i.uX)(),(0,i.CE)("video",{key:1,src:e.url,muted:""},null,8,$)):((0,i.uX)(),(0,i.CE)("div",S,[(0,i.bF)(B,{icon:"file"})]))]),(0,i.Lk)("div",T,[(0,i.Lk)("div",{class:"file-name",title:e.name},(0,a.v_)(e.name),9,_),(0,i.Lk)("div",{class:"file-url",title:e.url},(0,a.v_)(e.url),9,x)]),(0,i.Lk)("div",M,[(0,i.Lk)("div",R,(0,a.v_)(z.formatTime(e.time)),1)]),(0,i.Lk)("div",A,[(0,i.bF)(H,{circle:"",size:"small",type:"primary",onClick:t=>z.copyLink(e.url)},{default:(0,i.k6)(()=>[(0,i.bF)(B,{icon:"copy"})]),_:1},8,["onClick"]),(0,i.bF)(H,{circle:"",size:"small",class:"action-btn-view",onClick:t=>z.openLink(e.url)},{default:(0,i.k6)(()=>[(0,i.bF)(B,{icon:"external-link-alt"})]),_:1},8,["onClick"]),(0,i.bF)(H,{circle:"",size:"small",type:"danger",onClick:t=>z.deleteItem(e)},{default:(0,i.k6)(()=>[(0,i.bF)(B,{icon:"trash-alt"})]),_:1},8,["onClick"])])]))),128))]))]))),128)),z.hasMore?((0,i.uX)(),(0,i.CE)("div",E,[W.loadingMore?((0,i.uX)(),(0,i.CE)("div",D,[(0,i.bF)(B,{icon:"spinner",spin:""}),(0,i.Lk)("span",null,(0,a.v_)(e.$t("uploadHistory.loading")),1)])):((0,i.uX)(),(0,i.CE)("div",I,(0,a.v_)(e.$t("uploadHistory.pullToLoadMore")),1))])):W.historyList.length>0?((0,i.uX)(),(0,i.CE)("div",N,(0,a.v_)(e.$t("uploadHistory.noMoreRecords")),1)):(0,i.Q3)("",!0)],544)):((0,i.uX)(),(0,i.CE)("div",P,[(0,i.bF)(B,{icon:"history",class:"empty-icon"}),(0,i.Lk)("p",null,(0,a.v_)(e.$t("uploadHistory.emptyHistory")),1)]))],2)}o(44114),o(18111),o(22489),o(7588),o(61701),o(33110),o(58335);var W={name:"UploadHistory",props:{show:{type:Boolean,default:!1}},data(){return{historyList:[],allHistory:[],viewMode:"grid",pageSize:30,currentPage:0,loadingMore:!1,totalCount:0}},watch:{show(e){e&&this.resetAndLoad()}},computed:{hasMore(){return this.historyList.length{const o=new Date(t.time),s=`${o.getFullYear()}-${String(o.getMonth()+1).padStart(2,"0")}-${String(o.getDate()).padStart(2,"0")}`;e[s]||(e[s]=[]),e[s].push(t)}),Object.keys(e).sort((e,t)=>new Date(t)-new Date(e)).map(t=>({date:t,items:e[t]}))}},mounted(){const e=localStorage.getItem("historyViewMode");e&&(this.viewMode=e)},methods:{resetAndLoad(){this.historyList=[],this.currentPage=0,this.loadAllHistory(),this.loadMore()},loadAllHistory(){try{const e=JSON.parse(localStorage.getItem("uploadHistory")||"[]");this.allHistory=e.sort((e,t)=>t.time-e.time),this.totalCount=this.allHistory.length}catch(e){console.error("Failed to load history",e),this.allHistory=[],this.totalCount=0}},loadMore(){!this.loadingMore&&this.hasMore&&(this.loadingMore=!0,setTimeout(()=>{const e=this.currentPage*this.pageSize,t=e+this.pageSize,o=this.allHistory.slice(e,t);this.historyList=[...this.historyList,...o],this.currentPage++,this.loadingMore=!1},50))},handleScroll(e){const t=e.target,o=t.scrollTop,s=t.scrollHeight,l=t.clientHeight;s-o-l<100&&this.loadMore()},toggleViewMode(){this.viewMode="grid"===this.viewMode?"list":"grid",localStorage.setItem("historyViewMode",this.viewMode)},clearHistory(){this.$confirm(this.$t("uploadHistory.clearConfirmMessage"),this.$t("uploadHistory.clearConfirmTitle"),{confirmButtonText:this.$t("uploadHistory.clearConfirmOk"),cancelButtonText:this.$t("uploadHistory.clearConfirmCancel"),type:"warning"}).then(()=>{this.historyList=[],this.allHistory=[],this.totalCount=0,this.currentPage=0,localStorage.removeItem("uploadHistory"),this.$message.success(this.$t("uploadHistory.recordsCleared"))}).catch(()=>{})},deleteItem(e){this.$confirm(this.$t("uploadHistory.deleteConfirmMessage"),this.$t("uploadHistory.clearConfirmTitle"),{confirmButtonText:this.$t("uploadHistory.clearConfirmOk"),cancelButtonText:this.$t("uploadHistory.clearConfirmCancel"),type:"warning"}).then(()=>{this.historyList=this.historyList.filter(t=>t.time!==e.time),this.allHistory=this.allHistory.filter(t=>t.time!==e.time),this.totalCount=this.allHistory.length;try{localStorage.setItem("uploadHistory",JSON.stringify(this.allHistory)),this.$message.success(this.$t("uploadHistory.recordDeleted"))}catch(t){console.error("Failed to update history",t)}}).catch(()=>{})},isImage(e){const t=["jpg","jpeg","png","gif","bmp","webp","svg","tiff","ico","avif","heic","jfif","pjpeg","pjp"],o=e?e.split(".").pop().toLowerCase():"";return t.includes(o)},isVideo(e){const t=["mp4","webm","ogg","mkv"],o=e?e.split(".").pop().toLowerCase():"";return t.includes(o)},formatTime(e){const t=new Date(e),o=t.getFullYear(),s=String(t.getMonth()+1).padStart(2,"0"),l=String(t.getDate()).padStart(2,"0"),i=String(t.getHours()).padStart(2,"0"),a=String(t.getMinutes()).padStart(2,"0"),n=String(t.getSeconds()).padStart(2,"0");return`${o}-${s}-${l} ${i}:${a}:${n}`},copyLink(e){navigator.clipboard.writeText(e).then(()=>{this.$message.success(this.$t("uploadHistory.linkCopied"))}).catch(()=>{this.$message.error(this.$t("uploadHistory.copyFailed"))})},openLink(e){window.open(e,"_blank")},handleImageError(e){e.target.src=o(96682)}}},z=o(71241);const B=(0,z.A)(W,[["render",V],["__scopeId","data-v-550797ce"]]);var H=B,X=o(86975),O=o(9267),Q=(o(15616),o(81418)),j=(o(50333),o(74757)),q=o(55558),G=(o(10456),o(39623)),K=(o(29092),o(76018)),J=(o(96808),o(67819),o(66810));o(34396),o(4885);const Y={class:"dialog-section"},Z={class:"section-header"},ee={class:"section-title"},te={class:"section-content"},oe={class:"setting-item"},se={class:"setting-label"},le={key:0,class:"setting-item"},ie={class:"setting-label"},ae={class:"setting-item"},ne={class:"setting-label"},re={class:"setting-item"},de={class:"setting-label"},ce={class:"dialog-section"},ue={class:"section-header"},pe={class:"section-title"},he={class:"section-content"},me={class:"dialog-section"},ge={class:"section-header"},fe={class:"section-title"},ye={class:"section-content"},be={class:"setting-item"},ve={class:"setting-label"},Ce={class:"setting-item"},ke={class:"setting-label"},we={key:0,class:"setting-item slider-item"},Fe={class:"setting-label"},Le={class:"slider-wrapper"},Ue={class:"slider-input-wrapper"},$e={key:1,class:"setting-item slider-item"},Se={class:"setting-label"},Te={class:"slider-wrapper"},_e={class:"slider-input-wrapper"},xe={key:0,class:"dialog-section"},Me={class:"section-header"},Re={class:"section-title"},Ae={class:"section-content"},Ee={class:"setting-item"},De={class:"setting-label"},Ie={class:"dialog-action"};function Ne(e,t,o,n,r,d){const c=(0,i.g2)("font-awesome-icon"),u=J.ll,p=J.MQ,h=s.R7,m=K.P9,g=K.AV,f=G.WK,y=q.qi,b=j.B8,v=Q.lq,C=l.S2,k=O.kZ;return(0,i.uX)(),(0,i.Wv)(k,{title:e.$t("uploadSettings.title"),modelValue:d.visible,"onUpdate:modelValue":t[12]||(t[12]=e=>d.visible=e),width:d.dialogWidth,"show-close":!1,class:"settings-dialog"},{default:(0,i.k6)(()=>[(0,i.Lk)("div",Y,[(0,i.Lk)("div",Z,[(0,i.Lk)("span",ee,(0,a.v_)(e.$t("uploadSettings.uploadChannel")),1)]),(0,i.Lk)("div",te,[(0,i.Lk)("div",oe,[(0,i.Lk)("span",se,(0,a.v_)(e.$t("uploadSettings.channelType")),1),(0,i.bF)(p,{"model-value":o.uploadChannel,"onUpdate:modelValue":t[0]||(t[0]=t=>e.$emit("update:uploadChannel",t)),class:"radio-card-group compact"},{default:(0,i.k6)(()=>[(0,i.bF)(u,{label:"telegram",class:"radio-card"},{default:(0,i.k6)(()=>[(0,i.bF)(c,{icon:"paper-plane",class:"channel-icon"}),t[13]||(t[13]=(0,i.Lk)("span",null,"TG",-1))]),_:1}),(0,i.bF)(u,{label:"cfr2",class:"radio-card"},{default:(0,i.k6)(()=>[(0,i.bF)(c,{icon:"cloud",class:"channel-icon"}),t[14]||(t[14]=(0,i.Lk)("span",null,"R2",-1))]),_:1}),(0,i.bF)(u,{label:"s3",class:"radio-card"},{default:(0,i.k6)(()=>[(0,i.bF)(c,{icon:"database",class:"channel-icon"}),t[15]||(t[15]=(0,i.Lk)("span",null,"S3",-1))]),_:1}),(0,i.bF)(u,{label:"discord",class:"radio-card"},{default:(0,i.k6)(()=>[(0,i.bF)(c,{icon:"comments",class:"channel-icon"}),t[16]||(t[16]=(0,i.Lk)("span",null,"DC",-1))]),_:1}),(0,i.bF)(u,{label:"huggingface",class:"radio-card"},{default:(0,i.k6)(()=>[(0,i.bF)(c,{icon:"robot",class:"channel-icon"}),t[17]||(t[17]=(0,i.Lk)("span",null,"HF",-1))]),_:1})),(0,i.bF)(u,{label:"webdav",class:"radio-card"},{default:(0,i.k6)(()=>[(0,i.bF)(c,{icon:"folder",class:"channel-icon"}),(0,i.Lk)("span",null,"WD")]),_:1})]),_:1},8,["model-value"])]),o.currentChannelList.length>1?((0,i.uX)(),(0,i.CE)("div",le,[(0,i.Lk)("span",ie,[(0,i.eW)((0,a.v_)(e.$t("uploadSettings.channelName"))+" ",1),(0,i.bF)(h,{content:e.$t("uploadSettings.channelNameTooltip"),placement:"top"},{default:(0,i.k6)(()=>[(0,i.bF)(c,{icon:"question-circle",class:"inline-help-icon"})]),_:1},8,["content"])]),(0,i.bF)(g,{"model-value":o.channelName,"onUpdate:modelValue":t[1]||(t[1]=t=>e.$emit("update:channelName",t)),placeholder:e.$t("uploadSettings.autoSelect"),clearable:"",class:"setting-input"},{default:(0,i.k6)(()=>[((0,i.uX)(!0),(0,i.CE)(i.FK,null,(0,i.pI)(o.currentChannelList,e=>((0,i.uX)(),(0,i.Wv)(m,{key:e.name,label:e.name,value:e.name},null,8,["label","value"]))),128))]),_:1},8,["model-value","placeholder"])])):(0,i.Q3)("",!0),(0,i.Lk)("div",ae,[(0,i.Lk)("span",ne,(0,a.v_)(e.$t("uploadSettings.uploadDirectory")),1),(0,i.bF)(f,{"model-value":o.uploadFolder,"onUpdate:modelValue":d.handleUploadFolderInput,placeholder:e.$t("uploadSettings.uploadDirectoryPlaceholder"),class:"setting-input"},null,8,["model-value","onUpdate:modelValue","placeholder"])]),(0,i.Lk)("div",re,[(0,i.Lk)("span",de,[(0,i.eW)((0,a.v_)(e.$t("uploadSettings.autoSwitch"))+" ",1),(0,i.bF)(h,{content:e.$t("uploadSettings.autoSwitchTooltip"),placement:"top"},{default:(0,i.k6)(()=>[(0,i.bF)(c,{icon:"question-circle",class:"inline-help-icon"})]),_:1},8,["content"])]),(0,i.bF)(y,{"model-value":o.autoRetry,"onUpdate:modelValue":t[2]||(t[2]=t=>e.$emit("update:autoRetry",t))},null,8,["model-value"])])])]),(0,i.Lk)("div",ce,[(0,i.Lk)("div",ue,[(0,i.Lk)("span",pe,(0,a.v_)(e.$t("uploadSettings.fileNaming")),1)]),(0,i.Lk)("div",he,[(0,i.bF)(p,{"model-value":o.uploadNameType,"onUpdate:modelValue":t[3]||(t[3]=t=>e.$emit("update:uploadNameType",t)),class:"radio-card-group grid-2x2"},{default:(0,i.k6)(()=>[(0,i.bF)(u,{label:"default",class:"radio-card"},{default:(0,i.k6)(()=>[(0,i.bF)(c,{icon:"cog",class:"radio-icon"}),(0,i.Lk)("span",null,(0,a.v_)(e.$t("uploadSettings.namingDefault")),1)]),_:1}),(0,i.bF)(u,{label:"index",class:"radio-card"},{default:(0,i.k6)(()=>[(0,i.bF)(c,{icon:"hashtag",class:"radio-icon"}),(0,i.Lk)("span",null,(0,a.v_)(e.$t("uploadSettings.namingIndex")),1)]),_:1}),(0,i.bF)(u,{label:"origin",class:"radio-card"},{default:(0,i.k6)(()=>[(0,i.bF)(c,{icon:"file-signature",class:"radio-icon"}),(0,i.Lk)("span",null,(0,a.v_)(e.$t("uploadSettings.namingOrigin")),1)]),_:1}),(0,i.bF)(u,{label:"short",class:"radio-card"},{default:(0,i.k6)(()=>[(0,i.bF)(c,{icon:"compress-alt",class:"radio-icon"}),(0,i.Lk)("span",null,(0,a.v_)(e.$t("uploadSettings.namingShort")),1)]),_:1})]),_:1},8,["model-value"])])]),(0,i.Lk)("div",me,[(0,i.Lk)("div",ge,[(0,i.Lk)("span",fe,(0,a.v_)(e.$t("uploadSettings.filePreprocess")),1),(0,i.bF)(h,{content:e.$t("uploadSettings.filePreprocessTooltip"),placement:"top"},{default:(0,i.k6)(()=>[(0,i.bF)(c,{icon:"question-circle",class:"section-help-icon"})]),_:1},8,["content"])]),(0,i.Lk)("div",ye,[(0,i.Lk)("div",be,[(0,i.Lk)("span",ve,[(0,i.eW)((0,a.v_)(e.$t("uploadSettings.convertToWebp"))+" ",1),(0,i.bF)(h,{content:e.$t("uploadSettings.convertToWebpTooltip"),placement:"top"},{default:(0,i.k6)(()=>[(0,i.bF)(c,{icon:"question-circle",class:"inline-help-icon"})]),_:1},8,["content"])]),(0,i.bF)(y,{"model-value":o.convertToWebp,"onUpdate:modelValue":t[4]||(t[4]=t=>e.$emit("update:convertToWebp",t))},null,8,["model-value"])]),(0,i.Lk)("div",Ce,[(0,i.Lk)("span",ke,(0,a.v_)(e.$t("uploadSettings.fileCompress")),1),(0,i.bF)(y,{"model-value":o.customerCompress,"onUpdate:modelValue":t[5]||(t[5]=t=>e.$emit("update:customerCompress",t))},null,8,["model-value"])]),o.customerCompress?((0,i.uX)(),(0,i.CE)("div",we,[(0,i.Lk)("span",Fe,[(0,i.eW)((0,a.v_)(e.$t("uploadSettings.compressThreshold"))+" ",1),(0,i.bF)(h,{content:e.$t("uploadSettings.compressThresholdTooltip"),placement:"top"},{default:(0,i.k6)(()=>[(0,i.bF)(c,{icon:"question-circle",class:"inline-help-icon"})]),_:1},8,["content"])]),(0,i.Lk)("div",Le,[(0,i.bF)(b,{"model-value":o.compressBar,"onUpdate:modelValue":t[6]||(t[6]=t=>e.$emit("update:compressBar",t)),min:1,max:20,"format-tooltip":e=>`${e} MB`},null,8,["model-value","format-tooltip"]),(0,i.Lk)("div",Ue,[(0,i.bF)(v,{"model-value":o.compressBar,"onUpdate:modelValue":t[7]||(t[7]=t=>e.$emit("update:compressBar",t)),min:1,max:20,step:1,"value-on-clear":1,class:"slider-input","controls-position":"right"},null,8,["model-value"]),t[18]||(t[18]=(0,i.Lk)("span",{class:"slider-unit"},"MB",-1))])])])):(0,i.Q3)("",!0),o.customerCompress?((0,i.uX)(),(0,i.CE)("div",$e,[(0,i.Lk)("span",Se,[(0,i.eW)((0,a.v_)(e.$t("uploadSettings.expectedSize"))+" ",1),(0,i.bF)(h,{content:e.$t("uploadSettings.expectedSizeTooltip"),placement:"top"},{default:(0,i.k6)(()=>[(0,i.bF)(c,{icon:"question-circle",class:"inline-help-icon"})]),_:1},8,["content"])]),(0,i.Lk)("div",Te,[(0,i.bF)(b,{"model-value":o.compressQuality,"onUpdate:modelValue":t[8]||(t[8]=t=>e.$emit("update:compressQuality",t)),min:.5,max:o.compressBar,step:.1,"format-tooltip":e=>`${e} MB`},null,8,["model-value","max","format-tooltip"]),(0,i.Lk)("div",_e,[(0,i.bF)(v,{"model-value":o.compressQuality,"onUpdate:modelValue":t[9]||(t[9]=t=>e.$emit("update:compressQuality",t)),min:.5,max:o.compressBar,step:.1,precision:1,"value-on-clear":.5,class:"slider-input","controls-position":"right"},null,8,["model-value","max"]),t[19]||(t[19]=(0,i.Lk)("span",{class:"slider-unit"},"MB",-1))])])])):(0,i.Q3)("",!0)])]),"telegram"===o.uploadChannel?((0,i.uX)(),(0,i.CE)("div",xe,[(0,i.Lk)("div",Me,[(0,i.Lk)("span",Re,(0,a.v_)(e.$t("uploadSettings.serverCompress")),1),(0,i.bF)(h,{content:e.$t("uploadSettings.serverCompressTooltip"),placement:"top","raw-content":""},{default:(0,i.k6)(()=>[(0,i.bF)(c,{icon:"question-circle",class:"section-help-icon"})]),_:1},8,["content"])]),(0,i.Lk)("div",Ae,[(0,i.Lk)("div",Ee,[(0,i.Lk)("span",De,(0,a.v_)(e.$t("uploadSettings.enableCompress")),1),(0,i.bF)(y,{"model-value":o.serverCompress,"onUpdate:modelValue":t[10]||(t[10]=t=>e.$emit("update:serverCompress",t))},null,8,["model-value"])])])])):(0,i.Q3)("",!0),(0,i.Lk)("div",Ie,[(0,i.bF)(C,{type:"primary",onClick:t[11]||(t[11]=e=>d.visible=!1),class:"confirm-btn"},{default:(0,i.k6)(()=>[(0,i.eW)((0,a.v_)(e.$t("uploadSettings.confirm")),1)]),_:1})])]),_:1},8,["title","modelValue","width"])}var Pe={name:"UploadSettingsDialog",methods:{handleUploadFolderInput(e){e&&!e.startsWith("/")&&(e="/"+e),this.$emit("update:uploadFolder",e)}},props:{modelValue:{type:Boolean,default:!1},uploadChannel:{type:String,default:"telegram"},channelName:{type:String,default:""},currentChannelList:{type:Array,default:()=>[]},uploadFolder:{type:String,default:""},autoRetry:{type:Boolean,default:!0},uploadNameType:{type:String,default:"default"},convertToWebp:{type:Boolean,default:!1},customerCompress:{type:Boolean,default:!0},compressBar:{type:Number,default:5},compressQuality:{type:Number,default:4},serverCompress:{type:Boolean,default:!0}},emits:["update:modelValue","update:uploadChannel","update:channelName","update:uploadFolder","update:autoRetry","update:uploadNameType","update:convertToWebp","update:customerCompress","update:compressBar","update:compressQuality","update:serverCompress"],computed:{visible:{get(){return this.modelValue},set(e){this.$emit("update:modelValue",e)}},dialogWidth(){return window.innerWidth>768?"50%":"90%"}}};const Ve=(0,z.A)(Pe,[["render",Ne]]);var We=Ve,ze=o(88559),Be=(o(85970),o(813)),He=(o(34896),o(69655)),Xe=(o(2893),o(74253));o(79899);const Oe={class:"upload-list-item"},Qe=["href"],je={key:0,style:{width:"10vw","border-radius":"12px"},autoplay:"",muted:"",playsinline:"",loop:""},qe=["src"],Ge=["src"],Ke={key:2,style:{width:"10vw","border-radius":"12px"}},Je={class:"upload-list-item-content"},Ye={class:"upload-list-item-name-wrapper"},Ze={key:0,class:"upload-list-item-url"},et={class:"upload-list-item-url-row"},tt={class:"upload-list-item-url-row"},ot={key:1,class:"upload-list-item-progress"},st={class:"upload-list-item-action"};function lt(e,t,o,s,l,n){const r=(0,i.g2)("font-awesome-icon"),d=Xe.$g,c=G.WK,u=He.ve,p=(0,i.g2)("Link"),h=Be.tk,m=(0,i.g2)("Delete");return(0,i.uX)(),(0,i.CE)("div",Oe,[(0,i.Lk)("a",{href:o.file.url,target:"_blank",class:"upload-list-item-preview"},[n.isVideo(o.file.name)?((0,i.uX)(),(0,i.CE)("video",je,[(0,i.Lk)("source",{src:o.file.url,type:"video/mp4"},null,8,qe),t[7]||(t[7]=(0,i.eW)(" Your browser does not support the video tag. ",-1))])):n.isImage(o.file.name)?((0,i.uX)(),(0,i.CE)("img",{key:1,style:{width:"10vw","border-radius":"12px"},src:o.file.url,onError:t[0]||(t[0]=t=>e.$emit("preview-error",o.file))},null,40,Ge)):((0,i.uX)(),(0,i.CE)("div",Ke,[(0,i.bF)(r,{icon:"file",class:"file-icon"})]))],8,Qe),(0,i.Lk)("div",Je,[(0,i.Lk)("div",Ye,[(0,i.bF)(d,{class:"upload-list-item-name",truncated:""},{default:(0,i.k6)(()=>[(0,i.eW)((0,a.v_)(n.truncateFilename(o.file.name)),1)]),_:1})]),"done"===o.file.status?((0,i.uX)(),(0,i.CE)("div",Ze,[(0,i.Lk)("div",et,[(0,i.bF)(c,{modelValue:o.file.finalURL,"onUpdate:modelValue":t[1]||(t[1]=e=>o.file.finalURL=e),readonly:"",onClick:n.selectAllText,size:n.urlSize},{prepend:(0,i.k6)(()=>[...t[8]||(t[8]=[(0,i.eW)("URL",-1)])]),_:1},8,["modelValue","onClick","size"]),(0,i.bF)(c,{modelValue:o.file.mdURL,"onUpdate:modelValue":t[2]||(t[2]=e=>o.file.mdURL=e),readonly:"",onClick:n.selectAllText,size:n.urlSize},{prepend:(0,i.k6)(()=>[...t[9]||(t[9]=[(0,i.eW)("MarkDown",-1)])]),_:1},8,["modelValue","onClick","size"])]),(0,i.Lk)("div",tt,[(0,i.bF)(c,{modelValue:o.file.htmlURL,"onUpdate:modelValue":t[3]||(t[3]=e=>o.file.htmlURL=e),readonly:"",onClick:n.selectAllText,size:n.urlSize},{prepend:(0,i.k6)(()=>[...t[10]||(t[10]=[(0,i.eW)("HTML",-1)])]),_:1},8,["modelValue","onClick","size"]),(0,i.bF)(c,{modelValue:o.file.ubbURL,"onUpdate:modelValue":t[4]||(t[4]=e=>o.file.ubbURL=e),readonly:"",onClick:n.selectAllText,size:n.urlSize},{prepend:(0,i.k6)(()=>[...t[11]||(t[11]=[(0,i.eW)("BBCode",-1)])]),_:1},8,["modelValue","onClick","size"])])])):((0,i.uX)(),(0,i.CE)("div",ot,[(0,i.bF)(u,{percentage:o.file.progreess,status:o.file.status,"show-text":!1},null,8,["percentage","status"])]))]),(0,i.Lk)("div",st,[(0,i.Lk)("button",{class:"modern-file-action-btn modern-file-action-btn-primary",onClick:t[5]||(t[5]=t=>e.$emit("copy",o.file))},[(0,i.bF)(h,null,{default:(0,i.k6)(()=>[(0,i.bF)(p)]),_:1})]),(0,i.Lk)("button",{class:"modern-file-action-btn modern-file-action-btn-danger",onClick:t[6]||(t[6]=t=>e.$emit("remove",o.file))},[(0,i.bF)(h,null,{default:(0,i.k6)(()=>[(0,i.bF)(m)]),_:1})])])])}var it=o(57477);const at=["jpg","jpeg","png","gif","bmp","webp","svg","tiff","ico","avif","heic","jfif","pjpeg","pjp","raw","cr2","nef","dng","eps","ai","emf","wmf"],nt=["mp4","webm","ogg","mkv"];var rt={name:"UploadFileItem",components:{Link:it.Link,Delete:it.Delete},props:{file:{type:Object,required:!0}},emits:["copy","remove","preview-error"],computed:{urlSize(){return window.innerWidth<768?"small":"default"}},methods:{isImage(e){const t=e.split(".").pop().toLowerCase();return at.includes(t)},isVideo(e){const t=e.split(".").pop().toLowerCase();return nt.includes(t)},truncateFilename(e,t=20){if(!e||e.length<=t)return e;const o=e.lastIndexOf(".");let s,l;o>0?(s=e.substring(0,o),l=e.substring(o)):(s=e,l="");const i=l.length+4,a=t-i-3;return a<=0?e.substring(0,t-3)+"...":s.substring(0,a)+"..."+s.slice(-4)+l},selectAllText(e){navigator.clipboard.writeText(e.target.value).then(()=>{this.$message({type:"success",message:this.$t("uploadForm.copySuccess")})}).catch(()=>{this.$message({type:"error",message:this.$t("uploadForm.copyFailed")})})}}};const dt=(0,z.A)(rt,[["render",lt],["__scopeId","data-v-4848c2b0"]]);var ct=dt,ut=o(62086),pt=(o(40670),o(88830),o(23597),o(70683)),ht=(o(95385),o(47358));const mt={class:"upload-form"},gt={class:"upload-card-glow",ref:"uploadCardGlow"},ft=["innerHTML"],yt={key:0,class:"upload-card"},bt={class:"paste-card-actions"},vt={class:"upload-list-dashboard-action"},Ct={class:"modern-action-group"},kt={class:"modern-dropdown-item-content"},wt={class:"modern-action-btn modern-action-btn-danger"};function Ft(e,t,n,r,d,c){const u=(0,i.g2)("CameraFilled"),p=Be.tk,h=ht.j5,m=G.WK,g=l.S2,f=J.Zh,y=J.MQ,b=pt.Ik,v=(0,i.g2)("List"),C=(0,i.g2)("Checked"),k=(0,i.g2)("Failed"),w=Xe.$g,F=(0,i.g2)("font-awesome-icon"),L=s.R7,U=q.qi,$=ut.c6,S=ut.Iy,T=ut.dW,_=ct,x=ze.kA;return(0,i.uX)(),(0,i.CE)("div",mt,[(0,i.Lk)("div",{class:"upload-card-wrapper",onMousemove:t[0]||(t[0]=(...e)=>c.handleUploadCardMouseMove&&c.handleUploadCardMouseMove(...e)),onMouseleave:t[1]||(t[1]=(...e)=>c.handleUploadCardMouseLeave&&c.handleUploadCardMouseLeave(...e))},[(0,i.Lk)("div",gt,null,512),"default"===n.uploadMethod?((0,i.uX)(),(0,i.Wv)(h,{key:0,class:(0,a.C4)(["upload-card",{"is-uploading":d.uploading,"upload-card-busy":d.fileList.length}]),drag:"",multiple:"","http-request":c.uploadFile,onSuccess:c.handleSuccess,"on-error":c.handleError,"before-upload":c.beforeUpload,"on-progress":c.handleProgress,"file-list":d.fileList,"show-file-list":!1},{default:(0,i.k6)(()=>[(0,i.bF)(p,{class:(0,a.C4)(["el-icon--upload",{"upload-list-busy":d.fileList.length}])},{default:(0,i.k6)(()=>[(0,i.bF)(u)]),_:1},8,["class"]),(0,i.Lk)("div",{class:(0,a.C4)(["el-upload__text",{"upload-list-busy":d.fileList.length}]),innerHTML:e.$t("upload.dragUploadText")},null,10,ft)]),_:1},8,["class","http-request","onSuccess","on-error","before-upload","on-progress","file-list"])):(0,i.Q3)("",!0)],32),"paste"===n.uploadMethod?((0,i.uX)(),(0,i.CE)("div",yt,[(0,i.bF)(b,{class:(0,a.C4)(["paste-card",{"is-uploading":d.uploading,"upload-card-busy":d.fileList.length}])},{default:(0,i.k6)(()=>[(0,i.bF)(m,{modelValue:d.pastedUrls,"onUpdate:modelValue":t[2]||(t[2]=e=>d.pastedUrls=e),class:"upload-card-textarea",placeholder:e.$t("upload.pasteUrlPlaceholder"),type:"textarea",rows:d.fileList.length?4:14},null,8,["modelValue","placeholder","rows"]),(0,i.Lk)("div",bt,[(0,i.bF)(g,{class:"paste-card-upload-button",type:"primary",size:c.pasteCardMethodButtonSize,onClick:c.handleUploadPasteUrls},{default:(0,i.k6)(()=>[(0,i.eW)((0,a.v_)(e.$t("upload.pasteUploadBtn")),1)]),_:1},8,["size","onClick"]),(0,i.bF)(y,{modelValue:d.pasteUploadMethod,"onUpdate:modelValue":t[3]||(t[3]=e=>d.pasteUploadMethod=e),class:"paste-card-method-group",size:c.pasteCardMethodButtonSize},{default:(0,i.k6)(()=>[(0,i.bF)(f,{label:"save"},{default:(0,i.k6)(()=>[(0,i.eW)((0,a.v_)(e.$t("upload.pasteSave")),1)]),_:1}),(0,i.bF)(f,{label:"external"},{default:(0,i.k6)(()=>[(0,i.eW)((0,a.v_)(e.$t("upload.pasteExternal")),1)]),_:1})]),_:1},8,["modelValue","size"])])]),_:1},8,["class"])])):(0,i.Q3)("",!0),(0,i.bF)(b,{class:(0,a.C4)(["upload-list-card",{"upload-list-busy":d.fileList.length,"is-uploading":d.uploading}])},{default:(0,i.k6)(()=>[(0,i.Lk)("div",{class:(0,a.C4)(["upload-list-container",{"upload-list-busy":d.fileList.length}])},[(0,i.bF)(x,{onScroll:c.handleScroll,ref:"scrollContainer"},{default:(0,i.k6)(()=>[(0,i.Lk)("div",{class:(0,a.C4)(["upload-list-dashboard",{"list-scrolled":d.listScrolled}])},[(0,i.bF)(w,{class:"upload-list-dashboard-title"},{default:(0,i.k6)(()=>[(0,i.bF)(p,null,{default:(0,i.k6)(()=>[(0,i.bF)(v)]),_:1}),(0,i.eW)((0,a.v_)(c.uploadingCount+c.waitingCount)+" ",1),(0,i.bF)(p,null,{default:(0,i.k6)(()=>[(0,i.bF)(C)]),_:1}),(0,i.eW)((0,a.v_)(c.uploadSuccessCount)+" ",1),(0,i.bF)(p,null,{default:(0,i.k6)(()=>[(0,i.bF)(k)]),_:1}),(0,i.eW)((0,a.v_)(c.uploadErrorCount),1)]),_:1}),(0,i.Lk)("div",vt,[(0,i.Lk)("div",Ct,[(0,i.bF)(L,{disabled:c.disableTooltip,content:e.$t("upload.copyAll"),placement:"top"},{default:(0,i.k6)(()=>[(0,i.Lk)("button",{class:"modern-action-btn",onClick:t[4]||(t[4]=(...e)=>c.copyAll&&c.copyAll(...e))},[(0,i.bF)(F,{icon:"copy"})])]),_:1},8,["disabled","content"]),(0,i.bF)(L,{disabled:c.disableTooltip,content:e.$t("upload.retryFailed"),placement:"top"},{default:(0,i.k6)(()=>[(0,i.bF)(T,null,{dropdown:(0,i.k6)(()=>[(0,i.bF)(S,{class:"modern-dropdown-menu"},{default:(0,i.k6)(()=>[(0,i.bF)($,null,{default:(0,i.k6)(()=>[(0,i.Lk)("div",kt,[(0,i.Lk)("span",null,(0,a.v_)(e.$t("uploadForm.autoRetry")),1),(0,i.bF)(U,{modelValue:d.autoReUpload,"onUpdate:modelValue":t[6]||(t[6]=e=>d.autoReUpload=e),onChange:c.handleAutoRetryChange,size:"small"},null,8,["modelValue","onChange"])])]),_:1})]),_:1})]),default:(0,i.k6)(()=>[(0,i.Lk)("button",{class:"modern-action-btn",onClick:t[5]||(t[5]=(...e)=>c.retryError&&c.retryError(...e))},[(0,i.bF)(F,{icon:"redo"})])]),_:1})]),_:1},8,["disabled","content"]),(0,i.bF)(L,{disabled:c.disableTooltip,content:e.$t("upload.clearList"),placement:"top"},{default:(0,i.k6)(()=>[(0,i.bF)(T,null,{dropdown:(0,i.k6)(()=>[(0,i.bF)(S,{class:"modern-dropdown-menu"},{default:(0,i.k6)(()=>[(0,i.bF)($,{onClick:c.clearFileList},{default:(0,i.k6)(()=>[(0,i.eW)((0,a.v_)(e.$t("upload.clearAll")),1)]),_:1},8,["onClick"]),(0,i.bF)($,{onClick:c.clearSuccessList},{default:(0,i.k6)(()=>[(0,i.eW)((0,a.v_)(e.$t("upload.clearUploaded")),1)]),_:1},8,["onClick"])]),_:1})]),default:(0,i.k6)(()=>[(0,i.Lk)("button",wt,[(0,i.bF)(F,{icon:"trash-alt"})])]),_:1})]),_:1},8,["disabled","content"])])])],2),((0,i.uX)(!0),(0,i.CE)(i.FK,null,(0,i.pI)(d.fileList.slice().reverse(),e=>((0,i.uX)(),(0,i.Wv)(_,{key:e.name,file:e,onCopy:c.handleCopy,onRemove:c.handleRemove,onPreviewError:t[7]||(t[7]=e=>e.url=o(96682))},null,8,["file","onCopy","onRemove"]))),128))]),_:1},8,["onScroll"])],2)]),_:1},8,["class"])])}o(16573),o(78100),o(77936),o(20116),o(18237),o(79577),o(41549),o(49797),o(49631),o(35623),o(64979),o(14603),o(47566),o(98721);var Lt=o(457),Ut=o(76334),$t=o(60782);function St(e,t,o){const s=o+e;return{finalURL:s,mdURL:`![${t}](${s})`,htmlURL:`${t}`,ubbURL:`[img]${s}[/img]`}}function Tt(e,t){const o={url:e.finalURL,md:e.mdURL,html:e.htmlURL,ubb:e.ubbURL};return o[t]||e.finalURL}function _t(e,t){e.forEach(e=>{if("external"===e.uploadChannel)return;const o=St(e.srcID,e.name,t);Object.assign(e,o)})}const xt=new Uint32Array([1116352408,1899447441,3049323471,3921009573,961987163,1508970993,2453635748,2870763221,3624381080,310598401,607225278,1426881987,1925078388,2162078206,2614888103,3248222580,3835390401,4022224774,264347078,604807628,770255983,1249150122,1555081692,1996064986,2554220882,2821834349,2952996808,3210313671,3336571891,3584528711,113926993,338241895,666307205,773529912,1294757372,1396182291,1695183700,1986661051,2177026350,2456956037,2730485921,2820302411,3259730800,3345764771,3516065817,3600352804,4094571909,275423344,430227734,506948616,659060556,883997877,958139571,1322822218,1537002063,1747873779,1955562222,2024104815,2227730452,2361852424,2428436474,2756734187,3204031479,3329325298]),Mt=(e,t)=>e>>>t|e<<32-t;function Rt(e,t){const o=new Uint32Array(64);for(let u=0;u<16;u++)o[u]=e[4*u]<<24|e[4*u+1]<<16|e[4*u+2]<<8|e[4*u+3];for(let u=16;u<64;u++){const e=Mt(o[u-15],7)^Mt(o[u-15],18)^o[u-15]>>>3,t=Mt(o[u-2],17)^Mt(o[u-2],19)^o[u-2]>>>10;o[u]=o[u-16]+e+o[u-7]+t>>>0}let[s,l,i,a,n,r,d,c]=t;for(let u=0;u<64;u++){const e=Mt(n,6)^Mt(n,11)^Mt(n,25),t=n&r^~n&d,p=c+e+t+xt[u]+o[u]>>>0,h=Mt(s,2)^Mt(s,13)^Mt(s,22),m=s&l^s&i^l&i,g=h+m>>>0;c=d,d=r,r=n,n=a+p>>>0,a=i,i=l,l=s,s=p+g>>>0}t[0]=t[0]+s>>>0,t[1]=t[1]+l>>>0,t[2]=t[2]+i>>>0,t[3]=t[3]+a>>>0,t[4]=t[4]+n>>>0,t[5]=t[5]+r>>>0,t[6]=t[6]+d>>>0,t[7]=t[7]+c>>>0}function At(){let e=new Uint32Array([1779033703,3144134277,1013904242,2773480762,1359893119,2600822924,528734635,1541459225]),t=new Uint8Array(64),o=0,s=0;return{update(l){s+=l.length;let i=0;if(o>0){const s=64-o,a=Math.min(s,l.length);t.set(l.subarray(0,a),o),o+=a,i=a,64===o&&(Rt(t,e),o=0)}while(i+64<=l.length)Rt(l.subarray(i,i+64),e),i+=64;i56&&(t.fill(0,o,64),Rt(t,e),o=0),t.fill(0,o,56);const i=new DataView(t.buffer);i.setUint32(56,Math.floor(l/4294967296),!1),i.setUint32(60,l>>>0,!1),Rt(t,e);let a="";for(let t=0;t<8;t++)a+=e[t].toString(16).padStart(8,"0");return a}}}async function Et(e){const t=At(),o=4194304;let s=0;while(sthis.fileListLength&&this.$nextTick(()=>{setTimeout(()=>{this.$refs.scrollContainer&&this.$refs.scrollContainer.setScrollTop(0)},100)}),this.fileListLength=this.fileList.length},deep:!0},useCustomUrl:{handler(){_t(this.fileList,this.rootUrl)},immediate:!0},customUrlPrefix:{handler(){"true"===this.useCustomUrl&&_t(this.fileList,this.rootUrl)},immediate:!0},autoReUpload(e){this.$store.commit("setStoreAutoReUpload",e)}},computed:{...(0,$t.L8)(["storeAutoReUpload"]),uploadSuccessCount(){return this.fileList.filter(e=>"done"===e.status||"success"===e.status).length},uploadErrorCount(){return this.fileList.filter(e=>"exception"===e.status).length},uploadingCount(){return this.fileList.filter(e=>"uploading"===e.status).length},waitingCount(){return this.uploadQueue.length},urlSize(){return window.innerWidth<768?"small":"default"},disableTooltip(){return window.innerWidth<768},rootUrl(){return"true"===this.useCustomUrl?this.customUrlPrefix:this.urlPrefix||`${window.location.protocol}//${window.location.host}/file/`},pasteCardMethodButtonSize(){return this.fileList.length||window.innerWidth<768?"small":"medium"}},mounted(){document.addEventListener("paste",this.handlePaste),this.autoReUpload=this.storeAutoReUpload},beforeUnmount(){document.removeEventListener("paste",this.handlePaste),this.uploadQueue=[],this.fileList=[],this.activeUploads=0},methods:{truncateFilename(e,t=20){if(!e||e.length<=t)return e;const o=e.lastIndexOf(".");let s,l;o>0?(s=e.substring(0,o),l=e.substring(o)):(s=e,l="");const i=l.length+4,a=t-i-3;return a<=0?e.substring(0,t-3)+"...":s.substring(0,a)+"..."+s.slice(-4)+l},uploadFile(e){if(!this.fileList.find(t=>t.uid===e.file.uid))return;if(this.activeUploads>=this.maxConcurrentUploads){this.uploadQueue.push(e);const t=this.fileList.find(t=>t.uid===e.file.uid);return void(t&&(t.status="waiting"))}this.activeUploads++;const t=this.fileList.find(t=>t.uid===e.file.uid);t&&(t.status="uploading");const o=this.fileList.find(t=>t.uid===e.file.uid),s=o?.uploadChannel||this.uploadChannel;if("external"===s)return void this.uploadSingleFile(e);if("webdav"===s)return void this.uploadSingleFile(e);if("huggingface"===s){const t=20971520;return void(e.file.size>=t?this.uploadToHuggingFaceDirect(e):this.uploadSingleFile(e))}if("discord"===s){const t=9437184;return void(e.file.size>t?this.uploadFileInChunks(e):this.uploadSingleFile(e))}const l=20971520;e.file.size>l?this.uploadFileInChunks(e):this.uploadSingleFile(e)},processUploadQueue(){if(0===this.uploadQueue.length||this.activeUploads>=this.maxConcurrentUploads)return;const e=this.uploadQueue.shift();e&&this.fileList.find(t=>t.uid===e.file.uid)?this.uploadFile(e):this.processUploadQueue()},onUploadComplete(){this.activeUploads=Math.max(0,this.activeUploads-1),this.processUploadQueue(),0===this.activeUploads&&0===this.uploadQueue.length&&(this.uploading=!1)},async uploadSingleFile(e){const t=this.fileList.find(t=>t.uid===e.file.uid);if(!t)return;const o=t.serverCompress,s=t.uploadChannel||this.uploadChannel,l=this.autoRetry&&"external"!==s,i="external"===s?"default":this.uploadNameType,a=new AbortController;this.abortControllers.set(e.file.uid,a);const n=new FormData;if(n.append("file",e.file),"external"===s&&n.append("url",e.file.url),"huggingface"===s)try{console.log("Computing SHA256 for HuggingFace upload...");const t=await Et(e.file);n.append("sha256",t),console.log("SHA256 computed:",t)}catch(r){console.error("Failed to compute SHA256:",r)}(0,Lt.A)({url:"/upload?serverCompress="+o+"&uploadChannel="+s+(this.channelName?"&channelName="+encodeURIComponent(this.channelName):"")+"&uploadNameType="+i+"&autoRetry="+l+"&uploadFolder="+encodeURIComponent(this.uploadFolder),method:"post",data:n,withAuthCode:!0,signal:a.signal,onUploadProgress:t=>{const o=Math.round(t.loaded/t.total*100);e.onProgress({percent:o,file:e.file})}}).then(t=>{e.onSuccess(t,e.file)}).catch(t=>{"CanceledError"!==t.name&&"ERR_CANCELED"!==t.code?t.response&&401!==t.response.status?(this.exceptionList.push(e),e.onError(t,e.file)):t.response||(this.exceptionList.push(e),e.onError(t,e.file)):console.log("上传已取消:",e.file.name)}).finally(()=>{this.abortControllers.delete(e.file.uid),this.onUploadComplete()})},async uploadFileInChunks(e){const t=this.fileList.find(t=>t.uid===e.file.uid);if(!t)return;const o=t.uploadChannel||this.uploadChannel,s=new AbortController;this.abortControllers.set(e.file.uid,s);const l="discord"===o?9437184:16777216,i=e.file.size,a=Math.ceil(i/l),n=t.serverCompress,r=this.autoRetry&&"external"!==o,d="external"===o?"default":this.uploadNameType;let c=null;if("huggingface"===o)try{console.log("Computing SHA256 for HuggingFace chunked upload..."),c=await Et(e.file),console.log("SHA256 computed:",c)}catch(u){console.error("Failed to compute SHA256:",u)}try{const t=new FormData;t.append("originalFileName",e.file.name),t.append("originalFileType",e.file.type),t.append("totalChunks",a.toString());const p=await(0,Lt.A)({url:"/upload?serverCompress="+n+"&uploadChannel="+o+(this.channelName?"&channelName="+encodeURIComponent(this.channelName):"")+"&uploadNameType="+d+"&autoRetry="+r+"&uploadFolder="+encodeURIComponent(this.uploadFolder)+"&initChunked=true",method:"post",data:t,withAuthCode:!0});if(!p.data.success)throw new Error(this.$t("uploadForm.chunkInitFailed")+": "+p.data.message);const h=p.data.uploadId;console.log("分块上传初始化成功,uploadId:",h);const m=this.fileList.find(t=>t.uid===e.file.uid);m&&(m.totalChunks=a,m.uploadId=h);const g=3,f=new Array(a).fill(0);let y=0,b=!1,v="",C=!1;const k=async t=>{if(b||C)return;const c=t*l,p=Math.min(c+l,i),m=e.file.slice(c,p),g=new FormData;g.append("file",m,`${e.file.name}.part${t.toString().padStart(3,"0")}`),g.append("chunkIndex",t.toString()),g.append("totalChunks",a.toString()),g.append("uploadId",h),g.append("originalFileName",e.file.name),g.append("originalFileType",e.file.type);let y=0;const k=3;while(y{if(b||C)return;const s=Math.round(o.loaded/o.total*100);f[t]=s;const l=Math.round(f.reduce((e,t)=>e+t,0)/a);e.onProgress({percent:l,file:e.file})}})}catch(u){if("CanceledError"===u.name||"ERR_CANCELED"===u.code)return C=!0,void console.log("分块上传已取消:",e.file.name);if(y++,console.warn(`分块 ${t+1}/${a} 上传失败 (重试 ${y}/${k}):`,u),y>=k)throw b=!0,v=`分块 ${t+1}/${a} 上传失败: ${u.message}`,new Error(v);await new Promise(e=>setTimeout(e,2e3*y))}}},w=[];for(let e=0;e{while(yt.uid===e.file.uid);t&&t.uploadId&&this.cleanupUploadResources(t.uploadId,t.totalChunks).then(()=>{console.log(`已清理分块上传失败的资源: ${t.uploadId}`)}).catch(e=>{console.warn("清理分块上传失败资源时出错:",e)}),u.response&&401!==u.response.status?(this.exceptionList.push(e),e.onError(u,e.file)):u.response||(this.exceptionList.push(e),e.onError(u,e.file))}finally{this.abortControllers.delete(e.file.uid),this.onUploadComplete()}},handleRemove(e){this.abortControllers.has(e.uid)&&(this.abortControllers.get(e.uid).abort(),this.abortControllers.delete(e.uid)),this.uploadQueue=this.uploadQueue.filter(t=>t.file.uid!==e.uid),this.fileList=this.fileList.filter(t=>t.uid!==e.uid),this.$message({type:"info",message:this.$t("uploadForm.deleted",{name:this.truncateFilename(e.name)})})},async cleanupUploadResources(e,t=0){try{await(0,Lt.A)({url:`/upload?cleanup=true&uploadId=${e}&totalChunks=${t}`,method:"get",withAuthCode:!0,timeout:5e3}),console.log(`清理上传资源成功: ${e}`)}catch(o){console.warn("清理上传资源失败:",o)}},handleSuccess(e,t){const o=this.fileList.find(e=>e.uid===t.uid);if(o)try{const s=o.uploadChannel||this.uploadChannel;if("external"!==s){const s=e.data[0].src.replace("/file/","");o.url=`${window.location.protocol}//${window.location.host}/file/`+s;const l=St(s,t.name,this.rootUrl);Object.assign(o,l),o.srcID=s}o.progreess=100,o.status="success",this.saveToHistory(o),this.$message({type:"success",message:this.$t("uploadForm.uploadSuccess",{name:this.truncateFilename(t.name)})}),setTimeout(()=>{const e=this.fileList.find(e=>e.uid===t.uid);e&&(e.status="done")},1e3)}catch(s){this.$message.error(this.$t("uploadForm.uploadFailed",{name:this.truncateFilename(t.name)})),o.status="exception"}},saveToHistory(e){try{const t=JSON.parse(localStorage.getItem("uploadHistory")||"[]"),o={name:e.name,url:e.finalURL,time:Date.now(),type:e.name.split(".").pop().toLowerCase()};t.push(o),localStorage.setItem("uploadHistory",JSON.stringify(t))}catch(t){console.error("Failed to save history",t)}},handleError(e,t){const o=this.fileList.find(e=>e.uid===t.uid);o&&(this.$message.error(this.$t("uploadForm.uploadFailed",{name:this.truncateFilename(t.name)})),o.status="exception",this.autoReUpload&&this.scheduleAutoRetry())},handleCopy(e){const t=this.fileList.find(t=>t.uid===e.uid).status;"done"===t||"success"===t?(navigator.clipboard.writeText(Tt(e,this.selectedUrlForm)),this.$message({type:"success",message:this.$t("uploadForm.copySuccess")})):this.$message({type:"warning",message:this.$t("uploadForm.fileNotUploaded")})},beforeUpload(e){return new Promise(async(t,o)=>{let s=e;const l=this.convertToWebp&&e.type.includes("image")&&!e.type.includes("webp")&&!e.type.includes("gif")&&!e.type.includes("svg");if(l)try{const t=await this.convertImageToWebp(e);t&&(s=t,console.log(`WebP转换成功: ${e.name} -> ${t.name}, 大小: ${(e.size/1024).toFixed(1)}KB -> ${(t.size/1024).toFixed(1)}KB`))}catch(r){console.warn("WebP转换失败,使用原文件:",r)}const i=s.type.includes("image")&&this.customerCompress&&s.size/1024/1024>this.compressBar,a=s.size/1024/1024<=1024||"telegram"!==this.uploadChannel,n=(e,o)=>{const s=URL.createObjectURL(e);this.fileList.push({uid:e.uid,name:e.name,url:s,finalURL:"",mdURL:"",htmlURL:"",ubbURL:"",srcID:"",status:"uploading",progreess:0,serverCompress:o,retryCount:0}),t(e)};if(i)Ut.compressAccurately(s,1024*this.compressQuality).then(t=>{t.size/1024/1024>1024&&"telegram"===this.uploadChannel&&(this.$message.error(this.$t("uploadForm.compressedFileTooLarge",{name:s.name})),o(this.$t("uploadForm.fileSizeTooLarge"))),this.uploading=!0;const l=new File([t],s.name,{type:t.type});l.uid=e.uid;const i=this.uploadCount++,a=this.serverCompress&&l.size/1024/1024<10&&"telegram"===this.uploadChannel;0===i?n(l,a):setTimeout(()=>{n(l,a),this.uploadCount--},300*i)}).catch(e=>{this.$message.error(this.$t("uploadForm.compressFailedCannotUpload",{name:s.name})),o(e)});else if(a){this.uploading=!0;const e=this.uploadCount++,t="telegram"===this.uploadChannel&&this.serverCompress&&(!s.type.includes("image")||s.size/1024/1024<10);0===e?n(s,t):setTimeout(()=>{n(s,t),this.uploadCount--},300*e)}else this.$message.error(this.$t("uploadForm.fileTooLarge",{name:s.name})),o(this.$t("uploadForm.fileSizeTooLarge"))})},handleProgress(e){const t=this.fileList.find(t=>t.uid===e.file.uid);t&&(t.progreess=e.percent)},copyAll(){const e=this.fileList.filter(e=>"done"===e.status||"success"===e.status).map(e=>Tt(e,this.selectedUrlForm)).join("\n");navigator.clipboard.writeText(e),this.$message({type:"success",message:this.$t("uploadForm.copyAllSuccess")})},clearFileList(){this.fileList.length>0?(this.abortControllers.forEach((e,t)=>{e.abort()}),this.abortControllers.clear(),this.uploadQueue=[],this.fileList=[],this.$message({type:"success",message:this.$t("uploadForm.fileListCleared")})):this.$message({type:"info",message:this.$t("uploadForm.fileListEmpty")})},clearSuccessList(){this.uploadSuccessCount>0?(this.fileList=this.fileList.filter(e=>"done"!==e.status&&"success"!==e.status),this.$message({type:"success",message:this.$t("uploadForm.successFilesCleared")})):this.$message({type:"info",message:this.$t("uploadForm.successFilesEmpty")})},handlePaste(e){if("INPUT"===e.target.tagName||"TEXTAREA"===e.target.tagName)return;const t=e.clipboardData.items;t.length>0&&this.uploadFromUrl(t)},handleUploadPasteUrls(){const e=this.pastedUrls.split("\n"),t=e.map(e=>e.trim()).filter(e=>""!==e).filter(e=>/^(https?:\/\/[^\s$.?#].[^\s]*)$/.test(e));if("save"===this.pasteUploadMethod)this.uploadFromUrl(t.map(e=>({kind:"string",getAsString:t=>{t(e)}})));else if("external"===this.pasteUploadMethod)for(let o=0;o`,a=`[img]${e}[/img]`,n=new File([],e.split("/").pop(),{type:"text/plain"});n.uid=Date.now()+o,n.url=e,this.fileList.push({uid:n.uid,name:n.name,url:e,finalURL:e,mdURL:l,htmlURL:i,ubbURL:a,srcID:e,status:"uploading",progreess:0,serverCompress:!1,uploadChannel:"external",retryCount:0}),this.uploadFile({file:n,onProgress:e=>this.handleProgress(e),onSuccess:(e,t)=>this.handleSuccess(e,t),onError:(e,t)=>this.handleError(e,t)})}},uploadFromUrl(e){for(let t=0;t{e instanceof File&&this.uploadFile({file:e,onProgress:e=>this.handleProgress(e),onSuccess:(e,t)=>this.handleSuccess(e,t),onError:(e,t)=>this.handleError(e,t)})}).catch(e=>{console.log(e)})}else"string"===e[t].kind&&e[t].getAsString(e=>{const o=/^(https?:\/\/[^\s$.?#].[^\s]*)$/;let s="";o.test(e)&&Lt.A.post("/api/fetchRes",{url:e},{responseType:"blob",withAuthCode:!0}).then(o=>{o.headers["content-type"];if(200!=o.status)throw new Error("URL地址请求失败");{const i=o.headers["content-disposition"];if(i){const e=/filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/,t=/filename\*\s*=\s*UTF-8''([^;\n]*)/;let o=e.exec(i);if(null!=o&&o[1]){s=o[1].replace(/['"]/g,"");try{s=decodeURIComponent(s)}catch(l){s=""}}""===s&&(o=t.exec(i),null!=o&&o[1]&&(s=decodeURIComponent(o[1])))}if(""===s){const t=new URL(e);s=t.pathname.split("/").pop()}if(""===s){const o=new URL(e);let l=o.pathname.split(".").pop();(!l||""===l||l.length>10)&&(l="bin"),s="PastedFile"+Date.now()+t+"."+l}const a=o.data,n=new File([a],s,{type:a.type});n.uid=Date.now()+t;const r=this.beforeUpload(n);r instanceof Promise&&r.then(e=>{e instanceof File&&this.uploadFile({file:e,onProgress:e=>this.handleProgress(e),onSuccess:(e,t)=>this.handleSuccess(e,t),onError:(e,t)=>this.handleError(e,t)})}).catch(e=>{console.log(e)})}}).catch(e=>{this.$message({type:"warning",message:this.$t("uploadForm.urlRequestFailed")})})})},handleScroll(e){this.listScrolled=e.scrollTop>0&&this.fileList.length>0},retryError(){this.exceptionList.length>0?(this.retryFailedFiles(this.exceptionList),this.exceptionList=[]):this.$message({type:"info",message:this.$t("uploadForm.noFailedFiles")})},handleAutoRetryChange(e){this.$message({type:e?"success":"info",message:e?this.$t("uploadForm.autoRetryOn"):this.$t("uploadForm.autoRetryOff")}),e&&this.exceptionList.length>0&&this.scheduleAutoRetry()},retryFailedFiles(e){e.forEach(e=>{const t=e.retryCount||0;tthis.handleProgress(e),onSuccess:(e,t)=>this.handleSuccess(e,t),onError:(e,t)=>this.handleError(e,t)})):this.$message({type:"warning",message:this.$t("uploadForm.maxRetryReached",{name:e.name,max:this.maxRetryCount})})})},scheduleAutoRetry(){this.retryTimer&&clearTimeout(this.retryTimer),this.retryTimer=setTimeout(()=>{if(this.autoReUpload&&this.exceptionList.length>0){const e=[...this.exceptionList];this.exceptionList=[],this.retryFailedFiles(e)}},this.retryDelay)},async uploadToHuggingFaceDirect(e){const t=this.fileList.find(t=>t.uid===e.file.uid);if(!t)return;const o=new AbortController;this.abortControllers.set(e.file.uid,o);try{console.log("=== HuggingFace Direct Upload ==="),console.log("File:",e.file.name,"Size:",e.file.size),e.onProgress({percent:5,file:e.file}),console.log("Computing SHA256...");const t=await Et(e.file);if(console.log("SHA256:",t),o.signal.aborted)return void console.log("HuggingFace 上传已取消:",e.file.name);const s=new Uint8Array(await e.file.slice(0,512).arrayBuffer()),l=btoa(String.fromCharCode(...s));e.onProgress({percent:10,file:e.file}),console.log("Getting LFS upload URL...");const i=await(0,Lt.A)({url:"/upload/huggingface/getUploadUrl",method:"post",data:{fileSize:e.file.size,fileName:e.file.name,fileType:e.file.type,sha256:t,fileSample:l,channelName:this.channelName,uploadNameType:this.uploadNameType,uploadFolder:this.uploadFolder},withAuthCode:!0,signal:o.signal});if(!i.data.success)throw new Error(i.data.error||"Failed to get upload URL");const a=i.data;if(console.log("Upload info:",a),a.alreadyExists)console.log("File already exists in LFS, skipping upload"),e.onProgress({percent:90,file:e.file});else if(a.needsLfs&&a.uploadAction){const{href:t,header:s}=a.uploadAction;if(s?.chunk_size)await this.uploadToHuggingFaceMultipart(e,a,o);else{console.log("Uploading to S3 (basic)...");const l=await fetch(t,{method:"PUT",headers:s||{},body:e.file,signal:o.signal});if(!l.ok){const e=await l.text();throw new Error(`S3 upload failed: ${l.status} - ${e}`)}console.log("S3 upload complete")}}if(o.signal.aborted)return void console.log("HuggingFace 上传已取消:",e.file.name);e.onProgress({percent:95,file:e.file}),console.log("Committing file...");const n=await(0,Lt.A)({url:"/upload/huggingface/commitUpload",method:"post",data:{fullId:a.fullId,filePath:a.filePath,sha256:t,fileSize:e.file.size,fileName:e.file.name,fileType:e.file.type,channelName:a.channelName},withAuthCode:!0,signal:o.signal});if(!n.data.success)throw new Error(n.data.error||"Failed to commit file");console.log("Upload complete:",n.data);const r={data:[{src:n.data.src}]};e.onSuccess(r,e.file)}catch(s){if("CanceledError"===s.name||"ERR_CANCELED"===s.code||"AbortError"===s.name)return void console.log("HuggingFace 上传已取消:",e.file.name);console.error("HuggingFace direct upload error:",s),this.exceptionList.push(e),e.onError(s,e.file)}finally{this.abortControllers.delete(e.file.uid),this.onUploadComplete()}},async uploadToHuggingFaceMultipart(e,t,o){const{uploadAction:s}=t,{href:l,header:i}=s,a=parseInt(i.chunk_size),n=Object.keys(i).filter(e=>/^[0-9]+$/.test(e));console.log(`Multipart upload: ${n.length} parts, chunk size: ${a}`);const r=[],d=n.length;for(const u of n){if(o&&o.signal.aborted)throw console.log("HuggingFace 分片上传已取消"),new DOMException("Upload cancelled","AbortError");const t=parseInt(u)-1,s=t*a,l=Math.min(s+a,e.file.size),n=e.file.slice(s,l);console.log(`Uploading part ${u}/${d}`);const c=await fetch(i[u],{method:"PUT",body:n,signal:o?o.signal:void 0});if(!c.ok)throw new Error(`Failed to upload part ${u}: ${c.status}`);const p=c.headers.get("ETag");if(!p)throw new Error(`No ETag for part ${u}`);r.push({partNumber:parseInt(u),etag:p});const h=10+Math.round(parseInt(u)/d*80);e.onProgress({percent:h,file:e.file})}if(o&&o.signal.aborted)throw console.log("HuggingFace 分片上传已取消"),new DOMException("Upload cancelled","AbortError");console.log("Completing multipart upload...");const c=await fetch(l,{method:"POST",headers:{Accept:"application/vnd.git-lfs+json","Content-Type":"application/vnd.git-lfs+json"},body:JSON.stringify({oid:t.oid,parts:r}),signal:o?o.signal:void 0});if(!c.ok){const e=await c.text();throw new Error(`Multipart complete failed: ${c.status} - ${e}`)}console.log("Multipart upload complete")},async convertImageToWebp(e){return new Promise((t,o)=>{if(e.type.includes("gif")||e.type.includes("svg")||e.type.includes("webp"))return void t(null);const s=new Image,l=document.createElement("canvas"),i=l.getContext("2d");s.onload=()=>{l.width=s.width,l.height=s.height,i.drawImage(s,0,0),l.toBlob(l=>{if(l){const o=e.name,s=o.lastIndexOf("."),i=s>0?o.substring(0,s)+".webp":o+".webp",a=new File([l],i,{type:"image/webp"});a.uid=e.uid,t(a)}else o(new Error("WebP 转换失败"));URL.revokeObjectURL(s.src)},"image/webp",.92)},s.onerror=()=>{URL.revokeObjectURL(s.src),o(new Error(this.$t("uploadForm.imageLoadFailed")))},s.src=URL.createObjectURL(e)})},handleUploadCardMouseMove(e){const t=this.$refs.uploadCardGlow;if(!t)return;const o=e.currentTarget.getBoundingClientRect(),s=e.clientX-o.left,l=e.clientY-o.top;t.style.opacity="1",t.style.left=s+"px",t.style.top=l+"px"},handleUploadCardMouseLeave(){const e=this.$refs.uploadCardGlow;e&&(e.style.opacity="0")}},beforeDestroy(){this.retryTimer&&clearTimeout(this.retryTimer)}};const It=(0,z.A)(Dt,[["render",Ft],["__scopeId","data-v-37f80c81"]]);var Nt=It,Pt=o(732),Vt=o(33892),Wt=o(45130);const zt={class:"directory-suggestion-input",ref:"wrapperRef"},Bt={class:"suggestion-dropdown"},Ht={class:"suggestion-list"},Xt=["title","onMousedown"];function Ot(e,t,o,s,l,n){const r=G.WK;return(0,i.uX)(),(0,i.CE)("div",zt,[(0,i.bF)(r,{ref:"inputRef",modelValue:n.inputValue,"onUpdate:modelValue":t[0]||(t[0]=e=>n.inputValue=e),placeholder:o.placeholder,onFocus:n.handleFocus,onBlur:n.handleBlur,onInput:n.handleInput},null,8,["modelValue","placeholder","onFocus","onBlur","onInput"]),(0,i.bo)((0,i.Lk)("div",Bt,[(0,i.Lk)("ul",Ht,[((0,i.uX)(!0),(0,i.CE)(i.FK,null,(0,i.pI)(l.suggestions,(e,t)=>((0,i.uX)(),(0,i.CE)("li",{key:t,class:"suggestion-item",title:e.value,onMousedown:(0,Wt.D$)(t=>n.selectItem(e),["prevent"])},(0,a.v_)(e.value),41,Xt))),128))])],512),[[Wt.aG,l.dropdownVisible&&l.suggestions.length>0]])],512)}var Qt={name:"DirectorySuggestionInput",props:{modelValue:{type:String,default:""},placeholder:{type:String,default:""}},emits:["update:modelValue","focus","blur","select"],data(){return{directoryTreeRoot:null,directoryTreeLoaded:!1,directoryTreeLoading:!1,directoryChildrenMap:{},focusTime:null,dropdownVisible:!1,isFocused:!1,suggestions:[]}},computed:{inputValue:{get(){return this.modelValue},set(e){this.$emit("update:modelValue",e)}}},watch:{modelValue(){this.isFocused&&this.refreshSuggestions()}},methods:{handleFocus(){this.isFocused=!0,this.focusTime=Date.now(),this.ensureDirectoryTreeLoaded(),this.$emit("focus"),setTimeout(()=>{this.isFocused&&(this.refreshSuggestions(),this.dropdownVisible=!0)},500)},handleBlur(){this.isFocused=!1,this.dropdownVisible=!1,this.$emit("blur")},handleInput(e){this.$nextTick(()=>{this.refreshSuggestions(),this.isFocused&&(this.dropdownVisible=!0)})},selectItem(e){const t=e.value;this.inputValue=t,this.$emit("select",t);const o=this.normalizeDirectoryPath(t),s=this.directoryChildrenMap[o];s&&s.length>0?this.$nextTick(()=>{this.refreshSuggestions(),this.dropdownVisible=!0,this.$refs.inputRef?.focus()}):this.dropdownVisible=!1},refreshSuggestions(){this.suggestions=this.getDirectorySuggestions(this.modelValue||"")},normalizeDirectoryPath(e){if(!e)return"/";let t=e;return t.startsWith("/")||(t="/"+t),"/"===t||t.endsWith("/")||(t+="/"),t},buildDirectoryChildrenMap(e){const t={},o=e=>{const s=this.normalizeDirectoryPath(e.path),l=Array.isArray(e.children)?e.children:[];t[s]=l.map(e=>({name:e.name,path:this.normalizeDirectoryPath(e.path)})),l.forEach(o)};o(e),this.directoryChildrenMap=t},async ensureDirectoryTreeLoaded(){if(!this.directoryTreeLoaded&&!this.directoryTreeLoading){this.directoryTreeLoading=!0;try{const e=await Lt.A.get("/api/directoryTree",{withAuthCode:!0}),t=e?.data?.tree;t&&(this.directoryTreeRoot=t,this.buildDirectoryChildrenMap(t),this.directoryTreeLoaded=!0)}catch(e){console.error("Failed to load directory tree for autocomplete:",e)}finally{this.directoryTreeLoading=!1}}},parseDirectoryQuery(e){const t=e&&e.startsWith("/")?e:`/${e||""}`,o=t.slice(1),s=o.split("/"),l=s[s.length-1]||"",i=s.slice(0,-1).filter(Boolean),a=i.length>0?`/${i.join("/")}/`:"/";return{segmentInput:l,parentPath:a}},getDirectorySuggestions(e){const{segmentInput:t,parentPath:o}=this.parseDirectoryQuery(e),s=this.directoryChildrenMap[o]||[];if(!t)return s.slice(0,10).map(e=>({value:e.path}));const l=t.toLowerCase();return s.filter(e=>e.name.toLowerCase().startsWith(l)).slice(0,10).map(e=>({value:e.path}))}}};const jt=(0,z.A)(Qt,[["render",Ot],["__scopeId","data-v-0ff63416"]]);var qt=jt,Gt=o(6834);const Kt={class:"container"},Jt={class:"upload-home"},Yt={class:"toolbar-manage"},Zt={class:"toolbar"},eo={class:"header"},to={class:"title"},oo={class:"main-title",href:"https://github.com/MarSeventh/CloudFlare-ImgBed",target:"_blank"},so={class:"dialog-section"},lo={class:"section-header"},io={class:"section-title"},ao={class:"section-content"},no={class:"dialog-section"},ro={class:"section-header"},co={class:"section-title"},uo={class:"section-content"},po={class:"setting-item"},ho={class:"setting-label"},mo={key:0,class:"setting-item"},go={class:"setting-label"},fo={class:"dialog-action"},yo=["innerHTML"],bo={class:"dialog-footer"};function vo(e,t,o,n,r,d){const c=Gt.A,u=(0,i.g2)("font-awesome-icon"),p=l.S2,h=ut.c6,m=ut.Iy,g=ut.dW,f=qt,y=G.WK,b=Vt.A,v=s.R7,C=Pt.A,k=Nt,w=J.ll,F=J.MQ,L=q.qi,U=O.kZ,$=We,S=X.A,T=H;return(0,i.uX)(),(0,i.CE)("div",Kt,[(0,i.Lk)("div",Jt,[(0,i.bF)(c,{class:"toggle-dark-button desktop-only"}),(0,i.bF)(g,{class:"more-dropdown desktop-only",trigger:"click",onCommand:d.handleDesktopMenuCommand},{dropdown:(0,i.k6)(()=>[(0,i.bF)(m,null,{default:(0,i.k6)(()=>[(0,i.bF)(h,{command:"showHistory"},{default:(0,i.k6)(()=>[(0,i.bF)(u,{icon:"history",style:{width:"16px","margin-right":"8px","text-align":"center"}}),(0,i.eW)(" "+(0,a.v_)(e.$t("upload.history")),1)]),_:1}),(0,i.bF)(h,{command:"showAnnouncement",disabled:!d.announcementAvailable},{default:(0,i.k6)(()=>[(0,i.bF)(u,{icon:"bullhorn",style:{width:"16px","margin-right":"8px","text-align":"center"}}),(0,i.eW)(" "+(0,a.v_)(e.$t("upload.announcement")),1)]),_:1},8,["disabled"]),(0,i.bF)(h,{command:"toggleLanguage"},{default:(0,i.k6)(()=>[(0,i.bF)(u,{icon:"globe",style:{width:"16px","margin-right":"8px","text-align":"center"}}),(0,i.eW)(" "+(0,a.v_)("zh-CN"===e.$i18n.locale?"English":"简体中文"),1)]),_:1}),(0,i.bF)(h,{command:"viewDocs"},{default:(0,i.k6)(()=>[(0,i.bF)(u,{icon:"book",style:{width:"16px","margin-right":"8px","text-align":"center"}}),(0,i.eW)(" "+(0,a.v_)(e.$t("upload.viewDocs")),1)]),_:1})]),_:1})]),default:(0,i.k6)(()=>[(0,i.bF)(p,{class:"more-button"},{default:(0,i.k6)(()=>[(0,i.bF)(u,{icon:"ellipsis-v",size:"lg"})]),_:1})]),_:1},8,["onCommand"]),(0,i.Lk)("div",{class:(0,a.C4)(["upload-folder-container",{"no-announcement":!d.announcementAvailable}])},[(0,i.Lk)("div",{class:(0,a.C4)(["upload-folder",{active:r.isFolderInputActive}])},[d.showDirectorySuggestions?((0,i.uX)(),(0,i.Wv)(f,{key:0,modelValue:r.uploadFolder,"onUpdate:modelValue":t[0]||(t[0]=e=>r.uploadFolder=e),class:"inner-folder-input",placeholder:e.$t("upload.folderPlaceholder"),onFocus:d.handleFolderInputFocus,onBlur:d.handleFolderInputBlur,onSelect:d.handleDirectorySelect},null,8,["modelValue","placeholder","onFocus","onBlur","onSelect"])):((0,i.uX)(),(0,i.Wv)(y,{key:1,class:"inner-folder-input",modelValue:r.uploadFolder,"onUpdate:modelValue":t[1]||(t[1]=e=>r.uploadFolder=e),placeholder:e.$t("upload.folderPlaceholder"),onFocus:d.handleFolderInputFocus,onBlur:d.handleFolderInputBlur},null,8,["modelValue","placeholder","onFocus","onBlur"]))],2),d.showDirectorySuggestions?((0,i.uX)(),(0,i.Wv)(b,{key:0,"current-directory":r.uploadFolder,source:"upload",onSelect:d.handleDirectorySelect},{trigger:(0,i.k6)(()=>[(0,i.bF)(p,{class:"directory-tree-trigger"},{default:(0,i.k6)(()=>[(0,i.bF)(u,{icon:"folder-tree"})]),_:1})]),_:1},8,["current-directory","onSelect"])):(0,i.Q3)("",!0)],2),(0,i.bF)(v,{content:e.$t("upload.switchUploadMethod"),placement:"bottom",disabled:d.disableTooltip},{default:(0,i.k6)(()=>[(0,i.bF)(p,{class:"upload-method-button desktop-only",onClick:d.handleChangeUploadMethod},{default:(0,i.k6)(()=>["default"===r.uploadMethod?((0,i.uX)(),(0,i.Wv)(u,{key:0,icon:"folder-open",class:"upload-method-icon",size:"lg"})):"paste"===r.uploadMethod?((0,i.uX)(),(0,i.Wv)(u,{key:1,icon:"paste",class:"upload-method-icon",size:"lg"})):(0,i.Q3)("",!0)]),_:1},8,["onClick"])]),_:1},8,["content","disabled"]),(0,i.bF)(g,{class:"mobile-more-dropdown mobile-only",trigger:"click",onCommand:d.handleMobileMenuCommand},{dropdown:(0,i.k6)(()=>[(0,i.bF)(m,null,{default:(0,i.k6)(()=>[(0,i.bF)(h,{command:"toggleTheme"},{default:(0,i.k6)(()=>[(0,i.bF)(u,{icon:d.getThemeIcon(),style:{width:"16px","margin-right":"8px","text-align":"center"}},null,8,["icon"]),(0,i.eW)(" "+(0,a.v_)(d.getThemeText()),1)]),_:1}),(0,i.bF)(h,{command:"toggleUploadMethod"},{default:(0,i.k6)(()=>[(0,i.bF)(u,{icon:"default"===r.uploadMethod?"paste":"folder-open",style:{width:"16px","margin-right":"8px","text-align":"center"}},null,8,["icon"]),(0,i.eW)(" "+(0,a.v_)("default"===r.uploadMethod?e.$t("upload.pasteUpload"):e.$t("upload.fileUpload")),1)]),_:1}),(0,i.bF)(h,{command:"showHistory"},{default:(0,i.k6)(()=>[(0,i.bF)(u,{icon:"history",style:{width:"16px","margin-right":"8px","text-align":"center"}}),(0,i.eW)(" "+(0,a.v_)(e.$t("upload.history")),1)]),_:1}),(0,i.bF)(h,{command:"showAnnouncement",disabled:!d.announcementAvailable},{default:(0,i.k6)(()=>[(0,i.bF)(u,{icon:"bullhorn",style:{width:"16px","margin-right":"8px","text-align":"center"}}),(0,i.eW)(" "+(0,a.v_)(e.$t("upload.announcement")),1)]),_:1},8,["disabled"]),(0,i.bF)(h,{command:"toggleLanguage"},{default:(0,i.k6)(()=>[(0,i.bF)(u,{icon:"globe",style:{width:"16px","margin-right":"8px","text-align":"center"}}),(0,i.eW)(" "+(0,a.v_)("zh-CN"===e.$i18n.locale?"English":"简体中文"),1)]),_:1}),(0,i.bF)(h,{command:"viewDocs"},{default:(0,i.k6)(()=>[(0,i.bF)(u,{icon:"book",style:{width:"16px","margin-right":"8px","text-align":"center"}}),(0,i.eW)(" "+(0,a.v_)(e.$t("upload.viewDocs")),1)]),_:1})]),_:1})]),default:(0,i.k6)(()=>[(0,i.bF)(p,{class:"mobile-more-button"},{default:(0,i.k6)(()=>[(0,i.bF)(u,{icon:"ellipsis-v",size:"lg"})]),_:1})]),_:1},8,["onCommand"]),(0,i.Lk)("div",Yt,[(0,i.bF)(p,{class:(0,a.C4)(["toolbar-manage-button",{active:r.isToolBarOpen}]),size:"large",onClick:d.handleOpenToolbar,circle:""},{default:(0,i.k6)(()=>[r.isToolBarOpen?((0,i.uX)(),(0,i.Wv)(u,{key:1,icon:"times",class:"manage-icon",size:"lg"})):((0,i.uX)(),(0,i.Wv)(u,{key:0,icon:"bars",class:"manage-icon",size:"lg"}))]),_:1},8,["class","onClick"])]),(0,i.Lk)("div",Zt,[(0,i.bF)(v,{disabled:d.disableTooltip,content:e.$t("upload.settings"),placement:"top"},{default:(0,i.k6)(()=>[(0,i.bF)(p,{class:(0,a.C4)(["toolbar-button compress-button",{active:r.isToolBarOpen}]),size:"large",onClick:d.openCompressDialog,circle:""},{default:(0,i.k6)(()=>[(0,i.bF)(u,{icon:"cloud-upload",class:"compress-icon",size:"lg"})]),_:1},8,["class","onClick"])]),_:1},8,["disabled","content"]),(0,i.bF)(v,{disabled:d.disableTooltip,content:e.$t("upload.linkFormat"),placement:"left"},{default:(0,i.k6)(()=>[(0,i.bF)(p,{class:(0,a.C4)(["toolbar-button link-button",{active:r.isToolBarOpen}]),size:"large",onClick:d.openUrlDialog,circle:""},{default:(0,i.k6)(()=>[(0,i.bF)(u,{icon:"link",class:"link-icon",size:"lg"})]),_:1},8,["class","onClick"])]),_:1},8,["disabled","content"]),(0,i.bF)(v,{disabled:d.disableTooltip,content:e.$t("upload.manage"),placement:"left"},{default:(0,i.k6)(()=>[(0,i.bF)(p,{class:(0,a.C4)(["toolbar-button config-button",{active:r.isToolBarOpen}]),size:"large",onClick:d.handleManage,circle:""},{default:(0,i.k6)(()=>[(0,i.bF)(u,{icon:"cog",class:"config-icon",size:"lg"})]),_:1},8,["class","onClick"])]),_:1},8,["disabled","content"]),(0,i.bF)(v,{disabled:d.disableTooltip,content:e.$t("upload.logout"),placement:"left"},{default:(0,i.k6)(()=>[(0,i.bF)(p,{class:(0,a.C4)(["toolbar-button sign-out-button",{active:r.isToolBarOpen}]),size:"large",onClick:d.handleLogout,circle:""},{default:(0,i.k6)(()=>[(0,i.bF)(u,{icon:"sign-out-alt",class:"sign-out-icon",size:"lg"})]),_:1},8,["class","onClick"])]),_:1},8,["disabled","content"])]),(0,i.bF)(C,{useConfigLink:!0}),(0,i.Lk)("div",eo,[(0,i.Lk)("h1",to,[(0,i.Lk)("a",oo,(0,a.v_)(d.ownerName),1),t[21]||(t[21]=(0,i.eW)(" ImgHub",-1))])]),(0,i.bF)(k,{selectedUrlForm:r.selectedUrlForm,customerCompress:r.customerCompress,compressQuality:r.compressQuality,compressBar:r.compressBar,serverCompress:r.serverCompress,uploadChannel:r.uploadChannel,channelName:r.channelName,uploadNameType:r.uploadNameType,useCustomUrl:r.useCustomUrl,customUrlPrefix:r.customUrlPrefix,autoRetry:r.autoRetry,urlPrefix:d.urlPrefix,uploadMethod:r.uploadMethod,uploadFolder:r.uploadFolder,convertToWebp:r.convertToWebp,class:"upload"},null,8,["selectedUrlForm","customerCompress","compressQuality","compressBar","serverCompress","uploadChannel","channelName","uploadNameType","useCustomUrl","customUrlPrefix","autoRetry","urlPrefix","uploadMethod","uploadFolder","convertToWebp"]),(0,i.bF)(U,{title:e.$t("settings.linkFormatTitle"),modelValue:r.showUrlDialog,"onUpdate:modelValue":t[6]||(t[6]=e=>r.showUrlDialog=e),width:d.dialogWidth,"show-close":!1,class:"settings-dialog"},{default:(0,i.k6)(()=>[(0,i.Lk)("div",so,[(0,i.Lk)("div",lo,[(0,i.Lk)("span",io,(0,a.v_)(e.$t("settings.defaultCopyLink")),1)]),(0,i.Lk)("div",ao,[(0,i.bF)(F,{modelValue:r.selectedUrlForm,"onUpdate:modelValue":t[2]||(t[2]=e=>r.selectedUrlForm=e),onChange:d.changeUrlForm,class:"radio-card-group grid-2x2"},{default:(0,i.k6)(()=>[(0,i.bF)(w,{value:"url",class:"radio-card"},{default:(0,i.k6)(()=>[(0,i.bF)(u,{icon:"link",class:"radio-icon"}),(0,i.Lk)("span",null,(0,a.v_)(e.$t("settings.rawLink")),1)]),_:1}),(0,i.bF)(w,{value:"md",class:"radio-card"},{default:(0,i.k6)(()=>[(0,i.bF)(u,{icon:"code",class:"radio-icon"}),t[22]||(t[22]=(0,i.Lk)("span",null,"MarkDown",-1))]),_:1}),(0,i.bF)(w,{value:"html",class:"radio-card"},{default:(0,i.k6)(()=>[(0,i.bF)(u,{icon:"code-branch",class:"radio-icon"}),t[23]||(t[23]=(0,i.Lk)("span",null,"HTML",-1))]),_:1}),(0,i.bF)(w,{value:"ubb",class:"radio-card"},{default:(0,i.k6)(()=>[(0,i.bF)(u,{icon:"quote-right",class:"radio-icon"}),t[24]||(t[24]=(0,i.Lk)("span",null,"BBCode",-1))]),_:1})]),_:1},8,["modelValue","onChange"])])]),(0,i.Lk)("div",no,[(0,i.Lk)("div",ro,[(0,i.Lk)("span",co,(0,a.v_)(e.$t("settings.customLink")),1),(0,i.bF)(v,{content:e.$t("settings.customLinkTooltip"),placement:"top","raw-content":""},{default:(0,i.k6)(()=>[(0,i.bF)(u,{icon:"question-circle",class:"section-help-icon"})]),_:1},8,["content"])]),(0,i.Lk)("div",uo,[(0,i.Lk)("div",po,[(0,i.Lk)("span",ho,(0,a.v_)(e.$t("settings.enableCustom")),1),(0,i.bF)(L,{modelValue:r.useCustomUrl,"onUpdate:modelValue":t[3]||(t[3]=e=>r.useCustomUrl=e),"active-value":"true","inactive-value":"false"},null,8,["modelValue"])]),"true"===r.useCustomUrl?((0,i.uX)(),(0,i.CE)("div",mo,[(0,i.Lk)("span",go,(0,a.v_)(e.$t("settings.customPrefix")),1),(0,i.bF)(y,{modelValue:r.customUrlPrefix,"onUpdate:modelValue":t[4]||(t[4]=e=>r.customUrlPrefix=e),placeholder:e.$t("settings.customPrefixPlaceholder"),class:"setting-input"},null,8,["modelValue","placeholder"])])):(0,i.Q3)("",!0)])]),(0,i.Lk)("div",fo,[(0,i.bF)(p,{type:"primary",onClick:t[5]||(t[5]=e=>r.showUrlDialog=!1),class:"confirm-btn"},{default:(0,i.k6)(()=>[(0,i.eW)((0,a.v_)(e.$t("settings.confirm")),1)]),_:1})])]),_:1},8,["title","modelValue","width"]),(0,i.bF)($,{modelValue:r.showCompressDialog,"onUpdate:modelValue":t[7]||(t[7]=e=>r.showCompressDialog=e),uploadChannel:r.uploadChannel,"onUpdate:uploadChannel":t[8]||(t[8]=e=>r.uploadChannel=e),channelName:r.channelName,"onUpdate:channelName":t[9]||(t[9]=e=>r.channelName=e),currentChannelList:d.currentChannelList,uploadFolder:r.uploadFolder,"onUpdate:uploadFolder":t[10]||(t[10]=e=>r.uploadFolder=e),autoRetry:r.autoRetry,"onUpdate:autoRetry":t[11]||(t[11]=e=>r.autoRetry=e),uploadNameType:r.uploadNameType,"onUpdate:uploadNameType":t[12]||(t[12]=e=>r.uploadNameType=e),convertToWebp:r.convertToWebp,"onUpdate:convertToWebp":t[13]||(t[13]=e=>r.convertToWebp=e),customerCompress:r.customerCompress,"onUpdate:customerCompress":t[14]||(t[14]=e=>r.customerCompress=e),compressBar:r.compressBar,"onUpdate:compressBar":t[15]||(t[15]=e=>r.compressBar=e),compressQuality:r.compressQuality,"onUpdate:compressQuality":t[16]||(t[16]=e=>r.compressQuality=e),serverCompress:r.serverCompress,"onUpdate:serverCompress":t[17]||(t[17]=e=>r.serverCompress=e)},null,8,["modelValue","uploadChannel","channelName","currentChannelList","uploadFolder","autoRetry","uploadNameType","convertToWebp","customerCompress","compressBar","compressQuality","serverCompress"])]),(0,i.bF)(S,{class:"footer"}),(0,i.bF)(U,{title:e.$t("upload.announcementTitle"),modelValue:r.showAnnouncementDialog,"onUpdate:modelValue":t[19]||(t[19]=e=>r.showAnnouncementDialog=e),width:d.dialogWidth,"show-close":!1,"close-on-click-modal":!1,"close-on-press-escape":!1,center:""},{footer:(0,i.k6)(()=>[(0,i.Lk)("span",bo,[(0,i.bF)(p,{type:"primary",onClick:t[18]||(t[18]=e=>r.showAnnouncementDialog=!1)},{default:(0,i.k6)(()=>[(0,i.eW)((0,a.v_)(e.$t("upload.announcementAck")),1)]),_:1})])]),default:(0,i.k6)(()=>[(0,i.Lk)("div",{innerHTML:r.announcementContent},null,8,yo)]),_:1},8,["title","modelValue","width"]),(0,i.bF)(T,{show:r.showHistory,onClose:t[20]||(t[20]=e=>r.showHistory=!1)},null,8,["show"])])}o(13579);var Co=o(46638),ko=o(48903),wo=o(90144),Fo=o(62388),Lo={name:"UploadHome",mixins:[ko.A],data(){return{selectedUrlForm:(0,wo.KR)(""),showUrlDialog:!1,showCompressDialog:!1,customerCompress:!0,compressQuality:4,compressBar:5,convertToWebp:!1,serverCompress:!0,uploadChannel:"",channelName:"",availableChannels:{},uploadNameType:"",customUrlPrefix:"",useCustomUrl:"false",autoRetry:!0,useDefaultWallPaper:!1,isToolBarOpen:!1,uploadMethod:"default",uploadFolder:"",isFolderInputActive:!1,showAnnouncementDialog:!1,announcementContent:"",showHistory:!1,themeMode:"auto"}},watch:{customerCompress(e){this.updateCompressConfig("customerCompress",e)},compressQuality(e){this.updateCompressConfig("compressQuality",e)},compressBar(e){null===e||void 0===e||e<1?this.compressBar=1:(this.compressQuality>e&&(this.compressQuality=e),this.updateCompressConfig("compressBar",e))},serverCompress(e){this.updateCompressConfig("serverCompress",e)},convertToWebp(e){this.updateCompressConfig("convertToWebp",e)},uploadChannel(e){this.updateStoreUploadChannel(e);const t=this.availableChannels[e]||[],o=this.storeChannelName;o&&t.some(e=>e.name===o)?this.channelName=o:this.channelName=""},channelName(e){this.$store.commit("setStoreChannelName",e||"")},uploadNameType(e){this.updateStoreUploadNameType(e)},customUrlPrefix(e){this.$store.commit("setCustomUrlSettings",{key:"customUrlPrefix",value:e})},useCustomUrl(e){this.$store.commit("setCustomUrlSettings",{key:"useCustomUrl",value:e})},autoRetry(e){this.$store.commit("setStoreAutoRetry",e)},uploadFolder(e){if(this.validateUploadFolder(e,!1)){const t=(0,Fo.G)(e,{strict:!0});t.valid&&this.$store.commit("setStoreUploadFolder",e)}else this.$nextTick(()=>{this.uploadFolder=this.storeUploadFolder})}},computed:{...(0,$t.L8)(["userConfig","uploadCopyUrlForm","compressConfig","storeUploadChannel","storeChannelName","storeUploadNameType","customUrlSettings","storeAutoRetry","storeUploadMethod","storeUploadFolder"]),ownerName(){return this.userConfig?.ownerName||"Sanyue"},dialogWidth(){return window.innerWidth>768?"50%":"90%"},disableTooltip(){return window.innerWidth<768},urlPrefix(){return this.userConfig?.urlPrefix||`${window.location.protocol}//${window.location.host}/file/`},announcementAvailable(){return!!this.userConfig?.announcement},showDirectorySuggestions(){return this.userConfig?.showDirectorySuggestions??!1},currentChannelList(){return this.availableChannels[this.uploadChannel]||[]}},mounted(){this.initializeBackground("uploadBkImg",".container",!1,!0),this.selectedUrlForm=this.uploadCopyUrlForm||"url",this.customerCompress=this.compressConfig.customerCompress??this.parseBoolean(this.userConfig?.defaultCustomerCompress,!0),this.compressQuality=this.compressConfig.compressQuality??this.parseNumber(this.userConfig?.defaultCompressQuality,4),this.compressBar=this.compressConfig.compressBar??this.parseNumber(this.userConfig?.defaultCompressBar,5),this.serverCompress=this.compressConfig.serverCompress??!0,this.convertToWebp=this.compressConfig.convertToWebp??this.parseBoolean(this.userConfig?.defaultConvertToWebp,!1),this.uploadChannel=this.storeUploadChannel||this.userConfig?.defaultUploadChannel||"telegram",this.autoRetry=this.storeAutoRetry,this.uploadNameType=this.storeUploadNameType||this.userConfig?.defaultUploadNameType||"default",this.customUrlPrefix=this.customUrlSettings.customUrlPrefix,this.useCustomUrl=this.customUrlSettings.useCustomUrl,this.uploadMethod=this.storeUploadMethod,this.fetchAvailableChannels(),this.uploadFolder=this.storeUploadFolder||this.userConfig?.defaultUploadFolder||"";const e=this.$store.getters.cusDarkMode,t=this.$store.getters.useDarkMode;this.themeMode=e?t?"dark":"light":"auto";const o=localStorage.getItem("visitedUploadHome"),s=this.userConfig?.announcement;!o&&s&&(this.announcementContent=s,this.showAnnouncementDialog=!0,localStorage.setItem("visitedUploadHome","true"))},components:{UploadForm:Nt,Footer:X.A,ToggleDark:Gt.A,Logo:Pt.A,UploadHistory:H,UploadSettingsDialog:We,DirectoryTreePicker:Vt.A,DirectorySuggestionInput:qt},methods:{async fetchAvailableChannels(){try{const e=await Lt.A.get("/api/channels",{withAuthCode:!0});if(e.data){this.availableChannels=e.data;const t=this.storeChannelName,o=this.userConfig?.defaultChannelName,s=this.availableChannels[this.uploadChannel]||[];t&&s.some(e=>e.name===t)?this.channelName=t:""!==t&&null!==t&&void 0!==t||""!==t&&o&&s.some(e=>e.name===o)&&(this.channelName=o)}}catch(e){console.error("Failed to fetch available channels:",e)}},validateUploadFolder(e,t=!0){e&&!e.startsWith("/")&&(e="/"+e,this.uploadFolder=e);const o=(0,Fo.G)(e,{strict:t});return!!o.valid||(this.$message.error(o.error),!1)},handleFolderInputFocus(){this.isFolderInputActive=!0},handleFolderInputBlur(){this.isFolderInputActive=!1,this.uploadFolder&&!this.uploadFolder.startsWith("/")&&(this.uploadFolder="/"+this.uploadFolder),this.validateUploadFolder(this.uploadFolder,!0)||this.$nextTick(()=>{this.uploadFolder=this.storeUploadFolder})},handleManage(){this.$router.push("/dashboard")},parseBoolean(e,t){return void 0===e||null===e?t:"boolean"===typeof e?e:"string"===typeof e?"true"===e:t},parseNumber(e,t){if(void 0===e||null===e)return t;const o=parseFloat(e);return isNaN(o)?t:o},openUrlDialog(){this.showUrlDialog=!0},handleLogout(){Lt.A.post("/api/auth/logout",{authType:"user"},{withCredentials:!0}).finally(()=>{this.$store.commit("setUserLoggedIn",!1),this.$router.push("/login"),this.$message.success(this.$t("upload.logoutSuccess"))})},changeUrlForm(){this.$store.commit("setUploadCopyUrlForm",this.selectedUrlForm)},openCompressDialog(){this.showCompressDialog=!0},updateCompressConfig(e,t){this.$store.commit("setCompressConfig",{key:e,value:t})},updateStoreUploadChannel(e){this.$store.commit("setStoreUploadChannel",e)},updateStoreUploadNameType(e){this.$store.commit("setStoreUploadNameType",e)},handleOpenToolbar(){this.isToolBarOpen=!this.isToolBarOpen,setTimeout(()=>{const e=document.querySelectorAll(".toolbar-button");e.forEach(e=>{e.style.pointerEvents=this.isToolBarOpen?"auto":"none"})},300)},handleChangeUploadMethod(){this.uploadMethod="default"===this.uploadMethod?"paste":"default",this.$store.commit("setUploadMethod",this.uploadMethod)},handleMobileMenuCommand(e){if("toggleTheme"===e)"auto"===this.themeMode?(this.themeMode="light",this.$store.commit("setCusDarkMode",!0),this.$store.commit("setUseDarkMode",!1)):"light"===this.themeMode?(this.themeMode="dark",this.$store.commit("setCusDarkMode",!0),this.$store.commit("setUseDarkMode",!0)):(this.themeMode="auto",this.$store.commit("setCusDarkMode",!1));else if("toggleUploadMethod"===e)this.handleChangeUploadMethod();else if("viewDocs"===e)window.open("https://cfbed.sanyue.de/qa/","_blank");else if("showHistory"===e)this.showHistory=!0;else if("showAnnouncement"===e)this.handleShowAnnouncement();else if("toggleLanguage"===e){const e="zh-CN"===this.$i18n.locale?"en":"zh-CN";(0,Co.xS)(e)}},handleDesktopMenuCommand(e){if("viewDocs"===e)window.open("https://cfbed.sanyue.de/qa/","_blank");else if("showHistory"===e)this.showHistory=!0;else if("showAnnouncement"===e)this.handleShowAnnouncement();else if("toggleLanguage"===e){const e="zh-CN"===this.$i18n.locale?"en":"zh-CN";(0,Co.xS)(e)}},getThemeIcon(){return"auto"===this.themeMode?"sun":"light"===this.themeMode?"moon":"adjust"},getThemeText(){return"auto"===this.themeMode?this.$t("theme.lightMode"):"light"===this.themeMode?this.$t("theme.darkMode"):this.$t("theme.autoMode")},handleShowAnnouncement(){const e=this.userConfig?.announcement;e?(this.announcementContent=e,this.showAnnouncementDialog=!0):this.$message.info(this.$t("upload.noAnnouncement"))},handleDirectorySelect(e){this.uploadFolder=e,this.validateUploadFolder(e,!0)&&this.$store.commit("setStoreUploadFolder",e)}}};const Uo=(0,z.A)(Lo,[["render",vo],["__scopeId","data-v-f50dcc42"]]);var $o=Uo}}]); //# sourceMappingURL=577.2c9dad30.js.map \ No newline at end of file diff --git a/frontend-dist/js/577.2c9dad30.js.gz b/frontend-dist/js/577.2c9dad30.js.gz index b2763c15..bc2dab12 100644 Binary files a/frontend-dist/js/577.2c9dad30.js.gz and b/frontend-dist/js/577.2c9dad30.js.gz differ diff --git a/functions/api/channels.js b/functions/api/channels.js index 1f8f4d4f..0243c1cd 100644 --- a/functions/api/channels.js +++ b/functions/api/channels.js @@ -55,6 +55,10 @@ export async function onRequest(context) { huggingface: uploadConfig.huggingface.channels.map(ch => ({ name: ch.name, type: 'HuggingFace' + })), + webdav: uploadConfig.webdav.channels.map(ch => ({ + name: ch.name, + type: 'WebDAV' })) }; diff --git a/functions/api/manage/delete/[[path]].js b/functions/api/manage/delete/[[path]].js index 64a84479..865e0002 100644 --- a/functions/api/manage/delete/[[path]].js +++ b/functions/api/manage/delete/[[path]].js @@ -4,6 +4,8 @@ import { removeFileFromIndex, batchRemoveFilesFromIndex } from "../../../utils/i import { getDatabase } from '../../../utils/databaseAdapter.js'; import { DiscordAPI } from '../../../utils/discordAPI.js'; import { HuggingFaceAPI } from '../../../utils/huggingfaceAPI.js'; +import { WebDAVAPI } from '../../../utils/webdavAPI.js'; +import { resolveWebDAVConfig } from '../../../utils/webdavConfig.js'; // CORS 跨域响应头 const corsHeaders = { @@ -156,6 +158,11 @@ async function deleteFile(env, fileId, cdnUrl, url) { await deleteHuggingFaceFile(img); } + // WebDAV 渠道的图片,需要删除 WebDAV 中对应的文件 + if (img.metadata?.Channel === 'WebDAV') { + await deleteWebDAVFile(env, img); + } + // 删除数据库中的记录 // 注意:容量统计现在由索引自动维护,删除文件后索引更新时会自动重新计算 await db.delete(fileId); @@ -251,3 +258,28 @@ async function deleteHuggingFaceFile(img) { return false; } } + + +// 删除 WebDAV 渠道的图片 +async function deleteWebDAVFile(env, img) { + const filePath = img.metadata?.WebDAVFilePath; + + if (!filePath) { + console.warn('WebDAV file missing required metadata for deletion'); + return false; + } + + try { + const webdavConfig = await resolveWebDAVConfig(env, img.metadata); + if (!webdavConfig) { + console.warn('WebDAV channel config not found for deletion'); + return false; + } + + const webdavAPI = new WebDAVAPI(webdavConfig); + return await webdavAPI.deleteFile(filePath); + } catch (error) { + console.error("WebDAV Delete Failed:", error); + return false; + } +} diff --git a/functions/api/manage/move/[[path]].js b/functions/api/manage/move/[[path]].js index 8d9c4f3f..28f69ca6 100644 --- a/functions/api/manage/move/[[path]].js +++ b/functions/api/manage/move/[[path]].js @@ -3,6 +3,8 @@ import { purgeCFCache, purgeRandomFileListCache, purgePublicFileListCache } from import { moveFileInIndex, batchMoveFilesInIndex } from "../../../utils/indexManager.js"; import { getDatabase } from '../../../utils/databaseAdapter.js'; import { sanitizeUploadFolder } from "../../../upload/uploadTools.js"; +import { WebDAVAPI } from "../../../utils/webdavAPI.js"; +import { resolveWebDAVConfig } from "../../../utils/webdavConfig.js"; export async function onRequest(context) { const { request, env, params, waitUntil } = context; @@ -161,6 +163,23 @@ async function moveFile(env, fileId, newFileId, cdnUrl, url) { } } + // WebDAV 渠道的图片,需要移动 WebDAV 中对应的文件 + if (img.metadata?.Channel === 'WebDAV') { + const { success, error, webdavConfig } = await moveWebDAVFile(env, img, newFileId); + if (!success) { + throw new Error(error || 'WebDAV Move Failed'); + } + img.metadata.WebDAVFilePath = newFileId; + if (img.metadata.WebDAVPublicBaseUrl || img.metadata.WebDAVPublicUrl || webdavConfig?.publicUrl) { + const webdavAPI = new WebDAVAPI(webdavConfig || { baseUrl: img.metadata.WebDAVBaseUrl }); + const publicBaseUrl = img.metadata.WebDAVPublicBaseUrl + || webdavConfig?.publicUrl + || img.metadata.WebDAVPublicUrl.slice(0, img.metadata.WebDAVPublicUrl.length - fileId.split('/').map(encodeURIComponent).join('/').length); + img.metadata.WebDAVPublicBaseUrl = publicBaseUrl; + img.metadata.WebDAVPublicUrl = webdavAPI.buildPublicUrl(newFileId, publicBaseUrl); + } + } + // 旧版 Telegram 渠道和 Telegraph 渠道不支持移动 if (img.metadata?.Channel === 'Telegram' || img.metadata?.Channel === undefined) { throw new Error('Unsupported Channel'); @@ -226,4 +245,27 @@ async function moveS3File(img, newFileId) { console.error("S3 Move Failed:", error); return { success: false, error: error.message }; } -} \ No newline at end of file +} + +// 移动 WebDAV 渠道的图片 +async function moveWebDAVFile(env, img, newFileId) { + const oldPath = img.metadata?.WebDAVFilePath; + + if (!oldPath) { + return { success: false, error: 'WebDAV file missing required metadata for move' }; + } + + try { + const webdavConfig = await resolveWebDAVConfig(env, img.metadata); + if (!webdavConfig) { + return { success: false, error: 'WebDAV channel config not found for move' }; + } + + const webdavAPI = new WebDAVAPI(webdavConfig); + await webdavAPI.moveFile(oldPath, newFileId, true); + return { success: true, newKey: newFileId, webdavConfig }; + } catch (error) { + console.error("WebDAV Move Failed:", error); + return { success: false, error: error.message }; + } +} diff --git a/functions/api/manage/rename/[[path]].js b/functions/api/manage/rename/[[path]].js index 297a8553..c4301db3 100644 --- a/functions/api/manage/rename/[[path]].js +++ b/functions/api/manage/rename/[[path]].js @@ -3,6 +3,8 @@ import { purgeCFCache, purgeRandomFileListCache, purgePublicFileListCache } from import { moveFileInIndex } from "../../../utils/indexManager.js"; import { getDatabase } from '../../../utils/databaseAdapter.js'; import { sanitizeUploadFolder } from "../../../upload/uploadTools.js"; +import { WebDAVAPI } from "../../../utils/webdavAPI.js"; +import { resolveWebDAVConfig } from "../../../utils/webdavConfig.js"; // CORS 跨域响应头 const corsHeaders = { @@ -138,6 +140,23 @@ export async function onRequest(context) { } } + // WebDAV 渠道的图片,需要移动 WebDAV 中对应的文件 + if (metadata?.Channel === 'WebDAV') { + const { success, error, webdavConfig } = await moveWebDAVFile(env, fileData, newFileId); + if (!success) { + throw new Error(error || 'WebDAV Move Failed'); + } + metadata.WebDAVFilePath = newFileId; + if (metadata.WebDAVPublicBaseUrl || metadata.WebDAVPublicUrl || webdavConfig?.publicUrl) { + const webdavAPI = new WebDAVAPI(webdavConfig || { baseUrl: metadata.WebDAVBaseUrl }); + const publicBaseUrl = metadata.WebDAVPublicBaseUrl + || webdavConfig?.publicUrl + || metadata.WebDAVPublicUrl.slice(0, metadata.WebDAVPublicUrl.length - fileId.split('/').map(encodeURIComponent).join('/').length); + metadata.WebDAVPublicBaseUrl = publicBaseUrl; + metadata.WebDAVPublicUrl = webdavAPI.buildPublicUrl(newFileId, publicBaseUrl); + } + } + // 旧版 Telegram 渠道和 Telegraph 渠道不支持重命名 if (metadata?.Channel === 'Telegram' || metadata?.Channel === undefined) { return new Response(JSON.stringify({ @@ -228,3 +247,26 @@ async function moveS3File(img, newFileId) { return { success: false, error: error.message }; } } + +// 移动 WebDAV 渠道的图片 +async function moveWebDAVFile(env, img, newFileId) { + const oldPath = img.metadata?.WebDAVFilePath; + + if (!oldPath) { + return { success: false, error: 'WebDAV file missing required metadata for move' }; + } + + try { + const webdavConfig = await resolveWebDAVConfig(env, img.metadata); + if (!webdavConfig) { + return { success: false, error: 'WebDAV channel config not found for move' }; + } + + const webdavAPI = new WebDAVAPI(webdavConfig); + await webdavAPI.moveFile(oldPath, newFileId, true); + return { success: true, newKey: newFileId, webdavConfig }; + } catch (error) { + console.error("WebDAV Move Failed:", error); + return { success: false, error: error.message }; + } +} diff --git a/functions/api/manage/sysConfig/page.js b/functions/api/manage/sysConfig/page.js index 73512268..bc1194e0 100644 --- a/functions/api/manage/sysConfig/page.js +++ b/functions/api/manage/sysConfig/page.js @@ -152,6 +152,7 @@ export async function getPageConfig(db, env) { { label: 'S3', value: 's3' }, { label: 'Discord', value: 'discord' }, { label: 'HuggingFace', value: 'huggingface' }, + { label: 'WebDAV', value: 'webdav' }, ], placeholder: 'telegram', category: '客户端设置', @@ -315,4 +316,4 @@ export async function getPageConfig(db, env) { } return settings -} \ No newline at end of file +} diff --git a/functions/api/manage/sysConfig/upload.js b/functions/api/manage/sysConfig/upload.js index e26814ea..c2b58172 100644 --- a/functions/api/manage/sysConfig/upload.js +++ b/functions/api/manage/sysConfig/upload.js @@ -1,4 +1,5 @@ import { getDatabase } from '../../../utils/databaseAdapter.js'; +import { normalizeWebDAVHeaders } from '../../../utils/webdavAPI.js'; export async function onRequest(context) { // 上传设置相关,GET方法读取设置,POST方法保存设置 @@ -28,6 +29,14 @@ export async function onRequest(context) { if (request.method === 'POST') { const body = await request.json() const settings = body + // 兼容旧前端包:如果旧包尚未提交 webdav 配置,保留已有 WebDAV 渠道,避免保存其他上传设置时被清空。 + if (settings.webdav === undefined) { + const existingSettingsStr = await db.get('manage@sysConfig@upload') + const existingSettings = existingSettingsStr ? JSON.parse(existingSettingsStr) : {} + if (existingSettings.webdav !== undefined) { + settings.webdav = existingSettings.webdav + } + } // 写入数据库 await db.put('manage@sysConfig@upload', JSON.stringify(settings)) @@ -264,11 +273,63 @@ export async function getUploadConfig(db, env) { huggingface.loadBalance = huggingfaceLoadBalance + // =====================读取 WebDAV 渠道配置===================== + const webdav = {} + const webdavChannels = [] + webdav.channels = webdavChannels + + // 从环境变量读取 WebDAV 配置 + if (env.WEBDAV_BASE_URL) { + webdavChannels.push({ + id: 1, + name: 'WebDAV_env', + type: 'webdav', + savePath: 'environment variable', + baseUrl: env.WEBDAV_BASE_URL, + username: env.WEBDAV_USERNAME || '', + password: env.WEBDAV_PASSWORD || '', + publicUrl: env.WEBDAV_PUBLIC_URL || '', + headers: normalizeWebDAVHeaders(env.WEBDAV_HEADERS || {}), + createDirectory: env.WEBDAV_CREATE_DIRECTORY !== 'false', + enabled: true, + fixed: true, + }) + } + + for (const wd of settingsKV.webdav?.channels || []) { + // 如果 savePath 是 environment variable,修改可变参数 + if (wd.savePath === 'environment variable') { + // 如果环境变量未删除,进行覆盖操作 + if (webdavChannels[0]) { + webdavChannels[0].enabled = wd.enabled + webdavChannels[0].publicUrl = wd.publicUrl || webdavChannels[0].publicUrl + webdavChannels[0].headers = normalizeWebDAVHeaders(wd.headers || wd.customHeaders || webdavChannels[0].headers) + webdavChannels[0].createDirectory = wd.createDirectory !== false + webdavChannels[0].quota = wd.quota + } + continue + } + // id 自增 + wd.id = webdavChannels.length + 1 + wd.headers = normalizeWebDAVHeaders(wd.headers || wd.customHeaders || {}) + wd.createDirectory = wd.createDirectory !== false + webdavChannels.push(wd) + } + + // 负载均衡 + const webdavLoadBalance = settingsKV.webdav?.loadBalance || { + enabled: false, + channels: [], + } + webdav.loadBalance = webdavLoadBalance + + settings.telegram = telegram settings.cfr2 = cfr2 settings.s3 = s3 settings.discord = discord settings.huggingface = huggingface + settings.webdav = webdav return settings; -} \ No newline at end of file +} diff --git a/functions/file/[[path]].js b/functions/file/[[path]].js index 3cd2cea3..204c3fc9 100644 --- a/functions/file/[[path]].js +++ b/functions/file/[[path]].js @@ -3,6 +3,8 @@ import { fetchSecurityConfig } from "../utils/sysConfig"; import { TelegramAPI } from "../utils/telegramAPI"; import { DiscordAPI } from "../utils/discordAPI"; import { HuggingFaceAPI } from "../utils/huggingfaceAPI"; +import { WebDAVAPI } from "../utils/webdavAPI"; +import { resolveWebDAVConfig } from "../utils/webdavConfig"; import { setCommonHeaders, setRangeHeaders, handleHeadRequest, getFileContent, isTgChannel, returnWithCheck, return404, returnBlockImg, isDomainAllowed @@ -90,6 +92,11 @@ export async function onRequest(context) { // Contents of context object return await handleHuggingFaceFile(context, imgRecord.metadata, encodedFileName, fileType); } + /* WebDAV 渠道 */ + if (imgRecord.metadata?.Channel === 'WebDAV') { + return await handleWebDAVFile(context, imgRecord.metadata, encodedFileName, fileType); + } + /* 外链渠道 */ if (imgRecord.metadata?.Channel === 'External') { // 直接重定向到外链 @@ -891,3 +898,74 @@ async function handleHuggingFaceFile(context, metadata, encodedFileName, fileTyp return new Response(`Error: Failed to fetch from HuggingFace - ${error.message}`, { status: 500 }); } } + + +// 处理 WebDAV 文件读取 +async function handleWebDAVFile(context, metadata, encodedFileName, fileType) { + const { request, url, Referer } = context; + + try { + const filePath = metadata.WebDAVFilePath; + const publicUrl = metadata.WebDAVPublicUrl; + + if (!filePath && !publicUrl) { + return new Response('Error: WebDAV file info not found', { status: 500 }); + } + + const headers = new Headers(); + setCommonHeaders(headers, encodedFileName, fileType, Referer, url); + + const fetchHeaders = {}; + const range = request.headers.get('Range'); + if (range) { + fetchHeaders['Range'] = range; + } + + let response; + if (publicUrl) { + response = await fetch(publicUrl, { + method: request.method === 'HEAD' ? 'HEAD' : 'GET', + headers: fetchHeaders, + }); + } else { + const webdavConfig = await resolveWebDAVConfig(context.env, metadata); + if (!webdavConfig) { + return new Response('Error: WebDAV channel config not found', { status: 500 }); + } + + const webdavAPI = new WebDAVAPI(webdavConfig); + response = await webdavAPI.getFile(filePath, { + method: request.method === 'HEAD' ? 'HEAD' : 'GET', + headers: fetchHeaders, + }); + } + + if (!response.ok && response.status !== 206 && response.status !== 304) { + return new Response(`Error: Failed to fetch from WebDAV - ${response.status}`, { status: response.status }); + } + + if (response.headers.get('Content-Length')) { + headers.set('Content-Length', response.headers.get('Content-Length')); + } + if (response.headers.get('Content-Range')) { + headers.set('Content-Range', response.headers.get('Content-Range')); + } + if (response.headers.get('ETag')) { + headers.set('ETag', response.headers.get('ETag')); + } + if (response.status === 304) { + return new Response(null, { status: 304, headers }); + } + if (request.method === 'HEAD') { + return handleHeadRequest(headers, response.headers.get('ETag')); + } + + return new Response(response.body, { + status: response.status, + headers + }); + + } catch (error) { + return new Response(`Error: Failed to fetch from WebDAV - ${error.message}`, { status: 500 }); + } +} diff --git a/functions/upload/chunkMerge.js b/functions/upload/chunkMerge.js index d2ea1d20..e5693c32 100644 --- a/functions/upload/chunkMerge.js +++ b/functions/upload/chunkMerge.js @@ -46,6 +46,9 @@ export async function handleChunkMerge(context) { // 使用会话中的上传渠道,或者从URL参数获取 uploadChannel = url.searchParams.get('uploadChannel') || sessionInfo.uploadChannel || 'telegram'; + if (uploadChannel === 'webdav') { + return createResponse('Error: WebDAV channel does not support chunked uploads. Please use non-chunked upload within your Cloudflare request body limit.', { status: 400 }); + } // 获取指定的渠道名称(优先URL参数,其次会话信息) const channelName = url.searchParams.get('channelName') || sessionInfo.channelName || ''; diff --git a/functions/upload/chunkUpload.js b/functions/upload/chunkUpload.js index 6ebc12bc..e81ecb44 100644 --- a/functions/upload/chunkUpload.js +++ b/functions/upload/chunkUpload.js @@ -33,6 +33,9 @@ export async function initializeChunkedUpload(context) { // 获取上传渠道 const uploadChannel = url.searchParams.get('uploadChannel') || 'telegram'; + if (uploadChannel === 'webdav') { + return createResponse('Error: WebDAV channel does not support chunked uploads. Please use non-chunked upload within your Cloudflare request body limit.', { status: 400 }); + } // 获取指定的渠道名称 const channelName = url.searchParams.get('channelName') || ''; @@ -121,6 +124,9 @@ export async function handleChunkUpload(context) { // 获取上传渠道 const uploadChannel = url.searchParams.get('uploadChannel') || sessionInfo.uploadChannel || 'telegram'; + if (uploadChannel === 'webdav') { + return createResponse('Error: WebDAV channel does not support chunked uploads. Please use non-chunked upload within your Cloudflare request body limit.', { status: 400 }); + } // 获取指定的渠道名称 const channelName = url.searchParams.get('channelName') || sessionInfo.channelName || ''; diff --git a/functions/upload/index.js b/functions/upload/index.js index bb6ee7ff..b28133cf 100644 --- a/functions/upload/index.js +++ b/functions/upload/index.js @@ -10,6 +10,7 @@ import { handleChunkMerge } from "./chunkMerge"; import { TelegramAPI } from "../utils/telegramAPI"; import { DiscordAPI } from "../utils/discordAPI"; import { HuggingFaceAPI } from "../utils/huggingfaceAPI"; +import { WebDAVAPI } from "../utils/webdavAPI"; import { S3Client, PutObjectCommand } from "@aws-sdk/client-s3"; import { getDatabase } from '../utils/databaseAdapter.js'; @@ -115,6 +116,9 @@ async function processFileUpload(context, formdata = null) { case 'huggingface': uploadChannel = 'HuggingFace'; break; + case 'webdav': + uploadChannel = 'WebDAV'; + break; case 'external': uploadChannel = 'External'; break; @@ -234,6 +238,14 @@ async function processFileUpload(context, formdata = null) { } else { err = await res.text(); } + } else if (uploadChannel === 'WebDAV') { + // ---------------------WebDAV 渠道------------------ + const res = await uploadFileToWebDAV(context, fullId, metadata, returnLink); + if (res.status === 200 || !autoRetry) { + return res; + } else { + err = await res.text(); + } } else if (uploadChannel === 'External') { // --------------------外链渠道---------------------- const res = await uploadFileToExternal(context, fullId, metadata, returnLink); @@ -829,12 +841,95 @@ async function uploadFileToHuggingFace(context, fullId, metadata, returnLink) { } +// 上传到 WebDAV +async function uploadFileToWebDAV(context, fullId, metadata, returnLink) { + const { env, waitUntil, uploadConfig, securityConfig, url, formdata, specifiedChannelName } = context; + const db = getDatabase(env); + + const webdavSettings = uploadConfig.webdav; + if (!webdavSettings || !webdavSettings.channels || webdavSettings.channels.length === 0) { + return createResponse('Error: No WebDAV channel configured', { status: 400 }); + } + + const webdavChannels = webdavSettings.channels; + let webdavChannel; + if (specifiedChannelName) { + webdavChannel = webdavChannels.find(ch => ch.name === specifiedChannelName); + } + if (!webdavChannel) { + webdavChannel = webdavSettings.loadBalance?.enabled + ? webdavChannels[Math.floor(Math.random() * webdavChannels.length)] + : webdavChannels[0]; + } + + const baseUrl = webdavChannel?.baseUrl || webdavChannel?.endpoint || webdavChannel?.url; + if (!webdavChannel || !baseUrl) { + return createResponse('Error: WebDAV channel not properly configured', { status: 400 }); + } + + const file = formdata.get('file'); + if (!file) { + return createResponse('Error: No file provided', { status: 400 }); + } + + try { + const webdavAPI = new WebDAVAPI(webdavChannel); + await webdavAPI.putFile(fullId, file, file.type || metadata.FileType || 'application/octet-stream'); + + metadata.Channel = "WebDAV"; + metadata.ChannelName = webdavChannel.name || "WebDAV_env"; + metadata.WebDAVBaseUrl = baseUrl; + metadata.WebDAVFilePath = fullId; + if (webdavChannel.publicUrl) { + metadata.WebDAVPublicBaseUrl = webdavChannel.publicUrl; + metadata.WebDAVPublicUrl = webdavAPI.buildPublicUrl(fullId, webdavChannel.publicUrl); + } + + const uploadModerate = securityConfig.upload?.moderate; + if (uploadModerate && uploadModerate.enabled) { + if (metadata.WebDAVPublicUrl) { + metadata.Label = await moderateContent(env, metadata.WebDAVPublicUrl); + } else { + try { + await db.put(fullId, "", { metadata }); + } catch { + return createResponse('Error: Failed to write to database', { status: 500 }); + } + + const moderateUrl = `https://${url.hostname}/file/${fullId}`; + await purgeCDNCache(env, moderateUrl, url); + metadata.Label = await moderateContent(env, moderateUrl); + } + } + + try { + await db.put(fullId, "", { metadata }); + } catch { + return createResponse('Error: Failed to write to database', { status: 500 }); + } + + waitUntil(endUpload(context, fullId, metadata)); + + return createResponse( + JSON.stringify([{ 'src': returnLink }]), + { + status: 200, + headers: { 'Content-Type': 'application/json' } + } + ); + } catch (error) { + console.error('WebDAV upload error:', error.message); + return createResponse(`Error: WebDAV upload failed - ${error.message}`, { status: 500 }); + } +} + + // 自动切换渠道重试 async function tryRetry(err, context, uploadChannel, fullId, metadata, fileExt, fileName, fileType, returnLink) { const { env, url, formdata } = context; // 渠道列表(Discord 因为有 10MB 限制,放在最后尝试) - const channelList = ['CloudflareR2', 'TelegramNew', 'S3', 'HuggingFace', 'Discord']; + const channelList = ['CloudflareR2', 'TelegramNew', 'S3', 'HuggingFace', 'WebDAV', 'Discord']; const errMessages = {}; errMessages[uploadChannel] = 'Error: ' + uploadChannel + err; @@ -849,6 +944,8 @@ async function tryRetry(err, context, uploadChannel, fullId, metadata, fileExt, retryRes = await uploadFileToS3(context, fullId, metadata, returnLink); } else if (uploadChannel === 'HuggingFace') { retryRes = await uploadFileToHuggingFace(context, fullId, metadata, returnLink); + } else if (uploadChannel === 'WebDAV') { + retryRes = await uploadFileToWebDAV(context, fullId, metadata, returnLink); } else if (uploadChannel === 'Discord') { retryRes = await uploadFileToDiscord(context, fullId, metadata, returnLink); } @@ -872,6 +969,8 @@ async function tryRetry(err, context, uploadChannel, fullId, metadata, fileExt, res = await uploadFileToS3(context, fullId, metadata, returnLink); } else if (channelList[i] === 'HuggingFace') { res = await uploadFileToHuggingFace(context, fullId, metadata, returnLink); + } else if (channelList[i] === 'WebDAV') { + res = await uploadFileToWebDAV(context, fullId, metadata, returnLink); } else if (channelList[i] === 'Discord') { res = await uploadFileToDiscord(context, fullId, metadata, returnLink); } diff --git a/functions/utils/sysConfig.js b/functions/utils/sysConfig.js index 359b4957..45f2f443 100644 --- a/functions/utils/sysConfig.js +++ b/functions/utils/sysConfig.js @@ -1,7 +1,7 @@ -import { getUploadConfig } from '../api/manage/sysConfig/upload'; -import { getSecurityConfig } from '../api/manage/sysConfig/security'; -import { getPageConfig } from '../api/manage/sysConfig/page'; -import { getOthersConfig } from '../api/manage/sysConfig/others'; +import { getUploadConfig } from '../api/manage/sysConfig/upload.js'; +import { getSecurityConfig } from '../api/manage/sysConfig/security.js'; +import { getPageConfig } from '../api/manage/sysConfig/page.js'; +import { getOthersConfig } from '../api/manage/sysConfig/others.js'; import { getDatabase } from './databaseAdapter.js'; import { getIndexMeta } from './indexManager.js'; @@ -63,12 +63,14 @@ export async function fetchUploadConfig(env, context = null) { settings.s3.channels = settings.s3.channels.filter((channel) => channel.enabled); settings.discord.channels = settings.discord.channels.filter((channel) => channel.enabled); settings.huggingface.channels = settings.huggingface.channels.filter((channel) => channel.enabled); + settings.webdav.channels = settings.webdav.channels.filter((channel) => channel.enabled); - // 根据容量限制过滤渠道(仅 R2 和 S3) + // 根据容量限制过滤渠道(可用于 R2、S3、WebDAV) // 需要 context 来调用 getIndexMeta if (context) { settings.cfr2.channels = await filterChannelsByQuota(context, settings.cfr2.channels); settings.s3.channels = await filterChannelsByQuota(context, settings.s3.channels); + settings.webdav.channels = await filterChannelsByQuota(context, settings.webdav.channels); } return settings; @@ -80,7 +82,8 @@ export async function fetchUploadConfig(env, context = null) { cfr2: { channels: [] }, s3: { channels: [] }, discord: { channels: [] }, - huggingface: { channels: [] } + huggingface: { channels: [] }, + webdav: { channels: [] } }; } } @@ -130,4 +133,4 @@ export async function fetchOthersConfig(env) { telemetry: { enabled: false } }; } -} \ No newline at end of file +} diff --git a/functions/utils/webdavAPI.js b/functions/utils/webdavAPI.js new file mode 100644 index 00000000..ef060f63 --- /dev/null +++ b/functions/utils/webdavAPI.js @@ -0,0 +1,240 @@ +/** + * WebDAV API helper + * + * Uses only Fetch/Web APIs so it works in Cloudflare Pages Functions, + * Cloudflare Workers, and the local Node-based test/runtime paths. + */ +export class WebDAVAPI { + constructor(config = {}) { + const baseUrl = config.baseUrl || config.endpoint || config.url; + if (!baseUrl) { + throw new Error('WebDAV baseUrl is required'); + } + + this.baseUrl = normalizeBaseUrl(baseUrl); + this.username = config.username || ''; + this.password = config.password || ''; + this.headers = normalizeHeaders(config.headers || config.customHeaders || {}); + this.createDirectory = config.createDirectory !== false; + } + + buildObjectUrl(path) { + return buildWebDAVUrl(this.baseUrl, path); + } + + buildPublicUrl(path, publicUrl = '') { + if (!publicUrl) return ''; + return buildWebDAVUrl(normalizeBaseUrl(publicUrl), path); + } + + getRequestHeaders(extraHeaders = {}) { + const headers = new Headers(this.headers); + + if ((this.username || this.password) && !headers.has('Authorization')) { + headers.set('Authorization', `Basic ${base64EncodeUtf8(`${this.username}:${this.password}`)}`); + } + + for (const [key, value] of Object.entries(extraHeaders || {})) { + if (value !== undefined && value !== null && value !== '') { + headers.set(key, value); + } + } + + return headers; + } + + async ensureDirectory(path) { + if (!this.createDirectory) return; + + const dirParts = getDirectoryParts(path); + if (dirParts.length === 0) return; + + let currentPath = ''; + for (const part of dirParts) { + currentPath = currentPath ? `${currentPath}/${part}` : part; + const response = await fetch(this.buildObjectUrl(currentPath), { + method: 'MKCOL', + headers: this.getRequestHeaders(), + redirect: 'manual', + }); + + // 405 commonly means the collection already exists. Some servers return 200/204. + if (![200, 201, 204, 405].includes(response.status)) { + throw new Error(`WebDAV MKCOL failed for ${currentPath}: ${response.status} ${response.statusText}`); + } + } + } + + async putFile(path, body, contentType = '') { + await this.ensureDirectory(path); + + const headers = this.getRequestHeaders(contentType ? { 'Content-Type': contentType } : {}); + const response = await fetch(this.buildObjectUrl(path), { + method: 'PUT', + headers, + body, + redirect: 'manual', + }); + + if (!isSuccessStatus(response.status)) { + const detail = await safeReadResponseText(response); + throw new Error(`WebDAV PUT failed: ${response.status} ${response.statusText}${detail ? ` - ${detail}` : ''}`); + } + + return response; + } + + async getFile(path, options = {}) { + const response = await fetch(this.buildObjectUrl(path), { + method: options.method || 'GET', + headers: this.getRequestHeaders(options.headers || {}), + redirect: 'manual', + }); + + if (!isSuccessStatus(response.status) && response.status !== 304) { + const detail = await safeReadResponseText(response); + throw new Error(`WebDAV ${options.method || 'GET'} failed: ${response.status} ${response.statusText}${detail ? ` - ${detail}` : ''}`); + } + + return response; + } + + async moveFile(oldPath, newPath, overwrite = true) { + await this.ensureDirectory(newPath); + + const response = await fetch(this.buildObjectUrl(oldPath), { + method: 'MOVE', + headers: this.getRequestHeaders({ + Destination: this.buildObjectUrl(newPath), + Overwrite: overwrite ? 'T' : 'F', + }), + redirect: 'manual', + }); + + if (!isSuccessStatus(response.status)) { + const detail = await safeReadResponseText(response); + throw new Error(`WebDAV MOVE failed: ${response.status} ${response.statusText}${detail ? ` - ${detail}` : ''}`); + } + + return true; + } + + async deleteFile(path) { + const response = await fetch(this.buildObjectUrl(path), { + method: 'DELETE', + headers: this.getRequestHeaders(), + redirect: 'manual', + }); + + // DELETE is idempotent for app semantics; a missing remote object should not block DB cleanup. + if (response.status === 404) return true; + + if (!isSuccessStatus(response.status)) { + const detail = await safeReadResponseText(response); + throw new Error(`WebDAV DELETE failed: ${response.status} ${response.statusText}${detail ? ` - ${detail}` : ''}`); + } + + return true; + } +} + +export function normalizeBaseUrl(baseUrl) { + const normalized = String(baseUrl || '').trim(); + if (!normalized) { + throw new Error('WebDAV baseUrl is required'); + } + + const url = new URL(normalized); + if (!['http:', 'https:'].includes(url.protocol)) { + throw new Error('WebDAV baseUrl must use http or https'); + } + + if (!url.pathname.endsWith('/')) { + url.pathname = `${url.pathname}/`; + } + + return url.toString(); +} + +export function buildWebDAVUrl(baseUrl, path) { + const cleanPath = String(path || '') + .replace(/^\/+/, '') + .split('/') + .filter(Boolean) + .map(encodeURIComponent) + .join('/'); + + return new URL(cleanPath, normalizeBaseUrl(baseUrl)).toString(); +} + +export function normalizeWebDAVHeaders(headers) { + return normalizeHeaders(headers); +} + +function getDirectoryParts(path) { + const parts = String(path || '').replace(/^\/+/, '').split('/').filter(Boolean); + parts.pop(); + return parts; +} + +function normalizeHeaders(headers) { + if (!headers) return {}; + + if (typeof headers === 'string') { + try { + const parsed = JSON.parse(headers); + return normalizeHeaders(parsed); + } catch { + return {}; + } + } + + if (headers instanceof Headers) { + const result = {}; + headers.forEach((value, key) => { + result[key] = value; + }); + return result; + } + + if (typeof headers === 'object' && !Array.isArray(headers)) { + const result = {}; + for (const [key, value] of Object.entries(headers)) { + if (value !== undefined && value !== null && value !== '') { + result[key] = String(value); + } + } + return result; + } + + return {}; +} + +function isSuccessStatus(status) { + return status >= 200 && status < 300; +} + +async function safeReadResponseText(response) { + try { + const text = await response.text(); + return text.slice(0, 500); + } catch { + return ''; + } +} + +function base64EncodeUtf8(value) { + const bytes = new TextEncoder().encode(value); + let binary = ''; + const chunkSize = 0x8000; + for (let i = 0; i < bytes.length; i += chunkSize) { + binary += String.fromCharCode(...bytes.subarray(i, i + chunkSize)); + } + + if (typeof btoa === 'function') { + return btoa(binary); + } + + // Node-based local tests/runtimes. + return Buffer.from(value, 'utf8').toString('base64'); +} diff --git a/functions/utils/webdavConfig.js b/functions/utils/webdavConfig.js new file mode 100644 index 00000000..9ddacbff --- /dev/null +++ b/functions/utils/webdavConfig.js @@ -0,0 +1,50 @@ +import { getUploadConfig } from '../api/manage/sysConfig/upload.js'; +import { getDatabase } from './databaseAdapter.js'; +import { normalizeWebDAVHeaders } from './webdavAPI.js'; + +export async function resolveWebDAVConfig(env, metadata = {}) { + const channelName = metadata.ChannelName; + const metadataBaseUrl = metadata.WebDAVBaseUrl; + + try { + const db = getDatabase(env); + const uploadConfig = await getUploadConfig(db, env); + const channels = uploadConfig.webdav?.channels || []; + + const channel = channels.find((item) => item.name === channelName) + || channels.find((item) => getWebDAVBaseUrl(item) === metadataBaseUrl); + + if (channel) { + return normalizeWebDAVConfig(channel); + } + } catch (error) { + console.error('Failed to resolve WebDAV channel config:', error); + } + + return normalizeWebDAVConfig({ + baseUrl: metadataBaseUrl, + username: metadata.WebDAVUsername || '', + password: metadata.WebDAVPassword || '', + headers: metadata.WebDAVHeaders || {}, + createDirectory: metadata.WebDAVCreateDirectory !== false, + publicUrl: metadata.WebDAVPublicBaseUrl || '', + }); +} + +function normalizeWebDAVConfig(config = {}) { + const baseUrl = getWebDAVBaseUrl(config); + if (!baseUrl) return null; + + return { + baseUrl, + username: config.username || '', + password: config.password || '', + headers: normalizeWebDAVHeaders(config.headers || config.customHeaders || {}), + createDirectory: config.createDirectory !== false, + publicUrl: config.publicUrl || '', + }; +} + +function getWebDAVBaseUrl(config = {}) { + return config.baseUrl || config.endpoint || config.url || ''; +} diff --git a/test/webdavAPI.test.js b/test/webdavAPI.test.js new file mode 100644 index 00000000..177fb4a9 --- /dev/null +++ b/test/webdavAPI.test.js @@ -0,0 +1,92 @@ +import assert from 'node:assert/strict'; +import { WebDAVAPI, buildWebDAVUrl, normalizeBaseUrl } from '../functions/utils/webdavAPI.js'; + +describe('WebDAVAPI', () => { + let originalFetch; + let calls; + + beforeEach(() => { + originalFetch = globalThis.fetch; + calls = []; + globalThis.fetch = async (url, init = {}) => { + calls.push({ url: String(url), init }); + return new Response('ok', { status: 201, statusText: 'Created' }); + }; + }); + + afterEach(() => { + globalThis.fetch = originalFetch; + }); + + it('normalizes base URLs and encodes object paths segment-by-segment', () => { + assert.equal(normalizeBaseUrl('https://dav.example.com/root'), 'https://dav.example.com/root/'); + assert.equal( + buildWebDAVUrl('https://dav.example.com/root/', '相册/a b.png'), + 'https://dav.example.com/root/%E7%9B%B8%E5%86%8C/a%20b.png' + ); + }); + + it('creates parent collections and uploads with basic auth', async () => { + const api = new WebDAVAPI({ + baseUrl: 'https://dav.example.com/root', + username: 'user', + password: 'pass', + }); + + await api.putFile('album/photo.png', new Blob(['hello'], { type: 'image/png' }), 'image/png'); + + assert.equal(calls.length, 2); + assert.equal(calls[0].url, 'https://dav.example.com/root/album'); + assert.equal(calls[0].init.method, 'MKCOL'); + assert.equal(calls[1].url, 'https://dav.example.com/root/album/photo.png'); + assert.equal(calls[1].init.method, 'PUT'); + assert.equal(calls[1].init.headers.get('Authorization'), 'Basic dXNlcjpwYXNz'); + assert.equal(calls[1].init.headers.get('Content-Type'), 'image/png'); + }); + + it('forwards range headers when reading files', async () => { + globalThis.fetch = async (url, init = {}) => { + calls.push({ url: String(url), init }); + return new Response('partial', { status: 206, headers: { 'Content-Range': 'bytes 0-2/7' } }); + }; + + const api = new WebDAVAPI({ baseUrl: 'https://dav.example.com/root' }); + const res = await api.getFile('photo.png', { headers: { Range: 'bytes=0-2' } }); + + assert.equal(res.status, 206); + assert.equal(calls[0].init.method, 'GET'); + assert.equal(calls[0].init.headers.get('Range'), 'bytes=0-2'); + }); + + it('treats delete 404 as idempotent success', async () => { + globalThis.fetch = async (url, init = {}) => { + calls.push({ url: String(url), init }); + return new Response('missing', { status: 404 }); + }; + + const api = new WebDAVAPI({ baseUrl: 'https://dav.example.com/root' }); + assert.equal(await api.deleteFile('missing.png'), true); + assert.equal(calls[0].init.method, 'DELETE'); + }); + + it('uses WebDAV MOVE with an absolute destination URL', async () => { + const api = new WebDAVAPI({ baseUrl: 'https://dav.example.com/root' }); + + await api.moveFile('old/photo.png', 'new/photo.png'); + + assert.equal(calls[0].init.method, 'MKCOL'); + assert.equal(calls[1].init.method, 'MOVE'); + assert.equal(calls[1].init.headers.get('Destination'), 'https://dav.example.com/root/new/photo.png'); + assert.equal(calls[1].init.headers.get('Overwrite'), 'T'); + }); + + it('surfaces auth failures from providers', async () => { + globalThis.fetch = async () => new Response('auth failed', { status: 401, statusText: 'Unauthorized' }); + const api = new WebDAVAPI({ baseUrl: 'https://dav.example.com/root' }); + + await assert.rejects( + () => api.getFile('secret.png'), + /WebDAV GET failed: 401 Unauthorized - auth failed/ + ); + }); +}); diff --git a/test/webdavConfig.test.js b/test/webdavConfig.test.js new file mode 100644 index 00000000..27c6f0c0 --- /dev/null +++ b/test/webdavConfig.test.js @@ -0,0 +1,99 @@ +import assert from 'node:assert/strict'; +import { getUploadConfig } from '../functions/api/manage/sysConfig/upload.js'; +import { fetchUploadConfig } from '../functions/utils/sysConfig.js'; +import { resolveWebDAVConfig } from '../functions/utils/webdavConfig.js'; +import { onRequest as channelsOnRequest } from '../functions/api/channels.js'; + +function makeKV(initial = {}) { + const store = new Map(Object.entries(initial)); + return { + async get(key) { return store.get(key) ?? null; }, + async put(key, value) { store.set(key, value); }, + async delete(key) { store.delete(key); }, + async getWithMetadata(key) { return { value: store.get(key) ?? null, metadata: null }; }, + async list() { return { keys: [] }; }, + }; +} + +describe('WebDAV upload config', () => { + it('exposes an environment-backed fixed WebDAV channel', async () => { + const config = await getUploadConfig(makeKV(), { + WEBDAV_BASE_URL: 'https://dav.example.com/root/', + WEBDAV_USERNAME: 'alice', + WEBDAV_PASSWORD: 'secret', + WEBDAV_PUBLIC_URL: 'https://cdn.example.com/root/', + WEBDAV_HEADERS: '{"X-Test":"1"}', + WEBDAV_CREATE_DIRECTORY: 'false', + }); + + assert.equal(config.webdav.channels.length, 1); + assert.equal(config.webdav.channels[0].name, 'WebDAV_env'); + assert.equal(config.webdav.channels[0].type, 'webdav'); + assert.equal(config.webdav.channels[0].baseUrl, 'https://dav.example.com/root/'); + assert.equal(config.webdav.channels[0].headers['X-Test'], '1'); + assert.equal(config.webdav.channels[0].createDirectory, false); + assert.equal(config.webdav.channels[0].fixed, true); + }); + + it('filters disabled WebDAV channels from runtime upload config', async () => { + const uploadSettings = JSON.stringify({ + webdav: { + loadBalance: { enabled: false }, + channels: [ + { name: 'enabled-dav', type: 'webdav', baseUrl: 'https://dav.example.com/', enabled: true }, + { name: 'disabled-dav', type: 'webdav', baseUrl: 'https://dav2.example.com/', enabled: false }, + ], + }, + }); + const env = { img_url: makeKV({ 'manage@sysConfig@upload': uploadSettings }) }; + + const config = await fetchUploadConfig(env); + + assert.deepEqual(config.webdav.channels.map(ch => ch.name), ['enabled-dav']); + }); + + it('includes WebDAV channels in /api/channels output', async () => { + const uploadSettings = JSON.stringify({ + webdav: { + loadBalance: { enabled: false }, + channels: [{ name: 'dav-main', type: 'webdav', baseUrl: 'https://dav.example.com/', enabled: true }], + }, + }); + const env = { img_url: makeKV({ 'manage@sysConfig@upload': uploadSettings }) }; + const request = new Request('https://img.example.com/api/channels'); + + const response = await channelsOnRequest({ request, env }); + const body = await response.json(); + + assert.equal(response.status, 200); + assert.deepEqual(body.webdav, [{ name: 'dav-main', type: 'WebDAV' }]); + }); + + it('resolves WebDAV secrets from channel config by ChannelName', async () => { + const uploadSettings = JSON.stringify({ + webdav: { + loadBalance: { enabled: false }, + channels: [{ + name: 'dav-main', + type: 'webdav', + baseUrl: 'https://dav.example.com/root/', + username: 'alice', + password: 'secret', + headers: { 'X-Test': '1' }, + enabled: true, + }], + }, + }); + const env = { img_url: makeKV({ 'manage@sysConfig@upload': uploadSettings }) }; + + const config = await resolveWebDAVConfig(env, { + ChannelName: 'dav-main', + WebDAVBaseUrl: 'https://dav.example.com/root/', + WebDAVFilePath: 'a.png', + }); + + assert.equal(config.username, 'alice'); + assert.equal(config.password, 'secret'); + assert.deepEqual(config.headers, { 'X-Test': '1' }); + }); +});