From 1a97f75546d9a3fc301e15c0f98bf2e668440ed6 Mon Sep 17 00:00:00 2001 From: yangchunlong <292345300@qq.com> Date: Mon, 28 Jul 2025 10:03:07 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=F0=9F=9A=80=20tabs=E5=A2=9E=E5=8A=A0?= =?UTF-8?q?=E6=BB=9A=E5=8A=A8=E6=9D=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Editor/index.vue | 11 +- src/components/Editor/quill-tabs.js | 297 +++++++------- src/components/Editor/quill-tabs1.js | 335 ++++++++++------ src/components/Editor/quill-tabs222.js | 180 --------- src/components/Editor/quill-video.js | 14 +- ....timestamp-1753426525446-28eee6cbb234d.mjs | 372 ++++++++++++++++++ 6 files changed, 773 insertions(+), 436 deletions(-) delete mode 100644 src/components/Editor/quill-tabs222.js create mode 100644 vite.config.ts.timestamp-1753426525446-28eee6cbb234d.mjs diff --git a/src/components/Editor/index.vue b/src/components/Editor/index.vue index 7af50fe..0b84c4f 100644 --- a/src/components/Editor/index.vue +++ b/src/components/Editor/index.vue @@ -76,6 +76,7 @@ @keydown.backspace.stop v-else v-model="item.title" + max-length="" :ref="el => (editInputRefs[index] = el)" size="small" class="title-input" @@ -113,7 +114,7 @@ import { QuillEditor, Quill } from "@vueup/vue-quill"; import "@vueup/vue-quill/dist/vue-quill.snow.css"; import { getCurrentInstance, reactive, ref, toRaw, computed, onMounted, nextTick } from "vue"; import { generateUUID } from "@/utils"; -import { h } from "@/utils/url"; +// import { h } from "@/utils/url"; import { routerObj } from "./utils.js"; import { titleConfig } from "./titleConfig.js"; import { uploadVideo, uploadImg } from "@/api/modules/upload"; @@ -307,7 +308,7 @@ const handleHttpUpload = async options => { imageListDb.value.forEach(item => { const length = quill.getLength() - 1; quill.insertEmbed(length, "customImage", { - url: h + item.path, + url: item.path, id: item.serverImgId || generateUUID() }); quill.setSelection(length + 1); @@ -346,7 +347,7 @@ const handleVideoUpload = async evt => { let length = quill.selection.savedRange.index; const { data } = await uploadVideo(formData); quill.insertEmbed(length, "customVideo", { - url: h + data.path, + url: data.path, id: generateUUID() }); uploadFileVideo.value.value = ""; @@ -459,6 +460,7 @@ const handleQR = () => { return useMsg("error", "标签页内容为空 !"); } const range = quill.getSelection(true); + // 判断是否是编辑已有标签页(通过 currentEditingTabsRef 是否有值) if (currentEditingTabsRef.value) { // 1. 编辑模式:更新原有标签页组件 @@ -470,7 +472,10 @@ const handleQR = () => { } else { // 2. 新增模式:插入新的标签页组件 quill.insertEmbed(range.index, "tabs", tabsData.value); + // 关键:在标签页前方插入一个空段落(确保顶部有空间) + // quill.insertText(range.index, "\n"); // 插入换行 quill.setSelection(range.index + 1); + quill.insertText(range.index, "\n"); // 插入换行 } // 关闭弹窗并清空临时数据 setTabsInfo(); diff --git a/src/components/Editor/quill-tabs.js b/src/components/Editor/quill-tabs.js index 8cd45c1..3507501 100644 --- a/src/components/Editor/quill-tabs.js +++ b/src/components/Editor/quill-tabs.js @@ -28,7 +28,38 @@ class TabsBlot extends BlockEmbed { ` ); - // 标签栏 + // 标签栏滚动容器 - 优化高度计算 + const tabScrollContainer = document.createElement("div"); + tabScrollContainer.className = "m-quill-tab-scroll-container"; + tabScrollContainer.setAttribute( + "style", + ` + -webkit-overflow-scrolling: touch; + scrollbar-width: none; + -ms-overflow-style: none; + overflow-y: hidden; + height: auto; + ` + ); + + // height: auto; /* 自动高度 */ + + // Chrome, Safari 隐藏滚动条 + tabScrollContainer.style.overflow = "auto"; + tabScrollContainer.style.webkitOverflowScrolling = "touch"; + tabScrollContainer.style.scrollbarWidth = "none"; + tabScrollContainer.style.msOverflowStyle = "none"; + + // // 关键:隐藏滚动条但保留功能 + // tabScrollContainer.innerHTML = ` + // + // `; + + // 标签栏 - 保持原有样式不变 const tabList = document.createElement("div"); tabList.className = "m-quill-tab-list"; tabList.setAttribute( @@ -36,10 +67,54 @@ class TabsBlot extends BlockEmbed { ` display: flex; border-bottom: 1px solid #dddddd; + min-width: max-content; /* 确保内容撑开容器 */ ` ); - // 内容区 + // 生成标签按钮 - 优化内边距计算 + tabs.forEach((tab, index) => { + const btn = document.createElement("button"); + btn.className = `m-quill-tab-button`; + btn.setAttribute("data-index", index); + btn.textContent = tab.title; + btn.setAttribute( + "style", + ` + font-weight: 900; + color: #8f9099; + cursor: pointer; + background: transparent; + border: none; + margin-right: 5px; /* 增大间距 */ + cursor: pointer; + font-size:16px; + ${index === 0 ? "color: #1f2635; border-bottom: 3px solid #537CD8;font-size:16px;" : ""} + ` + ); + tabList.appendChild(btn); + }); + + // 编辑按钮 - 保持原有样式不变 + const editBtn = document.createElement("button"); + editBtn.className = "m-quill-tab-edit-btn"; + editBtn.innerHTML = "编辑"; + editBtn.setAttribute("data-action", "edit"); + editBtn.setAttribute( + "style", + ` + padding: 10px; + margin-left: auto; + color: #606266; + cursor: pointer; + width:50px; + background: transparent; + border: none; + display:block; + ` + ); + tabList.appendChild(editBtn); + + // 内容区 - 保持原有样式不变 const contentList = document.createElement("div"); contentList.className = "m-quill-tab-content-list"; contentList.setAttribute( @@ -49,31 +124,8 @@ class TabsBlot extends BlockEmbed { ` ); - // 生成标签按钮和内容面板 + // 生成内容面板 - 保持原有样式不变 tabs.forEach((tab, index) => { - // 标签按钮 - const btn = document.createElement("button"); - btn.className = `m-quill-tab-button`; - btn.setAttribute("data-index", index); - btn.textContent = tab.title; - btn.setAttribute( - "style", - ` - padding: 10px 15px; - font-weight: 900; - color: #8f9099; - cursor: pointer; - background: transparent; - border: none; - margin-right: 60px; - cursor: pointer; - font-size:16px; - ${index === 0 ? "color: #1f2635; border-bottom: 3px solid #537CD8;font-size:16px;" : ""} - ` - ); - tabList.appendChild(btn); - - // 内容面板 - 关键修改:设置为可编辑 const panel = document.createElement("div"); panel.className = `m-quill-tab-content`; panel.setAttribute("data-index", index); @@ -85,88 +137,61 @@ class TabsBlot extends BlockEmbed { min-height: 50px; ` ); - panel.contentEditable = "false"; // 内容面板可编辑 + panel.contentEditable = "false"; contentList.appendChild(panel); }); - // 编辑按钮 - const editBtn = document.createElement("button"); - editBtn.className = "m-quill-tab-edit-btn"; - editBtn.innerHTML = "编辑"; - editBtn.setAttribute("data-action", "edit"); - editBtn.setAttribute( - "style", - ` - - padding: 10px; - margin-left: auto; - color: #606266; - cursor: pointer; - background: transparent; - border: none; - display:block; - ` - ); - // display: flex; - //align-items: center; - // editBtn.onmouseover = () => { - // editBtn.style.color = "#007bff"; - // }; - // editBtn.onmouseout = () => { - // editBtn.style.color = "#606266"; - // }; - tabList.appendChild(editBtn); + // 组装结构 + tabScrollContainer.appendChild(tabList); + node.appendChild(tabScrollContainer); // 滚动容器添加到主节点 + node.appendChild(contentList); // 内容区 - // 标签页切换逻辑 + // 标签页切换逻辑 - 保持原有逻辑不变 const scriptTag = document.createElement("script"); - // 修改 scriptTag.textContent 中的逻辑 scriptTag.textContent = ` - (function() { - const container = document.currentScript.parentElement; - const isAdmin = window.location.pathname.includes('/admin'); - const editBtn1 = container.querySelector('.m-quill-tab-edit-btn'); - - // 仅在非管理系统(文章网站)隐藏编辑按钮,管理系统保持显示 - if (!isAdmin && editBtn1) { - editBtn1.style.display = 'none'; // 文章网站隐藏按钮 - } else if (isAdmin && editBtn1) { - editBtn1.style.display = 'block'; // 管理系统强制显示按钮 - } - - // 非管理系统才执行标签切换逻辑(管理系统不执行) - if (!isAdmin) { - const tabButtons = container.querySelectorAll('.m-quill-tab-button:not([data-action])'); - const contentPanels = container.querySelectorAll('.m-quill-tab-content'); - tabButtons.forEach(btn => { - btn.addEventListener('click', function() { - const index = parseInt(this.dataset.index); - tabButtons.forEach((b, i) => { - b.setAttribute('style', \` - padding: 10px 15px; - font-weight: 900; - cursor: pointer; - background: transparent; - font-size:16px; - margin-right: 60px; - color: #8f9099; - border: none; - \${i === index ? - 'color: #1f2635;border-bottom: 3px solid #537CD8;font-size:16px;' : - '' - } - \`); - }); - contentPanels.forEach((panel, i) => { - panel.style.display = i === index ? 'block' : 'none'; - }); + (function() { + const container = document.currentScript.parentElement; + const isAdmin = window.location.pathname.includes('/admin'); + const editBtn1 = container.querySelector('.m-quill-tab-edit-btn'); + + // 仅在非管理系统(文章网站)隐藏编辑按钮,管理系统保持显示 + if (!isAdmin && editBtn1) { + editBtn1.style.display = 'none'; // 文章网站隐藏按钮 + } else if (isAdmin && editBtn1) { + editBtn1.style.display = 'block'; // 管理系统强制显示按钮 + } + + // 非管理系统才执行标签切换逻辑(管理系统不执行) + if (!isAdmin) { + const tabButtons = container.querySelectorAll('.m-quill-tab-button:not([data-action])'); + const contentPanels = container.querySelectorAll('.m-quill-tab-content'); + tabButtons.forEach(btn => { + btn.addEventListener('click', function() { + const index = parseInt(this.dataset.index); + tabButtons.forEach((b, i) => { + b.setAttribute('style', \` + font-weight: 900; + cursor: pointer; + background: transparent; + font-size:16px; + margin-right: 5px; + color: #8f9099; + border: none; + \${i === index ? + 'color: #1f2635;border-bottom: 3px solid #537CD8;font-size:16px;' : + '' + } + \`); + }); + contentPanels.forEach((panel, i) => { + panel.style.display = i === index ? 'block' : 'none'; }); }); - } - })(); - `; + }); + } + })(); + `; - node.appendChild(tabList); - node.appendChild(contentList); node.appendChild(scriptTag); node.setAttribute("contenteditable", "false"); return node; @@ -177,15 +202,12 @@ class TabsBlot extends BlockEmbed { this.eventBoundElements = new WeakMap(); } - // 移除 eventBoundElements 依赖,直接重新绑定事件(避免弱映射导致的问题) + // 编辑按钮事件 - 保持原有逻辑不变 const editBtn = this.domNode.querySelector(".m-quill-tab-edit-btn"); if (editBtn) { - // 先移除旧事件,避免重复绑定 editBtn.removeEventListener("click", this.handleEditClick); - // 绑定新事件(使用箭头函数确保 this 指向正确) this.handleEditClick = e => { e.stopPropagation(); - console.log("1232323"); this.domNode.dispatchEvent( new CustomEvent("edit-tabs", { bubbles: true, @@ -196,7 +218,7 @@ class TabsBlot extends BlockEmbed { editBtn.addEventListener("click", this.handleEditClick); } - // 标签切换事件 + // 标签切换事件 - 保持原有逻辑不变 const tabButtons = this.domNode.querySelectorAll(".m-quill-tab-button:not([data-action])"); tabButtons.forEach(btn => { if (!this.eventBoundElements.has(btn)) { @@ -209,9 +231,8 @@ class TabsBlot extends BlockEmbed { }); } - // 增强版删除键处理 + // 增强版删除键处理 - 保持原有逻辑不变 bindDeleteKeyEvent() { - // 阻止从外部删除整个组件 this.domNode.addEventListener( "keydown", e => { @@ -222,30 +243,26 @@ class TabsBlot extends BlockEmbed { const range = selection.getRangeAt(0); const parentBlock = this.domNode; - // 判断光标是否在组件内部 const isInside = parentBlock.contains(range.commonAncestorContainer); - // 如果光标在组件外部,阻止删除 if (!isInside) { e.preventDefault(); return; } - // 检查是否选中了整个组件 if ( range.startContainer === parentBlock && range.endContainer === parentBlock && range.startOffset === 0 && range.endOffset >= parentBlock.childNodes.length ) { - e.preventDefault(); // 阻止删除整个组件 + e.preventDefault(); } } }, true - ); // 使用捕获阶段 + ); - // 标签栏禁止编辑 const tabList = this.domNode.querySelector(".m-quill-tab-list"); if (tabList) { tabList.querySelectorAll("*").forEach(el => { @@ -258,17 +275,18 @@ class TabsBlot extends BlockEmbed { const buttons = this.domNode.querySelectorAll(".m-quill-tab-button:not([data-action])"); const panels = this.domNode.querySelectorAll(".m-quill-tab-content"); + // 保持原有样式逻辑不变 buttons.forEach((btn, i) => { btn.setAttribute( "style", ` - padding: 10px 15px; + font-weight: 900; cursor: pointer; background: transparent; border: none; font-size:16px; - margin-right: 60px; + margin-right: 5px; color: #8f9099; border-bottom: 3px solid transparent; ${i === index ? "color: #1f2635;border-bottom: 3px solid #537CD8;font-size:16px;" : ""} @@ -279,6 +297,17 @@ class TabsBlot extends BlockEmbed { panels.forEach((panel, i) => { panel.style.display = i === index ? "block" : "none"; }); + + // 滚动到当前选中的标签 + const scrollContainer = this.domNode.querySelector(".m-quill-tab-scroll-container"); + const activeBtn = buttons[index]; + if (scrollContainer && activeBtn) { + activeBtn.scrollIntoView({ + behavior: "smooth", + block: "nearest", + inline: "center" + }); + } } static value(node) { @@ -301,26 +330,23 @@ class TabsBlot extends BlockEmbed { const scriptTag = this.domNode.querySelector("script"); if (scriptTag) { const newScript = document.createElement("script"); - newScript.textContent = scriptTag.textContent; scriptTag.parentNode.replaceChild(newScript, scriptTag); } this.bindEvents(); - this.bindDeleteKeyEvent(); // 重新绑定删除事件 + this.bindDeleteKeyEvent(); } getValue() { return TabsBlot.value(this.domNode); } - // 更新标签页数据(编辑后更新 DOM) + // 更新标签页数据 - 保持原有逻辑不变 updateContents(tabs) { - // 清空原有内容 const contentList = this.domNode.querySelector(".m-quill-tab-content-list"); const tabList = this.domNode.querySelector(".m-quill-tab-list"); - // 保留编辑按钮(如果需要) const editBtn = this.domNode.querySelector(".m-quill-tab-edit-btn"); - // 清空标签栏和内容区(保留编辑按钮) + Array.from(tabList.children).forEach(child => { if (!child.classList.contains("m-quill-tab-edit-btn")) { child.remove(); @@ -328,9 +354,7 @@ class TabsBlot extends BlockEmbed { }); contentList.innerHTML = ""; - // 重新渲染标签页(复用 create 方法中的逻辑) tabs.forEach((tab, index) => { - // 重建标签按钮 const btn = document.createElement("button"); btn.className = "m-quill-tab-button"; btn.setAttribute("data-index", index); @@ -338,20 +362,18 @@ class TabsBlot extends BlockEmbed { btn.setAttribute( "style", ` - padding: 10px 15px; - font-weight: 900; - color: #8f9099; - cursor: pointer; - background: transparent; - border: none; - margin-right: 60px; - font-size:16px; - ${index === 0 ? "color: #1f2635; border-bottom: 3px solid #537CD8;font-size:16px;" : ""} - ` + font-weight: 900; + color: #8f9099; + cursor: pointer; + background: transparent; + border: none; + margin-right: 5px; + font-size:16px; + ${index === 0 ? "color: #1f2635; border-bottom: 3px solid #537CD8;font-size:16px;" : ""} + ` ); - tabList.insertBefore(btn, editBtn); // 插入到编辑按钮前 + tabList.insertBefore(btn, editBtn); - // 重建内容面板 const panel = document.createElement("div"); panel.className = "m-quill-tab-content"; panel.setAttribute("data-index", index); @@ -359,15 +381,14 @@ class TabsBlot extends BlockEmbed { panel.setAttribute( "style", ` - display: ${index === 0 ? "block" : "none"}; - min-height: 50px; - ` + display: ${index === 0 ? "block" : "none"}; + min-height: 50px; + ` ); panel.contentEditable = "false"; contentList.appendChild(panel); }); - // 重新绑定事件(确保切换功能正常) this.bindEvents(); } } diff --git a/src/components/Editor/quill-tabs1.js b/src/components/Editor/quill-tabs1.js index 814269f..82a9ea3 100644 --- a/src/components/Editor/quill-tabs1.js +++ b/src/components/Editor/quill-tabs1.js @@ -5,7 +5,7 @@ const BlockEmbed = Quill.import("blots/block/embed"); class TabsBlot extends BlockEmbed { static blotName = "tabs"; static tagName = "div"; - static className = "quill-tabs"; + static className = "m-quill-tabs"; constructor(domNode) { super(domNode); @@ -23,27 +23,100 @@ class TabsBlot extends BlockEmbed { ` margin: 15px 0; overflow: hidden; - border: 1px solid #dddddd; border-radius: 4px; position: relative; ` ); - // 标签栏 + // 标签栏滚动容器 - 添加隐藏滚动条样式 + const tabScrollContainer = document.createElement("div"); + tabScrollContainer.className = "m-quill-tab-scroll-container"; + tabScrollContainer.setAttribute( + "style", + ` + overflow-x: auto; + overflow-y: hidden; + + -webkit-overflow-scrolling: touch; /* 增强移动端滚动体验 */ + scrollbar-width: none; /* Firefox 隐藏滚动条 */ + -ms-overflow-style: none; /* IE 10+ 隐藏滚动条 */ + ` + ); + + // Chrome, Safari 隐藏滚动条 + tabScrollContainer.style.overflow = "auto"; + tabScrollContainer.style.webkitOverflowScrolling = "touch"; + tabScrollContainer.style.scrollbarWidth = "none"; + tabScrollContainer.style.msOverflowStyle = "none"; + + // 关键:隐藏滚动条但保留功能 + tabScrollContainer.innerHTML = ` + + `; + + // 标签栏 - 保持原有样式不变 const tabList = document.createElement("div"); - tabList.className = "quill-tab-list"; + tabList.className = "m-quill-tab-list"; tabList.setAttribute( "style", ` display: flex; - background-color: #f8f9fa; border-bottom: 1px solid #dddddd; + min-width: max-content; /* 确保内容撑开容器 */ ` ); - // 内容区 + // 生成标签按钮 - 保持原有样式不变 + tabs.forEach((tab, index) => { + const btn = document.createElement("button"); + btn.className = `m-quill-tab-button`; + btn.setAttribute("data-index", index); + btn.textContent = tab.title; + btn.setAttribute( + "style", + ` + padding: 1%; + font-weight: 900; + color: #8f9099; + cursor: pointer; + background: transparent; + border: none; + margin-right: 1%; + cursor: pointer; + font-size:16px; + ${index === 0 ? "color: #1f2635; border-bottom: 3px solid #537CD8;font-size:16px;" : ""} + ` + ); + tabList.appendChild(btn); + }); + + // 编辑按钮 - 保持原有样式不变 + const editBtn = document.createElement("button"); + editBtn.className = "m-quill-tab-edit-btn"; + editBtn.innerHTML = "编辑"; + editBtn.setAttribute("data-action", "edit"); + editBtn.setAttribute( + "style", + ` + padding: 10px; + margin-left: auto; + color: #606266; + cursor: pointer; + width:50px; + background: transparent; + border: none; + display:block; + ` + ); + tabList.appendChild(editBtn); + + // 内容区 - 保持原有样式不变 const contentList = document.createElement("div"); - contentList.className = "quill-tab-content-list"; + contentList.className = "m-quill-tab-content-list"; contentList.setAttribute( "style", ` @@ -51,106 +124,77 @@ class TabsBlot extends BlockEmbed { ` ); - // 生成标签按钮和内容面板 + // 生成内容面板 - 保持原有样式不变 tabs.forEach((tab, index) => { - // 标签按钮 - const btn = document.createElement("button"); - btn.className = `quill-tab-button ${index === 0 ? "active" : ""}`; - btn.setAttribute("data-index", index); - btn.textContent = tab.title; - btn.setAttribute( - "style", - ` - padding: 10px 15px; - font-weight: 500; - cursor: pointer; - background: transparent; - border: none; - transition: background-color 0.2s; - ${index === 0 ? "color: #007bff; background-color: white; border-bottom: 2px solid #007bff;" : ""} - ` - ); - tabList.appendChild(btn); - - // 内容面板 - 关键修改:设置为可编辑 const panel = document.createElement("div"); - panel.className = `quill-tab-content ${index === 0 ? "active" : ""}`; + panel.className = `m-quill-tab-content`; panel.setAttribute("data-index", index); panel.innerHTML = tab.content; panel.setAttribute( "style", ` display: ${index === 0 ? "block" : "none"}; - min-height: 50px; /* 确保有编辑区域 */ + min-height: 50px; ` ); - panel.contentEditable = "true"; // 内容面板可编辑 + panel.contentEditable = "false"; contentList.appendChild(panel); }); - // 编辑按钮 - const editBtn = document.createElement("button"); - editBtn.className = "quill-tab-edit-btn"; - editBtn.innerHTML = "编辑"; - editBtn.setAttribute("data-action", "edit"); - editBtn.setAttribute( - "style", - ` - display: flex; - align-items: center; - padding: 10px; - margin-left: auto; - color: #606266; - cursor: pointer; - background: transparent; - border: none; - ` - ); - editBtn.onmouseover = () => { - editBtn.style.color = "#007bff"; - }; - editBtn.onmouseout = () => { - editBtn.style.color = "#606266"; - }; - tabList.appendChild(editBtn); - // 标签页切换逻辑 + // 组装结构 + tabScrollContainer.appendChild(tabList); + node.appendChild(tabScrollContainer); // 滚动容器添加到主节点 + node.appendChild(contentList); // 内容区 + + // 标签页切换逻辑 - 保持原有逻辑不变 const scriptTag = document.createElement("script"); scriptTag.textContent = ` (function() { const container = document.currentScript.parentElement; - const tabButtons = container.querySelectorAll('.quill-tab-button:not([data-action])'); - const contentPanels = container.querySelectorAll('.quill-tab-content'); - tabButtons.forEach(btn => { - btn.addEventListener('click', function() { - const index = parseInt(this.dataset.index); - tabButtons.forEach((b, i) => { - b.setAttribute('style', \` - padding: 10px 15px; - font-weight: 500; - cursor: pointer; - background: transparent; - border: none; - transition: background-color 0.2s; - \${i === index ? - 'color: #007bff; background-color: white; border-bottom: 2px solid #007bff;' : - '' - } - \`); - }); - - contentPanels.forEach((panel, i) => { - panel.style.display = i === index ? 'block' : 'none'; + const isAdmin = window.location.pathname.includes('/admin'); + const editBtn1 = container.querySelector('.m-quill-tab-edit-btn'); + + // 仅在非管理系统(文章网站)隐藏编辑按钮,管理系统保持显示 + if (!isAdmin && editBtn1) { + editBtn1.style.display = 'none'; // 文章网站隐藏按钮 + } else if (isAdmin && editBtn1) { + editBtn1.style.display = 'block'; // 管理系统强制显示按钮 + } + + // 非管理系统才执行标签切换逻辑(管理系统不执行) + if (!isAdmin) { + const tabButtons = container.querySelectorAll('.m-quill-tab-button:not([data-action])'); + const contentPanels = container.querySelectorAll('.m-quill-tab-content'); + tabButtons.forEach(btn => { + btn.addEventListener('click', function() { + const index = parseInt(this.dataset.index); + tabButtons.forEach((b, i) => { + b.setAttribute('style', \` + padding: 1%; + font-weight: 900; + cursor: pointer; + background: transparent; + font-size:16px; + margin-right: 1%; + color: #8f9099; + border: none; + \${i === index ? + 'color: #1f2635;border-bottom: 3px solid #537CD8;font-size:16px;' : + '' + } + \`); + }); + contentPanels.forEach((panel, i) => { + panel.style.display = i === index ? 'block' : 'none'; + }); }); }); - }); + } })(); `; - // 组装结构 - 关键修改:移除contenteditable="false" - node.appendChild(tabList); - node.appendChild(contentList); node.appendChild(scriptTag); - + node.setAttribute("contenteditable", "false"); return node; } @@ -159,10 +203,11 @@ class TabsBlot extends BlockEmbed { this.eventBoundElements = new WeakMap(); } - // 编辑按钮事件 - const editBtn = this.domNode.querySelector(".quill-tab-edit-btn"); - if (editBtn && !this.eventBoundElements.has(editBtn)) { - editBtn.addEventListener("click", e => { + // 编辑按钮事件 - 保持原有逻辑不变 + const editBtn = this.domNode.querySelector(".m-quill-tab-edit-btn"); + if (editBtn) { + editBtn.removeEventListener("click", this.handleEditClick); + this.handleEditClick = e => { e.stopPropagation(); this.domNode.dispatchEvent( new CustomEvent("edit-tabs", { @@ -170,12 +215,12 @@ class TabsBlot extends BlockEmbed { detail: { blot: this } }) ); - }); - this.eventBoundElements.set(editBtn, true); + }; + editBtn.addEventListener("click", this.handleEditClick); } - // 标签切换事件 - const tabButtons = this.domNode.querySelectorAll(".quill-tab-button:not([data-action])"); + // 标签切换事件 - 保持原有逻辑不变 + const tabButtons = this.domNode.querySelectorAll(".m-quill-tab-button:not([data-action])"); tabButtons.forEach(btn => { if (!this.eventBoundElements.has(btn)) { btn.addEventListener("click", () => { @@ -187,9 +232,8 @@ class TabsBlot extends BlockEmbed { }); } - // 增强版删除键处理 + // 增强版删除键处理 - 保持原有逻辑不变 bindDeleteKeyEvent() { - // 阻止从外部删除整个组件 this.domNode.addEventListener( "keydown", e => { @@ -200,31 +244,27 @@ class TabsBlot extends BlockEmbed { const range = selection.getRangeAt(0); const parentBlock = this.domNode; - // 判断光标是否在组件内部 const isInside = parentBlock.contains(range.commonAncestorContainer); - // 如果光标在组件外部,阻止删除 if (!isInside) { e.preventDefault(); return; } - // 检查是否选中了整个组件 if ( range.startContainer === parentBlock && range.endContainer === parentBlock && range.startOffset === 0 && range.endOffset >= parentBlock.childNodes.length ) { - e.preventDefault(); // 阻止删除整个组件 + e.preventDefault(); } } }, true - ); // 使用捕获阶段 + ); - // 标签栏禁止编辑 - const tabList = this.domNode.querySelector(".quill-tab-list"); + const tabList = this.domNode.querySelector(".m-quill-tab-list"); if (tabList) { tabList.querySelectorAll("*").forEach(el => { el.contentEditable = "false"; @@ -233,20 +273,24 @@ class TabsBlot extends BlockEmbed { } selectTab(index) { - const buttons = this.domNode.querySelectorAll(".quill-tab-button:not([data-action])"); - const panels = this.domNode.querySelectorAll(".quill-tab-content"); + const buttons = this.domNode.querySelectorAll(".m-quill-tab-button:not([data-action])"); + const panels = this.domNode.querySelectorAll(".m-quill-tab-content"); + // 保持原有样式逻辑不变 buttons.forEach((btn, i) => { btn.setAttribute( "style", ` - padding: 10px 15px; - font-weight: 500; + padding: 1%; + font-weight: 900; cursor: pointer; background: transparent; border: none; - transition: background-color 0.2s; - ${i === index ? "color: #007bff; background-color: white; border-bottom: 2px solid #007bff;" : ""} + font-size:16px; + margin-right: 1%; + color: #8f9099; + border-bottom: 3px solid transparent; + ${i === index ? "color: #1f2635;border-bottom: 3px solid #537CD8;font-size:16px;" : ""} ` ); }); @@ -254,21 +298,32 @@ class TabsBlot extends BlockEmbed { panels.forEach((panel, i) => { panel.style.display = i === index ? "block" : "none"; }); + + // 滚动到当前选中的标签 + const scrollContainer = this.domNode.querySelector(".m-quill-tab-scroll-container"); + const activeBtn = buttons[index]; + if (scrollContainer && activeBtn) { + activeBtn.scrollIntoView({ + behavior: "smooth", + block: "nearest", + inline: "center" + }); + } } static value(node) { const tabs = []; - const buttons = node.querySelectorAll(".quill-tab-button:not([data-action])"); - const panels = node.querySelectorAll(".quill-tab-content"); + const buttons = node.querySelectorAll(".m-quill-tab-button:not([data-action])"); + const panels = node.querySelectorAll(".m-quill-tab-content"); buttons.forEach((btn, i) => { tabs.push({ title: btn.textContent, - content: panels[i].innerHTML + content: panels[i]?.innerHTML || "" }); }); - return { tabs }; + return tabs; } update(mutations, context) { @@ -280,7 +335,63 @@ class TabsBlot extends BlockEmbed { scriptTag.parentNode.replaceChild(newScript, scriptTag); } this.bindEvents(); - this.bindDeleteKeyEvent(); // 重新绑定删除事件 + this.bindDeleteKeyEvent(); + } + + getValue() { + return TabsBlot.value(this.domNode); + } + + // 更新标签页数据 - 保持原有逻辑不变 + updateContents(tabs) { + const contentList = this.domNode.querySelector(".m-quill-tab-content-list"); + const tabList = this.domNode.querySelector(".m-quill-tab-list"); + const editBtn = this.domNode.querySelector(".m-quill-tab-edit-btn"); + + Array.from(tabList.children).forEach(child => { + if (!child.classList.contains("m-quill-tab-edit-btn")) { + child.remove(); + } + }); + contentList.innerHTML = ""; + + tabs.forEach((tab, index) => { + const btn = document.createElement("button"); + btn.className = "m-quill-tab-button"; + btn.setAttribute("data-index", index); + btn.textContent = tab.title; + btn.setAttribute( + "style", + ` + padding: 1%; + font-weight: 900; + color: #8f9099; + cursor: pointer; + background: transparent; + border: none; + margin-right: 1%; + font-size:16px; + ${index === 0 ? "color: #1f2635; border-bottom: 3px solid #537CD8;font-size:16px;" : ""} + ` + ); + tabList.insertBefore(btn, editBtn); + + const panel = document.createElement("div"); + panel.className = "m-quill-tab-content"; + panel.setAttribute("data-index", index); + panel.innerHTML = tab.content; + panel.setAttribute( + "style", + ` + display: ${index === 0 ? "block" : "none"}; + min-height: 50px; + ` + ); + panel.contentEditable = "false"; + contentList.appendChild(panel); + }); + + this.bindEvents(); } } diff --git a/src/components/Editor/quill-tabs222.js b/src/components/Editor/quill-tabs222.js deleted file mode 100644 index eb80593..0000000 --- a/src/components/Editor/quill-tabs222.js +++ /dev/null @@ -1,180 +0,0 @@ -import { Quill } from "@vueup/vue-quill"; - -const BlockEmbed = Quill.import("blots/block/embed"); - -class TabsBlot extends BlockEmbed { - static blotName = "tabs"; - static tagName = "div"; - static className = "quill-tabs"; - - constructor(domNode) { - super(domNode); - this.bindEvents(); - } - - static create(value) { - const tabs = Array.isArray(value) ? value : []; - const node = super.create(value); - - // 主容器样式 - node.setAttribute( - "style", - ` - margin: 15px 0; - overflow: hidden; - border: 1px solid #dddddd; - border-radius: 4px; - position: relative; - ` - ); - - // 标签栏容器 - const tabList = document.createElement("div"); - tabList.className = "quill-tab-list"; - tabList.style.cssText = ` - display: flex; - background-color: #f8f9fa; - border-bottom: 1px solid #dddddd; - `; - - // 内容区容器 - const contentList = document.createElement("div"); - contentList.className = "quill-tab-content-list"; - contentList.style.cssText = "padding: 15px;"; - - // 生成标签和内容 - tabs.forEach((tab, index) => { - // 标签按钮 - const btn = document.createElement("button"); - btn.className = `quill-tab-button ${index === 0 ? "active" : ""}`; - btn.dataset.index = index; - btn.textContent = tab.title || `标签${index + 1}`; - btn.style.cssText = ` - padding: 10px 15px; - font-weight: 500; - cursor: pointer; - background: transparent; - border: none; - ${index === 0 ? "color: #007bff; background-color: white; border-bottom: 2px solid #007bff;" : ""} - `; - tabList.appendChild(btn); - - // 内容面板 - const panel = document.createElement("div"); - panel.className = `quill-tab-content ${index === 0 ? "active" : ""}`; - panel.dataset.index = index; - panel.innerHTML = tab.content || ""; - panel.style.display = index === 0 ? "block" : "none"; - contentList.appendChild(panel); - }); - - // 编辑按钮 - const editBtn = document.createElement("button"); - editBtn.className = "quill-tab-edit-btn"; - editBtn.textContent = "编辑"; - editBtn.dataset.action = "edit"; - editBtn.style.cssText = ` - display: flex; - align-items: center; - padding: 10px; - margin-left: auto; - color: #606266; - cursor: pointer; - background: transparent; - border: none; - `; - editBtn.onmouseover = () => (editBtn.style.color = "#007bff"); - editBtn.onmouseout = () => (editBtn.style.color = "#606266"); - tabList.appendChild(editBtn); - - // 组装DOM - node.appendChild(tabList); - node.appendChild(contentList); - node.contentEditable = "false"; - - return node; - } - - // 改进的事件绑定方法,避免重复绑定 - bindEvents() { - // 使用WeakMap存储已绑定的元素,避免重复绑定 - if (!this.eventBoundElements) { - this.eventBoundElements = new WeakMap(); - } - - // 编辑按钮事件 - const editBtn = this.domNode.querySelector(".quill-tab-edit-btn"); - if (editBtn && !this.eventBoundElements.has(editBtn)) { - editBtn.addEventListener("click", e => { - e.stopPropagation(); - this.domNode.dispatchEvent( - new CustomEvent("edit-tabs", { - bubbles: true, - detail: { blot: this } - }) - ); - }); - this.eventBoundElements.set(editBtn, true); - } - - // 标签切换事件 - const tabButtons = this.domNode.querySelectorAll(".quill-tab-button:not([data-action])"); - tabButtons.forEach(btn => { - if (!this.eventBoundElements.has(btn)) { - btn.addEventListener("click", () => { - const index = parseInt(btn.dataset.index, 10); - this.selectTab(index); - }); - this.eventBoundElements.set(btn, true); - } - }); - } - - // 移除了有问题的unbindEvents方法 - - selectTab(index) { - const buttons = this.domNode.querySelectorAll(".quill-tab-button:not([data-action])"); - const panels = this.domNode.querySelectorAll(".quill-tab-content"); - - if (index < 0 || index >= buttons.length) return; - - // 更新按钮样式 - buttons.forEach((btn, i) => { - btn.style.cssText = ` - padding: 10px 15px; - font-weight: 500; - cursor: pointer; - background: transparent; - border: none; - ${i === index ? "color: #007bff; background-color: white; border-bottom: 2px solid #007bff;" : ""} - `; - }); - - // 更新内容面板显示 - panels.forEach((panel, i) => { - panel.style.display = i === index ? "block" : "none"; - }); - } - - static value(node) { - const tabs = []; - const buttons = node.querySelectorAll(".quill-tab-button:not([data-action])"); - const panels = node.querySelectorAll(".quill-tab-content"); - - buttons.forEach((btn, i) => { - tabs.push({ - title: btn.textContent, - content: panels[i]?.innerHTML || "" - }); - }); - - return tabs; - } - - update(mutations, context) { - super.update(mutations, context); - this.bindEvents(); - } -} - -export default TabsBlot; diff --git a/src/components/Editor/quill-video.js b/src/components/Editor/quill-video.js index 731e457..c36f249 100644 --- a/src/components/Editor/quill-video.js +++ b/src/components/Editor/quill-video.js @@ -14,8 +14,16 @@ class Video extends BlockEmbed { node.setAttribute("webkit-playsinline", "true"); node.setAttribute("type", "video/mp4"); // poster 属性指定视频下载时显示的图像,或者在用户点击播放按钮前显示的图像。 - node.setAttribute("poster", value.poster); + // console.log(value.url, "= value.poster="); + // node.setAttribute("poster", this.sanitize(value.url)); node.setAttribute("src", this.sanitize(value.url)); + node.setAttribute( + "style", + ` + width: 600px; + height: 300px; + ` + ); return node; } @@ -35,8 +43,8 @@ class Video extends BlockEmbed { static value(domNode) { // 设置自定义的属性值 return { - url: domNode.getAttribute("src"), - poster: domNode.getAttribute("poster") + url: domNode.getAttribute("src") + // poster: domNode.getAttribute("src") }; } diff --git a/vite.config.ts.timestamp-1753426525446-28eee6cbb234d.mjs b/vite.config.ts.timestamp-1753426525446-28eee6cbb234d.mjs new file mode 100644 index 0000000..36eea6f --- /dev/null +++ b/vite.config.ts.timestamp-1753426525446-28eee6cbb234d.mjs @@ -0,0 +1,372 @@ +// vite.config.ts +import { defineConfig, loadEnv } from "file:///D:/new_ops/orico-officialWebsite-ts-admin(%E5%AE%98%E7%BD%91%E5%90%8E%E5%8F%B0-git)/node_modules/vite/dist/node/index.js"; +import { resolve as resolve2 } from "path"; + +// build/getEnv.ts +function wrapperEnv(envConf) { + const ret = {}; + for (const envName of Object.keys(envConf)) { + let realName = envConf[envName].replace(/\\n/g, "\n"); + realName = realName === "true" ? true : realName === "false" ? false : realName; + if (envName === "VITE_PORT") + realName = Number(realName); + if (envName === "VITE_PROXY") { + try { + realName = JSON.parse(realName); + } catch (error) { + } + } + ret[envName] = realName; + } + return ret; +} + +// build/proxy.ts +function createProxy(list = []) { + const ret = {}; + for (const [prefix, target] of list) { + const httpsRE = /^https:\/\//; + const isHttps = httpsRE.test(target); + ret[prefix] = { + target, + changeOrigin: true, + ws: true, + rewrite: (path) => path.replace(new RegExp(`^${prefix}`), ""), + // https is require secure=false + ...isHttps ? { secure: false } : {} + }; + } + return ret; +} + +// build/plugins.ts +import { resolve } from "path"; +import { VitePWA } from "file:///D:/new_ops/orico-officialWebsite-ts-admin(%E5%AE%98%E7%BD%91%E5%90%8E%E5%8F%B0-git)/node_modules/vite-plugin-pwa/dist/index.js"; +import { visualizer } from "file:///D:/new_ops/orico-officialWebsite-ts-admin(%E5%AE%98%E7%BD%91%E5%90%8E%E5%8F%B0-git)/node_modules/rollup-plugin-visualizer/dist/plugin/index.js"; +import { createHtmlPlugin } from "file:///D:/new_ops/orico-officialWebsite-ts-admin(%E5%AE%98%E7%BD%91%E5%90%8E%E5%8F%B0-git)/node_modules/vite-plugin-html/dist/index.mjs"; +import { createSvgIconsPlugin } from "file:///D:/new_ops/orico-officialWebsite-ts-admin(%E5%AE%98%E7%BD%91%E5%90%8E%E5%8F%B0-git)/node_modules/vite-plugin-svg-icons/dist/index.mjs"; +import vue from "file:///D:/new_ops/orico-officialWebsite-ts-admin(%E5%AE%98%E7%BD%91%E5%90%8E%E5%8F%B0-git)/node_modules/@vitejs/plugin-vue/dist/index.mjs"; +import vueJsx from "file:///D:/new_ops/orico-officialWebsite-ts-admin(%E5%AE%98%E7%BD%91%E5%90%8E%E5%8F%B0-git)/node_modules/@vitejs/plugin-vue-jsx/dist/index.mjs"; +import eslintPlugin from "file:///D:/new_ops/orico-officialWebsite-ts-admin(%E5%AE%98%E7%BD%91%E5%90%8E%E5%8F%B0-git)/node_modules/vite-plugin-eslint/dist/index.mjs"; +import viteCompression from "file:///D:/new_ops/orico-officialWebsite-ts-admin(%E5%AE%98%E7%BD%91%E5%90%8E%E5%8F%B0-git)/node_modules/vite-plugin-compression/dist/index.mjs"; +import vueSetupExtend from "file:///D:/new_ops/orico-officialWebsite-ts-admin(%E5%AE%98%E7%BD%91%E5%90%8E%E5%8F%B0-git)/node_modules/unplugin-vue-setup-extend-plus/dist/vite.js"; +import AutoImport from "file:///D:/new_ops/orico-officialWebsite-ts-admin(%E5%AE%98%E7%BD%91%E5%90%8E%E5%8F%B0-git)/node_modules/unplugin-auto-import/dist/vite.js"; +import Components from "file:///D:/new_ops/orico-officialWebsite-ts-admin(%E5%AE%98%E7%BD%91%E5%90%8E%E5%8F%B0-git)/node_modules/unplugin-vue-components/dist/vite.mjs"; +import { ElementPlusResolver } from "file:///D:/new_ops/orico-officialWebsite-ts-admin(%E5%AE%98%E7%BD%91%E5%90%8E%E5%8F%B0-git)/node_modules/unplugin-vue-components/dist/resolvers.mjs"; +import Icons from "file:///D:/new_ops/orico-officialWebsite-ts-admin(%E5%AE%98%E7%BD%91%E5%90%8E%E5%8F%B0-git)/node_modules/unplugin-icons/dist/vite.mjs"; +import IconsResolver from "file:///D:/new_ops/orico-officialWebsite-ts-admin(%E5%AE%98%E7%BD%91%E5%90%8E%E5%8F%B0-git)/node_modules/unplugin-icons/dist/resolver.mjs"; +var createVitePlugins = (viteEnv) => { + const { VITE_GLOB_APP_TITLE, VITE_REPORT, VITE_PWA } = viteEnv; + return [ + vue(), + // vue 可以使用 jsx/tsx 语法 + vueJsx(), + // esLint 报错信息显示在浏览器界面上 + eslintPlugin(), + // name 可以写在 script 标签上 + vueSetupExtend({}), + // 创建打包压缩配置 + createCompression(viteEnv), + // 注入变量到 html 文件 + createHtmlPlugin({ + inject: { + data: { title: VITE_GLOB_APP_TITLE } + } + }), + // 使用 svg 图标 + createSvgIconsPlugin({ + iconDirs: [resolve(process.cwd(), "src/assets/icons")], + symbolId: "icon-[dir]-[name]" + }), + // element按需导入 + AutoImport({ + // 安装两行后你会发现在组件中不用再导入ref,reactive等 + imports: ["vue", "vue-router"], + dts: "src/auto-import.d.ts", + // element + resolvers: [ + ElementPlusResolver({ importStyle: "sass" }), + IconsResolver({ + prefix: "Icon" + }) + ] + }), + Components({ + // element + resolvers: [ + ElementPlusResolver({ importStyle: "sass" }), + IconsResolver({ + enabledCollections: ["ep"] + }) + ], + // 默认存放位置 + dts: "src/components.d.ts" + }), + Icons({ + autoInstall: true + }), + // vitePWA + VITE_PWA && createVitePwa(viteEnv), + // 是否生成包预览,分析依赖包大小做优化处理 + VITE_REPORT && visualizer({ filename: "stats.html", gzipSize: true, brotliSize: true }) + ]; +}; +var createCompression = (viteEnv) => { + const { VITE_BUILD_COMPRESS = "none", VITE_BUILD_COMPRESS_DELETE_ORIGIN_FILE } = viteEnv; + const compressList = VITE_BUILD_COMPRESS.split(","); + const plugins = []; + if (compressList.includes("gzip")) { + plugins.push( + viteCompression({ + ext: ".gz", + algorithm: "gzip", + deleteOriginFile: VITE_BUILD_COMPRESS_DELETE_ORIGIN_FILE + }) + ); + } + if (compressList.includes("brotli")) { + plugins.push( + viteCompression({ + ext: ".br", + algorithm: "brotliCompress", + deleteOriginFile: VITE_BUILD_COMPRESS_DELETE_ORIGIN_FILE + }) + ); + } + return plugins; +}; +var createVitePwa = (viteEnv) => { + const { VITE_GLOB_APP_TITLE } = viteEnv; + return VitePWA({ + registerType: "autoUpdate", + manifest: { + name: VITE_GLOB_APP_TITLE, + short_name: VITE_GLOB_APP_TITLE, + theme_color: "#ffffff", + icons: [ + { + src: "/logo.png", + sizes: "192x192", + type: "image/png" + }, + { + src: "/logo.png", + sizes: "512x512", + type: "image/png" + }, + { + src: "/logo.png", + sizes: "512x512", + type: "image/png", + purpose: "any maskable" + } + ] + } + }); +}; + +// package.json +var package_default = { + name: "yc_ops_admin_ts", + private: true, + version: "1.0.0", + type: "module", + scripts: { + dev: "vite", + serve: "vite", + "build:dev": "vue-tsc && vite build --mode development", + "build:test": "vue-tsc && vite build --mode test", + "build:pro": "vue-tsc && vite build --mode production", + "type:check": "vue-tsc --noEmit --skipLibCheck", + preview: "npm run build:dev && vite preview", + "lint:eslint": "eslint --fix --ext .js,.ts,.vue ./src", + "lint:prettier": 'prettier --write "src/**/*.{js,ts,json,tsx,css,less,scss,vue,html,md}"', + "lint:stylelint": 'stylelint --cache --fix "**/*.{vue,less,postcss,css,scss}" --cache --cache-location node_modules/.cache/stylelint/', + "lint:lint-staged": "lint-staged", + prepare: "husky install", + release: "standard-version", + commit: "git add -A && czg && git push" + }, + dependencies: { + "@element-plus/icons-vue": "^2.1.0", + "@types/decimal.js": "^7.4.0", + "@vueup/vue-quill": "^1.2.0", + "@vueuse/core": "^10.1.2", + "@wangeditor/editor": "^5.1.23", + "@wangeditor/editor-for-vue": "^5.1.12", + "@zhj-target/vue3-kind-editor": "^0.1.3", + "async-validator": "^4.2.5", + axios: "^1.4.0", + "bwip-js": "^4.3.2", + "crypto-js": "^4.2.0", + dayjs: "^1.11.9", + decimal: "^0.0.2", + "default-passive-events": "^2.0.0", + "driver.js": "^0.9.8", + "element-plus": "^2.3.4", + "file-saver": "^2.0.5", + "js-md5": "^0.7.3", + jsbarcode: "^3.11.6", + jsonpack: "^1.1.5", + "lodash-es": "^4.17.21", + "mavon-editor": "^3.0.2", + mitt: "^3.0.0", + nprogress: "^0.2.0", + pinia: "^2.1.3", + "pinia-plugin-persistedstate": "^3.1.0", + "print-js": "^1.6.0", + qs: "^6.13.1", + quill: "^2.0.3", + sortablejs: "^1.15.0", + vue: "^3.3.4", + "vue-router": "^4.2.2", + vuedraggable: "^4.1.0", + "vxe-table": "^4.5.0-beta.10", + "xe-utils": "^3.5.11", + xlsx: "^0.18.5" + }, + devDependencies: { + "@commitlint/cli": "^17.6.3", + "@commitlint/config-conventional": "^17.6.3", + "@iconify-json/ep": "^1.1.10", + "@types/crypto-js": "^4.2.2", + "@types/file-saver": "^2.0.5", + "@types/js-md5": "^0.7.0", + "@types/nprogress": "^0.2.0", + "@types/qs": "^6.9.7", + "@types/sortablejs": "^1.15.1", + "@typescript-eslint/eslint-plugin": "^5.59.7", + "@typescript-eslint/parser": "^5.59.7", + "@vitejs/plugin-vue": "^4.2.3", + "@vitejs/plugin-vue-jsx": "^3.0.1", + autoprefixer: "^10.4.14", + "cz-git": "^1.6.1", + czg: "^1.6.1", + eslint: "^8.41.0", + "eslint-config-prettier": "^8.8.0", + "eslint-plugin-prettier": "^4.2.1", + "eslint-plugin-vue": "^9.14.0", + husky: "^8.0.3", + "lint-staged": "^13.2.2", + postcss: "^8.4.23", + "postcss-html": "^1.5.0", + prettier: "^2.8.8", + qrcode: "^1.5.3", + "rollup-plugin-visualizer": "^5.9.0", + sass: "^1.62.1", + "standard-version": "^9.5.0", + stylelint: "^15.6.2", + "stylelint-config-html": "^1.1.0", + "stylelint-config-recess-order": "^4.0.0", + "stylelint-config-recommended-scss": "^12.0.0", + "stylelint-config-recommended-vue": "^1.4.0", + "stylelint-config-standard": "^33.0.0", + "stylelint-config-standard-scss": "^9.0.0", + typescript: "^5.0.2", + "unplugin-auto-import": "^0.16.4", + "unplugin-icons": "^0.16.3", + "unplugin-vue-components": "^0.25.1", + "unplugin-vue-setup-extend-plus": "^1.0.0", + vite: "^4.3.9", + "vite-plugin-compression": "^0.5.1", + "vite-plugin-eslint": "^1.8.1", + "vite-plugin-html": "^3.2.0", + "vite-plugin-pwa": "^0.15.0", + "vite-plugin-svg-icons": "^2.0.1", + "vue-tsc": "^1.6.5" + }, + engines: { + node: ">=16.0.0" + }, + browserslist: { + production: [ + "> 1%", + "not dead", + "not op_mini all" + ], + development: [ + "last 1 chrome version", + "last 1 firefox version", + "last 1 safari version" + ] + }, + config: { + commitizen: { + path: "node_modules/cz-git" + } + } +}; + +// vite.config.ts +import dayjs from "file:///D:/new_ops/orico-officialWebsite-ts-admin(%E5%AE%98%E7%BD%91%E5%90%8E%E5%8F%B0-git)/node_modules/dayjs/dayjs.min.js"; +var __vite_injected_original_dirname = "D:\\new_ops\\orico-officialWebsite-ts-admin(\u5B98\u7F51\u540E\u53F0-git)"; +var { dependencies, devDependencies, name, version } = package_default; +var __APP_INFO__ = { + pkg: { dependencies, devDependencies, name, version }, + lastBuildTime: dayjs().format("YYYY-MM-DD HH:mm:ss") +}; +var vite_config_default = defineConfig(({ mode }) => { + const root = process.cwd(); + const env = loadEnv(mode, root); + const viteEnv = wrapperEnv(env); + return { + base: viteEnv.VITE_PUBLIC_PATH, + root, + resolve: { + alias: { + "@": resolve2(__vite_injected_original_dirname, "./src") + } + }, + define: { + __APP_INFO__: JSON.stringify(__APP_INFO__) + }, + css: { + preprocessorOptions: { + scss: { + additionalData: `@use "@/styles/var.scss" as *;` + } + } + }, + server: { + host: "0.0.0.0", + port: viteEnv.VITE_PORT, + open: viteEnv.VITE_OPEN, + cors: true, + // Load proxy configuration from .env.development + proxy: createProxy(viteEnv.VITE_PROXY) + }, + plugins: createVitePlugins(viteEnv), + esbuild: { + //"console.log","console.log", + pure: viteEnv.VITE_DROP_CONSOLE ? ["debugger"] : [] + }, + build: { + outDir: "dist", + minify: "esbuild", + // esbuild 打包更快,但是不能去除 console.log,terser打包慢,但能去除 console.log + // minify: "terser", + // terserOptions: { + // compress: { + // drop_console: viteEnv.VITE_DROP_CONSOLE, + // drop_debugger: true + // } + // }, + // 禁用 gzip 压缩大小报告,可略微减少打包时间 + reportCompressedSize: false, + // 规定触发警告的 chunk 大小 + chunkSizeWarningLimit: 2e3, + rollupOptions: { + output: { + // Static resource classification and packaging + chunkFileNames: "assets/js/[name]-[hash].js", + entryFileNames: "assets/js/[name]-[hash].js", + assetFileNames: "assets/[ext]/[name]-[hash].[ext]" + } + } + } + }; +}); +export { + vite_config_default as default +}; +//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsidml0ZS5jb25maWcudHMiLCAiYnVpbGQvZ2V0RW52LnRzIiwgImJ1aWxkL3Byb3h5LnRzIiwgImJ1aWxkL3BsdWdpbnMudHMiLCAicGFja2FnZS5qc29uIl0sCiAgInNvdXJjZXNDb250ZW50IjogWyJjb25zdCBfX3ZpdGVfaW5qZWN0ZWRfb3JpZ2luYWxfZGlybmFtZSA9IFwiRDpcXFxcbmV3X29wc1xcXFxvcmljby1vZmZpY2lhbFdlYnNpdGUtdHMtYWRtaW4oXHU1Qjk4XHU3RjUxXHU1NDBFXHU1M0YwLWdpdClcIjtjb25zdCBfX3ZpdGVfaW5qZWN0ZWRfb3JpZ2luYWxfZmlsZW5hbWUgPSBcIkQ6XFxcXG5ld19vcHNcXFxcb3JpY28tb2ZmaWNpYWxXZWJzaXRlLXRzLWFkbWluKFx1NUI5OFx1N0Y1MVx1NTQwRVx1NTNGMC1naXQpXFxcXHZpdGUuY29uZmlnLnRzXCI7Y29uc3QgX192aXRlX2luamVjdGVkX29yaWdpbmFsX2ltcG9ydF9tZXRhX3VybCA9IFwiZmlsZTovLy9EOi9uZXdfb3BzL29yaWNvLW9mZmljaWFsV2Vic2l0ZS10cy1hZG1pbiglRTUlQUUlOTglRTclQkQlOTElRTUlOTAlOEUlRTUlOEYlQjAtZ2l0KS92aXRlLmNvbmZpZy50c1wiO2ltcG9ydCB7IGRlZmluZUNvbmZpZywgbG9hZEVudiwgQ29uZmlnRW52LCBVc2VyQ29uZmlnIH0gZnJvbSBcInZpdGVcIjtcclxuaW1wb3J0IHsgcmVzb2x2ZSB9IGZyb20gXCJwYXRoXCI7XHJcbmltcG9ydCB7IHdyYXBwZXJFbnYgfSBmcm9tIFwiLi9idWlsZC9nZXRFbnZcIjtcclxuaW1wb3J0IHsgY3JlYXRlUHJveHkgfSBmcm9tIFwiLi9idWlsZC9wcm94eVwiO1xyXG5pbXBvcnQgeyBjcmVhdGVWaXRlUGx1Z2lucyB9IGZyb20gXCIuL2J1aWxkL3BsdWdpbnNcIjtcclxuXHJcbmltcG9ydCBwa2cgZnJvbSBcIi4vcGFja2FnZS5qc29uXCI7XHJcbmltcG9ydCBkYXlqcyBmcm9tIFwiZGF5anNcIjtcclxuXHJcbmNvbnN0IHsgZGVwZW5kZW5jaWVzLCBkZXZEZXBlbmRlbmNpZXMsIG5hbWUsIHZlcnNpb24gfSA9IHBrZztcclxuY29uc3QgX19BUFBfSU5GT19fID0ge1xyXG4gICAgcGtnOiB7IGRlcGVuZGVuY2llcywgZGV2RGVwZW5kZW5jaWVzLCBuYW1lLCB2ZXJzaW9uIH0sXHJcbiAgICBsYXN0QnVpbGRUaW1lOiBkYXlqcygpLmZvcm1hdChcIllZWVktTU0tREQgSEg6bW06c3NcIilcclxufTtcclxuXHJcbi8vIEBzZWU6IGh0dHBzOi8vdml0ZWpzLmRldi9jb25maWcvXHJcbmV4cG9ydCBkZWZhdWx0IGRlZmluZUNvbmZpZygoeyBtb2RlIH06IENvbmZpZ0Vudik6IFVzZXJDb25maWcgPT4ge1xyXG4gICAgY29uc3Qgcm9vdCA9IHByb2Nlc3MuY3dkKCk7XHJcbiAgICBjb25zdCBlbnYgPSBsb2FkRW52KG1vZGUsIHJvb3QpO1xyXG4gICAgY29uc3Qgdml0ZUVudiA9IHdyYXBwZXJFbnYoZW52KTtcclxuXHJcbiAgICByZXR1cm4ge1xyXG4gICAgICAgIGJhc2U6IHZpdGVFbnYuVklURV9QVUJMSUNfUEFUSCxcclxuICAgICAgICByb290LFxyXG4gICAgICAgIHJlc29sdmU6IHtcclxuICAgICAgICAgICAgYWxpYXM6IHtcclxuICAgICAgICAgICAgICAgIFwiQFwiOiByZXNvbHZlKF9fZGlybmFtZSwgXCIuL3NyY1wiKVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSxcclxuICAgICAgICBkZWZpbmU6IHtcclxuICAgICAgICAgICAgX19BUFBfSU5GT19fOiBKU09OLnN0cmluZ2lmeShfX0FQUF9JTkZPX18pXHJcbiAgICAgICAgfSxcclxuICAgICAgICBjc3M6IHtcclxuICAgICAgICAgICAgcHJlcHJvY2Vzc29yT3B0aW9uczoge1xyXG4gICAgICAgICAgICAgICAgc2Nzczoge1xyXG4gICAgICAgICAgICAgICAgICAgIGFkZGl0aW9uYWxEYXRhOiBgQHVzZSBcIkAvc3R5bGVzL3Zhci5zY3NzXCIgYXMgKjtgXHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9LFxyXG4gICAgICAgIHNlcnZlcjoge1xyXG4gICAgICAgICAgICBob3N0OiBcIjAuMC4wLjBcIixcclxuICAgICAgICAgICAgcG9ydDogdml0ZUVudi5WSVRFX1BPUlQsXHJcbiAgICAgICAgICAgIG9wZW46IHZpdGVFbnYuVklURV9PUEVOLFxyXG4gICAgICAgICAgICBjb3JzOiB0cnVlLFxyXG4gICAgICAgICAgICAvLyBMb2FkIHByb3h5IGNvbmZpZ3VyYXRpb24gZnJvbSAuZW52LmRldmVsb3BtZW50XHJcbiAgICAgICAgICAgIHByb3h5OiBjcmVhdGVQcm94eSh2aXRlRW52LlZJVEVfUFJPWFkpXHJcbiAgICAgICAgfSxcclxuICAgICAgICBwbHVnaW5zOiBjcmVhdGVWaXRlUGx1Z2lucyh2aXRlRW52KSxcclxuICAgICAgICBlc2J1aWxkOiB7XHJcbiAgICAgICAgICAgIC8vXCJjb25zb2xlLmxvZ1wiLFwiY29uc29sZS5sb2dcIixcclxuICAgICAgICAgICAgcHVyZTogdml0ZUVudi5WSVRFX0RST1BfQ09OU09MRSA/IFtcImRlYnVnZ2VyXCJdIDogW11cclxuICAgICAgICB9LFxyXG4gICAgICAgIGJ1aWxkOiB7XHJcbiAgICAgICAgICAgIG91dERpcjogXCJkaXN0XCIsXHJcbiAgICAgICAgICAgIG1pbmlmeTogXCJlc2J1aWxkXCIsXHJcbiAgICAgICAgICAgIC8vIGVzYnVpbGQgXHU2MjUzXHU1MzA1XHU2NkY0XHU1RkVCXHVGRjBDXHU0RjQ2XHU2NjJGXHU0RTBEXHU4MEZEXHU1M0JCXHU5NjY0IGNvbnNvbGUubG9nXHVGRjBDdGVyc2VyXHU2MjUzXHU1MzA1XHU2MTYyXHVGRjBDXHU0RjQ2XHU4MEZEXHU1M0JCXHU5NjY0IGNvbnNvbGUubG9nXHJcbiAgICAgICAgICAgIC8vIG1pbmlmeTogXCJ0ZXJzZXJcIixcclxuICAgICAgICAgICAgLy8gdGVyc2VyT3B0aW9uczoge1xyXG4gICAgICAgICAgICAvLyBcdGNvbXByZXNzOiB7XHJcbiAgICAgICAgICAgIC8vIFx0XHRkcm9wX2NvbnNvbGU6IHZpdGVFbnYuVklURV9EUk9QX0NPTlNPTEUsXHJcbiAgICAgICAgICAgIC8vIFx0XHRkcm9wX2RlYnVnZ2VyOiB0cnVlXHJcbiAgICAgICAgICAgIC8vIFx0fVxyXG4gICAgICAgICAgICAvLyB9LFxyXG4gICAgICAgICAgICAvLyBcdTc5ODFcdTc1MjggZ3ppcCBcdTUzOEJcdTdGMjlcdTU5MjdcdTVDMEZcdTYyQTVcdTU0NEFcdUZGMENcdTUzRUZcdTc1NjVcdTVGQUVcdTUxQ0ZcdTVDMTFcdTYyNTNcdTUzMDVcdTY1RjZcdTk1RjRcclxuICAgICAgICAgICAgcmVwb3J0Q29tcHJlc3NlZFNpemU6IGZhbHNlLFxyXG4gICAgICAgICAgICAvLyBcdTg5QzRcdTVCOUFcdTg5RTZcdTUzRDFcdThCNjZcdTU0NEFcdTc2ODQgY2h1bmsgXHU1OTI3XHU1QzBGXHJcbiAgICAgICAgICAgIGNodW5rU2l6ZVdhcm5pbmdMaW1pdDogMjAwMCxcclxuICAgICAgICAgICAgcm9sbHVwT3B0aW9uczoge1xyXG4gICAgICAgICAgICAgICAgb3V0cHV0OiB7XHJcbiAgICAgICAgICAgICAgICAgICAgLy8gU3RhdGljIHJlc291cmNlIGNsYXNzaWZpY2F0aW9uIGFuZCBwYWNrYWdpbmdcclxuICAgICAgICAgICAgICAgICAgICBjaHVua0ZpbGVOYW1lczogXCJhc3NldHMvanMvW25hbWVdLVtoYXNoXS5qc1wiLFxyXG4gICAgICAgICAgICAgICAgICAgIGVudHJ5RmlsZU5hbWVzOiBcImFzc2V0cy9qcy9bbmFtZV0tW2hhc2hdLmpzXCIsXHJcbiAgICAgICAgICAgICAgICAgICAgYXNzZXRGaWxlTmFtZXM6IFwiYXNzZXRzL1tleHRdL1tuYW1lXS1baGFzaF0uW2V4dF1cIlxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgfTtcclxufSk7XHJcbiIsICJjb25zdCBfX3ZpdGVfaW5qZWN0ZWRfb3JpZ2luYWxfZGlybmFtZSA9IFwiRDpcXFxcbmV3X29wc1xcXFxvcmljby1vZmZpY2lhbFdlYnNpdGUtdHMtYWRtaW4oXHU1Qjk4XHU3RjUxXHU1NDBFXHU1M0YwLWdpdClcXFxcYnVpbGRcIjtjb25zdCBfX3ZpdGVfaW5qZWN0ZWRfb3JpZ2luYWxfZmlsZW5hbWUgPSBcIkQ6XFxcXG5ld19vcHNcXFxcb3JpY28tb2ZmaWNpYWxXZWJzaXRlLXRzLWFkbWluKFx1NUI5OFx1N0Y1MVx1NTQwRVx1NTNGMC1naXQpXFxcXGJ1aWxkXFxcXGdldEVudi50c1wiO2NvbnN0IF9fdml0ZV9pbmplY3RlZF9vcmlnaW5hbF9pbXBvcnRfbWV0YV91cmwgPSBcImZpbGU6Ly8vRDovbmV3X29wcy9vcmljby1vZmZpY2lhbFdlYnNpdGUtdHMtYWRtaW4oJUU1JUFFJTk4JUU3JUJEJTkxJUU1JTkwJThFJUU1JThGJUIwLWdpdCkvYnVpbGQvZ2V0RW52LnRzXCI7aW1wb3J0IHBhdGggZnJvbSBcInBhdGhcIjtcclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBpc0RldkZuKG1vZGU6IHN0cmluZyk6IGJvb2xlYW4ge1xyXG4gICAgcmV0dXJuIG1vZGUgPT09IFwiZGV2ZWxvcG1lbnRcIjtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIGlzUHJvZEZuKG1vZGU6IHN0cmluZyk6IGJvb2xlYW4ge1xyXG4gICAgcmV0dXJuIG1vZGUgPT09IFwicHJvZHVjdGlvblwiO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gaXNUZXN0Rm4obW9kZTogc3RyaW5nKTogYm9vbGVhbiB7XHJcbiAgICByZXR1cm4gbW9kZSA9PT0gXCJ0ZXN0XCI7XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBXaGV0aGVyIHRvIGdlbmVyYXRlIHBhY2thZ2UgcHJldmlld1xyXG4gKi9cclxuZXhwb3J0IGZ1bmN0aW9uIGlzUmVwb3J0TW9kZSgpOiBib29sZWFuIHtcclxuICAgIHJldHVybiBwcm9jZXNzLmVudi5WSVRFX1JFUE9SVCA9PT0gXCJ0cnVlXCI7XHJcbn1cclxuXHJcbi8vIFJlYWQgYWxsIGVudmlyb25tZW50IHZhcmlhYmxlIGNvbmZpZ3VyYXRpb24gZmlsZXMgdG8gcHJvY2Vzcy5lbnZcclxuZXhwb3J0IGZ1bmN0aW9uIHdyYXBwZXJFbnYoZW52Q29uZjogUmVjb3JkYWJsZSk6IFZpdGVFbnYge1xyXG4gICAgY29uc3QgcmV0OiBhbnkgPSB7fTtcclxuXHJcbiAgICBmb3IgKGNvbnN0IGVudk5hbWUgb2YgT2JqZWN0LmtleXMoZW52Q29uZikpIHtcclxuICAgICAgICBsZXQgcmVhbE5hbWUgPSBlbnZDb25mW2Vudk5hbWVdLnJlcGxhY2UoL1xcXFxuL2csIFwiXFxuXCIpO1xyXG4gICAgICAgIHJlYWxOYW1lID0gcmVhbE5hbWUgPT09IFwidHJ1ZVwiID8gdHJ1ZSA6IHJlYWxOYW1lID09PSBcImZhbHNlXCIgPyBmYWxzZSA6IHJlYWxOYW1lO1xyXG4gICAgICAgIGlmIChlbnZOYW1lID09PSBcIlZJVEVfUE9SVFwiKSByZWFsTmFtZSA9IE51bWJlcihyZWFsTmFtZSk7XHJcbiAgICAgICAgaWYgKGVudk5hbWUgPT09IFwiVklURV9QUk9YWVwiKSB7XHJcbiAgICAgICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgICAgICByZWFsTmFtZSA9IEpTT04ucGFyc2UocmVhbE5hbWUpO1xyXG4gICAgICAgICAgICB9IGNhdGNoIChlcnJvcikge31cclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0W2Vudk5hbWVdID0gcmVhbE5hbWU7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gcmV0O1xyXG59XHJcblxyXG4vKipcclxuICogR2V0IHVzZXIgcm9vdCBkaXJlY3RvcnlcclxuICogQHBhcmFtIGRpciBmaWxlIHBhdGhcclxuICovXHJcbmV4cG9ydCBmdW5jdGlvbiBnZXRSb290UGF0aCguLi5kaXI6IHN0cmluZ1tdKSB7XHJcbiAgICByZXR1cm4gcGF0aC5yZXNvbHZlKHByb2Nlc3MuY3dkKCksIC4uLmRpcik7XHJcbn1cclxuIiwgImNvbnN0IF9fdml0ZV9pbmplY3RlZF9vcmlnaW5hbF9kaXJuYW1lID0gXCJEOlxcXFxuZXdfb3BzXFxcXG9yaWNvLW9mZmljaWFsV2Vic2l0ZS10cy1hZG1pbihcdTVCOThcdTdGNTFcdTU0MEVcdTUzRjAtZ2l0KVxcXFxidWlsZFwiO2NvbnN0IF9fdml0ZV9pbmplY3RlZF9vcmlnaW5hbF9maWxlbmFtZSA9IFwiRDpcXFxcbmV3X29wc1xcXFxvcmljby1vZmZpY2lhbFdlYnNpdGUtdHMtYWRtaW4oXHU1Qjk4XHU3RjUxXHU1NDBFXHU1M0YwLWdpdClcXFxcYnVpbGRcXFxccHJveHkudHNcIjtjb25zdCBfX3ZpdGVfaW5qZWN0ZWRfb3JpZ2luYWxfaW1wb3J0X21ldGFfdXJsID0gXCJmaWxlOi8vL0Q6L25ld19vcHMvb3JpY28tb2ZmaWNpYWxXZWJzaXRlLXRzLWFkbWluKCVFNSVBRSU5OCVFNyVCRCU5MSVFNSU5MCU4RSVFNSU4RiVCMC1naXQpL2J1aWxkL3Byb3h5LnRzXCI7aW1wb3J0IHR5cGUgeyBQcm94eU9wdGlvbnMgfSBmcm9tIFwidml0ZVwiO1xyXG5cclxudHlwZSBQcm94eUl0ZW0gPSBbc3RyaW5nLCBzdHJpbmddO1xyXG5cclxudHlwZSBQcm94eUxpc3QgPSBQcm94eUl0ZW1bXTtcclxuXHJcbnR5cGUgUHJveHlUYXJnZXRMaXN0ID0gUmVjb3JkPHN0cmluZywgUHJveHlPcHRpb25zPjtcclxuXHJcbi8qKlxyXG4gKiBcdTUyMUJcdTVFRkFcdTRFRTNcdTc0MDZcdUZGMENcdTc1MjhcdTRFOEVcdTg5RTNcdTY3OTAgLmVudi5kZXZlbG9wbWVudCBcdTRFRTNcdTc0MDZcdTkxNERcdTdGNkVcclxuICogQHBhcmFtIGxpc3RcclxuICovXHJcbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVQcm94eShsaXN0OiBQcm94eUxpc3QgPSBbXSkge1xyXG4gICAgY29uc3QgcmV0OiBQcm94eVRhcmdldExpc3QgPSB7fTtcclxuICAgIGZvciAoY29uc3QgW3ByZWZpeCwgdGFyZ2V0XSBvZiBsaXN0KSB7XHJcbiAgICAgICAgY29uc3QgaHR0cHNSRSA9IC9eaHR0cHM6XFwvXFwvLztcclxuICAgICAgICBjb25zdCBpc0h0dHBzID0gaHR0cHNSRS50ZXN0KHRhcmdldCk7XHJcblxyXG4gICAgICAgIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9odHRwLXBhcnR5L25vZGUtaHR0cC1wcm94eSNvcHRpb25zXHJcbiAgICAgICAgcmV0W3ByZWZpeF0gPSB7XHJcbiAgICAgICAgICAgIHRhcmdldDogdGFyZ2V0LFxyXG4gICAgICAgICAgICBjaGFuZ2VPcmlnaW46IHRydWUsXHJcbiAgICAgICAgICAgIHdzOiB0cnVlLFxyXG4gICAgICAgICAgICByZXdyaXRlOiBwYXRoID0+IHBhdGgucmVwbGFjZShuZXcgUmVnRXhwKGBeJHtwcmVmaXh9YCksIFwiXCIpLFxyXG4gICAgICAgICAgICAvLyBodHRwcyBpcyByZXF1aXJlIHNlY3VyZT1mYWxzZVxyXG4gICAgICAgICAgICAuLi4oaXNIdHRwcyA/IHsgc2VjdXJlOiBmYWxzZSB9IDoge30pXHJcbiAgICAgICAgfTtcclxuICAgIH1cclxuICAgIHJldHVybiByZXQ7XHJcbn1cclxuIiwgImNvbnN0IF9fdml0ZV9pbmplY3RlZF9vcmlnaW5hbF9kaXJuYW1lID0gXCJEOlxcXFxuZXdfb3BzXFxcXG9yaWNvLW9mZmljaWFsV2Vic2l0ZS10cy1hZG1pbihcdTVCOThcdTdGNTFcdTU0MEVcdTUzRjAtZ2l0KVxcXFxidWlsZFwiO2NvbnN0IF9fdml0ZV9pbmplY3RlZF9vcmlnaW5hbF9maWxlbmFtZSA9IFwiRDpcXFxcbmV3X29wc1xcXFxvcmljby1vZmZpY2lhbFdlYnNpdGUtdHMtYWRtaW4oXHU1Qjk4XHU3RjUxXHU1NDBFXHU1M0YwLWdpdClcXFxcYnVpbGRcXFxccGx1Z2lucy50c1wiO2NvbnN0IF9fdml0ZV9pbmplY3RlZF9vcmlnaW5hbF9pbXBvcnRfbWV0YV91cmwgPSBcImZpbGU6Ly8vRDovbmV3X29wcy9vcmljby1vZmZpY2lhbFdlYnNpdGUtdHMtYWRtaW4oJUU1JUFFJTk4JUU3JUJEJTkxJUU1JTkwJThFJUU1JThGJUIwLWdpdCkvYnVpbGQvcGx1Z2lucy50c1wiO2ltcG9ydCB7IHJlc29sdmUgfSBmcm9tIFwicGF0aFwiO1xyXG5pbXBvcnQgeyBQbHVnaW5PcHRpb24gfSBmcm9tIFwidml0ZVwiO1xyXG5pbXBvcnQgeyBWaXRlUFdBIH0gZnJvbSBcInZpdGUtcGx1Z2luLXB3YVwiO1xyXG5pbXBvcnQgeyB2aXN1YWxpemVyIH0gZnJvbSBcInJvbGx1cC1wbHVnaW4tdmlzdWFsaXplclwiO1xyXG5pbXBvcnQgeyBjcmVhdGVIdG1sUGx1Z2luIH0gZnJvbSBcInZpdGUtcGx1Z2luLWh0bWxcIjtcclxuaW1wb3J0IHsgY3JlYXRlU3ZnSWNvbnNQbHVnaW4gfSBmcm9tIFwidml0ZS1wbHVnaW4tc3ZnLWljb25zXCI7XHJcbmltcG9ydCB2dWUgZnJvbSBcIkB2aXRlanMvcGx1Z2luLXZ1ZVwiO1xyXG5pbXBvcnQgdnVlSnN4IGZyb20gXCJAdml0ZWpzL3BsdWdpbi12dWUtanN4XCI7XHJcbmltcG9ydCBlc2xpbnRQbHVnaW4gZnJvbSBcInZpdGUtcGx1Z2luLWVzbGludFwiO1xyXG5pbXBvcnQgdml0ZUNvbXByZXNzaW9uIGZyb20gXCJ2aXRlLXBsdWdpbi1jb21wcmVzc2lvblwiO1xyXG5pbXBvcnQgdnVlU2V0dXBFeHRlbmQgZnJvbSBcInVucGx1Z2luLXZ1ZS1zZXR1cC1leHRlbmQtcGx1cy92aXRlXCI7XHJcbi8vIFx1ODFFQVx1NTJBOFx1NUJGQ1x1NTE2NXZ1ZVx1NEUyRGhvb2sgcmVhY3RpdmUgcmVmXHU3QjQ5XHJcbmltcG9ydCBBdXRvSW1wb3J0IGZyb20gXCJ1bnBsdWdpbi1hdXRvLWltcG9ydC92aXRlXCI7XHJcbi8vIFx1ODFFQVx1NTJBOFx1NUJGQ1x1NTE2NXVpLVx1N0VDNFx1NEVGNiBcdTZCRDRcdTU5ODJcdThCRjRhbnQtZGVzaWduLXZ1ZSAgZWxlbWVudC1wbHVzXHU3QjQ5XHJcbmltcG9ydCBDb21wb25lbnRzIGZyb20gXCJ1bnBsdWdpbi12dWUtY29tcG9uZW50cy92aXRlXCI7XHJcbi8vIGVsZW1lbnRcclxuaW1wb3J0IHsgRWxlbWVudFBsdXNSZXNvbHZlciB9IGZyb20gXCJ1bnBsdWdpbi12dWUtY29tcG9uZW50cy9yZXNvbHZlcnNcIjtcclxuLy8gXHU1QkZDXHU1MTY1XHU1NkZFXHU2ODA3XHJcbmltcG9ydCBJY29ucyBmcm9tIFwidW5wbHVnaW4taWNvbnMvdml0ZVwiO1xyXG5pbXBvcnQgSWNvbnNSZXNvbHZlciBmcm9tIFwidW5wbHVnaW4taWNvbnMvcmVzb2x2ZXJcIjtcclxuXHJcbi8qKlxyXG4gKiBcdTUyMUJcdTVFRkEgdml0ZSBcdTYzRDJcdTRFRjZcclxuICogQHBhcmFtIHZpdGVFbnZcclxuICovXHJcbmV4cG9ydCBjb25zdCBjcmVhdGVWaXRlUGx1Z2lucyA9ICh2aXRlRW52OiBWaXRlRW52KTogKFBsdWdpbk9wdGlvbiB8IFBsdWdpbk9wdGlvbltdKVtdID0+IHtcclxuICAgIGNvbnN0IHsgVklURV9HTE9CX0FQUF9USVRMRSwgVklURV9SRVBPUlQsIFZJVEVfUFdBIH0gPSB2aXRlRW52O1xyXG4gICAgcmV0dXJuIFtcclxuICAgICAgICB2dWUoKSxcclxuICAgICAgICAvLyB2dWUgXHU1M0VGXHU0RUU1XHU0RjdGXHU3NTI4IGpzeC90c3ggXHU4QkVEXHU2Q0Q1XHJcbiAgICAgICAgdnVlSnN4KCksXHJcbiAgICAgICAgLy8gZXNMaW50IFx1NjJBNVx1OTUxOVx1NEZFMVx1NjA2Rlx1NjYzRVx1NzkzQVx1NTcyOFx1NkQ0Rlx1ODlDOFx1NTY2OFx1NzU0Q1x1OTc2Mlx1NEUwQVxyXG4gICAgICAgIGVzbGludFBsdWdpbigpLFxyXG4gICAgICAgIC8vIG5hbWUgXHU1M0VGXHU0RUU1XHU1MTk5XHU1NzI4IHNjcmlwdCBcdTY4MDdcdTdCN0VcdTRFMEFcclxuICAgICAgICB2dWVTZXR1cEV4dGVuZCh7fSksXHJcbiAgICAgICAgLy8gXHU1MjFCXHU1RUZBXHU2MjUzXHU1MzA1XHU1MzhCXHU3RjI5XHU5MTREXHU3RjZFXHJcbiAgICAgICAgY3JlYXRlQ29tcHJlc3Npb24odml0ZUVudiksXHJcbiAgICAgICAgLy8gXHU2Q0U4XHU1MTY1XHU1M0Q4XHU5MUNGXHU1MjMwIGh0bWwgXHU2NTg3XHU0RUY2XHJcbiAgICAgICAgY3JlYXRlSHRtbFBsdWdpbih7XHJcbiAgICAgICAgICAgIGluamVjdDoge1xyXG4gICAgICAgICAgICAgICAgZGF0YTogeyB0aXRsZTogVklURV9HTE9CX0FQUF9USVRMRSB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9KSxcclxuICAgICAgICAvLyBcdTRGN0ZcdTc1Mjggc3ZnIFx1NTZGRVx1NjgwN1xyXG4gICAgICAgIGNyZWF0ZVN2Z0ljb25zUGx1Z2luKHtcclxuICAgICAgICAgICAgaWNvbkRpcnM6IFtyZXNvbHZlKHByb2Nlc3MuY3dkKCksIFwic3JjL2Fzc2V0cy9pY29uc1wiKV0sXHJcbiAgICAgICAgICAgIHN5bWJvbElkOiBcImljb24tW2Rpcl0tW25hbWVdXCJcclxuICAgICAgICB9KSxcclxuICAgICAgICAvLyBlbGVtZW50XHU2MzA5XHU5NzAwXHU1QkZDXHU1MTY1XHJcbiAgICAgICAgQXV0b0ltcG9ydCh7XHJcbiAgICAgICAgICAgIC8vIFx1NUI4OVx1ODhDNVx1NEUyNFx1ODg0Q1x1NTQwRVx1NEY2MFx1NEYxQVx1NTNEMVx1NzNCMFx1NTcyOFx1N0VDNFx1NEVGNlx1NEUyRFx1NEUwRFx1NzUyOFx1NTE4RFx1NUJGQ1x1NTE2NXJlZlx1RkYwQ3JlYWN0aXZlXHU3QjQ5XHJcbiAgICAgICAgICAgIGltcG9ydHM6IFtcInZ1ZVwiLCBcInZ1ZS1yb3V0ZXJcIl0sXHJcbiAgICAgICAgICAgIGR0czogXCJzcmMvYXV0by1pbXBvcnQuZC50c1wiLFxyXG4gICAgICAgICAgICAvLyBlbGVtZW50XHJcbiAgICAgICAgICAgIHJlc29sdmVyczogW1xyXG4gICAgICAgICAgICAgICAgRWxlbWVudFBsdXNSZXNvbHZlcih7IGltcG9ydFN0eWxlOiBcInNhc3NcIiB9KSxcclxuICAgICAgICAgICAgICAgIEljb25zUmVzb2x2ZXIoe1xyXG4gICAgICAgICAgICAgICAgICAgIHByZWZpeDogXCJJY29uXCJcclxuICAgICAgICAgICAgICAgIH0pXHJcbiAgICAgICAgICAgIF1cclxuICAgICAgICB9KSxcclxuICAgICAgICBDb21wb25lbnRzKHtcclxuICAgICAgICAgICAgLy8gZWxlbWVudFxyXG4gICAgICAgICAgICByZXNvbHZlcnM6IFtcclxuICAgICAgICAgICAgICAgIEVsZW1lbnRQbHVzUmVzb2x2ZXIoeyBpbXBvcnRTdHlsZTogXCJzYXNzXCIgfSksXHJcbiAgICAgICAgICAgICAgICBJY29uc1Jlc29sdmVyKHtcclxuICAgICAgICAgICAgICAgICAgICBlbmFibGVkQ29sbGVjdGlvbnM6IFtcImVwXCJdXHJcbiAgICAgICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICBdLFxyXG4gICAgICAgICAgICAvLyBcdTlFRDhcdThCQTRcdTVCNThcdTY1M0VcdTRGNERcdTdGNkVcclxuICAgICAgICAgICAgZHRzOiBcInNyYy9jb21wb25lbnRzLmQudHNcIlxyXG4gICAgICAgIH0pLFxyXG4gICAgICAgIEljb25zKHtcclxuICAgICAgICAgICAgYXV0b0luc3RhbGw6IHRydWVcclxuICAgICAgICB9KSxcclxuICAgICAgICAvLyB2aXRlUFdBXHJcbiAgICAgICAgVklURV9QV0EgJiYgY3JlYXRlVml0ZVB3YSh2aXRlRW52KSxcclxuICAgICAgICAvLyBcdTY2MkZcdTU0MjZcdTc1MUZcdTYyMTBcdTUzMDVcdTk4ODRcdTg5QzhcdUZGMENcdTUyMDZcdTY3OTBcdTRGOURcdThENTZcdTUzMDVcdTU5MjdcdTVDMEZcdTUwNUFcdTRGMThcdTUzMTZcdTU5MDRcdTc0MDZcclxuICAgICAgICBWSVRFX1JFUE9SVCAmJiAodmlzdWFsaXplcih7IGZpbGVuYW1lOiBcInN0YXRzLmh0bWxcIiwgZ3ppcFNpemU6IHRydWUsIGJyb3RsaVNpemU6IHRydWUgfSkgYXMgUGx1Z2luT3B0aW9uKVxyXG4gICAgXTtcclxufTtcclxuXHJcbi8qKlxyXG4gKiBAZGVzY3JpcHRpb24gXHU2ODM5XHU2MzZFIGNvbXByZXNzIFx1OTE0RFx1N0Y2RVx1RkYwQ1x1NzUxRlx1NjIxMFx1NEUwRFx1NTQwQ1x1NzY4NFx1NTM4Qlx1N0YyOVx1ODlDNFx1NTIxOVxyXG4gKiBAcGFyYW0gdml0ZUVudlxyXG4gKi9cclxuY29uc3QgY3JlYXRlQ29tcHJlc3Npb24gPSAodml0ZUVudjogVml0ZUVudik6IFBsdWdpbk9wdGlvbiB8IFBsdWdpbk9wdGlvbltdID0+IHtcclxuICAgIGNvbnN0IHsgVklURV9CVUlMRF9DT01QUkVTUyA9IFwibm9uZVwiLCBWSVRFX0JVSUxEX0NPTVBSRVNTX0RFTEVURV9PUklHSU5fRklMRSB9ID0gdml0ZUVudjtcclxuICAgIGNvbnN0IGNvbXByZXNzTGlzdCA9IFZJVEVfQlVJTERfQ09NUFJFU1Muc3BsaXQoXCIsXCIpO1xyXG4gICAgY29uc3QgcGx1Z2luczogUGx1Z2luT3B0aW9uW10gPSBbXTtcclxuICAgIGlmIChjb21wcmVzc0xpc3QuaW5jbHVkZXMoXCJnemlwXCIpKSB7XHJcbiAgICAgICAgcGx1Z2lucy5wdXNoKFxyXG4gICAgICAgICAgICB2aXRlQ29tcHJlc3Npb24oe1xyXG4gICAgICAgICAgICAgICAgZXh0OiBcIi5nelwiLFxyXG4gICAgICAgICAgICAgICAgYWxnb3JpdGhtOiBcImd6aXBcIixcclxuICAgICAgICAgICAgICAgIGRlbGV0ZU9yaWdpbkZpbGU6IFZJVEVfQlVJTERfQ09NUFJFU1NfREVMRVRFX09SSUdJTl9GSUxFXHJcbiAgICAgICAgICAgIH0pXHJcbiAgICAgICAgKTtcclxuICAgIH1cclxuICAgIGlmIChjb21wcmVzc0xpc3QuaW5jbHVkZXMoXCJicm90bGlcIikpIHtcclxuICAgICAgICBwbHVnaW5zLnB1c2goXHJcbiAgICAgICAgICAgIHZpdGVDb21wcmVzc2lvbih7XHJcbiAgICAgICAgICAgICAgICBleHQ6IFwiLmJyXCIsXHJcbiAgICAgICAgICAgICAgICBhbGdvcml0aG06IFwiYnJvdGxpQ29tcHJlc3NcIixcclxuICAgICAgICAgICAgICAgIGRlbGV0ZU9yaWdpbkZpbGU6IFZJVEVfQlVJTERfQ09NUFJFU1NfREVMRVRFX09SSUdJTl9GSUxFXHJcbiAgICAgICAgICAgIH0pXHJcbiAgICAgICAgKTtcclxuICAgIH1cclxuICAgIHJldHVybiBwbHVnaW5zO1xyXG59O1xyXG5cclxuLyoqXHJcbiAqIEBkZXNjcmlwdGlvbiBWaXRlUHdhXHJcbiAqIEBwYXJhbSB2aXRlRW52XHJcbiAqL1xyXG5jb25zdCBjcmVhdGVWaXRlUHdhID0gKHZpdGVFbnY6IFZpdGVFbnYpOiBQbHVnaW5PcHRpb24gfCBQbHVnaW5PcHRpb25bXSA9PiB7XHJcbiAgICBjb25zdCB7IFZJVEVfR0xPQl9BUFBfVElUTEUgfSA9IHZpdGVFbnY7XHJcbiAgICByZXR1cm4gVml0ZVBXQSh7XHJcbiAgICAgICAgcmVnaXN0ZXJUeXBlOiBcImF1dG9VcGRhdGVcIixcclxuICAgICAgICBtYW5pZmVzdDoge1xyXG4gICAgICAgICAgICBuYW1lOiBWSVRFX0dMT0JfQVBQX1RJVExFLFxyXG4gICAgICAgICAgICBzaG9ydF9uYW1lOiBWSVRFX0dMT0JfQVBQX1RJVExFLFxyXG4gICAgICAgICAgICB0aGVtZV9jb2xvcjogXCIjZmZmZmZmXCIsXHJcbiAgICAgICAgICAgIGljb25zOiBbXHJcbiAgICAgICAgICAgICAgICB7XHJcbiAgICAgICAgICAgICAgICAgICAgc3JjOiBcIi9sb2dvLnBuZ1wiLFxyXG4gICAgICAgICAgICAgICAgICAgIHNpemVzOiBcIjE5MngxOTJcIixcclxuICAgICAgICAgICAgICAgICAgICB0eXBlOiBcImltYWdlL3BuZ1wiXHJcbiAgICAgICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICAgICAge1xyXG4gICAgICAgICAgICAgICAgICAgIHNyYzogXCIvbG9nby5wbmdcIixcclxuICAgICAgICAgICAgICAgICAgICBzaXplczogXCI1MTJ4NTEyXCIsXHJcbiAgICAgICAgICAgICAgICAgICAgdHlwZTogXCJpbWFnZS9wbmdcIlxyXG4gICAgICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgICAgIHtcclxuICAgICAgICAgICAgICAgICAgICBzcmM6IFwiL2xvZ28ucG5nXCIsXHJcbiAgICAgICAgICAgICAgICAgICAgc2l6ZXM6IFwiNTEyeDUxMlwiLFxyXG4gICAgICAgICAgICAgICAgICAgIHR5cGU6IFwiaW1hZ2UvcG5nXCIsXHJcbiAgICAgICAgICAgICAgICAgICAgcHVycG9zZTogXCJhbnkgbWFza2FibGVcIlxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBdXHJcbiAgICAgICAgfVxyXG4gICAgfSk7XHJcbn07XHJcbiIsICJ7XHJcbiAgICBcIm5hbWVcIjogXCJ5Y19vcHNfYWRtaW5fdHNcIixcclxuICAgIFwicHJpdmF0ZVwiOiB0cnVlLFxyXG4gICAgXCJ2ZXJzaW9uXCI6IFwiMS4wLjBcIixcclxuICAgIFwidHlwZVwiOiBcIm1vZHVsZVwiLFxyXG4gICAgXCJzY3JpcHRzXCI6IHtcclxuICAgICAgICBcImRldlwiOiBcInZpdGVcIixcclxuICAgICAgICBcInNlcnZlXCI6IFwidml0ZVwiLFxyXG4gICAgICAgIFwiYnVpbGQ6ZGV2XCI6IFwidnVlLXRzYyAmJiB2aXRlIGJ1aWxkIC0tbW9kZSBkZXZlbG9wbWVudFwiLFxyXG4gICAgICAgIFwiYnVpbGQ6dGVzdFwiOiBcInZ1ZS10c2MgJiYgdml0ZSBidWlsZCAtLW1vZGUgdGVzdFwiLFxyXG4gICAgICAgIFwiYnVpbGQ6cHJvXCI6IFwidnVlLXRzYyAmJiB2aXRlIGJ1aWxkIC0tbW9kZSBwcm9kdWN0aW9uXCIsXHJcbiAgICAgICAgXCJ0eXBlOmNoZWNrXCI6IFwidnVlLXRzYyAtLW5vRW1pdCAtLXNraXBMaWJDaGVja1wiLFxyXG4gICAgICAgIFwicHJldmlld1wiOiBcIm5wbSBydW4gYnVpbGQ6ZGV2ICYmIHZpdGUgcHJldmlld1wiLFxyXG4gICAgICAgIFwibGludDplc2xpbnRcIjogXCJlc2xpbnQgLS1maXggLS1leHQgLmpzLC50cywudnVlIC4vc3JjXCIsXHJcbiAgICAgICAgXCJsaW50OnByZXR0aWVyXCI6IFwicHJldHRpZXIgLS13cml0ZSBcXFwic3JjLyoqLyoue2pzLHRzLGpzb24sdHN4LGNzcyxsZXNzLHNjc3MsdnVlLGh0bWwsbWR9XFxcIlwiLFxyXG4gICAgICAgIFwibGludDpzdHlsZWxpbnRcIjogXCJzdHlsZWxpbnQgLS1jYWNoZSAtLWZpeCBcXFwiKiovKi57dnVlLGxlc3MscG9zdGNzcyxjc3Msc2Nzc31cXFwiIC0tY2FjaGUgLS1jYWNoZS1sb2NhdGlvbiBub2RlX21vZHVsZXMvLmNhY2hlL3N0eWxlbGludC9cIixcclxuICAgICAgICBcImxpbnQ6bGludC1zdGFnZWRcIjogXCJsaW50LXN0YWdlZFwiLFxyXG4gICAgICAgIFwicHJlcGFyZVwiOiBcImh1c2t5IGluc3RhbGxcIixcclxuICAgICAgICBcInJlbGVhc2VcIjogXCJzdGFuZGFyZC12ZXJzaW9uXCIsXHJcbiAgICAgICAgXCJjb21taXRcIjogXCJnaXQgYWRkIC1BICYmIGN6ZyAmJiBnaXQgcHVzaFwiXHJcbiAgICB9LFxyXG4gICAgXCJkZXBlbmRlbmNpZXNcIjoge1xyXG4gICAgICAgIFwiQGVsZW1lbnQtcGx1cy9pY29ucy12dWVcIjogXCJeMi4xLjBcIixcclxuICAgICAgICBcIkB0eXBlcy9kZWNpbWFsLmpzXCI6IFwiXjcuNC4wXCIsXHJcbiAgICAgICAgXCJAdnVldXAvdnVlLXF1aWxsXCI6IFwiXjEuMi4wXCIsXHJcbiAgICAgICAgXCJAdnVldXNlL2NvcmVcIjogXCJeMTAuMS4yXCIsXHJcbiAgICAgICAgXCJAd2FuZ2VkaXRvci9lZGl0b3JcIjogXCJeNS4xLjIzXCIsXHJcbiAgICAgICAgXCJAd2FuZ2VkaXRvci9lZGl0b3ItZm9yLXZ1ZVwiOiBcIl41LjEuMTJcIixcclxuICAgICAgICBcIkB6aGotdGFyZ2V0L3Z1ZTMta2luZC1lZGl0b3JcIjogXCJeMC4xLjNcIixcclxuICAgICAgICBcImFzeW5jLXZhbGlkYXRvclwiOiBcIl40LjIuNVwiLFxyXG4gICAgICAgIFwiYXhpb3NcIjogXCJeMS40LjBcIixcclxuICAgICAgICBcImJ3aXAtanNcIjogXCJeNC4zLjJcIixcclxuICAgICAgICBcImNyeXB0by1qc1wiOiBcIl40LjIuMFwiLFxyXG4gICAgICAgIFwiZGF5anNcIjogXCJeMS4xMS45XCIsXHJcbiAgICAgICAgXCJkZWNpbWFsXCI6IFwiXjAuMC4yXCIsXHJcbiAgICAgICAgXCJkZWZhdWx0LXBhc3NpdmUtZXZlbnRzXCI6IFwiXjIuMC4wXCIsXHJcbiAgICAgICAgXCJkcml2ZXIuanNcIjogXCJeMC45LjhcIixcclxuICAgICAgICBcImVsZW1lbnQtcGx1c1wiOiBcIl4yLjMuNFwiLFxyXG4gICAgICAgIFwiZmlsZS1zYXZlclwiOiBcIl4yLjAuNVwiLFxyXG4gICAgICAgIFwianMtbWQ1XCI6IFwiXjAuNy4zXCIsXHJcbiAgICAgICAgXCJqc2JhcmNvZGVcIjogXCJeMy4xMS42XCIsXHJcbiAgICAgICAgXCJqc29ucGFja1wiOiBcIl4xLjEuNVwiLFxyXG4gICAgICAgIFwibG9kYXNoLWVzXCI6IFwiXjQuMTcuMjFcIixcclxuICAgICAgICBcIm1hdm9uLWVkaXRvclwiOiBcIl4zLjAuMlwiLFxyXG4gICAgICAgIFwibWl0dFwiOiBcIl4zLjAuMFwiLFxyXG4gICAgICAgIFwibnByb2dyZXNzXCI6IFwiXjAuMi4wXCIsXHJcbiAgICAgICAgXCJwaW5pYVwiOiBcIl4yLjEuM1wiLFxyXG4gICAgICAgIFwicGluaWEtcGx1Z2luLXBlcnNpc3RlZHN0YXRlXCI6IFwiXjMuMS4wXCIsXHJcbiAgICAgICAgXCJwcmludC1qc1wiOiBcIl4xLjYuMFwiLFxyXG4gICAgICAgIFwicXNcIjogXCJeNi4xMy4xXCIsXHJcbiAgICAgICAgXCJxdWlsbFwiOiBcIl4yLjAuM1wiLFxyXG4gICAgICAgIFwic29ydGFibGVqc1wiOiBcIl4xLjE1LjBcIixcclxuICAgICAgICBcInZ1ZVwiOiBcIl4zLjMuNFwiLFxyXG4gICAgICAgIFwidnVlLXJvdXRlclwiOiBcIl40LjIuMlwiLFxyXG4gICAgICAgIFwidnVlZHJhZ2dhYmxlXCI6IFwiXjQuMS4wXCIsXHJcbiAgICAgICAgXCJ2eGUtdGFibGVcIjogXCJeNC41LjAtYmV0YS4xMFwiLFxyXG4gICAgICAgIFwieGUtdXRpbHNcIjogXCJeMy41LjExXCIsXHJcbiAgICAgICAgXCJ4bHN4XCI6IFwiXjAuMTguNVwiXHJcbiAgICB9LFxyXG4gICAgXCJkZXZEZXBlbmRlbmNpZXNcIjoge1xyXG4gICAgICAgIFwiQGNvbW1pdGxpbnQvY2xpXCI6IFwiXjE3LjYuM1wiLFxyXG4gICAgICAgIFwiQGNvbW1pdGxpbnQvY29uZmlnLWNvbnZlbnRpb25hbFwiOiBcIl4xNy42LjNcIixcclxuICAgICAgICBcIkBpY29uaWZ5LWpzb24vZXBcIjogXCJeMS4xLjEwXCIsXHJcbiAgICAgICAgXCJAdHlwZXMvY3J5cHRvLWpzXCI6IFwiXjQuMi4yXCIsXHJcbiAgICAgICAgXCJAdHlwZXMvZmlsZS1zYXZlclwiOiBcIl4yLjAuNVwiLFxyXG4gICAgICAgIFwiQHR5cGVzL2pzLW1kNVwiOiBcIl4wLjcuMFwiLFxyXG4gICAgICAgIFwiQHR5cGVzL25wcm9ncmVzc1wiOiBcIl4wLjIuMFwiLFxyXG4gICAgICAgIFwiQHR5cGVzL3FzXCI6IFwiXjYuOS43XCIsXHJcbiAgICAgICAgXCJAdHlwZXMvc29ydGFibGVqc1wiOiBcIl4xLjE1LjFcIixcclxuICAgICAgICBcIkB0eXBlc2NyaXB0LWVzbGludC9lc2xpbnQtcGx1Z2luXCI6IFwiXjUuNTkuN1wiLFxyXG4gICAgICAgIFwiQHR5cGVzY3JpcHQtZXNsaW50L3BhcnNlclwiOiBcIl41LjU5LjdcIixcclxuICAgICAgICBcIkB2aXRlanMvcGx1Z2luLXZ1ZVwiOiBcIl40LjIuM1wiLFxyXG4gICAgICAgIFwiQHZpdGVqcy9wbHVnaW4tdnVlLWpzeFwiOiBcIl4zLjAuMVwiLFxyXG4gICAgICAgIFwiYXV0b3ByZWZpeGVyXCI6IFwiXjEwLjQuMTRcIixcclxuICAgICAgICBcImN6LWdpdFwiOiBcIl4xLjYuMVwiLFxyXG4gICAgICAgIFwiY3pnXCI6IFwiXjEuNi4xXCIsXHJcbiAgICAgICAgXCJlc2xpbnRcIjogXCJeOC40MS4wXCIsXHJcbiAgICAgICAgXCJlc2xpbnQtY29uZmlnLXByZXR0aWVyXCI6IFwiXjguOC4wXCIsXHJcbiAgICAgICAgXCJlc2xpbnQtcGx1Z2luLXByZXR0aWVyXCI6IFwiXjQuMi4xXCIsXHJcbiAgICAgICAgXCJlc2xpbnQtcGx1Z2luLXZ1ZVwiOiBcIl45LjE0LjBcIixcclxuICAgICAgICBcImh1c2t5XCI6IFwiXjguMC4zXCIsXHJcbiAgICAgICAgXCJsaW50LXN0YWdlZFwiOiBcIl4xMy4yLjJcIixcclxuICAgICAgICBcInBvc3Rjc3NcIjogXCJeOC40LjIzXCIsXHJcbiAgICAgICAgXCJwb3N0Y3NzLWh0bWxcIjogXCJeMS41LjBcIixcclxuICAgICAgICBcInByZXR0aWVyXCI6IFwiXjIuOC44XCIsXHJcbiAgICAgICAgXCJxcmNvZGVcIjogXCJeMS41LjNcIixcclxuICAgICAgICBcInJvbGx1cC1wbHVnaW4tdmlzdWFsaXplclwiOiBcIl41LjkuMFwiLFxyXG4gICAgICAgIFwic2Fzc1wiOiBcIl4xLjYyLjFcIixcclxuICAgICAgICBcInN0YW5kYXJkLXZlcnNpb25cIjogXCJeOS41LjBcIixcclxuICAgICAgICBcInN0eWxlbGludFwiOiBcIl4xNS42LjJcIixcclxuICAgICAgICBcInN0eWxlbGludC1jb25maWctaHRtbFwiOiBcIl4xLjEuMFwiLFxyXG4gICAgICAgIFwic3R5bGVsaW50LWNvbmZpZy1yZWNlc3Mtb3JkZXJcIjogXCJeNC4wLjBcIixcclxuICAgICAgICBcInN0eWxlbGludC1jb25maWctcmVjb21tZW5kZWQtc2Nzc1wiOiBcIl4xMi4wLjBcIixcclxuICAgICAgICBcInN0eWxlbGludC1jb25maWctcmVjb21tZW5kZWQtdnVlXCI6IFwiXjEuNC4wXCIsXHJcbiAgICAgICAgXCJzdHlsZWxpbnQtY29uZmlnLXN0YW5kYXJkXCI6IFwiXjMzLjAuMFwiLFxyXG4gICAgICAgIFwic3R5bGVsaW50LWNvbmZpZy1zdGFuZGFyZC1zY3NzXCI6IFwiXjkuMC4wXCIsXHJcbiAgICAgICAgXCJ0eXBlc2NyaXB0XCI6IFwiXjUuMC4yXCIsXHJcbiAgICAgICAgXCJ1bnBsdWdpbi1hdXRvLWltcG9ydFwiOiBcIl4wLjE2LjRcIixcclxuICAgICAgICBcInVucGx1Z2luLWljb25zXCI6IFwiXjAuMTYuM1wiLFxyXG4gICAgICAgIFwidW5wbHVnaW4tdnVlLWNvbXBvbmVudHNcIjogXCJeMC4yNS4xXCIsXHJcbiAgICAgICAgXCJ1bnBsdWdpbi12dWUtc2V0dXAtZXh0ZW5kLXBsdXNcIjogXCJeMS4wLjBcIixcclxuICAgICAgICBcInZpdGVcIjogXCJeNC4zLjlcIixcclxuICAgICAgICBcInZpdGUtcGx1Z2luLWNvbXByZXNzaW9uXCI6IFwiXjAuNS4xXCIsXHJcbiAgICAgICAgXCJ2aXRlLXBsdWdpbi1lc2xpbnRcIjogXCJeMS44LjFcIixcclxuICAgICAgICBcInZpdGUtcGx1Z2luLWh0bWxcIjogXCJeMy4yLjBcIixcclxuICAgICAgICBcInZpdGUtcGx1Z2luLXB3YVwiOiBcIl4wLjE1LjBcIixcclxuICAgICAgICBcInZpdGUtcGx1Z2luLXN2Zy1pY29uc1wiOiBcIl4yLjAuMVwiLFxyXG4gICAgICAgIFwidnVlLXRzY1wiOiBcIl4xLjYuNVwiXHJcbiAgICB9LFxyXG4gICAgXCJlbmdpbmVzXCI6IHtcclxuICAgICAgICBcIm5vZGVcIjogXCI+PTE2LjAuMFwiXHJcbiAgICB9LFxyXG4gICAgXCJicm93c2Vyc2xpc3RcIjoge1xyXG4gICAgICAgIFwicHJvZHVjdGlvblwiOiBbXHJcbiAgICAgICAgICAgIFwiPiAxJVwiLFxyXG4gICAgICAgICAgICBcIm5vdCBkZWFkXCIsXHJcbiAgICAgICAgICAgIFwibm90IG9wX21pbmkgYWxsXCJcclxuICAgICAgICBdLFxyXG4gICAgICAgIFwiZGV2ZWxvcG1lbnRcIjogW1xyXG4gICAgICAgICAgICBcImxhc3QgMSBjaHJvbWUgdmVyc2lvblwiLFxyXG4gICAgICAgICAgICBcImxhc3QgMSBmaXJlZm94IHZlcnNpb25cIixcclxuICAgICAgICAgICAgXCJsYXN0IDEgc2FmYXJpIHZlcnNpb25cIlxyXG4gICAgICAgIF1cclxuICAgIH0sXHJcbiAgICBcImNvbmZpZ1wiOiB7XHJcbiAgICAgICAgXCJjb21taXRpemVuXCI6IHtcclxuICAgICAgICAgICAgXCJwYXRoXCI6IFwibm9kZV9tb2R1bGVzL2N6LWdpdFwiXHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG59XHJcbiJdLAogICJtYXBwaW5ncyI6ICI7QUFBaVgsU0FBUyxjQUFjLGVBQXNDO0FBQzlhLFNBQVMsV0FBQUEsZ0JBQWU7OztBQ3FCakIsU0FBUyxXQUFXLFNBQThCO0FBQ3JELFFBQU0sTUFBVyxDQUFDO0FBRWxCLGFBQVcsV0FBVyxPQUFPLEtBQUssT0FBTyxHQUFHO0FBQ3hDLFFBQUksV0FBVyxRQUFRLE9BQU8sRUFBRSxRQUFRLFFBQVEsSUFBSTtBQUNwRCxlQUFXLGFBQWEsU0FBUyxPQUFPLGFBQWEsVUFBVSxRQUFRO0FBQ3ZFLFFBQUksWUFBWTtBQUFhLGlCQUFXLE9BQU8sUUFBUTtBQUN2RCxRQUFJLFlBQVksY0FBYztBQUMxQixVQUFJO0FBQ0EsbUJBQVcsS0FBSyxNQUFNLFFBQVE7QUFBQSxNQUNsQyxTQUFTLE9BQVA7QUFBQSxNQUFlO0FBQUEsSUFDckI7QUFDQSxRQUFJLE9BQU8sSUFBSTtBQUFBLEVBQ25CO0FBQ0EsU0FBTztBQUNYOzs7QUN6Qk8sU0FBUyxZQUFZLE9BQWtCLENBQUMsR0FBRztBQUM5QyxRQUFNLE1BQXVCLENBQUM7QUFDOUIsYUFBVyxDQUFDLFFBQVEsTUFBTSxLQUFLLE1BQU07QUFDakMsVUFBTSxVQUFVO0FBQ2hCLFVBQU0sVUFBVSxR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