From 31e5e40da2204c5aeb3143be981fad772574563e Mon Sep 17 00:00:00 2001 From: wochenlong Date: Fri, 29 May 2026 20:40:32 +0800 Subject: [PATCH 1/8] Add native dataset tag editor --- frontend/dist/assets/dataset-editor-entry.js | 218 +++++ frontend/dist/assets/dataset-editor.css | 771 +++++++++++++++++ frontend/dist/assets/dataset-editor.js | 826 +++++++++++++++++++ frontend/dist/dataset-editor.html | 180 ++++ frontend/dist/tageditor.html | 3 + gui.py | 14 +- mikazuki/app/api.py | 2 + mikazuki/app/application.py | 9 +- mikazuki/dataset_editor.py | 381 +++++++++ tests/test_dataset_editor_api.py | 491 +++++++++++ 10 files changed, 2890 insertions(+), 5 deletions(-) create mode 100644 frontend/dist/assets/dataset-editor-entry.js create mode 100644 frontend/dist/assets/dataset-editor.css create mode 100644 frontend/dist/assets/dataset-editor.js create mode 100644 frontend/dist/dataset-editor.html create mode 100644 mikazuki/dataset_editor.py create mode 100644 tests/test_dataset_editor_api.py diff --git a/frontend/dist/assets/dataset-editor-entry.js b/frontend/dist/assets/dataset-editor-entry.js new file mode 100644 index 00000000..9ef8fc5c --- /dev/null +++ b/frontend/dist/assets/dataset-editor-entry.js @@ -0,0 +1,218 @@ +(function () { + const EDITOR_SCRIPT_ID = "sd-native-dataset-editor-script"; + + function editorMarkup() { + return ` +
+
+ + + + + +
+
`; + } + + function mountEditor() { + if (document.getElementById("sd-native-editor-entry")) return true; + const content = document.querySelector(".theme-default-content"); + const theme = document.querySelector(".theme-container"); + const container = content || theme; + if (!container) return false; + + const entry = document.createElement("section"); + entry.id = "sd-native-editor-entry"; + entry.className = "sd-native-editor-entry sd-native-editor-entry--embedded"; + entry.innerHTML = editorMarkup(); + if (content) { + content.replaceChildren(entry); + return true; + } + + const stale = theme.querySelector(":scope > .sd-native-editor-entry"); + if (stale) stale.remove(); + theme.appendChild(entry); + return true; + } + + function loadEditorScript() { + if (document.getElementById(EDITOR_SCRIPT_ID)) return; + if ([...document.scripts].some((script) => script.src.includes("/assets/dataset-editor.js"))) return; + const configured = document.querySelector('meta[name="sd-dataset-editor-script"]')?.content; + const script = document.createElement("script"); + script.id = EDITOR_SCRIPT_ID; + script.src = configured || "/assets/dataset-editor.js?v=2.6.0"; + script.defer = true; + document.body.appendChild(script); + } + + function boot() { + const root = document.querySelector("#app"); + let mounted = false; + let stableTimer = 0; + + function scheduleMount() { + window.clearTimeout(stableTimer); + stableTimer = window.setTimeout(() => { + if (mounted) return; + if (mountEditor()) { + mounted = true; + loadEditorScript(); + if (observer) observer.disconnect(); + } + }, 120); + } + + const observer = root + ? new MutationObserver(scheduleMount) + : null; + + if (observer) { + observer.observe(root, { childList: true, subtree: true }); + } + + scheduleMount(); + window.addEventListener("load", () => { + if (mounted) return; + if (mountEditor()) { + mounted = true; + loadEditorScript(); + if (observer) observer.disconnect(); + } + }); + } + + if (document.readyState === "loading") { + document.addEventListener("DOMContentLoaded", boot); + } else { + boot(); + } +})(); diff --git a/frontend/dist/assets/dataset-editor.css b/frontend/dist/assets/dataset-editor.css new file mode 100644 index 00000000..577781f2 --- /dev/null +++ b/frontend/dist/assets/dataset-editor.css @@ -0,0 +1,771 @@ +:root { + color-scheme: light; + --de-bg: #f6f7f9; + --de-surface: #ffffff; + --de-border: #d8dde6; + --de-text: #1f2937; + --de-muted: #667085; + --de-accent: #0f766e; + --de-accent-strong: #0b5f59; + --de-warn: #b45309; + --de-workbench-min-width: 1320px; +} + +* { + box-sizing: border-box; +} + +body { + margin: 0; + background: var(--de-bg); + color: var(--de-text); + font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; + font-size: 14px; + overflow: auto hidden; +} + +button, +input, +select, +textarea { + font: inherit; +} + +button { + min-height: 34px; + border: 1px solid var(--de-border); + border-radius: 6px; + background: #fff; + color: var(--de-text); + cursor: pointer; +} + +button:hover { + border-color: var(--de-accent); +} + +button:disabled { + cursor: not-allowed; + opacity: 0.55; +} + +input, +select, +textarea { + width: 100%; + border: 1px solid var(--de-border); + border-radius: 6px; + background: #fff; + color: var(--de-text); + outline: none; +} + +input { + min-height: 34px; + padding: 6px 9px; +} + +select { + min-height: 34px; + padding: 6px 8px; +} + +textarea { + min-height: 160px; + resize: vertical; + padding: 10px; + line-height: 1.55; +} + +label { + color: var(--de-muted); + font-size: 12px; + font-weight: 600; +} + +.de-shell { + height: 100vh; + min-width: var(--de-workbench-min-width); + display: grid; + grid-template-rows: auto 1fr; + overflow: hidden; +} + +.de-topbar { + height: 52px; + display: flex; + align-items: center; + justify-content: space-between; + padding: 0 18px; + border-bottom: 1px solid var(--de-border); + background: var(--de-surface); +} + +.de-brand { + color: var(--de-text); + font-weight: 700; + text-decoration: none; +} + +.de-nav { + display: flex; + gap: 12px; +} + +.de-nav a { + color: var(--de-muted); + text-decoration: none; +} + +.de-status { + min-height: 20px; + margin: 0; + color: var(--de-muted); +} + +.de-primary { + border-color: var(--de-accent); + background: var(--de-accent); + color: #fff; +} + +.de-primary:hover { + background: var(--de-accent-strong); +} + +.de-workspace { + min-height: 0; + height: 100%; + display: grid; + grid-template-columns: 280px minmax(596px, 1fr) 420px; + gap: 12px; + padding: 12px; + overflow: hidden; +} + +.de-panel, +.de-gallery-wrap { + min-height: 0; + border: 1px solid var(--de-border); + border-radius: 8px; + background: var(--de-surface); +} + +.de-panel { + display: flex; + flex-direction: column; + gap: 9px; + padding: 12px; + overflow: auto; +} + +.de-panel h2 { + margin: 4px 0; + font-size: 15px; +} + +.de-dataset-card, +.de-scope-card { + position: relative; + display: grid; + gap: 8px; + padding: 10px; + border: 1px solid var(--de-border); + border-radius: 8px; + background: #f8fafc; +} + +.de-dataset-card { + min-height: 148px; + gap: 10px; + padding: 14px 12px 12px; + border-color: rgba(15, 118, 110, 0.36); + background: #f7fbfb; + box-shadow: 0 1px 3px rgba(16, 24, 40, 0.08); +} + +.de-dataset-card::before { + content: ""; + position: absolute; + inset: 12px auto 12px 0; + width: 3px; + border-radius: 0 3px 3px 0; + background: var(--de-accent); +} + +.de-dataset-card label, +.de-scope-card label { + color: var(--de-text); + font-size: 13px; +} + +.de-dataset-card label { + font-size: 14px; + font-weight: 700; +} + +.de-dataset-path { + min-height: 42px; + border-color: #c9d3e3; + background: #fbfcfe; + font-weight: 600; +} + +.de-dataset-path:focus, +.de-dataset-path:focus-within { + border-color: var(--de-accent); + box-shadow: 0 0 0 3px rgba(15, 118, 110, 0.14); +} + +.de-dataset-actions { + display: grid; + grid-template-columns: repeat(2, minmax(0, 1fr)); + gap: 8px; +} + +.de-dataset-actions button { + min-height: 42px; + font-weight: 700; +} + +.de-tabs { + display: grid; + grid-template-columns: repeat(5, 1fr); + gap: 4px; + padding: 3px; + border: 1px solid var(--de-border); + border-radius: 6px; + background: #f1f4f7; +} + +.de-tab { + min-height: 30px; + border: 0; + background: transparent; + font-size: 13px; +} + +.de-tab.is-active { + background: #fff; + color: var(--de-accent-strong); + box-shadow: 0 1px 2px rgba(16, 24, 40, 0.08); +} + +.de-tab-panel { + display: none; + min-height: 0; +} + +.de-tab-panel.is-active { + display: flex; + flex-direction: column; + gap: 9px; +} + +.de-gallery-wrap { + display: grid; + grid-template-rows: auto auto minmax(0, 1fr); + overflow: hidden; +} + +.de-selection-bar { + display: grid; + grid-template-columns: minmax(0, 1fr) auto; + gap: 8px; + align-items: center; + padding: 8px 12px; + border-bottom: 1px solid var(--de-border); + background: #fbfcfe; +} + +.de-selection-bar span { + color: var(--de-muted); + font-size: 12px; + font-weight: 600; +} + +.de-selection-actions { + display: flex; + justify-content: flex-end; + gap: 8px; +} + +.de-selection-actions button { + min-width: 74px; + padding: 0 10px; +} + +.de-gallery-pager { + display: grid; + grid-template-columns: minmax(0, 1fr) auto; + gap: 8px; + align-items: center; + padding: 8px 12px; + border-bottom: 1px solid var(--de-border); +} + +.de-gallery-page-summary { + min-width: 0; + color: var(--de-muted); + font-size: 12px; +} + +.de-gallery-page-controls { + display: flex; + justify-content: flex-end; + align-items: center; + gap: 8px; +} + +.de-gallery-page-controls button { + min-width: 56px; + padding: 0 10px; +} + +.de-gallery-page-controls input { + width: 64px; + min-height: 34px; + text-align: center; +} + +.de-gallery-page-controls select { + width: auto; + min-width: 74px; +} + +.de-gallery { + min-height: 0; + display: grid; + grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); + align-content: start; + gap: 10px; + padding: 12px; + overflow: auto; +} + +.de-card { + position: relative; + display: grid; + grid-template-rows: 220px 20px; + gap: 6px; + min-width: 0; + padding: 6px; + border: 1px solid var(--de-border); + border-radius: 8px; + background: #fff; + text-align: left; +} + +.de-card[aria-selected="true"] { + border-color: var(--de-accent); + box-shadow: 0 0 0 2px rgba(15, 118, 110, 0.16); +} + +.de-card[data-bulk-selected="true"] { + border-color: #2563eb; + box-shadow: 0 0 0 2px rgba(37, 99, 235, 0.18); +} + +.de-card-check { + position: absolute; + z-index: 2; + top: 10px; + left: 10px; + width: 24px; + min-height: 24px; + padding: 0; + border-color: rgba(31, 41, 55, 0.24); + background: rgba(255, 255, 255, 0.92); + color: #2563eb; + line-height: 20px; + text-align: center; + font-weight: 800; +} + +.de-card[data-bulk-selected="true"] .de-card-check { + border-color: #2563eb; + background: #eff6ff; +} + +.de-card img { + width: 100%; + height: 220px; + object-fit: contain; + border-radius: 5px; + background: #eef1f5; +} + +.de-gallery.is-cover .de-card img { + object-fit: cover; +} + +.de-card span { + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; + font-size: 12px; +} + +.de-preview { + display: grid; + place-items: center; + min-height: 220px; + border: 1px solid var(--de-border); + border-radius: 8px; + background: #eef1f5; + overflow: hidden; +} + +.de-preview img { + width: 100%; + height: 100%; + max-height: 360px; + object-fit: contain; +} + +.de-selected, +.de-stats, +.de-actions, +.de-replace { + display: flex; + gap: 8px; + align-items: center; +} + +.de-selected { + justify-content: space-between; +} + +.de-selected strong { + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; +} + +.de-actions button, +.de-replace input { + flex: 1; +} + +.de-tag-list, +.de-quick-tags { + display: flex; + flex-wrap: wrap; + gap: 6px; +} + +.de-tag-browser { + display: grid; + gap: 6px; +} + +.de-tag-list { + max-height: 84px; + overflow: hidden; +} + +.de-tag-list.is-expanded { + max-height: 220px; + overflow: auto; + padding-right: 2px; +} + +.de-tag { + max-width: 100%; + padding: 3px 7px; + border-radius: 999px; + background: #eef6f5; + color: #0b5f59; + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; + font-size: 12px; +} + +.de-link-button { + min-height: 26px; + justify-self: start; + padding: 0; + border: 0; + background: transparent; + color: var(--de-accent); + font-size: 12px; +} + +.de-link-button:hover { + border: 0; + color: var(--de-accent-strong); + text-decoration: underline; +} + +.de-quick-custom { + display: grid; + grid-template-columns: minmax(0, 1fr) 64px; + gap: 6px; +} + +.de-change-list { + display: grid; + gap: 7px; + max-height: 180px; + overflow: auto; +} + +.de-change { + display: grid; + gap: 4px; + padding: 8px; + border: 1px solid var(--de-border); + border-radius: 6px; + background: #fbfcfd; +} + +.de-change strong { + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; + font-size: 12px; +} + +.de-change-item, +.de-empty { + overflow: hidden; + color: var(--de-muted); + white-space: nowrap; + text-overflow: ellipsis; + font-size: 12px; +} + +.de-checkbox { + display: flex; + gap: 7px; + align-items: center; + color: var(--de-text); + font-size: 13px; +} + +.de-checkbox input { + width: auto; + min-height: auto; +} + +.de-placeholder { + padding: 10px; + border: 1px dashed var(--de-border); + border-radius: 8px; + color: var(--de-muted); +} + +.de-collapsible { + border-top: 1px solid var(--de-border); + padding-top: 8px; +} + +.de-collapsible summary { + cursor: pointer; + font-weight: 700; +} + +.de-collapsible .de-placeholder { + margin-top: 8px; +} + +#dirty-flag { + color: var(--de-warn); +} + +.sd-native-editor-entry { + width: 100%; +} + +.sd-native-editor-entry--embedded { + position: fixed; + inset: 0 0 0 var(--sidebar-width, 22rem); + z-index: 10; + width: auto; + margin: 0; + padding: 0; + overflow: hidden; +} + +.de-shell-embedded { + --de-bg: var(--c-bg-soft, #f9f9f9); + --de-surface: var(--c-bg, #ffffff); + --de-border: var(--c-border, rgba(60, 60, 60, 0.12)); + --de-text: var(--c-text-1, #213547); + --de-muted: var(--c-text-2, rgba(60, 60, 60, 0.7)); + --de-accent: var(--c-brand, #646cff); + --de-accent-strong: var(--c-brand-dark, #535bf2); + --de-workbench-min-width: 960px; + height: 100vh; + min-width: 0; + grid-template-rows: 1fr; + padding: 8px 12px 14px; + background: var(--de-bg); +} + +.de-shell-embedded .de-workspace { + grid-template-columns: 320px minmax(520px, 1fr) 380px; + gap: 10px; + height: 100%; + padding: 0; +} + +.de-shell-embedded .de-panel, +.de-shell-embedded .de-gallery-wrap { + border-color: var(--de-border); + border-radius: 8px; + box-shadow: none; +} + +.de-shell-embedded .de-panel { + gap: 8px; + padding: 10px; +} + +.de-shell-embedded .de-dataset-card { + min-height: 128px; + padding: 12px 10px 10px; + border-color: var(--de-border); + background: var(--de-surface); + box-shadow: none; +} + +.de-shell-embedded .de-dataset-card::before { + background: var(--de-accent); +} + +.de-shell-embedded .de-dataset-path, +.de-shell-embedded input, +.de-shell-embedded select, +.de-shell-embedded textarea { + border-color: var(--de-border); + border-radius: 6px; +} + +.de-shell-embedded .de-dataset-path, +.de-shell-embedded .de-dataset-actions button { + min-height: 36px; + font-weight: 500; +} + +.de-shell-embedded button { + border-radius: 6px; +} + +.de-shell-embedded .de-tabs { + grid-template-columns: repeat(5, minmax(0, 1fr)); +} + +.de-shell-embedded .de-tab { + min-height: 28px; + font-size: 12px; +} + +.de-shell-embedded .de-selection-bar, +.de-shell-embedded .de-gallery-pager { + padding: 7px 10px; +} + +.de-shell-embedded .de-selection-actions { + flex-wrap: wrap; + row-gap: 6px; +} + +.de-shell-embedded .de-selection-actions button, +.de-shell-embedded .de-gallery-page-controls button { + min-width: auto; + min-height: 30px; + padding: 0 8px; + font-size: 12px; +} + +.de-shell-embedded .de-gallery { + grid-template-columns: repeat(auto-fill, minmax(170px, 1fr)); + gap: 8px; + padding: 10px; +} + +.de-gallery-empty { + align-self: center; + justify-self: center; + width: min(360px, 100%); + padding: 22px; + border: 1px dashed var(--de-border); + border-radius: 8px; + background: var(--de-surface); + color: var(--de-muted); + text-align: center; +} + +.de-gallery-empty strong { + display: block; + margin-bottom: 8px; + color: var(--de-text); + font-size: 15px; +} + +.de-gallery-empty span { + font-size: 13px; + line-height: 1.6; +} + +.de-shell-embedded .de-card { + grid-template-rows: 170px 18px; +} + +.de-shell-embedded .de-card img { + height: 170px; +} + +.de-shell-embedded .de-preview { + min-height: 220px; +} + +.de-shell-embedded .de-actions { + grid-template-columns: repeat(3, minmax(0, 1fr)); +} + +@media (max-width: 1500px) { + .de-shell-embedded .de-workspace { + grid-template-columns: 300px minmax(420px, 1fr); + } + + .de-shell-embedded .de-editor { + grid-column: 1 / -1; + min-height: 320px; + } + + .de-shell-embedded .de-preview { + min-height: 180px; + } +} + +@media (max-width: 1080px) { + .de-shell-embedded { + height: auto; + } + + .de-shell-embedded .de-workspace { + grid-template-columns: 260px minmax(360px, 1fr); + } + + .de-shell-embedded .de-selection-bar, + .de-shell-embedded .de-gallery-pager { + grid-template-columns: 1fr; + align-items: start; + } + + .de-shell-embedded .de-selection-actions, + .de-shell-embedded .de-gallery-page-controls { + justify-content: flex-start; + } + + .de-shell-embedded .de-gallery-page-controls { + flex-wrap: wrap; + } + + .de-shell-embedded .de-editor { + grid-column: 1 / -1; + } +} diff --git a/frontend/dist/assets/dataset-editor.js b/frontend/dist/assets/dataset-editor.js new file mode 100644 index 00000000..bb145af1 --- /dev/null +++ b/frontend/dist/assets/dataset-editor.js @@ -0,0 +1,826 @@ +(function () { + const QUICK_TAGS_KEY = "sd-trainer.dataset-editor.quick-tags"; + const API_HISTORY = "/api/dataset-editor/history"; + const API_UNDO = "/api/dataset-editor/undo"; + const API_REDO = "/api/dataset-editor/redo"; + const TAG_COLLAPSED_LIMIT = 18; + const TAG_SEARCH_LIMIT = 80; + const TAG_EXPANDED_LIMIT = 240; + const DEFAULT_GALLERY_PAGE_SIZE = "auto"; + const GALLERY_PAGE_SIZE = 20; + const GALLERY_PAGE_SIZE_KEY = "sd-trainer.dataset-editor.gallery-page-size"; + const THUMBNAIL_FIT_KEY = "sd-trainer.dataset-editor.thumbnail-fit"; + const DEFAULT_QUICK_TAGS = ["masterpiece", "best quality", "1girl", "solo", "smile", "looking at viewer"]; + + const state = { + root: "", + items: [], + filtered: [], + selected: -1, + selectedPaths: new Set(), + selectionMode: "manual", + galleryPage: 0, + galleryPageSize: loadGalleryPageSize(), + autoGalleryPageSize: GALLERY_PAGE_SIZE, + thumbnailFit: localStorage.getItem(THUMBNAIL_FIT_KEY) || "contain", + dirty: false, + tags: [], + tagExpanded: false, + categories: [], + category: "", + changes: [], + canUndo: false, + canRedo: false, + quickTags: loadQuickTags(), + }; + + const el = { + path: document.getElementById("dataset-path"), + pick: document.getElementById("pick-folder"), + scan: document.getElementById("scan-dataset"), + status: document.getElementById("status"), + search: document.getElementById("search-tags"), + category: document.getElementById("category-filter"), + include: document.getElementById("include-tags"), + exclude: document.getElementById("exclude-tags"), + datasetCount: document.getElementById("dataset-count"), + filteredCount: document.getElementById("filtered-count"), + tagList: document.getElementById("tag-list"), + tagToggle: document.getElementById("tag-toggle"), + sideTabs: Array.from(document.querySelectorAll("[data-side-tab]")), + sidePanels: { + clean: document.getElementById("side-panel-clean"), + filter: document.getElementById("side-panel-filter"), + quick: document.getElementById("side-panel-quick"), + batch: document.getElementById("side-panel-batch"), + tagger: document.getElementById("side-panel-tagger"), + }, + quickTags: document.getElementById("quick-tags"), + quickTagInput: document.getElementById("quick-tag-input"), + quickTagAdd: document.getElementById("quick-tag-add"), + changeList: document.getElementById("change-list"), + gallery: document.getElementById("gallery"), + galleryFirstPage: document.getElementById("gallery-first-page"), + galleryPrevPage: document.getElementById("gallery-prev-page"), + galleryPageInput: document.getElementById("gallery-page-input"), + galleryPageSize: document.getElementById("gallery-page-size"), + galleryNextPage: document.getElementById("gallery-next-page"), + galleryLastPage: document.getElementById("gallery-last-page"), + galleryPageInfo: document.getElementById("gallery-page-info"), + selectionSummary: document.getElementById("selection-summary"), + selectPage: document.getElementById("select-page"), + selectFiltered: document.getElementById("select-filtered"), + selectAll: document.getElementById("select-all"), + clearSelection: document.getElementById("clear-selection"), + thumbnailFit: document.getElementById("thumbnail-fit"), + preview: document.getElementById("preview"), + selectedName: document.getElementById("selected-name"), + dirtyFlag: document.getElementById("dirty-flag"), + caption: document.getElementById("caption"), + save: document.getElementById("save-caption"), + undo: document.getElementById("undo-edit"), + redo: document.getElementById("redo-edit"), + prev: document.getElementById("prev-image"), + next: document.getElementById("next-image"), + append: document.getElementById("append-tags"), + remove: document.getElementById("remove-tags"), + replaceFrom: document.getElementById("replace-from"), + replaceTo: document.getElementById("replace-to"), + sort: document.getElementById("sort-tags"), + batch: document.getElementById("apply-batch"), + cleanCaption: document.getElementById("clean-caption"), + cleanUnderscore: document.getElementById("clean-underscore"), + cleanEscape: document.getElementById("clean-escape"), + cleanSort: document.getElementById("clean-sort"), + cleanup: document.getElementById("apply-cleanup"), + }; + + function loadQuickTags() { + try { + const saved = JSON.parse(localStorage.getItem(QUICK_TAGS_KEY) || "[]"); + return normalizeTagList([...saved, ...DEFAULT_QUICK_TAGS]).slice(0, 24); + } catch (_err) { + return DEFAULT_QUICK_TAGS; + } + } + + function loadGalleryPageSize() { + const stored = localStorage.getItem(GALLERY_PAGE_SIZE_KEY); + if (!stored || stored === "auto") return DEFAULT_GALLERY_PAGE_SIZE; + const value = Number(stored); + return [12, 15, 20, 24, 30, 48].includes(value) ? value : DEFAULT_GALLERY_PAGE_SIZE; + } + + function effectiveGalleryPageSize() { + return state.galleryPageSize === "auto" ? state.autoGalleryPageSize : Number(state.galleryPageSize); + } + + function updateAutoGalleryPageSize() { + const width = el.gallery?.clientWidth || 0; + const height = el.gallery?.clientHeight || 0; + const columns = Math.max(1, Math.floor(width / 230)); + const rows = Math.max(1, Math.floor(height / 236)); + state.autoGalleryPageSize = Math.min(60, Math.max(12, columns * rows)); + } + + function saveQuickTags() { + localStorage.setItem(QUICK_TAGS_KEY, JSON.stringify(state.quickTags.slice(0, 24))); + } + + function setStatus(text, isError) { + el.status.textContent = text; + el.status.style.color = isError ? "#b42318" : ""; + } + + function normalizeTagList(tags) { + const seen = new Set(); + return tags + .map((tag) => String(tag || "").trim()) + .filter((tag) => { + const key = tag.toLowerCase(); + if (!tag || seen.has(key)) return false; + seen.add(key); + return true; + }); + } + + function splitTags(value) { + return normalizeTagList(String(value || "").split(",")); + } + + async function api(url, options) { + const res = await fetch(url, options); + const json = await res.json().catch(() => null); + if (!res.ok || !json || json.status !== "success") { + const message = json?.message || json?.detail || res.statusText || "请求失败"; + throw new Error(message); + } + return json.data || {}; + } + + function currentItem() { + if (state.selected < 0) return null; + return state.filtered[state.selected] || null; + } + + function itemPath(item) { + return item?.relative_path || ""; + } + + function currentPageItems() { + const pageSize = effectiveGalleryPageSize(); + const start = state.galleryPage * pageSize; + return state.filtered.slice(start, start + pageSize); + } + + function selectedBatchItems() { + if (!state.selectedPaths.size) return state.filtered; + const selected = new Set(state.selectedPaths); + return state.items.filter((item) => selected.has(itemPath(item))); + } + + function pruneSelection() { + const existing = new Set(state.items.map((item) => itemPath(item))); + state.selectedPaths.forEach((path) => { + if (!existing.has(path)) state.selectedPaths.delete(path); + }); + } + + function toggleItemSelection(item) { + const path = itemPath(item); + if (!path) return; + if (state.selectedPaths.has(path)) { + state.selectedPaths.delete(path); + } else { + state.selectedPaths.add(path); + } + state.selectionMode = "manual"; + render(); + } + + function selectPageItems() { + currentPageItems().forEach((item) => state.selectedPaths.add(itemPath(item))); + state.selectionMode = "page"; + render(); + } + + function selectFilteredItems() { + state.filtered.forEach((item) => state.selectedPaths.add(itemPath(item))); + state.selectionMode = "filtered"; + render(); + } + + function selectAllItems() { + state.items.forEach((item) => state.selectedPaths.add(itemPath(item))); + state.selectionMode = "all"; + render(); + } + + function clearSelection() { + state.selectedPaths.clear(); + state.selectionMode = "manual"; + render(); + } + + function confirmDirty() { + if (!state.dirty) return true; + return window.confirm("当前 caption 尚未保存,确定切换图片吗?"); + } + + function applyFilters() { + const query = el.search.value.trim().toLowerCase(); + const include = splitTags(el.include.value).map((tag) => tag.toLowerCase()); + const exclude = splitTags(el.exclude.value).map((tag) => tag.toLowerCase()); + state.category = el.category.value; + state.filtered = state.items.filter((item) => { + const tags = (item.tags || []).map((tag) => tag.toLowerCase()); + const caption = String(item.caption || "").toLowerCase(); + if (state.category && item.category !== state.category) return false; + if (query && !caption.includes(query) && !tags.some((tag) => tag.includes(query))) return false; + if (include.length && !include.every((tag) => tags.includes(tag))) return false; + if (exclude.length && exclude.some((tag) => tags.includes(tag))) return false; + return true; + }); + pruneSelection(); + if (state.selected >= state.filtered.length) state.selected = state.filtered.length ? 0 : -1; + const maxPage = galleryPageCount() - 1; + if (state.galleryPage > maxPage) state.galleryPage = Math.max(0, maxPage); + if (state.selected >= 0) state.galleryPage = pageForIndex(state.selected); + render(); + } + + function renderCategories() { + const current = state.category; + el.category.innerHTML = ""; + const all = document.createElement("option"); + all.value = ""; + all.textContent = "全部"; + el.category.appendChild(all); + state.categories.forEach((item) => { + const option = document.createElement("option"); + option.value = item.value || ""; + option.textContent = `${item.name || "根目录"} ${item.count || 0}`; + el.category.appendChild(option); + }); + el.category.value = state.categories.some((item) => item.value === current) ? current : ""; + state.category = el.category.value; + } + + function renderTags() { + const query = el.search.value.trim().toLowerCase(); + const matched = state.tags.filter((item) => !query || item.tag.toLowerCase().includes(query)); + const limit = query ? TAG_SEARCH_LIMIT : state.tagExpanded ? TAG_EXPANDED_LIMIT : TAG_COLLAPSED_LIMIT; + const tags = matched.slice(0, limit); + el.tagList.innerHTML = ""; + el.tagList.classList.toggle("is-expanded", state.tagExpanded || !!query); + tags.forEach((item) => { + const chip = document.createElement("button"); + chip.type = "button"; + chip.className = "de-tag"; + chip.textContent = `${item.tag} ${item.count}`; + chip.title = item.tag; + chip.addEventListener("click", () => { + el.include.value = item.tag; + applyFilters(); + }); + el.tagList.appendChild(chip); + }); + const hidden = Math.max(0, matched.length - tags.length); + el.tagToggle.hidden = matched.length <= TAG_COLLAPSED_LIMIT && !state.tagExpanded; + el.tagToggle.textContent = state.tagExpanded + ? "收起标签" + : hidden + ? `显示更多标签(还有 ${hidden} 个)` + : "显示更多标签"; + } + + function renderQuickTags() { + const frequent = state.tags.map((item) => item.tag).slice(0, 18); + const tags = normalizeTagList([...state.quickTags, ...frequent]).slice(0, 30); + el.quickTags.innerHTML = ""; + tags.forEach((tag) => { + const chip = document.createElement("button"); + chip.type = "button"; + chip.className = "de-tag de-quick-tag"; + chip.textContent = tag; + chip.title = `添加 ${tag}`; + chip.addEventListener("click", () => appendTagToCaption(tag)); + el.quickTags.appendChild(chip); + }); + } + + function renderHistory() { + el.changeList.innerHTML = ""; + if (!state.root) { + el.changeList.innerHTML = '
扫描数据集后显示本次会话的改动。
'; + return; + } + if (!state.changes.length) { + el.changeList.innerHTML = '
暂无已保存改动。
'; + return; + } + state.changes.forEach((change) => { + const box = document.createElement("div"); + box.className = "de-change"; + const title = document.createElement("strong"); + title.textContent = `${change.label || "编辑"} · ${change.count || 0} 项`; + box.appendChild(title); + (change.items || []).slice(0, 4).forEach((item) => { + const row = document.createElement("div"); + row.className = "de-change-item"; + row.title = item.image; + row.textContent = item.image; + box.appendChild(row); + }); + if ((change.items || []).length > 4) { + const more = document.createElement("div"); + more.className = "de-change-item"; + more.textContent = `还有 ${(change.items || []).length - 4} 项`; + box.appendChild(more); + } + el.changeList.appendChild(box); + }); + } + + function renderGallery() { + const selected = currentItem(); + const pageSize = effectiveGalleryPageSize(); + const start = state.galleryPage * pageSize; + const pageItems = currentPageItems(); + el.gallery.innerHTML = ""; + el.gallery.classList.toggle("is-cover", state.thumbnailFit === "cover"); + if (!pageItems.length) { + const empty = document.createElement("div"); + empty.className = "de-gallery-empty"; + empty.innerHTML = state.items.length + ? "没有匹配的图片调整左侧范围或筛选条件后继续。" + : "未加载数据集从左侧选择 LoRA 训练图片目录后开始编辑。"; + el.gallery.appendChild(empty); + } + pageItems.forEach((item, pageIndex) => { + const index = start + pageIndex; + const path = itemPath(item); + const isBulkSelected = state.selectedPaths.has(path); + const card = document.createElement("button"); + card.type = "button"; + card.className = "de-card"; + card.setAttribute("aria-selected", item === selected ? "true" : "false"); + card.dataset.bulkSelected = isBulkSelected ? "true" : "false"; + card.innerHTML = "\"\""; + card.querySelector(".de-card-check").textContent = isBulkSelected ? "✓" : ""; + card.querySelector("img").src = item.image_url; + card.querySelector("img").alt = item.name; + card.querySelector("span:last-child").textContent = item.name; + card.addEventListener("click", (event) => { + if (event.ctrlKey || event.metaKey || event.shiftKey) { + toggleItemSelection(item); + return; + } + selectIndex(index); + }); + card.querySelector(".de-card-check").addEventListener("click", (event) => { + event.stopPropagation(); + toggleItemSelection(item); + }); + el.gallery.appendChild(card); + }); + const pages = galleryPageCount(); + const batchItems = selectedBatchItems(); + el.selectionSummary.textContent = state.selectedPaths.size + ? `已选 ${batchItems.length} 张` + : `未选中,将作用于当前筛选结果 ${state.filtered.length} 张`; + el.selectPage.disabled = pageItems.length === 0; + el.selectFiltered.disabled = state.filtered.length === 0; + el.selectAll.disabled = state.items.length === 0; + el.clearSelection.disabled = state.selectedPaths.size === 0; + el.galleryFirstPage.disabled = state.galleryPage <= 0; + el.galleryPrevPage.disabled = state.galleryPage <= 0; + el.galleryNextPage.disabled = state.galleryPage >= pages - 1; + el.galleryLastPage.disabled = state.galleryPage >= pages - 1; + el.galleryPageInput.disabled = !pages; + el.galleryPageInput.max = String(Math.max(1, pages)); + el.galleryPageInput.value = pages ? String(state.galleryPage + 1) : "1"; + el.galleryPageSize.value = String(state.galleryPageSize); + el.galleryPageInfo.textContent = pages + ? `${state.galleryPage + 1} / ${pages} · ${start + 1}-${Math.min(start + pageItems.length, state.filtered.length)}` + : "0 / 0"; + el.thumbnailFit.textContent = state.thumbnailFit === "cover" ? "填充" : "完整"; + el.thumbnailFit.setAttribute("aria-pressed", state.thumbnailFit === "cover" ? "true" : "false"); + } + + function renderEditor() { + const item = currentItem(); + el.dirtyFlag.textContent = state.dirty ? "未保存" : ""; + el.save.disabled = !item; + el.undo.disabled = !state.canUndo; + el.redo.disabled = !state.canRedo; + el.prev.disabled = state.selected <= 0; + el.next.disabled = state.selected < 0 || state.selected >= state.filtered.length - 1; + el.batch.disabled = state.filtered.length === 0; + + if (!item) { + el.preview.innerHTML = "未选择图片"; + el.selectedName.textContent = "-"; + el.caption.value = ""; + return; + } + + el.preview.innerHTML = "\"\""; + el.preview.querySelector("img").src = item.image_url; + el.preview.querySelector("img").alt = item.name; + el.selectedName.textContent = item.relative_path || item.name; + if (!state.dirty) el.caption.value = item.caption || ""; + } + + function render() { + el.datasetCount.textContent = `${state.items.length} 张图片`; + el.filteredCount.textContent = `${state.filtered.length} 个结果`; + renderTags(); + renderQuickTags(); + renderHistory(); + renderGallery(); + renderEditor(); + } + + function selectIndex(index) { + if (!confirmDirty()) return; + state.selected = index; + state.galleryPage = pageForIndex(index); + state.dirty = false; + render(); + } + + function galleryPageCount() { + return Math.ceil(state.filtered.length / effectiveGalleryPageSize()) || 0; + } + + function pageForIndex(index) { + if (index < 0) return 0; + return Math.floor(index / effectiveGalleryPageSize()); + } + + function changeGalleryPage(delta) { + goToGalleryPage(state.galleryPage + delta); + } + + function goToGalleryPage(page) { + const pages = galleryPageCount(); + if (!pages) return; + state.galleryPage = Math.min(Math.max(page, 0), pages - 1); + state.selected = state.galleryPage * effectiveGalleryPageSize(); + state.dirty = false; + render(); + } + + function setGalleryPageSize(value) { + if (value === "auto") { + updateAutoGalleryPageSize(); + const current = currentItem(); + state.galleryPageSize = "auto"; + localStorage.setItem(GALLERY_PAGE_SIZE_KEY, "auto"); + state.galleryPage = current ? pageForIndex(state.filtered.indexOf(current)) : 0; + render(); + return; + } + const nextSize = Number(value); + if (![12, 15, 20, 24, 30, 48].includes(nextSize)) return; + const current = currentItem(); + state.galleryPageSize = nextSize; + localStorage.setItem(GALLERY_PAGE_SIZE_KEY, String(nextSize)); + state.galleryPage = current ? pageForIndex(state.filtered.indexOf(current)) : 0; + render(); + } + + function toggleThumbnailFit() { + state.thumbnailFit = state.thumbnailFit === "cover" ? "contain" : "cover"; + localStorage.setItem(THUMBNAIL_FIT_KEY, state.thumbnailFit); + renderGallery(); + } + + function setSideTab(name) { + el.sideTabs.forEach((tab) => { + const active = tab.dataset.sideTab === name; + tab.classList.toggle("is-active", active); + tab.setAttribute("aria-selected", active ? "true" : "false"); + }); + Object.entries(el.sidePanels).forEach(([key, panel]) => { + if (panel) panel.classList.toggle("is-active", key === name); + }); + } + + async function refreshHistory() { + if (!state.root) { + state.canUndo = false; + state.canRedo = false; + state.changes = []; + renderHistory(); + renderEditor(); + return; + } + try { + const data = await api(API_HISTORY, { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ root: state.root }), + }); + state.canUndo = !!data.can_undo; + state.canRedo = !!data.can_redo; + state.changes = data.changes || []; + renderHistory(); + renderEditor(); + } catch (err) { + setStatus(err.message, true); + } + } + + async function scanDataset() { + const path = el.path.value.trim(); + if (!path) { + setStatus("请输入数据集目录。", true); + return; + } + setStatus("正在扫描数据集..."); + try { + const data = await api("/api/dataset-editor/scan", { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ path }), + }); + state.root = data.root; + state.items = data.items || []; + state.tags = data.tags || []; + state.categories = data.categories || []; + state.selectedPaths.clear(); + state.selectionMode = "manual"; + state.selected = state.items.length ? 0 : -1; + state.galleryPage = 0; + state.dirty = false; + el.path.value = state.root; + renderCategories(); + await refreshHistory(); + applyFilters(); + setStatus(`已加载 ${state.items.length} 张图片。`); + } catch (err) { + setStatus(err.message, true); + } + } + + async function pickFolder() { + try { + const data = await api("/api/pick_file?picker_type=folder"); + if (data.path) { + el.path.value = data.path; + await scanDataset(); + } + } catch (err) { + setStatus(err.message, true); + } + } + + async function saveCaption() { + const item = currentItem(); + if (!item) return; + try { + const data = await api("/api/dataset-editor/caption", { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ + root: state.root, + image: item.relative_path, + caption: el.caption.value, + }), + }); + item.caption = data.caption || ""; + item.tags = data.tags || []; + item.caption_exists = !!data.caption_exists; + state.dirty = false; + state.tags = buildTagCounts(); + setStatus("当前 caption 已保存。"); + await refreshHistory(); + applyFilters(); + } catch (err) { + setStatus(err.message, true); + } + } + + function applyChangedItems(items) { + const byPath = new Map((items || []).map((item) => [item.image, item])); + state.items.forEach((item) => { + const changed = byPath.get(item.relative_path); + if (changed) { + item.caption = changed.caption || ""; + item.tags = changed.tags || []; + item.caption_exists = !!changed.caption_exists; + } + }); + state.tags = buildTagCounts(); + pruneSelection(); + } + + function buildTagCounts() { + const counts = new Map(); + state.items.forEach((item) => { + (item.tags || []).forEach((tag) => counts.set(tag, (counts.get(tag) || 0) + 1)); + }); + return [...counts.entries()] + .sort((a, b) => a[0].localeCompare(b[0])) + .map(([tag, count]) => ({ tag, count })); + } + + async function undoEdit() { + await applyHistoryAction(API_UNDO, "撤回", "没有可撤回的已保存编辑。"); + } + + async function redoEdit() { + await applyHistoryAction(API_REDO, "重做", "没有可重做的编辑。"); + } + + async function applyHistoryAction(url, label, emptyMessage) { + if (!state.root) return; + if (state.dirty && !window.confirm(`当前输入框有未保存内容,${label}会刷新当前 caption,是否继续?`)) { + return; + } + try { + const data = await api(url, { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ root: state.root }), + }); + if (!data.changed) { + setStatus(emptyMessage); + await refreshHistory(); + return; + } + applyChangedItems(data.items || []); + state.dirty = false; + setStatus(`已${label}上一次操作,更新 ${data.changed} 个 caption。`); + await refreshHistory(); + applyFilters(); + } catch (err) { + setStatus(err.message, true); + } + } + + async function applyBatch() { + const targets = selectedBatchItems(); + if (!targets.length) return; + const replace = []; + if (el.replaceFrom.value.trim()) { + replace.push({ from: el.replaceFrom.value.trim(), to: el.replaceTo.value.trim() }); + } + const scope = state.selectedPaths.size ? "已选中" : "当前筛选结果中"; + const ok = window.confirm(`将修改${scope}的 ${targets.length} 张图片,是否继续?`); + if (!ok) return; + try { + const data = await api("/api/dataset-editor/batch", { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ + root: state.root, + images: targets.map((item) => item.relative_path), + append: splitTags(el.append.value), + remove: splitTags(el.remove.value), + replace, + sort: el.sort.checked, + }), + }); + applyChangedItems(data.items || []); + state.dirty = false; + setStatus(`批量编辑完成,修改 ${data.changed || 0} 张图片。`); + await refreshHistory(); + applyFilters(); + } catch (err) { + setStatus(err.message, true); + } + } + + async function applyCleanup() { + const targets = selectedBatchItems(); + if (!targets.length) return; + const scope = state.selectedPaths.size ? "已选中" : "当前筛选结果中"; + const ok = window.confirm(`将清理${scope}的 ${targets.length} 张图片,是否继续?`); + if (!ok) return; + try { + const data = await api("/api/dataset-editor/batch", { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ + root: state.root, + images: targets.map((item) => item.relative_path), + clean: el.cleanCaption.checked, + underscore_to_space: el.cleanUnderscore.checked, + strip_escape_chars: el.cleanEscape.checked, + sort: el.cleanSort.checked, + }), + }); + applyChangedItems(data.items || []); + state.dirty = false; + setStatus(`清理完成,修改 ${data.changed || 0} 张图片。`); + await refreshHistory(); + applyFilters(); + } catch (err) { + setStatus(err.message, true); + } + } + + function appendTagToCaption(tag) { + const item = currentItem(); + if (!item) return; + const tags = splitTags(el.caption.value); + if (!tags.some((item) => item.toLowerCase() === tag.toLowerCase())) { + tags.push(tag); + el.caption.value = tags.join(", "); + state.dirty = true; + renderEditor(); + } + } + + function addQuickTag() { + const tag = el.quickTagInput.value.trim(); + if (!tag) return; + state.quickTags = normalizeTagList([tag, ...state.quickTags]).slice(0, 24); + el.quickTagInput.value = ""; + saveQuickTags(); + renderQuickTags(); + appendTagToCaption(tag); + } + + el.scan.addEventListener("click", scanDataset); + el.pick.addEventListener("click", pickFolder); + el.search.addEventListener("input", applyFilters); + el.tagToggle.addEventListener("click", () => { + state.tagExpanded = !state.tagExpanded; + renderTags(); + }); + el.category.addEventListener("change", applyFilters); + el.include.addEventListener("input", applyFilters); + el.exclude.addEventListener("input", applyFilters); + el.caption.addEventListener("input", () => { + state.dirty = true; + renderEditor(); + }); + el.save.addEventListener("click", saveCaption); + el.undo.addEventListener("click", undoEdit); + el.redo.addEventListener("click", redoEdit); + el.galleryFirstPage.addEventListener("click", () => goToGalleryPage(0)); + el.galleryPrevPage.addEventListener("click", () => changeGalleryPage(-1)); + el.galleryPageSize.addEventListener("change", () => setGalleryPageSize(el.galleryPageSize.value)); + el.galleryNextPage.addEventListener("click", () => changeGalleryPage(1)); + el.galleryLastPage.addEventListener("click", () => goToGalleryPage(galleryPageCount() - 1)); + el.galleryPageInput.addEventListener("change", () => goToGalleryPage(Number(el.galleryPageInput.value) - 1)); + el.galleryPageInput.addEventListener("keydown", (event) => { + if (event.key === "Enter") goToGalleryPage(Number(el.galleryPageInput.value) - 1); + }); + el.thumbnailFit.addEventListener("click", toggleThumbnailFit); + el.selectPage.addEventListener("click", selectPageItems); + el.selectFiltered.addEventListener("click", selectFilteredItems); + el.selectAll.addEventListener("click", selectAllItems); + el.clearSelection.addEventListener("click", clearSelection); + el.sideTabs.forEach((tab) => tab.addEventListener("click", () => setSideTab(tab.dataset.sideTab))); + if (typeof ResizeObserver !== "undefined") { + new ResizeObserver(() => { + const previous = state.autoGalleryPageSize; + updateAutoGalleryPageSize(); + if (state.galleryPageSize === "auto" && previous !== state.autoGalleryPageSize) { + state.galleryPage = Math.min(state.galleryPage, Math.max(0, galleryPageCount() - 1)); + render(); + } + }).observe(el.gallery); + } + window.addEventListener("resize", () => { + const previous = state.autoGalleryPageSize; + updateAutoGalleryPageSize(); + if (state.galleryPageSize === "auto" && previous !== state.autoGalleryPageSize) { + state.galleryPage = Math.min(state.galleryPage, Math.max(0, galleryPageCount() - 1)); + render(); + } + }); + el.prev.addEventListener("click", () => selectIndex(state.selected - 1)); + el.next.addEventListener("click", () => selectIndex(state.selected + 1)); + el.batch.addEventListener("click", applyBatch); + el.cleanup.addEventListener("click", applyCleanup); + el.quickTagAdd.addEventListener("click", addQuickTag); + el.quickTagInput.addEventListener("keydown", (event) => { + if (event.key === "Enter") { + event.preventDefault(); + addQuickTag(); + } + }); + document.addEventListener("keydown", (event) => { + const key = event.key.toLowerCase(); + if ((event.ctrlKey || event.metaKey) && !event.shiftKey && key === "z") { + event.preventDefault(); + undoEdit(); + setStatus("Ctrl+Z: 正在撤回上一条已保存编辑。"); + } + if ((event.ctrlKey || event.metaKey) && (key === "y" || (event.shiftKey && key === "z"))) { + event.preventDefault(); + redoEdit(); + setStatus("正在重做上一条撤回编辑。"); + } + }); + + renderCategories(); + updateAutoGalleryPageSize(); + render(); +})(); diff --git a/frontend/dist/dataset-editor.html b/frontend/dist/dataset-editor.html new file mode 100644 index 00000000..c18111d0 --- /dev/null +++ b/frontend/dist/dataset-editor.html @@ -0,0 +1,180 @@ + + + + + + + + 数据集标签编辑器 | SD Trainer Next + + + +
+
+ SD Trainer Next + +
+ +
+ + + + + +
+
+ + + diff --git a/frontend/dist/tageditor.html b/frontend/dist/tageditor.html index 6b6886b9..2d242c5a 100644 --- a/frontend/dist/tageditor.html +++ b/frontend/dist/tageditor.html @@ -28,11 +28,14 @@ SD 训练 UI + +
+ diff --git a/gui.py b/gui.py index 5197f336..7626875f 100644 --- a/gui.py +++ b/gui.py @@ -18,6 +18,11 @@ parser.add_argument("--skip-prepare-onnxruntime", action="store_true") parser.add_argument("--disable-tensorboard", action="store_true", default=False) parser.add_argument("--disable-tageditor", action="store_true") +parser.add_argument( + "--enable-legacy-tageditor", + action="store_true", + help="Start the legacy Gradio Dataset Tag Editor compatibility service.", +) parser.add_argument("--disable-train-monitor", action="store_true") parser.add_argument("--disable-auto-mirror", action="store_true") parser.add_argument("--tensorboard-host", type=str, default="127.0.0.1", help="Port to run the tensorboard") @@ -119,6 +124,7 @@ def launch(): log.info("Starting SD-Trainer Mikazuki GUI...") log.info(f"Base directory: {base_dir_path()}, Working directory: {os.getcwd()}") log.info(f"{platform.system()} Python {platform.python_version()} {sys.executable}") + legacy_tageditor_enabled = args.enable_legacy_tageditor and not args.disable_tageditor if not args.skip_prepare_environment: prepare_environment(disable_auto_mirror=args.disable_auto_mirror) @@ -126,7 +132,7 @@ def launch(): # Protect each service's default port before scanning fallbacks. Otherwise # TensorBoard can claim 6008 as a fallback and make monitor links open it. protected_default_ports = {args.port} - if not args.disable_tageditor: + if legacy_tageditor_enabled: protected_default_ports.add(28001) if not args.disable_tensorboard: protected_default_ports.add(args.tensorboard_port) @@ -135,7 +141,7 @@ def launch(): reserved_ports: set[int] = set(protected_default_ports) tageditor_port = 28001 - if not args.disable_tageditor: + if legacy_tageditor_enabled: tageditor_port = ensure_port_available( 28001, 28001, 28020, "Tag editor", reserved_ports, preferred_reserved_port=28001 ) @@ -178,8 +184,10 @@ def launch(): args.host = "0.0.0.0" args.tensorboard_host = "0.0.0.0" - if not args.disable_tageditor: + if legacy_tageditor_enabled: run_tag_editor(tageditor_port) + else: + log.info("Using native dataset editor at /dataset-editor.html; legacy Gradio tag editor is disabled.") if not args.disable_tensorboard: run_tensorboard() diff --git a/mikazuki/app/api.py b/mikazuki/app/api.py index 405a0bac..f3668fea 100644 --- a/mikazuki/app/api.py +++ b/mikazuki/app/api.py @@ -22,6 +22,7 @@ from mikazuki.app.models import (APIResponse, APIResponseFail, APIResponseSuccess, TaggerInterrogateRequest, TaggerPrefetchRequest) +from mikazuki.dataset_editor import router as dataset_editor_router from mikazuki.log import log from mikazuki.tagger.interrogator import available_interrogators from mikazuki.tagger.jobs import run_interrogate_job, run_prefetch_job @@ -36,6 +37,7 @@ tkinter_available) router = APIRouter() +router.include_router(dataset_editor_router) ANIMA_TRAIN_TYPES = {"anima-lora", "sd3-lora", "anima-finetune"} ANIMA_FINETUNE_TYPE = "anima-finetune" diff --git a/mikazuki/app/application.py b/mikazuki/app/application.py index 76b929d1..c2fd8284 100644 --- a/mikazuki/app/application.py +++ b/mikazuki/app/application.py @@ -154,8 +154,13 @@ async def redirect_vuepress_md_to_html(request, call_next): async def add_cache_control_header(request, call_next): response = await call_next(request) path = request.url.path - if path.endswith(".html") or path.endswith("/assets/tagger-progress.js") or path.endswith( - "/assets/sd-trainer-brand.js" + if ( + path.endswith(".html") + or path.endswith("/assets/tagger-progress.js") + or path.endswith("/assets/sd-trainer-brand.js") + or path.endswith("/assets/dataset-editor.js") + or path.endswith("/assets/dataset-editor.css") + or path.endswith("/assets/dataset-editor-entry.js") ): response.headers["Cache-Control"] = "no-cache, must-revalidate" elif re.search(r"\.[a-f0-9]{8}\.(js|css|webp)$", path): diff --git a/mikazuki/dataset_editor.py b/mikazuki/dataset_editor.py new file mode 100644 index 00000000..945f80ab --- /dev/null +++ b/mikazuki/dataset_editor.py @@ -0,0 +1,381 @@ +from __future__ import annotations + +from collections import Counter +from dataclasses import dataclass +from pathlib import Path +from urllib.parse import urlencode + +from fastapi import APIRouter, HTTPException +from fastapi.responses import FileResponse +from pydantic import BaseModel, Field + +from mikazuki.app.models import APIResponseSuccess + + +IMAGE_EXTENSIONS = {".png", ".jpg", ".jpeg", ".webp", ".bmp"} + +router = APIRouter() +_UNDO_STACKS: dict[str, list["EditTransaction"]] = {} +_REDO_STACKS: dict[str, list["EditTransaction"]] = {} + + +@dataclass +class CaptionSnapshot: + image: str + caption: str + caption_exists: bool + + +@dataclass +class EditTransaction: + label: str + before: list[CaptionSnapshot] + after: list[CaptionSnapshot] + + +class DatasetScanRequest(BaseModel): + path: str + + +class CaptionWriteRequest(BaseModel): + root: str + image: str + caption: str = "" + + +class TagReplacement(BaseModel): + source: str = Field(alias="from") + target: str = Field(alias="to") + + +class BatchEditRequest(BaseModel): + root: str + images: list[str] + append: list[str] = [] + remove: list[str] = [] + replace: list[TagReplacement] = [] + sort: bool = False + clean: bool = False + underscore_to_space: bool = False + strip_escape_chars: bool = False + + +class UndoRequest(BaseModel): + root: str + + +def normalize_path(path: str) -> str: + return str(Path(path).resolve()).replace("\\", "/") + + +def normalize_relative_path(path: str | Path) -> str: + return str(path).replace("\\", "/") + + +def parse_tags(caption: str) -> list[str]: + tags = [] + seen = set() + for raw in caption.split(","): + tag = raw.strip() + if not tag or tag in seen: + continue + seen.add(tag) + tags.append(tag) + return tags + + +def normalize_caption_for_cleanup(caption: str, underscore_to_space: bool = False, strip_escape_chars: bool = False) -> list[str]: + normalized = ( + caption.replace(",", ",") + .replace(";", ",") + .replace(";", ",") + .replace("\r", ",") + .replace("\n", ",") + ) + tags = [] + seen = set() + for tag in parse_tags(normalized): + if strip_escape_chars: + tag = tag.replace("\\(", "(").replace("\\)", ")").replace("\\[", "[").replace("\\]", "]") + if underscore_to_space: + tag = tag.replace("_", " ") + tag = " ".join(tag.split()) + if not tag or tag in seen: + continue + seen.add(tag) + tags.append(tag) + return tags + + +def format_tags(tags: list[str]) -> str: + return ", ".join(tags) + + +def dataset_root(path: str) -> Path: + root = Path(path).expanduser().resolve() + if not root.is_dir(): + raise HTTPException(status_code=400, detail="dataset path is not a directory") + return root + + +def resolve_image(root: Path, image: str) -> Path: + image_path = (root / image).resolve() + try: + image_path.relative_to(root) + except ValueError as exc: + raise HTTPException(status_code=400, detail="image path is outside dataset root") from exc + if image_path.suffix.lower() not in IMAGE_EXTENSIONS: + raise HTTPException(status_code=400, detail="unsupported image file") + return image_path + + +def caption_path_for(image_path: Path) -> Path: + return image_path.with_suffix(".txt") + + +def read_caption(image_path: Path) -> str: + caption_path = caption_path_for(image_path) + if not caption_path.is_file(): + return "" + return caption_path.read_text(encoding="utf-8").strip() + + +def capture_caption(root: Path, image_path: Path) -> CaptionSnapshot: + caption_path = caption_path_for(image_path) + return CaptionSnapshot( + image=normalize_relative_path(image_path.relative_to(root)), + caption=read_caption(image_path), + caption_exists=caption_path.is_file(), + ) + + +def remember_edit(root: Path, label: str, before: list[CaptionSnapshot], after: list[CaptionSnapshot]) -> None: + if not before: + return + key = normalize_path(str(root)) + _UNDO_STACKS.setdefault(key, []).append(EditTransaction(label=label, before=before, after=after)) + _REDO_STACKS[key] = [] + + +def restore_caption(root: Path, snapshot: CaptionSnapshot) -> dict: + image_path = resolve_image(root, snapshot.image) + caption_path = caption_path_for(image_path) + if snapshot.caption_exists: + write_caption(image_path, snapshot.caption) + elif caption_path.exists(): + caption_path.unlink() + caption = read_caption(image_path) + return { + "image": snapshot.image, + "caption": caption, + "caption_exists": caption_path.is_file(), + "tags": parse_tags(caption), + } + + +def snapshot_to_item(snapshot: CaptionSnapshot) -> dict: + return { + "image": snapshot.image, + "caption": snapshot.caption, + "caption_exists": snapshot.caption_exists, + "tags": parse_tags(snapshot.caption), + } + + +def transaction_to_change(tx: EditTransaction) -> dict: + after_by_image = {item.image: item for item in tx.after} + items = [] + for before in tx.before: + after = after_by_image.get(before.image) + items.append( + { + "image": before.image, + "before": before.caption if before.caption_exists else "", + "after": after.caption if after and after.caption_exists else "", + "before_exists": before.caption_exists, + "after_exists": bool(after and after.caption_exists), + } + ) + return {"label": tx.label, "count": len(items), "items": items} + + +def category_for(root: Path, image_path: Path) -> str: + rel = image_path.relative_to(root) + if len(rel.parts) <= 1: + return "" + return rel.parts[0] + + +def write_caption(image_path: Path, caption: str) -> str: + normalized = caption.strip() + caption_path_for(image_path).write_text(normalized, encoding="utf-8") + return normalized + + +def scan_dataset(root: Path) -> dict: + items = [] + tag_counts: Counter[str] = Counter() + category_counts: Counter[str] = Counter() + for image_path in sorted(root.rglob("*"), key=lambda p: normalize_path(str(p))): + if not image_path.is_file() or image_path.suffix.lower() not in IMAGE_EXTENSIONS: + continue + rel = normalize_relative_path(image_path.relative_to(root)) + category = category_for(root, image_path) + caption = read_caption(image_path) + tags = parse_tags(caption) + tag_counts.update(tags) + category_counts.update([category]) + caption_path = caption_path_for(image_path) + image_query = urlencode({"root": normalize_path(str(root)), "image": rel}) + items.append( + { + "name": image_path.name, + "relative_path": rel, + "category": category, + "caption": caption, + "caption_exists": caption_path.is_file(), + "tags": tags, + "image_url": f"/api/dataset-editor/image?{image_query}", + } + ) + return { + "root": normalize_path(str(root)), + "total": len(items), + "items": items, + "tags": [{"tag": tag, "count": count} for tag, count in sorted(tag_counts.items())], + "categories": [ + {"name": category or "根目录", "value": category, "count": count} + for category, count in sorted(category_counts.items()) + ], + } + + +@router.post("/dataset-editor/scan") +async def scan(req: DatasetScanRequest): + return APIResponseSuccess(data=scan_dataset(dataset_root(req.path))) + + +@router.get("/dataset-editor/image") +async def image(root: str, image: str): + image_path = resolve_image(dataset_root(root), image) + if not image_path.is_file(): + raise HTTPException(status_code=404, detail="image not found") + return FileResponse(str(image_path)) + + +@router.post("/dataset-editor/caption") +async def save_caption(req: CaptionWriteRequest): + root = dataset_root(req.root) + image_path = resolve_image(root, req.image) + if not image_path.is_file(): + raise HTTPException(status_code=404, detail="image not found") + before = capture_caption(root, image_path) + caption = write_caption(image_path, req.caption) + if before.caption != caption or not before.caption_exists: + remember_edit(root, "保存当前 caption", [before], [capture_caption(root, image_path)]) + return APIResponseSuccess( + data={ + "image": normalize_relative_path(image_path.relative_to(root)), + "caption": caption, + "caption_exists": caption_path_for(image_path).is_file(), + "tags": parse_tags(caption), + } + ) + + +@router.post("/dataset-editor/batch") +async def batch_edit(req: BatchEditRequest): + root = dataset_root(req.root) + append_tags = parse_tags(",".join(req.append)) + remove_tags = set(parse_tags(",".join(req.remove))) + replacements = {item.source.strip(): item.target.strip() for item in req.replace if item.source.strip()} + changed = 0 + results = [] + before_snapshots = [] + after_snapshots = [] + + for rel in req.images: + image_path = resolve_image(root, rel) + if not image_path.is_file(): + continue + tags = ( + normalize_caption_for_cleanup( + read_caption(image_path), + underscore_to_space=req.underscore_to_space, + strip_escape_chars=req.strip_escape_chars, + ) + if req.clean + else parse_tags(read_caption(image_path)) + ) + next_tags = [] + for tag in tags: + if tag in remove_tags: + continue + tag = replacements.get(tag, tag) + if tag and tag not in next_tags: + next_tags.append(tag) + for tag in append_tags: + if tag not in next_tags: + next_tags.append(tag) + if req.sort: + next_tags = sorted(next_tags) + next_caption = format_tags(next_tags) + if next_caption != read_caption(image_path): + before_snapshots.append(capture_caption(root, image_path)) + write_caption(image_path, next_caption) + after_snapshots.append(capture_caption(root, image_path)) + changed += 1 + results.append( + { + "image": normalize_relative_path(image_path.relative_to(root)), + "caption": next_caption, + "caption_exists": caption_path_for(image_path).is_file(), + "tags": next_tags, + } + ) + + remember_edit(root, "批量编辑 caption", before_snapshots, after_snapshots) + return APIResponseSuccess(data={"changed": changed, "items": results}) + + +@router.post("/dataset-editor/undo") +async def undo(req: UndoRequest): + root = dataset_root(req.root) + stack = _UNDO_STACKS.get(normalize_path(str(root)), []) + if not stack: + return APIResponseSuccess(data={"changed": 0, "items": []}, message="nothing to undo") + + tx = stack.pop() + _REDO_STACKS.setdefault(normalize_path(str(root)), []).append(tx) + items = [restore_caption(root, snapshot) for snapshot in tx.before] + return APIResponseSuccess(data={"changed": len(items), "items": items}) + + +@router.post("/dataset-editor/redo") +async def redo(req: UndoRequest): + root = dataset_root(req.root) + key = normalize_path(str(root)) + stack = _REDO_STACKS.get(key, []) + if not stack: + return APIResponseSuccess(data={"changed": 0, "items": []}, message="nothing to redo") + + tx = stack.pop() + _UNDO_STACKS.setdefault(key, []).append(tx) + items = [restore_caption(root, snapshot) for snapshot in tx.after] + return APIResponseSuccess(data={"changed": len(items), "items": items}) + + +@router.post("/dataset-editor/history") +async def history(req: UndoRequest): + root = dataset_root(req.root) + key = normalize_path(str(root)) + undo_stack = _UNDO_STACKS.get(key, []) + redo_stack = _REDO_STACKS.get(key, []) + changes = [transaction_to_change(tx) for tx in reversed(undo_stack[-20:])] + return APIResponseSuccess( + data={ + "can_undo": bool(undo_stack), + "can_redo": bool(redo_stack), + "changes": changes, + } + ) diff --git a/tests/test_dataset_editor_api.py b/tests/test_dataset_editor_api.py new file mode 100644 index 00000000..3433e10e --- /dev/null +++ b/tests/test_dataset_editor_api.py @@ -0,0 +1,491 @@ +from pathlib import Path + +from fastapi.testclient import TestClient +from PIL import Image + +from mikazuki.app.application import app + + +ROOT = Path(__file__).resolve().parents[1] + + +def make_image(path: Path, color=(220, 80, 80)): + image = Image.new("RGB", (24, 18), color) + image.save(path) + + +def test_dataset_editor_scan_lists_images_and_captions(tmp_path): + make_image(tmp_path / "alpha.png") + (tmp_path / "alpha.txt").write_text("1girl, solo", encoding="utf-8") + make_image(tmp_path / "beta.jpg", color=(80, 120, 220)) + + client = TestClient(app) + response = client.post("/api/dataset-editor/scan", json={"path": str(tmp_path)}) + + assert response.status_code == 200 + payload = response.json() + assert payload["status"] == "success" + assert payload["data"]["root"] == str(tmp_path.resolve()).replace("\\", "/") + assert payload["data"]["total"] == 2 + assert payload["data"]["tags"] == [{"tag": "1girl", "count": 1}, {"tag": "solo", "count": 1}] + assert payload["data"]["categories"] == [{"name": "根目录", "value": "", "count": 2}] + + first = payload["data"]["items"][0] + assert first["name"] == "alpha.png" + assert first["caption"] == "1girl, solo" + assert first["tags"] == ["1girl", "solo"] + assert first["caption_exists"] is True + assert first["image_url"].startswith("/api/dataset-editor/image?") + assert "root=" in first["image_url"] + assert "image=alpha.png" in first["image_url"] + + second = payload["data"]["items"][1] + assert second["name"] == "beta.jpg" + assert second["caption"] == "" + assert second["caption_exists"] is False + + +def test_dataset_editor_scan_groups_first_level_subfolders(tmp_path): + char_dir = tmp_path / "10_character" + style_dir = tmp_path / "20_style" + char_dir.mkdir() + style_dir.mkdir() + make_image(char_dir / "alpha.png") + make_image(style_dir / "beta.png") + + client = TestClient(app) + response = client.post("/api/dataset-editor/scan", json={"path": str(tmp_path)}) + + assert response.status_code == 200 + data = response.json()["data"] + assert data["categories"] == [ + {"name": "10_character", "value": "10_character", "count": 1}, + {"name": "20_style", "value": "20_style", "count": 1}, + ] + assert data["items"][0]["category"] == "10_character" + assert data["items"][1]["category"] == "20_style" + + +def test_dataset_editor_save_caption_creates_txt_caption(tmp_path): + make_image(tmp_path / "alpha.png") + + client = TestClient(app) + response = client.post( + "/api/dataset-editor/caption", + json={"root": str(tmp_path), "image": "alpha.png", "caption": "cat ears, smile"}, + ) + + assert response.status_code == 200 + payload = response.json() + assert payload["status"] == "success" + assert payload["data"]["caption"] == "cat ears, smile" + assert (tmp_path / "alpha.txt").read_text(encoding="utf-8") == "cat ears, smile" + + +def test_dataset_editor_batch_replace_remove_append_and_sort(tmp_path): + make_image(tmp_path / "alpha.png") + make_image(tmp_path / "beta.png") + (tmp_path / "alpha.txt").write_text("solo, 1girl, old tag", encoding="utf-8") + (tmp_path / "beta.txt").write_text("solo, blue eyes", encoding="utf-8") + + client = TestClient(app) + response = client.post( + "/api/dataset-editor/batch", + json={ + "root": str(tmp_path), + "images": ["alpha.png", "beta.png"], + "append": ["masterpiece"], + "remove": ["solo"], + "replace": [{"from": "old tag", "to": "new tag"}], + "sort": True, + }, + ) + + assert response.status_code == 200 + payload = response.json() + assert payload["status"] == "success" + assert payload["data"]["changed"] == 2 + assert (tmp_path / "alpha.txt").read_text(encoding="utf-8") == "1girl, masterpiece, new tag" + assert (tmp_path / "beta.txt").read_text(encoding="utf-8") == "blue eyes, masterpiece" + + +def test_dataset_editor_batch_cleans_obvious_caption_noise(tmp_path): + make_image(tmp_path / "alpha.png") + (tmp_path / "alpha.txt").write_text( + "white_background, 1girl, 1girl; basketball \\(object\\)\nsolo", + encoding="utf-8", + ) + + client = TestClient(app) + response = client.post( + "/api/dataset-editor/batch", + json={ + "root": str(tmp_path), + "images": ["alpha.png"], + "clean": True, + "underscore_to_space": True, + "strip_escape_chars": True, + }, + ) + + assert response.status_code == 200 + assert response.json()["data"]["changed"] == 1 + assert (tmp_path / "alpha.txt").read_text(encoding="utf-8") == ( + "white background, 1girl, basketball (object), solo" + ) + + +def test_dataset_editor_undo_restores_single_caption_edit(tmp_path): + make_image(tmp_path / "alpha.png") + (tmp_path / "alpha.txt").write_text("original tag", encoding="utf-8") + + client = TestClient(app) + save = client.post( + "/api/dataset-editor/caption", + json={"root": str(tmp_path), "image": "alpha.png", "caption": "changed tag"}, + ) + assert save.status_code == 200 + assert (tmp_path / "alpha.txt").read_text(encoding="utf-8") == "changed tag" + + undo = client.post("/api/dataset-editor/undo", json={"root": str(tmp_path)}) + + assert undo.status_code == 200 + payload = undo.json() + assert payload["status"] == "success" + assert payload["data"]["changed"] == 1 + assert payload["data"]["items"][0]["caption"] == "original tag" + assert (tmp_path / "alpha.txt").read_text(encoding="utf-8") == "original tag" + + +def test_dataset_editor_redo_reapplies_undone_caption_edit(tmp_path): + make_image(tmp_path / "alpha.png") + (tmp_path / "alpha.txt").write_text("original tag", encoding="utf-8") + + client = TestClient(app) + client.post( + "/api/dataset-editor/caption", + json={"root": str(tmp_path), "image": "alpha.png", "caption": "changed tag"}, + ) + client.post("/api/dataset-editor/undo", json={"root": str(tmp_path)}) + + redo = client.post("/api/dataset-editor/redo", json={"root": str(tmp_path)}) + + assert redo.status_code == 200 + payload = redo.json() + assert payload["status"] == "success" + assert payload["data"]["changed"] == 1 + assert payload["data"]["items"][0]["caption"] == "changed tag" + assert (tmp_path / "alpha.txt").read_text(encoding="utf-8") == "changed tag" + + +def test_dataset_editor_history_lists_saved_transactions(tmp_path): + make_image(tmp_path / "alpha.png") + (tmp_path / "alpha.txt").write_text("before", encoding="utf-8") + + client = TestClient(app) + client.post( + "/api/dataset-editor/caption", + json={"root": str(tmp_path), "image": "alpha.png", "caption": "after"}, + ) + + history = client.post("/api/dataset-editor/history", json={"root": str(tmp_path)}) + + assert history.status_code == 200 + data = history.json()["data"] + assert data["can_undo"] is True + assert data["can_redo"] is False + assert data["changes"][0]["label"] == "保存当前 caption" + assert data["changes"][0]["items"][0]["before"] == "before" + assert data["changes"][0]["items"][0]["after"] == "after" + + +def test_dataset_editor_undo_restores_missing_caption_after_create(tmp_path): + make_image(tmp_path / "alpha.png") + + client = TestClient(app) + client.post( + "/api/dataset-editor/caption", + json={"root": str(tmp_path), "image": "alpha.png", "caption": "new tag"}, + ) + assert (tmp_path / "alpha.txt").is_file() + + undo = client.post("/api/dataset-editor/undo", json={"root": str(tmp_path)}) + + assert undo.status_code == 200 + assert undo.json()["data"]["items"][0]["caption_exists"] is False + assert not (tmp_path / "alpha.txt").exists() + + +def test_dataset_editor_undo_restores_batch_edit(tmp_path): + make_image(tmp_path / "alpha.png") + make_image(tmp_path / "beta.png") + (tmp_path / "alpha.txt").write_text("solo, 1girl", encoding="utf-8") + (tmp_path / "beta.txt").write_text("solo, blue eyes", encoding="utf-8") + + client = TestClient(app) + client.post( + "/api/dataset-editor/batch", + json={ + "root": str(tmp_path), + "images": ["alpha.png", "beta.png"], + "append": ["masterpiece"], + "remove": ["solo"], + "replace": [], + "sort": False, + }, + ) + + undo = client.post("/api/dataset-editor/undo", json={"root": str(tmp_path)}) + + assert undo.status_code == 200 + assert undo.json()["data"]["changed"] == 2 + assert (tmp_path / "alpha.txt").read_text(encoding="utf-8") == "solo, 1girl" + assert (tmp_path / "beta.txt").read_text(encoding="utf-8") == "solo, blue eyes" + + +def test_dataset_editor_rejects_path_escape(tmp_path): + make_image(tmp_path / "alpha.png") + outside = tmp_path.parent / "outside.png" + make_image(outside) + + client = TestClient(app) + response = client.post( + "/api/dataset-editor/caption", + json={"root": str(tmp_path), "image": "../outside.png", "caption": "bad"}, + ) + + assert response.status_code == 400 + assert "outside dataset" in response.json()["detail"] + + +def test_dataset_editor_html_is_served_from_main_webui(): + client = TestClient(app) + response = client.get("/dataset-editor.html") + + assert response.status_code == 200 + assert "dataset-editor.js" in response.text + assert "旧版兼容" in response.text + assert 'id="undo-edit"' in response.text + assert 'id="redo-edit"' in response.text + assert 'id="category-filter"' in response.text + assert 'id="quick-tags"' in response.text + assert 'id="tag-toggle"' in response.text + assert 'id="side-tab-filter"' in response.text + assert 'id="side-tab-quick"' in response.text + assert 'id="side-tab-batch"' in response.text + assert 'id="side-tab-clean"' in response.text + assert 'id="apply-cleanup"' in response.text + assert 'id="gallery-first-page"' in response.text + assert 'id="gallery-prev-page"' in response.text + assert 'id="gallery-page-input"' in response.text + assert 'id="gallery-page-size"' in response.text + assert 'value="auto"' in response.text + assert 'id="gallery-next-page"' in response.text + assert 'id="gallery-last-page"' in response.text + assert 'id="thumbnail-fit"' in response.text + assert 'id="change-list"' in response.text + assert 'id="side-tab-tagger"' in response.text + assert 'id="side-panel-tagger"' in response.text + assert " Date: Sat, 30 May 2026 00:37:36 +0800 Subject: [PATCH 2/8] Add native tag editor branch handoff --- agent_allinone.md | 123 ++++++++ build-scripts/03-copy-project.ps1 | 4 + build-scripts/build_portable.ps1 | 20 +- docs/api/dataset-tagging.md | 17 + docs/portable-packaging-git-update.md | 6 + frontend/dist/404.html | 5 +- frontend/dist/assets/app.547295de.js | 8 +- frontend/dist/assets/dataset-editor-entry.js | 87 +++++- frontend/dist/assets/dataset-editor.css | 291 ++++++++++++++++-- frontend/dist/assets/dataset-editor.js | 88 ++++++ frontend/dist/assets/sd-nav-i18n.js | 25 +- .../dist/assets/settings.html.06993f96.js | 2 +- frontend/dist/dataset-editor.html | 67 +++- frontend/dist/dreambooth/index.html | 4 +- frontend/dist/help/guide.html | 4 +- frontend/dist/index.html | 11 +- frontend/dist/lora/anima-finetune.html | 4 +- frontend/dist/lora/basic.html | 4 +- frontend/dist/lora/flux.html | 4 +- frontend/dist/lora/index.html | 4 +- frontend/dist/lora/master.html | 4 +- frontend/dist/lora/params.html | 4 +- frontend/dist/lora/sd3.html | 4 +- frontend/dist/lora/sdxl.html | 4 +- frontend/dist/lora/tools.html | 4 +- frontend/dist/native-tageditor.html | 43 +++ frontend/dist/other/about.html | 4 +- frontend/dist/other/changelog.html | 4 +- frontend/dist/other/settings.html | 12 +- frontend/dist/tageditor.html | 13 +- frontend/dist/tagger.html | 4 +- frontend/dist/task.html | 4 +- frontend/dist/tensorboard.html | 4 +- install-cn.ps1 | 3 +- mikazuki/app/application.py | 3 + mikazuki/dataset_editor.py | 189 ++++++++++++ mikazuki/tagger/interrogators/cl.py | 8 +- mikazuki/tagger/interrogators/wd14.py | 6 + mikazuki/tagger/jobs.py | 4 +- mikazuki/tagger/local_models.py | 61 ++++ mikazuki/tagger/model_fetch.py | 19 +- scripts/portable/README.md | 14 +- scripts/portable/launch_portable.bat | 3 +- scripts/prefetch_default_tagger.py | 53 +++- tests/test_dataset_editor_api.py | 271 +++++++++++++++- tests/test_portable_packaging_scripts.py | 15 + tests/test_tagger_progress_api.py | 55 ++++ 47 files changed, 1480 insertions(+), 110 deletions(-) create mode 100644 agent_allinone.md create mode 100644 frontend/dist/native-tageditor.html create mode 100644 mikazuki/tagger/local_models.py diff --git a/agent_allinone.md b/agent_allinone.md new file mode 100644 index 00000000..ea73915e --- /dev/null +++ b/agent_allinone.md @@ -0,0 +1,123 @@ +# Agent All-in-One Handoff: Native Tag Editor + +## Project + +Repository: `D:\ai\lora-scripts-next` + +Active branch for this work: `editor` + +This branch is intentionally separate from `main` because the native tag editor UI touches the trainer WebUI shell and can regress navigation, caching, and route behavior. + +## Must Read First + +Read these files before making changes: + +- `doc/local/AGENT_INTERNAL.md` +- `doc/local/HANDOFF_DATASET_EDITOR_2026-05-29.md` +- `.cursor/rules/00-project-overview.mdc` +- `.cursor/rules/embedded-service-ports.mdc` +- `docs/repo-layout.md` +- `docs/portable-packaging-git-update.md` +- `docs/team/risk-memo.md` +- `docs/team/backlog-priorities.md` + +## Hard Constraints + +- Do not push this UI work directly to `main`. +- Do not run npm build for the current frontend work. Edit `frontend/dist/` directly. +- Do not change portable contract directory names or the portable launch chain unless explicitly requested. +- Do not delete or commit local HuggingFace lock files under `huggingface/hub/.locks/`. +- Old Gradio tag editor must remain opt-in only through `--enable-legacy-tageditor`. +- `/dataset-editor.html` is the standalone native editor fallback/debug page. +- `/native-tageditor.html` is the native editor embedded in the trainer shell. +- `/tageditor.html` is the classic/legacy tag editor page. +- Keep changes scoped to dataset/tag editor integration unless the user explicitly asks otherwise. + +## Current Dev Server + +Common command: + +```powershell +python gui.py --dev --skip-prepare-environment --disable-tensorboard --disable-train-monitor --port 28182 +``` + +Useful URLs: + +- `http://127.0.0.1:28182/tagger.html` +- `http://127.0.0.1:28182/tageditor.html` +- `http://127.0.0.1:28182/native-tageditor.html` +- `http://127.0.0.1:28182/dataset-editor.html` +- `http://127.0.0.1:28182/other/settings.html` + +## What This Branch Contains + +- Native dataset/tag editor backend API in `mikazuki/dataset_editor.py`. +- Native editor frontend in `frontend/dist/dataset-editor.html` and `frontend/dist/assets/dataset-editor.*`. +- Trainer-embedded native editor entry in `frontend/dist/assets/dataset-editor-entry.js`. +- Separate navigation entries: + - Classic Tag Editor: `经典标签编辑`, `/tageditor.md` + - Native Tag Editor: `原生标签编辑`, `/native-tageditor.html` +- Dataset editor tagging controls for local/API tagging, tag/natural-language caption mode, model selection, conflict handling, and settings integration. +- Local tagger model storage helpers in `mikazuki/tagger/local_models.py`. +- Preferred local tagger model layout: + - `tagger-models/wd14//` + - `tagger-models/vlm//` + - Legacy flat `tagger-models//` remains compatible. +- Portable packaging updates to create/copy the tagger model directories. +- Cache-control workaround in `mikazuki/app/application.py` for patched dist core assets. +- Regression tests for route/sidebar JSON parsing and Chinese nav labels. + +## Important Recent Bug + +The VuePress app bundle `frontend/dist/assets/app.547295de.js` contains theme sidebar data as: + +```js +const WE=JSON.parse(`...`) +``` + +Manual edits previously broke this JSON and then corrupted Chinese menu text. The current fix stores that JSON with ASCII-only `\uXXXX` escapes so runtime text still renders Chinese while file writes are less likely to corrupt encoding. + +If navigation becomes 404-like, stuck on `Loading...`, or shows mojibake, first inspect and parse this `WE=JSON.parse(...)` block. + +Relevant test: + +```powershell +python -m pytest tests\test_dataset_editor_api.py::test_vuepress_theme_sidebar_json_stays_parseable -q +``` + +## Verification Commands + +Run before claiming the branch is healthy: + +```powershell +python -m pytest tests\test_dataset_editor_api.py tests\test_tagger_progress_api.py tests\test_portable_packaging_scripts.py -q +``` + +Last known result before this handoff: + +```text +47 passed, 4 warnings +``` + +Browser smoke checks: + +- Open `/tagger.html`, confirm no 404 and sidebar Chinese is readable. +- Open `/native-tageditor.html`, confirm it uses the trainer shell and native editor. +- Open `/dataset-editor.html`, confirm standalone fallback still loads. +- Open `/other/settings.html`, confirm tagger API settings are present. + +## Known Local Noise + +Do not commit these runtime files: + +- `huggingface/hub/.locks/models--SmilingWolf--wd-convnext-tagger-v3/*.lock` +- `huggingface/hub/.locks/models--SmilingWolf--wd-v1-4-moat-tagger-v2/*.lock` + +## Suggested Next Work + +1. Continue visual QA of `/native-tageditor.html` in the trainer shell. +2. Use a real dataset to test scan, thumbnails, selection, batch tagging, save, undo, and redo. +3. Improve native editor UI carefully, one small change at a time, with browser checks after each change. +4. Keep the classic editor and native editor separate in navigation. +5. Avoid broad frontend shell rewrites until the current editor flow is stable. + diff --git a/build-scripts/03-copy-project.ps1 b/build-scripts/03-copy-project.ps1 index d6ff681d..23c1ada2 100644 --- a/build-scripts/03-copy-project.ps1 +++ b/build-scripts/03-copy-project.ps1 @@ -31,6 +31,7 @@ $excludeDirs = @( "logs", "output", "huggingface", + "tagger-models", "sd-models", "wd14_tagger_model", "train", @@ -58,6 +59,9 @@ New-Item -ItemType Directory -Path (Join-Path $BuildDir "sd-models") -Force | Ou New-Item -ItemType Directory -Path (Join-Path $BuildDir "output") -Force | Out-Null New-Item -ItemType Directory -Path (Join-Path $BuildDir "logs") -Force | Out-Null New-Item -ItemType Directory -Path (Join-Path $BuildDir "huggingface") -Force | Out-Null +New-Item -ItemType Directory -Path (Join-Path $BuildDir "tagger-models") -Force | Out-Null +New-Item -ItemType Directory -Path (Join-Path $BuildDir "tagger-models\wd14") -Force | Out-Null +New-Item -ItemType Directory -Path (Join-Path $BuildDir "tagger-models\vlm") -Force | Out-Null Write-Host "用户目录创建完成" -ForegroundColor Green diff --git a/build-scripts/build_portable.ps1 b/build-scripts/build_portable.ps1 index dfa5dcb3..18fc77bc 100644 --- a/build-scripts/build_portable.ps1 +++ b/build-scripts/build_portable.ps1 @@ -333,7 +333,11 @@ Write-Host "" Write-Host "[3/6] Bundling default WD tagger (wd14-convnextv2-v2, ~388 MB)..." -ForegroundColor Cyan $hfHome = Join-Path $portableDir "huggingface" +$taggerModelsDir = Join-Path $portableDir "tagger-models" New-Item -ItemType Directory -Path $hfHome -Force | Out-Null +New-Item -ItemType Directory -Path $taggerModelsDir -Force | Out-Null +New-Item -ItemType Directory -Path (Join-Path $portableDir "tagger-models\wd14") -Force | Out-Null +New-Item -ItemType Directory -Path (Join-Path $portableDir "tagger-models\vlm") -Force | Out-Null $prefetchScript = Join-Path $sdtDir "scripts\prefetch_default_tagger.py" if (-not (Test-Path $prefetchScript)) { @@ -342,13 +346,14 @@ if (-not (Test-Path $prefetchScript)) { Write-Host " WARNING: no Python for tagger prefetch; tagger will download on first tag run" -ForegroundColor Yellow } else { $env:HF_HOME = $hfHome + $env:MIKAZUKI_TAGGER_MODELS_DIR = $taggerModelsDir # pip writes progress to stderr; with $ErrorActionPreference Stop that aborts the build. $prevEap = $ErrorActionPreference $ErrorActionPreference = 'Continue' $prefetchExit = 1 if (Get-Command python -ErrorAction SilentlyContinue) { & python -m pip install -q huggingface_hub 2>&1 | Out-Null - & python $prefetchScript --hf-home $hfHome --if-missing + & python $prefetchScript --hf-home $hfHome --tagger-models-dir $taggerModelsDir --if-missing $prefetchExit = $LASTEXITCODE } elseif (Test-Path $pythonExe) { if (Test-Path $getPipPath) { @@ -356,14 +361,14 @@ if (-not (Test-Path $prefetchScript)) { & $pythonExe $getPipPath --no-warn-script-location 2>&1 | Out-Null } & $pythonExe -s -m pip install -q huggingface_hub 2>&1 | Out-Null - & $pythonExe -s $prefetchScript --hf-home $hfHome --if-missing + & $pythonExe -s $prefetchScript --hf-home $hfHome --tagger-models-dir $taggerModelsDir --if-missing $prefetchExit = $LASTEXITCODE } $ErrorActionPreference = $prevEap if ($prefetchExit -ne 0) { Write-Host " WARNING: tagger prefetch failed; 7z may ship without offline tagger" -ForegroundColor Yellow } else { - Write-Host " Cached under huggingface/hub/" -ForegroundColor Green + Write-Host " Cached under huggingface/hub/ and tagger-models/" -ForegroundColor Green } } @@ -450,7 +455,7 @@ foreach ($bat in @("Update-SD-Trainer.bat", "Download-Anima-Model.bat")) { Write-Host "" Write-Host "[5/6] Creating user directories and README..." -ForegroundColor Cyan -foreach ($d in @("sd-models", "output", "logs", "huggingface")) { +foreach ($d in @("sd-models", "output", "logs", "huggingface", "tagger-models", "tagger-models\wd14", "tagger-models\vlm")) { $p = Join-Path $portableDir $d New-Item -ItemType Directory -Path $p -Force | Out-Null [System.IO.File]::WriteAllText((Join-Path $p ".gitkeep"), "") @@ -463,8 +468,10 @@ $readme += " 1. Double-click run_gui.bat`r`n" $readme += " 2. First launch requires internet (downloads ~3 GB of PyTorch)`r`n" $readme += " 3. Open http://127.0.0.1:28000 in browser`r`n`r`n" $readme += "Tagging:`r`n" -$readme += " Default WD tagger (wd14-convnextv2-v2) is bundled under huggingface/`r`n" -$readme += " (~400 MB). Use the built-in Tagger page without extra model download.`r`n`r`n" +$readme += " Default WD tagger (wd14-convnextv2-v2) is bundled under tagger-models/wd14/`r`n" +$readme += " (~400 MB). Put extra WD/CL tag models in tagger-models/wd14//`r`n" +$readme += " Future VLM caption models can be placed under tagger-models/vlm//`r`n" +$readme += " with the files required by that model, such as model.onnx and selected_tags.csv.`r`n`r`n" $readme += "Directories:`r`n" $readme += " run_gui.bat - Stable entrypoint for portable users`r`n" $readme += " run_gui_portable.bat - Legacy shim (logic in SD-Trainer/scripts/portable/)`r`n" @@ -473,6 +480,7 @@ $readme += " SD-Trainer/ - Project files`r`n" $readme += " sd-models/ - Put your models here`r`n" $readme += " output/ - Training output`r`n" $readme += " logs/ - Logs`r`n`r`n" +$readme += " tagger-models/ - Local tagger models`r`n`r`n" $readme += "Update:`r`n" $readme += " update\update_sd_trainer.bat - Shortcut to Update-SD-Trainer.bat`r`n" $readme += " update\update_dependencies.bat - Update Python packages`r`n`r`n" diff --git a/docs/api/dataset-tagging.md b/docs/api/dataset-tagging.md index 1b18cea7..e35e97b1 100644 --- a/docs/api/dataset-tagging.md +++ b/docs/api/dataset-tagging.md @@ -62,6 +62,23 @@ - `https://hf-mirror.com` - `https://modelscope.cn` +## 本地打标模型目录 + +WebUI 会优先检查本地 `tagger-models///`,文件齐全时不会访问 Hugging Face。默认模型目录为: + +```text +tagger-models/wd14/wd14-convnextv2-v2/ + model.onnx + selected_tags.csv +``` + +整合包会把默认 WD 模型放入该目录。用户也可以手动下载其它模型并放到对应的分类子目录: + +- `tagger-models/wd14//`:WD14 / CL 系列,主要用于 tag 打标。 +- `tagger-models/vlm//`:预留给 VLM / 自然语言描述模型。 + +为兼容已安装用户,旧的一层目录 `tagger-models//` 仍可识别。如果文件不完整,系统会继续回退到原有 `huggingface/` 缓存或在线下载流程。 + **成功**:`status: success`,`message: 模型下载已开始` **失败**:已有任务进行中、未知模型等返回 `status: fail`。 diff --git a/docs/portable-packaging-git-update.md b/docs/portable-packaging-git-update.md index 993ecfbc..04882f35 100644 --- a/docs/portable-packaging-git-update.md +++ b/docs/portable-packaging-git-update.md @@ -28,6 +28,9 @@ output/ logs/ huggingface/ + tagger-models/ + tagger-models/wd14/ + tagger-models/vlm/ ``` 这些路径被用户快捷方式、启动脚本和文档绑定,不要随意改名。 @@ -69,6 +72,9 @@ sd-models/ output/ logs/ huggingface/ +tagger-models/ +tagger-models/wd14/ +tagger-models/vlm/ train/ config/ toml/autosave/ diff --git a/frontend/dist/404.html b/frontend/dist/404.html index 8f60f71f..47c6466c 100644 --- a/frontend/dist/404.html +++ b/frontend/dist/404.html @@ -1,4 +1,4 @@ - + @@ -36,3 +36,6 @@ + + + diff --git a/frontend/dist/assets/app.547295de.js b/frontend/dist/assets/app.547295de.js index 8a65be93..a5522ea7 100644 --- a/frontend/dist/assets/app.547295de.js +++ b/frontend/dist/assets/app.547295de.js @@ -1,4 +1,4 @@ -var m2=Object.defineProperty;var h2=(e,t,n)=>t in e?m2(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n;var Hp=(e,t,n)=>(h2(e,typeof t!="symbol"?t+"":t,n),n);const zp={};const v2="modulepreload",jp={},g2="/",wt=function(t,n){return!n||n.length===0?t():Promise.all(n.map(r=>{if(r=`${g2}${r}`,r in jp)return;jp[r]=!0;const o=r.endsWith(".css"),a=o?'[rel="stylesheet"]':"";if(document.querySelector(`link[href="${r}"]${a}`))return;const l=document.createElement("link");if(l.rel=o?"stylesheet":v2,o||(l.as="script",l.crossOrigin=""),l.href=r,document.head.appendChild(l),o)return new Promise((s,i)=>{l.addEventListener("load",s),l.addEventListener("error",()=>i(new Error(`Unable to preload CSS for ${r}`)))})})).then(()=>t())},b2={"v-8daa1a0e":()=>wt(()=>import("./index.html.ec4ace46.js"),[]).then(({data:e})=>e),"v-6983ba2a":()=>wt(()=>import("./tageditor.html.66da263e.js"),[]).then(({data:e})=>e),"v-51615306":()=>wt(()=>import("./tagger.html.66f12b92.js"),[]).then(({data:e})=>e),"v-06850b9b":()=>wt(()=>import("./task.html.4e4c8633.js"),[]).then(({data:e})=>e),"v-13efe3c5":()=>wt(()=>import("./tensorboard.html.4a2799a9.js"),[]).then(({data:e})=>e),"v-33a23463":()=>wt(()=>import("./index.html.838bbc6c.js"),[]).then(({data:e})=>e),"v-b5471278":()=>wt(()=>import("./about.html.5b0c0de9.js"),[]).then(({data:e})=>e),"v-a1c9e4f2":()=>wt(()=>import("./changelog.html.a1b2c3d4.js"),[]).then(({data:e})=>e),"v-b8e2d701":()=>wt(()=>import("./guide.html.b8e2d701.js"),[]).then(({data:e})=>e),"v-72e1da3e":()=>wt(()=>import("./settings.html.06993f96.js"),[]).then(({data:e})=>e),"v-3e43d6e2":()=>wt(()=>import("./basic.html.48955584.js"),[]).then(({data:e})=>e),"v-fdbe4e28":()=>wt(()=>import("./flux.html.6fefc131.js"),[]).then(({data:e})=>e),"v-14e91824":()=>wt(()=>import("./index.html.b97ec799.js"),[]).then(({data:e})=>e),"v-1bf725da":()=>wt(()=>import("./master.html.54eb6415.js"),[]).then(({data:e})=>e),"v-0f9e746f":()=>wt(()=>import("./params.html.c8cc13ef.js"),[]).then(({data:e})=>e),"v-0dc76a3b":()=>wt(()=>import("./sd3.html.eaeb05e1.js"),[]).then(({data:e})=>e),"v-a1f1ne2e":()=>wt(()=>import("./anima-finetune.html.eaeb05f2.js"),[]).then(({data:e})=>e),"v-53c99f50":()=>wt(()=>import("./sdxl.html.6ab37b06.js"),[]).then(({data:e})=>e),"v-4441a302":()=>wt(()=>import("./tools.html.c0a4659a.js"),[]).then(({data:e})=>e),"v-3706649a":()=>wt(()=>import("./404.html.686caba0.js"),[]).then(({data:e})=>e)};function Jd(e,t){const n=Object.create(null),r=e.split(",");for(let o=0;o!!n[o.toLowerCase()]:o=>!!n[o]}const Ft={},Na=[],en=()=>{},y2=()=>!1,_2=/^on[^a-z]/,$s=e=>_2.test(e),Zd=e=>e.startsWith("onUpdate:"),Wt=Object.assign,Qd=(e,t)=>{const n=e.indexOf(t);n>-1&&e.splice(n,1)},w2=Object.prototype.hasOwnProperty,ft=(e,t)=>w2.call(e,t),De=Array.isArray,Da=e=>Ts(e)==="[object Map]",Su=e=>Ts(e)==="[object Set]",Yi=e=>Ts(e)==="[object Date]",Ke=e=>typeof e=="function",Ge=e=>typeof e=="string",Zl=e=>typeof e=="symbol",ht=e=>e!==null&&typeof e=="object",Gi=e=>ht(e)&&Ke(e.then)&&Ke(e.catch),Kg=Object.prototype.toString,Ts=e=>Kg.call(e),$i=e=>Ts(e).slice(8,-1),qg=e=>Ts(e)==="[object Object]",ef=e=>Ge(e)&&e!=="NaN"&&e[0]!=="-"&&""+parseInt(e,10)===e,Rl=Jd(",key,ref,ref_for,ref_key,onVnodeBeforeMount,onVnodeMounted,onVnodeBeforeUpdate,onVnodeUpdated,onVnodeBeforeUnmount,onVnodeUnmounted"),Eu=e=>{const t=Object.create(null);return n=>t[n]||(t[n]=e(n))},C2=/-(\w)/g,cr=Eu(e=>e.replace(C2,(t,n)=>n?n.toUpperCase():"")),k2=/\B([A-Z])/g,fa=Eu(e=>e.replace(k2,"-$1").toLowerCase()),$u=Eu(e=>e.charAt(0).toUpperCase()+e.slice(1)),Ti=Eu(e=>e?`on${$u(e)}`:""),Ql=(e,t)=>!Object.is(e,t),xi=(e,t)=>{for(let n=0;n{Object.defineProperty(e,t,{configurable:!0,enumerable:!1,value:n})},Vc=e=>{const t=parseFloat(e);return isNaN(t)?e:t},S2=e=>{const t=Ge(e)?Number(e):NaN;return isNaN(t)?e:t};let Wp;const Bc=()=>Wp||(Wp=typeof globalThis!="undefined"?globalThis:typeof self!="undefined"?self:typeof window!="undefined"?window:typeof global!="undefined"?global:{});function Qe(e){if(De(e)){const t={};for(let n=0;n{if(n){const r=n.split($2);r.length>1&&(t[r[0].trim()]=r[1].trim())}}),t}function D(e){let t="";if(Ge(e))t=e;else if(De(e))for(let n=0;nja(n,t))}const Ee=e=>Ge(e)?e:e==null?"":De(e)||ht(e)&&(e.toString===Kg||!Ke(e.toString))?JSON.stringify(e,Xg,2):String(e),Xg=(e,t)=>t&&t.__v_isRef?Xg(e,t.value):Da(t)?{[`Map(${t.size})`]:[...t.entries()].reduce((n,[r,o])=>(n[`${r} =>`]=o,n),{})}:Su(t)?{[`Set(${t.size})`]:[...t.values()]}:ht(t)&&!De(t)&&!qg(t)?String(t):t;let Vn;class Jg{constructor(t=!1){this.detached=t,this._active=!0,this.effects=[],this.cleanups=[],this.parent=Vn,!t&&Vn&&(this.index=(Vn.scopes||(Vn.scopes=[])).push(this)-1)}get active(){return this._active}run(t){if(this._active){const n=Vn;try{return Vn=this,t()}finally{Vn=n}}}on(){Vn=this}off(){Vn=this.parent}stop(t){if(this._active){let n,r;for(n=0,r=this.effects.length;n{const t=new Set(e);return t.w=0,t.n=0,t},eb=e=>(e.w&To)>0,tb=e=>(e.n&To)>0,R2=({deps:e})=>{if(e.length)for(let t=0;t{const{deps:t}=e;if(t.length){let n=0;for(let r=0;r{(d==="length"||d>=i)&&s.push(u)})}else switch(n!==void 0&&s.push(l.get(n)),t){case"add":De(e)?ef(n)&&s.push(l.get("length")):(s.push(l.get(na)),Da(e)&&s.push(l.get(Hc)));break;case"delete":De(e)||(s.push(l.get(na)),Da(e)&&s.push(l.get(Hc)));break;case"set":Da(e)&&s.push(l.get(na));break}if(s.length===1)s[0]&&jc(s[0]);else{const i=[];for(const u of s)u&&i.push(...u);jc(tf(i))}}function jc(e,t){const n=De(e)?e:[...e];for(const r of n)r.computed&&Kp(r);for(const r of n)r.computed||Kp(r)}function Kp(e,t){(e!==lr||e.allowRecurse)&&(e.scheduler?e.scheduler():e.run())}function D2(e,t){var n;return(n=Ji.get(e))==null?void 0:n.get(t)}const F2=Jd("__proto__,__v_isRef,__isVue"),ob=new Set(Object.getOwnPropertyNames(Symbol).filter(e=>e!=="arguments"&&e!=="caller").map(e=>Symbol[e]).filter(Zl)),V2=rf(),B2=rf(!1,!0),z2=rf(!0),qp=H2();function H2(){const e={};return["includes","indexOf","lastIndexOf"].forEach(t=>{e[t]=function(...n){const r=gt(this);for(let a=0,l=this.length;a{e[t]=function(...n){dl();const r=gt(this)[t].apply(this,n);return fl(),r}}),e}function j2(e){const t=gt(this);return Ln(t,"has",e),t.hasOwnProperty(e)}function rf(e=!1,t=!1){return function(r,o,a){if(o==="__v_isReactive")return!e;if(o==="__v_isReadonly")return e;if(o==="__v_isShallow")return t;if(o==="__v_raw"&&a===(e?t?aC:ub:t?ib:sb).get(r))return r;const l=De(r);if(!e){if(l&&ft(qp,o))return Reflect.get(qp,o,a);if(o==="hasOwnProperty")return j2}const s=Reflect.get(r,o,a);return(Zl(o)?ob.has(o):F2(o))||(e||Ln(r,"get",o),t)?s:mt(s)?l&&ef(o)?s:s.value:ht(s)?e?pa(s):Xt(s):s}}const W2=ab(),U2=ab(!0);function ab(e=!1){return function(n,r,o,a){let l=n[r];if(Wa(l)&&mt(l)&&!mt(o))return!1;if(!e&&(!Zi(o)&&!Wa(o)&&(l=gt(l),o=gt(o)),!De(n)&&mt(l)&&!mt(o)))return l.value=o,!0;const s=De(n)&&ef(r)?Number(r)e,Tu=e=>Reflect.getPrototypeOf(e);function qs(e,t,n=!1,r=!1){e=e.__v_raw;const o=gt(e),a=gt(t);n||(t!==a&&Ln(o,"get",t),Ln(o,"get",a));const{has:l}=Tu(o),s=r?of:n?uf:es;if(l.call(o,t))return s(e.get(t));if(l.call(o,a))return s(e.get(a));e!==o&&e.get(t)}function Ys(e,t=!1){const n=this.__v_raw,r=gt(n),o=gt(e);return t||(e!==o&&Ln(r,"has",e),Ln(r,"has",o)),e===o?n.has(e):n.has(e)||n.has(o)}function Gs(e,t=!1){return e=e.__v_raw,!t&&Ln(gt(e),"iterate",na),Reflect.get(e,"size",e)}function Yp(e){e=gt(e);const t=gt(this);return Tu(t).has.call(t,e)||(t.add(e),Yr(t,"add",e,e)),this}function Gp(e,t){t=gt(t);const n=gt(this),{has:r,get:o}=Tu(n);let a=r.call(n,e);a||(e=gt(e),a=r.call(n,e));const l=o.call(n,e);return n.set(e,t),a?Ql(t,l)&&Yr(n,"set",e,t):Yr(n,"add",e,t),this}function Xp(e){const t=gt(this),{has:n,get:r}=Tu(t);let o=n.call(t,e);o||(e=gt(e),o=n.call(t,e)),r&&r.call(t,e);const a=t.delete(e);return o&&Yr(t,"delete",e,void 0),a}function Jp(){const e=gt(this),t=e.size!==0,n=e.clear();return t&&Yr(e,"clear",void 0,void 0),n}function Xs(e,t){return function(r,o){const a=this,l=a.__v_raw,s=gt(l),i=t?of:e?uf:es;return!e&&Ln(s,"iterate",na),l.forEach((u,d)=>r.call(o,i(u),i(d),a))}}function Js(e,t,n){return function(...r){const o=this.__v_raw,a=gt(o),l=Da(a),s=e==="entries"||e===Symbol.iterator&&l,i=e==="keys"&&l,u=o[e](...r),d=n?of:t?uf:es;return!t&&Ln(a,"iterate",i?Hc:na),{next(){const{value:f,done:h}=u.next();return h?{value:f,done:h}:{value:s?[d(f[0]),d(f[1])]:d(f),done:h}},[Symbol.iterator](){return this}}}}function so(e){return function(...t){return e==="delete"?!1:this}}function J2(){const e={get(a){return qs(this,a)},get size(){return Gs(this)},has:Ys,add:Yp,set:Gp,delete:Xp,clear:Jp,forEach:Xs(!1,!1)},t={get(a){return qs(this,a,!1,!0)},get size(){return Gs(this)},has:Ys,add:Yp,set:Gp,delete:Xp,clear:Jp,forEach:Xs(!1,!0)},n={get(a){return qs(this,a,!0)},get size(){return Gs(this,!0)},has(a){return Ys.call(this,a,!0)},add:so("add"),set:so("set"),delete:so("delete"),clear:so("clear"),forEach:Xs(!0,!1)},r={get(a){return qs(this,a,!0,!0)},get size(){return Gs(this,!0)},has(a){return Ys.call(this,a,!0)},add:so("add"),set:so("set"),delete:so("delete"),clear:so("clear"),forEach:Xs(!0,!0)};return["keys","values","entries",Symbol.iterator].forEach(a=>{e[a]=Js(a,!1,!1),n[a]=Js(a,!0,!1),t[a]=Js(a,!1,!0),r[a]=Js(a,!0,!0)}),[e,n,t,r]}const[Z2,Q2,eC,tC]=J2();function af(e,t){const n=t?e?tC:eC:e?Q2:Z2;return(r,o,a)=>o==="__v_isReactive"?!e:o==="__v_isReadonly"?e:o==="__v_raw"?r:Reflect.get(ft(n,o)&&o in r?n:r,o,a)}const nC={get:af(!1,!1)},rC={get:af(!1,!0)},oC={get:af(!0,!1)},sb=new WeakMap,ib=new WeakMap,ub=new WeakMap,aC=new WeakMap;function lC(e){switch(e){case"Object":case"Array":return 1;case"Map":case"Set":case"WeakMap":case"WeakSet":return 2;default:return 0}}function sC(e){return e.__v_skip||!Object.isExtensible(e)?0:lC($i(e))}function Xt(e){return Wa(e)?e:sf(e,!1,lb,nC,sb)}function lf(e){return sf(e,!1,X2,rC,ib)}function pa(e){return sf(e,!0,G2,oC,ub)}function sf(e,t,n,r,o){if(!ht(e)||e.__v_raw&&!(t&&e.__v_isReactive))return e;const a=o.get(e);if(a)return a;const l=sC(e);if(l===0)return e;const s=new Proxy(e,l===2?r:n);return o.set(e,s),s}function Fa(e){return Wa(e)?Fa(e.__v_raw):!!(e&&e.__v_isReactive)}function Wa(e){return!!(e&&e.__v_isReadonly)}function Zi(e){return!!(e&&e.__v_isShallow)}function cb(e){return Fa(e)||Wa(e)}function gt(e){const t=e&&e.__v_raw;return t?gt(t):e}function db(e){return Xi(e,"__v_skip",!0),e}const es=e=>ht(e)?Xt(e):e,uf=e=>ht(e)?pa(e):e;function fb(e){So&&lr&&(e=gt(e),rb(e.dep||(e.dep=tf())))}function cf(e,t){e=gt(e);const n=e.dep;n&&jc(n)}function mt(e){return!!(e&&e.__v_isRef===!0)}function B(e){return pb(e,!1)}function On(e){return pb(e,!0)}function pb(e,t){return mt(e)?e:new iC(e,t)}class iC{constructor(t,n){this.__v_isShallow=n,this.dep=void 0,this.__v_isRef=!0,this._rawValue=n?t:gt(t),this._value=n?t:es(t)}get value(){return fb(this),this._value}set value(t){const n=this.__v_isShallow||Zi(t)||Wa(t);t=n?t:gt(t),Ql(t,this._rawValue)&&(this._rawValue=t,this._value=n?t:es(t),cf(this))}}function Cl(e){cf(e)}function c(e){return mt(e)?e.value:e}const uC={get:(e,t,n)=>c(Reflect.get(e,t,n)),set:(e,t,n,r)=>{const o=e[t];return mt(o)&&!mt(n)?(o.value=n,!0):Reflect.set(e,t,n,r)}};function mb(e){return Fa(e)?e:new Proxy(e,uC)}function dr(e){const t=De(e)?new Array(e.length):{};for(const n in e)t[n]=hb(e,n);return t}class cC{constructor(t,n,r){this._object=t,this._key=n,this._defaultValue=r,this.__v_isRef=!0}get value(){const t=this._object[this._key];return t===void 0?this._defaultValue:t}set value(t){this._object[this._key]=t}get dep(){return D2(gt(this._object),this._key)}}class dC{constructor(t){this._getter=t,this.__v_isRef=!0,this.__v_isReadonly=!0}get value(){return this._getter()}}function zt(e,t,n){return mt(e)?e:Ke(e)?new dC(e):ht(e)&&arguments.length>1?hb(e,t,n):B(e)}function hb(e,t,n){const r=e[t];return mt(r)?r:new cC(e,t,n)}class fC{constructor(t,n,r,o){this._setter=n,this.dep=void 0,this.__v_isRef=!0,this.__v_isReadonly=!1,this._dirty=!0,this.effect=new nf(t,()=>{this._dirty||(this._dirty=!0,cf(this))}),this.effect.computed=this,this.effect.active=this._cacheable=!o,this.__v_isReadonly=r}get value(){const t=gt(this);return fb(t),(t._dirty||!t._cacheable)&&(t._dirty=!1,t._value=t.effect.run()),t._value}set value(t){this._setter(t)}}function vb(e,t,n=!1){let r,o;const a=Ke(e);return a?(r=e,o=en):(r=e.get,o=e.set),new fC(r,o,a||!o,n)}function pC(e,...t){}function Eo(e,t,n,r){let o;try{o=r?e(...r):e()}catch(a){xs(a,t,n)}return o}function qn(e,t,n,r){if(Ke(e)){const a=Eo(e,t,n,r);return a&&Gi(a)&&a.catch(l=>{xs(l,t,n)}),a}const o=[];for(let a=0;a>>1;ns(pn[r])Sr&&pn.splice(t,1)}function gC(e){De(e)?Va.push(...e):(!zr||!zr.includes(e,e.allowRecurse?qo+1:qo))&&Va.push(e),bb()}function Zp(e,t=ts?Sr+1:0){for(;tns(n)-ns(r)),qo=0;qoe.id==null?1/0:e.id,bC=(e,t)=>{const n=ns(e)-ns(t);if(n===0){if(e.pre&&!t.pre)return-1;if(t.pre&&!e.pre)return 1}return n};function yb(e){Wc=!1,ts=!0,pn.sort(bC);const t=en;try{for(Sr=0;SrGe(p)?p.trim():p)),f&&(o=n.map(Vc))}let s,i=r[s=Ti(t)]||r[s=Ti(cr(t))];!i&&a&&(i=r[s=Ti(fa(t))]),i&&qn(i,e,6,o);const u=r[s+"Once"];if(u){if(!e.emitted)e.emitted={};else if(e.emitted[s])return;e.emitted[s]=!0,qn(u,e,6,o)}}function _b(e,t,n=!1){const r=t.emitsCache,o=r.get(e);if(o!==void 0)return o;const a=e.emits;let l={},s=!1;if(!Ke(e)){const i=u=>{const d=_b(u,t,!0);d&&(s=!0,Wt(l,d))};!n&&t.mixins.length&&t.mixins.forEach(i),e.extends&&i(e.extends),e.mixins&&e.mixins.forEach(i)}return!a&&!s?(ht(e)&&r.set(e,null),null):(De(a)?a.forEach(i=>l[i]=null):Wt(l,a),ht(e)&&r.set(e,l),l)}function Ou(e,t){return!e||!$s(t)?!1:(t=t.slice(2).replace(/Once$/,""),ft(e,t[0].toLowerCase()+t.slice(1))||ft(e,fa(t))||ft(e,t))}let sn=null,Au=null;function eu(e){const t=sn;return sn=e,Au=e&&e.type.__scopeId||null,t}function _C(e){Au=e}function wC(){Au=null}function G(e,t=sn,n){if(!t||e._n)return e;const r=(...o)=>{r._d&&dm(-1);const a=eu(t);let l;try{l=e(...o)}finally{eu(a),r._d&&dm(1)}return l};return r._n=!0,r._c=!0,r._d=!0,r}function ac(e){const{type:t,vnode:n,proxy:r,withProxy:o,props:a,propsOptions:[l],slots:s,attrs:i,emit:u,render:d,renderCache:f,data:h,setupState:p,ctx:v,inheritAttrs:g}=e;let w,m;const b=eu(e);try{if(n.shapeFlag&4){const y=o||r;w=or(d.call(y,y,f,a,p,h,v)),m=i}else{const y=t;w=or(y.length>1?y(a,{attrs:i,slots:s,emit:u}):y(a,null)),m=t.props?i:CC(i)}}catch(y){Vl.length=0,xs(y,e,1),w=Q(yn)}let _=w;if(m&&g!==!1){const y=Object.keys(m),{shapeFlag:C}=_;y.length&&C&7&&(l&&y.some(Zd)&&(m=kC(m,l)),_=Xr(_,m))}return n.dirs&&(_=Xr(_),_.dirs=_.dirs?_.dirs.concat(n.dirs):n.dirs),n.transition&&(_.transition=n.transition),w=_,eu(b),w}const CC=e=>{let t;for(const n in e)(n==="class"||n==="style"||$s(n))&&((t||(t={}))[n]=e[n]);return t},kC=(e,t)=>{const n={};for(const r in e)(!Zd(r)||!(r.slice(9)in t))&&(n[r]=e[r]);return n};function SC(e,t,n){const{props:r,children:o,component:a}=e,{props:l,children:s,patchFlag:i}=t,u=a.emitsOptions;if(t.dirs||t.transition)return!0;if(n&&i>=0){if(i&1024)return!0;if(i&16)return r?Qp(r,l,u):!!l;if(i&8){const d=t.dynamicProps;for(let f=0;fe.__isSuspense;function wb(e,t){t&&t.pendingBranch?De(e)?t.effects.push(...e):t.effects.push(e):gC(e)}function qr(e,t){return ff(e,null,t)}const Zs={};function $e(e,t,n){return ff(e,t,n)}function ff(e,t,{immediate:n,deep:r,flush:o,onTrack:a,onTrigger:l}=Ft){var s;const i=Zg()===((s=Zt)==null?void 0:s.scope)?Zt:null;let u,d=!1,f=!1;if(mt(e)?(u=()=>e.value,d=Zi(e)):Fa(e)?(u=()=>e,r=!0):De(e)?(f=!0,d=e.some(y=>Fa(y)||Zi(y)),u=()=>e.map(y=>{if(mt(y))return y.value;if(Fa(y))return Jo(y);if(Ke(y))return Eo(y,i,2)})):Ke(e)?t?u=()=>Eo(e,i,2):u=()=>{if(!(i&&i.isUnmounted))return h&&h(),qn(e,i,3,[p])}:u=en,t&&r){const y=u;u=()=>Jo(y())}let h,p=y=>{h=b.onStop=()=>{Eo(y,i,4)}},v;if(qa)if(p=en,t?n&&qn(t,i,3,[u(),f?[]:void 0,p]):u(),o==="sync"){const y=vk();v=y.__watcherHandles||(y.__watcherHandles=[])}else return en;let g=f?new Array(e.length).fill(Zs):Zs;const w=()=>{if(!!b.active)if(t){const y=b.run();(r||d||(f?y.some((C,k)=>Ql(C,g[k])):Ql(y,g)))&&(h&&h(),qn(t,i,3,[y,g===Zs?void 0:f&&g[0]===Zs?[]:g,p]),g=y)}else b.run()};w.allowRecurse=!!t;let m;o==="sync"?m=w:o==="post"?m=()=>Tn(w,i&&i.suspense):(w.pre=!0,i&&(w.id=i.uid),m=()=>xu(w));const b=new nf(u,m);t?n?w():g=b.run():o==="post"?Tn(b.run.bind(b),i&&i.suspense):b.run();const _=()=>{b.stop(),i&&i.scope&&Qd(i.scope.effects,b)};return v&&v.push(_),_}function TC(e,t,n){const r=this.proxy,o=Ge(e)?e.includes(".")?Cb(r,e):()=>r[e]:e.bind(r,r);let a;Ke(t)?a=t:(a=t.handler,n=t);const l=Zt;Ka(this);const s=ff(o,a.bind(r),n);return l?Ka(l):ra(),s}function Cb(e,t){const n=t.split(".");return()=>{let r=e;for(let o=0;o{Jo(n,t)});else if(qg(e))for(const n in e)Jo(e[n],t);return e}function vt(e,t){const n=sn;if(n===null)return e;const r=Mu(n)||n.proxy,o=e.dirs||(e.dirs=[]);for(let a=0;a{e.isMounted=!0}),rn(()=>{e.isUnmounting=!0}),e}const Wn=[Function,Array],Sb={mode:String,appear:Boolean,persisted:Boolean,onBeforeEnter:Wn,onEnter:Wn,onAfterEnter:Wn,onEnterCancelled:Wn,onBeforeLeave:Wn,onLeave:Wn,onAfterLeave:Wn,onLeaveCancelled:Wn,onBeforeAppear:Wn,onAppear:Wn,onAfterAppear:Wn,onAppearCancelled:Wn},xC={name:"BaseTransition",props:Sb,setup(e,{slots:t}){const n=lt(),r=kb();let o;return()=>{const a=t.default&&pf(t.default(),!0);if(!a||!a.length)return;let l=a[0];if(a.length>1){for(const g of a)if(g.type!==yn){l=g;break}}const s=gt(e),{mode:i}=s;if(r.isLeaving)return lc(l);const u=em(l);if(!u)return lc(l);const d=rs(u,s,r,n);os(u,d);const f=n.subTree,h=f&&em(f);let p=!1;const{getTransitionKey:v}=u.type;if(v){const g=v();o===void 0?o=g:g!==o&&(o=g,p=!0)}if(h&&h.type!==yn&&(!Yo(u,h)||p)){const g=rs(h,s,r,n);if(os(h,g),i==="out-in")return r.isLeaving=!0,g.afterLeave=()=>{r.isLeaving=!1,n.update.active!==!1&&n.update()},lc(l);i==="in-out"&&u.type!==yn&&(g.delayLeave=(w,m,b)=>{const _=Eb(r,h);_[String(h.key)]=h,w._leaveCb=()=>{m(),w._leaveCb=void 0,delete d.delayedLeave},d.delayedLeave=b})}return l}}},OC=xC;function Eb(e,t){const{leavingVNodes:n}=e;let r=n.get(t.type);return r||(r=Object.create(null),n.set(t.type,r)),r}function rs(e,t,n,r){const{appear:o,mode:a,persisted:l=!1,onBeforeEnter:s,onEnter:i,onAfterEnter:u,onEnterCancelled:d,onBeforeLeave:f,onLeave:h,onAfterLeave:p,onLeaveCancelled:v,onBeforeAppear:g,onAppear:w,onAfterAppear:m,onAppearCancelled:b}=t,_=String(e.key),y=Eb(n,e),C=(S,R)=>{S&&qn(S,r,9,R)},k=(S,R)=>{const L=R[1];C(S,R),De(S)?S.every(F=>F.length<=1)&&L():S.length<=1&&L()},E={mode:a,persisted:l,beforeEnter(S){let R=s;if(!n.isMounted)if(o)R=g||s;else return;S._leaveCb&&S._leaveCb(!0);const L=y[_];L&&Yo(e,L)&&L.el._leaveCb&&L.el._leaveCb(),C(R,[S])},enter(S){let R=i,L=u,F=d;if(!n.isMounted)if(o)R=w||i,L=m||u,F=b||d;else return;let N=!1;const A=S._enterCb=M=>{N||(N=!0,M?C(F,[S]):C(L,[S]),E.delayedLeave&&E.delayedLeave(),S._enterCb=void 0)};R?k(R,[S,A]):A()},leave(S,R){const L=String(e.key);if(S._enterCb&&S._enterCb(!0),n.isUnmounting)return R();C(f,[S]);let F=!1;const N=S._leaveCb=A=>{F||(F=!0,R(),A?C(v,[S]):C(p,[S]),S._leaveCb=void 0,y[L]===e&&delete y[L])};y[L]=e,h?k(h,[S,N]):N()},clone(S){return rs(S,t,n,r)}};return E}function lc(e){if(Os(e))return e=Xr(e),e.children=null,e}function em(e){return Os(e)?e.children?e.children[0]:void 0:e}function os(e,t){e.shapeFlag&6&&e.component?os(e.component.subTree,t):e.shapeFlag&128?(e.ssContent.transition=t.clone(e.ssContent),e.ssFallback.transition=t.clone(e.ssFallback)):e.transition=t}function pf(e,t=!1,n){let r=[],o=0;for(let a=0;a1)for(let a=0;aWt({name:e.name},t,{setup:e}))():e}const Ba=e=>!!e.type.__asyncLoader;function Jt(e){Ke(e)&&(e={loader:e});const{loader:t,loadingComponent:n,errorComponent:r,delay:o=200,timeout:a,suspensible:l=!0,onError:s}=e;let i=null,u,d=0;const f=()=>(d++,i=null,h()),h=()=>{let p;return i||(p=i=t().catch(v=>{if(v=v instanceof Error?v:new Error(String(v)),s)return new Promise((g,w)=>{s(v,()=>g(f()),()=>w(v),d+1)});throw v}).then(v=>p!==i&&i?i:(v&&(v.__esModule||v[Symbol.toStringTag]==="Module")&&(v=v.default),u=v,v)))};return se({name:"AsyncComponentWrapper",__asyncLoader:h,get __asyncResolved(){return u},setup(){const p=Zt;if(u)return()=>sc(u,p);const v=b=>{i=null,xs(b,p,13,!r)};if(l&&p.suspense||qa)return h().then(b=>()=>sc(b,p)).catch(b=>(v(b),()=>r?Q(r,{error:b}):null));const g=B(!1),w=B(),m=B(!!o);return o&&setTimeout(()=>{m.value=!1},o),a!=null&&setTimeout(()=>{if(!g.value&&!w.value){const b=new Error(`Async component timed out after ${a}ms.`);v(b),w.value=b}},a),h().then(()=>{g.value=!0,p.parent&&Os(p.parent.vnode)&&xu(p.parent.update)}).catch(b=>{v(b),w.value=b}),()=>{if(g.value&&u)return sc(u,p);if(w.value&&r)return Q(r,{error:w.value});if(n&&!m.value)return Q(n)}}})}function sc(e,t){const{ref:n,props:r,children:o,ce:a}=t.vnode,l=Q(e,r,o);return l.ref=n,l.ce=a,delete t.vnode.ce,l}const Os=e=>e.type.__isKeepAlive;function AC(e,t){Tb(e,"a",t)}function $b(e,t){Tb(e,"da",t)}function Tb(e,t,n=Zt){const r=e.__wdc||(e.__wdc=()=>{let o=n;for(;o;){if(o.isDeactivated)return;o=o.parent}return e()});if(Iu(t,r,n),n){let o=n.parent;for(;o&&o.parent;)Os(o.parent.vnode)&&IC(r,t,n,o),o=o.parent}}function IC(e,t,n,r){const o=Iu(t,e,r,!0);Mo(()=>{Qd(r[t],o)},n)}function Iu(e,t,n=Zt,r=!1){if(n){const o=n[e]||(n[e]=[]),a=t.__weh||(t.__weh=(...l)=>{if(n.isUnmounted)return;dl(),Ka(n);const s=qn(t,n,e,l);return ra(),fl(),s});return r?o.unshift(a):o.push(a),a}}const eo=e=>(t,n=Zt)=>(!qa||e==="sp")&&Iu(e,(...r)=>t(...r),n),As=eo("bm"),dt=eo("m"),PC=eo("bu"),pl=eo("u"),rn=eo("bum"),Mo=eo("um"),LC=eo("sp"),MC=eo("rtg"),RC=eo("rtc");function NC(e,t=Zt){Iu("ec",e,t)}const mf="components",DC="directives";function Ve(e,t){return vf(mf,e,!0,t)||e}const xb=Symbol.for("v-ndc");function Lt(e){return Ge(e)?vf(mf,e,!1)||e:e||xb}function hf(e){return vf(DC,e)}function vf(e,t,n=!0,r=!1){const o=sn||Zt;if(o){const a=o.type;if(e===mf){const s=pk(a,!1);if(s&&(s===t||s===cr(t)||s===$u(cr(t))))return a}const l=tm(o[e]||a[e],t)||tm(o.appContext[e],t);return!l&&r?a:l}}function tm(e,t){return e&&(e[t]||e[cr(t)]||e[$u(cr(t))])}function it(e,t,n,r){let o;const a=n&&n[r];if(De(e)||Ge(e)){o=new Array(e.length);for(let l=0,s=e.length;lt(l,s,void 0,a&&a[s]));else{const l=Object.keys(e);o=new Array(l.length);for(let s=0,i=l.length;s{const a=r.fn(...o);return a&&(a.key=r.key),a}:r.fn)}return e}function pe(e,t,n={},r,o){if(sn.isCE||sn.parent&&Ba(sn.parent)&&sn.parent.isCE)return t!=="default"&&(n.name=t),Q("slot",n,r&&r());let a=e[t];a&&a._c&&(a._d=!1),x();const l=a&&Ob(a(n)),s=ce(Pe,{key:n.key||l&&l.key||`_${t}`},l||(r?r():[]),l&&e._===1?64:-2);return!o&&s.scopeId&&(s.slotScopeIds=[s.scopeId+"-s"]),a&&a._c&&(a._d=!0),s}function Ob(e){return e.some(t=>Ua(t)?!(t.type===yn||t.type===Pe&&!Ob(t.children)):!0)?e:null}function FC(e,t){const n={};for(const r in e)n[t&&/[A-Z]/.test(r)?`on:${r}`:Ti(r)]=e[r];return n}const Uc=e=>e?Wb(e)?Mu(e)||e.proxy:Uc(e.parent):null,Nl=Wt(Object.create(null),{$:e=>e,$el:e=>e.vnode.el,$data:e=>e.data,$props:e=>e.props,$attrs:e=>e.attrs,$slots:e=>e.slots,$refs:e=>e.refs,$parent:e=>Uc(e.parent),$root:e=>Uc(e.root),$emit:e=>e.emit,$options:e=>gf(e),$forceUpdate:e=>e.f||(e.f=()=>xu(e.update)),$nextTick:e=>e.n||(e.n=qe.bind(e.proxy)),$watch:e=>TC.bind(e)}),ic=(e,t)=>e!==Ft&&!e.__isScriptSetup&&ft(e,t),VC={get({_:e},t){const{ctx:n,setupState:r,data:o,props:a,accessCache:l,type:s,appContext:i}=e;let u;if(t[0]!=="$"){const p=l[t];if(p!==void 0)switch(p){case 1:return r[t];case 2:return o[t];case 4:return n[t];case 3:return a[t]}else{if(ic(r,t))return l[t]=1,r[t];if(o!==Ft&&ft(o,t))return l[t]=2,o[t];if((u=e.propsOptions[0])&&ft(u,t))return l[t]=3,a[t];if(n!==Ft&&ft(n,t))return l[t]=4,n[t];Kc&&(l[t]=0)}}const d=Nl[t];let f,h;if(d)return t==="$attrs"&&Ln(e,"get",t),d(e);if((f=s.__cssModules)&&(f=f[t]))return f;if(n!==Ft&&ft(n,t))return l[t]=4,n[t];if(h=i.config.globalProperties,ft(h,t))return h[t]},set({_:e},t,n){const{data:r,setupState:o,ctx:a}=e;return ic(o,t)?(o[t]=n,!0):r!==Ft&&ft(r,t)?(r[t]=n,!0):ft(e.props,t)||t[0]==="$"&&t.slice(1)in e?!1:(a[t]=n,!0)},has({_:{data:e,setupState:t,accessCache:n,ctx:r,appContext:o,propsOptions:a}},l){let s;return!!n[l]||e!==Ft&&ft(e,l)||ic(t,l)||(s=a[0])&&ft(s,l)||ft(r,l)||ft(Nl,l)||ft(o.config.globalProperties,l)},defineProperty(e,t,n){return n.get!=null?e._.accessCache[t]=0:ft(n,"value")&&this.set(e,t,n.value,null),Reflect.defineProperty(e,t,n)}};function to(){return Ab().slots}function Pu(){return Ab().attrs}function Ab(){const e=lt();return e.setupContext||(e.setupContext=Kb(e))}function nm(e){return De(e)?e.reduce((t,n)=>(t[n]=null,t),{}):e}let Kc=!0;function BC(e){const t=gf(e),n=e.proxy,r=e.ctx;Kc=!1,t.beforeCreate&&rm(t.beforeCreate,e,"bc");const{data:o,computed:a,methods:l,watch:s,provide:i,inject:u,created:d,beforeMount:f,mounted:h,beforeUpdate:p,updated:v,activated:g,deactivated:w,beforeDestroy:m,beforeUnmount:b,destroyed:_,unmounted:y,render:C,renderTracked:k,renderTriggered:E,errorCaptured:S,serverPrefetch:R,expose:L,inheritAttrs:F,components:N,directives:A,filters:M}=t;if(u&&zC(u,r,null),l)for(const V in l){const X=l[V];Ke(X)&&(r[V]=X.bind(n))}if(o){const V=o.call(n,n);ht(V)&&(e.data=Xt(V))}if(Kc=!0,a)for(const V in a){const X=a[V],I=Ke(X)?X.bind(n,n):Ke(X.get)?X.get.bind(n,n):en,Y=!Ke(X)&&Ke(X.set)?X.set.bind(n):en,ee=O({get:I,set:Y});Object.defineProperty(r,V,{enumerable:!0,configurable:!0,get:()=>ee.value,set:W=>ee.value=W})}if(s)for(const V in s)Ib(s[V],r,n,V);if(i){const V=Ke(i)?i.call(n):i;Reflect.ownKeys(V).forEach(X=>{yt(X,V[X])})}d&&rm(d,e,"c");function j(V,X){De(X)?X.forEach(I=>V(I.bind(n))):X&&V(X.bind(n))}if(j(As,f),j(dt,h),j(PC,p),j(pl,v),j(AC,g),j($b,w),j(NC,S),j(RC,k),j(MC,E),j(rn,b),j(Mo,y),j(LC,R),De(L))if(L.length){const V=e.exposed||(e.exposed={});L.forEach(X=>{Object.defineProperty(V,X,{get:()=>n[X],set:I=>n[X]=I})})}else e.exposed||(e.exposed={});C&&e.render===en&&(e.render=C),F!=null&&(e.inheritAttrs=F),N&&(e.components=N),A&&(e.directives=A)}function zC(e,t,n=en){De(e)&&(e=qc(e));for(const r in e){const o=e[r];let a;ht(o)?"default"in o?a=Re(o.from||r,o.default,!0):a=Re(o.from||r):a=Re(o),mt(a)?Object.defineProperty(t,r,{enumerable:!0,configurable:!0,get:()=>a.value,set:l=>a.value=l}):t[r]=a}}function rm(e,t,n){qn(De(e)?e.map(r=>r.bind(t.proxy)):e.bind(t.proxy),t,n)}function Ib(e,t,n,r){const o=r.includes(".")?Cb(n,r):()=>n[r];if(Ge(e)){const a=t[e];Ke(a)&&$e(o,a)}else if(Ke(e))$e(o,e.bind(n));else if(ht(e))if(De(e))e.forEach(a=>Ib(a,t,n,r));else{const a=Ke(e.handler)?e.handler.bind(n):t[e.handler];Ke(a)&&$e(o,a,e)}}function gf(e){const t=e.type,{mixins:n,extends:r}=t,{mixins:o,optionsCache:a,config:{optionMergeStrategies:l}}=e.appContext,s=a.get(t);let i;return s?i=s:!o.length&&!n&&!r?i=t:(i={},o.length&&o.forEach(u=>tu(i,u,l,!0)),tu(i,t,l)),ht(t)&&a.set(t,i),i}function tu(e,t,n,r=!1){const{mixins:o,extends:a}=t;a&&tu(e,a,n,!0),o&&o.forEach(l=>tu(e,l,n,!0));for(const l in t)if(!(r&&l==="expose")){const s=HC[l]||n&&n[l];e[l]=s?s(e[l],t[l]):t[l]}return e}const HC={data:om,props:am,emits:am,methods:Ll,computed:Ll,beforeCreate:gn,created:gn,beforeMount:gn,mounted:gn,beforeUpdate:gn,updated:gn,beforeDestroy:gn,beforeUnmount:gn,destroyed:gn,unmounted:gn,activated:gn,deactivated:gn,errorCaptured:gn,serverPrefetch:gn,components:Ll,directives:Ll,watch:WC,provide:om,inject:jC};function om(e,t){return t?e?function(){return Wt(Ke(e)?e.call(this,this):e,Ke(t)?t.call(this,this):t)}:t:e}function jC(e,t){return Ll(qc(e),qc(t))}function qc(e){if(De(e)){const t={};for(let n=0;n1)return n&&Ke(t)?t.call(r&&r.proxy):t}}function qC(e,t,n,r=!1){const o={},a={};Xi(a,Lu,1),e.propsDefaults=Object.create(null),Lb(e,t,o,a);for(const l in e.propsOptions[0])l in o||(o[l]=void 0);n?e.props=r?o:lf(o):e.type.props?e.props=o:e.props=a,e.attrs=a}function YC(e,t,n,r){const{props:o,attrs:a,vnode:{patchFlag:l}}=e,s=gt(o),[i]=e.propsOptions;let u=!1;if((r||l>0)&&!(l&16)){if(l&8){const d=e.vnode.dynamicProps;for(let f=0;f{i=!0;const[h,p]=Mb(f,t,!0);Wt(l,h),p&&s.push(...p)};!n&&t.mixins.length&&t.mixins.forEach(d),e.extends&&d(e.extends),e.mixins&&e.mixins.forEach(d)}if(!a&&!i)return ht(e)&&r.set(e,Na),Na;if(De(a))for(let d=0;d-1,p[1]=g<0||v-1||ft(p,"default"))&&s.push(f)}}}const u=[l,s];return ht(e)&&r.set(e,u),u}function lm(e){return e[0]!=="$"}function sm(e){const t=e&&e.toString().match(/^\s*(function|class) (\w+)/);return t?t[2]:e===null?"null":""}function im(e,t){return sm(e)===sm(t)}function um(e,t){return De(t)?t.findIndex(n=>im(n,e)):Ke(t)&&im(t,e)?0:-1}const Rb=e=>e[0]==="_"||e==="$stable",bf=e=>De(e)?e.map(or):[or(e)],GC=(e,t,n)=>{if(t._n)return t;const r=G((...o)=>bf(t(...o)),n);return r._c=!1,r},Nb=(e,t,n)=>{const r=e._ctx;for(const o in e){if(Rb(o))continue;const a=e[o];if(Ke(a))t[o]=GC(o,a,r);else if(a!=null){const l=bf(a);t[o]=()=>l}}},Db=(e,t)=>{const n=bf(t);e.slots.default=()=>n},XC=(e,t)=>{if(e.vnode.shapeFlag&32){const n=t._;n?(e.slots=gt(t),Xi(t,"_",n)):Nb(t,e.slots={})}else e.slots={},t&&Db(e,t);Xi(e.slots,Lu,1)},JC=(e,t,n)=>{const{vnode:r,slots:o}=e;let a=!0,l=Ft;if(r.shapeFlag&32){const s=t._;s?n&&s===1?a=!1:(Wt(o,t),!n&&s===1&&delete o._):(a=!t.$stable,Nb(t,o)),l=t}else t&&(Db(e,t),l={default:1});if(a)for(const s in o)!Rb(s)&&!(s in l)&&delete o[s]};function ru(e,t,n,r,o=!1){if(De(e)){e.forEach((h,p)=>ru(h,t&&(De(t)?t[p]:t),n,r,o));return}if(Ba(r)&&!o)return;const a=r.shapeFlag&4?Mu(r.component)||r.component.proxy:r.el,l=o?null:a,{i:s,r:i}=e,u=t&&t.r,d=s.refs===Ft?s.refs={}:s.refs,f=s.setupState;if(u!=null&&u!==i&&(Ge(u)?(d[u]=null,ft(f,u)&&(f[u]=null)):mt(u)&&(u.value=null)),Ke(i))Eo(i,s,12,[l,d]);else{const h=Ge(i),p=mt(i);if(h||p){const v=()=>{if(e.f){const g=h?ft(f,i)?f[i]:d[i]:i.value;o?De(g)&&Qd(g,a):De(g)?g.includes(a)||g.push(a):h?(d[i]=[a],ft(f,i)&&(f[i]=d[i])):(i.value=[a],e.k&&(d[e.k]=i.value))}else h?(d[i]=l,ft(f,i)&&(f[i]=l)):p&&(i.value=l,e.k&&(d[e.k]=l))};l?(v.id=-1,Tn(v,n)):v()}}}let io=!1;const Qs=e=>/svg/.test(e.namespaceURI)&&e.tagName!=="foreignObject",ei=e=>e.nodeType===8;function ZC(e){const{mt:t,p:n,o:{patchProp:r,createText:o,nextSibling:a,parentNode:l,remove:s,insert:i,createComment:u}}=e,d=(m,b)=>{if(!b.hasChildNodes()){n(null,m,b),Qi(),b._vnode=m;return}io=!1,f(b.firstChild,m,null,null,null),Qi(),b._vnode=m,io&&console.error("Hydration completed but contains mismatches.")},f=(m,b,_,y,C,k=!1)=>{const E=ei(m)&&m.data==="[",S=()=>g(m,b,_,y,C,E),{type:R,ref:L,shapeFlag:F,patchFlag:N}=b;let A=m.nodeType;b.el=m,N===-2&&(k=!1,b.dynamicChildren=null);let M=null;switch(R){case Gr:A!==3?b.children===""?(i(b.el=o(""),l(m),m),M=m):M=S():(m.data!==b.children&&(io=!0,m.data=b.children),M=a(m));break;case yn:A!==8||E?M=S():M=a(m);break;case Fl:if(E&&(m=a(m),A=m.nodeType),A===1||A===3){M=m;const H=!b.children.length;for(let j=0;j{k=k||!!b.dynamicChildren;const{type:E,props:S,patchFlag:R,shapeFlag:L,dirs:F}=b,N=E==="input"&&F||E==="option";if(N||R!==-1){if(F&&kr(b,null,_,"created"),S)if(N||!k||R&48)for(const M in S)(N&&M.endsWith("value")||$s(M)&&!Rl(M))&&r(m,M,null,S[M],!1,void 0,_);else S.onClick&&r(m,"onClick",null,S.onClick,!1,void 0,_);let A;if((A=S&&S.onVnodeBeforeMount)&&Un(A,_,b),F&&kr(b,null,_,"beforeMount"),((A=S&&S.onVnodeMounted)||F)&&wb(()=>{A&&Un(A,_,b),F&&kr(b,null,_,"mounted")},y),L&16&&!(S&&(S.innerHTML||S.textContent))){let M=p(m.firstChild,b,m,_,y,C,k);for(;M;){io=!0;const H=M;M=M.nextSibling,s(H)}}else L&8&&m.textContent!==b.children&&(io=!0,m.textContent=b.children)}return m.nextSibling},p=(m,b,_,y,C,k,E)=>{E=E||!!b.dynamicChildren;const S=b.children,R=S.length;for(let L=0;L{const{slotScopeIds:E}=b;E&&(C=C?C.concat(E):E);const S=l(m),R=p(a(m),b,S,_,y,C,k);return R&&ei(R)&&R.data==="]"?a(b.anchor=R):(io=!0,i(b.anchor=u("]"),S,R),R)},g=(m,b,_,y,C,k)=>{if(io=!0,b.el=null,k){const R=w(m);for(;;){const L=a(m);if(L&&L!==R)s(L);else break}}const E=a(m),S=l(m);return s(m),n(null,b,S,E,_,y,Qs(S),C),E},w=m=>{let b=0;for(;m;)if(m=a(m),m&&ei(m)&&(m.data==="["&&b++,m.data==="]")){if(b===0)return a(m);b--}return m};return[d,f]}const Tn=wb;function QC(e){return Fb(e)}function ek(e){return Fb(e,ZC)}function Fb(e,t){const n=Bc();n.__VUE__=!0;const{insert:r,remove:o,patchProp:a,createElement:l,createText:s,createComment:i,setText:u,setElementText:d,parentNode:f,nextSibling:h,setScopeId:p=en,insertStaticContent:v}=e,g=(P,$,T,z=null,Z=null,oe=null,_e=!1,we=null,he=!!$.dynamicChildren)=>{if(P===$)return;P&&!Yo(P,$)&&(z=J(P),W(P,Z,oe,!0),P=null),$.patchFlag===-2&&(he=!1,$.dynamicChildren=null);const{type:ke,ref:Me,shapeFlag:ne}=$;switch(ke){case Gr:w(P,$,T,z);break;case yn:m(P,$,T,z);break;case Fl:P==null&&b($,T,z,_e);break;case Pe:N(P,$,T,z,Z,oe,_e,we,he);break;default:ne&1?C(P,$,T,z,Z,oe,_e,we,he):ne&6?A(P,$,T,z,Z,oe,_e,we,he):(ne&64||ne&128)&&ke.process(P,$,T,z,Z,oe,_e,we,he,ae)}Me!=null&&Z&&ru(Me,P&&P.ref,oe,$||P,!$)},w=(P,$,T,z)=>{if(P==null)r($.el=s($.children),T,z);else{const Z=$.el=P.el;$.children!==P.children&&u(Z,$.children)}},m=(P,$,T,z)=>{P==null?r($.el=i($.children||""),T,z):$.el=P.el},b=(P,$,T,z)=>{[P.el,P.anchor]=v(P.children,$,T,z,P.el,P.anchor)},_=({el:P,anchor:$},T,z)=>{let Z;for(;P&&P!==$;)Z=h(P),r(P,T,z),P=Z;r($,T,z)},y=({el:P,anchor:$})=>{let T;for(;P&&P!==$;)T=h(P),o(P),P=T;o($)},C=(P,$,T,z,Z,oe,_e,we,he)=>{_e=_e||$.type==="svg",P==null?k($,T,z,Z,oe,_e,we,he):R(P,$,Z,oe,_e,we,he)},k=(P,$,T,z,Z,oe,_e,we)=>{let he,ke;const{type:Me,props:ne,shapeFlag:ue,transition:ie,dirs:Oe}=P;if(he=P.el=l(P.type,oe,ne&&ne.is,ne),ue&8?d(he,P.children):ue&16&&S(P.children,he,null,z,Z,oe&&Me!=="foreignObject",_e,we),Oe&&kr(P,null,z,"created"),E(he,P,P.scopeId,_e,z),ne){for(const Xe in ne)Xe!=="value"&&!Rl(Xe)&&a(he,Xe,null,ne[Xe],oe,P.children,z,Z,ge);"value"in ne&&a(he,"value",null,ne.value),(ke=ne.onVnodeBeforeMount)&&Un(ke,z,P)}Oe&&kr(P,null,z,"beforeMount");const We=(!Z||Z&&!Z.pendingBranch)&&ie&&!ie.persisted;We&&ie.beforeEnter(he),r(he,$,T),((ke=ne&&ne.onVnodeMounted)||We||Oe)&&Tn(()=>{ke&&Un(ke,z,P),We&&ie.enter(he),Oe&&kr(P,null,z,"mounted")},Z)},E=(P,$,T,z,Z)=>{if(T&&p(P,T),z)for(let oe=0;oe{for(let ke=he;ke{const we=$.el=P.el;let{patchFlag:he,dynamicChildren:ke,dirs:Me}=$;he|=P.patchFlag&16;const ne=P.props||Ft,ue=$.props||Ft;let ie;T&&Bo(T,!1),(ie=ue.onVnodeBeforeUpdate)&&Un(ie,T,$,P),Me&&kr($,P,T,"beforeUpdate"),T&&Bo(T,!0);const Oe=Z&&$.type!=="foreignObject";if(ke?L(P.dynamicChildren,ke,we,T,z,Oe,oe):_e||X(P,$,we,null,T,z,Oe,oe,!1),he>0){if(he&16)F(we,$,ne,ue,T,z,Z);else if(he&2&&ne.class!==ue.class&&a(we,"class",null,ue.class,Z),he&4&&a(we,"style",ne.style,ue.style,Z),he&8){const We=$.dynamicProps;for(let Xe=0;Xe{ie&&Un(ie,T,$,P),Me&&kr($,P,T,"updated")},z)},L=(P,$,T,z,Z,oe,_e)=>{for(let we=0;we<$.length;we++){const he=P[we],ke=$[we],Me=he.el&&(he.type===Pe||!Yo(he,ke)||he.shapeFlag&70)?f(he.el):T;g(he,ke,Me,null,z,Z,oe,_e,!0)}},F=(P,$,T,z,Z,oe,_e)=>{if(T!==z){if(T!==Ft)for(const we in T)!Rl(we)&&!(we in z)&&a(P,we,T[we],null,_e,$.children,Z,oe,ge);for(const we in z){if(Rl(we))continue;const he=z[we],ke=T[we];he!==ke&&we!=="value"&&a(P,we,ke,he,_e,$.children,Z,oe,ge)}"value"in z&&a(P,"value",T.value,z.value)}},N=(P,$,T,z,Z,oe,_e,we,he)=>{const ke=$.el=P?P.el:s(""),Me=$.anchor=P?P.anchor:s("");let{patchFlag:ne,dynamicChildren:ue,slotScopeIds:ie}=$;ie&&(we=we?we.concat(ie):ie),P==null?(r(ke,T,z),r(Me,T,z),S($.children,T,Me,Z,oe,_e,we,he)):ne>0&&ne&64&&ue&&P.dynamicChildren?(L(P.dynamicChildren,ue,T,Z,oe,_e,we),($.key!=null||Z&&$===Z.subTree)&&yf(P,$,!0)):X(P,$,T,Me,Z,oe,_e,we,he)},A=(P,$,T,z,Z,oe,_e,we,he)=>{$.slotScopeIds=we,P==null?$.shapeFlag&512?Z.ctx.activate($,T,z,_e,he):M($,T,z,Z,oe,_e,he):H(P,$,he)},M=(P,$,T,z,Z,oe,_e)=>{const we=P.component=uk(P,z,Z);if(Os(P)&&(we.ctx.renderer=ae),ck(we),we.asyncDep){if(Z&&Z.registerDep(we,j),!P.el){const he=we.subTree=Q(yn);m(null,he,$,T)}return}j(we,P,$,T,Z,oe,_e)},H=(P,$,T)=>{const z=$.component=P.component;if(SC(P,$,T))if(z.asyncDep&&!z.asyncResolved){V(z,$,T);return}else z.next=$,vC(z.update),z.update();else $.el=P.el,z.vnode=$},j=(P,$,T,z,Z,oe,_e)=>{const we=()=>{if(P.isMounted){let{next:Me,bu:ne,u:ue,parent:ie,vnode:Oe}=P,We=Me,Xe;Bo(P,!1),Me?(Me.el=Oe.el,V(P,Me,_e)):Me=Oe,ne&&xi(ne),(Xe=Me.props&&Me.props.onVnodeBeforeUpdate)&&Un(Xe,ie,Me,Oe),Bo(P,!0);const fe=ac(P),ve=P.subTree;P.subTree=fe,g(ve,fe,f(ve.el),J(ve),P,Z,oe),Me.el=fe.el,We===null&&EC(P,fe.el),ue&&Tn(ue,Z),(Xe=Me.props&&Me.props.onVnodeUpdated)&&Tn(()=>Un(Xe,ie,Me,Oe),Z)}else{let Me;const{el:ne,props:ue}=$,{bm:ie,m:Oe,parent:We}=P,Xe=Ba($);if(Bo(P,!1),ie&&xi(ie),!Xe&&(Me=ue&&ue.onVnodeBeforeMount)&&Un(Me,We,$),Bo(P,!0),ne&&me){const fe=()=>{P.subTree=ac(P),me(ne,P.subTree,P,Z,null)};Xe?$.type.__asyncLoader().then(()=>!P.isUnmounted&&fe()):fe()}else{const fe=P.subTree=ac(P);g(null,fe,T,z,P,Z,oe),$.el=fe.el}if(Oe&&Tn(Oe,Z),!Xe&&(Me=ue&&ue.onVnodeMounted)){const fe=$;Tn(()=>Un(Me,We,fe),Z)}($.shapeFlag&256||We&&Ba(We.vnode)&&We.vnode.shapeFlag&256)&&P.a&&Tn(P.a,Z),P.isMounted=!0,$=T=z=null}},he=P.effect=new nf(we,()=>xu(ke),P.scope),ke=P.update=()=>he.run();ke.id=P.uid,Bo(P,!0),ke()},V=(P,$,T)=>{$.component=P;const z=P.vnode.props;P.vnode=$,P.next=null,YC(P,$.props,z,T),JC(P,$.children,T),dl(),Zp(),fl()},X=(P,$,T,z,Z,oe,_e,we,he=!1)=>{const ke=P&&P.children,Me=P?P.shapeFlag:0,ne=$.children,{patchFlag:ue,shapeFlag:ie}=$;if(ue>0){if(ue&128){Y(ke,ne,T,z,Z,oe,_e,we,he);return}else if(ue&256){I(ke,ne,T,z,Z,oe,_e,we,he);return}}ie&8?(Me&16&&ge(ke,Z,oe),ne!==ke&&d(T,ne)):Me&16?ie&16?Y(ke,ne,T,z,Z,oe,_e,we,he):ge(ke,Z,oe,!0):(Me&8&&d(T,""),ie&16&&S(ne,T,z,Z,oe,_e,we,he))},I=(P,$,T,z,Z,oe,_e,we,he)=>{P=P||Na,$=$||Na;const ke=P.length,Me=$.length,ne=Math.min(ke,Me);let ue;for(ue=0;ueMe?ge(P,Z,oe,!0,!1,ne):S($,T,z,Z,oe,_e,we,he,ne)},Y=(P,$,T,z,Z,oe,_e,we,he)=>{let ke=0;const Me=$.length;let ne=P.length-1,ue=Me-1;for(;ke<=ne&&ke<=ue;){const ie=P[ke],Oe=$[ke]=he?go($[ke]):or($[ke]);if(Yo(ie,Oe))g(ie,Oe,T,null,Z,oe,_e,we,he);else break;ke++}for(;ke<=ne&&ke<=ue;){const ie=P[ne],Oe=$[ue]=he?go($[ue]):or($[ue]);if(Yo(ie,Oe))g(ie,Oe,T,null,Z,oe,_e,we,he);else break;ne--,ue--}if(ke>ne){if(ke<=ue){const ie=ue+1,Oe=ieue)for(;ke<=ne;)W(P[ke],Z,oe,!0),ke++;else{const ie=ke,Oe=ke,We=new Map;for(ke=Oe;ke<=ue;ke++){const q=$[ke]=he?go($[ke]):or($[ke]);q.key!=null&&We.set(q.key,ke)}let Xe,fe=0;const ve=ue-Oe+1;let Ce=!1,Ye=0;const Se=new Array(ve);for(ke=0;ke=ve){W(q,Z,oe,!0);continue}let Ie;if(q.key!=null)Ie=We.get(q.key);else for(Xe=Oe;Xe<=ue;Xe++)if(Se[Xe-Oe]===0&&Yo(q,$[Xe])){Ie=Xe;break}Ie===void 0?W(q,Z,oe,!0):(Se[Ie-Oe]=ke+1,Ie>=Ye?Ye=Ie:Ce=!0,g(q,$[Ie],T,null,Z,oe,_e,we,he),fe++)}const Ae=Ce?tk(Se):Na;for(Xe=Ae.length-1,ke=ve-1;ke>=0;ke--){const q=Oe+ke,Ie=$[q],et=q+1{const{el:oe,type:_e,transition:we,children:he,shapeFlag:ke}=P;if(ke&6){ee(P.component.subTree,$,T,z);return}if(ke&128){P.suspense.move($,T,z);return}if(ke&64){_e.move(P,$,T,ae);return}if(_e===Pe){r(oe,$,T);for(let ne=0;newe.enter(oe),Z);else{const{leave:ne,delayLeave:ue,afterLeave:ie}=we,Oe=()=>r(oe,$,T),We=()=>{ne(oe,()=>{Oe(),ie&&ie()})};ue?ue(oe,Oe,We):We()}else r(oe,$,T)},W=(P,$,T,z=!1,Z=!1)=>{const{type:oe,props:_e,ref:we,children:he,dynamicChildren:ke,shapeFlag:Me,patchFlag:ne,dirs:ue}=P;if(we!=null&&ru(we,null,T,P,!0),Me&256){$.ctx.deactivate(P);return}const ie=Me&1&&ue,Oe=!Ba(P);let We;if(Oe&&(We=_e&&_e.onVnodeBeforeUnmount)&&Un(We,$,P),Me&6)Te(P.component,T,z);else{if(Me&128){P.suspense.unmount(T,z);return}ie&&kr(P,null,$,"beforeUnmount"),Me&64?P.type.remove(P,$,T,Z,ae,z):ke&&(oe!==Pe||ne>0&&ne&64)?ge(ke,$,T,!1,!0):(oe===Pe&&ne&384||!Z&&Me&16)&&ge(he,$,T),z&&re(P)}(Oe&&(We=_e&&_e.onVnodeUnmounted)||ie)&&Tn(()=>{We&&Un(We,$,P),ie&&kr(P,null,$,"unmounted")},T)},re=P=>{const{type:$,el:T,anchor:z,transition:Z}=P;if($===Pe){be(T,z);return}if($===Fl){y(P);return}const oe=()=>{o(T),Z&&!Z.persisted&&Z.afterLeave&&Z.afterLeave()};if(P.shapeFlag&1&&Z&&!Z.persisted){const{leave:_e,delayLeave:we}=Z,he=()=>_e(T,oe);we?we(P.el,oe,he):he()}else oe()},be=(P,$)=>{let T;for(;P!==$;)T=h(P),o(P),P=T;o($)},Te=(P,$,T)=>{const{bum:z,scope:Z,update:oe,subTree:_e,um:we}=P;z&&xi(z),Z.stop(),oe&&(oe.active=!1,W(_e,P,$,T)),we&&Tn(we,$),Tn(()=>{P.isUnmounted=!0},$),$&&$.pendingBranch&&!$.isUnmounted&&P.asyncDep&&!P.asyncResolved&&P.suspenseId===$.pendingId&&($.deps--,$.deps===0&&$.resolve())},ge=(P,$,T,z=!1,Z=!1,oe=0)=>{for(let _e=oe;_eP.shapeFlag&6?J(P.component.subTree):P.shapeFlag&128?P.suspense.next():h(P.anchor||P.el),te=(P,$,T)=>{P==null?$._vnode&&W($._vnode,null,null,!0):g($._vnode||null,P,$,null,null,null,T),Zp(),Qi(),$._vnode=P},ae={p:g,um:W,m:ee,r:re,mt:M,mc:S,pc:X,pbc:L,n:J,o:e};let le,me;return t&&([le,me]=t(ae)),{render:te,hydrate:le,createApp:KC(te,le)}}function Bo({effect:e,update:t},n){e.allowRecurse=t.allowRecurse=n}function yf(e,t,n=!1){const r=e.children,o=t.children;if(De(r)&&De(o))for(let a=0;a>1,e[n[s]]0&&(t[r]=n[a-1]),n[a]=r)}}for(a=n.length,l=n[a-1];a-- >0;)n[a]=l,l=t[l];return n}const nk=e=>e.__isTeleport,Dl=e=>e&&(e.disabled||e.disabled===""),cm=e=>typeof SVGElement!="undefined"&&e instanceof SVGElement,Gc=(e,t)=>{const n=e&&e.to;return Ge(n)?t?t(n):null:n},rk={__isTeleport:!0,process(e,t,n,r,o,a,l,s,i,u){const{mc:d,pc:f,pbc:h,o:{insert:p,querySelector:v,createText:g,createComment:w}}=u,m=Dl(t.props);let{shapeFlag:b,children:_,dynamicChildren:y}=t;if(e==null){const C=t.el=g(""),k=t.anchor=g("");p(C,n,r),p(k,n,r);const E=t.target=Gc(t.props,v),S=t.targetAnchor=g("");E&&(p(S,E),l=l||cm(E));const R=(L,F)=>{b&16&&d(_,L,F,o,a,l,s,i)};m?R(n,k):E&&R(E,S)}else{t.el=e.el;const C=t.anchor=e.anchor,k=t.target=e.target,E=t.targetAnchor=e.targetAnchor,S=Dl(e.props),R=S?n:k,L=S?C:E;if(l=l||cm(k),y?(h(e.dynamicChildren,y,R,o,a,l,s),yf(e,t,!0)):i||f(e,t,R,L,o,a,l,s,!1),m)S||ti(t,n,C,u,1);else if((t.props&&t.props.to)!==(e.props&&e.props.to)){const F=t.target=Gc(t.props,v);F&&ti(t,F,null,u,0)}else S&&ti(t,k,E,u,1)}Bb(t)},remove(e,t,n,r,{um:o,o:{remove:a}},l){const{shapeFlag:s,children:i,anchor:u,targetAnchor:d,target:f,props:h}=e;if(f&&a(d),(l||!Dl(h))&&(a(u),s&16))for(let p=0;p0?sr||Na:null,ak(),as>0&&sr&&sr.push(e),e}function U(e,t,n,r,o,a){return zb(K(e,t,n,r,o,a,!0))}function ce(e,t,n,r,o){return zb(Q(e,t,n,r,o,!0))}function Ua(e){return e?e.__v_isVNode===!0:!1}function Yo(e,t){return e.type===t.type&&e.key===t.key}const Lu="__vInternal",Hb=({key:e})=>e!=null?e:null,Oi=({ref:e,ref_key:t,ref_for:n})=>(typeof e=="number"&&(e=""+e),e!=null?Ge(e)||mt(e)||Ke(e)?{i:sn,r:e,k:t,f:!!n}:e:null);function K(e,t=null,n=null,r=0,o=null,a=e===Pe?0:1,l=!1,s=!1){const i={__v_isVNode:!0,__v_skip:!0,type:e,props:t,key:t&&Hb(t),ref:t&&Oi(t),scopeId:Au,slotScopeIds:null,children:n,component:null,suspense:null,ssContent:null,ssFallback:null,dirs:null,transition:null,el:null,anchor:null,target:null,targetAnchor:null,staticCount:0,shapeFlag:a,patchFlag:r,dynamicProps:o,dynamicChildren:null,appContext:null,ctx:sn};return s?(_f(i,n),a&128&&e.normalize(i)):n&&(i.shapeFlag|=Ge(n)?8:16),as>0&&!l&&sr&&(i.patchFlag>0||a&6)&&i.patchFlag!==32&&sr.push(i),i}const Q=lk;function lk(e,t=null,n=null,r=0,o=null,a=!1){if((!e||e===xb)&&(e=yn),Ua(e)){const s=Xr(e,t,!0);return n&&_f(s,n),as>0&&!a&&sr&&(s.shapeFlag&6?sr[sr.indexOf(e)]=s:sr.push(s)),s.patchFlag|=-2,s}if(mk(e)&&(e=e.__vccOpts),t){t=jb(t);let{class:s,style:i}=t;s&&!Ge(s)&&(t.class=D(s)),ht(i)&&(cb(i)&&!De(i)&&(i=Wt({},i)),t.style=Qe(i))}const l=Ge(e)?1:$C(e)?128:nk(e)?64:ht(e)?4:Ke(e)?2:0;return K(e,t,n,r,o,l,a,!0)}function jb(e){return e?cb(e)||Lu in e?Wt({},e):e:null}function Xr(e,t,n=!1){const{props:r,ref:o,patchFlag:a,children:l}=e,s=t?Ht(r||{},t):r;return{__v_isVNode:!0,__v_skip:!0,type:e.type,props:s,key:s&&Hb(s),ref:t&&t.ref?n&&o?De(o)?o.concat(Oi(t)):[o,Oi(t)]:Oi(t):o,scopeId:e.scopeId,slotScopeIds:e.slotScopeIds,children:l,target:e.target,targetAnchor:e.targetAnchor,staticCount:e.staticCount,shapeFlag:e.shapeFlag,patchFlag:t&&e.type!==Pe?a===-1?16:a|16:a,dynamicProps:e.dynamicProps,dynamicChildren:e.dynamicChildren,appContext:e.appContext,dirs:e.dirs,transition:e.transition,component:e.component,suspense:e.suspense,ssContent:e.ssContent&&Xr(e.ssContent),ssFallback:e.ssFallback&&Xr(e.ssFallback),el:e.el,anchor:e.anchor,ctx:e.ctx,ce:e.ce}}function Je(e=" ",t=0){return Q(Gr,null,e,t)}function dG(e,t){const n=Q(Fl,null,e);return n.staticCount=t,n}function ye(e="",t=!1){return t?(x(),ce(yn,null,e)):Q(yn,null,e)}function or(e){return e==null||typeof e=="boolean"?Q(yn):De(e)?Q(Pe,null,e.slice()):typeof e=="object"?go(e):Q(Gr,null,String(e))}function go(e){return e.el===null&&e.patchFlag!==-1||e.memo?e:Xr(e)}function _f(e,t){let n=0;const{shapeFlag:r}=e;if(t==null)t=null;else if(De(t))n=16;else if(typeof t=="object")if(r&65){const o=t.default;o&&(o._c&&(o._d=!1),_f(e,o()),o._c&&(o._d=!0));return}else{n=32;const o=t._;!o&&!(Lu in t)?t._ctx=sn:o===3&&sn&&(sn.slots._===1?t._=1:(t._=2,e.patchFlag|=1024))}else Ke(t)?(t={default:t,_ctx:sn},n=32):(t=String(t),r&64?(n=16,t=[Je(t)]):n=8);e.children=t,e.shapeFlag|=n}function Ht(...e){const t={};for(let n=0;nZt||sn;let wf,Sa,fm="__VUE_INSTANCE_SETTERS__";(Sa=Bc()[fm])||(Sa=Bc()[fm]=[]),Sa.push(e=>Zt=e),wf=e=>{Sa.length>1?Sa.forEach(t=>t(e)):Sa[0](e)};const Ka=e=>{wf(e),e.scope.on()},ra=()=>{Zt&&Zt.scope.off(),wf(null)};function Wb(e){return e.vnode.shapeFlag&4}let qa=!1;function ck(e,t=!1){qa=t;const{props:n,children:r}=e.vnode,o=Wb(e);qC(e,n,o,t),XC(e,r);const a=o?dk(e,t):void 0;return qa=!1,a}function dk(e,t){const n=e.type;e.accessCache=Object.create(null),e.proxy=db(new Proxy(e.ctx,VC));const{setup:r}=n;if(r){const o=e.setupContext=r.length>1?Kb(e):null;Ka(e),dl();const a=Eo(r,e,0,[e.props,o]);if(fl(),ra(),Gi(a)){if(a.then(ra,ra),t)return a.then(l=>{pm(e,l,t)}).catch(l=>{xs(l,e,0)});e.asyncDep=a}else pm(e,a,t)}else Ub(e,t)}function pm(e,t,n){Ke(t)?e.type.__ssrInlineRender?e.ssrRender=t:e.render=t:ht(t)&&(e.setupState=mb(t)),Ub(e,n)}let mm;function Ub(e,t,n){const r=e.type;if(!e.render){if(!t&&mm&&!r.render){const o=r.template||gf(e).template;if(o){const{isCustomElement:a,compilerOptions:l}=e.appContext.config,{delimiters:s,compilerOptions:i}=r,u=Wt(Wt({isCustomElement:a,delimiters:s},l),i);r.render=mm(o,u)}}e.render=r.render||en}Ka(e),dl(),BC(e),fl(),ra()}function fk(e){return e.attrsProxy||(e.attrsProxy=new Proxy(e.attrs,{get(t,n){return Ln(e,"get","$attrs"),t[n]}}))}function Kb(e){const t=n=>{e.exposed=n||{}};return{get attrs(){return fk(e)},slots:e.slots,emit:e.emit,expose:t}}function Mu(e){if(e.exposed)return e.exposeProxy||(e.exposeProxy=new Proxy(mb(db(e.exposed)),{get(t,n){if(n in t)return t[n];if(n in Nl)return Nl[n](e)},has(t,n){return n in t||n in Nl}}))}function pk(e,t=!0){return Ke(e)?e.displayName||e.name:e.name||t&&e.__name}function mk(e){return Ke(e)&&"__vccOpts"in e}const O=(e,t)=>vb(e,t,qa);function He(e,t,n){const r=arguments.length;return r===2?ht(t)&&!De(t)?Ua(t)?Q(e,null,[t]):Q(e,t):Q(e,null,t):(r>3?n=Array.prototype.slice.call(arguments,2):r===3&&Ua(n)&&(n=[n]),Q(e,t,n))}const hk=Symbol.for("v-scx"),vk=()=>Re(hk),qb="3.3.4",gk="http://www.w3.org/2000/svg",Go=typeof document!="undefined"?document:null,hm=Go&&Go.createElement("template"),bk={insert:(e,t,n)=>{t.insertBefore(e,n||null)},remove:e=>{const t=e.parentNode;t&&t.removeChild(e)},createElement:(e,t,n,r)=>{const o=t?Go.createElementNS(gk,e):Go.createElement(e,n?{is:n}:void 0);return e==="select"&&r&&r.multiple!=null&&o.setAttribute("multiple",r.multiple),o},createText:e=>Go.createTextNode(e),createComment:e=>Go.createComment(e),setText:(e,t)=>{e.nodeValue=t},setElementText:(e,t)=>{e.textContent=t},parentNode:e=>e.parentNode,nextSibling:e=>e.nextSibling,querySelector:e=>Go.querySelector(e),setScopeId(e,t){e.setAttribute(t,"")},insertStaticContent(e,t,n,r,o,a){const l=n?n.previousSibling:t.lastChild;if(o&&(o===a||o.nextSibling))for(;t.insertBefore(o.cloneNode(!0),n),!(o===a||!(o=o.nextSibling)););else{hm.innerHTML=r?`${e}`:e;const s=hm.content;if(r){const i=s.firstChild;for(;i.firstChild;)s.appendChild(i.firstChild);s.removeChild(i)}t.insertBefore(s,n)}return[l?l.nextSibling:t.firstChild,n?n.previousSibling:t.lastChild]}};function yk(e,t,n){const r=e._vtc;r&&(t=(t?[t,...r]:[...r]).join(" ")),t==null?e.removeAttribute("class"):n?e.setAttribute("class",t):e.className=t}function _k(e,t,n){const r=e.style,o=Ge(n);if(n&&!o){if(t&&!Ge(t))for(const a in t)n[a]==null&&Xc(r,a,"");for(const a in n)Xc(r,a,n[a])}else{const a=r.display;o?t!==n&&(r.cssText=n):t&&e.removeAttribute("style"),"_vod"in e&&(r.display=a)}}const vm=/\s*!important$/;function Xc(e,t,n){if(De(n))n.forEach(r=>Xc(e,t,r));else if(n==null&&(n=""),t.startsWith("--"))e.setProperty(t,n);else{const r=wk(e,t);vm.test(n)?e.setProperty(fa(r),n.replace(vm,""),"important"):e[r]=n}}const gm=["Webkit","Moz","ms"],uc={};function wk(e,t){const n=uc[t];if(n)return n;let r=cr(t);if(r!=="filter"&&r in e)return uc[t]=r;r=$u(r);for(let o=0;occ||(Tk.then(()=>cc=0),cc=Date.now());function Ok(e,t){const n=r=>{if(!r._vts)r._vts=Date.now();else if(r._vts<=n.attached)return;qn(Ak(r,n.value),t,5,[r])};return n.value=e,n.attached=xk(),n}function Ak(e,t){if(De(t)){const n=e.stopImmediatePropagation;return e.stopImmediatePropagation=()=>{n.call(e),e._stopped=!0},t.map(r=>o=>!o._stopped&&r&&r(o))}else return t}const _m=/^on[a-z]/,Ik=(e,t,n,r,o=!1,a,l,s,i)=>{t==="class"?yk(e,r,o):t==="style"?_k(e,n,r):$s(t)?Zd(t)||Ek(e,t,n,r,l):(t[0]==="."?(t=t.slice(1),!0):t[0]==="^"?(t=t.slice(1),!1):Pk(e,t,r,o))?kk(e,t,r,a,l,s,i):(t==="true-value"?e._trueValue=r:t==="false-value"&&(e._falseValue=r),Ck(e,t,r,o))};function Pk(e,t,n,r){return r?!!(t==="innerHTML"||t==="textContent"||t in e&&_m.test(t)&&Ke(n)):t==="spellcheck"||t==="draggable"||t==="translate"||t==="form"||t==="list"&&e.tagName==="INPUT"||t==="type"&&e.tagName==="TEXTAREA"||_m.test(t)&&Ge(n)?!1:t in e}const uo="transition",kl="animation",Mn=(e,{slots:t})=>He(OC,Gb(e),t);Mn.displayName="Transition";const Yb={name:String,type:String,css:{type:Boolean,default:!0},duration:[String,Number,Object],enterFromClass:String,enterActiveClass:String,enterToClass:String,appearFromClass:String,appearActiveClass:String,appearToClass:String,leaveFromClass:String,leaveActiveClass:String,leaveToClass:String},Lk=Mn.props=Wt({},Sb,Yb),zo=(e,t=[])=>{De(e)?e.forEach(n=>n(...t)):e&&e(...t)},wm=e=>e?De(e)?e.some(t=>t.length>1):e.length>1:!1;function Gb(e){const t={};for(const N in e)N in Yb||(t[N]=e[N]);if(e.css===!1)return t;const{name:n="v",type:r,duration:o,enterFromClass:a=`${n}-enter-from`,enterActiveClass:l=`${n}-enter-active`,enterToClass:s=`${n}-enter-to`,appearFromClass:i=a,appearActiveClass:u=l,appearToClass:d=s,leaveFromClass:f=`${n}-leave-from`,leaveActiveClass:h=`${n}-leave-active`,leaveToClass:p=`${n}-leave-to`}=e,v=Mk(o),g=v&&v[0],w=v&&v[1],{onBeforeEnter:m,onEnter:b,onEnterCancelled:_,onLeave:y,onLeaveCancelled:C,onBeforeAppear:k=m,onAppear:E=b,onAppearCancelled:S=_}=t,R=(N,A,M)=>{mo(N,A?d:s),mo(N,A?u:l),M&&M()},L=(N,A)=>{N._isLeaving=!1,mo(N,f),mo(N,p),mo(N,h),A&&A()},F=N=>(A,M)=>{const H=N?E:b,j=()=>R(A,N,M);zo(H,[A,j]),Cm(()=>{mo(A,N?i:a),Fr(A,N?d:s),wm(H)||km(A,r,g,j)})};return Wt(t,{onBeforeEnter(N){zo(m,[N]),Fr(N,a),Fr(N,l)},onBeforeAppear(N){zo(k,[N]),Fr(N,i),Fr(N,u)},onEnter:F(!1),onAppear:F(!0),onLeave(N,A){N._isLeaving=!0;const M=()=>L(N,A);Fr(N,f),Jb(),Fr(N,h),Cm(()=>{!N._isLeaving||(mo(N,f),Fr(N,p),wm(y)||km(N,r,w,M))}),zo(y,[N,M])},onEnterCancelled(N){R(N,!1),zo(_,[N])},onAppearCancelled(N){R(N,!0),zo(S,[N])},onLeaveCancelled(N){L(N),zo(C,[N])}})}function Mk(e){if(e==null)return null;if(ht(e))return[dc(e.enter),dc(e.leave)];{const t=dc(e);return[t,t]}}function dc(e){return S2(e)}function Fr(e,t){t.split(/\s+/).forEach(n=>n&&e.classList.add(n)),(e._vtc||(e._vtc=new Set)).add(t)}function mo(e,t){t.split(/\s+/).forEach(r=>r&&e.classList.remove(r));const{_vtc:n}=e;n&&(n.delete(t),n.size||(e._vtc=void 0))}function Cm(e){requestAnimationFrame(()=>{requestAnimationFrame(e)})}let Rk=0;function km(e,t,n,r){const o=e._endId=++Rk,a=()=>{o===e._endId&&r()};if(n)return setTimeout(a,n);const{type:l,timeout:s,propCount:i}=Xb(e,t);if(!l)return r();const u=l+"end";let d=0;const f=()=>{e.removeEventListener(u,h),a()},h=p=>{p.target===e&&++d>=i&&f()};setTimeout(()=>{d(n[v]||"").split(", "),o=r(`${uo}Delay`),a=r(`${uo}Duration`),l=Sm(o,a),s=r(`${kl}Delay`),i=r(`${kl}Duration`),u=Sm(s,i);let d=null,f=0,h=0;t===uo?l>0&&(d=uo,f=l,h=a.length):t===kl?u>0&&(d=kl,f=u,h=i.length):(f=Math.max(l,u),d=f>0?l>u?uo:kl:null,h=d?d===uo?a.length:i.length:0);const p=d===uo&&/\b(transform|all)(,|$)/.test(r(`${uo}Property`).toString());return{type:d,timeout:f,propCount:h,hasTransform:p}}function Sm(e,t){for(;e.lengthEm(n)+Em(e[r])))}function Em(e){return Number(e.slice(0,-1).replace(",","."))*1e3}function Jb(){return document.body.offsetHeight}const Zb=new WeakMap,Qb=new WeakMap,e0={name:"TransitionGroup",props:Wt({},Lk,{tag:String,moveClass:String}),setup(e,{slots:t}){const n=lt(),r=kb();let o,a;return pl(()=>{if(!o.length)return;const l=e.moveClass||`${e.name||"v"}-move`;if(!zk(o[0].el,n.vnode.el,l))return;o.forEach(Fk),o.forEach(Vk);const s=o.filter(Bk);Jb(),s.forEach(i=>{const u=i.el,d=u.style;Fr(u,l),d.transform=d.webkitTransform=d.transitionDuration="";const f=u._moveCb=h=>{h&&h.target!==u||(!h||/transform$/.test(h.propertyName))&&(u.removeEventListener("transitionend",f),u._moveCb=null,mo(u,l))};u.addEventListener("transitionend",f)})}),()=>{const l=gt(e),s=Gb(l);let i=l.tag||Pe;o=a,a=t.default?pf(t.default()):[];for(let u=0;udelete e.mode;e0.props;const Dk=e0;function Fk(e){const t=e.el;t._moveCb&&t._moveCb(),t._enterCb&&t._enterCb()}function Vk(e){Qb.set(e,e.el.getBoundingClientRect())}function Bk(e){const t=Zb.get(e),n=Qb.get(e),r=t.left-n.left,o=t.top-n.top;if(r||o){const a=e.el.style;return a.transform=a.webkitTransform=`translate(${r}px,${o}px)`,a.transitionDuration="0s",e}}function zk(e,t,n){const r=e.cloneNode();e._vtc&&e._vtc.forEach(l=>{l.split(/\s+/).forEach(s=>s&&r.classList.remove(s))}),n.split(/\s+/).forEach(l=>l&&r.classList.add(l)),r.style.display="none";const o=t.nodeType===1?t:t.parentNode;o.appendChild(r);const{hasTransform:a}=Xb(r);return o.removeChild(r),a}const Ya=e=>{const t=e.props["onUpdate:modelValue"]||!1;return De(t)?n=>xi(t,n):t};function Hk(e){e.target.composing=!0}function $m(e){const t=e.target;t.composing&&(t.composing=!1,t.dispatchEvent(new Event("input")))}const t0={created(e,{modifiers:{lazy:t,trim:n,number:r}},o){e._assign=Ya(o);const a=r||o.props&&o.props.type==="number";_o(e,t?"change":"input",l=>{if(l.target.composing)return;let s=e.value;n&&(s=s.trim()),a&&(s=Vc(s)),e._assign(s)}),n&&_o(e,"change",()=>{e.value=e.value.trim()}),t||(_o(e,"compositionstart",Hk),_o(e,"compositionend",$m),_o(e,"change",$m))},mounted(e,{value:t}){e.value=t==null?"":t},beforeUpdate(e,{value:t,modifiers:{lazy:n,trim:r,number:o}},a){if(e._assign=Ya(a),e.composing||document.activeElement===e&&e.type!=="range"&&(n||r&&e.value.trim()===t||(o||e.type==="number")&&Vc(e.value)===t))return;const l=t==null?"":t;e.value!==l&&(e.value=l)}},ou={deep:!0,created(e,t,n){e._assign=Ya(n),_o(e,"change",()=>{const r=e._modelValue,o=r0(e),a=e.checked,l=e._assign;if(De(r)){const s=Gg(r,o),i=s!==-1;if(a&&!i)l(r.concat(o));else if(!a&&i){const u=[...r];u.splice(s,1),l(u)}}else if(Su(r)){const s=new Set(r);a?s.add(o):s.delete(o),l(s)}else l(o0(e,a))})},mounted:Tm,beforeUpdate(e,t,n){e._assign=Ya(n),Tm(e,t,n)}};function Tm(e,{value:t,oldValue:n},r){e._modelValue=t,De(t)?e.checked=Gg(t,r.props.value)>-1:Su(t)?e.checked=t.has(r.props.value):t!==n&&(e.checked=ja(t,o0(e,!0)))}const n0={created(e,{value:t},n){e.checked=ja(t,n.props.value),e._assign=Ya(n),_o(e,"change",()=>{e._assign(r0(e))})},beforeUpdate(e,{value:t,oldValue:n},r){e._assign=Ya(r),t!==n&&(e.checked=ja(t,r.props.value))}};function r0(e){return"_value"in e?e._value:e.value}function o0(e,t){const n=t?"_trueValue":"_falseValue";return n in e?e[n]:t}const jk=["ctrl","shift","alt","meta"],Wk={stop:e=>e.stopPropagation(),prevent:e=>e.preventDefault(),self:e=>e.target!==e.currentTarget,ctrl:e=>!e.ctrlKey,shift:e=>!e.shiftKey,alt:e=>!e.altKey,meta:e=>!e.metaKey,left:e=>"button"in e&&e.button!==0,middle:e=>"button"in e&&e.button!==1,right:e=>"button"in e&&e.button!==2,exact:(e,t)=>jk.some(n=>e[`${n}Key`]&&!t.includes(n))},$t=(e,t)=>(n,...r)=>{for(let o=0;on=>{if(!("key"in n))return;const r=fa(n.key);if(t.some(o=>o===r||Uk[o]===r))return e(n)},qt={beforeMount(e,{value:t},{transition:n}){e._vod=e.style.display==="none"?"":e.style.display,n&&t?n.beforeEnter(e):Sl(e,t)},mounted(e,{value:t},{transition:n}){n&&t&&n.enter(e)},updated(e,{value:t,oldValue:n},{transition:r}){!t!=!n&&(r?t?(r.beforeEnter(e),Sl(e,!0),r.enter(e)):r.leave(e,()=>{Sl(e,!1)}):Sl(e,t))},beforeUnmount(e,{value:t}){Sl(e,t)}};function Sl(e,t){e.style.display=t?e._vod:"none"}const a0=Wt({patchProp:Ik},bk);let Bl,xm=!1;function Kk(){return Bl||(Bl=QC(a0))}function qk(){return Bl=xm?Bl:ek(a0),xm=!0,Bl}const Om=(...e)=>{Kk().render(...e)},Yk=(...e)=>{const t=qk().createApp(...e),{mount:n}=t;return t.mount=r=>{const o=Gk(r);if(o)return n(o,!0,o instanceof SVGElement)},t};function Gk(e){return Ge(e)?document.querySelector(e):e}const Xk=JSON.parse('{"base":"/","lang":"en-US","title":"SD \u8BAD\u7EC3 UI","description":"","head":[],"locales":{}}');var Jk=([e,t,n])=>e==="meta"&&t.name?`${e}.${t.name}`:["title","base"].includes(e)?e:e==="template"&&t.id?`${e}.${t.id}`:JSON.stringify([e,t,n]),Zk=e=>{const t=new Set,n=[];return e.forEach(r=>{const o=Jk(r);t.has(o)||(t.add(o),n.push(r))}),n},Qk=e=>/^(https?:)?\/\//.test(e),fG=e=>/^mailto:/.test(e),pG=e=>/^tel:/.test(e),l0=e=>Object.prototype.toString.call(e)==="[object Object]",eS=e=>e.replace(/\/$/,""),tS=e=>e.replace(/^\//,""),s0=(e,t)=>{const n=Object.keys(e).sort((r,o)=>{const a=o.split("/").length-r.split("/").length;return a!==0?a:o.length-r.length});for(const r of n)if(t.startsWith(r))return r;return"/"};const i0={"v-8daa1a0e":Jt(()=>wt(()=>import("./index.html.c6ef684b.js"),[])),"v-6983ba2a":Jt(()=>wt(()=>import("./tageditor.html.173f1b6a.js"),[])),"v-51615306":Jt(()=>wt(()=>import("./tagger.html.0daaef4e.js"),[])),"v-06850b9b":Jt(()=>wt(()=>import("./task.html.256f458b.js"),[])),"v-13efe3c5":Jt(()=>wt(()=>import("./tensorboard.html.9c3b4542.js"),[])),"v-33a23463":Jt(()=>wt(()=>import("./index.html.911dc78d.js"),[])),"v-b5471278":Jt(()=>wt(()=>import("./about.html.b4807002.js"),[])),"v-a1c9e4f2":Jt(()=>wt(()=>import("./changelog.html.e5f6a7b8.js"),[])),"v-b8e2d701":Jt(()=>wt(()=>import("./guide.html.c3f4a902.js"),[])),"v-72e1da3e":Jt(()=>wt(()=>import("./settings.html.07aaabcc.js"),[])),"v-3e43d6e2":Jt(()=>wt(()=>import("./basic.html.eb26832d.js"),[])),"v-fdbe4e28":Jt(()=>wt(()=>import("./flux.html.f22f5932.js"),[])),"v-14e91824":Jt(()=>wt(()=>import("./index.html.4896b94d.js"),[])),"v-1bf725da":Jt(()=>wt(()=>import("./master.html.404f21be.js"),[])),"v-0f9e746f":Jt(()=>wt(()=>import("./params.html.dea583bc.js"),[])),"v-0dc76a3b":Jt(()=>wt(()=>import("./sd3.html.1a4bf31e.js"),[])),"v-a1f1ne2e":Jt(()=>wt(()=>import("./anima-finetune.html.1a4bf32e.js"),[])),"v-53c99f50":Jt(()=>wt(()=>import("./sdxl.html.33fa069c.js"),[])),"v-4441a302":Jt(()=>wt(()=>import("./tools.html.6c8bfc09.js"),[])),"v-3706649a":Jt(()=>wt(()=>import("./404.html.7a24a487.js"),[]))},nS={404:Jt(()=>wt(()=>import("./404.47057000.js"),[])),Layout:Jt(()=>wt(()=>import("./layout.96d49288.js"),[]))};var u0=B(b2),c0=pa({key:"",path:"",title:"",lang:"",frontmatter:{},excerpt:"",headers:[]}),jr=B(c0),Ps=()=>jr;zp.webpackHot&&(__VUE_HMR_RUNTIME__.updatePageData=e=>{u0.value[e.key]=()=>Promise.resolve(e),e.key===jr.value.key&&(jr.value=e)});var d0=Symbol(""),rS=()=>{const e=Re(d0);if(!e)throw new Error("usePageFrontmatter() is called without provider.");return e},f0=Symbol(""),oS=()=>{const e=Re(f0);if(!e)throw new Error("usePageHead() is called without provider.");return e},aS=Symbol(""),p0=Symbol(""),lS=()=>{const e=Re(p0);if(!e)throw new Error("usePageLang() is called without provider.");return e},Cf=Symbol(""),sS=()=>{const e=Re(Cf);if(!e)throw new Error("useRouteLocale() is called without provider.");return e},wo=B(Xk),iS=()=>wo;zp.webpackHot&&(__VUE_HMR_RUNTIME__.updateSiteData=e=>{wo.value=e});var m0=Symbol(""),mG=()=>{const e=Re(m0);if(!e)throw new Error("useSiteLocaleData() is called without provider.");return e},uS=Symbol(""),Wo=Xt({resolvePageData:async e=>{const t=u0.value[e],n=await(t==null?void 0:t());return n!=null?n:c0},resolvePageFrontmatter:e=>e.frontmatter,resolvePageHead:(e,t,n)=>{const r=Ge(t.description)?t.description:n.description,o=[...De(t.head)?t.head:[],...n.head,["title",{},e],["meta",{name:"description",content:r}]];return Zk(o)},resolvePageHeadTitle:(e,t)=>`${e.title?`${e.title} | `:""}${t.title}`,resolvePageLang:e=>e.lang||"en",resolveRouteLocale:(e,t)=>s0(e,t),resolveSiteLocaleData:(e,t)=>({...e,...e.locales[t]})}),cS=se({name:"ClientOnly",setup(e,t){const n=B(!1);return dt(()=>{n.value=!0}),()=>{var r,o;return n.value?(o=(r=t.slots).default)==null?void 0:o.call(r):null}}}),dS=se({name:"Content",props:{pageKey:{type:String,required:!1,default:""}},setup(e){const t=Ps(),n=O(()=>i0[e.pageKey||t.value.key]);return()=>n.value?He(n.value):He("div","404 Not Found")}}),Am=se({name:"Vuepress",setup(){const e=Ps(),t=O(()=>{let n;if(e.value.path){const r=e.value.frontmatter.layout;Ge(r)?n=r:n="Layout"}else n="404";return nS[n]||Ve(n,!1)});return()=>He(t.value)}}),fS=e=>Qk(e)?e:`${iS().value.base}${tS(e)}`,Ro=e=>e;function h0(e,t,n){var r,o,a;t===void 0&&(t=50),n===void 0&&(n={});var l=(r=n.isImmediate)!=null&&r,s=(o=n.callback)!=null&&o,i=n.maxWait,u=Date.now(),d=[];function f(){if(i!==void 0){var p=Date.now()-u;if(p+t>=i)return i-p}return t}var h=function(){var p=[].slice.call(arguments),v=this;return new Promise(function(g,w){var m=l&&a===void 0;if(a!==void 0&&clearTimeout(a),a=setTimeout(function(){if(a=void 0,u=Date.now(),!l){var _=e.apply(v,p);s&&s(_),d.forEach(function(y){return(0,y.resolve)(_)}),d=[]}},f()),m){var b=e.apply(v,p);return s&&s(b),g(b)}d.push({resolve:g,reject:w})})};return h.cancel=function(p){a!==void 0&&clearTimeout(a),d.forEach(function(v){return(0,v.reject)(p)}),d=[]},h}/*! +var m2=Object.defineProperty;var h2=(e,t,n)=>t in e?m2(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n;var Hp=(e,t,n)=>(h2(e,typeof t!="symbol"?t+"":t,n),n);const zp={};const v2="modulepreload",jp={},g2="/",wt=function(t,n){return!n||n.length===0?t():Promise.all(n.map(r=>{if(r=`${g2}${r}`,r in jp)return;jp[r]=!0;const o=r.endsWith(".css"),a=o?'[rel="stylesheet"]':"";if(document.querySelector(`link[href="${r}"]${a}`))return;const l=document.createElement("link");if(l.rel=o?"stylesheet":v2,o||(l.as="script",l.crossOrigin=""),l.href=r,document.head.appendChild(l),o)return new Promise((s,i)=>{l.addEventListener("load",s),l.addEventListener("error",()=>i(new Error(`Unable to preload CSS for ${r}`)))})})).then(()=>t())},b2={"v-8daa1a0e":()=>wt(()=>import("./index.html.ec4ace46.js"),[]).then(({data:e})=>e),"v-6983ba2a":()=>wt(()=>import("./tageditor.html.66da263e.js"),[]).then(({data:e})=>e),"v-native-tageditor":()=>wt(()=>import("./tageditor.html.66da263e.js"),[]).then(({data:e})=>e),"v-51615306":()=>wt(()=>import("./tagger.html.66f12b92.js"),[]).then(({data:e})=>e),"v-06850b9b":()=>wt(()=>import("./task.html.4e4c8633.js"),[]).then(({data:e})=>e),"v-13efe3c5":()=>wt(()=>import("./tensorboard.html.4a2799a9.js"),[]).then(({data:e})=>e),"v-33a23463":()=>wt(()=>import("./index.html.838bbc6c.js"),[]).then(({data:e})=>e),"v-b5471278":()=>wt(()=>import("./about.html.5b0c0de9.js"),[]).then(({data:e})=>e),"v-a1c9e4f2":()=>wt(()=>import("./changelog.html.a1b2c3d4.js"),[]).then(({data:e})=>e),"v-b8e2d701":()=>wt(()=>import("./guide.html.b8e2d701.js"),[]).then(({data:e})=>e),"v-72e1da3e":()=>wt(()=>import("./settings.html.06993f96.js?v=dataset-tagger-api"),[]).then(({data:e})=>e),"v-3e43d6e2":()=>wt(()=>import("./basic.html.48955584.js"),[]).then(({data:e})=>e),"v-fdbe4e28":()=>wt(()=>import("./flux.html.6fefc131.js"),[]).then(({data:e})=>e),"v-14e91824":()=>wt(()=>import("./index.html.b97ec799.js"),[]).then(({data:e})=>e),"v-1bf725da":()=>wt(()=>import("./master.html.54eb6415.js"),[]).then(({data:e})=>e),"v-0f9e746f":()=>wt(()=>import("./params.html.c8cc13ef.js"),[]).then(({data:e})=>e),"v-0dc76a3b":()=>wt(()=>import("./sd3.html.eaeb05e1.js"),[]).then(({data:e})=>e),"v-a1f1ne2e":()=>wt(()=>import("./anima-finetune.html.eaeb05f2.js"),[]).then(({data:e})=>e),"v-53c99f50":()=>wt(()=>import("./sdxl.html.6ab37b06.js"),[]).then(({data:e})=>e),"v-4441a302":()=>wt(()=>import("./tools.html.c0a4659a.js"),[]).then(({data:e})=>e),"v-3706649a":()=>wt(()=>import("./404.html.686caba0.js"),[]).then(({data:e})=>e)};function Jd(e,t){const n=Object.create(null),r=e.split(",");for(let o=0;o!!n[o.toLowerCase()]:o=>!!n[o]}const Ft={},Na=[],en=()=>{},y2=()=>!1,_2=/^on[^a-z]/,$s=e=>_2.test(e),Zd=e=>e.startsWith("onUpdate:"),Wt=Object.assign,Qd=(e,t)=>{const n=e.indexOf(t);n>-1&&e.splice(n,1)},w2=Object.prototype.hasOwnProperty,ft=(e,t)=>w2.call(e,t),De=Array.isArray,Da=e=>Ts(e)==="[object Map]",Su=e=>Ts(e)==="[object Set]",Yi=e=>Ts(e)==="[object Date]",Ke=e=>typeof e=="function",Ge=e=>typeof e=="string",Zl=e=>typeof e=="symbol",ht=e=>e!==null&&typeof e=="object",Gi=e=>ht(e)&&Ke(e.then)&&Ke(e.catch),Kg=Object.prototype.toString,Ts=e=>Kg.call(e),$i=e=>Ts(e).slice(8,-1),qg=e=>Ts(e)==="[object Object]",ef=e=>Ge(e)&&e!=="NaN"&&e[0]!=="-"&&""+parseInt(e,10)===e,Rl=Jd(",key,ref,ref_for,ref_key,onVnodeBeforeMount,onVnodeMounted,onVnodeBeforeUpdate,onVnodeUpdated,onVnodeBeforeUnmount,onVnodeUnmounted"),Eu=e=>{const t=Object.create(null);return n=>t[n]||(t[n]=e(n))},C2=/-(\w)/g,cr=Eu(e=>e.replace(C2,(t,n)=>n?n.toUpperCase():"")),k2=/\B([A-Z])/g,fa=Eu(e=>e.replace(k2,"-$1").toLowerCase()),$u=Eu(e=>e.charAt(0).toUpperCase()+e.slice(1)),Ti=Eu(e=>e?`on${$u(e)}`:""),Ql=(e,t)=>!Object.is(e,t),xi=(e,t)=>{for(let n=0;n{Object.defineProperty(e,t,{configurable:!0,enumerable:!1,value:n})},Vc=e=>{const t=parseFloat(e);return isNaN(t)?e:t},S2=e=>{const t=Ge(e)?Number(e):NaN;return isNaN(t)?e:t};let Wp;const Bc=()=>Wp||(Wp=typeof globalThis!="undefined"?globalThis:typeof self!="undefined"?self:typeof window!="undefined"?window:typeof global!="undefined"?global:{});function Qe(e){if(De(e)){const t={};for(let n=0;n{if(n){const r=n.split($2);r.length>1&&(t[r[0].trim()]=r[1].trim())}}),t}function D(e){let t="";if(Ge(e))t=e;else if(De(e))for(let n=0;nja(n,t))}const Ee=e=>Ge(e)?e:e==null?"":De(e)||ht(e)&&(e.toString===Kg||!Ke(e.toString))?JSON.stringify(e,Xg,2):String(e),Xg=(e,t)=>t&&t.__v_isRef?Xg(e,t.value):Da(t)?{[`Map(${t.size})`]:[...t.entries()].reduce((n,[r,o])=>(n[`${r} =>`]=o,n),{})}:Su(t)?{[`Set(${t.size})`]:[...t.values()]}:ht(t)&&!De(t)&&!qg(t)?String(t):t;let Vn;class Jg{constructor(t=!1){this.detached=t,this._active=!0,this.effects=[],this.cleanups=[],this.parent=Vn,!t&&Vn&&(this.index=(Vn.scopes||(Vn.scopes=[])).push(this)-1)}get active(){return this._active}run(t){if(this._active){const n=Vn;try{return Vn=this,t()}finally{Vn=n}}}on(){Vn=this}off(){Vn=this.parent}stop(t){if(this._active){let n,r;for(n=0,r=this.effects.length;n{const t=new Set(e);return t.w=0,t.n=0,t},eb=e=>(e.w&To)>0,tb=e=>(e.n&To)>0,R2=({deps:e})=>{if(e.length)for(let t=0;t{const{deps:t}=e;if(t.length){let n=0;for(let r=0;r{(d==="length"||d>=i)&&s.push(u)})}else switch(n!==void 0&&s.push(l.get(n)),t){case"add":De(e)?ef(n)&&s.push(l.get("length")):(s.push(l.get(na)),Da(e)&&s.push(l.get(Hc)));break;case"delete":De(e)||(s.push(l.get(na)),Da(e)&&s.push(l.get(Hc)));break;case"set":Da(e)&&s.push(l.get(na));break}if(s.length===1)s[0]&&jc(s[0]);else{const i=[];for(const u of s)u&&i.push(...u);jc(tf(i))}}function jc(e,t){const n=De(e)?e:[...e];for(const r of n)r.computed&&Kp(r);for(const r of n)r.computed||Kp(r)}function Kp(e,t){(e!==lr||e.allowRecurse)&&(e.scheduler?e.scheduler():e.run())}function D2(e,t){var n;return(n=Ji.get(e))==null?void 0:n.get(t)}const F2=Jd("__proto__,__v_isRef,__isVue"),ob=new Set(Object.getOwnPropertyNames(Symbol).filter(e=>e!=="arguments"&&e!=="caller").map(e=>Symbol[e]).filter(Zl)),V2=rf(),B2=rf(!1,!0),z2=rf(!0),qp=H2();function H2(){const e={};return["includes","indexOf","lastIndexOf"].forEach(t=>{e[t]=function(...n){const r=gt(this);for(let a=0,l=this.length;a{e[t]=function(...n){dl();const r=gt(this)[t].apply(this,n);return fl(),r}}),e}function j2(e){const t=gt(this);return Ln(t,"has",e),t.hasOwnProperty(e)}function rf(e=!1,t=!1){return function(r,o,a){if(o==="__v_isReactive")return!e;if(o==="__v_isReadonly")return e;if(o==="__v_isShallow")return t;if(o==="__v_raw"&&a===(e?t?aC:ub:t?ib:sb).get(r))return r;const l=De(r);if(!e){if(l&&ft(qp,o))return Reflect.get(qp,o,a);if(o==="hasOwnProperty")return j2}const s=Reflect.get(r,o,a);return(Zl(o)?ob.has(o):F2(o))||(e||Ln(r,"get",o),t)?s:mt(s)?l&&ef(o)?s:s.value:ht(s)?e?pa(s):Xt(s):s}}const W2=ab(),U2=ab(!0);function ab(e=!1){return function(n,r,o,a){let l=n[r];if(Wa(l)&&mt(l)&&!mt(o))return!1;if(!e&&(!Zi(o)&&!Wa(o)&&(l=gt(l),o=gt(o)),!De(n)&&mt(l)&&!mt(o)))return l.value=o,!0;const s=De(n)&&ef(r)?Number(r)e,Tu=e=>Reflect.getPrototypeOf(e);function qs(e,t,n=!1,r=!1){e=e.__v_raw;const o=gt(e),a=gt(t);n||(t!==a&&Ln(o,"get",t),Ln(o,"get",a));const{has:l}=Tu(o),s=r?of:n?uf:es;if(l.call(o,t))return s(e.get(t));if(l.call(o,a))return s(e.get(a));e!==o&&e.get(t)}function Ys(e,t=!1){const n=this.__v_raw,r=gt(n),o=gt(e);return t||(e!==o&&Ln(r,"has",e),Ln(r,"has",o)),e===o?n.has(e):n.has(e)||n.has(o)}function Gs(e,t=!1){return e=e.__v_raw,!t&&Ln(gt(e),"iterate",na),Reflect.get(e,"size",e)}function Yp(e){e=gt(e);const t=gt(this);return Tu(t).has.call(t,e)||(t.add(e),Yr(t,"add",e,e)),this}function Gp(e,t){t=gt(t);const n=gt(this),{has:r,get:o}=Tu(n);let a=r.call(n,e);a||(e=gt(e),a=r.call(n,e));const l=o.call(n,e);return n.set(e,t),a?Ql(t,l)&&Yr(n,"set",e,t):Yr(n,"add",e,t),this}function Xp(e){const t=gt(this),{has:n,get:r}=Tu(t);let o=n.call(t,e);o||(e=gt(e),o=n.call(t,e)),r&&r.call(t,e);const a=t.delete(e);return o&&Yr(t,"delete",e,void 0),a}function Jp(){const e=gt(this),t=e.size!==0,n=e.clear();return t&&Yr(e,"clear",void 0,void 0),n}function Xs(e,t){return function(r,o){const a=this,l=a.__v_raw,s=gt(l),i=t?of:e?uf:es;return!e&&Ln(s,"iterate",na),l.forEach((u,d)=>r.call(o,i(u),i(d),a))}}function Js(e,t,n){return function(...r){const o=this.__v_raw,a=gt(o),l=Da(a),s=e==="entries"||e===Symbol.iterator&&l,i=e==="keys"&&l,u=o[e](...r),d=n?of:t?uf:es;return!t&&Ln(a,"iterate",i?Hc:na),{next(){const{value:f,done:h}=u.next();return h?{value:f,done:h}:{value:s?[d(f[0]),d(f[1])]:d(f),done:h}},[Symbol.iterator](){return this}}}}function so(e){return function(...t){return e==="delete"?!1:this}}function J2(){const e={get(a){return qs(this,a)},get size(){return Gs(this)},has:Ys,add:Yp,set:Gp,delete:Xp,clear:Jp,forEach:Xs(!1,!1)},t={get(a){return qs(this,a,!1,!0)},get size(){return Gs(this)},has:Ys,add:Yp,set:Gp,delete:Xp,clear:Jp,forEach:Xs(!1,!0)},n={get(a){return qs(this,a,!0)},get size(){return Gs(this,!0)},has(a){return Ys.call(this,a,!0)},add:so("add"),set:so("set"),delete:so("delete"),clear:so("clear"),forEach:Xs(!0,!1)},r={get(a){return qs(this,a,!0,!0)},get size(){return Gs(this,!0)},has(a){return Ys.call(this,a,!0)},add:so("add"),set:so("set"),delete:so("delete"),clear:so("clear"),forEach:Xs(!0,!0)};return["keys","values","entries",Symbol.iterator].forEach(a=>{e[a]=Js(a,!1,!1),n[a]=Js(a,!0,!1),t[a]=Js(a,!1,!0),r[a]=Js(a,!0,!0)}),[e,n,t,r]}const[Z2,Q2,eC,tC]=J2();function af(e,t){const n=t?e?tC:eC:e?Q2:Z2;return(r,o,a)=>o==="__v_isReactive"?!e:o==="__v_isReadonly"?e:o==="__v_raw"?r:Reflect.get(ft(n,o)&&o in r?n:r,o,a)}const nC={get:af(!1,!1)},rC={get:af(!1,!0)},oC={get:af(!0,!1)},sb=new WeakMap,ib=new WeakMap,ub=new WeakMap,aC=new WeakMap;function lC(e){switch(e){case"Object":case"Array":return 1;case"Map":case"Set":case"WeakMap":case"WeakSet":return 2;default:return 0}}function sC(e){return e.__v_skip||!Object.isExtensible(e)?0:lC($i(e))}function Xt(e){return Wa(e)?e:sf(e,!1,lb,nC,sb)}function lf(e){return sf(e,!1,X2,rC,ib)}function pa(e){return sf(e,!0,G2,oC,ub)}function sf(e,t,n,r,o){if(!ht(e)||e.__v_raw&&!(t&&e.__v_isReactive))return e;const a=o.get(e);if(a)return a;const l=sC(e);if(l===0)return e;const s=new Proxy(e,l===2?r:n);return o.set(e,s),s}function Fa(e){return Wa(e)?Fa(e.__v_raw):!!(e&&e.__v_isReactive)}function Wa(e){return!!(e&&e.__v_isReadonly)}function Zi(e){return!!(e&&e.__v_isShallow)}function cb(e){return Fa(e)||Wa(e)}function gt(e){const t=e&&e.__v_raw;return t?gt(t):e}function db(e){return Xi(e,"__v_skip",!0),e}const es=e=>ht(e)?Xt(e):e,uf=e=>ht(e)?pa(e):e;function fb(e){So&&lr&&(e=gt(e),rb(e.dep||(e.dep=tf())))}function cf(e,t){e=gt(e);const n=e.dep;n&&jc(n)}function mt(e){return!!(e&&e.__v_isRef===!0)}function B(e){return pb(e,!1)}function On(e){return pb(e,!0)}function pb(e,t){return mt(e)?e:new iC(e,t)}class iC{constructor(t,n){this.__v_isShallow=n,this.dep=void 0,this.__v_isRef=!0,this._rawValue=n?t:gt(t),this._value=n?t:es(t)}get value(){return fb(this),this._value}set value(t){const n=this.__v_isShallow||Zi(t)||Wa(t);t=n?t:gt(t),Ql(t,this._rawValue)&&(this._rawValue=t,this._value=n?t:es(t),cf(this))}}function Cl(e){cf(e)}function c(e){return mt(e)?e.value:e}const uC={get:(e,t,n)=>c(Reflect.get(e,t,n)),set:(e,t,n,r)=>{const o=e[t];return mt(o)&&!mt(n)?(o.value=n,!0):Reflect.set(e,t,n,r)}};function mb(e){return Fa(e)?e:new Proxy(e,uC)}function dr(e){const t=De(e)?new Array(e.length):{};for(const n in e)t[n]=hb(e,n);return t}class cC{constructor(t,n,r){this._object=t,this._key=n,this._defaultValue=r,this.__v_isRef=!0}get value(){const t=this._object[this._key];return t===void 0?this._defaultValue:t}set value(t){this._object[this._key]=t}get dep(){return D2(gt(this._object),this._key)}}class dC{constructor(t){this._getter=t,this.__v_isRef=!0,this.__v_isReadonly=!0}get value(){return this._getter()}}function zt(e,t,n){return mt(e)?e:Ke(e)?new dC(e):ht(e)&&arguments.length>1?hb(e,t,n):B(e)}function hb(e,t,n){const r=e[t];return mt(r)?r:new cC(e,t,n)}class fC{constructor(t,n,r,o){this._setter=n,this.dep=void 0,this.__v_isRef=!0,this.__v_isReadonly=!1,this._dirty=!0,this.effect=new nf(t,()=>{this._dirty||(this._dirty=!0,cf(this))}),this.effect.computed=this,this.effect.active=this._cacheable=!o,this.__v_isReadonly=r}get value(){const t=gt(this);return fb(t),(t._dirty||!t._cacheable)&&(t._dirty=!1,t._value=t.effect.run()),t._value}set value(t){this._setter(t)}}function vb(e,t,n=!1){let r,o;const a=Ke(e);return a?(r=e,o=en):(r=e.get,o=e.set),new fC(r,o,a||!o,n)}function pC(e,...t){}function Eo(e,t,n,r){let o;try{o=r?e(...r):e()}catch(a){xs(a,t,n)}return o}function qn(e,t,n,r){if(Ke(e)){const a=Eo(e,t,n,r);return a&&Gi(a)&&a.catch(l=>{xs(l,t,n)}),a}const o=[];for(let a=0;a>>1;ns(pn[r])Sr&&pn.splice(t,1)}function gC(e){De(e)?Va.push(...e):(!zr||!zr.includes(e,e.allowRecurse?qo+1:qo))&&Va.push(e),bb()}function Zp(e,t=ts?Sr+1:0){for(;tns(n)-ns(r)),qo=0;qoe.id==null?1/0:e.id,bC=(e,t)=>{const n=ns(e)-ns(t);if(n===0){if(e.pre&&!t.pre)return-1;if(t.pre&&!e.pre)return 1}return n};function yb(e){Wc=!1,ts=!0,pn.sort(bC);const t=en;try{for(Sr=0;SrGe(p)?p.trim():p)),f&&(o=n.map(Vc))}let s,i=r[s=Ti(t)]||r[s=Ti(cr(t))];!i&&a&&(i=r[s=Ti(fa(t))]),i&&qn(i,e,6,o);const u=r[s+"Once"];if(u){if(!e.emitted)e.emitted={};else if(e.emitted[s])return;e.emitted[s]=!0,qn(u,e,6,o)}}function _b(e,t,n=!1){const r=t.emitsCache,o=r.get(e);if(o!==void 0)return o;const a=e.emits;let l={},s=!1;if(!Ke(e)){const i=u=>{const d=_b(u,t,!0);d&&(s=!0,Wt(l,d))};!n&&t.mixins.length&&t.mixins.forEach(i),e.extends&&i(e.extends),e.mixins&&e.mixins.forEach(i)}return!a&&!s?(ht(e)&&r.set(e,null),null):(De(a)?a.forEach(i=>l[i]=null):Wt(l,a),ht(e)&&r.set(e,l),l)}function Ou(e,t){return!e||!$s(t)?!1:(t=t.slice(2).replace(/Once$/,""),ft(e,t[0].toLowerCase()+t.slice(1))||ft(e,fa(t))||ft(e,t))}let sn=null,Au=null;function eu(e){const t=sn;return sn=e,Au=e&&e.type.__scopeId||null,t}function _C(e){Au=e}function wC(){Au=null}function G(e,t=sn,n){if(!t||e._n)return e;const r=(...o)=>{r._d&&dm(-1);const a=eu(t);let l;try{l=e(...o)}finally{eu(a),r._d&&dm(1)}return l};return r._n=!0,r._c=!0,r._d=!0,r}function ac(e){const{type:t,vnode:n,proxy:r,withProxy:o,props:a,propsOptions:[l],slots:s,attrs:i,emit:u,render:d,renderCache:f,data:h,setupState:p,ctx:v,inheritAttrs:g}=e;let w,m;const b=eu(e);try{if(n.shapeFlag&4){const y=o||r;w=or(d.call(y,y,f,a,p,h,v)),m=i}else{const y=t;w=or(y.length>1?y(a,{attrs:i,slots:s,emit:u}):y(a,null)),m=t.props?i:CC(i)}}catch(y){Vl.length=0,xs(y,e,1),w=Q(yn)}let _=w;if(m&&g!==!1){const y=Object.keys(m),{shapeFlag:C}=_;y.length&&C&7&&(l&&y.some(Zd)&&(m=kC(m,l)),_=Xr(_,m))}return n.dirs&&(_=Xr(_),_.dirs=_.dirs?_.dirs.concat(n.dirs):n.dirs),n.transition&&(_.transition=n.transition),w=_,eu(b),w}const CC=e=>{let t;for(const n in e)(n==="class"||n==="style"||$s(n))&&((t||(t={}))[n]=e[n]);return t},kC=(e,t)=>{const n={};for(const r in e)(!Zd(r)||!(r.slice(9)in t))&&(n[r]=e[r]);return n};function SC(e,t,n){const{props:r,children:o,component:a}=e,{props:l,children:s,patchFlag:i}=t,u=a.emitsOptions;if(t.dirs||t.transition)return!0;if(n&&i>=0){if(i&1024)return!0;if(i&16)return r?Qp(r,l,u):!!l;if(i&8){const d=t.dynamicProps;for(let f=0;fe.__isSuspense;function wb(e,t){t&&t.pendingBranch?De(e)?t.effects.push(...e):t.effects.push(e):gC(e)}function qr(e,t){return ff(e,null,t)}const Zs={};function $e(e,t,n){return ff(e,t,n)}function ff(e,t,{immediate:n,deep:r,flush:o,onTrack:a,onTrigger:l}=Ft){var s;const i=Zg()===((s=Zt)==null?void 0:s.scope)?Zt:null;let u,d=!1,f=!1;if(mt(e)?(u=()=>e.value,d=Zi(e)):Fa(e)?(u=()=>e,r=!0):De(e)?(f=!0,d=e.some(y=>Fa(y)||Zi(y)),u=()=>e.map(y=>{if(mt(y))return y.value;if(Fa(y))return Jo(y);if(Ke(y))return Eo(y,i,2)})):Ke(e)?t?u=()=>Eo(e,i,2):u=()=>{if(!(i&&i.isUnmounted))return h&&h(),qn(e,i,3,[p])}:u=en,t&&r){const y=u;u=()=>Jo(y())}let h,p=y=>{h=b.onStop=()=>{Eo(y,i,4)}},v;if(qa)if(p=en,t?n&&qn(t,i,3,[u(),f?[]:void 0,p]):u(),o==="sync"){const y=vk();v=y.__watcherHandles||(y.__watcherHandles=[])}else return en;let g=f?new Array(e.length).fill(Zs):Zs;const w=()=>{if(!!b.active)if(t){const y=b.run();(r||d||(f?y.some((C,k)=>Ql(C,g[k])):Ql(y,g)))&&(h&&h(),qn(t,i,3,[y,g===Zs?void 0:f&&g[0]===Zs?[]:g,p]),g=y)}else b.run()};w.allowRecurse=!!t;let m;o==="sync"?m=w:o==="post"?m=()=>Tn(w,i&&i.suspense):(w.pre=!0,i&&(w.id=i.uid),m=()=>xu(w));const b=new nf(u,m);t?n?w():g=b.run():o==="post"?Tn(b.run.bind(b),i&&i.suspense):b.run();const _=()=>{b.stop(),i&&i.scope&&Qd(i.scope.effects,b)};return v&&v.push(_),_}function TC(e,t,n){const r=this.proxy,o=Ge(e)?e.includes(".")?Cb(r,e):()=>r[e]:e.bind(r,r);let a;Ke(t)?a=t:(a=t.handler,n=t);const l=Zt;Ka(this);const s=ff(o,a.bind(r),n);return l?Ka(l):ra(),s}function Cb(e,t){const n=t.split(".");return()=>{let r=e;for(let o=0;o{Jo(n,t)});else if(qg(e))for(const n in e)Jo(e[n],t);return e}function vt(e,t){const n=sn;if(n===null)return e;const r=Mu(n)||n.proxy,o=e.dirs||(e.dirs=[]);for(let a=0;a{e.isMounted=!0}),rn(()=>{e.isUnmounting=!0}),e}const Wn=[Function,Array],Sb={mode:String,appear:Boolean,persisted:Boolean,onBeforeEnter:Wn,onEnter:Wn,onAfterEnter:Wn,onEnterCancelled:Wn,onBeforeLeave:Wn,onLeave:Wn,onAfterLeave:Wn,onLeaveCancelled:Wn,onBeforeAppear:Wn,onAppear:Wn,onAfterAppear:Wn,onAppearCancelled:Wn},xC={name:"BaseTransition",props:Sb,setup(e,{slots:t}){const n=lt(),r=kb();let o;return()=>{const a=t.default&&pf(t.default(),!0);if(!a||!a.length)return;let l=a[0];if(a.length>1){for(const g of a)if(g.type!==yn){l=g;break}}const s=gt(e),{mode:i}=s;if(r.isLeaving)return lc(l);const u=em(l);if(!u)return lc(l);const d=rs(u,s,r,n);os(u,d);const f=n.subTree,h=f&&em(f);let p=!1;const{getTransitionKey:v}=u.type;if(v){const g=v();o===void 0?o=g:g!==o&&(o=g,p=!0)}if(h&&h.type!==yn&&(!Yo(u,h)||p)){const g=rs(h,s,r,n);if(os(h,g),i==="out-in")return r.isLeaving=!0,g.afterLeave=()=>{r.isLeaving=!1,n.update.active!==!1&&n.update()},lc(l);i==="in-out"&&u.type!==yn&&(g.delayLeave=(w,m,b)=>{const _=Eb(r,h);_[String(h.key)]=h,w._leaveCb=()=>{m(),w._leaveCb=void 0,delete d.delayedLeave},d.delayedLeave=b})}return l}}},OC=xC;function Eb(e,t){const{leavingVNodes:n}=e;let r=n.get(t.type);return r||(r=Object.create(null),n.set(t.type,r)),r}function rs(e,t,n,r){const{appear:o,mode:a,persisted:l=!1,onBeforeEnter:s,onEnter:i,onAfterEnter:u,onEnterCancelled:d,onBeforeLeave:f,onLeave:h,onAfterLeave:p,onLeaveCancelled:v,onBeforeAppear:g,onAppear:w,onAfterAppear:m,onAppearCancelled:b}=t,_=String(e.key),y=Eb(n,e),C=(S,R)=>{S&&qn(S,r,9,R)},k=(S,R)=>{const L=R[1];C(S,R),De(S)?S.every(F=>F.length<=1)&&L():S.length<=1&&L()},E={mode:a,persisted:l,beforeEnter(S){let R=s;if(!n.isMounted)if(o)R=g||s;else return;S._leaveCb&&S._leaveCb(!0);const L=y[_];L&&Yo(e,L)&&L.el._leaveCb&&L.el._leaveCb(),C(R,[S])},enter(S){let R=i,L=u,F=d;if(!n.isMounted)if(o)R=w||i,L=m||u,F=b||d;else return;let N=!1;const A=S._enterCb=M=>{N||(N=!0,M?C(F,[S]):C(L,[S]),E.delayedLeave&&E.delayedLeave(),S._enterCb=void 0)};R?k(R,[S,A]):A()},leave(S,R){const L=String(e.key);if(S._enterCb&&S._enterCb(!0),n.isUnmounting)return R();C(f,[S]);let F=!1;const N=S._leaveCb=A=>{F||(F=!0,R(),A?C(v,[S]):C(p,[S]),S._leaveCb=void 0,y[L]===e&&delete y[L])};y[L]=e,h?k(h,[S,N]):N()},clone(S){return rs(S,t,n,r)}};return E}function lc(e){if(Os(e))return e=Xr(e),e.children=null,e}function em(e){return Os(e)?e.children?e.children[0]:void 0:e}function os(e,t){e.shapeFlag&6&&e.component?os(e.component.subTree,t):e.shapeFlag&128?(e.ssContent.transition=t.clone(e.ssContent),e.ssFallback.transition=t.clone(e.ssFallback)):e.transition=t}function pf(e,t=!1,n){let r=[],o=0;for(let a=0;a1)for(let a=0;aWt({name:e.name},t,{setup:e}))():e}const Ba=e=>!!e.type.__asyncLoader;function Jt(e){Ke(e)&&(e={loader:e});const{loader:t,loadingComponent:n,errorComponent:r,delay:o=200,timeout:a,suspensible:l=!0,onError:s}=e;let i=null,u,d=0;const f=()=>(d++,i=null,h()),h=()=>{let p;return i||(p=i=t().catch(v=>{if(v=v instanceof Error?v:new Error(String(v)),s)return new Promise((g,w)=>{s(v,()=>g(f()),()=>w(v),d+1)});throw v}).then(v=>p!==i&&i?i:(v&&(v.__esModule||v[Symbol.toStringTag]==="Module")&&(v=v.default),u=v,v)))};return se({name:"AsyncComponentWrapper",__asyncLoader:h,get __asyncResolved(){return u},setup(){const p=Zt;if(u)return()=>sc(u,p);const v=b=>{i=null,xs(b,p,13,!r)};if(l&&p.suspense||qa)return h().then(b=>()=>sc(b,p)).catch(b=>(v(b),()=>r?Q(r,{error:b}):null));const g=B(!1),w=B(),m=B(!!o);return o&&setTimeout(()=>{m.value=!1},o),a!=null&&setTimeout(()=>{if(!g.value&&!w.value){const b=new Error(`Async component timed out after ${a}ms.`);v(b),w.value=b}},a),h().then(()=>{g.value=!0,p.parent&&Os(p.parent.vnode)&&xu(p.parent.update)}).catch(b=>{v(b),w.value=b}),()=>{if(g.value&&u)return sc(u,p);if(w.value&&r)return Q(r,{error:w.value});if(n&&!m.value)return Q(n)}}})}function sc(e,t){const{ref:n,props:r,children:o,ce:a}=t.vnode,l=Q(e,r,o);return l.ref=n,l.ce=a,delete t.vnode.ce,l}const Os=e=>e.type.__isKeepAlive;function AC(e,t){Tb(e,"a",t)}function $b(e,t){Tb(e,"da",t)}function Tb(e,t,n=Zt){const r=e.__wdc||(e.__wdc=()=>{let o=n;for(;o;){if(o.isDeactivated)return;o=o.parent}return e()});if(Iu(t,r,n),n){let o=n.parent;for(;o&&o.parent;)Os(o.parent.vnode)&&IC(r,t,n,o),o=o.parent}}function IC(e,t,n,r){const o=Iu(t,e,r,!0);Mo(()=>{Qd(r[t],o)},n)}function Iu(e,t,n=Zt,r=!1){if(n){const o=n[e]||(n[e]=[]),a=t.__weh||(t.__weh=(...l)=>{if(n.isUnmounted)return;dl(),Ka(n);const s=qn(t,n,e,l);return ra(),fl(),s});return r?o.unshift(a):o.push(a),a}}const eo=e=>(t,n=Zt)=>(!qa||e==="sp")&&Iu(e,(...r)=>t(...r),n),As=eo("bm"),dt=eo("m"),PC=eo("bu"),pl=eo("u"),rn=eo("bum"),Mo=eo("um"),LC=eo("sp"),MC=eo("rtg"),RC=eo("rtc");function NC(e,t=Zt){Iu("ec",e,t)}const mf="components",DC="directives";function Ve(e,t){return vf(mf,e,!0,t)||e}const xb=Symbol.for("v-ndc");function Lt(e){return Ge(e)?vf(mf,e,!1)||e:e||xb}function hf(e){return vf(DC,e)}function vf(e,t,n=!0,r=!1){const o=sn||Zt;if(o){const a=o.type;if(e===mf){const s=pk(a,!1);if(s&&(s===t||s===cr(t)||s===$u(cr(t))))return a}const l=tm(o[e]||a[e],t)||tm(o.appContext[e],t);return!l&&r?a:l}}function tm(e,t){return e&&(e[t]||e[cr(t)]||e[$u(cr(t))])}function it(e,t,n,r){let o;const a=n&&n[r];if(De(e)||Ge(e)){o=new Array(e.length);for(let l=0,s=e.length;lt(l,s,void 0,a&&a[s]));else{const l=Object.keys(e);o=new Array(l.length);for(let s=0,i=l.length;s{const a=r.fn(...o);return a&&(a.key=r.key),a}:r.fn)}return e}function pe(e,t,n={},r,o){if(sn.isCE||sn.parent&&Ba(sn.parent)&&sn.parent.isCE)return t!=="default"&&(n.name=t),Q("slot",n,r&&r());let a=e[t];a&&a._c&&(a._d=!1),x();const l=a&&Ob(a(n)),s=ce(Pe,{key:n.key||l&&l.key||`_${t}`},l||(r?r():[]),l&&e._===1?64:-2);return!o&&s.scopeId&&(s.slotScopeIds=[s.scopeId+"-s"]),a&&a._c&&(a._d=!0),s}function Ob(e){return e.some(t=>Ua(t)?!(t.type===yn||t.type===Pe&&!Ob(t.children)):!0)?e:null}function FC(e,t){const n={};for(const r in e)n[t&&/[A-Z]/.test(r)?`on:${r}`:Ti(r)]=e[r];return n}const Uc=e=>e?Wb(e)?Mu(e)||e.proxy:Uc(e.parent):null,Nl=Wt(Object.create(null),{$:e=>e,$el:e=>e.vnode.el,$data:e=>e.data,$props:e=>e.props,$attrs:e=>e.attrs,$slots:e=>e.slots,$refs:e=>e.refs,$parent:e=>Uc(e.parent),$root:e=>Uc(e.root),$emit:e=>e.emit,$options:e=>gf(e),$forceUpdate:e=>e.f||(e.f=()=>xu(e.update)),$nextTick:e=>e.n||(e.n=qe.bind(e.proxy)),$watch:e=>TC.bind(e)}),ic=(e,t)=>e!==Ft&&!e.__isScriptSetup&&ft(e,t),VC={get({_:e},t){const{ctx:n,setupState:r,data:o,props:a,accessCache:l,type:s,appContext:i}=e;let u;if(t[0]!=="$"){const p=l[t];if(p!==void 0)switch(p){case 1:return r[t];case 2:return o[t];case 4:return n[t];case 3:return a[t]}else{if(ic(r,t))return l[t]=1,r[t];if(o!==Ft&&ft(o,t))return l[t]=2,o[t];if((u=e.propsOptions[0])&&ft(u,t))return l[t]=3,a[t];if(n!==Ft&&ft(n,t))return l[t]=4,n[t];Kc&&(l[t]=0)}}const d=Nl[t];let f,h;if(d)return t==="$attrs"&&Ln(e,"get",t),d(e);if((f=s.__cssModules)&&(f=f[t]))return f;if(n!==Ft&&ft(n,t))return l[t]=4,n[t];if(h=i.config.globalProperties,ft(h,t))return h[t]},set({_:e},t,n){const{data:r,setupState:o,ctx:a}=e;return ic(o,t)?(o[t]=n,!0):r!==Ft&&ft(r,t)?(r[t]=n,!0):ft(e.props,t)||t[0]==="$"&&t.slice(1)in e?!1:(a[t]=n,!0)},has({_:{data:e,setupState:t,accessCache:n,ctx:r,appContext:o,propsOptions:a}},l){let s;return!!n[l]||e!==Ft&&ft(e,l)||ic(t,l)||(s=a[0])&&ft(s,l)||ft(r,l)||ft(Nl,l)||ft(o.config.globalProperties,l)},defineProperty(e,t,n){return n.get!=null?e._.accessCache[t]=0:ft(n,"value")&&this.set(e,t,n.value,null),Reflect.defineProperty(e,t,n)}};function to(){return Ab().slots}function Pu(){return Ab().attrs}function Ab(){const e=lt();return e.setupContext||(e.setupContext=Kb(e))}function nm(e){return De(e)?e.reduce((t,n)=>(t[n]=null,t),{}):e}let Kc=!0;function BC(e){const t=gf(e),n=e.proxy,r=e.ctx;Kc=!1,t.beforeCreate&&rm(t.beforeCreate,e,"bc");const{data:o,computed:a,methods:l,watch:s,provide:i,inject:u,created:d,beforeMount:f,mounted:h,beforeUpdate:p,updated:v,activated:g,deactivated:w,beforeDestroy:m,beforeUnmount:b,destroyed:_,unmounted:y,render:C,renderTracked:k,renderTriggered:E,errorCaptured:S,serverPrefetch:R,expose:L,inheritAttrs:F,components:N,directives:A,filters:M}=t;if(u&&zC(u,r,null),l)for(const V in l){const X=l[V];Ke(X)&&(r[V]=X.bind(n))}if(o){const V=o.call(n,n);ht(V)&&(e.data=Xt(V))}if(Kc=!0,a)for(const V in a){const X=a[V],I=Ke(X)?X.bind(n,n):Ke(X.get)?X.get.bind(n,n):en,Y=!Ke(X)&&Ke(X.set)?X.set.bind(n):en,ee=O({get:I,set:Y});Object.defineProperty(r,V,{enumerable:!0,configurable:!0,get:()=>ee.value,set:W=>ee.value=W})}if(s)for(const V in s)Ib(s[V],r,n,V);if(i){const V=Ke(i)?i.call(n):i;Reflect.ownKeys(V).forEach(X=>{yt(X,V[X])})}d&&rm(d,e,"c");function j(V,X){De(X)?X.forEach(I=>V(I.bind(n))):X&&V(X.bind(n))}if(j(As,f),j(dt,h),j(PC,p),j(pl,v),j(AC,g),j($b,w),j(NC,S),j(RC,k),j(MC,E),j(rn,b),j(Mo,y),j(LC,R),De(L))if(L.length){const V=e.exposed||(e.exposed={});L.forEach(X=>{Object.defineProperty(V,X,{get:()=>n[X],set:I=>n[X]=I})})}else e.exposed||(e.exposed={});C&&e.render===en&&(e.render=C),F!=null&&(e.inheritAttrs=F),N&&(e.components=N),A&&(e.directives=A)}function zC(e,t,n=en){De(e)&&(e=qc(e));for(const r in e){const o=e[r];let a;ht(o)?"default"in o?a=Re(o.from||r,o.default,!0):a=Re(o.from||r):a=Re(o),mt(a)?Object.defineProperty(t,r,{enumerable:!0,configurable:!0,get:()=>a.value,set:l=>a.value=l}):t[r]=a}}function rm(e,t,n){qn(De(e)?e.map(r=>r.bind(t.proxy)):e.bind(t.proxy),t,n)}function Ib(e,t,n,r){const o=r.includes(".")?Cb(n,r):()=>n[r];if(Ge(e)){const a=t[e];Ke(a)&&$e(o,a)}else if(Ke(e))$e(o,e.bind(n));else if(ht(e))if(De(e))e.forEach(a=>Ib(a,t,n,r));else{const a=Ke(e.handler)?e.handler.bind(n):t[e.handler];Ke(a)&&$e(o,a,e)}}function gf(e){const t=e.type,{mixins:n,extends:r}=t,{mixins:o,optionsCache:a,config:{optionMergeStrategies:l}}=e.appContext,s=a.get(t);let i;return s?i=s:!o.length&&!n&&!r?i=t:(i={},o.length&&o.forEach(u=>tu(i,u,l,!0)),tu(i,t,l)),ht(t)&&a.set(t,i),i}function tu(e,t,n,r=!1){const{mixins:o,extends:a}=t;a&&tu(e,a,n,!0),o&&o.forEach(l=>tu(e,l,n,!0));for(const l in t)if(!(r&&l==="expose")){const s=HC[l]||n&&n[l];e[l]=s?s(e[l],t[l]):t[l]}return e}const HC={data:om,props:am,emits:am,methods:Ll,computed:Ll,beforeCreate:gn,created:gn,beforeMount:gn,mounted:gn,beforeUpdate:gn,updated:gn,beforeDestroy:gn,beforeUnmount:gn,destroyed:gn,unmounted:gn,activated:gn,deactivated:gn,errorCaptured:gn,serverPrefetch:gn,components:Ll,directives:Ll,watch:WC,provide:om,inject:jC};function om(e,t){return t?e?function(){return Wt(Ke(e)?e.call(this,this):e,Ke(t)?t.call(this,this):t)}:t:e}function jC(e,t){return Ll(qc(e),qc(t))}function qc(e){if(De(e)){const t={};for(let n=0;n1)return n&&Ke(t)?t.call(r&&r.proxy):t}}function qC(e,t,n,r=!1){const o={},a={};Xi(a,Lu,1),e.propsDefaults=Object.create(null),Lb(e,t,o,a);for(const l in e.propsOptions[0])l in o||(o[l]=void 0);n?e.props=r?o:lf(o):e.type.props?e.props=o:e.props=a,e.attrs=a}function YC(e,t,n,r){const{props:o,attrs:a,vnode:{patchFlag:l}}=e,s=gt(o),[i]=e.propsOptions;let u=!1;if((r||l>0)&&!(l&16)){if(l&8){const d=e.vnode.dynamicProps;for(let f=0;f{i=!0;const[h,p]=Mb(f,t,!0);Wt(l,h),p&&s.push(...p)};!n&&t.mixins.length&&t.mixins.forEach(d),e.extends&&d(e.extends),e.mixins&&e.mixins.forEach(d)}if(!a&&!i)return ht(e)&&r.set(e,Na),Na;if(De(a))for(let d=0;d-1,p[1]=g<0||v-1||ft(p,"default"))&&s.push(f)}}}const u=[l,s];return ht(e)&&r.set(e,u),u}function lm(e){return e[0]!=="$"}function sm(e){const t=e&&e.toString().match(/^\s*(function|class) (\w+)/);return t?t[2]:e===null?"null":""}function im(e,t){return sm(e)===sm(t)}function um(e,t){return De(t)?t.findIndex(n=>im(n,e)):Ke(t)&&im(t,e)?0:-1}const Rb=e=>e[0]==="_"||e==="$stable",bf=e=>De(e)?e.map(or):[or(e)],GC=(e,t,n)=>{if(t._n)return t;const r=G((...o)=>bf(t(...o)),n);return r._c=!1,r},Nb=(e,t,n)=>{const r=e._ctx;for(const o in e){if(Rb(o))continue;const a=e[o];if(Ke(a))t[o]=GC(o,a,r);else if(a!=null){const l=bf(a);t[o]=()=>l}}},Db=(e,t)=>{const n=bf(t);e.slots.default=()=>n},XC=(e,t)=>{if(e.vnode.shapeFlag&32){const n=t._;n?(e.slots=gt(t),Xi(t,"_",n)):Nb(t,e.slots={})}else e.slots={},t&&Db(e,t);Xi(e.slots,Lu,1)},JC=(e,t,n)=>{const{vnode:r,slots:o}=e;let a=!0,l=Ft;if(r.shapeFlag&32){const s=t._;s?n&&s===1?a=!1:(Wt(o,t),!n&&s===1&&delete o._):(a=!t.$stable,Nb(t,o)),l=t}else t&&(Db(e,t),l={default:1});if(a)for(const s in o)!Rb(s)&&!(s in l)&&delete o[s]};function ru(e,t,n,r,o=!1){if(De(e)){e.forEach((h,p)=>ru(h,t&&(De(t)?t[p]:t),n,r,o));return}if(Ba(r)&&!o)return;const a=r.shapeFlag&4?Mu(r.component)||r.component.proxy:r.el,l=o?null:a,{i:s,r:i}=e,u=t&&t.r,d=s.refs===Ft?s.refs={}:s.refs,f=s.setupState;if(u!=null&&u!==i&&(Ge(u)?(d[u]=null,ft(f,u)&&(f[u]=null)):mt(u)&&(u.value=null)),Ke(i))Eo(i,s,12,[l,d]);else{const h=Ge(i),p=mt(i);if(h||p){const v=()=>{if(e.f){const g=h?ft(f,i)?f[i]:d[i]:i.value;o?De(g)&&Qd(g,a):De(g)?g.includes(a)||g.push(a):h?(d[i]=[a],ft(f,i)&&(f[i]=d[i])):(i.value=[a],e.k&&(d[e.k]=i.value))}else h?(d[i]=l,ft(f,i)&&(f[i]=l)):p&&(i.value=l,e.k&&(d[e.k]=l))};l?(v.id=-1,Tn(v,n)):v()}}}let io=!1;const Qs=e=>/svg/.test(e.namespaceURI)&&e.tagName!=="foreignObject",ei=e=>e.nodeType===8;function ZC(e){const{mt:t,p:n,o:{patchProp:r,createText:o,nextSibling:a,parentNode:l,remove:s,insert:i,createComment:u}}=e,d=(m,b)=>{if(!b.hasChildNodes()){n(null,m,b),Qi(),b._vnode=m;return}io=!1,f(b.firstChild,m,null,null,null),Qi(),b._vnode=m,io&&console.error("Hydration completed but contains mismatches.")},f=(m,b,_,y,C,k=!1)=>{const E=ei(m)&&m.data==="[",S=()=>g(m,b,_,y,C,E),{type:R,ref:L,shapeFlag:F,patchFlag:N}=b;let A=m.nodeType;b.el=m,N===-2&&(k=!1,b.dynamicChildren=null);let M=null;switch(R){case Gr:A!==3?b.children===""?(i(b.el=o(""),l(m),m),M=m):M=S():(m.data!==b.children&&(io=!0,m.data=b.children),M=a(m));break;case yn:A!==8||E?M=S():M=a(m);break;case Fl:if(E&&(m=a(m),A=m.nodeType),A===1||A===3){M=m;const H=!b.children.length;for(let j=0;j{k=k||!!b.dynamicChildren;const{type:E,props:S,patchFlag:R,shapeFlag:L,dirs:F}=b,N=E==="input"&&F||E==="option";if(N||R!==-1){if(F&&kr(b,null,_,"created"),S)if(N||!k||R&48)for(const M in S)(N&&M.endsWith("value")||$s(M)&&!Rl(M))&&r(m,M,null,S[M],!1,void 0,_);else S.onClick&&r(m,"onClick",null,S.onClick,!1,void 0,_);let A;if((A=S&&S.onVnodeBeforeMount)&&Un(A,_,b),F&&kr(b,null,_,"beforeMount"),((A=S&&S.onVnodeMounted)||F)&&wb(()=>{A&&Un(A,_,b),F&&kr(b,null,_,"mounted")},y),L&16&&!(S&&(S.innerHTML||S.textContent))){let M=p(m.firstChild,b,m,_,y,C,k);for(;M;){io=!0;const H=M;M=M.nextSibling,s(H)}}else L&8&&m.textContent!==b.children&&(io=!0,m.textContent=b.children)}return m.nextSibling},p=(m,b,_,y,C,k,E)=>{E=E||!!b.dynamicChildren;const S=b.children,R=S.length;for(let L=0;L{const{slotScopeIds:E}=b;E&&(C=C?C.concat(E):E);const S=l(m),R=p(a(m),b,S,_,y,C,k);return R&&ei(R)&&R.data==="]"?a(b.anchor=R):(io=!0,i(b.anchor=u("]"),S,R),R)},g=(m,b,_,y,C,k)=>{if(io=!0,b.el=null,k){const R=w(m);for(;;){const L=a(m);if(L&&L!==R)s(L);else break}}const E=a(m),S=l(m);return s(m),n(null,b,S,E,_,y,Qs(S),C),E},w=m=>{let b=0;for(;m;)if(m=a(m),m&&ei(m)&&(m.data==="["&&b++,m.data==="]")){if(b===0)return a(m);b--}return m};return[d,f]}const Tn=wb;function QC(e){return Fb(e)}function ek(e){return Fb(e,ZC)}function Fb(e,t){const n=Bc();n.__VUE__=!0;const{insert:r,remove:o,patchProp:a,createElement:l,createText:s,createComment:i,setText:u,setElementText:d,parentNode:f,nextSibling:h,setScopeId:p=en,insertStaticContent:v}=e,g=(P,$,T,z=null,Z=null,oe=null,_e=!1,we=null,he=!!$.dynamicChildren)=>{if(P===$)return;P&&!Yo(P,$)&&(z=J(P),W(P,Z,oe,!0),P=null),$.patchFlag===-2&&(he=!1,$.dynamicChildren=null);const{type:ke,ref:Me,shapeFlag:ne}=$;switch(ke){case Gr:w(P,$,T,z);break;case yn:m(P,$,T,z);break;case Fl:P==null&&b($,T,z,_e);break;case Pe:N(P,$,T,z,Z,oe,_e,we,he);break;default:ne&1?C(P,$,T,z,Z,oe,_e,we,he):ne&6?A(P,$,T,z,Z,oe,_e,we,he):(ne&64||ne&128)&&ke.process(P,$,T,z,Z,oe,_e,we,he,ae)}Me!=null&&Z&&ru(Me,P&&P.ref,oe,$||P,!$)},w=(P,$,T,z)=>{if(P==null)r($.el=s($.children),T,z);else{const Z=$.el=P.el;$.children!==P.children&&u(Z,$.children)}},m=(P,$,T,z)=>{P==null?r($.el=i($.children||""),T,z):$.el=P.el},b=(P,$,T,z)=>{[P.el,P.anchor]=v(P.children,$,T,z,P.el,P.anchor)},_=({el:P,anchor:$},T,z)=>{let Z;for(;P&&P!==$;)Z=h(P),r(P,T,z),P=Z;r($,T,z)},y=({el:P,anchor:$})=>{let T;for(;P&&P!==$;)T=h(P),o(P),P=T;o($)},C=(P,$,T,z,Z,oe,_e,we,he)=>{_e=_e||$.type==="svg",P==null?k($,T,z,Z,oe,_e,we,he):R(P,$,Z,oe,_e,we,he)},k=(P,$,T,z,Z,oe,_e,we)=>{let he,ke;const{type:Me,props:ne,shapeFlag:ue,transition:ie,dirs:Oe}=P;if(he=P.el=l(P.type,oe,ne&&ne.is,ne),ue&8?d(he,P.children):ue&16&&S(P.children,he,null,z,Z,oe&&Me!=="foreignObject",_e,we),Oe&&kr(P,null,z,"created"),E(he,P,P.scopeId,_e,z),ne){for(const Xe in ne)Xe!=="value"&&!Rl(Xe)&&a(he,Xe,null,ne[Xe],oe,P.children,z,Z,ge);"value"in ne&&a(he,"value",null,ne.value),(ke=ne.onVnodeBeforeMount)&&Un(ke,z,P)}Oe&&kr(P,null,z,"beforeMount");const We=(!Z||Z&&!Z.pendingBranch)&&ie&&!ie.persisted;We&&ie.beforeEnter(he),r(he,$,T),((ke=ne&&ne.onVnodeMounted)||We||Oe)&&Tn(()=>{ke&&Un(ke,z,P),We&&ie.enter(he),Oe&&kr(P,null,z,"mounted")},Z)},E=(P,$,T,z,Z)=>{if(T&&p(P,T),z)for(let oe=0;oe{for(let ke=he;ke{const we=$.el=P.el;let{patchFlag:he,dynamicChildren:ke,dirs:Me}=$;he|=P.patchFlag&16;const ne=P.props||Ft,ue=$.props||Ft;let ie;T&&Bo(T,!1),(ie=ue.onVnodeBeforeUpdate)&&Un(ie,T,$,P),Me&&kr($,P,T,"beforeUpdate"),T&&Bo(T,!0);const Oe=Z&&$.type!=="foreignObject";if(ke?L(P.dynamicChildren,ke,we,T,z,Oe,oe):_e||X(P,$,we,null,T,z,Oe,oe,!1),he>0){if(he&16)F(we,$,ne,ue,T,z,Z);else if(he&2&&ne.class!==ue.class&&a(we,"class",null,ue.class,Z),he&4&&a(we,"style",ne.style,ue.style,Z),he&8){const We=$.dynamicProps;for(let Xe=0;Xe{ie&&Un(ie,T,$,P),Me&&kr($,P,T,"updated")},z)},L=(P,$,T,z,Z,oe,_e)=>{for(let we=0;we<$.length;we++){const he=P[we],ke=$[we],Me=he.el&&(he.type===Pe||!Yo(he,ke)||he.shapeFlag&70)?f(he.el):T;g(he,ke,Me,null,z,Z,oe,_e,!0)}},F=(P,$,T,z,Z,oe,_e)=>{if(T!==z){if(T!==Ft)for(const we in T)!Rl(we)&&!(we in z)&&a(P,we,T[we],null,_e,$.children,Z,oe,ge);for(const we in z){if(Rl(we))continue;const he=z[we],ke=T[we];he!==ke&&we!=="value"&&a(P,we,ke,he,_e,$.children,Z,oe,ge)}"value"in z&&a(P,"value",T.value,z.value)}},N=(P,$,T,z,Z,oe,_e,we,he)=>{const ke=$.el=P?P.el:s(""),Me=$.anchor=P?P.anchor:s("");let{patchFlag:ne,dynamicChildren:ue,slotScopeIds:ie}=$;ie&&(we=we?we.concat(ie):ie),P==null?(r(ke,T,z),r(Me,T,z),S($.children,T,Me,Z,oe,_e,we,he)):ne>0&&ne&64&&ue&&P.dynamicChildren?(L(P.dynamicChildren,ue,T,Z,oe,_e,we),($.key!=null||Z&&$===Z.subTree)&&yf(P,$,!0)):X(P,$,T,Me,Z,oe,_e,we,he)},A=(P,$,T,z,Z,oe,_e,we,he)=>{$.slotScopeIds=we,P==null?$.shapeFlag&512?Z.ctx.activate($,T,z,_e,he):M($,T,z,Z,oe,_e,he):H(P,$,he)},M=(P,$,T,z,Z,oe,_e)=>{const we=P.component=uk(P,z,Z);if(Os(P)&&(we.ctx.renderer=ae),ck(we),we.asyncDep){if(Z&&Z.registerDep(we,j),!P.el){const he=we.subTree=Q(yn);m(null,he,$,T)}return}j(we,P,$,T,Z,oe,_e)},H=(P,$,T)=>{const z=$.component=P.component;if(SC(P,$,T))if(z.asyncDep&&!z.asyncResolved){V(z,$,T);return}else z.next=$,vC(z.update),z.update();else $.el=P.el,z.vnode=$},j=(P,$,T,z,Z,oe,_e)=>{const we=()=>{if(P.isMounted){let{next:Me,bu:ne,u:ue,parent:ie,vnode:Oe}=P,We=Me,Xe;Bo(P,!1),Me?(Me.el=Oe.el,V(P,Me,_e)):Me=Oe,ne&&xi(ne),(Xe=Me.props&&Me.props.onVnodeBeforeUpdate)&&Un(Xe,ie,Me,Oe),Bo(P,!0);const fe=ac(P),ve=P.subTree;P.subTree=fe,g(ve,fe,f(ve.el),J(ve),P,Z,oe),Me.el=fe.el,We===null&&EC(P,fe.el),ue&&Tn(ue,Z),(Xe=Me.props&&Me.props.onVnodeUpdated)&&Tn(()=>Un(Xe,ie,Me,Oe),Z)}else{let Me;const{el:ne,props:ue}=$,{bm:ie,m:Oe,parent:We}=P,Xe=Ba($);if(Bo(P,!1),ie&&xi(ie),!Xe&&(Me=ue&&ue.onVnodeBeforeMount)&&Un(Me,We,$),Bo(P,!0),ne&&me){const fe=()=>{P.subTree=ac(P),me(ne,P.subTree,P,Z,null)};Xe?$.type.__asyncLoader().then(()=>!P.isUnmounted&&fe()):fe()}else{const fe=P.subTree=ac(P);g(null,fe,T,z,P,Z,oe),$.el=fe.el}if(Oe&&Tn(Oe,Z),!Xe&&(Me=ue&&ue.onVnodeMounted)){const fe=$;Tn(()=>Un(Me,We,fe),Z)}($.shapeFlag&256||We&&Ba(We.vnode)&&We.vnode.shapeFlag&256)&&P.a&&Tn(P.a,Z),P.isMounted=!0,$=T=z=null}},he=P.effect=new nf(we,()=>xu(ke),P.scope),ke=P.update=()=>he.run();ke.id=P.uid,Bo(P,!0),ke()},V=(P,$,T)=>{$.component=P;const z=P.vnode.props;P.vnode=$,P.next=null,YC(P,$.props,z,T),JC(P,$.children,T),dl(),Zp(),fl()},X=(P,$,T,z,Z,oe,_e,we,he=!1)=>{const ke=P&&P.children,Me=P?P.shapeFlag:0,ne=$.children,{patchFlag:ue,shapeFlag:ie}=$;if(ue>0){if(ue&128){Y(ke,ne,T,z,Z,oe,_e,we,he);return}else if(ue&256){I(ke,ne,T,z,Z,oe,_e,we,he);return}}ie&8?(Me&16&&ge(ke,Z,oe),ne!==ke&&d(T,ne)):Me&16?ie&16?Y(ke,ne,T,z,Z,oe,_e,we,he):ge(ke,Z,oe,!0):(Me&8&&d(T,""),ie&16&&S(ne,T,z,Z,oe,_e,we,he))},I=(P,$,T,z,Z,oe,_e,we,he)=>{P=P||Na,$=$||Na;const ke=P.length,Me=$.length,ne=Math.min(ke,Me);let ue;for(ue=0;ueMe?ge(P,Z,oe,!0,!1,ne):S($,T,z,Z,oe,_e,we,he,ne)},Y=(P,$,T,z,Z,oe,_e,we,he)=>{let ke=0;const Me=$.length;let ne=P.length-1,ue=Me-1;for(;ke<=ne&&ke<=ue;){const ie=P[ke],Oe=$[ke]=he?go($[ke]):or($[ke]);if(Yo(ie,Oe))g(ie,Oe,T,null,Z,oe,_e,we,he);else break;ke++}for(;ke<=ne&&ke<=ue;){const ie=P[ne],Oe=$[ue]=he?go($[ue]):or($[ue]);if(Yo(ie,Oe))g(ie,Oe,T,null,Z,oe,_e,we,he);else break;ne--,ue--}if(ke>ne){if(ke<=ue){const ie=ue+1,Oe=ieue)for(;ke<=ne;)W(P[ke],Z,oe,!0),ke++;else{const ie=ke,Oe=ke,We=new Map;for(ke=Oe;ke<=ue;ke++){const q=$[ke]=he?go($[ke]):or($[ke]);q.key!=null&&We.set(q.key,ke)}let Xe,fe=0;const ve=ue-Oe+1;let Ce=!1,Ye=0;const Se=new Array(ve);for(ke=0;ke=ve){W(q,Z,oe,!0);continue}let Ie;if(q.key!=null)Ie=We.get(q.key);else for(Xe=Oe;Xe<=ue;Xe++)if(Se[Xe-Oe]===0&&Yo(q,$[Xe])){Ie=Xe;break}Ie===void 0?W(q,Z,oe,!0):(Se[Ie-Oe]=ke+1,Ie>=Ye?Ye=Ie:Ce=!0,g(q,$[Ie],T,null,Z,oe,_e,we,he),fe++)}const Ae=Ce?tk(Se):Na;for(Xe=Ae.length-1,ke=ve-1;ke>=0;ke--){const q=Oe+ke,Ie=$[q],et=q+1{const{el:oe,type:_e,transition:we,children:he,shapeFlag:ke}=P;if(ke&6){ee(P.component.subTree,$,T,z);return}if(ke&128){P.suspense.move($,T,z);return}if(ke&64){_e.move(P,$,T,ae);return}if(_e===Pe){r(oe,$,T);for(let ne=0;newe.enter(oe),Z);else{const{leave:ne,delayLeave:ue,afterLeave:ie}=we,Oe=()=>r(oe,$,T),We=()=>{ne(oe,()=>{Oe(),ie&&ie()})};ue?ue(oe,Oe,We):We()}else r(oe,$,T)},W=(P,$,T,z=!1,Z=!1)=>{const{type:oe,props:_e,ref:we,children:he,dynamicChildren:ke,shapeFlag:Me,patchFlag:ne,dirs:ue}=P;if(we!=null&&ru(we,null,T,P,!0),Me&256){$.ctx.deactivate(P);return}const ie=Me&1&&ue,Oe=!Ba(P);let We;if(Oe&&(We=_e&&_e.onVnodeBeforeUnmount)&&Un(We,$,P),Me&6)Te(P.component,T,z);else{if(Me&128){P.suspense.unmount(T,z);return}ie&&kr(P,null,$,"beforeUnmount"),Me&64?P.type.remove(P,$,T,Z,ae,z):ke&&(oe!==Pe||ne>0&&ne&64)?ge(ke,$,T,!1,!0):(oe===Pe&&ne&384||!Z&&Me&16)&&ge(he,$,T),z&&re(P)}(Oe&&(We=_e&&_e.onVnodeUnmounted)||ie)&&Tn(()=>{We&&Un(We,$,P),ie&&kr(P,null,$,"unmounted")},T)},re=P=>{const{type:$,el:T,anchor:z,transition:Z}=P;if($===Pe){be(T,z);return}if($===Fl){y(P);return}const oe=()=>{o(T),Z&&!Z.persisted&&Z.afterLeave&&Z.afterLeave()};if(P.shapeFlag&1&&Z&&!Z.persisted){const{leave:_e,delayLeave:we}=Z,he=()=>_e(T,oe);we?we(P.el,oe,he):he()}else oe()},be=(P,$)=>{let T;for(;P!==$;)T=h(P),o(P),P=T;o($)},Te=(P,$,T)=>{const{bum:z,scope:Z,update:oe,subTree:_e,um:we}=P;z&&xi(z),Z.stop(),oe&&(oe.active=!1,W(_e,P,$,T)),we&&Tn(we,$),Tn(()=>{P.isUnmounted=!0},$),$&&$.pendingBranch&&!$.isUnmounted&&P.asyncDep&&!P.asyncResolved&&P.suspenseId===$.pendingId&&($.deps--,$.deps===0&&$.resolve())},ge=(P,$,T,z=!1,Z=!1,oe=0)=>{for(let _e=oe;_eP.shapeFlag&6?J(P.component.subTree):P.shapeFlag&128?P.suspense.next():h(P.anchor||P.el),te=(P,$,T)=>{P==null?$._vnode&&W($._vnode,null,null,!0):g($._vnode||null,P,$,null,null,null,T),Zp(),Qi(),$._vnode=P},ae={p:g,um:W,m:ee,r:re,mt:M,mc:S,pc:X,pbc:L,n:J,o:e};let le,me;return t&&([le,me]=t(ae)),{render:te,hydrate:le,createApp:KC(te,le)}}function Bo({effect:e,update:t},n){e.allowRecurse=t.allowRecurse=n}function yf(e,t,n=!1){const r=e.children,o=t.children;if(De(r)&&De(o))for(let a=0;a>1,e[n[s]]0&&(t[r]=n[a-1]),n[a]=r)}}for(a=n.length,l=n[a-1];a-- >0;)n[a]=l,l=t[l];return n}const nk=e=>e.__isTeleport,Dl=e=>e&&(e.disabled||e.disabled===""),cm=e=>typeof SVGElement!="undefined"&&e instanceof SVGElement,Gc=(e,t)=>{const n=e&&e.to;return Ge(n)?t?t(n):null:n},rk={__isTeleport:!0,process(e,t,n,r,o,a,l,s,i,u){const{mc:d,pc:f,pbc:h,o:{insert:p,querySelector:v,createText:g,createComment:w}}=u,m=Dl(t.props);let{shapeFlag:b,children:_,dynamicChildren:y}=t;if(e==null){const C=t.el=g(""),k=t.anchor=g("");p(C,n,r),p(k,n,r);const E=t.target=Gc(t.props,v),S=t.targetAnchor=g("");E&&(p(S,E),l=l||cm(E));const R=(L,F)=>{b&16&&d(_,L,F,o,a,l,s,i)};m?R(n,k):E&&R(E,S)}else{t.el=e.el;const C=t.anchor=e.anchor,k=t.target=e.target,E=t.targetAnchor=e.targetAnchor,S=Dl(e.props),R=S?n:k,L=S?C:E;if(l=l||cm(k),y?(h(e.dynamicChildren,y,R,o,a,l,s),yf(e,t,!0)):i||f(e,t,R,L,o,a,l,s,!1),m)S||ti(t,n,C,u,1);else if((t.props&&t.props.to)!==(e.props&&e.props.to)){const F=t.target=Gc(t.props,v);F&&ti(t,F,null,u,0)}else S&&ti(t,k,E,u,1)}Bb(t)},remove(e,t,n,r,{um:o,o:{remove:a}},l){const{shapeFlag:s,children:i,anchor:u,targetAnchor:d,target:f,props:h}=e;if(f&&a(d),(l||!Dl(h))&&(a(u),s&16))for(let p=0;p0?sr||Na:null,ak(),as>0&&sr&&sr.push(e),e}function U(e,t,n,r,o,a){return zb(K(e,t,n,r,o,a,!0))}function ce(e,t,n,r,o){return zb(Q(e,t,n,r,o,!0))}function Ua(e){return e?e.__v_isVNode===!0:!1}function Yo(e,t){return e.type===t.type&&e.key===t.key}const Lu="__vInternal",Hb=({key:e})=>e!=null?e:null,Oi=({ref:e,ref_key:t,ref_for:n})=>(typeof e=="number"&&(e=""+e),e!=null?Ge(e)||mt(e)||Ke(e)?{i:sn,r:e,k:t,f:!!n}:e:null);function K(e,t=null,n=null,r=0,o=null,a=e===Pe?0:1,l=!1,s=!1){const i={__v_isVNode:!0,__v_skip:!0,type:e,props:t,key:t&&Hb(t),ref:t&&Oi(t),scopeId:Au,slotScopeIds:null,children:n,component:null,suspense:null,ssContent:null,ssFallback:null,dirs:null,transition:null,el:null,anchor:null,target:null,targetAnchor:null,staticCount:0,shapeFlag:a,patchFlag:r,dynamicProps:o,dynamicChildren:null,appContext:null,ctx:sn};return s?(_f(i,n),a&128&&e.normalize(i)):n&&(i.shapeFlag|=Ge(n)?8:16),as>0&&!l&&sr&&(i.patchFlag>0||a&6)&&i.patchFlag!==32&&sr.push(i),i}const Q=lk;function lk(e,t=null,n=null,r=0,o=null,a=!1){if((!e||e===xb)&&(e=yn),Ua(e)){const s=Xr(e,t,!0);return n&&_f(s,n),as>0&&!a&&sr&&(s.shapeFlag&6?sr[sr.indexOf(e)]=s:sr.push(s)),s.patchFlag|=-2,s}if(mk(e)&&(e=e.__vccOpts),t){t=jb(t);let{class:s,style:i}=t;s&&!Ge(s)&&(t.class=D(s)),ht(i)&&(cb(i)&&!De(i)&&(i=Wt({},i)),t.style=Qe(i))}const l=Ge(e)?1:$C(e)?128:nk(e)?64:ht(e)?4:Ke(e)?2:0;return K(e,t,n,r,o,l,a,!0)}function jb(e){return e?cb(e)||Lu in e?Wt({},e):e:null}function Xr(e,t,n=!1){const{props:r,ref:o,patchFlag:a,children:l}=e,s=t?Ht(r||{},t):r;return{__v_isVNode:!0,__v_skip:!0,type:e.type,props:s,key:s&&Hb(s),ref:t&&t.ref?n&&o?De(o)?o.concat(Oi(t)):[o,Oi(t)]:Oi(t):o,scopeId:e.scopeId,slotScopeIds:e.slotScopeIds,children:l,target:e.target,targetAnchor:e.targetAnchor,staticCount:e.staticCount,shapeFlag:e.shapeFlag,patchFlag:t&&e.type!==Pe?a===-1?16:a|16:a,dynamicProps:e.dynamicProps,dynamicChildren:e.dynamicChildren,appContext:e.appContext,dirs:e.dirs,transition:e.transition,component:e.component,suspense:e.suspense,ssContent:e.ssContent&&Xr(e.ssContent),ssFallback:e.ssFallback&&Xr(e.ssFallback),el:e.el,anchor:e.anchor,ctx:e.ctx,ce:e.ce}}function Je(e=" ",t=0){return Q(Gr,null,e,t)}function dG(e,t){const n=Q(Fl,null,e);return n.staticCount=t,n}function ye(e="",t=!1){return t?(x(),ce(yn,null,e)):Q(yn,null,e)}function or(e){return e==null||typeof e=="boolean"?Q(yn):De(e)?Q(Pe,null,e.slice()):typeof e=="object"?go(e):Q(Gr,null,String(e))}function go(e){return e.el===null&&e.patchFlag!==-1||e.memo?e:Xr(e)}function _f(e,t){let n=0;const{shapeFlag:r}=e;if(t==null)t=null;else if(De(t))n=16;else if(typeof t=="object")if(r&65){const o=t.default;o&&(o._c&&(o._d=!1),_f(e,o()),o._c&&(o._d=!0));return}else{n=32;const o=t._;!o&&!(Lu in t)?t._ctx=sn:o===3&&sn&&(sn.slots._===1?t._=1:(t._=2,e.patchFlag|=1024))}else Ke(t)?(t={default:t,_ctx:sn},n=32):(t=String(t),r&64?(n=16,t=[Je(t)]):n=8);e.children=t,e.shapeFlag|=n}function Ht(...e){const t={};for(let n=0;nZt||sn;let wf,Sa,fm="__VUE_INSTANCE_SETTERS__";(Sa=Bc()[fm])||(Sa=Bc()[fm]=[]),Sa.push(e=>Zt=e),wf=e=>{Sa.length>1?Sa.forEach(t=>t(e)):Sa[0](e)};const Ka=e=>{wf(e),e.scope.on()},ra=()=>{Zt&&Zt.scope.off(),wf(null)};function Wb(e){return e.vnode.shapeFlag&4}let qa=!1;function ck(e,t=!1){qa=t;const{props:n,children:r}=e.vnode,o=Wb(e);qC(e,n,o,t),XC(e,r);const a=o?dk(e,t):void 0;return qa=!1,a}function dk(e,t){const n=e.type;e.accessCache=Object.create(null),e.proxy=db(new Proxy(e.ctx,VC));const{setup:r}=n;if(r){const o=e.setupContext=r.length>1?Kb(e):null;Ka(e),dl();const a=Eo(r,e,0,[e.props,o]);if(fl(),ra(),Gi(a)){if(a.then(ra,ra),t)return a.then(l=>{pm(e,l,t)}).catch(l=>{xs(l,e,0)});e.asyncDep=a}else pm(e,a,t)}else Ub(e,t)}function pm(e,t,n){Ke(t)?e.type.__ssrInlineRender?e.ssrRender=t:e.render=t:ht(t)&&(e.setupState=mb(t)),Ub(e,n)}let mm;function Ub(e,t,n){const r=e.type;if(!e.render){if(!t&&mm&&!r.render){const o=r.template||gf(e).template;if(o){const{isCustomElement:a,compilerOptions:l}=e.appContext.config,{delimiters:s,compilerOptions:i}=r,u=Wt(Wt({isCustomElement:a,delimiters:s},l),i);r.render=mm(o,u)}}e.render=r.render||en}Ka(e),dl(),BC(e),fl(),ra()}function fk(e){return e.attrsProxy||(e.attrsProxy=new Proxy(e.attrs,{get(t,n){return Ln(e,"get","$attrs"),t[n]}}))}function Kb(e){const t=n=>{e.exposed=n||{}};return{get attrs(){return fk(e)},slots:e.slots,emit:e.emit,expose:t}}function Mu(e){if(e.exposed)return e.exposeProxy||(e.exposeProxy=new Proxy(mb(db(e.exposed)),{get(t,n){if(n in t)return t[n];if(n in Nl)return Nl[n](e)},has(t,n){return n in t||n in Nl}}))}function pk(e,t=!0){return Ke(e)?e.displayName||e.name:e.name||t&&e.__name}function mk(e){return Ke(e)&&"__vccOpts"in e}const O=(e,t)=>vb(e,t,qa);function He(e,t,n){const r=arguments.length;return r===2?ht(t)&&!De(t)?Ua(t)?Q(e,null,[t]):Q(e,t):Q(e,null,t):(r>3?n=Array.prototype.slice.call(arguments,2):r===3&&Ua(n)&&(n=[n]),Q(e,t,n))}const hk=Symbol.for("v-scx"),vk=()=>Re(hk),qb="3.3.4",gk="http://www.w3.org/2000/svg",Go=typeof document!="undefined"?document:null,hm=Go&&Go.createElement("template"),bk={insert:(e,t,n)=>{t.insertBefore(e,n||null)},remove:e=>{const t=e.parentNode;t&&t.removeChild(e)},createElement:(e,t,n,r)=>{const o=t?Go.createElementNS(gk,e):Go.createElement(e,n?{is:n}:void 0);return e==="select"&&r&&r.multiple!=null&&o.setAttribute("multiple",r.multiple),o},createText:e=>Go.createTextNode(e),createComment:e=>Go.createComment(e),setText:(e,t)=>{e.nodeValue=t},setElementText:(e,t)=>{e.textContent=t},parentNode:e=>e.parentNode,nextSibling:e=>e.nextSibling,querySelector:e=>Go.querySelector(e),setScopeId(e,t){e.setAttribute(t,"")},insertStaticContent(e,t,n,r,o,a){const l=n?n.previousSibling:t.lastChild;if(o&&(o===a||o.nextSibling))for(;t.insertBefore(o.cloneNode(!0),n),!(o===a||!(o=o.nextSibling)););else{hm.innerHTML=r?`${e}`:e;const s=hm.content;if(r){const i=s.firstChild;for(;i.firstChild;)s.appendChild(i.firstChild);s.removeChild(i)}t.insertBefore(s,n)}return[l?l.nextSibling:t.firstChild,n?n.previousSibling:t.lastChild]}};function yk(e,t,n){const r=e._vtc;r&&(t=(t?[t,...r]:[...r]).join(" ")),t==null?e.removeAttribute("class"):n?e.setAttribute("class",t):e.className=t}function _k(e,t,n){const r=e.style,o=Ge(n);if(n&&!o){if(t&&!Ge(t))for(const a in t)n[a]==null&&Xc(r,a,"");for(const a in n)Xc(r,a,n[a])}else{const a=r.display;o?t!==n&&(r.cssText=n):t&&e.removeAttribute("style"),"_vod"in e&&(r.display=a)}}const vm=/\s*!important$/;function Xc(e,t,n){if(De(n))n.forEach(r=>Xc(e,t,r));else if(n==null&&(n=""),t.startsWith("--"))e.setProperty(t,n);else{const r=wk(e,t);vm.test(n)?e.setProperty(fa(r),n.replace(vm,""),"important"):e[r]=n}}const gm=["Webkit","Moz","ms"],uc={};function wk(e,t){const n=uc[t];if(n)return n;let r=cr(t);if(r!=="filter"&&r in e)return uc[t]=r;r=$u(r);for(let o=0;occ||(Tk.then(()=>cc=0),cc=Date.now());function Ok(e,t){const n=r=>{if(!r._vts)r._vts=Date.now();else if(r._vts<=n.attached)return;qn(Ak(r,n.value),t,5,[r])};return n.value=e,n.attached=xk(),n}function Ak(e,t){if(De(t)){const n=e.stopImmediatePropagation;return e.stopImmediatePropagation=()=>{n.call(e),e._stopped=!0},t.map(r=>o=>!o._stopped&&r&&r(o))}else return t}const _m=/^on[a-z]/,Ik=(e,t,n,r,o=!1,a,l,s,i)=>{t==="class"?yk(e,r,o):t==="style"?_k(e,n,r):$s(t)?Zd(t)||Ek(e,t,n,r,l):(t[0]==="."?(t=t.slice(1),!0):t[0]==="^"?(t=t.slice(1),!1):Pk(e,t,r,o))?kk(e,t,r,a,l,s,i):(t==="true-value"?e._trueValue=r:t==="false-value"&&(e._falseValue=r),Ck(e,t,r,o))};function Pk(e,t,n,r){return r?!!(t==="innerHTML"||t==="textContent"||t in e&&_m.test(t)&&Ke(n)):t==="spellcheck"||t==="draggable"||t==="translate"||t==="form"||t==="list"&&e.tagName==="INPUT"||t==="type"&&e.tagName==="TEXTAREA"||_m.test(t)&&Ge(n)?!1:t in e}const uo="transition",kl="animation",Mn=(e,{slots:t})=>He(OC,Gb(e),t);Mn.displayName="Transition";const Yb={name:String,type:String,css:{type:Boolean,default:!0},duration:[String,Number,Object],enterFromClass:String,enterActiveClass:String,enterToClass:String,appearFromClass:String,appearActiveClass:String,appearToClass:String,leaveFromClass:String,leaveActiveClass:String,leaveToClass:String},Lk=Mn.props=Wt({},Sb,Yb),zo=(e,t=[])=>{De(e)?e.forEach(n=>n(...t)):e&&e(...t)},wm=e=>e?De(e)?e.some(t=>t.length>1):e.length>1:!1;function Gb(e){const t={};for(const N in e)N in Yb||(t[N]=e[N]);if(e.css===!1)return t;const{name:n="v",type:r,duration:o,enterFromClass:a=`${n}-enter-from`,enterActiveClass:l=`${n}-enter-active`,enterToClass:s=`${n}-enter-to`,appearFromClass:i=a,appearActiveClass:u=l,appearToClass:d=s,leaveFromClass:f=`${n}-leave-from`,leaveActiveClass:h=`${n}-leave-active`,leaveToClass:p=`${n}-leave-to`}=e,v=Mk(o),g=v&&v[0],w=v&&v[1],{onBeforeEnter:m,onEnter:b,onEnterCancelled:_,onLeave:y,onLeaveCancelled:C,onBeforeAppear:k=m,onAppear:E=b,onAppearCancelled:S=_}=t,R=(N,A,M)=>{mo(N,A?d:s),mo(N,A?u:l),M&&M()},L=(N,A)=>{N._isLeaving=!1,mo(N,f),mo(N,p),mo(N,h),A&&A()},F=N=>(A,M)=>{const H=N?E:b,j=()=>R(A,N,M);zo(H,[A,j]),Cm(()=>{mo(A,N?i:a),Fr(A,N?d:s),wm(H)||km(A,r,g,j)})};return Wt(t,{onBeforeEnter(N){zo(m,[N]),Fr(N,a),Fr(N,l)},onBeforeAppear(N){zo(k,[N]),Fr(N,i),Fr(N,u)},onEnter:F(!1),onAppear:F(!0),onLeave(N,A){N._isLeaving=!0;const M=()=>L(N,A);Fr(N,f),Jb(),Fr(N,h),Cm(()=>{!N._isLeaving||(mo(N,f),Fr(N,p),wm(y)||km(N,r,w,M))}),zo(y,[N,M])},onEnterCancelled(N){R(N,!1),zo(_,[N])},onAppearCancelled(N){R(N,!0),zo(S,[N])},onLeaveCancelled(N){L(N),zo(C,[N])}})}function Mk(e){if(e==null)return null;if(ht(e))return[dc(e.enter),dc(e.leave)];{const t=dc(e);return[t,t]}}function dc(e){return S2(e)}function Fr(e,t){t.split(/\s+/).forEach(n=>n&&e.classList.add(n)),(e._vtc||(e._vtc=new Set)).add(t)}function mo(e,t){t.split(/\s+/).forEach(r=>r&&e.classList.remove(r));const{_vtc:n}=e;n&&(n.delete(t),n.size||(e._vtc=void 0))}function Cm(e){requestAnimationFrame(()=>{requestAnimationFrame(e)})}let Rk=0;function km(e,t,n,r){const o=e._endId=++Rk,a=()=>{o===e._endId&&r()};if(n)return setTimeout(a,n);const{type:l,timeout:s,propCount:i}=Xb(e,t);if(!l)return r();const u=l+"end";let d=0;const f=()=>{e.removeEventListener(u,h),a()},h=p=>{p.target===e&&++d>=i&&f()};setTimeout(()=>{d(n[v]||"").split(", "),o=r(`${uo}Delay`),a=r(`${uo}Duration`),l=Sm(o,a),s=r(`${kl}Delay`),i=r(`${kl}Duration`),u=Sm(s,i);let d=null,f=0,h=0;t===uo?l>0&&(d=uo,f=l,h=a.length):t===kl?u>0&&(d=kl,f=u,h=i.length):(f=Math.max(l,u),d=f>0?l>u?uo:kl:null,h=d?d===uo?a.length:i.length:0);const p=d===uo&&/\b(transform|all)(,|$)/.test(r(`${uo}Property`).toString());return{type:d,timeout:f,propCount:h,hasTransform:p}}function Sm(e,t){for(;e.lengthEm(n)+Em(e[r])))}function Em(e){return Number(e.slice(0,-1).replace(",","."))*1e3}function Jb(){return document.body.offsetHeight}const Zb=new WeakMap,Qb=new WeakMap,e0={name:"TransitionGroup",props:Wt({},Lk,{tag:String,moveClass:String}),setup(e,{slots:t}){const n=lt(),r=kb();let o,a;return pl(()=>{if(!o.length)return;const l=e.moveClass||`${e.name||"v"}-move`;if(!zk(o[0].el,n.vnode.el,l))return;o.forEach(Fk),o.forEach(Vk);const s=o.filter(Bk);Jb(),s.forEach(i=>{const u=i.el,d=u.style;Fr(u,l),d.transform=d.webkitTransform=d.transitionDuration="";const f=u._moveCb=h=>{h&&h.target!==u||(!h||/transform$/.test(h.propertyName))&&(u.removeEventListener("transitionend",f),u._moveCb=null,mo(u,l))};u.addEventListener("transitionend",f)})}),()=>{const l=gt(e),s=Gb(l);let i=l.tag||Pe;o=a,a=t.default?pf(t.default()):[];for(let u=0;udelete e.mode;e0.props;const Dk=e0;function Fk(e){const t=e.el;t._moveCb&&t._moveCb(),t._enterCb&&t._enterCb()}function Vk(e){Qb.set(e,e.el.getBoundingClientRect())}function Bk(e){const t=Zb.get(e),n=Qb.get(e),r=t.left-n.left,o=t.top-n.top;if(r||o){const a=e.el.style;return a.transform=a.webkitTransform=`translate(${r}px,${o}px)`,a.transitionDuration="0s",e}}function zk(e,t,n){const r=e.cloneNode();e._vtc&&e._vtc.forEach(l=>{l.split(/\s+/).forEach(s=>s&&r.classList.remove(s))}),n.split(/\s+/).forEach(l=>l&&r.classList.add(l)),r.style.display="none";const o=t.nodeType===1?t:t.parentNode;o.appendChild(r);const{hasTransform:a}=Xb(r);return o.removeChild(r),a}const Ya=e=>{const t=e.props["onUpdate:modelValue"]||!1;return De(t)?n=>xi(t,n):t};function Hk(e){e.target.composing=!0}function $m(e){const t=e.target;t.composing&&(t.composing=!1,t.dispatchEvent(new Event("input")))}const t0={created(e,{modifiers:{lazy:t,trim:n,number:r}},o){e._assign=Ya(o);const a=r||o.props&&o.props.type==="number";_o(e,t?"change":"input",l=>{if(l.target.composing)return;let s=e.value;n&&(s=s.trim()),a&&(s=Vc(s)),e._assign(s)}),n&&_o(e,"change",()=>{e.value=e.value.trim()}),t||(_o(e,"compositionstart",Hk),_o(e,"compositionend",$m),_o(e,"change",$m))},mounted(e,{value:t}){e.value=t==null?"":t},beforeUpdate(e,{value:t,modifiers:{lazy:n,trim:r,number:o}},a){if(e._assign=Ya(a),e.composing||document.activeElement===e&&e.type!=="range"&&(n||r&&e.value.trim()===t||(o||e.type==="number")&&Vc(e.value)===t))return;const l=t==null?"":t;e.value!==l&&(e.value=l)}},ou={deep:!0,created(e,t,n){e._assign=Ya(n),_o(e,"change",()=>{const r=e._modelValue,o=r0(e),a=e.checked,l=e._assign;if(De(r)){const s=Gg(r,o),i=s!==-1;if(a&&!i)l(r.concat(o));else if(!a&&i){const u=[...r];u.splice(s,1),l(u)}}else if(Su(r)){const s=new Set(r);a?s.add(o):s.delete(o),l(s)}else l(o0(e,a))})},mounted:Tm,beforeUpdate(e,t,n){e._assign=Ya(n),Tm(e,t,n)}};function Tm(e,{value:t,oldValue:n},r){e._modelValue=t,De(t)?e.checked=Gg(t,r.props.value)>-1:Su(t)?e.checked=t.has(r.props.value):t!==n&&(e.checked=ja(t,o0(e,!0)))}const n0={created(e,{value:t},n){e.checked=ja(t,n.props.value),e._assign=Ya(n),_o(e,"change",()=>{e._assign(r0(e))})},beforeUpdate(e,{value:t,oldValue:n},r){e._assign=Ya(r),t!==n&&(e.checked=ja(t,r.props.value))}};function r0(e){return"_value"in e?e._value:e.value}function o0(e,t){const n=t?"_trueValue":"_falseValue";return n in e?e[n]:t}const jk=["ctrl","shift","alt","meta"],Wk={stop:e=>e.stopPropagation(),prevent:e=>e.preventDefault(),self:e=>e.target!==e.currentTarget,ctrl:e=>!e.ctrlKey,shift:e=>!e.shiftKey,alt:e=>!e.altKey,meta:e=>!e.metaKey,left:e=>"button"in e&&e.button!==0,middle:e=>"button"in e&&e.button!==1,right:e=>"button"in e&&e.button!==2,exact:(e,t)=>jk.some(n=>e[`${n}Key`]&&!t.includes(n))},$t=(e,t)=>(n,...r)=>{for(let o=0;on=>{if(!("key"in n))return;const r=fa(n.key);if(t.some(o=>o===r||Uk[o]===r))return e(n)},qt={beforeMount(e,{value:t},{transition:n}){e._vod=e.style.display==="none"?"":e.style.display,n&&t?n.beforeEnter(e):Sl(e,t)},mounted(e,{value:t},{transition:n}){n&&t&&n.enter(e)},updated(e,{value:t,oldValue:n},{transition:r}){!t!=!n&&(r?t?(r.beforeEnter(e),Sl(e,!0),r.enter(e)):r.leave(e,()=>{Sl(e,!1)}):Sl(e,t))},beforeUnmount(e,{value:t}){Sl(e,t)}};function Sl(e,t){e.style.display=t?e._vod:"none"}const a0=Wt({patchProp:Ik},bk);let Bl,xm=!1;function Kk(){return Bl||(Bl=QC(a0))}function qk(){return Bl=xm?Bl:ek(a0),xm=!0,Bl}const Om=(...e)=>{Kk().render(...e)},Yk=(...e)=>{const t=qk().createApp(...e),{mount:n}=t;return t.mount=r=>{const o=Gk(r);if(o)return n(o,!0,o instanceof SVGElement)},t};function Gk(e){return Ge(e)?document.querySelector(e):e}const Xk=JSON.parse('{"base":"/","lang":"en-US","title":"SD \u8BAD\u7EC3 UI","description":"","head":[],"locales":{}}');var Jk=([e,t,n])=>e==="meta"&&t.name?`${e}.${t.name}`:["title","base"].includes(e)?e:e==="template"&&t.id?`${e}.${t.id}`:JSON.stringify([e,t,n]),Zk=e=>{const t=new Set,n=[];return e.forEach(r=>{const o=Jk(r);t.has(o)||(t.add(o),n.push(r))}),n},Qk=e=>/^(https?:)?\/\//.test(e),fG=e=>/^mailto:/.test(e),pG=e=>/^tel:/.test(e),l0=e=>Object.prototype.toString.call(e)==="[object Object]",eS=e=>e.replace(/\/$/,""),tS=e=>e.replace(/^\//,""),s0=(e,t)=>{const n=Object.keys(e).sort((r,o)=>{const a=o.split("/").length-r.split("/").length;return a!==0?a:o.length-r.length});for(const r of n)if(t.startsWith(r))return r;return"/"};const i0={"v-8daa1a0e":Jt(()=>wt(()=>import("./index.html.c6ef684b.js"),[])),"v-6983ba2a":Jt(()=>wt(()=>import("./tageditor.html.173f1b6a.js"),[])),"v-51615306":Jt(()=>wt(()=>import("./tagger.html.0daaef4e.js"),[])),"v-06850b9b":Jt(()=>wt(()=>import("./task.html.256f458b.js"),[])),"v-13efe3c5":Jt(()=>wt(()=>import("./tensorboard.html.9c3b4542.js"),[])),"v-33a23463":Jt(()=>wt(()=>import("./index.html.911dc78d.js"),[])),"v-b5471278":Jt(()=>wt(()=>import("./about.html.b4807002.js"),[])),"v-a1c9e4f2":Jt(()=>wt(()=>import("./changelog.html.e5f6a7b8.js"),[])),"v-b8e2d701":Jt(()=>wt(()=>import("./guide.html.c3f4a902.js"),[])),"v-72e1da3e":Jt(()=>wt(()=>import("./settings.html.07aaabcc.js"),[])),"v-3e43d6e2":Jt(()=>wt(()=>import("./basic.html.eb26832d.js"),[])),"v-fdbe4e28":Jt(()=>wt(()=>import("./flux.html.f22f5932.js"),[])),"v-14e91824":Jt(()=>wt(()=>import("./index.html.4896b94d.js"),[])),"v-1bf725da":Jt(()=>wt(()=>import("./master.html.404f21be.js"),[])),"v-0f9e746f":Jt(()=>wt(()=>import("./params.html.dea583bc.js"),[])),"v-0dc76a3b":Jt(()=>wt(()=>import("./sd3.html.1a4bf31e.js"),[])),"v-a1f1ne2e":Jt(()=>wt(()=>import("./anima-finetune.html.1a4bf32e.js"),[])),"v-53c99f50":Jt(()=>wt(()=>import("./sdxl.html.33fa069c.js"),[])),"v-4441a302":Jt(()=>wt(()=>import("./tools.html.6c8bfc09.js"),[])),"v-3706649a":Jt(()=>wt(()=>import("./404.html.7a24a487.js"),[]))},nS={404:Jt(()=>wt(()=>import("./404.47057000.js"),[])),Layout:Jt(()=>wt(()=>import("./layout.96d49288.js"),[]))};var u0=B(b2),c0=pa({key:"",path:"",title:"",lang:"",frontmatter:{},excerpt:"",headers:[]}),jr=B(c0),Ps=()=>jr;zp.webpackHot&&(__VUE_HMR_RUNTIME__.updatePageData=e=>{u0.value[e.key]=()=>Promise.resolve(e),e.key===jr.value.key&&(jr.value=e)});var d0=Symbol(""),rS=()=>{const e=Re(d0);if(!e)throw new Error("usePageFrontmatter() is called without provider.");return e},f0=Symbol(""),oS=()=>{const e=Re(f0);if(!e)throw new Error("usePageHead() is called without provider.");return e},aS=Symbol(""),p0=Symbol(""),lS=()=>{const e=Re(p0);if(!e)throw new Error("usePageLang() is called without provider.");return e},Cf=Symbol(""),sS=()=>{const e=Re(Cf);if(!e)throw new Error("useRouteLocale() is called without provider.");return e},wo=B(Xk),iS=()=>wo;zp.webpackHot&&(__VUE_HMR_RUNTIME__.updateSiteData=e=>{wo.value=e});var m0=Symbol(""),mG=()=>{const e=Re(m0);if(!e)throw new Error("useSiteLocaleData() is called without provider.");return e},uS=Symbol(""),Wo=Xt({resolvePageData:async e=>{const t=u0.value[e],n=await(t==null?void 0:t());return n!=null?n:c0},resolvePageFrontmatter:e=>e.frontmatter,resolvePageHead:(e,t,n)=>{const r=Ge(t.description)?t.description:n.description,o=[...De(t.head)?t.head:[],...n.head,["title",{},e],["meta",{name:"description",content:r}]];return Zk(o)},resolvePageHeadTitle:(e,t)=>`${e.title?`${e.title} | `:""}${t.title}`,resolvePageLang:e=>e.lang||"en",resolveRouteLocale:(e,t)=>s0(e,t),resolveSiteLocaleData:(e,t)=>({...e,...e.locales[t]})}),cS=se({name:"ClientOnly",setup(e,t){const n=B(!1);return dt(()=>{n.value=!0}),()=>{var r,o;return n.value?(o=(r=t.slots).default)==null?void 0:o.call(r):null}}}),dS=se({name:"Content",props:{pageKey:{type:String,required:!1,default:""}},setup(e){const t=Ps(),n=O(()=>i0[e.pageKey||t.value.key]);return()=>n.value?He(n.value):He("div","404 Not Found")}}),Am=se({name:"Vuepress",setup(){const e=Ps(),t=O(()=>{let n;if(e.value.path){const r=e.value.frontmatter.layout;Ge(r)?n=r:n="Layout"}else n="404";return nS[n]||Ve(n,!1)});return()=>He(t.value)}}),fS=e=>Qk(e)?e:`${iS().value.base}${tS(e)}`,Ro=e=>e;function h0(e,t,n){var r,o,a;t===void 0&&(t=50),n===void 0&&(n={});var l=(r=n.isImmediate)!=null&&r,s=(o=n.callback)!=null&&o,i=n.maxWait,u=Date.now(),d=[];function f(){if(i!==void 0){var p=Date.now()-u;if(p+t>=i)return i-p}return t}var h=function(){var p=[].slice.call(arguments),v=this;return new Promise(function(g,w){var m=l&&a===void 0;if(a!==void 0&&clearTimeout(a),a=setTimeout(function(){if(a=void 0,u=Date.now(),!l){var _=e.apply(v,p);s&&s(_),d.forEach(function(y){return(0,y.resolve)(_)}),d=[]}},f()),m){var b=e.apply(v,p);return s&&s(b),g(b)}d.push({resolve:g,reject:w})})};return h.cancel=function(p){a!==void 0&&clearTimeout(a),d.forEach(function(v){return(0,v.reject)(p)}),d=[]},h}/*! * vue-router v4.2.4 * (c) 2023 Eduardo San Martin Morote * @license MIT @@ -7,7 +7,7 @@ Expects a CSS selector, a Node element, a NodeList or an array. See: https://github.com/francoischalifour/medium-zoom`)}},OE=function(t){var n=document.createElement("div");return n.classList.add("medium-zoom-overlay"),n.style.background=t,n},AE=function(t){var n=t.getBoundingClientRect(),r=n.top,o=n.left,a=n.width,l=n.height,s=t.cloneNode(),i=window.pageYOffset||document.documentElement.scrollTop||document.body.scrollTop||0,u=window.pageXOffset||document.documentElement.scrollLeft||document.body.scrollLeft||0;return s.removeAttribute("id"),s.style.position="absolute",s.style.top=r+i+"px",s.style.left=o+u+"px",s.style.width=a+"px",s.style.height=l+"px",s.style.transform="",s},Ea=function(t,n){var r=Uo({bubbles:!1,cancelable:!1,detail:void 0},n);if(typeof window.CustomEvent=="function")return new CustomEvent(t,r);var o=document.createEvent("CustomEvent");return o.initCustomEvent(t,r.bubbles,r.cancelable,r.detail),o},IE=function e(t){var n=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{},r=window.Promise||function(N){function A(){}N(A,A)},o=function(N){var A=N.target;if(A===R){v();return}_.indexOf(A)!==-1&&g({target:A})},a=function(){if(!(C||!S.original)){var N=window.pageYOffset||document.documentElement.scrollTop||document.body.scrollTop||0;Math.abs(k-N)>E.scrollOffset&&setTimeout(v,150)}},l=function(N){var A=N.key||N.keyCode;(A==="Escape"||A==="Esc"||A===27)&&v()},s=function(){var N=arguments.length>0&&arguments[0]!==void 0?arguments[0]:{},A=N;if(N.background&&(R.style.background=N.background),N.container&&N.container instanceof Object&&(A.container=Uo({},E.container,N.container)),N.template){var M=Ai(N.template)?N.template:document.querySelector(N.template);A.template=M}return E=Uo({},E,A),_.forEach(function(H){H.dispatchEvent(Ea("medium-zoom:update",{detail:{zoom:L}}))}),L},i=function(){var N=arguments.length>0&&arguments[0]!==void 0?arguments[0]:{};return e(Uo({},E,N))},u=function(){for(var N=arguments.length,A=Array(N),M=0;M0?A.reduce(function(j,V){return[].concat(j,Xm(V))},[]):_;return H.forEach(function(j){j.classList.remove("medium-zoom-image"),j.dispatchEvent(Ea("medium-zoom:detach",{detail:{zoom:L}}))}),_=_.filter(function(j){return H.indexOf(j)===-1}),L},f=function(N,A){var M=arguments.length>2&&arguments[2]!==void 0?arguments[2]:{};return _.forEach(function(H){H.addEventListener("medium-zoom:"+N,A,M)}),y.push({type:"medium-zoom:"+N,listener:A,options:M}),L},h=function(N,A){var M=arguments.length>2&&arguments[2]!==void 0?arguments[2]:{};return _.forEach(function(H){H.removeEventListener("medium-zoom:"+N,A,M)}),y=y.filter(function(H){return!(H.type==="medium-zoom:"+N&&H.listener.toString()===A.toString())}),L},p=function(){var N=arguments.length>0&&arguments[0]!==void 0?arguments[0]:{},A=N.target,M=function(){var j={width:document.documentElement.clientWidth,height:document.documentElement.clientHeight,left:0,top:0,right:0,bottom:0},V=void 0,X=void 0;if(E.container)if(E.container instanceof Object)j=Uo({},j,E.container),V=j.width-j.left-j.right-E.margin*2,X=j.height-j.top-j.bottom-E.margin*2;else{var I=Ai(E.container)?E.container:document.querySelector(E.container),Y=I.getBoundingClientRect(),ee=Y.width,W=Y.height,re=Y.left,be=Y.top;j=Uo({},j,{width:ee,height:W,left:re,top:be})}V=V||j.width-E.margin*2,X=X||j.height-E.margin*2;var Te=S.zoomedHd||S.original,ge=Gm(Te)?V:Te.naturalWidth||V,J=Gm(Te)?X:Te.naturalHeight||X,te=Te.getBoundingClientRect(),ae=te.top,le=te.left,me=te.width,P=te.height,$=Math.min(Math.max(me,ge),V)/me,T=Math.min(Math.max(P,J),X)/P,z=Math.min($,T),Z=(-le+(V-me)/2+E.margin+j.left)/z,oe=(-ae+(X-P)/2+E.margin+j.top)/z,_e="scale("+z+") translate3d("+Z+"px, "+oe+"px, 0)";S.zoomed.style.transform=_e,S.zoomedHd&&(S.zoomedHd.style.transform=_e)};return new r(function(H){if(A&&_.indexOf(A)===-1){H(L);return}var j=function ee(){C=!1,S.zoomed.removeEventListener("transitionend",ee),S.original.dispatchEvent(Ea("medium-zoom:opened",{detail:{zoom:L}})),H(L)};if(S.zoomed){H(L);return}if(A)S.original=A;else if(_.length>0){var V=_;S.original=V[0]}else{H(L);return}if(S.original.dispatchEvent(Ea("medium-zoom:open",{detail:{zoom:L}})),k=window.pageYOffset||document.documentElement.scrollTop||document.body.scrollTop||0,C=!0,S.zoomed=AE(S.original),document.body.appendChild(R),E.template){var X=Ai(E.template)?E.template:document.querySelector(E.template);S.template=document.createElement("div"),S.template.appendChild(X.content.cloneNode(!0)),document.body.appendChild(S.template)}if(S.original.parentElement&&S.original.parentElement.tagName==="PICTURE"&&S.original.currentSrc&&(S.zoomed.src=S.original.currentSrc),document.body.appendChild(S.zoomed),window.requestAnimationFrame(function(){document.body.classList.add("medium-zoom--opened")}),S.original.classList.add("medium-zoom-image--hidden"),S.zoomed.classList.add("medium-zoom-image--opened"),S.zoomed.addEventListener("click",v),S.zoomed.addEventListener("transitionend",j),S.original.getAttribute("data-zoom-src")){S.zoomedHd=S.zoomed.cloneNode(),S.zoomedHd.removeAttribute("srcset"),S.zoomedHd.removeAttribute("sizes"),S.zoomedHd.removeAttribute("loading"),S.zoomedHd.src=S.zoomed.getAttribute("data-zoom-src"),S.zoomedHd.onerror=function(){clearInterval(I),console.warn("Unable to reach the zoom image target "+S.zoomedHd.src),S.zoomedHd=null,M()};var I=setInterval(function(){S.zoomedHd.complete&&(clearInterval(I),S.zoomedHd.classList.add("medium-zoom-image--opened"),S.zoomedHd.addEventListener("click",v),document.body.appendChild(S.zoomedHd),M())},10)}else if(S.original.hasAttribute("srcset")){S.zoomedHd=S.zoomed.cloneNode(),S.zoomedHd.removeAttribute("sizes"),S.zoomedHd.removeAttribute("loading");var Y=S.zoomedHd.addEventListener("load",function(){S.zoomedHd.removeEventListener("load",Y),S.zoomedHd.classList.add("medium-zoom-image--opened"),S.zoomedHd.addEventListener("click",v),document.body.appendChild(S.zoomedHd),M()})}else M()})},v=function(){return new r(function(N){if(C||!S.original){N(L);return}var A=function M(){S.original.classList.remove("medium-zoom-image--hidden"),document.body.removeChild(S.zoomed),S.zoomedHd&&document.body.removeChild(S.zoomedHd),document.body.removeChild(R),S.zoomed.classList.remove("medium-zoom-image--opened"),S.template&&document.body.removeChild(S.template),C=!1,S.zoomed.removeEventListener("transitionend",M),S.original.dispatchEvent(Ea("medium-zoom:closed",{detail:{zoom:L}})),S.original=null,S.zoomed=null,S.zoomedHd=null,S.template=null,N(L)};C=!0,document.body.classList.remove("medium-zoom--opened"),S.zoomed.style.transform="",S.zoomedHd&&(S.zoomedHd.style.transform=""),S.template&&(S.template.style.transition="opacity 150ms",S.template.style.opacity=0),S.original.dispatchEvent(Ea("medium-zoom:close",{detail:{zoom:L}})),S.zoomed.addEventListener("transitionend",A)})},g=function(){var N=arguments.length>0&&arguments[0]!==void 0?arguments[0]:{},A=N.target;return S.original?v():p({target:A})},w=function(){return E},m=function(){return _},b=function(){return S.original},_=[],y=[],C=!1,k=0,E=n,S={original:null,zoomed:null,zoomedHd:null,template:null};Object.prototype.toString.call(t)==="[object Object]"?E=t:(t||typeof t=="string")&&u(t),E=Uo({margin:0,background:"#fff",scrollOffset:40,container:null,template:null},E);var R=OE(E.background);document.addEventListener("click",o),document.addEventListener("keyup",l),document.addEventListener("scroll",a),window.addEventListener("resize",v);var L={open:p,close:v,toggle:g,update:s,clone:i,attach:u,detach:d,on:f,off:h,getOptions:w,getImages:m,getZoomedImage:b};return L};function PE(e,t){t===void 0&&(t={});var n=t.insertAt;if(!(!e||typeof document=="undefined")){var r=document.head||document.getElementsByTagName("head")[0],o=document.createElement("style");o.type="text/css",n==="top"&&r.firstChild?r.insertBefore(o,r.firstChild):r.appendChild(o),o.styleSheet?o.styleSheet.cssText=e:o.appendChild(document.createTextNode(e))}}var LE=".medium-zoom-overlay{position:fixed;top:0;right:0;bottom:0;left:0;opacity:0;transition:opacity .3s;will-change:opacity}.medium-zoom--opened .medium-zoom-overlay{cursor:pointer;cursor:zoom-out;opacity:1}.medium-zoom-image{cursor:pointer;cursor:zoom-in;transition:transform .3s cubic-bezier(.2,0,.2,1)!important}.medium-zoom-image--hidden{visibility:hidden}.medium-zoom-image--opened{position:relative;cursor:pointer;cursor:zoom-out;will-change:transform}";PE(LE);var ME=IE;const RE=Symbol("mediumZoom");const NE=".theme-default-content > img, .theme-default-content :not(a) > img",DE={},FE=300;var VE=Ro({enhance({app:e,router:t}){const n=ME(DE);n.refresh=(r=NE)=>{n.detach(),n.attach(r)},e.provide(RE,n),t.afterEach(()=>{setTimeout(()=>n.refresh(),FE)})}});/** * NProgress, (c) 2013, 2014 Rico Sta. Cruz - http://ricostacruz.com/nprogress * @license MIT - */const Tt={settings:{minimum:.08,easing:"ease",speed:200,trickle:!0,trickleRate:.02,trickleSpeed:800,barSelector:'[role="bar"]',parent:"body",template:'
'},status:null,set:e=>{const t=Tt.isStarted();e=hc(e,Tt.settings.minimum,1),Tt.status=e===1?null:e;const n=Tt.render(!t),r=n.querySelector(Tt.settings.barSelector),o=Tt.settings.speed,a=Tt.settings.easing;return n.offsetWidth,BE(l=>{ri(r,{transform:"translate3d("+Jm(e)+"%,0,0)",transition:"all "+o+"ms "+a}),e===1?(ri(n,{transition:"none",opacity:"1"}),n.offsetWidth,setTimeout(function(){ri(n,{transition:"all "+o+"ms linear",opacity:"0"}),setTimeout(function(){Tt.remove(),l()},o)},o)):setTimeout(()=>l(),o)}),Tt},isStarted:()=>typeof Tt.status=="number",start:()=>{Tt.status||Tt.set(0);const e=()=>{setTimeout(()=>{!Tt.status||(Tt.trickle(),e())},Tt.settings.trickleSpeed)};return Tt.settings.trickle&&e(),Tt},done:e=>!e&&!Tt.status?Tt:Tt.inc(.3+.5*Math.random()).set(1),inc:e=>{let t=Tt.status;return t?(typeof e!="number"&&(e=(1-t)*hc(Math.random()*t,.1,.95)),t=hc(t+e,0,.994),Tt.set(t)):Tt.start()},trickle:()=>Tt.inc(Math.random()*Tt.settings.trickleRate),render:e=>{if(Tt.isRendered())return document.getElementById("nprogress");Zm(document.documentElement,"nprogress-busy");const t=document.createElement("div");t.id="nprogress",t.innerHTML=Tt.settings.template;const n=t.querySelector(Tt.settings.barSelector),r=e?"-100":Jm(Tt.status||0),o=document.querySelector(Tt.settings.parent);return ri(n,{transition:"all 0 linear",transform:"translate3d("+r+"%,0,0)"}),o!==document.body&&Zm(o,"nprogress-custom-parent"),o==null||o.appendChild(t),t},remove:()=>{Qm(document.documentElement,"nprogress-busy"),Qm(document.querySelector(Tt.settings.parent),"nprogress-custom-parent");const e=document.getElementById("nprogress");e&&zE(e)},isRendered:()=>!!document.getElementById("nprogress")},hc=(e,t,n)=>en?n:e,Jm=e=>(-1+e)*100,BE=function(){const e=[];function t(){const n=e.shift();n&&n(t)}return function(n){e.push(n),e.length===1&&t()}}(),ri=function(){const e=["Webkit","O","Moz","ms"],t={};function n(l){return l.replace(/^-ms-/,"ms-").replace(/-([\da-z])/gi,function(s,i){return i.toUpperCase()})}function r(l){const s=document.body.style;if(l in s)return l;let i=e.length;const u=l.charAt(0).toUpperCase()+l.slice(1);let d;for(;i--;)if(d=e[i]+u,d in s)return d;return l}function o(l){return l=n(l),t[l]||(t[l]=r(l))}function a(l,s,i){s=o(s),l.style[s]=i}return function(l,s){for(const i in s){const u=s[i];u!==void 0&&Object.prototype.hasOwnProperty.call(s,i)&&a(l,i,u)}}}(),T0=(e,t)=>(typeof e=="string"?e:Tf(e)).indexOf(" "+t+" ")>=0,Zm=(e,t)=>{const n=Tf(e),r=n+t;T0(n,t)||(e.className=r.substring(1))},Qm=(e,t)=>{const n=Tf(e);if(!T0(e,t))return;const r=n.replace(" "+t+" "," ");e.className=r.substring(1,r.length-1)},Tf=e=>(" "+(e.className||"")+" ").replace(/\s+/gi," "),zE=e=>{e&&e.parentNode&&e.parentNode.removeChild(e)};const HE=()=>{dt(()=>{const e=Ef(),t=new Set;t.add(e.currentRoute.value.path),e.beforeEach(n=>{t.has(n.path)||Tt.start()}),e.afterEach(n=>{t.add(n.path),Tt.done()})})};var jE=Ro({setup(){HE()}});const WE=JSON.parse(`{"navbar":false,"sidebar":[{"text":"Next Trainer","link":"/"},{"text":"训练","children":[{"text":"LoRA 训练","link":"/lora/index.md","collapsible":false,"children":[{"text":"Anima LoRA","link":"/lora/sd3.md"},{"text":"Flux","link":"/lora/flux.md"},{"text":"Stable Diffusion","link":"/lora/master.md"}]},{"text":"\u5168\u91cf\u5fae\u8c03","link":"/lora/anima-finetune.md","collapsible":false,"children":[{"text":"Anima Finetune","link":"/lora/anima-finetune.md"},{"text":"Stable Diffusion","link":"/dreambooth/index.md"}]}]},{"text":"工具与调试","children":[{"text":"Tensorboard","link":"/tensorboard.md"},{"text":"数据集打标","link":"/tagger.md"},{"text":"标签编辑","link":"/tageditor.md"},{"text":"LoRA 脚本工具","link":"/lora/tools.md"}]},{"text":"帮助","children":[{"text":"新手上路","link":"/help/guide.md"},{"text":"训练参数说明","link":"/lora/params.md"}]},{"text":"其他","collapsible":false,"children":[{"text":"UI 设置","link":"/other/settings.md"},{"text":"关于","link":"/other/about.md"},{"text":"更新日志","link":"/other/changelog.md"}]}],"locales":{"/":{"selectLanguageName":"English"}},"colorMode":"auto","colorModeSwitch":true,"logo":null,"repo":null,"selectLanguageText":"Languages","selectLanguageAriaLabel":"Select language","sidebarDepth":2,"editLink":true,"editLinkText":"Edit this page","lastUpdated":true,"lastUpdatedText":"Last Updated","contributors":true,"contributorsText":"Contributors","notFound":["There's nothing here.","How did we get here?","That's a Four-Oh-Four.","Looks like we've got some broken links."],"backToHome":"Take me home","openInNewWindow":"open in new window","toggleColorMode":"toggle color mode","toggleSidebar":"toggle sidebar"}`),x0=B(WE),UE=()=>x0;zp.webpackHot&&(__VUE_HMR_RUNTIME__.updateThemeData=e=>{x0.value=e});const O0=Symbol(""),KE=()=>{const e=Re(O0);if(!e)throw new Error("useThemeLocaleData() is called without provider.");return e},qE=(e,t)=>{var n;return{...e,...(n=e.locales)==null?void 0:n[t]}};var YE=Ro({enhance({app:e}){const t=UE(),n=e._context.provides[Cf],r=O(()=>qE(t.value,n.value));e.provide(O0,r),Object.defineProperties(e.config.globalProperties,{$theme:{get(){return t.value}},$themeLocale:{get(){return r.value}}})}}),St=(e,t)=>{const n=e.__vccOpts||e;for(const[r,o]of t)n[r]=o;return n};const GE=se({__name:"Badge",props:{type:{type:String,required:!1,default:"tip"},text:{type:String,required:!1,default:""},vertical:{type:String,required:!1,default:void 0}},setup(e){return(t,n)=>(x(),U("span",{class:D(["badge",e.type]),style:Qe({verticalAlign:e.vertical})},[pe(t.$slots,"default",{},()=>[Je(Ee(e.text),1)])],6))}});var XE=St(GE,[["__file","Badge.vue"]]);const JE=se({name:"CodeGroup",setup(e,{slots:t}){const n=B(-1),r=B([]),o=(s=n.value)=>{s{s>0?n.value=s-1:n.value=r.value.length-1,r.value[n.value].focus()},l=(s,i)=>{s.key===" "||s.key==="Enter"?(s.preventDefault(),n.value=i):s.key==="ArrowRight"?(s.preventDefault(),o(i)):s.key==="ArrowLeft"&&(s.preventDefault(),a(i))};return()=>{var i;const s=(((i=t.default)==null?void 0:i.call(t))||[]).filter(u=>u.type.name==="CodeGroupItem").map(u=>(u.props===null&&(u.props={}),u));return s.length===0?null:(n.value<0||n.value>s.length-1?(n.value=s.findIndex(u=>u.props.active===""||u.props.active===!0),n.value===-1&&(n.value=0)):s.forEach((u,d)=>{u.props.active=d===n.value}),He("div",{class:"code-group"},[He("div",{class:"code-group__nav"},He("ul",{class:"code-group__ul"},s.map((u,d)=>{const f=d===n.value;return He("li",{class:"code-group__li"},He("button",{ref:h=>{h&&(r.value[d]=h)},class:{"code-group__nav-tab":!0,"code-group__nav-tab-active":f},ariaPressed:f,ariaExpanded:f,onClick:()=>n.value=d,onKeydown:h=>l(h,d)},u.props.title))}))),s]))}}}),ZE=["aria-selected"],QE=se({name:"CodeGroupItem"}),e$=se({...QE,props:{title:{type:String,required:!0},active:{type:Boolean,required:!1,default:!1}},setup(e){return(t,n)=>(x(),U("div",{class:D(["code-group-item",{"code-group-item__active":e.active}]),"aria-selected":e.active},[pe(t.$slots,"default")],10,ZE))}});var t$=St(e$,[["__file","CodeGroupItem.vue"]]),n$=!0;function Ls(e){return Zg()?(Qg(e),!0):!1}var r$=Object.defineProperty,eh=Object.getOwnPropertySymbols,o$=Object.prototype.hasOwnProperty,a$=Object.prototype.propertyIsEnumerable,th=(e,t,n)=>t in e?r$(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n,l$=(e,t)=>{for(var n in t||(t={}))o$.call(t,n)&&th(e,n,t[n]);if(eh)for(var n of eh(t))a$.call(t,n)&&th(e,n,t[n]);return e};function s$(e,t){if(typeof Symbol!="undefined"){const n=l$({},e);return Object.defineProperty(n,Symbol.iterator,{enumerable:!1,value(){let r=0;return{next:()=>({value:t[r++],done:r>t.length})}}}),n}else return Object.assign([...t],e)}function Jr(e){return typeof e=="function"?e():c(e)}const xt=typeof window!="undefined",ss=()=>{},A0=i$();function i$(){var e;return xt&&((e=window==null?void 0:window.navigator)==null?void 0:e.userAgent)&&/iP(ad|hone|od)/.test(window.navigator.userAgent)}function I0(e,t){function n(...r){return new Promise((o,a)=>{Promise.resolve(e(()=>t.apply(this,r),{fn:t,thisArg:this,args:r})).then(o).catch(a)})}return n}const P0=e=>e();function u$(e,t={}){let n,r,o=ss;const a=s=>{clearTimeout(s),o(),o=ss};return s=>{const i=Jr(e),u=Jr(t.maxWait);return n&&a(n),i<=0||u!==void 0&&u<=0?(r&&(a(r),r=null),Promise.resolve(s())):new Promise((d,f)=>{o=t.rejectOnCancel?f:d,u&&!r&&(r=setTimeout(()=>{n&&a(n),r=null,d(s())},u)),n=setTimeout(()=>{r&&a(r),r=null,d(s())},i)})}}function c$(e=P0){const t=B(!0);function n(){t.value=!1}function r(){t.value=!0}const o=(...a)=>{t.value&&e(...a)};return{isActive:pa(t),pause:n,resume:r,eventFilter:o}}function d$(e){const t=Object.create(null);return n=>t[n]||(t[n]=e(n))}const f$=/-(\w)/g,p$=d$(e=>e.replace(f$,(t,n)=>n?n.toUpperCase():""));function m$(e,t=200,n={}){return I0(u$(t,n),e)}function h$(e,t=200,n={}){const r=B(e.value),o=m$(()=>{r.value=e.value},t,n);return $e(e,()=>o()),r}function ed(e,t,n={}){const{immediate:r=!0}=n,o=B(!1);let a=null;function l(){a&&(clearTimeout(a),a=null)}function s(){o.value=!1,l()}function i(...u){l(),o.value=!0,a=setTimeout(()=>{o.value=!1,a=null,e(...u)},Jr(t))}return r&&(o.value=!0,xt&&i()),Ls(s),{isPending:pa(o),start:i,stop:s}}function hG(e=!1,t={}){const{truthyValue:n=!0,falsyValue:r=!1}=t,o=mt(e),a=B(e);function l(s){if(arguments.length)return a.value=s,a.value;{const i=Jr(n);return a.value=a.value===i?Jr(r):i,a.value}}return o?l:[a,l]}var nh=Object.getOwnPropertySymbols,v$=Object.prototype.hasOwnProperty,g$=Object.prototype.propertyIsEnumerable,b$=(e,t)=>{var n={};for(var r in e)v$.call(e,r)&&t.indexOf(r)<0&&(n[r]=e[r]);if(e!=null&&nh)for(var r of nh(e))t.indexOf(r)<0&&g$.call(e,r)&&(n[r]=e[r]);return n};function y$(e,t,n={}){const r=n,{eventFilter:o=P0}=r,a=b$(r,["eventFilter"]);return $e(e,I0(o,t),a)}var _$=Object.defineProperty,w$=Object.defineProperties,C$=Object.getOwnPropertyDescriptors,lu=Object.getOwnPropertySymbols,L0=Object.prototype.hasOwnProperty,M0=Object.prototype.propertyIsEnumerable,rh=(e,t,n)=>t in e?_$(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n,k$=(e,t)=>{for(var n in t||(t={}))L0.call(t,n)&&rh(e,n,t[n]);if(lu)for(var n of lu(t))M0.call(t,n)&&rh(e,n,t[n]);return e},S$=(e,t)=>w$(e,C$(t)),E$=(e,t)=>{var n={};for(var r in e)L0.call(e,r)&&t.indexOf(r)<0&&(n[r]=e[r]);if(e!=null&&lu)for(var r of lu(e))t.indexOf(r)<0&&M0.call(e,r)&&(n[r]=e[r]);return n};function $$(e,t,n={}){const r=n,{eventFilter:o}=r,a=E$(r,["eventFilter"]),{eventFilter:l,pause:s,resume:i,isActive:u}=c$(o);return{stop:y$(e,t,S$(k$({},a),{eventFilter:l})),pause:s,resume:i,isActive:u}}var T$=Object.defineProperty,x$=Object.defineProperties,O$=Object.getOwnPropertyDescriptors,oh=Object.getOwnPropertySymbols,A$=Object.prototype.hasOwnProperty,I$=Object.prototype.propertyIsEnumerable,ah=(e,t,n)=>t in e?T$(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n,P$=(e,t)=>{for(var n in t||(t={}))A$.call(t,n)&&ah(e,n,t[n]);if(oh)for(var n of oh(t))I$.call(t,n)&&ah(e,n,t[n]);return e},L$=(e,t)=>x$(e,O$(t));function R0(e={}){if(!n$&&!qb.startsWith("2.7."))return;const{inheritAttrs:t=!0}=e,n=On(),r=se({setup(a,{slots:l}){return()=>{n.value=l.default}}}),o=se({inheritAttrs:t,setup(a,{attrs:l,slots:s}){return()=>{var i;n.value;const u=(i=n.value)==null?void 0:i.call(n,L$(P$({},M$(l)),{$slots:s}));return t&&(u==null?void 0:u.length)===1?u[0]:u}}});return s$({define:r,reuse:o},[r,o])}function M$(e){const t={};for(const n in e)t[p$(n)]=e[n];return t}function Kr(e){var t;const n=Jr(e);return(t=n==null?void 0:n.$el)!=null?t:n}const Ja=xt?window:void 0;xt&&window.document;xt&&window.navigator;xt&&window.location;function An(...e){let t,n,r,o;if(typeof e[0]=="string"||Array.isArray(e[0])?([n,r,o]=e,t=Ja):[t,n,r,o]=e,!t)return ss;Array.isArray(n)||(n=[n]),Array.isArray(r)||(r=[r]);const a=[],l=()=>{a.forEach(d=>d()),a.length=0},s=(d,f,h,p)=>(d.addEventListener(f,h,p),()=>d.removeEventListener(f,h,p)),i=$e(()=>[Kr(t),Jr(o)],([d,f])=>{l(),d&&a.push(...n.flatMap(h=>r.map(p=>s(d,h,p,f))))},{immediate:!0,flush:"post"}),u=()=>{i(),l()};return Ls(u),u}let lh=!1;function N0(e,t,n={}){const{window:r=Ja,ignore:o=[],capture:a=!0,detectIframe:l=!1}=n;if(!r)return;A0&&!lh&&(lh=!0,Array.from(r.document.body.children).forEach(h=>h.addEventListener("click",ss)),r.document.documentElement.addEventListener("click",ss));let s=!0;const i=h=>o.some(p=>{if(typeof p=="string")return Array.from(r.document.querySelectorAll(p)).some(v=>v===h.target||h.composedPath().includes(v));{const v=Kr(p);return v&&(h.target===v||h.composedPath().includes(v))}}),d=[An(r,"click",h=>{const p=Kr(e);if(!(!p||p===h.target||h.composedPath().includes(p))){if(h.detail===0&&(s=!i(h)),!s){s=!0;return}t(h)}},{passive:!0,capture:a}),An(r,"pointerdown",h=>{const p=Kr(e);p&&(s=!h.composedPath().includes(p)&&!i(h))},{passive:!0}),l&&An(r,"blur",h=>{setTimeout(()=>{var p;const v=Kr(e);((p=r.document.activeElement)==null?void 0:p.tagName)==="IFRAME"&&!(v!=null&&v.contains(r.document.activeElement))&&t(h)},0)})].filter(Boolean);return()=>d.forEach(h=>h())}function R$(){const e=B(!1);return lt()&&dt(()=>{e.value=!0}),e}function D0(e){const t=R$();return O(()=>(t.value,Boolean(e())))}function N$(e,t={}){const{window:n=Ja}=t,r=D0(()=>n&&"matchMedia"in n&&typeof n.matchMedia=="function");let o;const a=B(!1),l=u=>{a.value=u.matches},s=()=>{!o||("removeEventListener"in o?o.removeEventListener("change",l):o.removeListener(l))},i=qr(()=>{!r.value||(s(),o=n.matchMedia(Jr(e)),"addEventListener"in o?o.addEventListener("change",l):o.addListener(l),a.value=o.matches)});return Ls(()=>{i(),s(),o=void 0}),a}const oi=typeof globalThis!="undefined"?globalThis:typeof window!="undefined"?window:typeof global!="undefined"?global:typeof self!="undefined"?self:{},ai="__vueuse_ssr_handlers__",D$=F$();function F$(){return ai in oi||(oi[ai]=oi[ai]||{}),oi[ai]}function V$(e,t){return D$[e]||t}function B$(e){return e==null?"any":e instanceof Set?"set":e instanceof Map?"map":e instanceof Date?"date":typeof e=="boolean"?"boolean":typeof e=="string"?"string":typeof e=="object"?"object":Number.isNaN(e)?"any":"number"}var z$=Object.defineProperty,sh=Object.getOwnPropertySymbols,H$=Object.prototype.hasOwnProperty,j$=Object.prototype.propertyIsEnumerable,ih=(e,t,n)=>t in e?z$(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n,uh=(e,t)=>{for(var n in t||(t={}))H$.call(t,n)&&ih(e,n,t[n]);if(sh)for(var n of sh(t))j$.call(t,n)&&ih(e,n,t[n]);return e};const W$={boolean:{read:e=>e==="true",write:e=>String(e)},object:{read:e=>JSON.parse(e),write:e=>JSON.stringify(e)},number:{read:e=>Number.parseFloat(e),write:e=>String(e)},any:{read:e=>e,write:e=>String(e)},string:{read:e=>e,write:e=>String(e)},map:{read:e=>new Map(JSON.parse(e)),write:e=>JSON.stringify(Array.from(e.entries()))},set:{read:e=>new Set(JSON.parse(e)),write:e=>JSON.stringify(Array.from(e))},date:{read:e=>new Date(e),write:e=>e.toISOString()}},ch="vueuse-storage";function U$(e,t,n,r={}){var o;const{flush:a="pre",deep:l=!0,listenToStorageChanges:s=!0,writeDefaults:i=!0,mergeDefaults:u=!1,shallow:d,window:f=Ja,eventFilter:h,onError:p=S=>{console.error(S)}}=r,v=(d?On:B)(t);if(!n)try{n=V$("getDefaultStorage",()=>{var S;return(S=Ja)==null?void 0:S.localStorage})()}catch(S){p(S)}if(!n)return v;const g=Jr(t),w=B$(g),m=(o=r.serializer)!=null?o:W$[w],{pause:b,resume:_}=$$(v,()=>y(v.value),{flush:a,deep:l,eventFilter:h});return f&&s&&(An(f,"storage",E),An(f,ch,k)),E(),v;function y(S){try{if(S==null)n.removeItem(e);else{const R=m.write(S),L=n.getItem(e);L!==R&&(n.setItem(e,R),f&&f.dispatchEvent(new CustomEvent(ch,{detail:{key:e,oldValue:L,newValue:R,storageArea:n}})))}}catch(R){p(R)}}function C(S){const R=S?S.newValue:n.getItem(e);if(R==null)return i&&g!==null&&n.setItem(e,m.write(g)),g;if(!S&&u){const L=m.read(R);return typeof u=="function"?u(L,g):w==="object"&&!Array.isArray(L)?uh(uh({},g),L):L}else return typeof R!="string"?R:m.read(R)}function k(S){E(S.detail)}function E(S){if(!(S&&S.storageArea!==n)){if(S&&S.key==null){v.value=g;return}if(!(S&&S.key!==e)){b();try{v.value=C(S)}catch(R){p(R)}finally{S?qe(_):_()}}}}}function K$(e){return N$("(prefers-color-scheme: dark)",e)}var dh=Object.getOwnPropertySymbols,q$=Object.prototype.hasOwnProperty,Y$=Object.prototype.propertyIsEnumerable,G$=(e,t)=>{var n={};for(var r in e)q$.call(e,r)&&t.indexOf(r)<0&&(n[r]=e[r]);if(e!=null&&dh)for(var r of dh(e))t.indexOf(r)<0&&Y$.call(e,r)&&(n[r]=e[r]);return n};function xo(e,t,n={}){const r=n,{window:o=Ja}=r,a=G$(r,["window"]);let l;const s=D0(()=>o&&"ResizeObserver"in o),i=()=>{l&&(l.disconnect(),l=void 0)},u=O(()=>Array.isArray(e)?e.map(h=>Kr(h)):[Kr(e)]),d=$e(u,h=>{if(i(),s.value&&o){l=new ResizeObserver(t);for(const p of h)p&&l.observe(p,a)}},{immediate:!0,flush:"post",deep:!0}),f=()=>{i(),d()};return Ls(f),{isSupported:s,stop:f}}const F0=Symbol(""),vG=()=>{const e=Re(F0);if(!e)throw new Error("useDarkMode() is called without provider.");return e},X$=()=>{const e=H0(),t=K$(),n=U$("vuepress-color-scheme",e.value.colorMode),r=O({get(){return e.value.colorModeSwitch?n.value==="auto"?t.value:n.value==="dark":e.value.colorMode==="dark"},set(o){o===t.value?n.value="auto":n.value=o?"dark":"light"}});yt(F0,r),J$(r)},J$=e=>{const t=(n=e.value)=>{const r=window==null?void 0:window.document.querySelector("html");r==null||r.classList.toggle("dark",n)};dt(()=>{$e(e,t,{immediate:!0})}),Mo(()=>t())},V0=(...e)=>{const n=Ef().resolve(...e),r=n.matched[n.matched.length-1];if(!(r!=null&&r.redirect))return n;const{redirect:o}=r,a=Ke(o)?o(n):o,l=Ge(a)?{path:a}:a;return V0({hash:n.hash,query:n.query,params:n.params,...l})},Z$=e=>{const t=V0(encodeURI(e));return{text:t.meta.title||e,link:t.name==="404"?e:t.fullPath}};let vc=null,$l=null;const Q$={wait:()=>vc,pending:()=>{vc=new Promise(e=>$l=e)},resolve:()=>{$l==null||$l(),vc=null,$l=null}},eT=()=>Q$,B0=Symbol("sidebarItems"),gG=()=>{const e=Re(B0);if(!e)throw new Error("useSidebarItems() is called without provider.");return e},tT=()=>{const e=H0(),t=rS(),n=O(()=>nT(t.value,e.value));yt(B0,n)},nT=(e,t)=>{var o,a,l,s;const n=(a=(o=e.sidebar)!=null?o:t.sidebar)!=null?a:"auto",r=(s=(l=e.sidebarDepth)!=null?l:t.sidebarDepth)!=null?s:2;return e.home||n===!1?[]:n==="auto"?oT(r):De(n)?z0(n,r):l0(n)?aT(n,r):[]},rT=(e,t)=>({text:e.title,link:`#${e.slug}`,children:xf(e.children,t)}),xf=(e,t)=>t>0?e.map(n=>rT(n,t-1)):[],oT=e=>{const t=Ps();return[{text:t.value.title,children:xf(t.value.headers,e)}]},z0=(e,t)=>{const n=$f(),r=Ps(),o=a=>{var s;let l;if(Ge(a)?l=Z$(a):l=a,l.children)return{...l,children:l.children.map(i=>o(i))};if(l.link===n.path){const i=((s=r.value.headers[0])==null?void 0:s.level)===1?r.value.headers[0].children:r.value.headers;return{...l,children:xf(i,t)}}return l};return e.map(a=>o(a))},aT=(e,t)=>{var a;const n=$f(),r=s0(e,n.path),o=(a=e[r])!=null?a:[];return z0(o,t)},H0=()=>KE();var lT=Ro({enhance({app:e,router:t}){e.component("Badge",XE),e.component("CodeGroup",JE),e.component("CodeGroupItem",t$),e.component("AutoLinkExternalIcon",()=>{const r=e.component("ExternalLinkIcon");return r?He(r):null}),e.component("NavbarSearch",()=>{const r=e.component("Docsearch")||e.component("SearchBox");return r?He(r):null});const n=t.options.scrollBehavior;t.options.scrollBehavior=async(...r)=>(await eT().wait(),n(...r))},setup(){X$(),tT()}});function j0(){return{async:!1,baseUrl:null,breaks:!1,extensions:null,gfm:!0,headerIds:!0,headerPrefix:"",highlight:null,hooks:null,langPrefix:"language-",mangle:!0,pedantic:!1,renderer:null,sanitize:!1,sanitizer:null,silent:!1,smartypants:!1,tokenizer:null,walkTokens:null,xhtml:!1}}let ma=j0();function sT(e){ma=e}const W0=/[&<>"']/,iT=new RegExp(W0.source,"g"),U0=/[<>"']|&(?!(#\d{1,7}|#[Xx][a-fA-F0-9]{1,6}|\w+);)/,uT=new RegExp(U0.source,"g"),cT={"&":"&","<":"<",">":">",'"':""","'":"'"},fh=e=>cT[e];function dn(e,t){if(t){if(W0.test(e))return e.replace(iT,fh)}else if(U0.test(e))return e.replace(uT,fh);return e}const dT=/&(#(?:\d+)|(?:#x[0-9A-Fa-f]+)|(?:\w+));?/ig;function K0(e){return e.replace(dT,(t,n)=>(n=n.toLowerCase(),n==="colon"?":":n.charAt(0)==="#"?n.charAt(1)==="x"?String.fromCharCode(parseInt(n.substring(2),16)):String.fromCharCode(+n.substring(1)):""))}const fT=/(^|[^\[])\^/g;function Mt(e,t){e=typeof e=="string"?e:e.source,t=t||"";const n={replace:(r,o)=>(o=o.source||o,o=o.replace(fT,"$1"),e=e.replace(r,o),n),getRegex:()=>new RegExp(e,t)};return n}const pT=/[^\w:]/g,mT=/^$|^[a-z][a-z0-9+.-]*:|^[?#]/i;function ph(e,t,n){if(e){let r;try{r=decodeURIComponent(K0(n)).replace(pT,"").toLowerCase()}catch{return null}if(r.indexOf("javascript:")===0||r.indexOf("vbscript:")===0||r.indexOf("data:")===0)return null}t&&!mT.test(n)&&(n=bT(t,n));try{n=encodeURI(n).replace(/%25/g,"%")}catch{return null}return n}const li={},hT=/^[^:]+:\/*[^/]*$/,vT=/^([^:]+:)[\s\S]*$/,gT=/^([^:]+:\/*[^/]*)[\s\S]*$/;function bT(e,t){li[" "+e]||(hT.test(e)?li[" "+e]=e+"/":li[" "+e]=Ii(e,"/",!0)),e=li[" "+e];const n=e.indexOf(":")===-1;return t.substring(0,2)==="//"?n?t:e.replace(vT,"$1")+t:t.charAt(0)==="/"?n?t:e.replace(gT,"$1")+t:e+t}const su={exec:function(){}};function mh(e,t){const n=e.replace(/\|/g,(a,l,s)=>{let i=!1,u=l;for(;--u>=0&&s[u]==="\\";)i=!i;return i?"|":" |"}),r=n.split(/ \|/);let o=0;if(r[0].trim()||r.shift(),r.length>0&&!r[r.length-1].trim()&&r.pop(),r.length>t)r.splice(t);else for(;r.length1;)t&1&&(n+=e),t>>=1,e+=e;return n+e}function vh(e,t,n,r){const o=t.href,a=t.title?dn(t.title):null,l=e[1].replace(/\\([\[\]])/g,"$1");if(e[0].charAt(0)!=="!"){r.state.inLink=!0;const s={type:"link",raw:n,href:o,title:a,text:l,tokens:r.inlineTokens(l)};return r.state.inLink=!1,s}return{type:"image",raw:n,href:o,title:a,text:dn(l)}}function wT(e,t){const n=e.match(/^(\s+)(?:```)/);if(n===null)return t;const r=n[1];return t.split(` + */const Tt={settings:{minimum:.08,easing:"ease",speed:200,trickle:!0,trickleRate:.02,trickleSpeed:800,barSelector:'[role="bar"]',parent:"body",template:'
'},status:null,set:e=>{const t=Tt.isStarted();e=hc(e,Tt.settings.minimum,1),Tt.status=e===1?null:e;const n=Tt.render(!t),r=n.querySelector(Tt.settings.barSelector),o=Tt.settings.speed,a=Tt.settings.easing;return n.offsetWidth,BE(l=>{ri(r,{transform:"translate3d("+Jm(e)+"%,0,0)",transition:"all "+o+"ms "+a}),e===1?(ri(n,{transition:"none",opacity:"1"}),n.offsetWidth,setTimeout(function(){ri(n,{transition:"all "+o+"ms linear",opacity:"0"}),setTimeout(function(){Tt.remove(),l()},o)},o)):setTimeout(()=>l(),o)}),Tt},isStarted:()=>typeof Tt.status=="number",start:()=>{Tt.status||Tt.set(0);const e=()=>{setTimeout(()=>{!Tt.status||(Tt.trickle(),e())},Tt.settings.trickleSpeed)};return Tt.settings.trickle&&e(),Tt},done:e=>!e&&!Tt.status?Tt:Tt.inc(.3+.5*Math.random()).set(1),inc:e=>{let t=Tt.status;return t?(typeof e!="number"&&(e=(1-t)*hc(Math.random()*t,.1,.95)),t=hc(t+e,0,.994),Tt.set(t)):Tt.start()},trickle:()=>Tt.inc(Math.random()*Tt.settings.trickleRate),render:e=>{if(Tt.isRendered())return document.getElementById("nprogress");Zm(document.documentElement,"nprogress-busy");const t=document.createElement("div");t.id="nprogress",t.innerHTML=Tt.settings.template;const n=t.querySelector(Tt.settings.barSelector),r=e?"-100":Jm(Tt.status||0),o=document.querySelector(Tt.settings.parent);return ri(n,{transition:"all 0 linear",transform:"translate3d("+r+"%,0,0)"}),o!==document.body&&Zm(o,"nprogress-custom-parent"),o==null||o.appendChild(t),t},remove:()=>{Qm(document.documentElement,"nprogress-busy"),Qm(document.querySelector(Tt.settings.parent),"nprogress-custom-parent");const e=document.getElementById("nprogress");e&&zE(e)},isRendered:()=>!!document.getElementById("nprogress")},hc=(e,t,n)=>en?n:e,Jm=e=>(-1+e)*100,BE=function(){const e=[];function t(){const n=e.shift();n&&n(t)}return function(n){e.push(n),e.length===1&&t()}}(),ri=function(){const e=["Webkit","O","Moz","ms"],t={};function n(l){return l.replace(/^-ms-/,"ms-").replace(/-([\da-z])/gi,function(s,i){return i.toUpperCase()})}function r(l){const s=document.body.style;if(l in s)return l;let i=e.length;const u=l.charAt(0).toUpperCase()+l.slice(1);let d;for(;i--;)if(d=e[i]+u,d in s)return d;return l}function o(l){return l=n(l),t[l]||(t[l]=r(l))}function a(l,s,i){s=o(s),l.style[s]=i}return function(l,s){for(const i in s){const u=s[i];u!==void 0&&Object.prototype.hasOwnProperty.call(s,i)&&a(l,i,u)}}}(),T0=(e,t)=>(typeof e=="string"?e:Tf(e)).indexOf(" "+t+" ")>=0,Zm=(e,t)=>{const n=Tf(e),r=n+t;T0(n,t)||(e.className=r.substring(1))},Qm=(e,t)=>{const n=Tf(e);if(!T0(e,t))return;const r=n.replace(" "+t+" "," ");e.className=r.substring(1,r.length-1)},Tf=e=>(" "+(e.className||"")+" ").replace(/\s+/gi," "),zE=e=>{e&&e.parentNode&&e.parentNode.removeChild(e)};const HE=()=>{dt(()=>{const e=Ef(),t=new Set;t.add(e.currentRoute.value.path),e.beforeEach(n=>{t.has(n.path)||Tt.start()}),e.afterEach(n=>{t.add(n.path),Tt.done()})})};var jE=Ro({setup(){HE()}});const WE=JSON.parse(`{"navbar":false,"sidebar":[{"text":"Next Trainer","link":"/"},{"text":"\u8bad\u7ec3","children":[{"text":"LoRA \u8bad\u7ec3","link":"/lora/index.md","collapsible":false,"children":[{"text":"Anima LoRA","link":"/lora/sd3.md"},{"text":"Flux","link":"/lora/flux.md"},{"text":"Stable Diffusion","link":"/lora/master.md"}]},{"text":"\u5168\u91cf\u5fae\u8c03","link":"/lora/anima-finetune.md","collapsible":false,"children":[{"text":"Anima Finetune","link":"/lora/anima-finetune.md"},{"text":"Stable Diffusion","link":"/dreambooth/index.md"}]}]},{"text":"\u5de5\u5177\u4e0e\u8c03\u8bd5","children":[{"text":"Tensorboard","link":"/tensorboard.md"},{"text":"\u6570\u636e\u96c6\u6253\u6807","link":"/tagger.md"},{"text":"\u7ecf\u5178\u6807\u7b7e\u7f16\u8f91","link":"/tageditor.md"},{"text":"\u539f\u751f\u6807\u7b7e\u7f16\u8f91","link":"/native-tageditor.html"},{"text":"LoRA \u811a\u672c\u5de5\u5177","link":"/lora/tools.md"}]},{"text":"\u5e2e\u52a9","children":[{"text":"\u65b0\u624b\u4e0a\u8def","link":"/help/guide.md"},{"text":"\u8bad\u7ec3\u53c2\u6570\u8bf4\u660e","link":"/lora/params.md"}]},{"text":"\u5176\u4ed6","collapsible":false,"children":[{"text":"UI \u8bbe\u7f6e","link":"/other/settings.md"},{"text":"\u5173\u4e8e","link":"/other/about.md"},{"text":"\u66f4\u65b0\u65e5\u5fd7","link":"/other/changelog.md"}]}],"locales":{"/":{"selectLanguageName":"English"}},"colorMode":"auto","colorModeSwitch":true,"logo":null,"repo":null,"selectLanguageText":"Languages","selectLanguageAriaLabel":"Select language","sidebarDepth":2,"editLink":true,"editLinkText":"Edit this page","lastUpdated":true,"lastUpdatedText":"Last Updated","contributors":true,"contributorsText":"Contributors","notFound":["There's nothing here.","How did we get here?","That's a Four-Oh-Four.","Looks like we've got some broken links."],"backToHome":"Take me home","openInNewWindow":"open in new window","toggleColorMode":"toggle color mode","toggleSidebar":"toggle sidebar"}`),x0=B(WE),UE=()=>x0;zp.webpackHot&&(__VUE_HMR_RUNTIME__.updateThemeData=e=>{x0.value=e});const O0=Symbol(""),KE=()=>{const e=Re(O0);if(!e)throw new Error("useThemeLocaleData() is called without provider.");return e},qE=(e,t)=>{var n;return{...e,...(n=e.locales)==null?void 0:n[t]}};var YE=Ro({enhance({app:e}){const t=UE(),n=e._context.provides[Cf],r=O(()=>qE(t.value,n.value));e.provide(O0,r),Object.defineProperties(e.config.globalProperties,{$theme:{get(){return t.value}},$themeLocale:{get(){return r.value}}})}}),St=(e,t)=>{const n=e.__vccOpts||e;for(const[r,o]of t)n[r]=o;return n};const GE=se({__name:"Badge",props:{type:{type:String,required:!1,default:"tip"},text:{type:String,required:!1,default:""},vertical:{type:String,required:!1,default:void 0}},setup(e){return(t,n)=>(x(),U("span",{class:D(["badge",e.type]),style:Qe({verticalAlign:e.vertical})},[pe(t.$slots,"default",{},()=>[Je(Ee(e.text),1)])],6))}});var XE=St(GE,[["__file","Badge.vue"]]);const JE=se({name:"CodeGroup",setup(e,{slots:t}){const n=B(-1),r=B([]),o=(s=n.value)=>{s{s>0?n.value=s-1:n.value=r.value.length-1,r.value[n.value].focus()},l=(s,i)=>{s.key===" "||s.key==="Enter"?(s.preventDefault(),n.value=i):s.key==="ArrowRight"?(s.preventDefault(),o(i)):s.key==="ArrowLeft"&&(s.preventDefault(),a(i))};return()=>{var i;const s=(((i=t.default)==null?void 0:i.call(t))||[]).filter(u=>u.type.name==="CodeGroupItem").map(u=>(u.props===null&&(u.props={}),u));return s.length===0?null:(n.value<0||n.value>s.length-1?(n.value=s.findIndex(u=>u.props.active===""||u.props.active===!0),n.value===-1&&(n.value=0)):s.forEach((u,d)=>{u.props.active=d===n.value}),He("div",{class:"code-group"},[He("div",{class:"code-group__nav"},He("ul",{class:"code-group__ul"},s.map((u,d)=>{const f=d===n.value;return He("li",{class:"code-group__li"},He("button",{ref:h=>{h&&(r.value[d]=h)},class:{"code-group__nav-tab":!0,"code-group__nav-tab-active":f},ariaPressed:f,ariaExpanded:f,onClick:()=>n.value=d,onKeydown:h=>l(h,d)},u.props.title))}))),s]))}}}),ZE=["aria-selected"],QE=se({name:"CodeGroupItem"}),e$=se({...QE,props:{title:{type:String,required:!0},active:{type:Boolean,required:!1,default:!1}},setup(e){return(t,n)=>(x(),U("div",{class:D(["code-group-item",{"code-group-item__active":e.active}]),"aria-selected":e.active},[pe(t.$slots,"default")],10,ZE))}});var t$=St(e$,[["__file","CodeGroupItem.vue"]]),n$=!0;function Ls(e){return Zg()?(Qg(e),!0):!1}var r$=Object.defineProperty,eh=Object.getOwnPropertySymbols,o$=Object.prototype.hasOwnProperty,a$=Object.prototype.propertyIsEnumerable,th=(e,t,n)=>t in e?r$(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n,l$=(e,t)=>{for(var n in t||(t={}))o$.call(t,n)&&th(e,n,t[n]);if(eh)for(var n of eh(t))a$.call(t,n)&&th(e,n,t[n]);return e};function s$(e,t){if(typeof Symbol!="undefined"){const n=l$({},e);return Object.defineProperty(n,Symbol.iterator,{enumerable:!1,value(){let r=0;return{next:()=>({value:t[r++],done:r>t.length})}}}),n}else return Object.assign([...t],e)}function Jr(e){return typeof e=="function"?e():c(e)}const xt=typeof window!="undefined",ss=()=>{},A0=i$();function i$(){var e;return xt&&((e=window==null?void 0:window.navigator)==null?void 0:e.userAgent)&&/iP(ad|hone|od)/.test(window.navigator.userAgent)}function I0(e,t){function n(...r){return new Promise((o,a)=>{Promise.resolve(e(()=>t.apply(this,r),{fn:t,thisArg:this,args:r})).then(o).catch(a)})}return n}const P0=e=>e();function u$(e,t={}){let n,r,o=ss;const a=s=>{clearTimeout(s),o(),o=ss};return s=>{const i=Jr(e),u=Jr(t.maxWait);return n&&a(n),i<=0||u!==void 0&&u<=0?(r&&(a(r),r=null),Promise.resolve(s())):new Promise((d,f)=>{o=t.rejectOnCancel?f:d,u&&!r&&(r=setTimeout(()=>{n&&a(n),r=null,d(s())},u)),n=setTimeout(()=>{r&&a(r),r=null,d(s())},i)})}}function c$(e=P0){const t=B(!0);function n(){t.value=!1}function r(){t.value=!0}const o=(...a)=>{t.value&&e(...a)};return{isActive:pa(t),pause:n,resume:r,eventFilter:o}}function d$(e){const t=Object.create(null);return n=>t[n]||(t[n]=e(n))}const f$=/-(\w)/g,p$=d$(e=>e.replace(f$,(t,n)=>n?n.toUpperCase():""));function m$(e,t=200,n={}){return I0(u$(t,n),e)}function h$(e,t=200,n={}){const r=B(e.value),o=m$(()=>{r.value=e.value},t,n);return $e(e,()=>o()),r}function ed(e,t,n={}){const{immediate:r=!0}=n,o=B(!1);let a=null;function l(){a&&(clearTimeout(a),a=null)}function s(){o.value=!1,l()}function i(...u){l(),o.value=!0,a=setTimeout(()=>{o.value=!1,a=null,e(...u)},Jr(t))}return r&&(o.value=!0,xt&&i()),Ls(s),{isPending:pa(o),start:i,stop:s}}function hG(e=!1,t={}){const{truthyValue:n=!0,falsyValue:r=!1}=t,o=mt(e),a=B(e);function l(s){if(arguments.length)return a.value=s,a.value;{const i=Jr(n);return a.value=a.value===i?Jr(r):i,a.value}}return o?l:[a,l]}var nh=Object.getOwnPropertySymbols,v$=Object.prototype.hasOwnProperty,g$=Object.prototype.propertyIsEnumerable,b$=(e,t)=>{var n={};for(var r in e)v$.call(e,r)&&t.indexOf(r)<0&&(n[r]=e[r]);if(e!=null&&nh)for(var r of nh(e))t.indexOf(r)<0&&g$.call(e,r)&&(n[r]=e[r]);return n};function y$(e,t,n={}){const r=n,{eventFilter:o=P0}=r,a=b$(r,["eventFilter"]);return $e(e,I0(o,t),a)}var _$=Object.defineProperty,w$=Object.defineProperties,C$=Object.getOwnPropertyDescriptors,lu=Object.getOwnPropertySymbols,L0=Object.prototype.hasOwnProperty,M0=Object.prototype.propertyIsEnumerable,rh=(e,t,n)=>t in e?_$(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n,k$=(e,t)=>{for(var n in t||(t={}))L0.call(t,n)&&rh(e,n,t[n]);if(lu)for(var n of lu(t))M0.call(t,n)&&rh(e,n,t[n]);return e},S$=(e,t)=>w$(e,C$(t)),E$=(e,t)=>{var n={};for(var r in e)L0.call(e,r)&&t.indexOf(r)<0&&(n[r]=e[r]);if(e!=null&&lu)for(var r of lu(e))t.indexOf(r)<0&&M0.call(e,r)&&(n[r]=e[r]);return n};function $$(e,t,n={}){const r=n,{eventFilter:o}=r,a=E$(r,["eventFilter"]),{eventFilter:l,pause:s,resume:i,isActive:u}=c$(o);return{stop:y$(e,t,S$(k$({},a),{eventFilter:l})),pause:s,resume:i,isActive:u}}var T$=Object.defineProperty,x$=Object.defineProperties,O$=Object.getOwnPropertyDescriptors,oh=Object.getOwnPropertySymbols,A$=Object.prototype.hasOwnProperty,I$=Object.prototype.propertyIsEnumerable,ah=(e,t,n)=>t in e?T$(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n,P$=(e,t)=>{for(var n in t||(t={}))A$.call(t,n)&&ah(e,n,t[n]);if(oh)for(var n of oh(t))I$.call(t,n)&&ah(e,n,t[n]);return e},L$=(e,t)=>x$(e,O$(t));function R0(e={}){if(!n$&&!qb.startsWith("2.7."))return;const{inheritAttrs:t=!0}=e,n=On(),r=se({setup(a,{slots:l}){return()=>{n.value=l.default}}}),o=se({inheritAttrs:t,setup(a,{attrs:l,slots:s}){return()=>{var i;n.value;const u=(i=n.value)==null?void 0:i.call(n,L$(P$({},M$(l)),{$slots:s}));return t&&(u==null?void 0:u.length)===1?u[0]:u}}});return s$({define:r,reuse:o},[r,o])}function M$(e){const t={};for(const n in e)t[p$(n)]=e[n];return t}function Kr(e){var t;const n=Jr(e);return(t=n==null?void 0:n.$el)!=null?t:n}const Ja=xt?window:void 0;xt&&window.document;xt&&window.navigator;xt&&window.location;function An(...e){let t,n,r,o;if(typeof e[0]=="string"||Array.isArray(e[0])?([n,r,o]=e,t=Ja):[t,n,r,o]=e,!t)return ss;Array.isArray(n)||(n=[n]),Array.isArray(r)||(r=[r]);const a=[],l=()=>{a.forEach(d=>d()),a.length=0},s=(d,f,h,p)=>(d.addEventListener(f,h,p),()=>d.removeEventListener(f,h,p)),i=$e(()=>[Kr(t),Jr(o)],([d,f])=>{l(),d&&a.push(...n.flatMap(h=>r.map(p=>s(d,h,p,f))))},{immediate:!0,flush:"post"}),u=()=>{i(),l()};return Ls(u),u}let lh=!1;function N0(e,t,n={}){const{window:r=Ja,ignore:o=[],capture:a=!0,detectIframe:l=!1}=n;if(!r)return;A0&&!lh&&(lh=!0,Array.from(r.document.body.children).forEach(h=>h.addEventListener("click",ss)),r.document.documentElement.addEventListener("click",ss));let s=!0;const i=h=>o.some(p=>{if(typeof p=="string")return Array.from(r.document.querySelectorAll(p)).some(v=>v===h.target||h.composedPath().includes(v));{const v=Kr(p);return v&&(h.target===v||h.composedPath().includes(v))}}),d=[An(r,"click",h=>{const p=Kr(e);if(!(!p||p===h.target||h.composedPath().includes(p))){if(h.detail===0&&(s=!i(h)),!s){s=!0;return}t(h)}},{passive:!0,capture:a}),An(r,"pointerdown",h=>{const p=Kr(e);p&&(s=!h.composedPath().includes(p)&&!i(h))},{passive:!0}),l&&An(r,"blur",h=>{setTimeout(()=>{var p;const v=Kr(e);((p=r.document.activeElement)==null?void 0:p.tagName)==="IFRAME"&&!(v!=null&&v.contains(r.document.activeElement))&&t(h)},0)})].filter(Boolean);return()=>d.forEach(h=>h())}function R$(){const e=B(!1);return lt()&&dt(()=>{e.value=!0}),e}function D0(e){const t=R$();return O(()=>(t.value,Boolean(e())))}function N$(e,t={}){const{window:n=Ja}=t,r=D0(()=>n&&"matchMedia"in n&&typeof n.matchMedia=="function");let o;const a=B(!1),l=u=>{a.value=u.matches},s=()=>{!o||("removeEventListener"in o?o.removeEventListener("change",l):o.removeListener(l))},i=qr(()=>{!r.value||(s(),o=n.matchMedia(Jr(e)),"addEventListener"in o?o.addEventListener("change",l):o.addListener(l),a.value=o.matches)});return Ls(()=>{i(),s(),o=void 0}),a}const oi=typeof globalThis!="undefined"?globalThis:typeof window!="undefined"?window:typeof global!="undefined"?global:typeof self!="undefined"?self:{},ai="__vueuse_ssr_handlers__",D$=F$();function F$(){return ai in oi||(oi[ai]=oi[ai]||{}),oi[ai]}function V$(e,t){return D$[e]||t}function B$(e){return e==null?"any":e instanceof Set?"set":e instanceof Map?"map":e instanceof Date?"date":typeof e=="boolean"?"boolean":typeof e=="string"?"string":typeof e=="object"?"object":Number.isNaN(e)?"any":"number"}var z$=Object.defineProperty,sh=Object.getOwnPropertySymbols,H$=Object.prototype.hasOwnProperty,j$=Object.prototype.propertyIsEnumerable,ih=(e,t,n)=>t in e?z$(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n,uh=(e,t)=>{for(var n in t||(t={}))H$.call(t,n)&&ih(e,n,t[n]);if(sh)for(var n of sh(t))j$.call(t,n)&&ih(e,n,t[n]);return e};const W$={boolean:{read:e=>e==="true",write:e=>String(e)},object:{read:e=>JSON.parse(e),write:e=>JSON.stringify(e)},number:{read:e=>Number.parseFloat(e),write:e=>String(e)},any:{read:e=>e,write:e=>String(e)},string:{read:e=>e,write:e=>String(e)},map:{read:e=>new Map(JSON.parse(e)),write:e=>JSON.stringify(Array.from(e.entries()))},set:{read:e=>new Set(JSON.parse(e)),write:e=>JSON.stringify(Array.from(e))},date:{read:e=>new Date(e),write:e=>e.toISOString()}},ch="vueuse-storage";function U$(e,t,n,r={}){var o;const{flush:a="pre",deep:l=!0,listenToStorageChanges:s=!0,writeDefaults:i=!0,mergeDefaults:u=!1,shallow:d,window:f=Ja,eventFilter:h,onError:p=S=>{console.error(S)}}=r,v=(d?On:B)(t);if(!n)try{n=V$("getDefaultStorage",()=>{var S;return(S=Ja)==null?void 0:S.localStorage})()}catch(S){p(S)}if(!n)return v;const g=Jr(t),w=B$(g),m=(o=r.serializer)!=null?o:W$[w],{pause:b,resume:_}=$$(v,()=>y(v.value),{flush:a,deep:l,eventFilter:h});return f&&s&&(An(f,"storage",E),An(f,ch,k)),E(),v;function y(S){try{if(S==null)n.removeItem(e);else{const R=m.write(S),L=n.getItem(e);L!==R&&(n.setItem(e,R),f&&f.dispatchEvent(new CustomEvent(ch,{detail:{key:e,oldValue:L,newValue:R,storageArea:n}})))}}catch(R){p(R)}}function C(S){const R=S?S.newValue:n.getItem(e);if(R==null)return i&&g!==null&&n.setItem(e,m.write(g)),g;if(!S&&u){const L=m.read(R);return typeof u=="function"?u(L,g):w==="object"&&!Array.isArray(L)?uh(uh({},g),L):L}else return typeof R!="string"?R:m.read(R)}function k(S){E(S.detail)}function E(S){if(!(S&&S.storageArea!==n)){if(S&&S.key==null){v.value=g;return}if(!(S&&S.key!==e)){b();try{v.value=C(S)}catch(R){p(R)}finally{S?qe(_):_()}}}}}function K$(e){return N$("(prefers-color-scheme: dark)",e)}var dh=Object.getOwnPropertySymbols,q$=Object.prototype.hasOwnProperty,Y$=Object.prototype.propertyIsEnumerable,G$=(e,t)=>{var n={};for(var r in e)q$.call(e,r)&&t.indexOf(r)<0&&(n[r]=e[r]);if(e!=null&&dh)for(var r of dh(e))t.indexOf(r)<0&&Y$.call(e,r)&&(n[r]=e[r]);return n};function xo(e,t,n={}){const r=n,{window:o=Ja}=r,a=G$(r,["window"]);let l;const s=D0(()=>o&&"ResizeObserver"in o),i=()=>{l&&(l.disconnect(),l=void 0)},u=O(()=>Array.isArray(e)?e.map(h=>Kr(h)):[Kr(e)]),d=$e(u,h=>{if(i(),s.value&&o){l=new ResizeObserver(t);for(const p of h)p&&l.observe(p,a)}},{immediate:!0,flush:"post",deep:!0}),f=()=>{i(),d()};return Ls(f),{isSupported:s,stop:f}}const F0=Symbol(""),vG=()=>{const e=Re(F0);if(!e)throw new Error("useDarkMode() is called without provider.");return e},X$=()=>{const e=H0(),t=K$(),n=U$("vuepress-color-scheme",e.value.colorMode),r=O({get(){return e.value.colorModeSwitch?n.value==="auto"?t.value:n.value==="dark":e.value.colorMode==="dark"},set(o){o===t.value?n.value="auto":n.value=o?"dark":"light"}});yt(F0,r),J$(r)},J$=e=>{const t=(n=e.value)=>{const r=window==null?void 0:window.document.querySelector("html");r==null||r.classList.toggle("dark",n)};dt(()=>{$e(e,t,{immediate:!0})}),Mo(()=>t())},V0=(...e)=>{const n=Ef().resolve(...e),r=n.matched[n.matched.length-1];if(!(r!=null&&r.redirect))return n;const{redirect:o}=r,a=Ke(o)?o(n):o,l=Ge(a)?{path:a}:a;return V0({hash:n.hash,query:n.query,params:n.params,...l})},Z$=e=>{const t=V0(encodeURI(e));return{text:t.meta.title||e,link:t.name==="404"?e:t.fullPath}};let vc=null,$l=null;const Q$={wait:()=>vc,pending:()=>{vc=new Promise(e=>$l=e)},resolve:()=>{$l==null||$l(),vc=null,$l=null}},eT=()=>Q$,B0=Symbol("sidebarItems"),gG=()=>{const e=Re(B0);if(!e)throw new Error("useSidebarItems() is called without provider.");return e},tT=()=>{const e=H0(),t=rS(),n=O(()=>nT(t.value,e.value));yt(B0,n)},nT=(e,t)=>{var o,a,l,s;const n=(a=(o=e.sidebar)!=null?o:t.sidebar)!=null?a:"auto",r=(s=(l=e.sidebarDepth)!=null?l:t.sidebarDepth)!=null?s:2;return e.home||n===!1?[]:n==="auto"?oT(r):De(n)?z0(n,r):l0(n)?aT(n,r):[]},rT=(e,t)=>({text:e.title,link:`#${e.slug}`,children:xf(e.children,t)}),xf=(e,t)=>t>0?e.map(n=>rT(n,t-1)):[],oT=e=>{const t=Ps();return[{text:t.value.title,children:xf(t.value.headers,e)}]},z0=(e,t)=>{const n=$f(),r=Ps(),o=a=>{var s;let l;if(Ge(a)?l=Z$(a):l=a,l.children)return{...l,children:l.children.map(i=>o(i))};if(l.link===n.path){const i=((s=r.value.headers[0])==null?void 0:s.level)===1?r.value.headers[0].children:r.value.headers;return{...l,children:xf(i,t)}}return l};return e.map(a=>o(a))},aT=(e,t)=>{var a;const n=$f(),r=s0(e,n.path),o=(a=e[r])!=null?a:[];return z0(o,t)},H0=()=>KE();var lT=Ro({enhance({app:e,router:t}){e.component("Badge",XE),e.component("CodeGroup",JE),e.component("CodeGroupItem",t$),e.component("AutoLinkExternalIcon",()=>{const r=e.component("ExternalLinkIcon");return r?He(r):null}),e.component("NavbarSearch",()=>{const r=e.component("Docsearch")||e.component("SearchBox");return r?He(r):null});const n=t.options.scrollBehavior;t.options.scrollBehavior=async(...r)=>(await eT().wait(),n(...r))},setup(){X$(),tT()}});function j0(){return{async:!1,baseUrl:null,breaks:!1,extensions:null,gfm:!0,headerIds:!0,headerPrefix:"",highlight:null,hooks:null,langPrefix:"language-",mangle:!0,pedantic:!1,renderer:null,sanitize:!1,sanitizer:null,silent:!1,smartypants:!1,tokenizer:null,walkTokens:null,xhtml:!1}}let ma=j0();function sT(e){ma=e}const W0=/[&<>"']/,iT=new RegExp(W0.source,"g"),U0=/[<>"']|&(?!(#\d{1,7}|#[Xx][a-fA-F0-9]{1,6}|\w+);)/,uT=new RegExp(U0.source,"g"),cT={"&":"&","<":"<",">":">",'"':""","'":"'"},fh=e=>cT[e];function dn(e,t){if(t){if(W0.test(e))return e.replace(iT,fh)}else if(U0.test(e))return e.replace(uT,fh);return e}const dT=/&(#(?:\d+)|(?:#x[0-9A-Fa-f]+)|(?:\w+));?/ig;function K0(e){return e.replace(dT,(t,n)=>(n=n.toLowerCase(),n==="colon"?":":n.charAt(0)==="#"?n.charAt(1)==="x"?String.fromCharCode(parseInt(n.substring(2),16)):String.fromCharCode(+n.substring(1)):""))}const fT=/(^|[^\[])\^/g;function Mt(e,t){e=typeof e=="string"?e:e.source,t=t||"";const n={replace:(r,o)=>(o=o.source||o,o=o.replace(fT,"$1"),e=e.replace(r,o),n),getRegex:()=>new RegExp(e,t)};return n}const pT=/[^\w:]/g,mT=/^$|^[a-z][a-z0-9+.-]*:|^[?#]/i;function ph(e,t,n){if(e){let r;try{r=decodeURIComponent(K0(n)).replace(pT,"").toLowerCase()}catch{return null}if(r.indexOf("javascript:")===0||r.indexOf("vbscript:")===0||r.indexOf("data:")===0)return null}t&&!mT.test(n)&&(n=bT(t,n));try{n=encodeURI(n).replace(/%25/g,"%")}catch{return null}return n}const li={},hT=/^[^:]+:\/*[^/]*$/,vT=/^([^:]+:)[\s\S]*$/,gT=/^([^:]+:\/*[^/]*)[\s\S]*$/;function bT(e,t){li[" "+e]||(hT.test(e)?li[" "+e]=e+"/":li[" "+e]=Ii(e,"/",!0)),e=li[" "+e];const n=e.indexOf(":")===-1;return t.substring(0,2)==="//"?n?t:e.replace(vT,"$1")+t:t.charAt(0)==="/"?n?t:e.replace(gT,"$1")+t:e+t}const su={exec:function(){}};function mh(e,t){const n=e.replace(/\|/g,(a,l,s)=>{let i=!1,u=l;for(;--u>=0&&s[u]==="\\";)i=!i;return i?"|":" |"}),r=n.split(/ \|/);let o=0;if(r[0].trim()||r.shift(),r.length>0&&!r[r.length-1].trim()&&r.pop(),r.length>t)r.splice(t);else for(;r.length1;)t&1&&(n+=e),t>>=1,e+=e;return n+e}function vh(e,t,n,r){const o=t.href,a=t.title?dn(t.title):null,l=e[1].replace(/\\([\[\]])/g,"$1");if(e[0].charAt(0)!=="!"){r.state.inLink=!0;const s={type:"link",raw:n,href:o,title:a,text:l,tokens:r.inlineTokens(l)};return r.state.inLink=!1,s}return{type:"image",raw:n,href:o,title:a,text:dn(l)}}function wT(e,t){const n=e.match(/^(\s+)(?:```)/);if(n===null)return t;const r=n[1];return t.split(` `).map(o=>{const a=o.match(/^\s+/);if(a===null)return o;const[l]=a;return l.length>=r.length?o.slice(r.length):o}).join(` `)}class Of{constructor(t){this.options=t||ma}space(t){const n=this.rules.block.newline.exec(t);if(n&&n[0].length>0)return{type:"space",raw:n[0]}}code(t){const n=this.rules.block.code.exec(t);if(n){const r=n[0].replace(/^ {1,4}/gm,"");return{type:"code",raw:n[0],codeBlockStyle:"indented",text:this.options.pedantic?r:Ii(r,` `)}}}fences(t){const n=this.rules.block.fences.exec(t);if(n){const r=n[0],o=wT(r,n[3]||"");return{type:"code",raw:r,lang:n[2]?n[2].trim().replace(this.rules.inline._escapes,"$1"):n[2],text:o}}}heading(t){const n=this.rules.block.heading.exec(t);if(n){let r=n[2].trim();if(/#$/.test(r)){const o=Ii(r,"#");(this.options.pedantic||!o||/ $/.test(o))&&(r=o.trim())}return{type:"heading",raw:n[0],depth:n[1].length,text:r,tokens:this.lexer.inline(r)}}}hr(t){const n=this.rules.block.hr.exec(t);if(n)return{type:"hr",raw:n[0]}}blockquote(t){const n=this.rules.block.blockquote.exec(t);if(n){const r=n[0].replace(/^ *>[ \t]?/gm,""),o=this.lexer.state.top;this.lexer.state.top=!0;const a=this.lexer.blockTokens(r);return this.lexer.state.top=o,{type:"blockquote",raw:n[0],tokens:a,text:r}}}list(t){let n=this.rules.block.list.exec(t);if(n){let r,o,a,l,s,i,u,d,f,h,p,v,g=n[1].trim();const w=g.length>1,m={type:"list",raw:"",ordered:w,start:w?+g.slice(0,-1):"",loose:!1,items:[]};g=w?`\\d{1,9}\\${g.slice(-1)}`:`\\${g}`,this.options.pedantic&&(g=w?g:"[*+-]");const b=new RegExp(`^( {0,3}${g})((?:[ ][^\\n]*)?(?:\\n|$))`);for(;t&&(v=!1,!(!(n=b.exec(t))||this.rules.block.hr.test(t)));){if(r=n[0],t=t.substring(r.length),d=n[2].split(` @@ -117,4 +117,6 @@ Please report this to https://github.com/markedjs/marked.`,e){const o="

An err * vuex v4.0.2 * (c) 2021 Evan You * @license MIT - */var PY="store";function wl(e,t){Object.keys(e).forEach(function(n){return t(e[n],n)})}function LY(e){return e!==null&&typeof e=="object"}function MY(e){return e&&typeof e.then=="function"}function RY(e,t){return function(){return e(t)}}function n2(e,t,n){return t.indexOf(e)<0&&(n&&n.prepend?t.unshift(e):t.push(e)),function(){var r=t.indexOf(e);r>-1&&t.splice(r,1)}}function r2(e,t){e._actions=Object.create(null),e._mutations=Object.create(null),e._wrappedGetters=Object.create(null),e._modulesNamespaceMap=Object.create(null);var n=e.state;oc(e,n,[],e._modules.root,!0),Fp(e,n,t)}function Fp(e,t,n){var r=e._state;e.getters={},e._makeLocalGettersCache=Object.create(null);var o=e._wrappedGetters,a={};wl(o,function(l,s){a[s]=RY(l,e),Object.defineProperty(e.getters,s,{get:function(){return a[s]()},enumerable:!0})}),e._state=Xt({data:t}),e.strict&&BY(e),r&&n&&e._withCommit(function(){r.data=null})}function oc(e,t,n,r,o){var a=!n.length,l=e._modules.getNamespace(n);if(r.namespaced&&(e._modulesNamespaceMap[l],e._modulesNamespaceMap[l]=r),!a&&!o){var s=Vp(t,n.slice(0,-1)),i=n[n.length-1];e._withCommit(function(){s[i]=r.state})}var u=r.context=NY(e,l,n);r.forEachMutation(function(d,f){var h=l+f;DY(e,h,d,u)}),r.forEachAction(function(d,f){var h=d.root?f:l+f,p=d.handler||d;FY(e,h,p,u)}),r.forEachGetter(function(d,f){var h=l+f;VY(e,h,d,u)}),r.forEachChild(function(d,f){oc(e,t,n.concat(f),d,o)})}function NY(e,t,n){var r=t==="",o={dispatch:r?e.dispatch:function(a,l,s){var i=ku(a,l,s),u=i.payload,d=i.options,f=i.type;return(!d||!d.root)&&(f=t+f),e.dispatch(f,u)},commit:r?e.commit:function(a,l,s){var i=ku(a,l,s),u=i.payload,d=i.options,f=i.type;(!d||!d.root)&&(f=t+f),e.commit(f,u,d)}};return Object.defineProperties(o,{getters:{get:r?function(){return e.getters}:function(){return o2(e,t)}},state:{get:function(){return Vp(e.state,n)}}}),o}function o2(e,t){if(!e._makeLocalGettersCache[t]){var n={},r=t.length;Object.keys(e.getters).forEach(function(o){if(o.slice(0,r)===t){var a=o.slice(r);Object.defineProperty(n,a,{get:function(){return e.getters[o]},enumerable:!0})}}),e._makeLocalGettersCache[t]=n}return e._makeLocalGettersCache[t]}function DY(e,t,n,r){var o=e._mutations[t]||(e._mutations[t]=[]);o.push(function(l){n.call(e,r.state,l)})}function FY(e,t,n,r){var o=e._actions[t]||(e._actions[t]=[]);o.push(function(l){var s=n.call(e,{dispatch:r.dispatch,commit:r.commit,getters:r.getters,state:r.state,rootGetters:e.getters,rootState:e.state},l);return MY(s)||(s=Promise.resolve(s)),e._devtoolHook?s.catch(function(i){throw e._devtoolHook.emit("vuex:error",i),i}):s})}function VY(e,t,n,r){e._wrappedGetters[t]||(e._wrappedGetters[t]=function(a){return n(r.state,r.getters,a.state,a.getters)})}function BY(e){$e(function(){return e._state.data},function(){},{deep:!0,flush:"sync"})}function Vp(e,t){return t.reduce(function(n,r){return n[r]},e)}function ku(e,t,n){return LY(e)&&e.type&&(n=t,t=e,e=e.type),{type:e,payload:t,options:n}}var zY="vuex bindings",Wg="vuex:mutations",Dc="vuex:actions",Oa="vuex",HY=0;function jY(e,t){IY({id:"org.vuejs.vuex",app:e,label:"Vuex",homepage:"https://next.vuex.vuejs.org/",logo:"https://vuejs.org/images/icons/favicon-96x96.png",packageName:"vuex",componentStateTypes:[zY]},function(n){n.addTimelineLayer({id:Wg,label:"Vuex Mutations",color:Ug}),n.addTimelineLayer({id:Dc,label:"Vuex Actions",color:Ug}),n.addInspector({id:Oa,label:"Vuex",icon:"storage",treeFilterPlaceholder:"Filter stores..."}),n.on.getInspectorTree(function(r){if(r.app===e&&r.inspectorId===Oa)if(r.filter){var o=[];i2(o,t._modules.root,r.filter,""),r.rootNodes=o}else r.rootNodes=[s2(t._modules.root,"")]}),n.on.getInspectorState(function(r){if(r.app===e&&r.inspectorId===Oa){var o=r.nodeId;o2(t,o),r.state=KY(YY(t._modules,o),o==="root"?t.getters:t._makeLocalGettersCache,o)}}),n.on.editInspectorState(function(r){if(r.app===e&&r.inspectorId===Oa){var o=r.nodeId,a=r.path;o!=="root"&&(a=o.split("/").filter(Boolean).concat(a)),t._withCommit(function(){r.set(t._state.data,a,r.state.value)})}}),t.subscribe(function(r,o){var a={};r.payload&&(a.payload=r.payload),a.state=o,n.notifyComponentUpdate(),n.sendInspectorTree(Oa),n.sendInspectorState(Oa),n.addTimelineEvent({layerId:Wg,event:{time:Date.now(),title:r.type,data:a}})}),t.subscribeAction({before:function(r,o){var a={};r.payload&&(a.payload=r.payload),r._id=HY++,r._time=Date.now(),a.state=o,n.addTimelineEvent({layerId:Dc,event:{time:r._time,title:r.type,groupId:r._id,subtitle:"start",data:a}})},after:function(r,o){var a={},l=Date.now()-r._time;a.duration={_custom:{type:"duration",display:l+"ms",tooltip:"Action duration",value:l}},r.payload&&(a.payload=r.payload),a.state=o,n.addTimelineEvent({layerId:Dc,event:{time:Date.now(),title:r.type,groupId:r._id,subtitle:"end",data:a}})}})})}var Ug=8702998,WY=6710886,UY=16777215,a2={label:"namespaced",textColor:UY,backgroundColor:WY};function l2(e){return e&&e!=="root"?e.split("/").slice(-2,-1)[0]:"Root"}function s2(e,t){return{id:t||"root",label:l2(t),tags:e.namespaced?[a2]:[],children:Object.keys(e._children).map(function(n){return s2(e._children[n],t+n+"/")})}}function i2(e,t,n,r){r.includes(n)&&e.push({id:r||"root",label:r.endsWith("/")?r.slice(0,r.length-1):r||"Root",tags:t.namespaced?[a2]:[]}),Object.keys(t._children).forEach(function(o){i2(e,t._children[o],n,r+o+"/")})}function KY(e,t,n){t=n==="root"?t:t[n];var r=Object.keys(t),o={state:Object.keys(e.state).map(function(l){return{key:l,editable:!0,value:e.state[l]}})};if(r.length){var a=qY(t);o.getters=Object.keys(a).map(function(l){return{key:l.endsWith("/")?l2(l):l,editable:!1,value:Xd(function(){return a[l]})}})}return o}function qY(e){var t={};return Object.keys(e).forEach(function(n){var r=n.split("/");if(r.length>1){var o=t,a=r.pop();r.forEach(function(l){o[l]||(o[l]={_custom:{value:{},display:l,tooltip:"Module",abstract:!0}}),o=o[l]._custom.value}),o[a]=Xd(function(){return e[n]})}else t[n]=Xd(function(){return e[n]})}),t}function YY(e,t){var n=t.split("/").filter(function(r){return r});return n.reduce(function(r,o,a){var l=r[o];if(!l)throw new Error('Missing module "'+o+'" for path "'+t+'".');return a===n.length-1?l:l._children},t==="root"?e:e.root._children)}function Xd(e){try{return e()}catch(t){return t}}var _r=function(t,n){this.runtime=n,this._children=Object.create(null),this._rawModule=t;var r=t.state;this.state=(typeof r=="function"?r():r)||{}},u2={namespaced:{configurable:!0}};u2.namespaced.get=function(){return!!this._rawModule.namespaced};_r.prototype.addChild=function(t,n){this._children[t]=n};_r.prototype.removeChild=function(t){delete this._children[t]};_r.prototype.getChild=function(t){return this._children[t]};_r.prototype.hasChild=function(t){return t in this._children};_r.prototype.update=function(t){this._rawModule.namespaced=t.namespaced,t.actions&&(this._rawModule.actions=t.actions),t.mutations&&(this._rawModule.mutations=t.mutations),t.getters&&(this._rawModule.getters=t.getters)};_r.prototype.forEachChild=function(t){wl(this._children,t)};_r.prototype.forEachGetter=function(t){this._rawModule.getters&&wl(this._rawModule.getters,t)};_r.prototype.forEachAction=function(t){this._rawModule.actions&&wl(this._rawModule.actions,t)};_r.prototype.forEachMutation=function(t){this._rawModule.mutations&&wl(this._rawModule.mutations,t)};Object.defineProperties(_r.prototype,u2);var ka=function(t){this.register([],t,!1)};ka.prototype.get=function(t){return t.reduce(function(n,r){return n.getChild(r)},this.root)};ka.prototype.getNamespace=function(t){var n=this.root;return t.reduce(function(r,o){return n=n.getChild(o),r+(n.namespaced?o+"/":"")},"")};ka.prototype.update=function(t){c2([],this.root,t)};ka.prototype.register=function(t,n,r){var o=this;r===void 0&&(r=!0);var a=new _r(n,r);if(t.length===0)this.root=a;else{var l=this.get(t.slice(0,-1));l.addChild(t[t.length-1],a)}n.modules&&wl(n.modules,function(s,i){o.register(t.concat(i),s,r)})};ka.prototype.unregister=function(t){var n=this.get(t.slice(0,-1)),r=t[t.length-1],o=n.getChild(r);!o||!o.runtime||n.removeChild(r)};ka.prototype.isRegistered=function(t){var n=this.get(t.slice(0,-1)),r=t[t.length-1];return n?n.hasChild(r):!1};function c2(e,t,n){if(t.update(n),n.modules)for(var r in n.modules){if(!t.getChild(r))return;c2(e.concat(r),t.getChild(r),n.modules[r])}}function GY(e){return new Nn(e)}var Nn=function(t){var n=this;t===void 0&&(t={});var r=t.plugins;r===void 0&&(r=[]);var o=t.strict;o===void 0&&(o=!1);var a=t.devtools;this._committing=!1,this._actions=Object.create(null),this._actionSubscribers=[],this._mutations=Object.create(null),this._wrappedGetters=Object.create(null),this._modules=new ka(t),this._modulesNamespaceMap=Object.create(null),this._subscribers=[],this._makeLocalGettersCache=Object.create(null),this._devtools=a;var l=this,s=this,i=s.dispatch,u=s.commit;this.dispatch=function(h,p){return i.call(l,h,p)},this.commit=function(h,p,v){return u.call(l,h,p,v)},this.strict=o;var d=this._modules.root.state;oc(this,d,[],this._modules.root),Fp(this,d),r.forEach(function(f){return f(n)})},Bp={state:{configurable:!0}};Nn.prototype.install=function(t,n){t.provide(n||PY,this),t.config.globalProperties.$store=this;var r=this._devtools!==void 0?this._devtools:!1;r&&jY(t,this)};Bp.state.get=function(){return this._state.data};Bp.state.set=function(e){};Nn.prototype.commit=function(t,n,r){var o=this,a=ku(t,n,r),l=a.type,s=a.payload,i={type:l,payload:s},u=this._mutations[l];!u||(this._withCommit(function(){u.forEach(function(f){f(s)})}),this._subscribers.slice().forEach(function(d){return d(i,o.state)}))};Nn.prototype.dispatch=function(t,n){var r=this,o=ku(t,n),a=o.type,l=o.payload,s={type:a,payload:l},i=this._actions[a];if(!!i){try{this._actionSubscribers.slice().filter(function(d){return d.before}).forEach(function(d){return d.before(s,r.state)})}catch{}var u=i.length>1?Promise.all(i.map(function(d){return d(l)})):i[0](l);return new Promise(function(d,f){u.then(function(h){try{r._actionSubscribers.filter(function(p){return p.after}).forEach(function(p){return p.after(s,r.state)})}catch{}d(h)},function(h){try{r._actionSubscribers.filter(function(p){return p.error}).forEach(function(p){return p.error(s,r.state,h)})}catch{}f(h)})})}};Nn.prototype.subscribe=function(t,n){return n2(t,this._subscribers,n)};Nn.prototype.subscribeAction=function(t,n){var r=typeof t=="function"?{before:t}:t;return n2(r,this._actionSubscribers,n)};Nn.prototype.watch=function(t,n,r){var o=this;return $e(function(){return t(o.state,o.getters)},n,Object.assign({},r))};Nn.prototype.replaceState=function(t){var n=this;this._withCommit(function(){n._state.data=t})};Nn.prototype.registerModule=function(t,n,r){r===void 0&&(r={}),typeof t=="string"&&(t=[t]),this._modules.register(t,n),oc(this,this.state,t,this._modules.get(t),r.preserveState),Fp(this,this.state)};Nn.prototype.unregisterModule=function(t){var n=this;typeof t=="string"&&(t=[t]),this._modules.unregister(t),this._withCommit(function(){var r=Vp(n.state,t.slice(0,-1));delete r[t[t.length-1]]}),r2(this)};Nn.prototype.hasModule=function(t){return typeof t=="string"&&(t=[t]),this._modules.isRegistered(t)};Nn.prototype.hotUpdate=function(t){this._modules.update(t),r2(this,!0)};Nn.prototype._withCommit=function(t){var n=this._committing;this._committing=!0,t(),this._committing=n};Object.defineProperties(Nn.prototype,Bp);const d2=Vx({legacy:!1,locale:"zh-CN",fallbackLocale:""}),XY=GY({state:{filePickerOpened:!1}});globalThis.Schema=Rs;globalThis.i18n=d2;var JY=Ro({enhance({app:e,router:t,siteData:n}){e.use(XY),e.use(CV),e.use(tY),e.use(hB),e.use(vB),e.use(nY),e.use(Bz),e.use(Uz),e.use(Qr),e.use(da),e.use(Gz),e.use(SH),e.use(Ij),e.use(Xj),e.use(qW),e.use(YW),e.use(GW),e.use(Kn),e.use(Fw),e.use(sK),e.use(Oz),e.use(yl),e.use(Hw),e.use(DK),e.use(YK),e.use(j7),e.use(mw),e.use(Ca),e.use(G7),e.use(tW),e.use(d2),e.use(an),e.component("k-markdown",b4)},setup(){}});const Fc=[_E,kE,TE,VE,jE,YE,lT,JY],ZY=[["v-8daa1a0e","/",{title:"SD-Trainer"},["/index.html","/index.md"]],["v-6983ba2a","/tageditor.html",{title:""},["/tageditor","/tageditor.md"]],["v-51615306","/tagger.html",{title:"Tagger \u6807\u6CE8\u5DE5\u5177"},["/tagger","/tagger.md"]],["v-06850b9b","/task.html",{title:""},["/task","/task.md"]],["v-13efe3c5","/tensorboard.html",{title:""},["/tensorboard","/tensorboard.md"]],["v-33a23463","/dreambooth/",{title:"Dreambooth \u8BAD\u7EC3 \u4E13\u5BB6\u6A21\u5F0F"},["/dreambooth/index.html","/dreambooth/index.md"]],["v-b5471278","/other/about.html",{title:""},["/other/about","/other/about.md"]],["v-a1c9e4f2","/other/changelog.html",{title:"\u66F4\u65B0\u65E5\u5FD7"},["/other/changelog","/other/changelog.md"]],["v-b8e2d701","/help/guide.html",{title:"\u65b0\u624b\u4e0a\u8def"},["/help/guide","/help/guide.md"]],["v-72e1da3e","/other/settings.html",{title:"\u8BAD\u7EC3 UI \u8BBE\u7F6E"},["/other/settings","/other/settings.md"]],["v-3e43d6e2","/lora/basic.html",{title:"LoRA \u8BAD\u7EC3 \u65B0\u624B\u6A21\u5F0F"},["/lora/basic","/lora/basic.md"]],["v-fdbe4e28","/lora/flux.html",{title:"Flux LoRA \u8BAD\u7EC3 \u4E13\u5BB6\u6A21\u5F0F"},["/lora/flux","/lora/flux.md"]],["v-14e91824","/lora/",{title:"LoRA \u8BAD\u7EC3"},["/lora/index.html","/lora/index.md"]],["v-1bf725da","/lora/master.html",{title:"LoRA \u8BAD\u7EC3 \u4E13\u5BB6\u6A21\u5F0F"},["/lora/master","/lora/master.md"]],["v-0f9e746f","/lora/params.html",{title:"\u8BAD\u7EC3\u53C2\u6570\u8C03\u8282"},["/lora/params","/lora/params.md"]],["v-0dc76a3b","/lora/sd3.html",{title:"SD3 \u8BAD\u7EC3 \u4E13\u5BB6\u6A21\u5F0F"},["/lora/sd3","/lora/sd3.md"]],["v-a1f1ne2e","/lora/anima-finetune.html",{title:"Anima \u5168\u91cf\u5FAE\u8C03 \u4E13\u5BB6\u6A21\u5F0F"},["/lora/anima-finetune","/lora/anima-finetune.md"]],["v-53c99f50","/lora/sdxl.html",{title:"SDXL LoRA \u8BAD\u7EC3 \u4E13\u5BB6\u6A21\u5F0F"},["/lora/sdxl","/lora/sdxl.md"]],["v-4441a302","/lora/tools.html",{title:"LoRA \u76F8\u5173\u5DE5\u5177"},["/lora/tools","/lora/tools.md"]],["v-3706649a","/404.html",{title:""},["/404"]]];var QY=()=>ZY.reduce((e,[t,n,r,o])=>(e.push({name:t,path:n,component:Am,meta:r},...o.map(a=>({path:a,redirect:n}))),e),[{name:"404",path:"/:catchAll(.*)",component:Am}]),eG=AS,tG=()=>{const e=pE({history:eG(eS(wo.value.base)),routes:QY(),scrollBehavior:(t,n,r)=>r||(t.hash?{el:t.hash}:{top:0})});return e.beforeResolve(async(t,n)=>{var r;(t.path!==n.path||n===Vr)&&([jr.value]=await Promise.all([Wo.resolvePageData(t.name),(r=i0[t.name])==null?void 0:r.__asyncLoader()]))}),e},nG=e=>{e.component("ClientOnly",cS),e.component("Content",dS)},rG=(e,t)=>{const n=O(()=>Wo.resolveRouteLocale(wo.value.locales,t.currentRoute.value.path)),r=O(()=>Wo.resolveSiteLocaleData(wo.value,n.value)),o=O(()=>Wo.resolvePageFrontmatter(jr.value)),a=O(()=>Wo.resolvePageHeadTitle(jr.value,r.value)),l=O(()=>Wo.resolvePageHead(a.value,o.value,r.value)),s=O(()=>Wo.resolvePageLang(jr.value));return e.provide(Cf,n),e.provide(m0,r),e.provide(d0,o),e.provide(aS,a),e.provide(f0,l),e.provide(p0,s),Object.defineProperties(e.config.globalProperties,{$frontmatter:{get:()=>o.value},$head:{get:()=>l.value},$headTitle:{get:()=>a.value},$lang:{get:()=>s.value},$page:{get:()=>jr.value},$routeLocale:{get:()=>n.value},$site:{get:()=>wo.value},$siteLocale:{get:()=>r.value},$withBase:{get:()=>fS}}),{pageData:jr,pageFrontmatter:o,pageHead:l,pageHeadTitle:a,pageLang:s,routeLocale:n,siteData:wo,siteLocaleData:r}},oG=()=>{const e=$f(),t=oS(),n=lS(),r=B([]),o=()=>{t.value.forEach(l=>{const s=aG(l);s&&r.value.push(s)})},a=()=>{document.documentElement.lang=n.value,r.value.forEach(l=>{l.parentNode===document.head&&document.head.removeChild(l)}),r.value.splice(0,r.value.length),t.value.forEach(l=>{const s=lG(l);s!==null&&(document.head.appendChild(s),r.value.push(s))})};yt(uS,a),dt(()=>{o(),a(),$e(()=>e.path,()=>a())})},aG=([e,t,n=""])=>{const r=Object.entries(t).map(([s,i])=>Ge(i)?`[${s}="${i}"]`:i===!0?`[${s}]`:"").join(""),o=`head > ${e}${r}`;return Array.from(document.querySelectorAll(o)).find(s=>s.innerText===n)||null},lG=([e,t,n])=>{if(!Ge(e))return null;const r=document.createElement(e);return l0(t)&&Object.entries(t).forEach(([o,a])=>{Ge(a)?r.setAttribute(o,a):a===!0&&r.setAttribute(o,"")}),Ge(n)&&r.appendChild(document.createTextNode(n)),r},sG=Yk,iG=async()=>{var n;const e=sG({name:"VuepressApp",setup(){var r;oG();for(const o of Fc)(r=o.setup)==null||r.call(o);return()=>[He($0),...Fc.flatMap(({rootComponents:o=[]})=>o.map(a=>He(a)))]}}),t=tG();nG(e),rG(e,t);for(const r of Fc)await((n=r.enhance)==null?void 0:n.call(r,{app:e,router:t,siteData:wo}));return e.use(t),{app:e,router:t}};iG().then(({app:e,router:t})=>{t.isReady().then(()=>{e.mount("#app")})});export{ht as $,$e as A,V5 as B,dt as C,rn as D,at as E,K5 as F,dr as G,ze as H,c_ as I,ce as J,vt as K,D as L,Qe as M,$t as N,Lt as O,ye as P,Dt as Q,pe as R,qt as S,K1 as T,Mn as U,xt as V,Ge as W,Ua as X,Om as Y,ft as Z,St as _,K as a,Er as a0,Ke as a1,ua as a2,rS as a3,Pe as a4,it as a5,De as a6,$f as a7,Ht as a8,Qk as a9,CV as aA,bG as aB,xn as aC,Is as aD,fG as aa,pG as ab,iS as ac,mG as ad,vG as ae,He as af,fS as ag,cS as ah,tS as ai,eS as aj,Ef as ak,Z$ as al,Ps as am,gG as an,l0 as ao,hG as ap,Ei as aq,_C as ar,wC as as,Mo as at,eT as au,us as av,Rs as aw,gY as ax,kn as ay,As as az,Je as b,U as c,iG as createVueApp,Q as d,dG as e,se as f,H0 as g,c as h,Qr as i,A_ as j,Kn as k,Nj as l,nt as m,qe as n,x as o,q1 as p,uV as q,Ve as r,O as s,Ee as t,sS as u,B as v,G as w,Xt as x,gu as y,Lo as z}; + */var PY="store";function wl(e,t){Object.keys(e).forEach(function(n){return t(e[n],n)})}function LY(e){return e!==null&&typeof e=="object"}function MY(e){return e&&typeof e.then=="function"}function RY(e,t){return function(){return e(t)}}function n2(e,t,n){return t.indexOf(e)<0&&(n&&n.prepend?t.unshift(e):t.push(e)),function(){var r=t.indexOf(e);r>-1&&t.splice(r,1)}}function r2(e,t){e._actions=Object.create(null),e._mutations=Object.create(null),e._wrappedGetters=Object.create(null),e._modulesNamespaceMap=Object.create(null);var n=e.state;oc(e,n,[],e._modules.root,!0),Fp(e,n,t)}function Fp(e,t,n){var r=e._state;e.getters={},e._makeLocalGettersCache=Object.create(null);var o=e._wrappedGetters,a={};wl(o,function(l,s){a[s]=RY(l,e),Object.defineProperty(e.getters,s,{get:function(){return a[s]()},enumerable:!0})}),e._state=Xt({data:t}),e.strict&&BY(e),r&&n&&e._withCommit(function(){r.data=null})}function oc(e,t,n,r,o){var a=!n.length,l=e._modules.getNamespace(n);if(r.namespaced&&(e._modulesNamespaceMap[l],e._modulesNamespaceMap[l]=r),!a&&!o){var s=Vp(t,n.slice(0,-1)),i=n[n.length-1];e._withCommit(function(){s[i]=r.state})}var u=r.context=NY(e,l,n);r.forEachMutation(function(d,f){var h=l+f;DY(e,h,d,u)}),r.forEachAction(function(d,f){var h=d.root?f:l+f,p=d.handler||d;FY(e,h,p,u)}),r.forEachGetter(function(d,f){var h=l+f;VY(e,h,d,u)}),r.forEachChild(function(d,f){oc(e,t,n.concat(f),d,o)})}function NY(e,t,n){var r=t==="",o={dispatch:r?e.dispatch:function(a,l,s){var i=ku(a,l,s),u=i.payload,d=i.options,f=i.type;return(!d||!d.root)&&(f=t+f),e.dispatch(f,u)},commit:r?e.commit:function(a,l,s){var i=ku(a,l,s),u=i.payload,d=i.options,f=i.type;(!d||!d.root)&&(f=t+f),e.commit(f,u,d)}};return Object.defineProperties(o,{getters:{get:r?function(){return e.getters}:function(){return o2(e,t)}},state:{get:function(){return Vp(e.state,n)}}}),o}function o2(e,t){if(!e._makeLocalGettersCache[t]){var n={},r=t.length;Object.keys(e.getters).forEach(function(o){if(o.slice(0,r)===t){var a=o.slice(r);Object.defineProperty(n,a,{get:function(){return e.getters[o]},enumerable:!0})}}),e._makeLocalGettersCache[t]=n}return e._makeLocalGettersCache[t]}function DY(e,t,n,r){var o=e._mutations[t]||(e._mutations[t]=[]);o.push(function(l){n.call(e,r.state,l)})}function FY(e,t,n,r){var o=e._actions[t]||(e._actions[t]=[]);o.push(function(l){var s=n.call(e,{dispatch:r.dispatch,commit:r.commit,getters:r.getters,state:r.state,rootGetters:e.getters,rootState:e.state},l);return MY(s)||(s=Promise.resolve(s)),e._devtoolHook?s.catch(function(i){throw e._devtoolHook.emit("vuex:error",i),i}):s})}function VY(e,t,n,r){e._wrappedGetters[t]||(e._wrappedGetters[t]=function(a){return n(r.state,r.getters,a.state,a.getters)})}function BY(e){$e(function(){return e._state.data},function(){},{deep:!0,flush:"sync"})}function Vp(e,t){return t.reduce(function(n,r){return n[r]},e)}function ku(e,t,n){return LY(e)&&e.type&&(n=t,t=e,e=e.type),{type:e,payload:t,options:n}}var zY="vuex bindings",Wg="vuex:mutations",Dc="vuex:actions",Oa="vuex",HY=0;function jY(e,t){IY({id:"org.vuejs.vuex",app:e,label:"Vuex",homepage:"https://next.vuex.vuejs.org/",logo:"https://vuejs.org/images/icons/favicon-96x96.png",packageName:"vuex",componentStateTypes:[zY]},function(n){n.addTimelineLayer({id:Wg,label:"Vuex Mutations",color:Ug}),n.addTimelineLayer({id:Dc,label:"Vuex Actions",color:Ug}),n.addInspector({id:Oa,label:"Vuex",icon:"storage",treeFilterPlaceholder:"Filter stores..."}),n.on.getInspectorTree(function(r){if(r.app===e&&r.inspectorId===Oa)if(r.filter){var o=[];i2(o,t._modules.root,r.filter,""),r.rootNodes=o}else r.rootNodes=[s2(t._modules.root,"")]}),n.on.getInspectorState(function(r){if(r.app===e&&r.inspectorId===Oa){var o=r.nodeId;o2(t,o),r.state=KY(YY(t._modules,o),o==="root"?t.getters:t._makeLocalGettersCache,o)}}),n.on.editInspectorState(function(r){if(r.app===e&&r.inspectorId===Oa){var o=r.nodeId,a=r.path;o!=="root"&&(a=o.split("/").filter(Boolean).concat(a)),t._withCommit(function(){r.set(t._state.data,a,r.state.value)})}}),t.subscribe(function(r,o){var a={};r.payload&&(a.payload=r.payload),a.state=o,n.notifyComponentUpdate(),n.sendInspectorTree(Oa),n.sendInspectorState(Oa),n.addTimelineEvent({layerId:Wg,event:{time:Date.now(),title:r.type,data:a}})}),t.subscribeAction({before:function(r,o){var a={};r.payload&&(a.payload=r.payload),r._id=HY++,r._time=Date.now(),a.state=o,n.addTimelineEvent({layerId:Dc,event:{time:r._time,title:r.type,groupId:r._id,subtitle:"start",data:a}})},after:function(r,o){var a={},l=Date.now()-r._time;a.duration={_custom:{type:"duration",display:l+"ms",tooltip:"Action duration",value:l}},r.payload&&(a.payload=r.payload),a.state=o,n.addTimelineEvent({layerId:Dc,event:{time:Date.now(),title:r.type,groupId:r._id,subtitle:"end",data:a}})}})})}var Ug=8702998,WY=6710886,UY=16777215,a2={label:"namespaced",textColor:UY,backgroundColor:WY};function l2(e){return e&&e!=="root"?e.split("/").slice(-2,-1)[0]:"Root"}function s2(e,t){return{id:t||"root",label:l2(t),tags:e.namespaced?[a2]:[],children:Object.keys(e._children).map(function(n){return s2(e._children[n],t+n+"/")})}}function i2(e,t,n,r){r.includes(n)&&e.push({id:r||"root",label:r.endsWith("/")?r.slice(0,r.length-1):r||"Root",tags:t.namespaced?[a2]:[]}),Object.keys(t._children).forEach(function(o){i2(e,t._children[o],n,r+o+"/")})}function KY(e,t,n){t=n==="root"?t:t[n];var r=Object.keys(t),o={state:Object.keys(e.state).map(function(l){return{key:l,editable:!0,value:e.state[l]}})};if(r.length){var a=qY(t);o.getters=Object.keys(a).map(function(l){return{key:l.endsWith("/")?l2(l):l,editable:!1,value:Xd(function(){return a[l]})}})}return o}function qY(e){var t={};return Object.keys(e).forEach(function(n){var r=n.split("/");if(r.length>1){var o=t,a=r.pop();r.forEach(function(l){o[l]||(o[l]={_custom:{value:{},display:l,tooltip:"Module",abstract:!0}}),o=o[l]._custom.value}),o[a]=Xd(function(){return e[n]})}else t[n]=Xd(function(){return e[n]})}),t}function YY(e,t){var n=t.split("/").filter(function(r){return r});return n.reduce(function(r,o,a){var l=r[o];if(!l)throw new Error('Missing module "'+o+'" for path "'+t+'".');return a===n.length-1?l:l._children},t==="root"?e:e.root._children)}function Xd(e){try{return e()}catch(t){return t}}var _r=function(t,n){this.runtime=n,this._children=Object.create(null),this._rawModule=t;var r=t.state;this.state=(typeof r=="function"?r():r)||{}},u2={namespaced:{configurable:!0}};u2.namespaced.get=function(){return!!this._rawModule.namespaced};_r.prototype.addChild=function(t,n){this._children[t]=n};_r.prototype.removeChild=function(t){delete this._children[t]};_r.prototype.getChild=function(t){return this._children[t]};_r.prototype.hasChild=function(t){return t in this._children};_r.prototype.update=function(t){this._rawModule.namespaced=t.namespaced,t.actions&&(this._rawModule.actions=t.actions),t.mutations&&(this._rawModule.mutations=t.mutations),t.getters&&(this._rawModule.getters=t.getters)};_r.prototype.forEachChild=function(t){wl(this._children,t)};_r.prototype.forEachGetter=function(t){this._rawModule.getters&&wl(this._rawModule.getters,t)};_r.prototype.forEachAction=function(t){this._rawModule.actions&&wl(this._rawModule.actions,t)};_r.prototype.forEachMutation=function(t){this._rawModule.mutations&&wl(this._rawModule.mutations,t)};Object.defineProperties(_r.prototype,u2);var ka=function(t){this.register([],t,!1)};ka.prototype.get=function(t){return t.reduce(function(n,r){return n.getChild(r)},this.root)};ka.prototype.getNamespace=function(t){var n=this.root;return t.reduce(function(r,o){return n=n.getChild(o),r+(n.namespaced?o+"/":"")},"")};ka.prototype.update=function(t){c2([],this.root,t)};ka.prototype.register=function(t,n,r){var o=this;r===void 0&&(r=!0);var a=new _r(n,r);if(t.length===0)this.root=a;else{var l=this.get(t.slice(0,-1));l.addChild(t[t.length-1],a)}n.modules&&wl(n.modules,function(s,i){o.register(t.concat(i),s,r)})};ka.prototype.unregister=function(t){var n=this.get(t.slice(0,-1)),r=t[t.length-1],o=n.getChild(r);!o||!o.runtime||n.removeChild(r)};ka.prototype.isRegistered=function(t){var n=this.get(t.slice(0,-1)),r=t[t.length-1];return n?n.hasChild(r):!1};function c2(e,t,n){if(t.update(n),n.modules)for(var r in n.modules){if(!t.getChild(r))return;c2(e.concat(r),t.getChild(r),n.modules[r])}}function GY(e){return new Nn(e)}var Nn=function(t){var n=this;t===void 0&&(t={});var r=t.plugins;r===void 0&&(r=[]);var o=t.strict;o===void 0&&(o=!1);var a=t.devtools;this._committing=!1,this._actions=Object.create(null),this._actionSubscribers=[],this._mutations=Object.create(null),this._wrappedGetters=Object.create(null),this._modules=new ka(t),this._modulesNamespaceMap=Object.create(null),this._subscribers=[],this._makeLocalGettersCache=Object.create(null),this._devtools=a;var l=this,s=this,i=s.dispatch,u=s.commit;this.dispatch=function(h,p){return i.call(l,h,p)},this.commit=function(h,p,v){return u.call(l,h,p,v)},this.strict=o;var d=this._modules.root.state;oc(this,d,[],this._modules.root),Fp(this,d),r.forEach(function(f){return f(n)})},Bp={state:{configurable:!0}};Nn.prototype.install=function(t,n){t.provide(n||PY,this),t.config.globalProperties.$store=this;var r=this._devtools!==void 0?this._devtools:!1;r&&jY(t,this)};Bp.state.get=function(){return this._state.data};Bp.state.set=function(e){};Nn.prototype.commit=function(t,n,r){var o=this,a=ku(t,n,r),l=a.type,s=a.payload,i={type:l,payload:s},u=this._mutations[l];!u||(this._withCommit(function(){u.forEach(function(f){f(s)})}),this._subscribers.slice().forEach(function(d){return d(i,o.state)}))};Nn.prototype.dispatch=function(t,n){var r=this,o=ku(t,n),a=o.type,l=o.payload,s={type:a,payload:l},i=this._actions[a];if(!!i){try{this._actionSubscribers.slice().filter(function(d){return d.before}).forEach(function(d){return d.before(s,r.state)})}catch{}var u=i.length>1?Promise.all(i.map(function(d){return d(l)})):i[0](l);return new Promise(function(d,f){u.then(function(h){try{r._actionSubscribers.filter(function(p){return p.after}).forEach(function(p){return p.after(s,r.state)})}catch{}d(h)},function(h){try{r._actionSubscribers.filter(function(p){return p.error}).forEach(function(p){return p.error(s,r.state,h)})}catch{}f(h)})})}};Nn.prototype.subscribe=function(t,n){return n2(t,this._subscribers,n)};Nn.prototype.subscribeAction=function(t,n){var r=typeof t=="function"?{before:t}:t;return n2(r,this._actionSubscribers,n)};Nn.prototype.watch=function(t,n,r){var o=this;return $e(function(){return t(o.state,o.getters)},n,Object.assign({},r))};Nn.prototype.replaceState=function(t){var n=this;this._withCommit(function(){n._state.data=t})};Nn.prototype.registerModule=function(t,n,r){r===void 0&&(r={}),typeof t=="string"&&(t=[t]),this._modules.register(t,n),oc(this,this.state,t,this._modules.get(t),r.preserveState),Fp(this,this.state)};Nn.prototype.unregisterModule=function(t){var n=this;typeof t=="string"&&(t=[t]),this._modules.unregister(t),this._withCommit(function(){var r=Vp(n.state,t.slice(0,-1));delete r[t[t.length-1]]}),r2(this)};Nn.prototype.hasModule=function(t){return typeof t=="string"&&(t=[t]),this._modules.isRegistered(t)};Nn.prototype.hotUpdate=function(t){this._modules.update(t),r2(this,!0)};Nn.prototype._withCommit=function(t){var n=this._committing;this._committing=!0,t(),this._committing=n};Object.defineProperties(Nn.prototype,Bp);const d2=Vx({legacy:!1,locale:"zh-CN",fallbackLocale:""}),XY=GY({state:{filePickerOpened:!1}});globalThis.Schema=Rs;globalThis.i18n=d2;var JY=Ro({enhance({app:e,router:t,siteData:n}){e.use(XY),e.use(CV),e.use(tY),e.use(hB),e.use(vB),e.use(nY),e.use(Bz),e.use(Uz),e.use(Qr),e.use(da),e.use(Gz),e.use(SH),e.use(Ij),e.use(Xj),e.use(qW),e.use(YW),e.use(GW),e.use(Kn),e.use(Fw),e.use(sK),e.use(Oz),e.use(yl),e.use(Hw),e.use(DK),e.use(YK),e.use(j7),e.use(mw),e.use(Ca),e.use(G7),e.use(tW),e.use(d2),e.use(an),e.component("k-markdown",b4)},setup(){}});const Fc=[_E,kE,TE,VE,jE,YE,lT,JY],ZY=[["v-8daa1a0e","/",{title:"SD-Trainer"},["/index.html","/index.md"]],["v-6983ba2a","/tageditor.html",{title:""},["/tageditor","/tageditor.md"]],["v-native-tageditor","/native-tageditor.html",{title:""},["/native-tageditor","/native-tageditor.md"]],["v-51615306","/tagger.html",{title:"Tagger \u6807\u6CE8\u5DE5\u5177"},["/tagger","/tagger.md"]],["v-06850b9b","/task.html",{title:""},["/task","/task.md"]],["v-13efe3c5","/tensorboard.html",{title:""},["/tensorboard","/tensorboard.md"]],["v-33a23463","/dreambooth/",{title:"Dreambooth \u8BAD\u7EC3 \u4E13\u5BB6\u6A21\u5F0F"},["/dreambooth/index.html","/dreambooth/index.md"]],["v-b5471278","/other/about.html",{title:""},["/other/about","/other/about.md"]],["v-a1c9e4f2","/other/changelog.html",{title:"\u66F4\u65B0\u65E5\u5FD7"},["/other/changelog","/other/changelog.md"]],["v-b8e2d701","/help/guide.html",{title:"\u65b0\u624b\u4e0a\u8def"},["/help/guide","/help/guide.md"]],["v-72e1da3e","/other/settings.html",{title:"\u8BAD\u7EC3 UI \u8BBE\u7F6E"},["/other/settings","/other/settings.md"]],["v-3e43d6e2","/lora/basic.html",{title:"LoRA \u8BAD\u7EC3 \u65B0\u624B\u6A21\u5F0F"},["/lora/basic","/lora/basic.md"]],["v-fdbe4e28","/lora/flux.html",{title:"Flux LoRA \u8BAD\u7EC3 \u4E13\u5BB6\u6A21\u5F0F"},["/lora/flux","/lora/flux.md"]],["v-14e91824","/lora/",{title:"LoRA \u8BAD\u7EC3"},["/lora/index.html","/lora/index.md"]],["v-1bf725da","/lora/master.html",{title:"LoRA \u8BAD\u7EC3 \u4E13\u5BB6\u6A21\u5F0F"},["/lora/master","/lora/master.md"]],["v-0f9e746f","/lora/params.html",{title:"\u8BAD\u7EC3\u53C2\u6570\u8C03\u8282"},["/lora/params","/lora/params.md"]],["v-0dc76a3b","/lora/sd3.html",{title:"SD3 \u8BAD\u7EC3 \u4E13\u5BB6\u6A21\u5F0F"},["/lora/sd3","/lora/sd3.md"]],["v-a1f1ne2e","/lora/anima-finetune.html",{title:"Anima \u5168\u91cf\u5FAE\u8C03 \u4E13\u5BB6\u6A21\u5F0F"},["/lora/anima-finetune","/lora/anima-finetune.md"]],["v-53c99f50","/lora/sdxl.html",{title:"SDXL LoRA \u8BAD\u7EC3 \u4E13\u5BB6\u6A21\u5F0F"},["/lora/sdxl","/lora/sdxl.md"]],["v-4441a302","/lora/tools.html",{title:"LoRA \u76F8\u5173\u5DE5\u5177"},["/lora/tools","/lora/tools.md"]],["v-3706649a","/404.html",{title:""},["/404"]]];var QY=()=>ZY.reduce((e,[t,n,r,o])=>(e.push({name:t,path:n,component:Am,meta:r},...o.map(a=>({path:a,redirect:n}))),e),[{name:"404",path:"/:catchAll(.*)",component:Am}]),eG=AS,tG=()=>{const e=pE({history:eG(eS(wo.value.base)),routes:QY(),scrollBehavior:(t,n,r)=>r||(t.hash?{el:t.hash}:{top:0})});return e.beforeResolve(async(t,n)=>{var r;(t.path!==n.path||n===Vr)&&([jr.value]=await Promise.all([Wo.resolvePageData(t.name),(r=i0[t.name])==null?void 0:r.__asyncLoader()]))}),e},nG=e=>{e.component("ClientOnly",cS),e.component("Content",dS)},rG=(e,t)=>{const n=O(()=>Wo.resolveRouteLocale(wo.value.locales,t.currentRoute.value.path)),r=O(()=>Wo.resolveSiteLocaleData(wo.value,n.value)),o=O(()=>Wo.resolvePageFrontmatter(jr.value)),a=O(()=>Wo.resolvePageHeadTitle(jr.value,r.value)),l=O(()=>Wo.resolvePageHead(a.value,o.value,r.value)),s=O(()=>Wo.resolvePageLang(jr.value));return e.provide(Cf,n),e.provide(m0,r),e.provide(d0,o),e.provide(aS,a),e.provide(f0,l),e.provide(p0,s),Object.defineProperties(e.config.globalProperties,{$frontmatter:{get:()=>o.value},$head:{get:()=>l.value},$headTitle:{get:()=>a.value},$lang:{get:()=>s.value},$page:{get:()=>jr.value},$routeLocale:{get:()=>n.value},$site:{get:()=>wo.value},$siteLocale:{get:()=>r.value},$withBase:{get:()=>fS}}),{pageData:jr,pageFrontmatter:o,pageHead:l,pageHeadTitle:a,pageLang:s,routeLocale:n,siteData:wo,siteLocaleData:r}},oG=()=>{const e=$f(),t=oS(),n=lS(),r=B([]),o=()=>{t.value.forEach(l=>{const s=aG(l);s&&r.value.push(s)})},a=()=>{document.documentElement.lang=n.value,r.value.forEach(l=>{l.parentNode===document.head&&document.head.removeChild(l)}),r.value.splice(0,r.value.length),t.value.forEach(l=>{const s=lG(l);s!==null&&(document.head.appendChild(s),r.value.push(s))})};yt(uS,a),dt(()=>{o(),a(),$e(()=>e.path,()=>a())})},aG=([e,t,n=""])=>{const r=Object.entries(t).map(([s,i])=>Ge(i)?`[${s}="${i}"]`:i===!0?`[${s}]`:"").join(""),o=`head > ${e}${r}`;return Array.from(document.querySelectorAll(o)).find(s=>s.innerText===n)||null},lG=([e,t,n])=>{if(!Ge(e))return null;const r=document.createElement(e);return l0(t)&&Object.entries(t).forEach(([o,a])=>{Ge(a)?r.setAttribute(o,a):a===!0&&r.setAttribute(o,"")}),Ge(n)&&r.appendChild(document.createTextNode(n)),r},sG=Yk,iG=async()=>{var n;const e=sG({name:"VuepressApp",setup(){var r;oG();for(const o of Fc)(r=o.setup)==null||r.call(o);return()=>[He($0),...Fc.flatMap(({rootComponents:o=[]})=>o.map(a=>He(a)))]}}),t=tG();nG(e),rG(e,t);for(const r of Fc)await((n=r.enhance)==null?void 0:n.call(r,{app:e,router:t,siteData:wo}));return e.use(t),{app:e,router:t}};iG().then(({app:e,router:t})=>{t.isReady().then(()=>{e.mount("#app")})});export{ht as $,$e as A,V5 as B,dt as C,rn as D,at as E,K5 as F,dr as G,ze as H,c_ as I,ce as J,vt as K,D as L,Qe as M,$t as N,Lt as O,ye as P,Dt as Q,pe as R,qt as S,K1 as T,Mn as U,xt as V,Ge as W,Ua as X,Om as Y,ft as Z,St as _,K as a,Er as a0,Ke as a1,ua as a2,rS as a3,Pe as a4,it as a5,De as a6,$f as a7,Ht as a8,Qk as a9,CV as aA,bG as aB,xn as aC,Is as aD,fG as aa,pG as ab,iS as ac,mG as ad,vG as ae,He as af,fS as ag,cS as ah,tS as ai,eS as aj,Ef as ak,Z$ as al,Ps as am,gG as an,l0 as ao,hG as ap,Ei as aq,_C as ar,wC as as,Mo as at,eT as au,us as av,Rs as aw,gY as ax,kn as ay,As as az,Je as b,U as c,iG as createVueApp,Q as d,dG as e,se as f,H0 as g,c as h,Qr as i,A_ as j,Kn as k,Nj as l,nt as m,qe as n,x as o,q1 as p,uV as q,Ve as r,O as s,Ee as t,sS as u,B as v,G as w,Xt as x,gu as y,Lo as z}; + + diff --git a/frontend/dist/assets/dataset-editor-entry.js b/frontend/dist/assets/dataset-editor-entry.js index 9ef8fc5c..3a9c3e50 100644 --- a/frontend/dist/assets/dataset-editor-entry.js +++ b/frontend/dist/assets/dataset-editor-entry.js @@ -70,8 +70,66 @@

批量打标

-

预留位置:后续接入现有数据集打标能力,只作用于当前范围。

- +
+
+ + +
+
+ + +
+
+ + +
+
+
+ + +
+ + + + +
+
+
+ + + + +
+ +
+ + + + +
+
@@ -178,15 +236,15 @@ const root = document.querySelector("#app"); let mounted = false; let stableTimer = 0; + let started = false; function scheduleMount() { window.clearTimeout(stableTimer); stableTimer = window.setTimeout(() => { - if (mounted) return; + if (mounted && document.getElementById("sd-native-editor-entry")) return; if (mountEditor()) { mounted = true; loadEditorScript(); - if (observer) observer.disconnect(); } }, 120); } @@ -199,15 +257,20 @@ observer.observe(root, { childList: true, subtree: true }); } - scheduleMount(); - window.addEventListener("load", () => { - if (mounted) return; - if (mountEditor()) { - mounted = true; - loadEditorScript(); + function startAfterShellSettles() { + if (started) return; + started = true; + window.setTimeout(scheduleMount, 500); + window.setTimeout(() => { if (observer) observer.disconnect(); - } - }); + }, 5000); + } + + if (document.readyState === "complete") { + startAfterShellSettles(); + } else { + window.addEventListener("load", startAfterShellSettles, { once: true }); + } } if (document.readyState === "loading") { diff --git a/frontend/dist/assets/dataset-editor.css b/frontend/dist/assets/dataset-editor.css index 577781f2..c73a4544 100644 --- a/frontend/dist/assets/dataset-editor.css +++ b/frontend/dist/assets/dataset-editor.css @@ -556,6 +556,62 @@ label { color: var(--de-muted); } +.de-tagger-grid { + display: grid; + grid-template-columns: repeat(2, minmax(0, 1fr)); + gap: 8px; +} + +.de-tagger-card, +.de-tagger-model-card { + display: grid; + gap: 8px; + padding: 10px; + border: 1px solid var(--de-border); + border-radius: 8px; + background: #fbfcff; +} + +.de-tagger-card--primary { + border-color: color-mix(in srgb, var(--de-accent) 30%, var(--de-border)); + background: linear-gradient(180deg, color-mix(in srgb, var(--de-accent) 7%, #fff), #fff); +} + +.de-tagger-row { + display: grid; + gap: 6px; +} + +.de-tagger-row--split { + grid-template-columns: minmax(88px, 0.42fr) minmax(0, 1fr); + align-items: center; +} + +.de-tagger-card label, +.de-tagger-model-card label, +.de-tagger-grid label { + margin-top: 2px; + color: var(--de-muted); + font-size: 12px; + font-weight: 700; +} + +.de-tagger-flags { + display: grid; + grid-template-columns: repeat(2, minmax(0, 1fr)); + gap: 6px 8px; + padding: 4px 2px; +} + +.de-tagger-flags .de-checkbox { + min-width: 0; + font-size: 12px; +} + +.de-tagger-run { + min-height: 38px; +} + .de-collapsible { border-top: 1px solid var(--de-border); padding-top: 8px; @@ -589,18 +645,22 @@ label { } .de-shell-embedded { - --de-bg: var(--c-bg-soft, #f9f9f9); + --de-bg: color-mix(in srgb, var(--c-bg-soft, #f9f9f9) 90%, #eef2ff); --de-surface: var(--c-bg, #ffffff); + --de-surface-muted: color-mix(in srgb, var(--de-surface) 82%, #eef2ff); --de-border: var(--c-border, rgba(60, 60, 60, 0.12)); --de-text: var(--c-text-1, #213547); --de-muted: var(--c-text-2, rgba(60, 60, 60, 0.7)); - --de-accent: var(--c-brand, #646cff); - --de-accent-strong: var(--c-brand-dark, #535bf2); + --de-accent: var(--c-brand, #5865f2); + --de-accent-strong: var(--c-brand-dark, #4752d6); + --de-accent-soft: color-mix(in srgb, var(--de-accent) 14%, transparent); + --de-card-shadow: 0 14px 36px rgba(15, 23, 42, 0.08); + --de-soft-shadow: 0 8px 22px rgba(15, 23, 42, 0.05); --de-workbench-min-width: 960px; height: 100vh; min-width: 0; grid-template-rows: 1fr; - padding: 8px 12px 14px; + padding: 10px 14px 16px; background: var(--de-bg); } @@ -608,63 +668,139 @@ label { grid-template-columns: 320px minmax(520px, 1fr) 380px; gap: 10px; height: 100%; + align-items: start; padding: 0; } +.de-shell-embedded .de-filter, +.de-shell-embedded .de-editor { + align-self: start; + max-height: calc(100vh - 26px); +} + +.de-shell-embedded .de-gallery-wrap { + align-self: stretch; + height: 100%; + min-height: calc(100vh - 26px); +} + .de-shell-embedded .de-panel, .de-shell-embedded .de-gallery-wrap { - border-color: var(--de-border); - border-radius: 8px; - box-shadow: none; + border-color: color-mix(in srgb, var(--de-border) 78%, transparent); + border-radius: 10px; + box-shadow: var(--de-card-shadow); } .de-shell-embedded .de-panel { - gap: 8px; - padding: 10px; + gap: 10px; + padding: 16px; + background: var(--de-surface); +} + +.de-shell-embedded .de-gallery-wrap { + background: + radial-gradient(circle at 50% 48%, color-mix(in srgb, var(--de-accent) 8%, transparent), transparent 32%), + linear-gradient(180deg, var(--de-surface) 0%, var(--de-surface-muted) 100%); } .de-shell-embedded .de-dataset-card { - min-height: 128px; - padding: 12px 10px 10px; - border-color: var(--de-border); - background: var(--de-surface); - box-shadow: none; + min-height: 136px; + padding: 16px 14px 14px; + border-color: color-mix(in srgb, var(--de-accent) 22%, var(--de-border)); + background: linear-gradient(180deg, var(--de-surface) 0%, color-mix(in srgb, var(--de-accent) 9%, var(--de-surface)) 100%); + box-shadow: var(--de-soft-shadow); } .de-shell-embedded .de-dataset-card::before { background: var(--de-accent); } +.de-shell-embedded .de-panel h2, +.de-shell-embedded .de-dataset-card label, +.de-shell-embedded .de-scope-card label { + display: flex; + align-items: center; + gap: 8px; + color: var(--de-text); + font-size: 14px; + font-weight: 800; +} + +.de-shell-embedded .de-panel h2::before, +.de-shell-embedded .de-dataset-card label::before, +.de-shell-embedded .de-scope-card label::before { + content: ""; + width: 16px; + height: 16px; + border-radius: 5px; + background: + linear-gradient(90deg, transparent 30%, var(--de-accent) 30% 42%, transparent 42% 58%, var(--de-accent) 58% 70%, transparent 70%), + color-mix(in srgb, var(--de-accent) 12%, var(--de-surface)); + box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--de-accent) 52%, transparent); +} + .de-shell-embedded .de-dataset-path, .de-shell-embedded input, .de-shell-embedded select, .de-shell-embedded textarea { border-color: var(--de-border); border-radius: 6px; + background: var(--de-surface); } .de-shell-embedded .de-dataset-path, .de-shell-embedded .de-dataset-actions button { - min-height: 36px; + min-height: 38px; font-weight: 500; } +.de-shell-embedded .de-dataset-path { + padding-left: 34px; + background: + linear-gradient(var(--de-accent), var(--de-accent)) 16px 50% / 11px 1px no-repeat, + linear-gradient(90deg, transparent 40%, var(--de-accent) 40% 60%, transparent 60%) 13px 50% / 9px 13px no-repeat, + var(--de-surface); +} + .de-shell-embedded button { border-radius: 6px; } +.de-shell-embedded button:not(.de-primary) { + background: color-mix(in srgb, var(--de-surface) 90%, var(--de-bg)); +} + +.de-shell-embedded .de-primary { + border-color: transparent; + background: linear-gradient(135deg, var(--de-accent) 0%, color-mix(in srgb, var(--de-accent) 76%, #7c3aed) 100%); + box-shadow: 0 8px 18px color-mix(in srgb, var(--de-accent) 22%, transparent); +} + .de-shell-embedded .de-tabs { grid-template-columns: repeat(5, minmax(0, 1fr)); + border-color: var(--de-border); + border-radius: 10px; + background: var(--de-surface-muted); + padding: 6px; } .de-shell-embedded .de-tab { - min-height: 28px; + min-height: 40px; font-size: 12px; + font-weight: 700; +} + +.de-shell-embedded .de-tab.is-active { + background: var(--de-surface); + color: var(--de-accent-strong); + box-shadow: 0 6px 14px rgba(15, 23, 42, 0.08); } .de-shell-embedded .de-selection-bar, .de-shell-embedded .de-gallery-pager { - padding: 7px 10px; + padding: 8px 12px; + background: rgba(255, 255, 255, 0.54); + backdrop-filter: blur(8px); } .de-shell-embedded .de-selection-actions { @@ -683,7 +819,18 @@ label { .de-shell-embedded .de-gallery { grid-template-columns: repeat(auto-fill, minmax(170px, 1fr)); gap: 8px; - padding: 10px; + padding: 14px; +} + +.de-shell-embedded .de-gallery:has(.de-gallery-empty) { + align-content: center; +} + +.de-shell-embedded .de-card { + grid-template-rows: 170px 18px; + border-color: color-mix(in srgb, var(--de-border) 72%, transparent); + background: var(--de-surface); + box-shadow: 0 1px 2px rgba(15, 23, 42, 0.04); } .de-gallery-empty { @@ -710,8 +857,59 @@ label { line-height: 1.6; } -.de-shell-embedded .de-card { - grid-template-rows: 170px 18px; +.de-shell-embedded .de-gallery-empty { + grid-column: 1 / -1; + display: grid; + justify-items: center; + place-self: center; + position: relative; + gap: 14px; + width: min(560px, calc(100% - 64px)); + padding: 78px 44px 54px; + border: 0; + background: transparent; + box-shadow: none; +} + +.de-shell-embedded .de-gallery-empty::before { + content: ""; + width: 120px; + height: 84px; + border: 0; + border-radius: 18px; + background: + linear-gradient(180deg, color-mix(in srgb, var(--de-accent) 72%, #ffffff) 0%, color-mix(in srgb, var(--de-accent) 42%, #ffffff) 100%); + box-shadow: + inset 0 12px 0 color-mix(in srgb, var(--de-accent) 52%, #ffffff), + 0 18px 34px color-mix(in srgb, var(--de-accent) 22%, transparent); + clip-path: polygon(0 24%, 38% 24%, 46% 8%, 100% 8%, 100% 100%, 0 100%); +} + +.de-shell-embedded .de-gallery-empty::after { + content: ""; + width: 260px; + height: 46px; + margin-top: -24px; + border-radius: 50%; + background: + radial-gradient(circle, color-mix(in srgb, var(--de-accent) 18%, transparent) 0 2px, transparent 3px) 30px 8px / 48px 24px, + radial-gradient(ellipse at center, color-mix(in srgb, var(--de-accent) 16%, transparent), transparent 70%); + order: 1; +} + +.de-shell-embedded .de-gallery-empty strong { + order: 2; + margin-bottom: 0; + color: var(--de-text); + font-size: 24px; + letter-spacing: 0; +} + +.de-shell-embedded .de-gallery-empty span { + order: 3; + max-width: 300px; + font-size: 14px; + color: var(--de-muted); } .de-shell-embedded .de-card img { @@ -719,7 +917,53 @@ label { } .de-shell-embedded .de-preview { - min-height: 220px; + min-height: 230px; + border-style: dashed; + background: + radial-gradient(circle at 50% 42%, color-mix(in srgb, var(--de-accent) 20%, transparent) 0 6px, transparent 7px), + linear-gradient(135deg, transparent 48%, color-mix(in srgb, var(--de-accent) 12%, transparent) 49% 55%, transparent 56%), + var(--de-surface-muted); +} + +.de-shell-embedded .de-preview span { + display: grid; + justify-items: center; + gap: 8px; + color: var(--de-text); + font-weight: 700; +} + +.de-shell-embedded .de-preview span::before { + content: ""; + width: 54px; + height: 38px; + border-radius: 6px; + background: + linear-gradient(135deg, transparent 48%, color-mix(in srgb, var(--de-accent) 20%, transparent) 49%), + color-mix(in srgb, var(--de-accent) 12%, var(--de-surface)); + clip-path: polygon(12% 82%, 42% 38%, 58% 62%, 70% 28%, 92% 82%); +} + +.de-shell-embedded .de-selected { + min-height: 28px; + padding: 0 2px; +} + +.de-shell-embedded .de-editor textarea { + min-height: 170px; + border-color: color-mix(in srgb, var(--de-border) 80%, transparent); + background: color-mix(in srgb, var(--de-surface) 92%, var(--de-bg)); + font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; + font-size: 12px; +} + +.de-shell-embedded .de-editor .de-primary { + flex: 1.35; +} + +.de-shell-embedded .de-change-list { + max-height: 220px; + padding-top: 4px; } .de-shell-embedded .de-actions { @@ -731,6 +975,10 @@ label { grid-template-columns: 300px minmax(420px, 1fr); } + .de-shell-embedded .de-gallery-wrap { + min-height: min(560px, calc(100vh - 26px)); + } + .de-shell-embedded .de-editor { grid-column: 1 / -1; min-height: 320px; @@ -768,4 +1016,5 @@ label { .de-shell-embedded .de-editor { grid-column: 1 / -1; } + } diff --git a/frontend/dist/assets/dataset-editor.js b/frontend/dist/assets/dataset-editor.js index bb145af1..ea93b17c 100644 --- a/frontend/dist/assets/dataset-editor.js +++ b/frontend/dist/assets/dataset-editor.js @@ -93,6 +93,20 @@ cleanEscape: document.getElementById("clean-escape"), cleanSort: document.getElementById("clean-sort"), cleanup: document.getElementById("apply-cleanup"), + taggerProvider: document.getElementById("tagger-provider"), + taggerCaptionType: document.getElementById("tagger-caption-type"), + taggerConflict: document.getElementById("tagger-conflict"), + taggerModel: document.getElementById("tagger-model"), + taggerThreshold: document.getElementById("tagger-threshold"), + taggerCharacterThreshold: document.getElementById("tagger-character-threshold"), + taggerAdditional: document.getElementById("tagger-additional"), + taggerExclude: document.getElementById("tagger-exclude"), + taggerApiHint: document.getElementById("tagger-api-hint"), + taggerRating: document.getElementById("tagger-rating"), + taggerModelTag: document.getElementById("tagger-model-tag"), + taggerReplaceUnderscore: document.getElementById("tagger-replace-underscore"), + taggerEscape: document.getElementById("tagger-escape"), + taggerRun: document.getElementById("run-tagger"), }; function loadQuickTags() { @@ -111,6 +125,14 @@ return [12, 15, 20, 24, 30, 48].includes(value) ? value : DEFAULT_GALLERY_PAGE_SIZE; } + function loadUiConfigs() { + try { + return JSON.parse(localStorage.getItem("ui-configs") || "{}") || {}; + } catch (_err) { + return {}; + } + } + function effectiveGalleryPageSize() { return state.galleryPageSize === "auto" ? state.autoGalleryPageSize : Number(state.galleryPageSize); } @@ -417,6 +439,7 @@ el.prev.disabled = state.selected <= 0; el.next.disabled = state.selected < 0 || state.selected >= state.filtered.length - 1; el.batch.disabled = state.filtered.length === 0; + if (el.taggerRun) el.taggerRun.disabled = state.filtered.length === 0; if (!item) { el.preview.innerHTML = "未选择图片"; @@ -723,6 +746,68 @@ } } + function updateTaggerProvider() { + const apiMode = el.taggerProvider.value === "api"; + el.taggerApiHint.hidden = !apiMode; + el.taggerCaptionType.value = apiMode ? "caption" : "tags"; + } + + async function applyTagger() { + const targets = selectedBatchItems(); + if (!targets.length) return; + const provider = el.taggerProvider.value; + const uiConfigs = loadUiConfigs(); + const scope = state.selectedPaths.size ? "已选中" : "当前筛选结果中"; + const providerLabel = provider === "api" ? "API 自然语言" : "本地 TAG"; + const ok = window.confirm(`将使用${providerLabel}为${scope}的 ${targets.length} 张图片打标,是否继续?`); + if (!ok) return; + if ( + provider === "api" && + (!String(uiConfigs.dataset_tagger_api_key || "").trim() || + !String(uiConfigs.dataset_tagger_api_model || "").trim()) + ) { + setStatus("API 打标需要先在 UI 设置里填写 API Key 和模型。", true); + return; + } + el.taggerRun.disabled = true; + setStatus(`正在打标 ${targets.length} 张图片...`); + try { + const data = await api("/api/dataset-editor/tag", { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ + root: state.root, + images: targets.map((item) => item.relative_path), + provider, + caption_type: el.taggerCaptionType.value, + on_conflict: el.taggerConflict.value, + interrogator_model: el.taggerModel.value, + threshold: Number(el.taggerThreshold.value || 0.35), + character_threshold: Number(el.taggerCharacterThreshold.value || 0.6), + add_rating_tag: el.taggerRating.checked, + add_model_tag: el.taggerModelTag.checked, + additional_tags: el.taggerAdditional.value, + exclude_tags: el.taggerExclude.value, + replace_underscore: el.taggerReplaceUnderscore.checked, + escape_tag: el.taggerEscape.checked, + api_endpoint: uiConfigs.dataset_tagger_api_endpoint || "https://api.openai.com/v1", + api_key: uiConfigs.dataset_tagger_api_key || "", + api_model: uiConfigs.dataset_tagger_api_model || "", + api_prompt: uiConfigs.dataset_tagger_api_prompt || undefined, + }), + }); + applyChangedItems(data.items || []); + state.dirty = false; + setStatus(`打标完成,修改 ${data.changed || 0} 张,跳过 ${data.skipped || 0} 张。`); + await refreshHistory(); + applyFilters(); + } catch (err) { + setStatus(err.message, true); + } finally { + el.taggerRun.disabled = state.filtered.length === 0; + } + } + function appendTagToCaption(tag) { const item = currentItem(); if (!item) return; @@ -799,6 +884,8 @@ el.next.addEventListener("click", () => selectIndex(state.selected + 1)); el.batch.addEventListener("click", applyBatch); el.cleanup.addEventListener("click", applyCleanup); + el.taggerProvider.addEventListener("change", updateTaggerProvider); + el.taggerRun.addEventListener("click", applyTagger); el.quickTagAdd.addEventListener("click", addQuickTag); el.quickTagInput.addEventListener("keydown", (event) => { if (event.key === "Enter") { @@ -821,6 +908,7 @@ }); renderCategories(); + updateTaggerProvider(); updateAutoGalleryPageSize(); render(); })(); diff --git a/frontend/dist/assets/sd-nav-i18n.js b/frontend/dist/assets/sd-nav-i18n.js index fae52293..5c40baeb 100644 --- a/frontend/dist/assets/sd-nav-i18n.js +++ b/frontend/dist/assets/sd-nav-i18n.js @@ -1,4 +1,4 @@ -/** +/** * Sidebar / home hub locale labels when UI is English (en-US). * Schema forms use vue-i18n; VuePress sidebar SSR text stays Chinese without this patch. */ @@ -12,6 +12,8 @@ 全量微调: "Full Finetune", 工具与调试: "Tools", 数据集打标: "Dataset Tagging", + 经典标签编辑: "Legacy Tag Editor", + 原生标签编辑: "Native Tag Editor", 标签编辑: "Tag Editor", "LoRA 脚本工具": "LoRA Scripts", 帮助: "Help", @@ -81,7 +83,6 @@ if (i18nLoc) return i18nLoc.toLowerCase().startsWith("en"); const htmlLang = (document.documentElement.lang || "").toLowerCase(); - if (htmlLang.startsWith("en")) return true; if (htmlLang.startsWith("zh")) return false; const trainSpan = document.querySelector( @@ -91,7 +92,7 @@ if (/^start\s*training$/i.test(trainText)) return true; if (trainText.includes("开始训练")) return false; - return true; + return false; } function setNodeText(node, text) { @@ -153,6 +154,20 @@ } } + function ensureStableSidebarState() { + const sidebar = document.querySelector(".sidebar .sidebar-items"); + if (!sidebar) return; + const groups = Array.from(sidebar.children || []); + for (const li of groups) { + const heading = normalize(li.querySelector(":scope > p.sidebar-item.sidebar-heading")?.textContent); + if (heading !== "训练" && heading !== "Training") continue; + const ul = li.querySelector(":scope > ul.sidebar-item-children"); + if (!ul) continue; + ul.style.display = ""; + li.dataset.sdForceExpanded = "1"; + } + } + function hookLanguageToggle() { const bottom = document.querySelector(".sidebar-bottom"); if (!bottom || bottom.dataset.sdNavI18nHooked) return; @@ -179,12 +194,14 @@ scheduled = setTimeout(() => { scheduled = null; applyNavLocale(); + ensureStableSidebarState(); hookLanguageToggle(); }, 60); } function boot() { applyNavLocale(); + ensureStableSidebarState(); hookLanguageToggle(); const root = document.querySelector("#app"); @@ -204,3 +221,5 @@ boot(); } })(); + + diff --git a/frontend/dist/assets/settings.html.06993f96.js b/frontend/dist/assets/settings.html.06993f96.js index 6e867ca0..f7b88f22 100644 --- a/frontend/dist/assets/settings.html.06993f96.js +++ b/frontend/dist/assets/settings.html.06993f96.js @@ -1 +1 @@ -const e=JSON.parse(`{"key":"v-72e1da3e","path":"/other/settings.html","title":"\u8BAD\u7EC3 UI \u8BBE\u7F6E","lang":"en-US","frontmatter":{"type":"settings","code":"Schema.intersect([\\n Schema.object({\\n tensorboard_url: Schema.string().role('folder').description(\\"tensorboard \u5730\u5740\\")\\n }).description(\\"\u8BAD\u7EC3 UI \u8BBE\u7F6E\\"),\\n]);\\n"},"excerpt":"","headers":[],"filePathRelative":"other/settings.md"}`);export{e as data}; +const e=JSON.parse(`{"key":"v-72e1da3e","path":"/other/settings.html","title":"\u8BAD\u7EC3 UI \u8BBE\u7F6E","lang":"en-US","frontmatter":{"type":"settings","code":"Schema.intersect([\\n Schema.object({\\n tensorboard_url: Schema.string().role('folder').description(\\"tensorboard \u5730\u5740\\"),\\n dataset_tagger_api_endpoint: Schema.string().default(\\"https://api.openai.com/v1\\").description(\\"标签编辑器 API 打标地址\\"),\\n dataset_tagger_api_key: Schema.string().description(\\"标签编辑器 API Key\\"),\\n dataset_tagger_api_model: Schema.string().description(\\"标签编辑器 API 模型\\"),\\n dataset_tagger_api_prompt: Schema.string().role('textarea', { rows: 4 }).default(\\"Describe this image for image model training. Return a concise caption only, without markdown or explanations.\\").description(\\"标签编辑器 API 提示词\\")\\n }).description(\\"\u8BAD\u7EC3 UI \u8BBE\u7F6E\\"),\\n]);\\n"},"excerpt":"","headers":[],"filePathRelative":"other/settings.md"}`);export{e as data}; diff --git a/frontend/dist/dataset-editor.html b/frontend/dist/dataset-editor.html index c18111d0..520cde3a 100644 --- a/frontend/dist/dataset-editor.html +++ b/frontend/dist/dataset-editor.html @@ -99,8 +99,71 @@

批量编辑

批量打标

-

预留位置:后续接入现有数据集打标能力,只作用于当前范围。

- +
+
+ + +
+
+ + +
+
+ + +
+
+ +
+ + +
+ + + + +
+
+ +
+ + + + +
+ + + +
+ + + + +
+ +
diff --git a/frontend/dist/dreambooth/index.html b/frontend/dist/dreambooth/index.html index 20dcc2ec..97d1ac54 100644 --- a/frontend/dist/dreambooth/index.html +++ b/frontend/dist/dreambooth/index.html @@ -1,4 +1,4 @@ - + @@ -36,3 +36,5 @@ + + diff --git a/frontend/dist/help/guide.html b/frontend/dist/help/guide.html index 016dff2f..6d719b7c 100644 --- a/frontend/dist/help/guide.html +++ b/frontend/dist/help/guide.html @@ -1,4 +1,4 @@ - + @@ -36,3 +36,5 @@ + + diff --git a/frontend/dist/index.html b/frontend/dist/index.html index efe7d9ea..01a086a2 100644 --- a/frontend/dist/index.html +++ b/frontend/dist/index.html @@ -1,4 +1,4 @@ - + @@ -26,13 +26,16 @@ } Next Trainer | SD 训练 UI - + -

Next Trainer

lora-scripts-next · 下一代 图像生成模型 训练

Author wochenlongopen in new window Github lora-scriptsopen in new window

GitHub Repo starsGitHub forkslicenserelease

lora-scripts-next(Next Trainer)是基于秋叶 lora-scripts下一代 Stable Diffusion 训练 WebUI:在浏览器里配参数、一键开训。

LoRA 训练

全量微调

训练监控

详细步骤见 帮助 → 新手上路;秋叶用户迁移说明也在该页。参数释义 · 训练参数说明 · 更新日志

+

Next Trainer

lora-scripts-next · 下一代 图像生成模型 训练

Author wochenlongopen in new window Github lora-scriptsopen in new window

GitHub Repo starsGitHub forkslicenserelease

lora-scripts-next(Next Trainer)是基于秋叶 lora-scripts下一代 Stable Diffusion 训练 WebUI:在浏览器里配参数、一键开训。

LoRA 训练

全量微调

训练监控

详细步骤见 帮助 → 新手上路;秋叶用户迁移说明也在该页。参数释义 · 训练参数说明 · 更新日志

- + + + + diff --git a/frontend/dist/lora/anima-finetune.html b/frontend/dist/lora/anima-finetune.html index 0935daa5..f9c19e5c 100644 --- a/frontend/dist/lora/anima-finetune.html +++ b/frontend/dist/lora/anima-finetune.html @@ -1,4 +1,4 @@ - + @@ -36,3 +36,5 @@ + + diff --git a/frontend/dist/lora/basic.html b/frontend/dist/lora/basic.html index c97cdad5..b851259f 100644 --- a/frontend/dist/lora/basic.html +++ b/frontend/dist/lora/basic.html @@ -1,4 +1,4 @@ - + @@ -36,3 +36,5 @@ + + diff --git a/frontend/dist/lora/flux.html b/frontend/dist/lora/flux.html index dc474413..e9d95e7b 100644 --- a/frontend/dist/lora/flux.html +++ b/frontend/dist/lora/flux.html @@ -1,4 +1,4 @@ - + @@ -36,3 +36,5 @@ + + diff --git a/frontend/dist/lora/index.html b/frontend/dist/lora/index.html index 777af749..ba127ec9 100644 --- a/frontend/dist/lora/index.html +++ b/frontend/dist/lora/index.html @@ -1,4 +1,4 @@ - + @@ -36,3 +36,5 @@ + + diff --git a/frontend/dist/lora/master.html b/frontend/dist/lora/master.html index b66f7544..9191725f 100644 --- a/frontend/dist/lora/master.html +++ b/frontend/dist/lora/master.html @@ -1,4 +1,4 @@ - + @@ -36,3 +36,5 @@ + + diff --git a/frontend/dist/lora/params.html b/frontend/dist/lora/params.html index 31fdd309..507be10e 100644 --- a/frontend/dist/lora/params.html +++ b/frontend/dist/lora/params.html @@ -1,4 +1,4 @@ - + @@ -36,3 +36,5 @@ + + diff --git a/frontend/dist/lora/sd3.html b/frontend/dist/lora/sd3.html index 8bd8f4bd..f2cde7cc 100644 --- a/frontend/dist/lora/sd3.html +++ b/frontend/dist/lora/sd3.html @@ -1,4 +1,4 @@ - + @@ -36,3 +36,5 @@ + + diff --git a/frontend/dist/lora/sdxl.html b/frontend/dist/lora/sdxl.html index 6fd8981a..9145c88f 100644 --- a/frontend/dist/lora/sdxl.html +++ b/frontend/dist/lora/sdxl.html @@ -1,4 +1,4 @@ - + @@ -36,3 +36,5 @@ + + diff --git a/frontend/dist/lora/tools.html b/frontend/dist/lora/tools.html index 414a7ee5..0e009140 100644 --- a/frontend/dist/lora/tools.html +++ b/frontend/dist/lora/tools.html @@ -1,4 +1,4 @@ - + @@ -37,3 +37,5 @@ + + diff --git a/frontend/dist/native-tageditor.html b/frontend/dist/native-tageditor.html new file mode 100644 index 00000000..d686b6d5 --- /dev/null +++ b/frontend/dist/native-tageditor.html @@ -0,0 +1,43 @@ + + + + + + + + + + + + SD 训练 UI + + + + + + + + + + + + + + + diff --git a/frontend/dist/other/about.html b/frontend/dist/other/about.html index 146b5c3d..673ff516 100644 --- a/frontend/dist/other/about.html +++ b/frontend/dist/other/about.html @@ -1,4 +1,4 @@ - + @@ -36,3 +36,5 @@ + + diff --git a/frontend/dist/other/changelog.html b/frontend/dist/other/changelog.html index a204f7e1..6bb44690 100644 --- a/frontend/dist/other/changelog.html +++ b/frontend/dist/other/changelog.html @@ -1,4 +1,4 @@ - + @@ -36,3 +36,5 @@ + + diff --git a/frontend/dist/other/settings.html b/frontend/dist/other/settings.html index 55ac4efb..5c29b3a0 100644 --- a/frontend/dist/other/settings.html +++ b/frontend/dist/other/settings.html @@ -1,4 +1,4 @@ - + @@ -25,15 +25,15 @@ document.documentElement.classList.toggle('dark', true); } - 训练 UI 设置 | SD 训练 UI - + 璁粌 UI 璁剧疆 | SD 璁粌 UI + -

训练 UI 设置

tensorboard_url

tensorboard 地址

-

训练 UI 设置

不懂的不要碰这个

Output
{ }
+

璁粌 UI 璁剧疆

tensorboard_url

tensorboard 鍦板潃

+

璁粌 UI 璁剧疆

涓嶆噦鐨勪笉瑕佺杩欎釜

Output
{ }
- + diff --git a/frontend/dist/tageditor.html b/frontend/dist/tageditor.html index 2d242c5a..0b186d30 100644 --- a/frontend/dist/tageditor.html +++ b/frontend/dist/tageditor.html @@ -1,4 +1,4 @@ - + @@ -26,16 +26,15 @@ } SD 训练 UI - + - - - + - - + + + diff --git a/frontend/dist/tagger.html b/frontend/dist/tagger.html index 1df63324..404f1911 100644 --- a/frontend/dist/tagger.html +++ b/frontend/dist/tagger.html @@ -1,4 +1,4 @@ - + @@ -37,3 +37,5 @@ + + diff --git a/frontend/dist/task.html b/frontend/dist/task.html index 61e4a4a7..e4ea3be7 100644 --- a/frontend/dist/task.html +++ b/frontend/dist/task.html @@ -1,4 +1,4 @@ - + @@ -36,3 +36,5 @@ + + diff --git a/frontend/dist/tensorboard.html b/frontend/dist/tensorboard.html index 6e757864..fff6824e 100644 --- a/frontend/dist/tensorboard.html +++ b/frontend/dist/tensorboard.html @@ -1,4 +1,4 @@ - + @@ -36,3 +36,5 @@ + + diff --git a/install-cn.ps1 b/install-cn.ps1 index ed67782b..0cd25941 100644 --- a/install-cn.ps1 +++ b/install-cn.ps1 @@ -1,4 +1,5 @@ $Env:HF_HOME = "huggingface" +$Env:MIKAZUKI_TAGGER_MODELS_DIR = "tagger-models" $Env:PIP_DISABLE_PIP_VERSION_CHECK = 1 $Env:PIP_NO_CACHE_DIR = 1 $Env:PIP_INDEX_URL = "https://pypi.tuna.tsinghua.edu.cn/simple" @@ -177,7 +178,7 @@ python -m pip install --upgrade -r requirements.txt Check "训练依赖库安装失败。" Write-Output "预下载默认 WD 打标模型 wd14-convnextv2-v2(约 388MB,首次较慢)..." -python scripts/prefetch_default_tagger.py --if-missing +python scripts/prefetch_default_tagger.py --if-missing --tagger-models-dir "$Env:MIKAZUKI_TAGGER_MODELS_DIR" if ($LASTEXITCODE -ne 0) { Write-Output "警告: 默认打标模型预下载失败,可在启动后于「打标」页首次使用时自动下载。" } diff --git a/mikazuki/app/application.py b/mikazuki/app/application.py index c2fd8284..371110fe 100644 --- a/mikazuki/app/application.py +++ b/mikazuki/app/application.py @@ -158,6 +158,9 @@ async def add_cache_control_header(request, call_next): path.endswith(".html") or path.endswith("/assets/tagger-progress.js") or path.endswith("/assets/sd-trainer-brand.js") + or path.endswith("/assets/sd-nav-i18n.js") + or path.endswith("/assets/app.547295de.js") + or path.endswith("/assets/style.874872ce.css") or path.endswith("/assets/dataset-editor.js") or path.endswith("/assets/dataset-editor.css") or path.endswith("/assets/dataset-editor-entry.js") diff --git a/mikazuki/dataset_editor.py b/mikazuki/dataset_editor.py index 945f80ab..7fff685e 100644 --- a/mikazuki/dataset_editor.py +++ b/mikazuki/dataset_editor.py @@ -5,11 +5,21 @@ from pathlib import Path from urllib.parse import urlencode +import base64 +import copy +import mimetypes +import time + +import httpx from fastapi import APIRouter, HTTPException from fastapi.responses import FileResponse +from PIL import Image from pydantic import BaseModel, Field from mikazuki.app.models import APIResponseSuccess +from mikazuki.tagger.interrogator import available_interrogators +from mikazuki.tagger.interrogators.base import Interrogator +from mikazuki.tagger.model_fetch import ensure_interrogator_assets, use_download_endpoint IMAGE_EXTENSIONS = {".png", ".jpg", ".jpeg", ".webp", ".bmp"} @@ -60,6 +70,31 @@ class BatchEditRequest(BaseModel): strip_escape_chars: bool = False +class DatasetTagRequest(BaseModel): + root: str + images: list[str] + provider: str = Field(default="local", pattern="^(local|api)$") + caption_type: str = Field(default="tags", pattern="^(tags|caption)$") + on_conflict: str = Field(default="copy", pattern="^(ignore|copy|append|prepend)$") + interrogator_model: str = "wd14-convnextv2-v2" + threshold: float = Field(default=0.35, ge=0, le=1) + character_threshold: float = Field(default=0.6, ge=0, le=1) + add_rating_tag: bool = False + add_model_tag: bool = False + additional_tags: str = "" + exclude_tags: str = "" + replace_underscore: bool = True + escape_tag: bool = True + download_endpoint: str = "" + api_endpoint: str = "https://api.openai.com/v1" + api_key: str = "" + api_model: str = "" + api_prompt: str = ( + "Describe this image for image model training. Return a concise caption only, " + "without markdown or explanations." + ) + + class UndoRequest(BaseModel): root: str @@ -111,6 +146,16 @@ def format_tags(tags: list[str]) -> str: return ", ".join(tags) +def merge_caption(existing: str, generated: str, on_conflict: str) -> str | None: + if existing and on_conflict == "ignore": + return None + if not existing or on_conflict == "copy": + return generated.strip() + if on_conflict == "prepend": + return format_tags(parse_tags(f"{generated}, {existing}")) + return format_tags(parse_tags(f"{existing}, {generated}")) + + def dataset_root(path: str) -> Path: root = Path(path).expanduser().resolve() if not root.is_dir(): @@ -212,6 +257,99 @@ def write_caption(image_path: Path, caption: str) -> str: return normalized +def image_to_data_url(image_path: Path) -> str: + mime_type, _ = mimetypes.guess_type(str(image_path)) + if not mime_type: + mime_type = "image/png" + encoded = base64.b64encode(image_path.read_bytes()).decode("ascii") + return f"data:{mime_type};base64,{encoded}" + + +def build_chat_completions_url(endpoint: str) -> str: + endpoint = endpoint.rstrip("/") + if endpoint.endswith("/chat/completions"): + return endpoint + return f"{endpoint}/chat/completions" + + +def parse_api_caption(data: dict) -> str: + try: + content = data["choices"][0]["message"]["content"] + except (KeyError, IndexError, TypeError) as exc: + raise ValueError("API response does not contain choices[0].message.content") from exc + if isinstance(content, str): + caption = content.strip() + elif isinstance(content, list): + caption = " ".join( + str(item.get("text", "")).strip() + for item in content + if isinstance(item, dict) and item.get("type") in {None, "text", "output_text"} + ).strip() + else: + caption = "" + if not caption: + raise ValueError("API caption is empty") + return caption + + +def generate_api_caption(image_path: Path, req: DatasetTagRequest) -> str: + if not req.api_key.strip(): + raise HTTPException(status_code=400, detail="api_key is required for API tagging") + if not req.api_model.strip(): + raise HTTPException(status_code=400, detail="api_model is required for API tagging") + payload = { + "model": req.api_model, + "messages": [ + { + "role": "user", + "content": [ + {"type": "text", "text": req.api_prompt}, + {"type": "image_url", "image_url": {"url": image_to_data_url(image_path)}}, + ], + } + ], + } + headers = {"Authorization": f"Bearer {req.api_key}"} + last_error: Exception | None = None + for attempt in range(3): + try: + with httpx.Client(timeout=60) as client: + response = client.post(build_chat_completions_url(req.api_endpoint), headers=headers, json=payload) + response.raise_for_status() + return parse_api_caption(response.json()) + except Exception as exc: # noqa: BLE001 - surface provider failures to UI + last_error = exc + if attempt >= 2: + break + time.sleep(min(2**attempt, 5)) + raise RuntimeError(f"API tagging failed for {image_path.name}: {last_error}") from last_error + + +def generate_local_tags(image_path: Path, req: DatasetTagRequest) -> str: + if req.interrogator_model not in available_interrogators: + raise HTTPException(status_code=400, detail=f"unknown tagger model: {req.interrogator_model}") + interrogator = available_interrogators[req.interrogator_model] + with use_download_endpoint(req.download_endpoint): + ensure_interrogator_assets(req.interrogator_model, interrogator) + with Image.open(image_path) as image: + tags = interrogator.interrogate(image) + processed = Interrogator.postprocess_tags( + copy.deepcopy(tags), + req.threshold, + req.character_threshold, + req.add_rating_tag, + req.add_model_tag, + parse_tags(req.additional_tags), + parse_tags(req.exclude_tags), + False, + False, + req.replace_underscore, + [], + req.escape_tag, + ) + return format_tags(list(processed.keys())) + + def scan_dataset(root: Path) -> dict: items = [] tag_counts: Counter[str] = Counter() @@ -338,6 +476,57 @@ async def batch_edit(req: BatchEditRequest): return APIResponseSuccess(data={"changed": changed, "items": results}) +@router.post("/dataset-editor/tag") +async def tag_images(req: DatasetTagRequest): + root = dataset_root(req.root) + changed = 0 + skipped = 0 + failed = 0 + results = [] + before_snapshots = [] + after_snapshots = [] + + for rel in req.images: + image_path = resolve_image(root, rel) + if not image_path.is_file(): + continue + existing = read_caption(image_path) + if existing and req.on_conflict == "ignore": + skipped += 1 + results.append(snapshot_to_item(capture_caption(root, image_path))) + continue + try: + generated = ( + generate_api_caption(image_path, req) + if req.provider == "api" + else generate_local_tags(image_path, req) + ) + generated = format_tags(parse_tags(f"{generated}, {req.additional_tags}")) + generated = format_tags([tag for tag in parse_tags(generated) if tag not in set(parse_tags(req.exclude_tags))]) + next_caption = merge_caption(existing, generated, req.on_conflict) + if next_caption is None: + skipped += 1 + continue + if next_caption != existing: + before_snapshots.append(capture_caption(root, image_path)) + write_caption(image_path, next_caption) + after_snapshots.append(capture_caption(root, image_path)) + changed += 1 + results.append(snapshot_to_item(capture_caption(root, image_path))) + except Exception: + failed += 1 + raise + + label_provider = "API " if req.provider == "api" else "本地" + label_kind = "自然语言" if req.caption_type == "caption" else "标签" + remember_edit(root, f"{label_provider}{label_kind}打标", before_snapshots, after_snapshots) + if req.provider == "local" and req.interrogator_model in available_interrogators: + available_interrogators[req.interrogator_model].unload() + return APIResponseSuccess( + data={"changed": changed, "skipped": skipped, "failed": failed, "items": results} + ) + + @router.post("/dataset-editor/undo") async def undo(req: UndoRequest): root = dataset_root(req.root) diff --git a/mikazuki/tagger/interrogators/cl.py b/mikazuki/tagger/interrogators/cl.py index 31eebd38..8f6c8737 100644 --- a/mikazuki/tagger/interrogators/cl.py +++ b/mikazuki/tagger/interrogators/cl.py @@ -14,6 +14,7 @@ from dataclasses import dataclass from mikazuki.tagger import dbimutils, format from mikazuki.tagger.interrogators.base import Interrogator +from mikazuki.tagger.local_models import local_model_asset_paths @dataclass @@ -139,6 +140,11 @@ def __init__( self.kwargs = kwargs def download(self) -> Tuple[os.PathLike, os.PathLike]: + local_paths = local_model_asset_paths(self.name, self) + if local_paths: + print(f"Loading {self.name} model from local tagger-models directory") + return local_paths + print(f"Loading {self.name} model file from {self.kwargs['repo_id']}") model_path = Path(hf_hub_download( @@ -265,4 +271,4 @@ def stable_sigmoid(x): # output_text = ", ".join(output_tags) print(predictions) - return predictions \ No newline at end of file + return predictions diff --git a/mikazuki/tagger/interrogators/wd14.py b/mikazuki/tagger/interrogators/wd14.py index 38e8a016..34487860 100644 --- a/mikazuki/tagger/interrogators/wd14.py +++ b/mikazuki/tagger/interrogators/wd14.py @@ -14,6 +14,7 @@ from huggingface_hub import hf_hub_download from mikazuki.tagger.interrogators.base import Interrogator from mikazuki.tagger import dbimutils, format +from mikazuki.tagger.local_models import local_model_asset_paths class WaifuDiffusionInterrogator(Interrogator): @@ -30,6 +31,11 @@ def __init__( self.kwargs = kwargs def download(self) -> Tuple[os.PathLike, os.PathLike]: + local_paths = local_model_asset_paths(self.name, self) + if local_paths: + print(f"Loading {self.name} model from local tagger-models directory") + return local_paths + repo_id = self.kwargs["repo_id"] print(f"Loading {self.name} model from {repo_id} (first run may download ~400MB, see console log)") diff --git a/mikazuki/tagger/jobs.py b/mikazuki/tagger/jobs.py index 34d77300..0123a370 100644 --- a/mikazuki/tagger/jobs.py +++ b/mikazuki/tagger/jobs.py @@ -24,7 +24,7 @@ def run_prefetch_job(req) -> None: try: with use_download_endpoint(getattr(req, "download_endpoint", "")): - if interrogator_assets_ready(interrogator): + if interrogator_assets_ready(interrogator, model_key): tagger_progress.finish_download_success(f"模型 {model_key} 已在本地") return download_interrogator_assets(model_key, interrogator, continue_to_tagging=False) @@ -43,7 +43,7 @@ def run_interrogate_job(req) -> None: model_key, available_interrogators["wd14-convnextv2-v2"] ) - needs_download = not interrogator_assets_ready(interrogator) + needs_download = not interrogator_assets_ready(interrogator, model_key) initial_phase = "downloading" if needs_download else "tagging" initial_message = ( "正在下载模型,完成后自动开始打标…" diff --git a/mikazuki/tagger/local_models.py b/mikazuki/tagger/local_models.py new file mode 100644 index 00000000..db09fdcd --- /dev/null +++ b/mikazuki/tagger/local_models.py @@ -0,0 +1,61 @@ +"""Project-owned local storage for tagger model assets.""" + +from __future__ import annotations + +import os +from pathlib import Path +from typing import TYPE_CHECKING + +if TYPE_CHECKING: + from mikazuki.tagger.interrogators.base import Interrogator + + +TAGGER_MODELS_DIR_ENV = "MIKAZUKI_TAGGER_MODELS_DIR" +DEFAULT_TAGGER_MODELS_DIR = "tagger-models" +WD14_MODEL_FAMILY = "wd14" +VLM_MODEL_FAMILY = "vlm" + + +def local_models_root() -> Path: + configured = os.environ.get(TAGGER_MODELS_DIR_ENV) + if configured: + return Path(configured).expanduser().resolve() + return (Path.cwd() / DEFAULT_TAGGER_MODELS_DIR).resolve() + + +def local_model_dir(model_key: str) -> Path: + return local_models_root() / local_model_family(model_key) / model_key + + +def legacy_local_model_dir(model_key: str) -> Path: + return local_models_root() / model_key + + +def local_model_family(model_key: str) -> str: + if model_key.startswith("wd") or model_key.startswith("cl_tagger"): + return WD14_MODEL_FAMILY + return VLM_MODEL_FAMILY + + +def asset_filenames(interrogator: "Interrogator") -> list[str]: + files: list[str] = [] + for attr in ("model_path", "tags_path", "tag_mapping_path"): + value = getattr(interrogator, attr, None) + if value: + files.append(str(value).replace("\\", "/")) + return files + + +def local_model_asset_paths( + model_key: str, + interrogator: "Interrogator", +) -> tuple[Path, ...] | None: + files = asset_filenames(interrogator) + if not files: + return None + + for model_dir in (local_model_dir(model_key), legacy_local_model_dir(model_key)): + paths = tuple(model_dir / filename for filename in files) + if all(path.is_file() for path in paths): + return paths + return None diff --git a/mikazuki/tagger/model_fetch.py b/mikazuki/tagger/model_fetch.py index c76ae7bf..59e826b5 100644 --- a/mikazuki/tagger/model_fetch.py +++ b/mikazuki/tagger/model_fetch.py @@ -9,6 +9,7 @@ from huggingface_hub import hf_hub_download, try_to_load_from_cache +from mikazuki.tagger.local_models import asset_filenames, local_model_asset_paths from mikazuki.tagger.progress import TaggerCancelled, tagger_progress if TYPE_CHECKING: @@ -16,17 +17,7 @@ def _asset_filenames(interrogator: "Interrogator") -> list[str]: - model_path = getattr(interrogator, "model_path", None) - tags_path = getattr(interrogator, "tags_path", None) - mapping_path = getattr(interrogator, "tag_mapping_path", None) - files: list[str] = [] - if model_path: - files.append(str(model_path)) - if tags_path: - files.append(str(tags_path)) - if mapping_path: - files.append(str(mapping_path)) - return files + return asset_filenames(interrogator) def _hf_kwargs(interrogator: "Interrogator") -> dict: @@ -53,8 +44,10 @@ def _file_cached(kwargs: dict, filename: str) -> bool: return False -def interrogator_assets_ready(interrogator: "Interrogator") -> bool: +def interrogator_assets_ready(interrogator: "Interrogator", model_key: str | None = None) -> bool: """Return True when all HF files for this interrogator are already in the local cache.""" + if model_key and local_model_asset_paths(model_key, interrogator): + return True kwargs = _hf_kwargs(interrogator) files = _asset_filenames(interrogator) if not files: @@ -166,7 +159,7 @@ def ensure_interrogator_assets(model_key: str, interrogator: "Interrogator") -> Returns True if a download was performed (caller should expect brief load after). """ - if interrogator_assets_ready(interrogator): + if interrogator_assets_ready(interrogator, model_key): return False download_interrogator_assets(model_key, interrogator, continue_to_tagging=True) return True diff --git a/scripts/portable/README.md b/scripts/portable/README.md index 543d4081..8b658d1f 100644 --- a/scripts/portable/README.md +++ b/scripts/portable/README.md @@ -36,4 +36,16 @@ | Python | `python_embeded` | 系统 / `venv` | | 入口 | `run_gui.bat` → `launch_portable.bat` | `run_gui.bat` → `run_gui_source.bat` | | 首次依赖 | `setup_environment.py` | `install-cn.ps1` | -| 默认打标模型 | 7z 内置 `huggingface/hub/`(wd14-convnextv2-v2) | `install-cn.ps1` + 每次启动 `prefetch_default_tagger.py --if-missing` | +| 默认打标模型 | 7z 内置 `tagger-models/wd14/wd14-convnextv2-v2/`,并保留 `huggingface/` 缓存兜底 | `install-cn.ps1` + 每次启动 `prefetch_default_tagger.py --if-missing` | + +## 打标模型目录 + +整合包根目录包含 `tagger-models/`,用于放置用户可见的本地打标模型。默认 WD 模型位置: + +```text +/tagger-models/wd14/wd14-convnextv2-v2/ + model.onnx + selected_tags.csv +``` + +WD14 / CL 系列放在 `tagger-models/wd14//`,主要用于 tag 打标。VLM / 自然语言描述模型预留 `tagger-models/vlm//`。旧的一层目录 `tagger-models//` 仍兼容;文件缺失时会继续使用 `huggingface/` 缓存或在线下载。 diff --git a/scripts/portable/launch_portable.bat b/scripts/portable/launch_portable.bat index e879514d..7e798d2a 100644 --- a/scripts/portable/launch_portable.bat +++ b/scripts/portable/launch_portable.bat @@ -11,6 +11,7 @@ title SD-Trainer set "PORTABLE_ROOT=%~dp0..\..\..\" set "BASE_DIR=%PORTABLE_ROOT%" set "HF_HOME=%PORTABLE_ROOT%huggingface" +set "MIKAZUKI_TAGGER_MODELS_DIR=%PORTABLE_ROOT%tagger-models" if not defined HF_ENDPOINT set "HF_ENDPOINT=https://hf-mirror.com" set "PYTHONUTF8=1" set "PYTHON_EXE=%PORTABLE_ROOT%python_embeded\python.exe" @@ -61,7 +62,7 @@ if errorlevel 1 goto :no_project if exist "scripts\prefetch_default_tagger.py" ( echo [tagger] Ensuring default WD tagger cache >> "%LOG_FILE%" - "%PYTHON_EXE%" -s scripts\prefetch_default_tagger.py --if-missing >> "%LOG_FILE%" 2>&1 + "%PYTHON_EXE%" -s scripts\prefetch_default_tagger.py --if-missing --tagger-models-dir "%MIKAZUKI_TAGGER_MODELS_DIR%" >> "%LOG_FILE%" 2>&1 ) echo [launch] Starting gui.py >> "%LOG_FILE%" diff --git a/scripts/prefetch_default_tagger.py b/scripts/prefetch_default_tagger.py index e2786082..9417d1fc 100644 --- a/scripts/prefetch_default_tagger.py +++ b/scripts/prefetch_default_tagger.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -"""Download the default WD tagger into HF_HOME cache (source install + portable build).""" +"""Download the default WD tagger into HF cache and the visible tagger-models folder.""" from __future__ import annotations @@ -18,6 +18,10 @@ DEFAULT_TAGGER_REPO_ID, DEFAULT_TAGGER_REVISION, ) +from mikazuki.tagger.local_models import ( # noqa: E402 + DEFAULT_TAGGER_MODELS_DIR, + local_model_family, +) def _resolve_hf_home(explicit: str | None) -> Path: @@ -29,6 +33,23 @@ def _resolve_hf_home(explicit: str | None) -> Path: return (REPO_ROOT / "huggingface").resolve() +def _resolve_tagger_models_dir(explicit: str | None) -> Path: + if explicit: + return Path(explicit).resolve() + return (REPO_ROOT / DEFAULT_TAGGER_MODELS_DIR).resolve() + + +def _default_local_model_dir(tagger_models_dir: Path) -> Path: + return tagger_models_dir / local_model_family(DEFAULT_TAGGER_KEY) / DEFAULT_TAGGER_KEY + + +def is_default_tagger_in_local_dir(tagger_models_dir: Path | None = None) -> bool: + model_dir = _default_local_model_dir( + _resolve_tagger_models_dir(str(tagger_models_dir) if tagger_models_dir else None) + ) + return all((model_dir / filename).is_file() for filename in DEFAULT_TAGGER_FILES) + + def is_default_tagger_cached(hf_home: Path | None = None) -> bool: hf_home = _resolve_hf_home(str(hf_home) if hf_home else None) os.environ["HF_HOME"] = str(hf_home) @@ -53,20 +74,28 @@ def is_default_tagger_cached(hf_home: Path | None = None) -> bool: def ensure_default_tagger_model( hf_home: Path | None = None, *, + tagger_models_dir: Path | None = None, use_china_mirror: bool = True, force: bool = False, ) -> Path: hf_home = _resolve_hf_home(str(hf_home) if hf_home else None) + tagger_models_dir = _resolve_tagger_models_dir( + str(tagger_models_dir) if tagger_models_dir else None + ) hf_home.mkdir(parents=True, exist_ok=True) + model_dir = _default_local_model_dir(tagger_models_dir) + model_dir.mkdir(parents=True, exist_ok=True) os.environ["HF_HOME"] = str(hf_home) + os.environ["MIKAZUKI_TAGGER_MODELS_DIR"] = str(tagger_models_dir) if use_china_mirror and not os.environ.get("HF_ENDPOINT"): os.environ["HF_ENDPOINT"] = "https://hf-mirror.com" - if not force and is_default_tagger_cached(hf_home): + local_ready = is_default_tagger_in_local_dir(tagger_models_dir) + if not force and local_ready: print(f"[tagger] Default model already present ({DEFAULT_TAGGER_KEY})") - print(f" cache: {hf_home / 'hub'}") - return hf_home + print(f" local: {model_dir}") + return model_dir try: from huggingface_hub import hf_hub_download @@ -78,6 +107,7 @@ def ensure_default_tagger_model( print(f"[tagger] Downloading default WD tagger: {DEFAULT_TAGGER_REPO_ID}") print(f" revision={DEFAULT_TAGGER_REVISION} (~388 MB, please wait)") print(f" HF_HOME={hf_home}") + print(f" local={model_dir}") if os.environ.get("HF_ENDPOINT"): print(f" HF_ENDPOINT={os.environ['HF_ENDPOINT']}") @@ -89,9 +119,14 @@ def ensure_default_tagger_model( revision=DEFAULT_TAGGER_REVISION, ) print(f"[tagger] -> {path}") + target = model_dir / filename + target.parent.mkdir(parents=True, exist_ok=True) + if force or not target.is_file(): + target.write_bytes(Path(path).read_bytes()) + print(f"[tagger] local copy -> {target}") print(f"[tagger] Done. WebUI tagging can use '{DEFAULT_TAGGER_KEY}' offline.") - return hf_home + return model_dir def main() -> int: @@ -100,6 +135,10 @@ def main() -> int: "--hf-home", help="HF cache root (default: ./huggingface or HF_HOME env)", ) + parser.add_argument( + "--tagger-models-dir", + help=f"Visible tagger model root (default: ./{DEFAULT_TAGGER_MODELS_DIR})", + ) parser.add_argument( "--if-missing", action="store_true", @@ -118,12 +157,14 @@ def main() -> int: args = parser.parse_args() hf_home = _resolve_hf_home(args.hf_home) + tagger_models_dir = _resolve_tagger_models_dir(args.tagger_models_dir) - if args.if_missing and is_default_tagger_cached(hf_home) and not args.force: + if args.if_missing and is_default_tagger_in_local_dir(tagger_models_dir) and not args.force: return 0 ensure_default_tagger_model( hf_home, + tagger_models_dir=tagger_models_dir, use_china_mirror=not args.no_mirror, force=args.force, ) diff --git a/tests/test_dataset_editor_api.py b/tests/test_dataset_editor_api.py index 3433e10e..42420ea5 100644 --- a/tests/test_dataset_editor_api.py +++ b/tests/test_dataset_editor_api.py @@ -1,3 +1,5 @@ +import json +import re from pathlib import Path from fastapi.testclient import TestClient @@ -289,18 +291,114 @@ def test_dataset_editor_html_is_served_from_main_webui(): assert ".*?)`\),x0=", app_bundle).group("json") + ) + sidebar_text = json.dumps(theme["sidebar"], ensure_ascii=False) + assert "经典标签编辑" in sidebar_text + assert "原生标签编辑" in sidebar_text + assert '经典标签编辑: "Legacy Tag Editor"' in nav + assert '原生标签编辑: "Native Tag Editor"' in nav + assert 'a[href="/dataset-editor.html"]' not in nav + assert 'window.location.assign("/dataset-editor.html")' not in nav + + +def test_vuepress_theme_sidebar_json_stays_parseable(): + app_bundle = (ROOT / "frontend" / "dist" / "assets" / "app.547295de.js").read_text( + encoding="utf-8" + ) + match = re.search(r"const WE=JSON\.parse\(`(?P.*?)`\),x0=", app_bundle) + + assert match is not None + theme = json.loads(match.group("json")) + sidebar_text = json.dumps(theme["sidebar"], ensure_ascii=False) + assert "\u8bad\u7ec3" in sidebar_text + assert "\u5de5\u5177\u4e0e\u8c03\u8bd5" in sidebar_text + assert "\u6570\u636e\u96c6\u6253\u6807" in sidebar_text + assert "经典标签编辑" in sidebar_text + assert "原生标签编辑" in sidebar_text + assert "LoRA \u811a\u672c\u5de5\u5177" in sidebar_text + assert "\u5e2e\u52a9" in sidebar_text + assert "\u5176\u4ed6" in sidebar_text + assert "/native-tageditor.html" in sidebar_text + + +def test_nav_i18n_defaults_to_chinese_and_expands_training_group(): + nav = (ROOT / "frontend" / "dist" / "assets" / "sd-nav-i18n.js").read_text( + encoding="utf-8" + ) + + assert 'return false;' in nav + assert "ensureStableSidebarState" in nav + assert "训练" in nav + assert 'ul.style.display = ""' in nav + assert 'li.dataset.sdForceExpanded = "1"' in nav + + +def test_patched_frontend_core_assets_are_not_immutable_cached(): + client = TestClient(app) + + for path in ( + "/assets/sd-nav-i18n.js", + "/assets/app.547295de.js", + "/assets/style.874872ce.css", + ): + response = client.get(path) + assert response.status_code == 200 + assert response.headers["cache-control"] == "no-cache, must-revalidate" -def test_tageditor_embeds_native_editor_in_trainer_shell(): +def test_embedded_native_editor_assets_keep_trainer_shell_contract(): script = (ROOT / "frontend" / "dist" / "assets" / "dataset-editor-entry.js").read_text( encoding="utf-8" ) @@ -317,6 +415,8 @@ def test_tageditor_embeds_native_editor_in_trainer_shell(): assert "grid-template-rows: 1fr" in css assert ".de-shell-embedded .de-workspace" in css assert "height: 100%" in css + assert "startAfterShellSettles" in script + assert "window.setTimeout(scheduleMount, 500)" in script assert "grid-template-columns: 320px minmax(520px, 1fr) 380px" in css assert ".de-gallery-empty" in css assert "@media (max-width: 1500px)" in css @@ -448,6 +548,42 @@ def test_embedded_dataset_editor_compacts_toolbar_on_narrow_viewports(): assert "flex-wrap: wrap" in css +def test_embedded_dataset_editor_uses_native_workbench_visual_system(): + css = (ROOT / "frontend" / "dist" / "assets" / "dataset-editor.css").read_text( + encoding="utf-8" + ) + + assert ".de-shell-embedded .de-gallery-wrap" in css + assert "linear-gradient(180deg, var(--de-surface) 0%, var(--de-surface-muted) 100%)" in css + assert "min-height: calc(100vh - 26px)" in css + assert ".de-shell-embedded .de-gallery-empty::before" in css + assert "grid-column: 1 / -1" in css + assert ".de-shell-embedded .de-gallery:has(.de-gallery-empty)" in css + assert "align-content: center" in css + assert "content: \"\";" in css + assert ".de-shell-embedded .de-editor textarea" in css + assert "font-family: ui-monospace" in css + assert ".de-shell-embedded .de-editor .de-primary" in css + assert ".de-shell-embedded .de-change-list" in css + assert "--de-card-shadow" in css + assert ".de-shell-embedded .de-gallery-empty::after" in css + assert ".de-shell-embedded .de-preview span::before" in css + assert ".de-shell-embedded .de-panel h2::before" in css + + +def test_embedded_dataset_editor_keeps_side_panels_content_sized(): + css = (ROOT / "frontend" / "dist" / "assets" / "dataset-editor.css").read_text( + encoding="utf-8" + ) + + assert ".de-shell-embedded .de-workspace" in css + assert "align-items: start" in css + assert ".de-shell-embedded .de-filter" in css + assert ".de-shell-embedded .de-editor" in css + assert "align-self: start" in css + assert "max-height: calc(100vh - 26px)" in css + + def test_dataset_editor_dataset_picker_is_prominent(): html = (ROOT / "frontend" / "dist" / "dataset-editor.html").read_text(encoding="utf-8") css = (ROOT / "frontend" / "dist" / "assets" / "dataset-editor.css").read_text( @@ -489,3 +625,132 @@ def test_dataset_editor_left_sidebar_owns_dataset_scope_and_tagger(): assert "tagger: document.getElementById" in script assert ".de-scope-card" in css assert "grid-template-columns: repeat(5, 1fr)" in css + + +def test_dataset_editor_tagger_panel_exposes_local_and_api_caption_controls(): + html = (ROOT / "frontend" / "dist" / "dataset-editor.html").read_text(encoding="utf-8") + script = (ROOT / "frontend" / "dist" / "assets" / "dataset-editor.js").read_text( + encoding="utf-8" + ) + entry = (ROOT / "frontend" / "dist" / "assets" / "dataset-editor-entry.js").read_text( + encoding="utf-8" + ) + css = (ROOT / "frontend" / "dist" / "assets" / "dataset-editor.css").read_text( + encoding="utf-8" + ) + + assert 'id="tagger-provider"' in html + assert 'id="tagger-caption-type"' in html + assert 'id="tagger-conflict"' in html + assert 'id="tagger-model"' in html + assert 'class="de-tagger-card de-tagger-card--primary"' in html + assert 'class="de-tagger-row de-tagger-row--split"' in html + assert 'class="de-tagger-model-card"' in html + assert 'class="de-tagger-flags"' in html + assert 'id="tagger-api-endpoint"' not in html + assert 'id="tagger-api-key"' not in html + assert 'id="tagger-api-model"' not in html + assert 'id="tagger-api-prompt"' not in html + assert 'id="run-tagger"' in html + assert 'id="tagger-provider"' in entry + assert 'class="de-tagger-card de-tagger-card--primary"' in entry + assert 'class="de-tagger-model-card"' in entry + assert 'id="tagger-api-endpoint"' not in entry + assert 'id="tagger-api-key"' not in entry + assert 'id="tagger-api-model"' not in entry + assert 'id="tagger-api-prompt"' not in entry + assert 'id="run-tagger"' in entry + assert "/api/dataset-editor/tag" in script + assert "applyTagger" in script + assert "taggerProvider" in script + assert "tagger-caption-type" in script + assert "loadUiConfigs" in script + assert "dataset_tagger_api_endpoint" in script + assert "dataset_tagger_api_key" in script + assert "dataset_tagger_api_model" in script + assert "dataset_tagger_api_prompt" in script + assert ".de-tagger-grid" in css + assert ".de-tagger-card--primary" in css + assert ".de-tagger-row--split" in css + assert ".de-tagger-model-card" in css + assert ".de-tagger-flags" in css + + +def test_ui_settings_exposes_dataset_tagger_api_config(): + settings = (ROOT / "frontend" / "dist" / "assets" / "settings.html.06993f96.js").read_text( + encoding="utf-8" + ) + app_js = (ROOT / "frontend" / "dist" / "assets" / "app.547295de.js").read_text(encoding="utf-8") + settings_html = (ROOT / "frontend" / "dist" / "other" / "settings.html").read_text( + encoding="utf-8" + ) + + assert "dataset_tagger_api_endpoint" in settings + assert "dataset_tagger_api_key" in settings + assert "dataset_tagger_api_model" in settings + assert "dataset_tagger_api_prompt" in settings + assert "./settings.html.06993f96.js?v=dataset-tagger-api" in app_js + assert "/assets/app.547295de.js?v=dataset-tagger-api" in settings_html + + +def test_dataset_editor_tag_endpoint_writes_local_tags_and_api_caption(tmp_path, monkeypatch): + make_image(tmp_path / "alpha.png") + make_image(tmp_path / "beta.png") + (tmp_path / "alpha.txt").write_text("old tag", encoding="utf-8") + + from mikazuki import dataset_editor + + def fake_local_tags(_image_path, _req): + return "blue hair, smile" + + def fake_api_caption(_image_path, req): + assert req.api_key == "secret" + assert req.api_model == "vision-model" + return "a natural language caption" + + monkeypatch.setattr(dataset_editor, "generate_local_tags", fake_local_tags) + monkeypatch.setattr(dataset_editor, "generate_api_caption", fake_api_caption) + + client = TestClient(app) + local = client.post( + "/api/dataset-editor/tag", + json={ + "root": str(tmp_path), + "images": ["alpha.png", "beta.png"], + "provider": "local", + "caption_type": "tags", + "on_conflict": "append", + "additional_tags": "best quality", + }, + ) + + assert local.status_code == 200 + assert local.json()["status"] == "success" + assert local.json()["data"]["changed"] == 2 + assert (tmp_path / "alpha.txt").read_text(encoding="utf-8") == ( + "old tag, blue hair, smile, best quality" + ) + assert (tmp_path / "beta.txt").read_text(encoding="utf-8") == "blue hair, smile, best quality" + + api = client.post( + "/api/dataset-editor/tag", + json={ + "root": str(tmp_path), + "images": ["alpha.png"], + "provider": "api", + "caption_type": "caption", + "on_conflict": "copy", + "api_endpoint": "https://example.test/v1", + "api_key": "secret", + "api_model": "vision-model", + }, + ) + + assert api.status_code == 200 + assert api.json()["status"] == "success" + assert (tmp_path / "alpha.txt").read_text(encoding="utf-8") == "a natural language caption" + + history = client.post("/api/dataset-editor/history", json={"root": str(tmp_path)}) + labels = [change["label"] for change in history.json()["data"]["changes"]] + assert labels[:2] == ["API 自然语言打标", "本地标签打标"] + diff --git a/tests/test_portable_packaging_scripts.py b/tests/test_portable_packaging_scripts.py index c6c2d809..d8a6bca0 100644 --- a/tests/test_portable_packaging_scripts.py +++ b/tests/test_portable_packaging_scripts.py @@ -40,3 +40,18 @@ def test_portable_launcher_keeps_default_hf_mirror_for_skip_prepare_mode(): assert "HF_ENDPOINT" in launcher assert "https://hf-mirror.com" in launcher + + +def test_portable_builder_bundles_visible_tagger_models_directory(): + script = (ROOT / "build-scripts" / "build_portable.ps1").read_text( + encoding="utf-8" + ) + launcher = (ROOT / "scripts" / "portable" / "launch_portable.bat").read_text( + encoding="utf-8" + ) + + assert "tagger-models" in script + assert "tagger-models\\wd14" in script + assert "tagger-models\\vlm" in script + assert "--tagger-models-dir" in script + assert "MIKAZUKI_TAGGER_MODELS_DIR" in launcher diff --git a/tests/test_tagger_progress_api.py b/tests/test_tagger_progress_api.py index 54a50a94..0af290a4 100644 --- a/tests/test_tagger_progress_api.py +++ b/tests/test_tagger_progress_api.py @@ -5,6 +5,11 @@ from mikazuki.app.application import app from mikazuki.tagger.model_fetch import use_download_endpoint from mikazuki.tagger.progress import tagger_progress +from mikazuki.tagger.interrogators.wd14 import WaifuDiffusionInterrogator +from mikazuki.tagger.local_models import ( + local_model_asset_paths, + local_model_dir, +) def test_tagger_status_idle(): @@ -43,3 +48,53 @@ def test_tagger_default_download_endpoint_preserves_existing_hf_endpoint(monkeyp assert os.environ["HF_ENDPOINT"] == "https://hf-mirror.com" assert os.environ["HF_ENDPOINT"] == "https://hf-mirror.com" + + +def test_tagger_local_model_directory_resolves_by_model_key(tmp_path, monkeypatch): + monkeypatch.setenv("MIKAZUKI_TAGGER_MODELS_DIR", str(tmp_path / "tagger-models")) + + expected = tmp_path / "tagger-models" / "wd14" / "wd14-convnextv2-v2" + + assert local_model_dir("wd14-convnextv2-v2") == expected + + +def test_tagger_assets_ready_when_files_exist_in_wd14_local_model_dir(tmp_path, monkeypatch): + monkeypatch.setenv("MIKAZUKI_TAGGER_MODELS_DIR", str(tmp_path / "tagger-models")) + model_dir = tmp_path / "tagger-models" / "wd14" / "wd14-convnextv2-v2" + model_dir.mkdir(parents=True) + (model_dir / "model.onnx").write_bytes(b"fake onnx") + (model_dir / "selected_tags.csv").write_text("name,category\n", encoding="utf-8") + + interrogator = WaifuDiffusionInterrogator( + "wd14-convnextv2-v2", + repo_id="SmilingWolf/wd-v1-4-convnextv2-tagger-v2", + revision="v2.0", + ) + + assert local_model_asset_paths("wd14-convnextv2-v2", interrogator) == ( + model_dir / "model.onnx", + model_dir / "selected_tags.csv", + ) + assert interrogator.download() == ( + model_dir / "model.onnx", + model_dir / "selected_tags.csv", + ) + + +def test_tagger_assets_keep_legacy_flat_local_model_dir_compatible(tmp_path, monkeypatch): + monkeypatch.setenv("MIKAZUKI_TAGGER_MODELS_DIR", str(tmp_path / "tagger-models")) + model_dir = tmp_path / "tagger-models" / "wd14-convnextv2-v2" + model_dir.mkdir(parents=True) + (model_dir / "model.onnx").write_bytes(b"fake onnx") + (model_dir / "selected_tags.csv").write_text("name,category\n", encoding="utf-8") + + interrogator = WaifuDiffusionInterrogator( + "wd14-convnextv2-v2", + repo_id="SmilingWolf/wd-v1-4-convnextv2-tagger-v2", + revision="v2.0", + ) + + assert local_model_asset_paths("wd14-convnextv2-v2", interrogator) == ( + model_dir / "model.onnx", + model_dir / "selected_tags.csv", + ) From d996dff84bb549db28d9f16caa542628b810b0dd Mon Sep 17 00:00:00 2001 From: wochenlong Date: Sat, 30 May 2026 01:39:18 +0800 Subject: [PATCH 3/8] fix(editor): register native tag editor as dedicated VuePress page Co-authored-by: Cursor --- frontend/dist/assets/app.547295de.js | 3 +- .../assets/native-tageditor.html.native.js | 1 + frontend/dist/assets/sd-nav-i18n.js | 205 +++++++++++++++++- .../dist/assets/settings.html.06993f96.js | 2 +- frontend/dist/native-tageditor.html | 3 +- frontend/dist/other/settings.html | 6 +- mikazuki/app/application.py | 1 + tests/test_dataset_editor_api.py | 68 ++++++ 8 files changed, 282 insertions(+), 7 deletions(-) create mode 100644 frontend/dist/assets/native-tageditor.html.native.js diff --git a/frontend/dist/assets/app.547295de.js b/frontend/dist/assets/app.547295de.js index a5522ea7..c2d1af1e 100644 --- a/frontend/dist/assets/app.547295de.js +++ b/frontend/dist/assets/app.547295de.js @@ -1,4 +1,4 @@ -var m2=Object.defineProperty;var h2=(e,t,n)=>t in e?m2(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n;var Hp=(e,t,n)=>(h2(e,typeof t!="symbol"?t+"":t,n),n);const zp={};const v2="modulepreload",jp={},g2="/",wt=function(t,n){return!n||n.length===0?t():Promise.all(n.map(r=>{if(r=`${g2}${r}`,r in jp)return;jp[r]=!0;const o=r.endsWith(".css"),a=o?'[rel="stylesheet"]':"";if(document.querySelector(`link[href="${r}"]${a}`))return;const l=document.createElement("link");if(l.rel=o?"stylesheet":v2,o||(l.as="script",l.crossOrigin=""),l.href=r,document.head.appendChild(l),o)return new Promise((s,i)=>{l.addEventListener("load",s),l.addEventListener("error",()=>i(new Error(`Unable to preload CSS for ${r}`)))})})).then(()=>t())},b2={"v-8daa1a0e":()=>wt(()=>import("./index.html.ec4ace46.js"),[]).then(({data:e})=>e),"v-6983ba2a":()=>wt(()=>import("./tageditor.html.66da263e.js"),[]).then(({data:e})=>e),"v-native-tageditor":()=>wt(()=>import("./tageditor.html.66da263e.js"),[]).then(({data:e})=>e),"v-51615306":()=>wt(()=>import("./tagger.html.66f12b92.js"),[]).then(({data:e})=>e),"v-06850b9b":()=>wt(()=>import("./task.html.4e4c8633.js"),[]).then(({data:e})=>e),"v-13efe3c5":()=>wt(()=>import("./tensorboard.html.4a2799a9.js"),[]).then(({data:e})=>e),"v-33a23463":()=>wt(()=>import("./index.html.838bbc6c.js"),[]).then(({data:e})=>e),"v-b5471278":()=>wt(()=>import("./about.html.5b0c0de9.js"),[]).then(({data:e})=>e),"v-a1c9e4f2":()=>wt(()=>import("./changelog.html.a1b2c3d4.js"),[]).then(({data:e})=>e),"v-b8e2d701":()=>wt(()=>import("./guide.html.b8e2d701.js"),[]).then(({data:e})=>e),"v-72e1da3e":()=>wt(()=>import("./settings.html.06993f96.js?v=dataset-tagger-api"),[]).then(({data:e})=>e),"v-3e43d6e2":()=>wt(()=>import("./basic.html.48955584.js"),[]).then(({data:e})=>e),"v-fdbe4e28":()=>wt(()=>import("./flux.html.6fefc131.js"),[]).then(({data:e})=>e),"v-14e91824":()=>wt(()=>import("./index.html.b97ec799.js"),[]).then(({data:e})=>e),"v-1bf725da":()=>wt(()=>import("./master.html.54eb6415.js"),[]).then(({data:e})=>e),"v-0f9e746f":()=>wt(()=>import("./params.html.c8cc13ef.js"),[]).then(({data:e})=>e),"v-0dc76a3b":()=>wt(()=>import("./sd3.html.eaeb05e1.js"),[]).then(({data:e})=>e),"v-a1f1ne2e":()=>wt(()=>import("./anima-finetune.html.eaeb05f2.js"),[]).then(({data:e})=>e),"v-53c99f50":()=>wt(()=>import("./sdxl.html.6ab37b06.js"),[]).then(({data:e})=>e),"v-4441a302":()=>wt(()=>import("./tools.html.c0a4659a.js"),[]).then(({data:e})=>e),"v-3706649a":()=>wt(()=>import("./404.html.686caba0.js"),[]).then(({data:e})=>e)};function Jd(e,t){const n=Object.create(null),r=e.split(",");for(let o=0;o!!n[o.toLowerCase()]:o=>!!n[o]}const Ft={},Na=[],en=()=>{},y2=()=>!1,_2=/^on[^a-z]/,$s=e=>_2.test(e),Zd=e=>e.startsWith("onUpdate:"),Wt=Object.assign,Qd=(e,t)=>{const n=e.indexOf(t);n>-1&&e.splice(n,1)},w2=Object.prototype.hasOwnProperty,ft=(e,t)=>w2.call(e,t),De=Array.isArray,Da=e=>Ts(e)==="[object Map]",Su=e=>Ts(e)==="[object Set]",Yi=e=>Ts(e)==="[object Date]",Ke=e=>typeof e=="function",Ge=e=>typeof e=="string",Zl=e=>typeof e=="symbol",ht=e=>e!==null&&typeof e=="object",Gi=e=>ht(e)&&Ke(e.then)&&Ke(e.catch),Kg=Object.prototype.toString,Ts=e=>Kg.call(e),$i=e=>Ts(e).slice(8,-1),qg=e=>Ts(e)==="[object Object]",ef=e=>Ge(e)&&e!=="NaN"&&e[0]!=="-"&&""+parseInt(e,10)===e,Rl=Jd(",key,ref,ref_for,ref_key,onVnodeBeforeMount,onVnodeMounted,onVnodeBeforeUpdate,onVnodeUpdated,onVnodeBeforeUnmount,onVnodeUnmounted"),Eu=e=>{const t=Object.create(null);return n=>t[n]||(t[n]=e(n))},C2=/-(\w)/g,cr=Eu(e=>e.replace(C2,(t,n)=>n?n.toUpperCase():"")),k2=/\B([A-Z])/g,fa=Eu(e=>e.replace(k2,"-$1").toLowerCase()),$u=Eu(e=>e.charAt(0).toUpperCase()+e.slice(1)),Ti=Eu(e=>e?`on${$u(e)}`:""),Ql=(e,t)=>!Object.is(e,t),xi=(e,t)=>{for(let n=0;n{Object.defineProperty(e,t,{configurable:!0,enumerable:!1,value:n})},Vc=e=>{const t=parseFloat(e);return isNaN(t)?e:t},S2=e=>{const t=Ge(e)?Number(e):NaN;return isNaN(t)?e:t};let Wp;const Bc=()=>Wp||(Wp=typeof globalThis!="undefined"?globalThis:typeof self!="undefined"?self:typeof window!="undefined"?window:typeof global!="undefined"?global:{});function Qe(e){if(De(e)){const t={};for(let n=0;n{if(n){const r=n.split($2);r.length>1&&(t[r[0].trim()]=r[1].trim())}}),t}function D(e){let t="";if(Ge(e))t=e;else if(De(e))for(let n=0;nja(n,t))}const Ee=e=>Ge(e)?e:e==null?"":De(e)||ht(e)&&(e.toString===Kg||!Ke(e.toString))?JSON.stringify(e,Xg,2):String(e),Xg=(e,t)=>t&&t.__v_isRef?Xg(e,t.value):Da(t)?{[`Map(${t.size})`]:[...t.entries()].reduce((n,[r,o])=>(n[`${r} =>`]=o,n),{})}:Su(t)?{[`Set(${t.size})`]:[...t.values()]}:ht(t)&&!De(t)&&!qg(t)?String(t):t;let Vn;class Jg{constructor(t=!1){this.detached=t,this._active=!0,this.effects=[],this.cleanups=[],this.parent=Vn,!t&&Vn&&(this.index=(Vn.scopes||(Vn.scopes=[])).push(this)-1)}get active(){return this._active}run(t){if(this._active){const n=Vn;try{return Vn=this,t()}finally{Vn=n}}}on(){Vn=this}off(){Vn=this.parent}stop(t){if(this._active){let n,r;for(n=0,r=this.effects.length;n{const t=new Set(e);return t.w=0,t.n=0,t},eb=e=>(e.w&To)>0,tb=e=>(e.n&To)>0,R2=({deps:e})=>{if(e.length)for(let t=0;t{const{deps:t}=e;if(t.length){let n=0;for(let r=0;r{(d==="length"||d>=i)&&s.push(u)})}else switch(n!==void 0&&s.push(l.get(n)),t){case"add":De(e)?ef(n)&&s.push(l.get("length")):(s.push(l.get(na)),Da(e)&&s.push(l.get(Hc)));break;case"delete":De(e)||(s.push(l.get(na)),Da(e)&&s.push(l.get(Hc)));break;case"set":Da(e)&&s.push(l.get(na));break}if(s.length===1)s[0]&&jc(s[0]);else{const i=[];for(const u of s)u&&i.push(...u);jc(tf(i))}}function jc(e,t){const n=De(e)?e:[...e];for(const r of n)r.computed&&Kp(r);for(const r of n)r.computed||Kp(r)}function Kp(e,t){(e!==lr||e.allowRecurse)&&(e.scheduler?e.scheduler():e.run())}function D2(e,t){var n;return(n=Ji.get(e))==null?void 0:n.get(t)}const F2=Jd("__proto__,__v_isRef,__isVue"),ob=new Set(Object.getOwnPropertyNames(Symbol).filter(e=>e!=="arguments"&&e!=="caller").map(e=>Symbol[e]).filter(Zl)),V2=rf(),B2=rf(!1,!0),z2=rf(!0),qp=H2();function H2(){const e={};return["includes","indexOf","lastIndexOf"].forEach(t=>{e[t]=function(...n){const r=gt(this);for(let a=0,l=this.length;a{e[t]=function(...n){dl();const r=gt(this)[t].apply(this,n);return fl(),r}}),e}function j2(e){const t=gt(this);return Ln(t,"has",e),t.hasOwnProperty(e)}function rf(e=!1,t=!1){return function(r,o,a){if(o==="__v_isReactive")return!e;if(o==="__v_isReadonly")return e;if(o==="__v_isShallow")return t;if(o==="__v_raw"&&a===(e?t?aC:ub:t?ib:sb).get(r))return r;const l=De(r);if(!e){if(l&&ft(qp,o))return Reflect.get(qp,o,a);if(o==="hasOwnProperty")return j2}const s=Reflect.get(r,o,a);return(Zl(o)?ob.has(o):F2(o))||(e||Ln(r,"get",o),t)?s:mt(s)?l&&ef(o)?s:s.value:ht(s)?e?pa(s):Xt(s):s}}const W2=ab(),U2=ab(!0);function ab(e=!1){return function(n,r,o,a){let l=n[r];if(Wa(l)&&mt(l)&&!mt(o))return!1;if(!e&&(!Zi(o)&&!Wa(o)&&(l=gt(l),o=gt(o)),!De(n)&&mt(l)&&!mt(o)))return l.value=o,!0;const s=De(n)&&ef(r)?Number(r)e,Tu=e=>Reflect.getPrototypeOf(e);function qs(e,t,n=!1,r=!1){e=e.__v_raw;const o=gt(e),a=gt(t);n||(t!==a&&Ln(o,"get",t),Ln(o,"get",a));const{has:l}=Tu(o),s=r?of:n?uf:es;if(l.call(o,t))return s(e.get(t));if(l.call(o,a))return s(e.get(a));e!==o&&e.get(t)}function Ys(e,t=!1){const n=this.__v_raw,r=gt(n),o=gt(e);return t||(e!==o&&Ln(r,"has",e),Ln(r,"has",o)),e===o?n.has(e):n.has(e)||n.has(o)}function Gs(e,t=!1){return e=e.__v_raw,!t&&Ln(gt(e),"iterate",na),Reflect.get(e,"size",e)}function Yp(e){e=gt(e);const t=gt(this);return Tu(t).has.call(t,e)||(t.add(e),Yr(t,"add",e,e)),this}function Gp(e,t){t=gt(t);const n=gt(this),{has:r,get:o}=Tu(n);let a=r.call(n,e);a||(e=gt(e),a=r.call(n,e));const l=o.call(n,e);return n.set(e,t),a?Ql(t,l)&&Yr(n,"set",e,t):Yr(n,"add",e,t),this}function Xp(e){const t=gt(this),{has:n,get:r}=Tu(t);let o=n.call(t,e);o||(e=gt(e),o=n.call(t,e)),r&&r.call(t,e);const a=t.delete(e);return o&&Yr(t,"delete",e,void 0),a}function Jp(){const e=gt(this),t=e.size!==0,n=e.clear();return t&&Yr(e,"clear",void 0,void 0),n}function Xs(e,t){return function(r,o){const a=this,l=a.__v_raw,s=gt(l),i=t?of:e?uf:es;return!e&&Ln(s,"iterate",na),l.forEach((u,d)=>r.call(o,i(u),i(d),a))}}function Js(e,t,n){return function(...r){const o=this.__v_raw,a=gt(o),l=Da(a),s=e==="entries"||e===Symbol.iterator&&l,i=e==="keys"&&l,u=o[e](...r),d=n?of:t?uf:es;return!t&&Ln(a,"iterate",i?Hc:na),{next(){const{value:f,done:h}=u.next();return h?{value:f,done:h}:{value:s?[d(f[0]),d(f[1])]:d(f),done:h}},[Symbol.iterator](){return this}}}}function so(e){return function(...t){return e==="delete"?!1:this}}function J2(){const e={get(a){return qs(this,a)},get size(){return Gs(this)},has:Ys,add:Yp,set:Gp,delete:Xp,clear:Jp,forEach:Xs(!1,!1)},t={get(a){return qs(this,a,!1,!0)},get size(){return Gs(this)},has:Ys,add:Yp,set:Gp,delete:Xp,clear:Jp,forEach:Xs(!1,!0)},n={get(a){return qs(this,a,!0)},get size(){return Gs(this,!0)},has(a){return Ys.call(this,a,!0)},add:so("add"),set:so("set"),delete:so("delete"),clear:so("clear"),forEach:Xs(!0,!1)},r={get(a){return qs(this,a,!0,!0)},get size(){return Gs(this,!0)},has(a){return Ys.call(this,a,!0)},add:so("add"),set:so("set"),delete:so("delete"),clear:so("clear"),forEach:Xs(!0,!0)};return["keys","values","entries",Symbol.iterator].forEach(a=>{e[a]=Js(a,!1,!1),n[a]=Js(a,!0,!1),t[a]=Js(a,!1,!0),r[a]=Js(a,!0,!0)}),[e,n,t,r]}const[Z2,Q2,eC,tC]=J2();function af(e,t){const n=t?e?tC:eC:e?Q2:Z2;return(r,o,a)=>o==="__v_isReactive"?!e:o==="__v_isReadonly"?e:o==="__v_raw"?r:Reflect.get(ft(n,o)&&o in r?n:r,o,a)}const nC={get:af(!1,!1)},rC={get:af(!1,!0)},oC={get:af(!0,!1)},sb=new WeakMap,ib=new WeakMap,ub=new WeakMap,aC=new WeakMap;function lC(e){switch(e){case"Object":case"Array":return 1;case"Map":case"Set":case"WeakMap":case"WeakSet":return 2;default:return 0}}function sC(e){return e.__v_skip||!Object.isExtensible(e)?0:lC($i(e))}function Xt(e){return Wa(e)?e:sf(e,!1,lb,nC,sb)}function lf(e){return sf(e,!1,X2,rC,ib)}function pa(e){return sf(e,!0,G2,oC,ub)}function sf(e,t,n,r,o){if(!ht(e)||e.__v_raw&&!(t&&e.__v_isReactive))return e;const a=o.get(e);if(a)return a;const l=sC(e);if(l===0)return e;const s=new Proxy(e,l===2?r:n);return o.set(e,s),s}function Fa(e){return Wa(e)?Fa(e.__v_raw):!!(e&&e.__v_isReactive)}function Wa(e){return!!(e&&e.__v_isReadonly)}function Zi(e){return!!(e&&e.__v_isShallow)}function cb(e){return Fa(e)||Wa(e)}function gt(e){const t=e&&e.__v_raw;return t?gt(t):e}function db(e){return Xi(e,"__v_skip",!0),e}const es=e=>ht(e)?Xt(e):e,uf=e=>ht(e)?pa(e):e;function fb(e){So&&lr&&(e=gt(e),rb(e.dep||(e.dep=tf())))}function cf(e,t){e=gt(e);const n=e.dep;n&&jc(n)}function mt(e){return!!(e&&e.__v_isRef===!0)}function B(e){return pb(e,!1)}function On(e){return pb(e,!0)}function pb(e,t){return mt(e)?e:new iC(e,t)}class iC{constructor(t,n){this.__v_isShallow=n,this.dep=void 0,this.__v_isRef=!0,this._rawValue=n?t:gt(t),this._value=n?t:es(t)}get value(){return fb(this),this._value}set value(t){const n=this.__v_isShallow||Zi(t)||Wa(t);t=n?t:gt(t),Ql(t,this._rawValue)&&(this._rawValue=t,this._value=n?t:es(t),cf(this))}}function Cl(e){cf(e)}function c(e){return mt(e)?e.value:e}const uC={get:(e,t,n)=>c(Reflect.get(e,t,n)),set:(e,t,n,r)=>{const o=e[t];return mt(o)&&!mt(n)?(o.value=n,!0):Reflect.set(e,t,n,r)}};function mb(e){return Fa(e)?e:new Proxy(e,uC)}function dr(e){const t=De(e)?new Array(e.length):{};for(const n in e)t[n]=hb(e,n);return t}class cC{constructor(t,n,r){this._object=t,this._key=n,this._defaultValue=r,this.__v_isRef=!0}get value(){const t=this._object[this._key];return t===void 0?this._defaultValue:t}set value(t){this._object[this._key]=t}get dep(){return D2(gt(this._object),this._key)}}class dC{constructor(t){this._getter=t,this.__v_isRef=!0,this.__v_isReadonly=!0}get value(){return this._getter()}}function zt(e,t,n){return mt(e)?e:Ke(e)?new dC(e):ht(e)&&arguments.length>1?hb(e,t,n):B(e)}function hb(e,t,n){const r=e[t];return mt(r)?r:new cC(e,t,n)}class fC{constructor(t,n,r,o){this._setter=n,this.dep=void 0,this.__v_isRef=!0,this.__v_isReadonly=!1,this._dirty=!0,this.effect=new nf(t,()=>{this._dirty||(this._dirty=!0,cf(this))}),this.effect.computed=this,this.effect.active=this._cacheable=!o,this.__v_isReadonly=r}get value(){const t=gt(this);return fb(t),(t._dirty||!t._cacheable)&&(t._dirty=!1,t._value=t.effect.run()),t._value}set value(t){this._setter(t)}}function vb(e,t,n=!1){let r,o;const a=Ke(e);return a?(r=e,o=en):(r=e.get,o=e.set),new fC(r,o,a||!o,n)}function pC(e,...t){}function Eo(e,t,n,r){let o;try{o=r?e(...r):e()}catch(a){xs(a,t,n)}return o}function qn(e,t,n,r){if(Ke(e)){const a=Eo(e,t,n,r);return a&&Gi(a)&&a.catch(l=>{xs(l,t,n)}),a}const o=[];for(let a=0;a>>1;ns(pn[r])Sr&&pn.splice(t,1)}function gC(e){De(e)?Va.push(...e):(!zr||!zr.includes(e,e.allowRecurse?qo+1:qo))&&Va.push(e),bb()}function Zp(e,t=ts?Sr+1:0){for(;tns(n)-ns(r)),qo=0;qoe.id==null?1/0:e.id,bC=(e,t)=>{const n=ns(e)-ns(t);if(n===0){if(e.pre&&!t.pre)return-1;if(t.pre&&!e.pre)return 1}return n};function yb(e){Wc=!1,ts=!0,pn.sort(bC);const t=en;try{for(Sr=0;SrGe(p)?p.trim():p)),f&&(o=n.map(Vc))}let s,i=r[s=Ti(t)]||r[s=Ti(cr(t))];!i&&a&&(i=r[s=Ti(fa(t))]),i&&qn(i,e,6,o);const u=r[s+"Once"];if(u){if(!e.emitted)e.emitted={};else if(e.emitted[s])return;e.emitted[s]=!0,qn(u,e,6,o)}}function _b(e,t,n=!1){const r=t.emitsCache,o=r.get(e);if(o!==void 0)return o;const a=e.emits;let l={},s=!1;if(!Ke(e)){const i=u=>{const d=_b(u,t,!0);d&&(s=!0,Wt(l,d))};!n&&t.mixins.length&&t.mixins.forEach(i),e.extends&&i(e.extends),e.mixins&&e.mixins.forEach(i)}return!a&&!s?(ht(e)&&r.set(e,null),null):(De(a)?a.forEach(i=>l[i]=null):Wt(l,a),ht(e)&&r.set(e,l),l)}function Ou(e,t){return!e||!$s(t)?!1:(t=t.slice(2).replace(/Once$/,""),ft(e,t[0].toLowerCase()+t.slice(1))||ft(e,fa(t))||ft(e,t))}let sn=null,Au=null;function eu(e){const t=sn;return sn=e,Au=e&&e.type.__scopeId||null,t}function _C(e){Au=e}function wC(){Au=null}function G(e,t=sn,n){if(!t||e._n)return e;const r=(...o)=>{r._d&&dm(-1);const a=eu(t);let l;try{l=e(...o)}finally{eu(a),r._d&&dm(1)}return l};return r._n=!0,r._c=!0,r._d=!0,r}function ac(e){const{type:t,vnode:n,proxy:r,withProxy:o,props:a,propsOptions:[l],slots:s,attrs:i,emit:u,render:d,renderCache:f,data:h,setupState:p,ctx:v,inheritAttrs:g}=e;let w,m;const b=eu(e);try{if(n.shapeFlag&4){const y=o||r;w=or(d.call(y,y,f,a,p,h,v)),m=i}else{const y=t;w=or(y.length>1?y(a,{attrs:i,slots:s,emit:u}):y(a,null)),m=t.props?i:CC(i)}}catch(y){Vl.length=0,xs(y,e,1),w=Q(yn)}let _=w;if(m&&g!==!1){const y=Object.keys(m),{shapeFlag:C}=_;y.length&&C&7&&(l&&y.some(Zd)&&(m=kC(m,l)),_=Xr(_,m))}return n.dirs&&(_=Xr(_),_.dirs=_.dirs?_.dirs.concat(n.dirs):n.dirs),n.transition&&(_.transition=n.transition),w=_,eu(b),w}const CC=e=>{let t;for(const n in e)(n==="class"||n==="style"||$s(n))&&((t||(t={}))[n]=e[n]);return t},kC=(e,t)=>{const n={};for(const r in e)(!Zd(r)||!(r.slice(9)in t))&&(n[r]=e[r]);return n};function SC(e,t,n){const{props:r,children:o,component:a}=e,{props:l,children:s,patchFlag:i}=t,u=a.emitsOptions;if(t.dirs||t.transition)return!0;if(n&&i>=0){if(i&1024)return!0;if(i&16)return r?Qp(r,l,u):!!l;if(i&8){const d=t.dynamicProps;for(let f=0;fe.__isSuspense;function wb(e,t){t&&t.pendingBranch?De(e)?t.effects.push(...e):t.effects.push(e):gC(e)}function qr(e,t){return ff(e,null,t)}const Zs={};function $e(e,t,n){return ff(e,t,n)}function ff(e,t,{immediate:n,deep:r,flush:o,onTrack:a,onTrigger:l}=Ft){var s;const i=Zg()===((s=Zt)==null?void 0:s.scope)?Zt:null;let u,d=!1,f=!1;if(mt(e)?(u=()=>e.value,d=Zi(e)):Fa(e)?(u=()=>e,r=!0):De(e)?(f=!0,d=e.some(y=>Fa(y)||Zi(y)),u=()=>e.map(y=>{if(mt(y))return y.value;if(Fa(y))return Jo(y);if(Ke(y))return Eo(y,i,2)})):Ke(e)?t?u=()=>Eo(e,i,2):u=()=>{if(!(i&&i.isUnmounted))return h&&h(),qn(e,i,3,[p])}:u=en,t&&r){const y=u;u=()=>Jo(y())}let h,p=y=>{h=b.onStop=()=>{Eo(y,i,4)}},v;if(qa)if(p=en,t?n&&qn(t,i,3,[u(),f?[]:void 0,p]):u(),o==="sync"){const y=vk();v=y.__watcherHandles||(y.__watcherHandles=[])}else return en;let g=f?new Array(e.length).fill(Zs):Zs;const w=()=>{if(!!b.active)if(t){const y=b.run();(r||d||(f?y.some((C,k)=>Ql(C,g[k])):Ql(y,g)))&&(h&&h(),qn(t,i,3,[y,g===Zs?void 0:f&&g[0]===Zs?[]:g,p]),g=y)}else b.run()};w.allowRecurse=!!t;let m;o==="sync"?m=w:o==="post"?m=()=>Tn(w,i&&i.suspense):(w.pre=!0,i&&(w.id=i.uid),m=()=>xu(w));const b=new nf(u,m);t?n?w():g=b.run():o==="post"?Tn(b.run.bind(b),i&&i.suspense):b.run();const _=()=>{b.stop(),i&&i.scope&&Qd(i.scope.effects,b)};return v&&v.push(_),_}function TC(e,t,n){const r=this.proxy,o=Ge(e)?e.includes(".")?Cb(r,e):()=>r[e]:e.bind(r,r);let a;Ke(t)?a=t:(a=t.handler,n=t);const l=Zt;Ka(this);const s=ff(o,a.bind(r),n);return l?Ka(l):ra(),s}function Cb(e,t){const n=t.split(".");return()=>{let r=e;for(let o=0;o{Jo(n,t)});else if(qg(e))for(const n in e)Jo(e[n],t);return e}function vt(e,t){const n=sn;if(n===null)return e;const r=Mu(n)||n.proxy,o=e.dirs||(e.dirs=[]);for(let a=0;a{e.isMounted=!0}),rn(()=>{e.isUnmounting=!0}),e}const Wn=[Function,Array],Sb={mode:String,appear:Boolean,persisted:Boolean,onBeforeEnter:Wn,onEnter:Wn,onAfterEnter:Wn,onEnterCancelled:Wn,onBeforeLeave:Wn,onLeave:Wn,onAfterLeave:Wn,onLeaveCancelled:Wn,onBeforeAppear:Wn,onAppear:Wn,onAfterAppear:Wn,onAppearCancelled:Wn},xC={name:"BaseTransition",props:Sb,setup(e,{slots:t}){const n=lt(),r=kb();let o;return()=>{const a=t.default&&pf(t.default(),!0);if(!a||!a.length)return;let l=a[0];if(a.length>1){for(const g of a)if(g.type!==yn){l=g;break}}const s=gt(e),{mode:i}=s;if(r.isLeaving)return lc(l);const u=em(l);if(!u)return lc(l);const d=rs(u,s,r,n);os(u,d);const f=n.subTree,h=f&&em(f);let p=!1;const{getTransitionKey:v}=u.type;if(v){const g=v();o===void 0?o=g:g!==o&&(o=g,p=!0)}if(h&&h.type!==yn&&(!Yo(u,h)||p)){const g=rs(h,s,r,n);if(os(h,g),i==="out-in")return r.isLeaving=!0,g.afterLeave=()=>{r.isLeaving=!1,n.update.active!==!1&&n.update()},lc(l);i==="in-out"&&u.type!==yn&&(g.delayLeave=(w,m,b)=>{const _=Eb(r,h);_[String(h.key)]=h,w._leaveCb=()=>{m(),w._leaveCb=void 0,delete d.delayedLeave},d.delayedLeave=b})}return l}}},OC=xC;function Eb(e,t){const{leavingVNodes:n}=e;let r=n.get(t.type);return r||(r=Object.create(null),n.set(t.type,r)),r}function rs(e,t,n,r){const{appear:o,mode:a,persisted:l=!1,onBeforeEnter:s,onEnter:i,onAfterEnter:u,onEnterCancelled:d,onBeforeLeave:f,onLeave:h,onAfterLeave:p,onLeaveCancelled:v,onBeforeAppear:g,onAppear:w,onAfterAppear:m,onAppearCancelled:b}=t,_=String(e.key),y=Eb(n,e),C=(S,R)=>{S&&qn(S,r,9,R)},k=(S,R)=>{const L=R[1];C(S,R),De(S)?S.every(F=>F.length<=1)&&L():S.length<=1&&L()},E={mode:a,persisted:l,beforeEnter(S){let R=s;if(!n.isMounted)if(o)R=g||s;else return;S._leaveCb&&S._leaveCb(!0);const L=y[_];L&&Yo(e,L)&&L.el._leaveCb&&L.el._leaveCb(),C(R,[S])},enter(S){let R=i,L=u,F=d;if(!n.isMounted)if(o)R=w||i,L=m||u,F=b||d;else return;let N=!1;const A=S._enterCb=M=>{N||(N=!0,M?C(F,[S]):C(L,[S]),E.delayedLeave&&E.delayedLeave(),S._enterCb=void 0)};R?k(R,[S,A]):A()},leave(S,R){const L=String(e.key);if(S._enterCb&&S._enterCb(!0),n.isUnmounting)return R();C(f,[S]);let F=!1;const N=S._leaveCb=A=>{F||(F=!0,R(),A?C(v,[S]):C(p,[S]),S._leaveCb=void 0,y[L]===e&&delete y[L])};y[L]=e,h?k(h,[S,N]):N()},clone(S){return rs(S,t,n,r)}};return E}function lc(e){if(Os(e))return e=Xr(e),e.children=null,e}function em(e){return Os(e)?e.children?e.children[0]:void 0:e}function os(e,t){e.shapeFlag&6&&e.component?os(e.component.subTree,t):e.shapeFlag&128?(e.ssContent.transition=t.clone(e.ssContent),e.ssFallback.transition=t.clone(e.ssFallback)):e.transition=t}function pf(e,t=!1,n){let r=[],o=0;for(let a=0;a1)for(let a=0;aWt({name:e.name},t,{setup:e}))():e}const Ba=e=>!!e.type.__asyncLoader;function Jt(e){Ke(e)&&(e={loader:e});const{loader:t,loadingComponent:n,errorComponent:r,delay:o=200,timeout:a,suspensible:l=!0,onError:s}=e;let i=null,u,d=0;const f=()=>(d++,i=null,h()),h=()=>{let p;return i||(p=i=t().catch(v=>{if(v=v instanceof Error?v:new Error(String(v)),s)return new Promise((g,w)=>{s(v,()=>g(f()),()=>w(v),d+1)});throw v}).then(v=>p!==i&&i?i:(v&&(v.__esModule||v[Symbol.toStringTag]==="Module")&&(v=v.default),u=v,v)))};return se({name:"AsyncComponentWrapper",__asyncLoader:h,get __asyncResolved(){return u},setup(){const p=Zt;if(u)return()=>sc(u,p);const v=b=>{i=null,xs(b,p,13,!r)};if(l&&p.suspense||qa)return h().then(b=>()=>sc(b,p)).catch(b=>(v(b),()=>r?Q(r,{error:b}):null));const g=B(!1),w=B(),m=B(!!o);return o&&setTimeout(()=>{m.value=!1},o),a!=null&&setTimeout(()=>{if(!g.value&&!w.value){const b=new Error(`Async component timed out after ${a}ms.`);v(b),w.value=b}},a),h().then(()=>{g.value=!0,p.parent&&Os(p.parent.vnode)&&xu(p.parent.update)}).catch(b=>{v(b),w.value=b}),()=>{if(g.value&&u)return sc(u,p);if(w.value&&r)return Q(r,{error:w.value});if(n&&!m.value)return Q(n)}}})}function sc(e,t){const{ref:n,props:r,children:o,ce:a}=t.vnode,l=Q(e,r,o);return l.ref=n,l.ce=a,delete t.vnode.ce,l}const Os=e=>e.type.__isKeepAlive;function AC(e,t){Tb(e,"a",t)}function $b(e,t){Tb(e,"da",t)}function Tb(e,t,n=Zt){const r=e.__wdc||(e.__wdc=()=>{let o=n;for(;o;){if(o.isDeactivated)return;o=o.parent}return e()});if(Iu(t,r,n),n){let o=n.parent;for(;o&&o.parent;)Os(o.parent.vnode)&&IC(r,t,n,o),o=o.parent}}function IC(e,t,n,r){const o=Iu(t,e,r,!0);Mo(()=>{Qd(r[t],o)},n)}function Iu(e,t,n=Zt,r=!1){if(n){const o=n[e]||(n[e]=[]),a=t.__weh||(t.__weh=(...l)=>{if(n.isUnmounted)return;dl(),Ka(n);const s=qn(t,n,e,l);return ra(),fl(),s});return r?o.unshift(a):o.push(a),a}}const eo=e=>(t,n=Zt)=>(!qa||e==="sp")&&Iu(e,(...r)=>t(...r),n),As=eo("bm"),dt=eo("m"),PC=eo("bu"),pl=eo("u"),rn=eo("bum"),Mo=eo("um"),LC=eo("sp"),MC=eo("rtg"),RC=eo("rtc");function NC(e,t=Zt){Iu("ec",e,t)}const mf="components",DC="directives";function Ve(e,t){return vf(mf,e,!0,t)||e}const xb=Symbol.for("v-ndc");function Lt(e){return Ge(e)?vf(mf,e,!1)||e:e||xb}function hf(e){return vf(DC,e)}function vf(e,t,n=!0,r=!1){const o=sn||Zt;if(o){const a=o.type;if(e===mf){const s=pk(a,!1);if(s&&(s===t||s===cr(t)||s===$u(cr(t))))return a}const l=tm(o[e]||a[e],t)||tm(o.appContext[e],t);return!l&&r?a:l}}function tm(e,t){return e&&(e[t]||e[cr(t)]||e[$u(cr(t))])}function it(e,t,n,r){let o;const a=n&&n[r];if(De(e)||Ge(e)){o=new Array(e.length);for(let l=0,s=e.length;lt(l,s,void 0,a&&a[s]));else{const l=Object.keys(e);o=new Array(l.length);for(let s=0,i=l.length;s{const a=r.fn(...o);return a&&(a.key=r.key),a}:r.fn)}return e}function pe(e,t,n={},r,o){if(sn.isCE||sn.parent&&Ba(sn.parent)&&sn.parent.isCE)return t!=="default"&&(n.name=t),Q("slot",n,r&&r());let a=e[t];a&&a._c&&(a._d=!1),x();const l=a&&Ob(a(n)),s=ce(Pe,{key:n.key||l&&l.key||`_${t}`},l||(r?r():[]),l&&e._===1?64:-2);return!o&&s.scopeId&&(s.slotScopeIds=[s.scopeId+"-s"]),a&&a._c&&(a._d=!0),s}function Ob(e){return e.some(t=>Ua(t)?!(t.type===yn||t.type===Pe&&!Ob(t.children)):!0)?e:null}function FC(e,t){const n={};for(const r in e)n[t&&/[A-Z]/.test(r)?`on:${r}`:Ti(r)]=e[r];return n}const Uc=e=>e?Wb(e)?Mu(e)||e.proxy:Uc(e.parent):null,Nl=Wt(Object.create(null),{$:e=>e,$el:e=>e.vnode.el,$data:e=>e.data,$props:e=>e.props,$attrs:e=>e.attrs,$slots:e=>e.slots,$refs:e=>e.refs,$parent:e=>Uc(e.parent),$root:e=>Uc(e.root),$emit:e=>e.emit,$options:e=>gf(e),$forceUpdate:e=>e.f||(e.f=()=>xu(e.update)),$nextTick:e=>e.n||(e.n=qe.bind(e.proxy)),$watch:e=>TC.bind(e)}),ic=(e,t)=>e!==Ft&&!e.__isScriptSetup&&ft(e,t),VC={get({_:e},t){const{ctx:n,setupState:r,data:o,props:a,accessCache:l,type:s,appContext:i}=e;let u;if(t[0]!=="$"){const p=l[t];if(p!==void 0)switch(p){case 1:return r[t];case 2:return o[t];case 4:return n[t];case 3:return a[t]}else{if(ic(r,t))return l[t]=1,r[t];if(o!==Ft&&ft(o,t))return l[t]=2,o[t];if((u=e.propsOptions[0])&&ft(u,t))return l[t]=3,a[t];if(n!==Ft&&ft(n,t))return l[t]=4,n[t];Kc&&(l[t]=0)}}const d=Nl[t];let f,h;if(d)return t==="$attrs"&&Ln(e,"get",t),d(e);if((f=s.__cssModules)&&(f=f[t]))return f;if(n!==Ft&&ft(n,t))return l[t]=4,n[t];if(h=i.config.globalProperties,ft(h,t))return h[t]},set({_:e},t,n){const{data:r,setupState:o,ctx:a}=e;return ic(o,t)?(o[t]=n,!0):r!==Ft&&ft(r,t)?(r[t]=n,!0):ft(e.props,t)||t[0]==="$"&&t.slice(1)in e?!1:(a[t]=n,!0)},has({_:{data:e,setupState:t,accessCache:n,ctx:r,appContext:o,propsOptions:a}},l){let s;return!!n[l]||e!==Ft&&ft(e,l)||ic(t,l)||(s=a[0])&&ft(s,l)||ft(r,l)||ft(Nl,l)||ft(o.config.globalProperties,l)},defineProperty(e,t,n){return n.get!=null?e._.accessCache[t]=0:ft(n,"value")&&this.set(e,t,n.value,null),Reflect.defineProperty(e,t,n)}};function to(){return Ab().slots}function Pu(){return Ab().attrs}function Ab(){const e=lt();return e.setupContext||(e.setupContext=Kb(e))}function nm(e){return De(e)?e.reduce((t,n)=>(t[n]=null,t),{}):e}let Kc=!0;function BC(e){const t=gf(e),n=e.proxy,r=e.ctx;Kc=!1,t.beforeCreate&&rm(t.beforeCreate,e,"bc");const{data:o,computed:a,methods:l,watch:s,provide:i,inject:u,created:d,beforeMount:f,mounted:h,beforeUpdate:p,updated:v,activated:g,deactivated:w,beforeDestroy:m,beforeUnmount:b,destroyed:_,unmounted:y,render:C,renderTracked:k,renderTriggered:E,errorCaptured:S,serverPrefetch:R,expose:L,inheritAttrs:F,components:N,directives:A,filters:M}=t;if(u&&zC(u,r,null),l)for(const V in l){const X=l[V];Ke(X)&&(r[V]=X.bind(n))}if(o){const V=o.call(n,n);ht(V)&&(e.data=Xt(V))}if(Kc=!0,a)for(const V in a){const X=a[V],I=Ke(X)?X.bind(n,n):Ke(X.get)?X.get.bind(n,n):en,Y=!Ke(X)&&Ke(X.set)?X.set.bind(n):en,ee=O({get:I,set:Y});Object.defineProperty(r,V,{enumerable:!0,configurable:!0,get:()=>ee.value,set:W=>ee.value=W})}if(s)for(const V in s)Ib(s[V],r,n,V);if(i){const V=Ke(i)?i.call(n):i;Reflect.ownKeys(V).forEach(X=>{yt(X,V[X])})}d&&rm(d,e,"c");function j(V,X){De(X)?X.forEach(I=>V(I.bind(n))):X&&V(X.bind(n))}if(j(As,f),j(dt,h),j(PC,p),j(pl,v),j(AC,g),j($b,w),j(NC,S),j(RC,k),j(MC,E),j(rn,b),j(Mo,y),j(LC,R),De(L))if(L.length){const V=e.exposed||(e.exposed={});L.forEach(X=>{Object.defineProperty(V,X,{get:()=>n[X],set:I=>n[X]=I})})}else e.exposed||(e.exposed={});C&&e.render===en&&(e.render=C),F!=null&&(e.inheritAttrs=F),N&&(e.components=N),A&&(e.directives=A)}function zC(e,t,n=en){De(e)&&(e=qc(e));for(const r in e){const o=e[r];let a;ht(o)?"default"in o?a=Re(o.from||r,o.default,!0):a=Re(o.from||r):a=Re(o),mt(a)?Object.defineProperty(t,r,{enumerable:!0,configurable:!0,get:()=>a.value,set:l=>a.value=l}):t[r]=a}}function rm(e,t,n){qn(De(e)?e.map(r=>r.bind(t.proxy)):e.bind(t.proxy),t,n)}function Ib(e,t,n,r){const o=r.includes(".")?Cb(n,r):()=>n[r];if(Ge(e)){const a=t[e];Ke(a)&&$e(o,a)}else if(Ke(e))$e(o,e.bind(n));else if(ht(e))if(De(e))e.forEach(a=>Ib(a,t,n,r));else{const a=Ke(e.handler)?e.handler.bind(n):t[e.handler];Ke(a)&&$e(o,a,e)}}function gf(e){const t=e.type,{mixins:n,extends:r}=t,{mixins:o,optionsCache:a,config:{optionMergeStrategies:l}}=e.appContext,s=a.get(t);let i;return s?i=s:!o.length&&!n&&!r?i=t:(i={},o.length&&o.forEach(u=>tu(i,u,l,!0)),tu(i,t,l)),ht(t)&&a.set(t,i),i}function tu(e,t,n,r=!1){const{mixins:o,extends:a}=t;a&&tu(e,a,n,!0),o&&o.forEach(l=>tu(e,l,n,!0));for(const l in t)if(!(r&&l==="expose")){const s=HC[l]||n&&n[l];e[l]=s?s(e[l],t[l]):t[l]}return e}const HC={data:om,props:am,emits:am,methods:Ll,computed:Ll,beforeCreate:gn,created:gn,beforeMount:gn,mounted:gn,beforeUpdate:gn,updated:gn,beforeDestroy:gn,beforeUnmount:gn,destroyed:gn,unmounted:gn,activated:gn,deactivated:gn,errorCaptured:gn,serverPrefetch:gn,components:Ll,directives:Ll,watch:WC,provide:om,inject:jC};function om(e,t){return t?e?function(){return Wt(Ke(e)?e.call(this,this):e,Ke(t)?t.call(this,this):t)}:t:e}function jC(e,t){return Ll(qc(e),qc(t))}function qc(e){if(De(e)){const t={};for(let n=0;n1)return n&&Ke(t)?t.call(r&&r.proxy):t}}function qC(e,t,n,r=!1){const o={},a={};Xi(a,Lu,1),e.propsDefaults=Object.create(null),Lb(e,t,o,a);for(const l in e.propsOptions[0])l in o||(o[l]=void 0);n?e.props=r?o:lf(o):e.type.props?e.props=o:e.props=a,e.attrs=a}function YC(e,t,n,r){const{props:o,attrs:a,vnode:{patchFlag:l}}=e,s=gt(o),[i]=e.propsOptions;let u=!1;if((r||l>0)&&!(l&16)){if(l&8){const d=e.vnode.dynamicProps;for(let f=0;f{i=!0;const[h,p]=Mb(f,t,!0);Wt(l,h),p&&s.push(...p)};!n&&t.mixins.length&&t.mixins.forEach(d),e.extends&&d(e.extends),e.mixins&&e.mixins.forEach(d)}if(!a&&!i)return ht(e)&&r.set(e,Na),Na;if(De(a))for(let d=0;d-1,p[1]=g<0||v-1||ft(p,"default"))&&s.push(f)}}}const u=[l,s];return ht(e)&&r.set(e,u),u}function lm(e){return e[0]!=="$"}function sm(e){const t=e&&e.toString().match(/^\s*(function|class) (\w+)/);return t?t[2]:e===null?"null":""}function im(e,t){return sm(e)===sm(t)}function um(e,t){return De(t)?t.findIndex(n=>im(n,e)):Ke(t)&&im(t,e)?0:-1}const Rb=e=>e[0]==="_"||e==="$stable",bf=e=>De(e)?e.map(or):[or(e)],GC=(e,t,n)=>{if(t._n)return t;const r=G((...o)=>bf(t(...o)),n);return r._c=!1,r},Nb=(e,t,n)=>{const r=e._ctx;for(const o in e){if(Rb(o))continue;const a=e[o];if(Ke(a))t[o]=GC(o,a,r);else if(a!=null){const l=bf(a);t[o]=()=>l}}},Db=(e,t)=>{const n=bf(t);e.slots.default=()=>n},XC=(e,t)=>{if(e.vnode.shapeFlag&32){const n=t._;n?(e.slots=gt(t),Xi(t,"_",n)):Nb(t,e.slots={})}else e.slots={},t&&Db(e,t);Xi(e.slots,Lu,1)},JC=(e,t,n)=>{const{vnode:r,slots:o}=e;let a=!0,l=Ft;if(r.shapeFlag&32){const s=t._;s?n&&s===1?a=!1:(Wt(o,t),!n&&s===1&&delete o._):(a=!t.$stable,Nb(t,o)),l=t}else t&&(Db(e,t),l={default:1});if(a)for(const s in o)!Rb(s)&&!(s in l)&&delete o[s]};function ru(e,t,n,r,o=!1){if(De(e)){e.forEach((h,p)=>ru(h,t&&(De(t)?t[p]:t),n,r,o));return}if(Ba(r)&&!o)return;const a=r.shapeFlag&4?Mu(r.component)||r.component.proxy:r.el,l=o?null:a,{i:s,r:i}=e,u=t&&t.r,d=s.refs===Ft?s.refs={}:s.refs,f=s.setupState;if(u!=null&&u!==i&&(Ge(u)?(d[u]=null,ft(f,u)&&(f[u]=null)):mt(u)&&(u.value=null)),Ke(i))Eo(i,s,12,[l,d]);else{const h=Ge(i),p=mt(i);if(h||p){const v=()=>{if(e.f){const g=h?ft(f,i)?f[i]:d[i]:i.value;o?De(g)&&Qd(g,a):De(g)?g.includes(a)||g.push(a):h?(d[i]=[a],ft(f,i)&&(f[i]=d[i])):(i.value=[a],e.k&&(d[e.k]=i.value))}else h?(d[i]=l,ft(f,i)&&(f[i]=l)):p&&(i.value=l,e.k&&(d[e.k]=l))};l?(v.id=-1,Tn(v,n)):v()}}}let io=!1;const Qs=e=>/svg/.test(e.namespaceURI)&&e.tagName!=="foreignObject",ei=e=>e.nodeType===8;function ZC(e){const{mt:t,p:n,o:{patchProp:r,createText:o,nextSibling:a,parentNode:l,remove:s,insert:i,createComment:u}}=e,d=(m,b)=>{if(!b.hasChildNodes()){n(null,m,b),Qi(),b._vnode=m;return}io=!1,f(b.firstChild,m,null,null,null),Qi(),b._vnode=m,io&&console.error("Hydration completed but contains mismatches.")},f=(m,b,_,y,C,k=!1)=>{const E=ei(m)&&m.data==="[",S=()=>g(m,b,_,y,C,E),{type:R,ref:L,shapeFlag:F,patchFlag:N}=b;let A=m.nodeType;b.el=m,N===-2&&(k=!1,b.dynamicChildren=null);let M=null;switch(R){case Gr:A!==3?b.children===""?(i(b.el=o(""),l(m),m),M=m):M=S():(m.data!==b.children&&(io=!0,m.data=b.children),M=a(m));break;case yn:A!==8||E?M=S():M=a(m);break;case Fl:if(E&&(m=a(m),A=m.nodeType),A===1||A===3){M=m;const H=!b.children.length;for(let j=0;j{k=k||!!b.dynamicChildren;const{type:E,props:S,patchFlag:R,shapeFlag:L,dirs:F}=b,N=E==="input"&&F||E==="option";if(N||R!==-1){if(F&&kr(b,null,_,"created"),S)if(N||!k||R&48)for(const M in S)(N&&M.endsWith("value")||$s(M)&&!Rl(M))&&r(m,M,null,S[M],!1,void 0,_);else S.onClick&&r(m,"onClick",null,S.onClick,!1,void 0,_);let A;if((A=S&&S.onVnodeBeforeMount)&&Un(A,_,b),F&&kr(b,null,_,"beforeMount"),((A=S&&S.onVnodeMounted)||F)&&wb(()=>{A&&Un(A,_,b),F&&kr(b,null,_,"mounted")},y),L&16&&!(S&&(S.innerHTML||S.textContent))){let M=p(m.firstChild,b,m,_,y,C,k);for(;M;){io=!0;const H=M;M=M.nextSibling,s(H)}}else L&8&&m.textContent!==b.children&&(io=!0,m.textContent=b.children)}return m.nextSibling},p=(m,b,_,y,C,k,E)=>{E=E||!!b.dynamicChildren;const S=b.children,R=S.length;for(let L=0;L{const{slotScopeIds:E}=b;E&&(C=C?C.concat(E):E);const S=l(m),R=p(a(m),b,S,_,y,C,k);return R&&ei(R)&&R.data==="]"?a(b.anchor=R):(io=!0,i(b.anchor=u("]"),S,R),R)},g=(m,b,_,y,C,k)=>{if(io=!0,b.el=null,k){const R=w(m);for(;;){const L=a(m);if(L&&L!==R)s(L);else break}}const E=a(m),S=l(m);return s(m),n(null,b,S,E,_,y,Qs(S),C),E},w=m=>{let b=0;for(;m;)if(m=a(m),m&&ei(m)&&(m.data==="["&&b++,m.data==="]")){if(b===0)return a(m);b--}return m};return[d,f]}const Tn=wb;function QC(e){return Fb(e)}function ek(e){return Fb(e,ZC)}function Fb(e,t){const n=Bc();n.__VUE__=!0;const{insert:r,remove:o,patchProp:a,createElement:l,createText:s,createComment:i,setText:u,setElementText:d,parentNode:f,nextSibling:h,setScopeId:p=en,insertStaticContent:v}=e,g=(P,$,T,z=null,Z=null,oe=null,_e=!1,we=null,he=!!$.dynamicChildren)=>{if(P===$)return;P&&!Yo(P,$)&&(z=J(P),W(P,Z,oe,!0),P=null),$.patchFlag===-2&&(he=!1,$.dynamicChildren=null);const{type:ke,ref:Me,shapeFlag:ne}=$;switch(ke){case Gr:w(P,$,T,z);break;case yn:m(P,$,T,z);break;case Fl:P==null&&b($,T,z,_e);break;case Pe:N(P,$,T,z,Z,oe,_e,we,he);break;default:ne&1?C(P,$,T,z,Z,oe,_e,we,he):ne&6?A(P,$,T,z,Z,oe,_e,we,he):(ne&64||ne&128)&&ke.process(P,$,T,z,Z,oe,_e,we,he,ae)}Me!=null&&Z&&ru(Me,P&&P.ref,oe,$||P,!$)},w=(P,$,T,z)=>{if(P==null)r($.el=s($.children),T,z);else{const Z=$.el=P.el;$.children!==P.children&&u(Z,$.children)}},m=(P,$,T,z)=>{P==null?r($.el=i($.children||""),T,z):$.el=P.el},b=(P,$,T,z)=>{[P.el,P.anchor]=v(P.children,$,T,z,P.el,P.anchor)},_=({el:P,anchor:$},T,z)=>{let Z;for(;P&&P!==$;)Z=h(P),r(P,T,z),P=Z;r($,T,z)},y=({el:P,anchor:$})=>{let T;for(;P&&P!==$;)T=h(P),o(P),P=T;o($)},C=(P,$,T,z,Z,oe,_e,we,he)=>{_e=_e||$.type==="svg",P==null?k($,T,z,Z,oe,_e,we,he):R(P,$,Z,oe,_e,we,he)},k=(P,$,T,z,Z,oe,_e,we)=>{let he,ke;const{type:Me,props:ne,shapeFlag:ue,transition:ie,dirs:Oe}=P;if(he=P.el=l(P.type,oe,ne&&ne.is,ne),ue&8?d(he,P.children):ue&16&&S(P.children,he,null,z,Z,oe&&Me!=="foreignObject",_e,we),Oe&&kr(P,null,z,"created"),E(he,P,P.scopeId,_e,z),ne){for(const Xe in ne)Xe!=="value"&&!Rl(Xe)&&a(he,Xe,null,ne[Xe],oe,P.children,z,Z,ge);"value"in ne&&a(he,"value",null,ne.value),(ke=ne.onVnodeBeforeMount)&&Un(ke,z,P)}Oe&&kr(P,null,z,"beforeMount");const We=(!Z||Z&&!Z.pendingBranch)&&ie&&!ie.persisted;We&&ie.beforeEnter(he),r(he,$,T),((ke=ne&&ne.onVnodeMounted)||We||Oe)&&Tn(()=>{ke&&Un(ke,z,P),We&&ie.enter(he),Oe&&kr(P,null,z,"mounted")},Z)},E=(P,$,T,z,Z)=>{if(T&&p(P,T),z)for(let oe=0;oe{for(let ke=he;ke{const we=$.el=P.el;let{patchFlag:he,dynamicChildren:ke,dirs:Me}=$;he|=P.patchFlag&16;const ne=P.props||Ft,ue=$.props||Ft;let ie;T&&Bo(T,!1),(ie=ue.onVnodeBeforeUpdate)&&Un(ie,T,$,P),Me&&kr($,P,T,"beforeUpdate"),T&&Bo(T,!0);const Oe=Z&&$.type!=="foreignObject";if(ke?L(P.dynamicChildren,ke,we,T,z,Oe,oe):_e||X(P,$,we,null,T,z,Oe,oe,!1),he>0){if(he&16)F(we,$,ne,ue,T,z,Z);else if(he&2&&ne.class!==ue.class&&a(we,"class",null,ue.class,Z),he&4&&a(we,"style",ne.style,ue.style,Z),he&8){const We=$.dynamicProps;for(let Xe=0;Xe{ie&&Un(ie,T,$,P),Me&&kr($,P,T,"updated")},z)},L=(P,$,T,z,Z,oe,_e)=>{for(let we=0;we<$.length;we++){const he=P[we],ke=$[we],Me=he.el&&(he.type===Pe||!Yo(he,ke)||he.shapeFlag&70)?f(he.el):T;g(he,ke,Me,null,z,Z,oe,_e,!0)}},F=(P,$,T,z,Z,oe,_e)=>{if(T!==z){if(T!==Ft)for(const we in T)!Rl(we)&&!(we in z)&&a(P,we,T[we],null,_e,$.children,Z,oe,ge);for(const we in z){if(Rl(we))continue;const he=z[we],ke=T[we];he!==ke&&we!=="value"&&a(P,we,ke,he,_e,$.children,Z,oe,ge)}"value"in z&&a(P,"value",T.value,z.value)}},N=(P,$,T,z,Z,oe,_e,we,he)=>{const ke=$.el=P?P.el:s(""),Me=$.anchor=P?P.anchor:s("");let{patchFlag:ne,dynamicChildren:ue,slotScopeIds:ie}=$;ie&&(we=we?we.concat(ie):ie),P==null?(r(ke,T,z),r(Me,T,z),S($.children,T,Me,Z,oe,_e,we,he)):ne>0&&ne&64&&ue&&P.dynamicChildren?(L(P.dynamicChildren,ue,T,Z,oe,_e,we),($.key!=null||Z&&$===Z.subTree)&&yf(P,$,!0)):X(P,$,T,Me,Z,oe,_e,we,he)},A=(P,$,T,z,Z,oe,_e,we,he)=>{$.slotScopeIds=we,P==null?$.shapeFlag&512?Z.ctx.activate($,T,z,_e,he):M($,T,z,Z,oe,_e,he):H(P,$,he)},M=(P,$,T,z,Z,oe,_e)=>{const we=P.component=uk(P,z,Z);if(Os(P)&&(we.ctx.renderer=ae),ck(we),we.asyncDep){if(Z&&Z.registerDep(we,j),!P.el){const he=we.subTree=Q(yn);m(null,he,$,T)}return}j(we,P,$,T,Z,oe,_e)},H=(P,$,T)=>{const z=$.component=P.component;if(SC(P,$,T))if(z.asyncDep&&!z.asyncResolved){V(z,$,T);return}else z.next=$,vC(z.update),z.update();else $.el=P.el,z.vnode=$},j=(P,$,T,z,Z,oe,_e)=>{const we=()=>{if(P.isMounted){let{next:Me,bu:ne,u:ue,parent:ie,vnode:Oe}=P,We=Me,Xe;Bo(P,!1),Me?(Me.el=Oe.el,V(P,Me,_e)):Me=Oe,ne&&xi(ne),(Xe=Me.props&&Me.props.onVnodeBeforeUpdate)&&Un(Xe,ie,Me,Oe),Bo(P,!0);const fe=ac(P),ve=P.subTree;P.subTree=fe,g(ve,fe,f(ve.el),J(ve),P,Z,oe),Me.el=fe.el,We===null&&EC(P,fe.el),ue&&Tn(ue,Z),(Xe=Me.props&&Me.props.onVnodeUpdated)&&Tn(()=>Un(Xe,ie,Me,Oe),Z)}else{let Me;const{el:ne,props:ue}=$,{bm:ie,m:Oe,parent:We}=P,Xe=Ba($);if(Bo(P,!1),ie&&xi(ie),!Xe&&(Me=ue&&ue.onVnodeBeforeMount)&&Un(Me,We,$),Bo(P,!0),ne&&me){const fe=()=>{P.subTree=ac(P),me(ne,P.subTree,P,Z,null)};Xe?$.type.__asyncLoader().then(()=>!P.isUnmounted&&fe()):fe()}else{const fe=P.subTree=ac(P);g(null,fe,T,z,P,Z,oe),$.el=fe.el}if(Oe&&Tn(Oe,Z),!Xe&&(Me=ue&&ue.onVnodeMounted)){const fe=$;Tn(()=>Un(Me,We,fe),Z)}($.shapeFlag&256||We&&Ba(We.vnode)&&We.vnode.shapeFlag&256)&&P.a&&Tn(P.a,Z),P.isMounted=!0,$=T=z=null}},he=P.effect=new nf(we,()=>xu(ke),P.scope),ke=P.update=()=>he.run();ke.id=P.uid,Bo(P,!0),ke()},V=(P,$,T)=>{$.component=P;const z=P.vnode.props;P.vnode=$,P.next=null,YC(P,$.props,z,T),JC(P,$.children,T),dl(),Zp(),fl()},X=(P,$,T,z,Z,oe,_e,we,he=!1)=>{const ke=P&&P.children,Me=P?P.shapeFlag:0,ne=$.children,{patchFlag:ue,shapeFlag:ie}=$;if(ue>0){if(ue&128){Y(ke,ne,T,z,Z,oe,_e,we,he);return}else if(ue&256){I(ke,ne,T,z,Z,oe,_e,we,he);return}}ie&8?(Me&16&&ge(ke,Z,oe),ne!==ke&&d(T,ne)):Me&16?ie&16?Y(ke,ne,T,z,Z,oe,_e,we,he):ge(ke,Z,oe,!0):(Me&8&&d(T,""),ie&16&&S(ne,T,z,Z,oe,_e,we,he))},I=(P,$,T,z,Z,oe,_e,we,he)=>{P=P||Na,$=$||Na;const ke=P.length,Me=$.length,ne=Math.min(ke,Me);let ue;for(ue=0;ueMe?ge(P,Z,oe,!0,!1,ne):S($,T,z,Z,oe,_e,we,he,ne)},Y=(P,$,T,z,Z,oe,_e,we,he)=>{let ke=0;const Me=$.length;let ne=P.length-1,ue=Me-1;for(;ke<=ne&&ke<=ue;){const ie=P[ke],Oe=$[ke]=he?go($[ke]):or($[ke]);if(Yo(ie,Oe))g(ie,Oe,T,null,Z,oe,_e,we,he);else break;ke++}for(;ke<=ne&&ke<=ue;){const ie=P[ne],Oe=$[ue]=he?go($[ue]):or($[ue]);if(Yo(ie,Oe))g(ie,Oe,T,null,Z,oe,_e,we,he);else break;ne--,ue--}if(ke>ne){if(ke<=ue){const ie=ue+1,Oe=ieue)for(;ke<=ne;)W(P[ke],Z,oe,!0),ke++;else{const ie=ke,Oe=ke,We=new Map;for(ke=Oe;ke<=ue;ke++){const q=$[ke]=he?go($[ke]):or($[ke]);q.key!=null&&We.set(q.key,ke)}let Xe,fe=0;const ve=ue-Oe+1;let Ce=!1,Ye=0;const Se=new Array(ve);for(ke=0;ke=ve){W(q,Z,oe,!0);continue}let Ie;if(q.key!=null)Ie=We.get(q.key);else for(Xe=Oe;Xe<=ue;Xe++)if(Se[Xe-Oe]===0&&Yo(q,$[Xe])){Ie=Xe;break}Ie===void 0?W(q,Z,oe,!0):(Se[Ie-Oe]=ke+1,Ie>=Ye?Ye=Ie:Ce=!0,g(q,$[Ie],T,null,Z,oe,_e,we,he),fe++)}const Ae=Ce?tk(Se):Na;for(Xe=Ae.length-1,ke=ve-1;ke>=0;ke--){const q=Oe+ke,Ie=$[q],et=q+1{const{el:oe,type:_e,transition:we,children:he,shapeFlag:ke}=P;if(ke&6){ee(P.component.subTree,$,T,z);return}if(ke&128){P.suspense.move($,T,z);return}if(ke&64){_e.move(P,$,T,ae);return}if(_e===Pe){r(oe,$,T);for(let ne=0;newe.enter(oe),Z);else{const{leave:ne,delayLeave:ue,afterLeave:ie}=we,Oe=()=>r(oe,$,T),We=()=>{ne(oe,()=>{Oe(),ie&&ie()})};ue?ue(oe,Oe,We):We()}else r(oe,$,T)},W=(P,$,T,z=!1,Z=!1)=>{const{type:oe,props:_e,ref:we,children:he,dynamicChildren:ke,shapeFlag:Me,patchFlag:ne,dirs:ue}=P;if(we!=null&&ru(we,null,T,P,!0),Me&256){$.ctx.deactivate(P);return}const ie=Me&1&&ue,Oe=!Ba(P);let We;if(Oe&&(We=_e&&_e.onVnodeBeforeUnmount)&&Un(We,$,P),Me&6)Te(P.component,T,z);else{if(Me&128){P.suspense.unmount(T,z);return}ie&&kr(P,null,$,"beforeUnmount"),Me&64?P.type.remove(P,$,T,Z,ae,z):ke&&(oe!==Pe||ne>0&&ne&64)?ge(ke,$,T,!1,!0):(oe===Pe&&ne&384||!Z&&Me&16)&&ge(he,$,T),z&&re(P)}(Oe&&(We=_e&&_e.onVnodeUnmounted)||ie)&&Tn(()=>{We&&Un(We,$,P),ie&&kr(P,null,$,"unmounted")},T)},re=P=>{const{type:$,el:T,anchor:z,transition:Z}=P;if($===Pe){be(T,z);return}if($===Fl){y(P);return}const oe=()=>{o(T),Z&&!Z.persisted&&Z.afterLeave&&Z.afterLeave()};if(P.shapeFlag&1&&Z&&!Z.persisted){const{leave:_e,delayLeave:we}=Z,he=()=>_e(T,oe);we?we(P.el,oe,he):he()}else oe()},be=(P,$)=>{let T;for(;P!==$;)T=h(P),o(P),P=T;o($)},Te=(P,$,T)=>{const{bum:z,scope:Z,update:oe,subTree:_e,um:we}=P;z&&xi(z),Z.stop(),oe&&(oe.active=!1,W(_e,P,$,T)),we&&Tn(we,$),Tn(()=>{P.isUnmounted=!0},$),$&&$.pendingBranch&&!$.isUnmounted&&P.asyncDep&&!P.asyncResolved&&P.suspenseId===$.pendingId&&($.deps--,$.deps===0&&$.resolve())},ge=(P,$,T,z=!1,Z=!1,oe=0)=>{for(let _e=oe;_eP.shapeFlag&6?J(P.component.subTree):P.shapeFlag&128?P.suspense.next():h(P.anchor||P.el),te=(P,$,T)=>{P==null?$._vnode&&W($._vnode,null,null,!0):g($._vnode||null,P,$,null,null,null,T),Zp(),Qi(),$._vnode=P},ae={p:g,um:W,m:ee,r:re,mt:M,mc:S,pc:X,pbc:L,n:J,o:e};let le,me;return t&&([le,me]=t(ae)),{render:te,hydrate:le,createApp:KC(te,le)}}function Bo({effect:e,update:t},n){e.allowRecurse=t.allowRecurse=n}function yf(e,t,n=!1){const r=e.children,o=t.children;if(De(r)&&De(o))for(let a=0;a>1,e[n[s]]0&&(t[r]=n[a-1]),n[a]=r)}}for(a=n.length,l=n[a-1];a-- >0;)n[a]=l,l=t[l];return n}const nk=e=>e.__isTeleport,Dl=e=>e&&(e.disabled||e.disabled===""),cm=e=>typeof SVGElement!="undefined"&&e instanceof SVGElement,Gc=(e,t)=>{const n=e&&e.to;return Ge(n)?t?t(n):null:n},rk={__isTeleport:!0,process(e,t,n,r,o,a,l,s,i,u){const{mc:d,pc:f,pbc:h,o:{insert:p,querySelector:v,createText:g,createComment:w}}=u,m=Dl(t.props);let{shapeFlag:b,children:_,dynamicChildren:y}=t;if(e==null){const C=t.el=g(""),k=t.anchor=g("");p(C,n,r),p(k,n,r);const E=t.target=Gc(t.props,v),S=t.targetAnchor=g("");E&&(p(S,E),l=l||cm(E));const R=(L,F)=>{b&16&&d(_,L,F,o,a,l,s,i)};m?R(n,k):E&&R(E,S)}else{t.el=e.el;const C=t.anchor=e.anchor,k=t.target=e.target,E=t.targetAnchor=e.targetAnchor,S=Dl(e.props),R=S?n:k,L=S?C:E;if(l=l||cm(k),y?(h(e.dynamicChildren,y,R,o,a,l,s),yf(e,t,!0)):i||f(e,t,R,L,o,a,l,s,!1),m)S||ti(t,n,C,u,1);else if((t.props&&t.props.to)!==(e.props&&e.props.to)){const F=t.target=Gc(t.props,v);F&&ti(t,F,null,u,0)}else S&&ti(t,k,E,u,1)}Bb(t)},remove(e,t,n,r,{um:o,o:{remove:a}},l){const{shapeFlag:s,children:i,anchor:u,targetAnchor:d,target:f,props:h}=e;if(f&&a(d),(l||!Dl(h))&&(a(u),s&16))for(let p=0;p0?sr||Na:null,ak(),as>0&&sr&&sr.push(e),e}function U(e,t,n,r,o,a){return zb(K(e,t,n,r,o,a,!0))}function ce(e,t,n,r,o){return zb(Q(e,t,n,r,o,!0))}function Ua(e){return e?e.__v_isVNode===!0:!1}function Yo(e,t){return e.type===t.type&&e.key===t.key}const Lu="__vInternal",Hb=({key:e})=>e!=null?e:null,Oi=({ref:e,ref_key:t,ref_for:n})=>(typeof e=="number"&&(e=""+e),e!=null?Ge(e)||mt(e)||Ke(e)?{i:sn,r:e,k:t,f:!!n}:e:null);function K(e,t=null,n=null,r=0,o=null,a=e===Pe?0:1,l=!1,s=!1){const i={__v_isVNode:!0,__v_skip:!0,type:e,props:t,key:t&&Hb(t),ref:t&&Oi(t),scopeId:Au,slotScopeIds:null,children:n,component:null,suspense:null,ssContent:null,ssFallback:null,dirs:null,transition:null,el:null,anchor:null,target:null,targetAnchor:null,staticCount:0,shapeFlag:a,patchFlag:r,dynamicProps:o,dynamicChildren:null,appContext:null,ctx:sn};return s?(_f(i,n),a&128&&e.normalize(i)):n&&(i.shapeFlag|=Ge(n)?8:16),as>0&&!l&&sr&&(i.patchFlag>0||a&6)&&i.patchFlag!==32&&sr.push(i),i}const Q=lk;function lk(e,t=null,n=null,r=0,o=null,a=!1){if((!e||e===xb)&&(e=yn),Ua(e)){const s=Xr(e,t,!0);return n&&_f(s,n),as>0&&!a&&sr&&(s.shapeFlag&6?sr[sr.indexOf(e)]=s:sr.push(s)),s.patchFlag|=-2,s}if(mk(e)&&(e=e.__vccOpts),t){t=jb(t);let{class:s,style:i}=t;s&&!Ge(s)&&(t.class=D(s)),ht(i)&&(cb(i)&&!De(i)&&(i=Wt({},i)),t.style=Qe(i))}const l=Ge(e)?1:$C(e)?128:nk(e)?64:ht(e)?4:Ke(e)?2:0;return K(e,t,n,r,o,l,a,!0)}function jb(e){return e?cb(e)||Lu in e?Wt({},e):e:null}function Xr(e,t,n=!1){const{props:r,ref:o,patchFlag:a,children:l}=e,s=t?Ht(r||{},t):r;return{__v_isVNode:!0,__v_skip:!0,type:e.type,props:s,key:s&&Hb(s),ref:t&&t.ref?n&&o?De(o)?o.concat(Oi(t)):[o,Oi(t)]:Oi(t):o,scopeId:e.scopeId,slotScopeIds:e.slotScopeIds,children:l,target:e.target,targetAnchor:e.targetAnchor,staticCount:e.staticCount,shapeFlag:e.shapeFlag,patchFlag:t&&e.type!==Pe?a===-1?16:a|16:a,dynamicProps:e.dynamicProps,dynamicChildren:e.dynamicChildren,appContext:e.appContext,dirs:e.dirs,transition:e.transition,component:e.component,suspense:e.suspense,ssContent:e.ssContent&&Xr(e.ssContent),ssFallback:e.ssFallback&&Xr(e.ssFallback),el:e.el,anchor:e.anchor,ctx:e.ctx,ce:e.ce}}function Je(e=" ",t=0){return Q(Gr,null,e,t)}function dG(e,t){const n=Q(Fl,null,e);return n.staticCount=t,n}function ye(e="",t=!1){return t?(x(),ce(yn,null,e)):Q(yn,null,e)}function or(e){return e==null||typeof e=="boolean"?Q(yn):De(e)?Q(Pe,null,e.slice()):typeof e=="object"?go(e):Q(Gr,null,String(e))}function go(e){return e.el===null&&e.patchFlag!==-1||e.memo?e:Xr(e)}function _f(e,t){let n=0;const{shapeFlag:r}=e;if(t==null)t=null;else if(De(t))n=16;else if(typeof t=="object")if(r&65){const o=t.default;o&&(o._c&&(o._d=!1),_f(e,o()),o._c&&(o._d=!0));return}else{n=32;const o=t._;!o&&!(Lu in t)?t._ctx=sn:o===3&&sn&&(sn.slots._===1?t._=1:(t._=2,e.patchFlag|=1024))}else Ke(t)?(t={default:t,_ctx:sn},n=32):(t=String(t),r&64?(n=16,t=[Je(t)]):n=8);e.children=t,e.shapeFlag|=n}function Ht(...e){const t={};for(let n=0;nZt||sn;let wf,Sa,fm="__VUE_INSTANCE_SETTERS__";(Sa=Bc()[fm])||(Sa=Bc()[fm]=[]),Sa.push(e=>Zt=e),wf=e=>{Sa.length>1?Sa.forEach(t=>t(e)):Sa[0](e)};const Ka=e=>{wf(e),e.scope.on()},ra=()=>{Zt&&Zt.scope.off(),wf(null)};function Wb(e){return e.vnode.shapeFlag&4}let qa=!1;function ck(e,t=!1){qa=t;const{props:n,children:r}=e.vnode,o=Wb(e);qC(e,n,o,t),XC(e,r);const a=o?dk(e,t):void 0;return qa=!1,a}function dk(e,t){const n=e.type;e.accessCache=Object.create(null),e.proxy=db(new Proxy(e.ctx,VC));const{setup:r}=n;if(r){const o=e.setupContext=r.length>1?Kb(e):null;Ka(e),dl();const a=Eo(r,e,0,[e.props,o]);if(fl(),ra(),Gi(a)){if(a.then(ra,ra),t)return a.then(l=>{pm(e,l,t)}).catch(l=>{xs(l,e,0)});e.asyncDep=a}else pm(e,a,t)}else Ub(e,t)}function pm(e,t,n){Ke(t)?e.type.__ssrInlineRender?e.ssrRender=t:e.render=t:ht(t)&&(e.setupState=mb(t)),Ub(e,n)}let mm;function Ub(e,t,n){const r=e.type;if(!e.render){if(!t&&mm&&!r.render){const o=r.template||gf(e).template;if(o){const{isCustomElement:a,compilerOptions:l}=e.appContext.config,{delimiters:s,compilerOptions:i}=r,u=Wt(Wt({isCustomElement:a,delimiters:s},l),i);r.render=mm(o,u)}}e.render=r.render||en}Ka(e),dl(),BC(e),fl(),ra()}function fk(e){return e.attrsProxy||(e.attrsProxy=new Proxy(e.attrs,{get(t,n){return Ln(e,"get","$attrs"),t[n]}}))}function Kb(e){const t=n=>{e.exposed=n||{}};return{get attrs(){return fk(e)},slots:e.slots,emit:e.emit,expose:t}}function Mu(e){if(e.exposed)return e.exposeProxy||(e.exposeProxy=new Proxy(mb(db(e.exposed)),{get(t,n){if(n in t)return t[n];if(n in Nl)return Nl[n](e)},has(t,n){return n in t||n in Nl}}))}function pk(e,t=!0){return Ke(e)?e.displayName||e.name:e.name||t&&e.__name}function mk(e){return Ke(e)&&"__vccOpts"in e}const O=(e,t)=>vb(e,t,qa);function He(e,t,n){const r=arguments.length;return r===2?ht(t)&&!De(t)?Ua(t)?Q(e,null,[t]):Q(e,t):Q(e,null,t):(r>3?n=Array.prototype.slice.call(arguments,2):r===3&&Ua(n)&&(n=[n]),Q(e,t,n))}const hk=Symbol.for("v-scx"),vk=()=>Re(hk),qb="3.3.4",gk="http://www.w3.org/2000/svg",Go=typeof document!="undefined"?document:null,hm=Go&&Go.createElement("template"),bk={insert:(e,t,n)=>{t.insertBefore(e,n||null)},remove:e=>{const t=e.parentNode;t&&t.removeChild(e)},createElement:(e,t,n,r)=>{const o=t?Go.createElementNS(gk,e):Go.createElement(e,n?{is:n}:void 0);return e==="select"&&r&&r.multiple!=null&&o.setAttribute("multiple",r.multiple),o},createText:e=>Go.createTextNode(e),createComment:e=>Go.createComment(e),setText:(e,t)=>{e.nodeValue=t},setElementText:(e,t)=>{e.textContent=t},parentNode:e=>e.parentNode,nextSibling:e=>e.nextSibling,querySelector:e=>Go.querySelector(e),setScopeId(e,t){e.setAttribute(t,"")},insertStaticContent(e,t,n,r,o,a){const l=n?n.previousSibling:t.lastChild;if(o&&(o===a||o.nextSibling))for(;t.insertBefore(o.cloneNode(!0),n),!(o===a||!(o=o.nextSibling)););else{hm.innerHTML=r?`${e}`:e;const s=hm.content;if(r){const i=s.firstChild;for(;i.firstChild;)s.appendChild(i.firstChild);s.removeChild(i)}t.insertBefore(s,n)}return[l?l.nextSibling:t.firstChild,n?n.previousSibling:t.lastChild]}};function yk(e,t,n){const r=e._vtc;r&&(t=(t?[t,...r]:[...r]).join(" ")),t==null?e.removeAttribute("class"):n?e.setAttribute("class",t):e.className=t}function _k(e,t,n){const r=e.style,o=Ge(n);if(n&&!o){if(t&&!Ge(t))for(const a in t)n[a]==null&&Xc(r,a,"");for(const a in n)Xc(r,a,n[a])}else{const a=r.display;o?t!==n&&(r.cssText=n):t&&e.removeAttribute("style"),"_vod"in e&&(r.display=a)}}const vm=/\s*!important$/;function Xc(e,t,n){if(De(n))n.forEach(r=>Xc(e,t,r));else if(n==null&&(n=""),t.startsWith("--"))e.setProperty(t,n);else{const r=wk(e,t);vm.test(n)?e.setProperty(fa(r),n.replace(vm,""),"important"):e[r]=n}}const gm=["Webkit","Moz","ms"],uc={};function wk(e,t){const n=uc[t];if(n)return n;let r=cr(t);if(r!=="filter"&&r in e)return uc[t]=r;r=$u(r);for(let o=0;occ||(Tk.then(()=>cc=0),cc=Date.now());function Ok(e,t){const n=r=>{if(!r._vts)r._vts=Date.now();else if(r._vts<=n.attached)return;qn(Ak(r,n.value),t,5,[r])};return n.value=e,n.attached=xk(),n}function Ak(e,t){if(De(t)){const n=e.stopImmediatePropagation;return e.stopImmediatePropagation=()=>{n.call(e),e._stopped=!0},t.map(r=>o=>!o._stopped&&r&&r(o))}else return t}const _m=/^on[a-z]/,Ik=(e,t,n,r,o=!1,a,l,s,i)=>{t==="class"?yk(e,r,o):t==="style"?_k(e,n,r):$s(t)?Zd(t)||Ek(e,t,n,r,l):(t[0]==="."?(t=t.slice(1),!0):t[0]==="^"?(t=t.slice(1),!1):Pk(e,t,r,o))?kk(e,t,r,a,l,s,i):(t==="true-value"?e._trueValue=r:t==="false-value"&&(e._falseValue=r),Ck(e,t,r,o))};function Pk(e,t,n,r){return r?!!(t==="innerHTML"||t==="textContent"||t in e&&_m.test(t)&&Ke(n)):t==="spellcheck"||t==="draggable"||t==="translate"||t==="form"||t==="list"&&e.tagName==="INPUT"||t==="type"&&e.tagName==="TEXTAREA"||_m.test(t)&&Ge(n)?!1:t in e}const uo="transition",kl="animation",Mn=(e,{slots:t})=>He(OC,Gb(e),t);Mn.displayName="Transition";const Yb={name:String,type:String,css:{type:Boolean,default:!0},duration:[String,Number,Object],enterFromClass:String,enterActiveClass:String,enterToClass:String,appearFromClass:String,appearActiveClass:String,appearToClass:String,leaveFromClass:String,leaveActiveClass:String,leaveToClass:String},Lk=Mn.props=Wt({},Sb,Yb),zo=(e,t=[])=>{De(e)?e.forEach(n=>n(...t)):e&&e(...t)},wm=e=>e?De(e)?e.some(t=>t.length>1):e.length>1:!1;function Gb(e){const t={};for(const N in e)N in Yb||(t[N]=e[N]);if(e.css===!1)return t;const{name:n="v",type:r,duration:o,enterFromClass:a=`${n}-enter-from`,enterActiveClass:l=`${n}-enter-active`,enterToClass:s=`${n}-enter-to`,appearFromClass:i=a,appearActiveClass:u=l,appearToClass:d=s,leaveFromClass:f=`${n}-leave-from`,leaveActiveClass:h=`${n}-leave-active`,leaveToClass:p=`${n}-leave-to`}=e,v=Mk(o),g=v&&v[0],w=v&&v[1],{onBeforeEnter:m,onEnter:b,onEnterCancelled:_,onLeave:y,onLeaveCancelled:C,onBeforeAppear:k=m,onAppear:E=b,onAppearCancelled:S=_}=t,R=(N,A,M)=>{mo(N,A?d:s),mo(N,A?u:l),M&&M()},L=(N,A)=>{N._isLeaving=!1,mo(N,f),mo(N,p),mo(N,h),A&&A()},F=N=>(A,M)=>{const H=N?E:b,j=()=>R(A,N,M);zo(H,[A,j]),Cm(()=>{mo(A,N?i:a),Fr(A,N?d:s),wm(H)||km(A,r,g,j)})};return Wt(t,{onBeforeEnter(N){zo(m,[N]),Fr(N,a),Fr(N,l)},onBeforeAppear(N){zo(k,[N]),Fr(N,i),Fr(N,u)},onEnter:F(!1),onAppear:F(!0),onLeave(N,A){N._isLeaving=!0;const M=()=>L(N,A);Fr(N,f),Jb(),Fr(N,h),Cm(()=>{!N._isLeaving||(mo(N,f),Fr(N,p),wm(y)||km(N,r,w,M))}),zo(y,[N,M])},onEnterCancelled(N){R(N,!1),zo(_,[N])},onAppearCancelled(N){R(N,!0),zo(S,[N])},onLeaveCancelled(N){L(N),zo(C,[N])}})}function Mk(e){if(e==null)return null;if(ht(e))return[dc(e.enter),dc(e.leave)];{const t=dc(e);return[t,t]}}function dc(e){return S2(e)}function Fr(e,t){t.split(/\s+/).forEach(n=>n&&e.classList.add(n)),(e._vtc||(e._vtc=new Set)).add(t)}function mo(e,t){t.split(/\s+/).forEach(r=>r&&e.classList.remove(r));const{_vtc:n}=e;n&&(n.delete(t),n.size||(e._vtc=void 0))}function Cm(e){requestAnimationFrame(()=>{requestAnimationFrame(e)})}let Rk=0;function km(e,t,n,r){const o=e._endId=++Rk,a=()=>{o===e._endId&&r()};if(n)return setTimeout(a,n);const{type:l,timeout:s,propCount:i}=Xb(e,t);if(!l)return r();const u=l+"end";let d=0;const f=()=>{e.removeEventListener(u,h),a()},h=p=>{p.target===e&&++d>=i&&f()};setTimeout(()=>{d(n[v]||"").split(", "),o=r(`${uo}Delay`),a=r(`${uo}Duration`),l=Sm(o,a),s=r(`${kl}Delay`),i=r(`${kl}Duration`),u=Sm(s,i);let d=null,f=0,h=0;t===uo?l>0&&(d=uo,f=l,h=a.length):t===kl?u>0&&(d=kl,f=u,h=i.length):(f=Math.max(l,u),d=f>0?l>u?uo:kl:null,h=d?d===uo?a.length:i.length:0);const p=d===uo&&/\b(transform|all)(,|$)/.test(r(`${uo}Property`).toString());return{type:d,timeout:f,propCount:h,hasTransform:p}}function Sm(e,t){for(;e.lengthEm(n)+Em(e[r])))}function Em(e){return Number(e.slice(0,-1).replace(",","."))*1e3}function Jb(){return document.body.offsetHeight}const Zb=new WeakMap,Qb=new WeakMap,e0={name:"TransitionGroup",props:Wt({},Lk,{tag:String,moveClass:String}),setup(e,{slots:t}){const n=lt(),r=kb();let o,a;return pl(()=>{if(!o.length)return;const l=e.moveClass||`${e.name||"v"}-move`;if(!zk(o[0].el,n.vnode.el,l))return;o.forEach(Fk),o.forEach(Vk);const s=o.filter(Bk);Jb(),s.forEach(i=>{const u=i.el,d=u.style;Fr(u,l),d.transform=d.webkitTransform=d.transitionDuration="";const f=u._moveCb=h=>{h&&h.target!==u||(!h||/transform$/.test(h.propertyName))&&(u.removeEventListener("transitionend",f),u._moveCb=null,mo(u,l))};u.addEventListener("transitionend",f)})}),()=>{const l=gt(e),s=Gb(l);let i=l.tag||Pe;o=a,a=t.default?pf(t.default()):[];for(let u=0;udelete e.mode;e0.props;const Dk=e0;function Fk(e){const t=e.el;t._moveCb&&t._moveCb(),t._enterCb&&t._enterCb()}function Vk(e){Qb.set(e,e.el.getBoundingClientRect())}function Bk(e){const t=Zb.get(e),n=Qb.get(e),r=t.left-n.left,o=t.top-n.top;if(r||o){const a=e.el.style;return a.transform=a.webkitTransform=`translate(${r}px,${o}px)`,a.transitionDuration="0s",e}}function zk(e,t,n){const r=e.cloneNode();e._vtc&&e._vtc.forEach(l=>{l.split(/\s+/).forEach(s=>s&&r.classList.remove(s))}),n.split(/\s+/).forEach(l=>l&&r.classList.add(l)),r.style.display="none";const o=t.nodeType===1?t:t.parentNode;o.appendChild(r);const{hasTransform:a}=Xb(r);return o.removeChild(r),a}const Ya=e=>{const t=e.props["onUpdate:modelValue"]||!1;return De(t)?n=>xi(t,n):t};function Hk(e){e.target.composing=!0}function $m(e){const t=e.target;t.composing&&(t.composing=!1,t.dispatchEvent(new Event("input")))}const t0={created(e,{modifiers:{lazy:t,trim:n,number:r}},o){e._assign=Ya(o);const a=r||o.props&&o.props.type==="number";_o(e,t?"change":"input",l=>{if(l.target.composing)return;let s=e.value;n&&(s=s.trim()),a&&(s=Vc(s)),e._assign(s)}),n&&_o(e,"change",()=>{e.value=e.value.trim()}),t||(_o(e,"compositionstart",Hk),_o(e,"compositionend",$m),_o(e,"change",$m))},mounted(e,{value:t}){e.value=t==null?"":t},beforeUpdate(e,{value:t,modifiers:{lazy:n,trim:r,number:o}},a){if(e._assign=Ya(a),e.composing||document.activeElement===e&&e.type!=="range"&&(n||r&&e.value.trim()===t||(o||e.type==="number")&&Vc(e.value)===t))return;const l=t==null?"":t;e.value!==l&&(e.value=l)}},ou={deep:!0,created(e,t,n){e._assign=Ya(n),_o(e,"change",()=>{const r=e._modelValue,o=r0(e),a=e.checked,l=e._assign;if(De(r)){const s=Gg(r,o),i=s!==-1;if(a&&!i)l(r.concat(o));else if(!a&&i){const u=[...r];u.splice(s,1),l(u)}}else if(Su(r)){const s=new Set(r);a?s.add(o):s.delete(o),l(s)}else l(o0(e,a))})},mounted:Tm,beforeUpdate(e,t,n){e._assign=Ya(n),Tm(e,t,n)}};function Tm(e,{value:t,oldValue:n},r){e._modelValue=t,De(t)?e.checked=Gg(t,r.props.value)>-1:Su(t)?e.checked=t.has(r.props.value):t!==n&&(e.checked=ja(t,o0(e,!0)))}const n0={created(e,{value:t},n){e.checked=ja(t,n.props.value),e._assign=Ya(n),_o(e,"change",()=>{e._assign(r0(e))})},beforeUpdate(e,{value:t,oldValue:n},r){e._assign=Ya(r),t!==n&&(e.checked=ja(t,r.props.value))}};function r0(e){return"_value"in e?e._value:e.value}function o0(e,t){const n=t?"_trueValue":"_falseValue";return n in e?e[n]:t}const jk=["ctrl","shift","alt","meta"],Wk={stop:e=>e.stopPropagation(),prevent:e=>e.preventDefault(),self:e=>e.target!==e.currentTarget,ctrl:e=>!e.ctrlKey,shift:e=>!e.shiftKey,alt:e=>!e.altKey,meta:e=>!e.metaKey,left:e=>"button"in e&&e.button!==0,middle:e=>"button"in e&&e.button!==1,right:e=>"button"in e&&e.button!==2,exact:(e,t)=>jk.some(n=>e[`${n}Key`]&&!t.includes(n))},$t=(e,t)=>(n,...r)=>{for(let o=0;on=>{if(!("key"in n))return;const r=fa(n.key);if(t.some(o=>o===r||Uk[o]===r))return e(n)},qt={beforeMount(e,{value:t},{transition:n}){e._vod=e.style.display==="none"?"":e.style.display,n&&t?n.beforeEnter(e):Sl(e,t)},mounted(e,{value:t},{transition:n}){n&&t&&n.enter(e)},updated(e,{value:t,oldValue:n},{transition:r}){!t!=!n&&(r?t?(r.beforeEnter(e),Sl(e,!0),r.enter(e)):r.leave(e,()=>{Sl(e,!1)}):Sl(e,t))},beforeUnmount(e,{value:t}){Sl(e,t)}};function Sl(e,t){e.style.display=t?e._vod:"none"}const a0=Wt({patchProp:Ik},bk);let Bl,xm=!1;function Kk(){return Bl||(Bl=QC(a0))}function qk(){return Bl=xm?Bl:ek(a0),xm=!0,Bl}const Om=(...e)=>{Kk().render(...e)},Yk=(...e)=>{const t=qk().createApp(...e),{mount:n}=t;return t.mount=r=>{const o=Gk(r);if(o)return n(o,!0,o instanceof SVGElement)},t};function Gk(e){return Ge(e)?document.querySelector(e):e}const Xk=JSON.parse('{"base":"/","lang":"en-US","title":"SD \u8BAD\u7EC3 UI","description":"","head":[],"locales":{}}');var Jk=([e,t,n])=>e==="meta"&&t.name?`${e}.${t.name}`:["title","base"].includes(e)?e:e==="template"&&t.id?`${e}.${t.id}`:JSON.stringify([e,t,n]),Zk=e=>{const t=new Set,n=[];return e.forEach(r=>{const o=Jk(r);t.has(o)||(t.add(o),n.push(r))}),n},Qk=e=>/^(https?:)?\/\//.test(e),fG=e=>/^mailto:/.test(e),pG=e=>/^tel:/.test(e),l0=e=>Object.prototype.toString.call(e)==="[object Object]",eS=e=>e.replace(/\/$/,""),tS=e=>e.replace(/^\//,""),s0=(e,t)=>{const n=Object.keys(e).sort((r,o)=>{const a=o.split("/").length-r.split("/").length;return a!==0?a:o.length-r.length});for(const r of n)if(t.startsWith(r))return r;return"/"};const i0={"v-8daa1a0e":Jt(()=>wt(()=>import("./index.html.c6ef684b.js"),[])),"v-6983ba2a":Jt(()=>wt(()=>import("./tageditor.html.173f1b6a.js"),[])),"v-51615306":Jt(()=>wt(()=>import("./tagger.html.0daaef4e.js"),[])),"v-06850b9b":Jt(()=>wt(()=>import("./task.html.256f458b.js"),[])),"v-13efe3c5":Jt(()=>wt(()=>import("./tensorboard.html.9c3b4542.js"),[])),"v-33a23463":Jt(()=>wt(()=>import("./index.html.911dc78d.js"),[])),"v-b5471278":Jt(()=>wt(()=>import("./about.html.b4807002.js"),[])),"v-a1c9e4f2":Jt(()=>wt(()=>import("./changelog.html.e5f6a7b8.js"),[])),"v-b8e2d701":Jt(()=>wt(()=>import("./guide.html.c3f4a902.js"),[])),"v-72e1da3e":Jt(()=>wt(()=>import("./settings.html.07aaabcc.js"),[])),"v-3e43d6e2":Jt(()=>wt(()=>import("./basic.html.eb26832d.js"),[])),"v-fdbe4e28":Jt(()=>wt(()=>import("./flux.html.f22f5932.js"),[])),"v-14e91824":Jt(()=>wt(()=>import("./index.html.4896b94d.js"),[])),"v-1bf725da":Jt(()=>wt(()=>import("./master.html.404f21be.js"),[])),"v-0f9e746f":Jt(()=>wt(()=>import("./params.html.dea583bc.js"),[])),"v-0dc76a3b":Jt(()=>wt(()=>import("./sd3.html.1a4bf31e.js"),[])),"v-a1f1ne2e":Jt(()=>wt(()=>import("./anima-finetune.html.1a4bf32e.js"),[])),"v-53c99f50":Jt(()=>wt(()=>import("./sdxl.html.33fa069c.js"),[])),"v-4441a302":Jt(()=>wt(()=>import("./tools.html.6c8bfc09.js"),[])),"v-3706649a":Jt(()=>wt(()=>import("./404.html.7a24a487.js"),[]))},nS={404:Jt(()=>wt(()=>import("./404.47057000.js"),[])),Layout:Jt(()=>wt(()=>import("./layout.96d49288.js"),[]))};var u0=B(b2),c0=pa({key:"",path:"",title:"",lang:"",frontmatter:{},excerpt:"",headers:[]}),jr=B(c0),Ps=()=>jr;zp.webpackHot&&(__VUE_HMR_RUNTIME__.updatePageData=e=>{u0.value[e.key]=()=>Promise.resolve(e),e.key===jr.value.key&&(jr.value=e)});var d0=Symbol(""),rS=()=>{const e=Re(d0);if(!e)throw new Error("usePageFrontmatter() is called without provider.");return e},f0=Symbol(""),oS=()=>{const e=Re(f0);if(!e)throw new Error("usePageHead() is called without provider.");return e},aS=Symbol(""),p0=Symbol(""),lS=()=>{const e=Re(p0);if(!e)throw new Error("usePageLang() is called without provider.");return e},Cf=Symbol(""),sS=()=>{const e=Re(Cf);if(!e)throw new Error("useRouteLocale() is called without provider.");return e},wo=B(Xk),iS=()=>wo;zp.webpackHot&&(__VUE_HMR_RUNTIME__.updateSiteData=e=>{wo.value=e});var m0=Symbol(""),mG=()=>{const e=Re(m0);if(!e)throw new Error("useSiteLocaleData() is called without provider.");return e},uS=Symbol(""),Wo=Xt({resolvePageData:async e=>{const t=u0.value[e],n=await(t==null?void 0:t());return n!=null?n:c0},resolvePageFrontmatter:e=>e.frontmatter,resolvePageHead:(e,t,n)=>{const r=Ge(t.description)?t.description:n.description,o=[...De(t.head)?t.head:[],...n.head,["title",{},e],["meta",{name:"description",content:r}]];return Zk(o)},resolvePageHeadTitle:(e,t)=>`${e.title?`${e.title} | `:""}${t.title}`,resolvePageLang:e=>e.lang||"en",resolveRouteLocale:(e,t)=>s0(e,t),resolveSiteLocaleData:(e,t)=>({...e,...e.locales[t]})}),cS=se({name:"ClientOnly",setup(e,t){const n=B(!1);return dt(()=>{n.value=!0}),()=>{var r,o;return n.value?(o=(r=t.slots).default)==null?void 0:o.call(r):null}}}),dS=se({name:"Content",props:{pageKey:{type:String,required:!1,default:""}},setup(e){const t=Ps(),n=O(()=>i0[e.pageKey||t.value.key]);return()=>n.value?He(n.value):He("div","404 Not Found")}}),Am=se({name:"Vuepress",setup(){const e=Ps(),t=O(()=>{let n;if(e.value.path){const r=e.value.frontmatter.layout;Ge(r)?n=r:n="Layout"}else n="404";return nS[n]||Ve(n,!1)});return()=>He(t.value)}}),fS=e=>Qk(e)?e:`${iS().value.base}${tS(e)}`,Ro=e=>e;function h0(e,t,n){var r,o,a;t===void 0&&(t=50),n===void 0&&(n={});var l=(r=n.isImmediate)!=null&&r,s=(o=n.callback)!=null&&o,i=n.maxWait,u=Date.now(),d=[];function f(){if(i!==void 0){var p=Date.now()-u;if(p+t>=i)return i-p}return t}var h=function(){var p=[].slice.call(arguments),v=this;return new Promise(function(g,w){var m=l&&a===void 0;if(a!==void 0&&clearTimeout(a),a=setTimeout(function(){if(a=void 0,u=Date.now(),!l){var _=e.apply(v,p);s&&s(_),d.forEach(function(y){return(0,y.resolve)(_)}),d=[]}},f()),m){var b=e.apply(v,p);return s&&s(b),g(b)}d.push({resolve:g,reject:w})})};return h.cancel=function(p){a!==void 0&&clearTimeout(a),d.forEach(function(v){return(0,v.reject)(p)}),d=[]},h}/*! +var m2=Object.defineProperty;var h2=(e,t,n)=>t in e?m2(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n;var Hp=(e,t,n)=>(h2(e,typeof t!="symbol"?t+"":t,n),n);const zp={};const v2="modulepreload",jp={},g2="/",wt=function(t,n){return!n||n.length===0?t():Promise.all(n.map(r=>{if(r=`${g2}${r}`,r in jp)return;jp[r]=!0;const o=r.endsWith(".css"),a=o?'[rel="stylesheet"]':"";if(document.querySelector(`link[href="${r}"]${a}`))return;const l=document.createElement("link");if(l.rel=o?"stylesheet":v2,o||(l.as="script",l.crossOrigin=""),l.href=r,document.head.appendChild(l),o)return new Promise((s,i)=>{l.addEventListener("load",s),l.addEventListener("error",()=>i(new Error(`Unable to preload CSS for ${r}`)))})})).then(()=>t())},b2={"v-8daa1a0e":()=>wt(()=>import("./index.html.ec4ace46.js"),[]).then(({data:e})=>e),"v-6983ba2a":()=>wt(()=>import("./tageditor.html.66da263e.js"),[]).then(({data:e})=>e),"v-native-tageditor":()=>wt(()=>import("./native-tageditor.html.native.js"),[]).then(({data:e})=>e),"v-51615306":()=>wt(()=>import("./tagger.html.66f12b92.js"),[]).then(({data:e})=>e),"v-06850b9b":()=>wt(()=>import("./task.html.4e4c8633.js"),[]).then(({data:e})=>e),"v-13efe3c5":()=>wt(()=>import("./tensorboard.html.4a2799a9.js"),[]).then(({data:e})=>e),"v-33a23463":()=>wt(()=>import("./index.html.838bbc6c.js"),[]).then(({data:e})=>e),"v-b5471278":()=>wt(()=>import("./about.html.5b0c0de9.js"),[]).then(({data:e})=>e),"v-a1c9e4f2":()=>wt(()=>import("./changelog.html.a1b2c3d4.js"),[]).then(({data:e})=>e),"v-b8e2d701":()=>wt(()=>import("./guide.html.b8e2d701.js"),[]).then(({data:e})=>e),"v-72e1da3e":()=>wt(()=>import("./settings.html.06993f96.js?v=dataset-tagger-api"),[]).then(({data:e})=>e),"v-3e43d6e2":()=>wt(()=>import("./basic.html.48955584.js"),[]).then(({data:e})=>e),"v-fdbe4e28":()=>wt(()=>import("./flux.html.6fefc131.js"),[]).then(({data:e})=>e),"v-14e91824":()=>wt(()=>import("./index.html.b97ec799.js"),[]).then(({data:e})=>e),"v-1bf725da":()=>wt(()=>import("./master.html.54eb6415.js"),[]).then(({data:e})=>e),"v-0f9e746f":()=>wt(()=>import("./params.html.c8cc13ef.js"),[]).then(({data:e})=>e),"v-0dc76a3b":()=>wt(()=>import("./sd3.html.eaeb05e1.js"),[]).then(({data:e})=>e),"v-a1f1ne2e":()=>wt(()=>import("./anima-finetune.html.eaeb05f2.js"),[]).then(({data:e})=>e),"v-53c99f50":()=>wt(()=>import("./sdxl.html.6ab37b06.js"),[]).then(({data:e})=>e),"v-4441a302":()=>wt(()=>import("./tools.html.c0a4659a.js"),[]).then(({data:e})=>e),"v-3706649a":()=>wt(()=>import("./404.html.686caba0.js"),[]).then(({data:e})=>e)};function Jd(e,t){const n=Object.create(null),r=e.split(",");for(let o=0;o!!n[o.toLowerCase()]:o=>!!n[o]}const Ft={},Na=[],en=()=>{},y2=()=>!1,_2=/^on[^a-z]/,$s=e=>_2.test(e),Zd=e=>e.startsWith("onUpdate:"),Wt=Object.assign,Qd=(e,t)=>{const n=e.indexOf(t);n>-1&&e.splice(n,1)},w2=Object.prototype.hasOwnProperty,ft=(e,t)=>w2.call(e,t),De=Array.isArray,Da=e=>Ts(e)==="[object Map]",Su=e=>Ts(e)==="[object Set]",Yi=e=>Ts(e)==="[object Date]",Ke=e=>typeof e=="function",Ge=e=>typeof e=="string",Zl=e=>typeof e=="symbol",ht=e=>e!==null&&typeof e=="object",Gi=e=>ht(e)&&Ke(e.then)&&Ke(e.catch),Kg=Object.prototype.toString,Ts=e=>Kg.call(e),$i=e=>Ts(e).slice(8,-1),qg=e=>Ts(e)==="[object Object]",ef=e=>Ge(e)&&e!=="NaN"&&e[0]!=="-"&&""+parseInt(e,10)===e,Rl=Jd(",key,ref,ref_for,ref_key,onVnodeBeforeMount,onVnodeMounted,onVnodeBeforeUpdate,onVnodeUpdated,onVnodeBeforeUnmount,onVnodeUnmounted"),Eu=e=>{const t=Object.create(null);return n=>t[n]||(t[n]=e(n))},C2=/-(\w)/g,cr=Eu(e=>e.replace(C2,(t,n)=>n?n.toUpperCase():"")),k2=/\B([A-Z])/g,fa=Eu(e=>e.replace(k2,"-$1").toLowerCase()),$u=Eu(e=>e.charAt(0).toUpperCase()+e.slice(1)),Ti=Eu(e=>e?`on${$u(e)}`:""),Ql=(e,t)=>!Object.is(e,t),xi=(e,t)=>{for(let n=0;n{Object.defineProperty(e,t,{configurable:!0,enumerable:!1,value:n})},Vc=e=>{const t=parseFloat(e);return isNaN(t)?e:t},S2=e=>{const t=Ge(e)?Number(e):NaN;return isNaN(t)?e:t};let Wp;const Bc=()=>Wp||(Wp=typeof globalThis!="undefined"?globalThis:typeof self!="undefined"?self:typeof window!="undefined"?window:typeof global!="undefined"?global:{});function Qe(e){if(De(e)){const t={};for(let n=0;n{if(n){const r=n.split($2);r.length>1&&(t[r[0].trim()]=r[1].trim())}}),t}function D(e){let t="";if(Ge(e))t=e;else if(De(e))for(let n=0;nja(n,t))}const Ee=e=>Ge(e)?e:e==null?"":De(e)||ht(e)&&(e.toString===Kg||!Ke(e.toString))?JSON.stringify(e,Xg,2):String(e),Xg=(e,t)=>t&&t.__v_isRef?Xg(e,t.value):Da(t)?{[`Map(${t.size})`]:[...t.entries()].reduce((n,[r,o])=>(n[`${r} =>`]=o,n),{})}:Su(t)?{[`Set(${t.size})`]:[...t.values()]}:ht(t)&&!De(t)&&!qg(t)?String(t):t;let Vn;class Jg{constructor(t=!1){this.detached=t,this._active=!0,this.effects=[],this.cleanups=[],this.parent=Vn,!t&&Vn&&(this.index=(Vn.scopes||(Vn.scopes=[])).push(this)-1)}get active(){return this._active}run(t){if(this._active){const n=Vn;try{return Vn=this,t()}finally{Vn=n}}}on(){Vn=this}off(){Vn=this.parent}stop(t){if(this._active){let n,r;for(n=0,r=this.effects.length;n{const t=new Set(e);return t.w=0,t.n=0,t},eb=e=>(e.w&To)>0,tb=e=>(e.n&To)>0,R2=({deps:e})=>{if(e.length)for(let t=0;t{const{deps:t}=e;if(t.length){let n=0;for(let r=0;r{(d==="length"||d>=i)&&s.push(u)})}else switch(n!==void 0&&s.push(l.get(n)),t){case"add":De(e)?ef(n)&&s.push(l.get("length")):(s.push(l.get(na)),Da(e)&&s.push(l.get(Hc)));break;case"delete":De(e)||(s.push(l.get(na)),Da(e)&&s.push(l.get(Hc)));break;case"set":Da(e)&&s.push(l.get(na));break}if(s.length===1)s[0]&&jc(s[0]);else{const i=[];for(const u of s)u&&i.push(...u);jc(tf(i))}}function jc(e,t){const n=De(e)?e:[...e];for(const r of n)r.computed&&Kp(r);for(const r of n)r.computed||Kp(r)}function Kp(e,t){(e!==lr||e.allowRecurse)&&(e.scheduler?e.scheduler():e.run())}function D2(e,t){var n;return(n=Ji.get(e))==null?void 0:n.get(t)}const F2=Jd("__proto__,__v_isRef,__isVue"),ob=new Set(Object.getOwnPropertyNames(Symbol).filter(e=>e!=="arguments"&&e!=="caller").map(e=>Symbol[e]).filter(Zl)),V2=rf(),B2=rf(!1,!0),z2=rf(!0),qp=H2();function H2(){const e={};return["includes","indexOf","lastIndexOf"].forEach(t=>{e[t]=function(...n){const r=gt(this);for(let a=0,l=this.length;a{e[t]=function(...n){dl();const r=gt(this)[t].apply(this,n);return fl(),r}}),e}function j2(e){const t=gt(this);return Ln(t,"has",e),t.hasOwnProperty(e)}function rf(e=!1,t=!1){return function(r,o,a){if(o==="__v_isReactive")return!e;if(o==="__v_isReadonly")return e;if(o==="__v_isShallow")return t;if(o==="__v_raw"&&a===(e?t?aC:ub:t?ib:sb).get(r))return r;const l=De(r);if(!e){if(l&&ft(qp,o))return Reflect.get(qp,o,a);if(o==="hasOwnProperty")return j2}const s=Reflect.get(r,o,a);return(Zl(o)?ob.has(o):F2(o))||(e||Ln(r,"get",o),t)?s:mt(s)?l&&ef(o)?s:s.value:ht(s)?e?pa(s):Xt(s):s}}const W2=ab(),U2=ab(!0);function ab(e=!1){return function(n,r,o,a){let l=n[r];if(Wa(l)&&mt(l)&&!mt(o))return!1;if(!e&&(!Zi(o)&&!Wa(o)&&(l=gt(l),o=gt(o)),!De(n)&&mt(l)&&!mt(o)))return l.value=o,!0;const s=De(n)&&ef(r)?Number(r)e,Tu=e=>Reflect.getPrototypeOf(e);function qs(e,t,n=!1,r=!1){e=e.__v_raw;const o=gt(e),a=gt(t);n||(t!==a&&Ln(o,"get",t),Ln(o,"get",a));const{has:l}=Tu(o),s=r?of:n?uf:es;if(l.call(o,t))return s(e.get(t));if(l.call(o,a))return s(e.get(a));e!==o&&e.get(t)}function Ys(e,t=!1){const n=this.__v_raw,r=gt(n),o=gt(e);return t||(e!==o&&Ln(r,"has",e),Ln(r,"has",o)),e===o?n.has(e):n.has(e)||n.has(o)}function Gs(e,t=!1){return e=e.__v_raw,!t&&Ln(gt(e),"iterate",na),Reflect.get(e,"size",e)}function Yp(e){e=gt(e);const t=gt(this);return Tu(t).has.call(t,e)||(t.add(e),Yr(t,"add",e,e)),this}function Gp(e,t){t=gt(t);const n=gt(this),{has:r,get:o}=Tu(n);let a=r.call(n,e);a||(e=gt(e),a=r.call(n,e));const l=o.call(n,e);return n.set(e,t),a?Ql(t,l)&&Yr(n,"set",e,t):Yr(n,"add",e,t),this}function Xp(e){const t=gt(this),{has:n,get:r}=Tu(t);let o=n.call(t,e);o||(e=gt(e),o=n.call(t,e)),r&&r.call(t,e);const a=t.delete(e);return o&&Yr(t,"delete",e,void 0),a}function Jp(){const e=gt(this),t=e.size!==0,n=e.clear();return t&&Yr(e,"clear",void 0,void 0),n}function Xs(e,t){return function(r,o){const a=this,l=a.__v_raw,s=gt(l),i=t?of:e?uf:es;return!e&&Ln(s,"iterate",na),l.forEach((u,d)=>r.call(o,i(u),i(d),a))}}function Js(e,t,n){return function(...r){const o=this.__v_raw,a=gt(o),l=Da(a),s=e==="entries"||e===Symbol.iterator&&l,i=e==="keys"&&l,u=o[e](...r),d=n?of:t?uf:es;return!t&&Ln(a,"iterate",i?Hc:na),{next(){const{value:f,done:h}=u.next();return h?{value:f,done:h}:{value:s?[d(f[0]),d(f[1])]:d(f),done:h}},[Symbol.iterator](){return this}}}}function so(e){return function(...t){return e==="delete"?!1:this}}function J2(){const e={get(a){return qs(this,a)},get size(){return Gs(this)},has:Ys,add:Yp,set:Gp,delete:Xp,clear:Jp,forEach:Xs(!1,!1)},t={get(a){return qs(this,a,!1,!0)},get size(){return Gs(this)},has:Ys,add:Yp,set:Gp,delete:Xp,clear:Jp,forEach:Xs(!1,!0)},n={get(a){return qs(this,a,!0)},get size(){return Gs(this,!0)},has(a){return Ys.call(this,a,!0)},add:so("add"),set:so("set"),delete:so("delete"),clear:so("clear"),forEach:Xs(!0,!1)},r={get(a){return qs(this,a,!0,!0)},get size(){return Gs(this,!0)},has(a){return Ys.call(this,a,!0)},add:so("add"),set:so("set"),delete:so("delete"),clear:so("clear"),forEach:Xs(!0,!0)};return["keys","values","entries",Symbol.iterator].forEach(a=>{e[a]=Js(a,!1,!1),n[a]=Js(a,!0,!1),t[a]=Js(a,!1,!0),r[a]=Js(a,!0,!0)}),[e,n,t,r]}const[Z2,Q2,eC,tC]=J2();function af(e,t){const n=t?e?tC:eC:e?Q2:Z2;return(r,o,a)=>o==="__v_isReactive"?!e:o==="__v_isReadonly"?e:o==="__v_raw"?r:Reflect.get(ft(n,o)&&o in r?n:r,o,a)}const nC={get:af(!1,!1)},rC={get:af(!1,!0)},oC={get:af(!0,!1)},sb=new WeakMap,ib=new WeakMap,ub=new WeakMap,aC=new WeakMap;function lC(e){switch(e){case"Object":case"Array":return 1;case"Map":case"Set":case"WeakMap":case"WeakSet":return 2;default:return 0}}function sC(e){return e.__v_skip||!Object.isExtensible(e)?0:lC($i(e))}function Xt(e){return Wa(e)?e:sf(e,!1,lb,nC,sb)}function lf(e){return sf(e,!1,X2,rC,ib)}function pa(e){return sf(e,!0,G2,oC,ub)}function sf(e,t,n,r,o){if(!ht(e)||e.__v_raw&&!(t&&e.__v_isReactive))return e;const a=o.get(e);if(a)return a;const l=sC(e);if(l===0)return e;const s=new Proxy(e,l===2?r:n);return o.set(e,s),s}function Fa(e){return Wa(e)?Fa(e.__v_raw):!!(e&&e.__v_isReactive)}function Wa(e){return!!(e&&e.__v_isReadonly)}function Zi(e){return!!(e&&e.__v_isShallow)}function cb(e){return Fa(e)||Wa(e)}function gt(e){const t=e&&e.__v_raw;return t?gt(t):e}function db(e){return Xi(e,"__v_skip",!0),e}const es=e=>ht(e)?Xt(e):e,uf=e=>ht(e)?pa(e):e;function fb(e){So&&lr&&(e=gt(e),rb(e.dep||(e.dep=tf())))}function cf(e,t){e=gt(e);const n=e.dep;n&&jc(n)}function mt(e){return!!(e&&e.__v_isRef===!0)}function B(e){return pb(e,!1)}function On(e){return pb(e,!0)}function pb(e,t){return mt(e)?e:new iC(e,t)}class iC{constructor(t,n){this.__v_isShallow=n,this.dep=void 0,this.__v_isRef=!0,this._rawValue=n?t:gt(t),this._value=n?t:es(t)}get value(){return fb(this),this._value}set value(t){const n=this.__v_isShallow||Zi(t)||Wa(t);t=n?t:gt(t),Ql(t,this._rawValue)&&(this._rawValue=t,this._value=n?t:es(t),cf(this))}}function Cl(e){cf(e)}function c(e){return mt(e)?e.value:e}const uC={get:(e,t,n)=>c(Reflect.get(e,t,n)),set:(e,t,n,r)=>{const o=e[t];return mt(o)&&!mt(n)?(o.value=n,!0):Reflect.set(e,t,n,r)}};function mb(e){return Fa(e)?e:new Proxy(e,uC)}function dr(e){const t=De(e)?new Array(e.length):{};for(const n in e)t[n]=hb(e,n);return t}class cC{constructor(t,n,r){this._object=t,this._key=n,this._defaultValue=r,this.__v_isRef=!0}get value(){const t=this._object[this._key];return t===void 0?this._defaultValue:t}set value(t){this._object[this._key]=t}get dep(){return D2(gt(this._object),this._key)}}class dC{constructor(t){this._getter=t,this.__v_isRef=!0,this.__v_isReadonly=!0}get value(){return this._getter()}}function zt(e,t,n){return mt(e)?e:Ke(e)?new dC(e):ht(e)&&arguments.length>1?hb(e,t,n):B(e)}function hb(e,t,n){const r=e[t];return mt(r)?r:new cC(e,t,n)}class fC{constructor(t,n,r,o){this._setter=n,this.dep=void 0,this.__v_isRef=!0,this.__v_isReadonly=!1,this._dirty=!0,this.effect=new nf(t,()=>{this._dirty||(this._dirty=!0,cf(this))}),this.effect.computed=this,this.effect.active=this._cacheable=!o,this.__v_isReadonly=r}get value(){const t=gt(this);return fb(t),(t._dirty||!t._cacheable)&&(t._dirty=!1,t._value=t.effect.run()),t._value}set value(t){this._setter(t)}}function vb(e,t,n=!1){let r,o;const a=Ke(e);return a?(r=e,o=en):(r=e.get,o=e.set),new fC(r,o,a||!o,n)}function pC(e,...t){}function Eo(e,t,n,r){let o;try{o=r?e(...r):e()}catch(a){xs(a,t,n)}return o}function qn(e,t,n,r){if(Ke(e)){const a=Eo(e,t,n,r);return a&&Gi(a)&&a.catch(l=>{xs(l,t,n)}),a}const o=[];for(let a=0;a>>1;ns(pn[r])Sr&&pn.splice(t,1)}function gC(e){De(e)?Va.push(...e):(!zr||!zr.includes(e,e.allowRecurse?qo+1:qo))&&Va.push(e),bb()}function Zp(e,t=ts?Sr+1:0){for(;tns(n)-ns(r)),qo=0;qoe.id==null?1/0:e.id,bC=(e,t)=>{const n=ns(e)-ns(t);if(n===0){if(e.pre&&!t.pre)return-1;if(t.pre&&!e.pre)return 1}return n};function yb(e){Wc=!1,ts=!0,pn.sort(bC);const t=en;try{for(Sr=0;SrGe(p)?p.trim():p)),f&&(o=n.map(Vc))}let s,i=r[s=Ti(t)]||r[s=Ti(cr(t))];!i&&a&&(i=r[s=Ti(fa(t))]),i&&qn(i,e,6,o);const u=r[s+"Once"];if(u){if(!e.emitted)e.emitted={};else if(e.emitted[s])return;e.emitted[s]=!0,qn(u,e,6,o)}}function _b(e,t,n=!1){const r=t.emitsCache,o=r.get(e);if(o!==void 0)return o;const a=e.emits;let l={},s=!1;if(!Ke(e)){const i=u=>{const d=_b(u,t,!0);d&&(s=!0,Wt(l,d))};!n&&t.mixins.length&&t.mixins.forEach(i),e.extends&&i(e.extends),e.mixins&&e.mixins.forEach(i)}return!a&&!s?(ht(e)&&r.set(e,null),null):(De(a)?a.forEach(i=>l[i]=null):Wt(l,a),ht(e)&&r.set(e,l),l)}function Ou(e,t){return!e||!$s(t)?!1:(t=t.slice(2).replace(/Once$/,""),ft(e,t[0].toLowerCase()+t.slice(1))||ft(e,fa(t))||ft(e,t))}let sn=null,Au=null;function eu(e){const t=sn;return sn=e,Au=e&&e.type.__scopeId||null,t}function _C(e){Au=e}function wC(){Au=null}function G(e,t=sn,n){if(!t||e._n)return e;const r=(...o)=>{r._d&&dm(-1);const a=eu(t);let l;try{l=e(...o)}finally{eu(a),r._d&&dm(1)}return l};return r._n=!0,r._c=!0,r._d=!0,r}function ac(e){const{type:t,vnode:n,proxy:r,withProxy:o,props:a,propsOptions:[l],slots:s,attrs:i,emit:u,render:d,renderCache:f,data:h,setupState:p,ctx:v,inheritAttrs:g}=e;let w,m;const b=eu(e);try{if(n.shapeFlag&4){const y=o||r;w=or(d.call(y,y,f,a,p,h,v)),m=i}else{const y=t;w=or(y.length>1?y(a,{attrs:i,slots:s,emit:u}):y(a,null)),m=t.props?i:CC(i)}}catch(y){Vl.length=0,xs(y,e,1),w=Q(yn)}let _=w;if(m&&g!==!1){const y=Object.keys(m),{shapeFlag:C}=_;y.length&&C&7&&(l&&y.some(Zd)&&(m=kC(m,l)),_=Xr(_,m))}return n.dirs&&(_=Xr(_),_.dirs=_.dirs?_.dirs.concat(n.dirs):n.dirs),n.transition&&(_.transition=n.transition),w=_,eu(b),w}const CC=e=>{let t;for(const n in e)(n==="class"||n==="style"||$s(n))&&((t||(t={}))[n]=e[n]);return t},kC=(e,t)=>{const n={};for(const r in e)(!Zd(r)||!(r.slice(9)in t))&&(n[r]=e[r]);return n};function SC(e,t,n){const{props:r,children:o,component:a}=e,{props:l,children:s,patchFlag:i}=t,u=a.emitsOptions;if(t.dirs||t.transition)return!0;if(n&&i>=0){if(i&1024)return!0;if(i&16)return r?Qp(r,l,u):!!l;if(i&8){const d=t.dynamicProps;for(let f=0;fe.__isSuspense;function wb(e,t){t&&t.pendingBranch?De(e)?t.effects.push(...e):t.effects.push(e):gC(e)}function qr(e,t){return ff(e,null,t)}const Zs={};function $e(e,t,n){return ff(e,t,n)}function ff(e,t,{immediate:n,deep:r,flush:o,onTrack:a,onTrigger:l}=Ft){var s;const i=Zg()===((s=Zt)==null?void 0:s.scope)?Zt:null;let u,d=!1,f=!1;if(mt(e)?(u=()=>e.value,d=Zi(e)):Fa(e)?(u=()=>e,r=!0):De(e)?(f=!0,d=e.some(y=>Fa(y)||Zi(y)),u=()=>e.map(y=>{if(mt(y))return y.value;if(Fa(y))return Jo(y);if(Ke(y))return Eo(y,i,2)})):Ke(e)?t?u=()=>Eo(e,i,2):u=()=>{if(!(i&&i.isUnmounted))return h&&h(),qn(e,i,3,[p])}:u=en,t&&r){const y=u;u=()=>Jo(y())}let h,p=y=>{h=b.onStop=()=>{Eo(y,i,4)}},v;if(qa)if(p=en,t?n&&qn(t,i,3,[u(),f?[]:void 0,p]):u(),o==="sync"){const y=vk();v=y.__watcherHandles||(y.__watcherHandles=[])}else return en;let g=f?new Array(e.length).fill(Zs):Zs;const w=()=>{if(!!b.active)if(t){const y=b.run();(r||d||(f?y.some((C,k)=>Ql(C,g[k])):Ql(y,g)))&&(h&&h(),qn(t,i,3,[y,g===Zs?void 0:f&&g[0]===Zs?[]:g,p]),g=y)}else b.run()};w.allowRecurse=!!t;let m;o==="sync"?m=w:o==="post"?m=()=>Tn(w,i&&i.suspense):(w.pre=!0,i&&(w.id=i.uid),m=()=>xu(w));const b=new nf(u,m);t?n?w():g=b.run():o==="post"?Tn(b.run.bind(b),i&&i.suspense):b.run();const _=()=>{b.stop(),i&&i.scope&&Qd(i.scope.effects,b)};return v&&v.push(_),_}function TC(e,t,n){const r=this.proxy,o=Ge(e)?e.includes(".")?Cb(r,e):()=>r[e]:e.bind(r,r);let a;Ke(t)?a=t:(a=t.handler,n=t);const l=Zt;Ka(this);const s=ff(o,a.bind(r),n);return l?Ka(l):ra(),s}function Cb(e,t){const n=t.split(".");return()=>{let r=e;for(let o=0;o{Jo(n,t)});else if(qg(e))for(const n in e)Jo(e[n],t);return e}function vt(e,t){const n=sn;if(n===null)return e;const r=Mu(n)||n.proxy,o=e.dirs||(e.dirs=[]);for(let a=0;a{e.isMounted=!0}),rn(()=>{e.isUnmounting=!0}),e}const Wn=[Function,Array],Sb={mode:String,appear:Boolean,persisted:Boolean,onBeforeEnter:Wn,onEnter:Wn,onAfterEnter:Wn,onEnterCancelled:Wn,onBeforeLeave:Wn,onLeave:Wn,onAfterLeave:Wn,onLeaveCancelled:Wn,onBeforeAppear:Wn,onAppear:Wn,onAfterAppear:Wn,onAppearCancelled:Wn},xC={name:"BaseTransition",props:Sb,setup(e,{slots:t}){const n=lt(),r=kb();let o;return()=>{const a=t.default&&pf(t.default(),!0);if(!a||!a.length)return;let l=a[0];if(a.length>1){for(const g of a)if(g.type!==yn){l=g;break}}const s=gt(e),{mode:i}=s;if(r.isLeaving)return lc(l);const u=em(l);if(!u)return lc(l);const d=rs(u,s,r,n);os(u,d);const f=n.subTree,h=f&&em(f);let p=!1;const{getTransitionKey:v}=u.type;if(v){const g=v();o===void 0?o=g:g!==o&&(o=g,p=!0)}if(h&&h.type!==yn&&(!Yo(u,h)||p)){const g=rs(h,s,r,n);if(os(h,g),i==="out-in")return r.isLeaving=!0,g.afterLeave=()=>{r.isLeaving=!1,n.update.active!==!1&&n.update()},lc(l);i==="in-out"&&u.type!==yn&&(g.delayLeave=(w,m,b)=>{const _=Eb(r,h);_[String(h.key)]=h,w._leaveCb=()=>{m(),w._leaveCb=void 0,delete d.delayedLeave},d.delayedLeave=b})}return l}}},OC=xC;function Eb(e,t){const{leavingVNodes:n}=e;let r=n.get(t.type);return r||(r=Object.create(null),n.set(t.type,r)),r}function rs(e,t,n,r){const{appear:o,mode:a,persisted:l=!1,onBeforeEnter:s,onEnter:i,onAfterEnter:u,onEnterCancelled:d,onBeforeLeave:f,onLeave:h,onAfterLeave:p,onLeaveCancelled:v,onBeforeAppear:g,onAppear:w,onAfterAppear:m,onAppearCancelled:b}=t,_=String(e.key),y=Eb(n,e),C=(S,R)=>{S&&qn(S,r,9,R)},k=(S,R)=>{const L=R[1];C(S,R),De(S)?S.every(F=>F.length<=1)&&L():S.length<=1&&L()},E={mode:a,persisted:l,beforeEnter(S){let R=s;if(!n.isMounted)if(o)R=g||s;else return;S._leaveCb&&S._leaveCb(!0);const L=y[_];L&&Yo(e,L)&&L.el._leaveCb&&L.el._leaveCb(),C(R,[S])},enter(S){let R=i,L=u,F=d;if(!n.isMounted)if(o)R=w||i,L=m||u,F=b||d;else return;let N=!1;const A=S._enterCb=M=>{N||(N=!0,M?C(F,[S]):C(L,[S]),E.delayedLeave&&E.delayedLeave(),S._enterCb=void 0)};R?k(R,[S,A]):A()},leave(S,R){const L=String(e.key);if(S._enterCb&&S._enterCb(!0),n.isUnmounting)return R();C(f,[S]);let F=!1;const N=S._leaveCb=A=>{F||(F=!0,R(),A?C(v,[S]):C(p,[S]),S._leaveCb=void 0,y[L]===e&&delete y[L])};y[L]=e,h?k(h,[S,N]):N()},clone(S){return rs(S,t,n,r)}};return E}function lc(e){if(Os(e))return e=Xr(e),e.children=null,e}function em(e){return Os(e)?e.children?e.children[0]:void 0:e}function os(e,t){e.shapeFlag&6&&e.component?os(e.component.subTree,t):e.shapeFlag&128?(e.ssContent.transition=t.clone(e.ssContent),e.ssFallback.transition=t.clone(e.ssFallback)):e.transition=t}function pf(e,t=!1,n){let r=[],o=0;for(let a=0;a1)for(let a=0;aWt({name:e.name},t,{setup:e}))():e}const Ba=e=>!!e.type.__asyncLoader;function Jt(e){Ke(e)&&(e={loader:e});const{loader:t,loadingComponent:n,errorComponent:r,delay:o=200,timeout:a,suspensible:l=!0,onError:s}=e;let i=null,u,d=0;const f=()=>(d++,i=null,h()),h=()=>{let p;return i||(p=i=t().catch(v=>{if(v=v instanceof Error?v:new Error(String(v)),s)return new Promise((g,w)=>{s(v,()=>g(f()),()=>w(v),d+1)});throw v}).then(v=>p!==i&&i?i:(v&&(v.__esModule||v[Symbol.toStringTag]==="Module")&&(v=v.default),u=v,v)))};return se({name:"AsyncComponentWrapper",__asyncLoader:h,get __asyncResolved(){return u},setup(){const p=Zt;if(u)return()=>sc(u,p);const v=b=>{i=null,xs(b,p,13,!r)};if(l&&p.suspense||qa)return h().then(b=>()=>sc(b,p)).catch(b=>(v(b),()=>r?Q(r,{error:b}):null));const g=B(!1),w=B(),m=B(!!o);return o&&setTimeout(()=>{m.value=!1},o),a!=null&&setTimeout(()=>{if(!g.value&&!w.value){const b=new Error(`Async component timed out after ${a}ms.`);v(b),w.value=b}},a),h().then(()=>{g.value=!0,p.parent&&Os(p.parent.vnode)&&xu(p.parent.update)}).catch(b=>{v(b),w.value=b}),()=>{if(g.value&&u)return sc(u,p);if(w.value&&r)return Q(r,{error:w.value});if(n&&!m.value)return Q(n)}}})}function sc(e,t){const{ref:n,props:r,children:o,ce:a}=t.vnode,l=Q(e,r,o);return l.ref=n,l.ce=a,delete t.vnode.ce,l}const Os=e=>e.type.__isKeepAlive;function AC(e,t){Tb(e,"a",t)}function $b(e,t){Tb(e,"da",t)}function Tb(e,t,n=Zt){const r=e.__wdc||(e.__wdc=()=>{let o=n;for(;o;){if(o.isDeactivated)return;o=o.parent}return e()});if(Iu(t,r,n),n){let o=n.parent;for(;o&&o.parent;)Os(o.parent.vnode)&&IC(r,t,n,o),o=o.parent}}function IC(e,t,n,r){const o=Iu(t,e,r,!0);Mo(()=>{Qd(r[t],o)},n)}function Iu(e,t,n=Zt,r=!1){if(n){const o=n[e]||(n[e]=[]),a=t.__weh||(t.__weh=(...l)=>{if(n.isUnmounted)return;dl(),Ka(n);const s=qn(t,n,e,l);return ra(),fl(),s});return r?o.unshift(a):o.push(a),a}}const eo=e=>(t,n=Zt)=>(!qa||e==="sp")&&Iu(e,(...r)=>t(...r),n),As=eo("bm"),dt=eo("m"),PC=eo("bu"),pl=eo("u"),rn=eo("bum"),Mo=eo("um"),LC=eo("sp"),MC=eo("rtg"),RC=eo("rtc");function NC(e,t=Zt){Iu("ec",e,t)}const mf="components",DC="directives";function Ve(e,t){return vf(mf,e,!0,t)||e}const xb=Symbol.for("v-ndc");function Lt(e){return Ge(e)?vf(mf,e,!1)||e:e||xb}function hf(e){return vf(DC,e)}function vf(e,t,n=!0,r=!1){const o=sn||Zt;if(o){const a=o.type;if(e===mf){const s=pk(a,!1);if(s&&(s===t||s===cr(t)||s===$u(cr(t))))return a}const l=tm(o[e]||a[e],t)||tm(o.appContext[e],t);return!l&&r?a:l}}function tm(e,t){return e&&(e[t]||e[cr(t)]||e[$u(cr(t))])}function it(e,t,n,r){let o;const a=n&&n[r];if(De(e)||Ge(e)){o=new Array(e.length);for(let l=0,s=e.length;lt(l,s,void 0,a&&a[s]));else{const l=Object.keys(e);o=new Array(l.length);for(let s=0,i=l.length;s{const a=r.fn(...o);return a&&(a.key=r.key),a}:r.fn)}return e}function pe(e,t,n={},r,o){if(sn.isCE||sn.parent&&Ba(sn.parent)&&sn.parent.isCE)return t!=="default"&&(n.name=t),Q("slot",n,r&&r());let a=e[t];a&&a._c&&(a._d=!1),x();const l=a&&Ob(a(n)),s=ce(Pe,{key:n.key||l&&l.key||`_${t}`},l||(r?r():[]),l&&e._===1?64:-2);return!o&&s.scopeId&&(s.slotScopeIds=[s.scopeId+"-s"]),a&&a._c&&(a._d=!0),s}function Ob(e){return e.some(t=>Ua(t)?!(t.type===yn||t.type===Pe&&!Ob(t.children)):!0)?e:null}function FC(e,t){const n={};for(const r in e)n[t&&/[A-Z]/.test(r)?`on:${r}`:Ti(r)]=e[r];return n}const Uc=e=>e?Wb(e)?Mu(e)||e.proxy:Uc(e.parent):null,Nl=Wt(Object.create(null),{$:e=>e,$el:e=>e.vnode.el,$data:e=>e.data,$props:e=>e.props,$attrs:e=>e.attrs,$slots:e=>e.slots,$refs:e=>e.refs,$parent:e=>Uc(e.parent),$root:e=>Uc(e.root),$emit:e=>e.emit,$options:e=>gf(e),$forceUpdate:e=>e.f||(e.f=()=>xu(e.update)),$nextTick:e=>e.n||(e.n=qe.bind(e.proxy)),$watch:e=>TC.bind(e)}),ic=(e,t)=>e!==Ft&&!e.__isScriptSetup&&ft(e,t),VC={get({_:e},t){const{ctx:n,setupState:r,data:o,props:a,accessCache:l,type:s,appContext:i}=e;let u;if(t[0]!=="$"){const p=l[t];if(p!==void 0)switch(p){case 1:return r[t];case 2:return o[t];case 4:return n[t];case 3:return a[t]}else{if(ic(r,t))return l[t]=1,r[t];if(o!==Ft&&ft(o,t))return l[t]=2,o[t];if((u=e.propsOptions[0])&&ft(u,t))return l[t]=3,a[t];if(n!==Ft&&ft(n,t))return l[t]=4,n[t];Kc&&(l[t]=0)}}const d=Nl[t];let f,h;if(d)return t==="$attrs"&&Ln(e,"get",t),d(e);if((f=s.__cssModules)&&(f=f[t]))return f;if(n!==Ft&&ft(n,t))return l[t]=4,n[t];if(h=i.config.globalProperties,ft(h,t))return h[t]},set({_:e},t,n){const{data:r,setupState:o,ctx:a}=e;return ic(o,t)?(o[t]=n,!0):r!==Ft&&ft(r,t)?(r[t]=n,!0):ft(e.props,t)||t[0]==="$"&&t.slice(1)in e?!1:(a[t]=n,!0)},has({_:{data:e,setupState:t,accessCache:n,ctx:r,appContext:o,propsOptions:a}},l){let s;return!!n[l]||e!==Ft&&ft(e,l)||ic(t,l)||(s=a[0])&&ft(s,l)||ft(r,l)||ft(Nl,l)||ft(o.config.globalProperties,l)},defineProperty(e,t,n){return n.get!=null?e._.accessCache[t]=0:ft(n,"value")&&this.set(e,t,n.value,null),Reflect.defineProperty(e,t,n)}};function to(){return Ab().slots}function Pu(){return Ab().attrs}function Ab(){const e=lt();return e.setupContext||(e.setupContext=Kb(e))}function nm(e){return De(e)?e.reduce((t,n)=>(t[n]=null,t),{}):e}let Kc=!0;function BC(e){const t=gf(e),n=e.proxy,r=e.ctx;Kc=!1,t.beforeCreate&&rm(t.beforeCreate,e,"bc");const{data:o,computed:a,methods:l,watch:s,provide:i,inject:u,created:d,beforeMount:f,mounted:h,beforeUpdate:p,updated:v,activated:g,deactivated:w,beforeDestroy:m,beforeUnmount:b,destroyed:_,unmounted:y,render:C,renderTracked:k,renderTriggered:E,errorCaptured:S,serverPrefetch:R,expose:L,inheritAttrs:F,components:N,directives:A,filters:M}=t;if(u&&zC(u,r,null),l)for(const V in l){const X=l[V];Ke(X)&&(r[V]=X.bind(n))}if(o){const V=o.call(n,n);ht(V)&&(e.data=Xt(V))}if(Kc=!0,a)for(const V in a){const X=a[V],I=Ke(X)?X.bind(n,n):Ke(X.get)?X.get.bind(n,n):en,Y=!Ke(X)&&Ke(X.set)?X.set.bind(n):en,ee=O({get:I,set:Y});Object.defineProperty(r,V,{enumerable:!0,configurable:!0,get:()=>ee.value,set:W=>ee.value=W})}if(s)for(const V in s)Ib(s[V],r,n,V);if(i){const V=Ke(i)?i.call(n):i;Reflect.ownKeys(V).forEach(X=>{yt(X,V[X])})}d&&rm(d,e,"c");function j(V,X){De(X)?X.forEach(I=>V(I.bind(n))):X&&V(X.bind(n))}if(j(As,f),j(dt,h),j(PC,p),j(pl,v),j(AC,g),j($b,w),j(NC,S),j(RC,k),j(MC,E),j(rn,b),j(Mo,y),j(LC,R),De(L))if(L.length){const V=e.exposed||(e.exposed={});L.forEach(X=>{Object.defineProperty(V,X,{get:()=>n[X],set:I=>n[X]=I})})}else e.exposed||(e.exposed={});C&&e.render===en&&(e.render=C),F!=null&&(e.inheritAttrs=F),N&&(e.components=N),A&&(e.directives=A)}function zC(e,t,n=en){De(e)&&(e=qc(e));for(const r in e){const o=e[r];let a;ht(o)?"default"in o?a=Re(o.from||r,o.default,!0):a=Re(o.from||r):a=Re(o),mt(a)?Object.defineProperty(t,r,{enumerable:!0,configurable:!0,get:()=>a.value,set:l=>a.value=l}):t[r]=a}}function rm(e,t,n){qn(De(e)?e.map(r=>r.bind(t.proxy)):e.bind(t.proxy),t,n)}function Ib(e,t,n,r){const o=r.includes(".")?Cb(n,r):()=>n[r];if(Ge(e)){const a=t[e];Ke(a)&&$e(o,a)}else if(Ke(e))$e(o,e.bind(n));else if(ht(e))if(De(e))e.forEach(a=>Ib(a,t,n,r));else{const a=Ke(e.handler)?e.handler.bind(n):t[e.handler];Ke(a)&&$e(o,a,e)}}function gf(e){const t=e.type,{mixins:n,extends:r}=t,{mixins:o,optionsCache:a,config:{optionMergeStrategies:l}}=e.appContext,s=a.get(t);let i;return s?i=s:!o.length&&!n&&!r?i=t:(i={},o.length&&o.forEach(u=>tu(i,u,l,!0)),tu(i,t,l)),ht(t)&&a.set(t,i),i}function tu(e,t,n,r=!1){const{mixins:o,extends:a}=t;a&&tu(e,a,n,!0),o&&o.forEach(l=>tu(e,l,n,!0));for(const l in t)if(!(r&&l==="expose")){const s=HC[l]||n&&n[l];e[l]=s?s(e[l],t[l]):t[l]}return e}const HC={data:om,props:am,emits:am,methods:Ll,computed:Ll,beforeCreate:gn,created:gn,beforeMount:gn,mounted:gn,beforeUpdate:gn,updated:gn,beforeDestroy:gn,beforeUnmount:gn,destroyed:gn,unmounted:gn,activated:gn,deactivated:gn,errorCaptured:gn,serverPrefetch:gn,components:Ll,directives:Ll,watch:WC,provide:om,inject:jC};function om(e,t){return t?e?function(){return Wt(Ke(e)?e.call(this,this):e,Ke(t)?t.call(this,this):t)}:t:e}function jC(e,t){return Ll(qc(e),qc(t))}function qc(e){if(De(e)){const t={};for(let n=0;n1)return n&&Ke(t)?t.call(r&&r.proxy):t}}function qC(e,t,n,r=!1){const o={},a={};Xi(a,Lu,1),e.propsDefaults=Object.create(null),Lb(e,t,o,a);for(const l in e.propsOptions[0])l in o||(o[l]=void 0);n?e.props=r?o:lf(o):e.type.props?e.props=o:e.props=a,e.attrs=a}function YC(e,t,n,r){const{props:o,attrs:a,vnode:{patchFlag:l}}=e,s=gt(o),[i]=e.propsOptions;let u=!1;if((r||l>0)&&!(l&16)){if(l&8){const d=e.vnode.dynamicProps;for(let f=0;f{i=!0;const[h,p]=Mb(f,t,!0);Wt(l,h),p&&s.push(...p)};!n&&t.mixins.length&&t.mixins.forEach(d),e.extends&&d(e.extends),e.mixins&&e.mixins.forEach(d)}if(!a&&!i)return ht(e)&&r.set(e,Na),Na;if(De(a))for(let d=0;d-1,p[1]=g<0||v-1||ft(p,"default"))&&s.push(f)}}}const u=[l,s];return ht(e)&&r.set(e,u),u}function lm(e){return e[0]!=="$"}function sm(e){const t=e&&e.toString().match(/^\s*(function|class) (\w+)/);return t?t[2]:e===null?"null":""}function im(e,t){return sm(e)===sm(t)}function um(e,t){return De(t)?t.findIndex(n=>im(n,e)):Ke(t)&&im(t,e)?0:-1}const Rb=e=>e[0]==="_"||e==="$stable",bf=e=>De(e)?e.map(or):[or(e)],GC=(e,t,n)=>{if(t._n)return t;const r=G((...o)=>bf(t(...o)),n);return r._c=!1,r},Nb=(e,t,n)=>{const r=e._ctx;for(const o in e){if(Rb(o))continue;const a=e[o];if(Ke(a))t[o]=GC(o,a,r);else if(a!=null){const l=bf(a);t[o]=()=>l}}},Db=(e,t)=>{const n=bf(t);e.slots.default=()=>n},XC=(e,t)=>{if(e.vnode.shapeFlag&32){const n=t._;n?(e.slots=gt(t),Xi(t,"_",n)):Nb(t,e.slots={})}else e.slots={},t&&Db(e,t);Xi(e.slots,Lu,1)},JC=(e,t,n)=>{const{vnode:r,slots:o}=e;let a=!0,l=Ft;if(r.shapeFlag&32){const s=t._;s?n&&s===1?a=!1:(Wt(o,t),!n&&s===1&&delete o._):(a=!t.$stable,Nb(t,o)),l=t}else t&&(Db(e,t),l={default:1});if(a)for(const s in o)!Rb(s)&&!(s in l)&&delete o[s]};function ru(e,t,n,r,o=!1){if(De(e)){e.forEach((h,p)=>ru(h,t&&(De(t)?t[p]:t),n,r,o));return}if(Ba(r)&&!o)return;const a=r.shapeFlag&4?Mu(r.component)||r.component.proxy:r.el,l=o?null:a,{i:s,r:i}=e,u=t&&t.r,d=s.refs===Ft?s.refs={}:s.refs,f=s.setupState;if(u!=null&&u!==i&&(Ge(u)?(d[u]=null,ft(f,u)&&(f[u]=null)):mt(u)&&(u.value=null)),Ke(i))Eo(i,s,12,[l,d]);else{const h=Ge(i),p=mt(i);if(h||p){const v=()=>{if(e.f){const g=h?ft(f,i)?f[i]:d[i]:i.value;o?De(g)&&Qd(g,a):De(g)?g.includes(a)||g.push(a):h?(d[i]=[a],ft(f,i)&&(f[i]=d[i])):(i.value=[a],e.k&&(d[e.k]=i.value))}else h?(d[i]=l,ft(f,i)&&(f[i]=l)):p&&(i.value=l,e.k&&(d[e.k]=l))};l?(v.id=-1,Tn(v,n)):v()}}}let io=!1;const Qs=e=>/svg/.test(e.namespaceURI)&&e.tagName!=="foreignObject",ei=e=>e.nodeType===8;function ZC(e){const{mt:t,p:n,o:{patchProp:r,createText:o,nextSibling:a,parentNode:l,remove:s,insert:i,createComment:u}}=e,d=(m,b)=>{if(!b.hasChildNodes()){n(null,m,b),Qi(),b._vnode=m;return}io=!1,f(b.firstChild,m,null,null,null),Qi(),b._vnode=m,io&&console.error("Hydration completed but contains mismatches.")},f=(m,b,_,y,C,k=!1)=>{const E=ei(m)&&m.data==="[",S=()=>g(m,b,_,y,C,E),{type:R,ref:L,shapeFlag:F,patchFlag:N}=b;let A=m.nodeType;b.el=m,N===-2&&(k=!1,b.dynamicChildren=null);let M=null;switch(R){case Gr:A!==3?b.children===""?(i(b.el=o(""),l(m),m),M=m):M=S():(m.data!==b.children&&(io=!0,m.data=b.children),M=a(m));break;case yn:A!==8||E?M=S():M=a(m);break;case Fl:if(E&&(m=a(m),A=m.nodeType),A===1||A===3){M=m;const H=!b.children.length;for(let j=0;j{k=k||!!b.dynamicChildren;const{type:E,props:S,patchFlag:R,shapeFlag:L,dirs:F}=b,N=E==="input"&&F||E==="option";if(N||R!==-1){if(F&&kr(b,null,_,"created"),S)if(N||!k||R&48)for(const M in S)(N&&M.endsWith("value")||$s(M)&&!Rl(M))&&r(m,M,null,S[M],!1,void 0,_);else S.onClick&&r(m,"onClick",null,S.onClick,!1,void 0,_);let A;if((A=S&&S.onVnodeBeforeMount)&&Un(A,_,b),F&&kr(b,null,_,"beforeMount"),((A=S&&S.onVnodeMounted)||F)&&wb(()=>{A&&Un(A,_,b),F&&kr(b,null,_,"mounted")},y),L&16&&!(S&&(S.innerHTML||S.textContent))){let M=p(m.firstChild,b,m,_,y,C,k);for(;M;){io=!0;const H=M;M=M.nextSibling,s(H)}}else L&8&&m.textContent!==b.children&&(io=!0,m.textContent=b.children)}return m.nextSibling},p=(m,b,_,y,C,k,E)=>{E=E||!!b.dynamicChildren;const S=b.children,R=S.length;for(let L=0;L{const{slotScopeIds:E}=b;E&&(C=C?C.concat(E):E);const S=l(m),R=p(a(m),b,S,_,y,C,k);return R&&ei(R)&&R.data==="]"?a(b.anchor=R):(io=!0,i(b.anchor=u("]"),S,R),R)},g=(m,b,_,y,C,k)=>{if(io=!0,b.el=null,k){const R=w(m);for(;;){const L=a(m);if(L&&L!==R)s(L);else break}}const E=a(m),S=l(m);return s(m),n(null,b,S,E,_,y,Qs(S),C),E},w=m=>{let b=0;for(;m;)if(m=a(m),m&&ei(m)&&(m.data==="["&&b++,m.data==="]")){if(b===0)return a(m);b--}return m};return[d,f]}const Tn=wb;function QC(e){return Fb(e)}function ek(e){return Fb(e,ZC)}function Fb(e,t){const n=Bc();n.__VUE__=!0;const{insert:r,remove:o,patchProp:a,createElement:l,createText:s,createComment:i,setText:u,setElementText:d,parentNode:f,nextSibling:h,setScopeId:p=en,insertStaticContent:v}=e,g=(P,$,T,z=null,Z=null,oe=null,_e=!1,we=null,he=!!$.dynamicChildren)=>{if(P===$)return;P&&!Yo(P,$)&&(z=J(P),W(P,Z,oe,!0),P=null),$.patchFlag===-2&&(he=!1,$.dynamicChildren=null);const{type:ke,ref:Me,shapeFlag:ne}=$;switch(ke){case Gr:w(P,$,T,z);break;case yn:m(P,$,T,z);break;case Fl:P==null&&b($,T,z,_e);break;case Pe:N(P,$,T,z,Z,oe,_e,we,he);break;default:ne&1?C(P,$,T,z,Z,oe,_e,we,he):ne&6?A(P,$,T,z,Z,oe,_e,we,he):(ne&64||ne&128)&&ke.process(P,$,T,z,Z,oe,_e,we,he,ae)}Me!=null&&Z&&ru(Me,P&&P.ref,oe,$||P,!$)},w=(P,$,T,z)=>{if(P==null)r($.el=s($.children),T,z);else{const Z=$.el=P.el;$.children!==P.children&&u(Z,$.children)}},m=(P,$,T,z)=>{P==null?r($.el=i($.children||""),T,z):$.el=P.el},b=(P,$,T,z)=>{[P.el,P.anchor]=v(P.children,$,T,z,P.el,P.anchor)},_=({el:P,anchor:$},T,z)=>{let Z;for(;P&&P!==$;)Z=h(P),r(P,T,z),P=Z;r($,T,z)},y=({el:P,anchor:$})=>{let T;for(;P&&P!==$;)T=h(P),o(P),P=T;o($)},C=(P,$,T,z,Z,oe,_e,we,he)=>{_e=_e||$.type==="svg",P==null?k($,T,z,Z,oe,_e,we,he):R(P,$,Z,oe,_e,we,he)},k=(P,$,T,z,Z,oe,_e,we)=>{let he,ke;const{type:Me,props:ne,shapeFlag:ue,transition:ie,dirs:Oe}=P;if(he=P.el=l(P.type,oe,ne&&ne.is,ne),ue&8?d(he,P.children):ue&16&&S(P.children,he,null,z,Z,oe&&Me!=="foreignObject",_e,we),Oe&&kr(P,null,z,"created"),E(he,P,P.scopeId,_e,z),ne){for(const Xe in ne)Xe!=="value"&&!Rl(Xe)&&a(he,Xe,null,ne[Xe],oe,P.children,z,Z,ge);"value"in ne&&a(he,"value",null,ne.value),(ke=ne.onVnodeBeforeMount)&&Un(ke,z,P)}Oe&&kr(P,null,z,"beforeMount");const We=(!Z||Z&&!Z.pendingBranch)&&ie&&!ie.persisted;We&&ie.beforeEnter(he),r(he,$,T),((ke=ne&&ne.onVnodeMounted)||We||Oe)&&Tn(()=>{ke&&Un(ke,z,P),We&&ie.enter(he),Oe&&kr(P,null,z,"mounted")},Z)},E=(P,$,T,z,Z)=>{if(T&&p(P,T),z)for(let oe=0;oe{for(let ke=he;ke{const we=$.el=P.el;let{patchFlag:he,dynamicChildren:ke,dirs:Me}=$;he|=P.patchFlag&16;const ne=P.props||Ft,ue=$.props||Ft;let ie;T&&Bo(T,!1),(ie=ue.onVnodeBeforeUpdate)&&Un(ie,T,$,P),Me&&kr($,P,T,"beforeUpdate"),T&&Bo(T,!0);const Oe=Z&&$.type!=="foreignObject";if(ke?L(P.dynamicChildren,ke,we,T,z,Oe,oe):_e||X(P,$,we,null,T,z,Oe,oe,!1),he>0){if(he&16)F(we,$,ne,ue,T,z,Z);else if(he&2&&ne.class!==ue.class&&a(we,"class",null,ue.class,Z),he&4&&a(we,"style",ne.style,ue.style,Z),he&8){const We=$.dynamicProps;for(let Xe=0;Xe{ie&&Un(ie,T,$,P),Me&&kr($,P,T,"updated")},z)},L=(P,$,T,z,Z,oe,_e)=>{for(let we=0;we<$.length;we++){const he=P[we],ke=$[we],Me=he.el&&(he.type===Pe||!Yo(he,ke)||he.shapeFlag&70)?f(he.el):T;g(he,ke,Me,null,z,Z,oe,_e,!0)}},F=(P,$,T,z,Z,oe,_e)=>{if(T!==z){if(T!==Ft)for(const we in T)!Rl(we)&&!(we in z)&&a(P,we,T[we],null,_e,$.children,Z,oe,ge);for(const we in z){if(Rl(we))continue;const he=z[we],ke=T[we];he!==ke&&we!=="value"&&a(P,we,ke,he,_e,$.children,Z,oe,ge)}"value"in z&&a(P,"value",T.value,z.value)}},N=(P,$,T,z,Z,oe,_e,we,he)=>{const ke=$.el=P?P.el:s(""),Me=$.anchor=P?P.anchor:s("");let{patchFlag:ne,dynamicChildren:ue,slotScopeIds:ie}=$;ie&&(we=we?we.concat(ie):ie),P==null?(r(ke,T,z),r(Me,T,z),S($.children,T,Me,Z,oe,_e,we,he)):ne>0&&ne&64&&ue&&P.dynamicChildren?(L(P.dynamicChildren,ue,T,Z,oe,_e,we),($.key!=null||Z&&$===Z.subTree)&&yf(P,$,!0)):X(P,$,T,Me,Z,oe,_e,we,he)},A=(P,$,T,z,Z,oe,_e,we,he)=>{$.slotScopeIds=we,P==null?$.shapeFlag&512?Z.ctx.activate($,T,z,_e,he):M($,T,z,Z,oe,_e,he):H(P,$,he)},M=(P,$,T,z,Z,oe,_e)=>{const we=P.component=uk(P,z,Z);if(Os(P)&&(we.ctx.renderer=ae),ck(we),we.asyncDep){if(Z&&Z.registerDep(we,j),!P.el){const he=we.subTree=Q(yn);m(null,he,$,T)}return}j(we,P,$,T,Z,oe,_e)},H=(P,$,T)=>{const z=$.component=P.component;if(SC(P,$,T))if(z.asyncDep&&!z.asyncResolved){V(z,$,T);return}else z.next=$,vC(z.update),z.update();else $.el=P.el,z.vnode=$},j=(P,$,T,z,Z,oe,_e)=>{const we=()=>{if(P.isMounted){let{next:Me,bu:ne,u:ue,parent:ie,vnode:Oe}=P,We=Me,Xe;Bo(P,!1),Me?(Me.el=Oe.el,V(P,Me,_e)):Me=Oe,ne&&xi(ne),(Xe=Me.props&&Me.props.onVnodeBeforeUpdate)&&Un(Xe,ie,Me,Oe),Bo(P,!0);const fe=ac(P),ve=P.subTree;P.subTree=fe,g(ve,fe,f(ve.el),J(ve),P,Z,oe),Me.el=fe.el,We===null&&EC(P,fe.el),ue&&Tn(ue,Z),(Xe=Me.props&&Me.props.onVnodeUpdated)&&Tn(()=>Un(Xe,ie,Me,Oe),Z)}else{let Me;const{el:ne,props:ue}=$,{bm:ie,m:Oe,parent:We}=P,Xe=Ba($);if(Bo(P,!1),ie&&xi(ie),!Xe&&(Me=ue&&ue.onVnodeBeforeMount)&&Un(Me,We,$),Bo(P,!0),ne&&me){const fe=()=>{P.subTree=ac(P),me(ne,P.subTree,P,Z,null)};Xe?$.type.__asyncLoader().then(()=>!P.isUnmounted&&fe()):fe()}else{const fe=P.subTree=ac(P);g(null,fe,T,z,P,Z,oe),$.el=fe.el}if(Oe&&Tn(Oe,Z),!Xe&&(Me=ue&&ue.onVnodeMounted)){const fe=$;Tn(()=>Un(Me,We,fe),Z)}($.shapeFlag&256||We&&Ba(We.vnode)&&We.vnode.shapeFlag&256)&&P.a&&Tn(P.a,Z),P.isMounted=!0,$=T=z=null}},he=P.effect=new nf(we,()=>xu(ke),P.scope),ke=P.update=()=>he.run();ke.id=P.uid,Bo(P,!0),ke()},V=(P,$,T)=>{$.component=P;const z=P.vnode.props;P.vnode=$,P.next=null,YC(P,$.props,z,T),JC(P,$.children,T),dl(),Zp(),fl()},X=(P,$,T,z,Z,oe,_e,we,he=!1)=>{const ke=P&&P.children,Me=P?P.shapeFlag:0,ne=$.children,{patchFlag:ue,shapeFlag:ie}=$;if(ue>0){if(ue&128){Y(ke,ne,T,z,Z,oe,_e,we,he);return}else if(ue&256){I(ke,ne,T,z,Z,oe,_e,we,he);return}}ie&8?(Me&16&&ge(ke,Z,oe),ne!==ke&&d(T,ne)):Me&16?ie&16?Y(ke,ne,T,z,Z,oe,_e,we,he):ge(ke,Z,oe,!0):(Me&8&&d(T,""),ie&16&&S(ne,T,z,Z,oe,_e,we,he))},I=(P,$,T,z,Z,oe,_e,we,he)=>{P=P||Na,$=$||Na;const ke=P.length,Me=$.length,ne=Math.min(ke,Me);let ue;for(ue=0;ueMe?ge(P,Z,oe,!0,!1,ne):S($,T,z,Z,oe,_e,we,he,ne)},Y=(P,$,T,z,Z,oe,_e,we,he)=>{let ke=0;const Me=$.length;let ne=P.length-1,ue=Me-1;for(;ke<=ne&&ke<=ue;){const ie=P[ke],Oe=$[ke]=he?go($[ke]):or($[ke]);if(Yo(ie,Oe))g(ie,Oe,T,null,Z,oe,_e,we,he);else break;ke++}for(;ke<=ne&&ke<=ue;){const ie=P[ne],Oe=$[ue]=he?go($[ue]):or($[ue]);if(Yo(ie,Oe))g(ie,Oe,T,null,Z,oe,_e,we,he);else break;ne--,ue--}if(ke>ne){if(ke<=ue){const ie=ue+1,Oe=ieue)for(;ke<=ne;)W(P[ke],Z,oe,!0),ke++;else{const ie=ke,Oe=ke,We=new Map;for(ke=Oe;ke<=ue;ke++){const q=$[ke]=he?go($[ke]):or($[ke]);q.key!=null&&We.set(q.key,ke)}let Xe,fe=0;const ve=ue-Oe+1;let Ce=!1,Ye=0;const Se=new Array(ve);for(ke=0;ke=ve){W(q,Z,oe,!0);continue}let Ie;if(q.key!=null)Ie=We.get(q.key);else for(Xe=Oe;Xe<=ue;Xe++)if(Se[Xe-Oe]===0&&Yo(q,$[Xe])){Ie=Xe;break}Ie===void 0?W(q,Z,oe,!0):(Se[Ie-Oe]=ke+1,Ie>=Ye?Ye=Ie:Ce=!0,g(q,$[Ie],T,null,Z,oe,_e,we,he),fe++)}const Ae=Ce?tk(Se):Na;for(Xe=Ae.length-1,ke=ve-1;ke>=0;ke--){const q=Oe+ke,Ie=$[q],et=q+1{const{el:oe,type:_e,transition:we,children:he,shapeFlag:ke}=P;if(ke&6){ee(P.component.subTree,$,T,z);return}if(ke&128){P.suspense.move($,T,z);return}if(ke&64){_e.move(P,$,T,ae);return}if(_e===Pe){r(oe,$,T);for(let ne=0;newe.enter(oe),Z);else{const{leave:ne,delayLeave:ue,afterLeave:ie}=we,Oe=()=>r(oe,$,T),We=()=>{ne(oe,()=>{Oe(),ie&&ie()})};ue?ue(oe,Oe,We):We()}else r(oe,$,T)},W=(P,$,T,z=!1,Z=!1)=>{const{type:oe,props:_e,ref:we,children:he,dynamicChildren:ke,shapeFlag:Me,patchFlag:ne,dirs:ue}=P;if(we!=null&&ru(we,null,T,P,!0),Me&256){$.ctx.deactivate(P);return}const ie=Me&1&&ue,Oe=!Ba(P);let We;if(Oe&&(We=_e&&_e.onVnodeBeforeUnmount)&&Un(We,$,P),Me&6)Te(P.component,T,z);else{if(Me&128){P.suspense.unmount(T,z);return}ie&&kr(P,null,$,"beforeUnmount"),Me&64?P.type.remove(P,$,T,Z,ae,z):ke&&(oe!==Pe||ne>0&&ne&64)?ge(ke,$,T,!1,!0):(oe===Pe&&ne&384||!Z&&Me&16)&&ge(he,$,T),z&&re(P)}(Oe&&(We=_e&&_e.onVnodeUnmounted)||ie)&&Tn(()=>{We&&Un(We,$,P),ie&&kr(P,null,$,"unmounted")},T)},re=P=>{const{type:$,el:T,anchor:z,transition:Z}=P;if($===Pe){be(T,z);return}if($===Fl){y(P);return}const oe=()=>{o(T),Z&&!Z.persisted&&Z.afterLeave&&Z.afterLeave()};if(P.shapeFlag&1&&Z&&!Z.persisted){const{leave:_e,delayLeave:we}=Z,he=()=>_e(T,oe);we?we(P.el,oe,he):he()}else oe()},be=(P,$)=>{let T;for(;P!==$;)T=h(P),o(P),P=T;o($)},Te=(P,$,T)=>{const{bum:z,scope:Z,update:oe,subTree:_e,um:we}=P;z&&xi(z),Z.stop(),oe&&(oe.active=!1,W(_e,P,$,T)),we&&Tn(we,$),Tn(()=>{P.isUnmounted=!0},$),$&&$.pendingBranch&&!$.isUnmounted&&P.asyncDep&&!P.asyncResolved&&P.suspenseId===$.pendingId&&($.deps--,$.deps===0&&$.resolve())},ge=(P,$,T,z=!1,Z=!1,oe=0)=>{for(let _e=oe;_eP.shapeFlag&6?J(P.component.subTree):P.shapeFlag&128?P.suspense.next():h(P.anchor||P.el),te=(P,$,T)=>{P==null?$._vnode&&W($._vnode,null,null,!0):g($._vnode||null,P,$,null,null,null,T),Zp(),Qi(),$._vnode=P},ae={p:g,um:W,m:ee,r:re,mt:M,mc:S,pc:X,pbc:L,n:J,o:e};let le,me;return t&&([le,me]=t(ae)),{render:te,hydrate:le,createApp:KC(te,le)}}function Bo({effect:e,update:t},n){e.allowRecurse=t.allowRecurse=n}function yf(e,t,n=!1){const r=e.children,o=t.children;if(De(r)&&De(o))for(let a=0;a>1,e[n[s]]0&&(t[r]=n[a-1]),n[a]=r)}}for(a=n.length,l=n[a-1];a-- >0;)n[a]=l,l=t[l];return n}const nk=e=>e.__isTeleport,Dl=e=>e&&(e.disabled||e.disabled===""),cm=e=>typeof SVGElement!="undefined"&&e instanceof SVGElement,Gc=(e,t)=>{const n=e&&e.to;return Ge(n)?t?t(n):null:n},rk={__isTeleport:!0,process(e,t,n,r,o,a,l,s,i,u){const{mc:d,pc:f,pbc:h,o:{insert:p,querySelector:v,createText:g,createComment:w}}=u,m=Dl(t.props);let{shapeFlag:b,children:_,dynamicChildren:y}=t;if(e==null){const C=t.el=g(""),k=t.anchor=g("");p(C,n,r),p(k,n,r);const E=t.target=Gc(t.props,v),S=t.targetAnchor=g("");E&&(p(S,E),l=l||cm(E));const R=(L,F)=>{b&16&&d(_,L,F,o,a,l,s,i)};m?R(n,k):E&&R(E,S)}else{t.el=e.el;const C=t.anchor=e.anchor,k=t.target=e.target,E=t.targetAnchor=e.targetAnchor,S=Dl(e.props),R=S?n:k,L=S?C:E;if(l=l||cm(k),y?(h(e.dynamicChildren,y,R,o,a,l,s),yf(e,t,!0)):i||f(e,t,R,L,o,a,l,s,!1),m)S||ti(t,n,C,u,1);else if((t.props&&t.props.to)!==(e.props&&e.props.to)){const F=t.target=Gc(t.props,v);F&&ti(t,F,null,u,0)}else S&&ti(t,k,E,u,1)}Bb(t)},remove(e,t,n,r,{um:o,o:{remove:a}},l){const{shapeFlag:s,children:i,anchor:u,targetAnchor:d,target:f,props:h}=e;if(f&&a(d),(l||!Dl(h))&&(a(u),s&16))for(let p=0;p0?sr||Na:null,ak(),as>0&&sr&&sr.push(e),e}function U(e,t,n,r,o,a){return zb(K(e,t,n,r,o,a,!0))}function ce(e,t,n,r,o){return zb(Q(e,t,n,r,o,!0))}function Ua(e){return e?e.__v_isVNode===!0:!1}function Yo(e,t){return e.type===t.type&&e.key===t.key}const Lu="__vInternal",Hb=({key:e})=>e!=null?e:null,Oi=({ref:e,ref_key:t,ref_for:n})=>(typeof e=="number"&&(e=""+e),e!=null?Ge(e)||mt(e)||Ke(e)?{i:sn,r:e,k:t,f:!!n}:e:null);function K(e,t=null,n=null,r=0,o=null,a=e===Pe?0:1,l=!1,s=!1){const i={__v_isVNode:!0,__v_skip:!0,type:e,props:t,key:t&&Hb(t),ref:t&&Oi(t),scopeId:Au,slotScopeIds:null,children:n,component:null,suspense:null,ssContent:null,ssFallback:null,dirs:null,transition:null,el:null,anchor:null,target:null,targetAnchor:null,staticCount:0,shapeFlag:a,patchFlag:r,dynamicProps:o,dynamicChildren:null,appContext:null,ctx:sn};return s?(_f(i,n),a&128&&e.normalize(i)):n&&(i.shapeFlag|=Ge(n)?8:16),as>0&&!l&&sr&&(i.patchFlag>0||a&6)&&i.patchFlag!==32&&sr.push(i),i}const Q=lk;function lk(e,t=null,n=null,r=0,o=null,a=!1){if((!e||e===xb)&&(e=yn),Ua(e)){const s=Xr(e,t,!0);return n&&_f(s,n),as>0&&!a&&sr&&(s.shapeFlag&6?sr[sr.indexOf(e)]=s:sr.push(s)),s.patchFlag|=-2,s}if(mk(e)&&(e=e.__vccOpts),t){t=jb(t);let{class:s,style:i}=t;s&&!Ge(s)&&(t.class=D(s)),ht(i)&&(cb(i)&&!De(i)&&(i=Wt({},i)),t.style=Qe(i))}const l=Ge(e)?1:$C(e)?128:nk(e)?64:ht(e)?4:Ke(e)?2:0;return K(e,t,n,r,o,l,a,!0)}function jb(e){return e?cb(e)||Lu in e?Wt({},e):e:null}function Xr(e,t,n=!1){const{props:r,ref:o,patchFlag:a,children:l}=e,s=t?Ht(r||{},t):r;return{__v_isVNode:!0,__v_skip:!0,type:e.type,props:s,key:s&&Hb(s),ref:t&&t.ref?n&&o?De(o)?o.concat(Oi(t)):[o,Oi(t)]:Oi(t):o,scopeId:e.scopeId,slotScopeIds:e.slotScopeIds,children:l,target:e.target,targetAnchor:e.targetAnchor,staticCount:e.staticCount,shapeFlag:e.shapeFlag,patchFlag:t&&e.type!==Pe?a===-1?16:a|16:a,dynamicProps:e.dynamicProps,dynamicChildren:e.dynamicChildren,appContext:e.appContext,dirs:e.dirs,transition:e.transition,component:e.component,suspense:e.suspense,ssContent:e.ssContent&&Xr(e.ssContent),ssFallback:e.ssFallback&&Xr(e.ssFallback),el:e.el,anchor:e.anchor,ctx:e.ctx,ce:e.ce}}function Je(e=" ",t=0){return Q(Gr,null,e,t)}function dG(e,t){const n=Q(Fl,null,e);return n.staticCount=t,n}function ye(e="",t=!1){return t?(x(),ce(yn,null,e)):Q(yn,null,e)}function or(e){return e==null||typeof e=="boolean"?Q(yn):De(e)?Q(Pe,null,e.slice()):typeof e=="object"?go(e):Q(Gr,null,String(e))}function go(e){return e.el===null&&e.patchFlag!==-1||e.memo?e:Xr(e)}function _f(e,t){let n=0;const{shapeFlag:r}=e;if(t==null)t=null;else if(De(t))n=16;else if(typeof t=="object")if(r&65){const o=t.default;o&&(o._c&&(o._d=!1),_f(e,o()),o._c&&(o._d=!0));return}else{n=32;const o=t._;!o&&!(Lu in t)?t._ctx=sn:o===3&&sn&&(sn.slots._===1?t._=1:(t._=2,e.patchFlag|=1024))}else Ke(t)?(t={default:t,_ctx:sn},n=32):(t=String(t),r&64?(n=16,t=[Je(t)]):n=8);e.children=t,e.shapeFlag|=n}function Ht(...e){const t={};for(let n=0;nZt||sn;let wf,Sa,fm="__VUE_INSTANCE_SETTERS__";(Sa=Bc()[fm])||(Sa=Bc()[fm]=[]),Sa.push(e=>Zt=e),wf=e=>{Sa.length>1?Sa.forEach(t=>t(e)):Sa[0](e)};const Ka=e=>{wf(e),e.scope.on()},ra=()=>{Zt&&Zt.scope.off(),wf(null)};function Wb(e){return e.vnode.shapeFlag&4}let qa=!1;function ck(e,t=!1){qa=t;const{props:n,children:r}=e.vnode,o=Wb(e);qC(e,n,o,t),XC(e,r);const a=o?dk(e,t):void 0;return qa=!1,a}function dk(e,t){const n=e.type;e.accessCache=Object.create(null),e.proxy=db(new Proxy(e.ctx,VC));const{setup:r}=n;if(r){const o=e.setupContext=r.length>1?Kb(e):null;Ka(e),dl();const a=Eo(r,e,0,[e.props,o]);if(fl(),ra(),Gi(a)){if(a.then(ra,ra),t)return a.then(l=>{pm(e,l,t)}).catch(l=>{xs(l,e,0)});e.asyncDep=a}else pm(e,a,t)}else Ub(e,t)}function pm(e,t,n){Ke(t)?e.type.__ssrInlineRender?e.ssrRender=t:e.render=t:ht(t)&&(e.setupState=mb(t)),Ub(e,n)}let mm;function Ub(e,t,n){const r=e.type;if(!e.render){if(!t&&mm&&!r.render){const o=r.template||gf(e).template;if(o){const{isCustomElement:a,compilerOptions:l}=e.appContext.config,{delimiters:s,compilerOptions:i}=r,u=Wt(Wt({isCustomElement:a,delimiters:s},l),i);r.render=mm(o,u)}}e.render=r.render||en}Ka(e),dl(),BC(e),fl(),ra()}function fk(e){return e.attrsProxy||(e.attrsProxy=new Proxy(e.attrs,{get(t,n){return Ln(e,"get","$attrs"),t[n]}}))}function Kb(e){const t=n=>{e.exposed=n||{}};return{get attrs(){return fk(e)},slots:e.slots,emit:e.emit,expose:t}}function Mu(e){if(e.exposed)return e.exposeProxy||(e.exposeProxy=new Proxy(mb(db(e.exposed)),{get(t,n){if(n in t)return t[n];if(n in Nl)return Nl[n](e)},has(t,n){return n in t||n in Nl}}))}function pk(e,t=!0){return Ke(e)?e.displayName||e.name:e.name||t&&e.__name}function mk(e){return Ke(e)&&"__vccOpts"in e}const O=(e,t)=>vb(e,t,qa);function He(e,t,n){const r=arguments.length;return r===2?ht(t)&&!De(t)?Ua(t)?Q(e,null,[t]):Q(e,t):Q(e,null,t):(r>3?n=Array.prototype.slice.call(arguments,2):r===3&&Ua(n)&&(n=[n]),Q(e,t,n))}const hk=Symbol.for("v-scx"),vk=()=>Re(hk),qb="3.3.4",gk="http://www.w3.org/2000/svg",Go=typeof document!="undefined"?document:null,hm=Go&&Go.createElement("template"),bk={insert:(e,t,n)=>{t.insertBefore(e,n||null)},remove:e=>{const t=e.parentNode;t&&t.removeChild(e)},createElement:(e,t,n,r)=>{const o=t?Go.createElementNS(gk,e):Go.createElement(e,n?{is:n}:void 0);return e==="select"&&r&&r.multiple!=null&&o.setAttribute("multiple",r.multiple),o},createText:e=>Go.createTextNode(e),createComment:e=>Go.createComment(e),setText:(e,t)=>{e.nodeValue=t},setElementText:(e,t)=>{e.textContent=t},parentNode:e=>e.parentNode,nextSibling:e=>e.nextSibling,querySelector:e=>Go.querySelector(e),setScopeId(e,t){e.setAttribute(t,"")},insertStaticContent(e,t,n,r,o,a){const l=n?n.previousSibling:t.lastChild;if(o&&(o===a||o.nextSibling))for(;t.insertBefore(o.cloneNode(!0),n),!(o===a||!(o=o.nextSibling)););else{hm.innerHTML=r?`${e}`:e;const s=hm.content;if(r){const i=s.firstChild;for(;i.firstChild;)s.appendChild(i.firstChild);s.removeChild(i)}t.insertBefore(s,n)}return[l?l.nextSibling:t.firstChild,n?n.previousSibling:t.lastChild]}};function yk(e,t,n){const r=e._vtc;r&&(t=(t?[t,...r]:[...r]).join(" ")),t==null?e.removeAttribute("class"):n?e.setAttribute("class",t):e.className=t}function _k(e,t,n){const r=e.style,o=Ge(n);if(n&&!o){if(t&&!Ge(t))for(const a in t)n[a]==null&&Xc(r,a,"");for(const a in n)Xc(r,a,n[a])}else{const a=r.display;o?t!==n&&(r.cssText=n):t&&e.removeAttribute("style"),"_vod"in e&&(r.display=a)}}const vm=/\s*!important$/;function Xc(e,t,n){if(De(n))n.forEach(r=>Xc(e,t,r));else if(n==null&&(n=""),t.startsWith("--"))e.setProperty(t,n);else{const r=wk(e,t);vm.test(n)?e.setProperty(fa(r),n.replace(vm,""),"important"):e[r]=n}}const gm=["Webkit","Moz","ms"],uc={};function wk(e,t){const n=uc[t];if(n)return n;let r=cr(t);if(r!=="filter"&&r in e)return uc[t]=r;r=$u(r);for(let o=0;occ||(Tk.then(()=>cc=0),cc=Date.now());function Ok(e,t){const n=r=>{if(!r._vts)r._vts=Date.now();else if(r._vts<=n.attached)return;qn(Ak(r,n.value),t,5,[r])};return n.value=e,n.attached=xk(),n}function Ak(e,t){if(De(t)){const n=e.stopImmediatePropagation;return e.stopImmediatePropagation=()=>{n.call(e),e._stopped=!0},t.map(r=>o=>!o._stopped&&r&&r(o))}else return t}const _m=/^on[a-z]/,Ik=(e,t,n,r,o=!1,a,l,s,i)=>{t==="class"?yk(e,r,o):t==="style"?_k(e,n,r):$s(t)?Zd(t)||Ek(e,t,n,r,l):(t[0]==="."?(t=t.slice(1),!0):t[0]==="^"?(t=t.slice(1),!1):Pk(e,t,r,o))?kk(e,t,r,a,l,s,i):(t==="true-value"?e._trueValue=r:t==="false-value"&&(e._falseValue=r),Ck(e,t,r,o))};function Pk(e,t,n,r){return r?!!(t==="innerHTML"||t==="textContent"||t in e&&_m.test(t)&&Ke(n)):t==="spellcheck"||t==="draggable"||t==="translate"||t==="form"||t==="list"&&e.tagName==="INPUT"||t==="type"&&e.tagName==="TEXTAREA"||_m.test(t)&&Ge(n)?!1:t in e}const uo="transition",kl="animation",Mn=(e,{slots:t})=>He(OC,Gb(e),t);Mn.displayName="Transition";const Yb={name:String,type:String,css:{type:Boolean,default:!0},duration:[String,Number,Object],enterFromClass:String,enterActiveClass:String,enterToClass:String,appearFromClass:String,appearActiveClass:String,appearToClass:String,leaveFromClass:String,leaveActiveClass:String,leaveToClass:String},Lk=Mn.props=Wt({},Sb,Yb),zo=(e,t=[])=>{De(e)?e.forEach(n=>n(...t)):e&&e(...t)},wm=e=>e?De(e)?e.some(t=>t.length>1):e.length>1:!1;function Gb(e){const t={};for(const N in e)N in Yb||(t[N]=e[N]);if(e.css===!1)return t;const{name:n="v",type:r,duration:o,enterFromClass:a=`${n}-enter-from`,enterActiveClass:l=`${n}-enter-active`,enterToClass:s=`${n}-enter-to`,appearFromClass:i=a,appearActiveClass:u=l,appearToClass:d=s,leaveFromClass:f=`${n}-leave-from`,leaveActiveClass:h=`${n}-leave-active`,leaveToClass:p=`${n}-leave-to`}=e,v=Mk(o),g=v&&v[0],w=v&&v[1],{onBeforeEnter:m,onEnter:b,onEnterCancelled:_,onLeave:y,onLeaveCancelled:C,onBeforeAppear:k=m,onAppear:E=b,onAppearCancelled:S=_}=t,R=(N,A,M)=>{mo(N,A?d:s),mo(N,A?u:l),M&&M()},L=(N,A)=>{N._isLeaving=!1,mo(N,f),mo(N,p),mo(N,h),A&&A()},F=N=>(A,M)=>{const H=N?E:b,j=()=>R(A,N,M);zo(H,[A,j]),Cm(()=>{mo(A,N?i:a),Fr(A,N?d:s),wm(H)||km(A,r,g,j)})};return Wt(t,{onBeforeEnter(N){zo(m,[N]),Fr(N,a),Fr(N,l)},onBeforeAppear(N){zo(k,[N]),Fr(N,i),Fr(N,u)},onEnter:F(!1),onAppear:F(!0),onLeave(N,A){N._isLeaving=!0;const M=()=>L(N,A);Fr(N,f),Jb(),Fr(N,h),Cm(()=>{!N._isLeaving||(mo(N,f),Fr(N,p),wm(y)||km(N,r,w,M))}),zo(y,[N,M])},onEnterCancelled(N){R(N,!1),zo(_,[N])},onAppearCancelled(N){R(N,!0),zo(S,[N])},onLeaveCancelled(N){L(N),zo(C,[N])}})}function Mk(e){if(e==null)return null;if(ht(e))return[dc(e.enter),dc(e.leave)];{const t=dc(e);return[t,t]}}function dc(e){return S2(e)}function Fr(e,t){t.split(/\s+/).forEach(n=>n&&e.classList.add(n)),(e._vtc||(e._vtc=new Set)).add(t)}function mo(e,t){t.split(/\s+/).forEach(r=>r&&e.classList.remove(r));const{_vtc:n}=e;n&&(n.delete(t),n.size||(e._vtc=void 0))}function Cm(e){requestAnimationFrame(()=>{requestAnimationFrame(e)})}let Rk=0;function km(e,t,n,r){const o=e._endId=++Rk,a=()=>{o===e._endId&&r()};if(n)return setTimeout(a,n);const{type:l,timeout:s,propCount:i}=Xb(e,t);if(!l)return r();const u=l+"end";let d=0;const f=()=>{e.removeEventListener(u,h),a()},h=p=>{p.target===e&&++d>=i&&f()};setTimeout(()=>{d(n[v]||"").split(", "),o=r(`${uo}Delay`),a=r(`${uo}Duration`),l=Sm(o,a),s=r(`${kl}Delay`),i=r(`${kl}Duration`),u=Sm(s,i);let d=null,f=0,h=0;t===uo?l>0&&(d=uo,f=l,h=a.length):t===kl?u>0&&(d=kl,f=u,h=i.length):(f=Math.max(l,u),d=f>0?l>u?uo:kl:null,h=d?d===uo?a.length:i.length:0);const p=d===uo&&/\b(transform|all)(,|$)/.test(r(`${uo}Property`).toString());return{type:d,timeout:f,propCount:h,hasTransform:p}}function Sm(e,t){for(;e.lengthEm(n)+Em(e[r])))}function Em(e){return Number(e.slice(0,-1).replace(",","."))*1e3}function Jb(){return document.body.offsetHeight}const Zb=new WeakMap,Qb=new WeakMap,e0={name:"TransitionGroup",props:Wt({},Lk,{tag:String,moveClass:String}),setup(e,{slots:t}){const n=lt(),r=kb();let o,a;return pl(()=>{if(!o.length)return;const l=e.moveClass||`${e.name||"v"}-move`;if(!zk(o[0].el,n.vnode.el,l))return;o.forEach(Fk),o.forEach(Vk);const s=o.filter(Bk);Jb(),s.forEach(i=>{const u=i.el,d=u.style;Fr(u,l),d.transform=d.webkitTransform=d.transitionDuration="";const f=u._moveCb=h=>{h&&h.target!==u||(!h||/transform$/.test(h.propertyName))&&(u.removeEventListener("transitionend",f),u._moveCb=null,mo(u,l))};u.addEventListener("transitionend",f)})}),()=>{const l=gt(e),s=Gb(l);let i=l.tag||Pe;o=a,a=t.default?pf(t.default()):[];for(let u=0;udelete e.mode;e0.props;const Dk=e0;function Fk(e){const t=e.el;t._moveCb&&t._moveCb(),t._enterCb&&t._enterCb()}function Vk(e){Qb.set(e,e.el.getBoundingClientRect())}function Bk(e){const t=Zb.get(e),n=Qb.get(e),r=t.left-n.left,o=t.top-n.top;if(r||o){const a=e.el.style;return a.transform=a.webkitTransform=`translate(${r}px,${o}px)`,a.transitionDuration="0s",e}}function zk(e,t,n){const r=e.cloneNode();e._vtc&&e._vtc.forEach(l=>{l.split(/\s+/).forEach(s=>s&&r.classList.remove(s))}),n.split(/\s+/).forEach(l=>l&&r.classList.add(l)),r.style.display="none";const o=t.nodeType===1?t:t.parentNode;o.appendChild(r);const{hasTransform:a}=Xb(r);return o.removeChild(r),a}const Ya=e=>{const t=e.props["onUpdate:modelValue"]||!1;return De(t)?n=>xi(t,n):t};function Hk(e){e.target.composing=!0}function $m(e){const t=e.target;t.composing&&(t.composing=!1,t.dispatchEvent(new Event("input")))}const t0={created(e,{modifiers:{lazy:t,trim:n,number:r}},o){e._assign=Ya(o);const a=r||o.props&&o.props.type==="number";_o(e,t?"change":"input",l=>{if(l.target.composing)return;let s=e.value;n&&(s=s.trim()),a&&(s=Vc(s)),e._assign(s)}),n&&_o(e,"change",()=>{e.value=e.value.trim()}),t||(_o(e,"compositionstart",Hk),_o(e,"compositionend",$m),_o(e,"change",$m))},mounted(e,{value:t}){e.value=t==null?"":t},beforeUpdate(e,{value:t,modifiers:{lazy:n,trim:r,number:o}},a){if(e._assign=Ya(a),e.composing||document.activeElement===e&&e.type!=="range"&&(n||r&&e.value.trim()===t||(o||e.type==="number")&&Vc(e.value)===t))return;const l=t==null?"":t;e.value!==l&&(e.value=l)}},ou={deep:!0,created(e,t,n){e._assign=Ya(n),_o(e,"change",()=>{const r=e._modelValue,o=r0(e),a=e.checked,l=e._assign;if(De(r)){const s=Gg(r,o),i=s!==-1;if(a&&!i)l(r.concat(o));else if(!a&&i){const u=[...r];u.splice(s,1),l(u)}}else if(Su(r)){const s=new Set(r);a?s.add(o):s.delete(o),l(s)}else l(o0(e,a))})},mounted:Tm,beforeUpdate(e,t,n){e._assign=Ya(n),Tm(e,t,n)}};function Tm(e,{value:t,oldValue:n},r){e._modelValue=t,De(t)?e.checked=Gg(t,r.props.value)>-1:Su(t)?e.checked=t.has(r.props.value):t!==n&&(e.checked=ja(t,o0(e,!0)))}const n0={created(e,{value:t},n){e.checked=ja(t,n.props.value),e._assign=Ya(n),_o(e,"change",()=>{e._assign(r0(e))})},beforeUpdate(e,{value:t,oldValue:n},r){e._assign=Ya(r),t!==n&&(e.checked=ja(t,r.props.value))}};function r0(e){return"_value"in e?e._value:e.value}function o0(e,t){const n=t?"_trueValue":"_falseValue";return n in e?e[n]:t}const jk=["ctrl","shift","alt","meta"],Wk={stop:e=>e.stopPropagation(),prevent:e=>e.preventDefault(),self:e=>e.target!==e.currentTarget,ctrl:e=>!e.ctrlKey,shift:e=>!e.shiftKey,alt:e=>!e.altKey,meta:e=>!e.metaKey,left:e=>"button"in e&&e.button!==0,middle:e=>"button"in e&&e.button!==1,right:e=>"button"in e&&e.button!==2,exact:(e,t)=>jk.some(n=>e[`${n}Key`]&&!t.includes(n))},$t=(e,t)=>(n,...r)=>{for(let o=0;on=>{if(!("key"in n))return;const r=fa(n.key);if(t.some(o=>o===r||Uk[o]===r))return e(n)},qt={beforeMount(e,{value:t},{transition:n}){e._vod=e.style.display==="none"?"":e.style.display,n&&t?n.beforeEnter(e):Sl(e,t)},mounted(e,{value:t},{transition:n}){n&&t&&n.enter(e)},updated(e,{value:t,oldValue:n},{transition:r}){!t!=!n&&(r?t?(r.beforeEnter(e),Sl(e,!0),r.enter(e)):r.leave(e,()=>{Sl(e,!1)}):Sl(e,t))},beforeUnmount(e,{value:t}){Sl(e,t)}};function Sl(e,t){e.style.display=t?e._vod:"none"}const a0=Wt({patchProp:Ik},bk);let Bl,xm=!1;function Kk(){return Bl||(Bl=QC(a0))}function qk(){return Bl=xm?Bl:ek(a0),xm=!0,Bl}const Om=(...e)=>{Kk().render(...e)},Yk=(...e)=>{const t=qk().createApp(...e),{mount:n}=t;return t.mount=r=>{const o=Gk(r);if(o)return n(o,!0,o instanceof SVGElement)},t};function Gk(e){return Ge(e)?document.querySelector(e):e}const Xk=JSON.parse('{"base":"/","lang":"en-US","title":"SD \u8BAD\u7EC3 UI","description":"","head":[],"locales":{}}');var Jk=([e,t,n])=>e==="meta"&&t.name?`${e}.${t.name}`:["title","base"].includes(e)?e:e==="template"&&t.id?`${e}.${t.id}`:JSON.stringify([e,t,n]),Zk=e=>{const t=new Set,n=[];return e.forEach(r=>{const o=Jk(r);t.has(o)||(t.add(o),n.push(r))}),n},Qk=e=>/^(https?:)?\/\//.test(e),fG=e=>/^mailto:/.test(e),pG=e=>/^tel:/.test(e),l0=e=>Object.prototype.toString.call(e)==="[object Object]",eS=e=>e.replace(/\/$/,""),tS=e=>e.replace(/^\//,""),s0=(e,t)=>{const n=Object.keys(e).sort((r,o)=>{const a=o.split("/").length-r.split("/").length;return a!==0?a:o.length-r.length});for(const r of n)if(t.startsWith(r))return r;return"/"};const i0={"v-8daa1a0e":Jt(()=>wt(()=>import("./index.html.c6ef684b.js"),[])),"v-6983ba2a":Jt(()=>wt(()=>import("./tageditor.html.173f1b6a.js"),[])),"v-51615306":Jt(()=>wt(()=>import("./tagger.html.0daaef4e.js"),[])),"v-06850b9b":Jt(()=>wt(()=>import("./task.html.256f458b.js"),[])),"v-13efe3c5":Jt(()=>wt(()=>import("./tensorboard.html.9c3b4542.js"),[])),"v-33a23463":Jt(()=>wt(()=>import("./index.html.911dc78d.js"),[])),"v-b5471278":Jt(()=>wt(()=>import("./about.html.b4807002.js"),[])),"v-a1c9e4f2":Jt(()=>wt(()=>import("./changelog.html.e5f6a7b8.js"),[])),"v-b8e2d701":Jt(()=>wt(()=>import("./guide.html.c3f4a902.js"),[])),"v-72e1da3e":Jt(()=>wt(()=>import("./settings.html.07aaabcc.js"),[])),"v-3e43d6e2":Jt(()=>wt(()=>import("./basic.html.eb26832d.js"),[])),"v-fdbe4e28":Jt(()=>wt(()=>import("./flux.html.f22f5932.js"),[])),"v-14e91824":Jt(()=>wt(()=>import("./index.html.4896b94d.js"),[])),"v-1bf725da":Jt(()=>wt(()=>import("./master.html.404f21be.js"),[])),"v-0f9e746f":Jt(()=>wt(()=>import("./params.html.dea583bc.js"),[])),"v-0dc76a3b":Jt(()=>wt(()=>import("./sd3.html.1a4bf31e.js"),[])),"v-a1f1ne2e":Jt(()=>wt(()=>import("./anima-finetune.html.1a4bf32e.js"),[])),"v-53c99f50":Jt(()=>wt(()=>import("./sdxl.html.33fa069c.js"),[])),"v-4441a302":Jt(()=>wt(()=>import("./tools.html.6c8bfc09.js"),[])),"v-3706649a":Jt(()=>wt(()=>import("./404.html.7a24a487.js"),[]))},nS={404:Jt(()=>wt(()=>import("./404.47057000.js"),[])),Layout:Jt(()=>wt(()=>import("./layout.96d49288.js"),[]))};var u0=B(b2),c0=pa({key:"",path:"",title:"",lang:"",frontmatter:{},excerpt:"",headers:[]}),jr=B(c0),Ps=()=>jr;zp.webpackHot&&(__VUE_HMR_RUNTIME__.updatePageData=e=>{u0.value[e.key]=()=>Promise.resolve(e),e.key===jr.value.key&&(jr.value=e)});var d0=Symbol(""),rS=()=>{const e=Re(d0);if(!e)throw new Error("usePageFrontmatter() is called without provider.");return e},f0=Symbol(""),oS=()=>{const e=Re(f0);if(!e)throw new Error("usePageHead() is called without provider.");return e},aS=Symbol(""),p0=Symbol(""),lS=()=>{const e=Re(p0);if(!e)throw new Error("usePageLang() is called without provider.");return e},Cf=Symbol(""),sS=()=>{const e=Re(Cf);if(!e)throw new Error("useRouteLocale() is called without provider.");return e},wo=B(Xk),iS=()=>wo;zp.webpackHot&&(__VUE_HMR_RUNTIME__.updateSiteData=e=>{wo.value=e});var m0=Symbol(""),mG=()=>{const e=Re(m0);if(!e)throw new Error("useSiteLocaleData() is called without provider.");return e},uS=Symbol(""),Wo=Xt({resolvePageData:async e=>{const t=u0.value[e],n=await(t==null?void 0:t());return n!=null?n:c0},resolvePageFrontmatter:e=>e.frontmatter,resolvePageHead:(e,t,n)=>{const r=Ge(t.description)?t.description:n.description,o=[...De(t.head)?t.head:[],...n.head,["title",{},e],["meta",{name:"description",content:r}]];return Zk(o)},resolvePageHeadTitle:(e,t)=>`${e.title?`${e.title} | `:""}${t.title}`,resolvePageLang:e=>e.lang||"en",resolveRouteLocale:(e,t)=>s0(e,t),resolveSiteLocaleData:(e,t)=>({...e,...e.locales[t]})}),cS=se({name:"ClientOnly",setup(e,t){const n=B(!1);return dt(()=>{n.value=!0}),()=>{var r,o;return n.value?(o=(r=t.slots).default)==null?void 0:o.call(r):null}}}),dS=se({name:"Content",props:{pageKey:{type:String,required:!1,default:""}},setup(e){const t=Ps(),n=O(()=>i0[e.pageKey||t.value.key]);return()=>n.value?He(n.value):He("div","404 Not Found")}}),Am=se({name:"Vuepress",setup(){const e=Ps(),t=O(()=>{let n;if(e.value.path){const r=e.value.frontmatter.layout;Ge(r)?n=r:n="Layout"}else n="404";return nS[n]||Ve(n,!1)});return()=>He(t.value)}}),fS=e=>Qk(e)?e:`${iS().value.base}${tS(e)}`,Ro=e=>e;function h0(e,t,n){var r,o,a;t===void 0&&(t=50),n===void 0&&(n={});var l=(r=n.isImmediate)!=null&&r,s=(o=n.callback)!=null&&o,i=n.maxWait,u=Date.now(),d=[];function f(){if(i!==void 0){var p=Date.now()-u;if(p+t>=i)return i-p}return t}var h=function(){var p=[].slice.call(arguments),v=this;return new Promise(function(g,w){var m=l&&a===void 0;if(a!==void 0&&clearTimeout(a),a=setTimeout(function(){if(a=void 0,u=Date.now(),!l){var _=e.apply(v,p);s&&s(_),d.forEach(function(y){return(0,y.resolve)(_)}),d=[]}},f()),m){var b=e.apply(v,p);return s&&s(b),g(b)}d.push({resolve:g,reject:w})})};return h.cancel=function(p){a!==void 0&&clearTimeout(a),d.forEach(function(v){return(0,v.reject)(p)}),d=[]},h}/*! * vue-router v4.2.4 * (c) 2023 Eduardo San Martin Morote * @license MIT @@ -120,3 +120,4 @@ Please report this to https://github.com/markedjs/marked.`,e){const o="

An err */var PY="store";function wl(e,t){Object.keys(e).forEach(function(n){return t(e[n],n)})}function LY(e){return e!==null&&typeof e=="object"}function MY(e){return e&&typeof e.then=="function"}function RY(e,t){return function(){return e(t)}}function n2(e,t,n){return t.indexOf(e)<0&&(n&&n.prepend?t.unshift(e):t.push(e)),function(){var r=t.indexOf(e);r>-1&&t.splice(r,1)}}function r2(e,t){e._actions=Object.create(null),e._mutations=Object.create(null),e._wrappedGetters=Object.create(null),e._modulesNamespaceMap=Object.create(null);var n=e.state;oc(e,n,[],e._modules.root,!0),Fp(e,n,t)}function Fp(e,t,n){var r=e._state;e.getters={},e._makeLocalGettersCache=Object.create(null);var o=e._wrappedGetters,a={};wl(o,function(l,s){a[s]=RY(l,e),Object.defineProperty(e.getters,s,{get:function(){return a[s]()},enumerable:!0})}),e._state=Xt({data:t}),e.strict&&BY(e),r&&n&&e._withCommit(function(){r.data=null})}function oc(e,t,n,r,o){var a=!n.length,l=e._modules.getNamespace(n);if(r.namespaced&&(e._modulesNamespaceMap[l],e._modulesNamespaceMap[l]=r),!a&&!o){var s=Vp(t,n.slice(0,-1)),i=n[n.length-1];e._withCommit(function(){s[i]=r.state})}var u=r.context=NY(e,l,n);r.forEachMutation(function(d,f){var h=l+f;DY(e,h,d,u)}),r.forEachAction(function(d,f){var h=d.root?f:l+f,p=d.handler||d;FY(e,h,p,u)}),r.forEachGetter(function(d,f){var h=l+f;VY(e,h,d,u)}),r.forEachChild(function(d,f){oc(e,t,n.concat(f),d,o)})}function NY(e,t,n){var r=t==="",o={dispatch:r?e.dispatch:function(a,l,s){var i=ku(a,l,s),u=i.payload,d=i.options,f=i.type;return(!d||!d.root)&&(f=t+f),e.dispatch(f,u)},commit:r?e.commit:function(a,l,s){var i=ku(a,l,s),u=i.payload,d=i.options,f=i.type;(!d||!d.root)&&(f=t+f),e.commit(f,u,d)}};return Object.defineProperties(o,{getters:{get:r?function(){return e.getters}:function(){return o2(e,t)}},state:{get:function(){return Vp(e.state,n)}}}),o}function o2(e,t){if(!e._makeLocalGettersCache[t]){var n={},r=t.length;Object.keys(e.getters).forEach(function(o){if(o.slice(0,r)===t){var a=o.slice(r);Object.defineProperty(n,a,{get:function(){return e.getters[o]},enumerable:!0})}}),e._makeLocalGettersCache[t]=n}return e._makeLocalGettersCache[t]}function DY(e,t,n,r){var o=e._mutations[t]||(e._mutations[t]=[]);o.push(function(l){n.call(e,r.state,l)})}function FY(e,t,n,r){var o=e._actions[t]||(e._actions[t]=[]);o.push(function(l){var s=n.call(e,{dispatch:r.dispatch,commit:r.commit,getters:r.getters,state:r.state,rootGetters:e.getters,rootState:e.state},l);return MY(s)||(s=Promise.resolve(s)),e._devtoolHook?s.catch(function(i){throw e._devtoolHook.emit("vuex:error",i),i}):s})}function VY(e,t,n,r){e._wrappedGetters[t]||(e._wrappedGetters[t]=function(a){return n(r.state,r.getters,a.state,a.getters)})}function BY(e){$e(function(){return e._state.data},function(){},{deep:!0,flush:"sync"})}function Vp(e,t){return t.reduce(function(n,r){return n[r]},e)}function ku(e,t,n){return LY(e)&&e.type&&(n=t,t=e,e=e.type),{type:e,payload:t,options:n}}var zY="vuex bindings",Wg="vuex:mutations",Dc="vuex:actions",Oa="vuex",HY=0;function jY(e,t){IY({id:"org.vuejs.vuex",app:e,label:"Vuex",homepage:"https://next.vuex.vuejs.org/",logo:"https://vuejs.org/images/icons/favicon-96x96.png",packageName:"vuex",componentStateTypes:[zY]},function(n){n.addTimelineLayer({id:Wg,label:"Vuex Mutations",color:Ug}),n.addTimelineLayer({id:Dc,label:"Vuex Actions",color:Ug}),n.addInspector({id:Oa,label:"Vuex",icon:"storage",treeFilterPlaceholder:"Filter stores..."}),n.on.getInspectorTree(function(r){if(r.app===e&&r.inspectorId===Oa)if(r.filter){var o=[];i2(o,t._modules.root,r.filter,""),r.rootNodes=o}else r.rootNodes=[s2(t._modules.root,"")]}),n.on.getInspectorState(function(r){if(r.app===e&&r.inspectorId===Oa){var o=r.nodeId;o2(t,o),r.state=KY(YY(t._modules,o),o==="root"?t.getters:t._makeLocalGettersCache,o)}}),n.on.editInspectorState(function(r){if(r.app===e&&r.inspectorId===Oa){var o=r.nodeId,a=r.path;o!=="root"&&(a=o.split("/").filter(Boolean).concat(a)),t._withCommit(function(){r.set(t._state.data,a,r.state.value)})}}),t.subscribe(function(r,o){var a={};r.payload&&(a.payload=r.payload),a.state=o,n.notifyComponentUpdate(),n.sendInspectorTree(Oa),n.sendInspectorState(Oa),n.addTimelineEvent({layerId:Wg,event:{time:Date.now(),title:r.type,data:a}})}),t.subscribeAction({before:function(r,o){var a={};r.payload&&(a.payload=r.payload),r._id=HY++,r._time=Date.now(),a.state=o,n.addTimelineEvent({layerId:Dc,event:{time:r._time,title:r.type,groupId:r._id,subtitle:"start",data:a}})},after:function(r,o){var a={},l=Date.now()-r._time;a.duration={_custom:{type:"duration",display:l+"ms",tooltip:"Action duration",value:l}},r.payload&&(a.payload=r.payload),a.state=o,n.addTimelineEvent({layerId:Dc,event:{time:Date.now(),title:r.type,groupId:r._id,subtitle:"end",data:a}})}})})}var Ug=8702998,WY=6710886,UY=16777215,a2={label:"namespaced",textColor:UY,backgroundColor:WY};function l2(e){return e&&e!=="root"?e.split("/").slice(-2,-1)[0]:"Root"}function s2(e,t){return{id:t||"root",label:l2(t),tags:e.namespaced?[a2]:[],children:Object.keys(e._children).map(function(n){return s2(e._children[n],t+n+"/")})}}function i2(e,t,n,r){r.includes(n)&&e.push({id:r||"root",label:r.endsWith("/")?r.slice(0,r.length-1):r||"Root",tags:t.namespaced?[a2]:[]}),Object.keys(t._children).forEach(function(o){i2(e,t._children[o],n,r+o+"/")})}function KY(e,t,n){t=n==="root"?t:t[n];var r=Object.keys(t),o={state:Object.keys(e.state).map(function(l){return{key:l,editable:!0,value:e.state[l]}})};if(r.length){var a=qY(t);o.getters=Object.keys(a).map(function(l){return{key:l.endsWith("/")?l2(l):l,editable:!1,value:Xd(function(){return a[l]})}})}return o}function qY(e){var t={};return Object.keys(e).forEach(function(n){var r=n.split("/");if(r.length>1){var o=t,a=r.pop();r.forEach(function(l){o[l]||(o[l]={_custom:{value:{},display:l,tooltip:"Module",abstract:!0}}),o=o[l]._custom.value}),o[a]=Xd(function(){return e[n]})}else t[n]=Xd(function(){return e[n]})}),t}function YY(e,t){var n=t.split("/").filter(function(r){return r});return n.reduce(function(r,o,a){var l=r[o];if(!l)throw new Error('Missing module "'+o+'" for path "'+t+'".');return a===n.length-1?l:l._children},t==="root"?e:e.root._children)}function Xd(e){try{return e()}catch(t){return t}}var _r=function(t,n){this.runtime=n,this._children=Object.create(null),this._rawModule=t;var r=t.state;this.state=(typeof r=="function"?r():r)||{}},u2={namespaced:{configurable:!0}};u2.namespaced.get=function(){return!!this._rawModule.namespaced};_r.prototype.addChild=function(t,n){this._children[t]=n};_r.prototype.removeChild=function(t){delete this._children[t]};_r.prototype.getChild=function(t){return this._children[t]};_r.prototype.hasChild=function(t){return t in this._children};_r.prototype.update=function(t){this._rawModule.namespaced=t.namespaced,t.actions&&(this._rawModule.actions=t.actions),t.mutations&&(this._rawModule.mutations=t.mutations),t.getters&&(this._rawModule.getters=t.getters)};_r.prototype.forEachChild=function(t){wl(this._children,t)};_r.prototype.forEachGetter=function(t){this._rawModule.getters&&wl(this._rawModule.getters,t)};_r.prototype.forEachAction=function(t){this._rawModule.actions&&wl(this._rawModule.actions,t)};_r.prototype.forEachMutation=function(t){this._rawModule.mutations&&wl(this._rawModule.mutations,t)};Object.defineProperties(_r.prototype,u2);var ka=function(t){this.register([],t,!1)};ka.prototype.get=function(t){return t.reduce(function(n,r){return n.getChild(r)},this.root)};ka.prototype.getNamespace=function(t){var n=this.root;return t.reduce(function(r,o){return n=n.getChild(o),r+(n.namespaced?o+"/":"")},"")};ka.prototype.update=function(t){c2([],this.root,t)};ka.prototype.register=function(t,n,r){var o=this;r===void 0&&(r=!0);var a=new _r(n,r);if(t.length===0)this.root=a;else{var l=this.get(t.slice(0,-1));l.addChild(t[t.length-1],a)}n.modules&&wl(n.modules,function(s,i){o.register(t.concat(i),s,r)})};ka.prototype.unregister=function(t){var n=this.get(t.slice(0,-1)),r=t[t.length-1],o=n.getChild(r);!o||!o.runtime||n.removeChild(r)};ka.prototype.isRegistered=function(t){var n=this.get(t.slice(0,-1)),r=t[t.length-1];return n?n.hasChild(r):!1};function c2(e,t,n){if(t.update(n),n.modules)for(var r in n.modules){if(!t.getChild(r))return;c2(e.concat(r),t.getChild(r),n.modules[r])}}function GY(e){return new Nn(e)}var Nn=function(t){var n=this;t===void 0&&(t={});var r=t.plugins;r===void 0&&(r=[]);var o=t.strict;o===void 0&&(o=!1);var a=t.devtools;this._committing=!1,this._actions=Object.create(null),this._actionSubscribers=[],this._mutations=Object.create(null),this._wrappedGetters=Object.create(null),this._modules=new ka(t),this._modulesNamespaceMap=Object.create(null),this._subscribers=[],this._makeLocalGettersCache=Object.create(null),this._devtools=a;var l=this,s=this,i=s.dispatch,u=s.commit;this.dispatch=function(h,p){return i.call(l,h,p)},this.commit=function(h,p,v){return u.call(l,h,p,v)},this.strict=o;var d=this._modules.root.state;oc(this,d,[],this._modules.root),Fp(this,d),r.forEach(function(f){return f(n)})},Bp={state:{configurable:!0}};Nn.prototype.install=function(t,n){t.provide(n||PY,this),t.config.globalProperties.$store=this;var r=this._devtools!==void 0?this._devtools:!1;r&&jY(t,this)};Bp.state.get=function(){return this._state.data};Bp.state.set=function(e){};Nn.prototype.commit=function(t,n,r){var o=this,a=ku(t,n,r),l=a.type,s=a.payload,i={type:l,payload:s},u=this._mutations[l];!u||(this._withCommit(function(){u.forEach(function(f){f(s)})}),this._subscribers.slice().forEach(function(d){return d(i,o.state)}))};Nn.prototype.dispatch=function(t,n){var r=this,o=ku(t,n),a=o.type,l=o.payload,s={type:a,payload:l},i=this._actions[a];if(!!i){try{this._actionSubscribers.slice().filter(function(d){return d.before}).forEach(function(d){return d.before(s,r.state)})}catch{}var u=i.length>1?Promise.all(i.map(function(d){return d(l)})):i[0](l);return new Promise(function(d,f){u.then(function(h){try{r._actionSubscribers.filter(function(p){return p.after}).forEach(function(p){return p.after(s,r.state)})}catch{}d(h)},function(h){try{r._actionSubscribers.filter(function(p){return p.error}).forEach(function(p){return p.error(s,r.state,h)})}catch{}f(h)})})}};Nn.prototype.subscribe=function(t,n){return n2(t,this._subscribers,n)};Nn.prototype.subscribeAction=function(t,n){var r=typeof t=="function"?{before:t}:t;return n2(r,this._actionSubscribers,n)};Nn.prototype.watch=function(t,n,r){var o=this;return $e(function(){return t(o.state,o.getters)},n,Object.assign({},r))};Nn.prototype.replaceState=function(t){var n=this;this._withCommit(function(){n._state.data=t})};Nn.prototype.registerModule=function(t,n,r){r===void 0&&(r={}),typeof t=="string"&&(t=[t]),this._modules.register(t,n),oc(this,this.state,t,this._modules.get(t),r.preserveState),Fp(this,this.state)};Nn.prototype.unregisterModule=function(t){var n=this;typeof t=="string"&&(t=[t]),this._modules.unregister(t),this._withCommit(function(){var r=Vp(n.state,t.slice(0,-1));delete r[t[t.length-1]]}),r2(this)};Nn.prototype.hasModule=function(t){return typeof t=="string"&&(t=[t]),this._modules.isRegistered(t)};Nn.prototype.hotUpdate=function(t){this._modules.update(t),r2(this,!0)};Nn.prototype._withCommit=function(t){var n=this._committing;this._committing=!0,t(),this._committing=n};Object.defineProperties(Nn.prototype,Bp);const d2=Vx({legacy:!1,locale:"zh-CN",fallbackLocale:""}),XY=GY({state:{filePickerOpened:!1}});globalThis.Schema=Rs;globalThis.i18n=d2;var JY=Ro({enhance({app:e,router:t,siteData:n}){e.use(XY),e.use(CV),e.use(tY),e.use(hB),e.use(vB),e.use(nY),e.use(Bz),e.use(Uz),e.use(Qr),e.use(da),e.use(Gz),e.use(SH),e.use(Ij),e.use(Xj),e.use(qW),e.use(YW),e.use(GW),e.use(Kn),e.use(Fw),e.use(sK),e.use(Oz),e.use(yl),e.use(Hw),e.use(DK),e.use(YK),e.use(j7),e.use(mw),e.use(Ca),e.use(G7),e.use(tW),e.use(d2),e.use(an),e.component("k-markdown",b4)},setup(){}});const Fc=[_E,kE,TE,VE,jE,YE,lT,JY],ZY=[["v-8daa1a0e","/",{title:"SD-Trainer"},["/index.html","/index.md"]],["v-6983ba2a","/tageditor.html",{title:""},["/tageditor","/tageditor.md"]],["v-native-tageditor","/native-tageditor.html",{title:""},["/native-tageditor","/native-tageditor.md"]],["v-51615306","/tagger.html",{title:"Tagger \u6807\u6CE8\u5DE5\u5177"},["/tagger","/tagger.md"]],["v-06850b9b","/task.html",{title:""},["/task","/task.md"]],["v-13efe3c5","/tensorboard.html",{title:""},["/tensorboard","/tensorboard.md"]],["v-33a23463","/dreambooth/",{title:"Dreambooth \u8BAD\u7EC3 \u4E13\u5BB6\u6A21\u5F0F"},["/dreambooth/index.html","/dreambooth/index.md"]],["v-b5471278","/other/about.html",{title:""},["/other/about","/other/about.md"]],["v-a1c9e4f2","/other/changelog.html",{title:"\u66F4\u65B0\u65E5\u5FD7"},["/other/changelog","/other/changelog.md"]],["v-b8e2d701","/help/guide.html",{title:"\u65b0\u624b\u4e0a\u8def"},["/help/guide","/help/guide.md"]],["v-72e1da3e","/other/settings.html",{title:"\u8BAD\u7EC3 UI \u8BBE\u7F6E"},["/other/settings","/other/settings.md"]],["v-3e43d6e2","/lora/basic.html",{title:"LoRA \u8BAD\u7EC3 \u65B0\u624B\u6A21\u5F0F"},["/lora/basic","/lora/basic.md"]],["v-fdbe4e28","/lora/flux.html",{title:"Flux LoRA \u8BAD\u7EC3 \u4E13\u5BB6\u6A21\u5F0F"},["/lora/flux","/lora/flux.md"]],["v-14e91824","/lora/",{title:"LoRA \u8BAD\u7EC3"},["/lora/index.html","/lora/index.md"]],["v-1bf725da","/lora/master.html",{title:"LoRA \u8BAD\u7EC3 \u4E13\u5BB6\u6A21\u5F0F"},["/lora/master","/lora/master.md"]],["v-0f9e746f","/lora/params.html",{title:"\u8BAD\u7EC3\u53C2\u6570\u8C03\u8282"},["/lora/params","/lora/params.md"]],["v-0dc76a3b","/lora/sd3.html",{title:"SD3 \u8BAD\u7EC3 \u4E13\u5BB6\u6A21\u5F0F"},["/lora/sd3","/lora/sd3.md"]],["v-a1f1ne2e","/lora/anima-finetune.html",{title:"Anima \u5168\u91cf\u5FAE\u8C03 \u4E13\u5BB6\u6A21\u5F0F"},["/lora/anima-finetune","/lora/anima-finetune.md"]],["v-53c99f50","/lora/sdxl.html",{title:"SDXL LoRA \u8BAD\u7EC3 \u4E13\u5BB6\u6A21\u5F0F"},["/lora/sdxl","/lora/sdxl.md"]],["v-4441a302","/lora/tools.html",{title:"LoRA \u76F8\u5173\u5DE5\u5177"},["/lora/tools","/lora/tools.md"]],["v-3706649a","/404.html",{title:""},["/404"]]];var QY=()=>ZY.reduce((e,[t,n,r,o])=>(e.push({name:t,path:n,component:Am,meta:r},...o.map(a=>({path:a,redirect:n}))),e),[{name:"404",path:"/:catchAll(.*)",component:Am}]),eG=AS,tG=()=>{const e=pE({history:eG(eS(wo.value.base)),routes:QY(),scrollBehavior:(t,n,r)=>r||(t.hash?{el:t.hash}:{top:0})});return e.beforeResolve(async(t,n)=>{var r;(t.path!==n.path||n===Vr)&&([jr.value]=await Promise.all([Wo.resolvePageData(t.name),(r=i0[t.name])==null?void 0:r.__asyncLoader()]))}),e},nG=e=>{e.component("ClientOnly",cS),e.component("Content",dS)},rG=(e,t)=>{const n=O(()=>Wo.resolveRouteLocale(wo.value.locales,t.currentRoute.value.path)),r=O(()=>Wo.resolveSiteLocaleData(wo.value,n.value)),o=O(()=>Wo.resolvePageFrontmatter(jr.value)),a=O(()=>Wo.resolvePageHeadTitle(jr.value,r.value)),l=O(()=>Wo.resolvePageHead(a.value,o.value,r.value)),s=O(()=>Wo.resolvePageLang(jr.value));return e.provide(Cf,n),e.provide(m0,r),e.provide(d0,o),e.provide(aS,a),e.provide(f0,l),e.provide(p0,s),Object.defineProperties(e.config.globalProperties,{$frontmatter:{get:()=>o.value},$head:{get:()=>l.value},$headTitle:{get:()=>a.value},$lang:{get:()=>s.value},$page:{get:()=>jr.value},$routeLocale:{get:()=>n.value},$site:{get:()=>wo.value},$siteLocale:{get:()=>r.value},$withBase:{get:()=>fS}}),{pageData:jr,pageFrontmatter:o,pageHead:l,pageHeadTitle:a,pageLang:s,routeLocale:n,siteData:wo,siteLocaleData:r}},oG=()=>{const e=$f(),t=oS(),n=lS(),r=B([]),o=()=>{t.value.forEach(l=>{const s=aG(l);s&&r.value.push(s)})},a=()=>{document.documentElement.lang=n.value,r.value.forEach(l=>{l.parentNode===document.head&&document.head.removeChild(l)}),r.value.splice(0,r.value.length),t.value.forEach(l=>{const s=lG(l);s!==null&&(document.head.appendChild(s),r.value.push(s))})};yt(uS,a),dt(()=>{o(),a(),$e(()=>e.path,()=>a())})},aG=([e,t,n=""])=>{const r=Object.entries(t).map(([s,i])=>Ge(i)?`[${s}="${i}"]`:i===!0?`[${s}]`:"").join(""),o=`head > ${e}${r}`;return Array.from(document.querySelectorAll(o)).find(s=>s.innerText===n)||null},lG=([e,t,n])=>{if(!Ge(e))return null;const r=document.createElement(e);return l0(t)&&Object.entries(t).forEach(([o,a])=>{Ge(a)?r.setAttribute(o,a):a===!0&&r.setAttribute(o,"")}),Ge(n)&&r.appendChild(document.createTextNode(n)),r},sG=Yk,iG=async()=>{var n;const e=sG({name:"VuepressApp",setup(){var r;oG();for(const o of Fc)(r=o.setup)==null||r.call(o);return()=>[He($0),...Fc.flatMap(({rootComponents:o=[]})=>o.map(a=>He(a)))]}}),t=tG();nG(e),rG(e,t);for(const r of Fc)await((n=r.enhance)==null?void 0:n.call(r,{app:e,router:t,siteData:wo}));return e.use(t),{app:e,router:t}};iG().then(({app:e,router:t})=>{t.isReady().then(()=>{e.mount("#app")})});export{ht as $,$e as A,V5 as B,dt as C,rn as D,at as E,K5 as F,dr as G,ze as H,c_ as I,ce as J,vt as K,D as L,Qe as M,$t as N,Lt as O,ye as P,Dt as Q,pe as R,qt as S,K1 as T,Mn as U,xt as V,Ge as W,Ua as X,Om as Y,ft as Z,St as _,K as a,Er as a0,Ke as a1,ua as a2,rS as a3,Pe as a4,it as a5,De as a6,$f as a7,Ht as a8,Qk as a9,CV as aA,bG as aB,xn as aC,Is as aD,fG as aa,pG as ab,iS as ac,mG as ad,vG as ae,He as af,fS as ag,cS as ah,tS as ai,eS as aj,Ef as ak,Z$ as al,Ps as am,gG as an,l0 as ao,hG as ap,Ei as aq,_C as ar,wC as as,Mo as at,eT as au,us as av,Rs as aw,gY as ax,kn as ay,As as az,Je as b,U as c,iG as createVueApp,Q as d,dG as e,se as f,H0 as g,c as h,Qr as i,A_ as j,Kn as k,Nj as l,nt as m,qe as n,x as o,q1 as p,uV as q,Ve as r,O as s,Ee as t,sS as u,B as v,G as w,Xt as x,gu as y,Lo as z}; + diff --git a/frontend/dist/assets/native-tageditor.html.native.js b/frontend/dist/assets/native-tageditor.html.native.js new file mode 100644 index 00000000..e1e20c29 --- /dev/null +++ b/frontend/dist/assets/native-tageditor.html.native.js @@ -0,0 +1 @@ +const e=JSON.parse('{"key":"v-native-tageditor","path":"/native-tageditor.html","title":"\\u539f\\u751f\\u6807\\u7b7e\\u7f16\\u8f91","lang":"en-US","frontmatter":{"type":"native-dataset-editor"},"excerpt":"","headers":[],"filePathRelative":"native-tageditor.md"}');export{e as data}; diff --git a/frontend/dist/assets/sd-nav-i18n.js b/frontend/dist/assets/sd-nav-i18n.js index 5c40baeb..c3e6b35a 100644 --- a/frontend/dist/assets/sd-nav-i18n.js +++ b/frontend/dist/assets/sd-nav-i18n.js @@ -4,6 +4,11 @@ */ (function () { const STORAGE_KEY = "sd-trainer-ui-locale"; + const ADVANCED_LINKS_KEY = "sd-trainer-ui-advanced-links"; + const DEFAULT_ADVANCED_LINKS = { + showTensorboard: false, + showLegacyTagEditor: false, + }; const ZH_TO_EN = { 训练: "Training", @@ -20,7 +25,8 @@ 新手上路: "Getting Started", 训练参数说明: "Training Parameters", 其他: "More", - "UI 设置": "UI Settings", + "UI 设置": "Settings", + 设置: "Settings", 关于: "About", 更新日志: "Changelog", 训练监控: "Train Monitor", @@ -168,6 +174,193 @@ } } + function readAdvancedLinks() { + try { + return { + ...DEFAULT_ADVANCED_LINKS, + ...(JSON.parse(localStorage.getItem(ADVANCED_LINKS_KEY) || "{}") || {}), + }; + } catch (e) { + return { ...DEFAULT_ADVANCED_LINKS }; + } + } + + function writeAdvancedLinks(next) { + localStorage.setItem(ADVANCED_LINKS_KEY, JSON.stringify({ + ...DEFAULT_ADVANCED_LINKS, + ...next, + })); + } + + function setSidebarLinkVisible(selector, visible) { + const link = document.querySelector(`.sidebar .sidebar-items ${selector}`); + const item = link?.closest("li"); + if (!item) return; + item.hidden = !visible; + item.style.display = visible ? "" : "none"; + } + + function applyAdvancedLinkVisibility() { + const flags = readAdvancedLinks(); + setSidebarLinkVisible('a[href="/tensorboard.md"]', !!flags.showTensorboard); + setSidebarLinkVisible('a[href="/tageditor.md"]', !!flags.showLegacyTagEditor); + } + + function maskSettingsOutput() { + if (!location.pathname.endsWith("/other/settings.html")) return; + const output = document.querySelector("#test-output1"); + if (output) { + output.hidden = true; + output.style.display = "none"; + } + document.querySelectorAll("h1, h2.k-schema-header, a.sidebar-item").forEach((el) => { + const text = normalize(el.textContent); + if (text === "训练 UI 设置" || text === "UI 设置" || text === "UI Settings") { + if (el.matches("h1, h2.k-schema-header")) { + el.textContent = "设置"; + } else { + el.childNodes.forEach((node) => { + if (node.nodeType === Node.TEXT_NODE && normalize(node.textContent)) { + node.textContent = " 设置 "; + } + }); + } + el.setAttribute?.("aria-label", "设置"); + } + }); + document.title = document.title + .replace("训练 UI 设置", "设置") + .replace("UI 设置", "设置") + .replace("UI Settings", "Settings"); + } + + const SETTINGS_HELP = { + tensorboard_url: { + title: "Tensorboard 地址", + body: "用于打开训练日志的 Tensorboard 页面。这个入口默认隐藏,需要时可以在下方旧功能入口里打开。", + }, + dataset_tagger_api_endpoint: { + title: "标签编辑器 API 打标地址", + body: "填写兼容 OpenAI 风格的接口根地址,例如 https://api.openai.com/v1。本地或第三方 VLM 服务也可以放在这里。", + }, + dataset_tagger_api_key: { + title: "标签编辑器 API Key", + body: "敏感信息,只用于请求 API 打标服务。输入框会打码显示,右侧预览不会展示明文。", + }, + dataset_tagger_api_model: { + title: "标签编辑器 API 模型", + body: "用于自然语言 caption 的模型名称。不同 API 服务可能使用不同模型 id。", + }, + dataset_tagger_api_prompt: { + title: "标签编辑器 API 提示词", + body: "发送给自然语言模型的 caption 指令。建议要求输出简洁 caption,不要 Markdown 或解释。", + }, + advanced_links: { + title: "隐藏旧功能入口", + body: "Tensorboard 和经典标签编辑默认隐藏,避免用户优先进入旧页面。需要排查问题时可以临时显示。", + }, + }; + + function findSettingItem(name) { + return Array.from(document.querySelectorAll(".schema-container .k-schema-item")).find((item) => + normalize(item.textContent).includes(name) + ); + } + + function maskSensitiveSettingsFields() { + if (!location.pathname.endsWith("/other/settings.html")) return; + const keyItem = findSettingItem("dataset_tagger_api_key"); + const input = keyItem?.querySelector("input"); + if (!input) return; + input.type = "password"; + input.autocomplete = "new-password"; + input.setAttribute("spellcheck", "false"); + input.setAttribute("aria-label", "标签编辑器 API Key,已打码"); + } + + function renderSettingsHelp(activeKey = "dataset_tagger_api_endpoint") { + if (!location.pathname.endsWith("/other/settings.html")) return; + const container = document.querySelector(".right-container .theme-default-content main"); + if (!container) return; + const help = SETTINGS_HELP[activeKey] || SETTINGS_HELP.dataset_tagger_api_endpoint; + container.innerHTML = ` +

+

当前选项说明

+

${help.title}

+

${help.body}

+
`; + } + + function hookSettingsHelp() { + if (!location.pathname.endsWith("/other/settings.html")) return; + const pairs = [ + ["tensorboard_url", "tensorboard_url"], + ["dataset_tagger_api_endpoint", "dataset_tagger_api_endpoint"], + ["dataset_tagger_api_key", "dataset_tagger_api_key"], + ["dataset_tagger_api_model", "dataset_tagger_api_model"], + ["dataset_tagger_api_prompt", "dataset_tagger_api_prompt"], + ]; + for (const [needle, key] of pairs) { + const item = findSettingItem(needle); + if (!item || item.dataset.sdHelpHooked) continue; + item.dataset.sdHelpHooked = "1"; + item.addEventListener("mouseenter", () => renderSettingsHelp(key)); + item.addEventListener("focusin", () => renderSettingsHelp(key)); + item.addEventListener("click", () => renderSettingsHelp(key)); + } + const advanced = document.getElementById("sd-advanced-link-settings"); + if (advanced && !advanced.dataset.sdHelpHooked) { + advanced.dataset.sdHelpHooked = "1"; + advanced.addEventListener("mouseenter", () => renderSettingsHelp("advanced_links")); + advanced.addEventListener("focusin", () => renderSettingsHelp("advanced_links")); + advanced.addEventListener("click", () => renderSettingsHelp("advanced_links")); + } + renderSettingsHelp(); + } + + function injectAdvancedSettingsPanel() { + if (!location.pathname.endsWith("/other/settings.html")) return; + if (document.getElementById("sd-advanced-link-settings")) return; + const form = document.querySelector(".schema-container form"); + if (!form) return; + const flags = readAdvancedLinks(); + const panel = document.createElement("section"); + panel.id = "sd-advanced-link-settings"; + panel.className = "k-schema-item"; + panel.innerHTML = ` +
+
+
+

隐藏旧功能入口

+

Tensorboard 和经典标签编辑默认从侧边栏隐藏,需要时可临时显示。

+
+
+ + +
+
`; + form.appendChild(panel); + const tensorboard = panel.querySelector("#sd-show-tensorboard"); + const legacy = panel.querySelector("#sd-show-legacy-tageditor"); + tensorboard.checked = !!flags.showTensorboard; + legacy.checked = !!flags.showLegacyTagEditor; + const save = () => { + writeAdvancedLinks({ + showTensorboard: tensorboard.checked, + showLegacyTagEditor: legacy.checked, + }); + applyAdvancedLinkVisibility(); + }; + tensorboard.addEventListener("change", save); + legacy.addEventListener("change", save); + } + function hookLanguageToggle() { const bottom = document.querySelector(".sidebar-bottom"); if (!bottom || bottom.dataset.sdNavI18nHooked) return; @@ -195,6 +388,11 @@ scheduled = null; applyNavLocale(); ensureStableSidebarState(); + applyAdvancedLinkVisibility(); + maskSettingsOutput(); + injectAdvancedSettingsPanel(); + maskSensitiveSettingsFields(); + hookSettingsHelp(); hookLanguageToggle(); }, 60); } @@ -202,6 +400,11 @@ function boot() { applyNavLocale(); ensureStableSidebarState(); + applyAdvancedLinkVisibility(); + maskSettingsOutput(); + injectAdvancedSettingsPanel(); + maskSensitiveSettingsFields(); + hookSettingsHelp(); hookLanguageToggle(); const root = document.querySelector("#app"); diff --git a/frontend/dist/assets/settings.html.06993f96.js b/frontend/dist/assets/settings.html.06993f96.js index f7b88f22..e744171d 100644 --- a/frontend/dist/assets/settings.html.06993f96.js +++ b/frontend/dist/assets/settings.html.06993f96.js @@ -1 +1 @@ -const e=JSON.parse(`{"key":"v-72e1da3e","path":"/other/settings.html","title":"\u8BAD\u7EC3 UI \u8BBE\u7F6E","lang":"en-US","frontmatter":{"type":"settings","code":"Schema.intersect([\\n Schema.object({\\n tensorboard_url: Schema.string().role('folder').description(\\"tensorboard \u5730\u5740\\"),\\n dataset_tagger_api_endpoint: Schema.string().default(\\"https://api.openai.com/v1\\").description(\\"标签编辑器 API 打标地址\\"),\\n dataset_tagger_api_key: Schema.string().description(\\"标签编辑器 API Key\\"),\\n dataset_tagger_api_model: Schema.string().description(\\"标签编辑器 API 模型\\"),\\n dataset_tagger_api_prompt: Schema.string().role('textarea', { rows: 4 }).default(\\"Describe this image for image model training. Return a concise caption only, without markdown or explanations.\\").description(\\"标签编辑器 API 提示词\\")\\n }).description(\\"\u8BAD\u7EC3 UI \u8BBE\u7F6E\\"),\\n]);\\n"},"excerpt":"","headers":[],"filePathRelative":"other/settings.md"}`);export{e as data}; +const e={"key":"v-72e1da3e","path":"/other/settings.html","title":"\u8bbe\u7f6e","lang":"en-US","frontmatter":{"type":"settings","code":"Schema.intersect([\n Schema.object({\n tensorboard_url: Schema.string().role('folder').description(\"tensorboard \u5730\u5740\"),\n dataset_tagger_api_endpoint: Schema.string().default(\"https://api.openai.com/v1\").description(\"\u6807\u7b7e\u7f16\u8f91\u5668 API \u6253\u6807\u5730\u5740\"),\n dataset_tagger_api_key: Schema.string().role('password').description(\"\u6807\u7b7e\u7f16\u8f91\u5668 API Key\"),\n dataset_tagger_api_model: Schema.string().description(\"\u6807\u7b7e\u7f16\u8f91\u5668 API \u6a21\u578b\"),\n dataset_tagger_api_prompt: Schema.string().role('textarea', { rows: 4 }).default(\"Describe this image for image model training. Return a concise caption only, without markdown or explanations.\").description(\"\u6807\u7b7e\u7f16\u8f91\u5668 API \u63d0\u793a\u8bcd\")\n }).description(\"\u8bbe\u7f6e\"),\n]);\n"},"excerpt":"","headers":[],"filePathRelative":"other/settings.md"};export{e as data}; diff --git a/frontend/dist/native-tageditor.html b/frontend/dist/native-tageditor.html index d686b6d5..ed2c27bb 100644 --- a/frontend/dist/native-tageditor.html +++ b/frontend/dist/native-tageditor.html @@ -26,7 +26,7 @@ } SD 训练 UI - + @@ -41,3 +41,4 @@ + diff --git a/frontend/dist/other/settings.html b/frontend/dist/other/settings.html index 5c29b3a0..a326b696 100644 --- a/frontend/dist/other/settings.html +++ b/frontend/dist/other/settings.html @@ -25,13 +25,13 @@ document.documentElement.classList.toggle('dark', true); } - 璁粌 UI 璁剧疆 | SD 璁粌 UI + 设置 | SD 训练 UI -

璁粌 UI 璁剧疆

tensorboard_url

tensorboard 鍦板潃

-

璁粌 UI 璁剧疆

涓嶆噦鐨勪笉瑕佺杩欎釜

Output
{ }
+

设置

tensorboard_url

tensorboard 地址

+

设置

不懂的不要改这个

Output
{ }
diff --git a/mikazuki/app/application.py b/mikazuki/app/application.py index 371110fe..d11db82d 100644 --- a/mikazuki/app/application.py +++ b/mikazuki/app/application.py @@ -164,6 +164,7 @@ async def add_cache_control_header(request, call_next): or path.endswith("/assets/dataset-editor.js") or path.endswith("/assets/dataset-editor.css") or path.endswith("/assets/dataset-editor-entry.js") + or path.endswith("/assets/settings.html.06993f96.js") ): response.headers["Cache-Control"] = "no-cache, must-revalidate" elif re.search(r"\.[a-f0-9]{8}\.(js|css|webp)$", path): diff --git a/tests/test_dataset_editor_api.py b/tests/test_dataset_editor_api.py index 42420ea5..e0325d9f 100644 --- a/tests/test_dataset_editor_api.py +++ b/tests/test_dataset_editor_api.py @@ -315,6 +315,28 @@ def test_native_tageditor_embeds_native_editor_in_trainer_shell(): assert "原生标签编辑" in response.text +def test_native_tageditor_uses_native_vuepress_page_data(): + native_tageditor = (ROOT / "frontend" / "dist" / "native-tageditor.html").read_text( + encoding="utf-8" + ) + native_page_data = ( + ROOT / "frontend" / "dist" / "assets" / "native-tageditor.html.native.js" + ) + app_bundle = (ROOT / "frontend" / "dist" / "assets" / "app.547295de.js").read_text( + encoding="utf-8" + ) + + assert native_page_data.exists() + page_data = native_page_data.read_text(encoding="utf-8") + assert '"key":"v-native-tageditor"' in page_data + assert '"type":"native-dataset-editor"' in page_data + assert '"subtype":"tageditor"' not in page_data + assert '"v-native-tageditor":()=>wt(()=>import("./native-tageditor.html.native.js")' in app_bundle + assert '"v-native-tageditor":()=>wt(()=>import("./tageditor.html.66da263e.js")' not in app_bundle + assert 'rel="modulepreload" href="/assets/tageditor.html.66da263e.js"' not in native_tageditor + assert 'rel="modulepreload" href="/assets/tageditor.html.173f1b6a.js"' not in native_tageditor + + def test_trainer_sidebar_exposes_legacy_and_native_tag_editors(): index = (ROOT / "frontend" / "dist" / "index.html").read_text(encoding="utf-8") tageditor = (ROOT / "frontend" / "dist" / "tageditor.html").read_text(encoding="utf-8") @@ -392,6 +414,7 @@ def test_patched_frontend_core_assets_are_not_immutable_cached(): "/assets/sd-nav-i18n.js", "/assets/app.547295de.js", "/assets/style.874872ce.css", + "/assets/settings.html.06993f96.js", ): response = client.get(path) assert response.status_code == 200 @@ -687,10 +710,55 @@ def test_ui_settings_exposes_dataset_tagger_api_config(): assert "dataset_tagger_api_endpoint" in settings assert "dataset_tagger_api_key" in settings + assert "role('password')" in settings assert "dataset_tagger_api_model" in settings assert "dataset_tagger_api_prompt" in settings + assert "\\u8bbe\\u7f6e" in settings.lower() + assert "\\u8bad\\u7ec3 ui \\u8bbe\\u7f6e" not in settings.lower() assert "./settings.html.06993f96.js?v=dataset-tagger-api" in app_js assert "/assets/app.547295de.js?v=dataset-tagger-api" in settings_html + assert "maskSettingsOutput" in (ROOT / "frontend" / "dist" / "assets" / "sd-nav-i18n.js").read_text( + encoding="utf-8" + ) + + +def test_ui_settings_assets_are_parseable_and_not_mojibake(): + settings = (ROOT / "frontend" / "dist" / "assets" / "settings.html.06993f96.js").read_text( + encoding="utf-8" + ) + settings_html = (ROOT / "frontend" / "dist" / "other" / "settings.html").read_text( + encoding="utf-8" + ) + assert "const e={" in settings + assert '"title":"\\u8bbe\\u7f6e"' in settings.lower() + assert "role('password')" in settings + assert "\u8bbe\u7f6e" in settings_html + assert "\u8bad\u7ec3 UI \u8bbe\u7f6e" not in settings_html + assert not re.search(r"[璁鐠鏍鍦鍏甯]\S*", settings_html) + + +def test_ui_settings_masks_sensitive_output_and_hides_legacy_entries_by_default(): + nav = (ROOT / "frontend" / "dist" / "assets" / "sd-nav-i18n.js").read_text( + encoding="utf-8" + ) + settings = (ROOT / "frontend" / "dist" / "assets" / "settings.html.06993f96.js").read_text( + encoding="utf-8" + ) + + assert "sd-trainer-ui-advanced-links" in nav + assert "showTensorboard: false" in nav + assert "showLegacyTagEditor: false" in nav + assert 'a[href="/tensorboard.md"]' in nav + assert 'a[href="/tageditor.md"]' in nav + assert "隐藏旧功能入口" in nav + assert "maskSettingsOutput" in nav + assert "maskSensitiveSettingsFields" in nav + assert 'input.type = "password"' in nav + assert "renderSettingsHelp" in nav + assert "dataset_tagger_api_key" in nav + assert "当前选项说明" in nav + assert "dataset_tagger_api_key" in settings + assert "role('password')" in settings def test_dataset_editor_tag_endpoint_writes_local_tags_and_api_caption(tmp_path, monkeypatch): From ff6c3c137848f189da36a956913d08ce31bbda3a Mon Sep 17 00:00:00 2001 From: wochenlong Date: Sat, 30 May 2026 01:54:30 +0800 Subject: [PATCH 4/8] docs(editor): update native tag editor handoff --- agent_allinone.md | 42 +++++++++++++++++++++++++++++++++++++++--- 1 file changed, 39 insertions(+), 3 deletions(-) diff --git a/agent_allinone.md b/agent_allinone.md index ea73915e..0b9d105e 100644 --- a/agent_allinone.md +++ b/agent_allinone.md @@ -67,7 +67,9 @@ Useful URLs: - Cache-control workaround in `mikazuki/app/application.py` for patched dist core assets. - Regression tests for route/sidebar JSON parsing and Chinese nav labels. -## Important Recent Bug +## Important Recent Bugs + +### VuePress sidebar JSON and mojibake The VuePress app bundle `frontend/dist/assets/app.547295de.js` contains theme sidebar data as: @@ -85,6 +87,41 @@ Relevant test: python -m pytest tests\test_dataset_editor_api.py::test_vuepress_theme_sidebar_json_stays_parseable -q ``` +### Native editor route loading the classic editor + +Root cause found on 2026-05-30: + +- `/native-tageditor.html` existed and returned HTTP 200. +- The HTML loaded `dataset-editor-entry.js`, so the native editor injection path was present. +- But `frontend/dist/assets/app.547295de.js` mapped the VuePress page key `v-native-tageditor` to the classic editor page data chunk: + +```js +"v-native-tageditor":()=>wt(()=>import("./tageditor.html.66da263e.js"),[]).then(({data:e})=>e) +``` + +That classic chunk exports frontmatter like: + +```json +{"type":"iframe","subtype":"tageditor"} +``` + +So VuePress could render the old iframe/service warning on the native route. This was not primarily a port issue. + +Fix currently on branch: + +- Added `frontend/dist/assets/native-tageditor.html.native.js` as dedicated page data for `v-native-tageditor`. +- Patched `frontend/dist/assets/app.547295de.js` so `v-native-tageditor` imports `native-tageditor.html.native.js`. +- Patched `frontend/dist/native-tageditor.html` so it preloads the native page data chunk instead of old `tageditor.html.*.js` chunks. +- Added regression coverage in `tests/test_dataset_editor_api.py::test_native_tageditor_uses_native_vuepress_page_data`. + +Safe verification snippets for this minified bundle should avoid `Select-String` on the whole single-line file. Use bounded boolean checks instead: + +```powershell +$text = Get-Content frontend/dist/assets/app.547295de.js -Raw -Encoding UTF8 +$text.Contains('"v-native-tageditor":()=>wt(()=>import("./native-tageditor.html.native.js")') +$text.Contains('"v-native-tageditor":()=>wt(()=>import("./tageditor.html.66da263e.js")') +``` + ## Verification Commands Run before claiming the branch is healthy: @@ -96,7 +133,7 @@ python -m pytest tests\test_dataset_editor_api.py tests\test_tagger_progress_api Last known result before this handoff: ```text -47 passed, 4 warnings +50 passed, 4 warnings ``` Browser smoke checks: @@ -120,4 +157,3 @@ Do not commit these runtime files: 3. Improve native editor UI carefully, one small change at a time, with browser checks after each change. 4. Keep the classic editor and native editor separate in navigation. 5. Avoid broad frontend shell rewrites until the current editor flow is stable. - From 1c4bcb43a1f50f4bf3e6bd4487769cfe2f0cdbc0 Mon Sep 17 00:00:00 2001 From: wochenlong Date: Sat, 30 May 2026 02:21:32 +0800 Subject: [PATCH 5/8] docs(frontend): plan source-of-truth recovery --- docs/design/frontend-source-of-truth-plan.md | 224 +++++++++++++++++++ 1 file changed, 224 insertions(+) create mode 100644 docs/design/frontend-source-of-truth-plan.md diff --git a/docs/design/frontend-source-of-truth-plan.md b/docs/design/frontend-source-of-truth-plan.md new file mode 100644 index 00000000..1e348eb9 --- /dev/null +++ b/docs/design/frontend-source-of-truth-plan.md @@ -0,0 +1,224 @@ +# Frontend Source-of-Truth Recovery Plan + +Status: draft +Branch context: `editor` +Created: 2026-05-30 + +## Background + +SD Trainer Next currently serves the trainer WebUI from `frontend/dist/`. That directory is a vendored prebuilt VuePress/Vue application, originally sourced from `hanamizuki-ai/lora-gui-dist`. + +Public upstream history suggests the trainer frontend was published to the main Akegarasu repository as a dist submodule from its first visible integration: + +- `Akegarasu/lora-scripts` first added `frontend` as a submodule in commit `8ea34ab` on 2023-04-23. +- That submodule pointed to `https://github.com/hanamizuki-ai/lora-gui-dist`. +- The visible history of `hanamizuki-ai/lora-gui-dist` contains prebuilt `dist/` files from its earliest commits, not a source project with `package.json`, `src/`, or VuePress config. + +As a result, this fork currently patches compiled assets directly. This has worked for targeted fixes, but it is not a healthy long-term maintenance model. + +## Problem + +Important UI behavior is hidden inside minified build artifacts such as: + +- `frontend/dist/assets/app.547295de.js` +- hashed page-data chunks under `frontend/dist/assets/` +- SSR HTML snapshots under `frontend/dist/**/*.html` + +This creates recurring maintenance risks: + +- Route changes require hand-editing minified bundles. +- Sidebar changes must often be patched in both JS runtime data and SSR HTML. +- Encoding mistakes can corrupt Chinese text. +- Cache-busting and hashed asset names make fixes fragile. +- Multiple agents editing `frontend/dist/` can easily conflict. +- A simple search on a minified single-line bundle can produce huge tool output and destabilize agent sessions. + +The native tag editor work exposed this sharply: `/native-tageditor.html` returned HTTP 200 and loaded the native editor entry script, but VuePress still rendered the classic tag editor because `v-native-tageditor` was mapped to the classic `tageditor.html.*.js` page-data chunk inside `app.547295de.js`. + +## Goal + +Create a maintainable frontend source-of-truth owned by this project. + +In plain terms: future UI changes should be made in source files, then built into `frontend/dist/`, instead of manually patching compiled JavaScript and HTML. + +## Non-Goals + +This project must not become a broad UI rewrite while the native tag editor is still being stabilized. + +Do not do the following in the first phase: + +- Replace the trainer WebUI in `main`. +- Rewrite all training pages at once. +- Change portable contract directories or launch scripts. +- Break existing `frontend/dist/` serving behavior. +- Remove the classic editor before the native editor is proven stable. + +## Recommended Strategy + +Use a staged recovery rather than a big-bang rewrite. + +### Phase 0: Stabilize Current Editor Work + +Finish the native tag editor on the `editor` branch first. + +Required guardrails: + +- Keep `/dataset-editor.html` as standalone fallback/debug. +- Keep `/native-tageditor.html` as the trainer-embedded native editor. +- Keep `/tageditor.html` as the classic editor. +- Keep direct `frontend/dist/` patches small and test-covered. +- Keep the current regression tests for native route mapping, sidebar JSON, and settings behavior. + +Exit criteria: + +- Native editor loads reliably without falling back to the classic editor. +- Real dataset QA covers scan, thumbnails, selection, batch edit/tagging, save, undo, and redo. +- The branch has no known 404/mojibake/cache regressions. + +### Phase 1: Make Dist Patching Reproducible + +Before building a new frontend source tree, script the existing dist patches so they are repeatable. + +Deliverables: + +- A patch script under `scripts/`, for example `scripts/patch_frontend_dist.py`. +- The script should: + - detect expected input assets and hashes, + - patch route mappings, + - patch sidebar/theme data, + - patch SSR HTML where needed, + - validate that JSON blocks still parse, + - fail loudly when upstream dist layout changes. +- Tests should assert the final observable behavior, not just string replacement. + +This phase reduces risk immediately and gives the future frontend rebuild a baseline to compare against. + +### Phase 2: Create a Parallel Source Frontend Branch + +Create a separate branch, suggested name: + +```text +frontend-source +``` + +or: + +```text +app-shell-rebuild +``` + +This branch should not block the `editor` branch. + +Initial source project requirements: + +- Use a modern, boring stack, preferably Vite + Vue 3 + TypeScript. +- Reuse the existing trainer visual language where practical. +- Keep output compatible with the current FastAPI static serving model. +- Produce a `dist` folder that can be served by the existing backend without npm at runtime. +- Keep build tooling out of portable runtime requirements. + +Recommended early pages: + +- Trainer shell/sidebar. +- Settings page. +- Native tag editor page. +- Minimal compatibility routes for existing links. + +Do not migrate all training pages in the first pass unless necessary. + +### Phase 3: Compatibility Layer + +The rebuilt frontend must preserve current public routes or provide backend redirects. + +Important routes include: + +- `/` +- `/tagger.html` +- `/tageditor.html` +- `/native-tageditor.html` +- `/dataset-editor.html` +- `/tensorboard.html` +- `/other/settings.html` +- `/lora/*` + +The source frontend should define routes explicitly in source, with tests covering generated output. + +### Phase 4: Incremental Migration + +Once the new app shell is buildable and served successfully, migrate one page family at a time. + +Suggested order: + +1. Settings and utility pages. +2. Native tag editor. +3. Tagger page and tagging model settings. +4. Training pages only after shell and settings are stable. + +Each migrated area should include: + +- route tests, +- visual smoke checks, +- compatibility checks for old links, +- portable package validation where relevant. + +### Phase 5: Retire Manual Dist Surgery + +When the source frontend can generate the necessary production `dist`, stop hand-editing minified bundles. + +Retirement criteria: + +- No required behavior depends on manual edits to `app.*.js`. +- Sidebar and route data come from source files. +- Settings schema and sensitive-field behavior are source-owned. +- Native editor entry is source-owned. +- Build output is reproducible from a clean checkout. + +## Investigation Tasks for the Next Agent + +The next Codex/agent should start with evidence gathering, not implementation. + +Checklist: + +- Read `frontend/VENDOR.md`. +- Read `agent_allinone.md`. +- Read this document. +- Inspect `mikazuki/app/application.py` static serving behavior. +- Inspect existing tests in `tests/test_dataset_editor_api.py`. +- Confirm current branch state with: + +```powershell +git status --short --untracked-files=all +git log --oneline --decorate -5 +``` + +- Confirm upstream frontend history if needed: + +```powershell +git fetch akegarasu main +git show 8ea34ab3d8e5289b09f6977728979bd704fa806b:.gitmodules +git clone --bare --filter=blob:none https://github.com/hanamizuki-ai/lora-gui-dist.git ../_tmp_lora_gui_dist_bare +git --git-dir=../_tmp_lora_gui_dist_bare ls-tree -r --name-only 62b5805 +``` + +Clean up temporary clones after investigation. + +## Risks + +- Rebuilding the frontend source tree can accidentally regress mature training forms. +- Users rely on current URLs and portable packaging behavior. +- The existing WebUI has many hidden SSR/hydration assumptions. +- Multiple frontend efforts can conflict if they all edit `frontend/dist/` directly. +- A full rewrite before the native editor is stable would multiply risk. + +## Recommendation + +Do not start the full frontend source recovery until the native tag editor reaches a stable milestone. + +After that, create a separate branch and treat this as an engineering infrastructure project: + +1. Make current dist patches reproducible. +2. Build a parallel source-owned shell. +3. Migrate routes incrementally. +4. Retire manual dist patching only after the generated frontend passes compatibility tests. + +This lets the project stop depending on unavailable upstream frontend source without jeopardizing the current editor work. From 22ea5cf2de489d4c059e8e7ba2f17ed9a9b4b411 Mon Sep 17 00:00:00 2001 From: wochenlong <117965575+wochenlong@users.noreply.github.com> Date: Sat, 30 May 2026 02:23:21 +0800 Subject: [PATCH 6/8] fix(editor): clarify native editor batch scope --- frontend/dist/assets/dataset-editor.js | 30 +++++++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-) diff --git a/frontend/dist/assets/dataset-editor.js b/frontend/dist/assets/dataset-editor.js index ea93b17c..41a7b537 100644 --- a/frontend/dist/assets/dataset-editor.js +++ b/frontend/dist/assets/dataset-editor.js @@ -201,6 +201,17 @@ return state.items.filter((item) => selected.has(itemPath(item))); } + function batchScope() { + const count = selectedBatchItems().length; + const selected = state.selectedPaths.size > 0; + return { + count, + selected, + label: selected ? `已选 ${count} 张` : `当前筛选结果 ${count} 张`, + shortLabel: selected ? `已选 ${count}` : `筛选 ${count}`, + }; + } + function pruneSelection() { const existing = new Set(state.items.map((item) => itemPath(item))); state.selectedPaths.forEach((path) => { @@ -430,6 +441,20 @@ el.thumbnailFit.setAttribute("aria-pressed", state.thumbnailFit === "cover" ? "true" : "false"); } + function renderOperationControls() { + const scope = batchScope(); + const disabled = scope.count === 0; + el.batch.disabled = disabled; + el.cleanup.disabled = disabled; + if (el.taggerRun) el.taggerRun.disabled = disabled; + el.batch.textContent = scope.selected ? `应用到已选 ${scope.count} 张` : "应用到当前筛选结果"; + el.cleanup.textContent = scope.selected ? `清理已选 ${scope.count} 张` : "清理当前筛选结果"; + if (el.taggerRun) el.taggerRun.textContent = `开始打标(${scope.shortLabel})`; + el.batch.title = `将修改${scope.label}`; + el.cleanup.title = `将清理${scope.label}`; + if (el.taggerRun) el.taggerRun.title = `将为${scope.label}打标`; + } + function renderEditor() { const item = currentItem(); el.dirtyFlag.textContent = state.dirty ? "未保存" : ""; @@ -438,8 +463,7 @@ el.redo.disabled = !state.canRedo; el.prev.disabled = state.selected <= 0; el.next.disabled = state.selected < 0 || state.selected >= state.filtered.length - 1; - el.batch.disabled = state.filtered.length === 0; - if (el.taggerRun) el.taggerRun.disabled = state.filtered.length === 0; + renderOperationControls(); if (!item) { el.preview.innerHTML = "未选择图片"; @@ -804,7 +828,7 @@ } catch (err) { setStatus(err.message, true); } finally { - el.taggerRun.disabled = state.filtered.length === 0; + renderOperationControls(); } } From d642f2eb1dc48bfe335899fbc7f887758cd2585d Mon Sep 17 00:00:00 2001 From: wochenlong <117965575+wochenlong@users.noreply.github.com> Date: Sat, 30 May 2026 02:44:58 +0800 Subject: [PATCH 7/8] chore(frontend): script native editor dist patches --- docs/design/frontend-source-of-truth-plan.md | 5 + frontend/dist/dreambooth/index.html | 2 +- frontend/dist/help/guide.html | 2 +- frontend/dist/lora/anima-finetune.html | 2 +- frontend/dist/lora/basic.html | 2 +- frontend/dist/lora/flux.html | 2 +- frontend/dist/lora/index.html | 2 +- frontend/dist/lora/master.html | 2 +- frontend/dist/lora/params.html | 2 +- frontend/dist/lora/sd3.html | 2 +- frontend/dist/lora/sdxl.html | 2 +- frontend/dist/lora/tools.html | 2 +- frontend/dist/other/about.html | 2 +- frontend/dist/other/changelog.html | 2 +- frontend/dist/other/settings.html | 2 +- frontend/dist/tagger.html | 2 +- frontend/dist/task.html | 2 +- frontend/dist/tensorboard.html | 2 +- scripts/patch_frontend_dist.py | 251 +++++++++++++++++++ tests/test_dataset_editor_api.py | 28 +++ 20 files changed, 301 insertions(+), 17 deletions(-) create mode 100644 scripts/patch_frontend_dist.py diff --git a/docs/design/frontend-source-of-truth-plan.md b/docs/design/frontend-source-of-truth-plan.md index 1e348eb9..33a8fab0 100644 --- a/docs/design/frontend-source-of-truth-plan.md +++ b/docs/design/frontend-source-of-truth-plan.md @@ -4,6 +4,11 @@ Status: draft Branch context: `editor` Created: 2026-05-30 +## Progress + +- 2026-05-30: Added `scripts/patch_frontend_dist.py` to reapply and validate the current native tag editor dist patches. The script covers the VuePress app route mapping, sidebar JSON, native page-data chunk, native page preload contract, settings cache-bust URL, and SSR sidebar snapshots. +- 2026-05-30: The first script run found older SSR pages that still exposed the single `标签编辑` sidebar entry. Those snapshots were updated to split `经典标签编辑` and `原生标签编辑`, with regression coverage in `tests/test_dataset_editor_api.py`. + ## Background SD Trainer Next currently serves the trainer WebUI from `frontend/dist/`. That directory is a vendored prebuilt VuePress/Vue application, originally sourced from `hanamizuki-ai/lora-gui-dist`. diff --git a/frontend/dist/dreambooth/index.html b/frontend/dist/dreambooth/index.html index 97d1ac54..96ebb8c2 100644 --- a/frontend/dist/dreambooth/index.html +++ b/frontend/dist/dreambooth/index.html @@ -30,7 +30,7 @@ -

Dreambooth 训练 专家模式

你所热爱的 就是你的参数

参数预览
Loading...
Output
+

Dreambooth 训练 专家模式

你所热爱的 就是你的参数

参数预览
Loading...
Output
diff --git a/frontend/dist/help/guide.html b/frontend/dist/help/guide.html index 6d719b7c..1459bbde 100644 --- a/frontend/dist/help/guide.html +++ b/frontend/dist/help/guide.html @@ -30,7 +30,7 @@ -
Next Trainer

新手上路

  1. 准备数据:训练图片 + 同名 .txt 标签;可用「工具与调试 → 数据集打标」。
  2. 选择训练类型(侧栏「训练」):
  3. 填写参数并开训:中栏表单 → 右栏「开始训练」。
  4. 查看进度训练监控Tensorboard

从秋叶版迁移

若你使用过 Akegarasu/lora-scripts(秋叶一键包),本版主要变化:

  • 品牌:项目名 lora-scripts-next / Next Trainer,侧栏按「训练 / 工具 / 帮助 / 其他」分组。
  • 导航:LoRA 与全量微调分栏;原「新手 / 专家」不再平铺(SD1.5 精简页:/lora/basic.html)。
  • Anima:LoRA 与 Finetune 分入口(Qwen + T5 + DiT)。
  • 监控:独立 训练监控页、Loss 曲线、/train-log 日志流。
  • 更多版本说明见 更新日志
+
Next Trainer

新手上路

  1. 准备数据:训练图片 + 同名 .txt 标签;可用「工具与调试 → 数据集打标」。
  2. 选择训练类型(侧栏「训练」):
  3. 填写参数并开训:中栏表单 → 右栏「开始训练」。
  4. 查看进度训练监控Tensorboard

从秋叶版迁移

若你使用过 Akegarasu/lora-scripts(秋叶一键包),本版主要变化:

  • 品牌:项目名 lora-scripts-next / Next Trainer,侧栏按「训练 / 工具 / 帮助 / 其他」分组。
  • 导航:LoRA 与全量微调分栏;原「新手 / 专家」不再平铺(SD1.5 精简页:/lora/basic.html)。
  • Anima:LoRA 与 Finetune 分入口(Qwen + T5 + DiT)。
  • 监控:独立 训练监控页、Loss 曲线、/train-log 日志流。
  • 更多版本说明见 更新日志
diff --git a/frontend/dist/lora/anima-finetune.html b/frontend/dist/lora/anima-finetune.html index f9c19e5c..0944a152 100644 --- a/frontend/dist/lora/anima-finetune.html +++ b/frontend/dist/lora/anima-finetune.html @@ -30,7 +30,7 @@ -

anima-finetune ,一切皆有可能

Anima Finetune

Anima DiT 全量微调(full finetune)

更新完整 DiT 权重,适合进阶玩家训练,需充足样本与高显存

参数预览
Loading...
Output
+

anima-finetune ,一切皆有可能

Anima Finetune

Anima DiT 全量微调(full finetune)

更新完整 DiT 权重,适合进阶玩家训练,需充足样本与高显存

参数预览
Loading...
Output
diff --git a/frontend/dist/lora/basic.html b/frontend/dist/lora/basic.html index b851259f..2a81bbca 100644 --- a/frontend/dist/lora/basic.html +++ b/frontend/dist/lora/basic.html @@ -30,7 +30,7 @@ -

LoRA 训练 新手模式

默认设置为你准备好了所有需要的参数,只需要你修改底模路径、训练集路径、训练轮数即可一键训练模型。

训练 SDXL 模型的 LoRA 请前往专家模式,训练种类选择 sdxl-lora

参数预览
Loading...
Output
+

LoRA 训练 新手模式

默认设置为你准备好了所有需要的参数,只需要你修改底模路径、训练集路径、训练轮数即可一键训练模型。

训练 SDXL 模型的 LoRA 请前往专家模式,训练种类选择 sdxl-lora

参数预览
Loading...
Output
diff --git a/frontend/dist/lora/flux.html b/frontend/dist/lora/flux.html index e9d95e7b..3ca02192 100644 --- a/frontend/dist/lora/flux.html +++ b/frontend/dist/lora/flux.html @@ -30,7 +30,7 @@ -

Flux Stable Diffusion LoRA

Flux.1 模型 LoRA 训练 专家模式

别问为什么新手模式不行,问就是你都用 FLUX 了还想当新手?

参数预览
Loading...
Output
+

Flux Stable Diffusion LoRA

Flux.1 模型 LoRA 训练 专家模式

别问为什么新手模式不行,问就是你都用 FLUX 了还想当新手?

参数预览
Loading...
Output
diff --git a/frontend/dist/lora/index.html b/frontend/dist/lora/index.html index ba127ec9..017f991f 100644 --- a/frontend/dist/lora/index.html +++ b/frontend/dist/lora/index.html @@ -30,7 +30,7 @@ -

LoRA 训练

LoRA 为局部微调;全量微调请使用侧栏 Dreambooth 训练

  • Anima — 主推训练入口(Anima DiT)
  • Flux — Flux 模型 LoRA
  • Stable Diffusion — SD1.5 / SDXL(页顶切换训练种类,默认 SDXL)

打标、看日志、脚本工具等在侧栏 工具与调试;参数说明在 帮助

SD1.5 精简参数页仍保留:/lora/basic.html

+

LoRA 训练

LoRA 为局部微调;全量微调请使用侧栏 Dreambooth 训练

  • Anima — 主推训练入口(Anima DiT)
  • Flux — Flux 模型 LoRA
  • Stable Diffusion — SD1.5 / SDXL(页顶切换训练种类,默认 SDXL)

打标、看日志、脚本工具等在侧栏 工具与调试;参数说明在 帮助

SD1.5 精简参数页仍保留:/lora/basic.html

diff --git a/frontend/dist/lora/master.html b/frontend/dist/lora/master.html index 9191725f..c32d1043 100644 --- a/frontend/dist/lora/master.html +++ b/frontend/dist/lora/master.html @@ -30,7 +30,7 @@ -

Stable Diffusion LoRA

SD1.5 与 SDXL 共用本页:在「训练种类」中切换。默认 SDXL。SD1.5 精简入口见 SD1.5 精简

参数预览
Loading...
Output
+

Stable Diffusion LoRA

SD1.5 与 SDXL 共用本页:在「训练种类」中切换。默认 SDXL。SD1.5 精简入口见 SD1.5 精简

参数预览
Loading...
Output
diff --git a/frontend/dist/lora/params.html b/frontend/dist/lora/params.html index 507be10e..8003096a 100644 --- a/frontend/dist/lora/params.html +++ b/frontend/dist/lora/params.html @@ -30,7 +30,7 @@ -

训练参数调节

设置训练用模型、数据集

底模选择

底模,尽量选祖宗级别的模型练出来的LoRA会更通用。如果在融合模型上训练可能会仅仅在你训练的底模上生成图片拥有不错的效果 但是失去了通用性。可以自己抉择

什么是祖宗级别的模型?

sd1.5 2.0、novelai 原版泄露模型。也就是非融合模型。融合模型比如 anything 系列融合了一大堆,orangemix系列融合了 anything 和 basil 更灵车了等等。在他们上面训练的会迁移性更差一些。

训练分辨率

训练时的分辨率 宽,高,可以是非正方形,但必须为64的整数倍。建议使用大于 512x512 且小于 1024x1024 的值,长宽比根据训练集的占比决定,一般来说方形的可以照顾到各种不同的分辨率。如果多数为长图可以使用512x768这种分辨率,如果宽图居多则可以使用768x512等。

ARB 桶

默认开启 ARB 桶,以允许使用非固定宽高比的图像来训练(简单来说就是不需要手动剪裁了)。ARB 桶在一定程度上会增加训练时间。 ARB桶分辨率必须大于训练分辨率

学习率与优化器设置

学习率设置

UNet和TE的学习率通常是不同的,因为学习难度不同,通常UNet的学习率会比TE高 。

如图所示,我们希望UNet和TE都处于一个恰好的位置(绿色部分),但是这个值我们不知道。

如果UNet训练不足,那么生成的图会不像,UNet训练过度会导致面部扭曲或者产生大量色块。TE训练不足会让出图对Prompt的服从度低,TE训练过度则会生成多余的物品。

总学习步数 = (图片数量 * 重复次数 * epoch)/ 批次大小

以UNet学习率为1e-4为例,一般来说图片较少的时候训练人物需要至少1000步,训练画风则需要至少2500步,训练概念则需要至少3000步。这里只是最低的步数,图片多则需要更多步数。学习率更大可以适当减少步数,但并非线性关系,使用两倍的学习率需要使用比之前步数的一半更多的步数。

决定学习率和步数的最好方法是先训练,再测试。一般比较好的初始值为UNet使用1e-4,TE使用5e-5

学习率调整策略(lr_scheduler)

推荐使用余弦退火cosine。如果开启预热,预热步数应该占总步数的5%-10%。

如果使用带重启的余弦退火cosine_with_restarts,重启次数不应该超过4次。

批次大小 (batch_size)

Batch size 越大梯度越稳定,也可以使用更大的学习率来加速收敛,但是占用显存也更大。

一般而言 2 倍的 batch_size 可以使用两倍的 UNet 学习率,但是TE学习率不能提高太多。

优化器

这里只介绍最常用的三种:

  • AdamW8bit:启用的int8优化的AdamW优化器,默认选项。
  • Lion:Google Brain发表的新优化器,各方面表现优于AdamW,同时占用显存更小,可能需要更大的batch size以保持梯度更新稳定。
  • D-Adaptation:FB发表的自适应学习率的优化器,调参简单,无需手动控制学习率,但是占用显存巨大(通常需要大于8G)。使用时设置学习率为1即可,同时学习率调整策略使用constant。需要添加"--optimizer_args decouple=True"来分离UNet和TE的学习率。(这些设置训练UI都会帮你自动处理)

网络设置

网络结构(LoRA/LoCon/LoHa/DyLoRA)

不同网络结构对应不同的矩阵低秩分解方法。LoRA 是老祖宗,只控制模型中的线性层和1x1卷积层,后续的不同网络结构都是在 LoRA 的基础上进行改进。

LyCORIS 对其进行改进,添加了其他几种算法:

  • LoCon 加入了对卷积层 (Conv) 的控制
  • LoHa(哈达玛积)和 LoKr(克罗内克积)
  • IA3

理论上来说 LyCORIS 会比 LoRA 拥有更加强的微调效果,但是也更加容易过拟合。

需要注意的是,不同的网络结构一般需要对应不同的 dim 以及学习率。

网络大小

网络大小应该根据实际的训练集图片数量和使用的网络结构决定

network_dim

上表中值为我自己的角色训练推荐值,训练画风和概念需要适当增加 Linear 部分大小。推荐值并非对各个不同的数据集都是最优的,需要自己实验得出最优。Conv 的大小最好不要超过8。

网络Alpha(network_alpha)

alpha在训练期间缩放网络的权重,alpha越小学习越慢,关系可以认为是负线性相关的。

一般设置为dim/2或者dim/4。如果选择1,则需要提高学习率或者使用D-Adapation优化器。

高级设置

Caption 相关

caption dropout

网上关于这几个caption dropout的说明少之又少,甚至作者在文档里面也没有包含这些参数,只能在代码注释里面找到说明。但是caption dropout在某些情况下对模型性能有提升,所以拿出来讲一下。

caption_dropout_rate:丢弃全部标签的概率,对一个图片概率不使用caption或class token

caption_dropout_every_n_epochs:每N个epoch丢弃全部标签。

caption_tag_dropout_rate:按逗号分隔的标签来随机丢弃tag的概率。如果使用DB+标签的训练方法训练画风,推荐使用这个参数,能够有效防止tag过拟合,一般选择0.2-0.5之间的值训练人物则无需开启

token 热身

两个token热身相关的参数。

token_warmup_min:最小学习的token数量,token_warmup_step: 在多少步后达到最大token数量。

token_warmup可以理解为另一种形式的caption dropout,但是如果不随机打乱token,则只会学习前面N个token。本人并未实测过启用这两个参数的效果,有兴趣可以自行实验。

噪声相关

噪声偏移(noise_offset)

在训练过程中加入全局的噪声,改善图片的亮度变化范围(能生成更黑或者更白的图片)。

如果需要开启,推荐设置值为0.1同时需要增加学习步数作为网络收敛更慢的补偿

多分辨率/金字塔噪声 multires_noise_iterations、multires_noise_discount

多分辨率/金字塔噪声相关参数。iteration设置在6-8,再高提升不大。discount设置在0.3-0.8之间,更小的值需要更多步数。

其他一堆参数

  • CLIP_SKIP CLIP模型使用倒数第N层的输出,需要与底模使用的值保持一致,如果是基于NAI的二次元模型,应当使用2。如果是SD1.5等真实模型应当使用1。生成时也应该使用同样的值。

  • Min-SNR-γ 发表于 ICCV2023 上的一种加速扩散模型收敛的方法 Efficient Diffusion Training via Min-SNR Weighting Strategyopen in new window。不同样本批次的学习难度不同导致梯度方向不一致所以收敛慢,于是引入根据信噪比调整学习率比重。 设置在5左右的值是实验效果比较好的。

  • 数据增强相关 数据增强是在训练时实时对图片做变换的方法,可用于防止过拟合,能用的一共有四种: color_aug, flip_aug, face_crop_aug_range, random_crop。 其中只有翻转(flip_aug)能和cache latent兼容,因为latent可以直接翻转。 四种都不推荐使用,因为裁剪图片的两种cropping方法都会导致tag对应不上。color_aug无法启用cache latent导致训练慢,得不偿失。翻转的flip_aug在图像不对称的情况下表现差,会导致无法正确生成人物不对称的特征(刘海、发饰等)。

  • max_grad_norm 限制模型更新梯度的大小,改善数值稳定性。梯度的范数超过这个值将会被缩放到这个大小,一般来说无需设置

  • gradient_accumulation_steps 梯度累积步数,用于在小显存上模拟大batch size的效果。如果显存足够使用4以上的batch size就没必要启用

  • log_with、wandb_api_key 选择logger类型,可选tensorboard或者wandb。使用wandb需要指定api key。

  • prior_loss_weight DB训练当中先验部分的权重,控制正则化图像的强度,论文中使用的是1的值,如无特殊情况无需更改

  • debug_dataset 不训练模型,仅输出训练集元数据和训练参数信息,可以用来检查各项设置是否正确。

  • vae_batch_size cache lantent的时候VAE编码器的batch size,和训练效果无关。一般来说使用2-4可以加速一点cache latent的过程。因为VAE编码器本身参数量比较小,实测在Linux机器上8G的显卡也能开启4。Windows下系统占用显存较多,显存小于10G不建议开启。

TIP

文档尚未完结~!

by 秋葉open in new window & Impossib1e嗨open in new window

感谢 Impossib1e嗨 贡献的大量文档

+

训练参数调节

设置训练用模型、数据集

底模选择

底模,尽量选祖宗级别的模型练出来的LoRA会更通用。如果在融合模型上训练可能会仅仅在你训练的底模上生成图片拥有不错的效果 但是失去了通用性。可以自己抉择

什么是祖宗级别的模型?

sd1.5 2.0、novelai 原版泄露模型。也就是非融合模型。融合模型比如 anything 系列融合了一大堆,orangemix系列融合了 anything 和 basil 更灵车了等等。在他们上面训练的会迁移性更差一些。

训练分辨率

训练时的分辨率 宽,高,可以是非正方形,但必须为64的整数倍。建议使用大于 512x512 且小于 1024x1024 的值,长宽比根据训练集的占比决定,一般来说方形的可以照顾到各种不同的分辨率。如果多数为长图可以使用512x768这种分辨率,如果宽图居多则可以使用768x512等。

ARB 桶

默认开启 ARB 桶,以允许使用非固定宽高比的图像来训练(简单来说就是不需要手动剪裁了)。ARB 桶在一定程度上会增加训练时间。 ARB桶分辨率必须大于训练分辨率

学习率与优化器设置

学习率设置

UNet和TE的学习率通常是不同的,因为学习难度不同,通常UNet的学习率会比TE高 。

如图所示,我们希望UNet和TE都处于一个恰好的位置(绿色部分),但是这个值我们不知道。

如果UNet训练不足,那么生成的图会不像,UNet训练过度会导致面部扭曲或者产生大量色块。TE训练不足会让出图对Prompt的服从度低,TE训练过度则会生成多余的物品。

总学习步数 = (图片数量 * 重复次数 * epoch)/ 批次大小

以UNet学习率为1e-4为例,一般来说图片较少的时候训练人物需要至少1000步,训练画风则需要至少2500步,训练概念则需要至少3000步。这里只是最低的步数,图片多则需要更多步数。学习率更大可以适当减少步数,但并非线性关系,使用两倍的学习率需要使用比之前步数的一半更多的步数。

决定学习率和步数的最好方法是先训练,再测试。一般比较好的初始值为UNet使用1e-4,TE使用5e-5

学习率调整策略(lr_scheduler)

推荐使用余弦退火cosine。如果开启预热,预热步数应该占总步数的5%-10%。

如果使用带重启的余弦退火cosine_with_restarts,重启次数不应该超过4次。

批次大小 (batch_size)

Batch size 越大梯度越稳定,也可以使用更大的学习率来加速收敛,但是占用显存也更大。

一般而言 2 倍的 batch_size 可以使用两倍的 UNet 学习率,但是TE学习率不能提高太多。

优化器

这里只介绍最常用的三种:

  • AdamW8bit:启用的int8优化的AdamW优化器,默认选项。
  • Lion:Google Brain发表的新优化器,各方面表现优于AdamW,同时占用显存更小,可能需要更大的batch size以保持梯度更新稳定。
  • D-Adaptation:FB发表的自适应学习率的优化器,调参简单,无需手动控制学习率,但是占用显存巨大(通常需要大于8G)。使用时设置学习率为1即可,同时学习率调整策略使用constant。需要添加"--optimizer_args decouple=True"来分离UNet和TE的学习率。(这些设置训练UI都会帮你自动处理)

网络设置

网络结构(LoRA/LoCon/LoHa/DyLoRA)

不同网络结构对应不同的矩阵低秩分解方法。LoRA 是老祖宗,只控制模型中的线性层和1x1卷积层,后续的不同网络结构都是在 LoRA 的基础上进行改进。

LyCORIS 对其进行改进,添加了其他几种算法:

  • LoCon 加入了对卷积层 (Conv) 的控制
  • LoHa(哈达玛积)和 LoKr(克罗内克积)
  • IA3

理论上来说 LyCORIS 会比 LoRA 拥有更加强的微调效果,但是也更加容易过拟合。

需要注意的是,不同的网络结构一般需要对应不同的 dim 以及学习率。

网络大小

网络大小应该根据实际的训练集图片数量和使用的网络结构决定

network_dim

上表中值为我自己的角色训练推荐值,训练画风和概念需要适当增加 Linear 部分大小。推荐值并非对各个不同的数据集都是最优的,需要自己实验得出最优。Conv 的大小最好不要超过8。

网络Alpha(network_alpha)

alpha在训练期间缩放网络的权重,alpha越小学习越慢,关系可以认为是负线性相关的。

一般设置为dim/2或者dim/4。如果选择1,则需要提高学习率或者使用D-Adapation优化器。

高级设置

Caption 相关

caption dropout

网上关于这几个caption dropout的说明少之又少,甚至作者在文档里面也没有包含这些参数,只能在代码注释里面找到说明。但是caption dropout在某些情况下对模型性能有提升,所以拿出来讲一下。

caption_dropout_rate:丢弃全部标签的概率,对一个图片概率不使用caption或class token

caption_dropout_every_n_epochs:每N个epoch丢弃全部标签。

caption_tag_dropout_rate:按逗号分隔的标签来随机丢弃tag的概率。如果使用DB+标签的训练方法训练画风,推荐使用这个参数,能够有效防止tag过拟合,一般选择0.2-0.5之间的值训练人物则无需开启

token 热身

两个token热身相关的参数。

token_warmup_min:最小学习的token数量,token_warmup_step: 在多少步后达到最大token数量。

token_warmup可以理解为另一种形式的caption dropout,但是如果不随机打乱token,则只会学习前面N个token。本人并未实测过启用这两个参数的效果,有兴趣可以自行实验。

噪声相关

噪声偏移(noise_offset)

在训练过程中加入全局的噪声,改善图片的亮度变化范围(能生成更黑或者更白的图片)。

如果需要开启,推荐设置值为0.1同时需要增加学习步数作为网络收敛更慢的补偿

多分辨率/金字塔噪声 multires_noise_iterations、multires_noise_discount

多分辨率/金字塔噪声相关参数。iteration设置在6-8,再高提升不大。discount设置在0.3-0.8之间,更小的值需要更多步数。

其他一堆参数

  • CLIP_SKIP CLIP模型使用倒数第N层的输出,需要与底模使用的值保持一致,如果是基于NAI的二次元模型,应当使用2。如果是SD1.5等真实模型应当使用1。生成时也应该使用同样的值。

  • Min-SNR-γ 发表于 ICCV2023 上的一种加速扩散模型收敛的方法 Efficient Diffusion Training via Min-SNR Weighting Strategyopen in new window。不同样本批次的学习难度不同导致梯度方向不一致所以收敛慢,于是引入根据信噪比调整学习率比重。 设置在5左右的值是实验效果比较好的。

  • 数据增强相关 数据增强是在训练时实时对图片做变换的方法,可用于防止过拟合,能用的一共有四种: color_aug, flip_aug, face_crop_aug_range, random_crop。 其中只有翻转(flip_aug)能和cache latent兼容,因为latent可以直接翻转。 四种都不推荐使用,因为裁剪图片的两种cropping方法都会导致tag对应不上。color_aug无法启用cache latent导致训练慢,得不偿失。翻转的flip_aug在图像不对称的情况下表现差,会导致无法正确生成人物不对称的特征(刘海、发饰等)。

  • max_grad_norm 限制模型更新梯度的大小,改善数值稳定性。梯度的范数超过这个值将会被缩放到这个大小,一般来说无需设置

  • gradient_accumulation_steps 梯度累积步数,用于在小显存上模拟大batch size的效果。如果显存足够使用4以上的batch size就没必要启用

  • log_with、wandb_api_key 选择logger类型,可选tensorboard或者wandb。使用wandb需要指定api key。

  • prior_loss_weight DB训练当中先验部分的权重,控制正则化图像的强度,论文中使用的是1的值,如无特殊情况无需更改

  • debug_dataset 不训练模型,仅输出训练集元数据和训练参数信息,可以用来检查各项设置是否正确。

  • vae_batch_size cache lantent的时候VAE编码器的batch size,和训练效果无关。一般来说使用2-4可以加速一点cache latent的过程。因为VAE编码器本身参数量比较小,实测在Linux机器上8G的显卡也能开启4。Windows下系统占用显存较多,显存小于10G不建议开启。

TIP

文档尚未完结~!

by 秋葉open in new window & Impossib1e嗨open in new window

感谢 Impossib1e嗨 贡献的大量文档

diff --git a/frontend/dist/lora/sd3.html b/frontend/dist/lora/sd3.html index f2cde7cc..a2aa8c1e 100644 --- a/frontend/dist/lora/sd3.html +++ b/frontend/dist/lora/sd3.html @@ -30,7 +30,7 @@ -

Anima Stable Diffusion LoRA

Anima DiT 模型 LoRA 训练 专家模式

Anima DiT 训练入口,使用 Qwen3 + T5 + Anima 专用参数

参数预览
Loading...
Output
+

Anima Stable Diffusion LoRA

Anima DiT 模型 LoRA 训练 专家模式

Anima DiT 训练入口,使用 Qwen3 + T5 + Anima 专用参数

参数预览
Loading...
Output
diff --git a/frontend/dist/lora/sdxl.html b/frontend/dist/lora/sdxl.html index 9145c88f..797221f1 100644 --- a/frontend/dist/lora/sdxl.html +++ b/frontend/dist/lora/sdxl.html @@ -30,7 +30,7 @@ -

SDXL Stable Diffusion LoRA

SDXL 模型 LoRA 训练

参数预览
Loading...
Output
+

SDXL Stable Diffusion LoRA

SDXL 模型 LoRA 训练

参数预览
Loading...
Output
diff --git a/frontend/dist/lora/tools.html b/frontend/dist/lora/tools.html index 0e009140..32c9f630 100644 --- a/frontend/dist/lora/tools.html +++ b/frontend/dist/lora/tools.html @@ -30,7 +30,7 @@ -

参数设置

script_name

脚本名称

+

参数设置

script_name

脚本名称

LoRA 脚本工具

  • networks/extract_lora_from_models 使用 SVD 从两个模型中近似提取 LoRA
  • networks/extract_lora_from_dylora.py 从 DyLoRA 中提取 LoRA
参数预览
{ }
diff --git a/frontend/dist/other/about.html b/frontend/dist/other/about.html index 673ff516..49ab3395 100644 --- a/frontend/dist/other/about.html +++ b/frontend/dist/other/about.html @@ -30,7 +30,7 @@ - + diff --git a/frontend/dist/other/changelog.html b/frontend/dist/other/changelog.html index 6bb44690..7abeeb3e 100644 --- a/frontend/dist/other/changelog.html +++ b/frontend/dist/other/changelog.html @@ -30,7 +30,7 @@ -

更新日志

GitHub Repo starsGitHub forkslicenserelease

版本记录

v2.6.0

  • Anima 全量微调:侧栏「全量微调 → Anima Finetune」,路由 anima-finetuneanima_train.py
  • 训练监控正确显示 Anima Finetune(不再误标为 LoRA)
  • 文档与示例:docs/anima-backend.mddocs/examples/anima-full-finetune.toml
  • 显存参考:4090 实测专用显存约 23–24 GB(与 LoRA 的 12GB 档不同)

v2.5.3

  • 便携包依赖健康检查、侧栏版本号(#54

v2.5.0

  • UI 焕新:侧栏导航重构,训练 / 工具 / 帮助分区清晰
  • 首页传送门:卡片式入口快速跳转训练、监控、新手上路
  • 训练监控仪表盘:GPU 实时指标、总步数、训练参数速查
  • CSS 去重清理(~1660 行冗余代码)

v2.4.0

  • 训练子进程环境隔离,NaN 过滤,采样保护,attn_mode 降级
  • 路径规范化;整合包 tkinter 修复

v2.3.0

  • TensorBoard 同源 Loss 曲线;训练参数速查;日志同步到监控页
  • 整合包:跳过 triton-windows;run_gui 启动日志;跨盘监控修复

v2.1.0

  • Flash Attention 2 预构建 Wheel(Windows 免编译)
  • 按步数保存;LoKr 显示修复;跨盘监控修复

v2.0.0

  • Windows 便携包首发;Flash Attention 自动加速;AMD 提示;bf16 修复

基于原版的改进

  • Anima 训练(LoRA / LoKr / T-LoRA)
  • 交互式 Loss 曲线;实时训练监控(端口 6008)
  • Anima 后端迁移至 kohya-ss/sd-scripts

原版更新日志

本项目 Fork 自 Akegarasu/lora-scripts,完整记录见仓库根目录 CHANGELOG.md

+

更新日志

GitHub Repo starsGitHub forkslicenserelease

版本记录

v2.6.0

  • Anima 全量微调:侧栏「全量微调 → Anima Finetune」,路由 anima-finetuneanima_train.py
  • 训练监控正确显示 Anima Finetune(不再误标为 LoRA)
  • 文档与示例:docs/anima-backend.mddocs/examples/anima-full-finetune.toml
  • 显存参考:4090 实测专用显存约 23–24 GB(与 LoRA 的 12GB 档不同)

v2.5.3

  • 便携包依赖健康检查、侧栏版本号(#54

v2.5.0

  • UI 焕新:侧栏导航重构,训练 / 工具 / 帮助分区清晰
  • 首页传送门:卡片式入口快速跳转训练、监控、新手上路
  • 训练监控仪表盘:GPU 实时指标、总步数、训练参数速查
  • CSS 去重清理(~1660 行冗余代码)

v2.4.0

  • 训练子进程环境隔离,NaN 过滤,采样保护,attn_mode 降级
  • 路径规范化;整合包 tkinter 修复

v2.3.0

  • TensorBoard 同源 Loss 曲线;训练参数速查;日志同步到监控页
  • 整合包:跳过 triton-windows;run_gui 启动日志;跨盘监控修复

v2.1.0

  • Flash Attention 2 预构建 Wheel(Windows 免编译)
  • 按步数保存;LoKr 显示修复;跨盘监控修复

v2.0.0

  • Windows 便携包首发;Flash Attention 自动加速;AMD 提示;bf16 修复

基于原版的改进

  • Anima 训练(LoRA / LoKr / T-LoRA)
  • 交互式 Loss 曲线;实时训练监控(端口 6008)
  • Anima 后端迁移至 kohya-ss/sd-scripts

原版更新日志

本项目 Fork 自 Akegarasu/lora-scripts,完整记录见仓库根目录 CHANGELOG.md

diff --git a/frontend/dist/other/settings.html b/frontend/dist/other/settings.html index a326b696..6f247d5e 100644 --- a/frontend/dist/other/settings.html +++ b/frontend/dist/other/settings.html @@ -30,7 +30,7 @@ -

设置

tensorboard_url

tensorboard 地址

+

设置

tensorboard_url

tensorboard 地址

设置

不懂的不要改这个

Output
{ }
diff --git a/frontend/dist/tagger.html b/frontend/dist/tagger.html index 404f1911..df84f321 100644 --- a/frontend/dist/tagger.html +++ b/frontend/dist/tagger.html @@ -30,7 +30,7 @@ -

Tagger 标注工具

后端基于 wd14-tagger 开发。

(如果你自行部署,或有良好的网络访问环境,请忽略这行)训练包内自带默认离线模型 SmilingWolf/wd-v1-4-convnextv2-tagger-v2 如果你选择了其他模型,可能需要额外连接到 Huggingface 进行下载。

已更新 v3 的 Tagger 模型。

已更新 large 系列的 Tagger 模型。

已更新 CL 系列的 Tagger 模型。

推荐参数

阈值大于 0.35

+

Tagger 标注工具

后端基于 wd14-tagger 开发。

(如果你自行部署,或有良好的网络访问环境,请忽略这行)训练包内自带默认离线模型 SmilingWolf/wd-v1-4-convnextv2-tagger-v2 如果你选择了其他模型,可能需要额外连接到 Huggingface 进行下载。

已更新 v3 的 Tagger 模型。

已更新 large 系列的 Tagger 模型。

已更新 CL 系列的 Tagger 模型。

推荐参数

阈值大于 0.35

diff --git a/frontend/dist/task.html b/frontend/dist/task.html index e4ea3be7..5eec2de6 100644 --- a/frontend/dist/task.html +++ b/frontend/dist/task.html @@ -30,7 +30,7 @@ - + diff --git a/frontend/dist/tensorboard.html b/frontend/dist/tensorboard.html index fff6824e..e3072373 100644 --- a/frontend/dist/tensorboard.html +++ b/frontend/dist/tensorboard.html @@ -30,7 +30,7 @@ - + diff --git a/scripts/patch_frontend_dist.py b/scripts/patch_frontend_dist.py new file mode 100644 index 00000000..14fcce18 --- /dev/null +++ b/scripts/patch_frontend_dist.py @@ -0,0 +1,251 @@ +#!/usr/bin/env python3 +"""Reapply and validate the local frontend/dist patches. + +The trainer frontend is a vendored VuePress dist. Until a source-owned +frontend exists, route/sidebar/page-data edits need to be reproducible instead +of relying on ad hoc minified-bundle edits. +""" + +from __future__ import annotations + +import argparse +import json +import re +import sys +from pathlib import Path + + +APP_BUNDLE = Path("frontend/dist/assets/app.547295de.js") +NATIVE_PAGE_DATA = Path("frontend/dist/assets/native-tageditor.html.native.js") +NATIVE_HTML = Path("frontend/dist/native-tageditor.html") +SETTINGS_HTML = Path("frontend/dist/other/settings.html") + +SIDEBAR_RE = re.compile(r"const WE=JSON\.parse\(`(?P.*?)`\),x0=") +OLD_NATIVE_ROUTE = ( + '"v-native-tageditor":()=>wt(()=>import("./tageditor.html.66da263e.js"),[]).then(({data:e})=>e)' +) +NEW_NATIVE_ROUTE = ( + '"v-native-tageditor":()=>wt(()=>import("./native-tageditor.html.native.js"),[]).then(({data:e})=>e)' +) +OLD_SETTINGS_ROUTE = ( + '"v-72e1da3e":()=>wt(()=>import("./settings.html.06993f96.js"),[]).then(({data:e})=>e)' +) +NEW_SETTINGS_ROUTE = ( + '"v-72e1da3e":()=>wt(()=>import("./settings.html.06993f96.js?v=dataset-tagger-api"),[]).then(({data:e})=>e)' +) +NATIVE_PAGE_DATA_TEXT = ( + "const e=JSON.parse('{" + '"key":"v-native-tageditor",' + '"path":"/native-tageditor.html",' + '"title":"\\\\u539f\\\\u751f\\\\u6807\\\\u7b7e\\\\u7f16\\\\u8f91",' + '"lang":"en-US",' + '"frontmatter":{"type":"native-dataset-editor"},' + '"excerpt":"",' + '"headers":[],' + '"filePathRelative":"native-tageditor.md"' + "}');export{e as data};\n" +) +NATIVE_NAV_ITEM = ( + '
  • 原生标签编辑 ' + "
  • " +) + + +def read_text(path: Path) -> str: + if not path.is_file(): + raise FileNotFoundError(f"missing expected frontend asset: {path}") + return path.read_text(encoding="utf-8") + + +def write_if_changed(path: Path, text: str, dry_run: bool, changed: list[str]) -> None: + old = read_text(path) if path.exists() else "" + if old == text: + return + changed.append(str(path)) + if not dry_run: + path.parent.mkdir(parents=True, exist_ok=True) + path.write_text(text, encoding="utf-8", newline="\n") + + +def replace_expected(text: str, old: str, new: str, path: Path) -> tuple[str, bool]: + if new in text: + return text, False + if old not in text: + raise RuntimeError(f"{path}: expected patch target not found") + return text.replace(old, new, 1), True + + +def patch_sidebar_json(text: str, path: Path) -> tuple[str, bool]: + match = SIDEBAR_RE.search(text) + if not match: + raise RuntimeError(f"{path}: VuePress sidebar JSON block not found") + theme = json.loads(match.group("json")) + sidebar = theme.get("sidebar") + if not isinstance(sidebar, list): + raise RuntimeError(f"{path}: theme sidebar is not a list") + + tools = next((item for item in sidebar if item.get("text") == "工具与调试"), None) + if not tools or not isinstance(tools.get("children"), list): + raise RuntimeError(f"{path}: tools sidebar group not found") + + children = [ + item + for item in tools["children"] + if item.get("link") != "/dataset-editor.html" + and item.get("text") not in {"标签编辑", "原生标签编辑", "经典标签编辑"} + ] + tagger_index = next( + (idx for idx, item in enumerate(children) if item.get("link") == "/tagger.md"), + None, + ) + if tagger_index is None: + raise RuntimeError(f"{path}: tagger sidebar entry not found") + + insert_at = tagger_index + 1 + children[insert_at:insert_at] = [ + {"text": "经典标签编辑", "link": "/tageditor.md"}, + {"text": "原生标签编辑", "link": "/native-tageditor.html"}, + ] + tools["children"] = children + + encoded = json.dumps(theme, ensure_ascii=True, separators=(",", ":")) + json.loads(encoded) + old = match.group("json") + if old == encoded: + return text, False + return text[: match.start("json")] + encoded + text[match.end("json") :], True + + +def patch_app_bundle(root: Path, dry_run: bool, changed: list[str]) -> None: + path = root / APP_BUNDLE + text = read_text(path) + text, route_changed = replace_expected(text, OLD_NATIVE_ROUTE, NEW_NATIVE_ROUTE, path) + text, settings_changed = replace_expected(text, OLD_SETTINGS_ROUTE, NEW_SETTINGS_ROUTE, path) + text, sidebar_changed = patch_sidebar_json(text, path) + if route_changed or settings_changed or sidebar_changed: + write_if_changed(path, text, dry_run, changed) + + +def patch_native_page_data(root: Path, dry_run: bool, changed: list[str]) -> None: + path = root / NATIVE_PAGE_DATA + write_if_changed(path, NATIVE_PAGE_DATA_TEXT, dry_run, changed) + + +def patch_native_html(root: Path, dry_run: bool, changed: list[str]) -> None: + path = root / NATIVE_HTML + text = read_text(path) + text = text.replace('rel="modulepreload" href="/assets/tageditor.html.66da263e.js"', "") + text = text.replace('rel="modulepreload" href="/assets/tageditor.html.173f1b6a.js"', "") + if 'href="/assets/native-tageditor.html.native.js"' not in text: + app_preload = 'rel="modulepreload" href="/assets/app.547295de.js?v=native-tageditor-nav">' + if app_preload not in text: + raise RuntimeError(f"{path}: app modulepreload marker not found") + text = text.replace( + app_preload, + app_preload + '', + 1, + ) + if "dataset-editor-entry.js" not in text or 'name="sd-dataset-editor-script"' not in text: + raise RuntimeError(f"{path}: native editor entry script contract is missing") + write_if_changed(path, text, dry_run, changed) + + +def patch_settings_html(root: Path, dry_run: bool, changed: list[str]) -> None: + path = root / SETTINGS_HTML + text = read_text(path) + old = "/assets/app.547295de.js" + new = "/assets/app.547295de.js?v=dataset-tagger-api" + if new not in text: + if old not in text: + raise RuntimeError(f"{path}: app script URL not found") + text = text.replace(old, new, 1) + write_if_changed(path, text, dry_run, changed) + + +def patch_sidebar_html(root: Path, dry_run: bool, changed: list[str]) -> None: + dist = root / "frontend/dist" + legacy_re = re.compile( + r'(
  • (?:经典标签编辑|标签编辑) ' + r'
  • )', + re.DOTALL, + ) + for path in sorted(dist.rglob("*.html")): + text = read_text(path) + if 'href="/tageditor.md"' not in text or 'class="sidebar-items"' not in text: + continue + if 'aria-label="标签编辑"' in text: + text = text.replace('aria-label="标签编辑"', 'aria-label="经典标签编辑"') + text = text.replace(" 标签编辑 ", " 经典标签编辑 ") + if 'href="/native-tageditor.html"' not in text: + text, count = legacy_re.subn(r"\1" + NATIVE_NAV_ITEM, text, count=1) + if count != 1: + raise RuntimeError(f"{path}: legacy tag editor sidebar entry not patchable") + if 'href="/dataset-editor.html"' in text and path.name != "dataset-editor.html": + raise RuntimeError(f"{path}: dataset editor fallback leaked into trainer sidebar") + write_if_changed(path, text, dry_run, changed) + + +def validate(root: Path) -> None: + app = read_text(root / APP_BUNDLE) + page = read_text(root / NATIVE_PAGE_DATA) + native = read_text(root / NATIVE_HTML) + settings = read_text(root / SETTINGS_HTML) + match = SIDEBAR_RE.search(app) + if not match: + raise RuntimeError("sidebar JSON block missing after patch") + theme = json.loads(match.group("json")) + sidebar_text = json.dumps(theme["sidebar"], ensure_ascii=False) + required = [ + NEW_NATIVE_ROUTE, + NEW_SETTINGS_ROUTE, + "/native-tageditor.html", + "经典标签编辑", + "原生标签编辑", + ] + for needle in required: + haystack = app if needle.startswith('"v-') else sidebar_text + if needle not in haystack: + raise RuntimeError(f"validation failed: {needle!r} missing") + if '"subtype":"tageditor"' in page or '"type":"native-dataset-editor"' not in page: + raise RuntimeError("native page data is not native-dataset-editor") + if 'rel="modulepreload" href="/assets/tageditor.html.66da263e.js"' in native: + raise RuntimeError("native page still preloads the classic tag editor page data") + if "dataset-editor-entry.js" not in native: + raise RuntimeError("native page does not load dataset-editor-entry.js") + if "/assets/app.547295de.js?v=dataset-tagger-api" not in settings: + raise RuntimeError("settings HTML does not cache-bust patched app bundle") + + +def main() -> int: + parser = argparse.ArgumentParser() + parser.add_argument("--root", type=Path, default=Path.cwd()) + parser.add_argument("--check", action="store_true", help="validate without writing") + args = parser.parse_args() + + root = args.root.resolve() + changed: list[str] = [] + patch_app_bundle(root, args.check, changed) + patch_native_page_data(root, args.check, changed) + patch_native_html(root, args.check, changed) + patch_settings_html(root, args.check, changed) + patch_sidebar_html(root, args.check, changed) + validate(root) + + if args.check and changed: + print("frontend/dist patch drift detected:") + for path in changed: + print(f" {path}") + return 1 + if changed: + print("patched frontend/dist:") + for path in changed: + print(f" {path}") + else: + print("frontend/dist patches already applied") + return 0 + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/tests/test_dataset_editor_api.py b/tests/test_dataset_editor_api.py index e0325d9f..82ad34d3 100644 --- a/tests/test_dataset_editor_api.py +++ b/tests/test_dataset_editor_api.py @@ -1,5 +1,7 @@ import json import re +import subprocess +import sys from pathlib import Path from fastapi.testclient import TestClient @@ -375,6 +377,32 @@ def test_trainer_sidebar_exposes_legacy_and_native_tag_editors(): assert 'window.location.assign("/dataset-editor.html")' not in nav +def test_frontend_dist_patch_script_is_idempotent(): + result = subprocess.run( + [sys.executable, "scripts/patch_frontend_dist.py", "--check"], + cwd=ROOT, + text=True, + capture_output=True, + check=False, + ) + + assert result.returncode == 0, result.stdout + result.stderr + assert "frontend/dist patches already applied" in result.stdout + + +def test_all_trainer_sidebar_snapshots_split_legacy_and_native_editors(): + for path in (ROOT / "frontend" / "dist").rglob("*.html"): + html = path.read_text(encoding="utf-8") + if 'class="sidebar-items"' not in html or 'href="/tageditor.md"' not in html: + continue + assert 'aria-label="标签编辑"' not in html, str(path) + assert "经典标签编辑" in html, str(path) + assert "原生标签编辑" in html, str(path) + assert 'href="/native-tageditor.html"' in html, str(path) + if path.name != "dataset-editor.html": + assert 'href="/dataset-editor.html"' not in html, str(path) + + def test_vuepress_theme_sidebar_json_stays_parseable(): app_bundle = (ROOT / "frontend" / "dist" / "assets" / "app.547295de.js").read_text( encoding="utf-8" From 3d159087947b0c6542704294c6e306d6afc6273c Mon Sep 17 00:00:00 2001 From: wochenlong <117965575+wochenlong@users.noreply.github.com> Date: Sat, 30 May 2026 02:50:54 +0800 Subject: [PATCH 8/8] test(frontend): cover anima dist patch script --- docs/design/frontend-source-of-truth-plan.md | 1 + scripts/patch_frontend_dist.py | 87 ++++++++++++++++++++ tests/test_dataset_editor_api.py | 27 ++++++ 3 files changed, 115 insertions(+) diff --git a/docs/design/frontend-source-of-truth-plan.md b/docs/design/frontend-source-of-truth-plan.md index 33a8fab0..7b5884d2 100644 --- a/docs/design/frontend-source-of-truth-plan.md +++ b/docs/design/frontend-source-of-truth-plan.md @@ -8,6 +8,7 @@ Created: 2026-05-30 - 2026-05-30: Added `scripts/patch_frontend_dist.py` to reapply and validate the current native tag editor dist patches. The script covers the VuePress app route mapping, sidebar JSON, native page-data chunk, native page preload contract, settings cache-bust URL, and SSR sidebar snapshots. - 2026-05-30: The first script run found older SSR pages that still exposed the single `标签编辑` sidebar entry. Those snapshots were updated to split `经典标签编辑` and `原生标签编辑`, with regression coverage in `tests/test_dataset_editor_api.py`. +- 2026-05-30: Expanded the patch script to also cover the older Anima/SD3 dist text patches documented in `frontend/VENDOR.md`, including the app sidebar, `sd3` render chunk, `sd3` page-data chunk, and `lora/sd3.html` SSR copy. ## Background diff --git a/scripts/patch_frontend_dist.py b/scripts/patch_frontend_dist.py index 14fcce18..5f1f68ab 100644 --- a/scripts/patch_frontend_dist.py +++ b/scripts/patch_frontend_dist.py @@ -19,6 +19,9 @@ NATIVE_PAGE_DATA = Path("frontend/dist/assets/native-tageditor.html.native.js") NATIVE_HTML = Path("frontend/dist/native-tageditor.html") SETTINGS_HTML = Path("frontend/dist/other/settings.html") +SD3_RENDER_CHUNK = Path("frontend/dist/assets/sd3.html.1a4bf31e.js") +SD3_DATA_CHUNK = Path("frontend/dist/assets/sd3.html.eaeb05e1.js") +SD3_HTML = Path("frontend/dist/lora/sd3.html") SIDEBAR_RE = re.compile(r"const WE=JSON\.parse\(`(?P.*?)`\),x0=") OLD_NATIVE_ROUTE = ( @@ -50,6 +53,40 @@ 'aria-label="原生标签编辑"> 原生标签编辑 ' "" ) +ANIMA_SIDEBAR_ENTRY = {"text": "Anima LoRA", "link": "/lora/sd3.md"} +SD3_RENDER_REPLACEMENTS = ( + ( + 'a(" SD3 \\u8BAD\\u7EC3 \\u4E13\\u5BB6\\u6A21\\u5F0F")', + 'a(" Anima LoRA \\u8BAD\\u7EC3 \\u4E13\\u5BB6\\u6A21\\u5F0F")', + ), + ( + '"SD3 \\u6A21\\u578B LoRA \\u8BAD\\u7EC3 \\u4E13\\u5BB6\\u6A21\\u5F0F"', + '"Anima DiT \\u6A21\\u578B LoRA \\u8BAD\\u7EC3 \\u4E13\\u5BB6\\u6A21\\u5F0F"', + ), + ( + '"\\u652F\\u6301 SD3.5 \\u6A21\\u578B\\u7684 LoRA \\u8BAD\\u7EC3"', + '"Anima DiT \\u8BAD\\u7EC3\\u5165\\u53E3\\uFF0C\\u4F7F\\u7528 Qwen3 + T5 + Anima \\u4E13\\u7528\\u8BAD\\u7EC3\\u53C2\\u6570"', + ), + ( + ',r=e("p",null,"\\u522B\\u95EE\\u4E3A\\u4EC0\\u4E48\\u65B0\\u624B\\u6A21\\u5F0F\\u4E0D\\u884C\\uFF0C\\u95EE\\u5C31\\u662F\\u4F60\\u90FD\\u7528 SD3 \\u4E86\\u8FD8\\u60F3\\u5F53\\u65B0\\u624B\\uFF1F",-1),l=[c,n,d,r]', + ",l=[c,n,d]", + ), +) +SD3_DATA_REPLACEMENTS = ( + ( + '"title":"SD3 \\u8BAD\\u7EC3 \\u4E13\\u5BB6\\u6A21\\u5F0F"', + '"title":"Anima LoRA \\u8BAD\\u7EC3 \\u4E13\\u5BB6\\u6A21\\u5F0F"', + ), +) +SD3_HTML_REPLACEMENTS = ( + ("aria-label=\"SD3.5\"", "aria-label=\"Anima LoRA\""), + ("> SD3.5 ", "> Anima LoRA "), + ("SD3 训练 专家模式 | SD 训练 UI", "Anima Stable Diffusion LoRA | SD 训练 UI"), + ("> SD3 训练 专家模式", "> Anima Stable Diffusion LoRA"), + ("

    SD3 模型 LoRA 训练 专家模式

    ", "

    Anima DiT 模型 LoRA 训练 专家模式

    "), + ("

    支持 SD3.5 模型的 LoRA 训练

    ", "

    Anima DiT 训练入口,使用 Qwen3 + T5 + Anima 专用参数

    "), + ("

    别问为什么新手模式不行,问就是你都用 SD3 了还想当新手?

    ", ""), +) def read_text(path: Path) -> str: @@ -85,6 +122,17 @@ def patch_sidebar_json(text: str, path: Path) -> tuple[str, bool]: if not isinstance(sidebar, list): raise RuntimeError(f"{path}: theme sidebar is not a list") + lora_group = next((item for item in sidebar if item.get("text") == "训练"), None) + if not lora_group or not isinstance(lora_group.get("children"), list): + raise RuntimeError(f"{path}: training sidebar group not found") + for group in lora_group["children"]: + children = group.get("children") + if not isinstance(children, list): + continue + for item in children: + if item.get("link") == "/lora/sd3.md": + item.update(ANIMA_SIDEBAR_ENTRY) + tools = next((item for item in sidebar if item.get("text") == "工具与调试"), None) if not tools or not isinstance(tools.get("children"), list): raise RuntimeError(f"{path}: tools sidebar group not found") @@ -163,6 +211,20 @@ def patch_settings_html(root: Path, dry_run: bool, changed: list[str]) -> None: write_if_changed(path, text, dry_run, changed) +def patch_anima_sd3_assets(root: Path, dry_run: bool, changed: list[str]) -> None: + for rel_path, replacements in ( + (SD3_RENDER_CHUNK, SD3_RENDER_REPLACEMENTS), + (SD3_DATA_CHUNK, SD3_DATA_REPLACEMENTS), + (SD3_HTML, SD3_HTML_REPLACEMENTS), + ): + path = root / rel_path + text = read_text(path) + for old, new in replacements: + if old in text: + text = text.replace(old, new) + write_if_changed(path, text, dry_run, changed) + + def patch_sidebar_html(root: Path, dry_run: bool, changed: list[str]) -> None: dist = root / "frontend/dist" legacy_re = re.compile( @@ -175,6 +237,9 @@ def patch_sidebar_html(root: Path, dry_run: bool, changed: list[str]) -> None: text = read_text(path) if 'href="/tageditor.md"' not in text or 'class="sidebar-items"' not in text: continue + for old, new in SD3_HTML_REPLACEMENTS[:2]: + if old in text: + text = text.replace(old, new) if 'aria-label="标签编辑"' in text: text = text.replace('aria-label="标签编辑"', 'aria-label="经典标签编辑"') text = text.replace(" 标签编辑 ", " 经典标签编辑 ") @@ -192,6 +257,9 @@ def validate(root: Path) -> None: page = read_text(root / NATIVE_PAGE_DATA) native = read_text(root / NATIVE_HTML) settings = read_text(root / SETTINGS_HTML) + sd3_render = read_text(root / SD3_RENDER_CHUNK) + sd3_data = read_text(root / SD3_DATA_CHUNK) + sd3_html = read_text(root / SD3_HTML) match = SIDEBAR_RE.search(app) if not match: raise RuntimeError("sidebar JSON block missing after patch") @@ -216,6 +284,24 @@ def validate(root: Path) -> None: raise RuntimeError("native page does not load dataset-editor-entry.js") if "/assets/app.547295de.js?v=dataset-tagger-api" not in settings: raise RuntimeError("settings HTML does not cache-bust patched app bundle") + if "Anima LoRA" not in sidebar_text: + raise RuntimeError("sidebar does not expose Anima LoRA") + if "Anima LoRA" not in sd3_data or "trainType\":\"sd3-lora" not in sd3_data: + raise RuntimeError("sd3 page data does not preserve Anima title and sd3-lora route key") + if ( + "Anima LoRA" not in sd3_render + or "Anima DiT" not in sd3_render + or "Qwen3 + T5 + Anima" not in sd3_render + or "SD3.5" in sd3_render + ): + raise RuntimeError("sd3 render chunk is not patched for Anima") + if ( + "Anima Stable Diffusion LoRA" not in sd3_html + or "Anima DiT 模型 LoRA 训练 专家模式" not in sd3_html + or "Qwen3 + T5 + Anima" not in sd3_html + or 'aria-label="SD3.5"' in sd3_html + ): + raise RuntimeError("sd3 SSR HTML is not patched for Anima") def main() -> int: @@ -230,6 +316,7 @@ def main() -> int: patch_native_page_data(root, args.check, changed) patch_native_html(root, args.check, changed) patch_settings_html(root, args.check, changed) + patch_anima_sd3_assets(root, args.check, changed) patch_sidebar_html(root, args.check, changed) validate(root) diff --git a/tests/test_dataset_editor_api.py b/tests/test_dataset_editor_api.py index 82ad34d3..12e6e429 100644 --- a/tests/test_dataset_editor_api.py +++ b/tests/test_dataset_editor_api.py @@ -403,6 +403,33 @@ def test_all_trainer_sidebar_snapshots_split_legacy_and_native_editors(): assert 'href="/dataset-editor.html"' not in html, str(path) +def test_frontend_dist_patch_script_covers_anima_sd3_copy(): + app_bundle = (ROOT / "frontend" / "dist" / "assets" / "app.547295de.js").read_text( + encoding="utf-8" + ) + sd3_render = (ROOT / "frontend" / "dist" / "assets" / "sd3.html.1a4bf31e.js").read_text( + encoding="utf-8" + ) + sd3_data = (ROOT / "frontend" / "dist" / "assets" / "sd3.html.eaeb05e1.js").read_text( + encoding="utf-8" + ) + sd3_html = (ROOT / "frontend" / "dist" / "lora" / "sd3.html").read_text( + encoding="utf-8" + ) + + assert '"text":"Anima LoRA","link":"/lora/sd3.md"' in app_bundle + assert "Anima LoRA" in sd3_render + assert "Anima DiT" in sd3_render + assert "Qwen3 + T5 + Anima" in sd3_render + assert "SD3.5" not in sd3_render + assert '"title":"Anima LoRA \\u8BAD\\u7EC3 \\u4E13\\u5BB6\\u6A21\\u5F0F"' in sd3_data + assert '"trainType":"sd3-lora"' in sd3_data + assert "Anima Stable Diffusion LoRA" in sd3_html + assert "Anima DiT 模型 LoRA 训练 专家模式" in sd3_html + assert "Qwen3 + T5 + Anima" in sd3_html + assert 'aria-label="SD3.5"' not in sd3_html + + def test_vuepress_theme_sidebar_json_stays_parseable(): app_bundle = (ROOT / "frontend" / "dist" / "assets" / "app.547295de.js").read_text( encoding="utf-8"