Team Ai
Apppublic

LiteBlackEagle/OpenCoding

sourceHugging Faceapache-2.0updated 1y agoView on Hugging Face
1likes
index.html569 linesDownload Raw Back to root
1<!DOCTYPE html>2<html lang="en">3<head>4    <meta charset="UTF-8">5    <meta name="viewport" content="width=device-width, initial-scale=1.0">6    <title>LBE OpenCode</title>7    <script src="https://cdn.tailwindcss.com"></script>8    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.2/css/all.min.css" integrity="sha512-SnH5WK+bZxgPHs44uWIX+LLJAJ9/2PkPKZ5QiAj6Ta86w+fsb2TkcmfRyVX3pBnMFcV7oQPJkl9QevSCWr3W6A==" crossorigin="anonymous" referrerpolicy="no-referrer" />9    <script defer src="https://cdn.jsdelivr.net/npm/alpinejs@3.x.x/dist/cdn.min.js"></script>10    <script src="https://cdnjs.cloudflare.com/ajax/libs/ace/1.35.2/ace.js"></script>11    <link rel="preconnect" href="https://fonts.googleapis.com">12    <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>13    <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;700&family=Inconsolata:wght@400;600&display=swap" rel="stylesheet">14    <style>15        :root {16            --bg-primary: #18181b;17            --bg-secondary: #27272a;18            --bg-tertiary: #3f3f46;19            --border-color: rgba(255,255,255,0.15);20            --text-primary: #f4f4f5;21            --text-secondary: #a1a1aa;22            --accent-green: #2dd4bf;23            --accent-green-light: rgba(45,212,191,0.1);24            --error-color: #f87171;25        }26        body {27            font-family: 'Inter', sans-serif;28            background-color: var(--bg-primary);29            color: var(--text-primary);30            overflow: hidden;31            -webkit-font-smoothing: antialiased;32            -moz-osx-font-smoothing: grayscale;33        }34        body.is-resizing {35            cursor: ew-resize !important;36            user-select: none !important;37        }38        body.is-resizing * {39            transition: none !important;40            pointer-events: none !important;41        }42        ::-webkit-scrollbar {43            width: 8px;44            height: 8px;45        }46        ::-webkit-scrollbar-track {47            background: var(--bg-primary);48        }49        ::-webkit-scrollbar-thumb {50            background: var(--bg-tertiary);51            border-radius: 4px;52        }53        ::-webkit-scrollbar-thumb:hover {54            background: var(--accent-green);55        }56        .ace_editor {57            font-family: 'Inconsolata', monospace !important;58            font-size: 15px !important;59            line-height: 1.6 !important;60        }61        .ace-tomorrow_night {62            background-color: var(--bg-secondary) !important;63            color: var(--text-primary) !important;64        }65        .ace_gutter {66            background: var(--bg-primary) !important;67            color: var(--text-secondary) !important;68        }69        .ace-tomorrow_night .ace_cursor {70            border-left: 2px solid var(--accent-green) !important;71        }72        .ace-tomorrow_night .ace_marker-layer .ace_selection {73            background: rgba(45,212,191,0.25);74        }75        .ace-tomorrow_night .ace_active-line {76            background-color: rgba(255,255,255,0.04);77        }78        .ace-tomorrow_night .ace_gutter-active-line {79            background-color: var(--accent-green-light);80        }81        .ace_print-margin {82            display: none;83        }84        .ui-panel {85            background-color: rgba(39,39,42,0.8);86            border: 1px solid var(--border-color);87            backdrop-filter: blur(8px);88        }89        .tab-button {90            background-color: rgba(255,255,255,0.05);91            border: 1px solid transparent;92            transition: all .2s ease-in-out;93        }94        .tab-button:hover {95            background-color: rgba(255,255,255,0.1);96            border-color: var(--border-color);97        }98        .tab-button.active,99        .tab-button.glow {100            color: var(--accent-green);101            border-color: var(--accent-green);102            background-color: var(--accent-green-light);103            box-shadow: 0 0 8px rgba(45,212,191,0.3);104        }105        .list-item.active {106            border-color: var(--accent-green) !important;107            background-color: var(--accent-green-light);108        }109        .list-item:hover {110            border-color: rgba(45,212,191,0.5);111        }112        .history-entry.active {113            background-color: rgba(45,212,191,0.15);114            border-color: var(--accent-green) !important;115        }116        [x-cloak] {117            display: none !important;118        }119        #divider {120            z-index: 20;121            cursor: ew-resize;122            transition: all 0.2s ease;123        }124        #divider::before {125            content: '';126            position: absolute;127            top: 50%;128            left: 50%;129            transform: translate(-50%, -50%);130            width: 20px;131            height: 20px;132            background: radial-gradient(circle, rgba(45,212,191,0.15) 0%, transparent 70%);133            border-radius: 50%;134            opacity: 0;135            pointer-events: none;136        }137        #divider:hover::before,138        body.is-resizing #divider::before {139            opacity: 1;140        }141        #divider:hover .divider-line,142        body.is-resizing .divider-line {143            background-color: var(--accent-green) !important;144        }145    </style>146</head>147<body class="h-screen w-screen text-sm p-2.5" x-data="app()" x-init="init()" x-cloak>148    <div class="h-full w-full flex flex-col gap-2.5">149        <main class="flex-1 flex overflow-hidden">150            <aside class="ui-panel flex-shrink-0 flex flex-col rounded-lg transition-all duration-300 ease-in-out" :class="{'w-64 md:w-72 mr-2.5': sbVis, 'w-0': !sbVis, 'p-0 border-0': !sbVis}">151                <div class="flex-1 p-2 space-y-2 overflow-y-auto" :class="{'hidden': !sbVis}">152                    <template x-if="loading">153                        <div class="flex flex-col items-center justify-center h-full text-text-secondary">154                            <div class="w-8 h-8 border-2 border-dashed rounded-full animate-spin border-accent-green"></div>155                            <p class="mt-4 text-xs">Loading projects...</p>156                        </div>157                    </template>158                    <template x-if="!loading && p.length === 0">159                        <div class="text-center text-text-secondary p-4">Start typing in the editor to create a new project.</div>160                    </template>161                    <template x-for="item in p" :key="item.id">162                        <div class="list-item flex flex-col rounded-md border border-transparent transition-colors duration-200" :class="{'active': item.id === sId}">163                            <div class="flex items-center p-3 cursor-pointer gap-3" @click="selP(item.id)">164                                <div class="flex-1 overflow-hidden">165                                    <template x-if="eId === item.id">166                                        <input class="w-full bg-bg-primary border border-accent-green rounded px-2 py-1 text-base" :value="item.name" @click.stop @blur="endEdit(item.id, $event.target.value)" @keydown.enter="$event.target.blur()" x-init="$nextTick(() => $el.focus())">167                                    </template>168                                    <template x-if="eId !== item.id">169                                        <div>170                                            <h3 class="font-bold truncate" @dblclick.stop="startEdit(item.id)" x-text="item.name"></h3>171                                            <p class="text-xs text-text-secondary truncate opacity-75" x-text="`${new Date(item.createdAt).toLocaleString()}`"></p>172                                            <p class="text-xs text-text-secondary truncate mt-1" x-text="getPrev(item.id)"></p>173                                        </div>174                                    </template>175                                </div>176                                <div class="flex items-center gap-2 text-text-secondary flex-shrink-0">177                                    <button title="History" @click.stop="togH(item.id)" class="w-7 h-7 hover:text-accent-green"><i class="fas fa-history"></i></button>178                                    <button title="Delete" @click.stop="delP(item.id)" class="w-7 h-7 hover:text-error-color"><i class="fas fa-trash-alt"></i></button>179                                </div>180                            </div>181                            <div x-show="expHId === item.id" class="max-h-48 overflow-y-auto border-t border-border-color bg-black/20" x-transition>182                                <template x-if="!h[item.id] || h[item.id].history.length === 0">183                                    <div class="p-3 text-center text-xs text-text-secondary">No history found.</div>184                                </template>185                                <template x-for="(entry, index) in [...(h[item.id]?.history || [])].reverse()" :key="entry.ts">186                                    <div class="history-entry flex justify-between items-center p-2 border-b border-border-color/50 last:border-b-0 hover:bg-black/20" :title="new Date(entry.ts).toLocaleString()" :class="{'active': h[item.id].selIdx === (h[item.id].history.length - 1 - index)}">187                                        <div class="text-xs overflow-hidden">188                                            <div class="font-semibold" x-text="new Date(entry.ts).toLocaleString()"></div>189                                            <div class="text-text-secondary truncate" x-text="entry.c.substring(0,30) + '...'"></div>190                                        </div>191                                        <button @click.stop="loadH(item.id, h[item.id].history.length - 1 - index)" class="text-xs px-2 py-1 rounded bg-bg-tertiary hover:bg-accent-green flex-shrink-0 ml-2">Load</button>192                                    </div>193                                </template>194                            </div>195                        </div>196                    </template>197                </div>198                <div class="flex-shrink-0 p-3 border-t border-border-color" :class="{'hidden': !sbVis}">199                    <button @click="newP()" title="New Project" class="w-full flex items-center justify-center gap-2 h-10 rounded-md border text-accent-green border-accent-green bg-accent-green-light hover:bg-opacity-20 transition-all duration-200">200                        <i class="fas fa-plus"></i>201                        <span class="font-semibold">New Project</span>202                    </button>203                </div>204            </aside>205            <div x-ref="edWrap" class="flex-1 relative flex rounded-lg">206                <div id="ed-cont" class="relative h-full bg-bg-secondary transition-all duration-300 ease-in-out" :style="{ width: codeVis ? `${edW * 100}%` : '0%', display: codeVis ? 'block' : 'none' }">207                    <div id="code-ed" class="h-full w-full rounded-l-lg"></div>208                </div>209                <div id="divider"210                     class="absolute top-0 h-full w-2.5 cursor-ew-resize"211                     :style="{ left: `calc(${edW * 100}% - 5px)` }"212                     x-show="codeVis"213                     @pointerdown="startDrag($event)">214                    <div class="divider-line h-full w-0.5 bg-border-color mx-auto transition-colors duration-200"></div>215                </div>216                <div id="prev-cont" class="h-full bg-white transition-all duration-300 ease-in-out" :class="{'rounded-r-lg': codeVis, 'rounded-lg': !codeVis}" :style="{ width: codeVis ? `${(1 - edW) * 100}%` : '100%' }">217                    <iframe id="prev-frame" class="w-full h-full border-none" :class="{'rounded-r-lg': codeVis, 'rounded-lg': !codeVis}"></iframe>218                </div>219            </div>220        </main>221        <footer class="ui-panel h-12 flex-shrink-0 flex items-center justify-between rounded-lg px-3">222            <div class="flex items-center gap-1">223                <button @click="togSb()" class="tab-button p-2 rounded-md" :class="{'glow': sbVis}" title="Toggle Menu"><i class="fas fa-bars"></i></button>224                <button @click="togCode()" class="tab-button p-2 rounded-md" :class="{'active': codeVis}" title="Toggle Code Editor"><i class="fas fa-code"></i></button>225            </div>226            <div class="flex items-center gap-2">227                <button @click="logVis = !logVis" class="tab-button relative px-2.5 py-1.5 rounded-md" :class="{'glow': logVis}" title="View Console Logs">228                    <i class="fas fa-bug mr-1.5"></i>229                    <span x-show="errCt > 0" x-transition.scale class="absolute -top-1 -right-1 bg-error-color text-white text-[9px] w-4 h-4 rounded-full flex items-center justify-center font-bold border-1 border-bg-tertiary" x-text="errCt > 9 ? '9+' : errCt"></span>230                </button>231            </div>232        </footer>233    </div>234    <div x-show="logVis"235         x-transition:enter="transition ease-out duration-200"236         x-transition:enter-start="opacity-0 translate-y-4"237         x-transition:enter-end="opacity-100 translate-y-0"238         x-transition:leave="transition ease-in duration-150"239         x-transition:leave-start="opacity-100 translate-y-0"240         x-transition:leave-end="opacity-0 translate-y-4"241         class="fixed bottom-20 right-4 z-[9999] w-full max-w-lg ui-panel rounded-lg shadow-2xl">242        <div class="flex items-center justify-between p-3 border-b border-border-color">243            <h3 class="font-bold text-text-primary">Console Logs</h3>244            <button @click="logVis = false" class="text-text-secondary hover:text-white transition-all"><i class="fas fa-times"></i></button>245        </div>246        <div class="p-3 max-h-80 overflow-y-auto text-xs space-y-3">247            <template x-for="lg in logs.slice().reverse()" :key="lg.ts">248                <div class="border-l-4 pl-3" :class="lg.t === 'error' ? 'border-error-color' : 'border-accent-green'">249                    <div class="flex justify-between items-start">250                        <div class="font-bold break-words" :class="lg.t === 'error' ? 'text-error-color' : 'text-accent-green'" x-text="lg.m"></div>251                        <div class="text-xs text-text-secondary whitespace-nowrap ml-4" x-text="new Date(lg.ts).toLocaleTimeString()"></div>252                    </div>253                    <div class="text-xs text-text-secondary mt-1" x-text="`Source: ${lg.s}`"></div>254                    <template x-if="lg.stk">255                        <pre class="mt-2 p-2 bg-black/30 rounded-md text-text-secondary text-[11px] leading-relaxed whitespace-pre-wrap break-all" x-text="lg.stk"></pre>256                    </template>257                </div>258            </template>259            <template x-if="logs.length === 0">260                <div class="text-text-secondary text-center py-4">No logs yet. Errors from your code will appear here.</div>261            </template>262        </div>263    </div>264    <script>265        function app() {266            return {267                p: [],268                h: {},269                sId: null,270                eId: null,271                expHId: null,272                loading: true,273                sbVis: true,274                codeVis: true,275                logVis: false,276                edW: 0.5,277                logs: [],278                errCt: 0,279                ed: null,280                prevT: null,281                saveT: null,282                K: {283                    PREV_D: 300,284                    HIST_D: 1500,285                    MAX_H: 50,286                    ITEMS: 'LBE_OC_p',287                    HISTS: 'LBE_OC_h',288                    LAST: 'LBE_OC_last',289                    EDW: 'LBE_OC_edW',290                    SBV: 'LBE_OC_sbv',291                    CDV: 'LBE_OC_cdv'292                },293                init() {294                    this.loadUi();295                    this.setupErr();296                    this.initEd();297                    this.load();298                    this.$watch('logVis', v => { if (v) this.errCt = 0 });299                    this.$watch('sbVis', v => {300                        localStorage.setItem(this.K.SBV, JSON.stringify(v));301                        this.$nextTick(() => this.ed?.resize());302                    });303                    this.$watch('codeVis', v => {304                        localStorage.setItem(this.K.CDV, JSON.stringify(v));305                        this.$nextTick(() => this.ed?.resize());306                    });307                },308                loadUi() {309                    this.edW = parseFloat(localStorage.getItem(this.K.EDW) || 0.5);310                    this.sbVis = JSON.parse(localStorage.getItem(this.K.SBV) ?? (window.innerWidth > 768));311                    this.codeVis = JSON.parse(localStorage.getItem(this.K.CDV) ?? true);312                },313                setupErr() {314                    window.onerror = (m, s, l, c, e) => {315                        this.log(m, `${s.split('/').pop()}:${l}:${c}`, 'error', e);316                        return true;317                    };318                    window.addEventListener('unhandledrejection', e => {319                        const r = e.reason || 'Unhandled promise rejection';320                        this.log(r.message || r, 'Promise', 'error', r);321                        e.preventDefault();322                    });323                    window.addEventListener('beforeunload', () => this.saveOnExit());324                    window.addEventListener('message', e => {325                        if (e.data?.type === 'iframeError') {326                            this.log(e.data.payload.message, 'iframe', 'error', e.data.payload);327                        }328                    });329                },330                initEd() {331                    this.ed = ace.edit("code-ed");332                    this.ed.setTheme("ace/theme/tomorrow_night");333                    this.ed.session.setMode("ace/mode/html");334                    this.ed.setShowPrintMargin(false);335                    this.ed.setOptions({336                        enableBasicAutocompletion: true,337                        enableLiveAutocompletion: true,338                        tabSize: 2,339                        useSoftTabs: true,340                        wrap: true341                    });342                    this.ed.on('change', () => this.onEdChg());343                },344                onEdChg() {345                    const c = this.ed.getValue();346                    if (!this.sId && c.trim()) {347                        const i = `p_${Date.now()}`;348                        this.p.unshift({349                            id: i,350                            name: `Project ${this.p.length + 1}`,351                            createdAt: new Date().toISOString()352                        });353                        this.h[i] = { c: '', history: [] };354                        this.sId = i;355                        localStorage.setItem(this.K.LAST, this.sId);356                    }357                    clearTimeout(this.prevT);358                    this.prevT = setTimeout(() => this.updPrev(c), this.K.PREV_D);359                    clearTimeout(this.saveT);360                    this.saveT = setTimeout(() => this.saveH(c), this.K.HIST_D);361                },362                load() {363                    try {364                        this.p = JSON.parse(localStorage.getItem(this.K.ITEMS) || "[]");365                        this.h = JSON.parse(localStorage.getItem(this.K.HISTS) || "{}");366                        this.sId = localStorage.getItem(this.K.LAST);367                        this.p.sort((a, b) => new Date(b.createdAt) - new Date(a.createdAt));368                        if (!this.p.find(i => i.id === this.sId)) {369                            this.sId = this.p[0]?.id || null;370                        }371                        this.sId ? this.loadCont() : this.clearEd();372                    } catch (e) {373                        this.log('Failed to load data from storage. Resetting.', 'App Init', 'error', e);374                        localStorage.clear();375                        this.p = [];376                        this.h = {};377                        this.sId = null;378                        this.clearEd();379                    } finally {380                        this.loading = false;381                    }382                },383                save() {384                    try {385                        localStorage.setItem(this.K.ITEMS, JSON.stringify(this.p));386                        localStorage.setItem(this.K.HISTS, JSON.stringify(this.h));387                        if (this.sId) localStorage.setItem(this.K.LAST, this.sId);388                    } catch (e) {389                        this.log('Storage quota exceeded or other save error.', 'save', 'error', e);390                    }391                },392                saveOnExit() {393                    this.save();394                },395                newP(s = true) {396                    const i = `p_${Date.now()}`;397                    this.p.unshift({398                        id: i,399                        name: `Project ${this.p.length + 1}`,400                        createdAt: new Date().toISOString()401                    });402                    this.h[i] = { c: '', history: [] };403                    this.selP(i);404                    s && this.save();405                },406                delP(i) {407                    if (!confirm(`Delete "${this.p.find(p => p.id === i)?.name || 'this item'}"? This is irreversible.`)) return;408                    this.p = this.p.filter(p => p.id !== i);409                    delete this.h[i];410                    if (this.sId === i) {411                        this.sId = this.p[0]?.id || null;412                        this.selP(this.sId);413                    }414                    this.save();415                },416                selP(i) {417                    if (this.sId === i) return;418                    this.sId = i;419                    this.eId = null;420                    this.expHId = null;421                    if (this.sId) {422                        this.loadCont();423                        localStorage.setItem(this.K.LAST, this.sId);424                    } else {425                        this.clearEd();426                        localStorage.removeItem(this.K.LAST);427                    }428                },429                loadCont() {430                    if (!this.sId || !this.h[this.sId]) return this.clearEd();431                    const { c = '' } = this.h[this.sId];432                    this.ed.session.off('change');433                    this.ed.setValue(c, -1);434                    this.ed.session.getUndoManager().reset();435                    this.updPrev(c);436                    this.ed.session.on('change', () => this.onEdChg());437                },438                clearEd() {439                    this.ed?.setValue('', -1);440                    document.getElementById('prev-frame').srcdoc = `441                        <body style="background-color:#fff;color:#18181b;font-family:sans-serif;padding:2rem;display:grid;place-content:center;height:100vh;margin:0;text-align:center;">442                            <h1>Preview Area</h1>443                            <p style="color:#555;">Start typing to create your first project.</p>444                        </body>445                    `;446                },447                saveH(c) {448                    if (!this.sId || !this.h[this.sId]) return;449                    const d = this.h[this.sId];450                    d.c = c;451                    const last = d.history[d.history.length - 1];452                    if (!last || last.c !== c) {453                        d.history.push({ ts: Date.now(), c });454                        if (d.history.length > this.K.MAX_H) d.history.shift();455                        delete d.selIdx;456                    }457                    this.save();458                },459                loadH(i, x) {460                    const e = this.h[i]?.history[x];461                    if (!e || !this.ed) return;462                    this.ed.session.off('change');463                    this.ed.setValue(e.c, -1);464                    this.updPrev(e.c);465                    this.h[i].selIdx = x;466                    this.h[i].c = e.c;467                    this.ed.session.on('change', () => this.onEdChg());468                    this.save();469                },470                startEdit(i) {471                    this.eId = i;472                },473                endEdit(i, n) {474                    const t = this.p.find(p => p.id === i);475                    if (t && n.trim()) t.name = n.trim();476                    this.eId = null;477                    this.save();478                },479                togH(i) {480                    this.expHId = this.expHId === i ? null : i;481                },482                togSb() {483                    this.sbVis = !this.sbVis;484                },485                togCode() {486                    this.codeVis = !this.codeVis;487                },488                getPrev(i) {489                    return this.h[i]?.c?.trim().split('\n')[0].replace(/<[^>]+>/g, '') || 'No content yet';490                },491                startDrag(e) {492                    e.preventDefault();493                    const iframe = document.getElementById('prev-frame');494                    iframe.style.pointerEvents = 'none';495                    document.body.classList.add('is-resizing');496                    const wrap = this.$refs.edWrap;497                    const rect = wrap.getBoundingClientRect();498                    const initialX = e.clientX || e.touches[0].clientX;499                    const initialW = this.edW;500                    const moveHandler = (e) => {501                        e.preventDefault();502                        const clientX = e.clientX || e.touches[0].clientX;503                        const dx = (clientX - initialX) / rect.width;504                        let newW = initialW + dx;505                        newW = Math.max(0, Math.min(newW, 1));506                        this.edW = newW;507                        this.ed.resize();508                    };509                    const upHandler = () => {510                        document.body.classList.remove('is-resizing');511                        iframe.style.pointerEvents = 'auto';512                        localStorage.setItem(this.K.EDW, this.edW);513                        document.removeEventListener('pointermove', moveHandler);514                        document.removeEventListener('touchmove', moveHandler);515                        document.removeEventListener('pointerup', upHandler);516                        document.removeEventListener('touchend', upHandler);517                    };518                    document.addEventListener('pointermove', moveHandler, { passive: false });519                    document.addEventListener('touchmove', moveHandler, { passive: false });520                    document.addEventListener('pointerup', upHandler, { once: true });521                    document.addEventListener('touchend', upHandler, { once: true });522                },523                updPrev(c) {524                    const frame = document.getElementById('prev-frame');525                    const script = `<script>526                        window.onerror = (m,s,l,c,e)=>{parent.postMessage({type:'iframeError',payload:{message:m,source:s,lineno:l,colno:c,stack:e?.stack}},'*');return true;};527                        window.addEventListener('unhandledrejection', e=>{528                            parent.postMessage({type:'iframeError',payload:{message:e.reason?.message||'Unhandled',source:'Promise',lineno:0,colno:0,stack:e.reason?.stack}},'*');529                            e.preventDefault();530                        });531                    <\/script>`;532                    const html = c.includes('<html') || c.includes('<body') ? c : 533                      `534                      <!DOCTYPE html>535                      <html lang="en">536                      <head> 537                      <meta charset="UTF-8"> 538                      <meta name="viewport" content="width=device-width, initial-scale=1.0"> 539                      <title>Hello</title> 540                      <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css">541                      <script src="https://cdn.tailwindcss.com"><\/script>542                      </head>543                      <body class="bg-gray-100 flex items-center justify-center min-h-screen"> 544                      <div class="text-center"> 545                      <h1 class="text-5xl font-bold text-blue-600 animate-bounce">Hello!🤗</h1> 546                      <p class="mt-4 text-lg text-gray-700">Welcome to this simple website.</p> 547                      </div>548                      </body>549                      </html> 550                      `;551                    frame.srcdoc = html + script;552                },553                log(m, s = 'unknown', t = 'info', e = {}) {554                    const entry = {555                        m: m.toString(),556                        s: s,557                        t: t,558                        ts: Date.now(),559                        stk: e?.stack || (e.payload ? e.payload.stack : null)560                    };561                    this.logs.push(entry);562                    if (this.logs.length > 100) this.logs.shift();563                    if (t === 'error' && !this.logVis) this.errCt++;564                }565            };566        }567    </script>568</body>569</html>