1/* 2 * Copyright (C) 2022 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16import {DbPool} from "./database/SqlLite"; 17import {log} from "../log/Log"; 18 19export const applicationHtml: string = ` 20 <style> 21 :host{ 22 23 } 24 .dark{ 25 --dark-background: #272C34; 26 --dark-background1: #424851; 27 --dark-background2: #262f3c; 28 --dark-background3: #292D33; 29 --dark-background4: #323841; 30 --dark-background5: #333840; 31 --dark-background6: rgba(82,145,255,0.2); 32 --dark-background7: #494d52; 33 --dark-background8: #5291FF; 34 --dark-color: rgba(255,255,255,0.6); 35 --dark-color1: rgba(255,255,255,0.86); 36 --dark-color2: rgba(255,255,255,0.9); 37 --dark-border: #474F59; 38 --dark-color3:#4694C2; 39 --dark-color4:#5AADA0; 40 --dark-border1: #454E5A; 41 --bark-expansion:#0076FF; 42 --bark-prompt:#9e9e9e; 43 --dark-icon:#adafb3; 44 --dark-img: url('img/dark_pic.png'); 45 background: #272C34; 46 color: #FFFFFF; 47 } 48 .root{ 49 display: grid; 50 grid-template-rows: min-content 1fr; 51 grid-template-columns: min-content 1fr; 52 grid-template-areas: 'm s' 53 'm b'; 54 height: 100vh; 55 width: 100vw; 56 } 57 .filedrag::after { 58 content: 'Drop the trace file to open it'; 59 position: fixed; 60 z-index: 2001; 61 top: 0; 62 left: 0; 63 right: 0; 64 bottom: 0; 65 border: 5px dashed var(--dark-color1,#404854); 66 text-align: center; 67 font-size: 3rem; 68 line-height: 100vh; 69 background: rgba(255, 255, 255, 0.5); 70 } 71 .menu{ 72 grid-area: m; 73 /*transition: all 0.2s;*/ 74 box-shadow: 4px 0px 20px rgba(0,0,0,0.05); 75 z-index: 2000; 76 } 77 .search-vessel{ 78 z-index: 10; 79 position: relative; 80 cursor: default; 81 } 82 .progress{ 83 bottom: 0; 84 position: absolute; 85 height: 1px; 86 left: 0; 87 right: 0; 88 } 89 :host(:not([search])) .search-vessel { 90 display: none; 91 } 92 :host(:not([search])) .search-vessel .search { 93 background-color: var(--dark-background5,#F6F6F6); 94 } 95 .search{ 96 grid-area: s; 97 background-color: var(--dark-background,#FFFFFF); 98 height: 48px; 99 display: flex; 100 justify-content: center; 101 align-items: center; 102 103 } 104 .search .search-bg{ 105 background-color: var(--dark-background5,#fff); 106 border-radius: 40px; 107 padding: 3px 20px; 108 display: flex; 109 justify-content: center; 110 align-items: center; 111 border: 1px solid var(--dark-border,#c5c5c5); 112 } 113 lit-search input{ 114 outline: none; 115 border: 0px; 116 background-color: transparent; 117 font-size: inherit; 118 color: var(--dark-color,#666666); 119 width: 30vw; 120 height: auto; 121 vertical-align:middle; 122 line-height:inherit; 123 height:inherit; 124 padding: 6px 6px 6px 6px}; 125 max-height: inherit; 126 box-sizing: border-box; 127 128 } 129 ::placeholder { /* CSS 3 標準 */ 130 color: #b5b7ba; 131 font-size: 1em; 132 } 133 lit-search input::placeholder { 134 color: #b5b7ba; 135 font-size: 1em; 136 } 137 .content{ 138 grid-area: b; 139 background-color: #ffffff; 140 height: 100%; 141 overflow: auto; 142 position:relative; 143 } 144 .sheet{ 145 146 } 147 .sidebar-button{ 148 position: absolute; 149 top: 0; 150 left: 0; 151 background-color: var(--dark-background1,#FFFFFF); 152 height: 100%; 153 border-radius: 0 5px 5px 0; 154 width: 48px; 155 display: flex; 156 align-content: center; 157 justify-content: center; 158 cursor: pointer; 159 } 160 :host{ 161 font-size: inherit; 162 display: inline-block; 163 transition: .3s; 164 } 165 :host([spin]){ 166 animation: rotate 1.75s linear infinite; 167 } 168 @keyframes rotate { 169 to{ 170 transform: rotate(360deg); 171 } 172 } 173 .icon{ 174 display: block; 175 width: 1em; 176 height: 1em; 177 margin: auto; 178 fill: currentColor; 179 overflow: hidden; 180 font-size: 20px; 181 color: var(--dark-color1,#47A7E0); 182 } 183 .chart-filter { 184 visibility: hidden; 185 z-index: -1; 186 } 187 :host([chart_filter]) .chart-filter { 188 display: grid; 189 grid-template-rows: min-content min-content min-content max-content auto; 190 overflow-y: clip; 191 height: 99%; 192 visibility: visible; 193 position: absolute; 194 width: 40%; 195 right: 0; 196 z-index: 1001; 197 top: 0; 198 } 199 :host([custom-color]) .custom-color { 200 display: grid; 201 grid-template-rows: min-content min-content min-content max-content auto; 202 overflow-y: auto; 203 height: 100%; 204 visibility: visible; 205 position: absolute; 206 width: 50%; 207 right: 0; 208 z-index: 1002; 209 top: 0; 210 } 211 .filter-config { 212 opacity: 1; 213 visibility: hidden; 214 } 215 .filter-config:hover { 216 opacity: 0.7; 217 } 218 .page-button[prohibit] { 219 cursor: none; 220 } 221 .page-button { 222 background: #D8D8D8; 223 border-radius: 12px; 224 width: 24px; 225 height: 24px; 226 margin-right: 12px; 227 display: flex; 228 justify-content: center; 229 align-items: center; 230 } 231 #preview-button:hover { 232 cursor: pointer; 233 background: #0A59F7; 234 color: #FFFFFF; 235 opacity: 1; 236 } 237 #next-button:hover { 238 cursor: pointer; 239 background: #0A59F7; 240 color: #FFFFFF; 241 opacity: 1; 242 } 243 .pagination:hover { 244 cursor: pointer; 245 background: #0A59F7; 246 color: #FFFFFF; 247 opacity: 1; 248 } 249 .confirm-button:hover { 250 cursor: pointer; 251 background: #0A59F7; 252 color: #FFFFFF; 253 opacity: 1; 254 } 255 .pagination { 256 background: #D8D8D8; 257 color: #000000; 258 border-radius: 12px; 259 width: 24px; 260 height: 24px; 261 margin-right: 12px; 262 display: flex; 263 justify-content: center; 264 align-items: center; 265 font-family: Helvetica; 266 font-size: 12px; 267 text-align: center; 268 line-height: 20px; 269 font-weight: 400; 270 opacity: 0.6; 271 } 272 .pagination[selected] { 273 background: #0A59F7; 274 color: #FFFFFF; 275 opacity: 1; 276 } 277 .page-jump-font { 278 opacity: 0.6; 279 font-family: Helvetica; 280 font-size: 12px; 281 color: #000000; 282 text-align: center; 283 line-height: 20px; 284 font-weight: 400; 285 } 286 .page-input { 287 background: #D8D8D8; 288 border-radius: 10px; 289 width: 40px; 290 height: 24px; 291 justify-content: center; 292 align-items: center; 293 text-align: center; 294 margin-right: 8px; 295 border: none; 296 } 297 .confirm-button { 298 font-family: Helvetica; 299 font-size: 12px; 300 color: #0A59F7; 301 text-align: center; 302 font-weight: 400; 303 border: 1px solid #0A59F7; 304 border-radius: 10px; 305 width: 64px; 306 height: 24px; 307 line-height: 24px; 308 } 309 .long_trace_page { 310 justify-content: flex-end; 311 width: -webkit-fill-available; 312 margin-right: 80px; 313 align-items: center; 314 display: none; 315 } 316 .page-number-list { 317 display: flex; 318 } 319 </style> 320 <div class="root" style="position: relative;"> 321 <lit-main-menu id="main-menu" class="menu" data=''></lit-main-menu> 322 <sp-keyboard style="width:100%;height:100%;overflow:auto;visibility:hidden;top:0px;left:0px;right:0;bottom:0px;position:absolute;z-index: 8888" id="sp-keyboard"> 323 </sp-keyboard> 324 <div class="search-vessel"> 325 <div class="search" style="position: relative;"> 326 <div class="sidebar-button" style="width: 0"> 327 <svg class="icon" id="icon" aria-hidden="true" viewBox="0 0 1024 1024"> 328 <use id="use" xlink:href="./base-ui/icon.svg#icon-menu"></use> 329 </svg> 330 </div> 331 <div title="Import Key Path" id="import-key-path" style="display: none ;text-align: left; 332 position: absolute;left: 5px ; cursor: pointer;top: 15px"> 333 <input id="import-config" style="display: none;pointer-events: none" type="file" accept=".json" > 334 <label style="width: 20px;height: 20px;cursor: pointer;" for="import-config"> 335 <lit-icon id="import-btn" name="copy-csv" style="pointer-events: none" size="20"> 336 </lit-icon> 337 </label> 338 </div> 339 <lit-icon id="close-key-path" name="close" title="Close Key Path" color='#fff' size="20" style="display: none;text-align: left; position: absolute;left: 25px; cursor: pointer;top: 15px "> 340 </lit-icon> 341 <lit-search id="lit-search"></lit-search> 342 <lit-search id="lit-record-search"></lit-search> 343 <div class="long_trace_page" style="display: none;"> 344 <div class="page-button" id="preview-button"> 345 <img title="preview" src="img/preview.png"/> 346 </div> 347 <div class="page-number-list"></div> 348 <div class="page-button" id="next-button" style="margin-right: 8px;"> 349 <img title="next" src="img/next.png"/> 350 </div> 351 <div class="page-jump-font" style="margin-right: 8px;">To</div> 352 <input class="page-input" /> 353 <div class="confirm-button">Confirm</div> 354 </div> 355 </div> 356 <img class="cut-trace-file" title="Cut Trace File" src="img/menu-cut.svg" style="display: block;text-align: right;position: absolute;right: 3.2em;cursor: pointer;top: 20px"> 357 <img class="filter-config" title="Display Template" src="img/config_filter.png" style="display: block;text-align: right;position: absolute;right: 1.2em;cursor: pointer;top: 20px"> 358 <lit-progress-bar class="progress"></lit-progress-bar> 359 </div> 360 <div id="app-content" class="content"> 361 <sp-welcome style="visibility:visible;top:0px;left:0px;position:absolute;z-index: 100" id="sp-welcome"> 362 </sp-welcome> 363 <sp-system-trace style="visibility:visible;" id="sp-system-trace"> 364 </sp-system-trace> 365 <sp-record-trace style="width:100%;height:100%;overflow:auto;visibility:hidden;top:0px;left:0px;right:0;bottom:0px;position:absolute;z-index: 102" id="sp-record-trace"> 366 </sp-record-trace> 367 <sp-record-trace record_template='' style="width:100%;height:100%;overflow:auto;visibility:hidden;top:0px;left:0px;right:0;bottom:0px;position:absolute;z-index: 102" id="sp-record-template"> 368 </sp-record-trace> 369 <sp-scheduling-analysis style="width:100%;height:100%;overflow:auto;visibility:hidden;top:0;left:0;right:0;bottom:0;position:absolute;" id="sp-scheduling-analysis"></sp-scheduling-analysis> 370 <sp-metrics style="width:100%;height:100%;overflow:auto;visibility:hidden;top:0;left:0;right:0;bottom:0;position:absolute;z-index: 97" id="sp-metrics"> 371 </sp-metrics> 372 <sp-query-sql style="width:100%;height:100%;overflow:auto;visibility:hidden;top:0;left:0;right:0;bottom:0;position:absolute;z-index: 98" id="sp-query-sql"> 373 </sp-query-sql> 374 <sp-info-and-stats style="width:100%;height:100%;overflow:auto;visibility:hidden;top:0;left:0;right:0;bottom:0;position:absolute;z-index: 99" id="sp-info-and-stats"> 375 </sp-info-and-stats> 376 <sp-convert-trace style="width:100%;height:100%;overflow:auto;visibility:hidden;top:0;left:0;right:0;bottom:0;position:absolute;z-index: 99" id="sp-convert-trace"> 377 </sp-convert-trace> 378 <sp-help style="width:100%;height:100%;overflow:auto;visibility:hidden;top:0px;left:0px;right:0;bottom:0px;position:absolute;z-index: 103" id="sp-help"> 379 </sp-help> 380 <sp-flags style="width:100%;height:100%;overflow:auto;visibility:hidden;top:0px;left:0px;right:0;bottom:0px;position:absolute;z-index: 104" id="sp-flags"> 381 </sp-flags> 382 <trace-row-config class="chart-filter" style="height:100%;top:0px;right:0;bottom:0px;position:absolute;z-index: 1001"></trace-row-config> 383 <custom-theme-color class="custom-color" style="height:100%;top:0px;right:0;bottom:0px;position:absolute;z-index: 1001"></custom-theme-color> 384 </div> 385 </div> 386 `; 387 388export function readTraceFileBuffer(): Promise<ArrayBuffer | undefined> { 389 return new Promise((resolve) => { 390 caches.match(DbPool.fileCacheKey).then((res) => { 391 if (res) { 392 res.arrayBuffer().then((buffer) => { 393 resolve(buffer); 394 }); 395 } else { 396 resolve(undefined); 397 } 398 }); 399 }); 400} 401 402export function clearTraceFileCache(): void { 403 caches.keys().then((keys) => { 404 keys.forEach((key) => { 405 if (key === DbPool.fileCacheKey) { 406 caches.delete(key).then(); 407 } else if (key.includes('/') && key.includes('-')) { 408 let splits = key.split('/'); 409 let keyStr = splits[splits.length - 1]; 410 let time = keyStr.split('-')[0]; 411 let fileDate = new Date(parseInt(time)); 412 if (fileDate.toLocaleDateString() !== new Date().toLocaleDateString()) { 413 //如果不是当天的缓存则删去缓存文件 414 caches.delete(key).then(); 415 } 416 } else { 417 caches.delete(key).then(); 418 } 419 }); 420 }); 421} 422 423export function postLog(filename: string, fileSize: string) { 424 log('postLog filename is: ' + filename + ' fileSize: ' + fileSize); 425 fetch(`https://${window.location.host.split(':')[0]}:${window.location.port}/logger`, { 426 method: 'POST', 427 headers: { 428 'Content-Type': 'application/json', 429 }, 430 body: JSON.stringify({ 431 fileName: filename, 432 fileSize: fileSize, 433 }), 434 }) 435 .then((response) => response.json()) 436 .then((data) => { 437 }) 438 .catch((error) => { 439 }); 440} 441 442export function indexedDataToBufferData(sourceData: any): ArrayBuffer { 443 let uintArrayLength = 0; 444 let uintDataList = sourceData.map((item: any) => { 445 let currentBufData = new Uint8Array(item.buf); 446 uintArrayLength += currentBufData.length; 447 return currentBufData; 448 }); 449 let resultArrayBuffer = new ArrayBuffer(uintArrayLength); 450 let resultUintArray = new Uint8Array(resultArrayBuffer); 451 let offset = 0; 452 uintDataList.forEach((currentArray: Uint8Array) => { 453 resultUintArray.set(currentArray, offset); 454 offset += currentArray.length; 455 }); 456 return resultArrayBuffer; 457} 458 459export function findFreeSizeAlgorithm(numbers: Array<number>, freeSize: number): Array<number> { 460 let closestSize = 0; 461 let currentSize = 0; 462 let finalIndex: Array<number> = []; 463 let currentSelectIndex: Array<number> = []; 464 465 function reBackFind(index: number): void { 466 if (index === numbers.length) { 467 const sumDifference = Math.abs(currentSize - freeSize); 468 if (currentSize <= freeSize && sumDifference < Math.abs(closestSize - freeSize)) { 469 closestSize = currentSize; 470 finalIndex = [...currentSelectIndex]; 471 } 472 return; 473 } 474 currentSize += numbers[index]; 475 currentSelectIndex.push(index); 476 reBackFind(index + 1); 477 currentSize -= numbers[index]; 478 currentSelectIndex.pop(); 479 reBackFind(index + 1); 480 } 481 482 reBackFind(0); 483 return finalIndex; 484} 485 486export function getCurrentDataTime(): string[]{ 487 let current = new Date(); 488 let year = '' + current.getFullYear(); 489 let month = ('0' + (current.getMonth() + 1)).slice(-2); 490 let day = ('0' + current.getDate()).slice(-2); 491 let hours = ('0' + current.getHours()).slice(-2); 492 let minutes = ('0' + current.getMinutes()).slice(-2); 493 let seconds = ('0' + current.getSeconds()).slice(-2); 494 return [year, month, day, hours, minutes, seconds]; 495} 496