ainamika-sdk 1.0.3 → 1.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +26 -2
- package/dist/ainamika-sdk.js +1 -1
- package/dist/ainamika-sdk.js.map +1 -1
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -9,7 +9,8 @@
|
|
|
9
9
|
|
|
10
10
|
- **🤖 AI-Powered Analytics**: Intelligent event tracking with AI-generated insights
|
|
11
11
|
- **🛡️ Advanced Error Tracking**: Comprehensive error capture with stack traces, screenshots, and DOM snapshots
|
|
12
|
-
-
|
|
12
|
+
- **� Client ID Security**: Secure API access with client ID validation to prevent unauthorized usage
|
|
13
|
+
- **�📊 Real-time Event Tracking**: Track user interactions, page views, and custom events
|
|
13
14
|
- **🔧 Auto-Configuration**: Automatically analyze your DOM and suggest optimal tracking configurations
|
|
14
15
|
- **⚡ Web Worker Support**: Batched event processing for optimal performance
|
|
15
16
|
- **🌐 Offline Support**: Queue events when offline and sync when online
|
|
@@ -37,7 +38,7 @@ import AInamikaSDK from 'ainamika-sdk';
|
|
|
37
38
|
|
|
38
39
|
// Initialize the SDK
|
|
39
40
|
const analytics = new AInamikaSDK({
|
|
40
|
-
|
|
41
|
+
apiKey: '',
|
|
41
42
|
autoConfig: true,
|
|
42
43
|
debug: true,
|
|
43
44
|
clientId: 'YOU_WILL_GET_AFTER_SIGINING_UP_IN_DASHBOARD_UNDER_PROFILE',
|
|
@@ -188,6 +189,29 @@ const analytics = new window.AInamikaSDK({
|
|
|
188
189
|
5. **Batching & Web Worker**
|
|
189
190
|
- Events are batched and sent in the background using a web worker (if supported).
|
|
190
191
|
|
|
192
|
+
## 🔐 Security
|
|
193
|
+
|
|
194
|
+
**Client ID Validation**: All SDK requests are secured with client ID validation to prevent unauthorized access.
|
|
195
|
+
|
|
196
|
+
- **Required**: Every request must include a valid `clientId` that is registered with your Ainamika account
|
|
197
|
+
- **Automatic**: The SDK automatically includes your client ID in all API requests
|
|
198
|
+
- **Secure**: Invalid or missing client IDs will result in `400` error responses
|
|
199
|
+
- **Get Your Client ID**: Sign up in the Ainamika dashboard and find your unique client ID under Profile settings
|
|
200
|
+
|
|
201
|
+
```javascript
|
|
202
|
+
// ✅ Correct - Always provide your registered client ID
|
|
203
|
+
const analytics = new AInamikaSDK({
|
|
204
|
+
clientId: 'your-registered-client-id-from-dashboard',
|
|
205
|
+
// ... other config
|
|
206
|
+
});
|
|
207
|
+
|
|
208
|
+
// ❌ Invalid - Using unregistered client ID will fail
|
|
209
|
+
const analytics = new AInamikaSDK({
|
|
210
|
+
clientId: 'invalid-or-unregistered-id',
|
|
211
|
+
// ... other config
|
|
212
|
+
});
|
|
213
|
+
```
|
|
214
|
+
|
|
191
215
|
## Advanced
|
|
192
216
|
|
|
193
217
|
- **Custom API Endpoint**: Use the `apiDetails` option to send events to a custom endpoint with custom headers.
|
package/dist/ainamika-sdk.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.AInamikaSDKPro=t():e.AInamikaSDKPro=t()}("undefined"!=typeof self?self:"undefined"!=typeof window?window:"undefined"!=typeof global?global:this,function(){return function(){"use strict";var e={d:function(t,r){for(var n in r)e.o(r,n)&&!e.o(t,n)&&Object.defineProperty(t,n,{enumerable:!0,get:r[n]})},o:function(e,t){return Object.prototype.hasOwnProperty.call(e,t)}},t={};e.d(t,{default:function(){return v}});var r=function(){return r=Object.assign||function(e){for(var t,r=1,n=arguments.length;r<n;r++)for(var o in t=arguments[r])Object.prototype.hasOwnProperty.call(t,o)&&(e[o]=t[o]);return e},r.apply(this,arguments)},n=function(e,t,r,n){return new(r||(r=Promise))(function(o,a){function i(e){try{c(n.next(e))}catch(e){a(e)}}function s(e){try{c(n.throw(e))}catch(e){a(e)}}function c(e){var t;e.done?o(e.value):(t=e.value,t instanceof r?t:new r(function(e){e(t)})).then(i,s)}c((n=n.apply(e,t||[])).next())})},o=function(e,t){var r,n,o,a={label:0,sent:function(){if(1&o[0])throw o[1];return o[1]},trys:[],ops:[]},i=Object.create(("function"==typeof Iterator?Iterator:Object).prototype);return i.next=s(0),i.throw=s(1),i.return=s(2),"function"==typeof Symbol&&(i[Symbol.iterator]=function(){return this}),i;function s(s){return function(c){return function(s){if(r)throw new TypeError("Generator is already executing.");for(;i&&(i=0,s[0]&&(a=0)),a;)try{if(r=1,n&&(o=2&s[0]?n.return:s[0]?n.throw||((o=n.return)&&o.call(n),0):n.next)&&!(o=o.call(n,s[1])).done)return o;switch(n=0,o&&(s=[2&s[0],o.value]),s[0]){case 0:case 1:o=s;break;case 4:return a.label++,{value:s[1],done:!1};case 5:a.label++,n=s[1],s=[0];continue;case 7:s=a.ops.pop(),a.trys.pop();continue;default:if(!((o=(o=a.trys).length>0&&o[o.length-1])||6!==s[0]&&2!==s[0])){a=0;continue}if(3===s[0]&&(!o||s[1]>o[0]&&s[1]<o[3])){a.label=s[1];break}if(6===s[0]&&a.label<o[1]){a.label=o[1],o=s;break}if(o&&a.label<o[2]){a.label=o[2],a.ops.push(s);break}o[2]&&a.ops.pop(),a.trys.pop();continue}s=t.call(e,a)}catch(e){s=[6,e],n=0}finally{r=o=0}if(5&s[0])throw s[1];return{value:s[0]?s[1]:void 0,done:!0}}([s,c])}}},a=function(e,t,r){if(r||2===arguments.length)for(var n,o=0,a=t.length;o<a;o++)!n&&o in t||(n||(n=Array.prototype.slice.call(t,0,o)),n[o]=t[o]);return e.concat(n||Array.prototype.slice.call(t))},i=function(){function e(e){this.breadcrumbs=[],this.errorCount=0,this.errorDebounceMap=new Map,this.config=r({captureScreenshots:!0,captureDomSnapshots:!0,maxStackTraceDepth:50,maxErrorsPerSession:100,debounceMs:1e3,enableNetworkTracking:!0,enableConsoleCapture:!0},e),this.sessionId=this.generateSessionId(),this.originalConsole=r({},console),this.initialize()}return e.prototype.initialize=function(){var e=this;window.addEventListener("error",function(t){e.handleError({type:"javascript",message:t.message,filename:t.filename,line:t.lineno,column:t.colno,error:t.error})}),window.addEventListener("unhandledrejection",function(t){var r;e.handleError({type:"unhandled",message:(null===(r=t.reason)||void 0===r?void 0:r.message)||"Unhandled Promise Rejection",error:t.reason,promise:!0})}),this.config.enableNetworkTracking&&this.setupNetworkTracking(),this.config.enableConsoleCapture&&this.setupConsoleCapture(),this.setupNavigationTracking(),this.setupClickTracking(),console.log("[AInamika Error Tracker] Initialized successfully")},e.prototype.generateSessionId=function(){return"session_".concat(Date.now(),"_").concat(Math.random().toString(36).substr(2,9))},e.prototype.addBreadcrumb=function(e){this.breadcrumbs.push(r(r({},e),{timestamp:Date.now()})),this.breadcrumbs.length>50&&(this.breadcrumbs=this.breadcrumbs.slice(-50))},e.prototype.handleError=function(e){if(this.errorCount>=this.config.maxErrorsPerSession)console.warn("[AInamika Error Tracker] Max errors per session reached");else{var t="".concat(e.message,"_").concat(e.filename,"_").concat(e.line),r=Date.now();if(this.errorDebounceMap.has(t)&&r-this.errorDebounceMap.get(t)<this.config.debounceMs)return;this.errorDebounceMap.set(t,r),this.errorCount++,this.captureError(e)}},e.prototype.captureError=function(e){return n(this,void 0,void 0,function(){var t,r,n;return o(this,function(o){switch(o.label){case 0:return o.trys.push([0,4,,5]),t={client_id:this.config.clientId,error_type:e.type||"javascript",message:e.message||"Unknown error",stack_trace:this.extractStackTrace(e.error),url:window.location.href,user_agent:navigator.userAgent,timestamp:Date.now(),error_metadata:{line:e.line,column:e.column,filename:e.filename,userId:this.userId,sessionId:this.sessionId,breadcrumbs:a([],this.breadcrumbs,!0),networkInfo:this.getNetworkInfo(),performance:this.getPerformanceInfo()},severity:this.assessSeverity(e),session_id:this.sessionId,user_id:this.userId},this.config.captureDomSnapshots&&(t.dom_snapshot=this.captureDomSnapshot()),this.config.captureScreenshots?(r=t,[4,this.captureScreenshot()]):[3,2];case 1:r.screen_snapshot=o.sent(),o.label=2;case 2:return[4,this.sendError(t)];case 3:return o.sent(),this.addBreadcrumb({type:"error",message:"".concat(t.error_type,": ").concat(t.message),data:{severity:t.severity}}),[3,5];case 4:return n=o.sent(),console.error("[AInamika Error Tracker] Failed to capture error:",n),[3,5];case 5:return[2]}})})},e.prototype.extractStackTrace=function(e){if(!e||!e.stack)return"";var t=e.stack.split("\n"),r=this.config.maxStackTraceDepth;return t.slice(0,r).join("\n")},e.prototype.assessSeverity=function(e){var t,r=(null===(t=e.message)||void 0===t?void 0:t.toLowerCase())||"";return r.includes("out of memory")||r.includes("security")||r.includes("permission denied")||"unhandled"===e.type?"critical":r.includes("network")||r.includes("timeout")||r.includes("failed to fetch")||r.includes("cors")?"high":r.includes("undefined")||r.includes("null")||r.includes("cannot read property")?"medium":"low"},e.prototype.captureDomSnapshot=function(){try{var e={url:window.location.href,title:document.title,viewport:{width:window.innerWidth,height:window.innerHeight},elements:this.extractDomElements()};return JSON.stringify(e)}catch(e){return console.error("[AInamika Error Tracker] Failed to capture DOM snapshot:",e),""}},e.prototype.extractDomElements=function(){var e=this,t=[];return["body > *","[id]",'[class*="error"]','[class*="modal"]',"form","button",'input[type="submit"]'].forEach(function(r){try{var n=document.querySelectorAll(r);Array.from(n).slice(0,100-t.length).forEach(function(r){var n;t.push({tagName:r.tagName,id:r.id,className:r.className,textContent:null===(n=r.textContent)||void 0===n?void 0:n.substring(0,100),attributes:e.getElementAttributes(r)})})}catch(e){}}),t},e.prototype.getElementAttributes=function(e){var t={};return["id","class","type","name","value","href","src"].forEach(function(r){var n=e.getAttribute(r);n&&(t[r]=n)}),t},e.prototype.captureScreenshot=function(){return n(this,void 0,void 0,function(){var e;return o(this,function(t){switch(t.label){case 0:return t.trys.push([0,3,,4]),"function"!=typeof window.html2canvas?[3,2]:[4,window.html2canvas(document.body,{height:Math.min(window.innerHeight,1e3),width:Math.min(window.innerWidth,1e3),useCORS:!0})];case 1:return[2,t.sent().toDataURL("image/jpeg",.7)];case 2:return[2,""];case 3:return e=t.sent(),console.error("[AInamika Error Tracker] Failed to capture screenshot:",e),[2,""];case 4:return[2]}})})},e.prototype.getNetworkInfo=function(){var e=navigator.connection||navigator.mozConnection||navigator.webkitConnection;return e?{effectiveType:e.effectiveType,downlink:e.downlink,rtt:e.rtt,saveData:e.saveData}:{}},e.prototype.getPerformanceInfo=function(){var e={};if(performance.memory&&(e.memory={usedJSHeapSize:performance.memory.usedJSHeapSize,totalJSHeapSize:performance.memory.totalJSHeapSize,jsHeapSizeLimit:performance.memory.jsHeapSizeLimit}),performance.timing){var t=performance.timing;e.timing={domContentLoaded:t.domContentLoadedEventEnd-t.navigationStart,load:t.loadEventEnd-t.navigationStart},performance.getEntriesByType&&performance.getEntriesByType("paint").forEach(function(t){"first-paint"===t.name?e.timing.firstPaint=t.startTime:"first-contentful-paint"===t.name&&(e.timing.firstContentfulPaint=t.startTime)})}return e},e.prototype.setupNetworkTracking=function(){var e=this,t=window.fetch;window.fetch=function(){for(var r=[],a=0;a<arguments.length;a++)r[a]=arguments[a];return n(e,void 0,void 0,function(){var e,n,a,i;return o(this,function(o){switch(o.label){case 0:e=Date.now(),n=r[0]instanceof Request?r[0].url:String(r[0]),o.label=1;case 1:return o.trys.push([1,3,,4]),[4,t.apply(void 0,r)];case 2:return a=o.sent(),this.addBreadcrumb({type:"network",message:"Fetch ".concat(a.status," ").concat(n),data:{url:n,status:a.status,duration:Date.now()-e}}),a.ok||this.handleError({type:"network",message:"Network request failed: ".concat(a.status," ").concat(a.statusText),url:n,status:a.status}),[2,a];case 3:throw i=o.sent(),this.addBreadcrumb({type:"network",message:"Fetch failed ".concat(n),data:{url:n,error:(null==i?void 0:i.message)||"Unknown error"}}),this.handleError({type:"network",message:"Network request failed: ".concat((null==i?void 0:i.message)||"Unknown error"),url:n,error:i}),i;case 4:return[2]}})})};var r=XMLHttpRequest.prototype.open,i=XMLHttpRequest.prototype.send;XMLHttpRequest.prototype.open=function(e,t,n,o,a){return this._errorTracker={method:e,url:t,startTime:Date.now()},r.call(this,e,t,n||!0,o,a)},XMLHttpRequest.prototype.send=function(){for(var e=this,t=[],r=0;r<arguments.length;r++)t[r]=arguments[r];var n=this._errorTracker;return this.addEventListener("loadend",function(){if(n){var t=Date.now()-n.startTime;e.status>=400&&e.dispatchEvent(new CustomEvent("networkerror",{detail:{type:"network",message:"XHR request failed: ".concat(e.status," ").concat(e.statusText),url:n.url,status:e.status}})),e.dispatchEvent(new CustomEvent("networkbreadcrumb",{detail:{type:"network",message:"XHR ".concat(e.status," ").concat(n.url),data:{method:n.method,url:n.url,status:e.status,duration:t}}}))}}),i.call.apply(i,a([this],t,!1))},document.addEventListener("networkerror",function(t){e.handleError(t.detail)}),document.addEventListener("networkbreadcrumb",function(t){e.addBreadcrumb(t.detail)})},e.prototype.setupConsoleCapture=function(){var e=this;["error","warn"].forEach(function(t){var r=e.originalConsole[t];console[t]=function(){for(var n=[],o=0;o<arguments.length;o++)n[o]=arguments[o];"function"==typeof r&&r.call.apply(r,a([console],n,!1)),"error"===t&&e.handleError({type:"console",message:n.map(function(e){return String(e)}).join(" "),consoleMethod:t}),e.addBreadcrumb({type:"console",message:"Console ".concat(t,": ").concat(n.map(function(e){return String(e)}).join(" ")),data:{level:t}})}})},e.prototype.setupNavigationTracking=function(){var e=this,t=window.location.href,r=function(){var r=window.location.href;r!==t&&(e.addBreadcrumb({type:"navigation",message:"Navigation from ".concat(t," to ").concat(r),data:{from:t,to:r}}),t=r)};window.addEventListener("popstate",r),window.addEventListener("hashchange",r);var n=history.pushState,o=history.replaceState;history.pushState=function(){for(var e=[],t=0;t<arguments.length;t++)e[t]=arguments[t];n.apply(this,e),setTimeout(r,0)},history.replaceState=function(){for(var e=[],t=0;t<arguments.length;t++)e[t]=arguments[t];o.apply(this,e),setTimeout(r,0)}},e.prototype.setupClickTracking=function(){var e=this;document.addEventListener("click",function(t){var r,n=t.target;if(n){var o=e.getElementSelector(n),a=(null===(r=n.textContent)||void 0===r?void 0:r.trim().substring(0,50))||"";e.addBreadcrumb({type:"click",message:"Clicked ".concat(o).concat(a?": ".concat(a):""),data:{selector:o,text:a,tagName:n.tagName,id:n.id,className:n.className}})}})},e.prototype.getElementSelector=function(e){if(e.id)return"#".concat(e.id);if(e.className){var t=e.className.split(" ").filter(function(e){return e}).slice(0,2);if(t.length)return".".concat(t.join("."))}return e.tagName.toLowerCase()},e.prototype.sendError=function(e){return n(this,void 0,void 0,function(){var t,r;return o(this,function(n){switch(n.label){case 0:return n.trys.push([0,2,,3]),[4,fetch("".concat(this.config.endpoint,"/api/v1/errors"),{method:"POST",headers:{"Content-Type":"application/json",Authorization:"Bearer ".concat(this.config.apiKey)},body:JSON.stringify(e)})];case 1:if(!(t=n.sent()).ok)throw new Error("Failed to send error: ".concat(t.status," ").concat(t.statusText));return console.log("[AInamika Error Tracker] Error sent successfully"),[3,3];case 2:return r=n.sent(),console.error("[AInamika Error Tracker] Failed to send error:",r),this.storeErrorLocally(e),[3,3];case 3:return[2]}})})},e.prototype.storeErrorLocally=function(e){try{var t=localStorage.getItem("ainamika_errors")||"[]",r=JSON.parse(t);r.push(e),r.length>50&&r.splice(0,r.length-50),localStorage.setItem("ainamika_errors",JSON.stringify(r))}catch(e){console.error("[AInamika Error Tracker] Failed to store error locally:",e)}},e.prototype.captureException=function(e,t){this.handleError({type:"custom",message:e.message,error:e,context:t})},e.prototype.setUser=function(e){this.userId=e},e.prototype.addTag=function(e,t){this.config.clientId||(this.config.clientId+="_".concat(e,":").concat(t))},e.prototype.flushStoredErrors=function(){return n(this,void 0,void 0,function(){var e,t,r,n,a,i;return o(this,function(o){switch(o.label){case 0:if(o.trys.push([0,5,,6]),!(e=localStorage.getItem("ainamika_errors")))return[2];if(0===(t=JSON.parse(e)).length)return[2];console.log("[AInamika Error Tracker] Flushing ".concat(t.length," stored errors")),r=0,n=t,o.label=1;case 1:return r<n.length?(a=n[r],[4,this.sendError(a)]):[3,4];case 2:o.sent(),o.label=3;case 3:return r++,[3,1];case 4:return localStorage.removeItem("ainamika_errors"),[3,6];case 5:return i=o.sent(),console.error("[AInamika Error Tracker] Failed to flush stored errors:",i),[3,6];case 6:return[2]}})})},e}(),s=function(){if("undefined"!=typeof window&&window.__AINAMIKA_CONFIG__)return window.__AINAMIKA_CONFIG__;var e="undefined"!=typeof window&&("localhost"===window.location.hostname||"127.0.0.1"===window.location.hostname);return{API_BASE_URL:e?"http://localhost:5000":"https://ainamika-backend-768143418383.europe-west1.run.app",APP_ENV:e?"development":"production",DEBUG:e}}(),c={EVENTS:"".concat(s.API_BASE_URL,"/api/v1/events"),ERRORS:"".concat(s.API_BASE_URL,"/api/errors/report"),CONFIG:"".concat(s.API_BASE_URL,"/api/v1/sdk/config"),DEBUG_EVENTS:"".concat(s.API_BASE_URL,"/api/v1/debug/events")};s.DEBUG&&console.log("[Ainamika SDK] Environment Configuration:",{API_BASE_URL:s.API_BASE_URL,APP_ENV:s.APP_ENV,DEBUG:s.DEBUG,ENDPOINTS:c});var u=function(){return u=Object.assign||function(e){for(var t,r=1,n=arguments.length;r<n;r++)for(var o in t=arguments[r])Object.prototype.hasOwnProperty.call(t,o)&&(e[o]=t[o]);return e},u.apply(this,arguments)},l=function(e,t,r,n){return new(r||(r=Promise))(function(o,a){function i(e){try{c(n.next(e))}catch(e){a(e)}}function s(e){try{c(n.throw(e))}catch(e){a(e)}}function c(e){var t;e.done?o(e.value):(t=e.value,t instanceof r?t:new r(function(e){e(t)})).then(i,s)}c((n=n.apply(e,t||[])).next())})},h=function(e,t){var r,n,o,a={label:0,sent:function(){if(1&o[0])throw o[1];return o[1]},trys:[],ops:[]},i=Object.create(("function"==typeof Iterator?Iterator:Object).prototype);return i.next=s(0),i.throw=s(1),i.return=s(2),"function"==typeof Symbol&&(i[Symbol.iterator]=function(){return this}),i;function s(s){return function(c){return function(s){if(r)throw new TypeError("Generator is already executing.");for(;i&&(i=0,s[0]&&(a=0)),a;)try{if(r=1,n&&(o=2&s[0]?n.return:s[0]?n.throw||((o=n.return)&&o.call(n),0):n.next)&&!(o=o.call(n,s[1])).done)return o;switch(n=0,o&&(s=[2&s[0],o.value]),s[0]){case 0:case 1:o=s;break;case 4:return a.label++,{value:s[1],done:!1};case 5:a.label++,n=s[1],s=[0];continue;case 7:s=a.ops.pop(),a.trys.pop();continue;default:if(!((o=(o=a.trys).length>0&&o[o.length-1])||6!==s[0]&&2!==s[0])){a=0;continue}if(3===s[0]&&(!o||s[1]>o[0]&&s[1]<o[3])){a.label=s[1];break}if(6===s[0]&&a.label<o[1]){a.label=o[1],o=s;break}if(o&&a.label<o[2]){a.label=o[2],a.ops.push(s);break}o[2]&&a.ops.pop(),a.trys.pop();continue}s=t.call(e,a)}catch(e){s=[6,e],n=0}finally{r=o=0}if(5&s[0])throw s[1];return{value:s[0]?s[1]:void 0,done:!0}}([s,c])}}},d=function(){function e(e){void 0===e&&(e={}),this.STORAGE_KEY="ainamika_error_queue",this.METADATA_KEY="ainamika_error_metadata",this.isProcessing=!1,this.config=u({maxStorageSize:5242880,maxRetries:5,retryInterval:3e4,compressionEnabled:!0,encryptionEnabled:!1},e),this.initialize()}return e.prototype.initialize=function(){var e=this;this.cleanupOldErrors(),this.startRetryTimer(),this.setupStorageListener(),setTimeout(function(){return e.processQueue()},1e3)},e.prototype.storeError=function(e){return l(this,void 0,void 0,function(){var t,r,n,o=this;return h(this,function(a){switch(a.label){case 0:return a.trys.push([0,2,,3]),t=this.generateErrorId(),r={id:t,errorData:this.config.compressionEnabled?this.compressData(e):e,timestamp:Date.now(),retryCount:0},[4,this.addToQueue(r)];case 1:return a.sent(),this.updateMetadata(),setTimeout(function(){return o.processQueue()},100),[2,t];case 2:throw n=a.sent(),console.error("[AInamika Error Storage] Failed to store error:",n),n;case 3:return[2]}})})},e.prototype.getStoredErrors=function(){var e=this;try{var t=localStorage.getItem(this.STORAGE_KEY);return t?JSON.parse(t).map(function(t){return u(u({},t),{errorData:e.config.compressionEnabled?e.decompressData(t.errorData):t.errorData})}):[]}catch(e){return console.error("[AInamika Error Storage] Failed to get stored errors:",e),[]}},e.prototype.removeError=function(e){try{var t=this.getQueueRaw(),r=t.filter(function(t){return t.id!==e});return r.length!==t.length&&(localStorage.setItem(this.STORAGE_KEY,JSON.stringify(r)),this.updateMetadata(),!0)}catch(e){return console.error("[AInamika Error Storage] Failed to remove error:",e),!1}},e.prototype.clearAll=function(){try{localStorage.removeItem(this.STORAGE_KEY),localStorage.removeItem(this.METADATA_KEY),console.log("[AInamika Error Storage] All errors cleared")}catch(e){console.error("[AInamika Error Storage] Failed to clear errors:",e)}},e.prototype.getStorageStats=function(){try{var e=this.getQueueRaw(),t=new Blob([localStorage.getItem(this.STORAGE_KEY)||""]).size,r=e.map(function(e){return e.timestamp}).sort();return{errorCount:e.length,totalSize:t,oldestError:r[0],newestError:r[r.length-1]}}catch(e){return console.error("[AInamika Error Storage] Failed to get storage stats:",e),{errorCount:0,totalSize:0}}},e.prototype.processQueue=function(){return l(this,void 0,void 0,function(){var e,t,r,n,o;return h(this,function(a){switch(a.label){case 0:if(this.isProcessing)return[2];this.isProcessing=!0,a.label=1;case 1:if(a.trys.push([1,,8,9]),0===(e=this.getQueueRaw()).length)return[2];console.log("[AInamika Error Storage] Processing ".concat(e.length," queued errors")),t=0,r=e,a.label=2;case 2:if(!(t<r.length))return[3,7];if((n=r[t]).retryCount>=this.config.maxRetries)return console.warn("[AInamika Error Storage] Max retries reached for error ".concat(n.id)),this.removeError(n.id),[3,6];if(n.lastRetry&&Date.now()-n.lastRetry<this.config.retryInterval)return[3,6];a.label=3;case 3:return a.trys.push([3,5,,6]),[4,this.sendError(n)];case 4:return a.sent()?(this.removeError(n.id),console.log("[AInamika Error Storage] Successfully sent error ".concat(n.id))):this.incrementRetryCount(n.id),[3,6];case 5:return o=a.sent(),console.error("[AInamika Error Storage] Failed to send error ".concat(n.id,":"),o),this.incrementRetryCount(n.id),[3,6];case 6:return t++,[3,2];case 7:return[3,9];case 8:return this.isProcessing=!1,[7];case 9:return[2]}})})},e.prototype.retryError=function(e){return l(this,void 0,void 0,function(){var t,r,n;return h(this,function(o){switch(o.label){case 0:if(t=this.getQueueRaw(),!(r=t.find(function(t){return t.id===e})))return[2,!1];o.label=1;case 1:return o.trys.push([1,3,,4]),[4,this.sendError(r)];case 2:return o.sent()?(this.removeError(e),[2,!0]):(this.incrementRetryCount(e),[2,!1]);case 3:return n=o.sent(),console.error("[AInamika Error Storage] Failed to retry error ".concat(e,":"),n),this.incrementRetryCount(e),[2,!1];case 4:return[2]}})})},e.prototype.addToQueue=function(e){return l(this,void 0,void 0,function(){var t,r;return h(this,function(n){if((t=this.getQueueRaw()).push(e),r=JSON.stringify(t),new Blob([r]).size>this.config.maxStorageSize)for(;t.length>0&&new Blob([JSON.stringify(t)]).size>this.config.maxStorageSize;)t.shift(),console.warn("[AInamika Error Storage] Removed old error due to size limit");return localStorage.setItem(this.STORAGE_KEY,JSON.stringify(t)),[2]})})},e.prototype.getQueueRaw=function(){try{var e=localStorage.getItem(this.STORAGE_KEY);return e?JSON.parse(e):[]}catch(e){return console.error("[AInamika Error Storage] Failed to parse stored errors:",e),[]}},e.prototype.incrementRetryCount=function(e){try{var t=this.getQueueRaw(),r=t.findIndex(function(t){return t.id===e});-1!==r&&(t[r].retryCount++,t[r].lastRetry=Date.now(),localStorage.setItem(this.STORAGE_KEY,JSON.stringify(t)))}catch(e){console.error("[AInamika Error Storage] Failed to increment retry count:",e)}},e.prototype.sendError=function(e){return l(this,void 0,void 0,function(){var t,r,n,o;return h(this,function(a){switch(a.label){case 0:return a.trys.push([0,2,,3]),t=this.config.compressionEnabled?this.decompressData(e.errorData):e.errorData,r=t.endpoint||c.ERRORS,n=t.apiKey||"",[4,fetch("".concat(r,"/api/v1/errors"),{method:"POST",headers:{"Content-Type":"application/json",Authorization:n?"Bearer ".concat(n):""},body:JSON.stringify(t)})];case 1:return[2,a.sent().ok];case 2:return o=a.sent(),console.error("[AInamika Error Storage] Network error sending stored error:",o),[2,!1];case 3:return[2]}})})},e.prototype.compressData=function(e){try{var t=JSON.stringify(e);return btoa(t)}catch(t){return console.warn("[AInamika Error Storage] Compression failed, storing uncompressed:",t),e}},e.prototype.decompressData=function(e){try{if("string"==typeof e&&e.length>0){var t=atob(e);return JSON.parse(t)}return e}catch(t){return console.warn("[AInamika Error Storage] Decompression failed, returning raw data:",t),e}},e.prototype.generateErrorId=function(){return"error_".concat(Date.now(),"_").concat(Math.random().toString(36).substr(2,9))},e.prototype.cleanupOldErrors=function(){try{var e=this.getQueueRaw(),t=Date.now()-6048e5,r=e.filter(function(e){return e.timestamp>t});r.length!==e.length&&(localStorage.setItem(this.STORAGE_KEY,JSON.stringify(r)),console.log("[AInamika Error Storage] Cleaned up ".concat(e.length-r.length," old errors")))}catch(e){console.error("[AInamika Error Storage] Failed to cleanup old errors:",e)}},e.prototype.startRetryTimer=function(){var e=this;this.retryTimer=window.setInterval(function(){e.processQueue()},this.config.retryInterval)},e.prototype.setupStorageListener=function(){var e=this;window.addEventListener("storage",function(t){t.key===e.STORAGE_KEY&&(console.log("[AInamika Error Storage] Storage updated from another tab"),setTimeout(function(){return e.processQueue()},1e3))}),window.addEventListener("online",function(){console.log("[AInamika Error Storage] Network back online, processing queue"),setTimeout(function(){return e.processQueue()},1e3)}),window.addEventListener("offline",function(){console.log("[AInamika Error Storage] Network offline, errors will be queued")})},e.prototype.updateMetadata=function(){try{var e=this.getStorageStats(),t=u({lastUpdate:Date.now()},e);localStorage.setItem(this.METADATA_KEY,JSON.stringify(t))}catch(e){console.error("[AInamika Error Storage] Failed to update metadata:",e)}},e.prototype.exportErrors=function(){try{var e=this.getStoredErrors(),t={timestamp:Date.now(),version:"1.0",stats:this.getStorageStats(),errors:e};return JSON.stringify(t,null,2)}catch(e){return console.error("[AInamika Error Storage] Failed to export errors:",e),"{}"}},e.prototype.importErrors=function(e){try{var t=JSON.parse(e);if(!t.errors||!Array.isArray(t.errors))throw new Error("Invalid export format");this.clearAll();for(var r=0,n=t.errors;r<n.length;r++){var o=n[r];this.storeError(o.errorData)}return console.log("[AInamika Error Storage] Imported ".concat(t.errors.length," errors")),!0}catch(e){return console.error("[AInamika Error Storage] Failed to import errors:",e),!1}},e.prototype.destroy=function(){this.retryTimer&&(clearInterval(this.retryTimer),this.retryTimer=void 0),this.processQueue(),console.log("[AInamika Error Storage] Storage instance destroyed")},e}(),f=(function(){function e(){}e.getAinamikaStorageUsage=function(){var e=0,t=0,r=0;for(var n in localStorage)if(localStorage.hasOwnProperty(n)){var o=new Blob([localStorage.getItem(n)||""]).size;e+=o,n.startsWith("ainamika_error")?t+=o:n.startsWith("ainamika_")&&(r+=o)}return{totalSize:e,errorSize:t,otherSize:r}},e.checkStorageSpace=function(e){try{var t="ainamika_storage_test",r="x".repeat(Math.min(e,1048576));return localStorage.setItem(t,r),localStorage.removeItem(t),!0}catch(e){return!1}},e.cleanupAllAinamikaStorage=function(){var e=[];for(var t in localStorage)t.startsWith("ainamika_")&&e.push(t);e.forEach(function(e){return localStorage.removeItem(e)}),console.log("[AInamika Storage Utils] Cleaned up ".concat(e.length," storage keys"))},e.generateStorageReport=function(){var t=new d;return{usage:e.getAinamikaStorageUsage(),errors:t.getStoredErrors(),metadata:t.getStorageStats()}}}(),function(){return f=Object.assign||function(e){for(var t,r=1,n=arguments.length;r<n;r++)for(var o in t=arguments[r])Object.prototype.hasOwnProperty.call(t,o)&&(e[o]=t[o]);return e},f.apply(this,arguments)}),p=function(e,t,r,n){return new(r||(r=Promise))(function(o,a){function i(e){try{c(n.next(e))}catch(e){a(e)}}function s(e){try{c(n.throw(e))}catch(e){a(e)}}function c(e){var t;e.done?o(e.value):(t=e.value,t instanceof r?t:new r(function(e){e(t)})).then(i,s)}c((n=n.apply(e,t||[])).next())})},g=function(e,t){var r,n,o,a={label:0,sent:function(){if(1&o[0])throw o[1];return o[1]},trys:[],ops:[]},i=Object.create(("function"==typeof Iterator?Iterator:Object).prototype);return i.next=s(0),i.throw=s(1),i.return=s(2),"function"==typeof Symbol&&(i[Symbol.iterator]=function(){return this}),i;function s(s){return function(c){return function(s){if(r)throw new TypeError("Generator is already executing.");for(;i&&(i=0,s[0]&&(a=0)),a;)try{if(r=1,n&&(o=2&s[0]?n.return:s[0]?n.throw||((o=n.return)&&o.call(n),0):n.next)&&!(o=o.call(n,s[1])).done)return o;switch(n=0,o&&(s=[2&s[0],o.value]),s[0]){case 0:case 1:o=s;break;case 4:return a.label++,{value:s[1],done:!1};case 5:a.label++,n=s[1],s=[0];continue;case 7:s=a.ops.pop(),a.trys.pop();continue;default:if(!((o=(o=a.trys).length>0&&o[o.length-1])||6!==s[0]&&2!==s[0])){a=0;continue}if(3===s[0]&&(!o||s[1]>o[0]&&s[1]<o[3])){a.label=s[1];break}if(6===s[0]&&a.label<o[1]){a.label=o[1],o=s;break}if(o&&a.label<o[2]){a.label=o[2],a.ops.push(s);break}o[2]&&a.ops.pop(),a.trys.pop();continue}s=t.call(e,a)}catch(e){s=[6,e],n=0}finally{r=o=0}if(5&s[0])throw s[1];return{value:s[0]?s[1]:void 0,done:!0}}([s,c])}}},m=function(){function e(e){this.eventQueue=[],this.isInitialized=!1,this.batchRetryCount=0,this.maxBatchRetries=5,this.domHashCache={},this.lastDomHash="",this.lastConfigHash="",this.mutationDebounceTimer=null,this.mutationDebounceMs=2e3,this.attachedListeners=new WeakMap,this.config=f({endpoint:s.API_BASE_URL,batchInterval:5e3,useWebWorker:!0,debug:s.DEBUG,errorTracking:{enabled:!0,captureScreenshots:!0,captureDomSnapshots:!0,maxStackTraceDepth:50,maxErrorsPerSession:100,debounceMs:1e3,enableNetworkTracking:!0,enableConsoleCapture:!0}},e),this.sessionId=this.generateSessionId();var t=new Blob(["\n self.eventQueue = [];\n self.config = {\n apiUrl: '',\n batchSize: 10,\n batchInterval: 5000,\n headers: { 'Content-Type': 'application/json' }\n };\n let batchTimer = null;\n function flushQueue() {\n self.postMessage({ status: 'debug', message: '[AInamika Worker] flushQueue called', eventQueue: self.eventQueue, config: self.config });\n if (self.eventQueue.length === 0) return;\n const batch = self.eventQueue.splice(0, self.config.batchSize);\n fetch(self.config.apiUrl, {\n method: 'POST',\n headers: self.config.headers,\n body: JSON.stringify({ events: batch })\n }).then(r => {\n if (r.ok) {\n self.postMessage({ status: 'success' });\n } else {\n self.postMessage({ status: 'error', error: r.statusText, failedEvents: batch });\n }\n }).catch(e => {\n self.postMessage({ status: 'error', error: e.message, failedEvents: batch });\n });\n }\n self.onmessage = function(e) {\n self.postMessage({ status: 'debug', message: '[AInamika Worker] onmessage', data: e.data });\n if (e.data.type === 'config') {\n self.config = { ...self.config, ...e.data.payload };\n if (batchTimer) clearInterval(batchTimer);\n batchTimer = setInterval(flushQueue, self.config.batchInterval);\n self.postMessage({ status: 'debug', message: '[AInamika Worker] config set', config: self.config });\n } else if (e.data.type === 'track') {\n self.eventQueue.push(e.data.payload);\n // Only send when timer triggers, not when batch size is reached\n // This ensures true batching behavior\n } else if (e.data.type === 'batch') {\n // Handle batch flush from main thread\n self.postMessage({ status: 'debug', message: '[AInamika Worker] Received batch from main thread', events: e.data.events });\n self.eventQueue.push(...e.data.events);\n flushQueue();\n } else if (e.data.type === 'initConfig') {\n // No-op for now, can be used for advanced config\n }\n };\n "],{type:"application/javascript"}),r=URL.createObjectURL(t);this.worker=new Worker(r),this.initialize()}return e.prototype.initialize=function(){return p(this,void 0,void 0,function(){var e;return g(this,function(t){switch(t.label){case 0:return this.isInitialized?[2]:(this.isInitialized=!0,(null===(e=this.config.errorTracking)||void 0===e?void 0:e.enabled)&&this.initializeErrorTracking(),this.config.autoConfig?[4,this.setupAutoConfiguration()]:[3,2]);case 1:t.sent(),t.label=2;case 2:return this.setupDynamicDomTracking(),this.config.useWebWorker&&"undefined"!=typeof Worker?this.setupWebWorker():this.startBatchTimer(),this.log("AnalyticsPro SDK initialized",{config:this.config}),[2]}})})},e.prototype.initializeErrorTracking=function(){var e,t,r,n,o,a,c,u,l,h,f,p,g,m;try{this.errorStorage=new d({maxStorageSize:5242880,maxRetries:5,retryInterval:3e4,compressionEnabled:!0,encryptionEnabled:!1});var v={endpoint:s.API_BASE_URL,clientId:this.config.clientId,apiKey:this.config.apiKey,captureScreenshots:null===(t=null===(e=this.config.errorTracking)||void 0===e?void 0:e.captureScreenshots)||void 0===t||t,captureDomSnapshots:null===(n=null===(r=this.config.errorTracking)||void 0===r?void 0:r.captureDomSnapshots)||void 0===n||n,maxStackTraceDepth:null!==(a=null===(o=this.config.errorTracking)||void 0===o?void 0:o.maxStackTraceDepth)&&void 0!==a?a:50,maxErrorsPerSession:null!==(u=null===(c=this.config.errorTracking)||void 0===c?void 0:c.maxErrorsPerSession)&&void 0!==u?u:100,debounceMs:null!==(h=null===(l=this.config.errorTracking)||void 0===l?void 0:l.debounceMs)&&void 0!==h?h:1e3,enableNetworkTracking:null===(p=null===(f=this.config.errorTracking)||void 0===f?void 0:f.enableNetworkTracking)||void 0===p||p,enableConsoleCapture:null===(m=null===(g=this.config.errorTracking)||void 0===g?void 0:g.enableConsoleCapture)||void 0===m||m};this.errorTracker=new i(v);var y=this.getUserId();y&&this.errorTracker&&this.errorTracker.setUser(y),this.log("Error tracking initialized successfully")}catch(e){console.error("[AInamika SDK] Failed to initialize error tracking:",e)}},e.prototype.captureException=function(e,t){this.errorTracker&&this.errorTracker.captureException(e,t)},e.prototype.setUser=function(e){this.errorTracker&&this.errorTracker.setUser(e)},e.prototype.flushStoredErrors=function(){return p(this,void 0,void 0,function(){return g(this,function(e){switch(e.label){case 0:return this.errorStorage?[4,this.errorStorage.processQueue()]:[3,2];case 1:e.sent(),e.label=2;case 2:return this.errorTracker?[4,this.errorTracker.flushStoredErrors()]:[3,4];case 3:e.sent(),e.label=4;case 4:return[2]}})})},e.prototype.setupAutoConfiguration=function(){return p(this,void 0,void 0,function(){var e,t,r,n;return g(this,function(o){switch(o.label){case 0:return o.trys.push([0,7,,8]),this.log("Starting auto-configuration..."),[4,this.getDOMStructure()];case 1:return e=o.sent(),t=this.computeDomHash(e),this.lastDomHash=t,(r=this.getCachedConfigForDomHash(t))?(this.log("Loaded analytics config from localStorage cache for DOM hash:",t),[3,4]):[3,2];case 2:return[4,this.loadConfigFromFile()];case 3:(r=o.sent())&&this.log("Loaded analytics config from file"),o.label=4;case 4:return r?[3,6]:(this.log("No cached config found, fetching from backend for DOM hash:",t),[4,this.fetchGeneratedConfig(e,t)]);case 5:(r=o.sent())&&r.events_to_track&&(this.saveConfigToFile(r),this.setCachedConfigForDomHash(t,r),this.lastConfigHash=r.config_hash||""),o.label=6;case 6:return r&&r.events_to_track?(this.applyGeneratedConfig(r),this.config.useWebWorker&&"undefined"!=typeof Worker&&this.worker.postMessage({type:"initConfig",config:r}),this.log("Auto-configuration applied successfully",r)):this.log("Auto-configuration failed: Invalid config received from backend.",r),[3,8];case 7:return n=o.sent(),this.log("Auto-configuration failed with error",n),[3,8];case 8:return[2]}})})},e.prototype.getDOMStructure=function(){return p(this,void 0,void 0,function(){var e,t,r,n,o;return g(this,function(a){switch(a.label){case 0:return e=function(e){if(e.id)return"#".concat(e.id);if(e.className){var t=e.className.split(" ").filter(function(e){return e.trim()}).join(".");return t?".".concat(t):e.tagName.toLowerCase()}return e.tagName.toLowerCase()},[4,new Promise(function(e){return setTimeout(e,500)})];case 1:return a.sent(),t=Array.from(document.body.querySelectorAll('\n button, a, input, select, textarea, form, img, h1, h2, h3, h4, h5, h6,\n [role=button], [role=link], [onclick], [tabindex], [data-analytics], [data-track],\n .card, .btn, .btn-primary, .btn-secondary, .card-title, .card-description, .card-price, .card-actions,\n [id*="card"], [class*="card"], [class*="btn"], [class*="price"], [class*="title"],\n div, span, p\n ')),r=t.filter(function(e){var t=window.getComputedStyle(e),r="none"!==t.display&&"hidden"!==t.visibility&&"0"!==t.opacity,n="button"===e.tagName.toLowerCase()||"a"===e.tagName.toLowerCase()||e.hasAttribute("onclick")||"button"===e.getAttribute("role")||e.classList.contains("btn")||e.classList.contains("card"),o="cardsContainer"===e.id||e.classList.contains("cards-grid")||e.classList.contains("card")||"img"===e.tagName.toLowerCase()||-1!==["h1","h2","h3"].indexOf(e.tagName.toLowerCase());return r&&(n||o)||"cardsContainer"===e.id}),n=new Set,o=r.map(function(t){var r,n,o={};return Array.from(t.attributes).forEach(function(e){-1===["style","data-timestamp","data-rendered"].indexOf(e.name)&&(o[e.name]=e.value)}),{tagName:t.tagName.toLowerCase(),selector:e(t),id:t.id||"",className:t.className||"",textContent:(t.textContent||"").trim().substring(0,100),attributes:o,isInteractive:"button"===t.tagName.toLowerCase()||"a"===t.tagName.toLowerCase()||t.hasAttribute("onclick")||"button"===t.getAttribute("role")||t.classList.contains("btn"),hasChildren:t.children.length>0,childCount:t.children.length,parentTagName:(null===(r=t.parentElement)||void 0===r?void 0:r.tagName.toLowerCase())||"",index:Array.from((null===(n=t.parentElement)||void 0===n?void 0:n.children)||[]).indexOf(t)}}).filter(function(e){var t=e.tagName+"|"+e.selector+"|"+e.textContent.substring(0,20);return!n.has(t)&&(n.add(t),!0)}),this.log("DOM structure analyzed",{elementCount:o.length,elements:o}),[2,{elements:o}]}})})},e.prototype.fetchGeneratedConfig=function(e,t){return p(this,void 0,void 0,function(){var r,n,o;return g(this,function(a){switch(a.label){case 0:return a.trys.push([0,3,,4]),e&&e.elements&&0===e.elements.length?(this.log("No elements found in DOM structure, skipping config fetch."),[2,null]):(r={structure:e},t&&(r.domHash=t,r.lastConfigHash=this.lastConfigHash),[4,fetch(c.CONFIG,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(r)})]);case 1:if(!(n=a.sent()).ok)throw new Error("Backend returned ".concat(n.status));return[4,n.json()];case 2:return[2,a.sent()];case 3:return o=a.sent(),this.log("Error fetching generated config:",o),[2,null];case 4:return[2]}})})},e.prototype.applyGeneratedConfig=function(e){var t=this;e.events_to_track.forEach(function(e){try{var r=document.querySelectorAll(e.element_selector);r.length>0?r.forEach(function(r){var n=t.attachedListeners.get(r);n||(n=new Set,t.attachedListeners.set(r,n)),(Array.isArray(e.event_type)?e.event_type:[e.event_type]).forEach(function(o){n.has(o)||(n.add(o),"click"===o&&(r.addEventListener("click",function(r){var n=r.target,o=t.extractElementData(n);t.sendToWorker(e.event_name,{selector:e.element_selector,eventType:"click",element:o,timestamp:(new Date).toISOString()})}),t.log('Attached click listener for "'.concat(e.event_name,'" on "').concat(e.element_selector,'"'))),"view"===o&&"IntersectionObserver"in window&&(new IntersectionObserver(function(r){r.forEach(function(r){if(r.isIntersecting){var n=r.target,o=t.extractElementData(n);t.sendToWorker(e.event_name,{selector:e.element_selector,eventType:"view",element:o,intersectionRatio:r.intersectionRatio,timestamp:(new Date).toISOString()})}})},{threshold:[.1,.5,1]}).observe(r),t.log('Attached IntersectionObserver for "'.concat(e.event_name,'" on "').concat(e.element_selector,'"'))),"focus"!==o&&"blur"!==o||(r.addEventListener(o,function(){var n=r,a=t.extractElementData(n);t.sendToWorker(e.event_name,{selector:e.element_selector,eventType:o,element:a,timestamp:(new Date).toISOString()})}),t.log("Attached ".concat(o,' listener for "').concat(e.event_name,'" on "').concat(e.element_selector,'"'))))})}):t.log('No elements found for selector: "'.concat(e.element_selector,'"'))}catch(r){t.log('Error applying selector "'.concat(e.element_selector,'":'),r)}}),e.observe_mutations&&"MutationObserver"in window&&(new MutationObserver(function(e){e.forEach(function(e){t.sendToWorker("dom_mutation",{type:e.type,target:e.target.outerHTML,timestamp:(new Date).toISOString()})})}).observe(document.body,{childList:!0,subtree:!0}),this.log("MutationObserver attached for DOM changes"))},e.prototype.extractElementData=function(e){var t=e.getBoundingClientRect();return{tagName:e.tagName.toLowerCase(),id:e.id||"",className:e.className||"",textContent:(e.textContent||"").trim().substring(0,100),attributes:Array.from(e.attributes).reduce(function(e,t){return e[t.name]=t.value,e},{}),position:{x:Math.round(t.x),y:Math.round(t.y),width:Math.round(t.width),height:Math.round(t.height)},href:e.href||void 0,value:e.value||void 0}},e.prototype.sendToWorker=function(e,t){var r={event:e,properties:t,timestamp:Date.now(),userId:this.getUserId(),sessionId:this.sessionId,client_id:this.config.clientId||"demo-client-001"};this.config.useWebWorker&&"undefined"!=typeof Worker?this.worker.postMessage({type:"track",payload:r}):this.eventQueue.push(r),this.log("Event tracked:",r)},e.prototype.setupWebWorker=function(){var e,t,r,n,o=this;this.worker.postMessage({type:"config",payload:{apiUrl:(null===(e=this.config.apiDetails)||void 0===e?void 0:e.apiEndPoint)||"".concat(this.config.endpoint,"/api/v1/events"),batchSize:(null===(t=this.config.workerConfig)||void 0===t?void 0:t.batchSize)||10,batchInterval:(null===(r=this.config.workerConfig)||void 0===r?void 0:r.batchInterval)||5e3,headers:(null===(n=this.config.apiDetails)||void 0===n?void 0:n.headers)||{"Content-Type":"application/json"}}}),this.worker.onmessage=function(e){var t;"success"===e.data.status?o.log("Batch sent successfully by worker"):"debug"===e.data.status?o.log(e.data.message,e.data):"error"===e.data.status&&(o.log("Worker failed to send batch",e.data.error),e.data.failedEvents&&e.data.failedEvents.length>0&&(t=o.eventQueue).unshift.apply(t,e.data.failedEvents))},this.log("Web worker setup complete.")},e.prototype.track=function(e,t){void 0===t&&(t={});var r={event:e,properties:t,timestamp:Date.now(),userId:this.getUserId(),sessionId:this.sessionId,client_id:this.config.clientId||"demo-client-001"};this.config.useWebWorker&&"undefined"!=typeof Worker?this.worker.postMessage({type:"track",payload:r}):this.eventQueue.push(r),this.log("Event tracked public:",r)},e.prototype.startBatchTimer=function(){var e=this;this.batchTimer=window.setInterval(function(){e.flushQueue()},this.config.batchInterval)},e.prototype.flushQueue=function(){return p(this,void 0,void 0,function(){var e;return g(this,function(t){switch(t.label){case 0:return 0===this.eventQueue.length?[2]:(e=function(e,t,r){if(r||2===arguments.length)for(var n,o=0,a=t.length;o<a;o++)!n&&o in t||(n||(n=Array.prototype.slice.call(t,0,o)),n[o]=t[o]);return e.concat(n||Array.prototype.slice.call(t))}([],this.eventQueue,!0),this.eventQueue=[],this.config.useWebWorker&&"undefined"!=typeof Worker?(this.worker.postMessage({type:"batch",events:e,endpoint:"".concat(this.config.endpoint,"/api/v1/events")}),[3,3]):[3,1]);case 1:return[4,this.sendBatchWithRetry(e)];case 2:t.sent(),t.label=3;case 3:return[2]}})})},e.prototype.sendBatchWithRetry=function(e){return p(this,void 0,void 0,function(){var t,r;return g(this,function(n){switch(n.label){case 0:if(this.batchRetryCount>=this.maxBatchRetries)return this.batchTimer&&(clearInterval(this.batchTimer),this.batchTimer=void 0,this.log("Max batch retries reached. BatchTimer cancelled.")),[2];n.label=1;case 1:return n.trys.push([1,3,,4]),[4,this.sendBatch(e)];case 2:return n.sent(),this.batchRetryCount=0,[3,4];case 3:return t=n.sent(),this.batchRetryCount++,this.log("Batch send failed. Retry attempt ".concat(this.batchRetryCount," of ").concat(this.maxBatchRetries,"."),t),(r=this.eventQueue).unshift.apply(r,e),this.batchRetryCount>=this.maxBatchRetries&&this.batchTimer&&(clearInterval(this.batchTimer),this.batchTimer=void 0,this.log("Max batch retries reached. BatchTimer cancelled.")),[3,4];case 4:return[2]}})})},e.prototype.sendBatch=function(e){return p(this,void 0,void 0,function(){var t,r,n,o,a,i;return g(this,function(s){switch(s.label){case 0:t="".concat(this.config.endpoint,"/api/v1/events"),r={"Content-Type":"application/json"},this.config.apiDetails&&this.config.apiDetails.apiEndPoint&&(t=this.config.apiDetails.apiEndPoint,this.config.apiDetails.headers&&(r=f(f({},r),this.config.apiDetails.headers))),n=this.config.clientId||"f01a232e-eacc-4c2e-8a06-f1c522cb8201",o=e.map(function(e){return f({event:e.event,userId:e.userId,client_id:n,timestamp:new Date(e.timestamp).toISOString()},e.properties||{})}),s.label=1;case 1:return s.trys.push([1,3,,4]),[4,fetch(t,{method:"POST",headers:r,body:JSON.stringify({events:o})})];case 2:if(!(a=s.sent()).ok)throw new Error("Failed to send batch: ".concat(a.status));return this.log("Batch sent successfully:",o),[3,4];case 3:throw i=s.sent(),this.log("Error sending batch:",i),i;case 4:return[2]}})})},e.prototype.generateSessionId=function(){return"sess_"+Math.random().toString(36).substr(2,9)},e.prototype.getUserId=function(){return"user_"+Math.random().toString(36).substr(2,9)},e.prototype.log=function(e,t){this.config.debug&&console.log("[AnalyticsPro SDK] ".concat(e),t||"")},e.prototype.saveConfigToFile=function(e){this.config.debug},e.prototype.loadConfigFromFile=function(){return p(this,void 0,void 0,function(){var e;return g(this,function(t){switch(t.label){case 0:return t.trys.push([0,3,,4]),[4,fetch("/AInamika_config.json",{cache:"reload"})];case 1:return(e=t.sent()).ok?[4,e.json()]:[2,null];case 2:return[2,t.sent()];case 3:return t.sent(),[2,null];case 4:return[2]}})})},e.prototype.setupDynamicDomTracking=function(){return p(this,void 0,void 0,function(){var e=this;return g(this,function(t){return"MutationObserver"in window&&(new MutationObserver(function(){e.mutationDebounceTimer&&clearTimeout(e.mutationDebounceTimer),e.mutationDebounceTimer=window.setTimeout(function(){e.handleDomMutation()},e.mutationDebounceMs)}).observe(document.body,{childList:!0,subtree:!0,attributes:!0}),this.log("Dynamic DOM MutationObserver attached")),[2]})})},e.prototype.computeDomHash=function(e){for(var t=JSON.stringify(e),r=2166136261,n=0;n<t.length;n++)r^=t.charCodeAt(n),r+=(r<<1)+(r<<4)+(r<<7)+(r<<8)+(r<<24);return(r>>>0).toString(16)},e.prototype.getCachedConfigForDomHash=function(e){try{return JSON.parse(localStorage.getItem("ainamika_dom_config_cache")||"{}")[e]||null}catch(e){return null}},e.prototype.setCachedConfigForDomHash=function(e,t){try{var r=JSON.parse(localStorage.getItem("ainamika_dom_config_cache")||"{}");r[e]=t,localStorage.setItem("ainamika_dom_config_cache",JSON.stringify(r))}catch(e){}},e.prototype.handleDomMutation=function(){return p(this,void 0,void 0,function(){var e,t,r,n;return g(this,function(o){switch(o.label){case 0:return[4,this.getDOMStructure()];case 1:return e=o.sent(),(t=this.computeDomHash(e))===this.lastDomHash?(this.log("DOM hash unchanged after mutation, skipping config fetch."),[2]):(this.log("DOM hash changed, checking for cached config...",{oldHash:this.lastDomHash,newHash:t}),this.lastDomHash=t,(r=this.getCachedConfigForDomHash(t))?(this.log("Reusing cached config for DOM hash",t),this.applyGeneratedConfig(r),[2]):(this.log("Fetching new config from backend for DOM hash:",t),[4,this.fetchGeneratedConfig(e,t)]));case 2:return(n=o.sent())&&n.events_to_track?(this.applyGeneratedConfig(n),this.setCachedConfigForDomHash(t,n),this.lastConfigHash=n.config_hash||"",this.log("Fetched and applied new config for new DOM hash",t)):this.log("No valid config returned for new DOM hash",t),[2]}})})},e}();"undefined"!=typeof window&&(window.AInamikaSDKPro=m);var v=m;return t.default}()});
|
|
1
|
+
!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.AInamikaSDKPro=t():e.AInamikaSDKPro=t()}("undefined"!=typeof self?self:"undefined"!=typeof window?window:"undefined"!=typeof global?global:this,function(){return function(){"use strict";var e={d:function(t,r){for(var n in r)e.o(r,n)&&!e.o(t,n)&&Object.defineProperty(t,n,{enumerable:!0,get:r[n]})},o:function(e,t){return Object.prototype.hasOwnProperty.call(e,t)}},t={};e.d(t,{default:function(){return v}});var r=function(){return r=Object.assign||function(e){for(var t,r=1,n=arguments.length;r<n;r++)for(var o in t=arguments[r])Object.prototype.hasOwnProperty.call(t,o)&&(e[o]=t[o]);return e},r.apply(this,arguments)},n=function(e,t,r,n){return new(r||(r=Promise))(function(o,a){function i(e){try{c(n.next(e))}catch(e){a(e)}}function s(e){try{c(n.throw(e))}catch(e){a(e)}}function c(e){var t;e.done?o(e.value):(t=e.value,t instanceof r?t:new r(function(e){e(t)})).then(i,s)}c((n=n.apply(e,t||[])).next())})},o=function(e,t){var r,n,o,a={label:0,sent:function(){if(1&o[0])throw o[1];return o[1]},trys:[],ops:[]},i=Object.create(("function"==typeof Iterator?Iterator:Object).prototype);return i.next=s(0),i.throw=s(1),i.return=s(2),"function"==typeof Symbol&&(i[Symbol.iterator]=function(){return this}),i;function s(s){return function(c){return function(s){if(r)throw new TypeError("Generator is already executing.");for(;i&&(i=0,s[0]&&(a=0)),a;)try{if(r=1,n&&(o=2&s[0]?n.return:s[0]?n.throw||((o=n.return)&&o.call(n),0):n.next)&&!(o=o.call(n,s[1])).done)return o;switch(n=0,o&&(s=[2&s[0],o.value]),s[0]){case 0:case 1:o=s;break;case 4:return a.label++,{value:s[1],done:!1};case 5:a.label++,n=s[1],s=[0];continue;case 7:s=a.ops.pop(),a.trys.pop();continue;default:if(!((o=(o=a.trys).length>0&&o[o.length-1])||6!==s[0]&&2!==s[0])){a=0;continue}if(3===s[0]&&(!o||s[1]>o[0]&&s[1]<o[3])){a.label=s[1];break}if(6===s[0]&&a.label<o[1]){a.label=o[1],o=s;break}if(o&&a.label<o[2]){a.label=o[2],a.ops.push(s);break}o[2]&&a.ops.pop(),a.trys.pop();continue}s=t.call(e,a)}catch(e){s=[6,e],n=0}finally{r=o=0}if(5&s[0])throw s[1];return{value:s[0]?s[1]:void 0,done:!0}}([s,c])}}},a=function(e,t,r){if(r||2===arguments.length)for(var n,o=0,a=t.length;o<a;o++)!n&&o in t||(n||(n=Array.prototype.slice.call(t,0,o)),n[o]=t[o]);return e.concat(n||Array.prototype.slice.call(t))},i=function(){function e(e){this.breadcrumbs=[],this.errorCount=0,this.errorDebounceMap=new Map,this.config=r({captureScreenshots:!0,captureDomSnapshots:!0,maxStackTraceDepth:50,maxErrorsPerSession:100,debounceMs:1e3,enableNetworkTracking:!0,enableConsoleCapture:!0},e),this.sessionId=this.generateSessionId(),this.originalConsole=r({},console),this.initialize()}return e.prototype.initialize=function(){var e=this;window.addEventListener("error",function(t){e.handleError({type:"javascript",message:t.message,filename:t.filename,line:t.lineno,column:t.colno,error:t.error})}),window.addEventListener("unhandledrejection",function(t){var r;e.handleError({type:"unhandled",message:(null===(r=t.reason)||void 0===r?void 0:r.message)||"Unhandled Promise Rejection",error:t.reason,promise:!0})}),this.config.enableNetworkTracking&&this.setupNetworkTracking(),this.config.enableConsoleCapture&&this.setupConsoleCapture(),this.setupNavigationTracking(),this.setupClickTracking(),console.log("[AInamika Error Tracker] Initialized successfully")},e.prototype.generateSessionId=function(){return"session_".concat(Date.now(),"_").concat(Math.random().toString(36).substr(2,9))},e.prototype.addBreadcrumb=function(e){this.breadcrumbs.push(r(r({},e),{timestamp:Date.now()})),this.breadcrumbs.length>50&&(this.breadcrumbs=this.breadcrumbs.slice(-50))},e.prototype.handleError=function(e){if(this.errorCount>=this.config.maxErrorsPerSession)console.warn("[AInamika Error Tracker] Max errors per session reached");else{var t="".concat(e.message,"_").concat(e.filename,"_").concat(e.line),r=Date.now();if(this.errorDebounceMap.has(t)&&r-this.errorDebounceMap.get(t)<this.config.debounceMs)return;this.errorDebounceMap.set(t,r),this.errorCount++,this.captureError(e)}},e.prototype.captureError=function(e){return n(this,void 0,void 0,function(){var t,r,n;return o(this,function(o){switch(o.label){case 0:return o.trys.push([0,4,,5]),t={client_id:this.config.clientId,error_type:e.type||"javascript",message:e.message||"Unknown error",stack_trace:this.extractStackTrace(e.error),url:window.location.href,user_agent:navigator.userAgent,timestamp:Date.now(),error_metadata:{line:e.line,column:e.column,filename:e.filename,userId:this.userId,sessionId:this.sessionId,breadcrumbs:a([],this.breadcrumbs,!0),networkInfo:this.getNetworkInfo(),performance:this.getPerformanceInfo()},severity:this.assessSeverity(e),session_id:this.sessionId,user_id:this.userId},this.config.captureDomSnapshots&&(t.dom_snapshot=this.captureDomSnapshot()),this.config.captureScreenshots?(r=t,[4,this.captureScreenshot()]):[3,2];case 1:r.screen_snapshot=o.sent(),o.label=2;case 2:return[4,this.sendError(t)];case 3:return o.sent(),this.addBreadcrumb({type:"error",message:"".concat(t.error_type,": ").concat(t.message),data:{severity:t.severity}}),[3,5];case 4:return n=o.sent(),console.error("[AInamika Error Tracker] Failed to capture error:",n),[3,5];case 5:return[2]}})})},e.prototype.extractStackTrace=function(e){if(!e||!e.stack)return"";var t=e.stack.split("\n"),r=this.config.maxStackTraceDepth;return t.slice(0,r).join("\n")},e.prototype.assessSeverity=function(e){var t,r=(null===(t=e.message)||void 0===t?void 0:t.toLowerCase())||"";return r.includes("out of memory")||r.includes("security")||r.includes("permission denied")||"unhandled"===e.type?"critical":r.includes("network")||r.includes("timeout")||r.includes("failed to fetch")||r.includes("cors")?"high":r.includes("undefined")||r.includes("null")||r.includes("cannot read property")?"medium":"low"},e.prototype.captureDomSnapshot=function(){try{var e={url:window.location.href,title:document.title,viewport:{width:window.innerWidth,height:window.innerHeight},elements:this.extractDomElements()};return JSON.stringify(e)}catch(e){return console.error("[AInamika Error Tracker] Failed to capture DOM snapshot:",e),""}},e.prototype.extractDomElements=function(){var e=this,t=[];return["body > *","[id]",'[class*="error"]','[class*="modal"]',"form","button",'input[type="submit"]'].forEach(function(r){try{var n=document.querySelectorAll(r);Array.from(n).slice(0,100-t.length).forEach(function(r){var n;t.push({tagName:r.tagName,id:r.id,className:r.className,textContent:null===(n=r.textContent)||void 0===n?void 0:n.substring(0,100),attributes:e.getElementAttributes(r)})})}catch(e){}}),t},e.prototype.getElementAttributes=function(e){var t={};return["id","class","type","name","value","href","src"].forEach(function(r){var n=e.getAttribute(r);n&&(t[r]=n)}),t},e.prototype.captureScreenshot=function(){return n(this,void 0,void 0,function(){var e;return o(this,function(t){switch(t.label){case 0:return t.trys.push([0,3,,4]),"function"!=typeof window.html2canvas?[3,2]:[4,window.html2canvas(document.body,{height:Math.min(window.innerHeight,1e3),width:Math.min(window.innerWidth,1e3),useCORS:!0})];case 1:return[2,t.sent().toDataURL("image/jpeg",.7)];case 2:return[2,""];case 3:return e=t.sent(),console.error("[AInamika Error Tracker] Failed to capture screenshot:",e),[2,""];case 4:return[2]}})})},e.prototype.getNetworkInfo=function(){var e=navigator.connection||navigator.mozConnection||navigator.webkitConnection;return e?{effectiveType:e.effectiveType,downlink:e.downlink,rtt:e.rtt,saveData:e.saveData}:{}},e.prototype.getPerformanceInfo=function(){var e={};if(performance.memory&&(e.memory={usedJSHeapSize:performance.memory.usedJSHeapSize,totalJSHeapSize:performance.memory.totalJSHeapSize,jsHeapSizeLimit:performance.memory.jsHeapSizeLimit}),performance.timing){var t=performance.timing;e.timing={domContentLoaded:t.domContentLoadedEventEnd-t.navigationStart,load:t.loadEventEnd-t.navigationStart},performance.getEntriesByType&&performance.getEntriesByType("paint").forEach(function(t){"first-paint"===t.name?e.timing.firstPaint=t.startTime:"first-contentful-paint"===t.name&&(e.timing.firstContentfulPaint=t.startTime)})}return e},e.prototype.setupNetworkTracking=function(){var e=this,t=window.fetch;window.fetch=function(){for(var r=[],a=0;a<arguments.length;a++)r[a]=arguments[a];return n(e,void 0,void 0,function(){var e,n,a,i;return o(this,function(o){switch(o.label){case 0:e=Date.now(),n=r[0]instanceof Request?r[0].url:String(r[0]),o.label=1;case 1:return o.trys.push([1,3,,4]),[4,t.apply(void 0,r)];case 2:return a=o.sent(),this.addBreadcrumb({type:"network",message:"Fetch ".concat(a.status," ").concat(n),data:{url:n,status:a.status,duration:Date.now()-e}}),a.ok||this.handleError({type:"network",message:"Network request failed: ".concat(a.status," ").concat(a.statusText),url:n,status:a.status}),[2,a];case 3:throw i=o.sent(),this.addBreadcrumb({type:"network",message:"Fetch failed ".concat(n),data:{url:n,error:(null==i?void 0:i.message)||"Unknown error"}}),this.handleError({type:"network",message:"Network request failed: ".concat((null==i?void 0:i.message)||"Unknown error"),url:n,error:i}),i;case 4:return[2]}})})};var r=XMLHttpRequest.prototype.open,i=XMLHttpRequest.prototype.send;XMLHttpRequest.prototype.open=function(e,t,n,o,a){return this._errorTracker={method:e,url:t,startTime:Date.now()},r.call(this,e,t,n||!0,o,a)},XMLHttpRequest.prototype.send=function(){for(var e=this,t=[],r=0;r<arguments.length;r++)t[r]=arguments[r];var n=this._errorTracker;return this.addEventListener("loadend",function(){if(n){var t=Date.now()-n.startTime;e.status>=400&&e.dispatchEvent(new CustomEvent("networkerror",{detail:{type:"network",message:"XHR request failed: ".concat(e.status," ").concat(e.statusText),url:n.url,status:e.status}})),e.dispatchEvent(new CustomEvent("networkbreadcrumb",{detail:{type:"network",message:"XHR ".concat(e.status," ").concat(n.url),data:{method:n.method,url:n.url,status:e.status,duration:t}}}))}}),i.call.apply(i,a([this],t,!1))},document.addEventListener("networkerror",function(t){e.handleError(t.detail)}),document.addEventListener("networkbreadcrumb",function(t){e.addBreadcrumb(t.detail)})},e.prototype.setupConsoleCapture=function(){var e=this;["error","warn"].forEach(function(t){var r=e.originalConsole[t];console[t]=function(){for(var n=[],o=0;o<arguments.length;o++)n[o]=arguments[o];"function"==typeof r&&r.call.apply(r,a([console],n,!1)),"error"===t&&e.handleError({type:"console",message:n.map(function(e){return String(e)}).join(" "),consoleMethod:t}),e.addBreadcrumb({type:"console",message:"Console ".concat(t,": ").concat(n.map(function(e){return String(e)}).join(" ")),data:{level:t}})}})},e.prototype.setupNavigationTracking=function(){var e=this,t=window.location.href,r=function(){var r=window.location.href;r!==t&&(e.addBreadcrumb({type:"navigation",message:"Navigation from ".concat(t," to ").concat(r),data:{from:t,to:r}}),t=r)};window.addEventListener("popstate",r),window.addEventListener("hashchange",r);var n=history.pushState,o=history.replaceState;history.pushState=function(){for(var e=[],t=0;t<arguments.length;t++)e[t]=arguments[t];n.apply(this,e),setTimeout(r,0)},history.replaceState=function(){for(var e=[],t=0;t<arguments.length;t++)e[t]=arguments[t];o.apply(this,e),setTimeout(r,0)}},e.prototype.setupClickTracking=function(){var e=this;document.addEventListener("click",function(t){var r,n=t.target;if(n){var o=e.getElementSelector(n),a=(null===(r=n.textContent)||void 0===r?void 0:r.trim().substring(0,50))||"";e.addBreadcrumb({type:"click",message:"Clicked ".concat(o).concat(a?": ".concat(a):""),data:{selector:o,text:a,tagName:n.tagName,id:n.id,className:n.className}})}})},e.prototype.getElementSelector=function(e){if(e.id)return"#".concat(e.id);if(e.className){var t=e.className.split(" ").filter(function(e){return e}).slice(0,2);if(t.length)return".".concat(t.join("."))}return e.tagName.toLowerCase()},e.prototype.sendError=function(e){return n(this,void 0,void 0,function(){var t,r;return o(this,function(n){switch(n.label){case 0:return n.trys.push([0,2,,3]),[4,fetch("".concat(this.config.endpoint,"/api/v1/errors"),{method:"POST",headers:{"Content-Type":"application/json",Authorization:"Bearer ".concat(this.config.apiKey)},body:JSON.stringify(e)})];case 1:if(!(t=n.sent()).ok)throw new Error("Failed to send error: ".concat(t.status," ").concat(t.statusText));return console.log("[AInamika Error Tracker] Error sent successfully"),[3,3];case 2:return r=n.sent(),console.error("[AInamika Error Tracker] Failed to send error:",r),this.storeErrorLocally(e),[3,3];case 3:return[2]}})})},e.prototype.storeErrorLocally=function(e){try{var t=localStorage.getItem("ainamika_errors")||"[]",r=JSON.parse(t);r.push(e),r.length>50&&r.splice(0,r.length-50),localStorage.setItem("ainamika_errors",JSON.stringify(r))}catch(e){console.error("[AInamika Error Tracker] Failed to store error locally:",e)}},e.prototype.captureException=function(e,t){this.handleError({type:"custom",message:e.message,error:e,context:t})},e.prototype.setUser=function(e){this.userId=e},e.prototype.addTag=function(e,t){this.config.clientId||(this.config.clientId+="_".concat(e,":").concat(t))},e.prototype.flushStoredErrors=function(){return n(this,void 0,void 0,function(){var e,t,r,n,a,i;return o(this,function(o){switch(o.label){case 0:if(o.trys.push([0,5,,6]),!(e=localStorage.getItem("ainamika_errors")))return[2];if(0===(t=JSON.parse(e)).length)return[2];console.log("[AInamika Error Tracker] Flushing ".concat(t.length," stored errors")),r=0,n=t,o.label=1;case 1:return r<n.length?(a=n[r],[4,this.sendError(a)]):[3,4];case 2:o.sent(),o.label=3;case 3:return r++,[3,1];case 4:return localStorage.removeItem("ainamika_errors"),[3,6];case 5:return i=o.sent(),console.error("[AInamika Error Tracker] Failed to flush stored errors:",i),[3,6];case 6:return[2]}})})},e}(),s=function(){if("undefined"!=typeof window&&window.__AINAMIKA_CONFIG__)return window.__AINAMIKA_CONFIG__;var e="undefined"!=typeof window&&("localhost"===window.location.hostname||"127.0.0.1"===window.location.hostname);return{API_BASE_URL:e?"http://localhost:5000":"https://ainamika-backend-768143418383.europe-west1.run.app",APP_ENV:e?"development":"production",DEBUG:e}}(),c={EVENTS:"".concat(s.API_BASE_URL,"/api/v1/events"),ERRORS:"".concat(s.API_BASE_URL,"/api/errors/report"),CONFIG:"".concat(s.API_BASE_URL,"/api/v1/sdk/config"),DEBUG_EVENTS:"".concat(s.API_BASE_URL,"/api/v1/debug/events")};s.DEBUG&&console.log("[Ainamika SDK] Environment Configuration:",{API_BASE_URL:s.API_BASE_URL,APP_ENV:s.APP_ENV,DEBUG:s.DEBUG,ENDPOINTS:c});var u=function(){return u=Object.assign||function(e){for(var t,r=1,n=arguments.length;r<n;r++)for(var o in t=arguments[r])Object.prototype.hasOwnProperty.call(t,o)&&(e[o]=t[o]);return e},u.apply(this,arguments)},l=function(e,t,r,n){return new(r||(r=Promise))(function(o,a){function i(e){try{c(n.next(e))}catch(e){a(e)}}function s(e){try{c(n.throw(e))}catch(e){a(e)}}function c(e){var t;e.done?o(e.value):(t=e.value,t instanceof r?t:new r(function(e){e(t)})).then(i,s)}c((n=n.apply(e,t||[])).next())})},h=function(e,t){var r,n,o,a={label:0,sent:function(){if(1&o[0])throw o[1];return o[1]},trys:[],ops:[]},i=Object.create(("function"==typeof Iterator?Iterator:Object).prototype);return i.next=s(0),i.throw=s(1),i.return=s(2),"function"==typeof Symbol&&(i[Symbol.iterator]=function(){return this}),i;function s(s){return function(c){return function(s){if(r)throw new TypeError("Generator is already executing.");for(;i&&(i=0,s[0]&&(a=0)),a;)try{if(r=1,n&&(o=2&s[0]?n.return:s[0]?n.throw||((o=n.return)&&o.call(n),0):n.next)&&!(o=o.call(n,s[1])).done)return o;switch(n=0,o&&(s=[2&s[0],o.value]),s[0]){case 0:case 1:o=s;break;case 4:return a.label++,{value:s[1],done:!1};case 5:a.label++,n=s[1],s=[0];continue;case 7:s=a.ops.pop(),a.trys.pop();continue;default:if(!((o=(o=a.trys).length>0&&o[o.length-1])||6!==s[0]&&2!==s[0])){a=0;continue}if(3===s[0]&&(!o||s[1]>o[0]&&s[1]<o[3])){a.label=s[1];break}if(6===s[0]&&a.label<o[1]){a.label=o[1],o=s;break}if(o&&a.label<o[2]){a.label=o[2],a.ops.push(s);break}o[2]&&a.ops.pop(),a.trys.pop();continue}s=t.call(e,a)}catch(e){s=[6,e],n=0}finally{r=o=0}if(5&s[0])throw s[1];return{value:s[0]?s[1]:void 0,done:!0}}([s,c])}}},d=function(){function e(e){void 0===e&&(e={}),this.STORAGE_KEY="ainamika_error_queue",this.METADATA_KEY="ainamika_error_metadata",this.isProcessing=!1,this.config=u({maxStorageSize:5242880,maxRetries:5,retryInterval:3e4,compressionEnabled:!0,encryptionEnabled:!1},e),this.initialize()}return e.prototype.initialize=function(){var e=this;this.cleanupOldErrors(),this.startRetryTimer(),this.setupStorageListener(),setTimeout(function(){return e.processQueue()},1e3)},e.prototype.storeError=function(e){return l(this,void 0,void 0,function(){var t,r,n,o=this;return h(this,function(a){switch(a.label){case 0:return a.trys.push([0,2,,3]),t=this.generateErrorId(),r={id:t,errorData:this.config.compressionEnabled?this.compressData(e):e,timestamp:Date.now(),retryCount:0},[4,this.addToQueue(r)];case 1:return a.sent(),this.updateMetadata(),setTimeout(function(){return o.processQueue()},100),[2,t];case 2:throw n=a.sent(),console.error("[AInamika Error Storage] Failed to store error:",n),n;case 3:return[2]}})})},e.prototype.getStoredErrors=function(){var e=this;try{var t=localStorage.getItem(this.STORAGE_KEY);return t?JSON.parse(t).map(function(t){return u(u({},t),{errorData:e.config.compressionEnabled?e.decompressData(t.errorData):t.errorData})}):[]}catch(e){return console.error("[AInamika Error Storage] Failed to get stored errors:",e),[]}},e.prototype.removeError=function(e){try{var t=this.getQueueRaw(),r=t.filter(function(t){return t.id!==e});return r.length!==t.length&&(localStorage.setItem(this.STORAGE_KEY,JSON.stringify(r)),this.updateMetadata(),!0)}catch(e){return console.error("[AInamika Error Storage] Failed to remove error:",e),!1}},e.prototype.clearAll=function(){try{localStorage.removeItem(this.STORAGE_KEY),localStorage.removeItem(this.METADATA_KEY),console.log("[AInamika Error Storage] All errors cleared")}catch(e){console.error("[AInamika Error Storage] Failed to clear errors:",e)}},e.prototype.getStorageStats=function(){try{var e=this.getQueueRaw(),t=new Blob([localStorage.getItem(this.STORAGE_KEY)||""]).size,r=e.map(function(e){return e.timestamp}).sort();return{errorCount:e.length,totalSize:t,oldestError:r[0],newestError:r[r.length-1]}}catch(e){return console.error("[AInamika Error Storage] Failed to get storage stats:",e),{errorCount:0,totalSize:0}}},e.prototype.processQueue=function(){return l(this,void 0,void 0,function(){var e,t,r,n,o;return h(this,function(a){switch(a.label){case 0:if(this.isProcessing)return[2];this.isProcessing=!0,a.label=1;case 1:if(a.trys.push([1,,8,9]),0===(e=this.getQueueRaw()).length)return[2];console.log("[AInamika Error Storage] Processing ".concat(e.length," queued errors")),t=0,r=e,a.label=2;case 2:if(!(t<r.length))return[3,7];if((n=r[t]).retryCount>=this.config.maxRetries)return console.warn("[AInamika Error Storage] Max retries reached for error ".concat(n.id)),this.removeError(n.id),[3,6];if(n.lastRetry&&Date.now()-n.lastRetry<this.config.retryInterval)return[3,6];a.label=3;case 3:return a.trys.push([3,5,,6]),[4,this.sendError(n)];case 4:return a.sent()?(this.removeError(n.id),console.log("[AInamika Error Storage] Successfully sent error ".concat(n.id))):this.incrementRetryCount(n.id),[3,6];case 5:return o=a.sent(),console.error("[AInamika Error Storage] Failed to send error ".concat(n.id,":"),o),this.incrementRetryCount(n.id),[3,6];case 6:return t++,[3,2];case 7:return[3,9];case 8:return this.isProcessing=!1,[7];case 9:return[2]}})})},e.prototype.retryError=function(e){return l(this,void 0,void 0,function(){var t,r,n;return h(this,function(o){switch(o.label){case 0:if(t=this.getQueueRaw(),!(r=t.find(function(t){return t.id===e})))return[2,!1];o.label=1;case 1:return o.trys.push([1,3,,4]),[4,this.sendError(r)];case 2:return o.sent()?(this.removeError(e),[2,!0]):(this.incrementRetryCount(e),[2,!1]);case 3:return n=o.sent(),console.error("[AInamika Error Storage] Failed to retry error ".concat(e,":"),n),this.incrementRetryCount(e),[2,!1];case 4:return[2]}})})},e.prototype.addToQueue=function(e){return l(this,void 0,void 0,function(){var t,r;return h(this,function(n){if((t=this.getQueueRaw()).push(e),r=JSON.stringify(t),new Blob([r]).size>this.config.maxStorageSize)for(;t.length>0&&new Blob([JSON.stringify(t)]).size>this.config.maxStorageSize;)t.shift(),console.warn("[AInamika Error Storage] Removed old error due to size limit");return localStorage.setItem(this.STORAGE_KEY,JSON.stringify(t)),[2]})})},e.prototype.getQueueRaw=function(){try{var e=localStorage.getItem(this.STORAGE_KEY);return e?JSON.parse(e):[]}catch(e){return console.error("[AInamika Error Storage] Failed to parse stored errors:",e),[]}},e.prototype.incrementRetryCount=function(e){try{var t=this.getQueueRaw(),r=t.findIndex(function(t){return t.id===e});-1!==r&&(t[r].retryCount++,t[r].lastRetry=Date.now(),localStorage.setItem(this.STORAGE_KEY,JSON.stringify(t)))}catch(e){console.error("[AInamika Error Storage] Failed to increment retry count:",e)}},e.prototype.sendError=function(e){return l(this,void 0,void 0,function(){var t,r,n,o;return h(this,function(a){switch(a.label){case 0:return a.trys.push([0,2,,3]),t=this.config.compressionEnabled?this.decompressData(e.errorData):e.errorData,r=t.endpoint||c.ERRORS,n=t.apiKey||"",[4,fetch("".concat(r,"/api/v1/errors"),{method:"POST",headers:{"Content-Type":"application/json",Authorization:n?"Bearer ".concat(n):""},body:JSON.stringify(t)})];case 1:return[2,a.sent().ok];case 2:return o=a.sent(),console.error("[AInamika Error Storage] Network error sending stored error:",o),[2,!1];case 3:return[2]}})})},e.prototype.compressData=function(e){try{var t=JSON.stringify(e);return btoa(t)}catch(t){return console.warn("[AInamika Error Storage] Compression failed, storing uncompressed:",t),e}},e.prototype.decompressData=function(e){try{if("string"==typeof e&&e.length>0){var t=atob(e);return JSON.parse(t)}return e}catch(t){return console.warn("[AInamika Error Storage] Decompression failed, returning raw data:",t),e}},e.prototype.generateErrorId=function(){return"error_".concat(Date.now(),"_").concat(Math.random().toString(36).substr(2,9))},e.prototype.cleanupOldErrors=function(){try{var e=this.getQueueRaw(),t=Date.now()-6048e5,r=e.filter(function(e){return e.timestamp>t});r.length!==e.length&&(localStorage.setItem(this.STORAGE_KEY,JSON.stringify(r)),console.log("[AInamika Error Storage] Cleaned up ".concat(e.length-r.length," old errors")))}catch(e){console.error("[AInamika Error Storage] Failed to cleanup old errors:",e)}},e.prototype.startRetryTimer=function(){var e=this;this.retryTimer=window.setInterval(function(){e.processQueue()},this.config.retryInterval)},e.prototype.setupStorageListener=function(){var e=this;window.addEventListener("storage",function(t){t.key===e.STORAGE_KEY&&(console.log("[AInamika Error Storage] Storage updated from another tab"),setTimeout(function(){return e.processQueue()},1e3))}),window.addEventListener("online",function(){console.log("[AInamika Error Storage] Network back online, processing queue"),setTimeout(function(){return e.processQueue()},1e3)}),window.addEventListener("offline",function(){console.log("[AInamika Error Storage] Network offline, errors will be queued")})},e.prototype.updateMetadata=function(){try{var e=this.getStorageStats(),t=u({lastUpdate:Date.now()},e);localStorage.setItem(this.METADATA_KEY,JSON.stringify(t))}catch(e){console.error("[AInamika Error Storage] Failed to update metadata:",e)}},e.prototype.exportErrors=function(){try{var e=this.getStoredErrors(),t={timestamp:Date.now(),version:"1.0",stats:this.getStorageStats(),errors:e};return JSON.stringify(t,null,2)}catch(e){return console.error("[AInamika Error Storage] Failed to export errors:",e),"{}"}},e.prototype.importErrors=function(e){try{var t=JSON.parse(e);if(!t.errors||!Array.isArray(t.errors))throw new Error("Invalid export format");this.clearAll();for(var r=0,n=t.errors;r<n.length;r++){var o=n[r];this.storeError(o.errorData)}return console.log("[AInamika Error Storage] Imported ".concat(t.errors.length," errors")),!0}catch(e){return console.error("[AInamika Error Storage] Failed to import errors:",e),!1}},e.prototype.destroy=function(){this.retryTimer&&(clearInterval(this.retryTimer),this.retryTimer=void 0),this.processQueue(),console.log("[AInamika Error Storage] Storage instance destroyed")},e}(),f=(function(){function e(){}e.getAinamikaStorageUsage=function(){var e=0,t=0,r=0;for(var n in localStorage)if(localStorage.hasOwnProperty(n)){var o=new Blob([localStorage.getItem(n)||""]).size;e+=o,n.startsWith("ainamika_error")?t+=o:n.startsWith("ainamika_")&&(r+=o)}return{totalSize:e,errorSize:t,otherSize:r}},e.checkStorageSpace=function(e){try{var t="ainamika_storage_test",r="x".repeat(Math.min(e,1048576));return localStorage.setItem(t,r),localStorage.removeItem(t),!0}catch(e){return!1}},e.cleanupAllAinamikaStorage=function(){var e=[];for(var t in localStorage)t.startsWith("ainamika_")&&e.push(t);e.forEach(function(e){return localStorage.removeItem(e)}),console.log("[AInamika Storage Utils] Cleaned up ".concat(e.length," storage keys"))},e.generateStorageReport=function(){var t=new d;return{usage:e.getAinamikaStorageUsage(),errors:t.getStoredErrors(),metadata:t.getStorageStats()}}}(),function(){return f=Object.assign||function(e){for(var t,r=1,n=arguments.length;r<n;r++)for(var o in t=arguments[r])Object.prototype.hasOwnProperty.call(t,o)&&(e[o]=t[o]);return e},f.apply(this,arguments)}),p=function(e,t,r,n){return new(r||(r=Promise))(function(o,a){function i(e){try{c(n.next(e))}catch(e){a(e)}}function s(e){try{c(n.throw(e))}catch(e){a(e)}}function c(e){var t;e.done?o(e.value):(t=e.value,t instanceof r?t:new r(function(e){e(t)})).then(i,s)}c((n=n.apply(e,t||[])).next())})},g=function(e,t){var r,n,o,a={label:0,sent:function(){if(1&o[0])throw o[1];return o[1]},trys:[],ops:[]},i=Object.create(("function"==typeof Iterator?Iterator:Object).prototype);return i.next=s(0),i.throw=s(1),i.return=s(2),"function"==typeof Symbol&&(i[Symbol.iterator]=function(){return this}),i;function s(s){return function(c){return function(s){if(r)throw new TypeError("Generator is already executing.");for(;i&&(i=0,s[0]&&(a=0)),a;)try{if(r=1,n&&(o=2&s[0]?n.return:s[0]?n.throw||((o=n.return)&&o.call(n),0):n.next)&&!(o=o.call(n,s[1])).done)return o;switch(n=0,o&&(s=[2&s[0],o.value]),s[0]){case 0:case 1:o=s;break;case 4:return a.label++,{value:s[1],done:!1};case 5:a.label++,n=s[1],s=[0];continue;case 7:s=a.ops.pop(),a.trys.pop();continue;default:if(!((o=(o=a.trys).length>0&&o[o.length-1])||6!==s[0]&&2!==s[0])){a=0;continue}if(3===s[0]&&(!o||s[1]>o[0]&&s[1]<o[3])){a.label=s[1];break}if(6===s[0]&&a.label<o[1]){a.label=o[1],o=s;break}if(o&&a.label<o[2]){a.label=o[2],a.ops.push(s);break}o[2]&&a.ops.pop(),a.trys.pop();continue}s=t.call(e,a)}catch(e){s=[6,e],n=0}finally{r=o=0}if(5&s[0])throw s[1];return{value:s[0]?s[1]:void 0,done:!0}}([s,c])}}},m=function(){function e(e){this.eventQueue=[],this.isInitialized=!1,this.batchRetryCount=0,this.maxBatchRetries=5,this.domHashCache={},this.lastDomHash="",this.lastConfigHash="",this.mutationDebounceTimer=null,this.mutationDebounceMs=2e3,this.attachedListeners=new WeakMap,this.config=f({endpoint:s.API_BASE_URL,batchInterval:5e3,useWebWorker:!0,debug:s.DEBUG,errorTracking:{enabled:!0,captureScreenshots:!0,captureDomSnapshots:!0,maxStackTraceDepth:50,maxErrorsPerSession:100,debounceMs:1e3,enableNetworkTracking:!0,enableConsoleCapture:!0}},e),this.sessionId=this.generateSessionId();var t=new Blob(["\n self.eventQueue = [];\n self.config = {\n apiUrl: '',\n batchSize: 10,\n batchInterval: 5000,\n headers: { 'Content-Type': 'application/json' }\n };\n let batchTimer = null;\n function flushQueue() {\n self.postMessage({ status: 'debug', message: '[AInamika Worker] flushQueue called', eventQueue: self.eventQueue, config: self.config });\n if (self.eventQueue.length === 0) return;\n const batch = self.eventQueue.splice(0, self.config.batchSize);\n fetch(self.config.apiUrl, {\n method: 'POST',\n headers: self.config.headers,\n body: JSON.stringify({ events: batch })\n }).then(r => {\n if (r.ok) {\n self.postMessage({ status: 'success' });\n } else {\n self.postMessage({ status: 'error', error: r.statusText, failedEvents: batch });\n }\n }).catch(e => {\n self.postMessage({ status: 'error', error: e.message, failedEvents: batch });\n });\n }\n self.onmessage = function(e) {\n self.postMessage({ status: 'debug', message: '[AInamika Worker] onmessage', data: e.data });\n if (e.data.type === 'config') {\n self.config = { ...self.config, ...e.data.payload };\n if (batchTimer) clearInterval(batchTimer);\n batchTimer = setInterval(flushQueue, self.config.batchInterval);\n self.postMessage({ status: 'debug', message: '[AInamika Worker] config set', config: self.config });\n } else if (e.data.type === 'track') {\n self.eventQueue.push(e.data.payload);\n // Only send when timer triggers, not when batch size is reached\n // This ensures true batching behavior\n } else if (e.data.type === 'batch') {\n // Handle batch flush from main thread\n self.postMessage({ status: 'debug', message: '[AInamika Worker] Received batch from main thread', events: e.data.events });\n self.eventQueue.push(...e.data.events);\n flushQueue();\n } else if (e.data.type === 'initConfig') {\n // No-op for now, can be used for advanced config\n }\n };\n "],{type:"application/javascript"}),r=URL.createObjectURL(t);this.worker=new Worker(r),this.initialize()}return e.prototype.initialize=function(){return p(this,void 0,void 0,function(){var e;return g(this,function(t){switch(t.label){case 0:return this.isInitialized?[2]:(this.isInitialized=!0,(null===(e=this.config.errorTracking)||void 0===e?void 0:e.enabled)&&this.initializeErrorTracking(),this.config.autoConfig?[4,this.setupAutoConfiguration()]:[3,2]);case 1:t.sent(),t.label=2;case 2:return this.setupDynamicDomTracking(),this.config.useWebWorker&&"undefined"!=typeof Worker?this.setupWebWorker():this.startBatchTimer(),this.log("AnalyticsPro SDK initialized",{config:this.config}),[2]}})})},e.prototype.initializeErrorTracking=function(){var e,t,r,n,o,a,c,u,l,h,f,p,g,m;try{this.errorStorage=new d({maxStorageSize:5242880,maxRetries:5,retryInterval:3e4,compressionEnabled:!0,encryptionEnabled:!1});var v={endpoint:s.API_BASE_URL,clientId:this.config.clientId,apiKey:this.config.apiKey,captureScreenshots:null===(t=null===(e=this.config.errorTracking)||void 0===e?void 0:e.captureScreenshots)||void 0===t||t,captureDomSnapshots:null===(n=null===(r=this.config.errorTracking)||void 0===r?void 0:r.captureDomSnapshots)||void 0===n||n,maxStackTraceDepth:null!==(a=null===(o=this.config.errorTracking)||void 0===o?void 0:o.maxStackTraceDepth)&&void 0!==a?a:50,maxErrorsPerSession:null!==(u=null===(c=this.config.errorTracking)||void 0===c?void 0:c.maxErrorsPerSession)&&void 0!==u?u:100,debounceMs:null!==(h=null===(l=this.config.errorTracking)||void 0===l?void 0:l.debounceMs)&&void 0!==h?h:1e3,enableNetworkTracking:null===(p=null===(f=this.config.errorTracking)||void 0===f?void 0:f.enableNetworkTracking)||void 0===p||p,enableConsoleCapture:null===(m=null===(g=this.config.errorTracking)||void 0===g?void 0:g.enableConsoleCapture)||void 0===m||m};this.errorTracker=new i(v);var y=this.getUserId();y&&this.errorTracker&&this.errorTracker.setUser(y),this.log("Error tracking initialized successfully")}catch(e){console.error("[AInamika SDK] Failed to initialize error tracking:",e)}},e.prototype.captureException=function(e,t){this.errorTracker&&this.errorTracker.captureException(e,t)},e.prototype.setUser=function(e){this.errorTracker&&this.errorTracker.setUser(e)},e.prototype.flushStoredErrors=function(){return p(this,void 0,void 0,function(){return g(this,function(e){switch(e.label){case 0:return this.errorStorage?[4,this.errorStorage.processQueue()]:[3,2];case 1:e.sent(),e.label=2;case 2:return this.errorTracker?[4,this.errorTracker.flushStoredErrors()]:[3,4];case 3:e.sent(),e.label=4;case 4:return[2]}})})},e.prototype.setupAutoConfiguration=function(){return p(this,void 0,void 0,function(){var e,t,r,n;return g(this,function(o){switch(o.label){case 0:return o.trys.push([0,7,,8]),this.log("Starting auto-configuration..."),[4,this.getDOMStructure()];case 1:return e=o.sent(),t=this.computeDomHash(e),this.lastDomHash=t,(r=this.getCachedConfigForDomHash(t))?(this.log("Loaded analytics config from localStorage cache for DOM hash:",t),[3,4]):[3,2];case 2:return[4,this.loadConfigFromFile()];case 3:(r=o.sent())&&this.log("Loaded analytics config from file"),o.label=4;case 4:return r?[3,6]:(this.log("No cached config found, fetching from backend for DOM hash:",t),[4,this.fetchGeneratedConfig(e,t)]);case 5:(r=o.sent())&&r.events_to_track&&(this.saveConfigToFile(r),this.setCachedConfigForDomHash(t,r),this.lastConfigHash=r.config_hash||""),o.label=6;case 6:return r&&r.events_to_track?(this.applyGeneratedConfig(r),this.config.useWebWorker&&"undefined"!=typeof Worker&&this.worker.postMessage({type:"initConfig",config:r}),this.log("Auto-configuration applied successfully",r)):this.log("Auto-configuration failed: Invalid config received from backend.",r),[3,8];case 7:return n=o.sent(),this.log("Auto-configuration failed with error",n),[3,8];case 8:return[2]}})})},e.prototype.getDOMStructure=function(){return p(this,void 0,void 0,function(){var e,t,r,n,o;return g(this,function(a){switch(a.label){case 0:return e=function(e){if(e.id)return"#".concat(e.id);if(e.className){var t=e.className.split(" ").filter(function(e){return e.trim()}).join(".");return t?".".concat(t):e.tagName.toLowerCase()}return e.tagName.toLowerCase()},[4,new Promise(function(e){return setTimeout(e,500)})];case 1:return a.sent(),t=Array.from(document.body.querySelectorAll('\n button, a, input, select, textarea, form, img, h1, h2, h3, h4, h5, h6,\n [role=button], [role=link], [onclick], [tabindex], [data-analytics], [data-track],\n .card, .btn, .btn-primary, .btn-secondary, .card-title, .card-description, .card-price, .card-actions,\n [id*="card"], [class*="card"], [class*="btn"], [class*="price"], [class*="title"],\n div, span, p\n ')),r=t.filter(function(e){var t=window.getComputedStyle(e),r="none"!==t.display&&"hidden"!==t.visibility&&"0"!==t.opacity,n="button"===e.tagName.toLowerCase()||"a"===e.tagName.toLowerCase()||e.hasAttribute("onclick")||"button"===e.getAttribute("role")||e.classList.contains("btn")||e.classList.contains("card"),o="cardsContainer"===e.id||e.classList.contains("cards-grid")||e.classList.contains("card")||"img"===e.tagName.toLowerCase()||-1!==["h1","h2","h3"].indexOf(e.tagName.toLowerCase());return r&&(n||o)||"cardsContainer"===e.id}),n=new Set,o=r.map(function(t){var r,n,o={};return Array.from(t.attributes).forEach(function(e){-1===["style","data-timestamp","data-rendered"].indexOf(e.name)&&(o[e.name]=e.value)}),{tagName:t.tagName.toLowerCase(),selector:e(t),id:t.id||"",className:t.className||"",textContent:(t.textContent||"").trim().substring(0,100),attributes:o,isInteractive:"button"===t.tagName.toLowerCase()||"a"===t.tagName.toLowerCase()||t.hasAttribute("onclick")||"button"===t.getAttribute("role")||t.classList.contains("btn"),hasChildren:t.children.length>0,childCount:t.children.length,parentTagName:(null===(r=t.parentElement)||void 0===r?void 0:r.tagName.toLowerCase())||"",index:Array.from((null===(n=t.parentElement)||void 0===n?void 0:n.children)||[]).indexOf(t)}}).filter(function(e){var t=e.tagName+"|"+e.selector+"|"+e.textContent.substring(0,20);return!n.has(t)&&(n.add(t),!0)}),this.log("DOM structure analyzed",{elementCount:o.length,elements:o}),[2,{elements:o}]}})})},e.prototype.fetchGeneratedConfig=function(e,t){return p(this,void 0,void 0,function(){var r,n,o;return g(this,function(a){switch(a.label){case 0:return a.trys.push([0,3,,4]),e&&e.elements&&0===e.elements.length?(this.log("No elements found in DOM structure, skipping config fetch."),[2,null]):(r={structure:e},t&&(r.domHash=t,r.lastConfigHash=this.lastConfigHash),[4,fetch(c.CONFIG,{method:"POST",headers:{"Content-Type":"application/json","X-Tenant-ID":this.config.clientId},body:JSON.stringify(r)})]);case 1:if(!(n=a.sent()).ok)throw new Error("Backend returned ".concat(n.status));return[4,n.json()];case 2:return[2,a.sent()];case 3:return o=a.sent(),this.log("Error fetching generated config:",o),[2,null];case 4:return[2]}})})},e.prototype.applyGeneratedConfig=function(e){var t=this;e.events_to_track.forEach(function(e){try{var r=document.querySelectorAll(e.element_selector);r.length>0?r.forEach(function(r){var n=t.attachedListeners.get(r);n||(n=new Set,t.attachedListeners.set(r,n)),(Array.isArray(e.event_type)?e.event_type:[e.event_type]).forEach(function(o){n.has(o)||(n.add(o),"click"===o&&(r.addEventListener("click",function(r){var n=r.target,o=t.extractElementData(n);t.sendToWorker(e.event_name,{selector:e.element_selector,eventType:"click",element:o,timestamp:(new Date).toISOString()})}),t.log('Attached click listener for "'.concat(e.event_name,'" on "').concat(e.element_selector,'"'))),"view"===o&&"IntersectionObserver"in window&&(new IntersectionObserver(function(r){r.forEach(function(r){if(r.isIntersecting){var n=r.target,o=t.extractElementData(n);t.sendToWorker(e.event_name,{selector:e.element_selector,eventType:"view",element:o,intersectionRatio:r.intersectionRatio,timestamp:(new Date).toISOString()})}})},{threshold:[.1,.5,1]}).observe(r),t.log('Attached IntersectionObserver for "'.concat(e.event_name,'" on "').concat(e.element_selector,'"'))),"focus"!==o&&"blur"!==o||(r.addEventListener(o,function(){var n=r,a=t.extractElementData(n);t.sendToWorker(e.event_name,{selector:e.element_selector,eventType:o,element:a,timestamp:(new Date).toISOString()})}),t.log("Attached ".concat(o,' listener for "').concat(e.event_name,'" on "').concat(e.element_selector,'"'))))})}):t.log('No elements found for selector: "'.concat(e.element_selector,'"'))}catch(r){t.log('Error applying selector "'.concat(e.element_selector,'":'),r)}}),e.observe_mutations&&"MutationObserver"in window&&(new MutationObserver(function(e){e.forEach(function(e){t.sendToWorker("dom_mutation",{type:e.type,target:e.target.outerHTML,timestamp:(new Date).toISOString()})})}).observe(document.body,{childList:!0,subtree:!0}),this.log("MutationObserver attached for DOM changes"))},e.prototype.extractElementData=function(e){var t=e.getBoundingClientRect();return{tagName:e.tagName.toLowerCase(),id:e.id||"",className:e.className||"",textContent:(e.textContent||"").trim().substring(0,100),attributes:Array.from(e.attributes).reduce(function(e,t){return e[t.name]=t.value,e},{}),position:{x:Math.round(t.x),y:Math.round(t.y),width:Math.round(t.width),height:Math.round(t.height)},href:e.href||void 0,value:e.value||void 0}},e.prototype.sendToWorker=function(e,t){var r={event:e,properties:t,timestamp:Date.now(),userId:this.getUserId(),sessionId:this.sessionId,client_id:this.config.clientId||"5288aa7d-1b7c-481e-958d-eb9b8e951f14"};this.config.useWebWorker&&"undefined"!=typeof Worker?this.worker.postMessage({type:"track",payload:r}):this.eventQueue.push(r),this.log("Event tracked:",r)},e.prototype.setupWebWorker=function(){var e,t,r,n,o=this;this.worker.postMessage({type:"config",payload:{apiUrl:(null===(e=this.config.apiDetails)||void 0===e?void 0:e.apiEndPoint)||"".concat(this.config.endpoint,"/api/v1/events"),batchSize:(null===(t=this.config.workerConfig)||void 0===t?void 0:t.batchSize)||10,batchInterval:(null===(r=this.config.workerConfig)||void 0===r?void 0:r.batchInterval)||5e3,headers:(null===(n=this.config.apiDetails)||void 0===n?void 0:n.headers)||{"Content-Type":"application/json"}}}),this.worker.onmessage=function(e){var t;"success"===e.data.status?o.log("Batch sent successfully by worker"):"debug"===e.data.status?o.log(e.data.message,e.data):"error"===e.data.status&&(o.log("Worker failed to send batch",e.data.error),e.data.failedEvents&&e.data.failedEvents.length>0&&(t=o.eventQueue).unshift.apply(t,e.data.failedEvents))},this.log("Web worker setup complete.")},e.prototype.track=function(e,t){void 0===t&&(t={});var r={event:e,properties:t,timestamp:Date.now(),userId:this.getUserId(),sessionId:this.sessionId,client_id:this.config.clientId||"5288aa7d-1b7c-481e-958d-eb9b8e951f14"};this.config.useWebWorker&&"undefined"!=typeof Worker?this.worker.postMessage({type:"track",payload:r}):this.eventQueue.push(r),this.log("Event tracked public:",r)},e.prototype.startBatchTimer=function(){var e=this;this.batchTimer=window.setInterval(function(){e.flushQueue()},this.config.batchInterval)},e.prototype.flushQueue=function(){return p(this,void 0,void 0,function(){var e;return g(this,function(t){switch(t.label){case 0:return 0===this.eventQueue.length?[2]:(e=function(e,t,r){if(r||2===arguments.length)for(var n,o=0,a=t.length;o<a;o++)!n&&o in t||(n||(n=Array.prototype.slice.call(t,0,o)),n[o]=t[o]);return e.concat(n||Array.prototype.slice.call(t))}([],this.eventQueue,!0),this.eventQueue=[],this.config.useWebWorker&&"undefined"!=typeof Worker?(this.worker.postMessage({type:"batch",events:e,endpoint:"".concat(this.config.endpoint,"/api/v1/events")}),[3,3]):[3,1]);case 1:return[4,this.sendBatchWithRetry(e)];case 2:t.sent(),t.label=3;case 3:return[2]}})})},e.prototype.sendBatchWithRetry=function(e){return p(this,void 0,void 0,function(){var t,r;return g(this,function(n){switch(n.label){case 0:if(this.batchRetryCount>=this.maxBatchRetries)return this.batchTimer&&(clearInterval(this.batchTimer),this.batchTimer=void 0,this.log("Max batch retries reached. BatchTimer cancelled.")),[2];n.label=1;case 1:return n.trys.push([1,3,,4]),[4,this.sendBatch(e)];case 2:return n.sent(),this.batchRetryCount=0,[3,4];case 3:return t=n.sent(),this.batchRetryCount++,this.log("Batch send failed. Retry attempt ".concat(this.batchRetryCount," of ").concat(this.maxBatchRetries,"."),t),(r=this.eventQueue).unshift.apply(r,e),this.batchRetryCount>=this.maxBatchRetries&&this.batchTimer&&(clearInterval(this.batchTimer),this.batchTimer=void 0,this.log("Max batch retries reached. BatchTimer cancelled.")),[3,4];case 4:return[2]}})})},e.prototype.sendBatch=function(e){return p(this,void 0,void 0,function(){var t,r,n,o,a,i;return g(this,function(s){switch(s.label){case 0:t="".concat(this.config.endpoint,"/api/v1/events"),r={"Content-Type":"application/json"},this.config.apiDetails&&this.config.apiDetails.apiEndPoint&&(t=this.config.apiDetails.apiEndPoint,this.config.apiDetails.headers&&(r=f(f({},r),this.config.apiDetails.headers))),n=this.config.clientId||"5288aa7d-1b7c-481e-958d-eb9b8e951f14",o=e.map(function(e){return f({event:e.event,userId:e.userId,client_id:n,timestamp:new Date(e.timestamp).toISOString()},e.properties||{})}),s.label=1;case 1:return s.trys.push([1,3,,4]),[4,fetch(t,{method:"POST",headers:r,body:JSON.stringify({events:o})})];case 2:if(!(a=s.sent()).ok)throw new Error("Failed to send batch: ".concat(a.status));return this.log("Batch sent successfully:",o),[3,4];case 3:throw i=s.sent(),this.log("Error sending batch:",i),i;case 4:return[2]}})})},e.prototype.generateSessionId=function(){return"sess_"+Math.random().toString(36).substr(2,9)},e.prototype.getUserId=function(){return"user_"+Math.random().toString(36).substr(2,9)},e.prototype.log=function(e,t){this.config.debug&&console.log("[AnalyticsPro SDK] ".concat(e),t||"")},e.prototype.saveConfigToFile=function(e){this.config.debug},e.prototype.loadConfigFromFile=function(){return p(this,void 0,void 0,function(){var e;return g(this,function(t){switch(t.label){case 0:return t.trys.push([0,3,,4]),[4,fetch("/AInamika_config.json",{cache:"reload"})];case 1:return(e=t.sent()).ok?[4,e.json()]:[2,null];case 2:return[2,t.sent()];case 3:return t.sent(),[2,null];case 4:return[2]}})})},e.prototype.setupDynamicDomTracking=function(){return p(this,void 0,void 0,function(){var e=this;return g(this,function(t){return"MutationObserver"in window&&(new MutationObserver(function(){e.mutationDebounceTimer&&clearTimeout(e.mutationDebounceTimer),e.mutationDebounceTimer=window.setTimeout(function(){e.handleDomMutation()},e.mutationDebounceMs)}).observe(document.body,{childList:!0,subtree:!0,attributes:!0}),this.log("Dynamic DOM MutationObserver attached")),[2]})})},e.prototype.computeDomHash=function(e){for(var t=JSON.stringify(e),r=2166136261,n=0;n<t.length;n++)r^=t.charCodeAt(n),r+=(r<<1)+(r<<4)+(r<<7)+(r<<8)+(r<<24);return(r>>>0).toString(16)},e.prototype.getCachedConfigForDomHash=function(e){try{return JSON.parse(localStorage.getItem("ainamika_dom_config_cache")||"{}")[e]||null}catch(e){return null}},e.prototype.setCachedConfigForDomHash=function(e,t){try{var r=JSON.parse(localStorage.getItem("ainamika_dom_config_cache")||"{}");r[e]=t,localStorage.setItem("ainamika_dom_config_cache",JSON.stringify(r))}catch(e){}},e.prototype.handleDomMutation=function(){return p(this,void 0,void 0,function(){var e,t,r,n;return g(this,function(o){switch(o.label){case 0:return[4,this.getDOMStructure()];case 1:return e=o.sent(),(t=this.computeDomHash(e))===this.lastDomHash?(this.log("DOM hash unchanged after mutation, skipping config fetch."),[2]):(this.log("DOM hash changed, checking for cached config...",{oldHash:this.lastDomHash,newHash:t}),this.lastDomHash=t,(r=this.getCachedConfigForDomHash(t))?(this.log("Reusing cached config for DOM hash",t),this.applyGeneratedConfig(r),[2]):(this.log("Fetching new config from backend for DOM hash:",t),[4,this.fetchGeneratedConfig(e,t)]));case 2:return(n=o.sent())&&n.events_to_track?(this.applyGeneratedConfig(n),this.setCachedConfigForDomHash(t,n),this.lastConfigHash=n.config_hash||"",this.log("Fetched and applied new config for new DOM hash",t)):this.log("No valid config returned for new DOM hash",t),[2]}})})},e}();"undefined"!=typeof window&&(window.AInamikaSDKPro=m);var v=m;return t.default}()});
|
|
2
2
|
//# sourceMappingURL=ainamika-sdk.js.map
|
package/dist/ainamika-sdk.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ainamika-sdk.js","mappings":"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","sources":["webpack://AInamikaSDKPro/webpack/universalModuleDefinition","webpack://AInamikaSDKPro/webpack/bootstrap","webpack://AInamikaSDKPro/webpack/runtime/define property getters","webpack://AInamikaSDKPro/webpack/runtime/hasOwnProperty shorthand","webpack://AInamikaSDKPro/./src/error-tracker.ts","webpack://AInamikaSDKPro/./src/config.ts","webpack://AInamikaSDKPro/./src/error-storage.ts","webpack://AInamikaSDKPro/./src/sdk.ts"],"sourcesContent":["(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory();\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"AInamikaSDKPro\"] = factory();\n\telse\n\t\troot[\"AInamikaSDKPro\"] = factory();\n})((typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : typeof global !== \"undefined\" ? global : this), function() {\nreturn ","// The require scope\nvar __webpack_require__ = {};\n\n","// define getter functions for harmony exports\n__webpack_require__.d = function(exports, definition) {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.o = function(obj, prop) { return Object.prototype.hasOwnProperty.call(obj, prop); }","// error-tracker.ts - Advanced Error Tracking System for AInamika SDK\n\nexport interface ErrorConfig {\n endpoint: string;\n clientId: string;\n apiKey: string;\n captureScreenshots?: boolean;\n captureDomSnapshots?: boolean;\n maxStackTraceDepth?: number;\n maxErrorsPerSession?: number;\n debounceMs?: number;\n enableNetworkTracking?: boolean;\n enableConsoleCapture?: boolean;\n}\n\nexport interface ErrorData {\n id?: string;\n client_id: string;\n error_type: 'javascript' | 'network' | 'unhandled' | 'console' | 'custom';\n message: string;\n stack_trace?: string;\n url: string;\n user_agent: string;\n timestamp: number;\n error_metadata: {\n line?: number;\n column?: number;\n filename?: string;\n component?: string;\n props?: Record<string, any>;\n userId?: string;\n sessionId?: string;\n breadcrumbs?: ErrorBreadcrumb[];\n networkInfo?: NetworkInfo;\n performance?: PerformanceInfo;\n };\n dom_snapshot?: string;\n screen_snapshot?: string;\n severity: 'low' | 'medium' | 'high' | 'critical';\n session_id: string;\n user_id?: string;\n}\n\nexport interface ErrorBreadcrumb {\n timestamp: number;\n type: 'navigation' | 'click' | 'console' | 'network' | 'error';\n message: string;\n data?: Record<string, any>;\n}\n\nexport interface NetworkInfo {\n effectiveType?: string;\n downlink?: number;\n rtt?: number;\n saveData?: boolean;\n}\n\nexport interface PerformanceInfo {\n memory?: {\n usedJSHeapSize: number;\n totalJSHeapSize: number;\n jsHeapSizeLimit: number;\n };\n timing?: {\n domContentLoaded: number;\n load: number;\n firstPaint?: number;\n firstContentfulPaint?: number;\n };\n}\n\nexport class ErrorTracker {\n private config: ErrorConfig;\n private breadcrumbs: ErrorBreadcrumb[] = [];\n private errorCount = 0;\n private errorDebounceMap = new Map<string, number>();\n private originalConsole: Console;\n private sessionId: string;\n private userId?: string;\n\n constructor(config: ErrorConfig) {\n this.config = {\n captureScreenshots: true,\n captureDomSnapshots: true,\n maxStackTraceDepth: 50,\n maxErrorsPerSession: 100,\n debounceMs: 1000,\n enableNetworkTracking: true,\n enableConsoleCapture: true,\n ...config\n };\n\n this.sessionId = this.generateSessionId();\n this.originalConsole = { ...console };\n this.initialize();\n }\n\n private initialize() {\n // Global error handler\n window.addEventListener('error', (event) => {\n this.handleError({\n type: 'javascript',\n message: event.message,\n filename: event.filename,\n line: event.lineno,\n column: event.colno,\n error: event.error\n });\n });\n\n // Unhandled promise rejection handler\n window.addEventListener('unhandledrejection', (event) => {\n this.handleError({\n type: 'unhandled',\n message: event.reason?.message || 'Unhandled Promise Rejection',\n error: event.reason,\n promise: true\n });\n });\n\n // Network error tracking\n if (this.config.enableNetworkTracking) {\n this.setupNetworkTracking();\n }\n\n // Console capture\n if (this.config.enableConsoleCapture) {\n this.setupConsoleCapture();\n }\n\n // Navigation breadcrumbs\n this.setupNavigationTracking();\n\n // Click breadcrumbs\n this.setupClickTracking();\n\n console.log('[AInamika Error Tracker] Initialized successfully');\n }\n\n private generateSessionId(): string {\n return `session_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;\n }\n\n private addBreadcrumb(breadcrumb: Omit<ErrorBreadcrumb, 'timestamp'>) {\n this.breadcrumbs.push({\n ...breadcrumb,\n timestamp: Date.now()\n });\n\n // Keep only last 50 breadcrumbs\n if (this.breadcrumbs.length > 50) {\n this.breadcrumbs = this.breadcrumbs.slice(-50);\n }\n }\n\n private handleError(errorInfo: any) {\n if (this.errorCount >= this.config.maxErrorsPerSession!) {\n console.warn('[AInamika Error Tracker] Max errors per session reached');\n return;\n }\n\n const errorKey = `${errorInfo.message}_${errorInfo.filename}_${errorInfo.line}`;\n const now = Date.now();\n \n // Debounce duplicate errors\n if (this.errorDebounceMap.has(errorKey)) {\n const lastTime = this.errorDebounceMap.get(errorKey)!;\n if (now - lastTime < this.config.debounceMs!) {\n return;\n }\n }\n this.errorDebounceMap.set(errorKey, now);\n\n this.errorCount++;\n this.captureError(errorInfo);\n }\n\n private async captureError(errorInfo: any) {\n try {\n const errorData: ErrorData = {\n client_id: this.config.clientId,\n error_type: errorInfo.type || 'javascript',\n message: errorInfo.message || 'Unknown error',\n stack_trace: this.extractStackTrace(errorInfo.error),\n url: window.location.href,\n user_agent: navigator.userAgent,\n timestamp: Date.now(),\n error_metadata: {\n line: errorInfo.line,\n column: errorInfo.column,\n filename: errorInfo.filename,\n userId: this.userId,\n sessionId: this.sessionId,\n breadcrumbs: [...this.breadcrumbs],\n networkInfo: this.getNetworkInfo(),\n performance: this.getPerformanceInfo()\n },\n severity: this.assessSeverity(errorInfo),\n session_id: this.sessionId,\n user_id: this.userId\n };\n\n // Capture DOM snapshot\n if (this.config.captureDomSnapshots) {\n errorData.dom_snapshot = this.captureDomSnapshot();\n }\n\n // Capture screenshot\n if (this.config.captureScreenshots) {\n errorData.screen_snapshot = await this.captureScreenshot();\n }\n\n // Send error to backend\n await this.sendError(errorData);\n\n // Add error breadcrumb\n this.addBreadcrumb({\n type: 'error',\n message: `${errorData.error_type}: ${errorData.message}`,\n data: { severity: errorData.severity }\n });\n\n } catch (captureError) {\n console.error('[AInamika Error Tracker] Failed to capture error:', captureError);\n }\n }\n\n private extractStackTrace(error: Error): string {\n if (!error || !error.stack) return '';\n \n const stack = error.stack.split('\\n');\n const maxDepth = this.config.maxStackTraceDepth!;\n \n return stack.slice(0, maxDepth).join('\\n');\n }\n\n private assessSeverity(errorInfo: any): 'low' | 'medium' | 'high' | 'critical' {\n const message = errorInfo.message?.toLowerCase() || '';\n \n // Critical errors\n if (message.includes('out of memory') || \n message.includes('security') ||\n message.includes('permission denied') ||\n errorInfo.type === 'unhandled') {\n return 'critical';\n }\n \n // High severity\n if (message.includes('network') || \n message.includes('timeout') ||\n message.includes('failed to fetch') ||\n message.includes('cors')) {\n return 'high';\n }\n \n // Medium severity\n if (message.includes('undefined') || \n message.includes('null') ||\n message.includes('cannot read property')) {\n return 'medium';\n }\n \n return 'low';\n }\n\n private captureDomSnapshot(): string {\n try {\n // Create a simplified DOM snapshot\n const snapshot = {\n url: window.location.href,\n title: document.title,\n viewport: {\n width: window.innerWidth,\n height: window.innerHeight\n },\n elements: this.extractDomElements()\n };\n \n return JSON.stringify(snapshot);\n } catch (error) {\n console.error('[AInamika Error Tracker] Failed to capture DOM snapshot:', error);\n return '';\n }\n }\n\n private extractDomElements(): any[] {\n const elements: any[] = [];\n const maxElements = 100;\n \n // Get key elements\n const selectors = [\n 'body > *',\n '[id]',\n '[class*=\"error\"]',\n '[class*=\"modal\"]',\n 'form',\n 'button',\n 'input[type=\"submit\"]'\n ];\n \n selectors.forEach(selector => {\n try {\n const els = document.querySelectorAll(selector);\n Array.from(els).slice(0, maxElements - elements.length).forEach(el => {\n elements.push({\n tagName: el.tagName,\n id: el.id,\n className: el.className,\n textContent: el.textContent?.substring(0, 100),\n attributes: this.getElementAttributes(el)\n });\n });\n } catch (e) {\n // Ignore selector errors\n }\n });\n \n return elements;\n }\n\n private getElementAttributes(element: Element): Record<string, string> {\n const attrs: Record<string, string> = {};\n const importantAttrs = ['id', 'class', 'type', 'name', 'value', 'href', 'src'];\n \n importantAttrs.forEach(attr => {\n const value = element.getAttribute(attr);\n if (value) attrs[attr] = value;\n });\n \n return attrs;\n }\n\n private async captureScreenshot(): Promise<string> {\n try {\n // Use html2canvas if available, otherwise return empty\n if (typeof (window as any).html2canvas === 'function') {\n const canvas = await (window as any).html2canvas(document.body, {\n height: Math.min(window.innerHeight, 1000),\n width: Math.min(window.innerWidth, 1000),\n useCORS: true\n });\n return canvas.toDataURL('image/jpeg', 0.7);\n }\n return '';\n } catch (error) {\n console.error('[AInamika Error Tracker] Failed to capture screenshot:', error);\n return '';\n }\n }\n\n private getNetworkInfo(): NetworkInfo {\n const connection = (navigator as any).connection || \n (navigator as any).mozConnection || \n (navigator as any).webkitConnection;\n \n if (!connection) return {};\n \n return {\n effectiveType: connection.effectiveType,\n downlink: connection.downlink,\n rtt: connection.rtt,\n saveData: connection.saveData\n };\n }\n\n private getPerformanceInfo(): PerformanceInfo {\n const info: PerformanceInfo = {};\n \n // Memory info\n if ((performance as any).memory) {\n info.memory = {\n usedJSHeapSize: (performance as any).memory.usedJSHeapSize,\n totalJSHeapSize: (performance as any).memory.totalJSHeapSize,\n jsHeapSizeLimit: (performance as any).memory.jsHeapSizeLimit\n };\n }\n \n // Timing info\n if (performance.timing) {\n const timing = performance.timing;\n info.timing = {\n domContentLoaded: timing.domContentLoadedEventEnd - timing.navigationStart,\n load: timing.loadEventEnd - timing.navigationStart\n };\n \n // Paint timings\n if (performance.getEntriesByType) {\n const paintEntries = performance.getEntriesByType('paint');\n paintEntries.forEach((entry: any) => {\n if (entry.name === 'first-paint') {\n info.timing!.firstPaint = entry.startTime;\n } else if (entry.name === 'first-contentful-paint') {\n info.timing!.firstContentfulPaint = entry.startTime;\n }\n });\n }\n }\n \n return info;\n }\n\n private setupNetworkTracking() {\n // Override fetch\n const originalFetch = window.fetch;\n window.fetch = async (...args) => {\n const startTime = Date.now();\n const url = args[0] instanceof Request ? args[0].url : String(args[0]);\n \n try {\n const response = await originalFetch(...args);\n \n this.addBreadcrumb({\n type: 'network',\n message: `Fetch ${response.status} ${url}`,\n data: {\n url,\n status: response.status,\n duration: Date.now() - startTime\n }\n });\n \n if (!response.ok) {\n this.handleError({\n type: 'network',\n message: `Network request failed: ${response.status} ${response.statusText}`,\n url,\n status: response.status\n });\n }\n \n return response;\n } catch (error: any) {\n this.addBreadcrumb({\n type: 'network',\n message: `Fetch failed ${url}`,\n data: { url, error: error?.message || 'Unknown error' }\n });\n \n this.handleError({\n type: 'network',\n message: `Network request failed: ${error?.message || 'Unknown error'}`,\n url,\n error\n });\n \n throw error;\n }\n };\n\n // Override XMLHttpRequest\n const originalXHROpen = XMLHttpRequest.prototype.open;\n const originalXHRSend = XMLHttpRequest.prototype.send;\n \n XMLHttpRequest.prototype.open = function(method: string, url: string | URL, async?: boolean, username?: string | null, password?: string | null) {\n (this as any)._errorTracker = { method, url, startTime: Date.now() };\n return originalXHROpen.call(this, method, url, async || true, username, password);\n };\n \n XMLHttpRequest.prototype.send = function(...args) {\n const tracker = (this as any)._errorTracker;\n \n this.addEventListener('loadend', () => {\n if (tracker) {\n const duration = Date.now() - tracker.startTime;\n \n if (this.status >= 400) {\n this.dispatchEvent(new CustomEvent('networkerror', {\n detail: {\n type: 'network',\n message: `XHR request failed: ${this.status} ${this.statusText}`,\n url: tracker.url,\n status: this.status\n }\n }));\n }\n \n this.dispatchEvent(new CustomEvent('networkbreadcrumb', {\n detail: {\n type: 'network',\n message: `XHR ${this.status} ${tracker.url}`,\n data: {\n method: tracker.method,\n url: tracker.url,\n status: this.status,\n duration\n }\n }\n }));\n }\n });\n \n return originalXHRSend.call(this, ...args);\n };\n \n // Listen for custom events\n document.addEventListener('networkerror', (event: any) => {\n this.handleError(event.detail);\n });\n \n document.addEventListener('networkbreadcrumb', (event: any) => {\n this.addBreadcrumb(event.detail);\n });\n }\n\n private setupConsoleCapture() {\n // Override console methods\n ['error', 'warn'].forEach(method => {\n const original = this.originalConsole[method as keyof Console] as Function;\n (console as any)[method] = (...args: any[]) => {\n if (typeof original === 'function') {\n original.call(console, ...args);\n }\n \n if (method === 'error') {\n this.handleError({\n type: 'console',\n message: args.map(arg => String(arg)).join(' '),\n consoleMethod: method\n });\n }\n \n this.addBreadcrumb({\n type: 'console',\n message: `Console ${method}: ${args.map(arg => String(arg)).join(' ')}`,\n data: { level: method }\n });\n };\n });\n }\n\n private setupNavigationTracking() {\n // Track page changes\n let currentUrl = window.location.href;\n \n const trackNavigation = () => {\n const newUrl = window.location.href;\n if (newUrl !== currentUrl) {\n this.addBreadcrumb({\n type: 'navigation',\n message: `Navigation from ${currentUrl} to ${newUrl}`,\n data: { from: currentUrl, to: newUrl }\n });\n currentUrl = newUrl;\n }\n };\n \n // Listen for various navigation events\n window.addEventListener('popstate', trackNavigation);\n window.addEventListener('hashchange', trackNavigation);\n \n // Override pushState and replaceState\n const originalPushState = history.pushState;\n const originalReplaceState = history.replaceState;\n \n history.pushState = function(...args) {\n originalPushState.apply(this, args);\n setTimeout(trackNavigation, 0);\n };\n \n history.replaceState = function(...args) {\n originalReplaceState.apply(this, args);\n setTimeout(trackNavigation, 0);\n };\n }\n\n private setupClickTracking() {\n document.addEventListener('click', (event) => {\n const target = event.target as Element;\n if (!target) return;\n \n const selector = this.getElementSelector(target);\n const text = target.textContent?.trim().substring(0, 50) || '';\n \n this.addBreadcrumb({\n type: 'click',\n message: `Clicked ${selector}${text ? `: ${text}` : ''}`,\n data: {\n selector,\n text,\n tagName: target.tagName,\n id: target.id,\n className: target.className\n }\n });\n });\n }\n\n private getElementSelector(element: Element): string {\n if (element.id) return `#${element.id}`;\n if (element.className) {\n const classes = element.className.split(' ').filter(c => c).slice(0, 2);\n if (classes.length) return `.${classes.join('.')}`;\n }\n return element.tagName.toLowerCase();\n }\n\n private async sendError(errorData: ErrorData) {\n try {\n const response = await fetch(`${this.config.endpoint}/api/v1/errors`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${this.config.apiKey}`\n },\n body: JSON.stringify(errorData)\n });\n\n if (!response.ok) {\n throw new Error(`Failed to send error: ${response.status} ${response.statusText}`);\n }\n\n console.log('[AInamika Error Tracker] Error sent successfully');\n } catch (error) {\n console.error('[AInamika Error Tracker] Failed to send error:', error);\n // Store error locally for retry\n this.storeErrorLocally(errorData);\n }\n }\n\n private storeErrorLocally(errorData: ErrorData) {\n try {\n const stored = localStorage.getItem('ainamika_errors') || '[]';\n const errors = JSON.parse(stored);\n errors.push(errorData);\n \n // Keep only last 50 errors\n if (errors.length > 50) {\n errors.splice(0, errors.length - 50);\n }\n \n localStorage.setItem('ainamika_errors', JSON.stringify(errors));\n } catch (error) {\n console.error('[AInamika Error Tracker] Failed to store error locally:', error);\n }\n }\n\n // Public methods\n public captureException(error: Error, context?: Record<string, any>) {\n this.handleError({\n type: 'custom',\n message: error.message,\n error,\n context\n });\n }\n\n public setUser(userId: string) {\n this.userId = userId;\n }\n\n public addTag(key: string, value: string) {\n // Add custom tags to error metadata\n if (!this.config.clientId) {\n this.config.clientId += `_${key}:${value}`;\n }\n }\n\n public async flushStoredErrors() {\n try {\n const stored = localStorage.getItem('ainamika_errors');\n if (!stored) return;\n \n const errors = JSON.parse(stored);\n if (errors.length === 0) return;\n \n console.log(`[AInamika Error Tracker] Flushing ${errors.length} stored errors`);\n \n for (const error of errors) {\n await this.sendError(error);\n }\n \n localStorage.removeItem('ainamika_errors');\n } catch (error) {\n console.error('[AInamika Error Tracker] Failed to flush stored errors:', error);\n }\n }\n}\n","// config.ts - Environment-based configuration for Ainamika SDK\n\nexport interface EnvironmentConfig {\n API_BASE_URL: string;\n APP_ENV: 'development' | 'production';\n DEBUG: boolean;\n}\n\n// Environment configuration with fallbacks\ndeclare global {\n interface Window {\n __AINAMIKA_CONFIG__?: EnvironmentConfig;\n }\n}\n\n// Get environment configuration\nfunction getEnvironmentConfig(): EnvironmentConfig {\n // Check for explicitly set configuration\n if (typeof window !== 'undefined' && window.__AINAMIKA_CONFIG__) {\n return window.__AINAMIKA_CONFIG__;\n }\n\n // Default configuration based on hostname\n const isLocal = typeof window !== 'undefined' && \n (window.location.hostname === 'localhost' || window.location.hostname === '127.0.0.1');\n \n return {\n API_BASE_URL: isLocal ? 'http://localhost:5000' : 'https://ainamika-backend-768143418383.europe-west1.run.app',\n APP_ENV: isLocal ? 'development' : 'production',\n DEBUG: isLocal\n };\n}\n\nexport const ENV_CONFIG = getEnvironmentConfig();\n\n// API endpoint configuration\nexport const API_ENDPOINTS = {\n EVENTS: `${ENV_CONFIG.API_BASE_URL}/api/v1/events`,\n ERRORS: `${ENV_CONFIG.API_BASE_URL}/api/errors/report`,\n CONFIG: `${ENV_CONFIG.API_BASE_URL}/api/v1/sdk/config`,\n DEBUG_EVENTS: `${ENV_CONFIG.API_BASE_URL}/api/v1/debug/events`\n};\n\n// Configuration helper function\nexport function configureSDK(config: Partial<EnvironmentConfig>) {\n if (typeof window !== 'undefined') {\n window.__AINAMIKA_CONFIG__ = { ...ENV_CONFIG, ...config };\n }\n}\n\n// Log configuration for debugging\nif (ENV_CONFIG.DEBUG) {\n console.log('[Ainamika SDK] Environment Configuration:', {\n API_BASE_URL: ENV_CONFIG.API_BASE_URL,\n APP_ENV: ENV_CONFIG.APP_ENV,\n DEBUG: ENV_CONFIG.DEBUG,\n ENDPOINTS: API_ENDPOINTS\n });\n}","// error-storage.ts - Offline Storage and Queue Management for Error Tracking\nimport { API_ENDPOINTS } from './config';\n\nexport interface StoredError {\n id: string;\n errorData: any;\n timestamp: number;\n retryCount: number;\n lastRetry?: number;\n}\n\nexport interface StorageConfig {\n maxStorageSize: number;\n maxRetries: number;\n retryInterval: number;\n compressionEnabled: boolean;\n encryptionEnabled: boolean;\n}\n\nexport class ErrorStorage {\n private config: StorageConfig;\n private readonly STORAGE_KEY = 'ainamika_error_queue';\n private readonly METADATA_KEY = 'ainamika_error_metadata';\n private retryTimer?: number;\n private isProcessing = false;\n\n constructor(config: Partial<StorageConfig> = {}) {\n this.config = {\n maxStorageSize: 5 * 1024 * 1024, // 5MB\n maxRetries: 5,\n retryInterval: 30000, // 30 seconds\n compressionEnabled: true,\n encryptionEnabled: false,\n ...config\n };\n\n this.initialize();\n }\n\n private initialize() {\n this.cleanupOldErrors();\n this.startRetryTimer();\n this.setupStorageListener();\n \n // Process any existing errors on initialization\n setTimeout(() => this.processQueue(), 1000);\n }\n\n /**\n * Store error data with automatic compression and queue management\n */\n public async storeError(errorData: any): Promise<string> {\n try {\n const errorId = this.generateErrorId();\n const storedError: StoredError = {\n id: errorId,\n errorData: this.config.compressionEnabled ? this.compressData(errorData) : errorData,\n timestamp: Date.now(),\n retryCount: 0\n };\n\n await this.addToQueue(storedError);\n this.updateMetadata();\n \n // Trigger immediate processing\n setTimeout(() => this.processQueue(), 100);\n \n return errorId;\n } catch (error) {\n console.error('[AInamika Error Storage] Failed to store error:', error);\n throw error;\n }\n }\n\n /**\n * Get all stored errors\n */\n public getStoredErrors(): StoredError[] {\n try {\n const stored = localStorage.getItem(this.STORAGE_KEY);\n if (!stored) return [];\n \n const errors = JSON.parse(stored) as StoredError[];\n return errors.map(error => ({\n ...error,\n errorData: this.config.compressionEnabled ? this.decompressData(error.errorData) : error.errorData\n }));\n } catch (error) {\n console.error('[AInamika Error Storage] Failed to get stored errors:', error);\n return [];\n }\n }\n\n /**\n * Remove error from storage\n */\n public removeError(errorId: string): boolean {\n try {\n const errors = this.getQueueRaw();\n const filteredErrors = errors.filter(error => error.id !== errorId);\n \n if (filteredErrors.length !== errors.length) {\n localStorage.setItem(this.STORAGE_KEY, JSON.stringify(filteredErrors));\n this.updateMetadata();\n return true;\n }\n return false;\n } catch (error) {\n console.error('[AInamika Error Storage] Failed to remove error:', error);\n return false;\n }\n }\n\n /**\n * Clear all stored errors\n */\n public clearAll(): void {\n try {\n localStorage.removeItem(this.STORAGE_KEY);\n localStorage.removeItem(this.METADATA_KEY);\n console.log('[AInamika Error Storage] All errors cleared');\n } catch (error) {\n console.error('[AInamika Error Storage] Failed to clear errors:', error);\n }\n }\n\n /**\n * Get storage statistics\n */\n public getStorageStats(): {\n errorCount: number;\n totalSize: number;\n oldestError?: number;\n newestError?: number;\n } {\n try {\n const errors = this.getQueueRaw();\n const totalSize = new Blob([localStorage.getItem(this.STORAGE_KEY) || '']).size;\n \n const timestamps = errors.map(e => e.timestamp).sort();\n \n return {\n errorCount: errors.length,\n totalSize,\n oldestError: timestamps[0],\n newestError: timestamps[timestamps.length - 1]\n };\n } catch (error) {\n console.error('[AInamika Error Storage] Failed to get storage stats:', error);\n return { errorCount: 0, totalSize: 0 };\n }\n }\n\n /**\n * Process the error queue - attempt to send stored errors\n */\n public async processQueue(): Promise<void> {\n if (this.isProcessing) return;\n \n this.isProcessing = true;\n \n try {\n const errors = this.getQueueRaw();\n if (errors.length === 0) return;\n \n console.log(`[AInamika Error Storage] Processing ${errors.length} queued errors`);\n \n for (const storedError of errors) {\n if (storedError.retryCount >= this.config.maxRetries) {\n console.warn(`[AInamika Error Storage] Max retries reached for error ${storedError.id}`);\n this.removeError(storedError.id);\n continue;\n }\n\n // Check retry interval\n if (storedError.lastRetry && \n Date.now() - storedError.lastRetry < this.config.retryInterval) {\n continue;\n }\n\n try {\n const success = await this.sendError(storedError);\n if (success) {\n this.removeError(storedError.id);\n console.log(`[AInamika Error Storage] Successfully sent error ${storedError.id}`);\n } else {\n this.incrementRetryCount(storedError.id);\n }\n } catch (error) {\n console.error(`[AInamika Error Storage] Failed to send error ${storedError.id}:`, error);\n this.incrementRetryCount(storedError.id);\n }\n }\n } finally {\n this.isProcessing = false;\n }\n }\n\n /**\n * Force retry of a specific error\n */\n public async retryError(errorId: string): Promise<boolean> {\n const errors = this.getQueueRaw();\n const error = errors.find(e => e.id === errorId);\n \n if (!error) return false;\n \n try {\n const success = await this.sendError(error);\n if (success) {\n this.removeError(errorId);\n return true;\n } else {\n this.incrementRetryCount(errorId);\n return false;\n }\n } catch (err) {\n console.error(`[AInamika Error Storage] Failed to retry error ${errorId}:`, err);\n this.incrementRetryCount(errorId);\n return false;\n }\n }\n\n private async addToQueue(storedError: StoredError): Promise<void> {\n const errors = this.getQueueRaw();\n errors.push(storedError);\n \n // Check storage size limit\n const serialized = JSON.stringify(errors);\n if (new Blob([serialized]).size > this.config.maxStorageSize) {\n // Remove oldest errors until under limit\n while (errors.length > 0 && new Blob([JSON.stringify(errors)]).size > this.config.maxStorageSize) {\n errors.shift();\n console.warn('[AInamika Error Storage] Removed old error due to size limit');\n }\n }\n \n localStorage.setItem(this.STORAGE_KEY, JSON.stringify(errors));\n }\n\n private getQueueRaw(): StoredError[] {\n try {\n const stored = localStorage.getItem(this.STORAGE_KEY);\n return stored ? JSON.parse(stored) : [];\n } catch (error) {\n console.error('[AInamika Error Storage] Failed to parse stored errors:', error);\n return [];\n }\n }\n\n private incrementRetryCount(errorId: string): void {\n try {\n const errors = this.getQueueRaw();\n const errorIndex = errors.findIndex(e => e.id === errorId);\n \n if (errorIndex !== -1) {\n errors[errorIndex].retryCount++;\n errors[errorIndex].lastRetry = Date.now();\n localStorage.setItem(this.STORAGE_KEY, JSON.stringify(errors));\n }\n } catch (error) {\n console.error('[AInamika Error Storage] Failed to increment retry count:', error);\n }\n }\n\n private async sendError(storedError: StoredError): Promise<boolean> {\n try {\n const errorData = this.config.compressionEnabled ? \n this.decompressData(storedError.errorData) : \n storedError.errorData;\n\n // This should match the ErrorTracker's endpoint configuration\n const endpoint = errorData.endpoint || API_ENDPOINTS.ERRORS;\n const apiKey = errorData.apiKey || '';\n \n const response = await fetch(`${endpoint}/api/v1/errors`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': apiKey ? `Bearer ${apiKey}` : ''\n },\n body: JSON.stringify(errorData)\n });\n\n return response.ok;\n } catch (error) {\n console.error('[AInamika Error Storage] Network error sending stored error:', error);\n return false;\n }\n }\n\n private compressData(data: any): string {\n try {\n // Simple compression using JSON + base64\n const jsonString = JSON.stringify(data);\n return btoa(jsonString);\n } catch (error) {\n console.warn('[AInamika Error Storage] Compression failed, storing uncompressed:', error);\n return data;\n }\n }\n\n private decompressData(compressedData: any): any {\n try {\n if (typeof compressedData === 'string' && compressedData.length > 0) {\n const jsonString = atob(compressedData);\n return JSON.parse(jsonString);\n }\n return compressedData;\n } catch (error) {\n console.warn('[AInamika Error Storage] Decompression failed, returning raw data:', error);\n return compressedData;\n }\n }\n\n private generateErrorId(): string {\n return `error_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;\n }\n\n private cleanupOldErrors(): void {\n try {\n const errors = this.getQueueRaw();\n const cutoffTime = Date.now() - (7 * 24 * 60 * 60 * 1000); // 7 days\n \n const cleanErrors = errors.filter(error => error.timestamp > cutoffTime);\n \n if (cleanErrors.length !== errors.length) {\n localStorage.setItem(this.STORAGE_KEY, JSON.stringify(cleanErrors));\n console.log(`[AInamika Error Storage] Cleaned up ${errors.length - cleanErrors.length} old errors`);\n }\n } catch (error) {\n console.error('[AInamika Error Storage] Failed to cleanup old errors:', error);\n }\n }\n\n private startRetryTimer(): void {\n this.retryTimer = window.setInterval(() => {\n this.processQueue();\n }, this.config.retryInterval);\n }\n\n private setupStorageListener(): void {\n // Listen for storage changes from other tabs\n window.addEventListener('storage', (event) => {\n if (event.key === this.STORAGE_KEY) {\n console.log('[AInamika Error Storage] Storage updated from another tab');\n setTimeout(() => this.processQueue(), 1000);\n }\n });\n\n // Listen for online/offline events\n window.addEventListener('online', () => {\n console.log('[AInamika Error Storage] Network back online, processing queue');\n setTimeout(() => this.processQueue(), 1000);\n });\n\n window.addEventListener('offline', () => {\n console.log('[AInamika Error Storage] Network offline, errors will be queued');\n });\n }\n\n private updateMetadata(): void {\n try {\n const stats = this.getStorageStats();\n const metadata = {\n lastUpdate: Date.now(),\n ...stats\n };\n localStorage.setItem(this.METADATA_KEY, JSON.stringify(metadata));\n } catch (error) {\n console.error('[AInamika Error Storage] Failed to update metadata:', error);\n }\n }\n\n /**\n * Export stored errors for debugging\n */\n public exportErrors(): string {\n try {\n const errors = this.getStoredErrors();\n const exportData = {\n timestamp: Date.now(),\n version: '1.0',\n stats: this.getStorageStats(),\n errors: errors\n };\n return JSON.stringify(exportData, null, 2);\n } catch (error) {\n console.error('[AInamika Error Storage] Failed to export errors:', error);\n return '{}';\n }\n }\n\n /**\n * Import errors from export\n */\n public importErrors(exportData: string): boolean {\n try {\n const data = JSON.parse(exportData);\n if (!data.errors || !Array.isArray(data.errors)) {\n throw new Error('Invalid export format');\n }\n\n this.clearAll();\n \n for (const errorData of data.errors) {\n this.storeError(errorData.errorData);\n }\n \n console.log(`[AInamika Error Storage] Imported ${data.errors.length} errors`);\n return true;\n } catch (error) {\n console.error('[AInamika Error Storage] Failed to import errors:', error);\n return false;\n }\n }\n\n /**\n * Cleanup and destroy the storage instance\n */\n public destroy(): void {\n if (this.retryTimer) {\n clearInterval(this.retryTimer);\n this.retryTimer = undefined;\n }\n \n // Final attempt to process queue\n this.processQueue();\n \n console.log('[AInamika Error Storage] Storage instance destroyed');\n }\n}\n\n/**\n * Utility functions for error storage management\n */\nexport class ErrorStorageUtils {\n /**\n * Get total localStorage usage for AInamika\n */\n static getAinamikaStorageUsage(): { \n totalSize: number; \n errorSize: number; \n otherSize: number; \n } {\n let totalSize = 0;\n let errorSize = 0;\n let otherSize = 0;\n\n for (let key in localStorage) {\n if (localStorage.hasOwnProperty(key)) {\n const size = new Blob([localStorage.getItem(key) || '']).size;\n totalSize += size;\n \n if (key.startsWith('ainamika_error')) {\n errorSize += size;\n } else if (key.startsWith('ainamika_')) {\n otherSize += size;\n }\n }\n }\n\n return { totalSize, errorSize, otherSize };\n }\n\n /**\n * Check if localStorage has enough space\n */\n static checkStorageSpace(requiredBytes: number): boolean {\n try {\n const testKey = 'ainamika_storage_test';\n const testData = 'x'.repeat(Math.min(requiredBytes, 1024 * 1024));\n \n localStorage.setItem(testKey, testData);\n localStorage.removeItem(testKey);\n \n return true;\n } catch (error) {\n return false;\n }\n }\n\n /**\n * Clean up all AInamika storage\n */\n static cleanupAllAinamikaStorage(): void {\n const keysToRemove: string[] = [];\n \n for (let key in localStorage) {\n if (key.startsWith('ainamika_')) {\n keysToRemove.push(key);\n }\n }\n \n keysToRemove.forEach(key => localStorage.removeItem(key));\n console.log(`[AInamika Storage Utils] Cleaned up ${keysToRemove.length} storage keys`);\n }\n\n /**\n * Generate storage report\n */\n static generateStorageReport(): {\n usage: ReturnType<typeof ErrorStorageUtils.getAinamikaStorageUsage>;\n errors: any[];\n metadata: any;\n } {\n const storage = new ErrorStorage();\n \n return {\n usage: ErrorStorageUtils.getAinamikaStorageUsage(),\n errors: storage.getStoredErrors(),\n metadata: storage.getStorageStats()\n };\n }\n}\n","// src/index.ts - Main SDK entry point\nimport { ErrorTracker, ErrorConfig } from './error-tracker';\nimport { ErrorStorage } from './error-storage';\nimport { ENV_CONFIG, API_ENDPOINTS } from './config';\n\ninterface AnalyticsConfig {\n apiKey: string;\n endpoint?: string;\n autoConfig?: boolean;\n batchInterval?: number;\n useWebWorker?: boolean;\n workerPath?: string;\n debug?: boolean;\n clientId: string; // Optional client ID for user tracking\n apiDetails?: {\n apiEndPoint: string;\n headers?: Record<string, string>;\n };\n workerConfig?: {\n batchSize?: number;\n batchInterval?: number;\n };\n errorTracking?: {\n enabled?: boolean;\n captureScreenshots?: boolean;\n captureDomSnapshots?: boolean;\n maxStackTraceDepth?: number;\n maxErrorsPerSession?: number;\n debounceMs?: number;\n enableNetworkTracking?: boolean;\n enableConsoleCapture?: boolean;\n };\n}\n\ninterface EventData {\n event: string;\n properties?: Record<string, any>;\n timestamp?: number;\n userId?: string;\n sessionId?: string;\n}\n\ninterface AutoConfigResult {\n autoTrack: {\n clicks: string[];\n pageViews: boolean;\n formSubmissions: string[];\n customEvents: Record<string, any>;\n };\n metadata: {\n appType: string;\n framework: string;\n confidence: number;\n };\n}\n\nclass AInamikaSDKPro {\n private config: AnalyticsConfig;\n private worker: Worker;\n private sessionId: string;\n private autoConfig?: AutoConfigResult;\n private batchTimer?: number;\n private eventQueue: Map<string, any>[] = [];\n private isInitialized = false;\n private batchRetryCount: number = 0;\n private maxBatchRetries: number = 5;\n\n // --- Error Tracking Components ---\n private errorTracker?: ErrorTracker;\n private errorStorage?: ErrorStorage;\n\n // --- Dynamic DOM Fingerprinting and Smart Debouncing ---\n private domHashCache: Record<string, any> = {};\n private lastDomHash: string = '';\n private lastConfigHash: string = '';\n private mutationDebounceTimer: number | null = null;\n private mutationDebounceMs: number = 2000; // 2s debounce for dynamic DOM\n\n // Track attached event types per element to prevent duplicate listeners\n private attachedListeners: WeakMap<Element, Set<string>> = new WeakMap();\n\n constructor(config: AnalyticsConfig) {\n this.config = {\n endpoint: ENV_CONFIG.API_BASE_URL,\n batchInterval: 5000,\n useWebWorker: true,\n debug: ENV_CONFIG.DEBUG,\n errorTracking: {\n enabled: true,\n captureScreenshots: true,\n captureDomSnapshots: true,\n maxStackTraceDepth: 50,\n maxErrorsPerSession: 100,\n debounceMs: 1000,\n enableNetworkTracking: true,\n enableConsoleCapture: true\n },\n ...config\n };\n\n this.sessionId = this.generateSessionId();\n // Inline the worker code as a Blob to avoid cross-origin issues\n const workerCode = `\n self.eventQueue = [];\n self.config = {\n apiUrl: '',\n batchSize: 10,\n batchInterval: 5000,\n headers: { 'Content-Type': 'application/json' }\n };\n let batchTimer = null;\n function flushQueue() {\n self.postMessage({ status: 'debug', message: '[AInamika Worker] flushQueue called', eventQueue: self.eventQueue, config: self.config });\n if (self.eventQueue.length === 0) return;\n const batch = self.eventQueue.splice(0, self.config.batchSize);\n fetch(self.config.apiUrl, {\n method: 'POST',\n headers: self.config.headers,\n body: JSON.stringify({ events: batch })\n }).then(r => {\n if (r.ok) {\n self.postMessage({ status: 'success' });\n } else {\n self.postMessage({ status: 'error', error: r.statusText, failedEvents: batch });\n }\n }).catch(e => {\n self.postMessage({ status: 'error', error: e.message, failedEvents: batch });\n });\n }\n self.onmessage = function(e) {\n self.postMessage({ status: 'debug', message: '[AInamika Worker] onmessage', data: e.data });\n if (e.data.type === 'config') {\n self.config = { ...self.config, ...e.data.payload };\n if (batchTimer) clearInterval(batchTimer);\n batchTimer = setInterval(flushQueue, self.config.batchInterval);\n self.postMessage({ status: 'debug', message: '[AInamika Worker] config set', config: self.config });\n } else if (e.data.type === 'track') {\n self.eventQueue.push(e.data.payload);\n // Only send when timer triggers, not when batch size is reached\n // This ensures true batching behavior\n } else if (e.data.type === 'batch') {\n // Handle batch flush from main thread\n self.postMessage({ status: 'debug', message: '[AInamika Worker] Received batch from main thread', events: e.data.events });\n self.eventQueue.push(...e.data.events);\n flushQueue();\n } else if (e.data.type === 'initConfig') {\n // No-op for now, can be used for advanced config\n }\n };\n `;\n const blob = new Blob([workerCode], { type: 'application/javascript' });\n const workerUrl = URL.createObjectURL(blob);\n this.worker = new Worker(workerUrl);\n this.initialize();\n }\n\n private async initialize() {\n if (this.isInitialized) return;\n this.isInitialized = true;\n\n // Initialize Error Tracking\n if (this.config.errorTracking?.enabled) {\n this.initializeErrorTracking();\n }\n\n if (this.config.autoConfig) {\n await this.setupAutoConfiguration();\n }\n\n // Always enable dynamic DOM tracking for dynamic apps\n this.setupDynamicDomTracking();\n\n if (this.config.useWebWorker && typeof Worker !== 'undefined') {\n this.setupWebWorker();\n } else {\n // Fallback for environments without web workers\n this.startBatchTimer();\n }\n this.log('AnalyticsPro SDK initialized', { config: this.config });\n }\n\n // --- Error Tracking Initialization ---\n private initializeErrorTracking() {\n try {\n // Initialize error storage\n this.errorStorage = new ErrorStorage({\n maxStorageSize: 5 * 1024 * 1024, // 5MB\n maxRetries: 5,\n retryInterval: 30000, // 30 seconds\n compressionEnabled: true,\n encryptionEnabled: false\n });\n\n // Initialize error tracker\n const errorConfig: ErrorConfig = {\n endpoint: ENV_CONFIG.API_BASE_URL,\n clientId: this.config.clientId,\n apiKey: this.config.apiKey,\n captureScreenshots: this.config.errorTracking?.captureScreenshots ?? true,\n captureDomSnapshots: this.config.errorTracking?.captureDomSnapshots ?? true,\n maxStackTraceDepth: this.config.errorTracking?.maxStackTraceDepth ?? 50,\n maxErrorsPerSession: this.config.errorTracking?.maxErrorsPerSession ?? 100,\n debounceMs: this.config.errorTracking?.debounceMs ?? 1000,\n enableNetworkTracking: this.config.errorTracking?.enableNetworkTracking ?? true,\n enableConsoleCapture: this.config.errorTracking?.enableConsoleCapture ?? true\n };\n\n this.errorTracker = new ErrorTracker(errorConfig);\n \n // Set user for error tracking if available\n const userId = this.getUserId();\n if (userId && this.errorTracker) {\n this.errorTracker.setUser(userId);\n }\n\n this.log('Error tracking initialized successfully');\n } catch (error) {\n console.error('[AInamika SDK] Failed to initialize error tracking:', error);\n }\n }\n\n // Public method to capture custom exceptions\n public captureException(error: Error, context?: Record<string, any>) {\n if (this.errorTracker) {\n this.errorTracker.captureException(error, context);\n }\n }\n\n // Public method to set user for error tracking\n public setUser(userId: string) {\n if (this.errorTracker) {\n this.errorTracker.setUser(userId);\n }\n }\n\n // Public method to flush stored errors\n public async flushStoredErrors() {\n if (this.errorStorage) {\n await this.errorStorage.processQueue();\n }\n if (this.errorTracker) {\n await this.errorTracker.flushStoredErrors();\n }\n }\n\n private async setupAutoConfiguration() {\n try {\n this.log('Starting auto-configuration...');\n // Compute current DOM structure and hash\n const domStructure = await this.getDOMStructure();\n const domHash = this.computeDomHash(domStructure);\n this.lastDomHash = domHash; // Store the initial DOM hash\n \n // Try to load config from localStorage cache first using DOM hash\n let generatedConfig = this.getCachedConfigForDomHash(domHash);\n \n if (generatedConfig) {\n this.log('Loaded analytics config from localStorage cache for DOM hash:', domHash);\n } else {\n // Try to load config from file as fallback\n generatedConfig = await this.loadConfigFromFile();\n if (generatedConfig) {\n this.log('Loaded analytics config from file');\n }\n }\n \n if (!generatedConfig) {\n // Only call API if not found in cache or file, and include DOM hash\n this.log('No cached config found, fetching from backend for DOM hash:', domHash);\n generatedConfig = await this.fetchGeneratedConfig(domStructure, domHash);\n if (generatedConfig && generatedConfig.events_to_track) {\n this.saveConfigToFile(generatedConfig);\n this.setCachedConfigForDomHash(domHash, generatedConfig);\n this.lastConfigHash = generatedConfig.config_hash || '';\n }\n }\n \n if (generatedConfig && generatedConfig.events_to_track) {\n this.applyGeneratedConfig(generatedConfig);\n // Send config to worker for advanced tracking (scroll, focus, etc.)\n if (this.config.useWebWorker && typeof Worker !== 'undefined') {\n this.worker.postMessage({ type: 'initConfig', config: generatedConfig });\n }\n this.log('Auto-configuration applied successfully', generatedConfig);\n } else {\n this.log('Auto-configuration failed: Invalid config received from backend.', generatedConfig);\n }\n } catch (error) {\n this.log('Auto-configuration failed with error', error);\n }\n }\n\n private async getDOMStructure(): Promise<any> {\n const getSelector = (el: Element): string => {\n if (el.id) return `#${el.id}`;\n if (el.className) {\n const classes = el.className.split(' ').filter(c => c.trim()).join('.');\n return classes ? `.${classes}` : el.tagName.toLowerCase();\n }\n return el.tagName.toLowerCase();\n };\n\n // Wait a bit for any dynamic content to load\n await new Promise(resolve => setTimeout(resolve, 500));\n\n // Comprehensive selector for all interactive and important elements\n const elements = Array.from(document.body.querySelectorAll(`\n button, a, input, select, textarea, form, img, h1, h2, h3, h4, h5, h6,\n [role=button], [role=link], [onclick], [tabindex], [data-analytics], [data-track],\n .card, .btn, .btn-primary, .btn-secondary, .card-title, .card-description, .card-price, .card-actions,\n [id*=\"card\"], [class*=\"card\"], [class*=\"btn\"], [class*=\"price\"], [class*=\"title\"],\n div, span, p\n `));\n\n // Filter and enhance elements with more comprehensive logic\n const filteredElements = elements.filter(el => {\n const style = window.getComputedStyle(el);\n const isVisible = style.display !== 'none' && style.visibility !== 'hidden' && style.opacity !== '0';\n const hasInteraction = el.tagName.toLowerCase() === 'button' || \n el.tagName.toLowerCase() === 'a' || \n el.hasAttribute('onclick') ||\n el.getAttribute('role') === 'button' ||\n el.classList.contains('btn') ||\n el.classList.contains('card');\n const isImportantElement = el.id === 'cardsContainer' || \n el.classList.contains('cards-grid') ||\n el.classList.contains('card') ||\n el.tagName.toLowerCase() === 'img' ||\n ['h1', 'h2', 'h3'].indexOf(el.tagName.toLowerCase()) !== -1;\n \n return (isVisible && (hasInteraction || isImportantElement)) || el.id === 'cardsContainer';\n });\n\n // Deduplicate and add stable metadata (exclude dynamic properties)\n const seen = new Set<string>();\n const structure = filteredElements.map(el => {\n // Only include stable attributes that don't change between page loads\n const stableAttributes: Record<string, string> = {};\n Array.from(el.attributes).forEach(attr => {\n // Exclude dynamic attributes that might change\n if (['style', 'data-timestamp', 'data-rendered'].indexOf(attr.name) === -1) {\n stableAttributes[attr.name] = attr.value;\n }\n });\n \n const obj = {\n tagName: el.tagName.toLowerCase(),\n selector: getSelector(el),\n id: el.id || '',\n className: el.className || '',\n textContent: (el.textContent || '').trim().substring(0, 100),\n attributes: stableAttributes,\n // Remove position and computed styles as they can vary\n isInteractive: el.tagName.toLowerCase() === 'button' || \n el.tagName.toLowerCase() === 'a' || \n el.hasAttribute('onclick') ||\n el.getAttribute('role') === 'button' ||\n el.classList.contains('btn'),\n hasChildren: el.children.length > 0,\n childCount: el.children.length,\n // Add stable structural information\n parentTagName: el.parentElement?.tagName.toLowerCase() || '',\n index: Array.from(el.parentElement?.children || []).indexOf(el)\n };\n return obj;\n }).filter(obj => {\n const key = obj.tagName + '|' + obj.selector + '|' + obj.textContent.substring(0, 20);\n if (seen.has(key)) return false;\n seen.add(key);\n return true;\n });\n\n this.log('DOM structure analyzed', { elementCount: structure.length, elements: structure });\n return { elements: structure };\n }\n\n private async fetchGeneratedConfig(structure: any, domHash?: string): Promise<any> {\n try {\n if(structure && structure.elements && structure.elements.length === 0) {\n this.log('No elements found in DOM structure, skipping config fetch.');\n return null;\n }\n \n const requestBody: any = { structure };\n if (domHash) {\n requestBody.domHash = domHash;\n requestBody.lastConfigHash = this.lastConfigHash;\n }\n \n const response = await fetch(API_ENDPOINTS.CONFIG, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify(requestBody),\n });\n\n if (!response.ok) {\n throw new Error(`Backend returned ${response.status}`);\n }\n return await response.json();\n } catch (error) {\n this.log('Error fetching generated config:', error);\n return null;\n }\n }\n\n private applyGeneratedConfig(config: { events_to_track: any[], observe_mutations?: boolean }) {\n config.events_to_track.forEach(eventToTrack => {\n try {\n const elements = document.querySelectorAll(eventToTrack.element_selector);\n if (elements.length > 0) {\n elements.forEach(element => {\n // Prevent multiple listeners for the same event type on the same element\n let eventSet = this.attachedListeners.get(element);\n if (!eventSet) {\n eventSet = new Set();\n this.attachedListeners.set(element, eventSet);\n }\n \n // Handle array of event types\n const eventTypes = Array.isArray(eventToTrack.event_type) ? eventToTrack.event_type : [eventToTrack.event_type];\n \n eventTypes.forEach((eventType: string) => {\n if (eventSet.has(eventType)) return;\n eventSet.add(eventType);\n \n // Click events\n if (eventType === 'click') {\n element.addEventListener('click', (event: Event) => {\n // Don't prevent default for this demo, let buttons work normally\n const target = event.target as HTMLElement;\n const elementData = this.extractElementData(target);\n \n this.sendToWorker(eventToTrack.event_name, {\n selector: eventToTrack.element_selector,\n eventType: 'click',\n element: elementData,\n timestamp: new Date().toISOString()\n });\n });\n this.log(`Attached click listener for \"${eventToTrack.event_name}\" on \"${eventToTrack.element_selector}\"`);\n }\n \n // View events using IntersectionObserver\n if (eventType === 'view') {\n if ('IntersectionObserver' in window) {\n const observer = new IntersectionObserver((entries) => {\n entries.forEach(entry => {\n if (entry.isIntersecting) {\n const target = entry.target as HTMLElement;\n const elementData = this.extractElementData(target);\n \n this.sendToWorker(eventToTrack.event_name, {\n selector: eventToTrack.element_selector,\n eventType: 'view',\n element: elementData,\n intersectionRatio: entry.intersectionRatio,\n timestamp: new Date().toISOString()\n });\n }\n });\n }, { threshold: [0.1, 0.5, 1.0] });\n observer.observe(element);\n this.log(`Attached IntersectionObserver for \"${eventToTrack.event_name}\" on \"${eventToTrack.element_selector}\"`);\n }\n }\n \n // Focus/blur tracking\n if (eventType === 'focus' || eventType === 'blur') {\n element.addEventListener(eventType, () => {\n const target = element as HTMLElement;\n const elementData = this.extractElementData(target);\n \n this.sendToWorker(eventToTrack.event_name, {\n selector: eventToTrack.element_selector,\n eventType: eventType,\n element: elementData,\n timestamp: new Date().toISOString()\n });\n });\n this.log(`Attached ${eventType} listener for \"${eventToTrack.event_name}\" on \"${eventToTrack.element_selector}\"`);\n }\n });\n });\n } else {\n this.log(`No elements found for selector: \"${eventToTrack.element_selector}\"`);\n }\n } catch (e) {\n this.log(`Error applying selector \"${eventToTrack.element_selector}\":`, e);\n }\n });\n\n // MutationObserver for DOM changes (if requested by config)\n if (config.observe_mutations) {\n if ('MutationObserver' in window) {\n const observer = new MutationObserver((mutations) => {\n mutations.forEach(mutation => {\n this.sendToWorker('dom_mutation', {\n type: mutation.type,\n target: (mutation.target as HTMLElement).outerHTML,\n timestamp: new Date().toISOString()\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n this.log('MutationObserver attached for DOM changes');\n }\n }\n }\n\n private extractElementData(element: HTMLElement): any {\n const rect = element.getBoundingClientRect();\n return {\n tagName: element.tagName.toLowerCase(),\n id: element.id || '',\n className: element.className || '',\n textContent: (element.textContent || '').trim().substring(0, 100),\n attributes: Array.from(element.attributes).reduce((acc, attr) => {\n acc[attr.name] = attr.value;\n return acc;\n }, {} as Record<string, string>),\n position: {\n x: Math.round(rect.x),\n y: Math.round(rect.y),\n width: Math.round(rect.width),\n height: Math.round(rect.height)\n },\n href: (element as HTMLAnchorElement).href || undefined,\n value: (element as HTMLInputElement).value || undefined\n };\n }\n\n // Helper to send events to worker for batching\n private sendToWorker(eventName: string, properties: Record<string, any>) {\n const eventData: any = {\n event: eventName,\n properties,\n timestamp: Date.now(),\n userId: this.getUserId(),\n sessionId: this.sessionId,\n client_id: this.config.clientId || 'demo-client-001' // Ensure client_id is always present\n };\n if (this.config.useWebWorker && typeof Worker !== 'undefined') {\n this.worker.postMessage({ type: 'track', payload: eventData });\n } else {\n this.eventQueue.push(eventData);\n }\n this.log('Event tracked:', eventData);\n }\n\n private setupWebWorker() {\n // Pass worker config to the worker\n this.worker.postMessage({\n type: 'config',\n payload: {\n apiUrl: this.config.apiDetails?.apiEndPoint || `${this.config.endpoint}/api/v1/events`,\n batchSize: this.config.workerConfig?.batchSize || 10,\n batchInterval: this.config.workerConfig?.batchInterval || 5000,\n headers: this.config.apiDetails?.headers || { 'Content-Type': 'application/json' },\n }\n });\n this.worker.onmessage = (event) => {\n if (event.data.status === 'success') {\n this.log('Batch sent successfully by worker');\n // Don't re-queue failed events since we already cleared the queue\n } else if (event.data.status === 'debug') {\n this.log(event.data.message, event.data);\n } else if (event.data.status === 'error') {\n this.log('Worker failed to send batch', event.data.error);\n // Re-queue failed events only if we have them\n if (event.data.failedEvents && event.data.failedEvents.length > 0) {\n this.eventQueue.unshift(...event.data.failedEvents);\n }\n }\n };\n this.log('Web worker setup complete.');\n }\n\n public track(eventName: string, properties: Record<string, any> = {}) {\n const eventData: any = {\n event: eventName,\n properties,\n timestamp: Date.now(),\n userId: this.getUserId(),\n sessionId: this.sessionId,\n client_id: this.config.clientId || 'demo-client-001' // Ensure client_id is always present\n };\n\n // Use the same batching logic as sendToWorker\n if (this.config.useWebWorker && typeof Worker !== 'undefined') {\n this.worker.postMessage({ type: 'track', payload: eventData });\n } else {\n this.eventQueue.push(eventData);\n }\n this.log('Event tracked public:', eventData);\n }\n\n private startBatchTimer() {\n this.batchTimer = window.setInterval(() => {\n this.flushQueue();\n }, this.config.batchInterval);\n }\n\n private async flushQueue() {\n if (this.eventQueue.length === 0) {\n return;\n }\n\n const batch = [...this.eventQueue];\n // Clear the queue immediately to prevent duplicates\n this.eventQueue = [];\n\n if (this.config.useWebWorker && typeof Worker !== 'undefined') {\n this.worker.postMessage({\n type: 'batch',\n events: batch,\n endpoint: `${this.config.endpoint}/api/v1/events`,\n });\n } else {\n // Fallback send mechanism with retry logic\n await this.sendBatchWithRetry(batch);\n }\n }\n\n private async sendBatchWithRetry(batch: Map<string, any>[]) {\n if (this.batchRetryCount >= this.maxBatchRetries) {\n if (this.batchTimer) {\n clearInterval(this.batchTimer);\n this.batchTimer = undefined;\n this.log('Max batch retries reached. BatchTimer cancelled.');\n }\n return;\n }\n try {\n await this.sendBatch(batch);\n // On success, reset retry count (queue already cleared in flushQueue)\n this.batchRetryCount = 0;\n } catch (error) {\n this.batchRetryCount++;\n this.log(`Batch send failed. Retry attempt ${this.batchRetryCount} of ${this.maxBatchRetries}.`, error);\n // Re-queue the failed batch for retry\n this.eventQueue.unshift(...batch);\n if (this.batchRetryCount >= this.maxBatchRetries) {\n if (this.batchTimer) {\n clearInterval(this.batchTimer);\n this.batchTimer = undefined;\n this.log('Max batch retries reached. BatchTimer cancelled.');\n }\n }\n }\n }\n\n // Update sendBatch to support client db endpoint and headers\n private async sendBatch(batch: Map<string, any>[]) {\n let endpoint = `${this.config.endpoint}/api/v1/events`;\n let headers: Record<string, string> = { 'Content-Type': 'application/json' };\n if (this.config.apiDetails && this.config.apiDetails.apiEndPoint) {\n endpoint = this.config.apiDetails.apiEndPoint;\n if (this.config.apiDetails.headers) {\n headers = { ...headers, ...this.config.apiDetails.headers };\n }\n }\n // Transform batch to required format\n const clientId = this.config.clientId || 'f01a232e-eacc-4c2e-8a06-f1c522cb8201';\n const events = batch.map((e: any) => ({\n event: e.event, // keep 'event' key\n userId: e.userId,\n client_id: clientId,\n timestamp: new Date(e.timestamp).toISOString(),\n ...(e.properties || {})\n }));\n try {\n const response = await fetch(endpoint, {\n method: 'POST',\n headers,\n body: JSON.stringify({ events }),\n });\n if (!response.ok) {\n throw new Error(`Failed to send batch: ${response.status}`);\n }\n this.log('Batch sent successfully:', events);\n } catch (error) {\n this.log('Error sending batch:', error);\n throw error; // Let sendBatchWithRetry handle re-queuing\n }\n }\n\n private generateSessionId(): string {\n // Simple session ID generator (could be improved)\n return 'sess_' + Math.random().toString(36).substr(2, 9);\n }\n\n private getUserId(): string {\n // Placeholder for user ID logic (e.g., from cookies, localStorage, or auth context)\n return 'user_' + Math.random().toString(36).substr(2, 9);\n }\n\n private log(message: string, data?: any) {\n if (this.config.debug) {\n console.log(`[AnalyticsPro SDK] ${message}`, data || '');\n }\n }\n\n // Save config as a downloadable JSON file\nprivate saveConfigToFile(config: any) {\n if(!this.config.debug){\n return;\n }\n // const fileName = 'AInamika_config.json';\n // const json = JSON.stringify(config, null, 2);\n // const blob = new Blob([json], { type: 'application/json' });\n // const link = document.createElement('a');\n // link.href = URL.createObjectURL(blob);\n // link.download = fileName;\n // document.body.appendChild(link);\n // link.click();\n // document.body.removeChild(link);\n}\n\n// Load config from /AInamika_config.json in the project root\nprivate async loadConfigFromFile(): Promise<any | null> {\n try {\n const response = await fetch('/AInamika_config.json', { cache: 'reload' });\n if (!response.ok) {\n return null;\n }\n const config = await response.json();\n return config;\n } catch (err) {\n return null;\n }\n}\n\n// --- Dynamic DOM Fingerprinting and Smart Debouncing ---\nprivate async setupDynamicDomTracking() {\n // Use MutationObserver to watch for DOM changes\n if ('MutationObserver' in window) {\n const observer = new MutationObserver(() => {\n if (this.mutationDebounceTimer) {\n clearTimeout(this.mutationDebounceTimer);\n }\n this.mutationDebounceTimer = window.setTimeout(() => {\n this.handleDomMutation();\n }, this.mutationDebounceMs);\n });\n observer.observe(document.body, { childList: true, subtree: true, attributes: true });\n this.log('Dynamic DOM MutationObserver attached');\n }\n}\n\nprivate computeDomHash(structure: any): string {\n // Simple hash: JSON.stringify, then a basic hash (FNV-1a or similar)\n const str = JSON.stringify(structure);\n let hash = 2166136261;\n for (let i = 0; i < str.length; i++) {\n hash ^= str.charCodeAt(i);\n hash += (hash << 1) + (hash << 4) + (hash << 7) + (hash << 8) + (hash << 24);\n }\n return (hash >>> 0).toString(16);\n}\n\nprivate getCachedConfigForDomHash(domHash: string): any | null {\n try {\n const cache = JSON.parse(localStorage.getItem('ainamika_dom_config_cache') || '{}');\n return cache[domHash] || null;\n } catch {\n return null;\n }\n}\n\nprivate setCachedConfigForDomHash(domHash: string, config: any) {\n try {\n const cache = JSON.parse(localStorage.getItem('ainamika_dom_config_cache') || '{}');\n cache[domHash] = config;\n localStorage.setItem('ainamika_dom_config_cache', JSON.stringify(cache));\n } catch {}\n}\n\nprivate async handleDomMutation() {\n const domStructure = await this.getDOMStructure();\n const domHash = this.computeDomHash(domStructure);\n \n if (domHash === this.lastDomHash) {\n this.log('DOM hash unchanged after mutation, skipping config fetch.');\n return;\n }\n \n this.log('DOM hash changed, checking for cached config...', { oldHash: this.lastDomHash, newHash: domHash });\n this.lastDomHash = domHash;\n \n const cachedConfig = this.getCachedConfigForDomHash(domHash);\n if (cachedConfig) {\n this.log('Reusing cached config for DOM hash', domHash);\n this.applyGeneratedConfig(cachedConfig);\n return;\n }\n \n // Send to server: domStructure with domHash and lastConfigHash\n this.log('Fetching new config from backend for DOM hash:', domHash);\n const config = await this.fetchGeneratedConfig(domStructure, domHash);\n if (config && config.events_to_track) {\n this.applyGeneratedConfig(config);\n this.setCachedConfigForDomHash(domHash, config);\n this.lastConfigHash = config.config_hash || '';\n this.log('Fetched and applied new config for new DOM hash', domHash);\n } else {\n this.log('No valid config returned for new DOM hash', domHash);\n }\n}\n}\n\n// Make AnalyticsProSDK available globally for both classic and module scripts\nif (typeof window !== 'undefined') {\n (window as any).AInamikaSDKPro = AInamikaSDKPro;\n}\n\nexport default AInamikaSDKPro;\nexport { AInamikaSDKPro };"],"names":["root","factory","exports","module","define","amd","self","window","global","this","__webpack_require__","definition","key","o","Object","defineProperty","enumerable","get","obj","prop","prototype","hasOwnProperty","call","config","breadcrumbs","errorCount","errorDebounceMap","Map","captureScreenshots","captureDomSnapshots","maxStackTraceDepth","maxErrorsPerSession","debounceMs","enableNetworkTracking","enableConsoleCapture","sessionId","generateSessionId","originalConsole","console","initialize","addEventListener","event","handleError","type","message","filename","line","lineno","column","colno","error","reason","promise","setupNetworkTracking","setupConsoleCapture","setupNavigationTracking","setupClickTracking","log","Date","now","Math","random","toString","substr","addBreadcrumb","breadcrumb","push","timestamp","length","slice","errorInfo","warn","errorKey","has","set","captureError","errorData","client_id","clientId","error_type","stack_trace","extractStackTrace","url","location","href","user_agent","navigator","userAgent","error_metadata","userId","networkInfo","getNetworkInfo","performance","getPerformanceInfo","severity","assessSeverity","session_id","user_id","dom_snapshot","captureDomSnapshot","captureScreenshot","screen_snapshot","sendError","data","stack","split","maxDepth","join","toLowerCase","includes","snapshot","title","document","viewport","width","innerWidth","height","innerHeight","elements","extractDomElements","JSON","stringify","forEach","selector","els","querySelectorAll","Array","from","el","tagName","id","className","textContent","substring","attributes","getElementAttributes","e","element","attrs","attr","value","getAttribute","html2canvas","body","min","useCORS","toDataURL","connection","mozConnection","webkitConnection","effectiveType","downlink","rtt","saveData","info","memory","usedJSHeapSize","totalJSHeapSize","jsHeapSizeLimit","timing","domContentLoaded","domContentLoadedEventEnd","navigationStart","load","loadEventEnd","getEntriesByType","entry","name","firstPaint","startTime","firstContentfulPaint","originalFetch","fetch","args","Request","String","response","status","duration","ok","statusText","originalXHROpen","XMLHttpRequest","open","originalXHRSend","send","method","async","username","password","_errorTracker","tracker","dispatchEvent","CustomEvent","detail","original","map","arg","consoleMethod","level","currentUrl","trackNavigation","newUrl","to","originalPushState","history","pushState","originalReplaceState","replaceState","apply","setTimeout","target","getElementSelector","text","trim","classes","filter","c","endpoint","headers","apiKey","Error","storeErrorLocally","stored","localStorage","getItem","errors","parse","splice","setItem","captureException","context","setUser","addTag","flushStoredErrors","removeItem","ENV_CONFIG","__AINAMIKA_CONFIG__","isLocal","hostname","API_BASE_URL","APP_ENV","DEBUG","getEnvironmentConfig","API_ENDPOINTS","EVENTS","ERRORS","CONFIG","DEBUG_EVENTS","ENDPOINTS","STORAGE_KEY","METADATA_KEY","isProcessing","maxStorageSize","maxRetries","retryInterval","compressionEnabled","encryptionEnabled","cleanupOldErrors","startRetryTimer","setupStorageListener","processQueue","storeError","errorId","generateErrorId","storedError","compressData","retryCount","addToQueue","updateMetadata","getStoredErrors","decompressData","removeError","getQueueRaw","filteredErrors","clearAll","getStorageStats","totalSize","Blob","size","timestamps","sort","oldestError","newestError","lastRetry","incrementRetryCount","retryError","find","serialized","shift","errorIndex","findIndex","jsonString","btoa","compressedData","atob","cleanErrors","retryTimer","setInterval","stats","metadata","lastUpdate","exportErrors","exportData","version","importErrors","isArray","destroy","clearInterval","undefined","getAinamikaStorageUsage","errorSize","otherSize","startsWith","checkStorageSpace","requiredBytes","testKey","testData","repeat","cleanupAllAinamikaStorage","keysToRemove","generateStorageReport","storage","ErrorStorage","usage","ErrorStorageUtils","eventQueue","isInitialized","batchRetryCount","maxBatchRetries","domHashCache","lastDomHash","lastConfigHash","mutationDebounceTimer","mutationDebounceMs","attachedListeners","WeakMap","batchInterval","useWebWorker","debug","errorTracking","enabled","blob","workerUrl","URL","createObjectURL","worker","Worker","initializeErrorTracking","autoConfig","setupAutoConfiguration","setupDynamicDomTracking","setupWebWorker","startBatchTimer","errorStorage","errorConfig","errorTracker","ErrorTracker","getUserId","getDOMStructure","domStructure","domHash","computeDomHash","generatedConfig","getCachedConfigForDomHash","loadConfigFromFile","fetchGeneratedConfig","events_to_track","saveConfigToFile","setCachedConfigForDomHash","config_hash","applyGeneratedConfig","postMessage","getSelector","Promise","resolve","filteredElements","style","getComputedStyle","isVisible","display","visibility","opacity","hasInteraction","hasAttribute","classList","contains","isImportantElement","indexOf","seen","Set","structure","stableAttributes","isInteractive","hasChildren","children","childCount","parentTagName","parentElement","index","add","elementCount","requestBody","json","eventToTrack","element_selector","eventSet","event_type","eventType","elementData","extractElementData","sendToWorker","event_name","toISOString","IntersectionObserver","entries","isIntersecting","intersectionRatio","threshold","observe","observe_mutations","MutationObserver","mutations","mutation","outerHTML","childList","subtree","rect","getBoundingClientRect","reduce","acc","position","x","round","y","eventName","properties","eventData","payload","apiUrl","apiDetails","apiEndPoint","batchSize","workerConfig","onmessage","failedEvents","unshift","track","batchTimer","flushQueue","batch","events","sendBatchWithRetry","sendBatch","cache","clearTimeout","handleDomMutation","str","hash","i","charCodeAt","oldHash","newHash","cachedConfig","AInamikaSDKPro"],"sourceRoot":""}
|
|
1
|
+
{"version":3,"file":"ainamika-sdk.js","mappings":"CAAA,SAA2CA,EAAMC,GAC1B,iBAAZC,SAA0C,iBAAXC,OACxCA,OAAOD,QAAUD,IACQ,mBAAXG,QAAyBA,OAAOC,IAC9CD,OAAO,GAAIH,GACe,iBAAZC,QACdA,QAAwB,eAAID,IAE5BD,EAAqB,eAAIC,GAC1B,CATD,CASoB,oBAATK,KAAuBA,KAAyB,oBAAXC,OAAyBA,OAA2B,oBAAXC,OAAyBA,OAASC,KAAO,WAClI,O,wBCTA,IAAIC,EAAsB,CCA1BA,EAAwB,SAASR,EAASS,GACzC,IAAI,IAAIC,KAAOD,EACXD,EAAoBG,EAAEF,EAAYC,KAASF,EAAoBG,EAAEX,EAASU,IAC5EE,OAAOC,eAAeb,EAASU,EAAK,CAAEI,YAAY,EAAMC,IAAKN,EAAWC,IAG3E,ECPAF,EAAwB,SAASQ,EAAKC,GAAQ,OAAOL,OAAOM,UAAUC,eAAeC,KAAKJ,EAAKC,EAAO,G,w2DCuEtG,aASE,WAAYI,GAPJ,KAAAC,YAAiC,GACjC,KAAAC,WAAa,EACb,KAAAC,iBAAmB,IAAIC,IAM7BlB,KAAKc,OAAS,EAAH,CACTK,oBAAoB,EACpBC,qBAAqB,EACrBC,mBAAoB,GACpBC,oBAAqB,IACrBC,WAAY,IACZC,uBAAuB,EACvBC,sBAAsB,GACnBX,GAGLd,KAAK0B,UAAY1B,KAAK2B,oBACtB3B,KAAK4B,gBAAkB,EAAH,GAAQC,SAC5B7B,KAAK8B,YACP,CAqkBF,OAnkBU,YAAAA,WAAR,sBAEEhC,OAAOiC,iBAAiB,QAAS,SAACC,GAChC,EAAKC,YAAY,CACfC,KAAM,aACNC,QAASH,EAAMG,QACfC,SAAUJ,EAAMI,SAChBC,KAAML,EAAMM,OACZC,OAAQP,EAAMQ,MACdC,MAAOT,EAAMS,OAEjB,GAGA3C,OAAOiC,iBAAiB,qBAAsB,SAACC,G,MAC7C,EAAKC,YAAY,CACfC,KAAM,YACNC,SAAqB,QAAZ,EAAAH,EAAMU,cAAM,eAAEP,UAAW,8BAClCM,MAAOT,EAAMU,OACbC,SAAS,GAEb,GAGI3C,KAAKc,OAAOU,uBACdxB,KAAK4C,uBAIH5C,KAAKc,OAAOW,sBACdzB,KAAK6C,sBAIP7C,KAAK8C,0BAGL9C,KAAK+C,qBAELlB,QAAQmB,IAAI,oDACd,EAEQ,YAAArB,kBAAR,WACE,MAAO,kBAAWsB,KAAKC,MAAK,YAAIC,KAAKC,SAASC,SAAS,IAAIC,OAAO,EAAG,GACvE,EAEQ,YAAAC,cAAR,SAAsBC,GACpBxD,KAAKe,YAAY0C,KAAK,EAAD,KAChBD,GAAU,CACbE,UAAWT,KAAKC,SAIdlD,KAAKe,YAAY4C,OAAS,KAC5B3D,KAAKe,YAAcf,KAAKe,YAAY6C,OAAO,IAE/C,EAEQ,YAAA3B,YAAR,SAAoB4B,GAClB,GAAI7D,KAAKgB,YAAchB,KAAKc,OAAOQ,oBACjCO,QAAQiC,KAAK,+DADf,CAKA,IAAMC,EAAW,UAAGF,EAAU1B,QAAO,YAAI0B,EAAUzB,SAAQ,YAAIyB,EAAUxB,MACnEa,EAAMD,KAAKC,MAGjB,GAAIlD,KAAKiB,iBAAiB+C,IAAID,IAExBb,EADalD,KAAKiB,iBAAiBT,IAAIuD,GACtB/D,KAAKc,OAAOS,WAC/B,OAGJvB,KAAKiB,iBAAiBgD,IAAIF,EAAUb,GAEpClD,KAAKgB,aACLhB,KAAKkE,aAAaL,EAflB,CAgBF,EAEc,YAAAK,aAAd,SAA2BL,G,+HAEjBM,EAAuB,CAC3BC,UAAWpE,KAAKc,OAAOuD,SACvBC,WAAYT,EAAU3B,MAAQ,aAC9BC,QAAS0B,EAAU1B,SAAW,gBAC9BoC,YAAavE,KAAKwE,kBAAkBX,EAAUpB,OAC9CgC,IAAK3E,OAAO4E,SAASC,KACrBC,WAAYC,UAAUC,UACtBpB,UAAWT,KAAKC,MAChB6B,eAAgB,CACd1C,KAAMwB,EAAUxB,KAChBE,OAAQsB,EAAUtB,OAClBH,SAAUyB,EAAUzB,SACpB4C,OAAQhF,KAAKgF,OACbtD,UAAW1B,KAAK0B,UAChBX,YAAa,EAAF,GAAMf,KAAKe,aAAW,GACjCkE,YAAajF,KAAKkF,iBAClBC,YAAanF,KAAKoF,sBAEpBC,SAAUrF,KAAKsF,eAAezB,GAC9B0B,WAAYvF,KAAK0B,UACjB8D,QAASxF,KAAKgF,QAIZhF,KAAKc,OAAOM,sBACd+C,EAAUsB,aAAezF,KAAK0F,sBAI5B1F,KAAKc,OAAOK,oBACd,EAAAgD,EAA4B,GAAMnE,KAAK2F,sBADrC,M,OACF,EAAUC,gBAAkB,S,iBAI9B,SAAM5F,KAAK6F,UAAU1B,I,cAArB,SAGAnE,KAAKuD,cAAc,CACjBrB,KAAM,QACNC,QAAS,UAAGgC,EAAUG,WAAU,aAAKH,EAAUhC,SAC/C2D,KAAM,CAAET,SAAUlB,EAAUkB,Y,+BAI9BxD,QAAQY,MAAM,oDAAqD,G,6BAI/D,YAAA+B,kBAAR,SAA0B/B,GACxB,IAAKA,IAAUA,EAAMsD,MAAO,MAAO,GAEnC,IAAMA,EAAQtD,EAAMsD,MAAMC,MAAM,MAC1BC,EAAWjG,KAAKc,OAAOO,mBAE7B,OAAO0E,EAAMnC,MAAM,EAAGqC,GAAUC,KAAK,KACvC,EAEQ,YAAAZ,eAAR,SAAuBzB,G,MACf1B,GAA2B,QAAjB,EAAA0B,EAAU1B,eAAO,eAAEgE,gBAAiB,GAGpD,OAAIhE,EAAQiE,SAAS,kBACjBjE,EAAQiE,SAAS,aACjBjE,EAAQiE,SAAS,sBACE,cAAnBvC,EAAU3B,KACL,WAILC,EAAQiE,SAAS,YACjBjE,EAAQiE,SAAS,YACjBjE,EAAQiE,SAAS,oBACjBjE,EAAQiE,SAAS,QACZ,OAILjE,EAAQiE,SAAS,cACjBjE,EAAQiE,SAAS,SACjBjE,EAAQiE,SAAS,wBACZ,SAGF,KACT,EAEQ,YAAAV,mBAAR,WACE,IAEE,IAAMW,EAAW,CACf5B,IAAK3E,OAAO4E,SAASC,KACrB2B,MAAOC,SAASD,MAChBE,SAAU,CACRC,MAAO3G,OAAO4G,WACdC,OAAQ7G,OAAO8G,aAEjBC,SAAU7G,KAAK8G,sBAGjB,OAAOC,KAAKC,UAAUX,EACxB,CAAE,MAAO5D,GAEP,OADAZ,QAAQY,MAAM,2DAA4DA,GACnE,EACT,CACF,EAEQ,YAAAqE,mBAAR,sBACQD,EAAkB,GA+BxB,MA3BkB,CAChB,WACA,OACA,mBACA,mBACA,OACA,SACA,wBAGQI,QAAQ,SAAAC,GAChB,IACE,IAAMC,EAAMZ,SAASa,iBAAiBF,GACtCG,MAAMC,KAAKH,GAAKvD,MAAM,EAhBN,IAgBuBiD,EAASlD,QAAQsD,QAAQ,SAAAM,G,MAC9DV,EAASpD,KAAK,CACZ+D,QAASD,EAAGC,QACZC,GAAIF,EAAGE,GACPC,UAAWH,EAAGG,UACdC,YAA2B,QAAd,EAAAJ,EAAGI,mBAAW,eAAEC,UAAU,EAAG,KAC1CC,WAAY,EAAKC,qBAAqBP,IAE1C,EACF,CAAE,MAAOQ,GAET,CACF,GAEOlB,CACT,EAEQ,YAAAiB,qBAAR,SAA6BE,GAC3B,IAAMC,EAAgC,CAAC,EAQvC,MAPuB,CAAC,KAAM,QAAS,OAAQ,OAAQ,QAAS,OAAQ,OAEzDhB,QAAQ,SAAAiB,GACrB,IAAMC,EAAQH,EAAQI,aAAaF,GAC/BC,IAAOF,EAAMC,GAAQC,EAC3B,GAEOF,CACT,EAEc,YAAAtC,kBAAd,W,2HAG+C,mBAA/B7F,OAAeuI,YAAvB,MACa,GAAOvI,OAAeuI,YAAY9B,SAAS+B,KAAM,CAC9D3B,OAAQxD,KAAKoF,IAAIzI,OAAO8G,YAAa,KACrCH,MAAOtD,KAAKoF,IAAIzI,OAAO4G,WAAY,KACnC8B,SAAS,K,OAEX,MAAO,CAAP,EALe,SAKDC,UAAU,aAAc,K,OAExC,MAAO,CAAP,EAAO,I,OAGP,O,WADA5G,QAAQY,MAAM,yDAA0D,GACjE,CAAP,EAAO,I,uBAIH,YAAAyC,eAAR,WACE,IAAMwD,EAAc7D,UAAkB6D,YACnB7D,UAAkB8D,eAClB9D,UAAkB+D,iBAErC,OAAKF,EAEE,CACLG,cAAeH,EAAWG,cAC1BC,SAAUJ,EAAWI,SACrBC,IAAKL,EAAWK,IAChBC,SAAUN,EAAWM,UANC,CAAC,CAQ3B,EAEQ,YAAA5D,mBAAR,WACE,IAAM6D,EAAwB,CAAC,EAY/B,GATK9D,YAAoB+D,SACvBD,EAAKC,OAAS,CACZC,eAAiBhE,YAAoB+D,OAAOC,eAC5CC,gBAAkBjE,YAAoB+D,OAAOE,gBAC7CC,gBAAkBlE,YAAoB+D,OAAOG,kBAK7ClE,YAAYmE,OAAQ,CACtB,IAAMA,EAASnE,YAAYmE,OAC3BL,EAAKK,OAAS,CACZC,iBAAkBD,EAAOE,yBAA2BF,EAAOG,gBAC3DC,KAAMJ,EAAOK,aAAeL,EAAOG,iBAIjCtE,YAAYyE,kBACOzE,YAAYyE,iBAAiB,SACrC3C,QAAQ,SAAC4C,GACD,gBAAfA,EAAMC,KACRb,EAAKK,OAAQS,WAAaF,EAAMG,UACR,2BAAfH,EAAMC,OACfb,EAAKK,OAAQW,qBAAuBJ,EAAMG,UAE9C,EAEJ,CAEA,OAAOf,CACT,EAEQ,YAAArG,qBAAR,sBAEQsH,EAAgBpK,OAAOqK,MAC7BrK,OAAOqK,MAAQ,W,IAAO,sD,iGACdH,EAAY/G,KAAKC,MACjBuB,EAAM2F,EAAK,aAAcC,QAAUD,EAAK,GAAG3F,IAAM6F,OAAOF,EAAK,I,iBAGhD,O,sBAAA,GAAMF,EAAa,aAAIE,I,OAqBxC,OArBMG,EAAW,SAEjBvK,KAAKuD,cAAc,CACjBrB,KAAM,UACNC,QAAS,gBAASoI,EAASC,OAAM,YAAI/F,GACrCqB,KAAM,CACJrB,IAAG,EACH+F,OAAQD,EAASC,OACjBC,SAAUxH,KAAKC,MAAQ8G,KAItBO,EAASG,IACZ1K,KAAKiC,YAAY,CACfC,KAAM,UACNC,QAAS,kCAA2BoI,EAASC,OAAM,YAAID,EAASI,YAChElG,IAAG,EACH+F,OAAQD,EAASC,SAId,CAAP,EAAOD,G,OAeP,M,WAbAvK,KAAKuD,cAAc,CACjBrB,KAAM,UACNC,QAAS,uBAAgBsC,GACzBqB,KAAM,CAAErB,IAAG,EAAEhC,OAAO,aAAK,EAAL,EAAON,UAAW,mBAGxCnC,KAAKiC,YAAY,CACfC,KAAM,UACNC,QAAS,mCAA2B,aAAK,EAAL,EAAOA,UAAW,iBACtDsC,IAAG,EACHhC,MAAK,IAGD,E,uBAKV,IAAMmI,EAAkBC,eAAelK,UAAUmK,KAC3CC,EAAkBF,eAAelK,UAAUqK,KAEjDH,eAAelK,UAAUmK,KAAO,SAASG,EAAgBxG,EAAmByG,EAAiBC,EAA0BC,GAErH,OADCpL,KAAaqL,cAAgB,CAAEJ,OAAM,EAAExG,IAAG,EAAEuF,UAAW/G,KAAKC,OACtD0H,EAAgB/J,KAAKb,KAAMiL,EAAQxG,EAAKyG,IAAS,EAAMC,EAAUC,EAC1E,EAEAP,eAAelK,UAAUqK,KAAO,W,IAAA,WAAS,kDACvC,IAAMM,EAAWtL,KAAaqL,cAgC9B,OA9BArL,KAAK+B,iBAAiB,UAAW,WAC/B,GAAIuJ,EAAS,CACX,IAAMb,EAAWxH,KAAKC,MAAQoI,EAAQtB,UAElC,EAAKQ,QAAU,KACjB,EAAKe,cAAc,IAAIC,YAAY,eAAgB,CACjDC,OAAQ,CACNvJ,KAAM,UACNC,QAAS,8BAAuB,EAAKqI,OAAM,YAAI,EAAKG,YACpDlG,IAAK6G,EAAQ7G,IACb+F,OAAQ,EAAKA,WAKnB,EAAKe,cAAc,IAAIC,YAAY,oBAAqB,CACtDC,OAAQ,CACNvJ,KAAM,UACNC,QAAS,cAAO,EAAKqI,OAAM,YAAIc,EAAQ7G,KACvCqB,KAAM,CACJmF,OAAQK,EAAQL,OAChBxG,IAAK6G,EAAQ7G,IACb+F,OAAQ,EAAKA,OACbC,SAAQ,MAIhB,CACF,GAEOM,EAAgBlK,KAAI,MAApBkK,EAAe,GAAM/K,MAASoK,GAAI,GAC3C,EAGA7D,SAASxE,iBAAiB,eAAgB,SAACC,GACzC,EAAKC,YAAYD,EAAMyJ,OACzB,GAEAlF,SAASxE,iBAAiB,oBAAqB,SAACC,GAC9C,EAAKuB,cAAcvB,EAAMyJ,OAC3B,EACF,EAEQ,YAAA5I,oBAAR,sBAEE,CAAC,QAAS,QAAQoE,QAAQ,SAAAgE,GACxB,IAAMS,EAAW,EAAK9J,gBAAgBqJ,GACrCpJ,QAAgBoJ,GAAU,W,IAAC,sDACF,mBAAbS,GACTA,EAAS7K,KAAI,MAAb6K,EAAQ,GAAM7J,SAAYuI,GAAI,IAGjB,UAAXa,GACF,EAAKhJ,YAAY,CACfC,KAAM,UACNC,QAASiI,EAAKuB,IAAI,SAAAC,GAAO,OAAAtB,OAAOsB,EAAP,GAAa1F,KAAK,KAC3C2F,cAAeZ,IAInB,EAAK1H,cAAc,CACjBrB,KAAM,UACNC,QAAS,kBAAW8I,EAAM,aAAKb,EAAKuB,IAAI,SAAAC,GAAO,OAAAtB,OAAOsB,EAAP,GAAa1F,KAAK,MACjEJ,KAAM,CAAEgG,MAAOb,IAEnB,CACF,EACF,EAEQ,YAAAnI,wBAAR,sBAEMiJ,EAAajM,OAAO4E,SAASC,KAE3BqH,EAAkB,WACtB,IAAMC,EAASnM,OAAO4E,SAASC,KAC3BsH,IAAWF,IACb,EAAKxI,cAAc,CACjBrB,KAAM,aACNC,QAAS,0BAAmB4J,EAAU,eAAOE,GAC7CnG,KAAM,CAAEwB,KAAMyE,EAAYG,GAAID,KAEhCF,EAAaE,EAEjB,EAGAnM,OAAOiC,iBAAiB,WAAYiK,GACpClM,OAAOiC,iBAAiB,aAAciK,GAGtC,IAAMG,EAAoBC,QAAQC,UAC5BC,EAAuBF,QAAQG,aAErCH,QAAQC,UAAY,W,IAAS,sDAC3BF,EAAkBK,MAAMxM,KAAMoK,GAC9BqC,WAAWT,EAAiB,EAC9B,EAEAI,QAAQG,aAAe,W,IAAS,sDAC9BD,EAAqBE,MAAMxM,KAAMoK,GACjCqC,WAAWT,EAAiB,EAC9B,CACF,EAEQ,YAAAjJ,mBAAR,sBACEwD,SAASxE,iBAAiB,QAAS,SAACC,G,MAC5B0K,EAAS1K,EAAM0K,OACrB,GAAKA,EAAL,CAEA,IAAMxF,EAAW,EAAKyF,mBAAmBD,GACnCE,GAAyB,QAAlB,EAAAF,EAAO/E,mBAAW,eAAEkF,OAAOjF,UAAU,EAAG,MAAO,GAE5D,EAAKrE,cAAc,CACjBrB,KAAM,QACNC,QAAS,kBAAW+E,GAAQ,OAAG0F,EAAO,YAAKA,GAAS,IACpD9G,KAAM,CACJoB,SAAQ,EACR0F,KAAI,EACJpF,QAASkF,EAAOlF,QAChBC,GAAIiF,EAAOjF,GACXC,UAAWgF,EAAOhF,YAbH,CAgBrB,EACF,EAEQ,YAAAiF,mBAAR,SAA2B3E,GACzB,GAAIA,EAAQP,GAAI,MAAO,WAAIO,EAAQP,IACnC,GAAIO,EAAQN,UAAW,CACrB,IAAMoF,EAAU9E,EAAQN,UAAU1B,MAAM,KAAK+G,OAAO,SAAAC,GAAK,OAAAA,CAAA,GAAGpJ,MAAM,EAAG,GACrE,GAAIkJ,EAAQnJ,OAAQ,MAAO,WAAImJ,EAAQ5G,KAAK,KAC9C,CACA,OAAO8B,EAAQR,QAAQrB,aACzB,EAEc,YAAAN,UAAd,SAAwB1B,G,gGAEH,O,sBAAA,GAAMgG,MAAM,UAAGnK,KAAKc,OAAOmM,SAAQ,kBAAkB,CACpEhC,OAAQ,OACRiC,QAAS,CACP,eAAgB,mBAChB,cAAiB,iBAAUlN,KAAKc,OAAOqM,SAEzC7E,KAAMvB,KAAKC,UAAU7C,M,OAGvB,KATMoG,EAAW,UASHG,GACZ,MAAM,IAAI0C,MAAM,gCAAyB7C,EAASC,OAAM,YAAID,EAASI,a,OAGvE9I,QAAQmB,IAAI,oD,+BAEZnB,QAAQY,MAAM,iDAAkD,GAEhEzC,KAAKqN,kBAAkBlJ,G,6BAInB,YAAAkJ,kBAAR,SAA0BlJ,GACxB,IACE,IAAMmJ,EAASC,aAAaC,QAAQ,oBAAsB,KACpDC,EAAS1G,KAAK2G,MAAMJ,GAC1BG,EAAOhK,KAAKU,GAGRsJ,EAAO9J,OAAS,IAClB8J,EAAOE,OAAO,EAAGF,EAAO9J,OAAS,IAGnC4J,aAAaK,QAAQ,kBAAmB7G,KAAKC,UAAUyG,GACzD,CAAE,MAAOhL,GACPZ,QAAQY,MAAM,0DAA2DA,EAC3E,CACF,EAGO,YAAAoL,iBAAP,SAAwBpL,EAAcqL,GACpC9N,KAAKiC,YAAY,CACfC,KAAM,SACNC,QAASM,EAAMN,QACfM,MAAK,EACLqL,QAAO,GAEX,EAEO,YAAAC,QAAP,SAAe/I,GACbhF,KAAKgF,OAASA,CAChB,EAEO,YAAAgJ,OAAP,SAAc7N,EAAagI,GAEpBnI,KAAKc,OAAOuD,WACfrE,KAAKc,OAAOuD,UAAY,WAAIlE,EAAG,YAAIgI,GAEvC,EAEa,YAAA8F,kBAAb,W,wGAGI,G,wBADMX,EAASC,aAAaC,QAAQ,oBACvB,UAGb,GAAsB,KADhBC,EAAS1G,KAAK2G,MAAMJ,IACf3J,OAAc,UAEzB9B,QAAQmB,IAAI,4CAAqCyK,EAAO9J,OAAM,mB,IAE1C,EAAA8J,E,wBAAA,YAAThL,EAAK,KACd,GAAMzC,KAAK6F,UAAUpD,KADG,M,OACxB,S,wBADkB,I,oBAIpB8K,aAAaW,WAAW,mB,+BAExBrM,QAAQY,MAAM,0DAA2D,G,6BAG/E,EA7lBA,GCtCa0L,EAjBb,WAEE,GAAsB,oBAAXrO,QAA0BA,OAAOsO,oBAC1C,OAAOtO,OAAOsO,oBAIhB,IAAMC,EAA4B,oBAAXvO,SACS,cAA7BA,OAAO4E,SAAS4J,UAAyD,cAA7BxO,OAAO4E,SAAS4J,UAE/D,MAAO,CACLC,aAAcF,EAAU,wBAA0B,6DAClDG,QAASH,EAAU,cAAgB,aACnCI,MAAOJ,EAEX,CAE0BK,GAGbC,EAAgB,CAC3BC,OAAQ,UAAGT,EAAWI,aAAY,kBAClCM,OAAQ,UAAGV,EAAWI,aAAY,sBAClCO,OAAQ,UAAGX,EAAWI,aAAY,sBAClCQ,aAAc,UAAGZ,EAAWI,aAAY,yBAWtCJ,EAAWM,OACb5M,QAAQmB,IAAI,4CAA6C,CACvDuL,aAAcJ,EAAWI,aACzBC,QAASL,EAAWK,QACpBC,MAAON,EAAWM,MAClBO,UAAWL,I,2nDCrCf,aAOE,WAAY7N,QAAA,IAAAA,IAAAA,EAAA,IALK,KAAAmO,YAAc,uBACd,KAAAC,aAAe,0BAExB,KAAAC,cAAe,EAGrBnP,KAAKc,OAAS,GACZsO,eAAgB,QAChBC,WAAY,EACZC,cAAe,IACfC,oBAAoB,EACpBC,mBAAmB,GAChB1O,GAGLd,KAAK8B,YACP,CA0YF,OAxYU,YAAAA,WAAR,sBACE9B,KAAKyP,mBACLzP,KAAK0P,kBACL1P,KAAK2P,uBAGLlD,WAAW,WAAM,SAAKmD,cAAL,EAAqB,IACxC,EAKa,YAAAC,WAAb,SAAwB1L,G,yGAUpB,O,sBARM2L,EAAU9P,KAAK+P,kBACfC,EAA2B,CAC/BvI,GAAIqI,EACJ3L,UAAWnE,KAAKc,OAAOyO,mBAAqBvP,KAAKiQ,aAAa9L,GAAaA,EAC3ET,UAAWT,KAAKC,MAChBgN,WAAY,GAGd,GAAMlQ,KAAKmQ,WAAWH,I,OAMtB,OANA,SACAhQ,KAAKoQ,iBAGL3D,WAAW,WAAM,SAAKmD,cAAL,EAAqB,KAE/B,CAAP,EAAOE,G,OAGP,M,WADAjO,QAAQY,MAAM,kDAAmD,GAC3D,E,uBAOH,YAAA4N,gBAAP,sBACE,IACE,IAAM/C,EAASC,aAAaC,QAAQxN,KAAKiP,aACzC,OAAK3B,EAEUvG,KAAK2G,MAAMJ,GACZ3B,IAAI,SAAAlJ,GAAS,OAAC,OACvBA,GAAK,CACR0B,UAAW,EAAKrD,OAAOyO,mBAAqB,EAAKe,eAAe7N,EAAM0B,WAAa1B,EAAM0B,WAFhE,GAHP,EAOtB,CAAE,MAAO1B,GAEP,OADAZ,QAAQY,MAAM,wDAAyDA,GAChE,EACT,CACF,EAKO,YAAA8N,YAAP,SAAmBT,GACjB,IACE,IAAMrC,EAASzN,KAAKwQ,cACdC,EAAiBhD,EAAOV,OAAO,SAAAtK,GAAS,OAAAA,EAAMgF,KAAOqI,CAAb,GAE9C,OAAIW,EAAe9M,SAAW8J,EAAO9J,SACnC4J,aAAaK,QAAQ5N,KAAKiP,YAAalI,KAAKC,UAAUyJ,IACtDzQ,KAAKoQ,kBACE,EAGX,CAAE,MAAO3N,GAEP,OADAZ,QAAQY,MAAM,mDAAoDA,IAC3D,CACT,CACF,EAKO,YAAAiO,SAAP,WACE,IACEnD,aAAaW,WAAWlO,KAAKiP,aAC7B1B,aAAaW,WAAWlO,KAAKkP,cAC7BrN,QAAQmB,IAAI,8CACd,CAAE,MAAOP,GACPZ,QAAQY,MAAM,mDAAoDA,EACpE,CACF,EAKO,YAAAkO,gBAAP,WAME,IACE,IAAMlD,EAASzN,KAAKwQ,cACdI,EAAY,IAAIC,KAAK,CAACtD,aAAaC,QAAQxN,KAAKiP,cAAgB,KAAK6B,KAErEC,EAAatD,EAAO9B,IAAI,SAAA5D,GAAK,OAAAA,EAAErE,SAAF,GAAasN,OAEhD,MAAO,CACLhQ,WAAYyM,EAAO9J,OACnBiN,UAAS,EACTK,YAAaF,EAAW,GACxBG,YAAaH,EAAWA,EAAWpN,OAAS,GAEhD,CAAE,MAAOlB,GAEP,OADAZ,QAAQY,MAAM,wDAAyDA,GAChE,CAAEzB,WAAY,EAAG4P,UAAW,EACrC,CACF,EAKa,YAAAhB,aAAb,W,sGACE,GAAI5P,KAAKmP,aAAc,UAEvBnP,KAAKmP,cAAe,E,iBAIlB,G,sBAAsB,KADhB1B,EAASzN,KAAKwQ,eACT7M,OAAc,UAEzB9B,QAAQmB,IAAI,8CAAuCyK,EAAO9J,OAAM,mB,IAEtC,EAAA8J,E,sBAAA,YAAM,YAC9B,IADSuC,EAAW,MACJE,YAAclQ,KAAKc,OAAOuO,WAGxC,OAFAxN,QAAQiC,KAAK,iEAA0DkM,EAAYvI,KACnFzH,KAAKuQ,YAAYP,EAAYvI,IAC7B,MAIF,GAAIuI,EAAYmB,WACZlO,KAAKC,MAAQ8M,EAAYmB,UAAYnR,KAAKc,OAAOwO,cACnD,Y,iBAIgB,O,sBAAA,GAAMtP,KAAK6F,UAAUmK,I,cAArB,UAEdhQ,KAAKuQ,YAAYP,EAAYvI,IAC7B5F,QAAQmB,IAAI,2DAAoDgN,EAAYvI,MAE5EzH,KAAKoR,oBAAoBpB,EAAYvI,I,+BAGvC5F,QAAQY,MAAM,wDAAiDuN,EAAYvI,GAAE,KAAK,GAClFzH,KAAKoR,oBAAoBpB,EAAYvI,I,oBAvBf,I,uCA2B1BzH,KAAKmP,cAAe,E,2BAOX,YAAAkC,WAAb,SAAwBvB,G,kGAItB,GAHMrC,EAASzN,KAAKwQ,gBACd/N,EAAQgL,EAAO6D,KAAK,SAAAvJ,GAAK,OAAAA,EAAEN,KAAOqI,CAAT,IAEnB,MAAO,CAAP,GAAO,G,iBAGD,O,sBAAA,GAAM9P,KAAK6F,UAAUpD,I,OACrC,OADgB,UAEdzC,KAAKuQ,YAAYT,GACV,CAAP,GAAO,KAEP9P,KAAKoR,oBAAoBtB,GAClB,CAAP,GAAO,I,OAKT,O,WAFAjO,QAAQY,MAAM,yDAAkDqN,EAAO,KAAK,GAC5E9P,KAAKoR,oBAAoBtB,GAClB,CAAP,GAAO,G,uBAIG,YAAAK,WAAd,SAAyBH,G,yEAMvB,IALMvC,EAASzN,KAAKwQ,eACb/M,KAAKuM,GAGNuB,EAAaxK,KAAKC,UAAUyG,GAC9B,IAAIoD,KAAK,CAACU,IAAaT,KAAO9Q,KAAKc,OAAOsO,eAE5C,KAAO3B,EAAO9J,OAAS,GAAK,IAAIkN,KAAK,CAAC9J,KAAKC,UAAUyG,KAAUqD,KAAO9Q,KAAKc,OAAOsO,gBAChF3B,EAAO+D,QACP3P,QAAQiC,KAAK,gE,OAIjByJ,aAAaK,QAAQ5N,KAAKiP,YAAalI,KAAKC,UAAUyG,I,SAGhD,YAAA+C,YAAR,WACE,IACE,IAAMlD,EAASC,aAAaC,QAAQxN,KAAKiP,aACzC,OAAO3B,EAASvG,KAAK2G,MAAMJ,GAAU,EACvC,CAAE,MAAO7K,GAEP,OADAZ,QAAQY,MAAM,0DAA2DA,GAClE,EACT,CACF,EAEQ,YAAA2O,oBAAR,SAA4BtB,GAC1B,IACE,IAAMrC,EAASzN,KAAKwQ,cACdiB,EAAahE,EAAOiE,UAAU,SAAA3J,GAAK,OAAAA,EAAEN,KAAOqI,CAAT,IAErB,IAAhB2B,IACFhE,EAAOgE,GAAYvB,aACnBzC,EAAOgE,GAAYN,UAAYlO,KAAKC,MACpCqK,aAAaK,QAAQ5N,KAAKiP,YAAalI,KAAKC,UAAUyG,IAE1D,CAAE,MAAOhL,GACPZ,QAAQY,MAAM,4DAA6DA,EAC7E,CACF,EAEc,YAAAoD,UAAd,SAAwBmK,G,oGAUH,O,sBARX7L,EAAYnE,KAAKc,OAAOyO,mBAC5BvP,KAAKsQ,eAAeN,EAAY7L,WAChC6L,EAAY7L,UAGR8I,EAAW9I,EAAU8I,UAAY0B,EAAcE,OAC/C1B,EAAShJ,EAAUgJ,QAAU,GAElB,GAAMhD,MAAM,UAAG8C,EAAQ,kBAAkB,CACxDhC,OAAQ,OACRiC,QAAS,CACP,eAAgB,mBAChB,cAAiBC,EAAS,iBAAUA,GAAW,IAEjD7E,KAAMvB,KAAKC,UAAU7C,M,OAGvB,MAAO,CAAP,EATiB,SASDuG,I,OAGhB,O,WADA7I,QAAQY,MAAM,+DAAgE,GACvE,CAAP,GAAO,G,uBAIH,YAAAwN,aAAR,SAAqBnK,GACnB,IAEE,IAAM6L,EAAa5K,KAAKC,UAAUlB,GAClC,OAAO8L,KAAKD,EACd,CAAE,MAAOlP,GAEP,OADAZ,QAAQiC,KAAK,qEAAsErB,GAC5EqD,CACT,CACF,EAEQ,YAAAwK,eAAR,SAAuBuB,GACrB,IACE,GAA8B,iBAAnBA,GAA+BA,EAAelO,OAAS,EAAG,CACnE,IAAMgO,EAAaG,KAAKD,GACxB,OAAO9K,KAAK2G,MAAMiE,EACpB,CACA,OAAOE,CACT,CAAE,MAAOpP,GAEP,OADAZ,QAAQiC,KAAK,qEAAsErB,GAC5EoP,CACT,CACF,EAEQ,YAAA9B,gBAAR,WACE,MAAO,gBAAS9M,KAAKC,MAAK,YAAIC,KAAKC,SAASC,SAAS,IAAIC,OAAO,EAAG,GACrE,EAEQ,YAAAmM,iBAAR,WACE,IACE,IAAMhC,EAASzN,KAAKwQ,cACd,EAAavN,KAAKC,MAAQ,OAE1B6O,EAActE,EAAOV,OAAO,SAAAtK,GAAS,OAAAA,EAAMiB,UAAY,CAAlB,GAEvCqO,EAAYpO,SAAW8J,EAAO9J,SAChC4J,aAAaK,QAAQ5N,KAAKiP,YAAalI,KAAKC,UAAU+K,IACtDlQ,QAAQmB,IAAI,8CAAuCyK,EAAO9J,OAASoO,EAAYpO,OAAM,gBAEzF,CAAE,MAAOlB,GACPZ,QAAQY,MAAM,yDAA0DA,EAC1E,CACF,EAEQ,YAAAiN,gBAAR,sBACE1P,KAAKgS,WAAalS,OAAOmS,YAAY,WACnC,EAAKrC,cACP,EAAG5P,KAAKc,OAAOwO,cACjB,EAEQ,YAAAK,qBAAR,sBAEE7P,OAAOiC,iBAAiB,UAAW,SAACC,GAC9BA,EAAM7B,MAAQ,EAAK8O,cACrBpN,QAAQmB,IAAI,6DACZyJ,WAAW,WAAM,SAAKmD,cAAL,EAAqB,KAE1C,GAGA9P,OAAOiC,iBAAiB,SAAU,WAChCF,QAAQmB,IAAI,kEACZyJ,WAAW,WAAM,SAAKmD,cAAL,EAAqB,IACxC,GAEA9P,OAAOiC,iBAAiB,UAAW,WACjCF,QAAQmB,IAAI,kEACd,EACF,EAEQ,YAAAoN,eAAR,WACE,IACE,IAAM8B,EAAQlS,KAAK2Q,kBACbwB,EAAW,GACfC,WAAYnP,KAAKC,OACdgP,GAEL3E,aAAaK,QAAQ5N,KAAKkP,aAAcnI,KAAKC,UAAUmL,GACzD,CAAE,MAAO1P,GACPZ,QAAQY,MAAM,sDAAuDA,EACvE,CACF,EAKO,YAAA4P,aAAP,WACE,IACE,IAAM5E,EAASzN,KAAKqQ,kBACdiC,EAAa,CACjB5O,UAAWT,KAAKC,MAChBqP,QAAS,MACTL,MAAOlS,KAAK2Q,kBACZlD,OAAQA,GAEV,OAAO1G,KAAKC,UAAUsL,EAAY,KAAM,EAC1C,CAAE,MAAO7P,GAEP,OADAZ,QAAQY,MAAM,oDAAqDA,GAC5D,IACT,CACF,EAKO,YAAA+P,aAAP,SAAoBF,GAClB,IACE,IAAMxM,EAAOiB,KAAK2G,MAAM4E,GACxB,IAAKxM,EAAK2H,SAAWpG,MAAMoL,QAAQ3M,EAAK2H,QACtC,MAAM,IAAIL,MAAM,yBAGlBpN,KAAK0Q,WAEL,IAAwB,UAAA5K,EAAK2H,OAAL,eAAa,CAAhC,IAAMtJ,EAAS,KAClBnE,KAAK6P,WAAW1L,EAAUA,UAC5B,CAGA,OADAtC,QAAQmB,IAAI,4CAAqC8C,EAAK2H,OAAO9J,OAAM,aAC5D,CACT,CAAE,MAAOlB,GAEP,OADAZ,QAAQY,MAAM,oDAAqDA,IAC5D,CACT,CACF,EAKO,YAAAiQ,QAAP,WACM1S,KAAKgS,aACPW,cAAc3S,KAAKgS,YACnBhS,KAAKgS,gBAAaY,GAIpB5S,KAAK4P,eAEL/N,QAAQmB,IAAI,sDACd,EACF,EA5ZA,G,GAiaA,wBA8EA,CA1ES,EAAA6P,wBAAP,WAKE,IAAIjC,EAAY,EACZkC,EAAY,EACZC,EAAY,EAEhB,IAAK,IAAI5S,KAAOoN,aACd,GAAIA,aAAa3M,eAAeT,GAAM,CACpC,IAAM2Q,EAAO,IAAID,KAAK,CAACtD,aAAaC,QAAQrN,IAAQ,KAAK2Q,KACzDF,GAAaE,EAET3Q,EAAI6S,WAAW,kBACjBF,GAAahC,EACJ3Q,EAAI6S,WAAW,eACxBD,GAAajC,EAEjB,CAGF,MAAO,CAAEF,UAAS,EAAEkC,UAAS,EAAEC,UAAS,EAC1C,EAKO,EAAAE,kBAAP,SAAyBC,GACvB,IACE,IAAMC,EAAU,wBACVC,EAAW,IAAIC,OAAOlQ,KAAKoF,IAAI2K,EAAe,UAKpD,OAHA3F,aAAaK,QAAQuF,EAASC,GAC9B7F,aAAaW,WAAWiF,IAEjB,CACT,CAAE,MAAO1Q,GACP,OAAO,CACT,CACF,EAKO,EAAA6Q,0BAAP,WACE,IAAMC,EAAyB,GAE/B,IAAK,IAAIpT,KAAOoN,aACVpN,EAAI6S,WAAW,cACjBO,EAAa9P,KAAKtD,GAItBoT,EAAatM,QAAQ,SAAA9G,GAAO,OAAAoN,aAAaW,WAAW/N,EAAxB,GAC5B0B,QAAQmB,IAAI,8CAAuCuQ,EAAa5P,OAAM,iBACxE,EAKO,EAAA6P,sBAAP,WAKE,IAAMC,EAAU,IAAIC,EAEpB,MAAO,CACLC,MAAOC,EAAkBf,0BACzBpF,OAAQgG,EAAQpD,kBAChB8B,SAAUsB,EAAQ9C,kBAEtB,CACF,CA9EA,G,snDC5XA,aAyBE,WAAY7P,GAnBJ,KAAA+S,WAAiC,GACjC,KAAAC,eAAgB,EAChB,KAAAC,gBAA0B,EAC1B,KAAAC,gBAA0B,EAO1B,KAAAC,aAAoC,CAAC,EACrC,KAAAC,YAAsB,GACtB,KAAAC,eAAyB,GACzB,KAAAC,sBAAuC,KACvC,KAAAC,mBAA6B,IAG7B,KAAAC,kBAAmD,IAAIC,QAG7DvU,KAAKc,OAAS,GACZmM,SAAUkB,EAAWI,aACrBiG,cAAe,IACfC,cAAc,EACdC,MAAOvG,EAAWM,MAClBkG,cAAe,CACbC,SAAS,EACTzT,oBAAoB,EACpBC,qBAAqB,EACrBC,mBAAoB,GACpBC,oBAAqB,IACrBC,WAAY,IACZC,uBAAuB,EACvBC,sBAAsB,IAErBX,GAGLd,KAAK0B,UAAY1B,KAAK2B,oBAEtB,IAgDMkT,EAAO,IAAIhE,KAAK,CAhDH,8pEAgDiB,CAAE3O,KAAM,2BACtC4S,EAAYC,IAAIC,gBAAgBH,GACtC7U,KAAKiV,OAAS,IAAIC,OAAOJ,GACzB9U,KAAK8B,YACP,CAipBF,OA/oBgB,YAAAA,WAAd,W,8FACE,OAAI9B,KAAK8T,cAAe,KACxB9T,KAAK8T,eAAgB,GAGQ,QAAzB,EAAA9T,KAAKc,OAAO6T,qBAAa,eAAEC,UAC7B5U,KAAKmV,0BAGHnV,KAAKc,OAAOsU,WACd,GAAMpV,KAAKqV,0BADT,O,OACF,S,wBAIFrV,KAAKsV,0BAEDtV,KAAKc,OAAO2T,cAAkC,oBAAXS,OACrClV,KAAKuV,iBAGLvV,KAAKwV,kBAEPxV,KAAKgD,IAAI,+BAAgC,CAAElC,OAAQd,KAAKc,S,UAIlD,YAAAqU,wBAAR,W,gCACE,IAEEnV,KAAKyV,aAAe,IAAI/B,EAAa,CACnCtE,eAAgB,QAChBC,WAAY,EACZC,cAAe,IACfC,oBAAoB,EACpBC,mBAAmB,IAIrB,IAAMkG,EAA2B,CAC/BzI,SAAUkB,EAAWI,aACrBlK,SAAUrE,KAAKc,OAAOuD,SACtB8I,OAAQnN,KAAKc,OAAOqM,OACpBhM,mBAAiE,QAA7C,EAAyB,QAAzB,EAAAnB,KAAKc,OAAO6T,qBAAa,eAAExT,0BAAkB,SACjEC,oBAAmE,QAA9C,EAAyB,QAAzB,EAAApB,KAAKc,OAAO6T,qBAAa,eAAEvT,2BAAmB,SACnEC,mBAAiE,QAA7C,EAAyB,QAAzB,EAAArB,KAAKc,OAAO6T,qBAAa,eAAEtT,0BAAkB,QAAI,GACrEC,oBAAmE,QAA9C,EAAyB,QAAzB,EAAAtB,KAAKc,OAAO6T,qBAAa,eAAErT,2BAAmB,QAAI,IACvEC,WAAiD,QAArC,EAAyB,QAAzB,EAAAvB,KAAKc,OAAO6T,qBAAa,eAAEpT,kBAAU,QAAI,IACrDC,sBAAuE,QAAhD,EAAyB,QAAzB,EAAAxB,KAAKc,OAAO6T,qBAAa,eAAEnT,6BAAqB,SACvEC,qBAAqE,QAA/C,EAAyB,QAAzB,EAAAzB,KAAKc,OAAO6T,qBAAa,eAAElT,4BAAoB,UAGvEzB,KAAK2V,aAAe,IAAIC,EAAaF,GAGrC,IAAM1Q,EAAShF,KAAK6V,YAChB7Q,GAAUhF,KAAK2V,cACjB3V,KAAK2V,aAAa5H,QAAQ/I,GAG5BhF,KAAKgD,IAAI,0CACX,CAAE,MAAOP,GACPZ,QAAQY,MAAM,sDAAuDA,EACvE,CACF,EAGO,YAAAoL,iBAAP,SAAwBpL,EAAcqL,GAChC9N,KAAK2V,cACP3V,KAAK2V,aAAa9H,iBAAiBpL,EAAOqL,EAE9C,EAGO,YAAAC,QAAP,SAAe/I,GACThF,KAAK2V,cACP3V,KAAK2V,aAAa5H,QAAQ/I,EAE9B,EAGa,YAAAiJ,kBAAb,W,+FACMjO,KAAKyV,aACP,GAAMzV,KAAKyV,aAAa7F,gBADtB,M,OACF,S,wBAEE5P,KAAK2V,aACP,GAAM3V,KAAK2V,aAAa1H,qBADtB,M,OACF,S,iCAIU,YAAAoH,uBAAd,W,oGAIyB,O,sBAFrBrV,KAAKgD,IAAI,kCAEY,GAAMhD,KAAK8V,mB,cAA1BC,EAAe,SACfC,EAAUhW,KAAKiW,eAAeF,GACpC/V,KAAKkU,YAAc8B,GAGfE,EAAkBlW,KAAKmW,0BAA0BH,KAGnDhW,KAAKgD,IAAI,gEAAiEgT,G,OADxE,M,OAIgB,SAAMhW,KAAKoW,sB,QAA7BF,EAAkB,WAEhBlW,KAAKgD,IAAI,qC,wBAIRkT,EAAD,OAEFlW,KAAKgD,IAAI,8DAA+DgT,GACtD,GAAMhW,KAAKqW,qBAAqBN,EAAcC,K,QAAhEE,EAAkB,WACKA,EAAgBI,kBACrCtW,KAAKuW,iBAAiBL,GACtBlW,KAAKwW,0BAA0BR,EAASE,GACxClW,KAAKmU,eAAiB+B,EAAgBO,aAAe,I,wBAIrDP,GAAmBA,EAAgBI,iBACrCtW,KAAK0W,qBAAqBR,GAEtBlW,KAAKc,OAAO2T,cAAkC,oBAAXS,QACrClV,KAAKiV,OAAO0B,YAAY,CAAEzU,KAAM,aAAcpB,OAAQoV,IAExDlW,KAAKgD,IAAI,0CAA2CkT,IAEpDlW,KAAKgD,IAAI,mEAAoEkT,G,+BAG/ElW,KAAKgD,IAAI,uCAAwC,G,6BAIvC,YAAA8S,gBAAd,W,sGAWE,OAVMc,EAAc,SAACrP,GACnB,GAAIA,EAAGE,GAAI,MAAO,WAAIF,EAAGE,IACzB,GAAIF,EAAGG,UAAW,CAChB,IAAMoF,EAAUvF,EAAGG,UAAU1B,MAAM,KAAK+G,OAAO,SAAAC,GAAK,OAAAA,EAAEH,MAAF,GAAU3G,KAAK,KACnE,OAAO4G,EAAU,WAAIA,GAAYvF,EAAGC,QAAQrB,aAC9C,CACA,OAAOoB,EAAGC,QAAQrB,aACpB,EAGA,GAAM,IAAI0Q,QAAQ,SAAAC,GAAW,OAAArK,WAAWqK,EAAS,IAApB,I,OAsE7B,OAtEA,SAGMjQ,EAAWQ,MAAMC,KAAKf,SAAS+B,KAAKlB,iBAAiB,+YASrD2P,EAAmBlQ,EAASkG,OAAO,SAAAxF,GACvC,IAAMyP,EAAQlX,OAAOmX,iBAAiB1P,GAChC2P,EAA8B,SAAlBF,EAAMG,SAA2C,WAArBH,EAAMI,YAA6C,MAAlBJ,EAAMK,QAC/EC,EAA8C,WAA7B/P,EAAGC,QAAQrB,eACiB,MAA7BoB,EAAGC,QAAQrB,eACXoB,EAAGgQ,aAAa,YACY,WAA5BhQ,EAAGa,aAAa,SAChBb,EAAGiQ,UAAUC,SAAS,QACtBlQ,EAAGiQ,UAAUC,SAAS,QACtCC,EAA+B,mBAAVnQ,EAAGE,IACHF,EAAGiQ,UAAUC,SAAS,eACtBlQ,EAAGiQ,UAAUC,SAAS,SACO,QAA7BlQ,EAAGC,QAAQrB,gBAC+C,IAA1D,CAAC,KAAM,KAAM,MAAMwR,QAAQpQ,EAAGC,QAAQrB,eAEjE,OAAQ+Q,IAAcI,GAAkBI,IAAkC,mBAAVnQ,EAAGE,EACrE,GAGMmQ,EAAO,IAAIC,IACXC,EAAYf,EAAiBpL,IAAI,SAAApE,G,QAE/BwQ,EAA2C,CAAC,EA2BlD,OA1BA1Q,MAAMC,KAAKC,EAAGM,YAAYZ,QAAQ,SAAAiB,IAEyC,IAArE,CAAC,QAAS,iBAAkB,iBAAiByP,QAAQzP,EAAK4B,QAC5DiO,EAAiB7P,EAAK4B,MAAQ5B,EAAKC,MAEvC,GAEY,CACVX,QAASD,EAAGC,QAAQrB,cACpBe,SAAU0P,EAAYrP,GACtBE,GAAIF,EAAGE,IAAM,GACbC,UAAWH,EAAGG,WAAa,GAC3BC,aAAcJ,EAAGI,aAAe,IAAIkF,OAAOjF,UAAU,EAAG,KACxDC,WAAYkQ,EAEZC,cAA4C,WAA7BzQ,EAAGC,QAAQrB,eACiB,MAA7BoB,EAAGC,QAAQrB,eACXoB,EAAGgQ,aAAa,YACY,WAA5BhQ,EAAGa,aAAa,SAChBb,EAAGiQ,UAAUC,SAAS,OACpCQ,YAAa1Q,EAAG2Q,SAASvU,OAAS,EAClCwU,WAAY5Q,EAAG2Q,SAASvU,OAExByU,eAA+B,QAAhB,EAAA7Q,EAAG8Q,qBAAa,eAAE7Q,QAAQrB,gBAAiB,GAC1DmS,MAAOjR,MAAMC,MAAqB,QAAhB,EAAAC,EAAG8Q,qBAAa,eAAEH,WAAY,IAAIP,QAAQpQ,GAGhE,GAAGwF,OAAO,SAAAtM,GACR,IAAMN,EAAMM,EAAI+G,QAAU,IAAM/G,EAAIyG,SAAW,IAAMzG,EAAIkH,YAAYC,UAAU,EAAG,IAClF,OAAIgQ,EAAK5T,IAAI7D,KACbyX,EAAKW,IAAIpY,IACF,EACT,GAEAH,KAAKgD,IAAI,yBAA0B,CAAEwV,aAAcV,EAAUnU,OAAQkD,SAAUiR,IACxE,CAAP,EAAO,CAAEjR,SAAUiR,I,MAGP,YAAAzB,qBAAd,SAAmCyB,EAAgB9B,G,kGAE/C,O,sBAAG8B,GAAaA,EAAUjR,UAA0C,IAA9BiR,EAAUjR,SAASlD,QACvD3D,KAAKgD,IAAI,8DACF,CAAP,EAAO,QAGHyV,EAAmB,CAAEX,UAAS,GAChC9B,IACFyC,EAAYzC,QAAUA,EACtByC,EAAYtE,eAAiBnU,KAAKmU,gBAGnB,GAAMhK,MAAMwE,EAAcG,OAAQ,CACjD7D,OAAQ,OACRiC,QAAS,CACP,eAAgB,mBAChB,cAAelN,KAAKc,OAAOuD,UAE7BiE,KAAMvB,KAAKC,UAAUyR,O,OAGvB,KATMlO,EAAW,UASHG,GACZ,MAAM,IAAI0C,MAAM,2BAAoB7C,EAASC,SAExC,SAAMD,EAASmO,Q,OAAtB,MAAO,CAAP,EAAO,U,OAGP,O,WADA1Y,KAAKgD,IAAI,mCAAoC,GACtC,CAAP,EAAO,M,uBAIH,YAAA0T,qBAAR,SAA6B5V,GAA7B,WACEA,EAAOwV,gBAAgBrP,QAAQ,SAAA0R,GAC7B,IACE,IAAM9R,EAAWN,SAASa,iBAAiBuR,EAAaC,kBACpD/R,EAASlD,OAAS,EACpBkD,EAASI,QAAQ,SAAAe,GAEf,IAAI6Q,EAAW,EAAKvE,kBAAkB9T,IAAIwH,GACrC6Q,IACHA,EAAW,IAAIhB,IACf,EAAKvD,kBAAkBrQ,IAAI+D,EAAS6Q,KAInBxR,MAAMoL,QAAQkG,EAAaG,YAAcH,EAAaG,WAAa,CAACH,EAAaG,aAEzF7R,QAAQ,SAAC8R,GACdF,EAAS7U,IAAI+U,KACjBF,EAASN,IAAIQ,GAGK,UAAdA,IACF/Q,EAAQjG,iBAAiB,QAAS,SAACC,GAEjC,IAAM0K,EAAS1K,EAAM0K,OACfsM,EAAc,EAAKC,mBAAmBvM,GAE5C,EAAKwM,aAAaP,EAAaQ,WAAY,CACzCjS,SAAUyR,EAAaC,iBACvBG,UAAW,QACX/Q,QAASgR,EACTtV,WAAW,IAAIT,MAAOmW,eAE1B,GACA,EAAKpW,IAAI,uCAAgC2V,EAAaQ,WAAU,iBAASR,EAAaC,iBAAgB,OAItF,SAAdG,GACE,yBAA0BjZ,SACX,IAAIuZ,qBAAqB,SAACC,GACzCA,EAAQrS,QAAQ,SAAA4C,GACd,GAAIA,EAAM0P,eAAgB,CACxB,IAAM7M,EAAS7C,EAAM6C,OACfsM,EAAc,EAAKC,mBAAmBvM,GAE5C,EAAKwM,aAAaP,EAAaQ,WAAY,CACzCjS,SAAUyR,EAAaC,iBACvBG,UAAW,OACX/Q,QAASgR,EACTQ,kBAAmB3P,EAAM2P,kBACzB9V,WAAW,IAAIT,MAAOmW,eAE1B,CACF,EACF,EAAG,CAAEK,UAAW,CAAC,GAAK,GAAK,KAClBC,QAAQ1R,GACjB,EAAKhF,IAAI,6CAAsC2V,EAAaQ,WAAU,iBAASR,EAAaC,iBAAgB,OAK9F,UAAdG,GAAuC,SAAdA,IAC3B/Q,EAAQjG,iBAAiBgX,EAAW,WAClC,IAAMrM,EAAS1E,EACTgR,EAAc,EAAKC,mBAAmBvM,GAE5C,EAAKwM,aAAaP,EAAaQ,WAAY,CACzCjS,SAAUyR,EAAaC,iBACvBG,UAAWA,EACX/Q,QAASgR,EACTtV,WAAW,IAAIT,MAAOmW,eAE1B,GACA,EAAKpW,IAAI,mBAAY+V,EAAS,0BAAkBJ,EAAaQ,WAAU,iBAASR,EAAaC,iBAAgB,OAEjH,EACF,GAEA,EAAK5V,IAAI,2CAAoC2V,EAAaC,iBAAgB,KAE9E,CAAE,MAAO7Q,GACP,EAAK/E,IAAI,mCAA4B2V,EAAaC,iBAAgB,MAAM7Q,EAC1E,CACF,GAGIjH,EAAO6Y,mBACL,qBAAsB7Z,SACP,IAAI8Z,iBAAiB,SAACC,GACrCA,EAAU5S,QAAQ,SAAA6S,GAChB,EAAKZ,aAAa,eAAgB,CAChChX,KAAM4X,EAAS5X,KACfwK,OAASoN,EAASpN,OAAuBqN,UACzCrW,WAAW,IAAIT,MAAOmW,eAE1B,EACF,GACSM,QAAQnT,SAAS+B,KAAM,CAAE0R,WAAW,EAAMC,SAAS,IAC5Dja,KAAKgD,IAAI,6CAGf,EAEQ,YAAAiW,mBAAR,SAA2BjR,GACzB,IAAMkS,EAAOlS,EAAQmS,wBACrB,MAAO,CACL3S,QAASQ,EAAQR,QAAQrB,cACzBsB,GAAIO,EAAQP,IAAM,GAClBC,UAAWM,EAAQN,WAAa,GAChCC,aAAcK,EAAQL,aAAe,IAAIkF,OAAOjF,UAAU,EAAG,KAC7DC,WAAYR,MAAMC,KAAKU,EAAQH,YAAYuS,OAAO,SAACC,EAAKnS,GAEtD,OADAmS,EAAInS,EAAK4B,MAAQ5B,EAAKC,MACfkS,CACT,EAAG,CAAC,GACJC,SAAU,CACRC,EAAGpX,KAAKqX,MAAMN,EAAKK,GACnBE,EAAGtX,KAAKqX,MAAMN,EAAKO,GACnBhU,MAAOtD,KAAKqX,MAAMN,EAAKzT,OACvBE,OAAQxD,KAAKqX,MAAMN,EAAKvT,SAE1BhC,KAAOqD,EAA8BrD,WAAQiO,EAC7CzK,MAAQH,EAA6BG,YAASyK,EAElD,EAGQ,YAAAsG,aAAR,SAAqBwB,EAAmBC,GACtC,IAAMC,EAAiB,CACrB5Y,MAAO0Y,EACPC,WAAU,EACVjX,UAAWT,KAAKC,MAChB8B,OAAQhF,KAAK6V,YACbnU,UAAW1B,KAAK0B,UAChB0C,UAAWpE,KAAKc,OAAOuD,UAAY,wCAEjCrE,KAAKc,OAAO2T,cAAkC,oBAAXS,OACrClV,KAAKiV,OAAO0B,YAAY,CAAEzU,KAAM,QAAS2Y,QAASD,IAElD5a,KAAK6T,WAAWpQ,KAAKmX,GAEvB5a,KAAKgD,IAAI,iBAAkB4X,EAC7B,EAEQ,YAAArF,eAAR,e,QAAA,OAEEvV,KAAKiV,OAAO0B,YAAY,CACtBzU,KAAM,SACN2Y,QAAS,CACPC,QAA8B,QAAtB,EAAA9a,KAAKc,OAAOia,kBAAU,eAAEC,cAAe,UAAGhb,KAAKc,OAAOmM,SAAQ,kBACtEgO,WAAmC,QAAxB,EAAAjb,KAAKc,OAAOoa,oBAAY,eAAED,YAAa,GAClDzG,eAAuC,QAAxB,EAAAxU,KAAKc,OAAOoa,oBAAY,eAAE1G,gBAAiB,IAC1DtH,SAA+B,QAAtB,EAAAlN,KAAKc,OAAOia,kBAAU,eAAE7N,UAAW,CAAE,eAAgB,uBAGlElN,KAAKiV,OAAOkG,UAAY,SAACnZ,G,MACG,YAAtBA,EAAM8D,KAAK0E,OACb,EAAKxH,IAAI,qCAEsB,UAAtBhB,EAAM8D,KAAK0E,OACpB,EAAKxH,IAAIhB,EAAM8D,KAAK3D,QAASH,EAAM8D,MACJ,UAAtB9D,EAAM8D,KAAK0E,SACpB,EAAKxH,IAAI,8BAA+BhB,EAAM8D,KAAKrD,OAE/CT,EAAM8D,KAAKsV,cAAgBpZ,EAAM8D,KAAKsV,aAAazX,OAAS,IAC9D,IAAKkQ,YAAWwH,QAAO,QAAIrZ,EAAM8D,KAAKsV,cAG5C,EACApb,KAAKgD,IAAI,6BACX,EAEO,YAAAsY,MAAP,SAAaZ,EAAmBC,QAAA,IAAAA,IAAAA,EAAA,IAC9B,IAAMC,EAAiB,CACrB5Y,MAAO0Y,EACPC,WAAU,EACVjX,UAAWT,KAAKC,MAChB8B,OAAQhF,KAAK6V,YACbnU,UAAW1B,KAAK0B,UAChB0C,UAAWpE,KAAKc,OAAOuD,UAAY,wCAIjCrE,KAAKc,OAAO2T,cAAkC,oBAAXS,OACrClV,KAAKiV,OAAO0B,YAAY,CAAEzU,KAAM,QAAS2Y,QAASD,IAElD5a,KAAK6T,WAAWpQ,KAAKmX,GAEvB5a,KAAKgD,IAAI,wBAAyB4X,EACpC,EAEQ,YAAApF,gBAAR,sBACExV,KAAKub,WAAazb,OAAOmS,YAAY,WACnC,EAAKuJ,YACP,EAAGxb,KAAKc,OAAO0T,cACjB,EAEc,YAAAgH,WAAd,W,8FACE,OAA+B,IAA3Bxb,KAAK6T,WAAWlQ,OAClB,KAGI8X,E,+LAAQ,IAAIzb,KAAK6T,YAAU,GAEjC7T,KAAK6T,WAAa,GAEd7T,KAAKc,OAAO2T,cAAkC,oBAAXS,QACrClV,KAAKiV,OAAO0B,YAAY,CACtBzU,KAAM,QACNwZ,OAAQD,EACRxO,SAAU,UAAGjN,KAAKc,OAAOmM,SAAQ,oB,OAJjC,O,OAQF,SAAMjN,KAAK2b,mBAAmBF,I,OAA9B,S,iCAIU,YAAAE,mBAAd,SAAiCF,G,gGAC/B,GAAIzb,KAAK+T,iBAAmB/T,KAAKgU,gBAM/B,OALIhU,KAAKub,aACP5I,cAAc3S,KAAKub,YACnBvb,KAAKub,gBAAa3I,EAClB5S,KAAKgD,IAAI,qDAEX,I,iBAGA,O,sBAAA,GAAMhD,KAAK4b,UAAUH,I,cAArB,SAEAzb,KAAK+T,gBAAkB,E,+BAEvB/T,KAAK+T,kBACL/T,KAAKgD,IAAI,2CAAoChD,KAAK+T,gBAAe,eAAO/T,KAAKgU,gBAAe,KAAK,IAEjG,EAAAhU,KAAK6T,YAAWwH,QAAO,QAAII,GACvBzb,KAAK+T,iBAAmB/T,KAAKgU,iBAC3BhU,KAAKub,aACP5I,cAAc3S,KAAKub,YACnBvb,KAAKub,gBAAa3I,EAClB5S,KAAKgD,IAAI,qD,6BAOH,YAAA4Y,UAAd,SAAwBH,G,wGAClBxO,EAAW,UAAGjN,KAAKc,OAAOmM,SAAQ,kBAClCC,EAAkC,CAAE,eAAgB,oBACpDlN,KAAKc,OAAOia,YAAc/a,KAAKc,OAAOia,WAAWC,cACnD/N,EAAWjN,KAAKc,OAAOia,WAAWC,YAC9Bhb,KAAKc,OAAOia,WAAW7N,UACzBA,EAAU,OAAKA,GAAYlN,KAAKc,OAAOia,WAAW7N,WAIhD7I,EAAWrE,KAAKc,OAAOuD,UAAY,uCACnCqX,EAASD,EAAM9P,IAAI,SAAC5D,GAAW,OAAC,GACpC/F,MAAO+F,EAAE/F,MACTgD,OAAQ+C,EAAE/C,OACVZ,UAAWC,EACXX,UAAW,IAAIT,KAAK8E,EAAErE,WAAW0V,eAC7BrR,EAAE4S,YAAc,CAAC,EALc,G,iBAQlB,O,sBAAA,GAAMxQ,MAAM8C,EAAU,CACrChC,OAAQ,OACRiC,QAAO,EACP5E,KAAMvB,KAAKC,UAAU,CAAE0U,OAAM,O,OAE/B,KALMnR,EAAW,UAKHG,GACZ,MAAM,IAAI0C,MAAM,gCAAyB7C,EAASC,S,OAEpDxK,KAAKgD,IAAI,2BAA4B0Y,G,aAGrC,M,WADA1b,KAAKgD,IAAI,uBAAwB,GAC3B,E,uBAIF,YAAArB,kBAAR,WAEE,MAAO,QAAUwB,KAAKC,SAASC,SAAS,IAAIC,OAAO,EAAG,EACxD,EAEQ,YAAAuS,UAAR,WAEE,MAAO,QAAU1S,KAAKC,SAASC,SAAS,IAAIC,OAAO,EAAG,EACxD,EAEQ,YAAAN,IAAR,SAAYb,EAAiB2D,GACvB9F,KAAKc,OAAO4T,OACd7S,QAAQmB,IAAI,6BAAsBb,GAAW2D,GAAQ,GAEzD,EAGM,YAAAyQ,iBAAR,SAAyBzV,GACnBd,KAAKc,OAAO4T,KAYlB,EAGc,YAAA0B,mBAAd,W,8FAEqB,O,sBAAA,GAAMjM,MAAM,wBAAyB,CAAE0R,MAAO,Y,OAC/D,OADMtR,EAAW,UACHG,GAGC,GAAMH,EAASmO,QAFrB,CAAP,EAAO,M,OAGT,MAAO,CAAP,EADe,U,OAGf,O,SAAO,CAAP,EAAO,M,uBAKG,YAAApD,wBAAd,W,kFAEM,qBAAsBxV,SACP,IAAI8Z,iBAAiB,WAChC,EAAKxF,uBACP0H,aAAa,EAAK1H,uBAEpB,EAAKA,sBAAwBtU,OAAO2M,WAAW,WAC7C,EAAKsP,mBACP,EAAG,EAAK1H,mBACV,GACSqF,QAAQnT,SAAS+B,KAAM,CAAE0R,WAAW,EAAMC,SAAS,EAAMpS,YAAY,IAC9E7H,KAAKgD,IAAI,0C,SAIL,YAAAiT,eAAR,SAAuB6B,GAIrB,IAFA,IAAMkE,EAAMjV,KAAKC,UAAU8Q,GACvBmE,EAAO,WACFC,EAAI,EAAGA,EAAIF,EAAIrY,OAAQuY,IAC9BD,GAAQD,EAAIG,WAAWD,GACvBD,IAASA,GAAQ,IAAMA,GAAQ,IAAMA,GAAQ,IAAMA,GAAQ,IAAMA,GAAQ,IAE3E,OAAQA,IAAS,GAAG5Y,SAAS,GAC/B,EAEQ,YAAA8S,0BAAR,SAAkCH,GAChC,IAEE,OADcjP,KAAK2G,MAAMH,aAAaC,QAAQ,8BAAgC,MACjEwI,IAAY,IAC3B,CAAE,SACA,OAAO,IACT,CACF,EAEQ,YAAAQ,0BAAR,SAAkCR,EAAiBlV,GACjD,IACE,IAAM+a,EAAQ9U,KAAK2G,MAAMH,aAAaC,QAAQ,8BAAgC,MAC9EqO,EAAM7F,GAAWlV,EACjByM,aAAaK,QAAQ,4BAA6B7G,KAAKC,UAAU6U,GACnE,CAAE,SAAO,CACX,EAEc,YAAAE,kBAAd,W,oGACuB,SAAM/b,KAAK8V,mB,OAGhC,OAHMC,EAAe,UACfC,EAAUhW,KAAKiW,eAAeF,MAEpB/V,KAAKkU,aACnBlU,KAAKgD,IAAI,6DACT,MAGFhD,KAAKgD,IAAI,kDAAmD,CAAEoZ,QAASpc,KAAKkU,YAAamI,QAASrG,IAClGhW,KAAKkU,YAAc8B,GAEbsG,EAAetc,KAAKmW,0BAA0BH,KAElDhW,KAAKgD,IAAI,qCAAsCgT,GAC/ChW,KAAK0W,qBAAqB4F,GAC1B,MAIFtc,KAAKgD,IAAI,iDAAkDgT,GAC5C,GAAMhW,KAAKqW,qBAAqBN,EAAcC,M,cAAvDlV,EAAS,WACDA,EAAOwV,iBACnBtW,KAAK0W,qBAAqB5V,GAC1Bd,KAAKwW,0BAA0BR,EAASlV,GACxCd,KAAKmU,eAAiBrT,EAAO2V,aAAe,GAC5CzW,KAAKgD,IAAI,kDAAmDgT,IAE5DhW,KAAKgD,IAAI,4CAA6CgT,G,UAG1D,EAnvBA,GAsvBsB,oBAAXlW,SACRA,OAAeyc,eAAiBA,GAGnC,Q","sources":["webpack://AInamikaSDKPro/webpack/universalModuleDefinition","webpack://AInamikaSDKPro/webpack/bootstrap","webpack://AInamikaSDKPro/webpack/runtime/define property getters","webpack://AInamikaSDKPro/webpack/runtime/hasOwnProperty shorthand","webpack://AInamikaSDKPro/./src/error-tracker.ts","webpack://AInamikaSDKPro/./src/config.ts","webpack://AInamikaSDKPro/./src/error-storage.ts","webpack://AInamikaSDKPro/./src/sdk.ts"],"sourcesContent":["(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory();\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"AInamikaSDKPro\"] = factory();\n\telse\n\t\troot[\"AInamikaSDKPro\"] = factory();\n})((typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : typeof global !== \"undefined\" ? global : this), function() {\nreturn ","// The require scope\nvar __webpack_require__ = {};\n\n","// define getter functions for harmony exports\n__webpack_require__.d = function(exports, definition) {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.o = function(obj, prop) { return Object.prototype.hasOwnProperty.call(obj, prop); }","// error-tracker.ts - Advanced Error Tracking System for AInamika SDK\n\nexport interface ErrorConfig {\n endpoint: string;\n clientId: string;\n apiKey: string;\n captureScreenshots?: boolean;\n captureDomSnapshots?: boolean;\n maxStackTraceDepth?: number;\n maxErrorsPerSession?: number;\n debounceMs?: number;\n enableNetworkTracking?: boolean;\n enableConsoleCapture?: boolean;\n}\n\nexport interface ErrorData {\n id?: string;\n client_id: string;\n error_type: 'javascript' | 'network' | 'unhandled' | 'console' | 'custom';\n message: string;\n stack_trace?: string;\n url: string;\n user_agent: string;\n timestamp: number;\n error_metadata: {\n line?: number;\n column?: number;\n filename?: string;\n component?: string;\n props?: Record<string, any>;\n userId?: string;\n sessionId?: string;\n breadcrumbs?: ErrorBreadcrumb[];\n networkInfo?: NetworkInfo;\n performance?: PerformanceInfo;\n };\n dom_snapshot?: string;\n screen_snapshot?: string;\n severity: 'low' | 'medium' | 'high' | 'critical';\n session_id: string;\n user_id?: string;\n}\n\nexport interface ErrorBreadcrumb {\n timestamp: number;\n type: 'navigation' | 'click' | 'console' | 'network' | 'error';\n message: string;\n data?: Record<string, any>;\n}\n\nexport interface NetworkInfo {\n effectiveType?: string;\n downlink?: number;\n rtt?: number;\n saveData?: boolean;\n}\n\nexport interface PerformanceInfo {\n memory?: {\n usedJSHeapSize: number;\n totalJSHeapSize: number;\n jsHeapSizeLimit: number;\n };\n timing?: {\n domContentLoaded: number;\n load: number;\n firstPaint?: number;\n firstContentfulPaint?: number;\n };\n}\n\nexport class ErrorTracker {\n private config: ErrorConfig;\n private breadcrumbs: ErrorBreadcrumb[] = [];\n private errorCount = 0;\n private errorDebounceMap = new Map<string, number>();\n private originalConsole: Console;\n private sessionId: string;\n private userId?: string;\n\n constructor(config: ErrorConfig) {\n this.config = {\n captureScreenshots: true,\n captureDomSnapshots: true,\n maxStackTraceDepth: 50,\n maxErrorsPerSession: 100,\n debounceMs: 1000,\n enableNetworkTracking: true,\n enableConsoleCapture: true,\n ...config\n };\n\n this.sessionId = this.generateSessionId();\n this.originalConsole = { ...console };\n this.initialize();\n }\n\n private initialize() {\n // Global error handler\n window.addEventListener('error', (event) => {\n this.handleError({\n type: 'javascript',\n message: event.message,\n filename: event.filename,\n line: event.lineno,\n column: event.colno,\n error: event.error\n });\n });\n\n // Unhandled promise rejection handler\n window.addEventListener('unhandledrejection', (event) => {\n this.handleError({\n type: 'unhandled',\n message: event.reason?.message || 'Unhandled Promise Rejection',\n error: event.reason,\n promise: true\n });\n });\n\n // Network error tracking\n if (this.config.enableNetworkTracking) {\n this.setupNetworkTracking();\n }\n\n // Console capture\n if (this.config.enableConsoleCapture) {\n this.setupConsoleCapture();\n }\n\n // Navigation breadcrumbs\n this.setupNavigationTracking();\n\n // Click breadcrumbs\n this.setupClickTracking();\n\n console.log('[AInamika Error Tracker] Initialized successfully');\n }\n\n private generateSessionId(): string {\n return `session_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;\n }\n\n private addBreadcrumb(breadcrumb: Omit<ErrorBreadcrumb, 'timestamp'>) {\n this.breadcrumbs.push({\n ...breadcrumb,\n timestamp: Date.now()\n });\n\n // Keep only last 50 breadcrumbs\n if (this.breadcrumbs.length > 50) {\n this.breadcrumbs = this.breadcrumbs.slice(-50);\n }\n }\n\n private handleError(errorInfo: any) {\n if (this.errorCount >= this.config.maxErrorsPerSession!) {\n console.warn('[AInamika Error Tracker] Max errors per session reached');\n return;\n }\n\n const errorKey = `${errorInfo.message}_${errorInfo.filename}_${errorInfo.line}`;\n const now = Date.now();\n \n // Debounce duplicate errors\n if (this.errorDebounceMap.has(errorKey)) {\n const lastTime = this.errorDebounceMap.get(errorKey)!;\n if (now - lastTime < this.config.debounceMs!) {\n return;\n }\n }\n this.errorDebounceMap.set(errorKey, now);\n\n this.errorCount++;\n this.captureError(errorInfo);\n }\n\n private async captureError(errorInfo: any) {\n try {\n const errorData: ErrorData = {\n client_id: this.config.clientId,\n error_type: errorInfo.type || 'javascript',\n message: errorInfo.message || 'Unknown error',\n stack_trace: this.extractStackTrace(errorInfo.error),\n url: window.location.href,\n user_agent: navigator.userAgent,\n timestamp: Date.now(),\n error_metadata: {\n line: errorInfo.line,\n column: errorInfo.column,\n filename: errorInfo.filename,\n userId: this.userId,\n sessionId: this.sessionId,\n breadcrumbs: [...this.breadcrumbs],\n networkInfo: this.getNetworkInfo(),\n performance: this.getPerformanceInfo()\n },\n severity: this.assessSeverity(errorInfo),\n session_id: this.sessionId,\n user_id: this.userId\n };\n\n // Capture DOM snapshot\n if (this.config.captureDomSnapshots) {\n errorData.dom_snapshot = this.captureDomSnapshot();\n }\n\n // Capture screenshot\n if (this.config.captureScreenshots) {\n errorData.screen_snapshot = await this.captureScreenshot();\n }\n\n // Send error to backend\n await this.sendError(errorData);\n\n // Add error breadcrumb\n this.addBreadcrumb({\n type: 'error',\n message: `${errorData.error_type}: ${errorData.message}`,\n data: { severity: errorData.severity }\n });\n\n } catch (captureError) {\n console.error('[AInamika Error Tracker] Failed to capture error:', captureError);\n }\n }\n\n private extractStackTrace(error: Error): string {\n if (!error || !error.stack) return '';\n \n const stack = error.stack.split('\\n');\n const maxDepth = this.config.maxStackTraceDepth!;\n \n return stack.slice(0, maxDepth).join('\\n');\n }\n\n private assessSeverity(errorInfo: any): 'low' | 'medium' | 'high' | 'critical' {\n const message = errorInfo.message?.toLowerCase() || '';\n \n // Critical errors\n if (message.includes('out of memory') || \n message.includes('security') ||\n message.includes('permission denied') ||\n errorInfo.type === 'unhandled') {\n return 'critical';\n }\n \n // High severity\n if (message.includes('network') || \n message.includes('timeout') ||\n message.includes('failed to fetch') ||\n message.includes('cors')) {\n return 'high';\n }\n \n // Medium severity\n if (message.includes('undefined') || \n message.includes('null') ||\n message.includes('cannot read property')) {\n return 'medium';\n }\n \n return 'low';\n }\n\n private captureDomSnapshot(): string {\n try {\n // Create a simplified DOM snapshot\n const snapshot = {\n url: window.location.href,\n title: document.title,\n viewport: {\n width: window.innerWidth,\n height: window.innerHeight\n },\n elements: this.extractDomElements()\n };\n \n return JSON.stringify(snapshot);\n } catch (error) {\n console.error('[AInamika Error Tracker] Failed to capture DOM snapshot:', error);\n return '';\n }\n }\n\n private extractDomElements(): any[] {\n const elements: any[] = [];\n const maxElements = 100;\n \n // Get key elements\n const selectors = [\n 'body > *',\n '[id]',\n '[class*=\"error\"]',\n '[class*=\"modal\"]',\n 'form',\n 'button',\n 'input[type=\"submit\"]'\n ];\n \n selectors.forEach(selector => {\n try {\n const els = document.querySelectorAll(selector);\n Array.from(els).slice(0, maxElements - elements.length).forEach(el => {\n elements.push({\n tagName: el.tagName,\n id: el.id,\n className: el.className,\n textContent: el.textContent?.substring(0, 100),\n attributes: this.getElementAttributes(el)\n });\n });\n } catch (e) {\n // Ignore selector errors\n }\n });\n \n return elements;\n }\n\n private getElementAttributes(element: Element): Record<string, string> {\n const attrs: Record<string, string> = {};\n const importantAttrs = ['id', 'class', 'type', 'name', 'value', 'href', 'src'];\n \n importantAttrs.forEach(attr => {\n const value = element.getAttribute(attr);\n if (value) attrs[attr] = value;\n });\n \n return attrs;\n }\n\n private async captureScreenshot(): Promise<string> {\n try {\n // Use html2canvas if available, otherwise return empty\n if (typeof (window as any).html2canvas === 'function') {\n const canvas = await (window as any).html2canvas(document.body, {\n height: Math.min(window.innerHeight, 1000),\n width: Math.min(window.innerWidth, 1000),\n useCORS: true\n });\n return canvas.toDataURL('image/jpeg', 0.7);\n }\n return '';\n } catch (error) {\n console.error('[AInamika Error Tracker] Failed to capture screenshot:', error);\n return '';\n }\n }\n\n private getNetworkInfo(): NetworkInfo {\n const connection = (navigator as any).connection || \n (navigator as any).mozConnection || \n (navigator as any).webkitConnection;\n \n if (!connection) return {};\n \n return {\n effectiveType: connection.effectiveType,\n downlink: connection.downlink,\n rtt: connection.rtt,\n saveData: connection.saveData\n };\n }\n\n private getPerformanceInfo(): PerformanceInfo {\n const info: PerformanceInfo = {};\n \n // Memory info\n if ((performance as any).memory) {\n info.memory = {\n usedJSHeapSize: (performance as any).memory.usedJSHeapSize,\n totalJSHeapSize: (performance as any).memory.totalJSHeapSize,\n jsHeapSizeLimit: (performance as any).memory.jsHeapSizeLimit\n };\n }\n \n // Timing info\n if (performance.timing) {\n const timing = performance.timing;\n info.timing = {\n domContentLoaded: timing.domContentLoadedEventEnd - timing.navigationStart,\n load: timing.loadEventEnd - timing.navigationStart\n };\n \n // Paint timings\n if (performance.getEntriesByType) {\n const paintEntries = performance.getEntriesByType('paint');\n paintEntries.forEach((entry: any) => {\n if (entry.name === 'first-paint') {\n info.timing!.firstPaint = entry.startTime;\n } else if (entry.name === 'first-contentful-paint') {\n info.timing!.firstContentfulPaint = entry.startTime;\n }\n });\n }\n }\n \n return info;\n }\n\n private setupNetworkTracking() {\n // Override fetch\n const originalFetch = window.fetch;\n window.fetch = async (...args) => {\n const startTime = Date.now();\n const url = args[0] instanceof Request ? args[0].url : String(args[0]);\n \n try {\n const response = await originalFetch(...args);\n \n this.addBreadcrumb({\n type: 'network',\n message: `Fetch ${response.status} ${url}`,\n data: {\n url,\n status: response.status,\n duration: Date.now() - startTime\n }\n });\n \n if (!response.ok) {\n this.handleError({\n type: 'network',\n message: `Network request failed: ${response.status} ${response.statusText}`,\n url,\n status: response.status\n });\n }\n \n return response;\n } catch (error: any) {\n this.addBreadcrumb({\n type: 'network',\n message: `Fetch failed ${url}`,\n data: { url, error: error?.message || 'Unknown error' }\n });\n \n this.handleError({\n type: 'network',\n message: `Network request failed: ${error?.message || 'Unknown error'}`,\n url,\n error\n });\n \n throw error;\n }\n };\n\n // Override XMLHttpRequest\n const originalXHROpen = XMLHttpRequest.prototype.open;\n const originalXHRSend = XMLHttpRequest.prototype.send;\n \n XMLHttpRequest.prototype.open = function(method: string, url: string | URL, async?: boolean, username?: string | null, password?: string | null) {\n (this as any)._errorTracker = { method, url, startTime: Date.now() };\n return originalXHROpen.call(this, method, url, async || true, username, password);\n };\n \n XMLHttpRequest.prototype.send = function(...args) {\n const tracker = (this as any)._errorTracker;\n \n this.addEventListener('loadend', () => {\n if (tracker) {\n const duration = Date.now() - tracker.startTime;\n \n if (this.status >= 400) {\n this.dispatchEvent(new CustomEvent('networkerror', {\n detail: {\n type: 'network',\n message: `XHR request failed: ${this.status} ${this.statusText}`,\n url: tracker.url,\n status: this.status\n }\n }));\n }\n \n this.dispatchEvent(new CustomEvent('networkbreadcrumb', {\n detail: {\n type: 'network',\n message: `XHR ${this.status} ${tracker.url}`,\n data: {\n method: tracker.method,\n url: tracker.url,\n status: this.status,\n duration\n }\n }\n }));\n }\n });\n \n return originalXHRSend.call(this, ...args);\n };\n \n // Listen for custom events\n document.addEventListener('networkerror', (event: any) => {\n this.handleError(event.detail);\n });\n \n document.addEventListener('networkbreadcrumb', (event: any) => {\n this.addBreadcrumb(event.detail);\n });\n }\n\n private setupConsoleCapture() {\n // Override console methods\n ['error', 'warn'].forEach(method => {\n const original = this.originalConsole[method as keyof Console] as Function;\n (console as any)[method] = (...args: any[]) => {\n if (typeof original === 'function') {\n original.call(console, ...args);\n }\n \n if (method === 'error') {\n this.handleError({\n type: 'console',\n message: args.map(arg => String(arg)).join(' '),\n consoleMethod: method\n });\n }\n \n this.addBreadcrumb({\n type: 'console',\n message: `Console ${method}: ${args.map(arg => String(arg)).join(' ')}`,\n data: { level: method }\n });\n };\n });\n }\n\n private setupNavigationTracking() {\n // Track page changes\n let currentUrl = window.location.href;\n \n const trackNavigation = () => {\n const newUrl = window.location.href;\n if (newUrl !== currentUrl) {\n this.addBreadcrumb({\n type: 'navigation',\n message: `Navigation from ${currentUrl} to ${newUrl}`,\n data: { from: currentUrl, to: newUrl }\n });\n currentUrl = newUrl;\n }\n };\n \n // Listen for various navigation events\n window.addEventListener('popstate', trackNavigation);\n window.addEventListener('hashchange', trackNavigation);\n \n // Override pushState and replaceState\n const originalPushState = history.pushState;\n const originalReplaceState = history.replaceState;\n \n history.pushState = function(...args) {\n originalPushState.apply(this, args);\n setTimeout(trackNavigation, 0);\n };\n \n history.replaceState = function(...args) {\n originalReplaceState.apply(this, args);\n setTimeout(trackNavigation, 0);\n };\n }\n\n private setupClickTracking() {\n document.addEventListener('click', (event) => {\n const target = event.target as Element;\n if (!target) return;\n \n const selector = this.getElementSelector(target);\n const text = target.textContent?.trim().substring(0, 50) || '';\n \n this.addBreadcrumb({\n type: 'click',\n message: `Clicked ${selector}${text ? `: ${text}` : ''}`,\n data: {\n selector,\n text,\n tagName: target.tagName,\n id: target.id,\n className: target.className\n }\n });\n });\n }\n\n private getElementSelector(element: Element): string {\n if (element.id) return `#${element.id}`;\n if (element.className) {\n const classes = element.className.split(' ').filter(c => c).slice(0, 2);\n if (classes.length) return `.${classes.join('.')}`;\n }\n return element.tagName.toLowerCase();\n }\n\n private async sendError(errorData: ErrorData) {\n try {\n const response = await fetch(`${this.config.endpoint}/api/v1/errors`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${this.config.apiKey}`\n },\n body: JSON.stringify(errorData)\n });\n\n if (!response.ok) {\n throw new Error(`Failed to send error: ${response.status} ${response.statusText}`);\n }\n\n console.log('[AInamika Error Tracker] Error sent successfully');\n } catch (error) {\n console.error('[AInamika Error Tracker] Failed to send error:', error);\n // Store error locally for retry\n this.storeErrorLocally(errorData);\n }\n }\n\n private storeErrorLocally(errorData: ErrorData) {\n try {\n const stored = localStorage.getItem('ainamika_errors') || '[]';\n const errors = JSON.parse(stored);\n errors.push(errorData);\n \n // Keep only last 50 errors\n if (errors.length > 50) {\n errors.splice(0, errors.length - 50);\n }\n \n localStorage.setItem('ainamika_errors', JSON.stringify(errors));\n } catch (error) {\n console.error('[AInamika Error Tracker] Failed to store error locally:', error);\n }\n }\n\n // Public methods\n public captureException(error: Error, context?: Record<string, any>) {\n this.handleError({\n type: 'custom',\n message: error.message,\n error,\n context\n });\n }\n\n public setUser(userId: string) {\n this.userId = userId;\n }\n\n public addTag(key: string, value: string) {\n // Add custom tags to error metadata\n if (!this.config.clientId) {\n this.config.clientId += `_${key}:${value}`;\n }\n }\n\n public async flushStoredErrors() {\n try {\n const stored = localStorage.getItem('ainamika_errors');\n if (!stored) return;\n \n const errors = JSON.parse(stored);\n if (errors.length === 0) return;\n \n console.log(`[AInamika Error Tracker] Flushing ${errors.length} stored errors`);\n \n for (const error of errors) {\n await this.sendError(error);\n }\n \n localStorage.removeItem('ainamika_errors');\n } catch (error) {\n console.error('[AInamika Error Tracker] Failed to flush stored errors:', error);\n }\n }\n}\n","// config.ts - Environment-based configuration for Ainamika SDK\n\nexport interface EnvironmentConfig {\n API_BASE_URL: string;\n APP_ENV: 'development' | 'production';\n DEBUG: boolean;\n}\n\n// Environment configuration with fallbacks\ndeclare global {\n interface Window {\n __AINAMIKA_CONFIG__?: EnvironmentConfig;\n }\n}\n\n// Get environment configuration\nfunction getEnvironmentConfig(): EnvironmentConfig {\n // Check for explicitly set configuration\n if (typeof window !== 'undefined' && window.__AINAMIKA_CONFIG__) {\n return window.__AINAMIKA_CONFIG__;\n }\n\n // Default configuration based on hostname\n const isLocal = typeof window !== 'undefined' && \n (window.location.hostname === 'localhost' || window.location.hostname === '127.0.0.1');\n \n return {\n API_BASE_URL: isLocal ? 'http://localhost:5000' : 'https://ainamika-backend-768143418383.europe-west1.run.app',\n APP_ENV: isLocal ? 'development' : 'production',\n DEBUG: isLocal\n };\n}\n\nexport const ENV_CONFIG = getEnvironmentConfig();\n\n// API endpoint configuration\nexport const API_ENDPOINTS = {\n EVENTS: `${ENV_CONFIG.API_BASE_URL}/api/v1/events`,\n ERRORS: `${ENV_CONFIG.API_BASE_URL}/api/errors/report`,\n CONFIG: `${ENV_CONFIG.API_BASE_URL}/api/v1/sdk/config`,\n DEBUG_EVENTS: `${ENV_CONFIG.API_BASE_URL}/api/v1/debug/events`\n};\n\n// Configuration helper function\nexport function configureSDK(config: Partial<EnvironmentConfig>) {\n if (typeof window !== 'undefined') {\n window.__AINAMIKA_CONFIG__ = { ...ENV_CONFIG, ...config };\n }\n}\n\n// Log configuration for debugging\nif (ENV_CONFIG.DEBUG) {\n console.log('[Ainamika SDK] Environment Configuration:', {\n API_BASE_URL: ENV_CONFIG.API_BASE_URL,\n APP_ENV: ENV_CONFIG.APP_ENV,\n DEBUG: ENV_CONFIG.DEBUG,\n ENDPOINTS: API_ENDPOINTS\n });\n}","// error-storage.ts - Offline Storage and Queue Management for Error Tracking\nimport { API_ENDPOINTS } from './config';\n\nexport interface StoredError {\n id: string;\n errorData: any;\n timestamp: number;\n retryCount: number;\n lastRetry?: number;\n}\n\nexport interface StorageConfig {\n maxStorageSize: number;\n maxRetries: number;\n retryInterval: number;\n compressionEnabled: boolean;\n encryptionEnabled: boolean;\n}\n\nexport class ErrorStorage {\n private config: StorageConfig;\n private readonly STORAGE_KEY = 'ainamika_error_queue';\n private readonly METADATA_KEY = 'ainamika_error_metadata';\n private retryTimer?: number;\n private isProcessing = false;\n\n constructor(config: Partial<StorageConfig> = {}) {\n this.config = {\n maxStorageSize: 5 * 1024 * 1024, // 5MB\n maxRetries: 5,\n retryInterval: 30000, // 30 seconds\n compressionEnabled: true,\n encryptionEnabled: false,\n ...config\n };\n\n this.initialize();\n }\n\n private initialize() {\n this.cleanupOldErrors();\n this.startRetryTimer();\n this.setupStorageListener();\n \n // Process any existing errors on initialization\n setTimeout(() => this.processQueue(), 1000);\n }\n\n /**\n * Store error data with automatic compression and queue management\n */\n public async storeError(errorData: any): Promise<string> {\n try {\n const errorId = this.generateErrorId();\n const storedError: StoredError = {\n id: errorId,\n errorData: this.config.compressionEnabled ? this.compressData(errorData) : errorData,\n timestamp: Date.now(),\n retryCount: 0\n };\n\n await this.addToQueue(storedError);\n this.updateMetadata();\n \n // Trigger immediate processing\n setTimeout(() => this.processQueue(), 100);\n \n return errorId;\n } catch (error) {\n console.error('[AInamika Error Storage] Failed to store error:', error);\n throw error;\n }\n }\n\n /**\n * Get all stored errors\n */\n public getStoredErrors(): StoredError[] {\n try {\n const stored = localStorage.getItem(this.STORAGE_KEY);\n if (!stored) return [];\n \n const errors = JSON.parse(stored) as StoredError[];\n return errors.map(error => ({\n ...error,\n errorData: this.config.compressionEnabled ? this.decompressData(error.errorData) : error.errorData\n }));\n } catch (error) {\n console.error('[AInamika Error Storage] Failed to get stored errors:', error);\n return [];\n }\n }\n\n /**\n * Remove error from storage\n */\n public removeError(errorId: string): boolean {\n try {\n const errors = this.getQueueRaw();\n const filteredErrors = errors.filter(error => error.id !== errorId);\n \n if (filteredErrors.length !== errors.length) {\n localStorage.setItem(this.STORAGE_KEY, JSON.stringify(filteredErrors));\n this.updateMetadata();\n return true;\n }\n return false;\n } catch (error) {\n console.error('[AInamika Error Storage] Failed to remove error:', error);\n return false;\n }\n }\n\n /**\n * Clear all stored errors\n */\n public clearAll(): void {\n try {\n localStorage.removeItem(this.STORAGE_KEY);\n localStorage.removeItem(this.METADATA_KEY);\n console.log('[AInamika Error Storage] All errors cleared');\n } catch (error) {\n console.error('[AInamika Error Storage] Failed to clear errors:', error);\n }\n }\n\n /**\n * Get storage statistics\n */\n public getStorageStats(): {\n errorCount: number;\n totalSize: number;\n oldestError?: number;\n newestError?: number;\n } {\n try {\n const errors = this.getQueueRaw();\n const totalSize = new Blob([localStorage.getItem(this.STORAGE_KEY) || '']).size;\n \n const timestamps = errors.map(e => e.timestamp).sort();\n \n return {\n errorCount: errors.length,\n totalSize,\n oldestError: timestamps[0],\n newestError: timestamps[timestamps.length - 1]\n };\n } catch (error) {\n console.error('[AInamika Error Storage] Failed to get storage stats:', error);\n return { errorCount: 0, totalSize: 0 };\n }\n }\n\n /**\n * Process the error queue - attempt to send stored errors\n */\n public async processQueue(): Promise<void> {\n if (this.isProcessing) return;\n \n this.isProcessing = true;\n \n try {\n const errors = this.getQueueRaw();\n if (errors.length === 0) return;\n \n console.log(`[AInamika Error Storage] Processing ${errors.length} queued errors`);\n \n for (const storedError of errors) {\n if (storedError.retryCount >= this.config.maxRetries) {\n console.warn(`[AInamika Error Storage] Max retries reached for error ${storedError.id}`);\n this.removeError(storedError.id);\n continue;\n }\n\n // Check retry interval\n if (storedError.lastRetry && \n Date.now() - storedError.lastRetry < this.config.retryInterval) {\n continue;\n }\n\n try {\n const success = await this.sendError(storedError);\n if (success) {\n this.removeError(storedError.id);\n console.log(`[AInamika Error Storage] Successfully sent error ${storedError.id}`);\n } else {\n this.incrementRetryCount(storedError.id);\n }\n } catch (error) {\n console.error(`[AInamika Error Storage] Failed to send error ${storedError.id}:`, error);\n this.incrementRetryCount(storedError.id);\n }\n }\n } finally {\n this.isProcessing = false;\n }\n }\n\n /**\n * Force retry of a specific error\n */\n public async retryError(errorId: string): Promise<boolean> {\n const errors = this.getQueueRaw();\n const error = errors.find(e => e.id === errorId);\n \n if (!error) return false;\n \n try {\n const success = await this.sendError(error);\n if (success) {\n this.removeError(errorId);\n return true;\n } else {\n this.incrementRetryCount(errorId);\n return false;\n }\n } catch (err) {\n console.error(`[AInamika Error Storage] Failed to retry error ${errorId}:`, err);\n this.incrementRetryCount(errorId);\n return false;\n }\n }\n\n private async addToQueue(storedError: StoredError): Promise<void> {\n const errors = this.getQueueRaw();\n errors.push(storedError);\n \n // Check storage size limit\n const serialized = JSON.stringify(errors);\n if (new Blob([serialized]).size > this.config.maxStorageSize) {\n // Remove oldest errors until under limit\n while (errors.length > 0 && new Blob([JSON.stringify(errors)]).size > this.config.maxStorageSize) {\n errors.shift();\n console.warn('[AInamika Error Storage] Removed old error due to size limit');\n }\n }\n \n localStorage.setItem(this.STORAGE_KEY, JSON.stringify(errors));\n }\n\n private getQueueRaw(): StoredError[] {\n try {\n const stored = localStorage.getItem(this.STORAGE_KEY);\n return stored ? JSON.parse(stored) : [];\n } catch (error) {\n console.error('[AInamika Error Storage] Failed to parse stored errors:', error);\n return [];\n }\n }\n\n private incrementRetryCount(errorId: string): void {\n try {\n const errors = this.getQueueRaw();\n const errorIndex = errors.findIndex(e => e.id === errorId);\n \n if (errorIndex !== -1) {\n errors[errorIndex].retryCount++;\n errors[errorIndex].lastRetry = Date.now();\n localStorage.setItem(this.STORAGE_KEY, JSON.stringify(errors));\n }\n } catch (error) {\n console.error('[AInamika Error Storage] Failed to increment retry count:', error);\n }\n }\n\n private async sendError(storedError: StoredError): Promise<boolean> {\n try {\n const errorData = this.config.compressionEnabled ? \n this.decompressData(storedError.errorData) : \n storedError.errorData;\n\n // This should match the ErrorTracker's endpoint configuration\n const endpoint = errorData.endpoint || API_ENDPOINTS.ERRORS;\n const apiKey = errorData.apiKey || '';\n \n const response = await fetch(`${endpoint}/api/v1/errors`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': apiKey ? `Bearer ${apiKey}` : ''\n },\n body: JSON.stringify(errorData)\n });\n\n return response.ok;\n } catch (error) {\n console.error('[AInamika Error Storage] Network error sending stored error:', error);\n return false;\n }\n }\n\n private compressData(data: any): string {\n try {\n // Simple compression using JSON + base64\n const jsonString = JSON.stringify(data);\n return btoa(jsonString);\n } catch (error) {\n console.warn('[AInamika Error Storage] Compression failed, storing uncompressed:', error);\n return data;\n }\n }\n\n private decompressData(compressedData: any): any {\n try {\n if (typeof compressedData === 'string' && compressedData.length > 0) {\n const jsonString = atob(compressedData);\n return JSON.parse(jsonString);\n }\n return compressedData;\n } catch (error) {\n console.warn('[AInamika Error Storage] Decompression failed, returning raw data:', error);\n return compressedData;\n }\n }\n\n private generateErrorId(): string {\n return `error_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;\n }\n\n private cleanupOldErrors(): void {\n try {\n const errors = this.getQueueRaw();\n const cutoffTime = Date.now() - (7 * 24 * 60 * 60 * 1000); // 7 days\n \n const cleanErrors = errors.filter(error => error.timestamp > cutoffTime);\n \n if (cleanErrors.length !== errors.length) {\n localStorage.setItem(this.STORAGE_KEY, JSON.stringify(cleanErrors));\n console.log(`[AInamika Error Storage] Cleaned up ${errors.length - cleanErrors.length} old errors`);\n }\n } catch (error) {\n console.error('[AInamika Error Storage] Failed to cleanup old errors:', error);\n }\n }\n\n private startRetryTimer(): void {\n this.retryTimer = window.setInterval(() => {\n this.processQueue();\n }, this.config.retryInterval);\n }\n\n private setupStorageListener(): void {\n // Listen for storage changes from other tabs\n window.addEventListener('storage', (event) => {\n if (event.key === this.STORAGE_KEY) {\n console.log('[AInamika Error Storage] Storage updated from another tab');\n setTimeout(() => this.processQueue(), 1000);\n }\n });\n\n // Listen for online/offline events\n window.addEventListener('online', () => {\n console.log('[AInamika Error Storage] Network back online, processing queue');\n setTimeout(() => this.processQueue(), 1000);\n });\n\n window.addEventListener('offline', () => {\n console.log('[AInamika Error Storage] Network offline, errors will be queued');\n });\n }\n\n private updateMetadata(): void {\n try {\n const stats = this.getStorageStats();\n const metadata = {\n lastUpdate: Date.now(),\n ...stats\n };\n localStorage.setItem(this.METADATA_KEY, JSON.stringify(metadata));\n } catch (error) {\n console.error('[AInamika Error Storage] Failed to update metadata:', error);\n }\n }\n\n /**\n * Export stored errors for debugging\n */\n public exportErrors(): string {\n try {\n const errors = this.getStoredErrors();\n const exportData = {\n timestamp: Date.now(),\n version: '1.0',\n stats: this.getStorageStats(),\n errors: errors\n };\n return JSON.stringify(exportData, null, 2);\n } catch (error) {\n console.error('[AInamika Error Storage] Failed to export errors:', error);\n return '{}';\n }\n }\n\n /**\n * Import errors from export\n */\n public importErrors(exportData: string): boolean {\n try {\n const data = JSON.parse(exportData);\n if (!data.errors || !Array.isArray(data.errors)) {\n throw new Error('Invalid export format');\n }\n\n this.clearAll();\n \n for (const errorData of data.errors) {\n this.storeError(errorData.errorData);\n }\n \n console.log(`[AInamika Error Storage] Imported ${data.errors.length} errors`);\n return true;\n } catch (error) {\n console.error('[AInamika Error Storage] Failed to import errors:', error);\n return false;\n }\n }\n\n /**\n * Cleanup and destroy the storage instance\n */\n public destroy(): void {\n if (this.retryTimer) {\n clearInterval(this.retryTimer);\n this.retryTimer = undefined;\n }\n \n // Final attempt to process queue\n this.processQueue();\n \n console.log('[AInamika Error Storage] Storage instance destroyed');\n }\n}\n\n/**\n * Utility functions for error storage management\n */\nexport class ErrorStorageUtils {\n /**\n * Get total localStorage usage for AInamika\n */\n static getAinamikaStorageUsage(): { \n totalSize: number; \n errorSize: number; \n otherSize: number; \n } {\n let totalSize = 0;\n let errorSize = 0;\n let otherSize = 0;\n\n for (let key in localStorage) {\n if (localStorage.hasOwnProperty(key)) {\n const size = new Blob([localStorage.getItem(key) || '']).size;\n totalSize += size;\n \n if (key.startsWith('ainamika_error')) {\n errorSize += size;\n } else if (key.startsWith('ainamika_')) {\n otherSize += size;\n }\n }\n }\n\n return { totalSize, errorSize, otherSize };\n }\n\n /**\n * Check if localStorage has enough space\n */\n static checkStorageSpace(requiredBytes: number): boolean {\n try {\n const testKey = 'ainamika_storage_test';\n const testData = 'x'.repeat(Math.min(requiredBytes, 1024 * 1024));\n \n localStorage.setItem(testKey, testData);\n localStorage.removeItem(testKey);\n \n return true;\n } catch (error) {\n return false;\n }\n }\n\n /**\n * Clean up all AInamika storage\n */\n static cleanupAllAinamikaStorage(): void {\n const keysToRemove: string[] = [];\n \n for (let key in localStorage) {\n if (key.startsWith('ainamika_')) {\n keysToRemove.push(key);\n }\n }\n \n keysToRemove.forEach(key => localStorage.removeItem(key));\n console.log(`[AInamika Storage Utils] Cleaned up ${keysToRemove.length} storage keys`);\n }\n\n /**\n * Generate storage report\n */\n static generateStorageReport(): {\n usage: ReturnType<typeof ErrorStorageUtils.getAinamikaStorageUsage>;\n errors: any[];\n metadata: any;\n } {\n const storage = new ErrorStorage();\n \n return {\n usage: ErrorStorageUtils.getAinamikaStorageUsage(),\n errors: storage.getStoredErrors(),\n metadata: storage.getStorageStats()\n };\n }\n}\n","// src/index.ts - Main SDK entry point\nimport { ErrorTracker, ErrorConfig } from './error-tracker';\nimport { ErrorStorage } from './error-storage';\nimport { ENV_CONFIG, API_ENDPOINTS } from './config';\n\ninterface AnalyticsConfig {\n apiKey: string;\n endpoint?: string;\n autoConfig?: boolean;\n batchInterval?: number;\n useWebWorker?: boolean;\n workerPath?: string;\n debug?: boolean;\n clientId: string; // Optional client ID for user tracking\n apiDetails?: {\n apiEndPoint: string;\n headers?: Record<string, string>;\n };\n workerConfig?: {\n batchSize?: number;\n batchInterval?: number;\n };\n errorTracking?: {\n enabled?: boolean;\n captureScreenshots?: boolean;\n captureDomSnapshots?: boolean;\n maxStackTraceDepth?: number;\n maxErrorsPerSession?: number;\n debounceMs?: number;\n enableNetworkTracking?: boolean;\n enableConsoleCapture?: boolean;\n };\n}\n\ninterface EventData {\n event: string;\n properties?: Record<string, any>;\n timestamp?: number;\n userId?: string;\n sessionId?: string;\n}\n\ninterface AutoConfigResult {\n autoTrack: {\n clicks: string[];\n pageViews: boolean;\n formSubmissions: string[];\n customEvents: Record<string, any>;\n };\n metadata: {\n appType: string;\n framework: string;\n confidence: number;\n };\n}\n\nclass AInamikaSDKPro {\n private config: AnalyticsConfig;\n private worker: Worker;\n private sessionId: string;\n private autoConfig?: AutoConfigResult;\n private batchTimer?: number;\n private eventQueue: Map<string, any>[] = [];\n private isInitialized = false;\n private batchRetryCount: number = 0;\n private maxBatchRetries: number = 5;\n\n // --- Error Tracking Components ---\n private errorTracker?: ErrorTracker;\n private errorStorage?: ErrorStorage;\n\n // --- Dynamic DOM Fingerprinting and Smart Debouncing ---\n private domHashCache: Record<string, any> = {};\n private lastDomHash: string = '';\n private lastConfigHash: string = '';\n private mutationDebounceTimer: number | null = null;\n private mutationDebounceMs: number = 2000; // 2s debounce for dynamic DOM\n\n // Track attached event types per element to prevent duplicate listeners\n private attachedListeners: WeakMap<Element, Set<string>> = new WeakMap();\n\n constructor(config: AnalyticsConfig) {\n this.config = {\n endpoint: ENV_CONFIG.API_BASE_URL,\n batchInterval: 5000,\n useWebWorker: true,\n debug: ENV_CONFIG.DEBUG,\n errorTracking: {\n enabled: true,\n captureScreenshots: true,\n captureDomSnapshots: true,\n maxStackTraceDepth: 50,\n maxErrorsPerSession: 100,\n debounceMs: 1000,\n enableNetworkTracking: true,\n enableConsoleCapture: true\n },\n ...config\n };\n\n this.sessionId = this.generateSessionId();\n // Inline the worker code as a Blob to avoid cross-origin issues\n const workerCode = `\n self.eventQueue = [];\n self.config = {\n apiUrl: '',\n batchSize: 10,\n batchInterval: 5000,\n headers: { 'Content-Type': 'application/json' }\n };\n let batchTimer = null;\n function flushQueue() {\n self.postMessage({ status: 'debug', message: '[AInamika Worker] flushQueue called', eventQueue: self.eventQueue, config: self.config });\n if (self.eventQueue.length === 0) return;\n const batch = self.eventQueue.splice(0, self.config.batchSize);\n fetch(self.config.apiUrl, {\n method: 'POST',\n headers: self.config.headers,\n body: JSON.stringify({ events: batch })\n }).then(r => {\n if (r.ok) {\n self.postMessage({ status: 'success' });\n } else {\n self.postMessage({ status: 'error', error: r.statusText, failedEvents: batch });\n }\n }).catch(e => {\n self.postMessage({ status: 'error', error: e.message, failedEvents: batch });\n });\n }\n self.onmessage = function(e) {\n self.postMessage({ status: 'debug', message: '[AInamika Worker] onmessage', data: e.data });\n if (e.data.type === 'config') {\n self.config = { ...self.config, ...e.data.payload };\n if (batchTimer) clearInterval(batchTimer);\n batchTimer = setInterval(flushQueue, self.config.batchInterval);\n self.postMessage({ status: 'debug', message: '[AInamika Worker] config set', config: self.config });\n } else if (e.data.type === 'track') {\n self.eventQueue.push(e.data.payload);\n // Only send when timer triggers, not when batch size is reached\n // This ensures true batching behavior\n } else if (e.data.type === 'batch') {\n // Handle batch flush from main thread\n self.postMessage({ status: 'debug', message: '[AInamika Worker] Received batch from main thread', events: e.data.events });\n self.eventQueue.push(...e.data.events);\n flushQueue();\n } else if (e.data.type === 'initConfig') {\n // No-op for now, can be used for advanced config\n }\n };\n `;\n const blob = new Blob([workerCode], { type: 'application/javascript' });\n const workerUrl = URL.createObjectURL(blob);\n this.worker = new Worker(workerUrl);\n this.initialize();\n }\n\n private async initialize() {\n if (this.isInitialized) return;\n this.isInitialized = true;\n\n // Initialize Error Tracking\n if (this.config.errorTracking?.enabled) {\n this.initializeErrorTracking();\n }\n\n if (this.config.autoConfig) {\n await this.setupAutoConfiguration();\n }\n\n // Always enable dynamic DOM tracking for dynamic apps\n this.setupDynamicDomTracking();\n\n if (this.config.useWebWorker && typeof Worker !== 'undefined') {\n this.setupWebWorker();\n } else {\n // Fallback for environments without web workers\n this.startBatchTimer();\n }\n this.log('AnalyticsPro SDK initialized', { config: this.config });\n }\n\n // --- Error Tracking Initialization ---\n private initializeErrorTracking() {\n try {\n // Initialize error storage\n this.errorStorage = new ErrorStorage({\n maxStorageSize: 5 * 1024 * 1024, // 5MB\n maxRetries: 5,\n retryInterval: 30000, // 30 seconds\n compressionEnabled: true,\n encryptionEnabled: false\n });\n\n // Initialize error tracker\n const errorConfig: ErrorConfig = {\n endpoint: ENV_CONFIG.API_BASE_URL,\n clientId: this.config.clientId,\n apiKey: this.config.apiKey,\n captureScreenshots: this.config.errorTracking?.captureScreenshots ?? true,\n captureDomSnapshots: this.config.errorTracking?.captureDomSnapshots ?? true,\n maxStackTraceDepth: this.config.errorTracking?.maxStackTraceDepth ?? 50,\n maxErrorsPerSession: this.config.errorTracking?.maxErrorsPerSession ?? 100,\n debounceMs: this.config.errorTracking?.debounceMs ?? 1000,\n enableNetworkTracking: this.config.errorTracking?.enableNetworkTracking ?? true,\n enableConsoleCapture: this.config.errorTracking?.enableConsoleCapture ?? true\n };\n\n this.errorTracker = new ErrorTracker(errorConfig);\n \n // Set user for error tracking if available\n const userId = this.getUserId();\n if (userId && this.errorTracker) {\n this.errorTracker.setUser(userId);\n }\n\n this.log('Error tracking initialized successfully');\n } catch (error) {\n console.error('[AInamika SDK] Failed to initialize error tracking:', error);\n }\n }\n\n // Public method to capture custom exceptions\n public captureException(error: Error, context?: Record<string, any>) {\n if (this.errorTracker) {\n this.errorTracker.captureException(error, context);\n }\n }\n\n // Public method to set user for error tracking\n public setUser(userId: string) {\n if (this.errorTracker) {\n this.errorTracker.setUser(userId);\n }\n }\n\n // Public method to flush stored errors\n public async flushStoredErrors() {\n if (this.errorStorage) {\n await this.errorStorage.processQueue();\n }\n if (this.errorTracker) {\n await this.errorTracker.flushStoredErrors();\n }\n }\n\n private async setupAutoConfiguration() {\n try {\n this.log('Starting auto-configuration...');\n // Compute current DOM structure and hash\n const domStructure = await this.getDOMStructure();\n const domHash = this.computeDomHash(domStructure);\n this.lastDomHash = domHash; // Store the initial DOM hash\n \n // Try to load config from localStorage cache first using DOM hash\n let generatedConfig = this.getCachedConfigForDomHash(domHash);\n \n if (generatedConfig) {\n this.log('Loaded analytics config from localStorage cache for DOM hash:', domHash);\n } else {\n // Try to load config from file as fallback\n generatedConfig = await this.loadConfigFromFile();\n if (generatedConfig) {\n this.log('Loaded analytics config from file');\n }\n }\n \n if (!generatedConfig) {\n // Only call API if not found in cache or file, and include DOM hash\n this.log('No cached config found, fetching from backend for DOM hash:', domHash);\n generatedConfig = await this.fetchGeneratedConfig(domStructure, domHash);\n if (generatedConfig && generatedConfig.events_to_track) {\n this.saveConfigToFile(generatedConfig);\n this.setCachedConfigForDomHash(domHash, generatedConfig);\n this.lastConfigHash = generatedConfig.config_hash || '';\n }\n }\n \n if (generatedConfig && generatedConfig.events_to_track) {\n this.applyGeneratedConfig(generatedConfig);\n // Send config to worker for advanced tracking (scroll, focus, etc.)\n if (this.config.useWebWorker && typeof Worker !== 'undefined') {\n this.worker.postMessage({ type: 'initConfig', config: generatedConfig });\n }\n this.log('Auto-configuration applied successfully', generatedConfig);\n } else {\n this.log('Auto-configuration failed: Invalid config received from backend.', generatedConfig);\n }\n } catch (error) {\n this.log('Auto-configuration failed with error', error);\n }\n }\n\n private async getDOMStructure(): Promise<any> {\n const getSelector = (el: Element): string => {\n if (el.id) return `#${el.id}`;\n if (el.className) {\n const classes = el.className.split(' ').filter(c => c.trim()).join('.');\n return classes ? `.${classes}` : el.tagName.toLowerCase();\n }\n return el.tagName.toLowerCase();\n };\n\n // Wait a bit for any dynamic content to load\n await new Promise(resolve => setTimeout(resolve, 500));\n\n // Comprehensive selector for all interactive and important elements\n const elements = Array.from(document.body.querySelectorAll(`\n button, a, input, select, textarea, form, img, h1, h2, h3, h4, h5, h6,\n [role=button], [role=link], [onclick], [tabindex], [data-analytics], [data-track],\n .card, .btn, .btn-primary, .btn-secondary, .card-title, .card-description, .card-price, .card-actions,\n [id*=\"card\"], [class*=\"card\"], [class*=\"btn\"], [class*=\"price\"], [class*=\"title\"],\n div, span, p\n `));\n\n // Filter and enhance elements with more comprehensive logic\n const filteredElements = elements.filter(el => {\n const style = window.getComputedStyle(el);\n const isVisible = style.display !== 'none' && style.visibility !== 'hidden' && style.opacity !== '0';\n const hasInteraction = el.tagName.toLowerCase() === 'button' || \n el.tagName.toLowerCase() === 'a' || \n el.hasAttribute('onclick') ||\n el.getAttribute('role') === 'button' ||\n el.classList.contains('btn') ||\n el.classList.contains('card');\n const isImportantElement = el.id === 'cardsContainer' || \n el.classList.contains('cards-grid') ||\n el.classList.contains('card') ||\n el.tagName.toLowerCase() === 'img' ||\n ['h1', 'h2', 'h3'].indexOf(el.tagName.toLowerCase()) !== -1;\n \n return (isVisible && (hasInteraction || isImportantElement)) || el.id === 'cardsContainer';\n });\n\n // Deduplicate and add stable metadata (exclude dynamic properties)\n const seen = new Set<string>();\n const structure = filteredElements.map(el => {\n // Only include stable attributes that don't change between page loads\n const stableAttributes: Record<string, string> = {};\n Array.from(el.attributes).forEach(attr => {\n // Exclude dynamic attributes that might change\n if (['style', 'data-timestamp', 'data-rendered'].indexOf(attr.name) === -1) {\n stableAttributes[attr.name] = attr.value;\n }\n });\n \n const obj = {\n tagName: el.tagName.toLowerCase(),\n selector: getSelector(el),\n id: el.id || '',\n className: el.className || '',\n textContent: (el.textContent || '').trim().substring(0, 100),\n attributes: stableAttributes,\n // Remove position and computed styles as they can vary\n isInteractive: el.tagName.toLowerCase() === 'button' || \n el.tagName.toLowerCase() === 'a' || \n el.hasAttribute('onclick') ||\n el.getAttribute('role') === 'button' ||\n el.classList.contains('btn'),\n hasChildren: el.children.length > 0,\n childCount: el.children.length,\n // Add stable structural information\n parentTagName: el.parentElement?.tagName.toLowerCase() || '',\n index: Array.from(el.parentElement?.children || []).indexOf(el)\n };\n return obj;\n }).filter(obj => {\n const key = obj.tagName + '|' + obj.selector + '|' + obj.textContent.substring(0, 20);\n if (seen.has(key)) return false;\n seen.add(key);\n return true;\n });\n\n this.log('DOM structure analyzed', { elementCount: structure.length, elements: structure });\n return { elements: structure };\n }\n\n private async fetchGeneratedConfig(structure: any, domHash?: string): Promise<any> {\n try {\n if(structure && structure.elements && structure.elements.length === 0) {\n this.log('No elements found in DOM structure, skipping config fetch.');\n return null;\n }\n \n const requestBody: any = { structure };\n if (domHash) {\n requestBody.domHash = domHash;\n requestBody.lastConfigHash = this.lastConfigHash;\n }\n \n const response = await fetch(API_ENDPOINTS.CONFIG, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'X-Tenant-ID': this.config.clientId,\n },\n body: JSON.stringify(requestBody),\n });\n\n if (!response.ok) {\n throw new Error(`Backend returned ${response.status}`);\n }\n return await response.json();\n } catch (error) {\n this.log('Error fetching generated config:', error);\n return null;\n }\n }\n\n private applyGeneratedConfig(config: { events_to_track: any[], observe_mutations?: boolean }) {\n config.events_to_track.forEach(eventToTrack => {\n try {\n const elements = document.querySelectorAll(eventToTrack.element_selector);\n if (elements.length > 0) {\n elements.forEach(element => {\n // Prevent multiple listeners for the same event type on the same element\n let eventSet = this.attachedListeners.get(element);\n if (!eventSet) {\n eventSet = new Set();\n this.attachedListeners.set(element, eventSet);\n }\n \n // Handle array of event types\n const eventTypes = Array.isArray(eventToTrack.event_type) ? eventToTrack.event_type : [eventToTrack.event_type];\n \n eventTypes.forEach((eventType: string) => {\n if (eventSet.has(eventType)) return;\n eventSet.add(eventType);\n \n // Click events\n if (eventType === 'click') {\n element.addEventListener('click', (event: Event) => {\n // Don't prevent default for this demo, let buttons work normally\n const target = event.target as HTMLElement;\n const elementData = this.extractElementData(target);\n \n this.sendToWorker(eventToTrack.event_name, {\n selector: eventToTrack.element_selector,\n eventType: 'click',\n element: elementData,\n timestamp: new Date().toISOString()\n });\n });\n this.log(`Attached click listener for \"${eventToTrack.event_name}\" on \"${eventToTrack.element_selector}\"`);\n }\n \n // View events using IntersectionObserver\n if (eventType === 'view') {\n if ('IntersectionObserver' in window) {\n const observer = new IntersectionObserver((entries) => {\n entries.forEach(entry => {\n if (entry.isIntersecting) {\n const target = entry.target as HTMLElement;\n const elementData = this.extractElementData(target);\n \n this.sendToWorker(eventToTrack.event_name, {\n selector: eventToTrack.element_selector,\n eventType: 'view',\n element: elementData,\n intersectionRatio: entry.intersectionRatio,\n timestamp: new Date().toISOString()\n });\n }\n });\n }, { threshold: [0.1, 0.5, 1.0] });\n observer.observe(element);\n this.log(`Attached IntersectionObserver for \"${eventToTrack.event_name}\" on \"${eventToTrack.element_selector}\"`);\n }\n }\n \n // Focus/blur tracking\n if (eventType === 'focus' || eventType === 'blur') {\n element.addEventListener(eventType, () => {\n const target = element as HTMLElement;\n const elementData = this.extractElementData(target);\n \n this.sendToWorker(eventToTrack.event_name, {\n selector: eventToTrack.element_selector,\n eventType: eventType,\n element: elementData,\n timestamp: new Date().toISOString()\n });\n });\n this.log(`Attached ${eventType} listener for \"${eventToTrack.event_name}\" on \"${eventToTrack.element_selector}\"`);\n }\n });\n });\n } else {\n this.log(`No elements found for selector: \"${eventToTrack.element_selector}\"`);\n }\n } catch (e) {\n this.log(`Error applying selector \"${eventToTrack.element_selector}\":`, e);\n }\n });\n\n // MutationObserver for DOM changes (if requested by config)\n if (config.observe_mutations) {\n if ('MutationObserver' in window) {\n const observer = new MutationObserver((mutations) => {\n mutations.forEach(mutation => {\n this.sendToWorker('dom_mutation', {\n type: mutation.type,\n target: (mutation.target as HTMLElement).outerHTML,\n timestamp: new Date().toISOString()\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n this.log('MutationObserver attached for DOM changes');\n }\n }\n }\n\n private extractElementData(element: HTMLElement): any {\n const rect = element.getBoundingClientRect();\n return {\n tagName: element.tagName.toLowerCase(),\n id: element.id || '',\n className: element.className || '',\n textContent: (element.textContent || '').trim().substring(0, 100),\n attributes: Array.from(element.attributes).reduce((acc, attr) => {\n acc[attr.name] = attr.value;\n return acc;\n }, {} as Record<string, string>),\n position: {\n x: Math.round(rect.x),\n y: Math.round(rect.y),\n width: Math.round(rect.width),\n height: Math.round(rect.height)\n },\n href: (element as HTMLAnchorElement).href || undefined,\n value: (element as HTMLInputElement).value || undefined\n };\n }\n\n // Helper to send events to worker for batching\n private sendToWorker(eventName: string, properties: Record<string, any>) {\n const eventData: any = {\n event: eventName,\n properties,\n timestamp: Date.now(),\n userId: this.getUserId(),\n sessionId: this.sessionId,\n client_id: this.config.clientId || '5288aa7d-1b7c-481e-958d-eb9b8e951f14' // Ensure client_id is always present\n };\n if (this.config.useWebWorker && typeof Worker !== 'undefined') {\n this.worker.postMessage({ type: 'track', payload: eventData });\n } else {\n this.eventQueue.push(eventData);\n }\n this.log('Event tracked:', eventData);\n }\n\n private setupWebWorker() {\n // Pass worker config to the worker\n this.worker.postMessage({\n type: 'config',\n payload: {\n apiUrl: this.config.apiDetails?.apiEndPoint || `${this.config.endpoint}/api/v1/events`,\n batchSize: this.config.workerConfig?.batchSize || 10,\n batchInterval: this.config.workerConfig?.batchInterval || 5000,\n headers: this.config.apiDetails?.headers || { 'Content-Type': 'application/json' },\n }\n });\n this.worker.onmessage = (event) => {\n if (event.data.status === 'success') {\n this.log('Batch sent successfully by worker');\n // Don't re-queue failed events since we already cleared the queue\n } else if (event.data.status === 'debug') {\n this.log(event.data.message, event.data);\n } else if (event.data.status === 'error') {\n this.log('Worker failed to send batch', event.data.error);\n // Re-queue failed events only if we have them\n if (event.data.failedEvents && event.data.failedEvents.length > 0) {\n this.eventQueue.unshift(...event.data.failedEvents);\n }\n }\n };\n this.log('Web worker setup complete.');\n }\n\n public track(eventName: string, properties: Record<string, any> = {}) {\n const eventData: any = {\n event: eventName,\n properties,\n timestamp: Date.now(),\n userId: this.getUserId(),\n sessionId: this.sessionId,\n client_id: this.config.clientId || '5288aa7d-1b7c-481e-958d-eb9b8e951f14' // Ensure client_id is always present\n };\n\n // Use the same batching logic as sendToWorker\n if (this.config.useWebWorker && typeof Worker !== 'undefined') {\n this.worker.postMessage({ type: 'track', payload: eventData });\n } else {\n this.eventQueue.push(eventData);\n }\n this.log('Event tracked public:', eventData);\n }\n\n private startBatchTimer() {\n this.batchTimer = window.setInterval(() => {\n this.flushQueue();\n }, this.config.batchInterval);\n }\n\n private async flushQueue() {\n if (this.eventQueue.length === 0) {\n return;\n }\n\n const batch = [...this.eventQueue];\n // Clear the queue immediately to prevent duplicates\n this.eventQueue = [];\n\n if (this.config.useWebWorker && typeof Worker !== 'undefined') {\n this.worker.postMessage({\n type: 'batch',\n events: batch,\n endpoint: `${this.config.endpoint}/api/v1/events`,\n });\n } else {\n // Fallback send mechanism with retry logic\n await this.sendBatchWithRetry(batch);\n }\n }\n\n private async sendBatchWithRetry(batch: Map<string, any>[]) {\n if (this.batchRetryCount >= this.maxBatchRetries) {\n if (this.batchTimer) {\n clearInterval(this.batchTimer);\n this.batchTimer = undefined;\n this.log('Max batch retries reached. BatchTimer cancelled.');\n }\n return;\n }\n try {\n await this.sendBatch(batch);\n // On success, reset retry count (queue already cleared in flushQueue)\n this.batchRetryCount = 0;\n } catch (error) {\n this.batchRetryCount++;\n this.log(`Batch send failed. Retry attempt ${this.batchRetryCount} of ${this.maxBatchRetries}.`, error);\n // Re-queue the failed batch for retry\n this.eventQueue.unshift(...batch);\n if (this.batchRetryCount >= this.maxBatchRetries) {\n if (this.batchTimer) {\n clearInterval(this.batchTimer);\n this.batchTimer = undefined;\n this.log('Max batch retries reached. BatchTimer cancelled.');\n }\n }\n }\n }\n\n // Update sendBatch to support client db endpoint and headers\n private async sendBatch(batch: Map<string, any>[]) {\n let endpoint = `${this.config.endpoint}/api/v1/events`;\n let headers: Record<string, string> = { 'Content-Type': 'application/json' };\n if (this.config.apiDetails && this.config.apiDetails.apiEndPoint) {\n endpoint = this.config.apiDetails.apiEndPoint;\n if (this.config.apiDetails.headers) {\n headers = { ...headers, ...this.config.apiDetails.headers };\n }\n }\n // Transform batch to required format\n const clientId = this.config.clientId || '5288aa7d-1b7c-481e-958d-eb9b8e951f14';\n const events = batch.map((e: any) => ({\n event: e.event, // keep 'event' key\n userId: e.userId,\n client_id: clientId,\n timestamp: new Date(e.timestamp).toISOString(),\n ...(e.properties || {})\n }));\n try {\n const response = await fetch(endpoint, {\n method: 'POST',\n headers,\n body: JSON.stringify({ events }),\n });\n if (!response.ok) {\n throw new Error(`Failed to send batch: ${response.status}`);\n }\n this.log('Batch sent successfully:', events);\n } catch (error) {\n this.log('Error sending batch:', error);\n throw error; // Let sendBatchWithRetry handle re-queuing\n }\n }\n\n private generateSessionId(): string {\n // Simple session ID generator (could be improved)\n return 'sess_' + Math.random().toString(36).substr(2, 9);\n }\n\n private getUserId(): string {\n // Placeholder for user ID logic (e.g., from cookies, localStorage, or auth context)\n return 'user_' + Math.random().toString(36).substr(2, 9);\n }\n\n private log(message: string, data?: any) {\n if (this.config.debug) {\n console.log(`[AnalyticsPro SDK] ${message}`, data || '');\n }\n }\n\n // Save config as a downloadable JSON file\nprivate saveConfigToFile(config: any) {\n if(!this.config.debug){\n return;\n }\n // const fileName = 'AInamika_config.json';\n // const json = JSON.stringify(config, null, 2);\n // const blob = new Blob([json], { type: 'application/json' });\n // const link = document.createElement('a');\n // link.href = URL.createObjectURL(blob);\n // link.download = fileName;\n // document.body.appendChild(link);\n // link.click();\n // document.body.removeChild(link);\n}\n\n// Load config from /AInamika_config.json in the project root\nprivate async loadConfigFromFile(): Promise<any | null> {\n try {\n const response = await fetch('/AInamika_config.json', { cache: 'reload' });\n if (!response.ok) {\n return null;\n }\n const config = await response.json();\n return config;\n } catch (err) {\n return null;\n }\n}\n\n// --- Dynamic DOM Fingerprinting and Smart Debouncing ---\nprivate async setupDynamicDomTracking() {\n // Use MutationObserver to watch for DOM changes\n if ('MutationObserver' in window) {\n const observer = new MutationObserver(() => {\n if (this.mutationDebounceTimer) {\n clearTimeout(this.mutationDebounceTimer);\n }\n this.mutationDebounceTimer = window.setTimeout(() => {\n this.handleDomMutation();\n }, this.mutationDebounceMs);\n });\n observer.observe(document.body, { childList: true, subtree: true, attributes: true });\n this.log('Dynamic DOM MutationObserver attached');\n }\n}\n\nprivate computeDomHash(structure: any): string {\n // Simple hash: JSON.stringify, then a basic hash (FNV-1a or similar)\n const str = JSON.stringify(structure);\n let hash = 2166136261;\n for (let i = 0; i < str.length; i++) {\n hash ^= str.charCodeAt(i);\n hash += (hash << 1) + (hash << 4) + (hash << 7) + (hash << 8) + (hash << 24);\n }\n return (hash >>> 0).toString(16);\n}\n\nprivate getCachedConfigForDomHash(domHash: string): any | null {\n try {\n const cache = JSON.parse(localStorage.getItem('ainamika_dom_config_cache') || '{}');\n return cache[domHash] || null;\n } catch {\n return null;\n }\n}\n\nprivate setCachedConfigForDomHash(domHash: string, config: any) {\n try {\n const cache = JSON.parse(localStorage.getItem('ainamika_dom_config_cache') || '{}');\n cache[domHash] = config;\n localStorage.setItem('ainamika_dom_config_cache', JSON.stringify(cache));\n } catch {}\n}\n\nprivate async handleDomMutation() {\n const domStructure = await this.getDOMStructure();\n const domHash = this.computeDomHash(domStructure);\n \n if (domHash === this.lastDomHash) {\n this.log('DOM hash unchanged after mutation, skipping config fetch.');\n return;\n }\n \n this.log('DOM hash changed, checking for cached config...', { oldHash: this.lastDomHash, newHash: domHash });\n this.lastDomHash = domHash;\n \n const cachedConfig = this.getCachedConfigForDomHash(domHash);\n if (cachedConfig) {\n this.log('Reusing cached config for DOM hash', domHash);\n this.applyGeneratedConfig(cachedConfig);\n return;\n }\n \n // Send to server: domStructure with domHash and lastConfigHash\n this.log('Fetching new config from backend for DOM hash:', domHash);\n const config = await this.fetchGeneratedConfig(domStructure, domHash);\n if (config && config.events_to_track) {\n this.applyGeneratedConfig(config);\n this.setCachedConfigForDomHash(domHash, config);\n this.lastConfigHash = config.config_hash || '';\n this.log('Fetched and applied new config for new DOM hash', domHash);\n } else {\n this.log('No valid config returned for new DOM hash', domHash);\n }\n}\n}\n\n// Make AnalyticsProSDK available globally for both classic and module scripts\nif (typeof window !== 'undefined') {\n (window as any).AInamikaSDKPro = AInamikaSDKPro;\n}\n\nexport default AInamikaSDKPro;\nexport { AInamikaSDKPro };"],"names":["root","factory","exports","module","define","amd","self","window","global","this","__webpack_require__","definition","key","o","Object","defineProperty","enumerable","get","obj","prop","prototype","hasOwnProperty","call","config","breadcrumbs","errorCount","errorDebounceMap","Map","captureScreenshots","captureDomSnapshots","maxStackTraceDepth","maxErrorsPerSession","debounceMs","enableNetworkTracking","enableConsoleCapture","sessionId","generateSessionId","originalConsole","console","initialize","addEventListener","event","handleError","type","message","filename","line","lineno","column","colno","error","reason","promise","setupNetworkTracking","setupConsoleCapture","setupNavigationTracking","setupClickTracking","log","Date","now","Math","random","toString","substr","addBreadcrumb","breadcrumb","push","timestamp","length","slice","errorInfo","warn","errorKey","has","set","captureError","errorData","client_id","clientId","error_type","stack_trace","extractStackTrace","url","location","href","user_agent","navigator","userAgent","error_metadata","userId","networkInfo","getNetworkInfo","performance","getPerformanceInfo","severity","assessSeverity","session_id","user_id","dom_snapshot","captureDomSnapshot","captureScreenshot","screen_snapshot","sendError","data","stack","split","maxDepth","join","toLowerCase","includes","snapshot","title","document","viewport","width","innerWidth","height","innerHeight","elements","extractDomElements","JSON","stringify","forEach","selector","els","querySelectorAll","Array","from","el","tagName","id","className","textContent","substring","attributes","getElementAttributes","e","element","attrs","attr","value","getAttribute","html2canvas","body","min","useCORS","toDataURL","connection","mozConnection","webkitConnection","effectiveType","downlink","rtt","saveData","info","memory","usedJSHeapSize","totalJSHeapSize","jsHeapSizeLimit","timing","domContentLoaded","domContentLoadedEventEnd","navigationStart","load","loadEventEnd","getEntriesByType","entry","name","firstPaint","startTime","firstContentfulPaint","originalFetch","fetch","args","Request","String","response","status","duration","ok","statusText","originalXHROpen","XMLHttpRequest","open","originalXHRSend","send","method","async","username","password","_errorTracker","tracker","dispatchEvent","CustomEvent","detail","original","map","arg","consoleMethod","level","currentUrl","trackNavigation","newUrl","to","originalPushState","history","pushState","originalReplaceState","replaceState","apply","setTimeout","target","getElementSelector","text","trim","classes","filter","c","endpoint","headers","apiKey","Error","storeErrorLocally","stored","localStorage","getItem","errors","parse","splice","setItem","captureException","context","setUser","addTag","flushStoredErrors","removeItem","ENV_CONFIG","__AINAMIKA_CONFIG__","isLocal","hostname","API_BASE_URL","APP_ENV","DEBUG","getEnvironmentConfig","API_ENDPOINTS","EVENTS","ERRORS","CONFIG","DEBUG_EVENTS","ENDPOINTS","STORAGE_KEY","METADATA_KEY","isProcessing","maxStorageSize","maxRetries","retryInterval","compressionEnabled","encryptionEnabled","cleanupOldErrors","startRetryTimer","setupStorageListener","processQueue","storeError","errorId","generateErrorId","storedError","compressData","retryCount","addToQueue","updateMetadata","getStoredErrors","decompressData","removeError","getQueueRaw","filteredErrors","clearAll","getStorageStats","totalSize","Blob","size","timestamps","sort","oldestError","newestError","lastRetry","incrementRetryCount","retryError","find","serialized","shift","errorIndex","findIndex","jsonString","btoa","compressedData","atob","cleanErrors","retryTimer","setInterval","stats","metadata","lastUpdate","exportErrors","exportData","version","importErrors","isArray","destroy","clearInterval","undefined","getAinamikaStorageUsage","errorSize","otherSize","startsWith","checkStorageSpace","requiredBytes","testKey","testData","repeat","cleanupAllAinamikaStorage","keysToRemove","generateStorageReport","storage","ErrorStorage","usage","ErrorStorageUtils","eventQueue","isInitialized","batchRetryCount","maxBatchRetries","domHashCache","lastDomHash","lastConfigHash","mutationDebounceTimer","mutationDebounceMs","attachedListeners","WeakMap","batchInterval","useWebWorker","debug","errorTracking","enabled","blob","workerUrl","URL","createObjectURL","worker","Worker","initializeErrorTracking","autoConfig","setupAutoConfiguration","setupDynamicDomTracking","setupWebWorker","startBatchTimer","errorStorage","errorConfig","errorTracker","ErrorTracker","getUserId","getDOMStructure","domStructure","domHash","computeDomHash","generatedConfig","getCachedConfigForDomHash","loadConfigFromFile","fetchGeneratedConfig","events_to_track","saveConfigToFile","setCachedConfigForDomHash","config_hash","applyGeneratedConfig","postMessage","getSelector","Promise","resolve","filteredElements","style","getComputedStyle","isVisible","display","visibility","opacity","hasInteraction","hasAttribute","classList","contains","isImportantElement","indexOf","seen","Set","structure","stableAttributes","isInteractive","hasChildren","children","childCount","parentTagName","parentElement","index","add","elementCount","requestBody","json","eventToTrack","element_selector","eventSet","event_type","eventType","elementData","extractElementData","sendToWorker","event_name","toISOString","IntersectionObserver","entries","isIntersecting","intersectionRatio","threshold","observe","observe_mutations","MutationObserver","mutations","mutation","outerHTML","childList","subtree","rect","getBoundingClientRect","reduce","acc","position","x","round","y","eventName","properties","eventData","payload","apiUrl","apiDetails","apiEndPoint","batchSize","workerConfig","onmessage","failedEvents","unshift","track","batchTimer","flushQueue","batch","events","sendBatchWithRetry","sendBatch","cache","clearTimeout","handleDomMutation","str","hash","i","charCodeAt","oldHash","newHash","cachedConfig","AInamikaSDKPro"],"sourceRoot":""}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ainamika-sdk",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.5",
|
|
4
4
|
"description": "Advanced AI-powered analytics SDK with error tracking, event management, and real-time insights for web applications",
|
|
5
5
|
"main": "dist/ainamika-sdk.js",
|
|
6
6
|
"types": "dist/sdk.d.ts",
|
|
@@ -28,14 +28,14 @@
|
|
|
28
28
|
],
|
|
29
29
|
"author": {
|
|
30
30
|
"name": "Adarsh Singh",
|
|
31
|
-
"email": "
|
|
31
|
+
"email": "adarshsingh061295@gmail.com"
|
|
32
32
|
},
|
|
33
33
|
"license": "MIT",
|
|
34
34
|
"repository": {
|
|
35
35
|
"type": "git",
|
|
36
36
|
"url": "https://github.com/adarshsingh/ainamika-sdk.git"
|
|
37
37
|
},
|
|
38
|
-
"homepage": "https://ainamika.
|
|
38
|
+
"homepage": "https://ainamika.netlify.app/about.html",
|
|
39
39
|
"bugs": {
|
|
40
40
|
"url": "https://github.com/adarshsingh/ainamika-sdk/issues"
|
|
41
41
|
},
|