@design.estate/dees-catalog 3.35.1 → 3.36.0

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.
@@ -101154,6 +101154,7 @@ var init_versions = __esm({
101154
101154
  CDN_VERSIONS = {
101155
101155
  xterm: "5.3.0",
101156
101156
  xtermAddonFit: "0.8.0",
101157
+ xtermAddonSearch: "0.13.0",
101157
101158
  highlightJs: "11.11.1",
101158
101159
  apexcharts: "5.3.6",
101159
101160
  tiptap: "2.23.0",
@@ -101173,12 +101174,14 @@ var init_DeesServiceLibLoader = __esm({
101173
101174
  // Cached library references
101174
101175
  xtermLib = null;
101175
101176
  xtermFitAddonLib = null;
101177
+ xtermSearchAddonLib = null;
101176
101178
  highlightJsLib = null;
101177
101179
  apexChartsLib = null;
101178
101180
  tiptapLib = null;
101179
101181
  // Loading promises to prevent duplicate concurrent loads
101180
101182
  xtermLoadingPromise = null;
101181
101183
  xtermFitAddonLoadingPromise = null;
101184
+ xtermSearchAddonLoadingPromise = null;
101182
101185
  highlightJsLoadingPromise = null;
101183
101186
  apexChartsLoadingPromise = null;
101184
101187
  tiptapLoadingPromise = null;
@@ -101242,6 +101245,30 @@ var init_DeesServiceLibLoader = __esm({
101242
101245
  })();
101243
101246
  return this.xtermFitAddonLoadingPromise;
101244
101247
  }
101248
+ /**
101249
+ * Load xterm-addon-search from CDN
101250
+ * @returns Promise resolving to SearchAddon class
101251
+ */
101252
+ async loadXtermSearchAddon() {
101253
+ if (this.xtermSearchAddonLib) {
101254
+ return this.xtermSearchAddonLib;
101255
+ }
101256
+ if (this.xtermSearchAddonLoadingPromise) {
101257
+ return this.xtermSearchAddonLoadingPromise;
101258
+ }
101259
+ this.xtermSearchAddonLoadingPromise = (async () => {
101260
+ const url = `${CDN_BASE}/xterm-addon-search@${CDN_VERSIONS.xtermAddonSearch}/+esm`;
101261
+ const module = await import(
101262
+ /* @vite-ignore */
101263
+ url
101264
+ );
101265
+ this.xtermSearchAddonLib = {
101266
+ SearchAddon: module.SearchAddon
101267
+ };
101268
+ return this.xtermSearchAddonLib;
101269
+ })();
101270
+ return this.xtermSearchAddonLoadingPromise;
101271
+ }
101245
101272
  /**
101246
101273
  * Inject xterm CSS styles into the document head
101247
101274
  */
@@ -101368,6 +101395,7 @@ var init_DeesServiceLibLoader = __esm({
101368
101395
  await Promise.all([
101369
101396
  this.loadXterm(),
101370
101397
  this.loadXtermFitAddon(),
101398
+ this.loadXtermSearchAddon(),
101371
101399
  this.loadHighlightJs(),
101372
101400
  this.loadApexCharts(),
101373
101401
  this.loadTiptap()
@@ -101382,6 +101410,8 @@ var init_DeesServiceLibLoader = __esm({
101382
101410
  return this.xtermLib !== null;
101383
101411
  case "xtermFitAddon":
101384
101412
  return this.xtermFitAddonLib !== null;
101413
+ case "xtermSearchAddon":
101414
+ return this.xtermSearchAddonLib !== null;
101385
101415
  case "highlightJs":
101386
101416
  return this.highlightJsLib !== null;
101387
101417
  case "apexCharts":
@@ -129853,8 +129883,10 @@ init_dist_ts26();
129853
129883
  var demoFunc33 = () => {
129854
129884
  return b2`
129855
129885
  <dees-demowrapper .runAfterRender=${async (elementArg) => {
129856
- const logElement = elementArg.querySelector("dees-chart-log");
129857
- let intervalId;
129886
+ const structuredLog = elementArg.querySelector("#structured-log");
129887
+ const rawLog = elementArg.querySelector("#raw-log");
129888
+ let structuredIntervalId;
129889
+ let rawIntervalId;
129858
129890
  const serverSources = ["Server", "Database", "API", "Auth", "Cache", "Queue", "WebSocket", "Scheduler"];
129859
129891
  const logTemplates = {
129860
129892
  debug: [
@@ -129893,6 +129925,20 @@ var demoFunc33 = () => {
129893
129925
  "Health check passed: all systems operational"
129894
129926
  ]
129895
129927
  };
129928
+ const dockerLogTemplates = [
129929
+ "\x1B[90m2024-01-15T10:23:45.123Z\x1B[0m \x1B[36mINFO\x1B[0m [nginx] GET /api/health 200 - 2ms",
129930
+ "\x1B[90m2024-01-15T10:23:45.456Z\x1B[0m \x1B[33mWARN\x1B[0m [redis] Connection pool running low: 3/10",
129931
+ "\x1B[90m2024-01-15T10:23:45.789Z\x1B[0m \x1B[31mERROR\x1B[0m [mongodb] Query timeout after 30000ms",
129932
+ "\x1B[90m2024-01-15T10:23:46.012Z\x1B[0m \x1B[36mINFO\x1B[0m [app] Processing batch job #{{jobId}}",
129933
+ "\x1B[90m2024-01-15T10:23:46.345Z\x1B[0m \x1B[32mOK\x1B[0m [health] All services healthy",
129934
+ "\x1B[90m2024-01-15T10:23:46.678Z\x1B[0m \x1B[36mINFO\x1B[0m [kafka] Message consumed from topic: events",
129935
+ "\x1B[90m2024-01-15T10:23:47.001Z\x1B[0m \x1B[35mDEBUG\x1B[0m [grpc] Request received: GetUser(id={{userId}})",
129936
+ "\x1B[90m2024-01-15T10:23:47.234Z\x1B[0m \x1B[31mERROR\x1B[0m [auth] Token validation failed: expired",
129937
+ "\x1B[90m2024-01-15T10:23:47.567Z\x1B[0m \x1B[33mWARN\x1B[0m [rate-limit] IP {{ip}} approaching rate limit",
129938
+ "\x1B[90m2024-01-15T10:23:47.890Z\x1B[0m \x1B[36mINFO\x1B[0m [websocket] Client connected: session={{session}}",
129939
+ // Multi-line log entry like stack traces
129940
+ "\x1B[31mError: Connection refused\x1B[0m\n at TcpConnection.connect (/app/node_modules/pg/lib/connection.js:12:15)\n at Pool.connect (/app/node_modules/pg/lib/pool.js:45:23)\n at async DatabaseService.query (/app/src/db/service.ts:89:12)"
129941
+ ];
129896
129942
  const generateRandomLog = () => {
129897
129943
  const levels = ["debug", "info", "warn", "error", "success"];
129898
129944
  const weights = [0.2, 0.5, 0.15, 0.1, 0.05];
@@ -129910,15 +129956,21 @@ var demoFunc33 = () => {
129910
129956
  const templates = logTemplates[level];
129911
129957
  const template = templates[Math.floor(Math.random() * templates.length)];
129912
129958
  const message2 = template.replace("{{module}}", ["express", "mongoose", "redis", "socket.io"][Math.floor(Math.random() * 4)]).replace("{{key}}", "user:" + Math.floor(Math.random() * 1e3)).replace("{{time}}", String(Math.floor(Math.random() * 500) + 50)).replace("{{headers}}", "Content-Type: application/json, Authorization: Bearer ...").replace("{{var}}", ["NODE_ENV", "DATABASE_URL", "API_KEY", "PORT"][Math.floor(Math.random() * 4)]).replace("{{method}}", ["GET", "POST", "PUT", "DELETE"][Math.floor(Math.random() * 4)]).replace("{{path}}", ["/api/users", "/api/auth/login", "/api/products", "/health"][Math.floor(Math.random() * 4)]).replace("{{userId}}", String(Math.floor(Math.random() * 1e4))).replace("{{jobId}}", "job_" + Math.random().toString(36).substring(2, 11)).replace("{{task}}", ["cleanup", "backup", "report-generation", "cache-refresh"][Math.floor(Math.random() * 4)]).replace("{{ip}}", `192.168.1.${Math.floor(Math.random() * 255)}`).replace("{{query}}", "SELECT * FROM users WHERE ...").replace("{{percent}}", String(Math.floor(Math.random() * 30) + 70)).replace("{{endpoint}}", "/api/v1/legacy").replace("{{days}}", String(Math.floor(Math.random() * 30) + 1)).replace("{{error}}", ["ECONNREFUSED", "ETIMEDOUT", "ENOTFOUND"][Math.floor(Math.random() * 3)]).replace("{{user}}", "user_" + Math.floor(Math.random() * 1e3)).replace("{{service}}", ["Redis", "MongoDB", "ElasticSearch"][Math.floor(Math.random() * 3)]).replace("{{port}}", String(3e3 + Math.floor(Math.random() * 10))).replace("{{size}}", String(Math.floor(Math.random() * 500) + 100));
129913
- logElement.addLog(level, message2, source);
129959
+ structuredLog.addLog(level, message2, source);
129960
+ };
129961
+ const generateDockerLog = () => {
129962
+ const template = dockerLogTemplates[Math.floor(Math.random() * dockerLogTemplates.length)];
129963
+ const now2 = (/* @__PURE__ */ new Date()).toISOString();
129964
+ const logLine = template.replace(/2024-01-15T10:23:\d{2}\.\d{3}Z/g, now2).replace("{{jobId}}", String(Math.floor(Math.random() * 1e4))).replace("{{userId}}", String(Math.floor(Math.random() * 1e4))).replace("{{ip}}", `192.168.1.${Math.floor(Math.random() * 255)}`).replace("{{session}}", Math.random().toString(36).substring(2, 11));
129965
+ rawLog.writelnRaw(logLine);
129914
129966
  };
129915
- const startSimulation = () => {
129916
- if (!intervalId) {
129967
+ const startStructuredSimulation = () => {
129968
+ if (!structuredIntervalId) {
129917
129969
  const scheduleNext = () => {
129918
129970
  generateRandomLog();
129919
129971
  const nextDelay = Math.random() * 2e3 + 500;
129920
- intervalId = window.setTimeout(() => {
129921
- if (intervalId) {
129972
+ structuredIntervalId = window.setTimeout(() => {
129973
+ if (structuredIntervalId) {
129922
129974
  scheduleNext();
129923
129975
  }
129924
129976
  }, nextDelay);
@@ -129926,57 +129978,131 @@ var demoFunc33 = () => {
129926
129978
  scheduleNext();
129927
129979
  }
129928
129980
  };
129929
- const stopSimulation = () => {
129930
- if (intervalId) {
129931
- window.clearTimeout(intervalId);
129932
- intervalId = null;
129981
+ const stopStructuredSimulation = () => {
129982
+ if (structuredIntervalId) {
129983
+ window.clearTimeout(structuredIntervalId);
129984
+ structuredIntervalId = null;
129985
+ }
129986
+ };
129987
+ const startRawSimulation = () => {
129988
+ if (!rawIntervalId) {
129989
+ const scheduleNext = () => {
129990
+ generateDockerLog();
129991
+ const nextDelay = Math.random() * 1e3 + 200;
129992
+ rawIntervalId = window.setTimeout(() => {
129993
+ if (rawIntervalId) {
129994
+ scheduleNext();
129995
+ }
129996
+ }, nextDelay);
129997
+ };
129998
+ scheduleNext();
129999
+ }
130000
+ };
130001
+ const stopRawSimulation = () => {
130002
+ if (rawIntervalId) {
130003
+ window.clearTimeout(rawIntervalId);
130004
+ rawIntervalId = null;
129933
130005
  }
129934
130006
  };
129935
130007
  const buttons = elementArg.querySelectorAll("dees-button");
129936
130008
  buttons.forEach((button) => {
129937
130009
  const text9 = button.textContent?.trim();
129938
- if (text9 === "Add Single Log") {
129939
- button.addEventListener("click", () => generateRandomLog());
129940
- } else if (text9 === "Start Simulation") {
129941
- button.addEventListener("click", () => startSimulation());
129942
- } else if (text9 === "Stop Simulation") {
129943
- button.addEventListener("click", () => stopSimulation());
130010
+ switch (text9) {
130011
+ case "Add Structured Log":
130012
+ button.addEventListener("click", () => generateRandomLog());
130013
+ break;
130014
+ case "Start Structured":
130015
+ button.addEventListener("click", () => startStructuredSimulation());
130016
+ break;
130017
+ case "Stop Structured":
130018
+ button.addEventListener("click", () => stopStructuredSimulation());
130019
+ break;
130020
+ case "Add Docker Log":
130021
+ button.addEventListener("click", () => generateDockerLog());
130022
+ break;
130023
+ case "Start Docker":
130024
+ button.addEventListener("click", () => startRawSimulation());
130025
+ break;
130026
+ case "Stop Docker":
130027
+ button.addEventListener("click", () => stopRawSimulation());
130028
+ break;
129944
130029
  }
129945
130030
  });
129946
130031
  }}>
129947
130032
  <style>
129948
- .demoBox {
129949
- position: relative;
129950
- background: #000000;
129951
- height: 100%;
129952
- width: 100%;
129953
- padding: 40px;
129954
- box-sizing: border-box;
129955
- display: flex;
129956
- flex-direction: column;
129957
- gap: 20px;
129958
- }
129959
- .controls {
129960
- display: flex;
129961
- gap: 10px;
129962
- flex-wrap: wrap;
129963
- }
129964
- .info {
129965
- color: #888;
129966
- font-size: 12px;
129967
- font-family: 'Geist Sans', sans-serif;
129968
- }
129969
- </style>
130033
+ ${i`
130034
+ .demoBox {
130035
+ position: relative;
130036
+ background: ${cssManager.bdTheme("hsl(0 0% 95%)", "hsl(0 0% 5%)")};
130037
+ height: 100%;
130038
+ width: 100%;
130039
+ padding: 40px;
130040
+ box-sizing: border-box;
130041
+ display: flex;
130042
+ flex-direction: column;
130043
+ gap: 24px;
130044
+ }
130045
+ .section {
130046
+ display: flex;
130047
+ flex-direction: column;
130048
+ gap: 12px;
130049
+ }
130050
+ .section-title {
130051
+ color: ${cssManager.bdTheme("hsl(0 0% 9%)", "hsl(0 0% 95%)")};
130052
+ font-size: 14px;
130053
+ font-weight: 600;
130054
+ font-family: 'Geist Sans', sans-serif;
130055
+ }
130056
+ .section-description {
130057
+ color: ${cssManager.bdTheme("hsl(215.4 16.3% 46.9%)", "hsl(215 20.2% 65.1%)")};
130058
+ font-size: 12px;
130059
+ font-family: 'Geist Sans', sans-serif;
130060
+ }
130061
+ .controls {
130062
+ display: flex;
130063
+ gap: 10px;
130064
+ flex-wrap: wrap;
130065
+ }
130066
+ `}
130067
+ </style>
129970
130068
  <div class="demoBox">
129971
- <div class="controls">
129972
- <dees-button>Add Single Log</dees-button>
129973
- <dees-button>Start Simulation</dees-button>
129974
- <dees-button>Stop Simulation</dees-button>
130069
+ <!-- Structured Logs Section -->
130070
+ <div class="section">
130071
+ <div class="section-title">Structured Logs (ILogEntry)</div>
130072
+ <div class="section-description">
130073
+ Structured log entries with level, message, and source. Supports search and keyword highlighting.
130074
+ </div>
130075
+ <div class="controls">
130076
+ <dees-button>Add Structured Log</dees-button>
130077
+ <dees-button>Start Structured</dees-button>
130078
+ <dees-button>Stop Structured</dees-button>
130079
+ </div>
130080
+ <dees-chart-log
130081
+ id="structured-log"
130082
+ .label=${"Production Server Logs"}
130083
+ .highlightKeywords=${["error", "failed", "timeout"]}
130084
+ .showMetrics=${true}
130085
+ ></dees-chart-log>
130086
+ </div>
130087
+
130088
+ <!-- Raw Logs Section -->
130089
+ <div class="section">
130090
+ <div class="section-title">Raw Logs (Docker/Container Style)</div>
130091
+ <div class="section-description">
130092
+ Raw log output with ANSI escape sequences for real Docker/container logs.
130093
+ </div>
130094
+ <div class="controls">
130095
+ <dees-button>Add Docker Log</dees-button>
130096
+ <dees-button>Start Docker</dees-button>
130097
+ <dees-button>Stop Docker</dees-button>
130098
+ </div>
130099
+ <dees-chart-log
130100
+ id="raw-log"
130101
+ .label=${"Docker Container Logs"}
130102
+ .mode=${"raw"}
130103
+ .showMetrics=${false}
130104
+ ></dees-chart-log>
129975
130105
  </div>
129976
- <div class="info">Simulating realistic server logs with various levels and sources</div>
129977
- <dees-chart-log
129978
- .label=${"Production Server Logs"}
129979
- ></dees-chart-log>
129980
130106
  </div>
129981
130107
  </dees-demowrapper>
129982
130108
  `;
@@ -129986,16 +130112,37 @@ var demoFunc33 = () => {
129986
130112
  init_dist_ts26();
129987
130113
  init_dist_ts25();
129988
130114
  init_theme();
129989
- var _maxEntries_dec, _autoScroll_dec, _logEntries_dec, _label_dec6, _a45, _DeesChartLog_decorators, _init47, _label6, _logEntries, _autoScroll, _maxEntries;
130115
+ init_services();
130116
+ var _terminalReady_dec, _metrics_dec, _filterMode_dec, _searchQuery_dec2, _showMetrics_dec, _highlightKeywords_dec, _maxEntries_dec, _autoScroll_dec, _logEntries_dec, _mode_dec, _label_dec6, _a45, _DeesChartLog_decorators, _init47, _label6, _mode, _logEntries, _autoScroll, _maxEntries, _highlightKeywords, _showMetrics, _searchQuery2, _filterMode, _metrics, _terminalReady;
129990
130117
  _DeesChartLog_decorators = [t4("dees-chart-log")];
129991
- var DeesChartLog = class extends (_a45 = DeesElement, _label_dec6 = [n5()], _logEntries_dec = [n5({ type: Array })], _autoScroll_dec = [n5({ type: Boolean })], _maxEntries_dec = [n5({ type: Number })], _a45) {
130118
+ var DeesChartLog = class extends (_a45 = DeesElement, _label_dec6 = [n5()], _mode_dec = [n5({ type: String })], _logEntries_dec = [n5({ type: Array })], _autoScroll_dec = [n5({ type: Boolean })], _maxEntries_dec = [n5({ type: Number })], _highlightKeywords_dec = [n5({ type: Array })], _showMetrics_dec = [n5({ type: Boolean })], _searchQuery_dec2 = [r5()], _filterMode_dec = [r5()], _metrics_dec = [r5()], _terminalReady_dec = [r5()], _a45) {
129992
130119
  constructor() {
129993
130120
  super();
129994
130121
  __privateAdd(this, _label6, __runInitializers(_init47, 8, this, "Server Logs")), __runInitializers(_init47, 11, this);
129995
- __privateAdd(this, _logEntries, __runInitializers(_init47, 12, this, [])), __runInitializers(_init47, 15, this);
129996
- __privateAdd(this, _autoScroll, __runInitializers(_init47, 16, this, true)), __runInitializers(_init47, 19, this);
129997
- __privateAdd(this, _maxEntries, __runInitializers(_init47, 20, this, 1e3)), __runInitializers(_init47, 23, this);
129998
- __publicField(this, "logContainer");
130122
+ __privateAdd(this, _mode, __runInitializers(_init47, 12, this, "structured")), __runInitializers(_init47, 15, this);
130123
+ __privateAdd(this, _logEntries, __runInitializers(_init47, 16, this, [])), __runInitializers(_init47, 19, this);
130124
+ __privateAdd(this, _autoScroll, __runInitializers(_init47, 20, this, true)), __runInitializers(_init47, 23, this);
130125
+ __privateAdd(this, _maxEntries, __runInitializers(_init47, 24, this, 1e4)), __runInitializers(_init47, 27, this);
130126
+ __privateAdd(this, _highlightKeywords, __runInitializers(_init47, 28, this, [])), __runInitializers(_init47, 31, this);
130127
+ __privateAdd(this, _showMetrics, __runInitializers(_init47, 32, this, true)), __runInitializers(_init47, 35, this);
130128
+ __privateAdd(this, _searchQuery2, __runInitializers(_init47, 36, this, "")), __runInitializers(_init47, 39, this);
130129
+ __privateAdd(this, _filterMode, __runInitializers(_init47, 40, this, false)), __runInitializers(_init47, 43, this);
130130
+ __privateAdd(this, _metrics, __runInitializers(_init47, 44, this, { debug: 0, info: 0, warn: 0, error: 0, success: 0, total: 0, rate: 0 })), __runInitializers(_init47, 47, this);
130131
+ __privateAdd(this, _terminalReady, __runInitializers(_init47, 48, this, false)), __runInitializers(_init47, 51, this);
130132
+ // Buffer of all log entries for filter mode
130133
+ __publicField(this, "logBuffer", []);
130134
+ // Track trailing hidden entries count for live updates in filter mode
130135
+ __publicField(this, "trailingHiddenCount", 0);
130136
+ // xterm instances
130137
+ __publicField(this, "terminal", null);
130138
+ __publicField(this, "fitAddon", null);
130139
+ __publicField(this, "searchAddon", null);
130140
+ __publicField(this, "resizeObserver", null);
130141
+ __publicField(this, "terminalThemeSubscription", null);
130142
+ __publicField(this, "domtoolsInstance", null);
130143
+ // Rate calculation
130144
+ __publicField(this, "rateBuffer", []);
130145
+ __publicField(this, "rateInterval", null);
129999
130146
  domtools_elementbasic_exports.setup();
130000
130147
  }
130001
130148
  render() {
@@ -130003,105 +130150,508 @@ var DeesChartLog = class extends (_a45 = DeesElement, _label_dec6 = [n5()], _log
130003
130150
  <div class="mainbox">
130004
130151
  <div class="header">
130005
130152
  <div class="title">${this.label}</div>
130153
+ <div class="search-box">
130154
+ <input
130155
+ type="text"
130156
+ placeholder="Search logs..."
130157
+ .value=${this.searchQuery}
130158
+ @input=${(e11) => this.handleSearchInput(e11)}
130159
+ @keydown=${(e11) => this.handleSearchKeydown(e11)}
130160
+ />
130161
+ <div class="search-nav">
130162
+ <button @click=${() => this.searchPrevious()} title="Previous match">↑</button>
130163
+ <button @click=${() => this.searchNext()} title="Next match">↓</button>
130164
+ </div>
130165
+ <button
130166
+ class="filter-toggle ${this.filterMode ? "active" : ""}"
130167
+ @click=${() => this.toggleFilterMode()}
130168
+ title="${this.filterMode ? "Switch to highlight mode" : "Switch to filter mode"}"
130169
+ >
130170
+ ${this.filterMode ? "Filter" : "Highlight"}
130171
+ </button>
130172
+ </div>
130006
130173
  <div class="controls">
130007
- <button
130174
+ <button
130008
130175
  class="control-button ${this.autoScroll ? "active" : ""}"
130009
- @click=${() => {
130010
- this.autoScroll = !this.autoScroll;
130011
- }}
130176
+ @click=${() => this.toggleAutoScroll()}
130012
130177
  >
130013
130178
  Auto Scroll
130014
130179
  </button>
130015
- <button
130016
- class="control-button"
130017
- @click=${() => {
130018
- this.clearLogs();
130019
- }}
130020
- >
130180
+ <button class="control-button" @click=${() => this.clearLogs()}>
130021
130181
  Clear
130022
130182
  </button>
130023
130183
  </div>
130024
130184
  </div>
130025
- <div class="logContainer">
130026
- ${this.logEntries.length === 0 ? b2`<div class="empty-state">No logs to display</div>` : this.logEntries.map((entry) => this.renderLogEntry(entry))}
130185
+
130186
+ <div class="terminal-container">
130187
+ ${!this.terminalReady ? b2`<div class="loading-state">Loading terminal...</div>` : ""}
130027
130188
  </div>
130189
+
130190
+ ${this.showMetrics ? b2`
130191
+ <div class="metrics-bar">
130192
+ <span class="metric error">errors: ${this.metrics.error}</span>
130193
+ <span class="metric warn">warns: ${this.metrics.warn}</span>
130194
+ <span class="metric info">info: ${this.metrics.info}</span>
130195
+ <span class="metric success">success: ${this.metrics.success}</span>
130196
+ <span class="metric debug">debug: ${this.metrics.debug}</span>
130197
+ <span class="metric rate">${this.metrics.rate.toFixed(1)} logs/sec</span>
130198
+ </div>
130199
+ ` : ""}
130028
130200
  </div>
130029
130201
  `;
130030
130202
  }
130031
- renderLogEntry(entry) {
130032
- const timestamp2 = new Date(entry.timestamp).toLocaleTimeString("en-US", {
130203
+ async firstUpdated() {
130204
+ this.domtoolsInstance = await this.domtoolsPromise;
130205
+ await this.initializeTerminal();
130206
+ if (this.logEntries.length > 0) {
130207
+ for (const entry of this.logEntries) {
130208
+ this.writeLogEntry(entry);
130209
+ }
130210
+ }
130211
+ }
130212
+ async initializeTerminal() {
130213
+ const libLoader = DeesServiceLibLoader.getInstance();
130214
+ const [xtermBundle, fitBundle, searchBundle] = await Promise.all([
130215
+ libLoader.loadXterm(),
130216
+ libLoader.loadXtermFitAddon(),
130217
+ libLoader.loadXtermSearchAddon()
130218
+ ]);
130219
+ await this.injectXtermStylesIntoShadow();
130220
+ this.terminal = new xtermBundle.Terminal({
130221
+ cursorBlink: false,
130222
+ disableStdin: true,
130223
+ fontSize: 12,
130224
+ fontFamily: "'SF Mono', 'Monaco', 'Consolas', 'Liberation Mono', 'Courier New', monospace",
130225
+ theme: this.getTerminalTheme(),
130226
+ scrollback: this.maxEntries,
130227
+ convertEol: true
130228
+ });
130229
+ this.fitAddon = new fitBundle.FitAddon();
130230
+ this.searchAddon = new searchBundle.SearchAddon();
130231
+ this.terminal.loadAddon(this.fitAddon);
130232
+ this.terminal.loadAddon(this.searchAddon);
130233
+ const container = this.shadowRoot.querySelector(".terminal-container");
130234
+ this.terminal.open(container);
130235
+ await new Promise((resolve2) => requestAnimationFrame(resolve2));
130236
+ this.fitAddon.fit();
130237
+ this.resizeObserver = new ResizeObserver(() => {
130238
+ this.fitAddon?.fit();
130239
+ });
130240
+ this.resizeObserver.observe(container);
130241
+ this.terminalThemeSubscription = this.domtoolsInstance.themeManager.themeObservable.subscribe(() => {
130242
+ if (this.terminal) {
130243
+ this.terminal.options.theme = this.getTerminalTheme();
130244
+ }
130245
+ });
130246
+ this.rateInterval = setInterval(() => this.calculateRate(), 1e3);
130247
+ this.terminalReady = true;
130248
+ }
130249
+ getTerminalTheme() {
130250
+ const isDark = this.domtoolsInstance?.themeManager?.isDarkMode ?? true;
130251
+ return isDark ? {
130252
+ background: "#0a0a0a",
130253
+ foreground: "#e0e0e0",
130254
+ cursor: "#e0e0e0",
130255
+ selectionBackground: "#404040",
130256
+ black: "#000000",
130257
+ red: "#ff5555",
130258
+ green: "#50fa7b",
130259
+ yellow: "#f1fa8c",
130260
+ blue: "#6272a4",
130261
+ magenta: "#ff79c6",
130262
+ cyan: "#8be9fd",
130263
+ white: "#f8f8f2",
130264
+ brightBlack: "#6272a4",
130265
+ brightRed: "#ff6e6e",
130266
+ brightGreen: "#69ff94",
130267
+ brightYellow: "#ffffa5",
130268
+ brightBlue: "#d6acff",
130269
+ brightMagenta: "#ff92df",
130270
+ brightCyan: "#a4ffff",
130271
+ brightWhite: "#ffffff"
130272
+ } : {
130273
+ background: "#ffffff",
130274
+ foreground: "#333333",
130275
+ cursor: "#333333",
130276
+ selectionBackground: "#add6ff",
130277
+ black: "#000000",
130278
+ red: "#cd3131",
130279
+ green: "#00bc00",
130280
+ yellow: "#949800",
130281
+ blue: "#0451a5",
130282
+ magenta: "#bc05bc",
130283
+ cyan: "#0598bc",
130284
+ white: "#555555",
130285
+ brightBlack: "#666666",
130286
+ brightRed: "#cd3131",
130287
+ brightGreen: "#14ce14",
130288
+ brightYellow: "#b5ba00",
130289
+ brightBlue: "#0451a5",
130290
+ brightMagenta: "#bc05bc",
130291
+ brightCyan: "#0598bc",
130292
+ brightWhite: "#a5a5a5"
130293
+ };
130294
+ }
130295
+ /**
130296
+ * Inject xterm CSS styles into shadow root
130297
+ * This is needed because shadow DOM doesn't inherit styles from document.head
130298
+ */
130299
+ async injectXtermStylesIntoShadow() {
130300
+ const styleId = "xterm-shadow-styles";
130301
+ if (this.shadowRoot.getElementById(styleId)) {
130302
+ return;
130303
+ }
130304
+ const cssUrl = `${CDN_BASE}/xterm@${CDN_VERSIONS.xterm}/css/xterm.css`;
130305
+ const response = await fetch(cssUrl);
130306
+ const cssText = await response.text();
130307
+ const style = document.createElement("style");
130308
+ style.id = styleId;
130309
+ style.textContent = cssText;
130310
+ this.shadowRoot.appendChild(style);
130311
+ }
130312
+ // =====================
130313
+ // Structured Log Methods
130314
+ // =====================
130315
+ /**
130316
+ * Add a single structured log entry
130317
+ */
130318
+ addLog(level, message2, source) {
130319
+ const entry = {
130320
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
130321
+ level,
130322
+ message: message2,
130323
+ source
130324
+ };
130325
+ this.logBuffer.push(entry);
130326
+ if (this.logBuffer.length > this.maxEntries) {
130327
+ this.logBuffer.shift();
130328
+ }
130329
+ if (!this.filterMode || !this.searchQuery) {
130330
+ this.writeLogEntry(entry);
130331
+ } else if (this.entryMatchesFilter(entry)) {
130332
+ this.trailingHiddenCount = 0;
130333
+ this.writeLogEntry(entry);
130334
+ } else {
130335
+ this.updateTrailingPlaceholder();
130336
+ }
130337
+ this.updateMetrics(entry.level);
130338
+ }
130339
+ /**
130340
+ * Add multiple structured log entries
130341
+ */
130342
+ updateLog(entries) {
130343
+ if (!entries) return;
130344
+ for (const entry of entries) {
130345
+ this.logBuffer.push(entry);
130346
+ if (this.logBuffer.length > this.maxEntries) {
130347
+ this.logBuffer.shift();
130348
+ }
130349
+ if (!this.filterMode || !this.searchQuery) {
130350
+ this.writeLogEntry(entry);
130351
+ } else if (this.entryMatchesFilter(entry)) {
130352
+ this.trailingHiddenCount = 0;
130353
+ this.writeLogEntry(entry);
130354
+ } else {
130355
+ this.updateTrailingPlaceholder();
130356
+ }
130357
+ this.updateMetrics(entry.level);
130358
+ }
130359
+ }
130360
+ /**
130361
+ * Update the trailing hidden placeholder in real-time
130362
+ * Clears the last line if a placeholder already exists, then writes updated count
130363
+ */
130364
+ updateTrailingPlaceholder() {
130365
+ if (!this.terminal) return;
130366
+ if (this.trailingHiddenCount > 0) {
130367
+ this.terminal.write("\x1B[1A\x1B[2K\r");
130368
+ }
130369
+ this.trailingHiddenCount++;
130370
+ this.writeHiddenPlaceholder(this.trailingHiddenCount);
130371
+ if (this.autoScroll) {
130372
+ this.terminal.scrollToBottom();
130373
+ }
130374
+ }
130375
+ /**
130376
+ * Check if a log entry matches the current filter
130377
+ */
130378
+ entryMatchesFilter(entry) {
130379
+ if (!this.searchQuery) return true;
130380
+ const query4 = this.searchQuery.toLowerCase();
130381
+ return entry.message.toLowerCase().includes(query4) || entry.level.toLowerCase().includes(query4) || (entry.source?.toLowerCase().includes(query4) ?? false);
130382
+ }
130383
+ writeLogEntry(entry) {
130384
+ if (!this.terminal) return;
130385
+ const formatted = this.formatLogEntry(entry);
130386
+ this.terminal.writeln(formatted);
130387
+ if (this.autoScroll) {
130388
+ this.terminal.scrollToBottom();
130389
+ }
130390
+ }
130391
+ formatLogEntry(entry) {
130392
+ const timestamp2 = this.formatTimestamp(entry.timestamp);
130393
+ const levelColors = {
130394
+ debug: "\x1B[90m",
130395
+ // Gray
130396
+ info: "\x1B[36m",
130397
+ // Cyan
130398
+ warn: "\x1B[33m",
130399
+ // Yellow
130400
+ error: "\x1B[31m",
130401
+ // Red
130402
+ success: "\x1B[32m"
130403
+ // Green
130404
+ };
130405
+ const reset = "\x1B[0m";
130406
+ const dim = "\x1B[2m";
130407
+ const levelStr = `${levelColors[entry.level]}[${entry.level.toUpperCase().padEnd(7)}]${reset}`;
130408
+ const sourceStr = entry.source ? `${dim}[${entry.source}]${reset} ` : "";
130409
+ const messageStr = this.applyHighlights(entry.message);
130410
+ return `${dim}${timestamp2}${reset} ${levelStr} ${sourceStr}${messageStr}`;
130411
+ }
130412
+ formatTimestamp(isoString) {
130413
+ const date = new Date(isoString);
130414
+ return date.toLocaleTimeString("en-US", {
130033
130415
  hour12: false,
130034
130416
  hour: "2-digit",
130035
130417
  minute: "2-digit",
130036
130418
  second: "2-digit",
130037
130419
  fractionalSecondDigits: 3
130038
130420
  });
130039
- return b2`
130040
- <div class="logEntry">
130041
- <span class="timestamp">${timestamp2}</span>
130042
- <span class="level ${entry.level}">${entry.level}</span>
130043
- ${entry.source ? b2`<span class="source">[${entry.source}]</span>` : ""}
130044
- <span class="message">${entry.message}</span>
130045
- </div>
130046
- `;
130047
130421
  }
130048
- async firstUpdated() {
130049
- await this.domtoolsPromise;
130050
- this.logContainer = this.shadowRoot.querySelector(".logContainer");
130051
- const demoLogs = [
130052
- { timestamp: (/* @__PURE__ */ new Date()).toISOString(), level: "info", message: "Server started on port 3000", source: "Server" },
130053
- { timestamp: (/* @__PURE__ */ new Date()).toISOString(), level: "debug", message: "Loading configuration from /etc/app/config.json", source: "Config" },
130054
- { timestamp: (/* @__PURE__ */ new Date()).toISOString(), level: "info", message: "Connected to MongoDB at mongodb://localhost:27017", source: "Database" },
130055
- { timestamp: (/* @__PURE__ */ new Date()).toISOString(), level: "success", message: "Database connection established successfully", source: "Database" },
130056
- { timestamp: (/* @__PURE__ */ new Date()).toISOString(), level: "warn", message: "No SSL certificate found, using self-signed certificate", source: "Security" },
130057
- { timestamp: (/* @__PURE__ */ new Date()).toISOString(), level: "info", message: "API routes initialized: GET /api/users, POST /api/users, DELETE /api/users/:id", source: "Router" },
130058
- { timestamp: (/* @__PURE__ */ new Date()).toISOString(), level: "debug", message: "Middleware stack: cors, bodyParser, authentication, errorHandler", source: "Middleware" },
130059
- { timestamp: (/* @__PURE__ */ new Date()).toISOString(), level: "info", message: "WebSocket server listening on ws://localhost:3001", source: "WebSocket" }
130060
- ];
130061
- this.logEntries = demoLogs;
130062
- this.scrollToBottom();
130063
- }
130064
- async updateLog(entries) {
130065
- if (entries) {
130066
- this.logEntries = [...this.logEntries, ...entries];
130067
- if (this.logEntries.length > this.maxEntries) {
130068
- this.logEntries = this.logEntries.slice(-this.maxEntries);
130422
+ applyHighlights(text9) {
130423
+ const keywords = [...this.highlightKeywords];
130424
+ if (this.filterMode && this.searchQuery) {
130425
+ keywords.push(this.searchQuery);
130426
+ }
130427
+ if (keywords.length === 0) return text9;
130428
+ let result = text9;
130429
+ for (const keyword of keywords) {
130430
+ const escaped = keyword.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
130431
+ const regex = new RegExp(`(${escaped})`, "gi");
130432
+ result = result.replace(regex, "\x1B[43m\x1B[30m$1\x1B[0m");
130433
+ }
130434
+ return result;
130435
+ }
130436
+ // =====================
130437
+ // Raw Log Methods
130438
+ // =====================
130439
+ /**
130440
+ * Write raw data to the terminal (for Docker logs, etc.)
130441
+ */
130442
+ writeRaw(data) {
130443
+ if (!this.terminal) return;
130444
+ this.terminal.write(data);
130445
+ this.recordLogEvent();
130446
+ if (this.autoScroll) {
130447
+ this.terminal.scrollToBottom();
130448
+ }
130449
+ }
130450
+ /**
130451
+ * Write a raw line to the terminal
130452
+ */
130453
+ writelnRaw(line) {
130454
+ if (!this.terminal) return;
130455
+ this.terminal.writeln(line);
130456
+ this.recordLogEvent();
130457
+ if (this.autoScroll) {
130458
+ this.terminal.scrollToBottom();
130459
+ }
130460
+ }
130461
+ // =====================
130462
+ // Search Methods
130463
+ // =====================
130464
+ handleSearchInput(e11) {
130465
+ const input = e11.target;
130466
+ const newQuery = input.value;
130467
+ const queryChanged = this.searchQuery !== newQuery;
130468
+ this.searchQuery = newQuery;
130469
+ if (this.filterMode && queryChanged) {
130470
+ this.reRenderFilteredLogs();
130471
+ } else if (this.searchQuery) {
130472
+ this.searchAddon?.findNext(this.searchQuery);
130473
+ }
130474
+ }
130475
+ handleSearchKeydown(e11) {
130476
+ if (e11.key === "Enter") {
130477
+ if (e11.shiftKey) {
130478
+ this.searchPrevious();
130479
+ } else {
130480
+ this.searchNext();
130069
130481
  }
130070
- this.requestUpdate();
130071
- await this.updateComplete;
130072
- if (this.autoScroll) {
130073
- this.scrollToBottom();
130482
+ } else if (e11.key === "Escape") {
130483
+ this.searchQuery = "";
130484
+ e11.target.value = "";
130485
+ }
130486
+ }
130487
+ /**
130488
+ * Search for a query in the terminal
130489
+ */
130490
+ search(query4) {
130491
+ this.searchQuery = query4;
130492
+ this.searchAddon?.findNext(query4);
130493
+ }
130494
+ /**
130495
+ * Find next search match
130496
+ */
130497
+ searchNext() {
130498
+ if (this.searchQuery) {
130499
+ this.searchAddon?.findNext(this.searchQuery);
130500
+ }
130501
+ }
130502
+ /**
130503
+ * Find previous search match
130504
+ */
130505
+ searchPrevious() {
130506
+ if (this.searchQuery) {
130507
+ this.searchAddon?.findPrevious(this.searchQuery);
130508
+ }
130509
+ }
130510
+ // =====================
130511
+ // Control Methods
130512
+ // =====================
130513
+ toggleAutoScroll() {
130514
+ this.autoScroll = !this.autoScroll;
130515
+ if (this.autoScroll && this.terminal) {
130516
+ this.terminal.scrollToBottom();
130517
+ }
130518
+ }
130519
+ /**
130520
+ * Toggle between filter mode and highlight mode
130521
+ */
130522
+ toggleFilterMode() {
130523
+ this.filterMode = !this.filterMode;
130524
+ this.reRenderFilteredLogs();
130525
+ }
130526
+ /**
130527
+ * Re-render logs based on current filter state
130528
+ * In filter mode: show matching logs with placeholders for hidden entries
130529
+ * In highlight mode: show all logs
130530
+ */
130531
+ reRenderFilteredLogs() {
130532
+ if (!this.terminal) return;
130533
+ this.terminal.clear();
130534
+ this.trailingHiddenCount = 0;
130535
+ if (!this.filterMode || !this.searchQuery) {
130536
+ for (const entry of this.logBuffer) {
130537
+ const formatted = this.formatLogEntry(entry);
130538
+ this.terminal.writeln(formatted);
130074
130539
  }
130540
+ } else {
130541
+ let hiddenCount = 0;
130542
+ for (const entry of this.logBuffer) {
130543
+ if (this.entryMatchesFilter(entry)) {
130544
+ if (hiddenCount > 0) {
130545
+ this.writeHiddenPlaceholder(hiddenCount);
130546
+ hiddenCount = 0;
130547
+ }
130548
+ const formatted = this.formatLogEntry(entry);
130549
+ this.terminal.writeln(formatted);
130550
+ } else {
130551
+ hiddenCount++;
130552
+ }
130553
+ }
130554
+ if (hiddenCount > 0) {
130555
+ this.writeHiddenPlaceholder(hiddenCount);
130556
+ this.trailingHiddenCount = hiddenCount;
130557
+ }
130558
+ }
130559
+ if (this.autoScroll) {
130560
+ this.terminal.scrollToBottom();
130075
130561
  }
130076
130562
  }
130563
+ /**
130564
+ * Write a placeholder line showing how many log entries are hidden by filter
130565
+ */
130566
+ writeHiddenPlaceholder(count2) {
130567
+ const dim = "\x1B[2m";
130568
+ const reset = "\x1B[0m";
130569
+ const text9 = count2 === 1 ? `[1 log line hidden by filter ...]` : `[${count2} log lines hidden by filter ...]`;
130570
+ this.terminal?.writeln(`${dim}${text9}${reset}`);
130571
+ }
130572
+ /**
130573
+ * Clear all logs and reset metrics
130574
+ */
130077
130575
  clearLogs() {
130078
- this.logEntries = [];
130079
- this.requestUpdate();
130576
+ this.terminal?.clear();
130577
+ this.logBuffer = [];
130578
+ this.trailingHiddenCount = 0;
130579
+ this.resetMetrics();
130080
130580
  }
130581
+ /**
130582
+ * Scroll to the bottom of the log
130583
+ */
130081
130584
  scrollToBottom() {
130082
- if (this.logContainer) {
130083
- this.logContainer.scrollTop = this.logContainer.scrollHeight;
130084
- }
130585
+ this.terminal?.scrollToBottom();
130085
130586
  }
130086
- addLog(level, message2, source) {
130087
- const newEntry = {
130088
- timestamp: (/* @__PURE__ */ new Date()).toISOString(),
130089
- level,
130090
- message: message2,
130091
- source
130587
+ // =====================
130588
+ // Metrics Methods
130589
+ // =====================
130590
+ updateMetrics(level) {
130591
+ this.metrics = {
130592
+ ...this.metrics,
130593
+ [level]: this.metrics[level] + 1,
130594
+ total: this.metrics.total + 1
130092
130595
  };
130093
- this.updateLog([newEntry]);
130596
+ this.recordLogEvent();
130597
+ }
130598
+ recordLogEvent() {
130599
+ this.rateBuffer.push(Date.now());
130600
+ }
130601
+ calculateRate() {
130602
+ const now2 = Date.now();
130603
+ this.rateBuffer = this.rateBuffer.filter((t9) => now2 - t9 < 1e4);
130604
+ const rate = this.rateBuffer.length / 10;
130605
+ if (rate !== this.metrics.rate) {
130606
+ this.metrics = { ...this.metrics, rate };
130607
+ }
130608
+ }
130609
+ resetMetrics() {
130610
+ this.metrics = { debug: 0, info: 0, warn: 0, error: 0, success: 0, total: 0, rate: 0 };
130611
+ this.rateBuffer = [];
130612
+ }
130613
+ // =====================
130614
+ // Lifecycle
130615
+ // =====================
130616
+ async disconnectedCallback() {
130617
+ await super.disconnectedCallback();
130618
+ if (this.resizeObserver) {
130619
+ this.resizeObserver.disconnect();
130620
+ }
130621
+ if (this.terminalThemeSubscription) {
130622
+ this.terminalThemeSubscription.unsubscribe();
130623
+ }
130624
+ if (this.rateInterval) {
130625
+ clearInterval(this.rateInterval);
130626
+ }
130627
+ if (this.terminal) {
130628
+ this.terminal.dispose();
130629
+ }
130094
130630
  }
130095
130631
  };
130096
130632
  _init47 = __decoratorStart(_a45);
130097
130633
  _label6 = new WeakMap();
130634
+ _mode = new WeakMap();
130098
130635
  _logEntries = new WeakMap();
130099
130636
  _autoScroll = new WeakMap();
130100
130637
  _maxEntries = new WeakMap();
130638
+ _highlightKeywords = new WeakMap();
130639
+ _showMetrics = new WeakMap();
130640
+ _searchQuery2 = new WeakMap();
130641
+ _filterMode = new WeakMap();
130642
+ _metrics = new WeakMap();
130643
+ _terminalReady = new WeakMap();
130101
130644
  __decorateElement(_init47, 4, "label", _label_dec6, DeesChartLog, _label6);
130645
+ __decorateElement(_init47, 4, "mode", _mode_dec, DeesChartLog, _mode);
130102
130646
  __decorateElement(_init47, 4, "logEntries", _logEntries_dec, DeesChartLog, _logEntries);
130103
130647
  __decorateElement(_init47, 4, "autoScroll", _autoScroll_dec, DeesChartLog, _autoScroll);
130104
130648
  __decorateElement(_init47, 4, "maxEntries", _maxEntries_dec, DeesChartLog, _maxEntries);
130649
+ __decorateElement(_init47, 4, "highlightKeywords", _highlightKeywords_dec, DeesChartLog, _highlightKeywords);
130650
+ __decorateElement(_init47, 4, "showMetrics", _showMetrics_dec, DeesChartLog, _showMetrics);
130651
+ __decorateElement(_init47, 4, "searchQuery", _searchQuery_dec2, DeesChartLog, _searchQuery2);
130652
+ __decorateElement(_init47, 4, "filterMode", _filterMode_dec, DeesChartLog, _filterMode);
130653
+ __decorateElement(_init47, 4, "metrics", _metrics_dec, DeesChartLog, _metrics);
130654
+ __decorateElement(_init47, 4, "terminalReady", _terminalReady_dec, DeesChartLog, _terminalReady);
130105
130655
  DeesChartLog = __decorateElement(_init47, 0, "DeesChartLog", _DeesChartLog_decorators, DeesChartLog);
130106
130656
  __publicField(DeesChartLog, "demo", demoFunc33);
130107
130657
  __publicField(DeesChartLog, "demoGroup", "Chart");
@@ -130109,13 +130659,12 @@ __publicField(DeesChartLog, "styles", [
130109
130659
  themeDefaultStyles,
130110
130660
  cssManager.defaultStyles,
130111
130661
  i`
130112
- /* TODO: Migrate hardcoded values to --dees-* CSS variables */
130113
130662
  :host {
130114
- font-family: 'SF Mono', 'Monaco', 'Consolas', 'Liberation Mono', 'Courier New', monospace;
130663
+ display: block;
130664
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
130115
130665
  color: ${cssManager.bdTheme("hsl(0 0% 3.9%)", "hsl(0 0% 98%)")};
130116
- font-size: 12px;
130117
- line-height: 1.5;
130118
130666
  }
130667
+
130119
130668
  .mainbox {
130120
130669
  position: relative;
130121
130670
  width: 100%;
@@ -130130,143 +130679,197 @@ __publicField(DeesChartLog, "styles", [
130130
130679
 
130131
130680
  .header {
130132
130681
  background: ${cssManager.bdTheme("hsl(0 0% 97%)", "hsl(0 0% 7%)")};
130133
- padding: 12px 16px;
130682
+ padding: 8px 12px;
130134
130683
  border-bottom: 1px solid ${cssManager.bdTheme("hsl(0 0% 89.8%)", "hsl(0 0% 14.9%)")};
130135
130684
  display: flex;
130136
- justify-content: space-between;
130137
130685
  align-items: center;
130686
+ gap: 12px;
130138
130687
  flex-shrink: 0;
130688
+ flex-wrap: wrap;
130139
130689
  }
130140
130690
 
130141
130691
  .title {
130142
130692
  font-weight: 500;
130143
130693
  font-size: 14px;
130144
130694
  color: ${cssManager.bdTheme("hsl(0 0% 9%)", "hsl(0 0% 95%)")};
130145
- font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
130695
+ white-space: nowrap;
130146
130696
  }
130147
130697
 
130148
- .controls {
130698
+ .search-box {
130149
130699
  display: flex;
130150
- gap: 8px;
130700
+ align-items: center;
130701
+ gap: 4px;
130702
+ flex: 1;
130703
+ min-width: 150px;
130704
+ max-width: 300px;
130151
130705
  }
130152
130706
 
130153
- .control-button {
130154
- background: ${cssManager.bdTheme("hsl(0 0% 100%)", "hsl(0 0% 14.9%)")};
130155
- border: 1px solid ${cssManager.bdTheme("hsl(0 0% 89.8%)", "hsl(0 0% 14.9%)")};
130156
- border-radius: 6px;
130157
- padding: 6px 12px;
130158
- color: ${cssManager.bdTheme("hsl(0 0% 45.1%)", "hsl(0 0% 63.9%)")};
130159
- cursor: pointer;
130707
+ .search-box input {
130708
+ flex: 1;
130709
+ padding: 4px 8px;
130160
130710
  font-size: 12px;
130161
- font-weight: 500;
130162
- transition: all 0.15s;
130163
- font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
130164
- }
130165
-
130166
- .control-button:hover {
130167
- background: ${cssManager.bdTheme("hsl(0 0% 95.1%)", "hsl(0 0% 14.9%)")};
130168
- border-color: ${cssManager.bdTheme("hsl(0 0% 79.8%)", "hsl(0 0% 20.9%)")};
130169
- color: ${cssManager.bdTheme("hsl(0 0% 15%)", "hsl(0 0% 93.9%)")};
130711
+ border: 1px solid ${cssManager.bdTheme("hsl(0 0% 89.8%)", "hsl(0 0% 14.9%)")};
130712
+ border-radius: 4px;
130713
+ background: ${cssManager.bdTheme("hsl(0 0% 100%)", "hsl(0 0% 9%)")};
130714
+ color: ${cssManager.bdTheme("hsl(0 0% 9%)", "hsl(0 0% 95%)")};
130715
+ outline: none;
130170
130716
  }
130171
130717
 
130172
- .control-button.active {
130173
- background: ${cssManager.bdTheme("hsl(0 0% 9%)", "hsl(0 0% 93.9%)")};
130174
- color: ${cssManager.bdTheme("hsl(0 0% 98%)", "hsl(0 0% 3.9%)")};
130718
+ .search-box input:focus {
130719
+ border-color: ${cssManager.bdTheme("hsl(222.2 47.4% 51.2%)", "hsl(217.2 91.2% 59.8%)")};
130175
130720
  }
130176
130721
 
130177
- .logContainer {
130178
- flex: 1;
130179
- overflow-y: auto;
130180
- overflow-x: hidden;
130181
- padding: 16px;
130182
- font-size: 12px;
130722
+ .search-box input::placeholder {
130723
+ color: ${cssManager.bdTheme("hsl(0 0% 63.9%)", "hsl(0 0% 45.1%)")};
130183
130724
  }
130184
130725
 
130185
- .logEntry {
130186
- margin-bottom: 4px;
130726
+ .search-nav {
130187
130727
  display: flex;
130188
- white-space: pre-wrap;
130189
- word-break: break-all;
130190
- font-variant-numeric: tabular-nums;
130728
+ gap: 2px;
130191
130729
  }
130192
130730
 
130193
- .timestamp {
130194
- color: ${cssManager.bdTheme("hsl(0 0% 63.9%)", "hsl(0 0% 45.1%)")};
130195
- margin-right: 12px;
130196
- flex-shrink: 0;
130731
+ .search-nav button {
130732
+ padding: 4px 6px;
130733
+ font-size: 11px;
130734
+ background: ${cssManager.bdTheme("hsl(0 0% 100%)", "hsl(0 0% 14.9%)")};
130735
+ border: 1px solid ${cssManager.bdTheme("hsl(0 0% 89.8%)", "hsl(0 0% 14.9%)")};
130736
+ border-radius: 3px;
130737
+ color: ${cssManager.bdTheme("hsl(0 0% 45.1%)", "hsl(0 0% 63.9%)")};
130738
+ cursor: pointer;
130739
+ line-height: 1;
130197
130740
  }
130198
130741
 
130199
- .level {
130200
- margin-right: 8px;
130201
- padding: 0 6px;
130202
- border-radius: 3px;
130203
- font-weight: 600;
130204
- text-transform: uppercase;
130205
- font-size: 10px;
130206
- flex-shrink: 0;
130742
+ .search-nav button:hover {
130743
+ background: ${cssManager.bdTheme("hsl(0 0% 95.1%)", "hsl(0 0% 20%)")};
130744
+ color: ${cssManager.bdTheme("hsl(0 0% 15%)", "hsl(0 0% 93.9%)")};
130207
130745
  }
130208
130746
 
130209
- .level.debug {
130747
+ .filter-toggle {
130748
+ padding: 4px 8px;
130749
+ font-size: 11px;
130750
+ font-weight: 500;
130751
+ background: ${cssManager.bdTheme("hsl(0 0% 100%)", "hsl(0 0% 14.9%)")};
130752
+ border: 1px solid ${cssManager.bdTheme("hsl(0 0% 89.8%)", "hsl(0 0% 14.9%)")};
130753
+ border-radius: 4px;
130210
130754
  color: ${cssManager.bdTheme("hsl(0 0% 45.1%)", "hsl(0 0% 63.9%)")};
130211
- background: ${cssManager.bdTheme("hsl(0 0% 45.1% / 0.1)", "hsl(0 0% 63.9% / 0.1)")};
130755
+ cursor: pointer;
130756
+ transition: all 0.15s;
130757
+ white-space: nowrap;
130212
130758
  }
130213
130759
 
130214
- .level.info {
130215
- color: ${cssManager.bdTheme("hsl(222.2 47.4% 51.2%)", "hsl(217.2 91.2% 59.8%)")};
130216
- background: ${cssManager.bdTheme("hsl(222.2 47.4% 51.2% / 0.1)", "hsl(217.2 91.2% 59.8% / 0.1)")};
130760
+ .filter-toggle:hover {
130761
+ background: ${cssManager.bdTheme("hsl(0 0% 95.1%)", "hsl(0 0% 20%)")};
130762
+ color: ${cssManager.bdTheme("hsl(0 0% 15%)", "hsl(0 0% 93.9%)")};
130217
130763
  }
130218
130764
 
130219
- .level.warn {
130220
- color: ${cssManager.bdTheme("hsl(25 95% 53%)", "hsl(25 95% 63%)")};
130221
- background: ${cssManager.bdTheme("hsl(25 95% 53% / 0.1)", "hsl(25 95% 63% / 0.1)")};
130765
+ .filter-toggle.active {
130766
+ background: ${cssManager.bdTheme("hsl(45 93% 47%)", "hsl(45 93% 47%)")};
130767
+ border-color: ${cssManager.bdTheme("hsl(45 93% 47%)", "hsl(45 93% 47%)")};
130768
+ color: hsl(0 0% 9%);
130222
130769
  }
130223
130770
 
130224
- .level.error {
130225
- color: ${cssManager.bdTheme("hsl(0 84.2% 60.2%)", "hsl(0 72.2% 50.6%)")};
130226
- background: ${cssManager.bdTheme("hsl(0 84.2% 60.2% / 0.1)", "hsl(0 72.2% 50.6% / 0.1)")};
130771
+ .controls {
130772
+ display: flex;
130773
+ gap: 6px;
130774
+ margin-left: auto;
130227
130775
  }
130228
130776
 
130229
- .level.success {
130230
- color: ${cssManager.bdTheme("hsl(142.1 76.2% 36.3%)", "hsl(142.1 70.6% 45.3%)")};
130231
- background: ${cssManager.bdTheme("hsl(142.1 76.2% 36.3% / 0.1)", "hsl(142.1 70.6% 45.3% / 0.1)")};
130777
+ .control-button {
130778
+ background: ${cssManager.bdTheme("hsl(0 0% 100%)", "hsl(0 0% 14.9%)")};
130779
+ border: 1px solid ${cssManager.bdTheme("hsl(0 0% 89.8%)", "hsl(0 0% 14.9%)")};
130780
+ border-radius: 4px;
130781
+ padding: 4px 10px;
130782
+ color: ${cssManager.bdTheme("hsl(0 0% 45.1%)", "hsl(0 0% 63.9%)")};
130783
+ cursor: pointer;
130784
+ font-size: 12px;
130785
+ font-weight: 500;
130786
+ transition: all 0.15s;
130232
130787
  }
130233
130788
 
130234
- .source {
130235
- color: ${cssManager.bdTheme("hsl(0 0% 45.1%)", "hsl(0 0% 63.9%)")};
130236
- margin-right: 8px;
130237
- flex-shrink: 0;
130789
+ .control-button:hover {
130790
+ background: ${cssManager.bdTheme("hsl(0 0% 95.1%)", "hsl(0 0% 20%)")};
130791
+ border-color: ${cssManager.bdTheme("hsl(0 0% 79.8%)", "hsl(0 0% 25%)")};
130792
+ color: ${cssManager.bdTheme("hsl(0 0% 15%)", "hsl(0 0% 93.9%)")};
130238
130793
  }
130239
130794
 
130240
- .message {
130241
- color: ${cssManager.bdTheme("hsl(0 0% 15%)", "hsl(0 0% 90%)")};
130795
+ .control-button.active {
130796
+ background: ${cssManager.bdTheme("hsl(222.2 47.4% 51.2%)", "hsl(217.2 91.2% 59.8%)")};
130797
+ border-color: ${cssManager.bdTheme("hsl(222.2 47.4% 51.2%)", "hsl(217.2 91.2% 59.8%)")};
130798
+ color: white;
130799
+ }
130800
+
130801
+ .terminal-container {
130242
130802
  flex: 1;
130803
+ overflow: hidden;
130804
+ padding: 8px;
130805
+ background: ${cssManager.bdTheme("hsl(0 0% 100%)", "hsl(0 0% 3.9%)")};
130243
130806
  }
130244
130807
 
130245
- .empty-state {
130808
+ .terminal-container .xterm {
130809
+ height: 100%;
130810
+ }
130811
+
130812
+ .loading-state {
130246
130813
  display: flex;
130247
130814
  align-items: center;
130248
130815
  justify-content: center;
130249
130816
  height: 100%;
130250
130817
  color: ${cssManager.bdTheme("hsl(0 0% 45.1%)", "hsl(0 0% 63.9%)")};
130251
130818
  font-style: italic;
130819
+ font-size: 13px;
130252
130820
  }
130253
130821
 
130254
- /* Custom scrollbar */
130255
- .logContainer::-webkit-scrollbar {
130822
+ .metrics-bar {
130823
+ background: ${cssManager.bdTheme("hsl(0 0% 97%)", "hsl(0 0% 7%)")};
130824
+ border-top: 1px solid ${cssManager.bdTheme("hsl(0 0% 89.8%)", "hsl(0 0% 14.9%)")};
130825
+ padding: 6px 12px;
130826
+ display: flex;
130827
+ gap: 16px;
130828
+ font-size: 11px;
130829
+ font-weight: 500;
130830
+ flex-shrink: 0;
130831
+ }
130832
+
130833
+ .metric {
130834
+ display: flex;
130835
+ align-items: center;
130836
+ gap: 4px;
130837
+ }
130838
+
130839
+ .metric::before {
130840
+ content: '';
130256
130841
  width: 8px;
130842
+ height: 8px;
130843
+ border-radius: 50%;
130844
+ }
130845
+
130846
+ .metric.error::before {
130847
+ background: hsl(0 84.2% 60.2%);
130257
130848
  }
130258
130849
 
130259
- .logContainer::-webkit-scrollbar-track {
130260
- background: ${cssManager.bdTheme("hsl(0 0% 95%)", "hsl(0 0% 10%)")};
130850
+ .metric.warn::before {
130851
+ background: hsl(25 95% 53%);
130261
130852
  }
130262
130853
 
130263
- .logContainer::-webkit-scrollbar-thumb {
130264
- background: ${cssManager.bdTheme("hsl(0 0% 70%)", "hsl(0 0% 30%)")};
130265
- border-radius: 4px;
130854
+ .metric.info::before {
130855
+ background: hsl(222.2 47.4% 51.2%);
130266
130856
  }
130267
130857
 
130268
- .logContainer::-webkit-scrollbar-thumb:hover {
130269
- background: ${cssManager.bdTheme("hsl(0 0% 60%)", "hsl(0 0% 40%)")};
130858
+ .metric.success::before {
130859
+ background: hsl(142.1 76.2% 36.3%);
130860
+ }
130861
+
130862
+ .metric.debug::before {
130863
+ background: hsl(0 0% 63.9%);
130864
+ }
130865
+
130866
+ .metric.rate {
130867
+ margin-left: auto;
130868
+ color: ${cssManager.bdTheme("hsl(0 0% 45.1%)", "hsl(0 0% 63.9%)")};
130869
+ }
130870
+
130871
+ .metric.rate::before {
130872
+ display: none;
130270
130873
  }
130271
130874
  `
130272
130875
  ]);
@@ -154160,9 +154763,9 @@ var openWidgetContextMenu = ({
154160
154763
  // ts_web/elements/dees-dashboardgrid/dees-dashboardgrid.ts
154161
154764
  init_dist_ts26();
154162
154765
  init_dees_icon();
154163
- var _previewWidgets_dec, _resolvedMargins_dec, _metrics_dec, _placeholderPosition_dec, _activeBreakpoint_dec, _layouts_dec, _showGridLines_dec, _rtl_dec, _cellHeightUnit_dec, _enableAnimation_dec, _editable_dec, _columns_dec2, _margin_dec, _cellHeight_dec, _widgets_dec2, _a75, _DeesDashboardgrid_decorators, _init78, _widgets2, _cellHeight, _margin, _columns2, _editable, _enableAnimation, _cellHeightUnit, _rtl, _showGridLines, _layouts, _activeBreakpoint, _placeholderPosition, _metrics, _resolvedMargins, _previewWidgets;
154766
+ var _previewWidgets_dec, _resolvedMargins_dec, _metrics_dec2, _placeholderPosition_dec, _activeBreakpoint_dec, _layouts_dec, _showGridLines_dec, _rtl_dec, _cellHeightUnit_dec, _enableAnimation_dec, _editable_dec, _columns_dec2, _margin_dec, _cellHeight_dec, _widgets_dec2, _a75, _DeesDashboardgrid_decorators, _init78, _widgets2, _cellHeight, _margin, _columns2, _editable, _enableAnimation, _cellHeightUnit, _rtl, _showGridLines, _layouts, _activeBreakpoint, _placeholderPosition, _metrics2, _resolvedMargins, _previewWidgets;
154164
154767
  _DeesDashboardgrid_decorators = [t4("dees-dashboardgrid")];
154165
- var DeesDashboardgrid = class extends (_a75 = DeesElement, _widgets_dec2 = [n5({ type: Array })], _cellHeight_dec = [n5({ type: Number })], _margin_dec = [n5({ type: Object })], _columns_dec2 = [n5({ type: Number })], _editable_dec = [n5({ type: Boolean })], _enableAnimation_dec = [n5({ type: Boolean, reflect: true })], _cellHeightUnit_dec = [n5({ type: String })], _rtl_dec = [n5({ type: Boolean })], _showGridLines_dec = [n5({ type: Boolean })], _layouts_dec = [n5({ attribute: false })], _activeBreakpoint_dec = [n5({ type: String })], _placeholderPosition_dec = [r5()], _metrics_dec = [r5()], _resolvedMargins_dec = [r5()], _previewWidgets_dec = [r5()], _a75) {
154768
+ var DeesDashboardgrid = class extends (_a75 = DeesElement, _widgets_dec2 = [n5({ type: Array })], _cellHeight_dec = [n5({ type: Number })], _margin_dec = [n5({ type: Object })], _columns_dec2 = [n5({ type: Number })], _editable_dec = [n5({ type: Boolean })], _enableAnimation_dec = [n5({ type: Boolean, reflect: true })], _cellHeightUnit_dec = [n5({ type: String })], _rtl_dec = [n5({ type: Boolean })], _showGridLines_dec = [n5({ type: Boolean })], _layouts_dec = [n5({ attribute: false })], _activeBreakpoint_dec = [n5({ type: String })], _placeholderPosition_dec = [r5()], _metrics_dec2 = [r5()], _resolvedMargins_dec = [r5()], _previewWidgets_dec = [r5()], _a75) {
154166
154769
  constructor() {
154167
154770
  super(...arguments);
154168
154771
  __privateAdd(this, _widgets2, __runInitializers(_init78, 8, this, [])), __runInitializers(_init78, 11, this);
@@ -154177,7 +154780,7 @@ var DeesDashboardgrid = class extends (_a75 = DeesElement, _widgets_dec2 = [n5({
154177
154780
  __privateAdd(this, _layouts, __runInitializers(_init78, 44, this)), __runInitializers(_init78, 47, this);
154178
154781
  __privateAdd(this, _activeBreakpoint, __runInitializers(_init78, 48, this, "base")), __runInitializers(_init78, 51, this);
154179
154782
  __privateAdd(this, _placeholderPosition, __runInitializers(_init78, 52, this, null)), __runInitializers(_init78, 55, this);
154180
- __privateAdd(this, _metrics, __runInitializers(_init78, 56, this, null)), __runInitializers(_init78, 59, this);
154783
+ __privateAdd(this, _metrics2, __runInitializers(_init78, 56, this, null)), __runInitializers(_init78, 59, this);
154181
154784
  __privateAdd(this, _resolvedMargins, __runInitializers(_init78, 60, this, null)), __runInitializers(_init78, 63, this);
154182
154785
  __privateAdd(this, _previewWidgets, __runInitializers(_init78, 64, this, null)), __runInitializers(_init78, 67, this);
154183
154786
  __publicField(this, "containerBounds", null);
@@ -154754,7 +155357,7 @@ _showGridLines = new WeakMap();
154754
155357
  _layouts = new WeakMap();
154755
155358
  _activeBreakpoint = new WeakMap();
154756
155359
  _placeholderPosition = new WeakMap();
154757
- _metrics = new WeakMap();
155360
+ _metrics2 = new WeakMap();
154758
155361
  _resolvedMargins = new WeakMap();
154759
155362
  _previewWidgets = new WeakMap();
154760
155363
  __decorateElement(_init78, 4, "widgets", _widgets_dec2, DeesDashboardgrid, _widgets2);
@@ -154769,7 +155372,7 @@ __decorateElement(_init78, 4, "showGridLines", _showGridLines_dec, DeesDashboard
154769
155372
  __decorateElement(_init78, 4, "layouts", _layouts_dec, DeesDashboardgrid, _layouts);
154770
155373
  __decorateElement(_init78, 4, "activeBreakpoint", _activeBreakpoint_dec, DeesDashboardgrid, _activeBreakpoint);
154771
155374
  __decorateElement(_init78, 4, "placeholderPosition", _placeholderPosition_dec, DeesDashboardgrid, _placeholderPosition);
154772
- __decorateElement(_init78, 4, "metrics", _metrics_dec, DeesDashboardgrid, _metrics);
155375
+ __decorateElement(_init78, 4, "metrics", _metrics_dec2, DeesDashboardgrid, _metrics2);
154773
155376
  __decorateElement(_init78, 4, "resolvedMargins", _resolvedMargins_dec, DeesDashboardgrid, _resolvedMargins);
154774
155377
  __decorateElement(_init78, 4, "previewWidgets", _previewWidgets_dec, DeesDashboardgrid, _previewWidgets);
154775
155378
  DeesDashboardgrid = __decorateElement(_init78, 0, "DeesDashboardgrid", _DeesDashboardgrid_decorators, DeesDashboardgrid);
@@ -157504,7 +158107,7 @@ init_group_runtime();
157504
158107
  // ts_web/00_commitinfo_data.ts
157505
158108
  var commitinfo = {
157506
158109
  name: "@design.estate/dees-catalog",
157507
- version: "3.35.1",
158110
+ version: "3.36.0",
157508
158111
  description: "A comprehensive library that provides dynamic web components for building sophisticated and modern web applications using JavaScript and TypeScript."
157509
158112
  };
157510
158113
  export {
@@ -159407,4 +160010,4 @@ ibantools/jsnext/ibantools.js:
159407
160010
  * @preferred
159408
160011
  *)
159409
160012
  */
159410
- //# sourceMappingURL=bundle-1768256969916.js.map
160013
+ //# sourceMappingURL=bundle-1768261315087.js.map