From 8c7e5947cd36dd79e2d16c571dbda88bde9246ad Mon Sep 17 00:00:00 2001 From: weidingjian Date: Thu, 25 Jun 2026 22:55:11 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=96=B0=E5=A2=9Etrace=E5=8A=9F?= =?UTF-8?q?=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .DS_Store | Bin 0 -> 6148 bytes coverage/base.css | 224 +++ coverage/block-navigation.js | 87 + coverage/coverage-final.json | 27 + coverage/favicon.png | Bin 0 -> 445 bytes coverage/index.html | 161 ++ coverage/prettify.css | 1 + coverage/prettify.js | 2 + coverage/sort-arrow-sprite.png | Bin 0 -> 138 bytes coverage/sorter.js | 210 +++ coverage/src/core/Client.ts.html | 1177 ++++++++++++ coverage/src/core/ConfigManager.ts.html | 817 ++++++++ coverage/src/core/EventBus.ts.html | 226 +++ coverage/src/core/EventQueue.ts.html | 1036 ++++++++++ coverage/src/core/PluginManager.ts.html | 346 ++++ coverage/src/core/Reporter.ts.html | 1132 +++++++++++ coverage/src/core/TracingManager.ts.html | 679 +++++++ coverage/src/core/index.html | 206 ++ coverage/src/index.html | 116 ++ coverage/src/index.ts.html | 841 +++++++++ coverage/src/plugins/BehaviorPlugin.ts.html | 1090 +++++++++++ coverage/src/plugins/ErrorPlugin.ts.html | 982 ++++++++++ .../src/plugins/InteractionPlugin.ts.html | 706 +++++++ coverage/src/plugins/NetworkPlugin.ts.html | 1237 ++++++++++++ coverage/src/plugins/OfflinePlugin.ts.html | 997 ++++++++++ .../src/plugins/PerformancePlugin.ts.html | 1675 +++++++++++++++++ coverage/src/plugins/RouterPlugin.ts.html | 628 ++++++ coverage/src/plugins/SamplingPlugin.ts.html | 367 ++++ coverage/src/plugins/index.html | 221 +++ coverage/src/utils/baggage.ts.html | 382 ++++ coverage/src/utils/dsn.ts.html | 172 ++ coverage/src/utils/env.ts.html | 964 ++++++++++ coverage/src/utils/field-encoder.ts.html | 349 ++++ coverage/src/utils/hash.ts.html | 145 ++ coverage/src/utils/helper.ts.html | 241 +++ coverage/src/utils/identity.ts.html | 295 +++ coverage/src/utils/index.html | 251 +++ coverage/src/utils/logger.ts.html | 178 ++ coverage/src/utils/stacktrace.ts.html | 385 ++++ coverage/src/utils/tracing.ts.html | 1153 ++++++++++++ dist/core/Client.d.ts | 10 +- dist/core/ConfigManager.d.ts | 1 + dist/core/TracingManager.d.ts | 22 + dist/index.cjs.js | 6 +- dist/index.d.ts | 30 +- dist/index.esm.js | 6 +- dist/index.iife.js | 6 +- dist/plugins/InteractionPlugin.d.ts | 24 + dist/plugins/NetworkPlugin.d.ts | 5 + dist/plugins/PerformancePlugin.d.ts | 12 +- dist/plugins/RouterPlugin.d.ts | 26 + dist/types/index.d.ts | 122 +- dist/utils/baggage.d.ts | 14 + dist/utils/identity.d.ts | 21 + dist/utils/tracing.d.ts | 148 ++ docs/07-tracing.md | 348 ++++ package-lock.json | 461 ++++- package.json | 1 + src/core/Client.ts | 72 +- src/core/ConfigManager.ts | 19 + src/core/EventQueue.ts | 4 +- src/core/Reporter.ts | 2 - src/core/TracingManager.ts | 198 ++ src/index.ts | 81 +- src/plugins/ErrorPlugin.ts | 7 +- src/plugins/InteractionPlugin.ts | 207 ++ src/plugins/NetworkPlugin.ts | 134 +- src/plugins/PerformancePlugin.ts | 216 ++- src/plugins/RouterPlugin.ts | 181 ++ src/types/index.ts | 157 +- src/utils/baggage.ts | 99 + src/utils/env.ts | 5 + src/utils/identity.ts | 70 + src/utils/tracing.ts | 356 ++++ tests/ConfigManager.test.ts | 252 +++ tests/EventBus.test.ts | 189 ++ tests/EventQueue.test.ts | 383 ++++ tests/PluginManager.test.ts | 472 +++++ tests/SamplingPlugin.test.ts | 272 +++ tests/TracingManager.test.ts | 350 ++++ tests/baggage.test.ts | 250 +++ tests/env.test.ts | 238 ++- tests/field-encoder.test.ts | 239 +++ tests/helper.test.ts | 178 ++ tests/identity.test.ts | 168 ++ tests/index.test.ts | 199 ++ tests/logger.test.ts | 192 ++ tests/stacktrace.test.ts | 360 ++++ tests/tracing.test.ts | 458 +++++ 89 files changed, 26880 insertions(+), 97 deletions(-) create mode 100644 .DS_Store create mode 100644 coverage/base.css create mode 100644 coverage/block-navigation.js create mode 100644 coverage/coverage-final.json create mode 100644 coverage/favicon.png create mode 100644 coverage/index.html create mode 100644 coverage/prettify.css create mode 100644 coverage/prettify.js create mode 100644 coverage/sort-arrow-sprite.png create mode 100644 coverage/sorter.js create mode 100644 coverage/src/core/Client.ts.html create mode 100644 coverage/src/core/ConfigManager.ts.html create mode 100644 coverage/src/core/EventBus.ts.html create mode 100644 coverage/src/core/EventQueue.ts.html create mode 100644 coverage/src/core/PluginManager.ts.html create mode 100644 coverage/src/core/Reporter.ts.html create mode 100644 coverage/src/core/TracingManager.ts.html create mode 100644 coverage/src/core/index.html create mode 100644 coverage/src/index.html create mode 100644 coverage/src/index.ts.html create mode 100644 coverage/src/plugins/BehaviorPlugin.ts.html create mode 100644 coverage/src/plugins/ErrorPlugin.ts.html create mode 100644 coverage/src/plugins/InteractionPlugin.ts.html create mode 100644 coverage/src/plugins/NetworkPlugin.ts.html create mode 100644 coverage/src/plugins/OfflinePlugin.ts.html create mode 100644 coverage/src/plugins/PerformancePlugin.ts.html create mode 100644 coverage/src/plugins/RouterPlugin.ts.html create mode 100644 coverage/src/plugins/SamplingPlugin.ts.html create mode 100644 coverage/src/plugins/index.html create mode 100644 coverage/src/utils/baggage.ts.html create mode 100644 coverage/src/utils/dsn.ts.html create mode 100644 coverage/src/utils/env.ts.html create mode 100644 coverage/src/utils/field-encoder.ts.html create mode 100644 coverage/src/utils/hash.ts.html create mode 100644 coverage/src/utils/helper.ts.html create mode 100644 coverage/src/utils/identity.ts.html create mode 100644 coverage/src/utils/index.html create mode 100644 coverage/src/utils/logger.ts.html create mode 100644 coverage/src/utils/stacktrace.ts.html create mode 100644 coverage/src/utils/tracing.ts.html create mode 100644 dist/core/TracingManager.d.ts create mode 100644 dist/plugins/InteractionPlugin.d.ts create mode 100644 dist/plugins/RouterPlugin.d.ts create mode 100644 dist/utils/baggage.d.ts create mode 100644 dist/utils/identity.d.ts create mode 100644 dist/utils/tracing.d.ts create mode 100644 docs/07-tracing.md create mode 100644 src/core/TracingManager.ts create mode 100644 src/plugins/InteractionPlugin.ts create mode 100644 src/plugins/RouterPlugin.ts create mode 100644 src/utils/baggage.ts create mode 100644 src/utils/identity.ts create mode 100644 src/utils/tracing.ts create mode 100644 tests/EventBus.test.ts create mode 100644 tests/EventQueue.test.ts create mode 100644 tests/PluginManager.test.ts create mode 100644 tests/SamplingPlugin.test.ts create mode 100644 tests/TracingManager.test.ts create mode 100644 tests/baggage.test.ts create mode 100644 tests/field-encoder.test.ts create mode 100644 tests/helper.test.ts create mode 100644 tests/identity.test.ts create mode 100644 tests/index.test.ts create mode 100644 tests/logger.test.ts create mode 100644 tests/stacktrace.test.ts create mode 100644 tests/tracing.test.ts diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..1f9315fc80a50599cca306c1f418e55b3963314d GIT binary patch literal 6148 zcmeHK%}T>S5Z-O0-BN@c6nYGJEm*A;#Y>3w1&ruHr6#6mFlI}WnnNk%tS{t~_&m<+ zZp31}ir5+0{pNQ!`$6`HF~+@Vw9A;y7!%MCIVwv8-Ah9?lZ?o5jIhYYVIo7Y-%RYU z1Ae>3A|}}#%f5bpI8Nd$?{?pLt!}NYH$+3U#Et(T3qKF?Y32o!E40p~Ou|YJ!i#uR z4DHPmndU*9jwY%gjz*AjeHo{bEIc_)qfFKMIv|>&IkeleS%0tFaeDp3dB>R@p}yZc zn9rMHYkTMTZ1|WwrSe4+%7Jes8wM+Q1?6)+&;BG$WO@(2D!XrACN=a9s+hOSySs za9s|5$K<&NOO3jmaWylHV`i=%FI>$Ien+J2a) literal 0 HcmV?d00001 diff --git a/coverage/base.css b/coverage/base.css new file mode 100644 index 0000000..f418035 --- /dev/null +++ b/coverage/base.css @@ -0,0 +1,224 @@ +body, html { + margin:0; padding: 0; + height: 100%; +} +body { + font-family: Helvetica Neue, Helvetica, Arial; + font-size: 14px; + color:#333; +} +.small { font-size: 12px; } +*, *:after, *:before { + -webkit-box-sizing:border-box; + -moz-box-sizing:border-box; + box-sizing:border-box; + } +h1 { font-size: 20px; margin: 0;} +h2 { font-size: 14px; } +pre { + font: 12px/1.4 Consolas, "Liberation Mono", Menlo, Courier, monospace; + margin: 0; + padding: 0; + -moz-tab-size: 2; + -o-tab-size: 2; + tab-size: 2; +} +a { color:#0074D9; text-decoration:none; } +a:hover { text-decoration:underline; } +.strong { font-weight: bold; } +.space-top1 { padding: 10px 0 0 0; } +.pad2y { padding: 20px 0; } +.pad1y { padding: 10px 0; } +.pad2x { padding: 0 20px; } +.pad2 { padding: 20px; } +.pad1 { padding: 10px; } +.space-left2 { padding-left:55px; } +.space-right2 { padding-right:20px; } +.center { text-align:center; } +.clearfix { display:block; } +.clearfix:after { + content:''; + display:block; + height:0; + clear:both; + visibility:hidden; + } +.fl { float: left; } +@media only screen and (max-width:640px) { + .col3 { width:100%; max-width:100%; } + .hide-mobile { display:none!important; } +} + +.quiet { + color: #7f7f7f; + color: rgba(0,0,0,0.5); +} +.quiet a { opacity: 0.7; } + +.fraction { + font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; + font-size: 10px; + color: #555; + background: #E8E8E8; + padding: 4px 5px; + border-radius: 3px; + vertical-align: middle; +} + +div.path a:link, div.path a:visited { color: #333; } +table.coverage { + border-collapse: collapse; + margin: 10px 0 0 0; + padding: 0; +} + +table.coverage td { + margin: 0; + padding: 0; + vertical-align: top; +} +table.coverage td.line-count { + text-align: right; + padding: 0 5px 0 20px; +} +table.coverage td.line-coverage { + text-align: right; + padding-right: 10px; + min-width:20px; +} + +table.coverage td span.cline-any { + display: inline-block; + padding: 0 5px; + width: 100%; +} +.missing-if-branch { + display: inline-block; + margin-right: 5px; + border-radius: 3px; + position: relative; + padding: 0 4px; + background: #333; + color: yellow; +} + +.skip-if-branch { + display: none; + margin-right: 10px; + position: relative; + padding: 0 4px; + background: #ccc; + color: white; +} +.missing-if-branch .typ, .skip-if-branch .typ { + color: inherit !important; +} +.coverage-summary { + border-collapse: collapse; + width: 100%; +} +.coverage-summary tr { border-bottom: 1px solid #bbb; } +.keyline-all { border: 1px solid #ddd; } +.coverage-summary td, .coverage-summary th { padding: 10px; } +.coverage-summary tbody { border: 1px solid #bbb; } +.coverage-summary td { border-right: 1px solid #bbb; } +.coverage-summary td:last-child { border-right: none; } +.coverage-summary th { + text-align: left; + font-weight: normal; + white-space: nowrap; +} +.coverage-summary th.file { border-right: none !important; } +.coverage-summary th.pct { } +.coverage-summary th.pic, +.coverage-summary th.abs, +.coverage-summary td.pct, +.coverage-summary td.abs { text-align: right; } +.coverage-summary td.file { white-space: nowrap; } +.coverage-summary td.pic { min-width: 120px !important; } +.coverage-summary tfoot td { } + +.coverage-summary .sorter { + height: 10px; + width: 7px; + display: inline-block; + margin-left: 0.5em; + background: url(sort-arrow-sprite.png) no-repeat scroll 0 0 transparent; +} +.coverage-summary .sorted .sorter { + background-position: 0 -20px; +} +.coverage-summary .sorted-desc .sorter { + background-position: 0 -10px; +} +.status-line { height: 10px; } +/* yellow */ +.cbranch-no { background: yellow !important; color: #111; } +/* dark red */ +.red.solid, .status-line.low, .low .cover-fill { background:#C21F39 } +.low .chart { border:1px solid #C21F39 } +.highlighted, +.highlighted .cstat-no, .highlighted .fstat-no, .highlighted .cbranch-no{ + background: #C21F39 !important; +} +/* medium red */ +.cstat-no, .fstat-no, .cbranch-no, .cbranch-no { background:#F6C6CE } +/* light red */ +.low, .cline-no { background:#FCE1E5 } +/* light green */ +.high, .cline-yes { background:rgb(230,245,208) } +/* medium green */ +.cstat-yes { background:rgb(161,215,106) } +/* dark green */ +.status-line.high, .high .cover-fill { background:rgb(77,146,33) } +.high .chart { border:1px solid rgb(77,146,33) } +/* dark yellow (gold) */ +.status-line.medium, .medium .cover-fill { background: #f9cd0b; } +.medium .chart { border:1px solid #f9cd0b; } +/* light yellow */ +.medium { background: #fff4c2; } + +.cstat-skip { background: #ddd; color: #111; } +.fstat-skip { background: #ddd; color: #111 !important; } +.cbranch-skip { background: #ddd !important; color: #111; } + +span.cline-neutral { background: #eaeaea; } + +.coverage-summary td.empty { + opacity: .5; + padding-top: 4px; + padding-bottom: 4px; + line-height: 1; + color: #888; +} + +.cover-fill, .cover-empty { + display:inline-block; + height: 12px; +} +.chart { + line-height: 0; +} +.cover-empty { + background: white; +} +.cover-full { + border-right: none !important; +} +pre.prettyprint { + border: none !important; + padding: 0 !important; + margin: 0 !important; +} +.com { color: #999 !important; } +.ignore-none { color: #999; font-weight: normal; } + +.wrapper { + min-height: 100%; + height: auto !important; + height: 100%; + margin: 0 auto -48px; +} +.footer, .push { + height: 48px; +} diff --git a/coverage/block-navigation.js b/coverage/block-navigation.js new file mode 100644 index 0000000..530d1ed --- /dev/null +++ b/coverage/block-navigation.js @@ -0,0 +1,87 @@ +/* eslint-disable */ +var jumpToCode = (function init() { + // Classes of code we would like to highlight in the file view + var missingCoverageClasses = ['.cbranch-no', '.cstat-no', '.fstat-no']; + + // Elements to highlight in the file listing view + var fileListingElements = ['td.pct.low']; + + // We don't want to select elements that are direct descendants of another match + var notSelector = ':not(' + missingCoverageClasses.join('):not(') + ') > '; // becomes `:not(a):not(b) > ` + + // Selector that finds elements on the page to which we can jump + var selector = + fileListingElements.join(', ') + + ', ' + + notSelector + + missingCoverageClasses.join(', ' + notSelector); // becomes `:not(a):not(b) > a, :not(a):not(b) > b` + + // The NodeList of matching elements + var missingCoverageElements = document.querySelectorAll(selector); + + var currentIndex; + + function toggleClass(index) { + missingCoverageElements + .item(currentIndex) + .classList.remove('highlighted'); + missingCoverageElements.item(index).classList.add('highlighted'); + } + + function makeCurrent(index) { + toggleClass(index); + currentIndex = index; + missingCoverageElements.item(index).scrollIntoView({ + behavior: 'smooth', + block: 'center', + inline: 'center' + }); + } + + function goToPrevious() { + var nextIndex = 0; + if (typeof currentIndex !== 'number' || currentIndex === 0) { + nextIndex = missingCoverageElements.length - 1; + } else if (missingCoverageElements.length > 1) { + nextIndex = currentIndex - 1; + } + + makeCurrent(nextIndex); + } + + function goToNext() { + var nextIndex = 0; + + if ( + typeof currentIndex === 'number' && + currentIndex < missingCoverageElements.length - 1 + ) { + nextIndex = currentIndex + 1; + } + + makeCurrent(nextIndex); + } + + return function jump(event) { + if ( + document.getElementById('fileSearch') === document.activeElement && + document.activeElement != null + ) { + // if we're currently focused on the search input, we don't want to navigate + return; + } + + switch (event.which) { + case 78: // n + case 74: // j + goToNext(); + break; + case 66: // b + case 75: // k + case 80: // p + goToPrevious(); + break; + } + }; +})(); +window.addEventListener('keydown', jumpToCode); diff --git a/coverage/coverage-final.json b/coverage/coverage-final.json new file mode 100644 index 0000000..e9219bf --- /dev/null +++ b/coverage/coverage-final.json @@ -0,0 +1,27 @@ +{"/Users/weidingjian/Desktop/work/ai/light-sentry-sdk/src/index.ts": {"path":"/Users/weidingjian/Desktop/work/ai/light-sentry-sdk/src/index.ts","all":false,"statementMap":{"0":{"start":{"line":1,"column":0},"end":{"line":1,"column":35}},"1":{"start":{"line":2,"column":0},"end":{"line":2,"column":48}},"2":{"start":{"line":3,"column":0},"end":{"line":3,"column":60}},"3":{"start":{"line":4,"column":0},"end":{"line":4,"column":52}},"4":{"start":{"line":5,"column":0},"end":{"line":5,"column":54}},"5":{"start":{"line":6,"column":0},"end":{"line":6,"column":52}},"6":{"start":{"line":7,"column":0},"end":{"line":7,"column":54}},"7":{"start":{"line":8,"column":0},"end":{"line":8,"column":50}},"8":{"start":{"line":9,"column":0},"end":{"line":9,"column":60}},"9":{"start":{"line":10,"column":0},"end":{"line":10,"column":151}},"10":{"start":{"line":11,"column":0},"end":{"line":11,"column":95}},"11":{"start":{"line":12,"column":0},"end":{"line":12,"column":280}},"12":{"start":{"line":13,"column":0},"end":{"line":13,"column":52}},"13":{"start":{"line":14,"column":0},"end":{"line":14,"column":158}},"14":{"start":{"line":15,"column":0},"end":{"line":15,"column":0}},"15":{"start":{"line":16,"column":0},"end":{"line":16,"column":44}},"16":{"start":{"line":17,"column":0},"end":{"line":17,"column":0}},"17":{"start":{"line":18,"column":0},"end":{"line":18,"column":49}},"18":{"start":{"line":19,"column":0},"end":{"line":19,"column":34}},"19":{"start":{"line":20,"column":0},"end":{"line":20,"column":77}},"20":{"start":{"line":21,"column":0},"end":{"line":21,"column":0}},"21":{"start":{"line":22,"column":0},"end":{"line":22,"column":36}},"22":{"start":{"line":23,"column":0},"end":{"line":23,"column":0}},"23":{"start":{"line":24,"column":0},"end":{"line":24,"column":41}},"24":{"start":{"line":25,"column":0},"end":{"line":25,"column":24}},"25":{"start":{"line":26,"column":0},"end":{"line":26,"column":25}},"26":{"start":{"line":27,"column":0},"end":{"line":27,"column":22}},"27":{"start":{"line":28,"column":0},"end":{"line":28,"column":4}},"28":{"start":{"line":29,"column":0},"end":{"line":29,"column":0}},"29":{"start":{"line":30,"column":0},"end":{"line":30,"column":91}},"30":{"start":{"line":31,"column":0},"end":{"line":31,"column":2}},"31":{"start":{"line":32,"column":0},"end":{"line":32,"column":75}},"32":{"start":{"line":33,"column":0},"end":{"line":33,"column":49}},"33":{"start":{"line":34,"column":0},"end":{"line":34,"column":3}},"34":{"start":{"line":35,"column":0},"end":{"line":35,"column":71}},"35":{"start":{"line":36,"column":0},"end":{"line":36,"column":45}},"36":{"start":{"line":37,"column":0},"end":{"line":37,"column":3}},"37":{"start":{"line":38,"column":0},"end":{"line":38,"column":72}},"38":{"start":{"line":39,"column":0},"end":{"line":39,"column":46}},"39":{"start":{"line":40,"column":0},"end":{"line":40,"column":3}},"40":{"start":{"line":41,"column":0},"end":{"line":41,"column":70}},"41":{"start":{"line":42,"column":0},"end":{"line":42,"column":44}},"42":{"start":{"line":43,"column":0},"end":{"line":43,"column":3}},"43":{"start":{"line":44,"column":0},"end":{"line":44,"column":75}},"44":{"start":{"line":45,"column":0},"end":{"line":45,"column":49}},"45":{"start":{"line":46,"column":0},"end":{"line":46,"column":3}},"46":{"start":{"line":47,"column":0},"end":{"line":47,"column":0}},"47":{"start":{"line":48,"column":0},"end":{"line":48,"column":119}},"48":{"start":{"line":49,"column":0},"end":{"line":49,"column":0}},"49":{"start":{"line":50,"column":0},"end":{"line":50,"column":40}},"50":{"start":{"line":51,"column":0},"end":{"line":51,"column":23}},"51":{"start":{"line":52,"column":0},"end":{"line":52,"column":3}},"52":{"start":{"line":53,"column":0},"end":{"line":53,"column":0}},"53":{"start":{"line":54,"column":0},"end":{"line":54,"column":23}},"54":{"start":{"line":55,"column":0},"end":{"line":55,"column":42}},"55":{"start":{"line":56,"column":0},"end":{"line":56,"column":99}},"56":{"start":{"line":57,"column":0},"end":{"line":57,"column":42}},"57":{"start":{"line":58,"column":0},"end":{"line":58,"column":7}},"58":{"start":{"line":59,"column":0},"end":{"line":59,"column":5}},"59":{"start":{"line":60,"column":0},"end":{"line":60,"column":3}},"60":{"start":{"line":61,"column":0},"end":{"line":61,"column":0}},"61":{"start":{"line":62,"column":0},"end":{"line":62,"column":16}},"62":{"start":{"line":63,"column":0},"end":{"line":63,"column":0}},"63":{"start":{"line":64,"column":0},"end":{"line":64,"column":24}},"64":{"start":{"line":65,"column":0},"end":{"line":65,"column":56}},"65":{"start":{"line":66,"column":0},"end":{"line":66,"column":16}},"66":{"start":{"line":67,"column":0},"end":{"line":67,"column":1}},"67":{"start":{"line":68,"column":0},"end":{"line":68,"column":0}},"68":{"start":{"line":69,"column":0},"end":{"line":69,"column":42}},"69":{"start":{"line":70,"column":0},"end":{"line":70,"column":22}},"70":{"start":{"line":71,"column":0},"end":{"line":71,"column":1}},"71":{"start":{"line":72,"column":0},"end":{"line":72,"column":0}},"72":{"start":{"line":73,"column":0},"end":{"line":73,"column":57}},"73":{"start":{"line":74,"column":0},"end":{"line":74,"column":78}},"74":{"start":{"line":75,"column":0},"end":{"line":75,"column":22}},"75":{"start":{"line":76,"column":0},"end":{"line":76,"column":83}},"76":{"start":{"line":77,"column":0},"end":{"line":77,"column":11}},"77":{"start":{"line":78,"column":0},"end":{"line":78,"column":3}},"78":{"start":{"line":79,"column":0},"end":{"line":79,"column":39}},"79":{"start":{"line":80,"column":0},"end":{"line":80,"column":1}},"80":{"start":{"line":81,"column":0},"end":{"line":81,"column":0}},"81":{"start":{"line":82,"column":0},"end":{"line":82,"column":68}},"82":{"start":{"line":83,"column":0},"end":{"line":83,"column":76}},"83":{"start":{"line":84,"column":0},"end":{"line":84,"column":22}},"84":{"start":{"line":85,"column":0},"end":{"line":85,"column":83}},"85":{"start":{"line":86,"column":0},"end":{"line":86,"column":11}},"86":{"start":{"line":87,"column":0},"end":{"line":87,"column":3}},"87":{"start":{"line":88,"column":0},"end":{"line":88,"column":46}},"88":{"start":{"line":89,"column":0},"end":{"line":89,"column":1}},"89":{"start":{"line":90,"column":0},"end":{"line":90,"column":0}},"90":{"start":{"line":91,"column":0},"end":{"line":91,"column":77}},"91":{"start":{"line":92,"column":0},"end":{"line":92,"column":74}},"92":{"start":{"line":93,"column":0},"end":{"line":93,"column":22}},"93":{"start":{"line":94,"column":0},"end":{"line":94,"column":83}},"94":{"start":{"line":95,"column":0},"end":{"line":95,"column":11}},"95":{"start":{"line":96,"column":0},"end":{"line":96,"column":3}},"96":{"start":{"line":97,"column":0},"end":{"line":97,"column":35}},"97":{"start":{"line":98,"column":0},"end":{"line":98,"column":1}},"98":{"start":{"line":99,"column":0},"end":{"line":99,"column":0}},"99":{"start":{"line":100,"column":0},"end":{"line":100,"column":47}},"100":{"start":{"line":101,"column":0},"end":{"line":101,"column":30}},"101":{"start":{"line":102,"column":0},"end":{"line":102,"column":1}},"102":{"start":{"line":103,"column":0},"end":{"line":103,"column":0}},"103":{"start":{"line":104,"column":0},"end":{"line":104,"column":43}},"104":{"start":{"line":105,"column":0},"end":{"line":105,"column":27}},"105":{"start":{"line":106,"column":0},"end":{"line":106,"column":1}},"106":{"start":{"line":107,"column":0},"end":{"line":107,"column":0}},"107":{"start":{"line":108,"column":0},"end":{"line":108,"column":35}},"108":{"start":{"line":109,"column":0},"end":{"line":109,"column":27}},"109":{"start":{"line":110,"column":0},"end":{"line":110,"column":1}},"110":{"start":{"line":111,"column":0},"end":{"line":111,"column":0}},"111":{"start":{"line":112,"column":0},"end":{"line":112,"column":42}},"112":{"start":{"line":113,"column":0},"end":{"line":113,"column":32}},"113":{"start":{"line":114,"column":0},"end":{"line":114,"column":1}},"114":{"start":{"line":115,"column":0},"end":{"line":115,"column":0}},"115":{"start":{"line":116,"column":0},"end":{"line":116,"column":76}},"116":{"start":{"line":117,"column":0},"end":{"line":117,"column":57}},"117":{"start":{"line":118,"column":0},"end":{"line":118,"column":1}},"118":{"start":{"line":119,"column":0},"end":{"line":119,"column":0}},"119":{"start":{"line":120,"column":0},"end":{"line":120,"column":54}},"120":{"start":{"line":121,"column":0},"end":{"line":121,"column":55}},"121":{"start":{"line":122,"column":0},"end":{"line":122,"column":1}},"122":{"start":{"line":123,"column":0},"end":{"line":123,"column":0}},"123":{"start":{"line":124,"column":0},"end":{"line":124,"column":40}},"124":{"start":{"line":125,"column":0},"end":{"line":125,"column":48}},"125":{"start":{"line":126,"column":0},"end":{"line":126,"column":1}},"126":{"start":{"line":127,"column":0},"end":{"line":127,"column":0}},"127":{"start":{"line":128,"column":0},"end":{"line":128,"column":43}},"128":{"start":{"line":129,"column":0},"end":{"line":129,"column":30}},"129":{"start":{"line":130,"column":0},"end":{"line":130,"column":1}},"130":{"start":{"line":131,"column":0},"end":{"line":131,"column":0}},"131":{"start":{"line":132,"column":0},"end":{"line":132,"column":55}},"132":{"start":{"line":133,"column":0},"end":{"line":133,"column":50}},"133":{"start":{"line":134,"column":0},"end":{"line":134,"column":1}},"134":{"start":{"line":135,"column":0},"end":{"line":135,"column":0}},"135":{"start":{"line":136,"column":0},"end":{"line":136,"column":51}},"136":{"start":{"line":137,"column":0},"end":{"line":137,"column":35}},"137":{"start":{"line":138,"column":0},"end":{"line":138,"column":1}},"138":{"start":{"line":139,"column":0},"end":{"line":139,"column":0}},"139":{"start":{"line":140,"column":0},"end":{"line":140,"column":54}},"140":{"start":{"line":141,"column":0},"end":{"line":141,"column":30}},"141":{"start":{"line":142,"column":0},"end":{"line":142,"column":1}},"142":{"start":{"line":143,"column":0},"end":{"line":143,"column":0}},"143":{"start":{"line":144,"column":0},"end":{"line":144,"column":54}},"144":{"start":{"line":145,"column":0},"end":{"line":145,"column":37}},"145":{"start":{"line":146,"column":0},"end":{"line":146,"column":1}},"146":{"start":{"line":147,"column":0},"end":{"line":147,"column":0}},"147":{"start":{"line":148,"column":0},"end":{"line":148,"column":73}},"148":{"start":{"line":149,"column":0},"end":{"line":149,"column":42}},"149":{"start":{"line":150,"column":0},"end":{"line":150,"column":1}},"150":{"start":{"line":151,"column":0},"end":{"line":151,"column":0}},"151":{"start":{"line":152,"column":0},"end":{"line":152,"column":39}},"152":{"start":{"line":153,"column":0},"end":{"line":153,"column":30}},"153":{"start":{"line":154,"column":0},"end":{"line":154,"column":1}},"154":{"start":{"line":155,"column":0},"end":{"line":155,"column":0}},"155":{"start":{"line":156,"column":0},"end":{"line":156,"column":26}},"156":{"start":{"line":157,"column":0},"end":{"line":157,"column":26}},"157":{"start":{"line":158,"column":0},"end":{"line":158,"column":1}},"158":{"start":{"line":159,"column":0},"end":{"line":159,"column":0}},"159":{"start":{"line":160,"column":0},"end":{"line":160,"column":25}},"160":{"start":{"line":161,"column":0},"end":{"line":161,"column":25}},"161":{"start":{"line":162,"column":0},"end":{"line":162,"column":1}},"162":{"start":{"line":163,"column":0},"end":{"line":163,"column":0}},"163":{"start":{"line":164,"column":0},"end":{"line":164,"column":8}},"164":{"start":{"line":165,"column":0},"end":{"line":165,"column":7}},"165":{"start":{"line":166,"column":0},"end":{"line":166,"column":12}},"166":{"start":{"line":167,"column":0},"end":{"line":167,"column":19}},"167":{"start":{"line":168,"column":0},"end":{"line":168,"column":17}},"168":{"start":{"line":169,"column":0},"end":{"line":169,"column":15}},"169":{"start":{"line":170,"column":0},"end":{"line":170,"column":10}},"170":{"start":{"line":171,"column":0},"end":{"line":171,"column":17}},"171":{"start":{"line":172,"column":0},"end":{"line":172,"column":19}},"172":{"start":{"line":173,"column":0},"end":{"line":173,"column":17}},"173":{"start":{"line":174,"column":0},"end":{"line":174,"column":19}},"174":{"start":{"line":175,"column":0},"end":{"line":175,"column":24}},"175":{"start":{"line":176,"column":0},"end":{"line":176,"column":17}},"176":{"start":{"line":177,"column":0},"end":{"line":177,"column":10}},"177":{"start":{"line":178,"column":0},"end":{"line":178,"column":12}},"178":{"start":{"line":179,"column":0},"end":{"line":179,"column":9}},"179":{"start":{"line":180,"column":0},"end":{"line":180,"column":10}},"180":{"start":{"line":181,"column":0},"end":{"line":181,"column":11}},"181":{"start":{"line":182,"column":0},"end":{"line":182,"column":16}},"182":{"start":{"line":183,"column":0},"end":{"line":183,"column":8}},"183":{"start":{"line":184,"column":0},"end":{"line":184,"column":10}},"184":{"start":{"line":185,"column":0},"end":{"line":185,"column":9}},"185":{"start":{"line":186,"column":0},"end":{"line":186,"column":9}},"186":{"start":{"line":187,"column":0},"end":{"line":187,"column":25}},"187":{"start":{"line":188,"column":0},"end":{"line":188,"column":23}},"188":{"start":{"line":189,"column":0},"end":{"line":189,"column":21}},"189":{"start":{"line":190,"column":0},"end":{"line":190,"column":19}},"190":{"start":{"line":191,"column":0},"end":{"line":191,"column":15}},"191":{"start":{"line":192,"column":0},"end":{"line":192,"column":31}},"192":{"start":{"line":193,"column":0},"end":{"line":193,"column":14}},"193":{"start":{"line":194,"column":0},"end":{"line":194,"column":20}},"194":{"start":{"line":195,"column":0},"end":{"line":195,"column":16}},"195":{"start":{"line":196,"column":0},"end":{"line":196,"column":17}},"196":{"start":{"line":197,"column":0},"end":{"line":197,"column":16}},"197":{"start":{"line":198,"column":0},"end":{"line":198,"column":17}},"198":{"start":{"line":199,"column":0},"end":{"line":199,"column":15}},"199":{"start":{"line":200,"column":0},"end":{"line":200,"column":20}},"200":{"start":{"line":201,"column":0},"end":{"line":201,"column":2}},"201":{"start":{"line":202,"column":0},"end":{"line":202,"column":0}},"202":{"start":{"line":203,"column":0},"end":{"line":203,"column":62}},"203":{"start":{"line":204,"column":0},"end":{"line":204,"column":0}},"204":{"start":{"line":205,"column":0},"end":{"line":205,"column":13}},"205":{"start":{"line":206,"column":0},"end":{"line":206,"column":14}},"206":{"start":{"line":207,"column":0},"end":{"line":207,"column":14}},"207":{"start":{"line":208,"column":0},"end":{"line":208,"column":14}},"208":{"start":{"line":209,"column":0},"end":{"line":209,"column":14}},"209":{"start":{"line":210,"column":0},"end":{"line":210,"column":13}},"210":{"start":{"line":211,"column":0},"end":{"line":211,"column":19}},"211":{"start":{"line":212,"column":0},"end":{"line":212,"column":15}},"212":{"start":{"line":213,"column":0},"end":{"line":213,"column":16}},"213":{"start":{"line":214,"column":0},"end":{"line":214,"column":13}},"214":{"start":{"line":215,"column":0},"end":{"line":215,"column":11}},"215":{"start":{"line":216,"column":0},"end":{"line":216,"column":13}},"216":{"start":{"line":217,"column":0},"end":{"line":217,"column":10}},"217":{"start":{"line":218,"column":0},"end":{"line":218,"column":21}},"218":{"start":{"line":219,"column":0},"end":{"line":219,"column":14}},"219":{"start":{"line":220,"column":0},"end":{"line":220,"column":18}},"220":{"start":{"line":221,"column":0},"end":{"line":221,"column":16}},"221":{"start":{"line":222,"column":0},"end":{"line":222,"column":13}},"222":{"start":{"line":223,"column":0},"end":{"line":223,"column":11}},"223":{"start":{"line":224,"column":0},"end":{"line":224,"column":18}},"224":{"start":{"line":225,"column":0},"end":{"line":225,"column":2}},"225":{"start":{"line":226,"column":0},"end":{"line":226,"column":0}},"226":{"start":{"line":227,"column":0},"end":{"line":227,"column":16}},"227":{"start":{"line":228,"column":0},"end":{"line":228,"column":7}},"228":{"start":{"line":229,"column":0},"end":{"line":229,"column":12}},"229":{"start":{"line":230,"column":0},"end":{"line":230,"column":19}},"230":{"start":{"line":231,"column":0},"end":{"line":231,"column":17}},"231":{"start":{"line":232,"column":0},"end":{"line":232,"column":15}},"232":{"start":{"line":233,"column":0},"end":{"line":233,"column":10}},"233":{"start":{"line":234,"column":0},"end":{"line":234,"column":17}},"234":{"start":{"line":235,"column":0},"end":{"line":235,"column":19}},"235":{"start":{"line":236,"column":0},"end":{"line":236,"column":17}},"236":{"start":{"line":237,"column":0},"end":{"line":237,"column":19}},"237":{"start":{"line":238,"column":0},"end":{"line":238,"column":24}},"238":{"start":{"line":239,"column":0},"end":{"line":239,"column":17}},"239":{"start":{"line":240,"column":0},"end":{"line":240,"column":10}},"240":{"start":{"line":241,"column":0},"end":{"line":241,"column":12}},"241":{"start":{"line":242,"column":0},"end":{"line":242,"column":9}},"242":{"start":{"line":243,"column":0},"end":{"line":243,"column":10}},"243":{"start":{"line":244,"column":0},"end":{"line":244,"column":11}},"244":{"start":{"line":245,"column":0},"end":{"line":245,"column":16}},"245":{"start":{"line":246,"column":0},"end":{"line":246,"column":8}},"246":{"start":{"line":247,"column":0},"end":{"line":247,"column":10}},"247":{"start":{"line":248,"column":0},"end":{"line":248,"column":9}},"248":{"start":{"line":249,"column":0},"end":{"line":249,"column":18}},"249":{"start":{"line":250,"column":0},"end":{"line":250,"column":32}},"250":{"start":{"line":251,"column":0},"end":{"line":251,"column":25}},"251":{"start":{"line":252,"column":0},"end":{"line":252,"column":2}}},"s":{"0":1,"1":1,"2":1,"3":1,"4":1,"5":1,"6":1,"7":1,"8":1,"9":1,"10":1,"11":1,"12":1,"13":1,"14":1,"15":1,"16":1,"17":0,"18":0,"19":0,"20":0,"21":0,"22":0,"23":0,"24":0,"25":0,"26":0,"27":0,"28":0,"29":0,"30":0,"31":0,"32":0,"33":0,"34":0,"35":0,"36":0,"37":0,"38":0,"39":0,"40":0,"41":0,"42":0,"43":0,"44":0,"45":0,"46":0,"47":0,"48":0,"49":0,"50":0,"51":0,"52":0,"53":0,"54":0,"55":0,"56":0,"57":0,"58":0,"59":0,"60":0,"61":0,"62":0,"63":0,"64":0,"65":0,"66":0,"67":1,"68":0,"69":0,"70":0,"71":1,"72":0,"73":0,"74":0,"75":0,"76":0,"77":0,"78":0,"79":0,"80":1,"81":0,"82":0,"83":0,"84":0,"85":0,"86":0,"87":0,"88":0,"89":1,"90":0,"91":0,"92":0,"93":0,"94":0,"95":0,"96":0,"97":0,"98":1,"99":0,"100":0,"101":0,"102":1,"103":0,"104":0,"105":0,"106":1,"107":0,"108":0,"109":0,"110":1,"111":0,"112":0,"113":0,"114":1,"115":0,"116":0,"117":0,"118":1,"119":0,"120":0,"121":0,"122":1,"123":0,"124":0,"125":0,"126":1,"127":0,"128":0,"129":0,"130":1,"131":0,"132":0,"133":0,"134":1,"135":0,"136":0,"137":0,"138":1,"139":0,"140":0,"141":0,"142":1,"143":0,"144":0,"145":0,"146":1,"147":0,"148":0,"149":0,"150":1,"151":0,"152":0,"153":0,"154":1,"155":0,"156":0,"157":0,"158":1,"159":0,"160":0,"161":0,"162":1,"163":1,"164":1,"165":1,"166":1,"167":1,"168":1,"169":1,"170":1,"171":1,"172":1,"173":1,"174":1,"175":1,"176":1,"177":1,"178":1,"179":1,"180":1,"181":1,"182":1,"183":1,"184":1,"185":1,"186":1,"187":1,"188":1,"189":1,"190":1,"191":1,"192":1,"193":1,"194":1,"195":1,"196":1,"197":1,"198":1,"199":1,"200":1,"201":1,"202":1,"203":1,"204":1,"205":1,"206":1,"207":1,"208":1,"209":1,"210":1,"211":1,"212":1,"213":1,"214":1,"215":1,"216":1,"217":1,"218":1,"219":1,"220":1,"221":1,"222":1,"223":1,"224":1,"225":1,"226":1,"227":1,"228":1,"229":1,"230":1,"231":1,"232":1,"233":1,"234":1,"235":1,"236":1,"237":1,"238":1,"239":1,"240":1,"241":1,"242":1,"243":1,"244":1,"245":1,"246":1,"247":1,"248":1,"249":1,"250":1,"251":1},"branchMap":{},"b":{},"fnMap":{"0":{"name":"init","decl":{"start":{"line":18,"column":0},"end":{"line":67,"column":1}},"loc":{"start":{"line":18,"column":0},"end":{"line":67,"column":1}},"line":18},"1":{"name":"getClient","decl":{"start":{"line":69,"column":0},"end":{"line":71,"column":1}},"loc":{"start":{"line":69,"column":0},"end":{"line":71,"column":1}},"line":69},"2":{"name":"captureException","decl":{"start":{"line":73,"column":0},"end":{"line":80,"column":1}},"loc":{"start":{"line":73,"column":0},"end":{"line":80,"column":1}},"line":73},"3":{"name":"captureMessage","decl":{"start":{"line":82,"column":0},"end":{"line":89,"column":1}},"loc":{"start":{"line":82,"column":0},"end":{"line":89,"column":1}},"line":82},"4":{"name":"captureEvent","decl":{"start":{"line":91,"column":0},"end":{"line":98,"column":1}},"loc":{"start":{"line":91,"column":0},"end":{"line":98,"column":1}},"line":91},"5":{"name":"setUser","decl":{"start":{"line":100,"column":0},"end":{"line":102,"column":1}},"loc":{"start":{"line":100,"column":0},"end":{"line":102,"column":1}},"line":100},"6":{"name":"setAnonymousId","decl":{"start":{"line":104,"column":0},"end":{"line":106,"column":1}},"loc":{"start":{"line":104,"column":0},"end":{"line":106,"column":1}},"line":104},"7":{"name":"clearAnonymousId","decl":{"start":{"line":108,"column":0},"end":{"line":110,"column":1}},"loc":{"start":{"line":108,"column":0},"end":{"line":110,"column":1}},"line":108},"8":{"name":"getAnonymousId","decl":{"start":{"line":112,"column":0},"end":{"line":114,"column":1}},"loc":{"start":{"line":112,"column":0},"end":{"line":114,"column":1}},"line":112},"9":{"name":"startTransaction","decl":{"start":{"line":116,"column":0},"end":{"line":118,"column":1}},"loc":{"start":{"line":116,"column":0},"end":{"line":118,"column":1}},"line":116},"10":{"name":"getCurrentTransaction","decl":{"start":{"line":120,"column":0},"end":{"line":122,"column":1}},"loc":{"start":{"line":120,"column":0},"end":{"line":122,"column":1}},"line":120},"11":{"name":"getCurrentSpan","decl":{"start":{"line":124,"column":0},"end":{"line":126,"column":1}},"loc":{"start":{"line":124,"column":0},"end":{"line":126,"column":1}},"line":124},"12":{"name":"setSpan","decl":{"start":{"line":128,"column":0},"end":{"line":130,"column":1}},"loc":{"start":{"line":128,"column":0},"end":{"line":130,"column":1}},"line":128},"13":{"name":"startSpan","decl":{"start":{"line":132,"column":0},"end":{"line":134,"column":1}},"loc":{"start":{"line":132,"column":0},"end":{"line":134,"column":1}},"line":132},"14":{"name":"setTag","decl":{"start":{"line":136,"column":0},"end":{"line":138,"column":1}},"loc":{"start":{"line":136,"column":0},"end":{"line":138,"column":1}},"line":136},"15":{"name":"setTags","decl":{"start":{"line":140,"column":0},"end":{"line":142,"column":1}},"loc":{"start":{"line":140,"column":0},"end":{"line":142,"column":1}},"line":140},"16":{"name":"setExtra","decl":{"start":{"line":144,"column":0},"end":{"line":146,"column":1}},"loc":{"start":{"line":144,"column":0},"end":{"line":146,"column":1}},"line":144},"17":{"name":"addBreadcrumb","decl":{"start":{"line":148,"column":0},"end":{"line":150,"column":1}},"loc":{"start":{"line":148,"column":0},"end":{"line":150,"column":1}},"line":148},"18":{"name":"flush","decl":{"start":{"line":152,"column":0},"end":{"line":154,"column":1}},"loc":{"start":{"line":152,"column":0},"end":{"line":154,"column":1}},"line":152},"19":{"name":"disable","decl":{"start":{"line":156,"column":0},"end":{"line":158,"column":1}},"loc":{"start":{"line":156,"column":0},"end":{"line":158,"column":1}},"line":156},"20":{"name":"enable","decl":{"start":{"line":160,"column":0},"end":{"line":162,"column":1}},"loc":{"start":{"line":160,"column":0},"end":{"line":162,"column":1}},"line":160}},"f":{"0":0,"1":0,"2":0,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10":0,"11":0,"12":0,"13":0,"14":0,"15":0,"16":0,"17":0,"18":0,"19":0,"20":0}} +,"/Users/weidingjian/Desktop/work/ai/light-sentry-sdk/src/core/Client.ts": {"path":"/Users/weidingjian/Desktop/work/ai/light-sentry-sdk/src/core/Client.ts","all":false,"statementMap":{"0":{"start":{"line":1,"column":0},"end":{"line":1,"column":190}},"1":{"start":{"line":2,"column":0},"end":{"line":2,"column":40}},"2":{"start":{"line":3,"column":0},"end":{"line":3,"column":38}},"3":{"start":{"line":4,"column":0},"end":{"line":4,"column":51}},"4":{"start":{"line":5,"column":0},"end":{"line":5,"column":54}},"5":{"start":{"line":6,"column":0},"end":{"line":6,"column":53}},"6":{"start":{"line":7,"column":0},"end":{"line":7,"column":75}},"7":{"start":{"line":8,"column":0},"end":{"line":8,"column":48}},"8":{"start":{"line":9,"column":0},"end":{"line":9,"column":38}},"9":{"start":{"line":10,"column":0},"end":{"line":10,"column":42}},"10":{"start":{"line":11,"column":0},"end":{"line":11,"column":38}},"11":{"start":{"line":12,"column":0},"end":{"line":12,"column":48}},"12":{"start":{"line":13,"column":0},"end":{"line":13,"column":50}},"13":{"start":{"line":14,"column":0},"end":{"line":14,"column":0}},"14":{"start":{"line":15,"column":0},"end":{"line":15,"column":37}},"15":{"start":{"line":16,"column":0},"end":{"line":16,"column":15}},"16":{"start":{"line":17,"column":0},"end":{"line":17,"column":2}},"17":{"start":{"line":18,"column":0},"end":{"line":18,"column":39}},"18":{"start":{"line":19,"column":0},"end":{"line":19,"column":29}},"19":{"start":{"line":20,"column":0},"end":{"line":20,"column":28}},"20":{"start":{"line":21,"column":0},"end":{"line":21,"column":29}},"21":{"start":{"line":22,"column":0},"end":{"line":22,"column":39}},"22":{"start":{"line":23,"column":0},"end":{"line":23,"column":41}},"23":{"start":{"line":24,"column":0},"end":{"line":24,"column":41}},"24":{"start":{"line":25,"column":0},"end":{"line":25,"column":34}},"25":{"start":{"line":26,"column":0},"end":{"line":26,"column":0}},"26":{"start":{"line":27,"column":0},"end":{"line":27,"column":40}},"27":{"start":{"line":28,"column":0},"end":{"line":28,"column":58}},"28":{"start":{"line":29,"column":0},"end":{"line":29,"column":3}},"29":{"start":{"line":30,"column":0},"end":{"line":30,"column":0}},"30":{"start":{"line":31,"column":0},"end":{"line":31,"column":29}},"31":{"start":{"line":32,"column":0},"end":{"line":32,"column":39}},"32":{"start":{"line":33,"column":0},"end":{"line":33,"column":3}},"33":{"start":{"line":34,"column":0},"end":{"line":34,"column":0}},"34":{"start":{"line":35,"column":0},"end":{"line":35,"column":36}},"35":{"start":{"line":36,"column":0},"end":{"line":36,"column":22}},"36":{"start":{"line":37,"column":0},"end":{"line":37,"column":41}},"37":{"start":{"line":38,"column":0},"end":{"line":38,"column":5}},"38":{"start":{"line":39,"column":0},"end":{"line":39,"column":0}},"39":{"start":{"line":40,"column":0},"end":{"line":40,"column":36}},"40":{"start":{"line":41,"column":0},"end":{"line":41,"column":120}},"41":{"start":{"line":42,"column":0},"end":{"line":42,"column":0}},"42":{"start":{"line":43,"column":0},"end":{"line":43,"column":36}},"43":{"start":{"line":44,"column":0},"end":{"line":44,"column":51}},"44":{"start":{"line":45,"column":0},"end":{"line":45,"column":35}},"45":{"start":{"line":46,"column":0},"end":{"line":46,"column":33}},"46":{"start":{"line":47,"column":0},"end":{"line":47,"column":15}},"47":{"start":{"line":48,"column":0},"end":{"line":48,"column":48}},"48":{"start":{"line":49,"column":0},"end":{"line":49,"column":50}},"49":{"start":{"line":50,"column":0},"end":{"line":50,"column":6}},"50":{"start":{"line":51,"column":0},"end":{"line":51,"column":49}},"51":{"start":{"line":52,"column":0},"end":{"line":52,"column":79}},"52":{"start":{"line":53,"column":0},"end":{"line":53,"column":32}},"53":{"start":{"line":54,"column":0},"end":{"line":54,"column":52}},"54":{"start":{"line":55,"column":0},"end":{"line":55,"column":54}},"55":{"start":{"line":56,"column":0},"end":{"line":56,"column":20}},"56":{"start":{"line":57,"column":0},"end":{"line":57,"column":49}},"57":{"start":{"line":58,"column":0},"end":{"line":58,"column":46}},"58":{"start":{"line":59,"column":0},"end":{"line":59,"column":6}},"59":{"start":{"line":60,"column":0},"end":{"line":60,"column":0}},"60":{"start":{"line":61,"column":0},"end":{"line":61,"column":63}},"61":{"start":{"line":62,"column":0},"end":{"line":62,"column":69}},"62":{"start":{"line":63,"column":0},"end":{"line":63,"column":3}},"63":{"start":{"line":64,"column":0},"end":{"line":64,"column":0}},"64":{"start":{"line":65,"column":0},"end":{"line":65,"column":16}},"65":{"start":{"line":66,"column":0},"end":{"line":66,"column":30}},"66":{"start":{"line":67,"column":0},"end":{"line":67,"column":23}},"67":{"start":{"line":68,"column":0},"end":{"line":68,"column":23}},"68":{"start":{"line":69,"column":0},"end":{"line":69,"column":3}},"69":{"start":{"line":70,"column":0},"end":{"line":70,"column":0}},"70":{"start":{"line":71,"column":0},"end":{"line":71,"column":67}},"71":{"start":{"line":72,"column":0},"end":{"line":72,"column":75}},"72":{"start":{"line":73,"column":0},"end":{"line":73,"column":0}},"73":{"start":{"line":74,"column":0},"end":{"line":74,"column":46}},"74":{"start":{"line":75,"column":0},"end":{"line":75,"column":0}},"75":{"start":{"line":76,"column":0},"end":{"line":76,"column":33}},"76":{"start":{"line":77,"column":0},"end":{"line":77,"column":68}},"77":{"start":{"line":78,"column":0},"end":{"line":78,"column":22}},"78":{"start":{"line":79,"column":0},"end":{"line":79,"column":40}},"79":{"start":{"line":80,"column":0},"end":{"line":80,"column":14}},"80":{"start":{"line":81,"column":0},"end":{"line":81,"column":147}},"81":{"start":{"line":82,"column":0},"end":{"line":82,"column":7}},"82":{"start":{"line":83,"column":0},"end":{"line":83,"column":5}},"83":{"start":{"line":84,"column":0},"end":{"line":84,"column":0}},"84":{"start":{"line":85,"column":0},"end":{"line":85,"column":39}},"85":{"start":{"line":86,"column":0},"end":{"line":86,"column":77}},"86":{"start":{"line":87,"column":0},"end":{"line":87,"column":13}},"87":{"start":{"line":88,"column":0},"end":{"line":88,"column":5}},"88":{"start":{"line":89,"column":0},"end":{"line":89,"column":0}},"89":{"start":{"line":90,"column":0},"end":{"line":90,"column":30}},"90":{"start":{"line":91,"column":0},"end":{"line":91,"column":42}},"91":{"start":{"line":92,"column":0},"end":{"line":92,"column":4}},"92":{"start":{"line":93,"column":0},"end":{"line":93,"column":42}},"93":{"start":{"line":94,"column":0},"end":{"line":94,"column":80}},"94":{"start":{"line":95,"column":0},"end":{"line":95,"column":29}},"95":{"start":{"line":96,"column":0},"end":{"line":96,"column":6}},"96":{"start":{"line":97,"column":0},"end":{"line":97,"column":62}},"97":{"start":{"line":98,"column":0},"end":{"line":98,"column":79}},"98":{"start":{"line":99,"column":0},"end":{"line":99,"column":29}},"99":{"start":{"line":100,"column":0},"end":{"line":100,"column":81}},"100":{"start":{"line":101,"column":0},"end":{"line":101,"column":17}},"101":{"start":{"line":102,"column":0},"end":{"line":102,"column":7}},"102":{"start":{"line":103,"column":0},"end":{"line":103,"column":0}},"103":{"start":{"line":104,"column":0},"end":{"line":104,"column":40}},"104":{"start":{"line":105,"column":0},"end":{"line":105,"column":5}},"105":{"start":{"line":106,"column":0},"end":{"line":106,"column":0}},"106":{"start":{"line":107,"column":0},"end":{"line":107,"column":35}},"107":{"start":{"line":108,"column":0},"end":{"line":108,"column":75}},"108":{"start":{"line":109,"column":0},"end":{"line":109,"column":13}},"109":{"start":{"line":110,"column":0},"end":{"line":110,"column":5}},"110":{"start":{"line":111,"column":0},"end":{"line":111,"column":0}},"111":{"start":{"line":112,"column":0},"end":{"line":112,"column":74}},"112":{"start":{"line":113,"column":0},"end":{"line":113,"column":44}},"113":{"start":{"line":114,"column":0},"end":{"line":114,"column":56}},"114":{"start":{"line":115,"column":0},"end":{"line":115,"column":45}},"115":{"start":{"line":116,"column":0},"end":{"line":116,"column":0}},"116":{"start":{"line":117,"column":0},"end":{"line":117,"column":38}},"117":{"start":{"line":118,"column":0},"end":{"line":118,"column":49}},"118":{"start":{"line":119,"column":0},"end":{"line":119,"column":5}},"119":{"start":{"line":120,"column":0},"end":{"line":120,"column":3}},"120":{"start":{"line":121,"column":0},"end":{"line":121,"column":0}},"121":{"start":{"line":122,"column":0},"end":{"line":122,"column":56}},"122":{"start":{"line":123,"column":0},"end":{"line":123,"column":46}},"123":{"start":{"line":124,"column":0},"end":{"line":124,"column":0}},"124":{"start":{"line":125,"column":0},"end":{"line":125,"column":33}},"125":{"start":{"line":126,"column":0},"end":{"line":126,"column":68}},"126":{"start":{"line":127,"column":0},"end":{"line":127,"column":22}},"127":{"start":{"line":128,"column":0},"end":{"line":128,"column":40}},"128":{"start":{"line":129,"column":0},"end":{"line":129,"column":7}},"129":{"start":{"line":130,"column":0},"end":{"line":130,"column":5}},"130":{"start":{"line":131,"column":0},"end":{"line":131,"column":0}},"131":{"start":{"line":132,"column":0},"end":{"line":132,"column":45}},"132":{"start":{"line":133,"column":0},"end":{"line":133,"column":0}},"133":{"start":{"line":134,"column":0},"end":{"line":134,"column":30}},"134":{"start":{"line":135,"column":0},"end":{"line":135,"column":42}},"135":{"start":{"line":136,"column":0},"end":{"line":136,"column":4}},"136":{"start":{"line":137,"column":0},"end":{"line":137,"column":42}},"137":{"start":{"line":138,"column":0},"end":{"line":138,"column":80}},"138":{"start":{"line":139,"column":0},"end":{"line":139,"column":29}},"139":{"start":{"line":140,"column":0},"end":{"line":140,"column":6}},"140":{"start":{"line":141,"column":0},"end":{"line":141,"column":62}},"141":{"start":{"line":142,"column":0},"end":{"line":142,"column":79}},"142":{"start":{"line":143,"column":0},"end":{"line":143,"column":37}},"143":{"start":{"line":144,"column":0},"end":{"line":144,"column":0}},"144":{"start":{"line":145,"column":0},"end":{"line":145,"column":40}},"145":{"start":{"line":146,"column":0},"end":{"line":146,"column":5}},"146":{"start":{"line":147,"column":0},"end":{"line":147,"column":0}},"147":{"start":{"line":148,"column":0},"end":{"line":148,"column":41}},"148":{"start":{"line":149,"column":0},"end":{"line":149,"column":0}},"149":{"start":{"line":150,"column":0},"end":{"line":150,"column":42}},"150":{"start":{"line":151,"column":0},"end":{"line":151,"column":45}},"151":{"start":{"line":152,"column":0},"end":{"line":152,"column":3}},"152":{"start":{"line":153,"column":0},"end":{"line":153,"column":0}},"153":{"start":{"line":154,"column":0},"end":{"line":154,"column":66}},"154":{"start":{"line":155,"column":0},"end":{"line":155,"column":37}},"155":{"start":{"line":156,"column":0},"end":{"line":156,"column":3}},"156":{"start":{"line":157,"column":0},"end":{"line":157,"column":0}},"157":{"start":{"line":158,"column":0},"end":{"line":158,"column":67}},"158":{"start":{"line":159,"column":0},"end":{"line":159,"column":38}},"159":{"start":{"line":160,"column":0},"end":{"line":160,"column":3}},"160":{"start":{"line":161,"column":0},"end":{"line":161,"column":0}},"161":{"start":{"line":162,"column":0},"end":{"line":162,"column":49}},"162":{"start":{"line":163,"column":0},"end":{"line":163,"column":39}},"163":{"start":{"line":164,"column":0},"end":{"line":164,"column":3}},"164":{"start":{"line":165,"column":0},"end":{"line":165,"column":0}},"165":{"start":{"line":166,"column":0},"end":{"line":166,"column":50}},"166":{"start":{"line":167,"column":0},"end":{"line":167,"column":117}},"167":{"start":{"line":168,"column":0},"end":{"line":168,"column":0}},"168":{"start":{"line":169,"column":0},"end":{"line":169,"column":24}},"169":{"start":{"line":170,"column":0},"end":{"line":170,"column":67}},"170":{"start":{"line":171,"column":0},"end":{"line":171,"column":13}},"171":{"start":{"line":172,"column":0},"end":{"line":172,"column":5}},"172":{"start":{"line":173,"column":0},"end":{"line":173,"column":0}},"173":{"start":{"line":174,"column":0},"end":{"line":174,"column":51}},"174":{"start":{"line":175,"column":0},"end":{"line":175,"column":153}},"175":{"start":{"line":176,"column":0},"end":{"line":176,"column":0}},"176":{"start":{"line":177,"column":0},"end":{"line":177,"column":64}},"177":{"start":{"line":178,"column":0},"end":{"line":178,"column":84}},"178":{"start":{"line":179,"column":0},"end":{"line":179,"column":13}},"179":{"start":{"line":180,"column":0},"end":{"line":180,"column":5}},"180":{"start":{"line":181,"column":0},"end":{"line":181,"column":0}},"181":{"start":{"line":182,"column":0},"end":{"line":182,"column":40}},"182":{"start":{"line":183,"column":0},"end":{"line":183,"column":51}},"183":{"start":{"line":184,"column":0},"end":{"line":184,"column":88}},"184":{"start":{"line":185,"column":0},"end":{"line":185,"column":35}},"185":{"start":{"line":186,"column":0},"end":{"line":186,"column":3}},"186":{"start":{"line":187,"column":0},"end":{"line":187,"column":0}},"187":{"start":{"line":188,"column":0},"end":{"line":188,"column":69}},"188":{"start":{"line":189,"column":0},"end":{"line":189,"column":30}},"189":{"start":{"line":190,"column":0},"end":{"line":190,"column":0}},"190":{"start":{"line":191,"column":0},"end":{"line":191,"column":31}},"191":{"start":{"line":192,"column":0},"end":{"line":192,"column":20}},"192":{"start":{"line":193,"column":0},"end":{"line":193,"column":12}},"193":{"start":{"line":194,"column":0},"end":{"line":194,"column":14}},"194":{"start":{"line":195,"column":0},"end":{"line":195,"column":23}},"195":{"start":{"line":196,"column":0},"end":{"line":196,"column":41}},"196":{"start":{"line":197,"column":0},"end":{"line":197,"column":6}},"197":{"start":{"line":198,"column":0},"end":{"line":198,"column":0}},"198":{"start":{"line":199,"column":0},"end":{"line":199,"column":59}},"199":{"start":{"line":200,"column":0},"end":{"line":200,"column":0}},"200":{"start":{"line":201,"column":0},"end":{"line":201,"column":35}},"201":{"start":{"line":202,"column":0},"end":{"line":202,"column":30}},"202":{"start":{"line":203,"column":0},"end":{"line":203,"column":3}},"203":{"start":{"line":204,"column":0},"end":{"line":204,"column":0}},"204":{"start":{"line":205,"column":0},"end":{"line":205,"column":70}},"205":{"start":{"line":206,"column":0},"end":{"line":206,"column":30}},"206":{"start":{"line":207,"column":0},"end":{"line":207,"column":0}},"207":{"start":{"line":208,"column":0},"end":{"line":208,"column":23}},"208":{"start":{"line":209,"column":0},"end":{"line":209,"column":23}},"209":{"start":{"line":210,"column":0},"end":{"line":210,"column":34}},"210":{"start":{"line":211,"column":0},"end":{"line":211,"column":41}},"211":{"start":{"line":212,"column":0},"end":{"line":212,"column":15}},"212":{"start":{"line":213,"column":0},"end":{"line":213,"column":21}},"213":{"start":{"line":214,"column":0},"end":{"line":214,"column":0}},"214":{"start":{"line":215,"column":0},"end":{"line":215,"column":39}},"215":{"start":{"line":216,"column":0},"end":{"line":216,"column":34}},"216":{"start":{"line":217,"column":0},"end":{"line":217,"column":3}},"217":{"start":{"line":218,"column":0},"end":{"line":218,"column":0}},"218":{"start":{"line":219,"column":0},"end":{"line":219,"column":56}},"219":{"start":{"line":220,"column":0},"end":{"line":220,"column":61}},"220":{"start":{"line":221,"column":0},"end":{"line":221,"column":75}},"221":{"start":{"line":222,"column":0},"end":{"line":222,"column":0}},"222":{"start":{"line":223,"column":0},"end":{"line":223,"column":44}},"223":{"start":{"line":224,"column":0},"end":{"line":224,"column":74}},"224":{"start":{"line":225,"column":0},"end":{"line":225,"column":71}},"225":{"start":{"line":226,"column":0},"end":{"line":226,"column":53}},"226":{"start":{"line":227,"column":0},"end":{"line":227,"column":59}},"227":{"start":{"line":228,"column":0},"end":{"line":228,"column":71}},"228":{"start":{"line":229,"column":0},"end":{"line":229,"column":0}},"229":{"start":{"line":230,"column":0},"end":{"line":230,"column":24}},"230":{"start":{"line":231,"column":0},"end":{"line":231,"column":26}},"231":{"start":{"line":232,"column":0},"end":{"line":232,"column":16}},"232":{"start":{"line":233,"column":0},"end":{"line":233,"column":34}},"233":{"start":{"line":234,"column":0},"end":{"line":234,"column":32}},"234":{"start":{"line":235,"column":0},"end":{"line":235,"column":39}},"235":{"start":{"line":236,"column":0},"end":{"line":236,"column":13}},"236":{"start":{"line":237,"column":0},"end":{"line":237,"column":17}},"237":{"start":{"line":238,"column":0},"end":{"line":238,"column":10}},"238":{"start":{"line":239,"column":0},"end":{"line":239,"column":8}},"239":{"start":{"line":240,"column":0},"end":{"line":240,"column":5}},"240":{"start":{"line":241,"column":0},"end":{"line":241,"column":3}},"241":{"start":{"line":242,"column":0},"end":{"line":242,"column":0}},"242":{"start":{"line":243,"column":0},"end":{"line":243,"column":63}},"243":{"start":{"line":244,"column":0},"end":{"line":244,"column":28}},"244":{"start":{"line":245,"column":0},"end":{"line":245,"column":4}},"245":{"start":{"line":246,"column":0},"end":{"line":246,"column":33}},"246":{"start":{"line":247,"column":0},"end":{"line":247,"column":68}},"247":{"start":{"line":248,"column":0},"end":{"line":248,"column":80}},"248":{"start":{"line":249,"column":0},"end":{"line":249,"column":6}},"249":{"start":{"line":250,"column":0},"end":{"line":250,"column":14}},"250":{"start":{"line":251,"column":0},"end":{"line":251,"column":22}},"251":{"start":{"line":252,"column":0},"end":{"line":252,"column":23}},"252":{"start":{"line":253,"column":0},"end":{"line":253,"column":31}},"253":{"start":{"line":254,"column":0},"end":{"line":254,"column":18}},"254":{"start":{"line":255,"column":0},"end":{"line":255,"column":20}},"255":{"start":{"line":256,"column":0},"end":{"line":256,"column":27}},"256":{"start":{"line":257,"column":0},"end":{"line":257,"column":31}},"257":{"start":{"line":258,"column":0},"end":{"line":258,"column":23}},"258":{"start":{"line":259,"column":0},"end":{"line":259,"column":19}},"259":{"start":{"line":260,"column":0},"end":{"line":260,"column":12}},"260":{"start":{"line":261,"column":0},"end":{"line":261,"column":10}},"261":{"start":{"line":262,"column":0},"end":{"line":262,"column":20}},"262":{"start":{"line":263,"column":0},"end":{"line":263,"column":8}},"263":{"start":{"line":264,"column":0},"end":{"line":264,"column":5}},"264":{"start":{"line":265,"column":0},"end":{"line":265,"column":0}},"265":{"start":{"line":266,"column":0},"end":{"line":266,"column":34}},"266":{"start":{"line":267,"column":0},"end":{"line":267,"column":12}},"267":{"start":{"line":268,"column":0},"end":{"line":268,"column":20}},"268":{"start":{"line":269,"column":0},"end":{"line":269,"column":21}},"269":{"start":{"line":270,"column":0},"end":{"line":270,"column":14}},"270":{"start":{"line":271,"column":0},"end":{"line":271,"column":16}},"271":{"start":{"line":272,"column":0},"end":{"line":272,"column":6}},"272":{"start":{"line":273,"column":0},"end":{"line":273,"column":3}},"273":{"start":{"line":274,"column":0},"end":{"line":274,"column":0}},"274":{"start":{"line":275,"column":0},"end":{"line":275,"column":40}},"275":{"start":{"line":276,"column":0},"end":{"line":276,"column":37}},"276":{"start":{"line":277,"column":0},"end":{"line":277,"column":66}},"277":{"start":{"line":278,"column":0},"end":{"line":278,"column":3}},"278":{"start":{"line":279,"column":0},"end":{"line":279,"column":0}},"279":{"start":{"line":280,"column":0},"end":{"line":280,"column":36}},"280":{"start":{"line":281,"column":0},"end":{"line":281,"column":29}},"281":{"start":{"line":282,"column":0},"end":{"line":282,"column":3}},"282":{"start":{"line":283,"column":0},"end":{"line":283,"column":0}},"283":{"start":{"line":284,"column":0},"end":{"line":284,"column":69}},"284":{"start":{"line":285,"column":0},"end":{"line":285,"column":35}},"285":{"start":{"line":286,"column":0},"end":{"line":286,"column":0}},"286":{"start":{"line":287,"column":0},"end":{"line":287,"column":70}},"287":{"start":{"line":288,"column":0},"end":{"line":288,"column":45}},"288":{"start":{"line":289,"column":0},"end":{"line":289,"column":61}},"289":{"start":{"line":290,"column":0},"end":{"line":290,"column":31}},"290":{"start":{"line":291,"column":0},"end":{"line":291,"column":37}},"291":{"start":{"line":292,"column":0},"end":{"line":292,"column":9}},"292":{"start":{"line":293,"column":0},"end":{"line":293,"column":5}},"293":{"start":{"line":294,"column":0},"end":{"line":294,"column":0}},"294":{"start":{"line":295,"column":0},"end":{"line":295,"column":23}},"295":{"start":{"line":296,"column":0},"end":{"line":296,"column":3}},"296":{"start":{"line":297,"column":0},"end":{"line":297,"column":0}},"297":{"start":{"line":298,"column":0},"end":{"line":298,"column":47}},"298":{"start":{"line":299,"column":0},"end":{"line":299,"column":55}},"299":{"start":{"line":300,"column":0},"end":{"line":300,"column":3}},"300":{"start":{"line":301,"column":0},"end":{"line":301,"column":0}},"301":{"start":{"line":302,"column":0},"end":{"line":302,"column":33}},"302":{"start":{"line":303,"column":0},"end":{"line":303,"column":48}},"303":{"start":{"line":304,"column":0},"end":{"line":304,"column":3}},"304":{"start":{"line":305,"column":0},"end":{"line":305,"column":0}},"305":{"start":{"line":306,"column":0},"end":{"line":306,"column":36}},"306":{"start":{"line":307,"column":0},"end":{"line":307,"column":45}},"307":{"start":{"line":308,"column":0},"end":{"line":308,"column":3}},"308":{"start":{"line":309,"column":0},"end":{"line":309,"column":0}},"309":{"start":{"line":310,"column":0},"end":{"line":310,"column":48}},"310":{"start":{"line":311,"column":0},"end":{"line":311,"column":35}},"311":{"start":{"line":312,"column":0},"end":{"line":312,"column":50}},"312":{"start":{"line":313,"column":0},"end":{"line":313,"column":3}},"313":{"start":{"line":314,"column":0},"end":{"line":314,"column":0}},"314":{"start":{"line":315,"column":0},"end":{"line":315,"column":44}},"315":{"start":{"line":316,"column":0},"end":{"line":316,"column":42}},"316":{"start":{"line":317,"column":0},"end":{"line":317,"column":3}},"317":{"start":{"line":318,"column":0},"end":{"line":318,"column":0}},"318":{"start":{"line":319,"column":0},"end":{"line":319,"column":47}},"319":{"start":{"line":320,"column":0},"end":{"line":320,"column":37}},"320":{"start":{"line":321,"column":0},"end":{"line":321,"column":3}},"321":{"start":{"line":322,"column":0},"end":{"line":322,"column":0}},"322":{"start":{"line":323,"column":0},"end":{"line":323,"column":47}},"323":{"start":{"line":324,"column":0},"end":{"line":324,"column":44}},"324":{"start":{"line":325,"column":0},"end":{"line":325,"column":3}},"325":{"start":{"line":326,"column":0},"end":{"line":326,"column":0}},"326":{"start":{"line":327,"column":0},"end":{"line":327,"column":66}},"327":{"start":{"line":328,"column":0},"end":{"line":328,"column":40}},"328":{"start":{"line":329,"column":0},"end":{"line":329,"column":20}},"329":{"start":{"line":330,"column":0},"end":{"line":330,"column":23}},"330":{"start":{"line":331,"column":0},"end":{"line":331,"column":6}},"331":{"start":{"line":332,"column":0},"end":{"line":332,"column":0}},"332":{"start":{"line":333,"column":0},"end":{"line":333,"column":42}},"333":{"start":{"line":334,"column":0},"end":{"line":334,"column":56}},"334":{"start":{"line":335,"column":0},"end":{"line":335,"column":31}},"335":{"start":{"line":336,"column":0},"end":{"line":336,"column":5}},"336":{"start":{"line":337,"column":0},"end":{"line":337,"column":3}},"337":{"start":{"line":338,"column":0},"end":{"line":338,"column":0}},"338":{"start":{"line":339,"column":0},"end":{"line":339,"column":32}},"339":{"start":{"line":340,"column":0},"end":{"line":340,"column":29}},"340":{"start":{"line":341,"column":0},"end":{"line":341,"column":3}},"341":{"start":{"line":342,"column":0},"end":{"line":342,"column":0}},"342":{"start":{"line":343,"column":0},"end":{"line":343,"column":19}},"343":{"start":{"line":344,"column":0},"end":{"line":344,"column":25}},"344":{"start":{"line":345,"column":0},"end":{"line":345,"column":3}},"345":{"start":{"line":346,"column":0},"end":{"line":346,"column":0}},"346":{"start":{"line":347,"column":0},"end":{"line":347,"column":18}},"347":{"start":{"line":348,"column":0},"end":{"line":348,"column":24}},"348":{"start":{"line":349,"column":0},"end":{"line":349,"column":3}},"349":{"start":{"line":350,"column":0},"end":{"line":350,"column":0}},"350":{"start":{"line":351,"column":0},"end":{"line":351,"column":34}},"351":{"start":{"line":352,"column":0},"end":{"line":352,"column":35}},"352":{"start":{"line":353,"column":0},"end":{"line":353,"column":3}},"353":{"start":{"line":354,"column":0},"end":{"line":354,"column":0}},"354":{"start":{"line":355,"column":0},"end":{"line":355,"column":19}},"355":{"start":{"line":356,"column":0},"end":{"line":356,"column":33}},"356":{"start":{"line":357,"column":0},"end":{"line":357,"column":34}},"357":{"start":{"line":358,"column":0},"end":{"line":358,"column":25}},"358":{"start":{"line":359,"column":0},"end":{"line":359,"column":28}},"359":{"start":{"line":360,"column":0},"end":{"line":360,"column":26}},"360":{"start":{"line":361,"column":0},"end":{"line":361,"column":3}},"361":{"start":{"line":362,"column":0},"end":{"line":362,"column":1}},"362":{"start":{"line":363,"column":0},"end":{"line":363,"column":0}},"363":{"start":{"line":364,"column":0},"end":{"line":364,"column":22}}},"s":{"0":1,"1":1,"2":1,"3":1,"4":1,"5":1,"6":1,"7":1,"8":1,"9":1,"10":1,"11":1,"12":1,"13":1,"14":1,"15":1,"16":1,"17":1,"18":1,"19":1,"20":1,"21":1,"22":1,"23":1,"24":1,"25":1,"26":1,"27":1,"28":1,"29":1,"30":1,"31":0,"32":0,"33":1,"34":1,"35":0,"36":0,"37":0,"38":0,"39":0,"40":0,"41":0,"42":0,"43":0,"44":0,"45":0,"46":0,"47":0,"48":0,"49":0,"50":0,"51":0,"52":0,"53":0,"54":0,"55":0,"56":0,"57":0,"58":0,"59":0,"60":0,"61":0,"62":0,"63":1,"64":1,"65":0,"66":0,"67":0,"68":0,"69":1,"70":1,"71":0,"72":0,"73":0,"74":0,"75":0,"76":0,"77":0,"78":0,"79":0,"80":0,"81":0,"82":0,"83":0,"84":0,"85":0,"86":0,"87":0,"88":0,"89":0,"90":0,"91":0,"92":0,"93":0,"94":0,"95":0,"96":0,"97":0,"98":0,"99":0,"100":0,"101":0,"102":0,"103":0,"104":0,"105":0,"106":0,"107":0,"108":0,"109":0,"110":0,"111":0,"112":0,"113":0,"114":0,"115":0,"116":0,"117":0,"118":0,"119":0,"120":1,"121":1,"122":0,"123":0,"124":0,"125":0,"126":0,"127":0,"128":0,"129":0,"130":0,"131":0,"132":0,"133":0,"134":0,"135":0,"136":0,"137":0,"138":0,"139":0,"140":0,"141":0,"142":0,"143":0,"144":0,"145":0,"146":0,"147":0,"148":0,"149":0,"150":0,"151":0,"152":1,"153":1,"154":0,"155":0,"156":1,"157":1,"158":0,"159":0,"160":1,"161":1,"162":0,"163":0,"164":1,"165":1,"166":0,"167":0,"168":0,"169":0,"170":0,"171":0,"172":0,"173":0,"174":0,"175":0,"176":0,"177":0,"178":0,"179":0,"180":0,"181":0,"182":0,"183":0,"184":0,"185":0,"186":1,"187":1,"188":0,"189":0,"190":0,"191":0,"192":0,"193":0,"194":0,"195":0,"196":0,"197":0,"198":0,"199":0,"200":0,"201":0,"202":0,"203":1,"204":1,"205":0,"206":0,"207":0,"208":0,"209":0,"210":0,"211":0,"212":0,"213":0,"214":0,"215":0,"216":0,"217":1,"218":1,"219":0,"220":0,"221":0,"222":0,"223":0,"224":0,"225":0,"226":0,"227":0,"228":0,"229":0,"230":0,"231":0,"232":0,"233":0,"234":0,"235":0,"236":0,"237":0,"238":0,"239":0,"240":0,"241":1,"242":1,"243":0,"244":0,"245":0,"246":0,"247":0,"248":0,"249":0,"250":0,"251":0,"252":0,"253":0,"254":0,"255":0,"256":0,"257":0,"258":0,"259":0,"260":0,"261":0,"262":0,"263":0,"264":0,"265":0,"266":0,"267":0,"268":0,"269":0,"270":0,"271":0,"272":0,"273":1,"274":1,"275":0,"276":0,"277":0,"278":1,"279":1,"280":0,"281":0,"282":1,"283":1,"284":0,"285":0,"286":0,"287":0,"288":0,"289":0,"290":0,"291":0,"292":0,"293":0,"294":0,"295":0,"296":1,"297":1,"298":0,"299":0,"300":1,"301":1,"302":0,"303":0,"304":1,"305":1,"306":0,"307":0,"308":1,"309":1,"310":0,"311":0,"312":0,"313":1,"314":1,"315":0,"316":0,"317":1,"318":1,"319":0,"320":0,"321":1,"322":1,"323":0,"324":0,"325":1,"326":1,"327":0,"328":0,"329":0,"330":0,"331":0,"332":0,"333":0,"334":0,"335":0,"336":0,"337":1,"338":1,"339":0,"340":0,"341":1,"342":1,"343":0,"344":0,"345":1,"346":1,"347":0,"348":0,"349":1,"350":1,"351":0,"352":0,"353":1,"354":1,"355":0,"356":0,"357":0,"358":0,"359":0,"360":0,"361":1,"362":1,"363":1},"branchMap":{},"b":{},"fnMap":{"0":{"name":"Client","decl":{"start":{"line":35,"column":2},"end":{"line":63,"column":3}},"loc":{"start":{"line":35,"column":2},"end":{"line":63,"column":3}},"line":35},"1":{"name":"get config","decl":{"start":{"line":31,"column":2},"end":{"line":33,"column":3}},"loc":{"start":{"line":31,"column":2},"end":{"line":33,"column":3}},"line":31},"2":{"name":"init","decl":{"start":{"line":65,"column":2},"end":{"line":69,"column":3}},"loc":{"start":{"line":65,"column":2},"end":{"line":69,"column":3}},"line":65},"3":{"name":"flushEvents","decl":{"start":{"line":71,"column":2},"end":{"line":120,"column":3}},"loc":{"start":{"line":71,"column":2},"end":{"line":120,"column":3}},"line":71},"4":{"name":"syncFlushEvents","decl":{"start":{"line":122,"column":10},"end":{"line":152,"column":3}},"loc":{"start":{"line":122,"column":10},"end":{"line":152,"column":3}},"line":122},"5":{"name":"on","decl":{"start":{"line":154,"column":2},"end":{"line":156,"column":3}},"loc":{"start":{"line":154,"column":2},"end":{"line":156,"column":3}},"line":154},"6":{"name":"off","decl":{"start":{"line":158,"column":2},"end":{"line":160,"column":3}},"loc":{"start":{"line":158,"column":2},"end":{"line":160,"column":3}},"line":158},"7":{"name":"emit","decl":{"start":{"line":162,"column":2},"end":{"line":164,"column":3}},"loc":{"start":{"line":162,"column":2},"end":{"line":164,"column":3}},"line":162},"8":{"name":"captureException","decl":{"start":{"line":166,"column":2},"end":{"line":186,"column":3}},"loc":{"start":{"line":166,"column":2},"end":{"line":186,"column":3}},"line":166},"9":{"name":"captureMessage","decl":{"start":{"line":188,"column":2},"end":{"line":203,"column":3}},"loc":{"start":{"line":188,"column":2},"end":{"line":203,"column":3}},"line":188},"10":{"name":"captureEvent","decl":{"start":{"line":205,"column":2},"end":{"line":217,"column":3}},"loc":{"start":{"line":205,"column":2},"end":{"line":217,"column":3}},"line":205},"11":{"name":"attachTraceContext","decl":{"start":{"line":219,"column":10},"end":{"line":241,"column":3}},"loc":{"start":{"line":219,"column":10},"end":{"line":241,"column":3}},"line":219},"12":{"name":"buildErrorEvent","decl":{"start":{"line":243,"column":10},"end":{"line":273,"column":3}},"loc":{"start":{"line":243,"column":10},"end":{"line":273,"column":3}},"line":243},"13":{"name":"setUser","decl":{"start":{"line":275,"column":2},"end":{"line":278,"column":3}},"loc":{"start":{"line":275,"column":2},"end":{"line":278,"column":3}},"line":275},"14":{"name":"setAnonymousId","decl":{"start":{"line":280,"column":2},"end":{"line":282,"column":3}},"loc":{"start":{"line":280,"column":2},"end":{"line":282,"column":3}},"line":280},"15":{"name":"startTransaction","decl":{"start":{"line":284,"column":2},"end":{"line":296,"column":3}},"loc":{"start":{"line":284,"column":2},"end":{"line":296,"column":3}},"line":284},"16":{"name":"getCurrentTransaction","decl":{"start":{"line":298,"column":2},"end":{"line":300,"column":3}},"loc":{"start":{"line":298,"column":2},"end":{"line":300,"column":3}},"line":298},"17":{"name":"getCurrentSpan","decl":{"start":{"line":302,"column":2},"end":{"line":304,"column":3}},"loc":{"start":{"line":302,"column":2},"end":{"line":304,"column":3}},"line":302},"18":{"name":"setSpan","decl":{"start":{"line":306,"column":2},"end":{"line":308,"column":3}},"loc":{"start":{"line":306,"column":2},"end":{"line":308,"column":3}},"line":306},"19":{"name":"startSpan","decl":{"start":{"line":310,"column":2},"end":{"line":313,"column":3}},"loc":{"start":{"line":310,"column":2},"end":{"line":313,"column":3}},"line":310},"20":{"name":"setTag","decl":{"start":{"line":315,"column":2},"end":{"line":317,"column":3}},"loc":{"start":{"line":315,"column":2},"end":{"line":317,"column":3}},"line":315},"21":{"name":"setTags","decl":{"start":{"line":319,"column":2},"end":{"line":321,"column":3}},"loc":{"start":{"line":319,"column":2},"end":{"line":321,"column":3}},"line":319},"22":{"name":"setExtra","decl":{"start":{"line":323,"column":2},"end":{"line":325,"column":3}},"loc":{"start":{"line":323,"column":2},"end":{"line":325,"column":3}},"line":323},"23":{"name":"addBreadcrumb","decl":{"start":{"line":327,"column":2},"end":{"line":337,"column":3}},"loc":{"start":{"line":327,"column":2},"end":{"line":337,"column":3}},"line":327},"24":{"name":"flush","decl":{"start":{"line":339,"column":2},"end":{"line":341,"column":3}},"loc":{"start":{"line":339,"column":2},"end":{"line":341,"column":3}},"line":339},"25":{"name":"disable","decl":{"start":{"line":343,"column":2},"end":{"line":345,"column":3}},"loc":{"start":{"line":343,"column":2},"end":{"line":345,"column":3}},"line":343},"26":{"name":"enable","decl":{"start":{"line":347,"column":2},"end":{"line":349,"column":3}},"loc":{"start":{"line":347,"column":2},"end":{"line":349,"column":3}},"line":347},"27":{"name":"use","decl":{"start":{"line":351,"column":2},"end":{"line":353,"column":3}},"loc":{"start":{"line":351,"column":2},"end":{"line":353,"column":3}},"line":351},"28":{"name":"destroy","decl":{"start":{"line":355,"column":2},"end":{"line":361,"column":3}},"loc":{"start":{"line":355,"column":2},"end":{"line":361,"column":3}},"line":355}},"f":{"0":0,"1":0,"2":0,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10":0,"11":0,"12":0,"13":0,"14":0,"15":0,"16":0,"17":0,"18":0,"19":0,"20":0,"21":0,"22":0,"23":0,"24":0,"25":0,"26":0,"27":0,"28":0}} +,"/Users/weidingjian/Desktop/work/ai/light-sentry-sdk/src/core/ConfigManager.ts": {"path":"/Users/weidingjian/Desktop/work/ai/light-sentry-sdk/src/core/ConfigManager.ts","all":false,"statementMap":{"0":{"start":{"line":1,"column":0},"end":{"line":1,"column":132}},"1":{"start":{"line":2,"column":0},"end":{"line":2,"column":82}},"2":{"start":{"line":3,"column":0},"end":{"line":3,"column":48}},"3":{"start":{"line":4,"column":0},"end":{"line":4,"column":79}},"4":{"start":{"line":5,"column":0},"end":{"line":5,"column":0}},"5":{"start":{"line":6,"column":0},"end":{"line":6,"column":46}},"6":{"start":{"line":7,"column":0},"end":{"line":7,"column":16}},"7":{"start":{"line":8,"column":0},"end":{"line":8,"column":16}},"8":{"start":{"line":9,"column":0},"end":{"line":9,"column":20}},"9":{"start":{"line":10,"column":0},"end":{"line":10,"column":22}},"10":{"start":{"line":11,"column":0},"end":{"line":11,"column":16}},"11":{"start":{"line":12,"column":0},"end":{"line":12,"column":19}},"12":{"start":{"line":13,"column":0},"end":{"line":13,"column":28}},"13":{"start":{"line":14,"column":0},"end":{"line":14,"column":40}},"14":{"start":{"line":15,"column":0},"end":{"line":15,"column":17}},"15":{"start":{"line":16,"column":0},"end":{"line":16,"column":53}},"16":{"start":{"line":17,"column":0},"end":{"line":17,"column":53}},"17":{"start":{"line":18,"column":0},"end":{"line":18,"column":54}},"18":{"start":{"line":19,"column":0},"end":{"line":19,"column":51}},"19":{"start":{"line":20,"column":0},"end":{"line":20,"column":52}},"20":{"start":{"line":21,"column":0},"end":{"line":21,"column":4}},"21":{"start":{"line":22,"column":0},"end":{"line":22,"column":2}},"22":{"start":{"line":23,"column":0},"end":{"line":23,"column":0}},"23":{"start":{"line":24,"column":0},"end":{"line":24,"column":28}},"24":{"start":{"line":25,"column":0},"end":{"line":25,"column":30}},"25":{"start":{"line":26,"column":0},"end":{"line":26,"column":65}},"26":{"start":{"line":27,"column":0},"end":{"line":27,"column":42}},"27":{"start":{"line":28,"column":0},"end":{"line":28,"column":43}},"28":{"start":{"line":29,"column":0},"end":{"line":29,"column":0}},"29":{"start":{"line":30,"column":0},"end":{"line":30,"column":36}},"30":{"start":{"line":31,"column":0},"end":{"line":31,"column":66}},"31":{"start":{"line":32,"column":0},"end":{"line":32,"column":3}},"32":{"start":{"line":33,"column":0},"end":{"line":33,"column":0}},"33":{"start":{"line":34,"column":0},"end":{"line":34,"column":31}},"34":{"start":{"line":35,"column":0},"end":{"line":35,"column":32}},"35":{"start":{"line":36,"column":0},"end":{"line":36,"column":3}},"36":{"start":{"line":37,"column":0},"end":{"line":37,"column":0}},"37":{"start":{"line":38,"column":0},"end":{"line":38,"column":60}},"38":{"start":{"line":39,"column":0},"end":{"line":39,"column":28}},"39":{"start":{"line":40,"column":0},"end":{"line":40,"column":3}},"40":{"start":{"line":41,"column":0},"end":{"line":41,"column":0}},"41":{"start":{"line":42,"column":0},"end":{"line":42,"column":25}},"42":{"start":{"line":43,"column":0},"end":{"line":43,"column":30}},"43":{"start":{"line":44,"column":0},"end":{"line":44,"column":3}},"44":{"start":{"line":45,"column":0},"end":{"line":45,"column":0}},"45":{"start":{"line":46,"column":0},"end":{"line":46,"column":73}},"46":{"start":{"line":47,"column":0},"end":{"line":47,"column":29}},"47":{"start":{"line":48,"column":0},"end":{"line":48,"column":3}},"48":{"start":{"line":49,"column":0},"end":{"line":49,"column":0}},"49":{"start":{"line":50,"column":0},"end":{"line":50,"column":40}},"50":{"start":{"line":51,"column":0},"end":{"line":51,"column":41}},"51":{"start":{"line":52,"column":0},"end":{"line":52,"column":3}},"52":{"start":{"line":53,"column":0},"end":{"line":53,"column":0}},"53":{"start":{"line":54,"column":0},"end":{"line":54,"column":47}},"54":{"start":{"line":55,"column":0},"end":{"line":55,"column":64}},"55":{"start":{"line":56,"column":0},"end":{"line":56,"column":3}},"56":{"start":{"line":57,"column":0},"end":{"line":57,"column":0}},"57":{"start":{"line":58,"column":0},"end":{"line":58,"column":44}},"58":{"start":{"line":59,"column":0},"end":{"line":59,"column":28}},"59":{"start":{"line":60,"column":0},"end":{"line":60,"column":28}},"60":{"start":{"line":61,"column":0},"end":{"line":61,"column":5}},"61":{"start":{"line":62,"column":0},"end":{"line":62,"column":62}},"62":{"start":{"line":63,"column":0},"end":{"line":63,"column":3}},"63":{"start":{"line":64,"column":0},"end":{"line":64,"column":0}},"64":{"start":{"line":65,"column":0},"end":{"line":65,"column":47}},"65":{"start":{"line":66,"column":0},"end":{"line":66,"column":29}},"66":{"start":{"line":67,"column":0},"end":{"line":67,"column":29}},"67":{"start":{"line":68,"column":0},"end":{"line":68,"column":5}},"68":{"start":{"line":69,"column":0},"end":{"line":69,"column":64}},"69":{"start":{"line":70,"column":0},"end":{"line":70,"column":3}},"70":{"start":{"line":71,"column":0},"end":{"line":71,"column":0}},"71":{"start":{"line":72,"column":0},"end":{"line":72,"column":44}},"72":{"start":{"line":73,"column":0},"end":{"line":73,"column":66}},"73":{"start":{"line":74,"column":0},"end":{"line":74,"column":3}},"74":{"start":{"line":75,"column":0},"end":{"line":75,"column":0}},"75":{"start":{"line":76,"column":0},"end":{"line":76,"column":27}},"76":{"start":{"line":77,"column":0},"end":{"line":77,"column":45}},"77":{"start":{"line":78,"column":0},"end":{"line":78,"column":31}},"78":{"start":{"line":79,"column":0},"end":{"line":79,"column":32}},"79":{"start":{"line":80,"column":0},"end":{"line":80,"column":32}},"80":{"start":{"line":81,"column":0},"end":{"line":81,"column":3}},"81":{"start":{"line":82,"column":0},"end":{"line":82,"column":0}},"82":{"start":{"line":83,"column":0},"end":{"line":83,"column":5}},"83":{"start":{"line":84,"column":0},"end":{"line":84,"column":32}},"84":{"start":{"line":85,"column":0},"end":{"line":85,"column":39}},"85":{"start":{"line":86,"column":0},"end":{"line":86,"column":5}},"86":{"start":{"line":87,"column":0},"end":{"line":87,"column":63}},"87":{"start":{"line":88,"column":0},"end":{"line":88,"column":25}},"88":{"start":{"line":89,"column":0},"end":{"line":89,"column":36}},"89":{"start":{"line":90,"column":0},"end":{"line":90,"column":5}},"90":{"start":{"line":91,"column":0},"end":{"line":91,"column":25}},"91":{"start":{"line":92,"column":0},"end":{"line":92,"column":3}},"92":{"start":{"line":93,"column":0},"end":{"line":93,"column":0}},"93":{"start":{"line":94,"column":0},"end":{"line":94,"column":5}},"94":{"start":{"line":95,"column":0},"end":{"line":95,"column":13}},"95":{"start":{"line":96,"column":0},"end":{"line":96,"column":22}},"96":{"start":{"line":97,"column":0},"end":{"line":97,"column":54}},"97":{"start":{"line":98,"column":0},"end":{"line":98,"column":5}},"98":{"start":{"line":99,"column":0},"end":{"line":99,"column":85}},"99":{"start":{"line":100,"column":0},"end":{"line":100,"column":27}},"100":{"start":{"line":101,"column":0},"end":{"line":101,"column":59}},"101":{"start":{"line":102,"column":0},"end":{"line":102,"column":0}},"102":{"start":{"line":103,"column":0},"end":{"line":103,"column":14}},"103":{"start":{"line":104,"column":0},"end":{"line":104,"column":21}},"104":{"start":{"line":105,"column":0},"end":{"line":105,"column":40}},"105":{"start":{"line":106,"column":0},"end":{"line":106,"column":5}},"106":{"start":{"line":107,"column":0},"end":{"line":107,"column":0}},"107":{"start":{"line":108,"column":0},"end":{"line":108,"column":17}},"108":{"start":{"line":109,"column":0},"end":{"line":109,"column":24}},"109":{"start":{"line":110,"column":0},"end":{"line":110,"column":46}},"110":{"start":{"line":111,"column":0},"end":{"line":111,"column":5}},"111":{"start":{"line":112,"column":0},"end":{"line":112,"column":0}},"112":{"start":{"line":113,"column":0},"end":{"line":113,"column":32}},"113":{"start":{"line":114,"column":0},"end":{"line":114,"column":50}},"114":{"start":{"line":115,"column":0},"end":{"line":115,"column":34}},"115":{"start":{"line":116,"column":0},"end":{"line":116,"column":28}},"116":{"start":{"line":117,"column":0},"end":{"line":117,"column":15}},"117":{"start":{"line":118,"column":0},"end":{"line":118,"column":38}},"118":{"start":{"line":119,"column":0},"end":{"line":119,"column":28}},"119":{"start":{"line":120,"column":0},"end":{"line":120,"column":111}},"120":{"start":{"line":121,"column":0},"end":{"line":121,"column":22}},"121":{"start":{"line":122,"column":0},"end":{"line":122,"column":8}},"122":{"start":{"line":123,"column":0},"end":{"line":123,"column":5}},"123":{"start":{"line":124,"column":0},"end":{"line":124,"column":0}},"124":{"start":{"line":125,"column":0},"end":{"line":125,"column":21}},"125":{"start":{"line":126,"column":0},"end":{"line":126,"column":28}},"126":{"start":{"line":127,"column":0},"end":{"line":127,"column":82}},"127":{"start":{"line":128,"column":0},"end":{"line":128,"column":5}},"128":{"start":{"line":129,"column":0},"end":{"line":129,"column":0}},"129":{"start":{"line":130,"column":0},"end":{"line":130,"column":14}},"130":{"start":{"line":131,"column":0},"end":{"line":131,"column":21}},"131":{"start":{"line":132,"column":0},"end":{"line":132,"column":40}},"132":{"start":{"line":133,"column":0},"end":{"line":133,"column":5}},"133":{"start":{"line":134,"column":0},"end":{"line":134,"column":0}},"134":{"start":{"line":135,"column":0},"end":{"line":135,"column":18}},"135":{"start":{"line":136,"column":0},"end":{"line":136,"column":25}},"136":{"start":{"line":137,"column":0},"end":{"line":137,"column":48}},"137":{"start":{"line":138,"column":0},"end":{"line":138,"column":5}},"138":{"start":{"line":139,"column":0},"end":{"line":139,"column":0}},"139":{"start":{"line":140,"column":0},"end":{"line":140,"column":30}},"140":{"start":{"line":141,"column":0},"end":{"line":141,"column":45}},"141":{"start":{"line":142,"column":0},"end":{"line":142,"column":5}},"142":{"start":{"line":143,"column":0},"end":{"line":143,"column":34}},"143":{"start":{"line":144,"column":0},"end":{"line":144,"column":53}},"144":{"start":{"line":145,"column":0},"end":{"line":145,"column":5}},"145":{"start":{"line":146,"column":0},"end":{"line":146,"column":37}},"146":{"start":{"line":147,"column":0},"end":{"line":147,"column":27}},"147":{"start":{"line":148,"column":0},"end":{"line":148,"column":39}},"148":{"start":{"line":149,"column":0},"end":{"line":149,"column":5}},"149":{"start":{"line":150,"column":0},"end":{"line":150,"column":27}},"150":{"start":{"line":151,"column":0},"end":{"line":151,"column":95}},"151":{"start":{"line":152,"column":0},"end":{"line":152,"column":5}},"152":{"start":{"line":153,"column":0},"end":{"line":153,"column":0}},"153":{"start":{"line":154,"column":0},"end":{"line":154,"column":28}},"154":{"start":{"line":155,"column":0},"end":{"line":155,"column":26}},"155":{"start":{"line":156,"column":0},"end":{"line":156,"column":26}},"156":{"start":{"line":157,"column":0},"end":{"line":157,"column":32}},"157":{"start":{"line":158,"column":0},"end":{"line":158,"column":8}},"158":{"start":{"line":159,"column":0},"end":{"line":159,"column":68}},"159":{"start":{"line":160,"column":0},"end":{"line":160,"column":71}},"160":{"start":{"line":161,"column":0},"end":{"line":161,"column":5}},"161":{"start":{"line":162,"column":0},"end":{"line":162,"column":0}},"162":{"start":{"line":163,"column":0},"end":{"line":163,"column":26}},"163":{"start":{"line":164,"column":0},"end":{"line":164,"column":38}},"164":{"start":{"line":165,"column":0},"end":{"line":165,"column":5}},"165":{"start":{"line":166,"column":0},"end":{"line":166,"column":41}},"166":{"start":{"line":167,"column":0},"end":{"line":167,"column":0}},"167":{"start":{"line":168,"column":0},"end":{"line":168,"column":15}},"168":{"start":{"line":169,"column":0},"end":{"line":169,"column":48}},"169":{"start":{"line":170,"column":0},"end":{"line":170,"column":90}},"170":{"start":{"line":171,"column":0},"end":{"line":171,"column":64}},"171":{"start":{"line":172,"column":0},"end":{"line":172,"column":43}},"172":{"start":{"line":173,"column":0},"end":{"line":173,"column":24}},"173":{"start":{"line":174,"column":0},"end":{"line":174,"column":43}},"174":{"start":{"line":175,"column":0},"end":{"line":175,"column":7}},"175":{"start":{"line":176,"column":0},"end":{"line":176,"column":5}},"176":{"start":{"line":177,"column":0},"end":{"line":177,"column":0}},"177":{"start":{"line":178,"column":0},"end":{"line":178,"column":52}},"178":{"start":{"line":179,"column":0},"end":{"line":179,"column":0}},"179":{"start":{"line":180,"column":0},"end":{"line":180,"column":54}},"180":{"start":{"line":181,"column":0},"end":{"line":181,"column":27}},"181":{"start":{"line":182,"column":0},"end":{"line":182,"column":38}},"182":{"start":{"line":183,"column":0},"end":{"line":183,"column":7}},"183":{"start":{"line":184,"column":0},"end":{"line":184,"column":67}},"184":{"start":{"line":185,"column":0},"end":{"line":185,"column":49}},"185":{"start":{"line":186,"column":0},"end":{"line":186,"column":39}},"186":{"start":{"line":187,"column":0},"end":{"line":187,"column":43}},"187":{"start":{"line":188,"column":0},"end":{"line":188,"column":35}},"188":{"start":{"line":189,"column":0},"end":{"line":189,"column":39}},"189":{"start":{"line":190,"column":0},"end":{"line":190,"column":8}},"190":{"start":{"line":191,"column":0},"end":{"line":191,"column":5}},"191":{"start":{"line":192,"column":0},"end":{"line":192,"column":0}},"192":{"start":{"line":193,"column":0},"end":{"line":193,"column":44}},"193":{"start":{"line":194,"column":0},"end":{"line":194,"column":3}},"194":{"start":{"line":195,"column":0},"end":{"line":195,"column":0}},"195":{"start":{"line":196,"column":0},"end":{"line":196,"column":5}},"196":{"start":{"line":197,"column":0},"end":{"line":197,"column":38}},"197":{"start":{"line":198,"column":0},"end":{"line":198,"column":34}},"198":{"start":{"line":199,"column":0},"end":{"line":199,"column":5}},"199":{"start":{"line":200,"column":0},"end":{"line":200,"column":86}},"200":{"start":{"line":201,"column":0},"end":{"line":201,"column":81}},"201":{"start":{"line":202,"column":0},"end":{"line":202,"column":36}},"202":{"start":{"line":203,"column":0},"end":{"line":203,"column":0}},"203":{"start":{"line":204,"column":0},"end":{"line":204,"column":57}},"204":{"start":{"line":205,"column":0},"end":{"line":205,"column":69}},"205":{"start":{"line":206,"column":0},"end":{"line":206,"column":0}},"206":{"start":{"line":207,"column":0},"end":{"line":207,"column":16}},"207":{"start":{"line":208,"column":0},"end":{"line":208,"column":59}},"208":{"start":{"line":209,"column":0},"end":{"line":209,"column":0}},"209":{"start":{"line":210,"column":0},"end":{"line":210,"column":35}},"210":{"start":{"line":211,"column":0},"end":{"line":211,"column":89}},"211":{"start":{"line":212,"column":0},"end":{"line":212,"column":61}},"212":{"start":{"line":213,"column":0},"end":{"line":213,"column":65}},"213":{"start":{"line":214,"column":0},"end":{"line":214,"column":61}},"214":{"start":{"line":215,"column":0},"end":{"line":215,"column":39}},"215":{"start":{"line":216,"column":0},"end":{"line":216,"column":49}},"216":{"start":{"line":217,"column":0},"end":{"line":217,"column":33}},"217":{"start":{"line":218,"column":0},"end":{"line":218,"column":38}},"218":{"start":{"line":219,"column":0},"end":{"line":219,"column":18}},"219":{"start":{"line":220,"column":0},"end":{"line":220,"column":34}},"220":{"start":{"line":221,"column":0},"end":{"line":221,"column":21}},"221":{"start":{"line":222,"column":0},"end":{"line":222,"column":27}},"222":{"start":{"line":223,"column":0},"end":{"line":223,"column":22}},"223":{"start":{"line":224,"column":0},"end":{"line":224,"column":89}},"224":{"start":{"line":225,"column":0},"end":{"line":225,"column":16}},"225":{"start":{"line":226,"column":0},"end":{"line":226,"column":14}},"226":{"start":{"line":227,"column":0},"end":{"line":227,"column":11}},"227":{"start":{"line":228,"column":0},"end":{"line":228,"column":9}},"228":{"start":{"line":229,"column":0},"end":{"line":229,"column":7}},"229":{"start":{"line":230,"column":0},"end":{"line":230,"column":5}},"230":{"start":{"line":231,"column":0},"end":{"line":231,"column":0}},"231":{"start":{"line":232,"column":0},"end":{"line":232,"column":21}},"232":{"start":{"line":233,"column":0},"end":{"line":233,"column":64}},"233":{"start":{"line":234,"column":0},"end":{"line":234,"column":45}},"234":{"start":{"line":235,"column":0},"end":{"line":235,"column":39}},"235":{"start":{"line":236,"column":0},"end":{"line":236,"column":36}},"236":{"start":{"line":237,"column":0},"end":{"line":237,"column":14}},"237":{"start":{"line":238,"column":0},"end":{"line":238,"column":102}},"238":{"start":{"line":239,"column":0},"end":{"line":239,"column":7}},"239":{"start":{"line":240,"column":0},"end":{"line":240,"column":5}},"240":{"start":{"line":241,"column":0},"end":{"line":241,"column":0}},"241":{"start":{"line":242,"column":0},"end":{"line":242,"column":20}},"242":{"start":{"line":243,"column":0},"end":{"line":243,"column":3}},"243":{"start":{"line":244,"column":0},"end":{"line":244,"column":1}}},"s":{"0":1,"1":1,"2":1,"3":1,"4":1,"5":1,"6":1,"7":1,"8":1,"9":1,"10":1,"11":1,"12":1,"13":1,"14":1,"15":1,"16":1,"17":1,"18":1,"19":1,"20":1,"21":1,"22":1,"23":1,"24":1,"25":1,"26":1,"27":1,"28":1,"29":1,"30":40,"31":40,"32":1,"33":1,"34":1,"35":1,"36":1,"37":1,"38":10,"39":10,"40":1,"41":1,"42":4,"43":4,"44":1,"45":1,"46":1,"47":1,"48":1,"49":1,"50":3,"51":3,"52":1,"53":1,"54":2,"55":2,"56":1,"57":1,"58":3,"59":3,"60":3,"61":3,"62":3,"63":1,"64":1,"65":2,"66":2,"67":2,"68":2,"69":2,"70":1,"71":1,"72":4,"73":4,"74":1,"75":1,"76":2,"77":2,"78":1,"79":0,"80":2,"81":1,"82":1,"83":1,"84":1,"85":1,"86":1,"87":0,"88":0,"89":0,"90":0,"91":0,"92":1,"93":1,"94":1,"95":1,"96":1,"97":1,"98":1,"99":21,"100":21,"101":21,"102":21,"103":21,"104":1,"105":1,"106":21,"107":21,"108":21,"109":1,"110":1,"111":21,"112":21,"113":21,"114":3,"115":3,"116":3,"117":3,"118":3,"119":3,"120":3,"121":3,"122":3,"123":21,"124":21,"125":21,"126":3,"127":3,"128":21,"129":21,"130":21,"131":1,"132":1,"133":21,"134":21,"135":21,"136":0,"137":0,"138":21,"139":21,"140":8,"141":8,"142":21,"143":21,"144":21,"145":21,"146":21,"147":9,"148":9,"149":21,"150":8,"151":8,"152":21,"153":21,"154":20,"155":20,"156":20,"157":20,"158":21,"159":0,"160":0,"161":21,"162":21,"163":21,"164":21,"165":21,"166":21,"167":21,"168":21,"169":21,"170":21,"171":10,"172":10,"173":10,"174":10,"175":10,"176":21,"177":21,"178":21,"179":21,"180":20,"181":20,"182":20,"183":20,"184":20,"185":20,"186":20,"187":20,"188":20,"189":20,"190":20,"191":21,"192":21,"193":21,"194":1,"195":1,"196":1,"197":1,"198":1,"199":1,"200":21,"201":21,"202":21,"203":21,"204":21,"205":21,"206":21,"207":21,"208":21,"209":21,"210":21,"211":3,"212":3,"213":3,"214":3,"215":3,"216":1,"217":1,"218":3,"219":2,"220":2,"221":2,"222":2,"223":2,"224":2,"225":2,"226":2,"227":3,"228":3,"229":3,"230":21,"231":21,"232":21,"233":3,"234":1,"235":1,"236":3,"237":2,"238":2,"239":3,"240":21,"241":21,"242":21,"243":1},"branchMap":{"0":{"type":"branch","line":30,"loc":{"start":{"line":30,"column":2},"end":{"line":32,"column":3}},"locations":[{"start":{"line":30,"column":2},"end":{"line":32,"column":3}}]},"1":{"type":"branch","line":34,"loc":{"start":{"line":34,"column":2},"end":{"line":36,"column":3}},"locations":[{"start":{"line":34,"column":2},"end":{"line":36,"column":3}}]},"2":{"type":"branch","line":38,"loc":{"start":{"line":38,"column":2},"end":{"line":40,"column":3}},"locations":[{"start":{"line":38,"column":2},"end":{"line":40,"column":3}}]},"3":{"type":"branch","line":42,"loc":{"start":{"line":42,"column":2},"end":{"line":44,"column":3}},"locations":[{"start":{"line":42,"column":2},"end":{"line":44,"column":3}}]},"4":{"type":"branch","line":46,"loc":{"start":{"line":46,"column":2},"end":{"line":48,"column":3}},"locations":[{"start":{"line":46,"column":2},"end":{"line":48,"column":3}}]},"5":{"type":"branch","line":50,"loc":{"start":{"line":50,"column":2},"end":{"line":52,"column":3}},"locations":[{"start":{"line":50,"column":2},"end":{"line":52,"column":3}}]},"6":{"type":"branch","line":51,"loc":{"start":{"line":51,"column":23},"end":{"line":51,"column":41}},"locations":[{"start":{"line":51,"column":23},"end":{"line":51,"column":41}}]},"7":{"type":"branch","line":54,"loc":{"start":{"line":54,"column":2},"end":{"line":56,"column":3}},"locations":[{"start":{"line":54,"column":2},"end":{"line":56,"column":3}}]},"8":{"type":"branch","line":55,"loc":{"start":{"line":55,"column":41},"end":{"line":55,"column":54}},"locations":[{"start":{"line":55,"column":41},"end":{"line":55,"column":54}}]},"9":{"type":"branch","line":58,"loc":{"start":{"line":58,"column":2},"end":{"line":63,"column":3}},"locations":[{"start":{"line":58,"column":2},"end":{"line":63,"column":3}}]},"10":{"type":"branch","line":65,"loc":{"start":{"line":65,"column":2},"end":{"line":70,"column":3}},"locations":[{"start":{"line":65,"column":2},"end":{"line":70,"column":3}}]},"11":{"type":"branch","line":72,"loc":{"start":{"line":72,"column":2},"end":{"line":74,"column":3}},"locations":[{"start":{"line":72,"column":2},"end":{"line":74,"column":3}}]},"12":{"type":"branch","line":73,"loc":{"start":{"line":73,"column":46},"end":{"line":73,"column":64}},"locations":[{"start":{"line":73,"column":46},"end":{"line":73,"column":64}}]},"13":{"type":"branch","line":76,"loc":{"start":{"line":76,"column":2},"end":{"line":81,"column":3}},"locations":[{"start":{"line":76,"column":2},"end":{"line":81,"column":3}}]},"14":{"type":"branch","line":77,"loc":{"start":{"line":77,"column":29},"end":{"line":77,"column":45}},"locations":[{"start":{"line":77,"column":29},"end":{"line":77,"column":45}}]},"15":{"type":"branch","line":78,"loc":{"start":{"line":78,"column":19},"end":{"line":79,"column":32}},"locations":[{"start":{"line":78,"column":19},"end":{"line":79,"column":32}}]},"16":{"type":"branch","line":79,"loc":{"start":{"line":79,"column":26},"end":{"line":80,"column":32}},"locations":[{"start":{"line":79,"column":26},"end":{"line":80,"column":32}}]},"17":{"type":"branch","line":99,"loc":{"start":{"line":99,"column":2},"end":{"line":194,"column":3}},"locations":[{"start":{"line":99,"column":2},"end":{"line":194,"column":3}}]},"18":{"type":"branch","line":104,"loc":{"start":{"line":104,"column":20},"end":{"line":106,"column":5}},"locations":[{"start":{"line":104,"column":20},"end":{"line":106,"column":5}}]},"19":{"type":"branch","line":109,"loc":{"start":{"line":109,"column":23},"end":{"line":111,"column":5}},"locations":[{"start":{"line":109,"column":23},"end":{"line":111,"column":5}}]},"20":{"type":"branch","line":114,"loc":{"start":{"line":114,"column":23},"end":{"line":114,"column":49}},"locations":[{"start":{"line":114,"column":23},"end":{"line":114,"column":49}}]},"21":{"type":"branch","line":114,"loc":{"start":{"line":114,"column":49},"end":{"line":123,"column":5}},"locations":[{"start":{"line":114,"column":49},"end":{"line":123,"column":5}}]},"22":{"type":"branch","line":120,"loc":{"start":{"line":120,"column":97},"end":{"line":120,"column":111}},"locations":[{"start":{"line":120,"column":97},"end":{"line":120,"column":111}}]},"23":{"type":"branch","line":121,"loc":{"start":{"line":121,"column":8},"end":{"line":121,"column":22}},"locations":[{"start":{"line":121,"column":8},"end":{"line":121,"column":22}}]},"24":{"type":"branch","line":126,"loc":{"start":{"line":126,"column":27},"end":{"line":128,"column":5}},"locations":[{"start":{"line":126,"column":27},"end":{"line":128,"column":5}}]},"25":{"type":"branch","line":131,"loc":{"start":{"line":131,"column":20},"end":{"line":133,"column":5}},"locations":[{"start":{"line":131,"column":20},"end":{"line":133,"column":5}}]},"26":{"type":"branch","line":136,"loc":{"start":{"line":136,"column":24},"end":{"line":138,"column":5}},"locations":[{"start":{"line":136,"column":24},"end":{"line":138,"column":5}}]},"27":{"type":"branch","line":140,"loc":{"start":{"line":140,"column":29},"end":{"line":142,"column":5}},"locations":[{"start":{"line":140,"column":29},"end":{"line":142,"column":5}}]},"28":{"type":"branch","line":147,"loc":{"start":{"line":147,"column":26},"end":{"line":149,"column":5}},"locations":[{"start":{"line":147,"column":26},"end":{"line":149,"column":5}}]},"29":{"type":"branch","line":150,"loc":{"start":{"line":150,"column":26},"end":{"line":152,"column":5}},"locations":[{"start":{"line":150,"column":26},"end":{"line":152,"column":5}}]},"30":{"type":"branch","line":151,"loc":{"start":{"line":151,"column":55},"end":{"line":151,"column":93}},"locations":[{"start":{"line":151,"column":55},"end":{"line":151,"column":93}}]},"31":{"type":"branch","line":154,"loc":{"start":{"line":154,"column":27},"end":{"line":159,"column":15}},"locations":[{"start":{"line":154,"column":27},"end":{"line":159,"column":15}}]},"32":{"type":"branch","line":159,"loc":{"start":{"line":159,"column":4},"end":{"line":161,"column":5}},"locations":[{"start":{"line":159,"column":4},"end":{"line":161,"column":5}}]},"33":{"type":"branch","line":159,"loc":{"start":{"line":159,"column":67},"end":{"line":161,"column":5}},"locations":[{"start":{"line":159,"column":67},"end":{"line":161,"column":5}}]},"34":{"type":"branch","line":170,"loc":{"start":{"line":170,"column":34},"end":{"line":170,"column":47}},"locations":[{"start":{"line":170,"column":34},"end":{"line":170,"column":47}}]},"35":{"type":"branch","line":170,"loc":{"start":{"line":170,"column":40},"end":{"line":170,"column":90}},"locations":[{"start":{"line":170,"column":40},"end":{"line":170,"column":90}}]},"36":{"type":"branch","line":170,"loc":{"start":{"line":170,"column":53},"end":{"line":170,"column":90}},"locations":[{"start":{"line":170,"column":53},"end":{"line":170,"column":90}}]},"37":{"type":"branch","line":171,"loc":{"start":{"line":171,"column":9},"end":{"line":171,"column":63}},"locations":[{"start":{"line":171,"column":9},"end":{"line":171,"column":63}}]},"38":{"type":"branch","line":171,"loc":{"start":{"line":171,"column":63},"end":{"line":176,"column":5}},"locations":[{"start":{"line":171,"column":63},"end":{"line":176,"column":5}}]},"39":{"type":"branch","line":180,"loc":{"start":{"line":180,"column":53},"end":{"line":191,"column":5}},"locations":[{"start":{"line":180,"column":53},"end":{"line":191,"column":5}}]},"40":{"type":"branch","line":120,"loc":{"start":{"line":120,"column":68},"end":{"line":120,"column":97}},"locations":[{"start":{"line":120,"column":68},"end":{"line":120,"column":97}}]},"41":{"type":"branch","line":127,"loc":{"start":{"line":127,"column":51},"end":{"line":127,"column":80}},"locations":[{"start":{"line":127,"column":51},"end":{"line":127,"column":80}}]},"42":{"type":"branch","line":200,"loc":{"start":{"line":200,"column":10},"end":{"line":243,"column":3}},"locations":[{"start":{"line":200,"column":10},"end":{"line":243,"column":3}}]},"43":{"type":"branch","line":202,"loc":{"start":{"line":202,"column":23},"end":{"line":202,"column":36}},"locations":[{"start":{"line":202,"column":23},"end":{"line":202,"column":36}}]},"44":{"type":"branch","line":204,"loc":{"start":{"line":204,"column":25},"end":{"line":204,"column":57}},"locations":[{"start":{"line":204,"column":25},"end":{"line":204,"column":57}}]},"45":{"type":"branch","line":205,"loc":{"start":{"line":205,"column":42},"end":{"line":205,"column":69}},"locations":[{"start":{"line":205,"column":42},"end":{"line":205,"column":69}}]},"46":{"type":"branch","line":211,"loc":{"start":{"line":211,"column":23},"end":{"line":211,"column":51}},"locations":[{"start":{"line":211,"column":23},"end":{"line":211,"column":51}}]},"47":{"type":"branch","line":211,"loc":{"start":{"line":211,"column":38},"end":{"line":211,"column":88}},"locations":[{"start":{"line":211,"column":38},"end":{"line":211,"column":88}}]},"48":{"type":"branch","line":211,"loc":{"start":{"line":211,"column":88},"end":{"line":230,"column":5}},"locations":[{"start":{"line":211,"column":88},"end":{"line":230,"column":5}}]},"49":{"type":"branch","line":216,"loc":{"start":{"line":216,"column":48},"end":{"line":219,"column":17}},"locations":[{"start":{"line":216,"column":48},"end":{"line":219,"column":17}}]},"50":{"type":"branch","line":219,"loc":{"start":{"line":219,"column":10},"end":{"line":227,"column":11}},"locations":[{"start":{"line":219,"column":10},"end":{"line":227,"column":11}}]},"51":{"type":"branch","line":233,"loc":{"start":{"line":233,"column":14},"end":{"line":233,"column":63}},"locations":[{"start":{"line":233,"column":14},"end":{"line":233,"column":63}}]},"52":{"type":"branch","line":233,"loc":{"start":{"line":233,"column":63},"end":{"line":240,"column":5}},"locations":[{"start":{"line":233,"column":63},"end":{"line":240,"column":5}}]},"53":{"type":"branch","line":234,"loc":{"start":{"line":234,"column":44},"end":{"line":237,"column":13}},"locations":[{"start":{"line":234,"column":44},"end":{"line":237,"column":13}}]},"54":{"type":"branch","line":237,"loc":{"start":{"line":237,"column":6},"end":{"line":239,"column":7}},"locations":[{"start":{"line":237,"column":6},"end":{"line":239,"column":7}}]}},"b":{"0":[40],"1":[1],"2":[10],"3":[4],"4":[1],"5":[3],"6":[1],"7":[2],"8":[1],"9":[3],"10":[2],"11":[4],"12":[0],"13":[2],"14":[0],"15":[1],"16":[0],"17":[21],"18":[1],"19":[1],"20":[3],"21":[3],"22":[0],"23":[0],"24":[3],"25":[1],"26":[0],"27":[8],"28":[9],"29":[8],"30":[7],"31":[20],"32":[1],"33":[0],"34":[9],"35":[12],"36":[1],"37":[11],"38":[10],"39":[20],"40":[21],"41":[41],"42":[21],"43":[0],"44":[0],"45":[0],"46":[3],"47":[3],"48":[3],"49":[1],"50":[2],"51":[3],"52":[3],"53":[1],"54":[2]},"fnMap":{"0":{"name":"ConfigManager","decl":{"start":{"line":30,"column":2},"end":{"line":32,"column":3}},"loc":{"start":{"line":30,"column":2},"end":{"line":32,"column":3}},"line":30},"1":{"name":"markContextReported","decl":{"start":{"line":34,"column":2},"end":{"line":36,"column":3}},"loc":{"start":{"line":34,"column":2},"end":{"line":36,"column":3}},"line":34},"2":{"name":"get","decl":{"start":{"line":38,"column":2},"end":{"line":40,"column":3}},"loc":{"start":{"line":38,"column":2},"end":{"line":40,"column":3}},"line":38},"3":{"name":"getAll","decl":{"start":{"line":42,"column":2},"end":{"line":44,"column":3}},"loc":{"start":{"line":42,"column":2},"end":{"line":44,"column":3}},"line":42},"4":{"name":"set","decl":{"start":{"line":46,"column":2},"end":{"line":48,"column":3}},"loc":{"start":{"line":46,"column":2},"end":{"line":48,"column":3}},"line":46},"5":{"name":"setUser","decl":{"start":{"line":50,"column":2},"end":{"line":52,"column":3}},"loc":{"start":{"line":50,"column":2},"end":{"line":52,"column":3}},"line":50},"6":{"name":"setTags","decl":{"start":{"line":54,"column":2},"end":{"line":56,"column":3}},"loc":{"start":{"line":54,"column":2},"end":{"line":56,"column":3}},"line":54},"7":{"name":"setTag","decl":{"start":{"line":58,"column":2},"end":{"line":63,"column":3}},"loc":{"start":{"line":58,"column":2},"end":{"line":63,"column":3}},"line":58},"8":{"name":"setExtra","decl":{"start":{"line":65,"column":2},"end":{"line":70,"column":3}},"loc":{"start":{"line":65,"column":2},"end":{"line":70,"column":3}},"line":65},"9":{"name":"isIgnoredError","decl":{"start":{"line":72,"column":2},"end":{"line":74,"column":3}},"loc":{"start":{"line":72,"column":2},"end":{"line":74,"column":3}},"line":72},"10":{"name":"shouldSample","decl":{"start":{"line":76,"column":2},"end":{"line":81,"column":3}},"loc":{"start":{"line":76,"column":2},"end":{"line":81,"column":3}},"line":76},"11":{"name":"getEncodedContext","decl":{"start":{"line":87,"column":10},"end":{"line":92,"column":3}},"loc":{"start":{"line":87,"column":10},"end":{"line":92,"column":3}},"line":87},"12":{"name":"applyToEvent","decl":{"start":{"line":99,"column":2},"end":{"line":194,"column":3}},"loc":{"start":{"line":99,"column":2},"end":{"line":194,"column":3}},"line":99},"13":{"name":"applyContextLevel","decl":{"start":{"line":200,"column":10},"end":{"line":243,"column":3}},"loc":{"start":{"line":200,"column":10},"end":{"line":243,"column":3}},"line":200}},"f":{"0":40,"1":1,"2":10,"3":4,"4":1,"5":3,"6":2,"7":3,"8":2,"9":4,"10":2,"11":0,"12":21,"13":21}} +,"/Users/weidingjian/Desktop/work/ai/light-sentry-sdk/src/core/EventBus.ts": {"path":"/Users/weidingjian/Desktop/work/ai/light-sentry-sdk/src/core/EventBus.ts","all":false,"statementMap":{"0":{"start":{"line":1,"column":0},"end":{"line":1,"column":44}},"1":{"start":{"line":2,"column":0},"end":{"line":2,"column":0}},"2":{"start":{"line":3,"column":0},"end":{"line":3,"column":23}},"3":{"start":{"line":4,"column":0},"end":{"line":4,"column":55}},"4":{"start":{"line":5,"column":0},"end":{"line":5,"column":0}},"5":{"start":{"line":6,"column":0},"end":{"line":6,"column":45}},"6":{"start":{"line":7,"column":0},"end":{"line":7,"column":36}},"7":{"start":{"line":8,"column":0},"end":{"line":8,"column":35}},"8":{"start":{"line":9,"column":0},"end":{"line":9,"column":5}},"9":{"start":{"line":10,"column":0},"end":{"line":10,"column":44}},"10":{"start":{"line":11,"column":0},"end":{"line":11,"column":3}},"11":{"start":{"line":12,"column":0},"end":{"line":12,"column":0}},"12":{"start":{"line":13,"column":0},"end":{"line":13,"column":46}},"13":{"start":{"line":14,"column":0},"end":{"line":14,"column":51}},"14":{"start":{"line":15,"column":0},"end":{"line":15,"column":24}},"15":{"start":{"line":16,"column":0},"end":{"line":16,"column":51}},"16":{"start":{"line":17,"column":0},"end":{"line":17,"column":23}},"17":{"start":{"line":18,"column":0},"end":{"line":18,"column":39}},"18":{"start":{"line":19,"column":0},"end":{"line":19,"column":7}},"19":{"start":{"line":20,"column":0},"end":{"line":20,"column":5}},"20":{"start":{"line":21,"column":0},"end":{"line":21,"column":3}},"21":{"start":{"line":22,"column":0},"end":{"line":22,"column":0}},"22":{"start":{"line":23,"column":0},"end":{"line":23,"column":49}},"23":{"start":{"line":24,"column":0},"end":{"line":24,"column":51}},"24":{"start":{"line":25,"column":0},"end":{"line":25,"column":24}},"25":{"start":{"line":26,"column":0},"end":{"line":26,"column":44}},"26":{"start":{"line":27,"column":0},"end":{"line":27,"column":13}},"27":{"start":{"line":28,"column":0},"end":{"line":28,"column":27}},"28":{"start":{"line":29,"column":0},"end":{"line":29,"column":21}},"29":{"start":{"line":30,"column":0},"end":{"line":30,"column":65}},"30":{"start":{"line":31,"column":0},"end":{"line":31,"column":9}},"31":{"start":{"line":32,"column":0},"end":{"line":32,"column":7}},"32":{"start":{"line":33,"column":0},"end":{"line":33,"column":5}},"33":{"start":{"line":34,"column":0},"end":{"line":34,"column":3}},"34":{"start":{"line":35,"column":0},"end":{"line":35,"column":0}},"35":{"start":{"line":36,"column":0},"end":{"line":36,"column":47}},"36":{"start":{"line":37,"column":0},"end":{"line":37,"column":45}},"37":{"start":{"line":38,"column":0},"end":{"line":38,"column":31}},"38":{"start":{"line":39,"column":0},"end":{"line":39,"column":23}},"39":{"start":{"line":40,"column":0},"end":{"line":40,"column":6}},"40":{"start":{"line":41,"column":0},"end":{"line":41,"column":28}},"41":{"start":{"line":42,"column":0},"end":{"line":42,"column":3}},"42":{"start":{"line":43,"column":0},"end":{"line":43,"column":0}},"43":{"start":{"line":44,"column":0},"end":{"line":44,"column":19}},"44":{"start":{"line":45,"column":0},"end":{"line":45,"column":26}},"45":{"start":{"line":46,"column":0},"end":{"line":46,"column":3}},"46":{"start":{"line":47,"column":0},"end":{"line":47,"column":1}}},"s":{"0":1,"1":1,"2":1,"3":42,"4":1,"5":1,"6":21,"7":16,"8":16,"9":21,"10":21,"11":1,"12":1,"13":9,"14":9,"15":8,"16":8,"17":7,"18":7,"19":8,"20":9,"21":1,"22":1,"23":88,"24":88,"25":14,"26":15,"27":15,"28":15,"29":2,"30":2,"31":15,"32":14,"33":88,"34":1,"35":1,"36":5,"37":4,"38":4,"39":4,"40":5,"41":5,"42":1,"43":1,"44":3,"45":3,"46":1},"branchMap":{"0":{"type":"branch","line":3,"loc":{"start":{"line":3,"column":7},"end":{"line":4,"column":55}},"locations":[{"start":{"line":3,"column":7},"end":{"line":4,"column":55}}]},"1":{"type":"branch","line":6,"loc":{"start":{"line":6,"column":2},"end":{"line":11,"column":3}},"locations":[{"start":{"line":6,"column":2},"end":{"line":11,"column":3}}]},"2":{"type":"branch","line":7,"loc":{"start":{"line":7,"column":35},"end":{"line":9,"column":5}},"locations":[{"start":{"line":7,"column":35},"end":{"line":9,"column":5}}]},"3":{"type":"branch","line":13,"loc":{"start":{"line":13,"column":2},"end":{"line":21,"column":3}},"locations":[{"start":{"line":13,"column":2},"end":{"line":21,"column":3}}]},"4":{"type":"branch","line":15,"loc":{"start":{"line":15,"column":23},"end":{"line":20,"column":5}},"locations":[{"start":{"line":15,"column":23},"end":{"line":20,"column":5}}]},"5":{"type":"branch","line":17,"loc":{"start":{"line":17,"column":22},"end":{"line":19,"column":7}},"locations":[{"start":{"line":17,"column":22},"end":{"line":19,"column":7}}]},"6":{"type":"branch","line":23,"loc":{"start":{"line":23,"column":2},"end":{"line":34,"column":3}},"locations":[{"start":{"line":23,"column":2},"end":{"line":34,"column":3}}]},"7":{"type":"branch","line":25,"loc":{"start":{"line":25,"column":23},"end":{"line":33,"column":5}},"locations":[{"start":{"line":25,"column":23},"end":{"line":33,"column":5}}]},"8":{"type":"branch","line":26,"loc":{"start":{"line":26,"column":43},"end":{"line":32,"column":7}},"locations":[{"start":{"line":26,"column":43},"end":{"line":32,"column":7}}]},"9":{"type":"branch","line":29,"loc":{"start":{"line":29,"column":8},"end":{"line":31,"column":9}},"locations":[{"start":{"line":29,"column":8},"end":{"line":31,"column":9}}]},"10":{"type":"branch","line":36,"loc":{"start":{"line":36,"column":2},"end":{"line":42,"column":3}},"locations":[{"start":{"line":36,"column":2},"end":{"line":42,"column":3}}]},"11":{"type":"branch","line":37,"loc":{"start":{"line":37,"column":20},"end":{"line":40,"column":6}},"locations":[{"start":{"line":37,"column":20},"end":{"line":40,"column":6}}]},"12":{"type":"branch","line":44,"loc":{"start":{"line":44,"column":2},"end":{"line":46,"column":3}},"locations":[{"start":{"line":44,"column":2},"end":{"line":46,"column":3}}]}},"b":{"0":[42],"1":[21],"2":[16],"3":[9],"4":[8],"5":[7],"6":[88],"7":[14],"8":[15],"9":[2],"10":[5],"11":[4],"12":[3]},"fnMap":{"0":{"name":"EventBus","decl":{"start":{"line":3,"column":7},"end":{"line":4,"column":55}},"loc":{"start":{"line":3,"column":7},"end":{"line":4,"column":55}},"line":3},"1":{"name":"on","decl":{"start":{"line":6,"column":2},"end":{"line":11,"column":3}},"loc":{"start":{"line":6,"column":2},"end":{"line":11,"column":3}},"line":6},"2":{"name":"off","decl":{"start":{"line":13,"column":2},"end":{"line":21,"column":3}},"loc":{"start":{"line":13,"column":2},"end":{"line":21,"column":3}},"line":13},"3":{"name":"emit","decl":{"start":{"line":23,"column":2},"end":{"line":34,"column":3}},"loc":{"start":{"line":23,"column":2},"end":{"line":34,"column":3}},"line":23},"4":{"name":"once","decl":{"start":{"line":36,"column":2},"end":{"line":42,"column":3}},"loc":{"start":{"line":36,"column":2},"end":{"line":42,"column":3}},"line":36},"5":{"name":"wrapped","decl":{"start":{"line":37,"column":20},"end":{"line":40,"column":6}},"loc":{"start":{"line":37,"column":20},"end":{"line":40,"column":6}},"line":37},"6":{"name":"destroy","decl":{"start":{"line":44,"column":2},"end":{"line":46,"column":3}},"loc":{"start":{"line":44,"column":2},"end":{"line":46,"column":3}},"line":44}},"f":{"0":42,"1":21,"2":9,"3":88,"4":5,"5":4,"6":3}} +,"/Users/weidingjian/Desktop/work/ai/light-sentry-sdk/src/core/EventQueue.ts": {"path":"/Users/weidingjian/Desktop/work/ai/light-sentry-sdk/src/core/EventQueue.ts","all":false,"statementMap":{"0":{"start":{"line":1,"column":0},"end":{"line":1,"column":68}},"1":{"start":{"line":2,"column":0},"end":{"line":2,"column":38}},"2":{"start":{"line":3,"column":0},"end":{"line":3,"column":38}},"3":{"start":{"line":4,"column":0},"end":{"line":4,"column":43}},"4":{"start":{"line":5,"column":0},"end":{"line":5,"column":0}},"5":{"start":{"line":6,"column":0},"end":{"line":6,"column":23}},"6":{"start":{"line":7,"column":0},"end":{"line":7,"column":16}},"7":{"start":{"line":8,"column":0},"end":{"line":8,"column":19}},"8":{"start":{"line":9,"column":0},"end":{"line":9,"column":25}},"9":{"start":{"line":10,"column":0},"end":{"line":10,"column":1}},"10":{"start":{"line":11,"column":0},"end":{"line":11,"column":0}},"11":{"start":{"line":12,"column":0},"end":{"line":12,"column":25}},"12":{"start":{"line":13,"column":0},"end":{"line":13,"column":36}},"13":{"start":{"line":14,"column":0},"end":{"line":14,"column":26}},"14":{"start":{"line":15,"column":0},"end":{"line":15,"column":32}},"15":{"start":{"line":16,"column":0},"end":{"line":16,"column":61}},"16":{"start":{"line":17,"column":0},"end":{"line":17,"column":29}},"17":{"start":{"line":18,"column":0},"end":{"line":18,"column":66}},"18":{"start":{"line":19,"column":0},"end":{"line":19,"column":61}},"19":{"start":{"line":20,"column":0},"end":{"line":20,"column":36}},"20":{"start":{"line":21,"column":0},"end":{"line":21,"column":38}},"21":{"start":{"line":22,"column":0},"end":{"line":22,"column":42}},"22":{"start":{"line":23,"column":0},"end":{"line":23,"column":38}},"23":{"start":{"line":24,"column":0},"end":{"line":24,"column":34}},"24":{"start":{"line":25,"column":0},"end":{"line":25,"column":58}},"25":{"start":{"line":26,"column":0},"end":{"line":26,"column":102}},"26":{"start":{"line":27,"column":0},"end":{"line":27,"column":0}},"27":{"start":{"line":28,"column":0},"end":{"line":28,"column":60}},"28":{"start":{"line":29,"column":0},"end":{"line":29,"column":34}},"29":{"start":{"line":30,"column":0},"end":{"line":30,"column":66}},"30":{"start":{"line":31,"column":0},"end":{"line":31,"column":0}},"31":{"start":{"line":32,"column":0},"end":{"line":32,"column":14}},"32":{"start":{"line":33,"column":0},"end":{"line":33,"column":20}},"33":{"start":{"line":34,"column":0},"end":{"line":34,"column":26}},"34":{"start":{"line":35,"column":0},"end":{"line":35,"column":23}},"35":{"start":{"line":36,"column":0},"end":{"line":36,"column":60}},"36":{"start":{"line":37,"column":0},"end":{"line":37,"column":54}},"37":{"start":{"line":38,"column":0},"end":{"line":38,"column":5}},"38":{"start":{"line":39,"column":0},"end":{"line":39,"column":27}},"39":{"start":{"line":40,"column":0},"end":{"line":40,"column":39}},"40":{"start":{"line":41,"column":0},"end":{"line":41,"column":29}},"41":{"start":{"line":42,"column":0},"end":{"line":42,"column":39}},"42":{"start":{"line":43,"column":0},"end":{"line":43,"column":47}},"43":{"start":{"line":44,"column":0},"end":{"line":44,"column":3}},"44":{"start":{"line":45,"column":0},"end":{"line":45,"column":0}},"45":{"start":{"line":46,"column":0},"end":{"line":46,"column":17}},"46":{"start":{"line":47,"column":0},"end":{"line":47,"column":22}},"47":{"start":{"line":48,"column":0},"end":{"line":48,"column":35}},"48":{"start":{"line":49,"column":0},"end":{"line":49,"column":3}},"49":{"start":{"line":50,"column":0},"end":{"line":50,"column":0}},"50":{"start":{"line":51,"column":0},"end":{"line":51,"column":30}},"51":{"start":{"line":52,"column":0},"end":{"line":52,"column":27}},"52":{"start":{"line":53,"column":0},"end":{"line":53,"column":36}},"53":{"start":{"line":54,"column":0},"end":{"line":54,"column":65}},"54":{"start":{"line":55,"column":0},"end":{"line":55,"column":21}},"55":{"start":{"line":56,"column":0},"end":{"line":56,"column":7}},"56":{"start":{"line":57,"column":0},"end":{"line":57,"column":27}},"57":{"start":{"line":58,"column":0},"end":{"line":58,"column":3}},"58":{"start":{"line":59,"column":0},"end":{"line":59,"column":0}},"59":{"start":{"line":60,"column":0},"end":{"line":60,"column":43}},"60":{"start":{"line":61,"column":0},"end":{"line":61,"column":37}},"61":{"start":{"line":62,"column":0},"end":{"line":62,"column":86}},"62":{"start":{"line":63,"column":0},"end":{"line":63,"column":25}},"63":{"start":{"line":64,"column":0},"end":{"line":64,"column":7}},"64":{"start":{"line":65,"column":0},"end":{"line":65,"column":6}},"65":{"start":{"line":66,"column":0},"end":{"line":66,"column":42}},"66":{"start":{"line":67,"column":0},"end":{"line":67,"column":77}},"67":{"start":{"line":68,"column":0},"end":{"line":68,"column":5}},"68":{"start":{"line":69,"column":0},"end":{"line":69,"column":0}},"69":{"start":{"line":70,"column":0},"end":{"line":70,"column":33}},"70":{"start":{"line":71,"column":0},"end":{"line":71,"column":65}},"71":{"start":{"line":72,"column":0},"end":{"line":72,"column":25}},"72":{"start":{"line":73,"column":0},"end":{"line":73,"column":7}},"73":{"start":{"line":74,"column":0},"end":{"line":74,"column":6}},"74":{"start":{"line":75,"column":0},"end":{"line":75,"column":29}},"75":{"start":{"line":76,"column":0},"end":{"line":76,"column":65}},"76":{"start":{"line":77,"column":0},"end":{"line":77,"column":25}},"77":{"start":{"line":78,"column":0},"end":{"line":78,"column":7}},"78":{"start":{"line":79,"column":0},"end":{"line":79,"column":6}},"79":{"start":{"line":80,"column":0},"end":{"line":80,"column":40}},"80":{"start":{"line":81,"column":0},"end":{"line":81,"column":67}},"81":{"start":{"line":82,"column":0},"end":{"line":82,"column":59}},"82":{"start":{"line":83,"column":0},"end":{"line":83,"column":5}},"83":{"start":{"line":84,"column":0},"end":{"line":84,"column":3}},"84":{"start":{"line":85,"column":0},"end":{"line":85,"column":0}},"85":{"start":{"line":86,"column":0},"end":{"line":86,"column":59}},"86":{"start":{"line":87,"column":0},"end":{"line":87,"column":30}},"87":{"start":{"line":88,"column":0},"end":{"line":88,"column":43}},"88":{"start":{"line":89,"column":0},"end":{"line":89,"column":0}},"89":{"start":{"line":90,"column":0},"end":{"line":90,"column":45}},"90":{"start":{"line":91,"column":0},"end":{"line":91,"column":45}},"91":{"start":{"line":92,"column":0},"end":{"line":92,"column":5}},"92":{"start":{"line":93,"column":0},"end":{"line":93,"column":0}},"93":{"start":{"line":94,"column":0},"end":{"line":94,"column":53}},"94":{"start":{"line":95,"column":0},"end":{"line":95,"column":29}},"95":{"start":{"line":96,"column":0},"end":{"line":96,"column":4}},"96":{"start":{"line":97,"column":0},"end":{"line":97,"column":58}},"97":{"start":{"line":98,"column":0},"end":{"line":98,"column":21}},"98":{"start":{"line":99,"column":0},"end":{"line":99,"column":5}},"99":{"start":{"line":100,"column":0},"end":{"line":100,"column":0}},"100":{"start":{"line":101,"column":0},"end":{"line":101,"column":30}},"101":{"start":{"line":102,"column":0},"end":{"line":102,"column":47}},"102":{"start":{"line":103,"column":0},"end":{"line":103,"column":19}},"103":{"start":{"line":104,"column":0},"end":{"line":104,"column":5}},"104":{"start":{"line":105,"column":0},"end":{"line":105,"column":0}},"105":{"start":{"line":106,"column":0},"end":{"line":106,"column":29}},"106":{"start":{"line":107,"column":0},"end":{"line":107,"column":25}},"107":{"start":{"line":108,"column":0},"end":{"line":108,"column":118}},"108":{"start":{"line":109,"column":0},"end":{"line":109,"column":73}},"109":{"start":{"line":110,"column":0},"end":{"line":110,"column":27}},"110":{"start":{"line":111,"column":0},"end":{"line":111,"column":8}},"111":{"start":{"line":112,"column":0},"end":{"line":112,"column":30}},"112":{"start":{"line":113,"column":0},"end":{"line":113,"column":40}},"113":{"start":{"line":114,"column":0},"end":{"line":114,"column":9}},"114":{"start":{"line":115,"column":0},"end":{"line":115,"column":44}},"115":{"start":{"line":116,"column":0},"end":{"line":116,"column":30}},"116":{"start":{"line":117,"column":0},"end":{"line":117,"column":36}},"117":{"start":{"line":118,"column":0},"end":{"line":118,"column":75}},"118":{"start":{"line":119,"column":0},"end":{"line":119,"column":18}},"119":{"start":{"line":120,"column":0},"end":{"line":120,"column":7}},"120":{"start":{"line":121,"column":0},"end":{"line":121,"column":18}},"121":{"start":{"line":122,"column":0},"end":{"line":122,"column":5}},"122":{"start":{"line":123,"column":0},"end":{"line":123,"column":0}},"123":{"start":{"line":124,"column":0},"end":{"line":124,"column":17}},"124":{"start":{"line":125,"column":0},"end":{"line":125,"column":3}},"125":{"start":{"line":126,"column":0},"end":{"line":126,"column":0}},"126":{"start":{"line":127,"column":0},"end":{"line":127,"column":37}},"127":{"start":{"line":128,"column":0},"end":{"line":128,"column":169}},"128":{"start":{"line":129,"column":0},"end":{"line":129,"column":0}},"129":{"start":{"line":130,"column":0},"end":{"line":130,"column":22}},"130":{"start":{"line":131,"column":0},"end":{"line":131,"column":87}},"131":{"start":{"line":132,"column":0},"end":{"line":132,"column":13}},"132":{"start":{"line":133,"column":0},"end":{"line":133,"column":5}},"133":{"start":{"line":134,"column":0},"end":{"line":134,"column":0}},"134":{"start":{"line":135,"column":0},"end":{"line":135,"column":39}},"135":{"start":{"line":136,"column":0},"end":{"line":136,"column":0}},"136":{"start":{"line":137,"column":0},"end":{"line":137,"column":49}},"137":{"start":{"line":138,"column":0},"end":{"line":138,"column":4}},"138":{"start":{"line":139,"column":0},"end":{"line":139,"column":22}},"139":{"start":{"line":140,"column":0},"end":{"line":140,"column":48}},"140":{"start":{"line":141,"column":0},"end":{"line":141,"column":91}},"141":{"start":{"line":142,"column":0},"end":{"line":142,"column":15}},"142":{"start":{"line":143,"column":0},"end":{"line":143,"column":7}},"143":{"start":{"line":144,"column":0},"end":{"line":144,"column":0}},"144":{"start":{"line":145,"column":0},"end":{"line":145,"column":32}},"145":{"start":{"line":146,"column":0},"end":{"line":146,"column":55}},"146":{"start":{"line":147,"column":0},"end":{"line":147,"column":6}},"147":{"start":{"line":148,"column":0},"end":{"line":148,"column":21}},"148":{"start":{"line":149,"column":0},"end":{"line":149,"column":54}},"149":{"start":{"line":150,"column":0},"end":{"line":150,"column":36}},"150":{"start":{"line":151,"column":0},"end":{"line":151,"column":55}},"151":{"start":{"line":152,"column":0},"end":{"line":152,"column":108}},"152":{"start":{"line":153,"column":0},"end":{"line":153,"column":20}},"153":{"start":{"line":154,"column":0},"end":{"line":154,"column":67}},"154":{"start":{"line":155,"column":0},"end":{"line":155,"column":30}},"155":{"start":{"line":156,"column":0},"end":{"line":156,"column":43}},"156":{"start":{"line":157,"column":0},"end":{"line":157,"column":13}},"157":{"start":{"line":158,"column":0},"end":{"line":158,"column":116}},"158":{"start":{"line":159,"column":0},"end":{"line":159,"column":19}},"159":{"start":{"line":160,"column":0},"end":{"line":160,"column":11}},"160":{"start":{"line":161,"column":0},"end":{"line":161,"column":27}},"161":{"start":{"line":162,"column":0},"end":{"line":162,"column":42}},"162":{"start":{"line":163,"column":0},"end":{"line":163,"column":100}},"163":{"start":{"line":164,"column":0},"end":{"line":164,"column":16}},"164":{"start":{"line":165,"column":0},"end":{"line":165,"column":100}},"165":{"start":{"line":166,"column":0},"end":{"line":166,"column":49}},"166":{"start":{"line":167,"column":0},"end":{"line":167,"column":81}},"167":{"start":{"line":168,"column":0},"end":{"line":168,"column":9}},"168":{"start":{"line":169,"column":0},"end":{"line":169,"column":14}},"169":{"start":{"line":170,"column":0},"end":{"line":170,"column":99}},"170":{"start":{"line":171,"column":0},"end":{"line":171,"column":75}},"171":{"start":{"line":172,"column":0},"end":{"line":172,"column":7}},"172":{"start":{"line":173,"column":0},"end":{"line":173,"column":5}},"173":{"start":{"line":174,"column":0},"end":{"line":174,"column":0}},"174":{"start":{"line":175,"column":0},"end":{"line":175,"column":27}},"175":{"start":{"line":176,"column":0},"end":{"line":176,"column":85}},"176":{"start":{"line":177,"column":0},"end":{"line":177,"column":39}},"177":{"start":{"line":178,"column":0},"end":{"line":178,"column":0}},"178":{"start":{"line":179,"column":0},"end":{"line":179,"column":44}},"179":{"start":{"line":180,"column":0},"end":{"line":180,"column":99}},"180":{"start":{"line":181,"column":0},"end":{"line":181,"column":19}},"181":{"start":{"line":182,"column":0},"end":{"line":182,"column":5}},"182":{"start":{"line":183,"column":0},"end":{"line":183,"column":3}},"183":{"start":{"line":184,"column":0},"end":{"line":184,"column":0}},"184":{"start":{"line":185,"column":0},"end":{"line":185,"column":47}},"185":{"start":{"line":186,"column":0},"end":{"line":186,"column":36}},"186":{"start":{"line":187,"column":0},"end":{"line":187,"column":0}},"187":{"start":{"line":188,"column":0},"end":{"line":188,"column":30}},"188":{"start":{"line":189,"column":0},"end":{"line":189,"column":29}},"189":{"start":{"line":190,"column":0},"end":{"line":190,"column":0}},"190":{"start":{"line":191,"column":0},"end":{"line":191,"column":48}},"191":{"start":{"line":192,"column":0},"end":{"line":192,"column":54}},"192":{"start":{"line":193,"column":0},"end":{"line":193,"column":35}},"193":{"start":{"line":194,"column":0},"end":{"line":194,"column":7}},"194":{"start":{"line":195,"column":0},"end":{"line":195,"column":5}},"195":{"start":{"line":196,"column":0},"end":{"line":196,"column":3}},"196":{"start":{"line":197,"column":0},"end":{"line":197,"column":0}},"197":{"start":{"line":198,"column":0},"end":{"line":198,"column":45}},"198":{"start":{"line":199,"column":0},"end":{"line":199,"column":42}},"199":{"start":{"line":200,"column":0},"end":{"line":200,"column":0}},"200":{"start":{"line":201,"column":0},"end":{"line":201,"column":69}},"201":{"start":{"line":202,"column":0},"end":{"line":202,"column":33}},"202":{"start":{"line":203,"column":0},"end":{"line":203,"column":22}},"203":{"start":{"line":204,"column":0},"end":{"line":204,"column":20}},"204":{"start":{"line":205,"column":0},"end":{"line":205,"column":26}},"205":{"start":{"line":206,"column":0},"end":{"line":206,"column":32}},"206":{"start":{"line":207,"column":0},"end":{"line":207,"column":28}},"207":{"start":{"line":208,"column":0},"end":{"line":208,"column":25}},"208":{"start":{"line":209,"column":0},"end":{"line":209,"column":22}},"209":{"start":{"line":210,"column":0},"end":{"line":210,"column":8}},"210":{"start":{"line":211,"column":0},"end":{"line":211,"column":30}},"211":{"start":{"line":212,"column":0},"end":{"line":212,"column":5}},"212":{"start":{"line":213,"column":0},"end":{"line":213,"column":0}},"213":{"start":{"line":214,"column":0},"end":{"line":214,"column":23}},"214":{"start":{"line":215,"column":0},"end":{"line":215,"column":3}},"215":{"start":{"line":216,"column":0},"end":{"line":216,"column":0}},"216":{"start":{"line":217,"column":0},"end":{"line":217,"column":59}},"217":{"start":{"line":218,"column":0},"end":{"line":218,"column":33}},"218":{"start":{"line":219,"column":0},"end":{"line":219,"column":43}},"219":{"start":{"line":220,"column":0},"end":{"line":220,"column":54}},"220":{"start":{"line":221,"column":0},"end":{"line":221,"column":5}},"221":{"start":{"line":222,"column":0},"end":{"line":222,"column":16}},"222":{"start":{"line":223,"column":0},"end":{"line":223,"column":3}},"223":{"start":{"line":224,"column":0},"end":{"line":224,"column":0}},"224":{"start":{"line":225,"column":0},"end":{"line":225,"column":32}},"225":{"start":{"line":226,"column":0},"end":{"line":226,"column":146}},"226":{"start":{"line":227,"column":0},"end":{"line":227,"column":0}},"227":{"start":{"line":228,"column":0},"end":{"line":228,"column":67}},"228":{"start":{"line":229,"column":0},"end":{"line":229,"column":62}},"229":{"start":{"line":230,"column":0},"end":{"line":230,"column":13}},"230":{"start":{"line":231,"column":0},"end":{"line":231,"column":5}},"231":{"start":{"line":232,"column":0},"end":{"line":232,"column":26}},"232":{"start":{"line":233,"column":0},"end":{"line":233,"column":64}},"233":{"start":{"line":234,"column":0},"end":{"line":234,"column":13}},"234":{"start":{"line":235,"column":0},"end":{"line":235,"column":5}},"235":{"start":{"line":236,"column":0},"end":{"line":236,"column":0}},"236":{"start":{"line":237,"column":0},"end":{"line":237,"column":27}},"237":{"start":{"line":238,"column":0},"end":{"line":238,"column":0}},"238":{"start":{"line":239,"column":0},"end":{"line":239,"column":59}},"239":{"start":{"line":240,"column":0},"end":{"line":240,"column":48}},"240":{"start":{"line":241,"column":0},"end":{"line":241,"column":50}},"241":{"start":{"line":242,"column":0},"end":{"line":242,"column":0}},"242":{"start":{"line":243,"column":0},"end":{"line":243,"column":140}},"243":{"start":{"line":244,"column":0},"end":{"line":244,"column":0}},"244":{"start":{"line":245,"column":0},"end":{"line":245,"column":31}},"245":{"start":{"line":246,"column":0},"end":{"line":246,"column":44}},"246":{"start":{"line":247,"column":0},"end":{"line":247,"column":0}},"247":{"start":{"line":248,"column":0},"end":{"line":248,"column":9}},"248":{"start":{"line":249,"column":0},"end":{"line":249,"column":42}},"249":{"start":{"line":250,"column":0},"end":{"line":250,"column":33}},"250":{"start":{"line":251,"column":0},"end":{"line":251,"column":61}},"251":{"start":{"line":252,"column":0},"end":{"line":252,"column":48}},"252":{"start":{"line":253,"column":0},"end":{"line":253,"column":17}},"253":{"start":{"line":254,"column":0},"end":{"line":254,"column":127}},"254":{"start":{"line":255,"column":0},"end":{"line":255,"column":53}},"255":{"start":{"line":256,"column":0},"end":{"line":256,"column":14}},"256":{"start":{"line":257,"column":0},"end":{"line":257,"column":15}},"257":{"start":{"line":258,"column":0},"end":{"line":258,"column":30}},"258":{"start":{"line":259,"column":0},"end":{"line":259,"column":5}},"259":{"start":{"line":260,"column":0},"end":{"line":260,"column":3}},"260":{"start":{"line":261,"column":0},"end":{"line":261,"column":0}},"261":{"start":{"line":262,"column":0},"end":{"line":262,"column":21}},"262":{"start":{"line":263,"column":0},"end":{"line":263,"column":73}},"263":{"start":{"line":264,"column":0},"end":{"line":264,"column":0}},"264":{"start":{"line":265,"column":0},"end":{"line":265,"column":59}},"265":{"start":{"line":266,"column":0},"end":{"line":266,"column":62}},"266":{"start":{"line":267,"column":0},"end":{"line":267,"column":48}},"267":{"start":{"line":268,"column":0},"end":{"line":268,"column":50}},"268":{"start":{"line":269,"column":0},"end":{"line":269,"column":0}},"269":{"start":{"line":270,"column":0},"end":{"line":270,"column":31}},"270":{"start":{"line":271,"column":0},"end":{"line":271,"column":44}},"271":{"start":{"line":272,"column":0},"end":{"line":272,"column":0}},"272":{"start":{"line":273,"column":0},"end":{"line":273,"column":9}},"273":{"start":{"line":274,"column":0},"end":{"line":274,"column":40}},"274":{"start":{"line":275,"column":0},"end":{"line":275,"column":33}},"275":{"start":{"line":276,"column":0},"end":{"line":276,"column":48}},"276":{"start":{"line":277,"column":0},"end":{"line":277,"column":17}},"277":{"start":{"line":278,"column":0},"end":{"line":278,"column":55}},"278":{"start":{"line":279,"column":0},"end":{"line":279,"column":53}},"279":{"start":{"line":280,"column":0},"end":{"line":280,"column":57}},"280":{"start":{"line":281,"column":0},"end":{"line":281,"column":43}},"281":{"start":{"line":282,"column":0},"end":{"line":282,"column":45}},"282":{"start":{"line":283,"column":0},"end":{"line":283,"column":9}},"283":{"start":{"line":284,"column":0},"end":{"line":284,"column":7}},"284":{"start":{"line":285,"column":0},"end":{"line":285,"column":5}},"285":{"start":{"line":286,"column":0},"end":{"line":286,"column":3}},"286":{"start":{"line":287,"column":0},"end":{"line":287,"column":0}},"287":{"start":{"line":288,"column":0},"end":{"line":288,"column":18}},"288":{"start":{"line":289,"column":0},"end":{"line":289,"column":29}},"289":{"start":{"line":290,"column":0},"end":{"line":290,"column":3}},"290":{"start":{"line":291,"column":0},"end":{"line":291,"column":0}},"291":{"start":{"line":292,"column":0},"end":{"line":292,"column":19}},"292":{"start":{"line":293,"column":0},"end":{"line":293,"column":21}},"293":{"start":{"line":294,"column":0},"end":{"line":294,"column":32}},"294":{"start":{"line":295,"column":0},"end":{"line":295,"column":24}},"295":{"start":{"line":296,"column":0},"end":{"line":296,"column":5}},"296":{"start":{"line":297,"column":0},"end":{"line":297,"column":26}},"297":{"start":{"line":298,"column":0},"end":{"line":298,"column":36}},"298":{"start":{"line":299,"column":0},"end":{"line":299,"column":29}},"299":{"start":{"line":300,"column":0},"end":{"line":300,"column":5}},"300":{"start":{"line":301,"column":0},"end":{"line":301,"column":69}},"301":{"start":{"line":302,"column":0},"end":{"line":302,"column":80}},"302":{"start":{"line":303,"column":0},"end":{"line":303,"column":5}},"303":{"start":{"line":304,"column":0},"end":{"line":304,"column":40}},"304":{"start":{"line":305,"column":0},"end":{"line":305,"column":32}},"305":{"start":{"line":306,"column":0},"end":{"line":306,"column":72}},"306":{"start":{"line":307,"column":0},"end":{"line":307,"column":7}},"307":{"start":{"line":308,"column":0},"end":{"line":308,"column":28}},"308":{"start":{"line":309,"column":0},"end":{"line":309,"column":64}},"309":{"start":{"line":310,"column":0},"end":{"line":310,"column":7}},"310":{"start":{"line":311,"column":0},"end":{"line":311,"column":5}},"311":{"start":{"line":312,"column":0},"end":{"line":312,"column":20}},"312":{"start":{"line":313,"column":0},"end":{"line":313,"column":27}},"313":{"start":{"line":314,"column":0},"end":{"line":314,"column":31}},"314":{"start":{"line":315,"column":0},"end":{"line":315,"column":30}},"315":{"start":{"line":316,"column":0},"end":{"line":316,"column":3}},"316":{"start":{"line":317,"column":0},"end":{"line":317,"column":1}}},"s":{"0":1,"1":1,"2":1,"3":1,"4":1,"5":1,"6":1,"7":1,"8":1,"9":1,"10":1,"11":1,"12":1,"13":1,"14":1,"15":1,"16":1,"17":1,"18":1,"19":1,"20":1,"21":1,"22":1,"23":1,"24":1,"25":1,"26":1,"27":1,"28":1,"29":1,"30":1,"31":1,"32":27,"33":27,"34":27,"35":27,"36":27,"37":27,"38":27,"39":27,"40":27,"41":27,"42":27,"43":27,"44":1,"45":1,"46":2,"47":2,"48":2,"49":1,"50":1,"51":2,"52":2,"53":4,"54":1,"55":1,"56":2,"57":2,"58":1,"59":1,"60":2,"61":0,"62":0,"63":0,"64":0,"65":2,"66":2,"67":2,"68":2,"69":2,"70":0,"71":0,"72":0,"73":0,"74":2,"75":0,"76":0,"77":0,"78":0,"79":2,"80":2,"81":2,"82":2,"83":2,"84":1,"85":1,"86":80,"87":80,"88":80,"89":80,"90":26,"91":26,"92":80,"93":80,"94":80,"95":80,"96":80,"97":0,"98":0,"99":80,"100":80,"101":0,"102":0,"103":0,"104":80,"105":80,"106":3,"107":3,"108":3,"109":3,"110":3,"111":3,"112":0,"113":0,"114":3,"115":1,"116":1,"117":1,"118":3,"119":3,"120":3,"121":3,"122":77,"123":77,"124":80,"125":1,"126":1,"127":83,"128":83,"129":83,"130":1,"131":1,"132":1,"133":82,"134":82,"135":82,"136":82,"137":82,"138":83,"139":80,"140":3,"141":3,"142":3,"143":77,"144":77,"145":77,"146":77,"147":80,"148":51,"149":51,"150":33,"151":9,"152":33,"153":24,"154":24,"155":24,"156":24,"157":33,"158":33,"159":33,"160":18,"161":18,"162":18,"163":51,"164":0,"165":0,"166":0,"167":0,"168":80,"169":26,"170":26,"171":26,"172":80,"173":46,"174":46,"175":46,"176":46,"177":46,"178":83,"179":1,"180":1,"181":1,"182":83,"183":1,"184":1,"185":82,"186":3,"187":3,"188":3,"189":3,"190":3,"191":3,"192":0,"193":0,"194":3,"195":82,"196":1,"197":1,"198":11,"199":11,"200":11,"201":3,"202":3,"203":3,"204":3,"205":3,"206":3,"207":3,"208":3,"209":3,"210":3,"211":3,"212":11,"213":11,"214":11,"215":1,"216":1,"217":82,"218":80,"219":80,"220":80,"221":2,"222":82,"223":1,"224":1,"225":11,"226":11,"227":11,"228":2,"229":2,"230":2,"231":11,"232":0,"233":0,"234":0,"235":9,"236":9,"237":9,"238":9,"239":9,"240":9,"241":9,"242":9,"243":9,"244":9,"245":9,"246":9,"247":9,"248":9,"249":8,"250":8,"251":8,"252":11,"253":1,"254":1,"255":1,"256":11,"257":9,"258":9,"259":11,"260":1,"261":1,"262":2,"263":2,"264":2,"265":2,"266":2,"267":2,"268":2,"269":2,"270":2,"271":2,"272":2,"273":2,"274":2,"275":2,"276":2,"277":1,"278":1,"279":1,"280":0,"281":0,"282":0,"283":0,"284":1,"285":2,"286":1,"287":1,"288":19,"289":19,"290":1,"291":1,"292":28,"293":2,"294":2,"295":2,"296":28,"297":3,"298":3,"299":3,"300":28,"301":2,"302":2,"303":28,"304":28,"305":2,"306":2,"307":28,"308":2,"309":2,"310":28,"311":28,"312":28,"313":28,"314":28,"315":28,"316":1},"branchMap":{"0":{"type":"branch","line":32,"loc":{"start":{"line":32,"column":2},"end":{"line":44,"column":3}},"locations":[{"start":{"line":32,"column":2},"end":{"line":44,"column":3}}]},"1":{"type":"branch","line":46,"loc":{"start":{"line":46,"column":2},"end":{"line":49,"column":3}},"locations":[{"start":{"line":46,"column":2},"end":{"line":49,"column":3}}]},"2":{"type":"branch","line":51,"loc":{"start":{"line":51,"column":10},"end":{"line":58,"column":3}},"locations":[{"start":{"line":51,"column":10},"end":{"line":58,"column":3}}]},"3":{"type":"branch","line":52,"loc":{"start":{"line":52,"column":20},"end":{"line":52,"column":27}},"locations":[{"start":{"line":52,"column":20},"end":{"line":52,"column":27}}]},"4":{"type":"branch","line":53,"loc":{"start":{"line":53,"column":29},"end":{"line":57,"column":7}},"locations":[{"start":{"line":53,"column":29},"end":{"line":57,"column":7}}]},"5":{"type":"branch","line":54,"loc":{"start":{"line":54,"column":30},"end":{"line":54,"column":64}},"locations":[{"start":{"line":54,"column":30},"end":{"line":54,"column":64}}]},"6":{"type":"branch","line":54,"loc":{"start":{"line":54,"column":64},"end":{"line":56,"column":7}},"locations":[{"start":{"line":54,"column":64},"end":{"line":56,"column":7}}]},"7":{"type":"branch","line":60,"loc":{"start":{"line":60,"column":10},"end":{"line":84,"column":3}},"locations":[{"start":{"line":60,"column":10},"end":{"line":84,"column":3}}]},"8":{"type":"branch","line":86,"loc":{"start":{"line":86,"column":10},"end":{"line":125,"column":3}},"locations":[{"start":{"line":86,"column":10},"end":{"line":125,"column":3}}]},"9":{"type":"branch","line":90,"loc":{"start":{"line":90,"column":44},"end":{"line":92,"column":5}},"locations":[{"start":{"line":90,"column":44},"end":{"line":92,"column":5}}]},"10":{"type":"branch","line":97,"loc":{"start":{"line":97,"column":57},"end":{"line":99,"column":5}},"locations":[{"start":{"line":97,"column":57},"end":{"line":99,"column":5}}]},"11":{"type":"branch","line":101,"loc":{"start":{"line":101,"column":29},"end":{"line":104,"column":5}},"locations":[{"start":{"line":101,"column":29},"end":{"line":104,"column":5}}]},"12":{"type":"branch","line":106,"loc":{"start":{"line":106,"column":28},"end":{"line":122,"column":5}},"locations":[{"start":{"line":106,"column":28},"end":{"line":122,"column":5}}]},"13":{"type":"branch","line":112,"loc":{"start":{"line":112,"column":29},"end":{"line":114,"column":9}},"locations":[{"start":{"line":112,"column":29},"end":{"line":114,"column":9}}]},"14":{"type":"branch","line":122,"loc":{"start":{"line":122,"column":4},"end":{"line":124,"column":17}},"locations":[{"start":{"line":122,"column":4},"end":{"line":124,"column":17}}]},"15":{"type":"branch","line":115,"loc":{"start":{"line":115,"column":37},"end":{"line":119,"column":11}},"locations":[{"start":{"line":115,"column":37},"end":{"line":119,"column":11}}]},"16":{"type":"branch","line":127,"loc":{"start":{"line":127,"column":2},"end":{"line":183,"column":3}},"locations":[{"start":{"line":127,"column":2},"end":{"line":183,"column":3}}]},"17":{"type":"branch","line":128,"loc":{"start":{"line":128,"column":107},"end":{"line":128,"column":156}},"locations":[{"start":{"line":128,"column":107},"end":{"line":128,"column":156}}]},"18":{"type":"branch","line":128,"loc":{"start":{"line":128,"column":146},"end":{"line":128,"column":166}},"locations":[{"start":{"line":128,"column":146},"end":{"line":128,"column":166}}]},"19":{"type":"branch","line":130,"loc":{"start":{"line":130,"column":21},"end":{"line":133,"column":5}},"locations":[{"start":{"line":130,"column":21},"end":{"line":133,"column":5}}]},"20":{"type":"branch","line":133,"loc":{"start":{"line":133,"column":4},"end":{"line":139,"column":21}},"locations":[{"start":{"line":133,"column":4},"end":{"line":139,"column":21}}]},"21":{"type":"branch","line":139,"loc":{"start":{"line":139,"column":21},"end":{"line":173,"column":5}},"locations":[{"start":{"line":139,"column":21},"end":{"line":173,"column":5}}]},"22":{"type":"branch","line":140,"loc":{"start":{"line":140,"column":47},"end":{"line":143,"column":7}},"locations":[{"start":{"line":140,"column":47},"end":{"line":143,"column":7}}]},"23":{"type":"branch","line":143,"loc":{"start":{"line":143,"column":6},"end":{"line":148,"column":20}},"locations":[{"start":{"line":143,"column":6},"end":{"line":148,"column":20}}]},"24":{"type":"branch","line":148,"loc":{"start":{"line":148,"column":20},"end":{"line":169,"column":13}},"locations":[{"start":{"line":148,"column":20},"end":{"line":169,"column":13}}]},"25":{"type":"branch","line":150,"loc":{"start":{"line":150,"column":35},"end":{"line":160,"column":11}},"locations":[{"start":{"line":150,"column":35},"end":{"line":160,"column":11}}]},"26":{"type":"branch","line":151,"loc":{"start":{"line":151,"column":54},"end":{"line":153,"column":19}},"locations":[{"start":{"line":151,"column":54},"end":{"line":153,"column":19}}]},"27":{"type":"branch","line":153,"loc":{"start":{"line":153,"column":12},"end":{"line":157,"column":13}},"locations":[{"start":{"line":153,"column":12},"end":{"line":157,"column":13}}]},"28":{"type":"branch","line":160,"loc":{"start":{"line":160,"column":10},"end":{"line":164,"column":15}},"locations":[{"start":{"line":160,"column":10},"end":{"line":164,"column":15}}]},"29":{"type":"branch","line":164,"loc":{"start":{"line":164,"column":8},"end":{"line":168,"column":9}},"locations":[{"start":{"line":164,"column":8},"end":{"line":168,"column":9}}]},"30":{"type":"branch","line":169,"loc":{"start":{"line":169,"column":6},"end":{"line":172,"column":7}},"locations":[{"start":{"line":169,"column":6},"end":{"line":172,"column":7}}]},"31":{"type":"branch","line":173,"loc":{"start":{"line":173,"column":4},"end":{"line":179,"column":43}},"locations":[{"start":{"line":173,"column":4},"end":{"line":179,"column":43}}]},"32":{"type":"branch","line":179,"loc":{"start":{"line":179,"column":43},"end":{"line":182,"column":5}},"locations":[{"start":{"line":179,"column":43},"end":{"line":182,"column":5}}]},"33":{"type":"branch","line":185,"loc":{"start":{"line":185,"column":10},"end":{"line":196,"column":3}},"locations":[{"start":{"line":185,"column":10},"end":{"line":196,"column":3}}]},"34":{"type":"branch","line":186,"loc":{"start":{"line":186,"column":29},"end":{"line":186,"column":36}},"locations":[{"start":{"line":186,"column":29},"end":{"line":186,"column":36}}]},"35":{"type":"branch","line":186,"loc":{"start":{"line":186,"column":29},"end":{"line":195,"column":5}},"locations":[{"start":{"line":186,"column":29},"end":{"line":195,"column":5}}]},"36":{"type":"branch","line":192,"loc":{"start":{"line":192,"column":53},"end":{"line":194,"column":7}},"locations":[{"start":{"line":192,"column":53},"end":{"line":194,"column":7}}]},"37":{"type":"branch","line":198,"loc":{"start":{"line":198,"column":10},"end":{"line":215,"column":3}},"locations":[{"start":{"line":198,"column":10},"end":{"line":215,"column":3}}]},"38":{"type":"branch","line":201,"loc":{"start":{"line":201,"column":68},"end":{"line":212,"column":5}},"locations":[{"start":{"line":201,"column":68},"end":{"line":212,"column":5}}]},"39":{"type":"branch","line":217,"loc":{"start":{"line":217,"column":10},"end":{"line":223,"column":3}},"locations":[{"start":{"line":217,"column":10},"end":{"line":223,"column":3}}]},"40":{"type":"branch","line":218,"loc":{"start":{"line":218,"column":32},"end":{"line":221,"column":5}},"locations":[{"start":{"line":218,"column":32},"end":{"line":221,"column":5}}]},"41":{"type":"branch","line":220,"loc":{"start":{"line":220,"column":22},"end":{"line":220,"column":54}},"locations":[{"start":{"line":220,"column":22},"end":{"line":220,"column":54}}]},"42":{"type":"branch","line":221,"loc":{"start":{"line":221,"column":4},"end":{"line":222,"column":16}},"locations":[{"start":{"line":221,"column":4},"end":{"line":222,"column":16}}]},"43":{"type":"branch","line":225,"loc":{"start":{"line":225,"column":2},"end":{"line":260,"column":3}},"locations":[{"start":{"line":225,"column":2},"end":{"line":260,"column":3}}]},"44":{"type":"branch","line":228,"loc":{"start":{"line":228,"column":30},"end":{"line":228,"column":66}},"locations":[{"start":{"line":228,"column":30},"end":{"line":228,"column":66}}]},"45":{"type":"branch","line":228,"loc":{"start":{"line":228,"column":66},"end":{"line":231,"column":5}},"locations":[{"start":{"line":228,"column":66},"end":{"line":231,"column":5}}]},"46":{"type":"branch","line":231,"loc":{"start":{"line":231,"column":4},"end":{"line":232,"column":25}},"locations":[{"start":{"line":231,"column":4},"end":{"line":232,"column":25}}]},"47":{"type":"branch","line":232,"loc":{"start":{"line":232,"column":25},"end":{"line":235,"column":5}},"locations":[{"start":{"line":232,"column":25},"end":{"line":235,"column":5}}]},"48":{"type":"branch","line":235,"loc":{"start":{"line":235,"column":4},"end":{"line":249,"column":42}},"locations":[{"start":{"line":235,"column":4},"end":{"line":249,"column":42}}]},"49":{"type":"branch","line":249,"loc":{"start":{"line":249,"column":40},"end":{"line":253,"column":13}},"locations":[{"start":{"line":249,"column":40},"end":{"line":253,"column":13}}]},"50":{"type":"branch","line":253,"loc":{"start":{"line":253,"column":4},"end":{"line":257,"column":6}},"locations":[{"start":{"line":253,"column":4},"end":{"line":257,"column":6}}]},"51":{"type":"branch","line":254,"loc":{"start":{"line":254,"column":104},"end":{"line":254,"column":124}},"locations":[{"start":{"line":254,"column":104},"end":{"line":254,"column":124}}]},"52":{"type":"branch","line":257,"loc":{"start":{"line":257,"column":4},"end":{"line":257,"column":6}},"locations":[{"start":{"line":257,"column":4},"end":{"line":257,"column":6}}]},"53":{"type":"branch","line":257,"loc":{"start":{"line":257,"column":4},"end":{"line":259,"column":5}},"locations":[{"start":{"line":257,"column":4},"end":{"line":259,"column":5}}]},"54":{"type":"branch","line":255,"loc":{"start":{"line":255,"column":21},"end":{"line":255,"column":51}},"locations":[{"start":{"line":255,"column":21},"end":{"line":255,"column":51}}]},"55":{"type":"branch","line":262,"loc":{"start":{"line":262,"column":2},"end":{"line":286,"column":3}},"locations":[{"start":{"line":262,"column":2},"end":{"line":286,"column":3}}]},"56":{"type":"branch","line":263,"loc":{"start":{"line":263,"column":30},"end":{"line":263,"column":66}},"locations":[{"start":{"line":263,"column":30},"end":{"line":263,"column":66}}]},"57":{"type":"branch","line":263,"loc":{"start":{"line":263,"column":66},"end":{"line":263,"column":73}},"locations":[{"start":{"line":263,"column":66},"end":{"line":263,"column":73}}]},"58":{"type":"branch","line":277,"loc":{"start":{"line":277,"column":4},"end":{"line":285,"column":5}},"locations":[{"start":{"line":277,"column":4},"end":{"line":285,"column":5}}]},"59":{"type":"branch","line":280,"loc":{"start":{"line":280,"column":56},"end":{"line":284,"column":7}},"locations":[{"start":{"line":280,"column":56},"end":{"line":284,"column":7}}]},"60":{"type":"branch","line":279,"loc":{"start":{"line":279,"column":21},"end":{"line":279,"column":51}},"locations":[{"start":{"line":279,"column":21},"end":{"line":279,"column":51}}]},"61":{"type":"branch","line":288,"loc":{"start":{"line":288,"column":2},"end":{"line":290,"column":3}},"locations":[{"start":{"line":288,"column":2},"end":{"line":290,"column":3}}]},"62":{"type":"branch","line":292,"loc":{"start":{"line":292,"column":2},"end":{"line":316,"column":3}},"locations":[{"start":{"line":292,"column":2},"end":{"line":316,"column":3}}]},"63":{"type":"branch","line":293,"loc":{"start":{"line":293,"column":20},"end":{"line":296,"column":5}},"locations":[{"start":{"line":293,"column":20},"end":{"line":296,"column":5}}]},"64":{"type":"branch","line":297,"loc":{"start":{"line":297,"column":25},"end":{"line":300,"column":5}},"locations":[{"start":{"line":297,"column":25},"end":{"line":300,"column":5}}]},"65":{"type":"branch","line":301,"loc":{"start":{"line":301,"column":68},"end":{"line":303,"column":5}},"locations":[{"start":{"line":301,"column":68},"end":{"line":303,"column":5}}]},"66":{"type":"branch","line":305,"loc":{"start":{"line":305,"column":31},"end":{"line":307,"column":7}},"locations":[{"start":{"line":305,"column":31},"end":{"line":307,"column":7}}]},"67":{"type":"branch","line":308,"loc":{"start":{"line":308,"column":27},"end":{"line":310,"column":7}},"locations":[{"start":{"line":308,"column":27},"end":{"line":310,"column":7}}]}},"b":{"0":[27],"1":[2],"2":[2],"3":[0],"4":[4],"5":[3],"6":[1],"7":[2],"8":[80],"9":[26],"10":[0],"11":[0],"12":[3],"13":[0],"14":[77],"15":[1],"16":[83],"17":[81],"18":[2],"19":[1],"20":[82],"21":[80],"22":[3],"23":[77],"24":[51],"25":[33],"26":[9],"27":[24],"28":[18],"29":[0],"30":[26],"31":[46],"32":[1],"33":[82],"34":[79],"35":[3],"36":[0],"37":[11],"38":[3],"39":[82],"40":[80],"41":[17],"42":[2],"43":[11],"44":[2],"45":[2],"46":[9],"47":[0],"48":[9],"49":[8],"50":[1],"51":[0],"52":[8],"53":[9],"54":[1],"55":[2],"56":[0],"57":[0],"58":[1],"59":[0],"60":[1],"61":[19],"62":[28],"63":[2],"64":[3],"65":[2],"66":[2],"67":[2]},"fnMap":{"0":{"name":"EventQueue","decl":{"start":{"line":32,"column":2},"end":{"line":44,"column":3}},"loc":{"start":{"line":32,"column":2},"end":{"line":44,"column":3}},"line":32},"1":{"name":"start","decl":{"start":{"line":46,"column":2},"end":{"line":49,"column":3}},"loc":{"start":{"line":46,"column":2},"end":{"line":49,"column":3}},"line":46},"2":{"name":"startTimer","decl":{"start":{"line":51,"column":10},"end":{"line":58,"column":3}},"loc":{"start":{"line":51,"column":10},"end":{"line":58,"column":3}},"line":51},"3":{"name":"setupVisibilityListener","decl":{"start":{"line":60,"column":10},"end":{"line":84,"column":3}},"loc":{"start":{"line":60,"column":10},"end":{"line":84,"column":3}},"line":60},"4":{"name":"onVisibilityChange","decl":{"start":{"line":61,"column":30},"end":{"line":65,"column":6}},"loc":{"start":{"line":61,"column":30},"end":{"line":65,"column":6}},"line":61},"5":{"name":"onBeforeUnload","decl":{"start":{"line":70,"column":26},"end":{"line":74,"column":6}},"loc":{"start":{"line":70,"column":26},"end":{"line":74,"column":6}},"line":70},"6":{"name":"onPagehide","decl":{"start":{"line":75,"column":22},"end":{"line":79,"column":6}},"loc":{"start":{"line":75,"column":22},"end":{"line":79,"column":6}},"line":75},"7":{"name":"checkInfiniteLoop","decl":{"start":{"line":86,"column":10},"end":{"line":125,"column":3}},"loc":{"start":{"line":86,"column":10},"end":{"line":125,"column":3}},"line":86},"8":{"name":"enqueue","decl":{"start":{"line":127,"column":2},"end":{"line":183,"column":3}},"loc":{"start":{"line":127,"column":2},"end":{"line":183,"column":3}},"line":127},"9":{"name":"cleanupExpiredDedupeEntries","decl":{"start":{"line":185,"column":10},"end":{"line":196,"column":3}},"loc":{"start":{"line":185,"column":10},"end":{"line":196,"column":3}},"line":185},"10":{"name":"buildCountEvents","decl":{"start":{"line":198,"column":10},"end":{"line":215,"column":3}},"loc":{"start":{"line":198,"column":10},"end":{"line":215,"column":3}},"line":198},"11":{"name":"getDedupeKey","decl":{"start":{"line":217,"column":10},"end":{"line":223,"column":3}},"loc":{"start":{"line":217,"column":10},"end":{"line":223,"column":3}},"line":217},"12":{"name":"flush","decl":{"start":{"line":225,"column":2},"end":{"line":260,"column":3}},"loc":{"start":{"line":225,"column":2},"end":{"line":260,"column":3}},"line":225},"13":{"name":"flushSync","decl":{"start":{"line":262,"column":2},"end":{"line":286,"column":3}},"loc":{"start":{"line":262,"column":2},"end":{"line":286,"column":3}},"line":262},"14":{"name":"size","decl":{"start":{"line":288,"column":2},"end":{"line":290,"column":3}},"loc":{"start":{"line":288,"column":2},"end":{"line":290,"column":3}},"line":288},"15":{"name":"destroy","decl":{"start":{"line":292,"column":2},"end":{"line":316,"column":3}},"loc":{"start":{"line":292,"column":2},"end":{"line":316,"column":3}},"line":292}},"f":{"0":27,"1":2,"2":2,"3":2,"4":0,"5":0,"6":0,"7":80,"8":83,"9":82,"10":11,"11":82,"12":11,"13":2,"14":19,"15":28}} +,"/Users/weidingjian/Desktop/work/ai/light-sentry-sdk/src/core/PluginManager.ts": {"path":"/Users/weidingjian/Desktop/work/ai/light-sentry-sdk/src/core/PluginManager.ts","all":false,"statementMap":{"0":{"start":{"line":1,"column":0},"end":{"line":1,"column":70}},"1":{"start":{"line":2,"column":0},"end":{"line":2,"column":0}},"2":{"start":{"line":3,"column":0},"end":{"line":3,"column":28}},"3":{"start":{"line":4,"column":0},"end":{"line":4,"column":56}},"4":{"start":{"line":5,"column":0},"end":{"line":5,"column":30}},"5":{"start":{"line":6,"column":0},"end":{"line":6,"column":0}},"6":{"start":{"line":7,"column":0},"end":{"line":7,"column":36}},"7":{"start":{"line":8,"column":0},"end":{"line":8,"column":25}},"8":{"start":{"line":9,"column":0},"end":{"line":9,"column":3}},"9":{"start":{"line":10,"column":0},"end":{"line":10,"column":0}},"10":{"start":{"line":11,"column":0},"end":{"line":11,"column":34}},"11":{"start":{"line":12,"column":0},"end":{"line":12,"column":40}},"12":{"start":{"line":13,"column":0},"end":{"line":13,"column":13}},"13":{"start":{"line":14,"column":0},"end":{"line":14,"column":5}},"14":{"start":{"line":15,"column":0},"end":{"line":15,"column":42}},"15":{"start":{"line":16,"column":0},"end":{"line":16,"column":9}},"16":{"start":{"line":17,"column":0},"end":{"line":17,"column":32}},"17":{"start":{"line":18,"column":0},"end":{"line":18,"column":17}},"18":{"start":{"line":19,"column":0},"end":{"line":19,"column":74}},"19":{"start":{"line":20,"column":0},"end":{"line":20,"column":5}},"20":{"start":{"line":21,"column":0},"end":{"line":21,"column":3}},"21":{"start":{"line":22,"column":0},"end":{"line":22,"column":0}},"22":{"start":{"line":23,"column":0},"end":{"line":23,"column":30}},"23":{"start":{"line":24,"column":0},"end":{"line":24,"column":42}},"24":{"start":{"line":25,"column":0},"end":{"line":25,"column":17}},"25":{"start":{"line":26,"column":0},"end":{"line":26,"column":27}},"26":{"start":{"line":27,"column":0},"end":{"line":27,"column":13}},"27":{"start":{"line":28,"column":0},"end":{"line":28,"column":27}},"28":{"start":{"line":29,"column":0},"end":{"line":29,"column":21}},"29":{"start":{"line":30,"column":0},"end":{"line":30,"column":73}},"30":{"start":{"line":31,"column":0},"end":{"line":31,"column":9}},"31":{"start":{"line":32,"column":0},"end":{"line":32,"column":7}},"32":{"start":{"line":33,"column":0},"end":{"line":33,"column":32}},"33":{"start":{"line":34,"column":0},"end":{"line":34,"column":5}},"34":{"start":{"line":35,"column":0},"end":{"line":35,"column":3}},"35":{"start":{"line":36,"column":0},"end":{"line":36,"column":0}},"36":{"start":{"line":37,"column":0},"end":{"line":37,"column":46}},"37":{"start":{"line":38,"column":0},"end":{"line":38,"column":34}},"38":{"start":{"line":39,"column":0},"end":{"line":39,"column":3}},"39":{"start":{"line":40,"column":0},"end":{"line":40,"column":0}},"40":{"start":{"line":41,"column":0},"end":{"line":41,"column":30}},"41":{"start":{"line":42,"column":0},"end":{"line":42,"column":34}},"42":{"start":{"line":43,"column":0},"end":{"line":43,"column":3}},"43":{"start":{"line":44,"column":0},"end":{"line":44,"column":0}},"44":{"start":{"line":45,"column":0},"end":{"line":45,"column":61}},"45":{"start":{"line":46,"column":0},"end":{"line":46,"column":43}},"46":{"start":{"line":47,"column":0},"end":{"line":47,"column":49}},"47":{"start":{"line":48,"column":0},"end":{"line":48,"column":32}},"48":{"start":{"line":49,"column":0},"end":{"line":49,"column":13}},"49":{"start":{"line":50,"column":0},"end":{"line":50,"column":55}},"50":{"start":{"line":51,"column":0},"end":{"line":51,"column":34}},"51":{"start":{"line":52,"column":0},"end":{"line":52,"column":24}},"52":{"start":{"line":53,"column":0},"end":{"line":53,"column":11}},"53":{"start":{"line":54,"column":0},"end":{"line":54,"column":28}},"54":{"start":{"line":55,"column":0},"end":{"line":55,"column":21}},"55":{"start":{"line":56,"column":0},"end":{"line":56,"column":85}},"56":{"start":{"line":57,"column":0},"end":{"line":57,"column":9}},"57":{"start":{"line":58,"column":0},"end":{"line":58,"column":7}},"58":{"start":{"line":59,"column":0},"end":{"line":59,"column":5}},"59":{"start":{"line":60,"column":0},"end":{"line":60,"column":18}},"60":{"start":{"line":61,"column":0},"end":{"line":61,"column":3}},"61":{"start":{"line":62,"column":0},"end":{"line":62,"column":0}},"62":{"start":{"line":63,"column":0},"end":{"line":63,"column":46}},"63":{"start":{"line":64,"column":0},"end":{"line":64,"column":49}},"64":{"start":{"line":65,"column":0},"end":{"line":65,"column":31}},"65":{"start":{"line":66,"column":0},"end":{"line":66,"column":13}},"66":{"start":{"line":67,"column":0},"end":{"line":67,"column":36}},"67":{"start":{"line":68,"column":0},"end":{"line":68,"column":21}},"68":{"start":{"line":69,"column":0},"end":{"line":69,"column":84}},"69":{"start":{"line":70,"column":0},"end":{"line":70,"column":9}},"70":{"start":{"line":71,"column":0},"end":{"line":71,"column":7}},"71":{"start":{"line":72,"column":0},"end":{"line":72,"column":5}},"72":{"start":{"line":73,"column":0},"end":{"line":73,"column":3}},"73":{"start":{"line":74,"column":0},"end":{"line":74,"column":0}},"74":{"start":{"line":75,"column":0},"end":{"line":75,"column":19}},"75":{"start":{"line":76,"column":0},"end":{"line":76,"column":49}},"76":{"start":{"line":77,"column":0},"end":{"line":77,"column":27}},"77":{"start":{"line":78,"column":0},"end":{"line":78,"column":13}},"78":{"start":{"line":79,"column":0},"end":{"line":79,"column":27}},"79":{"start":{"line":80,"column":0},"end":{"line":80,"column":21}},"80":{"start":{"line":81,"column":0},"end":{"line":81,"column":80}},"81":{"start":{"line":82,"column":0},"end":{"line":82,"column":9}},"82":{"start":{"line":83,"column":0},"end":{"line":83,"column":7}},"83":{"start":{"line":84,"column":0},"end":{"line":84,"column":5}},"84":{"start":{"line":85,"column":0},"end":{"line":85,"column":25}},"85":{"start":{"line":86,"column":0},"end":{"line":86,"column":3}},"86":{"start":{"line":87,"column":0},"end":{"line":87,"column":1}}},"s":{"0":1,"1":1,"2":1,"3":1,"4":1,"5":1,"6":1,"7":26,"8":26,"9":1,"10":1,"11":30,"12":1,"13":1,"14":29,"15":29,"16":29,"17":30,"18":1,"19":1,"20":30,"21":1,"22":1,"23":5,"24":5,"25":4,"26":2,"27":2,"28":2,"29":1,"30":1,"31":2,"32":4,"33":4,"34":5,"35":1,"36":1,"37":2,"38":2,"39":1,"40":1,"41":8,"42":8,"43":1,"44":1,"45":5,"46":5,"47":8,"48":7,"49":7,"50":7,"51":1,"52":1,"53":5,"54":7,"55":1,"56":1,"57":7,"58":8,"59":4,"60":5,"61":1,"62":1,"63":3,"64":5,"65":4,"66":4,"67":4,"68":1,"69":1,"70":4,"71":5,"72":3,"73":1,"74":1,"75":4,"76":6,"77":4,"78":4,"79":4,"80":1,"81":1,"82":4,"83":6,"84":4,"85":4,"86":1},"branchMap":{"0":{"type":"branch","line":7,"loc":{"start":{"line":7,"column":2},"end":{"line":9,"column":3}},"locations":[{"start":{"line":7,"column":2},"end":{"line":9,"column":3}}]},"1":{"type":"branch","line":11,"loc":{"start":{"line":11,"column":2},"end":{"line":21,"column":3}},"locations":[{"start":{"line":11,"column":2},"end":{"line":21,"column":3}}]},"2":{"type":"branch","line":12,"loc":{"start":{"line":12,"column":39},"end":{"line":14,"column":5}},"locations":[{"start":{"line":12,"column":39},"end":{"line":14,"column":5}}]},"3":{"type":"branch","line":14,"loc":{"start":{"line":14,"column":4},"end":{"line":18,"column":13}},"locations":[{"start":{"line":14,"column":4},"end":{"line":18,"column":13}}]},"4":{"type":"branch","line":18,"loc":{"start":{"line":18,"column":4},"end":{"line":20,"column":5}},"locations":[{"start":{"line":18,"column":4},"end":{"line":20,"column":5}}]},"5":{"type":"branch","line":23,"loc":{"start":{"line":23,"column":2},"end":{"line":35,"column":3}},"locations":[{"start":{"line":23,"column":2},"end":{"line":35,"column":3}}]},"6":{"type":"branch","line":25,"loc":{"start":{"line":25,"column":16},"end":{"line":34,"column":5}},"locations":[{"start":{"line":25,"column":16},"end":{"line":34,"column":5}}]},"7":{"type":"branch","line":26,"loc":{"start":{"line":26,"column":26},"end":{"line":32,"column":7}},"locations":[{"start":{"line":26,"column":26},"end":{"line":32,"column":7}}]},"8":{"type":"branch","line":29,"loc":{"start":{"line":29,"column":8},"end":{"line":31,"column":9}},"locations":[{"start":{"line":29,"column":8},"end":{"line":31,"column":9}}]},"9":{"type":"branch","line":37,"loc":{"start":{"line":37,"column":2},"end":{"line":39,"column":3}},"locations":[{"start":{"line":37,"column":2},"end":{"line":39,"column":3}}]},"10":{"type":"branch","line":41,"loc":{"start":{"line":41,"column":2},"end":{"line":43,"column":3}},"locations":[{"start":{"line":41,"column":2},"end":{"line":43,"column":3}}]},"11":{"type":"branch","line":45,"loc":{"start":{"line":45,"column":2},"end":{"line":61,"column":3}},"locations":[{"start":{"line":45,"column":2},"end":{"line":61,"column":3}}]},"12":{"type":"branch","line":47,"loc":{"start":{"line":47,"column":48},"end":{"line":59,"column":5}},"locations":[{"start":{"line":47,"column":48},"end":{"line":59,"column":5}}]},"13":{"type":"branch","line":48,"loc":{"start":{"line":48,"column":31},"end":{"line":58,"column":7}},"locations":[{"start":{"line":48,"column":31},"end":{"line":58,"column":7}}]},"14":{"type":"branch","line":51,"loc":{"start":{"line":51,"column":33},"end":{"line":53,"column":11}},"locations":[{"start":{"line":51,"column":33},"end":{"line":53,"column":11}}]},"15":{"type":"branch","line":53,"loc":{"start":{"line":53,"column":10},"end":{"line":55,"column":17}},"locations":[{"start":{"line":53,"column":10},"end":{"line":55,"column":17}}]},"16":{"type":"branch","line":55,"loc":{"start":{"line":55,"column":8},"end":{"line":57,"column":9}},"locations":[{"start":{"line":55,"column":8},"end":{"line":57,"column":9}}]},"17":{"type":"branch","line":59,"loc":{"start":{"line":59,"column":4},"end":{"line":60,"column":18}},"locations":[{"start":{"line":59,"column":4},"end":{"line":60,"column":18}}]},"18":{"type":"branch","line":63,"loc":{"start":{"line":63,"column":2},"end":{"line":73,"column":3}},"locations":[{"start":{"line":63,"column":2},"end":{"line":73,"column":3}}]},"19":{"type":"branch","line":64,"loc":{"start":{"line":64,"column":48},"end":{"line":72,"column":5}},"locations":[{"start":{"line":64,"column":48},"end":{"line":72,"column":5}}]},"20":{"type":"branch","line":65,"loc":{"start":{"line":65,"column":30},"end":{"line":71,"column":7}},"locations":[{"start":{"line":65,"column":30},"end":{"line":71,"column":7}}]},"21":{"type":"branch","line":68,"loc":{"start":{"line":68,"column":8},"end":{"line":70,"column":9}},"locations":[{"start":{"line":68,"column":8},"end":{"line":70,"column":9}}]},"22":{"type":"branch","line":75,"loc":{"start":{"line":75,"column":2},"end":{"line":86,"column":3}},"locations":[{"start":{"line":75,"column":2},"end":{"line":86,"column":3}}]},"23":{"type":"branch","line":76,"loc":{"start":{"line":76,"column":48},"end":{"line":84,"column":5}},"locations":[{"start":{"line":76,"column":48},"end":{"line":84,"column":5}}]},"24":{"type":"branch","line":77,"loc":{"start":{"line":77,"column":26},"end":{"line":83,"column":7}},"locations":[{"start":{"line":77,"column":26},"end":{"line":83,"column":7}}]},"25":{"type":"branch","line":80,"loc":{"start":{"line":80,"column":8},"end":{"line":82,"column":9}},"locations":[{"start":{"line":80,"column":8},"end":{"line":82,"column":9}}]}},"b":{"0":[26],"1":[30],"2":[1],"3":[29],"4":[1],"5":[5],"6":[4],"7":[2],"8":[1],"9":[2],"10":[8],"11":[5],"12":[8],"13":[7],"14":[1],"15":[5],"16":[1],"17":[4],"18":[3],"19":[5],"20":[4],"21":[1],"22":[4],"23":[6],"24":[4],"25":[1]},"fnMap":{"0":{"name":"PluginManager","decl":{"start":{"line":7,"column":2},"end":{"line":9,"column":3}},"loc":{"start":{"line":7,"column":2},"end":{"line":9,"column":3}},"line":7},"1":{"name":"add","decl":{"start":{"line":11,"column":2},"end":{"line":21,"column":3}},"loc":{"start":{"line":11,"column":2},"end":{"line":21,"column":3}},"line":11},"2":{"name":"remove","decl":{"start":{"line":23,"column":2},"end":{"line":35,"column":3}},"loc":{"start":{"line":23,"column":2},"end":{"line":35,"column":3}},"line":23},"3":{"name":"get","decl":{"start":{"line":37,"column":2},"end":{"line":39,"column":3}},"loc":{"start":{"line":37,"column":2},"end":{"line":39,"column":3}},"line":37},"4":{"name":"has","decl":{"start":{"line":41,"column":2},"end":{"line":43,"column":3}},"loc":{"start":{"line":41,"column":2},"end":{"line":43,"column":3}},"line":41},"5":{"name":"applyBeforeReport","decl":{"start":{"line":45,"column":2},"end":{"line":61,"column":3}},"loc":{"start":{"line":45,"column":2},"end":{"line":61,"column":3}},"line":45},"6":{"name":"applyAfterReport","decl":{"start":{"line":63,"column":2},"end":{"line":73,"column":3}},"loc":{"start":{"line":63,"column":2},"end":{"line":73,"column":3}},"line":63},"7":{"name":"destroy","decl":{"start":{"line":75,"column":2},"end":{"line":86,"column":3}},"loc":{"start":{"line":75,"column":2},"end":{"line":86,"column":3}},"line":75}},"f":{"0":26,"1":30,"2":5,"3":2,"4":8,"5":5,"6":3,"7":4}} +,"/Users/weidingjian/Desktop/work/ai/light-sentry-sdk/src/core/Reporter.ts": {"path":"/Users/weidingjian/Desktop/work/ai/light-sentry-sdk/src/core/Reporter.ts","all":false,"statementMap":{"0":{"start":{"line":1,"column":0},"end":{"line":1,"column":65}},"1":{"start":{"line":2,"column":0},"end":{"line":2,"column":46}},"2":{"start":{"line":3,"column":0},"end":{"line":3,"column":55}},"3":{"start":{"line":4,"column":0},"end":{"line":4,"column":72}},"4":{"start":{"line":5,"column":0},"end":{"line":5,"column":53}},"5":{"start":{"line":6,"column":0},"end":{"line":6,"column":0}},"6":{"start":{"line":7,"column":0},"end":{"line":7,"column":23}},"7":{"start":{"line":8,"column":0},"end":{"line":8,"column":23}},"8":{"start":{"line":9,"column":0},"end":{"line":9,"column":29}},"9":{"start":{"line":10,"column":0},"end":{"line":10,"column":29}},"10":{"start":{"line":11,"column":0},"end":{"line":11,"column":54}},"11":{"start":{"line":12,"column":0},"end":{"line":12,"column":0}},"12":{"start":{"line":13,"column":0},"end":{"line":13,"column":69}},"13":{"start":{"line":14,"column":0},"end":{"line":14,"column":19}},"14":{"start":{"line":15,"column":0},"end":{"line":15,"column":33}},"15":{"start":{"line":16,"column":0},"end":{"line":16,"column":33}},"16":{"start":{"line":17,"column":0},"end":{"line":17,"column":3}},"17":{"start":{"line":18,"column":0},"end":{"line":18,"column":0}},"18":{"start":{"line":19,"column":0},"end":{"line":19,"column":54}},"19":{"start":{"line":20,"column":0},"end":{"line":20,"column":73}},"20":{"start":{"line":21,"column":0},"end":{"line":21,"column":0}},"21":{"start":{"line":22,"column":0},"end":{"line":22,"column":30}},"22":{"start":{"line":23,"column":0},"end":{"line":23,"column":59}},"23":{"start":{"line":24,"column":0},"end":{"line":24,"column":13}},"24":{"start":{"line":25,"column":0},"end":{"line":25,"column":5}},"25":{"start":{"line":26,"column":0},"end":{"line":26,"column":0}},"26":{"start":{"line":27,"column":0},"end":{"line":27,"column":48}},"27":{"start":{"line":28,"column":0},"end":{"line":28,"column":41}},"28":{"start":{"line":29,"column":0},"end":{"line":29,"column":83}},"29":{"start":{"line":30,"column":0},"end":{"line":30,"column":4}},"30":{"start":{"line":31,"column":0},"end":{"line":31,"column":20}},"31":{"start":{"line":32,"column":0},"end":{"line":32,"column":40}},"32":{"start":{"line":33,"column":0},"end":{"line":33,"column":11}},"33":{"start":{"line":34,"column":0},"end":{"line":34,"column":96}},"34":{"start":{"line":35,"column":0},"end":{"line":35,"column":41}},"35":{"start":{"line":36,"column":0},"end":{"line":36,"column":50}},"36":{"start":{"line":37,"column":0},"end":{"line":37,"column":15}},"37":{"start":{"line":38,"column":0},"end":{"line":38,"column":19}},"38":{"start":{"line":39,"column":0},"end":{"line":39,"column":57}},"39":{"start":{"line":40,"column":0},"end":{"line":40,"column":94}},"40":{"start":{"line":41,"column":0},"end":{"line":41,"column":54}},"41":{"start":{"line":42,"column":0},"end":{"line":42,"column":18}},"42":{"start":{"line":43,"column":0},"end":{"line":43,"column":9}},"43":{"start":{"line":44,"column":0},"end":{"line":44,"column":18}},"44":{"start":{"line":45,"column":0},"end":{"line":45,"column":40}},"45":{"start":{"line":46,"column":0},"end":{"line":46,"column":56}},"46":{"start":{"line":47,"column":0},"end":{"line":47,"column":18}},"47":{"start":{"line":48,"column":0},"end":{"line":48,"column":9}},"48":{"start":{"line":49,"column":0},"end":{"line":49,"column":83}},"49":{"start":{"line":50,"column":0},"end":{"line":50,"column":57}},"50":{"start":{"line":51,"column":0},"end":{"line":51,"column":34}},"51":{"start":{"line":52,"column":0},"end":{"line":52,"column":7}},"52":{"start":{"line":53,"column":0},"end":{"line":53,"column":5}},"53":{"start":{"line":54,"column":0},"end":{"line":54,"column":3}},"54":{"start":{"line":55,"column":0},"end":{"line":55,"column":0}},"55":{"start":{"line":56,"column":0},"end":{"line":56,"column":43}},"56":{"start":{"line":57,"column":0},"end":{"line":57,"column":36}},"57":{"start":{"line":58,"column":0},"end":{"line":58,"column":0}},"58":{"start":{"line":59,"column":0},"end":{"line":59,"column":48}},"59":{"start":{"line":60,"column":0},"end":{"line":60,"column":0}},"60":{"start":{"line":61,"column":0},"end":{"line":61,"column":9}},"61":{"start":{"line":62,"column":0},"end":{"line":62,"column":46}},"62":{"start":{"line":63,"column":0},"end":{"line":63,"column":26}},"63":{"start":{"line":64,"column":0},"end":{"line":64,"column":13}},"64":{"start":{"line":65,"column":0},"end":{"line":65,"column":27}},"65":{"start":{"line":66,"column":0},"end":{"line":66,"column":5}},"66":{"start":{"line":67,"column":0},"end":{"line":67,"column":0}},"67":{"start":{"line":68,"column":0},"end":{"line":68,"column":32}},"68":{"start":{"line":69,"column":0},"end":{"line":69,"column":3}},"69":{"start":{"line":70,"column":0},"end":{"line":70,"column":0}},"70":{"start":{"line":71,"column":0},"end":{"line":71,"column":5}},"71":{"start":{"line":72,"column":0},"end":{"line":72,"column":23}},"72":{"start":{"line":73,"column":0},"end":{"line":73,"column":5}},"73":{"start":{"line":74,"column":0},"end":{"line":74,"column":8}},"74":{"start":{"line":75,"column":0},"end":{"line":75,"column":48}},"75":{"start":{"line":76,"column":0},"end":{"line":76,"column":25}},"76":{"start":{"line":77,"column":0},"end":{"line":77,"column":27}},"77":{"start":{"line":78,"column":0},"end":{"line":78,"column":5}},"78":{"start":{"line":79,"column":0},"end":{"line":79,"column":56}},"79":{"start":{"line":80,"column":0},"end":{"line":80,"column":22}},"80":{"start":{"line":81,"column":0},"end":{"line":81,"column":54}},"81":{"start":{"line":82,"column":0},"end":{"line":82,"column":0}},"82":{"start":{"line":83,"column":0},"end":{"line":83,"column":25}},"83":{"start":{"line":84,"column":0},"end":{"line":84,"column":48}},"84":{"start":{"line":85,"column":0},"end":{"line":85,"column":34}},"85":{"start":{"line":86,"column":0},"end":{"line":86,"column":40}},"86":{"start":{"line":87,"column":0},"end":{"line":87,"column":23}},"87":{"start":{"line":88,"column":0},"end":{"line":88,"column":6}},"88":{"start":{"line":89,"column":0},"end":{"line":89,"column":0}},"89":{"start":{"line":90,"column":0},"end":{"line":90,"column":29}},"90":{"start":{"line":91,"column":0},"end":{"line":91,"column":30}},"91":{"start":{"line":92,"column":0},"end":{"line":92,"column":45}},"92":{"start":{"line":93,"column":0},"end":{"line":93,"column":5}},"93":{"start":{"line":94,"column":0},"end":{"line":94,"column":0}},"94":{"start":{"line":95,"column":0},"end":{"line":95,"column":32}},"95":{"start":{"line":96,"column":0},"end":{"line":96,"column":81}},"96":{"start":{"line":97,"column":0},"end":{"line":97,"column":0}},"97":{"start":{"line":98,"column":0},"end":{"line":98,"column":45}},"98":{"start":{"line":99,"column":0},"end":{"line":99,"column":0}},"99":{"start":{"line":100,"column":0},"end":{"line":100,"column":37}},"100":{"start":{"line":101,"column":0},"end":{"line":101,"column":0}},"101":{"start":{"line":102,"column":0},"end":{"line":102,"column":47}},"102":{"start":{"line":103,"column":0},"end":{"line":103,"column":22}},"103":{"start":{"line":104,"column":0},"end":{"line":104,"column":103}},"104":{"start":{"line":105,"column":0},"end":{"line":105,"column":0}},"105":{"start":{"line":106,"column":0},"end":{"line":106,"column":20}},"106":{"start":{"line":107,"column":0},"end":{"line":107,"column":32}},"107":{"start":{"line":108,"column":0},"end":{"line":108,"column":79}},"108":{"start":{"line":109,"column":0},"end":{"line":109,"column":7}},"109":{"start":{"line":110,"column":0},"end":{"line":110,"column":0}},"110":{"start":{"line":111,"column":0},"end":{"line":111,"column":56}},"111":{"start":{"line":112,"column":0},"end":{"line":112,"column":41}},"112":{"start":{"line":113,"column":0},"end":{"line":113,"column":68}},"113":{"start":{"line":114,"column":0},"end":{"line":114,"column":35}},"114":{"start":{"line":115,"column":0},"end":{"line":115,"column":9}},"115":{"start":{"line":116,"column":0},"end":{"line":116,"column":42}},"116":{"start":{"line":117,"column":0},"end":{"line":117,"column":5}},"117":{"start":{"line":118,"column":0},"end":{"line":118,"column":0}},"118":{"start":{"line":119,"column":0},"end":{"line":119,"column":28}},"119":{"start":{"line":120,"column":0},"end":{"line":120,"column":3}},"120":{"start":{"line":121,"column":0},"end":{"line":121,"column":0}},"121":{"start":{"line":122,"column":0},"end":{"line":122,"column":5}},"122":{"start":{"line":123,"column":0},"end":{"line":123,"column":11}},"123":{"start":{"line":124,"column":0},"end":{"line":124,"column":5}},"124":{"start":{"line":125,"column":0},"end":{"line":125,"column":9}},"125":{"start":{"line":126,"column":0},"end":{"line":126,"column":18}},"126":{"start":{"line":127,"column":0},"end":{"line":127,"column":38}},"127":{"start":{"line":128,"column":0},"end":{"line":128,"column":5}},"128":{"start":{"line":129,"column":0},"end":{"line":129,"column":32}},"129":{"start":{"line":130,"column":0},"end":{"line":130,"column":5}},"130":{"start":{"line":131,"column":0},"end":{"line":131,"column":137}},"131":{"start":{"line":132,"column":0},"end":{"line":132,"column":42}},"132":{"start":{"line":133,"column":0},"end":{"line":133,"column":0}},"133":{"start":{"line":134,"column":0},"end":{"line":134,"column":65}},"134":{"start":{"line":135,"column":0},"end":{"line":135,"column":101}},"135":{"start":{"line":136,"column":0},"end":{"line":136,"column":0}},"136":{"start":{"line":137,"column":0},"end":{"line":137,"column":26}},"137":{"start":{"line":138,"column":0},"end":{"line":138,"column":49}},"138":{"start":{"line":139,"column":0},"end":{"line":139,"column":52}},"139":{"start":{"line":140,"column":0},"end":{"line":140,"column":0}},"140":{"start":{"line":141,"column":0},"end":{"line":141,"column":45}},"141":{"start":{"line":142,"column":0},"end":{"line":142,"column":62}},"142":{"start":{"line":143,"column":0},"end":{"line":143,"column":0}},"143":{"start":{"line":144,"column":0},"end":{"line":144,"column":20}},"144":{"start":{"line":145,"column":0},"end":{"line":145,"column":23}},"145":{"start":{"line":146,"column":0},"end":{"line":146,"column":53}},"146":{"start":{"line":147,"column":0},"end":{"line":147,"column":14}},"147":{"start":{"line":148,"column":0},"end":{"line":148,"column":18}},"148":{"start":{"line":149,"column":0},"end":{"line":149,"column":110}},"149":{"start":{"line":150,"column":0},"end":{"line":150,"column":46}},"150":{"start":{"line":151,"column":0},"end":{"line":151,"column":8}},"151":{"start":{"line":152,"column":0},"end":{"line":152,"column":31}},"152":{"start":{"line":153,"column":0},"end":{"line":153,"column":46}},"153":{"start":{"line":154,"column":0},"end":{"line":154,"column":8}},"154":{"start":{"line":155,"column":0},"end":{"line":155,"column":47}},"155":{"start":{"line":156,"column":0},"end":{"line":156,"column":36}},"156":{"start":{"line":157,"column":0},"end":{"line":157,"column":87}},"157":{"start":{"line":158,"column":0},"end":{"line":158,"column":53}},"158":{"start":{"line":159,"column":0},"end":{"line":159,"column":39}},"159":{"start":{"line":160,"column":0},"end":{"line":160,"column":60}},"160":{"start":{"line":161,"column":0},"end":{"line":161,"column":9}},"161":{"start":{"line":162,"column":0},"end":{"line":162,"column":8}},"162":{"start":{"line":163,"column":0},"end":{"line":163,"column":27}},"163":{"start":{"line":164,"column":0},"end":{"line":164,"column":7}},"164":{"start":{"line":165,"column":0},"end":{"line":165,"column":5}},"165":{"start":{"line":166,"column":0},"end":{"line":166,"column":0}},"166":{"start":{"line":167,"column":0},"end":{"line":167,"column":18}},"167":{"start":{"line":168,"column":0},"end":{"line":168,"column":3}},"168":{"start":{"line":169,"column":0},"end":{"line":169,"column":0}},"169":{"start":{"line":170,"column":0},"end":{"line":170,"column":5}},"170":{"start":{"line":171,"column":0},"end":{"line":171,"column":15}},"171":{"start":{"line":172,"column":0},"end":{"line":172,"column":5}},"172":{"start":{"line":173,"column":0},"end":{"line":173,"column":77}},"173":{"start":{"line":174,"column":0},"end":{"line":174,"column":39}},"174":{"start":{"line":175,"column":0},"end":{"line":175,"column":0}},"175":{"start":{"line":176,"column":0},"end":{"line":176,"column":33}},"176":{"start":{"line":177,"column":0},"end":{"line":177,"column":45}},"177":{"start":{"line":178,"column":0},"end":{"line":178,"column":0}},"178":{"start":{"line":179,"column":0},"end":{"line":179,"column":28}},"179":{"start":{"line":180,"column":0},"end":{"line":180,"column":29}},"180":{"start":{"line":181,"column":0},"end":{"line":181,"column":81}},"181":{"start":{"line":182,"column":0},"end":{"line":182,"column":27}},"182":{"start":{"line":183,"column":0},"end":{"line":183,"column":42}},"183":{"start":{"line":184,"column":0},"end":{"line":184,"column":7}},"184":{"start":{"line":185,"column":0},"end":{"line":185,"column":5}},"185":{"start":{"line":186,"column":0},"end":{"line":186,"column":0}},"186":{"start":{"line":187,"column":0},"end":{"line":187,"column":32}},"187":{"start":{"line":188,"column":0},"end":{"line":188,"column":33}},"188":{"start":{"line":189,"column":0},"end":{"line":189,"column":85}},"189":{"start":{"line":190,"column":0},"end":{"line":190,"column":23}},"190":{"start":{"line":191,"column":0},"end":{"line":191,"column":50}},"191":{"start":{"line":192,"column":0},"end":{"line":192,"column":7}},"192":{"start":{"line":193,"column":0},"end":{"line":193,"column":5}},"193":{"start":{"line":194,"column":0},"end":{"line":194,"column":0}},"194":{"start":{"line":195,"column":0},"end":{"line":195,"column":25}},"195":{"start":{"line":196,"column":0},"end":{"line":196,"column":26}},"196":{"start":{"line":197,"column":0},"end":{"line":197,"column":44}},"197":{"start":{"line":198,"column":0},"end":{"line":198,"column":66}},"198":{"start":{"line":199,"column":0},"end":{"line":199,"column":8}},"199":{"start":{"line":200,"column":0},"end":{"line":200,"column":24}},"200":{"start":{"line":201,"column":0},"end":{"line":201,"column":36}},"201":{"start":{"line":202,"column":0},"end":{"line":202,"column":7}},"202":{"start":{"line":203,"column":0},"end":{"line":203,"column":5}},"203":{"start":{"line":204,"column":0},"end":{"line":204,"column":0}},"204":{"start":{"line":205,"column":0},"end":{"line":205,"column":23}},"205":{"start":{"line":206,"column":0},"end":{"line":206,"column":76}},"206":{"start":{"line":207,"column":0},"end":{"line":207,"column":19}},"207":{"start":{"line":208,"column":0},"end":{"line":208,"column":26}},"208":{"start":{"line":209,"column":0},"end":{"line":209,"column":5}},"209":{"start":{"line":210,"column":0},"end":{"line":210,"column":0}},"210":{"start":{"line":211,"column":0},"end":{"line":211,"column":16}},"211":{"start":{"line":212,"column":0},"end":{"line":212,"column":3}},"212":{"start":{"line":213,"column":0},"end":{"line":213,"column":0}},"213":{"start":{"line":214,"column":0},"end":{"line":214,"column":5}},"214":{"start":{"line":215,"column":0},"end":{"line":215,"column":18}},"215":{"start":{"line":216,"column":0},"end":{"line":216,"column":5}},"216":{"start":{"line":217,"column":0},"end":{"line":217,"column":105}},"217":{"start":{"line":218,"column":0},"end":{"line":218,"column":59}},"218":{"start":{"line":219,"column":0},"end":{"line":219,"column":0}},"219":{"start":{"line":220,"column":0},"end":{"line":220,"column":15}},"220":{"start":{"line":221,"column":0},"end":{"line":221,"column":60}},"221":{"start":{"line":222,"column":0},"end":{"line":222,"column":30}},"222":{"start":{"line":223,"column":0},"end":{"line":223,"column":5}},"223":{"start":{"line":224,"column":0},"end":{"line":224,"column":72}},"224":{"start":{"line":225,"column":0},"end":{"line":225,"column":34}},"225":{"start":{"line":226,"column":0},"end":{"line":226,"column":5}},"226":{"start":{"line":227,"column":0},"end":{"line":227,"column":83}},"227":{"start":{"line":228,"column":0},"end":{"line":228,"column":27}},"228":{"start":{"line":229,"column":0},"end":{"line":229,"column":5}},"229":{"start":{"line":230,"column":0},"end":{"line":230,"column":19}},"230":{"start":{"line":231,"column":0},"end":{"line":231,"column":26}},"231":{"start":{"line":232,"column":0},"end":{"line":232,"column":5}},"232":{"start":{"line":233,"column":0},"end":{"line":233,"column":0}},"233":{"start":{"line":234,"column":0},"end":{"line":234,"column":20}},"234":{"start":{"line":235,"column":0},"end":{"line":235,"column":3}},"235":{"start":{"line":236,"column":0},"end":{"line":236,"column":0}},"236":{"start":{"line":237,"column":0},"end":{"line":237,"column":55}},"237":{"start":{"line":238,"column":0},"end":{"line":238,"column":25}},"238":{"start":{"line":239,"column":0},"end":{"line":239,"column":19}},"239":{"start":{"line":240,"column":0},"end":{"line":240,"column":23}},"240":{"start":{"line":241,"column":0},"end":{"line":241,"column":14}},"241":{"start":{"line":242,"column":0},"end":{"line":242,"column":26}},"242":{"start":{"line":243,"column":0},"end":{"line":243,"column":5}},"243":{"start":{"line":244,"column":0},"end":{"line":244,"column":3}},"244":{"start":{"line":245,"column":0},"end":{"line":245,"column":0}},"245":{"start":{"line":246,"column":0},"end":{"line":246,"column":76}},"246":{"start":{"line":247,"column":0},"end":{"line":247,"column":41}},"247":{"start":{"line":248,"column":0},"end":{"line":248,"column":0}},"248":{"start":{"line":249,"column":0},"end":{"line":249,"column":31}},"249":{"start":{"line":250,"column":0},"end":{"line":250,"column":11}},"250":{"start":{"line":251,"column":0},"end":{"line":251,"column":81}},"251":{"start":{"line":252,"column":0},"end":{"line":252,"column":56}},"252":{"start":{"line":253,"column":0},"end":{"line":253,"column":28}},"253":{"start":{"line":254,"column":0},"end":{"line":254,"column":15}},"254":{"start":{"line":255,"column":0},"end":{"line":255,"column":42}},"255":{"start":{"line":256,"column":0},"end":{"line":256,"column":7}},"256":{"start":{"line":257,"column":0},"end":{"line":257,"column":5}},"257":{"start":{"line":258,"column":0},"end":{"line":258,"column":0}},"258":{"start":{"line":259,"column":0},"end":{"line":259,"column":38}},"259":{"start":{"line":260,"column":0},"end":{"line":260,"column":11}},"260":{"start":{"line":261,"column":0},"end":{"line":261,"column":49}},"261":{"start":{"line":262,"column":0},"end":{"line":262,"column":70}},"262":{"start":{"line":263,"column":0},"end":{"line":263,"column":43}},"263":{"start":{"line":264,"column":0},"end":{"line":264,"column":25}},"264":{"start":{"line":265,"column":0},"end":{"line":265,"column":15}},"265":{"start":{"line":266,"column":0},"end":{"line":266,"column":20}},"266":{"start":{"line":267,"column":0},"end":{"line":267,"column":60}},"267":{"start":{"line":268,"column":0},"end":{"line":268,"column":12}},"268":{"start":{"line":269,"column":0},"end":{"line":269,"column":26}},"269":{"start":{"line":270,"column":0},"end":{"line":270,"column":36}},"270":{"start":{"line":271,"column":0},"end":{"line":271,"column":11}},"271":{"start":{"line":272,"column":0},"end":{"line":272,"column":32}},"272":{"start":{"line":273,"column":0},"end":{"line":273,"column":32}},"273":{"start":{"line":274,"column":0},"end":{"line":274,"column":87}},"274":{"start":{"line":275,"column":0},"end":{"line":275,"column":37}},"275":{"start":{"line":276,"column":0},"end":{"line":276,"column":18}},"276":{"start":{"line":277,"column":0},"end":{"line":277,"column":19}},"277":{"start":{"line":278,"column":0},"end":{"line":278,"column":16}},"278":{"start":{"line":279,"column":0},"end":{"line":279,"column":7}},"279":{"start":{"line":280,"column":0},"end":{"line":280,"column":5}},"280":{"start":{"line":281,"column":0},"end":{"line":281,"column":0}},"281":{"start":{"line":282,"column":0},"end":{"line":282,"column":48}},"282":{"start":{"line":283,"column":0},"end":{"line":283,"column":47}},"283":{"start":{"line":284,"column":0},"end":{"line":284,"column":41}},"284":{"start":{"line":285,"column":0},"end":{"line":285,"column":39}},"285":{"start":{"line":286,"column":0},"end":{"line":286,"column":78}},"286":{"start":{"line":287,"column":0},"end":{"line":287,"column":28}},"287":{"start":{"line":288,"column":0},"end":{"line":288,"column":28}},"288":{"start":{"line":289,"column":0},"end":{"line":289,"column":54}},"289":{"start":{"line":290,"column":0},"end":{"line":290,"column":22}},"290":{"start":{"line":291,"column":0},"end":{"line":291,"column":18}},"291":{"start":{"line":292,"column":0},"end":{"line":292,"column":86}},"292":{"start":{"line":293,"column":0},"end":{"line":293,"column":36}},"293":{"start":{"line":294,"column":0},"end":{"line":294,"column":24}},"294":{"start":{"line":295,"column":0},"end":{"line":295,"column":11}},"295":{"start":{"line":296,"column":0},"end":{"line":296,"column":10}},"296":{"start":{"line":297,"column":0},"end":{"line":297,"column":63}},"297":{"start":{"line":298,"column":0},"end":{"line":298,"column":67}},"298":{"start":{"line":299,"column":0},"end":{"line":299,"column":23}},"299":{"start":{"line":300,"column":0},"end":{"line":300,"column":9}},"300":{"start":{"line":301,"column":0},"end":{"line":301,"column":5}},"301":{"start":{"line":302,"column":0},"end":{"line":302,"column":0}},"302":{"start":{"line":303,"column":0},"end":{"line":303,"column":46}},"303":{"start":{"line":304,"column":0},"end":{"line":304,"column":3}},"304":{"start":{"line":305,"column":0},"end":{"line":305,"column":0}},"305":{"start":{"line":306,"column":0},"end":{"line":306,"column":43}},"306":{"start":{"line":307,"column":0},"end":{"line":307,"column":41}},"307":{"start":{"line":308,"column":0},"end":{"line":308,"column":0}},"308":{"start":{"line":309,"column":0},"end":{"line":309,"column":31}},"309":{"start":{"line":310,"column":0},"end":{"line":310,"column":11}},"310":{"start":{"line":311,"column":0},"end":{"line":311,"column":81}},"311":{"start":{"line":312,"column":0},"end":{"line":312,"column":47}},"312":{"start":{"line":313,"column":0},"end":{"line":313,"column":15}},"313":{"start":{"line":314,"column":0},"end":{"line":314,"column":21}},"314":{"start":{"line":315,"column":0},"end":{"line":315,"column":7}},"315":{"start":{"line":316,"column":0},"end":{"line":316,"column":5}},"316":{"start":{"line":317,"column":0},"end":{"line":317,"column":0}},"317":{"start":{"line":318,"column":0},"end":{"line":318,"column":48}},"318":{"start":{"line":319,"column":0},"end":{"line":319,"column":11}},"319":{"start":{"line":320,"column":0},"end":{"line":320,"column":41}},"320":{"start":{"line":321,"column":0},"end":{"line":321,"column":37}},"321":{"start":{"line":322,"column":0},"end":{"line":322,"column":78}},"322":{"start":{"line":323,"column":0},"end":{"line":323,"column":23}},"323":{"start":{"line":324,"column":0},"end":{"line":324,"column":53}},"324":{"start":{"line":325,"column":0},"end":{"line":325,"column":15}},"325":{"start":{"line":326,"column":0},"end":{"line":326,"column":21}},"326":{"start":{"line":327,"column":0},"end":{"line":327,"column":7}},"327":{"start":{"line":328,"column":0},"end":{"line":328,"column":5}},"328":{"start":{"line":329,"column":0},"end":{"line":329,"column":0}},"329":{"start":{"line":330,"column":0},"end":{"line":330,"column":17}},"330":{"start":{"line":331,"column":0},"end":{"line":331,"column":3}},"331":{"start":{"line":332,"column":0},"end":{"line":332,"column":0}},"332":{"start":{"line":333,"column":0},"end":{"line":333,"column":47}},"333":{"start":{"line":334,"column":0},"end":{"line":334,"column":9}},"334":{"start":{"line":335,"column":0},"end":{"line":335,"column":43}},"335":{"start":{"line":336,"column":0},"end":{"line":336,"column":30}},"336":{"start":{"line":337,"column":0},"end":{"line":337,"column":53}},"337":{"start":{"line":338,"column":0},"end":{"line":338,"column":54}},"338":{"start":{"line":339,"column":0},"end":{"line":339,"column":78}},"339":{"start":{"line":340,"column":0},"end":{"line":340,"column":18}},"340":{"start":{"line":341,"column":0},"end":{"line":341,"column":13}},"341":{"start":{"line":342,"column":0},"end":{"line":342,"column":19}},"342":{"start":{"line":343,"column":0},"end":{"line":343,"column":5}},"343":{"start":{"line":344,"column":0},"end":{"line":344,"column":3}},"344":{"start":{"line":345,"column":0},"end":{"line":345,"column":0}},"345":{"start":{"line":346,"column":0},"end":{"line":346,"column":44}},"346":{"start":{"line":347,"column":0},"end":{"line":347,"column":59}},"347":{"start":{"line":348,"column":0},"end":{"line":348,"column":3}},"348":{"start":{"line":349,"column":0},"end":{"line":349,"column":1}}},"s":{"0":1,"1":1,"2":1,"3":1,"4":1,"5":1,"6":1,"7":1,"8":1,"9":1,"10":1,"11":1,"12":1,"13":0,"14":0,"15":0,"16":0,"17":1,"18":1,"19":0,"20":0,"21":0,"22":0,"23":0,"24":0,"25":0,"26":0,"27":0,"28":0,"29":0,"30":0,"31":0,"32":0,"33":0,"34":0,"35":0,"36":0,"37":0,"38":0,"39":0,"40":0,"41":0,"42":0,"43":0,"44":0,"45":0,"46":0,"47":0,"48":0,"49":0,"50":0,"51":0,"52":0,"53":0,"54":1,"55":1,"56":0,"57":0,"58":0,"59":0,"60":0,"61":0,"62":0,"63":0,"64":0,"65":0,"66":0,"67":0,"68":0,"69":1,"70":1,"71":1,"72":1,"73":1,"74":1,"75":1,"76":1,"77":1,"78":1,"79":0,"80":0,"81":0,"82":0,"83":0,"84":0,"85":0,"86":0,"87":0,"88":0,"89":0,"90":0,"91":0,"92":0,"93":0,"94":0,"95":0,"96":0,"97":0,"98":0,"99":0,"100":0,"101":0,"102":0,"103":0,"104":0,"105":0,"106":0,"107":0,"108":0,"109":0,"110":0,"111":0,"112":0,"113":0,"114":0,"115":0,"116":0,"117":0,"118":0,"119":0,"120":1,"121":1,"122":1,"123":1,"124":1,"125":1,"126":1,"127":1,"128":1,"129":1,"130":1,"131":0,"132":0,"133":0,"134":0,"135":0,"136":0,"137":0,"138":0,"139":0,"140":0,"141":0,"142":0,"143":0,"144":0,"145":0,"146":0,"147":0,"148":0,"149":0,"150":0,"151":0,"152":0,"153":0,"154":0,"155":0,"156":0,"157":0,"158":0,"159":0,"160":0,"161":0,"162":0,"163":0,"164":0,"165":0,"166":0,"167":0,"168":1,"169":1,"170":1,"171":1,"172":1,"173":0,"174":0,"175":0,"176":0,"177":0,"178":0,"179":0,"180":0,"181":0,"182":0,"183":0,"184":0,"185":0,"186":0,"187":0,"188":0,"189":0,"190":0,"191":0,"192":0,"193":0,"194":0,"195":0,"196":0,"197":0,"198":0,"199":0,"200":0,"201":0,"202":0,"203":0,"204":0,"205":0,"206":0,"207":0,"208":0,"209":0,"210":0,"211":0,"212":1,"213":1,"214":1,"215":1,"216":1,"217":0,"218":0,"219":0,"220":0,"221":0,"222":0,"223":0,"224":0,"225":0,"226":0,"227":0,"228":0,"229":0,"230":0,"231":0,"232":0,"233":0,"234":0,"235":1,"236":1,"237":0,"238":0,"239":0,"240":0,"241":0,"242":0,"243":0,"244":1,"245":1,"246":0,"247":0,"248":0,"249":0,"250":0,"251":0,"252":0,"253":0,"254":0,"255":0,"256":0,"257":0,"258":0,"259":0,"260":0,"261":0,"262":0,"263":0,"264":0,"265":0,"266":0,"267":0,"268":0,"269":0,"270":0,"271":0,"272":0,"273":0,"274":0,"275":0,"276":0,"277":0,"278":0,"279":0,"280":0,"281":0,"282":0,"283":0,"284":0,"285":0,"286":0,"287":0,"288":0,"289":0,"290":0,"291":0,"292":0,"293":0,"294":0,"295":0,"296":0,"297":0,"298":0,"299":0,"300":0,"301":0,"302":0,"303":0,"304":1,"305":1,"306":0,"307":0,"308":0,"309":0,"310":0,"311":0,"312":0,"313":0,"314":0,"315":0,"316":0,"317":0,"318":0,"319":0,"320":0,"321":0,"322":0,"323":0,"324":0,"325":0,"326":0,"327":0,"328":0,"329":0,"330":0,"331":1,"332":1,"333":0,"334":0,"335":0,"336":0,"337":0,"338":0,"339":0,"340":0,"341":0,"342":0,"343":0,"344":1,"345":1,"346":0,"347":0,"348":1},"branchMap":{},"b":{},"fnMap":{"0":{"name":"Reporter","decl":{"start":{"line":13,"column":2},"end":{"line":17,"column":3}},"loc":{"start":{"line":13,"column":2},"end":{"line":17,"column":3}},"line":13},"1":{"name":"report","decl":{"start":{"line":19,"column":2},"end":{"line":54,"column":3}},"loc":{"start":{"line":19,"column":2},"end":{"line":54,"column":3}},"line":19},"2":{"name":"reportSync","decl":{"start":{"line":56,"column":2},"end":{"line":69,"column":3}},"loc":{"start":{"line":56,"column":2},"end":{"line":69,"column":3}},"line":56},"3":{"name":"buildEnvelope","decl":{"start":{"line":79,"column":10},"end":{"line":120,"column":3}},"loc":{"start":{"line":79,"column":10},"end":{"line":120,"column":3}},"line":79},"4":{"name":"applyRelativeTimestamps","decl":{"start":{"line":131,"column":10},"end":{"line":168,"column":3}},"loc":{"start":{"line":131,"column":10},"end":{"line":168,"column":3}},"line":131},"5":{"name":"extractSharedMeta","decl":{"start":{"line":173,"column":10},"end":{"line":212,"column":3}},"loc":{"start":{"line":173,"column":10},"end":{"line":212,"column":3}},"line":173},"6":{"name":"stripSharedFields","decl":{"start":{"line":217,"column":10},"end":{"line":235,"column":3}},"loc":{"start":{"line":217,"column":10},"end":{"line":235,"column":3}},"line":217},"7":{"name":"getEnvelopeType","decl":{"start":{"line":237,"column":10},"end":{"line":244,"column":3}},"loc":{"start":{"line":237,"column":10},"end":{"line":244,"column":3}},"line":237},"8":{"name":"send","decl":{"start":{"line":246,"column":2},"end":{"line":304,"column":3}},"loc":{"start":{"line":246,"column":2},"end":{"line":304,"column":3}},"line":246},"9":{"name":"sendSync","decl":{"start":{"line":306,"column":10},"end":{"line":331,"column":3}},"loc":{"start":{"line":306,"column":10},"end":{"line":331,"column":3}},"line":306},"10":{"name":"sendViaImage","decl":{"start":{"line":333,"column":10},"end":{"line":344,"column":3}},"loc":{"start":{"line":333,"column":10},"end":{"line":344,"column":3}},"line":333},"11":{"name":"delay","decl":{"start":{"line":346,"column":10},"end":{"line":348,"column":3}},"loc":{"start":{"line":346,"column":10},"end":{"line":348,"column":3}},"line":346}},"f":{"0":0,"1":0,"2":0,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10":0,"11":0}} +,"/Users/weidingjian/Desktop/work/ai/light-sentry-sdk/src/core/TracingManager.ts": {"path":"/Users/weidingjian/Desktop/work/ai/light-sentry-sdk/src/core/TracingManager.ts","all":false,"statementMap":{"0":{"start":{"line":1,"column":0},"end":{"line":1,"column":126}},"1":{"start":{"line":2,"column":0},"end":{"line":2,"column":84}},"2":{"start":{"line":3,"column":0},"end":{"line":3,"column":43}},"3":{"start":{"line":4,"column":0},"end":{"line":4,"column":0}},"4":{"start":{"line":5,"column":0},"end":{"line":5,"column":29}},"5":{"start":{"line":6,"column":0},"end":{"line":6,"column":30}},"6":{"start":{"line":7,"column":0},"end":{"line":7,"column":32}},"7":{"start":{"line":8,"column":0},"end":{"line":8,"column":56}},"8":{"start":{"line":9,"column":0},"end":{"line":9,"column":33}},"9":{"start":{"line":10,"column":0},"end":{"line":10,"column":32}},"10":{"start":{"line":11,"column":0},"end":{"line":11,"column":0}},"11":{"start":{"line":12,"column":0},"end":{"line":12,"column":81}},"12":{"start":{"line":13,"column":0},"end":{"line":13,"column":25}},"13":{"start":{"line":14,"column":0},"end":{"line":14,"column":26}},"14":{"start":{"line":15,"column":0},"end":{"line":15,"column":37}},"15":{"start":{"line":16,"column":0},"end":{"line":16,"column":3}},"16":{"start":{"line":17,"column":0},"end":{"line":17,"column":0}},"17":{"start":{"line":18,"column":0},"end":{"line":18,"column":43}},"18":{"start":{"line":19,"column":0},"end":{"line":19,"column":25}},"19":{"start":{"line":20,"column":0},"end":{"line":20,"column":34}},"20":{"start":{"line":21,"column":0},"end":{"line":21,"column":75}},"21":{"start":{"line":22,"column":0},"end":{"line":22,"column":105}},"22":{"start":{"line":23,"column":0},"end":{"line":23,"column":5}},"23":{"start":{"line":24,"column":0},"end":{"line":24,"column":3}},"24":{"start":{"line":25,"column":0},"end":{"line":25,"column":0}},"25":{"start":{"line":26,"column":0},"end":{"line":26,"column":87}},"26":{"start":{"line":27,"column":0},"end":{"line":27,"column":46}},"27":{"start":{"line":28,"column":0},"end":{"line":28,"column":18}},"28":{"start":{"line":29,"column":0},"end":{"line":29,"column":48}},"29":{"start":{"line":30,"column":0},"end":{"line":30,"column":19}},"30":{"start":{"line":31,"column":0},"end":{"line":31,"column":22}},"31":{"start":{"line":32,"column":0},"end":{"line":32,"column":8}},"32":{"start":{"line":33,"column":0},"end":{"line":33,"column":46}},"33":{"start":{"line":34,"column":0},"end":{"line":34,"column":40}},"34":{"start":{"line":35,"column":0},"end":{"line":35,"column":22}},"35":{"start":{"line":36,"column":0},"end":{"line":36,"column":7}},"36":{"start":{"line":37,"column":0},"end":{"line":37,"column":59}},"37":{"start":{"line":38,"column":0},"end":{"line":38,"column":42}},"38":{"start":{"line":39,"column":0},"end":{"line":39,"column":41}},"39":{"start":{"line":40,"column":0},"end":{"line":40,"column":41}},"40":{"start":{"line":41,"column":0},"end":{"line":41,"column":5}},"41":{"start":{"line":42,"column":0},"end":{"line":42,"column":0}},"42":{"start":{"line":43,"column":0},"end":{"line":43,"column":51}},"43":{"start":{"line":44,"column":0},"end":{"line":44,"column":31}},"44":{"start":{"line":45,"column":0},"end":{"line":45,"column":32}},"45":{"start":{"line":46,"column":0},"end":{"line":46,"column":32}},"46":{"start":{"line":47,"column":0},"end":{"line":47,"column":3}},"47":{"start":{"line":48,"column":0},"end":{"line":48,"column":0}},"48":{"start":{"line":49,"column":0},"end":{"line":49,"column":69}},"49":{"start":{"line":50,"column":0},"end":{"line":50,"column":45}},"50":{"start":{"line":51,"column":0},"end":{"line":51,"column":66}},"51":{"start":{"line":52,"column":0},"end":{"line":52,"column":0}},"52":{"start":{"line":53,"column":0},"end":{"line":53,"column":81}},"53":{"start":{"line":54,"column":0},"end":{"line":54,"column":0}},"54":{"start":{"line":55,"column":0},"end":{"line":55,"column":44}},"55":{"start":{"line":56,"column":0},"end":{"line":56,"column":7}},"56":{"start":{"line":57,"column":0},"end":{"line":57,"column":19}},"57":{"start":{"line":58,"column":0},"end":{"line":58,"column":16}},"58":{"start":{"line":59,"column":0},"end":{"line":59,"column":8}},"59":{"start":{"line":60,"column":0},"end":{"line":60,"column":19}},"60":{"start":{"line":61,"column":0},"end":{"line":61,"column":24}},"61":{"start":{"line":62,"column":0},"end":{"line":62,"column":26}},"62":{"start":{"line":63,"column":0},"end":{"line":63,"column":29}},"63":{"start":{"line":64,"column":0},"end":{"line":64,"column":32}},"64":{"start":{"line":65,"column":0},"end":{"line":65,"column":0}},"65":{"start":{"line":66,"column":0},"end":{"line":66,"column":42}},"66":{"start":{"line":67,"column":0},"end":{"line":67,"column":35}},"67":{"start":{"line":68,"column":0},"end":{"line":68,"column":0}},"68":{"start":{"line":69,"column":0},"end":{"line":69,"column":55}},"69":{"start":{"line":70,"column":0},"end":{"line":70,"column":29}},"70":{"start":{"line":71,"column":0},"end":{"line":71,"column":35}},"71":{"start":{"line":72,"column":0},"end":{"line":72,"column":33}},"72":{"start":{"line":73,"column":0},"end":{"line":73,"column":14}},"73":{"start":{"line":74,"column":0},"end":{"line":74,"column":25}},"74":{"start":{"line":75,"column":0},"end":{"line":75,"column":7}},"75":{"start":{"line":76,"column":0},"end":{"line":76,"column":0}},"76":{"start":{"line":77,"column":0},"end":{"line":77,"column":23}},"77":{"start":{"line":78,"column":0},"end":{"line":78,"column":3}},"78":{"start":{"line":79,"column":0},"end":{"line":79,"column":0}},"79":{"start":{"line":80,"column":0},"end":{"line":80,"column":47}},"80":{"start":{"line":81,"column":0},"end":{"line":81,"column":35}},"81":{"start":{"line":82,"column":0},"end":{"line":82,"column":3}},"82":{"start":{"line":83,"column":0},"end":{"line":83,"column":0}},"83":{"start":{"line":84,"column":0},"end":{"line":84,"column":64}},"84":{"start":{"line":85,"column":0},"end":{"line":85,"column":42}},"85":{"start":{"line":86,"column":0},"end":{"line":86,"column":23}},"86":{"start":{"line":87,"column":0},"end":{"line":87,"column":26}},"87":{"start":{"line":88,"column":0},"end":{"line":88,"column":12}},"88":{"start":{"line":89,"column":0},"end":{"line":89,"column":37}},"89":{"start":{"line":90,"column":0},"end":{"line":90,"column":5}},"90":{"start":{"line":91,"column":0},"end":{"line":91,"column":3}},"91":{"start":{"line":92,"column":0},"end":{"line":92,"column":0}},"92":{"start":{"line":93,"column":0},"end":{"line":93,"column":33}},"93":{"start":{"line":94,"column":0},"end":{"line":94,"column":88}},"94":{"start":{"line":95,"column":0},"end":{"line":95,"column":3}},"95":{"start":{"line":96,"column":0},"end":{"line":96,"column":0}},"96":{"start":{"line":97,"column":0},"end":{"line":97,"column":43}},"97":{"start":{"line":98,"column":0},"end":{"line":98,"column":24}},"98":{"start":{"line":99,"column":0},"end":{"line":99,"column":38}},"99":{"start":{"line":100,"column":0},"end":{"line":100,"column":29}},"100":{"start":{"line":101,"column":0},"end":{"line":101,"column":7}},"101":{"start":{"line":102,"column":0},"end":{"line":102,"column":12}},"102":{"start":{"line":103,"column":0},"end":{"line":103,"column":32}},"103":{"start":{"line":104,"column":0},"end":{"line":104,"column":5}},"104":{"start":{"line":105,"column":0},"end":{"line":105,"column":3}},"105":{"start":{"line":106,"column":0},"end":{"line":106,"column":0}},"106":{"start":{"line":107,"column":0},"end":{"line":107,"column":48}},"107":{"start":{"line":108,"column":0},"end":{"line":108,"column":45}},"108":{"start":{"line":109,"column":0},"end":{"line":109,"column":0}},"109":{"start":{"line":110,"column":0},"end":{"line":110,"column":42}},"110":{"start":{"line":111,"column":0},"end":{"line":111,"column":85}},"111":{"start":{"line":112,"column":0},"end":{"line":112,"column":18}},"112":{"start":{"line":113,"column":0},"end":{"line":113,"column":5}},"113":{"start":{"line":114,"column":0},"end":{"line":114,"column":0}},"114":{"start":{"line":115,"column":0},"end":{"line":115,"column":19}},"115":{"start":{"line":116,"column":0},"end":{"line":116,"column":0}},"116":{"start":{"line":117,"column":0},"end":{"line":117,"column":21}},"117":{"start":{"line":118,"column":0},"end":{"line":118,"column":58}},"118":{"start":{"line":119,"column":0},"end":{"line":119,"column":12}},"119":{"start":{"line":120,"column":0},"end":{"line":120,"column":27}},"120":{"start":{"line":121,"column":0},"end":{"line":121,"column":19}},"121":{"start":{"line":122,"column":0},"end":{"line":122,"column":43}},"122":{"start":{"line":123,"column":0},"end":{"line":123,"column":28}},"123":{"start":{"line":124,"column":0},"end":{"line":124,"column":0}},"124":{"start":{"line":125,"column":0},"end":{"line":125,"column":36}},"125":{"start":{"line":126,"column":0},"end":{"line":126,"column":56}},"126":{"start":{"line":127,"column":0},"end":{"line":127,"column":104}},"127":{"start":{"line":128,"column":0},"end":{"line":128,"column":9}},"128":{"start":{"line":129,"column":0},"end":{"line":129,"column":96}},"129":{"start":{"line":130,"column":0},"end":{"line":130,"column":7}},"130":{"start":{"line":131,"column":0},"end":{"line":131,"column":5}},"131":{"start":{"line":132,"column":0},"end":{"line":132,"column":0}},"132":{"start":{"line":133,"column":0},"end":{"line":133,"column":30}},"133":{"start":{"line":134,"column":0},"end":{"line":134,"column":0}},"134":{"start":{"line":135,"column":0},"end":{"line":135,"column":48}},"135":{"start":{"line":136,"column":0},"end":{"line":136,"column":18}},"136":{"start":{"line":137,"column":0},"end":{"line":137,"column":36}},"137":{"start":{"line":138,"column":0},"end":{"line":138,"column":26}},"138":{"start":{"line":139,"column":0},"end":{"line":139,"column":38}},"139":{"start":{"line":140,"column":0},"end":{"line":140,"column":40}},"140":{"start":{"line":141,"column":0},"end":{"line":141,"column":7}},"141":{"start":{"line":142,"column":0},"end":{"line":142,"column":0}},"142":{"start":{"line":143,"column":0},"end":{"line":143,"column":16}},"143":{"start":{"line":144,"column":0},"end":{"line":144,"column":3}},"144":{"start":{"line":145,"column":0},"end":{"line":145,"column":0}},"145":{"start":{"line":146,"column":0},"end":{"line":146,"column":36}},"146":{"start":{"line":147,"column":0},"end":{"line":147,"column":49}},"147":{"start":{"line":148,"column":0},"end":{"line":148,"column":21}},"148":{"start":{"line":149,"column":0},"end":{"line":149,"column":36}},"149":{"start":{"line":150,"column":0},"end":{"line":150,"column":5}},"150":{"start":{"line":151,"column":0},"end":{"line":151,"column":0}},"151":{"start":{"line":152,"column":0},"end":{"line":152,"column":65}},"152":{"start":{"line":153,"column":0},"end":{"line":153,"column":49}},"153":{"start":{"line":154,"column":0},"end":{"line":154,"column":5}},"154":{"start":{"line":155,"column":0},"end":{"line":155,"column":0}},"155":{"start":{"line":156,"column":0},"end":{"line":156,"column":49}},"156":{"start":{"line":157,"column":0},"end":{"line":157,"column":18}},"157":{"start":{"line":158,"column":0},"end":{"line":158,"column":36}},"158":{"start":{"line":159,"column":0},"end":{"line":159,"column":26}},"159":{"start":{"line":160,"column":0},"end":{"line":160,"column":40}},"160":{"start":{"line":161,"column":0},"end":{"line":161,"column":7}},"161":{"start":{"line":162,"column":0},"end":{"line":162,"column":3}},"162":{"start":{"line":163,"column":0},"end":{"line":163,"column":0}},"163":{"start":{"line":164,"column":0},"end":{"line":164,"column":57}},"164":{"start":{"line":165,"column":0},"end":{"line":165,"column":50}},"165":{"start":{"line":166,"column":0},"end":{"line":166,"column":37}},"166":{"start":{"line":167,"column":0},"end":{"line":167,"column":26}},"167":{"start":{"line":168,"column":0},"end":{"line":168,"column":5}},"168":{"start":{"line":169,"column":0},"end":{"line":169,"column":0}},"169":{"start":{"line":170,"column":0},"end":{"line":170,"column":56}},"170":{"start":{"line":171,"column":0},"end":{"line":171,"column":29}},"171":{"start":{"line":172,"column":0},"end":{"line":172,"column":35}},"172":{"start":{"line":173,"column":0},"end":{"line":173,"column":42}},"173":{"start":{"line":174,"column":0},"end":{"line":174,"column":35}},"174":{"start":{"line":175,"column":0},"end":{"line":175,"column":7}},"175":{"start":{"line":176,"column":0},"end":{"line":176,"column":3}},"176":{"start":{"line":177,"column":0},"end":{"line":177,"column":0}},"177":{"start":{"line":178,"column":0},"end":{"line":178,"column":32}},"178":{"start":{"line":179,"column":0},"end":{"line":179,"column":18}},"179":{"start":{"line":180,"column":0},"end":{"line":180,"column":3}},"180":{"start":{"line":181,"column":0},"end":{"line":181,"column":0}},"181":{"start":{"line":182,"column":0},"end":{"line":182,"column":53}},"182":{"start":{"line":183,"column":0},"end":{"line":183,"column":25}},"183":{"start":{"line":184,"column":0},"end":{"line":184,"column":3}},"184":{"start":{"line":185,"column":0},"end":{"line":185,"column":0}},"185":{"start":{"line":186,"column":0},"end":{"line":186,"column":19}},"186":{"start":{"line":187,"column":0},"end":{"line":187,"column":34}},"187":{"start":{"line":188,"column":0},"end":{"line":188,"column":11}},"188":{"start":{"line":189,"column":0},"end":{"line":189,"column":53}},"189":{"start":{"line":190,"column":0},"end":{"line":190,"column":41}},"190":{"start":{"line":191,"column":0},"end":{"line":191,"column":15}},"191":{"start":{"line":192,"column":0},"end":{"line":192,"column":17}},"192":{"start":{"line":193,"column":0},"end":{"line":193,"column":7}},"193":{"start":{"line":194,"column":0},"end":{"line":194,"column":5}},"194":{"start":{"line":195,"column":0},"end":{"line":195,"column":35}},"195":{"start":{"line":196,"column":0},"end":{"line":196,"column":24}},"196":{"start":{"line":197,"column":0},"end":{"line":197,"column":3}},"197":{"start":{"line":198,"column":0},"end":{"line":198,"column":1}}},"s":{"0":1,"1":1,"2":1,"3":1,"4":1,"5":1,"6":1,"7":1,"8":1,"9":1,"10":1,"11":1,"12":29,"13":29,"14":29,"15":29,"16":1,"17":1,"18":1,"19":1,"20":1,"21":1,"22":1,"23":1,"24":1,"25":1,"26":19,"27":19,"28":2,"29":2,"30":2,"31":2,"32":2,"33":2,"34":2,"35":2,"36":0,"37":0,"38":0,"39":0,"40":0,"41":17,"42":19,"43":19,"44":2,"45":0,"46":19,"47":1,"48":1,"49":20,"50":20,"51":20,"52":20,"53":20,"54":20,"55":20,"56":20,"57":20,"58":20,"59":20,"60":20,"61":20,"62":20,"63":20,"64":20,"65":20,"66":20,"67":20,"68":20,"69":20,"70":20,"71":20,"72":20,"73":20,"74":20,"75":20,"76":20,"77":20,"78":1,"79":1,"80":8,"81":8,"82":1,"83":1,"84":0,"85":0,"86":0,"87":0,"88":0,"89":0,"90":0,"91":1,"92":1,"93":16,"94":16,"95":1,"96":1,"97":2,"98":1,"99":1,"100":1,"101":1,"102":1,"103":1,"104":2,"105":1,"106":1,"107":8,"108":8,"109":8,"110":1,"111":1,"112":1,"113":7,"114":7,"115":7,"116":8,"117":6,"118":8,"119":1,"120":1,"121":1,"122":1,"123":1,"124":1,"125":0,"126":0,"127":0,"128":0,"129":0,"130":1,"131":7,"132":7,"133":7,"134":7,"135":7,"136":7,"137":7,"138":7,"139":7,"140":7,"141":7,"142":7,"143":8,"144":1,"145":1,"146":1,"147":1,"148":1,"149":1,"150":1,"151":1,"152":0,"153":0,"154":1,"155":1,"156":1,"157":1,"158":1,"159":1,"160":1,"161":1,"162":1,"163":1,"164":2,"165":2,"166":2,"167":2,"168":2,"169":2,"170":2,"171":2,"172":2,"173":2,"174":2,"175":2,"176":1,"177":1,"178":0,"179":0,"180":1,"181":1,"182":0,"183":0,"184":1,"185":1,"186":31,"187":17,"188":17,"189":17,"190":17,"191":0,"192":0,"193":17,"194":31,"195":31,"196":31,"197":1},"branchMap":{"0":{"type":"branch","line":12,"loc":{"start":{"line":12,"column":2},"end":{"line":16,"column":3}},"locations":[{"start":{"line":12,"column":2},"end":{"line":16,"column":3}}]},"1":{"type":"branch","line":18,"loc":{"start":{"line":18,"column":2},"end":{"line":24,"column":3}},"locations":[{"start":{"line":18,"column":2},"end":{"line":24,"column":3}}]},"2":{"type":"branch","line":26,"loc":{"start":{"line":26,"column":10},"end":{"line":47,"column":3}},"locations":[{"start":{"line":26,"column":10},"end":{"line":47,"column":3}}]},"3":{"type":"branch","line":28,"loc":{"start":{"line":28,"column":17},"end":{"line":41,"column":5}},"locations":[{"start":{"line":28,"column":17},"end":{"line":41,"column":5}}]},"4":{"type":"branch","line":36,"loc":{"start":{"line":36,"column":6},"end":{"line":41,"column":5}},"locations":[{"start":{"line":36,"column":6},"end":{"line":41,"column":5}}]},"5":{"type":"branch","line":41,"loc":{"start":{"line":41,"column":4},"end":{"line":43,"column":49}},"locations":[{"start":{"line":41,"column":4},"end":{"line":43,"column":49}}]},"6":{"type":"branch","line":43,"loc":{"start":{"line":43,"column":29},"end":{"line":43,"column":51}},"locations":[{"start":{"line":43,"column":29},"end":{"line":43,"column":51}}]},"7":{"type":"branch","line":44,"loc":{"start":{"line":44,"column":19},"end":{"line":44,"column":31}},"locations":[{"start":{"line":44,"column":19},"end":{"line":44,"column":31}}]},"8":{"type":"branch","line":44,"loc":{"start":{"line":44,"column":26},"end":{"line":45,"column":32}},"locations":[{"start":{"line":44,"column":26},"end":{"line":45,"column":32}}]},"9":{"type":"branch","line":45,"loc":{"start":{"line":45,"column":26},"end":{"line":46,"column":32}},"locations":[{"start":{"line":45,"column":26},"end":{"line":46,"column":32}}]},"10":{"type":"branch","line":49,"loc":{"start":{"line":49,"column":2},"end":{"line":78,"column":3}},"locations":[{"start":{"line":49,"column":2},"end":{"line":78,"column":3}}]},"11":{"type":"branch","line":51,"loc":{"start":{"line":51,"column":26},"end":{"line":51,"column":56}},"locations":[{"start":{"line":51,"column":26},"end":{"line":51,"column":56}}]},"12":{"type":"branch","line":51,"loc":{"start":{"line":51,"column":46},"end":{"line":51,"column":66}},"locations":[{"start":{"line":51,"column":46},"end":{"line":51,"column":66}}]},"13":{"type":"branch","line":53,"loc":{"start":{"line":53,"column":28},"end":{"line":53,"column":81}},"locations":[{"start":{"line":53,"column":28},"end":{"line":53,"column":81}}]},"14":{"type":"branch","line":80,"loc":{"start":{"line":80,"column":2},"end":{"line":82,"column":3}},"locations":[{"start":{"line":80,"column":2},"end":{"line":82,"column":3}}]},"15":{"type":"branch","line":93,"loc":{"start":{"line":93,"column":2},"end":{"line":95,"column":3}},"locations":[{"start":{"line":93,"column":2},"end":{"line":95,"column":3}}]},"16":{"type":"branch","line":94,"loc":{"start":{"line":94,"column":35},"end":{"line":94,"column":83}},"locations":[{"start":{"line":94,"column":35},"end":{"line":94,"column":83}}]},"17":{"type":"branch","line":94,"loc":{"start":{"line":94,"column":79},"end":{"line":94,"column":88}},"locations":[{"start":{"line":94,"column":79},"end":{"line":94,"column":88}}]},"18":{"type":"branch","line":97,"loc":{"start":{"line":97,"column":2},"end":{"line":105,"column":3}},"locations":[{"start":{"line":97,"column":2},"end":{"line":105,"column":3}}]},"19":{"type":"branch","line":98,"loc":{"start":{"line":98,"column":23},"end":{"line":104,"column":5}},"locations":[{"start":{"line":98,"column":23},"end":{"line":104,"column":5}}]},"20":{"type":"branch","line":107,"loc":{"start":{"line":107,"column":2},"end":{"line":144,"column":3}},"locations":[{"start":{"line":107,"column":2},"end":{"line":144,"column":3}}]},"21":{"type":"branch","line":110,"loc":{"start":{"line":110,"column":9},"end":{"line":110,"column":41}},"locations":[{"start":{"line":110,"column":9},"end":{"line":110,"column":41}}]},"22":{"type":"branch","line":110,"loc":{"start":{"line":110,"column":41},"end":{"line":113,"column":5}},"locations":[{"start":{"line":110,"column":41},"end":{"line":113,"column":5}}]},"23":{"type":"branch","line":113,"loc":{"start":{"line":113,"column":4},"end":{"line":117,"column":20}},"locations":[{"start":{"line":113,"column":4},"end":{"line":117,"column":20}}]},"24":{"type":"branch","line":117,"loc":{"start":{"line":117,"column":20},"end":{"line":119,"column":11}},"locations":[{"start":{"line":117,"column":20},"end":{"line":119,"column":11}}]},"25":{"type":"branch","line":119,"loc":{"start":{"line":119,"column":4},"end":{"line":131,"column":5}},"locations":[{"start":{"line":119,"column":4},"end":{"line":131,"column":5}}]},"26":{"type":"branch","line":125,"loc":{"start":{"line":125,"column":35},"end":{"line":130,"column":7}},"locations":[{"start":{"line":125,"column":35},"end":{"line":130,"column":7}}]},"27":{"type":"branch","line":131,"loc":{"start":{"line":131,"column":4},"end":{"line":143,"column":16}},"locations":[{"start":{"line":131,"column":4},"end":{"line":143,"column":16}}]},"28":{"type":"branch","line":146,"loc":{"start":{"line":146,"column":2},"end":{"line":162,"column":3}},"locations":[{"start":{"line":146,"column":2},"end":{"line":162,"column":3}}]},"29":{"type":"branch","line":152,"loc":{"start":{"line":152,"column":34},"end":{"line":152,"column":64}},"locations":[{"start":{"line":152,"column":34},"end":{"line":152,"column":64}}]},"30":{"type":"branch","line":152,"loc":{"start":{"line":152,"column":64},"end":{"line":154,"column":5}},"locations":[{"start":{"line":152,"column":64},"end":{"line":154,"column":5}}]},"31":{"type":"branch","line":164,"loc":{"start":{"line":164,"column":2},"end":{"line":176,"column":3}},"locations":[{"start":{"line":164,"column":2},"end":{"line":176,"column":3}}]},"32":{"type":"branch","line":186,"loc":{"start":{"line":186,"column":2},"end":{"line":197,"column":3}},"locations":[{"start":{"line":186,"column":2},"end":{"line":197,"column":3}}]},"33":{"type":"branch","line":187,"loc":{"start":{"line":187,"column":33},"end":{"line":194,"column":5}},"locations":[{"start":{"line":187,"column":33},"end":{"line":194,"column":5}}]},"34":{"type":"branch","line":191,"loc":{"start":{"line":191,"column":6},"end":{"line":193,"column":7}},"locations":[{"start":{"line":191,"column":6},"end":{"line":193,"column":7}}]}},"b":{"0":[29],"1":[1],"2":[19],"3":[2],"4":[0],"5":[17],"6":[0],"7":[15],"8":[2],"9":[0],"10":[20],"11":[1],"12":[19],"13":[19],"14":[8],"15":[16],"16":[13],"17":[3],"18":[2],"19":[1],"20":[8],"21":[2],"22":[1],"23":[7],"24":[6],"25":[1],"26":[0],"27":[7],"28":[1],"29":[0],"30":[0],"31":[2],"32":[31],"33":[17],"34":[0]},"fnMap":{"0":{"name":"TracingManager","decl":{"start":{"line":12,"column":2},"end":{"line":16,"column":3}},"loc":{"start":{"line":12,"column":2},"end":{"line":16,"column":3}},"line":12},"1":{"name":"updateConfig","decl":{"start":{"line":18,"column":2},"end":{"line":24,"column":3}},"loc":{"start":{"line":18,"column":2},"end":{"line":24,"column":3}},"line":18},"2":{"name":"shouldSample","decl":{"start":{"line":26,"column":10},"end":{"line":47,"column":3}},"loc":{"start":{"line":26,"column":10},"end":{"line":47,"column":3}},"line":26},"3":{"name":"startTransaction","decl":{"start":{"line":49,"column":2},"end":{"line":78,"column":3}},"loc":{"start":{"line":49,"column":2},"end":{"line":78,"column":3}},"line":49},"4":{"name":"getCurrentTransaction","decl":{"start":{"line":80,"column":2},"end":{"line":82,"column":3}},"loc":{"start":{"line":80,"column":2},"end":{"line":82,"column":3}},"line":80},"5":{"name":"setCurrentTransaction","decl":{"start":{"line":84,"column":2},"end":{"line":91,"column":3}},"loc":{"start":{"line":84,"column":2},"end":{"line":91,"column":3}},"line":84},"6":{"name":"getCurrentSpan","decl":{"start":{"line":93,"column":2},"end":{"line":95,"column":3}},"loc":{"start":{"line":93,"column":2},"end":{"line":95,"column":3}},"line":93},"7":{"name":"setCurrentSpan","decl":{"start":{"line":97,"column":2},"end":{"line":105,"column":3}},"loc":{"start":{"line":97,"column":2},"end":{"line":105,"column":3}},"line":97},"8":{"name":"startSpan","decl":{"start":{"line":107,"column":2},"end":{"line":144,"column":3}},"loc":{"start":{"line":107,"column":2},"end":{"line":144,"column":3}},"line":107},"9":{"name":"onSpanFinished","decl":{"start":{"line":146,"column":2},"end":{"line":162,"column":3}},"loc":{"start":{"line":146,"column":2},"end":{"line":162,"column":3}},"line":146},"10":{"name":"onTransactionFinished","decl":{"start":{"line":164,"column":2},"end":{"line":176,"column":3}},"loc":{"start":{"line":164,"column":2},"end":{"line":176,"column":3}},"line":164},"11":{"name":"finishSpan","decl":{"start":{"line":178,"column":2},"end":{"line":180,"column":3}},"loc":{"start":{"line":178,"column":2},"end":{"line":180,"column":3}},"line":178},"12":{"name":"finishTransaction","decl":{"start":{"line":182,"column":2},"end":{"line":184,"column":3}},"loc":{"start":{"line":182,"column":2},"end":{"line":184,"column":3}},"line":182},"13":{"name":"destroy","decl":{"start":{"line":186,"column":2},"end":{"line":197,"column":3}},"loc":{"start":{"line":186,"column":2},"end":{"line":197,"column":3}},"line":186}},"f":{"0":29,"1":1,"2":19,"3":20,"4":8,"5":0,"6":16,"7":2,"8":8,"9":1,"10":2,"11":0,"12":0,"13":31}} +,"/Users/weidingjian/Desktop/work/ai/light-sentry-sdk/src/plugins/BehaviorPlugin.ts": {"path":"/Users/weidingjian/Desktop/work/ai/light-sentry-sdk/src/plugins/BehaviorPlugin.ts","all":false,"statementMap":{"0":{"start":{"line":1,"column":0},"end":{"line":1,"column":85}},"1":{"start":{"line":2,"column":0},"end":{"line":2,"column":48}},"2":{"start":{"line":3,"column":0},"end":{"line":3,"column":55}},"3":{"start":{"line":4,"column":0},"end":{"line":4,"column":0}},"4":{"start":{"line":5,"column":0},"end":{"line":5,"column":32}},"5":{"start":{"line":6,"column":0},"end":{"line":6,"column":22}},"6":{"start":{"line":7,"column":0},"end":{"line":7,"column":25}},"7":{"start":{"line":8,"column":0},"end":{"line":8,"column":25}},"8":{"start":{"line":9,"column":0},"end":{"line":9,"column":28}},"9":{"start":{"line":10,"column":0},"end":{"line":10,"column":26}},"10":{"start":{"line":11,"column":0},"end":{"line":11,"column":25}},"11":{"start":{"line":12,"column":0},"end":{"line":12,"column":26}},"12":{"start":{"line":13,"column":0},"end":{"line":13,"column":22}},"13":{"start":{"line":14,"column":0},"end":{"line":14,"column":1}},"14":{"start":{"line":15,"column":0},"end":{"line":15,"column":0}},"15":{"start":{"line":16,"column":0},"end":{"line":16,"column":45}},"16":{"start":{"line":17,"column":0},"end":{"line":17,"column":20}},"17":{"start":{"line":18,"column":0},"end":{"line":18,"column":20}},"18":{"start":{"line":19,"column":0},"end":{"line":19,"column":0}},"19":{"start":{"line":20,"column":0},"end":{"line":20,"column":31}},"20":{"start":{"line":21,"column":0},"end":{"line":21,"column":42}},"21":{"start":{"line":22,"column":0},"end":{"line":22,"column":20}},"22":{"start":{"line":23,"column":0},"end":{"line":23,"column":23}},"23":{"start":{"line":24,"column":0},"end":{"line":24,"column":23}},"24":{"start":{"line":25,"column":0},"end":{"line":25,"column":26}},"25":{"start":{"line":26,"column":0},"end":{"line":26,"column":24}},"26":{"start":{"line":27,"column":0},"end":{"line":27,"column":23}},"27":{"start":{"line":28,"column":0},"end":{"line":28,"column":25}},"28":{"start":{"line":29,"column":0},"end":{"line":29,"column":21}},"29":{"start":{"line":30,"column":0},"end":{"line":30,"column":4}},"30":{"start":{"line":31,"column":0},"end":{"line":31,"column":0}},"31":{"start":{"line":32,"column":0},"end":{"line":32,"column":36}},"32":{"start":{"line":33,"column":0},"end":{"line":33,"column":37}},"33":{"start":{"line":34,"column":0},"end":{"line":34,"column":37}},"34":{"start":{"line":35,"column":0},"end":{"line":35,"column":36}},"35":{"start":{"line":36,"column":0},"end":{"line":36,"column":42}},"36":{"start":{"line":37,"column":0},"end":{"line":37,"column":0}},"37":{"start":{"line":38,"column":0},"end":{"line":38,"column":55}},"38":{"start":{"line":39,"column":0},"end":{"line":39,"column":61}},"39":{"start":{"line":40,"column":0},"end":{"line":40,"column":32}},"40":{"start":{"line":41,"column":0},"end":{"line":41,"column":39}},"41":{"start":{"line":42,"column":0},"end":{"line":42,"column":42}},"42":{"start":{"line":43,"column":0},"end":{"line":43,"column":38}},"43":{"start":{"line":44,"column":0},"end":{"line":44,"column":34}},"44":{"start":{"line":45,"column":0},"end":{"line":45,"column":34}},"45":{"start":{"line":46,"column":0},"end":{"line":46,"column":36}},"46":{"start":{"line":47,"column":0},"end":{"line":47,"column":0}},"47":{"start":{"line":48,"column":0},"end":{"line":48,"column":36}},"48":{"start":{"line":49,"column":0},"end":{"line":49,"column":25}},"49":{"start":{"line":50,"column":0},"end":{"line":50,"column":22}},"50":{"start":{"line":51,"column":0},"end":{"line":51,"column":0}},"51":{"start":{"line":52,"column":0},"end":{"line":52,"column":32}},"52":{"start":{"line":53,"column":0},"end":{"line":53,"column":21}},"53":{"start":{"line":54,"column":0},"end":{"line":54,"column":5}},"54":{"start":{"line":55,"column":0},"end":{"line":55,"column":35}},"55":{"start":{"line":56,"column":0},"end":{"line":56,"column":24}},"56":{"start":{"line":57,"column":0},"end":{"line":57,"column":5}},"57":{"start":{"line":58,"column":0},"end":{"line":58,"column":35}},"58":{"start":{"line":59,"column":0},"end":{"line":59,"column":24}},"59":{"start":{"line":60,"column":0},"end":{"line":60,"column":5}},"60":{"start":{"line":61,"column":0},"end":{"line":61,"column":38}},"61":{"start":{"line":62,"column":0},"end":{"line":62,"column":31}},"62":{"start":{"line":63,"column":0},"end":{"line":63,"column":5}},"63":{"start":{"line":64,"column":0},"end":{"line":64,"column":36}},"64":{"start":{"line":65,"column":0},"end":{"line":65,"column":25}},"65":{"start":{"line":66,"column":0},"end":{"line":66,"column":5}},"66":{"start":{"line":67,"column":0},"end":{"line":67,"column":3}},"67":{"start":{"line":68,"column":0},"end":{"line":68,"column":0}},"68":{"start":{"line":69,"column":0},"end":{"line":69,"column":30}},"69":{"start":{"line":70,"column":0},"end":{"line":70,"column":59}},"70":{"start":{"line":71,"column":0},"end":{"line":71,"column":58}},"71":{"start":{"line":72,"column":0},"end":{"line":72,"column":77}},"72":{"start":{"line":73,"column":0},"end":{"line":73,"column":5}},"73":{"start":{"line":74,"column":0},"end":{"line":74,"column":3}},"74":{"start":{"line":75,"column":0},"end":{"line":75,"column":0}},"75":{"start":{"line":76,"column":0},"end":{"line":76,"column":35}},"76":{"start":{"line":77,"column":0},"end":{"line":77,"column":48}},"77":{"start":{"line":78,"column":0},"end":{"line":78,"column":31}},"78":{"start":{"line":79,"column":0},"end":{"line":79,"column":32}},"79":{"start":{"line":80,"column":0},"end":{"line":80,"column":32}},"80":{"start":{"line":81,"column":0},"end":{"line":81,"column":3}},"81":{"start":{"line":82,"column":0},"end":{"line":82,"column":0}},"82":{"start":{"line":83,"column":0},"end":{"line":83,"column":36}},"83":{"start":{"line":84,"column":0},"end":{"line":84,"column":83}},"84":{"start":{"line":85,"column":0},"end":{"line":85,"column":4}},"85":{"start":{"line":86,"column":0},"end":{"line":86,"column":75}},"86":{"start":{"line":87,"column":0},"end":{"line":87,"column":63}},"87":{"start":{"line":88,"column":0},"end":{"line":88,"column":63}},"88":{"start":{"line":89,"column":0},"end":{"line":89,"column":4}},"89":{"start":{"line":90,"column":0},"end":{"line":90,"column":49}},"90":{"start":{"line":91,"column":0},"end":{"line":91,"column":4}},"91":{"start":{"line":92,"column":0},"end":{"line":92,"column":88}},"92":{"start":{"line":93,"column":0},"end":{"line":93,"column":3}},"93":{"start":{"line":94,"column":0},"end":{"line":94,"column":0}},"94":{"start":{"line":95,"column":0},"end":{"line":95,"column":27}},"95":{"start":{"line":96,"column":0},"end":{"line":96,"column":46}},"96":{"start":{"line":97,"column":0},"end":{"line":97,"column":0}},"97":{"start":{"line":98,"column":0},"end":{"line":98,"column":29}},"98":{"start":{"line":99,"column":0},"end":{"line":99,"column":58}},"99":{"start":{"line":100,"column":0},"end":{"line":100,"column":0}},"100":{"start":{"line":101,"column":0},"end":{"line":101,"column":25}},"101":{"start":{"line":102,"column":0},"end":{"line":102,"column":21}},"102":{"start":{"line":103,"column":0},"end":{"line":103,"column":20}},"103":{"start":{"line":104,"column":0},"end":{"line":104,"column":15}},"104":{"start":{"line":105,"column":0},"end":{"line":105,"column":19}},"105":{"start":{"line":106,"column":0},"end":{"line":106,"column":30}},"106":{"start":{"line":107,"column":0},"end":{"line":107,"column":40}},"107":{"start":{"line":108,"column":0},"end":{"line":108,"column":35}},"108":{"start":{"line":109,"column":0},"end":{"line":109,"column":37}},"109":{"start":{"line":110,"column":0},"end":{"line":110,"column":42}},"110":{"start":{"line":111,"column":0},"end":{"line":111,"column":44}},"111":{"start":{"line":112,"column":0},"end":{"line":112,"column":37}},"112":{"start":{"line":113,"column":0},"end":{"line":113,"column":8}},"113":{"start":{"line":114,"column":0},"end":{"line":114,"column":7}},"114":{"start":{"line":115,"column":0},"end":{"line":115,"column":3}},"115":{"start":{"line":116,"column":0},"end":{"line":116,"column":0}},"116":{"start":{"line":117,"column":0},"end":{"line":117,"column":30}},"117":{"start":{"line":118,"column":0},"end":{"line":118,"column":48}},"118":{"start":{"line":119,"column":0},"end":{"line":119,"column":0}},"119":{"start":{"line":120,"column":0},"end":{"line":120,"column":34}},"120":{"start":{"line":121,"column":0},"end":{"line":121,"column":32}},"121":{"start":{"line":122,"column":0},"end":{"line":122,"column":56}},"122":{"start":{"line":123,"column":0},"end":{"line":123,"column":56}},"123":{"start":{"line":124,"column":0},"end":{"line":124,"column":15}},"124":{"start":{"line":125,"column":0},"end":{"line":125,"column":7}},"125":{"start":{"line":126,"column":0},"end":{"line":126,"column":39}},"126":{"start":{"line":127,"column":0},"end":{"line":127,"column":0}},"127":{"start":{"line":128,"column":0},"end":{"line":128,"column":45}},"128":{"start":{"line":129,"column":0},"end":{"line":129,"column":45}},"129":{"start":{"line":130,"column":0},"end":{"line":130,"column":0}},"130":{"start":{"line":131,"column":0},"end":{"line":131,"column":56}},"131":{"start":{"line":132,"column":0},"end":{"line":132,"column":22}},"132":{"start":{"line":133,"column":0},"end":{"line":133,"column":36}},"133":{"start":{"line":134,"column":0},"end":{"line":134,"column":7}},"134":{"start":{"line":135,"column":0},"end":{"line":135,"column":69}},"135":{"start":{"line":136,"column":0},"end":{"line":136,"column":90}},"136":{"start":{"line":137,"column":0},"end":{"line":137,"column":22}},"137":{"start":{"line":138,"column":0},"end":{"line":138,"column":36}},"138":{"start":{"line":139,"column":0},"end":{"line":139,"column":9}},"139":{"start":{"line":140,"column":0},"end":{"line":140,"column":7}},"140":{"start":{"line":141,"column":0},"end":{"line":141,"column":0}},"141":{"start":{"line":142,"column":0},"end":{"line":142,"column":59}},"142":{"start":{"line":143,"column":0},"end":{"line":143,"column":0}},"143":{"start":{"line":144,"column":0},"end":{"line":144,"column":27}},"144":{"start":{"line":145,"column":0},"end":{"line":145,"column":26}},"145":{"start":{"line":146,"column":0},"end":{"line":146,"column":31}},"146":{"start":{"line":147,"column":0},"end":{"line":147,"column":21}},"147":{"start":{"line":148,"column":0},"end":{"line":148,"column":19}},"148":{"start":{"line":149,"column":0},"end":{"line":149,"column":34}},"149":{"start":{"line":150,"column":0},"end":{"line":150,"column":45}},"150":{"start":{"line":151,"column":0},"end":{"line":151,"column":39}},"151":{"start":{"line":152,"column":0},"end":{"line":152,"column":39}},"152":{"start":{"line":153,"column":0},"end":{"line":153,"column":10}},"153":{"start":{"line":154,"column":0},"end":{"line":154,"column":9}},"154":{"start":{"line":155,"column":0},"end":{"line":155,"column":6}},"155":{"start":{"line":156,"column":0},"end":{"line":156,"column":0}},"156":{"start":{"line":157,"column":0},"end":{"line":157,"column":59}},"157":{"start":{"line":158,"column":0},"end":{"line":158,"column":3}},"158":{"start":{"line":159,"column":0},"end":{"line":159,"column":0}},"159":{"start":{"line":160,"column":0},"end":{"line":160,"column":30}},"160":{"start":{"line":161,"column":0},"end":{"line":161,"column":46}},"161":{"start":{"line":162,"column":0},"end":{"line":162,"column":0}},"162":{"start":{"line":163,"column":0},"end":{"line":163,"column":31}},"163":{"start":{"line":164,"column":0},"end":{"line":164,"column":0}},"164":{"start":{"line":165,"column":0},"end":{"line":165,"column":30}},"165":{"start":{"line":166,"column":0},"end":{"line":166,"column":38}},"166":{"start":{"line":167,"column":0},"end":{"line":167,"column":35}},"167":{"start":{"line":168,"column":0},"end":{"line":168,"column":29}},"168":{"start":{"line":169,"column":0},"end":{"line":169,"column":30}},"169":{"start":{"line":170,"column":0},"end":{"line":170,"column":29}},"170":{"start":{"line":171,"column":0},"end":{"line":171,"column":0}},"171":{"start":{"line":172,"column":0},"end":{"line":172,"column":29}},"172":{"start":{"line":173,"column":0},"end":{"line":173,"column":28}},"173":{"start":{"line":174,"column":0},"end":{"line":174,"column":23}},"174":{"start":{"line":175,"column":0},"end":{"line":175,"column":25}},"175":{"start":{"line":176,"column":0},"end":{"line":176,"column":23}},"176":{"start":{"line":177,"column":0},"end":{"line":177,"column":17}},"177":{"start":{"line":178,"column":0},"end":{"line":178,"column":15}},"178":{"start":{"line":179,"column":0},"end":{"line":179,"column":12}},"179":{"start":{"line":180,"column":0},"end":{"line":180,"column":11}},"180":{"start":{"line":181,"column":0},"end":{"line":181,"column":0}},"181":{"start":{"line":182,"column":0},"end":{"line":182,"column":35}},"182":{"start":{"line":183,"column":0},"end":{"line":183,"column":32}},"183":{"start":{"line":184,"column":0},"end":{"line":184,"column":36}},"184":{"start":{"line":185,"column":0},"end":{"line":185,"column":7}},"185":{"start":{"line":186,"column":0},"end":{"line":186,"column":6}},"186":{"start":{"line":187,"column":0},"end":{"line":187,"column":0}},"187":{"start":{"line":188,"column":0},"end":{"line":188,"column":47}},"188":{"start":{"line":189,"column":0},"end":{"line":189,"column":53}},"189":{"start":{"line":190,"column":0},"end":{"line":190,"column":22}},"190":{"start":{"line":191,"column":0},"end":{"line":191,"column":0}},"191":{"start":{"line":192,"column":0},"end":{"line":192,"column":37}},"192":{"start":{"line":193,"column":0},"end":{"line":193,"column":119}},"193":{"start":{"line":194,"column":0},"end":{"line":194,"column":32}},"194":{"start":{"line":195,"column":0},"end":{"line":195,"column":20}},"195":{"start":{"line":196,"column":0},"end":{"line":196,"column":6}},"196":{"start":{"line":197,"column":0},"end":{"line":197,"column":0}},"197":{"start":{"line":198,"column":0},"end":{"line":198,"column":40}},"198":{"start":{"line":199,"column":0},"end":{"line":199,"column":125}},"199":{"start":{"line":200,"column":0},"end":{"line":200,"column":32}},"200":{"start":{"line":201,"column":0},"end":{"line":201,"column":20}},"201":{"start":{"line":202,"column":0},"end":{"line":202,"column":6}},"202":{"start":{"line":203,"column":0},"end":{"line":203,"column":0}},"203":{"start":{"line":204,"column":0},"end":{"line":204,"column":59}},"204":{"start":{"line":205,"column":0},"end":{"line":205,"column":61}},"205":{"start":{"line":206,"column":0},"end":{"line":206,"column":0}},"206":{"start":{"line":207,"column":0},"end":{"line":207,"column":57}},"207":{"start":{"line":208,"column":0},"end":{"line":208,"column":61}},"208":{"start":{"line":209,"column":0},"end":{"line":209,"column":3}},"209":{"start":{"line":210,"column":0},"end":{"line":210,"column":0}},"210":{"start":{"line":211,"column":0},"end":{"line":211,"column":37}},"211":{"start":{"line":212,"column":0},"end":{"line":212,"column":46}},"212":{"start":{"line":213,"column":0},"end":{"line":213,"column":0}},"213":{"start":{"line":214,"column":0},"end":{"line":214,"column":31}},"214":{"start":{"line":215,"column":0},"end":{"line":215,"column":0}},"215":{"start":{"line":216,"column":0},"end":{"line":216,"column":32}},"216":{"start":{"line":217,"column":0},"end":{"line":217,"column":50}},"217":{"start":{"line":218,"column":0},"end":{"line":218,"column":28}},"218":{"start":{"line":219,"column":0},"end":{"line":219,"column":64}},"219":{"start":{"line":220,"column":0},"end":{"line":220,"column":30}},"220":{"start":{"line":221,"column":0},"end":{"line":221,"column":9}},"221":{"start":{"line":222,"column":0},"end":{"line":222,"column":0}},"222":{"start":{"line":223,"column":0},"end":{"line":223,"column":29}},"223":{"start":{"line":224,"column":0},"end":{"line":224,"column":31}},"224":{"start":{"line":225,"column":0},"end":{"line":225,"column":33}},"225":{"start":{"line":226,"column":0},"end":{"line":226,"column":23}},"226":{"start":{"line":227,"column":0},"end":{"line":227,"column":21}},"227":{"start":{"line":228,"column":0},"end":{"line":228,"column":50}},"228":{"start":{"line":229,"column":0},"end":{"line":229,"column":12}},"229":{"start":{"line":230,"column":0},"end":{"line":230,"column":11}},"230":{"start":{"line":231,"column":0},"end":{"line":231,"column":7}},"231":{"start":{"line":232,"column":0},"end":{"line":232,"column":6}},"232":{"start":{"line":233,"column":0},"end":{"line":233,"column":0}},"233":{"start":{"line":234,"column":0},"end":{"line":234,"column":37}},"234":{"start":{"line":235,"column":0},"end":{"line":235,"column":28}},"235":{"start":{"line":236,"column":0},"end":{"line":236,"column":23}},"236":{"start":{"line":237,"column":0},"end":{"line":237,"column":14}},"237":{"start":{"line":238,"column":0},"end":{"line":238,"column":35}},"238":{"start":{"line":239,"column":0},"end":{"line":239,"column":7}},"239":{"start":{"line":240,"column":0},"end":{"line":240,"column":6}},"240":{"start":{"line":241,"column":0},"end":{"line":241,"column":0}},"241":{"start":{"line":242,"column":0},"end":{"line":242,"column":39}},"242":{"start":{"line":243,"column":0},"end":{"line":243,"column":35}},"243":{"start":{"line":244,"column":0},"end":{"line":244,"column":0}},"244":{"start":{"line":245,"column":0},"end":{"line":245,"column":75}},"245":{"start":{"line":246,"column":0},"end":{"line":246,"column":65}},"246":{"start":{"line":247,"column":0},"end":{"line":247,"column":57}},"247":{"start":{"line":248,"column":0},"end":{"line":248,"column":3}},"248":{"start":{"line":249,"column":0},"end":{"line":249,"column":0}},"249":{"start":{"line":250,"column":0},"end":{"line":250,"column":31}},"250":{"start":{"line":251,"column":0},"end":{"line":251,"column":46}},"251":{"start":{"line":252,"column":0},"end":{"line":252,"column":0}},"252":{"start":{"line":253,"column":0},"end":{"line":253,"column":27}},"253":{"start":{"line":254,"column":0},"end":{"line":254,"column":32}},"254":{"start":{"line":255,"column":0},"end":{"line":255,"column":58}},"255":{"start":{"line":256,"column":0},"end":{"line":256,"column":57}},"256":{"start":{"line":257,"column":0},"end":{"line":257,"column":15}},"257":{"start":{"line":258,"column":0},"end":{"line":258,"column":7}},"258":{"start":{"line":259,"column":0},"end":{"line":259,"column":40}},"259":{"start":{"line":260,"column":0},"end":{"line":260,"column":0}},"260":{"start":{"line":261,"column":0},"end":{"line":261,"column":42}},"261":{"start":{"line":262,"column":0},"end":{"line":262,"column":40}},"262":{"start":{"line":263,"column":0},"end":{"line":263,"column":36}},"263":{"start":{"line":264,"column":0},"end":{"line":264,"column":7}},"264":{"start":{"line":265,"column":0},"end":{"line":265,"column":6}},"265":{"start":{"line":266,"column":0},"end":{"line":266,"column":0}},"266":{"start":{"line":267,"column":0},"end":{"line":267,"column":72}},"267":{"start":{"line":268,"column":0},"end":{"line":268,"column":3}},"268":{"start":{"line":269,"column":0},"end":{"line":269,"column":0}},"269":{"start":{"line":270,"column":0},"end":{"line":270,"column":32}},"270":{"start":{"line":271,"column":0},"end":{"line":271,"column":36}},"271":{"start":{"line":272,"column":0},"end":{"line":272,"column":31}},"272":{"start":{"line":273,"column":0},"end":{"line":273,"column":0}},"273":{"start":{"line":274,"column":0},"end":{"line":274,"column":25}},"274":{"start":{"line":275,"column":0},"end":{"line":275,"column":25}},"275":{"start":{"line":276,"column":0},"end":{"line":276,"column":29}},"276":{"start":{"line":277,"column":0},"end":{"line":277,"column":19}},"277":{"start":{"line":278,"column":0},"end":{"line":278,"column":39}},"278":{"start":{"line":279,"column":0},"end":{"line":279,"column":8}},"279":{"start":{"line":280,"column":0},"end":{"line":280,"column":7}},"280":{"start":{"line":281,"column":0},"end":{"line":281,"column":3}},"281":{"start":{"line":282,"column":0},"end":{"line":282,"column":0}},"282":{"start":{"line":283,"column":0},"end":{"line":283,"column":91}},"283":{"start":{"line":284,"column":0},"end":{"line":284,"column":37}},"284":{"start":{"line":285,"column":0},"end":{"line":285,"column":0}},"285":{"start":{"line":286,"column":0},"end":{"line":286,"column":34}},"286":{"start":{"line":287,"column":0},"end":{"line":287,"column":23}},"287":{"start":{"line":288,"column":0},"end":{"line":288,"column":20}},"288":{"start":{"line":289,"column":0},"end":{"line":289,"column":23}},"289":{"start":{"line":290,"column":0},"end":{"line":290,"column":13}},"290":{"start":{"line":291,"column":0},"end":{"line":291,"column":32}},"291":{"start":{"line":292,"column":0},"end":{"line":292,"column":31}},"292":{"start":{"line":293,"column":0},"end":{"line":293,"column":8}},"293":{"start":{"line":294,"column":0},"end":{"line":294,"column":14}},"294":{"start":{"line":295,"column":0},"end":{"line":295,"column":6}},"295":{"start":{"line":296,"column":0},"end":{"line":296,"column":0}},"296":{"start":{"line":297,"column":0},"end":{"line":297,"column":36}},"297":{"start":{"line":298,"column":0},"end":{"line":298,"column":3}},"298":{"start":{"line":299,"column":0},"end":{"line":299,"column":0}},"299":{"start":{"line":300,"column":0},"end":{"line":300,"column":19}},"300":{"start":{"line":301,"column":0},"end":{"line":301,"column":40}},"301":{"start":{"line":302,"column":0},"end":{"line":302,"column":35}},"302":{"start":{"line":303,"column":0},"end":{"line":303,"column":51}},"303":{"start":{"line":304,"column":0},"end":{"line":304,"column":7}},"304":{"start":{"line":305,"column":0},"end":{"line":305,"column":38}},"305":{"start":{"line":306,"column":0},"end":{"line":306,"column":57}},"306":{"start":{"line":307,"column":0},"end":{"line":307,"column":7}},"307":{"start":{"line":308,"column":0},"end":{"line":308,"column":28}},"308":{"start":{"line":309,"column":0},"end":{"line":309,"column":64}},"309":{"start":{"line":310,"column":0},"end":{"line":310,"column":7}},"310":{"start":{"line":311,"column":0},"end":{"line":311,"column":30}},"311":{"start":{"line":312,"column":0},"end":{"line":312,"column":68}},"312":{"start":{"line":313,"column":0},"end":{"line":313,"column":7}},"313":{"start":{"line":314,"column":0},"end":{"line":314,"column":32}},"314":{"start":{"line":315,"column":0},"end":{"line":315,"column":72}},"315":{"start":{"line":316,"column":0},"end":{"line":316,"column":7}},"316":{"start":{"line":317,"column":0},"end":{"line":317,"column":28}},"317":{"start":{"line":318,"column":0},"end":{"line":318,"column":64}},"318":{"start":{"line":319,"column":0},"end":{"line":319,"column":7}},"319":{"start":{"line":320,"column":0},"end":{"line":320,"column":26}},"320":{"start":{"line":321,"column":0},"end":{"line":321,"column":60}},"321":{"start":{"line":322,"column":0},"end":{"line":322,"column":7}},"322":{"start":{"line":323,"column":0},"end":{"line":323,"column":5}},"323":{"start":{"line":324,"column":0},"end":{"line":324,"column":42}},"324":{"start":{"line":325,"column":0},"end":{"line":325,"column":25}},"325":{"start":{"line":326,"column":0},"end":{"line":326,"column":66}},"326":{"start":{"line":327,"column":0},"end":{"line":327,"column":7}},"327":{"start":{"line":328,"column":0},"end":{"line":328,"column":36}},"328":{"start":{"line":329,"column":0},"end":{"line":329,"column":82}},"329":{"start":{"line":330,"column":0},"end":{"line":330,"column":7}},"330":{"start":{"line":331,"column":0},"end":{"line":331,"column":5}},"331":{"start":{"line":332,"column":0},"end":{"line":332,"column":3}},"332":{"start":{"line":333,"column":0},"end":{"line":333,"column":1}},"333":{"start":{"line":334,"column":0},"end":{"line":334,"column":0}},"334":{"start":{"line":335,"column":0},"end":{"line":335,"column":30}}},"s":{"0":1,"1":1,"2":1,"3":1,"4":1,"5":1,"6":1,"7":1,"8":1,"9":1,"10":1,"11":1,"12":1,"13":1,"14":1,"15":0,"16":0,"17":0,"18":0,"19":0,"20":0,"21":0,"22":0,"23":0,"24":0,"25":0,"26":0,"27":0,"28":0,"29":0,"30":0,"31":0,"32":0,"33":0,"34":0,"35":0,"36":1,"37":1,"38":1,"39":1,"40":1,"41":1,"42":1,"43":1,"44":1,"45":1,"46":1,"47":1,"48":0,"49":0,"50":0,"51":0,"52":0,"53":0,"54":0,"55":0,"56":0,"57":0,"58":0,"59":0,"60":0,"61":0,"62":0,"63":0,"64":0,"65":0,"66":0,"67":1,"68":1,"69":0,"70":0,"71":0,"72":0,"73":0,"74":1,"75":1,"76":0,"77":0,"78":0,"79":0,"80":0,"81":1,"82":1,"83":0,"84":0,"85":0,"86":0,"87":0,"88":0,"89":0,"90":0,"91":0,"92":0,"93":1,"94":1,"95":0,"96":0,"97":0,"98":0,"99":0,"100":0,"101":0,"102":0,"103":0,"104":0,"105":0,"106":0,"107":0,"108":0,"109":0,"110":0,"111":0,"112":0,"113":0,"114":0,"115":1,"116":1,"117":0,"118":0,"119":0,"120":0,"121":0,"122":0,"123":0,"124":0,"125":0,"126":0,"127":0,"128":0,"129":0,"130":0,"131":0,"132":0,"133":0,"134":0,"135":0,"136":0,"137":0,"138":0,"139":0,"140":0,"141":0,"142":0,"143":0,"144":0,"145":0,"146":0,"147":0,"148":0,"149":0,"150":0,"151":0,"152":0,"153":0,"154":0,"155":0,"156":0,"157":0,"158":1,"159":1,"160":0,"161":0,"162":0,"163":0,"164":0,"165":0,"166":0,"167":0,"168":0,"169":0,"170":0,"171":0,"172":0,"173":0,"174":0,"175":0,"176":0,"177":0,"178":0,"179":0,"180":0,"181":0,"182":0,"183":0,"184":0,"185":0,"186":0,"187":0,"188":0,"189":0,"190":0,"191":0,"192":0,"193":0,"194":0,"195":0,"196":0,"197":0,"198":0,"199":0,"200":0,"201":0,"202":0,"203":0,"204":0,"205":0,"206":0,"207":0,"208":0,"209":1,"210":1,"211":0,"212":0,"213":0,"214":0,"215":0,"216":0,"217":0,"218":0,"219":0,"220":0,"221":0,"222":0,"223":0,"224":0,"225":0,"226":0,"227":0,"228":0,"229":0,"230":0,"231":0,"232":0,"233":0,"234":0,"235":0,"236":0,"237":0,"238":0,"239":0,"240":0,"241":0,"242":0,"243":0,"244":0,"245":0,"246":0,"247":0,"248":1,"249":1,"250":0,"251":0,"252":0,"253":0,"254":0,"255":0,"256":0,"257":0,"258":0,"259":0,"260":0,"261":0,"262":0,"263":0,"264":0,"265":0,"266":0,"267":0,"268":1,"269":1,"270":0,"271":0,"272":0,"273":0,"274":0,"275":0,"276":0,"277":0,"278":0,"279":0,"280":0,"281":1,"282":1,"283":0,"284":0,"285":0,"286":0,"287":0,"288":0,"289":0,"290":0,"291":0,"292":0,"293":0,"294":0,"295":0,"296":0,"297":0,"298":1,"299":1,"300":0,"301":0,"302":0,"303":0,"304":0,"305":0,"306":0,"307":0,"308":0,"309":0,"310":0,"311":0,"312":0,"313":0,"314":0,"315":0,"316":0,"317":0,"318":0,"319":0,"320":0,"321":0,"322":0,"323":0,"324":0,"325":0,"326":0,"327":0,"328":0,"329":0,"330":0,"331":0,"332":1,"333":1,"334":1},"branchMap":{},"b":{},"fnMap":{"0":{"name":"BehaviorPlugin","decl":{"start":{"line":16,"column":0},"end":{"line":36,"column":42}},"loc":{"start":{"line":16,"column":0},"end":{"line":36,"column":42}},"line":16},"1":{"name":"setup","decl":{"start":{"line":48,"column":2},"end":{"line":67,"column":3}},"loc":{"start":{"line":48,"column":2},"end":{"line":67,"column":3}},"line":48},"2":{"name":"loadConfig","decl":{"start":{"line":69,"column":10},"end":{"line":74,"column":3}},"loc":{"start":{"line":69,"column":10},"end":{"line":74,"column":3}},"line":69},"3":{"name":"shouldSample","decl":{"start":{"line":76,"column":10},"end":{"line":81,"column":3}},"loc":{"start":{"line":76,"column":10},"end":{"line":81,"column":3}},"line":76},"4":{"name":"getScrollDepth","decl":{"start":{"line":83,"column":10},"end":{"line":93,"column":3}},"loc":{"start":{"line":83,"column":10},"end":{"line":93,"column":3}},"line":83},"5":{"name":"trackPV","decl":{"start":{"line":95,"column":10},"end":{"line":115,"column":3}},"loc":{"start":{"line":95,"column":10},"end":{"line":115,"column":3}},"line":95},"6":{"name":"trackClick","decl":{"start":{"line":117,"column":10},"end":{"line":158,"column":3}},"loc":{"start":{"line":117,"column":10},"end":{"line":158,"column":3}},"line":117},"7":{"name":"trackRoute","decl":{"start":{"line":160,"column":10},"end":{"line":209,"column":3}},"loc":{"start":{"line":160,"column":10},"end":{"line":209,"column":3}},"line":160},"8":{"name":"trackPageDuration","decl":{"start":{"line":211,"column":10},"end":{"line":248,"column":3}},"loc":{"start":{"line":211,"column":10},"end":{"line":248,"column":3}},"line":211},"9":{"name":"trackScroll","decl":{"start":{"line":250,"column":10},"end":{"line":268,"column":3}},"loc":{"start":{"line":250,"column":10},"end":{"line":268,"column":3}},"line":250},"10":{"name":"reportScroll","decl":{"start":{"line":270,"column":10},"end":{"line":281,"column":3}},"loc":{"start":{"line":270,"column":10},"end":{"line":281,"column":3}},"line":270},"11":{"name":"reportBehavior","decl":{"start":{"line":283,"column":10},"end":{"line":298,"column":3}},"loc":{"start":{"line":283,"column":10},"end":{"line":298,"column":3}},"line":283},"12":{"name":"destroy","decl":{"start":{"line":300,"column":2},"end":{"line":332,"column":3}},"loc":{"start":{"line":300,"column":2},"end":{"line":332,"column":3}},"line":300}},"f":{"0":0,"1":0,"2":0,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10":0,"11":0,"12":0}} +,"/Users/weidingjian/Desktop/work/ai/light-sentry-sdk/src/plugins/ErrorPlugin.ts": {"path":"/Users/weidingjian/Desktop/work/ai/light-sentry-sdk/src/plugins/ErrorPlugin.ts","all":false,"statementMap":{"0":{"start":{"line":1,"column":0},"end":{"line":1,"column":94}},"1":{"start":{"line":2,"column":0},"end":{"line":2,"column":63}},"2":{"start":{"line":3,"column":0},"end":{"line":3,"column":51}},"3":{"start":{"line":4,"column":0},"end":{"line":4,"column":60}},"4":{"start":{"line":5,"column":0},"end":{"line":5,"column":54}},"5":{"start":{"line":6,"column":0},"end":{"line":6,"column":43}},"6":{"start":{"line":7,"column":0},"end":{"line":7,"column":0}},"7":{"start":{"line":8,"column":0},"end":{"line":8,"column":29}},"8":{"start":{"line":9,"column":0},"end":{"line":9,"column":26}},"9":{"start":{"line":10,"column":0},"end":{"line":10,"column":31}},"10":{"start":{"line":11,"column":0},"end":{"line":11,"column":26}},"11":{"start":{"line":12,"column":0},"end":{"line":12,"column":29}},"12":{"start":{"line":13,"column":0},"end":{"line":13,"column":22}},"13":{"start":{"line":14,"column":0},"end":{"line":14,"column":30}},"14":{"start":{"line":15,"column":0},"end":{"line":15,"column":37}},"15":{"start":{"line":16,"column":0},"end":{"line":16,"column":35}},"16":{"start":{"line":17,"column":0},"end":{"line":17,"column":37}},"17":{"start":{"line":18,"column":0},"end":{"line":18,"column":1}},"18":{"start":{"line":19,"column":0},"end":{"line":19,"column":0}},"19":{"start":{"line":20,"column":0},"end":{"line":20,"column":42}},"20":{"start":{"line":21,"column":0},"end":{"line":21,"column":17}},"21":{"start":{"line":22,"column":0},"end":{"line":22,"column":20}},"22":{"start":{"line":23,"column":0},"end":{"line":23,"column":0}},"23":{"start":{"line":24,"column":0},"end":{"line":24,"column":31}},"24":{"start":{"line":25,"column":0},"end":{"line":25,"column":39}},"25":{"start":{"line":26,"column":0},"end":{"line":26,"column":22}},"26":{"start":{"line":27,"column":0},"end":{"line":27,"column":30}},"27":{"start":{"line":28,"column":0},"end":{"line":28,"column":24}},"28":{"start":{"line":29,"column":0},"end":{"line":29,"column":28}},"29":{"start":{"line":30,"column":0},"end":{"line":30,"column":28}},"30":{"start":{"line":31,"column":0},"end":{"line":31,"column":4}},"31":{"start":{"line":32,"column":0},"end":{"line":32,"column":0}},"32":{"start":{"line":33,"column":0},"end":{"line":33,"column":50}},"33":{"start":{"line":34,"column":0},"end":{"line":34,"column":72}},"34":{"start":{"line":35,"column":0},"end":{"line":35,"column":51}},"35":{"start":{"line":36,"column":0},"end":{"line":36,"column":0}},"36":{"start":{"line":37,"column":0},"end":{"line":37,"column":36}},"37":{"start":{"line":38,"column":0},"end":{"line":38,"column":25}},"38":{"start":{"line":39,"column":0},"end":{"line":39,"column":22}},"39":{"start":{"line":40,"column":0},"end":{"line":40,"column":28}},"40":{"start":{"line":41,"column":0},"end":{"line":41,"column":35}},"41":{"start":{"line":42,"column":0},"end":{"line":42,"column":30}},"42":{"start":{"line":43,"column":0},"end":{"line":43,"column":3}},"43":{"start":{"line":44,"column":0},"end":{"line":44,"column":0}},"44":{"start":{"line":45,"column":0},"end":{"line":45,"column":30}},"45":{"start":{"line":46,"column":0},"end":{"line":46,"column":59}},"46":{"start":{"line":47,"column":0},"end":{"line":47,"column":55}},"47":{"start":{"line":48,"column":0},"end":{"line":48,"column":74}},"48":{"start":{"line":49,"column":0},"end":{"line":49,"column":5}},"49":{"start":{"line":50,"column":0},"end":{"line":50,"column":36}},"50":{"start":{"line":51,"column":0},"end":{"line":51,"column":101}},"51":{"start":{"line":52,"column":0},"end":{"line":52,"column":5}},"52":{"start":{"line":53,"column":0},"end":{"line":53,"column":34}},"53":{"start":{"line":54,"column":0},"end":{"line":54,"column":95}},"54":{"start":{"line":55,"column":0},"end":{"line":55,"column":5}},"55":{"start":{"line":56,"column":0},"end":{"line":56,"column":36}},"56":{"start":{"line":57,"column":0},"end":{"line":57,"column":101}},"57":{"start":{"line":58,"column":0},"end":{"line":58,"column":5}},"58":{"start":{"line":59,"column":0},"end":{"line":59,"column":3}},"59":{"start":{"line":60,"column":0},"end":{"line":60,"column":0}},"60":{"start":{"line":61,"column":0},"end":{"line":61,"column":55}},"61":{"start":{"line":62,"column":0},"end":{"line":62,"column":31}},"62":{"start":{"line":63,"column":0},"end":{"line":63,"column":66}},"63":{"start":{"line":64,"column":0},"end":{"line":64,"column":3}},"64":{"start":{"line":65,"column":0},"end":{"line":65,"column":0}},"65":{"start":{"line":66,"column":0},"end":{"line":66,"column":55}},"66":{"start":{"line":67,"column":0},"end":{"line":67,"column":62}},"67":{"start":{"line":68,"column":0},"end":{"line":68,"column":3}},"68":{"start":{"line":69,"column":0},"end":{"line":69,"column":0}},"69":{"start":{"line":70,"column":0},"end":{"line":70,"column":60}},"70":{"start":{"line":71,"column":0},"end":{"line":71,"column":52}},"71":{"start":{"line":72,"column":0},"end":{"line":72,"column":43}},"72":{"start":{"line":73,"column":0},"end":{"line":73,"column":0}},"73":{"start":{"line":74,"column":0},"end":{"line":74,"column":32}},"74":{"start":{"line":75,"column":0},"end":{"line":75,"column":32}},"75":{"start":{"line":76,"column":0},"end":{"line":76,"column":42}},"76":{"start":{"line":77,"column":0},"end":{"line":77,"column":51}},"77":{"start":{"line":78,"column":0},"end":{"line":78,"column":9}},"78":{"start":{"line":79,"column":0},"end":{"line":79,"column":50}},"79":{"start":{"line":80,"column":0},"end":{"line":80,"column":8}},"80":{"start":{"line":81,"column":0},"end":{"line":81,"column":6}},"81":{"start":{"line":82,"column":0},"end":{"line":82,"column":3}},"82":{"start":{"line":83,"column":0},"end":{"line":83,"column":0}},"83":{"start":{"line":84,"column":0},"end":{"line":84,"column":35}},"84":{"start":{"line":85,"column":0},"end":{"line":85,"column":45}},"85":{"start":{"line":86,"column":0},"end":{"line":86,"column":31}},"86":{"start":{"line":87,"column":0},"end":{"line":87,"column":32}},"87":{"start":{"line":88,"column":0},"end":{"line":88,"column":32}},"88":{"start":{"line":89,"column":0},"end":{"line":89,"column":3}},"89":{"start":{"line":90,"column":0},"end":{"line":90,"column":0}},"90":{"start":{"line":91,"column":0},"end":{"line":91,"column":43}},"91":{"start":{"line":92,"column":0},"end":{"line":92,"column":55}},"92":{"start":{"line":93,"column":0},"end":{"line":93,"column":31}},"93":{"start":{"line":94,"column":0},"end":{"line":94,"column":32}},"94":{"start":{"line":95,"column":0},"end":{"line":95,"column":32}},"95":{"start":{"line":96,"column":0},"end":{"line":96,"column":3}},"96":{"start":{"line":97,"column":0},"end":{"line":97,"column":0}},"97":{"start":{"line":98,"column":0},"end":{"line":98,"column":36}},"98":{"start":{"line":99,"column":0},"end":{"line":99,"column":46}},"99":{"start":{"line":100,"column":0},"end":{"line":100,"column":0}},"100":{"start":{"line":101,"column":0},"end":{"line":101,"column":42}},"101":{"start":{"line":102,"column":0},"end":{"line":102,"column":0}},"102":{"start":{"line":103,"column":0},"end":{"line":103,"column":62}},"103":{"start":{"line":104,"column":0},"end":{"line":104,"column":11}},"104":{"start":{"line":105,"column":0},"end":{"line":105,"column":35}},"105":{"start":{"line":106,"column":0},"end":{"line":106,"column":80}},"106":{"start":{"line":107,"column":0},"end":{"line":107,"column":9}},"107":{"start":{"line":108,"column":0},"end":{"line":108,"column":0}},"108":{"start":{"line":109,"column":0},"end":{"line":109,"column":63}},"109":{"start":{"line":110,"column":0},"end":{"line":110,"column":23}},"110":{"start":{"line":111,"column":0},"end":{"line":111,"column":9}},"111":{"start":{"line":112,"column":0},"end":{"line":112,"column":0}},"112":{"start":{"line":113,"column":0},"end":{"line":113,"column":48}},"113":{"start":{"line":114,"column":0},"end":{"line":114,"column":39}},"114":{"start":{"line":115,"column":0},"end":{"line":115,"column":24}},"115":{"start":{"line":116,"column":0},"end":{"line":116,"column":27}},"116":{"start":{"line":117,"column":0},"end":{"line":117,"column":25}},"117":{"start":{"line":118,"column":0},"end":{"line":118,"column":10}},"118":{"start":{"line":119,"column":0},"end":{"line":119,"column":0}},"119":{"start":{"line":120,"column":0},"end":{"line":120,"column":25}},"120":{"start":{"line":121,"column":0},"end":{"line":121,"column":47}},"121":{"start":{"line":122,"column":0},"end":{"line":122,"column":9}},"122":{"start":{"line":123,"column":0},"end":{"line":123,"column":19}},"123":{"start":{"line":124,"column":0},"end":{"line":124,"column":65}},"124":{"start":{"line":125,"column":0},"end":{"line":125,"column":7}},"125":{"start":{"line":126,"column":0},"end":{"line":126,"column":0}},"126":{"start":{"line":127,"column":0},"end":{"line":127,"column":19}},"127":{"start":{"line":128,"column":0},"end":{"line":128,"column":6}},"128":{"start":{"line":129,"column":0},"end":{"line":129,"column":3}},"129":{"start":{"line":130,"column":0},"end":{"line":130,"column":0}},"130":{"start":{"line":131,"column":0},"end":{"line":131,"column":43}},"131":{"start":{"line":132,"column":0},"end":{"line":132,"column":46}},"132":{"start":{"line":133,"column":0},"end":{"line":133,"column":0}},"133":{"start":{"line":134,"column":0},"end":{"line":134,"column":44}},"134":{"start":{"line":135,"column":0},"end":{"line":135,"column":11}},"135":{"start":{"line":136,"column":0},"end":{"line":136,"column":36}},"136":{"start":{"line":137,"column":0},"end":{"line":137,"column":60}},"137":{"start":{"line":138,"column":0},"end":{"line":138,"column":0}},"138":{"start":{"line":139,"column":0},"end":{"line":139,"column":65}},"139":{"start":{"line":140,"column":0},"end":{"line":140,"column":17}},"140":{"start":{"line":141,"column":0},"end":{"line":141,"column":9}},"141":{"start":{"line":142,"column":0},"end":{"line":142,"column":0}},"142":{"start":{"line":143,"column":0},"end":{"line":143,"column":56}},"143":{"start":{"line":144,"column":0},"end":{"line":144,"column":8}},"144":{"start":{"line":145,"column":0},"end":{"line":145,"column":25}},"145":{"start":{"line":146,"column":0},"end":{"line":146,"column":44}},"146":{"start":{"line":147,"column":0},"end":{"line":147,"column":47}},"147":{"start":{"line":148,"column":0},"end":{"line":148,"column":57}},"148":{"start":{"line":149,"column":0},"end":{"line":149,"column":32}},"149":{"start":{"line":150,"column":0},"end":{"line":150,"column":30}},"150":{"start":{"line":151,"column":0},"end":{"line":151,"column":14}},"151":{"start":{"line":152,"column":0},"end":{"line":152,"column":11}},"152":{"start":{"line":153,"column":0},"end":{"line":153,"column":0}},"153":{"start":{"line":154,"column":0},"end":{"line":154,"column":47}},"154":{"start":{"line":155,"column":0},"end":{"line":155,"column":9}},"155":{"start":{"line":156,"column":0},"end":{"line":156,"column":19}},"156":{"start":{"line":157,"column":0},"end":{"line":157,"column":71}},"157":{"start":{"line":158,"column":0},"end":{"line":158,"column":7}},"158":{"start":{"line":159,"column":0},"end":{"line":159,"column":6}},"159":{"start":{"line":160,"column":0},"end":{"line":160,"column":0}},"160":{"start":{"line":161,"column":0},"end":{"line":161,"column":77}},"161":{"start":{"line":162,"column":0},"end":{"line":162,"column":3}},"162":{"start":{"line":163,"column":0},"end":{"line":163,"column":0}},"163":{"start":{"line":164,"column":0},"end":{"line":164,"column":64}},"164":{"start":{"line":165,"column":0},"end":{"line":165,"column":50}},"165":{"start":{"line":166,"column":0},"end":{"line":166,"column":89}},"166":{"start":{"line":167,"column":0},"end":{"line":167,"column":18}},"167":{"start":{"line":168,"column":0},"end":{"line":168,"column":24}},"168":{"start":{"line":169,"column":0},"end":{"line":169,"column":7}},"169":{"start":{"line":170,"column":0},"end":{"line":170,"column":74}},"170":{"start":{"line":171,"column":0},"end":{"line":171,"column":21}},"171":{"start":{"line":172,"column":0},"end":{"line":172,"column":27}},"172":{"start":{"line":173,"column":0},"end":{"line":173,"column":7}},"173":{"start":{"line":174,"column":0},"end":{"line":174,"column":5}},"174":{"start":{"line":175,"column":0},"end":{"line":175,"column":16}},"175":{"start":{"line":176,"column":0},"end":{"line":176,"column":3}},"176":{"start":{"line":177,"column":0},"end":{"line":177,"column":0}},"177":{"start":{"line":178,"column":0},"end":{"line":178,"column":38}},"178":{"start":{"line":179,"column":0},"end":{"line":179,"column":46}},"179":{"start":{"line":180,"column":0},"end":{"line":180,"column":0}},"180":{"start":{"line":181,"column":0},"end":{"line":181,"column":39}},"181":{"start":{"line":182,"column":0},"end":{"line":182,"column":34}},"182":{"start":{"line":183,"column":0},"end":{"line":183,"column":26}},"183":{"start":{"line":184,"column":0},"end":{"line":184,"column":0}},"184":{"start":{"line":185,"column":0},"end":{"line":185,"column":69}},"185":{"start":{"line":186,"column":0},"end":{"line":186,"column":87}},"186":{"start":{"line":187,"column":0},"end":{"line":187,"column":0}},"187":{"start":{"line":188,"column":0},"end":{"line":188,"column":92}},"188":{"start":{"line":189,"column":0},"end":{"line":189,"column":13}},"189":{"start":{"line":190,"column":0},"end":{"line":190,"column":54}},"190":{"start":{"line":191,"column":0},"end":{"line":191,"column":51}},"191":{"start":{"line":192,"column":0},"end":{"line":192,"column":0}},"192":{"start":{"line":193,"column":0},"end":{"line":193,"column":52}},"193":{"start":{"line":194,"column":0},"end":{"line":194,"column":48}},"194":{"start":{"line":195,"column":0},"end":{"line":195,"column":36}},"195":{"start":{"line":196,"column":0},"end":{"line":196,"column":26}},"196":{"start":{"line":197,"column":0},"end":{"line":197,"column":29}},"197":{"start":{"line":198,"column":0},"end":{"line":198,"column":72}},"198":{"start":{"line":199,"column":0},"end":{"line":199,"column":29}},"199":{"start":{"line":200,"column":0},"end":{"line":200,"column":24}},"200":{"start":{"line":201,"column":0},"end":{"line":201,"column":19}},"201":{"start":{"line":202,"column":0},"end":{"line":202,"column":37}},"202":{"start":{"line":203,"column":0},"end":{"line":203,"column":41}},"203":{"start":{"line":204,"column":0},"end":{"line":204,"column":14}},"204":{"start":{"line":205,"column":0},"end":{"line":205,"column":24}},"205":{"start":{"line":206,"column":0},"end":{"line":206,"column":36}},"206":{"start":{"line":207,"column":0},"end":{"line":207,"column":58}},"207":{"start":{"line":208,"column":0},"end":{"line":208,"column":14}},"208":{"start":{"line":209,"column":0},"end":{"line":209,"column":13}},"209":{"start":{"line":210,"column":0},"end":{"line":210,"column":21}},"210":{"start":{"line":211,"column":0},"end":{"line":211,"column":69}},"211":{"start":{"line":212,"column":0},"end":{"line":212,"column":9}},"212":{"start":{"line":213,"column":0},"end":{"line":213,"column":7}},"213":{"start":{"line":214,"column":0},"end":{"line":214,"column":6}},"214":{"start":{"line":215,"column":0},"end":{"line":215,"column":0}},"215":{"start":{"line":216,"column":0},"end":{"line":216,"column":65}},"216":{"start":{"line":217,"column":0},"end":{"line":217,"column":3}},"217":{"start":{"line":218,"column":0},"end":{"line":218,"column":0}},"218":{"start":{"line":219,"column":0},"end":{"line":219,"column":145}},"219":{"start":{"line":220,"column":0},"end":{"line":220,"column":28}},"220":{"start":{"line":221,"column":0},"end":{"line":221,"column":0}},"221":{"start":{"line":222,"column":0},"end":{"line":222,"column":33}},"222":{"start":{"line":223,"column":0},"end":{"line":223,"column":61}},"223":{"start":{"line":224,"column":0},"end":{"line":224,"column":6}},"224":{"start":{"line":225,"column":0},"end":{"line":225,"column":51}},"225":{"start":{"line":226,"column":0},"end":{"line":226,"column":59}},"226":{"start":{"line":227,"column":0},"end":{"line":227,"column":49}},"227":{"start":{"line":228,"column":0},"end":{"line":228,"column":55}},"228":{"start":{"line":229,"column":0},"end":{"line":229,"column":46}},"229":{"start":{"line":230,"column":0},"end":{"line":230,"column":9}},"230":{"start":{"line":231,"column":0},"end":{"line":231,"column":0}},"231":{"start":{"line":232,"column":0},"end":{"line":232,"column":55}},"232":{"start":{"line":233,"column":0},"end":{"line":233,"column":44}},"233":{"start":{"line":234,"column":0},"end":{"line":234,"column":0}},"234":{"start":{"line":235,"column":0},"end":{"line":235,"column":80}},"235":{"start":{"line":236,"column":0},"end":{"line":236,"column":0}},"236":{"start":{"line":237,"column":0},"end":{"line":237,"column":14}},"237":{"start":{"line":238,"column":0},"end":{"line":238,"column":22}},"238":{"start":{"line":239,"column":0},"end":{"line":239,"column":23}},"239":{"start":{"line":240,"column":0},"end":{"line":240,"column":31}},"240":{"start":{"line":241,"column":0},"end":{"line":241,"column":18}},"241":{"start":{"line":242,"column":0},"end":{"line":242,"column":20}},"242":{"start":{"line":243,"column":0},"end":{"line":243,"column":27}},"243":{"start":{"line":244,"column":0},"end":{"line":244,"column":31}},"244":{"start":{"line":245,"column":0},"end":{"line":245,"column":23}},"245":{"start":{"line":246,"column":0},"end":{"line":246,"column":19}},"246":{"start":{"line":247,"column":0},"end":{"line":247,"column":12}},"247":{"start":{"line":248,"column":0},"end":{"line":248,"column":10}},"248":{"start":{"line":249,"column":0},"end":{"line":249,"column":20}},"249":{"start":{"line":250,"column":0},"end":{"line":250,"column":8}},"250":{"start":{"line":251,"column":0},"end":{"line":251,"column":5}},"251":{"start":{"line":252,"column":0},"end":{"line":252,"column":0}},"252":{"start":{"line":253,"column":0},"end":{"line":253,"column":34}},"253":{"start":{"line":254,"column":0},"end":{"line":254,"column":53}},"254":{"start":{"line":255,"column":0},"end":{"line":255,"column":0}},"255":{"start":{"line":256,"column":0},"end":{"line":256,"column":36}},"256":{"start":{"line":257,"column":0},"end":{"line":257,"column":14}},"257":{"start":{"line":258,"column":0},"end":{"line":258,"column":19}},"258":{"start":{"line":259,"column":0},"end":{"line":259,"column":22}},"259":{"start":{"line":260,"column":0},"end":{"line":260,"column":15}},"260":{"start":{"line":261,"column":0},"end":{"line":261,"column":61}},"261":{"start":{"line":262,"column":0},"end":{"line":262,"column":21}},"262":{"start":{"line":263,"column":0},"end":{"line":263,"column":9}},"263":{"start":{"line":264,"column":0},"end":{"line":264,"column":5}},"264":{"start":{"line":265,"column":0},"end":{"line":265,"column":0}},"265":{"start":{"line":266,"column":0},"end":{"line":266,"column":53}},"266":{"start":{"line":267,"column":0},"end":{"line":267,"column":42}},"267":{"start":{"line":268,"column":0},"end":{"line":268,"column":0}},"268":{"start":{"line":269,"column":0},"end":{"line":269,"column":12}},"269":{"start":{"line":270,"column":0},"end":{"line":270,"column":20}},"270":{"start":{"line":271,"column":0},"end":{"line":271,"column":21}},"271":{"start":{"line":272,"column":0},"end":{"line":272,"column":14}},"272":{"start":{"line":273,"column":0},"end":{"line":273,"column":16}},"273":{"start":{"line":274,"column":0},"end":{"line":274,"column":18}},"274":{"start":{"line":275,"column":0},"end":{"line":275,"column":22}},"275":{"start":{"line":276,"column":0},"end":{"line":276,"column":23}},"276":{"start":{"line":277,"column":0},"end":{"line":277,"column":21}},"277":{"start":{"line":278,"column":0},"end":{"line":278,"column":17}},"278":{"start":{"line":279,"column":0},"end":{"line":279,"column":10}},"279":{"start":{"line":280,"column":0},"end":{"line":280,"column":8}},"280":{"start":{"line":281,"column":0},"end":{"line":281,"column":6}},"281":{"start":{"line":282,"column":0},"end":{"line":282,"column":3}},"282":{"start":{"line":283,"column":0},"end":{"line":283,"column":0}},"283":{"start":{"line":284,"column":0},"end":{"line":284,"column":19}},"284":{"start":{"line":285,"column":0},"end":{"line":285,"column":40}},"285":{"start":{"line":286,"column":0},"end":{"line":286,"column":47}},"286":{"start":{"line":287,"column":0},"end":{"line":287,"column":46}},"287":{"start":{"line":288,"column":0},"end":{"line":288,"column":7}},"288":{"start":{"line":289,"column":0},"end":{"line":289,"column":38}},"289":{"start":{"line":290,"column":0},"end":{"line":290,"column":84}},"290":{"start":{"line":291,"column":0},"end":{"line":291,"column":7}},"291":{"start":{"line":292,"column":0},"end":{"line":292,"column":33}},"292":{"start":{"line":293,"column":0},"end":{"line":293,"column":72}},"293":{"start":{"line":294,"column":0},"end":{"line":294,"column":7}},"294":{"start":{"line":295,"column":0},"end":{"line":295,"column":5}},"295":{"start":{"line":296,"column":0},"end":{"line":296,"column":3}},"296":{"start":{"line":297,"column":0},"end":{"line":297,"column":1}},"297":{"start":{"line":298,"column":0},"end":{"line":298,"column":0}},"298":{"start":{"line":299,"column":0},"end":{"line":299,"column":27}}},"s":{"0":1,"1":1,"2":1,"3":1,"4":1,"5":1,"6":1,"7":1,"8":1,"9":1,"10":1,"11":1,"12":1,"13":1,"14":1,"15":1,"16":1,"17":1,"18":1,"19":0,"20":0,"21":0,"22":0,"23":0,"24":0,"25":0,"26":0,"27":0,"28":0,"29":0,"30":0,"31":1,"32":1,"33":1,"34":1,"35":1,"36":1,"37":0,"38":0,"39":0,"40":0,"41":0,"42":0,"43":1,"44":1,"45":0,"46":0,"47":0,"48":0,"49":0,"50":0,"51":0,"52":0,"53":0,"54":0,"55":0,"56":0,"57":0,"58":0,"59":1,"60":1,"61":0,"62":0,"63":0,"64":1,"65":1,"66":0,"67":0,"68":1,"69":1,"70":0,"71":0,"72":0,"73":0,"74":0,"75":0,"76":0,"77":0,"78":0,"79":0,"80":0,"81":0,"82":1,"83":1,"84":0,"85":0,"86":0,"87":0,"88":0,"89":1,"90":1,"91":0,"92":0,"93":0,"94":0,"95":0,"96":1,"97":1,"98":0,"99":0,"100":0,"101":0,"102":0,"103":0,"104":0,"105":0,"106":0,"107":0,"108":0,"109":0,"110":0,"111":0,"112":0,"113":0,"114":0,"115":0,"116":0,"117":0,"118":0,"119":0,"120":0,"121":0,"122":0,"123":0,"124":0,"125":0,"126":0,"127":0,"128":0,"129":1,"130":1,"131":0,"132":0,"133":0,"134":0,"135":0,"136":0,"137":0,"138":0,"139":0,"140":0,"141":0,"142":0,"143":0,"144":0,"145":0,"146":0,"147":0,"148":0,"149":0,"150":0,"151":0,"152":0,"153":0,"154":0,"155":0,"156":0,"157":0,"158":0,"159":0,"160":0,"161":0,"162":1,"163":1,"164":0,"165":0,"166":0,"167":0,"168":0,"169":0,"170":0,"171":0,"172":0,"173":0,"174":0,"175":0,"176":1,"177":1,"178":0,"179":0,"180":0,"181":0,"182":0,"183":0,"184":0,"185":0,"186":0,"187":0,"188":0,"189":0,"190":0,"191":0,"192":0,"193":0,"194":0,"195":0,"196":0,"197":0,"198":0,"199":0,"200":0,"201":0,"202":0,"203":0,"204":0,"205":0,"206":0,"207":0,"208":0,"209":0,"210":0,"211":0,"212":0,"213":0,"214":0,"215":0,"216":0,"217":1,"218":1,"219":0,"220":0,"221":0,"222":0,"223":0,"224":0,"225":0,"226":0,"227":0,"228":0,"229":0,"230":0,"231":0,"232":0,"233":0,"234":0,"235":0,"236":0,"237":0,"238":0,"239":0,"240":0,"241":0,"242":0,"243":0,"244":0,"245":0,"246":0,"247":0,"248":0,"249":0,"250":0,"251":0,"252":0,"253":0,"254":0,"255":0,"256":0,"257":0,"258":0,"259":0,"260":0,"261":0,"262":0,"263":0,"264":0,"265":0,"266":0,"267":0,"268":0,"269":0,"270":0,"271":0,"272":0,"273":0,"274":0,"275":0,"276":0,"277":0,"278":0,"279":0,"280":0,"281":0,"282":1,"283":1,"284":0,"285":0,"286":0,"287":0,"288":0,"289":0,"290":0,"291":0,"292":0,"293":0,"294":0,"295":0,"296":1,"297":1,"298":1},"branchMap":{},"b":{},"fnMap":{"0":{"name":"ErrorPlugin","decl":{"start":{"line":20,"column":0},"end":{"line":31,"column":4}},"loc":{"start":{"line":20,"column":0},"end":{"line":31,"column":4}},"line":20},"1":{"name":"setup","decl":{"start":{"line":37,"column":2},"end":{"line":43,"column":3}},"loc":{"start":{"line":37,"column":2},"end":{"line":43,"column":3}},"line":37},"2":{"name":"loadConfig","decl":{"start":{"line":45,"column":10},"end":{"line":59,"column":3}},"loc":{"start":{"line":45,"column":10},"end":{"line":59,"column":3}},"line":45},"3":{"name":"shouldIgnoreError","decl":{"start":{"line":61,"column":10},"end":{"line":64,"column":3}},"loc":{"start":{"line":61,"column":10},"end":{"line":64,"column":3}},"line":61},"4":{"name":"shouldIgnoreScriptUrl","decl":{"start":{"line":66,"column":10},"end":{"line":68,"column":3}},"loc":{"start":{"line":66,"column":10},"end":{"line":68,"column":3}},"line":66},"5":{"name":"shouldIncludePath","decl":{"start":{"line":70,"column":10},"end":{"line":82,"column":3}},"loc":{"start":{"line":70,"column":10},"end":{"line":82,"column":3}},"line":70},"6":{"name":"shouldSample","decl":{"start":{"line":84,"column":10},"end":{"line":89,"column":3}},"loc":{"start":{"line":84,"column":10},"end":{"line":89,"column":3}},"line":84},"7":{"name":"shouldSampleResource","decl":{"start":{"line":91,"column":10},"end":{"line":96,"column":3}},"loc":{"start":{"line":91,"column":10},"end":{"line":96,"column":3}},"line":91},"8":{"name":"setupGlobalError","decl":{"start":{"line":98,"column":10},"end":{"line":129,"column":3}},"loc":{"start":{"line":98,"column":10},"end":{"line":129,"column":3}},"line":98},"9":{"name":"setupUnhandledRejection","decl":{"start":{"line":131,"column":10},"end":{"line":162,"column":3}},"loc":{"start":{"line":131,"column":10},"end":{"line":162,"column":3}},"line":131},"10":{"name":"extractUrlFromReason","decl":{"start":{"line":164,"column":10},"end":{"line":176,"column":3}},"loc":{"start":{"line":164,"column":10},"end":{"line":176,"column":3}},"line":164},"11":{"name":"setupResourceError","decl":{"start":{"line":178,"column":10},"end":{"line":217,"column":3}},"loc":{"start":{"line":178,"column":10},"end":{"line":217,"column":3}},"line":178},"12":{"name":"buildErrorEvent","decl":{"start":{"line":219,"column":10},"end":{"line":282,"column":3}},"loc":{"start":{"line":219,"column":10},"end":{"line":282,"column":3}},"line":219},"13":{"name":"destroy","decl":{"start":{"line":284,"column":2},"end":{"line":296,"column":3}},"loc":{"start":{"line":284,"column":2},"end":{"line":296,"column":3}},"line":284}},"f":{"0":0,"1":0,"2":0,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10":0,"11":0,"12":0,"13":0}} +,"/Users/weidingjian/Desktop/work/ai/light-sentry-sdk/src/plugins/InteractionPlugin.ts": {"path":"/Users/weidingjian/Desktop/work/ai/light-sentry-sdk/src/plugins/InteractionPlugin.ts","all":false,"statementMap":{"0":{"start":{"line":1,"column":0},"end":{"line":1,"column":101}},"1":{"start":{"line":2,"column":0},"end":{"line":2,"column":48}},"2":{"start":{"line":3,"column":0},"end":{"line":3,"column":0}},"3":{"start":{"line":4,"column":0},"end":{"line":4,"column":35}},"4":{"start":{"line":5,"column":0},"end":{"line":5,"column":19}},"5":{"start":{"line":6,"column":0},"end":{"line":6,"column":28}},"6":{"start":{"line":7,"column":0},"end":{"line":7,"column":36}},"7":{"start":{"line":8,"column":0},"end":{"line":8,"column":25}},"8":{"start":{"line":9,"column":0},"end":{"line":9,"column":26}},"9":{"start":{"line":10,"column":0},"end":{"line":10,"column":23}},"10":{"start":{"line":11,"column":0},"end":{"line":11,"column":24}},"11":{"start":{"line":12,"column":0},"end":{"line":12,"column":26}},"12":{"start":{"line":13,"column":0},"end":{"line":13,"column":1}},"13":{"start":{"line":14,"column":0},"end":{"line":14,"column":0}},"14":{"start":{"line":15,"column":0},"end":{"line":15,"column":51}},"15":{"start":{"line":16,"column":0},"end":{"line":16,"column":0}},"16":{"start":{"line":17,"column":0},"end":{"line":17,"column":48}},"17":{"start":{"line":18,"column":0},"end":{"line":18,"column":23}},"18":{"start":{"line":19,"column":0},"end":{"line":19,"column":20}},"19":{"start":{"line":20,"column":0},"end":{"line":20,"column":0}},"20":{"start":{"line":21,"column":0},"end":{"line":21,"column":31}},"21":{"start":{"line":22,"column":0},"end":{"line":22,"column":45}},"22":{"start":{"line":23,"column":0},"end":{"line":23,"column":17}},"23":{"start":{"line":24,"column":0},"end":{"line":24,"column":46}},"24":{"start":{"line":25,"column":0},"end":{"line":25,"column":36}},"25":{"start":{"line":26,"column":0},"end":{"line":26,"column":24}},"26":{"start":{"line":27,"column":0},"end":{"line":27,"column":21}},"27":{"start":{"line":28,"column":0},"end":{"line":28,"column":22}},"28":{"start":{"line":29,"column":0},"end":{"line":29,"column":25}},"29":{"start":{"line":30,"column":0},"end":{"line":30,"column":4}},"30":{"start":{"line":31,"column":0},"end":{"line":31,"column":0}},"31":{"start":{"line":32,"column":0},"end":{"line":32,"column":56}},"32":{"start":{"line":33,"column":0},"end":{"line":33,"column":65}},"33":{"start":{"line":34,"column":0},"end":{"line":34,"column":72}},"34":{"start":{"line":35,"column":0},"end":{"line":35,"column":69}},"35":{"start":{"line":36,"column":0},"end":{"line":36,"column":0}},"36":{"start":{"line":37,"column":0},"end":{"line":37,"column":36}},"37":{"start":{"line":38,"column":0},"end":{"line":38,"column":25}},"38":{"start":{"line":39,"column":0},"end":{"line":39,"column":22}},"39":{"start":{"line":40,"column":0},"end":{"line":40,"column":0}},"40":{"start":{"line":41,"column":0},"end":{"line":41,"column":46}},"41":{"start":{"line":42,"column":0},"end":{"line":42,"column":36}},"42":{"start":{"line":43,"column":0},"end":{"line":43,"column":0}},"43":{"start":{"line":44,"column":0},"end":{"line":44,"column":33}},"44":{"start":{"line":45,"column":0},"end":{"line":45,"column":65}},"45":{"start":{"line":46,"column":0},"end":{"line":46,"column":5}},"46":{"start":{"line":47,"column":0},"end":{"line":47,"column":34}},"47":{"start":{"line":48,"column":0},"end":{"line":48,"column":67}},"48":{"start":{"line":49,"column":0},"end":{"line":49,"column":5}},"49":{"start":{"line":50,"column":0},"end":{"line":50,"column":3}},"50":{"start":{"line":51,"column":0},"end":{"line":51,"column":0}},"51":{"start":{"line":52,"column":0},"end":{"line":52,"column":30}},"52":{"start":{"line":53,"column":0},"end":{"line":53,"column":59}},"53":{"start":{"line":54,"column":0},"end":{"line":54,"column":90}},"54":{"start":{"line":55,"column":0},"end":{"line":55,"column":109}},"55":{"start":{"line":56,"column":0},"end":{"line":56,"column":5}},"56":{"start":{"line":57,"column":0},"end":{"line":57,"column":3}},"57":{"start":{"line":58,"column":0},"end":{"line":58,"column":0}},"58":{"start":{"line":59,"column":0},"end":{"line":59,"column":49}},"59":{"start":{"line":60,"column":0},"end":{"line":60,"column":43}},"60":{"start":{"line":61,"column":0},"end":{"line":61,"column":47}},"61":{"start":{"line":62,"column":0},"end":{"line":62,"column":61}},"62":{"start":{"line":63,"column":0},"end":{"line":63,"column":70}},"63":{"start":{"line":64,"column":0},"end":{"line":64,"column":4}},"64":{"start":{"line":65,"column":0},"end":{"line":65,"column":0}},"65":{"start":{"line":66,"column":0},"end":{"line":66,"column":50}},"66":{"start":{"line":67,"column":0},"end":{"line":67,"column":43}},"67":{"start":{"line":68,"column":0},"end":{"line":68,"column":47}},"68":{"start":{"line":69,"column":0},"end":{"line":69,"column":62}},"69":{"start":{"line":70,"column":0},"end":{"line":70,"column":71}},"70":{"start":{"line":71,"column":0},"end":{"line":71,"column":4}},"71":{"start":{"line":72,"column":0},"end":{"line":72,"column":0}},"72":{"start":{"line":73,"column":0},"end":{"line":73,"column":49}},"73":{"start":{"line":74,"column":0},"end":{"line":74,"column":47}},"74":{"start":{"line":75,"column":0},"end":{"line":75,"column":29}},"75":{"start":{"line":76,"column":0},"end":{"line":76,"column":0}},"76":{"start":{"line":77,"column":0},"end":{"line":77,"column":75}},"77":{"start":{"line":78,"column":0},"end":{"line":78,"column":18}},"78":{"start":{"line":79,"column":0},"end":{"line":79,"column":5}},"79":{"start":{"line":80,"column":0},"end":{"line":80,"column":0}},"80":{"start":{"line":81,"column":0},"end":{"line":81,"column":17}},"81":{"start":{"line":82,"column":0},"end":{"line":82,"column":3}},"82":{"start":{"line":83,"column":0},"end":{"line":83,"column":0}},"83":{"start":{"line":84,"column":0},"end":{"line":84,"column":96}},"84":{"start":{"line":85,"column":0},"end":{"line":85,"column":29}},"85":{"start":{"line":86,"column":0},"end":{"line":86,"column":39}},"86":{"start":{"line":87,"column":0},"end":{"line":87,"column":5}},"87":{"start":{"line":88,"column":0},"end":{"line":88,"column":0}},"88":{"start":{"line":89,"column":0},"end":{"line":89,"column":43}},"89":{"start":{"line":90,"column":0},"end":{"line":90,"column":58}},"90":{"start":{"line":91,"column":0},"end":{"line":91,"column":10}},"91":{"start":{"line":92,"column":0},"end":{"line":92,"column":3}},"92":{"start":{"line":93,"column":0},"end":{"line":93,"column":0}},"93":{"start":{"line":94,"column":0},"end":{"line":94,"column":82}},"94":{"start":{"line":95,"column":0},"end":{"line":95,"column":35}},"95":{"start":{"line":96,"column":0},"end":{"line":96,"column":0}},"96":{"start":{"line":97,"column":0},"end":{"line":97,"column":73}},"97":{"start":{"line":98,"column":0},"end":{"line":98,"column":53}},"98":{"start":{"line":99,"column":0},"end":{"line":99,"column":44}},"99":{"start":{"line":100,"column":0},"end":{"line":100,"column":0}},"100":{"start":{"line":101,"column":0},"end":{"line":101,"column":60}},"101":{"start":{"line":102,"column":0},"end":{"line":102,"column":50}},"102":{"start":{"line":103,"column":0},"end":{"line":103,"column":78}},"103":{"start":{"line":104,"column":0},"end":{"line":104,"column":64}},"104":{"start":{"line":105,"column":0},"end":{"line":105,"column":11}},"105":{"start":{"line":106,"column":0},"end":{"line":106,"column":0}},"106":{"start":{"line":107,"column":0},"end":{"line":107,"column":48}},"107":{"start":{"line":108,"column":0},"end":{"line":108,"column":3}},"108":{"start":{"line":109,"column":0},"end":{"line":109,"column":0}},"109":{"start":{"line":110,"column":0},"end":{"line":110,"column":93}},"110":{"start":{"line":111,"column":0},"end":{"line":111,"column":29}},"111":{"start":{"line":112,"column":0},"end":{"line":112,"column":0}},"112":{"start":{"line":113,"column":0},"end":{"line":113,"column":34}},"113":{"start":{"line":114,"column":0},"end":{"line":114,"column":42}},"114":{"start":{"line":115,"column":0},"end":{"line":115,"column":5}},"115":{"start":{"line":116,"column":0},"end":{"line":116,"column":0}},"116":{"start":{"line":117,"column":0},"end":{"line":117,"column":54}},"117":{"start":{"line":118,"column":0},"end":{"line":118,"column":11}},"118":{"start":{"line":119,"column":0},"end":{"line":119,"column":21}},"119":{"start":{"line":120,"column":0},"end":{"line":120,"column":43}},"120":{"start":{"line":121,"column":0},"end":{"line":121,"column":31}},"121":{"start":{"line":122,"column":0},"end":{"line":122,"column":13}},"122":{"start":{"line":123,"column":0},"end":{"line":123,"column":31}},"123":{"start":{"line":124,"column":0},"end":{"line":124,"column":35}},"124":{"start":{"line":125,"column":0},"end":{"line":125,"column":8}},"125":{"start":{"line":126,"column":0},"end":{"line":126,"column":13}},"126":{"start":{"line":127,"column":0},"end":{"line":127,"column":44}},"127":{"start":{"line":128,"column":0},"end":{"line":128,"column":36}},"128":{"start":{"line":129,"column":0},"end":{"line":129,"column":66}},"129":{"start":{"line":130,"column":0},"end":{"line":130,"column":8}},"130":{"start":{"line":131,"column":0},"end":{"line":131,"column":7}},"131":{"start":{"line":132,"column":0},"end":{"line":132,"column":0}},"132":{"start":{"line":133,"column":0},"end":{"line":133,"column":22}},"133":{"start":{"line":134,"column":0},"end":{"line":134,"column":44}},"134":{"start":{"line":135,"column":0},"end":{"line":135,"column":32}},"135":{"start":{"line":136,"column":0},"end":{"line":136,"column":33}},"136":{"start":{"line":137,"column":0},"end":{"line":137,"column":5}},"137":{"start":{"line":138,"column":0},"end":{"line":138,"column":3}},"138":{"start":{"line":139,"column":0},"end":{"line":139,"column":0}},"139":{"start":{"line":140,"column":0},"end":{"line":140,"column":38}},"140":{"start":{"line":141,"column":0},"end":{"line":141,"column":25}},"141":{"start":{"line":142,"column":0},"end":{"line":142,"column":35}},"142":{"start":{"line":143,"column":0},"end":{"line":143,"column":5}},"143":{"start":{"line":144,"column":0},"end":{"line":144,"column":0}},"144":{"start":{"line":145,"column":0},"end":{"line":145,"column":58}},"145":{"start":{"line":146,"column":0},"end":{"line":146,"column":0}},"146":{"start":{"line":147,"column":0},"end":{"line":147,"column":39}},"147":{"start":{"line":148,"column":0},"end":{"line":148,"column":42}},"148":{"start":{"line":149,"column":0},"end":{"line":149,"column":20}},"149":{"start":{"line":150,"column":0},"end":{"line":150,"column":3}},"150":{"start":{"line":151,"column":0},"end":{"line":151,"column":0}},"151":{"start":{"line":152,"column":0},"end":{"line":152,"column":39}},"152":{"start":{"line":153,"column":0},"end":{"line":153,"column":32}},"153":{"start":{"line":154,"column":0},"end":{"line":154,"column":42}},"154":{"start":{"line":155,"column":0},"end":{"line":155,"column":5}},"155":{"start":{"line":156,"column":0},"end":{"line":156,"column":0}},"156":{"start":{"line":157,"column":0},"end":{"line":157,"column":70}},"157":{"start":{"line":158,"column":0},"end":{"line":158,"column":46}},"158":{"start":{"line":159,"column":0},"end":{"line":159,"column":57}},"159":{"start":{"line":160,"column":0},"end":{"line":160,"column":20}},"160":{"start":{"line":161,"column":0},"end":{"line":161,"column":3}},"161":{"start":{"line":162,"column":0},"end":{"line":162,"column":0}},"162":{"start":{"line":163,"column":0},"end":{"line":163,"column":69}},"163":{"start":{"line":164,"column":0},"end":{"line":164,"column":25}},"164":{"start":{"line":165,"column":0},"end":{"line":165,"column":35}},"165":{"start":{"line":166,"column":0},"end":{"line":166,"column":28}},"166":{"start":{"line":167,"column":0},"end":{"line":167,"column":5}},"167":{"start":{"line":168,"column":0},"end":{"line":168,"column":32}},"168":{"start":{"line":169,"column":0},"end":{"line":169,"column":42}},"169":{"start":{"line":170,"column":0},"end":{"line":170,"column":35}},"170":{"start":{"line":171,"column":0},"end":{"line":171,"column":5}},"171":{"start":{"line":172,"column":0},"end":{"line":172,"column":29}},"172":{"start":{"line":173,"column":0},"end":{"line":173,"column":39}},"173":{"start":{"line":174,"column":0},"end":{"line":174,"column":32}},"174":{"start":{"line":175,"column":0},"end":{"line":175,"column":5}},"175":{"start":{"line":176,"column":0},"end":{"line":176,"column":0}},"176":{"start":{"line":177,"column":0},"end":{"line":177,"column":34}},"177":{"start":{"line":178,"column":0},"end":{"line":178,"column":48}},"178":{"start":{"line":179,"column":0},"end":{"line":179,"column":39}},"179":{"start":{"line":180,"column":0},"end":{"line":180,"column":37}},"180":{"start":{"line":181,"column":0},"end":{"line":181,"column":5}},"181":{"start":{"line":182,"column":0},"end":{"line":182,"column":3}},"182":{"start":{"line":183,"column":0},"end":{"line":183,"column":0}},"183":{"start":{"line":184,"column":0},"end":{"line":184,"column":19}},"184":{"start":{"line":185,"column":0},"end":{"line":185,"column":42}},"185":{"start":{"line":186,"column":0},"end":{"line":186,"column":68}},"186":{"start":{"line":187,"column":0},"end":{"line":187,"column":70}},"187":{"start":{"line":188,"column":0},"end":{"line":188,"column":5}},"188":{"start":{"line":189,"column":0},"end":{"line":189,"column":0}},"189":{"start":{"line":190,"column":0},"end":{"line":190,"column":25}},"190":{"start":{"line":191,"column":0},"end":{"line":191,"column":35}},"191":{"start":{"line":192,"column":0},"end":{"line":192,"column":28}},"192":{"start":{"line":193,"column":0},"end":{"line":193,"column":5}},"193":{"start":{"line":194,"column":0},"end":{"line":194,"column":32}},"194":{"start":{"line":195,"column":0},"end":{"line":195,"column":42}},"195":{"start":{"line":196,"column":0},"end":{"line":196,"column":35}},"196":{"start":{"line":197,"column":0},"end":{"line":197,"column":5}},"197":{"start":{"line":198,"column":0},"end":{"line":198,"column":29}},"198":{"start":{"line":199,"column":0},"end":{"line":199,"column":39}},"199":{"start":{"line":200,"column":0},"end":{"line":200,"column":32}},"200":{"start":{"line":201,"column":0},"end":{"line":201,"column":5}},"201":{"start":{"line":202,"column":0},"end":{"line":202,"column":0}},"202":{"start":{"line":203,"column":0},"end":{"line":203,"column":45}},"203":{"start":{"line":204,"column":0},"end":{"line":204,"column":3}},"204":{"start":{"line":205,"column":0},"end":{"line":205,"column":1}},"205":{"start":{"line":206,"column":0},"end":{"line":206,"column":0}},"206":{"start":{"line":207,"column":0},"end":{"line":207,"column":33}}},"s":{"0":1,"1":1,"2":1,"3":1,"4":1,"5":1,"6":1,"7":1,"8":1,"9":1,"10":1,"11":1,"12":1,"13":1,"14":1,"15":1,"16":0,"17":0,"18":0,"19":0,"20":0,"21":0,"22":0,"23":0,"24":0,"25":0,"26":0,"27":0,"28":0,"29":0,"30":0,"31":0,"32":0,"33":0,"34":0,"35":0,"36":0,"37":0,"38":0,"39":0,"40":0,"41":0,"42":0,"43":0,"44":0,"45":0,"46":0,"47":0,"48":0,"49":0,"50":0,"51":0,"52":0,"53":0,"54":0,"55":0,"56":0,"57":0,"58":0,"59":0,"60":0,"61":0,"62":0,"63":0,"64":0,"65":0,"66":0,"67":0,"68":0,"69":0,"70":0,"71":1,"72":1,"73":0,"74":0,"75":0,"76":0,"77":0,"78":0,"79":0,"80":0,"81":0,"82":1,"83":1,"84":0,"85":0,"86":0,"87":0,"88":0,"89":0,"90":0,"91":0,"92":1,"93":1,"94":0,"95":0,"96":0,"97":0,"98":0,"99":0,"100":0,"101":0,"102":0,"103":0,"104":0,"105":0,"106":0,"107":0,"108":1,"109":1,"110":0,"111":0,"112":0,"113":0,"114":0,"115":0,"116":0,"117":0,"118":0,"119":0,"120":0,"121":0,"122":0,"123":0,"124":0,"125":0,"126":0,"127":0,"128":0,"129":0,"130":0,"131":0,"132":0,"133":0,"134":0,"135":0,"136":0,"137":0,"138":1,"139":1,"140":0,"141":0,"142":0,"143":0,"144":0,"145":0,"146":0,"147":0,"148":0,"149":0,"150":1,"151":1,"152":0,"153":0,"154":0,"155":0,"156":0,"157":0,"158":0,"159":0,"160":0,"161":1,"162":1,"163":0,"164":0,"165":0,"166":0,"167":0,"168":0,"169":0,"170":0,"171":0,"172":0,"173":0,"174":0,"175":0,"176":0,"177":0,"178":0,"179":0,"180":0,"181":0,"182":1,"183":1,"184":0,"185":0,"186":0,"187":0,"188":0,"189":0,"190":0,"191":0,"192":0,"193":0,"194":0,"195":0,"196":0,"197":0,"198":0,"199":0,"200":0,"201":0,"202":0,"203":0,"204":1,"205":1,"206":1},"branchMap":{},"b":{},"fnMap":{"0":{"name":"InteractionPlugin","decl":{"start":{"line":17,"column":0},"end":{"line":71,"column":4}},"loc":{"start":{"line":17,"column":0},"end":{"line":71,"column":4}},"line":17},"1":{"name":"loadConfig","decl":{"start":{"line":52,"column":10},"end":{"line":57,"column":3}},"loc":{"start":{"line":52,"column":10},"end":{"line":57,"column":3}},"line":52},"2":{"name":"isEventIgnored","decl":{"start":{"line":73,"column":10},"end":{"line":82,"column":3}},"loc":{"start":{"line":73,"column":10},"end":{"line":82,"column":3}},"line":73},"3":{"name":"scheduleInteractionTransaction","decl":{"start":{"line":84,"column":10},"end":{"line":92,"column":3}},"loc":{"start":{"line":84,"column":10},"end":{"line":92,"column":3}},"line":84},"4":{"name":"getElementName","decl":{"start":{"line":94,"column":10},"end":{"line":108,"column":3}},"loc":{"start":{"line":94,"column":10},"end":{"line":108,"column":3}},"line":94},"5":{"name":"startInteractionTransaction","decl":{"start":{"line":110,"column":10},"end":{"line":138,"column":3}},"loc":{"start":{"line":110,"column":10},"end":{"line":138,"column":3}},"line":110},"6":{"name":"scheduleIdleFinish","decl":{"start":{"line":140,"column":10},"end":{"line":150,"column":3}},"loc":{"start":{"line":140,"column":10},"end":{"line":150,"column":3}},"line":140},"7":{"name":"scheduleMaxDuration","decl":{"start":{"line":152,"column":10},"end":{"line":161,"column":3}},"loc":{"start":{"line":152,"column":10},"end":{"line":161,"column":3}},"line":152},"8":{"name":"finishCurrentTransaction","decl":{"start":{"line":163,"column":10},"end":{"line":182,"column":3}},"loc":{"start":{"line":163,"column":10},"end":{"line":182,"column":3}},"line":163},"9":{"name":"destroy","decl":{"start":{"line":184,"column":2},"end":{"line":204,"column":3}},"loc":{"start":{"line":184,"column":2},"end":{"line":204,"column":3}},"line":184}},"f":{"0":0,"1":0,"2":0,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0}} +,"/Users/weidingjian/Desktop/work/ai/light-sentry-sdk/src/plugins/NetworkPlugin.ts": {"path":"/Users/weidingjian/Desktop/work/ai/light-sentry-sdk/src/plugins/NetworkPlugin.ts","all":false,"statementMap":{"0":{"start":{"line":1,"column":0},"end":{"line":1,"column":103}},"1":{"start":{"line":2,"column":0},"end":{"line":2,"column":48}},"2":{"start":{"line":3,"column":0},"end":{"line":3,"column":60}},"3":{"start":{"line":4,"column":0},"end":{"line":4,"column":0}},"4":{"start":{"line":5,"column":0},"end":{"line":5,"column":31}},"5":{"start":{"line":6,"column":0},"end":{"line":6,"column":35}},"6":{"start":{"line":7,"column":0},"end":{"line":7,"column":23}},"7":{"start":{"line":8,"column":0},"end":{"line":8,"column":25}},"8":{"start":{"line":9,"column":0},"end":{"line":9,"column":27}},"9":{"start":{"line":10,"column":0},"end":{"line":10,"column":24}},"10":{"start":{"line":11,"column":0},"end":{"line":11,"column":31}},"11":{"start":{"line":12,"column":0},"end":{"line":12,"column":32}},"12":{"start":{"line":13,"column":0},"end":{"line":13,"column":35}},"13":{"start":{"line":14,"column":0},"end":{"line":14,"column":36}},"14":{"start":{"line":15,"column":0},"end":{"line":15,"column":27}},"15":{"start":{"line":16,"column":0},"end":{"line":16,"column":29}},"16":{"start":{"line":17,"column":0},"end":{"line":17,"column":25}},"17":{"start":{"line":18,"column":0},"end":{"line":18,"column":26}},"18":{"start":{"line":19,"column":0},"end":{"line":19,"column":31}},"19":{"start":{"line":20,"column":0},"end":{"line":20,"column":48}},"20":{"start":{"line":21,"column":0},"end":{"line":21,"column":1}},"21":{"start":{"line":22,"column":0},"end":{"line":22,"column":0}},"22":{"start":{"line":23,"column":0},"end":{"line":23,"column":44}},"23":{"start":{"line":24,"column":0},"end":{"line":24,"column":19}},"24":{"start":{"line":25,"column":0},"end":{"line":25,"column":20}},"25":{"start":{"line":26,"column":0},"end":{"line":26,"column":0}},"26":{"start":{"line":27,"column":0},"end":{"line":27,"column":31}},"27":{"start":{"line":28,"column":0},"end":{"line":28,"column":41}},"28":{"start":{"line":29,"column":0},"end":{"line":29,"column":21}},"29":{"start":{"line":30,"column":0},"end":{"line":30,"column":23}},"30":{"start":{"line":31,"column":0},"end":{"line":31,"column":26}},"31":{"start":{"line":32,"column":0},"end":{"line":32,"column":23}},"32":{"start":{"line":33,"column":0},"end":{"line":33,"column":30}},"33":{"start":{"line":34,"column":0},"end":{"line":34,"column":31}},"34":{"start":{"line":35,"column":0},"end":{"line":35,"column":58}},"35":{"start":{"line":36,"column":0},"end":{"line":36,"column":63}},"36":{"start":{"line":37,"column":0},"end":{"line":37,"column":25}},"37":{"start":{"line":38,"column":0},"end":{"line":38,"column":28}},"38":{"start":{"line":39,"column":0},"end":{"line":39,"column":24}},"39":{"start":{"line":40,"column":0},"end":{"line":40,"column":24}},"40":{"start":{"line":41,"column":0},"end":{"line":41,"column":26}},"41":{"start":{"line":42,"column":0},"end":{"line":42,"column":4}},"42":{"start":{"line":43,"column":0},"end":{"line":43,"column":0}},"43":{"start":{"line":44,"column":0},"end":{"line":44,"column":39}},"44":{"start":{"line":45,"column":0},"end":{"line":45,"column":65}},"45":{"start":{"line":46,"column":0},"end":{"line":46,"column":65}},"46":{"start":{"line":47,"column":0},"end":{"line":47,"column":0}},"47":{"start":{"line":48,"column":0},"end":{"line":48,"column":36}},"48":{"start":{"line":49,"column":0},"end":{"line":49,"column":25}},"49":{"start":{"line":50,"column":0},"end":{"line":50,"column":22}},"50":{"start":{"line":51,"column":0},"end":{"line":51,"column":35}},"51":{"start":{"line":52,"column":0},"end":{"line":52,"column":24}},"52":{"start":{"line":53,"column":0},"end":{"line":53,"column":5}},"53":{"start":{"line":54,"column":0},"end":{"line":54,"column":33}},"54":{"start":{"line":55,"column":0},"end":{"line":55,"column":22}},"55":{"start":{"line":56,"column":0},"end":{"line":56,"column":5}},"56":{"start":{"line":57,"column":0},"end":{"line":57,"column":3}},"57":{"start":{"line":58,"column":0},"end":{"line":58,"column":0}},"58":{"start":{"line":59,"column":0},"end":{"line":59,"column":30}},"59":{"start":{"line":60,"column":0},"end":{"line":60,"column":59}},"60":{"start":{"line":61,"column":0},"end":{"line":61,"column":57}},"61":{"start":{"line":62,"column":0},"end":{"line":62,"column":76}},"62":{"start":{"line":63,"column":0},"end":{"line":63,"column":5}},"63":{"start":{"line":64,"column":0},"end":{"line":64,"column":34}},"64":{"start":{"line":65,"column":0},"end":{"line":65,"column":95}},"65":{"start":{"line":66,"column":0},"end":{"line":66,"column":5}},"66":{"start":{"line":67,"column":0},"end":{"line":67,"column":47}},"67":{"start":{"line":68,"column":0},"end":{"line":68,"column":134}},"68":{"start":{"line":69,"column":0},"end":{"line":69,"column":45}},"69":{"start":{"line":70,"column":0},"end":{"line":70,"column":125}},"70":{"start":{"line":71,"column":0},"end":{"line":71,"column":5}},"71":{"start":{"line":72,"column":0},"end":{"line":72,"column":3}},"72":{"start":{"line":73,"column":0},"end":{"line":73,"column":0}},"73":{"start":{"line":74,"column":0},"end":{"line":74,"column":46}},"74":{"start":{"line":75,"column":0},"end":{"line":75,"column":62}},"75":{"start":{"line":76,"column":0},"end":{"line":76,"column":3}},"76":{"start":{"line":77,"column":0},"end":{"line":77,"column":0}},"77":{"start":{"line":78,"column":0},"end":{"line":78,"column":54}},"78":{"start":{"line":79,"column":0},"end":{"line":79,"column":56}},"79":{"start":{"line":80,"column":0},"end":{"line":80,"column":43}},"80":{"start":{"line":81,"column":0},"end":{"line":81,"column":36}},"81":{"start":{"line":82,"column":0},"end":{"line":82,"column":5}},"82":{"start":{"line":83,"column":0},"end":{"line":83,"column":36}},"83":{"start":{"line":84,"column":0},"end":{"line":84,"column":40}},"84":{"start":{"line":85,"column":0},"end":{"line":85,"column":37}},"85":{"start":{"line":86,"column":0},"end":{"line":86,"column":7}},"86":{"start":{"line":87,"column":0},"end":{"line":87,"column":31}},"87":{"start":{"line":88,"column":0},"end":{"line":88,"column":7}},"88":{"start":{"line":89,"column":0},"end":{"line":89,"column":3}},"89":{"start":{"line":90,"column":0},"end":{"line":90,"column":0}},"90":{"start":{"line":91,"column":0},"end":{"line":91,"column":46}},"91":{"start":{"line":92,"column":0},"end":{"line":92,"column":54}},"92":{"start":{"line":93,"column":0},"end":{"line":93,"column":9}},"93":{"start":{"line":94,"column":0},"end":{"line":94,"column":51}},"94":{"start":{"line":95,"column":0},"end":{"line":95,"column":47}},"95":{"start":{"line":96,"column":0},"end":{"line":96,"column":13}},"96":{"start":{"line":97,"column":0},"end":{"line":97,"column":19}},"97":{"start":{"line":98,"column":0},"end":{"line":98,"column":5}},"98":{"start":{"line":99,"column":0},"end":{"line":99,"column":3}},"99":{"start":{"line":100,"column":0},"end":{"line":100,"column":0}},"100":{"start":{"line":101,"column":0},"end":{"line":101,"column":50}},"101":{"start":{"line":102,"column":0},"end":{"line":102,"column":39}},"102":{"start":{"line":103,"column":0},"end":{"line":103,"column":0}},"103":{"start":{"line":104,"column":0},"end":{"line":104,"column":54}},"104":{"start":{"line":105,"column":0},"end":{"line":105,"column":24}},"105":{"start":{"line":106,"column":0},"end":{"line":106,"column":57}},"106":{"start":{"line":107,"column":0},"end":{"line":107,"column":8}},"107":{"start":{"line":108,"column":0},"end":{"line":108,"column":6}},"108":{"start":{"line":109,"column":0},"end":{"line":109,"column":0}},"109":{"start":{"line":110,"column":0},"end":{"line":110,"column":72}},"110":{"start":{"line":111,"column":0},"end":{"line":111,"column":30}},"111":{"start":{"line":112,"column":0},"end":{"line":112,"column":0}},"112":{"start":{"line":113,"column":0},"end":{"line":113,"column":46}},"113":{"start":{"line":114,"column":0},"end":{"line":114,"column":43}},"114":{"start":{"line":115,"column":0},"end":{"line":115,"column":6}},"115":{"start":{"line":116,"column":0},"end":{"line":116,"column":0}},"116":{"start":{"line":117,"column":0},"end":{"line":117,"column":36}},"117":{"start":{"line":118,"column":0},"end":{"line":118,"column":41}},"118":{"start":{"line":119,"column":0},"end":{"line":119,"column":5}},"119":{"start":{"line":120,"column":0},"end":{"line":120,"column":0}},"120":{"start":{"line":121,"column":0},"end":{"line":121,"column":21}},"121":{"start":{"line":122,"column":0},"end":{"line":122,"column":3}},"122":{"start":{"line":123,"column":0},"end":{"line":123,"column":0}},"123":{"start":{"line":124,"column":0},"end":{"line":124,"column":69}},"124":{"start":{"line":125,"column":0},"end":{"line":125,"column":104}},"125":{"start":{"line":126,"column":0},"end":{"line":126,"column":4}},"126":{"start":{"line":127,"column":0},"end":{"line":127,"column":70}},"127":{"start":{"line":128,"column":0},"end":{"line":128,"column":47}},"128":{"start":{"line":129,"column":0},"end":{"line":129,"column":5}},"129":{"start":{"line":130,"column":0},"end":{"line":130,"column":4}},"130":{"start":{"line":131,"column":0},"end":{"line":131,"column":31}},"131":{"start":{"line":132,"column":0},"end":{"line":132,"column":32}},"132":{"start":{"line":133,"column":0},"end":{"line":133,"column":32}},"133":{"start":{"line":134,"column":0},"end":{"line":134,"column":3}},"134":{"start":{"line":135,"column":0},"end":{"line":135,"column":0}},"135":{"start":{"line":136,"column":0},"end":{"line":136,"column":68}},"136":{"start":{"line":137,"column":0},"end":{"line":137,"column":53}},"137":{"start":{"line":138,"column":0},"end":{"line":138,"column":34}},"138":{"start":{"line":139,"column":0},"end":{"line":139,"column":0}},"139":{"start":{"line":140,"column":0},"end":{"line":140,"column":41}},"140":{"start":{"line":141,"column":0},"end":{"line":141,"column":24}},"141":{"start":{"line":142,"column":0},"end":{"line":142,"column":52}},"142":{"start":{"line":143,"column":0},"end":{"line":143,"column":13}},"143":{"start":{"line":144,"column":0},"end":{"line":144,"column":44}},"144":{"start":{"line":145,"column":0},"end":{"line":145,"column":37}},"145":{"start":{"line":146,"column":0},"end":{"line":146,"column":8}},"146":{"start":{"line":147,"column":0},"end":{"line":147,"column":7}},"147":{"start":{"line":148,"column":0},"end":{"line":148,"column":0}},"148":{"start":{"line":149,"column":0},"end":{"line":149,"column":16}},"149":{"start":{"line":150,"column":0},"end":{"line":150,"column":3}},"150":{"start":{"line":151,"column":0},"end":{"line":151,"column":0}},"151":{"start":{"line":152,"column":0},"end":{"line":152,"column":100}},"152":{"start":{"line":153,"column":0},"end":{"line":153,"column":53}},"153":{"start":{"line":154,"column":0},"end":{"line":154,"column":0}},"154":{"start":{"line":155,"column":0},"end":{"line":155,"column":25}},"155":{"start":{"line":156,"column":0},"end":{"line":156,"column":37}},"156":{"start":{"line":157,"column":0},"end":{"line":157,"column":25}},"157":{"start":{"line":158,"column":0},"end":{"line":158,"column":39}},"158":{"start":{"line":159,"column":0},"end":{"line":159,"column":5}},"159":{"start":{"line":160,"column":0},"end":{"line":160,"column":0}},"160":{"start":{"line":161,"column":0},"end":{"line":161,"column":18}},"161":{"start":{"line":162,"column":0},"end":{"line":162,"column":3}},"162":{"start":{"line":163,"column":0},"end":{"line":163,"column":0}},"163":{"start":{"line":164,"column":0},"end":{"line":164,"column":30}},"164":{"start":{"line":165,"column":0},"end":{"line":165,"column":45}},"165":{"start":{"line":166,"column":0},"end":{"line":166,"column":0}},"166":{"start":{"line":167,"column":0},"end":{"line":167,"column":38}},"167":{"start":{"line":168,"column":0},"end":{"line":168,"column":22}},"168":{"start":{"line":169,"column":0},"end":{"line":169,"column":0}},"169":{"start":{"line":170,"column":0},"end":{"line":170,"column":95}},"170":{"start":{"line":171,"column":0},"end":{"line":171,"column":30}},"171":{"start":{"line":172,"column":0},"end":{"line":172,"column":106}},"172":{"start":{"line":173,"column":0},"end":{"line":173,"column":43}},"173":{"start":{"line":174,"column":0},"end":{"line":174,"column":0}},"174":{"start":{"line":175,"column":0},"end":{"line":175,"column":35}},"175":{"start":{"line":176,"column":0},"end":{"line":176,"column":60}},"176":{"start":{"line":177,"column":0},"end":{"line":177,"column":7}},"177":{"start":{"line":178,"column":0},"end":{"line":178,"column":0}},"178":{"start":{"line":179,"column":0},"end":{"line":179,"column":44}},"179":{"start":{"line":180,"column":0},"end":{"line":180,"column":0}},"180":{"start":{"line":181,"column":0},"end":{"line":181,"column":63}},"181":{"start":{"line":182,"column":0},"end":{"line":182,"column":0}},"182":{"start":{"line":183,"column":0},"end":{"line":183,"column":77}},"183":{"start":{"line":184,"column":0},"end":{"line":184,"column":30}},"184":{"start":{"line":185,"column":0},"end":{"line":185,"column":0}},"185":{"start":{"line":186,"column":0},"end":{"line":186,"column":42}},"186":{"start":{"line":187,"column":0},"end":{"line":187,"column":53}},"187":{"start":{"line":188,"column":0},"end":{"line":188,"column":48}},"188":{"start":{"line":189,"column":0},"end":{"line":189,"column":0}},"189":{"start":{"line":190,"column":0},"end":{"line":190,"column":24}},"190":{"start":{"line":191,"column":0},"end":{"line":191,"column":18}},"191":{"start":{"line":192,"column":0},"end":{"line":192,"column":20}},"192":{"start":{"line":193,"column":0},"end":{"line":193,"column":37}},"193":{"start":{"line":194,"column":0},"end":{"line":194,"column":40}},"194":{"start":{"line":195,"column":0},"end":{"line":195,"column":55}},"195":{"start":{"line":196,"column":0},"end":{"line":196,"column":12}},"196":{"start":{"line":197,"column":0},"end":{"line":197,"column":10}},"197":{"start":{"line":198,"column":0},"end":{"line":198,"column":7}},"198":{"start":{"line":199,"column":0},"end":{"line":199,"column":0}},"199":{"start":{"line":200,"column":0},"end":{"line":200,"column":75}},"200":{"start":{"line":201,"column":0},"end":{"line":201,"column":0}},"201":{"start":{"line":202,"column":0},"end":{"line":202,"column":19}},"202":{"start":{"line":203,"column":0},"end":{"line":203,"column":23}},"203":{"start":{"line":204,"column":0},"end":{"line":204,"column":45}},"204":{"start":{"line":205,"column":0},"end":{"line":205,"column":40}},"205":{"start":{"line":206,"column":0},"end":{"line":206,"column":45}},"206":{"start":{"line":207,"column":0},"end":{"line":207,"column":0}},"207":{"start":{"line":208,"column":0},"end":{"line":208,"column":25}},"208":{"start":{"line":209,"column":0},"end":{"line":209,"column":76}},"209":{"start":{"line":210,"column":0},"end":{"line":210,"column":11}},"210":{"start":{"line":211,"column":0},"end":{"line":211,"column":0}},"211":{"start":{"line":212,"column":0},"end":{"line":212,"column":68}},"212":{"start":{"line":213,"column":0},"end":{"line":213,"column":28}},"213":{"start":{"line":214,"column":0},"end":{"line":214,"column":11}},"214":{"start":{"line":215,"column":0},"end":{"line":215,"column":0}},"215":{"start":{"line":216,"column":0},"end":{"line":216,"column":57}},"216":{"start":{"line":217,"column":0},"end":{"line":217,"column":28}},"217":{"start":{"line":218,"column":0},"end":{"line":218,"column":11}},"218":{"start":{"line":219,"column":0},"end":{"line":219,"column":0}},"219":{"start":{"line":220,"column":0},"end":{"line":220,"column":57}},"220":{"start":{"line":221,"column":0},"end":{"line":221,"column":32}},"221":{"start":{"line":222,"column":0},"end":{"line":222,"column":32}},"222":{"start":{"line":223,"column":0},"end":{"line":223,"column":43}},"223":{"start":{"line":224,"column":0},"end":{"line":224,"column":32}},"224":{"start":{"line":225,"column":0},"end":{"line":225,"column":38}},"225":{"start":{"line":226,"column":0},"end":{"line":226,"column":23}},"226":{"start":{"line":227,"column":0},"end":{"line":227,"column":33}},"227":{"start":{"line":228,"column":0},"end":{"line":228,"column":67}},"228":{"start":{"line":229,"column":0},"end":{"line":229,"column":15}},"229":{"start":{"line":230,"column":0},"end":{"line":230,"column":11}},"230":{"start":{"line":231,"column":0},"end":{"line":231,"column":0}},"231":{"start":{"line":232,"column":0},"end":{"line":232,"column":26}},"232":{"start":{"line":233,"column":0},"end":{"line":233,"column":10}},"233":{"start":{"line":234,"column":0},"end":{"line":234,"column":20}},"234":{"start":{"line":235,"column":0},"end":{"line":235,"column":45}},"235":{"start":{"line":236,"column":0},"end":{"line":236,"column":0}},"236":{"start":{"line":237,"column":0},"end":{"line":237,"column":25}},"237":{"start":{"line":238,"column":0},"end":{"line":238,"column":61}},"238":{"start":{"line":239,"column":0},"end":{"line":239,"column":11}},"239":{"start":{"line":240,"column":0},"end":{"line":240,"column":0}},"240":{"start":{"line":241,"column":0},"end":{"line":241,"column":50}},"241":{"start":{"line":242,"column":0},"end":{"line":242,"column":32}},"242":{"start":{"line":243,"column":0},"end":{"line":243,"column":32}},"243":{"start":{"line":244,"column":0},"end":{"line":244,"column":43}},"244":{"start":{"line":245,"column":0},"end":{"line":245,"column":32}},"245":{"start":{"line":246,"column":0},"end":{"line":246,"column":23}},"246":{"start":{"line":247,"column":0},"end":{"line":247,"column":29}},"247":{"start":{"line":248,"column":0},"end":{"line":248,"column":55}},"248":{"start":{"line":249,"column":0},"end":{"line":249,"column":15}},"249":{"start":{"line":250,"column":0},"end":{"line":250,"column":11}},"250":{"start":{"line":251,"column":0},"end":{"line":251,"column":0}},"251":{"start":{"line":252,"column":0},"end":{"line":252,"column":22}},"252":{"start":{"line":253,"column":0},"end":{"line":253,"column":9}},"253":{"start":{"line":254,"column":0},"end":{"line":254,"column":8}},"254":{"start":{"line":255,"column":0},"end":{"line":255,"column":0}},"255":{"start":{"line":256,"column":0},"end":{"line":256,"column":21}},"256":{"start":{"line":257,"column":0},"end":{"line":257,"column":6}},"257":{"start":{"line":258,"column":0},"end":{"line":258,"column":3}},"258":{"start":{"line":259,"column":0},"end":{"line":259,"column":0}},"259":{"start":{"line":260,"column":0},"end":{"line":260,"column":28}},"260":{"start":{"line":261,"column":0},"end":{"line":261,"column":54}},"261":{"start":{"line":262,"column":0},"end":{"line":262,"column":0}},"262":{"start":{"line":263,"column":0},"end":{"line":263,"column":57}},"263":{"start":{"line":264,"column":0},"end":{"line":264,"column":57}},"264":{"start":{"line":265,"column":0},"end":{"line":265,"column":22}},"265":{"start":{"line":266,"column":0},"end":{"line":266,"column":0}},"266":{"start":{"line":267,"column":0},"end":{"line":267,"column":82}},"267":{"start":{"line":268,"column":0},"end":{"line":268,"column":64}},"268":{"start":{"line":269,"column":0},"end":{"line":269,"column":98}},"269":{"start":{"line":270,"column":0},"end":{"line":270,"column":66}},"270":{"start":{"line":271,"column":0},"end":{"line":271,"column":120}},"271":{"start":{"line":272,"column":0},"end":{"line":272,"column":6}},"272":{"start":{"line":273,"column":0},"end":{"line":273,"column":0}},"273":{"start":{"line":274,"column":0},"end":{"line":274,"column":96}},"274":{"start":{"line":275,"column":0},"end":{"line":275,"column":30}},"275":{"start":{"line":276,"column":0},"end":{"line":276,"column":79}},"276":{"start":{"line":277,"column":0},"end":{"line":277,"column":67}},"277":{"start":{"line":278,"column":0},"end":{"line":278,"column":74}},"278":{"start":{"line":279,"column":0},"end":{"line":279,"column":0}},"279":{"start":{"line":280,"column":0},"end":{"line":280,"column":46}},"280":{"start":{"line":281,"column":0},"end":{"line":281,"column":122}},"281":{"start":{"line":282,"column":0},"end":{"line":282,"column":7}},"282":{"start":{"line":283,"column":0},"end":{"line":283,"column":0}},"283":{"start":{"line":284,"column":0},"end":{"line":284,"column":65}},"284":{"start":{"line":285,"column":0},"end":{"line":285,"column":44}},"285":{"start":{"line":286,"column":0},"end":{"line":286,"column":26}},"286":{"start":{"line":287,"column":0},"end":{"line":287,"column":45}},"287":{"start":{"line":288,"column":0},"end":{"line":288,"column":34}},"288":{"start":{"line":289,"column":0},"end":{"line":289,"column":7}},"289":{"start":{"line":290,"column":0},"end":{"line":290,"column":0}},"290":{"start":{"line":291,"column":0},"end":{"line":291,"column":65}},"291":{"start":{"line":292,"column":0},"end":{"line":292,"column":77}},"292":{"start":{"line":293,"column":0},"end":{"line":293,"column":0}},"293":{"start":{"line":294,"column":0},"end":{"line":294,"column":42}},"294":{"start":{"line":295,"column":0},"end":{"line":295,"column":13}},"295":{"start":{"line":296,"column":0},"end":{"line":296,"column":55}},"296":{"start":{"line":297,"column":0},"end":{"line":297,"column":50}},"297":{"start":{"line":298,"column":0},"end":{"line":298,"column":61}},"298":{"start":{"line":299,"column":0},"end":{"line":299,"column":24}},"299":{"start":{"line":300,"column":0},"end":{"line":300,"column":54}},"300":{"start":{"line":301,"column":0},"end":{"line":301,"column":11}},"301":{"start":{"line":302,"column":0},"end":{"line":302,"column":17}},"302":{"start":{"line":303,"column":0},"end":{"line":303,"column":19}},"303":{"start":{"line":304,"column":0},"end":{"line":304,"column":9}},"304":{"start":{"line":305,"column":0},"end":{"line":305,"column":7}},"305":{"start":{"line":306,"column":0},"end":{"line":306,"column":0}},"306":{"start":{"line":307,"column":0},"end":{"line":307,"column":147}},"307":{"start":{"line":308,"column":0},"end":{"line":308,"column":153}},"308":{"start":{"line":309,"column":0},"end":{"line":309,"column":43}},"309":{"start":{"line":310,"column":0},"end":{"line":310,"column":35}},"310":{"start":{"line":311,"column":0},"end":{"line":311,"column":56}},"311":{"start":{"line":312,"column":0},"end":{"line":312,"column":0}},"312":{"start":{"line":313,"column":0},"end":{"line":313,"column":23}},"313":{"start":{"line":314,"column":0},"end":{"line":314,"column":70}},"314":{"start":{"line":315,"column":0},"end":{"line":315,"column":9}},"315":{"start":{"line":316,"column":0},"end":{"line":316,"column":0}},"316":{"start":{"line":317,"column":0},"end":{"line":317,"column":60}},"317":{"start":{"line":318,"column":0},"end":{"line":318,"column":54}},"318":{"start":{"line":319,"column":0},"end":{"line":319,"column":65}},"319":{"start":{"line":320,"column":0},"end":{"line":320,"column":31}},"320":{"start":{"line":321,"column":0},"end":{"line":321,"column":15}},"321":{"start":{"line":322,"column":0},"end":{"line":322,"column":72}},"322":{"start":{"line":323,"column":0},"end":{"line":323,"column":29}},"323":{"start":{"line":324,"column":0},"end":{"line":324,"column":54}},"324":{"start":{"line":325,"column":0},"end":{"line":325,"column":13}},"325":{"start":{"line":326,"column":0},"end":{"line":326,"column":53}},"326":{"start":{"line":327,"column":0},"end":{"line":327,"column":54}},"327":{"start":{"line":328,"column":0},"end":{"line":328,"column":13}},"328":{"start":{"line":329,"column":0},"end":{"line":329,"column":19}},"329":{"start":{"line":330,"column":0},"end":{"line":330,"column":21}},"330":{"start":{"line":331,"column":0},"end":{"line":331,"column":11}},"331":{"start":{"line":332,"column":0},"end":{"line":332,"column":0}},"332":{"start":{"line":333,"column":0},"end":{"line":333,"column":30}},"333":{"start":{"line":334,"column":0},"end":{"line":334,"column":28}},"334":{"start":{"line":335,"column":0},"end":{"line":335,"column":41}},"335":{"start":{"line":336,"column":0},"end":{"line":336,"column":30}},"336":{"start":{"line":337,"column":0},"end":{"line":337,"column":32}},"337":{"start":{"line":338,"column":0},"end":{"line":338,"column":21}},"338":{"start":{"line":339,"column":0},"end":{"line":339,"column":51}},"339":{"start":{"line":340,"column":0},"end":{"line":340,"column":53}},"340":{"start":{"line":341,"column":0},"end":{"line":341,"column":31}},"341":{"start":{"line":342,"column":0},"end":{"line":342,"column":61}},"342":{"start":{"line":343,"column":0},"end":{"line":343,"column":13}},"343":{"start":{"line":344,"column":0},"end":{"line":344,"column":9}},"344":{"start":{"line":345,"column":0},"end":{"line":345,"column":0}},"345":{"start":{"line":346,"column":0},"end":{"line":346,"column":32}},"346":{"start":{"line":347,"column":0},"end":{"line":347,"column":50}},"347":{"start":{"line":348,"column":0},"end":{"line":348,"column":9}},"348":{"start":{"line":349,"column":0},"end":{"line":349,"column":8}},"349":{"start":{"line":350,"column":0},"end":{"line":350,"column":0}},"350":{"start":{"line":351,"column":0},"end":{"line":351,"column":120}},"351":{"start":{"line":352,"column":0},"end":{"line":352,"column":6}},"352":{"start":{"line":353,"column":0},"end":{"line":353,"column":3}},"353":{"start":{"line":354,"column":0},"end":{"line":354,"column":0}},"354":{"start":{"line":355,"column":0},"end":{"line":355,"column":89}},"355":{"start":{"line":356,"column":0},"end":{"line":356,"column":33}},"356":{"start":{"line":357,"column":0},"end":{"line":357,"column":22}},"357":{"start":{"line":358,"column":0},"end":{"line":358,"column":45}},"358":{"start":{"line":359,"column":0},"end":{"line":359,"column":23}},"359":{"start":{"line":360,"column":0},"end":{"line":360,"column":13}},"360":{"start":{"line":361,"column":0},"end":{"line":361,"column":28}},"361":{"start":{"line":362,"column":0},"end":{"line":362,"column":32}},"362":{"start":{"line":363,"column":0},"end":{"line":363,"column":38}},"363":{"start":{"line":364,"column":0},"end":{"line":364,"column":8}},"364":{"start":{"line":365,"column":0},"end":{"line":365,"column":14}},"365":{"start":{"line":366,"column":0},"end":{"line":366,"column":6}},"366":{"start":{"line":367,"column":0},"end":{"line":367,"column":0}},"367":{"start":{"line":368,"column":0},"end":{"line":368,"column":36}},"368":{"start":{"line":369,"column":0},"end":{"line":369,"column":3}},"369":{"start":{"line":370,"column":0},"end":{"line":370,"column":0}},"370":{"start":{"line":371,"column":0},"end":{"line":371,"column":19}},"371":{"start":{"line":372,"column":0},"end":{"line":372,"column":29}},"372":{"start":{"line":373,"column":0},"end":{"line":373,"column":40}},"373":{"start":{"line":374,"column":0},"end":{"line":374,"column":5}},"374":{"start":{"line":375,"column":0},"end":{"line":375,"column":31}},"375":{"start":{"line":376,"column":0},"end":{"line":376,"column":59}},"376":{"start":{"line":377,"column":0},"end":{"line":377,"column":5}},"377":{"start":{"line":378,"column":0},"end":{"line":378,"column":31}},"378":{"start":{"line":379,"column":0},"end":{"line":379,"column":59}},"379":{"start":{"line":380,"column":0},"end":{"line":380,"column":5}},"380":{"start":{"line":381,"column":0},"end":{"line":381,"column":3}},"381":{"start":{"line":382,"column":0},"end":{"line":382,"column":1}},"382":{"start":{"line":383,"column":0},"end":{"line":383,"column":0}},"383":{"start":{"line":384,"column":0},"end":{"line":384,"column":29}}},"s":{"0":1,"1":1,"2":1,"3":1,"4":1,"5":1,"6":1,"7":1,"8":1,"9":1,"10":1,"11":1,"12":1,"13":1,"14":1,"15":1,"16":1,"17":1,"18":1,"19":1,"20":1,"21":1,"22":0,"23":0,"24":0,"25":0,"26":0,"27":0,"28":0,"29":0,"30":0,"31":0,"32":0,"33":0,"34":0,"35":0,"36":0,"37":0,"38":0,"39":0,"40":0,"41":0,"42":1,"43":1,"44":1,"45":1,"46":1,"47":1,"48":0,"49":0,"50":0,"51":0,"52":0,"53":0,"54":0,"55":0,"56":0,"57":1,"58":1,"59":0,"60":0,"61":0,"62":0,"63":0,"64":0,"65":0,"66":0,"67":0,"68":0,"69":0,"70":0,"71":0,"72":1,"73":1,"74":0,"75":0,"76":1,"77":1,"78":0,"79":0,"80":0,"81":0,"82":0,"83":0,"84":0,"85":0,"86":0,"87":0,"88":0,"89":1,"90":1,"91":0,"92":0,"93":0,"94":0,"95":0,"96":0,"97":0,"98":0,"99":1,"100":1,"101":0,"102":0,"103":0,"104":0,"105":0,"106":0,"107":0,"108":0,"109":0,"110":0,"111":0,"112":0,"113":0,"114":0,"115":0,"116":0,"117":0,"118":0,"119":0,"120":0,"121":0,"122":1,"123":1,"124":0,"125":0,"126":0,"127":0,"128":0,"129":0,"130":0,"131":0,"132":0,"133":0,"134":1,"135":1,"136":0,"137":0,"138":0,"139":0,"140":0,"141":0,"142":0,"143":0,"144":0,"145":0,"146":0,"147":0,"148":0,"149":0,"150":1,"151":1,"152":0,"153":0,"154":0,"155":0,"156":0,"157":0,"158":0,"159":0,"160":0,"161":0,"162":1,"163":1,"164":0,"165":0,"166":0,"167":0,"168":0,"169":0,"170":0,"171":0,"172":0,"173":0,"174":0,"175":0,"176":0,"177":0,"178":0,"179":0,"180":0,"181":0,"182":0,"183":0,"184":0,"185":0,"186":0,"187":0,"188":0,"189":0,"190":0,"191":0,"192":0,"193":0,"194":0,"195":0,"196":0,"197":0,"198":0,"199":0,"200":0,"201":0,"202":0,"203":0,"204":0,"205":0,"206":0,"207":0,"208":0,"209":0,"210":0,"211":0,"212":0,"213":0,"214":0,"215":0,"216":0,"217":0,"218":0,"219":0,"220":0,"221":0,"222":0,"223":0,"224":0,"225":0,"226":0,"227":0,"228":0,"229":0,"230":0,"231":0,"232":0,"233":0,"234":0,"235":0,"236":0,"237":0,"238":0,"239":0,"240":0,"241":0,"242":0,"243":0,"244":0,"245":0,"246":0,"247":0,"248":0,"249":0,"250":0,"251":0,"252":0,"253":0,"254":0,"255":0,"256":0,"257":0,"258":1,"259":1,"260":0,"261":0,"262":0,"263":0,"264":0,"265":0,"266":0,"267":0,"268":0,"269":0,"270":0,"271":0,"272":0,"273":0,"274":0,"275":0,"276":0,"277":0,"278":0,"279":0,"280":0,"281":0,"282":0,"283":0,"284":0,"285":0,"286":0,"287":0,"288":0,"289":0,"290":0,"291":0,"292":0,"293":0,"294":0,"295":0,"296":0,"297":0,"298":0,"299":0,"300":0,"301":0,"302":0,"303":0,"304":0,"305":0,"306":0,"307":0,"308":0,"309":0,"310":0,"311":0,"312":0,"313":0,"314":0,"315":0,"316":0,"317":0,"318":0,"319":0,"320":0,"321":0,"322":0,"323":0,"324":0,"325":0,"326":0,"327":0,"328":0,"329":0,"330":0,"331":0,"332":0,"333":0,"334":0,"335":0,"336":0,"337":0,"338":0,"339":0,"340":0,"341":0,"342":0,"343":0,"344":0,"345":0,"346":0,"347":0,"348":0,"349":0,"350":0,"351":0,"352":0,"353":1,"354":1,"355":0,"356":0,"357":0,"358":0,"359":0,"360":0,"361":0,"362":0,"363":0,"364":0,"365":0,"366":0,"367":0,"368":0,"369":1,"370":1,"371":0,"372":0,"373":0,"374":0,"375":0,"376":0,"377":0,"378":0,"379":0,"380":0,"381":1,"382":1,"383":1},"branchMap":{},"b":{},"fnMap":{"0":{"name":"NetworkPlugin","decl":{"start":{"line":23,"column":0},"end":{"line":42,"column":4}},"loc":{"start":{"line":23,"column":0},"end":{"line":42,"column":4}},"line":23},"1":{"name":"setup","decl":{"start":{"line":48,"column":2},"end":{"line":57,"column":3}},"loc":{"start":{"line":48,"column":2},"end":{"line":57,"column":3}},"line":48},"2":{"name":"loadConfig","decl":{"start":{"line":59,"column":10},"end":{"line":72,"column":3}},"loc":{"start":{"line":59,"column":10},"end":{"line":72,"column":3}},"line":59},"3":{"name":"shouldIgnore","decl":{"start":{"line":74,"column":10},"end":{"line":76,"column":3}},"loc":{"start":{"line":74,"column":10},"end":{"line":76,"column":3}},"line":74},"4":{"name":"shouldTracePropagate","decl":{"start":{"line":78,"column":10},"end":{"line":89,"column":3}},"loc":{"start":{"line":78,"column":10},"end":{"line":89,"column":3}},"line":78},"5":{"name":"isSameOrigin","decl":{"start":{"line":91,"column":10},"end":{"line":99,"column":3}},"loc":{"start":{"line":91,"column":10},"end":{"line":99,"column":3}},"line":91},"6":{"name":"getBaggageHeader","decl":{"start":{"line":101,"column":10},"end":{"line":122,"column":3}},"loc":{"start":{"line":101,"column":10},"end":{"line":122,"column":3}},"line":101},"7":{"name":"shouldSample","decl":{"start":{"line":124,"column":10},"end":{"line":134,"column":3}},"loc":{"start":{"line":124,"column":10},"end":{"line":134,"column":3}},"line":124},"8":{"name":"createHttpSpan","decl":{"start":{"line":136,"column":10},"end":{"line":150,"column":3}},"loc":{"start":{"line":136,"column":10},"end":{"line":150,"column":3}},"line":136},"9":{"name":"finishHttpSpan","decl":{"start":{"line":152,"column":10},"end":{"line":162,"column":3}},"loc":{"start":{"line":152,"column":10},"end":{"line":162,"column":3}},"line":152},"10":{"name":"patchFetch","decl":{"start":{"line":164,"column":10},"end":{"line":258,"column":3}},"loc":{"start":{"line":164,"column":10},"end":{"line":258,"column":3}},"line":164},"11":{"name":"patchXHR","decl":{"start":{"line":260,"column":10},"end":{"line":353,"column":3}},"loc":{"start":{"line":260,"column":10},"end":{"line":353,"column":3}},"line":260},"12":{"name":"reportNetwork","decl":{"start":{"line":355,"column":10},"end":{"line":369,"column":3}},"loc":{"start":{"line":355,"column":10},"end":{"line":369,"column":3}},"line":355},"13":{"name":"destroy","decl":{"start":{"line":371,"column":2},"end":{"line":381,"column":3}},"loc":{"start":{"line":371,"column":2},"end":{"line":381,"column":3}},"line":371}},"f":{"0":0,"1":0,"2":0,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10":0,"11":0,"12":0,"13":0}} +,"/Users/weidingjian/Desktop/work/ai/light-sentry-sdk/src/plugins/OfflinePlugin.ts": {"path":"/Users/weidingjian/Desktop/work/ai/light-sentry-sdk/src/plugins/OfflinePlugin.ts","all":false,"statementMap":{"0":{"start":{"line":1,"column":0},"end":{"line":1,"column":83}},"1":{"start":{"line":2,"column":0},"end":{"line":2,"column":38}},"2":{"start":{"line":3,"column":0},"end":{"line":3,"column":0}},"3":{"start":{"line":4,"column":0},"end":{"line":4,"column":39}},"4":{"start":{"line":5,"column":0},"end":{"line":5,"column":28}},"5":{"start":{"line":6,"column":0},"end":{"line":6,"column":24}},"6":{"start":{"line":7,"column":0},"end":{"line":7,"column":0}},"7":{"start":{"line":8,"column":0},"end":{"line":8,"column":24}},"8":{"start":{"line":9,"column":0},"end":{"line":9,"column":13}},"9":{"start":{"line":10,"column":0},"end":{"line":10,"column":21}},"10":{"start":{"line":11,"column":0},"end":{"line":11,"column":20}},"11":{"start":{"line":12,"column":0},"end":{"line":12,"column":1}},"12":{"start":{"line":13,"column":0},"end":{"line":13,"column":0}},"13":{"start":{"line":14,"column":0},"end":{"line":14,"column":44}},"14":{"start":{"line":15,"column":0},"end":{"line":15,"column":19}},"15":{"start":{"line":16,"column":0},"end":{"line":16,"column":20}},"16":{"start":{"line":17,"column":0},"end":{"line":17,"column":0}},"17":{"start":{"line":18,"column":0},"end":{"line":18,"column":31}},"18":{"start":{"line":19,"column":0},"end":{"line":19,"column":69}},"19":{"start":{"line":20,"column":0},"end":{"line":20,"column":40}},"20":{"start":{"line":21,"column":0},"end":{"line":21,"column":35}},"21":{"start":{"line":22,"column":0},"end":{"line":22,"column":37}},"22":{"start":{"line":23,"column":0},"end":{"line":23,"column":32}},"23":{"start":{"line":24,"column":0},"end":{"line":24,"column":33}},"24":{"start":{"line":25,"column":0},"end":{"line":25,"column":44}},"25":{"start":{"line":26,"column":0},"end":{"line":26,"column":0}},"26":{"start":{"line":27,"column":0},"end":{"line":27,"column":36}},"27":{"start":{"line":28,"column":0},"end":{"line":28,"column":25}},"28":{"start":{"line":29,"column":0},"end":{"line":29,"column":22}},"29":{"start":{"line":30,"column":0},"end":{"line":30,"column":24}},"30":{"start":{"line":31,"column":0},"end":{"line":31,"column":33}},"31":{"start":{"line":32,"column":0},"end":{"line":32,"column":3}},"32":{"start":{"line":33,"column":0},"end":{"line":33,"column":0}},"33":{"start":{"line":34,"column":0},"end":{"line":34,"column":30}},"34":{"start":{"line":35,"column":0},"end":{"line":35,"column":59}},"35":{"start":{"line":36,"column":0},"end":{"line":36,"column":67}},"36":{"start":{"line":37,"column":0},"end":{"line":37,"column":76}},"37":{"start":{"line":38,"column":0},"end":{"line":38,"column":5}},"38":{"start":{"line":39,"column":0},"end":{"line":39,"column":3}},"39":{"start":{"line":40,"column":0},"end":{"line":40,"column":0}},"40":{"start":{"line":41,"column":0},"end":{"line":41,"column":47}},"41":{"start":{"line":42,"column":0},"end":{"line":42,"column":43}},"42":{"start":{"line":43,"column":0},"end":{"line":43,"column":72}},"43":{"start":{"line":44,"column":0},"end":{"line":44,"column":13}},"44":{"start":{"line":45,"column":0},"end":{"line":45,"column":5}},"45":{"start":{"line":46,"column":0},"end":{"line":46,"column":0}},"46":{"start":{"line":47,"column":0},"end":{"line":47,"column":45}},"47":{"start":{"line":48,"column":0},"end":{"line":48,"column":49}},"48":{"start":{"line":49,"column":0},"end":{"line":49,"column":0}},"49":{"start":{"line":50,"column":0},"end":{"line":50,"column":31}},"50":{"start":{"line":51,"column":0},"end":{"line":51,"column":75}},"51":{"start":{"line":52,"column":0},"end":{"line":52,"column":30}},"52":{"start":{"line":53,"column":0},"end":{"line":53,"column":8}},"53":{"start":{"line":54,"column":0},"end":{"line":54,"column":0}},"54":{"start":{"line":55,"column":0},"end":{"line":55,"column":33}},"55":{"start":{"line":56,"column":0},"end":{"line":56,"column":33}},"56":{"start":{"line":57,"column":0},"end":{"line":57,"column":18}},"57":{"start":{"line":58,"column":0},"end":{"line":58,"column":8}},"58":{"start":{"line":59,"column":0},"end":{"line":59,"column":0}},"59":{"start":{"line":60,"column":0},"end":{"line":60,"column":44}},"60":{"start":{"line":61,"column":0},"end":{"line":61,"column":61}},"61":{"start":{"line":62,"column":0},"end":{"line":62,"column":48}},"62":{"start":{"line":63,"column":0},"end":{"line":63,"column":8}},"63":{"start":{"line":64,"column":0},"end":{"line":64,"column":56}},"64":{"start":{"line":65,"column":0},"end":{"line":65,"column":76}},"65":{"start":{"line":66,"column":0},"end":{"line":66,"column":73}},"66":{"start":{"line":67,"column":0},"end":{"line":67,"column":9}},"67":{"start":{"line":68,"column":0},"end":{"line":68,"column":8}},"68":{"start":{"line":69,"column":0},"end":{"line":69,"column":25}},"69":{"start":{"line":70,"column":0},"end":{"line":70,"column":42}},"70":{"start":{"line":71,"column":0},"end":{"line":71,"column":8}},"71":{"start":{"line":72,"column":0},"end":{"line":72,"column":7}},"72":{"start":{"line":73,"column":0},"end":{"line":73,"column":3}},"73":{"start":{"line":74,"column":0},"end":{"line":74,"column":0}},"74":{"start":{"line":75,"column":0},"end":{"line":75,"column":41}},"75":{"start":{"line":76,"column":0},"end":{"line":76,"column":46}},"76":{"start":{"line":77,"column":0},"end":{"line":77,"column":0}},"77":{"start":{"line":78,"column":0},"end":{"line":78,"column":37}},"78":{"start":{"line":79,"column":0},"end":{"line":79,"column":0}},"79":{"start":{"line":80,"column":0},"end":{"line":80,"column":27}},"80":{"start":{"line":81,"column":0},"end":{"line":81,"column":63}},"81":{"start":{"line":82,"column":0},"end":{"line":82,"column":27}},"82":{"start":{"line":83,"column":0},"end":{"line":83,"column":31}},"83":{"start":{"line":84,"column":0},"end":{"line":84,"column":6}},"84":{"start":{"line":85,"column":0},"end":{"line":85,"column":0}},"85":{"start":{"line":86,"column":0},"end":{"line":86,"column":28}},"86":{"start":{"line":87,"column":0},"end":{"line":87,"column":64}},"87":{"start":{"line":88,"column":0},"end":{"line":88,"column":28}},"88":{"start":{"line":89,"column":0},"end":{"line":89,"column":6}},"89":{"start":{"line":90,"column":0},"end":{"line":90,"column":0}},"90":{"start":{"line":91,"column":0},"end":{"line":91,"column":53}},"91":{"start":{"line":92,"column":0},"end":{"line":92,"column":55}},"92":{"start":{"line":93,"column":0},"end":{"line":93,"column":3}},"93":{"start":{"line":94,"column":0},"end":{"line":94,"column":0}},"94":{"start":{"line":95,"column":0},"end":{"line":95,"column":32}},"95":{"start":{"line":96,"column":0},"end":{"line":96,"column":74}},"96":{"start":{"line":97,"column":0},"end":{"line":97,"column":3}},"97":{"start":{"line":98,"column":0},"end":{"line":98,"column":0}},"98":{"start":{"line":99,"column":0},"end":{"line":99,"column":68}},"99":{"start":{"line":100,"column":0},"end":{"line":100,"column":25}},"100":{"start":{"line":101,"column":0},"end":{"line":101,"column":0}},"101":{"start":{"line":102,"column":0},"end":{"line":102,"column":58}},"102":{"start":{"line":103,"column":0},"end":{"line":103,"column":0}},"103":{"start":{"line":104,"column":0},"end":{"line":104,"column":45}},"104":{"start":{"line":105,"column":0},"end":{"line":105,"column":29}},"105":{"start":{"line":106,"column":0},"end":{"line":106,"column":59}},"106":{"start":{"line":107,"column":0},"end":{"line":107,"column":5}},"107":{"start":{"line":108,"column":0},"end":{"line":108,"column":0}},"108":{"start":{"line":109,"column":0},"end":{"line":109,"column":45}},"109":{"start":{"line":110,"column":0},"end":{"line":110,"column":74}},"110":{"start":{"line":111,"column":0},"end":{"line":111,"column":56}},"111":{"start":{"line":112,"column":0},"end":{"line":112,"column":0}},"112":{"start":{"line":113,"column":0},"end":{"line":113,"column":42}},"113":{"start":{"line":114,"column":0},"end":{"line":114,"column":30}},"114":{"start":{"line":115,"column":0},"end":{"line":115,"column":16}},"115":{"start":{"line":116,"column":0},"end":{"line":116,"column":19}},"116":{"start":{"line":117,"column":0},"end":{"line":117,"column":24}},"117":{"start":{"line":118,"column":0},"end":{"line":118,"column":36}},"118":{"start":{"line":119,"column":0},"end":{"line":119,"column":25}},"119":{"start":{"line":120,"column":0},"end":{"line":120,"column":8}},"120":{"start":{"line":121,"column":0},"end":{"line":121,"column":0}},"121":{"start":{"line":122,"column":0},"end":{"line":122,"column":49}},"122":{"start":{"line":123,"column":0},"end":{"line":123,"column":45}},"123":{"start":{"line":124,"column":0},"end":{"line":124,"column":58}},"124":{"start":{"line":125,"column":0},"end":{"line":125,"column":7}},"125":{"start":{"line":126,"column":0},"end":{"line":126,"column":3}},"126":{"start":{"line":127,"column":0},"end":{"line":127,"column":0}},"127":{"start":{"line":128,"column":0},"end":{"line":128,"column":44}},"128":{"start":{"line":129,"column":0},"end":{"line":129,"column":44}},"129":{"start":{"line":130,"column":0},"end":{"line":130,"column":0}},"130":{"start":{"line":131,"column":0},"end":{"line":131,"column":45}},"131":{"start":{"line":132,"column":0},"end":{"line":132,"column":73}},"132":{"start":{"line":133,"column":0},"end":{"line":133,"column":56}},"133":{"start":{"line":134,"column":0},"end":{"line":134,"column":41}},"134":{"start":{"line":135,"column":0},"end":{"line":135,"column":66}},"135":{"start":{"line":136,"column":0},"end":{"line":136,"column":62}},"136":{"start":{"line":137,"column":0},"end":{"line":137,"column":7}},"137":{"start":{"line":138,"column":0},"end":{"line":138,"column":3}},"138":{"start":{"line":139,"column":0},"end":{"line":139,"column":0}},"139":{"start":{"line":140,"column":0},"end":{"line":140,"column":66}},"140":{"start":{"line":141,"column":0},"end":{"line":141,"column":39}},"141":{"start":{"line":142,"column":0},"end":{"line":142,"column":0}},"142":{"start":{"line":143,"column":0},"end":{"line":143,"column":45}},"143":{"start":{"line":144,"column":0},"end":{"line":144,"column":74}},"144":{"start":{"line":145,"column":0},"end":{"line":145,"column":56}},"145":{"start":{"line":146,"column":0},"end":{"line":146,"column":45}},"146":{"start":{"line":147,"column":0},"end":{"line":147,"column":0}},"147":{"start":{"line":148,"column":0},"end":{"line":148,"column":47}},"148":{"start":{"line":149,"column":0},"end":{"line":149,"column":22}},"149":{"start":{"line":150,"column":0},"end":{"line":150,"column":0}},"150":{"start":{"line":151,"column":0},"end":{"line":151,"column":44}},"151":{"start":{"line":152,"column":0},"end":{"line":152,"column":79}},"152":{"start":{"line":153,"column":0},"end":{"line":153,"column":40}},"153":{"start":{"line":154,"column":0},"end":{"line":154,"column":26}},"154":{"start":{"line":155,"column":0},"end":{"line":155,"column":20}},"155":{"start":{"line":156,"column":0},"end":{"line":156,"column":28}},"156":{"start":{"line":157,"column":0},"end":{"line":157,"column":16}},"157":{"start":{"line":158,"column":0},"end":{"line":158,"column":20}},"158":{"start":{"line":159,"column":0},"end":{"line":159,"column":9}},"159":{"start":{"line":160,"column":0},"end":{"line":160,"column":8}},"160":{"start":{"line":161,"column":0},"end":{"line":161,"column":0}},"161":{"start":{"line":162,"column":0},"end":{"line":162,"column":64}},"162":{"start":{"line":163,"column":0},"end":{"line":163,"column":7}},"163":{"start":{"line":164,"column":0},"end":{"line":164,"column":3}},"164":{"start":{"line":165,"column":0},"end":{"line":165,"column":0}},"165":{"start":{"line":166,"column":0},"end":{"line":166,"column":63}},"166":{"start":{"line":167,"column":0},"end":{"line":167,"column":28}},"167":{"start":{"line":168,"column":0},"end":{"line":168,"column":0}},"168":{"start":{"line":169,"column":0},"end":{"line":169,"column":45}},"169":{"start":{"line":170,"column":0},"end":{"line":170,"column":73}},"170":{"start":{"line":171,"column":0},"end":{"line":171,"column":56}},"171":{"start":{"line":172,"column":0},"end":{"line":172,"column":45}},"172":{"start":{"line":173,"column":0},"end":{"line":173,"column":37}},"173":{"start":{"line":174,"column":0},"end":{"line":174,"column":0}},"174":{"start":{"line":175,"column":0},"end":{"line":175,"column":33}},"175":{"start":{"line":176,"column":0},"end":{"line":176,"column":44}},"176":{"start":{"line":177,"column":0},"end":{"line":177,"column":16}},"177":{"start":{"line":178,"column":0},"end":{"line":178,"column":57}},"178":{"start":{"line":179,"column":0},"end":{"line":179,"column":24}},"179":{"start":{"line":180,"column":0},"end":{"line":180,"column":8}},"180":{"start":{"line":181,"column":0},"end":{"line":181,"column":0}},"181":{"start":{"line":182,"column":0},"end":{"line":182,"column":52}},"182":{"start":{"line":183,"column":0},"end":{"line":183,"column":7}},"183":{"start":{"line":184,"column":0},"end":{"line":184,"column":3}},"184":{"start":{"line":185,"column":0},"end":{"line":185,"column":0}},"185":{"start":{"line":186,"column":0},"end":{"line":186,"column":52}},"186":{"start":{"line":187,"column":0},"end":{"line":187,"column":25}},"187":{"start":{"line":188,"column":0},"end":{"line":188,"column":0}},"188":{"start":{"line":189,"column":0},"end":{"line":189,"column":45}},"189":{"start":{"line":190,"column":0},"end":{"line":190,"column":74}},"190":{"start":{"line":191,"column":0},"end":{"line":191,"column":56}},"191":{"start":{"line":192,"column":0},"end":{"line":192,"column":36}},"192":{"start":{"line":193,"column":0},"end":{"line":193,"column":0}},"193":{"start":{"line":194,"column":0},"end":{"line":194,"column":42}},"194":{"start":{"line":195,"column":0},"end":{"line":195,"column":52}},"195":{"start":{"line":196,"column":0},"end":{"line":196,"column":7}},"196":{"start":{"line":197,"column":0},"end":{"line":197,"column":3}},"197":{"start":{"line":198,"column":0},"end":{"line":198,"column":0}},"198":{"start":{"line":199,"column":0},"end":{"line":199,"column":44}},"199":{"start":{"line":200,"column":0},"end":{"line":200,"column":49}},"200":{"start":{"line":201,"column":0},"end":{"line":201,"column":0}},"201":{"start":{"line":202,"column":0},"end":{"line":202,"column":26}},"202":{"start":{"line":203,"column":0},"end":{"line":203,"column":69}},"203":{"start":{"line":204,"column":0},"end":{"line":204,"column":0}},"204":{"start":{"line":205,"column":0},"end":{"line":205,"column":9}},"205":{"start":{"line":206,"column":0},"end":{"line":206,"column":26}},"206":{"start":{"line":207,"column":0},"end":{"line":207,"column":0}},"207":{"start":{"line":208,"column":0},"end":{"line":208,"column":18}},"208":{"start":{"line":209,"column":0},"end":{"line":209,"column":45}},"209":{"start":{"line":210,"column":0},"end":{"line":210,"column":92}},"210":{"start":{"line":211,"column":0},"end":{"line":211,"column":13}},"211":{"start":{"line":212,"column":0},"end":{"line":212,"column":42}},"212":{"start":{"line":213,"column":0},"end":{"line":213,"column":24}},"213":{"start":{"line":214,"column":0},"end":{"line":214,"column":25}},"214":{"start":{"line":215,"column":0},"end":{"line":215,"column":94}},"215":{"start":{"line":216,"column":0},"end":{"line":216,"column":9}},"216":{"start":{"line":217,"column":0},"end":{"line":217,"column":7}},"217":{"start":{"line":218,"column":0},"end":{"line":218,"column":0}},"218":{"start":{"line":219,"column":0},"end":{"line":219,"column":27}},"219":{"start":{"line":220,"column":0},"end":{"line":220,"column":59}},"220":{"start":{"line":221,"column":0},"end":{"line":221,"column":36}},"221":{"start":{"line":222,"column":0},"end":{"line":222,"column":50}},"222":{"start":{"line":223,"column":0},"end":{"line":223,"column":15}},"223":{"start":{"line":224,"column":0},"end":{"line":224,"column":88}},"224":{"start":{"line":225,"column":0},"end":{"line":225,"column":44}},"225":{"start":{"line":226,"column":0},"end":{"line":226,"column":26}},"226":{"start":{"line":227,"column":0},"end":{"line":227,"column":27}},"227":{"start":{"line":228,"column":0},"end":{"line":228,"column":89}},"228":{"start":{"line":229,"column":0},"end":{"line":229,"column":11}},"229":{"start":{"line":230,"column":0},"end":{"line":230,"column":9}},"230":{"start":{"line":231,"column":0},"end":{"line":231,"column":7}},"231":{"start":{"line":232,"column":0},"end":{"line":232,"column":0}},"232":{"start":{"line":233,"column":0},"end":{"line":233,"column":19}},"233":{"start":{"line":234,"column":0},"end":{"line":234,"column":11}},"234":{"start":{"line":235,"column":0},"end":{"line":235,"column":34}},"235":{"start":{"line":236,"column":0},"end":{"line":236,"column":19}},"236":{"start":{"line":237,"column":0},"end":{"line":237,"column":35}},"237":{"start":{"line":238,"column":0},"end":{"line":238,"column":7}},"238":{"start":{"line":239,"column":0},"end":{"line":239,"column":0}},"239":{"start":{"line":240,"column":0},"end":{"line":240,"column":17}},"240":{"start":{"line":241,"column":0},"end":{"line":241,"column":37}},"241":{"start":{"line":242,"column":0},"end":{"line":242,"column":77}},"242":{"start":{"line":243,"column":0},"end":{"line":243,"column":21}},"243":{"start":{"line":244,"column":0},"end":{"line":244,"column":68}},"244":{"start":{"line":245,"column":0},"end":{"line":245,"column":15}},"245":{"start":{"line":246,"column":0},"end":{"line":246,"column":29}},"246":{"start":{"line":247,"column":0},"end":{"line":247,"column":5}},"247":{"start":{"line":248,"column":0},"end":{"line":248,"column":3}},"248":{"start":{"line":249,"column":0},"end":{"line":249,"column":0}},"249":{"start":{"line":250,"column":0},"end":{"line":250,"column":56}},"250":{"start":{"line":251,"column":0},"end":{"line":251,"column":25}},"251":{"start":{"line":252,"column":0},"end":{"line":252,"column":60}},"252":{"start":{"line":253,"column":0},"end":{"line":253,"column":51}},"253":{"start":{"line":254,"column":0},"end":{"line":254,"column":35}},"254":{"start":{"line":255,"column":0},"end":{"line":255,"column":7}},"255":{"start":{"line":256,"column":0},"end":{"line":256,"column":37}},"256":{"start":{"line":257,"column":0},"end":{"line":257,"column":35}},"257":{"start":{"line":258,"column":0},"end":{"line":258,"column":18}},"258":{"start":{"line":259,"column":0},"end":{"line":259,"column":5}},"259":{"start":{"line":260,"column":0},"end":{"line":260,"column":0}},"260":{"start":{"line":261,"column":0},"end":{"line":261,"column":37}},"261":{"start":{"line":262,"column":0},"end":{"line":262,"column":60}},"262":{"start":{"line":263,"column":0},"end":{"line":263,"column":38}},"263":{"start":{"line":264,"column":0},"end":{"line":264,"column":3}},"264":{"start":{"line":265,"column":0},"end":{"line":265,"column":0}},"265":{"start":{"line":266,"column":0},"end":{"line":266,"column":41}},"266":{"start":{"line":267,"column":0},"end":{"line":267,"column":48}},"267":{"start":{"line":268,"column":0},"end":{"line":268,"column":0}},"268":{"start":{"line":269,"column":0},"end":{"line":269,"column":75}},"269":{"start":{"line":270,"column":0},"end":{"line":270,"column":23}},"270":{"start":{"line":271,"column":0},"end":{"line":271,"column":0}},"271":{"start":{"line":272,"column":0},"end":{"line":272,"column":28}},"272":{"start":{"line":273,"column":0},"end":{"line":273,"column":46}},"273":{"start":{"line":274,"column":0},"end":{"line":274,"column":39}},"274":{"start":{"line":275,"column":0},"end":{"line":275,"column":46}},"275":{"start":{"line":276,"column":0},"end":{"line":276,"column":21}},"276":{"start":{"line":277,"column":0},"end":{"line":277,"column":19}},"277":{"start":{"line":278,"column":0},"end":{"line":278,"column":23}},"278":{"start":{"line":279,"column":0},"end":{"line":279,"column":85}},"279":{"start":{"line":280,"column":0},"end":{"line":280,"column":21}},"280":{"start":{"line":281,"column":0},"end":{"line":281,"column":64}},"281":{"start":{"line":282,"column":0},"end":{"line":282,"column":9}},"282":{"start":{"line":283,"column":0},"end":{"line":283,"column":6}},"283":{"start":{"line":284,"column":0},"end":{"line":284,"column":0}},"284":{"start":{"line":285,"column":0},"end":{"line":285,"column":15}},"285":{"start":{"line":286,"column":0},"end":{"line":286,"column":3}},"286":{"start":{"line":287,"column":0},"end":{"line":287,"column":0}},"287":{"start":{"line":288,"column":0},"end":{"line":288,"column":19}},"288":{"start":{"line":289,"column":0},"end":{"line":289,"column":40}},"289":{"start":{"line":290,"column":0},"end":{"line":290,"column":26}},"290":{"start":{"line":291,"column":0},"end":{"line":291,"column":60}},"291":{"start":{"line":292,"column":0},"end":{"line":292,"column":7}},"292":{"start":{"line":293,"column":0},"end":{"line":293,"column":27}},"293":{"start":{"line":294,"column":0},"end":{"line":294,"column":62}},"294":{"start":{"line":295,"column":0},"end":{"line":295,"column":7}},"295":{"start":{"line":296,"column":0},"end":{"line":296,"column":5}},"296":{"start":{"line":297,"column":0},"end":{"line":297,"column":18}},"297":{"start":{"line":298,"column":0},"end":{"line":298,"column":22}},"298":{"start":{"line":299,"column":0},"end":{"line":299,"column":21}},"299":{"start":{"line":300,"column":0},"end":{"line":300,"column":5}},"300":{"start":{"line":301,"column":0},"end":{"line":301,"column":3}},"301":{"start":{"line":302,"column":0},"end":{"line":302,"column":1}},"302":{"start":{"line":303,"column":0},"end":{"line":303,"column":0}},"303":{"start":{"line":304,"column":0},"end":{"line":304,"column":29}}},"s":{"0":1,"1":1,"2":1,"3":1,"4":1,"5":1,"6":1,"7":1,"8":1,"9":1,"10":1,"11":1,"12":1,"13":0,"14":0,"15":0,"16":0,"17":0,"18":0,"19":0,"20":0,"21":0,"22":0,"23":0,"24":0,"25":1,"26":1,"27":0,"28":0,"29":0,"30":0,"31":0,"32":1,"33":1,"34":0,"35":0,"36":0,"37":0,"38":0,"39":1,"40":1,"41":0,"42":0,"43":0,"44":0,"45":0,"46":0,"47":0,"48":0,"49":0,"50":0,"51":0,"52":0,"53":0,"54":0,"55":0,"56":0,"57":0,"58":0,"59":0,"60":0,"61":0,"62":0,"63":0,"64":0,"65":0,"66":0,"67":0,"68":0,"69":0,"70":0,"71":0,"72":0,"73":1,"74":1,"75":0,"76":0,"77":0,"78":0,"79":0,"80":0,"81":0,"82":0,"83":0,"84":0,"85":0,"86":0,"87":0,"88":0,"89":0,"90":0,"91":0,"92":0,"93":1,"94":1,"95":0,"96":0,"97":1,"98":1,"99":0,"100":0,"101":0,"102":0,"103":0,"104":0,"105":0,"106":0,"107":0,"108":0,"109":0,"110":0,"111":0,"112":0,"113":0,"114":0,"115":0,"116":0,"117":0,"118":0,"119":0,"120":0,"121":0,"122":0,"123":0,"124":0,"125":0,"126":1,"127":1,"128":0,"129":0,"130":0,"131":0,"132":0,"133":0,"134":0,"135":0,"136":0,"137":0,"138":1,"139":1,"140":0,"141":0,"142":0,"143":0,"144":0,"145":0,"146":0,"147":0,"148":0,"149":0,"150":0,"151":0,"152":0,"153":0,"154":0,"155":0,"156":0,"157":0,"158":0,"159":0,"160":0,"161":0,"162":0,"163":0,"164":1,"165":1,"166":0,"167":0,"168":0,"169":0,"170":0,"171":0,"172":0,"173":0,"174":0,"175":0,"176":0,"177":0,"178":0,"179":0,"180":0,"181":0,"182":0,"183":0,"184":1,"185":1,"186":0,"187":0,"188":0,"189":0,"190":0,"191":0,"192":0,"193":0,"194":0,"195":0,"196":0,"197":1,"198":1,"199":0,"200":0,"201":0,"202":0,"203":0,"204":0,"205":0,"206":0,"207":0,"208":0,"209":0,"210":0,"211":0,"212":0,"213":0,"214":0,"215":0,"216":0,"217":0,"218":0,"219":0,"220":0,"221":0,"222":0,"223":0,"224":0,"225":0,"226":0,"227":0,"228":0,"229":0,"230":0,"231":0,"232":0,"233":0,"234":0,"235":0,"236":0,"237":0,"238":0,"239":0,"240":0,"241":0,"242":0,"243":0,"244":0,"245":0,"246":0,"247":0,"248":1,"249":1,"250":0,"251":0,"252":0,"253":0,"254":0,"255":0,"256":0,"257":0,"258":0,"259":0,"260":0,"261":0,"262":0,"263":0,"264":1,"265":1,"266":0,"267":0,"268":0,"269":0,"270":0,"271":0,"272":0,"273":0,"274":0,"275":0,"276":0,"277":0,"278":0,"279":0,"280":0,"281":0,"282":0,"283":0,"284":0,"285":0,"286":1,"287":1,"288":0,"289":0,"290":0,"291":0,"292":0,"293":0,"294":0,"295":0,"296":0,"297":0,"298":0,"299":0,"300":0,"301":1,"302":1,"303":1},"branchMap":{},"b":{},"fnMap":{"0":{"name":"OfflinePlugin","decl":{"start":{"line":14,"column":0},"end":{"line":25,"column":44}},"loc":{"start":{"line":14,"column":0},"end":{"line":25,"column":44}},"line":14},"1":{"name":"setup","decl":{"start":{"line":27,"column":2},"end":{"line":32,"column":3}},"loc":{"start":{"line":27,"column":2},"end":{"line":32,"column":3}},"line":27},"2":{"name":"loadConfig","decl":{"start":{"line":34,"column":10},"end":{"line":39,"column":3}},"loc":{"start":{"line":34,"column":10},"end":{"line":39,"column":3}},"line":34},"3":{"name":"initDatabase","decl":{"start":{"line":41,"column":2},"end":{"line":73,"column":3}},"loc":{"start":{"line":41,"column":2},"end":{"line":73,"column":3}},"line":41},"4":{"name":"setupNetworkListeners","decl":{"start":{"line":75,"column":10},"end":{"line":93,"column":3}},"loc":{"start":{"line":75,"column":10},"end":{"line":93,"column":3}},"line":75},"5":{"name":"generateId","decl":{"start":{"line":95,"column":10},"end":{"line":97,"column":3}},"loc":{"start":{"line":95,"column":10},"end":{"line":97,"column":3}},"line":95},"6":{"name":"saveToIndexedDB","decl":{"start":{"line":99,"column":2},"end":{"line":126,"column":3}},"loc":{"start":{"line":99,"column":2},"end":{"line":126,"column":3}},"line":99},"7":{"name":"getEventCount","decl":{"start":{"line":128,"column":10},"end":{"line":138,"column":3}},"loc":{"start":{"line":128,"column":10},"end":{"line":138,"column":3}},"line":128},"8":{"name":"deleteOldestEvents","decl":{"start":{"line":140,"column":2},"end":{"line":164,"column":3}},"loc":{"start":{"line":140,"column":2},"end":{"line":164,"column":3}},"line":140},"9":{"name":"getAllStoredEvents","decl":{"start":{"line":166,"column":2},"end":{"line":184,"column":3}},"loc":{"start":{"line":166,"column":2},"end":{"line":184,"column":3}},"line":166},"10":{"name":"clearStoredEvents","decl":{"start":{"line":186,"column":2},"end":{"line":197,"column":3}},"loc":{"start":{"line":186,"column":2},"end":{"line":197,"column":3}},"line":186},"11":{"name":"syncPendingEvents","decl":{"start":{"line":199,"column":2},"end":{"line":248,"column":3}},"loc":{"start":{"line":199,"column":2},"end":{"line":248,"column":3}},"line":199},"12":{"name":"beforeReport","decl":{"start":{"line":250,"column":2},"end":{"line":264,"column":3}},"loc":{"start":{"line":250,"column":2},"end":{"line":264,"column":3}},"line":250},"13":{"name":"savePendingEventsToDB","decl":{"start":{"line":266,"column":10},"end":{"line":286,"column":3}},"loc":{"start":{"line":266,"column":10},"end":{"line":286,"column":3}},"line":266},"14":{"name":"destroy","decl":{"start":{"line":288,"column":2},"end":{"line":301,"column":3}},"loc":{"start":{"line":288,"column":2},"end":{"line":301,"column":3}},"line":288}},"f":{"0":0,"1":0,"2":0,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10":0,"11":0,"12":0,"13":0,"14":0}} +,"/Users/weidingjian/Desktop/work/ai/light-sentry-sdk/src/plugins/PerformancePlugin.ts": {"path":"/Users/weidingjian/Desktop/work/ai/light-sentry-sdk/src/plugins/PerformancePlugin.ts","all":false,"statementMap":{"0":{"start":{"line":1,"column":0},"end":{"line":1,"column":107}},"1":{"start":{"line":2,"column":0},"end":{"line":2,"column":48}},"2":{"start":{"line":3,"column":0},"end":{"line":3,"column":0}},"3":{"start":{"line":4,"column":0},"end":{"line":4,"column":35}},"4":{"start":{"line":5,"column":0},"end":{"line":5,"column":22}},"5":{"start":{"line":6,"column":0},"end":{"line":6,"column":29}},"6":{"start":{"line":7,"column":0},"end":{"line":7,"column":29}},"7":{"start":{"line":8,"column":0},"end":{"line":8,"column":30}},"8":{"start":{"line":9,"column":0},"end":{"line":9,"column":30}},"9":{"start":{"line":10,"column":0},"end":{"line":10,"column":30}},"10":{"start":{"line":11,"column":0},"end":{"line":11,"column":22}},"11":{"start":{"line":12,"column":0},"end":{"line":12,"column":65}},"12":{"start":{"line":13,"column":0},"end":{"line":13,"column":58}},"13":{"start":{"line":14,"column":0},"end":{"line":14,"column":1}},"14":{"start":{"line":15,"column":0},"end":{"line":15,"column":0}},"15":{"start":{"line":16,"column":0},"end":{"line":16,"column":28}},"16":{"start":{"line":17,"column":0},"end":{"line":17,"column":16}},"17":{"start":{"line":18,"column":0},"end":{"line":18,"column":16}},"18":{"start":{"line":19,"column":0},"end":{"line":19,"column":49}},"19":{"start":{"line":20,"column":0},"end":{"line":20,"column":1}},"20":{"start":{"line":21,"column":0},"end":{"line":21,"column":0}},"21":{"start":{"line":22,"column":0},"end":{"line":22,"column":48}},"22":{"start":{"line":23,"column":0},"end":{"line":23,"column":23}},"23":{"start":{"line":24,"column":0},"end":{"line":24,"column":20}},"24":{"start":{"line":25,"column":0},"end":{"line":25,"column":0}},"25":{"start":{"line":26,"column":0},"end":{"line":26,"column":31}},"26":{"start":{"line":27,"column":0},"end":{"line":27,"column":45}},"27":{"start":{"line":28,"column":0},"end":{"line":28,"column":20}},"28":{"start":{"line":29,"column":0},"end":{"line":29,"column":27}},"29":{"start":{"line":30,"column":0},"end":{"line":30,"column":28}},"30":{"start":{"line":31,"column":0},"end":{"line":31,"column":29}},"31":{"start":{"line":32,"column":0},"end":{"line":32,"column":29}},"32":{"start":{"line":33,"column":0},"end":{"line":33,"column":28}},"33":{"start":{"line":34,"column":0},"end":{"line":34,"column":20}},"34":{"start":{"line":35,"column":0},"end":{"line":35,"column":33}},"35":{"start":{"line":36,"column":0},"end":{"line":36,"column":25}},"36":{"start":{"line":37,"column":0},"end":{"line":37,"column":4}},"37":{"start":{"line":38,"column":0},"end":{"line":38,"column":0}},"38":{"start":{"line":39,"column":0},"end":{"line":39,"column":48}},"39":{"start":{"line":40,"column":0},"end":{"line":40,"column":30}},"40":{"start":{"line":41,"column":0},"end":{"line":41,"column":68}},"41":{"start":{"line":42,"column":0},"end":{"line":42,"column":40}},"42":{"start":{"line":43,"column":0},"end":{"line":43,"column":40}},"43":{"start":{"line":44,"column":0},"end":{"line":44,"column":42}},"44":{"start":{"line":45,"column":0},"end":{"line":45,"column":39}},"45":{"start":{"line":46,"column":0},"end":{"line":46,"column":64}},"46":{"start":{"line":47,"column":0},"end":{"line":47,"column":0}},"47":{"start":{"line":48,"column":0},"end":{"line":48,"column":57}},"48":{"start":{"line":49,"column":0},"end":{"line":49,"column":62}},"49":{"start":{"line":50,"column":0},"end":{"line":50,"column":40}},"50":{"start":{"line":51,"column":0},"end":{"line":51,"column":0}},"51":{"start":{"line":52,"column":0},"end":{"line":52,"column":36}},"52":{"start":{"line":53,"column":0},"end":{"line":53,"column":25}},"53":{"start":{"line":54,"column":0},"end":{"line":54,"column":22}},"54":{"start":{"line":55,"column":0},"end":{"line":55,"column":0}},"55":{"start":{"line":56,"column":0},"end":{"line":56,"column":44}},"56":{"start":{"line":57,"column":0},"end":{"line":57,"column":38}},"57":{"start":{"line":58,"column":0},"end":{"line":58,"column":5}},"58":{"start":{"line":59,"column":0},"end":{"line":59,"column":0}},"59":{"start":{"line":60,"column":0},"end":{"line":60,"column":28}},"60":{"start":{"line":61,"column":0},"end":{"line":61,"column":28}},"61":{"start":{"line":62,"column":0},"end":{"line":62,"column":29}},"62":{"start":{"line":63,"column":0},"end":{"line":63,"column":28}},"63":{"start":{"line":64,"column":0},"end":{"line":64,"column":3}},"64":{"start":{"line":65,"column":0},"end":{"line":65,"column":0}},"65":{"start":{"line":66,"column":0},"end":{"line":66,"column":44}},"66":{"start":{"line":67,"column":0},"end":{"line":67,"column":46}},"67":{"start":{"line":68,"column":0},"end":{"line":68,"column":0}},"68":{"start":{"line":69,"column":0},"end":{"line":69,"column":78}},"69":{"start":{"line":70,"column":0},"end":{"line":70,"column":94}},"70":{"start":{"line":71,"column":0},"end":{"line":71,"column":42}},"71":{"start":{"line":72,"column":0},"end":{"line":72,"column":14}},"72":{"start":{"line":73,"column":0},"end":{"line":73,"column":0}},"73":{"start":{"line":74,"column":0},"end":{"line":74,"column":61}},"74":{"start":{"line":75,"column":0},"end":{"line":75,"column":20}},"75":{"start":{"line":76,"column":0},"end":{"line":76,"column":21}},"76":{"start":{"line":77,"column":0},"end":{"line":77,"column":44}},"77":{"start":{"line":78,"column":0},"end":{"line":78,"column":31}},"78":{"start":{"line":79,"column":0},"end":{"line":79,"column":23}},"79":{"start":{"line":80,"column":0},"end":{"line":80,"column":13}},"80":{"start":{"line":81,"column":0},"end":{"line":81,"column":28}},"81":{"start":{"line":82,"column":0},"end":{"line":82,"column":8}},"82":{"start":{"line":83,"column":0},"end":{"line":83,"column":7}},"83":{"start":{"line":84,"column":0},"end":{"line":84,"column":3}},"84":{"start":{"line":85,"column":0},"end":{"line":85,"column":0}},"85":{"start":{"line":86,"column":0},"end":{"line":86,"column":30}},"86":{"start":{"line":87,"column":0},"end":{"line":87,"column":59}},"87":{"start":{"line":88,"column":0},"end":{"line":88,"column":61}},"88":{"start":{"line":89,"column":0},"end":{"line":89,"column":80}},"89":{"start":{"line":90,"column":0},"end":{"line":90,"column":5}},"90":{"start":{"line":91,"column":0},"end":{"line":91,"column":3}},"91":{"start":{"line":92,"column":0},"end":{"line":92,"column":0}},"92":{"start":{"line":93,"column":0},"end":{"line":93,"column":99}},"93":{"start":{"line":94,"column":0},"end":{"line":94,"column":45}},"94":{"start":{"line":95,"column":0},"end":{"line":95,"column":30}},"95":{"start":{"line":96,"column":0},"end":{"line":96,"column":52}},"96":{"start":{"line":97,"column":0},"end":{"line":97,"column":37}},"97":{"start":{"line":98,"column":0},"end":{"line":98,"column":52}},"98":{"start":{"line":99,"column":0},"end":{"line":99,"column":35}},"99":{"start":{"line":100,"column":0},"end":{"line":100,"column":15}},"100":{"start":{"line":101,"column":0},"end":{"line":101,"column":5}},"101":{"start":{"line":102,"column":0},"end":{"line":102,"column":31}},"102":{"start":{"line":103,"column":0},"end":{"line":103,"column":32}},"103":{"start":{"line":104,"column":0},"end":{"line":104,"column":32}},"104":{"start":{"line":105,"column":0},"end":{"line":105,"column":3}},"105":{"start":{"line":106,"column":0},"end":{"line":106,"column":0}},"106":{"start":{"line":107,"column":0},"end":{"line":107,"column":36}},"107":{"start":{"line":108,"column":0},"end":{"line":108,"column":59}},"108":{"start":{"line":109,"column":0},"end":{"line":109,"column":0}},"109":{"start":{"line":110,"column":0},"end":{"line":110,"column":24}},"110":{"start":{"line":111,"column":0},"end":{"line":111,"column":22}},"111":{"start":{"line":112,"column":0},"end":{"line":112,"column":22}},"112":{"start":{"line":113,"column":0},"end":{"line":113,"column":22}},"113":{"start":{"line":114,"column":0},"end":{"line":114,"column":23}},"114":{"start":{"line":115,"column":0},"end":{"line":115,"column":3}},"115":{"start":{"line":116,"column":0},"end":{"line":116,"column":0}},"116":{"start":{"line":117,"column":0},"end":{"line":117,"column":32}},"117":{"start":{"line":118,"column":0},"end":{"line":118,"column":9}},"118":{"start":{"line":119,"column":0},"end":{"line":119,"column":57}},"119":{"start":{"line":120,"column":0},"end":{"line":120,"column":68}},"120":{"start":{"line":121,"column":0},"end":{"line":121,"column":60}},"121":{"start":{"line":122,"column":0},"end":{"line":122,"column":78}},"122":{"start":{"line":123,"column":0},"end":{"line":123,"column":9}},"123":{"start":{"line":124,"column":0},"end":{"line":124,"column":80}},"124":{"start":{"line":125,"column":0},"end":{"line":125,"column":36}},"125":{"start":{"line":126,"column":0},"end":{"line":126,"column":49}},"126":{"start":{"line":127,"column":0},"end":{"line":127,"column":61}},"127":{"start":{"line":128,"column":0},"end":{"line":128,"column":80}},"128":{"start":{"line":129,"column":0},"end":{"line":129,"column":29}},"129":{"start":{"line":130,"column":0},"end":{"line":130,"column":9}},"130":{"start":{"line":131,"column":0},"end":{"line":131,"column":9}},"131":{"start":{"line":132,"column":0},"end":{"line":132,"column":52}},"132":{"start":{"line":133,"column":0},"end":{"line":133,"column":30}},"133":{"start":{"line":134,"column":0},"end":{"line":134,"column":13}},"134":{"start":{"line":135,"column":0},"end":{"line":135,"column":37}},"135":{"start":{"line":136,"column":0},"end":{"line":136,"column":5}},"136":{"start":{"line":137,"column":0},"end":{"line":137,"column":3}},"137":{"start":{"line":138,"column":0},"end":{"line":138,"column":0}},"138":{"start":{"line":139,"column":0},"end":{"line":139,"column":30}},"139":{"start":{"line":140,"column":0},"end":{"line":140,"column":9}},"140":{"start":{"line":141,"column":0},"end":{"line":141,"column":57}},"141":{"start":{"line":142,"column":0},"end":{"line":142,"column":47}},"142":{"start":{"line":143,"column":0},"end":{"line":143,"column":119}},"143":{"start":{"line":144,"column":0},"end":{"line":144,"column":24}},"144":{"start":{"line":145,"column":0},"end":{"line":145,"column":90}},"145":{"start":{"line":146,"column":0},"end":{"line":146,"column":62}},"146":{"start":{"line":147,"column":0},"end":{"line":147,"column":9}},"147":{"start":{"line":148,"column":0},"end":{"line":148,"column":9}},"148":{"start":{"line":149,"column":0},"end":{"line":149,"column":71}},"149":{"start":{"line":150,"column":0},"end":{"line":150,"column":30}},"150":{"start":{"line":151,"column":0},"end":{"line":151,"column":13}},"151":{"start":{"line":152,"column":0},"end":{"line":152,"column":26}},"152":{"start":{"line":153,"column":0},"end":{"line":153,"column":5}},"153":{"start":{"line":154,"column":0},"end":{"line":154,"column":3}},"154":{"start":{"line":155,"column":0},"end":{"line":155,"column":0}},"155":{"start":{"line":156,"column":0},"end":{"line":156,"column":30}},"156":{"start":{"line":157,"column":0},"end":{"line":157,"column":9}},"157":{"start":{"line":158,"column":0},"end":{"line":158,"column":57}},"158":{"start":{"line":159,"column":0},"end":{"line":159,"column":75}},"159":{"start":{"line":160,"column":0},"end":{"line":160,"column":33}},"160":{"start":{"line":161,"column":0},"end":{"line":161,"column":40}},"161":{"start":{"line":162,"column":0},"end":{"line":162,"column":74}},"162":{"start":{"line":163,"column":0},"end":{"line":163,"column":62}},"163":{"start":{"line":164,"column":0},"end":{"line":164,"column":9}},"164":{"start":{"line":165,"column":0},"end":{"line":165,"column":9}},"165":{"start":{"line":166,"column":0},"end":{"line":166,"column":58}},"166":{"start":{"line":167,"column":0},"end":{"line":167,"column":30}},"167":{"start":{"line":168,"column":0},"end":{"line":168,"column":13}},"168":{"start":{"line":169,"column":0},"end":{"line":169,"column":26}},"169":{"start":{"line":170,"column":0},"end":{"line":170,"column":5}},"170":{"start":{"line":171,"column":0},"end":{"line":171,"column":3}},"171":{"start":{"line":172,"column":0},"end":{"line":172,"column":0}},"172":{"start":{"line":173,"column":0},"end":{"line":173,"column":30}},"173":{"start":{"line":174,"column":0},"end":{"line":174,"column":9}},"174":{"start":{"line":175,"column":0},"end":{"line":175,"column":23}},"175":{"start":{"line":176,"column":0},"end":{"line":176,"column":27}},"176":{"start":{"line":177,"column":0},"end":{"line":177,"column":50}},"177":{"start":{"line":178,"column":0},"end":{"line":178,"column":0}},"178":{"start":{"line":179,"column":0},"end":{"line":179,"column":57}},"179":{"start":{"line":180,"column":0},"end":{"line":180,"column":145}},"180":{"start":{"line":181,"column":0},"end":{"line":181,"column":38}},"181":{"start":{"line":182,"column":0},"end":{"line":182,"column":38}},"182":{"start":{"line":183,"column":0},"end":{"line":183,"column":56}},"183":{"start":{"line":184,"column":0},"end":{"line":184,"column":79}},"184":{"start":{"line":185,"column":0},"end":{"line":185,"column":0}},"185":{"start":{"line":186,"column":0},"end":{"line":186,"column":16}},"186":{"start":{"line":187,"column":0},"end":{"line":187,"column":29}},"187":{"start":{"line":188,"column":0},"end":{"line":188,"column":75}},"188":{"start":{"line":189,"column":0},"end":{"line":189,"column":66}},"189":{"start":{"line":190,"column":0},"end":{"line":190,"column":15}},"190":{"start":{"line":191,"column":0},"end":{"line":191,"column":47}},"191":{"start":{"line":192,"column":0},"end":{"line":192,"column":72}},"192":{"start":{"line":193,"column":0},"end":{"line":193,"column":20}},"193":{"start":{"line":194,"column":0},"end":{"line":194,"column":46}},"194":{"start":{"line":195,"column":0},"end":{"line":195,"column":70}},"195":{"start":{"line":196,"column":0},"end":{"line":196,"column":13}},"196":{"start":{"line":197,"column":0},"end":{"line":197,"column":0}},"197":{"start":{"line":198,"column":0},"end":{"line":198,"column":42}},"198":{"start":{"line":199,"column":0},"end":{"line":199,"column":38}},"199":{"start":{"line":200,"column":0},"end":{"line":200,"column":67}},"200":{"start":{"line":201,"column":0},"end":{"line":201,"column":13}},"201":{"start":{"line":202,"column":0},"end":{"line":202,"column":11}},"202":{"start":{"line":203,"column":0},"end":{"line":203,"column":9}},"203":{"start":{"line":204,"column":0},"end":{"line":204,"column":9}},"204":{"start":{"line":205,"column":0},"end":{"line":205,"column":59}},"205":{"start":{"line":206,"column":0},"end":{"line":206,"column":30}},"206":{"start":{"line":207,"column":0},"end":{"line":207,"column":13}},"207":{"start":{"line":208,"column":0},"end":{"line":208,"column":26}},"208":{"start":{"line":209,"column":0},"end":{"line":209,"column":5}},"209":{"start":{"line":210,"column":0},"end":{"line":210,"column":3}},"210":{"start":{"line":211,"column":0},"end":{"line":211,"column":0}},"211":{"start":{"line":212,"column":0},"end":{"line":212,"column":31}},"212":{"start":{"line":213,"column":0},"end":{"line":213,"column":9}},"213":{"start":{"line":214,"column":0},"end":{"line":214,"column":57}},"214":{"start":{"line":215,"column":0},"end":{"line":215,"column":101}},"215":{"start":{"line":216,"column":0},"end":{"line":216,"column":36}},"216":{"start":{"line":217,"column":0},"end":{"line":217,"column":41}},"217":{"start":{"line":218,"column":0},"end":{"line":218,"column":70}},"218":{"start":{"line":219,"column":0},"end":{"line":219,"column":75}},"219":{"start":{"line":220,"column":0},"end":{"line":220,"column":9}},"220":{"start":{"line":221,"column":0},"end":{"line":221,"column":9}},"221":{"start":{"line":222,"column":0},"end":{"line":222,"column":57}},"222":{"start":{"line":223,"column":0},"end":{"line":223,"column":30}},"223":{"start":{"line":224,"column":0},"end":{"line":224,"column":13}},"224":{"start":{"line":225,"column":0},"end":{"line":225,"column":40}},"225":{"start":{"line":226,"column":0},"end":{"line":226,"column":5}},"226":{"start":{"line":227,"column":0},"end":{"line":227,"column":3}},"227":{"start":{"line":228,"column":0},"end":{"line":228,"column":0}},"228":{"start":{"line":229,"column":0},"end":{"line":229,"column":36}},"229":{"start":{"line":230,"column":0},"end":{"line":230,"column":46}},"230":{"start":{"line":231,"column":0},"end":{"line":231,"column":0}},"231":{"start":{"line":232,"column":0},"end":{"line":232,"column":9}},"232":{"start":{"line":233,"column":0},"end":{"line":233,"column":57}},"233":{"start":{"line":234,"column":0},"end":{"line":234,"column":47}},"234":{"start":{"line":235,"column":0},"end":{"line":235,"column":38}},"235":{"start":{"line":236,"column":0},"end":{"line":236,"column":59}},"236":{"start":{"line":237,"column":0},"end":{"line":237,"column":51}},"237":{"start":{"line":238,"column":0},"end":{"line":238,"column":47}},"238":{"start":{"line":239,"column":0},"end":{"line":239,"column":11}},"239":{"start":{"line":240,"column":0},"end":{"line":240,"column":0}},"240":{"start":{"line":241,"column":0},"end":{"line":241,"column":73}},"241":{"start":{"line":242,"column":0},"end":{"line":242,"column":53}},"242":{"start":{"line":243,"column":0},"end":{"line":243,"column":35}},"243":{"start":{"line":244,"column":0},"end":{"line":244,"column":53}},"244":{"start":{"line":245,"column":0},"end":{"line":245,"column":13}},"245":{"start":{"line":246,"column":0},"end":{"line":246,"column":11}},"246":{"start":{"line":247,"column":0},"end":{"line":247,"column":0}},"247":{"start":{"line":248,"column":0},"end":{"line":248,"column":78}},"248":{"start":{"line":249,"column":0},"end":{"line":249,"column":0}},"249":{"start":{"line":250,"column":0},"end":{"line":250,"column":29}},"250":{"start":{"line":251,"column":0},"end":{"line":251,"column":9}},"251":{"start":{"line":252,"column":0},"end":{"line":252,"column":9}},"252":{"start":{"line":253,"column":0},"end":{"line":253,"column":55}},"253":{"start":{"line":254,"column":0},"end":{"line":254,"column":30}},"254":{"start":{"line":255,"column":0},"end":{"line":255,"column":13}},"255":{"start":{"line":256,"column":0},"end":{"line":256,"column":33}},"256":{"start":{"line":257,"column":0},"end":{"line":257,"column":5}},"257":{"start":{"line":258,"column":0},"end":{"line":258,"column":3}},"258":{"start":{"line":259,"column":0},"end":{"line":259,"column":0}},"259":{"start":{"line":260,"column":0},"end":{"line":260,"column":31}},"260":{"start":{"line":261,"column":0},"end":{"line":261,"column":33}},"261":{"start":{"line":262,"column":0},"end":{"line":262,"column":0}},"262":{"start":{"line":263,"column":0},"end":{"line":263,"column":24}},"263":{"start":{"line":264,"column":0},"end":{"line":264,"column":34}},"264":{"start":{"line":265,"column":0},"end":{"line":265,"column":5}},"265":{"start":{"line":266,"column":0},"end":{"line":266,"column":0}},"266":{"start":{"line":267,"column":0},"end":{"line":267,"column":38}},"267":{"start":{"line":268,"column":0},"end":{"line":268,"column":35}},"268":{"start":{"line":269,"column":0},"end":{"line":269,"column":30}},"269":{"start":{"line":270,"column":0},"end":{"line":270,"column":0}},"270":{"start":{"line":271,"column":0},"end":{"line":271,"column":72}},"271":{"start":{"line":272,"column":0},"end":{"line":272,"column":56}},"272":{"start":{"line":273,"column":0},"end":{"line":273,"column":75}},"273":{"start":{"line":274,"column":0},"end":{"line":274,"column":13}},"274":{"start":{"line":275,"column":0},"end":{"line":275,"column":3}},"275":{"start":{"line":276,"column":0},"end":{"line":276,"column":0}},"276":{"start":{"line":277,"column":0},"end":{"line":277,"column":37}},"277":{"start":{"line":278,"column":0},"end":{"line":278,"column":47}},"278":{"start":{"line":279,"column":0},"end":{"line":279,"column":51}},"279":{"start":{"line":280,"column":0},"end":{"line":280,"column":0}},"280":{"start":{"line":281,"column":0},"end":{"line":281,"column":25}},"281":{"start":{"line":282,"column":0},"end":{"line":282,"column":44}},"282":{"start":{"line":283,"column":0},"end":{"line":283,"column":42}},"283":{"start":{"line":284,"column":0},"end":{"line":284,"column":28}},"284":{"start":{"line":285,"column":0},"end":{"line":285,"column":0}},"285":{"start":{"line":286,"column":0},"end":{"line":286,"column":55}},"286":{"start":{"line":287,"column":0},"end":{"line":287,"column":49}},"287":{"start":{"line":288,"column":0},"end":{"line":288,"column":71}},"288":{"start":{"line":289,"column":0},"end":{"line":289,"column":59}},"289":{"start":{"line":290,"column":0},"end":{"line":290,"column":65}},"290":{"start":{"line":291,"column":0},"end":{"line":291,"column":55}},"291":{"start":{"line":292,"column":0},"end":{"line":292,"column":103}},"292":{"start":{"line":293,"column":0},"end":{"line":293,"column":59}},"293":{"start":{"line":294,"column":0},"end":{"line":294,"column":62}},"294":{"start":{"line":295,"column":0},"end":{"line":295,"column":64}},"295":{"start":{"line":296,"column":0},"end":{"line":296,"column":10}},"296":{"start":{"line":297,"column":0},"end":{"line":297,"column":0}},"297":{"start":{"line":298,"column":0},"end":{"line":298,"column":62}},"298":{"start":{"line":299,"column":0},"end":{"line":299,"column":26}},"299":{"start":{"line":300,"column":0},"end":{"line":300,"column":49}},"300":{"start":{"line":301,"column":0},"end":{"line":301,"column":11}},"301":{"start":{"line":302,"column":0},"end":{"line":302,"column":9}},"302":{"start":{"line":303,"column":0},"end":{"line":303,"column":0}},"303":{"start":{"line":304,"column":0},"end":{"line":304,"column":85}},"304":{"start":{"line":305,"column":0},"end":{"line":305,"column":61}},"305":{"start":{"line":306,"column":0},"end":{"line":306,"column":71}},"306":{"start":{"line":307,"column":0},"end":{"line":307,"column":9}},"307":{"start":{"line":308,"column":0},"end":{"line":308,"column":0}},"308":{"start":{"line":309,"column":0},"end":{"line":309,"column":33}},"309":{"start":{"line":310,"column":0},"end":{"line":310,"column":12}},"310":{"start":{"line":311,"column":0},"end":{"line":311,"column":6}},"311":{"start":{"line":312,"column":0},"end":{"line":312,"column":0}},"312":{"start":{"line":313,"column":0},"end":{"line":313,"column":49}},"313":{"start":{"line":314,"column":0},"end":{"line":314,"column":3}},"314":{"start":{"line":315,"column":0},"end":{"line":315,"column":0}},"315":{"start":{"line":316,"column":0},"end":{"line":316,"column":90}},"316":{"start":{"line":317,"column":0},"end":{"line":317,"column":87}},"317":{"start":{"line":318,"column":0},"end":{"line":318,"column":102}},"318":{"start":{"line":319,"column":0},"end":{"line":319,"column":96}},"319":{"start":{"line":320,"column":0},"end":{"line":320,"column":110}},"320":{"start":{"line":321,"column":0},"end":{"line":321,"column":104}},"321":{"start":{"line":322,"column":0},"end":{"line":322,"column":106}},"322":{"start":{"line":323,"column":0},"end":{"line":323,"column":102}},"323":{"start":{"line":324,"column":0},"end":{"line":324,"column":127}},"324":{"start":{"line":325,"column":0},"end":{"line":325,"column":97}},"325":{"start":{"line":326,"column":0},"end":{"line":326,"column":6}},"326":{"start":{"line":327,"column":0},"end":{"line":327,"column":0}},"327":{"start":{"line":328,"column":0},"end":{"line":328,"column":33}},"328":{"start":{"line":329,"column":0},"end":{"line":329,"column":64}},"329":{"start":{"line":330,"column":0},"end":{"line":330,"column":34}},"330":{"start":{"line":331,"column":0},"end":{"line":331,"column":17}},"331":{"start":{"line":332,"column":0},"end":{"line":332,"column":19}},"332":{"start":{"line":333,"column":0},"end":{"line":333,"column":20}},"333":{"start":{"line":334,"column":0},"end":{"line":334,"column":17}},"334":{"start":{"line":335,"column":0},"end":{"line":335,"column":10}},"335":{"start":{"line":336,"column":0},"end":{"line":336,"column":7}},"336":{"start":{"line":337,"column":0},"end":{"line":337,"column":5}},"337":{"start":{"line":338,"column":0},"end":{"line":338,"column":3}},"338":{"start":{"line":339,"column":0},"end":{"line":339,"column":0}},"339":{"start":{"line":340,"column":0},"end":{"line":340,"column":60}},"340":{"start":{"line":341,"column":0},"end":{"line":341,"column":42}},"341":{"start":{"line":342,"column":0},"end":{"line":342,"column":0}},"342":{"start":{"line":343,"column":0},"end":{"line":343,"column":52}},"343":{"start":{"line":344,"column":0},"end":{"line":344,"column":100}},"344":{"start":{"line":345,"column":0},"end":{"line":345,"column":23}},"345":{"start":{"line":346,"column":0},"end":{"line":346,"column":25}},"346":{"start":{"line":347,"column":0},"end":{"line":347,"column":8}},"347":{"start":{"line":348,"column":0},"end":{"line":348,"column":5}},"348":{"start":{"line":349,"column":0},"end":{"line":349,"column":0}},"349":{"start":{"line":350,"column":0},"end":{"line":350,"column":45}},"350":{"start":{"line":351,"column":0},"end":{"line":351,"column":45}},"351":{"start":{"line":352,"column":0},"end":{"line":352,"column":36}},"352":{"start":{"line":353,"column":0},"end":{"line":353,"column":3}},"353":{"start":{"line":354,"column":0},"end":{"line":354,"column":0}},"354":{"start":{"line":355,"column":0},"end":{"line":355,"column":36}},"355":{"start":{"line":356,"column":0},"end":{"line":356,"column":84}},"356":{"start":{"line":357,"column":0},"end":{"line":357,"column":51}},"357":{"start":{"line":358,"column":0},"end":{"line":358,"column":0}},"358":{"start":{"line":359,"column":0},"end":{"line":359,"column":9}},"359":{"start":{"line":360,"column":0},"end":{"line":360,"column":57}},"360":{"start":{"line":361,"column":0},"end":{"line":361,"column":94}},"361":{"start":{"line":362,"column":0},"end":{"line":362,"column":38}},"362":{"start":{"line":363,"column":0},"end":{"line":363,"column":70}},"363":{"start":{"line":364,"column":0},"end":{"line":364,"column":70}},"364":{"start":{"line":365,"column":0},"end":{"line":365,"column":58}},"365":{"start":{"line":366,"column":0},"end":{"line":366,"column":49}},"366":{"start":{"line":367,"column":0},"end":{"line":367,"column":27}},"367":{"start":{"line":368,"column":0},"end":{"line":368,"column":11}},"368":{"start":{"line":369,"column":0},"end":{"line":369,"column":0}},"369":{"start":{"line":370,"column":0},"end":{"line":370,"column":78}},"370":{"start":{"line":371,"column":0},"end":{"line":371,"column":43}},"371":{"start":{"line":372,"column":0},"end":{"line":372,"column":11}},"372":{"start":{"line":373,"column":0},"end":{"line":373,"column":9}},"373":{"start":{"line":374,"column":0},"end":{"line":374,"column":9}},"374":{"start":{"line":375,"column":0},"end":{"line":375,"column":55}},"375":{"start":{"line":376,"column":0},"end":{"line":376,"column":30}},"376":{"start":{"line":377,"column":0},"end":{"line":377,"column":13}},"377":{"start":{"line":378,"column":0},"end":{"line":378,"column":38}},"378":{"start":{"line":379,"column":0},"end":{"line":379,"column":5}},"379":{"start":{"line":380,"column":0},"end":{"line":380,"column":3}},"380":{"start":{"line":381,"column":0},"end":{"line":381,"column":0}},"381":{"start":{"line":382,"column":0},"end":{"line":382,"column":89}},"382":{"start":{"line":383,"column":0},"end":{"line":383,"column":72}},"383":{"start":{"line":384,"column":0},"end":{"line":384,"column":38}},"384":{"start":{"line":385,"column":0},"end":{"line":385,"column":38}},"385":{"start":{"line":386,"column":0},"end":{"line":386,"column":37}},"386":{"start":{"line":387,"column":0},"end":{"line":387,"column":36}},"387":{"start":{"line":388,"column":0},"end":{"line":388,"column":37}},"388":{"start":{"line":389,"column":0},"end":{"line":389,"column":38}},"389":{"start":{"line":390,"column":0},"end":{"line":390,"column":6}},"390":{"start":{"line":391,"column":0},"end":{"line":391,"column":0}},"391":{"start":{"line":392,"column":0},"end":{"line":392,"column":39}},"392":{"start":{"line":393,"column":0},"end":{"line":393,"column":34}},"393":{"start":{"line":394,"column":0},"end":{"line":394,"column":0}},"394":{"start":{"line":395,"column":0},"end":{"line":395,"column":47}},"395":{"start":{"line":396,"column":0},"end":{"line":396,"column":60}},"396":{"start":{"line":397,"column":0},"end":{"line":397,"column":18}},"397":{"start":{"line":398,"column":0},"end":{"line":398,"column":3}},"398":{"start":{"line":399,"column":0},"end":{"line":399,"column":0}},"399":{"start":{"line":400,"column":0},"end":{"line":400,"column":185}},"400":{"start":{"line":401,"column":0},"end":{"line":401,"column":47}},"401":{"start":{"line":402,"column":0},"end":{"line":402,"column":0}},"402":{"start":{"line":403,"column":0},"end":{"line":403,"column":47}},"403":{"start":{"line":404,"column":0},"end":{"line":404,"column":4}},"404":{"start":{"line":405,"column":0},"end":{"line":405,"column":37}},"405":{"start":{"line":406,"column":0},"end":{"line":406,"column":26}},"406":{"start":{"line":407,"column":0},"end":{"line":407,"column":20}},"407":{"start":{"line":408,"column":0},"end":{"line":408,"column":19}},"408":{"start":{"line":409,"column":0},"end":{"line":409,"column":43}},"409":{"start":{"line":410,"column":0},"end":{"line":410,"column":11}},"410":{"start":{"line":411,"column":0},"end":{"line":411,"column":13}},"411":{"start":{"line":412,"column":0},"end":{"line":412,"column":23}},"412":{"start":{"line":413,"column":0},"end":{"line":413,"column":13}},"413":{"start":{"line":414,"column":0},"end":{"line":414,"column":21}},"414":{"start":{"line":415,"column":0},"end":{"line":415,"column":15}},"415":{"start":{"line":416,"column":0},"end":{"line":416,"column":21}},"416":{"start":{"line":417,"column":0},"end":{"line":417,"column":8}},"417":{"start":{"line":418,"column":0},"end":{"line":418,"column":6}},"418":{"start":{"line":419,"column":0},"end":{"line":419,"column":0}},"419":{"start":{"line":420,"column":0},"end":{"line":420,"column":36}},"420":{"start":{"line":421,"column":0},"end":{"line":421,"column":0}},"421":{"start":{"line":422,"column":0},"end":{"line":422,"column":81}},"422":{"start":{"line":423,"column":0},"end":{"line":423,"column":56}},"423":{"start":{"line":424,"column":0},"end":{"line":424,"column":5}},"424":{"start":{"line":425,"column":0},"end":{"line":425,"column":3}},"425":{"start":{"line":426,"column":0},"end":{"line":426,"column":0}},"426":{"start":{"line":427,"column":0},"end":{"line":427,"column":127}},"427":{"start":{"line":428,"column":0},"end":{"line":428,"column":42}},"428":{"start":{"line":429,"column":0},"end":{"line":429,"column":0}},"429":{"start":{"line":430,"column":0},"end":{"line":430,"column":31}},"430":{"start":{"line":431,"column":0},"end":{"line":431,"column":43}},"431":{"start":{"line":432,"column":0},"end":{"line":432,"column":11}},"432":{"start":{"line":433,"column":0},"end":{"line":433,"column":13}},"433":{"start":{"line":434,"column":0},"end":{"line":434,"column":6}},"434":{"start":{"line":435,"column":0},"end":{"line":435,"column":0}},"435":{"start":{"line":436,"column":0},"end":{"line":436,"column":87}},"436":{"start":{"line":437,"column":0},"end":{"line":437,"column":3}},"437":{"start":{"line":438,"column":0},"end":{"line":438,"column":0}},"438":{"start":{"line":439,"column":0},"end":{"line":439,"column":31}},"439":{"start":{"line":440,"column":0},"end":{"line":440,"column":15}},"440":{"start":{"line":441,"column":0},"end":{"line":441,"column":24}},"441":{"start":{"line":442,"column":0},"end":{"line":442,"column":22}},"442":{"start":{"line":443,"column":0},"end":{"line":443,"column":20}},"443":{"start":{"line":444,"column":0},"end":{"line":444,"column":33}},"444":{"start":{"line":445,"column":0},"end":{"line":445,"column":11}},"445":{"start":{"line":446,"column":0},"end":{"line":446,"column":88}},"446":{"start":{"line":447,"column":0},"end":{"line":447,"column":37}},"447":{"start":{"line":448,"column":0},"end":{"line":448,"column":0}},"448":{"start":{"line":449,"column":0},"end":{"line":449,"column":54}},"449":{"start":{"line":450,"column":0},"end":{"line":450,"column":26}},"450":{"start":{"line":451,"column":0},"end":{"line":451,"column":18}},"451":{"start":{"line":452,"column":0},"end":{"line":452,"column":32}},"452":{"start":{"line":453,"column":0},"end":{"line":453,"column":11}},"453":{"start":{"line":454,"column":0},"end":{"line":454,"column":7}},"454":{"start":{"line":455,"column":0},"end":{"line":455,"column":0}},"455":{"start":{"line":456,"column":0},"end":{"line":456,"column":25}},"456":{"start":{"line":457,"column":0},"end":{"line":457,"column":3}},"457":{"start":{"line":458,"column":0},"end":{"line":458,"column":0}},"458":{"start":{"line":459,"column":0},"end":{"line":459,"column":70}},"459":{"start":{"line":460,"column":0},"end":{"line":460,"column":88}},"460":{"start":{"line":461,"column":0},"end":{"line":461,"column":0}},"461":{"start":{"line":462,"column":0},"end":{"line":462,"column":60}},"462":{"start":{"line":463,"column":0},"end":{"line":463,"column":55}},"463":{"start":{"line":464,"column":0},"end":{"line":464,"column":29}},"464":{"start":{"line":465,"column":0},"end":{"line":465,"column":0}},"465":{"start":{"line":466,"column":0},"end":{"line":466,"column":83}},"466":{"start":{"line":467,"column":0},"end":{"line":467,"column":30}},"467":{"start":{"line":468,"column":0},"end":{"line":468,"column":51}},"468":{"start":{"line":469,"column":0},"end":{"line":469,"column":51}},"469":{"start":{"line":470,"column":0},"end":{"line":470,"column":90}},"470":{"start":{"line":471,"column":0},"end":{"line":471,"column":0}},"471":{"start":{"line":472,"column":0},"end":{"line":472,"column":37}},"472":{"start":{"line":473,"column":0},"end":{"line":473,"column":0}},"473":{"start":{"line":474,"column":0},"end":{"line":474,"column":45}},"474":{"start":{"line":475,"column":0},"end":{"line":475,"column":54}},"475":{"start":{"line":476,"column":0},"end":{"line":476,"column":55}},"476":{"start":{"line":477,"column":0},"end":{"line":477,"column":23}},"477":{"start":{"line":478,"column":0},"end":{"line":478,"column":32}},"478":{"start":{"line":479,"column":0},"end":{"line":479,"column":13}},"479":{"start":{"line":480,"column":0},"end":{"line":480,"column":56}},"480":{"start":{"line":481,"column":0},"end":{"line":481,"column":28}},"481":{"start":{"line":482,"column":0},"end":{"line":482,"column":66}},"482":{"start":{"line":483,"column":0},"end":{"line":483,"column":68}},"483":{"start":{"line":484,"column":0},"end":{"line":484,"column":8}},"484":{"start":{"line":485,"column":0},"end":{"line":485,"column":13}},"485":{"start":{"line":486,"column":0},"end":{"line":486,"column":41}},"486":{"start":{"line":487,"column":0},"end":{"line":487,"column":43}},"487":{"start":{"line":488,"column":0},"end":{"line":488,"column":43}},"488":{"start":{"line":489,"column":0},"end":{"line":489,"column":8}},"489":{"start":{"line":490,"column":0},"end":{"line":490,"column":7}},"490":{"start":{"line":491,"column":0},"end":{"line":491,"column":0}},"491":{"start":{"line":492,"column":0},"end":{"line":492,"column":25}},"492":{"start":{"line":493,"column":0},"end":{"line":493,"column":3}},"493":{"start":{"line":494,"column":0},"end":{"line":494,"column":0}},"494":{"start":{"line":495,"column":0},"end":{"line":495,"column":19}},"495":{"start":{"line":496,"column":0},"end":{"line":496,"column":44}},"496":{"start":{"line":497,"column":0},"end":{"line":497,"column":11}},"497":{"start":{"line":498,"column":0},"end":{"line":498,"column":30}},"498":{"start":{"line":499,"column":0},"end":{"line":499,"column":15}},"499":{"start":{"line":500,"column":0},"end":{"line":500,"column":17}},"500":{"start":{"line":501,"column":0},"end":{"line":501,"column":7}},"501":{"start":{"line":502,"column":0},"end":{"line":502,"column":5}},"502":{"start":{"line":503,"column":0},"end":{"line":503,"column":24}},"503":{"start":{"line":504,"column":0},"end":{"line":504,"column":0}},"504":{"start":{"line":505,"column":0},"end":{"line":505,"column":24}},"505":{"start":{"line":506,"column":0},"end":{"line":506,"column":34}},"506":{"start":{"line":507,"column":0},"end":{"line":507,"column":27}},"507":{"start":{"line":508,"column":0},"end":{"line":508,"column":5}},"508":{"start":{"line":509,"column":0},"end":{"line":509,"column":0}},"509":{"start":{"line":510,"column":0},"end":{"line":510,"column":28}},"510":{"start":{"line":511,"column":0},"end":{"line":511,"column":38}},"511":{"start":{"line":512,"column":0},"end":{"line":512,"column":31}},"512":{"start":{"line":513,"column":0},"end":{"line":513,"column":5}},"513":{"start":{"line":514,"column":0},"end":{"line":514,"column":0}},"514":{"start":{"line":515,"column":0},"end":{"line":515,"column":55}},"515":{"start":{"line":516,"column":0},"end":{"line":516,"column":54}},"516":{"start":{"line":517,"column":0},"end":{"line":517,"column":5}},"517":{"start":{"line":518,"column":0},"end":{"line":518,"column":0}},"518":{"start":{"line":519,"column":0},"end":{"line":519,"column":35}},"519":{"start":{"line":520,"column":0},"end":{"line":520,"column":59}},"520":{"start":{"line":521,"column":0},"end":{"line":521,"column":40}},"521":{"start":{"line":522,"column":0},"end":{"line":522,"column":38}},"522":{"start":{"line":523,"column":0},"end":{"line":523,"column":5}},"523":{"start":{"line":524,"column":0},"end":{"line":524,"column":0}},"524":{"start":{"line":525,"column":0},"end":{"line":525,"column":27}},"525":{"start":{"line":526,"column":0},"end":{"line":526,"column":31}},"526":{"start":{"line":527,"column":0},"end":{"line":527,"column":3}},"527":{"start":{"line":528,"column":0},"end":{"line":528,"column":1}},"528":{"start":{"line":529,"column":0},"end":{"line":529,"column":0}},"529":{"start":{"line":530,"column":0},"end":{"line":530,"column":33}}},"s":{"0":1,"1":1,"2":1,"3":1,"4":1,"5":1,"6":1,"7":1,"8":1,"9":1,"10":1,"11":1,"12":1,"13":1,"14":1,"15":1,"16":1,"17":1,"18":1,"19":1,"20":1,"21":0,"22":0,"23":0,"24":0,"25":0,"26":0,"27":0,"28":0,"29":0,"30":0,"31":0,"32":0,"33":0,"34":0,"35":0,"36":0,"37":0,"38":0,"39":0,"40":0,"41":0,"42":0,"43":0,"44":0,"45":0,"46":0,"47":0,"48":0,"49":0,"50":1,"51":1,"52":0,"53":0,"54":0,"55":0,"56":0,"57":0,"58":0,"59":0,"60":0,"61":0,"62":0,"63":0,"64":1,"65":1,"66":0,"67":0,"68":0,"69":0,"70":0,"71":0,"72":0,"73":0,"74":0,"75":0,"76":0,"77":0,"78":0,"79":0,"80":0,"81":0,"82":0,"83":0,"84":1,"85":1,"86":0,"87":0,"88":0,"89":0,"90":0,"91":1,"92":1,"93":0,"94":0,"95":0,"96":0,"97":0,"98":0,"99":0,"100":0,"101":0,"102":0,"103":0,"104":0,"105":1,"106":1,"107":0,"108":0,"109":0,"110":0,"111":0,"112":0,"113":0,"114":0,"115":1,"116":1,"117":0,"118":0,"119":0,"120":0,"121":0,"122":0,"123":0,"124":0,"125":0,"126":0,"127":0,"128":0,"129":0,"130":0,"131":0,"132":0,"133":0,"134":0,"135":0,"136":0,"137":1,"138":1,"139":0,"140":0,"141":0,"142":0,"143":0,"144":0,"145":0,"146":0,"147":0,"148":0,"149":0,"150":0,"151":0,"152":0,"153":0,"154":1,"155":1,"156":0,"157":0,"158":0,"159":0,"160":0,"161":0,"162":0,"163":0,"164":0,"165":0,"166":0,"167":0,"168":0,"169":0,"170":0,"171":1,"172":1,"173":0,"174":0,"175":0,"176":0,"177":0,"178":0,"179":0,"180":0,"181":0,"182":0,"183":0,"184":0,"185":0,"186":0,"187":0,"188":0,"189":0,"190":0,"191":0,"192":0,"193":0,"194":0,"195":0,"196":0,"197":0,"198":0,"199":0,"200":0,"201":0,"202":0,"203":0,"204":0,"205":0,"206":0,"207":0,"208":0,"209":0,"210":1,"211":1,"212":0,"213":0,"214":0,"215":0,"216":0,"217":0,"218":0,"219":0,"220":0,"221":0,"222":0,"223":0,"224":0,"225":0,"226":0,"227":1,"228":1,"229":0,"230":0,"231":0,"232":0,"233":0,"234":0,"235":0,"236":0,"237":0,"238":0,"239":0,"240":0,"241":0,"242":0,"243":0,"244":0,"245":0,"246":0,"247":0,"248":0,"249":0,"250":0,"251":0,"252":0,"253":0,"254":0,"255":0,"256":0,"257":0,"258":1,"259":1,"260":0,"261":0,"262":0,"263":0,"264":0,"265":0,"266":0,"267":0,"268":0,"269":0,"270":0,"271":0,"272":0,"273":0,"274":0,"275":1,"276":1,"277":0,"278":0,"279":0,"280":0,"281":0,"282":0,"283":0,"284":0,"285":0,"286":0,"287":0,"288":0,"289":0,"290":0,"291":0,"292":0,"293":0,"294":0,"295":0,"296":0,"297":0,"298":0,"299":0,"300":0,"301":0,"302":0,"303":0,"304":0,"305":0,"306":0,"307":0,"308":0,"309":0,"310":0,"311":0,"312":0,"313":0,"314":1,"315":1,"316":0,"317":0,"318":0,"319":0,"320":0,"321":0,"322":0,"323":0,"324":0,"325":0,"326":0,"327":0,"328":0,"329":0,"330":0,"331":0,"332":0,"333":0,"334":0,"335":0,"336":0,"337":0,"338":1,"339":1,"340":0,"341":0,"342":0,"343":0,"344":0,"345":0,"346":0,"347":0,"348":0,"349":0,"350":0,"351":0,"352":0,"353":1,"354":1,"355":0,"356":0,"357":0,"358":0,"359":0,"360":0,"361":0,"362":0,"363":0,"364":0,"365":0,"366":0,"367":0,"368":0,"369":0,"370":0,"371":0,"372":0,"373":0,"374":0,"375":0,"376":0,"377":0,"378":0,"379":0,"380":1,"381":1,"382":0,"383":0,"384":0,"385":0,"386":0,"387":0,"388":0,"389":0,"390":0,"391":0,"392":0,"393":0,"394":0,"395":0,"396":0,"397":0,"398":1,"399":1,"400":0,"401":0,"402":0,"403":0,"404":0,"405":0,"406":0,"407":0,"408":0,"409":0,"410":0,"411":0,"412":0,"413":0,"414":0,"415":0,"416":0,"417":0,"418":0,"419":0,"420":0,"421":0,"422":0,"423":0,"424":0,"425":1,"426":1,"427":0,"428":0,"429":0,"430":0,"431":0,"432":0,"433":0,"434":0,"435":0,"436":0,"437":1,"438":1,"439":0,"440":0,"441":0,"442":0,"443":0,"444":0,"445":0,"446":0,"447":0,"448":0,"449":0,"450":0,"451":0,"452":0,"453":0,"454":0,"455":0,"456":0,"457":1,"458":1,"459":0,"460":0,"461":0,"462":0,"463":0,"464":0,"465":0,"466":0,"467":0,"468":0,"469":0,"470":0,"471":0,"472":0,"473":0,"474":0,"475":0,"476":0,"477":0,"478":0,"479":0,"480":0,"481":0,"482":0,"483":0,"484":0,"485":0,"486":0,"487":0,"488":0,"489":0,"490":0,"491":0,"492":0,"493":1,"494":1,"495":0,"496":0,"497":0,"498":0,"499":0,"500":0,"501":0,"502":0,"503":0,"504":0,"505":0,"506":0,"507":0,"508":0,"509":0,"510":0,"511":0,"512":0,"513":0,"514":0,"515":0,"516":0,"517":0,"518":0,"519":0,"520":0,"521":0,"522":0,"523":0,"524":0,"525":0,"526":0,"527":1,"528":1,"529":1},"branchMap":{},"b":{},"fnMap":{"0":{"name":"PerformancePlugin","decl":{"start":{"line":22,"column":0},"end":{"line":50,"column":40}},"loc":{"start":{"line":22,"column":0},"end":{"line":50,"column":40}},"line":22},"1":{"name":"setup","decl":{"start":{"line":52,"column":2},"end":{"line":64,"column":3}},"loc":{"start":{"line":52,"column":2},"end":{"line":64,"column":3}},"line":52},"2":{"name":"startPageLoadTransaction","decl":{"start":{"line":66,"column":10},"end":{"line":84,"column":3}},"loc":{"start":{"line":66,"column":10},"end":{"line":84,"column":3}},"line":66},"3":{"name":"loadConfig","decl":{"start":{"line":86,"column":10},"end":{"line":91,"column":3}},"loc":{"start":{"line":86,"column":10},"end":{"line":91,"column":3}},"line":86},"4":{"name":"shouldSample","decl":{"start":{"line":93,"column":10},"end":{"line":105,"column":3}},"loc":{"start":{"line":93,"column":10},"end":{"line":105,"column":3}},"line":93},"5":{"name":"observeWebVitals","decl":{"start":{"line":107,"column":10},"end":{"line":115,"column":3}},"loc":{"start":{"line":107,"column":10},"end":{"line":115,"column":3}},"line":107},"6":{"name":"observePaint","decl":{"start":{"line":117,"column":10},"end":{"line":137,"column":3}},"loc":{"start":{"line":117,"column":10},"end":{"line":137,"column":3}},"line":117},"7":{"name":"observeLCP","decl":{"start":{"line":139,"column":10},"end":{"line":154,"column":3}},"loc":{"start":{"line":139,"column":10},"end":{"line":154,"column":3}},"line":139},"8":{"name":"observeFID","decl":{"start":{"line":156,"column":10},"end":{"line":171,"column":3}},"loc":{"start":{"line":156,"column":10},"end":{"line":171,"column":3}},"line":156},"9":{"name":"observeCLS","decl":{"start":{"line":173,"column":10},"end":{"line":210,"column":3}},"loc":{"start":{"line":173,"column":10},"end":{"line":210,"column":3}},"line":173},"10":{"name":"observeTTFB","decl":{"start":{"line":212,"column":10},"end":{"line":227,"column":3}},"loc":{"start":{"line":212,"column":10},"end":{"line":227,"column":3}},"line":212},"11":{"name":"observeLongTasks","decl":{"start":{"line":229,"column":10},"end":{"line":258,"column":3}},"loc":{"start":{"line":229,"column":10},"end":{"line":258,"column":3}},"line":229},"12":{"name":"scheduleTTI","decl":{"start":{"line":260,"column":10},"end":{"line":275,"column":3}},"loc":{"start":{"line":260,"column":10},"end":{"line":275,"column":3}},"line":260},"13":{"name":"observeNavigation","decl":{"start":{"line":277,"column":10},"end":{"line":314,"column":3}},"loc":{"start":{"line":277,"column":10},"end":{"line":314,"column":3}},"line":277},"14":{"name":"buildNavigationSpans","decl":{"start":{"line":316,"column":10},"end":{"line":338,"column":3}},"loc":{"start":{"line":316,"column":10},"end":{"line":338,"column":3}},"line":316},"15":{"name":"finishPageLoadTransaction","decl":{"start":{"line":340,"column":10},"end":{"line":353,"column":3}},"loc":{"start":{"line":340,"column":10},"end":{"line":353,"column":3}},"line":340},"16":{"name":"observeResources","decl":{"start":{"line":355,"column":10},"end":{"line":380,"column":3}},"loc":{"start":{"line":355,"column":10},"end":{"line":380,"column":3}},"line":355},"17":{"name":"getRating","decl":{"start":{"line":382,"column":10},"end":{"line":398,"column":3}},"loc":{"start":{"line":382,"column":10},"end":{"line":398,"column":3}},"line":382},"18":{"name":"reportMetric","decl":{"start":{"line":400,"column":10},"end":{"line":425,"column":3}},"loc":{"start":{"line":400,"column":10},"end":{"line":425,"column":3}},"line":400},"19":{"name":"recordMeasurement","decl":{"start":{"line":427,"column":10},"end":{"line":437,"column":3}},"loc":{"start":{"line":427,"column":10},"end":{"line":437,"column":3}},"line":427},"20":{"name":"createNavigationSpan","decl":{"start":{"line":439,"column":10},"end":{"line":457,"column":3}},"loc":{"start":{"line":439,"column":10},"end":{"line":457,"column":3}},"line":439},"21":{"name":"createResourceSpan","decl":{"start":{"line":459,"column":10},"end":{"line":493,"column":3}},"loc":{"start":{"line":459,"column":10},"end":{"line":493,"column":3}},"line":459},"22":{"name":"destroy","decl":{"start":{"line":495,"column":2},"end":{"line":527,"column":3}},"loc":{"start":{"line":495,"column":2},"end":{"line":527,"column":3}},"line":495}},"f":{"0":0,"1":0,"2":0,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10":0,"11":0,"12":0,"13":0,"14":0,"15":0,"16":0,"17":0,"18":0,"19":0,"20":0,"21":0,"22":0}} +,"/Users/weidingjian/Desktop/work/ai/light-sentry-sdk/src/plugins/RouterPlugin.ts": {"path":"/Users/weidingjian/Desktop/work/ai/light-sentry-sdk/src/plugins/RouterPlugin.ts","all":false,"statementMap":{"0":{"start":{"line":1,"column":0},"end":{"line":1,"column":95}},"1":{"start":{"line":2,"column":0},"end":{"line":2,"column":48}},"2":{"start":{"line":3,"column":0},"end":{"line":3,"column":0}},"3":{"start":{"line":4,"column":0},"end":{"line":4,"column":30}},"4":{"start":{"line":5,"column":0},"end":{"line":5,"column":19}},"5":{"start":{"line":6,"column":0},"end":{"line":6,"column":30}},"6":{"start":{"line":7,"column":0},"end":{"line":7,"column":27}},"7":{"start":{"line":8,"column":0},"end":{"line":8,"column":47}},"8":{"start":{"line":9,"column":0},"end":{"line":9,"column":36}},"9":{"start":{"line":10,"column":0},"end":{"line":10,"column":1}},"10":{"start":{"line":11,"column":0},"end":{"line":11,"column":0}},"11":{"start":{"line":12,"column":0},"end":{"line":12,"column":43}},"12":{"start":{"line":13,"column":0},"end":{"line":13,"column":18}},"13":{"start":{"line":14,"column":0},"end":{"line":14,"column":20}},"14":{"start":{"line":15,"column":0},"end":{"line":15,"column":0}},"15":{"start":{"line":16,"column":0},"end":{"line":16,"column":31}},"16":{"start":{"line":17,"column":0},"end":{"line":17,"column":40}},"17":{"start":{"line":18,"column":0},"end":{"line":18,"column":17}},"18":{"start":{"line":19,"column":0},"end":{"line":19,"column":28}},"19":{"start":{"line":20,"column":0},"end":{"line":20,"column":25}},"20":{"start":{"line":21,"column":0},"end":{"line":21,"column":36}},"21":{"start":{"line":22,"column":0},"end":{"line":22,"column":4}},"22":{"start":{"line":23,"column":0},"end":{"line":23,"column":0}},"23":{"start":{"line":24,"column":0},"end":{"line":24,"column":56}},"24":{"start":{"line":25,"column":0},"end":{"line":25,"column":33}},"25":{"start":{"line":26,"column":0},"end":{"line":26,"column":55}},"26":{"start":{"line":27,"column":0},"end":{"line":27,"column":61}},"27":{"start":{"line":28,"column":0},"end":{"line":28,"column":72}},"28":{"start":{"line":29,"column":0},"end":{"line":29,"column":72}},"29":{"start":{"line":30,"column":0},"end":{"line":30,"column":0}},"30":{"start":{"line":31,"column":0},"end":{"line":31,"column":36}},"31":{"start":{"line":32,"column":0},"end":{"line":32,"column":25}},"32":{"start":{"line":33,"column":0},"end":{"line":33,"column":22}},"33":{"start":{"line":34,"column":0},"end":{"line":34,"column":0}},"34":{"start":{"line":35,"column":0},"end":{"line":35,"column":46}},"35":{"start":{"line":36,"column":0},"end":{"line":36,"column":36}},"36":{"start":{"line":37,"column":0},"end":{"line":37,"column":0}},"37":{"start":{"line":38,"column":0},"end":{"line":38,"column":40}},"38":{"start":{"line":39,"column":0},"end":{"line":39,"column":31}},"39":{"start":{"line":40,"column":0},"end":{"line":40,"column":5}},"40":{"start":{"line":41,"column":0},"end":{"line":41,"column":0}},"41":{"start":{"line":42,"column":0},"end":{"line":42,"column":37}},"42":{"start":{"line":43,"column":0},"end":{"line":43,"column":28}},"43":{"start":{"line":44,"column":0},"end":{"line":44,"column":5}},"44":{"start":{"line":45,"column":0},"end":{"line":45,"column":3}},"45":{"start":{"line":46,"column":0},"end":{"line":46,"column":0}},"46":{"start":{"line":47,"column":0},"end":{"line":47,"column":30}},"47":{"start":{"line":48,"column":0},"end":{"line":48,"column":59}},"48":{"start":{"line":49,"column":0},"end":{"line":49,"column":85}},"49":{"start":{"line":50,"column":0},"end":{"line":50,"column":104}},"50":{"start":{"line":51,"column":0},"end":{"line":51,"column":5}},"51":{"start":{"line":52,"column":0},"end":{"line":52,"column":3}},"52":{"start":{"line":53,"column":0},"end":{"line":53,"column":0}},"53":{"start":{"line":54,"column":0},"end":{"line":54,"column":37}},"54":{"start":{"line":55,"column":0},"end":{"line":55,"column":69}},"55":{"start":{"line":56,"column":0},"end":{"line":56,"column":0}},"56":{"start":{"line":57,"column":0},"end":{"line":57,"column":61}},"57":{"start":{"line":58,"column":0},"end":{"line":58,"column":67}},"58":{"start":{"line":59,"column":0},"end":{"line":59,"column":0}},"59":{"start":{"line":60,"column":0},"end":{"line":60,"column":86}},"60":{"start":{"line":61,"column":0},"end":{"line":61,"column":48}},"61":{"start":{"line":62,"column":0},"end":{"line":62,"column":86}},"62":{"start":{"line":63,"column":0},"end":{"line":63,"column":6}},"63":{"start":{"line":64,"column":0},"end":{"line":64,"column":0}},"64":{"start":{"line":65,"column":0},"end":{"line":65,"column":89}},"65":{"start":{"line":66,"column":0},"end":{"line":66,"column":51}},"66":{"start":{"line":67,"column":0},"end":{"line":67,"column":89}},"67":{"start":{"line":68,"column":0},"end":{"line":68,"column":6}},"68":{"start":{"line":69,"column":0},"end":{"line":69,"column":0}},"69":{"start":{"line":70,"column":0},"end":{"line":70,"column":61}},"70":{"start":{"line":71,"column":0},"end":{"line":71,"column":3}},"71":{"start":{"line":72,"column":0},"end":{"line":72,"column":0}},"72":{"start":{"line":73,"column":0},"end":{"line":73,"column":40}},"73":{"start":{"line":74,"column":0},"end":{"line":74,"column":76}},"74":{"start":{"line":75,"column":0},"end":{"line":75,"column":4}},"75":{"start":{"line":76,"column":0},"end":{"line":76,"column":0}},"76":{"start":{"line":77,"column":0},"end":{"line":77,"column":34}},"77":{"start":{"line":78,"column":0},"end":{"line":78,"column":65}},"78":{"start":{"line":79,"column":0},"end":{"line":79,"column":3}},"79":{"start":{"line":80,"column":0},"end":{"line":80,"column":0}},"80":{"start":{"line":81,"column":0},"end":{"line":81,"column":42}},"81":{"start":{"line":82,"column":0},"end":{"line":82,"column":64}},"82":{"start":{"line":83,"column":0},"end":{"line":83,"column":4}},"83":{"start":{"line":84,"column":0},"end":{"line":84,"column":0}},"84":{"start":{"line":85,"column":0},"end":{"line":85,"column":63}},"85":{"start":{"line":86,"column":0},"end":{"line":86,"column":32}},"86":{"start":{"line":87,"column":0},"end":{"line":87,"column":42}},"87":{"start":{"line":88,"column":0},"end":{"line":88,"column":5}},"88":{"start":{"line":89,"column":0},"end":{"line":89,"column":0}},"89":{"start":{"line":90,"column":0},"end":{"line":90,"column":46}},"90":{"start":{"line":91,"column":0},"end":{"line":91,"column":35}},"91":{"start":{"line":92,"column":0},"end":{"line":92,"column":42}},"92":{"start":{"line":93,"column":0},"end":{"line":93,"column":11}},"93":{"start":{"line":94,"column":0},"end":{"line":94,"column":3}},"94":{"start":{"line":95,"column":0},"end":{"line":95,"column":0}},"95":{"start":{"line":96,"column":0},"end":{"line":96,"column":64}},"96":{"start":{"line":97,"column":0},"end":{"line":97,"column":52}},"97":{"start":{"line":98,"column":0},"end":{"line":98,"column":42}},"98":{"start":{"line":99,"column":0},"end":{"line":99,"column":25}},"99":{"start":{"line":100,"column":0},"end":{"line":100,"column":0}},"100":{"start":{"line":101,"column":0},"end":{"line":101,"column":45}},"101":{"start":{"line":102,"column":0},"end":{"line":102,"column":31}},"102":{"start":{"line":103,"column":0},"end":{"line":103,"column":0}},"103":{"start":{"line":104,"column":0},"end":{"line":104,"column":40}},"104":{"start":{"line":105,"column":0},"end":{"line":105,"column":55}},"105":{"start":{"line":106,"column":0},"end":{"line":106,"column":3}},"106":{"start":{"line":107,"column":0},"end":{"line":107,"column":0}},"107":{"start":{"line":108,"column":0},"end":{"line":108,"column":74}},"108":{"start":{"line":109,"column":0},"end":{"line":109,"column":29}},"109":{"start":{"line":110,"column":0},"end":{"line":110,"column":0}},"110":{"start":{"line":111,"column":0},"end":{"line":111,"column":54}},"111":{"start":{"line":112,"column":0},"end":{"line":112,"column":11}},"112":{"start":{"line":113,"column":0},"end":{"line":113,"column":23}},"113":{"start":{"line":114,"column":0},"end":{"line":114,"column":43}},"114":{"start":{"line":115,"column":0},"end":{"line":115,"column":25}},"115":{"start":{"line":116,"column":0},"end":{"line":116,"column":13}},"116":{"start":{"line":117,"column":0},"end":{"line":117,"column":27}},"117":{"start":{"line":118,"column":0},"end":{"line":118,"column":31}},"118":{"start":{"line":119,"column":0},"end":{"line":119,"column":8}},"119":{"start":{"line":120,"column":0},"end":{"line":120,"column":7}},"120":{"start":{"line":121,"column":0},"end":{"line":121,"column":0}},"121":{"start":{"line":122,"column":0},"end":{"line":122,"column":22}},"122":{"start":{"line":123,"column":0},"end":{"line":123,"column":44}},"123":{"start":{"line":124,"column":0},"end":{"line":124,"column":35}},"124":{"start":{"line":125,"column":0},"end":{"line":125,"column":5}},"125":{"start":{"line":126,"column":0},"end":{"line":126,"column":3}},"126":{"start":{"line":127,"column":0},"end":{"line":127,"column":0}},"127":{"start":{"line":128,"column":0},"end":{"line":128,"column":41}},"128":{"start":{"line":129,"column":0},"end":{"line":129,"column":32}},"129":{"start":{"line":130,"column":0},"end":{"line":130,"column":42}},"130":{"start":{"line":131,"column":0},"end":{"line":131,"column":5}},"131":{"start":{"line":132,"column":0},"end":{"line":132,"column":0}},"132":{"start":{"line":133,"column":0},"end":{"line":133,"column":70}},"133":{"start":{"line":134,"column":0},"end":{"line":134,"column":46}},"134":{"start":{"line":135,"column":0},"end":{"line":135,"column":36}},"135":{"start":{"line":136,"column":0},"end":{"line":136,"column":63}},"136":{"start":{"line":137,"column":0},"end":{"line":137,"column":59}},"137":{"start":{"line":138,"column":0},"end":{"line":138,"column":7}},"138":{"start":{"line":139,"column":0},"end":{"line":139,"column":20}},"139":{"start":{"line":140,"column":0},"end":{"line":140,"column":3}},"140":{"start":{"line":141,"column":0},"end":{"line":141,"column":0}},"141":{"start":{"line":142,"column":0},"end":{"line":142,"column":69}},"142":{"start":{"line":143,"column":0},"end":{"line":143,"column":32}},"143":{"start":{"line":144,"column":0},"end":{"line":144,"column":42}},"144":{"start":{"line":145,"column":0},"end":{"line":145,"column":35}},"145":{"start":{"line":146,"column":0},"end":{"line":146,"column":5}},"146":{"start":{"line":147,"column":0},"end":{"line":147,"column":0}},"147":{"start":{"line":148,"column":0},"end":{"line":148,"column":34}},"148":{"start":{"line":149,"column":0},"end":{"line":149,"column":48}},"149":{"start":{"line":150,"column":0},"end":{"line":150,"column":39}},"150":{"start":{"line":151,"column":0},"end":{"line":151,"column":37}},"151":{"start":{"line":152,"column":0},"end":{"line":152,"column":5}},"152":{"start":{"line":153,"column":0},"end":{"line":153,"column":3}},"153":{"start":{"line":154,"column":0},"end":{"line":154,"column":0}},"154":{"start":{"line":155,"column":0},"end":{"line":155,"column":19}},"155":{"start":{"line":156,"column":0},"end":{"line":156,"column":67}},"156":{"start":{"line":157,"column":0},"end":{"line":157,"column":49}},"157":{"start":{"line":158,"column":0},"end":{"line":158,"column":5}},"158":{"start":{"line":159,"column":0},"end":{"line":159,"column":70}},"159":{"start":{"line":160,"column":0},"end":{"line":160,"column":55}},"160":{"start":{"line":161,"column":0},"end":{"line":161,"column":5}},"161":{"start":{"line":162,"column":0},"end":{"line":162,"column":0}},"162":{"start":{"line":163,"column":0},"end":{"line":163,"column":40}},"163":{"start":{"line":164,"column":0},"end":{"line":164,"column":66}},"164":{"start":{"line":165,"column":0},"end":{"line":165,"column":70}},"165":{"start":{"line":166,"column":0},"end":{"line":166,"column":5}},"166":{"start":{"line":167,"column":0},"end":{"line":167,"column":0}},"167":{"start":{"line":168,"column":0},"end":{"line":168,"column":32}},"168":{"start":{"line":169,"column":0},"end":{"line":169,"column":42}},"169":{"start":{"line":170,"column":0},"end":{"line":170,"column":35}},"170":{"start":{"line":171,"column":0},"end":{"line":171,"column":5}},"171":{"start":{"line":172,"column":0},"end":{"line":172,"column":32}},"172":{"start":{"line":173,"column":0},"end":{"line":173,"column":42}},"173":{"start":{"line":174,"column":0},"end":{"line":174,"column":35}},"174":{"start":{"line":175,"column":0},"end":{"line":175,"column":5}},"175":{"start":{"line":176,"column":0},"end":{"line":176,"column":0}},"176":{"start":{"line":177,"column":0},"end":{"line":177,"column":45}},"177":{"start":{"line":178,"column":0},"end":{"line":178,"column":3}},"178":{"start":{"line":179,"column":0},"end":{"line":179,"column":1}},"179":{"start":{"line":180,"column":0},"end":{"line":180,"column":0}},"180":{"start":{"line":181,"column":0},"end":{"line":181,"column":28}}},"s":{"0":1,"1":1,"2":1,"3":1,"4":1,"5":1,"6":1,"7":1,"8":1,"9":1,"10":1,"11":0,"12":0,"13":0,"14":0,"15":0,"16":0,"17":0,"18":0,"19":0,"20":0,"21":0,"22":0,"23":0,"24":0,"25":0,"26":0,"27":0,"28":0,"29":0,"30":0,"31":0,"32":0,"33":0,"34":0,"35":0,"36":0,"37":0,"38":0,"39":0,"40":0,"41":0,"42":0,"43":0,"44":0,"45":0,"46":0,"47":0,"48":0,"49":0,"50":0,"51":0,"52":0,"53":0,"54":0,"55":0,"56":0,"57":0,"58":0,"59":0,"60":0,"61":0,"62":0,"63":0,"64":0,"65":0,"66":0,"67":0,"68":0,"69":0,"70":0,"71":0,"72":0,"73":0,"74":0,"75":0,"76":0,"77":0,"78":0,"79":0,"80":0,"81":0,"82":0,"83":1,"84":1,"85":0,"86":0,"87":0,"88":0,"89":0,"90":0,"91":0,"92":0,"93":0,"94":1,"95":1,"96":0,"97":0,"98":0,"99":0,"100":0,"101":0,"102":0,"103":0,"104":0,"105":0,"106":1,"107":1,"108":0,"109":0,"110":0,"111":0,"112":0,"113":0,"114":0,"115":0,"116":0,"117":0,"118":0,"119":0,"120":0,"121":0,"122":0,"123":0,"124":0,"125":0,"126":1,"127":1,"128":0,"129":0,"130":0,"131":0,"132":0,"133":0,"134":0,"135":0,"136":0,"137":0,"138":0,"139":0,"140":1,"141":1,"142":0,"143":0,"144":0,"145":0,"146":0,"147":0,"148":0,"149":0,"150":0,"151":0,"152":0,"153":1,"154":1,"155":0,"156":0,"157":0,"158":0,"159":0,"160":0,"161":0,"162":0,"163":0,"164":0,"165":0,"166":0,"167":0,"168":0,"169":0,"170":0,"171":0,"172":0,"173":0,"174":0,"175":0,"176":0,"177":0,"178":1,"179":1,"180":1},"branchMap":{},"b":{},"fnMap":{"0":{"name":"RouterPlugin","decl":{"start":{"line":12,"column":0},"end":{"line":83,"column":4}},"loc":{"start":{"line":12,"column":0},"end":{"line":83,"column":4}},"line":12},"1":{"name":"loadConfig","decl":{"start":{"line":47,"column":10},"end":{"line":52,"column":3}},"loc":{"start":{"line":47,"column":10},"end":{"line":52,"column":3}},"line":47},"2":{"name":"instrumentHistory","decl":{"start":{"line":54,"column":10},"end":{"line":71,"column":3}},"loc":{"start":{"line":54,"column":10},"end":{"line":71,"column":3}},"line":54},"3":{"name":"instrumentHash","decl":{"start":{"line":77,"column":10},"end":{"line":79,"column":3}},"loc":{"start":{"line":77,"column":10},"end":{"line":79,"column":3}},"line":77},"4":{"name":"handleRouteChange","decl":{"start":{"line":85,"column":10},"end":{"line":94,"column":3}},"loc":{"start":{"line":85,"column":10},"end":{"line":94,"column":3}},"line":85},"5":{"name":"processRouteChange","decl":{"start":{"line":96,"column":10},"end":{"line":106,"column":3}},"loc":{"start":{"line":96,"column":10},"end":{"line":106,"column":3}},"line":96},"6":{"name":"startNavigationTransaction","decl":{"start":{"line":108,"column":10},"end":{"line":126,"column":3}},"loc":{"start":{"line":108,"column":10},"end":{"line":126,"column":3}},"line":108},"7":{"name":"startMaxDurationTimer","decl":{"start":{"line":128,"column":10},"end":{"line":140,"column":3}},"loc":{"start":{"line":128,"column":10},"end":{"line":140,"column":3}},"line":128},"8":{"name":"finishCurrentTransaction","decl":{"start":{"line":142,"column":10},"end":{"line":153,"column":3}},"loc":{"start":{"line":142,"column":10},"end":{"line":153,"column":3}},"line":142},"9":{"name":"destroy","decl":{"start":{"line":155,"column":2},"end":{"line":178,"column":3}},"loc":{"start":{"line":155,"column":2},"end":{"line":178,"column":3}},"line":155}},"f":{"0":0,"1":0,"2":0,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0}} +,"/Users/weidingjian/Desktop/work/ai/light-sentry-sdk/src/plugins/SamplingPlugin.ts": {"path":"/Users/weidingjian/Desktop/work/ai/light-sentry-sdk/src/plugins/SamplingPlugin.ts","all":false,"statementMap":{"0":{"start":{"line":1,"column":0},"end":{"line":1,"column":83}},"1":{"start":{"line":2,"column":0},"end":{"line":2,"column":43}},"2":{"start":{"line":3,"column":0},"end":{"line":3,"column":43}},"3":{"start":{"line":4,"column":0},"end":{"line":4,"column":0}},"4":{"start":{"line":5,"column":0},"end":{"line":5,"column":28}},"5":{"start":{"line":6,"column":0},"end":{"line":6,"column":17}},"6":{"start":{"line":7,"column":0},"end":{"line":7,"column":23}},"7":{"start":{"line":8,"column":0},"end":{"line":8,"column":19}},"8":{"start":{"line":9,"column":0},"end":{"line":9,"column":20}},"9":{"start":{"line":10,"column":0},"end":{"line":10,"column":36}},"10":{"start":{"line":11,"column":0},"end":{"line":11,"column":1}},"11":{"start":{"line":12,"column":0},"end":{"line":12,"column":0}},"12":{"start":{"line":13,"column":0},"end":{"line":13,"column":32}},"13":{"start":{"line":14,"column":0},"end":{"line":14,"column":27}},"14":{"start":{"line":15,"column":0},"end":{"line":15,"column":1}},"15":{"start":{"line":16,"column":0},"end":{"line":16,"column":0}},"16":{"start":{"line":17,"column":0},"end":{"line":17,"column":45}},"17":{"start":{"line":18,"column":0},"end":{"line":18,"column":20}},"18":{"start":{"line":19,"column":0},"end":{"line":19,"column":20}},"19":{"start":{"line":20,"column":0},"end":{"line":20,"column":0}},"20":{"start":{"line":21,"column":0},"end":{"line":21,"column":31}},"21":{"start":{"line":22,"column":0},"end":{"line":22,"column":42}},"22":{"start":{"line":23,"column":0},"end":{"line":23,"column":12}},"23":{"start":{"line":24,"column":0},"end":{"line":24,"column":15}},"24":{"start":{"line":25,"column":0},"end":{"line":25,"column":21}},"25":{"start":{"line":26,"column":0},"end":{"line":26,"column":17}},"26":{"start":{"line":27,"column":0},"end":{"line":27,"column":18}},"27":{"start":{"line":28,"column":0},"end":{"line":28,"column":6}},"28":{"start":{"line":29,"column":0},"end":{"line":29,"column":4}},"29":{"start":{"line":30,"column":0},"end":{"line":30,"column":0}},"30":{"start":{"line":31,"column":0},"end":{"line":31,"column":36}},"31":{"start":{"line":32,"column":0},"end":{"line":32,"column":25}},"32":{"start":{"line":33,"column":0},"end":{"line":33,"column":22}},"33":{"start":{"line":34,"column":0},"end":{"line":34,"column":3}},"34":{"start":{"line":35,"column":0},"end":{"line":35,"column":0}},"35":{"start":{"line":36,"column":0},"end":{"line":36,"column":30}},"36":{"start":{"line":37,"column":0},"end":{"line":37,"column":59}},"37":{"start":{"line":38,"column":0},"end":{"line":38,"column":58}},"38":{"start":{"line":39,"column":0},"end":{"line":39,"column":61}},"39":{"start":{"line":40,"column":0},"end":{"line":40,"column":96}},"40":{"start":{"line":41,"column":0},"end":{"line":41,"column":133}},"41":{"start":{"line":42,"column":0},"end":{"line":42,"column":7}},"42":{"start":{"line":43,"column":0},"end":{"line":43,"column":5}},"43":{"start":{"line":44,"column":0},"end":{"line":44,"column":3}},"44":{"start":{"line":45,"column":0},"end":{"line":45,"column":0}},"45":{"start":{"line":46,"column":0},"end":{"line":46,"column":53}},"46":{"start":{"line":47,"column":0},"end":{"line":47,"column":75}},"47":{"start":{"line":48,"column":0},"end":{"line":48,"column":38}},"48":{"start":{"line":49,"column":0},"end":{"line":49,"column":0}},"49":{"start":{"line":50,"column":0},"end":{"line":50,"column":45}},"50":{"start":{"line":51,"column":0},"end":{"line":51,"column":0}},"51":{"start":{"line":52,"column":0},"end":{"line":52,"column":26}},"52":{"start":{"line":53,"column":0},"end":{"line":53,"column":40}},"53":{"start":{"line":54,"column":0},"end":{"line":54,"column":5}},"54":{"start":{"line":55,"column":0},"end":{"line":55,"column":51}},"55":{"start":{"line":56,"column":0},"end":{"line":56,"column":3}},"56":{"start":{"line":57,"column":0},"end":{"line":57,"column":0}},"57":{"start":{"line":58,"column":0},"end":{"line":58,"column":51}},"58":{"start":{"line":59,"column":0},"end":{"line":59,"column":42}},"59":{"start":{"line":60,"column":0},"end":{"line":60,"column":28}},"60":{"start":{"line":61,"column":0},"end":{"line":61,"column":0}},"61":{"start":{"line":62,"column":0},"end":{"line":62,"column":27}},"62":{"start":{"line":63,"column":0},"end":{"line":63,"column":15}},"63":{"start":{"line":64,"column":0},"end":{"line":64,"column":5}},"64":{"start":{"line":65,"column":0},"end":{"line":65,"column":0}},"65":{"start":{"line":66,"column":0},"end":{"line":66,"column":29}},"66":{"start":{"line":67,"column":0},"end":{"line":67,"column":41}},"67":{"start":{"line":68,"column":0},"end":{"line":68,"column":3}},"68":{"start":{"line":69,"column":0},"end":{"line":69,"column":0}},"69":{"start":{"line":70,"column":0},"end":{"line":70,"column":46}},"70":{"start":{"line":71,"column":0},"end":{"line":71,"column":31}},"71":{"start":{"line":72,"column":0},"end":{"line":72,"column":32}},"72":{"start":{"line":73,"column":0},"end":{"line":73,"column":32}},"73":{"start":{"line":74,"column":0},"end":{"line":74,"column":3}},"74":{"start":{"line":75,"column":0},"end":{"line":75,"column":0}},"75":{"start":{"line":76,"column":0},"end":{"line":76,"column":56}},"76":{"start":{"line":77,"column":0},"end":{"line":77,"column":45}},"77":{"start":{"line":78,"column":0},"end":{"line":78,"column":19}},"78":{"start":{"line":79,"column":0},"end":{"line":79,"column":63}},"79":{"start":{"line":80,"column":0},"end":{"line":80,"column":25}},"80":{"start":{"line":81,"column":0},"end":{"line":81,"column":72}},"81":{"start":{"line":82,"column":0},"end":{"line":82,"column":42}},"82":{"start":{"line":83,"column":0},"end":{"line":83,"column":9}},"83":{"start":{"line":84,"column":0},"end":{"line":84,"column":18}},"84":{"start":{"line":85,"column":0},"end":{"line":85,"column":5}},"85":{"start":{"line":86,"column":0},"end":{"line":86,"column":17}},"86":{"start":{"line":87,"column":0},"end":{"line":87,"column":3}},"87":{"start":{"line":88,"column":0},"end":{"line":88,"column":0}},"88":{"start":{"line":89,"column":0},"end":{"line":89,"column":19}},"89":{"start":{"line":90,"column":0},"end":{"line":90,"column":26}},"90":{"start":{"line":91,"column":0},"end":{"line":91,"column":3}},"91":{"start":{"line":92,"column":0},"end":{"line":92,"column":1}},"92":{"start":{"line":93,"column":0},"end":{"line":93,"column":0}},"93":{"start":{"line":94,"column":0},"end":{"line":94,"column":30}}},"s":{"0":1,"1":1,"2":1,"3":1,"4":1,"5":1,"6":1,"7":1,"8":1,"9":1,"10":1,"11":1,"12":1,"13":1,"14":1,"15":1,"16":18,"17":18,"18":18,"19":18,"20":18,"21":18,"22":18,"23":18,"24":18,"25":18,"26":18,"27":18,"28":18,"29":1,"30":1,"31":16,"32":16,"33":16,"34":1,"35":1,"36":16,"37":16,"38":14,"39":14,"40":13,"41":13,"42":14,"43":16,"44":1,"45":1,"46":16,"47":16,"48":13,"49":13,"50":13,"51":16,"52":11,"53":11,"54":2,"55":16,"56":1,"57":1,"58":19,"59":19,"60":19,"61":19,"62":1,"63":1,"64":18,"65":18,"66":19,"67":19,"68":1,"69":1,"70":13,"71":13,"72":4,"73":13,"74":1,"75":1,"76":16,"77":16,"78":6,"79":6,"80":6,"81":6,"82":6,"83":6,"84":6,"85":10,"86":16,"87":1,"88":1,"89":1,"90":1,"91":1,"92":1,"93":1},"branchMap":{"0":{"type":"branch","line":17,"loc":{"start":{"line":17,"column":0},"end":{"line":29,"column":4}},"locations":[{"start":{"line":17,"column":0},"end":{"line":29,"column":4}}]},"1":{"type":"branch","line":31,"loc":{"start":{"line":31,"column":2},"end":{"line":34,"column":3}},"locations":[{"start":{"line":31,"column":2},"end":{"line":34,"column":3}}]},"2":{"type":"branch","line":36,"loc":{"start":{"line":36,"column":10},"end":{"line":44,"column":3}},"locations":[{"start":{"line":36,"column":10},"end":{"line":44,"column":3}}]},"3":{"type":"branch","line":38,"loc":{"start":{"line":38,"column":57},"end":{"line":43,"column":5}},"locations":[{"start":{"line":38,"column":57},"end":{"line":43,"column":5}}]},"4":{"type":"branch","line":40,"loc":{"start":{"line":40,"column":21},"end":{"line":40,"column":95}},"locations":[{"start":{"line":40,"column":21},"end":{"line":40,"column":95}}]},"5":{"type":"branch","line":40,"loc":{"start":{"line":40,"column":95},"end":{"line":42,"column":7}},"locations":[{"start":{"line":40,"column":95},"end":{"line":42,"column":7}}]},"6":{"type":"branch","line":46,"loc":{"start":{"line":46,"column":10},"end":{"line":56,"column":3}},"locations":[{"start":{"line":46,"column":10},"end":{"line":56,"column":3}}]},"7":{"type":"branch","line":47,"loc":{"start":{"line":47,"column":59},"end":{"line":47,"column":75}},"locations":[{"start":{"line":47,"column":59},"end":{"line":47,"column":75}}]},"8":{"type":"branch","line":48,"loc":{"start":{"line":48,"column":25},"end":{"line":48,"column":38}},"locations":[{"start":{"line":48,"column":25},"end":{"line":48,"column":38}}]},"9":{"type":"branch","line":48,"loc":{"start":{"line":48,"column":32},"end":{"line":52,"column":25}},"locations":[{"start":{"line":48,"column":32},"end":{"line":52,"column":25}}]},"10":{"type":"branch","line":52,"loc":{"start":{"line":52,"column":25},"end":{"line":54,"column":5}},"locations":[{"start":{"line":52,"column":25},"end":{"line":54,"column":5}}]},"11":{"type":"branch","line":54,"loc":{"start":{"line":54,"column":4},"end":{"line":55,"column":51}},"locations":[{"start":{"line":54,"column":4},"end":{"line":55,"column":51}}]},"12":{"type":"branch","line":58,"loc":{"start":{"line":58,"column":10},"end":{"line":68,"column":3}},"locations":[{"start":{"line":58,"column":10},"end":{"line":68,"column":3}}]},"13":{"type":"branch","line":59,"loc":{"start":{"line":59,"column":30},"end":{"line":59,"column":42}},"locations":[{"start":{"line":59,"column":30},"end":{"line":59,"column":42}}]},"14":{"type":"branch","line":62,"loc":{"start":{"line":62,"column":26},"end":{"line":64,"column":5}},"locations":[{"start":{"line":62,"column":26},"end":{"line":64,"column":5}}]},"15":{"type":"branch","line":64,"loc":{"start":{"line":64,"column":4},"end":{"line":67,"column":32}},"locations":[{"start":{"line":64,"column":4},"end":{"line":67,"column":32}}]},"16":{"type":"branch","line":67,"loc":{"start":{"line":67,"column":20},"end":{"line":67,"column":39}},"locations":[{"start":{"line":67,"column":20},"end":{"line":67,"column":39}}]},"17":{"type":"branch","line":67,"loc":{"start":{"line":67,"column":32},"end":{"line":67,"column":41}},"locations":[{"start":{"line":67,"column":32},"end":{"line":67,"column":41}}]},"18":{"type":"branch","line":70,"loc":{"start":{"line":70,"column":10},"end":{"line":74,"column":3}},"locations":[{"start":{"line":70,"column":10},"end":{"line":74,"column":3}}]},"19":{"type":"branch","line":71,"loc":{"start":{"line":71,"column":19},"end":{"line":71,"column":31}},"locations":[{"start":{"line":71,"column":19},"end":{"line":71,"column":31}}]},"20":{"type":"branch","line":71,"loc":{"start":{"line":71,"column":26},"end":{"line":72,"column":26}},"locations":[{"start":{"line":71,"column":26},"end":{"line":72,"column":26}}]},"21":{"type":"branch","line":72,"loc":{"start":{"line":72,"column":19},"end":{"line":72,"column":32}},"locations":[{"start":{"line":72,"column":19},"end":{"line":72,"column":32}}]},"22":{"type":"branch","line":72,"loc":{"start":{"line":72,"column":26},"end":{"line":73,"column":32}},"locations":[{"start":{"line":72,"column":26},"end":{"line":73,"column":32}}]},"23":{"type":"branch","line":76,"loc":{"start":{"line":76,"column":2},"end":{"line":87,"column":3}},"locations":[{"start":{"line":76,"column":2},"end":{"line":87,"column":3}}]},"24":{"type":"branch","line":78,"loc":{"start":{"line":78,"column":18},"end":{"line":85,"column":5}},"locations":[{"start":{"line":78,"column":18},"end":{"line":85,"column":5}}]},"25":{"type":"branch","line":81,"loc":{"start":{"line":81,"column":56},"end":{"line":81,"column":72}},"locations":[{"start":{"line":81,"column":56},"end":{"line":81,"column":72}}]},"26":{"type":"branch","line":85,"loc":{"start":{"line":85,"column":4},"end":{"line":86,"column":17}},"locations":[{"start":{"line":85,"column":4},"end":{"line":86,"column":17}}]},"27":{"type":"branch","line":89,"loc":{"start":{"line":89,"column":2},"end":{"line":91,"column":3}},"locations":[{"start":{"line":89,"column":2},"end":{"line":91,"column":3}}]}},"b":{"0":[18],"1":[16],"2":[16],"3":[14],"4":[13],"5":[13],"6":[16],"7":[0],"8":[3],"9":[13],"10":[11],"11":[2],"12":[19],"13":[0],"14":[1],"15":[18],"16":[17],"17":[1],"18":[13],"19":[8],"20":[5],"21":[1],"22":[4],"23":[16],"24":[6],"25":[0],"26":[10],"27":[1]},"fnMap":{"0":{"name":"SamplingPlugin","decl":{"start":{"line":17,"column":0},"end":{"line":29,"column":4}},"loc":{"start":{"line":17,"column":0},"end":{"line":29,"column":4}},"line":17},"1":{"name":"setup","decl":{"start":{"line":31,"column":2},"end":{"line":34,"column":3}},"loc":{"start":{"line":31,"column":2},"end":{"line":34,"column":3}},"line":31},"2":{"name":"loadConfig","decl":{"start":{"line":36,"column":10},"end":{"line":44,"column":3}},"loc":{"start":{"line":36,"column":10},"end":{"line":44,"column":3}},"line":36},"3":{"name":"shouldSample","decl":{"start":{"line":46,"column":10},"end":{"line":56,"column":3}},"loc":{"start":{"line":46,"column":10},"end":{"line":56,"column":3}},"line":46},"4":{"name":"getTypeRate","decl":{"start":{"line":58,"column":10},"end":{"line":68,"column":3}},"loc":{"start":{"line":58,"column":10},"end":{"line":68,"column":3}},"line":58},"5":{"name":"randomCheck","decl":{"start":{"line":70,"column":10},"end":{"line":74,"column":3}},"loc":{"start":{"line":70,"column":10},"end":{"line":74,"column":3}},"line":70},"6":{"name":"beforeReport","decl":{"start":{"line":76,"column":2},"end":{"line":87,"column":3}},"loc":{"start":{"line":76,"column":2},"end":{"line":87,"column":3}},"line":76},"7":{"name":"destroy","decl":{"start":{"line":89,"column":2},"end":{"line":91,"column":3}},"loc":{"start":{"line":89,"column":2},"end":{"line":91,"column":3}},"line":89}},"f":{"0":18,"1":16,"2":16,"3":16,"4":19,"5":13,"6":16,"7":1}} +,"/Users/weidingjian/Desktop/work/ai/light-sentry-sdk/src/utils/baggage.ts": {"path":"/Users/weidingjian/Desktop/work/ai/light-sentry-sdk/src/utils/baggage.ts","all":false,"statementMap":{"0":{"start":{"line":1,"column":0},"end":{"line":1,"column":46}},"1":{"start":{"line":2,"column":0},"end":{"line":2,"column":0}},"2":{"start":{"line":3,"column":0},"end":{"line":3,"column":32}},"3":{"start":{"line":4,"column":0},"end":{"line":4,"column":32}},"4":{"start":{"line":5,"column":0},"end":{"line":5,"column":0}},"5":{"start":{"line":6,"column":0},"end":{"line":6,"column":65}},"6":{"start":{"line":7,"column":0},"end":{"line":7,"column":29}},"7":{"start":{"line":8,"column":0},"end":{"line":8,"column":0}},"8":{"start":{"line":9,"column":0},"end":{"line":9,"column":54}},"9":{"start":{"line":10,"column":0},"end":{"line":10,"column":72}},"10":{"start":{"line":11,"column":0},"end":{"line":11,"column":0}},"11":{"start":{"line":12,"column":0},"end":{"line":12,"column":87}},"12":{"start":{"line":13,"column":0},"end":{"line":13,"column":70}},"13":{"start":{"line":14,"column":0},"end":{"line":14,"column":3}},"14":{"start":{"line":15,"column":0},"end":{"line":15,"column":0}},"15":{"start":{"line":16,"column":0},"end":{"line":16,"column":31}},"16":{"start":{"line":17,"column":0},"end":{"line":17,"column":43}},"17":{"start":{"line":18,"column":0},"end":{"line":18,"column":53}},"18":{"start":{"line":19,"column":0},"end":{"line":19,"column":46}},"19":{"start":{"line":20,"column":0},"end":{"line":20,"column":24}},"20":{"start":{"line":21,"column":0},"end":{"line":21,"column":46}},"21":{"start":{"line":22,"column":0},"end":{"line":22,"column":5}},"22":{"start":{"line":23,"column":0},"end":{"line":23,"column":3}},"23":{"start":{"line":24,"column":0},"end":{"line":24,"column":0}},"24":{"start":{"line":25,"column":0},"end":{"line":25,"column":16}},"25":{"start":{"line":26,"column":0},"end":{"line":26,"column":1}},"26":{"start":{"line":27,"column":0},"end":{"line":27,"column":0}},"27":{"start":{"line":28,"column":0},"end":{"line":28,"column":61}},"28":{"start":{"line":29,"column":0},"end":{"line":29,"column":35}},"29":{"start":{"line":30,"column":0},"end":{"line":30,"column":0}},"30":{"start":{"line":31,"column":0},"end":{"line":31,"column":29}},"31":{"start":{"line":32,"column":0},"end":{"line":32,"column":0}},"32":{"start":{"line":33,"column":0},"end":{"line":33,"column":34}},"33":{"start":{"line":34,"column":0},"end":{"line":34,"column":29}},"34":{"start":{"line":35,"column":0},"end":{"line":35,"column":36}},"35":{"start":{"line":36,"column":0},"end":{"line":36,"column":31}},"36":{"start":{"line":37,"column":0},"end":{"line":37,"column":0}},"37":{"start":{"line":38,"column":0},"end":{"line":38,"column":51}},"38":{"start":{"line":39,"column":0},"end":{"line":39,"column":71}},"39":{"start":{"line":40,"column":0},"end":{"line":40,"column":0}},"40":{"start":{"line":41,"column":0},"end":{"line":41,"column":21}},"41":{"start":{"line":42,"column":0},"end":{"line":42,"column":43}},"42":{"start":{"line":43,"column":0},"end":{"line":43,"column":51}},"43":{"start":{"line":44,"column":0},"end":{"line":44,"column":5}},"44":{"start":{"line":45,"column":0},"end":{"line":45,"column":0}},"45":{"start":{"line":46,"column":0},"end":{"line":46,"column":14}},"46":{"start":{"line":47,"column":0},"end":{"line":47,"column":26}},"47":{"start":{"line":48,"column":0},"end":{"line":48,"column":5}},"48":{"start":{"line":49,"column":0},"end":{"line":49,"column":3}},"49":{"start":{"line":50,"column":0},"end":{"line":50,"column":0}},"50":{"start":{"line":51,"column":0},"end":{"line":51,"column":16}},"51":{"start":{"line":52,"column":0},"end":{"line":52,"column":1}},"52":{"start":{"line":53,"column":0},"end":{"line":53,"column":0}},"53":{"start":{"line":54,"column":0},"end":{"line":54,"column":45}},"54":{"start":{"line":55,"column":0},"end":{"line":55,"column":18}},"55":{"start":{"line":56,"column":0},"end":{"line":56,"column":13}},"56":{"start":{"line":57,"column":0},"end":{"line":57,"column":26}},"57":{"start":{"line":58,"column":0},"end":{"line":58,"column":22}},"58":{"start":{"line":59,"column":0},"end":{"line":59,"column":24}},"59":{"start":{"line":60,"column":0},"end":{"line":60,"column":45}},"60":{"start":{"line":61,"column":0},"end":{"line":61,"column":21}},"61":{"start":{"line":62,"column":0},"end":{"line":62,"column":25}},"62":{"start":{"line":63,"column":0},"end":{"line":63,"column":3}},"63":{"start":{"line":64,"column":0},"end":{"line":64,"column":18}},"64":{"start":{"line":65,"column":0},"end":{"line":65,"column":33}},"65":{"start":{"line":66,"column":0},"end":{"line":66,"column":22}},"66":{"start":{"line":67,"column":0},"end":{"line":67,"column":4}},"67":{"start":{"line":68,"column":0},"end":{"line":68,"column":0}},"68":{"start":{"line":69,"column":0},"end":{"line":69,"column":30}},"69":{"start":{"line":70,"column":0},"end":{"line":70,"column":45}},"70":{"start":{"line":71,"column":0},"end":{"line":71,"column":3}},"71":{"start":{"line":72,"column":0},"end":{"line":72,"column":0}},"72":{"start":{"line":73,"column":0},"end":{"line":73,"column":39}},"73":{"start":{"line":74,"column":0},"end":{"line":74,"column":56}},"74":{"start":{"line":75,"column":0},"end":{"line":75,"column":3}},"75":{"start":{"line":76,"column":0},"end":{"line":76,"column":0}},"76":{"start":{"line":77,"column":0},"end":{"line":77,"column":42}},"77":{"start":{"line":78,"column":0},"end":{"line":78,"column":52}},"78":{"start":{"line":79,"column":0},"end":{"line":79,"column":3}},"79":{"start":{"line":80,"column":0},"end":{"line":80,"column":0}},"80":{"start":{"line":81,"column":0},"end":{"line":81,"column":22}},"81":{"start":{"line":82,"column":0},"end":{"line":82,"column":26}},"82":{"start":{"line":83,"column":0},"end":{"line":83,"column":39}},"83":{"start":{"line":84,"column":0},"end":{"line":84,"column":5}},"84":{"start":{"line":85,"column":0},"end":{"line":85,"column":31}},"85":{"start":{"line":86,"column":0},"end":{"line":86,"column":49}},"86":{"start":{"line":87,"column":0},"end":{"line":87,"column":5}},"87":{"start":{"line":88,"column":0},"end":{"line":88,"column":3}},"88":{"start":{"line":89,"column":0},"end":{"line":89,"column":0}},"89":{"start":{"line":90,"column":0},"end":{"line":90,"column":25}},"90":{"start":{"line":91,"column":0},"end":{"line":91,"column":37}},"91":{"start":{"line":92,"column":0},"end":{"line":92,"column":3}},"92":{"start":{"line":93,"column":0},"end":{"line":93,"column":0}},"93":{"start":{"line":94,"column":0},"end":{"line":94,"column":29}},"94":{"start":{"line":95,"column":0},"end":{"line":95,"column":45}},"95":{"start":{"line":96,"column":0},"end":{"line":96,"column":3}},"96":{"start":{"line":97,"column":0},"end":{"line":97,"column":0}},"97":{"start":{"line":98,"column":0},"end":{"line":98,"column":16}},"98":{"start":{"line":99,"column":0},"end":{"line":99,"column":1}}},"s":{"0":1,"1":1,"2":1,"3":1,"4":1,"5":1,"6":15,"7":15,"8":15,"9":38,"10":36,"11":38,"12":38,"13":38,"14":15,"15":15,"16":15,"17":1,"18":1,"19":1,"20":0,"21":0,"22":1,"23":15,"24":15,"25":15,"26":1,"27":1,"28":8,"29":8,"30":8,"31":7,"32":7,"33":8,"34":20,"35":20,"36":19,"37":19,"38":19,"39":19,"40":19,"41":20,"42":16,"43":16,"44":19,"45":19,"46":19,"47":19,"48":20,"49":7,"50":7,"51":7,"52":1,"53":1,"54":16,"55":16,"56":16,"57":16,"58":16,"59":16,"60":16,"61":16,"62":16,"63":16,"64":16,"65":16,"66":16,"67":16,"68":16,"69":3,"70":3,"71":16,"72":16,"73":5,"74":5,"75":16,"76":16,"77":2,"78":2,"79":16,"80":16,"81":3,"82":3,"83":3,"84":3,"85":2,"86":2,"87":3,"88":16,"89":16,"90":1,"91":1,"92":16,"93":16,"94":1,"95":1,"96":16,"97":16,"98":16},"branchMap":{"0":{"type":"branch","line":6,"loc":{"start":{"line":6,"column":7},"end":{"line":26,"column":1}},"locations":[{"start":{"line":6,"column":7},"end":{"line":26,"column":1}}]},"1":{"type":"branch","line":9,"loc":{"start":{"line":9,"column":53},"end":{"line":14,"column":3}},"locations":[{"start":{"line":9,"column":53},"end":{"line":14,"column":3}}]},"2":{"type":"branch","line":10,"loc":{"start":{"line":10,"column":18},"end":{"line":10,"column":49}},"locations":[{"start":{"line":10,"column":18},"end":{"line":10,"column":49}}]},"3":{"type":"branch","line":10,"loc":{"start":{"line":10,"column":41},"end":{"line":10,"column":63}},"locations":[{"start":{"line":10,"column":41},"end":{"line":10,"column":63}}]},"4":{"type":"branch","line":10,"loc":{"start":{"line":10,"column":63},"end":{"line":10,"column":72}},"locations":[{"start":{"line":10,"column":63},"end":{"line":10,"column":72}}]},"5":{"type":"branch","line":10,"loc":{"start":{"line":10,"column":63},"end":{"line":12,"column":56}},"locations":[{"start":{"line":10,"column":63},"end":{"line":12,"column":56}}]},"6":{"type":"branch","line":12,"loc":{"start":{"line":12,"column":52},"end":{"line":12,"column":62}},"locations":[{"start":{"line":12,"column":52},"end":{"line":12,"column":62}}]},"7":{"type":"branch","line":12,"loc":{"start":{"line":12,"column":56},"end":{"line":12,"column":87}},"locations":[{"start":{"line":12,"column":56},"end":{"line":12,"column":87}}]},"8":{"type":"branch","line":17,"loc":{"start":{"line":17,"column":42},"end":{"line":23,"column":3}},"locations":[{"start":{"line":17,"column":42},"end":{"line":23,"column":3}}]},"9":{"type":"branch","line":20,"loc":{"start":{"line":20,"column":23},"end":{"line":22,"column":5}},"locations":[{"start":{"line":20,"column":23},"end":{"line":22,"column":5}}]},"10":{"type":"branch","line":28,"loc":{"start":{"line":28,"column":7},"end":{"line":52,"column":1}},"locations":[{"start":{"line":28,"column":7},"end":{"line":52,"column":1}}]},"11":{"type":"branch","line":31,"loc":{"start":{"line":31,"column":15},"end":{"line":31,"column":29}},"locations":[{"start":{"line":31,"column":15},"end":{"line":31,"column":29}}]},"12":{"type":"branch","line":31,"loc":{"start":{"line":31,"column":22},"end":{"line":34,"column":28}},"locations":[{"start":{"line":31,"column":22},"end":{"line":34,"column":28}}]},"13":{"type":"branch","line":34,"loc":{"start":{"line":34,"column":28},"end":{"line":49,"column":3}},"locations":[{"start":{"line":34,"column":28},"end":{"line":49,"column":3}}]},"14":{"type":"branch","line":36,"loc":{"start":{"line":36,"column":22},"end":{"line":36,"column":31}},"locations":[{"start":{"line":36,"column":22},"end":{"line":36,"column":31}}]},"15":{"type":"branch","line":36,"loc":{"start":{"line":36,"column":22},"end":{"line":42,"column":42}},"locations":[{"start":{"line":36,"column":22},"end":{"line":42,"column":42}}]},"16":{"type":"branch","line":42,"loc":{"start":{"line":42,"column":42},"end":{"line":44,"column":5}},"locations":[{"start":{"line":42,"column":42},"end":{"line":44,"column":5}}]},"17":{"type":"branch","line":44,"loc":{"start":{"line":44,"column":4},"end":{"line":48,"column":5}},"locations":[{"start":{"line":44,"column":4},"end":{"line":48,"column":5}}]},"18":{"type":"branch","line":49,"loc":{"start":{"line":49,"column":2},"end":{"line":52,"column":1}},"locations":[{"start":{"line":49,"column":2},"end":{"line":52,"column":1}}]},"19":{"type":"branch","line":54,"loc":{"start":{"line":54,"column":7},"end":{"line":99,"column":1}},"locations":[{"start":{"line":54,"column":7},"end":{"line":99,"column":1}}]},"20":{"type":"branch","line":69,"loc":{"start":{"line":69,"column":6},"end":{"line":69,"column":29}},"locations":[{"start":{"line":69,"column":6},"end":{"line":69,"column":29}}]},"21":{"type":"branch","line":69,"loc":{"start":{"line":69,"column":29},"end":{"line":71,"column":3}},"locations":[{"start":{"line":69,"column":29},"end":{"line":71,"column":3}}]},"22":{"type":"branch","line":73,"loc":{"start":{"line":73,"column":6},"end":{"line":73,"column":27}},"locations":[{"start":{"line":73,"column":6},"end":{"line":73,"column":27}}]},"23":{"type":"branch","line":73,"loc":{"start":{"line":73,"column":38},"end":{"line":75,"column":3}},"locations":[{"start":{"line":73,"column":38},"end":{"line":75,"column":3}}]},"24":{"type":"branch","line":74,"loc":{"start":{"line":74,"column":29},"end":{"line":74,"column":48}},"locations":[{"start":{"line":74,"column":29},"end":{"line":74,"column":48}}]},"25":{"type":"branch","line":74,"loc":{"start":{"line":74,"column":39},"end":{"line":74,"column":56}},"locations":[{"start":{"line":74,"column":39},"end":{"line":74,"column":56}}]},"26":{"type":"branch","line":77,"loc":{"start":{"line":77,"column":6},"end":{"line":77,"column":30}},"locations":[{"start":{"line":77,"column":6},"end":{"line":77,"column":30}}]},"27":{"type":"branch","line":77,"loc":{"start":{"line":77,"column":41},"end":{"line":79,"column":3}},"locations":[{"start":{"line":77,"column":41},"end":{"line":79,"column":3}}]},"28":{"type":"branch","line":81,"loc":{"start":{"line":81,"column":6},"end":{"line":81,"column":21}},"locations":[{"start":{"line":81,"column":6},"end":{"line":81,"column":21}}]},"29":{"type":"branch","line":81,"loc":{"start":{"line":81,"column":21},"end":{"line":88,"column":3}},"locations":[{"start":{"line":81,"column":21},"end":{"line":88,"column":3}}]},"30":{"type":"branch","line":85,"loc":{"start":{"line":85,"column":30},"end":{"line":87,"column":5}},"locations":[{"start":{"line":85,"column":30},"end":{"line":87,"column":5}}]},"31":{"type":"branch","line":90,"loc":{"start":{"line":90,"column":6},"end":{"line":90,"column":24}},"locations":[{"start":{"line":90,"column":6},"end":{"line":90,"column":24}}]},"32":{"type":"branch","line":90,"loc":{"start":{"line":90,"column":24},"end":{"line":92,"column":3}},"locations":[{"start":{"line":90,"column":24},"end":{"line":92,"column":3}}]},"33":{"type":"branch","line":94,"loc":{"start":{"line":94,"column":6},"end":{"line":94,"column":28}},"locations":[{"start":{"line":94,"column":6},"end":{"line":94,"column":28}}]},"34":{"type":"branch","line":94,"loc":{"start":{"line":94,"column":28},"end":{"line":96,"column":3}},"locations":[{"start":{"line":94,"column":28},"end":{"line":96,"column":3}}]}},"b":{"0":[15],"1":[38],"2":[37],"3":[37],"4":[2],"5":[36],"6":[1],"7":[35],"8":[1],"9":[0],"10":[8],"11":[1],"12":[7],"13":[20],"14":[1],"15":[19],"16":[16],"17":[19],"18":[7],"19":[16],"20":[14],"21":[3],"22":[14],"23":[5],"24":[4],"25":[1],"26":[14],"27":[2],"28":[14],"29":[3],"30":[2],"31":[14],"32":[1],"33":[14],"34":[1]},"fnMap":{"0":{"name":"serializeBaggage","decl":{"start":{"line":6,"column":7},"end":{"line":26,"column":1}},"loc":{"start":{"line":6,"column":7},"end":{"line":26,"column":1}},"line":6},"1":{"name":"parseBaggage","decl":{"start":{"line":28,"column":7},"end":{"line":52,"column":1}},"loc":{"start":{"line":28,"column":7},"end":{"line":52,"column":1}},"line":28},"2":{"name":"createBaggageFromTransaction","decl":{"start":{"line":54,"column":7},"end":{"line":99,"column":1}},"loc":{"start":{"line":54,"column":7},"end":{"line":99,"column":1}},"line":54}},"f":{"0":15,"1":8,"2":16}} +,"/Users/weidingjian/Desktop/work/ai/light-sentry-sdk/src/utils/dsn.ts": {"path":"/Users/weidingjian/Desktop/work/ai/light-sentry-sdk/src/utils/dsn.ts","all":false,"statementMap":{"0":{"start":{"line":1,"column":0},"end":{"line":1,"column":40}},"1":{"start":{"line":2,"column":0},"end":{"line":2,"column":0}},"2":{"start":{"line":3,"column":0},"end":{"line":3,"column":48}},"3":{"start":{"line":4,"column":0},"end":{"line":4,"column":7}},"4":{"start":{"line":5,"column":0},"end":{"line":5,"column":68}},"5":{"start":{"line":6,"column":0},"end":{"line":6,"column":17}},"6":{"start":{"line":7,"column":0},"end":{"line":7,"column":44}},"7":{"start":{"line":8,"column":0},"end":{"line":8,"column":5}},"8":{"start":{"line":9,"column":0},"end":{"line":9,"column":0}},"9":{"start":{"line":10,"column":0},"end":{"line":10,"column":59}},"10":{"start":{"line":11,"column":0},"end":{"line":11,"column":0}},"11":{"start":{"line":12,"column":0},"end":{"line":12,"column":12}},"12":{"start":{"line":13,"column":0},"end":{"line":13,"column":15}},"13":{"start":{"line":14,"column":0},"end":{"line":14,"column":16}},"14":{"start":{"line":15,"column":0},"end":{"line":15,"column":11}},"15":{"start":{"line":16,"column":0},"end":{"line":16,"column":16}},"16":{"start":{"line":17,"column":0},"end":{"line":17,"column":6}},"17":{"start":{"line":18,"column":0},"end":{"line":18,"column":15}},"18":{"start":{"line":19,"column":0},"end":{"line":19,"column":68}},"19":{"start":{"line":20,"column":0},"end":{"line":20,"column":3}},"20":{"start":{"line":21,"column":0},"end":{"line":21,"column":1}},"21":{"start":{"line":22,"column":0},"end":{"line":22,"column":0}},"22":{"start":{"line":23,"column":0},"end":{"line":23,"column":54}},"23":{"start":{"line":24,"column":0},"end":{"line":24,"column":100}},"24":{"start":{"line":25,"column":0},"end":{"line":25,"column":1}},"25":{"start":{"line":26,"column":0},"end":{"line":26,"column":0}},"26":{"start":{"line":27,"column":0},"end":{"line":27,"column":51}},"27":{"start":{"line":28,"column":0},"end":{"line":28,"column":97}},"28":{"start":{"line":29,"column":0},"end":{"line":29,"column":1}}},"s":{"0":1,"1":1,"2":1,"3":5,"4":5,"5":5,"6":2,"7":2,"8":3,"9":3,"10":3,"11":3,"12":3,"13":3,"14":3,"15":3,"16":3,"17":5,"18":2,"19":2,"20":5,"21":1,"22":1,"23":2,"24":2,"25":1,"26":1,"27":0,"28":0},"branchMap":{"0":{"type":"branch","line":3,"loc":{"start":{"line":3,"column":7},"end":{"line":21,"column":1}},"locations":[{"start":{"line":3,"column":7},"end":{"line":21,"column":1}}]},"1":{"type":"branch","line":6,"loc":{"start":{"line":6,"column":16},"end":{"line":8,"column":5}},"locations":[{"start":{"line":6,"column":16},"end":{"line":8,"column":5}}]},"2":{"type":"branch","line":8,"loc":{"start":{"line":8,"column":4},"end":{"line":18,"column":11}},"locations":[{"start":{"line":8,"column":4},"end":{"line":18,"column":11}}]},"3":{"type":"branch","line":18,"loc":{"start":{"line":18,"column":2},"end":{"line":20,"column":3}},"locations":[{"start":{"line":18,"column":2},"end":{"line":20,"column":3}}]},"4":{"type":"branch","line":23,"loc":{"start":{"line":23,"column":7},"end":{"line":25,"column":1}},"locations":[{"start":{"line":23,"column":7},"end":{"line":25,"column":1}}]}},"b":{"0":[5],"1":[2],"2":[3],"3":[2],"4":[2]},"fnMap":{"0":{"name":"parseDSN","decl":{"start":{"line":3,"column":7},"end":{"line":21,"column":1}},"loc":{"start":{"line":3,"column":7},"end":{"line":21,"column":1}},"line":3},"1":{"name":"getEnvelopeUrl","decl":{"start":{"line":23,"column":7},"end":{"line":25,"column":1}},"loc":{"start":{"line":23,"column":7},"end":{"line":25,"column":1}},"line":23},"2":{"name":"getStoreUrl","decl":{"start":{"line":27,"column":7},"end":{"line":29,"column":1}},"loc":{"start":{"line":27,"column":7},"end":{"line":29,"column":1}},"line":27}},"f":{"0":5,"1":2,"2":0}} +,"/Users/weidingjian/Desktop/work/ai/light-sentry-sdk/src/utils/env.ts": {"path":"/Users/weidingjian/Desktop/work/ai/light-sentry-sdk/src/utils/env.ts","all":false,"statementMap":{"0":{"start":{"line":1,"column":0},"end":{"line":1,"column":29}},"1":{"start":{"line":2,"column":0},"end":{"line":2,"column":0}},"2":{"start":{"line":3,"column":0},"end":{"line":3,"column":30}},"3":{"start":{"line":4,"column":0},"end":{"line":4,"column":15}},"4":{"start":{"line":5,"column":0},"end":{"line":5,"column":18}},"5":{"start":{"line":6,"column":0},"end":{"line":6,"column":16}},"6":{"start":{"line":7,"column":0},"end":{"line":7,"column":1}},"7":{"start":{"line":8,"column":0},"end":{"line":8,"column":0}},"8":{"start":{"line":9,"column":0},"end":{"line":9,"column":25}},"9":{"start":{"line":10,"column":0},"end":{"line":10,"column":15}},"10":{"start":{"line":11,"column":0},"end":{"line":11,"column":18}},"11":{"start":{"line":12,"column":0},"end":{"line":12,"column":1}},"12":{"start":{"line":13,"column":0},"end":{"line":13,"column":0}},"13":{"start":{"line":14,"column":0},"end":{"line":14,"column":29}},"14":{"start":{"line":15,"column":0},"end":{"line":15,"column":40}},"15":{"start":{"line":16,"column":0},"end":{"line":16,"column":17}},"16":{"start":{"line":17,"column":0},"end":{"line":17,"column":16}},"17":{"start":{"line":18,"column":0},"end":{"line":18,"column":1}},"18":{"start":{"line":19,"column":0},"end":{"line":19,"column":0}},"19":{"start":{"line":20,"column":0},"end":{"line":20,"column":26}},"20":{"start":{"line":21,"column":0},"end":{"line":21,"column":23}},"21":{"start":{"line":22,"column":0},"end":{"line":22,"column":13}},"22":{"start":{"line":23,"column":0},"end":{"line":23,"column":21}},"23":{"start":{"line":24,"column":0},"end":{"line":24,"column":14}},"24":{"start":{"line":25,"column":0},"end":{"line":25,"column":19}},"25":{"start":{"line":26,"column":0},"end":{"line":26,"column":16}},"26":{"start":{"line":27,"column":0},"end":{"line":27,"column":19}},"27":{"start":{"line":28,"column":0},"end":{"line":28,"column":21}},"28":{"start":{"line":29,"column":0},"end":{"line":29,"column":23}},"29":{"start":{"line":30,"column":0},"end":{"line":30,"column":24}},"30":{"start":{"line":31,"column":0},"end":{"line":31,"column":25}},"31":{"start":{"line":32,"column":0},"end":{"line":32,"column":26}},"32":{"start":{"line":33,"column":0},"end":{"line":33,"column":1}},"33":{"start":{"line":34,"column":0},"end":{"line":34,"column":0}},"34":{"start":{"line":35,"column":0},"end":{"line":35,"column":49}},"35":{"start":{"line":36,"column":0},"end":{"line":36,"column":80}},"36":{"start":{"line":37,"column":0},"end":{"line":37,"column":61}},"37":{"start":{"line":38,"column":0},"end":{"line":38,"column":60}},"38":{"start":{"line":39,"column":0},"end":{"line":39,"column":60}},"39":{"start":{"line":40,"column":0},"end":{"line":40,"column":48}},"40":{"start":{"line":41,"column":0},"end":{"line":41,"column":49}},"41":{"start":{"line":42,"column":0},"end":{"line":42,"column":49}},"42":{"start":{"line":43,"column":0},"end":{"line":43,"column":51}},"43":{"start":{"line":44,"column":0},"end":{"line":44,"column":55}},"44":{"start":{"line":45,"column":0},"end":{"line":45,"column":62}},"45":{"start":{"line":46,"column":0},"end":{"line":46,"column":53}},"46":{"start":{"line":47,"column":0},"end":{"line":47,"column":46}},"47":{"start":{"line":48,"column":0},"end":{"line":48,"column":53}},"48":{"start":{"line":49,"column":0},"end":{"line":49,"column":4}},"49":{"start":{"line":50,"column":0},"end":{"line":50,"column":0}},"50":{"start":{"line":51,"column":0},"end":{"line":51,"column":29}},"51":{"start":{"line":52,"column":0},"end":{"line":52,"column":38}},"52":{"start":{"line":53,"column":0},"end":{"line":53,"column":16}},"53":{"start":{"line":54,"column":0},"end":{"line":54,"column":37}},"54":{"start":{"line":55,"column":0},"end":{"line":55,"column":48}},"55":{"start":{"line":56,"column":0},"end":{"line":56,"column":46}},"56":{"start":{"line":57,"column":0},"end":{"line":57,"column":5}},"57":{"start":{"line":58,"column":0},"end":{"line":58,"column":3}},"58":{"start":{"line":59,"column":0},"end":{"line":59,"column":0}},"59":{"start":{"line":60,"column":0},"end":{"line":60,"column":53}},"60":{"start":{"line":61,"column":0},"end":{"line":61,"column":1}},"61":{"start":{"line":62,"column":0},"end":{"line":62,"column":0}},"62":{"start":{"line":63,"column":0},"end":{"line":63,"column":39}},"63":{"start":{"line":64,"column":0},"end":{"line":64,"column":75}},"64":{"start":{"line":65,"column":0},"end":{"line":65,"column":69}},"65":{"start":{"line":66,"column":0},"end":{"line":66,"column":57}},"66":{"start":{"line":67,"column":0},"end":{"line":67,"column":57}},"67":{"start":{"line":68,"column":0},"end":{"line":68,"column":55}},"68":{"start":{"line":69,"column":0},"end":{"line":69,"column":55}},"69":{"start":{"line":70,"column":0},"end":{"line":70,"column":59}},"70":{"start":{"line":71,"column":0},"end":{"line":71,"column":56}},"71":{"start":{"line":72,"column":0},"end":{"line":72,"column":54}},"72":{"start":{"line":73,"column":0},"end":{"line":73,"column":60}},"73":{"start":{"line":74,"column":0},"end":{"line":74,"column":54}},"74":{"start":{"line":75,"column":0},"end":{"line":75,"column":45}},"75":{"start":{"line":76,"column":0},"end":{"line":76,"column":41}},"76":{"start":{"line":77,"column":0},"end":{"line":77,"column":4}},"77":{"start":{"line":78,"column":0},"end":{"line":78,"column":0}},"78":{"start":{"line":79,"column":0},"end":{"line":79,"column":24}},"79":{"start":{"line":80,"column":0},"end":{"line":80,"column":38}},"80":{"start":{"line":81,"column":0},"end":{"line":81,"column":16}},"81":{"start":{"line":82,"column":0},"end":{"line":82,"column":35}},"82":{"start":{"line":83,"column":0},"end":{"line":83,"column":20}},"83":{"start":{"line":84,"column":0},"end":{"line":84,"column":45}},"84":{"start":{"line":85,"column":0},"end":{"line":85,"column":7}},"85":{"start":{"line":86,"column":0},"end":{"line":86,"column":39}},"86":{"start":{"line":87,"column":0},"end":{"line":87,"column":5}},"87":{"start":{"line":88,"column":0},"end":{"line":88,"column":3}},"88":{"start":{"line":89,"column":0},"end":{"line":89,"column":0}},"89":{"start":{"line":90,"column":0},"end":{"line":90,"column":42}},"90":{"start":{"line":91,"column":0},"end":{"line":91,"column":1}},"91":{"start":{"line":92,"column":0},"end":{"line":92,"column":0}},"92":{"start":{"line":93,"column":0},"end":{"line":93,"column":47}},"93":{"start":{"line":94,"column":0},"end":{"line":94,"column":94}},"94":{"start":{"line":95,"column":0},"end":{"line":95,"column":64}},"95":{"start":{"line":96,"column":0},"end":{"line":96,"column":0}},"96":{"start":{"line":97,"column":0},"end":{"line":97,"column":56}},"97":{"start":{"line":98,"column":0},"end":{"line":98,"column":17}},"98":{"start":{"line":99,"column":0},"end":{"line":99,"column":20}},"99":{"start":{"line":100,"column":0},"end":{"line":100,"column":24}},"100":{"start":{"line":101,"column":0},"end":{"line":101,"column":20}},"101":{"start":{"line":102,"column":0},"end":{"line":102,"column":3}},"102":{"start":{"line":103,"column":0},"end":{"line":103,"column":0}},"103":{"start":{"line":104,"column":0},"end":{"line":104,"column":18}},"104":{"start":{"line":105,"column":0},"end":{"line":105,"column":17}},"105":{"start":{"line":106,"column":0},"end":{"line":106,"column":0}},"106":{"start":{"line":107,"column":0},"end":{"line":107,"column":42}},"107":{"start":{"line":108,"column":0},"end":{"line":108,"column":38}},"108":{"start":{"line":109,"column":0},"end":{"line":109,"column":51}},"109":{"start":{"line":110,"column":0},"end":{"line":110,"column":52}},"110":{"start":{"line":111,"column":0},"end":{"line":111,"column":54}},"111":{"start":{"line":112,"column":0},"end":{"line":112,"column":0}},"112":{"start":{"line":113,"column":0},"end":{"line":113,"column":20}},"113":{"start":{"line":114,"column":0},"end":{"line":114,"column":21}},"114":{"start":{"line":115,"column":0},"end":{"line":115,"column":21}},"115":{"start":{"line":116,"column":0},"end":{"line":116,"column":25}},"116":{"start":{"line":117,"column":0},"end":{"line":117,"column":21}},"117":{"start":{"line":118,"column":0},"end":{"line":118,"column":19}},"118":{"start":{"line":119,"column":0},"end":{"line":119,"column":28}},"119":{"start":{"line":120,"column":0},"end":{"line":120,"column":23}},"120":{"start":{"line":121,"column":0},"end":{"line":121,"column":28}},"121":{"start":{"line":122,"column":0},"end":{"line":122,"column":26}},"122":{"start":{"line":123,"column":0},"end":{"line":123,"column":22}},"123":{"start":{"line":124,"column":0},"end":{"line":124,"column":37}},"124":{"start":{"line":125,"column":0},"end":{"line":125,"column":27}},"125":{"start":{"line":126,"column":0},"end":{"line":126,"column":22}},"126":{"start":{"line":127,"column":0},"end":{"line":127,"column":27}},"127":{"start":{"line":128,"column":0},"end":{"line":128,"column":3}},"128":{"start":{"line":129,"column":0},"end":{"line":129,"column":0}},"129":{"start":{"line":130,"column":0},"end":{"line":130,"column":33}},"130":{"start":{"line":131,"column":0},"end":{"line":131,"column":1}},"131":{"start":{"line":132,"column":0},"end":{"line":132,"column":0}},"132":{"start":{"line":133,"column":0},"end":{"line":133,"column":39}},"133":{"start":{"line":134,"column":0},"end":{"line":134,"column":73}},"134":{"start":{"line":135,"column":0},"end":{"line":135,"column":36}},"135":{"start":{"line":136,"column":0},"end":{"line":136,"column":26}},"136":{"start":{"line":137,"column":0},"end":{"line":137,"column":34}},"137":{"start":{"line":138,"column":0},"end":{"line":138,"column":0}},"138":{"start":{"line":139,"column":0},"end":{"line":139,"column":10}},"139":{"start":{"line":140,"column":0},"end":{"line":140,"column":12}},"140":{"start":{"line":141,"column":0},"end":{"line":141,"column":7}},"141":{"start":{"line":142,"column":0},"end":{"line":142,"column":11}},"142":{"start":{"line":143,"column":0},"end":{"line":143,"column":62}},"143":{"start":{"line":144,"column":0},"end":{"line":144,"column":71}},"144":{"start":{"line":145,"column":0},"end":{"line":145,"column":65}},"145":{"start":{"line":146,"column":0},"end":{"line":146,"column":73}},"146":{"start":{"line":147,"column":0},"end":{"line":147,"column":19}},"147":{"start":{"line":148,"column":0},"end":{"line":148,"column":67}},"148":{"start":{"line":149,"column":0},"end":{"line":149,"column":69}},"149":{"start":{"line":150,"column":0},"end":{"line":150,"column":74}},"150":{"start":{"line":151,"column":0},"end":{"line":151,"column":76}},"151":{"start":{"line":152,"column":0},"end":{"line":152,"column":4}},"152":{"start":{"line":153,"column":0},"end":{"line":153,"column":1}},"153":{"start":{"line":154,"column":0},"end":{"line":154,"column":0}},"154":{"start":{"line":155,"column":0},"end":{"line":155,"column":38}},"155":{"start":{"line":156,"column":0},"end":{"line":156,"column":62}},"156":{"start":{"line":157,"column":0},"end":{"line":157,"column":1}},"157":{"start":{"line":158,"column":0},"end":{"line":158,"column":0}},"158":{"start":{"line":159,"column":0},"end":{"line":159,"column":39}},"159":{"start":{"line":160,"column":0},"end":{"line":160,"column":66}},"160":{"start":{"line":161,"column":0},"end":{"line":161,"column":1}},"161":{"start":{"line":162,"column":0},"end":{"line":162,"column":0}},"162":{"start":{"line":163,"column":0},"end":{"line":163,"column":50}},"163":{"start":{"line":164,"column":0},"end":{"line":164,"column":23}},"164":{"start":{"line":165,"column":0},"end":{"line":165,"column":0}},"165":{"start":{"line":166,"column":0},"end":{"line":166,"column":29}},"166":{"start":{"line":167,"column":0},"end":{"line":167,"column":37}},"167":{"start":{"line":168,"column":0},"end":{"line":168,"column":35}},"168":{"start":{"line":169,"column":0},"end":{"line":169,"column":3}},"169":{"start":{"line":170,"column":0},"end":{"line":170,"column":0}},"170":{"start":{"line":171,"column":0},"end":{"line":171,"column":7}},"171":{"start":{"line":172,"column":0},"end":{"line":172,"column":32}},"172":{"start":{"line":173,"column":0},"end":{"line":173,"column":29}},"173":{"start":{"line":174,"column":0},"end":{"line":174,"column":34}},"174":{"start":{"line":175,"column":0},"end":{"line":175,"column":47}},"175":{"start":{"line":176,"column":0},"end":{"line":176,"column":33}},"176":{"start":{"line":177,"column":0},"end":{"line":177,"column":30}},"177":{"start":{"line":178,"column":0},"end":{"line":178,"column":21}},"178":{"start":{"line":179,"column":0},"end":{"line":179,"column":28}},"179":{"start":{"line":180,"column":0},"end":{"line":180,"column":30}},"180":{"start":{"line":181,"column":0},"end":{"line":181,"column":6}},"181":{"start":{"line":182,"column":0},"end":{"line":182,"column":0}},"182":{"start":{"line":183,"column":0},"end":{"line":183,"column":39}},"183":{"start":{"line":184,"column":0},"end":{"line":184,"column":25}},"184":{"start":{"line":185,"column":0},"end":{"line":185,"column":0}},"185":{"start":{"line":186,"column":0},"end":{"line":186,"column":50}},"186":{"start":{"line":187,"column":0},"end":{"line":187,"column":63}},"187":{"start":{"line":188,"column":0},"end":{"line":188,"column":60}},"188":{"start":{"line":189,"column":0},"end":{"line":189,"column":38}},"189":{"start":{"line":190,"column":0},"end":{"line":190,"column":24}},"190":{"start":{"line":191,"column":0},"end":{"line":191,"column":7}},"191":{"start":{"line":192,"column":0},"end":{"line":192,"column":5}},"192":{"start":{"line":193,"column":0},"end":{"line":193,"column":0}},"193":{"start":{"line":194,"column":0},"end":{"line":194,"column":48}},"194":{"start":{"line":195,"column":0},"end":{"line":195,"column":51}},"195":{"start":{"line":196,"column":0},"end":{"line":196,"column":38}},"196":{"start":{"line":197,"column":0},"end":{"line":197,"column":60}},"197":{"start":{"line":198,"column":0},"end":{"line":198,"column":33}},"198":{"start":{"line":199,"column":0},"end":{"line":199,"column":58}},"199":{"start":{"line":200,"column":0},"end":{"line":200,"column":67}},"200":{"start":{"line":201,"column":0},"end":{"line":201,"column":64}},"201":{"start":{"line":202,"column":0},"end":{"line":202,"column":46}},"202":{"start":{"line":203,"column":0},"end":{"line":203,"column":32}},"203":{"start":{"line":204,"column":0},"end":{"line":204,"column":11}},"204":{"start":{"line":205,"column":0},"end":{"line":205,"column":9}},"205":{"start":{"line":206,"column":0},"end":{"line":206,"column":27}},"206":{"start":{"line":207,"column":0},"end":{"line":207,"column":52}},"207":{"start":{"line":208,"column":0},"end":{"line":208,"column":26}},"208":{"start":{"line":209,"column":0},"end":{"line":209,"column":9}},"209":{"start":{"line":210,"column":0},"end":{"line":210,"column":7}},"210":{"start":{"line":211,"column":0},"end":{"line":211,"column":5}},"211":{"start":{"line":212,"column":0},"end":{"line":212,"column":0}},"212":{"start":{"line":213,"column":0},"end":{"line":213,"column":19}},"213":{"start":{"line":214,"column":0},"end":{"line":214,"column":31}},"214":{"start":{"line":215,"column":0},"end":{"line":215,"column":5}},"215":{"start":{"line":216,"column":0},"end":{"line":216,"column":15}},"216":{"start":{"line":217,"column":0},"end":{"line":217,"column":11}},"217":{"start":{"line":218,"column":0},"end":{"line":218,"column":15}},"218":{"start":{"line":219,"column":0},"end":{"line":219,"column":3}},"219":{"start":{"line":220,"column":0},"end":{"line":220,"column":1}},"220":{"start":{"line":221,"column":0},"end":{"line":221,"column":0}},"221":{"start":{"line":222,"column":0},"end":{"line":222,"column":93}},"222":{"start":{"line":223,"column":0},"end":{"line":223,"column":59}},"223":{"start":{"line":224,"column":0},"end":{"line":224,"column":0}},"224":{"start":{"line":225,"column":0},"end":{"line":225,"column":37}},"225":{"start":{"line":226,"column":0},"end":{"line":226,"column":38}},"226":{"start":{"line":227,"column":0},"end":{"line":227,"column":34}},"227":{"start":{"line":228,"column":0},"end":{"line":228,"column":40}},"228":{"start":{"line":229,"column":0},"end":{"line":229,"column":91}},"229":{"start":{"line":230,"column":0},"end":{"line":230,"column":42}},"230":{"start":{"line":231,"column":0},"end":{"line":231,"column":31}},"231":{"start":{"line":232,"column":0},"end":{"line":232,"column":7}},"232":{"start":{"line":233,"column":0},"end":{"line":233,"column":35}},"233":{"start":{"line":234,"column":0},"end":{"line":234,"column":5}},"234":{"start":{"line":235,"column":0},"end":{"line":235,"column":29}},"235":{"start":{"line":236,"column":0},"end":{"line":236,"column":5}},"236":{"start":{"line":237,"column":0},"end":{"line":237,"column":1}},"237":{"start":{"line":238,"column":0},"end":{"line":238,"column":0}},"238":{"start":{"line":239,"column":0},"end":{"line":239,"column":50}},"239":{"start":{"line":240,"column":0},"end":{"line":240,"column":16}},"240":{"start":{"line":241,"column":0},"end":{"line":241,"column":16}},"241":{"start":{"line":242,"column":0},"end":{"line":242,"column":17}},"242":{"start":{"line":243,"column":0},"end":{"line":243,"column":14}},"243":{"start":{"line":244,"column":0},"end":{"line":244,"column":15}},"244":{"start":{"line":245,"column":0},"end":{"line":245,"column":12}},"245":{"start":{"line":246,"column":0},"end":{"line":246,"column":16}},"246":{"start":{"line":247,"column":0},"end":{"line":247,"column":20}},"247":{"start":{"line":248,"column":0},"end":{"line":248,"column":20}},"248":{"start":{"line":249,"column":0},"end":{"line":249,"column":24}},"249":{"start":{"line":250,"column":0},"end":{"line":250,"column":24}},"250":{"start":{"line":251,"column":0},"end":{"line":251,"column":2}},"251":{"start":{"line":252,"column":0},"end":{"line":252,"column":0}},"252":{"start":{"line":253,"column":0},"end":{"line":253,"column":45}},"253":{"start":{"line":254,"column":0},"end":{"line":254,"column":22}},"254":{"start":{"line":255,"column":0},"end":{"line":255,"column":22}},"255":{"start":{"line":256,"column":0},"end":{"line":256,"column":23}},"256":{"start":{"line":257,"column":0},"end":{"line":257,"column":20}},"257":{"start":{"line":258,"column":0},"end":{"line":258,"column":20}},"258":{"start":{"line":259,"column":0},"end":{"line":259,"column":24}},"259":{"start":{"line":260,"column":0},"end":{"line":260,"column":22}},"260":{"start":{"line":261,"column":0},"end":{"line":261,"column":15}},"261":{"start":{"line":262,"column":0},"end":{"line":262,"column":13}},"262":{"start":{"line":263,"column":0},"end":{"line":263,"column":17}},"263":{"start":{"line":264,"column":0},"end":{"line":264,"column":15}},"264":{"start":{"line":265,"column":0},"end":{"line":265,"column":2}},"265":{"start":{"line":266,"column":0},"end":{"line":266,"column":0}},"266":{"start":{"line":267,"column":0},"end":{"line":267,"column":31}},"267":{"start":{"line":268,"column":0},"end":{"line":268,"column":27}},"268":{"start":{"line":269,"column":0},"end":{"line":269,"column":91}},"269":{"start":{"line":270,"column":0},"end":{"line":270,"column":71}},"270":{"start":{"line":271,"column":0},"end":{"line":271,"column":0}},"271":{"start":{"line":272,"column":0},"end":{"line":272,"column":10}},"272":{"start":{"line":273,"column":0},"end":{"line":273,"column":14}},"273":{"start":{"line":274,"column":0},"end":{"line":274,"column":24}},"274":{"start":{"line":275,"column":0},"end":{"line":275,"column":33}},"275":{"start":{"line":276,"column":0},"end":{"line":276,"column":6}},"276":{"start":{"line":277,"column":0},"end":{"line":277,"column":9}},"277":{"start":{"line":278,"column":0},"end":{"line":278,"column":19}},"278":{"start":{"line":279,"column":0},"end":{"line":279,"column":44}},"279":{"start":{"line":280,"column":0},"end":{"line":280,"column":6}},"280":{"start":{"line":281,"column":0},"end":{"line":281,"column":13}},"281":{"start":{"line":282,"column":0},"end":{"line":282,"column":28}},"282":{"start":{"line":283,"column":0},"end":{"line":283,"column":44}},"283":{"start":{"line":284,"column":0},"end":{"line":284,"column":43}},"284":{"start":{"line":285,"column":0},"end":{"line":285,"column":6}},"285":{"start":{"line":286,"column":0},"end":{"line":286,"column":4}},"286":{"start":{"line":287,"column":0},"end":{"line":287,"column":1}},"287":{"start":{"line":288,"column":0},"end":{"line":288,"column":0}},"288":{"start":{"line":289,"column":0},"end":{"line":289,"column":40}},"289":{"start":{"line":290,"column":0},"end":{"line":290,"column":27}},"290":{"start":{"line":291,"column":0},"end":{"line":291,"column":180}},"291":{"start":{"line":292,"column":0},"end":{"line":292,"column":35}},"292":{"start":{"line":293,"column":0},"end":{"line":293,"column":1}}},"s":{"0":1,"1":1,"2":1,"3":1,"4":1,"5":1,"6":1,"7":1,"8":1,"9":1,"10":1,"11":1,"12":1,"13":1,"14":1,"15":1,"16":1,"17":1,"18":1,"19":1,"20":1,"21":1,"22":1,"23":1,"24":1,"25":1,"26":1,"27":1,"28":1,"29":1,"30":1,"31":1,"32":1,"33":1,"34":31,"35":31,"36":31,"37":31,"38":31,"39":31,"40":31,"41":31,"42":31,"43":31,"44":31,"45":31,"46":31,"47":31,"48":31,"49":31,"50":31,"51":293,"52":293,"53":26,"54":26,"55":26,"56":26,"57":293,"58":5,"59":5,"60":5,"61":1,"62":31,"63":31,"64":31,"65":31,"66":31,"67":31,"68":31,"69":31,"70":31,"71":31,"72":31,"73":31,"74":31,"75":31,"76":31,"77":31,"78":31,"79":219,"80":219,"81":26,"82":26,"83":16,"84":16,"85":26,"86":26,"87":219,"88":5,"89":5,"90":5,"91":1,"92":31,"93":31,"94":31,"95":31,"96":31,"97":31,"98":2,"99":31,"100":11,"101":11,"102":31,"103":31,"104":31,"105":31,"106":31,"107":31,"108":31,"109":31,"110":31,"111":31,"112":31,"113":3,"114":3,"115":31,"116":2,"117":2,"118":28,"119":3,"120":3,"121":26,"122":1,"123":1,"124":23,"125":4,"126":4,"127":4,"128":31,"129":31,"130":31,"131":1,"132":1,"133":31,"134":31,"135":31,"136":31,"137":31,"138":31,"139":31,"140":31,"141":31,"142":31,"143":31,"144":31,"145":31,"146":31,"147":31,"148":31,"149":31,"150":31,"151":31,"152":31,"153":1,"154":1,"155":1,"156":1,"157":1,"158":1,"159":1,"160":1,"161":1,"162":1,"163":13,"164":10,"165":10,"166":13,"167":2,"168":2,"169":8,"170":8,"171":8,"172":8,"173":8,"174":8,"175":8,"176":8,"177":8,"178":8,"179":8,"180":8,"181":8,"182":8,"183":8,"184":8,"185":13,"186":15,"187":15,"188":9,"189":9,"190":9,"191":15,"192":7,"193":13,"194":1,"195":1,"196":1,"197":1,"198":1,"199":2,"200":2,"201":1,"202":1,"203":1,"204":2,"205":1,"206":1,"207":1,"208":1,"209":1,"210":1,"211":7,"212":13,"213":5,"214":5,"215":2,"216":13,"217":1,"218":1,"219":13,"220":1,"221":1,"222":11,"223":10,"224":10,"225":15,"226":12,"227":3,"228":3,"229":3,"230":3,"231":3,"232":9,"233":9,"234":3,"235":10,"236":10,"237":1,"238":1,"239":1,"240":1,"241":1,"242":1,"243":1,"244":1,"245":1,"246":1,"247":1,"248":1,"249":1,"250":1,"251":1,"252":1,"253":1,"254":1,"255":1,"256":1,"257":1,"258":1,"259":1,"260":1,"261":1,"262":1,"263":1,"264":1,"265":1,"266":1,"267":5,"268":5,"269":5,"270":5,"271":5,"272":5,"273":5,"274":5,"275":5,"276":5,"277":5,"278":5,"279":5,"280":5,"281":5,"282":5,"283":5,"284":5,"285":5,"286":5,"287":1,"288":1,"289":3,"290":3,"291":3,"292":3},"branchMap":{"0":{"type":"branch","line":35,"loc":{"start":{"line":35,"column":0},"end":{"line":61,"column":1}},"locations":[{"start":{"line":35,"column":0},"end":{"line":61,"column":1}}]},"1":{"type":"branch","line":51,"loc":{"start":{"line":51,"column":28},"end":{"line":58,"column":3}},"locations":[{"start":{"line":51,"column":28},"end":{"line":58,"column":3}}]},"2":{"type":"branch","line":53,"loc":{"start":{"line":53,"column":15},"end":{"line":57,"column":5}},"locations":[{"start":{"line":53,"column":15},"end":{"line":57,"column":5}}]},"3":{"type":"branch","line":54,"loc":{"start":{"line":54,"column":29},"end":{"line":54,"column":37}},"locations":[{"start":{"line":54,"column":29},"end":{"line":54,"column":37}}]},"4":{"type":"branch","line":55,"loc":{"start":{"line":55,"column":40},"end":{"line":55,"column":48}},"locations":[{"start":{"line":55,"column":40},"end":{"line":55,"column":48}}]},"5":{"type":"branch","line":58,"loc":{"start":{"line":58,"column":2},"end":{"line":61,"column":1}},"locations":[{"start":{"line":58,"column":2},"end":{"line":61,"column":1}}]},"6":{"type":"branch","line":63,"loc":{"start":{"line":63,"column":0},"end":{"line":91,"column":1}},"locations":[{"start":{"line":63,"column":0},"end":{"line":91,"column":1}}]},"7":{"type":"branch","line":79,"loc":{"start":{"line":79,"column":23},"end":{"line":88,"column":3}},"locations":[{"start":{"line":79,"column":23},"end":{"line":88,"column":3}}]},"8":{"type":"branch","line":81,"loc":{"start":{"line":81,"column":15},"end":{"line":87,"column":5}},"locations":[{"start":{"line":81,"column":15},"end":{"line":87,"column":5}}]},"9":{"type":"branch","line":82,"loc":{"start":{"line":82,"column":27},"end":{"line":82,"column":35}},"locations":[{"start":{"line":82,"column":27},"end":{"line":82,"column":35}}]},"10":{"type":"branch","line":83,"loc":{"start":{"line":83,"column":19},"end":{"line":85,"column":7}},"locations":[{"start":{"line":83,"column":19},"end":{"line":85,"column":7}}]},"11":{"type":"branch","line":88,"loc":{"start":{"line":88,"column":2},"end":{"line":91,"column":1}},"locations":[{"start":{"line":88,"column":2},"end":{"line":91,"column":1}}]},"12":{"type":"branch","line":93,"loc":{"start":{"line":93,"column":0},"end":{"line":131,"column":1}},"locations":[{"start":{"line":93,"column":0},"end":{"line":131,"column":1}}]},"13":{"type":"branch","line":98,"loc":{"start":{"line":98,"column":16},"end":{"line":100,"column":13}},"locations":[{"start":{"line":98,"column":16},"end":{"line":100,"column":13}}]},"14":{"type":"branch","line":100,"loc":{"start":{"line":100,"column":2},"end":{"line":102,"column":3}},"locations":[{"start":{"line":100,"column":2},"end":{"line":102,"column":3}}]},"15":{"type":"branch","line":100,"loc":{"start":{"line":100,"column":23},"end":{"line":102,"column":3}},"locations":[{"start":{"line":100,"column":23},"end":{"line":102,"column":3}}]},"16":{"type":"branch","line":113,"loc":{"start":{"line":113,"column":19},"end":{"line":116,"column":13}},"locations":[{"start":{"line":113,"column":19},"end":{"line":116,"column":13}}]},"17":{"type":"branch","line":116,"loc":{"start":{"line":116,"column":2},"end":{"line":128,"column":3}},"locations":[{"start":{"line":116,"column":2},"end":{"line":128,"column":3}}]},"18":{"type":"branch","line":116,"loc":{"start":{"line":116,"column":24},"end":{"line":119,"column":13}},"locations":[{"start":{"line":116,"column":24},"end":{"line":119,"column":13}}]},"19":{"type":"branch","line":119,"loc":{"start":{"line":119,"column":2},"end":{"line":128,"column":3}},"locations":[{"start":{"line":119,"column":2},"end":{"line":128,"column":3}}]},"20":{"type":"branch","line":119,"loc":{"start":{"line":119,"column":27},"end":{"line":122,"column":13}},"locations":[{"start":{"line":119,"column":27},"end":{"line":122,"column":13}}]},"21":{"type":"branch","line":122,"loc":{"start":{"line":122,"column":2},"end":{"line":128,"column":3}},"locations":[{"start":{"line":122,"column":2},"end":{"line":128,"column":3}}]},"22":{"type":"branch","line":122,"loc":{"start":{"line":122,"column":25},"end":{"line":125,"column":13}},"locations":[{"start":{"line":122,"column":25},"end":{"line":125,"column":13}}]},"23":{"type":"branch","line":125,"loc":{"start":{"line":125,"column":2},"end":{"line":128,"column":3}},"locations":[{"start":{"line":125,"column":2},"end":{"line":128,"column":3}}]},"24":{"type":"branch","line":125,"loc":{"start":{"line":125,"column":26},"end":{"line":128,"column":3}},"locations":[{"start":{"line":125,"column":26},"end":{"line":128,"column":3}}]},"25":{"type":"branch","line":133,"loc":{"start":{"line":133,"column":7},"end":{"line":153,"column":1}},"locations":[{"start":{"line":133,"column":7},"end":{"line":153,"column":1}}]},"26":{"type":"branch","line":134,"loc":{"start":{"line":134,"column":58},"end":{"line":134,"column":73}},"locations":[{"start":{"line":134,"column":58},"end":{"line":134,"column":73}}]},"27":{"type":"branch","line":143,"loc":{"start":{"line":143,"column":52},"end":{"line":143,"column":62}},"locations":[{"start":{"line":143,"column":52},"end":{"line":143,"column":62}}]},"28":{"type":"branch","line":144,"loc":{"start":{"line":144,"column":57},"end":{"line":144,"column":71}},"locations":[{"start":{"line":144,"column":57},"end":{"line":144,"column":71}}]},"29":{"type":"branch","line":145,"loc":{"start":{"line":145,"column":54},"end":{"line":145,"column":65}},"locations":[{"start":{"line":145,"column":54},"end":{"line":145,"column":65}}]},"30":{"type":"branch","line":146,"loc":{"start":{"line":146,"column":59},"end":{"line":146,"column":73}},"locations":[{"start":{"line":146,"column":59},"end":{"line":146,"column":73}}]},"31":{"type":"branch","line":148,"loc":{"start":{"line":148,"column":57},"end":{"line":148,"column":67}},"locations":[{"start":{"line":148,"column":57},"end":{"line":148,"column":67}}]},"32":{"type":"branch","line":149,"loc":{"start":{"line":149,"column":58},"end":{"line":149,"column":69}},"locations":[{"start":{"line":149,"column":58},"end":{"line":149,"column":69}}]},"33":{"type":"branch","line":150,"loc":{"start":{"line":150,"column":59},"end":{"line":150,"column":74}},"locations":[{"start":{"line":150,"column":59},"end":{"line":150,"column":74}}]},"34":{"type":"branch","line":151,"loc":{"start":{"line":151,"column":60},"end":{"line":151,"column":76}},"locations":[{"start":{"line":151,"column":60},"end":{"line":151,"column":76}}]},"35":{"type":"branch","line":155,"loc":{"start":{"line":155,"column":7},"end":{"line":157,"column":1}},"locations":[{"start":{"line":155,"column":7},"end":{"line":157,"column":1}}]},"36":{"type":"branch","line":156,"loc":{"start":{"line":156,"column":52},"end":{"line":156,"column":62}},"locations":[{"start":{"line":156,"column":52},"end":{"line":156,"column":62}}]},"37":{"type":"branch","line":159,"loc":{"start":{"line":159,"column":7},"end":{"line":161,"column":1}},"locations":[{"start":{"line":159,"column":7},"end":{"line":161,"column":1}}]},"38":{"type":"branch","line":160,"loc":{"start":{"line":160,"column":52},"end":{"line":160,"column":66}},"locations":[{"start":{"line":160,"column":52},"end":{"line":160,"column":66}}]},"39":{"type":"branch","line":163,"loc":{"start":{"line":163,"column":7},"end":{"line":220,"column":1}},"locations":[{"start":{"line":163,"column":7},"end":{"line":220,"column":1}}]},"40":{"type":"branch","line":164,"loc":{"start":{"line":164,"column":12},"end":{"line":164,"column":23}},"locations":[{"start":{"line":164,"column":12},"end":{"line":164,"column":23}}]},"41":{"type":"branch","line":164,"loc":{"start":{"line":164,"column":19},"end":{"line":167,"column":36}},"locations":[{"start":{"line":164,"column":19},"end":{"line":167,"column":36}}]},"42":{"type":"branch","line":167,"loc":{"start":{"line":167,"column":36},"end":{"line":169,"column":3}},"locations":[{"start":{"line":167,"column":36},"end":{"line":169,"column":3}}]},"43":{"type":"branch","line":169,"loc":{"start":{"line":169,"column":2},"end":{"line":186,"column":49}},"locations":[{"start":{"line":169,"column":2},"end":{"line":186,"column":49}}]},"44":{"type":"branch","line":186,"loc":{"start":{"line":186,"column":49},"end":{"line":192,"column":5}},"locations":[{"start":{"line":186,"column":49},"end":{"line":192,"column":5}}]},"45":{"type":"branch","line":188,"loc":{"start":{"line":188,"column":59},"end":{"line":191,"column":7}},"locations":[{"start":{"line":188,"column":59},"end":{"line":191,"column":7}}]},"46":{"type":"branch","line":192,"loc":{"start":{"line":192,"column":4},"end":{"line":194,"column":23}},"locations":[{"start":{"line":192,"column":4},"end":{"line":194,"column":23}}]},"47":{"type":"branch","line":194,"loc":{"start":{"line":194,"column":15},"end":{"line":194,"column":47}},"locations":[{"start":{"line":194,"column":15},"end":{"line":194,"column":47}}]},"48":{"type":"branch","line":194,"loc":{"start":{"line":194,"column":47},"end":{"line":211,"column":5}},"locations":[{"start":{"line":194,"column":47},"end":{"line":211,"column":5}}]},"49":{"type":"branch","line":199,"loc":{"start":{"line":199,"column":57},"end":{"line":205,"column":9}},"locations":[{"start":{"line":199,"column":57},"end":{"line":205,"column":9}}]},"50":{"type":"branch","line":201,"loc":{"start":{"line":201,"column":63},"end":{"line":204,"column":11}},"locations":[{"start":{"line":201,"column":63},"end":{"line":204,"column":11}}]},"51":{"type":"branch","line":211,"loc":{"start":{"line":211,"column":4},"end":{"line":213,"column":18}},"locations":[{"start":{"line":211,"column":4},"end":{"line":213,"column":18}}]},"52":{"type":"branch","line":213,"loc":{"start":{"line":213,"column":18},"end":{"line":215,"column":5}},"locations":[{"start":{"line":213,"column":18},"end":{"line":215,"column":5}}]},"53":{"type":"branch","line":215,"loc":{"start":{"line":215,"column":4},"end":{"line":217,"column":10}},"locations":[{"start":{"line":215,"column":4},"end":{"line":217,"column":10}}]},"54":{"type":"branch","line":217,"loc":{"start":{"line":217,"column":2},"end":{"line":219,"column":3}},"locations":[{"start":{"line":217,"column":2},"end":{"line":219,"column":3}}]},"55":{"type":"branch","line":188,"loc":{"start":{"line":188,"column":31},"end":{"line":188,"column":56}},"locations":[{"start":{"line":188,"column":31},"end":{"line":188,"column":56}}]},"56":{"type":"branch","line":201,"loc":{"start":{"line":201,"column":35},"end":{"line":201,"column":60}},"locations":[{"start":{"line":201,"column":35},"end":{"line":201,"column":60}}]},"57":{"type":"branch","line":222,"loc":{"start":{"line":222,"column":7},"end":{"line":237,"column":1}},"locations":[{"start":{"line":222,"column":7},"end":{"line":237,"column":1}}]},"58":{"type":"branch","line":223,"loc":{"start":{"line":223,"column":46},"end":{"line":223,"column":59}},"locations":[{"start":{"line":223,"column":46},"end":{"line":223,"column":59}}]},"59":{"type":"branch","line":223,"loc":{"start":{"line":223,"column":53},"end":{"line":237,"column":1}},"locations":[{"start":{"line":223,"column":53},"end":{"line":237,"column":1}}]},"60":{"type":"branch","line":225,"loc":{"start":{"line":225,"column":25},"end":{"line":236,"column":3}},"locations":[{"start":{"line":225,"column":25},"end":{"line":236,"column":3}}]},"61":{"type":"branch","line":226,"loc":{"start":{"line":226,"column":37},"end":{"line":234,"column":5}},"locations":[{"start":{"line":226,"column":37},"end":{"line":234,"column":5}}]},"62":{"type":"branch","line":227,"loc":{"start":{"line":227,"column":33},"end":{"line":232,"column":7}},"locations":[{"start":{"line":227,"column":33},"end":{"line":232,"column":7}}]},"63":{"type":"branch","line":232,"loc":{"start":{"line":232,"column":6},"end":{"line":234,"column":5}},"locations":[{"start":{"line":232,"column":6},"end":{"line":234,"column":5}}]},"64":{"type":"branch","line":234,"loc":{"start":{"line":234,"column":4},"end":{"line":235,"column":29}},"locations":[{"start":{"line":234,"column":4},"end":{"line":235,"column":29}}]},"65":{"type":"branch","line":267,"loc":{"start":{"line":267,"column":7},"end":{"line":287,"column":1}},"locations":[{"start":{"line":267,"column":7},"end":{"line":287,"column":1}}]},"66":{"type":"branch","line":269,"loc":{"start":{"line":269,"column":55},"end":{"line":269,"column":91}},"locations":[{"start":{"line":269,"column":55},"end":{"line":269,"column":91}}]},"67":{"type":"branch","line":270,"loc":{"start":{"line":270,"column":40},"end":{"line":270,"column":71}},"locations":[{"start":{"line":270,"column":40},"end":{"line":270,"column":71}}]},"68":{"type":"branch","line":283,"loc":{"start":{"line":283,"column":24},"end":{"line":283,"column":44}},"locations":[{"start":{"line":283,"column":24},"end":{"line":283,"column":44}}]},"69":{"type":"branch","line":284,"loc":{"start":{"line":284,"column":24},"end":{"line":284,"column":43}},"locations":[{"start":{"line":284,"column":24},"end":{"line":284,"column":43}}]},"70":{"type":"branch","line":289,"loc":{"start":{"line":289,"column":7},"end":{"line":293,"column":1}},"locations":[{"start":{"line":289,"column":7},"end":{"line":293,"column":1}}]}},"b":{"0":[31],"1":[293],"2":[26],"3":[0],"4":[0],"5":[5],"6":[31],"7":[219],"8":[26],"9":[10],"10":[16],"11":[5],"12":[31],"13":[2],"14":[29],"15":[11],"16":[3],"17":[28],"18":[2],"19":[26],"20":[3],"21":[23],"22":[1],"23":[22],"24":[4],"25":[31],"26":[0],"27":[0],"28":[0],"29":[0],"30":[0],"31":[0],"32":[0],"33":[0],"34":[0],"35":[1],"36":[0],"37":[1],"38":[0],"39":[13],"40":[3],"41":[10],"42":[2],"43":[8],"44":[15],"45":[9],"46":[7],"47":[1],"48":[1],"49":[2],"50":[1],"51":[7],"52":[5],"53":[2],"54":[1],"55":[164],"56":[21],"57":[11],"58":[1],"59":[10],"60":[15],"61":[12],"62":[3],"63":[9],"64":[3],"65":[5],"66":[0],"67":[0],"68":[2],"69":[2],"70":[3]},"fnMap":{"0":{"name":"detectBrowser","decl":{"start":{"line":35,"column":0},"end":{"line":61,"column":1}},"loc":{"start":{"line":35,"column":0},"end":{"line":61,"column":1}},"line":35},"1":{"name":"detectOS","decl":{"start":{"line":63,"column":0},"end":{"line":91,"column":1}},"loc":{"start":{"line":63,"column":0},"end":{"line":91,"column":1}},"line":63},"2":{"name":"detectDevice","decl":{"start":{"line":93,"column":0},"end":{"line":131,"column":1}},"loc":{"start":{"line":93,"column":0},"end":{"line":131,"column":1}},"line":93},"3":{"name":"getEnvInfo","decl":{"start":{"line":133,"column":7},"end":{"line":153,"column":1}},"loc":{"start":{"line":133,"column":7},"end":{"line":153,"column":1}},"line":133},"4":{"name":"getPageUrl","decl":{"start":{"line":155,"column":7},"end":{"line":157,"column":1}},"loc":{"start":{"line":155,"column":7},"end":{"line":157,"column":1}},"line":155},"5":{"name":"getReferrer","decl":{"start":{"line":159,"column":7},"end":{"line":161,"column":1}},"loc":{"start":{"line":159,"column":7},"end":{"line":161,"column":1}},"line":159},"6":{"name":"sanitizeUrl","decl":{"start":{"line":163,"column":7},"end":{"line":220,"column":1}},"loc":{"start":{"line":163,"column":7},"end":{"line":220,"column":1}},"line":163},"7":{"name":"shouldIgnoreUrl","decl":{"start":{"line":222,"column":7},"end":{"line":237,"column":1}},"loc":{"start":{"line":222,"column":7},"end":{"line":237,"column":1}},"line":222},"8":{"name":"getContexts","decl":{"start":{"line":267,"column":7},"end":{"line":287,"column":1}},"loc":{"start":{"line":267,"column":7},"end":{"line":287,"column":1}},"line":267},"9":{"name":"getContextId","decl":{"start":{"line":289,"column":7},"end":{"line":293,"column":1}},"loc":{"start":{"line":289,"column":7},"end":{"line":293,"column":1}},"line":289}},"f":{"0":31,"1":31,"2":31,"3":31,"4":1,"5":1,"6":13,"7":11,"8":5,"9":3}} +,"/Users/weidingjian/Desktop/work/ai/light-sentry-sdk/src/utils/field-encoder.ts": {"path":"/Users/weidingjian/Desktop/work/ai/light-sentry-sdk/src/utils/field-encoder.ts","all":false,"statementMap":{"0":{"start":{"line":1,"column":0},"end":{"line":1,"column":3}},"1":{"start":{"line":2,"column":0},"end":{"line":2,"column":10}},"2":{"start":{"line":3,"column":0},"end":{"line":3,"column":3}},"3":{"start":{"line":4,"column":0},"end":{"line":4,"column":30}},"4":{"start":{"line":5,"column":0},"end":{"line":5,"column":3}},"5":{"start":{"line":6,"column":0},"end":{"line":6,"column":62}},"6":{"start":{"line":7,"column":0},"end":{"line":7,"column":41}},"7":{"start":{"line":8,"column":0},"end":{"line":8,"column":3}},"8":{"start":{"line":9,"column":0},"end":{"line":9,"column":28}},"9":{"start":{"line":10,"column":0},"end":{"line":10,"column":22}},"10":{"start":{"line":11,"column":0},"end":{"line":11,"column":3}},"11":{"start":{"line":12,"column":0},"end":{"line":12,"column":0}},"12":{"start":{"line":13,"column":0},"end":{"line":13,"column":28}},"13":{"start":{"line":14,"column":0},"end":{"line":14,"column":57}},"14":{"start":{"line":15,"column":0},"end":{"line":15,"column":9}},"15":{"start":{"line":16,"column":0},"end":{"line":16,"column":18}},"16":{"start":{"line":17,"column":0},"end":{"line":17,"column":18}},"17":{"start":{"line":18,"column":0},"end":{"line":18,"column":25}},"18":{"start":{"line":19,"column":0},"end":{"line":19,"column":12}},"19":{"start":{"line":20,"column":0},"end":{"line":20,"column":13}},"20":{"start":{"line":21,"column":0},"end":{"line":21,"column":15}},"21":{"start":{"line":22,"column":0},"end":{"line":22,"column":16}},"22":{"start":{"line":23,"column":0},"end":{"line":23,"column":15}},"23":{"start":{"line":24,"column":0},"end":{"line":24,"column":19}},"24":{"start":{"line":25,"column":0},"end":{"line":25,"column":20}},"25":{"start":{"line":26,"column":0},"end":{"line":26,"column":20}},"26":{"start":{"line":27,"column":0},"end":{"line":27,"column":0}},"27":{"start":{"line":28,"column":0},"end":{"line":28,"column":7}},"28":{"start":{"line":29,"column":0},"end":{"line":29,"column":12}},"29":{"start":{"line":30,"column":0},"end":{"line":30,"column":0}},"30":{"start":{"line":31,"column":0},"end":{"line":31,"column":7}},"31":{"start":{"line":32,"column":0},"end":{"line":32,"column":13}},"32":{"start":{"line":33,"column":0},"end":{"line":33,"column":0}},"33":{"start":{"line":34,"column":0},"end":{"line":34,"column":7}},"34":{"start":{"line":35,"column":0},"end":{"line":35,"column":18}},"35":{"start":{"line":36,"column":0},"end":{"line":36,"column":0}},"36":{"start":{"line":37,"column":0},"end":{"line":37,"column":7}},"37":{"start":{"line":38,"column":0},"end":{"line":38,"column":17}},"38":{"start":{"line":39,"column":0},"end":{"line":39,"column":0}},"39":{"start":{"line":40,"column":0},"end":{"line":40,"column":8}},"40":{"start":{"line":41,"column":0},"end":{"line":41,"column":18}},"41":{"start":{"line":42,"column":0},"end":{"line":42,"column":0}},"42":{"start":{"line":43,"column":0},"end":{"line":43,"column":8}},"43":{"start":{"line":44,"column":0},"end":{"line":44,"column":20}},"44":{"start":{"line":45,"column":0},"end":{"line":45,"column":0}},"45":{"start":{"line":46,"column":0},"end":{"line":46,"column":16}},"46":{"start":{"line":47,"column":0},"end":{"line":47,"column":20}},"47":{"start":{"line":48,"column":0},"end":{"line":48,"column":16}},"48":{"start":{"line":49,"column":0},"end":{"line":49,"column":14}},"49":{"start":{"line":50,"column":0},"end":{"line":50,"column":0}},"50":{"start":{"line":51,"column":0},"end":{"line":51,"column":9}},"51":{"start":{"line":52,"column":0},"end":{"line":52,"column":14}},"52":{"start":{"line":53,"column":0},"end":{"line":53,"column":2}},"53":{"start":{"line":54,"column":0},"end":{"line":54,"column":0}},"54":{"start":{"line":55,"column":0},"end":{"line":55,"column":18}},"55":{"start":{"line":56,"column":0},"end":{"line":56,"column":75}},"56":{"start":{"line":57,"column":0},"end":{"line":57,"column":58}},"57":{"start":{"line":58,"column":0},"end":{"line":58,"column":2}},"58":{"start":{"line":59,"column":0},"end":{"line":59,"column":0}},"59":{"start":{"line":60,"column":0},"end":{"line":60,"column":3}},"60":{"start":{"line":61,"column":0},"end":{"line":61,"column":19}},"61":{"start":{"line":62,"column":0},"end":{"line":62,"column":23}},"62":{"start":{"line":63,"column":0},"end":{"line":63,"column":3}},"63":{"start":{"line":64,"column":0},"end":{"line":64,"column":85}},"64":{"start":{"line":65,"column":0},"end":{"line":65,"column":50}},"65":{"start":{"line":66,"column":0},"end":{"line":66,"column":0}},"66":{"start":{"line":67,"column":0},"end":{"line":67,"column":45}},"67":{"start":{"line":68,"column":0},"end":{"line":68,"column":51}},"68":{"start":{"line":69,"column":0},"end":{"line":69,"column":50}},"69":{"start":{"line":70,"column":0},"end":{"line":70,"column":29}},"70":{"start":{"line":71,"column":0},"end":{"line":71,"column":3}},"71":{"start":{"line":72,"column":0},"end":{"line":72,"column":16}},"72":{"start":{"line":73,"column":0},"end":{"line":73,"column":1}},"73":{"start":{"line":74,"column":0},"end":{"line":74,"column":0}},"74":{"start":{"line":75,"column":0},"end":{"line":75,"column":3}},"75":{"start":{"line":76,"column":0},"end":{"line":76,"column":17}},"76":{"start":{"line":77,"column":0},"end":{"line":77,"column":12}},"77":{"start":{"line":78,"column":0},"end":{"line":78,"column":3}},"78":{"start":{"line":79,"column":0},"end":{"line":79,"column":85}},"79":{"start":{"line":80,"column":0},"end":{"line":80,"column":50}},"80":{"start":{"line":81,"column":0},"end":{"line":81,"column":0}},"81":{"start":{"line":82,"column":0},"end":{"line":82,"column":45}},"82":{"start":{"line":83,"column":0},"end":{"line":83,"column":51}},"83":{"start":{"line":84,"column":0},"end":{"line":84,"column":49}},"84":{"start":{"line":85,"column":0},"end":{"line":85,"column":28}},"85":{"start":{"line":86,"column":0},"end":{"line":86,"column":3}},"86":{"start":{"line":87,"column":0},"end":{"line":87,"column":16}},"87":{"start":{"line":88,"column":0},"end":{"line":88,"column":1}}},"s":{"0":1,"1":1,"2":1,"3":1,"4":1,"5":1,"6":1,"7":1,"8":1,"9":1,"10":1,"11":1,"12":1,"13":1,"14":1,"15":1,"16":1,"17":1,"18":1,"19":1,"20":1,"21":1,"22":1,"23":1,"24":1,"25":1,"26":1,"27":1,"28":1,"29":1,"30":1,"31":1,"32":1,"33":1,"34":1,"35":1,"36":1,"37":1,"38":1,"39":1,"40":1,"41":1,"42":1,"43":1,"44":1,"45":1,"46":1,"47":1,"48":1,"49":1,"50":1,"51":1,"52":1,"53":1,"54":1,"55":1,"56":1,"57":1,"58":1,"59":1,"60":1,"61":1,"62":1,"63":1,"64":10,"65":6,"66":6,"67":10,"68":23,"69":23,"70":23,"71":6,"72":6,"73":1,"74":1,"75":1,"76":1,"77":1,"78":1,"79":9,"80":5,"81":5,"82":9,"83":18,"84":18,"85":18,"86":5,"87":5},"branchMap":{"0":{"type":"branch","line":57,"loc":{"start":{"line":57,"column":39},"end":{"line":57,"column":57}},"locations":[{"start":{"line":57,"column":39},"end":{"line":57,"column":57}}]},"1":{"type":"branch","line":64,"loc":{"start":{"line":64,"column":7},"end":{"line":73,"column":1}},"locations":[{"start":{"line":64,"column":7},"end":{"line":73,"column":1}}]},"2":{"type":"branch","line":65,"loc":{"start":{"line":65,"column":7},"end":{"line":65,"column":39}},"locations":[{"start":{"line":65,"column":7},"end":{"line":65,"column":39}}]},"3":{"type":"branch","line":65,"loc":{"start":{"line":65,"column":39},"end":{"line":65,"column":50}},"locations":[{"start":{"line":65,"column":39},"end":{"line":65,"column":50}}]},"4":{"type":"branch","line":65,"loc":{"start":{"line":65,"column":46},"end":{"line":68,"column":50}},"locations":[{"start":{"line":65,"column":46},"end":{"line":68,"column":50}}]},"5":{"type":"branch","line":68,"loc":{"start":{"line":68,"column":50},"end":{"line":71,"column":3}},"locations":[{"start":{"line":68,"column":50},"end":{"line":71,"column":3}}]},"6":{"type":"branch","line":69,"loc":{"start":{"line":69,"column":41},"end":{"line":69,"column":50}},"locations":[{"start":{"line":69,"column":41},"end":{"line":69,"column":50}}]},"7":{"type":"branch","line":71,"loc":{"start":{"line":71,"column":2},"end":{"line":73,"column":1}},"locations":[{"start":{"line":71,"column":2},"end":{"line":73,"column":1}}]},"8":{"type":"branch","line":79,"loc":{"start":{"line":79,"column":7},"end":{"line":88,"column":1}},"locations":[{"start":{"line":79,"column":7},"end":{"line":88,"column":1}}]},"9":{"type":"branch","line":80,"loc":{"start":{"line":80,"column":7},"end":{"line":80,"column":39}},"locations":[{"start":{"line":80,"column":7},"end":{"line":80,"column":39}}]},"10":{"type":"branch","line":80,"loc":{"start":{"line":80,"column":39},"end":{"line":80,"column":50}},"locations":[{"start":{"line":80,"column":39},"end":{"line":80,"column":50}}]},"11":{"type":"branch","line":80,"loc":{"start":{"line":80,"column":46},"end":{"line":83,"column":50}},"locations":[{"start":{"line":80,"column":46},"end":{"line":83,"column":50}}]},"12":{"type":"branch","line":83,"loc":{"start":{"line":83,"column":50},"end":{"line":86,"column":3}},"locations":[{"start":{"line":83,"column":50},"end":{"line":86,"column":3}}]},"13":{"type":"branch","line":84,"loc":{"start":{"line":84,"column":40},"end":{"line":84,"column":49}},"locations":[{"start":{"line":84,"column":40},"end":{"line":84,"column":49}}]},"14":{"type":"branch","line":86,"loc":{"start":{"line":86,"column":2},"end":{"line":88,"column":1}},"locations":[{"start":{"line":86,"column":2},"end":{"line":88,"column":1}}]}},"b":{"0":[42],"1":[10],"2":[8],"3":[4],"4":[6],"5":[23],"6":[2],"7":[6],"8":[9],"9":[7],"10":[4],"11":[5],"12":[18],"13":[2],"14":[5]},"fnMap":{"0":{"name":"encodeFields","decl":{"start":{"line":64,"column":7},"end":{"line":73,"column":1}},"loc":{"start":{"line":64,"column":7},"end":{"line":73,"column":1}},"line":64},"1":{"name":"decodeFields","decl":{"start":{"line":79,"column":7},"end":{"line":88,"column":1}},"loc":{"start":{"line":79,"column":7},"end":{"line":88,"column":1}},"line":79}},"f":{"0":10,"1":9}} +,"/Users/weidingjian/Desktop/work/ai/light-sentry-sdk/src/utils/hash.ts": {"path":"/Users/weidingjian/Desktop/work/ai/light-sentry-sdk/src/utils/hash.ts","all":false,"statementMap":{"0":{"start":{"line":1,"column":0},"end":{"line":1,"column":49}},"1":{"start":{"line":2,"column":0},"end":{"line":2,"column":18}},"2":{"start":{"line":3,"column":0},"end":{"line":3,"column":21}},"3":{"start":{"line":4,"column":0},"end":{"line":4,"column":13}},"4":{"start":{"line":5,"column":0},"end":{"line":5,"column":45}},"5":{"start":{"line":6,"column":0},"end":{"line":6,"column":3}},"6":{"start":{"line":7,"column":0},"end":{"line":7,"column":20}},"7":{"start":{"line":8,"column":0},"end":{"line":8,"column":1}},"8":{"start":{"line":9,"column":0},"end":{"line":9,"column":0}},"9":{"start":{"line":10,"column":0},"end":{"line":10,"column":42}},"10":{"start":{"line":11,"column":0},"end":{"line":11,"column":29}},"11":{"start":{"line":12,"column":0},"end":{"line":12,"column":23}},"12":{"start":{"line":13,"column":0},"end":{"line":13,"column":38}},"13":{"start":{"line":14,"column":0},"end":{"line":14,"column":1}},"14":{"start":{"line":15,"column":0},"end":{"line":15,"column":0}},"15":{"start":{"line":16,"column":0},"end":{"line":16,"column":129}},"16":{"start":{"line":17,"column":0},"end":{"line":17,"column":92}},"17":{"start":{"line":18,"column":0},"end":{"line":18,"column":94}},"18":{"start":{"line":19,"column":0},"end":{"line":19,"column":58}},"19":{"start":{"line":20,"column":0},"end":{"line":20,"column":1}}},"s":{"0":1,"1":19,"2":19,"3":19,"4":288,"5":288,"6":19,"7":19,"8":1,"9":1,"10":14,"11":14,"12":14,"13":14,"14":1,"15":1,"16":5,"17":5,"18":5,"19":5},"branchMap":{"0":{"type":"branch","line":1,"loc":{"start":{"line":1,"column":7},"end":{"line":8,"column":1}},"locations":[{"start":{"line":1,"column":7},"end":{"line":8,"column":1}}]},"1":{"type":"branch","line":4,"loc":{"start":{"line":4,"column":12},"end":{"line":6,"column":3}},"locations":[{"start":{"line":4,"column":12},"end":{"line":6,"column":3}}]},"2":{"type":"branch","line":10,"loc":{"start":{"line":10,"column":7},"end":{"line":14,"column":1}},"locations":[{"start":{"line":10,"column":7},"end":{"line":14,"column":1}}]},"3":{"type":"branch","line":16,"loc":{"start":{"line":16,"column":7},"end":{"line":20,"column":1}},"locations":[{"start":{"line":16,"column":7},"end":{"line":20,"column":1}}]},"4":{"type":"branch","line":17,"loc":{"start":{"line":17,"column":43},"end":{"line":17,"column":80}},"locations":[{"start":{"line":17,"column":43},"end":{"line":17,"column":80}}]},"5":{"type":"branch","line":17,"loc":{"start":{"line":17,"column":67},"end":{"line":17,"column":78}},"locations":[{"start":{"line":17,"column":67},"end":{"line":17,"column":78}}]}},"b":{"0":[19],"1":[288],"2":[14],"3":[5],"4":[5],"5":[0]},"fnMap":{"0":{"name":"hashString","decl":{"start":{"line":1,"column":7},"end":{"line":8,"column":1}},"loc":{"start":{"line":1,"column":7},"end":{"line":8,"column":1}},"line":1},"1":{"name":"md5","decl":{"start":{"line":10,"column":7},"end":{"line":14,"column":1}},"loc":{"start":{"line":10,"column":7},"end":{"line":14,"column":1}},"line":10},"2":{"name":"computeFingerprint","decl":{"start":{"line":16,"column":7},"end":{"line":20,"column":1}},"loc":{"start":{"line":16,"column":7},"end":{"line":20,"column":1}},"line":16}},"f":{"0":19,"1":14,"2":5}} +,"/Users/weidingjian/Desktop/work/ai/light-sentry-sdk/src/utils/helper.ts": {"path":"/Users/weidingjian/Desktop/work/ai/light-sentry-sdk/src/utils/helper.ts","all":false,"statementMap":{"0":{"start":{"line":1,"column":0},"end":{"line":1,"column":43}},"1":{"start":{"line":2,"column":0},"end":{"line":2,"column":67}},"2":{"start":{"line":3,"column":0},"end":{"line":3,"column":51}},"3":{"start":{"line":4,"column":0},"end":{"line":4,"column":5}},"4":{"start":{"line":5,"column":0},"end":{"line":5,"column":1}},"5":{"start":{"line":6,"column":0},"end":{"line":6,"column":0}},"6":{"start":{"line":7,"column":0},"end":{"line":7,"column":31}},"7":{"start":{"line":8,"column":0},"end":{"line":8,"column":20}},"8":{"start":{"line":9,"column":0},"end":{"line":9,"column":1}},"9":{"start":{"line":10,"column":0},"end":{"line":10,"column":0}},"10":{"start":{"line":11,"column":0},"end":{"line":11,"column":32}},"11":{"start":{"line":12,"column":0},"end":{"line":12,"column":59}},"12":{"start":{"line":13,"column":0},"end":{"line":13,"column":49}},"13":{"start":{"line":14,"column":0},"end":{"line":14,"column":3}},"14":{"start":{"line":15,"column":0},"end":{"line":15,"column":27}},"15":{"start":{"line":16,"column":0},"end":{"line":16,"column":1}},"16":{"start":{"line":17,"column":0},"end":{"line":17,"column":0}},"17":{"start":{"line":18,"column":0},"end":{"line":18,"column":80}},"18":{"start":{"line":19,"column":0},"end":{"line":19,"column":34}},"19":{"start":{"line":20,"column":0},"end":{"line":20,"column":1}},"20":{"start":{"line":21,"column":0},"end":{"line":21,"column":0}},"21":{"start":{"line":22,"column":0},"end":{"line":22,"column":59}},"22":{"start":{"line":23,"column":0},"end":{"line":23,"column":35}},"23":{"start":{"line":24,"column":0},"end":{"line":24,"column":1}},"24":{"start":{"line":25,"column":0},"end":{"line":25,"column":0}},"25":{"start":{"line":26,"column":0},"end":{"line":26,"column":76}},"26":{"start":{"line":27,"column":0},"end":{"line":27,"column":78}},"27":{"start":{"line":28,"column":0},"end":{"line":28,"column":1}},"28":{"start":{"line":29,"column":0},"end":{"line":29,"column":0}},"29":{"start":{"line":30,"column":0},"end":{"line":30,"column":61}},"30":{"start":{"line":31,"column":0},"end":{"line":31,"column":7}},"31":{"start":{"line":32,"column":0},"end":{"line":32,"column":24}},"32":{"start":{"line":33,"column":0},"end":{"line":33,"column":56}},"33":{"start":{"line":34,"column":0},"end":{"line":34,"column":11}},"34":{"start":{"line":35,"column":0},"end":{"line":35,"column":24}},"35":{"start":{"line":36,"column":0},"end":{"line":36,"column":3}},"36":{"start":{"line":37,"column":0},"end":{"line":37,"column":1}},"37":{"start":{"line":38,"column":0},"end":{"line":38,"column":0}},"38":{"start":{"line":39,"column":0},"end":{"line":39,"column":63}},"39":{"start":{"line":40,"column":0},"end":{"line":40,"column":39}},"40":{"start":{"line":41,"column":0},"end":{"line":41,"column":38}},"41":{"start":{"line":42,"column":0},"end":{"line":42,"column":1}},"42":{"start":{"line":43,"column":0},"end":{"line":43,"column":0}},"43":{"start":{"line":44,"column":0},"end":{"line":44,"column":86}},"44":{"start":{"line":45,"column":0},"end":{"line":45,"column":55}},"45":{"start":{"line":46,"column":0},"end":{"line":46,"column":35}},"46":{"start":{"line":47,"column":0},"end":{"line":47,"column":38}},"47":{"start":{"line":48,"column":0},"end":{"line":48,"column":37}},"48":{"start":{"line":49,"column":0},"end":{"line":49,"column":5}},"49":{"start":{"line":50,"column":0},"end":{"line":50,"column":31}},"50":{"start":{"line":51,"column":0},"end":{"line":51,"column":5}},"51":{"start":{"line":52,"column":0},"end":{"line":52,"column":1}}},"s":{"0":1,"1":3,"2":96,"3":3,"4":3,"5":1,"6":1,"7":293,"8":293,"9":1,"10":1,"11":190,"12":190,"13":190,"14":0,"15":0,"16":1,"17":1,"18":9,"19":9,"20":1,"21":1,"22":8,"23":8,"24":1,"25":1,"26":38,"27":38,"28":1,"29":1,"30":7,"31":7,"32":7,"33":7,"34":1,"35":1,"36":7,"37":1,"38":1,"39":5,"40":1,"41":1,"42":1,"43":1,"44":15,"45":13,"46":18,"47":11,"48":11,"49":7,"50":13,"51":13},"branchMap":{"0":{"type":"branch","line":1,"loc":{"start":{"line":1,"column":7},"end":{"line":5,"column":1}},"locations":[{"start":{"line":1,"column":7},"end":{"line":5,"column":1}}]},"1":{"type":"branch","line":2,"loc":{"start":{"line":2,"column":60},"end":{"line":4,"column":3}},"locations":[{"start":{"line":2,"column":60},"end":{"line":4,"column":3}}]},"2":{"type":"branch","line":7,"loc":{"start":{"line":7,"column":7},"end":{"line":9,"column":1}},"locations":[{"start":{"line":7,"column":7},"end":{"line":9,"column":1}}]},"3":{"type":"branch","line":11,"loc":{"start":{"line":11,"column":7},"end":{"line":16,"column":1}},"locations":[{"start":{"line":11,"column":7},"end":{"line":16,"column":1}}]},"4":{"type":"branch","line":14,"loc":{"start":{"line":14,"column":2},"end":{"line":16,"column":1}},"locations":[{"start":{"line":14,"column":2},"end":{"line":16,"column":1}}]},"5":{"type":"branch","line":18,"loc":{"start":{"line":18,"column":7},"end":{"line":20,"column":1}},"locations":[{"start":{"line":18,"column":7},"end":{"line":20,"column":1}}]},"6":{"type":"branch","line":22,"loc":{"start":{"line":22,"column":7},"end":{"line":24,"column":1}},"locations":[{"start":{"line":22,"column":7},"end":{"line":24,"column":1}}]},"7":{"type":"branch","line":26,"loc":{"start":{"line":26,"column":7},"end":{"line":28,"column":1}},"locations":[{"start":{"line":26,"column":7},"end":{"line":28,"column":1}}]},"8":{"type":"branch","line":27,"loc":{"start":{"line":27,"column":19},"end":{"line":27,"column":56}},"locations":[{"start":{"line":27,"column":19},"end":{"line":27,"column":56}}]},"9":{"type":"branch","line":27,"loc":{"start":{"line":27,"column":44},"end":{"line":27,"column":78}},"locations":[{"start":{"line":27,"column":44},"end":{"line":27,"column":78}}]},"10":{"type":"branch","line":30,"loc":{"start":{"line":30,"column":7},"end":{"line":37,"column":1}},"locations":[{"start":{"line":30,"column":7},"end":{"line":37,"column":1}}]},"11":{"type":"branch","line":33,"loc":{"start":{"line":33,"column":22},"end":{"line":33,"column":49}},"locations":[{"start":{"line":33,"column":22},"end":{"line":33,"column":49}}]},"12":{"type":"branch","line":33,"loc":{"start":{"line":33,"column":34},"end":{"line":33,"column":56}},"locations":[{"start":{"line":33,"column":34},"end":{"line":33,"column":56}}]},"13":{"type":"branch","line":34,"loc":{"start":{"line":34,"column":2},"end":{"line":36,"column":3}},"locations":[{"start":{"line":34,"column":2},"end":{"line":36,"column":3}}]},"14":{"type":"branch","line":39,"loc":{"start":{"line":39,"column":7},"end":{"line":42,"column":1}},"locations":[{"start":{"line":39,"column":7},"end":{"line":42,"column":1}}]},"15":{"type":"branch","line":40,"loc":{"start":{"line":40,"column":28},"end":{"line":40,"column":39}},"locations":[{"start":{"line":40,"column":28},"end":{"line":40,"column":39}}]},"16":{"type":"branch","line":40,"loc":{"start":{"line":40,"column":35},"end":{"line":42,"column":1}},"locations":[{"start":{"line":40,"column":35},"end":{"line":42,"column":1}}]},"17":{"type":"branch","line":44,"loc":{"start":{"line":44,"column":7},"end":{"line":52,"column":1}},"locations":[{"start":{"line":44,"column":7},"end":{"line":52,"column":1}}]},"18":{"type":"branch","line":45,"loc":{"start":{"line":45,"column":7},"end":{"line":45,"column":42}},"locations":[{"start":{"line":45,"column":7},"end":{"line":45,"column":42}}]},"19":{"type":"branch","line":45,"loc":{"start":{"line":45,"column":42},"end":{"line":45,"column":55}},"locations":[{"start":{"line":45,"column":42},"end":{"line":45,"column":55}}]},"20":{"type":"branch","line":45,"loc":{"start":{"line":45,"column":49},"end":{"line":52,"column":1}},"locations":[{"start":{"line":45,"column":49},"end":{"line":52,"column":1}}]},"21":{"type":"branch","line":46,"loc":{"start":{"line":46,"column":23},"end":{"line":51,"column":3}},"locations":[{"start":{"line":46,"column":23},"end":{"line":51,"column":3}}]},"22":{"type":"branch","line":47,"loc":{"start":{"line":47,"column":37},"end":{"line":49,"column":5}},"locations":[{"start":{"line":47,"column":37},"end":{"line":49,"column":5}}]},"23":{"type":"branch","line":49,"loc":{"start":{"line":49,"column":4},"end":{"line":50,"column":31}},"locations":[{"start":{"line":49,"column":4},"end":{"line":50,"column":31}}]}},"b":{"0":[3],"1":[96],"2":[293],"3":[190],"4":[0],"5":[9],"6":[8],"7":[38],"8":[37],"9":[31],"10":[7],"11":[1],"12":[5],"13":[1],"14":[5],"15":[4],"16":[1],"17":[15],"18":[14],"19":[2],"20":[13],"21":[18],"22":[11],"23":[7]},"fnMap":{"0":{"name":"generateEventId","decl":{"start":{"line":1,"column":7},"end":{"line":5,"column":1}},"loc":{"start":{"line":1,"column":7},"end":{"line":5,"column":1}},"line":1},"1":{"name":"now","decl":{"start":{"line":7,"column":7},"end":{"line":9,"column":1}},"loc":{"start":{"line":7,"column":7},"end":{"line":9,"column":1}},"line":7},"2":{"name":"uuid","decl":{"start":{"line":11,"column":7},"end":{"line":16,"column":1}},"loc":{"start":{"line":11,"column":7},"end":{"line":16,"column":1}},"line":11},"3":{"name":"isFunction","decl":{"start":{"line":18,"column":7},"end":{"line":20,"column":1}},"loc":{"start":{"line":18,"column":7},"end":{"line":20,"column":1}},"line":18},"4":{"name":"isString","decl":{"start":{"line":22,"column":7},"end":{"line":24,"column":1}},"loc":{"start":{"line":22,"column":7},"end":{"line":24,"column":1}},"line":22},"5":{"name":"isObject","decl":{"start":{"line":26,"column":7},"end":{"line":28,"column":1}},"loc":{"start":{"line":26,"column":7},"end":{"line":28,"column":1}},"line":26},"6":{"name":"safeGet","decl":{"start":{"line":30,"column":7},"end":{"line":37,"column":1}},"loc":{"start":{"line":30,"column":7},"end":{"line":37,"column":1}},"line":30},"7":{"name":"truncate","decl":{"start":{"line":39,"column":7},"end":{"line":42,"column":1}},"loc":{"start":{"line":39,"column":7},"end":{"line":42,"column":1}},"line":39},"8":{"name":"matchPatterns","decl":{"start":{"line":44,"column":7},"end":{"line":52,"column":1}},"loc":{"start":{"line":44,"column":7},"end":{"line":52,"column":1}},"line":44}},"f":{"0":3,"1":293,"2":190,"3":9,"4":8,"5":38,"6":7,"7":5,"8":15}} +,"/Users/weidingjian/Desktop/work/ai/light-sentry-sdk/src/utils/identity.ts": {"path":"/Users/weidingjian/Desktop/work/ai/light-sentry-sdk/src/utils/identity.ts","all":false,"statementMap":{"0":{"start":{"line":1,"column":0},"end":{"line":1,"column":32}},"1":{"start":{"line":2,"column":0},"end":{"line":2,"column":0}},"2":{"start":{"line":3,"column":0},"end":{"line":3,"column":44}},"3":{"start":{"line":4,"column":0},"end":{"line":4,"column":0}},"4":{"start":{"line":5,"column":0},"end":{"line":5,"column":3}},"5":{"start":{"line":6,"column":0},"end":{"line":6,"column":11}},"6":{"start":{"line":7,"column":0},"end":{"line":7,"column":38}},"7":{"start":{"line":8,"column":0},"end":{"line":8,"column":3}},"8":{"start":{"line":9,"column":0},"end":{"line":9,"column":49}},"9":{"start":{"line":10,"column":0},"end":{"line":10,"column":12}},"10":{"start":{"line":11,"column":0},"end":{"line":11,"column":44}},"11":{"start":{"line":12,"column":0},"end":{"line":12,"column":16}},"12":{"start":{"line":13,"column":0},"end":{"line":13,"column":3}},"13":{"start":{"line":14,"column":0},"end":{"line":14,"column":0}},"14":{"start":{"line":15,"column":0},"end":{"line":15,"column":7}},"15":{"start":{"line":16,"column":0},"end":{"line":16,"column":61}},"16":{"start":{"line":17,"column":0},"end":{"line":17,"column":0}},"17":{"start":{"line":18,"column":0},"end":{"line":18,"column":23}},"18":{"start":{"line":19,"column":0},"end":{"line":19,"column":27}},"19":{"start":{"line":20,"column":0},"end":{"line":20,"column":58}},"20":{"start":{"line":21,"column":0},"end":{"line":21,"column":5}},"21":{"start":{"line":22,"column":0},"end":{"line":22,"column":0}},"22":{"start":{"line":23,"column":0},"end":{"line":23,"column":23}},"23":{"start":{"line":24,"column":0},"end":{"line":24,"column":11}},"24":{"start":{"line":25,"column":0},"end":{"line":25,"column":36}},"25":{"start":{"line":26,"column":0},"end":{"line":26,"column":16}},"26":{"start":{"line":27,"column":0},"end":{"line":27,"column":3}},"27":{"start":{"line":28,"column":0},"end":{"line":28,"column":1}},"28":{"start":{"line":29,"column":0},"end":{"line":29,"column":0}},"29":{"start":{"line":30,"column":0},"end":{"line":30,"column":3}},"30":{"start":{"line":31,"column":0},"end":{"line":31,"column":11}},"31":{"start":{"line":32,"column":0},"end":{"line":32,"column":14}},"32":{"start":{"line":33,"column":0},"end":{"line":33,"column":3}},"33":{"start":{"line":34,"column":0},"end":{"line":34,"column":53}},"34":{"start":{"line":35,"column":0},"end":{"line":35,"column":44}},"35":{"start":{"line":36,"column":0},"end":{"line":36,"column":17}},"36":{"start":{"line":37,"column":0},"end":{"line":37,"column":3}},"37":{"start":{"line":38,"column":0},"end":{"line":38,"column":0}},"38":{"start":{"line":39,"column":0},"end":{"line":39,"column":7}},"39":{"start":{"line":40,"column":0},"end":{"line":40,"column":47}},"40":{"start":{"line":41,"column":0},"end":{"line":41,"column":16}},"41":{"start":{"line":42,"column":0},"end":{"line":42,"column":11}},"42":{"start":{"line":43,"column":0},"end":{"line":43,"column":17}},"43":{"start":{"line":44,"column":0},"end":{"line":44,"column":3}},"44":{"start":{"line":45,"column":0},"end":{"line":45,"column":1}},"45":{"start":{"line":46,"column":0},"end":{"line":46,"column":0}},"46":{"start":{"line":47,"column":0},"end":{"line":47,"column":3}},"47":{"start":{"line":48,"column":0},"end":{"line":48,"column":11}},"48":{"start":{"line":49,"column":0},"end":{"line":49,"column":13}},"49":{"start":{"line":50,"column":0},"end":{"line":50,"column":3}},"50":{"start":{"line":51,"column":0},"end":{"line":51,"column":45}},"51":{"start":{"line":52,"column":0},"end":{"line":52,"column":44}},"52":{"start":{"line":53,"column":0},"end":{"line":53,"column":17}},"53":{"start":{"line":54,"column":0},"end":{"line":54,"column":3}},"54":{"start":{"line":55,"column":0},"end":{"line":55,"column":0}},"55":{"start":{"line":56,"column":0},"end":{"line":56,"column":7}},"56":{"start":{"line":57,"column":0},"end":{"line":57,"column":46}},"57":{"start":{"line":58,"column":0},"end":{"line":58,"column":16}},"58":{"start":{"line":59,"column":0},"end":{"line":59,"column":11}},"59":{"start":{"line":60,"column":0},"end":{"line":60,"column":17}},"60":{"start":{"line":61,"column":0},"end":{"line":61,"column":3}},"61":{"start":{"line":62,"column":0},"end":{"line":62,"column":1}},"62":{"start":{"line":63,"column":0},"end":{"line":63,"column":0}},"63":{"start":{"line":64,"column":0},"end":{"line":64,"column":3}},"64":{"start":{"line":65,"column":0},"end":{"line":65,"column":16}},"65":{"start":{"line":66,"column":0},"end":{"line":66,"column":3}},"66":{"start":{"line":67,"column":0},"end":{"line":67,"column":96}},"67":{"start":{"line":68,"column":0},"end":{"line":68,"column":27}},"68":{"start":{"line":69,"column":0},"end":{"line":69,"column":46}},"69":{"start":{"line":70,"column":0},"end":{"line":70,"column":1}}},"s":{"0":1,"1":1,"2":1,"3":1,"4":1,"5":1,"6":1,"7":1,"8":1,"9":20,"10":20,"11":1,"12":1,"13":19,"14":19,"15":19,"16":19,"17":20,"18":8,"19":8,"20":8,"21":18,"22":18,"23":20,"24":1,"25":1,"26":1,"27":20,"28":1,"29":1,"30":1,"31":1,"32":1,"33":1,"34":6,"35":1,"36":1,"37":5,"38":5,"39":5,"40":5,"41":6,"42":1,"43":1,"44":6,"45":1,"46":1,"47":1,"48":1,"49":1,"50":1,"51":5,"52":1,"53":1,"54":4,"55":4,"56":4,"57":4,"58":5,"59":1,"60":1,"61":5,"62":1,"63":1,"64":1,"65":1,"66":1,"67":16,"68":16,"69":16},"branchMap":{"0":{"type":"branch","line":9,"loc":{"start":{"line":9,"column":7},"end":{"line":28,"column":1}},"locations":[{"start":{"line":9,"column":7},"end":{"line":28,"column":1}}]},"1":{"type":"branch","line":11,"loc":{"start":{"line":11,"column":43},"end":{"line":13,"column":3}},"locations":[{"start":{"line":11,"column":43},"end":{"line":13,"column":3}}]},"2":{"type":"branch","line":13,"loc":{"start":{"line":13,"column":2},"end":{"line":18,"column":22}},"locations":[{"start":{"line":13,"column":2},"end":{"line":18,"column":22}}]},"3":{"type":"branch","line":18,"loc":{"start":{"line":18,"column":22},"end":{"line":21,"column":5}},"locations":[{"start":{"line":18,"column":22},"end":{"line":21,"column":5}}]},"4":{"type":"branch","line":21,"loc":{"start":{"line":21,"column":4},"end":{"line":24,"column":10}},"locations":[{"start":{"line":21,"column":4},"end":{"line":24,"column":10}}]},"5":{"type":"branch","line":24,"loc":{"start":{"line":24,"column":2},"end":{"line":27,"column":3}},"locations":[{"start":{"line":24,"column":2},"end":{"line":27,"column":3}}]},"6":{"type":"branch","line":34,"loc":{"start":{"line":34,"column":7},"end":{"line":45,"column":1}},"locations":[{"start":{"line":34,"column":7},"end":{"line":45,"column":1}}]},"7":{"type":"branch","line":35,"loc":{"start":{"line":35,"column":43},"end":{"line":37,"column":3}},"locations":[{"start":{"line":35,"column":43},"end":{"line":37,"column":3}}]},"8":{"type":"branch","line":37,"loc":{"start":{"line":37,"column":2},"end":{"line":42,"column":10}},"locations":[{"start":{"line":37,"column":2},"end":{"line":42,"column":10}}]},"9":{"type":"branch","line":42,"loc":{"start":{"line":42,"column":2},"end":{"line":44,"column":3}},"locations":[{"start":{"line":42,"column":2},"end":{"line":44,"column":3}}]},"10":{"type":"branch","line":51,"loc":{"start":{"line":51,"column":7},"end":{"line":62,"column":1}},"locations":[{"start":{"line":51,"column":7},"end":{"line":62,"column":1}}]},"11":{"type":"branch","line":52,"loc":{"start":{"line":52,"column":43},"end":{"line":54,"column":3}},"locations":[{"start":{"line":52,"column":43},"end":{"line":54,"column":3}}]},"12":{"type":"branch","line":54,"loc":{"start":{"line":54,"column":2},"end":{"line":59,"column":10}},"locations":[{"start":{"line":54,"column":2},"end":{"line":59,"column":10}}]},"13":{"type":"branch","line":59,"loc":{"start":{"line":59,"column":2},"end":{"line":61,"column":3}},"locations":[{"start":{"line":59,"column":2},"end":{"line":61,"column":3}}]},"14":{"type":"branch","line":67,"loc":{"start":{"line":67,"column":7},"end":{"line":70,"column":1}},"locations":[{"start":{"line":67,"column":7},"end":{"line":70,"column":1}}]}},"b":{"0":[20],"1":[1],"2":[19],"3":[8],"4":[18],"5":[1],"6":[6],"7":[1],"8":[5],"9":[1],"10":[5],"11":[1],"12":[4],"13":[1],"14":[16]},"fnMap":{"0":{"name":"getAnonymousId","decl":{"start":{"line":9,"column":7},"end":{"line":28,"column":1}},"loc":{"start":{"line":9,"column":7},"end":{"line":28,"column":1}},"line":9},"1":{"name":"setAnonymousId","decl":{"start":{"line":34,"column":7},"end":{"line":45,"column":1}},"loc":{"start":{"line":34,"column":7},"end":{"line":45,"column":1}},"line":34},"2":{"name":"clearAnonymousId","decl":{"start":{"line":51,"column":7},"end":{"line":62,"column":1}},"loc":{"start":{"line":51,"column":7},"end":{"line":62,"column":1}},"line":51},"3":{"name":"isAnonymousTrackingEnabled","decl":{"start":{"line":67,"column":7},"end":{"line":70,"column":1}},"loc":{"start":{"line":67,"column":7},"end":{"line":70,"column":1}},"line":67}},"f":{"0":20,"1":6,"2":5,"3":16}} +,"/Users/weidingjian/Desktop/work/ai/light-sentry-sdk/src/utils/logger.ts": {"path":"/Users/weidingjian/Desktop/work/ai/light-sentry-sdk/src/utils/logger.ts","all":false,"statementMap":{"0":{"start":{"line":1,"column":0},"end":{"line":1,"column":25}},"1":{"start":{"line":2,"column":0},"end":{"line":2,"column":0}},"2":{"start":{"line":3,"column":0},"end":{"line":3,"column":50}},"3":{"start":{"line":4,"column":0},"end":{"line":4,"column":25}},"4":{"start":{"line":5,"column":0},"end":{"line":5,"column":1}},"5":{"start":{"line":6,"column":0},"end":{"line":6,"column":0}},"6":{"start":{"line":7,"column":0},"end":{"line":7,"column":43}},"7":{"start":{"line":8,"column":0},"end":{"line":8,"column":22}},"8":{"start":{"line":9,"column":0},"end":{"line":9,"column":1}},"9":{"start":{"line":10,"column":0},"end":{"line":10,"column":0}},"10":{"start":{"line":11,"column":0},"end":{"line":11,"column":78}},"11":{"start":{"line":12,"column":0},"end":{"line":12,"column":28}},"12":{"start":{"line":13,"column":0},"end":{"line":13,"column":45}},"13":{"start":{"line":14,"column":0},"end":{"line":14,"column":38}},"14":{"start":{"line":15,"column":0},"end":{"line":15,"column":27}},"15":{"start":{"line":16,"column":0},"end":{"line":16,"column":59}},"16":{"start":{"line":17,"column":0},"end":{"line":17,"column":10}},"17":{"start":{"line":18,"column":0},"end":{"line":18,"column":53}},"18":{"start":{"line":19,"column":0},"end":{"line":19,"column":3}},"19":{"start":{"line":20,"column":0},"end":{"line":20,"column":1}},"20":{"start":{"line":21,"column":0},"end":{"line":21,"column":0}},"21":{"start":{"line":22,"column":0},"end":{"line":22,"column":79}},"22":{"start":{"line":23,"column":0},"end":{"line":23,"column":28}},"23":{"start":{"line":24,"column":0},"end":{"line":24,"column":45}},"24":{"start":{"line":25,"column":0},"end":{"line":25,"column":45}},"25":{"start":{"line":26,"column":0},"end":{"line":26,"column":28}},"26":{"start":{"line":27,"column":0},"end":{"line":27,"column":62}},"27":{"start":{"line":28,"column":0},"end":{"line":28,"column":10}},"28":{"start":{"line":29,"column":0},"end":{"line":29,"column":55}},"29":{"start":{"line":30,"column":0},"end":{"line":30,"column":3}},"30":{"start":{"line":31,"column":0},"end":{"line":31,"column":1}}},"s":{"0":1,"1":1,"2":1,"3":42,"4":42,"5":1,"6":1,"7":6,"8":6,"9":1,"10":1,"11":289,"12":8,"13":8,"14":10,"15":3,"16":10,"17":5,"18":5,"19":289,"20":1,"21":1,"22":10,"23":8,"24":8,"25":10,"26":3,"27":10,"28":5,"29":5,"30":10},"branchMap":{"0":{"type":"branch","line":3,"loc":{"start":{"line":3,"column":7},"end":{"line":5,"column":1}},"locations":[{"start":{"line":3,"column":7},"end":{"line":5,"column":1}}]},"1":{"type":"branch","line":7,"loc":{"start":{"line":7,"column":7},"end":{"line":9,"column":1}},"locations":[{"start":{"line":7,"column":7},"end":{"line":9,"column":1}}]},"2":{"type":"branch","line":11,"loc":{"start":{"line":11,"column":7},"end":{"line":20,"column":1}},"locations":[{"start":{"line":11,"column":7},"end":{"line":20,"column":1}}]},"3":{"type":"branch","line":12,"loc":{"start":{"line":12,"column":21},"end":{"line":12,"column":28}},"locations":[{"start":{"line":12,"column":21},"end":{"line":12,"column":28}}]},"4":{"type":"branch","line":12,"loc":{"start":{"line":12,"column":21},"end":{"line":19,"column":3}},"locations":[{"start":{"line":12,"column":21},"end":{"line":19,"column":3}}]},"5":{"type":"branch","line":12,"loc":{"start":{"line":12,"column":21},"end":{"line":15,"column":26}},"locations":[{"start":{"line":12,"column":21},"end":{"line":15,"column":26}}]},"6":{"type":"branch","line":15,"loc":{"start":{"line":15,"column":26},"end":{"line":17,"column":9}},"locations":[{"start":{"line":15,"column":26},"end":{"line":17,"column":9}}]},"7":{"type":"branch","line":17,"loc":{"start":{"line":17,"column":2},"end":{"line":19,"column":3}},"locations":[{"start":{"line":17,"column":2},"end":{"line":19,"column":3}}]},"8":{"type":"branch","line":22,"loc":{"start":{"line":22,"column":7},"end":{"line":31,"column":1}},"locations":[{"start":{"line":22,"column":7},"end":{"line":31,"column":1}}]},"9":{"type":"branch","line":23,"loc":{"start":{"line":23,"column":21},"end":{"line":23,"column":28}},"locations":[{"start":{"line":23,"column":21},"end":{"line":23,"column":28}}]},"10":{"type":"branch","line":23,"loc":{"start":{"line":23,"column":21},"end":{"line":26,"column":27}},"locations":[{"start":{"line":23,"column":21},"end":{"line":26,"column":27}}]},"11":{"type":"branch","line":26,"loc":{"start":{"line":26,"column":27},"end":{"line":28,"column":9}},"locations":[{"start":{"line":26,"column":27},"end":{"line":28,"column":9}}]},"12":{"type":"branch","line":28,"loc":{"start":{"line":28,"column":2},"end":{"line":30,"column":3}},"locations":[{"start":{"line":28,"column":2},"end":{"line":30,"column":3}}]}},"b":{"0":[42],"1":[6],"2":[289],"3":[281],"4":[10],"5":[8],"6":[3],"7":[5],"8":[10],"9":[2],"10":[8],"11":[3],"12":[5]},"fnMap":{"0":{"name":"setDebug","decl":{"start":{"line":3,"column":7},"end":{"line":5,"column":1}},"loc":{"start":{"line":3,"column":7},"end":{"line":5,"column":1}},"line":3},"1":{"name":"isDebugEnabled","decl":{"start":{"line":7,"column":7},"end":{"line":9,"column":1}},"loc":{"start":{"line":7,"column":7},"end":{"line":9,"column":1}},"line":7},"2":{"name":"logDebug","decl":{"start":{"line":11,"column":7},"end":{"line":20,"column":1}},"loc":{"start":{"line":11,"column":7},"end":{"line":20,"column":1}},"line":11},"3":{"name":"logError","decl":{"start":{"line":22,"column":7},"end":{"line":31,"column":1}},"loc":{"start":{"line":22,"column":7},"end":{"line":31,"column":1}},"line":22}},"f":{"0":42,"1":6,"2":289,"3":10}} +,"/Users/weidingjian/Desktop/work/ai/light-sentry-sdk/src/utils/stacktrace.ts": {"path":"/Users/weidingjian/Desktop/work/ai/light-sentry-sdk/src/utils/stacktrace.ts","all":false,"statementMap":{"0":{"start":{"line":1,"column":0},"end":{"line":1,"column":43}},"1":{"start":{"line":2,"column":0},"end":{"line":2,"column":0}},"2":{"start":{"line":3,"column":0},"end":{"line":3,"column":36}},"3":{"start":{"line":4,"column":0},"end":{"line":4,"column":31}},"4":{"start":{"line":5,"column":0},"end":{"line":5,"column":26}},"5":{"start":{"line":6,"column":0},"end":{"line":6,"column":29}},"6":{"start":{"line":7,"column":0},"end":{"line":7,"column":21}},"7":{"start":{"line":8,"column":0},"end":{"line":8,"column":1}},"8":{"start":{"line":9,"column":0},"end":{"line":9,"column":0}},"9":{"start":{"line":10,"column":0},"end":{"line":10,"column":96}},"10":{"start":{"line":11,"column":0},"end":{"line":11,"column":24}},"11":{"start":{"line":12,"column":0},"end":{"line":12,"column":0}},"12":{"start":{"line":13,"column":0},"end":{"line":13,"column":9}},"13":{"start":{"line":14,"column":0},"end":{"line":14,"column":31}},"14":{"start":{"line":15,"column":0},"end":{"line":15,"column":25}},"15":{"start":{"line":16,"column":0},"end":{"line":16,"column":29}},"16":{"start":{"line":17,"column":0},"end":{"line":17,"column":14}},"17":{"start":{"line":18,"column":0},"end":{"line":18,"column":14}},"18":{"start":{"line":19,"column":0},"end":{"line":19,"column":0}},"19":{"start":{"line":20,"column":0},"end":{"line":20,"column":34}},"20":{"start":{"line":21,"column":0},"end":{"line":21,"column":34}},"21":{"start":{"line":22,"column":0},"end":{"line":22,"column":97}},"22":{"start":{"line":23,"column":0},"end":{"line":23,"column":0}},"23":{"start":{"line":24,"column":0},"end":{"line":24,"column":29}},"24":{"start":{"line":25,"column":0},"end":{"line":25,"column":75}},"25":{"start":{"line":26,"column":0},"end":{"line":26,"column":16}},"26":{"start":{"line":27,"column":0},"end":{"line":27,"column":54}},"27":{"start":{"line":28,"column":0},"end":{"line":28,"column":6}},"28":{"start":{"line":29,"column":0},"end":{"line":29,"column":62}},"29":{"start":{"line":30,"column":0},"end":{"line":30,"column":49}},"30":{"start":{"line":31,"column":0},"end":{"line":31,"column":17}},"31":{"start":{"line":32,"column":0},"end":{"line":32,"column":7}},"32":{"start":{"line":33,"column":0},"end":{"line":33,"column":0}},"33":{"start":{"line":34,"column":0},"end":{"line":34,"column":35}},"34":{"start":{"line":35,"column":0},"end":{"line":35,"column":70}},"35":{"start":{"line":36,"column":0},"end":{"line":36,"column":58}},"36":{"start":{"line":37,"column":0},"end":{"line":37,"column":7}},"37":{"start":{"line":38,"column":0},"end":{"line":38,"column":0}},"38":{"start":{"line":39,"column":0},"end":{"line":39,"column":19}},"39":{"start":{"line":40,"column":0},"end":{"line":40,"column":32}},"40":{"start":{"line":41,"column":0},"end":{"line":41,"column":21}},"41":{"start":{"line":42,"column":0},"end":{"line":42,"column":38}},"42":{"start":{"line":43,"column":0},"end":{"line":43,"column":64}},"43":{"start":{"line":44,"column":0},"end":{"line":44,"column":31}},"44":{"start":{"line":45,"column":0},"end":{"line":45,"column":9}},"45":{"start":{"line":46,"column":0},"end":{"line":46,"column":12}},"46":{"start":{"line":47,"column":0},"end":{"line":47,"column":73}},"47":{"start":{"line":48,"column":0},"end":{"line":48,"column":18}},"48":{"start":{"line":49,"column":0},"end":{"line":49,"column":56}},"49":{"start":{"line":50,"column":0},"end":{"line":50,"column":6}},"50":{"start":{"line":51,"column":0},"end":{"line":51,"column":62}},"51":{"start":{"line":52,"column":0},"end":{"line":52,"column":49}},"52":{"start":{"line":53,"column":0},"end":{"line":53,"column":17}},"53":{"start":{"line":54,"column":0},"end":{"line":54,"column":7}},"54":{"start":{"line":55,"column":0},"end":{"line":55,"column":0}},"55":{"start":{"line":56,"column":0},"end":{"line":56,"column":35}},"56":{"start":{"line":57,"column":0},"end":{"line":57,"column":70}},"57":{"start":{"line":58,"column":0},"end":{"line":58,"column":58}},"58":{"start":{"line":59,"column":0},"end":{"line":59,"column":7}},"59":{"start":{"line":60,"column":0},"end":{"line":60,"column":0}},"60":{"start":{"line":61,"column":0},"end":{"line":61,"column":19}},"61":{"start":{"line":62,"column":0},"end":{"line":62,"column":32}},"62":{"start":{"line":63,"column":0},"end":{"line":63,"column":38}},"63":{"start":{"line":64,"column":0},"end":{"line":64,"column":38}},"64":{"start":{"line":65,"column":0},"end":{"line":65,"column":64}},"65":{"start":{"line":66,"column":0},"end":{"line":66,"column":31}},"66":{"start":{"line":67,"column":0},"end":{"line":67,"column":9}},"67":{"start":{"line":68,"column":0},"end":{"line":68,"column":15}},"68":{"start":{"line":69,"column":0},"end":{"line":69,"column":5}},"69":{"start":{"line":70,"column":0},"end":{"line":70,"column":0}},"70":{"start":{"line":71,"column":0},"end":{"line":71,"column":66}},"71":{"start":{"line":72,"column":0},"end":{"line":72,"column":19}},"72":{"start":{"line":73,"column":0},"end":{"line":73,"column":53}},"73":{"start":{"line":74,"column":0},"end":{"line":74,"column":8}},"74":{"start":{"line":75,"column":0},"end":{"line":75,"column":64}},"75":{"start":{"line":76,"column":0},"end":{"line":76,"column":51}},"76":{"start":{"line":77,"column":0},"end":{"line":77,"column":19}},"77":{"start":{"line":78,"column":0},"end":{"line":78,"column":9}},"78":{"start":{"line":79,"column":0},"end":{"line":79,"column":0}},"79":{"start":{"line":80,"column":0},"end":{"line":80,"column":37}},"80":{"start":{"line":81,"column":0},"end":{"line":81,"column":72}},"81":{"start":{"line":82,"column":0},"end":{"line":82,"column":60}},"82":{"start":{"line":83,"column":0},"end":{"line":83,"column":9}},"83":{"start":{"line":84,"column":0},"end":{"line":84,"column":0}},"84":{"start":{"line":85,"column":0},"end":{"line":85,"column":21}},"85":{"start":{"line":86,"column":0},"end":{"line":86,"column":34}},"86":{"start":{"line":87,"column":0},"end":{"line":87,"column":40}},"87":{"start":{"line":88,"column":0},"end":{"line":88,"column":66}},"88":{"start":{"line":89,"column":0},"end":{"line":89,"column":33}},"89":{"start":{"line":90,"column":0},"end":{"line":90,"column":11}},"90":{"start":{"line":91,"column":0},"end":{"line":91,"column":7}},"91":{"start":{"line":92,"column":0},"end":{"line":92,"column":5}},"92":{"start":{"line":93,"column":0},"end":{"line":93,"column":3}},"93":{"start":{"line":94,"column":0},"end":{"line":94,"column":0}},"94":{"start":{"line":95,"column":0},"end":{"line":95,"column":36}},"95":{"start":{"line":96,"column":0},"end":{"line":96,"column":49}},"96":{"start":{"line":97,"column":0},"end":{"line":97,"column":40}},"97":{"start":{"line":98,"column":0},"end":{"line":98,"column":3}},"98":{"start":{"line":99,"column":0},"end":{"line":99,"column":18}},"99":{"start":{"line":100,"column":0},"end":{"line":100,"column":1}}},"s":{"0":1,"1":1,"2":1,"3":1,"4":1,"5":1,"6":1,"7":1,"8":1,"9":1,"10":26,"11":24,"12":24,"13":24,"14":24,"15":24,"16":24,"17":24,"18":24,"19":24,"20":24,"21":26,"22":26,"23":26,"24":73,"25":73,"26":28,"27":28,"28":28,"29":28,"30":2,"31":2,"32":26,"33":26,"34":28,"35":0,"36":0,"37":26,"38":26,"39":26,"40":26,"41":26,"42":28,"43":28,"44":28,"45":73,"46":45,"47":45,"48":11,"49":11,"50":11,"51":11,"52":1,"53":1,"54":10,"55":10,"56":11,"57":2,"58":2,"59":10,"60":10,"61":10,"62":11,"63":11,"64":11,"65":11,"66":11,"67":11,"68":11,"69":34,"70":34,"71":45,"72":10,"73":10,"74":10,"75":10,"76":1,"77":1,"78":9,"79":9,"80":10,"81":2,"82":2,"83":9,"84":9,"85":9,"86":9,"87":10,"88":10,"89":10,"90":10,"91":45,"92":73,"93":24,"94":24,"95":26,"96":1,"97":1,"98":23,"99":23},"branchMap":{"0":{"type":"branch","line":10,"loc":{"start":{"line":10,"column":7},"end":{"line":100,"column":1}},"locations":[{"start":{"line":10,"column":7},"end":{"line":100,"column":1}}]},"1":{"type":"branch","line":11,"loc":{"start":{"line":11,"column":14},"end":{"line":11,"column":24}},"locations":[{"start":{"line":11,"column":14},"end":{"line":11,"column":24}}]},"2":{"type":"branch","line":11,"loc":{"start":{"line":11,"column":22},"end":{"line":22,"column":51}},"locations":[{"start":{"line":11,"column":22},"end":{"line":22,"column":51}}]},"3":{"type":"branch","line":22,"loc":{"start":{"line":22,"column":37},"end":{"line":22,"column":94}},"locations":[{"start":{"line":22,"column":37},"end":{"line":22,"column":94}}]},"4":{"type":"branch","line":22,"loc":{"start":{"line":22,"column":89},"end":{"line":22,"column":97}},"locations":[{"start":{"line":22,"column":89},"end":{"line":22,"column":97}}]},"5":{"type":"branch","line":24,"loc":{"start":{"line":24,"column":28},"end":{"line":93,"column":3}},"locations":[{"start":{"line":24,"column":28},"end":{"line":93,"column":3}}]},"6":{"type":"branch","line":26,"loc":{"start":{"line":26,"column":15},"end":{"line":46,"column":11}},"locations":[{"start":{"line":26,"column":15},"end":{"line":46,"column":11}}]},"7":{"type":"branch","line":30,"loc":{"start":{"line":30,"column":11},"end":{"line":30,"column":48}},"locations":[{"start":{"line":30,"column":11},"end":{"line":30,"column":48}}]},"8":{"type":"branch","line":30,"loc":{"start":{"line":30,"column":48},"end":{"line":32,"column":7}},"locations":[{"start":{"line":30,"column":48},"end":{"line":32,"column":7}}]},"9":{"type":"branch","line":32,"loc":{"start":{"line":32,"column":6},"end":{"line":35,"column":30}},"locations":[{"start":{"line":32,"column":6},"end":{"line":35,"column":30}}]},"10":{"type":"branch","line":35,"loc":{"start":{"line":35,"column":10},"end":{"line":35,"column":40}},"locations":[{"start":{"line":35,"column":10},"end":{"line":35,"column":40}}]},"11":{"type":"branch","line":35,"loc":{"start":{"line":35,"column":30},"end":{"line":35,"column":69}},"locations":[{"start":{"line":35,"column":30},"end":{"line":35,"column":69}}]},"12":{"type":"branch","line":35,"loc":{"start":{"line":35,"column":69},"end":{"line":37,"column":7}},"locations":[{"start":{"line":35,"column":69},"end":{"line":37,"column":7}}]},"13":{"type":"branch","line":37,"loc":{"start":{"line":37,"column":6},"end":{"line":43,"column":31}},"locations":[{"start":{"line":37,"column":6},"end":{"line":43,"column":31}}]},"14":{"type":"branch","line":43,"loc":{"start":{"line":43,"column":15},"end":{"line":43,"column":54}},"locations":[{"start":{"line":43,"column":15},"end":{"line":43,"column":54}}]},"15":{"type":"branch","line":43,"loc":{"start":{"line":43,"column":50},"end":{"line":43,"column":64}},"locations":[{"start":{"line":43,"column":50},"end":{"line":43,"column":64}}]},"16":{"type":"branch","line":46,"loc":{"start":{"line":46,"column":4},"end":{"line":92,"column":5}},"locations":[{"start":{"line":46,"column":4},"end":{"line":92,"column":5}}]},"17":{"type":"branch","line":48,"loc":{"start":{"line":48,"column":17},"end":{"line":69,"column":5}},"locations":[{"start":{"line":48,"column":17},"end":{"line":69,"column":5}}]},"18":{"type":"branch","line":52,"loc":{"start":{"line":52,"column":11},"end":{"line":52,"column":48}},"locations":[{"start":{"line":52,"column":11},"end":{"line":52,"column":48}}]},"19":{"type":"branch","line":52,"loc":{"start":{"line":52,"column":48},"end":{"line":54,"column":7}},"locations":[{"start":{"line":52,"column":48},"end":{"line":54,"column":7}}]},"20":{"type":"branch","line":54,"loc":{"start":{"line":54,"column":6},"end":{"line":57,"column":30}},"locations":[{"start":{"line":54,"column":6},"end":{"line":57,"column":30}}]},"21":{"type":"branch","line":57,"loc":{"start":{"line":57,"column":10},"end":{"line":57,"column":40}},"locations":[{"start":{"line":57,"column":10},"end":{"line":57,"column":40}}]},"22":{"type":"branch","line":57,"loc":{"start":{"line":57,"column":30},"end":{"line":57,"column":69}},"locations":[{"start":{"line":57,"column":30},"end":{"line":57,"column":69}}]},"23":{"type":"branch","line":57,"loc":{"start":{"line":57,"column":69},"end":{"line":59,"column":7}},"locations":[{"start":{"line":57,"column":69},"end":{"line":59,"column":7}}]},"24":{"type":"branch","line":59,"loc":{"start":{"line":59,"column":6},"end":{"line":63,"column":24}},"locations":[{"start":{"line":59,"column":6},"end":{"line":63,"column":24}}]},"25":{"type":"branch","line":63,"loc":{"start":{"line":63,"column":18},"end":{"line":63,"column":38}},"locations":[{"start":{"line":63,"column":18},"end":{"line":63,"column":38}}]},"26":{"type":"branch","line":65,"loc":{"start":{"line":65,"column":15},"end":{"line":65,"column":54}},"locations":[{"start":{"line":65,"column":15},"end":{"line":65,"column":54}}]},"27":{"type":"branch","line":65,"loc":{"start":{"line":65,"column":50},"end":{"line":65,"column":64}},"locations":[{"start":{"line":65,"column":50},"end":{"line":65,"column":64}}]},"28":{"type":"branch","line":69,"loc":{"start":{"line":69,"column":4},"end":{"line":72,"column":18}},"locations":[{"start":{"line":69,"column":4},"end":{"line":72,"column":18}}]},"29":{"type":"branch","line":72,"loc":{"start":{"line":72,"column":18},"end":{"line":91,"column":7}},"locations":[{"start":{"line":72,"column":18},"end":{"line":91,"column":7}}]},"30":{"type":"branch","line":76,"loc":{"start":{"line":76,"column":13},"end":{"line":76,"column":50}},"locations":[{"start":{"line":76,"column":13},"end":{"line":76,"column":50}}]},"31":{"type":"branch","line":76,"loc":{"start":{"line":76,"column":50},"end":{"line":78,"column":9}},"locations":[{"start":{"line":76,"column":50},"end":{"line":78,"column":9}}]},"32":{"type":"branch","line":78,"loc":{"start":{"line":78,"column":8},"end":{"line":81,"column":32}},"locations":[{"start":{"line":78,"column":8},"end":{"line":81,"column":32}}]},"33":{"type":"branch","line":81,"loc":{"start":{"line":81,"column":12},"end":{"line":81,"column":42}},"locations":[{"start":{"line":81,"column":12},"end":{"line":81,"column":42}}]},"34":{"type":"branch","line":81,"loc":{"start":{"line":81,"column":32},"end":{"line":81,"column":71}},"locations":[{"start":{"line":81,"column":32},"end":{"line":81,"column":71}}]},"35":{"type":"branch","line":81,"loc":{"start":{"line":81,"column":71},"end":{"line":83,"column":9}},"locations":[{"start":{"line":81,"column":71},"end":{"line":83,"column":9}}]},"36":{"type":"branch","line":83,"loc":{"start":{"line":83,"column":8},"end":{"line":88,"column":33}},"locations":[{"start":{"line":83,"column":8},"end":{"line":88,"column":33}}]},"37":{"type":"branch","line":88,"loc":{"start":{"line":88,"column":17},"end":{"line":88,"column":56}},"locations":[{"start":{"line":88,"column":17},"end":{"line":88,"column":56}}]},"38":{"type":"branch","line":88,"loc":{"start":{"line":88,"column":52},"end":{"line":88,"column":66}},"locations":[{"start":{"line":88,"column":52},"end":{"line":88,"column":66}}]},"39":{"type":"branch","line":93,"loc":{"start":{"line":93,"column":2},"end":{"line":96,"column":33}},"locations":[{"start":{"line":93,"column":2},"end":{"line":96,"column":33}}]},"40":{"type":"branch","line":96,"loc":{"start":{"line":96,"column":20},"end":{"line":96,"column":48}},"locations":[{"start":{"line":96,"column":20},"end":{"line":96,"column":48}}]},"41":{"type":"branch","line":96,"loc":{"start":{"line":96,"column":48},"end":{"line":98,"column":3}},"locations":[{"start":{"line":96,"column":48},"end":{"line":98,"column":3}}]},"42":{"type":"branch","line":98,"loc":{"start":{"line":98,"column":2},"end":{"line":100,"column":1}},"locations":[{"start":{"line":98,"column":2},"end":{"line":100,"column":1}}]}},"b":{"0":[26],"1":[2],"2":[24],"3":[2],"4":[22],"5":[73],"6":[28],"7":[24],"8":[2],"9":[26],"10":[2],"11":[0],"12":[0],"13":[26],"14":[25],"15":[1],"16":[45],"17":[11],"18":[9],"19":[1],"20":[10],"21":[2],"22":[2],"23":[2],"24":[10],"25":[0],"26":[9],"27":[1],"28":[34],"29":[10],"30":[8],"31":[1],"32":[9],"33":[2],"34":[2],"35":[2],"36":[9],"37":[8],"38":[1],"39":[24],"40":[2],"41":[1],"42":[23]},"fnMap":{"0":{"name":"parseStackTrace","decl":{"start":{"line":10,"column":7},"end":{"line":100,"column":1}},"loc":{"start":{"line":10,"column":7},"end":{"line":100,"column":1}},"line":10}},"f":{"0":26}} +,"/Users/weidingjian/Desktop/work/ai/light-sentry-sdk/src/utils/tracing.ts": {"path":"/Users/weidingjian/Desktop/work/ai/light-sentry-sdk/src/utils/tracing.ts","all":false,"statementMap":{"0":{"start":{"line":1,"column":0},"end":{"line":1,"column":164}},"1":{"start":{"line":2,"column":0},"end":{"line":2,"column":37}},"2":{"start":{"line":3,"column":0},"end":{"line":3,"column":75}},"3":{"start":{"line":4,"column":0},"end":{"line":4,"column":0}},"4":{"start":{"line":5,"column":0},"end":{"line":5,"column":36}},"5":{"start":{"line":6,"column":0},"end":{"line":6,"column":34}},"6":{"start":{"line":7,"column":0},"end":{"line":7,"column":1}},"7":{"start":{"line":8,"column":0},"end":{"line":8,"column":0}},"8":{"start":{"line":9,"column":0},"end":{"line":9,"column":35}},"9":{"start":{"line":10,"column":0},"end":{"line":10,"column":51}},"10":{"start":{"line":11,"column":0},"end":{"line":11,"column":1}},"11":{"start":{"line":12,"column":0},"end":{"line":12,"column":0}},"12":{"start":{"line":13,"column":0},"end":{"line":13,"column":72}},"13":{"start":{"line":14,"column":0},"end":{"line":14,"column":57}},"14":{"start":{"line":15,"column":0},"end":{"line":15,"column":52}},"15":{"start":{"line":16,"column":0},"end":{"line":16,"column":51}},"16":{"start":{"line":17,"column":0},"end":{"line":17,"column":53}},"17":{"start":{"line":18,"column":0},"end":{"line":18,"column":45}},"18":{"start":{"line":19,"column":0},"end":{"line":19,"column":50}},"19":{"start":{"line":20,"column":0},"end":{"line":20,"column":54}},"20":{"start":{"line":21,"column":0},"end":{"line":21,"column":71}},"21":{"start":{"line":22,"column":0},"end":{"line":22,"column":69}},"22":{"start":{"line":23,"column":0},"end":{"line":23,"column":25}},"23":{"start":{"line":24,"column":0},"end":{"line":24,"column":1}},"24":{"start":{"line":25,"column":0},"end":{"line":25,"column":0}},"25":{"start":{"line":26,"column":0},"end":{"line":26,"column":82}},"26":{"start":{"line":27,"column":0},"end":{"line":27,"column":83}},"27":{"start":{"line":28,"column":0},"end":{"line":28,"column":27}},"28":{"start":{"line":29,"column":0},"end":{"line":29,"column":3}},"29":{"start":{"line":30,"column":0},"end":{"line":30,"column":0}},"30":{"start":{"line":31,"column":0},"end":{"line":31,"column":92}},"31":{"start":{"line":32,"column":0},"end":{"line":32,"column":0}},"32":{"start":{"line":33,"column":0},"end":{"line":33,"column":44}},"33":{"start":{"line":34,"column":0},"end":{"line":34,"column":57}},"34":{"start":{"line":35,"column":0},"end":{"line":35,"column":50}},"35":{"start":{"line":36,"column":0},"end":{"line":36,"column":55}},"36":{"start":{"line":37,"column":0},"end":{"line":37,"column":42}},"37":{"start":{"line":38,"column":0},"end":{"line":38,"column":0}},"38":{"start":{"line":39,"column":0},"end":{"line":39,"column":25}},"39":{"start":{"line":40,"column":0},"end":{"line":40,"column":1}},"40":{"start":{"line":41,"column":0},"end":{"line":41,"column":0}},"41":{"start":{"line":42,"column":0},"end":{"line":42,"column":35}},"42":{"start":{"line":43,"column":0},"end":{"line":43,"column":38}},"43":{"start":{"line":44,"column":0},"end":{"line":44,"column":24}},"44":{"start":{"line":45,"column":0},"end":{"line":45,"column":15}},"45":{"start":{"line":46,"column":0},"end":{"line":46,"column":51}},"46":{"start":{"line":47,"column":0},"end":{"line":47,"column":0}},"47":{"start":{"line":48,"column":0},"end":{"line":48,"column":35}},"48":{"start":{"line":49,"column":0},"end":{"line":49,"column":45}},"49":{"start":{"line":50,"column":0},"end":{"line":50,"column":71}},"50":{"start":{"line":51,"column":0},"end":{"line":51,"column":86}},"51":{"start":{"line":52,"column":0},"end":{"line":52,"column":72}},"52":{"start":{"line":53,"column":0},"end":{"line":53,"column":56}},"53":{"start":{"line":54,"column":0},"end":{"line":54,"column":66}},"54":{"start":{"line":55,"column":0},"end":{"line":55,"column":72}},"55":{"start":{"line":56,"column":0},"end":{"line":56,"column":74}},"56":{"start":{"line":57,"column":0},"end":{"line":57,"column":76}},"57":{"start":{"line":58,"column":0},"end":{"line":58,"column":70}},"58":{"start":{"line":59,"column":0},"end":{"line":59,"column":68}},"59":{"start":{"line":60,"column":0},"end":{"line":60,"column":66}},"60":{"start":{"line":61,"column":0},"end":{"line":61,"column":0}},"61":{"start":{"line":62,"column":0},"end":{"line":62,"column":40}},"62":{"start":{"line":63,"column":0},"end":{"line":63,"column":25}},"63":{"start":{"line":64,"column":0},"end":{"line":64,"column":44}},"64":{"start":{"line":65,"column":0},"end":{"line":65,"column":5}},"65":{"start":{"line":66,"column":0},"end":{"line":66,"column":27}},"66":{"start":{"line":67,"column":0},"end":{"line":67,"column":3}},"67":{"start":{"line":68,"column":0},"end":{"line":68,"column":0}},"68":{"start":{"line":69,"column":0},"end":{"line":69,"column":35}},"69":{"start":{"line":70,"column":0},"end":{"line":70,"column":40}},"70":{"start":{"line":71,"column":0},"end":{"line":71,"column":44}},"71":{"start":{"line":72,"column":0},"end":{"line":72,"column":5}},"72":{"start":{"line":73,"column":0},"end":{"line":73,"column":0}},"73":{"start":{"line":74,"column":0},"end":{"line":74,"column":31}},"74":{"start":{"line":75,"column":0},"end":{"line":75,"column":42}},"75":{"start":{"line":76,"column":0},"end":{"line":76,"column":5}},"76":{"start":{"line":77,"column":0},"end":{"line":77,"column":0}},"77":{"start":{"line":78,"column":0},"end":{"line":78,"column":34}},"78":{"start":{"line":79,"column":0},"end":{"line":79,"column":43}},"79":{"start":{"line":80,"column":0},"end":{"line":80,"column":3}},"80":{"start":{"line":81,"column":0},"end":{"line":81,"column":0}},"81":{"start":{"line":82,"column":0},"end":{"line":82,"column":25}},"82":{"start":{"line":83,"column":0},"end":{"line":83,"column":1}},"83":{"start":{"line":84,"column":0},"end":{"line":84,"column":0}},"84":{"start":{"line":85,"column":0},"end":{"line":85,"column":44}},"85":{"start":{"line":86,"column":0},"end":{"line":86,"column":27}},"86":{"start":{"line":87,"column":0},"end":{"line":87,"column":26}},"87":{"start":{"line":88,"column":0},"end":{"line":88,"column":33}},"88":{"start":{"line":89,"column":0},"end":{"line":89,"column":14}},"89":{"start":{"line":90,"column":0},"end":{"line":90,"column":23}},"90":{"start":{"line":91,"column":0},"end":{"line":91,"column":22}},"91":{"start":{"line":92,"column":0},"end":{"line":92,"column":36}},"92":{"start":{"line":93,"column":0},"end":{"line":93,"column":37}},"93":{"start":{"line":94,"column":0},"end":{"line":94,"column":34}},"94":{"start":{"line":95,"column":0},"end":{"line":95,"column":24}},"95":{"start":{"line":96,"column":0},"end":{"line":96,"column":37}},"96":{"start":{"line":97,"column":0},"end":{"line":97,"column":0}},"97":{"start":{"line":98,"column":0},"end":{"line":98,"column":32}},"98":{"start":{"line":99,"column":0},"end":{"line":99,"column":34}},"99":{"start":{"line":100,"column":0},"end":{"line":100,"column":0}},"100":{"start":{"line":101,"column":0},"end":{"line":101,"column":95}},"101":{"start":{"line":102,"column":0},"end":{"line":102,"column":56}},"102":{"start":{"line":103,"column":0},"end":{"line":103,"column":53}},"103":{"start":{"line":104,"column":0},"end":{"line":104,"column":45}},"104":{"start":{"line":105,"column":0},"end":{"line":105,"column":25}},"105":{"start":{"line":106,"column":0},"end":{"line":106,"column":43}},"106":{"start":{"line":107,"column":0},"end":{"line":107,"column":33}},"107":{"start":{"line":108,"column":0},"end":{"line":108,"column":36}},"108":{"start":{"line":109,"column":0},"end":{"line":109,"column":36}},"109":{"start":{"line":110,"column":0},"end":{"line":110,"column":58}},"110":{"start":{"line":111,"column":0},"end":{"line":111,"column":35}},"111":{"start":{"line":112,"column":0},"end":{"line":112,"column":26}},"112":{"start":{"line":113,"column":0},"end":{"line":113,"column":3}},"113":{"start":{"line":114,"column":0},"end":{"line":114,"column":0}},"114":{"start":{"line":115,"column":0},"end":{"line":115,"column":44}},"115":{"start":{"line":116,"column":0},"end":{"line":116,"column":27}},"116":{"start":{"line":117,"column":0},"end":{"line":117,"column":16}},"117":{"start":{"line":118,"column":0},"end":{"line":118,"column":3}},"118":{"start":{"line":119,"column":0},"end":{"line":119,"column":0}},"119":{"start":{"line":120,"column":0},"end":{"line":120,"column":46}},"120":{"start":{"line":121,"column":0},"end":{"line":121,"column":27}},"121":{"start":{"line":122,"column":0},"end":{"line":122,"column":16}},"122":{"start":{"line":123,"column":0},"end":{"line":123,"column":3}},"123":{"start":{"line":124,"column":0},"end":{"line":124,"column":0}},"124":{"start":{"line":125,"column":0},"end":{"line":125,"column":39}},"125":{"start":{"line":126,"column":0},"end":{"line":126,"column":25}},"126":{"start":{"line":127,"column":0},"end":{"line":127,"column":16}},"127":{"start":{"line":128,"column":0},"end":{"line":128,"column":3}},"128":{"start":{"line":129,"column":0},"end":{"line":129,"column":0}},"129":{"start":{"line":130,"column":0},"end":{"line":130,"column":43}},"130":{"start":{"line":131,"column":0},"end":{"line":131,"column":55}},"131":{"start":{"line":132,"column":0},"end":{"line":132,"column":56}},"132":{"start":{"line":133,"column":0},"end":{"line":133,"column":16}},"133":{"start":{"line":134,"column":0},"end":{"line":134,"column":3}},"134":{"start":{"line":135,"column":0},"end":{"line":135,"column":0}},"135":{"start":{"line":136,"column":0},"end":{"line":136,"column":85}},"136":{"start":{"line":137,"column":0},"end":{"line":137,"column":59}},"137":{"start":{"line":138,"column":0},"end":{"line":138,"column":31}},"138":{"start":{"line":139,"column":0},"end":{"line":139,"column":41}},"139":{"start":{"line":140,"column":0},"end":{"line":140,"column":42}},"140":{"start":{"line":141,"column":0},"end":{"line":141,"column":5}},"141":{"start":{"line":142,"column":0},"end":{"line":142,"column":16}},"142":{"start":{"line":143,"column":0},"end":{"line":143,"column":3}},"143":{"start":{"line":144,"column":0},"end":{"line":144,"column":0}},"144":{"start":{"line":145,"column":0},"end":{"line":145,"column":47}},"145":{"start":{"line":146,"column":0},"end":{"line":146,"column":32}},"146":{"start":{"line":147,"column":0},"end":{"line":147,"column":44}},"147":{"start":{"line":148,"column":0},"end":{"line":148,"column":0}},"148":{"start":{"line":149,"column":0},"end":{"line":149,"column":27}},"149":{"start":{"line":150,"column":0},"end":{"line":150,"column":7}},"150":{"start":{"line":151,"column":0},"end":{"line":151,"column":19}},"151":{"start":{"line":152,"column":0},"end":{"line":152,"column":30}},"152":{"start":{"line":153,"column":0},"end":{"line":153,"column":34}},"153":{"start":{"line":154,"column":0},"end":{"line":154,"column":8}},"154":{"start":{"line":155,"column":0},"end":{"line":155,"column":9}},"155":{"start":{"line":156,"column":0},"end":{"line":156,"column":18}},"156":{"start":{"line":157,"column":0},"end":{"line":157,"column":6}},"157":{"start":{"line":158,"column":0},"end":{"line":158,"column":0}},"158":{"start":{"line":159,"column":0},"end":{"line":159,"column":26}},"159":{"start":{"line":160,"column":0},"end":{"line":160,"column":42}},"160":{"start":{"line":161,"column":0},"end":{"line":161,"column":5}},"161":{"start":{"line":162,"column":0},"end":{"line":162,"column":0}},"162":{"start":{"line":163,"column":0},"end":{"line":163,"column":17}},"163":{"start":{"line":164,"column":0},"end":{"line":164,"column":3}},"164":{"start":{"line":165,"column":0},"end":{"line":165,"column":0}},"165":{"start":{"line":166,"column":0},"end":{"line":166,"column":39}},"166":{"start":{"line":167,"column":0},"end":{"line":167,"column":33}},"167":{"start":{"line":168,"column":0},"end":{"line":168,"column":28}},"168":{"start":{"line":169,"column":0},"end":{"line":169,"column":46}},"169":{"start":{"line":170,"column":0},"end":{"line":170,"column":0}},"170":{"start":{"line":171,"column":0},"end":{"line":171,"column":23}},"171":{"start":{"line":172,"column":0},"end":{"line":172,"column":118}},"172":{"start":{"line":173,"column":0},"end":{"line":173,"column":58}},"173":{"start":{"line":174,"column":0},"end":{"line":174,"column":59}},"174":{"start":{"line":175,"column":0},"end":{"line":175,"column":7}},"175":{"start":{"line":176,"column":0},"end":{"line":176,"column":5}},"176":{"start":{"line":177,"column":0},"end":{"line":177,"column":3}},"177":{"start":{"line":178,"column":0},"end":{"line":178,"column":0}},"178":{"start":{"line":179,"column":0},"end":{"line":179,"column":27}},"179":{"start":{"line":180,"column":0},"end":{"line":180,"column":46}},"180":{"start":{"line":181,"column":0},"end":{"line":181,"column":73}},"181":{"start":{"line":182,"column":0},"end":{"line":182,"column":22}},"182":{"start":{"line":183,"column":0},"end":{"line":183,"column":55}},"183":{"start":{"line":184,"column":0},"end":{"line":184,"column":41}},"184":{"start":{"line":185,"column":0},"end":{"line":185,"column":3}},"185":{"start":{"line":186,"column":0},"end":{"line":186,"column":0}},"186":{"start":{"line":187,"column":0},"end":{"line":187,"column":12}},"187":{"start":{"line":188,"column":0},"end":{"line":188,"column":12}},"188":{"start":{"line":189,"column":0},"end":{"line":189,"column":29}},"189":{"start":{"line":190,"column":0},"end":{"line":190,"column":27}},"190":{"start":{"line":191,"column":0},"end":{"line":191,"column":40}},"191":{"start":{"line":192,"column":0},"end":{"line":192,"column":18}},"192":{"start":{"line":193,"column":0},"end":{"line":193,"column":36}},"193":{"start":{"line":194,"column":0},"end":{"line":194,"column":26}},"194":{"start":{"line":195,"column":0},"end":{"line":195,"column":77}},"195":{"start":{"line":196,"column":0},"end":{"line":196,"column":77}},"196":{"start":{"line":197,"column":0},"end":{"line":197,"column":43}},"197":{"start":{"line":198,"column":0},"end":{"line":198,"column":58}},"198":{"start":{"line":199,"column":0},"end":{"line":199,"column":6}},"199":{"start":{"line":200,"column":0},"end":{"line":200,"column":3}},"200":{"start":{"line":201,"column":0},"end":{"line":201,"column":1}},"201":{"start":{"line":202,"column":0},"end":{"line":202,"column":0}},"202":{"start":{"line":203,"column":0},"end":{"line":203,"column":71}},"203":{"start":{"line":204,"column":0},"end":{"line":204,"column":15}},"204":{"start":{"line":205,"column":0},"end":{"line":205,"column":16}},"205":{"start":{"line":206,"column":0},"end":{"line":206,"column":21}},"206":{"start":{"line":207,"column":0},"end":{"line":207,"column":20}},"207":{"start":{"line":208,"column":0},"end":{"line":208,"column":26}},"208":{"start":{"line":209,"column":0},"end":{"line":209,"column":35}},"209":{"start":{"line":210,"column":0},"end":{"line":210,"column":33}},"210":{"start":{"line":211,"column":0},"end":{"line":211,"column":28}},"211":{"start":{"line":212,"column":0},"end":{"line":212,"column":32}},"212":{"start":{"line":213,"column":0},"end":{"line":213,"column":36}},"213":{"start":{"line":214,"column":0},"end":{"line":214,"column":0}},"214":{"start":{"line":215,"column":0},"end":{"line":215,"column":148}},"215":{"start":{"line":216,"column":0},"end":{"line":216,"column":38}},"216":{"start":{"line":217,"column":0},"end":{"line":217,"column":29}},"217":{"start":{"line":218,"column":0},"end":{"line":218,"column":29}},"218":{"start":{"line":219,"column":0},"end":{"line":219,"column":35}},"219":{"start":{"line":220,"column":0},"end":{"line":220,"column":28}},"220":{"start":{"line":221,"column":0},"end":{"line":221,"column":38}},"221":{"start":{"line":222,"column":0},"end":{"line":222,"column":28}},"222":{"start":{"line":223,"column":0},"end":{"line":223,"column":36}},"223":{"start":{"line":224,"column":0},"end":{"line":224,"column":33}},"224":{"start":{"line":225,"column":0},"end":{"line":225,"column":31}},"225":{"start":{"line":226,"column":0},"end":{"line":226,"column":5}},"226":{"start":{"line":227,"column":0},"end":{"line":227,"column":3}},"227":{"start":{"line":228,"column":0},"end":{"line":228,"column":0}},"228":{"start":{"line":229,"column":0},"end":{"line":229,"column":30}},"229":{"start":{"line":230,"column":0},"end":{"line":230,"column":45}},"230":{"start":{"line":231,"column":0},"end":{"line":231,"column":27}},"231":{"start":{"line":232,"column":0},"end":{"line":232,"column":13}},"232":{"start":{"line":233,"column":0},"end":{"line":233,"column":5}},"233":{"start":{"line":234,"column":0},"end":{"line":234,"column":26}},"234":{"start":{"line":235,"column":0},"end":{"line":235,"column":3}},"235":{"start":{"line":236,"column":0},"end":{"line":236,"column":0}},"236":{"start":{"line":237,"column":0},"end":{"line":237,"column":43}},"237":{"start":{"line":238,"column":0},"end":{"line":238,"column":25}},"238":{"start":{"line":239,"column":0},"end":{"line":239,"column":51}},"239":{"start":{"line":240,"column":0},"end":{"line":240,"column":21}},"240":{"start":{"line":241,"column":0},"end":{"line":241,"column":9}},"241":{"start":{"line":242,"column":0},"end":{"line":242,"column":43}},"242":{"start":{"line":243,"column":0},"end":{"line":243,"column":32}},"243":{"start":{"line":244,"column":0},"end":{"line":244,"column":33}},"244":{"start":{"line":245,"column":0},"end":{"line":245,"column":41}},"245":{"start":{"line":246,"column":0},"end":{"line":246,"column":9}},"246":{"start":{"line":247,"column":0},"end":{"line":247,"column":8}},"247":{"start":{"line":248,"column":0},"end":{"line":248,"column":5}},"248":{"start":{"line":249,"column":0},"end":{"line":249,"column":25}},"249":{"start":{"line":250,"column":0},"end":{"line":250,"column":3}},"250":{"start":{"line":251,"column":0},"end":{"line":251,"column":0}},"251":{"start":{"line":252,"column":0},"end":{"line":252,"column":48}},"252":{"start":{"line":253,"column":0},"end":{"line":253,"column":42}},"253":{"start":{"line":254,"column":0},"end":{"line":254,"column":25}},"254":{"start":{"line":255,"column":0},"end":{"line":255,"column":16}},"255":{"start":{"line":256,"column":0},"end":{"line":256,"column":3}},"256":{"start":{"line":257,"column":0},"end":{"line":257,"column":0}},"257":{"start":{"line":258,"column":0},"end":{"line":258,"column":59}},"258":{"start":{"line":259,"column":0},"end":{"line":259,"column":42}},"259":{"start":{"line":260,"column":0},"end":{"line":260,"column":31}},"260":{"start":{"line":261,"column":0},"end":{"line":261,"column":31}},"261":{"start":{"line":262,"column":0},"end":{"line":262,"column":12}},"262":{"start":{"line":263,"column":0},"end":{"line":263,"column":29}},"263":{"start":{"line":264,"column":0},"end":{"line":264,"column":5}},"264":{"start":{"line":265,"column":0},"end":{"line":265,"column":32}},"265":{"start":{"line":266,"column":0},"end":{"line":266,"column":37}},"266":{"start":{"line":267,"column":0},"end":{"line":267,"column":12}},"267":{"start":{"line":268,"column":0},"end":{"line":268,"column":34}},"268":{"start":{"line":269,"column":0},"end":{"line":269,"column":5}},"269":{"start":{"line":270,"column":0},"end":{"line":270,"column":16}},"270":{"start":{"line":271,"column":0},"end":{"line":271,"column":3}},"271":{"start":{"line":272,"column":0},"end":{"line":272,"column":0}},"272":{"start":{"line":273,"column":0},"end":{"line":273,"column":35}},"273":{"start":{"line":274,"column":0},"end":{"line":274,"column":42}},"274":{"start":{"line":275,"column":0},"end":{"line":275,"column":37}},"275":{"start":{"line":276,"column":0},"end":{"line":276,"column":3}},"276":{"start":{"line":277,"column":0},"end":{"line":277,"column":0}},"277":{"start":{"line":278,"column":0},"end":{"line":278,"column":43}},"278":{"start":{"line":279,"column":0},"end":{"line":279,"column":25}},"279":{"start":{"line":280,"column":0},"end":{"line":280,"column":3}},"280":{"start":{"line":281,"column":0},"end":{"line":281,"column":0}},"281":{"start":{"line":282,"column":0},"end":{"line":282,"column":39}},"282":{"start":{"line":283,"column":0},"end":{"line":283,"column":33}},"283":{"start":{"line":284,"column":0},"end":{"line":284,"column":31}},"284":{"start":{"line":285,"column":0},"end":{"line":285,"column":0}},"285":{"start":{"line":286,"column":0},"end":{"line":286,"column":39}},"286":{"start":{"line":287,"column":0},"end":{"line":287,"column":35}},"287":{"start":{"line":288,"column":0},"end":{"line":288,"column":39}},"288":{"start":{"line":289,"column":0},"end":{"line":289,"column":5}},"289":{"start":{"line":290,"column":0},"end":{"line":290,"column":0}},"290":{"start":{"line":291,"column":0},"end":{"line":291,"column":23}},"291":{"start":{"line":292,"column":0},"end":{"line":292,"column":130}},"292":{"start":{"line":293,"column":0},"end":{"line":293,"column":65}},"293":{"start":{"line":294,"column":0},"end":{"line":294,"column":66}},"294":{"start":{"line":295,"column":0},"end":{"line":295,"column":7}},"295":{"start":{"line":296,"column":0},"end":{"line":296,"column":5}},"296":{"start":{"line":297,"column":0},"end":{"line":297,"column":3}},"297":{"start":{"line":298,"column":0},"end":{"line":298,"column":0}},"298":{"start":{"line":299,"column":0},"end":{"line":299,"column":32}},"299":{"start":{"line":300,"column":0},"end":{"line":300,"column":24}},"300":{"start":{"line":301,"column":0},"end":{"line":301,"column":22}},"301":{"start":{"line":302,"column":0},"end":{"line":302,"column":21}},"302":{"start":{"line":303,"column":0},"end":{"line":303,"column":24}},"303":{"start":{"line":304,"column":0},"end":{"line":304,"column":23}},"304":{"start":{"line":305,"column":0},"end":{"line":305,"column":30}},"305":{"start":{"line":306,"column":0},"end":{"line":306,"column":20}},"306":{"start":{"line":307,"column":0},"end":{"line":307,"column":14}},"307":{"start":{"line":308,"column":0},"end":{"line":308,"column":24}},"308":{"start":{"line":309,"column":0},"end":{"line":309,"column":5}},"309":{"start":{"line":310,"column":0},"end":{"line":310,"column":3}},"310":{"start":{"line":311,"column":0},"end":{"line":311,"column":0}},"311":{"start":{"line":312,"column":0},"end":{"line":312,"column":13}},"312":{"start":{"line":313,"column":0},"end":{"line":313,"column":31}},"313":{"start":{"line":314,"column":0},"end":{"line":314,"column":61}},"314":{"start":{"line":315,"column":0},"end":{"line":315,"column":155}},"315":{"start":{"line":316,"column":0},"end":{"line":316,"column":29}},"316":{"start":{"line":317,"column":0},"end":{"line":317,"column":0}},"317":{"start":{"line":318,"column":0},"end":{"line":318,"column":12}},"318":{"start":{"line":319,"column":0},"end":{"line":319,"column":35}},"319":{"start":{"line":320,"column":0},"end":{"line":320,"column":29}},"320":{"start":{"line":321,"column":0},"end":{"line":321,"column":25}},"321":{"start":{"line":322,"column":0},"end":{"line":322,"column":34}},"322":{"start":{"line":323,"column":0},"end":{"line":323,"column":8}},"323":{"start":{"line":324,"column":0},"end":{"line":324,"column":29}},"324":{"start":{"line":325,"column":0},"end":{"line":325,"column":32}},"325":{"start":{"line":326,"column":0},"end":{"line":326,"column":44}},"326":{"start":{"line":327,"column":0},"end":{"line":327,"column":47}},"327":{"start":{"line":328,"column":0},"end":{"line":328,"column":17}},"328":{"start":{"line":329,"column":0},"end":{"line":329,"column":16}},"329":{"start":{"line":330,"column":0},"end":{"line":330,"column":33}},"330":{"start":{"line":331,"column":0},"end":{"line":331,"column":31}},"331":{"start":{"line":332,"column":0},"end":{"line":332,"column":44}},"332":{"start":{"line":333,"column":0},"end":{"line":333,"column":22}},"333":{"start":{"line":334,"column":0},"end":{"line":334,"column":30}},"334":{"start":{"line":335,"column":0},"end":{"line":335,"column":10}},"335":{"start":{"line":336,"column":0},"end":{"line":336,"column":8}},"336":{"start":{"line":337,"column":0},"end":{"line":337,"column":22}},"337":{"start":{"line":338,"column":0},"end":{"line":338,"column":61}},"338":{"start":{"line":339,"column":0},"end":{"line":339,"column":19}},"339":{"start":{"line":340,"column":0},"end":{"line":340,"column":29}},"340":{"start":{"line":341,"column":0},"end":{"line":341,"column":6}},"341":{"start":{"line":342,"column":0},"end":{"line":342,"column":3}},"342":{"start":{"line":343,"column":0},"end":{"line":343,"column":0}},"343":{"start":{"line":344,"column":0},"end":{"line":344,"column":12}},"344":{"start":{"line":345,"column":0},"end":{"line":345,"column":32}},"345":{"start":{"line":346,"column":0},"end":{"line":346,"column":12}},"346":{"start":{"line":347,"column":0},"end":{"line":347,"column":14}},"347":{"start":{"line":348,"column":0},"end":{"line":348,"column":29}},"348":{"start":{"line":349,"column":0},"end":{"line":349,"column":22}},"349":{"start":{"line":350,"column":0},"end":{"line":350,"column":47}},"350":{"start":{"line":351,"column":0},"end":{"line":351,"column":28}},"351":{"start":{"line":352,"column":0},"end":{"line":352,"column":6}},"352":{"start":{"line":353,"column":0},"end":{"line":353,"column":3}},"353":{"start":{"line":354,"column":0},"end":{"line":354,"column":1}},"354":{"start":{"line":355,"column":0},"end":{"line":355,"column":0}},"355":{"start":{"line":356,"column":0},"end":{"line":356,"column":43}}},"s":{"0":1,"1":1,"2":1,"3":1,"4":81,"5":81,"6":81,"7":1,"8":98,"9":98,"10":98,"11":1,"12":1,"13":21,"14":21,"15":21,"16":21,"17":21,"18":21,"19":21,"20":21,"21":21,"22":0,"23":0,"24":1,"25":1,"26":17,"27":3,"28":3,"29":14,"30":17,"31":17,"32":17,"33":17,"34":17,"35":17,"36":2,"37":0,"38":0,"39":0,"40":1,"41":1,"42":13,"43":13,"44":13,"45":13,"46":12,"47":13,"48":6,"49":6,"50":6,"51":6,"52":6,"53":6,"54":6,"55":6,"56":6,"57":6,"58":6,"59":6,"60":1,"61":1,"62":6,"63":0,"64":0,"65":1,"66":1,"67":6,"68":6,"69":6,"70":4,"71":4,"72":2,"73":6,"74":2,"75":2,"76":0,"77":0,"78":0,"79":6,"80":0,"81":0,"82":0,"83":1,"84":1,"85":1,"86":1,"87":1,"88":1,"89":1,"90":1,"91":1,"92":1,"93":1,"94":1,"95":1,"96":1,"97":1,"98":1,"99":1,"100":1,"101":99,"102":99,"103":99,"104":99,"105":99,"106":99,"107":99,"108":99,"109":99,"110":99,"111":99,"112":99,"113":1,"114":1,"115":11,"116":11,"117":11,"118":1,"119":1,"120":4,"121":4,"122":4,"123":1,"124":1,"125":28,"126":28,"127":28,"128":1,"129":1,"130":4,"131":4,"132":4,"133":4,"134":1,"135":1,"136":4,"137":4,"138":4,"139":1,"140":1,"141":4,"142":4,"143":1,"144":1,"145":16,"146":16,"147":16,"148":16,"149":16,"150":16,"151":16,"152":16,"153":16,"154":16,"155":16,"156":16,"157":16,"158":16,"159":13,"160":13,"161":16,"162":16,"163":16,"164":1,"165":1,"166":22,"167":21,"168":22,"169":22,"170":22,"171":17,"172":17,"173":0,"174":0,"175":17,"176":22,"177":1,"178":1,"179":3,"180":3,"181":3,"182":2,"183":1,"184":3,"185":1,"186":1,"187":31,"188":31,"189":31,"190":31,"191":31,"192":31,"193":31,"194":31,"195":31,"196":31,"197":31,"198":31,"199":31,"200":1,"201":1,"202":1,"203":1,"204":1,"205":1,"206":1,"207":1,"208":1,"209":1,"210":1,"211":1,"212":1,"213":1,"214":1,"215":42,"216":42,"217":42,"218":42,"219":42,"220":42,"221":42,"222":42,"223":42,"224":2,"225":2,"226":42,"227":1,"228":1,"229":13,"230":1,"231":1,"232":1,"233":12,"234":13,"235":1,"236":1,"237":13,"238":7,"239":7,"240":7,"241":7,"242":7,"243":7,"244":7,"245":7,"246":7,"247":7,"248":13,"249":13,"250":1,"251":1,"252":1,"253":1,"254":1,"255":1,"256":1,"257":1,"258":5,"259":5,"260":4,"261":5,"262":1,"263":1,"264":5,"265":2,"266":5,"267":3,"268":3,"269":5,"270":5,"271":1,"272":1,"273":7,"274":7,"275":7,"276":1,"277":1,"278":0,"279":0,"280":1,"281":1,"282":17,"283":17,"284":17,"285":17,"286":13,"287":13,"288":13,"289":17,"290":17,"291":17,"292":17,"293":0,"294":0,"295":17,"296":17,"297":1,"298":1,"299":14,"300":14,"301":0,"302":14,"303":0,"304":14,"305":0,"306":14,"307":14,"308":14,"309":14,"310":1,"311":1,"312":14,"313":14,"314":14,"315":14,"316":14,"317":14,"318":14,"319":14,"320":14,"321":14,"322":14,"323":14,"324":14,"325":14,"326":14,"327":14,"328":14,"329":14,"330":14,"331":14,"332":14,"333":14,"334":14,"335":14,"336":14,"337":14,"338":14,"339":14,"340":14,"341":14,"342":1,"343":1,"344":15,"345":15,"346":15,"347":15,"348":15,"349":15,"350":15,"351":15,"352":15,"353":1,"354":1,"355":1},"branchMap":{"0":{"type":"branch","line":5,"loc":{"start":{"line":5,"column":0},"end":{"line":7,"column":1}},"locations":[{"start":{"line":5,"column":0},"end":{"line":7,"column":1}}]},"1":{"type":"branch","line":9,"loc":{"start":{"line":9,"column":0},"end":{"line":11,"column":1}},"locations":[{"start":{"line":9,"column":0},"end":{"line":11,"column":1}}]},"2":{"type":"branch","line":13,"loc":{"start":{"line":13,"column":7},"end":{"line":24,"column":1}},"locations":[{"start":{"line":13,"column":7},"end":{"line":24,"column":1}}]},"3":{"type":"branch","line":14,"loc":{"start":{"line":14,"column":45},"end":{"line":14,"column":57}},"locations":[{"start":{"line":14,"column":45},"end":{"line":14,"column":57}}]},"4":{"type":"branch","line":14,"loc":{"start":{"line":14,"column":52},"end":{"line":15,"column":33}},"locations":[{"start":{"line":14,"column":52},"end":{"line":15,"column":33}}]},"5":{"type":"branch","line":15,"loc":{"start":{"line":15,"column":26},"end":{"line":15,"column":52}},"locations":[{"start":{"line":15,"column":26},"end":{"line":15,"column":52}}]},"6":{"type":"branch","line":15,"loc":{"start":{"line":15,"column":33},"end":{"line":16,"column":33}},"locations":[{"start":{"line":15,"column":33},"end":{"line":16,"column":33}}]},"7":{"type":"branch","line":16,"loc":{"start":{"line":16,"column":26},"end":{"line":16,"column":51}},"locations":[{"start":{"line":16,"column":26},"end":{"line":16,"column":51}}]},"8":{"type":"branch","line":16,"loc":{"start":{"line":16,"column":33},"end":{"line":17,"column":33}},"locations":[{"start":{"line":16,"column":33},"end":{"line":17,"column":33}}]},"9":{"type":"branch","line":17,"loc":{"start":{"line":17,"column":26},"end":{"line":17,"column":53}},"locations":[{"start":{"line":17,"column":26},"end":{"line":17,"column":53}}]},"10":{"type":"branch","line":17,"loc":{"start":{"line":17,"column":33},"end":{"line":18,"column":33}},"locations":[{"start":{"line":17,"column":33},"end":{"line":18,"column":33}}]},"11":{"type":"branch","line":18,"loc":{"start":{"line":18,"column":26},"end":{"line":18,"column":45}},"locations":[{"start":{"line":18,"column":26},"end":{"line":18,"column":45}}]},"12":{"type":"branch","line":18,"loc":{"start":{"line":18,"column":33},"end":{"line":19,"column":33}},"locations":[{"start":{"line":18,"column":33},"end":{"line":19,"column":33}}]},"13":{"type":"branch","line":19,"loc":{"start":{"line":19,"column":26},"end":{"line":19,"column":50}},"locations":[{"start":{"line":19,"column":26},"end":{"line":19,"column":50}}]},"14":{"type":"branch","line":19,"loc":{"start":{"line":19,"column":33},"end":{"line":20,"column":33}},"locations":[{"start":{"line":19,"column":33},"end":{"line":20,"column":33}}]},"15":{"type":"branch","line":20,"loc":{"start":{"line":20,"column":26},"end":{"line":20,"column":54}},"locations":[{"start":{"line":20,"column":26},"end":{"line":20,"column":54}}]},"16":{"type":"branch","line":20,"loc":{"start":{"line":20,"column":33},"end":{"line":21,"column":45}},"locations":[{"start":{"line":20,"column":33},"end":{"line":21,"column":45}}]},"17":{"type":"branch","line":21,"loc":{"start":{"line":21,"column":45},"end":{"line":21,"column":71}},"locations":[{"start":{"line":21,"column":45},"end":{"line":21,"column":71}}]},"18":{"type":"branch","line":21,"loc":{"start":{"line":21,"column":52},"end":{"line":22,"column":45}},"locations":[{"start":{"line":21,"column":52},"end":{"line":22,"column":45}}]},"19":{"type":"branch","line":22,"loc":{"start":{"line":22,"column":45},"end":{"line":22,"column":69}},"locations":[{"start":{"line":22,"column":45},"end":{"line":22,"column":69}}]},"20":{"type":"branch","line":22,"loc":{"start":{"line":22,"column":52},"end":{"line":24,"column":1}},"locations":[{"start":{"line":22,"column":52},"end":{"line":24,"column":1}}]},"21":{"type":"branch","line":26,"loc":{"start":{"line":26,"column":7},"end":{"line":40,"column":1}},"locations":[{"start":{"line":26,"column":7},"end":{"line":40,"column":1}}]},"22":{"type":"branch","line":27,"loc":{"start":{"line":27,"column":23},"end":{"line":27,"column":61}},"locations":[{"start":{"line":27,"column":23},"end":{"line":27,"column":61}}]},"23":{"type":"branch","line":27,"loc":{"start":{"line":27,"column":53},"end":{"line":27,"column":82}},"locations":[{"start":{"line":27,"column":53},"end":{"line":27,"column":82}}]},"24":{"type":"branch","line":27,"loc":{"start":{"line":27,"column":82},"end":{"line":29,"column":3}},"locations":[{"start":{"line":27,"column":82},"end":{"line":29,"column":3}}]},"25":{"type":"branch","line":29,"loc":{"start":{"line":29,"column":2},"end":{"line":31,"column":50}},"locations":[{"start":{"line":29,"column":2},"end":{"line":31,"column":50}}]},"26":{"type":"branch","line":31,"loc":{"start":{"line":31,"column":39},"end":{"line":31,"column":79}},"locations":[{"start":{"line":31,"column":39},"end":{"line":31,"column":79}}]},"27":{"type":"branch","line":31,"loc":{"start":{"line":31,"column":75},"end":{"line":31,"column":92}},"locations":[{"start":{"line":31,"column":75},"end":{"line":31,"column":92}}]},"28":{"type":"branch","line":33,"loc":{"start":{"line":33,"column":15},"end":{"line":33,"column":32}},"locations":[{"start":{"line":33,"column":15},"end":{"line":33,"column":32}}]},"29":{"type":"branch","line":33,"loc":{"start":{"line":33,"column":32},"end":{"line":33,"column":44}},"locations":[{"start":{"line":33,"column":32},"end":{"line":33,"column":44}}]},"30":{"type":"branch","line":33,"loc":{"start":{"line":33,"column":39},"end":{"line":34,"column":31}},"locations":[{"start":{"line":33,"column":39},"end":{"line":34,"column":31}}]},"31":{"type":"branch","line":34,"loc":{"start":{"line":34,"column":31},"end":{"line":34,"column":57}},"locations":[{"start":{"line":34,"column":31},"end":{"line":34,"column":57}}]},"32":{"type":"branch","line":34,"loc":{"start":{"line":34,"column":38},"end":{"line":35,"column":31}},"locations":[{"start":{"line":34,"column":38},"end":{"line":35,"column":31}}]},"33":{"type":"branch","line":35,"loc":{"start":{"line":35,"column":31},"end":{"line":35,"column":50}},"locations":[{"start":{"line":35,"column":31},"end":{"line":35,"column":50}}]},"34":{"type":"branch","line":35,"loc":{"start":{"line":35,"column":38},"end":{"line":36,"column":31}},"locations":[{"start":{"line":35,"column":38},"end":{"line":36,"column":31}}]},"35":{"type":"branch","line":36,"loc":{"start":{"line":36,"column":31},"end":{"line":37,"column":42}},"locations":[{"start":{"line":36,"column":31},"end":{"line":37,"column":42}}]},"36":{"type":"branch","line":37,"loc":{"start":{"line":37,"column":25},"end":{"line":40,"column":1}},"locations":[{"start":{"line":37,"column":25},"end":{"line":40,"column":1}}]},"37":{"type":"branch","line":42,"loc":{"start":{"line":42,"column":7},"end":{"line":83,"column":1}},"locations":[{"start":{"line":42,"column":7},"end":{"line":83,"column":1}}]},"38":{"type":"branch","line":46,"loc":{"start":{"line":46,"column":28},"end":{"line":46,"column":51}},"locations":[{"start":{"line":46,"column":28},"end":{"line":46,"column":51}}]},"39":{"type":"branch","line":46,"loc":{"start":{"line":46,"column":35},"end":{"line":48,"column":34}},"locations":[{"start":{"line":46,"column":35},"end":{"line":48,"column":34}}]},"40":{"type":"branch","line":48,"loc":{"start":{"line":48,"column":34},"end":{"line":80,"column":3}},"locations":[{"start":{"line":48,"column":34},"end":{"line":80,"column":3}}]},"41":{"type":"branch","line":50,"loc":{"start":{"line":50,"column":24},"end":{"line":50,"column":59}},"locations":[{"start":{"line":50,"column":24},"end":{"line":50,"column":59}}]},"42":{"type":"branch","line":50,"loc":{"start":{"line":50,"column":59},"end":{"line":51,"column":39}},"locations":[{"start":{"line":50,"column":59},"end":{"line":51,"column":39}}]},"43":{"type":"branch","line":51,"loc":{"start":{"line":51,"column":24},"end":{"line":51,"column":67}},"locations":[{"start":{"line":51,"column":24},"end":{"line":51,"column":67}}]},"44":{"type":"branch","line":51,"loc":{"start":{"line":51,"column":67},"end":{"line":51,"column":86}},"locations":[{"start":{"line":51,"column":67},"end":{"line":51,"column":86}}]},"45":{"type":"branch","line":51,"loc":{"start":{"line":51,"column":74},"end":{"line":52,"column":52}},"locations":[{"start":{"line":51,"column":74},"end":{"line":52,"column":52}}]},"46":{"type":"branch","line":52,"loc":{"start":{"line":52,"column":45},"end":{"line":52,"column":72}},"locations":[{"start":{"line":52,"column":45},"end":{"line":52,"column":72}}]},"47":{"type":"branch","line":52,"loc":{"start":{"line":52,"column":52},"end":{"line":53,"column":44}},"locations":[{"start":{"line":52,"column":52},"end":{"line":53,"column":44}}]},"48":{"type":"branch","line":53,"loc":{"start":{"line":53,"column":37},"end":{"line":53,"column":56}},"locations":[{"start":{"line":53,"column":37},"end":{"line":53,"column":56}}]},"49":{"type":"branch","line":53,"loc":{"start":{"line":53,"column":44},"end":{"line":54,"column":49}},"locations":[{"start":{"line":53,"column":44},"end":{"line":54,"column":49}}]},"50":{"type":"branch","line":54,"loc":{"start":{"line":54,"column":42},"end":{"line":54,"column":66}},"locations":[{"start":{"line":54,"column":42},"end":{"line":54,"column":66}}]},"51":{"type":"branch","line":54,"loc":{"start":{"line":54,"column":49},"end":{"line":55,"column":52}},"locations":[{"start":{"line":54,"column":49},"end":{"line":55,"column":52}}]},"52":{"type":"branch","line":55,"loc":{"start":{"line":55,"column":45},"end":{"line":55,"column":72}},"locations":[{"start":{"line":55,"column":45},"end":{"line":55,"column":72}}]},"53":{"type":"branch","line":55,"loc":{"start":{"line":55,"column":52},"end":{"line":56,"column":53}},"locations":[{"start":{"line":55,"column":52},"end":{"line":56,"column":53}}]},"54":{"type":"branch","line":56,"loc":{"start":{"line":56,"column":46},"end":{"line":56,"column":74}},"locations":[{"start":{"line":56,"column":46},"end":{"line":56,"column":74}}]},"55":{"type":"branch","line":56,"loc":{"start":{"line":56,"column":53},"end":{"line":57,"column":54}},"locations":[{"start":{"line":56,"column":53},"end":{"line":57,"column":54}}]},"56":{"type":"branch","line":57,"loc":{"start":{"line":57,"column":47},"end":{"line":57,"column":76}},"locations":[{"start":{"line":57,"column":47},"end":{"line":57,"column":76}}]},"57":{"type":"branch","line":57,"loc":{"start":{"line":57,"column":54},"end":{"line":58,"column":51}},"locations":[{"start":{"line":57,"column":54},"end":{"line":58,"column":51}}]},"58":{"type":"branch","line":58,"loc":{"start":{"line":58,"column":44},"end":{"line":58,"column":70}},"locations":[{"start":{"line":58,"column":44},"end":{"line":58,"column":70}}]},"59":{"type":"branch","line":58,"loc":{"start":{"line":58,"column":51},"end":{"line":59,"column":50}},"locations":[{"start":{"line":58,"column":51},"end":{"line":59,"column":50}}]},"60":{"type":"branch","line":59,"loc":{"start":{"line":59,"column":43},"end":{"line":59,"column":68}},"locations":[{"start":{"line":59,"column":43},"end":{"line":59,"column":68}}]},"61":{"type":"branch","line":59,"loc":{"start":{"line":59,"column":50},"end":{"line":60,"column":49}},"locations":[{"start":{"line":59,"column":50},"end":{"line":60,"column":49}}]},"62":{"type":"branch","line":60,"loc":{"start":{"line":60,"column":42},"end":{"line":60,"column":66}},"locations":[{"start":{"line":60,"column":42},"end":{"line":60,"column":66}}]},"63":{"type":"branch","line":60,"loc":{"start":{"line":60,"column":49},"end":{"line":63,"column":24}},"locations":[{"start":{"line":60,"column":49},"end":{"line":63,"column":24}}]},"64":{"type":"branch","line":63,"loc":{"start":{"line":63,"column":24},"end":{"line":65,"column":5}},"locations":[{"start":{"line":63,"column":24},"end":{"line":65,"column":5}}]},"65":{"type":"branch","line":65,"loc":{"start":{"line":65,"column":4},"end":{"line":67,"column":3}},"locations":[{"start":{"line":65,"column":4},"end":{"line":67,"column":3}}]},"66":{"type":"branch","line":70,"loc":{"start":{"line":70,"column":18},"end":{"line":70,"column":39}},"locations":[{"start":{"line":70,"column":18},"end":{"line":70,"column":39}}]},"67":{"type":"branch","line":70,"loc":{"start":{"line":70,"column":39},"end":{"line":72,"column":5}},"locations":[{"start":{"line":70,"column":39},"end":{"line":72,"column":5}}]},"68":{"type":"branch","line":72,"loc":{"start":{"line":72,"column":4},"end":{"line":74,"column":23}},"locations":[{"start":{"line":72,"column":4},"end":{"line":74,"column":23}}]},"69":{"type":"branch","line":74,"loc":{"start":{"line":74,"column":30},"end":{"line":76,"column":5}},"locations":[{"start":{"line":74,"column":30},"end":{"line":76,"column":5}}]},"70":{"type":"branch","line":76,"loc":{"start":{"line":76,"column":4},"end":{"line":79,"column":43}},"locations":[{"start":{"line":76,"column":4},"end":{"line":79,"column":43}}]},"71":{"type":"branch","line":80,"loc":{"start":{"line":80,"column":2},"end":{"line":83,"column":1}},"locations":[{"start":{"line":80,"column":2},"end":{"line":83,"column":1}}]},"72":{"type":"branch","line":101,"loc":{"start":{"line":101,"column":2},"end":{"line":113,"column":3}},"locations":[{"start":{"line":101,"column":2},"end":{"line":113,"column":3}}]},"73":{"type":"branch","line":102,"loc":{"start":{"line":102,"column":27},"end":{"line":102,"column":56}},"locations":[{"start":{"line":102,"column":27},"end":{"line":102,"column":56}}]},"74":{"type":"branch","line":103,"loc":{"start":{"line":103,"column":26},"end":{"line":103,"column":53}},"locations":[{"start":{"line":103,"column":26},"end":{"line":103,"column":53}}]},"75":{"type":"branch","line":110,"loc":{"start":{"line":110,"column":34},"end":{"line":110,"column":58}},"locations":[{"start":{"line":110,"column":34},"end":{"line":110,"column":58}}]},"76":{"type":"branch","line":115,"loc":{"start":{"line":115,"column":2},"end":{"line":118,"column":3}},"locations":[{"start":{"line":115,"column":2},"end":{"line":118,"column":3}}]},"77":{"type":"branch","line":120,"loc":{"start":{"line":120,"column":2},"end":{"line":123,"column":3}},"locations":[{"start":{"line":120,"column":2},"end":{"line":123,"column":3}}]},"78":{"type":"branch","line":125,"loc":{"start":{"line":125,"column":2},"end":{"line":128,"column":3}},"locations":[{"start":{"line":125,"column":2},"end":{"line":128,"column":3}}]},"79":{"type":"branch","line":130,"loc":{"start":{"line":130,"column":2},"end":{"line":134,"column":3}},"locations":[{"start":{"line":130,"column":2},"end":{"line":134,"column":3}}]},"80":{"type":"branch","line":136,"loc":{"start":{"line":136,"column":2},"end":{"line":143,"column":3}},"locations":[{"start":{"line":136,"column":2},"end":{"line":143,"column":3}}]},"81":{"type":"branch","line":139,"loc":{"start":{"line":139,"column":8},"end":{"line":139,"column":40}},"locations":[{"start":{"line":139,"column":8},"end":{"line":139,"column":40}}]},"82":{"type":"branch","line":139,"loc":{"start":{"line":139,"column":40},"end":{"line":141,"column":5}},"locations":[{"start":{"line":139,"column":40},"end":{"line":141,"column":5}}]},"83":{"type":"branch","line":145,"loc":{"start":{"line":145,"column":2},"end":{"line":164,"column":3}},"locations":[{"start":{"line":145,"column":2},"end":{"line":164,"column":3}}]},"84":{"type":"branch","line":147,"loc":{"start":{"line":147,"column":22},"end":{"line":147,"column":38}},"locations":[{"start":{"line":147,"column":22},"end":{"line":147,"column":38}}]},"85":{"type":"branch","line":159,"loc":{"start":{"line":159,"column":8},"end":{"line":159,"column":25}},"locations":[{"start":{"line":159,"column":8},"end":{"line":159,"column":25}}]},"86":{"type":"branch","line":159,"loc":{"start":{"line":159,"column":25},"end":{"line":161,"column":5}},"locations":[{"start":{"line":159,"column":25},"end":{"line":161,"column":5}}]},"87":{"type":"branch","line":166,"loc":{"start":{"line":166,"column":2},"end":{"line":177,"column":3}},"locations":[{"start":{"line":166,"column":2},"end":{"line":177,"column":3}}]},"88":{"type":"branch","line":167,"loc":{"start":{"line":167,"column":26},"end":{"line":167,"column":33}},"locations":[{"start":{"line":167,"column":26},"end":{"line":167,"column":33}}]},"89":{"type":"branch","line":167,"loc":{"start":{"line":167,"column":26},"end":{"line":169,"column":40}},"locations":[{"start":{"line":167,"column":26},"end":{"line":169,"column":40}}]},"90":{"type":"branch","line":169,"loc":{"start":{"line":169,"column":24},"end":{"line":169,"column":46}},"locations":[{"start":{"line":169,"column":24},"end":{"line":169,"column":46}}]},"91":{"type":"branch","line":171,"loc":{"start":{"line":171,"column":22},"end":{"line":176,"column":5}},"locations":[{"start":{"line":171,"column":22},"end":{"line":176,"column":5}}]},"92":{"type":"branch","line":173,"loc":{"start":{"line":173,"column":25},"end":{"line":173,"column":57}},"locations":[{"start":{"line":173,"column":25},"end":{"line":173,"column":57}}]},"93":{"type":"branch","line":173,"loc":{"start":{"line":173,"column":57},"end":{"line":175,"column":7}},"locations":[{"start":{"line":173,"column":57},"end":{"line":175,"column":7}}]},"94":{"type":"branch","line":179,"loc":{"start":{"line":179,"column":2},"end":{"line":185,"column":3}},"locations":[{"start":{"line":179,"column":2},"end":{"line":185,"column":3}}]},"95":{"type":"branch","line":180,"loc":{"start":{"line":180,"column":25},"end":{"line":180,"column":46}},"locations":[{"start":{"line":180,"column":25},"end":{"line":180,"column":46}}]},"96":{"type":"branch","line":181,"loc":{"start":{"line":181,"column":36},"end":{"line":181,"column":53}},"locations":[{"start":{"line":181,"column":36},"end":{"line":181,"column":53}}]},"97":{"type":"branch","line":181,"loc":{"start":{"line":181,"column":48},"end":{"line":181,"column":73}},"locations":[{"start":{"line":181,"column":48},"end":{"line":181,"column":73}}]},"98":{"type":"branch","line":181,"loc":{"start":{"line":181,"column":53},"end":{"line":181,"column":69}},"locations":[{"start":{"line":181,"column":53},"end":{"line":181,"column":69}}]},"99":{"type":"branch","line":181,"loc":{"start":{"line":181,"column":63},"end":{"line":181,"column":73}},"locations":[{"start":{"line":181,"column":63},"end":{"line":181,"column":73}}]},"100":{"type":"branch","line":182,"loc":{"start":{"line":182,"column":11},"end":{"line":183,"column":55}},"locations":[{"start":{"line":182,"column":11},"end":{"line":183,"column":55}}]},"101":{"type":"branch","line":183,"loc":{"start":{"line":183,"column":53},"end":{"line":184,"column":41}},"locations":[{"start":{"line":183,"column":53},"end":{"line":184,"column":41}}]},"102":{"type":"branch","line":187,"loc":{"start":{"line":187,"column":2},"end":{"line":200,"column":3}},"locations":[{"start":{"line":187,"column":2},"end":{"line":200,"column":3}}]},"103":{"type":"branch","line":195,"loc":{"start":{"line":195,"column":44},"end":{"line":195,"column":67}},"locations":[{"start":{"line":195,"column":44},"end":{"line":195,"column":67}}]},"104":{"type":"branch","line":195,"loc":{"start":{"line":195,"column":63},"end":{"line":195,"column":77}},"locations":[{"start":{"line":195,"column":63},"end":{"line":195,"column":77}}]},"105":{"type":"branch","line":196,"loc":{"start":{"line":196,"column":44},"end":{"line":196,"column":67}},"locations":[{"start":{"line":196,"column":44},"end":{"line":196,"column":67}}]},"106":{"type":"branch","line":196,"loc":{"start":{"line":196,"column":63},"end":{"line":196,"column":77}},"locations":[{"start":{"line":196,"column":63},"end":{"line":196,"column":77}}]},"107":{"type":"branch","line":198,"loc":{"start":{"line":198,"column":22},"end":{"line":198,"column":58}},"locations":[{"start":{"line":198,"column":22},"end":{"line":198,"column":58}}]},"108":{"type":"branch","line":215,"loc":{"start":{"line":215,"column":2},"end":{"line":227,"column":3}},"locations":[{"start":{"line":215,"column":2},"end":{"line":227,"column":3}}]},"109":{"type":"branch","line":224,"loc":{"start":{"line":224,"column":32},"end":{"line":226,"column":5}},"locations":[{"start":{"line":224,"column":32},"end":{"line":226,"column":5}}]},"110":{"type":"branch","line":229,"loc":{"start":{"line":229,"column":2},"end":{"line":235,"column":3}},"locations":[{"start":{"line":229,"column":2},"end":{"line":235,"column":3}}]},"111":{"type":"branch","line":230,"loc":{"start":{"line":230,"column":44},"end":{"line":233,"column":5}},"locations":[{"start":{"line":230,"column":44},"end":{"line":233,"column":5}}]},"112":{"type":"branch","line":233,"loc":{"start":{"line":233,"column":4},"end":{"line":234,"column":26}},"locations":[{"start":{"line":233,"column":4},"end":{"line":234,"column":26}}]},"113":{"type":"branch","line":237,"loc":{"start":{"line":237,"column":10},"end":{"line":250,"column":3}},"locations":[{"start":{"line":237,"column":10},"end":{"line":250,"column":3}}]},"114":{"type":"branch","line":238,"loc":{"start":{"line":238,"column":24},"end":{"line":248,"column":5}},"locations":[{"start":{"line":238,"column":24},"end":{"line":248,"column":5}}]},"115":{"type":"branch","line":252,"loc":{"start":{"line":252,"column":2},"end":{"line":256,"column":3}},"locations":[{"start":{"line":252,"column":2},"end":{"line":256,"column":3}}]},"116":{"type":"branch","line":258,"loc":{"start":{"line":258,"column":2},"end":{"line":271,"column":3}},"locations":[{"start":{"line":258,"column":2},"end":{"line":271,"column":3}}]},"117":{"type":"branch","line":260,"loc":{"start":{"line":260,"column":30},"end":{"line":262,"column":11}},"locations":[{"start":{"line":260,"column":30},"end":{"line":262,"column":11}}]},"118":{"type":"branch","line":262,"loc":{"start":{"line":262,"column":4},"end":{"line":264,"column":5}},"locations":[{"start":{"line":262,"column":4},"end":{"line":264,"column":5}}]},"119":{"type":"branch","line":265,"loc":{"start":{"line":265,"column":31},"end":{"line":267,"column":11}},"locations":[{"start":{"line":265,"column":31},"end":{"line":267,"column":11}}]},"120":{"type":"branch","line":267,"loc":{"start":{"line":267,"column":4},"end":{"line":269,"column":5}},"locations":[{"start":{"line":267,"column":4},"end":{"line":269,"column":5}}]},"121":{"type":"branch","line":273,"loc":{"start":{"line":273,"column":2},"end":{"line":276,"column":3}},"locations":[{"start":{"line":273,"column":2},"end":{"line":276,"column":3}}]},"122":{"type":"branch","line":282,"loc":{"start":{"line":282,"column":2},"end":{"line":297,"column":3}},"locations":[{"start":{"line":282,"column":2},"end":{"line":297,"column":3}}]},"123":{"type":"branch","line":283,"loc":{"start":{"line":283,"column":26},"end":{"line":283,"column":33}},"locations":[{"start":{"line":283,"column":26},"end":{"line":283,"column":33}}]},"124":{"type":"branch","line":286,"loc":{"start":{"line":286,"column":38},"end":{"line":289,"column":5}},"locations":[{"start":{"line":286,"column":38},"end":{"line":289,"column":5}}]},"125":{"type":"branch","line":293,"loc":{"start":{"line":293,"column":25},"end":{"line":293,"column":64}},"locations":[{"start":{"line":293,"column":25},"end":{"line":293,"column":64}}]},"126":{"type":"branch","line":293,"loc":{"start":{"line":293,"column":64},"end":{"line":295,"column":7}},"locations":[{"start":{"line":293,"column":64},"end":{"line":295,"column":7}}]},"127":{"type":"branch","line":299,"loc":{"start":{"line":299,"column":10},"end":{"line":310,"column":3}},"locations":[{"start":{"line":299,"column":10},"end":{"line":310,"column":3}}]},"128":{"type":"branch","line":301,"loc":{"start":{"line":301,"column":6},"end":{"line":302,"column":21}},"locations":[{"start":{"line":301,"column":6},"end":{"line":302,"column":21}}]},"129":{"type":"branch","line":303,"loc":{"start":{"line":303,"column":6},"end":{"line":304,"column":23}},"locations":[{"start":{"line":303,"column":6},"end":{"line":304,"column":23}}]},"130":{"type":"branch","line":305,"loc":{"start":{"line":305,"column":6},"end":{"line":306,"column":20}},"locations":[{"start":{"line":305,"column":6},"end":{"line":306,"column":20}}]},"131":{"type":"branch","line":312,"loc":{"start":{"line":312,"column":2},"end":{"line":342,"column":3}},"locations":[{"start":{"line":312,"column":2},"end":{"line":342,"column":3}}]},"132":{"type":"branch","line":338,"loc":{"start":{"line":338,"column":40},"end":{"line":338,"column":51}},"locations":[{"start":{"line":338,"column":40},"end":{"line":338,"column":51}}]},"133":{"type":"branch","line":327,"loc":{"start":{"line":327,"column":28},"end":{"line":327,"column":45}},"locations":[{"start":{"line":327,"column":28},"end":{"line":327,"column":45}}]},"134":{"type":"branch","line":344,"loc":{"start":{"line":344,"column":2},"end":{"line":353,"column":3}},"locations":[{"start":{"line":344,"column":2},"end":{"line":353,"column":3}}]},"135":{"type":"branch","line":350,"loc":{"start":{"line":350,"column":28},"end":{"line":350,"column":45}},"locations":[{"start":{"line":350,"column":28},"end":{"line":350,"column":45}}]}},"b":{"0":[81],"1":[98],"2":[21],"3":[6],"4":[15],"5":[1],"6":[14],"7":[1],"8":[13],"9":[1],"10":[12],"11":[4],"12":[8],"13":[1],"14":[7],"15":[1],"16":[6],"17":[1],"18":[5],"19":[5],"20":[0],"21":[17],"22":[16],"23":[15],"24":[3],"25":[14],"26":[2],"27":[12],"28":[11],"29":[5],"30":[9],"31":[3],"32":[6],"33":[2],"34":[4],"35":[2],"36":[0],"37":[13],"38":[1],"39":[12],"40":[6],"41":[4],"42":[3],"43":[2],"44":[2],"45":[1],"46":[0],"47":[1],"48":[0],"49":[1],"50":[0],"51":[1],"52":[0],"53":[1],"54":[0],"55":[1],"56":[0],"57":[1],"58":[0],"59":[1],"60":[0],"61":[1],"62":[0],"63":[1],"64":[0],"65":[1],"66":[4],"67":[4],"68":[2],"69":[2],"70":[0],"71":[0],"72":[99],"73":[81],"74":[98],"75":[98],"76":[11],"77":[4],"78":[28],"79":[4],"80":[4],"81":[1],"82":[1],"83":[16],"84":[15],"85":[15],"86":[13],"87":[22],"88":[1],"89":[21],"90":[20],"91":[17],"92":[0],"93":[0],"94":[3],"95":[2],"96":[1],"97":[2],"98":[1],"99":[1],"100":[2],"101":[1],"102":[31],"103":[1],"104":[30],"105":[1],"106":[30],"107":[17],"108":[42],"109":[2],"110":[13],"111":[1],"112":[12],"113":[13],"114":[7],"115":[1],"116":[5],"117":[4],"118":[1],"119":[2],"120":[3],"121":[7],"122":[17],"123":[0],"124":[13],"125":[0],"126":[0],"127":[14],"128":[0],"129":[0],"130":[0],"131":[14],"132":[0],"133":[6],"134":[15],"135":[8]},"fnMap":{"0":{"name":"generateTraceId","decl":{"start":{"line":5,"column":0},"end":{"line":7,"column":1}},"loc":{"start":{"line":5,"column":0},"end":{"line":7,"column":1}},"line":5},"1":{"name":"generateSpanId","decl":{"start":{"line":9,"column":0},"end":{"line":11,"column":1}},"loc":{"start":{"line":9,"column":0},"end":{"line":11,"column":1}},"line":9},"2":{"name":"httpStatusToSpanStatus","decl":{"start":{"line":13,"column":7},"end":{"line":24,"column":1}},"loc":{"start":{"line":13,"column":7},"end":{"line":24,"column":1}},"line":13},"3":{"name":"dbStatusToSpanStatus","decl":{"start":{"line":26,"column":7},"end":{"line":40,"column":1}},"loc":{"start":{"line":26,"column":7},"end":{"line":40,"column":1}},"line":26},"4":{"name":"statusToSpanStatus","decl":{"start":{"line":42,"column":7},"end":{"line":83,"column":1}},"loc":{"start":{"line":42,"column":7},"end":{"line":83,"column":1}},"line":42},"5":{"name":"Span","decl":{"start":{"line":101,"column":2},"end":{"line":113,"column":3}},"loc":{"start":{"line":101,"column":2},"end":{"line":113,"column":3}},"line":101},"6":{"name":"setTag","decl":{"start":{"line":115,"column":2},"end":{"line":118,"column":3}},"loc":{"start":{"line":115,"column":2},"end":{"line":118,"column":3}},"line":115},"7":{"name":"setData","decl":{"start":{"line":120,"column":2},"end":{"line":123,"column":3}},"loc":{"start":{"line":120,"column":2},"end":{"line":123,"column":3}},"line":120},"8":{"name":"setStatus","decl":{"start":{"line":125,"column":2},"end":{"line":128,"column":3}},"loc":{"start":{"line":125,"column":2},"end":{"line":128,"column":3}},"line":125},"9":{"name":"setHttpStatus","decl":{"start":{"line":130,"column":2},"end":{"line":134,"column":3}},"loc":{"start":{"line":130,"column":2},"end":{"line":134,"column":3}},"line":130},"10":{"name":"setStatusFromResponse","decl":{"start":{"line":136,"column":2},"end":{"line":143,"column":3}},"loc":{"start":{"line":136,"column":2},"end":{"line":143,"column":3}},"line":136},"11":{"name":"startChild","decl":{"start":{"line":145,"column":2},"end":{"line":164,"column":3}},"loc":{"start":{"line":145,"column":2},"end":{"line":164,"column":3}},"line":145},"12":{"name":"finish","decl":{"start":{"line":166,"column":2},"end":{"line":177,"column":3}},"loc":{"start":{"line":166,"column":2},"end":{"line":177,"column":3}},"line":166},"13":{"name":"toTraceparent","decl":{"start":{"line":179,"column":2},"end":{"line":185,"column":3}},"loc":{"start":{"line":179,"column":2},"end":{"line":185,"column":3}},"line":179},"14":{"name":"toJSON","decl":{"start":{"line":187,"column":2},"end":{"line":200,"column":3}},"loc":{"start":{"line":187,"column":2},"end":{"line":200,"column":3}},"line":187},"15":{"name":"Transaction","decl":{"start":{"line":215,"column":2},"end":{"line":227,"column":3}},"loc":{"start":{"line":215,"column":2},"end":{"line":227,"column":3}},"line":215},"16":{"name":"_addSpan","decl":{"start":{"line":229,"column":2},"end":{"line":235,"column":3}},"loc":{"start":{"line":229,"column":2},"end":{"line":235,"column":3}},"line":229},"17":{"name":"_ensureBaggage","decl":{"start":{"line":237,"column":10},"end":{"line":250,"column":3}},"loc":{"start":{"line":237,"column":10},"end":{"line":250,"column":3}},"line":237},"18":{"name":"setBaggage","decl":{"start":{"line":252,"column":2},"end":{"line":256,"column":3}},"loc":{"start":{"line":252,"column":2},"end":{"line":256,"column":3}},"line":252},"19":{"name":"setUserBaggage","decl":{"start":{"line":258,"column":2},"end":{"line":271,"column":3}},"loc":{"start":{"line":258,"column":2},"end":{"line":271,"column":3}},"line":258},"20":{"name":"toBaggage","decl":{"start":{"line":273,"column":2},"end":{"line":276,"column":3}},"loc":{"start":{"line":273,"column":2},"end":{"line":276,"column":3}},"line":273},"21":{"name":"getBaggage","decl":{"start":{"line":278,"column":2},"end":{"line":280,"column":3}},"loc":{"start":{"line":278,"column":2},"end":{"line":280,"column":3}},"line":278},"22":{"name":"finish","decl":{"start":{"line":282,"column":2},"end":{"line":297,"column":3}},"loc":{"start":{"line":282,"column":2},"end":{"line":297,"column":3}},"line":282},"23":{"name":"_getSource","decl":{"start":{"line":299,"column":10},"end":{"line":310,"column":3}},"loc":{"start":{"line":299,"column":10},"end":{"line":310,"column":3}},"line":299},"24":{"name":"toEvent","decl":{"start":{"line":312,"column":2},"end":{"line":342,"column":3}},"loc":{"start":{"line":312,"column":2},"end":{"line":342,"column":3}},"line":312},"25":{"name":"toJSON","decl":{"start":{"line":344,"column":2},"end":{"line":353,"column":3}},"loc":{"start":{"line":344,"column":2},"end":{"line":353,"column":3}},"line":344}},"f":{"0":81,"1":98,"2":21,"3":17,"4":13,"5":99,"6":11,"7":4,"8":28,"9":4,"10":4,"11":16,"12":22,"13":3,"14":31,"15":42,"16":13,"17":13,"18":1,"19":5,"20":7,"21":0,"22":17,"23":14,"24":14,"25":15}} +} diff --git a/coverage/favicon.png b/coverage/favicon.png new file mode 100644 index 0000000000000000000000000000000000000000..c1525b811a167671e9de1fa78aab9f5c0b61cef7 GIT binary patch literal 445 zcmV;u0Yd(XP))rP{nL}Ln%S7`m{0DjX9TLF* zFCb$4Oi7vyLOydb!7n&^ItCzb-%BoB`=x@N2jll2Nj`kauio%aw_@fe&*}LqlFT43 z8doAAe))z_%=P%v^@JHp3Hjhj^6*Kr_h|g_Gr?ZAa&y>wxHE99Gk>A)2MplWz2xdG zy8VD2J|Uf#EAw*bo5O*PO_}X2Tob{%bUoO2G~T`@%S6qPyc}VkhV}UifBuRk>%5v( z)x7B{I~z*k<7dv#5tC+m{km(D087J4O%+<<;K|qwefb6@GSX45wCK}Sn*> + + + + Code coverage report for All files + + + + + + + + + +
+
+

All files

+
+ +
+ 49.43% + Statements + 2635/5330 +
+ + +
+ 87.24% + Branches + 513/588 +
+ + +
+ 41.97% + Functions + 123/293 +
+ + +
+ 49.43% + Lines + 2635/5330 +
+ + +
+

+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +

+ +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FileStatementsBranchesFunctionsLines
src +
+
50.39%127/252100%0/00%0/2150.39%127/252
src/core +
+
60.64%974/160685.78%169/19752%52/10060.64%974/1606
src/plugins +
+
18.25%426/233489.28%25/287.47%8/10718.25%426/2334
src/utils +
+
97.36%1108/113887.87%319/36396.92%63/6597.36%1108/1138
+
+
+
+ + + + + + + + \ No newline at end of file diff --git a/coverage/prettify.css b/coverage/prettify.css new file mode 100644 index 0000000..b317a7c --- /dev/null +++ b/coverage/prettify.css @@ -0,0 +1 @@ +.pln{color:#000}@media screen{.str{color:#080}.kwd{color:#008}.com{color:#800}.typ{color:#606}.lit{color:#066}.pun,.opn,.clo{color:#660}.tag{color:#008}.atn{color:#606}.atv{color:#080}.dec,.var{color:#606}.fun{color:red}}@media print,projection{.str{color:#060}.kwd{color:#006;font-weight:bold}.com{color:#600;font-style:italic}.typ{color:#404;font-weight:bold}.lit{color:#044}.pun,.opn,.clo{color:#440}.tag{color:#006;font-weight:bold}.atn{color:#404}.atv{color:#060}}pre.prettyprint{padding:2px;border:1px solid #888}ol.linenums{margin-top:0;margin-bottom:0}li.L0,li.L1,li.L2,li.L3,li.L5,li.L6,li.L7,li.L8{list-style-type:none}li.L1,li.L3,li.L5,li.L7,li.L9{background:#eee} diff --git a/coverage/prettify.js b/coverage/prettify.js new file mode 100644 index 0000000..b322523 --- /dev/null +++ b/coverage/prettify.js @@ -0,0 +1,2 @@ +/* eslint-disable */ +window.PR_SHOULD_USE_CONTINUATION=true;(function(){var h=["break,continue,do,else,for,if,return,while"];var u=[h,"auto,case,char,const,default,double,enum,extern,float,goto,int,long,register,short,signed,sizeof,static,struct,switch,typedef,union,unsigned,void,volatile"];var p=[u,"catch,class,delete,false,import,new,operator,private,protected,public,this,throw,true,try,typeof"];var l=[p,"alignof,align_union,asm,axiom,bool,concept,concept_map,const_cast,constexpr,decltype,dynamic_cast,explicit,export,friend,inline,late_check,mutable,namespace,nullptr,reinterpret_cast,static_assert,static_cast,template,typeid,typename,using,virtual,where"];var x=[p,"abstract,boolean,byte,extends,final,finally,implements,import,instanceof,null,native,package,strictfp,super,synchronized,throws,transient"];var R=[x,"as,base,by,checked,decimal,delegate,descending,dynamic,event,fixed,foreach,from,group,implicit,in,interface,internal,into,is,lock,object,out,override,orderby,params,partial,readonly,ref,sbyte,sealed,stackalloc,string,select,uint,ulong,unchecked,unsafe,ushort,var"];var r="all,and,by,catch,class,else,extends,false,finally,for,if,in,is,isnt,loop,new,no,not,null,of,off,on,or,return,super,then,true,try,unless,until,when,while,yes";var w=[p,"debugger,eval,export,function,get,null,set,undefined,var,with,Infinity,NaN"];var s="caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,package,redo,require,sub,undef,unless,until,use,wantarray,while,BEGIN,END";var I=[h,"and,as,assert,class,def,del,elif,except,exec,finally,from,global,import,in,is,lambda,nonlocal,not,or,pass,print,raise,try,with,yield,False,True,None"];var f=[h,"alias,and,begin,case,class,def,defined,elsif,end,ensure,false,in,module,next,nil,not,or,redo,rescue,retry,self,super,then,true,undef,unless,until,when,yield,BEGIN,END"];var H=[h,"case,done,elif,esac,eval,fi,function,in,local,set,then,until"];var A=[l,R,w,s+I,f,H];var e=/^(DIR|FILE|vector|(de|priority_)?queue|list|stack|(const_)?iterator|(multi)?(set|map)|bitset|u?(int|float)\d*)/;var C="str";var z="kwd";var j="com";var O="typ";var G="lit";var L="pun";var F="pln";var m="tag";var E="dec";var J="src";var P="atn";var n="atv";var N="nocode";var M="(?:^^\\.?|[+-]|\\!|\\!=|\\!==|\\#|\\%|\\%=|&|&&|&&=|&=|\\(|\\*|\\*=|\\+=|\\,|\\-=|\\->|\\/|\\/=|:|::|\\;|<|<<|<<=|<=|=|==|===|>|>=|>>|>>=|>>>|>>>=|\\?|\\@|\\[|\\^|\\^=|\\^\\^|\\^\\^=|\\{|\\||\\|=|\\|\\||\\|\\|=|\\~|break|case|continue|delete|do|else|finally|instanceof|return|throw|try|typeof)\\s*";function k(Z){var ad=0;var S=false;var ac=false;for(var V=0,U=Z.length;V122)){if(!(al<65||ag>90)){af.push([Math.max(65,ag)|32,Math.min(al,90)|32])}if(!(al<97||ag>122)){af.push([Math.max(97,ag)&~32,Math.min(al,122)&~32])}}}}af.sort(function(av,au){return(av[0]-au[0])||(au[1]-av[1])});var ai=[];var ap=[NaN,NaN];for(var ar=0;arat[0]){if(at[1]+1>at[0]){an.push("-")}an.push(T(at[1]))}}an.push("]");return an.join("")}function W(al){var aj=al.source.match(new RegExp("(?:\\[(?:[^\\x5C\\x5D]|\\\\[\\s\\S])*\\]|\\\\u[A-Fa-f0-9]{4}|\\\\x[A-Fa-f0-9]{2}|\\\\[0-9]+|\\\\[^ux0-9]|\\(\\?[:!=]|[\\(\\)\\^]|[^\\x5B\\x5C\\(\\)\\^]+)","g"));var ah=aj.length;var an=[];for(var ak=0,am=0;ak=2&&ai==="["){aj[ak]=X(ag)}else{if(ai!=="\\"){aj[ak]=ag.replace(/[a-zA-Z]/g,function(ao){var ap=ao.charCodeAt(0);return"["+String.fromCharCode(ap&~32,ap|32)+"]"})}}}}return aj.join("")}var aa=[];for(var V=0,U=Z.length;V=0;){S[ac.charAt(ae)]=Y}}var af=Y[1];var aa=""+af;if(!ag.hasOwnProperty(aa)){ah.push(af);ag[aa]=null}}ah.push(/[\0-\uffff]/);V=k(ah)})();var X=T.length;var W=function(ah){var Z=ah.sourceCode,Y=ah.basePos;var ad=[Y,F];var af=0;var an=Z.match(V)||[];var aj={};for(var ae=0,aq=an.length;ae=5&&"lang-"===ap.substring(0,5);if(am&&!(ai&&typeof ai[1]==="string")){am=false;ap=J}if(!am){aj[ag]=ap}}var ab=af;af+=ag.length;if(!am){ad.push(Y+ab,ap)}else{var al=ai[1];var ak=ag.indexOf(al);var ac=ak+al.length;if(ai[2]){ac=ag.length-ai[2].length;ak=ac-al.length}var ar=ap.substring(5);B(Y+ab,ag.substring(0,ak),W,ad);B(Y+ab+ak,al,q(ar,al),ad);B(Y+ab+ac,ag.substring(ac),W,ad)}}ah.decorations=ad};return W}function i(T){var W=[],S=[];if(T.tripleQuotedStrings){W.push([C,/^(?:\'\'\'(?:[^\'\\]|\\[\s\S]|\'{1,2}(?=[^\']))*(?:\'\'\'|$)|\"\"\"(?:[^\"\\]|\\[\s\S]|\"{1,2}(?=[^\"]))*(?:\"\"\"|$)|\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$))/,null,"'\""])}else{if(T.multiLineStrings){W.push([C,/^(?:\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$)|\`(?:[^\\\`]|\\[\s\S])*(?:\`|$))/,null,"'\"`"])}else{W.push([C,/^(?:\'(?:[^\\\'\r\n]|\\.)*(?:\'|$)|\"(?:[^\\\"\r\n]|\\.)*(?:\"|$))/,null,"\"'"])}}if(T.verbatimStrings){S.push([C,/^@\"(?:[^\"]|\"\")*(?:\"|$)/,null])}var Y=T.hashComments;if(Y){if(T.cStyleComments){if(Y>1){W.push([j,/^#(?:##(?:[^#]|#(?!##))*(?:###|$)|.*)/,null,"#"])}else{W.push([j,/^#(?:(?:define|elif|else|endif|error|ifdef|include|ifndef|line|pragma|undef|warning)\b|[^\r\n]*)/,null,"#"])}S.push([C,/^<(?:(?:(?:\.\.\/)*|\/?)(?:[\w-]+(?:\/[\w-]+)+)?[\w-]+\.h|[a-z]\w*)>/,null])}else{W.push([j,/^#[^\r\n]*/,null,"#"])}}if(T.cStyleComments){S.push([j,/^\/\/[^\r\n]*/,null]);S.push([j,/^\/\*[\s\S]*?(?:\*\/|$)/,null])}if(T.regexLiterals){var X=("/(?=[^/*])(?:[^/\\x5B\\x5C]|\\x5C[\\s\\S]|\\x5B(?:[^\\x5C\\x5D]|\\x5C[\\s\\S])*(?:\\x5D|$))+/");S.push(["lang-regex",new RegExp("^"+M+"("+X+")")])}var V=T.types;if(V){S.push([O,V])}var U=(""+T.keywords).replace(/^ | $/g,"");if(U.length){S.push([z,new RegExp("^(?:"+U.replace(/[\s,]+/g,"|")+")\\b"),null])}W.push([F,/^\s+/,null," \r\n\t\xA0"]);S.push([G,/^@[a-z_$][a-z_$@0-9]*/i,null],[O,/^(?:[@_]?[A-Z]+[a-z][A-Za-z_$@0-9]*|\w+_t\b)/,null],[F,/^[a-z_$][a-z_$@0-9]*/i,null],[G,new RegExp("^(?:0x[a-f0-9]+|(?:\\d(?:_\\d+)*\\d*(?:\\.\\d*)?|\\.\\d\\+)(?:e[+\\-]?\\d+)?)[a-z]*","i"),null,"0123456789"],[F,/^\\[\s\S]?/,null],[L,/^.[^\s\w\.$@\'\"\`\/\#\\]*/,null]);return g(W,S)}var K=i({keywords:A,hashComments:true,cStyleComments:true,multiLineStrings:true,regexLiterals:true});function Q(V,ag){var U=/(?:^|\s)nocode(?:\s|$)/;var ab=/\r\n?|\n/;var ac=V.ownerDocument;var S;if(V.currentStyle){S=V.currentStyle.whiteSpace}else{if(window.getComputedStyle){S=ac.defaultView.getComputedStyle(V,null).getPropertyValue("white-space")}}var Z=S&&"pre"===S.substring(0,3);var af=ac.createElement("LI");while(V.firstChild){af.appendChild(V.firstChild)}var W=[af];function ae(al){switch(al.nodeType){case 1:if(U.test(al.className)){break}if("BR"===al.nodeName){ad(al);if(al.parentNode){al.parentNode.removeChild(al)}}else{for(var an=al.firstChild;an;an=an.nextSibling){ae(an)}}break;case 3:case 4:if(Z){var am=al.nodeValue;var aj=am.match(ab);if(aj){var ai=am.substring(0,aj.index);al.nodeValue=ai;var ah=am.substring(aj.index+aj[0].length);if(ah){var ak=al.parentNode;ak.insertBefore(ac.createTextNode(ah),al.nextSibling)}ad(al);if(!ai){al.parentNode.removeChild(al)}}}break}}function ad(ak){while(!ak.nextSibling){ak=ak.parentNode;if(!ak){return}}function ai(al,ar){var aq=ar?al.cloneNode(false):al;var ao=al.parentNode;if(ao){var ap=ai(ao,1);var an=al.nextSibling;ap.appendChild(aq);for(var am=an;am;am=an){an=am.nextSibling;ap.appendChild(am)}}return aq}var ah=ai(ak.nextSibling,0);for(var aj;(aj=ah.parentNode)&&aj.nodeType===1;){ah=aj}W.push(ah)}for(var Y=0;Y=S){ah+=2}if(V>=ap){Z+=2}}}var t={};function c(U,V){for(var S=V.length;--S>=0;){var T=V[S];if(!t.hasOwnProperty(T)){t[T]=U}else{if(window.console){console.warn("cannot override language handler %s",T)}}}}function q(T,S){if(!(T&&t.hasOwnProperty(T))){T=/^\s*]*(?:>|$)/],[j,/^<\!--[\s\S]*?(?:-\->|$)/],["lang-",/^<\?([\s\S]+?)(?:\?>|$)/],["lang-",/^<%([\s\S]+?)(?:%>|$)/],[L,/^(?:<[%?]|[%?]>)/],["lang-",/^]*>([\s\S]+?)<\/xmp\b[^>]*>/i],["lang-js",/^]*>([\s\S]*?)(<\/script\b[^>]*>)/i],["lang-css",/^]*>([\s\S]*?)(<\/style\b[^>]*>)/i],["lang-in.tag",/^(<\/?[a-z][^<>]*>)/i]]),["default-markup","htm","html","mxml","xhtml","xml","xsl"]);c(g([[F,/^[\s]+/,null," \t\r\n"],[n,/^(?:\"[^\"]*\"?|\'[^\']*\'?)/,null,"\"'"]],[[m,/^^<\/?[a-z](?:[\w.:-]*\w)?|\/?>$/i],[P,/^(?!style[\s=]|on)[a-z](?:[\w:-]*\w)?/i],["lang-uq.val",/^=\s*([^>\'\"\s]*(?:[^>\'\"\s\/]|\/(?=\s)))/],[L,/^[=<>\/]+/],["lang-js",/^on\w+\s*=\s*\"([^\"]+)\"/i],["lang-js",/^on\w+\s*=\s*\'([^\']+)\'/i],["lang-js",/^on\w+\s*=\s*([^\"\'>\s]+)/i],["lang-css",/^style\s*=\s*\"([^\"]+)\"/i],["lang-css",/^style\s*=\s*\'([^\']+)\'/i],["lang-css",/^style\s*=\s*([^\"\'>\s]+)/i]]),["in.tag"]);c(g([],[[n,/^[\s\S]+/]]),["uq.val"]);c(i({keywords:l,hashComments:true,cStyleComments:true,types:e}),["c","cc","cpp","cxx","cyc","m"]);c(i({keywords:"null,true,false"}),["json"]);c(i({keywords:R,hashComments:true,cStyleComments:true,verbatimStrings:true,types:e}),["cs"]);c(i({keywords:x,cStyleComments:true}),["java"]);c(i({keywords:H,hashComments:true,multiLineStrings:true}),["bsh","csh","sh"]);c(i({keywords:I,hashComments:true,multiLineStrings:true,tripleQuotedStrings:true}),["cv","py"]);c(i({keywords:s,hashComments:true,multiLineStrings:true,regexLiterals:true}),["perl","pl","pm"]);c(i({keywords:f,hashComments:true,multiLineStrings:true,regexLiterals:true}),["rb"]);c(i({keywords:w,cStyleComments:true,regexLiterals:true}),["js"]);c(i({keywords:r,hashComments:3,cStyleComments:true,multilineStrings:true,tripleQuotedStrings:true,regexLiterals:true}),["coffee"]);c(g([],[[C,/^[\s\S]+/]]),["regex"]);function d(V){var U=V.langExtension;try{var S=a(V.sourceNode);var T=S.sourceCode;V.sourceCode=T;V.spans=S.spans;V.basePos=0;q(U,T)(V);D(V)}catch(W){if("console" in window){console.log(W&&W.stack?W.stack:W)}}}function y(W,V,U){var S=document.createElement("PRE");S.innerHTML=W;if(U){Q(S,U)}var T={langExtension:V,numberLines:U,sourceNode:S};d(T);return S.innerHTML}function b(ad){function Y(af){return document.getElementsByTagName(af)}var ac=[Y("pre"),Y("code"),Y("xmp")];var T=[];for(var aa=0;aa=0){var ah=ai.match(ab);var am;if(!ah&&(am=o(aj))&&"CODE"===am.tagName){ah=am.className.match(ab)}if(ah){ah=ah[1]}var al=false;for(var ak=aj.parentNode;ak;ak=ak.parentNode){if((ak.tagName==="pre"||ak.tagName==="code"||ak.tagName==="xmp")&&ak.className&&ak.className.indexOf("prettyprint")>=0){al=true;break}}if(!al){var af=aj.className.match(/\blinenums\b(?::(\d+))?/);af=af?af[1]&&af[1].length?+af[1]:true:false;if(af){Q(aj,af)}S={langExtension:ah,sourceNode:aj,numberLines:af};d(S)}}}if(X]*(?:>|$)/],[PR.PR_COMMENT,/^<\!--[\s\S]*?(?:-\->|$)/],[PR.PR_PUNCTUATION,/^(?:<[%?]|[%?]>)/],["lang-",/^<\?([\s\S]+?)(?:\?>|$)/],["lang-",/^<%([\s\S]+?)(?:%>|$)/],["lang-",/^]*>([\s\S]+?)<\/xmp\b[^>]*>/i],["lang-handlebars",/^]*type\s*=\s*['"]?text\/x-handlebars-template['"]?\b[^>]*>([\s\S]*?)(<\/script\b[^>]*>)/i],["lang-js",/^]*>([\s\S]*?)(<\/script\b[^>]*>)/i],["lang-css",/^]*>([\s\S]*?)(<\/style\b[^>]*>)/i],["lang-in.tag",/^(<\/?[a-z][^<>]*>)/i],[PR.PR_DECLARATION,/^{{[#^>/]?\s*[\w.][^}]*}}/],[PR.PR_DECLARATION,/^{{&?\s*[\w.][^}]*}}/],[PR.PR_DECLARATION,/^{{{>?\s*[\w.][^}]*}}}/],[PR.PR_COMMENT,/^{{![^}]*}}/]]),["handlebars","hbs"]);PR.registerLangHandler(PR.createSimpleLexer([[PR.PR_PLAIN,/^[ \t\r\n\f]+/,null," \t\r\n\f"]],[[PR.PR_STRING,/^\"(?:[^\n\r\f\\\"]|\\(?:\r\n?|\n|\f)|\\[\s\S])*\"/,null],[PR.PR_STRING,/^\'(?:[^\n\r\f\\\']|\\(?:\r\n?|\n|\f)|\\[\s\S])*\'/,null],["lang-css-str",/^url\(([^\)\"\']*)\)/i],[PR.PR_KEYWORD,/^(?:url|rgb|\!important|@import|@page|@media|@charset|inherit)(?=[^\-\w]|$)/i,null],["lang-css-kw",/^(-?(?:[_a-z]|(?:\\[0-9a-f]+ ?))(?:[_a-z0-9\-]|\\(?:\\[0-9a-f]+ ?))*)\s*:/i],[PR.PR_COMMENT,/^\/\*[^*]*\*+(?:[^\/*][^*]*\*+)*\//],[PR.PR_COMMENT,/^(?:)/],[PR.PR_LITERAL,/^(?:\d+|\d*\.\d+)(?:%|[a-z]+)?/i],[PR.PR_LITERAL,/^#(?:[0-9a-f]{3}){1,2}/i],[PR.PR_PLAIN,/^-?(?:[_a-z]|(?:\\[\da-f]+ ?))(?:[_a-z\d\-]|\\(?:\\[\da-f]+ ?))*/i],[PR.PR_PUNCTUATION,/^[^\s\w\'\"]+/]]),["css"]);PR.registerLangHandler(PR.createSimpleLexer([],[[PR.PR_KEYWORD,/^-?(?:[_a-z]|(?:\\[\da-f]+ ?))(?:[_a-z\d\-]|\\(?:\\[\da-f]+ ?))*/i]]),["css-kw"]);PR.registerLangHandler(PR.createSimpleLexer([],[[PR.PR_STRING,/^[^\)\"\']+/]]),["css-str"]); diff --git a/coverage/sort-arrow-sprite.png b/coverage/sort-arrow-sprite.png new file mode 100644 index 0000000000000000000000000000000000000000..6ed68316eb3f65dec9063332d2f69bf3093bbfab GIT binary patch literal 138 zcmeAS@N?(olHy`uVBq!ia0vp^>_9Bd!3HEZxJ@+%Qh}Z>jv*C{$p!i!8j}?a+@3A= zIAGwzjijN=FBi!|L1t?LM;Q;gkwn>2cAy-KV{dn nf0J1DIvEHQu*n~6U}x}qyky7vi4|9XhBJ7&`njxgN@xNA8m%nc literal 0 HcmV?d00001 diff --git a/coverage/sorter.js b/coverage/sorter.js new file mode 100644 index 0000000..4ed70ae --- /dev/null +++ b/coverage/sorter.js @@ -0,0 +1,210 @@ +/* eslint-disable */ +var addSorting = (function() { + 'use strict'; + var cols, + currentSort = { + index: 0, + desc: false + }; + + // returns the summary table element + function getTable() { + return document.querySelector('.coverage-summary'); + } + // returns the thead element of the summary table + function getTableHeader() { + return getTable().querySelector('thead tr'); + } + // returns the tbody element of the summary table + function getTableBody() { + return getTable().querySelector('tbody'); + } + // returns the th element for nth column + function getNthColumn(n) { + return getTableHeader().querySelectorAll('th')[n]; + } + + function onFilterInput() { + const searchValue = document.getElementById('fileSearch').value; + const rows = document.getElementsByTagName('tbody')[0].children; + + // Try to create a RegExp from the searchValue. If it fails (invalid regex), + // it will be treated as a plain text search + let searchRegex; + try { + searchRegex = new RegExp(searchValue, 'i'); // 'i' for case-insensitive + } catch (error) { + searchRegex = null; + } + + for (let i = 0; i < rows.length; i++) { + const row = rows[i]; + let isMatch = false; + + if (searchRegex) { + // If a valid regex was created, use it for matching + isMatch = searchRegex.test(row.textContent); + } else { + // Otherwise, fall back to the original plain text search + isMatch = row.textContent + .toLowerCase() + .includes(searchValue.toLowerCase()); + } + + row.style.display = isMatch ? '' : 'none'; + } + } + + // loads the search box + function addSearchBox() { + var template = document.getElementById('filterTemplate'); + var templateClone = template.content.cloneNode(true); + templateClone.getElementById('fileSearch').oninput = onFilterInput; + template.parentElement.appendChild(templateClone); + } + + // loads all columns + function loadColumns() { + var colNodes = getTableHeader().querySelectorAll('th'), + colNode, + cols = [], + col, + i; + + for (i = 0; i < colNodes.length; i += 1) { + colNode = colNodes[i]; + col = { + key: colNode.getAttribute('data-col'), + sortable: !colNode.getAttribute('data-nosort'), + type: colNode.getAttribute('data-type') || 'string' + }; + cols.push(col); + if (col.sortable) { + col.defaultDescSort = col.type === 'number'; + colNode.innerHTML = + colNode.innerHTML + ''; + } + } + return cols; + } + // attaches a data attribute to every tr element with an object + // of data values keyed by column name + function loadRowData(tableRow) { + var tableCols = tableRow.querySelectorAll('td'), + colNode, + col, + data = {}, + i, + val; + for (i = 0; i < tableCols.length; i += 1) { + colNode = tableCols[i]; + col = cols[i]; + val = colNode.getAttribute('data-value'); + if (col.type === 'number') { + val = Number(val); + } + data[col.key] = val; + } + return data; + } + // loads all row data + function loadData() { + var rows = getTableBody().querySelectorAll('tr'), + i; + + for (i = 0; i < rows.length; i += 1) { + rows[i].data = loadRowData(rows[i]); + } + } + // sorts the table using the data for the ith column + function sortByIndex(index, desc) { + var key = cols[index].key, + sorter = function(a, b) { + a = a.data[key]; + b = b.data[key]; + return a < b ? -1 : a > b ? 1 : 0; + }, + finalSorter = sorter, + tableBody = document.querySelector('.coverage-summary tbody'), + rowNodes = tableBody.querySelectorAll('tr'), + rows = [], + i; + + if (desc) { + finalSorter = function(a, b) { + return -1 * sorter(a, b); + }; + } + + for (i = 0; i < rowNodes.length; i += 1) { + rows.push(rowNodes[i]); + tableBody.removeChild(rowNodes[i]); + } + + rows.sort(finalSorter); + + for (i = 0; i < rows.length; i += 1) { + tableBody.appendChild(rows[i]); + } + } + // removes sort indicators for current column being sorted + function removeSortIndicators() { + var col = getNthColumn(currentSort.index), + cls = col.className; + + cls = cls.replace(/ sorted$/, '').replace(/ sorted-desc$/, ''); + col.className = cls; + } + // adds sort indicators for current column being sorted + function addSortIndicators() { + getNthColumn(currentSort.index).className += currentSort.desc + ? ' sorted-desc' + : ' sorted'; + } + // adds event listeners for all sorter widgets + function enableUI() { + var i, + el, + ithSorter = function ithSorter(i) { + var col = cols[i]; + + return function() { + var desc = col.defaultDescSort; + + if (currentSort.index === i) { + desc = !currentSort.desc; + } + sortByIndex(i, desc); + removeSortIndicators(); + currentSort.index = i; + currentSort.desc = desc; + addSortIndicators(); + }; + }; + for (i = 0; i < cols.length; i += 1) { + if (cols[i].sortable) { + // add the click event handler on the th so users + // dont have to click on those tiny arrows + el = getNthColumn(i).querySelector('.sorter').parentElement; + if (el.addEventListener) { + el.addEventListener('click', ithSorter(i)); + } else { + el.attachEvent('onclick', ithSorter(i)); + } + } + } + } + // adds sorting functionality to the UI + return function() { + if (!getTable()) { + return; + } + cols = loadColumns(); + loadData(); + addSearchBox(); + addSortIndicators(); + enableUI(); + }; +})(); + +window.addEventListener('load', addSorting); diff --git a/coverage/src/core/Client.ts.html b/coverage/src/core/Client.ts.html new file mode 100644 index 0000000..77fb1b5 --- /dev/null +++ b/coverage/src/core/Client.ts.html @@ -0,0 +1,1177 @@ + + + + + + Code coverage report for src/core/Client.ts + + + + + + + + + +
+
+

All files / src/core Client.ts

+
+ +
+ 24.72% + Statements + 90/364 +
+ + +
+ 100% + Branches + 0/0 +
+ + +
+ 0% + Functions + 0/29 +
+ + +
+ 24.72% + Lines + 90/364 +
+ + +
+

+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +

+ +
+
+

+
1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +30 +31 +32 +33 +34 +35 +36 +37 +38 +39 +40 +41 +42 +43 +44 +45 +46 +47 +48 +49 +50 +51 +52 +53 +54 +55 +56 +57 +58 +59 +60 +61 +62 +63 +64 +65 +66 +67 +68 +69 +70 +71 +72 +73 +74 +75 +76 +77 +78 +79 +80 +81 +82 +83 +84 +85 +86 +87 +88 +89 +90 +91 +92 +93 +94 +95 +96 +97 +98 +99 +100 +101 +102 +103 +104 +105 +106 +107 +108 +109 +110 +111 +112 +113 +114 +115 +116 +117 +118 +119 +120 +121 +122 +123 +124 +125 +126 +127 +128 +129 +130 +131 +132 +133 +134 +135 +136 +137 +138 +139 +140 +141 +142 +143 +144 +145 +146 +147 +148 +149 +150 +151 +152 +153 +154 +155 +156 +157 +158 +159 +160 +161 +162 +163 +164 +165 +166 +167 +168 +169 +170 +171 +172 +173 +174 +175 +176 +177 +178 +179 +180 +181 +182 +183 +184 +185 +186 +187 +188 +189 +190 +191 +192 +193 +194 +195 +196 +197 +198 +199 +200 +201 +202 +203 +204 +205 +206 +207 +208 +209 +210 +211 +212 +213 +214 +215 +216 +217 +218 +219 +220 +221 +222 +223 +224 +225 +226 +227 +228 +229 +230 +231 +232 +233 +234 +235 +236 +237 +238 +239 +240 +241 +242 +243 +244 +245 +246 +247 +248 +249 +250 +251 +252 +253 +254 +255 +256 +257 +258 +259 +260 +261 +262 +263 +264 +265 +266 +267 +268 +269 +270 +271 +272 +273 +274 +275 +276 +277 +278 +279 +280 +281 +282 +283 +284 +285 +286 +287 +288 +289 +290 +291 +292 +293 +294 +295 +296 +297 +298 +299 +300 +301 +302 +303 +304 +305 +306 +307 +308 +309 +310 +311 +312 +313 +314 +315 +316 +317 +318 +319 +320 +321 +322 +323 +324 +325 +326 +327 +328 +329 +330 +331 +332 +333 +334 +335 +336 +337 +338 +339 +340 +341 +342 +343 +344 +345 +346 +347 +348 +349 +350 +351 +352 +353 +354 +355 +356 +357 +358 +359 +360 +361 +362 +363 +364 +3651x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +  +  +1x +1x +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +1x +1x +  +  +  +  +1x +1x +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +1x +1x +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +1x +1x +  +  +1x +1x +  +  +1x +1x +  +  +1x +1x +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +1x +1x +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +1x +1x +  +  +  +  +  +  +  +  +  +  +  +  +1x +1x +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +1x +1x +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +1x +1x +  +  +  +1x +1x +  +  +1x +1x +  +  +  +  +  +  +  +  +  +  +  +  +1x +1x +  +  +1x +1x +  +  +1x +1x +  +  +1x +1x +  +  +  +1x +1x +  +  +1x +1x +  +  +1x +1x +  +  +1x +1x +  +  +  +  +  +  +  +  +  +  +1x +1x +  +  +1x +1x +  +  +1x +1x +  +  +1x +1x +  +  +1x +1x +  +  +  +  +  +  +1x +1x +1x + 
import type { LightConfig, LightClient, LightPlugin, DSNInfo, SentryEvent, EventLevel, UserInfo, Breadcrumb, ErrorEvent, TransactionContext, SpanContext, Transaction, Span } from '../types';
+import { parseDSN } from '../utils/dsn';
+import { now } from '../utils/helper';
+import { computeFingerprint } from '../utils/hash';
+import { parseStackTrace } from '../utils/stacktrace';
+import { logDebug, setDebug } from '../utils/logger';
+import { setAnonymousId as setStoredAnonymousId } from '../utils/identity';
+import { ConfigManager } from './ConfigManager';
+import { EventBus } from './EventBus';
+import { EventQueue } from './EventQueue';
+import { Reporter } from './Reporter';
+import { PluginManager } from './PluginManager';
+import { TracingManager } from './TracingManager';
+ 
+class Client implements LightClient {
+  dsn: DSNInfo;
+  
+  private configManager: ConfigManager;
+  private eventBus: EventBus;
+  private queue: EventQueue;
+  private reporter: Reporter;
+  private pluginManager: PluginManager;
+  private tracingManager: TracingManager;
+  private breadcrumbs: Breadcrumb[] = [];
+  private enabled: boolean = true;
+ 
+  private get maxBreadcrumbs(): number {
+    return this.configManager.get('maxBreadcrumbs') ?? 20;
+  }
+ 
+  get config(): LightConfig {
+    return this.configManager.getAll();
+  }
+ 
+  constructor(config: LightConfig) {
+    if (!config.dsn) {
+      throw new Error('DSN is required');
+    }
+
+    setDebug(config.debug === true);
+    logDebug('Client', 'Initializing SDK', { dsn: config.dsn, debug: config.debug, enabled: config.enabled !== false });
+
+    this.dsn = parseDSN(config.dsn);
+    this.configManager = new ConfigManager(config);
+    this.eventBus = new EventBus();
+    this.reporter = new Reporter(
+      this.dsn,
+      this.configManager.get('maxRetries') ?? 3,
+      this.configManager.get('retryDelay') ?? 1000
+    );
+    this.pluginManager = new PluginManager(this);
+    this.tracingManager = new TracingManager(config, this, this.dsn.publicKey);
+    this.queue = new EventQueue(
+      this.configManager.get('maxQueueSize') ?? 100,
+      this.configManager.get('flushInterval') ?? 5000,
+      this.eventBus,
+      async (events) => this.flushEvents(events),
+      (events) => this.syncFlushEvents(events)
+    );
+
+    this.enabled = this.configManager.get('enabled') !== false;
+    logDebug('Client', 'SDK initialized', { enabled: this.enabled });
+  }
+ 
+  init(): void {
+    if (!this.enabled) return;
+    this.queue.start();
+    this.emit('ready');
+  }
+ 
+  private async flushEvents(events: SentryEvent[]): Promise<void> {
+    logDebug('Client', 'flushEvents start', { eventCount: events.length });
+
+    const processedEvents: SentryEvent[] = [];
+
+    for (const event of events) {
+      const processed = this.pluginManager.applyBeforeReport(event);
+      if (processed) {
+        processedEvents.push(processed);
+      } else {
+        logDebug('Client', 'Event filtered by beforeReport plugin', { type: event.type, message: 'message' in event ? event.message : undefined });
+      }
+    }
+
+    if (processedEvents.length === 0) {
+      logDebug('Client', 'flushEvents: all events filtered by beforeReport');
+      return;
+    }
+
+    let isFirstInBatch = true;
+    const finalEvents: SentryEvent[] = [];
+    
+    for (const event of processedEvents) {
+      const withConfig = this.configManager.applyToEvent(event, isFirstInBatch);
+      isFirstInBatch = false;
+      
+      const beforeSend = this.configManager.get('beforeSend');
+      const afterBeforeSend = beforeSend ? beforeSend(withConfig) : withConfig;
+      if (!afterBeforeSend) {
+        logDebug('Client', 'Event filtered by beforeSend', { type: event.type });
+        continue;
+      }
+
+      finalEvents.push(afterBeforeSend);
+    }
+
+    if (finalEvents.length === 0) {
+      logDebug('Client', 'flushEvents: all events filtered by beforeSend');
+      return;
+    }
+
+    logDebug('Client', 'Reporting events', { count: finalEvents.length });
+    await this.reporter.report(finalEvents);
+    logDebug('Client', 'Report completed successfully');
+    this.configManager.markContextReported();
+
+    for (const event of finalEvents) {
+      this.pluginManager.applyAfterReport(event);
+    }
+  }
+ 
+  private syncFlushEvents(events: SentryEvent[]): void {
+    const processedEvents: SentryEvent[] = [];
+
+    for (const event of events) {
+      const processed = this.pluginManager.applyBeforeReport(event);
+      if (processed) {
+        processedEvents.push(processed);
+      }
+    }
+
+    if (processedEvents.length === 0) return;
+
+    let isFirstInBatch = true;
+    const finalEvents: SentryEvent[] = [];
+    
+    for (const event of processedEvents) {
+      const withConfig = this.configManager.applyToEvent(event, isFirstInBatch);
+      isFirstInBatch = false;
+      
+      const beforeSend = this.configManager.get('beforeSend');
+      const afterBeforeSend = beforeSend ? beforeSend(withConfig) : withConfig;
+      if (!afterBeforeSend) continue;
+
+      finalEvents.push(afterBeforeSend);
+    }
+
+    if (finalEvents.length === 0) return;
+
+    this.reporter.reportSync(finalEvents);
+    this.configManager.markContextReported();
+  }
+ 
+  on(event: string, handler: (...args: unknown[]) => void): void {
+    this.eventBus.on(event, handler);
+  }
+ 
+  off(event: string, handler: (...args: unknown[]) => void): void {
+    this.eventBus.off(event, handler);
+  }
+ 
+  emit(event: string, ...args: unknown[]): void {
+    this.eventBus.emit(event, ...args);
+  }
+ 
+  captureException(error: Error | unknown): void {
+    logDebug('Client', 'captureException called', { error: error instanceof Error ? error.message : String(error) });
+
+    if (!this.enabled) {
+      logDebug('Client', 'captureException skipped: SDK disabled');
+      return;
+    }
+
+    const errorEvent = this.buildErrorEvent(error);
+    logDebug('Client', 'Error event built', { type: errorEvent.type, message: errorEvent.message, fingerprint: (errorEvent as ErrorEvent).fingerprint });
+
+    if (this.configManager.isIgnoredError(errorEvent.message)) {
+      logDebug('Client', 'captureException skipped: error ignored by ignoreErrors');
+      return;
+    }
+
+    this.attachTraceContext(errorEvent);
+    errorEvent.breadcrumbs = [...this.breadcrumbs];
+    logDebug('Client', 'Enqueue error event', { breadcrumbs: this.breadcrumbs.length });
+    this.queue.enqueue(errorEvent);
+  }
+ 
+  captureMessage(message: string, level: EventLevel = 'info'): void {
+    if (!this.enabled) return;
+
+    const event: ErrorEvent = {
+      type: 'error',
+      level,
+      message,
+      timestamp: now(),
+      breadcrumbs: [...this.breadcrumbs],
+    };
+
+    if (this.configManager.isIgnoredError(message)) return;
+
+    this.attachTraceContext(event);
+    this.queue.enqueue(event);
+  }
+ 
+  captureEvent(event: Partial<SentryEvent> & { type: string }): void {
+    if (!this.enabled) return;
+
+    const fullEvent = {
+      timestamp: now(),
+      level: 'info' as EventLevel,
+      breadcrumbs: [...this.breadcrumbs],
+      ...event,
+    } as SentryEvent;
+
+    this.attachTraceContext(fullEvent);
+    this.queue.enqueue(fullEvent);
+  }
+ 
+  private attachTraceContext(event: SentryEvent): void {
+    const currentSpan = this.tracingManager.getCurrentSpan();
+    const currentTransaction = this.tracingManager.getCurrentTransaction();
+
+    if (currentSpan || currentTransaction) {
+      const traceId = currentSpan?.traceId || currentTransaction?.traceId;
+      const spanId = currentSpan?.spanId || currentTransaction?.spanId;
+      const parentSpanId = currentSpan?.parentSpanId;
+      const op = currentSpan?.op || currentTransaction?.op;
+      const status = currentSpan?.status || currentTransaction?.status;
+
+      event.contexts = {
+        ...event.contexts,
+        trace: {
+          trace_id: traceId || '',
+          span_id: spanId || '',
+          parent_span_id: parentSpanId,
+          op,
+          status,
+        },
+      };
+    }
+  }
+ 
+  private buildErrorEvent(error: Error | unknown): ErrorEvent {
+    const timestamp = now();
+    
+    if (error instanceof Error) {
+      const frames = parseStackTrace(error.stack, { maxFrames: 5 });
+      const fingerprint = computeFingerprint(error.name, error.message, frames);
+      
+      return {
+        type: 'error',
+        level: 'error',
+        message: error.message,
+        timestamp,
+        exception: {
+          type: error.name,
+          value: error.message,
+          stacktrace: {
+            frames,
+          },
+        },
+        fingerprint,
+      };
+    }
+
+    const message = String(error);
+    return {
+      type: 'error',
+      level: 'error',
+      message,
+      timestamp,
+    };
+  }
+ 
+  setUser(user: UserInfo | null): void {
+    this.configManager.setUser(user);
+    this.tracingManager.updateConfig(this.configManager.getAll());
+  }
+ 
+  setAnonymousId(id: string): void {
+    setStoredAnonymousId(id);
+  }
+ 
+  startTransaction(context: TransactionContext): Transaction | null {
+    if (!this.enabled) return null;
+
+    const transaction = this.tracingManager.startTransaction(context);
+    if (transaction && transaction.sampled) {
+      logDebug('Client', 'Transaction started and sampled', {
+        name: transaction.name,
+        traceId: transaction.traceId,
+      });
+    }
+
+    return transaction;
+  }
+ 
+  getCurrentTransaction(): Transaction | null {
+    return this.tracingManager.getCurrentTransaction();
+  }
+ 
+  getCurrentSpan(): Span | null {
+    return this.tracingManager.getCurrentSpan();
+  }
+ 
+  setSpan(span: Span | null): void {
+    this.tracingManager.setCurrentSpan(span);
+  }
+ 
+  startSpan(context: SpanContext): Span | null {
+    if (!this.enabled) return null;
+    return this.tracingManager.startSpan(context);
+  }
+ 
+  setTag(key: string, value: string): void {
+    this.configManager.setTag(key, value);
+  }
+ 
+  setTags(tags: Record<string, string>): void {
+    this.configManager.setTags(tags);
+  }
+ 
+  setExtra(key: string, value: unknown): void {
+    this.configManager.setExtra(key, value);
+  }
+ 
+  addBreadcrumb(breadcrumb: Omit<Breadcrumb, 'timestamp'>): void {
+    const fullBreadcrumb: Breadcrumb = {
+      ...breadcrumb,
+      timestamp: now(),
+    };
+
+    this.breadcrumbs.push(fullBreadcrumb);
+    if (this.breadcrumbs.length > this.maxBreadcrumbs) {
+      this.breadcrumbs.shift();
+    }
+  }
+ 
+  async flush(): Promise<void> {
+    await this.queue.flush();
+  }
+ 
+  disable(): void {
+    this.enabled = false;
+  }
+ 
+  enable(): void {
+    this.enabled = true;
+  }
+ 
+  use(plugin: LightPlugin): void {
+    this.pluginManager.add(plugin);
+  }
+ 
+  destroy(): void {
+    this.pluginManager.destroy();
+    this.tracingManager.destroy();
+    this.queue.destroy();
+    this.eventBus.destroy();
+    this.breadcrumbs = [];
+  }
+}
+ 
+export default Client;
+ 
+ +
+
+ + + + + + + + \ No newline at end of file diff --git a/coverage/src/core/ConfigManager.ts.html b/coverage/src/core/ConfigManager.ts.html new file mode 100644 index 0000000..faf83ee --- /dev/null +++ b/coverage/src/core/ConfigManager.ts.html @@ -0,0 +1,817 @@ + + + + + + Code coverage report for src/core/ConfigManager.ts + + + + + + + + + +
+
+

All files / src/core ConfigManager.ts

+
+ +
+ 95.9% + Statements + 234/244 +
+ + +
+ 81.81% + Branches + 45/55 +
+ + +
+ 92.85% + Functions + 13/14 +
+ + +
+ 95.9% + Lines + 234/244 +
+ + +
+

+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +

+ +
+
+

+
1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +30 +31 +32 +33 +34 +35 +36 +37 +38 +39 +40 +41 +42 +43 +44 +45 +46 +47 +48 +49 +50 +51 +52 +53 +54 +55 +56 +57 +58 +59 +60 +61 +62 +63 +64 +65 +66 +67 +68 +69 +70 +71 +72 +73 +74 +75 +76 +77 +78 +79 +80 +81 +82 +83 +84 +85 +86 +87 +88 +89 +90 +91 +92 +93 +94 +95 +96 +97 +98 +99 +100 +101 +102 +103 +104 +105 +106 +107 +108 +109 +110 +111 +112 +113 +114 +115 +116 +117 +118 +119 +120 +121 +122 +123 +124 +125 +126 +127 +128 +129 +130 +131 +132 +133 +134 +135 +136 +137 +138 +139 +140 +141 +142 +143 +144 +145 +146 +147 +148 +149 +150 +151 +152 +153 +154 +155 +156 +157 +158 +159 +160 +161 +162 +163 +164 +165 +166 +167 +168 +169 +170 +171 +172 +173 +174 +175 +176 +177 +178 +179 +180 +181 +182 +183 +184 +185 +186 +187 +188 +189 +190 +191 +192 +193 +194 +195 +196 +197 +198 +199 +200 +201 +202 +203 +204 +205 +206 +207 +208 +209 +210 +211 +212 +213 +214 +215 +216 +217 +218 +219 +220 +221 +222 +223 +224 +225 +226 +227 +228 +229 +230 +231 +232 +233 +234 +235 +236 +237 +238 +239 +240 +241 +242 +243 +244 +2451x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +40x +40x +1x +1x +1x +1x +1x +1x +10x +10x +1x +1x +4x +4x +1x +1x +1x +1x +1x +1x +3x +3x +1x +1x +2x +2x +1x +1x +3x +3x +3x +3x +3x +1x +1x +2x +2x +2x +2x +2x +1x +1x +4x +4x +1x +1x +2x +2x +1x +  +2x +1x +1x +1x +1x +1x +1x +  +  +  +  +  +1x +1x +1x +1x +1x +1x +1x +21x +21x +21x +21x +21x +1x +1x +21x +21x +21x +1x +1x +21x +21x +21x +3x +3x +3x +3x +3x +3x +3x +3x +3x +21x +21x +21x +3x +3x +21x +21x +21x +1x +1x +21x +21x +21x +  +  +21x +21x +8x +8x +21x +21x +21x +21x +21x +9x +9x +21x +8x +8x +21x +21x +20x +20x +20x +20x +21x +  +  +21x +21x +21x +21x +21x +21x +21x +21x +21x +21x +10x +10x +10x +10x +10x +21x +21x +21x +21x +20x +20x +20x +20x +20x +20x +20x +20x +20x +20x +20x +21x +21x +21x +1x +1x +1x +1x +1x +1x +21x +21x +21x +21x +21x +21x +21x +21x +21x +21x +21x +3x +3x +3x +3x +3x +1x +1x +3x +2x +2x +2x +2x +2x +2x +2x +2x +3x +3x +3x +21x +21x +21x +3x +1x +1x +3x +2x +2x +3x +21x +21x +21x +1x + 
import type { LightConfig, SentryEvent, UserInfo, ContextLevelMap, ErrorEvent, StackFrame, Breadcrumb, EventLevel } from '../types';
+import { getContexts, getContextId, getPageUrl, getReferrer } from '../utils/env';
+import { matchPatterns } from '../utils/helper';
+import { getAnonymousId, isAnonymousTrackingEnabled } from '../utils/identity';
+ 
+const DEFAULT_CONFIG: Partial<LightConfig> = {
+  enabled: true,
+  sampleRate: 1,
+  maxQueueSize: 100,
+  flushInterval: 5000,
+  maxRetries: 3,
+  retryDelay: 1000,
+  environment: 'production',
+  // 上下文分层策略:按事件级别决定堆栈深度和 breadcrumbs 数量
+  contextLevel: {
+    fatal: { maxStackFrames: 5, maxBreadcrumbs: 20 },
+    error: { maxStackFrames: 5, maxBreadcrumbs: 10 },
+    warning: { maxStackFrames: 3, maxBreadcrumbs: 5 },
+    info: { maxStackFrames: 0, maxBreadcrumbs: 0 },
+    debug: { maxStackFrames: 0, maxBreadcrumbs: 0 },
+  },
+};
+ 
+export class ConfigManager {
+  private config: LightConfig;
+  private contexts: ReturnType<typeof getContexts> | null = null;
+  private contextId: string | null = null;
+  private contextReported: boolean = false;
+ 
+  constructor(config: LightConfig) {
+    this.config = { ...DEFAULT_CONFIG, ...config } as LightConfig;
+  }
+ 
+  markContextReported(): void {
+    this.contextReported = true;
+  }
+ 
+  get<K extends keyof LightConfig>(key: K): LightConfig[K] {
+    return this.config[key];
+  }
+ 
+  getAll(): LightConfig {
+    return { ...this.config };
+  }
+ 
+  set<K extends keyof LightConfig>(key: K, value: LightConfig[K]): void {
+    this.config[key] = value;
+  }
+ 
+  setUser(user: UserInfo | null): void {
+    this.config.user = user || undefined;
+  }
+ 
+  setTags(tags: Record<string, string>): void {
+    this.config.tags = { ...(this.config.tags || {}), ...tags };
+  }
+ 
+  setTag(key: string, value: string): void {
+    if (!this.config.tags) {
+      this.config.tags = {};
+    }
+    (this.config.tags as Record<string, string>)[key] = value;
+  }
+ 
+  setExtra(key: string, value: unknown): void {
+    if (!this.config.extra) {
+      this.config.extra = {};
+    }
+    (this.config.extra as Record<string, unknown>)[key] = value;
+  }
+ 
+  isIgnoredError(message: string): boolean {
+    return matchPatterns(message, this.config.ignoreErrors || []);
+  }
+ 
+  shouldSample(): boolean {
+    const rate = this.config.sampleRate ?? 1;
+    if (rate >= 1) return true;
+    if (rate <= 0) return false;
+    return Math.random() < rate;
+  }
+ 
+  /**
+   * 获取编码后的环境信息(延迟初始化,只在首次上报时计算)
+   * 注意:env.ts 的 getContexts 已经返回编码后的数据
+   */
+  private getEncodedContext(): ReturnType<typeof getContexts> {
+    if (!this.contexts) {
+      this.contexts = getContexts();
+    }
+    return this.contexts;
+  }
+ 
+  /**
+   * 将配置应用到事件
+   * @param event 事件对象
+   * @param includeFullContext 是否包含完整环境信息(批次内只有首个事件需要)
+   */
+  applyToEvent(event: SentryEvent, includeFullContext: boolean = true): SentryEvent {
+    // 使用 Record 来避免联合类型的问题
+    const enriched: Record<string, unknown> = { ...event };
+ 
+    // 处理 tags
+    if (event.tags) {
+      enriched.tags = { ...event.tags };
+    }
+ 
+    // 处理 request
+    if (event.request) {
+      enriched.request = { ...event.request };
+    }
+ 
+    // 处理 exception(仅 error 事件有)
+    if ('exception' in event && event.exception) {
+      const exc = event.exception;
+      enriched.exception = {
+        ...exc,
+        stacktrace: exc.stacktrace ? {
+          ...exc.stacktrace,
+          frames: exc.stacktrace.frames ? exc.stacktrace.frames.map((f: StackFrame) => ({ ...f })) : undefined,
+        } : undefined,
+      };
+    }
+ 
+    // 处理 breadcrumbs
+    if (event.breadcrumbs) {
+      enriched.breadcrumbs = event.breadcrumbs.map((b: Breadcrumb) => ({ ...b }));
+    }
+ 
+    // 处理 user
+    if (event.user) {
+      enriched.user = { ...event.user };
+    }
+ 
+    // 处理 contexts
+    if (event.contexts) {
+      enriched.contexts = { ...event.contexts };
+    }
+ 
+    if (this.config.release) {
+      enriched.release = this.config.release;
+    }
+    if (this.config.environment) {
+      enriched.environment = this.config.environment;
+    }
+    enriched.platform = 'javascript';
+    if (this.config.user) {
+      enriched.user = this.config.user;
+    }
+    if (this.config.tags) {
+      enriched.tags = { ...this.config.tags, ...(event.tags as Record<string, string> || {}) };
+    }
+ 
+    if (!enriched.request) {
+      enriched.request = {
+        url: getPageUrl(),
+        referrer: getReferrer(),
+      };
+    } else if (!(enriched.request as Record<string, unknown>).url) {
+      (enriched.request as Record<string, unknown>).url = getPageUrl();
+    }
+ 
+    if (!this.contextId) {
+      this.contextId = getContextId();
+    }
+    enriched.context_id = this.contextId;
+ 
+    // 处理匿名用户ID
+    // 只有在没有设置 user.id 且启用了匿名追踪时,才添加 anonymousId
+    const hasUserId = this.config.user?.id || (event.user as Record<string, unknown>)?.id;
+    if (!hasUserId && isAnonymousTrackingEnabled(this.config)) {
+      const anonymousId = getAnonymousId();
+      if (anonymousId) {
+        enriched.anonymousId = anonymousId;
+      }
+    }
+ 
+    const result = this.applyContextLevel(enriched);
+ 
+    if (includeFullContext && !this.contextReported) {
+      if (!this.contexts) {
+        this.contexts = getContexts();
+      }
+      (result as Record<string, unknown>).contexts = this.contexts;
+      (result as Record<string, unknown>).env = {
+        b: this.contexts.browser?.name,
+        bv: this.contexts.browser?.version,
+        os: this.contexts.os?.name,
+        osv: this.contexts.os?.version,
+      };
+    }
+ 
+    return result as unknown as SentryEvent;
+  }
+ 
+  /**
+   * 应用上下文分层策略:根据事件级别裁剪堆栈和 breadcrumbs
+   * 注意:此方法不修改原始 event 对象,返回裁剪后的副本
+   */
+  private applyContextLevel(event: Record<string, unknown>): Record<string, unknown> {
+    const contextLevel = this.config.contextLevel as ContextLevelMap | undefined;
+    if (!contextLevel) return event;
+ 
+    const level = (event.level || 'error') as EventLevel;
+    const levelConfig = contextLevel[level] || contextLevel['error'];
+ 
+    // 创建浅拷贝用于裁剪
+    const enriched: Record<string, unknown> = { ...event };
+ 
+    // 裁剪堆栈帧(仅 error 事件有 exception)
+    if ('exception' in event && event.exception && typeof event.exception === 'object') {
+      const exc = event.exception as Record<string, unknown>;
+      if (exc.stacktrace && typeof exc.stacktrace === 'object') {
+        const st = exc.stacktrace as Record<string, unknown>;
+        if (Array.isArray(st.frames)) {
+          if (levelConfig.maxStackFrames === 0) {
+            // info/debug 级别不需要堆栈
+            delete enriched.exception;
+          } else {
+            enriched.exception = {
+              ...exc,
+              stacktrace: {
+                ...st,
+                frames: (st.frames as StackFrame[]).slice(0, levelConfig.maxStackFrames),
+              },
+            };
+          }
+        }
+      }
+    }
+ 
+    // 裁剪 breadcrumbs
+    if (event.breadcrumbs && Array.isArray(event.breadcrumbs)) {
+      if (levelConfig.maxBreadcrumbs === 0) {
+        // info/debug 级别不需要 breadcrumbs
+        delete enriched.breadcrumbs;
+      } else {
+        enriched.breadcrumbs = (event.breadcrumbs as Breadcrumb[]).slice(-levelConfig.maxBreadcrumbs);
+      }
+    }
+ 
+    return enriched;
+  }
+}
+ 
+ +
+
+ + + + + + + + \ No newline at end of file diff --git a/coverage/src/core/EventBus.ts.html b/coverage/src/core/EventBus.ts.html new file mode 100644 index 0000000..4cf77b4 --- /dev/null +++ b/coverage/src/core/EventBus.ts.html @@ -0,0 +1,226 @@ + + + + + + Code coverage report for src/core/EventBus.ts + + + + + + + + + +
+
+

All files / src/core EventBus.ts

+
+ +
+ 100% + Statements + 47/47 +
+ + +
+ 100% + Branches + 13/13 +
+ + +
+ 100% + Functions + 7/7 +
+ + +
+ 100% + Lines + 47/47 +
+ + +
+

+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +

+ +
+
+

+
1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +30 +31 +32 +33 +34 +35 +36 +37 +38 +39 +40 +41 +42 +43 +44 +45 +46 +47 +481x +1x +1x +42x +1x +1x +21x +16x +16x +21x +21x +1x +1x +9x +9x +8x +8x +7x +7x +8x +9x +1x +1x +88x +88x +14x +15x +15x +15x +2x +2x +15x +14x +88x +1x +1x +5x +4x +4x +4x +5x +5x +1x +1x +3x +3x +1x + 
type Handler = (...args: unknown[]) => void;
+ 
+export class EventBus {
+  private handlers: Map<string, Handler[]> = new Map();
+ 
+  on(event: string, handler: Handler): void {
+    if (!this.handlers.has(event)) {
+      this.handlers.set(event, []);
+    }
+    this.handlers.get(event)!.push(handler);
+  }
+ 
+  off(event: string, handler: Handler): void {
+    const eventHandlers = this.handlers.get(event);
+    if (eventHandlers) {
+      const index = eventHandlers.indexOf(handler);
+      if (index > -1) {
+        eventHandlers.splice(index, 1);
+      }
+    }
+  }
+ 
+  emit(event: string, ...args: unknown[]): void {
+    const eventHandlers = this.handlers.get(event);
+    if (eventHandlers) {
+      for (const handler of eventHandlers) {
+        try {
+          handler(...args);
+        } catch (e) {
+          console.error('[LightSDK] EventBus handler error:', e);
+        }
+      }
+    }
+  }
+ 
+  once(event: string, handler: Handler): void {
+    const wrapped = (...args: unknown[]) => {
+      this.off(event, wrapped);
+      handler(...args);
+    };
+    this.on(event, wrapped);
+  }
+ 
+  destroy(): void {
+    this.handlers.clear();
+  }
+}
+ 
+ +
+
+ + + + + + + + \ No newline at end of file diff --git a/coverage/src/core/EventQueue.ts.html b/coverage/src/core/EventQueue.ts.html new file mode 100644 index 0000000..84591d6 --- /dev/null +++ b/coverage/src/core/EventQueue.ts.html @@ -0,0 +1,1036 @@ + + + + + + Code coverage report for src/core/EventQueue.ts + + + + + + + + + +
+
+

All files / src/core EventQueue.ts

+
+ +
+ 89.9% + Statements + 285/317 +
+ + +
+ 83.82% + Branches + 57/68 +
+ + +
+ 81.25% + Functions + 13/16 +
+ + +
+ 89.9% + Lines + 285/317 +
+ + +
+

+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +

+ +
+
+

+
1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +30 +31 +32 +33 +34 +35 +36 +37 +38 +39 +40 +41 +42 +43 +44 +45 +46 +47 +48 +49 +50 +51 +52 +53 +54 +55 +56 +57 +58 +59 +60 +61 +62 +63 +64 +65 +66 +67 +68 +69 +70 +71 +72 +73 +74 +75 +76 +77 +78 +79 +80 +81 +82 +83 +84 +85 +86 +87 +88 +89 +90 +91 +92 +93 +94 +95 +96 +97 +98 +99 +100 +101 +102 +103 +104 +105 +106 +107 +108 +109 +110 +111 +112 +113 +114 +115 +116 +117 +118 +119 +120 +121 +122 +123 +124 +125 +126 +127 +128 +129 +130 +131 +132 +133 +134 +135 +136 +137 +138 +139 +140 +141 +142 +143 +144 +145 +146 +147 +148 +149 +150 +151 +152 +153 +154 +155 +156 +157 +158 +159 +160 +161 +162 +163 +164 +165 +166 +167 +168 +169 +170 +171 +172 +173 +174 +175 +176 +177 +178 +179 +180 +181 +182 +183 +184 +185 +186 +187 +188 +189 +190 +191 +192 +193 +194 +195 +196 +197 +198 +199 +200 +201 +202 +203 +204 +205 +206 +207 +208 +209 +210 +211 +212 +213 +214 +215 +216 +217 +218 +219 +220 +221 +222 +223 +224 +225 +226 +227 +228 +229 +230 +231 +232 +233 +234 +235 +236 +237 +238 +239 +240 +241 +242 +243 +244 +245 +246 +247 +248 +249 +250 +251 +252 +253 +254 +255 +256 +257 +258 +259 +260 +261 +262 +263 +264 +265 +266 +267 +268 +269 +270 +271 +272 +273 +274 +275 +276 +277 +278 +279 +280 +281 +282 +283 +284 +285 +286 +287 +288 +289 +290 +291 +292 +293 +294 +295 +296 +297 +298 +299 +300 +301 +302 +303 +304 +305 +306 +307 +308 +309 +310 +311 +312 +313 +314 +315 +316 +317 +3181x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +27x +27x +27x +27x +27x +27x +27x +27x +27x +27x +27x +27x +1x +1x +2x +2x +2x +1x +1x +2x +2x +4x +1x +1x +2x +2x +1x +1x +2x +  +  +  +  +2x +2x +2x +2x +2x +  +  +  +  +2x +  +  +  +  +2x +2x +2x +2x +2x +1x +1x +80x +80x +80x +80x +26x +26x +80x +80x +80x +80x +80x +  +  +80x +80x +  +  +  +80x +80x +3x +3x +3x +3x +3x +3x +  +  +3x +1x +1x +1x +3x +3x +3x +3x +77x +77x +80x +1x +1x +83x +83x +83x +1x +1x +1x +82x +82x +82x +82x +82x +83x +80x +3x +3x +3x +77x +77x +77x +77x +80x +51x +51x +33x +9x +33x +24x +24x +24x +24x +33x +33x +33x +18x +18x +18x +51x +  +  +  +  +80x +26x +26x +26x +80x +46x +46x +46x +46x +46x +83x +1x +1x +1x +83x +1x +1x +82x +3x +3x +3x +3x +3x +3x +  +  +3x +82x +1x +1x +11x +11x +11x +3x +3x +3x +3x +3x +3x +3x +3x +3x +3x +3x +11x +11x +11x +1x +1x +82x +80x +80x +80x +2x +82x +1x +1x +11x +11x +11x +2x +2x +2x +11x +  +  +  +9x +9x +9x +9x +9x +9x +9x +9x +9x +9x +9x +9x +9x +9x +8x +8x +8x +11x +1x +1x +1x +11x +9x +9x +11x +1x +1x +2x +2x +2x +2x +2x +2x +2x +2x +2x +2x +2x +2x +2x +2x +2x +1x +1x +1x +  +  +  +  +1x +2x +1x +1x +19x +19x +1x +1x +28x +2x +2x +2x +28x +3x +3x +3x +28x +2x +2x +28x +28x +2x +2x +28x +2x +2x +28x +28x +28x +28x +28x +28x +1x + 
import type { SentryEvent, ErrorEvent, CountEvent } from '../types';
+import { EventBus } from './EventBus';
+import { now } from '../utils/helper';
+import { logDebug } from '../utils/logger';
+ 
+interface DedupeEntry {
+  count: number;
+  lastTime: number;
+  firstReported: boolean;
+}
+ 
+export class EventQueue {
+  private queue: SentryEvent[] = [];
+  private maxSize: number;
+  private flushInterval: number;
+  private timer: ReturnType<typeof setTimeout> | null = null;
+  private eventBus: EventBus;
+  private flushCallback: (events: SentryEvent[]) => Promise<void>;
+  private syncFlushCallback: (events: SentryEvent[]) => void;
+  private lastFlushTime: number = 0;
+  private isFlushing: boolean = false;
+  private onVisibilityChange?: () => void;
+  private onBeforeUnload?: () => void;
+  private onPagehide?: () => void;
+  private dedupeMap: Map<string, DedupeEntry> = new Map();
+  private pendingCounts: Map<string, { count: number; ts_start: number; ts_end: number }> = new Map();
+ 
+  private errorRateWindow: { [key: string]: number[] } = {};
+  private paused: boolean = false;
+  private pauseTimer: ReturnType<typeof setTimeout> | null = null;
+ 
+  constructor(
+    maxSize: number,
+    flushInterval: number,
+    eventBus: EventBus,
+    flushCallback: (events: SentryEvent[]) => Promise<void>,
+    syncFlushCallback: (events: SentryEvent[]) => void
+  ) {
+    this.maxSize = maxSize;
+    this.flushInterval = flushInterval;
+    this.eventBus = eventBus;
+    this.flushCallback = flushCallback;
+    this.syncFlushCallback = syncFlushCallback;
+  }
+ 
+  start(): void {
+    this.startTimer();
+    this.setupVisibilityListener();
+  }
+ 
+  private startTimer(): void {
+    if (this.timer) return;
+    this.timer = setInterval(() => {
+      if (this.queue.length > 0 || this.pendingCounts.size > 0) {
+        this.flush();
+      }
+    }, this.flushInterval);
+  }
+ 
+  private setupVisibilityListener(): void {
+    this.onVisibilityChange = () => {
+      if (document.hidden && (this.queue.length > 0 || this.pendingCounts.size > 0)) {
+        this.flushSync();
+      }
+    };
+    if (typeof document !== 'undefined') {
+      document.addEventListener('visibilitychange', this.onVisibilityChange);
+    }
+ 
+    this.onBeforeUnload = () => {
+      if (this.queue.length > 0 || this.pendingCounts.size > 0) {
+        this.flushSync();
+      }
+    };
+    this.onPagehide = () => {
+      if (this.queue.length > 0 || this.pendingCounts.size > 0) {
+        this.flushSync();
+      }
+    };
+    if (typeof window !== 'undefined') {
+      window.addEventListener('beforeunload', this.onBeforeUnload);
+      window.addEventListener('pagehide', this.onPagehide);
+    }
+  }
+ 
+  private checkInfiniteLoop(fingerprint: string): boolean {
+    const currentTime = now();
+    const windowStart = currentTime - 1000;
+ 
+    if (!this.errorRateWindow[fingerprint]) {
+      this.errorRateWindow[fingerprint] = [];
+    }
+ 
+    const window = this.errorRateWindow[fingerprint];
+    window.push(currentTime);
+    
+    while (window.length > 0 && window[0] < windowStart) {
+      window.shift();
+    }
+ 
+    if (window.length === 0) {
+      delete this.errorRateWindow[fingerprint];
+      return false;
+    }
+ 
+    if (window.length > 10) {
+      if (!this.paused) {
+        console.warn('[LightSDK] Infinite loop detected, pausing SDK for 60s', { fingerprint, count: window.length });
+        this.eventBus.emit('error', new Error('Infinite loop detected'));
+        this.paused = true;
+        
+        if (this.pauseTimer) {
+          clearTimeout(this.pauseTimer);
+        }
+        this.pauseTimer = setTimeout(() => {
+          this.paused = false;
+          this.errorRateWindow = {};
+          console.info('[LightSDK] Resumed after infinite loop detection');
+        }, 60000);
+      }
+      return true;
+    }
+ 
+    return false;
+  }
+ 
+  enqueue(event: SentryEvent): void {
+    logDebug('EventQueue', 'enqueue called', { type: event.type, level: event.level, message: 'message' in event ? (event as { message: string }).message : undefined });
+ 
+    if (this.paused) {
+      logDebug('EventQueue', 'enqueue skipped: queue paused (infinite loop detected)');
+      return;
+    }
+ 
+    this.cleanupExpiredDedupeEntries();
+ 
+    const fingerprint = this.getDedupeKey(event);
+    
+    if (fingerprint) {
+      if (this.checkInfiniteLoop(fingerprint)) {
+        logDebug('EventQueue', 'enqueue skipped: infinite loop detected', { fingerprint });
+        return;
+      }
+ 
+      const currentTime = now();
+      const existing = this.dedupeMap.get(fingerprint);
+      
+      if (existing) {
+        if (currentTime - existing.lastTime < 60000) {
+          if (existing.count >= 3) {
+            if (!this.pendingCounts.has(fingerprint)) {
+              this.pendingCounts.set(fingerprint, { count: 1, ts_start: currentTime, ts_end: currentTime });
+            } else {
+              const pending = this.pendingCounts.get(fingerprint)!;
+              pending.count++;
+              pending.ts_end = currentTime;
+            }
+            logDebug('EventQueue', 'enqueue skipped: deduped (count >= 3)', { fingerprint, count: existing.count });
+            return;
+          }
+          existing.count++;
+          existing.lastTime = currentTime;
+          logDebug('EventQueue', 'Dedup count incremented', { fingerprint, count: existing.count });
+        } else {
+          this.dedupeMap.set(fingerprint, { count: 1, lastTime: currentTime, firstReported: true });
+          this.pendingCounts.delete(fingerprint);
+          logDebug('EventQueue', 'Dedup entry reset (expired)', { fingerprint });
+        }
+      } else {
+        this.dedupeMap.set(fingerprint, { count: 1, lastTime: currentTime, firstReported: false });
+        logDebug('EventQueue', 'New dedup entry created', { fingerprint });
+      }
+    }
+ 
+    this.queue.push(event);
+    logDebug('EventQueue', 'Event added to queue', { queueSize: this.queue.length });
+    this.eventBus.emit('event', event);
+ 
+    if (this.queue.length >= this.maxSize) {
+      logDebug('EventQueue', 'Queue reached maxSize, triggering flush', { maxSize: this.maxSize });
+      this.flush();
+    }
+  }
+ 
+  private cleanupExpiredDedupeEntries(): void {
+    if (Math.random() > 0.1) return;
+ 
+    const currentTime = now();
+    const expiryTime = 60000;
+ 
+    for (const [key, entry] of this.dedupeMap) {
+      if (currentTime - entry.lastTime > expiryTime) {
+        this.dedupeMap.delete(key);
+      }
+    }
+  }
+ 
+  private buildCountEvents(): SentryEvent[] {
+    const countEvents: SentryEvent[] = [];
+ 
+    for (const [fingerprint, data] of this.pendingCounts.entries()) {
+      const event: CountEvent = {
+        type: 'count',
+        fingerprint,
+        count: data.count,
+        ts_start: data.ts_start,
+        ts_end: data.ts_end,
+        timestamp: now(),
+        level: 'info',
+      };
+      countEvents.push(event);
+    }
+ 
+    return countEvents;
+  }
+ 
+  private getDedupeKey(event: SentryEvent): string | null {
+    if (event.type === 'error') {
+      const errEvent = event as ErrorEvent;
+      return errEvent.fingerprint || errEvent.message;
+    }
+    return null;
+  }
+ 
+  async flush(): Promise<void> {
+    logDebug('EventQueue', 'flush called', { queueSize: this.queue.length, pendingCounts: this.pendingCounts.size, isFlushing: this.isFlushing });
+ 
+    if (this.queue.length === 0 && this.pendingCounts.size === 0) {
+      logDebug('EventQueue', 'flush skipped: queue is empty');
+      return;
+    }
+    if (this.isFlushing) {
+      logDebug('EventQueue', 'flush skipped: already flushing');
+      return;
+    }
+ 
+    this.isFlushing = true;
+ 
+    const events = this.queue.splice(0, this.queue.length);
+    const countEvents = this.buildCountEvents();
+    const allEvents = [...events, ...countEvents];
+ 
+    logDebug('EventQueue', 'flush events to callback', { total: allEvents.length, events: events.length, countEvents: countEvents.length });
+ 
+    this.lastFlushTime = now();
+    this.eventBus.emit('report', allEvents);
+ 
+    try {
+      await this.flushCallback(allEvents);
+      this.pendingCounts.clear();
+      logDebug('EventQueue', 'flush completed successfully');
+      this.eventBus.emit('reported', allEvents);
+    } catch (e) {
+      logDebug('EventQueue', 'flush failed, returning events to queue', { error: e instanceof Error ? e.message : String(e) });
+      events.forEach(evt => this.queue.unshift(evt));
+      throw e;
+    } finally {
+      this.isFlushing = false;
+    }
+  }
+ 
+  flushSync(): void {
+    if (this.queue.length === 0 && this.pendingCounts.size === 0) return;
+ 
+    const events = this.queue.splice(0, this.queue.length);
+    const pendingCountsSnapshot = new Map(this.pendingCounts);
+    const countEvents = this.buildCountEvents();
+    const allEvents = [...events, ...countEvents];
+ 
+    this.lastFlushTime = now();
+    this.eventBus.emit('report', allEvents);
+ 
+    try {
+      this.syncFlushCallback(allEvents);
+      this.pendingCounts.clear();
+      this.eventBus.emit('reported', allEvents);
+    } catch (e) {
+      console.error('[LightSDK] Sync flush failed', e);
+      events.forEach(evt => this.queue.unshift(evt));
+      for (const [key, value] of pendingCountsSnapshot) {
+        if (!this.pendingCounts.has(key)) {
+          this.pendingCounts.set(key, value);
+        }
+      }
+    }
+  }
+ 
+  size(): number {
+    return this.queue.length;
+  }
+ 
+  destroy(): void {
+    if (this.timer) {
+      clearInterval(this.timer);
+      this.timer = null;
+    }
+    if (this.pauseTimer) {
+      clearTimeout(this.pauseTimer);
+      this.pauseTimer = null;
+    }
+    if (typeof document !== 'undefined' && this.onVisibilityChange) {
+      document.removeEventListener('visibilitychange', this.onVisibilityChange);
+    }
+    if (typeof window !== 'undefined') {
+      if (this.onBeforeUnload) {
+        window.removeEventListener('beforeunload', this.onBeforeUnload);
+      }
+      if (this.onPagehide) {
+        window.removeEventListener('pagehide', this.onPagehide);
+      }
+    }
+    this.queue = [];
+    this.dedupeMap.clear();
+    this.pendingCounts.clear();
+    this.errorRateWindow = {};
+  }
+}
+ 
+ +
+
+ + + + + + + + \ No newline at end of file diff --git a/coverage/src/core/PluginManager.ts.html b/coverage/src/core/PluginManager.ts.html new file mode 100644 index 0000000..c9ce622 --- /dev/null +++ b/coverage/src/core/PluginManager.ts.html @@ -0,0 +1,346 @@ + + + + + + Code coverage report for src/core/PluginManager.ts + + + + + + + + + +
+
+

All files / src/core PluginManager.ts

+
+ +
+ 100% + Statements + 87/87 +
+ + +
+ 100% + Branches + 26/26 +
+ + +
+ 100% + Functions + 8/8 +
+ + +
+ 100% + Lines + 87/87 +
+ + +
+

+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +

+ +
+
+

+
1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +30 +31 +32 +33 +34 +35 +36 +37 +38 +39 +40 +41 +42 +43 +44 +45 +46 +47 +48 +49 +50 +51 +52 +53 +54 +55 +56 +57 +58 +59 +60 +61 +62 +63 +64 +65 +66 +67 +68 +69 +70 +71 +72 +73 +74 +75 +76 +77 +78 +79 +80 +81 +82 +83 +84 +85 +86 +87 +881x +1x +1x +1x +1x +1x +1x +26x +26x +1x +1x +30x +1x +1x +29x +29x +29x +30x +1x +1x +30x +1x +1x +5x +5x +4x +2x +2x +2x +1x +1x +2x +4x +4x +5x +1x +1x +2x +2x +1x +1x +8x +8x +1x +1x +5x +5x +8x +7x +7x +7x +1x +1x +5x +7x +1x +1x +7x +8x +4x +5x +1x +1x +3x +5x +4x +4x +4x +1x +1x +4x +5x +3x +1x +1x +4x +6x +4x +4x +4x +1x +1x +4x +6x +4x +4x +1x + 
import type { LightPlugin, LightClient, SentryEvent } from '../types';
+ 
+export class PluginManager {
+  private plugins: Map<string, LightPlugin> = new Map();
+  private client: LightClient;
+ 
+  constructor(client: LightClient) {
+    this.client = client;
+  }
+ 
+  add(plugin: LightPlugin): void {
+    if (this.plugins.has(plugin.name)) {
+      return;
+    }
+    this.plugins.set(plugin.name, plugin);
+    try {
+      plugin.setup(this.client);
+    } catch (e) {
+      console.error(`[LightSDK] Plugin "${plugin.name}" setup error:`, e);
+    }
+  }
+ 
+  remove(name: string): void {
+    const plugin = this.plugins.get(name);
+    if (plugin) {
+      if (plugin.destroy) {
+        try {
+          plugin.destroy();
+        } catch (e) {
+          console.error(`[LightSDK] Plugin "${name}" destroy error:`, e);
+        }
+      }
+      this.plugins.delete(name);
+    }
+  }
+ 
+  get(name: string): LightPlugin | undefined {
+    return this.plugins.get(name);
+  }
+ 
+  has(name: string): boolean {
+    return this.plugins.has(name);
+  }
+ 
+  applyBeforeReport(event: SentryEvent): SentryEvent | null {
+    let result: SentryEvent | null = event;
+    for (const plugin of this.plugins.values()) {
+      if (plugin.beforeReport) {
+        try {
+          const modified = plugin.beforeReport(result);
+          if (modified === null) {
+            return null;
+          }
+          result = modified;
+        } catch (e) {
+          console.error(`[LightSDK] Plugin "${plugin.name}" beforeReport error:`, e);
+        }
+      }
+    }
+    return result;
+  }
+ 
+  applyAfterReport(event: SentryEvent): void {
+    for (const plugin of this.plugins.values()) {
+      if (plugin.afterReport) {
+        try {
+          plugin.afterReport(event);
+        } catch (e) {
+          console.error(`[LightSDK] Plugin "${plugin.name}" afterReport error:`, e);
+        }
+      }
+    }
+  }
+ 
+  destroy(): void {
+    for (const plugin of this.plugins.values()) {
+      if (plugin.destroy) {
+        try {
+          plugin.destroy();
+        } catch (e) {
+          console.error(`[LightSDK] Plugin "${plugin.name}" destroy error:`, e);
+        }
+      }
+    }
+    this.plugins.clear();
+  }
+}
+ 
+ +
+
+ + + + + + + + \ No newline at end of file diff --git a/coverage/src/core/Reporter.ts.html b/coverage/src/core/Reporter.ts.html new file mode 100644 index 0000000..a69a4ae --- /dev/null +++ b/coverage/src/core/Reporter.ts.html @@ -0,0 +1,1132 @@ + + + + + + Code coverage report for src/core/Reporter.ts + + + + + + + + + +
+
+

All files / src/core Reporter.ts

+
+ +
+ 16.9% + Statements + 59/349 +
+ + +
+ 100% + Branches + 0/0 +
+ + +
+ 0% + Functions + 0/12 +
+ + +
+ 16.9% + Lines + 59/349 +
+ + +
+

+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +

+ +
+
+

+
1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +30 +31 +32 +33 +34 +35 +36 +37 +38 +39 +40 +41 +42 +43 +44 +45 +46 +47 +48 +49 +50 +51 +52 +53 +54 +55 +56 +57 +58 +59 +60 +61 +62 +63 +64 +65 +66 +67 +68 +69 +70 +71 +72 +73 +74 +75 +76 +77 +78 +79 +80 +81 +82 +83 +84 +85 +86 +87 +88 +89 +90 +91 +92 +93 +94 +95 +96 +97 +98 +99 +100 +101 +102 +103 +104 +105 +106 +107 +108 +109 +110 +111 +112 +113 +114 +115 +116 +117 +118 +119 +120 +121 +122 +123 +124 +125 +126 +127 +128 +129 +130 +131 +132 +133 +134 +135 +136 +137 +138 +139 +140 +141 +142 +143 +144 +145 +146 +147 +148 +149 +150 +151 +152 +153 +154 +155 +156 +157 +158 +159 +160 +161 +162 +163 +164 +165 +166 +167 +168 +169 +170 +171 +172 +173 +174 +175 +176 +177 +178 +179 +180 +181 +182 +183 +184 +185 +186 +187 +188 +189 +190 +191 +192 +193 +194 +195 +196 +197 +198 +199 +200 +201 +202 +203 +204 +205 +206 +207 +208 +209 +210 +211 +212 +213 +214 +215 +216 +217 +218 +219 +220 +221 +222 +223 +224 +225 +226 +227 +228 +229 +230 +231 +232 +233 +234 +235 +236 +237 +238 +239 +240 +241 +242 +243 +244 +245 +246 +247 +248 +249 +250 +251 +252 +253 +254 +255 +256 +257 +258 +259 +260 +261 +262 +263 +264 +265 +266 +267 +268 +269 +270 +271 +272 +273 +274 +275 +276 +277 +278 +279 +280 +281 +282 +283 +284 +285 +286 +287 +288 +289 +290 +291 +292 +293 +294 +295 +296 +297 +298 +299 +300 +301 +302 +303 +304 +305 +306 +307 +308 +309 +310 +311 +312 +313 +314 +315 +316 +317 +318 +319 +320 +321 +322 +323 +324 +325 +326 +327 +328 +329 +330 +331 +332 +333 +334 +335 +336 +337 +338 +339 +340 +341 +342 +343 +344 +345 +346 +347 +348 +349 +3501x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +  +  +  +  +1x +1x +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +1x +1x +  +  +  +  +  +  +  +  +  +  +  +  +  +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +1x +1x +1x +1x +1x +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +1x +1x +1x +1x +1x +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +1x +1x +  +  +  +  +  +  +  +1x +1x +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +1x +1x +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +1x +1x +  +  +  +  +  +  +  +  +  +  +  +1x +1x +  +  +1x + 
import type { DSNInfo, SentryEvent, ErrorEvent } from '../types';
+import { getEnvelopeUrl } from '../utils/dsn';
+import { now, generateEventId } from '../utils/helper';
+import { encodeFields, FIELD_ENCODE_MAP } from '../utils/field-encoder';
+import { logDebug, logError } from '../utils/logger';
+ 
+export class Reporter {
+  private dsn: DSNInfo;
+  private maxRetries: number;
+  private retryDelay: number;
+  private useShortFields: boolean = true; // 是否使用短字段编码
+ 
+  constructor(dsn: DSNInfo, maxRetries: number, retryDelay: number) {
+    this.dsn = dsn;
+    this.maxRetries = maxRetries;
+    this.retryDelay = retryDelay;
+  }
+ 
+  async report(events: SentryEvent[]): Promise<void> {
+    logDebug('Reporter', 'report called', { eventCount: events.length });
+
+    if (events.length === 0) {
+      logDebug('Reporter', 'report skipped: empty events');
+      return;
+    }
+
+    const envelope = this.buildEnvelope(events);
+    const url = getEnvelopeUrl(this.dsn);
+    logDebug('Reporter', 'Envelope built', { envelopeSize: envelope.length, url });
+    
+    let retries = 0;
+    while (retries <= this.maxRetries) {
+      try {
+        logDebug('Reporter', `Sending request (attempt ${retries + 1}/${this.maxRetries + 1})`);
+        await this.send(envelope, false);
+        logDebug('Reporter', 'Request succeeded');
+        return;
+      } catch (e) {
+        const status = (e as { status?: number }).status;
+        logError('Reporter', `Request failed (attempt ${retries + 1})`, { status, error: e });
+        if (status && status >= 400 && status < 500) {
+          throw e;
+        }
+        retries++;
+        if (retries > this.maxRetries) {
+          logError('Reporter', 'All retries exhausted');
+          throw e;
+        }
+        const backoff = Math.min(this.retryDelay * Math.pow(2, retries - 1), 5000);
+        logDebug('Reporter', `Retrying in ${backoff}ms`);
+        await this.delay(backoff);
+      }
+    }
+  }
+ 
+  reportSync(events: SentryEvent[]): void {
+    if (events.length === 0) return;
+
+    const envelope = this.buildEnvelope(events);
+
+    try {
+      const success = this.sendSync(envelope);
+      if (success) return;
+    } catch {
+      // ignore sync errors
+    }
+
+    this.sendViaImage(envelope);
+  }
+ 
+  /**
+   * 构建 Sentry Envelope
+   * 
+   * 优化:
+   * 1. 批量元数据共享 - 同批次共享 release/environment/user
+   * 2. 字段短编码 - 常用字段名使用短码
+   * 3. 时间戳相对化 - 批次内后续事件用差值
+   */
+  private buildEnvelope(events: SentryEvent[]): string {
+    // 提取公共元数据(从第一个事件)
+    const sharedMeta = this.extractSharedMeta(events);
+
+    // 构建 header(包含公共元数据)
+    const headerObj: Record<string, unknown> = {
+      event_id: generateEventId(),
+      sent_at: new Date().toISOString(),
+      meta: sharedMeta,
+    };
+
+    // 如果启用短字段编码,在 header 中标记
+    if (this.useShortFields) {
+      headerObj._sf = 1; // short fields flag
+    }
+
+    // 时间戳相对化:第一个事件带基准时间,后续事件用差值
+    const eventsWithRelativeTs = this.applyRelativeTimestamps(events, headerObj);
+
+    const header = JSON.stringify(headerObj);
+
+    const items: string[] = [header];
+
+    for (const event of eventsWithRelativeTs) {
+      // 移除已共享的字段,减少重复
+      let strippedEvent: unknown = this.stripSharedFields(event as unknown as SentryEvent, sharedMeta);
+
+      // 短字段编码(如果启用)
+      if (this.useShortFields) {
+        strippedEvent = encodeFields(strippedEvent as Record<string, unknown>);
+      }
+
+      const itemPayload = JSON.stringify(strippedEvent);
+      const itemHeader = JSON.stringify({
+        type: this.getEnvelopeType(event as unknown as SentryEvent),
+        length: itemPayload.length,
+      });
+      items.push(itemHeader, itemPayload);
+    }
+
+    return items.join('\n');
+  }
+ 
+  /**
+   * 时间戳相对化
+   * 
+   * 批次内:
+   * - 第一个事件:完整时间戳
+   * - 后续事件:相对于第一个事件的毫秒差值(用 _dts 字段表示)
+   * 
+   * 这样可以将时间戳从 13 位数字减少到 2-4 位数字
+   */
+  private applyRelativeTimestamps(events: SentryEvent[], headerObj: Record<string, unknown>): (SentryEvent | Record<string, unknown>)[] {
+    if (events.length <= 1) return events;
+
+    const result: (SentryEvent | Record<string, unknown>)[] = [];
+    const baseTimestamp = events[0].timestamp ? new Date(events[0].timestamp).getTime() : Date.now();
+
+    // 在 header 中标记使用相对时间戳
+    headerObj._rt = 1; // relative timestamp flag
+    headerObj._bt = baseTimestamp; // base timestamp
+
+    for (let i = 0; i < events.length; i++) {
+      const event: Record<string, unknown> = { ...events[i] };
+
+      if (i === 0) {
+        // 第一个事件保持完整时间戳
+        result.push(event as unknown as SentryEvent);
+      } else {
+        // 后续事件用差值
+        const eventTs = event.timestamp ? new Date(event.timestamp as string | number).getTime() : Date.now();
+        const delta = eventTs - baseTimestamp;
+        
+        delete event.timestamp;
+        event._dts = delta; // delta timestamp
+        
+        // 同时处理 start_timestamp(transaction 事件)
+        if (event.start_timestamp) {
+          const startTs = new Date(event.start_timestamp as string | number).getTime();
+          const startDelta = startTs - baseTimestamp;
+          delete event.start_timestamp;
+          event._dsts = startDelta; // delta start timestamp
+        }
+        
+        result.push(event);
+      }
+    }
+
+    return result;
+  }
+ 
+  /**
+   * 提取批次内公共元数据
+   */
+  private extractSharedMeta(events: SentryEvent[]): Record<string, unknown> {
+    if (events.length === 0) return {};
+
+    const firstEvent = events[0];
+    const meta: Record<string, unknown> = {};
+
+    // 提取 release(如果所有事件都相同)
+    if (firstEvent.release) {
+      const allSameRelease = events.every(e => e.release === firstEvent.release);
+      if (allSameRelease) {
+        meta.release = firstEvent.release;
+      }
+    }
+
+    // 提取 environment(如果所有事件都相同)
+    if (firstEvent.environment) {
+      const allSameEnv = events.every(e => e.environment === firstEvent.environment);
+      if (allSameEnv) {
+        meta.environment = firstEvent.environment;
+      }
+    }
+
+    // 提取 user(如果所有事件都相同)
+    if (firstEvent.user) {
+      const allSameUser = events.every(e => 
+        JSON.stringify(e.user) === JSON.stringify(firstEvent.user)
+      );
+      if (allSameUser) {
+        meta.user = firstEvent.user;
+      }
+    }
+
+    // 提取 env(编码后的环境信息)
+    const firstEnv = (firstEvent as unknown as Record<string, unknown>).env;
+    if (firstEnv) {
+      meta.env = firstEnv;
+    }
+
+    return meta;
+  }
+ 
+  /**
+   * 移除已共享的字段,减少重复
+   */
+  private stripSharedFields(event: SentryEvent, meta: Record<string, unknown>): Record<string, unknown> {
+    const stripped: Record<string, unknown> = { ...event };
+
+    // 移除已共享的字段
+    if (meta.release && stripped.release === meta.release) {
+      delete stripped.release;
+    }
+    if (meta.environment && stripped.environment === meta.environment) {
+      delete stripped.environment;
+    }
+    if (meta.user && JSON.stringify(stripped.user) === JSON.stringify(meta.user)) {
+      delete stripped.user;
+    }
+    if (meta.env) {
+      delete stripped.env;
+    }
+
+    return stripped;
+  }
+ 
+  private getEnvelopeType(event: SentryEvent): string {
+    switch (event.type) {
+      case 'error':
+        return 'event';
+      default:
+        return event.type;
+    }
+  }
+ 
+  private async send(body: string, isSync: boolean = false): Promise<void> {
+    const url = getEnvelopeUrl(this.dsn);
+
+    if (navigator.sendBeacon) {
+      try {
+        const blob = new Blob([body], { type: 'application/x-sentry-envelope' });
+        const success = navigator.sendBeacon(url, blob);
+        if (success) return;
+      } catch {
+        // sendBeacon failed, fall through
+      }
+    }
+
+    if (typeof fetch === 'function') {
+      try {
+        const controller = new AbortController();
+        const timeoutId = setTimeout(() => controller.abort(), 10000);
+        const response = await fetch(url, {
+          method: 'POST',
+          body,
+          headers: {
+            'Content-Type': 'application/x-sentry-envelope',
+          },
+          keepalive: true,
+          signal: controller.signal,
+        });
+        clearTimeout(timeoutId);
+        if (response.ok) return;
+        const err = new Error(`HTTP ${response.status}`) as Error & { status: number };
+        err.status = response.status;
+        throw err;
+      } catch (e) {
+        throw e;
+      }
+    }
+
+    if (typeof XMLHttpRequest !== 'undefined') {
+      return new Promise((resolve, reject) => {
+        const xhr = new XMLHttpRequest();
+        xhr.open('POST', url, !isSync);
+        xhr.setRequestHeader('Content-Type', 'application/x-sentry-envelope');
+        xhr.timeout = 10000;
+        xhr.onload = () => {
+          if (xhr.status >= 200 && xhr.status < 300) {
+            resolve();
+          } else {
+            const err = new Error(`HTTP ${xhr.status}`) as Error & { status: number };
+            err.status = xhr.status;
+            reject(err);
+          }
+        };
+        xhr.onerror = () => reject(new Error('Network error'));
+        xhr.ontimeout = () => reject(new Error('Request timeout'));
+        xhr.send(body);
+      });
+    }
+
+    throw new Error('No transport available');
+  }
+ 
+  private sendSync(body: string): boolean {
+    const url = getEnvelopeUrl(this.dsn);
+
+    if (navigator.sendBeacon) {
+      try {
+        const blob = new Blob([body], { type: 'application/x-sentry-envelope' });
+        return navigator.sendBeacon(url, blob);
+      } catch {
+        return false;
+      }
+    }
+
+    if (typeof XMLHttpRequest !== 'undefined') {
+      try {
+        const xhr = new XMLHttpRequest();
+        xhr.open('POST', url, false);
+        xhr.setRequestHeader('Content-Type', 'application/x-sentry-envelope');
+        xhr.send(body);
+        return xhr.status >= 200 && xhr.status < 300;
+      } catch {
+        return false;
+      }
+    }
+
+    return false;
+  }
+ 
+  private sendViaImage(body: string): boolean {
+    try {
+      const url = getEnvelopeUrl(this.dsn);
+      const img = new Image();
+      const encoded = encodeURIComponent(btoa(body));
+      const separator = url.includes('?') ? '&' : '?';
+      img.src = url + separator + 'sentry_data=' + encoded.substring(0, 2000);
+      return true;
+    } catch {
+      return false;
+    }
+  }
+ 
+  private delay(ms: number): Promise<void> {
+    return new Promise(resolve => setTimeout(resolve, ms));
+  }
+}
+ 
+ +
+
+ + + + + + + + \ No newline at end of file diff --git a/coverage/src/core/TracingManager.ts.html b/coverage/src/core/TracingManager.ts.html new file mode 100644 index 0000000..c21acf2 --- /dev/null +++ b/coverage/src/core/TracingManager.ts.html @@ -0,0 +1,679 @@ + + + + + + Code coverage report for src/core/TracingManager.ts + + + + + + + + + +
+
+

All files / src/core TracingManager.ts

+
+ +
+ 86.86% + Statements + 172/198 +
+ + +
+ 80% + Branches + 28/35 +
+ + +
+ 78.57% + Functions + 11/14 +
+ + +
+ 86.86% + Lines + 172/198 +
+ + +
+

+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +

+ +
+
+

+
1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +30 +31 +32 +33 +34 +35 +36 +37 +38 +39 +40 +41 +42 +43 +44 +45 +46 +47 +48 +49 +50 +51 +52 +53 +54 +55 +56 +57 +58 +59 +60 +61 +62 +63 +64 +65 +66 +67 +68 +69 +70 +71 +72 +73 +74 +75 +76 +77 +78 +79 +80 +81 +82 +83 +84 +85 +86 +87 +88 +89 +90 +91 +92 +93 +94 +95 +96 +97 +98 +99 +100 +101 +102 +103 +104 +105 +106 +107 +108 +109 +110 +111 +112 +113 +114 +115 +116 +117 +118 +119 +120 +121 +122 +123 +124 +125 +126 +127 +128 +129 +130 +131 +132 +133 +134 +135 +136 +137 +138 +139 +140 +141 +142 +143 +144 +145 +146 +147 +148 +149 +150 +151 +152 +153 +154 +155 +156 +157 +158 +159 +160 +161 +162 +163 +164 +165 +166 +167 +168 +169 +170 +171 +172 +173 +174 +175 +176 +177 +178 +179 +180 +181 +182 +183 +184 +185 +186 +187 +188 +189 +190 +191 +192 +193 +194 +195 +196 +197 +198 +1991x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +29x +29x +29x +29x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +19x +19x +2x +2x +2x +2x +2x +2x +2x +2x +  +  +  +  +  +17x +19x +19x +2x +  +19x +1x +1x +20x +20x +20x +20x +20x +20x +20x +20x +20x +20x +20x +20x +20x +20x +20x +20x +20x +20x +20x +20x +20x +20x +20x +20x +20x +20x +20x +20x +20x +1x +1x +8x +8x +1x +1x +  +  +  +  +  +  +  +1x +1x +16x +16x +1x +1x +2x +1x +1x +1x +1x +1x +1x +2x +1x +1x +8x +8x +8x +1x +1x +1x +7x +7x +7x +8x +6x +8x +1x +1x +1x +1x +1x +1x +  +  +  +  +  +1x +7x +7x +7x +7x +7x +7x +7x +7x +7x +7x +7x +7x +8x +1x +1x +1x +1x +1x +1x +1x +1x +  +  +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +2x +2x +2x +2x +2x +2x +2x +2x +2x +2x +2x +2x +1x +1x +  +  +1x +1x +  +  +1x +1x +31x +17x +17x +17x +17x +  +  +17x +31x +31x +31x +1x + 
import type { LightConfig, SpanContext, TransactionContext, Span, Transaction, LightClient, SamplingContext } from '../types';
+import { Span as SpanImpl, Transaction as TransactionImpl } from '../utils/tracing';
+import { logDebug } from '../utils/logger';
+ 
+export class TracingManager {
+  private config: LightConfig;
+  private _client?: LightClient;
+  private currentTransaction: Transaction | null = null;
+  private spanStack: Span[] = [];
+  private dsnPublicKey?: string;
+ 
+  constructor(config: LightConfig, client?: LightClient, dsnPublicKey?: string) {
+    this.config = config;
+    this._client = client;
+    this.dsnPublicKey = dsnPublicKey;
+  }
+ 
+  updateConfig(config: LightConfig): void {
+    this.config = config;
+    if (this.currentTransaction) {
+      const txImpl = this.currentTransaction as unknown as TransactionImpl;
+      txImpl.setUserBaggage(config.user?.id, (config.user as { segment?: string } | undefined)?.segment);
+    }
+  }
+ 
+  private shouldSample(context: TransactionContext, parentSampled?: boolean): boolean {
+    const sampler = this.config.tracesSampler;
+    if (sampler) {
+      const samplingContext: SamplingContext = {
+        ...context,
+        parentSampled,
+      };
+      const result = sampler(samplingContext);
+      if (typeof result === 'boolean') {
+        return result;
+      }
+      const clampedRate = Math.max(0, Math.min(1, result));
+      if (clampedRate === 0) return false;
+      if (clampedRate === 1) return true;
+      return Math.random() < clampedRate;
+    }
+ 
+    const rate = this.config.tracesSampleRate ?? 0;
+    if (rate >= 1) return true;
+    if (rate <= 0) return false;
+    return Math.random() < rate;
+  }
+ 
+  startTransaction(context: TransactionContext): Transaction | null {
+    const parentTx = this.currentTransaction;
+    const parentSampled = parentTx ? parentTx.sampled : undefined;
+ 
+    const sampled = context.sampled ?? this.shouldSample(context, parentSampled);
+ 
+    const transaction = new TransactionImpl(
+      {
+        ...context,
+        sampled,
+      },
+      this._client,
+      this.dsnPublicKey,
+      this.config.release,
+      this.config.environment
+    ) as unknown as Transaction;
+ 
+    this.currentTransaction = transaction;
+    this.spanStack = [transaction];
+ 
+    logDebug('TracingManager', 'Transaction started', {
+      name: transaction.name,
+      traceId: transaction.traceId,
+      spanId: transaction.spanId,
+      sampled,
+      op: transaction.op,
+    });
+ 
+    return transaction;
+  }
+ 
+  getCurrentTransaction(): Transaction | null {
+    return this.currentTransaction;
+  }
+ 
+  setCurrentTransaction(transaction: Transaction | null): void {
+    this.currentTransaction = transaction;
+    if (!transaction) {
+      this.spanStack = [];
+    } else {
+      this.spanStack = [transaction];
+    }
+  }
+ 
+  getCurrentSpan(): Span | null {
+    return this.spanStack.length > 0 ? this.spanStack[this.spanStack.length - 1] : null;
+  }
+ 
+  setCurrentSpan(span: Span | null): void {
+    if (span === null) {
+      if (this.spanStack.length > 1) {
+        this.spanStack.pop();
+      }
+    } else {
+      this.spanStack.push(span);
+    }
+  }
+ 
+  startSpan(context: SpanContext): Span | null {
+    const parentSpan = this.getCurrentSpan();
+ 
+    if (!parentSpan && !context.traceId) {
+      logDebug('TracingManager', 'startSpan skipped: no active span and no traceId');
+      return null;
+    }
+ 
+    let span: Span;
+ 
+    if (parentSpan) {
+      span = (parentSpan as SpanImpl).startChild(context);
+    } else {
+      span = new SpanImpl({
+        ...context,
+        parentSpanId: context.parentSpanId,
+      }) as unknown as Span;
+ 
+      if (this.currentTransaction) {
+        if (this.currentTransaction.sampled !== false) {
+          (this.currentTransaction as unknown as TransactionImpl)._addSpan(span as unknown as SpanImpl);
+        }
+        (span as SpanImpl & { transaction: Transaction }).transaction = this.currentTransaction;
+      }
+    }
+ 
+    this.spanStack.push(span);
+ 
+    logDebug('TracingManager', 'Span started', {
+      op: span.op,
+      description: span.description,
+      spanId: span.spanId,
+      parentSpanId: span.parentSpanId,
+      stackDepth: this.spanStack.length,
+    });
+ 
+    return span;
+  }
+ 
+  onSpanFinished(span: Span): void {
+    const idx = this.spanStack.lastIndexOf(span);
+    if (idx !== -1) {
+      this.spanStack.splice(idx, 1);
+    }
+ 
+    if (this.spanStack.length === 0 && this.currentTransaction) {
+      this.spanStack = [this.currentTransaction];
+    }
+ 
+    logDebug('TracingManager', 'Span finished', {
+      op: span.op,
+      description: span.description,
+      spanId: span.spanId,
+      stackDepth: this.spanStack.length,
+    });
+  }
+ 
+  onTransactionFinished(transaction: Transaction): void {
+    if (this.currentTransaction === transaction) {
+      this.currentTransaction = null;
+      this.spanStack = [];
+    }
+ 
+    logDebug('TracingManager', 'Transaction finished', {
+      name: transaction.name,
+      traceId: transaction.traceId,
+      spanCount: transaction.spans.length,
+      sampled: transaction.sampled,
+    });
+  }
+ 
+  finishSpan(span: Span): void {
+    span.finish();
+  }
+ 
+  finishTransaction(transaction: Transaction): void {
+    transaction.finish();
+  }
+ 
+  destroy(): void {
+    if (this.currentTransaction) {
+      try {
+        this.currentTransaction.setStatus('aborted');
+        this.currentTransaction.finish();
+      } catch {
+        // ignore
+      }
+    }
+    this.currentTransaction = null;
+    this.spanStack = [];
+  }
+}
+ 
+ +
+
+ + + + + + + + \ No newline at end of file diff --git a/coverage/src/core/index.html b/coverage/src/core/index.html new file mode 100644 index 0000000..0aeb5a0 --- /dev/null +++ b/coverage/src/core/index.html @@ -0,0 +1,206 @@ + + + + + + Code coverage report for src/core + + + + + + + + + +
+
+

All files src/core

+
+ +
+ 60.64% + Statements + 974/1606 +
+ + +
+ 85.78% + Branches + 169/197 +
+ + +
+ 52% + Functions + 52/100 +
+ + +
+ 60.64% + Lines + 974/1606 +
+ + +
+

+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +

+ +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FileStatementsBranchesFunctionsLines
Client.ts +
+
24.72%90/364100%0/00%0/2924.72%90/364
ConfigManager.ts +
+
95.9%234/24481.81%45/5592.85%13/1495.9%234/244
EventBus.ts +
+
100%47/47100%13/13100%7/7100%47/47
EventQueue.ts +
+
89.9%285/31783.82%57/6881.25%13/1689.9%285/317
PluginManager.ts +
+
100%87/87100%26/26100%8/8100%87/87
Reporter.ts +
+
16.9%59/349100%0/00%0/1216.9%59/349
TracingManager.ts +
+
86.86%172/19880%28/3578.57%11/1486.86%172/198
+
+
+
+ + + + + + + + \ No newline at end of file diff --git a/coverage/src/index.html b/coverage/src/index.html new file mode 100644 index 0000000..6fb3373 --- /dev/null +++ b/coverage/src/index.html @@ -0,0 +1,116 @@ + + + + + + Code coverage report for src + + + + + + + + + +
+
+

All files src

+
+ +
+ 50.39% + Statements + 127/252 +
+ + +
+ 100% + Branches + 0/0 +
+ + +
+ 0% + Functions + 0/21 +
+ + +
+ 50.39% + Lines + 127/252 +
+ + +
+

+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +

+ +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FileStatementsBranchesFunctionsLines
index.ts +
+
50.39%127/252100%0/00%0/2150.39%127/252
+
+
+
+ + + + + + + + \ No newline at end of file diff --git a/coverage/src/index.ts.html b/coverage/src/index.ts.html new file mode 100644 index 0000000..6c978c1 --- /dev/null +++ b/coverage/src/index.ts.html @@ -0,0 +1,841 @@ + + + + + + Code coverage report for src/index.ts + + + + + + + + + +
+
+

All files / src index.ts

+
+ +
+ 50.39% + Statements + 127/252 +
+ + +
+ 100% + Branches + 0/0 +
+ + +
+ 0% + Functions + 0/21 +
+ + +
+ 50.39% + Lines + 127/252 +
+ + +
+

+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +

+ +
+
+

+
1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +30 +31 +32 +33 +34 +35 +36 +37 +38 +39 +40 +41 +42 +43 +44 +45 +46 +47 +48 +49 +50 +51 +52 +53 +54 +55 +56 +57 +58 +59 +60 +61 +62 +63 +64 +65 +66 +67 +68 +69 +70 +71 +72 +73 +74 +75 +76 +77 +78 +79 +80 +81 +82 +83 +84 +85 +86 +87 +88 +89 +90 +91 +92 +93 +94 +95 +96 +97 +98 +99 +100 +101 +102 +103 +104 +105 +106 +107 +108 +109 +110 +111 +112 +113 +114 +115 +116 +117 +118 +119 +120 +121 +122 +123 +124 +125 +126 +127 +128 +129 +130 +131 +132 +133 +134 +135 +136 +137 +138 +139 +140 +141 +142 +143 +144 +145 +146 +147 +148 +149 +150 +151 +152 +153 +154 +155 +156 +157 +158 +159 +160 +161 +162 +163 +164 +165 +166 +167 +168 +169 +170 +171 +172 +173 +174 +175 +176 +177 +178 +179 +180 +181 +182 +183 +184 +185 +186 +187 +188 +189 +190 +191 +192 +193 +194 +195 +196 +197 +198 +199 +200 +201 +202 +203 +204 +205 +206 +207 +208 +209 +210 +211 +212 +213 +214 +215 +216 +217 +218 +219 +220 +221 +222 +223 +224 +225 +226 +227 +228 +229 +230 +231 +232 +233 +234 +235 +236 +237 +238 +239 +240 +241 +242 +243 +244 +245 +246 +247 +248 +249 +250 +251 +252 +2531x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +1x +  +  +  +1x +  +  +  +  +  +  +  +  +1x +  +  +  +  +  +  +  +  +1x +  +  +  +  +  +  +  +  +1x +  +  +  +1x +  +  +  +1x +  +  +  +1x +  +  +  +1x +  +  +  +1x +  +  +  +1x +  +  +  +1x +  +  +  +1x +  +  +  +1x +  +  +  +1x +  +  +  +1x +  +  +  +1x +  +  +  +1x +  +  +  +1x +  +  +  +1x +  +  +  +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x + 
import Client from './core/Client';
+import ErrorPlugin from './plugins/ErrorPlugin';
+import PerformancePlugin from './plugins/PerformancePlugin';
+import NetworkPlugin from './plugins/NetworkPlugin';
+import BehaviorPlugin from './plugins/BehaviorPlugin';
+import OfflinePlugin from './plugins/OfflinePlugin';
+import SamplingPlugin from './plugins/SamplingPlugin';
+import RouterPlugin from './plugins/RouterPlugin';
+import InteractionPlugin from './plugins/InteractionPlugin';
+import { Span as SpanClass, Transaction as TransactionClass, httpStatusToSpanStatus, dbStatusToSpanStatus, statusToSpanStatus } from './utils/tracing';
+import { serializeBaggage, parseBaggage, createBaggageFromTransaction } from './utils/baggage';
+import type { LightConfig, LightClient, SentryEvent, EventLevel, UserInfo, Breadcrumb, LightPlugin, ErrorEvent, PerformanceEvent, NetworkEvent, BehaviorEvent, DSNInfo, TransactionContext, SpanContext, Transaction, Span, SamplingContext, BaggageFields, SpanStatus } from './types';
+import { logDebug, setDebug } from './utils/logger';
+import { setAnonymousId as setStoredAnonymousId, clearAnonymousId as clearStoredAnonymousId, getAnonymousId as getStoredAnonymousId } from './utils/identity';
+ 
+let globalClient: LightClient | null = null;
+ 
+function init(config: LightConfig): LightClient {
+  setDebug(config.debug === true);
+  logDebug('Index', 'init called', { dsn: config.dsn, debug: config.debug });
+
+  const client = new Client(config);
+
+  const defaultPlugins: LightPlugin[] = [
+    new OfflinePlugin(),
+    new SamplingPlugin(),
+    new ErrorPlugin(),
+  ];
+
+  const pluginNames = config.plugins?.filter(p => typeof p === 'string') as string[] || [];
+  
+  if (pluginNames.includes('performance') || pluginNames.includes('all')) {
+    defaultPlugins.push(new PerformancePlugin());
+  }
+  if (pluginNames.includes('network') || pluginNames.includes('all')) {
+    defaultPlugins.push(new NetworkPlugin());
+  }
+  if (pluginNames.includes('behavior') || pluginNames.includes('all')) {
+    defaultPlugins.push(new BehaviorPlugin());
+  }
+  if (pluginNames.includes('router') || pluginNames.includes('all')) {
+    defaultPlugins.push(new RouterPlugin());
+  }
+  if (pluginNames.includes('interaction') || pluginNames.includes('all')) {
+    defaultPlugins.push(new InteractionPlugin());
+  }
+
+  logDebug('Index', 'Registering plugins', { count: defaultPlugins.length, plugins: defaultPlugins.map(p => p.name) });
+
+  for (const plugin of defaultPlugins) {
+    client.use(plugin);
+  }
+
+  if (config.plugins) {
+    for (const plugin of config.plugins) {
+      if (typeof plugin === 'object' && plugin !== null && 'name' in plugin && 'setup' in plugin) {
+        client.use(plugin as LightPlugin);
+      }
+    }
+  }
+
+  client.init();
+
+  globalClient = client;
+  logDebug('Index', 'init completed, globalClient set');
+  return client;
+}
+ 
+function getClient(): LightClient | null {
+  return globalClient;
+}
+ 
+function captureException(error: Error | unknown): void {
+  logDebug('Index', 'captureException called', { hasClient: !!globalClient });
+  if (!globalClient) {
+    console.warn('[LightSDK] SDK not initialized. Call LightSentry.init() first.');
+    return;
+  }
+  globalClient.captureException(error);
+}
+ 
+function captureMessage(message: string, level?: EventLevel): void {
+  logDebug('Index', 'captureMessage called', { hasClient: !!globalClient });
+  if (!globalClient) {
+    console.warn('[LightSDK] SDK not initialized. Call LightSentry.init() first.');
+    return;
+  }
+  globalClient.captureMessage(message, level);
+}
+ 
+function captureEvent(event: Partial<SentryEvent> & { type: string }): void {
+  logDebug('Index', 'captureEvent called', { hasClient: !!globalClient });
+  if (!globalClient) {
+    console.warn('[LightSDK] SDK not initialized. Call LightSentry.init() first.');
+    return;
+  }
+  globalClient.captureEvent(event);
+}
+ 
+function setUser(user: UserInfo | null): void {
+  globalClient?.setUser(user);
+}
+ 
+function setAnonymousId(id: string): void {
+  setStoredAnonymousId(id);
+}
+ 
+function clearAnonymousId(): void {
+  clearStoredAnonymousId();
+}
+ 
+function getAnonymousId(): string | null {
+  return getStoredAnonymousId();
+}
+ 
+function startTransaction(context: TransactionContext): Transaction | null {
+  return globalClient?.startTransaction(context) || null;
+}
+ 
+function getCurrentTransaction(): Transaction | null {
+  return globalClient?.getCurrentTransaction() || null;
+}
+ 
+function getCurrentSpan(): Span | null {
+  return globalClient?.getCurrentSpan() || null;
+}
+ 
+function setSpan(span: Span | null): void {
+  globalClient?.setSpan(span);
+}
+ 
+function startSpan(context: SpanContext): Span | null {
+  return globalClient?.startSpan(context) || null;
+}
+ 
+function setTag(key: string, value: string): void {
+  globalClient?.setTag(key, value);
+}
+ 
+function setTags(tags: Record<string, string>): void {
+  globalClient?.setTags(tags);
+}
+ 
+function setExtra(key: string, value: unknown): void {
+  globalClient?.setExtra(key, value);
+}
+ 
+function addBreadcrumb(breadcrumb: Omit<Breadcrumb, 'timestamp'>): void {
+  globalClient?.addBreadcrumb(breadcrumb);
+}
+ 
+async function flush(): Promise<void> {
+  await globalClient?.flush();
+}
+ 
+function disable(): void {
+  globalClient?.disable();
+}
+ 
+function enable(): void {
+  globalClient?.enable();
+}
+ 
+export {
+  init,
+  getClient,
+  captureException,
+  captureMessage,
+  captureEvent,
+  setUser,
+  setAnonymousId,
+  clearAnonymousId,
+  getAnonymousId,
+  startTransaction,
+  getCurrentTransaction,
+  getCurrentSpan,
+  setSpan,
+  startSpan,
+  setTag,
+  setTags,
+  setExtra,
+  addBreadcrumb,
+  flush,
+  disable,
+  enable,
+  Client,
+  httpStatusToSpanStatus,
+  dbStatusToSpanStatus,
+  statusToSpanStatus,
+  serializeBaggage,
+  parseBaggage,
+  createBaggageFromTransaction,
+  ErrorPlugin,
+  PerformancePlugin,
+  NetworkPlugin,
+  BehaviorPlugin,
+  OfflinePlugin,
+  SamplingPlugin,
+  RouterPlugin,
+  InteractionPlugin,
+};
+ 
+export { SpanClass as Span, TransactionClass as Transaction };
+ 
+export type {
+  LightConfig,
+  LightClient,
+  LightPlugin,
+  SentryEvent,
+  ErrorEvent,
+  PerformanceEvent,
+  NetworkEvent,
+  BehaviorEvent,
+  EventLevel,
+  UserInfo,
+  Breadcrumb,
+  DSNInfo,
+  TransactionContext,
+  SpanContext,
+  SamplingContext,
+  BaggageFields,
+  SpanStatus,
+  SpanJSON,
+  TransactionJSON,
+};
+ 
+export default {
+  init,
+  getClient,
+  captureException,
+  captureMessage,
+  captureEvent,
+  setUser,
+  setAnonymousId,
+  clearAnonymousId,
+  getAnonymousId,
+  startTransaction,
+  getCurrentTransaction,
+  getCurrentSpan,
+  setSpan,
+  startSpan,
+  setTag,
+  setTags,
+  setExtra,
+  addBreadcrumb,
+  flush,
+  disable,
+  enable,
+  Span: SpanClass,
+  Transaction: TransactionClass,
+  httpStatusToSpanStatus,
+};
+ 
+ +
+
+ + + + + + + + \ No newline at end of file diff --git a/coverage/src/plugins/BehaviorPlugin.ts.html b/coverage/src/plugins/BehaviorPlugin.ts.html new file mode 100644 index 0000000..e38d043 --- /dev/null +++ b/coverage/src/plugins/BehaviorPlugin.ts.html @@ -0,0 +1,1090 @@ + + + + + + Code coverage report for src/plugins/BehaviorPlugin.ts + + + + + + + + + +
+
+

All files / src/plugins BehaviorPlugin.ts

+
+ +
+ 15.52% + Statements + 52/335 +
+ + +
+ 100% + Branches + 0/0 +
+ + +
+ 0% + Functions + 0/13 +
+ + +
+ 15.52% + Lines + 52/335 +
+ + +
+

+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +

+ +
+
+

+
1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +30 +31 +32 +33 +34 +35 +36 +37 +38 +39 +40 +41 +42 +43 +44 +45 +46 +47 +48 +49 +50 +51 +52 +53 +54 +55 +56 +57 +58 +59 +60 +61 +62 +63 +64 +65 +66 +67 +68 +69 +70 +71 +72 +73 +74 +75 +76 +77 +78 +79 +80 +81 +82 +83 +84 +85 +86 +87 +88 +89 +90 +91 +92 +93 +94 +95 +96 +97 +98 +99 +100 +101 +102 +103 +104 +105 +106 +107 +108 +109 +110 +111 +112 +113 +114 +115 +116 +117 +118 +119 +120 +121 +122 +123 +124 +125 +126 +127 +128 +129 +130 +131 +132 +133 +134 +135 +136 +137 +138 +139 +140 +141 +142 +143 +144 +145 +146 +147 +148 +149 +150 +151 +152 +153 +154 +155 +156 +157 +158 +159 +160 +161 +162 +163 +164 +165 +166 +167 +168 +169 +170 +171 +172 +173 +174 +175 +176 +177 +178 +179 +180 +181 +182 +183 +184 +185 +186 +187 +188 +189 +190 +191 +192 +193 +194 +195 +196 +197 +198 +199 +200 +201 +202 +203 +204 +205 +206 +207 +208 +209 +210 +211 +212 +213 +214 +215 +216 +217 +218 +219 +220 +221 +222 +223 +224 +225 +226 +227 +228 +229 +230 +231 +232 +233 +234 +235 +236 +237 +238 +239 +240 +241 +242 +243 +244 +245 +246 +247 +248 +249 +250 +251 +252 +253 +254 +255 +256 +257 +258 +259 +260 +261 +262 +263 +264 +265 +266 +267 +268 +269 +270 +271 +272 +273 +274 +275 +276 +277 +278 +279 +280 +281 +282 +283 +284 +285 +286 +287 +288 +289 +290 +291 +292 +293 +294 +295 +296 +297 +298 +299 +300 +301 +302 +303 +304 +305 +306 +307 +308 +309 +310 +311 +312 +313 +314 +315 +316 +317 +318 +319 +320 +321 +322 +323 +324 +325 +326 +327 +328 +329 +330 +331 +332 +333 +334 +335 +3361x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +1x +1x +  +  +  +  +  +1x +1x +  +  +  +  +  +1x +1x +  +  +  +  +  +  +  +  +  +  +1x +1x +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +1x +1x +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +1x +1x +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +1x +1x +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +1x +1x +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +1x +1x +  +  +  +  +  +  +  +  +  +  +  +1x +1x +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +1x +1x +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +1x +1x +1x + 
import type { LightPlugin, LightClient, BehaviorEvent, LightConfig } from '../types';
+import { now, isObject } from '../utils/helper';
+import { getPageUrl, sanitizeUrl } from '../utils/env';
+ 
+interface BehaviorPluginConfig {
+  capturePV?: boolean;
+  captureClick?: boolean;
+  captureRoute?: boolean;
+  captureDuration?: boolean;
+  captureScroll?: boolean;
+  clickThrottle?: number;
+  scrollThrottle?: number;
+  sampleRate?: number;
+}
+ 
+class BehaviorPlugin implements LightPlugin {
+  name = 'behavior';
+  version = '1.0.0';
+
+  private client!: LightClient;
+  private config: BehaviorPluginConfig = {
+    capturePV: true,
+    captureClick: true,
+    captureRoute: true,
+    captureDuration: true,
+    captureScroll: true,
+    clickThrottle: 300,
+    scrollThrottle: 1000,
+    sampleRate: 0.01,
+  };
+
+  private lastClickTime: number = 0;
+  private lastScrollTime: number = 0;
+  private maxScrollDepth: number = 0;
+  private pageEnterTime: number = 0;
+  private scrollReported: boolean = false;
+ 
+  private originalPushState?: typeof history.pushState;
+  private originalReplaceState?: typeof history.replaceState;
+  private onScroll?: () => void;
+  private onClick?: (e: Event) => void;
+  private onVisibilityChange?: () => void;
+  private onBeforeUnload?: () => void;
+  private onPagehide?: () => void;
+  private onPopState?: () => void;
+  private onHashchange?: () => void;
+ 
+  setup(client: LightClient): void {
+    this.client = client;
+    this.loadConfig();
+
+    if (this.config.capturePV) {
+      this.trackPV();
+    }
+    if (this.config.captureClick) {
+      this.trackClick();
+    }
+    if (this.config.captureRoute) {
+      this.trackRoute();
+    }
+    if (this.config.captureDuration) {
+      this.trackPageDuration();
+    }
+    if (this.config.captureScroll) {
+      this.trackScroll();
+    }
+  }
+ 
+  private loadConfig(): void {
+    const clientConfig = this.client.config as LightConfig;
+    if (clientConfig && isObject(clientConfig.behavior)) {
+      this.config = { ...this.config, ...(clientConfig.behavior as object) };
+    }
+  }
+ 
+  private shouldSample(): boolean {
+    const rate = this.config.sampleRate ?? 0.01;
+    if (rate >= 1) return true;
+    if (rate <= 0) return false;
+    return Math.random() < rate;
+  }
+ 
+  private getScrollDepth(): number {
+    if (typeof window === 'undefined' || typeof document === 'undefined') return 0;
+    
+    const scrollTop = window.scrollY || document.documentElement.scrollTop;
+    const scrollHeight = document.documentElement.scrollHeight;
+    const clientHeight = document.documentElement.clientHeight;
+    
+    if (scrollHeight <= clientHeight) return 100;
+    
+    return Math.min(100, Math.round((scrollTop / (scrollHeight - clientHeight)) * 100));
+  }
+ 
+  private trackPV(): void {
+    if (typeof window === 'undefined') return;
+
+    const url = getPageUrl();
+    const referrer = sanitizeUrl(document.referrer || '');
+
+    this.reportBehavior({
+      sub_type: 'pv',
+      page_url: url,
+      referrer,
+      properties: {
+        title: document.title,
+        user_agent: navigator.userAgent,
+        screen_width: screen.width,
+        screen_height: screen.height,
+        viewport_width: window.innerWidth,
+        viewport_height: window.innerHeight,
+        language: navigator.language,
+      },
+    });
+  }
+ 
+  private trackClick(): void {
+    if (typeof document === 'undefined') return;
+
+    this.onClick = (e: Event) => {
+      const currentTime = now();
+      const throttle = this.config.clickThrottle ?? 300;
+      if (currentTime - this.lastClickTime < throttle) {
+        return;
+      }
+      this.lastClickTime = currentTime;
+
+      const target = e.target as HTMLElement;
+      if (!target || !target.tagName) return;
+
+      let selector = target.tagName.toLowerCase() || '';
+      if (target.id) {
+        selector += `#${target.id}`;
+      }
+      if (target.className && typeof target.className === 'string') {
+        const classes = target.className.split(' ').filter(Boolean).slice(0, 3).join('.');
+        if (classes) {
+          selector += `.${classes}`;
+        }
+      }
+
+      const text = target.textContent?.trim().slice(0, 50);
+
+      this.reportBehavior({
+        sub_type: 'click',
+        page_url: getPageUrl(),
+        properties: {
+          selector,
+          text: text || undefined,
+          tag: target.tagName?.toLowerCase(),
+          x: (e as MouseEvent).clientX,
+          y: (e as MouseEvent).clientY,
+        },
+      });
+    };
+
+    document.addEventListener('click', this.onClick, true);
+  }
+ 
+  private trackRoute(): void {
+    if (typeof window === 'undefined') return;
+
+    let lastUrl = getPageUrl();
+
+    const checkRoute = () => {
+      const currentUrl = getPageUrl();
+      if (currentUrl !== lastUrl) {
+        const from = lastUrl;
+        const to = currentUrl;
+        lastUrl = currentUrl;
+
+        this.reportBehavior({
+          sub_type: 'route',
+          page_url: to,
+          referrer: from,
+          properties: {
+            from,
+            to,
+          },
+        });
+
+        this.pageEnterTime = now();
+        this.maxScrollDepth = 0;
+        this.scrollReported = false;
+      }
+    };
+
+    this.originalPushState = history.pushState;
+    this.originalReplaceState = history.replaceState;
+    const self = this;
+
+    history.pushState = function () {
+      const result = self.originalPushState!.apply(this, arguments as unknown as Parameters<typeof history.pushState>);
+      setTimeout(checkRoute, 0);
+      return result;
+    };
+
+    history.replaceState = function () {
+      const result = self.originalReplaceState!.apply(this, arguments as unknown as Parameters<typeof history.replaceState>);
+      setTimeout(checkRoute, 0);
+      return result;
+    };
+
+    this.onPopState = () => { setTimeout(checkRoute, 0); };
+    this.onHashchange = () => { setTimeout(checkRoute, 0); };
+
+    window.addEventListener('popstate', this.onPopState);
+    window.addEventListener('hashchange', this.onHashchange);
+  }
+ 
+  private trackPageDuration(): void {
+    if (typeof window === 'undefined') return;
+
+    this.pageEnterTime = now();
+
+    const sendDuration = () => {
+      const duration = now() - this.pageEnterTime;
+      if (duration > 1000) {
+        if (this.config.captureScroll && !this.scrollReported) {
+          this.reportScroll();
+        }
+
+        this.reportBehavior({
+          sub_type: 'duration',
+          page_url: getPageUrl(),
+          properties: {
+            duration,
+            max_scroll_depth: this.maxScrollDepth,
+          },
+        });
+      }
+    };
+
+    this.onVisibilityChange = () => {
+      if (document.hidden) {
+        sendDuration();
+      } else {
+        this.pageEnterTime = now();
+      }
+    };
+
+    this.onBeforeUnload = sendDuration;
+    this.onPagehide = sendDuration;
+
+    document.addEventListener('visibilitychange', this.onVisibilityChange);
+    window.addEventListener('beforeunload', this.onBeforeUnload);
+    window.addEventListener('pagehide', this.onPagehide);
+  }
+ 
+  private trackScroll(): void {
+    if (typeof window === 'undefined') return;
+
+    this.onScroll = () => {
+      const currentTime = now();
+      const throttle = this.config.scrollThrottle ?? 1000;
+      if (currentTime - this.lastScrollTime < throttle) {
+        return;
+      }
+      this.lastScrollTime = currentTime;
+
+      const depth = this.getScrollDepth();
+      if (depth > this.maxScrollDepth) {
+        this.maxScrollDepth = depth;
+      }
+    };
+
+    window.addEventListener('scroll', this.onScroll, { passive: true });
+  }
+ 
+  private reportScroll(): void {
+    if (this.scrollReported) return;
+    this.scrollReported = true;
+
+    this.reportBehavior({
+      sub_type: 'scroll',
+      page_url: getPageUrl(),
+      properties: {
+        max_depth: this.maxScrollDepth,
+      },
+    });
+  }
+ 
+  private reportBehavior(data: Omit<BehaviorEvent, 'type' | 'level' | 'timestamp'>): void {
+    if (!this.shouldSample()) return;
+
+    const event: BehaviorEvent = {
+      type: 'behavior',
+      level: 'info',
+      timestamp: now(),
+      tags: {
+        sub_type: data.sub_type,
+        page_url: getPageUrl(),
+      },
+      ...data,
+    };
+
+    this.client.captureEvent(event);
+  }
+ 
+  destroy(): void {
+    if (typeof window !== 'undefined') {
+      if (this.originalPushState) {
+        history.pushState = this.originalPushState;
+      }
+      if (this.originalReplaceState) {
+        history.replaceState = this.originalReplaceState;
+      }
+      if (this.onPopState) {
+        window.removeEventListener('popstate', this.onPopState);
+      }
+      if (this.onHashchange) {
+        window.removeEventListener('hashchange', this.onHashchange);
+      }
+      if (this.onBeforeUnload) {
+        window.removeEventListener('beforeunload', this.onBeforeUnload);
+      }
+      if (this.onPagehide) {
+        window.removeEventListener('pagehide', this.onPagehide);
+      }
+      if (this.onScroll) {
+        window.removeEventListener('scroll', this.onScroll);
+      }
+    }
+    if (typeof document !== 'undefined') {
+      if (this.onClick) {
+        document.removeEventListener('click', this.onClick, true);
+      }
+      if (this.onVisibilityChange) {
+        document.removeEventListener('visibilitychange', this.onVisibilityChange);
+      }
+    }
+  }
+}
+ 
+export default BehaviorPlugin;
+ 
+ +
+
+ + + + + + + + \ No newline at end of file diff --git a/coverage/src/plugins/ErrorPlugin.ts.html b/coverage/src/plugins/ErrorPlugin.ts.html new file mode 100644 index 0000000..0826c07 --- /dev/null +++ b/coverage/src/plugins/ErrorPlugin.ts.html @@ -0,0 +1,982 @@ + + + + + + Code coverage report for src/plugins/ErrorPlugin.ts + + + + + + + + + +
+
+

All files / src/plugins ErrorPlugin.ts

+
+ +
+ 17.39% + Statements + 52/299 +
+ + +
+ 100% + Branches + 0/0 +
+ + +
+ 0% + Functions + 0/14 +
+ + +
+ 17.39% + Lines + 52/299 +
+ + +
+

+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +

+ +
+
+

+
1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +30 +31 +32 +33 +34 +35 +36 +37 +38 +39 +40 +41 +42 +43 +44 +45 +46 +47 +48 +49 +50 +51 +52 +53 +54 +55 +56 +57 +58 +59 +60 +61 +62 +63 +64 +65 +66 +67 +68 +69 +70 +71 +72 +73 +74 +75 +76 +77 +78 +79 +80 +81 +82 +83 +84 +85 +86 +87 +88 +89 +90 +91 +92 +93 +94 +95 +96 +97 +98 +99 +100 +101 +102 +103 +104 +105 +106 +107 +108 +109 +110 +111 +112 +113 +114 +115 +116 +117 +118 +119 +120 +121 +122 +123 +124 +125 +126 +127 +128 +129 +130 +131 +132 +133 +134 +135 +136 +137 +138 +139 +140 +141 +142 +143 +144 +145 +146 +147 +148 +149 +150 +151 +152 +153 +154 +155 +156 +157 +158 +159 +160 +161 +162 +163 +164 +165 +166 +167 +168 +169 +170 +171 +172 +173 +174 +175 +176 +177 +178 +179 +180 +181 +182 +183 +184 +185 +186 +187 +188 +189 +190 +191 +192 +193 +194 +195 +196 +197 +198 +199 +200 +201 +202 +203 +204 +205 +206 +207 +208 +209 +210 +211 +212 +213 +214 +215 +216 +217 +218 +219 +220 +221 +222 +223 +224 +225 +226 +227 +228 +229 +230 +231 +232 +233 +234 +235 +236 +237 +238 +239 +240 +241 +242 +243 +244 +245 +246 +247 +248 +249 +250 +251 +252 +253 +254 +255 +256 +257 +258 +259 +260 +261 +262 +263 +264 +265 +266 +267 +268 +269 +270 +271 +272 +273 +274 +275 +276 +277 +278 +279 +280 +281 +282 +283 +284 +285 +286 +287 +288 +289 +290 +291 +292 +293 +294 +295 +296 +297 +298 +299 +3001x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +  +  +  +  +  +  +  +  +  +  +  +  +1x +1x +1x +1x +1x +1x +  +  +  +  +  +  +1x +1x +  +  +  +  +  +  +  +  +  +  +  +  +  +  +1x +1x +  +  +  +1x +1x +  +  +1x +1x +  +  +  +  +  +  +  +  +  +  +  +  +1x +1x +  +  +  +  +  +1x +1x +  +  +  +  +  +1x +1x +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +1x +1x +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +1x +1x +  +  +  +  +  +  +  +  +  +  +  +  +1x +1x +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +1x +1x +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +1x +1x +  +  +  +  +  +  +  +  +  +  +  +  +1x +1x +1x + 
import type { LightPlugin, LightClient, ErrorEvent, StackFrame, LightConfig } from '../types';
+import { now, isObject, matchPatterns } from '../utils/helper';
+import { computeFingerprint } from '../utils/hash';
+import { sanitizeUrl, shouldIgnoreUrl } from '../utils/env';
+import { parseStackTrace } from '../utils/stacktrace';
+import { logError } from '../utils/logger';
+ 
+interface ErrorPluginConfig {
+  maxStackFrames?: number;
+  captureNodeModules?: boolean;
+  captureColumn?: boolean;
+  relativePathOnly?: boolean;
+  sampleRate?: number;
+  resourceSampleRate?: number;
+  ignoreErrors?: (string | RegExp)[];
+  ignoreUrls?: (string | RegExp)[];
+  includePaths?: (string | RegExp)[];
+}
+ 
+class ErrorPlugin implements LightPlugin {
+  name = 'error';
+  version = '1.0.0';
+
+  private client!: LightClient;
+  private config: ErrorPluginConfig = {
+    maxStackFrames: 5,
+    captureNodeModules: false,
+    captureColumn: true,
+    relativePathOnly: false,
+    resourceSampleRate: 0.1,
+  };
+ 
+  private originalOnError?: typeof window.onerror;
+  private onUnhandledRejection?: (event: PromiseRejectionEvent) => void;
+  private onResourceError?: (event: Event) => void;
+ 
+  setup(client: LightClient): void {
+    this.client = client;
+    this.loadConfig();
+    this.setupGlobalError();
+    this.setupUnhandledRejection();
+    this.setupResourceError();
+  }
+ 
+  private loadConfig(): void {
+    const clientConfig = this.client.config as LightConfig;
+    if (clientConfig && isObject(clientConfig.error)) {
+      this.config = { ...this.config, ...(clientConfig.error as object) };
+    }
+    if (clientConfig.ignoreErrors) {
+      this.config.ignoreErrors = [...(this.config.ignoreErrors || []), ...clientConfig.ignoreErrors];
+    }
+    if (clientConfig.ignoreUrls) {
+      this.config.ignoreUrls = [...(this.config.ignoreUrls || []), ...clientConfig.ignoreUrls];
+    }
+    if (clientConfig.includePaths) {
+      this.config.includePaths = [...(this.config.includePaths || []), ...clientConfig.includePaths];
+    }
+  }
+ 
+  private shouldIgnoreError(message: string): boolean {
+    if (!message) return false;
+    return matchPatterns(message, this.config.ignoreErrors || []);
+  }
+ 
+  private shouldIgnoreScriptUrl(url: string): boolean {
+    return shouldIgnoreUrl(url, this.config.ignoreUrls || []);
+  }
+ 
+  private shouldIncludePath(frames: StackFrame[]): boolean {
+    const patterns = this.config.includePaths || [];
+    if (patterns.length === 0) return true;
+
+    return frames.some(frame => 
+      patterns.some(pattern => {
+        if (typeof pattern === 'string') {
+          return frame.filename?.includes(pattern);
+        }
+        return pattern.test(frame.filename || '');
+      })
+    );
+  }
+ 
+  private shouldSample(): boolean {
+    const rate = this.config.sampleRate ?? 1;
+    if (rate >= 1) return true;
+    if (rate <= 0) return false;
+    return Math.random() < rate;
+  }
+ 
+  private shouldSampleResource(): boolean {
+    const rate = this.config.resourceSampleRate ?? 0.1;
+    if (rate >= 1) return true;
+    if (rate <= 0) return false;
+    return Math.random() < rate;
+  }
+ 
+  private setupGlobalError(): void {
+    if (typeof window === 'undefined') return;
+
+    this.originalOnError = window.onerror;
+
+    window.onerror = (message, url, lineno, colno, error) => {
+      try {
+        if (this.originalOnError) {
+          this.originalOnError.call(window, message, url, lineno, colno, error);
+        }
+
+        if (url && this.shouldIgnoreScriptUrl(url as string)) {
+          return false;
+        }
+
+        const errorEvent = this.buildErrorEvent(
+          error || (message as string),
+          url as string,
+          lineno as number,
+          colno as number
+        );
+
+        if (errorEvent) {
+          this.client.captureEvent(errorEvent);
+        }
+      } catch (e) {
+        logError('ErrorPlugin', 'Global error handler error', e);
+      }
+
+      return false;
+    };
+  }
+ 
+  private setupUnhandledRejection(): void {
+    if (typeof window === 'undefined') return;
+
+    this.onUnhandledRejection = (event) => {
+      try {
+        const reason = event.reason;
+        const sourceUrl = this.extractUrlFromReason(reason);
+
+        if (sourceUrl && this.shouldIgnoreScriptUrl(sourceUrl)) {
+          return;
+        }
+
+        const errorEvent = this.buildErrorEvent(reason);
+        
+        if (errorEvent) {
+          if (errorEvent.type === 'error') {
+            (errorEvent as ErrorEvent).tags = {
+              ...((errorEvent as ErrorEvent).tags || {}),
+              unhandled: 'true',
+              promise: 'true',
+            };
+          }
+
+          this.client.captureEvent(errorEvent);
+        }
+      } catch (e) {
+        logError('ErrorPlugin', 'Unhandledrejection handler error', e);
+      }
+    };
+
+    window.addEventListener('unhandledrejection', this.onUnhandledRejection);
+  }
+ 
+  private extractUrlFromReason(reason: unknown): string | null {
+    if (reason instanceof Error && reason.stack) {
+      const match = reason.stack.match(/at\s+(?:.+?\s+)?\((https?:\/\/[^:]+):\d+:\d+\)/);
+      if (match) {
+        return match[1];
+      }
+      const urlMatch = reason.stack.match(/(https?:\/\/[^\s)]+):\d+:\d+/);
+      if (urlMatch) {
+        return urlMatch[1];
+      }
+    }
+    return null;
+  }
+ 
+  private setupResourceError(): void {
+    if (typeof window === 'undefined') return;
+
+    this.onResourceError = (event) => {
+      const target = event.target;
+      if (!target) return;
+
+      const tagName = (target as HTMLElement).tagName?.toLowerCase();
+      const src = (target as HTMLImageElement).src || (target as HTMLLinkElement).href;
+
+      if (tagName && src && ['img', 'script', 'link', 'audio', 'video'].includes(tagName)) {
+        try {
+          if (this.shouldIgnoreScriptUrl(src)) return;
+          if (!this.shouldSampleResource()) return;
+
+          const fingerprint = `resource:${tagName}`;
+          const sanitizedSrc = sanitizeUrl(src);
+          this.client.captureEvent({
+            type: 'error',
+            level: 'warning',
+            message: `Resource load failed: ${tagName} ${sanitizedSrc}`,
+            timestamp: now(),
+            fingerprint,
+            tags: {
+              resource_type: tagName,
+              resource_url: sanitizedSrc,
+            },
+            exception: {
+              type: 'ResourceError',
+              value: `Failed to load ${tagName} resource`,
+            },
+          });
+        } catch (e) {
+          logError('ErrorPlugin', 'Resource error handler error', e);
+        }
+      }
+    };
+
+    window.addEventListener('error', this.onResourceError, true);
+  }
+ 
+  private buildErrorEvent(error: Error | unknown, url?: string, lineno?: number, colno?: number): Partial<ErrorEvent> & { type: string } | null {
+    const timestamp = now();
+
+    if (error instanceof Error) {
+      if (this.shouldIgnoreError(error.message)) return null;
+      
+      const frames = parseStackTrace(error.stack, {
+        captureNodeModules: this.config.captureNodeModules,
+        captureColumn: this.config.captureColumn,
+        relativePathOnly: this.config.relativePathOnly,
+        maxFrames: this.config.maxStackFrames,
+      });
+
+      if (!this.shouldIncludePath(frames)) return null;
+      if (!this.shouldSample()) return null;
+
+      const fingerprint = computeFingerprint(error.name, error.message, frames);
+
+      return {
+        type: 'error',
+        level: 'error',
+        message: error.message,
+        timestamp,
+        exception: {
+          type: error.name,
+          value: error.message,
+          stacktrace: {
+            frames,
+          },
+        },
+        fingerprint,
+      };
+    }
+
+    const message = String(error);
+    if (this.shouldIgnoreError(message)) return null;
+
+    const frames: StackFrame[] = [];
+    if (url) {
+      frames.push({
+        filename: url,
+        lineno,
+        colno: this.config.captureColumn ? colno : undefined,
+        in_app: true,
+      });
+    }
+
+    if (!this.shouldIncludePath(frames)) return null;
+    if (!this.shouldSample()) return null;
+
+    return {
+      type: 'error',
+      level: 'error',
+      message,
+      timestamp,
+      exception: {
+        type: 'Error',
+        value: message,
+        stacktrace: {
+          frames,
+        },
+      },
+    };
+  }
+ 
+  destroy(): void {
+    if (typeof window !== 'undefined') {
+      if (this.originalOnError !== undefined) {
+        window.onerror = this.originalOnError;
+      }
+      if (this.onUnhandledRejection) {
+        window.removeEventListener('unhandledrejection', this.onUnhandledRejection);
+      }
+      if (this.onResourceError) {
+        window.removeEventListener('error', this.onResourceError, true);
+      }
+    }
+  }
+}
+ 
+export default ErrorPlugin;
+ 
+ +
+
+ + + + + + + + \ No newline at end of file diff --git a/coverage/src/plugins/InteractionPlugin.ts.html b/coverage/src/plugins/InteractionPlugin.ts.html new file mode 100644 index 0000000..a15fd5a --- /dev/null +++ b/coverage/src/plugins/InteractionPlugin.ts.html @@ -0,0 +1,706 @@ + + + + + + Code coverage report for src/plugins/InteractionPlugin.ts + + + + + + + + + +
+
+

All files / src/plugins InteractionPlugin.ts

+
+ +
+ 16.9% + Statements + 35/207 +
+ + +
+ 100% + Branches + 0/0 +
+ + +
+ 0% + Functions + 0/10 +
+ + +
+ 16.9% + Lines + 35/207 +
+ + +
+

+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +

+ +
+
+

+
1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +30 +31 +32 +33 +34 +35 +36 +37 +38 +39 +40 +41 +42 +43 +44 +45 +46 +47 +48 +49 +50 +51 +52 +53 +54 +55 +56 +57 +58 +59 +60 +61 +62 +63 +64 +65 +66 +67 +68 +69 +70 +71 +72 +73 +74 +75 +76 +77 +78 +79 +80 +81 +82 +83 +84 +85 +86 +87 +88 +89 +90 +91 +92 +93 +94 +95 +96 +97 +98 +99 +100 +101 +102 +103 +104 +105 +106 +107 +108 +109 +110 +111 +112 +113 +114 +115 +116 +117 +118 +119 +120 +121 +122 +123 +124 +125 +126 +127 +128 +129 +130 +131 +132 +133 +134 +135 +136 +137 +138 +139 +140 +141 +142 +143 +144 +145 +146 +147 +148 +149 +150 +151 +152 +153 +154 +155 +156 +157 +158 +159 +160 +161 +162 +163 +164 +165 +166 +167 +168 +169 +170 +171 +172 +173 +174 +175 +176 +177 +178 +179 +180 +181 +182 +183 +184 +185 +186 +187 +188 +189 +190 +191 +192 +193 +194 +195 +196 +197 +198 +199 +200 +201 +202 +203 +204 +205 +206 +207 +2081x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +1x +1x +  +  +  +  +  +  +  +  +  +1x +1x +  +  +  +  +  +  +  +  +1x +1x +  +  +  +  +  +  +  +  +  +  +  +  +  +  +1x +1x +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +1x +1x +  +  +  +  +  +  +  +  +  +  +1x +1x +  +  +  +  +  +  +  +  +  +1x +1x +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +1x +1x +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +1x +1x +1x + 
import type { LightPlugin, LightClient, Transaction, Span, SpanStatus, LightConfig } from '../types';
+import { now, isObject } from '../utils/helper';
+ 
+interface InteractionPluginConfig {
+  enable?: boolean;
+  elementAttribute?: string;
+  maxTransactionDurationMs?: number;
+  idleTimeoutMs?: number;
+  captureScroll?: boolean;
+  trackClick?: boolean;
+  trackSubmit?: boolean;
+  trackKeypress?: boolean;
+}
+ 
+const DEFAULT_TRACKING_TYPES = ['click', 'submit'];
+ 
+class InteractionPlugin implements LightPlugin {
+  name = 'interaction';
+  version = '1.0.0';
+
+  private client!: LightClient;
+  private config: InteractionPluginConfig = {
+    enable: true,
+    elementAttribute: 'data-sentry-component',
+    maxTransactionDurationMs: 30000,
+    idleTimeoutMs: 1000,
+    trackClick: true,
+    trackSubmit: true,
+    trackKeypress: false,
+  };
+
+  private currentTransaction: Transaction | null = null;
+  private idleTimer: ReturnType<typeof setTimeout> | null = null;
+  private maxDurationTimer: ReturnType<typeof setTimeout> | null = null;
+  private debounceTimer: ReturnType<typeof setTimeout> | null = null;
+
+  setup(client: LightClient): void {
+    this.client = client;
+    this.loadConfig();
+
+    if (typeof window === 'undefined') return;
+    if (!this.config.enable) return;
+
+    if (this.config.trackClick) {
+      document.addEventListener('click', this.handleClick, true);
+    }
+    if (this.config.trackSubmit) {
+      document.addEventListener('submit', this.handleSubmit, true);
+    }
+  }
+
+  private loadConfig(): void {
+    const clientConfig = this.client.config as LightConfig;
+    if (clientConfig && isObject((clientConfig as Record<string, unknown>).interaction)) {
+      this.config = { ...this.config, ...((clientConfig as Record<string, unknown>).interaction as object) };
+    }
+  }
+
+  private handleClick = (event: Event): void => {
+    if (this.isEventIgnored(event)) return;
+    const target = event.target as HTMLElement;
+    const elementName = this.getElementName(target, 'click');
+    this.scheduleInteractionTransaction(elementName, 'click', target);
+  };
+
+  private handleSubmit = (event: Event): void => {
+    if (this.isEventIgnored(event)) return;
+    const target = event.target as HTMLElement;
+    const elementName = this.getElementName(target, 'submit');
+    this.scheduleInteractionTransaction(elementName, 'submit', target);
+  };
+ 
+  private isEventIgnored(event: Event): boolean {
+    const target = event.target as HTMLElement;
+    if (!target) return true;
+
+    if (target.hasAttribute && target.hasAttribute('data-sentry-ignore')) {
+      return true;
+    }
+
+    return false;
+  }
+ 
+  private scheduleInteractionTransaction(name: string, op: string, element: HTMLElement): void {
+    if (this.debounceTimer) {
+      clearTimeout(this.debounceTimer);
+    }
+
+    this.debounceTimer = setTimeout(() => {
+      this.startInteractionTransaction(name, op, element);
+    }, 0);
+  }
+ 
+  private getElementName(element: HTMLElement | null, eventType: string): string {
+    if (!element) return eventType;
+
+    const attr = this.config.elementAttribute || 'data-sentry-component';
+    const componentName = element.getAttribute(attr);
+    if (componentName) return componentName;
+
+    const tag = element.tagName?.toLowerCase() || 'element';
+    const id = element.id ? `#${element.id}` : '';
+    const classes = element.className && typeof element.className === 'string'
+      ? `.${element.className.split(' ').slice(0, 3).join('.')}`
+      : '';
+
+    return `${eventType}@${tag}${id}${classes}`;
+  }
+ 
+  private startInteractionTransaction(name: string, op: string, element: HTMLElement): void {
+    if (!this.client) return;
+
+    if (this.currentTransaction) {
+      this.finishCurrentTransaction('ok');
+    }
+
+    const transaction = this.client.startTransaction({
+      name,
+      op: `ui.${op}`,
+      description: `User ${op} on ${name}`,
+      type: 'user-interaction',
+      tags: {
+        'interaction.type': op,
+        'interaction.target': name,
+      },
+      data: {
+        tag: element.tagName?.toLowerCase(),
+        id: element.id || undefined,
+        text: element.textContent?.substring(0, 100) || undefined,
+      },
+    });
+
+    if (transaction) {
+      this.currentTransaction = transaction;
+      this.scheduleIdleFinish();
+      this.scheduleMaxDuration();
+    }
+  }
+ 
+  private scheduleIdleFinish(): void {
+    if (this.idleTimer) {
+      clearTimeout(this.idleTimer);
+    }
+
+    const idleTimeout = this.config.idleTimeoutMs ?? 1000;
+
+    this.idleTimer = setTimeout(() => {
+      this.finishCurrentTransaction('ok');
+    }, idleTimeout);
+  }
+ 
+  private scheduleMaxDuration(): void {
+    if (this.maxDurationTimer) {
+      clearTimeout(this.maxDurationTimer);
+    }
+
+    const maxDuration = this.config.maxTransactionDurationMs ?? 30000;
+    this.maxDurationTimer = setTimeout(() => {
+      this.finishCurrentTransaction('deadline_exceeded');
+    }, maxDuration);
+  }
+ 
+  private finishCurrentTransaction(status: SpanStatus = 'ok'): void {
+    if (this.idleTimer) {
+      clearTimeout(this.idleTimer);
+      this.idleTimer = null;
+    }
+    if (this.maxDurationTimer) {
+      clearTimeout(this.maxDurationTimer);
+      this.maxDurationTimer = null;
+    }
+    if (this.debounceTimer) {
+      clearTimeout(this.debounceTimer);
+      this.debounceTimer = null;
+    }
+
+    if (this.currentTransaction) {
+      this.currentTransaction.setStatus(status);
+      this.currentTransaction.finish();
+      this.currentTransaction = null;
+    }
+  }
+ 
+  destroy(): void {
+    if (typeof document !== 'undefined') {
+      document.removeEventListener('click', this.handleClick, true);
+      document.removeEventListener('submit', this.handleSubmit, true);
+    }
+
+    if (this.idleTimer) {
+      clearTimeout(this.idleTimer);
+      this.idleTimer = null;
+    }
+    if (this.maxDurationTimer) {
+      clearTimeout(this.maxDurationTimer);
+      this.maxDurationTimer = null;
+    }
+    if (this.debounceTimer) {
+      clearTimeout(this.debounceTimer);
+      this.debounceTimer = null;
+    }
+
+    this.finishCurrentTransaction('aborted');
+  }
+}
+ 
+export default InteractionPlugin;
+ 
+ +
+
+ + + + + + + + \ No newline at end of file diff --git a/coverage/src/plugins/NetworkPlugin.ts.html b/coverage/src/plugins/NetworkPlugin.ts.html new file mode 100644 index 0000000..ed80fd2 --- /dev/null +++ b/coverage/src/plugins/NetworkPlugin.ts.html @@ -0,0 +1,1237 @@ + + + + + + Code coverage report for src/plugins/NetworkPlugin.ts + + + + + + + + + +
+
+

All files / src/plugins NetworkPlugin.ts

+
+ +
+ 14.32% + Statements + 55/384 +
+ + +
+ 100% + Branches + 0/0 +
+ + +
+ 0% + Functions + 0/14 +
+ + +
+ 14.32% + Lines + 55/384 +
+ + +
+

+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +

+ +
+
+

+
1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +30 +31 +32 +33 +34 +35 +36 +37 +38 +39 +40 +41 +42 +43 +44 +45 +46 +47 +48 +49 +50 +51 +52 +53 +54 +55 +56 +57 +58 +59 +60 +61 +62 +63 +64 +65 +66 +67 +68 +69 +70 +71 +72 +73 +74 +75 +76 +77 +78 +79 +80 +81 +82 +83 +84 +85 +86 +87 +88 +89 +90 +91 +92 +93 +94 +95 +96 +97 +98 +99 +100 +101 +102 +103 +104 +105 +106 +107 +108 +109 +110 +111 +112 +113 +114 +115 +116 +117 +118 +119 +120 +121 +122 +123 +124 +125 +126 +127 +128 +129 +130 +131 +132 +133 +134 +135 +136 +137 +138 +139 +140 +141 +142 +143 +144 +145 +146 +147 +148 +149 +150 +151 +152 +153 +154 +155 +156 +157 +158 +159 +160 +161 +162 +163 +164 +165 +166 +167 +168 +169 +170 +171 +172 +173 +174 +175 +176 +177 +178 +179 +180 +181 +182 +183 +184 +185 +186 +187 +188 +189 +190 +191 +192 +193 +194 +195 +196 +197 +198 +199 +200 +201 +202 +203 +204 +205 +206 +207 +208 +209 +210 +211 +212 +213 +214 +215 +216 +217 +218 +219 +220 +221 +222 +223 +224 +225 +226 +227 +228 +229 +230 +231 +232 +233 +234 +235 +236 +237 +238 +239 +240 +241 +242 +243 +244 +245 +246 +247 +248 +249 +250 +251 +252 +253 +254 +255 +256 +257 +258 +259 +260 +261 +262 +263 +264 +265 +266 +267 +268 +269 +270 +271 +272 +273 +274 +275 +276 +277 +278 +279 +280 +281 +282 +283 +284 +285 +286 +287 +288 +289 +290 +291 +292 +293 +294 +295 +296 +297 +298 +299 +300 +301 +302 +303 +304 +305 +306 +307 +308 +309 +310 +311 +312 +313 +314 +315 +316 +317 +318 +319 +320 +321 +322 +323 +324 +325 +326 +327 +328 +329 +330 +331 +332 +333 +334 +335 +336 +337 +338 +339 +340 +341 +342 +343 +344 +345 +346 +347 +348 +349 +350 +351 +352 +353 +354 +355 +356 +357 +358 +359 +360 +361 +362 +363 +364 +365 +366 +367 +368 +369 +370 +371 +372 +373 +374 +375 +376 +377 +378 +379 +380 +381 +382 +383 +384 +3851x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +1x +1x +1x +1x +1x +1x +  +  +  +  +  +  +  +  +  +1x +1x +  +  +  +  +  +  +  +  +  +  +  +  +  +1x +1x +  +  +1x +1x +  +  +  +  +  +  +  +  +  +  +  +1x +1x +  +  +  +  +  +  +  +  +1x +1x +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +1x +1x +  +  +  +  +  +  +  +  +  +  +1x +1x +  +  +  +  +  +  +  +  +  +  +  +  +  +  +1x +1x +  +  +  +  +  +  +  +  +  +  +1x +1x +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +1x +1x +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +1x +1x +  +  +  +  +  +  +  +  +  +  +  +  +  +  +1x +1x +  +  +  +  +  +  +  +  +  +  +1x +1x +1x + 
import type { LightPlugin, LightClient, NetworkEvent, LightConfig, Span, Transaction } from '../types';
+import { now, isObject } from '../utils/helper';
+import { sanitizeUrl, shouldIgnoreUrl } from '../utils/env';
+ 
+interface NetworkPluginConfig {
+  ignoreUrls?: (string | RegExp)[];
+  captureXHR?: boolean;
+  captureFetch?: boolean;
+  captureSuccess?: boolean;
+  captureBody?: boolean;
+  captureRequestBody?: boolean;
+  captureResponseBody?: boolean;
+  captureRequestHeaders?: string[];
+  captureResponseHeaders?: string[];
+  errorSampleRate?: number;
+  successSampleRate?: number;
+  slowThreshold?: number;
+  slowSampleRate?: number;
+  ignoreStatusCodes?: number[];
+  tracePropagationTargets?: (string | RegExp)[];
+}
+ 
+class NetworkPlugin implements LightPlugin {
+  name = 'network';
+  version = '1.1.0';
+
+  private client!: LightClient;
+  private config: NetworkPluginConfig = {
+    captureXHR: true,
+    captureFetch: true,
+    captureSuccess: false,
+    captureBody: false,
+    captureRequestBody: false,
+    captureResponseBody: false,
+    captureRequestHeaders: ['content-type', 'user-agent'],
+    captureResponseHeaders: ['content-type', 'content-length'],
+    errorSampleRate: 1.0,
+    successSampleRate: 0.01,
+    slowThreshold: 3000,
+    slowSampleRate: 1.0,
+    ignoreStatusCodes: [],
+  };
+ 
+  private originalFetch!: typeof fetch;
+  private originalXHROpen!: typeof XMLHttpRequest.prototype.open;
+  private originalXHRSend!: typeof XMLHttpRequest.prototype.send;
+ 
+  setup(client: LightClient): void {
+    this.client = client;
+    this.loadConfig();
+    if (this.config.captureFetch) {
+      this.patchFetch();
+    }
+    if (this.config.captureXHR) {
+      this.patchXHR();
+    }
+  }
+ 
+  private loadConfig(): void {
+    const clientConfig = this.client.config as LightConfig;
+    if (clientConfig && isObject(clientConfig.network)) {
+      this.config = { ...this.config, ...(clientConfig.network as object) };
+    }
+    if (clientConfig.ignoreUrls) {
+      this.config.ignoreUrls = [...(this.config.ignoreUrls || []), ...clientConfig.ignoreUrls];
+    }
+    if (clientConfig.tracePropagationTargets) {
+      this.config.tracePropagationTargets = [...(this.config.tracePropagationTargets || []), ...clientConfig.tracePropagationTargets];
+    } else if (clientConfig.tracingOrigins) {
+      this.config.tracePropagationTargets = [...(this.config.tracePropagationTargets || []), ...clientConfig.tracingOrigins];
+    }
+  }
+ 
+  private shouldIgnore(url: string): boolean {
+    return shouldIgnoreUrl(url, this.config.ignoreUrls || []);
+  }
+ 
+  private shouldTracePropagate(url: string): boolean {
+    const targets = this.config.tracePropagationTargets;
+    if (!targets || targets.length === 0) {
+      return this.isSameOrigin(url);
+    }
+    return targets.some(pattern => {
+      if (typeof pattern === 'string') {
+        return url.includes(pattern);
+      }
+      return pattern.test(url);
+    });
+  }
+ 
+  private isSameOrigin(url: string): boolean {
+    if (typeof location === 'undefined') return false;
+    try {
+      const urlObj = new URL(url, location.origin);
+      return urlObj.origin === location.origin;
+    } catch {
+      return false;
+    }
+  }
+ 
+  private getBaggageHeader(): string | undefined {
+    if (!this.client) return undefined;
+
+    const clientInternal = this.client as unknown as {
+      tracingManager?: {
+        getCurrentTransaction?: () => Transaction | null;
+      };
+    };
+
+    const tx = clientInternal.tracingManager?.getCurrentTransaction?.();
+    if (!tx) return undefined;
+
+    const transactionImpl = tx as unknown as {
+      toBaggage?: () => string | undefined;
+    };
+
+    if (transactionImpl.toBaggage) {
+      return transactionImpl.toBaggage();
+    }
+
+    return undefined;
+  }
+ 
+  private shouldSample(isError: boolean, duration: number): boolean {
+    let rate = isError ? (this.config.errorSampleRate ?? 1.0) : (this.config.successSampleRate ?? 0.01);
+    
+    if (!isError && duration >= (this.config.slowThreshold ?? 3000)) {
+      rate = this.config.slowSampleRate ?? 1.0;
+    }
+    
+    if (rate >= 1) return true;
+    if (rate <= 0) return false;
+    return Math.random() < rate;
+  }
+ 
+  private createHttpSpan(method: string, url: string): Span | null {
+    const currentSpan = this.client.getCurrentSpan();
+    if (!currentSpan) return null;
+
+    const span = currentSpan.startChild({
+      op: 'http.client',
+      description: `${method.toUpperCase()} ${url}`,
+      tags: {
+        'http.method': method.toUpperCase(),
+        'http.url': sanitizeUrl(url),
+      },
+    });
+
+    return span;
+  }
+ 
+  private finishHttpSpan(span: Span, statusCode: number, duration: number, isError: boolean): void {
+    span.setData('http.response.duration', duration);
+
+    if (statusCode > 0) {
+      span.setHttpStatus(statusCode);
+    } else if (isError) {
+      span.setStatus('internal_error');
+    }
+
+    span.finish();
+  }
+ 
+  private patchFetch(): void {
+    if (typeof fetch === 'undefined') return;
+
+    this.originalFetch = window.fetch;
+    const self = this;
+
+    window.fetch = function (input: RequestInfo | URL, init?: RequestInit): Promise<Response> {
+      const startTime = now();
+      const url = typeof input === 'string' ? input : input instanceof URL ? input.toString() : input.url;
+      const method = init?.method || 'GET';
+
+      if (self.shouldIgnore(url)) {
+        return self.originalFetch.call(window, input, init);
+      }
+
+      const sanitizedUrl = sanitizeUrl(url);
+
+      let httpSpan = self.createHttpSpan(method, sanitizedUrl);
+
+      const shouldInjectTrace = self.shouldTracePropagate(url) && !!httpSpan;
+      let modifiedInit = init;
+
+      if (shouldInjectTrace && httpSpan) {
+        const traceHeader = httpSpan.toTraceparent();
+        const baggage = self.getBaggageHeader();
+
+        modifiedInit = {
+          ...init,
+          headers: {
+            ...(init?.headers || {}),
+            'sentry-trace': traceHeader,
+            ...(baggage ? { 'baggage': baggage } : {}),
+          },
+        };
+      }
+
+      const promise = self.originalFetch.call(window, input, modifiedInit);
+
+      promise.then(
+        (response) => {
+          const duration = now() - startTime;
+          const isSuccess = response.ok;
+          const statusCode = response.status;
+
+          if (httpSpan) {
+            self.finishHttpSpan(httpSpan, statusCode, duration, !isSuccess);
+          }
+
+          if (self.config.ignoreStatusCodes?.includes(statusCode)) {
+            return response;
+          }
+
+          if (!self.shouldSample(!isSuccess, duration)) {
+            return response;
+          }
+
+          if (!isSuccess || self.config.captureSuccess) {
+            self.reportNetwork({
+              sub_type: 'fetch',
+              method: method.toUpperCase(),
+              url: sanitizedUrl,
+              status_code: statusCode,
+              duration,
+              success: isSuccess,
+              error: !isSuccess ? `HTTP ${statusCode}` : undefined,
+            });
+          }
+
+          return response;
+        },
+        (error) => {
+          const duration = now() - startTime;
+
+          if (httpSpan) {
+            self.finishHttpSpan(httpSpan, 0, duration, true);
+          }
+
+          if (self.shouldSample(true, duration)) {
+            self.reportNetwork({
+              sub_type: 'fetch',
+              method: method.toUpperCase(),
+              url: sanitizedUrl,
+              duration,
+              success: false,
+              error: error?.message || 'Network error',
+            });
+          }
+
+          throw error;
+        }
+      );
+
+      return promise;
+    };
+  }
+ 
+  private patchXHR(): void {
+    if (typeof XMLHttpRequest === 'undefined') return;
+
+    this.originalXHROpen = XMLHttpRequest.prototype.open;
+    this.originalXHRSend = XMLHttpRequest.prototype.send;
+    const self = this;
+
+    XMLHttpRequest.prototype.open = function (method: string, url: string | URL) {
+      (this as { _lightMethod?: string })._lightMethod = method;
+      (this as { _lightUrl?: string })._lightUrl = typeof url === 'string' ? url : url.toString();
+      (this as { _lightTracked?: boolean })._lightTracked = false;
+      return self.originalXHROpen.apply(this, arguments as unknown as Parameters<typeof XMLHttpRequest.prototype.open>);
+    };
+
+    XMLHttpRequest.prototype.send = function (body?: Document | XMLHttpRequestBodyInit | null) {
+      const startTime = now();
+      const method = (this as { _lightMethod?: string })._lightMethod || 'GET';
+      const url = (this as { _lightUrl?: string })._lightUrl || '';
+      const tracked = (this as { _lightTracked?: boolean })._lightTracked;
+
+      if (self.shouldIgnore(url) || tracked) {
+        return self.originalXHRSend.apply(this, arguments as unknown as Parameters<typeof XMLHttpRequest.prototype.send>);
+      }
+
+      (this as { _lightTracked?: boolean })._lightTracked = true;
+      const sanitizedUrl = sanitizeUrl(url);
+      let requestSize = 0;
+      if (body && typeof body === 'string') {
+        requestSize = body.length;
+      }
+
+      const httpSpan = self.createHttpSpan(method, sanitizedUrl);
+      const shouldInjectTrace = self.shouldTracePropagate(url) && !!httpSpan;
+
+      if (shouldInjectTrace && httpSpan) {
+        try {
+          const traceHeader = httpSpan.toTraceparent();
+          const baggage = self.getBaggageHeader();
+          this.setRequestHeader('sentry-trace', traceHeader);
+          if (baggage) {
+            this.setRequestHeader('baggage', baggage);
+          }
+        } catch {
+          // ignore
+        }
+      }
+
+      const originalOnLoadEnd = (this as XMLHttpRequest & { onloadend?: ((this: XMLHttpRequest, ev: ProgressEvent) => unknown) | null }).onloadend;
+      (this as XMLHttpRequest & { onloadend?: ((this: XMLHttpRequest, ev: ProgressEvent) => unknown) | null }).onloadend = function (ev: ProgressEvent) {
+        const duration = now() - startTime;
+        const status = this.status;
+        const isSuccess = status >= 200 && status < 300;
+
+        if (httpSpan) {
+          self.finishHttpSpan(httpSpan, status, duration, !isSuccess);
+        }
+
+        if (!self.config.ignoreStatusCodes?.includes(status)
+            && self.shouldSample(!isSuccess, duration)
+            && (isSuccess ? self.config.captureSuccess : true)) {
+          let responseSize = 0;
+          try {
+            const sizeHeader = this.getResponseHeader('content-length');
+            if (sizeHeader) {
+              responseSize = parseInt(sizeHeader, 10);
+            }
+            if (!responseSize && this.responseText) {
+              responseSize = this.responseText.length;
+            }
+          } catch {
+            // ignore
+          }
+
+          self.reportNetwork({
+            sub_type: 'xhr',
+            method: method.toUpperCase(),
+            url: sanitizedUrl,
+            status_code: status,
+            duration,
+            request_size: requestSize || undefined,
+            response_size: responseSize || undefined,
+            success: isSuccess,
+            error: !isSuccess ? `HTTP ${status}` : undefined,
+          });
+        }
+
+        if (originalOnLoadEnd) {
+          return originalOnLoadEnd.call(this, ev);
+        }
+      };
+
+      return self.originalXHRSend.apply(this, arguments as unknown as Parameters<typeof XMLHttpRequest.prototype.send>);
+    };
+  }
+ 
+  private reportNetwork(data: Omit<NetworkEvent, 'type' | 'level' | 'timestamp'>): void {
+    const event: NetworkEvent = {
+      type: 'network',
+      level: data.success ? 'info' : 'error',
+      timestamp: now(),
+      tags: {
+        method: data.method,
+        sub_type: data.sub_type,
+        success: String(data.success),
+      },
+      ...data,
+    };
+
+    this.client.captureEvent(event);
+  }
+ 
+  destroy(): void {
+    if (this.originalFetch) {
+      window.fetch = this.originalFetch;
+    }
+    if (this.originalXHROpen) {
+      XMLHttpRequest.prototype.open = this.originalXHROpen;
+    }
+    if (this.originalXHRSend) {
+      XMLHttpRequest.prototype.send = this.originalXHRSend;
+    }
+  }
+}
+ 
+export default NetworkPlugin;
+ 
+ +
+
+ + + + + + + + \ No newline at end of file diff --git a/coverage/src/plugins/OfflinePlugin.ts.html b/coverage/src/plugins/OfflinePlugin.ts.html new file mode 100644 index 0000000..c61ecfb --- /dev/null +++ b/coverage/src/plugins/OfflinePlugin.ts.html @@ -0,0 +1,997 @@ + + + + + + Code coverage report for src/plugins/OfflinePlugin.ts + + + + + + + + + +
+
+

All files / src/plugins OfflinePlugin.ts

+
+ +
+ 14.47% + Statements + 44/304 +
+ + +
+ 100% + Branches + 0/0 +
+ + +
+ 0% + Functions + 0/15 +
+ + +
+ 14.47% + Lines + 44/304 +
+ + +
+

+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +

+ +
+
+

+
1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +30 +31 +32 +33 +34 +35 +36 +37 +38 +39 +40 +41 +42 +43 +44 +45 +46 +47 +48 +49 +50 +51 +52 +53 +54 +55 +56 +57 +58 +59 +60 +61 +62 +63 +64 +65 +66 +67 +68 +69 +70 +71 +72 +73 +74 +75 +76 +77 +78 +79 +80 +81 +82 +83 +84 +85 +86 +87 +88 +89 +90 +91 +92 +93 +94 +95 +96 +97 +98 +99 +100 +101 +102 +103 +104 +105 +106 +107 +108 +109 +110 +111 +112 +113 +114 +115 +116 +117 +118 +119 +120 +121 +122 +123 +124 +125 +126 +127 +128 +129 +130 +131 +132 +133 +134 +135 +136 +137 +138 +139 +140 +141 +142 +143 +144 +145 +146 +147 +148 +149 +150 +151 +152 +153 +154 +155 +156 +157 +158 +159 +160 +161 +162 +163 +164 +165 +166 +167 +168 +169 +170 +171 +172 +173 +174 +175 +176 +177 +178 +179 +180 +181 +182 +183 +184 +185 +186 +187 +188 +189 +190 +191 +192 +193 +194 +195 +196 +197 +198 +199 +200 +201 +202 +203 +204 +205 +206 +207 +208 +209 +210 +211 +212 +213 +214 +215 +216 +217 +218 +219 +220 +221 +222 +223 +224 +225 +226 +227 +228 +229 +230 +231 +232 +233 +234 +235 +236 +237 +238 +239 +240 +241 +242 +243 +244 +245 +246 +247 +248 +249 +250 +251 +252 +253 +254 +255 +256 +257 +258 +259 +260 +261 +262 +263 +264 +265 +266 +267 +268 +269 +270 +271 +272 +273 +274 +275 +276 +277 +278 +279 +280 +281 +282 +283 +284 +285 +286 +287 +288 +289 +290 +291 +292 +293 +294 +295 +296 +297 +298 +299 +300 +301 +302 +303 +304 +3051x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +  +  +  +  +  +  +  +  +  +  +  +  +1x +1x +  +  +  +  +  +1x +1x +  +  +  +  +  +1x +1x +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +1x +1x +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +1x +1x +  +  +1x +1x +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +1x +1x +  +  +  +  +  +  +  +  +  +  +1x +1x +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +1x +1x +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +1x +1x +  +  +  +  +  +  +  +  +  +  +  +1x +1x +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +1x +1x +  +  +  +  +  +  +  +  +  +  +  +  +  +  +1x +1x +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +1x +1x +  +  +  +  +  +  +  +  +  +  +  +  +  +1x +1x +1x + 
import type { LightPlugin, LightClient, SentryEvent, LightConfig } from '../types';
+import { now } from '../utils/helper';
+ 
+const DB_NAME = 'light-sentry-offline';
+const STORE_NAME = 'events';
+const MAX_EVENTS = 1000;
+ 
+interface OfflineEvent {
+  id: string;
+  event: SentryEvent;
+  timestamp: number;
+}
+ 
+class OfflinePlugin implements LightPlugin {
+  name = 'offline';
+  version = '1.0.0';
+
+  private client!: LightClient;
+  private config: { maxEvents?: number } = { maxEvents: MAX_EVENTS };
+  private db: IDBDatabase | null = null;
+  private isOnline: boolean = true;
+  private isSyncing: boolean = false;
+  private onOnline?: () => void;
+  private onOffline?: () => void;
+  private pendingEvents: SentryEvent[] = [];
+ 
+  setup(client: LightClient): void {
+    this.client = client;
+    this.loadConfig();
+    this.initDatabase();
+    this.setupNetworkListeners();
+  }
+ 
+  private loadConfig(): void {
+    const clientConfig = this.client.config as LightConfig;
+    if (clientConfig && typeof clientConfig.offline === 'object') {
+      this.config = { ...this.config, ...(clientConfig.offline as object) };
+    }
+  }
+ 
+  private async initDatabase(): Promise<void> {
+    if (typeof indexedDB === 'undefined') {
+      console.warn('[LightSDK] OfflinePlugin: IndexedDB not available');
+      return;
+    }
+
+    return new Promise((resolve, reject) => {
+      const request = indexedDB.open(DB_NAME, 1);
+
+      request.onerror = () => {
+        console.warn('[LightSDK] OfflinePlugin: Failed to open IndexedDB');
+        reject(request.error);
+      };
+
+      request.onsuccess = () => {
+        this.db = request.result;
+        resolve();
+      };
+
+      request.onupgradeneeded = (event) => {
+        const db = (event.target as IDBOpenDBRequest).result;
+        const currentVersion = event.oldVersion;
+        
+        if (!db.objectStoreNames.contains(STORE_NAME)) {
+          const store = db.createObjectStore(STORE_NAME, { keyPath: 'id' });
+          store.createIndex('timestamp', 'timestamp', { unique: false });
+        }
+        
+        // 未来版本迁移可以在这里处理:
+        // if (currentVersion < 2) { ... }
+      };
+    });
+  }
+ 
+  private setupNetworkListeners(): void {
+    if (typeof window === 'undefined') return;
+
+    this.isOnline = navigator.onLine;
+
+    this.onOnline = () => {
+      console.info('[LightSDK] OfflinePlugin: Network online');
+      this.isOnline = true;
+      this.syncPendingEvents();
+    };
+
+    this.onOffline = () => {
+      console.info('[LightSDK] OfflinePlugin: Network offline');
+      this.isOnline = false;
+    };
+
+    window.addEventListener('online', this.onOnline);
+    window.addEventListener('offline', this.onOffline);
+  }
+ 
+  private generateId(): string {
+    return `${Date.now()}-${Math.random().toString(36).substring(2, 11)}`;
+  }
+ 
+  private async saveToIndexedDB(event: SentryEvent): Promise<void> {
+    if (!this.db) return;
+
+    const maxEvents = this.config.maxEvents || MAX_EVENTS;
+
+    const count = await this.getEventCount();
+    if (count >= maxEvents) {
+      await this.deleteOldestEvents(count - maxEvents + 1);
+    }
+
+    return new Promise((resolve, reject) => {
+      const transaction = this.db!.transaction([STORE_NAME], 'readwrite');
+      const store = transaction.objectStore(STORE_NAME);
+
+      const offlineEvent: OfflineEvent = {
+        id: this.generateId(),
+        event: {
+          ...event,
+          offline: true,
+        } as unknown as SentryEvent,
+        timestamp: now(),
+      };
+
+      const addRequest = store.add(offlineEvent);
+      addRequest.onsuccess = () => resolve();
+      addRequest.onerror = () => reject(addRequest.error);
+    });
+  }
+ 
+  private getEventCount(): Promise<number> {
+    if (!this.db) return Promise.resolve(0);
+
+    return new Promise((resolve, reject) => {
+      const transaction = this.db!.transaction([STORE_NAME], 'readonly');
+      const store = transaction.objectStore(STORE_NAME);
+      const countRequest = store.count();
+      countRequest.onsuccess = () => resolve(countRequest.result);
+      countRequest.onerror = () => reject(countRequest.error);
+    });
+  }
+ 
+  private async deleteOldestEvents(count: number): Promise<void> {
+    if (!this.db || count <= 0) return;
+
+    return new Promise((resolve, reject) => {
+      const transaction = this.db!.transaction([STORE_NAME], 'readwrite');
+      const store = transaction.objectStore(STORE_NAME);
+      const index = store.index('timestamp');
+
+      const cursorRequest = index.openCursor();
+      let deleted = 0;
+
+      cursorRequest.onsuccess = (event) => {
+        const cursor = (event.target as IDBRequest<IDBCursorWithValue>).result;
+        if (cursor && deleted < count) {
+          cursor.delete();
+          deleted++;
+          cursor.continue();
+        } else {
+          resolve();
+        }
+      };
+
+      cursorRequest.onerror = () => reject(cursorRequest.error);
+    });
+  }
+ 
+  private async getAllStoredEvents(): Promise<OfflineEvent[]> {
+    if (!this.db) return [];
+
+    return new Promise((resolve, reject) => {
+      const transaction = this.db!.transaction([STORE_NAME], 'readonly');
+      const store = transaction.objectStore(STORE_NAME);
+      const index = store.index('timestamp');
+      const request = index.getAll();
+
+      request.onsuccess = () => {
+        const events = request.result || [];
+        // 按时间排序
+        events.sort((a, b) => a.timestamp - b.timestamp);
+        resolve(events);
+      };
+
+      request.onerror = () => reject(request.error);
+    });
+  }
+ 
+  private async clearStoredEvents(): Promise<void> {
+    if (!this.db) return;
+
+    return new Promise((resolve, reject) => {
+      const transaction = this.db!.transaction([STORE_NAME], 'readwrite');
+      const store = transaction.objectStore(STORE_NAME);
+      const request = store.clear();
+
+      request.onsuccess = () => resolve();
+      request.onerror = () => reject(request.error);
+    });
+  }
+ 
+  async syncPendingEvents(): Promise<void> {
+    if (!this.isOnline || this.isSyncing) return;
+
+    this.isSyncing = true;
+    console.info('[LightSDK] OfflinePlugin: Syncing pending events');
+
+    try {
+      let syncedCount = 0;
+
+      // 先处理内存中的事件
+      while (this.pendingEvents.length > 0) {
+        const event = this.pendingEvents.shift() as Partial<SentryEvent> & { type: string };
+        try {
+          this.client.captureEvent(event);
+          syncedCount++;
+        } catch (error) {
+          console.error('[LightSDK] OfflinePlugin: Failed to re-enqueue memory event', error);
+        }
+      }
+
+      // 再处理 IndexedDB 中的事件
+      const storedEvents = await this.getAllStoredEvents();
+      if (storedEvents.length > 0) {
+        for (const offlineEvent of storedEvents) {
+          try {
+            const event = offlineEvent.event as Partial<SentryEvent> & { type: string };
+            this.client.captureEvent(event);
+            syncedCount++;
+          } catch (error) {
+            console.error('[LightSDK] OfflinePlugin: Failed to re-enqueue event', error);
+          }
+        }
+      }
+
+      // 等待队列 flush
+      try {
+        await this.client.flush();
+      } catch (e) {
+        // flush 失败不影响,事件已在队列中会自动重试
+      }
+
+      // 清空已同步的事件
+      await this.clearStoredEvents();
+      console.info(`[LightSDK] OfflinePlugin: Synced ${syncedCount} events`);
+    } catch (error) {
+      console.error('[LightSDK] OfflinePlugin: Sync failed', error);
+    } finally {
+      this.isSyncing = false;
+    }
+  }
+ 
+  beforeReport(event: SentryEvent): SentryEvent | null {
+    if (!this.isOnline) {
+      const maxEvents = this.config.maxEvents || MAX_EVENTS;
+      if (this.pendingEvents.length >= maxEvents) {
+        this.pendingEvents.shift();
+      }
+      this.pendingEvents.push(event);
+      this.savePendingEventsToDB();
+      return null;
+    }
+
+    const onlineEvent = { ...event };
+    delete (onlineEvent as Record<string, unknown>).offline;
+    return onlineEvent as SentryEvent;
+  }
+ 
+  private savePendingEventsToDB(): void {
+    if (this.pendingEvents.length === 0) return;
+
+    const events = this.pendingEvents.splice(0, this.pendingEvents.length);
+    let savedCount = 0;
+
+    const saveNext = () => {
+      if (savedCount >= events.length) return;
+      const event = events[savedCount];
+      this.saveToIndexedDB(event).then(() => {
+        savedCount++;
+        saveNext();
+      }).catch(err => {
+        console.error('[LightSDK] OfflinePlugin: Failed to save event offline', err);
+        // 恢复剩余未保存的事件
+        this.pendingEvents.unshift(...events.slice(savedCount));
+      });
+    };
+
+    saveNext();
+  }
+ 
+  destroy(): void {
+    if (typeof window !== 'undefined') {
+      if (this.onOnline) {
+        window.removeEventListener('online', this.onOnline);
+      }
+      if (this.onOffline) {
+        window.removeEventListener('offline', this.onOffline);
+      }
+    }
+    if (this.db) {
+      this.db.close();
+      this.db = null;
+    }
+  }
+}
+ 
+export default OfflinePlugin;
+ 
+ +
+
+ + + + + + + + \ No newline at end of file diff --git a/coverage/src/plugins/PerformancePlugin.ts.html b/coverage/src/plugins/PerformancePlugin.ts.html new file mode 100644 index 0000000..8e02420 --- /dev/null +++ b/coverage/src/plugins/PerformancePlugin.ts.html @@ -0,0 +1,1675 @@ + + + + + + Code coverage report for src/plugins/PerformancePlugin.ts + + + + + + + + + +
+
+

All files / src/plugins PerformancePlugin.ts

+
+ +
+ 12.83% + Statements + 68/530 +
+ + +
+ 100% + Branches + 0/0 +
+ + +
+ 0% + Functions + 0/23 +
+ + +
+ 12.83% + Lines + 68/530 +
+ + +
+

+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +

+ +
+
+

+
1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +30 +31 +32 +33 +34 +35 +36 +37 +38 +39 +40 +41 +42 +43 +44 +45 +46 +47 +48 +49 +50 +51 +52 +53 +54 +55 +56 +57 +58 +59 +60 +61 +62 +63 +64 +65 +66 +67 +68 +69 +70 +71 +72 +73 +74 +75 +76 +77 +78 +79 +80 +81 +82 +83 +84 +85 +86 +87 +88 +89 +90 +91 +92 +93 +94 +95 +96 +97 +98 +99 +100 +101 +102 +103 +104 +105 +106 +107 +108 +109 +110 +111 +112 +113 +114 +115 +116 +117 +118 +119 +120 +121 +122 +123 +124 +125 +126 +127 +128 +129 +130 +131 +132 +133 +134 +135 +136 +137 +138 +139 +140 +141 +142 +143 +144 +145 +146 +147 +148 +149 +150 +151 +152 +153 +154 +155 +156 +157 +158 +159 +160 +161 +162 +163 +164 +165 +166 +167 +168 +169 +170 +171 +172 +173 +174 +175 +176 +177 +178 +179 +180 +181 +182 +183 +184 +185 +186 +187 +188 +189 +190 +191 +192 +193 +194 +195 +196 +197 +198 +199 +200 +201 +202 +203 +204 +205 +206 +207 +208 +209 +210 +211 +212 +213 +214 +215 +216 +217 +218 +219 +220 +221 +222 +223 +224 +225 +226 +227 +228 +229 +230 +231 +232 +233 +234 +235 +236 +237 +238 +239 +240 +241 +242 +243 +244 +245 +246 +247 +248 +249 +250 +251 +252 +253 +254 +255 +256 +257 +258 +259 +260 +261 +262 +263 +264 +265 +266 +267 +268 +269 +270 +271 +272 +273 +274 +275 +276 +277 +278 +279 +280 +281 +282 +283 +284 +285 +286 +287 +288 +289 +290 +291 +292 +293 +294 +295 +296 +297 +298 +299 +300 +301 +302 +303 +304 +305 +306 +307 +308 +309 +310 +311 +312 +313 +314 +315 +316 +317 +318 +319 +320 +321 +322 +323 +324 +325 +326 +327 +328 +329 +330 +331 +332 +333 +334 +335 +336 +337 +338 +339 +340 +341 +342 +343 +344 +345 +346 +347 +348 +349 +350 +351 +352 +353 +354 +355 +356 +357 +358 +359 +360 +361 +362 +363 +364 +365 +366 +367 +368 +369 +370 +371 +372 +373 +374 +375 +376 +377 +378 +379 +380 +381 +382 +383 +384 +385 +386 +387 +388 +389 +390 +391 +392 +393 +394 +395 +396 +397 +398 +399 +400 +401 +402 +403 +404 +405 +406 +407 +408 +409 +410 +411 +412 +413 +414 +415 +416 +417 +418 +419 +420 +421 +422 +423 +424 +425 +426 +427 +428 +429 +430 +431 +432 +433 +434 +435 +436 +437 +438 +439 +440 +441 +442 +443 +444 +445 +446 +447 +448 +449 +450 +451 +452 +453 +454 +455 +456 +457 +458 +459 +460 +461 +462 +463 +464 +465 +466 +467 +468 +469 +470 +471 +472 +473 +474 +475 +476 +477 +478 +479 +480 +481 +482 +483 +484 +485 +486 +487 +488 +489 +490 +491 +492 +493 +494 +495 +496 +497 +498 +499 +500 +501 +502 +503 +504 +505 +506 +507 +508 +509 +510 +511 +512 +513 +514 +515 +516 +517 +518 +519 +520 +521 +522 +523 +524 +525 +526 +527 +528 +529 +530 +5311x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +1x +1x +  +  +  +  +  +  +  +  +  +  +  +  +1x +1x +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +1x +1x +  +  +  +  +  +1x +1x +  +  +  +  +  +  +  +  +  +  +  +  +1x +1x +  +  +  +  +  +  +  +  +1x +1x +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +1x +1x +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +1x +1x +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +1x +1x +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +1x +1x +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +1x +1x +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +1x +1x +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +1x +1x +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +1x +1x +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +1x +1x +  +  +  +  +  +  +  +  +  +  +  +  +  +1x +1x +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +1x +1x +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +1x +1x +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +1x +1x +  +  +  +  +  +  +  +  +  +  +1x +1x +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +1x +1x +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +1x +1x +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +1x +1x +1x + 
import type { LightPlugin, LightClient, PerformanceEvent, LightConfig, Transaction, Span } from '../types';
+import { now, isObject } from '../utils/helper';
+ 
+interface PerformancePluginConfig {
+  sampleRate?: number;
+  captureLongTasks?: boolean;
+  captureResources?: boolean;
+  resourceSampleRate?: number;
+  longTaskSampleRate?: number;
+  captureNavigation?: boolean;
+  captureFP?: boolean;
+  enablePageLoadTracing?: boolean;  // 是否启用 Page Load Transaction
+  maxResourceSpans?: number;        // 最大 Resource Span 数量
+}
+ 
+interface VitalMeasurement {
+  value: number;
+  unit?: string;
+  rating?: 'good' | 'needs-improvement' | 'poor';
+}
+ 
+class PerformancePlugin implements LightPlugin {
+  name = 'performance';
+  version = '2.0.0';
+
+  private client!: LightClient;
+  private config: PerformancePluginConfig = {
+    sampleRate: 0.1,
+    captureLongTasks: true,
+    captureResources: false,
+    resourceSampleRate: 0.01,
+    longTaskSampleRate: 0.05,
+    captureNavigation: true,
+    captureFP: true,
+    enablePageLoadTracing: false,
+    maxResourceSpans: 50,
+  };
+
+  private observers: PerformanceObserver[] = [];
+  private onLoad?: () => void;
+  private navLoadTimer: ReturnType<typeof setTimeout> | null = null;
+  private totalBlockingTime: number = 0;
+  private fcpTime: number | null = null;
+  private lastLongTaskEndTime: number = 0;
+  private ttiReported: boolean = false;
+  private ttiTimer: ReturnType<typeof setTimeout> | null = null;
+
+  private pageLoadTransaction: Transaction | null = null;
+  private measurements: Record<string, VitalMeasurement> = {};
+  private resourceSpanCount: number = 0;
+ 
+  setup(client: LightClient): void {
+    this.client = client;
+    this.loadConfig();
+
+    if (this.config.enablePageLoadTracing) {
+      this.startPageLoadTransaction();
+    }
+
+    this.observeWebVitals();
+    this.observeLongTasks();
+    this.observeNavigation();
+    this.observeResources();
+  }
+ 
+  private startPageLoadTransaction(): void {
+    if (typeof window === 'undefined') return;
+
+    const pageUrl = typeof location !== 'undefined' ? location.pathname : '/';
+    const navStart = typeof performance !== 'undefined' && performance.timing?.navigationStart
+      ? performance.timing.navigationStart
+      : now();
+
+    this.pageLoadTransaction = this.client.startTransaction({
+      name: pageUrl,
+      op: 'pageload',
+      description: `Page load - ${pageUrl}`,
+      startTimestamp: navStart,
+      type: 'pageload',
+      tags: {
+        'page.url': pageUrl,
+      },
+    });
+  }
+ 
+  private loadConfig(): void {
+    const clientConfig = this.client.config as LightConfig;
+    if (clientConfig && isObject(clientConfig.performance)) {
+      this.config = { ...this.config, ...(clientConfig.performance as object) };
+    }
+  }
+ 
+  private shouldSample(type: 'default' | 'resource' | 'longtask' | 'vitals' = 'default'): boolean {
+    let rate = this.config.sampleRate ?? 0.1;
+    if (type === 'resource') {
+      rate = this.config.resourceSampleRate ?? 0.01;
+    } else if (type === 'longtask') {
+      rate = this.config.longTaskSampleRate ?? 0.05;
+    } else if (type === 'vitals') {
+      rate = 1;
+    }
+    if (rate >= 1) return true;
+    if (rate <= 0) return false;
+    return Math.random() < rate;
+  }
+ 
+  private observeWebVitals(): void {
+    if (typeof PerformanceObserver === 'undefined') return;
+
+    this.observePaint();
+    this.observeLCP();
+    this.observeFID();
+    this.observeCLS();
+    this.observeTTFB();
+  }
+ 
+  private observePaint(): void {
+    try {
+      const po = new PerformanceObserver((entryList) => {
+        const fpEntries = entryList.getEntriesByName('first-paint');
+        if (fpEntries.length > 0 && this.config.captureFP) {
+          this.reportMetric('FP', fpEntries[0].startTime, 'ms', {}, 'vitals');
+        }
+        const fcpEntries = entryList.getEntriesByName('first-contentful-paint');
+        if (fcpEntries.length > 0) {
+          this.fcpTime = fcpEntries[0].startTime;
+          this.lastLongTaskEndTime = fcpEntries[0].startTime;
+          this.reportMetric('FCP', fcpEntries[0].startTime, 'ms', {}, 'vitals');
+          this.scheduleTTI();
+        }
+      });
+      po.observe({ type: 'paint', buffered: true });
+      this.observers.push(po);
+    } catch {
+      // Paint observer not supported
+    }
+  }
+ 
+  private observeLCP(): void {
+    try {
+      const po = new PerformanceObserver((entryList) => {
+        const entries = entryList.getEntries();
+        const lastEntry = entries[entries.length - 1] as PerformanceEntry & { renderTime?: number; loadTime?: number };
+        if (lastEntry) {
+          const value = lastEntry.renderTime || lastEntry.loadTime || lastEntry.startTime;
+          this.reportMetric('LCP', value, 'ms', {}, 'vitals');
+        }
+      });
+      po.observe({ type: 'largest-contentful-paint', buffered: true });
+      this.observers.push(po);
+    } catch {
+      // LCP not supported
+    }
+  }
+ 
+  private observeFID(): void {
+    try {
+      const po = new PerformanceObserver((entryList) => {
+        const entries = entryList.getEntries() as PerformanceEventTiming[];
+        if (entries.length > 0) {
+          const firstEntry = entries[0];
+          const value = firstEntry.processingStart - firstEntry.startTime;
+          this.reportMetric('FID', value, 'ms', {}, 'vitals');
+        }
+      });
+      po.observe({ type: 'first-input', buffered: true });
+      this.observers.push(po);
+    } catch {
+      // FID not supported
+    }
+  }
+ 
+  private observeCLS(): void {
+    try {
+      let clsValue = 0;
+      let sessionValue = 0;
+      let sessionEntries: PerformanceEntry[] = [];
+
+      const po = new PerformanceObserver((entryList) => {
+        const entries = entryList.getEntries() as unknown as { hadRecentInput?: boolean; value?: number; startTime: number; endTime?: number }[];
+        for (const entry of entries) {
+          if (!entry.hadRecentInput) {
+            const firstSessionEntry = sessionEntries[0];
+            const lastSessionEntry = sessionEntries[sessionEntries.length - 1];
+
+            if (
+              sessionValue &&
+              entry.startTime - (lastSessionEntry?.duration || 0) < 1000 &&
+              entry.startTime - firstSessionEntry.startTime < 5000
+            ) {
+              sessionValue += entry.value || 0;
+              sessionEntries.push(entry as unknown as PerformanceEntry);
+            } else {
+              sessionValue = entry.value || 0;
+              sessionEntries = [entry as unknown as PerformanceEntry];
+            }
+
+            if (sessionValue > clsValue) {
+              clsValue = sessionValue;
+              this.reportMetric('CLS', clsValue, '', {}, 'vitals');
+            }
+          }
+        }
+      });
+      po.observe({ type: 'layout-shift', buffered: true });
+      this.observers.push(po);
+    } catch {
+      // CLS not supported
+    }
+  }
+ 
+  private observeTTFB(): void {
+    try {
+      const po = new PerformanceObserver((entryList) => {
+        const navEntries = entryList.getEntriesByType('navigation') as PerformanceNavigationTiming[];
+        if (navEntries.length > 0) {
+          const navEntry = navEntries[0];
+          const ttfb = navEntry.responseStart - navEntry.requestStart;
+          this.reportMetric('TTFB', Math.max(0, ttfb), 'ms', {}, 'vitals');
+        }
+      });
+      po.observe({ type: 'navigation', buffered: true });
+      this.observers.push(po);
+    } catch {
+      // Navigation timing not supported
+    }
+  }
+ 
+  private observeLongTasks(): void {
+    if (!this.config.captureLongTasks) return;
+
+    try {
+      const po = new PerformanceObserver((entryList) => {
+        const entries = entryList.getEntries();
+        for (const entry of entries) {
+          const endTime = entry.startTime + entry.duration;
+          if (endTime > this.lastLongTaskEndTime) {
+            this.lastLongTaskEndTime = endTime;
+          }
+
+          if (this.fcpTime !== null && entry.startTime >= this.fcpTime) {
+            const blockingTime = entry.duration - 50;
+            if (blockingTime > 0) {
+              this.totalBlockingTime += blockingTime;
+            }
+          }
+
+          this.reportMetric('longtask', entry.duration, 'ms', {}, 'longtask');
+
+          this.scheduleTTI();
+        }
+      });
+      po.observe({ type: 'longtask', buffered: true });
+      this.observers.push(po);
+    } catch {
+      // Long tasks not supported
+    }
+  }
+ 
+  private scheduleTTI(): void {
+    if (this.ttiReported) return;
+
+    if (this.ttiTimer) {
+      clearTimeout(this.ttiTimer);
+    }
+
+    this.ttiTimer = setTimeout(() => {
+      if (this.ttiReported) return;
+      this.ttiReported = true;
+
+      const tti = Math.max(this.lastLongTaskEndTime, this.fcpTime || 0);
+      this.reportMetric('TTI', tti, 'ms', {}, 'vitals');
+      this.reportMetric('TBT', this.totalBlockingTime, 'ms', {}, 'vitals');
+    }, 5000);
+  }
+ 
+  private observeNavigation(): void {
+    if (!this.config.captureNavigation) return;
+    if (typeof performance === 'undefined') return;
+
+    this.onLoad = () => {
+      this.navLoadTimer = setTimeout(() => {
+        const timing = performance.timing;
+        if (!timing) return;
+
+        const navigationStart = timing.navigationStart;
+        const metrics: Record<string, number> = {
+          dom_ready: timing.domContentLoadedEventEnd - navigationStart,
+          load_time: timing.loadEventEnd - navigationStart,
+          dns: timing.domainLookupEnd - timing.domainLookupStart,
+          tcp: timing.connectEnd - timing.connectStart,
+          ssl: timing.secureConnectionStart > 0 ? timing.connectEnd - timing.secureConnectionStart : 0,
+          ttfb: timing.responseStart - timing.requestStart,
+          download: timing.responseEnd - timing.responseStart,
+          dom_parse: timing.domInteractive - timing.responseEnd,
+        };
+
+        for (const [name, value] of Object.entries(metrics)) {
+          if (value > 0) {
+            this.reportMetric(name, value, 'ms');
+          }
+        }
+
+        if (this.pageLoadTransaction && this.pageLoadTransaction.sampled !== false) {
+          this.buildNavigationSpans(timing, navigationStart);
+          this.finishPageLoadTransaction(timing.loadEventEnd || now());
+        }
+
+        this.navLoadTimer = null;
+      }, 0);
+    };
+
+    window.addEventListener('load', this.onLoad);
+  }
+ 
+  private buildNavigationSpans(timing: PerformanceTiming, navigationStart: number): void {
+    const spanDefs: Array<{ op: string; desc: string; start: number; end: number }> = [
+      { op: 'dns', desc: 'DNS Lookup', start: timing.domainLookupStart, end: timing.domainLookupEnd },
+      { op: 'tcp', desc: 'TCP Connection', start: timing.connectStart, end: timing.connectEnd },
+      { op: 'ssl', desc: 'SSL/TLS Negotiation', start: timing.secureConnectionStart, end: timing.connectEnd },
+      { op: 'ttfb', desc: 'Time to First Byte', start: timing.requestStart, end: timing.responseStart },
+      { op: 'response', desc: 'Response Download', start: timing.responseStart, end: timing.responseEnd },
+      { op: 'dom_parse', desc: 'DOM Parsing', start: timing.responseEnd, end: timing.domInteractive },
+      { op: 'dom_content_loaded', desc: 'DOM Content Loaded', start: timing.domLoading, end: timing.domContentLoadedEventEnd },
+      { op: 'load', desc: 'Page Load', start: timing.navigationStart, end: timing.loadEventEnd },
+    ];
+
+    for (const def of spanDefs) {
+      if (def.start > 0 && def.end > 0 && def.end > def.start) {
+        this.createNavigationSpan(
+          def.op,
+          def.desc,
+          def.start,
+          def.end
+        );
+      }
+    }
+  }
+ 
+  private finishPageLoadTransaction(endTime: number): void {
+    if (!this.pageLoadTransaction) return;
+
+    if (Object.keys(this.measurements).length > 0) {
+      (this.pageLoadTransaction as unknown as { setData: (k: string, v: unknown) => void }).setData(
+        'measurements',
+        this.measurements
+      );
+    }
+
+    this.pageLoadTransaction.setStatus('ok');
+    this.pageLoadTransaction.finish(endTime);
+    this.pageLoadTransaction = null;
+  }
+ 
+  private observeResources(): void {
+    if (!this.config.captureResources && !this.config.enablePageLoadTracing) return;
+    if (typeof performance === 'undefined') return;
+
+    try {
+      const po = new PerformanceObserver((entryList) => {
+        const entries = entryList.getEntriesByType('resource') as PerformanceResourceTiming[];
+        for (const entry of entries) {
+          if (entry.duration > 1000 && this.config.captureResources) {
+            this.reportMetric('resource_slow', entry.duration, 'ms', {
+              resource_name: entry.name.substring(0, 200),
+              resource_type: entry.initiatorType,
+            }, 'resource');
+          }
+
+          if (this.config.enablePageLoadTracing && this.pageLoadTransaction) {
+            this.createResourceSpan(entry);
+          }
+        }
+      });
+      po.observe({ type: 'resource', buffered: true });
+      this.observers.push(po);
+    } catch {
+      // Resource timing not supported
+    }
+  }
+ 
+  private getRating(name: string, value: number): 'good' | 'needs-improvement' | 'poor' {
+    const thresholds: Record<string, { good: number; poor: number }> = {
+      LCP: { good: 2500, poor: 4000 },
+      FCP: { good: 1800, poor: 3000 },
+      FP: { good: 1800, poor: 3000 },
+      FID: { good: 100, poor: 300 },
+      CLS: { good: 0.1, poor: 0.25 },
+      TTFB: { good: 800, poor: 1800 },
+    };
+
+    const threshold = thresholds[name];
+    if (!threshold) return 'good';
+
+    if (value <= threshold.good) return 'good';
+    if (value <= threshold.poor) return 'needs-improvement';
+    return 'poor';
+  }
+ 
+  private reportMetric(name: string, value: number, unit: string, extraTags: Record<string, string> = {}, sampleType: 'default' | 'resource' | 'longtask' | 'vitals' = 'default'): void {
+    if (!this.shouldSample(sampleType)) return;
+
+    const rating = this.getRating(name, value);
+    
+    const event: PerformanceEvent = {
+      type: 'performance',
+      level: 'info',
+      metric: name,
+      value: Math.round(value * 100) / 100,
+      unit,
+      rating,
+      timestamp: now(),
+      tags: {
+        metric: name,
+        rating,
+        ...extraTags,
+      },
+    };
+
+    this.client.captureEvent(event);
+
+    if (this.pageLoadTransaction && this.pageLoadTransaction.sampled !== false) {
+      this.recordMeasurement(name, value, unit, rating);
+    }
+  }
+ 
+  private recordMeasurement(name: string, value: number, unit?: string, rating?: 'good' | 'needs-improvement' | 'poor'): void {
+    if (!this.pageLoadTransaction) return;
+
+    this.measurements[name] = {
+      value: Math.round(value * 100) / 100,
+      unit,
+      rating,
+    };
+
+    this.pageLoadTransaction.setTag(`measurement.${name}.rating`, rating || 'unknown');
+  }
+ 
+  private createNavigationSpan(
+    op: string,
+    description: string,
+    startTime: number,
+    endTime: number,
+    tags?: Record<string, string>
+  ): void {
+    if (!this.pageLoadTransaction || this.pageLoadTransaction.sampled === false) return;
+    if (endTime <= startTime) return;
+
+    const span = this.pageLoadTransaction.startChild({
+      op: `browser.${op}`,
+      description,
+      startTimestamp: startTime,
+      tags,
+    });
+
+    span.finish(endTime);
+  }
+ 
+  private createResourceSpan(entry: PerformanceResourceTiming): void {
+    if (!this.pageLoadTransaction || this.pageLoadTransaction.sampled === false) return;
+
+    const maxResources = this.config.maxResourceSpans ?? 50;
+    if (this.resourceSpanCount >= maxResources) return;
+    this.resourceSpanCount++;
+
+    const timeOrigin = typeof performance !== 'undefined' && performance.timeOrigin
+      ? performance.timeOrigin
+      : (performance.timing?.navigationStart || 0);
+    const startTime = timeOrigin + entry.startTime;
+    const endTime = timeOrigin + (entry.responseEnd || entry.duration || entry.startTime);
+
+    if (endTime <= startTime) return;
+
+    const url = entry.name.substring(0, 200);
+    const span = this.pageLoadTransaction.startChild({
+      op: `resource.${entry.initiatorType || 'other'}`,
+      description: url,
+      startTimestamp: startTime,
+      tags: {
+        'resource.type': entry.initiatorType || 'other',
+        'resource.url': url,
+        'resource.transfer_size': String(entry.transferSize || 0),
+        'resource.decoded_size': String(entry.decodedBodySize || 0),
+      },
+      data: {
+        transferSize: entry.transferSize,
+        decodedSize: entry.decodedBodySize,
+        encodedSize: entry.encodedBodySize,
+      },
+    });
+
+    span.finish(endTime);
+  }
+ 
+  destroy(): void {
+    for (const observer of this.observers) {
+      try {
+        observer.disconnect();
+      } catch {
+        // ignore
+      }
+    }
+    this.observers = [];
+
+    if (this.ttiTimer) {
+      clearTimeout(this.ttiTimer);
+      this.ttiTimer = null;
+    }
+
+    if (this.navLoadTimer) {
+      clearTimeout(this.navLoadTimer);
+      this.navLoadTimer = null;
+    }
+
+    if (typeof window !== 'undefined' && this.onLoad) {
+      window.removeEventListener('load', this.onLoad);
+    }
+
+    if (this.pageLoadTransaction) {
+      this.pageLoadTransaction.setStatus('internal_error');
+      this.pageLoadTransaction.finish();
+      this.pageLoadTransaction = null;
+    }
+
+    this.measurements = {};
+    this.resourceSpanCount = 0;
+  }
+}
+ 
+export default PerformancePlugin;
+ 
+ +
+
+ + + + + + + + \ No newline at end of file diff --git a/coverage/src/plugins/RouterPlugin.ts.html b/coverage/src/plugins/RouterPlugin.ts.html new file mode 100644 index 0000000..d6b50b3 --- /dev/null +++ b/coverage/src/plugins/RouterPlugin.ts.html @@ -0,0 +1,628 @@ + + + + + + Code coverage report for src/plugins/RouterPlugin.ts + + + + + + + + + +
+
+

All files / src/plugins RouterPlugin.ts

+
+ +
+ 14.36% + Statements + 26/181 +
+ + +
+ 100% + Branches + 0/0 +
+ + +
+ 0% + Functions + 0/10 +
+ + +
+ 14.36% + Lines + 26/181 +
+ + +
+

+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +

+ +
+
+

+
1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +30 +31 +32 +33 +34 +35 +36 +37 +38 +39 +40 +41 +42 +43 +44 +45 +46 +47 +48 +49 +50 +51 +52 +53 +54 +55 +56 +57 +58 +59 +60 +61 +62 +63 +64 +65 +66 +67 +68 +69 +70 +71 +72 +73 +74 +75 +76 +77 +78 +79 +80 +81 +82 +83 +84 +85 +86 +87 +88 +89 +90 +91 +92 +93 +94 +95 +96 +97 +98 +99 +100 +101 +102 +103 +104 +105 +106 +107 +108 +109 +110 +111 +112 +113 +114 +115 +116 +117 +118 +119 +120 +121 +122 +123 +124 +125 +126 +127 +128 +129 +130 +131 +132 +133 +134 +135 +136 +137 +138 +139 +140 +141 +142 +143 +144 +145 +146 +147 +148 +149 +150 +151 +152 +153 +154 +155 +156 +157 +158 +159 +160 +161 +162 +163 +164 +165 +166 +167 +168 +169 +170 +171 +172 +173 +174 +175 +176 +177 +178 +179 +180 +181 +1821x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +1x +1x +  +  +  +  +  +  +  +  +  +1x +1x +  +  +  +  +  +  +  +  +  +  +1x +1x +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +1x +1x +  +  +  +  +  +  +  +  +  +  +  +  +1x +1x +  +  +  +  +  +  +  +  +  +  +  +1x +1x +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +1x +1x +1x + 
import type { LightPlugin, LightClient, Transaction, SpanStatus, LightConfig } from '../types';
+import { now, isObject } from '../utils/helper';
+ 
+interface RouterPluginConfig {
+  enable?: boolean;
+  instrumentHistory?: boolean;
+  instrumentHash?: boolean;
+  routeNameFormatter?: (url: string) => string;
+  maxTransactionDurationMs?: number;
+}
+ 
+class RouterPlugin implements LightPlugin {
+  name = 'router';
+  version = '1.0.0';
+
+  private client!: LightClient;
+  private config: RouterPluginConfig = {
+    enable: true,
+    instrumentHistory: true,
+    instrumentHash: true,
+    maxTransactionDurationMs: 30000,
+  };
+
+  private currentTransaction: Transaction | null = null;
+  private lastRoute: string = '';
+  private originalPushState?: typeof history.pushState;
+  private originalReplaceState?: typeof history.replaceState;
+  private maxDurationTimer: ReturnType<typeof setTimeout> | null = null;
+  private routeChangeTimer: ReturnType<typeof setTimeout> | null = null;
+
+  setup(client: LightClient): void {
+    this.client = client;
+    this.loadConfig();
+
+    if (typeof window === 'undefined') return;
+    if (!this.config.enable) return;
+
+    if (this.config.instrumentHistory) {
+      this.instrumentHistory();
+    }
+
+    if (this.config.instrumentHash) {
+      this.instrumentHash();
+    }
+  }
+
+  private loadConfig(): void {
+    const clientConfig = this.client.config as LightConfig;
+    if (clientConfig && isObject((clientConfig as Record<string, unknown>).router)) {
+      this.config = { ...this.config, ...((clientConfig as Record<string, unknown>).router as object) };
+    }
+  }
+
+  private instrumentHistory(): void {
+    if (typeof history === 'undefined' || !history.pushState) return;
+
+    this.originalPushState = history.pushState.bind(history);
+    this.originalReplaceState = history.replaceState.bind(history);
+
+    history.pushState = (data: unknown, title: string, url?: string | null): void => {
+      this.originalPushState!(data, title, url);
+      this.handleRouteChange(url || location.pathname + location.search, 'pushState');
+    };
+
+    history.replaceState = (data: unknown, title: string, url?: string | null): void => {
+      this.originalReplaceState!(data, title, url);
+      this.handleRouteChange(url || location.pathname + location.search, 'replaceState');
+    };
+
+    window.addEventListener('popstate', this.handlePopState);
+  }
+
+  private handlePopState = (): void => {
+    this.handleRouteChange(location.pathname + location.search, 'popstate');
+  };
+
+  private instrumentHash(): void {
+    window.addEventListener('hashchange', this.handleHashChange);
+  }
+
+  private handleHashChange = (): void => {
+    this.handleRouteChange(location.hash || '#/', 'hashchange');
+  };
+ 
+  private handleRouteChange(to: string, source: string): void {
+    if (this.routeChangeTimer) {
+      clearTimeout(this.routeChangeTimer);
+    }
+
+    this.routeChangeTimer = setTimeout(() => {
+      this.routeChangeTimer = null;
+      this.processRouteChange(to, source);
+    }, 50);
+  }
+ 
+  private processRouteChange(to: string, source: string): void {
+    const routeName = this.config.routeNameFormatter
+      ? this.config.routeNameFormatter(to)
+      : to.split('?')[0];
+
+    if (routeName === this.lastRoute) return;
+    this.lastRoute = routeName;
+
+    this.finishCurrentTransaction('ok');
+    this.startNavigationTransaction(routeName, source);
+  }
+ 
+  private startNavigationTransaction(name: string, source: string): void {
+    if (!this.client) return;
+
+    const transaction = this.client.startTransaction({
+      name,
+      op: 'navigation',
+      description: `Navigation to ${name}`,
+      type: 'navigation',
+      tags: {
+        'route.name': name,
+        'route.source': source,
+      },
+    });
+
+    if (transaction) {
+      this.currentTransaction = transaction;
+      this.startMaxDurationTimer();
+    }
+  }
+ 
+  private startMaxDurationTimer(): void {
+    if (this.maxDurationTimer) {
+      clearTimeout(this.maxDurationTimer);
+    }
+
+    const maxDuration = this.config.maxTransactionDurationMs ?? 30000;
+    this.maxDurationTimer = setTimeout(() => {
+      if (this.currentTransaction) {
+        this.currentTransaction.setStatus('deadline_exceeded');
+        this.finishCurrentTransaction('deadline_exceeded');
+      }
+    }, maxDuration);
+  }
+ 
+  private finishCurrentTransaction(status: SpanStatus = 'ok'): void {
+    if (this.maxDurationTimer) {
+      clearTimeout(this.maxDurationTimer);
+      this.maxDurationTimer = null;
+    }
+
+    if (this.currentTransaction) {
+      this.currentTransaction.setStatus(status);
+      this.currentTransaction.finish();
+      this.currentTransaction = null;
+    }
+  }
+ 
+  destroy(): void {
+    if (this.originalPushState && typeof history !== 'undefined') {
+      history.pushState = this.originalPushState;
+    }
+    if (this.originalReplaceState && typeof history !== 'undefined') {
+      history.replaceState = this.originalReplaceState;
+    }
+
+    if (typeof window !== 'undefined') {
+      window.removeEventListener('popstate', this.handlePopState);
+      window.removeEventListener('hashchange', this.handleHashChange);
+    }
+
+    if (this.maxDurationTimer) {
+      clearTimeout(this.maxDurationTimer);
+      this.maxDurationTimer = null;
+    }
+    if (this.routeChangeTimer) {
+      clearTimeout(this.routeChangeTimer);
+      this.routeChangeTimer = null;
+    }
+
+    this.finishCurrentTransaction('aborted');
+  }
+}
+ 
+export default RouterPlugin;
+ 
+ +
+
+ + + + + + + + \ No newline at end of file diff --git a/coverage/src/plugins/SamplingPlugin.ts.html b/coverage/src/plugins/SamplingPlugin.ts.html new file mode 100644 index 0000000..520a4be --- /dev/null +++ b/coverage/src/plugins/SamplingPlugin.ts.html @@ -0,0 +1,367 @@ + + + + + + Code coverage report for src/plugins/SamplingPlugin.ts + + + + + + + + + +
+
+

All files / src/plugins SamplingPlugin.ts

+
+ +
+ 100% + Statements + 94/94 +
+ + +
+ 89.28% + Branches + 25/28 +
+ + +
+ 100% + Functions + 8/8 +
+ + +
+ 100% + Lines + 94/94 +
+ + +
+

+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +

+ +
+
+

+
1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +30 +31 +32 +33 +34 +35 +36 +37 +38 +39 +40 +41 +42 +43 +44 +45 +46 +47 +48 +49 +50 +51 +52 +53 +54 +55 +56 +57 +58 +59 +60 +61 +62 +63 +64 +65 +66 +67 +68 +69 +70 +71 +72 +73 +74 +75 +76 +77 +78 +79 +80 +81 +82 +83 +84 +85 +86 +87 +88 +89 +90 +91 +92 +93 +94 +951x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +18x +18x +18x +18x +18x +18x +18x +18x +18x +18x +18x +18x +18x +1x +1x +16x +16x +16x +1x +1x +16x +16x +14x +14x +13x +13x +14x +16x +1x +1x +16x +16x +13x +13x +13x +16x +11x +11x +2x +16x +1x +1x +19x +19x +19x +19x +1x +1x +18x +18x +19x +19x +1x +1x +13x +13x +4x +13x +1x +1x +16x +16x +6x +6x +6x +6x +6x +6x +6x +10x +16x +1x +1x +1x +1x +1x +1x +1x + 
import type { LightPlugin, LightClient, SentryEvent, LightConfig } from '../types';
+import { isObject } from '../utils/helper';
+import { logDebug } from '../utils/logger';
+ 
+interface SampleRateConfig {
+  error?: number;
+  performance?: number;
+  network?: number;
+  behavior?: number;
+  [key: string]: number | undefined;
+}
+ 
+interface SamplingPluginConfig {
+  rates?: SampleRateConfig;
+}
+ 
+class SamplingPlugin implements LightPlugin {
+  name = 'sampling';
+  version = '1.0.0';
+ 
+  private client!: LightClient;
+  private config: SamplingPluginConfig = {
+    rates: {
+      error: 1,
+      performance: 1,
+      network: 1,
+      behavior: 1,
+    },
+  };
+ 
+  setup(client: LightClient): void {
+    this.client = client;
+    this.loadConfig();
+  }
+ 
+  private loadConfig(): void {
+    const clientConfig = this.client.config as LightConfig;
+    if (clientConfig && isObject(clientConfig.sampling)) {
+      const samplingConfig = clientConfig.sampling as object;
+      if ('rates' in samplingConfig && isObject((samplingConfig as { rates?: object }).rates)) {
+        this.config.rates = { ...this.config.rates, ...((samplingConfig as { rates: object }).rates as object) } as SampleRateConfig;
+      }
+    }
+  }
+ 
+  private shouldSample(event: SentryEvent): boolean {
+    const globalRate = (this.client.config as LightConfig).sampleRate ?? 1;
+    if (globalRate <= 0) return false;
+ 
+    const typeRate = this.getTypeRate(event);
+ 
+    if (globalRate >= 1) {
+      return this.randomCheck(typeRate);
+    }
+    return this.randomCheck(globalRate * typeRate);
+  }
+ 
+  private getTypeRate(event: SentryEvent): number {
+    const rates = this.config.rates || {};
+    const type = event.type;
+ 
+    if (type === 'count') {
+      return 1;
+    }
+ 
+    const rate = rates[type];
+    return rate !== undefined ? rate : 1;
+  }
+ 
+  private randomCheck(rate: number): boolean {
+    if (rate >= 1) return true;
+    if (rate <= 0) return false;
+    return Math.random() < rate;
+  }
+ 
+  beforeReport(event: SentryEvent): SentryEvent | null {
+    const sampled = this.shouldSample(event);
+    if (!sampled) {
+      logDebug('SamplingPlugin', 'Event dropped by sampling', {
+        type: event.type,
+        globalRate: (this.client.config as LightConfig).sampleRate ?? 1,
+        typeRate: this.getTypeRate(event),
+      });
+      return null;
+    }
+    return event;
+  }
+ 
+  destroy(): void {
+    // nothing to clean up
+  }
+}
+ 
+export default SamplingPlugin;
+ 
+ +
+
+ + + + + + + + \ No newline at end of file diff --git a/coverage/src/plugins/index.html b/coverage/src/plugins/index.html new file mode 100644 index 0000000..a8c839e --- /dev/null +++ b/coverage/src/plugins/index.html @@ -0,0 +1,221 @@ + + + + + + Code coverage report for src/plugins + + + + + + + + + +
+
+

All files src/plugins

+
+ +
+ 18.25% + Statements + 426/2334 +
+ + +
+ 89.28% + Branches + 25/28 +
+ + +
+ 7.47% + Functions + 8/107 +
+ + +
+ 18.25% + Lines + 426/2334 +
+ + +
+

+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +

+ +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FileStatementsBranchesFunctionsLines
BehaviorPlugin.ts +
+
15.52%52/335100%0/00%0/1315.52%52/335
ErrorPlugin.ts +
+
17.39%52/299100%0/00%0/1417.39%52/299
InteractionPlugin.ts +
+
16.9%35/207100%0/00%0/1016.9%35/207
NetworkPlugin.ts +
+
14.32%55/384100%0/00%0/1414.32%55/384
OfflinePlugin.ts +
+
14.47%44/304100%0/00%0/1514.47%44/304
PerformancePlugin.ts +
+
12.83%68/530100%0/00%0/2312.83%68/530
RouterPlugin.ts +
+
14.36%26/181100%0/00%0/1014.36%26/181
SamplingPlugin.ts +
+
100%94/9489.28%25/28100%8/8100%94/94
+
+
+
+ + + + + + + + \ No newline at end of file diff --git a/coverage/src/utils/baggage.ts.html b/coverage/src/utils/baggage.ts.html new file mode 100644 index 0000000..13c2bbf --- /dev/null +++ b/coverage/src/utils/baggage.ts.html @@ -0,0 +1,382 @@ + + + + + + Code coverage report for src/utils/baggage.ts + + + + + + + + + +
+
+

All files / src/utils baggage.ts

+
+ +
+ 97.97% + Statements + 97/99 +
+ + +
+ 97.14% + Branches + 34/35 +
+ + +
+ 100% + Functions + 3/3 +
+ + +
+ 97.97% + Lines + 97/99 +
+ + +
+

+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +

+ +
+
+

+
1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +30 +31 +32 +33 +34 +35 +36 +37 +38 +39 +40 +41 +42 +43 +44 +45 +46 +47 +48 +49 +50 +51 +52 +53 +54 +55 +56 +57 +58 +59 +60 +61 +62 +63 +64 +65 +66 +67 +68 +69 +70 +71 +72 +73 +74 +75 +76 +77 +78 +79 +80 +81 +82 +83 +84 +85 +86 +87 +88 +89 +90 +91 +92 +93 +94 +95 +96 +97 +98 +99 +1001x +1x +1x +1x +1x +1x +15x +15x +15x +38x +36x +38x +38x +38x +15x +15x +15x +1x +1x +1x +  +  +1x +15x +15x +15x +1x +1x +8x +8x +8x +7x +7x +8x +20x +20x +19x +19x +19x +19x +19x +20x +16x +16x +19x +19x +19x +19x +20x +7x +7x +7x +1x +1x +16x +16x +16x +16x +16x +16x +16x +16x +16x +16x +16x +16x +16x +16x +16x +3x +3x +16x +16x +5x +5x +16x +16x +2x +2x +16x +16x +3x +3x +3x +3x +2x +2x +3x +16x +16x +1x +1x +16x +16x +1x +1x +16x +16x +16x + 
import type { BaggageFields } from '../types';
+ 
+const SENTRY_PREFIX = 'sentry-';
+const MAX_BAGGAGE_LENGTH = 8192;
+ 
+export function serializeBaggage(fields: BaggageFields): string {
+  const parts: string[] = [];
+ 
+  for (const [key, value] of Object.entries(fields)) {
+    if (value === undefined || value === null || value === '') continue;
+ 
+    const prefixedKey = key.startsWith(SENTRY_PREFIX) ? key : `${SENTRY_PREFIX}${key}`;
+    parts.push(`${prefixedKey}=${encodeURIComponent(String(value))}`);
+  }
+ 
+  let result = parts.join(',');
+  if (result.length > MAX_BAGGAGE_LENGTH) {
+    result = result.substring(0, MAX_BAGGAGE_LENGTH);
+    const lastComma = result.lastIndexOf(',');
+    if (lastComma > 0) {
+      result = result.substring(0, lastComma);
+    }
+  }
+ 
+  return result;
+}
+ 
+export function parseBaggage(header: string): BaggageFields {
+  const fields: BaggageFields = {};
+ 
+  if (!header) return fields;
+ 
+  const parts = header.split(',');
+  for (const part of parts) {
+    const eqIdx = part.indexOf('=');
+    if (eqIdx === -1) continue;
+ 
+    const rawKey = part.substring(0, eqIdx).trim();
+    const value = decodeURIComponent(part.substring(eqIdx + 1).trim());
+ 
+    let key = rawKey;
+    if (rawKey.startsWith(SENTRY_PREFIX)) {
+      key = rawKey.substring(SENTRY_PREFIX.length);
+    }
+ 
+    if (key) {
+      fields[key] = value;
+    }
+  }
+ 
+  return fields;
+}
+ 
+export function createBaggageFromTransaction(
+  traceId: string,
+  options?: {
+    dsnPublicKey?: string;
+    sampled?: boolean;
+    sampleRate?: number;
+    user?: { id?: string; segment?: string };
+    release?: string;
+    environment?: string;
+  }
+): BaggageFields {
+  const fields: BaggageFields = {
+    trace_id: traceId,
+  };
+ 
+  if (options?.dsnPublicKey) {
+    fields.public_key = options.dsnPublicKey;
+  }
+ 
+  if (options?.sampled !== undefined) {
+    fields.sampled = options.sampled ? 'true' : 'false';
+  }
+ 
+  if (options?.sampleRate !== undefined) {
+    fields.sample_rate = String(options.sampleRate);
+  }
+ 
+  if (options?.user) {
+    if (options.user.id) {
+      fields.user_id = options.user.id;
+    }
+    if (options.user.segment) {
+      fields.user_segment = options.user.segment;
+    }
+  }
+ 
+  if (options?.release) {
+    fields.release = options.release;
+  }
+ 
+  if (options?.environment) {
+    fields.environment = options.environment;
+  }
+ 
+  return fields;
+}
+ 
+ +
+
+ + + + + + + + \ No newline at end of file diff --git a/coverage/src/utils/dsn.ts.html b/coverage/src/utils/dsn.ts.html new file mode 100644 index 0000000..40a3e79 --- /dev/null +++ b/coverage/src/utils/dsn.ts.html @@ -0,0 +1,172 @@ + + + + + + Code coverage report for src/utils/dsn.ts + + + + + + + + + +
+
+

All files / src/utils dsn.ts

+
+ +
+ 93.1% + Statements + 27/29 +
+ + +
+ 100% + Branches + 5/5 +
+ + +
+ 66.66% + Functions + 2/3 +
+ + +
+ 93.1% + Lines + 27/29 +
+ + +
+

+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +

+ +
+
+

+
1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +301x +1x +1x +5x +5x +5x +2x +2x +3x +3x +3x +3x +3x +3x +3x +3x +3x +5x +2x +2x +5x +1x +1x +2x +2x +1x +1x +  +  + 
import type { DSNInfo } from '../types';
+ 
+export function parseDSN(dsn: string): DSNInfo {
+  try {
+    const match = dsn.match(/^(https?):\/\/([^@]+)@([^/]+)\/(.+)$/);
+    if (!match) {
+      throw new Error('Invalid DSN format');
+    }
+ 
+    const [, protocol, publicKey, host, projectId] = match;
+ 
+    return {
+      protocol,
+      publicKey,
+      host,
+      projectId,
+    };
+  } catch (e) {
+    throw new Error(`Failed to parse DSN: ${(e as Error).message}`);
+  }
+}
+ 
+export function getEnvelopeUrl(dsn: DSNInfo): string {
+  return `${dsn.protocol}://${dsn.host}/api/${dsn.projectId}/envelope/?sentry_key=${dsn.publicKey}`;
+}
+ 
+export function getStoreUrl(dsn: DSNInfo): string {
+  return `${dsn.protocol}://${dsn.host}/api/${dsn.projectId}/store/?sentry_key=${dsn.publicKey}`;
+}
+ +
+
+ + + + + + + + \ No newline at end of file diff --git a/coverage/src/utils/env.ts.html b/coverage/src/utils/env.ts.html new file mode 100644 index 0000000..3c02b66 --- /dev/null +++ b/coverage/src/utils/env.ts.html @@ -0,0 +1,964 @@ + + + + + + Code coverage report for src/utils/env.ts + + + + + + + + + +
+
+

All files / src/utils env.ts

+
+ +
+ 100% + Statements + 293/293 +
+ + +
+ 78.87% + Branches + 56/71 +
+ + +
+ 100% + Functions + 10/10 +
+ + +
+ 100% + Lines + 293/293 +
+ + +
+

+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +

+ +
+
+

+
1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +30 +31 +32 +33 +34 +35 +36 +37 +38 +39 +40 +41 +42 +43 +44 +45 +46 +47 +48 +49 +50 +51 +52 +53 +54 +55 +56 +57 +58 +59 +60 +61 +62 +63 +64 +65 +66 +67 +68 +69 +70 +71 +72 +73 +74 +75 +76 +77 +78 +79 +80 +81 +82 +83 +84 +85 +86 +87 +88 +89 +90 +91 +92 +93 +94 +95 +96 +97 +98 +99 +100 +101 +102 +103 +104 +105 +106 +107 +108 +109 +110 +111 +112 +113 +114 +115 +116 +117 +118 +119 +120 +121 +122 +123 +124 +125 +126 +127 +128 +129 +130 +131 +132 +133 +134 +135 +136 +137 +138 +139 +140 +141 +142 +143 +144 +145 +146 +147 +148 +149 +150 +151 +152 +153 +154 +155 +156 +157 +158 +159 +160 +161 +162 +163 +164 +165 +166 +167 +168 +169 +170 +171 +172 +173 +174 +175 +176 +177 +178 +179 +180 +181 +182 +183 +184 +185 +186 +187 +188 +189 +190 +191 +192 +193 +194 +195 +196 +197 +198 +199 +200 +201 +202 +203 +204 +205 +206 +207 +208 +209 +210 +211 +212 +213 +214 +215 +216 +217 +218 +219 +220 +221 +222 +223 +224 +225 +226 +227 +228 +229 +230 +231 +232 +233 +234 +235 +236 +237 +238 +239 +240 +241 +242 +243 +244 +245 +246 +247 +248 +249 +250 +251 +252 +253 +254 +255 +256 +257 +258 +259 +260 +261 +262 +263 +264 +265 +266 +267 +268 +269 +270 +271 +272 +273 +274 +275 +276 +277 +278 +279 +280 +281 +282 +283 +284 +285 +286 +287 +288 +289 +290 +291 +292 +293 +2941x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +31x +31x +31x +31x +31x +31x +31x +31x +31x +31x +31x +31x +31x +31x +31x +31x +31x +293x +293x +26x +26x +26x +26x +293x +5x +5x +5x +1x +31x +31x +31x +31x +31x +31x +31x +31x +31x +31x +31x +31x +31x +31x +31x +31x +31x +219x +219x +26x +26x +16x +16x +26x +26x +219x +5x +5x +5x +1x +31x +31x +31x +31x +31x +31x +2x +31x +11x +11x +31x +31x +31x +31x +31x +31x +31x +31x +31x +31x +31x +3x +3x +31x +2x +2x +28x +3x +3x +26x +1x +1x +23x +4x +4x +4x +31x +31x +31x +1x +1x +31x +31x +31x +31x +31x +31x +31x +31x +31x +31x +31x +31x +31x +31x +31x +31x +31x +31x +31x +31x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +13x +10x +10x +13x +2x +2x +8x +8x +8x +8x +8x +8x +8x +8x +8x +8x +8x +8x +8x +8x +8x +8x +13x +15x +15x +9x +9x +9x +15x +7x +13x +1x +1x +1x +1x +1x +2x +2x +1x +1x +1x +2x +1x +1x +1x +1x +1x +1x +7x +13x +5x +5x +2x +13x +1x +1x +13x +1x +1x +11x +10x +10x +15x +12x +3x +3x +3x +3x +3x +9x +9x +3x +10x +10x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +5x +5x +5x +5x +5x +5x +5x +5x +5x +5x +5x +5x +5x +5x +5x +5x +5x +5x +5x +5x +1x +1x +3x +3x +3x +3x + 
import { md5 } from './hash';
+ 
+export interface BrowserInfo {
+  name: string;
+  version: string;
+  major: string;
+}
+ 
+export interface OSInfo {
+  name: string;
+  version: string;
+}
+ 
+export interface DeviceInfo {
+  type: 'desktop' | 'mobile' | 'tablet';
+  vendor: string;
+  model: string;
+}
+ 
+export interface EnvInfo {
+  browser: BrowserInfo;
+  os: OSInfo;
+  device: DeviceInfo;
+  url: string;
+  referrer: string;
+  title: string;
+  language: string;
+  user_agent: string;
+  screen_width: number;
+  screen_height: number;
+  viewport_width: number;
+  viewport_height: number;
+}
+ 
+function detectBrowser(ua: string): BrowserInfo {
+  const browsers: { name: string; pattern: RegExp; versionIndex?: number }[] = [
+    { name: 'WeChat', pattern: /MicroMessenger\/([\d.]+)/i },
+    { name: 'QQ Browser', pattern: /QIBrowser\/([\d.]+)/i },
+    { name: 'UC Browser', pattern: /UCBrowser\/([\d.]+)/i },
+    { name: 'Edge', pattern: /Edg\/([\d.]+)/i },
+    { name: 'Edge', pattern: /Edge\/([\d.]+)/i },
+    { name: 'Opera', pattern: /OPR\/([\d.]+)/i },
+    { name: 'Opera', pattern: /Opera\/([\d.]+)/i },
+    { name: 'Firefox', pattern: /Firefox\/([\d.]+)/i },
+    { name: 'Safari', pattern: /Version\/([\d.]+).*Safari/i },
+    { name: 'Chrome', pattern: /Chrome\/([\d.]+)/i },
+    { name: 'IE', pattern: /MSIE ([\d.]+)/i },
+    { name: 'IE', pattern: /Trident.*rv:([\d.]+)/i },
+  ];
+ 
+  for (const b of browsers) {
+    const match = ua.match(b.pattern);
+    if (match) {
+      const version = match[1] || '';
+      const major = version.split('.')[0] || '';
+      return { name: b.name, version, major };
+    }
+  }
+ 
+  return { name: 'Unknown', version: '', major: '' };
+}
+ 
+function detectOS(ua: string): OSInfo {
+  const oss: { name: string; pattern: RegExp; versionIndex?: number }[] = [
+    { name: 'Windows 11', pattern: /Windows NT 10\.0.*Win64.*x64/i },
+    { name: 'Windows 10', pattern: /Windows NT 10\.0/i },
+    { name: 'Windows 8.1', pattern: /Windows NT 6\.3/i },
+    { name: 'Windows 8', pattern: /Windows NT 6\.2/i },
+    { name: 'Windows 7', pattern: /Windows NT 6\.1/i },
+    { name: 'Windows Vista', pattern: /Windows NT 6\.0/i },
+    { name: 'Windows XP', pattern: /Windows NT 5\.1/i },
+    { name: 'macOS', pattern: /Mac OS X ([\d_.]+)/i },
+    { name: 'iOS', pattern: /OS ([\d_.]+) like Mac OS X/i },
+    { name: 'Android', pattern: /Android ([\d.]+)/i },
+    { name: 'Android', pattern: /Android/i },
+    { name: 'Linux', pattern: /Linux/i },
+  ];
+ 
+  for (const o of oss) {
+    const match = ua.match(o.pattern);
+    if (match) {
+      let version = match[1] || '';
+      if (version) {
+        version = version.replace(/_/g, '.');
+      }
+      return { name: o.name, version };
+    }
+  }
+ 
+  return { name: 'Unknown', version: '' };
+}
+ 
+function detectDevice(ua: string): DeviceInfo {
+  const isMobile = /Mobile|Android|iPhone|iPod|BlackBerry|Windows Phone|Opera Mini/i.test(ua);
+  const isTablet = /Tablet|iPad|PlayBook|Kindle|Silk/i.test(ua);
+ 
+  let type: 'desktop' | 'mobile' | 'tablet' = 'desktop';
+  if (isTablet) {
+    type = 'tablet';
+  } else if (isMobile) {
+    type = 'mobile';
+  }
+ 
+  let vendor = '';
+  let model = '';
+ 
+  const iphoneMatch = ua.match(/iPhone/i);
+  const ipadMatch = ua.match(/iPad/i);
+  const samsungMatch = ua.match(/SM-([A-Z0-9]+)/i);
+  const pixelMatch = ua.match(/Pixel ([0-9A-Z]+)/i);
+  const huaweiMatch = ua.match(/HUAWEI ([A-Z0-9]+)/i);
+ 
+  if (iphoneMatch) {
+    vendor = 'Apple';
+    model = 'iPhone';
+  } else if (ipadMatch) {
+    vendor = 'Apple';
+    model = 'iPad';
+  } else if (samsungMatch) {
+    vendor = 'Samsung';
+    model = samsungMatch[1];
+  } else if (pixelMatch) {
+    vendor = 'Google';
+    model = `Pixel ${pixelMatch[1]}`;
+  } else if (huaweiMatch) {
+    vendor = 'Huawei';
+    model = huaweiMatch[1];
+  }
+ 
+  return { type, vendor, model };
+}
+ 
+export function getEnvInfo(): EnvInfo {
+  const ua = typeof navigator !== 'undefined' ? navigator.userAgent : '';
+  const browser = detectBrowser(ua);
+  const os = detectOS(ua);
+  const device = detectDevice(ua);
+ 
+  return {
+    browser,
+    os,
+    device,
+    url: typeof location !== 'undefined' ? location.href : '',
+    referrer: typeof document !== 'undefined' ? document.referrer : '',
+    title: typeof document !== 'undefined' ? document.title : '',
+    language: typeof navigator !== 'undefined' ? navigator.language : '',
+    user_agent: ua,
+    screen_width: typeof screen !== 'undefined' ? screen.width : 0,
+    screen_height: typeof screen !== 'undefined' ? screen.height : 0,
+    viewport_width: typeof window !== 'undefined' ? window.innerWidth : 0,
+    viewport_height: typeof window !== 'undefined' ? window.innerHeight : 0,
+  };
+}
+ 
+export function getPageUrl(): string {
+  return typeof location !== 'undefined' ? location.href : '';
+}
+ 
+export function getReferrer(): string {
+  return typeof document !== 'undefined' ? document.referrer : '';
+}
+ 
+export function sanitizeUrl(url: string): string {
+  if (!url) return url;
+ 
+  // 过滤 javascript: 伪协议防止 XSS
+  if (/^\s*javascript:/i.test(url)) {
+    return 'javascript:[filtered]';
+  }
+ 
+  try {
+    const urlObj = new URL(url);
+    const sensitiveParams = [
+      'password', 'passwd', 'pwd',
+      'token', 'access_token', 'refresh_token',
+      'api_key', 'apikey', 'key',
+      'secret', 'private_key',
+      'code', 'auth',
+      'id_token', 'idToken',
+      'session', 'session_id',
+    ];
+ 
+    const params = urlObj.searchParams;
+    let modified = false;
+ 
+    for (const key of Array.from(params.keys())) {
+      const lowerKey = key.toLowerCase().replace(/[-_]/g, '_');
+      if (sensitiveParams.some(s => lowerKey.includes(s))) {
+        params.set(key, '[Filtered]');
+        modified = true;
+      }
+    }
+ 
+    if (urlObj.hash && urlObj.hash.length > 1) {
+      const hashContent = urlObj.hash.substring(1);
+      if (hashContent.includes('=')) {
+        const hashParams = new URLSearchParams(hashContent);
+        let hashModified = false;
+        for (const key of Array.from(hashParams.keys())) {
+          const lowerKey = key.toLowerCase().replace(/[-_]/g, '_');
+          if (sensitiveParams.some(s => lowerKey.includes(s))) {
+            hashParams.set(key, '[Filtered]');
+            hashModified = true;
+          }
+        }
+        if (hashModified) {
+          urlObj.hash = '#' + hashParams.toString();
+          modified = true;
+        }
+      }
+    }
+ 
+    if (modified) {
+      return urlObj.toString();
+    }
+    return url;
+  } catch {
+    return url;
+  }
+}
+ 
+export function shouldIgnoreUrl(url: string, ignoreUrls: (string | RegExp)[] = []): boolean {
+  if (!ignoreUrls || ignoreUrls.length === 0) return false;
+ 
+  return ignoreUrls.some(pattern => {
+    if (typeof pattern === 'string') {
+      if (pattern.includes('*')) {
+        // 移除开头的 ^ 和结尾的 $,允许匹配 URL 的任意部分
+        const escaped = pattern.replace(/[.+?^${}()|[\]\\]/g, '\\$&').replace(/\*/g, '.*');
+        const regex = new RegExp(escaped);
+        return regex.test(url);
+      }
+      return url.includes(pattern);
+    }
+    return pattern.test(url);
+  });
+}
+ 
+const BROWSER_CODE_MAP: Record<string, string> = {
+  'Chrome': 'c',
+  'Safari': 's',
+  'Firefox': 'f',
+  'Edge': 'e',
+  'Opera': 'o',
+  'IE': 'i',
+  'WeChat': 'w',
+  'QQ Browser': 'q',
+  'UC Browser': 'u',
+  'Mobile Chrome': 'cm',
+  'Mobile Safari': 'sm',
+};
+ 
+const OS_CODE_MAP: Record<string, string> = {
+  'Windows 11': 'w11',
+  'Windows 10': 'w10',
+  'Windows 8.1': 'w81',
+  'Windows 8': 'w8',
+  'Windows 7': 'w7',
+  'Windows Vista': 'wv',
+  'Windows XP': 'wxp',
+  'macOS': 'm',
+  'iOS': 'i',
+  'Android': 'a',
+  'Linux': 'l',
+};
+ 
+export function getContexts() {
+  const env = getEnvInfo();
+  const browserCode = BROWSER_CODE_MAP[env.browser.name] || env.browser.name.toLowerCase();
+  const osCode = OS_CODE_MAP[env.os.name] || env.os.name.toLowerCase();
+ 
+  return {
+    browser: {
+      name: browserCode,
+      version: env.browser.major,
+    },
+    os: {
+      name: osCode,
+      version: env.os.version.split('.')[0],
+    },
+    device: {
+      type: env.device.type,
+      brand: env.device.vendor || undefined,
+      model: env.device.model || undefined,
+    },
+  };
+}
+ 
+export function getContextId(): string {
+  const env = getEnvInfo();
+  const key = `${env.browser.name}|${env.browser.major}|${env.os.name}|${env.os.version.split('.')[0]}|${env.device.type}|${env.device.vendor}|${env.device.model}|${env.language}`;
+  return md5(key).substring(0, 16);
+}
+ 
+ +
+
+ + + + + + + + \ No newline at end of file diff --git a/coverage/src/utils/field-encoder.ts.html b/coverage/src/utils/field-encoder.ts.html new file mode 100644 index 0000000..a91d05d --- /dev/null +++ b/coverage/src/utils/field-encoder.ts.html @@ -0,0 +1,349 @@ + + + + + + Code coverage report for src/utils/field-encoder.ts + + + + + + + + + +
+
+

All files / src/utils field-encoder.ts

+
+ +
+ 100% + Statements + 88/88 +
+ + +
+ 100% + Branches + 15/15 +
+ + +
+ 100% + Functions + 2/2 +
+ + +
+ 100% + Lines + 88/88 +
+ + +
+

+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +

+ +
+
+

+
1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +30 +31 +32 +33 +34 +35 +36 +37 +38 +39 +40 +41 +42 +43 +44 +45 +46 +47 +48 +49 +50 +51 +52 +53 +54 +55 +56 +57 +58 +59 +60 +61 +62 +63 +64 +65 +66 +67 +68 +69 +70 +71 +72 +73 +74 +75 +76 +77 +78 +79 +80 +81 +82 +83 +84 +85 +86 +87 +88 +891x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +10x +6x +6x +10x +23x +23x +23x +6x +6x +1x +1x +1x +1x +1x +1x +9x +5x +5x +9x +18x +18x +18x +5x +5x + 
/**
+ * 字段短编码映射
+ * 
+ * 将常用字段名编码为 2-3 个字符的短码,减少上报体积
+ * 
+ * 编码前:{ "type": "error", "level": "error", "message": "..." }
+ * 编码后:{ "t": "e", "l": "e", "m": "..." }
+ * 
+ * 注意:只对最外层高频字段编码,不对嵌套对象深度编码
+ * 避免复杂嵌套带来的解析问题和兼容性风险
+ */
+ 
+// SDK 端:字段名编码映射(只包含最外层高频字段)
+export const FIELD_ENCODE_MAP: Record<string, string> = {
+  // 基础字段
+  event_id: 'eid',
+  timestamp: 'ts',
+  start_timestamp: 'sts',
+  type: 't',
+  level: 'l',
+  message: 'm',
+  platform: 'p',
+  release: 'r',
+  environment: 'e',
+  fingerprint: 'fp',
+  context_id: 'cid',
+ 
+  // 用户
+  user: 'u',
+ 
+  // 标签
+  tags: 'tg',
+ 
+  // 异常
+  exception: 'ex',
+ 
+  // 请求
+  request: 'req',
+ 
+  // 上下文
+  contexts: 'ctx',
+ 
+  // 面包屑
+  breadcrumbs: 'bc',
+ 
+  // Transaction
+  transaction: 'tx',
+  duration: 'd',
+  spans: 'sp',
+ 
+  // 额外信息
+  extra: 'xt',
+};
+ 
+// 服务端:字段名解码映射(反向)
+export const FIELD_DECODE_MAP: Record<string, string> = Object.fromEntries(
+  Object.entries(FIELD_ENCODE_MAP).map(([k, v]) => [v, k])
+);
+ 
+/**
+ * 编码事件字段名(SDK 端使用)
+ * 只对最外层字段编码,避免深度编码的复杂性
+ */
+export function encodeFields(obj: Record<string, unknown>): Record<string, unknown> {
+  if (!obj || typeof obj !== 'object') return obj;
+ 
+  const result: Record<string, unknown> = {};
+  for (const [key, value] of Object.entries(obj)) {
+    const shortKey = FIELD_ENCODE_MAP[key] || key;
+    result[shortKey] = value;
+  }
+  return result;
+}
+ 
+/**
+ * 解码事件字段名(服务端使用)
+ * 只对最外层字段解码
+ */
+export function decodeFields(obj: Record<string, unknown>): Record<string, unknown> {
+  if (!obj || typeof obj !== 'object') return obj;
+ 
+  const result: Record<string, unknown> = {};
+  for (const [key, value] of Object.entries(obj)) {
+    const fullKey = FIELD_DECODE_MAP[key] || key;
+    result[fullKey] = value;
+  }
+  return result;
+}
+ 
+ +
+
+ + + + + + + + \ No newline at end of file diff --git a/coverage/src/utils/hash.ts.html b/coverage/src/utils/hash.ts.html new file mode 100644 index 0000000..9ad3000 --- /dev/null +++ b/coverage/src/utils/hash.ts.html @@ -0,0 +1,145 @@ + + + + + + Code coverage report for src/utils/hash.ts + + + + + + + + + +
+
+

All files / src/utils hash.ts

+
+ +
+ 100% + Statements + 20/20 +
+ + +
+ 83.33% + Branches + 5/6 +
+ + +
+ 100% + Functions + 3/3 +
+ + +
+ 100% + Lines + 20/20 +
+ + +
+

+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +

+ +
+
+

+
1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +211x +19x +19x +19x +288x +288x +19x +19x +1x +1x +14x +14x +14x +14x +1x +1x +5x +5x +5x +5x + 
export function hashString(str: string): number {
+  let hash = 5381;
+  let i = str.length;
+  while (i) {
+    hash = (hash * 33) ^ str.charCodeAt(--i);
+  }
+  return hash >>> 0;
+}
+ 
+export function md5(str: string): string {
+  // 使用 hashString 替代不安全的 md5
+  // 用于非加密场景(ID生成、指纹计算)
+  return hashString(str).toString(16);
+}
+ 
+export function computeFingerprint(type: string, message: string, frames: { filename: string; lineno?: number }[] = []): string {
+  const keyFrames = frames.slice(0, 3).map(f => `${f.filename}:${f.lineno || 0}`).join('|');
+  const normalizedMessage = message.replace(/['"]?\d+['"]?/g, '').replace(/\s+/g, ' ').trim();
+  return md5(`${type}:${normalizedMessage}:${keyFrames}`);
+}
+ 
+ +
+
+ + + + + + + + \ No newline at end of file diff --git a/coverage/src/utils/helper.ts.html b/coverage/src/utils/helper.ts.html new file mode 100644 index 0000000..198a988 --- /dev/null +++ b/coverage/src/utils/helper.ts.html @@ -0,0 +1,241 @@ + + + + + + Code coverage report for src/utils/helper.ts + + + + + + + + + +
+
+

All files / src/utils helper.ts

+
+ +
+ 96.15% + Statements + 50/52 +
+ + +
+ 95.83% + Branches + 23/24 +
+ + +
+ 100% + Functions + 9/9 +
+ + +
+ 96.15% + Lines + 50/52 +
+ + +
+

+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +

+ +
+
+

+
1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +30 +31 +32 +33 +34 +35 +36 +37 +38 +39 +40 +41 +42 +43 +44 +45 +46 +47 +48 +49 +50 +51 +52 +531x +3x +96x +3x +3x +1x +1x +293x +293x +1x +1x +190x +190x +190x +  +  +1x +1x +9x +9x +1x +1x +8x +8x +1x +1x +38x +38x +1x +1x +7x +7x +7x +7x +1x +1x +7x +1x +1x +5x +1x +1x +1x +1x +15x +13x +18x +11x +11x +7x +13x +13x + 
export function generateEventId(): string {
+  return 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'.replace(/[x]/g, () => {
+    return ((Math.random() * 16) | 0).toString(16);
+  });
+}
+ 
+export function now(): number {
+  return Date.now();
+}
+ 
+export function uuid(): string {
+  if (typeof crypto !== 'undefined' && crypto.randomUUID) {
+    return crypto.randomUUID().replace(/-/g, '');
+  }
+  return generateEventId();
+}
+ 
+export function isFunction(fn: unknown): fn is (...args: unknown[]) => unknown {
+  return typeof fn === 'function';
+}
+ 
+export function isString(value: unknown): value is string {
+  return typeof value === 'string';
+}
+ 
+export function isObject(value: unknown): value is Record<string, unknown> {
+  return value !== null && typeof value === 'object' && !Array.isArray(value);
+}
+ 
+export function safeGet<T>(fn: () => T, defaultValue: T): T {
+  try {
+    const result = fn();
+    return result === undefined ? defaultValue : result;
+  } catch {
+    return defaultValue;
+  }
+}
+ 
+export function truncate(str: string, maxLen: number): string {
+  if (str.length <= maxLen) return str;
+  return str.slice(0, maxLen) + '...';
+}
+ 
+export function matchPatterns(value: string, patterns: (string | RegExp)[]): boolean {
+  if (!patterns || patterns.length === 0) return false;
+  return patterns.some(pattern => {
+    if (typeof pattern === 'string') {
+      return value.includes(pattern);
+    }
+    return pattern.test(value);
+  });
+}
+ 
+ +
+
+ + + + + + + + \ No newline at end of file diff --git a/coverage/src/utils/identity.ts.html b/coverage/src/utils/identity.ts.html new file mode 100644 index 0000000..279dcec --- /dev/null +++ b/coverage/src/utils/identity.ts.html @@ -0,0 +1,295 @@ + + + + + + Code coverage report for src/utils/identity.ts + + + + + + + + + +
+
+

All files / src/utils identity.ts

+
+ +
+ 100% + Statements + 70/70 +
+ + +
+ 100% + Branches + 15/15 +
+ + +
+ 100% + Functions + 4/4 +
+ + +
+ 100% + Lines + 70/70 +
+ + +
+

+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +

+ +
+
+

+
1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +30 +31 +32 +33 +34 +35 +36 +37 +38 +39 +40 +41 +42 +43 +44 +45 +46 +47 +48 +49 +50 +51 +52 +53 +54 +55 +56 +57 +58 +59 +60 +61 +62 +63 +64 +65 +66 +67 +68 +69 +70 +711x +1x +1x +1x +1x +1x +1x +1x +1x +20x +20x +1x +1x +19x +19x +19x +19x +20x +8x +8x +8x +18x +18x +20x +1x +1x +1x +20x +1x +1x +1x +1x +1x +1x +6x +1x +1x +5x +5x +5x +5x +6x +1x +1x +6x +1x +1x +1x +1x +1x +1x +5x +1x +1x +4x +4x +4x +4x +5x +1x +1x +5x +1x +1x +1x +1x +1x +16x +16x +16x + 
import { uuid } from './helper';
+ 
+const ANONYMOUS_ID_KEY = 'light_sentry_aid';
+ 
+/**
+ * 获取匿名用户ID
+ * 优先从 localStorage 获取已存在的ID,不存在则生成并存储
+ */
+export function getAnonymousId(): string | null {
+  // 浏览器环境检查
+  if (typeof localStorage === 'undefined') {
+    return null;
+  }
+ 
+  try {
+    let anonymousId = localStorage.getItem(ANONYMOUS_ID_KEY);
+ 
+    if (!anonymousId) {
+      anonymousId = uuid();
+      localStorage.setItem(ANONYMOUS_ID_KEY, anonymousId);
+    }
+ 
+    return anonymousId;
+  } catch {
+    // localStorage 不可用(如隐私模式、跨域限制等)
+    return null;
+  }
+}
+ 
+/**
+ * 设置匿名用户ID
+ * 用于覆盖自动生成的ID
+ */
+export function setAnonymousId(id: string): boolean {
+  if (typeof localStorage === 'undefined') {
+    return false;
+  }
+ 
+  try {
+    localStorage.setItem(ANONYMOUS_ID_KEY, id);
+    return true;
+  } catch {
+    return false;
+  }
+}
+ 
+/**
+ * 清除匿名用户ID
+ * 通常在用户登出后调用
+ */
+export function clearAnonymousId(): boolean {
+  if (typeof localStorage === 'undefined') {
+    return false;
+  }
+ 
+  try {
+    localStorage.removeItem(ANONYMOUS_ID_KEY);
+    return true;
+  } catch {
+    return false;
+  }
+}
+ 
+/**
+ * 检查是否启用了匿名用户追踪
+ */
+export function isAnonymousTrackingEnabled(config: { trackAnonymousUsers?: boolean }): boolean {
+  // 默认为 true,除非明确设置为 false
+  return config.trackAnonymousUsers !== false;
+}
+ 
+ +
+
+ + + + + + + + \ No newline at end of file diff --git a/coverage/src/utils/index.html b/coverage/src/utils/index.html new file mode 100644 index 0000000..f469c8a --- /dev/null +++ b/coverage/src/utils/index.html @@ -0,0 +1,251 @@ + + + + + + Code coverage report for src/utils + + + + + + + + + +
+
+

All files src/utils

+
+ +
+ 97.36% + Statements + 1108/1138 +
+ + +
+ 87.87% + Branches + 319/363 +
+ + +
+ 96.92% + Functions + 63/65 +
+ + +
+ 97.36% + Lines + 1108/1138 +
+ + +
+

+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +

+ +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FileStatementsBranchesFunctionsLines
baggage.ts +
+
97.97%97/9997.14%34/35100%3/397.97%97/99
dsn.ts +
+
93.1%27/29100%5/566.66%2/393.1%27/29
env.ts +
+
100%293/29378.87%56/71100%10/10100%293/293
field-encoder.ts +
+
100%88/88100%15/15100%2/2100%88/88
hash.ts +
+
100%20/2083.33%5/6100%3/3100%20/20
helper.ts +
+
96.15%50/5295.83%23/24100%9/996.15%50/52
identity.ts +
+
100%70/70100%15/15100%4/4100%70/70
logger.ts +
+
100%31/31100%13/13100%4/4100%31/31
stacktrace.ts +
+
98%98/10093.02%40/43100%1/198%98/100
tracing.ts +
+
93.82%334/35683.08%113/13696.15%25/2693.82%334/356
+
+
+
+ + + + + + + + \ No newline at end of file diff --git a/coverage/src/utils/logger.ts.html b/coverage/src/utils/logger.ts.html new file mode 100644 index 0000000..73a7596 --- /dev/null +++ b/coverage/src/utils/logger.ts.html @@ -0,0 +1,178 @@ + + + + + + Code coverage report for src/utils/logger.ts + + + + + + + + + +
+
+

All files / src/utils logger.ts

+
+ +
+ 100% + Statements + 31/31 +
+ + +
+ 100% + Branches + 13/13 +
+ + +
+ 100% + Functions + 4/4 +
+ + +
+ 100% + Lines + 31/31 +
+ + +
+

+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +

+ +
+
+

+
1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +30 +31 +321x +1x +1x +42x +42x +1x +1x +6x +6x +1x +1x +289x +8x +8x +10x +3x +10x +5x +5x +289x +1x +1x +10x +8x +8x +10x +3x +10x +5x +5x +10x + 
let debugEnabled = false;
+ 
+export function setDebug(enabled: boolean): void {
+  debugEnabled = enabled;
+}
+ 
+export function isDebugEnabled(): boolean {
+  return debugEnabled;
+}
+ 
+export function logDebug(tag: string, message: string, data?: unknown): void {
+  if (!debugEnabled) return;
+  const timestamp = new Date().toISOString();
+  const prefix = `[LightSDK][${tag}]`;
+  if (data !== undefined) {
+    console.log(`${prefix} ${timestamp} ${message}`, data);
+  } else {
+    console.log(`${prefix} ${timestamp} ${message}`);
+  }
+}
+ 
+export function logError(tag: string, message: string, error?: unknown): void {
+  if (!debugEnabled) return;
+  const timestamp = new Date().toISOString();
+  const prefix = `[LightSDK][${tag}][ERROR]`;
+  if (error !== undefined) {
+    console.error(`${prefix} ${timestamp} ${message}`, error);
+  } else {
+    console.error(`${prefix} ${timestamp} ${message}`);
+  }
+}
+ 
+ +
+
+ + + + + + + + \ No newline at end of file diff --git a/coverage/src/utils/stacktrace.ts.html b/coverage/src/utils/stacktrace.ts.html new file mode 100644 index 0000000..a40d8bc --- /dev/null +++ b/coverage/src/utils/stacktrace.ts.html @@ -0,0 +1,385 @@ + + + + + + Code coverage report for src/utils/stacktrace.ts + + + + + + + + + +
+
+

All files / src/utils stacktrace.ts

+
+ +
+ 98% + Statements + 98/100 +
+ + +
+ 93.02% + Branches + 40/43 +
+ + +
+ 100% + Functions + 1/1 +
+ + +
+ 98% + Lines + 98/100 +
+ + +
+

+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +

+ +
+
+

+
1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +30 +31 +32 +33 +34 +35 +36 +37 +38 +39 +40 +41 +42 +43 +44 +45 +46 +47 +48 +49 +50 +51 +52 +53 +54 +55 +56 +57 +58 +59 +60 +61 +62 +63 +64 +65 +66 +67 +68 +69 +70 +71 +72 +73 +74 +75 +76 +77 +78 +79 +80 +81 +82 +83 +84 +85 +86 +87 +88 +89 +90 +91 +92 +93 +94 +95 +96 +97 +98 +99 +100 +1011x +1x +1x +1x +1x +1x +1x +1x +1x +1x +26x +24x +24x +24x +24x +24x +24x +24x +24x +24x +24x +26x +26x +26x +73x +73x +28x +28x +28x +28x +2x +2x +26x +26x +28x +  +  +26x +26x +26x +26x +26x +28x +28x +28x +73x +45x +45x +11x +11x +11x +11x +1x +1x +10x +10x +11x +2x +2x +10x +10x +10x +11x +11x +11x +11x +11x +11x +11x +34x +34x +45x +10x +10x +10x +10x +1x +1x +9x +9x +10x +2x +2x +9x +9x +9x +9x +10x +10x +10x +10x +45x +73x +24x +24x +26x +1x +1x +23x +23x + 
import type { StackFrame } from '../types';
+ 
+export interface ParseStackOptions {
+  captureNodeModules?: boolean;
+  captureColumn?: boolean;
+  relativePathOnly?: boolean;
+  maxFrames?: number;
+}
+ 
+export function parseStackTrace(stack?: string, options: ParseStackOptions = {}): StackFrame[] {
+  if (!stack) return [];
+ 
+  const {
+    captureNodeModules = false,
+    captureColumn = true,
+    relativePathOnly = false,
+    maxFrames,
+  } = options;
+ 
+  const frames: StackFrame[] = [];
+  const lines = stack.split('\n');
+  const origin = typeof location !== 'undefined' ? `${location.protocol}//${location.host}` : '';
+ 
+  for (const line of lines) {
+    const match = line.match(/^\s*at\s*(.+?)\s*\((.+?):(\d+):(\d+)\)\s*$/);
+    if (match) {
+      const [, fn, filename, lineNum, colNum] = match;
+      
+      const isNodeModules = filename.includes('node_modules');
+      if (!captureNodeModules && isNodeModules) {
+        continue;
+      }
+ 
+      let finalFilename = filename;
+      if (relativePathOnly && origin && filename.startsWith(origin)) {
+        finalFilename = filename.substring(origin.length);
+      }
+ 
+      frames.push({
+        filename: finalFilename,
+        function: fn,
+        lineno: parseInt(lineNum, 10),
+        colno: captureColumn ? parseInt(colNum, 10) : undefined,
+        in_app: !isNodeModules,
+      });
+    } else {
+      const v8Match = line.match(/^\s*at\s*(.+?)@(.+?):(\d+):(\d+)\s*$/);
+    if (v8Match) {
+      const [, fn, filename, lineNum, colNum] = v8Match;
+      
+      const isNodeModules = filename.includes('node_modules');
+      if (!captureNodeModules && isNodeModules) {
+        continue;
+      }
+ 
+      let finalFilename = filename;
+      if (relativePathOnly && origin && filename.startsWith(origin)) {
+        finalFilename = filename.substring(origin.length);
+      }
+ 
+      frames.push({
+        filename: finalFilename,
+        function: fn || '<anonymous>',
+        lineno: parseInt(lineNum, 10),
+        colno: captureColumn ? parseInt(colNum, 10) : undefined,
+        in_app: !isNodeModules,
+      });
+      continue;
+    }
+ 
+    const urlMatch = line.match(/^\s*at\s*(.+?):(\d+):(\d+)\s*$/);
+    if (urlMatch) {
+      const [, filename, lineNum, colNum] = urlMatch;
+        
+        const isNodeModules = filename.includes('node_modules');
+        if (!captureNodeModules && isNodeModules) {
+          continue;
+        }
+ 
+        let finalFilename = filename;
+        if (relativePathOnly && origin && filename.startsWith(origin)) {
+          finalFilename = filename.substring(origin.length);
+        }
+ 
+        frames.push({
+          filename: finalFilename,
+          lineno: parseInt(lineNum, 10),
+          colno: captureColumn ? parseInt(colNum, 10) : undefined,
+          in_app: !isNodeModules,
+        });
+      }
+    }
+  }
+ 
+  const reversed = frames.reverse();
+  if (maxFrames !== undefined && maxFrames > 0) {
+    return reversed.slice(0, maxFrames);
+  }
+  return reversed;
+}
+ 
+ +
+
+ + + + + + + + \ No newline at end of file diff --git a/coverage/src/utils/tracing.ts.html b/coverage/src/utils/tracing.ts.html new file mode 100644 index 0000000..6b993e3 --- /dev/null +++ b/coverage/src/utils/tracing.ts.html @@ -0,0 +1,1153 @@ + + + + + + Code coverage report for src/utils/tracing.ts + + + + + + + + + +
+
+

All files / src/utils tracing.ts

+
+ +
+ 93.82% + Statements + 334/356 +
+ + +
+ 83.08% + Branches + 113/136 +
+ + +
+ 96.15% + Functions + 25/26 +
+ + +
+ 93.82% + Lines + 334/356 +
+ + +
+

+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +

+ +
+
+

+
1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +30 +31 +32 +33 +34 +35 +36 +37 +38 +39 +40 +41 +42 +43 +44 +45 +46 +47 +48 +49 +50 +51 +52 +53 +54 +55 +56 +57 +58 +59 +60 +61 +62 +63 +64 +65 +66 +67 +68 +69 +70 +71 +72 +73 +74 +75 +76 +77 +78 +79 +80 +81 +82 +83 +84 +85 +86 +87 +88 +89 +90 +91 +92 +93 +94 +95 +96 +97 +98 +99 +100 +101 +102 +103 +104 +105 +106 +107 +108 +109 +110 +111 +112 +113 +114 +115 +116 +117 +118 +119 +120 +121 +122 +123 +124 +125 +126 +127 +128 +129 +130 +131 +132 +133 +134 +135 +136 +137 +138 +139 +140 +141 +142 +143 +144 +145 +146 +147 +148 +149 +150 +151 +152 +153 +154 +155 +156 +157 +158 +159 +160 +161 +162 +163 +164 +165 +166 +167 +168 +169 +170 +171 +172 +173 +174 +175 +176 +177 +178 +179 +180 +181 +182 +183 +184 +185 +186 +187 +188 +189 +190 +191 +192 +193 +194 +195 +196 +197 +198 +199 +200 +201 +202 +203 +204 +205 +206 +207 +208 +209 +210 +211 +212 +213 +214 +215 +216 +217 +218 +219 +220 +221 +222 +223 +224 +225 +226 +227 +228 +229 +230 +231 +232 +233 +234 +235 +236 +237 +238 +239 +240 +241 +242 +243 +244 +245 +246 +247 +248 +249 +250 +251 +252 +253 +254 +255 +256 +257 +258 +259 +260 +261 +262 +263 +264 +265 +266 +267 +268 +269 +270 +271 +272 +273 +274 +275 +276 +277 +278 +279 +280 +281 +282 +283 +284 +285 +286 +287 +288 +289 +290 +291 +292 +293 +294 +295 +296 +297 +298 +299 +300 +301 +302 +303 +304 +305 +306 +307 +308 +309 +310 +311 +312 +313 +314 +315 +316 +317 +318 +319 +320 +321 +322 +323 +324 +325 +326 +327 +328 +329 +330 +331 +332 +333 +334 +335 +336 +337 +338 +339 +340 +341 +342 +343 +344 +345 +346 +347 +348 +349 +350 +351 +352 +353 +354 +355 +356 +3571x +1x +1x +1x +81x +81x +81x +1x +98x +98x +98x +1x +1x +21x +21x +21x +21x +21x +21x +21x +21x +21x +  +  +1x +1x +17x +3x +3x +14x +17x +17x +17x +17x +17x +17x +2x +  +  +  +1x +1x +13x +13x +13x +13x +12x +13x +6x +6x +6x +6x +6x +6x +6x +6x +6x +6x +6x +6x +1x +1x +6x +  +  +1x +1x +6x +6x +6x +4x +4x +2x +6x +2x +2x +  +  +  +6x +  +  +  +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +99x +99x +99x +99x +99x +99x +99x +99x +99x +99x +99x +99x +1x +1x +11x +11x +11x +1x +1x +4x +4x +4x +1x +1x +28x +28x +28x +1x +1x +4x +4x +4x +4x +1x +1x +4x +4x +4x +1x +1x +4x +4x +1x +1x +16x +16x +16x +16x +16x +16x +16x +16x +16x +16x +16x +16x +16x +16x +13x +13x +16x +16x +16x +1x +1x +22x +21x +22x +22x +22x +17x +17x +  +  +17x +22x +1x +1x +3x +3x +3x +2x +1x +3x +1x +1x +31x +31x +31x +31x +31x +31x +31x +31x +31x +31x +31x +31x +31x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +42x +42x +42x +42x +42x +42x +42x +42x +42x +2x +2x +42x +1x +1x +13x +1x +1x +1x +12x +13x +1x +1x +13x +7x +7x +7x +7x +7x +7x +7x +7x +7x +7x +13x +13x +1x +1x +1x +1x +1x +1x +1x +1x +5x +5x +4x +5x +1x +1x +5x +2x +5x +3x +3x +5x +5x +1x +1x +7x +7x +7x +1x +1x +  +  +1x +1x +17x +17x +17x +17x +13x +13x +13x +17x +17x +17x +17x +  +  +17x +17x +1x +1x +14x +14x +  +14x +  +14x +  +14x +14x +14x +14x +1x +1x +14x +14x +14x +14x +14x +14x +14x +14x +14x +14x +14x +14x +14x +14x +14x +14x +14x +14x +14x +14x +14x +14x +14x +14x +14x +14x +14x +14x +14x +14x +1x +1x +15x +15x +15x +15x +15x +15x +15x +15x +15x +1x +1x +1x + 
import type { Span as SpanInterface, SpanContext, Transaction as TransactionInterface, TransactionContext, SpanStatus, LightClient, BaggageFields } from '../types';
+import { uuid, now } from './helper';
+import { createBaggageFromTransaction, serializeBaggage } from './baggage';
+ 
+function generateTraceId(): string {
+  return uuid().replace(/-/g, '');
+}
+ 
+function generateSpanId(): string {
+  return uuid().replace(/-/g, '').substring(0, 16);
+}
+ 
+export function httpStatusToSpanStatus(statusCode: number): SpanStatus {
+  if (statusCode >= 200 && statusCode < 300) return 'ok';
+  if (statusCode === 400) return 'invalid_argument';
+  if (statusCode === 401) return 'unauthenticated';
+  if (statusCode === 403) return 'permission_denied';
+  if (statusCode === 404) return 'not_found';
+  if (statusCode === 409) return 'already_exists';
+  if (statusCode === 429) return 'resource_exhausted';
+  if (statusCode >= 400 && statusCode < 500) return 'invalid_argument';
+  if (statusCode >= 500 && statusCode < 600) return 'internal_error';
+  return 'unknown_error';
+}
+ 
+export function dbStatusToSpanStatus(dbStatusCode?: string | number): SpanStatus {
+  if (dbStatusCode === undefined || dbStatusCode === null || dbStatusCode === '') {
+    return 'unknown_error';
+  }
+ 
+  const code = typeof dbStatusCode === 'string' ? parseInt(dbStatusCode, 10) : dbStatusCode;
+ 
+  if (code === 0 || code === 1) return 'ok';
+  if (code >= 10 && code < 20) return 'invalid_argument';
+  if (code >= 20 && code < 30) return 'not_found';
+  if (code >= 30 && code < 40) return 'already_exists';
+  if (code >= 50) return 'internal_error';
+
+  return 'unknown_error';
+}
+ 
+export function statusToSpanStatus(
+  status: string | number | undefined,
+  op: string | undefined
+): SpanStatus {
+  if (status === undefined) return 'unknown_error';
+ 
+  if (typeof status === 'string') {
+    const lowerStatus = status.toLowerCase();
+    if (lowerStatus === 'ok' || lowerStatus === 'success') return 'ok';
+    if (lowerStatus === 'cancelled' || lowerStatus === 'canceled') return 'cancelled';
+    if (lowerStatus === 'deadline_exceeded') return 'deadline_exceeded';
+    if (lowerStatus === 'not_found') return 'not_found';
+    if (lowerStatus === 'already_exists') return 'already_exists';
+    if (lowerStatus === 'permission_denied') return 'permission_denied';
+    if (lowerStatus === 'resource_exhausted') return 'resource_exhausted';
+    if (lowerStatus === 'failed_precondition') return 'failed_precondition';
+    if (lowerStatus === 'invalid_argument') return 'invalid_argument';
+    if (lowerStatus === 'unauthenticated') return 'unauthenticated';
+    if (lowerStatus === 'internal_error') return 'internal_error';
+ 
+    const parsed = parseInt(status, 10);
+    if (!isNaN(parsed)) {
+      return statusToSpanStatus(parsed, op);
+    }
+    return 'unknown_error';
+  }
+ 
+  if (typeof status === 'number') {
+    if (status >= 200 && status < 600) {
+      return httpStatusToSpanStatus(status);
+    }
+ 
+    if (op?.startsWith('db')) {
+      return dbStatusToSpanStatus(status);
+    }
+
+    if (status === 0) return 'ok';
+    if (status > 0) return 'unknown_error';
+  }
+
+  return 'unknown_error';
+}
+ 
+export class Span implements SpanInterface {
+  readonly traceId: string;
+  readonly spanId: string;
+  readonly parentSpanId?: string;
+  op?: string;
+  description?: string;
+  status?: SpanStatus;
+  tags: Record<string, string> = {};
+  data: Record<string, unknown> = {};
+  readonly startTimestamp: number;
+  endTimestamp?: number;
+  transaction?: TransactionInterface;
+ 
+  protected _isFinished = false;
+  protected _client?: LightClient;
+ 
+  constructor(context: SpanContext, transaction?: TransactionInterface, client?: LightClient) {
+    this.traceId = context.traceId || generateTraceId();
+    this.spanId = context.spanId || generateSpanId();
+    this.parentSpanId = context.parentSpanId;
+    this.op = context.op;
+    this.description = context.description;
+    this.status = context.status;
+    this.tags = { ...context.tags };
+    this.data = { ...context.data };
+    this.startTimestamp = context.startTimestamp || now();
+    this.transaction = transaction;
+    this._client = client;
+  }
+ 
+  setTag(key: string, value: string): this {
+    this.tags[key] = value;
+    return this;
+  }
+ 
+  setData(key: string, value: unknown): this {
+    this.data[key] = value;
+    return this;
+  }
+ 
+  setStatus(status: SpanStatus): this {
+    this.status = status;
+    return this;
+  }
+ 
+  setHttpStatus(statusCode: number): this {
+    this.setStatus(httpStatusToSpanStatus(statusCode));
+    this.setTag('http.status_code', String(statusCode));
+    return this;
+  }
+ 
+  setStatusFromResponse(status: string | number | undefined, tagKey?: string): this {
+    const spanStatus = statusToSpanStatus(status, this.op);
+    this.setStatus(spanStatus);
+    if (tagKey && status !== undefined) {
+      this.setTag(tagKey, String(status));
+    }
+    return this;
+  }
+ 
+  startChild(context: SpanContext = {}): Span {
+    const tx = this.transaction;
+    const isSampled = tx?.sampled !== false;
+ 
+    const child = new Span(
+      {
+        ...context,
+        traceId: this.traceId,
+        parentSpanId: this.spanId,
+      },
+      tx,
+      this._client
+    );
+ 
+    if (tx && isSampled) {
+      (tx as Transaction)._addSpan(child);
+    }
+ 
+    return child;
+  }
+ 
+  finish(endTimestamp?: number): void {
+    if (this._isFinished) return;
+    this._isFinished = true;
+    this.endTimestamp = endTimestamp || now();
+ 
+    if (this._client) {
+      const clientInternal = this._client as unknown as { tracingManager?: { onSpanFinished: (span: Span) => void } };
+      if (clientInternal.tracingManager?.onSpanFinished) {
+        clientInternal.tracingManager.onSpanFinished(this);
+      }
+    }
+  }
+ 
+  toTraceparent(): string {
+    const sampled = this.transaction?.sampled;
+    const sampledFlag = sampled === undefined ? '' : sampled ? '1' : '0';
+    return sampledFlag
+      ? `${this.traceId}-${this.spanId}-${sampledFlag}`
+      : `${this.traceId}-${this.spanId}`;
+  }
+ 
+  toJSON() {
+    return {
+      trace_id: this.traceId,
+      span_id: this.spanId,
+      parent_span_id: this.parentSpanId,
+      op: this.op,
+      description: this.description,
+      status: this.status,
+      tags: Object.keys(this.tags).length > 0 ? { ...this.tags } : undefined,
+      data: Object.keys(this.data).length > 0 ? { ...this.data } : undefined,
+      start_timestamp: this.startTimestamp,
+      timestamp: this.endTimestamp || this.startTimestamp,
+    };
+  }
+}
+ 
+export class Transaction extends Span implements TransactionInterface {
+  name: string;
+  type?: string;
+  spans: Span[] = [];
+  sampled?: boolean;
+  maxSpans: number = 1000;
+  private _baggage?: BaggageFields;
+  private _dsnPublicKey?: string;
+  private _release?: string;
+  private _environment?: string;
+  private _droppedSpans: number = 0;
+ 
+  constructor(context: TransactionContext, client?: LightClient, dsnPublicKey?: string, release?: string, environment?: string, maxSpans?: number) {
+    super(context, undefined, client);
+    this.name = context.name;
+    this.type = context.type;
+    this.sampled = context.sampled;
+    this.transaction = this;
+    this._dsnPublicKey = dsnPublicKey;
+    this._release = release;
+    this._environment = environment;
+    if (maxSpans !== undefined) {
+      this.maxSpans = maxSpans;
+    }
+  }
+ 
+  _addSpan(span: Span): void {
+    if (this.spans.length >= this.maxSpans) {
+      this._droppedSpans++;
+      return;
+    }
+    this.spans.push(span);
+  }
+ 
+  private _ensureBaggage(): BaggageFields {
+    if (!this._baggage) {
+      this._baggage = createBaggageFromTransaction(
+        this.traceId,
+        {
+          dsnPublicKey: this._dsnPublicKey,
+          sampled: this.sampled,
+          release: this._release,
+          environment: this._environment,
+        }
+      );
+    }
+    return this._baggage;
+  }
+ 
+  setBaggage(key: string, value: string): this {
+    const baggage = this._ensureBaggage();
+    baggage[key] = value;
+    return this;
+  }
+ 
+  setUserBaggage(userId?: string, segment?: string): this {
+    const baggage = this._ensureBaggage();
+    if (userId !== undefined) {
+      baggage.user_id = userId;
+    } else {
+      delete baggage.user_id;
+    }
+    if (segment !== undefined) {
+      baggage.user_segment = segment;
+    } else {
+      delete baggage.user_segment;
+    }
+    return this;
+  }
+ 
+  toBaggage(): string | undefined {
+    const baggage = this._ensureBaggage();
+    return serializeBaggage(baggage);
+  }
+ 
+  getBaggage(): BaggageFields | undefined {
+    return this._baggage;
+  }
+ 
+  finish(endTimestamp?: number): void {
+    if (this._isFinished) return;
+    super.finish(endTimestamp);
+ 
+    if (this._client && this.sampled) {
+      const event = this.toEvent();
+      this._client.captureEvent(event);
+    }
+ 
+    if (this._client) {
+      const clientInternal = this._client as unknown as { tracingManager?: { onTransactionFinished: (tx: Transaction) => void } };
+      if (clientInternal.tracingManager?.onTransactionFinished) {
+        clientInternal.tracingManager.onTransactionFinished(this);
+      }
+    }
+  }
+ 
+  private _getSource(): string {
+    switch (this.type) {
+      case 'pageload':
+        return 'url';
+      case 'navigation':
+        return 'route';
+      case 'user-interaction':
+        return 'ui';
+      default:
+        return 'custom';
+    }
+  }
+ 
+  toEvent() {
+    const json = this.toJSON();
+    const data = { ...json.data } as Record<string, unknown>;
+    const measurements = data.measurements as Record<string, { value: number; unit?: string; rating?: 'good' | 'needs-improvement' | 'poor' }> | undefined;
+    delete data.measurements;
+ 
+    return {
+      type: 'transaction' as const,
+      transaction: this.name,
+      transaction_info: {
+        source: this._getSource(),
+      },
+      level: 'info' as const,
+      timestamp: json.timestamp,
+      start_timestamp: json.start_timestamp,
+      spans: this.spans.map((s) => s.toJSON()),
+      contexts: {
+        trace: {
+          trace_id: this.traceId,
+          span_id: this.spanId,
+          parent_span_id: this.parentSpanId,
+          op: this.op,
+          status: this.status,
+        },
+      },
+      tags: json.tags,
+      extra: Object.keys(data).length > 0 ? data : undefined,
+      measurements,
+      platform: 'javascript',
+    };
+  }
+ 
+  toJSON() {
+    const base = super.toJSON();
+    return {
+      ...base,
+      transaction: this.name,
+      type: this.type,
+      spans: this.spans.map((s) => s.toJSON()),
+      sampled: this.sampled,
+    };
+  }
+}
+ 
+export { generateTraceId, generateSpanId };
+ 
+ +
+
+ + + + + + + + \ No newline at end of file diff --git a/dist/core/Client.d.ts b/dist/core/Client.d.ts index 35f9bd3..40f0350 100644 --- a/dist/core/Client.d.ts +++ b/dist/core/Client.d.ts @@ -1,4 +1,4 @@ -import type { LightConfig, LightClient, LightPlugin, DSNInfo, SentryEvent, EventLevel, UserInfo, Breadcrumb } from '../types'; +import type { LightConfig, LightClient, LightPlugin, DSNInfo, SentryEvent, EventLevel, UserInfo, Breadcrumb, TransactionContext, SpanContext, Transaction, Span } from '../types'; declare class Client implements LightClient { dsn: DSNInfo; private configManager; @@ -6,6 +6,7 @@ declare class Client implements LightClient { private queue; private reporter; private pluginManager; + private tracingManager; private breadcrumbs; private enabled; private get maxBreadcrumbs(); @@ -22,8 +23,15 @@ declare class Client implements LightClient { captureEvent(event: Partial & { type: string; }): void; + private attachTraceContext; private buildErrorEvent; setUser(user: UserInfo | null): void; + setAnonymousId(id: string): void; + startTransaction(context: TransactionContext): Transaction | null; + getCurrentTransaction(): Transaction | null; + getCurrentSpan(): Span | null; + setSpan(span: Span | null): void; + startSpan(context: SpanContext): Span | null; setTag(key: string, value: string): void; setTags(tags: Record): void; setExtra(key: string, value: unknown): void; diff --git a/dist/core/ConfigManager.d.ts b/dist/core/ConfigManager.d.ts index eac58d8..459c093 100644 --- a/dist/core/ConfigManager.d.ts +++ b/dist/core/ConfigManager.d.ts @@ -14,6 +14,7 @@ export declare class ConfigManager { setTag(key: string, value: string): void; setExtra(key: string, value: unknown): void; isIgnoredError(message: string): boolean; + shouldSample(): boolean; /** * 获取编码后的环境信息(延迟初始化,只在首次上报时计算) * 注意:env.ts 的 getContexts 已经返回编码后的数据 diff --git a/dist/core/TracingManager.d.ts b/dist/core/TracingManager.d.ts new file mode 100644 index 0000000..faa34e6 --- /dev/null +++ b/dist/core/TracingManager.d.ts @@ -0,0 +1,22 @@ +import type { LightConfig, SpanContext, TransactionContext, Span, Transaction, LightClient } from '../types'; +export declare class TracingManager { + private config; + private _client?; + private currentTransaction; + private spanStack; + private dsnPublicKey?; + constructor(config: LightConfig, client?: LightClient, dsnPublicKey?: string); + updateConfig(config: LightConfig): void; + private shouldSample; + startTransaction(context: TransactionContext): Transaction | null; + getCurrentTransaction(): Transaction | null; + setCurrentTransaction(transaction: Transaction | null): void; + getCurrentSpan(): Span | null; + setCurrentSpan(span: Span | null): void; + startSpan(context: SpanContext): Span | null; + onSpanFinished(span: Span): void; + onTransactionFinished(transaction: Transaction): void; + finishSpan(span: Span): void; + finishTransaction(transaction: Transaction): void; + destroy(): void; +} diff --git a/dist/index.cjs.js b/dist/index.cjs.js index 3a175d4..95b3260 100644 --- a/dist/index.cjs.js +++ b/dist/index.cjs.js @@ -1,3 +1,3 @@ -"use strict";var q=Object.defineProperty;var Re=Object.getOwnPropertyDescriptor;var ke=Object.getOwnPropertyNames;var Ce=Object.prototype.hasOwnProperty;var Le=(s,e)=>{for(var t in e)q(s,t,{get:e[t],enumerable:!0})},Te=(s,e,t,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let r of ke(e))!Ce.call(s,r)&&r!==t&&q(s,r,{get:()=>e[r],enumerable:!(n=Re(e,r))||n.enumerable});return s};var Pe=s=>Te(q({},"__esModule",{value:!0}),s);var Ue={};Le(Ue,{BehaviorPlugin:()=>J,Client:()=>j,ErrorPlugin:()=>X,NetworkPlugin:()=>Q,OfflinePlugin:()=>ee,PerformancePlugin:()=>z,SamplingPlugin:()=>ne,addBreadcrumb:()=>Ee,captureEvent:()=>ge,captureException:()=>he,captureMessage:()=>fe,default:()=>Ne,disable:()=>Se,enable:()=>xe,flush:()=>we,getClient:()=>pe,init:()=>de,setExtra:()=>be,setTag:()=>ve,setTags:()=>ye,setUser:()=>me});module.exports=Pe(Ue);function ie(s){try{let e=s.match(/^(https?):\/\/([^@]+)@([^/]+)\/(.+)$/);if(!e)throw new Error("Invalid DSN format");let[,t,n,r,i]=e;return{protocol:t,publicKey:n,host:r,projectId:i}}catch(e){throw new Error(`Failed to parse DSN: ${e.message}`)}}function C(s){return`${s.protocol}://${s.host}/api/${s.projectId}/envelope/?sentry_key=${s.publicKey}`}function se(){return"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx".replace(/[x]/g,()=>(Math.random()*16|0).toString(16))}function p(){return Date.now()}function b(s){return s!==null&&typeof s=="object"&&!Array.isArray(s)}function L(s,e){return!e||e.length===0?!1:e.some(t=>typeof t=="string"?s.includes(t):t.test(s))}function Me(s){let e=5381,t=s.length;for(;t;)e=e*33^s.charCodeAt(--t);return e>>>0}function N(s){return Me(s).toString(16)}function T(s,e,t=[]){let n=t.slice(0,3).map(i=>`${i.filename}:${i.lineno||0}`).join("|"),r=e.replace(/['"]?\d+['"]?/g,"").replace(/\s+/g," ").trim();return N(`${s}:${r}:${n}`)}function P(s,e={}){if(!s)return[];let{captureNodeModules:t=!1,captureColumn:n=!0,relativePathOnly:r=!1,maxFrames:i}=e,o=[],a=s.split(` -`),u=typeof location!="undefined"?`${location.protocol}//${location.host}`:"";for(let h of a){let w=h.match(/^\s*at\s*(.+?)\s*\((.+?):(\d+):(\d+)\)\s*$/);if(w){let[,g,f,y,m]=w,S=f.includes("node_modules");if(!t&&S)continue;let x=f;r&&u&&f.startsWith(u)&&(x=f.substring(u.length)),o.push({filename:x,function:g,lineno:parseInt(y,10),colno:n?parseInt(m,10):void 0,in_app:!S})}else{let g=h.match(/^\s*at\s*(.+?)@(.+?):(\d+):(\d+)\s*$/);if(g){let[,y,m,S,x]=g,k=m.includes("node_modules");if(!t&&k)continue;let re=m;r&&u&&m.startsWith(u)&&(re=m.substring(u.length)),o.push({filename:re,function:y||"",lineno:parseInt(S,10),colno:n?parseInt(x,10):void 0,in_app:!k});continue}let f=h.match(/^\s*at\s*(.+?):(\d+):(\d+)\s*$/);if(f){let[,y,m,S]=f,x=y.includes("node_modules");if(!t&&x)continue;let k=y;r&&u&&y.startsWith(u)&&(k=y.substring(u.length)),o.push({filename:k,lineno:parseInt(m,10),colno:n?parseInt(S,10):void 0,in_app:!x})}}}let c=o.reverse();return i!==void 0&&i>0?c.slice(0,i):c}var U=!1;function M(s){U=s}function l(s,e,t){if(!U)return;let n=new Date().toISOString(),r=`[LightSDK][${s}]`;t!==void 0?console.log(`${r} ${n} ${e}`,t):console.log(`${r} ${n} ${e}`)}function H(s,e,t){if(!U)return;let n=new Date().toISOString(),r=`[LightSDK][${s}][ERROR]`;t!==void 0?console.error(`${r} ${n} ${e}`,t):console.error(`${r} ${n} ${e}`)}function De(s){let e=[{name:"WeChat",pattern:/MicroMessenger\/([\d.]+)/i},{name:"QQ Browser",pattern:/QIBrowser\/([\d.]+)/i},{name:"UC Browser",pattern:/UCBrowser\/([\d.]+)/i},{name:"Edge",pattern:/Edg\/([\d.]+)/i},{name:"Edge",pattern:/Edge\/([\d.]+)/i},{name:"Opera",pattern:/OPR\/([\d.]+)/i},{name:"Opera",pattern:/Opera\/([\d.]+)/i},{name:"Firefox",pattern:/Firefox\/([\d.]+)/i},{name:"Safari",pattern:/Version\/([\d.]+).*Safari/i},{name:"Chrome",pattern:/Chrome\/([\d.]+)/i},{name:"IE",pattern:/MSIE ([\d.]+)/i},{name:"IE",pattern:/Trident.*rv:([\d.]+)/i}];for(let t of e){let n=s.match(t.pattern);if(n){let r=n[1]||"",i=r.split(".")[0]||"";return{name:t.name,version:r,major:i}}}return{name:"Unknown",version:"",major:""}}function Ie(s){let e=[{name:"Windows 11",pattern:/Windows NT 10\.0.*Win64.*x64/i},{name:"Windows 10",pattern:/Windows NT 10\.0/i},{name:"Windows 8.1",pattern:/Windows NT 6\.3/i},{name:"Windows 8",pattern:/Windows NT 6\.2/i},{name:"Windows 7",pattern:/Windows NT 6\.1/i},{name:"Windows Vista",pattern:/Windows NT 6\.0/i},{name:"Windows XP",pattern:/Windows NT 5\.1/i},{name:"macOS",pattern:/Mac OS X ([\d_.]+)/i},{name:"iOS",pattern:/OS ([\d_.]+) like Mac OS X/i},{name:"Android",pattern:/Android ([\d.]+)/i},{name:"Android",pattern:/Android/i},{name:"Linux",pattern:/Linux/i}];for(let t of e){let n=s.match(t.pattern);if(n){let r=n[1]||"";return r&&(r=r.replace(/_/g,".")),{name:t.name,version:r}}}return{name:"Unknown",version:""}}function Be(s){let e=/Mobile|Android|iPhone|iPod|BlackBerry|Windows Phone|Opera Mini/i.test(s),t=/Tablet|iPad|PlayBook|Kindle|Silk/i.test(s),n="desktop";t?n="tablet":e&&(n="mobile");let r="",i="",o=s.match(/iPhone/i),a=s.match(/iPad/i),u=s.match(/SM-([A-Z0-9]+)/i),c=s.match(/Pixel ([0-9A-Z]+)/i),h=s.match(/HUAWEI ([A-Z0-9]+)/i);return o?(r="Apple",i="iPhone"):a?(r="Apple",i="iPad"):u?(r="Samsung",i=u[1]):c?(r="Google",i=`Pixel ${c[1]}`):h&&(r="Huawei",i=h[1]),{type:n,vendor:r,model:i}}function oe(){let s=typeof navigator!="undefined"?navigator.userAgent:"",e=De(s),t=Ie(s),n=Be(s);return{browser:e,os:t,device:n,url:typeof location!="undefined"?location.href:"",referrer:typeof document!="undefined"?document.referrer:"",title:typeof document!="undefined"?document.title:"",language:typeof navigator!="undefined"?navigator.language:"",user_agent:s,screen_width:typeof screen!="undefined"?screen.width:0,screen_height:typeof screen!="undefined"?screen.height:0,viewport_width:typeof window!="undefined"?window.innerWidth:0,viewport_height:typeof window!="undefined"?window.innerHeight:0}}function E(){return typeof location!="undefined"?location.href:""}function ae(){return typeof document!="undefined"?document.referrer:""}function R(s){if(!s)return s;try{let e=new URL(s),t=["password","passwd","pwd","token","access_token","refresh_token","api_key","apikey","key","secret","private_key","code","auth","id_token","idToken","session","session_id"],n=e.searchParams,r=!1;for(let i of Array.from(n.keys())){let o=i.toLowerCase().replace(/[-_]/g,"_");t.some(a=>o.includes(a))&&(n.set(i,"[Filtered]"),r=!0)}if(e.hash&&e.hash.length>1){let i=e.hash.substring(1);if(i.includes("=")){let o=new URLSearchParams(i),a=!1;for(let u of Array.from(o.keys())){let c=u.toLowerCase().replace(/[-_]/g,"_");t.some(h=>c.includes(h))&&(o.set(u,"[Filtered]"),a=!0)}a&&(e.hash="#"+o.toString(),r=!0)}}return r?e.toString():s}catch(e){return s}}function D(s,e=[]){return!e||e.length===0?!1:e.some(t=>{if(typeof t=="string"){if(t.includes("*")){let n=t.replace(/[.+?^${}()|[\]\\]/g,"\\$&").replace(/\*/g,".*");return new RegExp(n).test(s)}return s.includes(t)}return t.test(s)})}var _e={Chrome:"c",Safari:"s",Firefox:"f",Edge:"e",Opera:"o",IE:"i",WeChat:"w","QQ Browser":"q","UC Browser":"u","Mobile Chrome":"cm","Mobile Safari":"sm"},Oe={"Windows 11":"w11","Windows 10":"w10","Windows 8.1":"w81","Windows 8":"w8","Windows 7":"w7","Windows Vista":"wv","Windows XP":"wxp",macOS:"m",iOS:"i",Android:"a",Linux:"l"};function $(){let s=oe(),e=_e[s.browser.name]||s.browser.name.toLowerCase(),t=Oe[s.os.name]||s.os.name.toLowerCase();return{browser:{name:e,version:s.browser.major},os:{name:t,version:s.os.version.split(".")[0]},device:{type:s.device.type,brand:s.device.vendor||void 0,model:s.device.model||void 0}}}function ue(){let s=oe(),e=`${s.browser.name}|${s.browser.major}|${s.os.name}|${s.os.version.split(".")[0]}|${s.device.type}|${s.device.vendor}|${s.device.model}|${s.language}`;return N(e).substring(0,16)}var Fe={enabled:!0,sampleRate:1,maxQueueSize:100,flushInterval:5e3,maxRetries:3,retryDelay:1e3,environment:"production",contextLevel:{fatal:{maxStackFrames:5,maxBreadcrumbs:20},error:{maxStackFrames:5,maxBreadcrumbs:10},warning:{maxStackFrames:3,maxBreadcrumbs:5},info:{maxStackFrames:0,maxBreadcrumbs:0},debug:{maxStackFrames:0,maxBreadcrumbs:0}}},I=class{constructor(e){this.contexts=null;this.contextId=null;this.contextReported=!1;this.config={...Fe,...e}}markContextReported(){this.contextReported=!0}get(e){return this.config[e]}getAll(){return{...this.config}}set(e,t){this.config[e]=t}setUser(e){this.config.user=e||void 0}setTags(e){this.config.tags={...this.config.tags||{},...e}}setTag(e,t){this.config.tags||(this.config.tags={}),this.config.tags[e]=t}setExtra(e,t){this.config.extra||(this.config.extra={}),this.config.extra[e]=t}isIgnoredError(e){return L(e,this.config.ignoreErrors||[])}getEncodedContext(){return this.contexts||(this.contexts=$()),this.contexts}applyToEvent(e,t=!0){var i,o,a,u;let n={...e};if(e.tags&&(n.tags={...e.tags}),e.request&&(n.request={...e.request}),"exception"in e&&e.exception){let c=e.exception;n.exception={...c,stacktrace:c.stacktrace?{...c.stacktrace,frames:c.stacktrace.frames?c.stacktrace.frames.map(h=>({...h})):void 0}:void 0}}e.breadcrumbs&&(n.breadcrumbs=e.breadcrumbs.map(c=>({...c}))),e.user&&(n.user={...e.user}),e.contexts&&(n.contexts={...e.contexts}),this.config.release&&(n.release=this.config.release),this.config.environment&&(n.environment=this.config.environment),this.config.user&&(n.user=this.config.user),this.config.tags&&(n.tags={...this.config.tags,...e.tags||{}}),n.request?n.request.url||(n.request.url=E()):n.request={url:E(),referrer:ae()},this.contextId||(this.contextId=ue()),n.context_id=this.contextId;let r=this.applyContextLevel(n);return t&&!this.contextReported&&(this.contexts||(this.contexts=$()),r.contexts=this.contexts,r.env={b:(i=this.contexts.browser)==null?void 0:i.name,bv:(o=this.contexts.browser)==null?void 0:o.version,os:(a=this.contexts.os)==null?void 0:a.name,osv:(u=this.contexts.os)==null?void 0:u.version}),r}applyContextLevel(e){let t=this.config.contextLevel;if(!t)return e;let n=e.level||"error",r=t[n]||t.error,i={...e};if("exception"in e&&e.exception&&typeof e.exception=="object"){let o=e.exception;if(o.stacktrace&&typeof o.stacktrace=="object"){let a=o.stacktrace;Array.isArray(a.frames)&&(r.maxStackFrames===0?delete i.exception:i.exception={...o,stacktrace:{...a,frames:a.frames.slice(0,r.maxStackFrames)}})}}return e.breadcrumbs&&Array.isArray(e.breadcrumbs)&&(r.maxBreadcrumbs===0?delete i.breadcrumbs:i.breadcrumbs=e.breadcrumbs.slice(-r.maxBreadcrumbs)),i}};var B=class{constructor(){this.handlers=new Map}on(e,t){this.handlers.has(e)||this.handlers.set(e,[]),this.handlers.get(e).push(t)}off(e,t){let n=this.handlers.get(e);if(n){let r=n.indexOf(t);r>-1&&n.splice(r,1)}}emit(e,...t){let n=this.handlers.get(e);if(n)for(let r of n)try{r(...t)}catch(i){console.error("[LightSDK] EventBus handler error:",i)}}once(e,t){let n=(...r)=>{this.off(e,n),t(...r)};this.on(e,n)}destroy(){this.handlers.clear()}};var _=class{constructor(e,t,n,r,i){this.queue=[];this.timer=null;this.lastFlushTime=0;this.isFlushing=!1;this.dedupeMap=new Map;this.pendingCounts=new Map;this.errorRateWindow={};this.paused=!1;this.pauseTimer=null;this.maxSize=e,this.flushInterval=t,this.eventBus=n,this.flushCallback=r,this.syncFlushCallback=i}start(){this.startTimer(),this.setupVisibilityListener()}startTimer(){this.timer||(this.timer=setInterval(()=>{(this.queue.length>0||this.pendingCounts.size>0)&&this.flush()},this.flushInterval))}setupVisibilityListener(){this.onVisibilityChange=()=>{document.hidden&&(this.queue.length>0||this.pendingCounts.size>0)&&this.flushSync()},typeof document!="undefined"&&document.addEventListener("visibilitychange",this.onVisibilityChange),this.onBeforeUnload=()=>{(this.queue.length>0||this.pendingCounts.size>0)&&this.flushSync()},this.onPagehide=()=>{(this.queue.length>0||this.pendingCounts.size>0)&&this.flushSync()},typeof window!="undefined"&&(window.addEventListener("beforeunload",this.onBeforeUnload),window.addEventListener("pagehide",this.onPagehide))}checkInfiniteLoop(e){let t=p(),n=t-1e3;this.errorRateWindow[e]||(this.errorRateWindow[e]=[]);let r=this.errorRateWindow[e];for(r.push(t);r.length>0&&r[0]10?(this.paused||(console.warn("[LightSDK] Infinite loop detected, pausing SDK for 60s",{fingerprint:e,count:r.length}),this.eventBus.emit("error",new Error("Infinite loop detected")),this.paused=!0,this.pauseTimer&&clearTimeout(this.pauseTimer),this.pauseTimer=setTimeout(()=>{this.paused=!1,this.errorRateWindow={},console.info("[LightSDK] Resumed after infinite loop detection")},6e4)),!0):!1}enqueue(e){if(l("EventQueue","enqueue called",{type:e.type,level:e.level,message:"message"in e?e.message:void 0}),this.paused){l("EventQueue","enqueue skipped: queue paused (infinite loop detected)");return}this.cleanupExpiredDedupeEntries();let t=this.getDedupeKey(e);if(t){if(this.checkInfiniteLoop(t)){l("EventQueue","enqueue skipped: infinite loop detected",{fingerprint:t});return}let n=p(),r=this.dedupeMap.get(t);if(r)if(n-r.lastTime<6e4){if(r.count>=3){if(!this.pendingCounts.has(t))this.pendingCounts.set(t,{count:1,ts_start:n,ts_end:n});else{let i=this.pendingCounts.get(t);i.count++,i.ts_end=n}l("EventQueue","enqueue skipped: deduped (count >= 3)",{fingerprint:t,count:r.count});return}r.count++,r.lastTime=n,l("EventQueue","Dedup count incremented",{fingerprint:t,count:r.count})}else this.dedupeMap.set(t,{count:1,lastTime:n,firstReported:!0}),this.pendingCounts.delete(t),l("EventQueue","Dedup entry reset (expired)",{fingerprint:t});else this.dedupeMap.set(t,{count:1,lastTime:n,firstReported:!1}),l("EventQueue","New dedup entry created",{fingerprint:t})}this.queue.push(e),l("EventQueue","Event added to queue",{queueSize:this.queue.length}),this.eventBus.emit("event",e),this.queue.length>=this.maxSize&&(l("EventQueue","Queue reached maxSize, triggering flush",{maxSize:this.maxSize}),this.flush())}cleanupExpiredDedupeEntries(){if(this.dedupeMap.size<100&&Math.random()>.1)return;let e=p(),t=6e4;for(let[n,r]of this.dedupeMap)e-r.lastTime>t&&this.dedupeMap.delete(n)}buildCountEvents(){let e=[];for(let[t,n]of this.pendingCounts.entries()){let r={type:"count",fingerprint:t,count:n.count,ts_start:n.ts_start,ts_end:n.ts_end,timestamp:p(),level:"info"};e.push(r)}return e}getDedupeKey(e){if(e.type==="error"){let t=e;return t.fingerprint||t.message}return null}async flush(){if(l("EventQueue","flush called",{queueSize:this.queue.length,pendingCounts:this.pendingCounts.size,isFlushing:this.isFlushing}),this.queue.length===0&&this.pendingCounts.size===0){l("EventQueue","flush skipped: queue is empty");return}if(this.isFlushing){l("EventQueue","flush skipped: already flushing");return}this.isFlushing=!0;let e=this.queue.splice(0,this.queue.length),t=this.buildCountEvents(),n=[...e,...t];l("EventQueue","flush events to callback",{total:n.length,events:e.length,countEvents:t.length}),this.lastFlushTime=p(),this.eventBus.emit("report",n);try{await this.flushCallback(n),this.pendingCounts.clear(),l("EventQueue","flush completed successfully"),this.eventBus.emit("reported",n)}catch(r){throw l("EventQueue","flush failed, returning events to queue",{error:r instanceof Error?r.message:String(r)}),e.forEach(i=>this.queue.unshift(i)),r}finally{this.isFlushing=!1}}flushSync(){if(this.queue.length===0&&this.pendingCounts.size===0)return;let e=this.queue.splice(0,this.queue.length),t=new Map(this.pendingCounts),n=this.buildCountEvents(),r=[...e,...n];this.lastFlushTime=p(),this.eventBus.emit("report",r);try{this.syncFlushCallback(r),this.pendingCounts.clear(),this.eventBus.emit("reported",r)}catch(i){console.error("[LightSDK] Sync flush failed",i),e.forEach(o=>this.queue.unshift(o));for(let[o,a]of t)this.pendingCounts.has(o)||this.pendingCounts.set(o,a)}}size(){return this.queue.length}destroy(){this.timer&&(clearInterval(this.timer),this.timer=null),this.pauseTimer&&(clearTimeout(this.pauseTimer),this.pauseTimer=null),typeof document!="undefined"&&this.onVisibilityChange&&document.removeEventListener("visibilitychange",this.onVisibilityChange),typeof window!="undefined"&&(this.onBeforeUnload&&window.removeEventListener("beforeunload",this.onBeforeUnload),this.onPagehide&&window.removeEventListener("pagehide",this.onPagehide)),this.dedupeMap.clear(),this.pendingCounts.clear(),this.errorRateWindow={}}};var ce={event_id:"eid",timestamp:"ts",start_timestamp:"sts",type:"t",level:"l",message:"m",platform:"p",release:"r",environment:"e",fingerprint:"fp",context_id:"cid",user:"u",tags:"tg",exception:"ex",request:"req",contexts:"ctx",breadcrumbs:"bc",transaction:"tx",duration:"d",spans:"sp",extra:"xt"},tt=Object.fromEntries(Object.entries(ce).map(([s,e])=>[e,s]));function le(s){if(!s||typeof s!="object")return s;let e={};for(let[t,n]of Object.entries(s)){let r=ce[t]||t;e[r]=n}return e}var O=class{constructor(e,t,n){this.useShortFields=!0;this.dsn=e,this.maxRetries=t,this.retryDelay=n}async report(e){if(l("Reporter","report called",{eventCount:e.length}),e.length===0){l("Reporter","report skipped: empty events");return}let t=this.buildEnvelope(e),n=C(this.dsn);l("Reporter","Envelope built",{envelopeSize:t.length,url:n});let r=0;for(;r<=this.maxRetries;)try{l("Reporter",`Sending request (attempt ${r+1}/${this.maxRetries+1})`),await this.send(t,!1),l("Reporter","Request succeeded");return}catch(i){let o=i.status;if(H("Reporter",`Request failed (attempt ${r+1})`,{status:o,error:i}),o&&o>=400&&o<500)throw i;if(r++,r>this.maxRetries)throw H("Reporter","All retries exhausted"),i;let a=Math.min(this.retryDelay*Math.pow(2,r-1),5e3);l("Reporter",`Retrying in ${a}ms`),await this.delay(a)}}reportSync(e){if(e.length===0)return;let t=this.buildEnvelope(e);try{if(this.sendSync(t))return}catch(n){}this.sendViaImage(t)}buildEnvelope(e){let t=this.extractSharedMeta(e),n={event_id:se(),sent_at:new Date().toISOString(),meta:t};this.useShortFields&&(n._sf=1);let r=this.applyRelativeTimestamps(e,n),o=[JSON.stringify(n)];for(let a of r){let u=this.stripSharedFields(a,t);this.useShortFields&&(u=le(u));let c=JSON.stringify(u),h=JSON.stringify({type:this.getEnvelopeType(a),length:c.length});o.push(h,c)}return o.join(` -`)}applyRelativeTimestamps(e,t){if(e.length<=1)return e;let n=[],r=e[0].timestamp?new Date(e[0].timestamp).getTime():Date.now();t._rt=1,t._bt=r;for(let i=0;io.release===t.release)&&(n.release=t.release),t.environment&&e.every(o=>o.environment===t.environment)&&(n.environment=t.environment),t.user&&e.every(o=>JSON.stringify(o.user)===JSON.stringify(t.user))&&(n.user=t.user);let r=t.env;return r&&(n.env=r),n}stripSharedFields(e,t){let n={...e};return t.release&&n.release===t.release&&delete n.release,t.environment&&n.environment===t.environment&&delete n.environment,t.user&&JSON.stringify(n.user)===JSON.stringify(t.user)&&delete n.user,t.env&&delete n.env,n}getEnvelopeType(e){switch(e.type){case"error":return"event";case"performance":return"transaction";default:return e.type}}async send(e,t=!1){let n=C(this.dsn);if(navigator.sendBeacon)try{let r=new Blob([e],{type:"application/x-sentry-envelope"});if(navigator.sendBeacon(n,r))return}catch(r){}if(typeof fetch=="function")try{let r=new AbortController,i=setTimeout(()=>r.abort(),1e4),o=await fetch(n,{method:"POST",body:e,headers:{"Content-Type":"application/x-sentry-envelope"},keepalive:!0,signal:r.signal});if(clearTimeout(i),o.ok)return;let a=new Error(`HTTP ${o.status}`);throw a.status=o.status,a}catch(r){throw r}if(typeof XMLHttpRequest!="undefined")return new Promise((r,i)=>{let o=new XMLHttpRequest;o.open("POST",n,!t),o.setRequestHeader("Content-Type","application/x-sentry-envelope"),o.timeout=1e4,o.onload=()=>{if(o.status>=200&&o.status<300)r();else{let a=new Error(`HTTP ${o.status}`);a.status=o.status,i(a)}},o.onerror=()=>i(new Error("Network error")),o.ontimeout=()=>i(new Error("Request timeout")),o.send(e)});throw new Error("No transport available")}sendSync(e){let t=C(this.dsn);if(navigator.sendBeacon)try{let n=new Blob([e],{type:"application/x-sentry-envelope"});return navigator.sendBeacon(t,n)}catch(n){return!1}if(typeof XMLHttpRequest!="undefined")try{let n=new XMLHttpRequest;return n.open("POST",t,!1),n.setRequestHeader("Content-Type","application/x-sentry-envelope"),n.send(e),n.status>=200&&n.status<300}catch(n){return!1}return!1}sendViaImage(e){try{let t=C(this.dsn),n=new Image,r=encodeURIComponent(btoa(e)),i=t.includes("?")?"&":"?";return n.src=t+i+"sentry_data="+r.substring(0,2e3),!0}catch(t){return!1}}delay(e){return new Promise(t=>setTimeout(t,e))}};var F=class{constructor(e){this.plugins=new Map;this.client=e}add(e){if(!this.plugins.has(e.name)){this.plugins.set(e.name,e);try{e.setup(this.client)}catch(t){console.error(`[LightSDK] Plugin "${e.name}" setup error:`,t)}}}remove(e){let t=this.plugins.get(e);if(t){if(t.destroy)try{t.destroy()}catch(n){console.error(`[LightSDK] Plugin "${e}" destroy error:`,n)}this.plugins.delete(e)}}get(e){return this.plugins.get(e)}has(e){return this.plugins.has(e)}applyBeforeReport(e){let t=e;for(let n of this.plugins.values())if(n.beforeReport)try{let r=n.beforeReport(t);if(r===null)return null;t=r}catch(r){console.error(`[LightSDK] Plugin "${n.name}" beforeReport error:`,r)}return t}applyAfterReport(e){for(let t of this.plugins.values())if(t.afterReport)try{t.afterReport(e)}catch(n){console.error(`[LightSDK] Plugin "${t.name}" afterReport error:`,n)}}destroy(){for(let e of this.plugins.values())if(e.destroy)try{e.destroy()}catch(t){console.error(`[LightSDK] Plugin "${e.name}" destroy error:`,t)}this.plugins.clear()}};var K=class{constructor(e){this.breadcrumbs=[];this.enabled=!0;var t,n,r,i;if(!e.dsn)throw new Error("DSN is required");M(e.debug===!0),l("Client","Initializing SDK",{dsn:e.dsn,debug:e.debug,enabled:e.enabled!==!1}),this.dsn=ie(e.dsn),this.configManager=new I(e),this.eventBus=new B,this.reporter=new O(this.dsn,(t=this.configManager.get("maxRetries"))!=null?t:3,(n=this.configManager.get("retryDelay"))!=null?n:1e3),this.pluginManager=new F(this),this.queue=new _((r=this.configManager.get("maxQueueSize"))!=null?r:100,(i=this.configManager.get("flushInterval"))!=null?i:5e3,this.eventBus,async o=>this.flushEvents(o),o=>this.syncFlushEvents(o)),this.enabled=this.configManager.get("enabled")!==!1,l("Client","SDK initialized",{enabled:this.enabled})}get maxBreadcrumbs(){var e;return(e=this.configManager.get("maxBreadcrumbs"))!=null?e:20}get config(){return this.configManager.getAll()}init(){this.enabled&&(this.queue.start(),this.emit("ready"))}async flushEvents(e){l("Client","flushEvents start",{eventCount:e.length});let t=[];for(let i of e){let o=this.pluginManager.applyBeforeReport(i);o?t.push(o):l("Client","Event filtered by beforeReport plugin",{type:i.type,message:"message"in i?i.message:void 0})}if(t.length===0){l("Client","flushEvents: all events filtered by beforeReport");return}let n=!0,r=[];for(let i of t){let o=this.configManager.applyToEvent(i,n);n=!1;let a=this.configManager.get("beforeSend"),u=a?a(o):o;if(!u){l("Client","Event filtered by beforeSend",{type:i.type});continue}r.push(u)}if(r.length===0){l("Client","flushEvents: all events filtered by beforeSend");return}l("Client","Reporting events",{count:r.length}),await this.reporter.report(r),l("Client","Report completed successfully"),this.configManager.markContextReported();for(let i of r)this.pluginManager.applyAfterReport(i)}syncFlushEvents(e){let t=[];for(let i of e){let o=this.pluginManager.applyBeforeReport(i);o&&t.push(o)}if(t.length===0)return;let n=!0,r=[];for(let i of t){let o=this.configManager.applyToEvent(i,n);n=!1;let a=this.configManager.get("beforeSend"),u=a?a(o):o;u&&r.push(u)}r.length!==0&&(this.reporter.reportSync(r),this.configManager.markContextReported())}on(e,t){this.eventBus.on(e,t)}off(e,t){this.eventBus.off(e,t)}emit(e,...t){this.eventBus.emit(e,...t)}captureException(e){if(l("Client","captureException called",{error:e instanceof Error?e.message:String(e)}),!this.enabled){l("Client","captureException skipped: SDK disabled");return}let t=this.buildErrorEvent(e);if(l("Client","Error event built",{type:t.type,message:t.message,fingerprint:t.fingerprint}),this.configManager.isIgnoredError(t.message)){l("Client","captureException skipped: error ignored by ignoreErrors");return}t.breadcrumbs=[...this.breadcrumbs],l("Client","Enqueue error event",{breadcrumbs:this.breadcrumbs.length}),this.queue.enqueue(t)}captureMessage(e,t="info"){if(!this.enabled)return;let n={type:"error",level:t,message:e,timestamp:p(),breadcrumbs:[...this.breadcrumbs]};this.configManager.isIgnoredError(e)||this.queue.enqueue(n)}captureEvent(e){if(!this.enabled)return;let t={timestamp:p(),level:"info",breadcrumbs:[...this.breadcrumbs],...e};this.queue.enqueue(t)}buildErrorEvent(e){let t=p();if(e instanceof Error){let r=P(e.stack,{maxFrames:5}),i=T(e.name,e.message,r);return{type:"error",level:"error",message:e.message,timestamp:t,exception:{type:e.name,value:e.message,stacktrace:{frames:r}},fingerprint:i}}return{type:"error",level:"error",message:String(e),timestamp:t}}setUser(e){this.configManager.setUser(e)}setTag(e,t){this.configManager.setTag(e,t)}setTags(e){this.configManager.setTags(e)}setExtra(e,t){this.configManager.setExtra(e,t)}addBreadcrumb(e){let t={...e,timestamp:p()};this.breadcrumbs.push(t),this.breadcrumbs.length>this.maxBreadcrumbs&&this.breadcrumbs.shift()}async flush(){await this.queue.flush()}disable(){this.enabled=!1}enable(){this.enabled=!0}use(e){this.pluginManager.add(e)}destroy(){this.queue.destroy(),this.pluginManager.destroy(),this.eventBus.destroy(),this.breadcrumbs=[]}},j=K;var W=class{constructor(){this.name="error";this.version="1.0.0";this.config={maxStackFrames:5,captureNodeModules:!1,captureColumn:!0,relativePathOnly:!1,resourceSampleRate:.1}}setup(e){this.client=e,this.loadConfig(),this.setupGlobalError(),this.setupUnhandledRejection(),this.setupResourceError()}loadConfig(){let e=this.client.config;e&&b(e.error)&&(this.config={...this.config,...e.error}),e.ignoreErrors&&(this.config.ignoreErrors=[...this.config.ignoreErrors||[],...e.ignoreErrors]),e.ignoreUrls&&(this.config.ignoreUrls=[...this.config.ignoreUrls||[],...e.ignoreUrls]),e.includePaths&&(this.config.includePaths=[...this.config.includePaths||[],...e.includePaths])}shouldIgnoreError(e){return e?L(e,this.config.ignoreErrors||[]):!1}shouldIgnoreScriptUrl(e){return D(e,this.config.ignoreUrls||[])}shouldIncludePath(e){let t=this.config.includePaths||[];return t.length===0?!0:e.some(n=>t.some(r=>{var i;return typeof r=="string"?(i=n.filename)==null?void 0:i.includes(r):r.test(n.filename||"")}))}shouldSample(){var t;let e=(t=this.config.sampleRate)!=null?t:1;return e>=1?!0:e<=0?!1:Math.random()=1?!0:e<=0?!1:Math.random(){try{if(this.originalOnError&&this.originalOnError.call(window,e,t,n,r,i),t&&this.shouldIgnoreScriptUrl(t))return!1;let o=this.buildErrorEvent(i||e,t,n,r);o&&this.client.captureEvent(o)}catch(o){console.error("[LightSDK] ErrorPlugin global error handler error:",o)}return!1})}setupUnhandledRejection(){typeof window!="undefined"&&(this.onUnhandledRejection=e=>{try{let t=e.reason,n=this.extractUrlFromReason(t);if(n&&this.shouldIgnoreScriptUrl(n))return;let r=this.buildErrorEvent(t);r&&(r.type==="error"&&(r.tags={...r.tags||{},unhandled:"true",promise:"true"}),this.client.captureEvent(r))}catch(t){console.error("[LightSDK] ErrorPlugin unhandledrejection handler error:",t)}},window.addEventListener("unhandledrejection",this.onUnhandledRejection))}extractUrlFromReason(e){if(e instanceof Error&&e.stack){let t=e.stack.match(/at\s+(?:.+?\s+)?\((https?:\/\/[^:]+):\d+:\d+\)/);if(t)return t[1];let n=e.stack.match(/(https?:\/\/[^\s)]+):\d+:\d+/);if(n)return n[1]}return null}setupResourceError(){typeof window!="undefined"&&(this.onResourceError=e=>{var i;let t=e.target;if(!t)return;let n=(i=t.tagName)==null?void 0:i.toLowerCase(),r=t.src||t.href;if(n&&r&&["img","script","link","audio","video"].includes(n))try{if(this.shouldIgnoreScriptUrl(r)||!this.shouldSampleResource())return;let o=`resource:${n}`,a=R(r);this.client.captureEvent({type:"error",level:"warning",message:`Resource load failed: ${n} ${a}`,timestamp:p(),fingerprint:o,tags:{resource_type:n,resource_url:a},exception:{type:"ResourceError",value:`Failed to load ${n} resource`}})}catch(o){console.error("[LightSDK] ErrorPlugin resource error handler error:",o)}},window.addEventListener("error",this.onResourceError,!0))}buildErrorEvent(e,t,n,r){let i=p();if(e instanceof Error){if(this.shouldIgnoreError(e.message))return null;let u=P(e.stack,{captureNodeModules:this.config.captureNodeModules,captureColumn:this.config.captureColumn,relativePathOnly:this.config.relativePathOnly,maxFrames:this.config.maxStackFrames});if(!this.shouldIncludePath(u)||!this.shouldSample())return null;let c=T(e.name,e.message,u);return{type:"error",level:"error",message:e.message,timestamp:i,exception:{type:e.name,value:e.message,stacktrace:{frames:u}},fingerprint:c}}let o=String(e);if(this.shouldIgnoreError(o))return null;let a=[];return t&&a.push({filename:t,lineno:n,colno:this.config.captureColumn?r:void 0,in_app:!0}),!this.shouldIncludePath(a)||!this.shouldSample()?null:{type:"error",level:"error",message:o,timestamp:i,exception:{type:"Error",value:o,stacktrace:{frames:a}}}}destroy(){typeof window!="undefined"&&(this.originalOnError!==void 0&&(window.onerror=this.originalOnError),this.onUnhandledRejection&&window.removeEventListener("unhandledrejection",this.onUnhandledRejection),this.onResourceError&&window.removeEventListener("error",this.onResourceError,!0))}},X=W;var A=class{constructor(){this.name="performance";this.version="1.0.0";this.config={sampleRate:.1,captureLongTasks:!0,captureResources:!1,resourceSampleRate:.01,longTaskSampleRate:.05,captureNavigation:!0,captureFP:!0};this.observers=[];this.navLoadTimer=null;this.totalBlockingTime=0;this.fcpTime=null;this.lastLongTaskEndTime=0;this.ttiReported=!1;this.ttiTimer=null}setup(e){this.client=e,this.loadConfig(),this.observeWebVitals(),this.observeLongTasks(),this.observeNavigation(),this.observeResources()}loadConfig(){let e=this.client.config;e&&b(e.performance)&&(this.config={...this.config,...e.performance})}shouldSample(e="default"){var n,r,i;let t=(n=this.config.sampleRate)!=null?n:.1;return e==="resource"?t=(r=this.config.resourceSampleRate)!=null?r:.01:e==="longtask"?t=(i=this.config.longTaskSampleRate)!=null?i:.05:e==="vitals"&&(t=1),t>=1?!0:t<=0?!1:Math.random(){let n=t.getEntriesByName("first-paint");n.length>0&&this.reportMetric("FP",n[0].startTime,"ms",{},"vitals")});e.observe({type:"paint",buffered:!0}),this.observers.push(e)}catch(e){}}observeLCP(){try{let e=new PerformanceObserver(t=>{let n=t.getEntries(),r=n[n.length-1];if(r){let i=r.renderTime||r.loadTime||r.startTime;this.reportMetric("LCP",i,"ms",{},"vitals")}});e.observe({type:"largest-contentful-paint",buffered:!0}),this.observers.push(e)}catch(e){}}observeFID(){try{let e=new PerformanceObserver(t=>{let n=t.getEntries();if(n.length>0){let r=n[0],i=r.processingStart-r.startTime;this.reportMetric("FID",i,"ms",{},"vitals")}});e.observe({type:"first-input",buffered:!0}),this.observers.push(e)}catch(e){}}observeCLS(){try{let e=0,t=0,n=[],r=new PerformanceObserver(i=>{let o=i.getEntries();for(let a of o)if(!a.hadRecentInput){let u=n[0],c=n[n.length-1];t&&a.startTime-((c==null?void 0:c.duration)||0)<1e3&&a.startTime-u.startTime<5e3?(t+=a.value||0,n.push(a)):(t=a.value||0,n=[a]),t>e&&(e=t,this.reportMetric("CLS",e,"",{},"vitals"))}});r.observe({type:"layout-shift",buffered:!0}),this.observers.push(r)}catch(e){}}observeFCP(){try{let e=new PerformanceObserver(t=>{let n=t.getEntriesByName("first-contentful-paint");n.length>0&&(this.fcpTime=n[0].startTime,this.lastLongTaskEndTime=n[0].startTime,this.reportMetric("FCP",n[0].startTime,"ms",{},"vitals"),this.scheduleTTI())});e.observe({type:"paint",buffered:!0}),this.observers.push(e)}catch(e){}}observeTTFB(){try{let e=new PerformanceObserver(t=>{let n=t.getEntriesByType("navigation");if(n.length>0){let r=n[0],i=r.responseStart-r.requestStart;this.reportMetric("TTFB",Math.max(0,i),"ms",{},"vitals")}});e.observe({type:"navigation",buffered:!0}),this.observers.push(e)}catch(e){}}observeLongTasks(){if(this.config.captureLongTasks)try{let e=new PerformanceObserver(t=>{let n=t.getEntries();for(let r of n){let i=r.startTime+r.duration;if(i>this.lastLongTaskEndTime&&(this.lastLongTaskEndTime=i),this.fcpTime!==null&&r.startTime>=this.fcpTime){let o=r.duration-50;o>0&&(this.totalBlockingTime+=o)}this.reportMetric("longtask",r.duration,"ms",{},"longtask"),this.scheduleTTI()}});e.observe({type:"longtask",buffered:!0}),this.observers.push(e)}catch(e){}}scheduleTTI(){this.ttiReported||(this.ttiTimer&&clearTimeout(this.ttiTimer),this.ttiTimer=setTimeout(()=>{if(this.ttiReported)return;this.ttiReported=!0;let e=Math.max(this.lastLongTaskEndTime,this.fcpTime||0);this.reportMetric("TTI",e,"ms",{},"vitals"),this.reportMetric("TBT",this.totalBlockingTime,"ms",{},"vitals")},5e3))}observeNavigation(){this.config.captureNavigation&&typeof performance!="undefined"&&(this.onLoad=()=>{this.navLoadTimer=setTimeout(()=>{let e=performance.timing;if(!e)return;let t=e.navigationStart,n={dom_ready:e.domContentLoadedEventEnd-t,load_time:e.loadEventEnd-t,dns:e.domainLookupEnd-e.domainLookupStart,tcp:e.connectEnd-e.connectStart,ssl:e.secureConnectionStart>0?e.connectEnd-e.secureConnectionStart:0,ttfb:e.responseStart-e.requestStart,download:e.responseEnd-e.responseStart,dom_parse:e.domInteractive-e.responseEnd};for(let[r,i]of Object.entries(n))i>0&&this.reportMetric(r,i,"ms");this.navLoadTimer=null},0)},window.addEventListener("load",this.onLoad))}observeResources(){if(this.config.captureResources&&typeof performance!="undefined")try{let e=new PerformanceObserver(t=>{let n=t.getEntriesByType("resource");for(let r of n)r.duration>1e3&&this.reportMetric("resource_slow",r.duration,"ms",{resource_name:r.name.substring(0,200),resource_type:r.initiatorType},"resource")});e.observe({type:"resource",buffered:!0}),this.observers.push(e)}catch(e){}}getRating(e,t){let r={LCP:{good:2500,poor:4e3},FCP:{good:1800,poor:3e3},FP:{good:1800,poor:3e3},FID:{good:100,poor:300},CLS:{good:.1,poor:.25},TTFB:{good:800,poor:1800}}[e];return!r||t<=r.good?"good":t<=r.poor?"needs-improvement":"poor"}reportMetric(e,t,n,r={},i="default"){if(!this.shouldSample(i))return;let o=this.getRating(e,t),a={type:"performance",level:"info",metric:e,value:Math.round(t*100)/100,unit:n,rating:o,timestamp:p(),tags:{metric:e,rating:o,...r}};this.client.captureEvent(a)}destroy(){for(let e of this.observers)try{e.disconnect()}catch(t){}this.observers=[],this.ttiTimer&&(clearTimeout(this.ttiTimer),this.ttiTimer=null),this.navLoadTimer&&(clearTimeout(this.navLoadTimer),this.navLoadTimer=null),typeof window!="undefined"&&this.onLoad&&window.removeEventListener("load",this.onLoad)}},z=A;var V=class{constructor(){this.name="network";this.version="1.0.0";this.config={captureXHR:!0,captureFetch:!0,captureSuccess:!1,captureBody:!1,captureRequestBody:!1,captureResponseBody:!1,captureRequestHeaders:["content-type","user-agent"],captureResponseHeaders:["content-type","content-length"],errorSampleRate:1,successSampleRate:.01,slowThreshold:3e3,slowSampleRate:1,ignoreStatusCodes:[]}}setup(e){this.client=e,this.loadConfig(),this.config.captureFetch&&this.patchFetch(),this.config.captureXHR&&this.patchXHR()}loadConfig(){let e=this.client.config;e&&b(e.network)&&(this.config={...this.config,...e.network}),e.ignoreUrls&&(this.config.ignoreUrls=[...this.config.ignoreUrls||[],...e.ignoreUrls])}shouldIgnore(e){return D(e,this.config.ignoreUrls||[])}shouldSample(e,t){var r,i,o,a;let n=e?(r=this.config.errorSampleRate)!=null?r:1:(i=this.config.successSampleRate)!=null?i:.01;return!e&&t>=((o=this.config.slowThreshold)!=null?o:3e3)&&(n=(a=this.config.slowSampleRate)!=null?a:1),n>=1?!0:n<=0?!1:Math.random(){var f;let h=p()-r,w=c.ok,g=c.status;return(f=e.config.ignoreStatusCodes)!=null&&f.includes(g)||!e.shouldSample(!w,h)||(!w||e.config.captureSuccess)&&e.reportNetwork({sub_type:"fetch",method:o.toUpperCase(),url:a,status_code:g,duration:h,success:w,error:w?void 0:`HTTP ${g}`}),c},c=>{let h=p()-r;throw e.shouldSample(!0,h)&&e.reportNetwork({sub_type:"fetch",method:o.toUpperCase(),url:a,duration:h,success:!1,error:(c==null?void 0:c.message)||"Network error"}),c}),u}}patchXHR(){if(typeof XMLHttpRequest=="undefined")return;this.originalXHROpen=XMLHttpRequest.prototype.open,this.originalXHRSend=XMLHttpRequest.prototype.send;let e=this;XMLHttpRequest.prototype.open=function(t,n){return this._lightMethod=t,this._lightUrl=typeof n=="string"?n:n.toString(),this._lightTracked=!1,e.originalXHROpen.apply(this,arguments)},XMLHttpRequest.prototype.send=function(t){let n=p(),r=this._lightMethod||"GET",i=this._lightUrl||"",o=this._lightTracked;if(e.shouldIgnore(i)||o)return e.originalXHRSend.apply(this,arguments);this._lightTracked=!0;let a=R(i),u=0;t&&typeof t=="string"&&(u=t.length);let c=this.onloadend;return this.onloadend=function(h){var y;let w=p()-n,g=this.status,f=g>=200&&g<300;if(!((y=e.config.ignoreStatusCodes)!=null&&y.includes(g))&&e.shouldSample(!f,w)&&(!f||e.config.captureSuccess)){let m=0;try{let S=this.getResponseHeader("content-length");S&&(m=parseInt(S,10)),!m&&this.responseText&&(m=this.responseText.length)}catch(S){}e.reportNetwork({sub_type:"xhr",method:r.toUpperCase(),url:a,status_code:g,duration:w,request_size:u||void 0,response_size:m||void 0,success:f,error:f?void 0:`HTTP ${g}`})}if(c)return c.call(this,h)},e.originalXHRSend.apply(this,arguments)}}reportNetwork(e){let t={type:"network",level:e.success?"info":"error",timestamp:p(),tags:{method:e.method,sub_type:e.sub_type,success:String(e.success)},...e};this.client.captureEvent(t)}destroy(){this.originalFetch&&(window.fetch=this.originalFetch),this.originalXHROpen&&(XMLHttpRequest.prototype.open=this.originalXHROpen),this.originalXHRSend&&(XMLHttpRequest.prototype.send=this.originalXHRSend)}},Q=V;var G=class{constructor(){this.name="behavior";this.version="1.0.0";this.config={capturePV:!0,captureClick:!0,captureRoute:!0,captureDuration:!0,captureScroll:!0,clickThrottle:300,scrollThrottle:1e3,sampleRate:.01};this.lastClickTime=0;this.lastScrollTime=0;this.maxScrollDepth=0;this.pageEnterTime=0;this.scrollReported=!1}setup(e){this.client=e,this.loadConfig(),this.config.capturePV&&this.trackPV(),this.config.captureClick&&this.trackClick(),this.config.captureRoute&&this.trackRoute(),this.config.captureDuration&&this.trackPageDuration(),this.config.captureScroll&&this.trackScroll()}loadConfig(){let e=this.client.config;e&&b(e.behavior)&&(this.config={...this.config,...e.behavior})}shouldSample(){var t;let e=(t=this.config.sampleRate)!=null?t:.01;return e>=1?!0:e<=0?!1:Math.random(){var a,u,c;let t=p(),n=(a=this.config.clickThrottle)!=null?a:300;if(t-this.lastClickTime{let r=E();if(r!==e){let i=e,o=r;e=r,this.reportBehavior({sub_type:"route",page_url:o,referrer:i,properties:{from:i,to:o}}),this.pageEnterTime=p(),this.maxScrollDepth=0,this.scrollReported=!1}};this.originalPushState=history.pushState,this.originalReplaceState=history.replaceState;let n=this;history.pushState=function(){let r=n.originalPushState.apply(this,arguments);return setTimeout(t,0),r},history.replaceState=function(){let r=n.originalReplaceState.apply(this,arguments);return setTimeout(t,0),r},this.onPopState=()=>{setTimeout(t,0)},this.onHashchange=()=>{setTimeout(t,0)},window.addEventListener("popstate",this.onPopState),window.addEventListener("hashchange",this.onHashchange)}trackPageDuration(){if(typeof window=="undefined")return;this.pageEnterTime=p();let e=()=>{let t=p()-this.pageEnterTime;t>1e3&&(this.config.captureScroll&&!this.scrollReported&&this.reportScroll(),this.reportBehavior({sub_type:"duration",page_url:E(),properties:{duration:t,max_scroll_depth:this.maxScrollDepth}}))};this.onVisibilityChange=()=>{document.hidden?e():this.pageEnterTime=p()},this.onBeforeUnload=e,this.onPagehide=e,document.addEventListener("visibilitychange",this.onVisibilityChange),window.addEventListener("beforeunload",this.onBeforeUnload),window.addEventListener("pagehide",this.onPagehide)}trackScroll(){typeof window!="undefined"&&(this.onScroll=()=>{var r;let e=p(),t=(r=this.config.scrollThrottle)!=null?r:1e3;if(e-this.lastScrollTimethis.maxScrollDepth&&(this.maxScrollDepth=n)},window.addEventListener("scroll",this.onScroll,{passive:!0}))}reportScroll(){this.scrollReported||(this.scrollReported=!0,this.reportBehavior({sub_type:"scroll",page_url:E(),properties:{max_depth:this.maxScrollDepth}}))}reportBehavior(e){if(!this.shouldSample())return;let t={type:"behavior",level:"info",timestamp:p(),tags:{sub_type:e.sub_type,page_url:E()},...e};this.client.captureEvent(t)}destroy(){typeof window!="undefined"&&(this.originalPushState&&(history.pushState=this.originalPushState),this.originalReplaceState&&(history.replaceState=this.originalReplaceState),this.onPopState&&window.removeEventListener("popstate",this.onPopState),this.onHashchange&&window.removeEventListener("hashchange",this.onHashchange),this.onBeforeUnload&&window.removeEventListener("beforeunload",this.onBeforeUnload),this.onPagehide&&window.removeEventListener("pagehide",this.onPagehide),this.onScroll&&window.removeEventListener("scroll",this.onScroll)),typeof document!="undefined"&&(this.onClick&&document.removeEventListener("click",this.onClick,!0),this.onVisibilityChange&&document.removeEventListener("visibilitychange",this.onVisibilityChange))}},J=G;var qe="light-sentry-offline",v="events",Z=1e3,Y=class{constructor(){this.name="offline";this.version="1.0.0";this.config={maxEvents:Z};this.db=null;this.isOnline=!0;this.isSyncing=!1;this.pendingEvents=[]}setup(e){this.client=e,this.loadConfig(),this.initDatabase(),this.setupNetworkListeners()}loadConfig(){let e=this.client.config;e&&typeof e.offline=="object"&&(this.config={...this.config,...e.offline})}async initDatabase(){if(typeof indexedDB=="undefined"){console.warn("[LightSDK] OfflinePlugin: IndexedDB not available");return}return new Promise((e,t)=>{let n=indexedDB.open(qe,1);n.onerror=()=>{console.warn("[LightSDK] OfflinePlugin: Failed to open IndexedDB"),t(n.error)},n.onsuccess=()=>{this.db=n.result,e()},n.onupgradeneeded=r=>{let i=r.target.result,o=r.oldVersion;i.objectStoreNames.contains(v)||i.createObjectStore(v,{keyPath:"id"}).createIndex("timestamp","timestamp",{unique:!1})}})}setupNetworkListeners(){typeof window!="undefined"&&(this.isOnline=navigator.onLine,this.onOnline=()=>{console.info("[LightSDK] OfflinePlugin: Network online"),this.isOnline=!0,this.syncPendingEvents()},this.onOffline=()=>{console.info("[LightSDK] OfflinePlugin: Network offline"),this.isOnline=!1},window.addEventListener("online",this.onOnline),window.addEventListener("offline",this.onOffline))}generateId(){return`${Date.now()}-${Math.random().toString(36).substring(2,11)}`}async saveToIndexedDB(e){if(!this.db)return;let t=this.config.maxEvents||Z,n=await this.getEventCount();return n>=t&&await this.deleteOldestEvents(n-t+1),new Promise((r,i)=>{let a=this.db.transaction([v],"readwrite").objectStore(v),u={id:this.generateId(),event:{...e,offline:!0},timestamp:p()},c=a.add(u);c.onsuccess=()=>r(),c.onerror=()=>i(c.error)})}getEventCount(){return this.db?new Promise((e,t)=>{let i=this.db.transaction([v],"readonly").objectStore(v).count();i.onsuccess=()=>e(i.result),i.onerror=()=>t(i.error)}):Promise.resolve(0)}async deleteOldestEvents(e){if(!(!this.db||e<=0))return new Promise((t,n)=>{let a=this.db.transaction([v],"readwrite").objectStore(v).index("timestamp").openCursor(),u=0;a.onsuccess=c=>{let h=c.target.result;h&&un(a.error)})}async getAllStoredEvents(){return this.db?new Promise((e,t)=>{let o=this.db.transaction([v],"readonly").objectStore(v).index("timestamp").getAll();o.onsuccess=()=>{let a=o.result||[];a.sort((u,c)=>u.timestamp-c.timestamp),e(a)},o.onerror=()=>t(o.error)}):[]}async clearStoredEvents(){if(this.db)return new Promise((e,t)=>{let i=this.db.transaction([v],"readwrite").objectStore(v).clear();i.onsuccess=()=>e(),i.onerror=()=>t(i.error)})}async syncPendingEvents(){if(!(!this.isOnline||this.isSyncing)){this.isSyncing=!0,console.info("[LightSDK] OfflinePlugin: Syncing pending events");try{let e=0;for(;this.pendingEvents.length>0;){let n=this.pendingEvents.shift();try{this.client.captureEvent(n),e++}catch(r){console.error("[LightSDK] OfflinePlugin: Failed to re-enqueue memory event",r)}}let t=await this.getAllStoredEvents();if(t.length>0)for(let n of t)try{let r=n.event;this.client.captureEvent(r),e++}catch(r){console.error("[LightSDK] OfflinePlugin: Failed to re-enqueue event",r)}try{await this.client.flush()}catch(n){}await this.clearStoredEvents(),console.info(`[LightSDK] OfflinePlugin: Synced ${e} events`)}catch(e){console.error("[LightSDK] OfflinePlugin: Sync failed",e)}finally{this.isSyncing=!1}}}beforeReport(e){if(!this.isOnline){let n=this.config.maxEvents||Z;return this.pendingEvents.length>=n&&this.pendingEvents.shift(),this.pendingEvents.push(e),this.savePendingEventsToDB(),null}let t={...e};return delete t.offline,t}savePendingEventsToDB(){if(this.pendingEvents.length===0)return;let e=this.pendingEvents.splice(0,this.pendingEvents.length),t=0,n=()=>{if(t>=e.length)return;let r=e[t];this.saveToIndexedDB(r).then(()=>{t++,n()}).catch(i=>{console.error("[LightSDK] OfflinePlugin: Failed to save event offline",i),this.pendingEvents.unshift(...e.slice(t))})};n()}destroy(){typeof window!="undefined"&&(this.onOnline&&window.removeEventListener("online",this.onOnline),this.onOffline&&window.removeEventListener("offline",this.onOffline)),this.db&&(this.db.close(),this.db=null)}},ee=Y;var te=class{constructor(){this.name="sampling";this.version="1.0.0";this.config={rates:{error:1,performance:1,network:1,behavior:1}}}setup(e){this.client=e,this.loadConfig()}loadConfig(){let e=this.client.config;if(e&&b(e.sampling)){let t=e.sampling;"rates"in t&&b(t.rates)&&(this.config.rates={...this.config.rates,...t.rates})}}shouldSample(e){var r;let t=(r=this.client.config.sampleRate)!=null?r:1;if(t<=0)return!1;let n=this.getTypeRate(e);return t>=1?this.randomCheck(n):this.randomCheck(t*n)}getTypeRate(e){let t=this.config.rates||{},n=e.type;if(n==="count")return 1;let r=t[n];return r!==void 0?r:1}randomCheck(e){return e>=1?!0:e<=0?!1:Math.random()typeof i=="string"))||[];(n.includes("performance")||n.includes("all"))&&t.push(new z),(n.includes("network")||n.includes("all"))&&t.push(new Q),(n.includes("behavior")||n.includes("all"))&&t.push(new J),l("Index","Registering plugins",{count:t.length,plugins:t.map(i=>i.name)});for(let i of t)e.use(i);if(s.plugins)for(let i of s.plugins)typeof i=="object"&&i!==null&&"name"in i&&"setup"in i&&e.use(i);return e.init(),d=e,l("Index","init completed, globalClient set"),e}function pe(){return d}function he(s){if(l("Index","captureException called",{hasClient:!!d}),!d){console.warn("[LightSDK] SDK not initialized. Call LightSentry.init() first.");return}d.captureException(s)}function fe(s,e){if(l("Index","captureMessage called",{hasClient:!!d}),!d){console.warn("[LightSDK] SDK not initialized. Call LightSentry.init() first.");return}d.captureMessage(s,e)}function ge(s){if(l("Index","captureEvent called",{hasClient:!!d}),!d){console.warn("[LightSDK] SDK not initialized. Call LightSentry.init() first.");return}d.captureEvent(s)}function me(s){d==null||d.setUser(s)}function ve(s,e){d==null||d.setTag(s,e)}function ye(s){d==null||d.setTags(s)}function be(s,e){d==null||d.setExtra(s,e)}function Ee(s){d==null||d.addBreadcrumb(s)}async function we(){await(d==null?void 0:d.flush())}function Se(){d==null||d.disable()}function xe(){d==null||d.enable()}var Ne={init:de,getClient:pe,captureException:he,captureMessage:fe,captureEvent:ge,setUser:me,setTag:ve,setTags:ye,setExtra:be,addBreadcrumb:Ee,flush:we,disable:Se,enable:xe}; +"use strict";var G=Object.defineProperty;var Ye=Object.getOwnPropertyDescriptor;var Ze=Object.getOwnPropertyNames;var et=Object.prototype.hasOwnProperty;var tt=(s,e)=>{for(var t in e)G(s,t,{get:e[t],enumerable:!0})},nt=(s,e,t,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let r of Ze(e))!et.call(s,r)&&r!==t&&G(s,r,{get:()=>e[r],enumerable:!(n=Ye(e,r))||n.enumerable});return s};var rt=s=>nt(G({},"__esModule",{value:!0}),s);var ft={};tt(ft,{BehaviorPlugin:()=>de,Client:()=>re,ErrorPlugin:()=>se,InteractionPlugin:()=>be,NetworkPlugin:()=>ue,OfflinePlugin:()=>ge,PerformancePlugin:()=>ae,RouterPlugin:()=>ye,SamplingPlugin:()=>me,Span:()=>C,Transaction:()=>L,addBreadcrumb:()=>Ve,captureEvent:()=>Oe,captureException:()=>De,captureMessage:()=>Be,clearAnonymousId:()=>He,createBaggageFromTransaction:()=>W,dbStatusToSpanStatus:()=>te,default:()=>gt,disable:()=>Ge,enable:()=>Je,flush:()=>Qe,getAnonymousId:()=>qe,getClient:()=>Me,getCurrentSpan:()=>Ae,getCurrentTransaction:()=>$e,httpStatusToSpanStatus:()=>_,init:()=>_e,parseBaggage:()=>Ie,serializeBaggage:()=>X,setAnonymousId:()=>Ne,setExtra:()=>We,setSpan:()=>je,setTag:()=>ze,setTags:()=>Xe,setUser:()=>Fe,startSpan:()=>Ke,startTransaction:()=>Ue,statusToSpanStatus:()=>V});module.exports=rt(ft);function Ee(s){try{let e=s.match(/^(https?):\/\/([^@]+)@([^/]+)\/(.+)$/);if(!e)throw new Error("Invalid DSN format");let[,t,n,r,i]=e;return{protocol:t,publicKey:n,host:r,projectId:i}}catch(e){throw new Error(`Failed to parse DSN: ${e.message}`)}}function P(s){return`${s.protocol}://${s.host}/api/${s.projectId}/envelope/?sentry_key=${s.publicKey}`}function J(){return"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx".replace(/[x]/g,()=>(Math.random()*16|0).toString(16))}function p(){return Date.now()}function I(){return typeof crypto!="undefined"&&crypto.randomUUID?crypto.randomUUID().replace(/-/g,""):J()}function y(s){return s!==null&&typeof s=="object"&&!Array.isArray(s)}function M(s,e){return!e||e.length===0?!1:e.some(t=>typeof t=="string"?s.includes(t):t.test(s))}function it(s){let e=5381,t=s.length;for(;t;)e=e*33^s.charCodeAt(--t);return e>>>0}function Y(s){return it(s).toString(16)}function D(s,e,t=[]){let n=t.slice(0,3).map(i=>`${i.filename}:${i.lineno||0}`).join("|"),r=e.replace(/['"]?\d+['"]?/g,"").replace(/\s+/g," ").trim();return Y(`${s}:${r}:${n}`)}function B(s,e={}){if(!s)return[];let{captureNodeModules:t=!1,captureColumn:n=!0,relativePathOnly:r=!1,maxFrames:i}=e,o=[],a=s.split(` +`),c=typeof location!="undefined"?`${location.protocol}//${location.host}`:"";for(let f of a){let E=f.match(/^\s*at\s*(.+?)\s*\((.+?):(\d+):(\d+)\)\s*$/);if(E){let[,h,g,m,v]=E,S=g.includes("node_modules");if(!t&&S)continue;let b=g;r&&c&&g.startsWith(c)&&(b=g.substring(c.length)),o.push({filename:b,function:h,lineno:parseInt(m,10),colno:n?parseInt(v,10):void 0,in_app:!S})}else{let h=f.match(/^\s*at\s*(.+?)@(.+?):(\d+):(\d+)\s*$/);if(h){let[,m,v,S,b]=h,x=v.includes("node_modules");if(!t&&x)continue;let Te=v;r&&c&&v.startsWith(c)&&(Te=v.substring(c.length)),o.push({filename:Te,function:m||"",lineno:parseInt(S,10),colno:n?parseInt(b,10):void 0,in_app:!x});continue}let g=f.match(/^\s*at\s*(.+?):(\d+):(\d+)\s*$/);if(g){let[,m,v,S]=g,b=m.includes("node_modules");if(!t&&b)continue;let x=m;r&&c&&m.startsWith(c)&&(x=m.substring(c.length)),o.push({filename:x,lineno:parseInt(v,10),colno:n?parseInt(S,10):void 0,in_app:!b})}}}let d=o.reverse();return i!==void 0&&i>0?d.slice(0,i):d}var Z=!1;function O(s){Z=s}function u(s,e,t){if(!Z)return;let n=new Date().toISOString(),r=`[LightSDK][${s}]`;t!==void 0?console.log(`${r} ${n} ${e}`,t):console.log(`${r} ${n} ${e}`)}function R(s,e,t){if(!Z)return;let n=new Date().toISOString(),r=`[LightSDK][${s}][ERROR]`;t!==void 0?console.error(`${r} ${n} ${e}`,t):console.error(`${r} ${n} ${e}`)}var F="light_sentry_aid";function N(){if(typeof localStorage=="undefined")return null;try{let s=localStorage.getItem(F);return s||(s=I(),localStorage.setItem(F,s)),s}catch(s){return null}}function H(s){if(typeof localStorage=="undefined")return!1;try{return localStorage.setItem(F,s),!0}catch(e){return!1}}function we(){if(typeof localStorage=="undefined")return!1;try{return localStorage.removeItem(F),!0}catch(s){return!1}}function xe(s){return s.trackAnonymousUsers!==!1}function st(s){let e=[{name:"WeChat",pattern:/MicroMessenger\/([\d.]+)/i},{name:"QQ Browser",pattern:/QIBrowser\/([\d.]+)/i},{name:"UC Browser",pattern:/UCBrowser\/([\d.]+)/i},{name:"Edge",pattern:/Edg\/([\d.]+)/i},{name:"Edge",pattern:/Edge\/([\d.]+)/i},{name:"Opera",pattern:/OPR\/([\d.]+)/i},{name:"Opera",pattern:/Opera\/([\d.]+)/i},{name:"Firefox",pattern:/Firefox\/([\d.]+)/i},{name:"Safari",pattern:/Version\/([\d.]+).*Safari/i},{name:"Chrome",pattern:/Chrome\/([\d.]+)/i},{name:"IE",pattern:/MSIE ([\d.]+)/i},{name:"IE",pattern:/Trident.*rv:([\d.]+)/i}];for(let t of e){let n=s.match(t.pattern);if(n){let r=n[1]||"",i=r.split(".")[0]||"";return{name:t.name,version:r,major:i}}}return{name:"Unknown",version:"",major:""}}function ot(s){let e=[{name:"Windows 11",pattern:/Windows NT 10\.0.*Win64.*x64/i},{name:"Windows 10",pattern:/Windows NT 10\.0/i},{name:"Windows 8.1",pattern:/Windows NT 6\.3/i},{name:"Windows 8",pattern:/Windows NT 6\.2/i},{name:"Windows 7",pattern:/Windows NT 6\.1/i},{name:"Windows Vista",pattern:/Windows NT 6\.0/i},{name:"Windows XP",pattern:/Windows NT 5\.1/i},{name:"macOS",pattern:/Mac OS X ([\d_.]+)/i},{name:"iOS",pattern:/OS ([\d_.]+) like Mac OS X/i},{name:"Android",pattern:/Android ([\d.]+)/i},{name:"Android",pattern:/Android/i},{name:"Linux",pattern:/Linux/i}];for(let t of e){let n=s.match(t.pattern);if(n){let r=n[1]||"";return r&&(r=r.replace(/_/g,".")),{name:t.name,version:r}}}return{name:"Unknown",version:""}}function at(s){let e=/Mobile|Android|iPhone|iPod|BlackBerry|Windows Phone|Opera Mini/i.test(s),t=/Tablet|iPad|PlayBook|Kindle|Silk/i.test(s),n="desktop";t?n="tablet":e&&(n="mobile");let r="",i="",o=s.match(/iPhone/i),a=s.match(/iPad/i),c=s.match(/SM-([A-Z0-9]+)/i),d=s.match(/Pixel ([0-9A-Z]+)/i),f=s.match(/HUAWEI ([A-Z0-9]+)/i);return o?(r="Apple",i="iPhone"):a?(r="Apple",i="iPad"):c?(r="Samsung",i=c[1]):d?(r="Google",i=`Pixel ${d[1]}`):f&&(r="Huawei",i=f[1]),{type:n,vendor:r,model:i}}function ke(){let s=typeof navigator!="undefined"?navigator.userAgent:"",e=st(s),t=ot(s),n=at(s);return{browser:e,os:t,device:n,url:typeof location!="undefined"?location.href:"",referrer:typeof document!="undefined"?document.referrer:"",title:typeof document!="undefined"?document.title:"",language:typeof navigator!="undefined"?navigator.language:"",user_agent:s,screen_width:typeof screen!="undefined"?screen.width:0,screen_height:typeof screen!="undefined"?screen.height:0,viewport_width:typeof window!="undefined"?window.innerWidth:0,viewport_height:typeof window!="undefined"?window.innerHeight:0}}function w(){return typeof location!="undefined"?location.href:""}function Ce(){return typeof document!="undefined"?document.referrer:""}function k(s){if(!s)return s;if(/^\s*javascript:/i.test(s))return"javascript:[filtered]";try{let e=new URL(s),t=["password","passwd","pwd","token","access_token","refresh_token","api_key","apikey","key","secret","private_key","code","auth","id_token","idToken","session","session_id"],n=e.searchParams,r=!1;for(let i of Array.from(n.keys())){let o=i.toLowerCase().replace(/[-_]/g,"_");t.some(a=>o.includes(a))&&(n.set(i,"[Filtered]"),r=!0)}if(e.hash&&e.hash.length>1){let i=e.hash.substring(1);if(i.includes("=")){let o=new URLSearchParams(i),a=!1;for(let c of Array.from(o.keys())){let d=c.toLowerCase().replace(/[-_]/g,"_");t.some(f=>d.includes(f))&&(o.set(c,"[Filtered]"),a=!0)}a&&(e.hash="#"+o.toString(),r=!0)}}return r?e.toString():s}catch(e){return s}}function q(s,e=[]){return!e||e.length===0?!1:e.some(t=>{if(typeof t=="string"){if(t.includes("*")){let n=t.replace(/[.+?^${}()|[\]\\]/g,"\\$&").replace(/\*/g,".*");return new RegExp(n).test(s)}return s.includes(t)}return t.test(s)})}var ct={Chrome:"c",Safari:"s",Firefox:"f",Edge:"e",Opera:"o",IE:"i",WeChat:"w","QQ Browser":"q","UC Browser":"u","Mobile Chrome":"cm","Mobile Safari":"sm"},ut={"Windows 11":"w11","Windows 10":"w10","Windows 8.1":"w81","Windows 8":"w8","Windows 7":"w7","Windows Vista":"wv","Windows XP":"wxp",macOS:"m",iOS:"i",Android:"a",Linux:"l"};function ee(){let s=ke(),e=ct[s.browser.name]||s.browser.name.toLowerCase(),t=ut[s.os.name]||s.os.name.toLowerCase();return{browser:{name:e,version:s.browser.major},os:{name:t,version:s.os.version.split(".")[0]},device:{type:s.device.type,brand:s.device.vendor||void 0,model:s.device.model||void 0}}}function Re(){let s=ke(),e=`${s.browser.name}|${s.browser.major}|${s.os.name}|${s.os.version.split(".")[0]}|${s.device.type}|${s.device.vendor}|${s.device.model}|${s.language}`;return Y(e).substring(0,16)}var lt={enabled:!0,sampleRate:1,maxQueueSize:100,flushInterval:5e3,maxRetries:3,retryDelay:1e3,environment:"production",contextLevel:{fatal:{maxStackFrames:5,maxBreadcrumbs:20},error:{maxStackFrames:5,maxBreadcrumbs:10},warning:{maxStackFrames:3,maxBreadcrumbs:5},info:{maxStackFrames:0,maxBreadcrumbs:0},debug:{maxStackFrames:0,maxBreadcrumbs:0}}},U=class{constructor(e){this.contexts=null;this.contextId=null;this.contextReported=!1;this.config={...lt,...e}}markContextReported(){this.contextReported=!0}get(e){return this.config[e]}getAll(){return{...this.config}}set(e,t){this.config[e]=t}setUser(e){this.config.user=e||void 0}setTags(e){this.config.tags={...this.config.tags||{},...e}}setTag(e,t){this.config.tags||(this.config.tags={}),this.config.tags[e]=t}setExtra(e,t){this.config.extra||(this.config.extra={}),this.config.extra[e]=t}isIgnoredError(e){return M(e,this.config.ignoreErrors||[])}shouldSample(){var t;let e=(t=this.config.sampleRate)!=null?t:1;return e>=1?!0:e<=0?!1:Math.random()({...g})):void 0}:void 0}}if(e.breadcrumbs&&(n.breadcrumbs=e.breadcrumbs.map(h=>({...h}))),e.user&&(n.user={...e.user}),e.contexts&&(n.contexts={...e.contexts}),this.config.release&&(n.release=this.config.release),this.config.environment&&(n.environment=this.config.environment),n.platform="javascript",this.config.user&&(n.user=this.config.user),this.config.tags&&(n.tags={...this.config.tags,...e.tags||{}}),n.request?n.request.url||(n.request.url=w()):n.request={url:w(),referrer:Ce()},this.contextId||(this.contextId=Re()),n.context_id=this.contextId,!(((o=this.config.user)==null?void 0:o.id)||((a=e.user)==null?void 0:a.id))&&xe(this.config)){let h=N();h&&(n.anonymousId=h)}let i=this.applyContextLevel(n);return t&&!this.contextReported&&(this.contexts||(this.contexts=ee()),i.contexts=this.contexts,i.env={b:(c=this.contexts.browser)==null?void 0:c.name,bv:(d=this.contexts.browser)==null?void 0:d.version,os:(f=this.contexts.os)==null?void 0:f.name,osv:(E=this.contexts.os)==null?void 0:E.version}),i}applyContextLevel(e){let t=this.config.contextLevel;if(!t)return e;let n=e.level||"error",r=t[n]||t.error,i={...e};if("exception"in e&&e.exception&&typeof e.exception=="object"){let o=e.exception;if(o.stacktrace&&typeof o.stacktrace=="object"){let a=o.stacktrace;Array.isArray(a.frames)&&(r.maxStackFrames===0?delete i.exception:i.exception={...o,stacktrace:{...a,frames:a.frames.slice(0,r.maxStackFrames)}})}}return e.breadcrumbs&&Array.isArray(e.breadcrumbs)&&(r.maxBreadcrumbs===0?delete i.breadcrumbs:i.breadcrumbs=e.breadcrumbs.slice(-r.maxBreadcrumbs)),i}};var $=class{constructor(){this.handlers=new Map}on(e,t){this.handlers.has(e)||this.handlers.set(e,[]),this.handlers.get(e).push(t)}off(e,t){let n=this.handlers.get(e);if(n){let r=n.indexOf(t);r>-1&&n.splice(r,1)}}emit(e,...t){let n=this.handlers.get(e);if(n)for(let r of n)try{r(...t)}catch(i){console.error("[LightSDK] EventBus handler error:",i)}}once(e,t){let n=(...r)=>{this.off(e,n),t(...r)};this.on(e,n)}destroy(){this.handlers.clear()}};var A=class{constructor(e,t,n,r,i){this.queue=[];this.timer=null;this.lastFlushTime=0;this.isFlushing=!1;this.dedupeMap=new Map;this.pendingCounts=new Map;this.errorRateWindow={};this.paused=!1;this.pauseTimer=null;this.maxSize=e,this.flushInterval=t,this.eventBus=n,this.flushCallback=r,this.syncFlushCallback=i}start(){this.startTimer(),this.setupVisibilityListener()}startTimer(){this.timer||(this.timer=setInterval(()=>{(this.queue.length>0||this.pendingCounts.size>0)&&this.flush()},this.flushInterval))}setupVisibilityListener(){this.onVisibilityChange=()=>{document.hidden&&(this.queue.length>0||this.pendingCounts.size>0)&&this.flushSync()},typeof document!="undefined"&&document.addEventListener("visibilitychange",this.onVisibilityChange),this.onBeforeUnload=()=>{(this.queue.length>0||this.pendingCounts.size>0)&&this.flushSync()},this.onPagehide=()=>{(this.queue.length>0||this.pendingCounts.size>0)&&this.flushSync()},typeof window!="undefined"&&(window.addEventListener("beforeunload",this.onBeforeUnload),window.addEventListener("pagehide",this.onPagehide))}checkInfiniteLoop(e){let t=p(),n=t-1e3;this.errorRateWindow[e]||(this.errorRateWindow[e]=[]);let r=this.errorRateWindow[e];for(r.push(t);r.length>0&&r[0]10?(this.paused||(console.warn("[LightSDK] Infinite loop detected, pausing SDK for 60s",{fingerprint:e,count:r.length}),this.eventBus.emit("error",new Error("Infinite loop detected")),this.paused=!0,this.pauseTimer&&clearTimeout(this.pauseTimer),this.pauseTimer=setTimeout(()=>{this.paused=!1,this.errorRateWindow={},console.info("[LightSDK] Resumed after infinite loop detection")},6e4)),!0):!1}enqueue(e){if(u("EventQueue","enqueue called",{type:e.type,level:e.level,message:"message"in e?e.message:void 0}),this.paused){u("EventQueue","enqueue skipped: queue paused (infinite loop detected)");return}this.cleanupExpiredDedupeEntries();let t=this.getDedupeKey(e);if(t){if(this.checkInfiniteLoop(t)){u("EventQueue","enqueue skipped: infinite loop detected",{fingerprint:t});return}let n=p(),r=this.dedupeMap.get(t);if(r)if(n-r.lastTime<6e4){if(r.count>=3){if(!this.pendingCounts.has(t))this.pendingCounts.set(t,{count:1,ts_start:n,ts_end:n});else{let i=this.pendingCounts.get(t);i.count++,i.ts_end=n}u("EventQueue","enqueue skipped: deduped (count >= 3)",{fingerprint:t,count:r.count});return}r.count++,r.lastTime=n,u("EventQueue","Dedup count incremented",{fingerprint:t,count:r.count})}else this.dedupeMap.set(t,{count:1,lastTime:n,firstReported:!0}),this.pendingCounts.delete(t),u("EventQueue","Dedup entry reset (expired)",{fingerprint:t});else this.dedupeMap.set(t,{count:1,lastTime:n,firstReported:!1}),u("EventQueue","New dedup entry created",{fingerprint:t})}this.queue.push(e),u("EventQueue","Event added to queue",{queueSize:this.queue.length}),this.eventBus.emit("event",e),this.queue.length>=this.maxSize&&(u("EventQueue","Queue reached maxSize, triggering flush",{maxSize:this.maxSize}),this.flush())}cleanupExpiredDedupeEntries(){if(Math.random()>.1)return;let e=p(),t=6e4;for(let[n,r]of this.dedupeMap)e-r.lastTime>t&&this.dedupeMap.delete(n)}buildCountEvents(){let e=[];for(let[t,n]of this.pendingCounts.entries()){let r={type:"count",fingerprint:t,count:n.count,ts_start:n.ts_start,ts_end:n.ts_end,timestamp:p(),level:"info"};e.push(r)}return e}getDedupeKey(e){if(e.type==="error"){let t=e;return t.fingerprint||t.message}return null}async flush(){if(u("EventQueue","flush called",{queueSize:this.queue.length,pendingCounts:this.pendingCounts.size,isFlushing:this.isFlushing}),this.queue.length===0&&this.pendingCounts.size===0){u("EventQueue","flush skipped: queue is empty");return}if(this.isFlushing){u("EventQueue","flush skipped: already flushing");return}this.isFlushing=!0;let e=this.queue.splice(0,this.queue.length),t=this.buildCountEvents(),n=[...e,...t];u("EventQueue","flush events to callback",{total:n.length,events:e.length,countEvents:t.length}),this.lastFlushTime=p(),this.eventBus.emit("report",n);try{await this.flushCallback(n),this.pendingCounts.clear(),u("EventQueue","flush completed successfully"),this.eventBus.emit("reported",n)}catch(r){throw u("EventQueue","flush failed, returning events to queue",{error:r instanceof Error?r.message:String(r)}),e.forEach(i=>this.queue.unshift(i)),r}finally{this.isFlushing=!1}}flushSync(){if(this.queue.length===0&&this.pendingCounts.size===0)return;let e=this.queue.splice(0,this.queue.length),t=new Map(this.pendingCounts),n=this.buildCountEvents(),r=[...e,...n];this.lastFlushTime=p(),this.eventBus.emit("report",r);try{this.syncFlushCallback(r),this.pendingCounts.clear(),this.eventBus.emit("reported",r)}catch(i){console.error("[LightSDK] Sync flush failed",i),e.forEach(o=>this.queue.unshift(o));for(let[o,a]of t)this.pendingCounts.has(o)||this.pendingCounts.set(o,a)}}size(){return this.queue.length}destroy(){this.timer&&(clearInterval(this.timer),this.timer=null),this.pauseTimer&&(clearTimeout(this.pauseTimer),this.pauseTimer=null),typeof document!="undefined"&&this.onVisibilityChange&&document.removeEventListener("visibilitychange",this.onVisibilityChange),typeof window!="undefined"&&(this.onBeforeUnload&&window.removeEventListener("beforeunload",this.onBeforeUnload),this.onPagehide&&window.removeEventListener("pagehide",this.onPagehide)),this.queue=[],this.dedupeMap.clear(),this.pendingCounts.clear(),this.errorRateWindow={}}};var Le={event_id:"eid",timestamp:"ts",start_timestamp:"sts",type:"t",level:"l",message:"m",platform:"p",release:"r",environment:"e",fingerprint:"fp",context_id:"cid",user:"u",tags:"tg",exception:"ex",request:"req",contexts:"ctx",breadcrumbs:"bc",transaction:"tx",duration:"d",spans:"sp",extra:"xt"},Bt=Object.fromEntries(Object.entries(Le).map(([s,e])=>[e,s]));function Pe(s){if(!s||typeof s!="object")return s;let e={};for(let[t,n]of Object.entries(s)){let r=Le[t]||t;e[r]=n}return e}var j=class{constructor(e,t,n){this.useShortFields=!0;this.dsn=e,this.maxRetries=t,this.retryDelay=n}async report(e){if(u("Reporter","report called",{eventCount:e.length}),e.length===0){u("Reporter","report skipped: empty events");return}let t=this.buildEnvelope(e),n=P(this.dsn);u("Reporter","Envelope built",{envelopeSize:t.length,url:n});let r=0;for(;r<=this.maxRetries;)try{u("Reporter",`Sending request (attempt ${r+1}/${this.maxRetries+1})`),await this.send(t,!1),u("Reporter","Request succeeded");return}catch(i){let o=i.status;if(R("Reporter",`Request failed (attempt ${r+1})`,{status:o,error:i}),o&&o>=400&&o<500)throw i;if(r++,r>this.maxRetries)throw R("Reporter","All retries exhausted"),i;let a=Math.min(this.retryDelay*Math.pow(2,r-1),5e3);u("Reporter",`Retrying in ${a}ms`),await this.delay(a)}}reportSync(e){if(e.length===0)return;let t=this.buildEnvelope(e);try{if(this.sendSync(t))return}catch(n){}this.sendViaImage(t)}buildEnvelope(e){let t=this.extractSharedMeta(e),n={event_id:J(),sent_at:new Date().toISOString(),meta:t};this.useShortFields&&(n._sf=1);let r=this.applyRelativeTimestamps(e,n),o=[JSON.stringify(n)];for(let a of r){let c=this.stripSharedFields(a,t);this.useShortFields&&(c=Pe(c));let d=JSON.stringify(c),f=JSON.stringify({type:this.getEnvelopeType(a),length:d.length});o.push(f,d)}return o.join(` +`)}applyRelativeTimestamps(e,t){if(e.length<=1)return e;let n=[],r=e[0].timestamp?new Date(e[0].timestamp).getTime():Date.now();t._rt=1,t._bt=r;for(let i=0;io.release===t.release)&&(n.release=t.release),t.environment&&e.every(o=>o.environment===t.environment)&&(n.environment=t.environment),t.user&&e.every(o=>JSON.stringify(o.user)===JSON.stringify(t.user))&&(n.user=t.user);let r=t.env;return r&&(n.env=r),n}stripSharedFields(e,t){let n={...e};return t.release&&n.release===t.release&&delete n.release,t.environment&&n.environment===t.environment&&delete n.environment,t.user&&JSON.stringify(n.user)===JSON.stringify(t.user)&&delete n.user,t.env&&delete n.env,n}getEnvelopeType(e){switch(e.type){case"error":return"event";default:return e.type}}async send(e,t=!1){let n=P(this.dsn);if(navigator.sendBeacon)try{let r=new Blob([e],{type:"application/x-sentry-envelope"});if(navigator.sendBeacon(n,r))return}catch(r){}if(typeof fetch=="function")try{let r=new AbortController,i=setTimeout(()=>r.abort(),1e4),o=await fetch(n,{method:"POST",body:e,headers:{"Content-Type":"application/x-sentry-envelope"},keepalive:!0,signal:r.signal});if(clearTimeout(i),o.ok)return;let a=new Error(`HTTP ${o.status}`);throw a.status=o.status,a}catch(r){throw r}if(typeof XMLHttpRequest!="undefined")return new Promise((r,i)=>{let o=new XMLHttpRequest;o.open("POST",n,!t),o.setRequestHeader("Content-Type","application/x-sentry-envelope"),o.timeout=1e4,o.onload=()=>{if(o.status>=200&&o.status<300)r();else{let a=new Error(`HTTP ${o.status}`);a.status=o.status,i(a)}},o.onerror=()=>i(new Error("Network error")),o.ontimeout=()=>i(new Error("Request timeout")),o.send(e)});throw new Error("No transport available")}sendSync(e){let t=P(this.dsn);if(navigator.sendBeacon)try{let n=new Blob([e],{type:"application/x-sentry-envelope"});return navigator.sendBeacon(t,n)}catch(n){return!1}if(typeof XMLHttpRequest!="undefined")try{let n=new XMLHttpRequest;return n.open("POST",t,!1),n.setRequestHeader("Content-Type","application/x-sentry-envelope"),n.send(e),n.status>=200&&n.status<300}catch(n){return!1}return!1}sendViaImage(e){try{let t=P(this.dsn),n=new Image,r=encodeURIComponent(btoa(e)),i=t.includes("?")?"&":"?";return n.src=t+i+"sentry_data="+r.substring(0,2e3),!0}catch(t){return!1}}delay(e){return new Promise(t=>setTimeout(t,e))}};var K=class{constructor(e){this.plugins=new Map;this.client=e}add(e){if(!this.plugins.has(e.name)){this.plugins.set(e.name,e);try{e.setup(this.client)}catch(t){console.error(`[LightSDK] Plugin "${e.name}" setup error:`,t)}}}remove(e){let t=this.plugins.get(e);if(t){if(t.destroy)try{t.destroy()}catch(n){console.error(`[LightSDK] Plugin "${e}" destroy error:`,n)}this.plugins.delete(e)}}get(e){return this.plugins.get(e)}has(e){return this.plugins.has(e)}applyBeforeReport(e){let t=e;for(let n of this.plugins.values())if(n.beforeReport)try{let r=n.beforeReport(t);if(r===null)return null;t=r}catch(r){console.error(`[LightSDK] Plugin "${n.name}" beforeReport error:`,r)}return t}applyAfterReport(e){for(let t of this.plugins.values())if(t.afterReport)try{t.afterReport(e)}catch(n){console.error(`[LightSDK] Plugin "${t.name}" afterReport error:`,n)}}destroy(){for(let e of this.plugins.values())if(e.destroy)try{e.destroy()}catch(t){console.error(`[LightSDK] Plugin "${e.name}" destroy error:`,t)}this.plugins.clear()}};var z="sentry-";function X(s){let e=[];for(let[n,r]of Object.entries(s)){if(r==null||r==="")continue;let i=n.startsWith(z)?n:`${z}${n}`;e.push(`${i}=${encodeURIComponent(String(r))}`)}let t=e.join(",");if(t.length>8192){t=t.substring(0,8192);let n=t.lastIndexOf(",");n>0&&(t=t.substring(0,n))}return t}function Ie(s){let e={};if(!s)return e;let t=s.split(",");for(let n of t){let r=n.indexOf("=");if(r===-1)continue;let i=n.substring(0,r).trim(),o=decodeURIComponent(n.substring(r+1).trim()),a=i;i.startsWith(z)&&(a=i.substring(z.length)),a&&(e[a]=o)}return e}function W(s,e){let t={trace_id:s};return e!=null&&e.dsnPublicKey&&(t.public_key=e.dsnPublicKey),(e==null?void 0:e.sampled)!==void 0&&(t.sampled=e.sampled?"true":"false"),(e==null?void 0:e.sampleRate)!==void 0&&(t.sample_rate=String(e.sampleRate)),e!=null&&e.user&&(e.user.id&&(t.user_id=e.user.id),e.user.segment&&(t.user_segment=e.user.segment)),e!=null&&e.release&&(t.release=e.release),e!=null&&e.environment&&(t.environment=e.environment),t}function dt(){return I().replace(/-/g,"")}function pt(){return I().replace(/-/g,"").substring(0,16)}function _(s){return s>=200&&s<300?"ok":s===400?"invalid_argument":s===401?"unauthenticated":s===403?"permission_denied":s===404?"not_found":s===409?"already_exists":s===429?"resource_exhausted":s>=400&&s<500?"invalid_argument":s>=500&&s<600?"internal_error":"unknown_error"}function te(s){if(s==null||s==="")return"unknown_error";let e=typeof s=="string"?parseInt(s,10):s;return e===0||e===1?"ok":e>=10&&e<20?"invalid_argument":e>=20&&e<30?"not_found":e>=30&&e<40?"already_exists":e>=50?"internal_error":"unknown_error"}function V(s,e){if(s===void 0)return"unknown_error";if(typeof s=="string"){let t=s.toLowerCase();if(t==="ok"||t==="success")return"ok";if(t==="cancelled"||t==="canceled")return"cancelled";if(t==="deadline_exceeded")return"deadline_exceeded";if(t==="not_found")return"not_found";if(t==="already_exists")return"already_exists";if(t==="permission_denied")return"permission_denied";if(t==="resource_exhausted")return"resource_exhausted";if(t==="failed_precondition")return"failed_precondition";if(t==="invalid_argument")return"invalid_argument";if(t==="unauthenticated")return"unauthenticated";if(t==="internal_error")return"internal_error";let n=parseInt(s,10);return isNaN(n)?"unknown_error":V(n,e)}if(typeof s=="number"){if(s>=200&&s<600)return _(s);if(e!=null&&e.startsWith("db"))return te(s);if(s===0)return"ok";if(s>0)return"unknown_error"}return"unknown_error"}var C=class s{constructor(e,t,n){this.tags={};this.data={};this._isFinished=!1;this.traceId=e.traceId||dt(),this.spanId=e.spanId||pt(),this.parentSpanId=e.parentSpanId,this.op=e.op,this.description=e.description,this.status=e.status,this.tags={...e.tags},this.data={...e.data},this.startTimestamp=e.startTimestamp||p(),this.transaction=t,this._client=n}setTag(e,t){return this.tags[e]=t,this}setData(e,t){return this.data[e]=t,this}setStatus(e){return this.status=e,this}setHttpStatus(e){return this.setStatus(_(e)),this.setTag("http.status_code",String(e)),this}setStatusFromResponse(e,t){let n=V(e,this.op);return this.setStatus(n),t&&e!==void 0&&this.setTag(t,String(e)),this}startChild(e={}){let t=this.transaction,n=(t==null?void 0:t.sampled)!==!1,r=new s({...e,traceId:this.traceId,parentSpanId:this.spanId},t,this._client);return t&&n&&t._addSpan(r),r}finish(e){var t;if(!this._isFinished&&(this._isFinished=!0,this.endTimestamp=e||p(),this._client)){let n=this._client;(t=n.tracingManager)!=null&&t.onSpanFinished&&n.tracingManager.onSpanFinished(this)}}toTraceparent(){var n;let e=(n=this.transaction)==null?void 0:n.sampled,t=e===void 0?"":e?"1":"0";return t?`${this.traceId}-${this.spanId}-${t}`:`${this.traceId}-${this.spanId}`}toJSON(){return{trace_id:this.traceId,span_id:this.spanId,parent_span_id:this.parentSpanId,op:this.op,description:this.description,status:this.status,tags:Object.keys(this.tags).length>0?{...this.tags}:void 0,data:Object.keys(this.data).length>0?{...this.data}:void 0,start_timestamp:this.startTimestamp,timestamp:this.endTimestamp||this.startTimestamp}}},L=class extends C{constructor(t,n,r,i,o,a){super(t,void 0,n);this.spans=[];this.maxSpans=1e3;this._droppedSpans=0;this.name=t.name,this.type=t.type,this.sampled=t.sampled,this.transaction=this,this._dsnPublicKey=r,this._release=i,this._environment=o,a!==void 0&&(this.maxSpans=a)}_addSpan(t){if(this.spans.length>=this.maxSpans){this._droppedSpans++;return}this.spans.push(t)}_ensureBaggage(){return this._baggage||(this._baggage=W(this.traceId,{dsnPublicKey:this._dsnPublicKey,sampled:this.sampled,release:this._release,environment:this._environment})),this._baggage}setBaggage(t,n){let r=this._ensureBaggage();return r[t]=n,this}setUserBaggage(t,n){let r=this._ensureBaggage();return t!==void 0?r.user_id=t:delete r.user_id,n!==void 0?r.user_segment=n:delete r.user_segment,this}toBaggage(){let t=this._ensureBaggage();return X(t)}getBaggage(){return this._baggage}finish(t){var n;if(!this._isFinished){if(super.finish(t),this._client&&this.sampled){let r=this.toEvent();this._client.captureEvent(r)}if(this._client){let r=this._client;(n=r.tracingManager)!=null&&n.onTransactionFinished&&r.tracingManager.onTransactionFinished(this)}}}_getSource(){switch(this.type){case"pageload":return"url";case"navigation":return"route";case"user-interaction":return"ui";default:return"custom"}}toEvent(){let t=this.toJSON(),n={...t.data},r=n.measurements;return delete n.measurements,{type:"transaction",transaction:this.name,transaction_info:{source:this._getSource()},level:"info",timestamp:t.timestamp,start_timestamp:t.start_timestamp,spans:this.spans.map(i=>i.toJSON()),contexts:{trace:{trace_id:this.traceId,span_id:this.spanId,parent_span_id:this.parentSpanId,op:this.op,status:this.status}},tags:t.tags,extra:Object.keys(n).length>0?n:void 0,measurements:r,platform:"javascript"}}toJSON(){return{...super.toJSON(),transaction:this.name,type:this.type,spans:this.spans.map(n=>n.toJSON()),sampled:this.sampled}}};var Q=class{constructor(e,t,n){this.currentTransaction=null;this.spanStack=[];this.config=e,this._client=t,this.dsnPublicKey=n}updateConfig(e){var t,n;this.config=e,this.currentTransaction&&this.currentTransaction.setUserBaggage((t=e.user)==null?void 0:t.id,(n=e.user)==null?void 0:n.segment)}shouldSample(e,t){var i;let n=this.config.tracesSampler;if(n){let o={...e,parentSampled:t},a=n(o);if(typeof a=="boolean")return a;let c=Math.max(0,Math.min(1,a));return c===0?!1:c===1?!0:Math.random()=1?!0:r<=0?!1:Math.random()0?this.spanStack[this.spanStack.length-1]:null}setCurrentSpan(e){e===null?this.spanStack.length>1&&this.spanStack.pop():this.spanStack.push(e)}startSpan(e){let t=this.getCurrentSpan();if(!t&&!e.traceId)return u("TracingManager","startSpan skipped: no active span and no traceId"),null;let n;return t?n=t.startChild(e):(n=new C({...e,parentSpanId:e.parentSpanId}),this.currentTransaction&&(this.currentTransaction.sampled!==!1&&this.currentTransaction._addSpan(n),n.transaction=this.currentTransaction)),this.spanStack.push(n),u("TracingManager","Span started",{op:n.op,description:n.description,spanId:n.spanId,parentSpanId:n.parentSpanId,stackDepth:this.spanStack.length}),n}onSpanFinished(e){let t=this.spanStack.lastIndexOf(e);t!==-1&&this.spanStack.splice(t,1),this.spanStack.length===0&&this.currentTransaction&&(this.spanStack=[this.currentTransaction]),u("TracingManager","Span finished",{op:e.op,description:e.description,spanId:e.spanId,stackDepth:this.spanStack.length})}onTransactionFinished(e){this.currentTransaction===e&&(this.currentTransaction=null,this.spanStack=[]),u("TracingManager","Transaction finished",{name:e.name,traceId:e.traceId,spanCount:e.spans.length,sampled:e.sampled})}finishSpan(e){e.finish()}finishTransaction(e){e.finish()}destroy(){if(this.currentTransaction)try{this.currentTransaction.setStatus("aborted"),this.currentTransaction.finish()}catch(e){}this.currentTransaction=null,this.spanStack=[]}};var ne=class{constructor(e){this.breadcrumbs=[];this.enabled=!0;var t,n,r,i;if(!e.dsn)throw new Error("DSN is required");O(e.debug===!0),u("Client","Initializing SDK",{dsn:e.dsn,debug:e.debug,enabled:e.enabled!==!1}),this.dsn=Ee(e.dsn),this.configManager=new U(e),this.eventBus=new $,this.reporter=new j(this.dsn,(t=this.configManager.get("maxRetries"))!=null?t:3,(n=this.configManager.get("retryDelay"))!=null?n:1e3),this.pluginManager=new K(this),this.tracingManager=new Q(e,this,this.dsn.publicKey),this.queue=new A((r=this.configManager.get("maxQueueSize"))!=null?r:100,(i=this.configManager.get("flushInterval"))!=null?i:5e3,this.eventBus,async o=>this.flushEvents(o),o=>this.syncFlushEvents(o)),this.enabled=this.configManager.get("enabled")!==!1,u("Client","SDK initialized",{enabled:this.enabled})}get maxBreadcrumbs(){var e;return(e=this.configManager.get("maxBreadcrumbs"))!=null?e:20}get config(){return this.configManager.getAll()}init(){this.enabled&&(this.queue.start(),this.emit("ready"))}async flushEvents(e){u("Client","flushEvents start",{eventCount:e.length});let t=[];for(let i of e){let o=this.pluginManager.applyBeforeReport(i);o?t.push(o):u("Client","Event filtered by beforeReport plugin",{type:i.type,message:"message"in i?i.message:void 0})}if(t.length===0){u("Client","flushEvents: all events filtered by beforeReport");return}let n=!0,r=[];for(let i of t){let o=this.configManager.applyToEvent(i,n);n=!1;let a=this.configManager.get("beforeSend"),c=a?a(o):o;if(!c){u("Client","Event filtered by beforeSend",{type:i.type});continue}r.push(c)}if(r.length===0){u("Client","flushEvents: all events filtered by beforeSend");return}u("Client","Reporting events",{count:r.length}),await this.reporter.report(r),u("Client","Report completed successfully"),this.configManager.markContextReported();for(let i of r)this.pluginManager.applyAfterReport(i)}syncFlushEvents(e){let t=[];for(let i of e){let o=this.pluginManager.applyBeforeReport(i);o&&t.push(o)}if(t.length===0)return;let n=!0,r=[];for(let i of t){let o=this.configManager.applyToEvent(i,n);n=!1;let a=this.configManager.get("beforeSend"),c=a?a(o):o;c&&r.push(c)}r.length!==0&&(this.reporter.reportSync(r),this.configManager.markContextReported())}on(e,t){this.eventBus.on(e,t)}off(e,t){this.eventBus.off(e,t)}emit(e,...t){this.eventBus.emit(e,...t)}captureException(e){if(u("Client","captureException called",{error:e instanceof Error?e.message:String(e)}),!this.enabled){u("Client","captureException skipped: SDK disabled");return}let t=this.buildErrorEvent(e);if(u("Client","Error event built",{type:t.type,message:t.message,fingerprint:t.fingerprint}),this.configManager.isIgnoredError(t.message)){u("Client","captureException skipped: error ignored by ignoreErrors");return}this.attachTraceContext(t),t.breadcrumbs=[...this.breadcrumbs],u("Client","Enqueue error event",{breadcrumbs:this.breadcrumbs.length}),this.queue.enqueue(t)}captureMessage(e,t="info"){if(!this.enabled)return;let n={type:"error",level:t,message:e,timestamp:p(),breadcrumbs:[...this.breadcrumbs]};this.configManager.isIgnoredError(e)||(this.attachTraceContext(n),this.queue.enqueue(n))}captureEvent(e){if(!this.enabled)return;let t={timestamp:p(),level:"info",breadcrumbs:[...this.breadcrumbs],...e};this.attachTraceContext(t),this.queue.enqueue(t)}attachTraceContext(e){let t=this.tracingManager.getCurrentSpan(),n=this.tracingManager.getCurrentTransaction();if(t||n){let r=(t==null?void 0:t.traceId)||(n==null?void 0:n.traceId),i=(t==null?void 0:t.spanId)||(n==null?void 0:n.spanId),o=t==null?void 0:t.parentSpanId,a=(t==null?void 0:t.op)||(n==null?void 0:n.op),c=(t==null?void 0:t.status)||(n==null?void 0:n.status);e.contexts={...e.contexts,trace:{trace_id:r||"",span_id:i||"",parent_span_id:o,op:a,status:c}}}}buildErrorEvent(e){let t=p();if(e instanceof Error){let r=B(e.stack,{maxFrames:5}),i=D(e.name,e.message,r);return{type:"error",level:"error",message:e.message,timestamp:t,exception:{type:e.name,value:e.message,stacktrace:{frames:r}},fingerprint:i}}return{type:"error",level:"error",message:String(e),timestamp:t}}setUser(e){this.configManager.setUser(e),this.tracingManager.updateConfig(this.configManager.getAll())}setAnonymousId(e){H(e)}startTransaction(e){if(!this.enabled)return null;let t=this.tracingManager.startTransaction(e);return t&&t.sampled&&u("Client","Transaction started and sampled",{name:t.name,traceId:t.traceId}),t}getCurrentTransaction(){return this.tracingManager.getCurrentTransaction()}getCurrentSpan(){return this.tracingManager.getCurrentSpan()}setSpan(e){this.tracingManager.setCurrentSpan(e)}startSpan(e){return this.enabled?this.tracingManager.startSpan(e):null}setTag(e,t){this.configManager.setTag(e,t)}setTags(e){this.configManager.setTags(e)}setExtra(e,t){this.configManager.setExtra(e,t)}addBreadcrumb(e){let t={...e,timestamp:p()};this.breadcrumbs.push(t),this.breadcrumbs.length>this.maxBreadcrumbs&&this.breadcrumbs.shift()}async flush(){await this.queue.flush()}disable(){this.enabled=!1}enable(){this.enabled=!0}use(e){this.pluginManager.add(e)}destroy(){this.pluginManager.destroy(),this.tracingManager.destroy(),this.queue.destroy(),this.eventBus.destroy(),this.breadcrumbs=[]}},re=ne;var ie=class{constructor(){this.name="error";this.version="1.0.0";this.config={maxStackFrames:5,captureNodeModules:!1,captureColumn:!0,relativePathOnly:!1,resourceSampleRate:.1}}setup(e){this.client=e,this.loadConfig(),this.setupGlobalError(),this.setupUnhandledRejection(),this.setupResourceError()}loadConfig(){let e=this.client.config;e&&y(e.error)&&(this.config={...this.config,...e.error}),e.ignoreErrors&&(this.config.ignoreErrors=[...this.config.ignoreErrors||[],...e.ignoreErrors]),e.ignoreUrls&&(this.config.ignoreUrls=[...this.config.ignoreUrls||[],...e.ignoreUrls]),e.includePaths&&(this.config.includePaths=[...this.config.includePaths||[],...e.includePaths])}shouldIgnoreError(e){return e?M(e,this.config.ignoreErrors||[]):!1}shouldIgnoreScriptUrl(e){return q(e,this.config.ignoreUrls||[])}shouldIncludePath(e){let t=this.config.includePaths||[];return t.length===0?!0:e.some(n=>t.some(r=>{var i;return typeof r=="string"?(i=n.filename)==null?void 0:i.includes(r):r.test(n.filename||"")}))}shouldSample(){var t;let e=(t=this.config.sampleRate)!=null?t:1;return e>=1?!0:e<=0?!1:Math.random()=1?!0:e<=0?!1:Math.random(){try{if(this.originalOnError&&this.originalOnError.call(window,e,t,n,r,i),t&&this.shouldIgnoreScriptUrl(t))return!1;let o=this.buildErrorEvent(i||e,t,n,r);o&&this.client.captureEvent(o)}catch(o){R("ErrorPlugin","Global error handler error",o)}return!1})}setupUnhandledRejection(){typeof window!="undefined"&&(this.onUnhandledRejection=e=>{try{let t=e.reason,n=this.extractUrlFromReason(t);if(n&&this.shouldIgnoreScriptUrl(n))return;let r=this.buildErrorEvent(t);r&&(r.type==="error"&&(r.tags={...r.tags||{},unhandled:"true",promise:"true"}),this.client.captureEvent(r))}catch(t){R("ErrorPlugin","Unhandledrejection handler error",t)}},window.addEventListener("unhandledrejection",this.onUnhandledRejection))}extractUrlFromReason(e){if(e instanceof Error&&e.stack){let t=e.stack.match(/at\s+(?:.+?\s+)?\((https?:\/\/[^:]+):\d+:\d+\)/);if(t)return t[1];let n=e.stack.match(/(https?:\/\/[^\s)]+):\d+:\d+/);if(n)return n[1]}return null}setupResourceError(){typeof window!="undefined"&&(this.onResourceError=e=>{var i;let t=e.target;if(!t)return;let n=(i=t.tagName)==null?void 0:i.toLowerCase(),r=t.src||t.href;if(n&&r&&["img","script","link","audio","video"].includes(n))try{if(this.shouldIgnoreScriptUrl(r)||!this.shouldSampleResource())return;let o=`resource:${n}`,a=k(r);this.client.captureEvent({type:"error",level:"warning",message:`Resource load failed: ${n} ${a}`,timestamp:p(),fingerprint:o,tags:{resource_type:n,resource_url:a},exception:{type:"ResourceError",value:`Failed to load ${n} resource`}})}catch(o){R("ErrorPlugin","Resource error handler error",o)}},window.addEventListener("error",this.onResourceError,!0))}buildErrorEvent(e,t,n,r){let i=p();if(e instanceof Error){if(this.shouldIgnoreError(e.message))return null;let c=B(e.stack,{captureNodeModules:this.config.captureNodeModules,captureColumn:this.config.captureColumn,relativePathOnly:this.config.relativePathOnly,maxFrames:this.config.maxStackFrames});if(!this.shouldIncludePath(c)||!this.shouldSample())return null;let d=D(e.name,e.message,c);return{type:"error",level:"error",message:e.message,timestamp:i,exception:{type:e.name,value:e.message,stacktrace:{frames:c}},fingerprint:d}}let o=String(e);if(this.shouldIgnoreError(o))return null;let a=[];return t&&a.push({filename:t,lineno:n,colno:this.config.captureColumn?r:void 0,in_app:!0}),!this.shouldIncludePath(a)||!this.shouldSample()?null:{type:"error",level:"error",message:o,timestamp:i,exception:{type:"Error",value:o,stacktrace:{frames:a}}}}destroy(){typeof window!="undefined"&&(this.originalOnError!==void 0&&(window.onerror=this.originalOnError),this.onUnhandledRejection&&window.removeEventListener("unhandledrejection",this.onUnhandledRejection),this.onResourceError&&window.removeEventListener("error",this.onResourceError,!0))}},se=ie;var oe=class{constructor(){this.name="performance";this.version="2.0.0";this.config={sampleRate:.1,captureLongTasks:!0,captureResources:!1,resourceSampleRate:.01,longTaskSampleRate:.05,captureNavigation:!0,captureFP:!0,enablePageLoadTracing:!1,maxResourceSpans:50};this.observers=[];this.navLoadTimer=null;this.totalBlockingTime=0;this.fcpTime=null;this.lastLongTaskEndTime=0;this.ttiReported=!1;this.ttiTimer=null;this.pageLoadTransaction=null;this.measurements={};this.resourceSpanCount=0}setup(e){this.client=e,this.loadConfig(),this.config.enablePageLoadTracing&&this.startPageLoadTransaction(),this.observeWebVitals(),this.observeLongTasks(),this.observeNavigation(),this.observeResources()}startPageLoadTransaction(){var n;if(typeof window=="undefined")return;let e=typeof location!="undefined"?location.pathname:"/",t=typeof performance!="undefined"&&((n=performance.timing)!=null&&n.navigationStart)?performance.timing.navigationStart:p();this.pageLoadTransaction=this.client.startTransaction({name:e,op:"pageload",description:`Page load - ${e}`,startTimestamp:t,type:"pageload",tags:{"page.url":e}})}loadConfig(){let e=this.client.config;e&&y(e.performance)&&(this.config={...this.config,...e.performance})}shouldSample(e="default"){var n,r,i;let t=(n=this.config.sampleRate)!=null?n:.1;return e==="resource"?t=(r=this.config.resourceSampleRate)!=null?r:.01:e==="longtask"?t=(i=this.config.longTaskSampleRate)!=null?i:.05:e==="vitals"&&(t=1),t>=1?!0:t<=0?!1:Math.random(){let n=t.getEntriesByName("first-paint");n.length>0&&this.config.captureFP&&this.reportMetric("FP",n[0].startTime,"ms",{},"vitals");let r=t.getEntriesByName("first-contentful-paint");r.length>0&&(this.fcpTime=r[0].startTime,this.lastLongTaskEndTime=r[0].startTime,this.reportMetric("FCP",r[0].startTime,"ms",{},"vitals"),this.scheduleTTI())});e.observe({type:"paint",buffered:!0}),this.observers.push(e)}catch(e){}}observeLCP(){try{let e=new PerformanceObserver(t=>{let n=t.getEntries(),r=n[n.length-1];if(r){let i=r.renderTime||r.loadTime||r.startTime;this.reportMetric("LCP",i,"ms",{},"vitals")}});e.observe({type:"largest-contentful-paint",buffered:!0}),this.observers.push(e)}catch(e){}}observeFID(){try{let e=new PerformanceObserver(t=>{let n=t.getEntries();if(n.length>0){let r=n[0],i=r.processingStart-r.startTime;this.reportMetric("FID",i,"ms",{},"vitals")}});e.observe({type:"first-input",buffered:!0}),this.observers.push(e)}catch(e){}}observeCLS(){try{let e=0,t=0,n=[],r=new PerformanceObserver(i=>{let o=i.getEntries();for(let a of o)if(!a.hadRecentInput){let c=n[0],d=n[n.length-1];t&&a.startTime-((d==null?void 0:d.duration)||0)<1e3&&a.startTime-c.startTime<5e3?(t+=a.value||0,n.push(a)):(t=a.value||0,n=[a]),t>e&&(e=t,this.reportMetric("CLS",e,"",{},"vitals"))}});r.observe({type:"layout-shift",buffered:!0}),this.observers.push(r)}catch(e){}}observeTTFB(){try{let e=new PerformanceObserver(t=>{let n=t.getEntriesByType("navigation");if(n.length>0){let r=n[0],i=r.responseStart-r.requestStart;this.reportMetric("TTFB",Math.max(0,i),"ms",{},"vitals")}});e.observe({type:"navigation",buffered:!0}),this.observers.push(e)}catch(e){}}observeLongTasks(){if(this.config.captureLongTasks)try{let e=new PerformanceObserver(t=>{let n=t.getEntries();for(let r of n){let i=r.startTime+r.duration;if(i>this.lastLongTaskEndTime&&(this.lastLongTaskEndTime=i),this.fcpTime!==null&&r.startTime>=this.fcpTime){let o=r.duration-50;o>0&&(this.totalBlockingTime+=o)}this.reportMetric("longtask",r.duration,"ms",{},"longtask"),this.scheduleTTI()}});e.observe({type:"longtask",buffered:!0}),this.observers.push(e)}catch(e){}}scheduleTTI(){this.ttiReported||(this.ttiTimer&&clearTimeout(this.ttiTimer),this.ttiTimer=setTimeout(()=>{if(this.ttiReported)return;this.ttiReported=!0;let e=Math.max(this.lastLongTaskEndTime,this.fcpTime||0);this.reportMetric("TTI",e,"ms",{},"vitals"),this.reportMetric("TBT",this.totalBlockingTime,"ms",{},"vitals")},5e3))}observeNavigation(){this.config.captureNavigation&&typeof performance!="undefined"&&(this.onLoad=()=>{this.navLoadTimer=setTimeout(()=>{let e=performance.timing;if(!e)return;let t=e.navigationStart,n={dom_ready:e.domContentLoadedEventEnd-t,load_time:e.loadEventEnd-t,dns:e.domainLookupEnd-e.domainLookupStart,tcp:e.connectEnd-e.connectStart,ssl:e.secureConnectionStart>0?e.connectEnd-e.secureConnectionStart:0,ttfb:e.responseStart-e.requestStart,download:e.responseEnd-e.responseStart,dom_parse:e.domInteractive-e.responseEnd};for(let[r,i]of Object.entries(n))i>0&&this.reportMetric(r,i,"ms");this.pageLoadTransaction&&this.pageLoadTransaction.sampled!==!1&&(this.buildNavigationSpans(e,t),this.finishPageLoadTransaction(e.loadEventEnd||p())),this.navLoadTimer=null},0)},window.addEventListener("load",this.onLoad))}buildNavigationSpans(e,t){let n=[{op:"dns",desc:"DNS Lookup",start:e.domainLookupStart,end:e.domainLookupEnd},{op:"tcp",desc:"TCP Connection",start:e.connectStart,end:e.connectEnd},{op:"ssl",desc:"SSL/TLS Negotiation",start:e.secureConnectionStart,end:e.connectEnd},{op:"ttfb",desc:"Time to First Byte",start:e.requestStart,end:e.responseStart},{op:"response",desc:"Response Download",start:e.responseStart,end:e.responseEnd},{op:"dom_parse",desc:"DOM Parsing",start:e.responseEnd,end:e.domInteractive},{op:"dom_content_loaded",desc:"DOM Content Loaded",start:e.domLoading,end:e.domContentLoadedEventEnd},{op:"load",desc:"Page Load",start:e.navigationStart,end:e.loadEventEnd}];for(let r of n)r.start>0&&r.end>0&&r.end>r.start&&this.createNavigationSpan(r.op,r.desc,r.start,r.end)}finishPageLoadTransaction(e){this.pageLoadTransaction&&(Object.keys(this.measurements).length>0&&this.pageLoadTransaction.setData("measurements",this.measurements),this.pageLoadTransaction.setStatus("ok"),this.pageLoadTransaction.finish(e),this.pageLoadTransaction=null)}observeResources(){if(!(!this.config.captureResources&&!this.config.enablePageLoadTracing)&&typeof performance!="undefined")try{let e=new PerformanceObserver(t=>{let n=t.getEntriesByType("resource");for(let r of n)r.duration>1e3&&this.config.captureResources&&this.reportMetric("resource_slow",r.duration,"ms",{resource_name:r.name.substring(0,200),resource_type:r.initiatorType},"resource"),this.config.enablePageLoadTracing&&this.pageLoadTransaction&&this.createResourceSpan(r)});e.observe({type:"resource",buffered:!0}),this.observers.push(e)}catch(e){}}getRating(e,t){let r={LCP:{good:2500,poor:4e3},FCP:{good:1800,poor:3e3},FP:{good:1800,poor:3e3},FID:{good:100,poor:300},CLS:{good:.1,poor:.25},TTFB:{good:800,poor:1800}}[e];return!r||t<=r.good?"good":t<=r.poor?"needs-improvement":"poor"}reportMetric(e,t,n,r={},i="default"){if(!this.shouldSample(i))return;let o=this.getRating(e,t),a={type:"performance",level:"info",metric:e,value:Math.round(t*100)/100,unit:n,rating:o,timestamp:p(),tags:{metric:e,rating:o,...r}};this.client.captureEvent(a),this.pageLoadTransaction&&this.pageLoadTransaction.sampled!==!1&&this.recordMeasurement(e,t,n,o)}recordMeasurement(e,t,n,r){this.pageLoadTransaction&&(this.measurements[e]={value:Math.round(t*100)/100,unit:n,rating:r},this.pageLoadTransaction.setTag(`measurement.${e}.rating`,r||"unknown"))}createNavigationSpan(e,t,n,r,i){if(!this.pageLoadTransaction||this.pageLoadTransaction.sampled===!1||r<=n)return;this.pageLoadTransaction.startChild({op:`browser.${e}`,description:t,startTimestamp:n,tags:i}).finish(r)}createResourceSpan(e){var c,d;if(!this.pageLoadTransaction||this.pageLoadTransaction.sampled===!1)return;let t=(c=this.config.maxResourceSpans)!=null?c:50;if(this.resourceSpanCount>=t)return;this.resourceSpanCount++;let n=typeof performance!="undefined"&&performance.timeOrigin?performance.timeOrigin:((d=performance.timing)==null?void 0:d.navigationStart)||0,r=n+e.startTime,i=n+(e.responseEnd||e.duration||e.startTime);if(i<=r)return;let o=e.name.substring(0,200);this.pageLoadTransaction.startChild({op:`resource.${e.initiatorType||"other"}`,description:o,startTimestamp:r,tags:{"resource.type":e.initiatorType||"other","resource.url":o,"resource.transfer_size":String(e.transferSize||0),"resource.decoded_size":String(e.decodedBodySize||0)},data:{transferSize:e.transferSize,decodedSize:e.decodedBodySize,encodedSize:e.encodedBodySize}}).finish(i)}destroy(){for(let e of this.observers)try{e.disconnect()}catch(t){}this.observers=[],this.ttiTimer&&(clearTimeout(this.ttiTimer),this.ttiTimer=null),this.navLoadTimer&&(clearTimeout(this.navLoadTimer),this.navLoadTimer=null),typeof window!="undefined"&&this.onLoad&&window.removeEventListener("load",this.onLoad),this.pageLoadTransaction&&(this.pageLoadTransaction.setStatus("internal_error"),this.pageLoadTransaction.finish(),this.pageLoadTransaction=null),this.measurements={},this.resourceSpanCount=0}},ae=oe;var ce=class{constructor(){this.name="network";this.version="1.1.0";this.config={captureXHR:!0,captureFetch:!0,captureSuccess:!1,captureBody:!1,captureRequestBody:!1,captureResponseBody:!1,captureRequestHeaders:["content-type","user-agent"],captureResponseHeaders:["content-type","content-length"],errorSampleRate:1,successSampleRate:.01,slowThreshold:3e3,slowSampleRate:1,ignoreStatusCodes:[]}}setup(e){this.client=e,this.loadConfig(),this.config.captureFetch&&this.patchFetch(),this.config.captureXHR&&this.patchXHR()}loadConfig(){let e=this.client.config;e&&y(e.network)&&(this.config={...this.config,...e.network}),e.ignoreUrls&&(this.config.ignoreUrls=[...this.config.ignoreUrls||[],...e.ignoreUrls]),e.tracePropagationTargets?this.config.tracePropagationTargets=[...this.config.tracePropagationTargets||[],...e.tracePropagationTargets]:e.tracingOrigins&&(this.config.tracePropagationTargets=[...this.config.tracePropagationTargets||[],...e.tracingOrigins])}shouldIgnore(e){return q(e,this.config.ignoreUrls||[])}shouldTracePropagate(e){let t=this.config.tracePropagationTargets;return!t||t.length===0?this.isSameOrigin(e):t.some(n=>typeof n=="string"?e.includes(n):n.test(e))}isSameOrigin(e){if(typeof location=="undefined")return!1;try{return new URL(e,location.origin).origin===location.origin}catch(t){return!1}}getBaggageHeader(){var r,i;if(!this.client)return;let t=(i=(r=this.client.tracingManager)==null?void 0:r.getCurrentTransaction)==null?void 0:i.call(r);if(!t)return;let n=t;if(n.toBaggage)return n.toBaggage()}shouldSample(e,t){var r,i,o,a;let n=e?(r=this.config.errorSampleRate)!=null?r:1:(i=this.config.successSampleRate)!=null?i:.01;return!e&&t>=((o=this.config.slowThreshold)!=null?o:3e3)&&(n=(a=this.config.slowSampleRate)!=null?a:1),n>=1?!0:n<=0?!1:Math.random()0?e.setHttpStatus(t):r&&e.setStatus("internal_error"),e.finish()}patchFetch(){if(typeof fetch=="undefined")return;this.originalFetch=window.fetch;let e=this;window.fetch=function(t,n){let r=p(),i=typeof t=="string"?t:t instanceof URL?t.toString():t.url,o=(n==null?void 0:n.method)||"GET";if(e.shouldIgnore(i))return e.originalFetch.call(window,t,n);let a=k(i),c=e.createHttpSpan(o,a),d=e.shouldTracePropagate(i)&&!!c,f=n;if(d&&c){let h=c.toTraceparent(),g=e.getBaggageHeader();f={...n,headers:{...(n==null?void 0:n.headers)||{},"sentry-trace":h,...g?{baggage:g}:{}}}}let E=e.originalFetch.call(window,t,f);return E.then(h=>{var S;let g=p()-r,m=h.ok,v=h.status;return c&&e.finishHttpSpan(c,v,g,!m),(S=e.config.ignoreStatusCodes)!=null&&S.includes(v)||!e.shouldSample(!m,g)||(!m||e.config.captureSuccess)&&e.reportNetwork({sub_type:"fetch",method:o.toUpperCase(),url:a,status_code:v,duration:g,success:m,error:m?void 0:`HTTP ${v}`}),h},h=>{let g=p()-r;throw c&&e.finishHttpSpan(c,0,g,!0),e.shouldSample(!0,g)&&e.reportNetwork({sub_type:"fetch",method:o.toUpperCase(),url:a,duration:g,success:!1,error:(h==null?void 0:h.message)||"Network error"}),h}),E}}patchXHR(){if(typeof XMLHttpRequest=="undefined")return;this.originalXHROpen=XMLHttpRequest.prototype.open,this.originalXHRSend=XMLHttpRequest.prototype.send;let e=this;XMLHttpRequest.prototype.open=function(t,n){return this._lightMethod=t,this._lightUrl=typeof n=="string"?n:n.toString(),this._lightTracked=!1,e.originalXHROpen.apply(this,arguments)},XMLHttpRequest.prototype.send=function(t){let n=p(),r=this._lightMethod||"GET",i=this._lightUrl||"",o=this._lightTracked;if(e.shouldIgnore(i)||o)return e.originalXHRSend.apply(this,arguments);this._lightTracked=!0;let a=k(i),c=0;t&&typeof t=="string"&&(c=t.length);let d=e.createHttpSpan(r,a);if(e.shouldTracePropagate(i)&&!!d&&d)try{let h=d.toTraceparent(),g=e.getBaggageHeader();this.setRequestHeader("sentry-trace",h),g&&this.setRequestHeader("baggage",g)}catch(h){}let E=this.onloadend;return this.onloadend=function(h){var S;let g=p()-n,m=this.status,v=m>=200&&m<300;if(d&&e.finishHttpSpan(d,m,g,!v),!((S=e.config.ignoreStatusCodes)!=null&&S.includes(m))&&e.shouldSample(!v,g)&&(!v||e.config.captureSuccess)){let b=0;try{let x=this.getResponseHeader("content-length");x&&(b=parseInt(x,10)),!b&&this.responseText&&(b=this.responseText.length)}catch(x){}e.reportNetwork({sub_type:"xhr",method:r.toUpperCase(),url:a,status_code:m,duration:g,request_size:c||void 0,response_size:b||void 0,success:v,error:v?void 0:`HTTP ${m}`})}if(E)return E.call(this,h)},e.originalXHRSend.apply(this,arguments)}}reportNetwork(e){let t={type:"network",level:e.success?"info":"error",timestamp:p(),tags:{method:e.method,sub_type:e.sub_type,success:String(e.success)},...e};this.client.captureEvent(t)}destroy(){this.originalFetch&&(window.fetch=this.originalFetch),this.originalXHROpen&&(XMLHttpRequest.prototype.open=this.originalXHROpen),this.originalXHRSend&&(XMLHttpRequest.prototype.send=this.originalXHRSend)}},ue=ce;var le=class{constructor(){this.name="behavior";this.version="1.0.0";this.config={capturePV:!0,captureClick:!0,captureRoute:!0,captureDuration:!0,captureScroll:!0,clickThrottle:300,scrollThrottle:1e3,sampleRate:.01};this.lastClickTime=0;this.lastScrollTime=0;this.maxScrollDepth=0;this.pageEnterTime=0;this.scrollReported=!1}setup(e){this.client=e,this.loadConfig(),this.config.capturePV&&this.trackPV(),this.config.captureClick&&this.trackClick(),this.config.captureRoute&&this.trackRoute(),this.config.captureDuration&&this.trackPageDuration(),this.config.captureScroll&&this.trackScroll()}loadConfig(){let e=this.client.config;e&&y(e.behavior)&&(this.config={...this.config,...e.behavior})}shouldSample(){var t;let e=(t=this.config.sampleRate)!=null?t:.01;return e>=1?!0:e<=0?!1:Math.random(){var a,c,d;let t=p(),n=(a=this.config.clickThrottle)!=null?a:300;if(t-this.lastClickTime{let r=w();if(r!==e){let i=e,o=r;e=r,this.reportBehavior({sub_type:"route",page_url:o,referrer:i,properties:{from:i,to:o}}),this.pageEnterTime=p(),this.maxScrollDepth=0,this.scrollReported=!1}};this.originalPushState=history.pushState,this.originalReplaceState=history.replaceState;let n=this;history.pushState=function(){let r=n.originalPushState.apply(this,arguments);return setTimeout(t,0),r},history.replaceState=function(){let r=n.originalReplaceState.apply(this,arguments);return setTimeout(t,0),r},this.onPopState=()=>{setTimeout(t,0)},this.onHashchange=()=>{setTimeout(t,0)},window.addEventListener("popstate",this.onPopState),window.addEventListener("hashchange",this.onHashchange)}trackPageDuration(){if(typeof window=="undefined")return;this.pageEnterTime=p();let e=()=>{let t=p()-this.pageEnterTime;t>1e3&&(this.config.captureScroll&&!this.scrollReported&&this.reportScroll(),this.reportBehavior({sub_type:"duration",page_url:w(),properties:{duration:t,max_scroll_depth:this.maxScrollDepth}}))};this.onVisibilityChange=()=>{document.hidden?e():this.pageEnterTime=p()},this.onBeforeUnload=e,this.onPagehide=e,document.addEventListener("visibilitychange",this.onVisibilityChange),window.addEventListener("beforeunload",this.onBeforeUnload),window.addEventListener("pagehide",this.onPagehide)}trackScroll(){typeof window!="undefined"&&(this.onScroll=()=>{var r;let e=p(),t=(r=this.config.scrollThrottle)!=null?r:1e3;if(e-this.lastScrollTimethis.maxScrollDepth&&(this.maxScrollDepth=n)},window.addEventListener("scroll",this.onScroll,{passive:!0}))}reportScroll(){this.scrollReported||(this.scrollReported=!0,this.reportBehavior({sub_type:"scroll",page_url:w(),properties:{max_depth:this.maxScrollDepth}}))}reportBehavior(e){if(!this.shouldSample())return;let t={type:"behavior",level:"info",timestamp:p(),tags:{sub_type:e.sub_type,page_url:w()},...e};this.client.captureEvent(t)}destroy(){typeof window!="undefined"&&(this.originalPushState&&(history.pushState=this.originalPushState),this.originalReplaceState&&(history.replaceState=this.originalReplaceState),this.onPopState&&window.removeEventListener("popstate",this.onPopState),this.onHashchange&&window.removeEventListener("hashchange",this.onHashchange),this.onBeforeUnload&&window.removeEventListener("beforeunload",this.onBeforeUnload),this.onPagehide&&window.removeEventListener("pagehide",this.onPagehide),this.onScroll&&window.removeEventListener("scroll",this.onScroll)),typeof document!="undefined"&&(this.onClick&&document.removeEventListener("click",this.onClick,!0),this.onVisibilityChange&&document.removeEventListener("visibilitychange",this.onVisibilityChange))}},de=le;var ht="light-sentry-offline",T="events",pe=1e3,he=class{constructor(){this.name="offline";this.version="1.0.0";this.config={maxEvents:pe};this.db=null;this.isOnline=!0;this.isSyncing=!1;this.pendingEvents=[]}setup(e){this.client=e,this.loadConfig(),this.initDatabase(),this.setupNetworkListeners()}loadConfig(){let e=this.client.config;e&&typeof e.offline=="object"&&(this.config={...this.config,...e.offline})}async initDatabase(){if(typeof indexedDB=="undefined"){console.warn("[LightSDK] OfflinePlugin: IndexedDB not available");return}return new Promise((e,t)=>{let n=indexedDB.open(ht,1);n.onerror=()=>{console.warn("[LightSDK] OfflinePlugin: Failed to open IndexedDB"),t(n.error)},n.onsuccess=()=>{this.db=n.result,e()},n.onupgradeneeded=r=>{let i=r.target.result,o=r.oldVersion;i.objectStoreNames.contains(T)||i.createObjectStore(T,{keyPath:"id"}).createIndex("timestamp","timestamp",{unique:!1})}})}setupNetworkListeners(){typeof window!="undefined"&&(this.isOnline=navigator.onLine,this.onOnline=()=>{console.info("[LightSDK] OfflinePlugin: Network online"),this.isOnline=!0,this.syncPendingEvents()},this.onOffline=()=>{console.info("[LightSDK] OfflinePlugin: Network offline"),this.isOnline=!1},window.addEventListener("online",this.onOnline),window.addEventListener("offline",this.onOffline))}generateId(){return`${Date.now()}-${Math.random().toString(36).substring(2,11)}`}async saveToIndexedDB(e){if(!this.db)return;let t=this.config.maxEvents||pe,n=await this.getEventCount();return n>=t&&await this.deleteOldestEvents(n-t+1),new Promise((r,i)=>{let a=this.db.transaction([T],"readwrite").objectStore(T),c={id:this.generateId(),event:{...e,offline:!0},timestamp:p()},d=a.add(c);d.onsuccess=()=>r(),d.onerror=()=>i(d.error)})}getEventCount(){return this.db?new Promise((e,t)=>{let i=this.db.transaction([T],"readonly").objectStore(T).count();i.onsuccess=()=>e(i.result),i.onerror=()=>t(i.error)}):Promise.resolve(0)}async deleteOldestEvents(e){if(!(!this.db||e<=0))return new Promise((t,n)=>{let a=this.db.transaction([T],"readwrite").objectStore(T).index("timestamp").openCursor(),c=0;a.onsuccess=d=>{let f=d.target.result;f&&cn(a.error)})}async getAllStoredEvents(){return this.db?new Promise((e,t)=>{let o=this.db.transaction([T],"readonly").objectStore(T).index("timestamp").getAll();o.onsuccess=()=>{let a=o.result||[];a.sort((c,d)=>c.timestamp-d.timestamp),e(a)},o.onerror=()=>t(o.error)}):[]}async clearStoredEvents(){if(this.db)return new Promise((e,t)=>{let i=this.db.transaction([T],"readwrite").objectStore(T).clear();i.onsuccess=()=>e(),i.onerror=()=>t(i.error)})}async syncPendingEvents(){if(!(!this.isOnline||this.isSyncing)){this.isSyncing=!0,console.info("[LightSDK] OfflinePlugin: Syncing pending events");try{let e=0;for(;this.pendingEvents.length>0;){let n=this.pendingEvents.shift();try{this.client.captureEvent(n),e++}catch(r){console.error("[LightSDK] OfflinePlugin: Failed to re-enqueue memory event",r)}}let t=await this.getAllStoredEvents();if(t.length>0)for(let n of t)try{let r=n.event;this.client.captureEvent(r),e++}catch(r){console.error("[LightSDK] OfflinePlugin: Failed to re-enqueue event",r)}try{await this.client.flush()}catch(n){}await this.clearStoredEvents(),console.info(`[LightSDK] OfflinePlugin: Synced ${e} events`)}catch(e){console.error("[LightSDK] OfflinePlugin: Sync failed",e)}finally{this.isSyncing=!1}}}beforeReport(e){if(!this.isOnline){let n=this.config.maxEvents||pe;return this.pendingEvents.length>=n&&this.pendingEvents.shift(),this.pendingEvents.push(e),this.savePendingEventsToDB(),null}let t={...e};return delete t.offline,t}savePendingEventsToDB(){if(this.pendingEvents.length===0)return;let e=this.pendingEvents.splice(0,this.pendingEvents.length),t=0,n=()=>{if(t>=e.length)return;let r=e[t];this.saveToIndexedDB(r).then(()=>{t++,n()}).catch(i=>{console.error("[LightSDK] OfflinePlugin: Failed to save event offline",i),this.pendingEvents.unshift(...e.slice(t))})};n()}destroy(){typeof window!="undefined"&&(this.onOnline&&window.removeEventListener("online",this.onOnline),this.onOffline&&window.removeEventListener("offline",this.onOffline)),this.db&&(this.db.close(),this.db=null)}},ge=he;var fe=class{constructor(){this.name="sampling";this.version="1.0.0";this.config={rates:{error:1,performance:1,network:1,behavior:1}}}setup(e){this.client=e,this.loadConfig()}loadConfig(){let e=this.client.config;if(e&&y(e.sampling)){let t=e.sampling;"rates"in t&&y(t.rates)&&(this.config.rates={...this.config.rates,...t.rates})}}shouldSample(e){var r;let t=(r=this.client.config.sampleRate)!=null?r:1;if(t<=0)return!1;let n=this.getTypeRate(e);return t>=1?this.randomCheck(n):this.randomCheck(t*n)}getTypeRate(e){let t=this.config.rates||{},n=e.type;if(n==="count")return 1;let r=t[n];return r!==void 0?r:1}randomCheck(e){return e>=1?!0:e<=0?!1:Math.random(){this.handleRouteChange(location.pathname+location.search,"popstate")};this.handleHashChange=()=>{this.handleRouteChange(location.hash||"#/","hashchange")}}setup(e){this.client=e,this.loadConfig(),typeof window!="undefined"&&this.config.enable&&(this.config.instrumentHistory&&this.instrumentHistory(),this.config.instrumentHash&&this.instrumentHash())}loadConfig(){let e=this.client.config;e&&y(e.router)&&(this.config={...this.config,...e.router})}instrumentHistory(){typeof history=="undefined"||!history.pushState||(this.originalPushState=history.pushState.bind(history),this.originalReplaceState=history.replaceState.bind(history),history.pushState=(e,t,n)=>{this.originalPushState(e,t,n),this.handleRouteChange(n||location.pathname+location.search,"pushState")},history.replaceState=(e,t,n)=>{this.originalReplaceState(e,t,n),this.handleRouteChange(n||location.pathname+location.search,"replaceState")},window.addEventListener("popstate",this.handlePopState))}instrumentHash(){window.addEventListener("hashchange",this.handleHashChange)}handleRouteChange(e,t){this.routeChangeTimer&&clearTimeout(this.routeChangeTimer),this.routeChangeTimer=setTimeout(()=>{this.routeChangeTimer=null,this.processRouteChange(e,t)},50)}processRouteChange(e,t){let n=this.config.routeNameFormatter?this.config.routeNameFormatter(e):e.split("?")[0];n!==this.lastRoute&&(this.lastRoute=n,this.finishCurrentTransaction("ok"),this.startNavigationTransaction(n,t))}startNavigationTransaction(e,t){if(!this.client)return;let n=this.client.startTransaction({name:e,op:"navigation",description:`Navigation to ${e}`,type:"navigation",tags:{"route.name":e,"route.source":t}});n&&(this.currentTransaction=n,this.startMaxDurationTimer())}startMaxDurationTimer(){var t;this.maxDurationTimer&&clearTimeout(this.maxDurationTimer);let e=(t=this.config.maxTransactionDurationMs)!=null?t:3e4;this.maxDurationTimer=setTimeout(()=>{this.currentTransaction&&(this.currentTransaction.setStatus("deadline_exceeded"),this.finishCurrentTransaction("deadline_exceeded"))},e)}finishCurrentTransaction(e="ok"){this.maxDurationTimer&&(clearTimeout(this.maxDurationTimer),this.maxDurationTimer=null),this.currentTransaction&&(this.currentTransaction.setStatus(e),this.currentTransaction.finish(),this.currentTransaction=null)}destroy(){this.originalPushState&&typeof history!="undefined"&&(history.pushState=this.originalPushState),this.originalReplaceState&&typeof history!="undefined"&&(history.replaceState=this.originalReplaceState),typeof window!="undefined"&&(window.removeEventListener("popstate",this.handlePopState),window.removeEventListener("hashchange",this.handleHashChange)),this.maxDurationTimer&&(clearTimeout(this.maxDurationTimer),this.maxDurationTimer=null),this.routeChangeTimer&&(clearTimeout(this.routeChangeTimer),this.routeChangeTimer=null),this.finishCurrentTransaction("aborted")}},ye=ve;var Se=class{constructor(){this.name="interaction";this.version="1.0.0";this.config={enable:!0,elementAttribute:"data-sentry-component",maxTransactionDurationMs:3e4,idleTimeoutMs:1e3,trackClick:!0,trackSubmit:!0,trackKeypress:!1};this.currentTransaction=null;this.idleTimer=null;this.maxDurationTimer=null;this.debounceTimer=null;this.handleClick=e=>{if(this.isEventIgnored(e))return;let t=e.target,n=this.getElementName(t,"click");this.scheduleInteractionTransaction(n,"click",t)};this.handleSubmit=e=>{if(this.isEventIgnored(e))return;let t=e.target,n=this.getElementName(t,"submit");this.scheduleInteractionTransaction(n,"submit",t)}}setup(e){this.client=e,this.loadConfig(),typeof window!="undefined"&&this.config.enable&&(this.config.trackClick&&document.addEventListener("click",this.handleClick,!0),this.config.trackSubmit&&document.addEventListener("submit",this.handleSubmit,!0))}loadConfig(){let e=this.client.config;e&&y(e.interaction)&&(this.config={...this.config,...e.interaction})}isEventIgnored(e){let t=e.target;return!!(!t||t.hasAttribute&&t.hasAttribute("data-sentry-ignore"))}scheduleInteractionTransaction(e,t,n){this.debounceTimer&&clearTimeout(this.debounceTimer),this.debounceTimer=setTimeout(()=>{this.startInteractionTransaction(e,t,n)},0)}getElementName(e,t){var c;if(!e)return t;let n=this.config.elementAttribute||"data-sentry-component",r=e.getAttribute(n);if(r)return r;let i=((c=e.tagName)==null?void 0:c.toLowerCase())||"element",o=e.id?`#${e.id}`:"",a=e.className&&typeof e.className=="string"?`.${e.className.split(" ").slice(0,3).join(".")}`:"";return`${t}@${i}${o}${a}`}startInteractionTransaction(e,t,n){var i,o;if(!this.client)return;this.currentTransaction&&this.finishCurrentTransaction("ok");let r=this.client.startTransaction({name:e,op:`ui.${t}`,description:`User ${t} on ${e}`,type:"user-interaction",tags:{"interaction.type":t,"interaction.target":e},data:{tag:(i=n.tagName)==null?void 0:i.toLowerCase(),id:n.id||void 0,text:((o=n.textContent)==null?void 0:o.substring(0,100))||void 0}});r&&(this.currentTransaction=r,this.scheduleIdleFinish(),this.scheduleMaxDuration())}scheduleIdleFinish(){var t;this.idleTimer&&clearTimeout(this.idleTimer);let e=(t=this.config.idleTimeoutMs)!=null?t:1e3;this.idleTimer=setTimeout(()=>{this.finishCurrentTransaction("ok")},e)}scheduleMaxDuration(){var t;this.maxDurationTimer&&clearTimeout(this.maxDurationTimer);let e=(t=this.config.maxTransactionDurationMs)!=null?t:3e4;this.maxDurationTimer=setTimeout(()=>{this.finishCurrentTransaction("deadline_exceeded")},e)}finishCurrentTransaction(e="ok"){this.idleTimer&&(clearTimeout(this.idleTimer),this.idleTimer=null),this.maxDurationTimer&&(clearTimeout(this.maxDurationTimer),this.maxDurationTimer=null),this.debounceTimer&&(clearTimeout(this.debounceTimer),this.debounceTimer=null),this.currentTransaction&&(this.currentTransaction.setStatus(e),this.currentTransaction.finish(),this.currentTransaction=null)}destroy(){typeof document!="undefined"&&(document.removeEventListener("click",this.handleClick,!0),document.removeEventListener("submit",this.handleSubmit,!0)),this.idleTimer&&(clearTimeout(this.idleTimer),this.idleTimer=null),this.maxDurationTimer&&(clearTimeout(this.maxDurationTimer),this.maxDurationTimer=null),this.debounceTimer&&(clearTimeout(this.debounceTimer),this.debounceTimer=null),this.finishCurrentTransaction("aborted")}},be=Se;var l=null;function _e(s){var r;O(s.debug===!0),u("Index","init called",{dsn:s.dsn,debug:s.debug});let e=new re(s),t=[new ge,new me,new se],n=((r=s.plugins)==null?void 0:r.filter(i=>typeof i=="string"))||[];(n.includes("performance")||n.includes("all"))&&t.push(new ae),(n.includes("network")||n.includes("all"))&&t.push(new ue),(n.includes("behavior")||n.includes("all"))&&t.push(new de),(n.includes("router")||n.includes("all"))&&t.push(new ye),(n.includes("interaction")||n.includes("all"))&&t.push(new be),u("Index","Registering plugins",{count:t.length,plugins:t.map(i=>i.name)});for(let i of t)e.use(i);if(s.plugins)for(let i of s.plugins)typeof i=="object"&&i!==null&&"name"in i&&"setup"in i&&e.use(i);return e.init(),l=e,u("Index","init completed, globalClient set"),e}function Me(){return l}function De(s){if(u("Index","captureException called",{hasClient:!!l}),!l){console.warn("[LightSDK] SDK not initialized. Call LightSentry.init() first.");return}l.captureException(s)}function Be(s,e){if(u("Index","captureMessage called",{hasClient:!!l}),!l){console.warn("[LightSDK] SDK not initialized. Call LightSentry.init() first.");return}l.captureMessage(s,e)}function Oe(s){if(u("Index","captureEvent called",{hasClient:!!l}),!l){console.warn("[LightSDK] SDK not initialized. Call LightSentry.init() first.");return}l.captureEvent(s)}function Fe(s){l==null||l.setUser(s)}function Ne(s){H(s)}function He(){we()}function qe(){return N()}function Ue(s){return(l==null?void 0:l.startTransaction(s))||null}function $e(){return(l==null?void 0:l.getCurrentTransaction())||null}function Ae(){return(l==null?void 0:l.getCurrentSpan())||null}function je(s){l==null||l.setSpan(s)}function Ke(s){return(l==null?void 0:l.startSpan(s))||null}function ze(s,e){l==null||l.setTag(s,e)}function Xe(s){l==null||l.setTags(s)}function We(s,e){l==null||l.setExtra(s,e)}function Ve(s){l==null||l.addBreadcrumb(s)}async function Qe(){await(l==null?void 0:l.flush())}function Ge(){l==null||l.disable()}function Je(){l==null||l.enable()}var gt={init:_e,getClient:Me,captureException:De,captureMessage:Be,captureEvent:Oe,setUser:Fe,setAnonymousId:Ne,clearAnonymousId:He,getAnonymousId:qe,startTransaction:Ue,getCurrentTransaction:$e,getCurrentSpan:Ae,setSpan:je,startSpan:Ke,setTag:ze,setTags:Xe,setExtra:We,addBreadcrumb:Ve,flush:Qe,disable:Ge,enable:Je,Span:C,Transaction:L,httpStatusToSpanStatus:_}; diff --git a/dist/index.d.ts b/dist/index.d.ts index 1a85cc2..c1def43 100644 --- a/dist/index.d.ts +++ b/dist/index.d.ts @@ -5,7 +5,11 @@ import NetworkPlugin from './plugins/NetworkPlugin'; import BehaviorPlugin from './plugins/BehaviorPlugin'; import OfflinePlugin from './plugins/OfflinePlugin'; import SamplingPlugin from './plugins/SamplingPlugin'; -import type { LightConfig, LightClient, SentryEvent, EventLevel, UserInfo, Breadcrumb, LightPlugin, ErrorEvent, PerformanceEvent, NetworkEvent, BehaviorEvent, DSNInfo } from './types'; +import RouterPlugin from './plugins/RouterPlugin'; +import InteractionPlugin from './plugins/InteractionPlugin'; +import { Span as SpanClass, Transaction as TransactionClass, httpStatusToSpanStatus, dbStatusToSpanStatus, statusToSpanStatus } from './utils/tracing'; +import { serializeBaggage, parseBaggage, createBaggageFromTransaction } from './utils/baggage'; +import type { LightConfig, LightClient, SentryEvent, EventLevel, UserInfo, Breadcrumb, LightPlugin, ErrorEvent, PerformanceEvent, NetworkEvent, BehaviorEvent, DSNInfo, TransactionContext, SpanContext, Transaction, Span, SamplingContext, BaggageFields, SpanStatus } from './types'; declare function init(config: LightConfig): LightClient; declare function getClient(): LightClient | null; declare function captureException(error: Error | unknown): void; @@ -14,6 +18,14 @@ declare function captureEvent(event: Partial & { type: string; }): void; declare function setUser(user: UserInfo | null): void; +declare function setAnonymousId(id: string): void; +declare function clearAnonymousId(): void; +declare function getAnonymousId(): string | null; +declare function startTransaction(context: TransactionContext): Transaction | null; +declare function getCurrentTransaction(): Transaction | null; +declare function getCurrentSpan(): Span | null; +declare function setSpan(span: Span | null): void; +declare function startSpan(context: SpanContext): Span | null; declare function setTag(key: string, value: string): void; declare function setTags(tags: Record): void; declare function setExtra(key: string, value: unknown): void; @@ -21,8 +33,9 @@ declare function addBreadcrumb(breadcrumb: Omit): void; declare function flush(): Promise; declare function disable(): void; declare function enable(): void; -export { init, getClient, captureException, captureMessage, captureEvent, setUser, setTag, setTags, setExtra, addBreadcrumb, flush, disable, enable, Client, ErrorPlugin, PerformancePlugin, NetworkPlugin, BehaviorPlugin, OfflinePlugin, SamplingPlugin, }; -export type { LightConfig, LightClient, LightPlugin, SentryEvent, ErrorEvent, PerformanceEvent, NetworkEvent, BehaviorEvent, EventLevel, UserInfo, Breadcrumb, DSNInfo, }; +export { init, getClient, captureException, captureMessage, captureEvent, setUser, setAnonymousId, clearAnonymousId, getAnonymousId, startTransaction, getCurrentTransaction, getCurrentSpan, setSpan, startSpan, setTag, setTags, setExtra, addBreadcrumb, flush, disable, enable, Client, httpStatusToSpanStatus, dbStatusToSpanStatus, statusToSpanStatus, serializeBaggage, parseBaggage, createBaggageFromTransaction, ErrorPlugin, PerformancePlugin, NetworkPlugin, BehaviorPlugin, OfflinePlugin, SamplingPlugin, RouterPlugin, InteractionPlugin, }; +export { SpanClass as Span, TransactionClass as Transaction }; +export type { LightConfig, LightClient, LightPlugin, SentryEvent, ErrorEvent, PerformanceEvent, NetworkEvent, BehaviorEvent, EventLevel, UserInfo, Breadcrumb, DSNInfo, TransactionContext, SpanContext, SamplingContext, BaggageFields, SpanStatus, SpanJSON, TransactionJSON, }; declare const _default: { init: typeof init; getClient: typeof getClient; @@ -30,6 +43,14 @@ declare const _default: { captureMessage: typeof captureMessage; captureEvent: typeof captureEvent; setUser: typeof setUser; + setAnonymousId: typeof setAnonymousId; + clearAnonymousId: typeof clearAnonymousId; + getAnonymousId: typeof getAnonymousId; + startTransaction: typeof startTransaction; + getCurrentTransaction: typeof getCurrentTransaction; + getCurrentSpan: typeof getCurrentSpan; + setSpan: typeof setSpan; + startSpan: typeof startSpan; setTag: typeof setTag; setTags: typeof setTags; setExtra: typeof setExtra; @@ -37,5 +58,8 @@ declare const _default: { flush: typeof flush; disable: typeof disable; enable: typeof enable; + Span: typeof SpanClass; + Transaction: typeof TransactionClass; + httpStatusToSpanStatus: typeof httpStatusToSpanStatus; }; export default _default; diff --git a/dist/index.esm.js b/dist/index.esm.js index 7505ce6..f501363 100644 --- a/dist/index.esm.js +++ b/dist/index.esm.js @@ -1,3 +1,3 @@ -function G(o){try{let e=o.match(/^(https?):\/\/([^@]+)@([^/]+)\/(.+)$/);if(!e)throw new Error("Invalid DSN format");let[,t,n,r,i]=e;return{protocol:t,publicKey:n,host:r,projectId:i}}catch(e){throw new Error(`Failed to parse DSN: ${e.message}`)}}function C(o){return`${o.protocol}://${o.host}/api/${o.projectId}/envelope/?sentry_key=${o.publicKey}`}function J(){return"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx".replace(/[x]/g,()=>(Math.random()*16|0).toString(16))}function p(){return Date.now()}function b(o){return o!==null&&typeof o=="object"&&!Array.isArray(o)}function L(o,e){return!e||e.length===0?!1:e.some(t=>typeof t=="string"?o.includes(t):t.test(o))}function le(o){let e=5381,t=o.length;for(;t;)e=e*33^o.charCodeAt(--t);return e>>>0}function q(o){return le(o).toString(16)}function T(o,e,t=[]){let n=t.slice(0,3).map(i=>`${i.filename}:${i.lineno||0}`).join("|"),r=e.replace(/['"]?\d+['"]?/g,"").replace(/\s+/g," ").trim();return q(`${o}:${r}:${n}`)}function P(o,e={}){if(!o)return[];let{captureNodeModules:t=!1,captureColumn:n=!0,relativePathOnly:r=!1,maxFrames:i}=e,s=[],a=o.split(` -`),u=typeof location!="undefined"?`${location.protocol}//${location.host}`:"";for(let h of a){let w=h.match(/^\s*at\s*(.+?)\s*\((.+?):(\d+):(\d+)\)\s*$/);if(w){let[,g,f,y,m]=w,S=f.includes("node_modules");if(!t&&S)continue;let x=f;r&&u&&f.startsWith(u)&&(x=f.substring(u.length)),s.push({filename:x,function:g,lineno:parseInt(y,10),colno:n?parseInt(m,10):void 0,in_app:!S})}else{let g=h.match(/^\s*at\s*(.+?)@(.+?):(\d+):(\d+)\s*$/);if(g){let[,y,m,S,x]=g,k=m.includes("node_modules");if(!t&&k)continue;let Q=m;r&&u&&m.startsWith(u)&&(Q=m.substring(u.length)),s.push({filename:Q,function:y||"",lineno:parseInt(S,10),colno:n?parseInt(x,10):void 0,in_app:!k});continue}let f=h.match(/^\s*at\s*(.+?):(\d+):(\d+)\s*$/);if(f){let[,y,m,S]=f,x=y.includes("node_modules");if(!t&&x)continue;let k=y;r&&u&&y.startsWith(u)&&(k=y.substring(u.length)),s.push({filename:k,lineno:parseInt(m,10),colno:n?parseInt(S,10):void 0,in_app:!x})}}}let c=s.reverse();return i!==void 0&&i>0?c.slice(0,i):c}var N=!1;function M(o){N=o}function l(o,e,t){if(!N)return;let n=new Date().toISOString(),r=`[LightSDK][${o}]`;t!==void 0?console.log(`${r} ${n} ${e}`,t):console.log(`${r} ${n} ${e}`)}function U(o,e,t){if(!N)return;let n=new Date().toISOString(),r=`[LightSDK][${o}][ERROR]`;t!==void 0?console.error(`${r} ${n} ${e}`,t):console.error(`${r} ${n} ${e}`)}function de(o){let e=[{name:"WeChat",pattern:/MicroMessenger\/([\d.]+)/i},{name:"QQ Browser",pattern:/QIBrowser\/([\d.]+)/i},{name:"UC Browser",pattern:/UCBrowser\/([\d.]+)/i},{name:"Edge",pattern:/Edg\/([\d.]+)/i},{name:"Edge",pattern:/Edge\/([\d.]+)/i},{name:"Opera",pattern:/OPR\/([\d.]+)/i},{name:"Opera",pattern:/Opera\/([\d.]+)/i},{name:"Firefox",pattern:/Firefox\/([\d.]+)/i},{name:"Safari",pattern:/Version\/([\d.]+).*Safari/i},{name:"Chrome",pattern:/Chrome\/([\d.]+)/i},{name:"IE",pattern:/MSIE ([\d.]+)/i},{name:"IE",pattern:/Trident.*rv:([\d.]+)/i}];for(let t of e){let n=o.match(t.pattern);if(n){let r=n[1]||"",i=r.split(".")[0]||"";return{name:t.name,version:r,major:i}}}return{name:"Unknown",version:"",major:""}}function pe(o){let e=[{name:"Windows 11",pattern:/Windows NT 10\.0.*Win64.*x64/i},{name:"Windows 10",pattern:/Windows NT 10\.0/i},{name:"Windows 8.1",pattern:/Windows NT 6\.3/i},{name:"Windows 8",pattern:/Windows NT 6\.2/i},{name:"Windows 7",pattern:/Windows NT 6\.1/i},{name:"Windows Vista",pattern:/Windows NT 6\.0/i},{name:"Windows XP",pattern:/Windows NT 5\.1/i},{name:"macOS",pattern:/Mac OS X ([\d_.]+)/i},{name:"iOS",pattern:/OS ([\d_.]+) like Mac OS X/i},{name:"Android",pattern:/Android ([\d.]+)/i},{name:"Android",pattern:/Android/i},{name:"Linux",pattern:/Linux/i}];for(let t of e){let n=o.match(t.pattern);if(n){let r=n[1]||"";return r&&(r=r.replace(/_/g,".")),{name:t.name,version:r}}}return{name:"Unknown",version:""}}function he(o){let e=/Mobile|Android|iPhone|iPod|BlackBerry|Windows Phone|Opera Mini/i.test(o),t=/Tablet|iPad|PlayBook|Kindle|Silk/i.test(o),n="desktop";t?n="tablet":e&&(n="mobile");let r="",i="",s=o.match(/iPhone/i),a=o.match(/iPad/i),u=o.match(/SM-([A-Z0-9]+)/i),c=o.match(/Pixel ([0-9A-Z]+)/i),h=o.match(/HUAWEI ([A-Z0-9]+)/i);return s?(r="Apple",i="iPhone"):a?(r="Apple",i="iPad"):u?(r="Samsung",i=u[1]):c?(r="Google",i=`Pixel ${c[1]}`):h&&(r="Huawei",i=h[1]),{type:n,vendor:r,model:i}}function Z(){let o=typeof navigator!="undefined"?navigator.userAgent:"",e=de(o),t=pe(o),n=he(o);return{browser:e,os:t,device:n,url:typeof location!="undefined"?location.href:"",referrer:typeof document!="undefined"?document.referrer:"",title:typeof document!="undefined"?document.title:"",language:typeof navigator!="undefined"?navigator.language:"",user_agent:o,screen_width:typeof screen!="undefined"?screen.width:0,screen_height:typeof screen!="undefined"?screen.height:0,viewport_width:typeof window!="undefined"?window.innerWidth:0,viewport_height:typeof window!="undefined"?window.innerHeight:0}}function E(){return typeof location!="undefined"?location.href:""}function Y(){return typeof document!="undefined"?document.referrer:""}function R(o){if(!o)return o;try{let e=new URL(o),t=["password","passwd","pwd","token","access_token","refresh_token","api_key","apikey","key","secret","private_key","code","auth","id_token","idToken","session","session_id"],n=e.searchParams,r=!1;for(let i of Array.from(n.keys())){let s=i.toLowerCase().replace(/[-_]/g,"_");t.some(a=>s.includes(a))&&(n.set(i,"[Filtered]"),r=!0)}if(e.hash&&e.hash.length>1){let i=e.hash.substring(1);if(i.includes("=")){let s=new URLSearchParams(i),a=!1;for(let u of Array.from(s.keys())){let c=u.toLowerCase().replace(/[-_]/g,"_");t.some(h=>c.includes(h))&&(s.set(u,"[Filtered]"),a=!0)}a&&(e.hash="#"+s.toString(),r=!0)}}return r?e.toString():o}catch(e){return o}}function D(o,e=[]){return!e||e.length===0?!1:e.some(t=>{if(typeof t=="string"){if(t.includes("*")){let n=t.replace(/[.+?^${}()|[\]\\]/g,"\\$&").replace(/\*/g,".*");return new RegExp(n).test(o)}return o.includes(t)}return t.test(o)})}var fe={Chrome:"c",Safari:"s",Firefox:"f",Edge:"e",Opera:"o",IE:"i",WeChat:"w","QQ Browser":"q","UC Browser":"u","Mobile Chrome":"cm","Mobile Safari":"sm"},ge={"Windows 11":"w11","Windows 10":"w10","Windows 8.1":"w81","Windows 8":"w8","Windows 7":"w7","Windows Vista":"wv","Windows XP":"wxp",macOS:"m",iOS:"i",Android:"a",Linux:"l"};function H(){let o=Z(),e=fe[o.browser.name]||o.browser.name.toLowerCase(),t=ge[o.os.name]||o.os.name.toLowerCase();return{browser:{name:e,version:o.browser.major},os:{name:t,version:o.os.version.split(".")[0]},device:{type:o.device.type,brand:o.device.vendor||void 0,model:o.device.model||void 0}}}function ee(){let o=Z(),e=`${o.browser.name}|${o.browser.major}|${o.os.name}|${o.os.version.split(".")[0]}|${o.device.type}|${o.device.vendor}|${o.device.model}|${o.language}`;return q(e).substring(0,16)}var me={enabled:!0,sampleRate:1,maxQueueSize:100,flushInterval:5e3,maxRetries:3,retryDelay:1e3,environment:"production",contextLevel:{fatal:{maxStackFrames:5,maxBreadcrumbs:20},error:{maxStackFrames:5,maxBreadcrumbs:10},warning:{maxStackFrames:3,maxBreadcrumbs:5},info:{maxStackFrames:0,maxBreadcrumbs:0},debug:{maxStackFrames:0,maxBreadcrumbs:0}}},I=class{constructor(e){this.contexts=null;this.contextId=null;this.contextReported=!1;this.config={...me,...e}}markContextReported(){this.contextReported=!0}get(e){return this.config[e]}getAll(){return{...this.config}}set(e,t){this.config[e]=t}setUser(e){this.config.user=e||void 0}setTags(e){this.config.tags={...this.config.tags||{},...e}}setTag(e,t){this.config.tags||(this.config.tags={}),this.config.tags[e]=t}setExtra(e,t){this.config.extra||(this.config.extra={}),this.config.extra[e]=t}isIgnoredError(e){return L(e,this.config.ignoreErrors||[])}getEncodedContext(){return this.contexts||(this.contexts=H()),this.contexts}applyToEvent(e,t=!0){var i,s,a,u;let n={...e};if(e.tags&&(n.tags={...e.tags}),e.request&&(n.request={...e.request}),"exception"in e&&e.exception){let c=e.exception;n.exception={...c,stacktrace:c.stacktrace?{...c.stacktrace,frames:c.stacktrace.frames?c.stacktrace.frames.map(h=>({...h})):void 0}:void 0}}e.breadcrumbs&&(n.breadcrumbs=e.breadcrumbs.map(c=>({...c}))),e.user&&(n.user={...e.user}),e.contexts&&(n.contexts={...e.contexts}),this.config.release&&(n.release=this.config.release),this.config.environment&&(n.environment=this.config.environment),this.config.user&&(n.user=this.config.user),this.config.tags&&(n.tags={...this.config.tags,...e.tags||{}}),n.request?n.request.url||(n.request.url=E()):n.request={url:E(),referrer:Y()},this.contextId||(this.contextId=ee()),n.context_id=this.contextId;let r=this.applyContextLevel(n);return t&&!this.contextReported&&(this.contexts||(this.contexts=H()),r.contexts=this.contexts,r.env={b:(i=this.contexts.browser)==null?void 0:i.name,bv:(s=this.contexts.browser)==null?void 0:s.version,os:(a=this.contexts.os)==null?void 0:a.name,osv:(u=this.contexts.os)==null?void 0:u.version}),r}applyContextLevel(e){let t=this.config.contextLevel;if(!t)return e;let n=e.level||"error",r=t[n]||t.error,i={...e};if("exception"in e&&e.exception&&typeof e.exception=="object"){let s=e.exception;if(s.stacktrace&&typeof s.stacktrace=="object"){let a=s.stacktrace;Array.isArray(a.frames)&&(r.maxStackFrames===0?delete i.exception:i.exception={...s,stacktrace:{...a,frames:a.frames.slice(0,r.maxStackFrames)}})}}return e.breadcrumbs&&Array.isArray(e.breadcrumbs)&&(r.maxBreadcrumbs===0?delete i.breadcrumbs:i.breadcrumbs=e.breadcrumbs.slice(-r.maxBreadcrumbs)),i}};var B=class{constructor(){this.handlers=new Map}on(e,t){this.handlers.has(e)||this.handlers.set(e,[]),this.handlers.get(e).push(t)}off(e,t){let n=this.handlers.get(e);if(n){let r=n.indexOf(t);r>-1&&n.splice(r,1)}}emit(e,...t){let n=this.handlers.get(e);if(n)for(let r of n)try{r(...t)}catch(i){console.error("[LightSDK] EventBus handler error:",i)}}once(e,t){let n=(...r)=>{this.off(e,n),t(...r)};this.on(e,n)}destroy(){this.handlers.clear()}};var _=class{constructor(e,t,n,r,i){this.queue=[];this.timer=null;this.lastFlushTime=0;this.isFlushing=!1;this.dedupeMap=new Map;this.pendingCounts=new Map;this.errorRateWindow={};this.paused=!1;this.pauseTimer=null;this.maxSize=e,this.flushInterval=t,this.eventBus=n,this.flushCallback=r,this.syncFlushCallback=i}start(){this.startTimer(),this.setupVisibilityListener()}startTimer(){this.timer||(this.timer=setInterval(()=>{(this.queue.length>0||this.pendingCounts.size>0)&&this.flush()},this.flushInterval))}setupVisibilityListener(){this.onVisibilityChange=()=>{document.hidden&&(this.queue.length>0||this.pendingCounts.size>0)&&this.flushSync()},typeof document!="undefined"&&document.addEventListener("visibilitychange",this.onVisibilityChange),this.onBeforeUnload=()=>{(this.queue.length>0||this.pendingCounts.size>0)&&this.flushSync()},this.onPagehide=()=>{(this.queue.length>0||this.pendingCounts.size>0)&&this.flushSync()},typeof window!="undefined"&&(window.addEventListener("beforeunload",this.onBeforeUnload),window.addEventListener("pagehide",this.onPagehide))}checkInfiniteLoop(e){let t=p(),n=t-1e3;this.errorRateWindow[e]||(this.errorRateWindow[e]=[]);let r=this.errorRateWindow[e];for(r.push(t);r.length>0&&r[0]10?(this.paused||(console.warn("[LightSDK] Infinite loop detected, pausing SDK for 60s",{fingerprint:e,count:r.length}),this.eventBus.emit("error",new Error("Infinite loop detected")),this.paused=!0,this.pauseTimer&&clearTimeout(this.pauseTimer),this.pauseTimer=setTimeout(()=>{this.paused=!1,this.errorRateWindow={},console.info("[LightSDK] Resumed after infinite loop detection")},6e4)),!0):!1}enqueue(e){if(l("EventQueue","enqueue called",{type:e.type,level:e.level,message:"message"in e?e.message:void 0}),this.paused){l("EventQueue","enqueue skipped: queue paused (infinite loop detected)");return}this.cleanupExpiredDedupeEntries();let t=this.getDedupeKey(e);if(t){if(this.checkInfiniteLoop(t)){l("EventQueue","enqueue skipped: infinite loop detected",{fingerprint:t});return}let n=p(),r=this.dedupeMap.get(t);if(r)if(n-r.lastTime<6e4){if(r.count>=3){if(!this.pendingCounts.has(t))this.pendingCounts.set(t,{count:1,ts_start:n,ts_end:n});else{let i=this.pendingCounts.get(t);i.count++,i.ts_end=n}l("EventQueue","enqueue skipped: deduped (count >= 3)",{fingerprint:t,count:r.count});return}r.count++,r.lastTime=n,l("EventQueue","Dedup count incremented",{fingerprint:t,count:r.count})}else this.dedupeMap.set(t,{count:1,lastTime:n,firstReported:!0}),this.pendingCounts.delete(t),l("EventQueue","Dedup entry reset (expired)",{fingerprint:t});else this.dedupeMap.set(t,{count:1,lastTime:n,firstReported:!1}),l("EventQueue","New dedup entry created",{fingerprint:t})}this.queue.push(e),l("EventQueue","Event added to queue",{queueSize:this.queue.length}),this.eventBus.emit("event",e),this.queue.length>=this.maxSize&&(l("EventQueue","Queue reached maxSize, triggering flush",{maxSize:this.maxSize}),this.flush())}cleanupExpiredDedupeEntries(){if(this.dedupeMap.size<100&&Math.random()>.1)return;let e=p(),t=6e4;for(let[n,r]of this.dedupeMap)e-r.lastTime>t&&this.dedupeMap.delete(n)}buildCountEvents(){let e=[];for(let[t,n]of this.pendingCounts.entries()){let r={type:"count",fingerprint:t,count:n.count,ts_start:n.ts_start,ts_end:n.ts_end,timestamp:p(),level:"info"};e.push(r)}return e}getDedupeKey(e){if(e.type==="error"){let t=e;return t.fingerprint||t.message}return null}async flush(){if(l("EventQueue","flush called",{queueSize:this.queue.length,pendingCounts:this.pendingCounts.size,isFlushing:this.isFlushing}),this.queue.length===0&&this.pendingCounts.size===0){l("EventQueue","flush skipped: queue is empty");return}if(this.isFlushing){l("EventQueue","flush skipped: already flushing");return}this.isFlushing=!0;let e=this.queue.splice(0,this.queue.length),t=this.buildCountEvents(),n=[...e,...t];l("EventQueue","flush events to callback",{total:n.length,events:e.length,countEvents:t.length}),this.lastFlushTime=p(),this.eventBus.emit("report",n);try{await this.flushCallback(n),this.pendingCounts.clear(),l("EventQueue","flush completed successfully"),this.eventBus.emit("reported",n)}catch(r){throw l("EventQueue","flush failed, returning events to queue",{error:r instanceof Error?r.message:String(r)}),e.forEach(i=>this.queue.unshift(i)),r}finally{this.isFlushing=!1}}flushSync(){if(this.queue.length===0&&this.pendingCounts.size===0)return;let e=this.queue.splice(0,this.queue.length),t=new Map(this.pendingCounts),n=this.buildCountEvents(),r=[...e,...n];this.lastFlushTime=p(),this.eventBus.emit("report",r);try{this.syncFlushCallback(r),this.pendingCounts.clear(),this.eventBus.emit("reported",r)}catch(i){console.error("[LightSDK] Sync flush failed",i),e.forEach(s=>this.queue.unshift(s));for(let[s,a]of t)this.pendingCounts.has(s)||this.pendingCounts.set(s,a)}}size(){return this.queue.length}destroy(){this.timer&&(clearInterval(this.timer),this.timer=null),this.pauseTimer&&(clearTimeout(this.pauseTimer),this.pauseTimer=null),typeof document!="undefined"&&this.onVisibilityChange&&document.removeEventListener("visibilitychange",this.onVisibilityChange),typeof window!="undefined"&&(this.onBeforeUnload&&window.removeEventListener("beforeunload",this.onBeforeUnload),this.onPagehide&&window.removeEventListener("pagehide",this.onPagehide)),this.dedupeMap.clear(),this.pendingCounts.clear(),this.errorRateWindow={}}};var te={event_id:"eid",timestamp:"ts",start_timestamp:"sts",type:"t",level:"l",message:"m",platform:"p",release:"r",environment:"e",fingerprint:"fp",context_id:"cid",user:"u",tags:"tg",exception:"ex",request:"req",contexts:"ctx",breadcrumbs:"bc",transaction:"tx",duration:"d",spans:"sp",extra:"xt"},Xe=Object.fromEntries(Object.entries(te).map(([o,e])=>[e,o]));function ne(o){if(!o||typeof o!="object")return o;let e={};for(let[t,n]of Object.entries(o)){let r=te[t]||t;e[r]=n}return e}var O=class{constructor(e,t,n){this.useShortFields=!0;this.dsn=e,this.maxRetries=t,this.retryDelay=n}async report(e){if(l("Reporter","report called",{eventCount:e.length}),e.length===0){l("Reporter","report skipped: empty events");return}let t=this.buildEnvelope(e),n=C(this.dsn);l("Reporter","Envelope built",{envelopeSize:t.length,url:n});let r=0;for(;r<=this.maxRetries;)try{l("Reporter",`Sending request (attempt ${r+1}/${this.maxRetries+1})`),await this.send(t,!1),l("Reporter","Request succeeded");return}catch(i){let s=i.status;if(U("Reporter",`Request failed (attempt ${r+1})`,{status:s,error:i}),s&&s>=400&&s<500)throw i;if(r++,r>this.maxRetries)throw U("Reporter","All retries exhausted"),i;let a=Math.min(this.retryDelay*Math.pow(2,r-1),5e3);l("Reporter",`Retrying in ${a}ms`),await this.delay(a)}}reportSync(e){if(e.length===0)return;let t=this.buildEnvelope(e);try{if(this.sendSync(t))return}catch(n){}this.sendViaImage(t)}buildEnvelope(e){let t=this.extractSharedMeta(e),n={event_id:J(),sent_at:new Date().toISOString(),meta:t};this.useShortFields&&(n._sf=1);let r=this.applyRelativeTimestamps(e,n),s=[JSON.stringify(n)];for(let a of r){let u=this.stripSharedFields(a,t);this.useShortFields&&(u=ne(u));let c=JSON.stringify(u),h=JSON.stringify({type:this.getEnvelopeType(a),length:c.length});s.push(h,c)}return s.join(` -`)}applyRelativeTimestamps(e,t){if(e.length<=1)return e;let n=[],r=e[0].timestamp?new Date(e[0].timestamp).getTime():Date.now();t._rt=1,t._bt=r;for(let i=0;is.release===t.release)&&(n.release=t.release),t.environment&&e.every(s=>s.environment===t.environment)&&(n.environment=t.environment),t.user&&e.every(s=>JSON.stringify(s.user)===JSON.stringify(t.user))&&(n.user=t.user);let r=t.env;return r&&(n.env=r),n}stripSharedFields(e,t){let n={...e};return t.release&&n.release===t.release&&delete n.release,t.environment&&n.environment===t.environment&&delete n.environment,t.user&&JSON.stringify(n.user)===JSON.stringify(t.user)&&delete n.user,t.env&&delete n.env,n}getEnvelopeType(e){switch(e.type){case"error":return"event";case"performance":return"transaction";default:return e.type}}async send(e,t=!1){let n=C(this.dsn);if(navigator.sendBeacon)try{let r=new Blob([e],{type:"application/x-sentry-envelope"});if(navigator.sendBeacon(n,r))return}catch(r){}if(typeof fetch=="function")try{let r=new AbortController,i=setTimeout(()=>r.abort(),1e4),s=await fetch(n,{method:"POST",body:e,headers:{"Content-Type":"application/x-sentry-envelope"},keepalive:!0,signal:r.signal});if(clearTimeout(i),s.ok)return;let a=new Error(`HTTP ${s.status}`);throw a.status=s.status,a}catch(r){throw r}if(typeof XMLHttpRequest!="undefined")return new Promise((r,i)=>{let s=new XMLHttpRequest;s.open("POST",n,!t),s.setRequestHeader("Content-Type","application/x-sentry-envelope"),s.timeout=1e4,s.onload=()=>{if(s.status>=200&&s.status<300)r();else{let a=new Error(`HTTP ${s.status}`);a.status=s.status,i(a)}},s.onerror=()=>i(new Error("Network error")),s.ontimeout=()=>i(new Error("Request timeout")),s.send(e)});throw new Error("No transport available")}sendSync(e){let t=C(this.dsn);if(navigator.sendBeacon)try{let n=new Blob([e],{type:"application/x-sentry-envelope"});return navigator.sendBeacon(t,n)}catch(n){return!1}if(typeof XMLHttpRequest!="undefined")try{let n=new XMLHttpRequest;return n.open("POST",t,!1),n.setRequestHeader("Content-Type","application/x-sentry-envelope"),n.send(e),n.status>=200&&n.status<300}catch(n){return!1}return!1}sendViaImage(e){try{let t=C(this.dsn),n=new Image,r=encodeURIComponent(btoa(e)),i=t.includes("?")?"&":"?";return n.src=t+i+"sentry_data="+r.substring(0,2e3),!0}catch(t){return!1}}delay(e){return new Promise(t=>setTimeout(t,e))}};var F=class{constructor(e){this.plugins=new Map;this.client=e}add(e){if(!this.plugins.has(e.name)){this.plugins.set(e.name,e);try{e.setup(this.client)}catch(t){console.error(`[LightSDK] Plugin "${e.name}" setup error:`,t)}}}remove(e){let t=this.plugins.get(e);if(t){if(t.destroy)try{t.destroy()}catch(n){console.error(`[LightSDK] Plugin "${e}" destroy error:`,n)}this.plugins.delete(e)}}get(e){return this.plugins.get(e)}has(e){return this.plugins.has(e)}applyBeforeReport(e){let t=e;for(let n of this.plugins.values())if(n.beforeReport)try{let r=n.beforeReport(t);if(r===null)return null;t=r}catch(r){console.error(`[LightSDK] Plugin "${n.name}" beforeReport error:`,r)}return t}applyAfterReport(e){for(let t of this.plugins.values())if(t.afterReport)try{t.afterReport(e)}catch(n){console.error(`[LightSDK] Plugin "${t.name}" afterReport error:`,n)}}destroy(){for(let e of this.plugins.values())if(e.destroy)try{e.destroy()}catch(t){console.error(`[LightSDK] Plugin "${e.name}" destroy error:`,t)}this.plugins.clear()}};var $=class{constructor(e){this.breadcrumbs=[];this.enabled=!0;var t,n,r,i;if(!e.dsn)throw new Error("DSN is required");M(e.debug===!0),l("Client","Initializing SDK",{dsn:e.dsn,debug:e.debug,enabled:e.enabled!==!1}),this.dsn=G(e.dsn),this.configManager=new I(e),this.eventBus=new B,this.reporter=new O(this.dsn,(t=this.configManager.get("maxRetries"))!=null?t:3,(n=this.configManager.get("retryDelay"))!=null?n:1e3),this.pluginManager=new F(this),this.queue=new _((r=this.configManager.get("maxQueueSize"))!=null?r:100,(i=this.configManager.get("flushInterval"))!=null?i:5e3,this.eventBus,async s=>this.flushEvents(s),s=>this.syncFlushEvents(s)),this.enabled=this.configManager.get("enabled")!==!1,l("Client","SDK initialized",{enabled:this.enabled})}get maxBreadcrumbs(){var e;return(e=this.configManager.get("maxBreadcrumbs"))!=null?e:20}get config(){return this.configManager.getAll()}init(){this.enabled&&(this.queue.start(),this.emit("ready"))}async flushEvents(e){l("Client","flushEvents start",{eventCount:e.length});let t=[];for(let i of e){let s=this.pluginManager.applyBeforeReport(i);s?t.push(s):l("Client","Event filtered by beforeReport plugin",{type:i.type,message:"message"in i?i.message:void 0})}if(t.length===0){l("Client","flushEvents: all events filtered by beforeReport");return}let n=!0,r=[];for(let i of t){let s=this.configManager.applyToEvent(i,n);n=!1;let a=this.configManager.get("beforeSend"),u=a?a(s):s;if(!u){l("Client","Event filtered by beforeSend",{type:i.type});continue}r.push(u)}if(r.length===0){l("Client","flushEvents: all events filtered by beforeSend");return}l("Client","Reporting events",{count:r.length}),await this.reporter.report(r),l("Client","Report completed successfully"),this.configManager.markContextReported();for(let i of r)this.pluginManager.applyAfterReport(i)}syncFlushEvents(e){let t=[];for(let i of e){let s=this.pluginManager.applyBeforeReport(i);s&&t.push(s)}if(t.length===0)return;let n=!0,r=[];for(let i of t){let s=this.configManager.applyToEvent(i,n);n=!1;let a=this.configManager.get("beforeSend"),u=a?a(s):s;u&&r.push(u)}r.length!==0&&(this.reporter.reportSync(r),this.configManager.markContextReported())}on(e,t){this.eventBus.on(e,t)}off(e,t){this.eventBus.off(e,t)}emit(e,...t){this.eventBus.emit(e,...t)}captureException(e){if(l("Client","captureException called",{error:e instanceof Error?e.message:String(e)}),!this.enabled){l("Client","captureException skipped: SDK disabled");return}let t=this.buildErrorEvent(e);if(l("Client","Error event built",{type:t.type,message:t.message,fingerprint:t.fingerprint}),this.configManager.isIgnoredError(t.message)){l("Client","captureException skipped: error ignored by ignoreErrors");return}t.breadcrumbs=[...this.breadcrumbs],l("Client","Enqueue error event",{breadcrumbs:this.breadcrumbs.length}),this.queue.enqueue(t)}captureMessage(e,t="info"){if(!this.enabled)return;let n={type:"error",level:t,message:e,timestamp:p(),breadcrumbs:[...this.breadcrumbs]};this.configManager.isIgnoredError(e)||this.queue.enqueue(n)}captureEvent(e){if(!this.enabled)return;let t={timestamp:p(),level:"info",breadcrumbs:[...this.breadcrumbs],...e};this.queue.enqueue(t)}buildErrorEvent(e){let t=p();if(e instanceof Error){let r=P(e.stack,{maxFrames:5}),i=T(e.name,e.message,r);return{type:"error",level:"error",message:e.message,timestamp:t,exception:{type:e.name,value:e.message,stacktrace:{frames:r}},fingerprint:i}}return{type:"error",level:"error",message:String(e),timestamp:t}}setUser(e){this.configManager.setUser(e)}setTag(e,t){this.configManager.setTag(e,t)}setTags(e){this.configManager.setTags(e)}setExtra(e,t){this.configManager.setExtra(e,t)}addBreadcrumb(e){let t={...e,timestamp:p()};this.breadcrumbs.push(t),this.breadcrumbs.length>this.maxBreadcrumbs&&this.breadcrumbs.shift()}async flush(){await this.queue.flush()}disable(){this.enabled=!1}enable(){this.enabled=!0}use(e){this.pluginManager.add(e)}destroy(){this.queue.destroy(),this.pluginManager.destroy(),this.eventBus.destroy(),this.breadcrumbs=[]}},re=$;var K=class{constructor(){this.name="error";this.version="1.0.0";this.config={maxStackFrames:5,captureNodeModules:!1,captureColumn:!0,relativePathOnly:!1,resourceSampleRate:.1}}setup(e){this.client=e,this.loadConfig(),this.setupGlobalError(),this.setupUnhandledRejection(),this.setupResourceError()}loadConfig(){let e=this.client.config;e&&b(e.error)&&(this.config={...this.config,...e.error}),e.ignoreErrors&&(this.config.ignoreErrors=[...this.config.ignoreErrors||[],...e.ignoreErrors]),e.ignoreUrls&&(this.config.ignoreUrls=[...this.config.ignoreUrls||[],...e.ignoreUrls]),e.includePaths&&(this.config.includePaths=[...this.config.includePaths||[],...e.includePaths])}shouldIgnoreError(e){return e?L(e,this.config.ignoreErrors||[]):!1}shouldIgnoreScriptUrl(e){return D(e,this.config.ignoreUrls||[])}shouldIncludePath(e){let t=this.config.includePaths||[];return t.length===0?!0:e.some(n=>t.some(r=>{var i;return typeof r=="string"?(i=n.filename)==null?void 0:i.includes(r):r.test(n.filename||"")}))}shouldSample(){var t;let e=(t=this.config.sampleRate)!=null?t:1;return e>=1?!0:e<=0?!1:Math.random()=1?!0:e<=0?!1:Math.random(){try{if(this.originalOnError&&this.originalOnError.call(window,e,t,n,r,i),t&&this.shouldIgnoreScriptUrl(t))return!1;let s=this.buildErrorEvent(i||e,t,n,r);s&&this.client.captureEvent(s)}catch(s){console.error("[LightSDK] ErrorPlugin global error handler error:",s)}return!1})}setupUnhandledRejection(){typeof window!="undefined"&&(this.onUnhandledRejection=e=>{try{let t=e.reason,n=this.extractUrlFromReason(t);if(n&&this.shouldIgnoreScriptUrl(n))return;let r=this.buildErrorEvent(t);r&&(r.type==="error"&&(r.tags={...r.tags||{},unhandled:"true",promise:"true"}),this.client.captureEvent(r))}catch(t){console.error("[LightSDK] ErrorPlugin unhandledrejection handler error:",t)}},window.addEventListener("unhandledrejection",this.onUnhandledRejection))}extractUrlFromReason(e){if(e instanceof Error&&e.stack){let t=e.stack.match(/at\s+(?:.+?\s+)?\((https?:\/\/[^:]+):\d+:\d+\)/);if(t)return t[1];let n=e.stack.match(/(https?:\/\/[^\s)]+):\d+:\d+/);if(n)return n[1]}return null}setupResourceError(){typeof window!="undefined"&&(this.onResourceError=e=>{var i;let t=e.target;if(!t)return;let n=(i=t.tagName)==null?void 0:i.toLowerCase(),r=t.src||t.href;if(n&&r&&["img","script","link","audio","video"].includes(n))try{if(this.shouldIgnoreScriptUrl(r)||!this.shouldSampleResource())return;let s=`resource:${n}`,a=R(r);this.client.captureEvent({type:"error",level:"warning",message:`Resource load failed: ${n} ${a}`,timestamp:p(),fingerprint:s,tags:{resource_type:n,resource_url:a},exception:{type:"ResourceError",value:`Failed to load ${n} resource`}})}catch(s){console.error("[LightSDK] ErrorPlugin resource error handler error:",s)}},window.addEventListener("error",this.onResourceError,!0))}buildErrorEvent(e,t,n,r){let i=p();if(e instanceof Error){if(this.shouldIgnoreError(e.message))return null;let u=P(e.stack,{captureNodeModules:this.config.captureNodeModules,captureColumn:this.config.captureColumn,relativePathOnly:this.config.relativePathOnly,maxFrames:this.config.maxStackFrames});if(!this.shouldIncludePath(u)||!this.shouldSample())return null;let c=T(e.name,e.message,u);return{type:"error",level:"error",message:e.message,timestamp:i,exception:{type:e.name,value:e.message,stacktrace:{frames:u}},fingerprint:c}}let s=String(e);if(this.shouldIgnoreError(s))return null;let a=[];return t&&a.push({filename:t,lineno:n,colno:this.config.captureColumn?r:void 0,in_app:!0}),!this.shouldIncludePath(a)||!this.shouldSample()?null:{type:"error",level:"error",message:s,timestamp:i,exception:{type:"Error",value:s,stacktrace:{frames:a}}}}destroy(){typeof window!="undefined"&&(this.originalOnError!==void 0&&(window.onerror=this.originalOnError),this.onUnhandledRejection&&window.removeEventListener("unhandledrejection",this.onUnhandledRejection),this.onResourceError&&window.removeEventListener("error",this.onResourceError,!0))}},ie=K;var j=class{constructor(){this.name="performance";this.version="1.0.0";this.config={sampleRate:.1,captureLongTasks:!0,captureResources:!1,resourceSampleRate:.01,longTaskSampleRate:.05,captureNavigation:!0,captureFP:!0};this.observers=[];this.navLoadTimer=null;this.totalBlockingTime=0;this.fcpTime=null;this.lastLongTaskEndTime=0;this.ttiReported=!1;this.ttiTimer=null}setup(e){this.client=e,this.loadConfig(),this.observeWebVitals(),this.observeLongTasks(),this.observeNavigation(),this.observeResources()}loadConfig(){let e=this.client.config;e&&b(e.performance)&&(this.config={...this.config,...e.performance})}shouldSample(e="default"){var n,r,i;let t=(n=this.config.sampleRate)!=null?n:.1;return e==="resource"?t=(r=this.config.resourceSampleRate)!=null?r:.01:e==="longtask"?t=(i=this.config.longTaskSampleRate)!=null?i:.05:e==="vitals"&&(t=1),t>=1?!0:t<=0?!1:Math.random(){let n=t.getEntriesByName("first-paint");n.length>0&&this.reportMetric("FP",n[0].startTime,"ms",{},"vitals")});e.observe({type:"paint",buffered:!0}),this.observers.push(e)}catch(e){}}observeLCP(){try{let e=new PerformanceObserver(t=>{let n=t.getEntries(),r=n[n.length-1];if(r){let i=r.renderTime||r.loadTime||r.startTime;this.reportMetric("LCP",i,"ms",{},"vitals")}});e.observe({type:"largest-contentful-paint",buffered:!0}),this.observers.push(e)}catch(e){}}observeFID(){try{let e=new PerformanceObserver(t=>{let n=t.getEntries();if(n.length>0){let r=n[0],i=r.processingStart-r.startTime;this.reportMetric("FID",i,"ms",{},"vitals")}});e.observe({type:"first-input",buffered:!0}),this.observers.push(e)}catch(e){}}observeCLS(){try{let e=0,t=0,n=[],r=new PerformanceObserver(i=>{let s=i.getEntries();for(let a of s)if(!a.hadRecentInput){let u=n[0],c=n[n.length-1];t&&a.startTime-((c==null?void 0:c.duration)||0)<1e3&&a.startTime-u.startTime<5e3?(t+=a.value||0,n.push(a)):(t=a.value||0,n=[a]),t>e&&(e=t,this.reportMetric("CLS",e,"",{},"vitals"))}});r.observe({type:"layout-shift",buffered:!0}),this.observers.push(r)}catch(e){}}observeFCP(){try{let e=new PerformanceObserver(t=>{let n=t.getEntriesByName("first-contentful-paint");n.length>0&&(this.fcpTime=n[0].startTime,this.lastLongTaskEndTime=n[0].startTime,this.reportMetric("FCP",n[0].startTime,"ms",{},"vitals"),this.scheduleTTI())});e.observe({type:"paint",buffered:!0}),this.observers.push(e)}catch(e){}}observeTTFB(){try{let e=new PerformanceObserver(t=>{let n=t.getEntriesByType("navigation");if(n.length>0){let r=n[0],i=r.responseStart-r.requestStart;this.reportMetric("TTFB",Math.max(0,i),"ms",{},"vitals")}});e.observe({type:"navigation",buffered:!0}),this.observers.push(e)}catch(e){}}observeLongTasks(){if(this.config.captureLongTasks)try{let e=new PerformanceObserver(t=>{let n=t.getEntries();for(let r of n){let i=r.startTime+r.duration;if(i>this.lastLongTaskEndTime&&(this.lastLongTaskEndTime=i),this.fcpTime!==null&&r.startTime>=this.fcpTime){let s=r.duration-50;s>0&&(this.totalBlockingTime+=s)}this.reportMetric("longtask",r.duration,"ms",{},"longtask"),this.scheduleTTI()}});e.observe({type:"longtask",buffered:!0}),this.observers.push(e)}catch(e){}}scheduleTTI(){this.ttiReported||(this.ttiTimer&&clearTimeout(this.ttiTimer),this.ttiTimer=setTimeout(()=>{if(this.ttiReported)return;this.ttiReported=!0;let e=Math.max(this.lastLongTaskEndTime,this.fcpTime||0);this.reportMetric("TTI",e,"ms",{},"vitals"),this.reportMetric("TBT",this.totalBlockingTime,"ms",{},"vitals")},5e3))}observeNavigation(){this.config.captureNavigation&&typeof performance!="undefined"&&(this.onLoad=()=>{this.navLoadTimer=setTimeout(()=>{let e=performance.timing;if(!e)return;let t=e.navigationStart,n={dom_ready:e.domContentLoadedEventEnd-t,load_time:e.loadEventEnd-t,dns:e.domainLookupEnd-e.domainLookupStart,tcp:e.connectEnd-e.connectStart,ssl:e.secureConnectionStart>0?e.connectEnd-e.secureConnectionStart:0,ttfb:e.responseStart-e.requestStart,download:e.responseEnd-e.responseStart,dom_parse:e.domInteractive-e.responseEnd};for(let[r,i]of Object.entries(n))i>0&&this.reportMetric(r,i,"ms");this.navLoadTimer=null},0)},window.addEventListener("load",this.onLoad))}observeResources(){if(this.config.captureResources&&typeof performance!="undefined")try{let e=new PerformanceObserver(t=>{let n=t.getEntriesByType("resource");for(let r of n)r.duration>1e3&&this.reportMetric("resource_slow",r.duration,"ms",{resource_name:r.name.substring(0,200),resource_type:r.initiatorType},"resource")});e.observe({type:"resource",buffered:!0}),this.observers.push(e)}catch(e){}}getRating(e,t){let r={LCP:{good:2500,poor:4e3},FCP:{good:1800,poor:3e3},FP:{good:1800,poor:3e3},FID:{good:100,poor:300},CLS:{good:.1,poor:.25},TTFB:{good:800,poor:1800}}[e];return!r||t<=r.good?"good":t<=r.poor?"needs-improvement":"poor"}reportMetric(e,t,n,r={},i="default"){if(!this.shouldSample(i))return;let s=this.getRating(e,t),a={type:"performance",level:"info",metric:e,value:Math.round(t*100)/100,unit:n,rating:s,timestamp:p(),tags:{metric:e,rating:s,...r}};this.client.captureEvent(a)}destroy(){for(let e of this.observers)try{e.disconnect()}catch(t){}this.observers=[],this.ttiTimer&&(clearTimeout(this.ttiTimer),this.ttiTimer=null),this.navLoadTimer&&(clearTimeout(this.navLoadTimer),this.navLoadTimer=null),typeof window!="undefined"&&this.onLoad&&window.removeEventListener("load",this.onLoad)}},se=j;var W=class{constructor(){this.name="network";this.version="1.0.0";this.config={captureXHR:!0,captureFetch:!0,captureSuccess:!1,captureBody:!1,captureRequestBody:!1,captureResponseBody:!1,captureRequestHeaders:["content-type","user-agent"],captureResponseHeaders:["content-type","content-length"],errorSampleRate:1,successSampleRate:.01,slowThreshold:3e3,slowSampleRate:1,ignoreStatusCodes:[]}}setup(e){this.client=e,this.loadConfig(),this.config.captureFetch&&this.patchFetch(),this.config.captureXHR&&this.patchXHR()}loadConfig(){let e=this.client.config;e&&b(e.network)&&(this.config={...this.config,...e.network}),e.ignoreUrls&&(this.config.ignoreUrls=[...this.config.ignoreUrls||[],...e.ignoreUrls])}shouldIgnore(e){return D(e,this.config.ignoreUrls||[])}shouldSample(e,t){var r,i,s,a;let n=e?(r=this.config.errorSampleRate)!=null?r:1:(i=this.config.successSampleRate)!=null?i:.01;return!e&&t>=((s=this.config.slowThreshold)!=null?s:3e3)&&(n=(a=this.config.slowSampleRate)!=null?a:1),n>=1?!0:n<=0?!1:Math.random(){var f;let h=p()-r,w=c.ok,g=c.status;return(f=e.config.ignoreStatusCodes)!=null&&f.includes(g)||!e.shouldSample(!w,h)||(!w||e.config.captureSuccess)&&e.reportNetwork({sub_type:"fetch",method:s.toUpperCase(),url:a,status_code:g,duration:h,success:w,error:w?void 0:`HTTP ${g}`}),c},c=>{let h=p()-r;throw e.shouldSample(!0,h)&&e.reportNetwork({sub_type:"fetch",method:s.toUpperCase(),url:a,duration:h,success:!1,error:(c==null?void 0:c.message)||"Network error"}),c}),u}}patchXHR(){if(typeof XMLHttpRequest=="undefined")return;this.originalXHROpen=XMLHttpRequest.prototype.open,this.originalXHRSend=XMLHttpRequest.prototype.send;let e=this;XMLHttpRequest.prototype.open=function(t,n){return this._lightMethod=t,this._lightUrl=typeof n=="string"?n:n.toString(),this._lightTracked=!1,e.originalXHROpen.apply(this,arguments)},XMLHttpRequest.prototype.send=function(t){let n=p(),r=this._lightMethod||"GET",i=this._lightUrl||"",s=this._lightTracked;if(e.shouldIgnore(i)||s)return e.originalXHRSend.apply(this,arguments);this._lightTracked=!0;let a=R(i),u=0;t&&typeof t=="string"&&(u=t.length);let c=this.onloadend;return this.onloadend=function(h){var y;let w=p()-n,g=this.status,f=g>=200&&g<300;if(!((y=e.config.ignoreStatusCodes)!=null&&y.includes(g))&&e.shouldSample(!f,w)&&(!f||e.config.captureSuccess)){let m=0;try{let S=this.getResponseHeader("content-length");S&&(m=parseInt(S,10)),!m&&this.responseText&&(m=this.responseText.length)}catch(S){}e.reportNetwork({sub_type:"xhr",method:r.toUpperCase(),url:a,status_code:g,duration:w,request_size:u||void 0,response_size:m||void 0,success:f,error:f?void 0:`HTTP ${g}`})}if(c)return c.call(this,h)},e.originalXHRSend.apply(this,arguments)}}reportNetwork(e){let t={type:"network",level:e.success?"info":"error",timestamp:p(),tags:{method:e.method,sub_type:e.sub_type,success:String(e.success)},...e};this.client.captureEvent(t)}destroy(){this.originalFetch&&(window.fetch=this.originalFetch),this.originalXHROpen&&(XMLHttpRequest.prototype.open=this.originalXHROpen),this.originalXHRSend&&(XMLHttpRequest.prototype.send=this.originalXHRSend)}},oe=W;var X=class{constructor(){this.name="behavior";this.version="1.0.0";this.config={capturePV:!0,captureClick:!0,captureRoute:!0,captureDuration:!0,captureScroll:!0,clickThrottle:300,scrollThrottle:1e3,sampleRate:.01};this.lastClickTime=0;this.lastScrollTime=0;this.maxScrollDepth=0;this.pageEnterTime=0;this.scrollReported=!1}setup(e){this.client=e,this.loadConfig(),this.config.capturePV&&this.trackPV(),this.config.captureClick&&this.trackClick(),this.config.captureRoute&&this.trackRoute(),this.config.captureDuration&&this.trackPageDuration(),this.config.captureScroll&&this.trackScroll()}loadConfig(){let e=this.client.config;e&&b(e.behavior)&&(this.config={...this.config,...e.behavior})}shouldSample(){var t;let e=(t=this.config.sampleRate)!=null?t:.01;return e>=1?!0:e<=0?!1:Math.random(){var a,u,c;let t=p(),n=(a=this.config.clickThrottle)!=null?a:300;if(t-this.lastClickTime{let r=E();if(r!==e){let i=e,s=r;e=r,this.reportBehavior({sub_type:"route",page_url:s,referrer:i,properties:{from:i,to:s}}),this.pageEnterTime=p(),this.maxScrollDepth=0,this.scrollReported=!1}};this.originalPushState=history.pushState,this.originalReplaceState=history.replaceState;let n=this;history.pushState=function(){let r=n.originalPushState.apply(this,arguments);return setTimeout(t,0),r},history.replaceState=function(){let r=n.originalReplaceState.apply(this,arguments);return setTimeout(t,0),r},this.onPopState=()=>{setTimeout(t,0)},this.onHashchange=()=>{setTimeout(t,0)},window.addEventListener("popstate",this.onPopState),window.addEventListener("hashchange",this.onHashchange)}trackPageDuration(){if(typeof window=="undefined")return;this.pageEnterTime=p();let e=()=>{let t=p()-this.pageEnterTime;t>1e3&&(this.config.captureScroll&&!this.scrollReported&&this.reportScroll(),this.reportBehavior({sub_type:"duration",page_url:E(),properties:{duration:t,max_scroll_depth:this.maxScrollDepth}}))};this.onVisibilityChange=()=>{document.hidden?e():this.pageEnterTime=p()},this.onBeforeUnload=e,this.onPagehide=e,document.addEventListener("visibilitychange",this.onVisibilityChange),window.addEventListener("beforeunload",this.onBeforeUnload),window.addEventListener("pagehide",this.onPagehide)}trackScroll(){typeof window!="undefined"&&(this.onScroll=()=>{var r;let e=p(),t=(r=this.config.scrollThrottle)!=null?r:1e3;if(e-this.lastScrollTimethis.maxScrollDepth&&(this.maxScrollDepth=n)},window.addEventListener("scroll",this.onScroll,{passive:!0}))}reportScroll(){this.scrollReported||(this.scrollReported=!0,this.reportBehavior({sub_type:"scroll",page_url:E(),properties:{max_depth:this.maxScrollDepth}}))}reportBehavior(e){if(!this.shouldSample())return;let t={type:"behavior",level:"info",timestamp:p(),tags:{sub_type:e.sub_type,page_url:E()},...e};this.client.captureEvent(t)}destroy(){typeof window!="undefined"&&(this.originalPushState&&(history.pushState=this.originalPushState),this.originalReplaceState&&(history.replaceState=this.originalReplaceState),this.onPopState&&window.removeEventListener("popstate",this.onPopState),this.onHashchange&&window.removeEventListener("hashchange",this.onHashchange),this.onBeforeUnload&&window.removeEventListener("beforeunload",this.onBeforeUnload),this.onPagehide&&window.removeEventListener("pagehide",this.onPagehide),this.onScroll&&window.removeEventListener("scroll",this.onScroll)),typeof document!="undefined"&&(this.onClick&&document.removeEventListener("click",this.onClick,!0),this.onVisibilityChange&&document.removeEventListener("visibilitychange",this.onVisibilityChange))}},ae=X;var ve="light-sentry-offline",v="events",A=1e3,z=class{constructor(){this.name="offline";this.version="1.0.0";this.config={maxEvents:A};this.db=null;this.isOnline=!0;this.isSyncing=!1;this.pendingEvents=[]}setup(e){this.client=e,this.loadConfig(),this.initDatabase(),this.setupNetworkListeners()}loadConfig(){let e=this.client.config;e&&typeof e.offline=="object"&&(this.config={...this.config,...e.offline})}async initDatabase(){if(typeof indexedDB=="undefined"){console.warn("[LightSDK] OfflinePlugin: IndexedDB not available");return}return new Promise((e,t)=>{let n=indexedDB.open(ve,1);n.onerror=()=>{console.warn("[LightSDK] OfflinePlugin: Failed to open IndexedDB"),t(n.error)},n.onsuccess=()=>{this.db=n.result,e()},n.onupgradeneeded=r=>{let i=r.target.result,s=r.oldVersion;i.objectStoreNames.contains(v)||i.createObjectStore(v,{keyPath:"id"}).createIndex("timestamp","timestamp",{unique:!1})}})}setupNetworkListeners(){typeof window!="undefined"&&(this.isOnline=navigator.onLine,this.onOnline=()=>{console.info("[LightSDK] OfflinePlugin: Network online"),this.isOnline=!0,this.syncPendingEvents()},this.onOffline=()=>{console.info("[LightSDK] OfflinePlugin: Network offline"),this.isOnline=!1},window.addEventListener("online",this.onOnline),window.addEventListener("offline",this.onOffline))}generateId(){return`${Date.now()}-${Math.random().toString(36).substring(2,11)}`}async saveToIndexedDB(e){if(!this.db)return;let t=this.config.maxEvents||A,n=await this.getEventCount();return n>=t&&await this.deleteOldestEvents(n-t+1),new Promise((r,i)=>{let a=this.db.transaction([v],"readwrite").objectStore(v),u={id:this.generateId(),event:{...e,offline:!0},timestamp:p()},c=a.add(u);c.onsuccess=()=>r(),c.onerror=()=>i(c.error)})}getEventCount(){return this.db?new Promise((e,t)=>{let i=this.db.transaction([v],"readonly").objectStore(v).count();i.onsuccess=()=>e(i.result),i.onerror=()=>t(i.error)}):Promise.resolve(0)}async deleteOldestEvents(e){if(!(!this.db||e<=0))return new Promise((t,n)=>{let a=this.db.transaction([v],"readwrite").objectStore(v).index("timestamp").openCursor(),u=0;a.onsuccess=c=>{let h=c.target.result;h&&un(a.error)})}async getAllStoredEvents(){return this.db?new Promise((e,t)=>{let s=this.db.transaction([v],"readonly").objectStore(v).index("timestamp").getAll();s.onsuccess=()=>{let a=s.result||[];a.sort((u,c)=>u.timestamp-c.timestamp),e(a)},s.onerror=()=>t(s.error)}):[]}async clearStoredEvents(){if(this.db)return new Promise((e,t)=>{let i=this.db.transaction([v],"readwrite").objectStore(v).clear();i.onsuccess=()=>e(),i.onerror=()=>t(i.error)})}async syncPendingEvents(){if(!(!this.isOnline||this.isSyncing)){this.isSyncing=!0,console.info("[LightSDK] OfflinePlugin: Syncing pending events");try{let e=0;for(;this.pendingEvents.length>0;){let n=this.pendingEvents.shift();try{this.client.captureEvent(n),e++}catch(r){console.error("[LightSDK] OfflinePlugin: Failed to re-enqueue memory event",r)}}let t=await this.getAllStoredEvents();if(t.length>0)for(let n of t)try{let r=n.event;this.client.captureEvent(r),e++}catch(r){console.error("[LightSDK] OfflinePlugin: Failed to re-enqueue event",r)}try{await this.client.flush()}catch(n){}await this.clearStoredEvents(),console.info(`[LightSDK] OfflinePlugin: Synced ${e} events`)}catch(e){console.error("[LightSDK] OfflinePlugin: Sync failed",e)}finally{this.isSyncing=!1}}}beforeReport(e){if(!this.isOnline){let n=this.config.maxEvents||A;return this.pendingEvents.length>=n&&this.pendingEvents.shift(),this.pendingEvents.push(e),this.savePendingEventsToDB(),null}let t={...e};return delete t.offline,t}savePendingEventsToDB(){if(this.pendingEvents.length===0)return;let e=this.pendingEvents.splice(0,this.pendingEvents.length),t=0,n=()=>{if(t>=e.length)return;let r=e[t];this.saveToIndexedDB(r).then(()=>{t++,n()}).catch(i=>{console.error("[LightSDK] OfflinePlugin: Failed to save event offline",i),this.pendingEvents.unshift(...e.slice(t))})};n()}destroy(){typeof window!="undefined"&&(this.onOnline&&window.removeEventListener("online",this.onOnline),this.onOffline&&window.removeEventListener("offline",this.onOffline)),this.db&&(this.db.close(),this.db=null)}},ue=z;var V=class{constructor(){this.name="sampling";this.version="1.0.0";this.config={rates:{error:1,performance:1,network:1,behavior:1}}}setup(e){this.client=e,this.loadConfig()}loadConfig(){let e=this.client.config;if(e&&b(e.sampling)){let t=e.sampling;"rates"in t&&b(t.rates)&&(this.config.rates={...this.config.rates,...t.rates})}}shouldSample(e){var r;let t=(r=this.client.config.sampleRate)!=null?r:1;if(t<=0)return!1;let n=this.getTypeRate(e);return t>=1?this.randomCheck(n):this.randomCheck(t*n)}getTypeRate(e){let t=this.config.rates||{},n=e.type;if(n==="count")return 1;let r=t[n];return r!==void 0?r:1}randomCheck(e){return e>=1?!0:e<=0?!1:Math.random()typeof i=="string"))||[];(n.includes("performance")||n.includes("all"))&&t.push(new se),(n.includes("network")||n.includes("all"))&&t.push(new oe),(n.includes("behavior")||n.includes("all"))&&t.push(new ae),l("Index","Registering plugins",{count:t.length,plugins:t.map(i=>i.name)});for(let i of t)e.use(i);if(o.plugins)for(let i of o.plugins)typeof i=="object"&&i!==null&&"name"in i&&"setup"in i&&e.use(i);return e.init(),d=e,l("Index","init completed, globalClient set"),e}function be(){return d}function Ee(o){if(l("Index","captureException called",{hasClient:!!d}),!d){console.warn("[LightSDK] SDK not initialized. Call LightSentry.init() first.");return}d.captureException(o)}function we(o,e){if(l("Index","captureMessage called",{hasClient:!!d}),!d){console.warn("[LightSDK] SDK not initialized. Call LightSentry.init() first.");return}d.captureMessage(o,e)}function Se(o){if(l("Index","captureEvent called",{hasClient:!!d}),!d){console.warn("[LightSDK] SDK not initialized. Call LightSentry.init() first.");return}d.captureEvent(o)}function xe(o){d==null||d.setUser(o)}function Re(o,e){d==null||d.setTag(o,e)}function ke(o){d==null||d.setTags(o)}function Ce(o,e){d==null||d.setExtra(o,e)}function Le(o){d==null||d.addBreadcrumb(o)}async function Te(){await(d==null?void 0:d.flush())}function Pe(){d==null||d.disable()}function Me(){d==null||d.enable()}var Nt={init:ye,getClient:be,captureException:Ee,captureMessage:we,captureEvent:Se,setUser:xe,setTag:Re,setTags:ke,setExtra:Ce,addBreadcrumb:Le,flush:Te,disable:Pe,enable:Me};export{ae as BehaviorPlugin,re as Client,ie as ErrorPlugin,oe as NetworkPlugin,ue as OfflinePlugin,se as PerformancePlugin,ce as SamplingPlugin,Le as addBreadcrumb,Se as captureEvent,Ee as captureException,we as captureMessage,Nt as default,Pe as disable,Me as enable,Te as flush,be as getClient,ye as init,Ce as setExtra,Re as setTag,ke as setTags,xe as setUser}; +function de(s){try{let e=s.match(/^(https?):\/\/([^@]+)@([^/]+)\/(.+)$/);if(!e)throw new Error("Invalid DSN format");let[,t,n,r,i]=e;return{protocol:t,publicKey:n,host:r,projectId:i}}catch(e){throw new Error(`Failed to parse DSN: ${e.message}`)}}function P(s){return`${s.protocol}://${s.host}/api/${s.projectId}/envelope/?sentry_key=${s.publicKey}`}function W(){return"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx".replace(/[x]/g,()=>(Math.random()*16|0).toString(16))}function p(){return Date.now()}function I(){return typeof crypto!="undefined"&&crypto.randomUUID?crypto.randomUUID().replace(/-/g,""):W()}function y(s){return s!==null&&typeof s=="object"&&!Array.isArray(s)}function _(s,e){return!e||e.length===0?!1:e.some(t=>typeof t=="string"?s.includes(t):t.test(s))}function Pe(s){let e=5381,t=s.length;for(;t;)e=e*33^s.charCodeAt(--t);return e>>>0}function V(s){return Pe(s).toString(16)}function M(s,e,t=[]){let n=t.slice(0,3).map(i=>`${i.filename}:${i.lineno||0}`).join("|"),r=e.replace(/['"]?\d+['"]?/g,"").replace(/\s+/g," ").trim();return V(`${s}:${r}:${n}`)}function D(s,e={}){if(!s)return[];let{captureNodeModules:t=!1,captureColumn:n=!0,relativePathOnly:r=!1,maxFrames:i}=e,o=[],a=s.split(` +`),c=typeof location!="undefined"?`${location.protocol}//${location.host}`:"";for(let f of a){let E=f.match(/^\s*at\s*(.+?)\s*\((.+?):(\d+):(\d+)\)\s*$/);if(E){let[,h,g,m,v]=E,S=g.includes("node_modules");if(!t&&S)continue;let b=g;r&&c&&g.startsWith(c)&&(b=g.substring(c.length)),o.push({filename:b,function:h,lineno:parseInt(m,10),colno:n?parseInt(v,10):void 0,in_app:!S})}else{let h=f.match(/^\s*at\s*(.+?)@(.+?):(\d+):(\d+)\s*$/);if(h){let[,m,v,S,b]=h,x=v.includes("node_modules");if(!t&&x)continue;let le=v;r&&c&&v.startsWith(c)&&(le=v.substring(c.length)),o.push({filename:le,function:m||"",lineno:parseInt(S,10),colno:n?parseInt(b,10):void 0,in_app:!x});continue}let g=f.match(/^\s*at\s*(.+?):(\d+):(\d+)\s*$/);if(g){let[,m,v,S]=g,b=m.includes("node_modules");if(!t&&b)continue;let x=m;r&&c&&m.startsWith(c)&&(x=m.substring(c.length)),o.push({filename:x,lineno:parseInt(v,10),colno:n?parseInt(S,10):void 0,in_app:!b})}}}let d=o.reverse();return i!==void 0&&i>0?d.slice(0,i):d}var Q=!1;function B(s){Q=s}function u(s,e,t){if(!Q)return;let n=new Date().toISOString(),r=`[LightSDK][${s}]`;t!==void 0?console.log(`${r} ${n} ${e}`,t):console.log(`${r} ${n} ${e}`)}function C(s,e,t){if(!Q)return;let n=new Date().toISOString(),r=`[LightSDK][${s}][ERROR]`;t!==void 0?console.error(`${r} ${n} ${e}`,t):console.error(`${r} ${n} ${e}`)}var O="light_sentry_aid";function F(){if(typeof localStorage=="undefined")return null;try{let s=localStorage.getItem(O);return s||(s=I(),localStorage.setItem(O,s)),s}catch(s){return null}}function N(s){if(typeof localStorage=="undefined")return!1;try{return localStorage.setItem(O,s),!0}catch(e){return!1}}function pe(){if(typeof localStorage=="undefined")return!1;try{return localStorage.removeItem(O),!0}catch(s){return!1}}function he(s){return s.trackAnonymousUsers!==!1}function Ie(s){let e=[{name:"WeChat",pattern:/MicroMessenger\/([\d.]+)/i},{name:"QQ Browser",pattern:/QIBrowser\/([\d.]+)/i},{name:"UC Browser",pattern:/UCBrowser\/([\d.]+)/i},{name:"Edge",pattern:/Edg\/([\d.]+)/i},{name:"Edge",pattern:/Edge\/([\d.]+)/i},{name:"Opera",pattern:/OPR\/([\d.]+)/i},{name:"Opera",pattern:/Opera\/([\d.]+)/i},{name:"Firefox",pattern:/Firefox\/([\d.]+)/i},{name:"Safari",pattern:/Version\/([\d.]+).*Safari/i},{name:"Chrome",pattern:/Chrome\/([\d.]+)/i},{name:"IE",pattern:/MSIE ([\d.]+)/i},{name:"IE",pattern:/Trident.*rv:([\d.]+)/i}];for(let t of e){let n=s.match(t.pattern);if(n){let r=n[1]||"",i=r.split(".")[0]||"";return{name:t.name,version:r,major:i}}}return{name:"Unknown",version:"",major:""}}function _e(s){let e=[{name:"Windows 11",pattern:/Windows NT 10\.0.*Win64.*x64/i},{name:"Windows 10",pattern:/Windows NT 10\.0/i},{name:"Windows 8.1",pattern:/Windows NT 6\.3/i},{name:"Windows 8",pattern:/Windows NT 6\.2/i},{name:"Windows 7",pattern:/Windows NT 6\.1/i},{name:"Windows Vista",pattern:/Windows NT 6\.0/i},{name:"Windows XP",pattern:/Windows NT 5\.1/i},{name:"macOS",pattern:/Mac OS X ([\d_.]+)/i},{name:"iOS",pattern:/OS ([\d_.]+) like Mac OS X/i},{name:"Android",pattern:/Android ([\d.]+)/i},{name:"Android",pattern:/Android/i},{name:"Linux",pattern:/Linux/i}];for(let t of e){let n=s.match(t.pattern);if(n){let r=n[1]||"";return r&&(r=r.replace(/_/g,".")),{name:t.name,version:r}}}return{name:"Unknown",version:""}}function Me(s){let e=/Mobile|Android|iPhone|iPod|BlackBerry|Windows Phone|Opera Mini/i.test(s),t=/Tablet|iPad|PlayBook|Kindle|Silk/i.test(s),n="desktop";t?n="tablet":e&&(n="mobile");let r="",i="",o=s.match(/iPhone/i),a=s.match(/iPad/i),c=s.match(/SM-([A-Z0-9]+)/i),d=s.match(/Pixel ([0-9A-Z]+)/i),f=s.match(/HUAWEI ([A-Z0-9]+)/i);return o?(r="Apple",i="iPhone"):a?(r="Apple",i="iPad"):c?(r="Samsung",i=c[1]):d?(r="Google",i=`Pixel ${d[1]}`):f&&(r="Huawei",i=f[1]),{type:n,vendor:r,model:i}}function ge(){let s=typeof navigator!="undefined"?navigator.userAgent:"",e=Ie(s),t=_e(s),n=Me(s);return{browser:e,os:t,device:n,url:typeof location!="undefined"?location.href:"",referrer:typeof document!="undefined"?document.referrer:"",title:typeof document!="undefined"?document.title:"",language:typeof navigator!="undefined"?navigator.language:"",user_agent:s,screen_width:typeof screen!="undefined"?screen.width:0,screen_height:typeof screen!="undefined"?screen.height:0,viewport_width:typeof window!="undefined"?window.innerWidth:0,viewport_height:typeof window!="undefined"?window.innerHeight:0}}function w(){return typeof location!="undefined"?location.href:""}function fe(){return typeof document!="undefined"?document.referrer:""}function k(s){if(!s)return s;if(/^\s*javascript:/i.test(s))return"javascript:[filtered]";try{let e=new URL(s),t=["password","passwd","pwd","token","access_token","refresh_token","api_key","apikey","key","secret","private_key","code","auth","id_token","idToken","session","session_id"],n=e.searchParams,r=!1;for(let i of Array.from(n.keys())){let o=i.toLowerCase().replace(/[-_]/g,"_");t.some(a=>o.includes(a))&&(n.set(i,"[Filtered]"),r=!0)}if(e.hash&&e.hash.length>1){let i=e.hash.substring(1);if(i.includes("=")){let o=new URLSearchParams(i),a=!1;for(let c of Array.from(o.keys())){let d=c.toLowerCase().replace(/[-_]/g,"_");t.some(f=>d.includes(f))&&(o.set(c,"[Filtered]"),a=!0)}a&&(e.hash="#"+o.toString(),r=!0)}}return r?e.toString():s}catch(e){return s}}function H(s,e=[]){return!e||e.length===0?!1:e.some(t=>{if(typeof t=="string"){if(t.includes("*")){let n=t.replace(/[.+?^${}()|[\]\\]/g,"\\$&").replace(/\*/g,".*");return new RegExp(n).test(s)}return s.includes(t)}return t.test(s)})}var De={Chrome:"c",Safari:"s",Firefox:"f",Edge:"e",Opera:"o",IE:"i",WeChat:"w","QQ Browser":"q","UC Browser":"u","Mobile Chrome":"cm","Mobile Safari":"sm"},Be={"Windows 11":"w11","Windows 10":"w10","Windows 8.1":"w81","Windows 8":"w8","Windows 7":"w7","Windows Vista":"wv","Windows XP":"wxp",macOS:"m",iOS:"i",Android:"a",Linux:"l"};function G(){let s=ge(),e=De[s.browser.name]||s.browser.name.toLowerCase(),t=Be[s.os.name]||s.os.name.toLowerCase();return{browser:{name:e,version:s.browser.major},os:{name:t,version:s.os.version.split(".")[0]},device:{type:s.device.type,brand:s.device.vendor||void 0,model:s.device.model||void 0}}}function me(){let s=ge(),e=`${s.browser.name}|${s.browser.major}|${s.os.name}|${s.os.version.split(".")[0]}|${s.device.type}|${s.device.vendor}|${s.device.model}|${s.language}`;return V(e).substring(0,16)}var Oe={enabled:!0,sampleRate:1,maxQueueSize:100,flushInterval:5e3,maxRetries:3,retryDelay:1e3,environment:"production",contextLevel:{fatal:{maxStackFrames:5,maxBreadcrumbs:20},error:{maxStackFrames:5,maxBreadcrumbs:10},warning:{maxStackFrames:3,maxBreadcrumbs:5},info:{maxStackFrames:0,maxBreadcrumbs:0},debug:{maxStackFrames:0,maxBreadcrumbs:0}}},q=class{constructor(e){this.contexts=null;this.contextId=null;this.contextReported=!1;this.config={...Oe,...e}}markContextReported(){this.contextReported=!0}get(e){return this.config[e]}getAll(){return{...this.config}}set(e,t){this.config[e]=t}setUser(e){this.config.user=e||void 0}setTags(e){this.config.tags={...this.config.tags||{},...e}}setTag(e,t){this.config.tags||(this.config.tags={}),this.config.tags[e]=t}setExtra(e,t){this.config.extra||(this.config.extra={}),this.config.extra[e]=t}isIgnoredError(e){return _(e,this.config.ignoreErrors||[])}shouldSample(){var t;let e=(t=this.config.sampleRate)!=null?t:1;return e>=1?!0:e<=0?!1:Math.random()({...g})):void 0}:void 0}}if(e.breadcrumbs&&(n.breadcrumbs=e.breadcrumbs.map(h=>({...h}))),e.user&&(n.user={...e.user}),e.contexts&&(n.contexts={...e.contexts}),this.config.release&&(n.release=this.config.release),this.config.environment&&(n.environment=this.config.environment),n.platform="javascript",this.config.user&&(n.user=this.config.user),this.config.tags&&(n.tags={...this.config.tags,...e.tags||{}}),n.request?n.request.url||(n.request.url=w()):n.request={url:w(),referrer:fe()},this.contextId||(this.contextId=me()),n.context_id=this.contextId,!(((o=this.config.user)==null?void 0:o.id)||((a=e.user)==null?void 0:a.id))&&he(this.config)){let h=F();h&&(n.anonymousId=h)}let i=this.applyContextLevel(n);return t&&!this.contextReported&&(this.contexts||(this.contexts=G()),i.contexts=this.contexts,i.env={b:(c=this.contexts.browser)==null?void 0:c.name,bv:(d=this.contexts.browser)==null?void 0:d.version,os:(f=this.contexts.os)==null?void 0:f.name,osv:(E=this.contexts.os)==null?void 0:E.version}),i}applyContextLevel(e){let t=this.config.contextLevel;if(!t)return e;let n=e.level||"error",r=t[n]||t.error,i={...e};if("exception"in e&&e.exception&&typeof e.exception=="object"){let o=e.exception;if(o.stacktrace&&typeof o.stacktrace=="object"){let a=o.stacktrace;Array.isArray(a.frames)&&(r.maxStackFrames===0?delete i.exception:i.exception={...o,stacktrace:{...a,frames:a.frames.slice(0,r.maxStackFrames)}})}}return e.breadcrumbs&&Array.isArray(e.breadcrumbs)&&(r.maxBreadcrumbs===0?delete i.breadcrumbs:i.breadcrumbs=e.breadcrumbs.slice(-r.maxBreadcrumbs)),i}};var U=class{constructor(){this.handlers=new Map}on(e,t){this.handlers.has(e)||this.handlers.set(e,[]),this.handlers.get(e).push(t)}off(e,t){let n=this.handlers.get(e);if(n){let r=n.indexOf(t);r>-1&&n.splice(r,1)}}emit(e,...t){let n=this.handlers.get(e);if(n)for(let r of n)try{r(...t)}catch(i){console.error("[LightSDK] EventBus handler error:",i)}}once(e,t){let n=(...r)=>{this.off(e,n),t(...r)};this.on(e,n)}destroy(){this.handlers.clear()}};var $=class{constructor(e,t,n,r,i){this.queue=[];this.timer=null;this.lastFlushTime=0;this.isFlushing=!1;this.dedupeMap=new Map;this.pendingCounts=new Map;this.errorRateWindow={};this.paused=!1;this.pauseTimer=null;this.maxSize=e,this.flushInterval=t,this.eventBus=n,this.flushCallback=r,this.syncFlushCallback=i}start(){this.startTimer(),this.setupVisibilityListener()}startTimer(){this.timer||(this.timer=setInterval(()=>{(this.queue.length>0||this.pendingCounts.size>0)&&this.flush()},this.flushInterval))}setupVisibilityListener(){this.onVisibilityChange=()=>{document.hidden&&(this.queue.length>0||this.pendingCounts.size>0)&&this.flushSync()},typeof document!="undefined"&&document.addEventListener("visibilitychange",this.onVisibilityChange),this.onBeforeUnload=()=>{(this.queue.length>0||this.pendingCounts.size>0)&&this.flushSync()},this.onPagehide=()=>{(this.queue.length>0||this.pendingCounts.size>0)&&this.flushSync()},typeof window!="undefined"&&(window.addEventListener("beforeunload",this.onBeforeUnload),window.addEventListener("pagehide",this.onPagehide))}checkInfiniteLoop(e){let t=p(),n=t-1e3;this.errorRateWindow[e]||(this.errorRateWindow[e]=[]);let r=this.errorRateWindow[e];for(r.push(t);r.length>0&&r[0]10?(this.paused||(console.warn("[LightSDK] Infinite loop detected, pausing SDK for 60s",{fingerprint:e,count:r.length}),this.eventBus.emit("error",new Error("Infinite loop detected")),this.paused=!0,this.pauseTimer&&clearTimeout(this.pauseTimer),this.pauseTimer=setTimeout(()=>{this.paused=!1,this.errorRateWindow={},console.info("[LightSDK] Resumed after infinite loop detection")},6e4)),!0):!1}enqueue(e){if(u("EventQueue","enqueue called",{type:e.type,level:e.level,message:"message"in e?e.message:void 0}),this.paused){u("EventQueue","enqueue skipped: queue paused (infinite loop detected)");return}this.cleanupExpiredDedupeEntries();let t=this.getDedupeKey(e);if(t){if(this.checkInfiniteLoop(t)){u("EventQueue","enqueue skipped: infinite loop detected",{fingerprint:t});return}let n=p(),r=this.dedupeMap.get(t);if(r)if(n-r.lastTime<6e4){if(r.count>=3){if(!this.pendingCounts.has(t))this.pendingCounts.set(t,{count:1,ts_start:n,ts_end:n});else{let i=this.pendingCounts.get(t);i.count++,i.ts_end=n}u("EventQueue","enqueue skipped: deduped (count >= 3)",{fingerprint:t,count:r.count});return}r.count++,r.lastTime=n,u("EventQueue","Dedup count incremented",{fingerprint:t,count:r.count})}else this.dedupeMap.set(t,{count:1,lastTime:n,firstReported:!0}),this.pendingCounts.delete(t),u("EventQueue","Dedup entry reset (expired)",{fingerprint:t});else this.dedupeMap.set(t,{count:1,lastTime:n,firstReported:!1}),u("EventQueue","New dedup entry created",{fingerprint:t})}this.queue.push(e),u("EventQueue","Event added to queue",{queueSize:this.queue.length}),this.eventBus.emit("event",e),this.queue.length>=this.maxSize&&(u("EventQueue","Queue reached maxSize, triggering flush",{maxSize:this.maxSize}),this.flush())}cleanupExpiredDedupeEntries(){if(Math.random()>.1)return;let e=p(),t=6e4;for(let[n,r]of this.dedupeMap)e-r.lastTime>t&&this.dedupeMap.delete(n)}buildCountEvents(){let e=[];for(let[t,n]of this.pendingCounts.entries()){let r={type:"count",fingerprint:t,count:n.count,ts_start:n.ts_start,ts_end:n.ts_end,timestamp:p(),level:"info"};e.push(r)}return e}getDedupeKey(e){if(e.type==="error"){let t=e;return t.fingerprint||t.message}return null}async flush(){if(u("EventQueue","flush called",{queueSize:this.queue.length,pendingCounts:this.pendingCounts.size,isFlushing:this.isFlushing}),this.queue.length===0&&this.pendingCounts.size===0){u("EventQueue","flush skipped: queue is empty");return}if(this.isFlushing){u("EventQueue","flush skipped: already flushing");return}this.isFlushing=!0;let e=this.queue.splice(0,this.queue.length),t=this.buildCountEvents(),n=[...e,...t];u("EventQueue","flush events to callback",{total:n.length,events:e.length,countEvents:t.length}),this.lastFlushTime=p(),this.eventBus.emit("report",n);try{await this.flushCallback(n),this.pendingCounts.clear(),u("EventQueue","flush completed successfully"),this.eventBus.emit("reported",n)}catch(r){throw u("EventQueue","flush failed, returning events to queue",{error:r instanceof Error?r.message:String(r)}),e.forEach(i=>this.queue.unshift(i)),r}finally{this.isFlushing=!1}}flushSync(){if(this.queue.length===0&&this.pendingCounts.size===0)return;let e=this.queue.splice(0,this.queue.length),t=new Map(this.pendingCounts),n=this.buildCountEvents(),r=[...e,...n];this.lastFlushTime=p(),this.eventBus.emit("report",r);try{this.syncFlushCallback(r),this.pendingCounts.clear(),this.eventBus.emit("reported",r)}catch(i){console.error("[LightSDK] Sync flush failed",i),e.forEach(o=>this.queue.unshift(o));for(let[o,a]of t)this.pendingCounts.has(o)||this.pendingCounts.set(o,a)}}size(){return this.queue.length}destroy(){this.timer&&(clearInterval(this.timer),this.timer=null),this.pauseTimer&&(clearTimeout(this.pauseTimer),this.pauseTimer=null),typeof document!="undefined"&&this.onVisibilityChange&&document.removeEventListener("visibilitychange",this.onVisibilityChange),typeof window!="undefined"&&(this.onBeforeUnload&&window.removeEventListener("beforeunload",this.onBeforeUnload),this.onPagehide&&window.removeEventListener("pagehide",this.onPagehide)),this.queue=[],this.dedupeMap.clear(),this.pendingCounts.clear(),this.errorRateWindow={}}};var ve={event_id:"eid",timestamp:"ts",start_timestamp:"sts",type:"t",level:"l",message:"m",platform:"p",release:"r",environment:"e",fingerprint:"fp",context_id:"cid",user:"u",tags:"tg",exception:"ex",request:"req",contexts:"ctx",breadcrumbs:"bc",transaction:"tx",duration:"d",spans:"sp",extra:"xt"},xt=Object.fromEntries(Object.entries(ve).map(([s,e])=>[e,s]));function ye(s){if(!s||typeof s!="object")return s;let e={};for(let[t,n]of Object.entries(s)){let r=ve[t]||t;e[r]=n}return e}var A=class{constructor(e,t,n){this.useShortFields=!0;this.dsn=e,this.maxRetries=t,this.retryDelay=n}async report(e){if(u("Reporter","report called",{eventCount:e.length}),e.length===0){u("Reporter","report skipped: empty events");return}let t=this.buildEnvelope(e),n=P(this.dsn);u("Reporter","Envelope built",{envelopeSize:t.length,url:n});let r=0;for(;r<=this.maxRetries;)try{u("Reporter",`Sending request (attempt ${r+1}/${this.maxRetries+1})`),await this.send(t,!1),u("Reporter","Request succeeded");return}catch(i){let o=i.status;if(C("Reporter",`Request failed (attempt ${r+1})`,{status:o,error:i}),o&&o>=400&&o<500)throw i;if(r++,r>this.maxRetries)throw C("Reporter","All retries exhausted"),i;let a=Math.min(this.retryDelay*Math.pow(2,r-1),5e3);u("Reporter",`Retrying in ${a}ms`),await this.delay(a)}}reportSync(e){if(e.length===0)return;let t=this.buildEnvelope(e);try{if(this.sendSync(t))return}catch(n){}this.sendViaImage(t)}buildEnvelope(e){let t=this.extractSharedMeta(e),n={event_id:W(),sent_at:new Date().toISOString(),meta:t};this.useShortFields&&(n._sf=1);let r=this.applyRelativeTimestamps(e,n),o=[JSON.stringify(n)];for(let a of r){let c=this.stripSharedFields(a,t);this.useShortFields&&(c=ye(c));let d=JSON.stringify(c),f=JSON.stringify({type:this.getEnvelopeType(a),length:d.length});o.push(f,d)}return o.join(` +`)}applyRelativeTimestamps(e,t){if(e.length<=1)return e;let n=[],r=e[0].timestamp?new Date(e[0].timestamp).getTime():Date.now();t._rt=1,t._bt=r;for(let i=0;io.release===t.release)&&(n.release=t.release),t.environment&&e.every(o=>o.environment===t.environment)&&(n.environment=t.environment),t.user&&e.every(o=>JSON.stringify(o.user)===JSON.stringify(t.user))&&(n.user=t.user);let r=t.env;return r&&(n.env=r),n}stripSharedFields(e,t){let n={...e};return t.release&&n.release===t.release&&delete n.release,t.environment&&n.environment===t.environment&&delete n.environment,t.user&&JSON.stringify(n.user)===JSON.stringify(t.user)&&delete n.user,t.env&&delete n.env,n}getEnvelopeType(e){switch(e.type){case"error":return"event";default:return e.type}}async send(e,t=!1){let n=P(this.dsn);if(navigator.sendBeacon)try{let r=new Blob([e],{type:"application/x-sentry-envelope"});if(navigator.sendBeacon(n,r))return}catch(r){}if(typeof fetch=="function")try{let r=new AbortController,i=setTimeout(()=>r.abort(),1e4),o=await fetch(n,{method:"POST",body:e,headers:{"Content-Type":"application/x-sentry-envelope"},keepalive:!0,signal:r.signal});if(clearTimeout(i),o.ok)return;let a=new Error(`HTTP ${o.status}`);throw a.status=o.status,a}catch(r){throw r}if(typeof XMLHttpRequest!="undefined")return new Promise((r,i)=>{let o=new XMLHttpRequest;o.open("POST",n,!t),o.setRequestHeader("Content-Type","application/x-sentry-envelope"),o.timeout=1e4,o.onload=()=>{if(o.status>=200&&o.status<300)r();else{let a=new Error(`HTTP ${o.status}`);a.status=o.status,i(a)}},o.onerror=()=>i(new Error("Network error")),o.ontimeout=()=>i(new Error("Request timeout")),o.send(e)});throw new Error("No transport available")}sendSync(e){let t=P(this.dsn);if(navigator.sendBeacon)try{let n=new Blob([e],{type:"application/x-sentry-envelope"});return navigator.sendBeacon(t,n)}catch(n){return!1}if(typeof XMLHttpRequest!="undefined")try{let n=new XMLHttpRequest;return n.open("POST",t,!1),n.setRequestHeader("Content-Type","application/x-sentry-envelope"),n.send(e),n.status>=200&&n.status<300}catch(n){return!1}return!1}sendViaImage(e){try{let t=P(this.dsn),n=new Image,r=encodeURIComponent(btoa(e)),i=t.includes("?")?"&":"?";return n.src=t+i+"sentry_data="+r.substring(0,2e3),!0}catch(t){return!1}}delay(e){return new Promise(t=>setTimeout(t,e))}};var j=class{constructor(e){this.plugins=new Map;this.client=e}add(e){if(!this.plugins.has(e.name)){this.plugins.set(e.name,e);try{e.setup(this.client)}catch(t){console.error(`[LightSDK] Plugin "${e.name}" setup error:`,t)}}}remove(e){let t=this.plugins.get(e);if(t){if(t.destroy)try{t.destroy()}catch(n){console.error(`[LightSDK] Plugin "${e}" destroy error:`,n)}this.plugins.delete(e)}}get(e){return this.plugins.get(e)}has(e){return this.plugins.has(e)}applyBeforeReport(e){let t=e;for(let n of this.plugins.values())if(n.beforeReport)try{let r=n.beforeReport(t);if(r===null)return null;t=r}catch(r){console.error(`[LightSDK] Plugin "${n.name}" beforeReport error:`,r)}return t}applyAfterReport(e){for(let t of this.plugins.values())if(t.afterReport)try{t.afterReport(e)}catch(n){console.error(`[LightSDK] Plugin "${t.name}" afterReport error:`,n)}}destroy(){for(let e of this.plugins.values())if(e.destroy)try{e.destroy()}catch(t){console.error(`[LightSDK] Plugin "${e.name}" destroy error:`,t)}this.plugins.clear()}};var K="sentry-";function J(s){let e=[];for(let[n,r]of Object.entries(s)){if(r==null||r==="")continue;let i=n.startsWith(K)?n:`${K}${n}`;e.push(`${i}=${encodeURIComponent(String(r))}`)}let t=e.join(",");if(t.length>8192){t=t.substring(0,8192);let n=t.lastIndexOf(",");n>0&&(t=t.substring(0,n))}return t}function Fe(s){let e={};if(!s)return e;let t=s.split(",");for(let n of t){let r=n.indexOf("=");if(r===-1)continue;let i=n.substring(0,r).trim(),o=decodeURIComponent(n.substring(r+1).trim()),a=i;i.startsWith(K)&&(a=i.substring(K.length)),a&&(e[a]=o)}return e}function Y(s,e){let t={trace_id:s};return e!=null&&e.dsnPublicKey&&(t.public_key=e.dsnPublicKey),(e==null?void 0:e.sampled)!==void 0&&(t.sampled=e.sampled?"true":"false"),(e==null?void 0:e.sampleRate)!==void 0&&(t.sample_rate=String(e.sampleRate)),e!=null&&e.user&&(e.user.id&&(t.user_id=e.user.id),e.user.segment&&(t.user_segment=e.user.segment)),e!=null&&e.release&&(t.release=e.release),e!=null&&e.environment&&(t.environment=e.environment),t}function Ne(){return I().replace(/-/g,"")}function He(){return I().replace(/-/g,"").substring(0,16)}function z(s){return s>=200&&s<300?"ok":s===400?"invalid_argument":s===401?"unauthenticated":s===403?"permission_denied":s===404?"not_found":s===409?"already_exists":s===429?"resource_exhausted":s>=400&&s<500?"invalid_argument":s>=500&&s<600?"internal_error":"unknown_error"}function Se(s){if(s==null||s==="")return"unknown_error";let e=typeof s=="string"?parseInt(s,10):s;return e===0||e===1?"ok":e>=10&&e<20?"invalid_argument":e>=20&&e<30?"not_found":e>=30&&e<40?"already_exists":e>=50?"internal_error":"unknown_error"}function Z(s,e){if(s===void 0)return"unknown_error";if(typeof s=="string"){let t=s.toLowerCase();if(t==="ok"||t==="success")return"ok";if(t==="cancelled"||t==="canceled")return"cancelled";if(t==="deadline_exceeded")return"deadline_exceeded";if(t==="not_found")return"not_found";if(t==="already_exists")return"already_exists";if(t==="permission_denied")return"permission_denied";if(t==="resource_exhausted")return"resource_exhausted";if(t==="failed_precondition")return"failed_precondition";if(t==="invalid_argument")return"invalid_argument";if(t==="unauthenticated")return"unauthenticated";if(t==="internal_error")return"internal_error";let n=parseInt(s,10);return isNaN(n)?"unknown_error":Z(n,e)}if(typeof s=="number"){if(s>=200&&s<600)return z(s);if(e!=null&&e.startsWith("db"))return Se(s);if(s===0)return"ok";if(s>0)return"unknown_error"}return"unknown_error"}var R=class s{constructor(e,t,n){this.tags={};this.data={};this._isFinished=!1;this.traceId=e.traceId||Ne(),this.spanId=e.spanId||He(),this.parentSpanId=e.parentSpanId,this.op=e.op,this.description=e.description,this.status=e.status,this.tags={...e.tags},this.data={...e.data},this.startTimestamp=e.startTimestamp||p(),this.transaction=t,this._client=n}setTag(e,t){return this.tags[e]=t,this}setData(e,t){return this.data[e]=t,this}setStatus(e){return this.status=e,this}setHttpStatus(e){return this.setStatus(z(e)),this.setTag("http.status_code",String(e)),this}setStatusFromResponse(e,t){let n=Z(e,this.op);return this.setStatus(n),t&&e!==void 0&&this.setTag(t,String(e)),this}startChild(e={}){let t=this.transaction,n=(t==null?void 0:t.sampled)!==!1,r=new s({...e,traceId:this.traceId,parentSpanId:this.spanId},t,this._client);return t&&n&&t._addSpan(r),r}finish(e){var t;if(!this._isFinished&&(this._isFinished=!0,this.endTimestamp=e||p(),this._client)){let n=this._client;(t=n.tracingManager)!=null&&t.onSpanFinished&&n.tracingManager.onSpanFinished(this)}}toTraceparent(){var n;let e=(n=this.transaction)==null?void 0:n.sampled,t=e===void 0?"":e?"1":"0";return t?`${this.traceId}-${this.spanId}-${t}`:`${this.traceId}-${this.spanId}`}toJSON(){return{trace_id:this.traceId,span_id:this.spanId,parent_span_id:this.parentSpanId,op:this.op,description:this.description,status:this.status,tags:Object.keys(this.tags).length>0?{...this.tags}:void 0,data:Object.keys(this.data).length>0?{...this.data}:void 0,start_timestamp:this.startTimestamp,timestamp:this.endTimestamp||this.startTimestamp}}},L=class extends R{constructor(t,n,r,i,o,a){super(t,void 0,n);this.spans=[];this.maxSpans=1e3;this._droppedSpans=0;this.name=t.name,this.type=t.type,this.sampled=t.sampled,this.transaction=this,this._dsnPublicKey=r,this._release=i,this._environment=o,a!==void 0&&(this.maxSpans=a)}_addSpan(t){if(this.spans.length>=this.maxSpans){this._droppedSpans++;return}this.spans.push(t)}_ensureBaggage(){return this._baggage||(this._baggage=Y(this.traceId,{dsnPublicKey:this._dsnPublicKey,sampled:this.sampled,release:this._release,environment:this._environment})),this._baggage}setBaggage(t,n){let r=this._ensureBaggage();return r[t]=n,this}setUserBaggage(t,n){let r=this._ensureBaggage();return t!==void 0?r.user_id=t:delete r.user_id,n!==void 0?r.user_segment=n:delete r.user_segment,this}toBaggage(){let t=this._ensureBaggage();return J(t)}getBaggage(){return this._baggage}finish(t){var n;if(!this._isFinished){if(super.finish(t),this._client&&this.sampled){let r=this.toEvent();this._client.captureEvent(r)}if(this._client){let r=this._client;(n=r.tracingManager)!=null&&n.onTransactionFinished&&r.tracingManager.onTransactionFinished(this)}}}_getSource(){switch(this.type){case"pageload":return"url";case"navigation":return"route";case"user-interaction":return"ui";default:return"custom"}}toEvent(){let t=this.toJSON(),n={...t.data},r=n.measurements;return delete n.measurements,{type:"transaction",transaction:this.name,transaction_info:{source:this._getSource()},level:"info",timestamp:t.timestamp,start_timestamp:t.start_timestamp,spans:this.spans.map(i=>i.toJSON()),contexts:{trace:{trace_id:this.traceId,span_id:this.spanId,parent_span_id:this.parentSpanId,op:this.op,status:this.status}},tags:t.tags,extra:Object.keys(n).length>0?n:void 0,measurements:r,platform:"javascript"}}toJSON(){return{...super.toJSON(),transaction:this.name,type:this.type,spans:this.spans.map(n=>n.toJSON()),sampled:this.sampled}}};var X=class{constructor(e,t,n){this.currentTransaction=null;this.spanStack=[];this.config=e,this._client=t,this.dsnPublicKey=n}updateConfig(e){var t,n;this.config=e,this.currentTransaction&&this.currentTransaction.setUserBaggage((t=e.user)==null?void 0:t.id,(n=e.user)==null?void 0:n.segment)}shouldSample(e,t){var i;let n=this.config.tracesSampler;if(n){let o={...e,parentSampled:t},a=n(o);if(typeof a=="boolean")return a;let c=Math.max(0,Math.min(1,a));return c===0?!1:c===1?!0:Math.random()=1?!0:r<=0?!1:Math.random()0?this.spanStack[this.spanStack.length-1]:null}setCurrentSpan(e){e===null?this.spanStack.length>1&&this.spanStack.pop():this.spanStack.push(e)}startSpan(e){let t=this.getCurrentSpan();if(!t&&!e.traceId)return u("TracingManager","startSpan skipped: no active span and no traceId"),null;let n;return t?n=t.startChild(e):(n=new R({...e,parentSpanId:e.parentSpanId}),this.currentTransaction&&(this.currentTransaction.sampled!==!1&&this.currentTransaction._addSpan(n),n.transaction=this.currentTransaction)),this.spanStack.push(n),u("TracingManager","Span started",{op:n.op,description:n.description,spanId:n.spanId,parentSpanId:n.parentSpanId,stackDepth:this.spanStack.length}),n}onSpanFinished(e){let t=this.spanStack.lastIndexOf(e);t!==-1&&this.spanStack.splice(t,1),this.spanStack.length===0&&this.currentTransaction&&(this.spanStack=[this.currentTransaction]),u("TracingManager","Span finished",{op:e.op,description:e.description,spanId:e.spanId,stackDepth:this.spanStack.length})}onTransactionFinished(e){this.currentTransaction===e&&(this.currentTransaction=null,this.spanStack=[]),u("TracingManager","Transaction finished",{name:e.name,traceId:e.traceId,spanCount:e.spans.length,sampled:e.sampled})}finishSpan(e){e.finish()}finishTransaction(e){e.finish()}destroy(){if(this.currentTransaction)try{this.currentTransaction.setStatus("aborted"),this.currentTransaction.finish()}catch(e){}this.currentTransaction=null,this.spanStack=[]}};var ee=class{constructor(e){this.breadcrumbs=[];this.enabled=!0;var t,n,r,i;if(!e.dsn)throw new Error("DSN is required");B(e.debug===!0),u("Client","Initializing SDK",{dsn:e.dsn,debug:e.debug,enabled:e.enabled!==!1}),this.dsn=de(e.dsn),this.configManager=new q(e),this.eventBus=new U,this.reporter=new A(this.dsn,(t=this.configManager.get("maxRetries"))!=null?t:3,(n=this.configManager.get("retryDelay"))!=null?n:1e3),this.pluginManager=new j(this),this.tracingManager=new X(e,this,this.dsn.publicKey),this.queue=new $((r=this.configManager.get("maxQueueSize"))!=null?r:100,(i=this.configManager.get("flushInterval"))!=null?i:5e3,this.eventBus,async o=>this.flushEvents(o),o=>this.syncFlushEvents(o)),this.enabled=this.configManager.get("enabled")!==!1,u("Client","SDK initialized",{enabled:this.enabled})}get maxBreadcrumbs(){var e;return(e=this.configManager.get("maxBreadcrumbs"))!=null?e:20}get config(){return this.configManager.getAll()}init(){this.enabled&&(this.queue.start(),this.emit("ready"))}async flushEvents(e){u("Client","flushEvents start",{eventCount:e.length});let t=[];for(let i of e){let o=this.pluginManager.applyBeforeReport(i);o?t.push(o):u("Client","Event filtered by beforeReport plugin",{type:i.type,message:"message"in i?i.message:void 0})}if(t.length===0){u("Client","flushEvents: all events filtered by beforeReport");return}let n=!0,r=[];for(let i of t){let o=this.configManager.applyToEvent(i,n);n=!1;let a=this.configManager.get("beforeSend"),c=a?a(o):o;if(!c){u("Client","Event filtered by beforeSend",{type:i.type});continue}r.push(c)}if(r.length===0){u("Client","flushEvents: all events filtered by beforeSend");return}u("Client","Reporting events",{count:r.length}),await this.reporter.report(r),u("Client","Report completed successfully"),this.configManager.markContextReported();for(let i of r)this.pluginManager.applyAfterReport(i)}syncFlushEvents(e){let t=[];for(let i of e){let o=this.pluginManager.applyBeforeReport(i);o&&t.push(o)}if(t.length===0)return;let n=!0,r=[];for(let i of t){let o=this.configManager.applyToEvent(i,n);n=!1;let a=this.configManager.get("beforeSend"),c=a?a(o):o;c&&r.push(c)}r.length!==0&&(this.reporter.reportSync(r),this.configManager.markContextReported())}on(e,t){this.eventBus.on(e,t)}off(e,t){this.eventBus.off(e,t)}emit(e,...t){this.eventBus.emit(e,...t)}captureException(e){if(u("Client","captureException called",{error:e instanceof Error?e.message:String(e)}),!this.enabled){u("Client","captureException skipped: SDK disabled");return}let t=this.buildErrorEvent(e);if(u("Client","Error event built",{type:t.type,message:t.message,fingerprint:t.fingerprint}),this.configManager.isIgnoredError(t.message)){u("Client","captureException skipped: error ignored by ignoreErrors");return}this.attachTraceContext(t),t.breadcrumbs=[...this.breadcrumbs],u("Client","Enqueue error event",{breadcrumbs:this.breadcrumbs.length}),this.queue.enqueue(t)}captureMessage(e,t="info"){if(!this.enabled)return;let n={type:"error",level:t,message:e,timestamp:p(),breadcrumbs:[...this.breadcrumbs]};this.configManager.isIgnoredError(e)||(this.attachTraceContext(n),this.queue.enqueue(n))}captureEvent(e){if(!this.enabled)return;let t={timestamp:p(),level:"info",breadcrumbs:[...this.breadcrumbs],...e};this.attachTraceContext(t),this.queue.enqueue(t)}attachTraceContext(e){let t=this.tracingManager.getCurrentSpan(),n=this.tracingManager.getCurrentTransaction();if(t||n){let r=(t==null?void 0:t.traceId)||(n==null?void 0:n.traceId),i=(t==null?void 0:t.spanId)||(n==null?void 0:n.spanId),o=t==null?void 0:t.parentSpanId,a=(t==null?void 0:t.op)||(n==null?void 0:n.op),c=(t==null?void 0:t.status)||(n==null?void 0:n.status);e.contexts={...e.contexts,trace:{trace_id:r||"",span_id:i||"",parent_span_id:o,op:a,status:c}}}}buildErrorEvent(e){let t=p();if(e instanceof Error){let r=D(e.stack,{maxFrames:5}),i=M(e.name,e.message,r);return{type:"error",level:"error",message:e.message,timestamp:t,exception:{type:e.name,value:e.message,stacktrace:{frames:r}},fingerprint:i}}return{type:"error",level:"error",message:String(e),timestamp:t}}setUser(e){this.configManager.setUser(e),this.tracingManager.updateConfig(this.configManager.getAll())}setAnonymousId(e){N(e)}startTransaction(e){if(!this.enabled)return null;let t=this.tracingManager.startTransaction(e);return t&&t.sampled&&u("Client","Transaction started and sampled",{name:t.name,traceId:t.traceId}),t}getCurrentTransaction(){return this.tracingManager.getCurrentTransaction()}getCurrentSpan(){return this.tracingManager.getCurrentSpan()}setSpan(e){this.tracingManager.setCurrentSpan(e)}startSpan(e){return this.enabled?this.tracingManager.startSpan(e):null}setTag(e,t){this.configManager.setTag(e,t)}setTags(e){this.configManager.setTags(e)}setExtra(e,t){this.configManager.setExtra(e,t)}addBreadcrumb(e){let t={...e,timestamp:p()};this.breadcrumbs.push(t),this.breadcrumbs.length>this.maxBreadcrumbs&&this.breadcrumbs.shift()}async flush(){await this.queue.flush()}disable(){this.enabled=!1}enable(){this.enabled=!0}use(e){this.pluginManager.add(e)}destroy(){this.pluginManager.destroy(),this.tracingManager.destroy(),this.queue.destroy(),this.eventBus.destroy(),this.breadcrumbs=[]}},be=ee;var te=class{constructor(){this.name="error";this.version="1.0.0";this.config={maxStackFrames:5,captureNodeModules:!1,captureColumn:!0,relativePathOnly:!1,resourceSampleRate:.1}}setup(e){this.client=e,this.loadConfig(),this.setupGlobalError(),this.setupUnhandledRejection(),this.setupResourceError()}loadConfig(){let e=this.client.config;e&&y(e.error)&&(this.config={...this.config,...e.error}),e.ignoreErrors&&(this.config.ignoreErrors=[...this.config.ignoreErrors||[],...e.ignoreErrors]),e.ignoreUrls&&(this.config.ignoreUrls=[...this.config.ignoreUrls||[],...e.ignoreUrls]),e.includePaths&&(this.config.includePaths=[...this.config.includePaths||[],...e.includePaths])}shouldIgnoreError(e){return e?_(e,this.config.ignoreErrors||[]):!1}shouldIgnoreScriptUrl(e){return H(e,this.config.ignoreUrls||[])}shouldIncludePath(e){let t=this.config.includePaths||[];return t.length===0?!0:e.some(n=>t.some(r=>{var i;return typeof r=="string"?(i=n.filename)==null?void 0:i.includes(r):r.test(n.filename||"")}))}shouldSample(){var t;let e=(t=this.config.sampleRate)!=null?t:1;return e>=1?!0:e<=0?!1:Math.random()=1?!0:e<=0?!1:Math.random(){try{if(this.originalOnError&&this.originalOnError.call(window,e,t,n,r,i),t&&this.shouldIgnoreScriptUrl(t))return!1;let o=this.buildErrorEvent(i||e,t,n,r);o&&this.client.captureEvent(o)}catch(o){C("ErrorPlugin","Global error handler error",o)}return!1})}setupUnhandledRejection(){typeof window!="undefined"&&(this.onUnhandledRejection=e=>{try{let t=e.reason,n=this.extractUrlFromReason(t);if(n&&this.shouldIgnoreScriptUrl(n))return;let r=this.buildErrorEvent(t);r&&(r.type==="error"&&(r.tags={...r.tags||{},unhandled:"true",promise:"true"}),this.client.captureEvent(r))}catch(t){C("ErrorPlugin","Unhandledrejection handler error",t)}},window.addEventListener("unhandledrejection",this.onUnhandledRejection))}extractUrlFromReason(e){if(e instanceof Error&&e.stack){let t=e.stack.match(/at\s+(?:.+?\s+)?\((https?:\/\/[^:]+):\d+:\d+\)/);if(t)return t[1];let n=e.stack.match(/(https?:\/\/[^\s)]+):\d+:\d+/);if(n)return n[1]}return null}setupResourceError(){typeof window!="undefined"&&(this.onResourceError=e=>{var i;let t=e.target;if(!t)return;let n=(i=t.tagName)==null?void 0:i.toLowerCase(),r=t.src||t.href;if(n&&r&&["img","script","link","audio","video"].includes(n))try{if(this.shouldIgnoreScriptUrl(r)||!this.shouldSampleResource())return;let o=`resource:${n}`,a=k(r);this.client.captureEvent({type:"error",level:"warning",message:`Resource load failed: ${n} ${a}`,timestamp:p(),fingerprint:o,tags:{resource_type:n,resource_url:a},exception:{type:"ResourceError",value:`Failed to load ${n} resource`}})}catch(o){C("ErrorPlugin","Resource error handler error",o)}},window.addEventListener("error",this.onResourceError,!0))}buildErrorEvent(e,t,n,r){let i=p();if(e instanceof Error){if(this.shouldIgnoreError(e.message))return null;let c=D(e.stack,{captureNodeModules:this.config.captureNodeModules,captureColumn:this.config.captureColumn,relativePathOnly:this.config.relativePathOnly,maxFrames:this.config.maxStackFrames});if(!this.shouldIncludePath(c)||!this.shouldSample())return null;let d=M(e.name,e.message,c);return{type:"error",level:"error",message:e.message,timestamp:i,exception:{type:e.name,value:e.message,stacktrace:{frames:c}},fingerprint:d}}let o=String(e);if(this.shouldIgnoreError(o))return null;let a=[];return t&&a.push({filename:t,lineno:n,colno:this.config.captureColumn?r:void 0,in_app:!0}),!this.shouldIncludePath(a)||!this.shouldSample()?null:{type:"error",level:"error",message:o,timestamp:i,exception:{type:"Error",value:o,stacktrace:{frames:a}}}}destroy(){typeof window!="undefined"&&(this.originalOnError!==void 0&&(window.onerror=this.originalOnError),this.onUnhandledRejection&&window.removeEventListener("unhandledrejection",this.onUnhandledRejection),this.onResourceError&&window.removeEventListener("error",this.onResourceError,!0))}},Te=te;var ne=class{constructor(){this.name="performance";this.version="2.0.0";this.config={sampleRate:.1,captureLongTasks:!0,captureResources:!1,resourceSampleRate:.01,longTaskSampleRate:.05,captureNavigation:!0,captureFP:!0,enablePageLoadTracing:!1,maxResourceSpans:50};this.observers=[];this.navLoadTimer=null;this.totalBlockingTime=0;this.fcpTime=null;this.lastLongTaskEndTime=0;this.ttiReported=!1;this.ttiTimer=null;this.pageLoadTransaction=null;this.measurements={};this.resourceSpanCount=0}setup(e){this.client=e,this.loadConfig(),this.config.enablePageLoadTracing&&this.startPageLoadTransaction(),this.observeWebVitals(),this.observeLongTasks(),this.observeNavigation(),this.observeResources()}startPageLoadTransaction(){var n;if(typeof window=="undefined")return;let e=typeof location!="undefined"?location.pathname:"/",t=typeof performance!="undefined"&&((n=performance.timing)!=null&&n.navigationStart)?performance.timing.navigationStart:p();this.pageLoadTransaction=this.client.startTransaction({name:e,op:"pageload",description:`Page load - ${e}`,startTimestamp:t,type:"pageload",tags:{"page.url":e}})}loadConfig(){let e=this.client.config;e&&y(e.performance)&&(this.config={...this.config,...e.performance})}shouldSample(e="default"){var n,r,i;let t=(n=this.config.sampleRate)!=null?n:.1;return e==="resource"?t=(r=this.config.resourceSampleRate)!=null?r:.01:e==="longtask"?t=(i=this.config.longTaskSampleRate)!=null?i:.05:e==="vitals"&&(t=1),t>=1?!0:t<=0?!1:Math.random(){let n=t.getEntriesByName("first-paint");n.length>0&&this.config.captureFP&&this.reportMetric("FP",n[0].startTime,"ms",{},"vitals");let r=t.getEntriesByName("first-contentful-paint");r.length>0&&(this.fcpTime=r[0].startTime,this.lastLongTaskEndTime=r[0].startTime,this.reportMetric("FCP",r[0].startTime,"ms",{},"vitals"),this.scheduleTTI())});e.observe({type:"paint",buffered:!0}),this.observers.push(e)}catch(e){}}observeLCP(){try{let e=new PerformanceObserver(t=>{let n=t.getEntries(),r=n[n.length-1];if(r){let i=r.renderTime||r.loadTime||r.startTime;this.reportMetric("LCP",i,"ms",{},"vitals")}});e.observe({type:"largest-contentful-paint",buffered:!0}),this.observers.push(e)}catch(e){}}observeFID(){try{let e=new PerformanceObserver(t=>{let n=t.getEntries();if(n.length>0){let r=n[0],i=r.processingStart-r.startTime;this.reportMetric("FID",i,"ms",{},"vitals")}});e.observe({type:"first-input",buffered:!0}),this.observers.push(e)}catch(e){}}observeCLS(){try{let e=0,t=0,n=[],r=new PerformanceObserver(i=>{let o=i.getEntries();for(let a of o)if(!a.hadRecentInput){let c=n[0],d=n[n.length-1];t&&a.startTime-((d==null?void 0:d.duration)||0)<1e3&&a.startTime-c.startTime<5e3?(t+=a.value||0,n.push(a)):(t=a.value||0,n=[a]),t>e&&(e=t,this.reportMetric("CLS",e,"",{},"vitals"))}});r.observe({type:"layout-shift",buffered:!0}),this.observers.push(r)}catch(e){}}observeTTFB(){try{let e=new PerformanceObserver(t=>{let n=t.getEntriesByType("navigation");if(n.length>0){let r=n[0],i=r.responseStart-r.requestStart;this.reportMetric("TTFB",Math.max(0,i),"ms",{},"vitals")}});e.observe({type:"navigation",buffered:!0}),this.observers.push(e)}catch(e){}}observeLongTasks(){if(this.config.captureLongTasks)try{let e=new PerformanceObserver(t=>{let n=t.getEntries();for(let r of n){let i=r.startTime+r.duration;if(i>this.lastLongTaskEndTime&&(this.lastLongTaskEndTime=i),this.fcpTime!==null&&r.startTime>=this.fcpTime){let o=r.duration-50;o>0&&(this.totalBlockingTime+=o)}this.reportMetric("longtask",r.duration,"ms",{},"longtask"),this.scheduleTTI()}});e.observe({type:"longtask",buffered:!0}),this.observers.push(e)}catch(e){}}scheduleTTI(){this.ttiReported||(this.ttiTimer&&clearTimeout(this.ttiTimer),this.ttiTimer=setTimeout(()=>{if(this.ttiReported)return;this.ttiReported=!0;let e=Math.max(this.lastLongTaskEndTime,this.fcpTime||0);this.reportMetric("TTI",e,"ms",{},"vitals"),this.reportMetric("TBT",this.totalBlockingTime,"ms",{},"vitals")},5e3))}observeNavigation(){this.config.captureNavigation&&typeof performance!="undefined"&&(this.onLoad=()=>{this.navLoadTimer=setTimeout(()=>{let e=performance.timing;if(!e)return;let t=e.navigationStart,n={dom_ready:e.domContentLoadedEventEnd-t,load_time:e.loadEventEnd-t,dns:e.domainLookupEnd-e.domainLookupStart,tcp:e.connectEnd-e.connectStart,ssl:e.secureConnectionStart>0?e.connectEnd-e.secureConnectionStart:0,ttfb:e.responseStart-e.requestStart,download:e.responseEnd-e.responseStart,dom_parse:e.domInteractive-e.responseEnd};for(let[r,i]of Object.entries(n))i>0&&this.reportMetric(r,i,"ms");this.pageLoadTransaction&&this.pageLoadTransaction.sampled!==!1&&(this.buildNavigationSpans(e,t),this.finishPageLoadTransaction(e.loadEventEnd||p())),this.navLoadTimer=null},0)},window.addEventListener("load",this.onLoad))}buildNavigationSpans(e,t){let n=[{op:"dns",desc:"DNS Lookup",start:e.domainLookupStart,end:e.domainLookupEnd},{op:"tcp",desc:"TCP Connection",start:e.connectStart,end:e.connectEnd},{op:"ssl",desc:"SSL/TLS Negotiation",start:e.secureConnectionStart,end:e.connectEnd},{op:"ttfb",desc:"Time to First Byte",start:e.requestStart,end:e.responseStart},{op:"response",desc:"Response Download",start:e.responseStart,end:e.responseEnd},{op:"dom_parse",desc:"DOM Parsing",start:e.responseEnd,end:e.domInteractive},{op:"dom_content_loaded",desc:"DOM Content Loaded",start:e.domLoading,end:e.domContentLoadedEventEnd},{op:"load",desc:"Page Load",start:e.navigationStart,end:e.loadEventEnd}];for(let r of n)r.start>0&&r.end>0&&r.end>r.start&&this.createNavigationSpan(r.op,r.desc,r.start,r.end)}finishPageLoadTransaction(e){this.pageLoadTransaction&&(Object.keys(this.measurements).length>0&&this.pageLoadTransaction.setData("measurements",this.measurements),this.pageLoadTransaction.setStatus("ok"),this.pageLoadTransaction.finish(e),this.pageLoadTransaction=null)}observeResources(){if(!(!this.config.captureResources&&!this.config.enablePageLoadTracing)&&typeof performance!="undefined")try{let e=new PerformanceObserver(t=>{let n=t.getEntriesByType("resource");for(let r of n)r.duration>1e3&&this.config.captureResources&&this.reportMetric("resource_slow",r.duration,"ms",{resource_name:r.name.substring(0,200),resource_type:r.initiatorType},"resource"),this.config.enablePageLoadTracing&&this.pageLoadTransaction&&this.createResourceSpan(r)});e.observe({type:"resource",buffered:!0}),this.observers.push(e)}catch(e){}}getRating(e,t){let r={LCP:{good:2500,poor:4e3},FCP:{good:1800,poor:3e3},FP:{good:1800,poor:3e3},FID:{good:100,poor:300},CLS:{good:.1,poor:.25},TTFB:{good:800,poor:1800}}[e];return!r||t<=r.good?"good":t<=r.poor?"needs-improvement":"poor"}reportMetric(e,t,n,r={},i="default"){if(!this.shouldSample(i))return;let o=this.getRating(e,t),a={type:"performance",level:"info",metric:e,value:Math.round(t*100)/100,unit:n,rating:o,timestamp:p(),tags:{metric:e,rating:o,...r}};this.client.captureEvent(a),this.pageLoadTransaction&&this.pageLoadTransaction.sampled!==!1&&this.recordMeasurement(e,t,n,o)}recordMeasurement(e,t,n,r){this.pageLoadTransaction&&(this.measurements[e]={value:Math.round(t*100)/100,unit:n,rating:r},this.pageLoadTransaction.setTag(`measurement.${e}.rating`,r||"unknown"))}createNavigationSpan(e,t,n,r,i){if(!this.pageLoadTransaction||this.pageLoadTransaction.sampled===!1||r<=n)return;this.pageLoadTransaction.startChild({op:`browser.${e}`,description:t,startTimestamp:n,tags:i}).finish(r)}createResourceSpan(e){var c,d;if(!this.pageLoadTransaction||this.pageLoadTransaction.sampled===!1)return;let t=(c=this.config.maxResourceSpans)!=null?c:50;if(this.resourceSpanCount>=t)return;this.resourceSpanCount++;let n=typeof performance!="undefined"&&performance.timeOrigin?performance.timeOrigin:((d=performance.timing)==null?void 0:d.navigationStart)||0,r=n+e.startTime,i=n+(e.responseEnd||e.duration||e.startTime);if(i<=r)return;let o=e.name.substring(0,200);this.pageLoadTransaction.startChild({op:`resource.${e.initiatorType||"other"}`,description:o,startTimestamp:r,tags:{"resource.type":e.initiatorType||"other","resource.url":o,"resource.transfer_size":String(e.transferSize||0),"resource.decoded_size":String(e.decodedBodySize||0)},data:{transferSize:e.transferSize,decodedSize:e.decodedBodySize,encodedSize:e.encodedBodySize}}).finish(i)}destroy(){for(let e of this.observers)try{e.disconnect()}catch(t){}this.observers=[],this.ttiTimer&&(clearTimeout(this.ttiTimer),this.ttiTimer=null),this.navLoadTimer&&(clearTimeout(this.navLoadTimer),this.navLoadTimer=null),typeof window!="undefined"&&this.onLoad&&window.removeEventListener("load",this.onLoad),this.pageLoadTransaction&&(this.pageLoadTransaction.setStatus("internal_error"),this.pageLoadTransaction.finish(),this.pageLoadTransaction=null),this.measurements={},this.resourceSpanCount=0}},Ee=ne;var re=class{constructor(){this.name="network";this.version="1.1.0";this.config={captureXHR:!0,captureFetch:!0,captureSuccess:!1,captureBody:!1,captureRequestBody:!1,captureResponseBody:!1,captureRequestHeaders:["content-type","user-agent"],captureResponseHeaders:["content-type","content-length"],errorSampleRate:1,successSampleRate:.01,slowThreshold:3e3,slowSampleRate:1,ignoreStatusCodes:[]}}setup(e){this.client=e,this.loadConfig(),this.config.captureFetch&&this.patchFetch(),this.config.captureXHR&&this.patchXHR()}loadConfig(){let e=this.client.config;e&&y(e.network)&&(this.config={...this.config,...e.network}),e.ignoreUrls&&(this.config.ignoreUrls=[...this.config.ignoreUrls||[],...e.ignoreUrls]),e.tracePropagationTargets?this.config.tracePropagationTargets=[...this.config.tracePropagationTargets||[],...e.tracePropagationTargets]:e.tracingOrigins&&(this.config.tracePropagationTargets=[...this.config.tracePropagationTargets||[],...e.tracingOrigins])}shouldIgnore(e){return H(e,this.config.ignoreUrls||[])}shouldTracePropagate(e){let t=this.config.tracePropagationTargets;return!t||t.length===0?this.isSameOrigin(e):t.some(n=>typeof n=="string"?e.includes(n):n.test(e))}isSameOrigin(e){if(typeof location=="undefined")return!1;try{return new URL(e,location.origin).origin===location.origin}catch(t){return!1}}getBaggageHeader(){var r,i;if(!this.client)return;let t=(i=(r=this.client.tracingManager)==null?void 0:r.getCurrentTransaction)==null?void 0:i.call(r);if(!t)return;let n=t;if(n.toBaggage)return n.toBaggage()}shouldSample(e,t){var r,i,o,a;let n=e?(r=this.config.errorSampleRate)!=null?r:1:(i=this.config.successSampleRate)!=null?i:.01;return!e&&t>=((o=this.config.slowThreshold)!=null?o:3e3)&&(n=(a=this.config.slowSampleRate)!=null?a:1),n>=1?!0:n<=0?!1:Math.random()0?e.setHttpStatus(t):r&&e.setStatus("internal_error"),e.finish()}patchFetch(){if(typeof fetch=="undefined")return;this.originalFetch=window.fetch;let e=this;window.fetch=function(t,n){let r=p(),i=typeof t=="string"?t:t instanceof URL?t.toString():t.url,o=(n==null?void 0:n.method)||"GET";if(e.shouldIgnore(i))return e.originalFetch.call(window,t,n);let a=k(i),c=e.createHttpSpan(o,a),d=e.shouldTracePropagate(i)&&!!c,f=n;if(d&&c){let h=c.toTraceparent(),g=e.getBaggageHeader();f={...n,headers:{...(n==null?void 0:n.headers)||{},"sentry-trace":h,...g?{baggage:g}:{}}}}let E=e.originalFetch.call(window,t,f);return E.then(h=>{var S;let g=p()-r,m=h.ok,v=h.status;return c&&e.finishHttpSpan(c,v,g,!m),(S=e.config.ignoreStatusCodes)!=null&&S.includes(v)||!e.shouldSample(!m,g)||(!m||e.config.captureSuccess)&&e.reportNetwork({sub_type:"fetch",method:o.toUpperCase(),url:a,status_code:v,duration:g,success:m,error:m?void 0:`HTTP ${v}`}),h},h=>{let g=p()-r;throw c&&e.finishHttpSpan(c,0,g,!0),e.shouldSample(!0,g)&&e.reportNetwork({sub_type:"fetch",method:o.toUpperCase(),url:a,duration:g,success:!1,error:(h==null?void 0:h.message)||"Network error"}),h}),E}}patchXHR(){if(typeof XMLHttpRequest=="undefined")return;this.originalXHROpen=XMLHttpRequest.prototype.open,this.originalXHRSend=XMLHttpRequest.prototype.send;let e=this;XMLHttpRequest.prototype.open=function(t,n){return this._lightMethod=t,this._lightUrl=typeof n=="string"?n:n.toString(),this._lightTracked=!1,e.originalXHROpen.apply(this,arguments)},XMLHttpRequest.prototype.send=function(t){let n=p(),r=this._lightMethod||"GET",i=this._lightUrl||"",o=this._lightTracked;if(e.shouldIgnore(i)||o)return e.originalXHRSend.apply(this,arguments);this._lightTracked=!0;let a=k(i),c=0;t&&typeof t=="string"&&(c=t.length);let d=e.createHttpSpan(r,a);if(e.shouldTracePropagate(i)&&!!d&&d)try{let h=d.toTraceparent(),g=e.getBaggageHeader();this.setRequestHeader("sentry-trace",h),g&&this.setRequestHeader("baggage",g)}catch(h){}let E=this.onloadend;return this.onloadend=function(h){var S;let g=p()-n,m=this.status,v=m>=200&&m<300;if(d&&e.finishHttpSpan(d,m,g,!v),!((S=e.config.ignoreStatusCodes)!=null&&S.includes(m))&&e.shouldSample(!v,g)&&(!v||e.config.captureSuccess)){let b=0;try{let x=this.getResponseHeader("content-length");x&&(b=parseInt(x,10)),!b&&this.responseText&&(b=this.responseText.length)}catch(x){}e.reportNetwork({sub_type:"xhr",method:r.toUpperCase(),url:a,status_code:m,duration:g,request_size:c||void 0,response_size:b||void 0,success:v,error:v?void 0:`HTTP ${m}`})}if(E)return E.call(this,h)},e.originalXHRSend.apply(this,arguments)}}reportNetwork(e){let t={type:"network",level:e.success?"info":"error",timestamp:p(),tags:{method:e.method,sub_type:e.sub_type,success:String(e.success)},...e};this.client.captureEvent(t)}destroy(){this.originalFetch&&(window.fetch=this.originalFetch),this.originalXHROpen&&(XMLHttpRequest.prototype.open=this.originalXHROpen),this.originalXHRSend&&(XMLHttpRequest.prototype.send=this.originalXHRSend)}},we=re;var ie=class{constructor(){this.name="behavior";this.version="1.0.0";this.config={capturePV:!0,captureClick:!0,captureRoute:!0,captureDuration:!0,captureScroll:!0,clickThrottle:300,scrollThrottle:1e3,sampleRate:.01};this.lastClickTime=0;this.lastScrollTime=0;this.maxScrollDepth=0;this.pageEnterTime=0;this.scrollReported=!1}setup(e){this.client=e,this.loadConfig(),this.config.capturePV&&this.trackPV(),this.config.captureClick&&this.trackClick(),this.config.captureRoute&&this.trackRoute(),this.config.captureDuration&&this.trackPageDuration(),this.config.captureScroll&&this.trackScroll()}loadConfig(){let e=this.client.config;e&&y(e.behavior)&&(this.config={...this.config,...e.behavior})}shouldSample(){var t;let e=(t=this.config.sampleRate)!=null?t:.01;return e>=1?!0:e<=0?!1:Math.random(){var a,c,d;let t=p(),n=(a=this.config.clickThrottle)!=null?a:300;if(t-this.lastClickTime{let r=w();if(r!==e){let i=e,o=r;e=r,this.reportBehavior({sub_type:"route",page_url:o,referrer:i,properties:{from:i,to:o}}),this.pageEnterTime=p(),this.maxScrollDepth=0,this.scrollReported=!1}};this.originalPushState=history.pushState,this.originalReplaceState=history.replaceState;let n=this;history.pushState=function(){let r=n.originalPushState.apply(this,arguments);return setTimeout(t,0),r},history.replaceState=function(){let r=n.originalReplaceState.apply(this,arguments);return setTimeout(t,0),r},this.onPopState=()=>{setTimeout(t,0)},this.onHashchange=()=>{setTimeout(t,0)},window.addEventListener("popstate",this.onPopState),window.addEventListener("hashchange",this.onHashchange)}trackPageDuration(){if(typeof window=="undefined")return;this.pageEnterTime=p();let e=()=>{let t=p()-this.pageEnterTime;t>1e3&&(this.config.captureScroll&&!this.scrollReported&&this.reportScroll(),this.reportBehavior({sub_type:"duration",page_url:w(),properties:{duration:t,max_scroll_depth:this.maxScrollDepth}}))};this.onVisibilityChange=()=>{document.hidden?e():this.pageEnterTime=p()},this.onBeforeUnload=e,this.onPagehide=e,document.addEventListener("visibilitychange",this.onVisibilityChange),window.addEventListener("beforeunload",this.onBeforeUnload),window.addEventListener("pagehide",this.onPagehide)}trackScroll(){typeof window!="undefined"&&(this.onScroll=()=>{var r;let e=p(),t=(r=this.config.scrollThrottle)!=null?r:1e3;if(e-this.lastScrollTimethis.maxScrollDepth&&(this.maxScrollDepth=n)},window.addEventListener("scroll",this.onScroll,{passive:!0}))}reportScroll(){this.scrollReported||(this.scrollReported=!0,this.reportBehavior({sub_type:"scroll",page_url:w(),properties:{max_depth:this.maxScrollDepth}}))}reportBehavior(e){if(!this.shouldSample())return;let t={type:"behavior",level:"info",timestamp:p(),tags:{sub_type:e.sub_type,page_url:w()},...e};this.client.captureEvent(t)}destroy(){typeof window!="undefined"&&(this.originalPushState&&(history.pushState=this.originalPushState),this.originalReplaceState&&(history.replaceState=this.originalReplaceState),this.onPopState&&window.removeEventListener("popstate",this.onPopState),this.onHashchange&&window.removeEventListener("hashchange",this.onHashchange),this.onBeforeUnload&&window.removeEventListener("beforeunload",this.onBeforeUnload),this.onPagehide&&window.removeEventListener("pagehide",this.onPagehide),this.onScroll&&window.removeEventListener("scroll",this.onScroll)),typeof document!="undefined"&&(this.onClick&&document.removeEventListener("click",this.onClick,!0),this.onVisibilityChange&&document.removeEventListener("visibilitychange",this.onVisibilityChange))}},xe=ie;var qe="light-sentry-offline",T="events",se=1e3,oe=class{constructor(){this.name="offline";this.version="1.0.0";this.config={maxEvents:se};this.db=null;this.isOnline=!0;this.isSyncing=!1;this.pendingEvents=[]}setup(e){this.client=e,this.loadConfig(),this.initDatabase(),this.setupNetworkListeners()}loadConfig(){let e=this.client.config;e&&typeof e.offline=="object"&&(this.config={...this.config,...e.offline})}async initDatabase(){if(typeof indexedDB=="undefined"){console.warn("[LightSDK] OfflinePlugin: IndexedDB not available");return}return new Promise((e,t)=>{let n=indexedDB.open(qe,1);n.onerror=()=>{console.warn("[LightSDK] OfflinePlugin: Failed to open IndexedDB"),t(n.error)},n.onsuccess=()=>{this.db=n.result,e()},n.onupgradeneeded=r=>{let i=r.target.result,o=r.oldVersion;i.objectStoreNames.contains(T)||i.createObjectStore(T,{keyPath:"id"}).createIndex("timestamp","timestamp",{unique:!1})}})}setupNetworkListeners(){typeof window!="undefined"&&(this.isOnline=navigator.onLine,this.onOnline=()=>{console.info("[LightSDK] OfflinePlugin: Network online"),this.isOnline=!0,this.syncPendingEvents()},this.onOffline=()=>{console.info("[LightSDK] OfflinePlugin: Network offline"),this.isOnline=!1},window.addEventListener("online",this.onOnline),window.addEventListener("offline",this.onOffline))}generateId(){return`${Date.now()}-${Math.random().toString(36).substring(2,11)}`}async saveToIndexedDB(e){if(!this.db)return;let t=this.config.maxEvents||se,n=await this.getEventCount();return n>=t&&await this.deleteOldestEvents(n-t+1),new Promise((r,i)=>{let a=this.db.transaction([T],"readwrite").objectStore(T),c={id:this.generateId(),event:{...e,offline:!0},timestamp:p()},d=a.add(c);d.onsuccess=()=>r(),d.onerror=()=>i(d.error)})}getEventCount(){return this.db?new Promise((e,t)=>{let i=this.db.transaction([T],"readonly").objectStore(T).count();i.onsuccess=()=>e(i.result),i.onerror=()=>t(i.error)}):Promise.resolve(0)}async deleteOldestEvents(e){if(!(!this.db||e<=0))return new Promise((t,n)=>{let a=this.db.transaction([T],"readwrite").objectStore(T).index("timestamp").openCursor(),c=0;a.onsuccess=d=>{let f=d.target.result;f&&cn(a.error)})}async getAllStoredEvents(){return this.db?new Promise((e,t)=>{let o=this.db.transaction([T],"readonly").objectStore(T).index("timestamp").getAll();o.onsuccess=()=>{let a=o.result||[];a.sort((c,d)=>c.timestamp-d.timestamp),e(a)},o.onerror=()=>t(o.error)}):[]}async clearStoredEvents(){if(this.db)return new Promise((e,t)=>{let i=this.db.transaction([T],"readwrite").objectStore(T).clear();i.onsuccess=()=>e(),i.onerror=()=>t(i.error)})}async syncPendingEvents(){if(!(!this.isOnline||this.isSyncing)){this.isSyncing=!0,console.info("[LightSDK] OfflinePlugin: Syncing pending events");try{let e=0;for(;this.pendingEvents.length>0;){let n=this.pendingEvents.shift();try{this.client.captureEvent(n),e++}catch(r){console.error("[LightSDK] OfflinePlugin: Failed to re-enqueue memory event",r)}}let t=await this.getAllStoredEvents();if(t.length>0)for(let n of t)try{let r=n.event;this.client.captureEvent(r),e++}catch(r){console.error("[LightSDK] OfflinePlugin: Failed to re-enqueue event",r)}try{await this.client.flush()}catch(n){}await this.clearStoredEvents(),console.info(`[LightSDK] OfflinePlugin: Synced ${e} events`)}catch(e){console.error("[LightSDK] OfflinePlugin: Sync failed",e)}finally{this.isSyncing=!1}}}beforeReport(e){if(!this.isOnline){let n=this.config.maxEvents||se;return this.pendingEvents.length>=n&&this.pendingEvents.shift(),this.pendingEvents.push(e),this.savePendingEventsToDB(),null}let t={...e};return delete t.offline,t}savePendingEventsToDB(){if(this.pendingEvents.length===0)return;let e=this.pendingEvents.splice(0,this.pendingEvents.length),t=0,n=()=>{if(t>=e.length)return;let r=e[t];this.saveToIndexedDB(r).then(()=>{t++,n()}).catch(i=>{console.error("[LightSDK] OfflinePlugin: Failed to save event offline",i),this.pendingEvents.unshift(...e.slice(t))})};n()}destroy(){typeof window!="undefined"&&(this.onOnline&&window.removeEventListener("online",this.onOnline),this.onOffline&&window.removeEventListener("offline",this.onOffline)),this.db&&(this.db.close(),this.db=null)}},ke=oe;var ae=class{constructor(){this.name="sampling";this.version="1.0.0";this.config={rates:{error:1,performance:1,network:1,behavior:1}}}setup(e){this.client=e,this.loadConfig()}loadConfig(){let e=this.client.config;if(e&&y(e.sampling)){let t=e.sampling;"rates"in t&&y(t.rates)&&(this.config.rates={...this.config.rates,...t.rates})}}shouldSample(e){var r;let t=(r=this.client.config.sampleRate)!=null?r:1;if(t<=0)return!1;let n=this.getTypeRate(e);return t>=1?this.randomCheck(n):this.randomCheck(t*n)}getTypeRate(e){let t=this.config.rates||{},n=e.type;if(n==="count")return 1;let r=t[n];return r!==void 0?r:1}randomCheck(e){return e>=1?!0:e<=0?!1:Math.random(){this.handleRouteChange(location.pathname+location.search,"popstate")};this.handleHashChange=()=>{this.handleRouteChange(location.hash||"#/","hashchange")}}setup(e){this.client=e,this.loadConfig(),typeof window!="undefined"&&this.config.enable&&(this.config.instrumentHistory&&this.instrumentHistory(),this.config.instrumentHash&&this.instrumentHash())}loadConfig(){let e=this.client.config;e&&y(e.router)&&(this.config={...this.config,...e.router})}instrumentHistory(){typeof history=="undefined"||!history.pushState||(this.originalPushState=history.pushState.bind(history),this.originalReplaceState=history.replaceState.bind(history),history.pushState=(e,t,n)=>{this.originalPushState(e,t,n),this.handleRouteChange(n||location.pathname+location.search,"pushState")},history.replaceState=(e,t,n)=>{this.originalReplaceState(e,t,n),this.handleRouteChange(n||location.pathname+location.search,"replaceState")},window.addEventListener("popstate",this.handlePopState))}instrumentHash(){window.addEventListener("hashchange",this.handleHashChange)}handleRouteChange(e,t){this.routeChangeTimer&&clearTimeout(this.routeChangeTimer),this.routeChangeTimer=setTimeout(()=>{this.routeChangeTimer=null,this.processRouteChange(e,t)},50)}processRouteChange(e,t){let n=this.config.routeNameFormatter?this.config.routeNameFormatter(e):e.split("?")[0];n!==this.lastRoute&&(this.lastRoute=n,this.finishCurrentTransaction("ok"),this.startNavigationTransaction(n,t))}startNavigationTransaction(e,t){if(!this.client)return;let n=this.client.startTransaction({name:e,op:"navigation",description:`Navigation to ${e}`,type:"navigation",tags:{"route.name":e,"route.source":t}});n&&(this.currentTransaction=n,this.startMaxDurationTimer())}startMaxDurationTimer(){var t;this.maxDurationTimer&&clearTimeout(this.maxDurationTimer);let e=(t=this.config.maxTransactionDurationMs)!=null?t:3e4;this.maxDurationTimer=setTimeout(()=>{this.currentTransaction&&(this.currentTransaction.setStatus("deadline_exceeded"),this.finishCurrentTransaction("deadline_exceeded"))},e)}finishCurrentTransaction(e="ok"){this.maxDurationTimer&&(clearTimeout(this.maxDurationTimer),this.maxDurationTimer=null),this.currentTransaction&&(this.currentTransaction.setStatus(e),this.currentTransaction.finish(),this.currentTransaction=null)}destroy(){this.originalPushState&&typeof history!="undefined"&&(history.pushState=this.originalPushState),this.originalReplaceState&&typeof history!="undefined"&&(history.replaceState=this.originalReplaceState),typeof window!="undefined"&&(window.removeEventListener("popstate",this.handlePopState),window.removeEventListener("hashchange",this.handleHashChange)),this.maxDurationTimer&&(clearTimeout(this.maxDurationTimer),this.maxDurationTimer=null),this.routeChangeTimer&&(clearTimeout(this.routeChangeTimer),this.routeChangeTimer=null),this.finishCurrentTransaction("aborted")}},Re=ce;var ue=class{constructor(){this.name="interaction";this.version="1.0.0";this.config={enable:!0,elementAttribute:"data-sentry-component",maxTransactionDurationMs:3e4,idleTimeoutMs:1e3,trackClick:!0,trackSubmit:!0,trackKeypress:!1};this.currentTransaction=null;this.idleTimer=null;this.maxDurationTimer=null;this.debounceTimer=null;this.handleClick=e=>{if(this.isEventIgnored(e))return;let t=e.target,n=this.getElementName(t,"click");this.scheduleInteractionTransaction(n,"click",t)};this.handleSubmit=e=>{if(this.isEventIgnored(e))return;let t=e.target,n=this.getElementName(t,"submit");this.scheduleInteractionTransaction(n,"submit",t)}}setup(e){this.client=e,this.loadConfig(),typeof window!="undefined"&&this.config.enable&&(this.config.trackClick&&document.addEventListener("click",this.handleClick,!0),this.config.trackSubmit&&document.addEventListener("submit",this.handleSubmit,!0))}loadConfig(){let e=this.client.config;e&&y(e.interaction)&&(this.config={...this.config,...e.interaction})}isEventIgnored(e){let t=e.target;return!!(!t||t.hasAttribute&&t.hasAttribute("data-sentry-ignore"))}scheduleInteractionTransaction(e,t,n){this.debounceTimer&&clearTimeout(this.debounceTimer),this.debounceTimer=setTimeout(()=>{this.startInteractionTransaction(e,t,n)},0)}getElementName(e,t){var c;if(!e)return t;let n=this.config.elementAttribute||"data-sentry-component",r=e.getAttribute(n);if(r)return r;let i=((c=e.tagName)==null?void 0:c.toLowerCase())||"element",o=e.id?`#${e.id}`:"",a=e.className&&typeof e.className=="string"?`.${e.className.split(" ").slice(0,3).join(".")}`:"";return`${t}@${i}${o}${a}`}startInteractionTransaction(e,t,n){var i,o;if(!this.client)return;this.currentTransaction&&this.finishCurrentTransaction("ok");let r=this.client.startTransaction({name:e,op:`ui.${t}`,description:`User ${t} on ${e}`,type:"user-interaction",tags:{"interaction.type":t,"interaction.target":e},data:{tag:(i=n.tagName)==null?void 0:i.toLowerCase(),id:n.id||void 0,text:((o=n.textContent)==null?void 0:o.substring(0,100))||void 0}});r&&(this.currentTransaction=r,this.scheduleIdleFinish(),this.scheduleMaxDuration())}scheduleIdleFinish(){var t;this.idleTimer&&clearTimeout(this.idleTimer);let e=(t=this.config.idleTimeoutMs)!=null?t:1e3;this.idleTimer=setTimeout(()=>{this.finishCurrentTransaction("ok")},e)}scheduleMaxDuration(){var t;this.maxDurationTimer&&clearTimeout(this.maxDurationTimer);let e=(t=this.config.maxTransactionDurationMs)!=null?t:3e4;this.maxDurationTimer=setTimeout(()=>{this.finishCurrentTransaction("deadline_exceeded")},e)}finishCurrentTransaction(e="ok"){this.idleTimer&&(clearTimeout(this.idleTimer),this.idleTimer=null),this.maxDurationTimer&&(clearTimeout(this.maxDurationTimer),this.maxDurationTimer=null),this.debounceTimer&&(clearTimeout(this.debounceTimer),this.debounceTimer=null),this.currentTransaction&&(this.currentTransaction.setStatus(e),this.currentTransaction.finish(),this.currentTransaction=null)}destroy(){typeof document!="undefined"&&(document.removeEventListener("click",this.handleClick,!0),document.removeEventListener("submit",this.handleSubmit,!0)),this.idleTimer&&(clearTimeout(this.idleTimer),this.idleTimer=null),this.maxDurationTimer&&(clearTimeout(this.maxDurationTimer),this.maxDurationTimer=null),this.debounceTimer&&(clearTimeout(this.debounceTimer),this.debounceTimer=null),this.finishCurrentTransaction("aborted")}},Le=ue;var l=null;function Ue(s){var r;B(s.debug===!0),u("Index","init called",{dsn:s.dsn,debug:s.debug});let e=new be(s),t=[new ke,new Ce,new Te],n=((r=s.plugins)==null?void 0:r.filter(i=>typeof i=="string"))||[];(n.includes("performance")||n.includes("all"))&&t.push(new Ee),(n.includes("network")||n.includes("all"))&&t.push(new we),(n.includes("behavior")||n.includes("all"))&&t.push(new xe),(n.includes("router")||n.includes("all"))&&t.push(new Re),(n.includes("interaction")||n.includes("all"))&&t.push(new Le),u("Index","Registering plugins",{count:t.length,plugins:t.map(i=>i.name)});for(let i of t)e.use(i);if(s.plugins)for(let i of s.plugins)typeof i=="object"&&i!==null&&"name"in i&&"setup"in i&&e.use(i);return e.init(),l=e,u("Index","init completed, globalClient set"),e}function $e(){return l}function Ae(s){if(u("Index","captureException called",{hasClient:!!l}),!l){console.warn("[LightSDK] SDK not initialized. Call LightSentry.init() first.");return}l.captureException(s)}function je(s,e){if(u("Index","captureMessage called",{hasClient:!!l}),!l){console.warn("[LightSDK] SDK not initialized. Call LightSentry.init() first.");return}l.captureMessage(s,e)}function Ke(s){if(u("Index","captureEvent called",{hasClient:!!l}),!l){console.warn("[LightSDK] SDK not initialized. Call LightSentry.init() first.");return}l.captureEvent(s)}function ze(s){l==null||l.setUser(s)}function Xe(s){N(s)}function We(){pe()}function Ve(){return F()}function Qe(s){return(l==null?void 0:l.startTransaction(s))||null}function Ge(){return(l==null?void 0:l.getCurrentTransaction())||null}function Je(){return(l==null?void 0:l.getCurrentSpan())||null}function Ye(s){l==null||l.setSpan(s)}function Ze(s){return(l==null?void 0:l.startSpan(s))||null}function et(s,e){l==null||l.setTag(s,e)}function tt(s){l==null||l.setTags(s)}function nt(s,e){l==null||l.setExtra(s,e)}function rt(s){l==null||l.addBreadcrumb(s)}async function it(){await(l==null?void 0:l.flush())}function st(){l==null||l.disable()}function ot(){l==null||l.enable()}var qn={init:Ue,getClient:$e,captureException:Ae,captureMessage:je,captureEvent:Ke,setUser:ze,setAnonymousId:Xe,clearAnonymousId:We,getAnonymousId:Ve,startTransaction:Qe,getCurrentTransaction:Ge,getCurrentSpan:Je,setSpan:Ye,startSpan:Ze,setTag:et,setTags:tt,setExtra:nt,addBreadcrumb:rt,flush:it,disable:st,enable:ot,Span:R,Transaction:L,httpStatusToSpanStatus:z};export{xe as BehaviorPlugin,be as Client,Te as ErrorPlugin,Le as InteractionPlugin,we as NetworkPlugin,ke as OfflinePlugin,Ee as PerformancePlugin,Re as RouterPlugin,Ce as SamplingPlugin,R as Span,L as Transaction,rt as addBreadcrumb,Ke as captureEvent,Ae as captureException,je as captureMessage,We as clearAnonymousId,Y as createBaggageFromTransaction,Se as dbStatusToSpanStatus,qn as default,st as disable,ot as enable,it as flush,Ve as getAnonymousId,$e as getClient,Je as getCurrentSpan,Ge as getCurrentTransaction,z as httpStatusToSpanStatus,Ue as init,Fe as parseBaggage,J as serializeBaggage,Xe as setAnonymousId,nt as setExtra,Ye as setSpan,et as setTag,tt as setTags,ze as setUser,Ze as startSpan,Qe as startTransaction,Z as statusToSpanStatus}; diff --git a/dist/index.iife.js b/dist/index.iife.js index 78910d4..bd83124 100644 --- a/dist/index.iife.js +++ b/dist/index.iife.js @@ -1,3 +1,3 @@ -"use strict";var LightSDK=(()=>{var q=Object.defineProperty;var Re=Object.getOwnPropertyDescriptor;var ke=Object.getOwnPropertyNames;var Ce=Object.prototype.hasOwnProperty;var Le=(s,e)=>{for(var t in e)q(s,t,{get:e[t],enumerable:!0})},Te=(s,e,t,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let r of ke(e))!Ce.call(s,r)&&r!==t&&q(s,r,{get:()=>e[r],enumerable:!(n=Re(e,r))||n.enumerable});return s};var Pe=s=>Te(q({},"__esModule",{value:!0}),s);var Ue={};Le(Ue,{BehaviorPlugin:()=>J,Client:()=>j,ErrorPlugin:()=>X,NetworkPlugin:()=>Q,OfflinePlugin:()=>ee,PerformancePlugin:()=>z,SamplingPlugin:()=>ne,addBreadcrumb:()=>Ee,captureEvent:()=>ge,captureException:()=>he,captureMessage:()=>fe,default:()=>Ne,disable:()=>Se,enable:()=>xe,flush:()=>we,getClient:()=>pe,init:()=>de,setExtra:()=>be,setTag:()=>ve,setTags:()=>ye,setUser:()=>me});function ie(s){try{let e=s.match(/^(https?):\/\/([^@]+)@([^/]+)\/(.+)$/);if(!e)throw new Error("Invalid DSN format");let[,t,n,r,i]=e;return{protocol:t,publicKey:n,host:r,projectId:i}}catch(e){throw new Error(`Failed to parse DSN: ${e.message}`)}}function C(s){return`${s.protocol}://${s.host}/api/${s.projectId}/envelope/?sentry_key=${s.publicKey}`}function se(){return"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx".replace(/[x]/g,()=>(Math.random()*16|0).toString(16))}function p(){return Date.now()}function b(s){return s!==null&&typeof s=="object"&&!Array.isArray(s)}function L(s,e){return!e||e.length===0?!1:e.some(t=>typeof t=="string"?s.includes(t):t.test(s))}function Me(s){let e=5381,t=s.length;for(;t;)e=e*33^s.charCodeAt(--t);return e>>>0}function N(s){return Me(s).toString(16)}function T(s,e,t=[]){let n=t.slice(0,3).map(i=>`${i.filename}:${i.lineno||0}`).join("|"),r=e.replace(/['"]?\d+['"]?/g,"").replace(/\s+/g," ").trim();return N(`${s}:${r}:${n}`)}function P(s,e={}){if(!s)return[];let{captureNodeModules:t=!1,captureColumn:n=!0,relativePathOnly:r=!1,maxFrames:i}=e,o=[],a=s.split(` -`),u=typeof location!="undefined"?`${location.protocol}//${location.host}`:"";for(let h of a){let w=h.match(/^\s*at\s*(.+?)\s*\((.+?):(\d+):(\d+)\)\s*$/);if(w){let[,g,f,y,m]=w,S=f.includes("node_modules");if(!t&&S)continue;let x=f;r&&u&&f.startsWith(u)&&(x=f.substring(u.length)),o.push({filename:x,function:g,lineno:parseInt(y,10),colno:n?parseInt(m,10):void 0,in_app:!S})}else{let g=h.match(/^\s*at\s*(.+?)@(.+?):(\d+):(\d+)\s*$/);if(g){let[,y,m,S,x]=g,k=m.includes("node_modules");if(!t&&k)continue;let re=m;r&&u&&m.startsWith(u)&&(re=m.substring(u.length)),o.push({filename:re,function:y||"",lineno:parseInt(S,10),colno:n?parseInt(x,10):void 0,in_app:!k});continue}let f=h.match(/^\s*at\s*(.+?):(\d+):(\d+)\s*$/);if(f){let[,y,m,S]=f,x=y.includes("node_modules");if(!t&&x)continue;let k=y;r&&u&&y.startsWith(u)&&(k=y.substring(u.length)),o.push({filename:k,lineno:parseInt(m,10),colno:n?parseInt(S,10):void 0,in_app:!x})}}}let c=o.reverse();return i!==void 0&&i>0?c.slice(0,i):c}var U=!1;function M(s){U=s}function l(s,e,t){if(!U)return;let n=new Date().toISOString(),r=`[LightSDK][${s}]`;t!==void 0?console.log(`${r} ${n} ${e}`,t):console.log(`${r} ${n} ${e}`)}function H(s,e,t){if(!U)return;let n=new Date().toISOString(),r=`[LightSDK][${s}][ERROR]`;t!==void 0?console.error(`${r} ${n} ${e}`,t):console.error(`${r} ${n} ${e}`)}function De(s){let e=[{name:"WeChat",pattern:/MicroMessenger\/([\d.]+)/i},{name:"QQ Browser",pattern:/QIBrowser\/([\d.]+)/i},{name:"UC Browser",pattern:/UCBrowser\/([\d.]+)/i},{name:"Edge",pattern:/Edg\/([\d.]+)/i},{name:"Edge",pattern:/Edge\/([\d.]+)/i},{name:"Opera",pattern:/OPR\/([\d.]+)/i},{name:"Opera",pattern:/Opera\/([\d.]+)/i},{name:"Firefox",pattern:/Firefox\/([\d.]+)/i},{name:"Safari",pattern:/Version\/([\d.]+).*Safari/i},{name:"Chrome",pattern:/Chrome\/([\d.]+)/i},{name:"IE",pattern:/MSIE ([\d.]+)/i},{name:"IE",pattern:/Trident.*rv:([\d.]+)/i}];for(let t of e){let n=s.match(t.pattern);if(n){let r=n[1]||"",i=r.split(".")[0]||"";return{name:t.name,version:r,major:i}}}return{name:"Unknown",version:"",major:""}}function Ie(s){let e=[{name:"Windows 11",pattern:/Windows NT 10\.0.*Win64.*x64/i},{name:"Windows 10",pattern:/Windows NT 10\.0/i},{name:"Windows 8.1",pattern:/Windows NT 6\.3/i},{name:"Windows 8",pattern:/Windows NT 6\.2/i},{name:"Windows 7",pattern:/Windows NT 6\.1/i},{name:"Windows Vista",pattern:/Windows NT 6\.0/i},{name:"Windows XP",pattern:/Windows NT 5\.1/i},{name:"macOS",pattern:/Mac OS X ([\d_.]+)/i},{name:"iOS",pattern:/OS ([\d_.]+) like Mac OS X/i},{name:"Android",pattern:/Android ([\d.]+)/i},{name:"Android",pattern:/Android/i},{name:"Linux",pattern:/Linux/i}];for(let t of e){let n=s.match(t.pattern);if(n){let r=n[1]||"";return r&&(r=r.replace(/_/g,".")),{name:t.name,version:r}}}return{name:"Unknown",version:""}}function Be(s){let e=/Mobile|Android|iPhone|iPod|BlackBerry|Windows Phone|Opera Mini/i.test(s),t=/Tablet|iPad|PlayBook|Kindle|Silk/i.test(s),n="desktop";t?n="tablet":e&&(n="mobile");let r="",i="",o=s.match(/iPhone/i),a=s.match(/iPad/i),u=s.match(/SM-([A-Z0-9]+)/i),c=s.match(/Pixel ([0-9A-Z]+)/i),h=s.match(/HUAWEI ([A-Z0-9]+)/i);return o?(r="Apple",i="iPhone"):a?(r="Apple",i="iPad"):u?(r="Samsung",i=u[1]):c?(r="Google",i=`Pixel ${c[1]}`):h&&(r="Huawei",i=h[1]),{type:n,vendor:r,model:i}}function oe(){let s=typeof navigator!="undefined"?navigator.userAgent:"",e=De(s),t=Ie(s),n=Be(s);return{browser:e,os:t,device:n,url:typeof location!="undefined"?location.href:"",referrer:typeof document!="undefined"?document.referrer:"",title:typeof document!="undefined"?document.title:"",language:typeof navigator!="undefined"?navigator.language:"",user_agent:s,screen_width:typeof screen!="undefined"?screen.width:0,screen_height:typeof screen!="undefined"?screen.height:0,viewport_width:typeof window!="undefined"?window.innerWidth:0,viewport_height:typeof window!="undefined"?window.innerHeight:0}}function E(){return typeof location!="undefined"?location.href:""}function ae(){return typeof document!="undefined"?document.referrer:""}function R(s){if(!s)return s;try{let e=new URL(s),t=["password","passwd","pwd","token","access_token","refresh_token","api_key","apikey","key","secret","private_key","code","auth","id_token","idToken","session","session_id"],n=e.searchParams,r=!1;for(let i of Array.from(n.keys())){let o=i.toLowerCase().replace(/[-_]/g,"_");t.some(a=>o.includes(a))&&(n.set(i,"[Filtered]"),r=!0)}if(e.hash&&e.hash.length>1){let i=e.hash.substring(1);if(i.includes("=")){let o=new URLSearchParams(i),a=!1;for(let u of Array.from(o.keys())){let c=u.toLowerCase().replace(/[-_]/g,"_");t.some(h=>c.includes(h))&&(o.set(u,"[Filtered]"),a=!0)}a&&(e.hash="#"+o.toString(),r=!0)}}return r?e.toString():s}catch(e){return s}}function D(s,e=[]){return!e||e.length===0?!1:e.some(t=>{if(typeof t=="string"){if(t.includes("*")){let n=t.replace(/[.+?^${}()|[\]\\]/g,"\\$&").replace(/\*/g,".*");return new RegExp(n).test(s)}return s.includes(t)}return t.test(s)})}var _e={Chrome:"c",Safari:"s",Firefox:"f",Edge:"e",Opera:"o",IE:"i",WeChat:"w","QQ Browser":"q","UC Browser":"u","Mobile Chrome":"cm","Mobile Safari":"sm"},Oe={"Windows 11":"w11","Windows 10":"w10","Windows 8.1":"w81","Windows 8":"w8","Windows 7":"w7","Windows Vista":"wv","Windows XP":"wxp",macOS:"m",iOS:"i",Android:"a",Linux:"l"};function $(){let s=oe(),e=_e[s.browser.name]||s.browser.name.toLowerCase(),t=Oe[s.os.name]||s.os.name.toLowerCase();return{browser:{name:e,version:s.browser.major},os:{name:t,version:s.os.version.split(".")[0]},device:{type:s.device.type,brand:s.device.vendor||void 0,model:s.device.model||void 0}}}function ue(){let s=oe(),e=`${s.browser.name}|${s.browser.major}|${s.os.name}|${s.os.version.split(".")[0]}|${s.device.type}|${s.device.vendor}|${s.device.model}|${s.language}`;return N(e).substring(0,16)}var Fe={enabled:!0,sampleRate:1,maxQueueSize:100,flushInterval:5e3,maxRetries:3,retryDelay:1e3,environment:"production",contextLevel:{fatal:{maxStackFrames:5,maxBreadcrumbs:20},error:{maxStackFrames:5,maxBreadcrumbs:10},warning:{maxStackFrames:3,maxBreadcrumbs:5},info:{maxStackFrames:0,maxBreadcrumbs:0},debug:{maxStackFrames:0,maxBreadcrumbs:0}}},I=class{constructor(e){this.contexts=null;this.contextId=null;this.contextReported=!1;this.config={...Fe,...e}}markContextReported(){this.contextReported=!0}get(e){return this.config[e]}getAll(){return{...this.config}}set(e,t){this.config[e]=t}setUser(e){this.config.user=e||void 0}setTags(e){this.config.tags={...this.config.tags||{},...e}}setTag(e,t){this.config.tags||(this.config.tags={}),this.config.tags[e]=t}setExtra(e,t){this.config.extra||(this.config.extra={}),this.config.extra[e]=t}isIgnoredError(e){return L(e,this.config.ignoreErrors||[])}getEncodedContext(){return this.contexts||(this.contexts=$()),this.contexts}applyToEvent(e,t=!0){var i,o,a,u;let n={...e};if(e.tags&&(n.tags={...e.tags}),e.request&&(n.request={...e.request}),"exception"in e&&e.exception){let c=e.exception;n.exception={...c,stacktrace:c.stacktrace?{...c.stacktrace,frames:c.stacktrace.frames?c.stacktrace.frames.map(h=>({...h})):void 0}:void 0}}e.breadcrumbs&&(n.breadcrumbs=e.breadcrumbs.map(c=>({...c}))),e.user&&(n.user={...e.user}),e.contexts&&(n.contexts={...e.contexts}),this.config.release&&(n.release=this.config.release),this.config.environment&&(n.environment=this.config.environment),this.config.user&&(n.user=this.config.user),this.config.tags&&(n.tags={...this.config.tags,...e.tags||{}}),n.request?n.request.url||(n.request.url=E()):n.request={url:E(),referrer:ae()},this.contextId||(this.contextId=ue()),n.context_id=this.contextId;let r=this.applyContextLevel(n);return t&&!this.contextReported&&(this.contexts||(this.contexts=$()),r.contexts=this.contexts,r.env={b:(i=this.contexts.browser)==null?void 0:i.name,bv:(o=this.contexts.browser)==null?void 0:o.version,os:(a=this.contexts.os)==null?void 0:a.name,osv:(u=this.contexts.os)==null?void 0:u.version}),r}applyContextLevel(e){let t=this.config.contextLevel;if(!t)return e;let n=e.level||"error",r=t[n]||t.error,i={...e};if("exception"in e&&e.exception&&typeof e.exception=="object"){let o=e.exception;if(o.stacktrace&&typeof o.stacktrace=="object"){let a=o.stacktrace;Array.isArray(a.frames)&&(r.maxStackFrames===0?delete i.exception:i.exception={...o,stacktrace:{...a,frames:a.frames.slice(0,r.maxStackFrames)}})}}return e.breadcrumbs&&Array.isArray(e.breadcrumbs)&&(r.maxBreadcrumbs===0?delete i.breadcrumbs:i.breadcrumbs=e.breadcrumbs.slice(-r.maxBreadcrumbs)),i}};var B=class{constructor(){this.handlers=new Map}on(e,t){this.handlers.has(e)||this.handlers.set(e,[]),this.handlers.get(e).push(t)}off(e,t){let n=this.handlers.get(e);if(n){let r=n.indexOf(t);r>-1&&n.splice(r,1)}}emit(e,...t){let n=this.handlers.get(e);if(n)for(let r of n)try{r(...t)}catch(i){console.error("[LightSDK] EventBus handler error:",i)}}once(e,t){let n=(...r)=>{this.off(e,n),t(...r)};this.on(e,n)}destroy(){this.handlers.clear()}};var _=class{constructor(e,t,n,r,i){this.queue=[];this.timer=null;this.lastFlushTime=0;this.isFlushing=!1;this.dedupeMap=new Map;this.pendingCounts=new Map;this.errorRateWindow={};this.paused=!1;this.pauseTimer=null;this.maxSize=e,this.flushInterval=t,this.eventBus=n,this.flushCallback=r,this.syncFlushCallback=i}start(){this.startTimer(),this.setupVisibilityListener()}startTimer(){this.timer||(this.timer=setInterval(()=>{(this.queue.length>0||this.pendingCounts.size>0)&&this.flush()},this.flushInterval))}setupVisibilityListener(){this.onVisibilityChange=()=>{document.hidden&&(this.queue.length>0||this.pendingCounts.size>0)&&this.flushSync()},typeof document!="undefined"&&document.addEventListener("visibilitychange",this.onVisibilityChange),this.onBeforeUnload=()=>{(this.queue.length>0||this.pendingCounts.size>0)&&this.flushSync()},this.onPagehide=()=>{(this.queue.length>0||this.pendingCounts.size>0)&&this.flushSync()},typeof window!="undefined"&&(window.addEventListener("beforeunload",this.onBeforeUnload),window.addEventListener("pagehide",this.onPagehide))}checkInfiniteLoop(e){let t=p(),n=t-1e3;this.errorRateWindow[e]||(this.errorRateWindow[e]=[]);let r=this.errorRateWindow[e];for(r.push(t);r.length>0&&r[0]10?(this.paused||(console.warn("[LightSDK] Infinite loop detected, pausing SDK for 60s",{fingerprint:e,count:r.length}),this.eventBus.emit("error",new Error("Infinite loop detected")),this.paused=!0,this.pauseTimer&&clearTimeout(this.pauseTimer),this.pauseTimer=setTimeout(()=>{this.paused=!1,this.errorRateWindow={},console.info("[LightSDK] Resumed after infinite loop detection")},6e4)),!0):!1}enqueue(e){if(l("EventQueue","enqueue called",{type:e.type,level:e.level,message:"message"in e?e.message:void 0}),this.paused){l("EventQueue","enqueue skipped: queue paused (infinite loop detected)");return}this.cleanupExpiredDedupeEntries();let t=this.getDedupeKey(e);if(t){if(this.checkInfiniteLoop(t)){l("EventQueue","enqueue skipped: infinite loop detected",{fingerprint:t});return}let n=p(),r=this.dedupeMap.get(t);if(r)if(n-r.lastTime<6e4){if(r.count>=3){if(!this.pendingCounts.has(t))this.pendingCounts.set(t,{count:1,ts_start:n,ts_end:n});else{let i=this.pendingCounts.get(t);i.count++,i.ts_end=n}l("EventQueue","enqueue skipped: deduped (count >= 3)",{fingerprint:t,count:r.count});return}r.count++,r.lastTime=n,l("EventQueue","Dedup count incremented",{fingerprint:t,count:r.count})}else this.dedupeMap.set(t,{count:1,lastTime:n,firstReported:!0}),this.pendingCounts.delete(t),l("EventQueue","Dedup entry reset (expired)",{fingerprint:t});else this.dedupeMap.set(t,{count:1,lastTime:n,firstReported:!1}),l("EventQueue","New dedup entry created",{fingerprint:t})}this.queue.push(e),l("EventQueue","Event added to queue",{queueSize:this.queue.length}),this.eventBus.emit("event",e),this.queue.length>=this.maxSize&&(l("EventQueue","Queue reached maxSize, triggering flush",{maxSize:this.maxSize}),this.flush())}cleanupExpiredDedupeEntries(){if(this.dedupeMap.size<100&&Math.random()>.1)return;let e=p(),t=6e4;for(let[n,r]of this.dedupeMap)e-r.lastTime>t&&this.dedupeMap.delete(n)}buildCountEvents(){let e=[];for(let[t,n]of this.pendingCounts.entries()){let r={type:"count",fingerprint:t,count:n.count,ts_start:n.ts_start,ts_end:n.ts_end,timestamp:p(),level:"info"};e.push(r)}return e}getDedupeKey(e){if(e.type==="error"){let t=e;return t.fingerprint||t.message}return null}async flush(){if(l("EventQueue","flush called",{queueSize:this.queue.length,pendingCounts:this.pendingCounts.size,isFlushing:this.isFlushing}),this.queue.length===0&&this.pendingCounts.size===0){l("EventQueue","flush skipped: queue is empty");return}if(this.isFlushing){l("EventQueue","flush skipped: already flushing");return}this.isFlushing=!0;let e=this.queue.splice(0,this.queue.length),t=this.buildCountEvents(),n=[...e,...t];l("EventQueue","flush events to callback",{total:n.length,events:e.length,countEvents:t.length}),this.lastFlushTime=p(),this.eventBus.emit("report",n);try{await this.flushCallback(n),this.pendingCounts.clear(),l("EventQueue","flush completed successfully"),this.eventBus.emit("reported",n)}catch(r){throw l("EventQueue","flush failed, returning events to queue",{error:r instanceof Error?r.message:String(r)}),e.forEach(i=>this.queue.unshift(i)),r}finally{this.isFlushing=!1}}flushSync(){if(this.queue.length===0&&this.pendingCounts.size===0)return;let e=this.queue.splice(0,this.queue.length),t=new Map(this.pendingCounts),n=this.buildCountEvents(),r=[...e,...n];this.lastFlushTime=p(),this.eventBus.emit("report",r);try{this.syncFlushCallback(r),this.pendingCounts.clear(),this.eventBus.emit("reported",r)}catch(i){console.error("[LightSDK] Sync flush failed",i),e.forEach(o=>this.queue.unshift(o));for(let[o,a]of t)this.pendingCounts.has(o)||this.pendingCounts.set(o,a)}}size(){return this.queue.length}destroy(){this.timer&&(clearInterval(this.timer),this.timer=null),this.pauseTimer&&(clearTimeout(this.pauseTimer),this.pauseTimer=null),typeof document!="undefined"&&this.onVisibilityChange&&document.removeEventListener("visibilitychange",this.onVisibilityChange),typeof window!="undefined"&&(this.onBeforeUnload&&window.removeEventListener("beforeunload",this.onBeforeUnload),this.onPagehide&&window.removeEventListener("pagehide",this.onPagehide)),this.dedupeMap.clear(),this.pendingCounts.clear(),this.errorRateWindow={}}};var ce={event_id:"eid",timestamp:"ts",start_timestamp:"sts",type:"t",level:"l",message:"m",platform:"p",release:"r",environment:"e",fingerprint:"fp",context_id:"cid",user:"u",tags:"tg",exception:"ex",request:"req",contexts:"ctx",breadcrumbs:"bc",transaction:"tx",duration:"d",spans:"sp",extra:"xt"},tt=Object.fromEntries(Object.entries(ce).map(([s,e])=>[e,s]));function le(s){if(!s||typeof s!="object")return s;let e={};for(let[t,n]of Object.entries(s)){let r=ce[t]||t;e[r]=n}return e}var O=class{constructor(e,t,n){this.useShortFields=!0;this.dsn=e,this.maxRetries=t,this.retryDelay=n}async report(e){if(l("Reporter","report called",{eventCount:e.length}),e.length===0){l("Reporter","report skipped: empty events");return}let t=this.buildEnvelope(e),n=C(this.dsn);l("Reporter","Envelope built",{envelopeSize:t.length,url:n});let r=0;for(;r<=this.maxRetries;)try{l("Reporter",`Sending request (attempt ${r+1}/${this.maxRetries+1})`),await this.send(t,!1),l("Reporter","Request succeeded");return}catch(i){let o=i.status;if(H("Reporter",`Request failed (attempt ${r+1})`,{status:o,error:i}),o&&o>=400&&o<500)throw i;if(r++,r>this.maxRetries)throw H("Reporter","All retries exhausted"),i;let a=Math.min(this.retryDelay*Math.pow(2,r-1),5e3);l("Reporter",`Retrying in ${a}ms`),await this.delay(a)}}reportSync(e){if(e.length===0)return;let t=this.buildEnvelope(e);try{if(this.sendSync(t))return}catch(n){}this.sendViaImage(t)}buildEnvelope(e){let t=this.extractSharedMeta(e),n={event_id:se(),sent_at:new Date().toISOString(),meta:t};this.useShortFields&&(n._sf=1);let r=this.applyRelativeTimestamps(e,n),o=[JSON.stringify(n)];for(let a of r){let u=this.stripSharedFields(a,t);this.useShortFields&&(u=le(u));let c=JSON.stringify(u),h=JSON.stringify({type:this.getEnvelopeType(a),length:c.length});o.push(h,c)}return o.join(` -`)}applyRelativeTimestamps(e,t){if(e.length<=1)return e;let n=[],r=e[0].timestamp?new Date(e[0].timestamp).getTime():Date.now();t._rt=1,t._bt=r;for(let i=0;io.release===t.release)&&(n.release=t.release),t.environment&&e.every(o=>o.environment===t.environment)&&(n.environment=t.environment),t.user&&e.every(o=>JSON.stringify(o.user)===JSON.stringify(t.user))&&(n.user=t.user);let r=t.env;return r&&(n.env=r),n}stripSharedFields(e,t){let n={...e};return t.release&&n.release===t.release&&delete n.release,t.environment&&n.environment===t.environment&&delete n.environment,t.user&&JSON.stringify(n.user)===JSON.stringify(t.user)&&delete n.user,t.env&&delete n.env,n}getEnvelopeType(e){switch(e.type){case"error":return"event";case"performance":return"transaction";default:return e.type}}async send(e,t=!1){let n=C(this.dsn);if(navigator.sendBeacon)try{let r=new Blob([e],{type:"application/x-sentry-envelope"});if(navigator.sendBeacon(n,r))return}catch(r){}if(typeof fetch=="function")try{let r=new AbortController,i=setTimeout(()=>r.abort(),1e4),o=await fetch(n,{method:"POST",body:e,headers:{"Content-Type":"application/x-sentry-envelope"},keepalive:!0,signal:r.signal});if(clearTimeout(i),o.ok)return;let a=new Error(`HTTP ${o.status}`);throw a.status=o.status,a}catch(r){throw r}if(typeof XMLHttpRequest!="undefined")return new Promise((r,i)=>{let o=new XMLHttpRequest;o.open("POST",n,!t),o.setRequestHeader("Content-Type","application/x-sentry-envelope"),o.timeout=1e4,o.onload=()=>{if(o.status>=200&&o.status<300)r();else{let a=new Error(`HTTP ${o.status}`);a.status=o.status,i(a)}},o.onerror=()=>i(new Error("Network error")),o.ontimeout=()=>i(new Error("Request timeout")),o.send(e)});throw new Error("No transport available")}sendSync(e){let t=C(this.dsn);if(navigator.sendBeacon)try{let n=new Blob([e],{type:"application/x-sentry-envelope"});return navigator.sendBeacon(t,n)}catch(n){return!1}if(typeof XMLHttpRequest!="undefined")try{let n=new XMLHttpRequest;return n.open("POST",t,!1),n.setRequestHeader("Content-Type","application/x-sentry-envelope"),n.send(e),n.status>=200&&n.status<300}catch(n){return!1}return!1}sendViaImage(e){try{let t=C(this.dsn),n=new Image,r=encodeURIComponent(btoa(e)),i=t.includes("?")?"&":"?";return n.src=t+i+"sentry_data="+r.substring(0,2e3),!0}catch(t){return!1}}delay(e){return new Promise(t=>setTimeout(t,e))}};var F=class{constructor(e){this.plugins=new Map;this.client=e}add(e){if(!this.plugins.has(e.name)){this.plugins.set(e.name,e);try{e.setup(this.client)}catch(t){console.error(`[LightSDK] Plugin "${e.name}" setup error:`,t)}}}remove(e){let t=this.plugins.get(e);if(t){if(t.destroy)try{t.destroy()}catch(n){console.error(`[LightSDK] Plugin "${e}" destroy error:`,n)}this.plugins.delete(e)}}get(e){return this.plugins.get(e)}has(e){return this.plugins.has(e)}applyBeforeReport(e){let t=e;for(let n of this.plugins.values())if(n.beforeReport)try{let r=n.beforeReport(t);if(r===null)return null;t=r}catch(r){console.error(`[LightSDK] Plugin "${n.name}" beforeReport error:`,r)}return t}applyAfterReport(e){for(let t of this.plugins.values())if(t.afterReport)try{t.afterReport(e)}catch(n){console.error(`[LightSDK] Plugin "${t.name}" afterReport error:`,n)}}destroy(){for(let e of this.plugins.values())if(e.destroy)try{e.destroy()}catch(t){console.error(`[LightSDK] Plugin "${e.name}" destroy error:`,t)}this.plugins.clear()}};var K=class{constructor(e){this.breadcrumbs=[];this.enabled=!0;var t,n,r,i;if(!e.dsn)throw new Error("DSN is required");M(e.debug===!0),l("Client","Initializing SDK",{dsn:e.dsn,debug:e.debug,enabled:e.enabled!==!1}),this.dsn=ie(e.dsn),this.configManager=new I(e),this.eventBus=new B,this.reporter=new O(this.dsn,(t=this.configManager.get("maxRetries"))!=null?t:3,(n=this.configManager.get("retryDelay"))!=null?n:1e3),this.pluginManager=new F(this),this.queue=new _((r=this.configManager.get("maxQueueSize"))!=null?r:100,(i=this.configManager.get("flushInterval"))!=null?i:5e3,this.eventBus,async o=>this.flushEvents(o),o=>this.syncFlushEvents(o)),this.enabled=this.configManager.get("enabled")!==!1,l("Client","SDK initialized",{enabled:this.enabled})}get maxBreadcrumbs(){var e;return(e=this.configManager.get("maxBreadcrumbs"))!=null?e:20}get config(){return this.configManager.getAll()}init(){this.enabled&&(this.queue.start(),this.emit("ready"))}async flushEvents(e){l("Client","flushEvents start",{eventCount:e.length});let t=[];for(let i of e){let o=this.pluginManager.applyBeforeReport(i);o?t.push(o):l("Client","Event filtered by beforeReport plugin",{type:i.type,message:"message"in i?i.message:void 0})}if(t.length===0){l("Client","flushEvents: all events filtered by beforeReport");return}let n=!0,r=[];for(let i of t){let o=this.configManager.applyToEvent(i,n);n=!1;let a=this.configManager.get("beforeSend"),u=a?a(o):o;if(!u){l("Client","Event filtered by beforeSend",{type:i.type});continue}r.push(u)}if(r.length===0){l("Client","flushEvents: all events filtered by beforeSend");return}l("Client","Reporting events",{count:r.length}),await this.reporter.report(r),l("Client","Report completed successfully"),this.configManager.markContextReported();for(let i of r)this.pluginManager.applyAfterReport(i)}syncFlushEvents(e){let t=[];for(let i of e){let o=this.pluginManager.applyBeforeReport(i);o&&t.push(o)}if(t.length===0)return;let n=!0,r=[];for(let i of t){let o=this.configManager.applyToEvent(i,n);n=!1;let a=this.configManager.get("beforeSend"),u=a?a(o):o;u&&r.push(u)}r.length!==0&&(this.reporter.reportSync(r),this.configManager.markContextReported())}on(e,t){this.eventBus.on(e,t)}off(e,t){this.eventBus.off(e,t)}emit(e,...t){this.eventBus.emit(e,...t)}captureException(e){if(l("Client","captureException called",{error:e instanceof Error?e.message:String(e)}),!this.enabled){l("Client","captureException skipped: SDK disabled");return}let t=this.buildErrorEvent(e);if(l("Client","Error event built",{type:t.type,message:t.message,fingerprint:t.fingerprint}),this.configManager.isIgnoredError(t.message)){l("Client","captureException skipped: error ignored by ignoreErrors");return}t.breadcrumbs=[...this.breadcrumbs],l("Client","Enqueue error event",{breadcrumbs:this.breadcrumbs.length}),this.queue.enqueue(t)}captureMessage(e,t="info"){if(!this.enabled)return;let n={type:"error",level:t,message:e,timestamp:p(),breadcrumbs:[...this.breadcrumbs]};this.configManager.isIgnoredError(e)||this.queue.enqueue(n)}captureEvent(e){if(!this.enabled)return;let t={timestamp:p(),level:"info",breadcrumbs:[...this.breadcrumbs],...e};this.queue.enqueue(t)}buildErrorEvent(e){let t=p();if(e instanceof Error){let r=P(e.stack,{maxFrames:5}),i=T(e.name,e.message,r);return{type:"error",level:"error",message:e.message,timestamp:t,exception:{type:e.name,value:e.message,stacktrace:{frames:r}},fingerprint:i}}return{type:"error",level:"error",message:String(e),timestamp:t}}setUser(e){this.configManager.setUser(e)}setTag(e,t){this.configManager.setTag(e,t)}setTags(e){this.configManager.setTags(e)}setExtra(e,t){this.configManager.setExtra(e,t)}addBreadcrumb(e){let t={...e,timestamp:p()};this.breadcrumbs.push(t),this.breadcrumbs.length>this.maxBreadcrumbs&&this.breadcrumbs.shift()}async flush(){await this.queue.flush()}disable(){this.enabled=!1}enable(){this.enabled=!0}use(e){this.pluginManager.add(e)}destroy(){this.queue.destroy(),this.pluginManager.destroy(),this.eventBus.destroy(),this.breadcrumbs=[]}},j=K;var W=class{constructor(){this.name="error";this.version="1.0.0";this.config={maxStackFrames:5,captureNodeModules:!1,captureColumn:!0,relativePathOnly:!1,resourceSampleRate:.1}}setup(e){this.client=e,this.loadConfig(),this.setupGlobalError(),this.setupUnhandledRejection(),this.setupResourceError()}loadConfig(){let e=this.client.config;e&&b(e.error)&&(this.config={...this.config,...e.error}),e.ignoreErrors&&(this.config.ignoreErrors=[...this.config.ignoreErrors||[],...e.ignoreErrors]),e.ignoreUrls&&(this.config.ignoreUrls=[...this.config.ignoreUrls||[],...e.ignoreUrls]),e.includePaths&&(this.config.includePaths=[...this.config.includePaths||[],...e.includePaths])}shouldIgnoreError(e){return e?L(e,this.config.ignoreErrors||[]):!1}shouldIgnoreScriptUrl(e){return D(e,this.config.ignoreUrls||[])}shouldIncludePath(e){let t=this.config.includePaths||[];return t.length===0?!0:e.some(n=>t.some(r=>{var i;return typeof r=="string"?(i=n.filename)==null?void 0:i.includes(r):r.test(n.filename||"")}))}shouldSample(){var t;let e=(t=this.config.sampleRate)!=null?t:1;return e>=1?!0:e<=0?!1:Math.random()=1?!0:e<=0?!1:Math.random(){try{if(this.originalOnError&&this.originalOnError.call(window,e,t,n,r,i),t&&this.shouldIgnoreScriptUrl(t))return!1;let o=this.buildErrorEvent(i||e,t,n,r);o&&this.client.captureEvent(o)}catch(o){console.error("[LightSDK] ErrorPlugin global error handler error:",o)}return!1})}setupUnhandledRejection(){typeof window!="undefined"&&(this.onUnhandledRejection=e=>{try{let t=e.reason,n=this.extractUrlFromReason(t);if(n&&this.shouldIgnoreScriptUrl(n))return;let r=this.buildErrorEvent(t);r&&(r.type==="error"&&(r.tags={...r.tags||{},unhandled:"true",promise:"true"}),this.client.captureEvent(r))}catch(t){console.error("[LightSDK] ErrorPlugin unhandledrejection handler error:",t)}},window.addEventListener("unhandledrejection",this.onUnhandledRejection))}extractUrlFromReason(e){if(e instanceof Error&&e.stack){let t=e.stack.match(/at\s+(?:.+?\s+)?\((https?:\/\/[^:]+):\d+:\d+\)/);if(t)return t[1];let n=e.stack.match(/(https?:\/\/[^\s)]+):\d+:\d+/);if(n)return n[1]}return null}setupResourceError(){typeof window!="undefined"&&(this.onResourceError=e=>{var i;let t=e.target;if(!t)return;let n=(i=t.tagName)==null?void 0:i.toLowerCase(),r=t.src||t.href;if(n&&r&&["img","script","link","audio","video"].includes(n))try{if(this.shouldIgnoreScriptUrl(r)||!this.shouldSampleResource())return;let o=`resource:${n}`,a=R(r);this.client.captureEvent({type:"error",level:"warning",message:`Resource load failed: ${n} ${a}`,timestamp:p(),fingerprint:o,tags:{resource_type:n,resource_url:a},exception:{type:"ResourceError",value:`Failed to load ${n} resource`}})}catch(o){console.error("[LightSDK] ErrorPlugin resource error handler error:",o)}},window.addEventListener("error",this.onResourceError,!0))}buildErrorEvent(e,t,n,r){let i=p();if(e instanceof Error){if(this.shouldIgnoreError(e.message))return null;let u=P(e.stack,{captureNodeModules:this.config.captureNodeModules,captureColumn:this.config.captureColumn,relativePathOnly:this.config.relativePathOnly,maxFrames:this.config.maxStackFrames});if(!this.shouldIncludePath(u)||!this.shouldSample())return null;let c=T(e.name,e.message,u);return{type:"error",level:"error",message:e.message,timestamp:i,exception:{type:e.name,value:e.message,stacktrace:{frames:u}},fingerprint:c}}let o=String(e);if(this.shouldIgnoreError(o))return null;let a=[];return t&&a.push({filename:t,lineno:n,colno:this.config.captureColumn?r:void 0,in_app:!0}),!this.shouldIncludePath(a)||!this.shouldSample()?null:{type:"error",level:"error",message:o,timestamp:i,exception:{type:"Error",value:o,stacktrace:{frames:a}}}}destroy(){typeof window!="undefined"&&(this.originalOnError!==void 0&&(window.onerror=this.originalOnError),this.onUnhandledRejection&&window.removeEventListener("unhandledrejection",this.onUnhandledRejection),this.onResourceError&&window.removeEventListener("error",this.onResourceError,!0))}},X=W;var A=class{constructor(){this.name="performance";this.version="1.0.0";this.config={sampleRate:.1,captureLongTasks:!0,captureResources:!1,resourceSampleRate:.01,longTaskSampleRate:.05,captureNavigation:!0,captureFP:!0};this.observers=[];this.navLoadTimer=null;this.totalBlockingTime=0;this.fcpTime=null;this.lastLongTaskEndTime=0;this.ttiReported=!1;this.ttiTimer=null}setup(e){this.client=e,this.loadConfig(),this.observeWebVitals(),this.observeLongTasks(),this.observeNavigation(),this.observeResources()}loadConfig(){let e=this.client.config;e&&b(e.performance)&&(this.config={...this.config,...e.performance})}shouldSample(e="default"){var n,r,i;let t=(n=this.config.sampleRate)!=null?n:.1;return e==="resource"?t=(r=this.config.resourceSampleRate)!=null?r:.01:e==="longtask"?t=(i=this.config.longTaskSampleRate)!=null?i:.05:e==="vitals"&&(t=1),t>=1?!0:t<=0?!1:Math.random(){let n=t.getEntriesByName("first-paint");n.length>0&&this.reportMetric("FP",n[0].startTime,"ms",{},"vitals")});e.observe({type:"paint",buffered:!0}),this.observers.push(e)}catch(e){}}observeLCP(){try{let e=new PerformanceObserver(t=>{let n=t.getEntries(),r=n[n.length-1];if(r){let i=r.renderTime||r.loadTime||r.startTime;this.reportMetric("LCP",i,"ms",{},"vitals")}});e.observe({type:"largest-contentful-paint",buffered:!0}),this.observers.push(e)}catch(e){}}observeFID(){try{let e=new PerformanceObserver(t=>{let n=t.getEntries();if(n.length>0){let r=n[0],i=r.processingStart-r.startTime;this.reportMetric("FID",i,"ms",{},"vitals")}});e.observe({type:"first-input",buffered:!0}),this.observers.push(e)}catch(e){}}observeCLS(){try{let e=0,t=0,n=[],r=new PerformanceObserver(i=>{let o=i.getEntries();for(let a of o)if(!a.hadRecentInput){let u=n[0],c=n[n.length-1];t&&a.startTime-((c==null?void 0:c.duration)||0)<1e3&&a.startTime-u.startTime<5e3?(t+=a.value||0,n.push(a)):(t=a.value||0,n=[a]),t>e&&(e=t,this.reportMetric("CLS",e,"",{},"vitals"))}});r.observe({type:"layout-shift",buffered:!0}),this.observers.push(r)}catch(e){}}observeFCP(){try{let e=new PerformanceObserver(t=>{let n=t.getEntriesByName("first-contentful-paint");n.length>0&&(this.fcpTime=n[0].startTime,this.lastLongTaskEndTime=n[0].startTime,this.reportMetric("FCP",n[0].startTime,"ms",{},"vitals"),this.scheduleTTI())});e.observe({type:"paint",buffered:!0}),this.observers.push(e)}catch(e){}}observeTTFB(){try{let e=new PerformanceObserver(t=>{let n=t.getEntriesByType("navigation");if(n.length>0){let r=n[0],i=r.responseStart-r.requestStart;this.reportMetric("TTFB",Math.max(0,i),"ms",{},"vitals")}});e.observe({type:"navigation",buffered:!0}),this.observers.push(e)}catch(e){}}observeLongTasks(){if(this.config.captureLongTasks)try{let e=new PerformanceObserver(t=>{let n=t.getEntries();for(let r of n){let i=r.startTime+r.duration;if(i>this.lastLongTaskEndTime&&(this.lastLongTaskEndTime=i),this.fcpTime!==null&&r.startTime>=this.fcpTime){let o=r.duration-50;o>0&&(this.totalBlockingTime+=o)}this.reportMetric("longtask",r.duration,"ms",{},"longtask"),this.scheduleTTI()}});e.observe({type:"longtask",buffered:!0}),this.observers.push(e)}catch(e){}}scheduleTTI(){this.ttiReported||(this.ttiTimer&&clearTimeout(this.ttiTimer),this.ttiTimer=setTimeout(()=>{if(this.ttiReported)return;this.ttiReported=!0;let e=Math.max(this.lastLongTaskEndTime,this.fcpTime||0);this.reportMetric("TTI",e,"ms",{},"vitals"),this.reportMetric("TBT",this.totalBlockingTime,"ms",{},"vitals")},5e3))}observeNavigation(){this.config.captureNavigation&&typeof performance!="undefined"&&(this.onLoad=()=>{this.navLoadTimer=setTimeout(()=>{let e=performance.timing;if(!e)return;let t=e.navigationStart,n={dom_ready:e.domContentLoadedEventEnd-t,load_time:e.loadEventEnd-t,dns:e.domainLookupEnd-e.domainLookupStart,tcp:e.connectEnd-e.connectStart,ssl:e.secureConnectionStart>0?e.connectEnd-e.secureConnectionStart:0,ttfb:e.responseStart-e.requestStart,download:e.responseEnd-e.responseStart,dom_parse:e.domInteractive-e.responseEnd};for(let[r,i]of Object.entries(n))i>0&&this.reportMetric(r,i,"ms");this.navLoadTimer=null},0)},window.addEventListener("load",this.onLoad))}observeResources(){if(this.config.captureResources&&typeof performance!="undefined")try{let e=new PerformanceObserver(t=>{let n=t.getEntriesByType("resource");for(let r of n)r.duration>1e3&&this.reportMetric("resource_slow",r.duration,"ms",{resource_name:r.name.substring(0,200),resource_type:r.initiatorType},"resource")});e.observe({type:"resource",buffered:!0}),this.observers.push(e)}catch(e){}}getRating(e,t){let r={LCP:{good:2500,poor:4e3},FCP:{good:1800,poor:3e3},FP:{good:1800,poor:3e3},FID:{good:100,poor:300},CLS:{good:.1,poor:.25},TTFB:{good:800,poor:1800}}[e];return!r||t<=r.good?"good":t<=r.poor?"needs-improvement":"poor"}reportMetric(e,t,n,r={},i="default"){if(!this.shouldSample(i))return;let o=this.getRating(e,t),a={type:"performance",level:"info",metric:e,value:Math.round(t*100)/100,unit:n,rating:o,timestamp:p(),tags:{metric:e,rating:o,...r}};this.client.captureEvent(a)}destroy(){for(let e of this.observers)try{e.disconnect()}catch(t){}this.observers=[],this.ttiTimer&&(clearTimeout(this.ttiTimer),this.ttiTimer=null),this.navLoadTimer&&(clearTimeout(this.navLoadTimer),this.navLoadTimer=null),typeof window!="undefined"&&this.onLoad&&window.removeEventListener("load",this.onLoad)}},z=A;var V=class{constructor(){this.name="network";this.version="1.0.0";this.config={captureXHR:!0,captureFetch:!0,captureSuccess:!1,captureBody:!1,captureRequestBody:!1,captureResponseBody:!1,captureRequestHeaders:["content-type","user-agent"],captureResponseHeaders:["content-type","content-length"],errorSampleRate:1,successSampleRate:.01,slowThreshold:3e3,slowSampleRate:1,ignoreStatusCodes:[]}}setup(e){this.client=e,this.loadConfig(),this.config.captureFetch&&this.patchFetch(),this.config.captureXHR&&this.patchXHR()}loadConfig(){let e=this.client.config;e&&b(e.network)&&(this.config={...this.config,...e.network}),e.ignoreUrls&&(this.config.ignoreUrls=[...this.config.ignoreUrls||[],...e.ignoreUrls])}shouldIgnore(e){return D(e,this.config.ignoreUrls||[])}shouldSample(e,t){var r,i,o,a;let n=e?(r=this.config.errorSampleRate)!=null?r:1:(i=this.config.successSampleRate)!=null?i:.01;return!e&&t>=((o=this.config.slowThreshold)!=null?o:3e3)&&(n=(a=this.config.slowSampleRate)!=null?a:1),n>=1?!0:n<=0?!1:Math.random(){var f;let h=p()-r,w=c.ok,g=c.status;return(f=e.config.ignoreStatusCodes)!=null&&f.includes(g)||!e.shouldSample(!w,h)||(!w||e.config.captureSuccess)&&e.reportNetwork({sub_type:"fetch",method:o.toUpperCase(),url:a,status_code:g,duration:h,success:w,error:w?void 0:`HTTP ${g}`}),c},c=>{let h=p()-r;throw e.shouldSample(!0,h)&&e.reportNetwork({sub_type:"fetch",method:o.toUpperCase(),url:a,duration:h,success:!1,error:(c==null?void 0:c.message)||"Network error"}),c}),u}}patchXHR(){if(typeof XMLHttpRequest=="undefined")return;this.originalXHROpen=XMLHttpRequest.prototype.open,this.originalXHRSend=XMLHttpRequest.prototype.send;let e=this;XMLHttpRequest.prototype.open=function(t,n){return this._lightMethod=t,this._lightUrl=typeof n=="string"?n:n.toString(),this._lightTracked=!1,e.originalXHROpen.apply(this,arguments)},XMLHttpRequest.prototype.send=function(t){let n=p(),r=this._lightMethod||"GET",i=this._lightUrl||"",o=this._lightTracked;if(e.shouldIgnore(i)||o)return e.originalXHRSend.apply(this,arguments);this._lightTracked=!0;let a=R(i),u=0;t&&typeof t=="string"&&(u=t.length);let c=this.onloadend;return this.onloadend=function(h){var y;let w=p()-n,g=this.status,f=g>=200&&g<300;if(!((y=e.config.ignoreStatusCodes)!=null&&y.includes(g))&&e.shouldSample(!f,w)&&(!f||e.config.captureSuccess)){let m=0;try{let S=this.getResponseHeader("content-length");S&&(m=parseInt(S,10)),!m&&this.responseText&&(m=this.responseText.length)}catch(S){}e.reportNetwork({sub_type:"xhr",method:r.toUpperCase(),url:a,status_code:g,duration:w,request_size:u||void 0,response_size:m||void 0,success:f,error:f?void 0:`HTTP ${g}`})}if(c)return c.call(this,h)},e.originalXHRSend.apply(this,arguments)}}reportNetwork(e){let t={type:"network",level:e.success?"info":"error",timestamp:p(),tags:{method:e.method,sub_type:e.sub_type,success:String(e.success)},...e};this.client.captureEvent(t)}destroy(){this.originalFetch&&(window.fetch=this.originalFetch),this.originalXHROpen&&(XMLHttpRequest.prototype.open=this.originalXHROpen),this.originalXHRSend&&(XMLHttpRequest.prototype.send=this.originalXHRSend)}},Q=V;var G=class{constructor(){this.name="behavior";this.version="1.0.0";this.config={capturePV:!0,captureClick:!0,captureRoute:!0,captureDuration:!0,captureScroll:!0,clickThrottle:300,scrollThrottle:1e3,sampleRate:.01};this.lastClickTime=0;this.lastScrollTime=0;this.maxScrollDepth=0;this.pageEnterTime=0;this.scrollReported=!1}setup(e){this.client=e,this.loadConfig(),this.config.capturePV&&this.trackPV(),this.config.captureClick&&this.trackClick(),this.config.captureRoute&&this.trackRoute(),this.config.captureDuration&&this.trackPageDuration(),this.config.captureScroll&&this.trackScroll()}loadConfig(){let e=this.client.config;e&&b(e.behavior)&&(this.config={...this.config,...e.behavior})}shouldSample(){var t;let e=(t=this.config.sampleRate)!=null?t:.01;return e>=1?!0:e<=0?!1:Math.random(){var a,u,c;let t=p(),n=(a=this.config.clickThrottle)!=null?a:300;if(t-this.lastClickTime{let r=E();if(r!==e){let i=e,o=r;e=r,this.reportBehavior({sub_type:"route",page_url:o,referrer:i,properties:{from:i,to:o}}),this.pageEnterTime=p(),this.maxScrollDepth=0,this.scrollReported=!1}};this.originalPushState=history.pushState,this.originalReplaceState=history.replaceState;let n=this;history.pushState=function(){let r=n.originalPushState.apply(this,arguments);return setTimeout(t,0),r},history.replaceState=function(){let r=n.originalReplaceState.apply(this,arguments);return setTimeout(t,0),r},this.onPopState=()=>{setTimeout(t,0)},this.onHashchange=()=>{setTimeout(t,0)},window.addEventListener("popstate",this.onPopState),window.addEventListener("hashchange",this.onHashchange)}trackPageDuration(){if(typeof window=="undefined")return;this.pageEnterTime=p();let e=()=>{let t=p()-this.pageEnterTime;t>1e3&&(this.config.captureScroll&&!this.scrollReported&&this.reportScroll(),this.reportBehavior({sub_type:"duration",page_url:E(),properties:{duration:t,max_scroll_depth:this.maxScrollDepth}}))};this.onVisibilityChange=()=>{document.hidden?e():this.pageEnterTime=p()},this.onBeforeUnload=e,this.onPagehide=e,document.addEventListener("visibilitychange",this.onVisibilityChange),window.addEventListener("beforeunload",this.onBeforeUnload),window.addEventListener("pagehide",this.onPagehide)}trackScroll(){typeof window!="undefined"&&(this.onScroll=()=>{var r;let e=p(),t=(r=this.config.scrollThrottle)!=null?r:1e3;if(e-this.lastScrollTimethis.maxScrollDepth&&(this.maxScrollDepth=n)},window.addEventListener("scroll",this.onScroll,{passive:!0}))}reportScroll(){this.scrollReported||(this.scrollReported=!0,this.reportBehavior({sub_type:"scroll",page_url:E(),properties:{max_depth:this.maxScrollDepth}}))}reportBehavior(e){if(!this.shouldSample())return;let t={type:"behavior",level:"info",timestamp:p(),tags:{sub_type:e.sub_type,page_url:E()},...e};this.client.captureEvent(t)}destroy(){typeof window!="undefined"&&(this.originalPushState&&(history.pushState=this.originalPushState),this.originalReplaceState&&(history.replaceState=this.originalReplaceState),this.onPopState&&window.removeEventListener("popstate",this.onPopState),this.onHashchange&&window.removeEventListener("hashchange",this.onHashchange),this.onBeforeUnload&&window.removeEventListener("beforeunload",this.onBeforeUnload),this.onPagehide&&window.removeEventListener("pagehide",this.onPagehide),this.onScroll&&window.removeEventListener("scroll",this.onScroll)),typeof document!="undefined"&&(this.onClick&&document.removeEventListener("click",this.onClick,!0),this.onVisibilityChange&&document.removeEventListener("visibilitychange",this.onVisibilityChange))}},J=G;var qe="light-sentry-offline",v="events",Z=1e3,Y=class{constructor(){this.name="offline";this.version="1.0.0";this.config={maxEvents:Z};this.db=null;this.isOnline=!0;this.isSyncing=!1;this.pendingEvents=[]}setup(e){this.client=e,this.loadConfig(),this.initDatabase(),this.setupNetworkListeners()}loadConfig(){let e=this.client.config;e&&typeof e.offline=="object"&&(this.config={...this.config,...e.offline})}async initDatabase(){if(typeof indexedDB=="undefined"){console.warn("[LightSDK] OfflinePlugin: IndexedDB not available");return}return new Promise((e,t)=>{let n=indexedDB.open(qe,1);n.onerror=()=>{console.warn("[LightSDK] OfflinePlugin: Failed to open IndexedDB"),t(n.error)},n.onsuccess=()=>{this.db=n.result,e()},n.onupgradeneeded=r=>{let i=r.target.result,o=r.oldVersion;i.objectStoreNames.contains(v)||i.createObjectStore(v,{keyPath:"id"}).createIndex("timestamp","timestamp",{unique:!1})}})}setupNetworkListeners(){typeof window!="undefined"&&(this.isOnline=navigator.onLine,this.onOnline=()=>{console.info("[LightSDK] OfflinePlugin: Network online"),this.isOnline=!0,this.syncPendingEvents()},this.onOffline=()=>{console.info("[LightSDK] OfflinePlugin: Network offline"),this.isOnline=!1},window.addEventListener("online",this.onOnline),window.addEventListener("offline",this.onOffline))}generateId(){return`${Date.now()}-${Math.random().toString(36).substring(2,11)}`}async saveToIndexedDB(e){if(!this.db)return;let t=this.config.maxEvents||Z,n=await this.getEventCount();return n>=t&&await this.deleteOldestEvents(n-t+1),new Promise((r,i)=>{let a=this.db.transaction([v],"readwrite").objectStore(v),u={id:this.generateId(),event:{...e,offline:!0},timestamp:p()},c=a.add(u);c.onsuccess=()=>r(),c.onerror=()=>i(c.error)})}getEventCount(){return this.db?new Promise((e,t)=>{let i=this.db.transaction([v],"readonly").objectStore(v).count();i.onsuccess=()=>e(i.result),i.onerror=()=>t(i.error)}):Promise.resolve(0)}async deleteOldestEvents(e){if(!(!this.db||e<=0))return new Promise((t,n)=>{let a=this.db.transaction([v],"readwrite").objectStore(v).index("timestamp").openCursor(),u=0;a.onsuccess=c=>{let h=c.target.result;h&&un(a.error)})}async getAllStoredEvents(){return this.db?new Promise((e,t)=>{let o=this.db.transaction([v],"readonly").objectStore(v).index("timestamp").getAll();o.onsuccess=()=>{let a=o.result||[];a.sort((u,c)=>u.timestamp-c.timestamp),e(a)},o.onerror=()=>t(o.error)}):[]}async clearStoredEvents(){if(this.db)return new Promise((e,t)=>{let i=this.db.transaction([v],"readwrite").objectStore(v).clear();i.onsuccess=()=>e(),i.onerror=()=>t(i.error)})}async syncPendingEvents(){if(!(!this.isOnline||this.isSyncing)){this.isSyncing=!0,console.info("[LightSDK] OfflinePlugin: Syncing pending events");try{let e=0;for(;this.pendingEvents.length>0;){let n=this.pendingEvents.shift();try{this.client.captureEvent(n),e++}catch(r){console.error("[LightSDK] OfflinePlugin: Failed to re-enqueue memory event",r)}}let t=await this.getAllStoredEvents();if(t.length>0)for(let n of t)try{let r=n.event;this.client.captureEvent(r),e++}catch(r){console.error("[LightSDK] OfflinePlugin: Failed to re-enqueue event",r)}try{await this.client.flush()}catch(n){}await this.clearStoredEvents(),console.info(`[LightSDK] OfflinePlugin: Synced ${e} events`)}catch(e){console.error("[LightSDK] OfflinePlugin: Sync failed",e)}finally{this.isSyncing=!1}}}beforeReport(e){if(!this.isOnline){let n=this.config.maxEvents||Z;return this.pendingEvents.length>=n&&this.pendingEvents.shift(),this.pendingEvents.push(e),this.savePendingEventsToDB(),null}let t={...e};return delete t.offline,t}savePendingEventsToDB(){if(this.pendingEvents.length===0)return;let e=this.pendingEvents.splice(0,this.pendingEvents.length),t=0,n=()=>{if(t>=e.length)return;let r=e[t];this.saveToIndexedDB(r).then(()=>{t++,n()}).catch(i=>{console.error("[LightSDK] OfflinePlugin: Failed to save event offline",i),this.pendingEvents.unshift(...e.slice(t))})};n()}destroy(){typeof window!="undefined"&&(this.onOnline&&window.removeEventListener("online",this.onOnline),this.onOffline&&window.removeEventListener("offline",this.onOffline)),this.db&&(this.db.close(),this.db=null)}},ee=Y;var te=class{constructor(){this.name="sampling";this.version="1.0.0";this.config={rates:{error:1,performance:1,network:1,behavior:1}}}setup(e){this.client=e,this.loadConfig()}loadConfig(){let e=this.client.config;if(e&&b(e.sampling)){let t=e.sampling;"rates"in t&&b(t.rates)&&(this.config.rates={...this.config.rates,...t.rates})}}shouldSample(e){var r;let t=(r=this.client.config.sampleRate)!=null?r:1;if(t<=0)return!1;let n=this.getTypeRate(e);return t>=1?this.randomCheck(n):this.randomCheck(t*n)}getTypeRate(e){let t=this.config.rates||{},n=e.type;if(n==="count")return 1;let r=t[n];return r!==void 0?r:1}randomCheck(e){return e>=1?!0:e<=0?!1:Math.random()typeof i=="string"))||[];(n.includes("performance")||n.includes("all"))&&t.push(new z),(n.includes("network")||n.includes("all"))&&t.push(new Q),(n.includes("behavior")||n.includes("all"))&&t.push(new J),l("Index","Registering plugins",{count:t.length,plugins:t.map(i=>i.name)});for(let i of t)e.use(i);if(s.plugins)for(let i of s.plugins)typeof i=="object"&&i!==null&&"name"in i&&"setup"in i&&e.use(i);return e.init(),d=e,l("Index","init completed, globalClient set"),e}function pe(){return d}function he(s){if(l("Index","captureException called",{hasClient:!!d}),!d){console.warn("[LightSDK] SDK not initialized. Call LightSentry.init() first.");return}d.captureException(s)}function fe(s,e){if(l("Index","captureMessage called",{hasClient:!!d}),!d){console.warn("[LightSDK] SDK not initialized. Call LightSentry.init() first.");return}d.captureMessage(s,e)}function ge(s){if(l("Index","captureEvent called",{hasClient:!!d}),!d){console.warn("[LightSDK] SDK not initialized. Call LightSentry.init() first.");return}d.captureEvent(s)}function me(s){d==null||d.setUser(s)}function ve(s,e){d==null||d.setTag(s,e)}function ye(s){d==null||d.setTags(s)}function be(s,e){d==null||d.setExtra(s,e)}function Ee(s){d==null||d.addBreadcrumb(s)}async function we(){await(d==null?void 0:d.flush())}function Se(){d==null||d.disable()}function xe(){d==null||d.enable()}var Ne={init:de,getClient:pe,captureException:he,captureMessage:fe,captureEvent:ge,setUser:me,setTag:ve,setTags:ye,setExtra:be,addBreadcrumb:Ee,flush:we,disable:Se,enable:xe};return Pe(Ue);})(); +"use strict";var LightSDK=(()=>{var G=Object.defineProperty;var Ye=Object.getOwnPropertyDescriptor;var Ze=Object.getOwnPropertyNames;var et=Object.prototype.hasOwnProperty;var tt=(s,e)=>{for(var t in e)G(s,t,{get:e[t],enumerable:!0})},nt=(s,e,t,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let r of Ze(e))!et.call(s,r)&&r!==t&&G(s,r,{get:()=>e[r],enumerable:!(n=Ye(e,r))||n.enumerable});return s};var rt=s=>nt(G({},"__esModule",{value:!0}),s);var ft={};tt(ft,{BehaviorPlugin:()=>de,Client:()=>re,ErrorPlugin:()=>se,InteractionPlugin:()=>be,NetworkPlugin:()=>ue,OfflinePlugin:()=>ge,PerformancePlugin:()=>ae,RouterPlugin:()=>ye,SamplingPlugin:()=>me,Span:()=>C,Transaction:()=>L,addBreadcrumb:()=>Ve,captureEvent:()=>Oe,captureException:()=>De,captureMessage:()=>Be,clearAnonymousId:()=>He,createBaggageFromTransaction:()=>W,dbStatusToSpanStatus:()=>te,default:()=>gt,disable:()=>Ge,enable:()=>Je,flush:()=>Qe,getAnonymousId:()=>qe,getClient:()=>Me,getCurrentSpan:()=>Ae,getCurrentTransaction:()=>$e,httpStatusToSpanStatus:()=>_,init:()=>_e,parseBaggage:()=>Ie,serializeBaggage:()=>X,setAnonymousId:()=>Ne,setExtra:()=>We,setSpan:()=>je,setTag:()=>ze,setTags:()=>Xe,setUser:()=>Fe,startSpan:()=>Ke,startTransaction:()=>Ue,statusToSpanStatus:()=>V});function Ee(s){try{let e=s.match(/^(https?):\/\/([^@]+)@([^/]+)\/(.+)$/);if(!e)throw new Error("Invalid DSN format");let[,t,n,r,i]=e;return{protocol:t,publicKey:n,host:r,projectId:i}}catch(e){throw new Error(`Failed to parse DSN: ${e.message}`)}}function P(s){return`${s.protocol}://${s.host}/api/${s.projectId}/envelope/?sentry_key=${s.publicKey}`}function J(){return"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx".replace(/[x]/g,()=>(Math.random()*16|0).toString(16))}function p(){return Date.now()}function I(){return typeof crypto!="undefined"&&crypto.randomUUID?crypto.randomUUID().replace(/-/g,""):J()}function y(s){return s!==null&&typeof s=="object"&&!Array.isArray(s)}function M(s,e){return!e||e.length===0?!1:e.some(t=>typeof t=="string"?s.includes(t):t.test(s))}function it(s){let e=5381,t=s.length;for(;t;)e=e*33^s.charCodeAt(--t);return e>>>0}function Y(s){return it(s).toString(16)}function D(s,e,t=[]){let n=t.slice(0,3).map(i=>`${i.filename}:${i.lineno||0}`).join("|"),r=e.replace(/['"]?\d+['"]?/g,"").replace(/\s+/g," ").trim();return Y(`${s}:${r}:${n}`)}function B(s,e={}){if(!s)return[];let{captureNodeModules:t=!1,captureColumn:n=!0,relativePathOnly:r=!1,maxFrames:i}=e,o=[],a=s.split(` +`),c=typeof location!="undefined"?`${location.protocol}//${location.host}`:"";for(let f of a){let E=f.match(/^\s*at\s*(.+?)\s*\((.+?):(\d+):(\d+)\)\s*$/);if(E){let[,h,g,m,v]=E,S=g.includes("node_modules");if(!t&&S)continue;let b=g;r&&c&&g.startsWith(c)&&(b=g.substring(c.length)),o.push({filename:b,function:h,lineno:parseInt(m,10),colno:n?parseInt(v,10):void 0,in_app:!S})}else{let h=f.match(/^\s*at\s*(.+?)@(.+?):(\d+):(\d+)\s*$/);if(h){let[,m,v,S,b]=h,x=v.includes("node_modules");if(!t&&x)continue;let Te=v;r&&c&&v.startsWith(c)&&(Te=v.substring(c.length)),o.push({filename:Te,function:m||"",lineno:parseInt(S,10),colno:n?parseInt(b,10):void 0,in_app:!x});continue}let g=f.match(/^\s*at\s*(.+?):(\d+):(\d+)\s*$/);if(g){let[,m,v,S]=g,b=m.includes("node_modules");if(!t&&b)continue;let x=m;r&&c&&m.startsWith(c)&&(x=m.substring(c.length)),o.push({filename:x,lineno:parseInt(v,10),colno:n?parseInt(S,10):void 0,in_app:!b})}}}let d=o.reverse();return i!==void 0&&i>0?d.slice(0,i):d}var Z=!1;function O(s){Z=s}function u(s,e,t){if(!Z)return;let n=new Date().toISOString(),r=`[LightSDK][${s}]`;t!==void 0?console.log(`${r} ${n} ${e}`,t):console.log(`${r} ${n} ${e}`)}function R(s,e,t){if(!Z)return;let n=new Date().toISOString(),r=`[LightSDK][${s}][ERROR]`;t!==void 0?console.error(`${r} ${n} ${e}`,t):console.error(`${r} ${n} ${e}`)}var F="light_sentry_aid";function N(){if(typeof localStorage=="undefined")return null;try{let s=localStorage.getItem(F);return s||(s=I(),localStorage.setItem(F,s)),s}catch(s){return null}}function H(s){if(typeof localStorage=="undefined")return!1;try{return localStorage.setItem(F,s),!0}catch(e){return!1}}function we(){if(typeof localStorage=="undefined")return!1;try{return localStorage.removeItem(F),!0}catch(s){return!1}}function xe(s){return s.trackAnonymousUsers!==!1}function st(s){let e=[{name:"WeChat",pattern:/MicroMessenger\/([\d.]+)/i},{name:"QQ Browser",pattern:/QIBrowser\/([\d.]+)/i},{name:"UC Browser",pattern:/UCBrowser\/([\d.]+)/i},{name:"Edge",pattern:/Edg\/([\d.]+)/i},{name:"Edge",pattern:/Edge\/([\d.]+)/i},{name:"Opera",pattern:/OPR\/([\d.]+)/i},{name:"Opera",pattern:/Opera\/([\d.]+)/i},{name:"Firefox",pattern:/Firefox\/([\d.]+)/i},{name:"Safari",pattern:/Version\/([\d.]+).*Safari/i},{name:"Chrome",pattern:/Chrome\/([\d.]+)/i},{name:"IE",pattern:/MSIE ([\d.]+)/i},{name:"IE",pattern:/Trident.*rv:([\d.]+)/i}];for(let t of e){let n=s.match(t.pattern);if(n){let r=n[1]||"",i=r.split(".")[0]||"";return{name:t.name,version:r,major:i}}}return{name:"Unknown",version:"",major:""}}function ot(s){let e=[{name:"Windows 11",pattern:/Windows NT 10\.0.*Win64.*x64/i},{name:"Windows 10",pattern:/Windows NT 10\.0/i},{name:"Windows 8.1",pattern:/Windows NT 6\.3/i},{name:"Windows 8",pattern:/Windows NT 6\.2/i},{name:"Windows 7",pattern:/Windows NT 6\.1/i},{name:"Windows Vista",pattern:/Windows NT 6\.0/i},{name:"Windows XP",pattern:/Windows NT 5\.1/i},{name:"macOS",pattern:/Mac OS X ([\d_.]+)/i},{name:"iOS",pattern:/OS ([\d_.]+) like Mac OS X/i},{name:"Android",pattern:/Android ([\d.]+)/i},{name:"Android",pattern:/Android/i},{name:"Linux",pattern:/Linux/i}];for(let t of e){let n=s.match(t.pattern);if(n){let r=n[1]||"";return r&&(r=r.replace(/_/g,".")),{name:t.name,version:r}}}return{name:"Unknown",version:""}}function at(s){let e=/Mobile|Android|iPhone|iPod|BlackBerry|Windows Phone|Opera Mini/i.test(s),t=/Tablet|iPad|PlayBook|Kindle|Silk/i.test(s),n="desktop";t?n="tablet":e&&(n="mobile");let r="",i="",o=s.match(/iPhone/i),a=s.match(/iPad/i),c=s.match(/SM-([A-Z0-9]+)/i),d=s.match(/Pixel ([0-9A-Z]+)/i),f=s.match(/HUAWEI ([A-Z0-9]+)/i);return o?(r="Apple",i="iPhone"):a?(r="Apple",i="iPad"):c?(r="Samsung",i=c[1]):d?(r="Google",i=`Pixel ${d[1]}`):f&&(r="Huawei",i=f[1]),{type:n,vendor:r,model:i}}function ke(){let s=typeof navigator!="undefined"?navigator.userAgent:"",e=st(s),t=ot(s),n=at(s);return{browser:e,os:t,device:n,url:typeof location!="undefined"?location.href:"",referrer:typeof document!="undefined"?document.referrer:"",title:typeof document!="undefined"?document.title:"",language:typeof navigator!="undefined"?navigator.language:"",user_agent:s,screen_width:typeof screen!="undefined"?screen.width:0,screen_height:typeof screen!="undefined"?screen.height:0,viewport_width:typeof window!="undefined"?window.innerWidth:0,viewport_height:typeof window!="undefined"?window.innerHeight:0}}function w(){return typeof location!="undefined"?location.href:""}function Ce(){return typeof document!="undefined"?document.referrer:""}function k(s){if(!s)return s;if(/^\s*javascript:/i.test(s))return"javascript:[filtered]";try{let e=new URL(s),t=["password","passwd","pwd","token","access_token","refresh_token","api_key","apikey","key","secret","private_key","code","auth","id_token","idToken","session","session_id"],n=e.searchParams,r=!1;for(let i of Array.from(n.keys())){let o=i.toLowerCase().replace(/[-_]/g,"_");t.some(a=>o.includes(a))&&(n.set(i,"[Filtered]"),r=!0)}if(e.hash&&e.hash.length>1){let i=e.hash.substring(1);if(i.includes("=")){let o=new URLSearchParams(i),a=!1;for(let c of Array.from(o.keys())){let d=c.toLowerCase().replace(/[-_]/g,"_");t.some(f=>d.includes(f))&&(o.set(c,"[Filtered]"),a=!0)}a&&(e.hash="#"+o.toString(),r=!0)}}return r?e.toString():s}catch(e){return s}}function q(s,e=[]){return!e||e.length===0?!1:e.some(t=>{if(typeof t=="string"){if(t.includes("*")){let n=t.replace(/[.+?^${}()|[\]\\]/g,"\\$&").replace(/\*/g,".*");return new RegExp(n).test(s)}return s.includes(t)}return t.test(s)})}var ct={Chrome:"c",Safari:"s",Firefox:"f",Edge:"e",Opera:"o",IE:"i",WeChat:"w","QQ Browser":"q","UC Browser":"u","Mobile Chrome":"cm","Mobile Safari":"sm"},ut={"Windows 11":"w11","Windows 10":"w10","Windows 8.1":"w81","Windows 8":"w8","Windows 7":"w7","Windows Vista":"wv","Windows XP":"wxp",macOS:"m",iOS:"i",Android:"a",Linux:"l"};function ee(){let s=ke(),e=ct[s.browser.name]||s.browser.name.toLowerCase(),t=ut[s.os.name]||s.os.name.toLowerCase();return{browser:{name:e,version:s.browser.major},os:{name:t,version:s.os.version.split(".")[0]},device:{type:s.device.type,brand:s.device.vendor||void 0,model:s.device.model||void 0}}}function Re(){let s=ke(),e=`${s.browser.name}|${s.browser.major}|${s.os.name}|${s.os.version.split(".")[0]}|${s.device.type}|${s.device.vendor}|${s.device.model}|${s.language}`;return Y(e).substring(0,16)}var lt={enabled:!0,sampleRate:1,maxQueueSize:100,flushInterval:5e3,maxRetries:3,retryDelay:1e3,environment:"production",contextLevel:{fatal:{maxStackFrames:5,maxBreadcrumbs:20},error:{maxStackFrames:5,maxBreadcrumbs:10},warning:{maxStackFrames:3,maxBreadcrumbs:5},info:{maxStackFrames:0,maxBreadcrumbs:0},debug:{maxStackFrames:0,maxBreadcrumbs:0}}},U=class{constructor(e){this.contexts=null;this.contextId=null;this.contextReported=!1;this.config={...lt,...e}}markContextReported(){this.contextReported=!0}get(e){return this.config[e]}getAll(){return{...this.config}}set(e,t){this.config[e]=t}setUser(e){this.config.user=e||void 0}setTags(e){this.config.tags={...this.config.tags||{},...e}}setTag(e,t){this.config.tags||(this.config.tags={}),this.config.tags[e]=t}setExtra(e,t){this.config.extra||(this.config.extra={}),this.config.extra[e]=t}isIgnoredError(e){return M(e,this.config.ignoreErrors||[])}shouldSample(){var t;let e=(t=this.config.sampleRate)!=null?t:1;return e>=1?!0:e<=0?!1:Math.random()({...g})):void 0}:void 0}}if(e.breadcrumbs&&(n.breadcrumbs=e.breadcrumbs.map(h=>({...h}))),e.user&&(n.user={...e.user}),e.contexts&&(n.contexts={...e.contexts}),this.config.release&&(n.release=this.config.release),this.config.environment&&(n.environment=this.config.environment),n.platform="javascript",this.config.user&&(n.user=this.config.user),this.config.tags&&(n.tags={...this.config.tags,...e.tags||{}}),n.request?n.request.url||(n.request.url=w()):n.request={url:w(),referrer:Ce()},this.contextId||(this.contextId=Re()),n.context_id=this.contextId,!(((o=this.config.user)==null?void 0:o.id)||((a=e.user)==null?void 0:a.id))&&xe(this.config)){let h=N();h&&(n.anonymousId=h)}let i=this.applyContextLevel(n);return t&&!this.contextReported&&(this.contexts||(this.contexts=ee()),i.contexts=this.contexts,i.env={b:(c=this.contexts.browser)==null?void 0:c.name,bv:(d=this.contexts.browser)==null?void 0:d.version,os:(f=this.contexts.os)==null?void 0:f.name,osv:(E=this.contexts.os)==null?void 0:E.version}),i}applyContextLevel(e){let t=this.config.contextLevel;if(!t)return e;let n=e.level||"error",r=t[n]||t.error,i={...e};if("exception"in e&&e.exception&&typeof e.exception=="object"){let o=e.exception;if(o.stacktrace&&typeof o.stacktrace=="object"){let a=o.stacktrace;Array.isArray(a.frames)&&(r.maxStackFrames===0?delete i.exception:i.exception={...o,stacktrace:{...a,frames:a.frames.slice(0,r.maxStackFrames)}})}}return e.breadcrumbs&&Array.isArray(e.breadcrumbs)&&(r.maxBreadcrumbs===0?delete i.breadcrumbs:i.breadcrumbs=e.breadcrumbs.slice(-r.maxBreadcrumbs)),i}};var $=class{constructor(){this.handlers=new Map}on(e,t){this.handlers.has(e)||this.handlers.set(e,[]),this.handlers.get(e).push(t)}off(e,t){let n=this.handlers.get(e);if(n){let r=n.indexOf(t);r>-1&&n.splice(r,1)}}emit(e,...t){let n=this.handlers.get(e);if(n)for(let r of n)try{r(...t)}catch(i){console.error("[LightSDK] EventBus handler error:",i)}}once(e,t){let n=(...r)=>{this.off(e,n),t(...r)};this.on(e,n)}destroy(){this.handlers.clear()}};var A=class{constructor(e,t,n,r,i){this.queue=[];this.timer=null;this.lastFlushTime=0;this.isFlushing=!1;this.dedupeMap=new Map;this.pendingCounts=new Map;this.errorRateWindow={};this.paused=!1;this.pauseTimer=null;this.maxSize=e,this.flushInterval=t,this.eventBus=n,this.flushCallback=r,this.syncFlushCallback=i}start(){this.startTimer(),this.setupVisibilityListener()}startTimer(){this.timer||(this.timer=setInterval(()=>{(this.queue.length>0||this.pendingCounts.size>0)&&this.flush()},this.flushInterval))}setupVisibilityListener(){this.onVisibilityChange=()=>{document.hidden&&(this.queue.length>0||this.pendingCounts.size>0)&&this.flushSync()},typeof document!="undefined"&&document.addEventListener("visibilitychange",this.onVisibilityChange),this.onBeforeUnload=()=>{(this.queue.length>0||this.pendingCounts.size>0)&&this.flushSync()},this.onPagehide=()=>{(this.queue.length>0||this.pendingCounts.size>0)&&this.flushSync()},typeof window!="undefined"&&(window.addEventListener("beforeunload",this.onBeforeUnload),window.addEventListener("pagehide",this.onPagehide))}checkInfiniteLoop(e){let t=p(),n=t-1e3;this.errorRateWindow[e]||(this.errorRateWindow[e]=[]);let r=this.errorRateWindow[e];for(r.push(t);r.length>0&&r[0]10?(this.paused||(console.warn("[LightSDK] Infinite loop detected, pausing SDK for 60s",{fingerprint:e,count:r.length}),this.eventBus.emit("error",new Error("Infinite loop detected")),this.paused=!0,this.pauseTimer&&clearTimeout(this.pauseTimer),this.pauseTimer=setTimeout(()=>{this.paused=!1,this.errorRateWindow={},console.info("[LightSDK] Resumed after infinite loop detection")},6e4)),!0):!1}enqueue(e){if(u("EventQueue","enqueue called",{type:e.type,level:e.level,message:"message"in e?e.message:void 0}),this.paused){u("EventQueue","enqueue skipped: queue paused (infinite loop detected)");return}this.cleanupExpiredDedupeEntries();let t=this.getDedupeKey(e);if(t){if(this.checkInfiniteLoop(t)){u("EventQueue","enqueue skipped: infinite loop detected",{fingerprint:t});return}let n=p(),r=this.dedupeMap.get(t);if(r)if(n-r.lastTime<6e4){if(r.count>=3){if(!this.pendingCounts.has(t))this.pendingCounts.set(t,{count:1,ts_start:n,ts_end:n});else{let i=this.pendingCounts.get(t);i.count++,i.ts_end=n}u("EventQueue","enqueue skipped: deduped (count >= 3)",{fingerprint:t,count:r.count});return}r.count++,r.lastTime=n,u("EventQueue","Dedup count incremented",{fingerprint:t,count:r.count})}else this.dedupeMap.set(t,{count:1,lastTime:n,firstReported:!0}),this.pendingCounts.delete(t),u("EventQueue","Dedup entry reset (expired)",{fingerprint:t});else this.dedupeMap.set(t,{count:1,lastTime:n,firstReported:!1}),u("EventQueue","New dedup entry created",{fingerprint:t})}this.queue.push(e),u("EventQueue","Event added to queue",{queueSize:this.queue.length}),this.eventBus.emit("event",e),this.queue.length>=this.maxSize&&(u("EventQueue","Queue reached maxSize, triggering flush",{maxSize:this.maxSize}),this.flush())}cleanupExpiredDedupeEntries(){if(Math.random()>.1)return;let e=p(),t=6e4;for(let[n,r]of this.dedupeMap)e-r.lastTime>t&&this.dedupeMap.delete(n)}buildCountEvents(){let e=[];for(let[t,n]of this.pendingCounts.entries()){let r={type:"count",fingerprint:t,count:n.count,ts_start:n.ts_start,ts_end:n.ts_end,timestamp:p(),level:"info"};e.push(r)}return e}getDedupeKey(e){if(e.type==="error"){let t=e;return t.fingerprint||t.message}return null}async flush(){if(u("EventQueue","flush called",{queueSize:this.queue.length,pendingCounts:this.pendingCounts.size,isFlushing:this.isFlushing}),this.queue.length===0&&this.pendingCounts.size===0){u("EventQueue","flush skipped: queue is empty");return}if(this.isFlushing){u("EventQueue","flush skipped: already flushing");return}this.isFlushing=!0;let e=this.queue.splice(0,this.queue.length),t=this.buildCountEvents(),n=[...e,...t];u("EventQueue","flush events to callback",{total:n.length,events:e.length,countEvents:t.length}),this.lastFlushTime=p(),this.eventBus.emit("report",n);try{await this.flushCallback(n),this.pendingCounts.clear(),u("EventQueue","flush completed successfully"),this.eventBus.emit("reported",n)}catch(r){throw u("EventQueue","flush failed, returning events to queue",{error:r instanceof Error?r.message:String(r)}),e.forEach(i=>this.queue.unshift(i)),r}finally{this.isFlushing=!1}}flushSync(){if(this.queue.length===0&&this.pendingCounts.size===0)return;let e=this.queue.splice(0,this.queue.length),t=new Map(this.pendingCounts),n=this.buildCountEvents(),r=[...e,...n];this.lastFlushTime=p(),this.eventBus.emit("report",r);try{this.syncFlushCallback(r),this.pendingCounts.clear(),this.eventBus.emit("reported",r)}catch(i){console.error("[LightSDK] Sync flush failed",i),e.forEach(o=>this.queue.unshift(o));for(let[o,a]of t)this.pendingCounts.has(o)||this.pendingCounts.set(o,a)}}size(){return this.queue.length}destroy(){this.timer&&(clearInterval(this.timer),this.timer=null),this.pauseTimer&&(clearTimeout(this.pauseTimer),this.pauseTimer=null),typeof document!="undefined"&&this.onVisibilityChange&&document.removeEventListener("visibilitychange",this.onVisibilityChange),typeof window!="undefined"&&(this.onBeforeUnload&&window.removeEventListener("beforeunload",this.onBeforeUnload),this.onPagehide&&window.removeEventListener("pagehide",this.onPagehide)),this.queue=[],this.dedupeMap.clear(),this.pendingCounts.clear(),this.errorRateWindow={}}};var Le={event_id:"eid",timestamp:"ts",start_timestamp:"sts",type:"t",level:"l",message:"m",platform:"p",release:"r",environment:"e",fingerprint:"fp",context_id:"cid",user:"u",tags:"tg",exception:"ex",request:"req",contexts:"ctx",breadcrumbs:"bc",transaction:"tx",duration:"d",spans:"sp",extra:"xt"},Bt=Object.fromEntries(Object.entries(Le).map(([s,e])=>[e,s]));function Pe(s){if(!s||typeof s!="object")return s;let e={};for(let[t,n]of Object.entries(s)){let r=Le[t]||t;e[r]=n}return e}var j=class{constructor(e,t,n){this.useShortFields=!0;this.dsn=e,this.maxRetries=t,this.retryDelay=n}async report(e){if(u("Reporter","report called",{eventCount:e.length}),e.length===0){u("Reporter","report skipped: empty events");return}let t=this.buildEnvelope(e),n=P(this.dsn);u("Reporter","Envelope built",{envelopeSize:t.length,url:n});let r=0;for(;r<=this.maxRetries;)try{u("Reporter",`Sending request (attempt ${r+1}/${this.maxRetries+1})`),await this.send(t,!1),u("Reporter","Request succeeded");return}catch(i){let o=i.status;if(R("Reporter",`Request failed (attempt ${r+1})`,{status:o,error:i}),o&&o>=400&&o<500)throw i;if(r++,r>this.maxRetries)throw R("Reporter","All retries exhausted"),i;let a=Math.min(this.retryDelay*Math.pow(2,r-1),5e3);u("Reporter",`Retrying in ${a}ms`),await this.delay(a)}}reportSync(e){if(e.length===0)return;let t=this.buildEnvelope(e);try{if(this.sendSync(t))return}catch(n){}this.sendViaImage(t)}buildEnvelope(e){let t=this.extractSharedMeta(e),n={event_id:J(),sent_at:new Date().toISOString(),meta:t};this.useShortFields&&(n._sf=1);let r=this.applyRelativeTimestamps(e,n),o=[JSON.stringify(n)];for(let a of r){let c=this.stripSharedFields(a,t);this.useShortFields&&(c=Pe(c));let d=JSON.stringify(c),f=JSON.stringify({type:this.getEnvelopeType(a),length:d.length});o.push(f,d)}return o.join(` +`)}applyRelativeTimestamps(e,t){if(e.length<=1)return e;let n=[],r=e[0].timestamp?new Date(e[0].timestamp).getTime():Date.now();t._rt=1,t._bt=r;for(let i=0;io.release===t.release)&&(n.release=t.release),t.environment&&e.every(o=>o.environment===t.environment)&&(n.environment=t.environment),t.user&&e.every(o=>JSON.stringify(o.user)===JSON.stringify(t.user))&&(n.user=t.user);let r=t.env;return r&&(n.env=r),n}stripSharedFields(e,t){let n={...e};return t.release&&n.release===t.release&&delete n.release,t.environment&&n.environment===t.environment&&delete n.environment,t.user&&JSON.stringify(n.user)===JSON.stringify(t.user)&&delete n.user,t.env&&delete n.env,n}getEnvelopeType(e){switch(e.type){case"error":return"event";default:return e.type}}async send(e,t=!1){let n=P(this.dsn);if(navigator.sendBeacon)try{let r=new Blob([e],{type:"application/x-sentry-envelope"});if(navigator.sendBeacon(n,r))return}catch(r){}if(typeof fetch=="function")try{let r=new AbortController,i=setTimeout(()=>r.abort(),1e4),o=await fetch(n,{method:"POST",body:e,headers:{"Content-Type":"application/x-sentry-envelope"},keepalive:!0,signal:r.signal});if(clearTimeout(i),o.ok)return;let a=new Error(`HTTP ${o.status}`);throw a.status=o.status,a}catch(r){throw r}if(typeof XMLHttpRequest!="undefined")return new Promise((r,i)=>{let o=new XMLHttpRequest;o.open("POST",n,!t),o.setRequestHeader("Content-Type","application/x-sentry-envelope"),o.timeout=1e4,o.onload=()=>{if(o.status>=200&&o.status<300)r();else{let a=new Error(`HTTP ${o.status}`);a.status=o.status,i(a)}},o.onerror=()=>i(new Error("Network error")),o.ontimeout=()=>i(new Error("Request timeout")),o.send(e)});throw new Error("No transport available")}sendSync(e){let t=P(this.dsn);if(navigator.sendBeacon)try{let n=new Blob([e],{type:"application/x-sentry-envelope"});return navigator.sendBeacon(t,n)}catch(n){return!1}if(typeof XMLHttpRequest!="undefined")try{let n=new XMLHttpRequest;return n.open("POST",t,!1),n.setRequestHeader("Content-Type","application/x-sentry-envelope"),n.send(e),n.status>=200&&n.status<300}catch(n){return!1}return!1}sendViaImage(e){try{let t=P(this.dsn),n=new Image,r=encodeURIComponent(btoa(e)),i=t.includes("?")?"&":"?";return n.src=t+i+"sentry_data="+r.substring(0,2e3),!0}catch(t){return!1}}delay(e){return new Promise(t=>setTimeout(t,e))}};var K=class{constructor(e){this.plugins=new Map;this.client=e}add(e){if(!this.plugins.has(e.name)){this.plugins.set(e.name,e);try{e.setup(this.client)}catch(t){console.error(`[LightSDK] Plugin "${e.name}" setup error:`,t)}}}remove(e){let t=this.plugins.get(e);if(t){if(t.destroy)try{t.destroy()}catch(n){console.error(`[LightSDK] Plugin "${e}" destroy error:`,n)}this.plugins.delete(e)}}get(e){return this.plugins.get(e)}has(e){return this.plugins.has(e)}applyBeforeReport(e){let t=e;for(let n of this.plugins.values())if(n.beforeReport)try{let r=n.beforeReport(t);if(r===null)return null;t=r}catch(r){console.error(`[LightSDK] Plugin "${n.name}" beforeReport error:`,r)}return t}applyAfterReport(e){for(let t of this.plugins.values())if(t.afterReport)try{t.afterReport(e)}catch(n){console.error(`[LightSDK] Plugin "${t.name}" afterReport error:`,n)}}destroy(){for(let e of this.plugins.values())if(e.destroy)try{e.destroy()}catch(t){console.error(`[LightSDK] Plugin "${e.name}" destroy error:`,t)}this.plugins.clear()}};var z="sentry-";function X(s){let e=[];for(let[n,r]of Object.entries(s)){if(r==null||r==="")continue;let i=n.startsWith(z)?n:`${z}${n}`;e.push(`${i}=${encodeURIComponent(String(r))}`)}let t=e.join(",");if(t.length>8192){t=t.substring(0,8192);let n=t.lastIndexOf(",");n>0&&(t=t.substring(0,n))}return t}function Ie(s){let e={};if(!s)return e;let t=s.split(",");for(let n of t){let r=n.indexOf("=");if(r===-1)continue;let i=n.substring(0,r).trim(),o=decodeURIComponent(n.substring(r+1).trim()),a=i;i.startsWith(z)&&(a=i.substring(z.length)),a&&(e[a]=o)}return e}function W(s,e){let t={trace_id:s};return e!=null&&e.dsnPublicKey&&(t.public_key=e.dsnPublicKey),(e==null?void 0:e.sampled)!==void 0&&(t.sampled=e.sampled?"true":"false"),(e==null?void 0:e.sampleRate)!==void 0&&(t.sample_rate=String(e.sampleRate)),e!=null&&e.user&&(e.user.id&&(t.user_id=e.user.id),e.user.segment&&(t.user_segment=e.user.segment)),e!=null&&e.release&&(t.release=e.release),e!=null&&e.environment&&(t.environment=e.environment),t}function dt(){return I().replace(/-/g,"")}function pt(){return I().replace(/-/g,"").substring(0,16)}function _(s){return s>=200&&s<300?"ok":s===400?"invalid_argument":s===401?"unauthenticated":s===403?"permission_denied":s===404?"not_found":s===409?"already_exists":s===429?"resource_exhausted":s>=400&&s<500?"invalid_argument":s>=500&&s<600?"internal_error":"unknown_error"}function te(s){if(s==null||s==="")return"unknown_error";let e=typeof s=="string"?parseInt(s,10):s;return e===0||e===1?"ok":e>=10&&e<20?"invalid_argument":e>=20&&e<30?"not_found":e>=30&&e<40?"already_exists":e>=50?"internal_error":"unknown_error"}function V(s,e){if(s===void 0)return"unknown_error";if(typeof s=="string"){let t=s.toLowerCase();if(t==="ok"||t==="success")return"ok";if(t==="cancelled"||t==="canceled")return"cancelled";if(t==="deadline_exceeded")return"deadline_exceeded";if(t==="not_found")return"not_found";if(t==="already_exists")return"already_exists";if(t==="permission_denied")return"permission_denied";if(t==="resource_exhausted")return"resource_exhausted";if(t==="failed_precondition")return"failed_precondition";if(t==="invalid_argument")return"invalid_argument";if(t==="unauthenticated")return"unauthenticated";if(t==="internal_error")return"internal_error";let n=parseInt(s,10);return isNaN(n)?"unknown_error":V(n,e)}if(typeof s=="number"){if(s>=200&&s<600)return _(s);if(e!=null&&e.startsWith("db"))return te(s);if(s===0)return"ok";if(s>0)return"unknown_error"}return"unknown_error"}var C=class s{constructor(e,t,n){this.tags={};this.data={};this._isFinished=!1;this.traceId=e.traceId||dt(),this.spanId=e.spanId||pt(),this.parentSpanId=e.parentSpanId,this.op=e.op,this.description=e.description,this.status=e.status,this.tags={...e.tags},this.data={...e.data},this.startTimestamp=e.startTimestamp||p(),this.transaction=t,this._client=n}setTag(e,t){return this.tags[e]=t,this}setData(e,t){return this.data[e]=t,this}setStatus(e){return this.status=e,this}setHttpStatus(e){return this.setStatus(_(e)),this.setTag("http.status_code",String(e)),this}setStatusFromResponse(e,t){let n=V(e,this.op);return this.setStatus(n),t&&e!==void 0&&this.setTag(t,String(e)),this}startChild(e={}){let t=this.transaction,n=(t==null?void 0:t.sampled)!==!1,r=new s({...e,traceId:this.traceId,parentSpanId:this.spanId},t,this._client);return t&&n&&t._addSpan(r),r}finish(e){var t;if(!this._isFinished&&(this._isFinished=!0,this.endTimestamp=e||p(),this._client)){let n=this._client;(t=n.tracingManager)!=null&&t.onSpanFinished&&n.tracingManager.onSpanFinished(this)}}toTraceparent(){var n;let e=(n=this.transaction)==null?void 0:n.sampled,t=e===void 0?"":e?"1":"0";return t?`${this.traceId}-${this.spanId}-${t}`:`${this.traceId}-${this.spanId}`}toJSON(){return{trace_id:this.traceId,span_id:this.spanId,parent_span_id:this.parentSpanId,op:this.op,description:this.description,status:this.status,tags:Object.keys(this.tags).length>0?{...this.tags}:void 0,data:Object.keys(this.data).length>0?{...this.data}:void 0,start_timestamp:this.startTimestamp,timestamp:this.endTimestamp||this.startTimestamp}}},L=class extends C{constructor(t,n,r,i,o,a){super(t,void 0,n);this.spans=[];this.maxSpans=1e3;this._droppedSpans=0;this.name=t.name,this.type=t.type,this.sampled=t.sampled,this.transaction=this,this._dsnPublicKey=r,this._release=i,this._environment=o,a!==void 0&&(this.maxSpans=a)}_addSpan(t){if(this.spans.length>=this.maxSpans){this._droppedSpans++;return}this.spans.push(t)}_ensureBaggage(){return this._baggage||(this._baggage=W(this.traceId,{dsnPublicKey:this._dsnPublicKey,sampled:this.sampled,release:this._release,environment:this._environment})),this._baggage}setBaggage(t,n){let r=this._ensureBaggage();return r[t]=n,this}setUserBaggage(t,n){let r=this._ensureBaggage();return t!==void 0?r.user_id=t:delete r.user_id,n!==void 0?r.user_segment=n:delete r.user_segment,this}toBaggage(){let t=this._ensureBaggage();return X(t)}getBaggage(){return this._baggage}finish(t){var n;if(!this._isFinished){if(super.finish(t),this._client&&this.sampled){let r=this.toEvent();this._client.captureEvent(r)}if(this._client){let r=this._client;(n=r.tracingManager)!=null&&n.onTransactionFinished&&r.tracingManager.onTransactionFinished(this)}}}_getSource(){switch(this.type){case"pageload":return"url";case"navigation":return"route";case"user-interaction":return"ui";default:return"custom"}}toEvent(){let t=this.toJSON(),n={...t.data},r=n.measurements;return delete n.measurements,{type:"transaction",transaction:this.name,transaction_info:{source:this._getSource()},level:"info",timestamp:t.timestamp,start_timestamp:t.start_timestamp,spans:this.spans.map(i=>i.toJSON()),contexts:{trace:{trace_id:this.traceId,span_id:this.spanId,parent_span_id:this.parentSpanId,op:this.op,status:this.status}},tags:t.tags,extra:Object.keys(n).length>0?n:void 0,measurements:r,platform:"javascript"}}toJSON(){return{...super.toJSON(),transaction:this.name,type:this.type,spans:this.spans.map(n=>n.toJSON()),sampled:this.sampled}}};var Q=class{constructor(e,t,n){this.currentTransaction=null;this.spanStack=[];this.config=e,this._client=t,this.dsnPublicKey=n}updateConfig(e){var t,n;this.config=e,this.currentTransaction&&this.currentTransaction.setUserBaggage((t=e.user)==null?void 0:t.id,(n=e.user)==null?void 0:n.segment)}shouldSample(e,t){var i;let n=this.config.tracesSampler;if(n){let o={...e,parentSampled:t},a=n(o);if(typeof a=="boolean")return a;let c=Math.max(0,Math.min(1,a));return c===0?!1:c===1?!0:Math.random()=1?!0:r<=0?!1:Math.random()0?this.spanStack[this.spanStack.length-1]:null}setCurrentSpan(e){e===null?this.spanStack.length>1&&this.spanStack.pop():this.spanStack.push(e)}startSpan(e){let t=this.getCurrentSpan();if(!t&&!e.traceId)return u("TracingManager","startSpan skipped: no active span and no traceId"),null;let n;return t?n=t.startChild(e):(n=new C({...e,parentSpanId:e.parentSpanId}),this.currentTransaction&&(this.currentTransaction.sampled!==!1&&this.currentTransaction._addSpan(n),n.transaction=this.currentTransaction)),this.spanStack.push(n),u("TracingManager","Span started",{op:n.op,description:n.description,spanId:n.spanId,parentSpanId:n.parentSpanId,stackDepth:this.spanStack.length}),n}onSpanFinished(e){let t=this.spanStack.lastIndexOf(e);t!==-1&&this.spanStack.splice(t,1),this.spanStack.length===0&&this.currentTransaction&&(this.spanStack=[this.currentTransaction]),u("TracingManager","Span finished",{op:e.op,description:e.description,spanId:e.spanId,stackDepth:this.spanStack.length})}onTransactionFinished(e){this.currentTransaction===e&&(this.currentTransaction=null,this.spanStack=[]),u("TracingManager","Transaction finished",{name:e.name,traceId:e.traceId,spanCount:e.spans.length,sampled:e.sampled})}finishSpan(e){e.finish()}finishTransaction(e){e.finish()}destroy(){if(this.currentTransaction)try{this.currentTransaction.setStatus("aborted"),this.currentTransaction.finish()}catch(e){}this.currentTransaction=null,this.spanStack=[]}};var ne=class{constructor(e){this.breadcrumbs=[];this.enabled=!0;var t,n,r,i;if(!e.dsn)throw new Error("DSN is required");O(e.debug===!0),u("Client","Initializing SDK",{dsn:e.dsn,debug:e.debug,enabled:e.enabled!==!1}),this.dsn=Ee(e.dsn),this.configManager=new U(e),this.eventBus=new $,this.reporter=new j(this.dsn,(t=this.configManager.get("maxRetries"))!=null?t:3,(n=this.configManager.get("retryDelay"))!=null?n:1e3),this.pluginManager=new K(this),this.tracingManager=new Q(e,this,this.dsn.publicKey),this.queue=new A((r=this.configManager.get("maxQueueSize"))!=null?r:100,(i=this.configManager.get("flushInterval"))!=null?i:5e3,this.eventBus,async o=>this.flushEvents(o),o=>this.syncFlushEvents(o)),this.enabled=this.configManager.get("enabled")!==!1,u("Client","SDK initialized",{enabled:this.enabled})}get maxBreadcrumbs(){var e;return(e=this.configManager.get("maxBreadcrumbs"))!=null?e:20}get config(){return this.configManager.getAll()}init(){this.enabled&&(this.queue.start(),this.emit("ready"))}async flushEvents(e){u("Client","flushEvents start",{eventCount:e.length});let t=[];for(let i of e){let o=this.pluginManager.applyBeforeReport(i);o?t.push(o):u("Client","Event filtered by beforeReport plugin",{type:i.type,message:"message"in i?i.message:void 0})}if(t.length===0){u("Client","flushEvents: all events filtered by beforeReport");return}let n=!0,r=[];for(let i of t){let o=this.configManager.applyToEvent(i,n);n=!1;let a=this.configManager.get("beforeSend"),c=a?a(o):o;if(!c){u("Client","Event filtered by beforeSend",{type:i.type});continue}r.push(c)}if(r.length===0){u("Client","flushEvents: all events filtered by beforeSend");return}u("Client","Reporting events",{count:r.length}),await this.reporter.report(r),u("Client","Report completed successfully"),this.configManager.markContextReported();for(let i of r)this.pluginManager.applyAfterReport(i)}syncFlushEvents(e){let t=[];for(let i of e){let o=this.pluginManager.applyBeforeReport(i);o&&t.push(o)}if(t.length===0)return;let n=!0,r=[];for(let i of t){let o=this.configManager.applyToEvent(i,n);n=!1;let a=this.configManager.get("beforeSend"),c=a?a(o):o;c&&r.push(c)}r.length!==0&&(this.reporter.reportSync(r),this.configManager.markContextReported())}on(e,t){this.eventBus.on(e,t)}off(e,t){this.eventBus.off(e,t)}emit(e,...t){this.eventBus.emit(e,...t)}captureException(e){if(u("Client","captureException called",{error:e instanceof Error?e.message:String(e)}),!this.enabled){u("Client","captureException skipped: SDK disabled");return}let t=this.buildErrorEvent(e);if(u("Client","Error event built",{type:t.type,message:t.message,fingerprint:t.fingerprint}),this.configManager.isIgnoredError(t.message)){u("Client","captureException skipped: error ignored by ignoreErrors");return}this.attachTraceContext(t),t.breadcrumbs=[...this.breadcrumbs],u("Client","Enqueue error event",{breadcrumbs:this.breadcrumbs.length}),this.queue.enqueue(t)}captureMessage(e,t="info"){if(!this.enabled)return;let n={type:"error",level:t,message:e,timestamp:p(),breadcrumbs:[...this.breadcrumbs]};this.configManager.isIgnoredError(e)||(this.attachTraceContext(n),this.queue.enqueue(n))}captureEvent(e){if(!this.enabled)return;let t={timestamp:p(),level:"info",breadcrumbs:[...this.breadcrumbs],...e};this.attachTraceContext(t),this.queue.enqueue(t)}attachTraceContext(e){let t=this.tracingManager.getCurrentSpan(),n=this.tracingManager.getCurrentTransaction();if(t||n){let r=(t==null?void 0:t.traceId)||(n==null?void 0:n.traceId),i=(t==null?void 0:t.spanId)||(n==null?void 0:n.spanId),o=t==null?void 0:t.parentSpanId,a=(t==null?void 0:t.op)||(n==null?void 0:n.op),c=(t==null?void 0:t.status)||(n==null?void 0:n.status);e.contexts={...e.contexts,trace:{trace_id:r||"",span_id:i||"",parent_span_id:o,op:a,status:c}}}}buildErrorEvent(e){let t=p();if(e instanceof Error){let r=B(e.stack,{maxFrames:5}),i=D(e.name,e.message,r);return{type:"error",level:"error",message:e.message,timestamp:t,exception:{type:e.name,value:e.message,stacktrace:{frames:r}},fingerprint:i}}return{type:"error",level:"error",message:String(e),timestamp:t}}setUser(e){this.configManager.setUser(e),this.tracingManager.updateConfig(this.configManager.getAll())}setAnonymousId(e){H(e)}startTransaction(e){if(!this.enabled)return null;let t=this.tracingManager.startTransaction(e);return t&&t.sampled&&u("Client","Transaction started and sampled",{name:t.name,traceId:t.traceId}),t}getCurrentTransaction(){return this.tracingManager.getCurrentTransaction()}getCurrentSpan(){return this.tracingManager.getCurrentSpan()}setSpan(e){this.tracingManager.setCurrentSpan(e)}startSpan(e){return this.enabled?this.tracingManager.startSpan(e):null}setTag(e,t){this.configManager.setTag(e,t)}setTags(e){this.configManager.setTags(e)}setExtra(e,t){this.configManager.setExtra(e,t)}addBreadcrumb(e){let t={...e,timestamp:p()};this.breadcrumbs.push(t),this.breadcrumbs.length>this.maxBreadcrumbs&&this.breadcrumbs.shift()}async flush(){await this.queue.flush()}disable(){this.enabled=!1}enable(){this.enabled=!0}use(e){this.pluginManager.add(e)}destroy(){this.pluginManager.destroy(),this.tracingManager.destroy(),this.queue.destroy(),this.eventBus.destroy(),this.breadcrumbs=[]}},re=ne;var ie=class{constructor(){this.name="error";this.version="1.0.0";this.config={maxStackFrames:5,captureNodeModules:!1,captureColumn:!0,relativePathOnly:!1,resourceSampleRate:.1}}setup(e){this.client=e,this.loadConfig(),this.setupGlobalError(),this.setupUnhandledRejection(),this.setupResourceError()}loadConfig(){let e=this.client.config;e&&y(e.error)&&(this.config={...this.config,...e.error}),e.ignoreErrors&&(this.config.ignoreErrors=[...this.config.ignoreErrors||[],...e.ignoreErrors]),e.ignoreUrls&&(this.config.ignoreUrls=[...this.config.ignoreUrls||[],...e.ignoreUrls]),e.includePaths&&(this.config.includePaths=[...this.config.includePaths||[],...e.includePaths])}shouldIgnoreError(e){return e?M(e,this.config.ignoreErrors||[]):!1}shouldIgnoreScriptUrl(e){return q(e,this.config.ignoreUrls||[])}shouldIncludePath(e){let t=this.config.includePaths||[];return t.length===0?!0:e.some(n=>t.some(r=>{var i;return typeof r=="string"?(i=n.filename)==null?void 0:i.includes(r):r.test(n.filename||"")}))}shouldSample(){var t;let e=(t=this.config.sampleRate)!=null?t:1;return e>=1?!0:e<=0?!1:Math.random()=1?!0:e<=0?!1:Math.random(){try{if(this.originalOnError&&this.originalOnError.call(window,e,t,n,r,i),t&&this.shouldIgnoreScriptUrl(t))return!1;let o=this.buildErrorEvent(i||e,t,n,r);o&&this.client.captureEvent(o)}catch(o){R("ErrorPlugin","Global error handler error",o)}return!1})}setupUnhandledRejection(){typeof window!="undefined"&&(this.onUnhandledRejection=e=>{try{let t=e.reason,n=this.extractUrlFromReason(t);if(n&&this.shouldIgnoreScriptUrl(n))return;let r=this.buildErrorEvent(t);r&&(r.type==="error"&&(r.tags={...r.tags||{},unhandled:"true",promise:"true"}),this.client.captureEvent(r))}catch(t){R("ErrorPlugin","Unhandledrejection handler error",t)}},window.addEventListener("unhandledrejection",this.onUnhandledRejection))}extractUrlFromReason(e){if(e instanceof Error&&e.stack){let t=e.stack.match(/at\s+(?:.+?\s+)?\((https?:\/\/[^:]+):\d+:\d+\)/);if(t)return t[1];let n=e.stack.match(/(https?:\/\/[^\s)]+):\d+:\d+/);if(n)return n[1]}return null}setupResourceError(){typeof window!="undefined"&&(this.onResourceError=e=>{var i;let t=e.target;if(!t)return;let n=(i=t.tagName)==null?void 0:i.toLowerCase(),r=t.src||t.href;if(n&&r&&["img","script","link","audio","video"].includes(n))try{if(this.shouldIgnoreScriptUrl(r)||!this.shouldSampleResource())return;let o=`resource:${n}`,a=k(r);this.client.captureEvent({type:"error",level:"warning",message:`Resource load failed: ${n} ${a}`,timestamp:p(),fingerprint:o,tags:{resource_type:n,resource_url:a},exception:{type:"ResourceError",value:`Failed to load ${n} resource`}})}catch(o){R("ErrorPlugin","Resource error handler error",o)}},window.addEventListener("error",this.onResourceError,!0))}buildErrorEvent(e,t,n,r){let i=p();if(e instanceof Error){if(this.shouldIgnoreError(e.message))return null;let c=B(e.stack,{captureNodeModules:this.config.captureNodeModules,captureColumn:this.config.captureColumn,relativePathOnly:this.config.relativePathOnly,maxFrames:this.config.maxStackFrames});if(!this.shouldIncludePath(c)||!this.shouldSample())return null;let d=D(e.name,e.message,c);return{type:"error",level:"error",message:e.message,timestamp:i,exception:{type:e.name,value:e.message,stacktrace:{frames:c}},fingerprint:d}}let o=String(e);if(this.shouldIgnoreError(o))return null;let a=[];return t&&a.push({filename:t,lineno:n,colno:this.config.captureColumn?r:void 0,in_app:!0}),!this.shouldIncludePath(a)||!this.shouldSample()?null:{type:"error",level:"error",message:o,timestamp:i,exception:{type:"Error",value:o,stacktrace:{frames:a}}}}destroy(){typeof window!="undefined"&&(this.originalOnError!==void 0&&(window.onerror=this.originalOnError),this.onUnhandledRejection&&window.removeEventListener("unhandledrejection",this.onUnhandledRejection),this.onResourceError&&window.removeEventListener("error",this.onResourceError,!0))}},se=ie;var oe=class{constructor(){this.name="performance";this.version="2.0.0";this.config={sampleRate:.1,captureLongTasks:!0,captureResources:!1,resourceSampleRate:.01,longTaskSampleRate:.05,captureNavigation:!0,captureFP:!0,enablePageLoadTracing:!1,maxResourceSpans:50};this.observers=[];this.navLoadTimer=null;this.totalBlockingTime=0;this.fcpTime=null;this.lastLongTaskEndTime=0;this.ttiReported=!1;this.ttiTimer=null;this.pageLoadTransaction=null;this.measurements={};this.resourceSpanCount=0}setup(e){this.client=e,this.loadConfig(),this.config.enablePageLoadTracing&&this.startPageLoadTransaction(),this.observeWebVitals(),this.observeLongTasks(),this.observeNavigation(),this.observeResources()}startPageLoadTransaction(){var n;if(typeof window=="undefined")return;let e=typeof location!="undefined"?location.pathname:"/",t=typeof performance!="undefined"&&((n=performance.timing)!=null&&n.navigationStart)?performance.timing.navigationStart:p();this.pageLoadTransaction=this.client.startTransaction({name:e,op:"pageload",description:`Page load - ${e}`,startTimestamp:t,type:"pageload",tags:{"page.url":e}})}loadConfig(){let e=this.client.config;e&&y(e.performance)&&(this.config={...this.config,...e.performance})}shouldSample(e="default"){var n,r,i;let t=(n=this.config.sampleRate)!=null?n:.1;return e==="resource"?t=(r=this.config.resourceSampleRate)!=null?r:.01:e==="longtask"?t=(i=this.config.longTaskSampleRate)!=null?i:.05:e==="vitals"&&(t=1),t>=1?!0:t<=0?!1:Math.random(){let n=t.getEntriesByName("first-paint");n.length>0&&this.config.captureFP&&this.reportMetric("FP",n[0].startTime,"ms",{},"vitals");let r=t.getEntriesByName("first-contentful-paint");r.length>0&&(this.fcpTime=r[0].startTime,this.lastLongTaskEndTime=r[0].startTime,this.reportMetric("FCP",r[0].startTime,"ms",{},"vitals"),this.scheduleTTI())});e.observe({type:"paint",buffered:!0}),this.observers.push(e)}catch(e){}}observeLCP(){try{let e=new PerformanceObserver(t=>{let n=t.getEntries(),r=n[n.length-1];if(r){let i=r.renderTime||r.loadTime||r.startTime;this.reportMetric("LCP",i,"ms",{},"vitals")}});e.observe({type:"largest-contentful-paint",buffered:!0}),this.observers.push(e)}catch(e){}}observeFID(){try{let e=new PerformanceObserver(t=>{let n=t.getEntries();if(n.length>0){let r=n[0],i=r.processingStart-r.startTime;this.reportMetric("FID",i,"ms",{},"vitals")}});e.observe({type:"first-input",buffered:!0}),this.observers.push(e)}catch(e){}}observeCLS(){try{let e=0,t=0,n=[],r=new PerformanceObserver(i=>{let o=i.getEntries();for(let a of o)if(!a.hadRecentInput){let c=n[0],d=n[n.length-1];t&&a.startTime-((d==null?void 0:d.duration)||0)<1e3&&a.startTime-c.startTime<5e3?(t+=a.value||0,n.push(a)):(t=a.value||0,n=[a]),t>e&&(e=t,this.reportMetric("CLS",e,"",{},"vitals"))}});r.observe({type:"layout-shift",buffered:!0}),this.observers.push(r)}catch(e){}}observeTTFB(){try{let e=new PerformanceObserver(t=>{let n=t.getEntriesByType("navigation");if(n.length>0){let r=n[0],i=r.responseStart-r.requestStart;this.reportMetric("TTFB",Math.max(0,i),"ms",{},"vitals")}});e.observe({type:"navigation",buffered:!0}),this.observers.push(e)}catch(e){}}observeLongTasks(){if(this.config.captureLongTasks)try{let e=new PerformanceObserver(t=>{let n=t.getEntries();for(let r of n){let i=r.startTime+r.duration;if(i>this.lastLongTaskEndTime&&(this.lastLongTaskEndTime=i),this.fcpTime!==null&&r.startTime>=this.fcpTime){let o=r.duration-50;o>0&&(this.totalBlockingTime+=o)}this.reportMetric("longtask",r.duration,"ms",{},"longtask"),this.scheduleTTI()}});e.observe({type:"longtask",buffered:!0}),this.observers.push(e)}catch(e){}}scheduleTTI(){this.ttiReported||(this.ttiTimer&&clearTimeout(this.ttiTimer),this.ttiTimer=setTimeout(()=>{if(this.ttiReported)return;this.ttiReported=!0;let e=Math.max(this.lastLongTaskEndTime,this.fcpTime||0);this.reportMetric("TTI",e,"ms",{},"vitals"),this.reportMetric("TBT",this.totalBlockingTime,"ms",{},"vitals")},5e3))}observeNavigation(){this.config.captureNavigation&&typeof performance!="undefined"&&(this.onLoad=()=>{this.navLoadTimer=setTimeout(()=>{let e=performance.timing;if(!e)return;let t=e.navigationStart,n={dom_ready:e.domContentLoadedEventEnd-t,load_time:e.loadEventEnd-t,dns:e.domainLookupEnd-e.domainLookupStart,tcp:e.connectEnd-e.connectStart,ssl:e.secureConnectionStart>0?e.connectEnd-e.secureConnectionStart:0,ttfb:e.responseStart-e.requestStart,download:e.responseEnd-e.responseStart,dom_parse:e.domInteractive-e.responseEnd};for(let[r,i]of Object.entries(n))i>0&&this.reportMetric(r,i,"ms");this.pageLoadTransaction&&this.pageLoadTransaction.sampled!==!1&&(this.buildNavigationSpans(e,t),this.finishPageLoadTransaction(e.loadEventEnd||p())),this.navLoadTimer=null},0)},window.addEventListener("load",this.onLoad))}buildNavigationSpans(e,t){let n=[{op:"dns",desc:"DNS Lookup",start:e.domainLookupStart,end:e.domainLookupEnd},{op:"tcp",desc:"TCP Connection",start:e.connectStart,end:e.connectEnd},{op:"ssl",desc:"SSL/TLS Negotiation",start:e.secureConnectionStart,end:e.connectEnd},{op:"ttfb",desc:"Time to First Byte",start:e.requestStart,end:e.responseStart},{op:"response",desc:"Response Download",start:e.responseStart,end:e.responseEnd},{op:"dom_parse",desc:"DOM Parsing",start:e.responseEnd,end:e.domInteractive},{op:"dom_content_loaded",desc:"DOM Content Loaded",start:e.domLoading,end:e.domContentLoadedEventEnd},{op:"load",desc:"Page Load",start:e.navigationStart,end:e.loadEventEnd}];for(let r of n)r.start>0&&r.end>0&&r.end>r.start&&this.createNavigationSpan(r.op,r.desc,r.start,r.end)}finishPageLoadTransaction(e){this.pageLoadTransaction&&(Object.keys(this.measurements).length>0&&this.pageLoadTransaction.setData("measurements",this.measurements),this.pageLoadTransaction.setStatus("ok"),this.pageLoadTransaction.finish(e),this.pageLoadTransaction=null)}observeResources(){if(!(!this.config.captureResources&&!this.config.enablePageLoadTracing)&&typeof performance!="undefined")try{let e=new PerformanceObserver(t=>{let n=t.getEntriesByType("resource");for(let r of n)r.duration>1e3&&this.config.captureResources&&this.reportMetric("resource_slow",r.duration,"ms",{resource_name:r.name.substring(0,200),resource_type:r.initiatorType},"resource"),this.config.enablePageLoadTracing&&this.pageLoadTransaction&&this.createResourceSpan(r)});e.observe({type:"resource",buffered:!0}),this.observers.push(e)}catch(e){}}getRating(e,t){let r={LCP:{good:2500,poor:4e3},FCP:{good:1800,poor:3e3},FP:{good:1800,poor:3e3},FID:{good:100,poor:300},CLS:{good:.1,poor:.25},TTFB:{good:800,poor:1800}}[e];return!r||t<=r.good?"good":t<=r.poor?"needs-improvement":"poor"}reportMetric(e,t,n,r={},i="default"){if(!this.shouldSample(i))return;let o=this.getRating(e,t),a={type:"performance",level:"info",metric:e,value:Math.round(t*100)/100,unit:n,rating:o,timestamp:p(),tags:{metric:e,rating:o,...r}};this.client.captureEvent(a),this.pageLoadTransaction&&this.pageLoadTransaction.sampled!==!1&&this.recordMeasurement(e,t,n,o)}recordMeasurement(e,t,n,r){this.pageLoadTransaction&&(this.measurements[e]={value:Math.round(t*100)/100,unit:n,rating:r},this.pageLoadTransaction.setTag(`measurement.${e}.rating`,r||"unknown"))}createNavigationSpan(e,t,n,r,i){if(!this.pageLoadTransaction||this.pageLoadTransaction.sampled===!1||r<=n)return;this.pageLoadTransaction.startChild({op:`browser.${e}`,description:t,startTimestamp:n,tags:i}).finish(r)}createResourceSpan(e){var c,d;if(!this.pageLoadTransaction||this.pageLoadTransaction.sampled===!1)return;let t=(c=this.config.maxResourceSpans)!=null?c:50;if(this.resourceSpanCount>=t)return;this.resourceSpanCount++;let n=typeof performance!="undefined"&&performance.timeOrigin?performance.timeOrigin:((d=performance.timing)==null?void 0:d.navigationStart)||0,r=n+e.startTime,i=n+(e.responseEnd||e.duration||e.startTime);if(i<=r)return;let o=e.name.substring(0,200);this.pageLoadTransaction.startChild({op:`resource.${e.initiatorType||"other"}`,description:o,startTimestamp:r,tags:{"resource.type":e.initiatorType||"other","resource.url":o,"resource.transfer_size":String(e.transferSize||0),"resource.decoded_size":String(e.decodedBodySize||0)},data:{transferSize:e.transferSize,decodedSize:e.decodedBodySize,encodedSize:e.encodedBodySize}}).finish(i)}destroy(){for(let e of this.observers)try{e.disconnect()}catch(t){}this.observers=[],this.ttiTimer&&(clearTimeout(this.ttiTimer),this.ttiTimer=null),this.navLoadTimer&&(clearTimeout(this.navLoadTimer),this.navLoadTimer=null),typeof window!="undefined"&&this.onLoad&&window.removeEventListener("load",this.onLoad),this.pageLoadTransaction&&(this.pageLoadTransaction.setStatus("internal_error"),this.pageLoadTransaction.finish(),this.pageLoadTransaction=null),this.measurements={},this.resourceSpanCount=0}},ae=oe;var ce=class{constructor(){this.name="network";this.version="1.1.0";this.config={captureXHR:!0,captureFetch:!0,captureSuccess:!1,captureBody:!1,captureRequestBody:!1,captureResponseBody:!1,captureRequestHeaders:["content-type","user-agent"],captureResponseHeaders:["content-type","content-length"],errorSampleRate:1,successSampleRate:.01,slowThreshold:3e3,slowSampleRate:1,ignoreStatusCodes:[]}}setup(e){this.client=e,this.loadConfig(),this.config.captureFetch&&this.patchFetch(),this.config.captureXHR&&this.patchXHR()}loadConfig(){let e=this.client.config;e&&y(e.network)&&(this.config={...this.config,...e.network}),e.ignoreUrls&&(this.config.ignoreUrls=[...this.config.ignoreUrls||[],...e.ignoreUrls]),e.tracePropagationTargets?this.config.tracePropagationTargets=[...this.config.tracePropagationTargets||[],...e.tracePropagationTargets]:e.tracingOrigins&&(this.config.tracePropagationTargets=[...this.config.tracePropagationTargets||[],...e.tracingOrigins])}shouldIgnore(e){return q(e,this.config.ignoreUrls||[])}shouldTracePropagate(e){let t=this.config.tracePropagationTargets;return!t||t.length===0?this.isSameOrigin(e):t.some(n=>typeof n=="string"?e.includes(n):n.test(e))}isSameOrigin(e){if(typeof location=="undefined")return!1;try{return new URL(e,location.origin).origin===location.origin}catch(t){return!1}}getBaggageHeader(){var r,i;if(!this.client)return;let t=(i=(r=this.client.tracingManager)==null?void 0:r.getCurrentTransaction)==null?void 0:i.call(r);if(!t)return;let n=t;if(n.toBaggage)return n.toBaggage()}shouldSample(e,t){var r,i,o,a;let n=e?(r=this.config.errorSampleRate)!=null?r:1:(i=this.config.successSampleRate)!=null?i:.01;return!e&&t>=((o=this.config.slowThreshold)!=null?o:3e3)&&(n=(a=this.config.slowSampleRate)!=null?a:1),n>=1?!0:n<=0?!1:Math.random()0?e.setHttpStatus(t):r&&e.setStatus("internal_error"),e.finish()}patchFetch(){if(typeof fetch=="undefined")return;this.originalFetch=window.fetch;let e=this;window.fetch=function(t,n){let r=p(),i=typeof t=="string"?t:t instanceof URL?t.toString():t.url,o=(n==null?void 0:n.method)||"GET";if(e.shouldIgnore(i))return e.originalFetch.call(window,t,n);let a=k(i),c=e.createHttpSpan(o,a),d=e.shouldTracePropagate(i)&&!!c,f=n;if(d&&c){let h=c.toTraceparent(),g=e.getBaggageHeader();f={...n,headers:{...(n==null?void 0:n.headers)||{},"sentry-trace":h,...g?{baggage:g}:{}}}}let E=e.originalFetch.call(window,t,f);return E.then(h=>{var S;let g=p()-r,m=h.ok,v=h.status;return c&&e.finishHttpSpan(c,v,g,!m),(S=e.config.ignoreStatusCodes)!=null&&S.includes(v)||!e.shouldSample(!m,g)||(!m||e.config.captureSuccess)&&e.reportNetwork({sub_type:"fetch",method:o.toUpperCase(),url:a,status_code:v,duration:g,success:m,error:m?void 0:`HTTP ${v}`}),h},h=>{let g=p()-r;throw c&&e.finishHttpSpan(c,0,g,!0),e.shouldSample(!0,g)&&e.reportNetwork({sub_type:"fetch",method:o.toUpperCase(),url:a,duration:g,success:!1,error:(h==null?void 0:h.message)||"Network error"}),h}),E}}patchXHR(){if(typeof XMLHttpRequest=="undefined")return;this.originalXHROpen=XMLHttpRequest.prototype.open,this.originalXHRSend=XMLHttpRequest.prototype.send;let e=this;XMLHttpRequest.prototype.open=function(t,n){return this._lightMethod=t,this._lightUrl=typeof n=="string"?n:n.toString(),this._lightTracked=!1,e.originalXHROpen.apply(this,arguments)},XMLHttpRequest.prototype.send=function(t){let n=p(),r=this._lightMethod||"GET",i=this._lightUrl||"",o=this._lightTracked;if(e.shouldIgnore(i)||o)return e.originalXHRSend.apply(this,arguments);this._lightTracked=!0;let a=k(i),c=0;t&&typeof t=="string"&&(c=t.length);let d=e.createHttpSpan(r,a);if(e.shouldTracePropagate(i)&&!!d&&d)try{let h=d.toTraceparent(),g=e.getBaggageHeader();this.setRequestHeader("sentry-trace",h),g&&this.setRequestHeader("baggage",g)}catch(h){}let E=this.onloadend;return this.onloadend=function(h){var S;let g=p()-n,m=this.status,v=m>=200&&m<300;if(d&&e.finishHttpSpan(d,m,g,!v),!((S=e.config.ignoreStatusCodes)!=null&&S.includes(m))&&e.shouldSample(!v,g)&&(!v||e.config.captureSuccess)){let b=0;try{let x=this.getResponseHeader("content-length");x&&(b=parseInt(x,10)),!b&&this.responseText&&(b=this.responseText.length)}catch(x){}e.reportNetwork({sub_type:"xhr",method:r.toUpperCase(),url:a,status_code:m,duration:g,request_size:c||void 0,response_size:b||void 0,success:v,error:v?void 0:`HTTP ${m}`})}if(E)return E.call(this,h)},e.originalXHRSend.apply(this,arguments)}}reportNetwork(e){let t={type:"network",level:e.success?"info":"error",timestamp:p(),tags:{method:e.method,sub_type:e.sub_type,success:String(e.success)},...e};this.client.captureEvent(t)}destroy(){this.originalFetch&&(window.fetch=this.originalFetch),this.originalXHROpen&&(XMLHttpRequest.prototype.open=this.originalXHROpen),this.originalXHRSend&&(XMLHttpRequest.prototype.send=this.originalXHRSend)}},ue=ce;var le=class{constructor(){this.name="behavior";this.version="1.0.0";this.config={capturePV:!0,captureClick:!0,captureRoute:!0,captureDuration:!0,captureScroll:!0,clickThrottle:300,scrollThrottle:1e3,sampleRate:.01};this.lastClickTime=0;this.lastScrollTime=0;this.maxScrollDepth=0;this.pageEnterTime=0;this.scrollReported=!1}setup(e){this.client=e,this.loadConfig(),this.config.capturePV&&this.trackPV(),this.config.captureClick&&this.trackClick(),this.config.captureRoute&&this.trackRoute(),this.config.captureDuration&&this.trackPageDuration(),this.config.captureScroll&&this.trackScroll()}loadConfig(){let e=this.client.config;e&&y(e.behavior)&&(this.config={...this.config,...e.behavior})}shouldSample(){var t;let e=(t=this.config.sampleRate)!=null?t:.01;return e>=1?!0:e<=0?!1:Math.random(){var a,c,d;let t=p(),n=(a=this.config.clickThrottle)!=null?a:300;if(t-this.lastClickTime{let r=w();if(r!==e){let i=e,o=r;e=r,this.reportBehavior({sub_type:"route",page_url:o,referrer:i,properties:{from:i,to:o}}),this.pageEnterTime=p(),this.maxScrollDepth=0,this.scrollReported=!1}};this.originalPushState=history.pushState,this.originalReplaceState=history.replaceState;let n=this;history.pushState=function(){let r=n.originalPushState.apply(this,arguments);return setTimeout(t,0),r},history.replaceState=function(){let r=n.originalReplaceState.apply(this,arguments);return setTimeout(t,0),r},this.onPopState=()=>{setTimeout(t,0)},this.onHashchange=()=>{setTimeout(t,0)},window.addEventListener("popstate",this.onPopState),window.addEventListener("hashchange",this.onHashchange)}trackPageDuration(){if(typeof window=="undefined")return;this.pageEnterTime=p();let e=()=>{let t=p()-this.pageEnterTime;t>1e3&&(this.config.captureScroll&&!this.scrollReported&&this.reportScroll(),this.reportBehavior({sub_type:"duration",page_url:w(),properties:{duration:t,max_scroll_depth:this.maxScrollDepth}}))};this.onVisibilityChange=()=>{document.hidden?e():this.pageEnterTime=p()},this.onBeforeUnload=e,this.onPagehide=e,document.addEventListener("visibilitychange",this.onVisibilityChange),window.addEventListener("beforeunload",this.onBeforeUnload),window.addEventListener("pagehide",this.onPagehide)}trackScroll(){typeof window!="undefined"&&(this.onScroll=()=>{var r;let e=p(),t=(r=this.config.scrollThrottle)!=null?r:1e3;if(e-this.lastScrollTimethis.maxScrollDepth&&(this.maxScrollDepth=n)},window.addEventListener("scroll",this.onScroll,{passive:!0}))}reportScroll(){this.scrollReported||(this.scrollReported=!0,this.reportBehavior({sub_type:"scroll",page_url:w(),properties:{max_depth:this.maxScrollDepth}}))}reportBehavior(e){if(!this.shouldSample())return;let t={type:"behavior",level:"info",timestamp:p(),tags:{sub_type:e.sub_type,page_url:w()},...e};this.client.captureEvent(t)}destroy(){typeof window!="undefined"&&(this.originalPushState&&(history.pushState=this.originalPushState),this.originalReplaceState&&(history.replaceState=this.originalReplaceState),this.onPopState&&window.removeEventListener("popstate",this.onPopState),this.onHashchange&&window.removeEventListener("hashchange",this.onHashchange),this.onBeforeUnload&&window.removeEventListener("beforeunload",this.onBeforeUnload),this.onPagehide&&window.removeEventListener("pagehide",this.onPagehide),this.onScroll&&window.removeEventListener("scroll",this.onScroll)),typeof document!="undefined"&&(this.onClick&&document.removeEventListener("click",this.onClick,!0),this.onVisibilityChange&&document.removeEventListener("visibilitychange",this.onVisibilityChange))}},de=le;var ht="light-sentry-offline",T="events",pe=1e3,he=class{constructor(){this.name="offline";this.version="1.0.0";this.config={maxEvents:pe};this.db=null;this.isOnline=!0;this.isSyncing=!1;this.pendingEvents=[]}setup(e){this.client=e,this.loadConfig(),this.initDatabase(),this.setupNetworkListeners()}loadConfig(){let e=this.client.config;e&&typeof e.offline=="object"&&(this.config={...this.config,...e.offline})}async initDatabase(){if(typeof indexedDB=="undefined"){console.warn("[LightSDK] OfflinePlugin: IndexedDB not available");return}return new Promise((e,t)=>{let n=indexedDB.open(ht,1);n.onerror=()=>{console.warn("[LightSDK] OfflinePlugin: Failed to open IndexedDB"),t(n.error)},n.onsuccess=()=>{this.db=n.result,e()},n.onupgradeneeded=r=>{let i=r.target.result,o=r.oldVersion;i.objectStoreNames.contains(T)||i.createObjectStore(T,{keyPath:"id"}).createIndex("timestamp","timestamp",{unique:!1})}})}setupNetworkListeners(){typeof window!="undefined"&&(this.isOnline=navigator.onLine,this.onOnline=()=>{console.info("[LightSDK] OfflinePlugin: Network online"),this.isOnline=!0,this.syncPendingEvents()},this.onOffline=()=>{console.info("[LightSDK] OfflinePlugin: Network offline"),this.isOnline=!1},window.addEventListener("online",this.onOnline),window.addEventListener("offline",this.onOffline))}generateId(){return`${Date.now()}-${Math.random().toString(36).substring(2,11)}`}async saveToIndexedDB(e){if(!this.db)return;let t=this.config.maxEvents||pe,n=await this.getEventCount();return n>=t&&await this.deleteOldestEvents(n-t+1),new Promise((r,i)=>{let a=this.db.transaction([T],"readwrite").objectStore(T),c={id:this.generateId(),event:{...e,offline:!0},timestamp:p()},d=a.add(c);d.onsuccess=()=>r(),d.onerror=()=>i(d.error)})}getEventCount(){return this.db?new Promise((e,t)=>{let i=this.db.transaction([T],"readonly").objectStore(T).count();i.onsuccess=()=>e(i.result),i.onerror=()=>t(i.error)}):Promise.resolve(0)}async deleteOldestEvents(e){if(!(!this.db||e<=0))return new Promise((t,n)=>{let a=this.db.transaction([T],"readwrite").objectStore(T).index("timestamp").openCursor(),c=0;a.onsuccess=d=>{let f=d.target.result;f&&cn(a.error)})}async getAllStoredEvents(){return this.db?new Promise((e,t)=>{let o=this.db.transaction([T],"readonly").objectStore(T).index("timestamp").getAll();o.onsuccess=()=>{let a=o.result||[];a.sort((c,d)=>c.timestamp-d.timestamp),e(a)},o.onerror=()=>t(o.error)}):[]}async clearStoredEvents(){if(this.db)return new Promise((e,t)=>{let i=this.db.transaction([T],"readwrite").objectStore(T).clear();i.onsuccess=()=>e(),i.onerror=()=>t(i.error)})}async syncPendingEvents(){if(!(!this.isOnline||this.isSyncing)){this.isSyncing=!0,console.info("[LightSDK] OfflinePlugin: Syncing pending events");try{let e=0;for(;this.pendingEvents.length>0;){let n=this.pendingEvents.shift();try{this.client.captureEvent(n),e++}catch(r){console.error("[LightSDK] OfflinePlugin: Failed to re-enqueue memory event",r)}}let t=await this.getAllStoredEvents();if(t.length>0)for(let n of t)try{let r=n.event;this.client.captureEvent(r),e++}catch(r){console.error("[LightSDK] OfflinePlugin: Failed to re-enqueue event",r)}try{await this.client.flush()}catch(n){}await this.clearStoredEvents(),console.info(`[LightSDK] OfflinePlugin: Synced ${e} events`)}catch(e){console.error("[LightSDK] OfflinePlugin: Sync failed",e)}finally{this.isSyncing=!1}}}beforeReport(e){if(!this.isOnline){let n=this.config.maxEvents||pe;return this.pendingEvents.length>=n&&this.pendingEvents.shift(),this.pendingEvents.push(e),this.savePendingEventsToDB(),null}let t={...e};return delete t.offline,t}savePendingEventsToDB(){if(this.pendingEvents.length===0)return;let e=this.pendingEvents.splice(0,this.pendingEvents.length),t=0,n=()=>{if(t>=e.length)return;let r=e[t];this.saveToIndexedDB(r).then(()=>{t++,n()}).catch(i=>{console.error("[LightSDK] OfflinePlugin: Failed to save event offline",i),this.pendingEvents.unshift(...e.slice(t))})};n()}destroy(){typeof window!="undefined"&&(this.onOnline&&window.removeEventListener("online",this.onOnline),this.onOffline&&window.removeEventListener("offline",this.onOffline)),this.db&&(this.db.close(),this.db=null)}},ge=he;var fe=class{constructor(){this.name="sampling";this.version="1.0.0";this.config={rates:{error:1,performance:1,network:1,behavior:1}}}setup(e){this.client=e,this.loadConfig()}loadConfig(){let e=this.client.config;if(e&&y(e.sampling)){let t=e.sampling;"rates"in t&&y(t.rates)&&(this.config.rates={...this.config.rates,...t.rates})}}shouldSample(e){var r;let t=(r=this.client.config.sampleRate)!=null?r:1;if(t<=0)return!1;let n=this.getTypeRate(e);return t>=1?this.randomCheck(n):this.randomCheck(t*n)}getTypeRate(e){let t=this.config.rates||{},n=e.type;if(n==="count")return 1;let r=t[n];return r!==void 0?r:1}randomCheck(e){return e>=1?!0:e<=0?!1:Math.random(){this.handleRouteChange(location.pathname+location.search,"popstate")};this.handleHashChange=()=>{this.handleRouteChange(location.hash||"#/","hashchange")}}setup(e){this.client=e,this.loadConfig(),typeof window!="undefined"&&this.config.enable&&(this.config.instrumentHistory&&this.instrumentHistory(),this.config.instrumentHash&&this.instrumentHash())}loadConfig(){let e=this.client.config;e&&y(e.router)&&(this.config={...this.config,...e.router})}instrumentHistory(){typeof history=="undefined"||!history.pushState||(this.originalPushState=history.pushState.bind(history),this.originalReplaceState=history.replaceState.bind(history),history.pushState=(e,t,n)=>{this.originalPushState(e,t,n),this.handleRouteChange(n||location.pathname+location.search,"pushState")},history.replaceState=(e,t,n)=>{this.originalReplaceState(e,t,n),this.handleRouteChange(n||location.pathname+location.search,"replaceState")},window.addEventListener("popstate",this.handlePopState))}instrumentHash(){window.addEventListener("hashchange",this.handleHashChange)}handleRouteChange(e,t){this.routeChangeTimer&&clearTimeout(this.routeChangeTimer),this.routeChangeTimer=setTimeout(()=>{this.routeChangeTimer=null,this.processRouteChange(e,t)},50)}processRouteChange(e,t){let n=this.config.routeNameFormatter?this.config.routeNameFormatter(e):e.split("?")[0];n!==this.lastRoute&&(this.lastRoute=n,this.finishCurrentTransaction("ok"),this.startNavigationTransaction(n,t))}startNavigationTransaction(e,t){if(!this.client)return;let n=this.client.startTransaction({name:e,op:"navigation",description:`Navigation to ${e}`,type:"navigation",tags:{"route.name":e,"route.source":t}});n&&(this.currentTransaction=n,this.startMaxDurationTimer())}startMaxDurationTimer(){var t;this.maxDurationTimer&&clearTimeout(this.maxDurationTimer);let e=(t=this.config.maxTransactionDurationMs)!=null?t:3e4;this.maxDurationTimer=setTimeout(()=>{this.currentTransaction&&(this.currentTransaction.setStatus("deadline_exceeded"),this.finishCurrentTransaction("deadline_exceeded"))},e)}finishCurrentTransaction(e="ok"){this.maxDurationTimer&&(clearTimeout(this.maxDurationTimer),this.maxDurationTimer=null),this.currentTransaction&&(this.currentTransaction.setStatus(e),this.currentTransaction.finish(),this.currentTransaction=null)}destroy(){this.originalPushState&&typeof history!="undefined"&&(history.pushState=this.originalPushState),this.originalReplaceState&&typeof history!="undefined"&&(history.replaceState=this.originalReplaceState),typeof window!="undefined"&&(window.removeEventListener("popstate",this.handlePopState),window.removeEventListener("hashchange",this.handleHashChange)),this.maxDurationTimer&&(clearTimeout(this.maxDurationTimer),this.maxDurationTimer=null),this.routeChangeTimer&&(clearTimeout(this.routeChangeTimer),this.routeChangeTimer=null),this.finishCurrentTransaction("aborted")}},ye=ve;var Se=class{constructor(){this.name="interaction";this.version="1.0.0";this.config={enable:!0,elementAttribute:"data-sentry-component",maxTransactionDurationMs:3e4,idleTimeoutMs:1e3,trackClick:!0,trackSubmit:!0,trackKeypress:!1};this.currentTransaction=null;this.idleTimer=null;this.maxDurationTimer=null;this.debounceTimer=null;this.handleClick=e=>{if(this.isEventIgnored(e))return;let t=e.target,n=this.getElementName(t,"click");this.scheduleInteractionTransaction(n,"click",t)};this.handleSubmit=e=>{if(this.isEventIgnored(e))return;let t=e.target,n=this.getElementName(t,"submit");this.scheduleInteractionTransaction(n,"submit",t)}}setup(e){this.client=e,this.loadConfig(),typeof window!="undefined"&&this.config.enable&&(this.config.trackClick&&document.addEventListener("click",this.handleClick,!0),this.config.trackSubmit&&document.addEventListener("submit",this.handleSubmit,!0))}loadConfig(){let e=this.client.config;e&&y(e.interaction)&&(this.config={...this.config,...e.interaction})}isEventIgnored(e){let t=e.target;return!!(!t||t.hasAttribute&&t.hasAttribute("data-sentry-ignore"))}scheduleInteractionTransaction(e,t,n){this.debounceTimer&&clearTimeout(this.debounceTimer),this.debounceTimer=setTimeout(()=>{this.startInteractionTransaction(e,t,n)},0)}getElementName(e,t){var c;if(!e)return t;let n=this.config.elementAttribute||"data-sentry-component",r=e.getAttribute(n);if(r)return r;let i=((c=e.tagName)==null?void 0:c.toLowerCase())||"element",o=e.id?`#${e.id}`:"",a=e.className&&typeof e.className=="string"?`.${e.className.split(" ").slice(0,3).join(".")}`:"";return`${t}@${i}${o}${a}`}startInteractionTransaction(e,t,n){var i,o;if(!this.client)return;this.currentTransaction&&this.finishCurrentTransaction("ok");let r=this.client.startTransaction({name:e,op:`ui.${t}`,description:`User ${t} on ${e}`,type:"user-interaction",tags:{"interaction.type":t,"interaction.target":e},data:{tag:(i=n.tagName)==null?void 0:i.toLowerCase(),id:n.id||void 0,text:((o=n.textContent)==null?void 0:o.substring(0,100))||void 0}});r&&(this.currentTransaction=r,this.scheduleIdleFinish(),this.scheduleMaxDuration())}scheduleIdleFinish(){var t;this.idleTimer&&clearTimeout(this.idleTimer);let e=(t=this.config.idleTimeoutMs)!=null?t:1e3;this.idleTimer=setTimeout(()=>{this.finishCurrentTransaction("ok")},e)}scheduleMaxDuration(){var t;this.maxDurationTimer&&clearTimeout(this.maxDurationTimer);let e=(t=this.config.maxTransactionDurationMs)!=null?t:3e4;this.maxDurationTimer=setTimeout(()=>{this.finishCurrentTransaction("deadline_exceeded")},e)}finishCurrentTransaction(e="ok"){this.idleTimer&&(clearTimeout(this.idleTimer),this.idleTimer=null),this.maxDurationTimer&&(clearTimeout(this.maxDurationTimer),this.maxDurationTimer=null),this.debounceTimer&&(clearTimeout(this.debounceTimer),this.debounceTimer=null),this.currentTransaction&&(this.currentTransaction.setStatus(e),this.currentTransaction.finish(),this.currentTransaction=null)}destroy(){typeof document!="undefined"&&(document.removeEventListener("click",this.handleClick,!0),document.removeEventListener("submit",this.handleSubmit,!0)),this.idleTimer&&(clearTimeout(this.idleTimer),this.idleTimer=null),this.maxDurationTimer&&(clearTimeout(this.maxDurationTimer),this.maxDurationTimer=null),this.debounceTimer&&(clearTimeout(this.debounceTimer),this.debounceTimer=null),this.finishCurrentTransaction("aborted")}},be=Se;var l=null;function _e(s){var r;O(s.debug===!0),u("Index","init called",{dsn:s.dsn,debug:s.debug});let e=new re(s),t=[new ge,new me,new se],n=((r=s.plugins)==null?void 0:r.filter(i=>typeof i=="string"))||[];(n.includes("performance")||n.includes("all"))&&t.push(new ae),(n.includes("network")||n.includes("all"))&&t.push(new ue),(n.includes("behavior")||n.includes("all"))&&t.push(new de),(n.includes("router")||n.includes("all"))&&t.push(new ye),(n.includes("interaction")||n.includes("all"))&&t.push(new be),u("Index","Registering plugins",{count:t.length,plugins:t.map(i=>i.name)});for(let i of t)e.use(i);if(s.plugins)for(let i of s.plugins)typeof i=="object"&&i!==null&&"name"in i&&"setup"in i&&e.use(i);return e.init(),l=e,u("Index","init completed, globalClient set"),e}function Me(){return l}function De(s){if(u("Index","captureException called",{hasClient:!!l}),!l){console.warn("[LightSDK] SDK not initialized. Call LightSentry.init() first.");return}l.captureException(s)}function Be(s,e){if(u("Index","captureMessage called",{hasClient:!!l}),!l){console.warn("[LightSDK] SDK not initialized. Call LightSentry.init() first.");return}l.captureMessage(s,e)}function Oe(s){if(u("Index","captureEvent called",{hasClient:!!l}),!l){console.warn("[LightSDK] SDK not initialized. Call LightSentry.init() first.");return}l.captureEvent(s)}function Fe(s){l==null||l.setUser(s)}function Ne(s){H(s)}function He(){we()}function qe(){return N()}function Ue(s){return(l==null?void 0:l.startTransaction(s))||null}function $e(){return(l==null?void 0:l.getCurrentTransaction())||null}function Ae(){return(l==null?void 0:l.getCurrentSpan())||null}function je(s){l==null||l.setSpan(s)}function Ke(s){return(l==null?void 0:l.startSpan(s))||null}function ze(s,e){l==null||l.setTag(s,e)}function Xe(s){l==null||l.setTags(s)}function We(s,e){l==null||l.setExtra(s,e)}function Ve(s){l==null||l.addBreadcrumb(s)}async function Qe(){await(l==null?void 0:l.flush())}function Ge(){l==null||l.disable()}function Je(){l==null||l.enable()}var gt={init:_e,getClient:Me,captureException:De,captureMessage:Be,captureEvent:Oe,setUser:Fe,setAnonymousId:Ne,clearAnonymousId:He,getAnonymousId:qe,startTransaction:Ue,getCurrentTransaction:$e,getCurrentSpan:Ae,setSpan:je,startSpan:Ke,setTag:ze,setTags:Xe,setExtra:We,addBreadcrumb:Ve,flush:Qe,disable:Ge,enable:Je,Span:C,Transaction:L,httpStatusToSpanStatus:_};return rt(ft);})(); diff --git a/dist/plugins/InteractionPlugin.d.ts b/dist/plugins/InteractionPlugin.d.ts new file mode 100644 index 0000000..e9dcf05 --- /dev/null +++ b/dist/plugins/InteractionPlugin.d.ts @@ -0,0 +1,24 @@ +import type { LightPlugin, LightClient } from '../types'; +declare class InteractionPlugin implements LightPlugin { + name: string; + version: string; + private client; + private config; + private currentTransaction; + private idleTimer; + private maxDurationTimer; + private debounceTimer; + setup(client: LightClient): void; + private loadConfig; + private handleClick; + private handleSubmit; + private isEventIgnored; + private scheduleInteractionTransaction; + private getElementName; + private startInteractionTransaction; + private scheduleIdleFinish; + private scheduleMaxDuration; + private finishCurrentTransaction; + destroy(): void; +} +export default InteractionPlugin; diff --git a/dist/plugins/NetworkPlugin.d.ts b/dist/plugins/NetworkPlugin.d.ts index ae9b34f..fc0256f 100644 --- a/dist/plugins/NetworkPlugin.d.ts +++ b/dist/plugins/NetworkPlugin.d.ts @@ -10,7 +10,12 @@ declare class NetworkPlugin implements LightPlugin { setup(client: LightClient): void; private loadConfig; private shouldIgnore; + private shouldTracePropagate; + private isSameOrigin; + private getBaggageHeader; private shouldSample; + private createHttpSpan; + private finishHttpSpan; private patchFetch; private patchXHR; private reportNetwork; diff --git a/dist/plugins/PerformancePlugin.d.ts b/dist/plugins/PerformancePlugin.d.ts index 9b41493..c0bb48f 100644 --- a/dist/plugins/PerformancePlugin.d.ts +++ b/dist/plugins/PerformancePlugin.d.ts @@ -12,22 +12,30 @@ declare class PerformancePlugin implements LightPlugin { private lastLongTaskEndTime; private ttiReported; private ttiTimer; + private pageLoadTransaction; + private measurements; + private resourceSpanCount; setup(client: LightClient): void; + private startPageLoadTransaction; private loadConfig; private shouldSample; private observeWebVitals; - private observeFP; + private observePaint; private observeLCP; private observeFID; private observeCLS; - private observeFCP; private observeTTFB; private observeLongTasks; private scheduleTTI; private observeNavigation; + private buildNavigationSpans; + private finishPageLoadTransaction; private observeResources; private getRating; private reportMetric; + private recordMeasurement; + private createNavigationSpan; + private createResourceSpan; destroy(): void; } export default PerformancePlugin; diff --git a/dist/plugins/RouterPlugin.d.ts b/dist/plugins/RouterPlugin.d.ts new file mode 100644 index 0000000..1a483f1 --- /dev/null +++ b/dist/plugins/RouterPlugin.d.ts @@ -0,0 +1,26 @@ +import type { LightPlugin, LightClient } from '../types'; +declare class RouterPlugin implements LightPlugin { + name: string; + version: string; + private client; + private config; + private currentTransaction; + private lastRoute; + private originalPushState?; + private originalReplaceState?; + private maxDurationTimer; + private routeChangeTimer; + setup(client: LightClient): void; + private loadConfig; + private instrumentHistory; + private handlePopState; + private instrumentHash; + private handleHashChange; + private handleRouteChange; + private processRouteChange; + private startNavigationTransaction; + private startMaxDurationTimer; + private finishCurrentTransaction; + destroy(): void; +} +export default RouterPlugin; diff --git a/dist/types/index.d.ts b/dist/types/index.d.ts index ff2f17b..9e7e8d9 100644 --- a/dist/types/index.d.ts +++ b/dist/types/index.d.ts @@ -44,10 +44,31 @@ export interface DeviceContext { brand?: string; type?: string; } +export interface TraceContext { + trace_id: string; + span_id: string; + parent_span_id?: string; + op?: string; + status?: string; + description?: string; +} +export interface BaggageFields { + trace_id?: string; + public_key?: string; + sample_rate?: string; + sampled?: string; + user_id?: string; + user_segment?: string; + release?: string; + environment?: string; + replay_id?: string; + [key: string]: string | undefined; +} export interface Contexts { browser?: BrowserContext; os?: OSContext; device?: DeviceContext; + trace?: TraceContext; } export interface Breadcrumb { type: string; @@ -64,6 +85,7 @@ export interface BaseEvent { release?: string; environment?: string; user?: UserInfo; + anonymousId?: string; tags?: Record; extra?: Record; breadcrumbs?: Breadcrumb[]; @@ -111,7 +133,91 @@ export interface CountEvent extends BaseEvent { ts_start: number; ts_end: number; } -export type SentryEvent = ErrorEvent | PerformanceEvent | NetworkEvent | BehaviorEvent | CountEvent; +export type SpanStatus = 'ok' | 'cancelled' | 'unknown' | 'unknown_error' | 'invalid_argument' | 'deadline_exceeded' | 'not_found' | 'already_exists' | 'permission_denied' | 'resource_exhausted' | 'failed_precondition' | 'aborted' | 'out_of_range' | 'unimplemented' | 'internal_error' | 'unavailable' | 'data_loss' | 'unauthenticated'; +export interface SpanContext { + op?: string; + description?: string; + startTimestamp?: number; + status?: SpanStatus; + tags?: Record; + data?: Record; + traceId?: string; + spanId?: string; + parentSpanId?: string; + sampled?: boolean; +} +export interface SamplingContext extends TransactionContext { + parentSampled?: boolean; +} +export interface TransactionContext extends SpanContext { + name: string; + type?: string; +} +export interface SpanJSON { + trace_id: string; + span_id: string; + parent_span_id?: string; + op?: string; + description?: string; + status?: SpanStatus; + tags?: Record; + data?: Record; + start_timestamp: number; + timestamp: number; +} +export interface TransactionJSON extends SpanJSON { + transaction: string; + type?: string; + spans: SpanJSON[]; + sampled?: boolean; +} +export interface Span { + readonly traceId: string; + readonly spanId: string; + readonly parentSpanId?: string; + op?: string; + description?: string; + status?: SpanStatus; + tags: Record; + data: Record; + readonly startTimestamp: number; + readonly endTimestamp?: number; + readonly transaction?: Transaction; + setTag(key: string, value: string): this; + setData(key: string, value: unknown): this; + setStatus(status: SpanStatus): this; + setHttpStatus(statusCode: number): this; + setStatusFromResponse(status: string | number | undefined, tagKey?: string): this; + startChild(context?: SpanContext): Span; + finish(endTimestamp?: number): void; + toTraceparent(): string; + toJSON(): SpanJSON; +} +export interface Transaction extends Omit { + name: string; + type?: string; + spans: Span[]; + sampled?: boolean; + maxSpans?: number; + toJSON(): TransactionJSON; + toEvent(): TransactionEvent; +} +export interface MeasurementValue { + value: number; + unit?: string; + rating?: 'good' | 'needs-improvement' | 'poor'; +} +export interface TransactionEvent extends BaseEvent { + type: 'transaction'; + transaction: string; + transaction_info?: { + source: string; + }; + spans: Array>; + start_timestamp: number; + measurements?: Record; +} +export type SentryEvent = ErrorEvent | PerformanceEvent | NetworkEvent | BehaviorEvent | CountEvent | TransactionEvent; export interface DSNInfo { protocol: string; publicKey: string; @@ -134,6 +240,13 @@ export interface LightConfig { enabled?: boolean; debug?: boolean; sampleRate?: number; + tracesSampleRate?: number; + tracesSampler?: (context: SamplingContext) => number | boolean; + /** + * @deprecated 请使用 tracePropagationTargets 替代 + */ + tracingOrigins?: (string | RegExp)[]; + tracePropagationTargets?: (string | RegExp)[]; maxQueueSize?: number; flushInterval?: number; maxRetries?: number; @@ -144,6 +257,7 @@ export interface LightConfig { maxBreadcrumbs?: number; beforeSend?: (event: SentryEvent) => SentryEvent | null; user?: UserInfo; + trackAnonymousUsers?: boolean; plugins?: (LightPlugin | string)[]; contextLevel?: Partial; sampling?: SamplingConfig; @@ -169,10 +283,16 @@ export interface LightClient { type: string; }): void; setUser(user: UserInfo | null): void; + setAnonymousId(id: string): void; setTag(key: string, value: string): void; setTags(tags: Record): void; setExtra(key: string, value: unknown): void; addBreadcrumb(breadcrumb: Omit): void; + startTransaction(context: TransactionContext): Transaction | null; + getCurrentTransaction(): Transaction | null; + getCurrentSpan(): Span | null; + setSpan(span: Span | null): void; + startSpan(context: SpanContext): Span | null; flush(): Promise; disable(): void; enable(): void; diff --git a/dist/utils/baggage.d.ts b/dist/utils/baggage.d.ts new file mode 100644 index 0000000..1b5e9dc --- /dev/null +++ b/dist/utils/baggage.d.ts @@ -0,0 +1,14 @@ +import type { BaggageFields } from '../types'; +export declare function serializeBaggage(fields: BaggageFields): string; +export declare function parseBaggage(header: string): BaggageFields; +export declare function createBaggageFromTransaction(traceId: string, options?: { + dsnPublicKey?: string; + sampled?: boolean; + sampleRate?: number; + user?: { + id?: string; + segment?: string; + }; + release?: string; + environment?: string; +}): BaggageFields; diff --git a/dist/utils/identity.d.ts b/dist/utils/identity.d.ts new file mode 100644 index 0000000..de00ed3 --- /dev/null +++ b/dist/utils/identity.d.ts @@ -0,0 +1,21 @@ +/** + * 获取匿名用户ID + * 优先从 localStorage 获取已存在的ID,不存在则生成并存储 + */ +export declare function getAnonymousId(): string | null; +/** + * 设置匿名用户ID + * 用于覆盖自动生成的ID + */ +export declare function setAnonymousId(id: string): boolean; +/** + * 清除匿名用户ID + * 通常在用户登出后调用 + */ +export declare function clearAnonymousId(): boolean; +/** + * 检查是否启用了匿名用户追踪 + */ +export declare function isAnonymousTrackingEnabled(config: { + trackAnonymousUsers?: boolean; +}): boolean; diff --git a/dist/utils/tracing.d.ts b/dist/utils/tracing.d.ts new file mode 100644 index 0000000..1ae0bab --- /dev/null +++ b/dist/utils/tracing.d.ts @@ -0,0 +1,148 @@ +import type { Span as SpanInterface, SpanContext, Transaction as TransactionInterface, TransactionContext, SpanStatus, LightClient, BaggageFields } from '../types'; +declare function generateTraceId(): string; +declare function generateSpanId(): string; +export declare function httpStatusToSpanStatus(statusCode: number): SpanStatus; +export declare function dbStatusToSpanStatus(dbStatusCode?: string | number): SpanStatus; +export declare function statusToSpanStatus(status: string | number | undefined, op: string | undefined): SpanStatus; +export declare class Span implements SpanInterface { + readonly traceId: string; + readonly spanId: string; + readonly parentSpanId?: string; + op?: string; + description?: string; + status?: SpanStatus; + tags: Record; + data: Record; + readonly startTimestamp: number; + endTimestamp?: number; + transaction?: TransactionInterface; + protected _isFinished: boolean; + protected _client?: LightClient; + constructor(context: SpanContext, transaction?: TransactionInterface, client?: LightClient); + setTag(key: string, value: string): this; + setData(key: string, value: unknown): this; + setStatus(status: SpanStatus): this; + setHttpStatus(statusCode: number): this; + setStatusFromResponse(status: string | number | undefined, tagKey?: string): this; + startChild(context?: SpanContext): Span; + finish(endTimestamp?: number): void; + toTraceparent(): string; + toJSON(): { + trace_id: string; + span_id: string; + parent_span_id: string; + op: string; + description: string; + status: SpanStatus; + tags: { + [x: string]: string; + }; + data: { + [x: string]: unknown; + }; + start_timestamp: number; + timestamp: number; + }; +} +export declare class Transaction extends Span implements TransactionInterface { + name: string; + type?: string; + spans: Span[]; + sampled?: boolean; + maxSpans: number; + private _baggage?; + private _dsnPublicKey?; + private _release?; + private _environment?; + private _droppedSpans; + constructor(context: TransactionContext, client?: LightClient, dsnPublicKey?: string, release?: string, environment?: string, maxSpans?: number); + _addSpan(span: Span): void; + private _ensureBaggage; + setBaggage(key: string, value: string): this; + setUserBaggage(userId?: string, segment?: string): this; + toBaggage(): string | undefined; + getBaggage(): BaggageFields | undefined; + finish(endTimestamp?: number): void; + private _getSource; + toEvent(): { + type: "transaction"; + transaction: string; + transaction_info: { + source: string; + }; + level: "info"; + timestamp: number; + start_timestamp: number; + spans: { + trace_id: string; + span_id: string; + parent_span_id: string; + op: string; + description: string; + status: SpanStatus; + tags: { + [x: string]: string; + }; + data: { + [x: string]: unknown; + }; + start_timestamp: number; + timestamp: number; + }[]; + contexts: { + trace: { + trace_id: string; + span_id: string; + parent_span_id: string; + op: string; + status: SpanStatus; + }; + }; + tags: { + [x: string]: string; + }; + extra: Record; + measurements: Record; + platform: string; + }; + toJSON(): { + transaction: string; + type: string; + spans: { + trace_id: string; + span_id: string; + parent_span_id: string; + op: string; + description: string; + status: SpanStatus; + tags: { + [x: string]: string; + }; + data: { + [x: string]: unknown; + }; + start_timestamp: number; + timestamp: number; + }[]; + sampled: boolean; + trace_id: string; + span_id: string; + parent_span_id: string; + op: string; + description: string; + status: SpanStatus; + tags: { + [x: string]: string; + }; + data: { + [x: string]: unknown; + }; + start_timestamp: number; + timestamp: number; + }; +} +export { generateTraceId, generateSpanId }; diff --git a/docs/07-tracing.md b/docs/07-tracing.md new file mode 100644 index 0000000..cacea15 --- /dev/null +++ b/docs/07-tracing.md @@ -0,0 +1,348 @@ +# 分布式追踪(Distributed Tracing)设计文档 + +## 一、背景与目标 + +### 1.1 背景 +当前 SDK 已支持错误采集、性能指标(Web Vitals)、网络请求监控、用户行为采集等能力,但缺乏**前后端链路打通**的分布式追踪能力。当用户遇到"接口慢"或"报错"时,无法关联前端操作与后端服务的内部调用链路,排查问题效率低。 + +### 1.2 目标 +- **第一阶段(P0)**:实现 Trace/Span 核心模型 + 前后端 Trace 传播 + 手动 API +- **第二阶段(P1)**:自动 Instrumentation(Page Load、路由变化、用户交互) +- **第三阶段(P2)**:采样策略升级 + Baggage 支持 + 完整开发者体验 + +--- + +## 二、核心概念 + +### 2.1 Trace +一条完整的分布式调用链路,全局唯一 `trace_id` 标识。一条 Trace 跨越多个服务、多个进程。 + +### 2.2 Transaction +Trace 中的"根 Span",代表一个完整的用户操作或业务流程。前端常见的 Transaction 类型: +- `pageload`:页面加载 +- `navigation`:路由切换(SPA) +- `user-interaction`:用户交互(点击、提交等) +- `custom`:自定义事务 + +### 2.3 Span +Transaction 中的具体操作步骤,有父子关系。常见 Span 类型: +- `http`:HTTP 请求 +- `resource`:资源加载 +- `browser`:浏览器内部操作(DOM 解析、脚本执行等) +- `db`:数据库查询(后端) +- `middleware`:中间件(后端) + +### 2.4 Span 关系 +``` +Trace (trace_id = abc123) + └── Transaction: "page-load" (span_id = s1) + ├── Span: "http GET /api/user" (span_id = s2, parent = s1) + │ └── 后端服务的多个 Span(通过 trace header 关联) + ├── Span: "resource /static/app.js" (span_id = s3, parent = s1) + └── Span: "dom-parse" (span_id = s4, parent = s1) +``` + +--- + +## 三、数据模型设计 + +### 3.1 Span 接口 +```typescript +interface Span { + trace_id: string; // 16/32 位十六进制,全局唯一 + span_id: string; // 16 位十六进制,Span 唯一 + parent_span_id?: string; // 父 Span ID + op?: string; // 操作类型:http、resource、browser 等 + description?: string; // 描述信息 + start_timestamp: number; // 开始时间(毫秒时间戳) + timestamp: number; // 结束时间(毫秒时间戳) + status?: SpanStatus; // 状态 + tags?: Record; // 标签 + data?: Record; // 附加数据 + same_process_as_parent?: boolean; +} + +type SpanStatus = + | 'ok' + | 'cancelled' + | 'unknown' + | 'invalid_argument' + | 'deadline_exceeded' + | 'not_found' + | 'already_exists' + | 'permission_denied' + | 'resource_exhausted' + | 'failed_precondition' + | 'aborted' + | 'out_of_range' + | 'unimplemented' + | 'internal_error' + | 'unavailable' + | 'data_loss' + | 'unauthenticated'; +``` + +### 3.2 Transaction 接口 +```typescript +interface Transaction extends Span { + name: string; // 事务名称(如 "GET /api/users") + spans: Span[]; // 子 Span 列表 + transaction: string; // 事务名称冗余字段 + type?: string; // 事务类型:page-load、navigation 等 + sampled?: boolean; // 是否采样 +} +``` + +### 3.3 上报事件类型 +新增 `transaction` 事件类型: +```typescript +interface TransactionEvent extends BaseEvent { + type: 'transaction'; + transaction: string; + spans: Span[]; + start_timestamp: number; + timestamp: number; + // ... +} +``` + +--- + +## 四、前后端 Trace 传播 + +### 4.1 协议选择 +采用 **Sentry Trace 协议**(`sentry-trace` header),同时支持 W3C Trace Context 作为兼容。 + +### 4.2 sentry-trace Header 格式 +``` +sentry-trace: {trace_id}-{span_id}-{sampled} +``` +- `trace_id`: 32 位十六进制字符串 +- `span_id`: 16 位十六进制字符串 +- `sampled`: 可选,`1` = 采样,`0` = 不采样 + +示例: +``` +sentry-trace: 8839b8a3914c485bb1f52ce3c08c9c0b-b89e261f348c022b-1 +``` + +### 4.3 baggage Header(后续阶段) +``` +baggage: sentry-trace_id=xxx,sentry-public_key=xxx,sentry-sample_rate=1.0 +``` + +### 4.4 追踪域名白名单 +为避免向第三方接口泄漏 trace 信息,需要配置 `tracingOrigins`: +```typescript +LightSentry.init({ + dsn: '...', + tracingOrigins: [ + 'api.example.com', + /^https:\/\/internal\./, + 'localhost', + ], +}); +``` +默认匹配同源域名。 + +--- + +## 五、核心模块设计 + +### 5.1 TracingManager +职责: +- 维护当前活跃的 Transaction +- 维护 Span 栈(当前执行上下文) +- 生成 trace_id / span_id +- 管理 Span 的父子关系 + +关键方法: +```typescript +class TracingManager { + startTransaction(context: TransactionContext): Transaction; + getCurrentTransaction(): Transaction | null; + setCurrentTransaction(transaction: Transaction | null): void; + startSpan(context: SpanContext): Span | null; + getCurrentSpan(): Span | null; + finishSpan(span: Span): void; +} +``` + +### 5.2 Span 类 +```typescript +class Span { + traceId: string; + spanId: string; + parentSpanId?: string; + op?: string; + description?: string; + startTimestamp: number; + endTimestamp?: number; + status?: string; + tags: Record; + data: Record; + + setTag(key: string, value: string): this; + setData(key: string, value: unknown): this; + setStatus(status: string): this; + startChild(context: SpanContext): Span; + finish(endTimestamp?: number): void; + toJSON(): Span; + toTraceparent(): string; // 生成 sentry-trace header 值 +} +``` + +### 5.3 Transaction 类 +```typescript +class Transaction extends Span { + name: string; + spans: Span[]; + type?: string; + sampled?: boolean; + + finish(endTimestamp?: number): void; + toJSON(): Transaction; +} +``` + +--- + +## 六、插件改造 + +### 6.1 NetworkPlugin 改造 + +**改造前**:上报独立的 `network` 事件 +**改造后**:创建 `http` Span,关联到当前 Transaction,并注入 trace header + +具体改动: +1. 请求开始时,如果存在活跃 Transaction,创建 Span +2. 向匹配的域名注入 `sentry-trace` header +3. 请求结束时,设置 Span status 和 data,finish Span +4. 保持原有 `network` 事件上报(兼容) + +### 6.2 PerformancePlugin 改造(第二阶段) + +改造为 Page Load Transaction: +- Navigation Timing → 拆解为多个 Span +- Resource Timing → 作为 resource Span +- Web Vitals → 作为标记点或 measurement + +### 6.3 新增 RouterPlugin(第二阶段) + +监听路由变化: +- History API(pushState / replaceState / popstate) +- hashchange +- 每次路由变化创建新的 navigation Transaction + +--- + +## 七、对外 API + +### 7.1 顶层 API +```typescript +// 开始事务 +LightSentry.startTransaction({ + name: 'search-products', + op: 'user-interaction', +}); + +// 获取当前 Span +const span = LightSentry.getCurrentSpan(); + +// 创建子 Span(基于当前活跃 Span) +const childSpan = LightSentry.startSpan({ + op: 'http', + description: 'GET /api/search', +}); + +// 手动设置 Span +LightSentry.setSpan(span); +``` + +### 7.2 配置项 +```typescript +interface LightConfig { + // ... + tracesSampleRate?: number; // 全局 Trace 采样率 0~1,默认 0 + tracesSampler?: (context: any) => number; // 动态采样函数 + tracingOrigins?: (string | RegExp)[]; // 追踪域名白名单 + tracePropagationTargets?: (string | RegExp)[]; // trace header 传播目标 +} +``` + +--- + +## 八、采样策略(第一阶段简化版) + +第一阶段采用简单策略: +1. 配置 `tracesSampleRate`(默认 0 = 关闭) +2. Transaction 创建时决定是否采样 +3. 采样决策通过 `sentry-trace` 的 `sampled` 标志传递给后端 +4. 未采样的 Transaction 不上报,但仍传递 trace_id(用于关联) + +--- + +## 九、实施计划 + +### 第一阶段:核心能力(已完成) +- [x] 设计文档 +- [x] 新增 Trace/Span 类型定义 +- [x] 实现 Span 类 +- [x] 实现 Transaction 类 +- [x] 实现 TracingManager +- [x] 改造 NetworkPlugin(注入 trace header + 创建 HTTP Span) +- [x] 对外暴露 startTransaction / startSpan API +- [x] 集成到 Client +- [x] 编译验证 +- [x] 错误事件自动关联 Trace 上下文 +- [x] Transaction 完成后自动上报 +- [x] Span 栈生命周期管理 +- [x] 未采样 Transaction 不收集 Span(性能优化) + +### 第二阶段:自动 Instrumentation(已完成) +- [x] PerformancePlugin 改造:Page Load Transaction + - [x] Navigation Timing 拆解为 browser.* Span 树 + - [x] Resource Timing 转为 resource.* Span + - [x] Web Vitals 作为 measurements 附加到 Transaction + - [x] LCP/FP/FCP 等关键指标标记 +- [x] 新增 RouterPlugin(路由变化追踪) + - [x] History API 监听(pushState / replaceState / popstate) + - [x] Hash 路由监听(hashchange) + - [x] 路由切换期间的 Span 自动关联 +- [x] 新增 InteractionPlugin(用户交互追踪) + - [x] 点击/表单提交等交互自动创建 Transaction + - [x] 交互期间的网络请求自动关联 +- [x] Error 与 Trace 深度集成 + - [x] 错误事件自动附加 contexts.trace + - [ ] 错误作为 error Span 加入当前 Transaction(可选) + +### 第三阶段:进阶能力(已完成) +- [x] Baggage header 支持 + - [x] Transaction 携带 user、release 等信息 + - [x] NetworkPlugin 自动注入 baggage header + - [x] 后端可以读取 baggage 传递的信息 +- [x] 动态采样 tracesSampler 实现 + - [x] tracesSampler 函数支持 + - [x] 根据 transaction 上下文动态决定采样率 +- [x] 完整 Span Status 映射增强 + - [x] 数据库操作状态映射(dbStatusToSpanStatus) + - [x] 自定义操作状态映射(statusToSpanStatus) + - [x] Span status 与 error 关联(setStatusFromResponse) +- [x] 错误作为 error Span 加入 Transaction(可选功能) + +--- + +## 十、兼容性考虑 + +1. **向后兼容**:默认 `tracesSampleRate = 0`,即默认关闭,不影响现有功能 +2. **事件类型新增**:新增 `transaction` 事件类型,后端需支持 +3. **NetworkPlugin**:保持原有 `network` 事件上报,同时新增 Span(可配置开关) +4. **浏览器兼容性**:不依赖新 API,使用现有能力实现 + +--- + +## 十一、参考资料 + +- [Sentry Tracing 文档](https://docs.sentry.io/product/sentry-basics/concepts/tracing/) +- [Sentry Performance 数据模型](https://develop.sentry.dev/sdk/performance/) +- [W3C Trace Context](https://www.w3.org/TR/trace-context/) diff --git a/package-lock.json b/package-lock.json index 42c900e..e9b9031 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,12 +9,27 @@ "version": "0.1.0", "license": "MIT", "devDependencies": { + "@vitest/coverage-v8": "^1.6.0", "esbuild": "^0.20.0", "jsdom": "^24.0.0", "typescript": "^5.4.0", "vitest": "^1.4.0" } }, + "node_modules/@ampproject/remapping": { + "version": "2.3.0", + "resolved": "https://registry.npmmirror.com/@ampproject/remapping/-/remapping-2.3.0.tgz", + "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, "node_modules/@asamuzakjp/css-color": { "version": "3.2.0", "resolved": "https://registry.npmmirror.com/@asamuzakjp/css-color/-/css-color-3.2.0.tgz", @@ -29,6 +44,63 @@ "lru-cache": "^10.4.3" } }, + "node_modules/@babel/helper-string-parser": { + "version": "7.29.7", + "resolved": "https://registry.npmmirror.com/@babel/helper-string-parser/-/helper-string-parser-7.29.7.tgz", + "integrity": "sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.29.7", + "resolved": "https://registry.npmmirror.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.29.7.tgz", + "integrity": "sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.29.7", + "resolved": "https://registry.npmmirror.com/@babel/parser/-/parser-7.29.7.tgz", + "integrity": "sha512-hnORnjP/1P/zFEndoeX+n+t1RwWRJiJpM/jO7FW32Kn9r5+sJB2JWOdYo4L6k78j15eCwY3Gm/7364B1EMwtNg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.29.7" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/types": { + "version": "7.29.7", + "resolved": "https://registry.npmmirror.com/@babel/types/-/types-7.29.7.tgz", + "integrity": "sha512-4zBIxpPzowiZpusoFkyGVwakdRJUyuH5PxQ/PrqghfdFWWasvnCdPfQXHrenDai+gyLARulZjZowCOj6fjT4pA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.29.7", + "@babel/helper-validator-identifier": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@bcoe/v8-coverage": { + "version": "0.2.3", + "resolved": "https://registry.npmmirror.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", + "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", + "dev": true, + "license": "MIT" + }, "node_modules/@csstools/color-helpers": { "version": "5.1.0", "resolved": "https://registry.npmmirror.com/@csstools/color-helpers/-/color-helpers-5.1.0.tgz", @@ -535,6 +607,16 @@ "node": ">=12" } }, + "node_modules/@istanbuljs/schema": { + "version": "0.1.6", + "resolved": "https://registry.npmmirror.com/@istanbuljs/schema/-/schema-0.1.6.tgz", + "integrity": "sha512-+Sg6GCR/wy1oSmQDFq4LQDAhm3ETKnorxN+y5nbLULOR3P0c14f2Wurzj3/xqPXtasLFfHd5iRFQ7AJt4KH2cw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/@jest/schemas": { "version": "29.6.3", "resolved": "https://registry.npmmirror.com/@jest/schemas/-/schemas-29.6.3.tgz", @@ -548,6 +630,27 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.13", + "resolved": "https://registry.npmmirror.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", + "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmmirror.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, "node_modules/@jridgewell/sourcemap-codec": { "version": "1.5.5", "resolved": "https://registry.npmmirror.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", @@ -555,6 +658,17 @@ "dev": true, "license": "MIT" }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.31", + "resolved": "https://registry.npmmirror.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, "node_modules/@rollup/rollup-android-arm-eabi": { "version": "4.62.2", "resolved": "https://registry.npmmirror.com/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.62.2.tgz", @@ -919,15 +1033,43 @@ "dev": true, "license": "MIT" }, - "node_modules/@vitest/expect": { - "version": "1.6.1", - "resolved": "https://registry.npmmirror.com/@vitest/expect/-/expect-1.6.1.tgz", - "integrity": "sha512-jXL+9+ZNIJKruofqXuuTClf44eSpcHlgj3CiuNihUF3Ioujtmc0zIa3UJOW5RjDK1YLBJZnWBlPuqhYycLioog==", + "node_modules/@vitest/coverage-v8": { + "version": "1.6.0", + "resolved": "https://registry.npmmirror.com/@vitest/coverage-v8/-/coverage-v8-1.6.0.tgz", + "integrity": "sha512-KvapcbMY/8GYIG0rlwwOKCVNRc0OL20rrhFkg/CHNzncV03TE2XWvO5w9uZYoxNiMEBacAJt3unSOiZ7svePew==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/spy": "1.6.1", - "@vitest/utils": "1.6.1", + "@ampproject/remapping": "^2.2.1", + "@bcoe/v8-coverage": "^0.2.3", + "debug": "^4.3.4", + "istanbul-lib-coverage": "^3.2.2", + "istanbul-lib-report": "^3.0.1", + "istanbul-lib-source-maps": "^5.0.4", + "istanbul-reports": "^3.1.6", + "magic-string": "^0.30.5", + "magicast": "^0.3.3", + "picocolors": "^1.0.0", + "std-env": "^3.5.0", + "strip-literal": "^2.0.0", + "test-exclude": "^6.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "vitest": "1.6.0" + } + }, + "node_modules/@vitest/expect": { + "version": "1.6.0", + "resolved": "https://registry.npmmirror.com/@vitest/expect/-/expect-1.6.0.tgz", + "integrity": "sha512-ixEvFVQjycy/oNgHjqsL6AZCDduC+tflRluaHIzKIsdbzkLn2U/iBnVeJwB6HsIjQBdfMR8Z0tRxKUsvFJEeWQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/spy": "1.6.0", + "@vitest/utils": "1.6.0", "chai": "^4.3.10" }, "funding": { @@ -935,13 +1077,13 @@ } }, "node_modules/@vitest/runner": { - "version": "1.6.1", - "resolved": "https://registry.npmmirror.com/@vitest/runner/-/runner-1.6.1.tgz", - "integrity": "sha512-3nSnYXkVkf3mXFfE7vVyPmi3Sazhb/2cfZGGs0JRzFsPFvAMBEcrweV1V1GsrstdXeKCTXlJbvnQwGWgEIHmOA==", + "version": "1.6.0", + "resolved": "https://registry.npmmirror.com/@vitest/runner/-/runner-1.6.0.tgz", + "integrity": "sha512-P4xgwPjwesuBiHisAVz/LSSZtDjOTPYZVmNAnpHHSR6ONrf8eCJOFRvUwdHn30F5M1fxhqtl7QZQUk2dprIXAg==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/utils": "1.6.1", + "@vitest/utils": "1.6.0", "p-limit": "^5.0.0", "pathe": "^1.1.1" }, @@ -950,9 +1092,9 @@ } }, "node_modules/@vitest/snapshot": { - "version": "1.6.1", - "resolved": "https://registry.npmmirror.com/@vitest/snapshot/-/snapshot-1.6.1.tgz", - "integrity": "sha512-WvidQuWAzU2p95u8GAKlRMqMyN1yOJkGHnx3M1PL9Raf7AQ1kwLKg04ADlCa3+OXUZE7BceOhVZiuWAbzCKcUQ==", + "version": "1.6.0", + "resolved": "https://registry.npmmirror.com/@vitest/snapshot/-/snapshot-1.6.0.tgz", + "integrity": "sha512-+Hx43f8Chus+DCmygqqfetcAZrDJwvTj0ymqjQq4CvmpKFSTVteEOBzCusu1x2tt4OJcvBflyHUE0DZSLgEMtQ==", "dev": true, "license": "MIT", "dependencies": { @@ -965,9 +1107,9 @@ } }, "node_modules/@vitest/spy": { - "version": "1.6.1", - "resolved": "https://registry.npmmirror.com/@vitest/spy/-/spy-1.6.1.tgz", - "integrity": "sha512-MGcMmpGkZebsMZhbQKkAf9CX5zGvjkBTqf8Zx3ApYWXr3wG+QvEu2eXWfnIIWYSJExIp4V9FCKDEeygzkYrXMw==", + "version": "1.6.0", + "resolved": "https://registry.npmmirror.com/@vitest/spy/-/spy-1.6.0.tgz", + "integrity": "sha512-leUTap6B/cqi/bQkXUu6bQV5TZPx7pmMBKBQiI0rJA8c3pB56ZsaTbREnF7CJfmvAS4V2cXIBAh/3rVwrrCYgw==", "dev": true, "license": "MIT", "dependencies": { @@ -978,9 +1120,9 @@ } }, "node_modules/@vitest/utils": { - "version": "1.6.1", - "resolved": "https://registry.npmmirror.com/@vitest/utils/-/utils-1.6.1.tgz", - "integrity": "sha512-jOrrUvXM4Av9ZWiG1EajNto0u96kWAhJ1LmPmJhXXQx/32MecEKd10pOLYgS2BQx1TgkGhloPU1ArDW2vvaY6g==", + "version": "1.6.0", + "resolved": "https://registry.npmmirror.com/@vitest/utils/-/utils-1.6.0.tgz", + "integrity": "sha512-21cPiuGMoMZwiOHa2i4LXkMkMkCGzA+MVFV70jRwHo95dL4x/ts5GZhML1QWuy7yfp3WzK3lRvZi3JnXTYqrBw==", "dev": true, "license": "MIT", "dependencies": { @@ -1059,6 +1201,24 @@ "dev": true, "license": "MIT" }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmmirror.com/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/brace-expansion": { + "version": "1.1.15", + "resolved": "https://registry.npmmirror.com/brace-expansion/-/brace-expansion-1.1.15.tgz", + "integrity": "sha512-EwOCDEex4quD37XhqM3omwtMoJjr//isUZz1JopUNWms+4Z2ViyM/k1YIRePpoVNnQhENnxtFjLaxNHrT7xIUg==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, "node_modules/cac": { "version": "6.7.14", "resolved": "https://registry.npmmirror.com/cac/-/cac-6.7.14.tgz", @@ -1128,6 +1288,13 @@ "node": ">= 0.8" } }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmmirror.com/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true, + "license": "MIT" + }, "node_modules/confbox": { "version": "0.1.8", "resolved": "https://registry.npmmirror.com/confbox/-/confbox-0.1.8.tgz", @@ -1410,6 +1577,13 @@ "node": ">= 6" } }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmmirror.com/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true, + "license": "ISC" + }, "node_modules/fsevents": { "version": "2.3.3", "resolved": "https://registry.npmmirror.com/fsevents/-/fsevents-2.3.3.tgz", @@ -1497,6 +1671,28 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmmirror.com/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "dev": true, + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/gopd": { "version": "1.2.0", "resolved": "https://registry.npmmirror.com/gopd/-/gopd-1.2.0.tgz", @@ -1510,6 +1706,16 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmmirror.com/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/has-symbols": { "version": "1.1.0", "resolved": "https://registry.npmmirror.com/has-symbols/-/has-symbols-1.1.0.tgz", @@ -1565,6 +1771,13 @@ "node": ">=18" } }, + "node_modules/html-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmmirror.com/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", + "dev": true, + "license": "MIT" + }, "node_modules/http-proxy-agent": { "version": "7.0.2", "resolved": "https://registry.npmmirror.com/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", @@ -1616,6 +1829,25 @@ "node": ">=0.10.0" } }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmmirror.com/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", + "dev": true, + "license": "ISC", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmmirror.com/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true, + "license": "ISC" + }, "node_modules/is-potential-custom-element-name": { "version": "1.0.1", "resolved": "https://registry.npmmirror.com/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", @@ -1643,6 +1875,60 @@ "dev": true, "license": "ISC" }, + "node_modules/istanbul-lib-coverage": { + "version": "3.2.2", + "resolved": "https://registry.npmmirror.com/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", + "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-report": { + "version": "3.0.1", + "resolved": "https://registry.npmmirror.com/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", + "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^4.0.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-source-maps": { + "version": "5.0.6", + "resolved": "https://registry.npmmirror.com/istanbul-lib-source-maps/-/istanbul-lib-source-maps-5.0.6.tgz", + "integrity": "sha512-yg2d+Em4KizZC5niWhQaIomgf5WlL4vOOjZ5xGCmF8SnPE/mDWWXgvRExdcpCgh9lLRRa1/fSYp2ymmbJ1pI+A==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.23", + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-reports": { + "version": "3.2.0", + "resolved": "https://registry.npmmirror.com/istanbul-reports/-/istanbul-reports-3.2.0.tgz", + "integrity": "sha512-HGYWWS/ehqTV3xN10i23tkPkpH46MLCIMFNCaaKNavAXTF1RkqxawEPtnjnGZ6XKSInBKkiOA5BKS+aZiY3AvA==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/js-tokens": { "version": "9.0.1", "resolved": "https://registry.npmmirror.com/js-tokens/-/js-tokens-9.0.1.tgz", @@ -1735,6 +2021,34 @@ "@jridgewell/sourcemap-codec": "^1.5.5" } }, + "node_modules/magicast": { + "version": "0.3.5", + "resolved": "https://registry.npmmirror.com/magicast/-/magicast-0.3.5.tgz", + "integrity": "sha512-L0WhttDl+2BOsybvEOLK7fW3UA0OQ0IQ2d6Zl2x/a6vVRs3bAY0ECOSHHeL5jD+SbOpOCUEi0y1DgHEn9Qn1AQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.25.4", + "@babel/types": "^7.25.4", + "source-map-js": "^1.2.0" + } + }, + "node_modules/make-dir": { + "version": "4.0.0", + "resolved": "https://registry.npmmirror.com/make-dir/-/make-dir-4.0.0.tgz", + "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", + "dev": true, + "license": "MIT", + "dependencies": { + "semver": "^7.5.3" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/math-intrinsics": { "version": "1.1.0", "resolved": "https://registry.npmmirror.com/math-intrinsics/-/math-intrinsics-1.1.0.tgz", @@ -1788,6 +2102,19 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/minimatch": { + "version": "3.1.5", + "resolved": "https://registry.npmmirror.com/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, "node_modules/mlly": { "version": "1.8.2", "resolved": "https://registry.npmmirror.com/mlly/-/mlly-1.8.2.tgz", @@ -1870,6 +2197,16 @@ "dev": true, "license": "MIT" }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmmirror.com/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "license": "ISC", + "dependencies": { + "wrappy": "1" + } + }, "node_modules/onetime": { "version": "6.0.0", "resolved": "https://registry.npmmirror.com/onetime/-/onetime-6.0.0.tgz", @@ -1915,6 +2252,16 @@ "url": "https://github.com/inikulin/parse5?sponsor=1" } }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmmirror.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/path-key": { "version": "3.1.1", "resolved": "https://registry.npmmirror.com/path-key/-/path-key-3.1.1.tgz", @@ -2128,6 +2475,19 @@ "node": ">=v12.22.7" } }, + "node_modules/semver": { + "version": "7.8.5", + "resolved": "https://registry.npmmirror.com/semver/-/semver-7.8.5.tgz", + "integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmmirror.com/shebang-command/-/shebang-command-2.0.0.tgz", @@ -2221,6 +2581,19 @@ "url": "https://github.com/sponsors/antfu" } }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmmirror.com/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/symbol-tree": { "version": "3.2.4", "resolved": "https://registry.npmmirror.com/symbol-tree/-/symbol-tree-3.2.4.tgz", @@ -2228,6 +2601,21 @@ "dev": true, "license": "MIT" }, + "node_modules/test-exclude": { + "version": "6.0.0", + "resolved": "https://registry.npmmirror.com/test-exclude/-/test-exclude-6.0.0.tgz", + "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", + "dev": true, + "license": "ISC", + "dependencies": { + "@istanbuljs/schema": "^0.1.2", + "glob": "^7.1.4", + "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/tinybench": { "version": "2.9.0", "resolved": "https://registry.npmmirror.com/tinybench/-/tinybench-2.9.0.tgz", @@ -2397,9 +2785,9 @@ } }, "node_modules/vite-node": { - "version": "1.6.1", - "resolved": "https://registry.npmmirror.com/vite-node/-/vite-node-1.6.1.tgz", - "integrity": "sha512-YAXkfvGtuTzwWbDSACdJSg4A4DZiAqckWe90Zapc/sEX3XvHcw1NdurM/6od8J207tSDqNbSsgdCacBgvJKFuA==", + "version": "1.6.0", + "resolved": "https://registry.npmmirror.com/vite-node/-/vite-node-1.6.0.tgz", + "integrity": "sha512-de6HJgzC+TFzOu0NTC4RAIsyf/DY/ibWDYQUcuEA84EMHhcefTUGkjFHKKEJhQN4A+6I0u++kr3l36ZF2d7XRw==", "dev": true, "license": "MIT", "dependencies": { @@ -2850,17 +3238,17 @@ } }, "node_modules/vitest": { - "version": "1.6.1", - "resolved": "https://registry.npmmirror.com/vitest/-/vitest-1.6.1.tgz", - "integrity": "sha512-Ljb1cnSJSivGN0LqXd/zmDbWEM0RNNg2t1QW/XUhYl/qPqyu7CsqeWtqQXHVaJsecLPuDoak2oJcZN2QoRIOag==", + "version": "1.6.0", + "resolved": "https://registry.npmmirror.com/vitest/-/vitest-1.6.0.tgz", + "integrity": "sha512-H5r/dN06swuFnzNFhq/dnz37bPXnq8xB2xB5JOVk8K09rUtoeNN+LHWkoQ0A/i3hvbUKKcCei9KpbxqHMLhLLA==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/expect": "1.6.1", - "@vitest/runner": "1.6.1", - "@vitest/snapshot": "1.6.1", - "@vitest/spy": "1.6.1", - "@vitest/utils": "1.6.1", + "@vitest/expect": "1.6.0", + "@vitest/runner": "1.6.0", + "@vitest/snapshot": "1.6.0", + "@vitest/spy": "1.6.0", + "@vitest/utils": "1.6.0", "acorn-walk": "^8.3.2", "chai": "^4.3.10", "debug": "^4.3.4", @@ -2874,7 +3262,7 @@ "tinybench": "^2.5.1", "tinypool": "^0.8.3", "vite": "^5.0.0", - "vite-node": "1.6.1", + "vite-node": "1.6.0", "why-is-node-running": "^2.2.2" }, "bin": { @@ -2889,8 +3277,8 @@ "peerDependencies": { "@edge-runtime/vm": "*", "@types/node": "^18.0.0 || >=20.0.0", - "@vitest/browser": "1.6.1", - "@vitest/ui": "1.6.1", + "@vitest/browser": "1.6.0", + "@vitest/ui": "1.6.0", "happy-dom": "*", "jsdom": "*" }, @@ -3009,6 +3397,13 @@ "node": ">=8" } }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmmirror.com/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true, + "license": "ISC" + }, "node_modules/ws": { "version": "8.21.0", "resolved": "https://registry.npmmirror.com/ws/-/ws-8.21.0.tgz", diff --git a/package.json b/package.json index cd5ba1e..a514e67 100644 --- a/package.json +++ b/package.json @@ -26,6 +26,7 @@ "author": "", "license": "MIT", "devDependencies": { + "@vitest/coverage-v8": "^1.6.0", "esbuild": "^0.20.0", "jsdom": "^24.0.0", "typescript": "^5.4.0", diff --git a/src/core/Client.ts b/src/core/Client.ts index c4827ea..ad4d340 100644 --- a/src/core/Client.ts +++ b/src/core/Client.ts @@ -1,14 +1,16 @@ -import type { LightConfig, LightClient, LightPlugin, DSNInfo, SentryEvent, EventLevel, UserInfo, Breadcrumb, ErrorEvent } from '../types'; +import type { LightConfig, LightClient, LightPlugin, DSNInfo, SentryEvent, EventLevel, UserInfo, Breadcrumb, ErrorEvent, TransactionContext, SpanContext, Transaction, Span } from '../types'; import { parseDSN } from '../utils/dsn'; import { now } from '../utils/helper'; import { computeFingerprint } from '../utils/hash'; import { parseStackTrace } from '../utils/stacktrace'; import { logDebug, setDebug } from '../utils/logger'; +import { setAnonymousId as setStoredAnonymousId } from '../utils/identity'; import { ConfigManager } from './ConfigManager'; import { EventBus } from './EventBus'; import { EventQueue } from './EventQueue'; import { Reporter } from './Reporter'; import { PluginManager } from './PluginManager'; +import { TracingManager } from './TracingManager'; class Client implements LightClient { dsn: DSNInfo; @@ -18,6 +20,7 @@ class Client implements LightClient { private queue: EventQueue; private reporter: Reporter; private pluginManager: PluginManager; + private tracingManager: TracingManager; private breadcrumbs: Breadcrumb[] = []; private enabled: boolean = true; @@ -46,6 +49,7 @@ class Client implements LightClient { this.configManager.get('retryDelay') ?? 1000 ); this.pluginManager = new PluginManager(this); + this.tracingManager = new TracingManager(config, this, this.dsn.publicKey); this.queue = new EventQueue( this.configManager.get('maxQueueSize') ?? 100, this.configManager.get('flushInterval') ?? 5000, @@ -175,6 +179,7 @@ class Client implements LightClient { return; } + this.attachTraceContext(errorEvent); errorEvent.breadcrumbs = [...this.breadcrumbs]; logDebug('Client', 'Enqueue error event', { breadcrumbs: this.breadcrumbs.length }); this.queue.enqueue(errorEvent); @@ -193,6 +198,7 @@ class Client implements LightClient { if (this.configManager.isIgnoredError(message)) return; + this.attachTraceContext(event); this.queue.enqueue(event); } @@ -206,9 +212,34 @@ class Client implements LightClient { ...event, } as SentryEvent; + this.attachTraceContext(fullEvent); this.queue.enqueue(fullEvent); } + private attachTraceContext(event: SentryEvent): void { + const currentSpan = this.tracingManager.getCurrentSpan(); + const currentTransaction = this.tracingManager.getCurrentTransaction(); + + if (currentSpan || currentTransaction) { + const traceId = currentSpan?.traceId || currentTransaction?.traceId; + const spanId = currentSpan?.spanId || currentTransaction?.spanId; + const parentSpanId = currentSpan?.parentSpanId; + const op = currentSpan?.op || currentTransaction?.op; + const status = currentSpan?.status || currentTransaction?.status; + + event.contexts = { + ...event.contexts, + trace: { + trace_id: traceId || '', + span_id: spanId || '', + parent_span_id: parentSpanId, + op, + status, + }, + }; + } + } + private buildErrorEvent(error: Error | unknown): ErrorEvent { const timestamp = now(); @@ -243,6 +274,42 @@ class Client implements LightClient { setUser(user: UserInfo | null): void { this.configManager.setUser(user); + this.tracingManager.updateConfig(this.configManager.getAll()); + } + + setAnonymousId(id: string): void { + setStoredAnonymousId(id); + } + + startTransaction(context: TransactionContext): Transaction | null { + if (!this.enabled) return null; + + const transaction = this.tracingManager.startTransaction(context); + if (transaction && transaction.sampled) { + logDebug('Client', 'Transaction started and sampled', { + name: transaction.name, + traceId: transaction.traceId, + }); + } + + return transaction; + } + + getCurrentTransaction(): Transaction | null { + return this.tracingManager.getCurrentTransaction(); + } + + getCurrentSpan(): Span | null { + return this.tracingManager.getCurrentSpan(); + } + + setSpan(span: Span | null): void { + this.tracingManager.setCurrentSpan(span); + } + + startSpan(context: SpanContext): Span | null { + if (!this.enabled) return null; + return this.tracingManager.startSpan(context); } setTag(key: string, value: string): void { @@ -286,8 +353,9 @@ class Client implements LightClient { } destroy(): void { - this.queue.destroy(); this.pluginManager.destroy(); + this.tracingManager.destroy(); + this.queue.destroy(); this.eventBus.destroy(); this.breadcrumbs = []; } diff --git a/src/core/ConfigManager.ts b/src/core/ConfigManager.ts index ca76418..18cb045 100644 --- a/src/core/ConfigManager.ts +++ b/src/core/ConfigManager.ts @@ -1,6 +1,7 @@ import type { LightConfig, SentryEvent, UserInfo, ContextLevelMap, ErrorEvent, StackFrame, Breadcrumb, EventLevel } from '../types'; import { getContexts, getContextId, getPageUrl, getReferrer } from '../utils/env'; import { matchPatterns } from '../utils/helper'; +import { getAnonymousId, isAnonymousTrackingEnabled } from '../utils/identity'; const DEFAULT_CONFIG: Partial = { enabled: true, @@ -72,6 +73,13 @@ export class ConfigManager { return matchPatterns(message, this.config.ignoreErrors || []); } + shouldSample(): boolean { + const rate = this.config.sampleRate ?? 1; + if (rate >= 1) return true; + if (rate <= 0) return false; + return Math.random() < rate; + } + /** * 获取编码后的环境信息(延迟初始化,只在首次上报时计算) * 注意:env.ts 的 getContexts 已经返回编码后的数据 @@ -135,6 +143,7 @@ export class ConfigManager { if (this.config.environment) { enriched.environment = this.config.environment; } + enriched.platform = 'javascript'; if (this.config.user) { enriched.user = this.config.user; } @@ -156,6 +165,16 @@ export class ConfigManager { } enriched.context_id = this.contextId; + // 处理匿名用户ID + // 只有在没有设置 user.id 且启用了匿名追踪时,才添加 anonymousId + const hasUserId = this.config.user?.id || (event.user as Record)?.id; + if (!hasUserId && isAnonymousTrackingEnabled(this.config)) { + const anonymousId = getAnonymousId(); + if (anonymousId) { + enriched.anonymousId = anonymousId; + } + } + const result = this.applyContextLevel(enriched); if (includeFullContext && !this.contextReported) { diff --git a/src/core/EventQueue.ts b/src/core/EventQueue.ts index f0e3b9d..4e8ab5e 100644 --- a/src/core/EventQueue.ts +++ b/src/core/EventQueue.ts @@ -183,8 +183,7 @@ export class EventQueue { } private cleanupExpiredDedupeEntries(): void { - // 每 100 条或每 10 次清理一次,避免过于频繁 - if (this.dedupeMap.size < 100 && Math.random() > 0.1) return; + if (Math.random() > 0.1) return; const currentTime = now(); const expiryTime = 60000; @@ -310,6 +309,7 @@ export class EventQueue { window.removeEventListener('pagehide', this.onPagehide); } } + this.queue = []; this.dedupeMap.clear(); this.pendingCounts.clear(); this.errorRateWindow = {}; diff --git a/src/core/Reporter.ts b/src/core/Reporter.ts index 228d4d9..3e9f855 100644 --- a/src/core/Reporter.ts +++ b/src/core/Reporter.ts @@ -238,8 +238,6 @@ export class Reporter { switch (event.type) { case 'error': return 'event'; - case 'performance': - return 'transaction'; default: return event.type; } diff --git a/src/core/TracingManager.ts b/src/core/TracingManager.ts new file mode 100644 index 0000000..9e5e81a --- /dev/null +++ b/src/core/TracingManager.ts @@ -0,0 +1,198 @@ +import type { LightConfig, SpanContext, TransactionContext, Span, Transaction, LightClient, SamplingContext } from '../types'; +import { Span as SpanImpl, Transaction as TransactionImpl } from '../utils/tracing'; +import { logDebug } from '../utils/logger'; + +export class TracingManager { + private config: LightConfig; + private _client?: LightClient; + private currentTransaction: Transaction | null = null; + private spanStack: Span[] = []; + private dsnPublicKey?: string; + + constructor(config: LightConfig, client?: LightClient, dsnPublicKey?: string) { + this.config = config; + this._client = client; + this.dsnPublicKey = dsnPublicKey; + } + + updateConfig(config: LightConfig): void { + this.config = config; + if (this.currentTransaction) { + const txImpl = this.currentTransaction as unknown as TransactionImpl; + txImpl.setUserBaggage(config.user?.id, (config.user as { segment?: string } | undefined)?.segment); + } + } + + private shouldSample(context: TransactionContext, parentSampled?: boolean): boolean { + const sampler = this.config.tracesSampler; + if (sampler) { + const samplingContext: SamplingContext = { + ...context, + parentSampled, + }; + const result = sampler(samplingContext); + if (typeof result === 'boolean') { + return result; + } + const clampedRate = Math.max(0, Math.min(1, result)); + if (clampedRate === 0) return false; + if (clampedRate === 1) return true; + return Math.random() < clampedRate; + } + + const rate = this.config.tracesSampleRate ?? 0; + if (rate >= 1) return true; + if (rate <= 0) return false; + return Math.random() < rate; + } + + startTransaction(context: TransactionContext): Transaction | null { + const parentTx = this.currentTransaction; + const parentSampled = parentTx ? parentTx.sampled : undefined; + + const sampled = context.sampled ?? this.shouldSample(context, parentSampled); + + const transaction = new TransactionImpl( + { + ...context, + sampled, + }, + this._client, + this.dsnPublicKey, + this.config.release, + this.config.environment + ) as unknown as Transaction; + + this.currentTransaction = transaction; + this.spanStack = [transaction]; + + logDebug('TracingManager', 'Transaction started', { + name: transaction.name, + traceId: transaction.traceId, + spanId: transaction.spanId, + sampled, + op: transaction.op, + }); + + return transaction; + } + + getCurrentTransaction(): Transaction | null { + return this.currentTransaction; + } + + setCurrentTransaction(transaction: Transaction | null): void { + this.currentTransaction = transaction; + if (!transaction) { + this.spanStack = []; + } else { + this.spanStack = [transaction]; + } + } + + getCurrentSpan(): Span | null { + return this.spanStack.length > 0 ? this.spanStack[this.spanStack.length - 1] : null; + } + + setCurrentSpan(span: Span | null): void { + if (span === null) { + if (this.spanStack.length > 1) { + this.spanStack.pop(); + } + } else { + this.spanStack.push(span); + } + } + + startSpan(context: SpanContext): Span | null { + const parentSpan = this.getCurrentSpan(); + + if (!parentSpan && !context.traceId) { + logDebug('TracingManager', 'startSpan skipped: no active span and no traceId'); + return null; + } + + let span: Span; + + if (parentSpan) { + span = (parentSpan as SpanImpl).startChild(context); + } else { + span = new SpanImpl({ + ...context, + parentSpanId: context.parentSpanId, + }) as unknown as Span; + + if (this.currentTransaction) { + if (this.currentTransaction.sampled !== false) { + (this.currentTransaction as unknown as TransactionImpl)._addSpan(span as unknown as SpanImpl); + } + (span as SpanImpl & { transaction: Transaction }).transaction = this.currentTransaction; + } + } + + this.spanStack.push(span); + + logDebug('TracingManager', 'Span started', { + op: span.op, + description: span.description, + spanId: span.spanId, + parentSpanId: span.parentSpanId, + stackDepth: this.spanStack.length, + }); + + return span; + } + + onSpanFinished(span: Span): void { + const idx = this.spanStack.lastIndexOf(span); + if (idx !== -1) { + this.spanStack.splice(idx, 1); + } + + if (this.spanStack.length === 0 && this.currentTransaction) { + this.spanStack = [this.currentTransaction]; + } + + logDebug('TracingManager', 'Span finished', { + op: span.op, + description: span.description, + spanId: span.spanId, + stackDepth: this.spanStack.length, + }); + } + + onTransactionFinished(transaction: Transaction): void { + if (this.currentTransaction === transaction) { + this.currentTransaction = null; + this.spanStack = []; + } + + logDebug('TracingManager', 'Transaction finished', { + name: transaction.name, + traceId: transaction.traceId, + spanCount: transaction.spans.length, + sampled: transaction.sampled, + }); + } + + finishSpan(span: Span): void { + span.finish(); + } + + finishTransaction(transaction: Transaction): void { + transaction.finish(); + } + + destroy(): void { + if (this.currentTransaction) { + try { + this.currentTransaction.setStatus('aborted'); + this.currentTransaction.finish(); + } catch { + // ignore + } + } + this.currentTransaction = null; + this.spanStack = []; + } +} diff --git a/src/index.ts b/src/index.ts index 8f7a2ba..a23022e 100644 --- a/src/index.ts +++ b/src/index.ts @@ -5,8 +5,13 @@ import NetworkPlugin from './plugins/NetworkPlugin'; import BehaviorPlugin from './plugins/BehaviorPlugin'; import OfflinePlugin from './plugins/OfflinePlugin'; import SamplingPlugin from './plugins/SamplingPlugin'; -import type { LightConfig, LightClient, SentryEvent, EventLevel, UserInfo, Breadcrumb, LightPlugin, ErrorEvent, PerformanceEvent, NetworkEvent, BehaviorEvent, DSNInfo } from './types'; +import RouterPlugin from './plugins/RouterPlugin'; +import InteractionPlugin from './plugins/InteractionPlugin'; +import { Span as SpanClass, Transaction as TransactionClass, httpStatusToSpanStatus, dbStatusToSpanStatus, statusToSpanStatus } from './utils/tracing'; +import { serializeBaggage, parseBaggage, createBaggageFromTransaction } from './utils/baggage'; +import type { LightConfig, LightClient, SentryEvent, EventLevel, UserInfo, Breadcrumb, LightPlugin, ErrorEvent, PerformanceEvent, NetworkEvent, BehaviorEvent, DSNInfo, TransactionContext, SpanContext, Transaction, Span, SamplingContext, BaggageFields, SpanStatus } from './types'; import { logDebug, setDebug } from './utils/logger'; +import { setAnonymousId as setStoredAnonymousId, clearAnonymousId as clearStoredAnonymousId, getAnonymousId as getStoredAnonymousId } from './utils/identity'; let globalClient: LightClient | null = null; @@ -33,6 +38,12 @@ function init(config: LightConfig): LightClient { if (pluginNames.includes('behavior') || pluginNames.includes('all')) { defaultPlugins.push(new BehaviorPlugin()); } + if (pluginNames.includes('router') || pluginNames.includes('all')) { + defaultPlugins.push(new RouterPlugin()); + } + if (pluginNames.includes('interaction') || pluginNames.includes('all')) { + defaultPlugins.push(new InteractionPlugin()); + } logDebug('Index', 'Registering plugins', { count: defaultPlugins.length, plugins: defaultPlugins.map(p => p.name) }); @@ -90,6 +101,38 @@ function setUser(user: UserInfo | null): void { globalClient?.setUser(user); } +function setAnonymousId(id: string): void { + setStoredAnonymousId(id); +} + +function clearAnonymousId(): void { + clearStoredAnonymousId(); +} + +function getAnonymousId(): string | null { + return getStoredAnonymousId(); +} + +function startTransaction(context: TransactionContext): Transaction | null { + return globalClient?.startTransaction(context) || null; +} + +function getCurrentTransaction(): Transaction | null { + return globalClient?.getCurrentTransaction() || null; +} + +function getCurrentSpan(): Span | null { + return globalClient?.getCurrentSpan() || null; +} + +function setSpan(span: Span | null): void { + globalClient?.setSpan(span); +} + +function startSpan(context: SpanContext): Span | null { + return globalClient?.startSpan(context) || null; +} + function setTag(key: string, value: string): void { globalClient?.setTag(key, value); } @@ -125,6 +168,14 @@ export { captureMessage, captureEvent, setUser, + setAnonymousId, + clearAnonymousId, + getAnonymousId, + startTransaction, + getCurrentTransaction, + getCurrentSpan, + setSpan, + startSpan, setTag, setTags, setExtra, @@ -133,14 +184,24 @@ export { disable, enable, Client, + httpStatusToSpanStatus, + dbStatusToSpanStatus, + statusToSpanStatus, + serializeBaggage, + parseBaggage, + createBaggageFromTransaction, ErrorPlugin, PerformancePlugin, NetworkPlugin, BehaviorPlugin, OfflinePlugin, SamplingPlugin, + RouterPlugin, + InteractionPlugin, }; +export { SpanClass as Span, TransactionClass as Transaction }; + export type { LightConfig, LightClient, @@ -154,6 +215,13 @@ export type { UserInfo, Breadcrumb, DSNInfo, + TransactionContext, + SpanContext, + SamplingContext, + BaggageFields, + SpanStatus, + SpanJSON, + TransactionJSON, }; export default { @@ -163,6 +231,14 @@ export default { captureMessage, captureEvent, setUser, + setAnonymousId, + clearAnonymousId, + getAnonymousId, + startTransaction, + getCurrentTransaction, + getCurrentSpan, + setSpan, + startSpan, setTag, setTags, setExtra, @@ -170,4 +246,7 @@ export default { flush, disable, enable, + Span: SpanClass, + Transaction: TransactionClass, + httpStatusToSpanStatus, }; diff --git a/src/plugins/ErrorPlugin.ts b/src/plugins/ErrorPlugin.ts index 84f5d3a..43be321 100644 --- a/src/plugins/ErrorPlugin.ts +++ b/src/plugins/ErrorPlugin.ts @@ -3,6 +3,7 @@ import { now, isObject, matchPatterns } from '../utils/helper'; import { computeFingerprint } from '../utils/hash'; import { sanitizeUrl, shouldIgnoreUrl } from '../utils/env'; import { parseStackTrace } from '../utils/stacktrace'; +import { logError } from '../utils/logger'; interface ErrorPluginConfig { maxStackFrames?: number; @@ -120,7 +121,7 @@ class ErrorPlugin implements LightPlugin { this.client.captureEvent(errorEvent); } } catch (e) { - console.error('[LightSDK] ErrorPlugin global error handler error:', e); + logError('ErrorPlugin', 'Global error handler error', e); } return false; @@ -153,7 +154,7 @@ class ErrorPlugin implements LightPlugin { this.client.captureEvent(errorEvent); } } catch (e) { - console.error('[LightSDK] ErrorPlugin unhandledrejection handler error:', e); + logError('ErrorPlugin', 'Unhandledrejection handler error', e); } }; @@ -207,7 +208,7 @@ class ErrorPlugin implements LightPlugin { }, }); } catch (e) { - console.error('[LightSDK] ErrorPlugin resource error handler error:', e); + logError('ErrorPlugin', 'Resource error handler error', e); } } }; diff --git a/src/plugins/InteractionPlugin.ts b/src/plugins/InteractionPlugin.ts new file mode 100644 index 0000000..e268d8d --- /dev/null +++ b/src/plugins/InteractionPlugin.ts @@ -0,0 +1,207 @@ +import type { LightPlugin, LightClient, Transaction, Span, SpanStatus, LightConfig } from '../types'; +import { now, isObject } from '../utils/helper'; + +interface InteractionPluginConfig { + enable?: boolean; + elementAttribute?: string; + maxTransactionDurationMs?: number; + idleTimeoutMs?: number; + captureScroll?: boolean; + trackClick?: boolean; + trackSubmit?: boolean; + trackKeypress?: boolean; +} + +const DEFAULT_TRACKING_TYPES = ['click', 'submit']; + +class InteractionPlugin implements LightPlugin { + name = 'interaction'; + version = '1.0.0'; + + private client!: LightClient; + private config: InteractionPluginConfig = { + enable: true, + elementAttribute: 'data-sentry-component', + maxTransactionDurationMs: 30000, + idleTimeoutMs: 1000, + trackClick: true, + trackSubmit: true, + trackKeypress: false, + }; + + private currentTransaction: Transaction | null = null; + private idleTimer: ReturnType | null = null; + private maxDurationTimer: ReturnType | null = null; + private debounceTimer: ReturnType | null = null; + + setup(client: LightClient): void { + this.client = client; + this.loadConfig(); + + if (typeof window === 'undefined') return; + if (!this.config.enable) return; + + if (this.config.trackClick) { + document.addEventListener('click', this.handleClick, true); + } + if (this.config.trackSubmit) { + document.addEventListener('submit', this.handleSubmit, true); + } + } + + private loadConfig(): void { + const clientConfig = this.client.config as LightConfig; + if (clientConfig && isObject((clientConfig as Record).interaction)) { + this.config = { ...this.config, ...((clientConfig as Record).interaction as object) }; + } + } + + private handleClick = (event: Event): void => { + if (this.isEventIgnored(event)) return; + const target = event.target as HTMLElement; + const elementName = this.getElementName(target, 'click'); + this.scheduleInteractionTransaction(elementName, 'click', target); + }; + + private handleSubmit = (event: Event): void => { + if (this.isEventIgnored(event)) return; + const target = event.target as HTMLElement; + const elementName = this.getElementName(target, 'submit'); + this.scheduleInteractionTransaction(elementName, 'submit', target); + }; + + private isEventIgnored(event: Event): boolean { + const target = event.target as HTMLElement; + if (!target) return true; + + if (target.hasAttribute && target.hasAttribute('data-sentry-ignore')) { + return true; + } + + return false; + } + + private scheduleInteractionTransaction(name: string, op: string, element: HTMLElement): void { + if (this.debounceTimer) { + clearTimeout(this.debounceTimer); + } + + this.debounceTimer = setTimeout(() => { + this.startInteractionTransaction(name, op, element); + }, 0); + } + + private getElementName(element: HTMLElement | null, eventType: string): string { + if (!element) return eventType; + + const attr = this.config.elementAttribute || 'data-sentry-component'; + const componentName = element.getAttribute(attr); + if (componentName) return componentName; + + const tag = element.tagName?.toLowerCase() || 'element'; + const id = element.id ? `#${element.id}` : ''; + const classes = element.className && typeof element.className === 'string' + ? `.${element.className.split(' ').slice(0, 3).join('.')}` + : ''; + + return `${eventType}@${tag}${id}${classes}`; + } + + private startInteractionTransaction(name: string, op: string, element: HTMLElement): void { + if (!this.client) return; + + if (this.currentTransaction) { + this.finishCurrentTransaction('ok'); + } + + const transaction = this.client.startTransaction({ + name, + op: `ui.${op}`, + description: `User ${op} on ${name}`, + type: 'user-interaction', + tags: { + 'interaction.type': op, + 'interaction.target': name, + }, + data: { + tag: element.tagName?.toLowerCase(), + id: element.id || undefined, + text: element.textContent?.substring(0, 100) || undefined, + }, + }); + + if (transaction) { + this.currentTransaction = transaction; + this.scheduleIdleFinish(); + this.scheduleMaxDuration(); + } + } + + private scheduleIdleFinish(): void { + if (this.idleTimer) { + clearTimeout(this.idleTimer); + } + + const idleTimeout = this.config.idleTimeoutMs ?? 1000; + + this.idleTimer = setTimeout(() => { + this.finishCurrentTransaction('ok'); + }, idleTimeout); + } + + private scheduleMaxDuration(): void { + if (this.maxDurationTimer) { + clearTimeout(this.maxDurationTimer); + } + + const maxDuration = this.config.maxTransactionDurationMs ?? 30000; + this.maxDurationTimer = setTimeout(() => { + this.finishCurrentTransaction('deadline_exceeded'); + }, maxDuration); + } + + private finishCurrentTransaction(status: SpanStatus = 'ok'): void { + if (this.idleTimer) { + clearTimeout(this.idleTimer); + this.idleTimer = null; + } + if (this.maxDurationTimer) { + clearTimeout(this.maxDurationTimer); + this.maxDurationTimer = null; + } + if (this.debounceTimer) { + clearTimeout(this.debounceTimer); + this.debounceTimer = null; + } + + if (this.currentTransaction) { + this.currentTransaction.setStatus(status); + this.currentTransaction.finish(); + this.currentTransaction = null; + } + } + + destroy(): void { + if (typeof document !== 'undefined') { + document.removeEventListener('click', this.handleClick, true); + document.removeEventListener('submit', this.handleSubmit, true); + } + + if (this.idleTimer) { + clearTimeout(this.idleTimer); + this.idleTimer = null; + } + if (this.maxDurationTimer) { + clearTimeout(this.maxDurationTimer); + this.maxDurationTimer = null; + } + if (this.debounceTimer) { + clearTimeout(this.debounceTimer); + this.debounceTimer = null; + } + + this.finishCurrentTransaction('aborted'); + } +} + +export default InteractionPlugin; diff --git a/src/plugins/NetworkPlugin.ts b/src/plugins/NetworkPlugin.ts index 5e3140f..bcddd0e 100644 --- a/src/plugins/NetworkPlugin.ts +++ b/src/plugins/NetworkPlugin.ts @@ -1,4 +1,4 @@ -import type { LightPlugin, LightClient, NetworkEvent, LightConfig } from '../types'; +import type { LightPlugin, LightClient, NetworkEvent, LightConfig, Span, Transaction } from '../types'; import { now, isObject } from '../utils/helper'; import { sanitizeUrl, shouldIgnoreUrl } from '../utils/env'; @@ -17,11 +17,12 @@ interface NetworkPluginConfig { slowThreshold?: number; slowSampleRate?: number; ignoreStatusCodes?: number[]; + tracePropagationTargets?: (string | RegExp)[]; } class NetworkPlugin implements LightPlugin { name = 'network'; - version = '1.0.0'; + version = '1.1.0'; private client!: LightClient; private config: NetworkPluginConfig = { @@ -63,12 +64,63 @@ class NetworkPlugin implements LightPlugin { if (clientConfig.ignoreUrls) { this.config.ignoreUrls = [...(this.config.ignoreUrls || []), ...clientConfig.ignoreUrls]; } + if (clientConfig.tracePropagationTargets) { + this.config.tracePropagationTargets = [...(this.config.tracePropagationTargets || []), ...clientConfig.tracePropagationTargets]; + } else if (clientConfig.tracingOrigins) { + this.config.tracePropagationTargets = [...(this.config.tracePropagationTargets || []), ...clientConfig.tracingOrigins]; + } } private shouldIgnore(url: string): boolean { return shouldIgnoreUrl(url, this.config.ignoreUrls || []); } + private shouldTracePropagate(url: string): boolean { + const targets = this.config.tracePropagationTargets; + if (!targets || targets.length === 0) { + return this.isSameOrigin(url); + } + return targets.some(pattern => { + if (typeof pattern === 'string') { + return url.includes(pattern); + } + return pattern.test(url); + }); + } + + private isSameOrigin(url: string): boolean { + if (typeof location === 'undefined') return false; + try { + const urlObj = new URL(url, location.origin); + return urlObj.origin === location.origin; + } catch { + return false; + } + } + + private getBaggageHeader(): string | undefined { + if (!this.client) return undefined; + + const clientInternal = this.client as unknown as { + tracingManager?: { + getCurrentTransaction?: () => Transaction | null; + }; + }; + + const tx = clientInternal.tracingManager?.getCurrentTransaction?.(); + if (!tx) return undefined; + + const transactionImpl = tx as unknown as { + toBaggage?: () => string | undefined; + }; + + if (transactionImpl.toBaggage) { + return transactionImpl.toBaggage(); + } + + return undefined; + } + private shouldSample(isError: boolean, duration: number): boolean { let rate = isError ? (this.config.errorSampleRate ?? 1.0) : (this.config.successSampleRate ?? 0.01); @@ -81,6 +133,34 @@ class NetworkPlugin implements LightPlugin { return Math.random() < rate; } + private createHttpSpan(method: string, url: string): Span | null { + const currentSpan = this.client.getCurrentSpan(); + if (!currentSpan) return null; + + const span = currentSpan.startChild({ + op: 'http.client', + description: `${method.toUpperCase()} ${url}`, + tags: { + 'http.method': method.toUpperCase(), + 'http.url': sanitizeUrl(url), + }, + }); + + return span; + } + + private finishHttpSpan(span: Span, statusCode: number, duration: number, isError: boolean): void { + span.setData('http.response.duration', duration); + + if (statusCode > 0) { + span.setHttpStatus(statusCode); + } else if (isError) { + span.setStatus('internal_error'); + } + + span.finish(); + } + private patchFetch(): void { if (typeof fetch === 'undefined') return; @@ -97,7 +177,27 @@ class NetworkPlugin implements LightPlugin { } const sanitizedUrl = sanitizeUrl(url); - const promise = self.originalFetch.call(window, input, init); + + let httpSpan = self.createHttpSpan(method, sanitizedUrl); + + const shouldInjectTrace = self.shouldTracePropagate(url) && !!httpSpan; + let modifiedInit = init; + + if (shouldInjectTrace && httpSpan) { + const traceHeader = httpSpan.toTraceparent(); + const baggage = self.getBaggageHeader(); + + modifiedInit = { + ...init, + headers: { + ...(init?.headers || {}), + 'sentry-trace': traceHeader, + ...(baggage ? { 'baggage': baggage } : {}), + }, + }; + } + + const promise = self.originalFetch.call(window, input, modifiedInit); promise.then( (response) => { @@ -105,6 +205,10 @@ class NetworkPlugin implements LightPlugin { const isSuccess = response.ok; const statusCode = response.status; + if (httpSpan) { + self.finishHttpSpan(httpSpan, statusCode, duration, !isSuccess); + } + if (self.config.ignoreStatusCodes?.includes(statusCode)) { return response; } @@ -130,6 +234,10 @@ class NetworkPlugin implements LightPlugin { (error) => { const duration = now() - startTime; + if (httpSpan) { + self.finishHttpSpan(httpSpan, 0, duration, true); + } + if (self.shouldSample(true, duration)) { self.reportNetwork({ sub_type: 'fetch', @@ -180,12 +288,32 @@ class NetworkPlugin implements LightPlugin { requestSize = body.length; } + const httpSpan = self.createHttpSpan(method, sanitizedUrl); + const shouldInjectTrace = self.shouldTracePropagate(url) && !!httpSpan; + + if (shouldInjectTrace && httpSpan) { + try { + const traceHeader = httpSpan.toTraceparent(); + const baggage = self.getBaggageHeader(); + this.setRequestHeader('sentry-trace', traceHeader); + if (baggage) { + this.setRequestHeader('baggage', baggage); + } + } catch { + // ignore + } + } + const originalOnLoadEnd = (this as XMLHttpRequest & { onloadend?: ((this: XMLHttpRequest, ev: ProgressEvent) => unknown) | null }).onloadend; (this as XMLHttpRequest & { onloadend?: ((this: XMLHttpRequest, ev: ProgressEvent) => unknown) | null }).onloadend = function (ev: ProgressEvent) { const duration = now() - startTime; const status = this.status; const isSuccess = status >= 200 && status < 300; + if (httpSpan) { + self.finishHttpSpan(httpSpan, status, duration, !isSuccess); + } + if (!self.config.ignoreStatusCodes?.includes(status) && self.shouldSample(!isSuccess, duration) && (isSuccess ? self.config.captureSuccess : true)) { diff --git a/src/plugins/PerformancePlugin.ts b/src/plugins/PerformancePlugin.ts index 1001dcb..b295eb0 100644 --- a/src/plugins/PerformancePlugin.ts +++ b/src/plugins/PerformancePlugin.ts @@ -1,4 +1,4 @@ -import type { LightPlugin, LightClient, PerformanceEvent, LightConfig } from '../types'; +import type { LightPlugin, LightClient, PerformanceEvent, LightConfig, Transaction, Span } from '../types'; import { now, isObject } from '../utils/helper'; interface PerformancePluginConfig { @@ -9,11 +9,19 @@ interface PerformancePluginConfig { longTaskSampleRate?: number; captureNavigation?: boolean; captureFP?: boolean; + enablePageLoadTracing?: boolean; // 是否启用 Page Load Transaction + maxResourceSpans?: number; // 最大 Resource Span 数量 +} + +interface VitalMeasurement { + value: number; + unit?: string; + rating?: 'good' | 'needs-improvement' | 'poor'; } class PerformancePlugin implements LightPlugin { name = 'performance'; - version = '1.0.0'; + version = '2.0.0'; private client!: LightClient; private config: PerformancePluginConfig = { @@ -24,6 +32,8 @@ class PerformancePlugin implements LightPlugin { longTaskSampleRate: 0.05, captureNavigation: true, captureFP: true, + enablePageLoadTracing: false, + maxResourceSpans: 50, }; private observers: PerformanceObserver[] = []; @@ -35,16 +45,44 @@ class PerformancePlugin implements LightPlugin { private ttiReported: boolean = false; private ttiTimer: ReturnType | null = null; + private pageLoadTransaction: Transaction | null = null; + private measurements: Record = {}; + private resourceSpanCount: number = 0; + setup(client: LightClient): void { this.client = client; this.loadConfig(); + if (this.config.enablePageLoadTracing) { + this.startPageLoadTransaction(); + } + this.observeWebVitals(); this.observeLongTasks(); this.observeNavigation(); this.observeResources(); } + private startPageLoadTransaction(): void { + if (typeof window === 'undefined') return; + + const pageUrl = typeof location !== 'undefined' ? location.pathname : '/'; + const navStart = typeof performance !== 'undefined' && performance.timing?.navigationStart + ? performance.timing.navigationStart + : now(); + + this.pageLoadTransaction = this.client.startTransaction({ + name: pageUrl, + op: 'pageload', + description: `Page load - ${pageUrl}`, + startTimestamp: navStart, + type: 'pageload', + tags: { + 'page.url': pageUrl, + }, + }); + } + private loadConfig(): void { const clientConfig = this.client.config as LightConfig; if (clientConfig && isObject(clientConfig.performance)) { @@ -69,28 +107,32 @@ class PerformancePlugin implements LightPlugin { private observeWebVitals(): void { if (typeof PerformanceObserver === 'undefined') return; - if (this.config.captureFP) { - this.observeFP(); - } + this.observePaint(); this.observeLCP(); this.observeFID(); this.observeCLS(); - this.observeFCP(); this.observeTTFB(); } - private observeFP(): void { + private observePaint(): void { try { const po = new PerformanceObserver((entryList) => { - const entries = entryList.getEntriesByName('first-paint'); - if (entries.length > 0) { - this.reportMetric('FP', entries[0].startTime, 'ms', {}, 'vitals'); + const fpEntries = entryList.getEntriesByName('first-paint'); + if (fpEntries.length > 0 && this.config.captureFP) { + this.reportMetric('FP', fpEntries[0].startTime, 'ms', {}, 'vitals'); + } + const fcpEntries = entryList.getEntriesByName('first-contentful-paint'); + if (fcpEntries.length > 0) { + this.fcpTime = fcpEntries[0].startTime; + this.lastLongTaskEndTime = fcpEntries[0].startTime; + this.reportMetric('FCP', fcpEntries[0].startTime, 'ms', {}, 'vitals'); + this.scheduleTTI(); } }); po.observe({ type: 'paint', buffered: true }); this.observers.push(po); } catch { - // FP not supported + // Paint observer not supported } } @@ -167,24 +209,6 @@ class PerformancePlugin implements LightPlugin { } } - private observeFCP(): void { - try { - const po = new PerformanceObserver((entryList) => { - const entries = entryList.getEntriesByName('first-contentful-paint'); - if (entries.length > 0) { - this.fcpTime = entries[0].startTime; - this.lastLongTaskEndTime = entries[0].startTime; - this.reportMetric('FCP', entries[0].startTime, 'ms', {}, 'vitals'); - this.scheduleTTI(); - } - }); - po.observe({ type: 'paint', buffered: true }); - this.observers.push(po); - } catch { - // FCP not supported - } - } - private observeTTFB(): void { try { const po = new PerformanceObserver((entryList) => { @@ -276,6 +300,12 @@ class PerformancePlugin implements LightPlugin { this.reportMetric(name, value, 'ms'); } } + + if (this.pageLoadTransaction && this.pageLoadTransaction.sampled !== false) { + this.buildNavigationSpans(timing, navigationStart); + this.finishPageLoadTransaction(timing.loadEventEnd || now()); + } + this.navLoadTimer = null; }, 0); }; @@ -283,20 +313,63 @@ class PerformancePlugin implements LightPlugin { window.addEventListener('load', this.onLoad); } + private buildNavigationSpans(timing: PerformanceTiming, navigationStart: number): void { + const spanDefs: Array<{ op: string; desc: string; start: number; end: number }> = [ + { op: 'dns', desc: 'DNS Lookup', start: timing.domainLookupStart, end: timing.domainLookupEnd }, + { op: 'tcp', desc: 'TCP Connection', start: timing.connectStart, end: timing.connectEnd }, + { op: 'ssl', desc: 'SSL/TLS Negotiation', start: timing.secureConnectionStart, end: timing.connectEnd }, + { op: 'ttfb', desc: 'Time to First Byte', start: timing.requestStart, end: timing.responseStart }, + { op: 'response', desc: 'Response Download', start: timing.responseStart, end: timing.responseEnd }, + { op: 'dom_parse', desc: 'DOM Parsing', start: timing.responseEnd, end: timing.domInteractive }, + { op: 'dom_content_loaded', desc: 'DOM Content Loaded', start: timing.domLoading, end: timing.domContentLoadedEventEnd }, + { op: 'load', desc: 'Page Load', start: timing.navigationStart, end: timing.loadEventEnd }, + ]; + + for (const def of spanDefs) { + if (def.start > 0 && def.end > 0 && def.end > def.start) { + this.createNavigationSpan( + def.op, + def.desc, + def.start, + def.end + ); + } + } + } + + private finishPageLoadTransaction(endTime: number): void { + if (!this.pageLoadTransaction) return; + + if (Object.keys(this.measurements).length > 0) { + (this.pageLoadTransaction as unknown as { setData: (k: string, v: unknown) => void }).setData( + 'measurements', + this.measurements + ); + } + + this.pageLoadTransaction.setStatus('ok'); + this.pageLoadTransaction.finish(endTime); + this.pageLoadTransaction = null; + } + private observeResources(): void { - if (!this.config.captureResources) return; + if (!this.config.captureResources && !this.config.enablePageLoadTracing) return; if (typeof performance === 'undefined') return; try { const po = new PerformanceObserver((entryList) => { const entries = entryList.getEntriesByType('resource') as PerformanceResourceTiming[]; for (const entry of entries) { - if (entry.duration > 1000) { + if (entry.duration > 1000 && this.config.captureResources) { this.reportMetric('resource_slow', entry.duration, 'ms', { resource_name: entry.name.substring(0, 200), resource_type: entry.initiatorType, }, 'resource'); } + + if (this.config.enablePageLoadTracing && this.pageLoadTransaction) { + this.createResourceSpan(entry); + } } }); po.observe({ type: 'resource', buffered: true }); @@ -345,6 +418,78 @@ class PerformancePlugin implements LightPlugin { }; this.client.captureEvent(event); + + if (this.pageLoadTransaction && this.pageLoadTransaction.sampled !== false) { + this.recordMeasurement(name, value, unit, rating); + } + } + + private recordMeasurement(name: string, value: number, unit?: string, rating?: 'good' | 'needs-improvement' | 'poor'): void { + if (!this.pageLoadTransaction) return; + + this.measurements[name] = { + value: Math.round(value * 100) / 100, + unit, + rating, + }; + + this.pageLoadTransaction.setTag(`measurement.${name}.rating`, rating || 'unknown'); + } + + private createNavigationSpan( + op: string, + description: string, + startTime: number, + endTime: number, + tags?: Record + ): void { + if (!this.pageLoadTransaction || this.pageLoadTransaction.sampled === false) return; + if (endTime <= startTime) return; + + const span = this.pageLoadTransaction.startChild({ + op: `browser.${op}`, + description, + startTimestamp: startTime, + tags, + }); + + span.finish(endTime); + } + + private createResourceSpan(entry: PerformanceResourceTiming): void { + if (!this.pageLoadTransaction || this.pageLoadTransaction.sampled === false) return; + + const maxResources = this.config.maxResourceSpans ?? 50; + if (this.resourceSpanCount >= maxResources) return; + this.resourceSpanCount++; + + const timeOrigin = typeof performance !== 'undefined' && performance.timeOrigin + ? performance.timeOrigin + : (performance.timing?.navigationStart || 0); + const startTime = timeOrigin + entry.startTime; + const endTime = timeOrigin + (entry.responseEnd || entry.duration || entry.startTime); + + if (endTime <= startTime) return; + + const url = entry.name.substring(0, 200); + const span = this.pageLoadTransaction.startChild({ + op: `resource.${entry.initiatorType || 'other'}`, + description: url, + startTimestamp: startTime, + tags: { + 'resource.type': entry.initiatorType || 'other', + 'resource.url': url, + 'resource.transfer_size': String(entry.transferSize || 0), + 'resource.decoded_size': String(entry.decodedBodySize || 0), + }, + data: { + transferSize: entry.transferSize, + decodedSize: entry.decodedBodySize, + encodedSize: entry.encodedBodySize, + }, + }); + + span.finish(endTime); } destroy(): void { @@ -370,6 +515,15 @@ class PerformancePlugin implements LightPlugin { if (typeof window !== 'undefined' && this.onLoad) { window.removeEventListener('load', this.onLoad); } + + if (this.pageLoadTransaction) { + this.pageLoadTransaction.setStatus('internal_error'); + this.pageLoadTransaction.finish(); + this.pageLoadTransaction = null; + } + + this.measurements = {}; + this.resourceSpanCount = 0; } } diff --git a/src/plugins/RouterPlugin.ts b/src/plugins/RouterPlugin.ts new file mode 100644 index 0000000..251f4de --- /dev/null +++ b/src/plugins/RouterPlugin.ts @@ -0,0 +1,181 @@ +import type { LightPlugin, LightClient, Transaction, SpanStatus, LightConfig } from '../types'; +import { now, isObject } from '../utils/helper'; + +interface RouterPluginConfig { + enable?: boolean; + instrumentHistory?: boolean; + instrumentHash?: boolean; + routeNameFormatter?: (url: string) => string; + maxTransactionDurationMs?: number; +} + +class RouterPlugin implements LightPlugin { + name = 'router'; + version = '1.0.0'; + + private client!: LightClient; + private config: RouterPluginConfig = { + enable: true, + instrumentHistory: true, + instrumentHash: true, + maxTransactionDurationMs: 30000, + }; + + private currentTransaction: Transaction | null = null; + private lastRoute: string = ''; + private originalPushState?: typeof history.pushState; + private originalReplaceState?: typeof history.replaceState; + private maxDurationTimer: ReturnType | null = null; + private routeChangeTimer: ReturnType | null = null; + + setup(client: LightClient): void { + this.client = client; + this.loadConfig(); + + if (typeof window === 'undefined') return; + if (!this.config.enable) return; + + if (this.config.instrumentHistory) { + this.instrumentHistory(); + } + + if (this.config.instrumentHash) { + this.instrumentHash(); + } + } + + private loadConfig(): void { + const clientConfig = this.client.config as LightConfig; + if (clientConfig && isObject((clientConfig as Record).router)) { + this.config = { ...this.config, ...((clientConfig as Record).router as object) }; + } + } + + private instrumentHistory(): void { + if (typeof history === 'undefined' || !history.pushState) return; + + this.originalPushState = history.pushState.bind(history); + this.originalReplaceState = history.replaceState.bind(history); + + history.pushState = (data: unknown, title: string, url?: string | null): void => { + this.originalPushState!(data, title, url); + this.handleRouteChange(url || location.pathname + location.search, 'pushState'); + }; + + history.replaceState = (data: unknown, title: string, url?: string | null): void => { + this.originalReplaceState!(data, title, url); + this.handleRouteChange(url || location.pathname + location.search, 'replaceState'); + }; + + window.addEventListener('popstate', this.handlePopState); + } + + private handlePopState = (): void => { + this.handleRouteChange(location.pathname + location.search, 'popstate'); + }; + + private instrumentHash(): void { + window.addEventListener('hashchange', this.handleHashChange); + } + + private handleHashChange = (): void => { + this.handleRouteChange(location.hash || '#/', 'hashchange'); + }; + + private handleRouteChange(to: string, source: string): void { + if (this.routeChangeTimer) { + clearTimeout(this.routeChangeTimer); + } + + this.routeChangeTimer = setTimeout(() => { + this.routeChangeTimer = null; + this.processRouteChange(to, source); + }, 50); + } + + private processRouteChange(to: string, source: string): void { + const routeName = this.config.routeNameFormatter + ? this.config.routeNameFormatter(to) + : to.split('?')[0]; + + if (routeName === this.lastRoute) return; + this.lastRoute = routeName; + + this.finishCurrentTransaction('ok'); + this.startNavigationTransaction(routeName, source); + } + + private startNavigationTransaction(name: string, source: string): void { + if (!this.client) return; + + const transaction = this.client.startTransaction({ + name, + op: 'navigation', + description: `Navigation to ${name}`, + type: 'navigation', + tags: { + 'route.name': name, + 'route.source': source, + }, + }); + + if (transaction) { + this.currentTransaction = transaction; + this.startMaxDurationTimer(); + } + } + + private startMaxDurationTimer(): void { + if (this.maxDurationTimer) { + clearTimeout(this.maxDurationTimer); + } + + const maxDuration = this.config.maxTransactionDurationMs ?? 30000; + this.maxDurationTimer = setTimeout(() => { + if (this.currentTransaction) { + this.currentTransaction.setStatus('deadline_exceeded'); + this.finishCurrentTransaction('deadline_exceeded'); + } + }, maxDuration); + } + + private finishCurrentTransaction(status: SpanStatus = 'ok'): void { + if (this.maxDurationTimer) { + clearTimeout(this.maxDurationTimer); + this.maxDurationTimer = null; + } + + if (this.currentTransaction) { + this.currentTransaction.setStatus(status); + this.currentTransaction.finish(); + this.currentTransaction = null; + } + } + + destroy(): void { + if (this.originalPushState && typeof history !== 'undefined') { + history.pushState = this.originalPushState; + } + if (this.originalReplaceState && typeof history !== 'undefined') { + history.replaceState = this.originalReplaceState; + } + + if (typeof window !== 'undefined') { + window.removeEventListener('popstate', this.handlePopState); + window.removeEventListener('hashchange', this.handleHashChange); + } + + if (this.maxDurationTimer) { + clearTimeout(this.maxDurationTimer); + this.maxDurationTimer = null; + } + if (this.routeChangeTimer) { + clearTimeout(this.routeChangeTimer); + this.routeChangeTimer = null; + } + + this.finishCurrentTransaction('aborted'); + } +} + +export default RouterPlugin; diff --git a/src/types/index.ts b/src/types/index.ts index 1f8afca..47e32f5 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -54,10 +54,33 @@ export interface DeviceContext { type?: string; } +export interface TraceContext { + trace_id: string; + span_id: string; + parent_span_id?: string; + op?: string; + status?: string; + description?: string; +} + +export interface BaggageFields { + trace_id?: string; + public_key?: string; + sample_rate?: string; + sampled?: string; + user_id?: string; + user_segment?: string; + release?: string; + environment?: string; + replay_id?: string; + [key: string]: string | undefined; +} + export interface Contexts { browser?: BrowserContext; os?: OSContext; device?: DeviceContext; + trace?: TraceContext; } export interface Breadcrumb { @@ -76,6 +99,7 @@ export interface BaseEvent { release?: string; environment?: string; user?: UserInfo; + anonymousId?: string; // 匿名用户ID(未登录用户) tags?: Record; extra?: Record; breadcrumbs?: Breadcrumb[]; @@ -129,7 +153,124 @@ export interface CountEvent extends BaseEvent { ts_end: number; } -export type SentryEvent = ErrorEvent | PerformanceEvent | NetworkEvent | BehaviorEvent | CountEvent; +export type SpanStatus = + | 'ok' + | 'cancelled' + | 'unknown' + | 'unknown_error' + | 'invalid_argument' + | 'deadline_exceeded' + | 'not_found' + | 'already_exists' + | 'permission_denied' + | 'resource_exhausted' + | 'failed_precondition' + | 'aborted' + | 'out_of_range' + | 'unimplemented' + | 'internal_error' + | 'unavailable' + | 'data_loss' + | 'unauthenticated'; + +export interface SpanContext { + op?: string; + description?: string; + startTimestamp?: number; + status?: SpanStatus; + tags?: Record; + data?: Record; + traceId?: string; + spanId?: string; + parentSpanId?: string; + sampled?: boolean; +} + +export interface SamplingContext extends TransactionContext { + parentSampled?: boolean; +} + +export interface TransactionContext extends SpanContext { + name: string; + type?: string; +} + +// Span JSON 输出类型 +export interface SpanJSON { + trace_id: string; + span_id: string; + parent_span_id?: string; + op?: string; + description?: string; + status?: SpanStatus; + tags?: Record; + data?: Record; + start_timestamp: number; + timestamp: number; +} + +// Transaction JSON 输出类型 +export interface TransactionJSON extends SpanJSON { + transaction: string; + type?: string; + spans: SpanJSON[]; + sampled?: boolean; +} + +export interface Span { + readonly traceId: string; + readonly spanId: string; + readonly parentSpanId?: string; + op?: string; + description?: string; + status?: SpanStatus; + tags: Record; + data: Record; + readonly startTimestamp: number; + readonly endTimestamp?: number; + readonly transaction?: Transaction; + + setTag(key: string, value: string): this; + setData(key: string, value: unknown): this; + setStatus(status: SpanStatus): this; + setHttpStatus(statusCode: number): this; + setStatusFromResponse(status: string | number | undefined, tagKey?: string): this; + startChild(context?: SpanContext): Span; + finish(endTimestamp?: number): void; + toTraceparent(): string; + toJSON(): SpanJSON; +} + +// 使用 Omit 排除 Span 中需要 override 的属性,Transaction 扩展其余属性 +export interface Transaction extends Omit { + name: string; + type?: string; + spans: Span[]; + sampled?: boolean; + maxSpans?: number; + + toJSON(): TransactionJSON; + toEvent(): TransactionEvent; +} + +export interface MeasurementValue { + value: number; + unit?: string; + rating?: 'good' | 'needs-improvement' | 'poor'; +} + +export interface TransactionEvent extends BaseEvent { + type: 'transaction'; + transaction: string; + transaction_info?: { + source: string; + }; + spans: Array>; + start_timestamp: number; + measurements?: Record; +} + +export type SentryEvent = ErrorEvent | PerformanceEvent | NetworkEvent | BehaviorEvent | CountEvent | TransactionEvent; export interface DSNInfo { protocol: string; @@ -155,6 +296,13 @@ export interface LightConfig { enabled?: boolean; debug?: boolean; sampleRate?: number; + tracesSampleRate?: number; // Trace 采样率 0~1,默认 0(关闭) + tracesSampler?: (context: SamplingContext) => number | boolean; // 动态采样函数 + /** + * @deprecated 请使用 tracePropagationTargets 替代 + */ + tracingOrigins?: (string | RegExp)[]; // 追踪域名白名单(已废弃) + tracePropagationTargets?: (string | RegExp)[]; // trace header 传播目标 maxQueueSize?: number; flushInterval?: number; maxRetries?: number; @@ -165,6 +313,7 @@ export interface LightConfig { maxBreadcrumbs?: number; beforeSend?: (event: SentryEvent) => SentryEvent | null; user?: UserInfo; + trackAnonymousUsers?: boolean; // 是否启用匿名用户追踪,默认 true plugins?: (LightPlugin | string)[]; contextLevel?: Partial; sampling?: SamplingConfig; @@ -190,10 +339,16 @@ export interface LightClient { captureMessage(message: string, level?: EventLevel): void; captureEvent(event: Partial & { type: string }): void; setUser(user: UserInfo | null): void; + setAnonymousId(id: string): void; // 设置匿名用户ID setTag(key: string, value: string): void; setTags(tags: Record): void; setExtra(key: string, value: unknown): void; addBreadcrumb(breadcrumb: Omit): void; + startTransaction(context: TransactionContext): Transaction | null; + getCurrentTransaction(): Transaction | null; + getCurrentSpan(): Span | null; + setSpan(span: Span | null): void; + startSpan(context: SpanContext): Span | null; flush(): Promise; disable(): void; enable(): void; diff --git a/src/utils/baggage.ts b/src/utils/baggage.ts new file mode 100644 index 0000000..ae0b7e6 --- /dev/null +++ b/src/utils/baggage.ts @@ -0,0 +1,99 @@ +import type { BaggageFields } from '../types'; + +const SENTRY_PREFIX = 'sentry-'; +const MAX_BAGGAGE_LENGTH = 8192; + +export function serializeBaggage(fields: BaggageFields): string { + const parts: string[] = []; + + for (const [key, value] of Object.entries(fields)) { + if (value === undefined || value === null || value === '') continue; + + const prefixedKey = key.startsWith(SENTRY_PREFIX) ? key : `${SENTRY_PREFIX}${key}`; + parts.push(`${prefixedKey}=${encodeURIComponent(String(value))}`); + } + + let result = parts.join(','); + if (result.length > MAX_BAGGAGE_LENGTH) { + result = result.substring(0, MAX_BAGGAGE_LENGTH); + const lastComma = result.lastIndexOf(','); + if (lastComma > 0) { + result = result.substring(0, lastComma); + } + } + + return result; +} + +export function parseBaggage(header: string): BaggageFields { + const fields: BaggageFields = {}; + + if (!header) return fields; + + const parts = header.split(','); + for (const part of parts) { + const eqIdx = part.indexOf('='); + if (eqIdx === -1) continue; + + const rawKey = part.substring(0, eqIdx).trim(); + const value = decodeURIComponent(part.substring(eqIdx + 1).trim()); + + let key = rawKey; + if (rawKey.startsWith(SENTRY_PREFIX)) { + key = rawKey.substring(SENTRY_PREFIX.length); + } + + if (key) { + fields[key] = value; + } + } + + return fields; +} + +export function createBaggageFromTransaction( + traceId: string, + options?: { + dsnPublicKey?: string; + sampled?: boolean; + sampleRate?: number; + user?: { id?: string; segment?: string }; + release?: string; + environment?: string; + } +): BaggageFields { + const fields: BaggageFields = { + trace_id: traceId, + }; + + if (options?.dsnPublicKey) { + fields.public_key = options.dsnPublicKey; + } + + if (options?.sampled !== undefined) { + fields.sampled = options.sampled ? 'true' : 'false'; + } + + if (options?.sampleRate !== undefined) { + fields.sample_rate = String(options.sampleRate); + } + + if (options?.user) { + if (options.user.id) { + fields.user_id = options.user.id; + } + if (options.user.segment) { + fields.user_segment = options.user.segment; + } + } + + if (options?.release) { + fields.release = options.release; + } + + if (options?.environment) { + fields.environment = options.environment; + } + + return fields; +} diff --git a/src/utils/env.ts b/src/utils/env.ts index a4456fa..dba5352 100644 --- a/src/utils/env.ts +++ b/src/utils/env.ts @@ -163,6 +163,11 @@ export function getReferrer(): string { export function sanitizeUrl(url: string): string { if (!url) return url; + // 过滤 javascript: 伪协议防止 XSS + if (/^\s*javascript:/i.test(url)) { + return 'javascript:[filtered]'; + } + try { const urlObj = new URL(url); const sensitiveParams = [ diff --git a/src/utils/identity.ts b/src/utils/identity.ts new file mode 100644 index 0000000..32d33c8 --- /dev/null +++ b/src/utils/identity.ts @@ -0,0 +1,70 @@ +import { uuid } from './helper'; + +const ANONYMOUS_ID_KEY = 'light_sentry_aid'; + +/** + * 获取匿名用户ID + * 优先从 localStorage 获取已存在的ID,不存在则生成并存储 + */ +export function getAnonymousId(): string | null { + // 浏览器环境检查 + if (typeof localStorage === 'undefined') { + return null; + } + + try { + let anonymousId = localStorage.getItem(ANONYMOUS_ID_KEY); + + if (!anonymousId) { + anonymousId = uuid(); + localStorage.setItem(ANONYMOUS_ID_KEY, anonymousId); + } + + return anonymousId; + } catch { + // localStorage 不可用(如隐私模式、跨域限制等) + return null; + } +} + +/** + * 设置匿名用户ID + * 用于覆盖自动生成的ID + */ +export function setAnonymousId(id: string): boolean { + if (typeof localStorage === 'undefined') { + return false; + } + + try { + localStorage.setItem(ANONYMOUS_ID_KEY, id); + return true; + } catch { + return false; + } +} + +/** + * 清除匿名用户ID + * 通常在用户登出后调用 + */ +export function clearAnonymousId(): boolean { + if (typeof localStorage === 'undefined') { + return false; + } + + try { + localStorage.removeItem(ANONYMOUS_ID_KEY); + return true; + } catch { + return false; + } +} + +/** + * 检查是否启用了匿名用户追踪 + */ +export function isAnonymousTrackingEnabled(config: { trackAnonymousUsers?: boolean }): boolean { + // 默认为 true,除非明确设置为 false + return config.trackAnonymousUsers !== false; +} diff --git a/src/utils/tracing.ts b/src/utils/tracing.ts new file mode 100644 index 0000000..39b85d5 --- /dev/null +++ b/src/utils/tracing.ts @@ -0,0 +1,356 @@ +import type { Span as SpanInterface, SpanContext, Transaction as TransactionInterface, TransactionContext, SpanStatus, LightClient, BaggageFields } from '../types'; +import { uuid, now } from './helper'; +import { createBaggageFromTransaction, serializeBaggage } from './baggage'; + +function generateTraceId(): string { + return uuid().replace(/-/g, ''); +} + +function generateSpanId(): string { + return uuid().replace(/-/g, '').substring(0, 16); +} + +export function httpStatusToSpanStatus(statusCode: number): SpanStatus { + if (statusCode >= 200 && statusCode < 300) return 'ok'; + if (statusCode === 400) return 'invalid_argument'; + if (statusCode === 401) return 'unauthenticated'; + if (statusCode === 403) return 'permission_denied'; + if (statusCode === 404) return 'not_found'; + if (statusCode === 409) return 'already_exists'; + if (statusCode === 429) return 'resource_exhausted'; + if (statusCode >= 400 && statusCode < 500) return 'invalid_argument'; + if (statusCode >= 500 && statusCode < 600) return 'internal_error'; + return 'unknown_error'; +} + +export function dbStatusToSpanStatus(dbStatusCode?: string | number): SpanStatus { + if (dbStatusCode === undefined || dbStatusCode === null || dbStatusCode === '') { + return 'unknown_error'; + } + + const code = typeof dbStatusCode === 'string' ? parseInt(dbStatusCode, 10) : dbStatusCode; + + if (code === 0 || code === 1) return 'ok'; + if (code >= 10 && code < 20) return 'invalid_argument'; + if (code >= 20 && code < 30) return 'not_found'; + if (code >= 30 && code < 40) return 'already_exists'; + if (code >= 50) return 'internal_error'; + + return 'unknown_error'; +} + +export function statusToSpanStatus( + status: string | number | undefined, + op: string | undefined +): SpanStatus { + if (status === undefined) return 'unknown_error'; + + if (typeof status === 'string') { + const lowerStatus = status.toLowerCase(); + if (lowerStatus === 'ok' || lowerStatus === 'success') return 'ok'; + if (lowerStatus === 'cancelled' || lowerStatus === 'canceled') return 'cancelled'; + if (lowerStatus === 'deadline_exceeded') return 'deadline_exceeded'; + if (lowerStatus === 'not_found') return 'not_found'; + if (lowerStatus === 'already_exists') return 'already_exists'; + if (lowerStatus === 'permission_denied') return 'permission_denied'; + if (lowerStatus === 'resource_exhausted') return 'resource_exhausted'; + if (lowerStatus === 'failed_precondition') return 'failed_precondition'; + if (lowerStatus === 'invalid_argument') return 'invalid_argument'; + if (lowerStatus === 'unauthenticated') return 'unauthenticated'; + if (lowerStatus === 'internal_error') return 'internal_error'; + + const parsed = parseInt(status, 10); + if (!isNaN(parsed)) { + return statusToSpanStatus(parsed, op); + } + return 'unknown_error'; + } + + if (typeof status === 'number') { + if (status >= 200 && status < 600) { + return httpStatusToSpanStatus(status); + } + + if (op?.startsWith('db')) { + return dbStatusToSpanStatus(status); + } + + if (status === 0) return 'ok'; + if (status > 0) return 'unknown_error'; + } + + return 'unknown_error'; +} + +export class Span implements SpanInterface { + readonly traceId: string; + readonly spanId: string; + readonly parentSpanId?: string; + op?: string; + description?: string; + status?: SpanStatus; + tags: Record = {}; + data: Record = {}; + readonly startTimestamp: number; + endTimestamp?: number; + transaction?: TransactionInterface; + + protected _isFinished = false; + protected _client?: LightClient; + + constructor(context: SpanContext, transaction?: TransactionInterface, client?: LightClient) { + this.traceId = context.traceId || generateTraceId(); + this.spanId = context.spanId || generateSpanId(); + this.parentSpanId = context.parentSpanId; + this.op = context.op; + this.description = context.description; + this.status = context.status; + this.tags = { ...context.tags }; + this.data = { ...context.data }; + this.startTimestamp = context.startTimestamp || now(); + this.transaction = transaction; + this._client = client; + } + + setTag(key: string, value: string): this { + this.tags[key] = value; + return this; + } + + setData(key: string, value: unknown): this { + this.data[key] = value; + return this; + } + + setStatus(status: SpanStatus): this { + this.status = status; + return this; + } + + setHttpStatus(statusCode: number): this { + this.setStatus(httpStatusToSpanStatus(statusCode)); + this.setTag('http.status_code', String(statusCode)); + return this; + } + + setStatusFromResponse(status: string | number | undefined, tagKey?: string): this { + const spanStatus = statusToSpanStatus(status, this.op); + this.setStatus(spanStatus); + if (tagKey && status !== undefined) { + this.setTag(tagKey, String(status)); + } + return this; + } + + startChild(context: SpanContext = {}): Span { + const tx = this.transaction; + const isSampled = tx?.sampled !== false; + + const child = new Span( + { + ...context, + traceId: this.traceId, + parentSpanId: this.spanId, + }, + tx, + this._client + ); + + if (tx && isSampled) { + (tx as Transaction)._addSpan(child); + } + + return child; + } + + finish(endTimestamp?: number): void { + if (this._isFinished) return; + this._isFinished = true; + this.endTimestamp = endTimestamp || now(); + + if (this._client) { + const clientInternal = this._client as unknown as { tracingManager?: { onSpanFinished: (span: Span) => void } }; + if (clientInternal.tracingManager?.onSpanFinished) { + clientInternal.tracingManager.onSpanFinished(this); + } + } + } + + toTraceparent(): string { + const sampled = this.transaction?.sampled; + const sampledFlag = sampled === undefined ? '' : sampled ? '1' : '0'; + return sampledFlag + ? `${this.traceId}-${this.spanId}-${sampledFlag}` + : `${this.traceId}-${this.spanId}`; + } + + toJSON() { + return { + trace_id: this.traceId, + span_id: this.spanId, + parent_span_id: this.parentSpanId, + op: this.op, + description: this.description, + status: this.status, + tags: Object.keys(this.tags).length > 0 ? { ...this.tags } : undefined, + data: Object.keys(this.data).length > 0 ? { ...this.data } : undefined, + start_timestamp: this.startTimestamp, + timestamp: this.endTimestamp || this.startTimestamp, + }; + } +} + +export class Transaction extends Span implements TransactionInterface { + name: string; + type?: string; + spans: Span[] = []; + sampled?: boolean; + maxSpans: number = 1000; + private _baggage?: BaggageFields; + private _dsnPublicKey?: string; + private _release?: string; + private _environment?: string; + private _droppedSpans: number = 0; + + constructor(context: TransactionContext, client?: LightClient, dsnPublicKey?: string, release?: string, environment?: string, maxSpans?: number) { + super(context, undefined, client); + this.name = context.name; + this.type = context.type; + this.sampled = context.sampled; + this.transaction = this; + this._dsnPublicKey = dsnPublicKey; + this._release = release; + this._environment = environment; + if (maxSpans !== undefined) { + this.maxSpans = maxSpans; + } + } + + _addSpan(span: Span): void { + if (this.spans.length >= this.maxSpans) { + this._droppedSpans++; + return; + } + this.spans.push(span); + } + + private _ensureBaggage(): BaggageFields { + if (!this._baggage) { + this._baggage = createBaggageFromTransaction( + this.traceId, + { + dsnPublicKey: this._dsnPublicKey, + sampled: this.sampled, + release: this._release, + environment: this._environment, + } + ); + } + return this._baggage; + } + + setBaggage(key: string, value: string): this { + const baggage = this._ensureBaggage(); + baggage[key] = value; + return this; + } + + setUserBaggage(userId?: string, segment?: string): this { + const baggage = this._ensureBaggage(); + if (userId !== undefined) { + baggage.user_id = userId; + } else { + delete baggage.user_id; + } + if (segment !== undefined) { + baggage.user_segment = segment; + } else { + delete baggage.user_segment; + } + return this; + } + + toBaggage(): string | undefined { + const baggage = this._ensureBaggage(); + return serializeBaggage(baggage); + } + + getBaggage(): BaggageFields | undefined { + return this._baggage; + } + + finish(endTimestamp?: number): void { + if (this._isFinished) return; + super.finish(endTimestamp); + + if (this._client && this.sampled) { + const event = this.toEvent(); + this._client.captureEvent(event); + } + + if (this._client) { + const clientInternal = this._client as unknown as { tracingManager?: { onTransactionFinished: (tx: Transaction) => void } }; + if (clientInternal.tracingManager?.onTransactionFinished) { + clientInternal.tracingManager.onTransactionFinished(this); + } + } + } + + private _getSource(): string { + switch (this.type) { + case 'pageload': + return 'url'; + case 'navigation': + return 'route'; + case 'user-interaction': + return 'ui'; + default: + return 'custom'; + } + } + + toEvent() { + const json = this.toJSON(); + const data = { ...json.data } as Record; + const measurements = data.measurements as Record | undefined; + delete data.measurements; + + return { + type: 'transaction' as const, + transaction: this.name, + transaction_info: { + source: this._getSource(), + }, + level: 'info' as const, + timestamp: json.timestamp, + start_timestamp: json.start_timestamp, + spans: this.spans.map((s) => s.toJSON()), + contexts: { + trace: { + trace_id: this.traceId, + span_id: this.spanId, + parent_span_id: this.parentSpanId, + op: this.op, + status: this.status, + }, + }, + tags: json.tags, + extra: Object.keys(data).length > 0 ? data : undefined, + measurements, + platform: 'javascript', + }; + } + + toJSON() { + const base = super.toJSON(); + return { + ...base, + transaction: this.name, + type: this.type, + spans: this.spans.map((s) => s.toJSON()), + sampled: this.sampled, + }; + } +} + +export { generateTraceId, generateSpanId }; diff --git a/tests/ConfigManager.test.ts b/tests/ConfigManager.test.ts index aad95e9..6656074 100644 --- a/tests/ConfigManager.test.ts +++ b/tests/ConfigManager.test.ts @@ -245,4 +245,256 @@ describe('ConfigManager', () => { expect(result.context_id).toBe('test_context_id'); }); }); + + describe('anonymousId', () => { + beforeEach(() => { + localStorage.clear(); + }); + + it('should add anonymousId when user.id is not set and tracking is enabled', () => { + configManager = new ConfigManager({ + dsn: 'https://proj_abc123@log.example.com/1001', + trackAnonymousUsers: true, + }); + const event: SentryEvent = { + type: 'error', + level: 'error', + timestamp: Date.now(), + } as ErrorEvent; + const result = configManager.applyToEvent(event); + expect((result as any).anonymousId).toBeTruthy(); + expect(typeof (result as any).anonymousId).toBe('string'); + }); + + it('should not add anonymousId when user.id is set', () => { + configManager = new ConfigManager({ + dsn: 'https://proj_abc123@log.example.com/1001', + user: { id: 'user-123' }, + trackAnonymousUsers: true, + }); + const event: SentryEvent = { + type: 'error', + level: 'error', + timestamp: Date.now(), + } as ErrorEvent; + const result = configManager.applyToEvent(event); + expect((result as any).anonymousId).toBeUndefined(); + }); + + it('should not add anonymousId when trackAnonymousUsers is false', () => { + configManager = new ConfigManager({ + dsn: 'https://proj_abc123@log.example.com/1001', + trackAnonymousUsers: false, + }); + const event: SentryEvent = { + type: 'error', + level: 'error', + timestamp: Date.now(), + } as ErrorEvent; + const result = configManager.applyToEvent(event); + expect((result as any).anonymousId).toBeUndefined(); + }); + + it('should not add anonymousId when event has user.id', () => { + configManager = new ConfigManager({ + dsn: 'https://proj_abc123@log.example.com/1001', + trackAnonymousUsers: true, + }); + const event: SentryEvent = { + type: 'error', + level: 'error', + timestamp: Date.now(), + user: { id: 'event-user-id' }, + } as ErrorEvent; + const result = configManager.applyToEvent(event); + expect((result as any).anonymousId).toBeUndefined(); + }); + }); + + describe('contextLevel', () => { + beforeEach(() => { + configManager = new ConfigManager({ + dsn: 'https://proj_abc123@log.example.com/1001', + contextLevel: { + error: { maxStackFrames: 5, maxBreadcrumbs: 10 }, + info: { maxStackFrames: 0, maxBreadcrumbs: 0 }, + warning: { maxStackFrames: 3, maxBreadcrumbs: 5 }, + }, + }); + }); + + it('should truncate stack frames for error level', () => { + const frames = Array.from({ length: 10 }, (_, i) => ({ + filename: `file${i}.js`, + function: `fn${i}`, + lineno: i * 10, + colno: i, + })); + const event: SentryEvent = { + type: 'error', + level: 'error', + timestamp: Date.now(), + exception: { + type: 'Error', + value: 'test', + stacktrace: { frames }, + }, + } as ErrorEvent; + const result = configManager.applyToEvent(event); + expect((result as ErrorEvent).exception?.stacktrace?.frames).toHaveLength(5); + }); + + it('should remove exception entirely for info level (maxStackFrames=0)', () => { + const frames = [{ filename: 'file.js', function: 'fn', lineno: 1, colno: 1 }]; + const event: SentryEvent = { + type: 'error', + level: 'info', + timestamp: Date.now(), + exception: { + type: 'Error', + value: 'test', + stacktrace: { frames }, + }, + } as ErrorEvent; + const result = configManager.applyToEvent(event); + expect((result as ErrorEvent).exception).toBeUndefined(); + }); + + it('should truncate breadcrumbs for error level', () => { + const breadcrumbs = Array.from({ length: 20 }, (_, i) => ({ + type: 'default', + message: `breadcrumb ${i}`, + timestamp: Date.now() + i, + })); + const event: SentryEvent = { + type: 'error', + level: 'error', + timestamp: Date.now(), + breadcrumbs, + } as ErrorEvent; + const result = configManager.applyToEvent(event); + expect(result.breadcrumbs).toHaveLength(10); + }); + + it('should remove breadcrumbs for info level (maxBreadcrumbs=0)', () => { + const breadcrumbs = [{ type: 'default', message: 'test', timestamp: Date.now() }]; + const event: SentryEvent = { + type: 'error', + level: 'info', + timestamp: Date.now(), + breadcrumbs, + } as ErrorEvent; + const result = configManager.applyToEvent(event); + expect(result.breadcrumbs).toBeUndefined(); + }); + + it('should keep last N breadcrumbs', () => { + const breadcrumbs = Array.from({ length: 20 }, (_, i) => ({ + type: 'default', + message: `breadcrumb ${i}`, + timestamp: Date.now() + i, + })); + const event: SentryEvent = { + type: 'error', + level: 'warning', + timestamp: Date.now(), + breadcrumbs, + } as ErrorEvent; + const result = configManager.applyToEvent(event); + expect(result.breadcrumbs).toHaveLength(5); + // Should keep last 5 + expect(result.breadcrumbs?.[0].message).toBe('breadcrumb 15'); + expect(result.breadcrumbs?.[4].message).toBe('breadcrumb 19'); + }); + + it('should not modify original event', () => { + const frames = Array.from({ length: 10 }, (_, i) => ({ + filename: `file${i}.js`, + function: `fn${i}`, + lineno: i * 10, + colno: i, + })); + const event: ErrorEvent = { + type: 'error', + level: 'error', + message: 'test', + timestamp: Date.now(), + exception: { + type: 'Error', + value: 'test', + stacktrace: { frames }, + }, + }; + configManager.applyToEvent(event); + // Original event should not be modified + expect(event.exception?.stacktrace?.frames).toHaveLength(10); + }); + + it('should handle event without exception', () => { + const event: SentryEvent = { + type: 'error', + level: 'error', + timestamp: Date.now(), + } as ErrorEvent; + const result = configManager.applyToEvent(event); + expect(result).toBeDefined(); + }); + + it('should handle event without breadcrumbs', () => { + const event: SentryEvent = { + type: 'error', + level: 'error', + timestamp: Date.now(), + } as ErrorEvent; + const result = configManager.applyToEvent(event); + expect(result).toBeDefined(); + }); + }); + + describe('setUser', () => { + beforeEach(() => { + configManager = new ConfigManager({ + dsn: 'https://proj_abc123@log.example.com/1001', + user: { id: 'existing-user' }, + }); + }); + + it('should set user info', () => { + configManager.setUser({ id: 'new-user', username: 'test' }); + expect(configManager.get('user')).toEqual({ id: 'new-user', username: 'test' }); + }); + + it('should clear user info when null is passed', () => { + configManager.setUser(null); + expect(configManager.get('user')).toBeUndefined(); + }); + }); + + describe('setTag / setTags / setExtra', () => { + beforeEach(() => { + configManager = new ConfigManager({ + dsn: 'https://proj_abc123@log.example.com/1001', + }); + }); + + it('should set tag when no tags exist', () => { + configManager.setTag('key1', 'value1'); + expect(configManager.get('tags')).toEqual({ key1: 'value1' }); + }); + + it('should merge tags', () => { + configManager.setTag('key1', 'value1'); + configManager.setTags({ key2: 'value2', key3: 'value3' }); + expect(configManager.get('tags')).toEqual({ + key1: 'value1', + key2: 'value2', + key3: 'value3', + }); + }); + + it('should set extra when no extra exists', () => { + configManager.setExtra('key1', 'value1'); + expect(configManager.get('extra')).toEqual({ key1: 'value1' }); + }); + }); }); diff --git a/tests/EventBus.test.ts b/tests/EventBus.test.ts new file mode 100644 index 0000000..65a0cf7 --- /dev/null +++ b/tests/EventBus.test.ts @@ -0,0 +1,189 @@ +import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest'; +import { EventBus } from '../src/core/EventBus'; + +describe('EventBus', () => { + let consoleSpy: ReturnType; + + beforeEach(() => { + consoleSpy = vi.spyOn(console, 'error').mockImplementation(() => {}); + }); + + afterEach(() => { + vi.restoreAllMocks(); + }); + + describe('on / emit', () => { + it('should register a handler and call it on emit', () => { + const bus = new EventBus(); + const handler = vi.fn(); + bus.on('test-event', handler); + bus.emit('test-event', 'data1', 'data2'); + expect(handler).toHaveBeenCalledTimes(1); + expect(handler).toHaveBeenCalledWith('data1', 'data2'); + }); + + it('should call multiple handlers on same event', () => { + const bus = new EventBus(); + const handler1 = vi.fn(); + const handler2 = vi.fn(); + bus.on('test-event', handler1); + bus.on('test-event', handler2); + bus.emit('test-event'); + expect(handler1).toHaveBeenCalledTimes(1); + expect(handler2).toHaveBeenCalledTimes(1); + }); + + it('should not call handlers for different events', () => { + const bus = new EventBus(); + const handler = vi.fn(); + bus.on('event-a', handler); + bus.emit('event-b'); + expect(handler).not.toHaveBeenCalled(); + }); + + it('should handle emit on non-existent event', () => { + const bus = new EventBus(); + expect(() => bus.emit('non-existent', 'data')).not.toThrow(); + }); + + it('should pass multiple arguments to handler', () => { + const bus = new EventBus(); + const handler = vi.fn(); + bus.on('multi-arg', handler); + bus.emit('multi-arg', 1, 'two', { three: 3 }, [4, 5]); + expect(handler).toHaveBeenCalledWith(1, 'two', { three: 3 }, [4, 5]); + }); + + it('should not throw if a handler throws', () => { + const bus = new EventBus(); + const handler1 = vi.fn(() => { + throw new Error('Handler error'); + }); + const handler2 = vi.fn(); + bus.on('error-event', handler1); + bus.on('error-event', handler2); + expect(() => bus.emit('error-event')).not.toThrow(); + expect(handler2).toHaveBeenCalledTimes(1); + expect(consoleSpy).toHaveBeenCalled(); + }); + }); + + describe('off', () => { + it('should remove a registered handler', () => { + const bus = new EventBus(); + const handler = vi.fn(); + bus.on('test-event', handler); + bus.off('test-event', handler); + bus.emit('test-event'); + expect(handler).not.toHaveBeenCalled(); + }); + + it('should not remove other handlers', () => { + const bus = new EventBus(); + const handler1 = vi.fn(); + const handler2 = vi.fn(); + bus.on('test-event', handler1); + bus.on('test-event', handler2); + bus.off('test-event', handler1); + bus.emit('test-event'); + expect(handler1).not.toHaveBeenCalled(); + expect(handler2).toHaveBeenCalledTimes(1); + }); + + it('should handle off for non-existent event', () => { + const bus = new EventBus(); + const handler = vi.fn(); + expect(() => bus.off('non-existent', handler)).not.toThrow(); + }); + + it('should handle off for non-existent handler', () => { + const bus = new EventBus(); + const handler1 = vi.fn(); + const handler2 = vi.fn(); + bus.on('test-event', handler1); + bus.off('test-event', handler2); + bus.emit('test-event'); + expect(handler1).toHaveBeenCalledTimes(1); + }); + + it('should only remove one instance if handler is registered multiple times', () => { + const bus = new EventBus(); + const handler = vi.fn(); + bus.on('test-event', handler); + bus.on('test-event', handler); + bus.off('test-event', handler); + bus.emit('test-event'); + expect(handler).toHaveBeenCalledTimes(1); + }); + }); + + describe('once', () => { + it('should call handler only once', () => { + const bus = new EventBus(); + const handler = vi.fn(); + bus.once('once-event', handler); + bus.emit('once-event'); + bus.emit('once-event'); + expect(handler).toHaveBeenCalledTimes(1); + }); + + it('should pass arguments to once handler', () => { + const bus = new EventBus(); + const handler = vi.fn(); + bus.once('once-event', handler); + bus.emit('once-event', 'arg1', 'arg2'); + expect(handler).toHaveBeenCalledWith('arg1', 'arg2'); + }); + + it('should work with on and once mixed', () => { + const bus = new EventBus(); + const onHandler = vi.fn(); + const onceHandler = vi.fn(); + bus.on('mixed-event', onHandler); + bus.once('mixed-event', onceHandler); + bus.emit('mixed-event'); + bus.emit('mixed-event'); + expect(onHandler).toHaveBeenCalledTimes(2); + expect(onceHandler).toHaveBeenCalledTimes(1); + }); + + it('should not throw if once handler throws', () => { + const bus = new EventBus(); + const handler = vi.fn(() => { + throw new Error('Once handler error'); + }); + bus.once('once-error', handler); + expect(() => bus.emit('once-error')).not.toThrow(); + expect(consoleSpy).toHaveBeenCalled(); + }); + }); + + describe('destroy', () => { + it('should clear all handlers', () => { + const bus = new EventBus(); + const handler1 = vi.fn(); + const handler2 = vi.fn(); + bus.on('event-a', handler1); + bus.on('event-b', handler2); + bus.destroy(); + bus.emit('event-a'); + bus.emit('event-b'); + expect(handler1).not.toHaveBeenCalled(); + expect(handler2).not.toHaveBeenCalled(); + }); + + it('should handle destroy on empty bus', () => { + const bus = new EventBus(); + expect(() => bus.destroy()).not.toThrow(); + }); + + it('should work with once handlers after destroy', () => { + const bus = new EventBus(); + const handler = vi.fn(); + bus.once('event', handler); + bus.destroy(); + bus.emit('event'); + expect(handler).not.toHaveBeenCalled(); + }); + }); +}); diff --git a/tests/EventQueue.test.ts b/tests/EventQueue.test.ts new file mode 100644 index 0000000..2dbf8b6 --- /dev/null +++ b/tests/EventQueue.test.ts @@ -0,0 +1,383 @@ +import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest'; +import { EventQueue } from '../src/core/EventQueue'; +import { EventBus } from '../src/core/EventBus'; +import type { SentryEvent, ErrorEvent } from '../src/types'; + +describe('EventQueue', () => { + let eventQueue: EventQueue; + let eventBus: EventBus; + let flushCallback: ReturnType; + let syncFlushCallback: ReturnType; + + beforeEach(() => { + eventBus = new EventBus(); + flushCallback = vi.fn().mockResolvedValue(undefined); + syncFlushCallback = vi.fn(); + eventQueue = new EventQueue(100, 5000, eventBus, flushCallback, syncFlushCallback); + }); + + afterEach(() => { + eventQueue.destroy(); + vi.clearAllMocks(); + }); + + describe('enqueue', () => { + it('should add event to queue', () => { + const event = createErrorEvent('Test error'); + eventQueue.enqueue(event); + expect(eventQueue.size()).toBe(1); + }); + + it('should emit event when enqueueing', () => { + const event = createErrorEvent('Test error'); + const emitSpy = vi.spyOn(eventBus, 'emit'); + eventQueue.enqueue(event); + expect(emitSpy).toHaveBeenCalledWith('event', event); + }); + + it('should trigger flush when queue is full', () => { + const eventQueueSmall = new EventQueue(2, 5000, eventBus, flushCallback, syncFlushCallback); + eventQueueSmall.enqueue(createErrorEvent('error 1')); + eventQueueSmall.enqueue(createErrorEvent('error 2')); + // flushCallback should be called due to maxSize reached + expect(flushCallback).toHaveBeenCalled(); + eventQueueSmall.destroy(); + }); + + it('should skip deduplicated events', () => { + const event1 = createErrorEvent('Duplicate error', 'fingerprint1'); + const event2 = createErrorEvent('Duplicate error', 'fingerprint1'); + const event3 = createErrorEvent('Duplicate error', 'fingerprint1'); + const event4 = createErrorEvent('Duplicate error', 'fingerprint1'); // count >= 3, should be deduped + + eventQueue.enqueue(event1); + eventQueue.enqueue(event2); + eventQueue.enqueue(event3); + eventQueue.enqueue(event4); + + // First 3 events are allowed, 4th is deduped + expect(eventQueue.size()).toBe(3); + }); + + it('should not skip non-duplicate events', () => { + const event1 = createErrorEvent('Error 1', 'fp1'); + const event2 = createErrorEvent('Error 2', 'fp2'); + eventQueue.enqueue(event1); + eventQueue.enqueue(event2); + expect(eventQueue.size()).toBe(2); + }); + }); + + describe('flush', () => { + it('should call flush callback with events', async () => { + const event1 = createErrorEvent('Error 1'); + const event2 = createErrorEvent('Error 2'); + eventQueue.enqueue(event1); + eventQueue.enqueue(event2); + + await eventQueue.flush(); + + expect(flushCallback).toHaveBeenCalledWith(expect.arrayContaining([ + expect.objectContaining({ message: 'Error 1' }), + expect.objectContaining({ message: 'Error 2' }), + ])); + }); + + it('should not flush when queue is empty', async () => { + await eventQueue.flush(); + expect(flushCallback).not.toHaveBeenCalled(); + }); + + it('should clear queue after successful flush', async () => { + const event = createErrorEvent('Test error'); + eventQueue.enqueue(event); + expect(eventQueue.size()).toBe(1); + + await eventQueue.flush(); + expect(eventQueue.size()).toBe(0); + }); + + it('should return events to queue on flush failure', async () => { + flushCallback.mockRejectedValueOnce(new Error('Network error')); + + const event = createErrorEvent('Test error'); + eventQueue.enqueue(event); + + await expect(eventQueue.flush()).rejects.toThrow('Network error'); + // Events should be returned to queue + expect(eventQueue.size()).toBe(1); + }); + + it('should prevent concurrent flush reentry', async () => { + flushCallback.mockImplementation(async () => { + await new Promise(resolve => setTimeout(resolve, 50)); + }); + + const event = createErrorEvent('Test error'); + eventQueue.enqueue(event); + + // Start first flush + const flushPromise = eventQueue.flush(); + // Try second flush immediately + await eventQueue.flush(); + + await flushPromise; + // flushCallback should only be called once + expect(flushCallback).toHaveBeenCalledTimes(1); + }); + }); + + describe('flushSync', () => { + it('should call sync flush callback', () => { + const event = createErrorEvent('Sync error'); + eventQueue.enqueue(event); + + eventQueue.flushSync(); + + expect(syncFlushCallback).toHaveBeenCalledWith(expect.arrayContaining([ + expect.objectContaining({ message: 'Sync error' }), + ])); + }); + + it('should return events to queue on sync flush failure', () => { + syncFlushCallback.mockImplementationOnce(() => { + throw new Error('Sync error'); + }); + + const event = createErrorEvent('Test error'); + eventQueue.enqueue(event); + + eventQueue.flushSync(); + + // Events should be returned to queue + expect(eventQueue.size()).toBe(1); + }); + }); + + describe('destroy', () => { + it('should clear all data', () => { + const event = createErrorEvent('Test error'); + eventQueue.enqueue(event); + expect(eventQueue.size()).toBe(1); + + eventQueue.destroy(); + + expect(eventQueue.size()).toBe(0); + }); + }); + + describe('deduplication', () => { + it('should generate dedup key from fingerprint first', () => { + const event = createErrorEvent('Test error', 'fp1'); + eventQueue.enqueue(event); + expect(eventQueue.size()).toBe(1); + }); + + it('should generate dedup key from message if no fingerprint', () => { + const event1 = createErrorEvent('Same message'); + const event2 = createErrorEvent('Same message'); + const event3 = createErrorEvent('Same message'); + const event4 = createErrorEvent('Same message'); + + eventQueue.enqueue(event1); + eventQueue.enqueue(event2); + eventQueue.enqueue(event3); + eventQueue.enqueue(event4); + + expect(eventQueue.size()).toBe(3); + }); + + it('should reset dedup entry after expiry', async () => { + const event1 = createErrorEvent('Test', 'fp-expire'); + const event2 = createErrorEvent('Test', 'fp-expire'); + const event3 = createErrorEvent('Test', 'fp-expire'); + + eventQueue.enqueue(event1); + eventQueue.enqueue(event2); + eventQueue.enqueue(event3); + expect(eventQueue.size()).toBe(3); + + // 4th event should be deduped + const event4 = createErrorEvent('Test', 'fp-expire'); + eventQueue.enqueue(event4); + expect(eventQueue.size()).toBe(3); + }); + }); + + describe('count events', () => { + it('should build count events for deduped errors', async () => { + // Enqueue 3 events to reach threshold + for (let i = 0; i < 3; i++) { + eventQueue.enqueue(createErrorEvent('Dedup error', 'count-fp')); + } + // 4th event is deduped and goes to pendingCounts + eventQueue.enqueue(createErrorEvent('Dedup error', 'count-fp')); + eventQueue.enqueue(createErrorEvent('Dedup error', 'count-fp')); + + expect(eventQueue.size()).toBe(3); + + // Flush should include count events + await eventQueue.flush(); + + expect(flushCallback).toHaveBeenCalledWith( + expect.arrayContaining([ + expect.objectContaining({ type: 'count', fingerprint: 'count-fp', count: 2 }), + ]) + ); + }); + + it('should flush pending counts even when regular queue is empty', async () => { + for (let i = 0; i < 3; i++) { + eventQueue.enqueue(createErrorEvent('Dedup error', 'count-only-fp')); + } + // Add some deduped events (keep below infinite loop threshold of 10) + for (let i = 0; i < 5; i++) { + eventQueue.enqueue(createErrorEvent('Dedup error', 'count-only-fp')); + } + + // Flush first to clear regular queue + await eventQueue.flush(); + flushCallback.mockClear(); + + // Enqueue more deduped events + for (let i = 0; i < 3; i++) { + eventQueue.enqueue(createErrorEvent('Dedup error 2', 'count-only-fp-2')); + } + for (let i = 0; i < 2; i++) { + eventQueue.enqueue(createErrorEvent('Dedup error 2', 'count-only-fp-2')); + } + + // Flush again - should have count events even with empty regular queue + await eventQueue.flush(); + + const lastCall = flushCallback.mock.calls[flushCallback.mock.calls.length - 1]; + const countEvents = lastCall[0].filter((e: any) => e.type === 'count'); + expect(countEvents.length).toBeGreaterThan(0); + }); + }); + + describe('infinite loop detection', () => { + beforeEach(() => { + vi.useFakeTimers(); + }); + + afterEach(() => { + vi.useRealTimers(); + }); + + it('should pause queue when too many errors in 1 second', () => { + const consoleWarnSpy = vi.spyOn(console, 'warn').mockImplementation(() => {}); + + for (let i = 0; i < 11; i++) { + eventQueue.enqueue(createErrorEvent('Infinite loop test', 'infinite-fp')); + } + + // Should have paused + expect(consoleWarnSpy).toHaveBeenCalled(); + // After pause, no more events should be added + const sizeAfterLoop = eventQueue.size(); + eventQueue.enqueue(createErrorEvent('After pause', 'infinite-fp')); + expect(eventQueue.size()).toBe(sizeAfterLoop); + + consoleWarnSpy.mockRestore(); + }); + + it('should emit error event on infinite loop detection', () => { + const emitSpy = vi.spyOn(eventBus, 'emit'); + + for (let i = 0; i < 11; i++) { + eventQueue.enqueue(createErrorEvent('Infinite loop', 'loop-fp')); + } + + expect(emitSpy).toHaveBeenCalledWith('error', expect.any(Error)); + }); + + it('should resume after pause duration', () => { + const consoleWarnSpy = vi.spyOn(console, 'warn').mockImplementation(() => {}); + const consoleInfoSpy = vi.spyOn(console, 'info').mockImplementation(() => {}); + + for (let i = 0; i < 11; i++) { + eventQueue.enqueue(createErrorEvent('Resume test', 'resume-fp')); + } + + const sizeBeforeResume = eventQueue.size(); + + // Advance time past the 60s pause + vi.advanceTimersByTime(61000); + + // Should resume accepting events + eventQueue.enqueue(createErrorEvent('After resume', 'different-fp')); + expect(eventQueue.size()).toBe(sizeBeforeResume + 1); + + consoleWarnSpy.mockRestore(); + consoleInfoSpy.mockRestore(); + }); + }); + + describe('non-error events', () => { + it('should enqueue non-error events without dedup', () => { + const transactionEvent: SentryEvent = { + type: 'transaction', + level: 'info', + transaction: 'test-tx', + timestamp: Date.now(), + } as any; + + eventQueue.enqueue(transactionEvent); + eventQueue.enqueue(transactionEvent); + expect(eventQueue.size()).toBe(2); + }); + }); + + describe('start/stop timer', () => { + beforeEach(() => { + vi.useFakeTimers(); + }); + + afterEach(() => { + vi.useRealTimers(); + }); + + it('should start timer and flush on interval when queue has events', async () => { + const eq = new EventQueue(100, 1000, eventBus, flushCallback, syncFlushCallback); + eq.start(); + + eq.enqueue(createErrorEvent('Interval test')); + + // flushCallback should not be called yet + expect(flushCallback).not.toHaveBeenCalled(); + + // Advance timer past interval + vi.advanceTimersByTime(1500); + + // Wait for the flush promise to resolve + await vi.runOnlyPendingTimersAsync(); + + expect(flushCallback).toHaveBeenCalled(); + + eq.destroy(); + }); + + it('should not flush on interval when queue is empty', async () => { + const eq = new EventQueue(100, 1000, eventBus, flushCallback, syncFlushCallback); + eq.start(); + + vi.advanceTimersByTime(1500); + await vi.runOnlyPendingTimersAsync(); + + expect(flushCallback).not.toHaveBeenCalled(); + + eq.destroy(); + }); + }); +}); + +function createErrorEvent(message: string, fingerprint?: string): ErrorEvent { + return { + type: 'error', + level: 'error', + message, + timestamp: Date.now(), + fingerprint, + }; +} diff --git a/tests/PluginManager.test.ts b/tests/PluginManager.test.ts new file mode 100644 index 0000000..aa7e6c5 --- /dev/null +++ b/tests/PluginManager.test.ts @@ -0,0 +1,472 @@ +import { describe, it, expect, vi, beforeEach } from 'vitest'; +import { PluginManager } from '../src/core/PluginManager'; +import type { LightPlugin, LightClient, SentryEvent } from '../src/types'; + +describe('PluginManager', () => { + let mockClient: LightClient; + let consoleSpy: ReturnType; + + beforeEach(() => { + mockClient = { + config: { dsn: 'https://abc@sentry.io/123' }, + dsn: { protocol: 'https', publicKey: 'abc', host: 'sentry.io', projectId: '123' }, + on: vi.fn(), + off: vi.fn(), + emit: vi.fn(), + captureException: vi.fn(), + captureMessage: vi.fn(), + captureEvent: vi.fn(), + setUser: vi.fn(), + setAnonymousId: vi.fn(), + setTag: vi.fn(), + setTags: vi.fn(), + setExtra: vi.fn(), + addBreadcrumb: vi.fn(), + startTransaction: vi.fn(), + getCurrentTransaction: vi.fn(), + getCurrentSpan: vi.fn(), + setSpan: vi.fn(), + startSpan: vi.fn(), + flush: vi.fn(), + disable: vi.fn(), + enable: vi.fn(), + use: vi.fn(), + init: vi.fn(), + destroy: vi.fn(), + } as unknown as LightClient; + + consoleSpy = vi.spyOn(console, 'error').mockImplementation(() => {}); + }); + + describe('constructor', () => { + it('should create a PluginManager instance', () => { + const manager = new PluginManager(mockClient); + expect(manager).toBeDefined(); + }); + }); + + describe('add', () => { + it('should add a plugin', () => { + const manager = new PluginManager(mockClient); + const plugin: LightPlugin = { + name: 'test-plugin', + version: '1.0.0', + setup: vi.fn(), + }; + + manager.add(plugin); + expect(manager.has('test-plugin')).toBe(true); + }); + + it('should not add duplicate plugin', () => { + const manager = new PluginManager(mockClient); + const setup1 = vi.fn(); + const setup2 = vi.fn(); + const plugin1: LightPlugin = { + name: 'test-plugin', + version: '1.0.0', + setup: setup1, + }; + const plugin2: LightPlugin = { + name: 'test-plugin', + version: '2.0.0', + setup: setup2, + }; + + manager.add(plugin1); + manager.add(plugin2); + + expect(manager.has('test-plugin')).toBe(true); + expect(setup1).toHaveBeenCalledWith(mockClient); + expect(setup2).not.toHaveBeenCalled(); + }); + + it('should call plugin setup with client', () => { + const manager = new PluginManager(mockClient); + const setupFn = vi.fn(); + const plugin: LightPlugin = { + name: 'setup-test', + version: '1.0.0', + setup: setupFn, + }; + + manager.add(plugin); + expect(setupFn).toHaveBeenCalledWith(mockClient); + }); + + it('should not throw if setup throws', () => { + const manager = new PluginManager(mockClient); + const plugin: LightPlugin = { + name: 'error-plugin', + version: '1.0.0', + setup: () => { + throw new Error('Setup error'); + }, + }; + + expect(() => manager.add(plugin)).not.toThrow(); + expect(consoleSpy).toHaveBeenCalled(); + }); + }); + + describe('remove', () => { + it('should remove a plugin', () => { + const manager = new PluginManager(mockClient); + const plugin: LightPlugin = { + name: 'removable', + version: '1.0.0', + setup: vi.fn(), + }; + + manager.add(plugin); + expect(manager.has('removable')).toBe(true); + + manager.remove('removable'); + expect(manager.has('removable')).toBe(false); + }); + + it('should call plugin destroy when removing', () => { + const manager = new PluginManager(mockClient); + const destroyFn = vi.fn(); + const plugin: LightPlugin = { + name: 'destroyable', + version: '1.0.0', + setup: vi.fn(), + destroy: destroyFn, + }; + + manager.add(plugin); + manager.remove('destroyable'); + + expect(destroyFn).toHaveBeenCalled(); + }); + + it('should not throw if destroy throws', () => { + const manager = new PluginManager(mockClient); + const plugin: LightPlugin = { + name: 'destroy-error', + version: '1.0.0', + setup: vi.fn(), + destroy: () => { + throw new Error('Destroy error'); + }, + }; + + manager.add(plugin); + expect(() => manager.remove('destroy-error')).not.toThrow(); + expect(consoleSpy).toHaveBeenCalled(); + }); + + it('should do nothing if plugin does not exist', () => { + const manager = new PluginManager(mockClient); + manager.remove('non-existent'); + expect(consoleSpy).not.toHaveBeenCalled(); + }); + + it('should do nothing if plugin has no destroy method', () => { + const manager = new PluginManager(mockClient); + const plugin: LightPlugin = { + name: 'no-destroy', + version: '1.0.0', + setup: vi.fn(), + }; + + manager.add(plugin); + expect(() => manager.remove('no-destroy')).not.toThrow(); + }); + }); + + describe('get', () => { + it('should return plugin by name', () => { + const manager = new PluginManager(mockClient); + const plugin: LightPlugin = { + name: 'gettable', + version: '1.0.0', + setup: vi.fn(), + }; + + manager.add(plugin); + const retrieved = manager.get('gettable'); + expect(retrieved).toBe(plugin); + }); + + it('should return undefined for non-existent plugin', () => { + const manager = new PluginManager(mockClient); + const retrieved = manager.get('non-existent'); + expect(retrieved).toBeUndefined(); + }); + }); + + describe('has', () => { + it('should return true for added plugin', () => { + const manager = new PluginManager(mockClient); + const plugin: LightPlugin = { + name: 'checkable', + version: '1.0.0', + setup: vi.fn(), + }; + + manager.add(plugin); + expect(manager.has('checkable')).toBe(true); + }); + + it('should return false for non-existent plugin', () => { + const manager = new PluginManager(mockClient); + expect(manager.has('non-existent')).toBe(false); + }); + }); + + describe('applyBeforeReport', () => { + it('should pass event through all plugins', () => { + const manager = new PluginManager(mockClient); + const plugin1: LightPlugin = { + name: 'before-1', + version: '1.0.0', + setup: vi.fn(), + beforeReport: (event) => ({ ...event, extra: { ...event.extra, from1: true } }), + }; + const plugin2: LightPlugin = { + name: 'before-2', + version: '1.0.0', + setup: vi.fn(), + beforeReport: (event) => ({ ...event, extra: { ...event.extra, from2: true } }), + }; + + manager.add(plugin1); + manager.add(plugin2); + + const event = { type: 'error', level: 'error', timestamp: Date.now() } as SentryEvent; + const result = manager.applyBeforeReport(event); + + expect(result.extra).toEqual({ from1: true, from2: true }); + }); + + it('should return null if any plugin filters the event', () => { + const manager = new PluginManager(mockClient); + const plugin1: LightPlugin = { + name: 'filter-1', + version: '1.0.0', + setup: vi.fn(), + beforeReport: (event) => event, + }; + const plugin2: LightPlugin = { + name: 'filter-2', + version: '1.0.0', + setup: vi.fn(), + beforeReport: () => null, + }; + + manager.add(plugin1); + manager.add(plugin2); + + const event = { type: 'error', level: 'error', timestamp: Date.now() } as SentryEvent; + const result = manager.applyBeforeReport(event); + + expect(result).toBeNull(); + }); + + it('should continue if plugin beforeReport throws', () => { + const manager = new PluginManager(mockClient); + const plugin1: LightPlugin = { + name: 'error-before', + version: '1.0.0', + setup: vi.fn(), + beforeReport: () => { + throw new Error('BeforeReport error'); + }, + }; + const plugin2: LightPlugin = { + name: 'ok-after', + version: '1.0.0', + setup: vi.fn(), + beforeReport: (event) => ({ ...event, extra: { passed: true } }), + }; + + manager.add(plugin1); + manager.add(plugin2); + + const event = { type: 'error', level: 'error', timestamp: Date.now() } as SentryEvent; + const result = manager.applyBeforeReport(event); + + expect(result?.extra).toEqual({ passed: true }); + expect(consoleSpy).toHaveBeenCalled(); + }); + + it('should skip plugin without beforeReport', () => { + const manager = new PluginManager(mockClient); + const plugin1: LightPlugin = { + name: 'no-before', + version: '1.0.0', + setup: vi.fn(), + }; + const plugin2: LightPlugin = { + name: 'modify-after', + version: '1.0.0', + setup: vi.fn(), + beforeReport: (event) => ({ ...event, extra: { modified: true } }), + }; + + manager.add(plugin1); + manager.add(plugin2); + + const event = { type: 'error', level: 'error', timestamp: Date.now() } as SentryEvent; + const result = manager.applyBeforeReport(event); + + expect(result?.extra).toEqual({ modified: true }); + }); + + it('should return event when no plugins', () => { + const manager = new PluginManager(mockClient); + const event = { type: 'error', level: 'error', timestamp: Date.now() } as SentryEvent; + const result = manager.applyBeforeReport(event); + expect(result).toBe(event); + }); + }); + + describe('applyAfterReport', () => { + it('should call afterReport on all plugins', () => { + const manager = new PluginManager(mockClient); + const after1 = vi.fn(); + const after2 = vi.fn(); + const plugin1: LightPlugin = { + name: 'after-1', + version: '1.0.0', + setup: vi.fn(), + afterReport: after1, + }; + const plugin2: LightPlugin = { + name: 'after-2', + version: '1.0.0', + setup: vi.fn(), + afterReport: after2, + }; + + manager.add(plugin1); + manager.add(plugin2); + + const event = { type: 'error', level: 'error', timestamp: Date.now() } as SentryEvent; + manager.applyAfterReport(event); + + expect(after1).toHaveBeenCalledWith(event); + expect(after2).toHaveBeenCalledWith(event); + }); + + it('should continue if afterReport throws', () => { + const manager = new PluginManager(mockClient); + const plugin1: LightPlugin = { + name: 'error-after', + version: '1.0.0', + setup: vi.fn(), + afterReport: () => { + throw new Error('AfterReport error'); + }, + }; + const plugin2: LightPlugin = { + name: 'ok-after', + version: '1.0.0', + setup: vi.fn(), + afterReport: vi.fn(), + }; + + manager.add(plugin1); + manager.add(plugin2); + + const event = { type: 'error', level: 'error', timestamp: Date.now() } as SentryEvent; + expect(() => manager.applyAfterReport(event)).not.toThrow(); + expect(consoleSpy).toHaveBeenCalled(); + }); + + it('should skip plugin without afterReport', () => { + const manager = new PluginManager(mockClient); + const plugin: LightPlugin = { + name: 'no-after', + version: '1.0.0', + setup: vi.fn(), + }; + + manager.add(plugin); + + const event = { type: 'error', level: 'error', timestamp: Date.now() } as SentryEvent; + expect(() => manager.applyAfterReport(event)).not.toThrow(); + }); + }); + + describe('destroy', () => { + it('should call destroy on all plugins', () => { + const manager = new PluginManager(mockClient); + const destroy1 = vi.fn(); + const destroy2 = vi.fn(); + const plugin1: LightPlugin = { + name: 'destroy-1', + version: '1.0.0', + setup: vi.fn(), + destroy: destroy1, + }; + const plugin2: LightPlugin = { + name: 'destroy-2', + version: '1.0.0', + setup: vi.fn(), + destroy: destroy2, + }; + + manager.add(plugin1); + manager.add(plugin2); + manager.destroy(); + + expect(destroy1).toHaveBeenCalled(); + expect(destroy2).toHaveBeenCalled(); + }); + + it('should clear plugins after destroy', () => { + const manager = new PluginManager(mockClient); + const plugin: LightPlugin = { + name: 'clear-me', + version: '1.0.0', + setup: vi.fn(), + }; + + manager.add(plugin); + expect(manager.has('clear-me')).toBe(true); + + manager.destroy(); + expect(manager.has('clear-me')).toBe(false); + }); + + it('should continue even if destroy throws', () => { + const manager = new PluginManager(mockClient); + const plugin1: LightPlugin = { + name: 'destroy-error', + version: '1.0.0', + setup: vi.fn(), + destroy: () => { + throw new Error('Destroy error'); + }, + }; + const plugin2: LightPlugin = { + name: 'destroy-ok', + version: '1.0.0', + setup: vi.fn(), + destroy: vi.fn(), + }; + + manager.add(plugin1); + manager.add(plugin2); + manager.destroy(); + + expect(consoleSpy).toHaveBeenCalled(); + expect((plugin2 as any).destroy).toHaveBeenCalled(); + }); + + it('should not throw if plugin has no destroy method', () => { + const manager = new PluginManager(mockClient); + const plugin: LightPlugin = { + name: 'no-destroy', + version: '1.0.0', + setup: vi.fn(), + }; + + manager.add(plugin); + expect(() => manager.destroy()).not.toThrow(); + }); + }); +}); diff --git a/tests/SamplingPlugin.test.ts b/tests/SamplingPlugin.test.ts new file mode 100644 index 0000000..3fc80a4 --- /dev/null +++ b/tests/SamplingPlugin.test.ts @@ -0,0 +1,272 @@ +import { describe, it, expect, vi, beforeEach } from 'vitest'; +import SamplingPlugin from '../src/plugins/SamplingPlugin'; +import type { LightClient, LightConfig, SentryEvent, ErrorEvent } from '../src/types'; + +describe('SamplingPlugin', () => { + function createMockClient(configOverrides: Partial = {}): LightClient { + const config: LightConfig = { + dsn: 'https://abc@sentry.io/123', + sampleRate: 1, + sampling: { + rates: { + error: 1, + performance: 1, + network: 1, + behavior: 1, + }, + }, + ...configOverrides, + } as LightConfig; + + return { + config, + dsn: { protocol: 'https', publicKey: 'abc', host: 'sentry.io', projectId: '123' }, + on: vi.fn(), + off: vi.fn(), + emit: vi.fn(), + captureException: vi.fn(), + captureMessage: vi.fn(), + captureEvent: vi.fn(), + setUser: vi.fn(), + setAnonymousId: vi.fn(), + setTag: vi.fn(), + setTags: vi.fn(), + setExtra: vi.fn(), + addBreadcrumb: vi.fn(), + startTransaction: vi.fn(), + getCurrentTransaction: vi.fn(), + getCurrentSpan: vi.fn(), + setSpan: vi.fn(), + startSpan: vi.fn(), + flush: vi.fn(), + disable: vi.fn(), + enable: vi.fn(), + use: vi.fn(), + init: vi.fn(), + destroy: vi.fn(), + } as unknown as LightClient; + } + + function createErrorEvent(): ErrorEvent { + return { + type: 'error', + level: 'error', + message: 'Test error', + timestamp: Date.now(), + }; + } + + function createEvent(type: string): SentryEvent { + return { + type: type as any, + level: 'info', + timestamp: Date.now(), + } as SentryEvent; + } + + describe('constructor', () => { + it('should create plugin with correct name and version', () => { + const plugin = new SamplingPlugin(); + expect(plugin.name).toBe('sampling'); + expect(plugin.version).toBe('1.0.0'); + }); + }); + + describe('setup', () => { + it('should call setup with client', () => { + const plugin = new SamplingPlugin(); + const client = createMockClient(); + expect(() => plugin.setup(client)).not.toThrow(); + }); + + it('should load default rates when no sampling config', () => { + const plugin = new SamplingPlugin(); + const client = createMockClient({ sampling: undefined }); + plugin.setup(client); + const event = createErrorEvent(); + const result = plugin.beforeReport(event); + expect(result).not.toBeNull(); + }); + + it('should load custom rates from config', () => { + const plugin = new SamplingPlugin(); + const client = createMockClient({ + sampleRate: 1, + sampling: { + rates: { + error: 0.5, + performance: 0.1, + }, + }, + }); + plugin.setup(client); + const randomSpy = vi.spyOn(Math, 'random').mockReturnValue(0.1); + expect(plugin.beforeReport(createEvent('error'))).toBeTruthy(); + randomSpy.mockRestore(); + }); + }); + + describe('beforeReport', () => { + it('should return event when sampling rate is 1', () => { + const plugin = new SamplingPlugin(); + const client = createMockClient({ sampleRate: 1 }); + plugin.setup(client); + const event = createErrorEvent(); + const result = plugin.beforeReport(event); + expect(result).toBe(event); + }); + + it('should return null when global sampleRate is 0', () => { + const plugin = new SamplingPlugin(); + const client = createMockClient({ sampleRate: 0 }); + plugin.setup(client); + const event = createErrorEvent(); + const result = plugin.beforeReport(event); + expect(result).toBeNull(); + }); + + it('should return null when global sampleRate is negative', () => { + const plugin = new SamplingPlugin(); + const client = createMockClient({ sampleRate: -1 }); + plugin.setup(client); + const event = createErrorEvent(); + const result = plugin.beforeReport(event); + expect(result).toBeNull(); + }); + + it('should return event when type rate is 1', () => { + const plugin = new SamplingPlugin(); + const client = createMockClient({ + sampleRate: 1, + sampling: { rates: { error: 1 } }, + }); + plugin.setup(client); + const event = createErrorEvent(); + const result = plugin.beforeReport(event); + expect(result).toBe(event); + }); + + it('should return null when type rate is 0', () => { + const plugin = new SamplingPlugin(); + const client = createMockClient({ + sampleRate: 1, + sampling: { rates: { error: 0 } }, + }); + plugin.setup(client); + const event = createErrorEvent(); + const result = plugin.beforeReport(event); + expect(result).toBeNull(); + }); + + it('should always sample count events (rate = 1)', () => { + const plugin = new SamplingPlugin(); + const client = createMockClient({ + sampleRate: 0, + sampling: { rates: { error: 0 } }, + }); + plugin.setup(client); + const countEvent = { + type: 'count' as const, + level: 'info' as const, + timestamp: Date.now(), + fingerprint: 'test', + count: 1, + ts_start: Date.now(), + ts_end: Date.now(), + }; + const result = plugin.beforeReport(countEvent); + expect(result).toBeNull(); + }); + + it('should handle unknown event types (default rate = 1)', () => { + const plugin = new SamplingPlugin(); + const client = createMockClient({ sampleRate: 1 }); + plugin.setup(client); + const unknownEvent = createEvent('unknown_type'); + const result = plugin.beforeReport(unknownEvent); + expect(result).not.toBeNull(); + }); + + it('should use combined rate when globalRate < 1', () => { + const plugin = new SamplingPlugin(); + const client = createMockClient({ + sampleRate: 0.5, + sampling: { rates: { error: 0.5 } }, + }); + plugin.setup(client); + const randomSpy = vi.spyOn(Math, 'random').mockReturnValue(0.9); + const event = createErrorEvent(); + const result = plugin.beforeReport(event); + expect(result).toBeNull(); + randomSpy.mockRestore(); + }); + + it('should pass when random is below combined rate', () => { + const plugin = new SamplingPlugin(); + const client = createMockClient({ + sampleRate: 0.5, + sampling: { rates: { error: 0.5 } }, + }); + plugin.setup(client); + const randomSpy = vi.spyOn(Math, 'random').mockReturnValue(0.1); + const event = createErrorEvent(); + const result = plugin.beforeReport(event); + expect(result).toBe(event); + randomSpy.mockRestore(); + }); + + it('should pass when type rate is 1 and globalRate is 1', () => { + const plugin = new SamplingPlugin(); + const client = createMockClient({ sampleRate: 1 }); + plugin.setup(client); + const randomSpy = vi.spyOn(Math, 'random').mockReturnValue(0.99); + const event = createErrorEvent(); + const result = plugin.beforeReport(event); + expect(result).toBe(event); + randomSpy.mockRestore(); + }); + }); + + describe('destroy', () => { + it('should not throw when destroy is called', () => { + const plugin = new SamplingPlugin(); + expect(() => plugin.destroy()).not.toThrow(); + }); + }); + + describe('config loading', () => { + it('should handle missing sampling config', () => { + const plugin = new SamplingPlugin(); + const client = createMockClient({ sampling: undefined }); + plugin.setup(client); + const event = createErrorEvent(); + const result = plugin.beforeReport(event); + expect(result).not.toBeNull(); + }); + + it('should handle sampling config without rates', () => { + const plugin = new SamplingPlugin(); + const client = createMockClient({ sampling: {} }); + plugin.setup(client); + const event = createErrorEvent(); + const result = plugin.beforeReport(event); + expect(result).not.toBeNull(); + }); + + it('should merge custom rates with defaults', () => { + const plugin = new SamplingPlugin(); + const client = createMockClient({ + sampling: { + rates: { + error: 0.5, + }, + }, + }); + plugin.setup(client); + const randomSpy = vi.spyOn(Math, 'random').mockReturnValue(0.9); + expect(plugin.beforeReport(createEvent('error'))).toBeNull(); + expect(plugin.beforeReport(createEvent('performance'))).not.toBeNull(); + randomSpy.mockRestore(); + }); + }); +}); diff --git a/tests/TracingManager.test.ts b/tests/TracingManager.test.ts new file mode 100644 index 0000000..8b8a8fe --- /dev/null +++ b/tests/TracingManager.test.ts @@ -0,0 +1,350 @@ +import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest'; +import { TracingManager } from '../src/core/TracingManager'; +import type { LightConfig, Transaction, Span } from '../src/types'; + +describe('TracingManager', () => { + let tracingManager: TracingManager; + let mockClient: ReturnType; + + beforeEach(() => { + mockClient = createMockClient(); + const config: LightConfig = { + dsn: 'https://abc@log.example.com/1001', + tracesSampleRate: 1, + }; + tracingManager = new TracingManager(config, mockClient, 'abc'); + }); + + afterEach(() => { + tracingManager.destroy(); + vi.clearAllMocks(); + }); + + describe('startTransaction', () => { + it('should create transaction with correct properties', () => { + const transaction = tracingManager.startTransaction({ + name: 'test-transaction', + op: 'custom', + }); + + expect(transaction).toBeDefined(); + expect(transaction?.name).toBe('test-transaction'); + expect(transaction?.op).toBe('custom'); + expect(transaction?.traceId).toBeDefined(); + expect(transaction?.spanId).toBeDefined(); + expect(transaction?.sampled).toBe(true); // tracesSampleRate = 1 + }); + + it('should return transaction even when SDK would be disabled (TracingManager does not check enabled)', () => { + // Note: Client.startTransaction checks enabled, but TracingManager does not + const disabledConfig: LightConfig = { + dsn: 'https://abc@log.example.com/1001', + enabled: false, + tracesSampleRate: 1, + }; + const disabledManager = new TracingManager(disabledConfig, mockClient, 'abc'); + + const transaction = disabledManager.startTransaction({ + name: 'test-transaction', + }); + + // TracingManager doesn't know about enabled flag, it still creates transaction + expect(transaction).toBeDefined(); + disabledManager.destroy(); + }); + + it('should sample transaction based on tracesSampleRate', () => { + const sampledConfig: LightConfig = { + dsn: 'https://abc@log.example.com/1001', + tracesSampleRate: 0, // No sampling + }; + const sampledManager = new TracingManager(sampledConfig, mockClient, 'abc'); + + const transaction = sampledManager.startTransaction({ + name: 'test-transaction', + }); + + expect(transaction?.sampled).toBe(false); + sampledManager.destroy(); + }); + + it('should use tracesSampler for dynamic sampling', () => { + const customSamplerConfig: LightConfig = { + dsn: 'https://abc@log.example.com/1001', + tracesSampler: () => false, + }; + const customSamplerManager = new TracingManager(customSamplerConfig, mockClient, 'abc'); + + const transaction = customSamplerManager.startTransaction({ + name: 'test-transaction', + }); + + expect(transaction?.sampled).toBe(false); + customSamplerManager.destroy(); + }); + + it('should set current transaction after start', () => { + const transaction = tracingManager.startTransaction({ + name: 'test-transaction', + }); + + expect(tracingManager.getCurrentTransaction()).toBe(transaction); + }); + + it('should use tracesSampler for dynamic sampling with parentSampled', () => { + // With tracesSampler, parentSampled is passed to the sampler + const customSamplerConfig: LightConfig = { + dsn: 'https://abc@log.example.com/1001', + tracesSampler: (ctx) => { + // If parent was sampled=false, child should also be not sampled + if (ctx.parentSampled === false) { + return false; + } + return true; + }, + }; + const parentSamplerManager = new TracingManager(customSamplerConfig, mockClient, 'abc'); + + const parentTransaction = parentSamplerManager.startTransaction({ + name: 'parent', + sampled: false, + }); + + const childTransaction = parentSamplerManager.startTransaction({ + name: 'child', + sampled: undefined, + }); + + // Child should inherit parent's sampled=false via tracesSampler + expect(childTransaction?.sampled).toBe(false); + parentSamplerManager.destroy(); + }); + }); + + describe('getCurrentTransaction', () => { + it('should return null when no transaction exists', () => { + expect(tracingManager.getCurrentTransaction()).toBeNull(); + }); + + it('should return current transaction', () => { + const transaction = tracingManager.startTransaction({ + name: 'test-transaction', + }); + + expect(tracingManager.getCurrentTransaction()).toBe(transaction); + }); + + it('should return current transaction after finish (via TracingManager.onTransactionFinished)', () => { + // Note: Transaction.finish() calls client.tracingManager.onTransactionFinished + // if client is properly set up. With mock client, this doesn't happen automatically. + const transaction = tracingManager.startTransaction({ + name: 'test-transaction', + }); + + expect(tracingManager.getCurrentTransaction()).toBe(transaction); + + // Manually call onTransactionFinished to simulate proper cleanup + tracingManager.onTransactionFinished(transaction!); + expect(tracingManager.getCurrentTransaction()).toBeNull(); + }); + }); + + describe('getCurrentSpan', () => { + it('should return transaction as span when no child spans', () => { + const transaction = tracingManager.startTransaction({ + name: 'test-transaction', + }); + + const currentSpan = tracingManager.getCurrentSpan(); + expect(currentSpan?.spanId).toBe(transaction?.spanId); + }); + + it('should return most recent child span', () => { + const transaction = tracingManager.startTransaction({ + name: 'test-transaction', + }); + + const childSpan = tracingManager.startSpan({ + op: 'child.span', + description: 'child operation', + }); + + const currentSpan = tracingManager.getCurrentSpan(); + expect(currentSpan?.spanId).toBe(childSpan?.spanId); + }); + }); + + describe('startSpan', () => { + it('should create child span under current transaction', () => { + tracingManager.startTransaction({ + name: 'test-transaction', + }); + + const childSpan = tracingManager.startSpan({ + op: 'http.client', + description: 'GET /api/users', + }); + + expect(childSpan).toBeDefined(); + expect(childSpan?.op).toBe('http.client'); + expect(childSpan?.parentSpanId).toBeDefined(); + }); + + it('should return null when no active span and no traceId', () => { + const noSpanManager = new TracingManager( + { dsn: 'https://abc@log.example.com/1001' }, + mockClient, + 'abc' + ); + + const span = noSpanManager.startSpan({ + op: 'test.span', + }); + + expect(span).toBeNull(); + noSpanManager.destroy(); + }); + + it('should create span with traceId when no parent span exists', () => { + const noSpanManager = new TracingManager( + { dsn: 'https://abc@log.example.com/1001' }, + mockClient, + 'abc' + ); + + const span = noSpanManager.startSpan({ + op: 'test.span', + traceId: 'abcd1234abcd1234abcd1234abcd1234', + }); + + expect(span).toBeDefined(); + expect(span?.traceId).toBe('abcd1234abcd1234abcd1234abcd1234'); + noSpanManager.destroy(); + }); + + it('should not add span to unsampled transaction', () => { + const unsampledManager = new TracingManager( + { dsn: 'https://abc@log.example.com/1001', tracesSampleRate: 0 }, + mockClient, + 'abc' + ); + + const transaction = unsampledManager.startTransaction({ name: 'unsampled' }); + const span = unsampledManager.startSpan({ op: 'child' }); + + expect(span).toBeDefined(); + // Span should not be in transaction.spans for unsampled transaction + expect(transaction?.spans.length).toBe(0); + unsampledManager.destroy(); + }); + }); + + describe('setCurrentSpan', () => { + it('should set current span', () => { + tracingManager.startTransaction({ name: 'test' }); + + const customSpan = { spanId: 'custom-span' } as Span; + tracingManager.setCurrentSpan(customSpan); + + expect(tracingManager.getCurrentSpan()?.spanId).toBe('custom-span'); + }); + + it('should pop span from stack when set to null', () => { + tracingManager.startTransaction({ name: 'test' }); + const childSpan = tracingManager.startSpan({ op: 'child' }); + expect(tracingManager.getCurrentSpan()?.spanId).toBe(childSpan?.spanId); + + tracingManager.setCurrentSpan(null); + // Should return to transaction + expect(tracingManager.getCurrentSpan()?.spanId).toBeDefined(); + }); + }); + + describe('onSpanFinished', () => { + it('should remove finished span from stack', () => { + tracingManager.startTransaction({ name: 'test' }); + const childSpan = tracingManager.startSpan({ op: 'child' }); + expect(tracingManager.getCurrentSpan()?.spanId).toBe(childSpan?.spanId); + + tracingManager.onSpanFinished(childSpan!); + // Should return to transaction after child is removed + expect(tracingManager.getCurrentSpan()?.spanId).toBeDefined(); + }); + }); + + describe('onTransactionFinished', () => { + it('should clear current transaction', () => { + const transaction = tracingManager.startTransaction({ name: 'test' }); + expect(tracingManager.getCurrentTransaction()).toBe(transaction); + + tracingManager.onTransactionFinished(transaction!); + expect(tracingManager.getCurrentTransaction()).toBeNull(); + }); + }); + + describe('updateConfig', () => { + it('should update baggage when user changes', () => { + const transaction = tracingManager.startTransaction({ name: 'test' }); + expect(transaction).toBeDefined(); + + tracingManager.updateConfig({ + dsn: 'https://abc@log.example.com/1001', + user: { id: 'user123', segment: 'premium' }, + }); + + // Transaction baggage should have user info + // This is an internal detail, just verify no error + expect(transaction).toBeDefined(); + }); + }); + + describe('destroy', () => { + it('should finish current transaction on destroy', () => { + const transaction = tracingManager.startTransaction({ name: 'test' }); + + tracingManager.destroy(); + + // Transaction should be finished (sampled=false since no client capture) + expect(tracingManager.getCurrentTransaction()).toBeNull(); + }); + + it('should clear span stack on destroy', () => { + tracingManager.startTransaction({ name: 'test' }); + tracingManager.startSpan({ op: 'child' }); + + tracingManager.destroy(); + + expect(tracingManager.getCurrentSpan()).toBeNull(); + }); + }); +}); + +function createMockClient() { + return { + config: {}, + dsn: { protocol: 'https', publicKey: 'abc', host: 'log.example.com', projectId: '1001' }, + captureException: vi.fn(), + captureMessage: vi.fn(), + captureEvent: vi.fn(), + setUser: vi.fn(), + setAnonymousId: vi.fn(), + setTag: vi.fn(), + setTags: vi.fn(), + setExtra: vi.fn(), + addBreadcrumb: vi.fn(), + startTransaction: vi.fn(), + getCurrentTransaction: vi.fn(), + getCurrentSpan: vi.fn(), + setSpan: vi.fn(), + startSpan: vi.fn(), + flush: vi.fn(), + disable: vi.fn(), + enable: vi.fn(), + use: vi.fn(), + init: vi.fn(), + destroy: vi.fn(), + on: vi.fn(), + off: vi.fn(), + emit: vi.fn(), + } as any; +} diff --git a/tests/baggage.test.ts b/tests/baggage.test.ts new file mode 100644 index 0000000..464d8e7 --- /dev/null +++ b/tests/baggage.test.ts @@ -0,0 +1,250 @@ +import { describe, it, expect } from 'vitest'; +import { + serializeBaggage, + parseBaggage, + createBaggageFromTransaction, +} from '../src/utils/baggage'; +import type { BaggageFields } from '../src/types'; + +describe('baggage utils', () => { + describe('serializeBaggage', () => { + it('should serialize empty baggage', () => { + const result = serializeBaggage({}); + expect(result).toBe(''); + }); + + it('should serialize baggage with all fields', () => { + const baggage: BaggageFields = { + trace_id: 'abc123', + public_key: 'key123', + sample_rate: '0.5', + sampled: 'true', + user_id: 'user1', + user_segment: 'premium', + release: '1.0.0', + environment: 'production', + }; + + const result = serializeBaggage(baggage); + + expect(result).toContain('sentry-trace_id=abc123'); + expect(result).toContain('sentry-public_key=key123'); + expect(result).toContain('sentry-sample_rate=0.5'); + expect(result).toContain('sentry-sampled=true'); + expect(result).toContain('sentry-user_id=user1'); + expect(result).toContain('sentry-user_segment=premium'); + expect(result).toContain('sentry-release=1.0.0'); + expect(result).toContain('sentry-environment=production'); + }); + + it('should skip null, undefined, and empty string values', () => { + const baggage: BaggageFields = { + trace_id: 'abc123', + public_key: undefined as any, + sampled: '', + }; + + const result = serializeBaggage(baggage); + + expect(result).toContain('sentry-trace_id=abc123'); + expect(result).not.toContain('public_key'); + expect(result).not.toContain('sampled'); + }); + + it('should add sentry- prefix to non-sentry keys', () => { + const baggage: BaggageFields = { + trace_id: 'abc123', + custom_field: 'value', + }; + + const result = serializeBaggage(baggage); + + expect(result).toContain('sentry-trace_id=abc123'); + expect(result).toContain('sentry-custom_field=value'); + }); + + it('should preserve sentry- prefix on sentry keys', () => { + const baggage: BaggageFields = { + 'sentry-trace_id': 'abc123', + }; + + const result = serializeBaggage(baggage); + + expect(result).toContain('sentry-trace_id=abc123'); + // Should not double-prefix + expect(result).not.toContain('sentry-sentry-'); + }); + + it('should truncate long baggage to 8192 characters', () => { + const longBaggage: BaggageFields = {}; + // Create a very long value + const longValue = 'a'.repeat(10000); + longBaggage.trace_id = longValue; + + const result = serializeBaggage(longBaggage); + + expect(result.length).toBeLessThanOrEqual(8192); + }); + + it('should URL encode values', () => { + const baggage: BaggageFields = { + user_id: 'user with spaces', + custom_field: 'value=special&chars', + }; + + const result = serializeBaggage(baggage); + + expect(result).toContain(encodeURIComponent('user with spaces')); + expect(result).toContain(encodeURIComponent('value=special&chars')); + }); + }); + + describe('parseBaggage', () => { + it('should parse empty baggage', () => { + const result = parseBaggage(''); + expect(result).toEqual({}); + }); + + it('should parse valid baggage header', () => { + const header = 'sentry-trace_id=abc123,sentry-sampled=true,sentry-user_id=user1'; + const result = parseBaggage(header); + + expect(result.trace_id).toBe('abc123'); + expect(result.sampled).toBe('true'); + expect(result.user_id).toBe('user1'); + }); + + it('should remove sentry- prefix from keys', () => { + const header = 'sentry-public_key=key123,sentry-release=1.0.0'; + const result = parseBaggage(header); + + expect(result.public_key).toBe('key123'); + expect(result.release).toBe('1.0.0'); + expect(result['sentry-public_key']).toBeUndefined(); + }); + + it('should handle custom fields without prefix', () => { + const header = 'custom_field=value,another=data'; + const result = parseBaggage(header); + + expect(result.custom_field).toBe('value'); + expect(result.another).toBe('data'); + }); + + it('should URL decode values', () => { + const header = `sentry-user_id=${encodeURIComponent('user with spaces')}`; + const result = parseBaggage(header); + + expect(result.user_id).toBe('user with spaces'); + }); + + it('should skip malformed entries', () => { + const header = 'valid=key,invalid-entry-no-equals,sentry-trace_id=abc123'; + const result = parseBaggage(header); + + expect(result.valid).toBe('key'); + expect(result['sentry-trace_id']).toBeUndefined(); + expect(result.trace_id).toBe('abc123'); + }); + + it('should handle whitespace around entries', () => { + const header = ' sentry-trace_id=abc123 , sentry-sampled=true '; + const result = parseBaggage(header); + + expect(result.trace_id).toBe('abc123'); + expect(result.sampled).toBe('true'); + }); + }); + + describe('createBaggageFromTransaction', () => { + it('should create baggage with only trace_id', () => { + const result = createBaggageFromTransaction('abc123'); + + expect(result.trace_id).toBe('abc123'); + expect(Object.keys(result)).toHaveLength(1); + }); + + it('should create baggage with all options', () => { + const result = createBaggageFromTransaction('abc123', { + dsnPublicKey: 'key123', + sampled: true, + sampleRate: 0.5, + user: { id: 'user1', segment: 'premium' }, + release: '1.0.0', + environment: 'production', + }); + + expect(result.trace_id).toBe('abc123'); + expect(result.public_key).toBe('key123'); + expect(result.sampled).toBe('true'); + expect(result.sample_rate).toBe('0.5'); + expect(result.user_id).toBe('user1'); + expect(result.user_segment).toBe('premium'); + expect(result.release).toBe('1.0.0'); + expect(result.environment).toBe('production'); + }); + + it('should convert sampled boolean to string', () => { + expect(createBaggageFromTransaction('abc', { sampled: true }).sampled).toBe('true'); + expect(createBaggageFromTransaction('abc', { sampled: false }).sampled).toBe('false'); + }); + + it('should convert sampleRate number to string', () => { + const result = createBaggageFromTransaction('abc', { sampleRate: 0.1 }); + expect(result.sample_rate).toBe('0.1'); + }); + + it('should handle optional user object', () => { + const result1 = createBaggageFromTransaction('abc', { user: { id: 'user1' } }); + expect(result1.user_id).toBe('user1'); + expect(result1.user_segment).toBeUndefined(); + + const result2 = createBaggageFromTransaction('abc', { user: { id: 'user2', segment: 'vip' } }); + expect(result2.user_id).toBe('user2'); + expect(result2.user_segment).toBe('vip'); + }); + + it('should not include undefined options', () => { + const result = createBaggageFromTransaction('abc', { + dsnPublicKey: 'key', + sampled: undefined, + sampleRate: undefined, + }); + + expect(result.trace_id).toBe('abc'); + expect(result.public_key).toBe('key'); + expect(result.sampled).toBeUndefined(); + expect(result.sample_rate).toBeUndefined(); + }); + + it('should work without options', () => { + const result = createBaggageFromTransaction('abc'); + expect(result.trace_id).toBe('abc'); + }); + }); + + describe('serialize/parse roundtrip', () => { + it('should preserve baggage through serialize/parse cycle', () => { + const original: BaggageFields = { + trace_id: 'abc123', + public_key: 'key123', + sampled: 'true', + user_id: 'user1', + release: '1.0.0', + environment: 'production', + custom: 'value', + }; + + const serialized = serializeBaggage(original); + const parsed = parseBaggage(serialized); + + expect(parsed.trace_id).toBe(original.trace_id); + expect(parsed.public_key).toBe(original.public_key); + expect(parsed.sampled).toBe(original.sampled); + expect(parsed.user_id).toBe(original.user_id); + expect(parsed.release).toBe(original.release); + expect(parsed.environment).toBe(original.environment); + expect(parsed.custom).toBe(original.custom); + }); + }); +}); diff --git a/tests/env.test.ts b/tests/env.test.ts index 3c13165..c55f30e 100644 --- a/tests/env.test.ts +++ b/tests/env.test.ts @@ -1,4 +1,4 @@ -import { describe, it, expect } from 'vitest'; +import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest'; import { getEnvInfo, getContexts, @@ -10,6 +10,17 @@ import { } from '../src/utils/env'; describe('env utils', () => { + const originalNavigator = global.navigator; + const originalUserAgent = navigator.userAgent; + + function setUserAgent(ua: string) { + Object.defineProperty(global.navigator, 'userAgent', { + value: ua, + configurable: true, + writable: true, + }); + } + describe('getEnvInfo', () => { it('should return env info object', () => { const env = getEnvInfo(); @@ -38,6 +49,158 @@ describe('env utils', () => { }); }); + describe('browser detection', () => { + const testCases = [ + { + name: 'Chrome on Windows', + ua: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36', + browser: 'Chrome', + os: 'Windows 11', + device: 'desktop', + }, + { + name: 'Firefox on macOS', + ua: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:121.0) Gecko/20100101 Firefox/121.0', + browser: 'Firefox', + os: 'macOS', + device: 'desktop', + }, + { + name: 'Safari on macOS', + ua: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 14_2) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.2 Safari/605.1.15', + browser: 'Safari', + os: 'macOS', + device: 'desktop', + }, + { + name: 'Edge on Windows', + ua: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36 Edg/120.0.0.0', + browser: 'Edge', + os: 'Windows 11', + device: 'desktop', + }, + { + name: 'WeChat', + ua: 'Mozilla/5.0 (iPhone; CPU iPhone OS 17_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 MicroMessenger/8.0.33(0x1800212d)', + browser: 'WeChat', + os: 'iOS', + device: 'mobile', + }, + { + name: 'iPhone Safari', + ua: 'Mozilla/5.0 (iPhone; CPU iPhone OS 17_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.0 Mobile/15E148 Safari/604.1', + browser: 'Safari', + os: 'iOS', + device: 'mobile', + }, + { + name: 'iPad Safari', + ua: 'Mozilla/5.0 (iPad; CPU OS 17_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.0 Mobile/15E148 Safari/604.1', + browser: 'Safari', + os: 'iOS', + device: 'tablet', + }, + { + name: 'Android Chrome', + ua: 'Mozilla/5.0 (Linux; Android 13; SM-G991B) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Mobile Safari/537.36', + browser: 'Chrome', + os: 'Android', + device: 'mobile', + }, + { + name: 'Samsung device', + ua: 'Mozilla/5.0 (Linux; Android 13; SM-G991B) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Mobile Safari/537.36', + browser: 'Chrome', + os: 'Android', + device: 'mobile', + vendor: 'Samsung', + }, + { + name: 'Opera', + ua: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36 OPR/106.0.0.0', + browser: 'Opera', + os: 'Windows 11', + device: 'desktop', + }, + ]; + + testCases.forEach(tc => { + it(`should detect ${tc.name}`, () => { + setUserAgent(tc.ua); + const env = getEnvInfo(); + expect(env.browser.name).toBe(tc.browser); + expect(env.os.name).toBe(tc.os); + expect(env.device.type).toBe(tc.device); + }); + }); + + it('should detect Unknown browser for unrecognized UA', () => { + setUserAgent('SomeCustomBot/1.0'); + const env = getEnvInfo(); + expect(env.browser.name).toBe('Unknown'); + }); + + it('should detect Windows 11', () => { + setUserAgent('Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36'); + // The current code doesn't distinguish Win10 vs Win11 based on Win64 x64 alone + const env = getEnvInfo(); + expect(env.os.name).toMatch(/Windows/); + }); + + it('should parse browser version', () => { + setUserAgent('Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.5481.100 Safari/537.36'); + const env = getEnvInfo(); + expect(env.browser.version).toMatch(/^120/); + expect(env.browser.major).toBe('120'); + }); + + it('should parse macOS version with underscores', () => { + setUserAgent('Mozilla/5.0 (Macintosh; Intel Mac OS X 14_2_1) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.2 Safari/605.1.15'); + const env = getEnvInfo(); + expect(env.os.name).toBe('macOS'); + expect(env.os.version).toContain('14.2.1'); + }); + }); + + describe('device detection', () => { + it('should detect iPhone as mobile Apple device', () => { + setUserAgent('Mozilla/5.0 (iPhone; CPU iPhone OS 17_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.0 Mobile/15E148 Safari/604.1'); + const env = getEnvInfo(); + expect(env.device.type).toBe('mobile'); + expect(env.device.vendor).toBe('Apple'); + expect(env.device.model).toBe('iPhone'); + }); + + it('should detect iPad as tablet Apple device', () => { + setUserAgent('Mozilla/5.0 (iPad; CPU OS 17_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.0 Mobile/15E148 Safari/604.1'); + const env = getEnvInfo(); + expect(env.device.type).toBe('tablet'); + expect(env.device.vendor).toBe('Apple'); + expect(env.device.model).toBe('iPad'); + }); + + it('should detect Samsung device', () => { + setUserAgent('Mozilla/5.0 (Linux; Android 13; SM-G991B) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Mobile Safari/537.36'); + const env = getEnvInfo(); + expect(env.device.vendor).toBe('Samsung'); + expect(env.device.model).toBe('G991B'); + }); + + it('should detect Pixel device', () => { + setUserAgent('Mozilla/5.0 (Linux; Android 14; Pixel 8) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Mobile Safari/537.36'); + const env = getEnvInfo(); + expect(env.device.vendor).toBe('Google'); + expect(env.device.model).toBe('Pixel 8'); + }); + + it('should detect Huawei device', () => { + setUserAgent('Mozilla/5.0 (Linux; Android 12; HUAWEI Mate40 Pro) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Mobile Safari/537.36'); + const env = getEnvInfo(); + expect(env.device.vendor).toBe('Huawei'); + expect(env.device.model).toBe('Mate40'); + }); + }); + describe('getContexts', () => { it('should return contexts with encoded values', () => { const contexts = getContexts(); @@ -56,13 +219,26 @@ describe('env utils', () => { const contexts = getContexts(); expect(contexts.os.name.length).toBeLessThanOrEqual(10); }); + + it('should map Chrome to c', () => { + setUserAgent('Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36'); + const contexts = getContexts(); + expect(contexts.browser.name).toBe('c'); + }); + + it('should map Windows 11 to w11', () => { + setUserAgent('Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36'); + const contexts = getContexts(); + expect(contexts.os.name).toBe('w11'); + }); }); describe('getContextId', () => { - it('should return a 16 character string', () => { + it('should return a hex string of up to 8 characters (32-bit hash)', () => { const contextId = getContextId(); expect(contextId).toBeDefined(); - expect(contextId.length).toBe(16); + expect(contextId.length).toBeLessThanOrEqual(16); + expect(contextId.length).toBeGreaterThan(0); expect(contextId).toMatch(/^[a-f0-9]+$/i); }); @@ -121,6 +297,49 @@ describe('env utils', () => { expect(sanitized).toContain('code'); expect(sanitized).toContain('%5BFiltered%5D'); }); + + it('should filter sensitive params in hash', () => { + const url = 'https://example.com/page#access_token=secret123&other=value'; + const sanitized = sanitizeUrl(url); + expect(sanitized).toContain('access_token'); + expect(sanitized).toContain('%5BFiltered%5D'); + }); + + it('should filter javascript: protocol', () => { + const url = 'javascript:alert(1)'; + const sanitized = sanitizeUrl(url); + expect(sanitized).toBe('javascript:[filtered]'); + }); + + it('should filter javascript: with whitespace', () => { + const url = ' javascript:alert(document.cookie)'; + const sanitized = sanitizeUrl(url); + expect(sanitized).toBe('javascript:[filtered]'); + }); + + it('should handle empty string', () => { + const sanitized = sanitizeUrl(''); + expect(sanitized).toBe(''); + }); + + it('should handle null/undefined', () => { + expect(sanitizeUrl(null as any)).toBeNull(); + expect(sanitizeUrl(undefined as any)).toBeUndefined(); + }); + + it('should filter multiple sensitive params', () => { + const url = 'https://example.com/api?password=pwd&token=tkn&api_key=key&secret=sec&session=sess'; + const sanitized = sanitizeUrl(url); + expect(sanitized).toContain('%5BFiltered%5D'); + const filteredCount = (sanitized.match(/%5BFiltered%5D/g) || []).length; + expect(filteredCount).toBe(5); + }); + + it('should keep non-sensitive params unchanged', () => { + const url = 'https://example.com/api?page=1&limit=10&sort=desc'; + const sanitized = sanitizeUrl(url); + expect(sanitized).toBe(url); + }); }); describe('shouldIgnoreUrl', () => { @@ -153,5 +372,18 @@ describe('env utils', () => { const result = shouldIgnoreUrl('https://example.com/api/users/123', [/api\/users\/\d+/]); expect(result).toBe(true); }); + + it('should match multiple patterns (OR logic)', () => { + const patterns = ['/health', '/metrics', /\/debug/]; + expect(shouldIgnoreUrl('https://example.com/health', patterns)).toBe(true); + expect(shouldIgnoreUrl('https://example.com/api/metrics', patterns)).toBe(true); + expect(shouldIgnoreUrl('https://example.com/debug/vars', patterns)).toBe(true); + expect(shouldIgnoreUrl('https://example.com/api/users', patterns)).toBe(false); + }); + + it('should match wildcard with multiple *', () => { + const result = shouldIgnoreUrl('https://api.example.com/v1/users/123/info', ['*.example.com/*/users/*']); + expect(result).toBe(true); + }); }); }); diff --git a/tests/field-encoder.test.ts b/tests/field-encoder.test.ts new file mode 100644 index 0000000..4b4ea11 --- /dev/null +++ b/tests/field-encoder.test.ts @@ -0,0 +1,239 @@ +import { describe, it, expect } from 'vitest'; +import { + FIELD_ENCODE_MAP, + FIELD_DECODE_MAP, + encodeFields, + decodeFields, +} from '../src/utils/field-encoder'; + +describe('field-encoder', () => { + describe('FIELD_ENCODE_MAP', () => { + it('should contain mappings for all basic fields', () => { + expect(FIELD_ENCODE_MAP.event_id).toBe('eid'); + expect(FIELD_ENCODE_MAP.timestamp).toBe('ts'); + expect(FIELD_ENCODE_MAP.start_timestamp).toBe('sts'); + expect(FIELD_ENCODE_MAP.type).toBe('t'); + expect(FIELD_ENCODE_MAP.level).toBe('l'); + expect(FIELD_ENCODE_MAP.message).toBe('m'); + expect(FIELD_ENCODE_MAP.platform).toBe('p'); + expect(FIELD_ENCODE_MAP.release).toBe('r'); + expect(FIELD_ENCODE_MAP.environment).toBe('e'); + expect(FIELD_ENCODE_MAP.fingerprint).toBe('fp'); + expect(FIELD_ENCODE_MAP.context_id).toBe('cid'); + }); + + it('should contain mappings for user fields', () => { + expect(FIELD_ENCODE_MAP.user).toBe('u'); + }); + + it('should contain mappings for tags', () => { + expect(FIELD_ENCODE_MAP.tags).toBe('tg'); + }); + + it('should contain mappings for exception', () => { + expect(FIELD_ENCODE_MAP.exception).toBe('ex'); + }); + + it('should contain mappings for request', () => { + expect(FIELD_ENCODE_MAP.request).toBe('req'); + }); + + it('should contain mappings for contexts', () => { + expect(FIELD_ENCODE_MAP.contexts).toBe('ctx'); + }); + + it('should contain mappings for breadcrumbs', () => { + expect(FIELD_ENCODE_MAP.breadcrumbs).toBe('bc'); + }); + + it('should contain mappings for transaction', () => { + expect(FIELD_ENCODE_MAP.transaction).toBe('tx'); + expect(FIELD_ENCODE_MAP.duration).toBe('d'); + expect(FIELD_ENCODE_MAP.spans).toBe('sp'); + }); + + it('should contain mappings for extra', () => { + expect(FIELD_ENCODE_MAP.extra).toBe('xt'); + }); + }); + + describe('FIELD_DECODE_MAP', () => { + it('should be reverse of FIELD_ENCODE_MAP', () => { + for (const [key, value] of Object.entries(FIELD_ENCODE_MAP)) { + expect(FIELD_DECODE_MAP[value]).toBe(key); + } + }); + + it('should decode short codes back to original field names', () => { + expect(FIELD_DECODE_MAP['eid']).toBe('event_id'); + expect(FIELD_DECODE_MAP['ts']).toBe('timestamp'); + expect(FIELD_DECODE_MAP['t']).toBe('type'); + expect(FIELD_DECODE_MAP['l']).toBe('level'); + expect(FIELD_DECODE_MAP['m']).toBe('message'); + }); + }); + + describe('encodeFields', () => { + it('should encode basic fields to short codes', () => { + const event = { + event_id: 'abc123', + timestamp: '2024-01-01T00:00:00.000Z', + type: 'error', + level: 'error', + message: 'Test error', + }; + + const encoded = encodeFields(event); + + expect(encoded.eid).toBe('abc123'); + expect(encoded.ts).toBe('2024-01-01T00:00:00.000Z'); + expect(encoded.t).toBe('error'); + expect(encoded.l).toBe('error'); + expect(encoded.m).toBe('Test error'); + }); + + it('should keep unknown fields unchanged', () => { + const event = { + event_id: 'abc123', + custom_field: 'custom_value', + another_field: 123, + }; + + const encoded = encodeFields(event); + + expect(encoded.eid).toBe('abc123'); + expect(encoded.custom_field).toBe('custom_value'); + expect(encoded.another_field).toBe(123); + }); + + it('should return non-object input unchanged', () => { + expect(encodeFields(null as any)).toBe(null); + expect(encodeFields(undefined as any)).toBe(undefined); + expect(encodeFields(123 as any)).toBe(123); + expect(encodeFields('string' as any)).toBe('string'); + }); + + it('should handle empty object', () => { + const encoded = encodeFields({}); + expect(encoded).toEqual({}); + }); + + it('should encode nested objects without modification', () => { + const event = { + event_id: 'abc123', + user: { id: 'user1', name: 'Test' }, + contexts: { trace: { trace_id: 'xyz' } }, + }; + + const encoded = encodeFields(event); + + expect(encoded.eid).toBe('abc123'); + // user is encoded to 'u', contexts is encoded to 'ctx' + expect(encoded.u).toEqual({ id: 'user1', name: 'Test' }); + expect(encoded.ctx).toEqual({ trace: { trace_id: 'xyz' } }); + }); + + it('should encode transaction fields', () => { + const transaction = { + type: 'transaction', + transaction: 'test-transaction', + duration: 1000, + spans: [], + start_timestamp: '2024-01-01T00:00:00.000Z', + }; + + const encoded = encodeFields(transaction); + + expect(encoded.t).toBe('transaction'); + expect(encoded.tx).toBe('test-transaction'); + expect(encoded.d).toBe(1000); + expect(encoded.sp).toEqual([]); + expect(encoded.sts).toBe('2024-01-01T00:00:00.000Z'); + }); + }); + + describe('decodeFields', () => { + it('should decode short codes back to original field names', () => { + const event = { + eid: 'abc123', + ts: '2024-01-01T00:00:00.000Z', + t: 'error', + l: 'error', + m: 'Test error', + }; + + const decoded = decodeFields(event); + + expect(decoded.event_id).toBe('abc123'); + expect(decoded.timestamp).toBe('2024-01-01T00:00:00.000Z'); + expect(decoded.type).toBe('error'); + expect(decoded.level).toBe('error'); + expect(decoded.message).toBe('Test error'); + }); + + it('should keep unknown fields unchanged', () => { + const event = { + eid: 'abc123', + custom_field: 'custom_value', + another_field: 123, + }; + + const decoded = decodeFields(event); + + expect(decoded.event_id).toBe('abc123'); + expect(decoded.custom_field).toBe('custom_value'); + expect(decoded.another_field).toBe(123); + }); + + it('should return non-object input unchanged', () => { + expect(decodeFields(null as any)).toBe(null); + expect(decodeFields(undefined as any)).toBe(undefined); + expect(decodeFields(123 as any)).toBe(123); + expect(decodeFields('string' as any)).toBe('string'); + }); + + it('should handle empty object', () => { + const decoded = decodeFields({}); + expect(decoded).toEqual({}); + }); + + it('should decode nested objects without modification', () => { + const event = { + eid: 'abc123', + u: { id: 'user1', name: 'Test' }, + ctx: { trace: { trace_id: 'xyz' } }, + }; + + const decoded = decodeFields(event); + + expect(decoded.event_id).toBe('abc123'); + expect(decoded.user).toEqual({ id: 'user1', name: 'Test' }); + expect(decoded.contexts).toEqual({ trace: { trace_id: 'xyz' } }); + }); + }); + + describe('encode/decode round-trip', () => { + it('should preserve data through encode/decode cycle', () => { + const original = { + event_id: 'abc123', + timestamp: '2024-01-01T00:00:00.000Z', + type: 'error', + level: 'error', + message: 'Test error', + user: { id: 'user1' }, + tags: { env: 'prod' }, + }; + + const encoded = encodeFields(original); + const decoded = decodeFields(encoded); + + expect(decoded.event_id).toBe(original.event_id); + expect(decoded.timestamp).toBe(original.timestamp); + expect(decoded.type).toBe(original.type); + expect(decoded.level).toBe(original.level); + expect(decoded.message).toBe(original.message); + expect(decoded.user).toEqual(original.user); + expect(decoded.tags).toEqual(original.tags); + }); + }); +}); diff --git a/tests/helper.test.ts b/tests/helper.test.ts new file mode 100644 index 0000000..1bc8775 --- /dev/null +++ b/tests/helper.test.ts @@ -0,0 +1,178 @@ +import { describe, it, expect } from 'vitest'; +import { + generateEventId, + now, + uuid, + isFunction, + isString, + isObject, + safeGet, + truncate, + matchPatterns, +} from '../src/utils/helper'; + +describe('helper utils', () => { + describe('generateEventId', () => { + it('should generate 32 character hex string', () => { + const id = generateEventId(); + expect(id).toMatch(/^[a-f0-9]{32}$/i); + }); + + it('should generate unique IDs', () => { + const id1 = generateEventId(); + const id2 = generateEventId(); + expect(id1).not.toBe(id2); + }); + }); + + describe('now', () => { + it('should return current timestamp in milliseconds', () => { + const before = Date.now(); + const timestamp = now(); + const after = Date.now(); + expect(timestamp).toBeGreaterThanOrEqual(before); + expect(timestamp).toBeLessThanOrEqual(after); + }); + }); + + describe('uuid', () => { + it('should generate 32 character hex string (UUID without hyphens)', () => { + const id = uuid(); + expect(id).toMatch(/^[a-f0-9]{32}$/i); + }); + + it('should generate unique UUIDs', () => { + const id1 = uuid(); + const id2 = uuid(); + expect(id1).not.toBe(id2); + }); + }); + + describe('isFunction', () => { + it('should return true for functions', () => { + expect(isFunction(() => {})).toBe(true); + expect(isFunction(async () => {})).toBe(true); + expect(isFunction(function() {})).toBe(true); + }); + + it('should return false for non-functions', () => { + expect(isFunction('string')).toBe(false); + expect(isFunction(123)).toBe(false); + expect(isFunction(null)).toBe(false); + expect(isFunction(undefined)).toBe(false); + expect(isFunction({})).toBe(false); + expect(isFunction([])).toBe(false); + }); + }); + + describe('isString', () => { + it('should return true for strings', () => { + expect(isString('')).toBe(true); + expect(isString('hello')).toBe(true); + expect(isString(String(123))).toBe(true); + }); + + it('should return false for non-strings', () => { + expect(isString(123)).toBe(false); + expect(isString(null)).toBe(false); + expect(isString(undefined)).toBe(false); + expect(isString({})).toBe(false); + expect(isString([])).toBe(false); + }); + }); + + describe('isObject', () => { + it('should return true for objects', () => { + expect(isObject({})).toBe(true); + expect(isObject({ a: 1 })).toBe(true); + expect(isObject(new Object())).toBe(true); + }); + + it('should return false for non-objects', () => { + expect(isObject(null)).toBe(false); + expect(isObject([])).toBe(false); + expect(isObject('string')).toBe(false); + expect(isObject(123)).toBe(false); + expect(isObject(undefined)).toBe(false); + expect(isObject(() => {})).toBe(false); + }); + }); + + describe('safeGet', () => { + it('should return result of function when successful', () => { + const result = safeGet(() => 42, 0); + expect(result).toBe(42); + }); + + it('should return default value when function throws', () => { + const result = safeGet(() => { throw new Error('test'); }, 'default'); + expect(result).toBe('default'); + }); + + it('should return default value when function returns undefined', () => { + const result = safeGet(() => undefined, 'default'); + expect(result).toBe('default'); + }); + + it('should return null when function returns null (null is a valid value)', () => { + const result = safeGet(() => null, 'default'); + expect(result).toBeNull(); + }); + + it('should allow falsy values that are not undefined', () => { + expect(safeGet(() => 0, 100)).toBe(0); + expect(safeGet(() => '', 'default')).toBe(''); + expect(safeGet(() => false, true)).toBe(false); + }); + }); + + describe('truncate', () => { + it('should return original string if shorter than max length', () => { + expect(truncate('hello', 10)).toBe('hello'); + expect(truncate('hello', 5)).toBe('hello'); + }); + + it('should truncate string longer than max length', () => { + expect(truncate('hello world', 5)).toBe('hello...'); + }); + + it('should handle empty string', () => { + expect(truncate('', 10)).toBe(''); + }); + + it('should handle exact length', () => { + expect(truncate('hello', 5)).toBe('hello'); + }); + }); + + describe('matchPatterns', () => { + it('should return false for empty patterns', () => { + expect(matchPatterns('test', [])).toBe(false); + expect(matchPatterns('test', undefined as any)).toBe(false); + }); + + it('should match string patterns', () => { + expect(matchPatterns('error: something went wrong', ['error'])).toBe(true); + expect(matchPatterns('something went wrong', ['error'])).toBe(false); + }); + + it('should match multiple string patterns (OR)', () => { + expect(matchPatterns('warning: low memory', ['error', 'warning'])).toBe(true); + expect(matchPatterns('info: normal', ['error', 'warning'])).toBe(false); + }); + + it('should match RegExp patterns', () => { + expect(matchPatterns('Error: validation failed', [/Error/])).toBe(true); + expect(matchPatterns('error: validation failed', [/validation/])).toBe(true); + }); + + it('should match combined string and RegExp patterns', () => { + expect(matchPatterns('WARNING: high CPU', ['error', /WARNING/])).toBe(true); + }); + + it('should handle special regex characters in string patterns', () => { + expect(matchPatterns('test.file.txt', ['test.file'])).toBe(true); + expect(matchPatterns('test123', ['test(123)'])).toBe(false); + }); + }); +}); diff --git a/tests/identity.test.ts b/tests/identity.test.ts new file mode 100644 index 0000000..aaed8f9 --- /dev/null +++ b/tests/identity.test.ts @@ -0,0 +1,168 @@ +import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest'; +import { + getAnonymousId, + setAnonymousId, + clearAnonymousId, + isAnonymousTrackingEnabled, +} from '../src/utils/identity'; + +const ANONYMOUS_ID_KEY = 'light_sentry_aid'; + +describe('identity utils', () => { + beforeEach(() => { + localStorage.clear(); + }); + + afterEach(() => { + vi.restoreAllMocks(); + }); + + describe('getAnonymousId', () => { + it('should generate and store a new anonymous ID when none exists', () => { + const id = getAnonymousId(); + expect(id).toBeTruthy(); + expect(typeof id).toBe('string'); + expect(id!.length).toBeGreaterThan(0); + const stored = localStorage.getItem(ANONYMOUS_ID_KEY); + expect(stored).toBe(id); + }); + + it('should return the same ID on subsequent calls', () => { + const id1 = getAnonymousId(); + const id2 = getAnonymousId(); + expect(id1).toBe(id2); + }); + + it('should return existing ID from localStorage', () => { + localStorage.setItem(ANONYMOUS_ID_KEY, 'existing-id-123'); + const id = getAnonymousId(); + expect(id).toBe('existing-id-123'); + }); + + it('should return null when localStorage is not available', () => { + const originalLocalStorage = (global as any).localStorage; + delete (global as any).localStorage; + const id = getAnonymousId(); + expect(id).toBeNull(); + (global as any).localStorage = originalLocalStorage; + }); + + it('should return null when localStorage throws', () => { + const getItemSpy = vi.spyOn(Storage.prototype, 'getItem').mockImplementation(() => { + throw new Error('Storage error'); + }); + const id = getAnonymousId(); + expect(id).toBeNull(); + getItemSpy.mockRestore(); + }); + + it('should generate UUID format (32 hex chars without hyphens)', () => { + const id = getAnonymousId(); + expect(id).toMatch(/^[a-f0-9]{32}$/i); + }); + }); + + describe('setAnonymousId', () => { + it('should set custom anonymous ID', () => { + const result = setAnonymousId('custom-id-123'); + expect(result).toBe(true); + expect(localStorage.getItem(ANONYMOUS_ID_KEY)).toBe('custom-id-123'); + }); + + it('should override existing ID', () => { + localStorage.setItem(ANONYMOUS_ID_KEY, 'old-id'); + setAnonymousId('new-id'); + expect(localStorage.getItem(ANONYMOUS_ID_KEY)).toBe('new-id'); + }); + + it('should return false when localStorage is not available', () => { + const originalLocalStorage = (global as any).localStorage; + delete (global as any).localStorage; + const result = setAnonymousId('test-id'); + expect(result).toBe(false); + (global as any).localStorage = originalLocalStorage; + }); + + it('should return false when localStorage throws', () => { + const setItemSpy = vi.spyOn(Storage.prototype, 'setItem').mockImplementation(() => { + throw new Error('Storage error'); + }); + const result = setAnonymousId('test-id'); + expect(result).toBe(false); + setItemSpy.mockRestore(); + }); + + it('should set empty string ID', () => { + const result = setAnonymousId(''); + expect(result).toBe(true); + expect(localStorage.getItem(ANONYMOUS_ID_KEY)).toBe(''); + }); + }); + + describe('clearAnonymousId', () => { + it('should clear existing anonymous ID', () => { + localStorage.setItem(ANONYMOUS_ID_KEY, 'existing-id'); + const result = clearAnonymousId(); + expect(result).toBe(true); + expect(localStorage.getItem(ANONYMOUS_ID_KEY)).toBeNull(); + }); + + it('should return true even when no ID exists', () => { + const result = clearAnonymousId(); + expect(result).toBe(true); + }); + + it('should return false when localStorage is not available', () => { + const originalLocalStorage = (global as any).localStorage; + delete (global as any).localStorage; + const result = clearAnonymousId(); + expect(result).toBe(false); + (global as any).localStorage = originalLocalStorage; + }); + + it('should return false when localStorage throws', () => { + const removeItemSpy = vi.spyOn(Storage.prototype, 'removeItem').mockImplementation(() => { + throw new Error('Storage error'); + }); + const result = clearAnonymousId(); + expect(result).toBe(false); + removeItemSpy.mockRestore(); + }); + }); + + describe('isAnonymousTrackingEnabled', () => { + it('should return true when trackAnonymousUsers is undefined', () => { + expect(isAnonymousTrackingEnabled({})).toBe(true); + }); + + it('should return true when trackAnonymousUsers is true', () => { + expect(isAnonymousTrackingEnabled({ trackAnonymousUsers: true })).toBe(true); + }); + + it('should return false when trackAnonymousUsers is false', () => { + expect(isAnonymousTrackingEnabled({ trackAnonymousUsers: false })).toBe(false); + }); + + it('should return true for other truthy values', () => { + expect(isAnonymousTrackingEnabled({ trackAnonymousUsers: 1 as any })).toBe(true); + expect(isAnonymousTrackingEnabled({ trackAnonymousUsers: 'yes' as any })).toBe(true); + }); + }); + + describe('integration: full lifecycle', () => { + it('should handle set -> get -> clear flow', () => { + const id1 = getAnonymousId(); + expect(id1).toBeTruthy(); + + setAnonymousId('custom-user-id'); + const id2 = getAnonymousId(); + expect(id2).toBe('custom-user-id'); + + clearAnonymousId(); + const id3 = getAnonymousId(); + expect(id3).toBeTruthy(); + expect(id3).not.toBe('custom-user-id'); + expect(id3).not.toBe(id1); + }); + }); +}); diff --git a/tests/index.test.ts b/tests/index.test.ts new file mode 100644 index 0000000..035bd94 --- /dev/null +++ b/tests/index.test.ts @@ -0,0 +1,199 @@ +import { describe, it, expect } from 'vitest'; +import * as exports from '../src/index'; + +describe('index exports', () => { + describe('named exports', () => { + it('should export init function', () => { + expect(typeof exports.init).toBe('function'); + }); + + it('should export getClient function', () => { + expect(typeof exports.getClient).toBe('function'); + }); + + it('should export captureException function', () => { + expect(typeof exports.captureException).toBe('function'); + }); + + it('should export captureMessage function', () => { + expect(typeof exports.captureMessage).toBe('function'); + }); + + it('should export captureEvent function', () => { + expect(typeof exports.captureEvent).toBe('function'); + }); + + it('should export setUser function', () => { + expect(typeof exports.setUser).toBe('function'); + }); + + it('should export setAnonymousId function', () => { + expect(typeof exports.setAnonymousId).toBe('function'); + }); + + it('should export clearAnonymousId function', () => { + expect(typeof exports.clearAnonymousId).toBe('function'); + }); + + it('should export getAnonymousId function', () => { + expect(typeof exports.getAnonymousId).toBe('function'); + }); + + it('should export startTransaction function', () => { + expect(typeof exports.startTransaction).toBe('function'); + }); + + it('should export getCurrentTransaction function', () => { + expect(typeof exports.getCurrentTransaction).toBe('function'); + }); + + it('should export getCurrentSpan function', () => { + expect(typeof exports.getCurrentSpan).toBe('function'); + }); + + it('should export setSpan function', () => { + expect(typeof exports.setSpan).toBe('function'); + }); + + it('should export startSpan function', () => { + expect(typeof exports.startSpan).toBe('function'); + }); + + it('should export setTag function', () => { + expect(typeof exports.setTag).toBe('function'); + }); + + it('should export setTags function', () => { + expect(typeof exports.setTags).toBe('function'); + }); + + it('should export setExtra function', () => { + expect(typeof exports.setExtra).toBe('function'); + }); + + it('should export addBreadcrumb function', () => { + expect(typeof exports.addBreadcrumb).toBe('function'); + }); + + it('should export flush function', () => { + expect(typeof exports.flush).toBe('function'); + }); + + it('should export disable function', () => { + expect(typeof exports.disable).toBe('function'); + }); + + it('should export enable function', () => { + expect(typeof exports.enable).toBe('function'); + }); + + it('should export Client class', () => { + expect(typeof exports.Client).toBe('function'); + }); + + it('should export Span class', () => { + expect(typeof exports.Span).toBe('function'); + }); + + it('should export Transaction class', () => { + expect(typeof exports.Transaction).toBe('function'); + }); + + it('should export httpStatusToSpanStatus function', () => { + expect(typeof exports.httpStatusToSpanStatus).toBe('function'); + }); + + it('should export dbStatusToSpanStatus function', () => { + expect(typeof exports.dbStatusToSpanStatus).toBe('function'); + }); + + it('should export statusToSpanStatus function', () => { + expect(typeof exports.statusToSpanStatus).toBe('function'); + }); + + it('should export serializeBaggage function', () => { + expect(typeof exports.serializeBaggage).toBe('function'); + }); + + it('should export parseBaggage function', () => { + expect(typeof exports.parseBaggage).toBe('function'); + }); + + it('should export createBaggageFromTransaction function', () => { + expect(typeof exports.createBaggageFromTransaction).toBe('function'); + }); + }); + + describe('plugin exports', () => { + it('should export ErrorPlugin class', () => { + expect(typeof exports.ErrorPlugin).toBe('function'); + }); + + it('should export PerformancePlugin class', () => { + expect(typeof exports.PerformancePlugin).toBe('function'); + }); + + it('should export NetworkPlugin class', () => { + expect(typeof exports.NetworkPlugin).toBe('function'); + }); + + it('should export BehaviorPlugin class', () => { + expect(typeof exports.BehaviorPlugin).toBe('function'); + }); + + it('should export OfflinePlugin class', () => { + expect(typeof exports.OfflinePlugin).toBe('function'); + }); + + it('should export SamplingPlugin class', () => { + expect(typeof exports.SamplingPlugin).toBe('function'); + }); + + it('should export RouterPlugin class', () => { + expect(typeof exports.RouterPlugin).toBe('function'); + }); + + it('should export InteractionPlugin class', () => { + expect(typeof exports.InteractionPlugin).toBe('function'); + }); + }); + + describe('default export', () => { + it('should export default object with core functions', () => { + const d = exports.default; + expect(d).toBeDefined(); + expect(typeof d.init).toBe('function'); + expect(typeof d.getClient).toBe('function'); + expect(typeof d.captureException).toBe('function'); + expect(typeof d.captureMessage).toBe('function'); + expect(typeof d.captureEvent).toBe('function'); + expect(typeof d.setUser).toBe('function'); + expect(typeof d.setAnonymousId).toBe('function'); + expect(typeof d.clearAnonymousId).toBe('function'); + expect(typeof d.getAnonymousId).toBe('function'); + expect(typeof d.startTransaction).toBe('function'); + expect(typeof d.getCurrentTransaction).toBe('function'); + expect(typeof d.getCurrentSpan).toBe('function'); + expect(typeof d.setSpan).toBe('function'); + expect(typeof d.startSpan).toBe('function'); + expect(typeof d.setTag).toBe('function'); + expect(typeof d.setTags).toBe('function'); + expect(typeof d.setExtra).toBe('function'); + expect(typeof d.addBreadcrumb).toBe('function'); + expect(typeof d.flush).toBe('function'); + expect(typeof d.disable).toBe('function'); + expect(typeof d.enable).toBe('function'); + }); + + it('should export default object with Span and Transaction classes', () => { + const d = exports.default; + expect(typeof d.Span).toBe('function'); + expect(typeof d.Transaction).toBe('function'); + }); + + it('should export default object with utility functions', () => { + const d = exports.default; + expect(typeof d.httpStatusToSpanStatus).toBe('function'); + }); + }); +}); diff --git a/tests/logger.test.ts b/tests/logger.test.ts new file mode 100644 index 0000000..0b1e7e6 --- /dev/null +++ b/tests/logger.test.ts @@ -0,0 +1,192 @@ +import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest'; +import { + setDebug, + isDebugEnabled, + logDebug, + logError, +} from '../src/utils/logger'; + +describe('logger', () => { + beforeEach(() => { + setDebug(false); + }); + + afterEach(() => { + vi.restoreAllMocks(); + }); + + describe('setDebug', () => { + it('should enable debug mode', () => { + expect(isDebugEnabled()).toBe(false); + setDebug(true); + expect(isDebugEnabled()).toBe(true); + }); + + it('should disable debug mode', () => { + setDebug(true); + expect(isDebugEnabled()).toBe(true); + setDebug(false); + expect(isDebugEnabled()).toBe(false); + }); + }); + + describe('isDebugEnabled', () => { + it('should return current debug state', () => { + expect(isDebugEnabled()).toBe(false); + setDebug(true); + expect(isDebugEnabled()).toBe(true); + }); + }); + + describe('logDebug', () => { + it('should not log when debug is disabled', () => { + const consoleSpy = vi.spyOn(console, 'log').mockImplementation(() => {}); + logDebug('Test', 'This should not appear'); + expect(consoleSpy).not.toHaveBeenCalled(); + }); + + it('should log message when debug is enabled', () => { + setDebug(true); + const consoleSpy = vi.spyOn(console, 'log').mockImplementation(() => {}); + logDebug('Test', 'This should appear'); + expect(consoleSpy).toHaveBeenCalled(); + }); + + it('should log message with data when debug is enabled', () => { + setDebug(true); + const consoleSpy = vi.spyOn(console, 'log').mockImplementation(() => {}); + logDebug('Test', 'Message with data', { key: 'value', num: 123 }); + expect(consoleSpy).toHaveBeenCalled(); + const loggedMessage = consoleSpy.mock.calls[0].join(' '); + expect(loggedMessage).toContain('[LightSDK][Test]'); + expect(loggedMessage).toContain('Message with data'); + }); + + it('should include timestamp in log message', () => { + setDebug(true); + const consoleSpy = vi.spyOn(console, 'log').mockImplementation(() => {}); + logDebug('Module', 'Test message'); + expect(consoleSpy).toHaveBeenCalled(); + const loggedMessage = consoleSpy.mock.calls[0][0]; + expect(loggedMessage).toMatch(/^\[LightSDK\]\[Module\]/); + }); + + it('should handle message without data', () => { + setDebug(true); + const consoleSpy = vi.spyOn(console, 'log').mockImplementation(() => {}); + logDebug('Module', 'Simple message'); + expect(consoleSpy).toHaveBeenCalled(); + }); + + it('should handle undefined data', () => { + setDebug(true); + const consoleSpy = vi.spyOn(console, 'log').mockImplementation(() => {}); + logDebug('Module', 'Message', undefined); + expect(consoleSpy).toHaveBeenCalled(); + }); + + it('should handle null data', () => { + setDebug(true); + const consoleSpy = vi.spyOn(console, 'log').mockImplementation(() => {}); + logDebug('Module', 'Message', null); + expect(consoleSpy).toHaveBeenCalled(); + }); + + it('should handle complex data objects', () => { + setDebug(true); + const consoleSpy = vi.spyOn(console, 'log').mockImplementation(() => {}); + const complexData = { + nested: { deeply: { value: 123 } }, + array: [1, 2, 3], + bool: true, + null: null, + }; + logDebug('Module', 'Complex data', complexData); + expect(consoleSpy).toHaveBeenCalled(); + }); + }); + + describe('logError', () => { + it('should not log when debug is disabled', () => { + const consoleSpy = vi.spyOn(console, 'error').mockImplementation(() => {}); + logError('Test', 'This should not appear'); + expect(consoleSpy).not.toHaveBeenCalled(); + }); + + it('should log error message when debug is enabled', () => { + setDebug(true); + const consoleSpy = vi.spyOn(console, 'error').mockImplementation(() => {}); + logError('Test', 'This error should appear'); + expect(consoleSpy).toHaveBeenCalled(); + }); + + it('should include ERROR tag in log message', () => { + setDebug(true); + const consoleSpy = vi.spyOn(console, 'error').mockImplementation(() => {}); + logError('Module', 'Error message'); + expect(consoleSpy).toHaveBeenCalled(); + const loggedMessage = consoleSpy.mock.calls[0][0]; + expect(loggedMessage).toContain('[LightSDK][Module][ERROR]'); + }); + + it('should log error with error data', () => { + setDebug(true); + const consoleSpy = vi.spyOn(console, 'error').mockImplementation(() => {}); + const error = new Error('Test error'); + logError('Module', 'Error occurred', error); + expect(consoleSpy).toHaveBeenCalled(); + }); + + it('should handle plain object error', () => { + setDebug(true); + const consoleSpy = vi.spyOn(console, 'error').mockImplementation(() => {}); + const errorObj = { status: 404, message: 'Not found' }; + logError('Module', 'Request failed', errorObj); + expect(consoleSpy).toHaveBeenCalled(); + }); + + it('should handle error message without data', () => { + setDebug(true); + const consoleSpy = vi.spyOn(console, 'error').mockImplementation(() => {}); + logError('Module', 'Simple error'); + expect(consoleSpy).toHaveBeenCalled(); + }); + + it('should handle string error', () => { + setDebug(true); + const consoleSpy = vi.spyOn(console, 'error').mockImplementation(() => {}); + logError('Module', 'String error', 'error details'); + expect(consoleSpy).toHaveBeenCalled(); + }); + + it('should handle undefined error', () => { + setDebug(true); + const consoleSpy = vi.spyOn(console, 'error').mockImplementation(() => {}); + logError('Module', 'Error without details', undefined); + expect(consoleSpy).toHaveBeenCalled(); + }); + }); + + describe('debug toggle behavior', () => { + it('should toggle between enabled and disabled', () => { + const consoleLogSpy = vi.spyOn(console, 'log').mockImplementation(() => {}); + const consoleErrorSpy = vi.spyOn(console, 'error').mockImplementation(() => {}); + + setDebug(true); + logDebug('Test', 'Debug on'); + expect(consoleLogSpy).toHaveBeenCalled(); + + setDebug(false); + logDebug('Test', 'Debug off'); + expect(consoleLogSpy).toHaveBeenCalledTimes(1); + + setDebug(true); + logError('Test', 'Error on'); + expect(consoleErrorSpy).toHaveBeenCalled(); + + setDebug(false); + logError('Test', 'Error off'); + expect(consoleErrorSpy).toHaveBeenCalledTimes(1); + }); + }); +}); diff --git a/tests/stacktrace.test.ts b/tests/stacktrace.test.ts new file mode 100644 index 0000000..3a5925d --- /dev/null +++ b/tests/stacktrace.test.ts @@ -0,0 +1,360 @@ +import { describe, it, expect, beforeEach } from 'vitest'; +import { parseStackTrace } from '../src/utils/stacktrace'; + +describe('stacktrace', () => { + // Mock location for jsdom environment + beforeEach(() => { + delete (global as any).location; + }); + + describe('parseStackTrace', () => { + it('should return empty array for undefined stack', () => { + expect(parseStackTrace(undefined)).toEqual([]); + }); + + it('should return empty array for empty string', () => { + expect(parseStackTrace('')).toEqual([]); + }); + + it('should parse standard Chrome/Node.js stack trace format', () => { + // Stack trace: newest call first (Function1), then Function2, then Function3 + // After reverse, order becomes Function3, Function2, Function1 + const stack = `Error + at Function3 (http://example.com/js/index.js:30:5) + at Function2 (http://example.com/js/main.js:25:10) + at Function1 (http://example.com/js/app.js:10:15)`; + + const frames = parseStackTrace(stack); + + expect(frames).toHaveLength(3); + // After reverse, Function1 should be first (oldest call in the trace) + expect(frames[0]).toEqual({ + filename: 'http://example.com/js/app.js', + function: 'Function1', + lineno: 10, + colno: 15, + in_app: true, + }); + expect(frames[1]).toEqual({ + filename: 'http://example.com/js/main.js', + function: 'Function2', + lineno: 25, + colno: 10, + in_app: true, + }); + expect(frames[2]).toEqual({ + filename: 'http://example.com/js/index.js', + function: 'Function3', + lineno: 30, + colno: 5, + in_app: true, + }); + }); + + it('should parse V8 format with @ separator', () => { + // V8 format requires 'at' prefix: at Function1@path:line:col + const stack = `Error + at Function1@http://example.com/js/app.js:10:15 + at Function2@http://example.com/js/main.js:25:10`; + + const frames = parseStackTrace(stack); + + expect(frames).toHaveLength(2); + // After reverse, order is reversed + expect(frames[0]).toEqual({ + filename: 'http://example.com/js/main.js', + function: 'Function2', + lineno: 25, + colno: 10, + in_app: true, + }); + expect(frames[1]).toEqual({ + filename: 'http://example.com/js/app.js', + function: 'Function1', + lineno: 10, + colno: 15, + in_app: true, + }); + }); + + it('should parse URL-only format (no function name)', () => { + const stack = `Error + at http://example.com/js/app.js:10:15 + at http://example.com/js/main.js:25:10`; + + const frames = parseStackTrace(stack); + + expect(frames).toHaveLength(2); + expect(frames[0]).toEqual({ + filename: 'http://example.com/js/main.js', + lineno: 25, + colno: 10, + in_app: true, + }); + expect(frames[1]).toEqual({ + filename: 'http://example.com/js/app.js', + lineno: 10, + colno: 15, + in_app: true, + }); + }); + + it('should mark node_modules frames as in_app: false when captured', () => { + // When captureNodeModules is true, node_modules frames are included + const stack = `Error + at Function1 (http://example.com/node_modules/dep.js:10:15) + at Function2 (http://example.com/js/app.js:25:10)`; + + const frames = parseStackTrace(stack, { captureNodeModules: true }); + + // After reverse, order is Function2, Function1 + expect(frames).toHaveLength(2); + expect(frames[0].in_app).toBe(true); // Function2 (app code) + expect(frames[1].in_app).toBe(false); // Function1 (node_modules) + }); + + it('should skip node_modules frames when captureNodeModules is false', () => { + const stack = `Error + at Function1 (http://example.com/node_modules/dep.js:10:15) + at Function2 (http://example.com/js/app.js:25:10) + at Function3 (http://example.com/node_modules/other.js:30:5)`; + + const frames = parseStackTrace(stack, { captureNodeModules: false }); + + // After reverse: Function3, Function2, Function1, then filter node_modules + expect(frames).toHaveLength(1); + expect(frames[0].function).toBe('Function2'); + }); + + it('should include node_modules when captureNodeModules is true', () => { + const stack = `Error + at Function1 (http://example.com/node_modules/dep.js:10:15) + at Function2 (http://example.com/js/app.js:25:10)`; + + const frames = parseStackTrace(stack, { captureNodeModules: true }); + + expect(frames).toHaveLength(2); + }); + + it('should not include column when captureColumn is false', () => { + const stack = `Error + at Function1 (http://example.com/js/app.js:10:15)`; + + const frames = parseStackTrace(stack, { captureColumn: false }); + + expect(frames).toHaveLength(1); + expect(frames[0].colno).toBeUndefined(); + }); + + it('should not apply relativePathOnly when origin does not match', () => { + // In jsdom, location.origin would be 'http://localhost:3000' or similar + // so example.com URLs won't match + const stack = `Error + at Function2 (http://other.com/js/main.js:25:10) + at Function1 (http://example.com/js/app.js:10:15)`; + + const frames = parseStackTrace(stack, { relativePathOnly: true }); + + // URLs don't match location.origin, so they remain unchanged + // After reverse: Function1, Function2 + expect(frames[0].filename).toBe('http://example.com/js/app.js'); + expect(frames[1].filename).toBe('http://other.com/js/main.js'); + }); + + it('should limit frames with maxFrames option', () => { + const stack = `Error + at Function4 (http://example.com/js/index.js:40:0) + at Function3 (http://example.com/js/util.js:35:0) + at Function2 (http://example.com/js/main.js:25:10) + at Function1 (http://example.com/js/app.js:10:15)`; + + // After reverse: Function1, Function2, Function3, Function4 + // maxFrames=2 returns first 2: Function1, Function2 + const frames = parseStackTrace(stack, { maxFrames: 2 }); + + expect(frames).toHaveLength(2); + expect(frames[0].function).toBe('Function1'); + expect(frames[1].function).toBe('Function2'); + }); + + it('should return all frames when maxFrames is 0 or undefined', () => { + const stack = `Error + at Function1 (http://example.com/js/app.js:10:15) + at Function2 (http://example.com/js/main.js:25:10)`; + + const frames1 = parseStackTrace(stack, { maxFrames: 0 }); + const frames2 = parseStackTrace(stack, { maxFrames: undefined }); + + expect(frames1).toHaveLength(2); + expect(frames2).toHaveLength(2); + }); + + it('should handle anonymous functions in V8 format', () => { + // V8 format requires 'at' prefix: at @path:line:col + const stack = `Error + at @http://example.com/js/app.js:10:15`; + + const frames = parseStackTrace(stack); + + expect(frames).toHaveLength(1); + expect(frames[0].function).toBe(''); + }); + + it('should handle stack with extra whitespace', () => { + // Note: complex whitespace may cause regex to fail, test with standard format + const stack = `Error + at Function2 (http://example.com/js/main.js:25:10) + at Function1 (http://example.com/js/app.js:10:15)`; + + const frames = parseStackTrace(stack); + + // After reverse: Function1, Function2 + expect(frames).toHaveLength(2); + expect(frames[0].function).toBe('Function1'); + expect(frames[1].function).toBe('Function2'); + }); + + it('should handle file:// URLs', () => { + const stack = `Error + at Function1 (file:///Users/name/project/app.js:10:15)`; + + const frames = parseStackTrace(stack); + + expect(frames).toHaveLength(1); + expect(frames[0].filename).toBe('file:///Users/name/project/app.js'); + expect(frames[0].in_app).toBe(true); + }); + + it('should handle mixed format stacks', () => { + const stack = `Error + at Function1 (http://example.com/js/app.js:10:15) + at Function2@http://example.com/js/main.js:25:10 + at http://example.com/js/index.js:30:5`; + + const frames = parseStackTrace(stack); + + expect(frames).toHaveLength(3); + }); + + it('should handle V8 format with captureColumn: false', () => { + const stack = `Error + at Function1@http://example.com/js/app.js:10:15`; + + const frames = parseStackTrace(stack, { captureColumn: false }); + + expect(frames).toHaveLength(1); + expect(frames[0].colno).toBeUndefined(); + expect(frames[0].function).toBe('Function1'); + }); + + it('should handle URL-only format with captureColumn: false', () => { + const stack = `Error + at http://example.com/js/app.js:10:15`; + + const frames = parseStackTrace(stack, { captureColumn: false }); + + expect(frames).toHaveLength(1); + expect(frames[0].colno).toBeUndefined(); + }); + + it('should skip node_modules in V8 format', () => { + const stack = `Error + at Function1@http://example.com/node_modules/dep.js:10:15 + at Function2@http://example.com/js/app.js:25:10`; + + const frames = parseStackTrace(stack, { captureNodeModules: false }); + + expect(frames).toHaveLength(1); + expect(frames[0].function).toBe('Function2'); + }); + + it('should skip node_modules in URL-only format', () => { + const stack = `Error + at http://example.com/node_modules/dep.js:10:15 + at http://example.com/js/app.js:25:10`; + + const frames = parseStackTrace(stack, { captureNodeModules: false }); + + expect(frames).toHaveLength(1); + }); + + it('should include node_modules in V8 format when captureNodeModules is true', () => { + const stack = `Error + at Function1@http://example.com/node_modules/dep.js:10:15 + at Function2@http://example.com/js/app.js:25:10`; + + const frames = parseStackTrace(stack, { captureNodeModules: true }); + + expect(frames).toHaveLength(2); + expect(frames[0].in_app).toBe(true); + expect(frames[1].in_app).toBe(false); + }); + + it('should include node_modules in URL-only format when captureNodeModules is true', () => { + const stack = `Error + at http://example.com/node_modules/dep.js:10:15 + at http://example.com/js/app.js:25:10`; + + const frames = parseStackTrace(stack, { captureNodeModules: true }); + + expect(frames).toHaveLength(2); + }); + + it('should apply relativePathOnly to V8 format', () => { + // Set up location mock + const mockLocation = { + protocol: 'http:', + host: 'example.com', + }; + (global as any).location = mockLocation; + + const stack = `Error + at Function1@http://example.com/js/app.js:10:15 + at Function2@http://example.com/js/main.js:25:10`; + + const frames = parseStackTrace(stack, { relativePathOnly: true }); + + expect(frames).toHaveLength(2); + expect(frames[0].filename).toBe('/js/main.js'); + expect(frames[1].filename).toBe('/js/app.js'); + + delete (global as any).location; + }); + + it('should apply relativePathOnly to URL-only format', () => { + const mockLocation = { + protocol: 'http:', + host: 'example.com', + }; + (global as any).location = mockLocation; + + const stack = `Error + at http://example.com/js/app.js:10:15 + at http://example.com/js/main.js:25:10`; + + const frames = parseStackTrace(stack, { relativePathOnly: true }); + + expect(frames).toHaveLength(2); + expect(frames[0].filename).toBe('/js/main.js'); + expect(frames[1].filename).toBe('/js/app.js'); + + delete (global as any).location; + }); + + it('should return reversed frames (newest call first after reversal)', () => { + // In standard stack traces, the first line after "Error" is the most recent call + const stack = `Error + at Function1 (http://example.com/js/app.js:10:15) + at Function2 (http://example.com/js/main.js:25:10) + at Function3 (http://example.com/js/index.js:30:5)`; + + const frames = parseStackTrace(stack); + + // After reverse of [Function1, Function2, Function3], we get [Function3, Function2, Function1] + // This puts the oldest call first + expect(frames[0].function).toBe('Function3'); + expect(frames[1].function).toBe('Function2'); + expect(frames[2].function).toBe('Function1'); + }); + }); +}); diff --git a/tests/tracing.test.ts b/tests/tracing.test.ts new file mode 100644 index 0000000..b4ee943 --- /dev/null +++ b/tests/tracing.test.ts @@ -0,0 +1,458 @@ +import { describe, it, expect, vi, beforeEach } from 'vitest'; +import { Span, Transaction, httpStatusToSpanStatus, dbStatusToSpanStatus, statusToSpanStatus } from '../src/utils/tracing'; +import type { SpanContext, TransactionContext } from '../src/types'; + +describe('Span', () => { + let span: Span; + + beforeEach(() => { + span = new Span({ op: 'test.span' }); + }); + + describe('constructor', () => { + it('should create span with generated IDs when not provided', () => { + const newSpan = new Span({ op: 'test' }); + expect(newSpan.traceId).toMatch(/^[a-f0-9]{32}$/i); + expect(newSpan.spanId).toMatch(/^[a-f0-9]{16}$/i); + }); + + it('should use provided traceId and spanId', () => { + const newSpan = new Span({ + op: 'test', + traceId: 'abc123abc123abc123abc123abc123ab', + spanId: 'abc123abc123abcd', + }); + expect(newSpan.traceId).toBe('abc123abc123abc123abc123abc123ab'); + expect(newSpan.spanId).toBe('abc123abc123abcd'); + }); + + it('should set parentSpanId from context', () => { + const childSpan = new Span({ + op: 'child', + parentSpanId: 'parent-span-id', + }); + expect(childSpan.parentSpanId).toBe('parent-span-id'); + }); + + it('should set op and description', () => { + const newSpan = new Span({ + op: 'http.client', + description: 'GET /api/users', + }); + expect(newSpan.op).toBe('http.client'); + expect(newSpan.description).toBe('GET /api/users'); + }); + + it('should initialize with current timestamp', () => { + const before = Date.now(); + const newSpan = new Span({ op: 'test' }); + const after = Date.now(); + expect(newSpan.startTimestamp).toBeGreaterThanOrEqual(before); + expect(newSpan.startTimestamp).toBeLessThanOrEqual(after); + }); + + it('should use provided startTimestamp', () => { + const newSpan = new Span({ + op: 'test', + startTimestamp: 1234567890000, + }); + expect(newSpan.startTimestamp).toBe(1234567890000); + }); + }); + + describe('setTag', () => { + it('should add tag to span', () => { + const result = span.setTag('http.method', 'GET'); + expect(span.tags).toEqual({ 'http.method': 'GET' }); + expect(result).toBe(span); // should return this for chaining + }); + + it('should overwrite existing tag', () => { + span.setTag('http.method', 'GET'); + span.setTag('http.method', 'POST'); + expect(span.tags['http.method']).toBe('POST'); + }); + + it('should support chaining', () => { + const result = span.setTag('key1', 'value1').setTag('key2', 'value2'); + expect(result).toBe(span); + expect(span.tags).toEqual({ key1: 'value1', key2: 'value2' }); + }); + }); + + describe('setData', () => { + it('should add data to span', () => { + span.setData('http.url', 'https://api.example.com/users'); + expect(span.data).toEqual({ 'http.url': 'https://api.example.com/users' }); + }); + + it('should support chaining', () => { + const result = span.setData('key1', 'value1').setData('key2', 'value2'); + expect(result).toBe(span); + }); + }); + + describe('setStatus', () => { + it('should set status', () => { + span.setStatus('ok'); + expect(span.status).toBe('ok'); + }); + + it('should support chaining', () => { + const result = span.setStatus('ok'); + expect(result).toBe(span); + }); + }); + + describe('setHttpStatus', () => { + it('should set status for 2xx', () => { + span.setHttpStatus(200); + expect(span.status).toBe('ok'); + expect(span.tags['http.status_code']).toBe('200'); + }); + + it('should set status for 4xx', () => { + span.setHttpStatus(404); + expect(span.status).toBe('not_found'); + expect(span.tags['http.status_code']).toBe('404'); + }); + + it('should set status for 5xx', () => { + span.setHttpStatus(500); + expect(span.status).toBe('internal_error'); + expect(span.tags['http.status_code']).toBe('500'); + }); + + it('should support chaining', () => { + const result = span.setHttpStatus(200); + expect(result).toBe(span); + }); + }); + + describe('setStatusFromResponse', () => { + it('should handle string status', () => { + span.setStatusFromResponse('ok'); + expect(span.status).toBe('ok'); + }); + + it('should handle number status', () => { + span.setStatusFromResponse(404); + expect(span.status).toBe('not_found'); + }); + + it('should handle undefined status', () => { + span.setStatusFromResponse(undefined); + expect(span.status).toBe('unknown_error'); + }); + + it('should set tag when tagKey provided', () => { + span.setStatusFromResponse(200, 'custom.status'); + expect(span.tags['custom.status']).toBe('200'); + }); + }); + + describe('startChild', () => { + it('should create child span', () => { + const child = span.startChild({ op: 'http.client' }); + expect(child).toBeDefined(); + expect(child.op).toBe('http.client'); + expect(child.parentSpanId).toBe(span.spanId); + expect(child.traceId).toBe(span.traceId); + }); + + it('should set transaction reference', () => { + const tx = new Transaction({ name: 'test-tx' }); + const child = tx.startChild({ op: 'child' }); + expect(child.transaction).toBe(tx); + }); + + it('should not add span to unsampled transaction', () => { + const tx = new Transaction({ name: 'test-tx', sampled: false }); + const child = tx.startChild({ op: 'child' }); + expect(tx.spans.length).toBe(0); + }); + }); + + describe('finish', () => { + it('should set endTimestamp', () => { + span.finish(); + expect(span.endTimestamp).toBeDefined(); + }); + + it('should use provided endTimestamp', () => { + span.finish(1234567890000); + expect(span.endTimestamp).toBe(1234567890000); + }); + + it('should only finish once', () => { + span.finish(); + const firstEndTime = span.endTimestamp; + span.finish(); // should not change + expect(span.endTimestamp).toBe(firstEndTime); + }); + }); + + describe('toTraceparent', () => { + it('should return traceparent without sampled flag when not sampled', () => { + const newSpan = new Span({ op: 'test' }); + const traceparent = newSpan.toTraceparent(); + expect(traceparent).toMatch(/^[a-f0-9]{32}-[a-f0-9]{16}$/); + }); + + it('should return traceparent with sampled=1 when sampled', () => { + const tx = new Transaction({ name: 'test', sampled: true }); + const traceparent = tx.toTraceparent(); + expect(traceparent).toMatch(/^[a-f0-9]{32}-[a-f0-9]{16}-1$/); + }); + + it('should return traceparent with sampled=0 when not sampled', () => { + const tx = new Transaction({ name: 'test', sampled: false }); + const traceparent = tx.toTraceparent(); + expect(traceparent).toMatch(/^[a-f0-9]{32}-[a-f0-9]{16}-0$/); + }); + }); + + describe('toJSON', () => { + it('should return correct JSON structure', () => { + span.setTag('http.method', 'GET'); + span.setData('http.url', 'https://api.example.com'); + span.setStatus('ok'); + span.finish(); + + const json = span.toJSON(); + + expect(json.trace_id).toBe(span.traceId); + expect(json.span_id).toBe(span.spanId); + expect(json.op).toBe('test.span'); + expect(json.status).toBe('ok'); + expect(json.tags).toEqual({ 'http.method': 'GET' }); + expect(json.data).toEqual({ 'http.url': 'https://api.example.com' }); + expect(json.start_timestamp).toBe(span.startTimestamp); + expect(json.timestamp).toBe(span.endTimestamp); + }); + + it('should omit empty tags and data', () => { + const newSpan = new Span({ op: 'test' }); + const json = newSpan.toJSON(); + expect(json.tags).toBeUndefined(); + expect(json.data).toBeUndefined(); + }); + }); +}); + +describe('Transaction', () => { + let transaction: Transaction; + + beforeEach(() => { + transaction = new Transaction({ name: 'test-transaction', op: 'transaction' }); + }); + + describe('constructor', () => { + it('should create transaction with name and op', () => { + expect(transaction.name).toBe('test-transaction'); + expect(transaction.op).toBe('transaction'); + }); + + it('should set transaction reference to itself', () => { + expect(transaction.transaction).toBe(transaction); + }); + + it('should initialize empty spans array', () => { + expect(transaction.spans).toEqual([]); + }); + + it('should set maxSpans default', () => { + expect(transaction.maxSpans).toBe(1000); + }); + + it('should accept custom maxSpans', () => { + const tx = new Transaction({ name: 'test' }, undefined, undefined, undefined, undefined, 500); + expect(tx.maxSpans).toBe(500); + }); + }); + + describe('_addSpan', () => { + it('should add span to transaction', () => { + const child = transaction.startChild({ op: 'child' }); + expect(transaction.spans.length).toBe(1); + expect(transaction.spans[0]).toBe(child); + }); + + it('should not exceed maxSpans', () => { + const tx = new Transaction({ name: 'test' }, undefined, undefined, undefined, undefined, 2); + tx.startChild({ op: 'child1' }); + tx.startChild({ op: 'child2' }); + tx.startChild({ op: 'child3' }); // should be dropped + expect(tx.spans.length).toBe(2); + }); + }); + + describe('setBaggage', () => { + it('should set baggage field', () => { + const result = transaction.setBaggage('custom.key', 'value'); + expect(transaction.toBaggage()).toContain('custom.key=value'); + expect(result).toBe(transaction); + }); + }); + + describe('setUserBaggage', () => { + it('should set user_id in baggage', () => { + transaction.setUserBaggage('user123'); + expect(transaction.toBaggage()).toContain('sentry-user_id=user123'); + }); + + it('should set user_segment in baggage', () => { + transaction.setUserBaggage('user123', 'premium'); + expect(transaction.toBaggage()).toContain('sentry-user_id=user123'); + expect(transaction.toBaggage()).toContain('sentry-user_segment=premium'); + }); + + it('should delete user_id when undefined', () => { + transaction.setUserBaggage('user123'); + transaction.setUserBaggage(undefined); + expect(transaction.toBaggage()).not.toContain('user_id'); + }); + }); + + describe('toBaggage', () => { + it('should return serialized baggage with trace_id', () => { + const baggage = transaction.toBaggage(); + expect(baggage).toContain('sentry-trace_id='); + }); + + it('should include sampled when explicitly set', () => { + const txWithSample = new Transaction({ name: 'test', sampled: true }); + const baggage = txWithSample.toBaggage(); + expect(baggage).toContain('sentry-sampled=true'); + }); + }); + + describe('toJSON', () => { + it('should include spans in JSON', () => { + transaction.startChild({ op: 'child1' }); + transaction.startChild({ op: 'child2' }); + + const json = transaction.toJSON(); + + expect(json.spans).toHaveLength(2); + expect(json.transaction).toBe('test-transaction'); + expect(json.sampled).toBeUndefined(); // not sampled by default + }); + }); + + describe('toEvent', () => { + it('should return transaction event', () => { + transaction.startChild({ op: 'child' }); + const event = transaction.toEvent(); + + expect(event.type).toBe('transaction'); + expect(event.transaction).toBe('test-transaction'); + expect(event.spans).toHaveLength(1); + expect(event.contexts?.trace).toBeDefined(); + expect(event.platform).toBe('javascript'); + }); + }); +}); + +describe('httpStatusToSpanStatus', () => { + it('should map 2xx to ok', () => { + expect(httpStatusToSpanStatus(200)).toBe('ok'); + expect(httpStatusToSpanStatus(201)).toBe('ok'); + expect(httpStatusToSpanStatus(299)).toBe('ok'); + }); + + it('should map 400 to invalid_argument', () => { + expect(httpStatusToSpanStatus(400)).toBe('invalid_argument'); + }); + + it('should map 401 to unauthenticated', () => { + expect(httpStatusToSpanStatus(401)).toBe('unauthenticated'); + }); + + it('should map 403 to permission_denied', () => { + expect(httpStatusToSpanStatus(403)).toBe('permission_denied'); + }); + + it('should map 404 to not_found', () => { + expect(httpStatusToSpanStatus(404)).toBe('not_found'); + }); + + it('should map 409 to already_exists', () => { + expect(httpStatusToSpanStatus(409)).toBe('already_exists'); + }); + + it('should map 429 to resource_exhausted', () => { + expect(httpStatusToSpanStatus(429)).toBe('resource_exhausted'); + }); + + it('should map 4xx to invalid_argument', () => { + expect(httpStatusToSpanStatus(499)).toBe('invalid_argument'); + }); + + it('should map 5xx to internal_error', () => { + expect(httpStatusToSpanStatus(500)).toBe('internal_error'); + expect(httpStatusToSpanStatus(503)).toBe('internal_error'); + expect(httpStatusToSpanStatus(599)).toBe('internal_error'); + }); +}); + +describe('dbStatusToSpanStatus', () => { + it('should map 0 and 1 to ok', () => { + expect(dbStatusToSpanStatus(0)).toBe('ok'); + expect(dbStatusToSpanStatus(1)).toBe('ok'); + expect(dbStatusToSpanStatus('0')).toBe('ok'); + expect(dbStatusToSpanStatus('1')).toBe('ok'); + }); + + it('should map 10-19 to invalid_argument', () => { + expect(dbStatusToSpanStatus(10)).toBe('invalid_argument'); + expect(dbStatusToSpanStatus(15)).toBe('invalid_argument'); + }); + + it('should map 20-29 to not_found', () => { + expect(dbStatusToSpanStatus(20)).toBe('not_found'); + expect(dbStatusToSpanStatus(25)).toBe('not_found'); + }); + + it('should map 30-39 to already_exists', () => { + expect(dbStatusToSpanStatus(30)).toBe('already_exists'); + expect(dbStatusToSpanStatus(35)).toBe('already_exists'); + }); + + it('should map 50+ to internal_error', () => { + expect(dbStatusToSpanStatus(50)).toBe('internal_error'); + expect(dbStatusToSpanStatus(100)).toBe('internal_error'); + }); + + it('should return unknown_error for undefined/null/empty', () => { + expect(dbStatusToSpanStatus(undefined)).toBe('unknown_error'); + expect(dbStatusToSpanStatus(null)).toBe('unknown_error'); + expect(dbStatusToSpanStatus('')).toBe('unknown_error'); + }); +}); + +describe('statusToSpanStatus', () => { + it('should handle string status ok', () => { + expect(statusToSpanStatus('ok', undefined)).toBe('ok'); + expect(statusToSpanStatus('success', undefined)).toBe('ok'); + }); + + it('should handle string status cancelled', () => { + expect(statusToSpanStatus('cancelled', undefined)).toBe('cancelled'); + expect(statusToSpanStatus('canceled', undefined)).toBe('cancelled'); + }); + + it('should handle HTTP status codes', () => { + expect(statusToSpanStatus(404, undefined)).toBe('not_found'); + expect(statusToSpanStatus(500, undefined)).toBe('internal_error'); + }); + + it('should use db rules for db ops', () => { + expect(statusToSpanStatus(0, 'db.query')).toBe('ok'); + expect(statusToSpanStatus(10, 'db.query')).toBe('invalid_argument'); + }); + + it('should return unknown_error for unknown strings', () => { + expect(statusToSpanStatus('unknown_status', undefined)).toBe('unknown_error'); + }); +});