|
|
|
@@ -1,5 +1,5 @@
|
|
|
|
<script setup lang="ts">
|
|
|
|
<script setup lang="ts">
|
|
|
|
import { ref, computed } from "vue";
|
|
|
|
import {ref, computed} from "vue";
|
|
|
|
import TreeEntry from "./TreeEntry.vue";
|
|
|
|
import TreeEntry from "./TreeEntry.vue";
|
|
|
|
|
|
|
|
|
|
|
|
interface DirEntry {
|
|
|
|
interface DirEntry {
|
|
|
|
@@ -10,16 +10,16 @@ interface DirEntry {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const props = withDefaults(
|
|
|
|
const props = withDefaults(
|
|
|
|
defineProps<{
|
|
|
|
defineProps<{
|
|
|
|
folderPath: string;
|
|
|
|
folderPath: string;
|
|
|
|
entries: DirEntry[];
|
|
|
|
entries: DirEntry[];
|
|
|
|
content?: string;
|
|
|
|
content?: string;
|
|
|
|
currentFilePath?: string | null;
|
|
|
|
currentFilePath?: string | null;
|
|
|
|
}>(),
|
|
|
|
}>(),
|
|
|
|
{
|
|
|
|
{
|
|
|
|
content: "",
|
|
|
|
content: "",
|
|
|
|
currentFilePath: null,
|
|
|
|
currentFilePath: null,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
);
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
const emit = defineEmits<{
|
|
|
|
const emit = defineEmits<{
|
|
|
|
@@ -27,34 +27,36 @@ const emit = defineEmits<{
|
|
|
|
openFolder: [];
|
|
|
|
openFolder: [];
|
|
|
|
toggleFolder: [path: string];
|
|
|
|
toggleFolder: [path: string];
|
|
|
|
openFile: [path: string];
|
|
|
|
openFile: [path: string];
|
|
|
|
|
|
|
|
createFile: [];
|
|
|
|
|
|
|
|
createFolder: [];
|
|
|
|
}>();
|
|
|
|
}>();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Wrap the workspace root as a top-level tree node
|
|
|
|
|
|
|
|
const rootEntry = computed<DirEntry | null>(() => {
|
|
|
|
|
|
|
|
if (!props.folderPath) return null;
|
|
|
|
|
|
|
|
const name = props.folderPath.split(/[/\\]/).pop() || props.folderPath;
|
|
|
|
|
|
|
|
return {
|
|
|
|
|
|
|
|
name,
|
|
|
|
|
|
|
|
path: props.folderPath,
|
|
|
|
|
|
|
|
is_dir: true,
|
|
|
|
|
|
|
|
children: props.entries,
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
// ---- sidebar view mode ----
|
|
|
|
// ---- sidebar view mode ----
|
|
|
|
type ViewMode = "folder" | "search" | "outline";
|
|
|
|
type ViewMode = "folder" | "search" | "outline";
|
|
|
|
const activeView = ref<ViewMode>("folder");
|
|
|
|
const activeView = ref<ViewMode>("folder");
|
|
|
|
const collapsed = ref(true);
|
|
|
|
const expanded = ref(true);
|
|
|
|
|
|
|
|
|
|
|
|
const viewLabels: Record<ViewMode, string> = {
|
|
|
|
|
|
|
|
folder: "文件",
|
|
|
|
|
|
|
|
search: "搜索",
|
|
|
|
|
|
|
|
outline: "大纲",
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function switchView(view: ViewMode) {
|
|
|
|
function switchView(view: ViewMode) {
|
|
|
|
if (collapsed.value) {
|
|
|
|
if (activeView.value === view) {
|
|
|
|
collapsed.value = false;
|
|
|
|
expanded.value = !expanded.value;
|
|
|
|
activeView.value = view;
|
|
|
|
|
|
|
|
} else if (activeView.value === view) {
|
|
|
|
|
|
|
|
collapsed.value = true;
|
|
|
|
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
activeView.value = view;
|
|
|
|
activeView.value = view;
|
|
|
|
|
|
|
|
expanded.value = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function collapseSidebar() {
|
|
|
|
|
|
|
|
collapsed.value = true;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// ---- outline state ----
|
|
|
|
// ---- outline state ----
|
|
|
|
interface OutlineItem {
|
|
|
|
interface OutlineItem {
|
|
|
|
text: string;
|
|
|
|
text: string;
|
|
|
|
@@ -72,14 +74,14 @@ const headings = computed<OutlineItem[]>(() => {
|
|
|
|
// Strip any remaining markdown formatting from the heading text
|
|
|
|
// Strip any remaining markdown formatting from the heading text
|
|
|
|
const text = match[2].replace(/\*{1,3}|_{1,3}|`+|~~|\[([^\]]*)\]\([^)]*\)/g, (_, linkText) => linkText || "").trim();
|
|
|
|
const text = match[2].replace(/\*{1,3}|_{1,3}|`+|~~|\[([^\]]*)\]\([^)]*\)/g, (_, linkText) => linkText || "").trim();
|
|
|
|
if (text) {
|
|
|
|
if (text) {
|
|
|
|
result.push({ text, level, id: `heading-${result.length}` });
|
|
|
|
result.push({text, level, id: `heading-${result.length}`});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
return result;
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
function onHeadingClick(item: OutlineItem) {
|
|
|
|
function onHeadingClick(item: OutlineItem) {
|
|
|
|
emit("headingClick", { text: item.text, level: item.level });
|
|
|
|
emit("headingClick", {text: item.text, level: item.level});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// ---- settings modal ----
|
|
|
|
// ---- settings modal ----
|
|
|
|
@@ -88,96 +90,77 @@ const showSettings = ref(false);
|
|
|
|
|
|
|
|
|
|
|
|
<template>
|
|
|
|
<template>
|
|
|
|
<aside
|
|
|
|
<aside
|
|
|
|
:class="[
|
|
|
|
:class="['flex flex-row border-r border-[#e8e4da] bg-[#f4f1eb]/80 transition-all duration-300 ease-in-out overflow-hidden shrink-0', expanded ? 'w-72' : 'w-12']"
|
|
|
|
'flex flex-col border-r border-[#e8e4da] bg-[#f4f1eb]/80 transition-all duration-300 ease-in-out overflow-hidden shrink-0',
|
|
|
|
|
|
|
|
collapsed ? 'w-12' : 'w-56',
|
|
|
|
|
|
|
|
]"
|
|
|
|
|
|
|
|
>
|
|
|
|
>
|
|
|
|
<!-- ============ COLLAPSED: icon bar ============ -->
|
|
|
|
<!-- ============ Icon bar ============ -->
|
|
|
|
<template v-if="collapsed">
|
|
|
|
<div class="w-12 shrink-0 flex flex-col items-center gap-1 py-3">
|
|
|
|
<div class="flex flex-col items-center gap-1 py-3 flex-1">
|
|
|
|
<!-- Folder -->
|
|
|
|
<!-- Folder -->
|
|
|
|
<button
|
|
|
|
<button
|
|
|
|
|
|
|
|
class="p-2 rounded-md transition-colors"
|
|
|
|
class="p-2 rounded-md transition-colors"
|
|
|
|
:class="activeView === 'folder' ? 'text-[#bf6a3b] bg-[#ede8de]' : 'text-[#b8b3a8] hover:text-[#5c574e] hover:bg-[#ede8de]'"
|
|
|
|
:class="activeView === 'folder' ? 'text-[#bf6a3b] bg-[#ede8de]' : 'text-[#b8b3a8] hover:text-[#5c574e] hover:bg-[#ede8de]'"
|
|
|
|
title="文件"
|
|
|
|
title="文件"
|
|
|
|
@click="switchView('folder')"
|
|
|
|
@click="switchView('folder')"
|
|
|
|
>
|
|
|
|
>
|
|
|
|
<i class="ri-folder-line text-base"></i>
|
|
|
|
<i class="ri-folder-line text-base"></i>
|
|
|
|
</button>
|
|
|
|
</button>
|
|
|
|
<!-- Search -->
|
|
|
|
<!-- Search -->
|
|
|
|
<button
|
|
|
|
<button
|
|
|
|
class="p-2 rounded-md transition-colors"
|
|
|
|
class="p-2 rounded-md transition-colors"
|
|
|
|
:class="activeView === 'search' ? 'text-[#bf6a3b] bg-[#ede8de]' : 'text-[#b8b3a8] hover:text-[#5c574e] hover:bg-[#ede8de]'"
|
|
|
|
:class="activeView === 'search' ? 'text-[#bf6a3b] bg-[#ede8de]' : 'text-[#b8b3a8] hover:text-[#5c574e] hover:bg-[#ede8de]'"
|
|
|
|
title="搜索"
|
|
|
|
title="搜索"
|
|
|
|
@click="switchView('search')"
|
|
|
|
@click="switchView('search')"
|
|
|
|
>
|
|
|
|
>
|
|
|
|
<i class="ri-search-line text-base"></i>
|
|
|
|
<i class="ri-search-line text-base"></i>
|
|
|
|
</button>
|
|
|
|
</button>
|
|
|
|
<!-- Outline -->
|
|
|
|
<!-- Outline -->
|
|
|
|
<button
|
|
|
|
<button
|
|
|
|
class="p-2 rounded-md transition-colors"
|
|
|
|
class="p-2 rounded-md transition-colors"
|
|
|
|
:class="activeView === 'outline' ? 'text-[#bf6a3b] bg-[#ede8de]' : 'text-[#b8b3a8] hover:text-[#5c574e] hover:bg-[#ede8de]'"
|
|
|
|
:class="activeView === 'outline' ? 'text-[#bf6a3b] bg-[#ede8de]' : 'text-[#b8b3a8] hover:text-[#5c574e] hover:bg-[#ede8de]'"
|
|
|
|
title="大纲"
|
|
|
|
title="大纲"
|
|
|
|
@click="switchView('outline')"
|
|
|
|
@click="switchView('outline')"
|
|
|
|
>
|
|
|
|
>
|
|
|
|
<i class="ri-menu-line text-base"></i>
|
|
|
|
<i class="ri-menu-line text-base"></i>
|
|
|
|
</button>
|
|
|
|
</button>
|
|
|
|
</div>
|
|
|
|
<!-- ===== Settings ===== -->
|
|
|
|
</template>
|
|
|
|
<button
|
|
|
|
|
|
|
|
class="p-2 rounded-md transition-colors mt-auto"
|
|
|
|
<!-- ============ EXPANDED: full sidebar ============ -->
|
|
|
|
:class="activeView === 'outline' ? 'text-[#bf6a3b] bg-[#ede8de]' : 'text-[#b8b3a8] hover:text-[#5c574e] hover:bg-[#ede8de]'"
|
|
|
|
<template v-else>
|
|
|
|
title="设置"
|
|
|
|
<!-- Header -->
|
|
|
|
@click="showSettings = true"
|
|
|
|
<div class="flex items-center justify-between px-3 py-3 border-b border-[#e8e4da]">
|
|
|
|
>
|
|
|
|
<span class="text-xs font-semibold text-[#8c877d] uppercase tracking-wider">
|
|
|
|
<i class="ri-settings-line text-sm"></i>
|
|
|
|
{{ viewLabels[activeView] }}
|
|
|
|
</button>
|
|
|
|
</span>
|
|
|
|
</div>
|
|
|
|
<button
|
|
|
|
|
|
|
|
class="p-1 rounded-md text-[#8c877d] hover:text-[#38342e] hover:bg-[#e0dbcf] transition-colors"
|
|
|
|
|
|
|
|
title="折叠侧边栏"
|
|
|
|
|
|
|
|
@click="collapseSidebar"
|
|
|
|
|
|
|
|
>
|
|
|
|
|
|
|
|
<i class="ri-arrow-left-double-line text-base"></i>
|
|
|
|
|
|
|
|
</button>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<!-- ============ Expanded panel ============ -->
|
|
|
|
|
|
|
|
<div v-show="expanded" class="flex-1 flex flex-col overflow-hidden border-l border-[#e8e4da]">
|
|
|
|
<!-- ===== FOLDER VIEW ===== -->
|
|
|
|
<!-- ===== FOLDER VIEW ===== -->
|
|
|
|
<div v-if="activeView === 'folder'" class="flex flex-col flex-1 overflow-hidden">
|
|
|
|
<div v-if="activeView === 'folder'" class="flex flex-col flex-1 overflow-hidden">
|
|
|
|
<!-- File tree -->
|
|
|
|
<!-- File tree -->
|
|
|
|
<div class="flex-1 overflow-y-auto px-2 py-2 space-y-0.5">
|
|
|
|
<div class="flex-1 overflow-y-auto px-2 py-2 space-y-0.5">
|
|
|
|
<!-- Folder path indicator -->
|
|
|
|
<!-- Workspace root as top-level tree node -->
|
|
|
|
<div
|
|
|
|
<TreeEntry
|
|
|
|
v-if="folderPath"
|
|
|
|
v-if="rootEntry"
|
|
|
|
class="px-2 py-1 text-xs text-[#b8b3a8] truncate mb-2 border-b border-[#e8e4da] pb-2"
|
|
|
|
:entry="rootEntry"
|
|
|
|
:title="folderPath"
|
|
|
|
:depth="0"
|
|
|
|
>
|
|
|
|
@toggle-folder="(path: string) => emit('toggleFolder', path)"
|
|
|
|
📁 {{ folderPath.split(/[/\\]/).pop() || folderPath }}
|
|
|
|
@open-file="(path: string) => emit('openFile', path)"
|
|
|
|
</div>
|
|
|
|
/>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- Empty state -->
|
|
|
|
<!-- Empty state -->
|
|
|
|
<div
|
|
|
|
<div
|
|
|
|
v-if="!folderPath"
|
|
|
|
v-if="!folderPath"
|
|
|
|
class="px-2 py-4 text-xs text-[#b8b3a8] text-center"
|
|
|
|
class="px-2 py-4 text-xs text-[#b8b3a8] text-center"
|
|
|
|
>
|
|
|
|
>
|
|
|
|
<p class="mb-3">暂无打开的文件夹</p>
|
|
|
|
<p class="mb-3">暂无打开的文件夹</p>
|
|
|
|
<button
|
|
|
|
<button
|
|
|
|
class="inline-flex items-center gap-1.5 px-3 py-1.5 text-xs rounded-md bg-[#fdf0e5] text-[#bf6a3b] border border-[#d4a574]/40 hover:bg-[#fdf0e5]/80 hover:text-[#bf6a3b] transition-colors"
|
|
|
|
class="inline-flex items-center gap-1.5 px-3 py-1.5 text-xs rounded-md bg-[#fdf0e5] text-[#bf6a3b] border border-[#d4a574]/40 hover:bg-[#fdf0e5]/80 hover:text-[#bf6a3b] transition-colors"
|
|
|
|
@click="$emit('openFolder')"
|
|
|
|
@click="$emit('openFolder')"
|
|
|
|
>
|
|
|
|
>
|
|
|
|
<i class="ri-folder-open-line"></i>
|
|
|
|
<i class="ri-folder-open-line"></i>
|
|
|
|
打开文件夹
|
|
|
|
打开文件夹
|
|
|
|
</button>
|
|
|
|
</button>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<TreeEntry
|
|
|
|
|
|
|
|
v-for="entry in entries"
|
|
|
|
|
|
|
|
:key="entry.path"
|
|
|
|
|
|
|
|
:entry="entry"
|
|
|
|
|
|
|
|
:depth="0"
|
|
|
|
|
|
|
|
@toggle-folder="(path: string) => emit('toggleFolder', path)"
|
|
|
|
|
|
|
|
@open-file="(path: string) => emit('openFile', path)"
|
|
|
|
|
|
|
|
/>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
@@ -187,9 +170,9 @@ const showSettings = ref(false);
|
|
|
|
<div class="relative">
|
|
|
|
<div class="relative">
|
|
|
|
<i class="ri-search-line absolute left-2.5 top-1/2 -translate-y-1/2 text-sm text-[#b8b3a8]"></i>
|
|
|
|
<i class="ri-search-line absolute left-2.5 top-1/2 -translate-y-1/2 text-sm text-[#b8b3a8]"></i>
|
|
|
|
<input
|
|
|
|
<input
|
|
|
|
class="w-full pl-8 pr-3 py-1.5 text-xs bg-[#ede8de] border border-[#e0dbcf] rounded-md text-[#38342e] outline-none focus:border-[#bf6a3b] placeholder-[#b8b3a8]"
|
|
|
|
class="w-full pl-8 pr-3 py-1.5 text-xs bg-[#ede8de] border border-[#e0dbcf] rounded-md text-[#38342e] outline-none focus:border-[#bf6a3b] placeholder-[#b8b3a8]"
|
|
|
|
placeholder="搜索文件内容..."
|
|
|
|
placeholder="搜索文件内容..."
|
|
|
|
disabled
|
|
|
|
disabled
|
|
|
|
/>
|
|
|
|
/>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
@@ -209,14 +192,14 @@ const showSettings = ref(false);
|
|
|
|
</template>
|
|
|
|
</template>
|
|
|
|
<template v-else-if="headings.length === 0">
|
|
|
|
<template v-else-if="headings.length === 0">
|
|
|
|
<p class="text-xs text-[#b8b3a8] px-2 py-4 text-center leading-relaxed">
|
|
|
|
<p class="text-xs text-[#b8b3a8] px-2 py-4 text-center leading-relaxed">
|
|
|
|
暂无标题<br />使用 H1-H3 标题<br />自动生成大纲
|
|
|
|
暂无标题<br/>使用 H1-H3 标题<br/>自动生成大纲
|
|
|
|
</p>
|
|
|
|
</p>
|
|
|
|
</template>
|
|
|
|
</template>
|
|
|
|
<template v-else>
|
|
|
|
<template v-else>
|
|
|
|
<div
|
|
|
|
<div
|
|
|
|
v-for="item in headings"
|
|
|
|
v-for="item in headings"
|
|
|
|
:key="item.id"
|
|
|
|
:key="item.id"
|
|
|
|
:class="[
|
|
|
|
:class="[
|
|
|
|
'px-2 py-1 rounded-md text-sm cursor-pointer hover:bg-[#ede8de] transition-colors truncate',
|
|
|
|
'px-2 py-1 rounded-md text-sm cursor-pointer hover:bg-[#ede8de] transition-colors truncate',
|
|
|
|
item.level === 1
|
|
|
|
item.level === 1
|
|
|
|
? 'text-[#38342e] font-medium ml-0'
|
|
|
|
? 'text-[#38342e] font-medium ml-0'
|
|
|
|
@@ -224,11 +207,11 @@ const showSettings = ref(false);
|
|
|
|
? 'text-[#8c877d] ml-3'
|
|
|
|
? 'text-[#8c877d] ml-3'
|
|
|
|
: 'text-[#b8b3a8] ml-6 text-xs',
|
|
|
|
: 'text-[#b8b3a8] ml-6 text-xs',
|
|
|
|
]"
|
|
|
|
]"
|
|
|
|
:title="item.text"
|
|
|
|
:title="item.text"
|
|
|
|
@click="onHeadingClick(item)"
|
|
|
|
@click="onHeadingClick(item)"
|
|
|
|
>
|
|
|
|
>
|
|
|
|
<span
|
|
|
|
<span
|
|
|
|
:class="[
|
|
|
|
:class="[
|
|
|
|
'inline-block w-1.5 h-1.5 rounded-full mr-1.5 align-middle',
|
|
|
|
'inline-block w-1.5 h-1.5 rounded-full mr-1.5 align-middle',
|
|
|
|
item.level === 1
|
|
|
|
item.level === 1
|
|
|
|
? 'bg-[#bf6a3b]'
|
|
|
|
? 'bg-[#bf6a3b]'
|
|
|
|
@@ -241,33 +224,22 @@ const showSettings = ref(false);
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</template>
|
|
|
|
</template>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
<!-- ===== BOTTOM: Settings ===== -->
|
|
|
|
|
|
|
|
<div class="border-t border-[#e8e4da] px-3 py-2">
|
|
|
|
|
|
|
|
<button
|
|
|
|
|
|
|
|
class="w-full flex items-center gap-2 px-2 py-1.5 text-xs text-[#8c877d] hover:text-[#38342e] hover:bg-[#ede8de] rounded-md transition-colors"
|
|
|
|
|
|
|
|
@click="showSettings = true"
|
|
|
|
|
|
|
|
>
|
|
|
|
|
|
|
|
<i class="ri-settings-line text-sm"></i>
|
|
|
|
|
|
|
|
设置
|
|
|
|
|
|
|
|
</button>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
</aside>
|
|
|
|
</aside>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- ===== SETTINGS MODAL ===== -->
|
|
|
|
<!-- ===== SETTINGS MODAL ===== -->
|
|
|
|
<Teleport to="body">
|
|
|
|
<Teleport to="body">
|
|
|
|
<div
|
|
|
|
<div
|
|
|
|
v-if="showSettings"
|
|
|
|
v-if="showSettings"
|
|
|
|
class="fixed inset-0 z-50 flex items-center justify-center bg-[#38342e]/25 backdrop-blur-sm"
|
|
|
|
class="fixed inset-0 z-50 flex items-center justify-center bg-[#38342e]/25 backdrop-blur-sm"
|
|
|
|
@click.self="showSettings = false"
|
|
|
|
@click.self="showSettings = false"
|
|
|
|
>
|
|
|
|
>
|
|
|
|
<div class="bg-white border border-[#e0dbcf] rounded-xl shadow-2xl w-80 max-h-[70vh] overflow-y-auto">
|
|
|
|
<div class="bg-white border border-[#e0dbcf] rounded-xl shadow-2xl w-80 max-h-[70vh] overflow-y-auto">
|
|
|
|
<div class="flex items-center justify-between px-4 py-3 border-b border-[#e8e4da]">
|
|
|
|
<div class="flex items-center justify-between px-4 py-3 border-b border-[#e8e4da]">
|
|
|
|
<span class="text-sm font-semibold text-[#38342e]">设置</span>
|
|
|
|
<span class="text-sm font-semibold text-[#38342e]">设置</span>
|
|
|
|
<button
|
|
|
|
<button
|
|
|
|
class="p-1 rounded-md text-[#8c877d] hover:text-[#38342e] hover:bg-[#e0dbcf] transition-colors"
|
|
|
|
class="p-1 rounded-md text-[#8c877d] hover:text-[#38342e] hover:bg-[#e0dbcf] transition-colors"
|
|
|
|
@click="showSettings = false"
|
|
|
|
@click="showSettings = false"
|
|
|
|
>
|
|
|
|
>
|
|
|
|
<i class="ri-close-line text-base"></i>
|
|
|
|
<i class="ri-close-line text-base"></i>
|
|
|
|
</button>
|
|
|
|
</button>
|
|
|
|
|