From 112eb775927c26e7e8bdc75ce9eb3920008f2fef Mon Sep 17 00:00:00 2001 From: axibayuit Date: Wed, 31 Dec 2025 23:18:56 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BC=98=E5=8C=96=E6=97=8B=E8=BD=AC?= =?UTF-8?q?=E8=A7=A6=E5=8F=91=E9=80=BB=E8=BE=91-=E8=A7=92=E5=BA=A6?= =?UTF-8?q?=E4=BC=98=E5=85=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- css/733.ce2542a6.css | 1 + css/733.ce2542a6.css.gz | Bin 0 -> 2067 bytes index.html | 2 +- index.html.gz | Bin 512 -> 511 bytes js/733.0149a1b8.js | 2 ++ js/733.0149a1b8.js.gz | Bin 0 -> 7715 bytes js/733.0149a1b8.js.map | 1 + js/733.0149a1b8.js.map.gz | Bin 0 -> 20885 bytes js/app.c7b1facf.js | 2 ++ js/app.c7b1facf.js.gz | Bin 0 -> 4907 bytes js/app.c7b1facf.js.map | 1 + js/app.c7b1facf.js.map.gz | Bin 0 -> 15251 bytes 12 files changed, 8 insertions(+), 1 deletion(-) create mode 100644 css/733.ce2542a6.css create mode 100644 css/733.ce2542a6.css.gz create mode 100644 js/733.0149a1b8.js create mode 100644 js/733.0149a1b8.js.gz create mode 100644 js/733.0149a1b8.js.map create mode 100644 js/733.0149a1b8.js.map.gz create mode 100644 js/app.c7b1facf.js create mode 100644 js/app.c7b1facf.js.gz create mode 100644 js/app.c7b1facf.js.map create mode 100644 js/app.c7b1facf.js.map.gz diff --git a/css/733.ce2542a6.css b/css/733.ce2542a6.css new file mode 100644 index 0000000..e17518e --- /dev/null +++ b/css/733.ce2542a6.css @@ -0,0 +1 @@ +.tm-viewport[data-v-5c291694]{width:100%;height:100%;display:flex;align-items:center;justify-content:center;touch-action:none;-webkit-user-select:none;-moz-user-select:none;user-select:none}.tm-media[data-v-5c291694]{max-width:100%;max-height:100%;-o-object-fit:contain;object-fit:contain;-webkit-user-drag:none}.public-browse[data-v-7aa9aaa3]{min-height:100vh;background:#0a0a0a;color:#fff}.header[data-v-7aa9aaa3]{position:sticky;top:0;z-index:100;display:flex;align-items:center;justify-content:space-between;padding:16px 32px;background:hsla(0,0%,6%,.95);backdrop-filter:blur(10px);border-bottom:1px solid #1a1a1a}.logo[data-v-7aa9aaa3]{font-size:20px;font-weight:600;color:#fff}.breadcrumb[data-v-7aa9aaa3]{display:flex;align-items:center;gap:4px;font-size:14px}.breadcrumb-item[data-v-7aa9aaa3]{padding:6px 12px;border-radius:6px;cursor:pointer;transition:background .2s;color:#ccc}.breadcrumb-item[data-v-7aa9aaa3]:hover{background:#252525;color:#fff}.breadcrumb-sep[data-v-7aa9aaa3]{color:#444}.file-count[data-v-7aa9aaa3]{color:#666;font-size:14px}.error-container[data-v-7aa9aaa3],.loading-container[data-v-7aa9aaa3]{display:flex;flex-direction:column;align-items:center;justify-content:center;min-height:60vh;color:#666}.loading-spinner[data-v-7aa9aaa3]{width:48px;height:48px;border:3px solid #222;border-top-color:#3b82f6;border-radius:50%;animation:spin-7aa9aaa3 1s linear infinite}.loading-spinner-small[data-v-7aa9aaa3]{width:24px;height:24px;border:2px solid #222;border-top-color:#3b82f6;border-radius:50%;animation:spin-7aa9aaa3 1s linear infinite}@keyframes spin-7aa9aaa3{to{transform:rotate(1turn)}}.retry-btn[data-v-7aa9aaa3]{margin-top:20px;padding:10px 32px;background:#3b82f6;border:none;border-radius:8px;color:#fff;font-size:14px;cursor:pointer;transition:background .2s}.retry-btn[data-v-7aa9aaa3]:hover{background:#2563eb}.gallery-container[data-v-7aa9aaa3]{padding:8px}@media (min-width:1200px){.gallery-container[data-v-7aa9aaa3]{max-width:1400px;margin:0 auto;padding:24px}}.folders-section[data-v-7aa9aaa3]{margin-bottom:24px}.folders-grid[data-v-7aa9aaa3]{display:grid;grid-template-columns:repeat(auto-fill,minmax(160px,1fr));gap:16px}.folder-card[data-v-7aa9aaa3]{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:24px 16px;background:#141414;border-radius:12px;border:1px solid #1a1a1a;cursor:pointer;transition:all .2s}.folder-card[data-v-7aa9aaa3]:hover{background:#1a1a1a;border-color:#333;transform:translateY(-2px)}.folder-icon[data-v-7aa9aaa3]{width:48px;height:48px;margin-bottom:12px;color:#555}.folder-icon svg[data-v-7aa9aaa3]{width:100%;height:100%}.folder-name[data-v-7aa9aaa3]{font-size:14px;color:#999;text-align:center;word-break:break-all}.waterfall[data-v-7aa9aaa3]{display:flex;gap:16px}.waterfall-column[data-v-7aa9aaa3]{flex:1;display:flex;flex-direction:column;gap:16px}.waterfall-item[data-v-7aa9aaa3]{cursor:pointer}.image-wrapper[data-v-7aa9aaa3]{position:relative;border-radius:12px;overflow:hidden;background:#141414;border:1px solid #1a1a1a;min-height:180px}.image-wrapper[data-v-7aa9aaa3]:before{content:"";position:absolute;inset:0;background:linear-gradient(90deg,#141414 25%,#1a1a1a 50%,#141414 75%);background-size:200% 100%;animation:shimmer-7aa9aaa3 1.5s infinite;z-index:1;pointer-events:none}.image-wrapper.loaded[data-v-7aa9aaa3]:before{display:none}.image-wrapper.loaded[data-v-7aa9aaa3]{min-height:auto}.image-wrapper img[data-v-7aa9aaa3],.image-wrapper video[data-v-7aa9aaa3]{width:100%;display:block;position:relative;z-index:2}@keyframes shimmer-7aa9aaa3{0%{background-position:200% 0}to{background-position:-200% 0}}.image-wrapper[data-v-7aa9aaa3]:hover{border-color:#333}.overlay[data-v-7aa9aaa3]{position:absolute;inset:0;background:linear-gradient(transparent 50%,rgba(0,0,0,.85));opacity:0;transition:opacity .2s;display:flex;align-items:flex-end;justify-content:flex-end;padding:12px;z-index:10}.image-wrapper:hover .overlay[data-v-7aa9aaa3]{opacity:1}.file-placeholder[data-v-7aa9aaa3]{width:100%;height:200px;display:flex;align-items:center;justify-content:center;background:#141414;color:#333}.file-placeholder svg[data-v-7aa9aaa3]{width:56px;height:56px}.overlay-actions[data-v-7aa9aaa3]{display:flex;gap:8px}.action-btn[data-v-7aa9aaa3]{width:32px;height:32px;border:none;border-radius:50%;background:hsla(0,0%,100%,.08);backdrop-filter:blur(8px);cursor:pointer;transition:all .2s;display:flex;align-items:center;justify-content:center;color:hsla(0,0%,100%,.6)}.action-btn svg[data-v-7aa9aaa3]{width:16px;height:16px}.action-btn[data-v-7aa9aaa3]:hover{background:hsla(0,0%,100%,.2);color:#fff;transform:scale(1.1)}.load-trigger[data-v-7aa9aaa3]{display:flex;justify-content:center;align-items:center;padding:48px;min-height:100px}.loading-more[data-v-7aa9aaa3]{display:flex;align-items:center;gap:12px;color:#666;font-size:14px}.no-more[data-v-7aa9aaa3]{color:#444;font-size:14px}.preview-modal[data-v-7aa9aaa3]{position:fixed;inset:0;z-index:1000;background:rgba(0,0,0,.97)}.preview-content[data-v-7aa9aaa3],.preview-modal[data-v-7aa9aaa3]{display:flex;align-items:center;justify-content:center;overflow:hidden}.preview-content[data-v-7aa9aaa3]{width:100%;height:100%;padding:60px 80px;box-sizing:border-box}.swipe-viewport[data-v-7aa9aaa3]{width:100%;height:100%;overflow:hidden;position:relative}.swipe-track[data-v-7aa9aaa3]{width:300%;height:100%;display:flex;will-change:transform}.swipe-slide[data-v-7aa9aaa3]{width:33.333%;flex-shrink:0;height:100%;display:flex;align-items:center;justify-content:center}.preview-image[data-v-7aa9aaa3],.preview-video[data-v-7aa9aaa3]{max-width:100%;max-height:100%;-o-object-fit:contain;object-fit:contain;-webkit-user-select:none;-moz-user-select:none;user-select:none;-webkit-user-drag:none}.preview-close[data-v-7aa9aaa3]{position:fixed;top:20px;right:20px;background:hsla(0,0%,100%,.1);border:none;color:#fff;cursor:pointer;width:48px;height:48px;border-radius:50%;display:flex;align-items:center;justify-content:center;transition:background .2s;z-index:1010}.preview-close[data-v-7aa9aaa3]:hover{background:hsla(0,0%,100%,.2)}.preview-close svg[data-v-7aa9aaa3]{width:28px;height:28px}.page-indicator[data-v-7aa9aaa3]{position:fixed;bottom:30px;left:50%;transform:translateX(-50%);background:rgba(0,0,0,.6);color:hsla(0,0%,100%,.8);padding:8px 16px;border-radius:20px;font-size:14px;z-index:1010}.preview-next[data-v-7aa9aaa3],.preview-prev[data-v-7aa9aaa3]{position:fixed;top:50%;transform:translateY(-50%);background:hsla(0,0%,100%,.1);border:none;color:#fff;padding:16px;cursor:pointer;border-radius:50%;width:56px;height:56px;display:flex;align-items:center;justify-content:center;transition:background .2s;z-index:1010}.preview-next[data-v-7aa9aaa3]:hover,.preview-prev[data-v-7aa9aaa3]:hover{background:hsla(0,0%,100%,.2)}.preview-next svg[data-v-7aa9aaa3],.preview-prev svg[data-v-7aa9aaa3]{width:32px;height:32px}.preview-prev[data-v-7aa9aaa3]{left:20px}.preview-next[data-v-7aa9aaa3]{right:20px}.rotate-btn[data-v-7aa9aaa3]{position:fixed;bottom:30px;right:20px;background:hsla(0,0%,100%,.1);border:none;color:#fff;cursor:pointer;width:48px;height:48px;border-radius:50%;display:flex;align-items:center;justify-content:center;transition:background .2s;z-index:1010}.rotate-btn[data-v-7aa9aaa3]:hover{background:hsla(0,0%,100%,.2)}.rotate-btn svg[data-v-7aa9aaa3]{width:24px;height:24px}@media (max-width:768px){.desktop-only[data-v-7aa9aaa3]{display:none!important}.preview-content.mobile-only[data-v-7aa9aaa3]{display:block;padding:0;width:100%;height:100%;position:absolute;top:0;left:0}.page-indicator[data-v-7aa9aaa3]{bottom:40px}}@media (min-width:769px){.mobile-only[data-v-7aa9aaa3]{display:none!important}}@media (max-width:1199px) and (min-width:601px){.gallery-container[data-v-7aa9aaa3]{padding:12px}.waterfall-column[data-v-7aa9aaa3],.waterfall[data-v-7aa9aaa3]{gap:10px}.image-wrapper[data-v-7aa9aaa3]{border-radius:8px}}@media (max-width:600px){.header[data-v-7aa9aaa3]{padding:10px 12px}.header-left .logo[data-v-7aa9aaa3]{font-size:16px}.breadcrumb[data-v-7aa9aaa3]{font-size:12px}.breadcrumb-item[data-v-7aa9aaa3]{padding:4px 8px}.file-count[data-v-7aa9aaa3]{font-size:12px}.gallery-container[data-v-7aa9aaa3]{padding:6px}.waterfall-column[data-v-7aa9aaa3],.waterfall[data-v-7aa9aaa3]{gap:6px}.image-wrapper[data-v-7aa9aaa3]{border-radius:6px;min-height:120px}.folders-section[data-v-7aa9aaa3]{margin-bottom:12px}.folders-grid[data-v-7aa9aaa3]{grid-template-columns:repeat(2,1fr);gap:8px}.folder-card[data-v-7aa9aaa3]{padding:16px 12px;border-radius:8px}.folder-icon[data-v-7aa9aaa3]{width:36px;height:36px;margin-bottom:8px}.folder-name[data-v-7aa9aaa3]{font-size:12px}.load-trigger[data-v-7aa9aaa3]{padding:24px;min-height:60px}}.copy-toast{position:fixed;bottom:80px;left:50%;transform:translateX(-50%) translateY(20px);background:rgba(0,0,0,.8);color:#fff;padding:10px 24px;border-radius:20px;font-size:14px;opacity:0;transition:all .3s ease;z-index:9999;pointer-events:none}.copy-toast.show{opacity:1;transform:translateX(-50%) translateY(0)} \ No newline at end of file diff --git a/css/733.ce2542a6.css.gz b/css/733.ce2542a6.css.gz new file mode 100644 index 0000000000000000000000000000000000000000..12990e12c47a94394b9628af072aa17163fb740a GIT binary patch literal 2067 zcmV+u2<-PCiwFP!000023f)@WuB)~ZeihoSNQo39APFmhn?6RXqh1&=#9hWl##tdd z%DW%g{24GLS!#PxMas_NXFN0hX6BpmwnYxUFuE3ui~l81K=1_)v3GL))Bex<6(`~x zxQ??5&j@E{QU6YGSrB*&Qi7@w5}Z+h1f@0C!$l1^7)$xUgEpm{f1jDK7Ijn%DzWh@+0WiR#zfded zibWt5g_wqhO9K@X4zp(E;t~-YgNU8>_eBt2Cz7W6bu<;J^Gvg9aqGGCj^Xz`Vf7mG|2*m6{#q4vw?@v60IAg4t zQdw&W-=;Eoj!d2RS0rimY%kvmYflD_1uueiev}A#JnWQ_1o0A-b&SpKLzAu5Tir_; z$H{yM%e$fc0s`d)fkGw~8Np@1QGuXXONC^CAln?%99C=BcZzE3rhKzeiC7k!b~zA3 zp8UfJLwAlP7axGk-OJAiSX!!|*0Kd)K|*RoEm>#4R3o@iqK)9)F6^UB{gVFvV-38b z+H`B+*tEkliEg;@%FJf9!{IOxX_a5uoY*lX>|UfWM@vP%j>~$%)9DlnR0*JVvfZpJ z;|Y*;?K4o{021=BuTUVK8q?$eDm}cqHyU^vv?7v1g)czOB-Kn8hRAr>IENVmR}PC} zk=}7cpuk_q1Vagyl(1`X#z}(cJa`RA)p_XAkrpg#6htUx9NpUp`t{ea(-B4`BNu@} zOiLsJM^~gS93Yc=BP!M>Cqdb^QP1)Yt8Jr^b#PYQ^^e19qe*FbptG_Rz_dbj#(9po zR;%no*_ElD4~LE80s2BzlnqxOn5?QVN@gu@;qb<*I@_1YZ}ggl^UOe-hR=NA1hK_% zYZZ$Ki$B9Da#|;NgQ`7p+}&Aec?Wb-l+&GuV8*+kx&0J9O=25ov4<_M6L?#QfOpWP zQego(qC(+`XOU`Dw$9c*9yXhh6)?u)7C3rtZZ0Y+KHD#-1b}EVsU_Wwj^rfM zZ)#Uq^M`*VxEP7jA9mIMd1=WheWzx_{U0wU5Wj_#55$#j30M zx-LfxPMea9@xtCl=gvLRC}T*_+O^$H-Kqe=ah5%8>t>8LxTlSvnve`8CDN$2J<1tJ z-|O^sT4U;IDVq`A_sf%a3XbHU4CE|-4ed#W&tF)Qcwy zd=rx+a`9Y|xuIY;D3P6E=rGZb|3(8?_dPSC8}oxR)bRyBVt&m7aw!1)`7ru}}X>aqZf83OT-%t7BD z)y~gRTeuNsnxl@ws+$||rU=drEb9#CZU!|%%XXt2zc>}ri^_LL-?KBpK0!zdvFwdk zQu;{7QaSN7b3Ijq3rS!wO>hha<4<>^X(D%W7YIs)@{pln{e2A%&VcC;@}Iw%sf@=> zs0~n>&V8^Y{mi)UF3ldLs9H*@^52)xH)G--QxjhYqdtTmBXbHtGw=GhkZJT|4a_Ir zd=I^H9V2*$t1RJr%oiU|c3VN%bMyy|*53Q%^RVmLr{Po{{!Izoz7Jw007xz{R#j8 literal 0 HcmV?d00001 diff --git a/index.html b/index.html index f1f88d7..9821f91 100644 --- a/index.html +++ b/index.html @@ -1 +1 @@ -Sanyue ImgHub
\ No newline at end of file +Sanyue ImgHub
\ No newline at end of file diff --git a/index.html.gz b/index.html.gz index 311e1457950250b27d9913582ed6856d5f68c72a..39ebc9c5dfab009ca235b88b333ef8d73a44d7f2 100644 GIT binary patch delta 477 zcmV<30V4i@1pfn&7zG9TsSMlSn_(Vfg>{^ckGzG@MwYdLWqv`P< zD5wEzF*)2tO8l&D=M3B0;N&zGhhXJ`W2bzPwenc6MI*fnTS(|@;WPySHer8Pi^@|^ zWeojEg^JN*!8B@Hyk9-2ynUk#GoXR&ND^XxHOL>8~n`$p@{ z&GoHT>$fn~a``QpxsidM9B`u0H$U+#A!JHvhIVAghl%}mLvP0x3}Hf_{e_&GPRy0*aH9n4@vC7 delta 478 zcmV<40U`eX1AqjO7zL9h{Q_)}9Te8Upb=f0JP)5dtT#13(>_!~3hB;*Tcd%n6erG@Lvd`29$+mGQK#^zkT#5TH73vP3 zKwkD(iP7RNP~;bNJFD4L8b_-zI|K{sEnDfbq@=@YCF;^yzlDgd5>}BHU?P9El_(r_ zln39PRLBqV*0fbC`XB2XI(QAq+zrI;ESC^N! z`C}4wSqB?ZL_{wqu$)+DkU**GV$av8AKN6=zXKr z=H~iV$<+$`0h|9JjP%dm=61~e!#pej$O;*zYuLlu=;S|d$rn* Uby>`6i^E6$2X!%+DA)r40Lb0&Z~y=R diff --git a/js/733.0149a1b8.js b/js/733.0149a1b8.js new file mode 100644 index 0000000..849f3f5 --- /dev/null +++ b/js/733.0149a1b8.js @@ -0,0 +1,2 @@ +"use strict";(self["webpackChunksanyue_imghub"]=self["webpackChunksanyue_imghub"]||[]).push([[733],{6733:function(t,e,i){i.r(e),i.d(e,{default:function(){return q}});var s=i(6768),r=i(5130),o=i(4232);const n=["src"],a=["src"];function l(t,e,i,l,h,c){return(0,s.uX)(),(0,s.CE)("div",{class:"tm-viewport",ref:"viewport",onPointerdown:e[1]||(e[1]=(...t)=>c.onPointerDown&&c.onPointerDown(...t)),onPointermove:e[2]||(e[2]=(...t)=>c.onPointerMove&&c.onPointerMove(...t)),onPointerup:e[3]||(e[3]=(...t)=>c.onPointerUp&&c.onPointerUp(...t)),onPointercancel:e[4]||(e[4]=(...t)=>c.onPointerUp&&c.onPointerUp(...t)),onDblclick:e[5]||(e[5]=(0,r.D$)((...t)=>c.onDblClick&&c.onDblClick(...t),["prevent"]))},[i.isImage?((0,s.uX)(),(0,s.CE)("img",{key:0,class:"tm-media",src:i.src,draggable:"false",style:(0,o.Tr)(c.mediaStyle),onLoad:e[0]||(e[0]=(...t)=>c.onLoad&&c.onLoad(...t))},null,44,n)):i.isVideo?((0,s.uX)(),(0,s.CE)("video",{key:1,class:"tm-media",src:i.src,controls:"",autoplay:"",playsinline:"",style:(0,o.Tr)(c.mediaStyle)},null,12,a)):(0,s.Q3)("",!0)],544)}var h={name:"TransformMedia",props:{file:{type:Object,required:!0},src:{type:String,required:!0},isImage:{type:Boolean,default:!0},isVideo:{type:Boolean,default:!1}},data(){return{pointers:new Map,scale:1,rotation:0,rotatePreview:0,tx:0,ty:0,naturalWidth:0,naturalHeight:0,startScale:1,startRotation:0,startTx:0,startTy:0,startCenter:null,startDist:0,startAngle:0,dragging:!1,dragStart:null,viewportRect:null,minScale:1,maxScale:4,gestureMode:null}},computed:{isActiveTransform(){return this.scale>1.001||this.pointers.size>=2||this.dragging},displayRotation(){return this.rotation+this.rotatePreview},rotateShrink(){const t=Math.min(1,Math.abs(this.rotatePreview)/90),e=Math.sin(Math.PI*t);return 1-.12*e},mediaStyle(){const t=this.scale*this.rotateShrink,e=this.pointers.size>0;return{transform:`translate3d(${this.tx}px, ${this.ty}px, 0) scale(${t}) rotate(${this.displayRotation}deg)`,transition:e?"none":"transform 0.25s ease",transformOrigin:"center center"}}},watch:{isActiveTransform(t){this.$emit(t?"lock":"unlock")}},methods:{onLoad(t){const e=t.target;this.naturalWidth=e.naturalWidth,this.naturalHeight=e.naturalHeight},reset(){this.scale=1,this.rotation=0,this.rotatePreview=0,this.tx=0,this.ty=0,this.pointers.clear(),this.dragging=!1,this.$emit("unlock")},clamp(t,e,i){return Math.max(e,Math.min(i,t))},rubberBand(t,e,i=.55){return t*e*i/(e+i*t)},getViewportRect(){return this.$refs.viewport?.getBoundingClientRect()},getPanBounds(){const t=this.$refs.viewport?.getBoundingClientRect();if(!t)return{maxX:0,maxY:0,vw:0,vh:0};const e=t.width,i=t.height,s=this.$el.querySelector("img, video"),r=s?.clientWidth||e,o=s?.clientHeight||i,n=r*this.scale,a=o*this.scale,l=Math.max(0,(n-e)/2),h=Math.max(0,(a-i)/2);return{maxX:l,maxY:h,vw:e,vh:i}},applyBoundWithRubber(t,e,i){return t>e?e+this.rubberBand(t-e,i,.55):t<-e?-e-this.rubberBand(-e-t,i,.55):t},calcTwoPointer(){const t=Array.from(this.pointers.values()),e=t[0],i=t[1],s=i.x-e.x,r=i.y-e.y,o=Math.hypot(s,r),n=Math.atan2(r,s)*(180/Math.PI),a={x:(e.x+i.x)/2,y:(e.y+i.y)/2};return{dist:o,angle:n,center:a}},normalizeAngle(t){return t=(t%360+360)%360,t>180?t-360:t},onPointerDown(t){if(t.currentTarget.setPointerCapture?.(t.pointerId),this.viewportRect=this.getViewportRect(),this.pointers.set(t.pointerId,{x:t.clientX,y:t.clientY}),2===this.pointers.size){const{dist:t,angle:e,center:i}=this.calcTwoPointer();return this.startDist=t,this.startAngle=e,this.startCenter=i,this.startScale=this.scale,this.startRotation=this.rotation,this.startTx=this.tx,this.startTy=this.ty,this.dragging=!1,this.gestureMode=null,void(this.rotatePreview=0)}this.scale>1.001&&(this.dragging=!0,this.dragStart={x:t.clientX,y:t.clientY},this.startTx=this.tx,this.startTy=this.ty)},onPointerMove(t){if(this.pointers.has(t.pointerId)){if(this.pointers.set(t.pointerId,{x:t.clientX,y:t.clientY}),2===this.pointers.size){t.preventDefault();const{dist:e,angle:i,center:s}=this.calcTwoPointer(),r=e/(this.startDist||e),o=Math.abs(r-1),n=this.normalizeAngle(i-this.startAngle),a=Math.abs(n),l=8,h=.08;if(!this.gestureMode)if(a>=l)this.gestureMode="rotate";else{if(!(o>=h))return;this.gestureMode="pinch"}if("rotate"===this.gestureMode)return this.scale=this.startScale,void(this.rotatePreview=this.clamp(n,-90,90));if("pinch"===this.gestureMode&&(this.scale=this.clamp(this.startScale*r,this.minScale,this.maxScale),this.rotatePreview=0),this.startCenter&&this.viewportRect){const t=this.startCenter.x-this.viewportRect.left-this.viewportRect.width/2,e=this.startCenter.y-this.viewportRect.top-this.viewportRect.height/2,i=s.x-this.viewportRect.left-this.viewportRect.width/2,r=s.y-this.viewportRect.top-this.viewportRect.height/2;this.tx=this.startTx+(i-t),this.ty=this.startTy+(r-e)}return}if(this.dragging&&this.scale>1.001){t.preventDefault();const e=t.clientX-this.dragStart.x,i=t.clientY-this.dragStart.y,s=this.startTx+e,r=this.startTy+i,{maxX:o,maxY:n,vw:a,vh:l}=this.getPanBounds();this.tx=this.applyBoundWithRubber(s,o,a),this.ty=this.applyBoundWithRubber(r,n,l)}}},onPointerUp(t){if(this.pointers.has(t.pointerId)&&this.pointers.delete(t.pointerId),this.pointers.size<2&&"rotate"===this.gestureMode&&(this.finishRotate(),this.gestureMode=null),this.pointers.size<2&&(this.startCenter=null,this.startDist=0,this.startAngle=0,this.gestureMode=null),0===this.pointers.size)if(this.dragging=!1,this.scale<=1.001)this.scale=1,this.tx=0,this.ty=0;else{const{maxX:t,maxY:e}=this.getPanBounds();this.tx=Math.max(-t,Math.min(t,this.tx)),this.ty=Math.max(-e,Math.min(e,this.ty))}},finishRotate(){const t=this.rotatePreview,e=30;let i=0;Math.abs(t)>=e&&(i=t>0?90:-90);const s=((this.rotation+i)%360+360)%360;this.rotation=s,this.rotatePreview=0,this.updateFillScale()},updateFillScale(){const t=this.$refs.viewport?.getBoundingClientRect();if(!t||!this.naturalWidth||!this.naturalHeight)return;const e=t.width,i=t.height,s=this.naturalWidth,r=this.naturalHeight,o=this.rotation%360,n=90===o||270===o,a=n?r:s,l=n?s:r,h=Math.min(e/a,i/l),c=Math.max(e/a,i/l);if(n){const t=c/h;this.scale=Math.min(t,this.maxScale),this.tx=0,this.ty=0}else this.scale=1,this.tx=0,this.ty=0},onDblClick(){this.scale>1.001?(this.scale=1,this.tx=0,this.ty=0):this.scale=2}}},c=i(1241);const d=(0,c.A)(h,[["render",l],["__scopeId","data-v-5c291694"]]);var u=d;const p={class:"public-browse"},m={class:"header"},g={class:"header-left"},v={class:"logo"},w={class:"header-center"},f={class:"breadcrumb"},y=["onClick"],k={class:"header-right"},C={class:"file-count"},x={key:0,class:"loading-container"},b={key:1,class:"error-container"},L={key:2,class:"gallery-container",ref:"galleryContainer"},I={key:0,class:"folders-section"},M={class:"folders-grid"},F=["onClick"],P={class:"folder-name"},T={class:"waterfall",ref:"waterfall"},S=["onClick"],X=["src","alt","onLoad"],R=["src","onLoadedmetadata"],$={key:2,class:"file-placeholder"},E={class:"overlay"},D={class:"overlay-actions"},B=["onClick"],A=["onClick"],z={ref:"loadTrigger",class:"load-trigger"},H={key:0,class:"loading-more"},V={key:1,class:"no-more"},W=["src"],U=["src"],_={class:"page-indicator"};function Y(t,e,i,n,a,l){const h=u;return(0,s.uX)(),(0,s.CE)("div",p,[(0,s.Lk)("header",m,[(0,s.Lk)("div",g,[(0,s.Lk)("span",v,(0,o.v_)(l.siteName),1)]),(0,s.Lk)("div",w,[(0,s.Lk)("div",f,[(0,s.Lk)("span",{class:"breadcrumb-item",onClick:e[0]||(e[0]=(...t)=>l.goToRoot&&l.goToRoot(...t))},(0,o.v_)(l.rootDirName),1),((0,s.uX)(!0),(0,s.CE)(s.FK,null,(0,s.pI)(l.pathParts,(t,i)=>((0,s.uX)(),(0,s.CE)(s.FK,{key:i},[e[18]||(e[18]=(0,s.Lk)("span",{class:"breadcrumb-sep"},"/",-1)),(0,s.Lk)("span",{class:"breadcrumb-item",onClick:t=>l.goToPath(i)},(0,o.v_)(t),9,y)],64))),128))])]),(0,s.Lk)("div",k,[(0,s.Lk)("span",C,(0,o.v_)(a.totalCount)+" 个文件",1)])]),a.loading&&0===a.files.length?((0,s.uX)(),(0,s.CE)("div",x,[...e[19]||(e[19]=[(0,s.Lk)("div",{class:"loading-spinner"},null,-1),(0,s.Lk)("p",null,"加载中...",-1)])])):a.error?((0,s.uX)(),(0,s.CE)("div",b,[(0,s.Lk)("p",null,(0,o.v_)(a.error),1),a.canRetry?((0,s.uX)(),(0,s.CE)("button",{key:0,onClick:e[1]||(e[1]=(...t)=>l.loadFiles&&l.loadFiles(...t)),class:"retry-btn"},"重试")):(0,s.Q3)("",!0)])):((0,s.uX)(),(0,s.CE)("div",L,[l.folders.length>0?((0,s.uX)(),(0,s.CE)("div",I,[(0,s.Lk)("div",M,[((0,s.uX)(!0),(0,s.CE)(s.FK,null,(0,s.pI)(l.folders,t=>((0,s.uX)(),(0,s.CE)("div",{key:t.name,class:"folder-card",onClick:e=>l.enterFolder(t.name)},[e[20]||(e[20]=(0,s.Lk)("div",{class:"folder-icon"},[(0,s.Lk)("svg",{viewBox:"0 0 24 24",fill:"currentColor"},[(0,s.Lk)("path",{d:"M10 4H4c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V8c0-1.1-.9-2-2-2h-8l-2-2z"})])],-1)),(0,s.Lk)("span",P,(0,o.v_)(l.getFolderName(t.name)),1)],8,F))),128))])])):(0,s.Q3)("",!0),(0,s.Lk)("div",T,[((0,s.uX)(!0),(0,s.CE)(s.FK,null,(0,s.pI)(l.columns,(t,i)=>((0,s.uX)(),(0,s.CE)("div",{key:i,class:"waterfall-column"},[((0,s.uX)(!0),(0,s.CE)(s.FK,null,(0,s.pI)(t,t=>((0,s.uX)(),(0,s.CE)("div",{key:t.name,class:"waterfall-item",onClick:e=>l.openPreview(t)},[(0,s.Lk)("div",{class:(0,o.C4)(["image-wrapper",{loaded:t.loaded}])},[l.isImage(t)?((0,s.uX)(),(0,s.CE)("img",{key:0,src:l.getFileUrl(t.name),alt:t.name,loading:"lazy",onLoad:e=>l.onImageLoad(e,t),onError:e[2]||(e[2]=(...t)=>l.handleImageError&&l.handleImageError(...t))},null,40,X)):l.isVideo(t)?((0,s.uX)(),(0,s.CE)("video",{key:1,src:l.getFileUrl(t.name),muted:"",loop:"",preload:"metadata",onLoadedmetadata:e=>l.onVideoLoad(e,t),onMouseenter:e[3]||(e[3]=t=>t.target.play()),onMouseleave:e[4]||(e[4]=t=>t.target.pause())},null,40,R)):((0,s.uX)(),(0,s.CE)("div",$,[...e[21]||(e[21]=[(0,s.Lk)("svg",{viewBox:"0 0 24 24",fill:"currentColor"},[(0,s.Lk)("path",{d:"M14 2H6c-1.1 0-2 .9-2 2v16c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V8l-6-6zm-1 7V3.5L18.5 9H13z"})],-1)])])),(0,s.Lk)("div",E,[(0,s.Lk)("div",D,[(0,s.Lk)("button",{class:"action-btn",onClick:(0,r.D$)(e=>l.copyLink(t.name),["stop"]),title:"复制链接"},[...e[22]||(e[22]=[(0,s.Lk)("svg",{viewBox:"0 0 24 24",fill:"currentColor"},[(0,s.Lk)("path",{d:"M3.9 12c0-1.71 1.39-3.1 3.1-3.1h4V7H7c-2.76 0-5 2.24-5 5s2.24 5 5 5h4v-1.9H7c-1.71 0-3.1-1.39-3.1-3.1zM8 13h8v-2H8v2zm9-6h-4v1.9h4c1.71 0 3.1 1.39 3.1 3.1s-1.39 3.1-3.1 3.1h-4V17h4c2.76 0 5-2.24 5-5s-2.24-5-5-5z"})],-1)])],8,B),(0,s.Lk)("button",{class:"action-btn",onClick:(0,r.D$)(e=>l.downloadFile(t.name),["stop"]),title:"下载"},[...e[23]||(e[23]=[(0,s.Lk)("svg",{viewBox:"0 0 24 24",fill:"currentColor"},[(0,s.Lk)("path",{d:"M19 9h-4V3H9v6H5l7 7 7-7zM5 18v2h14v-2H5z"})],-1)])],8,A)])])],2)],8,S))),128))]))),128))],512),(0,s.Lk)("div",z,[a.loading&&a.files.length>0?((0,s.uX)(),(0,s.CE)("div",H,[...e[24]||(e[24]=[(0,s.Lk)("div",{class:"loading-spinner-small"},null,-1),(0,s.Lk)("span",null,"加载中...",-1)])])):!a.hasMore&&l.mediaFiles.length>0?((0,s.uX)(),(0,s.CE)("div",V," 已加载全部 ")):(0,s.Q3)("",!0)],512)],512)),a.previewVisible?((0,s.uX)(),(0,s.CE)("div",{key:3,class:"preview-modal",onClick:e[17]||(e[17]=(0,r.D$)((...t)=>l.closePreview&&l.closePreview(...t),["self"]))},[(0,s.Lk)("button",{class:"preview-close",onClick:e[5]||(e[5]=(0,r.D$)((...t)=>l.closePreview&&l.closePreview(...t),["stop"]))},[...e[25]||(e[25]=[(0,s.Lk)("svg",{viewBox:"0 0 24 24",fill:"currentColor"},[(0,s.Lk)("path",{d:"M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"})],-1)])]),(0,s.Lk)("div",{class:"preview-content desktop-only",onClick:e[6]||(e[6]=(0,r.D$)(()=>{},["stop"]))},[l.currentPreviewFile&&l.isImage(l.currentPreviewFile)?((0,s.uX)(),(0,s.CE)("img",{key:0,src:l.getFileUrl(l.currentPreviewFile.name),class:"preview-image",style:(0,o.Tr)(l.desktopImageStyle),draggable:"false"},null,12,W)):l.currentPreviewFile&&l.isVideo(l.currentPreviewFile)?((0,s.uX)(),(0,s.CE)("video",{key:1,src:l.getFileUrl(l.currentPreviewFile.name),controls:"",autoplay:"",class:"preview-video",style:(0,o.Tr)(l.desktopImageStyle)},null,12,U)):(0,s.Q3)("",!0)]),(0,s.Lk)("div",{class:"preview-content mobile-only",onClick:e[13]||(e[13]=(0,r.D$)(()=>{},["stop"]))},[(0,s.Lk)("div",{class:"swipe-viewport",ref:"mobileViewport",onTouchstart:e[10]||(e[10]=(...t)=>l.onSwipeStart&&l.onSwipeStart(...t)),onTouchmove:e[11]||(e[11]=(...t)=>l.onSwipeMove&&l.onSwipeMove(...t)),onTouchend:e[12]||(e[12]=(...t)=>l.onSwipeEnd&&l.onSwipeEnd(...t))},[(0,s.Lk)("div",{class:"swipe-track",style:(0,o.Tr)(l.swipeTrackStyle),onTransitionend:e[9]||(e[9]=(...t)=>l.onSwipeTransitionEnd&&l.onSwipeTransitionEnd(...t))},[((0,s.uX)(!0),(0,s.CE)(s.FK,null,(0,s.pI)(l.swipeWindow,(t,i)=>((0,s.uX)(),(0,s.CE)("div",{class:"swipe-slide",key:l.getSlideKey(t,i)},[t?((0,s.uX)(),(0,s.Wv)(h,{key:0,file:t,src:l.getFileUrl(t.name),"is-image":l.isImage(t),"is-video":l.isVideo(t),onLock:e[7]||(e[7]=t=>a.gestureLocked=!0),onUnlock:e[8]||(e[8]=t=>a.gestureLocked=!1)},null,8,["file","src","is-image","is-video"])):(0,s.Q3)("",!0)]))),128))],36)],544)]),a.previewIndex>0?((0,s.uX)(),(0,s.CE)("button",{key:0,class:"preview-prev desktop-only",onClick:e[14]||(e[14]=(0,r.D$)((...t)=>l.prevImage&&l.prevImage(...t),["stop"]))},[...e[26]||(e[26]=[(0,s.Lk)("svg",{viewBox:"0 0 24 24",fill:"currentColor"},[(0,s.Lk)("path",{d:"M15.41 7.41L14 6l-6 6 6 6 1.41-1.41L10.83 12z"})],-1)])])):(0,s.Q3)("",!0),a.previewIndexl.nextImage&&l.nextImage(...t),["stop"]))},[...e[27]||(e[27]=[(0,s.Lk)("svg",{viewBox:"0 0 24 24",fill:"currentColor"},[(0,s.Lk)("path",{d:"M10 6L8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z"})],-1)])])):(0,s.Q3)("",!0),(0,s.Lk)("button",{class:"rotate-btn desktop-only",onClick:e[16]||(e[16]=(0,r.D$)((...t)=>l.rotateImage&&l.rotateImage(...t),["stop"])),title:"旋转90°"},[...e[28]||(e[28]=[(0,s.Lk)("svg",{viewBox:"0 0 24 24",fill:"currentColor"},[(0,s.Lk)("path",{d:"M7.11 8.53L5.7 7.11C4.8 8.27 4.24 9.61 4.07 11h2.02c.14-.87.49-1.72 1.02-2.47zM6.09 13H4.07c.17 1.39.72 2.73 1.62 3.89l1.41-1.42c-.52-.75-.87-1.59-1.01-2.47zm1.01 5.32c1.16.9 2.51 1.44 3.9 1.61V17.9c-.87-.15-1.71-.49-2.46-1.03L7.1 18.32zM13 4.07V1L8.45 5.55 13 10V6.09c2.84.48 5 2.94 5 5.91s-2.16 5.43-5 5.91v2.02c3.95-.49 7-3.85 7-7.93s-3.05-7.44-7-7.93z"})],-1)])]),(0,s.Lk)("div",_,(0,o.v_)(a.previewIndex+1)+" / "+(0,o.v_)(l.mediaFiles.length),1)])):(0,s.Q3)("",!0)])}i(4114),i(8111),i(2489),i(7588),i(1701);var Q=i(4373),K=i(8401),N={name:"PublicBrowse",components:{TransformMedia:u},data(){return{files:[],allowedDirs:[],rootDir:"",currentPath:"",totalCount:0,loading:!1,error:null,canRetry:!0,hasMore:!0,previewVisible:!1,previewIndex:0,observer:null,pageSize:24,columnCount:4,columnHeights:[0,0,0,0],imageRotation:0,swipeX:0,swipeStartX:0,swipeStartY:0,swipeStartT:0,swipeActive:!1,swipeAnimating:!1,swipeDir:0,viewportW:0,gestureLocked:!1}},computed:{...(0,K.L8)(["userConfig"]),siteName(){return this.userConfig?.siteTitle||"公开相册"},rootDirName(){return this.rootDir.split("/").filter(Boolean).pop()||"根目录"},pathParts(){if(!this.currentPath||!this.rootDir)return[];const t=this.currentPath.replace(this.rootDir,"").replace(/^\/+/,"");return t.split("/").filter(Boolean)},folders(){return this.files.filter(t=>t.isFolder)},mediaFiles(){return this.files.filter(t=>!t.isFolder)},columns(){const t=Array.from({length:this.columnCount},()=>[]);for(const e of this.mediaFiles){const i=e.columnIndex??0;i0?this.mediaFiles[this.previewIndex-1]:null},nextPreviewFile(){return this.previewIndex{t.columnIndex=void 0,this.assignToColumn(t)}))},getShortestColumn(){let t=0,e=this.columnHeights[0];for(let i=1;i{const e=t[0];e.isIntersecting&&this.hasMore&&!this.loading&&this.loadMore()},{rootMargin:"200px"})},observeLoadTrigger(){this.$nextTick(()=>{this.$refs.loadTrigger&&this.observer&&this.observer.observe(this.$refs.loadTrigger)})},async initFromRoute(){const t=this.$route.params.dir||"",e=Array.isArray(t)?t.join("/"):t;if(!e)return this.error="请指定要浏览的目录,例如: /browse/landscape",void(this.canRetry=!1);const i=e.split("/").filter(Boolean);this.rootDir=i[0],this.currentPath=e,this.files=[],this.hasMore=!0,this.columnHeights=new Array(this.columnCount).fill(0),await this.loadFiles(),this.observeLoadTrigger()},async loadFiles(){this.loading=!0,this.error=null,this.canRetry=!0;try{const t=await Q.A.get(`/api/public/list?dir=${encodeURIComponent(this.currentPath)}&count=${this.pageSize}`);t.data.allowedDirs&&(this.allowedDirs=t.data.allowedDirs);const e=(t.data.directories||[]).map(t=>({name:t,isFolder:!0})),i=(t.data.files||[]).map(t=>({name:t.name,isFolder:!1,metadata:t.metadata,columnIndex:void 0}));i.forEach(t=>this.assignToColumn(t)),this.files=[...e,...i],this.totalCount=t.data.totalCount||this.files.length,this.hasMore=this.mediaFiles.length({name:t.name,isFolder:!1,metadata:t.metadata,columnIndex:void 0}));i.forEach(t=>this.assignToColumn(t)),this.files.push(...i),this.hasMore=this.mediaFiles.length{this.showToast("已复制")}).catch(()=>{const t=document.createElement("input");t.value=e,document.body.appendChild(t),t.select(),document.execCommand("copy"),document.body.removeChild(t),this.showToast("已复制")})},showToast(t){const e=document.querySelector(".copy-toast");e&&e.remove();const i=document.createElement("div");i.className="copy-toast",i.textContent=t,document.body.appendChild(i),setTimeout(()=>i.classList.add("show"),10),setTimeout(()=>{i.classList.remove("show"),setTimeout(()=>i.remove(),300)},1500)},downloadFile(t){const e=document.createElement("a");e.href=this.getFileUrl(t),e.download=t.split("/").pop(),e.click()},openPreview(t){if(t.isFolder)return;const e=this.mediaFiles.findIndex(e=>e.name===t.name);e>=0&&(this.previewIndex=e,this.previewVisible=!0,this.imageRotation=0,this.gestureLocked=!1,document.body.style.overflow="hidden",this.$nextTick(()=>{this.viewportW=this.$refs.mobileViewport?.getBoundingClientRect().width||window.innerWidth}))},closePreview(){this.previewVisible=!1,this.imageRotation=0,this.gestureLocked=!1,document.body.style.overflow=""},prevImage(){this.previewIndex>0&&(this.previewIndex--,this.imageRotation=0)},nextImage(){this.previewIndex=360&&setTimeout(()=>{const t=this.$el.querySelector(".preview-image, .preview-video");t?(t.style.transition="none",this.imageRotation=0,t.offsetHeight,t.style.transition=""):this.imageRotation=0},300)},onSwipeStart(t){if(this.gestureLocked)return;if(this.swipeAnimating)return;const e=t.touches[0];this.swipeStartX=e.clientX,this.swipeStartY=e.clientY,this.swipeStartT=performance.now(),this.swipeX=0,this.swipeActive=!1,this.viewportW=this.$refs.mobileViewport?.getBoundingClientRect().width||window.innerWidth},onSwipeMove(t){if(this.gestureLocked)return;if(this.swipeAnimating)return;const e=t.touches[0],i=e.clientX-this.swipeStartX,s=e.clientY-this.swipeStartY;if(!this.swipeActive){if(Math.abs(i)<8)return;if(Math.abs(i)<=Math.abs(s))return;this.swipeActive=!0}t.preventDefault();let r=i;0===this.previewIndex&&r>0?r=this.rubberBand(r,this.viewportW,.55):this.previewIndex===this.mediaFiles.length-1&&r<0&&(r=-this.rubberBand(-r,this.viewportW,.55)),this.swipeX=r},onSwipeEnd(){if(this.gestureLocked)return;if(this.swipeAnimating)return;if(!this.swipeActive)return void(this.swipeX=0);const t=Math.max(1,performance.now()-this.swipeStartT),e=this.swipeX/t,i=.2*this.viewportW;let s=0;(this.swipeX<=-i||e<=-.8)&&(s=1),(this.swipeX>=i||e>=.8)&&(s=-1),(-1===s&&0===this.previewIndex||1===s&&this.previewIndex===this.mediaFiles.length-1)&&(s=0),this.swipeDir=s,this.swipeAnimating=!0,this.swipeX=1===s?-this.viewportW:-1===s?+this.viewportW:0},onSwipeTransitionEnd(){this.swipeAnimating&&(1===this.swipeDir&&this.previewIndex++,-1===this.swipeDir&&this.previewIndex--,this.swipeAnimating=!1,this.swipeDir=0,this.swipeX=0)},rubberBand(t,e,i=.55){return t*e*i/(e+i*t)}}};const j=(0,c.A)(N,[["render",Y],["__scopeId","data-v-7aa9aaa3"]]);var q=j}}]); +//# sourceMappingURL=733.0149a1b8.js.map \ No newline at end of file diff --git a/js/733.0149a1b8.js.gz b/js/733.0149a1b8.js.gz new file mode 100644 index 0000000000000000000000000000000000000000..cfd45cf323653ca07fc0c4dc6c223ee9ddc33bc0 GIT binary patch literal 7715 zcmV+;9^By{iwFP!000023e9|fkK0I=*#G$yG~+Z_?qW4bNiB&oyD`)Dz{a+By>{C( z1D!HvQ`J(9DN;+8x?5Hg$mO!x!|iSoB)J^0n;?f^_p-R$%_PC)c7ofv0QoFqkN2

Dt(bsE#(OdxIQpa8lDaH3wk>DgXc%nMf5!N zqve8r!e*1{;#41bZ>({3H5?%_U!+rGIPA7sBfQ%0wp#AlA__Q*BZFg#8Co%t7!+Yf z#sU#+nR(9W z#XL^9juU$3>g8)3J&akzX)=y4B9{*B(bbg!Kb}Dd;mA7(NKxlbd=c&JGzw%rR6?4? z=hUS`M?!KoLV6IN(;6fwSc9~fyL8x+a9SJTJek*^JejY-2>d9Zp-YEt38($8aPFLj zLCAvVE**9xh|b6}ES!)#H<3|=b>}oZf|?Rk{w8bSp*~OOIgPkJLMX#SMp$}(=1=IM zv5|soHqr6wIbFIIF6lUft(;xKh}9s3I&&qIF+&+wbFC}a_Z*XyREMrJ$MN5~ap_kezMNC{d#9h$fa8SzV8IePc5hgj7_I-)QlSKwO|++k?}?Y(FcQrD8q$fAjR!xqnv;iGJmYn(?kP$e@K<)fJSm-4ZV zCp6`Ygg%JJR8-3{9K^Hvg440PV(EJUXXmsaW2t2Ml%+(V>A)tIWnW#1k{pvHWiRM~ z=cwX*pcx*s6c{c?K?7ip@7?k(M|q|w@OYZA=(&MbQh#&rfzPL8#v;SU;?X}%jrHbe zuWuntW$lzjhIn{*{}x9BH3HitwsVVSxa9asH|2zHRiMk!VCrp{y`=!Jc#b~znRpC+ zPFrK+=1Mf;m)ZOhYx&z!yje&SeL0$EI>2CSM*Si;)v?5UUaQl z#Ob6O^+9D7rQb`~ghj3%2yWBlkDg^2zVLZ4-NXSL$wAztGsX>msE2XzTzBT$yTWJ38sz^F=&M{BRRT0zQESwp^OIH4)!h8mE-muKS|BY75H z=Y_nGUlvcx{HY*e5K=!e5U%mBcSFIKvo9wNigz~8EfvL3k~95FgW`fo85SBoS)88I z)ULeEl?i~Av&Q2u_rh{i0M9EFTV zs*M2i(2vBow8__R31q;|j2j#&wx0QyAGsDNlaE~spMz37pSo5yD2aU`NXa}-rh;TR zRsGSB{9r+oQ5=_LlKxj$3`bsatE4{my}0@s zdIbqAY(yqSdk(_WTB&a`C>>NM70O9XVNw((#j*_h^Le-wSox6g=_5hF2Eq9OJ)}x^ zRS0Z?4G9Ex`E8RPn$&Dofuf>Lh66tgPA+0)994+*UXu7ra+bt1qt318ez>5ifk4Ia zp)~@W5A6|7Jw`4~N-n_!CQFl&C649%r^|WFjT9#cN3z7{e&iSlPSGvH?pb?EMI!8b zt4r6Q?!6Hd$#7~4SAt~jm(vd%h)$EWM zJjc!bv6A8HiYU2oO|Tj&0F+Aw4qjclTyfw>cv(DuoFVLZ-i9SW5l$k8E5y(oF)Wi! zn$#ZDme_pl_c$&K1R6bBDUtSq$0|i)iLb0%l~4K7;nkF7rNYUjr&MIMaH$HHTeM=u znDC?(60@b!Dw1+Irzm_vzagOJN5wJwUxY;YAwd(kjL zIP`jW>Jh6am4AcGh@Bb!ffu4R`sBC$8Tjii9WGTN7(FJxNjk`q^X`a^p-Par6aY_*ZaJcNN&q*Z1twhY_!n^ zL2J^xv$LkCn)YW|nOvG{wMj_N_=aM!4DUIZu0vUFsLtd0hElnL?>U%x>F?5c;-$Ys zZ-d-YtBUw8uq`S~x2mA;8i`3!Cb=ZbNwbFhom^hegh*LD<(L?Ap#4(y7}@p zT2SGx_&%l~<#fYBThnv5ot>R)#5otRGZwLQ`bfGtX!B~a4ZN|o3W~L-v3y!<%cr%i z8*8)1ZZcD`>C1{0uY=~F z5%_0yWY;xJO-W(uwX8u%xyC$ePmq( z={5e@Vm|gc{eXp`P@~|)tQGwpe$3U?jWsW{Q6?RYe93yVUsLm76K@?9j_W3uFnJ@d z4=fj7T{&IxfPF7IOxzTQUUZncN#U{pDffKL_Ckb%lGJ$_%quEU66{R}6?Sa0O=Eeg zvuOrws=bMsGhEqst@`0oxgHvC0)X5~4F}Xx;4#B?+IG%RW7zu*$a~0`;^9zFXf&pY zj>8ci>Ysd)2JxKUAM03$9X<2h>;z8V-tV{d(MSdX7T#DvntS;M{d{p6vcNn|;)|5( z8J-nirql=U8J;wXOjzCY44)U}VLXZT3|}-W=9?(^toU-8P=6dGi`l83;iWg!<4B-P zAK~ZC<_WNgp5de71MHTXLA;2d_|mKIQHQY)+-<_{uFoRT@u^qe4W>yFC$$>KvWAn_ znD}8xlVzojj9aMkqe|2JjRBm+;g}|=nNkrm(KGy@9J%^7N!VD=@CUV-KWtPpVar(0 z@JUgA;d7dt`C+I=Q@&^TaShf-Dt3c)Kjb>r<;Igf!jFm%vWSjnl>5Ld`Uu}_U_l^y z9{K^DiV^7nV z3Nw6f3zcVa0w{XgAaE4tUp_3tSx<_mPfEV`C)8xom<2wM6Fn;(3~{HX5l;%GMWa z@XprZtqYsUIGsVr?MTIw)`Ku1nZzgYqd4X}JLPi`h^dS)iDQ0;CHWw68I8GNRj`th z556O#B%)}3AKK1+K7HsXJjDjb40#6|Lph?UAS}!9kPhvhiVgNe{Oe7VP3c_Eu)e2b z(?(Skz9o8ij*W*tpBk(>dya4)FVP6^w-G|vc6tbnHqhz$I#rHJC_dpa_roL5WN25{ zzWU-XU;T$4ef4*Ls|%u!5cY{;^qn182Ymt(nUau36F%J%{}LTv;vpe~4(+}|S%2g; zS!UIcrF70BsnP_wz(p=w%yn6+zx+!OBZpT( zh5#T~$tQsyJ)%5WZh?2Y;5?3s@MOu*>(S#-pzs608*p^-lE+sS5)$amJmsLT_22&J zr>{T%Q+-274~n+W@E8w6qIA3>(t&jyO75@8@dG@37eP{;VZKF#6r}-8oWOcgU!}~z zPsSC60O%5{^#|g!A=@A!eU4HVj#ZVu8Yd~BED+0HmG#ddmJDX-`|+i#TbiXgZOv)x z_>6_2tE=tHqc{XDT;mg;Pj$Q+yZQs$(%SdhfoT(4vrI=LebdpLbK40l%_cVKYYzNP z?fpPh(Hs-XOy_AYu%ML*E#Plz_Col5p=ZFpoAtxPsQyNE=P;d&A5j@sOf+; zrfDjLlXoL=5QmFdbiJmmkeT78v0zFF0h;sW@foORciMNU2es{G;pj>rJ()IZDktc5PMrX0%LObMEc0YnlC~mT}g! zOla<#`!8mut#zNaNaxt@k&f2CXSal&Db~uSKDfIk40oy}#agGtOxo6BsVYRQ$OaOm z3*!0m7;*w~E*R=5kLUUbVa_;Y>b(5LPhbA=-~RUB{r#(d^-I8n#A?pN&Nq+M7U^rC zs7;%6ZOtaFzS$zS)*?3iPTNnr_qu`UknX-_nH|j`PTTBgofICl4*X5q=cY~iP))$F zprM&Vg8yGU=xKIq+B-L$d%bh##jJ1cPtEqZP5RSzAR9rCqI*qspPKnwKA@@Derk88 z?Ldx3>zHy7W+ye}xZtl!QryGuSE>5$6ocHi+%nltwXeST@#` zfQZ(;{`vmBPT1ADTG#Bpc+k=8-nlci+koXJ7TyyKKEjT8dt6x-iznQ%oizz~frk}K zw{GQLZ$RD4aiKJf(|&6^*Gy;9bKYR>N(ZK z|0zMg{Nb;D`$xah^o<#0wxj+9t9ULK(5EbAry)Ij)AHQPS7z1DoW)~5tona;SJ}(m z4H<hX{!$2V%p^-pKS6|-!!96bhDB9aJX ztG<^x(gKjm`?m8<0DA)*nfG0LZ9t(Bq$k_T7_yxWK<-B43XHo^nW%g{K6v5>&o@w4 zd_94WMV9nQk-R9!qxNz78%9%Bt&gi#UK!y#_?}{5AF^m1U%ZX~S(|JcvN6>$h>8%B z$MF6gx)g9SJml*#_Tf1MHI(uYInjK(YooJNX$iOL1&VShMm0Z5xH*Ei)tc88&WN9f zJK-Z8dw`QTdLq&oT{=`dj=jxw?OY0bcqlf@b*whmi?LOPGupVHR2W9BeU&jjsx0;Q zqcOeQYD+Y>!5ShCzgt%ZTNzAtd*jLrZ3RYwpNg05Ypz;ooc(WM&F#R#*cHoeTiXxK zeNFz^qzw)Llv||NYObB@`!IE^-riufnfBXY+HPVxqLmee3`J_tJY(qV4p)c|>-JZEHQ!X&rY+SA(~s zHtA_S;&in(IFo&{Z)d4UVz*7w>ymaK+*?PpiRG9MX?I^d*e4d4hxed< zAV@-5eW>G*ZcDStzN58BuOH^}-~=Y=I40?K0HSG=4#2c*32p|DT8Fg6{>47*U62m= z#O<~wymYc}KefB0ABfh(?g)R|gpoO2Y((gb|TGwomUI$!G(r=|^ zi&!1AOWJKymRxHje^L!9R3(1bhA7LPrtemEcGq-(jJR!3)fqF|w%taU89m#!;n!*R z`taNB^m_1XcP(2+*}o6R>RR0v!r$?j(Q8{a!r#qL0X-Dq_V;D9T^uigWuB+*s(wDm zT{I8o2+!CZj<6qw@dX{yOs-YzZQii4h_=XsFnO@WyN;&KcbsLf`J2r5NZp}@#oq{v6|#Ev2keHA z@&{qz)!#m@y`AK5@ z(2JBNM{#tO__JsrU=2qd(s<64N!32QP}r@{ew z`i=sx5_g89K`l$D(tspX1pJL^Gpy^V_^|g+|6p%-4~mMs>}y7yVHKik%vWylsLEnf zn58npg4B5<8Kt|v)s0#+6)D+#JYXfITc+1k_%p-c)(l5za26+q%4pK!GudG|k{l@W zsA?|6;PB8Iu-i?bhkVFJ@&qqME}TEeU$T5U8D94l8?!AtAIj{ziujE(A&uJ`Hw?%( z0yOQBJnx3V2zfiWw;NDPE9#Bi?H1jwxwfUYtDF<7ANZ@y#09Tu038PSVhxNm4 zJvDDv9(}8vVbgCW@q$w__Y;2xr{@ygUCF>yk|(XPi181Sc=iZt8X`Y-2AoaDTWYAx zPs$hb`yxkFrayg8tr2+znXhT|8W(D9*>=j&I*|13`K`oR=5^NLrsqz6Y3 zG?nJ)rzx96C$XF$M1zq$jrVvOC!D5SeLyRi8YC)HZ+(D6Ya}$bOvbf0DB%Iy-9;N3 zve9iw*4+q{jWG9Exw2)rIa*9T$Fj=RAkR^54t`Ka0K*%5+w~}` z)@o_9d#ssS>-4N!=|JKcc(2;Kl7z-oD4cYoDxB`!5V@;m%y;`h#BN404Dt3&4&oXW zQkQSRq8lp${}s8(z$g?ph>DuUv4|aQG^dElnldt~%$1nflpS#+gOeNk6{b-y9{+#NSQ%JeL0UKz8(yH2SL=LLPsK?+q zXVY%Ym6)&)y`ie02wWVUdv_J*U-*n`1w$yK6jv!#BY#elO666Rxr(7kbe0D*N~Bl= zo-7L@$^m?zya!6gc(&)y*`7?--V0gE563L=Zmwt)#AEv8(fy;`nKYUhLfMYUnfCIP zNcn5oGtgDwW|E3inXeO-B5%D`c{0dQAIB^a=a(5xQ!1*dIDLeqI1rSuR^=+N=9;3lj;^k% zpS~Mwk_Q{GUw{5fsS3XO;-@cv_=m4Q`$G2i`m_J@+dunEcWZS;+3WxE-(LOr-+ujf z|4DC(fn7Oqkq=$Q%YX4dUjNN6|KT@3dHwmXRigRv+@)tjo zWY;lA+o_%5TJ~yPX4Lk@AMEYkl-n1T^)Zn%c$TkQ!V(9oG*5uf*Yz#6s|!@oP~?qQ z2O+7bc5Fx*vVa;E=DV<$=v6`N8Z=Mx*7x*XT3MRkIB+KWuP3aQp2=J6Fmc&DkGJJ* zpWR$3?<0%@;dzr-T$hsV0TTcgzmiEB?XWMsBG?`{^@+8 zWBt=Pg`ar@|4!JMj>VN}I@V8T@GorCk4lvU0r4`}_dE7Ho3~{*GdLeJfu3jad9$0f z6i&DSCeLXUvEBSa8c(_2xXj3Fa6=8xgUCN;6F7+iCu!%Wv7d|&$wdPDiS&{i6cIk9 zQN^T8r}4!}?5Et&A)QEM_30=>L<*FsnCq@_94uxu;v`6@&*|Ne!keM9XujaURPxRY zkK&@{X*^!SsaYD0kESeyi)%34E)hx}x~NAlX>b(JW^i+d4s+E}1BmpqOCZ+`KEvgg z3cd<}jeAl=x}(XVx{d~PXNRiZjMBK=Hg|{@fU*;@DUcLTuRz0$aC*s)WU7S6uR#n$ z;J2Kx8I2cQ;9UWQT?N?LFm#xdj<9X5Rb5rJ?=k~_y+ zfo@+2>?kcZe!bEEMXjmilL@hMnheodS z%iUR}_qPy=#AjzIRd+VwO|5lx3b@fUQ!-ymfvVh8P@{e>e)-4xUh(<~ZZ2}4#I{;l zU&i1(THNH)`1En{>Eq_76K_rv*o%hiFG&PD?v*MZ71s}x0lb2>za9C))s(Mq9&4DD zXfm4^#A%7B=EslAdt@re5aTN@7+~mjuQIf1d3iTYTE9xBhFL4yaH|JwohBX|l-D~{ zByeXZIj|1Zk^RceTuFmQ>W;28J?(khZ<6-}6}QX?IC~r}w{vdQ=P78Bde)%Y$!{hMGCc^c6JOqA9OyZ4fERF#pc`8%U8ALbnM2g>(jH|?drlT zzYFlw;u44NRxfe*c*`XYUElBfzTYY?arlAvX_k%9;2-Vn{bMbS7fC=L`13i7CQlw6 dd)-!xSa!Sb+owJ9DO_wZ|9^8>cAlkL000 $options.onPointerDown && $options.onPointerDown(...args)),\n onPointermove: _cache[2] || (_cache[2] = (...args) => $options.onPointerMove && $options.onPointerMove(...args)),\n onPointerup: _cache[3] || (_cache[3] = (...args) => $options.onPointerUp && $options.onPointerUp(...args)),\n onPointercancel: _cache[4] || (_cache[4] = (...args) => $options.onPointerUp && $options.onPointerUp(...args)),\n onDblclick: _cache[5] || (_cache[5] = _withModifiers((...args) => $options.onDblClick && $options.onDblClick(...args), [\"prevent\"]))\n }, [$props.isImage ? (_openBlock(), _createElementBlock(\"img\", {\n key: 0,\n class: \"tm-media\",\n src: $props.src,\n draggable: \"false\",\n style: _normalizeStyle($options.mediaStyle),\n onLoad: _cache[0] || (_cache[0] = (...args) => $options.onLoad && $options.onLoad(...args))\n }, null, 44, _hoisted_1)) : $props.isVideo ? (_openBlock(), _createElementBlock(\"video\", {\n key: 1,\n class: \"tm-media\",\n src: $props.src,\n controls: \"\",\n autoplay: \"\",\n playsinline: \"\",\n style: _normalizeStyle($options.mediaStyle)\n }, null, 12, _hoisted_2)) : _createCommentVNode(\"\", true)], 544);\n}","export default {\n name: \"TransformMedia\",\n props: {\n file: {\n type: Object,\n required: true\n },\n src: {\n type: String,\n required: true\n },\n isImage: {\n type: Boolean,\n default: true\n },\n isVideo: {\n type: Boolean,\n default: false\n }\n },\n data() {\n return {\n pointers: new Map(),\n // transform state\n scale: 1,\n rotation: 0,\n // 落地的旋转角度:0, 90, 180, 270\n rotatePreview: 0,\n // 旋转预览角度(-90~+90,跟手)\n tx: 0,\n ty: 0,\n // 图片原始尺寸\n naturalWidth: 0,\n naturalHeight: 0,\n // gesture start snapshots\n startScale: 1,\n startRotation: 0,\n startTx: 0,\n startTy: 0,\n startCenter: null,\n startDist: 0,\n startAngle: 0,\n // drag\n dragging: false,\n dragStart: null,\n viewportRect: null,\n // bounds\n minScale: 1,\n maxScale: 4,\n // 手势模式锁定:'pinch' | 'rotate' | null\n gestureMode: null\n };\n },\n computed: {\n isActiveTransform() {\n return this.scale > 1.001 || this.pointers.size >= 2 || this.dragging;\n },\n // 实际显示的旋转角度 = 落地角度 + 预览角度\n displayRotation() {\n return this.rotation + this.rotatePreview;\n },\n // 旋转时缩小系数(中间最小,两端恢复)\n rotateShrink() {\n const p = Math.min(1, Math.abs(this.rotatePreview) / 90);\n const k = Math.sin(Math.PI * p);\n return 1 - 0.12 * k; // 最多缩小12%\n },\n mediaStyle() {\n const finalScale = this.scale * this.rotateShrink;\n const inGesture = this.pointers.size > 0;\n return {\n transform: `translate3d(${this.tx}px, ${this.ty}px, 0) scale(${finalScale}) rotate(${this.displayRotation}deg)`,\n transition: inGesture ? \"none\" : \"transform 0.25s ease\",\n transformOrigin: \"center center\"\n };\n }\n },\n watch: {\n isActiveTransform(v) {\n this.$emit(v ? \"lock\" : \"unlock\");\n }\n },\n methods: {\n onLoad(e) {\n // 记录图片原始尺寸\n const img = e.target;\n this.naturalWidth = img.naturalWidth;\n this.naturalHeight = img.naturalHeight;\n },\n reset() {\n this.scale = 1;\n this.rotation = 0;\n this.rotatePreview = 0;\n this.tx = 0;\n this.ty = 0;\n this.pointers.clear();\n this.dragging = false;\n this.$emit(\"unlock\");\n },\n clamp(v, min, max) {\n return Math.max(min, Math.min(max, v));\n },\n // iOS 风格橡皮筋阻尼函数\n rubberBand(distance, dimension, constant = 0.55) {\n return distance * dimension * constant / (dimension + constant * distance);\n },\n getViewportRect() {\n return this.$refs.viewport?.getBoundingClientRect();\n },\n // 计算放大后允许的最大平移范围\n getPanBounds() {\n const rect = this.$refs.viewport?.getBoundingClientRect();\n if (!rect) return {\n maxX: 0,\n maxY: 0,\n vw: 0,\n vh: 0\n };\n const vw = rect.width,\n vh = rect.height;\n const img = this.$el.querySelector('img, video');\n const iw = img?.clientWidth || vw;\n const ih = img?.clientHeight || vh;\n const sw = iw * this.scale;\n const sh = ih * this.scale;\n const maxX = Math.max(0, (sw - vw) / 2);\n const maxY = Math.max(0, (sh - vh) / 2);\n return {\n maxX,\n maxY,\n vw,\n vh\n };\n },\n // 应用边界阻尼\n applyBoundWithRubber(value, max, dimension) {\n if (value > max) {\n return max + this.rubberBand(value - max, dimension, 0.55);\n }\n if (value < -max) {\n return -max - this.rubberBand(-max - value, dimension, 0.55);\n }\n return value;\n },\n calcTwoPointer() {\n const pts = Array.from(this.pointers.values());\n const p0 = pts[0],\n p1 = pts[1];\n const dx = p1.x - p0.x;\n const dy = p1.y - p0.y;\n const dist = Math.hypot(dx, dy);\n const angle = Math.atan2(dy, dx) * (180 / Math.PI);\n const center = {\n x: (p0.x + p1.x) / 2,\n y: (p0.y + p1.y) / 2\n };\n return {\n dist,\n angle,\n center\n };\n },\n // 角度归一化到 -180~180\n normalizeAngle(deg) {\n deg = (deg % 360 + 360) % 360;\n return deg > 180 ? deg - 360 : deg;\n },\n onPointerDown(e) {\n e.currentTarget.setPointerCapture?.(e.pointerId);\n this.viewportRect = this.getViewportRect();\n this.pointers.set(e.pointerId, {\n x: e.clientX,\n y: e.clientY\n });\n\n // 2指开始:初始化 pinch/rotate 基准\n if (this.pointers.size === 2) {\n const {\n dist,\n angle,\n center\n } = this.calcTwoPointer();\n this.startDist = dist;\n this.startAngle = angle;\n this.startCenter = center;\n this.startScale = this.scale;\n this.startRotation = this.rotation;\n this.startTx = this.tx;\n this.startTy = this.ty;\n this.dragging = false;\n this.gestureMode = null;\n this.rotatePreview = 0;\n return;\n }\n\n // 1指:如果已放大,则进入拖拽\n if (this.scale > 1.001) {\n this.dragging = true;\n this.dragStart = {\n x: e.clientX,\n y: e.clientY\n };\n this.startTx = this.tx;\n this.startTy = this.ty;\n }\n },\n onPointerMove(e) {\n if (!this.pointers.has(e.pointerId)) return;\n this.pointers.set(e.pointerId, {\n x: e.clientX,\n y: e.clientY\n });\n\n // 2指:缩放 + 旋转(带死区锁定)\n if (this.pointers.size === 2) {\n e.preventDefault();\n const {\n dist,\n angle,\n center\n } = this.calcTwoPointer();\n const scaleFactor = dist / (this.startDist || dist);\n const scaleChange = Math.abs(scaleFactor - 1);\n const deltaAngle = this.normalizeAngle(angle - this.startAngle);\n const angleChange = Math.abs(deltaAngle);\n\n // 阈值\n const rotateStartDeg = 8; // 8° 开始进入旋转模式\n const pinchStartScale = 0.08; // 8% 缩放变化开始进入缩放模式\n\n // 判断手势模式(只在第一次超过死区时锁定)\n // 优先判断旋转:角度变化超过8°就进入旋转模式(不管缩放)\n if (!this.gestureMode) {\n if (angleChange >= rotateStartDeg) {\n this.gestureMode = 'rotate';\n } else if (scaleChange >= pinchStartScale) {\n this.gestureMode = 'pinch';\n } else {\n return; // 还在死区内\n }\n }\n\n // 旋转模式:预览角跟手,限制在 -90~+90\n if (this.gestureMode === 'rotate') {\n this.scale = this.startScale; // 锁定缩放\n this.rotatePreview = this.clamp(deltaAngle, -90, 90);\n return;\n }\n\n // 缩放模式\n if (this.gestureMode === 'pinch') {\n this.scale = this.clamp(this.startScale * scaleFactor, this.minScale, this.maxScale);\n this.rotatePreview = 0;\n }\n\n // 跟随双指中心移动\n if (this.startCenter && this.viewportRect) {\n const cx0 = this.startCenter.x - this.viewportRect.left - this.viewportRect.width / 2;\n const cy0 = this.startCenter.y - this.viewportRect.top - this.viewportRect.height / 2;\n const cx1 = center.x - this.viewportRect.left - this.viewportRect.width / 2;\n const cy1 = center.y - this.viewportRect.top - this.viewportRect.height / 2;\n this.tx = this.startTx + (cx1 - cx0);\n this.ty = this.startTy + (cy1 - cy0);\n }\n return;\n }\n\n // 1指:拖拽(只在 scale>1 时)+ 边界阻尼\n if (this.dragging && this.scale > 1.001) {\n e.preventDefault();\n const dx = e.clientX - this.dragStart.x;\n const dy = e.clientY - this.dragStart.y;\n const rawX = this.startTx + dx;\n const rawY = this.startTy + dy;\n const {\n maxX,\n maxY,\n vw,\n vh\n } = this.getPanBounds();\n this.tx = this.applyBoundWithRubber(rawX, maxX, vw);\n this.ty = this.applyBoundWithRubber(rawY, maxY, vh);\n }\n },\n onPointerUp(e) {\n if (this.pointers.has(e.pointerId)) this.pointers.delete(e.pointerId);\n\n // 两指结束:处理旋转吸附\n if (this.pointers.size < 2 && this.gestureMode === 'rotate') {\n this.finishRotate();\n this.gestureMode = null;\n }\n if (this.pointers.size < 2) {\n this.startCenter = null;\n this.startDist = 0;\n this.startAngle = 0;\n this.gestureMode = null;\n }\n if (this.pointers.size === 0) {\n this.dragging = false;\n // 缩放回到1附近,自动归位\n if (this.scale <= 1.001) {\n this.scale = 1;\n this.tx = 0;\n this.ty = 0;\n } else {\n // 放大状态:回弹到合法范围\n const {\n maxX,\n maxY\n } = this.getPanBounds();\n this.tx = Math.max(-maxX, Math.min(maxX, this.tx));\n this.ty = Math.max(-maxY, Math.min(maxY, this.ty));\n }\n }\n },\n // 松手后吸附到 0° 或 ±90°\n finishRotate() {\n const d = this.rotatePreview;\n const commitDeg = 30; // 超过30°就翻到90°\n\n let target = 0;\n if (Math.abs(d) >= commitDeg) {\n target = d > 0 ? 90 : -90;\n }\n\n // 计算新的落地角度\n const newRot = ((this.rotation + target) % 360 + 360) % 360;\n\n // 落地并重置预览角(transition 会自动处理动画)\n this.rotation = newRot;\n this.rotatePreview = 0;\n\n // 计算旋转后的铺满缩放\n this.updateFillScale();\n },\n // 计算旋转后让图片铺满屏幕的缩放比例\n updateFillScale() {\n const rect = this.$refs.viewport?.getBoundingClientRect();\n if (!rect || !this.naturalWidth || !this.naturalHeight) return;\n const vw = rect.width;\n const vh = rect.height;\n const nw = this.naturalWidth;\n const nh = this.naturalHeight;\n\n // 旋转 90° 或 270° 时宽高交换\n const rot = this.rotation % 360;\n const isRotated = rot === 90 || rot === 270;\n const effW = isRotated ? nh : nw;\n const effH = isRotated ? nw : nh;\n\n // 计算 contain 模式下的基础缩放(让图片完全显示)\n const containScale = Math.min(vw / effW, vh / effH);\n // 计算 cover 模式下的缩放(让图片铺满,可能裁切)\n const coverScale = Math.max(vw / effW, vh / effH);\n\n // 旋转后使用 cover 模式铺满屏幕\n if (isRotated) {\n // 计算相对于 contain 的放大倍数\n const fillScale = coverScale / containScale;\n this.scale = Math.min(fillScale, this.maxScale);\n this.tx = 0;\n this.ty = 0;\n } else {\n // 0° 或 180° 恢复正常\n this.scale = 1;\n this.tx = 0;\n this.ty = 0;\n }\n },\n onDblClick() {\n if (this.scale > 1.001) {\n this.scale = 1;\n this.tx = 0;\n this.ty = 0;\n } else {\n this.scale = 2;\n }\n }\n }\n};","/* unplugin-vue-components disabled */import { render } from \"./TransformMedia.vue?vue&type=template&id=5c291694&scoped=true\"\nimport script from \"./TransformMedia.vue?vue&type=script&lang=js\"\nexport * from \"./TransformMedia.vue?vue&type=script&lang=js\"\n\nimport \"./TransformMedia.vue?vue&type=style&index=0&id=5c291694&scoped=true&lang=css\"\n\nimport exportComponent from \"../../node_modules/vue-loader/dist/exportHelper.js\"\nconst __exports__ = /*#__PURE__*/exportComponent(script, [['render',render],['__scopeId',\"data-v-5c291694\"]])\n\nexport default __exports__","import { toDisplayString as _toDisplayString, createElementVNode as _createElementVNode, renderList as _renderList, Fragment as _Fragment, openBlock as _openBlock, createElementBlock as _createElementBlock, createCommentVNode as _createCommentVNode, withModifiers as _withModifiers, normalizeClass as _normalizeClass, normalizeStyle as _normalizeStyle, resolveComponent as _resolveComponent, createBlock as _createBlock } from \"vue\";\nconst _hoisted_1 = {\n class: \"public-browse\"\n};\nconst _hoisted_2 = {\n class: \"header\"\n};\nconst _hoisted_3 = {\n class: \"header-left\"\n};\nconst _hoisted_4 = {\n class: \"logo\"\n};\nconst _hoisted_5 = {\n class: \"header-center\"\n};\nconst _hoisted_6 = {\n class: \"breadcrumb\"\n};\nconst _hoisted_7 = [\"onClick\"];\nconst _hoisted_8 = {\n class: \"header-right\"\n};\nconst _hoisted_9 = {\n class: \"file-count\"\n};\nconst _hoisted_10 = {\n key: 0,\n class: \"loading-container\"\n};\nconst _hoisted_11 = {\n key: 1,\n class: \"error-container\"\n};\nconst _hoisted_12 = {\n key: 2,\n class: \"gallery-container\",\n ref: \"galleryContainer\"\n};\nconst _hoisted_13 = {\n key: 0,\n class: \"folders-section\"\n};\nconst _hoisted_14 = {\n class: \"folders-grid\"\n};\nconst _hoisted_15 = [\"onClick\"];\nconst _hoisted_16 = {\n class: \"folder-name\"\n};\nconst _hoisted_17 = {\n class: \"waterfall\",\n ref: \"waterfall\"\n};\nconst _hoisted_18 = [\"onClick\"];\nconst _hoisted_19 = [\"src\", \"alt\", \"onLoad\"];\nconst _hoisted_20 = [\"src\", \"onLoadedmetadata\"];\nconst _hoisted_21 = {\n key: 2,\n class: \"file-placeholder\"\n};\nconst _hoisted_22 = {\n class: \"overlay\"\n};\nconst _hoisted_23 = {\n class: \"overlay-actions\"\n};\nconst _hoisted_24 = [\"onClick\"];\nconst _hoisted_25 = [\"onClick\"];\nconst _hoisted_26 = {\n ref: \"loadTrigger\",\n class: \"load-trigger\"\n};\nconst _hoisted_27 = {\n key: 0,\n class: \"loading-more\"\n};\nconst _hoisted_28 = {\n key: 1,\n class: \"no-more\"\n};\nconst _hoisted_29 = [\"src\"];\nconst _hoisted_30 = [\"src\"];\nconst _hoisted_31 = {\n class: \"page-indicator\"\n};\nexport function render(_ctx, _cache, $props, $setup, $data, $options) {\n const _component_TransformMedia = _resolveComponent(\"TransformMedia\");\n return _openBlock(), _createElementBlock(\"div\", _hoisted_1, [_createElementVNode(\"header\", _hoisted_2, [_createElementVNode(\"div\", _hoisted_3, [_createElementVNode(\"span\", _hoisted_4, _toDisplayString($options.siteName), 1)]), _createElementVNode(\"div\", _hoisted_5, [_createElementVNode(\"div\", _hoisted_6, [_createElementVNode(\"span\", {\n class: \"breadcrumb-item\",\n onClick: _cache[0] || (_cache[0] = (...args) => $options.goToRoot && $options.goToRoot(...args))\n }, _toDisplayString($options.rootDirName), 1), (_openBlock(true), _createElementBlock(_Fragment, null, _renderList($options.pathParts, (part, index) => {\n return _openBlock(), _createElementBlock(_Fragment, {\n key: index\n }, [_cache[18] || (_cache[18] = _createElementVNode(\"span\", {\n class: \"breadcrumb-sep\"\n }, \"/\", -1)), _createElementVNode(\"span\", {\n class: \"breadcrumb-item\",\n onClick: $event => $options.goToPath(index)\n }, _toDisplayString(part), 9, _hoisted_7)], 64);\n }), 128))])]), _createElementVNode(\"div\", _hoisted_8, [_createElementVNode(\"span\", _hoisted_9, _toDisplayString($data.totalCount) + \" 个文件\", 1)])]), $data.loading && $data.files.length === 0 ? (_openBlock(), _createElementBlock(\"div\", _hoisted_10, [...(_cache[19] || (_cache[19] = [_createElementVNode(\"div\", {\n class: \"loading-spinner\"\n }, null, -1), _createElementVNode(\"p\", null, \"加载中...\", -1)]))])) : $data.error ? (_openBlock(), _createElementBlock(\"div\", _hoisted_11, [_createElementVNode(\"p\", null, _toDisplayString($data.error), 1), $data.canRetry ? (_openBlock(), _createElementBlock(\"button\", {\n key: 0,\n onClick: _cache[1] || (_cache[1] = (...args) => $options.loadFiles && $options.loadFiles(...args)),\n class: \"retry-btn\"\n }, \"重试\")) : _createCommentVNode(\"\", true)])) : (_openBlock(), _createElementBlock(\"div\", _hoisted_12, [$options.folders.length > 0 ? (_openBlock(), _createElementBlock(\"div\", _hoisted_13, [_createElementVNode(\"div\", _hoisted_14, [(_openBlock(true), _createElementBlock(_Fragment, null, _renderList($options.folders, folder => {\n return _openBlock(), _createElementBlock(\"div\", {\n key: folder.name,\n class: \"folder-card\",\n onClick: $event => $options.enterFolder(folder.name)\n }, [_cache[20] || (_cache[20] = _createElementVNode(\"div\", {\n class: \"folder-icon\"\n }, [_createElementVNode(\"svg\", {\n viewBox: \"0 0 24 24\",\n fill: \"currentColor\"\n }, [_createElementVNode(\"path\", {\n d: \"M10 4H4c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V8c0-1.1-.9-2-2-2h-8l-2-2z\"\n })])], -1)), _createElementVNode(\"span\", _hoisted_16, _toDisplayString($options.getFolderName(folder.name)), 1)], 8, _hoisted_15);\n }), 128))])])) : _createCommentVNode(\"\", true), _createElementVNode(\"div\", _hoisted_17, [(_openBlock(true), _createElementBlock(_Fragment, null, _renderList($options.columns, (column, colIndex) => {\n return _openBlock(), _createElementBlock(\"div\", {\n key: colIndex,\n class: \"waterfall-column\"\n }, [(_openBlock(true), _createElementBlock(_Fragment, null, _renderList(column, file => {\n return _openBlock(), _createElementBlock(\"div\", {\n key: file.name,\n class: \"waterfall-item\",\n onClick: $event => $options.openPreview(file)\n }, [_createElementVNode(\"div\", {\n class: _normalizeClass([\"image-wrapper\", {\n loaded: file.loaded\n }])\n }, [$options.isImage(file) ? (_openBlock(), _createElementBlock(\"img\", {\n key: 0,\n src: $options.getFileUrl(file.name),\n alt: file.name,\n loading: \"lazy\",\n onLoad: $event => $options.onImageLoad($event, file),\n onError: _cache[2] || (_cache[2] = (...args) => $options.handleImageError && $options.handleImageError(...args))\n }, null, 40, _hoisted_19)) : $options.isVideo(file) ? (_openBlock(), _createElementBlock(\"video\", {\n key: 1,\n src: $options.getFileUrl(file.name),\n muted: \"\",\n loop: \"\",\n preload: \"metadata\",\n onLoadedmetadata: $event => $options.onVideoLoad($event, file),\n onMouseenter: _cache[3] || (_cache[3] = $event => $event.target.play()),\n onMouseleave: _cache[4] || (_cache[4] = $event => $event.target.pause())\n }, null, 40, _hoisted_20)) : (_openBlock(), _createElementBlock(\"div\", _hoisted_21, [...(_cache[21] || (_cache[21] = [_createElementVNode(\"svg\", {\n viewBox: \"0 0 24 24\",\n fill: \"currentColor\"\n }, [_createElementVNode(\"path\", {\n d: \"M14 2H6c-1.1 0-2 .9-2 2v16c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V8l-6-6zm-1 7V3.5L18.5 9H13z\"\n })], -1)]))])), _createElementVNode(\"div\", _hoisted_22, [_createElementVNode(\"div\", _hoisted_23, [_createElementVNode(\"button\", {\n class: \"action-btn\",\n onClick: _withModifiers($event => $options.copyLink(file.name), [\"stop\"]),\n title: \"复制链接\"\n }, [...(_cache[22] || (_cache[22] = [_createElementVNode(\"svg\", {\n viewBox: \"0 0 24 24\",\n fill: \"currentColor\"\n }, [_createElementVNode(\"path\", {\n d: \"M3.9 12c0-1.71 1.39-3.1 3.1-3.1h4V7H7c-2.76 0-5 2.24-5 5s2.24 5 5 5h4v-1.9H7c-1.71 0-3.1-1.39-3.1-3.1zM8 13h8v-2H8v2zm9-6h-4v1.9h4c1.71 0 3.1 1.39 3.1 3.1s-1.39 3.1-3.1 3.1h-4V17h4c2.76 0 5-2.24 5-5s-2.24-5-5-5z\"\n })], -1)]))], 8, _hoisted_24), _createElementVNode(\"button\", {\n class: \"action-btn\",\n onClick: _withModifiers($event => $options.downloadFile(file.name), [\"stop\"]),\n title: \"下载\"\n }, [...(_cache[23] || (_cache[23] = [_createElementVNode(\"svg\", {\n viewBox: \"0 0 24 24\",\n fill: \"currentColor\"\n }, [_createElementVNode(\"path\", {\n d: \"M19 9h-4V3H9v6H5l7 7 7-7zM5 18v2h14v-2H5z\"\n })], -1)]))], 8, _hoisted_25)])])], 2)], 8, _hoisted_18);\n }), 128))]);\n }), 128))], 512), _createElementVNode(\"div\", _hoisted_26, [$data.loading && $data.files.length > 0 ? (_openBlock(), _createElementBlock(\"div\", _hoisted_27, [...(_cache[24] || (_cache[24] = [_createElementVNode(\"div\", {\n class: \"loading-spinner-small\"\n }, null, -1), _createElementVNode(\"span\", null, \"加载中...\", -1)]))])) : !$data.hasMore && $options.mediaFiles.length > 0 ? (_openBlock(), _createElementBlock(\"div\", _hoisted_28, \" 已加载全部 \")) : _createCommentVNode(\"\", true)], 512)], 512)), $data.previewVisible ? (_openBlock(), _createElementBlock(\"div\", {\n key: 3,\n class: \"preview-modal\",\n onClick: _cache[17] || (_cache[17] = _withModifiers((...args) => $options.closePreview && $options.closePreview(...args), [\"self\"]))\n }, [_createElementVNode(\"button\", {\n class: \"preview-close\",\n onClick: _cache[5] || (_cache[5] = _withModifiers((...args) => $options.closePreview && $options.closePreview(...args), [\"stop\"]))\n }, [...(_cache[25] || (_cache[25] = [_createElementVNode(\"svg\", {\n viewBox: \"0 0 24 24\",\n fill: \"currentColor\"\n }, [_createElementVNode(\"path\", {\n d: \"M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z\"\n })], -1)]))]), _createElementVNode(\"div\", {\n class: \"preview-content desktop-only\",\n onClick: _cache[6] || (_cache[6] = _withModifiers(() => {}, [\"stop\"]))\n }, [$options.currentPreviewFile && $options.isImage($options.currentPreviewFile) ? (_openBlock(), _createElementBlock(\"img\", {\n key: 0,\n src: $options.getFileUrl($options.currentPreviewFile.name),\n class: \"preview-image\",\n style: _normalizeStyle($options.desktopImageStyle),\n draggable: \"false\"\n }, null, 12, _hoisted_29)) : $options.currentPreviewFile && $options.isVideo($options.currentPreviewFile) ? (_openBlock(), _createElementBlock(\"video\", {\n key: 1,\n src: $options.getFileUrl($options.currentPreviewFile.name),\n controls: \"\",\n autoplay: \"\",\n class: \"preview-video\",\n style: _normalizeStyle($options.desktopImageStyle)\n }, null, 12, _hoisted_30)) : _createCommentVNode(\"\", true)]), _createElementVNode(\"div\", {\n class: \"preview-content mobile-only\",\n onClick: _cache[13] || (_cache[13] = _withModifiers(() => {}, [\"stop\"]))\n }, [_createElementVNode(\"div\", {\n class: \"swipe-viewport\",\n ref: \"mobileViewport\",\n onTouchstart: _cache[10] || (_cache[10] = (...args) => $options.onSwipeStart && $options.onSwipeStart(...args)),\n onTouchmove: _cache[11] || (_cache[11] = (...args) => $options.onSwipeMove && $options.onSwipeMove(...args)),\n onTouchend: _cache[12] || (_cache[12] = (...args) => $options.onSwipeEnd && $options.onSwipeEnd(...args))\n }, [_createElementVNode(\"div\", {\n class: \"swipe-track\",\n style: _normalizeStyle($options.swipeTrackStyle),\n onTransitionend: _cache[9] || (_cache[9] = (...args) => $options.onSwipeTransitionEnd && $options.onSwipeTransitionEnd(...args))\n }, [(_openBlock(true), _createElementBlock(_Fragment, null, _renderList($options.swipeWindow, (f, i) => {\n return _openBlock(), _createElementBlock(\"div\", {\n class: \"swipe-slide\",\n key: $options.getSlideKey(f, i)\n }, [f ? (_openBlock(), _createBlock(_component_TransformMedia, {\n key: 0,\n file: f,\n src: $options.getFileUrl(f.name),\n \"is-image\": $options.isImage(f),\n \"is-video\": $options.isVideo(f),\n onLock: _cache[7] || (_cache[7] = $event => $data.gestureLocked = true),\n onUnlock: _cache[8] || (_cache[8] = $event => $data.gestureLocked = false)\n }, null, 8, [\"file\", \"src\", \"is-image\", \"is-video\"])) : _createCommentVNode(\"\", true)]);\n }), 128))], 36)], 544)]), $data.previewIndex > 0 ? (_openBlock(), _createElementBlock(\"button\", {\n key: 0,\n class: \"preview-prev desktop-only\",\n onClick: _cache[14] || (_cache[14] = _withModifiers((...args) => $options.prevImage && $options.prevImage(...args), [\"stop\"]))\n }, [...(_cache[26] || (_cache[26] = [_createElementVNode(\"svg\", {\n viewBox: \"0 0 24 24\",\n fill: \"currentColor\"\n }, [_createElementVNode(\"path\", {\n d: \"M15.41 7.41L14 6l-6 6 6 6 1.41-1.41L10.83 12z\"\n })], -1)]))])) : _createCommentVNode(\"\", true), $data.previewIndex < $options.mediaFiles.length - 1 ? (_openBlock(), _createElementBlock(\"button\", {\n key: 1,\n class: \"preview-next desktop-only\",\n onClick: _cache[15] || (_cache[15] = _withModifiers((...args) => $options.nextImage && $options.nextImage(...args), [\"stop\"]))\n }, [...(_cache[27] || (_cache[27] = [_createElementVNode(\"svg\", {\n viewBox: \"0 0 24 24\",\n fill: \"currentColor\"\n }, [_createElementVNode(\"path\", {\n d: \"M10 6L8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z\"\n })], -1)]))])) : _createCommentVNode(\"\", true), _createElementVNode(\"button\", {\n class: \"rotate-btn desktop-only\",\n onClick: _cache[16] || (_cache[16] = _withModifiers((...args) => $options.rotateImage && $options.rotateImage(...args), [\"stop\"])),\n title: \"旋转90°\"\n }, [...(_cache[28] || (_cache[28] = [_createElementVNode(\"svg\", {\n viewBox: \"0 0 24 24\",\n fill: \"currentColor\"\n }, [_createElementVNode(\"path\", {\n d: \"M7.11 8.53L5.7 7.11C4.8 8.27 4.24 9.61 4.07 11h2.02c.14-.87.49-1.72 1.02-2.47zM6.09 13H4.07c.17 1.39.72 2.73 1.62 3.89l1.41-1.42c-.52-.75-.87-1.59-1.01-2.47zm1.01 5.32c1.16.9 2.51 1.44 3.9 1.61V17.9c-.87-.15-1.71-.49-2.46-1.03L7.1 18.32zM13 4.07V1L8.45 5.55 13 10V6.09c2.84.48 5 2.94 5 5.91s-2.16 5.43-5 5.91v2.02c3.95-.49 7-3.85 7-7.93s-3.05-7.44-7-7.93z\"\n })], -1)]))]), _createElementVNode(\"div\", _hoisted_31, _toDisplayString($data.previewIndex + 1) + \" / \" + _toDisplayString($options.mediaFiles.length), 1)])) : _createCommentVNode(\"\", true)]);\n}","import \"core-js/modules/es.array.push.js\";\nimport \"core-js/modules/es.iterator.constructor.js\";\nimport \"core-js/modules/es.iterator.filter.js\";\nimport \"core-js/modules/es.iterator.for-each.js\";\nimport \"core-js/modules/es.iterator.map.js\";\nimport axios from 'axios';\nimport { mapGetters } from 'vuex';\nimport TransformMedia from '@/components/TransformMedia.vue';\nexport default {\n name: 'PublicBrowse',\n components: {\n TransformMedia\n },\n data() {\n return {\n files: [],\n allowedDirs: [],\n rootDir: '',\n currentPath: '',\n totalCount: 0,\n loading: false,\n error: null,\n canRetry: true,\n hasMore: true,\n previewVisible: false,\n previewIndex: 0,\n observer: null,\n pageSize: 24,\n columnCount: 4,\n columnHeights: [0, 0, 0, 0],\n // 桌面端旋转\n imageRotation: 0,\n // 手机端滑动\n swipeX: 0,\n swipeStartX: 0,\n swipeStartY: 0,\n swipeStartT: 0,\n swipeActive: false,\n swipeAnimating: false,\n swipeDir: 0,\n viewportW: 0,\n // 手势锁定(子组件缩放/旋转时锁住轮播)\n gestureLocked: false\n };\n },\n computed: {\n ...mapGetters(['userConfig']),\n siteName() {\n return this.userConfig?.siteTitle || '公开相册';\n },\n rootDirName() {\n return this.rootDir.split('/').filter(Boolean).pop() || '根目录';\n },\n pathParts() {\n if (!this.currentPath || !this.rootDir) return [];\n const relative = this.currentPath.replace(this.rootDir, '').replace(/^\\/+/, '');\n return relative.split('/').filter(Boolean);\n },\n folders() {\n return this.files.filter(f => f.isFolder);\n },\n mediaFiles() {\n return this.files.filter(f => !f.isFolder);\n },\n columns() {\n const cols = Array.from({\n length: this.columnCount\n }, () => []);\n for (const file of this.mediaFiles) {\n const idx = file.columnIndex ?? 0;\n if (idx < this.columnCount) {\n cols[idx].push(file);\n } else {\n cols[0].push(file);\n }\n }\n return cols;\n },\n currentPreviewFile() {\n return this.mediaFiles[this.previewIndex];\n },\n prevPreviewFile() {\n return this.previewIndex > 0 ? this.mediaFiles[this.previewIndex - 1] : null;\n },\n nextPreviewFile() {\n return this.previewIndex < this.mediaFiles.length - 1 ? this.mediaFiles[this.previewIndex + 1] : null;\n },\n desktopImageStyle() {\n return {\n transform: `rotate(${this.imageRotation}deg)`,\n transition: 'transform 0.3s ease'\n };\n },\n swipeWindow() {\n return [this.prevPreviewFile, this.currentPreviewFile, this.nextPreviewFile];\n },\n swipeTrackStyle() {\n // 默认停在中间那页(-viewportW)\n const base = -this.viewportW;\n const x = base + this.swipeX;\n return {\n transform: `translate3d(${x}px, 0, 0)`,\n transition: this.swipeAnimating ? 'transform 0.28s ease' : 'none'\n };\n }\n },\n watch: {\n '$route.params.dir': {\n handler() {\n this.initFromRoute();\n }\n }\n },\n mounted() {\n this.initFromRoute();\n this.setupIntersectionObserver();\n this.updateColumnCount();\n window.addEventListener('resize', this.updateColumnCount);\n },\n beforeUnmount() {\n if (this.observer) {\n this.observer.disconnect();\n }\n window.removeEventListener('resize', this.updateColumnCount);\n },\n methods: {\n // 生成 slide key,切换时让子组件重新挂载以重置 transform\n getSlideKey(f, i) {\n if (!f) return `empty-${i}`;\n // 中间那张用 previewIndex 作为 key 的一部分,确保切换时重新挂载\n if (i === 1) return `${f.name}-${this.previewIndex}`;\n return f.name;\n },\n updateColumnCount() {\n const width = window.innerWidth;\n let newCount;\n if (width < 600) {\n newCount = 2;\n } else if (width < 900) {\n newCount = 3;\n } else {\n newCount = 4;\n }\n if (newCount !== this.columnCount) {\n this.columnCount = newCount;\n this.columnHeights = new Array(this.columnCount).fill(0);\n this.mediaFiles.forEach(f => {\n f.columnIndex = undefined;\n this.assignToColumn(f);\n });\n }\n },\n getShortestColumn() {\n let minIndex = 0;\n let minHeight = this.columnHeights[0];\n for (let i = 1; i < this.columnCount; i++) {\n if (this.columnHeights[i] < minHeight) {\n minHeight = this.columnHeights[i];\n minIndex = i;\n }\n }\n return minIndex;\n },\n assignToColumn(file, height = 200) {\n const colIndex = this.getShortestColumn();\n file.columnIndex = colIndex;\n this.columnHeights[colIndex] += height;\n },\n onImageLoad(event, file) {\n const img = event.target;\n const ratio = img.naturalHeight / img.naturalWidth;\n const height = 280 * ratio;\n if (file.columnIndex === undefined) {\n this.assignToColumn(file, height);\n }\n file.loaded = true;\n },\n onVideoLoad(event, file) {\n const video = event.target;\n const ratio = video.videoHeight / video.videoWidth;\n const height = 280 * ratio;\n if (file.columnIndex === undefined) {\n this.assignToColumn(file, height);\n }\n file.loaded = true;\n },\n setupIntersectionObserver() {\n this.observer = new IntersectionObserver(entries => {\n const entry = entries[0];\n if (entry.isIntersecting && this.hasMore && !this.loading) {\n this.loadMore();\n }\n }, {\n rootMargin: '200px'\n });\n },\n observeLoadTrigger() {\n this.$nextTick(() => {\n if (this.$refs.loadTrigger && this.observer) {\n this.observer.observe(this.$refs.loadTrigger);\n }\n });\n },\n async initFromRoute() {\n const dirParam = this.$route.params.dir || '';\n const dirPath = Array.isArray(dirParam) ? dirParam.join('/') : dirParam;\n if (!dirPath) {\n this.error = '请指定要浏览的目录,例如: /browse/landscape';\n this.canRetry = false;\n return;\n }\n const parts = dirPath.split('/').filter(Boolean);\n this.rootDir = parts[0];\n this.currentPath = dirPath;\n this.files = [];\n this.hasMore = true;\n this.columnHeights = new Array(this.columnCount).fill(0);\n await this.loadFiles();\n this.observeLoadTrigger();\n },\n async loadFiles() {\n this.loading = true;\n this.error = null;\n this.canRetry = true;\n try {\n const res = await axios.get(`/api/public/list?dir=${encodeURIComponent(this.currentPath)}&count=${this.pageSize}`);\n if (res.data.allowedDirs) {\n this.allowedDirs = res.data.allowedDirs;\n }\n const dirs = (res.data.directories || []).map(d => ({\n name: d,\n isFolder: true\n }));\n const files = (res.data.files || []).map(f => ({\n name: f.name,\n isFolder: false,\n metadata: f.metadata,\n columnIndex: undefined\n }));\n files.forEach(f => this.assignToColumn(f));\n this.files = [...dirs, ...files];\n this.totalCount = res.data.totalCount || this.files.length;\n this.hasMore = this.mediaFiles.length < this.totalCount;\n } catch (err) {\n if (err.response?.status === 403) {\n const msg = err.response?.data?.error || '';\n if (msg.includes('disabled')) {\n this.error = '公开浏览功能未启用';\n } else if (msg.includes('not allowed') || msg.includes('No public')) {\n this.error = '该目录不允许公开访问';\n } else {\n this.error = '访问被拒绝';\n }\n this.canRetry = false;\n } else {\n this.error = '加载失败,请重试';\n }\n } finally {\n this.loading = false;\n }\n },\n async loadMore() {\n if (this.loading || !this.hasMore) return;\n this.loading = true;\n try {\n const start = this.mediaFiles.length;\n const res = await axios.get(`/api/public/list?dir=${encodeURIComponent(this.currentPath)}&start=${start}&count=${this.pageSize}`);\n const moreFiles = (res.data.files || []).map(f => ({\n name: f.name,\n isFolder: false,\n metadata: f.metadata,\n columnIndex: undefined\n }));\n moreFiles.forEach(f => this.assignToColumn(f));\n this.files.push(...moreFiles);\n this.hasMore = this.mediaFiles.length < this.totalCount;\n } catch (err) {\n console.error('加载更多失败', err);\n } finally {\n this.loading = false;\n }\n },\n enterFolder(folderPath) {\n const newPath = folderPath.replace(/\\/+$/, '');\n this.$router.push(`/browse/${newPath}`);\n },\n goToRoot() {\n this.$router.push(`/browse/${this.rootDir}`);\n },\n goToPath(index) {\n const parts = this.pathParts.slice(0, index + 1);\n const newPath = this.rootDir + (parts.length ? '/' + parts.join('/') : '');\n this.$router.push(`/browse/${newPath}`);\n },\n getFolderName(path) {\n return path.split('/').filter(Boolean).pop() || path;\n },\n getFileUrl(name) {\n return `${window.location.origin}/file/${name}`;\n },\n isImage(file) {\n const ext = file.name.split('.').pop().toLowerCase();\n return ['jpg', 'jpeg', 'png', 'gif', 'webp', 'bmp', 'svg'].includes(ext);\n },\n isVideo(file) {\n const ext = file.name.split('.').pop().toLowerCase();\n return ['mp4', 'webm', 'ogg', 'mov'].includes(ext);\n },\n handleImageError(e) {\n e.target.style.display = 'none';\n },\n copyLink(name) {\n const url = this.getFileUrl(name);\n navigator.clipboard?.writeText(url).then(() => {\n this.showToast('已复制');\n }).catch(() => {\n const input = document.createElement('input');\n input.value = url;\n document.body.appendChild(input);\n input.select();\n document.execCommand('copy');\n document.body.removeChild(input);\n this.showToast('已复制');\n });\n },\n showToast(msg) {\n const existing = document.querySelector('.copy-toast');\n if (existing) existing.remove();\n const toast = document.createElement('div');\n toast.className = 'copy-toast';\n toast.textContent = msg;\n document.body.appendChild(toast);\n setTimeout(() => toast.classList.add('show'), 10);\n setTimeout(() => {\n toast.classList.remove('show');\n setTimeout(() => toast.remove(), 300);\n }, 1500);\n },\n downloadFile(name) {\n const link = document.createElement('a');\n link.href = this.getFileUrl(name);\n link.download = name.split('/').pop();\n link.click();\n },\n openPreview(file) {\n if (file.isFolder) return;\n const mediaIndex = this.mediaFiles.findIndex(f => f.name === file.name);\n if (mediaIndex >= 0) {\n this.previewIndex = mediaIndex;\n this.previewVisible = true;\n this.imageRotation = 0;\n this.gestureLocked = false;\n document.body.style.overflow = 'hidden';\n this.$nextTick(() => {\n this.viewportW = this.$refs.mobileViewport?.getBoundingClientRect().width || window.innerWidth;\n });\n }\n },\n closePreview() {\n this.previewVisible = false;\n this.imageRotation = 0;\n this.gestureLocked = false;\n document.body.style.overflow = '';\n },\n prevImage() {\n if (this.previewIndex > 0) {\n this.previewIndex--;\n this.imageRotation = 0;\n }\n },\n nextImage() {\n if (this.previewIndex < this.mediaFiles.length - 1) {\n this.previewIndex++;\n this.imageRotation = 0;\n }\n },\n rotateImage() {\n this.imageRotation += 90;\n // 动画结束后归一化(无动画)\n if (this.imageRotation >= 360) {\n setTimeout(() => {\n // 临时禁用 transition\n const el = this.$el.querySelector('.preview-image, .preview-video');\n if (el) {\n el.style.transition = 'none';\n this.imageRotation = 0;\n // 强制重绘后恢复 transition\n el.offsetHeight;\n el.style.transition = '';\n } else {\n this.imageRotation = 0;\n }\n }, 300);\n }\n },\n // 手机端滑动:开始\n onSwipeStart(e) {\n if (this.gestureLocked) return;\n if (this.swipeAnimating) return;\n const t = e.touches[0];\n this.swipeStartX = t.clientX;\n this.swipeStartY = t.clientY;\n this.swipeStartT = performance.now();\n this.swipeX = 0;\n this.swipeActive = false;\n this.viewportW = this.$refs.mobileViewport?.getBoundingClientRect().width || window.innerWidth;\n },\n // 手机端滑动:移动\n onSwipeMove(e) {\n if (this.gestureLocked) return;\n if (this.swipeAnimating) return;\n const t = e.touches[0];\n const dx = t.clientX - this.swipeStartX;\n const dy = t.clientY - this.swipeStartY;\n if (!this.swipeActive) {\n if (Math.abs(dx) < 8) return;\n if (Math.abs(dx) <= Math.abs(dy)) return;\n this.swipeActive = true;\n }\n e.preventDefault();\n let x = dx;\n // 边界阻尼:用 rubberBand 代替线性 *0.3\n if (this.previewIndex === 0 && x > 0) {\n x = this.rubberBand(x, this.viewportW, 0.55);\n } else if (this.previewIndex === this.mediaFiles.length - 1 && x < 0) {\n x = -this.rubberBand(-x, this.viewportW, 0.55);\n }\n this.swipeX = x;\n },\n // 手机端滑动:结束\n onSwipeEnd() {\n if (this.gestureLocked) return;\n if (this.swipeAnimating) return;\n if (!this.swipeActive) {\n this.swipeX = 0;\n return;\n }\n const dt = Math.max(1, performance.now() - this.swipeStartT);\n const vx = this.swipeX / dt;\n const threshold = this.viewportW * 0.2;\n let dir = 0;\n if (this.swipeX <= -threshold || vx <= -0.8) dir = +1;\n if (this.swipeX >= threshold || vx >= 0.8) dir = -1;\n if (dir === -1 && this.previewIndex === 0 || dir === +1 && this.previewIndex === this.mediaFiles.length - 1) {\n dir = 0;\n }\n this.swipeDir = dir;\n this.swipeAnimating = true;\n if (dir === +1) this.swipeX = -this.viewportW;else if (dir === -1) this.swipeX = +this.viewportW;else this.swipeX = 0;\n },\n onSwipeTransitionEnd() {\n if (!this.swipeAnimating) return;\n if (this.swipeDir === +1) this.previewIndex++;\n if (this.swipeDir === -1) this.previewIndex--;\n this.swipeAnimating = false;\n this.swipeDir = 0;\n this.swipeX = 0;\n },\n // iOS 风格橡皮筋阻尼函数\n rubberBand(distance, dimension, constant = 0.55) {\n return distance * dimension * constant / (dimension + constant * distance);\n }\n }\n};","/* unplugin-vue-components disabled */import { render } from \"./PublicBrowse.vue?vue&type=template&id=7aa9aaa3&scoped=true\"\nimport script from \"./PublicBrowse.vue?vue&type=script&lang=js\"\nexport * from \"./PublicBrowse.vue?vue&type=script&lang=js\"\n\nimport \"./PublicBrowse.vue?vue&type=style&index=0&id=7aa9aaa3&scoped=true&lang=css\"\n\nimport exportComponent from \"../../node_modules/vue-loader/dist/exportHelper.js\"\nconst __exports__ = /*#__PURE__*/exportComponent(script, [['render',render],['__scopeId',\"data-v-7aa9aaa3\"]])\n\nexport default __exports__"],"names":["_hoisted_1","_hoisted_2","render","_ctx","_cache","$props","$setup","$data","$options","class","ref","onPointerdown","args","onPointerDown","onPointermove","onPointerMove","onPointerup","onPointerUp","onPointercancel","onDblclick","onDblClick","isImage","key","src","draggable","style","mediaStyle","onLoad","isVideo","controls","autoplay","playsinline","name","props","file","type","Object","required","String","Boolean","default","data","pointers","Map","scale","rotation","rotatePreview","tx","ty","naturalWidth","naturalHeight","startScale","startRotation","startTx","startTy","startCenter","startDist","startAngle","dragging","dragStart","viewportRect","minScale","maxScale","gestureMode","computed","isActiveTransform","this","size","displayRotation","rotateShrink","p","Math","min","abs","k","sin","PI","finalScale","inGesture","transform","transition","transformOrigin","watch","v","$emit","methods","e","img","target","reset","clear","clamp","max","rubberBand","distance","dimension","constant","getViewportRect","$refs","viewport","getBoundingClientRect","getPanBounds","rect","maxX","maxY","vw","vh","width","height","$el","querySelector","iw","clientWidth","ih","clientHeight","sw","sh","applyBoundWithRubber","value","calcTwoPointer","pts","Array","from","values","p0","p1","dx","x","dy","y","dist","hypot","angle","atan2","center","normalizeAngle","deg","currentTarget","setPointerCapture","pointerId","set","clientX","clientY","has","preventDefault","scaleFactor","scaleChange","deltaAngle","angleChange","rotateStartDeg","pinchStartScale","cx0","left","cy0","top","cx1","cy1","rawX","rawY","delete","finishRotate","d","commitDeg","newRot","updateFillScale","nw","nh","rot","isRotated","effW","effH","containScale","coverScale","fillScale","__exports__","_hoisted_3","_hoisted_4","_hoisted_5","_hoisted_6","_hoisted_7","_hoisted_8","_hoisted_9","_hoisted_10","_hoisted_11","_hoisted_12","_hoisted_13","_hoisted_14","_hoisted_15","_hoisted_16","_hoisted_17","_hoisted_18","_hoisted_19","_hoisted_20","_hoisted_21","_hoisted_22","_hoisted_23","_hoisted_24","_hoisted_25","_hoisted_26","_hoisted_27","_hoisted_28","_hoisted_29","_hoisted_30","_hoisted_31","_component_TransformMedia","siteName","onClick","goToRoot","rootDirName","pathParts","part","index","$event","goToPath","totalCount","loading","files","length","error","canRetry","loadFiles","folders","folder","enterFolder","viewBox","fill","getFolderName","columns","column","colIndex","openPreview","loaded","getFileUrl","alt","onImageLoad","onError","handleImageError","muted","loop","preload","onLoadedmetadata","onVideoLoad","onMouseenter","play","onMouseleave","pause","copyLink","title","downloadFile","hasMore","mediaFiles","previewVisible","closePreview","currentPreviewFile","desktopImageStyle","onTouchstart","onSwipeStart","onTouchmove","onSwipeMove","onTouchend","onSwipeEnd","swipeTrackStyle","onTransitionend","onSwipeTransitionEnd","swipeWindow","f","i","getSlideKey","onLock","gestureLocked","onUnlock","previewIndex","prevImage","nextImage","rotateImage","components","TransformMedia","allowedDirs","rootDir","currentPath","observer","pageSize","columnCount","columnHeights","imageRotation","swipeX","swipeStartX","swipeStartY","swipeStartT","swipeActive","swipeAnimating","swipeDir","viewportW","userConfig","siteTitle","split","filter","pop","relative","replace","isFolder","cols","idx","columnIndex","push","prevPreviewFile","nextPreviewFile","base","handler","initFromRoute","mounted","setupIntersectionObserver","updateColumnCount","window","addEventListener","beforeUnmount","disconnect","removeEventListener","innerWidth","newCount","forEach","undefined","assignToColumn","getShortestColumn","minIndex","minHeight","event","ratio","video","videoHeight","videoWidth","IntersectionObserver","entries","entry","isIntersecting","loadMore","rootMargin","observeLoadTrigger","$nextTick","loadTrigger","observe","dirParam","$route","params","dir","dirPath","isArray","join","parts","res","axios","get","encodeURIComponent","dirs","directories","map","metadata","err","response","status","msg","includes","start","moreFiles","console","folderPath","newPath","$router","slice","path","location","origin","ext","toLowerCase","display","url","navigator","clipboard","writeText","then","showToast","catch","input","document","createElement","body","appendChild","select","execCommand","removeChild","existing","remove","toast","className","textContent","setTimeout","classList","add","link","href","download","click","mediaIndex","findIndex","overflow","mobileViewport","el","offsetHeight","t","touches","performance","now","dt","vx","threshold"],"ignoreList":[],"sourceRoot":""} \ No newline at end of file diff --git a/js/733.0149a1b8.js.map.gz b/js/733.0149a1b8.js.map.gz new file mode 100644 index 0000000000000000000000000000000000000000..c22adfbadb489f282162e48c1bae796541ea9857 GIT binary patch literal 20885 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 literal 0 HcmV?d00001 diff --git a/js/app.c7b1facf.js b/js/app.c7b1facf.js new file mode 100644 index 0000000..44d7a7e --- /dev/null +++ b/js/app.c7b1facf.js @@ -0,0 +1,2 @@ +(function(){"use strict";var e={457:function(e,t,o){o(4114);var n=o(4373),r=o(4570),a=o.n(r),s=o(6915),i=o(1219);const l=n.A.create({baseURL:"/"});l.interceptors.request.use(e=>{if(e.withAuthCode){const t=a().get("authCode");t&&(e.headers["authCode"]=t)}return e},e=>Promise.reject(e)),l.interceptors.response.use(e=>e,e=>(e.config?.withAuthCode&&401===e.response?.status&&(i.nk.error("认证失败,请重新登录!"),s.A.push("/login")),Promise.reject(e))),t.A=l},3354:function(e,t,o){o(8111),o(7588);var n=o(5130),r=o(3888),a=o(4068),s=(o(9436),o(372),o(8950)),i=o(2353),l=o(292),u=o(6768);function c(e,t,o,n,r,a){const s=(0,u.g2)("router-view");return(0,u.uX)(),(0,u.Wv)(s)}var d=o(8401),p=o(3785),m={computed:{...(0,d.L8)(["userConfig","useDarkMode"])},mounted(){this.$nextTick(()=>{this.initOverlayScrollbars()})},watch:{useDarkMode(){this.setSiteIcon()}},methods:{initOverlayScrollbars(){try{if(p.ae.valid(document.body))return;(0,p.ae)(document.body,{scrollbars:{theme:"os-theme-dark",visibility:"auto",autoHide:"scroll",autoHideDelay:600,dragScroll:!0,clickScroll:!0},overflow:{x:"hidden",y:"scroll"}}),console.log("OverlayScrollbars initialized successfully")}catch(e){console.error("Failed to initialize OverlayScrollbars:",e)}},setSiteIcon(){const e=document.querySelectorAll('link[rel="icon"], link[rel="apple-touch-icon"], link[rel="mask-icon"]');e.forEach(e=>e.remove());const t=document.createElement("link"),o=document.createElement("link"),n=document.createElement("link");t.rel="icon",o.rel="apple-touch-icon",n.rel="mask-icon",this.useDarkMode?(t.href=this.userConfig?.siteIcon||"/logo-dark.png",o.href=this.userConfig?.siteIcon||"/logo-dark.png",n.href=this.userConfig?.siteIcon||"/logo-dark.png"):(t.href=this.userConfig?.siteIcon||"/logo.png",o.href=this.userConfig?.siteIcon||"/logo.png",n.href=this.userConfig?.siteIcon||"/logo.png"),document.head.appendChild(t),document.head.appendChild(o),document.head.appendChild(n)}}},f=o(1241);const h=(0,f.A)(m,[["render",c]]);var g=h,b=o(6915),k=o(5507),y=o(7477);o(1862),o(635);s.Yv.add(i.X7I);const C=(0,n.Ef)(g),v=(0,r.Zf)();C.component("font-awesome-icon",l.gc);for(const[M,E]of Object.entries(y))C.component(M,E);const A=()=>{const e=document.documentElement;let t;if(k.A.state.cusDarkMode&&null!==k.A.state.useDarkMode)t=k.A.state.useDarkMode;else{if(t=window.matchMedia("(prefers-color-scheme: dark)").matches,!t){const e=new Date,o=e.getHours();t=o>=22||o<6}k.A.commit("setUseDarkMode",t)}t?e.classList.add("dark"):e.classList.remove("dark")},U=e=>{const t=document.documentElement;e?t.classList.add("dark"):t.classList.remove("dark")},w=e=>{document.title=e?.siteTitle||"Sanyue ImgHub"},S=(e,t)=>{const o=document.querySelectorAll('link[rel="icon"], link[rel="apple-touch-icon"], link[rel="mask-icon"]');o.forEach(e=>e.remove());const n=document.createElement("link"),r=document.createElement("link"),a=document.createElement("link");n.rel="icon",r.rel="apple-touch-icon",a.rel="mask-icon",e?(n.href=t?.siteIcon||"/logo-dark.png",r.href=t?.siteIcon||"/logo-dark.png",a.href=t?.siteIcon||"/logo-dark.png"):(n.href=t?.siteIcon||"/logo.png",r.href=t?.siteIcon||"/logo.png",a.href=t?.siteIcon||"/logo.png"),document.head.appendChild(n),document.head.appendChild(r),document.head.appendChild(a)};k.A.dispatch("fetchUserConfig").then(()=>{A(),w(k.A.getters.userConfig),S(k.A.state.useDarkMode,k.A.getters.userConfig),k.A.subscribe((e,t)=>{"setUseDarkMode"===e.type&&k.A.state.cusDarkMode&&(U(t.useDarkMode),S(t.useDarkMode,k.A.getters.userConfig)),"setCusDarkMode"!==e.type||e.payload||(A(),S(k.A.state.useDarkMode,k.A.getters.userConfig))}),C.use(k.A).use(b.A).use(a.A).mount("#app")}).catch(e=>{console.error("Failed to load user configuration:",e),C.use(k.A).use(b.A).use(a.A).use(v).mount("#app")})},5507:function(e,t,o){o(8111),o(1701);var n=o(8401),r=o(457),a=o(5131);t.A=(0,n.y$)({state:{userConfig:null,bingWallPapers:[],credentials:null,uploadMethod:"default",uploadCopyUrlForm:"",compressConfig:{customerCompress:!0,compressQuality:4,compressBar:5,serverCompress:!0},storeUploadChannel:"",storeAutoRetry:!0,storeUploadNameType:"",uploadFolder:"",customUrlSettings:{useCustomUrl:"false",customUrlPrefix:""},adminUrlSettings:{useCustomUrl:"false",customUrlPrefix:""},autoReUpload:!0,useDarkMode:null,cusDarkMode:!1},getters:{userConfig:e=>e.userConfig,bingWallPapers:e=>e.bingWallPapers,credentials:e=>e.credentials,storeUploadMethod:e=>e.uploadMethod,uploadCopyUrlForm:e=>e.uploadCopyUrlForm,compressConfig:e=>e.compressConfig,storeUploadChannel:e=>e.storeUploadChannel,storeUploadNameType:e=>e.storeUploadNameType,customUrlSettings:e=>e.customUrlSettings,storeAutoRetry:e=>e.storeAutoRetry,adminUrlSettings:e=>e.adminUrlSettings,storeUploadFolder:e=>e.uploadFolder||localStorage.getItem("uploadFolder")||"",useDarkMode:e=>e.useDarkMode,cusDarkMode:e=>e.cusDarkMode,storeAutoReUpload:e=>e.autoReUpload},mutations:{setUserConfig(e,t){e.userConfig=t},setBingWallPapers(e,t){e.bingWallPapers=t},setCredentials(e,t){e.credentials=t},setUploadMethod(e,t){e.uploadMethod=t},setUploadCopyUrlForm(e,t){e.uploadCopyUrlForm=t},setCompressConfig(e,{key:t,value:o}){e.compressConfig[t]=o},setStoreUploadChannel(e,t){e.storeUploadChannel=t},setStoreUploadNameType(e,t){e.storeUploadNameType=t},setCustomUrlSettings(e,{key:t,value:o}){e.customUrlSettings[t]=o},setStoreAutoRetry(e,t){e.storeAutoRetry=t},setAdminUrlSettings(e,{key:t,value:o}){e.adminUrlSettings[t]=o},setUseDarkMode(e,t){e.useDarkMode=t},setCusDarkMode(e,t){e.cusDarkMode=t},setStoreUploadFolder(e,t){e.uploadFolder=t,localStorage.setItem("uploadFolder",t)},setStoreAutoReUpload(e,t){e.autoReUpload=t}},actions:{async fetchUserConfig({commit:e}){try{const t=await r.A.get("/api/userConfig");e("setUserConfig",t.data)}catch(t){console.log(t)}},async fetchBingWallPapers({commit:e}){try{const t=await r.A.get("/api/bing/wallpaper"),o=t.data.data,n=o.map(e=>({url:"https://www.bing.com"+e.url}));await Promise.all(n.map(e=>new Promise((t,o)=>{const n=new Image;n.onload=t,n.onerror=o,n.src=e.url}))),e("setBingWallPapers",n)}catch(t){console.log(t)}}},modules:{},plugins:[(0,a.A)()]})},6915:function(e,t,o){o(4979);var n=o(8512),r=o(1219),a=o(4570),s=o.n(a),i=o(5507),l=o(457);const u=(e,t,o)=>{const n=i.A.getters.credentials;if(null===n&&"adminLogin"!==e.name){const e=btoa("unset:unset");l.A.get("/api/manage/check",{headers:{Authorization:"Basic "+e},withCredentials:!0}).then(t=>{if(200!==t.status)throw new Error("认证失败!");i.A.commit("setCredentials",e),o()}).catch(e=>{r.nk.error("请先认证!"),o({name:"adminLogin"})})}else o()},c=(e,t,o)=>{let n=s().get("authCode");null===n&&"login"!==e.name?l.A.post("/api/login",{authCode:"unset"}).then(e=>{if(200!==e.status)throw new Error("认证失败!");s().set("authCode","unset","14d"),n="unset",o()}).catch(e=>{r.nk.error("请先认证!"),o({name:"login"})}):o()},d=[{path:"/",name:"home",component:()=>Promise.all([o.e(171),o.e(747)]).then(o.bind(o,3695)),beforeEnter:c},{path:"/login",name:"login",component:()=>Promise.all([o.e(171),o.e(672)]).then(o.bind(o,2560))},{path:"/dashboard",name:"dashboard",component:()=>Promise.all([o.e(239),o.e(482)]).then(o.bind(o,1482)),beforeEnter:u},{path:"/customerConfig",name:"customerConfig",component:()=>Promise.all([o.e(239),o.e(419)]).then(o.bind(o,8419)),beforeEnter:u},{path:"/systemConfig",name:"systemConfig",component:()=>Promise.all([o.e(239),o.e(643)]).then(o.bind(o,6643)),beforeEnter:u},{path:"/adminLogin",name:"adminLogin",component:()=>Promise.all([o.e(171),o.e(698)]).then(o.bind(o,3950))},{path:"/blockimg",name:"blockimg",component:()=>o.e(917).then(o.bind(o,4917))},{path:"/whiteliston",name:"whiteliston",component:()=>o.e(845).then(o.bind(o,7226))},{path:"/browse/:dir*",name:"publicBrowse",component:()=>o.e(733).then(o.bind(o,6733))},{path:"/:pathMatch(.*)*",name:"notFound",component:()=>o.e(226).then(o.bind(o,8226))}],p=(0,n.aE)({history:(0,n.LA)("/"),routes:d});t.A=p}},t={};function o(n){var r=t[n];if(void 0!==r)return r.exports;var a=t[n]={exports:{}};return e[n].call(a.exports,a,a.exports,o),a.exports}o.m=e,function(){var e=[];o.O=function(t,n,r,a){if(!n){var s=1/0;for(c=0;c=a)&&Object.keys(o.O).every(function(e){return o.O[e](n[l])})?n.splice(l--,1):(i=!1,a0&&e[c-1][2]>a;c--)e[c]=e[c-1];e[c]=[n,r,a]}}(),function(){o.n=function(e){var t=e&&e.__esModule?function(){return e["default"]}:function(){return e};return o.d(t,{a:t}),t}}(),function(){o.d=function(e,t){for(var n in t)o.o(t,n)&&!o.o(e,n)&&Object.defineProperty(e,n,{enumerable:!0,get:t[n]})}}(),function(){o.f={},o.e=function(e){return Promise.all(Object.keys(o.f).reduce(function(t,n){return o.f[n](e,t),t},[]))}}(),function(){o.u=function(e){return"js/"+e+"."+{171:"833208d0",226:"577ea134",239:"32572dba",419:"99e00aec",482:"e302adaf",643:"d1f24e26",672:"11bec4e1",698:"77f859a8",733:"0149a1b8",747:"51eee506",845:"6b4cb4a5",917:"5bf3db27"}[e]+".js"}}(),function(){o.miniCssF=function(e){return"css/"+e+"."+{226:"6548e7b4",239:"6563616d",419:"1d235d6e",482:"f42e1415",643:"74c1c29d",672:"aed3581b",698:"aed3581b",733:"ce2542a6",747:"e115ba5f",845:"6b45e8e3",917:"8529ad1e"}[e]+".css"}}(),function(){o.g=function(){if("object"===typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"===typeof window)return window}}()}(),function(){o.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)}}(),function(){var e={},t="sanyue_imghub:";o.l=function(n,r,a,s){if(e[n])e[n].push(r);else{var i,l;if(void 0!==a)for(var u=document.getElementsByTagName("script"),c=0;c=HLcGKIUHL5ENc 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 d#rSF!#Di%# {\r\n // 如果配置中标记了withAuthCode,则添加authCode到header\r\n if (config.withAuthCode) {\r\n const authCode = cookies.get('authCode');\r\n if (authCode) {\r\n config.headers['authCode'] = authCode;\r\n }\r\n }\r\n return config;\r\n },\r\n (error) => {\r\n return Promise.reject(error);\r\n }\r\n);\r\n\r\n// 响应拦截器\r\ninstance.interceptors.response.use(\r\n (response) => {\r\n return response;\r\n },\r\n (error) => {\r\n // 如果请求配置了withAuthCode且返回401,则跳转到登录页\r\n if (error.config?.withAuthCode && error.response?.status === 401) {\r\n ElMessage.error('认证失败,请重新登录!');\r\n router.push('/login');\r\n }\r\n return Promise.reject(error);\r\n }\r\n);\r\n\r\nexport default instance;\r\n","import { resolveComponent as _resolveComponent, openBlock as _openBlock, createBlock as _createBlock } from \"vue\";\nexport function render(_ctx, _cache, $props, $setup, $data, $options) {\n const _component_router_view = _resolveComponent(\"router-view\");\n return _openBlock(), _createBlock(_component_router_view);\n}","import \"core-js/modules/es.iterator.constructor.js\";\nimport \"core-js/modules/es.iterator.for-each.js\";\nimport { mapGetters } from 'vuex';\nimport { OverlayScrollbars } from 'overlayscrollbars';\nexport default {\n computed: {\n ...mapGetters(['userConfig', 'useDarkMode'])\n },\n mounted() {\n // 初始化 OverlayScrollbars 悬浮滚动条\n this.$nextTick(() => {\n this.initOverlayScrollbars();\n });\n },\n watch: {\n useDarkMode() {\n this.setSiteIcon();\n }\n },\n methods: {\n initOverlayScrollbars() {\n try {\n // 检查是否已经初始化\n if (OverlayScrollbars.valid(document.body)) {\n return;\n }\n\n // 应用到 body 实现全局悬浮滚动条\n OverlayScrollbars(document.body, {\n scrollbars: {\n theme: 'os-theme-dark',\n visibility: 'auto',\n autoHide: 'scroll',\n autoHideDelay: 600,\n dragScroll: true,\n clickScroll: true\n },\n overflow: {\n x: 'hidden',\n y: 'scroll'\n }\n });\n console.log('OverlayScrollbars initialized successfully');\n } catch (error) {\n console.error('Failed to initialize OverlayScrollbars:', error);\n }\n },\n setSiteIcon() {\n // 同时更改 icon apple-touch-icon 和 mask-icon\n const existingIcons = document.querySelectorAll('link[rel=\"icon\"], link[rel=\"apple-touch-icon\"], link[rel=\"mask-icon\"]');\n existingIcons.forEach(icon => icon.remove());\n const iconLink = document.createElement('link');\n const appleIconLink = document.createElement('link');\n const maskIconLink = document.createElement('link');\n iconLink.rel = 'icon';\n appleIconLink.rel = 'apple-touch-icon';\n maskIconLink.rel = 'mask-icon';\n if (this.useDarkMode) {\n iconLink.href = this.userConfig?.siteIcon || '/logo-dark.png';\n appleIconLink.href = this.userConfig?.siteIcon || '/logo-dark.png';\n maskIconLink.href = this.userConfig?.siteIcon || '/logo-dark.png';\n } else {\n iconLink.href = this.userConfig?.siteIcon || '/logo.png';\n appleIconLink.href = this.userConfig?.siteIcon || '/logo.png';\n maskIconLink.href = this.userConfig?.siteIcon || '/logo.png';\n }\n document.head.appendChild(iconLink);\n document.head.appendChild(appleIconLink);\n document.head.appendChild(maskIconLink);\n }\n }\n};","/* unplugin-vue-components disabled */import { render } from \"./App.vue?vue&type=template&id=7d6c298a\"\nimport script from \"./App.vue?vue&type=script&lang=js\"\nexport * from \"./App.vue?vue&type=script&lang=js\"\n\nimport \"./App.vue?vue&type=style&index=0&id=7d6c298a&lang=css\"\nimport \"./App.vue?vue&type=style&index=1&id=7d6c298a&lang=css\"\n\nimport exportComponent from \"../node_modules/vue-loader/dist/exportHelper.js\"\nconst __exports__ = /*#__PURE__*/exportComponent(script, [['render',render]])\n\nexport default __exports__","import { createApp } from 'vue'\r\nimport { createHead } from '@vueuse/head'; // 导入 createHead\r\nimport ElementPlus from 'element-plus'\r\nimport 'element-plus/es/components/message/style/css'\r\nimport 'element-plus/es/components/message-box/style/css'\r\n\r\nimport { library } from '@fortawesome/fontawesome-svg-core';\r\nimport { fas } from '@fortawesome/free-solid-svg-icons'; // 引入所有 solid 图标\r\nimport { FontAwesomeIcon } from '@fortawesome/vue-fontawesome';\r\n\r\nimport App from './App.vue'\r\nimport router from './router'\r\nimport store from './store'\r\n\r\nimport * as ElementPlusIconsVue from '@element-plus/icons-vue'\r\nimport 'element-plus/theme-chalk/dark/css-vars.css'\r\nimport './styles/global.css'\r\n\r\n// OverlayScrollbars 悬浮滚动条\r\nimport 'overlayscrollbars/overlayscrollbars.css'\r\n\r\n\r\nlibrary.add(fas);\r\n\r\nconst app = createApp(App);\r\nconst head = createHead(); // 创建 head 对象\r\n\r\napp.component('font-awesome-icon', FontAwesomeIcon);\r\nfor (const [key, component] of Object.entries(ElementPlusIconsVue)) {\r\n app.component(key, component)\r\n}\r\n\r\n// 根据 useDarkMode 的值添加或移除 dark 类\r\nconst initDarkModeClass = () => {\r\n const htmlElement = document.documentElement;\r\n let isDarkMode;\r\n\r\n // 判断用户是否是自定义模式\r\n if (store.state.cusDarkMode && store.state.useDarkMode !== null) {\r\n // 用户手动设置了暗色模式\r\n isDarkMode = store.state.useDarkMode;\r\n } else {\r\n // 跟随系统模式或时间\r\n isDarkMode = window.matchMedia('(prefers-color-scheme: dark)').matches;\r\n if (!isDarkMode) {\r\n const now = new Date();\r\n const hour = now.getHours();\r\n isDarkMode = hour >= 22 || hour < 6;\r\n }\r\n // 更新 useDarkMode 的值\r\n store.commit('setUseDarkMode', isDarkMode);\r\n }\r\n\r\n if (isDarkMode) {\r\n htmlElement.classList.add('dark');\r\n } else {\r\n htmlElement.classList.remove('dark');\r\n }\r\n};\r\n\r\nconst applyDarkModeClass = (isDarkMode) => {\r\n const htmlElement = document.documentElement;\r\n if (isDarkMode) {\r\n htmlElement.classList.add('dark');\r\n } else {\r\n htmlElement.classList.remove('dark');\r\n }\r\n};\r\n\r\n// 预设网站标题的函数\r\nconst presetSiteTitle = (userConfig) => {\r\n document.title = userConfig?.siteTitle || 'Sanyue ImgHub';\r\n};\r\n\r\n// 预设网站图标的函数\r\nconst presetSiteIcon = (isDarkMode, userConfig) => {\r\n // 同时更改 icon apple-touch-icon 和 mask-icon\r\n const existingIcons = document.querySelectorAll('link[rel=\"icon\"], link[rel=\"apple-touch-icon\"], link[rel=\"mask-icon\"]');\r\n existingIcons.forEach(icon => icon.remove());\r\n\r\n const iconLink = document.createElement('link');\r\n const appleIconLink = document.createElement('link');\r\n const maskIconLink = document.createElement('link');\r\n iconLink.rel = 'icon';\r\n appleIconLink.rel = 'apple-touch-icon';\r\n maskIconLink.rel = 'mask-icon';\r\n\r\n if (isDarkMode) {\r\n iconLink.href = userConfig?.siteIcon || '/logo-dark.png';\r\n appleIconLink.href = userConfig?.siteIcon || '/logo-dark.png';\r\n maskIconLink.href = userConfig?.siteIcon || '/logo-dark.png';\r\n } else {\r\n iconLink.href = userConfig?.siteIcon || '/logo.png';\r\n appleIconLink.href = userConfig?.siteIcon || '/logo.png';\r\n maskIconLink.href = userConfig?.siteIcon || '/logo.png';\r\n }\r\n\r\n document.head.appendChild(iconLink);\r\n document.head.appendChild(appleIconLink);\r\n document.head.appendChild(maskIconLink);\r\n};\r\n\r\nstore.dispatch('fetchUserConfig').then(() => {\r\n // 初始化时应用 dark 模式\r\n initDarkModeClass();\r\n\r\n // 预设网站标题和图标\r\n presetSiteTitle(store.getters.userConfig);\r\n presetSiteIcon(store.state.useDarkMode, store.getters.userConfig);\r\n\r\n // 监听 useDarkMode 和 cusDarkMode 的变化\r\n store.subscribe((mutation, state) => {\r\n if (mutation.type === 'setUseDarkMode' && store.state.cusDarkMode) {\r\n applyDarkModeClass(state.useDarkMode);\r\n // 同时更新网站图标\r\n presetSiteIcon(state.useDarkMode, store.getters.userConfig);\r\n }\r\n\r\n // 监听 cusDarkMode 变化,当设置为 false 时重新初始化\r\n if (mutation.type === 'setCusDarkMode' && !mutation.payload) {\r\n // 切换到跟随系统模式,重新初始化\r\n initDarkModeClass();\r\n // 同时更新网站图标\r\n presetSiteIcon(store.state.useDarkMode, store.getters.userConfig);\r\n }\r\n });\r\n\r\n app.use(store).use(router).use(ElementPlus).mount('#app');\r\n}).catch(error => {\r\n console.error('Failed to load user configuration:', error);\r\n app.use(store).use(router).use(ElementPlus).use(head).mount('#app');\r\n})\r\n","import { createStore } from 'vuex'\r\nimport axios from '@/utils/axios';\r\nimport createPersistedState from 'vuex-persistedstate';\r\n\r\nexport default createStore({\r\n state: {\r\n userConfig: null,\r\n bingWallPapers: [],\r\n credentials: null,\r\n uploadMethod: 'default',\r\n uploadCopyUrlForm: '',\r\n compressConfig: {\r\n customerCompress: true,\r\n compressQuality: 4,\r\n compressBar: 5,\r\n serverCompress: true,\r\n },\r\n storeUploadChannel: '',\r\n storeAutoRetry: true,\r\n storeUploadNameType: '',\r\n uploadFolder: '',\r\n customUrlSettings: {\r\n useCustomUrl: 'false',\r\n customUrlPrefix: '',\r\n },\r\n adminUrlSettings: {\r\n useCustomUrl: 'false',\r\n customUrlPrefix: '',\r\n },\r\n autoReUpload: true,\r\n // 深色模式\r\n useDarkMode: null,\r\n cusDarkMode: false,\r\n },\r\n getters: {\r\n userConfig: state => state.userConfig,\r\n bingWallPapers: state => state.bingWallPapers,\r\n credentials: state => state.credentials,\r\n storeUploadMethod: state => state.uploadMethod,\r\n uploadCopyUrlForm: state => state.uploadCopyUrlForm,\r\n compressConfig: state => state.compressConfig,\r\n storeUploadChannel: state => state.storeUploadChannel,\r\n storeUploadNameType: state => state.storeUploadNameType,\r\n customUrlSettings: state => state.customUrlSettings,\r\n storeAutoRetry: state => state.storeAutoRetry,\r\n adminUrlSettings: state => state.adminUrlSettings,\r\n storeUploadFolder: (state) => {\r\n return state.uploadFolder || localStorage.getItem('uploadFolder') || ''\r\n },\r\n useDarkMode: state => state.useDarkMode,\r\n cusDarkMode: state => state.cusDarkMode,\r\n storeAutoReUpload: state => state.autoReUpload,\r\n },\r\n mutations: {\r\n setUserConfig(state, userConfig) {\r\n state.userConfig = userConfig;\r\n },\r\n setBingWallPapers(state, bingWallPapers) {\r\n state.bingWallPapers = bingWallPapers;\r\n },\r\n setCredentials(state, credentials) {\r\n state.credentials = credentials;\r\n },\r\n setUploadMethod(state, uploadMethod) {\r\n state.uploadMethod = uploadMethod;\r\n },\r\n setUploadCopyUrlForm(state, uploadCopyUrlForm) {\r\n state.uploadCopyUrlForm = uploadCopyUrlForm;\r\n },\r\n setCompressConfig(state, { key, value }) {\r\n state.compressConfig[key] = value;\r\n },\r\n setStoreUploadChannel(state, uploadChannel) {\r\n state.storeUploadChannel = uploadChannel;\r\n },\r\n setStoreUploadNameType(state, storeUploadNameType) {\r\n state.storeUploadNameType = storeUploadNameType;\r\n },\r\n setCustomUrlSettings(state, { key, value }) {\r\n state.customUrlSettings[key] = value;\r\n },\r\n setStoreAutoRetry(state, storeAutoRetry) {\r\n state.storeAutoRetry = storeAutoRetry;\r\n },\r\n setAdminUrlSettings(state, { key, value }) {\r\n state.adminUrlSettings[key] = value;\r\n },\r\n setUseDarkMode(state, useDarkMode) {\r\n state.useDarkMode = useDarkMode;\r\n },\r\n setCusDarkMode(state, cusDarkMode) {\r\n state.cusDarkMode = cusDarkMode;\r\n },\r\n setStoreUploadFolder(state, folder) {\r\n state.uploadFolder = folder\r\n localStorage.setItem('uploadFolder', folder)\r\n },\r\n setStoreAutoReUpload(state, autoReUpload) {\r\n state.autoReUpload = autoReUpload;\r\n }\r\n },\r\n actions: {\r\n async fetchUserConfig({ commit }) {\r\n try {\r\n const response = await axios.get('/api/userConfig');\r\n commit('setUserConfig', response.data);\r\n } catch (error) {\r\n console.log(error);\r\n }\r\n },\r\n async fetchBingWallPapers({ commit }) {\r\n try {\r\n const response = await axios.get('/api/bing/wallpaper');\r\n const wallpapers = response.data.data;\r\n const bingWallPapers = wallpapers.map(wallpaper => {\r\n return {\r\n url: 'https://www.bing.com' + wallpaper.url,\r\n };\r\n }\r\n );\r\n\r\n //预加载图片,阻塞直到图片加载完成\r\n await Promise.all(bingWallPapers.map(wallpaper => {\r\n return new Promise((resolve, reject) => {\r\n const img = new Image();\r\n img.onload = resolve;\r\n img.onerror = reject;\r\n img.src = wallpaper.url;\r\n });\r\n }));\r\n commit('setBingWallPapers', bingWallPapers);\r\n } catch (error) {\r\n console.log(error);\r\n }\r\n }\r\n },\r\n modules: {\r\n },\r\n plugins: [createPersistedState()]\r\n})\r\n","import { createRouter, createWebHistory } from 'vue-router'\r\nimport { ElMessage } from 'element-plus'\r\nimport cookies from 'vue-cookies'\r\nimport store from '../store'\r\nimport axios from '@/utils/axios'\r\n\r\n// 通用的管理员认证守卫\r\nconst adminAuthGuard = (to, from, next) => {\r\n // 从store中获取凭据\r\n const credentials = store.getters.credentials\r\n if (credentials === null && to.name !== 'adminLogin') {\r\n // 尝试未设置密码的情况\r\n const credentials = btoa('unset:unset')\r\n axios.get('/api/manage/check', {\r\n headers: {\r\n 'Authorization': 'Basic ' + credentials\r\n },\r\n withCredentials: true\r\n }).then(res => {\r\n if (res.status !== 200) {\r\n throw new Error('认证失败!')\r\n }\r\n store.commit('setCredentials', credentials)\r\n next()\r\n }).catch(err => {\r\n ElMessage.error('请先认证!')\r\n next({ name: 'adminLogin' })\r\n })\r\n } else {\r\n next()\r\n }\r\n}\r\n\r\n// 通用的用户认证守卫\r\nconst userAuthGuard = (to, from, next) => {\r\n let authCode = cookies.get('authCode');\r\n if (authCode === null && to.name !== 'login') {\r\n // 尝试未设置密码的情况\r\n axios.post('/api/login', {\r\n authCode: 'unset'\r\n }).then(res => {\r\n if (res.status !== 200) {\r\n throw new Error('认证失败!')\r\n }\r\n cookies.set('authCode', 'unset', '14d')\r\n authCode = 'unset'\r\n next()\r\n }).catch(err => {\r\n ElMessage.error('请先认证!')\r\n next({ name: 'login' })\r\n })\r\n } else {\r\n next()\r\n }\r\n}\r\n\r\nconst routes = [\r\n {\r\n path: '/',\r\n name: 'home',\r\n component: () => import('../views/UploadHome.vue'),\r\n beforeEnter: userAuthGuard\r\n },\r\n {\r\n path: '/login',\r\n name: 'login',\r\n component: () => import('../views/Login.vue')\r\n },\r\n {\r\n path: '/dashboard',\r\n name: 'dashboard',\r\n component: () => import('../views/AdminDashBoard.vue'),\r\n beforeEnter: adminAuthGuard\r\n },\r\n {\r\n path: '/customerConfig',\r\n name: 'customerConfig',\r\n component: () => import('../views/CustomerConfig.vue'),\r\n beforeEnter: adminAuthGuard\r\n },\r\n {\r\n path: '/systemConfig',\r\n name: 'systemConfig',\r\n component: () => import('../views/SystemConfig.vue'),\r\n beforeEnter: adminAuthGuard\r\n },\r\n {\r\n path: '/adminLogin',\r\n name: 'adminLogin',\r\n component: () => import('../views/AdminLogin.vue'),\r\n },\r\n {\r\n path: '/blockimg',\r\n name: 'blockimg',\r\n component: () => import('../views/BlockImage.vue'),\r\n },\r\n {\r\n path: '/whiteliston',\r\n name: 'whiteliston',\r\n component: () => import('../views/WhiteListOn.vue'),\r\n },\r\n {\r\n path: '/browse/:dir*',\r\n name: 'publicBrowse',\r\n component: () => import('../views/PublicBrowse.vue'),\r\n },\r\n {\r\n path: '/:pathMatch(.*)*',\r\n name: 'notFound',\r\n component: () => import('../views/NotFound.vue'),\r\n },\r\n]\r\n\r\nconst router = createRouter({\r\n history: createWebHistory(process.env.BASE_URL),\r\n routes\r\n})\r\n\r\nexport default router\r\n","// The module cache\nvar __webpack_module_cache__ = {};\n\n// The require function\nfunction __webpack_require__(moduleId) {\n\t// Check if module is in cache\n\tvar cachedModule = __webpack_module_cache__[moduleId];\n\tif (cachedModule !== undefined) {\n\t\treturn cachedModule.exports;\n\t}\n\t// Create a new module (and put it into the cache)\n\tvar module = __webpack_module_cache__[moduleId] = {\n\t\t// no module.id needed\n\t\t// no module.loaded needed\n\t\texports: {}\n\t};\n\n\t// Execute the module function\n\t__webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n\t// Return the exports of the module\n\treturn module.exports;\n}\n\n// expose the modules object (__webpack_modules__)\n__webpack_require__.m = __webpack_modules__;\n\n","var deferred = [];\n__webpack_require__.O = function(result, chunkIds, fn, priority) {\n\tif(chunkIds) {\n\t\tpriority = priority || 0;\n\t\tfor(var i = deferred.length; i > 0 && deferred[i - 1][2] > priority; i--) deferred[i] = deferred[i - 1];\n\t\tdeferred[i] = [chunkIds, fn, priority];\n\t\treturn;\n\t}\n\tvar notFulfilled = Infinity;\n\tfor (var i = 0; i < deferred.length; i++) {\n\t\tvar chunkIds = deferred[i][0];\n\t\tvar fn = deferred[i][1];\n\t\tvar priority = deferred[i][2];\n\t\tvar fulfilled = true;\n\t\tfor (var j = 0; j < chunkIds.length; j++) {\n\t\t\tif ((priority & 1 === 0 || notFulfilled >= priority) && Object.keys(__webpack_require__.O).every(function(key) { return __webpack_require__.O[key](chunkIds[j]); })) {\n\t\t\t\tchunkIds.splice(j--, 1);\n\t\t\t} else {\n\t\t\t\tfulfilled = false;\n\t\t\t\tif(priority < notFulfilled) notFulfilled = priority;\n\t\t\t}\n\t\t}\n\t\tif(fulfilled) {\n\t\t\tdeferred.splice(i--, 1)\n\t\t\tvar r = fn();\n\t\t\tif (r !== undefined) result = r;\n\t\t}\n\t}\n\treturn result;\n};","// getDefaultExport function for compatibility with non-harmony modules\n__webpack_require__.n = function(module) {\n\tvar getter = module && module.__esModule ?\n\t\tfunction() { return module['default']; } :\n\t\tfunction() { return module; };\n\t__webpack_require__.d(getter, { a: getter });\n\treturn getter;\n};","// define getter functions for harmony exports\n__webpack_require__.d = function(exports, definition) {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.f = {};\n// This file contains only the entry chunk.\n// The chunk loading function for additional chunks\n__webpack_require__.e = function(chunkId) {\n\treturn Promise.all(Object.keys(__webpack_require__.f).reduce(function(promises, key) {\n\t\t__webpack_require__.f[key](chunkId, promises);\n\t\treturn promises;\n\t}, []));\n};","// This function allow to reference async chunks\n__webpack_require__.u = function(chunkId) {\n\t// return url for filenames based on template\n\treturn \"js/\" + chunkId + \".\" + {\"171\":\"833208d0\",\"226\":\"577ea134\",\"239\":\"32572dba\",\"419\":\"99e00aec\",\"482\":\"e302adaf\",\"643\":\"d1f24e26\",\"672\":\"11bec4e1\",\"698\":\"77f859a8\",\"733\":\"0149a1b8\",\"747\":\"51eee506\",\"845\":\"6b4cb4a5\",\"917\":\"5bf3db27\"}[chunkId] + \".js\";\n};","// This function allow to reference async chunks\n__webpack_require__.miniCssF = function(chunkId) {\n\t// return url for filenames based on template\n\treturn \"css/\" + chunkId + \".\" + {\"226\":\"6548e7b4\",\"239\":\"6563616d\",\"419\":\"1d235d6e\",\"482\":\"f42e1415\",\"643\":\"74c1c29d\",\"672\":\"aed3581b\",\"698\":\"aed3581b\",\"733\":\"ce2542a6\",\"747\":\"e115ba5f\",\"845\":\"6b45e8e3\",\"917\":\"8529ad1e\"}[chunkId] + \".css\";\n};","__webpack_require__.g = (function() {\n\tif (typeof globalThis === 'object') return globalThis;\n\ttry {\n\t\treturn this || new Function('return this')();\n\t} catch (e) {\n\t\tif (typeof window === 'object') return window;\n\t}\n})();","__webpack_require__.o = function(obj, prop) { return Object.prototype.hasOwnProperty.call(obj, prop); }","var inProgress = {};\nvar dataWebpackPrefix = \"sanyue_imghub:\";\n// loadScript function to load a script via script tag\n__webpack_require__.l = function(url, done, key, chunkId) {\n\tif(inProgress[url]) { inProgress[url].push(done); return; }\n\tvar script, needAttach;\n\tif(key !== undefined) {\n\t\tvar scripts = document.getElementsByTagName(\"script\");\n\t\tfor(var i = 0; i < scripts.length; i++) {\n\t\t\tvar s = scripts[i];\n\t\t\tif(s.getAttribute(\"src\") == url || s.getAttribute(\"data-webpack\") == dataWebpackPrefix + key) { script = s; break; }\n\t\t}\n\t}\n\tif(!script) {\n\t\tneedAttach = true;\n\t\tscript = document.createElement('script');\n\n\t\tscript.charset = 'utf-8';\n\t\tif (__webpack_require__.nc) {\n\t\t\tscript.setAttribute(\"nonce\", __webpack_require__.nc);\n\t\t}\n\t\tscript.setAttribute(\"data-webpack\", dataWebpackPrefix + key);\n\n\t\tscript.src = url;\n\t}\n\tinProgress[url] = [done];\n\tvar onScriptComplete = function(prev, event) {\n\t\t// avoid mem leaks in IE.\n\t\tscript.onerror = script.onload = null;\n\t\tclearTimeout(timeout);\n\t\tvar doneFns = inProgress[url];\n\t\tdelete inProgress[url];\n\t\tscript.parentNode && script.parentNode.removeChild(script);\n\t\tdoneFns && doneFns.forEach(function(fn) { return fn(event); });\n\t\tif(prev) return prev(event);\n\t}\n\tvar timeout = setTimeout(onScriptComplete.bind(null, undefined, { type: 'timeout', target: script }), 120000);\n\tscript.onerror = onScriptComplete.bind(null, script.onerror);\n\tscript.onload = onScriptComplete.bind(null, script.onload);\n\tneedAttach && document.head.appendChild(script);\n};","// define __esModule on exports\n__webpack_require__.r = function(exports) {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","__webpack_require__.p = \"/\";","if (typeof document === \"undefined\") return;\nvar createStylesheet = function(chunkId, fullhref, oldTag, resolve, reject) {\n\tvar linkTag = document.createElement(\"link\");\n\n\tlinkTag.rel = \"stylesheet\";\n\tlinkTag.type = \"text/css\";\n\tif (__webpack_require__.nc) {\n\t\tlinkTag.nonce = __webpack_require__.nc;\n\t}\n\tvar onLinkComplete = function(event) {\n\t\t// avoid mem leaks.\n\t\tlinkTag.onerror = linkTag.onload = null;\n\t\tif (event.type === 'load') {\n\t\t\tresolve();\n\t\t} else {\n\t\t\tvar errorType = event && event.type;\n\t\t\tvar realHref = event && event.target && event.target.href || fullhref;\n\t\t\tvar err = new Error(\"Loading CSS chunk \" + chunkId + \" failed.\\n(\" + errorType + \": \" + realHref + \")\");\n\t\t\terr.name = \"ChunkLoadError\";\n\t\t\terr.code = \"CSS_CHUNK_LOAD_FAILED\";\n\t\t\terr.type = errorType;\n\t\t\terr.request = realHref;\n\t\t\tif (linkTag.parentNode) linkTag.parentNode.removeChild(linkTag)\n\t\t\treject(err);\n\t\t}\n\t}\n\tlinkTag.onerror = linkTag.onload = onLinkComplete;\n\tlinkTag.href = fullhref;\n\n\n\tif (oldTag) {\n\t\toldTag.parentNode.insertBefore(linkTag, oldTag.nextSibling);\n\t} else {\n\t\tdocument.head.appendChild(linkTag);\n\t}\n\treturn linkTag;\n};\nvar findStylesheet = function(href, fullhref) {\n\tvar existingLinkTags = document.getElementsByTagName(\"link\");\n\tfor(var i = 0; i < existingLinkTags.length; i++) {\n\t\tvar tag = existingLinkTags[i];\n\t\tvar dataHref = tag.getAttribute(\"data-href\") || tag.getAttribute(\"href\");\n\t\tif(tag.rel === \"stylesheet\" && (dataHref === href || dataHref === fullhref)) return tag;\n\t}\n\tvar existingStyleTags = document.getElementsByTagName(\"style\");\n\tfor(var i = 0; i < existingStyleTags.length; i++) {\n\t\tvar tag = existingStyleTags[i];\n\t\tvar dataHref = tag.getAttribute(\"data-href\");\n\t\tif(dataHref === href || dataHref === fullhref) return tag;\n\t}\n};\nvar loadStylesheet = function(chunkId) {\n\treturn new Promise(function(resolve, reject) {\n\t\tvar href = __webpack_require__.miniCssF(chunkId);\n\t\tvar fullhref = __webpack_require__.p + href;\n\t\tif(findStylesheet(href, fullhref)) return resolve();\n\t\tcreateStylesheet(chunkId, fullhref, null, resolve, reject);\n\t});\n}\n// object to store loaded CSS chunks\nvar installedCssChunks = {\n\t524: 0\n};\n\n__webpack_require__.f.miniCss = function(chunkId, promises) {\n\tvar cssChunks = {\"226\":1,\"239\":1,\"419\":1,\"482\":1,\"643\":1,\"672\":1,\"698\":1,\"733\":1,\"747\":1,\"845\":1,\"917\":1};\n\tif(installedCssChunks[chunkId]) promises.push(installedCssChunks[chunkId]);\n\telse if(installedCssChunks[chunkId] !== 0 && cssChunks[chunkId]) {\n\t\tpromises.push(installedCssChunks[chunkId] = loadStylesheet(chunkId).then(function() {\n\t\t\tinstalledCssChunks[chunkId] = 0;\n\t\t}, function(e) {\n\t\t\tdelete installedCssChunks[chunkId];\n\t\t\tthrow e;\n\t\t}));\n\t}\n};\n\n// no hmr\n\n// no prefetching\n\n// no preloaded","// no baseURI\n\n// object to store loaded and loading chunks\n// undefined = chunk not loaded, null = chunk preloaded/prefetched\n// [resolve, reject, Promise] = chunk loading, 0 = chunk loaded\nvar installedChunks = {\n\t524: 0\n};\n\n__webpack_require__.f.j = function(chunkId, promises) {\n\t\t// JSONP chunk loading for javascript\n\t\tvar installedChunkData = __webpack_require__.o(installedChunks, chunkId) ? installedChunks[chunkId] : undefined;\n\t\tif(installedChunkData !== 0) { // 0 means \"already installed\".\n\n\t\t\t// a Promise means \"currently loading\".\n\t\t\tif(installedChunkData) {\n\t\t\t\tpromises.push(installedChunkData[2]);\n\t\t\t} else {\n\t\t\t\tif(true) { // all chunks have JS\n\t\t\t\t\t// setup Promise in chunk cache\n\t\t\t\t\tvar promise = new Promise(function(resolve, reject) { installedChunkData = installedChunks[chunkId] = [resolve, reject]; });\n\t\t\t\t\tpromises.push(installedChunkData[2] = promise);\n\n\t\t\t\t\t// start chunk loading\n\t\t\t\t\tvar url = __webpack_require__.p + __webpack_require__.u(chunkId);\n\t\t\t\t\t// create error before stack unwound to get useful stacktrace later\n\t\t\t\t\tvar error = new Error();\n\t\t\t\t\tvar loadingEnded = function(event) {\n\t\t\t\t\t\tif(__webpack_require__.o(installedChunks, chunkId)) {\n\t\t\t\t\t\t\tinstalledChunkData = installedChunks[chunkId];\n\t\t\t\t\t\t\tif(installedChunkData !== 0) installedChunks[chunkId] = undefined;\n\t\t\t\t\t\t\tif(installedChunkData) {\n\t\t\t\t\t\t\t\tvar errorType = event && (event.type === 'load' ? 'missing' : event.type);\n\t\t\t\t\t\t\t\tvar realSrc = event && event.target && event.target.src;\n\t\t\t\t\t\t\t\terror.message = 'Loading chunk ' + chunkId + ' failed.\\n(' + errorType + ': ' + realSrc + ')';\n\t\t\t\t\t\t\t\terror.name = 'ChunkLoadError';\n\t\t\t\t\t\t\t\terror.type = errorType;\n\t\t\t\t\t\t\t\terror.request = realSrc;\n\t\t\t\t\t\t\t\tinstalledChunkData[1](error);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t};\n\t\t\t\t\t__webpack_require__.l(url, loadingEnded, \"chunk-\" + chunkId, chunkId);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n};\n\n// no prefetching\n\n// no preloaded\n\n// no HMR\n\n// no HMR manifest\n\n__webpack_require__.O.j = function(chunkId) { return installedChunks[chunkId] === 0; };\n\n// install a JSONP callback for chunk loading\nvar webpackJsonpCallback = function(parentChunkLoadingFunction, data) {\n\tvar chunkIds = data[0];\n\tvar moreModules = data[1];\n\tvar runtime = data[2];\n\t// add \"moreModules\" to the modules object,\n\t// then flag all \"chunkIds\" as loaded and fire callback\n\tvar moduleId, chunkId, i = 0;\n\tif(chunkIds.some(function(id) { return installedChunks[id] !== 0; })) {\n\t\tfor(moduleId in moreModules) {\n\t\t\tif(__webpack_require__.o(moreModules, moduleId)) {\n\t\t\t\t__webpack_require__.m[moduleId] = moreModules[moduleId];\n\t\t\t}\n\t\t}\n\t\tif(runtime) var result = runtime(__webpack_require__);\n\t}\n\tif(parentChunkLoadingFunction) parentChunkLoadingFunction(data);\n\tfor(;i < chunkIds.length; i++) {\n\t\tchunkId = chunkIds[i];\n\t\tif(__webpack_require__.o(installedChunks, chunkId) && installedChunks[chunkId]) {\n\t\t\tinstalledChunks[chunkId][0]();\n\t\t}\n\t\tinstalledChunks[chunkId] = 0;\n\t}\n\treturn __webpack_require__.O(result);\n}\n\nvar chunkLoadingGlobal = self[\"webpackChunksanyue_imghub\"] = self[\"webpackChunksanyue_imghub\"] || [];\nchunkLoadingGlobal.forEach(webpackJsonpCallback.bind(null, 0));\nchunkLoadingGlobal.push = webpackJsonpCallback.bind(null, chunkLoadingGlobal.push.bind(chunkLoadingGlobal));","// startup\n// Load entry module and return exports\n// This entry module depends on other loaded chunks and execution need to be delayed\nvar __webpack_exports__ = __webpack_require__.O(undefined, [504], function() { return __webpack_require__(3354); })\n__webpack_exports__ = __webpack_require__.O(__webpack_exports__);\n"],"names":["instance","axios","create","baseURL","interceptors","request","use","config","withAuthCode","authCode","cookies","headers","error","Promise","reject","response","status","ElMessage","router","push","render","_ctx","_cache","$props","$setup","$data","$options","_component_router_view","computed","mounted","this","$nextTick","initOverlayScrollbars","watch","useDarkMode","setSiteIcon","methods","valid","document","body","scrollbars","theme","visibility","autoHide","autoHideDelay","dragScroll","clickScroll","overflow","x","y","console","log","existingIcons","querySelectorAll","forEach","icon","remove","iconLink","createElement","appleIconLink","maskIconLink","rel","href","userConfig","siteIcon","head","appendChild","__exports__","library","add","fas","app","createApp","App","createHead","component","FontAwesomeIcon","key","Object","entries","ElementPlusIconsVue","initDarkModeClass","htmlElement","documentElement","isDarkMode","store","state","cusDarkMode","window","matchMedia","matches","now","Date","hour","getHours","commit","classList","applyDarkModeClass","presetSiteTitle","title","siteTitle","presetSiteIcon","dispatch","then","getters","subscribe","mutation","type","payload","ElementPlus","mount","catch","createStore","bingWallPapers","credentials","uploadMethod","uploadCopyUrlForm","compressConfig","customerCompress","compressQuality","compressBar","serverCompress","storeUploadChannel","storeAutoRetry","storeUploadNameType","uploadFolder","customUrlSettings","useCustomUrl","customUrlPrefix","adminUrlSettings","autoReUpload","storeUploadMethod","storeUploadFolder","localStorage","getItem","storeAutoReUpload","mutations","setUserConfig","setBingWallPapers","setCredentials","setUploadMethod","setUploadCopyUrlForm","setCompressConfig","value","setStoreUploadChannel","uploadChannel","setStoreUploadNameType","setCustomUrlSettings","setStoreAutoRetry","setAdminUrlSettings","setUseDarkMode","setCusDarkMode","setStoreUploadFolder","folder","setItem","setStoreAutoReUpload","actions","fetchUserConfig","get","data","fetchBingWallPapers","wallpapers","map","wallpaper","url","all","resolve","img","Image","onload","onerror","src","modules","plugins","createPersistedState","adminAuthGuard","to","from","next","name","btoa","withCredentials","res","Error","err","userAuthGuard","post","routes","path","beforeEnter","createRouter","history","createWebHistory","process","__webpack_module_cache__","__webpack_require__","moduleId","cachedModule","undefined","exports","module","__webpack_modules__","call","m","deferred","O","result","chunkIds","fn","priority","notFulfilled","Infinity","i","length","fulfilled","j","keys","every","splice","r","n","getter","__esModule","d","a","definition","o","defineProperty","enumerable","f","e","chunkId","reduce","promises","u","miniCssF","g","globalThis","Function","obj","prop","prototype","hasOwnProperty","inProgress","dataWebpackPrefix","l","done","script","needAttach","scripts","getElementsByTagName","s","getAttribute","charset","nc","setAttribute","onScriptComplete","prev","event","clearTimeout","timeout","doneFns","parentNode","removeChild","setTimeout","bind","target","Symbol","toStringTag","p","createStylesheet","fullhref","oldTag","linkTag","nonce","onLinkComplete","errorType","realHref","code","insertBefore","nextSibling","findStylesheet","existingLinkTags","tag","dataHref","existingStyleTags","loadStylesheet","installedCssChunks","miniCss","cssChunks","installedChunks","installedChunkData","promise","loadingEnded","realSrc","message","webpackJsonpCallback","parentChunkLoadingFunction","moreModules","runtime","some","id","chunkLoadingGlobal","self","__webpack_exports__"],"ignoreList":[],"sourceRoot":""} \ No newline at end of file diff --git a/js/app.c7b1facf.js.map.gz b/js/app.c7b1facf.js.map.gz new file mode 100644 index 0000000000000000000000000000000000000000..7e68a3ccb489a0cc7eea098c451a941bcbfd1320 GIT binary patch literal 15251 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