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.
- package/dist/frontend/assets/{main-0oxRTIkL.js → main-C8GKnEhz.js} +4 -4
- package/dist/frontend/assets/main-C8GKnEhz.js.br +0 -0
- package/dist/frontend/assets/{main-0oxRTIkL.js.gz → main-C8GKnEhz.js.gz} +0 -0
- package/dist/frontend/assets/{main-TYgLak6O.css → main-bU4x_yEW.css} +1 -1
- package/dist/frontend/assets/main-bU4x_yEW.css.br +0 -0
- package/dist/frontend/assets/main-bU4x_yEW.css.gz +0 -0
- package/dist/frontend/index.html +2 -2
- package/dist/frontend/index.html.br +0 -0
- package/dist/frontend/index.html.gz +0 -0
- package/dist/index.mjs +94 -83
- package/dist/index.mjs.map +1 -1
- package/package.json +11 -8
- package/dist/frontend/assets/main-0oxRTIkL.js.br +0 -0
- package/dist/frontend/assets/main-TYgLak6O.css.br +0 -0
- package/dist/frontend/assets/main-TYgLak6O.css.gz +0 -0
|
Binary file
|
|
Binary file
|
|
@@ -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)}}
|
|
Binary file
|
|
Binary file
|
package/dist/frontend/index.html
CHANGED
|
@@ -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-
|
|
10
|
-
<link rel="stylesheet" crossorigin href="/admin/assets/main-
|
|
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
|
-
|
|
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.
|
|
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 =
|
|
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
|
|
928
|
-
durationMax: 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.
|
|
1109
|
+
const escapeHtml = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll("\"", """).replaceAll("'", "'");
|
|
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, "&").replace(/</g, "<")
|
|
|
1114
1114
|
*/
|
|
1115
1115
|
const convertAsciiToHtml = (text) => {
|
|
1116
1116
|
let html = escapeHtml(text);
|
|
1117
|
-
html = html.
|
|
1118
|
-
html = html.
|
|
1117
|
+
html = html.replaceAll(/\r\n|\r|\n/g, "<br />");
|
|
1118
|
+
html = html.replaceAll(" ", " ");
|
|
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 (
|
|
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
|
|
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:
|
|
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:
|
|
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.
|
|
1838
|
-
page.body = text.
|
|
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
|
|
1849
|
-
else
|
|
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 (
|
|
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
|
-
}
|
|
1874
|
+
}
|
|
1863
1875
|
}
|
|
1864
1876
|
break;
|
|
1865
1877
|
case "status":
|
|
1866
1878
|
{
|
|
1867
|
-
const statusCode = parseInt(header.value, 10);
|
|
1868
|
-
if (
|
|
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.
|
|
1873
|
-
}
|
|
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.
|
|
1897
|
-
value: line.
|
|
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.
|
|
1916
|
-
value: firstElement.
|
|
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.
|
|
1922
|
-
else if (element.toLowerCase().startsWith("domain=")) cookie.options.domain = element.
|
|
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.
|
|
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.
|
|
2537
|
-
|
|
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 ?? "").
|
|
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).
|
|
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.
|
|
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.
|
|
2868
|
+
const tmp = trimPath(pathname.slice(0, Math.max(0, pathname.lastIndexOf("/") + 1)));
|
|
2862
2869
|
return {
|
|
2863
2870
|
script: `/${tmp}`,
|
|
2864
|
-
prefix: `/${tmp.
|
|
2865
|
-
dad: tmp.
|
|
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.
|
|
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 = (
|
|
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.
|
|
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.
|
|
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.
|
|
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
|
-
|
|
3371
|
-
|
|
3372
|
-
|
|
3373
|
-
|
|
3374
|
-
|
|
3375
|
-
|
|
3376
|
-
|
|
3377
|
-
|
|
3378
|
-
|
|
3379
|
-
|
|
3380
|
-
|
|
3381
|
-
|
|
3382
|
-
|
|
3383
|
-
|
|
3384
|
-
|
|
3385
|
-
|
|
3386
|
-
|
|
3387
|
-
|
|
3388
|
-
|
|
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.
|
|
3423
|
+
return res.json(logs.data.toReversed());
|
|
3413
3424
|
} catch (err) {
|
|
3414
3425
|
return res.status(500).json({ error: String(err) });
|
|
3415
3426
|
}
|