web_plsql 1.3.0 → 1.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- :root{--accent-rgb: 59, 130, 246;--bg-main: #f8fafc;--bg-side: #fff;--bg-card: #fff;--bg-hover: #f1f5f9;--text-main: #475569;--text-bright: #0f172a;--accent: #3b82f6;--border: #e2e8f0;--success: #10b981;--warning: #f59e0b;--danger: #ef4444;--shadow: 0 1px 3px 0 rgb(0 0 0 / .1), 0 1px 2px -1px rgb(0 0 0 / .1);--terminal-bg: #1e293b;--config-key: #3b82f6}body.dark{--bg-main: #0f172a;--bg-side: #1e293b;--bg-card: #1e293b;--bg-hover: #334155;--text-main: #94a3b8;--text-bright: #f8fafc;--accent: #3b82f6;--border: #334155;--success: #10b981;--warning: #f59e0b;--danger: #ef4444;--shadow: 0 4px 6px -1px rgb(0 0 0 / .1), 0 2px 4px -2px rgb(0 0 0 / .1);--terminal-bg: #000;--config-key: #60a5fa}body{margin:0;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica,Arial,sans-serif;background-color:var(--bg-main);color:var(--text-main);-webkit-font-smoothing:antialiased;transition:background-color .3s,color .3s}.app-container{display:flex;height:100vh}.sidebar{width:240px;background-color:var(--bg-side);border-right:1px solid var(--border);display:flex;flex-direction:column;z-index:10}.logo{padding:24px;font-weight:700;font-size:1.25rem;color:var(--text-bright);display:flex;align-items:center;gap:12px}.logo .material-symbols-rounded{color:var(--accent);font-size:28px}nav{flex:1;padding:12px}.status-indicator{padding:20px;border-top:1px solid var(--border);display:flex;align-items:center;font-size:.85rem;font-weight:500}.dot{height:8px;width:8px;background-color:#64748b;border-radius:50%;display:inline-block;margin-right:12px;box-shadow:0 0 0 4px #64748b1a}.dot.running{background-color:var(--success);box-shadow:0 0 0 4px #10b98133}.dot.paused{background-color:var(--warning);box-shadow:0 0 0 4px #f59e0b33}.content{flex:1;display:flex;flex-direction:column;overflow:hidden}.main-header{padding:20px 32px;background-color:var(--bg-main);border-bottom:1px solid var(--border);display:flex;justify-content:space-between;align-items:center}.main-header h1{margin:0;font-size:1.5rem;color:var(--text-bright);font-weight:600;display:flex;align-items:center;gap:12px}.main-header h1 .material-symbols-rounded{color:var(--accent);font-size:28px}.header-toolbar{display:flex;align-items:center;gap:24px}.auto-refresh-group{display:flex;align-items:center;gap:12px;font-size:.875rem;background:var(--bg-side);padding:6px 12px;border-radius:6px;border:1px solid var(--border)}.auto-refresh-group select{background:none;border:none;color:var(--text-bright);cursor:pointer;font-weight:500}.view{flex:1;padding:32px;overflow-y:auto}.metrics-grid,.pools-grid,.cache-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(280px,1fr));gap:24px;margin-bottom:32px}.card{background-color:var(--bg-card);padding:24px;border-radius:12px;border:1px solid var(--border);box-shadow:var(--shadow)}.card-header{display:flex;align-items:center;gap:12px;margin-bottom:16px}.card-header .material-symbols-rounded{color:var(--accent)}.card h3{margin:0;font-size:.875rem;text-transform:uppercase;letter-spacing:.05em;color:var(--text-main)}.card p{font-size:2rem;font-weight:700;margin:0;color:var(--text-bright)}.card small{display:block;margin-top:8px;font-size:.875rem;color:var(--text-main)}.card.warning{border-left:4px solid var(--warning)}.table-container{background:var(--bg-card);border-radius:12px;border:1px solid var(--border);overflow:hidden;box-shadow:var(--shadow)}table{width:100%;border-collapse:collapse}th,td{padding:16px 24px;text-align:left;border-bottom:1px solid var(--border)}th{background-color:var(--bg-hover);color:var(--text-main);font-size:.75rem;text-transform:uppercase;letter-spacing:.05em;font-weight:600}td{color:var(--text-bright);font-size:.9375rem}tr:last-child td{border-bottom:none}.terminal-container,.config-container{background-color:var(--bg-side);border-radius:12px;border:1px solid var(--border);overflow:hidden;box-shadow:var(--shadow)}.terminal{background-color:var(--terminal-bg);color:#10b981;padding:24px;font-family:JetBrains Mono,Fira Code,monospace;font-size:.875rem;line-height:1.6;margin:0;overflow-x:auto;white-space:pre}.config-view-content{padding:0;max-width:900px;margin:0 auto}.config-table{width:100%;border-collapse:collapse}.config-table tr{border-bottom:1px solid var(--border)}.config-table tr:last-child{border-bottom:none}.config-table td{padding:16px 24px;vertical-align:top}.config-label{font-weight:600;color:var(--text-main);width:240px;font-size:.875rem;background-color:var(--bg-main)}.config-value{font-family:JetBrains Mono,monospace;color:var(--text-bright);word-break:break-all;font-size:.875rem}.config-section-header{background-color:var(--bg-hover);padding:12px 24px;font-weight:700;font-size:.75rem;text-transform:uppercase;color:var(--accent);letter-spacing:.05em;border-bottom:1px solid var(--border)}.inner-config-table{width:100%;border-collapse:collapse;font-size:.8125rem}.inner-config-table td{padding:4px 8px;border:none}.cache-card .badge{align-self:center}.card-header h4{color:var(--accent)}.stat-row-label{flex:0 0 180px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.stat-row-value{flex:1;text-align:right}@media(max-width:640px){.stat-row{flex-direction:column;align-items:flex-start;gap:4px}.stat-row-label{flex:none;opacity:.7;font-size:.75rem;text-align:left}.stat-row-value{text-align:left;width:100%}}.view-system-compact{padding:20px 32px}.view-system-compact .metrics-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(300px,1fr));gap:16px;align-items:start;margin-bottom:24px}.view-system-compact .card{padding:16px}.view-system-compact .stat-row{padding:4px 0}.view-system-compact .card-header{margin-bottom:12px}.resource-card{display:flex;flex-direction:column;min-height:350px}.resource-card .chart-container-mini{margin-top:auto}.chart-container-mini{height:100px;width:100%;position:relative;overflow:hidden;border:none;border-radius:4px}.chart-container{margin-bottom:32px;height:300px;position:relative}.btn,.icon-btn{display:inline-flex;align-items:center;justify-content:center;gap:8px;padding:10px 20px;border-radius:8px;font-weight:600;font-size:.875rem;cursor:pointer;border:none;transition:all .2s;background-color:var(--bg-hover);color:var(--text-bright)}.btn .material-symbols-rounded,.icon-btn .material-symbols-rounded{font-size:18px}.btn:hover,.icon-btn:hover{background-color:var(--border)}.btn-primary{background-color:var(--accent);color:#fff}.btn-primary:hover{opacity:.9;background-color:var(--accent)}.btn-success{background-color:var(--success);color:#fff}.btn-success:hover{opacity:.9}.btn-warning{background-color:var(--warning);color:#000}.btn-warning:hover{opacity:.9}.btn-danger{background-color:var(--danger);color:#fff}.btn-danger:hover{opacity:.9}.btn-outline{background:transparent;border:1px solid var(--border);color:var(--accent)}.btn-outline:hover{background-color:var(--bg-hover)}.btn-full{width:100%}.btn-sm{padding:6px 12px;font-size:.8125rem}.btn-sm .material-symbols-rounded{font-size:16px}.btn-lg{padding:14px 28px;font-size:1rem}.btn-lg .material-symbols-rounded{font-size:22px}nav button{width:100%;padding:12px 16px;text-align:left;background:none;border:none;color:var(--text-main);cursor:pointer;font-size:.95rem;display:flex;align-items:center;gap:12px;border-radius:8px;transition:all .2s;margin-bottom:4px}nav button:hover{background-color:var(--bg-hover);color:var(--text-bright)}nav button.active{background-color:var(--accent);color:#fff}nav button .material-symbols-rounded{font-size:20px}.icon-btn{padding:10px;min-width:40px;min-height:40px}.icon-btn.icon-sm{padding:6px;min-width:32px;min-height:32px}.icon-btn.icon-sm .material-symbols-rounded{font-size:20px}.control-group{display:flex;gap:16px;margin-top:24px;flex-wrap:wrap}.control-group .btn{flex:1;min-width:140px}.gap-1{gap:4px}.mt-1{margin-top:4px}.mt-2{margin-top:8px}.mt-3{margin-top:12px}.mt-4{margin-top:16px}.mt-6{margin-top:24px}.mb-1{margin-bottom:4px}.mb-2{margin-bottom:8px}.mb-3{margin-bottom:12px}.mb-4{margin-bottom:16px}.mb-6{margin-bottom:24px}.p-2{padding:8px}.p-3{padding:12px}.p-4{padding:16px}.p-6{padding:24px}.mx-auto{margin-left:auto;margin-right:auto}.flex{display:flex}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-center{align-items:center}.items-baseline{align-items:baseline}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.justify-end{justify-content:flex-end}.self-center{align-self:center}.self-end{align-self:flex-end}.text-xs{font-size:.75rem}.text-sm{font-size:.875rem}.text-lg{font-size:1.125rem}.text-xl{font-size:1.25rem}.text-2xl{font-size:1.5rem}.text-3xl{font-size:1.875rem}.font-medium{font-weight:500}.font-semibold{font-weight:600}.font-bold{font-weight:700}.text-center{text-align:center}.text-right{text-align:right}.text-main{color:var(--text-main)}.text-bright{color:var(--text-bright)}.text-accent{color:var(--accent)}.text-success{color:var(--success)}.text-warning{color:var(--warning)}.text-danger{color:var(--danger)}.bg-main{background-color:var(--bg-main)}.bg-card{background-color:var(--bg-card)}.bg-hover{background-color:var(--bg-hover)}.bg-success{background-color:var(--success)}.bg-warning{background-color:var(--warning)}.bg-danger{background-color:var(--danger)}.border{border:1px solid var(--border)}.border-b{border-bottom:1px solid var(--border)}.border-none{border:none}.border-t{border-top:1px solid var(--border)}.border-l{border-left:1px solid var(--border)}.border-r{border-right:1px solid var(--border)}.rounded{border-radius:4px}.rounded-md{border-radius:6px}.rounded-lg{border-radius:8px}.rounded-xl{border-radius:12px}.rounded-full{border-radius:9999px}.shadow-sm{box-shadow:var(--shadow)}.shadow-md{box-shadow:0 4px 6px -1px #0000001a,0 2px 4px -2px #0000001a}.w-full{width:100%}.w-auto{width:auto}.max-w-xs{max-width:120px}.max-w-sm{max-width:200px}.max-w-md{max-width:280px}.overflow-hidden{overflow:hidden}.overflow-auto{overflow:auto}.overflow-x-auto{overflow-x:auto}.cursor-pointer{cursor:pointer}.transition{transition:all .2s ease}.transition-colors{transition:background-color .2s,color .2s,border-color .2s}.transition-all{transition:all .2s ease}.duration-200{transition-duration:.2s}.duration-300{transition-duration:.3s}.hover-bg:hover{background-color:var(--bg-hover)}.hover-border:hover{border-color:var(--accent)}.opacity-50{opacity:.5}.opacity-75{opacity:.75}.opacity-90{opacity:.9}.leading-tight{line-height:1.25}.leading-normal{line-height:1.5}.leading-relaxed{line-height:1.625}.whitespace-normal{white-space:normal}.whitespace-nowrap{white-space:nowrap}.break-all{word-break:break-all}.grid{display:grid}.grid-cols-2{grid-template-columns:repeat(2,1fr)}.grid-cols-3{grid-template-columns:repeat(3,1fr)}.grid-cols-auto{grid-template-columns:repeat(auto-fit,minmax(120px,1fr))}.gap-2{gap:8px}.gap-3{gap:12px}.gap-4{gap:16px}.gap-6{gap:24px}.stat-card{background-color:var(--bg-card);padding:16px;border-radius:8px;border:1px solid var(--border);text-align:center}.stat-card-value{font-size:1.75rem;font-weight:700;color:var(--text-bright);line-height:1.2}.stat-card-label{font-size:.75rem;text-transform:uppercase;letter-spacing:.05em;color:var(--text-main);margin-top:4px}.progress-bar{height:6px;background:var(--bg-main);border-radius:3px;overflow:hidden}.progress-bar-fill{height:100%;border-radius:3px;transition:width .3s ease}.progress-bar-sm{height:4px}.progress-bar-lg{height:8px}.badge{display:inline-flex;align-items:center;padding:4px 8px;border-radius:9999px;font-size:.75rem;font-weight:600;gap:4px}.badge-success{background-color:#10b98126;color:var(--success)}.badge-warning{background-color:#f59e0b26;color:var(--warning)}.badge-danger{background-color:#ef444426;color:var(--danger)}.badge-info{background-color:#3b82f626;color:var(--accent)}.status-dot{display:inline-flex;align-items:center;gap:6px;font-size:.875rem;font-weight:500}.status-dot .dot{margin:0;flex-shrink:0}.table-row-hover tbody tr{transition:background-color .15s ease}.table-row-hover tbody tr:hover{background-color:var(--bg-hover)}.table-cell{padding:12px 16px;text-align:left;border-bottom:1px solid var(--border)}.table-cell-sm{padding:8px 12px;font-size:.8125rem}.table-header{background-color:var(--bg-hover);color:var(--text-main);font-size:.75rem;text-transform:uppercase;letter-spacing:.05em;font-weight:600;padding:12px 16px;text-align:left}.dense-table th,.dense-table td{padding:6px 12px;font-size:.8125rem}.table-layout-auto{table-layout:auto}.table-layout-fixed{table-layout:fixed}.code{font-family:JetBrains Mono,Fira Code,monospace;font-size:.875rem;background-color:var(--bg-main);padding:2px 6px;border-radius:4px;color:var(--accent)}.code-sm{font-size:.75rem;padding:1px 4px}.description{font-size:.75rem;color:var(--text-main);font-weight:400}.stat-row{display:flex;justify-content:space-between;align-items:center;padding:8px 0;border-bottom:1px solid var(--border)}.stat-row:last-child{border-bottom:none}.stat-row-label{color:var(--text-main);font-size:.875rem}.stat-row-value{color:var(--text-bright);font-weight:600;font-family:monospace}.card-section{margin-bottom:24px}.card-section:last-child{margin-bottom:0}.card-clickable{cursor:pointer;transition:all .2s ease}.card-clickable:hover{border-color:var(--accent);box-shadow:0 4px 12px #3b82f626}.icon-xs{font-size:14px}.icon-sm{font-size:18px}.icon-md{font-size:20px}.icon-lg{font-size:24px}.icon-xl{font-size:28px}.modal{position:fixed;inset:0;background-color:#000000b3;display:flex;align-items:center;justify-content:center;z-index:1000;padding:20px}.modal-content{background-color:var(--bg-card);border-radius:12px;width:100%;max-width:900px;box-shadow:var(--shadow);display:flex;flex-direction:column;max-height:90vh}.modal-header{padding:16px 24px;border-bottom:1px solid var(--border);display:flex;justify-content:space-between;align-items:center}.modal-header h3{margin:0;font-size:1.125rem;color:var(--text-bright)}.modal-body{padding:24px;overflow-y:auto}.stat-values-inline{display:flex;align-items:center;gap:8px}.stat-values{display:flex;flex-direction:column;align-items:flex-end}.min-max{font-size:.7rem;opacity:.7;margin-top:2px}.search-group{position:relative;display:flex;align-items:center}.input-sm{background-color:var(--bg-side);border:1px solid var(--border);border-radius:6px;color:var(--text-bright);padding:6px 12px;font-size:.875rem}.input-sm:focus{border-color:var(--accent);outline:none}.errors-table-row{cursor:pointer;transition:background-color .2s}.errors-table-row:hover{background-color:rgba(var(--accent-rgb),.08)}.server-status{display:flex;align-items:center;gap:8px;padding:8px 12px;background-color:var(--bg-card);border-radius:8px;border:1px solid var(--border)}.server-status-indicator{display:flex;align-items:center;gap:8px}.server-status-dot{width:10px;height:10px;border-radius:50%;flex-shrink:0}.server-status-dot.running{background-color:var(--success);box-shadow:0 0 8px #10b98166}.server-status-dot.paused{background-color:var(--warning);box-shadow:0 0 8px #f59e0b66}.server-status-dot.stopped{background-color:var(--danger);box-shadow:0 0 8px #ef444466}.server-status-text{font-size:.875rem;font-weight:500;text-transform:uppercase;letter-spacing:.025em}.danger-zone{border:1px solid var(--warning);border-left-width:4px;background-color:#f59e0b08}.danger-zone-title{color:var(--warning);font-weight:600;margin-bottom:8px}.empty-state{text-align:center;padding:48px 24px;color:var(--text-main)}.empty-state-icon{font-size:48px;color:var(--text-main);opacity:.5;margin-bottom:16px}.empty-state-text{font-size:.875rem}.skeleton{background:linear-gradient(90deg,var(--bg-main) 25%,var(--bg-hover) 50%,var(--bg-main) 75%);background-size:200% 100%;animation:skeleton-loading 1.5s infinite;border-radius:4px}@keyframes skeleton-loading{0%{background-position:200% 0}to{background-position:-200% 0}}::-webkit-scrollbar{width:8px;height:8px}::-webkit-scrollbar-track{background:var(--bg-main)}::-webkit-scrollbar-thumb{background:var(--border);border-radius:4px}::-webkit-scrollbar-thumb:hover{background:var(--text-main);opacity:.5}button:focus-visible,input:focus-visible,select:focus-visible{outline:2px solid var(--accent);outline-offset:2px}input[type=checkbox]{width:18px;height:18px;accent-color:var(--accent);cursor:pointer}select{accent-color:var(--accent);cursor:pointer}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.animate-spin{animation:spin 1s linear infinite;display:inline-block}.btn.loading{pointer-events:none;opacity:.8}@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-rotate-x:initial;--tw-rotate-y:initial;--tw-rotate-z:initial;--tw-skew-x:initial;--tw-skew-y:initial;--tw-border-style:solid;--tw-font-weight:initial;--tw-tracking:initial;--tw-blur:initial;--tw-brightness:initial;--tw-contrast:initial;--tw-grayscale:initial;--tw-hue-rotate:initial;--tw-invert:initial;--tw-opacity:initial;--tw-saturate:initial;--tw-sepia:initial;--tw-drop-shadow:initial;--tw-drop-shadow-color:initial;--tw-drop-shadow-alpha:100%;--tw-drop-shadow-size:initial;--tw-duration:initial}}}@layer theme{:root,:host{--font-sans:ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";--font-mono:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;--color-black:#000;--color-white:#fff;--spacing:.25rem;--text-xs:.75rem;--text-xs--line-height:calc(1/.75);--text-sm:.875rem;--text-sm--line-height:calc(1.25/.875);--text-lg:1.125rem;--text-lg--line-height:calc(1.75/1.125);--text-2xl:1.5rem;--text-2xl--line-height:calc(2/1.5);--text-3xl:1.875rem;--text-3xl--line-height: 1.2 ;--font-weight-medium:500;--font-weight-bold:700;--tracking-wider:.05em;--radius-lg:.5rem;--animate-spin:spin 1s linear infinite;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4,0,.2,1);--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono);--color-success:#10b981;--color-warning:#f59e0b;--color-danger:#ef4444}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;tab-size:4;line-height:1.5;font-family:var(--default-font-family,ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab,red,red)){::placeholder{color:color-mix(in oklab,currentcolor 50%,transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){appearance:button}::file-selector-button{appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}}@layer components;@layer utilities{.visible{visibility:visible}.fixed{position:fixed}.relative{position:relative}.static{position:static}.mt-2{margin-top:calc(var(--spacing)*2)}.mt-4{margin-top:calc(var(--spacing)*4)}.mt-6{margin-top:calc(var(--spacing)*6)}.mr-2{margin-right:calc(var(--spacing)*2)}.mb-2{margin-bottom:calc(var(--spacing)*2)}.mb-3{margin-bottom:calc(var(--spacing)*3)}.mb-4{margin-bottom:calc(var(--spacing)*4)}.mb-6{margin-bottom:calc(var(--spacing)*6)}.mb-8{margin-bottom:calc(var(--spacing)*8)}.ml-auto{margin-left:auto}.block{display:block}.flex{display:flex}.grid{display:grid}.inline-block{display:inline-block}.table{display:table}.w-full{width:100%}.max-w-\[150px\]{max-width:150px}.max-w-\[200px\]{max-width:200px}.max-w-\[300px\]{max-width:300px}.max-w-\[800px\]{max-width:800px}.transform{transform:var(--tw-rotate-x,)var(--tw-rotate-y,)var(--tw-rotate-z,)var(--tw-skew-x,)var(--tw-skew-y,)}.animate-spin{animation:var(--animate-spin)}.cursor-pointer{cursor:pointer}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.items-baseline{align-items:baseline}.items-center{align-items:center}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.gap-1{gap:calc(var(--spacing)*1)}.gap-2{gap:calc(var(--spacing)*2)}.gap-3{gap:calc(var(--spacing)*3)}.gap-4{gap:calc(var(--spacing)*4)}.gap-6{gap:calc(var(--spacing)*6)}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.rounded-lg{border-radius:var(--radius-lg)}.border{border-style:var(--tw-border-style);border-width:1px}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.border-white\/5{border-color:#ffffff0d}@supports (color:color-mix(in lab,red,red)){.border-white\/5{border-color:color-mix(in oklab,var(--color-white)5%,transparent)}}.bg-success{background-color:var(--color-success)}.bg-white\/10{background-color:#ffffff1a}@supports (color:color-mix(in lab,red,red)){.bg-white\/10{background-color:color-mix(in oklab,var(--color-white)10%,transparent)}}.px-4{padding-inline:calc(var(--spacing)*4)}.py-2{padding-block:calc(var(--spacing)*2)}.pt-4{padding-top:calc(var(--spacing)*4)}.text-center{text-align:center}.text-right{text-align:right}.font-mono{font-family:var(--font-mono)}.text-2xl{font-size:var(--text-2xl);line-height:var(--tw-leading,var(--text-2xl--line-height))}.text-3xl{font-size:var(--text-3xl);line-height:var(--tw-leading,var(--text-3xl--line-height))}.text-lg{font-size:var(--text-lg);line-height:var(--tw-leading,var(--text-lg--line-height))}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.font-bold{--tw-font-weight:var(--font-weight-bold);font-weight:var(--font-weight-bold)}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.tracking-wider{--tw-tracking:var(--tracking-wider);letter-spacing:var(--tracking-wider)}.break-all{word-break:break-all}.whitespace-nowrap{white-space:nowrap}.text-black{color:var(--color-black)}.text-danger{color:var(--color-danger)}.text-success{color:var(--color-success)}.text-warning{color:var(--color-warning)}.text-white{color:var(--color-white)}.uppercase{text-transform:uppercase}.opacity-30{opacity:.3}.opacity-70{opacity:.7}.opacity-75{opacity:.75}.filter{filter:var(--tw-blur,)var(--tw-brightness,)var(--tw-contrast,)var(--tw-grayscale,)var(--tw-hue-rotate,)var(--tw-invert,)var(--tw-saturate,)var(--tw-sepia,)var(--tw-drop-shadow,)}.transition-all{transition-property:all;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.duration-200{--tw-duration:.2s;transition-duration:.2s}.duration-300{--tw-duration:.3s;transition-duration:.3s}@media(hover:hover){.hover\:bg-success\/80:hover{background-color:#10b981cc}@supports (color:color-mix(in lab,red,red)){.hover\:bg-success\/80:hover{background-color:color-mix(in oklab,var(--color-success)80%,transparent)}}.hover\:bg-white\/5:hover{background-color:#ffffff0d}@supports (color:color-mix(in lab,red,red)){.hover\:bg-white\/5:hover{background-color:color-mix(in oklab,var(--color-white)5%,transparent)}}.hover\:bg-white\/20:hover{background-color:#fff3}@supports (color:color-mix(in lab,red,red)){.hover\:bg-white\/20:hover{background-color:color-mix(in oklab,var(--color-white)20%,transparent)}}}@media(min-width:48rem){.md\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}}}body{-webkit-font-smoothing:antialiased;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica,Arial,sans-serif}body.dark{--bg-main:#0f172a;--bg-side:#1e293b;--bg-card:#1e293b;--bg-hover:#334155;--text-main:#94a3b8;--text-bright:#f8fafc;--border:#334155}body:not(.dark){--bg-main:#f8fafc;--bg-side:#fff;--bg-card:#fff;--bg-hover:#f1f5f9;--text-main:#475569;--text-bright:#0f172a;--border:#e2e8f0}@property --tw-rotate-x{syntax:"*";inherits:false}@property --tw-rotate-y{syntax:"*";inherits:false}@property --tw-rotate-z{syntax:"*";inherits:false}@property --tw-skew-x{syntax:"*";inherits:false}@property --tw-skew-y{syntax:"*";inherits:false}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-tracking{syntax:"*";inherits:false}@property --tw-blur{syntax:"*";inherits:false}@property --tw-brightness{syntax:"*";inherits:false}@property --tw-contrast{syntax:"*";inherits:false}@property --tw-grayscale{syntax:"*";inherits:false}@property --tw-hue-rotate{syntax:"*";inherits:false}@property --tw-invert{syntax:"*";inherits:false}@property --tw-opacity{syntax:"*";inherits:false}@property --tw-saturate{syntax:"*";inherits:false}@property --tw-sepia{syntax:"*";inherits:false}@property --tw-drop-shadow{syntax:"*";inherits:false}@property --tw-drop-shadow-color{syntax:"*";inherits:false}@property --tw-drop-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-drop-shadow-size{syntax:"*";inherits:false}@property --tw-duration{syntax:"*";inherits:false}@keyframes spin{to{transform:rotate(360deg)}}
1
+ :root{--accent-rgb: 59, 130, 246;--bg-main: #f8fafc;--bg-side: #fff;--bg-card: #fff;--bg-hover: #f1f5f9;--text-main: #475569;--text-bright: #0f172a;--accent: #3b82f6;--border: #e2e8f0;--success: #10b981;--warning: #f59e0b;--danger: #ef4444;--shadow: 0 1px 3px 0 rgb(0 0 0 / .1), 0 1px 2px -1px rgb(0 0 0 / .1);--terminal-bg: #1e293b;--config-key: #3b82f6}body.dark{--bg-main: #0f172a;--bg-side: #1e293b;--bg-card: #1e293b;--bg-hover: #334155;--text-main: #94a3b8;--text-bright: #f8fafc;--accent: #3b82f6;--border: #334155;--success: #10b981;--warning: #f59e0b;--danger: #ef4444;--shadow: 0 4px 6px -1px rgb(0 0 0 / .1), 0 2px 4px -2px rgb(0 0 0 / .1);--terminal-bg: #000;--config-key: #60a5fa}body{margin:0;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica,Arial,sans-serif;background-color:var(--bg-main);color:var(--text-main);-webkit-font-smoothing:antialiased;transition:background-color .3s,color .3s}.app-container{display:flex;height:100vh}.sidebar{width:240px;background-color:var(--bg-side);border-right:1px solid var(--border);display:flex;flex-direction:column;z-index:10}.logo{padding:24px;font-weight:700;font-size:1.25rem;color:var(--text-bright);display:flex;align-items:center;gap:12px}.logo .material-symbols-rounded{color:var(--accent);font-size:28px}nav{flex:1;padding:12px}.status-indicator{padding:20px;border-top:1px solid var(--border);display:flex;align-items:center;font-size:.85rem;font-weight:500}.dot{height:8px;width:8px;background-color:#64748b;border-radius:50%;display:inline-block;margin-right:12px;box-shadow:0 0 0 4px #64748b1a}.dot.running{background-color:var(--success);box-shadow:0 0 0 4px #10b98133}.dot.paused{background-color:var(--warning);box-shadow:0 0 0 4px #f59e0b33}.content{flex:1;display:flex;flex-direction:column;overflow:hidden}.main-header{padding:20px 32px;background-color:var(--bg-main);border-bottom:1px solid var(--border);display:flex;justify-content:space-between;align-items:center}.main-header h1{margin:0;font-size:1.5rem;color:var(--text-bright);font-weight:600;display:flex;align-items:center;gap:12px}.main-header h1 .material-symbols-rounded{color:var(--accent);font-size:28px}.header-toolbar{display:flex;align-items:center;gap:24px}.auto-refresh-group{display:flex;align-items:center;gap:12px;font-size:.875rem;background:var(--bg-side);padding:6px 12px;border-radius:6px;border:1px solid var(--border)}.auto-refresh-group select{background:none;border:none;color:var(--text-bright);cursor:pointer;font-weight:500}.view{flex:1;padding:32px;overflow-y:auto}.metrics-grid,.pools-grid,.cache-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(280px,1fr));gap:24px;margin-bottom:32px}.card{background-color:var(--bg-card);padding:24px;border-radius:12px;border:1px solid var(--border);box-shadow:var(--shadow)}.card-header{display:flex;align-items:center;gap:12px;margin-bottom:16px}.card-header .material-symbols-rounded{color:var(--accent)}.card h3{margin:0;font-size:.875rem;text-transform:uppercase;letter-spacing:.05em;color:var(--text-main)}.card p{font-size:2rem;font-weight:700;margin:0;color:var(--text-bright)}.card small{display:block;margin-top:8px;font-size:.875rem;color:var(--text-main)}.card.warning{border-left:4px solid var(--warning)}.table-container{background:var(--bg-card);border-radius:12px;border:1px solid var(--border);overflow:hidden;box-shadow:var(--shadow)}table{width:100%;border-collapse:collapse}th,td{padding:16px 24px;text-align:left;border-bottom:1px solid var(--border)}th{background-color:var(--bg-hover);color:var(--text-main);font-size:.75rem;text-transform:uppercase;letter-spacing:.05em;font-weight:600}td{color:var(--text-bright);font-size:.9375rem}tr:last-child td{border-bottom:none}.terminal-container,.config-container{background-color:var(--bg-side);border-radius:12px;border:1px solid var(--border);overflow:hidden;box-shadow:var(--shadow)}.terminal{background-color:var(--terminal-bg);color:#10b981;padding:24px;font-family:JetBrains Mono,Fira Code,monospace;font-size:.875rem;line-height:1.6;margin:0;overflow-x:auto;white-space:pre}.config-view-content{padding:0;max-width:900px;margin:0 auto}.config-table{width:100%;border-collapse:collapse}.config-table tr{border-bottom:1px solid var(--border)}.config-table tr:last-child{border-bottom:none}.config-table td{padding:16px 24px;vertical-align:top}.config-label{font-weight:600;color:var(--text-main);width:240px;font-size:.875rem;background-color:var(--bg-main)}.config-value{font-family:JetBrains Mono,monospace;color:var(--text-bright);word-break:break-all;font-size:.875rem}.config-section-header{background-color:var(--bg-hover);padding:12px 24px;font-weight:700;font-size:.75rem;text-transform:uppercase;color:var(--accent);letter-spacing:.05em;border-bottom:1px solid var(--border)}.inner-config-table{width:100%;border-collapse:collapse;font-size:.8125rem}.inner-config-table td{padding:4px 8px;border:none}.cache-card .badge{align-self:center}.card-header h4{color:var(--accent)}.stat-row-label{flex:0 0 180px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.stat-row-value{flex:1;text-align:right}@media(max-width:640px){.stat-row{flex-direction:column;align-items:flex-start;gap:4px}.stat-row-label{flex:none;opacity:.7;font-size:.75rem;text-align:left}.stat-row-value{text-align:left;width:100%}}.view-system-compact{padding:20px 32px}.view-system-compact .metrics-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(300px,1fr));gap:16px;align-items:start;margin-bottom:24px}.view-system-compact .card{padding:16px}.view-system-compact .stat-row{padding:4px 0}.view-system-compact .card-header{margin-bottom:12px}.resource-card{display:flex;flex-direction:column;min-height:350px}.resource-card .chart-container-mini{margin-top:auto}.chart-container-mini{height:100px;width:100%;position:relative;overflow:hidden;border:none;border-radius:4px}.chart-container{margin-bottom:32px;height:300px;position:relative}.btn,.icon-btn{display:inline-flex;align-items:center;justify-content:center;gap:8px;padding:10px 20px;border-radius:8px;font-weight:600;font-size:.875rem;cursor:pointer;border:none;transition:all .2s;background-color:var(--bg-hover);color:var(--text-bright)}.btn .material-symbols-rounded,.icon-btn .material-symbols-rounded{font-size:18px}.btn:hover,.icon-btn:hover{background-color:var(--border)}.btn-primary{background-color:var(--accent);color:#fff}.btn-primary:hover{opacity:.9;background-color:var(--accent)}.btn-success{background-color:var(--success);color:#fff}.btn-success:hover{opacity:.9}.btn-warning{background-color:var(--warning);color:#000}.btn-warning:hover{opacity:.9}.btn-danger{background-color:var(--danger);color:#fff}.btn-danger:hover{opacity:.9}.btn-outline{background:transparent;border:1px solid var(--border);color:var(--accent)}.btn-outline:hover{background-color:var(--bg-hover)}.btn-full{width:100%}.btn-sm{padding:6px 12px;font-size:.8125rem}.btn-sm .material-symbols-rounded{font-size:16px}.btn-lg{padding:14px 28px;font-size:1rem}.btn-lg .material-symbols-rounded{font-size:22px}nav button{width:100%;padding:12px 16px;text-align:left;background:none;border:none;color:var(--text-main);cursor:pointer;font-size:.95rem;display:flex;align-items:center;gap:12px;border-radius:8px;transition:all .2s;margin-bottom:4px}nav button:hover{background-color:var(--bg-hover);color:var(--text-bright)}nav button.active{background-color:var(--accent);color:#fff}nav button .material-symbols-rounded{font-size:20px}.icon-btn{padding:10px;min-width:40px;min-height:40px}.icon-btn.icon-sm{padding:6px;min-width:32px;min-height:32px}.icon-btn.icon-sm .material-symbols-rounded{font-size:20px}.control-group{display:flex;gap:16px;margin-top:24px;flex-wrap:wrap}.control-group .btn{flex:1;min-width:140px}.gap-1{gap:4px}.mt-1{margin-top:4px}.mt-2{margin-top:8px}.mt-3{margin-top:12px}.mt-4{margin-top:16px}.mt-6{margin-top:24px}.mb-1{margin-bottom:4px}.mb-2{margin-bottom:8px}.mb-3{margin-bottom:12px}.mb-4{margin-bottom:16px}.mb-6{margin-bottom:24px}.p-2{padding:8px}.p-3{padding:12px}.p-4{padding:16px}.p-6{padding:24px}.mx-auto{margin-left:auto;margin-right:auto}.flex{display:flex}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-center{align-items:center}.items-baseline{align-items:baseline}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.justify-end{justify-content:flex-end}.self-center{align-self:center}.self-end{align-self:flex-end}.text-xs{font-size:.75rem}.text-sm{font-size:.875rem}.text-lg{font-size:1.125rem}.text-xl{font-size:1.25rem}.text-2xl{font-size:1.5rem}.text-3xl{font-size:1.875rem}.font-medium{font-weight:500}.font-semibold{font-weight:600}.font-bold{font-weight:700}.text-center{text-align:center}.text-right{text-align:right}.text-main{color:var(--text-main)}.text-bright{color:var(--text-bright)}.text-accent{color:var(--accent)}.text-success{color:var(--success)}.text-warning{color:var(--warning)}.text-danger{color:var(--danger)}.bg-main{background-color:var(--bg-main)}.bg-card{background-color:var(--bg-card)}.bg-hover{background-color:var(--bg-hover)}.bg-success{background-color:var(--success)}.bg-warning{background-color:var(--warning)}.bg-danger{background-color:var(--danger)}.border{border:1px solid var(--border)}.border-b{border-bottom:1px solid var(--border)}.border-none{border:none}.border-t{border-top:1px solid var(--border)}.border-l{border-left:1px solid var(--border)}.border-r{border-right:1px solid var(--border)}.rounded{border-radius:4px}.rounded-md{border-radius:6px}.rounded-lg{border-radius:8px}.rounded-xl{border-radius:12px}.rounded-full{border-radius:9999px}.shadow-sm{box-shadow:var(--shadow)}.shadow-md{box-shadow:0 4px 6px -1px #0000001a,0 2px 4px -2px #0000001a}.w-full{width:100%}.w-auto{width:auto}.max-w-xs{max-width:120px}.max-w-sm{max-width:200px}.max-w-md{max-width:280px}.overflow-hidden{overflow:hidden}.overflow-auto{overflow:auto}.overflow-x-auto{overflow-x:auto}.cursor-pointer{cursor:pointer}.transition{transition:all .2s ease}.transition-colors{transition:background-color .2s,color .2s,border-color .2s}.transition-all{transition:all .2s ease}.duration-200{transition-duration:.2s}.duration-300{transition-duration:.3s}.hover-bg:hover{background-color:var(--bg-hover)}.hover-border:hover{border-color:var(--accent)}.opacity-50{opacity:.5}.opacity-75{opacity:.75}.opacity-90{opacity:.9}.leading-tight{line-height:1.25}.leading-normal{line-height:1.5}.leading-relaxed{line-height:1.625}.whitespace-normal{white-space:normal}.whitespace-nowrap{white-space:nowrap}.break-all{word-break:break-all}.grid{display:grid}.grid-cols-2{grid-template-columns:repeat(2,1fr)}.grid-cols-3{grid-template-columns:repeat(3,1fr)}.grid-cols-auto{grid-template-columns:repeat(auto-fit,minmax(120px,1fr))}.gap-2{gap:8px}.gap-3{gap:12px}.gap-4{gap:16px}.gap-6{gap:24px}.stat-card{background-color:var(--bg-card);padding:16px;border-radius:8px;border:1px solid var(--border);text-align:center}.stat-card-value{font-size:1.75rem;font-weight:700;color:var(--text-bright);line-height:1.2}.stat-card-label{font-size:.75rem;text-transform:uppercase;letter-spacing:.05em;color:var(--text-main);margin-top:4px}.progress-bar{height:6px;background:var(--bg-main);border-radius:3px;overflow:hidden}.progress-bar-fill{height:100%;border-radius:3px;transition:width .3s ease}.progress-bar-sm{height:4px}.progress-bar-lg{height:8px}.badge{display:inline-flex;align-items:center;padding:4px 8px;border-radius:9999px;font-size:.75rem;font-weight:600;gap:4px}.badge-success{background-color:#10b98126;color:var(--success)}.badge-warning{background-color:#f59e0b26;color:var(--warning)}.badge-danger{background-color:#ef444426;color:var(--danger)}.badge-info{background-color:#3b82f626;color:var(--accent)}.status-dot{display:inline-flex;align-items:center;gap:6px;font-size:.875rem;font-weight:500}.status-dot .dot{margin:0;flex-shrink:0}.table-row-hover tbody tr{transition:background-color .15s ease}.table-row-hover tbody tr:hover{background-color:var(--bg-hover)}.table-cell{padding:12px 16px;text-align:left;border-bottom:1px solid var(--border)}.table-cell-sm{padding:8px 12px;font-size:.8125rem}.table-header{background-color:var(--bg-hover);color:var(--text-main);font-size:.75rem;text-transform:uppercase;letter-spacing:.05em;font-weight:600;padding:12px 16px;text-align:left}.dense-table th,.dense-table td{padding:6px 12px;font-size:.8125rem}.table-layout-auto{table-layout:auto}.table-layout-fixed{table-layout:fixed}.code{font-family:JetBrains Mono,Fira Code,monospace;font-size:.875rem;background-color:var(--bg-main);padding:2px 6px;border-radius:4px;color:var(--accent)}.code-sm{font-size:.75rem;padding:1px 4px}.description{font-size:.75rem;color:var(--text-main);font-weight:400}.stat-row{display:flex;justify-content:space-between;align-items:center;padding:8px 0;border-bottom:1px solid var(--border)}.stat-row:last-child{border-bottom:none}.stat-row-label{color:var(--text-main);font-size:.875rem}.stat-row-value{color:var(--text-bright);font-weight:600;font-family:monospace}.card-section{margin-bottom:24px}.card-section:last-child{margin-bottom:0}.card-clickable{cursor:pointer;transition:all .2s ease}.card-clickable:hover{border-color:var(--accent);box-shadow:0 4px 12px #3b82f626}.icon-xs{font-size:14px}.icon-sm{font-size:18px}.icon-md{font-size:20px}.icon-lg{font-size:24px}.icon-xl{font-size:28px}.modal{position:fixed;inset:0;background-color:#000000b3;display:flex;align-items:center;justify-content:center;z-index:1000;padding:20px}.modal-content{background-color:var(--bg-card);border-radius:12px;width:100%;max-width:900px;box-shadow:var(--shadow);display:flex;flex-direction:column;max-height:90vh}.modal-header{padding:16px 24px;border-bottom:1px solid var(--border);display:flex;justify-content:space-between;align-items:center}.modal-header h3{margin:0;font-size:1.125rem;color:var(--text-bright)}.modal-body{padding:24px;overflow-y:auto}.stat-values-inline{display:flex;align-items:center;gap:8px}.stat-values{display:flex;flex-direction:column;align-items:flex-end}.min-max{font-size:.7rem;opacity:.7;margin-top:2px}.search-group{position:relative;display:flex;align-items:center}.input-sm{background-color:var(--bg-side);border:1px solid var(--border);border-radius:6px;color:var(--text-bright);padding:6px 12px;font-size:.875rem}.input-sm:focus{border-color:var(--accent);outline:none}.errors-table-row{cursor:pointer;transition:background-color .2s}.errors-table-row:hover{background-color:rgba(var(--accent-rgb),.08)}.server-status{display:flex;align-items:center;gap:8px;padding:8px 12px;background-color:var(--bg-card);border-radius:8px;border:1px solid var(--border)}.server-status-indicator{display:flex;align-items:center;gap:8px}.server-status-dot{width:10px;height:10px;border-radius:50%;flex-shrink:0}.server-status-dot.running{background-color:var(--success);box-shadow:0 0 8px #10b98166}.server-status-dot.paused{background-color:var(--warning);box-shadow:0 0 8px #f59e0b66}.server-status-dot.stopped{background-color:var(--danger);box-shadow:0 0 8px #ef444466}.server-status-text{font-size:.875rem;font-weight:500;text-transform:uppercase;letter-spacing:.025em}.danger-zone{border:1px solid var(--warning);border-left-width:4px;background-color:#f59e0b08}.danger-zone-title{color:var(--warning);font-weight:600;margin-bottom:8px}.empty-state{text-align:center;padding:48px 24px;color:var(--text-main)}.empty-state-icon{font-size:48px;color:var(--text-main);opacity:.5;margin-bottom:16px}.empty-state-text{font-size:.875rem}.skeleton{background:linear-gradient(90deg,var(--bg-main) 25%,var(--bg-hover) 50%,var(--bg-main) 75%);background-size:200% 100%;animation:skeleton-loading 1.5s infinite;border-radius:4px}@keyframes skeleton-loading{0%{background-position:200% 0}to{background-position:-200% 0}}::-webkit-scrollbar{width:8px;height:8px}::-webkit-scrollbar-track{background:var(--bg-main)}::-webkit-scrollbar-thumb{background:var(--border);border-radius:4px}::-webkit-scrollbar-thumb:hover{background:var(--text-main);opacity:.5}button:focus-visible,input:focus-visible,select:focus-visible{outline:2px solid var(--accent);outline-offset:2px}input[type=checkbox]{width:18px;height:18px;accent-color:var(--accent);cursor:pointer}select{accent-color:var(--accent);cursor:pointer}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.animate-spin{animation:spin 1s linear infinite;display:inline-block}.btn.loading{pointer-events:none;opacity:.8}@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-rotate-x:initial;--tw-rotate-y:initial;--tw-rotate-z:initial;--tw-skew-x:initial;--tw-skew-y:initial;--tw-border-style:solid;--tw-font-weight:initial;--tw-tracking:initial;--tw-blur:initial;--tw-brightness:initial;--tw-contrast:initial;--tw-grayscale:initial;--tw-hue-rotate:initial;--tw-invert:initial;--tw-opacity:initial;--tw-saturate:initial;--tw-sepia:initial;--tw-drop-shadow:initial;--tw-drop-shadow-color:initial;--tw-drop-shadow-alpha:100%;--tw-drop-shadow-size:initial;--tw-duration:initial}}}@layer theme{:root,:host{--font-sans:ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";--font-mono:ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;--color-black:#000;--color-white:#fff;--spacing:.25rem;--text-xs:.75rem;--text-xs--line-height:calc(1 / .75);--text-sm:.875rem;--text-sm--line-height:calc(1.25 / .875);--text-lg:1.125rem;--text-lg--line-height:calc(1.75 / 1.125);--text-2xl:1.5rem;--text-2xl--line-height:calc(2 / 1.5);--text-3xl:1.875rem;--text-3xl--line-height: 1.2 ;--font-weight-medium:500;--font-weight-bold:700;--tracking-wider:.05em;--radius-lg:.5rem;--animate-spin:spin 1s linear infinite;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4, 0, .2, 1);--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono);--color-success:#10b981;--color-warning:#f59e0b;--color-danger:#ef4444}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;tab-size:4;line-height:1.5;font-family:var(--default-font-family,ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab,red,red)){::placeholder{color:color-mix(in oklab,currentcolor 50%,transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){appearance:button}::file-selector-button{appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}}@layer components;@layer utilities{.visible{visibility:visible}.fixed{position:fixed}.relative{position:relative}.static{position:static}.start{inset-inline-start:var(--spacing)}.mt-2{margin-top:calc(var(--spacing) * 2)}.mt-4{margin-top:calc(var(--spacing) * 4)}.mt-6{margin-top:calc(var(--spacing) * 6)}.mr-2{margin-right:calc(var(--spacing) * 2)}.mb-2{margin-bottom:calc(var(--spacing) * 2)}.mb-3{margin-bottom:calc(var(--spacing) * 3)}.mb-4{margin-bottom:calc(var(--spacing) * 4)}.mb-6{margin-bottom:calc(var(--spacing) * 6)}.mb-8{margin-bottom:calc(var(--spacing) * 8)}.ml-auto{margin-left:auto}.block{display:block}.flex{display:flex}.grid{display:grid}.inline-block{display:inline-block}.table{display:table}.w-full{width:100%}.max-w-\[150px\]{max-width:150px}.max-w-\[200px\]{max-width:200px}.max-w-\[300px\]{max-width:300px}.max-w-\[800px\]{max-width:800px}.transform{transform:var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,)}.animate-spin{animation:var(--animate-spin)}.cursor-pointer{cursor:pointer}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.items-baseline{align-items:baseline}.items-center{align-items:center}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.gap-1{gap:calc(var(--spacing) * 1)}.gap-2{gap:calc(var(--spacing) * 2)}.gap-3{gap:calc(var(--spacing) * 3)}.gap-4{gap:calc(var(--spacing) * 4)}.gap-6{gap:calc(var(--spacing) * 6)}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.rounded-lg{border-radius:var(--radius-lg)}.border{border-style:var(--tw-border-style);border-width:1px}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.border-white\/5{border-color:#ffffff0d}@supports (color:color-mix(in lab,red,red)){.border-white\/5{border-color:color-mix(in oklab,var(--color-white) 5%,transparent)}}.bg-success{background-color:var(--color-success)}.bg-white\/10{background-color:#ffffff1a}@supports (color:color-mix(in lab,red,red)){.bg-white\/10{background-color:color-mix(in oklab,var(--color-white) 10%,transparent)}}.px-4{padding-inline:calc(var(--spacing) * 4)}.py-2{padding-block:calc(var(--spacing) * 2)}.pt-4{padding-top:calc(var(--spacing) * 4)}.text-center{text-align:center}.text-right{text-align:right}.font-mono{font-family:var(--font-mono)}.text-2xl{font-size:var(--text-2xl);line-height:var(--tw-leading,var(--text-2xl--line-height))}.text-3xl{font-size:var(--text-3xl);line-height:var(--tw-leading,var(--text-3xl--line-height))}.text-lg{font-size:var(--text-lg);line-height:var(--tw-leading,var(--text-lg--line-height))}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.font-bold{--tw-font-weight:var(--font-weight-bold);font-weight:var(--font-weight-bold)}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.tracking-wider{--tw-tracking:var(--tracking-wider);letter-spacing:var(--tracking-wider)}.break-all{word-break:break-all}.whitespace-nowrap{white-space:nowrap}.text-black{color:var(--color-black)}.text-danger{color:var(--color-danger)}.text-success{color:var(--color-success)}.text-warning{color:var(--color-warning)}.text-white{color:var(--color-white)}.uppercase{text-transform:uppercase}.opacity-30{opacity:.3}.opacity-70{opacity:.7}.opacity-75{opacity:.75}.filter{filter:var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,)}.transition-all{transition-property:all;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.duration-200{--tw-duration:.2s;transition-duration:.2s}.duration-300{--tw-duration:.3s;transition-duration:.3s}@media(hover:hover){.hover\:bg-success\/80:hover{background-color:#10b981cc}@supports (color:color-mix(in lab,red,red)){.hover\:bg-success\/80:hover{background-color:color-mix(in oklab,var(--color-success) 80%,transparent)}}.hover\:bg-white\/5:hover{background-color:#ffffff0d}@supports (color:color-mix(in lab,red,red)){.hover\:bg-white\/5:hover{background-color:color-mix(in oklab,var(--color-white) 5%,transparent)}}.hover\:bg-white\/20:hover{background-color:#fff3}@supports (color:color-mix(in lab,red,red)){.hover\:bg-white\/20:hover{background-color:color-mix(in oklab,var(--color-white) 20%,transparent)}}}@media(min-width:48rem){.md\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}}}body{-webkit-font-smoothing:antialiased;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica,Arial,sans-serif}body.dark{--bg-main:#0f172a;--bg-side:#1e293b;--bg-card:#1e293b;--bg-hover:#334155;--text-main:#94a3b8;--text-bright:#f8fafc;--border:#334155}body:not(.dark){--bg-main:#f8fafc;--bg-side:#fff;--bg-card:#fff;--bg-hover:#f1f5f9;--text-main:#475569;--text-bright:#0f172a;--border:#e2e8f0}@property --tw-rotate-x{syntax:"*";inherits:false}@property --tw-rotate-y{syntax:"*";inherits:false}@property --tw-rotate-z{syntax:"*";inherits:false}@property --tw-skew-x{syntax:"*";inherits:false}@property --tw-skew-y{syntax:"*";inherits:false}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-tracking{syntax:"*";inherits:false}@property --tw-blur{syntax:"*";inherits:false}@property --tw-brightness{syntax:"*";inherits:false}@property --tw-contrast{syntax:"*";inherits:false}@property --tw-grayscale{syntax:"*";inherits:false}@property --tw-hue-rotate{syntax:"*";inherits:false}@property --tw-invert{syntax:"*";inherits:false}@property --tw-opacity{syntax:"*";inherits:false}@property --tw-saturate{syntax:"*";inherits:false}@property --tw-sepia{syntax:"*";inherits:false}@property --tw-drop-shadow{syntax:"*";inherits:false}@property --tw-drop-shadow-color{syntax:"*";inherits:false}@property --tw-drop-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-drop-shadow-size{syntax:"*";inherits:false}@property --tw-duration{syntax:"*";inherits:false}@keyframes spin{to{transform:rotate(360deg)}}
@@ -6,8 +6,8 @@
6
6
  <title>web_plsql Admin Console</title>
7
7
  <link rel="icon" type="image/svg+xml" href="/admin/assets/favicon-mQAM4tVu.svg" />
8
8
  <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Rounded:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200" />
9
- <script type="module" crossorigin src="/admin/assets/main-0oxRTIkL.js"></script>
10
- <link rel="stylesheet" crossorigin href="/admin/assets/main-TYgLak6O.css">
9
+ <script type="module" crossorigin src="/admin/assets/main-C8GKnEhz.js"></script>
10
+ <link rel="stylesheet" crossorigin href="/admin/assets/main-bU4x_yEW.css">
11
11
  </head>
12
12
  <body class="dark">
13
13
  <div class="app-container">
Binary file
Binary file
package/dist/index.mjs CHANGED
@@ -206,12 +206,12 @@ const DB_TYPE_DATE = oracledb.DB_TYPE_DATE;
206
206
 
207
207
  //#endregion
208
208
  //#region src/backend/version.ts
209
- if (typeof globalThis.__VERSION__ === "undefined") globalThis.__VERSION__ = "**development**";
209
+ globalThis.__VERSION__ ??= "**development**";
210
210
  /**
211
211
  * Returns the current library version
212
212
  * @returns {string} - Version.
213
213
  */
214
- const getVersion = () => "1.3.0";
214
+ const getVersion = () => "1.3.1";
215
215
 
216
216
  //#endregion
217
217
  //#region src/backend/server/config.ts
@@ -913,7 +913,7 @@ var StatsManager = class {
913
913
  let p95 = 0;
914
914
  let p99 = 0;
915
915
  if (b.durations.length > 0) {
916
- const sorted = [...b.durations].sort((x, y) => x - y);
916
+ const sorted = b.durations.toSorted((x, y) => x - y);
917
917
  const p95Idx = Math.floor(sorted.length * .95);
918
918
  const p99Idx = Math.floor(sorted.length * .99);
919
919
  const lastIdx = sorted.length - 1;
@@ -924,8 +924,8 @@ var StatsManager = class {
924
924
  timestamp: Date.now(),
925
925
  requests: b.count,
926
926
  errors: b.errors,
927
- durationMin: b.durationMin < 0 ? 0 : b.durationMin,
928
- durationMax: b.durationMax < 0 ? 0 : b.durationMax,
927
+ durationMin: Math.max(b.durationMin, 0),
928
+ durationMax: Math.max(b.durationMax, 0),
929
929
  durationAvg: b.count > 0 ? b.durationSum / b.count : 0,
930
930
  durationP95: p95,
931
931
  durationP99: p99,
@@ -1106,7 +1106,7 @@ const isFile = async (filePath) => {
1106
1106
  * @param value - The value.
1107
1107
  * @returns The escaped value.
1108
1108
  */
1109
- const escapeHtml = (value) => value.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#39;");
1109
+ const escapeHtml = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll("\"", "&quot;").replaceAll("'", "&#39;");
1110
1110
  /**
1111
1111
  * Convert LF and/or CR to <br>
1112
1112
  * @param text - The text to convert.
@@ -1114,8 +1114,8 @@ const escapeHtml = (value) => value.replace(/&/g, "&amp;").replace(/</g, "&lt;")
1114
1114
  */
1115
1115
  const convertAsciiToHtml = (text) => {
1116
1116
  let html = escapeHtml(text);
1117
- html = html.replace(/(?:\r\n|\r|\n)/g, "<br />");
1118
- html = html.replace(/\t/g, "&nbsp;&nbsp;&nbsp;");
1117
+ html = html.replaceAll(/\r\n|\r|\n/g, "<br />");
1118
+ html = html.replaceAll(" ", "&nbsp;&nbsp;&nbsp;");
1119
1119
  return html;
1120
1120
  };
1121
1121
  /**
@@ -1180,6 +1180,12 @@ const inspect = (value, depth = null) => {
1180
1180
  return "Unable to convert value to string";
1181
1181
  };
1182
1182
  /**
1183
+ * @param cell - The string
1184
+ * @param width - The width
1185
+ * @returns The result
1186
+ */
1187
+ const padCell = (cell, width) => cell.padEnd(width, " ");
1188
+ /**
1183
1189
  * Return a tabular representation of the values.
1184
1190
  *
1185
1191
  * @param head - The header values.
@@ -1193,12 +1199,6 @@ const toTable = (head, body) => {
1193
1199
  return Math.max(h.length, bodyMax);
1194
1200
  });
1195
1201
  /**
1196
- * @param cell - The string
1197
- * @param width - The width
1198
- * @returns The result
1199
- */
1200
- const padCell = (cell, width) => cell.padEnd(width, " ");
1201
- /**
1202
1202
  * @param i - The index
1203
1203
  * @returns The width
1204
1204
  */
@@ -1705,19 +1705,25 @@ const findArguments = async (procedure, databaseConnection, argumentCache) => {
1705
1705
  * @returns The binding.
1706
1706
  */
1707
1707
  const getBinding = (argName, argValue, argType) => {
1708
+ const isEmpty = argValue === "" || argValue === null || argValue === void 0;
1708
1709
  if (argType === DATA_TYPES.VARCHAR2 || argType === DATA_TYPES.CHAR) return {
1709
1710
  dir: BIND_IN,
1710
1711
  type: DB_TYPE_VARCHAR,
1711
- val: argValue
1712
+ val: isEmpty ? null : argValue
1712
1713
  };
1713
1714
  if (argType === DATA_TYPES.CLOB) return {
1714
1715
  dir: BIND_IN,
1715
1716
  type: DB_TYPE_CLOB,
1716
- val: argValue
1717
+ val: isEmpty ? null : argValue
1717
1718
  };
1718
1719
  if (argType === DATA_TYPES.NUMBER || argType === DATA_TYPES.BINARY_INTEGER) {
1720
+ if (isEmpty) return {
1721
+ dir: BIND_IN,
1722
+ type: DB_TYPE_NUMBER,
1723
+ val: null
1724
+ };
1719
1725
  const value = stringToNumber(argValue);
1720
- if (value === null) throw new Error(`Error in named parameter "${argName}": invalid value "${argValue}" for type "${argType}"`);
1726
+ if (value === null) throw new Error(`Error in named parameter "${argName}": invalid value "${inspect(argValue)}" for type "${argType}"`);
1721
1727
  return {
1722
1728
  dir: BIND_IN,
1723
1729
  type: DB_TYPE_NUMBER,
@@ -1725,18 +1731,23 @@ const getBinding = (argName, argValue, argType) => {
1725
1731
  };
1726
1732
  }
1727
1733
  if (argType === DATA_TYPES.DATE) {
1728
- if (typeof argValue !== "string") throw new Error(`Error in named parameter "${argName}": invalid value "${argValue}" for type "${argType}"`);
1734
+ if (isEmpty) return {
1735
+ dir: BIND_IN,
1736
+ type: DB_TYPE_DATE,
1737
+ val: null
1738
+ };
1739
+ if (typeof argValue !== "string") throw new TypeError(`Error in named parameter "${argName}": invalid value "${inspect(argValue)}" for type "${argType}"`);
1729
1740
  const value = new Date(argValue);
1730
- if (Number.isNaN(value.getTime())) throw new Error(`Error in named parameter "${argName}": invalid value "${argValue}" for type "${argType}"`);
1741
+ if (Number.isNaN(value.getTime())) throw new TypeError(`Error in named parameter "${argName}": invalid value "${inspect(argValue)}" for type "${argType}"`);
1731
1742
  return {
1732
1743
  dir: BIND_IN,
1733
- type: DB_TYPE_VARCHAR,
1744
+ type: DB_TYPE_DATE,
1734
1745
  val: value
1735
1746
  };
1736
1747
  }
1737
1748
  if (argType === DATA_TYPES.PL_SQL_TABLE || Array.isArray(argValue)) return {
1738
1749
  dir: BIND_IN,
1739
- type: DB_TYPE_DATE,
1750
+ type: DB_TYPE_VARCHAR,
1740
1751
  val: typeof argValue === "string" ? [argValue] : argValue
1741
1752
  };
1742
1753
  throw new Error(`Error in named parameter "${argName}": invalid binding type "${argType}"`);
@@ -1834,8 +1845,8 @@ const parsePage = (text) => {
1834
1845
  const headerEndPosition = text.indexOf("\n\n");
1835
1846
  if (headerEndPosition === -1) head = text;
1836
1847
  else {
1837
- head = text.substring(0, headerEndPosition + 2);
1838
- page.body = text.substring(headerEndPosition + 2);
1848
+ head = text.slice(0, Math.max(0, headerEndPosition + 2));
1849
+ page.body = text.slice(Math.max(0, headerEndPosition + 2));
1839
1850
  }
1840
1851
  debug$8("parsing the headers received from PL/SQL");
1841
1852
  head.split("\n").forEach((line) => {
@@ -1845,8 +1856,8 @@ const parsePage = (text) => {
1845
1856
  {
1846
1857
  const cookie = parseCookie(header.value);
1847
1858
  debug$8(`oracle header "set-cookie" with value "${header.value}" was received has been parsed to ${JSON.stringify(cookie)}`);
1848
- if (cookie !== null) page.head.cookies.push(cookie);
1849
- else throw new Error(`Unable to parse header "set-cookie" with value "${header.value}" received from PL/SQL`);
1859
+ if (cookie === null) throw new Error(`Unable to parse header "set-cookie" with value "${header.value}" received from PL/SQL`);
1860
+ else page.head.cookies.push(cookie);
1850
1861
  }
1851
1862
  break;
1852
1863
  case "content-type":
@@ -1855,22 +1866,24 @@ const parsePage = (text) => {
1855
1866
  break;
1856
1867
  case "x-db-content-length":
1857
1868
  {
1858
- const contentLength = parseInt(header.value, 10);
1859
- if (!Number.isNaN(contentLength)) {
1869
+ const contentLength = Number.parseInt(header.value, 10);
1870
+ if (Number.isNaN(contentLength)) throw new TypeError(`Unable to parse header "x-db-content-length" with value "${header.value}" received from PL/SQL`);
1871
+ else {
1860
1872
  page.head.contentLength = contentLength;
1861
1873
  debug$8(`oracle header "x-db-content-length" with value "${page.head.contentLength}" was parsed`);
1862
- } else throw new Error(`Unable to parse header "x-db-content-length" with value "${header.value}" received from PL/SQL`);
1874
+ }
1863
1875
  }
1864
1876
  break;
1865
1877
  case "status":
1866
1878
  {
1867
- const statusCode = parseInt(header.value, 10);
1868
- if (!Number.isNaN(statusCode)) {
1879
+ const statusCode = Number.parseInt(header.value, 10);
1880
+ if (Number.isNaN(statusCode)) throw new TypeError(`Unable to parse header "status" with value "${header.value}" received from PL/SQL`);
1881
+ else {
1869
1882
  page.head.statusCode = statusCode;
1870
1883
  debug$8(`oracle header "status" with value "${page.head.statusCode}" was parsed`);
1871
1884
  const index = header.value.indexOf(" ");
1872
- if (index !== -1) page.head.statusDescription = header.value.substring(index + 1);
1873
- } else throw new Error(`Unable to parse header "status" with value "${header.value}" received from PL/SQL`);
1885
+ if (index !== -1) page.head.statusDescription = header.value.slice(Math.max(0, index + 1));
1886
+ }
1874
1887
  }
1875
1888
  break;
1876
1889
  case "location":
@@ -1893,8 +1906,8 @@ const parsePage = (text) => {
1893
1906
  const getHeader = (line) => {
1894
1907
  const index = line.indexOf(":");
1895
1908
  if (index !== -1) return {
1896
- name: line.substring(0, index).trim(),
1897
- value: line.substring(index + 1).trim()
1909
+ name: line.slice(0, Math.max(0, index)).trim(),
1910
+ value: line.slice(Math.max(0, index + 1)).trim()
1898
1911
  };
1899
1912
  return null;
1900
1913
  };
@@ -1912,17 +1925,17 @@ const parseCookie = (text) => {
1912
1925
  const index = firstElement.indexOf("=");
1913
1926
  if (index <= 0) return null;
1914
1927
  const cookie = {
1915
- name: firstElement.substring(0, index).trim(),
1916
- value: firstElement.substring(index + 1).trim(),
1928
+ name: firstElement.slice(0, Math.max(0, index)).trim(),
1929
+ value: firstElement.slice(Math.max(0, index + 1)).trim(),
1917
1930
  options: {}
1918
1931
  };
1919
1932
  cookieElements.shift();
1920
1933
  cookieElements.forEach((element) => {
1921
- if (element.toLowerCase().startsWith("path=")) cookie.options.path = element.substring(5);
1922
- else if (element.toLowerCase().startsWith("domain=")) cookie.options.domain = element.substring(7);
1934
+ if (element.toLowerCase().startsWith("path=")) cookie.options.path = element.slice(5);
1935
+ else if (element.toLowerCase().startsWith("domain=")) cookie.options.domain = element.slice(7);
1923
1936
  else if (element.toLowerCase().startsWith("secure")) cookie.options.secure = true;
1924
1937
  else if (element.toLowerCase().startsWith("expires=")) {
1925
- const date = tryDecodeDate(element.substring(8));
1938
+ const date = tryDecodeDate(element.slice(8));
1926
1939
  if (date) cookie.options.expires = date;
1927
1940
  } else if (element.toLowerCase().startsWith("httponly")) cookie.options.httpOnly = true;
1928
1941
  });
@@ -2449,14 +2462,9 @@ var OWAPageStream = class extends Readable {
2449
2462
  //#endregion
2450
2463
  //#region src/backend/util/traceManager.ts
2451
2464
  var TraceManager = class {
2452
- enabled;
2453
- filename;
2454
- maxEntries;
2455
- constructor() {
2456
- this.enabled = false;
2457
- this.filename = "trace.json.log";
2458
- this.maxEntries = 1e3;
2459
- }
2465
+ enabled = false;
2466
+ filename = "trace.json.log";
2467
+ maxEntries = 1e3;
2460
2468
  /**
2461
2469
  * Toggle tracing
2462
2470
  * @param enabled - New state
@@ -2533,12 +2541,11 @@ const getProcedure = async (req, procName, argObj, options, databaseConnection,
2533
2541
  };
2534
2542
  }
2535
2543
  const useVariableArguments = procName.startsWith("!");
2536
- const sanitizedProcName = await sanitizeProcName(useVariableArguments ? procName.substring(1) : procName, databaseConnection, options, procedureNameCache);
2537
- if (useVariableArguments) return {
2544
+ const sanitizedProcName = await sanitizeProcName(useVariableArguments ? procName.slice(1) : procName, databaseConnection, options, procedureNameCache);
2545
+ return useVariableArguments ? {
2538
2546
  ...getProcedureVariable(req, sanitizedProcName, argObj),
2539
2547
  resolvedName: sanitizedProcName
2540
- };
2541
- else return {
2548
+ } : {
2542
2549
  ...await getProcedureNamed(req, sanitizedProcName, argObj, databaseConnection, argumentCache),
2543
2550
  resolvedName: sanitizedProcName
2544
2551
  };
@@ -2580,7 +2587,7 @@ const procedurePrepare = async (cgiObj, databaseConnection) => {
2580
2587
  remote_user: {
2581
2588
  dir: BIND_IN,
2582
2589
  type: STRING,
2583
- val: (cgiObj.REMOTE_USER ?? "").substring(0, 30)
2590
+ val: (cgiObj.REMOTE_USER ?? "").slice(0, 30)
2584
2591
  }
2585
2592
  };
2586
2593
  try {
@@ -2679,7 +2686,7 @@ const invokeProcedure = async (req, res, argObj, cgiObj, filesToUpload, options,
2679
2686
  const startTime = Date.now();
2680
2687
  let traceData = null;
2681
2688
  if (traceManager.isEnabled()) traceData = {
2682
- id: Math.random().toString(36).substring(2, 15),
2689
+ id: Math.random().toString(36).slice(2, 15),
2683
2690
  timestamp: (/* @__PURE__ */ new Date()).toISOString(),
2684
2691
  source: cgiObj.REMOTE_ADDR ?? "",
2685
2692
  url: req.originalUrl,
@@ -2762,7 +2769,7 @@ const invokeProcedure = async (req, res, argObj, cgiObj, filesToUpload, options,
2762
2769
  streamInstance.push = (chunk) => {
2763
2770
  if (chunk !== null && htmlBuffer.length < MAX_HTML_SIZE) {
2764
2771
  htmlBuffer += String(chunk);
2765
- if (htmlBuffer.length > MAX_HTML_SIZE) htmlBuffer = htmlBuffer.substring(0, MAX_HTML_SIZE) + "... [truncated]";
2772
+ if (htmlBuffer.length > MAX_HTML_SIZE) htmlBuffer = htmlBuffer.slice(0, Math.max(0, MAX_HTML_SIZE)) + "... [truncated]";
2766
2773
  }
2767
2774
  return originalPush(chunk);
2768
2775
  };
@@ -2858,11 +2865,11 @@ const getCookieString = (req) => {
2858
2865
  */
2859
2866
  const getPath = (req) => {
2860
2867
  const pathname = new URL(`${req.protocol}://${os.hostname()}${req.originalUrl}`).pathname;
2861
- const tmp = trimPath(pathname.substring(0, pathname.lastIndexOf("/") + 1));
2868
+ const tmp = trimPath(pathname.slice(0, Math.max(0, pathname.lastIndexOf("/") + 1)));
2862
2869
  return {
2863
2870
  script: `/${tmp}`,
2864
- prefix: `/${tmp.substring(0, tmp.lastIndexOf("/"))}`,
2865
- dad: tmp.substring(tmp.indexOf("/") + 1)
2871
+ prefix: `/${tmp.slice(0, Math.max(0, tmp.lastIndexOf("/")))}`,
2872
+ dad: tmp.slice(Math.max(0, tmp.indexOf("/") + 1))
2866
2873
  };
2867
2874
  };
2868
2875
  /**
@@ -2871,7 +2878,7 @@ const getPath = (req) => {
2871
2878
  * @param value - The value to trim.
2872
2879
  * @returns The trimmed value.
2873
2880
  */
2874
- const trimPath = (value) => value.replace(/^\/+|\/+$/g, "");
2881
+ const trimPath = (value) => value.replaceAll(/^\/+|\/+$/g, "");
2875
2882
  /**
2876
2883
  * Create a CGI object
2877
2884
  *
@@ -3222,7 +3229,7 @@ const readLastLines = async (filePath, n = 100, filter = "") => {
3222
3229
  const createAdminRouter = (adminContext) => {
3223
3230
  const router = express.Router();
3224
3231
  router.get("/api/status", (req, res) => {
3225
- const uptime = ((/* @__PURE__ */ new Date()).getTime() - adminContext.startTime.getTime()) / 1e3;
3232
+ const uptime = (Date.now() - adminContext.startTime.getTime()) / 1e3;
3226
3233
  const includeHistory = req.query.history === "true";
3227
3234
  const includeConfig = req.query.config === "true";
3228
3235
  const poolStats = adminContext.pools.map((pool, index) => {
@@ -3315,11 +3322,11 @@ const createAdminRouter = (adminContext) => {
3315
3322
  let limit = 100;
3316
3323
  if (typeof limitQuery === "string") {
3317
3324
  const parsed = Number(limitQuery);
3318
- if (!isNaN(parsed)) limit = parsed;
3325
+ if (!Number.isNaN(parsed)) limit = parsed;
3319
3326
  }
3320
3327
  const history = adminContext.statsManager.getHistory();
3321
3328
  const slice = limit > 0 ? history.slice(-limit) : [...history];
3322
- res.json(slice.reverse());
3329
+ res.json(slice.toReversed());
3323
3330
  });
3324
3331
  router.get("/api/logs/error", async (req, res) => {
3325
3332
  try {
@@ -3332,7 +3339,7 @@ const createAdminRouter = (adminContext) => {
3332
3339
  }).filter((l) => l !== null);
3333
3340
  const logs = z.array(logEntrySchema).safeParse(parsedLines);
3334
3341
  if (!logs.success) throw new Error(`Validation failed: ${logs.error.message}`);
3335
- return res.json(logs.data.reverse());
3342
+ return res.json(logs.data.toReversed());
3336
3343
  } catch (err) {
3337
3344
  return res.status(500).json({ error: String(err) });
3338
3345
  }
@@ -3347,7 +3354,7 @@ const createAdminRouter = (adminContext) => {
3347
3354
  return;
3348
3355
  }
3349
3356
  const lines = await readLastLines(logFile, limit, filter);
3350
- res.json(lines.reverse());
3357
+ res.json(lines.toReversed());
3351
3358
  } catch (err) {
3352
3359
  res.status(500).json({ error: String(err) });
3353
3360
  }
@@ -3367,25 +3374,29 @@ const createAdminRouter = (adminContext) => {
3367
3374
  res.json({ message: `Cleared ${cleared} caches` });
3368
3375
  });
3369
3376
  router.post("/api/server/:action", (req, res) => {
3370
- const action = req.params.action;
3371
- if (action === "stop") {
3372
- res.json({ message: "Server shutting down..." });
3373
- setTimeout(() => {
3374
- forceShutdown();
3375
- }, SHUTDOWN_GRACE_DELAY_MS);
3376
- } else if (action === "pause") {
3377
- adminContext.setPaused(true);
3378
- res.json({
3379
- message: "Server paused",
3380
- status: "paused"
3381
- });
3382
- } else if (action === "resume") {
3383
- adminContext.setPaused(false);
3384
- res.json({
3385
- message: "Server resumed",
3386
- status: "running"
3387
- });
3388
- } else res.status(400).json({ error: "Invalid action" });
3377
+ switch (req.params.action) {
3378
+ case "stop":
3379
+ res.json({ message: "Server shutting down..." });
3380
+ setTimeout(() => {
3381
+ forceShutdown();
3382
+ }, SHUTDOWN_GRACE_DELAY_MS);
3383
+ break;
3384
+ case "pause":
3385
+ adminContext.setPaused(true);
3386
+ res.json({
3387
+ message: "Server paused",
3388
+ status: "paused"
3389
+ });
3390
+ break;
3391
+ case "resume":
3392
+ adminContext.setPaused(false);
3393
+ res.json({
3394
+ message: "Server resumed",
3395
+ status: "running"
3396
+ });
3397
+ break;
3398
+ default: res.status(400).json({ error: "Invalid action" });
3399
+ }
3389
3400
  });
3390
3401
  router.get("/api/trace/status", (_req, res) => {
3391
3402
  res.json({ enabled: traceManager.isEnabled() });
@@ -3409,7 +3420,7 @@ const createAdminRouter = (adminContext) => {
3409
3420
  }).filter((l) => l !== null);
3410
3421
  const logs = z.array(procedureTraceEntrySchema).safeParse(parsedLines);
3411
3422
  if (!logs.success) throw new Error(`Validation failed: ${logs.error.message}`);
3412
- return res.json(logs.data.reverse());
3423
+ return res.json(logs.data.toReversed());
3413
3424
  } catch (err) {
3414
3425
  return res.status(500).json({ error: String(err) });
3415
3426
  }