feat: 更新管理员登录为简易版jwt
This commit is contained in:
@@ -2,14 +2,79 @@
|
|||||||
# @Author : Lan
|
# @Author : Lan
|
||||||
# @File : depends.py
|
# @File : depends.py
|
||||||
# @Software: PyCharm
|
# @Software: PyCharm
|
||||||
from fastapi import Header, HTTPException
|
from fastapi import Header, HTTPException, Depends
|
||||||
from fastapi.requests import Request
|
from fastapi.requests import Request
|
||||||
|
import base64
|
||||||
|
import hmac
|
||||||
|
import json
|
||||||
|
import time
|
||||||
from core.settings import settings
|
from core.settings import settings
|
||||||
from apps.admin.services import FileService, ConfigService, LocalFileService
|
from apps.admin.services import FileService, ConfigService, LocalFileService
|
||||||
|
|
||||||
|
def create_token(data: dict, expires_in: int = 3600 * 24) -> str:
|
||||||
|
"""
|
||||||
|
创建JWT token
|
||||||
|
:param data: 数据负载
|
||||||
|
:param expires_in: 过期时间(秒)
|
||||||
|
"""
|
||||||
|
header = base64.b64encode(json.dumps({"alg": "HS256", "typ": "JWT"}).encode()).decode()
|
||||||
|
payload = base64.b64encode(json.dumps({
|
||||||
|
**data,
|
||||||
|
"exp": int(time.time()) + expires_in
|
||||||
|
}).encode()).decode()
|
||||||
|
|
||||||
|
signature = hmac.new(
|
||||||
|
settings.jwt_secret_key.encode(),
|
||||||
|
f"{header}.{payload}".encode(),
|
||||||
|
'sha256'
|
||||||
|
).digest()
|
||||||
|
signature = base64.b64encode(signature).decode()
|
||||||
|
|
||||||
|
return f"{header}.{payload}.{signature}"
|
||||||
|
|
||||||
|
def verify_token(token: str) -> dict:
|
||||||
|
"""
|
||||||
|
验证JWT token
|
||||||
|
:param token: JWT token
|
||||||
|
:return: 解码后的数据
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
header_b64, payload_b64, signature_b64 = token.split('.')
|
||||||
|
|
||||||
|
# 验证签名
|
||||||
|
expected_signature = hmac.new(
|
||||||
|
settings.jwt_secret_key.encode(),
|
||||||
|
f"{header_b64}.{payload_b64}".encode(),
|
||||||
|
'sha256'
|
||||||
|
).digest()
|
||||||
|
expected_signature_b64 = base64.b64encode(expected_signature).decode()
|
||||||
|
|
||||||
|
if signature_b64 != expected_signature_b64:
|
||||||
|
raise ValueError("无效的签名")
|
||||||
|
|
||||||
|
# 解码payload
|
||||||
|
payload = json.loads(base64.b64decode(payload_b64))
|
||||||
|
|
||||||
|
# 检查是否过期
|
||||||
|
if payload.get("exp", 0) < time.time():
|
||||||
|
raise ValueError("token已过期")
|
||||||
|
|
||||||
|
return payload
|
||||||
|
except Exception as e:
|
||||||
|
raise ValueError(f"token验证失败: {str(e)}")
|
||||||
|
|
||||||
async def admin_required(authorization: str = Header(default=None), request: Request = None):
|
async def admin_required(authorization: str = Header(default=None), request: Request = None):
|
||||||
is_admin = (authorization.split(' ')[-1] if authorization else '') == settings.admin_token
|
"""
|
||||||
|
验证管理员权限
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
if not authorization or not authorization.startswith('Bearer '):
|
||||||
|
raise ValueError("缺少Bearer token")
|
||||||
|
|
||||||
|
token = authorization.split(' ')[1]
|
||||||
|
payload = verify_token(token)
|
||||||
|
is_admin = payload.get("is_admin", False)
|
||||||
|
|
||||||
if request.url.path.startswith('/share/'):
|
if request.url.path.startswith('/share/'):
|
||||||
if not settings.openUpload and not is_admin:
|
if not settings.openUpload and not is_admin:
|
||||||
raise HTTPException(status_code=403, detail='本站未开启游客上传,如需上传请先登录后台')
|
raise HTTPException(status_code=403, detail='本站未开启游客上传,如需上传请先登录后台')
|
||||||
@@ -17,7 +82,8 @@ async def admin_required(authorization: str = Header(default=None), request: Req
|
|||||||
if not is_admin:
|
if not is_admin:
|
||||||
raise HTTPException(status_code=401, detail='未授权或授权校验失败')
|
raise HTTPException(status_code=401, detail='未授权或授权校验失败')
|
||||||
return is_admin
|
return is_admin
|
||||||
|
except ValueError as e:
|
||||||
|
raise HTTPException(status_code=401, detail=str(e))
|
||||||
|
|
||||||
async def get_file_service():
|
async def get_file_service():
|
||||||
return FileService()
|
return FileService()
|
||||||
|
|||||||
@@ -13,3 +13,7 @@ class ShareItem(BaseModel):
|
|||||||
|
|
||||||
class DeleteItem(BaseModel):
|
class DeleteItem(BaseModel):
|
||||||
filename: str
|
filename: str
|
||||||
|
|
||||||
|
|
||||||
|
class LoginData(BaseModel):
|
||||||
|
password: str
|
||||||
|
|||||||
+15
-4
@@ -4,19 +4,30 @@
|
|||||||
# @Software: PyCharm
|
# @Software: PyCharm
|
||||||
import datetime
|
import datetime
|
||||||
|
|
||||||
from fastapi import APIRouter, Depends
|
from fastapi import APIRouter, Depends, HTTPException
|
||||||
from apps.admin.services import FileService, ConfigService, LocalFileService
|
from apps.admin.services import FileService, ConfigService, LocalFileService
|
||||||
from apps.admin.dependencies import admin_required, get_file_service, get_config_service, get_local_file_service
|
from apps.admin.dependencies import admin_required, get_file_service, get_config_service, get_local_file_service
|
||||||
from apps.admin.schemas import IDData, ShareItem, DeleteItem
|
from apps.admin.schemas import IDData, ShareItem, DeleteItem, LoginData
|
||||||
from core.response import APIResponse
|
from core.response import APIResponse
|
||||||
from apps.base.models import FileCodes, KeyValue
|
from apps.base.models import FileCodes, KeyValue
|
||||||
|
from apps.admin.dependencies import create_token
|
||||||
|
from core.settings import settings
|
||||||
|
|
||||||
admin_api = APIRouter(prefix='/admin', tags=['管理'])
|
admin_api = APIRouter(prefix='/admin', tags=['管理'])
|
||||||
|
|
||||||
|
|
||||||
@admin_api.post('/login')
|
@admin_api.post('/login')
|
||||||
async def login(admin: bool = Depends(admin_required)):
|
async def login(data: LoginData):
|
||||||
return APIResponse()
|
# 验证管理员密码
|
||||||
|
if data.password != settings.admin_password:
|
||||||
|
raise HTTPException(status_code=401, detail="密码错误")
|
||||||
|
|
||||||
|
# 生成包含管理员身份的token
|
||||||
|
token = create_token({"is_admin": True})
|
||||||
|
return APIResponse(detail={
|
||||||
|
"token": token,
|
||||||
|
"token_type": "Bearer"
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
@admin_api.get('/dashboard')
|
@admin_api.get('/dashboard')
|
||||||
|
|||||||
@@ -66,6 +66,9 @@ DEFAULT_CONFIG = {
|
|||||||
'port': 12345,
|
'port': 12345,
|
||||||
'showAdminAddr': 0,
|
'showAdminAddr': 0,
|
||||||
'robotsText': 'User-agent: *\nDisallow: /',
|
'robotsText': 'User-agent: *\nDisallow: /',
|
||||||
|
'jwt_secret_key': "your-secret-key", # 建议使用环境变量
|
||||||
|
'jwt_algorithm': "HS256",
|
||||||
|
'admin_password': 'FileCodeBox2023', # 建议使用环境变量存储
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
import{c as i,B as k,r as h,o as u,I as v,d as x,e as t,n as o,g as e,i as w,f as n,X as _,F as M,q as C,p as z,y as B,J as L,m as D,K as F,t as I,z as d}from"./index-CiI2cp0V.js";import{B as j}from"./box-BA8SMkDM.js";/**
|
import{c as i,B as k,r as h,o as u,I as v,d as x,e as t,n as o,g as e,i as w,f as n,X as _,F as M,q as C,p as z,y as B,J as L,m as D,K as F,t as I,z as d}from"./index-BXFy05WO.js";import{B as j}from"./box-Cg0hrykV.js";/**
|
||||||
* @license lucide-vue-next v0.445.0 - ISC
|
* @license lucide-vue-next v0.445.0 - ISC
|
||||||
*
|
*
|
||||||
* This source code is licensed under the ISC license.
|
* This source code is licensed under the ISC license.
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
import{c as g,B as v,H as w,o as _,d as u,e as t,n as a,g as e,i as k,t as i,f as y,F as U,q as F,A as M,z as p,J as z,K as C}from"./index-CiI2cp0V.js";import{F as m}from"./file-CWusGEpI.js";import{H as D,T as S}from"./trash-dDHutUhM.js";/**
|
import{c as g,B as v,H as w,o as _,d as u,e as t,n as a,g as e,i as k,t as i,f as y,F as U,q as F,A as M,z as p,J as z,K as C}from"./index-BXFy05WO.js";import{F as m}from"./file-DYxS796P.js";import{H as D,T as S}from"./trash-CUA4S_ac.js";/**
|
||||||
* @license lucide-vue-next v0.445.0 - ISC
|
* @license lucide-vue-next v0.445.0 - ISC
|
||||||
*
|
*
|
||||||
* This source code is licensed under the ISC license.
|
* This source code is licensed under the ISC license.
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
import{c as V,B as T,u as q,r as _,b as k,d as c,e as t,n as o,g as a,i as A,j as P,f as m,v as H,m as I,F as v,q as w,t as d,A as S,z as g}from"./index-CiI2cp0V.js";import{F as L}from"./file-CWusGEpI.js";/**
|
import{c as V,B as T,u as q,r as _,b as k,d as c,e as t,n as o,g as a,i as A,j as P,f as m,v as H,m as I,F as v,q as w,t as d,A as S,z as g}from"./index-BXFy05WO.js";import{F as L}from"./file-DYxS796P.js";/**
|
||||||
* @license lucide-vue-next v0.445.0 - ISC
|
* @license lucide-vue-next v0.445.0 - ISC
|
||||||
*
|
*
|
||||||
* This source code is licensed under the ISC license.
|
* This source code is licensed under the ISC license.
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
import{G as y,r as u,B as b,u as v,d as w,e,n as l,g as o,i as x,f as h,h as k,j as S,v as A,m as V,t as B,y as D,z as j,A as P,_}from"./index-BXFy05WO.js";import{B as z}from"./box-Cg0hrykV.js";const M=y("adminData",()=>{const d=u(localStorage.getItem("adminPassword")||"");function n(a){d.value=a,localStorage.setItem("token",a)}return{adminPassword:d,updateAdminPwd:n}}),I={class:"mx-auto h-16 w-16 relative"},L={class:"rounded-md shadow-sm -space-y-px"},N=["disabled"],T=b({__name:"LoginView",setup(d){const n=v(),a=u(""),i=u(!1),s=x("isDarkMode"),c=M(),p=()=>{let r=!0;return a.value?a.value.length<6&&(n.showAlert("密码长度至少为6位","error"),r=!1):(n.showAlert("无效的密码","error"),r=!1),r},m=D(),f=async()=>{if(p()){P.post("/admin/login",{password:a.value}).then(r=>{c.updateAdminPwd(r.detail.token),m.push("/admin")}).catch(r=>{n.showAlert(r.response.data.detail,"error")}),i.value=!0;try{await new Promise(r=>setTimeout(r,2e3))}catch{}finally{i.value=!1}}};return(r,t)=>(j(),w("div",{class:l(["min-h-screen flex items-center justify-center py-12 px-4 sm:px-6 lg:px-8 transition-colors duration-200 relative overflow-hidden",o(s)?"bg-gray-900":"bg-gray-50"])},[t[6]||(t[6]=e("div",{class:"absolute inset-0 z-0"},[e("div",{class:"cyber-grid"}),e("div",{class:"floating-particles"})],-1)),e("div",{class:l(["max-w-md w-full space-y-8 backdrop-blur-lg bg-opacity-20 p-8 rounded-xl border border-opacity-20",[o(s)?"bg-gray-800 border-gray-600":"bg-white/70 border-gray-200"]])},[e("div",null,[e("div",I,[t[1]||(t[1]=e("div",{class:"absolute inset-0 bg-gradient-to-r from-cyan-500 via-purple-500 to-pink-500 rounded-full animate-spin-slow"},null,-1)),t[2]||(t[2]=e("div",{class:"absolute -inset-2 bg-gradient-to-r from-cyan-500 via-purple-500 to-pink-500 rounded-full opacity-50 blur-md animate-pulse"},null,-1)),e("div",{class:l(["absolute inset-1 rounded-full flex items-center justify-center",o(s)?"bg-gray-800":"bg-white"])},[h(o(z),{class:l(["h-8 w-8",o(s)?"text-cyan-400":"text-cyan-600"])},null,8,["class"])],2)]),e("h2",{class:l(["mt-6 text-center text-3xl font-extrabold",o(s)?"text-white":"text-gray-900"])}," 登录 ",2)]),e("form",{class:"mt-8 space-y-6",onSubmit:k(f,["prevent"])},[t[5]||(t[5]=e("input",{type:"hidden",name:"remember",value:"true"},null,-1)),e("div",L,[e("div",null,[t[3]||(t[3]=e("label",{for:"password",class:"sr-only"},"密码",-1)),S(e("input",{id:"password",name:"password",type:"password",autocomplete:"current-password",required:"","onUpdate:modelValue":t[0]||(t[0]=g=>a.value=g),class:l(["appearance-none rounded-t-md relative block w-full px-4 py-3 border transition-all duration-200 placeholder-gray-500 focus:outline-none focus:ring-2 focus:ring-cyan-500 focus:border-cyan-500 focus:z-10 sm:text-sm backdrop-blur-sm",o(s)?"bg-gray-800/50 border-gray-600 text-white placeholder-gray-400 hover:border-gray-500":"bg-white/50 border-gray-300 text-gray-900 hover:border-gray-400"]),placeholder:"密码"},null,2),[[A,a.value]])])]),e("div",null,[e("button",{type:"submit",class:l(["group relative w-full flex justify-center py-3 px-4 border border-transparent text-sm font-medium rounded-md text-white transition-all duration-300 transform hover:scale-[1.02] focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-cyan-500 shadow-lg hover:shadow-cyan-500/50",o(s)?"bg-gradient-to-r from-cyan-500 to-purple-500 hover:from-cyan-600 hover:to-purple-600":"bg-gradient-to-r from-cyan-600 to-purple-600 hover:from-cyan-700 hover:to-purple-700",i.value?"opacity-75 cursor-not-allowed":""]),disabled:i.value},[t[4]||(t[4]=e("span",{class:"absolute left-0 inset-y-0 flex items-center pl-3"},null,-1)),V(" "+B(i.value?"登录中...":"登录"),1)],10,N)])],32)],2)],2))}}),E=_(T,[["__scopeId","data-v-3d6e2ab2"]]);export{E as default};
|
||||||
@@ -1 +0,0 @@
|
|||||||
@keyframes spin-2e50c3fa{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.animate-spin-slow[data-v-2e50c3fa]{animation:spin-2e50c3fa 8s linear infinite}.fade-enter-active[data-v-2e50c3fa],.fade-leave-active[data-v-2e50c3fa]{transition:opacity .3s ease}.fade-enter-from[data-v-2e50c3fa],.fade-leave-to[data-v-2e50c3fa]{opacity:0}input[data-v-2e50c3fa]:focus{box-shadow:0 0 15px #6366f14d}button[data-v-2e50c3fa]:active:not(:disabled){transform:scale(.98)}.cyber-grid[data-v-2e50c3fa]{background-image:linear-gradient(transparent 95%,#6366f11a 50%),linear-gradient(90deg,transparent 95%,rgba(99,102,241,.1) 50%);background-size:30px 30px;width:100%;height:100%;position:absolute;opacity:.5}.floating-particles[data-v-2e50c3fa]{position:absolute;width:100%;height:100%;background:radial-gradient(circle at center,transparent 0%,transparent 100%);filter:url(#gooey)}.floating-particles[data-v-2e50c3fa]:before,.floating-particles[data-v-2e50c3fa]:after{content:"";position:absolute;width:100%;height:100%;background-image:radial-gradient(circle at center,rgba(99,102,241,.1) 0%,transparent 50%);animation:float-2e50c3fa 20s infinite linear}.floating-particles[data-v-2e50c3fa]:after{animation-delay:-10s;opacity:.5}@keyframes float-2e50c3fa{0%{transform:translate(0) scale(1)}50%{transform:translate(50px,50px) scale(1.5)}to{transform:translate(0) scale(1)}}button[data-v-2e50c3fa]:hover:not(:disabled){box-shadow:0 0 25px #6366f180}.fade-enter-active[data-v-2e50c3fa],.fade-leave-active[data-v-2e50c3fa]{transition:all .5s cubic-bezier(.4,0,.2,1)}
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
import{G as y,r as u,B as v,u as b,d as w,e,n as l,g as o,i as x,f as h,h as k,j as S,v as A,m as V,t as B,y as D,z as j,A as P,_}from"./index-CiI2cp0V.js";import{B as z}from"./box-BA8SMkDM.js";const M=y("adminData",()=>{const d=u(localStorage.getItem("adminPassword")||"");function n(t){d.value=t,localStorage.setItem("token",t)}return{adminPassword:d,updateAdminPwd:n}}),I={class:"mx-auto h-16 w-16 relative"},L={class:"rounded-md shadow-sm -space-y-px"},N=["disabled"],T=v({__name:"LoginView",setup(d){const n=b(),t=u(""),i=u(!1),s=x("isDarkMode"),c=M(),p=()=>{let a=!0;return t.value?t.value.length<6&&(n.showAlert("密码长度至少为6位","error"),a=!1):(n.showAlert("无效的密码","error"),a=!1),a},m=D(),f=async()=>{if(p()){c.updateAdminPwd(t.value),P.post("/admin/login",{password:t.value}).then(()=>{m.push("/admin")}).catch(a=>{n.showAlert(a.response.data.detail,"error")}),i.value=!0;try{await new Promise(a=>setTimeout(a,2e3))}catch{}finally{i.value=!1}}};return(a,r)=>(j(),w("div",{class:l(["min-h-screen flex items-center justify-center py-12 px-4 sm:px-6 lg:px-8 transition-colors duration-200 relative overflow-hidden",o(s)?"bg-gray-900":"bg-gray-50"])},[r[6]||(r[6]=e("div",{class:"absolute inset-0 z-0"},[e("div",{class:"cyber-grid"}),e("div",{class:"floating-particles"})],-1)),e("div",{class:l(["max-w-md w-full space-y-8 backdrop-blur-lg bg-opacity-20 p-8 rounded-xl border border-opacity-20",[o(s)?"bg-gray-800 border-gray-600":"bg-white/70 border-gray-200"]])},[e("div",null,[e("div",I,[r[1]||(r[1]=e("div",{class:"absolute inset-0 bg-gradient-to-r from-cyan-500 via-purple-500 to-pink-500 rounded-full animate-spin-slow"},null,-1)),r[2]||(r[2]=e("div",{class:"absolute -inset-2 bg-gradient-to-r from-cyan-500 via-purple-500 to-pink-500 rounded-full opacity-50 blur-md animate-pulse"},null,-1)),e("div",{class:l(["absolute inset-1 rounded-full flex items-center justify-center",o(s)?"bg-gray-800":"bg-white"])},[h(o(z),{class:l(["h-8 w-8",o(s)?"text-cyan-400":"text-cyan-600"])},null,8,["class"])],2)]),e("h2",{class:l(["mt-6 text-center text-3xl font-extrabold",o(s)?"text-white":"text-gray-900"])}," 登录 ",2)]),e("form",{class:"mt-8 space-y-6",onSubmit:k(f,["prevent"])},[r[5]||(r[5]=e("input",{type:"hidden",name:"remember",value:"true"},null,-1)),e("div",L,[e("div",null,[r[3]||(r[3]=e("label",{for:"password",class:"sr-only"},"密码",-1)),S(e("input",{id:"password",name:"password",type:"password",autocomplete:"current-password",required:"","onUpdate:modelValue":r[0]||(r[0]=g=>t.value=g),class:l(["appearance-none rounded-t-md relative block w-full px-4 py-3 border transition-all duration-200 placeholder-gray-500 focus:outline-none focus:ring-2 focus:ring-cyan-500 focus:border-cyan-500 focus:z-10 sm:text-sm backdrop-blur-sm",o(s)?"bg-gray-800/50 border-gray-600 text-white placeholder-gray-400 hover:border-gray-500":"bg-white/50 border-gray-300 text-gray-900 hover:border-gray-400"]),placeholder:"密码"},null,2),[[A,t.value]])])]),e("div",null,[e("button",{type:"submit",class:l(["group relative w-full flex justify-center py-3 px-4 border border-transparent text-sm font-medium rounded-md text-white transition-all duration-300 transform hover:scale-[1.02] focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-cyan-500 shadow-lg hover:shadow-cyan-500/50",o(s)?"bg-gradient-to-r from-cyan-500 to-purple-500 hover:from-cyan-600 hover:to-purple-600":"bg-gradient-to-r from-cyan-600 to-purple-600 hover:from-cyan-700 hover:to-purple-700",i.value?"opacity-75 cursor-not-allowed":""]),disabled:i.value},[r[4]||(r[4]=e("span",{class:"absolute left-0 inset-y-0 flex items-center pl-3"},null,-1)),V(" "+B(i.value?"登录中...":"登录"),1)],10,N)])],32)],2)],2))}}),E=_(T,[["__scopeId","data-v-2e50c3fa"]]);export{E as default};
|
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
@keyframes spin-3d6e2ab2{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.animate-spin-slow[data-v-3d6e2ab2]{animation:spin-3d6e2ab2 8s linear infinite}.fade-enter-active[data-v-3d6e2ab2],.fade-leave-active[data-v-3d6e2ab2]{transition:opacity .3s ease}.fade-enter-from[data-v-3d6e2ab2],.fade-leave-to[data-v-3d6e2ab2]{opacity:0}input[data-v-3d6e2ab2]:focus{box-shadow:0 0 15px #6366f14d}button[data-v-3d6e2ab2]:active:not(:disabled){transform:scale(.98)}.cyber-grid[data-v-3d6e2ab2]{background-image:linear-gradient(transparent 95%,#6366f11a 50%),linear-gradient(90deg,transparent 95%,rgba(99,102,241,.1) 50%);background-size:30px 30px;width:100%;height:100%;position:absolute;opacity:.5}.floating-particles[data-v-3d6e2ab2]{position:absolute;width:100%;height:100%;background:radial-gradient(circle at center,transparent 0%,transparent 100%);filter:url(#gooey)}.floating-particles[data-v-3d6e2ab2]:before,.floating-particles[data-v-3d6e2ab2]:after{content:"";position:absolute;width:100%;height:100%;background-image:radial-gradient(circle at center,rgba(99,102,241,.1) 0%,transparent 50%);animation:float-3d6e2ab2 20s infinite linear}.floating-particles[data-v-3d6e2ab2]:after{animation-delay:-10s;opacity:.5}@keyframes float-3d6e2ab2{0%{transform:translate(0) scale(1)}50%{transform:translate(50px,50px) scale(1.5)}to{transform:translate(0) scale(1)}}button[data-v-3d6e2ab2]:hover:not(:disabled){box-shadow:0 0 25px #6366f180}.fade-enter-active[data-v-3d6e2ab2],.fade-leave-active[data-v-3d6e2ab2]{transition:all .5s cubic-bezier(.4,0,.2,1)}
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
var De=Object.defineProperty;var Pe=(d,e,t)=>e in d?De(d,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):d[e]=t;var v=(d,e,t)=>Pe(d,typeof e!="symbol"?e+"":e,t);import{c as _e,_ as Fe,u as Ze,s as Oe,r as D,o as Ue,a as Qe,w as He,b as Ne,d as I,e as p,f as $,n as w,g as f,i as Ve,t as j,h as Ge,j as We,k as Y,v as Xe,l as Q,m as Z,p as Ke,X as xe,T as Je,F as Ye,q as et,x as le,y as tt,z as L,A as nt}from"./index-CiI2cp0V.js";import{c as H,u as st,S as it,C as rt,a as ot,Q as lt,E as at}from"./_commonjsHelpers-GlvjlJV-.js";import{B as ct}from"./box-BA8SMkDM.js";import{F as ke}from"./file-CWusGEpI.js";import{H as ut,T as pt}from"./trash-dDHutUhM.js";/**
|
var De=Object.defineProperty;var Pe=(d,e,t)=>e in d?De(d,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):d[e]=t;var v=(d,e,t)=>Pe(d,typeof e!="symbol"?e+"":e,t);import{c as _e,_ as Fe,u as Ze,s as Oe,r as D,o as Ue,a as Qe,w as He,b as Ne,d as I,e as p,f as $,n as w,g as f,i as Ve,t as j,h as Ge,j as We,k as Y,v as Xe,l as Q,m as Z,p as Ke,X as xe,T as Je,F as Ye,q as et,x as le,y as tt,z as L,A as nt}from"./index-BXFy05WO.js";import{c as H,u as st,S as it,C as rt,a as ot,Q as lt,E as at}from"./_commonjsHelpers-CoPwux66.js";import{B as ct}from"./box-Cg0hrykV.js";import{F as ke}from"./file-DYxS796P.js";import{H as ut,T as pt}from"./trash-CUA4S_ac.js";/**
|
||||||
* @license lucide-vue-next v0.445.0 - ISC
|
* @license lucide-vue-next v0.445.0 - ISC
|
||||||
*
|
*
|
||||||
* This source code is licensed under the ISC license.
|
* This source code is licensed under the ISC license.
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
import{c as W,B as oe,r as z,o as ne,w as he,d as F,z as D,e as a,_ as se,u as ae,y as ge,i as pe,b as ye,p as ve,f as M,n as f,g as i,t as U,h as Q,l as E,k as N,j as J,v as X,x as K,C as be,F as Y,q as Z,m as V,X as xe,T as me,A as ee}from"./index-CiI2cp0V.js";import{g as we,u as _e,S as Ce,C as Ae,E as Me,a as Se,Q as Be}from"./_commonjsHelpers-GlvjlJV-.js";import{F as te}from"./file-CWusGEpI.js";import{T as Ie,H as Te}from"./trash-dDHutUhM.js";/**
|
import{c as W,B as oe,r as z,o as ne,w as he,d as F,z as D,e as a,_ as se,u as ae,y as ge,i as pe,b as ye,p as ve,f as M,n as f,g as i,t as U,h as Q,l as E,k as N,j as J,v as X,x as K,C as be,F as Y,q as Z,m as V,X as xe,T as me,A as ee}from"./index-BXFy05WO.js";import{g as we,u as _e,S as Ce,C as Ae,E as Me,a as Se,Q as Be}from"./_commonjsHelpers-CoPwux66.js";import{F as te}from"./file-DYxS796P.js";import{T as Ie,H as Te}from"./trash-CUA4S_ac.js";/**
|
||||||
* @license lucide-vue-next v0.445.0 - ISC
|
* @license lucide-vue-next v0.445.0 - ISC
|
||||||
*
|
*
|
||||||
* This source code is licensed under the ISC license.
|
* This source code is licensed under the ISC license.
|
||||||
+1
-1
File diff suppressed because one or more lines are too long
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
import{c as k,B as F,D as R,r as _,E as K,o as V,F as X,G as x,H as Y}from"./index-CiI2cp0V.js";/**
|
import{c as k,B as F,D as R,r as _,E as K,o as V,F as X,G as x,H as Y}from"./index-BXFy05WO.js";/**
|
||||||
* @license lucide-vue-next v0.445.0 - ISC
|
* @license lucide-vue-next v0.445.0 - ISC
|
||||||
*
|
*
|
||||||
* This source code is licensed under the ISC license.
|
* This source code is licensed under the ISC license.
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
import{c as a}from"./index-CiI2cp0V.js";/**
|
import{c as a}from"./index-BXFy05WO.js";/**
|
||||||
* @license lucide-vue-next v0.445.0 - ISC
|
* @license lucide-vue-next v0.445.0 - ISC
|
||||||
*
|
*
|
||||||
* This source code is licensed under the ISC license.
|
* This source code is licensed under the ISC license.
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
import{c as a}from"./index-CiI2cp0V.js";/**
|
import{c as a}from"./index-BXFy05WO.js";/**
|
||||||
* @license lucide-vue-next v0.445.0 - ISC
|
* @license lucide-vue-next v0.445.0 - ISC
|
||||||
*
|
*
|
||||||
* This source code is licensed under the ISC license.
|
* This source code is licensed under the ISC license.
|
||||||
File diff suppressed because one or more lines are too long
@@ -1,4 +1,4 @@
|
|||||||
import{c as a}from"./index-CiI2cp0V.js";/**
|
import{c as a}from"./index-BXFy05WO.js";/**
|
||||||
* @license lucide-vue-next v0.445.0 - ISC
|
* @license lucide-vue-next v0.445.0 - ISC
|
||||||
*
|
*
|
||||||
* This source code is licensed under the ISC license.
|
* This source code is licensed under the ISC license.
|
||||||
@@ -11,7 +11,7 @@
|
|||||||
<meta name="keywords" content="{{keywords}}" />
|
<meta name="keywords" content="{{keywords}}" />
|
||||||
<meta name="generator" content="FileCodeBox2.2" />
|
<meta name="generator" content="FileCodeBox2.2" />
|
||||||
<title>{{title}}</title>
|
<title>{{title}}</title>
|
||||||
<script type="module" crossorigin src="/assets/index-CiI2cp0V.js"></script>
|
<script type="module" crossorigin src="/assets/index-BXFy05WO.js"></script>
|
||||||
<link rel="stylesheet" crossorigin href="/assets/index-Bx419AMb.css">
|
<link rel="stylesheet" crossorigin href="/assets/index-Bx419AMb.css">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|||||||
Reference in New Issue
Block a user