Merge pull request #7105 from coollabsio/light-mode-wtf
fix: light mode wtf
This commit is contained in:
commit
bc3deeed03
3 changed files with 235 additions and 230 deletions
|
|
@ -124,7 +124,7 @@ @utility menu {
|
||||||
}
|
}
|
||||||
|
|
||||||
@utility menu-item {
|
@utility menu-item {
|
||||||
@apply flex gap-3 items-center px-2 py-1 w-full text-sm sm:pr-0 dark:hover:bg-coolgray-100 dark:hover:text-white hover:bg-neutral-300 min-w-fit sm:min-w-64;
|
@apply flex gap-3 items-center px-2 py-1 w-full text-sm sm:pr-0 dark:hover:bg-coolgray-100 dark:hover:text-white hover:bg-neutral-300 min-w-fit sm:min-w-64 text-black dark:text-neutral-400;
|
||||||
}
|
}
|
||||||
|
|
||||||
@utility menu-item-active {
|
@utility menu-item-active {
|
||||||
|
|
@ -220,7 +220,7 @@ @utility title {
|
||||||
}
|
}
|
||||||
|
|
||||||
@utility subtitle {
|
@utility subtitle {
|
||||||
@apply pt-2 pb-9;
|
@apply pt-2 pb-9 text-neutral-500 dark:text-neutral-400;
|
||||||
}
|
}
|
||||||
|
|
||||||
@utility fullscreen {
|
@utility fullscreen {
|
||||||
|
|
|
||||||
|
|
@ -9,15 +9,16 @@
|
||||||
@auth
|
@auth
|
||||||
<livewire:deployments-indicator />
|
<livewire:deployments-indicator />
|
||||||
<div x-data="{
|
<div x-data="{
|
||||||
open: false,
|
open: false,
|
||||||
init() {
|
init() {
|
||||||
this.pageWidth = localStorage.getItem('pageWidth');
|
this.pageWidth = localStorage.getItem('pageWidth');
|
||||||
if (!this.pageWidth) {
|
if (!this.pageWidth) {
|
||||||
this.pageWidth = 'full';
|
this.pageWidth = 'full';
|
||||||
localStorage.setItem('pageWidth', 'full');
|
localStorage.setItem('pageWidth', 'full');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}" x-cloak class="mx-auto" :class="pageWidth === 'full' ? '' : 'max-w-7xl'">
|
}" x-cloak class="mx-auto text-neutral-800 dark:text-white"
|
||||||
|
:class="pageWidth === 'full' ? '' : 'max-w-7xl'">
|
||||||
<div class="relative z-50 lg:hidden" :class="open ? 'block' : 'hidden'" role="dialog" aria-modal="true">
|
<div class="relative z-50 lg:hidden" :class="open ? 'block' : 'hidden'" role="dialog" aria-modal="true">
|
||||||
<div class="fixed inset-0 bg-black/80" x-on:click="open = false"></div>
|
<div class="fixed inset-0 bg-black/80" x-on:click="open = false"></div>
|
||||||
<div class="fixed inset-y-0 right-0 h-full flex">
|
<div class="fixed inset-y-0 right-0 h-full flex">
|
||||||
|
|
@ -45,16 +46,18 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="sticky top-0 z-40 flex items-center justify-between px-4 py-4 gap-x-6 sm:px-6 lg:hidden bg-white/95 dark:bg-base/95 backdrop-blur-sm border-b border-neutral-300/50 dark:border-coolgray-200/50">
|
<div
|
||||||
|
class="sticky top-0 z-40 flex items-center justify-between px-4 py-4 gap-x-6 sm:px-6 lg:hidden bg-white/95 dark:bg-base/95 backdrop-blur-sm border-b border-neutral-300/50 dark:border-coolgray-200/50">
|
||||||
<div class="flex items-center gap-3 flex-shrink-0">
|
<div class="flex items-center gap-3 flex-shrink-0">
|
||||||
<a href="/" class="text-xl font-bold tracking-wide dark:text-white hover:opacity-80 transition-opacity">Coolify</a>
|
<a href="/"
|
||||||
|
class="text-xl font-bold tracking-wide dark:text-white hover:opacity-80 transition-opacity">Coolify</a>
|
||||||
<livewire:switch-team />
|
<livewire:switch-team />
|
||||||
</div>
|
</div>
|
||||||
<button type="button" class="-m-2.5 p-2.5 dark:text-warning" x-on:click="open = !open">
|
<button type="button" class="-m-2.5 p-2.5 dark:text-warning" x-on:click="open = !open">
|
||||||
<span class="sr-only">Open sidebar</span>
|
<span class="sr-only">Open sidebar</span>
|
||||||
<svg class="w-6 h-6" xmlns="http://www.w3.org/2000/svg" width="200" height="200" viewBox="0 0 24 24">
|
<svg class="w-6 h-6" xmlns="http://www.w3.org/2000/svg" width="200" height="200" viewBox="0 0 24 24">
|
||||||
<path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"
|
<path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
||||||
stroke-width="2" d="M4 6h16M4 12h16M4 18h16" />
|
d="M4 6h16M4 12h16M4 18h16" />
|
||||||
</svg>
|
</svg>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -2,17 +2,19 @@
|
||||||
<html data-theme="dark" lang="{{ str_replace('_', '-', app()->getLocale()) }}">
|
<html data-theme="dark" lang="{{ str_replace('_', '-', app()->getLocale()) }}">
|
||||||
<script>
|
<script>
|
||||||
// Immediate theme application - runs before any rendering
|
// Immediate theme application - runs before any rendering
|
||||||
(function() {
|
(function () {
|
||||||
const t = localStorage.theme || 'dark';
|
const t = localStorage.theme || 'dark';
|
||||||
const d = t === 'dark' || (t === 'system' && matchMedia('(prefers-color-scheme: dark)').matches);
|
const d = t === 'dark' || (t === 'system' && matchMedia('(prefers-color-scheme: dark)').matches);
|
||||||
document.documentElement.classList[d ? 'add' : 'remove']('dark');
|
document.documentElement.classList[d ? 'add' : 'remove']('dark');
|
||||||
|
document.documentElement.setAttribute('data-theme', d ? 'dark' : 'light');
|
||||||
})();
|
})();
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
<meta name="robots" content="noindex">
|
<meta name="robots" content="noindex">
|
||||||
<meta name="theme-color" content="#101010" id="theme-color-meta" />
|
<meta name="theme-color" content="#ffffff" id="theme-color-meta" />
|
||||||
<meta name="color-scheme" content="dark light" />
|
<meta name="color-scheme" content="dark light" />
|
||||||
<meta name="Description" content="Coolify: An open-source & self-hostable Heroku / Netlify / Vercel alternative" />
|
<meta name="Description" content="Coolify: An open-source & self-hostable Heroku / Netlify / Vercel alternative" />
|
||||||
<meta name="viewport" content="width=device-width,initial-scale=1" />
|
<meta name="viewport" content="width=device-width,initial-scale=1" />
|
||||||
|
|
@ -73,102 +75,102 @@
|
||||||
</head>
|
</head>
|
||||||
@section('body')
|
@section('body')
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
<x-toast />
|
<x-toast />
|
||||||
<script data-navigate-once>
|
<script data-navigate-once>
|
||||||
// Global HTML sanitization function using DOMPurify
|
// Global HTML sanitization function using DOMPurify
|
||||||
window.sanitizeHTML = function(html) {
|
window.sanitizeHTML = function (html) {
|
||||||
if (!html) return '';
|
if (!html) return '';
|
||||||
const URL_RE = /^(https?:|mailto:)/i;
|
const URL_RE = /^(https?:|mailto:)/i;
|
||||||
const config = {
|
const config = {
|
||||||
ALLOWED_TAGS: ['a', 'b', 'br', 'code', 'del', 'div', 'em', 'i', 'p', 'pre', 's', 'span', 'strong',
|
ALLOWED_TAGS: ['a', 'b', 'br', 'code', 'del', 'div', 'em', 'i', 'p', 'pre', 's', 'span', 'strong',
|
||||||
'u'
|
'u'
|
||||||
],
|
],
|
||||||
ALLOWED_ATTR: ['class', 'href', 'target', 'title', 'rel'],
|
ALLOWED_ATTR: ['class', 'href', 'target', 'title', 'rel'],
|
||||||
ALLOW_DATA_ATTR: false,
|
ALLOW_DATA_ATTR: false,
|
||||||
FORBID_TAGS: ['script', 'object', 'embed', 'applet', 'iframe', 'form', 'input', 'button', 'select',
|
FORBID_TAGS: ['script', 'object', 'embed', 'applet', 'iframe', 'form', 'input', 'button', 'select',
|
||||||
'textarea', 'details', 'summary', 'dialog', 'style'
|
'textarea', 'details', 'summary', 'dialog', 'style'
|
||||||
],
|
],
|
||||||
FORBID_ATTR: ['onerror', 'onload', 'onclick', 'onmouseover', 'onfocus', 'onblur', 'onchange',
|
FORBID_ATTR: ['onerror', 'onload', 'onclick', 'onmouseover', 'onfocus', 'onblur', 'onchange',
|
||||||
'onsubmit', 'ontoggle', 'style'
|
'onsubmit', 'ontoggle', 'style'
|
||||||
],
|
],
|
||||||
KEEP_CONTENT: true,
|
KEEP_CONTENT: true,
|
||||||
RETURN_DOM: false,
|
RETURN_DOM: false,
|
||||||
RETURN_DOM_FRAGMENT: false,
|
RETURN_DOM_FRAGMENT: false,
|
||||||
SANITIZE_DOM: true,
|
SANITIZE_DOM: true,
|
||||||
SANITIZE_NAMED_PROPS: true,
|
SANITIZE_NAMED_PROPS: true,
|
||||||
SAFE_FOR_TEMPLATES: true,
|
SAFE_FOR_TEMPLATES: true,
|
||||||
ALLOWED_URI_REGEXP: URL_RE
|
ALLOWED_URI_REGEXP: URL_RE
|
||||||
};
|
|
||||||
|
|
||||||
// One-time hook registration (idempotent pattern)
|
|
||||||
if (!window.__dpLinkHook) {
|
|
||||||
DOMPurify.addHook('afterSanitizeAttributes', node => {
|
|
||||||
// Remove Alpine.js directives to prevent XSS
|
|
||||||
if (node.hasAttributes && node.hasAttributes()) {
|
|
||||||
const attrs = Array.from(node.attributes);
|
|
||||||
attrs.forEach(attr => {
|
|
||||||
// Remove x-* attributes (Alpine directives)
|
|
||||||
if (attr.name.startsWith('x-')) {
|
|
||||||
node.removeAttribute(attr.name);
|
|
||||||
}
|
|
||||||
// Remove @* attributes (Alpine event shorthand)
|
|
||||||
if (attr.name.startsWith('@')) {
|
|
||||||
node.removeAttribute(attr.name);
|
|
||||||
}
|
|
||||||
// Remove :* attributes (Alpine binding shorthand)
|
|
||||||
if (attr.name.startsWith(':')) {
|
|
||||||
node.removeAttribute(attr.name);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Existing link sanitization
|
|
||||||
if (node.nodeName === 'A' && node.hasAttribute('href')) {
|
|
||||||
const href = node.getAttribute('href') || '';
|
|
||||||
if (!URL_RE.test(href)) node.removeAttribute('href');
|
|
||||||
if (node.getAttribute('target') === '_blank') {
|
|
||||||
node.setAttribute('rel', 'noopener noreferrer');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
window.__dpLinkHook = true;
|
|
||||||
}
|
|
||||||
return DOMPurify.sanitize(html, config);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Initialize theme if not set
|
// One-time hook registration (idempotent pattern)
|
||||||
if (!('theme' in localStorage)) {
|
if (!window.__dpLinkHook) {
|
||||||
localStorage.theme = 'dark';
|
DOMPurify.addHook('afterSanitizeAttributes', node => {
|
||||||
}
|
// Remove Alpine.js directives to prevent XSS
|
||||||
|
if (node.hasAttributes && node.hasAttributes()) {
|
||||||
|
const attrs = Array.from(node.attributes);
|
||||||
|
attrs.forEach(attr => {
|
||||||
|
// Remove x-* attributes (Alpine directives)
|
||||||
|
if (attr.name.startsWith('x-')) {
|
||||||
|
node.removeAttribute(attr.name);
|
||||||
|
}
|
||||||
|
// Remove @* attributes (Alpine event shorthand)
|
||||||
|
if (attr.name.startsWith('@')) {
|
||||||
|
node.removeAttribute(attr.name);
|
||||||
|
}
|
||||||
|
// Remove :* attributes (Alpine binding shorthand)
|
||||||
|
if (attr.name.startsWith(':')) {
|
||||||
|
node.removeAttribute(attr.name);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
let theme = localStorage.theme
|
// Existing link sanitization
|
||||||
let cpuColor = '#1e90ff'
|
if (node.nodeName === 'A' && node.hasAttribute('href')) {
|
||||||
let ramColor = '#00ced1'
|
const href = node.getAttribute('href') || '';
|
||||||
let textColor = '#ffffff'
|
if (!URL_RE.test(href)) node.removeAttribute('href');
|
||||||
let editorBackground = '#181818'
|
if (node.getAttribute('target') === '_blank') {
|
||||||
let editorTheme = 'blackboard'
|
node.setAttribute('rel', 'noopener noreferrer');
|
||||||
|
}
|
||||||
function checkTheme() {
|
}
|
||||||
theme = localStorage.theme
|
});
|
||||||
if (theme == 'system') {
|
window.__dpLinkHook = true;
|
||||||
theme = window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light'
|
|
||||||
}
|
|
||||||
if (theme == 'dark') {
|
|
||||||
cpuColor = '#1e90ff'
|
|
||||||
ramColor = '#00ced1'
|
|
||||||
textColor = '#ffffff'
|
|
||||||
editorBackground = '#181818'
|
|
||||||
editorTheme = 'blackboard'
|
|
||||||
} else {
|
|
||||||
cpuColor = '#1e90ff'
|
|
||||||
ramColor = '#00ced1'
|
|
||||||
textColor = '#000000'
|
|
||||||
editorBackground = '#ffffff'
|
|
||||||
editorTheme = null
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@auth
|
return DOMPurify.sanitize(html, config);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Initialize theme if not set
|
||||||
|
if (!('theme' in localStorage)) {
|
||||||
|
localStorage.theme = 'dark';
|
||||||
|
}
|
||||||
|
|
||||||
|
let theme = localStorage.theme
|
||||||
|
let cpuColor = '#1e90ff'
|
||||||
|
let ramColor = '#00ced1'
|
||||||
|
let textColor = '#ffffff'
|
||||||
|
let editorBackground = '#181818'
|
||||||
|
let editorTheme = 'blackboard'
|
||||||
|
|
||||||
|
function checkTheme() {
|
||||||
|
theme = localStorage.theme
|
||||||
|
if (theme == 'system') {
|
||||||
|
theme = window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light'
|
||||||
|
}
|
||||||
|
if (theme == 'dark') {
|
||||||
|
cpuColor = '#1e90ff'
|
||||||
|
ramColor = '#00ced1'
|
||||||
|
textColor = '#ffffff'
|
||||||
|
editorBackground = '#181818'
|
||||||
|
editorTheme = 'blackboard'
|
||||||
|
} else {
|
||||||
|
cpuColor = '#1e90ff'
|
||||||
|
ramColor = '#00ced1'
|
||||||
|
textColor = '#000000'
|
||||||
|
editorBackground = '#ffffff'
|
||||||
|
editorTheme = null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@auth
|
||||||
window.Pusher = Pusher;
|
window.Pusher = Pusher;
|
||||||
window.Echo = new Echo({
|
window.Echo = new Echo({
|
||||||
broadcaster: 'pusher',
|
broadcaster: 'pusher',
|
||||||
|
|
@ -197,131 +199,131 @@ function checkTheme() {
|
||||||
// Maximum number of reconnection attempts
|
// Maximum number of reconnection attempts
|
||||||
maxAttempts: 15
|
maxAttempts: 15
|
||||||
});
|
});
|
||||||
@endauth
|
@endauth
|
||||||
let checkHealthInterval = null;
|
let checkHealthInterval = null;
|
||||||
let checkIfIamDeadInterval = null;
|
let checkIfIamDeadInterval = null;
|
||||||
|
|
||||||
function changePasswordFieldType(event) {
|
function changePasswordFieldType(event) {
|
||||||
let element = event.target
|
let element = event.target
|
||||||
for (let i = 0; i < 10; i++) {
|
for (let i = 0; i < 10; i++) {
|
||||||
if (element.className === "relative") {
|
if (element.className === "relative") {
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
element = element.parentElement;
|
|
||||||
}
|
}
|
||||||
element = element.children[1];
|
element = element.parentElement;
|
||||||
if (element.nodeName === 'INPUT' || element.nodeName === 'TEXTAREA') {
|
}
|
||||||
if (element.type === 'password') {
|
element = element.children[1];
|
||||||
element.type = 'text';
|
if (element.nodeName === 'INPUT' || element.nodeName === 'TEXTAREA') {
|
||||||
if (element.disabled) return;
|
if (element.type === 'password') {
|
||||||
element.classList.add('truncate');
|
element.type = 'text';
|
||||||
this.type = 'text';
|
if (element.disabled) return;
|
||||||
} else {
|
element.classList.add('truncate');
|
||||||
element.type = 'password';
|
this.type = 'text';
|
||||||
if (element.disabled) return;
|
} else {
|
||||||
element.classList.remove('truncate');
|
element.type = 'password';
|
||||||
this.type = 'password';
|
if (element.disabled) return;
|
||||||
}
|
element.classList.remove('truncate');
|
||||||
|
this.type = 'password';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function copyToClipboard(text) {
|
function copyToClipboard(text) {
|
||||||
navigator?.clipboard?.writeText(text) && window.Livewire.dispatch('success', 'Copied to clipboard.');
|
navigator?.clipboard?.writeText(text) && window.Livewire.dispatch('success', 'Copied to clipboard.');
|
||||||
}
|
}
|
||||||
document.addEventListener('livewire:init', () => {
|
document.addEventListener('livewire:init', () => {
|
||||||
window.Livewire.on('reloadWindow', (timeout) => {
|
window.Livewire.on('reloadWindow', (timeout) => {
|
||||||
if (timeout) {
|
if (timeout) {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
window.location.reload();
|
|
||||||
}, timeout);
|
|
||||||
return;
|
|
||||||
} else {
|
|
||||||
window.location.reload();
|
window.location.reload();
|
||||||
}
|
}, timeout);
|
||||||
})
|
return;
|
||||||
window.Livewire.on('info', (message) => {
|
} else {
|
||||||
if (typeof message === 'string') {
|
window.location.reload();
|
||||||
window.toast('Info', {
|
}
|
||||||
type: 'info',
|
})
|
||||||
description: message,
|
window.Livewire.on('info', (message) => {
|
||||||
})
|
if (typeof message === 'string') {
|
||||||
return;
|
window.toast('Info', {
|
||||||
}
|
type: 'info',
|
||||||
if (message.length == 1) {
|
description: message,
|
||||||
window.toast('Info', {
|
})
|
||||||
type: 'info',
|
return;
|
||||||
description: message[0],
|
}
|
||||||
})
|
if (message.length == 1) {
|
||||||
} else if (message.length == 2) {
|
window.toast('Info', {
|
||||||
window.toast(message[0], {
|
type: 'info',
|
||||||
type: 'info',
|
description: message[0],
|
||||||
description: message[1],
|
})
|
||||||
})
|
} else if (message.length == 2) {
|
||||||
}
|
window.toast(message[0], {
|
||||||
})
|
type: 'info',
|
||||||
window.Livewire.on('error', (message) => {
|
description: message[1],
|
||||||
if (typeof message === 'string') {
|
})
|
||||||
window.toast('Error', {
|
}
|
||||||
type: 'danger',
|
})
|
||||||
description: message,
|
window.Livewire.on('error', (message) => {
|
||||||
})
|
if (typeof message === 'string') {
|
||||||
return;
|
window.toast('Error', {
|
||||||
}
|
type: 'danger',
|
||||||
if (message.length == 1) {
|
description: message,
|
||||||
window.toast('Error', {
|
})
|
||||||
type: 'danger',
|
return;
|
||||||
description: message[0],
|
}
|
||||||
})
|
if (message.length == 1) {
|
||||||
} else if (message.length == 2) {
|
window.toast('Error', {
|
||||||
window.toast(message[0], {
|
type: 'danger',
|
||||||
type: 'danger',
|
description: message[0],
|
||||||
description: message[1],
|
})
|
||||||
})
|
} else if (message.length == 2) {
|
||||||
}
|
window.toast(message[0], {
|
||||||
})
|
type: 'danger',
|
||||||
window.Livewire.on('warning', (message) => {
|
description: message[1],
|
||||||
if (typeof message === 'string') {
|
})
|
||||||
window.toast('Warning', {
|
}
|
||||||
type: 'warning',
|
})
|
||||||
description: message,
|
window.Livewire.on('warning', (message) => {
|
||||||
})
|
if (typeof message === 'string') {
|
||||||
return;
|
window.toast('Warning', {
|
||||||
}
|
type: 'warning',
|
||||||
if (message.length == 1) {
|
description: message,
|
||||||
window.toast('Warning', {
|
})
|
||||||
type: 'warning',
|
return;
|
||||||
description: message[0],
|
}
|
||||||
})
|
if (message.length == 1) {
|
||||||
} else if (message.length == 2) {
|
window.toast('Warning', {
|
||||||
window.toast(message[0], {
|
type: 'warning',
|
||||||
type: 'warning',
|
description: message[0],
|
||||||
description: message[1],
|
})
|
||||||
})
|
} else if (message.length == 2) {
|
||||||
}
|
window.toast(message[0], {
|
||||||
})
|
type: 'warning',
|
||||||
window.Livewire.on('success', (message) => {
|
description: message[1],
|
||||||
if (typeof message === 'string') {
|
})
|
||||||
window.toast('Success', {
|
}
|
||||||
type: 'success',
|
})
|
||||||
description: message,
|
window.Livewire.on('success', (message) => {
|
||||||
})
|
if (typeof message === 'string') {
|
||||||
return;
|
window.toast('Success', {
|
||||||
}
|
type: 'success',
|
||||||
if (message.length == 1) {
|
description: message,
|
||||||
window.toast('Success', {
|
})
|
||||||
type: 'success',
|
return;
|
||||||
description: message[0],
|
}
|
||||||
})
|
if (message.length == 1) {
|
||||||
} else if (message.length == 2) {
|
window.toast('Success', {
|
||||||
window.toast(message[0], {
|
type: 'success',
|
||||||
type: 'success',
|
description: message[0],
|
||||||
description: message[1],
|
})
|
||||||
})
|
} else if (message.length == 2) {
|
||||||
}
|
window.toast(message[0], {
|
||||||
})
|
type: 'success',
|
||||||
});
|
description: message[1],
|
||||||
</script>
|
})
|
||||||
</body>
|
}
|
||||||
|
})
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
@show
|
@show
|
||||||
|
|
||||||
</html>
|
</html>
|
||||||
Loading…
Reference in a new issue