Before Width: | Height: | Size: 4.5 KiB After Width: | Height: | Size: 4.5 KiB |
Before Width: | Height: | Size: 3.6 KiB After Width: | Height: | Size: 3.6 KiB |
After Width: | Height: | Size: 3.9 KiB |
After Width: | Height: | Size: 2.7 KiB |
After Width: | Height: | Size: 3.2 KiB |
After Width: | Height: | Size: 4.5 KiB |
After Width: | Height: | Size: 3.6 KiB |
@ -1,88 +1,90 @@ |
|||
<template> |
|||
<div class="container"> |
|||
<div class="nav"> |
|||
<ul> |
|||
<li |
|||
v-for="(item, index) in items" |
|||
:key="index" |
|||
@click="selectItem(index)" |
|||
:class="{ active: index === activeIndex }" |
|||
> |
|||
{{ item }} |
|||
</li> |
|||
</ul> |
|||
</div> |
|||
<div class="setting"> |
|||
<div v-if="0 === activeIndex"> |
|||
<div class="setting-item"> |
|||
<h1 class="setting-title">{{ t("language") }}</h1> |
|||
</div> |
|||
<div class="setting-item"> |
|||
<label></label> |
|||
<el-select v-model="modelvalue"> |
|||
<el-option |
|||
v-for="(item, key) in langList" |
|||
:key="key" |
|||
:label="item.label" |
|||
:value="item.value" |
|||
/> |
|||
</el-select> |
|||
</div> |
|||
<div class="container"> |
|||
<div class="nav"> |
|||
<ul> |
|||
<li |
|||
v-for="(item, index) in items" |
|||
:key="index" |
|||
@click="selectItem(index)" |
|||
:class="{ active: index === activeIndex }" |
|||
> |
|||
{{ item }} |
|||
</li> |
|||
</ul> |
|||
</div> |
|||
<div class="setting"> |
|||
<div v-if="0 === activeIndex"> |
|||
<div class="setting-item"> |
|||
<h1 class="setting-title">{{ t("language") }}</h1> |
|||
</div> |
|||
<div class="setting-item"> |
|||
<label></label> |
|||
<el-select v-model="modelvalue"> |
|||
<el-option |
|||
v-for="(item, key) in langList" |
|||
:key="key" |
|||
:label="item.label" |
|||
:value="item.value" |
|||
/> |
|||
</el-select> |
|||
</div> |
|||
|
|||
<div class="setting-item"> |
|||
<label></label> |
|||
<el-button @click="submit" type="primary"> |
|||
{{ t("confirm") }} |
|||
</el-button> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
|
|||
<div class="setting-item"> |
|||
<label></label> |
|||
<el-button |
|||
@click="submit" |
|||
type="primary" |
|||
> |
|||
{{ t("confirm") }} |
|||
</el-button> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</template> |
|||
|
|||
<script lang="ts" setup> |
|||
import { ref } from "vue"; |
|||
import { ElMessageBox } from 'element-plus' |
|||
import { t, getLang, setLang } from "@/i18n"; |
|||
import { useI18n } from 'vue-i18n'; |
|||
const { locale } = useI18n() |
|||
const showDialog = ref(false); |
|||
const langList = [ |
|||
{ |
|||
label: "中文", |
|||
value: "zh-cn", |
|||
}, |
|||
{ |
|||
label: "English", |
|||
value: "en", |
|||
}, |
|||
]; |
|||
const items = [t("language")]; |
|||
import { getLang, setLang, t } from "@/i18n"; |
|||
import { ElMessageBox } from "element-plus"; |
|||
import { ref } from "vue"; |
|||
import { useI18n } from "vue-i18n"; |
|||
const { locale } = useI18n(); |
|||
// const showDialog = ref(false); |
|||
const langList = [ |
|||
{ |
|||
label: "中文", |
|||
value: "zh-cn", |
|||
}, |
|||
{ |
|||
label: "English", |
|||
value: "en", |
|||
}, |
|||
]; |
|||
const items = [t("language")]; |
|||
|
|||
const activeIndex = ref(0); |
|||
const currentLang = getLang(); |
|||
const modelvalue = ref(currentLang); |
|||
const activeIndex = ref(0); |
|||
const currentLang = getLang(); |
|||
const modelvalue = ref(currentLang); |
|||
|
|||
const selectItem = (index: number) => { |
|||
activeIndex.value = index; |
|||
}; |
|||
const selectItem = (index: number) => { |
|||
activeIndex.value = index; |
|||
}; |
|||
|
|||
async function submit() { |
|||
setLang(modelvalue.value); |
|||
locale.value = modelvalue.value; |
|||
ElMessageBox.alert(t("save.success"), t("language"), { |
|||
confirmButtonText: 'OK', |
|||
}) |
|||
//showDialog.value = false |
|||
async function submit() { |
|||
setLang(modelvalue.value); |
|||
locale.value = modelvalue.value; |
|||
ElMessageBox.alert(t("save.success"), t("language"), { |
|||
confirmButtonText: "OK", |
|||
}); |
|||
//showDialog.value = false |
|||
|
|||
// Dialog.showMessageBox({ |
|||
// message: t("save.success"), |
|||
// title: t("language"), |
|||
// type: "info", |
|||
// }); |
|||
} |
|||
// Dialog.showMessageBox({ |
|||
// message: t("save.success"), |
|||
// title: t("language"), |
|||
// type: "info", |
|||
// }); |
|||
} |
|||
</script> |
|||
<style scoped> |
|||
@import "./setStyle.css"; |
|||
@import "./setStyle.css"; |
|||
</style> |
|||
|
@ -1,269 +1,274 @@ |
|||
<template> |
|||
<iframe class="setiframe" allow="fullscreen" ref="storeRef" :src="src"></iframe> |
|||
<iframe |
|||
class="setiframe" |
|||
allow="fullscreen" |
|||
ref="storeRef" |
|||
:src="src" |
|||
></iframe> |
|||
</template> |
|||
<script lang="ts" setup name="IframeFile"> |
|||
//@ts-ignore |
|||
import { BrowserWindow, Dialog, Notify, System } from "@/system"; |
|||
import { getSplit, getSystemConfig, setSystemKey } from "@/system/config"; |
|||
import { base64ToBuffer, isBase64 } from "@/util/file"; |
|||
import { isShareFile } from "@/util/sharePath.ts"; |
|||
import { inject, onMounted, onUnmounted, ref, toRaw } from "vue"; |
|||
import { askAi } from "@/hook/useAi"; |
|||
import { useChooseStore } from "@/stores/choose"; |
|||
import { nanoid } from "nanoid"; |
|||
import eventBus from "@/system/event/eventBus"; |
|||
const SP = getSplit(); |
|||
//@ts-ignore |
|||
import { askAi } from "@/hook/useAi"; |
|||
import { useChooseStore } from "@/stores/choose"; |
|||
import { BrowserWindow, Dialog, Notify, System } from "@/system"; |
|||
import { getSplit, getSystemConfig, setSystemKey } from "@/system/config"; |
|||
import eventBus from "@/system/event/eventBus"; |
|||
import { base64ToBuffer, isBase64 } from "@/util/file"; |
|||
import { isShareFile } from "@/util/sharePath.ts"; |
|||
import { nanoid } from "nanoid"; |
|||
import { inject, onMounted, onUnmounted, ref, toRaw } from "vue"; |
|||
const SP = getSplit(); |
|||
|
|||
const sys: any = inject<System>("system"); |
|||
const win: any = inject<BrowserWindow>("browserWindow"); |
|||
const props = defineProps({ |
|||
src: { |
|||
type: String, |
|||
default: "", |
|||
}, |
|||
eventType: { |
|||
type: String, |
|||
default: "", |
|||
}, |
|||
ext: { |
|||
type: String, |
|||
default: "md", |
|||
}, |
|||
}); |
|||
const storeRef = ref<HTMLIFrameElement | null>(null); |
|||
let hasInit = false; |
|||
const sys: any = inject<System>("system"); |
|||
const win: any = inject<BrowserWindow>("browserWindow"); |
|||
const props = defineProps({ |
|||
src: { |
|||
type: String, |
|||
default: "", |
|||
}, |
|||
eventType: { |
|||
type: String, |
|||
default: "", |
|||
}, |
|||
ext: { |
|||
type: String, |
|||
default: "md", |
|||
}, |
|||
}); |
|||
const storeRef = ref<HTMLIFrameElement | null>(null); |
|||
let hasInit = false; |
|||
|
|||
const choose = useChooseStore(); |
|||
const componentID = nanoid(); |
|||
// console.log("唯一ID:", componentID); |
|||
const saveFile = async (e: any) => { |
|||
if (e.componentID !== componentID) return; |
|||
let data = JSON.parse(e.eventData.data); |
|||
let ext: any = props.ext; |
|||
if (ext instanceof Array) { |
|||
ext = ext[0]; |
|||
} |
|||
if (data.ext) { |
|||
ext = data.ext; |
|||
} |
|||
let path:string |
|||
e.filePath !== "" |
|||
? (path = `${e.filePath}/${e.fileName}.${ext}`) |
|||
: (path = `${SP}C${SP}Users${SP}Desktop${SP}${e.fileName}.${ext}`); |
|||
// console.log('路径:',path); |
|||
await writeFile(path, data, e.fileName); |
|||
}; |
|||
eventBus.on("saveFile", saveFile); |
|||
const writeFile = async (path: string, data: any, title: string) => { |
|||
const isShare = ref(false); |
|||
const isWrite = ref(0); |
|||
if (isShareFile(path)) { |
|||
const file = await sys?.fs.getShareInfo(path); |
|||
isShare.value = true; |
|||
isWrite.value = |
|||
file.fs.sender === getSystemConfig().userInfo.id |
|||
? 1 |
|||
: file.fs.is_write; |
|||
if ( |
|||
!isWrite.value && |
|||
file.fs.sender !== getSystemConfig().userInfo.id |
|||
) { |
|||
new Notify({ |
|||
title: "提示", |
|||
content: "该文件没有编辑权限", |
|||
}); |
|||
return; |
|||
} |
|||
} else if (await sys?.fs.exists(path)) { |
|||
let res = await Dialog.showMessageBox({ |
|||
type: "info", |
|||
title: "提示", |
|||
message: "存在相同的文件名-" + title, |
|||
buttons: ["覆盖文件?", "取消"], |
|||
}); |
|||
//console.log(res) |
|||
if (res.response > 0) { |
|||
return; |
|||
} |
|||
} |
|||
if (typeof data.content === "string") { |
|||
if (data.content.indexOf(";base64,") > -1) { |
|||
const parts = data.content.split(";base64,"); |
|||
data.content = parts[1]; |
|||
} |
|||
if (isBase64(data.content)) { |
|||
data.content = base64ToBuffer(data.content); |
|||
//console.log(data.content) |
|||
} |
|||
} |
|||
const choose = useChooseStore(); |
|||
const componentID = nanoid(); |
|||
// console.log("唯一ID:", componentID); |
|||
const saveFile = async (e: any) => { |
|||
if (e.componentID !== componentID) return; |
|||
let data = JSON.parse(e.eventData.data); |
|||
let ext: any = props.ext; |
|||
if (ext instanceof Array) { |
|||
ext = ext[0]; |
|||
} |
|||
if (data.ext) { |
|||
ext = data.ext; |
|||
} |
|||
let path: string; |
|||
e.filePath !== "" |
|||
? (path = `${e.filePath}/${e.fileName}.${ext}`) |
|||
: (path = `${SP}C${SP}Users${SP}Desktop${SP}${e.fileName}.${ext}`); |
|||
// console.log('路径:',path); |
|||
await writeFile(path, data, e.fileName); |
|||
}; |
|||
eventBus.on("saveFile", saveFile); |
|||
const writeFile = async (path: string, data: any, title: string) => { |
|||
const isShare = ref(false); |
|||
const isWrite = ref(0); |
|||
if (isShareFile(path)) { |
|||
const file = await sys?.fs.getShareInfo(path); |
|||
isShare.value = true; |
|||
isWrite.value = |
|||
file.fs.sender === getSystemConfig().userInfo.id |
|||
? 1 |
|||
: file.fs.is_write; |
|||
if ( |
|||
!isWrite.value && |
|||
file.fs.sender !== getSystemConfig().userInfo.id |
|||
) { |
|||
new Notify({ |
|||
title: "提示", |
|||
content: "该文件没有编辑权限", |
|||
}); |
|||
return; |
|||
} |
|||
} else if (await sys?.fs.exists(path)) { |
|||
let res = await Dialog.showMessageBox({ |
|||
type: "info", |
|||
title: "提示", |
|||
message: "存在相同的文件名-" + title, |
|||
buttons: ["覆盖文件?", "取消"], |
|||
}); |
|||
//console.log(res) |
|||
if (res.response > 0) { |
|||
return; |
|||
} |
|||
} |
|||
if (typeof data.content === "string") { |
|||
if (data.content.indexOf(";base64,") > -1) { |
|||
const parts = data.content.split(";base64,"); |
|||
data.content = parts[1]; |
|||
} |
|||
if (isBase64(data.content)) { |
|||
data.content = base64ToBuffer(data.content); |
|||
//console.log(data.content) |
|||
} |
|||
} |
|||
|
|||
const res = isShare.value |
|||
? await sys?.fs.writeShareFile(path, data.content, isWrite.value) |
|||
: await sys?.fs.writeFile(path, data.content); |
|||
// console.log("编写文件:", res, isShare); |
|||
new Notify({ |
|||
title: "提示", |
|||
content: res.message, |
|||
// content: res.code === 0 ? "文件已保存" : res.message, |
|||
}); |
|||
sys.refershAppList(); |
|||
}; |
|||
const eventHandler = async (e: MessageEvent) => { |
|||
const eventData = e.data; |
|||
// console.log('是否同一个:', componentID == eventData.componentID); |
|||
if (eventData.type == props.eventType) { |
|||
// if (eventData.componentID !== componentID) return; |
|||
let data = JSON.parse(eventData.data); |
|||
let title = data.title; |
|||
let path; |
|||
let ext: any = props.ext; |
|||
if (ext instanceof Array) { |
|||
ext = ext[0]; |
|||
} |
|||
if (data.ext) { |
|||
ext = data.ext; |
|||
} |
|||
if (title.indexOf("." + ext) > -1) { |
|||
title = title.replace("." + ext, ""); |
|||
} |
|||
const res = isShare.value |
|||
? await sys?.fs.writeShareFile(path, data.content, isWrite.value) |
|||
: await sys?.fs.writeFile(path, data.content); |
|||
// console.log("编写文件:", res, isShare); |
|||
new Notify({ |
|||
title: "提示", |
|||
content: res.message, |
|||
// content: res.code === 0 ? "文件已保存" : res.message, |
|||
}); |
|||
sys.refershAppList(); |
|||
}; |
|||
const eventHandler = async (e: MessageEvent) => { |
|||
const eventData = e.data; |
|||
// console.log('是否同一个:', componentID == eventData.componentID); |
|||
if (eventData.type == props.eventType) { |
|||
// if (eventData.componentID !== componentID) return; |
|||
let data = JSON.parse(eventData.data); |
|||
let title = data.title; |
|||
let path; |
|||
let ext: any = props.ext; |
|||
if (ext instanceof Array) { |
|||
ext = ext[0]; |
|||
} |
|||
if (data.ext) { |
|||
ext = data.ext; |
|||
} |
|||
if (title.indexOf("." + ext) > -1) { |
|||
title = title.replace("." + ext, ""); |
|||
} |
|||
|
|||
if (win.config && win.config.path) { |
|||
path = win.config.path; |
|||
if (win.config && win.config.path) { |
|||
path = win.config.path; |
|||
|
|||
//去除重复文件名后的(1) |
|||
let fileTitleArr = path.split(SP).pop().split("."); |
|||
let oldExt = fileTitleArr.pop(); |
|||
let fileTitle = fileTitleArr.join("."); |
|||
if (fileTitle != title) { |
|||
path = path.replace(fileTitle, title); |
|||
} |
|||
if (oldExt != ext) { |
|||
path = path.replace("." + oldExt, "." + ext); |
|||
} |
|||
} else { |
|||
choose.saveFile("选择地址", "*", componentID, eventData); |
|||
return; |
|||
// path = `${SP}C${SP}Users${SP}Desktop${SP}${title}.${ext}`; |
|||
} |
|||
writeFile(path, data, title); |
|||
} else if (eventData.type == "initSuccess") { |
|||
if (hasInit) { |
|||
return; |
|||
} |
|||
hasInit = true; |
|||
let content = win?.config?.content; |
|||
let title = win.getTitle(); |
|||
// console.log("win.config;", win?.config); |
|||
// console.log(title); |
|||
title = title.split(SP).pop(); |
|||
//去除重复文件名后的(1) |
|||
let fileTitleArr = path.split(SP).pop().split("."); |
|||
let oldExt = fileTitleArr.pop(); |
|||
let fileTitle = fileTitleArr.join("."); |
|||
if (fileTitle != title) { |
|||
path = path.replace(fileTitle, title); |
|||
} |
|||
if (oldExt != ext) { |
|||
path = path.replace("." + oldExt, "." + ext); |
|||
} |
|||
} else { |
|||
choose.saveFile("选择地址", "*", componentID, eventData); |
|||
return; |
|||
// path = `${SP}C${SP}Users${SP}Desktop${SP}${title}.${ext}`; |
|||
} |
|||
writeFile(path, data, title); |
|||
} else if (eventData.type == "initSuccess") { |
|||
if (hasInit) { |
|||
return; |
|||
} |
|||
hasInit = true; |
|||
let content = win?.config?.content; |
|||
let title = win.getTitle(); |
|||
// console.log("win.config;", win?.config); |
|||
// console.log(title); |
|||
title = title.split(SP).pop(); |
|||
|
|||
// if (!content && win?.config.path) { |
|||
// const header = { |
|||
// pwd: '' |
|||
// }; |
|||
// const filePwd = getSystemConfig().fileInputPwd |
|||
// const pos = filePwd.findIndex((item: any) => item.path == win?.config.path) |
|||
// //console.log('路径:', win?.config.path, pos, filePwd); |
|||
// const userType = getSystemConfig().userType |
|||
// if (pos !== -1) { |
|||
// header.pwd = userType == 'person' ? md5(filePwd[pos].pwd) : filePwd[pos].pwd |
|||
// } |
|||
// content = await sys?.fs.readFile(win?.config.path, header); |
|||
// } |
|||
content = toRaw(content); |
|||
if (content && content !== "") { |
|||
storeRef.value?.contentWindow?.postMessage( |
|||
{ |
|||
type: "init", |
|||
data: { content, title }, |
|||
componentID, |
|||
}, |
|||
"*" |
|||
); |
|||
} else { |
|||
storeRef.value?.contentWindow?.postMessage( |
|||
{ |
|||
type: "start", |
|||
title, |
|||
componentID, |
|||
}, |
|||
"*" |
|||
); |
|||
} |
|||
} else if (eventData.type == "close") { |
|||
// console.log("关闭"); |
|||
win.close(); |
|||
} else if (eventData.type == "saveMind") { |
|||
// console.log("保存"); |
|||
const data = eventData.data; |
|||
const path = win?.config?.path; |
|||
//console.log(path,data) |
|||
const winMind = new BrowserWindow({ |
|||
title: data.title, |
|||
url: "/mind/index.html", |
|||
frame: true, |
|||
config: { |
|||
ext: "mind", |
|||
path: path, |
|||
content: data.content, |
|||
}, |
|||
icon: "gallery", |
|||
width: 700, |
|||
height: 500, |
|||
x: 100, |
|||
y: 100, |
|||
//center: true, |
|||
minimizable: false, |
|||
resizable: true, |
|||
}); |
|||
winMind.show(); |
|||
} else if (eventData.type == "aiCreater") { |
|||
console.log("传递内容: ", eventData); |
|||
let postData: any = {}; |
|||
if (eventData.data) { |
|||
postData.content = eventData.data; |
|||
} |
|||
if (eventData.title) { |
|||
postData.title = eventData.title; |
|||
} |
|||
if (eventData.category) { |
|||
postData.category = eventData.category; |
|||
} |
|||
//console.log(postData,eventData.action) |
|||
// 模拟AI返回数据 |
|||
const res: any = await askAi(postData, eventData.action); |
|||
storeRef.value?.contentWindow?.postMessage( |
|||
{ |
|||
type: "aiReciver", |
|||
data: res, |
|||
action: eventData.action, |
|||
}, |
|||
"*" |
|||
); |
|||
} |
|||
}; |
|||
//删除本地暂存的文件密码 |
|||
const delFileInputPwd = async () => { |
|||
let fileInputPwd = getSystemConfig().fileInputPwd; |
|||
const currentPath = win.config.path; |
|||
const temp = fileInputPwd.filter( |
|||
(item: any) => item.path !== currentPath |
|||
); |
|||
setSystemKey("fileInputPwd", temp); |
|||
}; |
|||
onMounted(() => { |
|||
window.addEventListener("message", eventHandler); |
|||
}); |
|||
// if (!content && win?.config.path) { |
|||
// const header = { |
|||
// pwd: '' |
|||
// }; |
|||
// const filePwd = getSystemConfig().fileInputPwd |
|||
// const pos = filePwd.findIndex((item: any) => item.path == win?.config.path) |
|||
// //console.log('路径:', win?.config.path, pos, filePwd); |
|||
// const userType = getSystemConfig().userType |
|||
// if (pos !== -1) { |
|||
// header.pwd = userType == 'person' ? md5(filePwd[pos].pwd) : filePwd[pos].pwd |
|||
// } |
|||
// content = await sys?.fs.readFile(win?.config.path, header); |
|||
// } |
|||
content = toRaw(content); |
|||
if (content && content !== "") { |
|||
storeRef.value?.contentWindow?.postMessage( |
|||
{ |
|||
type: "init", |
|||
data: { content, title }, |
|||
componentID, |
|||
}, |
|||
"*" |
|||
); |
|||
} else { |
|||
storeRef.value?.contentWindow?.postMessage( |
|||
{ |
|||
type: "start", |
|||
title, |
|||
componentID, |
|||
}, |
|||
"*" |
|||
); |
|||
} |
|||
} else if (eventData.type == "close") { |
|||
// console.log("关闭"); |
|||
win.close(); |
|||
} else if (eventData.type == "saveMind") { |
|||
// console.log("保存"); |
|||
const data = eventData.data; |
|||
const path = win?.config?.path; |
|||
//console.log(path,data) |
|||
const winMind = new BrowserWindow({ |
|||
title: data.title, |
|||
url: "/mind/index.html", |
|||
frame: true, |
|||
config: { |
|||
ext: "mind", |
|||
path: path, |
|||
content: data.content, |
|||
}, |
|||
icon: "gallery", |
|||
width: 700, |
|||
height: 500, |
|||
x: 100, |
|||
y: 100, |
|||
//center: true, |
|||
minimizable: false, |
|||
resizable: true, |
|||
}); |
|||
winMind.show(); |
|||
} else if (eventData.type == "aiCreater") { |
|||
console.log("传递内容: ", eventData); |
|||
let postData: any = {}; |
|||
if (eventData.data) { |
|||
postData.content = eventData.data; |
|||
} |
|||
if (eventData.title) { |
|||
postData.title = eventData.title; |
|||
} |
|||
if (eventData.category) { |
|||
postData.category = eventData.category; |
|||
} |
|||
//console.log(postData,eventData.action) |
|||
// 模拟AI返回数据 |
|||
const res: any = await askAi(postData, eventData.action); |
|||
storeRef.value?.contentWindow?.postMessage( |
|||
{ |
|||
type: "aiReciver", |
|||
data: res, |
|||
action: eventData.action, |
|||
}, |
|||
"*" |
|||
); |
|||
} |
|||
}; |
|||
//删除本地暂存的文件密码 |
|||
const delFileInputPwd = async () => { |
|||
let fileInputPwd = getSystemConfig().fileInputPwd; |
|||
const currentPath = win.config.path; |
|||
const temp = fileInputPwd.filter( |
|||
(item: any) => item.path !== currentPath |
|||
); |
|||
setSystemKey("fileInputPwd", temp); |
|||
}; |
|||
onMounted(() => { |
|||
window.addEventListener("message", eventHandler); |
|||
}); |
|||
|
|||
onUnmounted(async () => { |
|||
await delFileInputPwd(); |
|||
window.removeEventListener("message", eventHandler); |
|||
}); |
|||
onUnmounted(async () => { |
|||
await delFileInputPwd(); |
|||
window.removeEventListener("message", eventHandler); |
|||
}); |
|||
</script> |
|||
<style scoped> |
|||
.setiframe { |
|||
width: 100%; |
|||
height: 100%; |
|||
border: none; |
|||
} |
|||
.setiframe { |
|||
width: 100%; |
|||
height: 100%; |
|||
border: none; |
|||
} |
|||
</style> |
|||
|