├── .npmignore
├── CHANGELOG.md
├── README.md
├── atatus.d.ts
├── atatus.min.js
├── bower.json
├── component.json
└── package.json
/.npmignore:
--------------------------------------------------------------------------------
1 | bower.json
2 | component.json
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | Changelog
2 | =========
3 |
4 | 4.6.4
5 | -----
6 |
7 | - Add support for max duplicate errors option.
8 |
9 |
10 | 4.6.3
11 | -----
12 |
13 | - Fix status code in Ajax abort failures.
14 |
15 |
16 | 4.6.2
17 | -----
18 |
19 | - Add support for `onTransformRouteUrl` callback.
20 |
21 |
22 | 4.6.1
23 | -----
24 |
25 | - Add support for INP web vital.
26 |
27 |
28 | 4.6.0
29 | -----
30 |
31 | - Add timestamp support in XHR calls.
32 |
33 |
34 | 4.5.0
35 | -----
36 |
37 | - Fixed fetch failure exceptions.
38 | - Fixed XHR payload sending.
39 |
40 |
41 | 4.4.1
42 | -----
43 |
44 | - Fixed ignored urls.
45 |
46 |
47 | 4.4.0
48 | -----
49 |
50 | - Fixed web vitals sending issue during page unload.
51 | - Fixed higher XHR timing issue.
52 |
53 |
54 | 4.3.2
55 | -----
56 |
57 | - Fixed web vitals issue in ES6 and Require.js modules.
58 | - Updated collector endpoint.
59 |
60 |
61 | 4.3.1
62 | -----
63 |
64 | - Fixed web vitals support for not supporting browser.
65 |
66 |
67 | 4.3.0
68 | -----
69 |
70 | - Added web vitals support.
71 |
72 |
73 | 4.2.1
74 | -----
75 |
76 | - Updated typescript definition file for setHashRoutes, setWhitelistUrls and setIgnoreUrls.
77 |
78 |
79 | 4.2.0
80 | -----
81 |
82 | - Limit number of payloads sent to Atatus server.
83 | - Added limit to breadcrumb messages.
84 | - Added separate version to SPA.
85 | - Added support for network information.
86 | - Added support for detailed timing metrics.
87 | - Added support for hash route options.
88 |
89 |
90 | 4.1.1
91 | -----
92 |
93 | - Fixed sending page load two times.
94 |
95 |
96 | 4.1.0
97 | -----
98 |
99 | - Sent session data in XHR instead of query parameter.
100 | - Added SameSite=None in cookie.
101 |
102 |
103 | 4.0.4
104 | -----
105 |
106 | - Fixed issue in type script set user definition.
107 |
108 | 4.0.3
109 | -----
110 |
111 | - Added support for ignoreUrls and whitelistUrls
112 |
113 | 4.0.2
114 | -----
115 |
116 | - Fixed slowest routes duration issue.
117 | - Fixed slowest route queue limit.
118 |
119 | 4.0.1
120 | -----
121 |
122 | - Fixed typescript name issue.
123 |
124 | 4.0.0
125 | -----
126 |
127 | - Added support for single page applications (SPA).
128 | - Allow AJAX duration up to 150 seconds
129 | - Ignore analytics domains in AJAX monitoring.
130 | - Updated recordTransactions with failure option.
131 | - Fixed negative number in scs timing.
132 |
133 | 3.1.1
134 | -----
135 |
136 | - Fixed naming issue in typescript file.
137 |
138 | 3.1.0
139 | -----
140 |
141 | - Added CommonJS, Browserify and AMD support.
142 | - Reported unhandled promise rejection as error.
143 |
144 | 3.0.9
145 | -----
146 |
147 | - Added REGEX support for AJAX Allowed Domains.
148 |
149 | 3.0.8
150 | -----
151 |
152 | - Added fetch as AJAX in session traces.
153 | - Fixed session variable issue.
154 |
155 | 3.0.7
156 | -----
157 | - Limit number of errors to be stored in local storage during offline save.
158 | - Introduced "recordTransaction" to directly record custom duration.
159 |
160 | 3.0.6
161 | -----
162 | - For individual errors, removed appending of original custom data, and tags.
163 |
164 | 3.0.5
165 | -----
166 | - Fixed failed session payloads. Sorry, last fix does not work in certain scenario.
167 |
168 | 3.0.4
169 | -----
170 | - Fixed failed session payloads.
171 |
172 | 3.0.3
173 | -----
174 | - Added anonymize IP support
175 |
176 | 3.0.2
177 | -----
178 | - Added regex support for allowed domains
179 | - Added Async support
180 |
181 | 3.0.1
182 | -----
183 | - Removed UMD support.
184 |
185 | 3.0.0
186 | -----
187 | - Added support for Session Tracking
188 | - Added support for Single Page Application route change performances
189 |
190 | 2.3.12
191 | -----
192 | - Added console timeline support
193 | - Added console.error notify
194 |
195 | 2.3.11
196 | -----
197 | - Added request object for on before send
198 |
199 | 2.3.10
200 | -----
201 | - Added grouping key support
202 | - Added support for options in config object.
203 | - Added option to report console errors
204 |
205 | 2.3.9
206 | -----
207 | - Added an option to disable Real User Monitoring
208 |
209 | 2.3.8
210 | -----
211 | - Fixed version number and user id integer values
212 | - Added uninstall support
213 |
214 | 2.3.7
215 | -----
216 | - Fixed enable sourcemap type issue.
217 | - Removed atatus URL from stacktrace
218 |
219 | 2.3.6
220 | -----
221 | - Added user support
222 | - Removed sourcemap file
223 |
224 | 2.3.5
225 | -----
226 | - Added a map file
227 | - Fixed ignore errors issue
228 |
229 | 2.3.4
230 | -----
231 | - Fixed callback duration.
232 | - Removed 70 sec check in page load performance
233 |
234 | 2.3.3
235 | -----
236 | - Increased AJAX Batch Size to 25
237 | - Renamed AJAX Payload key name.
238 | - Ignored Page Load time greater than 70 sec
239 |
240 | 2.3.2
241 | -----
242 | - Removed query string from AJAX URL
243 |
244 | 2.3.1
245 | -----
246 | - Fixed responseText issue
247 |
248 | 2.3.0
249 | -----
250 | - Added support for Ajax Monitoring
251 | - Added support for Transaction Monitoring
252 |
253 | 2.2.5
254 | -----
255 | - Added `isConfigured` to check whether API key is configured or not
256 |
257 | 2.2.4
258 | -----
259 | - Fixed bug in jQuery.event wrapping if handler not a func
260 | - Handle exceptions on windows phone 8 in cordova
261 | - Normalize Firefox's 0-based column number
262 |
263 | 2.2.3
264 | -----
265 | - Add support for source map
266 | - Add support for application version
267 | - Add a `onBeforeErrorSend` callback to allow filtering of errors being sent to Atatus
268 |
269 | 2.2.2
270 | -----
271 | - Don't send duplicate exceptions from the client
272 | - Fixed bug navigation start with 0 instead of time
273 | - First version available on bower and npm as atatus-js
274 |
275 | 2.2.1
276 | -----
277 | - Use image tag instead of CORS to make requests, for better cross-browser support
278 |
279 | 2.2.0
280 | -----
281 | - Add support for performance
282 |
283 | 1.0.0
284 | -----
285 | - First public release
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Atatus-JS
2 |
3 | [Atatus](https://www.atatus.com) Real User Monitoring and Advanced error tracking plugin for web.
4 |
5 | [Signup for Atatus](https://www.atatus.com/signup).
6 |
7 | ## Getting Started
8 |
9 | ### With Bower
10 |
11 | Run `bower install atatus-js`
12 |
13 | ### With NPM
14 |
15 | Run `npm install atatus-js --save`
16 |
17 | ## Usage
18 |
19 | In your web page:
20 |
21 | ```html
22 |
23 |
26 | ```
27 |
28 | For more advanced options, refer [our documentation](https://www.atatus.com/docs).
29 |
30 |
31 | ### CDN
32 |
33 | Atatus is also available from our content delivery network:
34 |
35 | ```html
36 |
37 |
40 | ```
41 |
42 | ### Module loaders (CommonJS)
43 |
44 | Atatus can be loaded using a module loader like Browserify or Webpack.
45 |
46 | ```javascript
47 | var atatus = require('atatus-js');
48 | atatus.config('YOUR_API_KEY').install();
49 | ```
50 |
51 |
--------------------------------------------------------------------------------
/atatus.d.ts:
--------------------------------------------------------------------------------
1 | // Type definitions for atatus.js
2 | // Project: https://github.com/atatus/atatus-js
3 |
4 | interface AtatusOptions {
5 |
6 | /** Print debug message */
7 | debugMode?: boolean;
8 |
9 | /** When present, the IP address of the sender will be anonymized. */
10 | anonymizeIp?: boolean;
11 |
12 | /** When present, change hash routes into clean path. */
13 | hashRoutes?: boolean;
14 |
15 | /** Control what should be monitored with Atatus */
16 | disableBreadcrumbs?: boolean;
17 | disableErrorTracking?: boolean;
18 | disableAjaxMonitoring?: boolean;
19 | disableRUM?: boolean;
20 | disableSession?: boolean;
21 | disableSPA?: boolean;
22 |
23 | /** Report AJAX 4xx and 5xx status codes as error to Atatus */
24 | reportAjaxErrors?: boolean;
25 |
26 | /** Report unhandled promise rejections as error to Atatus */
27 | reportUnhandledRejections?: boolean;
28 |
29 | /** Additional data to be sent onto the error. */
30 | customData?: Object;
31 |
32 | /** Additional Filterable data to be tagged onto the performance and error data. */
33 | tags?: string[];
34 |
35 | /** Save data during offline and Send it to Atatus when it is online. */
36 | offline?: boolean;
37 |
38 | /** The release version of the application you are monitoring with Atatus */
39 | version?: string;
40 |
41 | /** List of error messages to be filtered out before being sent to Atatus. */
42 | ignoreErrors?: (RegExp | string)[];
43 |
44 | /** DEPRECATED: Only report performances metrics from whole domains matching a regex pattern. */
45 | allowedDomains?: (RegExp | string)[];
46 |
47 | /** It will ignore performance metrics from whole urls matching a regex pattern or string. */
48 | ignoreUrls?: (RegExp | string)[];
49 |
50 | /** The inverse of ignoreUrls. Only report performance metrics from whole urls matching a regex pattern or string. */
51 | whitelistUrls?: (RegExp | string)[];
52 |
53 | // Enable or Disable all console activity
54 | console? : boolean;
55 | consoleTimeline? : boolean;
56 | consoleDisplay? : boolean;
57 | consoleErrorNotify? : boolean;
58 | consoleTimelineLevels? : string[];
59 |
60 | /** A function which allows mutation of the data payload right before being sent to Atatus */
61 | beforeSend?: (data: any) => any;
62 |
63 | /** A function which allows mutation of the error data payload right before being sent to Atatus */
64 | beforeErrorSend?: (data: any) => any;
65 |
66 | /** A callback function that allows to specify the custom grouping key of the error. */
67 | groupingKeyCallback?: (data: any) => string;
68 |
69 | /** By default, Atatus does not truncate messages. If you need to truncate characters for whatever reason, you may set this to limit the length. */
70 | // maxMessageLength?: number;
71 |
72 | urlMaxLength?: number;
73 | maxDuplicateErrors?: number;
74 | }
75 |
76 |
77 | interface Atatus {
78 |
79 | /** Atatus.js version. */
80 | VERSION: string;
81 |
82 | /**
83 | * If you need to conditionally check if atatus needs to be initialized or not,
84 | * you can use the isConfigured function. It will return true if Atatus is already initialized.
85 | *
86 | * @return {boolean}
87 | */
88 | isConfigured(): boolean;
89 |
90 | /**
91 | * Allow multiple versions of Atatus to be installed.
92 | * Strip Atatus from the global context and returns the instance.
93 | *
94 | * @return {!Atatus} A self reference.
95 | */
96 | noConflict(): Atatus;
97 |
98 | /**
99 | * Configure Atatus with a API Key and extra options
100 | *
101 | * @param {string} apiKey The public Atatus project API Key
102 | * @param {object} options Optional set of of global options [optional]
103 | * @return {!Atatus} A self reference.
104 | */
105 | config(apiKey: string, options?: AtatusOptions): Atatus;
106 |
107 | /**
108 | * Installs all necessary configurations to capture errors and
109 | * performance metrics.
110 | *
111 | * @return {!Atatus} A self reference.
112 | */
113 | install(): Atatus;
114 |
115 | /**
116 | * Un-install Atatus Agent
117 | *
118 | * @return {!Atatus} A self reference.
119 | */
120 | uninstall(): Atatus;
121 |
122 | /**
123 | * Manually capture an exception and send it over to Atatus
124 | *
125 | * @param {error} ex An exception to be logged
126 | * @param {object} customData Custom meta data for this error [optional]
127 | * @param {array} tags List of tags for this error [optional]
128 | * @return {!Atatus} A self reference.
129 | */
130 | notify(ex: Error, customData?: Object, tags?: string[]): Atatus;
131 |
132 | /**
133 | * Set a user to be sent along with the payload.
134 | *
135 | * @param {object} user An object representing user data [optional]
136 | * @return {!Atatus} A self reference.
137 | */
138 | setUser(id: string, email?: string, name?: string): Atatus;
139 |
140 | /**
141 | * Clear the user context, removing the user data that would be sent to Atatus.
142 | *
143 | * @return {!Atatus} A self reference.
144 | */
145 | resetUser(): Atatus;
146 |
147 | /**
148 | * Enable hash routes or path
149 | *
150 | * @param {boolean} hashRoutes Value indicates whether to convert hash routes into clean URL.
151 | * @return {!Atatus} A self reference.
152 | */
153 | setHashRoutes(hashRoutes: boolean): Atatus;
154 |
155 | /**
156 | * Enable offline
157 | *
158 | * @param {boolean} offline Value indicates whether to enable offline data collection or not.
159 | * @return {!Atatus} A self reference.
160 | */
161 | enableOffline(offline: boolean): Atatus;
162 |
163 | /**
164 | * Set release version of application
165 | *
166 | * @param {string} version Application version number
167 | * @return {!Atatus} A self reference.
168 | */
169 | setVersion(version: string): Atatus;
170 |
171 | /**
172 | * Set meta data which helps you to debug the error
173 | *
174 | * @param {Object} customData Object contains custom details to be send with error.
175 | * @return {!Atatus} A self reference.
176 | */
177 | setCustomData(customData: Object): Atatus;
178 |
179 | /**
180 | * Set tags by which you can filter the error and performance data
181 | *
182 | * @param {string[]} tags List of tags
183 | * @return {!Atatus} A self reference.
184 | */
185 | setTags(tags: string[]): Atatus;
186 |
187 | /**
188 | * Set ignored urls
189 | *
190 | * @param {(RegExp | string)[]} ignoreUrls List of ignored urls.
191 | * @return {!Atatus} A self reference.
192 | */
193 | setIgnoreUrls(ignoreUrls: (RegExp | string)[]): Atatus;
194 |
195 | /**
196 | * Get list of ignored urls
197 | *
198 | * @return {(RegExp | string)[]}
199 | */
200 | getIgnoreUrls(): (RegExp | string)[];
201 |
202 | /**
203 | * Set white-list urls
204 | *
205 | * @param {(RegExp | string)[]} whitelistUrls List of whitelist urls.
206 | * @return {!Atatus} A self reference.
207 | */
208 | setWhitelistUrls(whitelistUrls: (RegExp | string)[]): Atatus;
209 |
210 | /**
211 | * Get list of white-list urls
212 | *
213 | * @return {(RegExp | string)[]}
214 | */
215 | getWhitelistUrls(): (RegExp | string)[];
216 |
217 | /**
218 | * Set allowed domains
219 | *
220 | * @param {(RegExp | string)[]} allowedDomains List of allowed domains.
221 | * @return {!Atatus} A self reference.
222 | */
223 | setAllowedDomains(allowedDomains: (RegExp | string)[]): Atatus;
224 |
225 | /**
226 | * Get list of allowed domains
227 | *
228 | * @return {(RegExp | string)[]}
229 | */
230 | getAllowedDomains(): (RegExp | string)[];
231 |
232 | /**
233 | * Set the endpoint where data should be sent
234 | *
235 | * @param {string} apiEndpoint The endpoint where all data has to be sent.
236 | * @return {!Atatus} A self reference.
237 | */
238 | setAPIEndpoint(apiEndpoint: string): Atatus;
239 |
240 | /**
241 | * Get the API Endpoint
242 | *
243 | * @return {string}
244 | */
245 | getAPIEndpoint(): string;
246 |
247 | /**
248 | * Log a breadcrumb
249 | *
250 | * @param {any} value Value of the breadcrumb.
251 | * @param {string} type Type of the breadcrumb can be info, error, warn.
252 | * @return {!Atatus} A self reference.
253 | */
254 | leaveBreadcrumb(value: any, type?: string): Atatus;
255 |
256 | /**
257 | * Specify a function that allows mutation of the data payload right before being sent to Atatus.
258 | *
259 | * @param {any} data Payload of the error or performance.
260 | * @return {!Atatus} A self reference.
261 | */
262 | onBeforeSend(data: any): Atatus;
263 |
264 | /**
265 | * Specify a callback function that allows you to apply your own filters to determine if the message should be sent to Atatus.
266 | *
267 | * @param {any} data Payload of the error.
268 | * @return {!Atatus} A self reference.
269 | */
270 | onBeforeErrorSend(data: any): Atatus;
271 |
272 | /**
273 | * Specify a callback function that allows to specify the custom grouping key of the error
274 | *
275 | * @param {any} data Payload of the error.
276 | * @return {!Atatus} A self reference.
277 | */
278 | setGroupingKeyCallback(data: any): Atatus;
279 |
280 | /**
281 | * End the session
282 | *
283 | * @return {!Atatus} A self reference.
284 | */
285 | endSession(): Atatus;
286 |
287 | /**
288 | * Begin the transaction
289 | *
290 | * @param {String} txnName - Transaction name
291 | */
292 | beginTransaction(txnName: string): void;
293 |
294 | /**
295 | * End the transaction successfully
296 | *
297 | * @param {String} txnName - Transaction name
298 | */
299 | endTransaction(txnName: string): void;
300 |
301 | /**
302 | * Fail the transaction
303 | *
304 | * @param {String} txnName - Transaction name
305 | */
306 | failTransaction(txnName: string): void;
307 |
308 | /**
309 | * Cancel the transaction
310 | *
311 | * @param {String} txnName - Transaction name
312 | */
313 | cancelTransaction(txnName: string): void;
314 |
315 | /**
316 | * Record the transaction with the given duration
317 | *
318 | * @param {String} txnName - Transaction name
319 | * @param {Number} duration - Time duration in milliseconds
320 | */
321 | recordTransaction(txnName: string, duration: number, success?: boolean): void;
322 |
323 | }
324 |
325 | interface Window {
326 | _atatusConfig: AtatusOptions
327 | }
328 |
329 | declare var atatus: Atatus;
330 | declare module "atatus-js" {
331 | export = atatus;
332 | }
333 |
--------------------------------------------------------------------------------
/atatus.min.js:
--------------------------------------------------------------------------------
1 | /*! AtatusJs - v4.6.4 - 2024-11-19
2 | * Copyright (c) 2024 Atatus */
3 | !function(){"undefined"!=typeof window&&(!function(a){function b(a,b){return Object.prototype.hasOwnProperty.call(a,b)}function c(a){return"undefined"==typeof a}if(a){var d={},e=a.TraceKit,f=[].slice,g="?";d.noConflict=function(){return a.TraceKit=e,d},d.wrap=function(a){function b(){try{return a.apply(this,arguments)}catch(b){throw d.report(b),b}}try{if("function"!=typeof a||!a.apply)return a}catch(c){return a}return b},d.report=function(){function c(a){h(),m.push(a)}function e(a){for(var b=m.length-1;b>=0;--b)m[b]===a&&m.splice(b,1)}function f(a,c,e){var f=null;if(!c||d.collectWindowErrors){for(var g in m)if(b(m,g))try{m[g](a,c,e)}catch(h){f=h}if(f)throw f}}function g(a,b,c,e,g){var h=null;if(o)d.computeStackTrace.augmentStackTraceWithInitialElement(o,b,c,a),i();else if(g)h=d.computeStackTrace(g),f(h,!0,g);else{var j={url:b,line:c,column:e};j.func=d.computeStackTrace.guessFunctionName(j.url,j.line),j.context=d.computeStackTrace.gatherContext(j.url,j.line),h={mode:"onerror",message:a,stack:[j]},f(h,!0,null)}return k?k.apply(this,arguments):!1}function h(){l!==!0&&(k=a.onerror,a.onerror=g,l=!0)}function i(){var a=o,b=n;o=null,n=null,f(a,!1,b)}function j(b){if(o){if(n===b)return;i()}var c=d.computeStackTrace(b);throw o=c,n=b,a.setTimeout(function(){n===b&&i()},c.incomplete?2e3:0),b}var k,l,m=[],n=null,o=null;return j.subscribe=c,j.unsubscribe=e,j}(),d.computeStackTrace=function(){function e(a){return"string"!=typeof a?[]:""}function f(c){if("string"!=typeof c)return[];if(!b(w,c)){var d="",f="";try{f=a.document.domain}catch(g){}var h=/(.*)\:\/\/([^:\/]+)([:\d]*)\/{0,1}([\s\S]*)/.exec(c);h&&h[2]===f&&(d=e(c)),w[c]=d?d.split("\n"):[]}return w[c]}function h(a,b){var d,e=/function ([^(]*)\(([^)]*)\)/,h=/['"]?([0-9A-Za-z$_]+)['"]?\s*[:=]\s*(function|eval|new Function)/,i="",j=10,k=f(a);if(!k.length)return g;for(var l=0;j>l;++l)if(i=k[b-l]+i,!c(i)){if(d=h.exec(i))return d[1];if(d=e.exec(i))return d[1]}return g}function i(a,b){var e=f(a);if(!e.length)return null;var g=[],h=Math.floor(d.linesOfContext/2),i=h+d.linesOfContext%2,j=Math.max(0,b-h-1),k=Math.min(e.length,b+i-1);b-=1;for(var l=j;k>l;++l)c(e[l])||g.push(e[l]);return g.length>0?g:null}function j(a){return a.replace(/[\-\[\]{}()*+?.,\\\^$|#]/g,"\\$&")}function k(a){return j(a).replace("<","(?:<|<)").replace(">","(?:>|>)").replace("&","(?:&|&)").replace('"','(?:"|")').replace(/\s+/g,"\\s+")}function l(a,b){for(var c,d,e=0,g=b.length;g>e;++e)if((c=f(b[e])).length&&(c=c.join("\n"),d=a.exec(c)))return{url:b[e],line:c.substring(0,d.index).split("\n").length,column:d.index-c.lastIndexOf("\n",d.index)-1};return null}function m(a,b,c){var d,e=f(b),g=new RegExp("\\b"+j(a)+"\\b");return c-=1,e&&e.length>c&&(d=g.exec(e[c]))?d.index:null}function n(b){if(!c(a&&a.document)){for(var d,e,f,g,h=[a.location.href],i=a.document.getElementsByTagName("script"),m=""+b,n=/^function(?:\s+([\w$]+))?\s*\(([\w\s,]*)\)\s*\{\s*(\S[\s\S]*\S)\s*\}\s*$/,o=/^function on([\w$]+)\s*\(event\)\s*\{\s*(\S[\s\S]*\S)\s*\}\s*$/,p=0;po;++o){if(b=e.exec(k[o])){var q=b[2]&&-1!==b[2].indexOf("native");d={url:q?null:b[2],func:b[1]||g,args:q?[b[2]]:[],line:b[3]?+b[3]:null,column:b[4]?+b[4]:null}}else if(b=j.exec(k[o]))d={url:b[2],func:b[1]||g,args:[],line:+b[3],column:b[4]?+b[4]:null};else{if(!(b=f.exec(k[o])))continue;d={url:b[3],func:b[1]||g,args:b[2]?b[2].split(","):[],line:b[4]?+b[4]:null,column:b[5]?+b[5]:null}}!d.func&&d.line&&(d.func=h(d.url,d.line)),d.line&&(d.context=i(d.url,d.line)),l.push(d)}return l.length?(l[0]&&l[0].line&&!l[0].column&&n?l[0].column=m(n[1],l[0].url,l[0].line):l[0].column||c(a.columnNumber)||(l[0].column=a.columnNumber+1),{mode:"stack",name:a.name,message:a.message,stack:l}):null}function p(a){var b=a.stacktrace;if(b){for(var c,d=/ line (\d+).*script (?:in )?(\S+)(?:: in function (\S+))?$/i,e=/ line (\d+), column (\d+)\s*(?:in (?:]+)>|([^\)]+))\((.*)\))? in (.*):\s*$/i,f=b.split("\n"),g=[],j=0;j=0&&(s.line=t+v.substring(0,w).split("\n").length)}}}else if(e=m.exec(d[r])){var x=a.location.href.replace(/#.*$/,""),y=new RegExp(k(d[r+1])),z=l(y,[x]);s={url:x,func:"",args:[],line:z?z.line:e[1],column:null}}if(s){s.func||(s.func=h(s.url,s.line));var A=i(s.url,s.line),B=A?A[Math.floor(A.length/2)]:null;s.context=A&&B.replace(/^\s*/,"")===d[r+1].replace(/^\s*/,"")?A:[d[r+1]],n.push(s)}}return n.length?{mode:"multiline",name:c.name,message:d[0],stack:n}:null}function r(a,b,c,d){var e={url:b,line:c};if(e.url&&e.line){a.incomplete=!1,e.func||(e.func=h(e.url,e.line)),e.context||(e.context=i(e.url,e.line));var f=/ '([^']+)' /.exec(d);if(f&&(e.column=m(f[1],e.url,e.line)),a.stack.length>0&&a.stack[0].url===e.url){if(a.stack[0].line===e.line)return!1;if(!a.stack[0].line&&a.stack[0].func===e.func)return a.stack[0].line=e.line,a.stack[0].context=e.context,!1}return a.stack.unshift(e),a.partial=!0,!0}return a.incomplete=!0,!1}function s(a,b){for(var c,e,f,i=/function\s+([_$a-zA-Z\xA0-\uFFFF][_$a-zA-Z0-9\xA0-\uFFFF]*)?\s*\(/i,j=[],k={},l=!1,o=s.caller;o&&!l;o=o.caller)if(o!==t&&o!==d.report){if(e={url:null,func:g,args:[],line:null,column:null},o.name?e.func=o.name:(c=i.exec(o.toString()))&&(e.func=c[1]),"undefined"==typeof e.func)try{e.func=c.input.substring(0,c.input.indexOf("{"))}catch(p){}if(f=n(o)){e.url=f.url,e.line=f.line,e.func===g&&(e.func=h(e.url,e.line));var q=/ '([^']+)' /.exec(a.message||a.description);q&&(e.column=m(q[1],f.url,f.line))}k[""+o]?l=!0:k[""+o]=!0,j.push(e)}b&&j.splice(0,b);var u={mode:"callers",name:a.name,message:a.message,stack:j};return r(u,a.sourceURL||a.fileName,a.line||a.lineNumber,a.message||a.description),u}function t(a,b){var c=null;b=null==b?0:+b;try{if(c=p(a))return c}catch(d){if(v)throw d}try{if(c=o(a))return c}catch(d){if(v)throw d}try{if(c=q(a))return c}catch(d){if(v)throw d}try{if(c=s(a,b+1))return c}catch(d){if(v)throw d}return{mode:"failed"}}function u(a){a=(null==a?0:+a)+1;try{throw new Error}catch(b){return t(b,a+1)}}var v=!1,w={};return t.augmentStackTraceWithInitialElement=r,t.guessFunctionName=h,t.gatherContext=i,t.ofCaller=u,t.getSource=f,t}(),d.extendToAsynchronousCallbacks=function(){var b=function(b){var c=a[b];a[b]=function(){var a=f.call(arguments),b=a[0];return"function"==typeof b&&(a[0]=d.wrap(b)),c.apply?c.apply(this,a):c(a[0],a[1])}};b("setTimeout"),b("setInterval")},d.remoteFetching||(d.remoteFetching=!0),d.collectWindowErrors||(d.collectWindowErrors=!0),(!d.linesOfContext||d.linesOfContext<1)&&(d.linesOfContext=11),a.TraceKit=d}}("undefined"!=typeof window?window:global),function(a,b){"use strict";if(a&&a.event&&a.event.add){var c=a.event.add;a.event.add=function(d,e,f,g,h){if("function"!=typeof f&&"function"!=typeof f.handler)return c.call(this,d,e,f,g,h);var i;return f.handler?(i=f.handler,f.handler=b.wrap(f.handler)):(i=f,f=b.wrap(f)),f.guid=i.guid?i.guid:i.guid=a.guid++,c.call(this,d,e,f,g,h)};var d=a.fn.ready;a.fn.ready=function(a){return d.call(this,b.wrap(a))};var e=a.ajax;a.ajax=function(c,d){"object"==typeof c&&(d=c,c=void 0),d=d||{};for(var f,g=["complete","error","success"];f=g.pop();)a.isFunction(d[f])&&(d[f]=b.wrap(d[f]));try{return c?e.call(this,c,d):e.call(this,d)}catch(h){throw b.report(h),h}}}}(window.jQuery,window.TraceKit),window.webVitals=function(a){"use strict";var b,c,d,e,f,g=-1,h=function(a){addEventListener("pageshow",function(b){b.persisted&&(g=b.timeStamp,a(b))},!0)},i=function(){return window.performance&&performance.getEntriesByType&&performance.getEntriesByType("navigation")[0]},j=function(){var a=i();return a&&a.activationStart||0},k=function(a,b){var c=i(),d="navigate";return g>=0?d="back-forward-cache":c&&(document.prerendering||j()>0?d="prerender":document.wasDiscarded?d="restore":c.type&&(d=c.type.replace(/_/g,"-"))),{name:a,value:void 0===b?-1:b,rating:"good",delta:0,entries:[],id:"v3-".concat(Date.now(),"-").concat(Math.floor(8999999999999*Math.random())+1e12),navigationType:d}},l=function(a,b,c){try{if(PerformanceObserver.supportedEntryTypes.includes(a)){var d=new PerformanceObserver(function(a){Promise.resolve().then(function(){b(a.getEntries())})});return d.observe(Object.assign({type:a,buffered:!0},c||{})),d}}catch(a){}},m=function(a,b,c,d){var e,f;return function(g){b.value>=0&&(g||d)&&((f=b.value-(e||0))||void 0===e)&&(e=b.value,b.delta=f,b.rating=function(a,b){return a>b[1]?"poor":a>b[0]?"needs-improvement":"good"}(b.value,c),a(b))}},n=function(a){requestAnimationFrame(function(){return requestAnimationFrame(function(){return a()})})},o=function(a){var b=function(b){"pagehide"!==b.type&&"hidden"!==document.visibilityState||a(b)};addEventListener("visibilitychange",b,!0),addEventListener("pagehide",b,!0)},p=function(a){var b=!1;return function(c){b||(a(c),b=!0)}},q=-1,r=function(){return"hidden"!==document.visibilityState||document.prerendering?1/0:0},s=function(a){"hidden"===document.visibilityState&&q>-1&&(q="visibilitychange"===a.type?a.timeStamp:0,u())},t=function(){addEventListener("visibilitychange",s,!0),addEventListener("prerenderingchange",s,!0)},u=function(){removeEventListener("visibilitychange",s,!0),removeEventListener("prerenderingchange",s,!0)},v=function(){return 0>q&&(q=r(),t(),h(function(){setTimeout(function(){q=r(),t()},0)})),{get firstHiddenTime(){return q}}},w=function(a){document.prerendering?addEventListener("prerenderingchange",function(){return a()},!0):a()},x=[1800,3e3],y=function(a,b){b=b||{},w(function(){var c,d=v(),e=k("FCP"),f=l("paint",function(a){a.forEach(function(a){"first-contentful-paint"===a.name&&(f.disconnect(),a.startTimed.value&&(d.value=e,d.entries=f,c())},i=l("layout-shift",g);i&&(c=m(a,d,z,b.reportAllChanges),o(function(){g(i.takeRecords()),c(!0)}),h(function(){e=0,d=k("CLS",0),c=m(a,d,z,b.reportAllChanges),n(function(){return c()})}),setTimeout(c,0))}))},B={passive:!0,capture:!0},C=new Date,D=function(a,e){b||(b=e,c=a,d=new Date,G(removeEventListener),E())},E=function(){if(c>=0&&d-C>c){var a={entryType:"first-input",name:b.type,target:b.target,cancelable:b.cancelable,startTime:b.timeStamp,processingStart:b.timeStamp+c};e.forEach(function(b){b(a)}),e=[]}},F=function(a){if(a.cancelable){var b=(a.timeStamp>1e12?new Date:performance.now())-a.timeStamp;"pointerdown"==a.type?function(a,b){var c=function(){D(a,b),e()},d=function(){e()},e=function(){removeEventListener("pointerup",c,B),removeEventListener("pointercancel",d,B)};addEventListener("pointerup",c,B),addEventListener("pointercancel",d,B)}(b,a):D(b,a)}},G=function(a){["mousedown","keydown","touchstart","pointerdown"].forEach(function(b){return a(b,F,B)})},H=[100,300],I=function(a,d){d=d||{},w(function(){var f,g=v(),i=k("FID"),j=function(a){a.startTimeb.latency){if(c)c.entries.push(a),c.latency=Math.max(c.latency,a.duration);else{var d={id:a.interactionId,latency:a.duration,entries:[a]};T[d.id]=d,S.push(d)}S.sort(function(a,b){return b.latency-a.latency}),S.splice(10).forEach(function(a){delete T[a.id]})}},V=function(a,b){b=b||{},w(function(){var c;O();var d,e=k("INP"),f=function(a){a.forEach(function(a){a.interactionId&&U(a),"first-input"===a.entryType&&!S.some(function(b){return b.entries.some(function(b){return a.duration===b.duration&&a.startTime===b.startTime})})&&U(a)});var b,c=(b=Math.min(S.length-1,Math.floor(R()/50)),S[b]);c&&c.latency!==e.value&&(e.value=c.latency,e.entries=c.entries,d())},g=l("event",f,{durationThreshold:null!==(c=b.durationThreshold)&&void 0!==c?c:40});d=m(a,e,P,b.reportAllChanges),g&&("interactionId"in PerformanceEventTiming.prototype&&g.observe({type:"first-input",buffered:!0}),o(function(){f(g.takeRecords()),e.value<0&&R()>0&&(e.value=0,e.entries=[]),d(!0)}),h(function(){S=[],Q=N(),e=k("INP"),d=m(a,e,P,b.reportAllChanges)}))})},W=[2500,4e3],X={},Y=function(a,b){b=b||{},w(function(){var c,d=v(),e=k("LCP"),f=function(a){var b=a[a.length-1];b&&b.startTime=f||f>performance.now())return;c.value=Math.max(f-j(),0),c.entries=[e],d(!0),h(function(){c=k("TTFB",0),(d=m(a,c,Z,b.reportAllChanges))(!0)})}})};return a.CLSThresholds=z,a.FCPThresholds=x,a.FIDThresholds=H,a.INPThresholds=P,a.LCPThresholds=W,a.TTFBThresholds=Z,a.getCLS=A,a.getFCP=y,a.getFID=I,a.getINP=V,a.getLCP=Y,a.getTTFB=_,a.onCLS=A,a.onFCP=y,a.onFID=I,a.onINP=V,a.onLCP=Y,a.onTTFB=_,Object.defineProperty(a,"__esModule",{value:!0}),a}({}),function(a,b,c,d){function e(){try{C=null,o()&&localStorage.removeItem(ka),D=null,Ha.createCookie(la,"",-1)}catch(a){Ha.log("Atatus Reset User",a)}}function f(a,b,c,d){if(a){C={},a&&(C.id=""+a),b&&(C.email=""+b),c&&(C.name=""+c),d&&(C.anonymous=d);try{o()&&localStorage.setItem(ka,JSON.stringify(C)),D=null,Ha.createCookie(la,"",-1)}catch(e){Ha.log("Atatus Set User: Invalid JSON object in LocalStorage",e)}}}function g(){try{var a;if(o()&&(a=localStorage.getItem(ka)),a)C=JSON.parse(a),D=null;else{var b,c=Ha.readCookie(la);c&&(b=Ha.readCookieElement(c,"id")),b&&"undefined"!==b?D=b:(D=Ha.uuid4(),Ha.createCookie(la,D))}}catch(d){Ha.log("Atatus Get User: Invalid JSON object in LocalStorage",d)}}function h(a){var b=a,c=a.split("//")[1];if(c){var d=c.indexOf("?"),e=c.toString().substring(0,d),f=e.split("/").slice(0,4).join("/"),g=e.substring(0,48);b=f.length";b&&(b instanceof Error||b.message)?La.notify(b):(b="object"==typeof b?"