PluginProbe
HubSpot All-In-One Marketing – Forms, Popups, Live Chat / 11.3.65
HubSpot All-In-One Marketing – Forms, Popups, Live Chat v11.3.65
11.3.75 11.3.73 11.3.71 11.3.70 11.3.69 11.3.64 11.3.65 11.3.62 11.3.61 11.3.56 11.3.58 11.0.31 11.0.52 11.0.54 11.0.56 11.0.58 11.0.7 11.1.10 11.1.11 11.1.13 11.1.14 11.1.15 11.1.2 11.1.20 11.1.21 All 73 releases
leadin / build / feedback.js

feedback.js in HubSpot All-In-One Marketing – Forms, Popups, Live Chat 11.3.65, at build/feedback.js

4,007 lines 133.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 /******/ (() => { // webpackBootstrap
2 /******/ var __webpack_modules__ = ({
3
4 /***/ "./scripts/api/wordpressApiClient.ts":
5 /*!*******************************************!*\
6 !*** ./scripts/api/wordpressApiClient.ts ***!
7 \*******************************************/
8 /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
9
10 "use strict";
11 __webpack_require__.r(__webpack_exports__);
12 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
13 /* harmony export */ "disableInternalTracking": () => (/* binding */ disableInternalTracking),
14 /* harmony export */ "fetchAccessToken": () => (/* binding */ fetchAccessToken),
15 /* harmony export */ "fetchDisableInternalTracking": () => (/* binding */ fetchDisableInternalTracking),
16 /* harmony export */ "fetchProxyMappingsEnabled": () => (/* binding */ fetchProxyMappingsEnabled),
17 /* harmony export */ "getBusinessUnitId": () => (/* binding */ getBusinessUnitId),
18 /* harmony export */ "healthcheckRestApi": () => (/* binding */ healthcheckRestApi),
19 /* harmony export */ "refreshProxyMappingsCache": () => (/* binding */ refreshProxyMappingsCache),
20 /* harmony export */ "setBusinessUnitId": () => (/* binding */ setBusinessUnitId),
21 /* harmony export */ "skipReview": () => (/* binding */ skipReview),
22 /* harmony export */ "toggleProxyMappingsEnabled": () => (/* binding */ toggleProxyMappingsEnabled),
23 /* harmony export */ "trackConsent": () => (/* binding */ trackConsent),
24 /* harmony export */ "updateHublet": () => (/* binding */ updateHublet)
25 /* harmony export */ });
26 /* harmony import */ var jquery__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! jquery */ "jquery");
27 /* harmony import */ var jquery__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(jquery__WEBPACK_IMPORTED_MODULE_0__);
28 /* harmony import */ var _lib_Raven__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../lib/Raven */ "./scripts/lib/Raven.ts");
29 /* harmony import */ var _constants_leadinConfig__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../constants/leadinConfig */ "./scripts/constants/leadinConfig.ts");
30 /* harmony import */ var _utils_queryParams__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../utils/queryParams */ "./scripts/utils/queryParams.ts");
31
32
33
34
35 function makeRequest(method, path) {
36 var data = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
37 var queryParams = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
38 // eslint-disable-next-line compat/compat
39 var restApiUrl = new URL("".concat(_constants_leadinConfig__WEBPACK_IMPORTED_MODULE_2__.restUrl, "leadin/v1").concat(path));
40 (0,_utils_queryParams__WEBPACK_IMPORTED_MODULE_3__.addQueryObjectToUrl)(restApiUrl, queryParams);
41 return new Promise(function (resolve, reject) {
42 var payload = {
43 url: restApiUrl.toString(),
44 method: method,
45 contentType: 'application/json',
46 beforeSend: function beforeSend(xhr) {
47 return xhr.setRequestHeader('X-WP-Nonce', _constants_leadinConfig__WEBPACK_IMPORTED_MODULE_2__.restNonce);
48 },
49 success: resolve,
50 error: function error(response) {
51 _lib_Raven__WEBPACK_IMPORTED_MODULE_1__["default"].captureMessage("HTTP Request to ".concat(restApiUrl, " failed with error ").concat(response.status, ": ").concat(response.responseText), {
52 fingerprint: ['{{ default }}', path, response.status, response.responseText]
53 });
54 reject(response);
55 }
56 };
57 if (method !== 'get') {
58 payload.data = JSON.stringify(data);
59 }
60 jquery__WEBPACK_IMPORTED_MODULE_0___default().ajax(payload);
61 });
62 }
63 function healthcheckRestApi() {
64 return makeRequest('get', '/healthcheck');
65 }
66 function disableInternalTracking(value) {
67 return makeRequest('put', '/internal-tracking', value ? '1' : '0');
68 }
69 function fetchDisableInternalTracking() {
70 return makeRequest('get', '/internal-tracking').then(function (message) {
71 return {
72 message: message
73 };
74 });
75 }
76 function updateHublet(hublet) {
77 return makeRequest('put', '/hublet', {
78 hublet: hublet
79 });
80 }
81 function skipReview() {
82 return makeRequest('post', '/skip-review');
83 }
84 function trackConsent(canTrack) {
85 return makeRequest('post', '/track-consent', {
86 canTrack: canTrack
87 }).then(function (message) {
88 return {
89 message: message
90 };
91 });
92 }
93 function setBusinessUnitId(businessUnitId) {
94 return makeRequest('put', '/business-unit', {
95 businessUnitId: businessUnitId
96 });
97 }
98 function getBusinessUnitId() {
99 return makeRequest('get', '/business-unit');
100 }
101 function refreshProxyMappingsCache() {
102 return makeRequest('post', '/wp-mappings-cache-reset');
103 }
104 function fetchProxyMappingsEnabled() {
105 return makeRequest('get', '/wp-mappings-proxy-enabled');
106 }
107 function toggleProxyMappingsEnabled(value) {
108 return makeRequest('put', '/wp-mappings-proxy-enabled', value);
109 }
110 var ACCESS_TOKEN_CACHE_KEY = 'leadin_access_token';
111 var ACCESS_TOKEN_MIN_TTL_SECONDS = 300;
112 var accessTokenRequest = null;
113 function fetchAccessToken() {
114 try {
115 var cached = sessionStorage.getItem(ACCESS_TOKEN_CACHE_KEY);
116 if (cached) {
117 var _JSON$parse = JSON.parse(cached),
118 accessToken = _JSON$parse.accessToken,
119 expiresAt = _JSON$parse.expiresAt;
120 if (accessToken && expiresAt > Math.floor(Date.now() / 1000) + ACCESS_TOKEN_MIN_TTL_SECONDS) {
121 return Promise.resolve({
122 accessToken: accessToken,
123 expiresIn: expiresAt - Math.floor(Date.now() / 1000)
124 });
125 }
126 }
127 } catch (_) {}
128 if (!accessTokenRequest) {
129 accessTokenRequest = makeRequest('get', '/access-token').then(function (response) {
130 try {
131 sessionStorage.setItem(ACCESS_TOKEN_CACHE_KEY, JSON.stringify({
132 accessToken: response.accessToken,
133 expiresAt: Math.floor(Date.now() / 1000) + response.expiresIn
134 }));
135 } catch (_) {}
136 return response;
137 })["finally"](function () {
138 accessTokenRequest = null;
139 });
140 }
141 return accessTokenRequest;
142 }
143
144 /***/ }),
145
146 /***/ "./scripts/constants/leadinConfig.ts":
147 /*!*******************************************!*\
148 !*** ./scripts/constants/leadinConfig.ts ***!
149 \*******************************************/
150 /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
151
152 "use strict";
153 __webpack_require__.r(__webpack_exports__);
154 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
155 /* harmony export */ "accountName": () => (/* binding */ accountName),
156 /* harmony export */ "activationTime": () => (/* binding */ activationTime),
157 /* harmony export */ "adminUrl": () => (/* binding */ adminUrl),
158 /* harmony export */ "connectionStatus": () => (/* binding */ connectionStatus),
159 /* harmony export */ "contentEmbed": () => (/* binding */ contentEmbed),
160 /* harmony export */ "decryptError": () => (/* binding */ decryptError),
161 /* harmony export */ "deviceId": () => (/* binding */ deviceId),
162 /* harmony export */ "didDisconnect": () => (/* binding */ didDisconnect),
163 /* harmony export */ "env": () => (/* binding */ env),
164 /* harmony export */ "formsScript": () => (/* binding */ formsScript),
165 /* harmony export */ "formsScriptPayload": () => (/* binding */ formsScriptPayload),
166 /* harmony export */ "hublet": () => (/* binding */ hublet),
167 /* harmony export */ "hubspotBaseUrl": () => (/* binding */ hubspotBaseUrl),
168 /* harmony export */ "hubspotNonce": () => (/* binding */ hubspotNonce),
169 /* harmony export */ "iframeUrl": () => (/* binding */ iframeUrl),
170 /* harmony export */ "impactLink": () => (/* binding */ impactLink),
171 /* harmony export */ "lastAuthorizeTime": () => (/* binding */ lastAuthorizeTime),
172 /* harmony export */ "lastDeauthorizeTime": () => (/* binding */ lastDeauthorizeTime),
173 /* harmony export */ "lastDisconnectTime": () => (/* binding */ lastDisconnectTime),
174 /* harmony export */ "leadinPluginVersion": () => (/* binding */ leadinPluginVersion),
175 /* harmony export */ "leadinQueryParams": () => (/* binding */ leadinQueryParams),
176 /* harmony export */ "locale": () => (/* binding */ locale),
177 /* harmony export */ "loginUrl": () => (/* binding */ loginUrl),
178 /* harmony export */ "meetingsScript": () => (/* binding */ meetingsScript),
179 /* harmony export */ "phpVersion": () => (/* binding */ phpVersion),
180 /* harmony export */ "pluginPath": () => (/* binding */ pluginPath),
181 /* harmony export */ "plugins": () => (/* binding */ plugins),
182 /* harmony export */ "portalDomain": () => (/* binding */ portalDomain),
183 /* harmony export */ "portalEmail": () => (/* binding */ portalEmail),
184 /* harmony export */ "portalId": () => (/* binding */ portalId),
185 /* harmony export */ "redirectNonce": () => (/* binding */ redirectNonce),
186 /* harmony export */ "refreshToken": () => (/* binding */ refreshToken),
187 /* harmony export */ "requiresContentEmbedScope": () => (/* binding */ requiresContentEmbedScope),
188 /* harmony export */ "restNonce": () => (/* binding */ restNonce),
189 /* harmony export */ "restUrl": () => (/* binding */ restUrl),
190 /* harmony export */ "reviewSkippedDate": () => (/* binding */ reviewSkippedDate),
191 /* harmony export */ "theme": () => (/* binding */ theme),
192 /* harmony export */ "trackConsent": () => (/* binding */ trackConsent),
193 /* harmony export */ "wpVersion": () => (/* binding */ wpVersion)
194 /* harmony export */ });
195 var _window$leadinConfig = window.leadinConfig,
196 accountName = _window$leadinConfig.accountName,
197 adminUrl = _window$leadinConfig.adminUrl,
198 activationTime = _window$leadinConfig.activationTime,
199 connectionStatus = _window$leadinConfig.connectionStatus,
200 deviceId = _window$leadinConfig.deviceId,
201 didDisconnect = _window$leadinConfig.didDisconnect,
202 env = _window$leadinConfig.env,
203 formsScript = _window$leadinConfig.formsScript,
204 meetingsScript = _window$leadinConfig.meetingsScript,
205 formsScriptPayload = _window$leadinConfig.formsScriptPayload,
206 hublet = _window$leadinConfig.hublet,
207 hubspotBaseUrl = _window$leadinConfig.hubspotBaseUrl,
208 hubspotNonce = _window$leadinConfig.hubspotNonce,
209 iframeUrl = _window$leadinConfig.iframeUrl,
210 impactLink = _window$leadinConfig.impactLink,
211 lastAuthorizeTime = _window$leadinConfig.lastAuthorizeTime,
212 lastDeauthorizeTime = _window$leadinConfig.lastDeauthorizeTime,
213 lastDisconnectTime = _window$leadinConfig.lastDisconnectTime,
214 leadinPluginVersion = _window$leadinConfig.leadinPluginVersion,
215 leadinQueryParams = _window$leadinConfig.leadinQueryParams,
216 locale = _window$leadinConfig.locale,
217 loginUrl = _window$leadinConfig.loginUrl,
218 phpVersion = _window$leadinConfig.phpVersion,
219 pluginPath = _window$leadinConfig.pluginPath,
220 plugins = _window$leadinConfig.plugins,
221 portalDomain = _window$leadinConfig.portalDomain,
222 portalEmail = _window$leadinConfig.portalEmail,
223 portalId = _window$leadinConfig.portalId,
224 redirectNonce = _window$leadinConfig.redirectNonce,
225 restNonce = _window$leadinConfig.restNonce,
226 restUrl = _window$leadinConfig.restUrl,
227 refreshToken = _window$leadinConfig.refreshToken,
228 reviewSkippedDate = _window$leadinConfig.reviewSkippedDate,
229 theme = _window$leadinConfig.theme,
230 trackConsent = _window$leadinConfig.trackConsent,
231 wpVersion = _window$leadinConfig.wpVersion,
232 contentEmbed = _window$leadinConfig.contentEmbed,
233 requiresContentEmbedScope = _window$leadinConfig.requiresContentEmbedScope,
234 decryptError = _window$leadinConfig.decryptError;
235
236
237 /***/ }),
238
239 /***/ "./scripts/constants/selectors.ts":
240 /*!****************************************!*\
241 !*** ./scripts/constants/selectors.ts ***!
242 \****************************************/
243 /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
244
245 "use strict";
246 __webpack_require__.r(__webpack_exports__);
247 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
248 /* harmony export */ "domElements": () => (/* binding */ domElements)
249 /* harmony export */ });
250 var domElements = {
251 iframe: '#leadin-iframe',
252 subMenu: '.toplevel_page_leadin > ul',
253 subMenuLinks: '.toplevel_page_leadin > ul a',
254 subMenuButtons: '.toplevel_page_leadin > ul > li',
255 deactivatePluginButton: '[data-slug="leadin"] .deactivate a',
256 deactivateFeedbackForm: 'form.leadin-deactivate-form',
257 deactivateFeedbackSubmit: 'button#leadin-feedback-submit',
258 deactivateFeedbackSkip: 'button#leadin-feedback-skip',
259 thickboxModalClose: '.leadin-modal-close',
260 thickboxModalWindow: 'div#TB_window.thickbox-loading',
261 thickboxModalContent: 'div#TB_ajaxContent.TB_modal',
262 reviewBannerContainer: '#leadin-review-banner',
263 reviewBannerLeaveReviewLink: 'a#leave-review-button',
264 reviewBannerDismissButton: 'a#dismiss-review-banner-button',
265 leadinIframeContainer: 'leadin-iframe-container',
266 leadinIframe: 'leadin-iframe',
267 leadinIframeFallbackContainer: 'leadin-iframe-fallback-container'
268 };
269
270 /***/ }),
271
272 /***/ "./scripts/feedback/ThickBoxModal.ts":
273 /*!*******************************************!*\
274 !*** ./scripts/feedback/ThickBoxModal.ts ***!
275 \*******************************************/
276 /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
277
278 "use strict";
279 __webpack_require__.r(__webpack_exports__);
280 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
281 /* harmony export */ "default": () => (/* binding */ ThickBoxModal)
282 /* harmony export */ });
283 /* harmony import */ var jquery__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! jquery */ "jquery");
284 /* harmony import */ var jquery__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(jquery__WEBPACK_IMPORTED_MODULE_0__);
285 /* harmony import */ var _constants_selectors__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../constants/selectors */ "./scripts/constants/selectors.ts");
286 function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
287 function _classCallCheck(a, n) { if (!(a instanceof n)) throw new TypeError("Cannot call a class as a function"); }
288 function _defineProperties(e, r) { for (var t = 0; t < r.length; t++) { var o = r[t]; o.enumerable = o.enumerable || !1, o.configurable = !0, "value" in o && (o.writable = !0), Object.defineProperty(e, _toPropertyKey(o.key), o); } }
289 function _createClass(e, r, t) { return r && _defineProperties(e.prototype, r), t && _defineProperties(e, t), Object.defineProperty(e, "prototype", { writable: !1 }), e; }
290 function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
291 function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; }
292 function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
293
294
295 var ThickBoxModal = /*#__PURE__*/function () {
296 function ThickBoxModal(openTriggerSelector, inlineContentId, windowCssClass, contentCssClass) {
297 _classCallCheck(this, ThickBoxModal);
298 _defineProperty(this, "openTriggerSelector", void 0);
299 _defineProperty(this, "inlineContentId", void 0);
300 _defineProperty(this, "windowCssClass", void 0);
301 _defineProperty(this, "contentCssClass", void 0);
302 this.openTriggerSelector = openTriggerSelector;
303 this.inlineContentId = inlineContentId;
304 this.windowCssClass = windowCssClass;
305 this.contentCssClass = contentCssClass;
306 jquery__WEBPACK_IMPORTED_MODULE_0___default()(openTriggerSelector).on('click', this.init.bind(this));
307 }
308 return _createClass(ThickBoxModal, [{
309 key: "close",
310 value: function close() {
311 //@ts-expect-error global
312 window.tb_remove();
313 }
314 }, {
315 key: "init",
316 value: function init(e) {
317 //@ts-expect-error global
318 window.tb_show('', "#TB_inline?inlineId=".concat(this.inlineContentId, "&modal=true"));
319 // thickbox doesn't respect the width and height url parameters https://core.trac.wordpress.org/ticket/17249
320 // We override thickboxes css with !important in the css
321 jquery__WEBPACK_IMPORTED_MODULE_0___default()(_constants_selectors__WEBPACK_IMPORTED_MODULE_1__.domElements.thickboxModalWindow).addClass(this.windowCssClass);
322 // have to modify the css of the thickbox content container as well
323 jquery__WEBPACK_IMPORTED_MODULE_0___default()(_constants_selectors__WEBPACK_IMPORTED_MODULE_1__.domElements.thickboxModalContent).addClass(this.contentCssClass);
324 // we unbind previous handlers because a thickbox modal is a single global object.
325 // Everytime it is re-opened, it still has old handlers bound
326 jquery__WEBPACK_IMPORTED_MODULE_0___default()(_constants_selectors__WEBPACK_IMPORTED_MODULE_1__.domElements.thickboxModalClose).off('click').on('click', this.close);
327 e.preventDefault();
328 }
329 }]);
330 }();
331
332
333 /***/ }),
334
335 /***/ "./scripts/feedback/feedbackFormApi.ts":
336 /*!*********************************************!*\
337 !*** ./scripts/feedback/feedbackFormApi.ts ***!
338 \*********************************************/
339 /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
340
341 "use strict";
342 __webpack_require__.r(__webpack_exports__);
343 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
344 /* harmony export */ "submitFeedbackForm": () => (/* binding */ submitFeedbackForm)
345 /* harmony export */ });
346 /* harmony import */ var jquery__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! jquery */ "jquery");
347 /* harmony import */ var jquery__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(jquery__WEBPACK_IMPORTED_MODULE_0__);
348
349 var portalId = '6275621';
350 var formId = '0e8807f8-2ac3-4664-b742-44552bfa09e2';
351 var formSubmissionUrl = "https://api.hsforms.com/submissions/v3/integration/submit/".concat(portalId, "/").concat(formId);
352 function submitFeedbackForm(formSelector) {
353 var formSubmissionPayload = {
354 fields: jquery__WEBPACK_IMPORTED_MODULE_0___default()(formSelector).serializeArray(),
355 skipValidation: true
356 };
357 return new Promise(function (resolve, reject) {
358 jquery__WEBPACK_IMPORTED_MODULE_0___default().ajax({
359 type: 'POST',
360 url: formSubmissionUrl,
361 contentType: 'application/json',
362 data: JSON.stringify(formSubmissionPayload),
363 success: resolve,
364 error: reject
365 });
366 });
367 }
368
369 /***/ }),
370
371 /***/ "./scripts/iframe/integratedMessages/core/CoreMessages.ts":
372 /*!****************************************************************!*\
373 !*** ./scripts/iframe/integratedMessages/core/CoreMessages.ts ***!
374 \****************************************************************/
375 /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
376
377 "use strict";
378 __webpack_require__.r(__webpack_exports__);
379 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
380 /* harmony export */ "CoreMessages": () => (/* binding */ CoreMessages)
381 /* harmony export */ });
382 var CoreMessages = {
383 HandshakeReceive: 'INTEGRATED_APP_EMBEDDER_HANDSHAKE_RECEIVED',
384 SendRefreshToken: 'INTEGRATED_APP_EMBEDDER_SEND_REFRESH_TOKEN',
385 ReloadParentFrame: 'INTEGRATED_APP_EMBEDDER_RELOAD_PARENT_FRAME',
386 RedirectParentFrame: 'INTEGRATED_APP_EMBEDDER_REDIRECT_PARENT_FRAME',
387 SendLocale: 'INTEGRATED_APP_EMBEDDER_SEND_LOCALE',
388 SendDeviceId: 'INTEGRATED_APP_EMBEDDER_SEND_DEVICE_ID',
389 SendIntegratedAppConfig: 'INTEGRATED_APP_EMBEDDER_CONFIG'
390 };
391
392 /***/ }),
393
394 /***/ "./scripts/iframe/integratedMessages/forms/FormsMessages.ts":
395 /*!******************************************************************!*\
396 !*** ./scripts/iframe/integratedMessages/forms/FormsMessages.ts ***!
397 \******************************************************************/
398 /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
399
400 "use strict";
401 __webpack_require__.r(__webpack_exports__);
402 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
403 /* harmony export */ "FormMessages": () => (/* binding */ FormMessages)
404 /* harmony export */ });
405 var FormMessages = {
406 CreateFormAppNavigation: 'CREATE_FORM_APP_NAVIGATION'
407 };
408
409 /***/ }),
410
411 /***/ "./scripts/iframe/integratedMessages/index.ts":
412 /*!****************************************************!*\
413 !*** ./scripts/iframe/integratedMessages/index.ts ***!
414 \****************************************************/
415 /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
416
417 "use strict";
418 __webpack_require__.r(__webpack_exports__);
419 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
420 /* harmony export */ "CoreMessages": () => (/* reexport safe */ _core_CoreMessages__WEBPACK_IMPORTED_MODULE_0__.CoreMessages),
421 /* harmony export */ "FormMessages": () => (/* reexport safe */ _forms_FormsMessages__WEBPACK_IMPORTED_MODULE_1__.FormMessages),
422 /* harmony export */ "LiveChatMessages": () => (/* reexport safe */ _livechat_LiveChatMessages__WEBPACK_IMPORTED_MODULE_2__.LiveChatMessages),
423 /* harmony export */ "PluginMessages": () => (/* reexport safe */ _plugin_PluginMessages__WEBPACK_IMPORTED_MODULE_3__.PluginMessages),
424 /* harmony export */ "ProxyMessages": () => (/* reexport safe */ _proxy_ProxyMessages__WEBPACK_IMPORTED_MODULE_4__.ProxyMessages)
425 /* harmony export */ });
426 /* harmony import */ var _core_CoreMessages__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./core/CoreMessages */ "./scripts/iframe/integratedMessages/core/CoreMessages.ts");
427 /* harmony import */ var _forms_FormsMessages__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./forms/FormsMessages */ "./scripts/iframe/integratedMessages/forms/FormsMessages.ts");
428 /* harmony import */ var _livechat_LiveChatMessages__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./livechat/LiveChatMessages */ "./scripts/iframe/integratedMessages/livechat/LiveChatMessages.ts");
429 /* harmony import */ var _plugin_PluginMessages__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./plugin/PluginMessages */ "./scripts/iframe/integratedMessages/plugin/PluginMessages.ts");
430 /* harmony import */ var _proxy_ProxyMessages__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./proxy/ProxyMessages */ "./scripts/iframe/integratedMessages/proxy/ProxyMessages.ts");
431
432
433
434
435
436
437 /***/ }),
438
439 /***/ "./scripts/iframe/integratedMessages/livechat/LiveChatMessages.ts":
440 /*!************************************************************************!*\
441 !*** ./scripts/iframe/integratedMessages/livechat/LiveChatMessages.ts ***!
442 \************************************************************************/
443 /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
444
445 "use strict";
446 __webpack_require__.r(__webpack_exports__);
447 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
448 /* harmony export */ "LiveChatMessages": () => (/* binding */ LiveChatMessages)
449 /* harmony export */ });
450 var LiveChatMessages = {
451 CreateLiveChatAppNavigation: 'CREATE_LIVE_CHAT_APP_NAVIGATION'
452 };
453
454 /***/ }),
455
456 /***/ "./scripts/iframe/integratedMessages/plugin/PluginMessages.ts":
457 /*!********************************************************************!*\
458 !*** ./scripts/iframe/integratedMessages/plugin/PluginMessages.ts ***!
459 \********************************************************************/
460 /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
461
462 "use strict";
463 __webpack_require__.r(__webpack_exports__);
464 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
465 /* harmony export */ "PluginMessages": () => (/* binding */ PluginMessages)
466 /* harmony export */ });
467 var PluginMessages = {
468 PluginSettingsNavigation: 'PLUGIN_SETTINGS_NAVIGATION',
469 PluginLeadinConfig: 'PLUGIN_LEADIN_CONFIG',
470 TrackConsent: 'INTEGRATED_APP_EMBEDDER_TRACK_CONSENT',
471 InternalTrackingFetchRequest: 'INTEGRATED_TRACKING_FETCH_REQUEST',
472 InternalTrackingFetchResponse: 'INTEGRATED_TRACKING_FETCH_RESPONSE',
473 InternalTrackingFetchError: 'INTEGRATED_TRACKING_FETCH_ERROR',
474 InternalTrackingChangeRequest: 'INTEGRATED_TRACKING_CHANGE_REQUEST',
475 InternalTrackingChangeError: 'INTEGRATED_TRACKING_CHANGE_ERROR',
476 BusinessUnitFetchRequest: 'BUSINESS_UNIT_FETCH_REQUEST',
477 BusinessUnitFetchResponse: 'BUSINESS_UNIT_FETCH_FETCH_RESPONSE',
478 BusinessUnitFetchError: 'BUSINESS_UNIT_FETCH_FETCH_ERROR',
479 BusinessUnitChangeRequest: 'BUSINESS_UNIT_CHANGE_REQUEST',
480 BusinessUnitChangeError: 'BUSINESS_UNIT_CHANGE_ERROR',
481 SkipReviewRequest: 'SKIP_REVIEW_REQUEST',
482 SkipReviewResponse: 'SKIP_REVIEW_RESPONSE',
483 SkipReviewError: 'SKIP_REVIEW_ERROR',
484 RemoveParentQueryParam: 'REMOVE_PARENT_QUERY_PARAM',
485 ContentEmbedInstallRequest: 'CONTENT_EMBED_INSTALL_REQUEST',
486 ContentEmbedInstallResponse: 'CONTENT_EMBED_INSTALL_RESPONSE',
487 ContentEmbedInstallError: 'CONTENT_EMBED_INSTALL_ERROR',
488 ContentEmbedActivationRequest: 'CONTENT_EMBED_ACTIVATION_REQUEST',
489 ContentEmbedActivationResponse: 'CONTENT_EMBED_ACTIVATION_RESPONSE',
490 ContentEmbedActivationError: 'CONTENT_EMBED_ACTIVATION_ERROR',
491 ProxyMappingsEnabledRequest: 'PROXY_MAPPINGS_ENABLED_REQUEST',
492 ProxyMappingsEnabledResponse: 'PROXY_MAPPINGS_ENABLED_RESPONSE',
493 ProxyMappingsEnabledError: 'PROXY_MAPPINGS_ENABLED_ERROR',
494 ProxyMappingsEnabledChangeRequest: 'PROXY_MAPPINGS_ENABLED_CHANGE_REQUEST',
495 ProxyMappingsEnabledChangeError: 'PROXY_MAPPINGS_ENABLED_CHANGE_ERROR',
496 RefreshProxyMappingsRequest: 'REFRESH_PROXY_MAPPINGS_REQUEST',
497 RefreshProxyMappingsResponse: 'REFRESH_PROXY_MAPPINGS_RESPONSE',
498 RefreshProxyMappingsError: 'REFRESH_PROXY_MAPPINGS_ERROR'
499 };
500
501 /***/ }),
502
503 /***/ "./scripts/iframe/integratedMessages/proxy/ProxyMessages.ts":
504 /*!******************************************************************!*\
505 !*** ./scripts/iframe/integratedMessages/proxy/ProxyMessages.ts ***!
506 \******************************************************************/
507 /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
508
509 "use strict";
510 __webpack_require__.r(__webpack_exports__);
511 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
512 /* harmony export */ "ProxyMessages": () => (/* binding */ ProxyMessages)
513 /* harmony export */ });
514 var ProxyMessages = {
515 FetchForms: 'FETCH_FORMS',
516 FetchForm: 'FETCH_FORM',
517 CreateFormFromTemplate: 'CREATE_FORM_FROM_TEMPLATE',
518 GetTemplateAvailability: 'GET_TEMPLATE_AVAILABILITY',
519 FetchAuth: 'FETCH_AUTH',
520 FetchMeetingsAndUsers: 'FETCH_MEETINGS_AND_USERS',
521 FetchContactsCreateSinceActivation: 'FETCH_CONTACTS_CREATED_SINCE_ACTIVATION',
522 FetchOrCreateMeetingUser: 'FETCH_OR_CREATE_MEETING_USER',
523 ConnectMeetingsCalendar: 'CONNECT_MEETINGS_CALENDAR',
524 TrackFormPreviewRender: 'TRACK_FORM_PREVIEW_RENDER',
525 TrackFormCreatedFromTemplate: 'TRACK_FORM_CREATED_FROM_TEMPLATE',
526 TrackFormCreationFailed: 'TRACK_FORM_CREATION_FAILED',
527 TrackMeetingPreviewRender: 'TRACK_MEETING_PREVIEW_RENDER',
528 TrackSidebarMetaChange: 'TRACK_SIDEBAR_META_CHANGE',
529 TrackReviewBannerRender: 'TRACK_REVIEW_BANNER_RENDER',
530 TrackReviewBannerInteraction: 'TRACK_REVIEW_BANNER_INTERACTION',
531 TrackReviewBannerDismissed: 'TRACK_REVIEW_BANNER_DISMISSED',
532 TrackPluginDeactivation: 'TRACK_PLUGIN_DEACTIVATION'
533 };
534
535 /***/ }),
536
537 /***/ "./scripts/lib/Raven.ts":
538 /*!******************************!*\
539 !*** ./scripts/lib/Raven.ts ***!
540 \******************************/
541 /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
542
543 "use strict";
544 __webpack_require__.r(__webpack_exports__);
545 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
546 /* harmony export */ "configureRaven": () => (/* binding */ configureRaven),
547 /* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
548 /* harmony export */ });
549 /* harmony import */ var raven_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! raven-js */ "./node_modules/raven-js/src/singleton.js");
550 /* harmony import */ var raven_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(raven_js__WEBPACK_IMPORTED_MODULE_0__);
551 /* harmony import */ var _constants_leadinConfig__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../constants/leadinConfig */ "./scripts/constants/leadinConfig.ts");
552
553
554 function configureRaven() {
555 if (_constants_leadinConfig__WEBPACK_IMPORTED_MODULE_1__.hubspotBaseUrl.indexOf('local') !== -1) {
556 return;
557 }
558 var domain = _constants_leadinConfig__WEBPACK_IMPORTED_MODULE_1__.hubspotBaseUrl.replace(/https?:\/\/app/, '');
559 raven_js__WEBPACK_IMPORTED_MODULE_0___default().config("https://a9f08e536ef66abb0bf90becc905b09e@exceptions".concat(domain, "/v2/1"), {
560 instrument: {
561 tryCatch: false
562 },
563 shouldSendCallback: function shouldSendCallback(data) {
564 return !!data && !!data.culprit && /plugins\/leadin\//.test(data.culprit);
565 },
566 release: _constants_leadinConfig__WEBPACK_IMPORTED_MODULE_1__.leadinPluginVersion
567 }).install();
568 raven_js__WEBPACK_IMPORTED_MODULE_0___default().setTagsContext({
569 v: _constants_leadinConfig__WEBPACK_IMPORTED_MODULE_1__.leadinPluginVersion,
570 php: _constants_leadinConfig__WEBPACK_IMPORTED_MODULE_1__.phpVersion,
571 wordpress: _constants_leadinConfig__WEBPACK_IMPORTED_MODULE_1__.wpVersion
572 });
573 raven_js__WEBPACK_IMPORTED_MODULE_0___default().setExtraContext({
574 hub: _constants_leadinConfig__WEBPACK_IMPORTED_MODULE_1__.portalId,
575 plugins: Object.keys(_constants_leadinConfig__WEBPACK_IMPORTED_MODULE_1__.plugins).map(function (name) {
576 return "".concat(name, "#").concat(_constants_leadinConfig__WEBPACK_IMPORTED_MODULE_1__.plugins[name]);
577 }).join(',')
578 });
579 }
580 /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = ((raven_js__WEBPACK_IMPORTED_MODULE_0___default()));
581
582 /***/ }),
583
584 /***/ "./scripts/utils/appUtils.ts":
585 /*!***********************************!*\
586 !*** ./scripts/utils/appUtils.ts ***!
587 \***********************************/
588 /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
589
590 "use strict";
591 __webpack_require__.r(__webpack_exports__);
592 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
593 /* harmony export */ "initApp": () => (/* binding */ initApp),
594 /* harmony export */ "initAppOnReady": () => (/* binding */ initAppOnReady)
595 /* harmony export */ });
596 /* harmony import */ var jquery__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! jquery */ "jquery");
597 /* harmony import */ var jquery__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(jquery__WEBPACK_IMPORTED_MODULE_0__);
598 /* harmony import */ var _lib_Raven__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../lib/Raven */ "./scripts/lib/Raven.ts");
599
600
601 function initApp(initFn) {
602 (0,_lib_Raven__WEBPACK_IMPORTED_MODULE_1__.configureRaven)();
603 _lib_Raven__WEBPACK_IMPORTED_MODULE_1__["default"].context(initFn);
604 }
605 function initAppOnReady(initFn) {
606 function main() {
607 jquery__WEBPACK_IMPORTED_MODULE_0___default()(initFn);
608 }
609 initApp(main);
610 }
611
612 /***/ }),
613
614 /***/ "./scripts/utils/backgroundAppUtils.ts":
615 /*!*********************************************!*\
616 !*** ./scripts/utils/backgroundAppUtils.ts ***!
617 \*********************************************/
618 /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
619
620 "use strict";
621 __webpack_require__.r(__webpack_exports__);
622 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
623 /* harmony export */ "getOrCreateBackgroundApp": () => (/* binding */ getOrCreateBackgroundApp),
624 /* harmony export */ "initBackgroundApp": () => (/* binding */ initBackgroundApp)
625 /* harmony export */ });
626 /* harmony import */ var _constants_leadinConfig__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../constants/leadinConfig */ "./scripts/constants/leadinConfig.ts");
627 /* harmony import */ var _appUtils__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./appUtils */ "./scripts/utils/appUtils.ts");
628 /* harmony import */ var _api_wordpressApiClient__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../api/wordpressApiClient */ "./scripts/api/wordpressApiClient.ts");
629
630
631
632 function initBackgroundApp(initFn) {
633 function main() {
634 if (Array.isArray(initFn)) {
635 initFn.forEach(function (callback) {
636 return callback();
637 });
638 } else {
639 initFn();
640 }
641 }
642 (0,_appUtils__WEBPACK_IMPORTED_MODULE_1__.initApp)(main);
643 }
644 var getLeadinConfig = function getLeadinConfig() {
645 return {
646 leadinPluginVersion: _constants_leadinConfig__WEBPACK_IMPORTED_MODULE_0__.leadinPluginVersion
647 };
648 };
649 var getOrCreateBackgroundApp = function getOrCreateBackgroundApp() {
650 var accessToken = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
651 var expiresIn = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
652 if (window.LeadinBackgroundApp) {
653 return window.LeadinBackgroundApp;
654 }
655 var _window = window,
656 IntegratedAppEmbedder = _window.IntegratedAppEmbedder,
657 IntegratedAppOptions = _window.IntegratedAppOptions;
658 var options = new IntegratedAppOptions().setLocale(_constants_leadinConfig__WEBPACK_IMPORTED_MODULE_0__.locale).setDeviceId(_constants_leadinConfig__WEBPACK_IMPORTED_MODULE_0__.deviceId).setLeadinConfig(getLeadinConfig()).setAccessToken(accessToken, expiresIn);
659 var embedder = new IntegratedAppEmbedder('integrated-plugin-proxy', _constants_leadinConfig__WEBPACK_IMPORTED_MODULE_0__.portalId, _constants_leadinConfig__WEBPACK_IMPORTED_MODULE_0__.hubspotBaseUrl, function () {}).setOptions(options);
660 embedder.attachTo(document.body, false);
661 embedder.setTokenRenewalCallback(_api_wordpressApiClient__WEBPACK_IMPORTED_MODULE_2__.fetchAccessToken);
662 embedder.postStartAppMessage(); // lets the app know all data has been passed to it
663 window.LeadinBackgroundApp = embedder;
664 return window.LeadinBackgroundApp;
665 };
666
667 /***/ }),
668
669 /***/ "./scripts/utils/queryParams.ts":
670 /*!**************************************!*\
671 !*** ./scripts/utils/queryParams.ts ***!
672 \**************************************/
673 /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
674
675 "use strict";
676 __webpack_require__.r(__webpack_exports__);
677 /* harmony export */ __webpack_require__.d(__webpack_exports__, {
678 /* harmony export */ "addQueryObjectToUrl": () => (/* binding */ addQueryObjectToUrl),
679 /* harmony export */ "removeQueryParamFromLocation": () => (/* binding */ removeQueryParamFromLocation)
680 /* harmony export */ });
681 function addQueryObjectToUrl(urlObject, queryParams) {
682 Object.keys(queryParams).forEach(function (key) {
683 urlObject.searchParams.append(key, queryParams[key]);
684 });
685 }
686 function removeQueryParamFromLocation(key) {
687 var location = new URL(window.location.href);
688 location.searchParams["delete"](key);
689 window.history.replaceState(null, '', location.href);
690 }
691
692 /***/ }),
693
694 /***/ "./node_modules/raven-js/src/configError.js":
695 /*!**************************************************!*\
696 !*** ./node_modules/raven-js/src/configError.js ***!
697 \**************************************************/
698 /***/ ((module) => {
699
700 function RavenConfigError(message) {
701 this.name = 'RavenConfigError';
702 this.message = message;
703 }
704 RavenConfigError.prototype = new Error();
705 RavenConfigError.prototype.constructor = RavenConfigError;
706
707 module.exports = RavenConfigError;
708
709
710 /***/ }),
711
712 /***/ "./node_modules/raven-js/src/console.js":
713 /*!**********************************************!*\
714 !*** ./node_modules/raven-js/src/console.js ***!
715 \**********************************************/
716 /***/ ((module) => {
717
718 var wrapMethod = function(console, level, callback) {
719 var originalConsoleLevel = console[level];
720 var originalConsole = console;
721
722 if (!(level in console)) {
723 return;
724 }
725
726 var sentryLevel = level === 'warn' ? 'warning' : level;
727
728 console[level] = function() {
729 var args = [].slice.call(arguments);
730
731 var msg = '' + args.join(' ');
732 var data = {level: sentryLevel, logger: 'console', extra: {arguments: args}};
733
734 if (level === 'assert') {
735 if (args[0] === false) {
736 // Default browsers message
737 msg = 'Assertion failed: ' + (args.slice(1).join(' ') || 'console.assert');
738 data.extra.arguments = args.slice(1);
739 callback && callback(msg, data);
740 }
741 } else {
742 callback && callback(msg, data);
743 }
744
745 // this fails for some browsers. :(
746 if (originalConsoleLevel) {
747 // IE9 doesn't allow calling apply on console functions directly
748 // See: https://stackoverflow.com/questions/5472938/does-ie9-support-console-log-and-is-it-a-real-function#answer-5473193
749 Function.prototype.apply.call(originalConsoleLevel, originalConsole, args);
750 }
751 };
752 };
753
754 module.exports = {
755 wrapMethod: wrapMethod
756 };
757
758
759 /***/ }),
760
761 /***/ "./node_modules/raven-js/src/raven.js":
762 /*!********************************************!*\
763 !*** ./node_modules/raven-js/src/raven.js ***!
764 \********************************************/
765 /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
766
767 /*global XDomainRequest:false */
768
769 var TraceKit = __webpack_require__(/*! ../vendor/TraceKit/tracekit */ "./node_modules/raven-js/vendor/TraceKit/tracekit.js");
770 var stringify = __webpack_require__(/*! ../vendor/json-stringify-safe/stringify */ "./node_modules/raven-js/vendor/json-stringify-safe/stringify.js");
771 var RavenConfigError = __webpack_require__(/*! ./configError */ "./node_modules/raven-js/src/configError.js");
772
773 var utils = __webpack_require__(/*! ./utils */ "./node_modules/raven-js/src/utils.js");
774 var isError = utils.isError;
775 var isObject = utils.isObject;
776 var isObject = utils.isObject;
777 var isErrorEvent = utils.isErrorEvent;
778 var isUndefined = utils.isUndefined;
779 var isFunction = utils.isFunction;
780 var isString = utils.isString;
781 var isEmptyObject = utils.isEmptyObject;
782 var each = utils.each;
783 var objectMerge = utils.objectMerge;
784 var truncate = utils.truncate;
785 var objectFrozen = utils.objectFrozen;
786 var hasKey = utils.hasKey;
787 var joinRegExp = utils.joinRegExp;
788 var urlencode = utils.urlencode;
789 var uuid4 = utils.uuid4;
790 var htmlTreeAsString = utils.htmlTreeAsString;
791 var isSameException = utils.isSameException;
792 var isSameStacktrace = utils.isSameStacktrace;
793 var parseUrl = utils.parseUrl;
794 var fill = utils.fill;
795
796 var wrapConsoleMethod = (__webpack_require__(/*! ./console */ "./node_modules/raven-js/src/console.js").wrapMethod);
797
798 var dsnKeys = 'source protocol user pass host port path'.split(' '),
799 dsnPattern = /^(?:(\w+):)?\/\/(?:(\w+)(:\w+)?@)?([\w\.-]+)(?::(\d+))?(\/.*)/;
800
801 function now() {
802 return +new Date();
803 }
804
805 // This is to be defensive in environments where window does not exist (see https://github.com/getsentry/raven-js/pull/785)
806 var _window =
807 typeof window !== 'undefined'
808 ? window
809 : typeof __webpack_require__.g !== 'undefined' ? __webpack_require__.g : typeof self !== 'undefined' ? self : {};
810 var _document = _window.document;
811 var _navigator = _window.navigator;
812
813 function keepOriginalCallback(original, callback) {
814 return isFunction(callback)
815 ? function(data) {
816 return callback(data, original);
817 }
818 : callback;
819 }
820
821 // First, check for JSON support
822 // If there is no JSON, we no-op the core features of Raven
823 // since JSON is required to encode the payload
824 function Raven() {
825 this._hasJSON = !!(typeof JSON === 'object' && JSON.stringify);
826 // Raven can run in contexts where there's no document (react-native)
827 this._hasDocument = !isUndefined(_document);
828 this._hasNavigator = !isUndefined(_navigator);
829 this._lastCapturedException = null;
830 this._lastData = null;
831 this._lastEventId = null;
832 this._globalServer = null;
833 this._globalKey = null;
834 this._globalProject = null;
835 this._globalContext = {};
836 this._globalOptions = {
837 logger: 'javascript',
838 ignoreErrors: [],
839 ignoreUrls: [],
840 whitelistUrls: [],
841 includePaths: [],
842 collectWindowErrors: true,
843 maxMessageLength: 0,
844
845 // By default, truncates URL values to 250 chars
846 maxUrlLength: 250,
847 stackTraceLimit: 50,
848 autoBreadcrumbs: true,
849 instrument: true,
850 sampleRate: 1
851 };
852 this._ignoreOnError = 0;
853 this._isRavenInstalled = false;
854 this._originalErrorStackTraceLimit = Error.stackTraceLimit;
855 // capture references to window.console *and* all its methods first
856 // before the console plugin has a chance to monkey patch
857 this._originalConsole = _window.console || {};
858 this._originalConsoleMethods = {};
859 this._plugins = [];
860 this._startTime = now();
861 this._wrappedBuiltIns = [];
862 this._breadcrumbs = [];
863 this._lastCapturedEvent = null;
864 this._keypressTimeout;
865 this._location = _window.location;
866 this._lastHref = this._location && this._location.href;
867 this._resetBackoff();
868
869 // eslint-disable-next-line guard-for-in
870 for (var method in this._originalConsole) {
871 this._originalConsoleMethods[method] = this._originalConsole[method];
872 }
873 }
874
875 /*
876 * The core Raven singleton
877 *
878 * @this {Raven}
879 */
880
881 Raven.prototype = {
882 // Hardcode version string so that raven source can be loaded directly via
883 // webpack (using a build step causes webpack #1617). Grunt verifies that
884 // this value matches package.json during build.
885 // See: https://github.com/getsentry/raven-js/issues/465
886 VERSION: '3.19.1',
887
888 debug: false,
889
890 TraceKit: TraceKit, // alias to TraceKit
891
892 /*
893 * Configure Raven with a DSN and extra options
894 *
895 * @param {string} dsn The public Sentry DSN
896 * @param {object} options Set of global options [optional]
897 * @return {Raven}
898 */
899 config: function(dsn, options) {
900 var self = this;
901
902 if (self._globalServer) {
903 this._logDebug('error', 'Error: Raven has already been configured');
904 return self;
905 }
906 if (!dsn) return self;
907
908 var globalOptions = self._globalOptions;
909
910 // merge in options
911 if (options) {
912 each(options, function(key, value) {
913 // tags and extra are special and need to be put into context
914 if (key === 'tags' || key === 'extra' || key === 'user') {
915 self._globalContext[key] = value;
916 } else {
917 globalOptions[key] = value;
918 }
919 });
920 }
921
922 self.setDSN(dsn);
923
924 // "Script error." is hard coded into browsers for errors that it can't read.
925 // this is the result of a script being pulled in from an external domain and CORS.
926 globalOptions.ignoreErrors.push(/^Script error\.?$/);
927 globalOptions.ignoreErrors.push(/^Javascript error: Script error\.? on line 0$/);
928
929 // join regexp rules into one big rule
930 globalOptions.ignoreErrors = joinRegExp(globalOptions.ignoreErrors);
931 globalOptions.ignoreUrls = globalOptions.ignoreUrls.length
932 ? joinRegExp(globalOptions.ignoreUrls)
933 : false;
934 globalOptions.whitelistUrls = globalOptions.whitelistUrls.length
935 ? joinRegExp(globalOptions.whitelistUrls)
936 : false;
937 globalOptions.includePaths = joinRegExp(globalOptions.includePaths);
938 globalOptions.maxBreadcrumbs = Math.max(
939 0,
940 Math.min(globalOptions.maxBreadcrumbs || 100, 100)
941 ); // default and hard limit is 100
942
943 var autoBreadcrumbDefaults = {
944 xhr: true,
945 console: true,
946 dom: true,
947 location: true
948 };
949
950 var autoBreadcrumbs = globalOptions.autoBreadcrumbs;
951 if ({}.toString.call(autoBreadcrumbs) === '[object Object]') {
952 autoBreadcrumbs = objectMerge(autoBreadcrumbDefaults, autoBreadcrumbs);
953 } else if (autoBreadcrumbs !== false) {
954 autoBreadcrumbs = autoBreadcrumbDefaults;
955 }
956 globalOptions.autoBreadcrumbs = autoBreadcrumbs;
957
958 var instrumentDefaults = {
959 tryCatch: true
960 };
961
962 var instrument = globalOptions.instrument;
963 if ({}.toString.call(instrument) === '[object Object]') {
964 instrument = objectMerge(instrumentDefaults, instrument);
965 } else if (instrument !== false) {
966 instrument = instrumentDefaults;
967 }
968 globalOptions.instrument = instrument;
969
970 TraceKit.collectWindowErrors = !!globalOptions.collectWindowErrors;
971
972 // return for chaining
973 return self;
974 },
975
976 /*
977 * Installs a global window.onerror error handler
978 * to capture and report uncaught exceptions.
979 * At this point, install() is required to be called due
980 * to the way TraceKit is set up.
981 *
982 * @return {Raven}
983 */
984 install: function() {
985 var self = this;
986 if (self.isSetup() && !self._isRavenInstalled) {
987 TraceKit.report.subscribe(function() {
988 self._handleOnErrorStackInfo.apply(self, arguments);
989 });
990 if (self._globalOptions.instrument && self._globalOptions.instrument.tryCatch) {
991 self._instrumentTryCatch();
992 }
993
994 if (self._globalOptions.autoBreadcrumbs) self._instrumentBreadcrumbs();
995
996 // Install all of the plugins
997 self._drainPlugins();
998
999 self._isRavenInstalled = true;
1000 }
1001
1002 Error.stackTraceLimit = self._globalOptions.stackTraceLimit;
1003 return this;
1004 },
1005
1006 /*
1007 * Set the DSN (can be called multiple time unlike config)
1008 *
1009 * @param {string} dsn The public Sentry DSN
1010 */
1011 setDSN: function(dsn) {
1012 var self = this,
1013 uri = self._parseDSN(dsn),
1014 lastSlash = uri.path.lastIndexOf('/'),
1015 path = uri.path.substr(1, lastSlash);
1016
1017 self._dsn = dsn;
1018 self._globalKey = uri.user;
1019 self._globalSecret = uri.pass && uri.pass.substr(1);
1020 self._globalProject = uri.path.substr(lastSlash + 1);
1021
1022 self._globalServer = self._getGlobalServer(uri);
1023
1024 self._globalEndpoint =
1025 self._globalServer + '/' + path + 'api/' + self._globalProject + '/store/';
1026
1027 // Reset backoff state since we may be pointing at a
1028 // new project/server
1029 this._resetBackoff();
1030 },
1031
1032 /*
1033 * Wrap code within a context so Raven can capture errors
1034 * reliably across domains that is executed immediately.
1035 *
1036 * @param {object} options A specific set of options for this context [optional]
1037 * @param {function} func The callback to be immediately executed within the context
1038 * @param {array} args An array of arguments to be called with the callback [optional]
1039 */
1040 context: function(options, func, args) {
1041 if (isFunction(options)) {
1042 args = func || [];
1043 func = options;
1044 options = undefined;
1045 }
1046
1047 return this.wrap(options, func).apply(this, args);
1048 },
1049
1050 /*
1051 * Wrap code within a context and returns back a new function to be executed
1052 *
1053 * @param {object} options A specific set of options for this context [optional]
1054 * @param {function} func The function to be wrapped in a new context
1055 * @param {function} func A function to call before the try/catch wrapper [optional, private]
1056 * @return {function} The newly wrapped functions with a context
1057 */
1058 wrap: function(options, func, _before) {
1059 var self = this;
1060 // 1 argument has been passed, and it's not a function
1061 // so just return it
1062 if (isUndefined(func) && !isFunction(options)) {
1063 return options;
1064 }
1065
1066 // options is optional
1067 if (isFunction(options)) {
1068 func = options;
1069 options = undefined;
1070 }
1071
1072 // At this point, we've passed along 2 arguments, and the second one
1073 // is not a function either, so we'll just return the second argument.
1074 if (!isFunction(func)) {
1075 return func;
1076 }
1077
1078 // We don't wanna wrap it twice!
1079 try {
1080 if (func.__raven__) {
1081 return func;
1082 }
1083
1084 // If this has already been wrapped in the past, return that
1085 if (func.__raven_wrapper__) {
1086 return func.__raven_wrapper__;
1087 }
1088 } catch (e) {
1089 // Just accessing custom props in some Selenium environments
1090 // can cause a "Permission denied" exception (see raven-js#495).
1091 // Bail on wrapping and return the function as-is (defers to window.onerror).
1092 return func;
1093 }
1094
1095 function wrapped() {
1096 var args = [],
1097 i = arguments.length,
1098 deep = !options || (options && options.deep !== false);
1099
1100 if (_before && isFunction(_before)) {
1101 _before.apply(this, arguments);
1102 }
1103
1104 // Recursively wrap all of a function's arguments that are
1105 // functions themselves.
1106 while (i--) args[i] = deep ? self.wrap(options, arguments[i]) : arguments[i];
1107
1108 try {
1109 // Attempt to invoke user-land function
1110 // NOTE: If you are a Sentry user, and you are seeing this stack frame, it
1111 // means Raven caught an error invoking your application code. This is
1112 // expected behavior and NOT indicative of a bug with Raven.js.
1113 return func.apply(this, args);
1114 } catch (e) {
1115 self._ignoreNextOnError();
1116 self.captureException(e, options);
1117 throw e;
1118 }
1119 }
1120
1121 // copy over properties of the old function
1122 for (var property in func) {
1123 if (hasKey(func, property)) {
1124 wrapped[property] = func[property];
1125 }
1126 }
1127 wrapped.prototype = func.prototype;
1128
1129 func.__raven_wrapper__ = wrapped;
1130 // Signal that this function has been wrapped already
1131 // for both debugging and to prevent it to being wrapped twice
1132 wrapped.__raven__ = true;
1133 wrapped.__inner__ = func;
1134
1135 return wrapped;
1136 },
1137
1138 /*
1139 * Uninstalls the global error handler.
1140 *
1141 * @return {Raven}
1142 */
1143 uninstall: function() {
1144 TraceKit.report.uninstall();
1145
1146 this._restoreBuiltIns();
1147
1148 Error.stackTraceLimit = this._originalErrorStackTraceLimit;
1149 this._isRavenInstalled = false;
1150
1151 return this;
1152 },
1153
1154 /*
1155 * Manually capture an exception and send it over to Sentry
1156 *
1157 * @param {error} ex An exception to be logged
1158 * @param {object} options A specific set of options for this error [optional]
1159 * @return {Raven}
1160 */
1161 captureException: function(ex, options) {
1162 // Cases for sending ex as a message, rather than an exception
1163 var isNotError = !isError(ex);
1164 var isNotErrorEvent = !isErrorEvent(ex);
1165 var isErrorEventWithoutError = isErrorEvent(ex) && !ex.error;
1166
1167 if ((isNotError && isNotErrorEvent) || isErrorEventWithoutError) {
1168 return this.captureMessage(
1169 ex,
1170 objectMerge(
1171 {
1172 trimHeadFrames: 1,
1173 stacktrace: true // if we fall back to captureMessage, default to attempting a new trace
1174 },
1175 options
1176 )
1177 );
1178 }
1179
1180 // Get actual Error from ErrorEvent
1181 if (isErrorEvent(ex)) ex = ex.error;
1182
1183 // Store the raw exception object for potential debugging and introspection
1184 this._lastCapturedException = ex;
1185
1186 // TraceKit.report will re-raise any exception passed to it,
1187 // which means you have to wrap it in try/catch. Instead, we
1188 // can wrap it here and only re-raise if TraceKit.report
1189 // raises an exception different from the one we asked to
1190 // report on.
1191 try {
1192 var stack = TraceKit.computeStackTrace(ex);
1193 this._handleStackInfo(stack, options);
1194 } catch (ex1) {
1195 if (ex !== ex1) {
1196 throw ex1;
1197 }
1198 }
1199
1200 return this;
1201 },
1202
1203 /*
1204 * Manually send a message to Sentry
1205 *
1206 * @param {string} msg A plain message to be captured in Sentry
1207 * @param {object} options A specific set of options for this message [optional]
1208 * @return {Raven}
1209 */
1210 captureMessage: function(msg, options) {
1211 // config() automagically converts ignoreErrors from a list to a RegExp so we need to test for an
1212 // early call; we'll error on the side of logging anything called before configuration since it's
1213 // probably something you should see:
1214 if (
1215 !!this._globalOptions.ignoreErrors.test &&
1216 this._globalOptions.ignoreErrors.test(msg)
1217 ) {
1218 return;
1219 }
1220
1221 options = options || {};
1222
1223 var data = objectMerge(
1224 {
1225 message: msg + '' // Make sure it's actually a string
1226 },
1227 options
1228 );
1229
1230 var ex;
1231 // Generate a "synthetic" stack trace from this point.
1232 // NOTE: If you are a Sentry user, and you are seeing this stack frame, it is NOT indicative
1233 // of a bug with Raven.js. Sentry generates synthetic traces either by configuration,
1234 // or if it catches a thrown object without a "stack" property.
1235 try {
1236 throw new Error(msg);
1237 } catch (ex1) {
1238 ex = ex1;
1239 }
1240
1241 // null exception name so `Error` isn't prefixed to msg
1242 ex.name = null;
1243 var stack = TraceKit.computeStackTrace(ex);
1244
1245 // stack[0] is `throw new Error(msg)` call itself, we are interested in the frame that was just before that, stack[1]
1246 var initialCall = stack.stack[1];
1247
1248 var fileurl = (initialCall && initialCall.url) || '';
1249
1250 if (
1251 !!this._globalOptions.ignoreUrls.test &&
1252 this._globalOptions.ignoreUrls.test(fileurl)
1253 ) {
1254 return;
1255 }
1256
1257 if (
1258 !!this._globalOptions.whitelistUrls.test &&
1259 !this._globalOptions.whitelistUrls.test(fileurl)
1260 ) {
1261 return;
1262 }
1263
1264 if (this._globalOptions.stacktrace || (options && options.stacktrace)) {
1265 options = objectMerge(
1266 {
1267 // fingerprint on msg, not stack trace (legacy behavior, could be
1268 // revisited)
1269 fingerprint: msg,
1270 // since we know this is a synthetic trace, the top N-most frames
1271 // MUST be from Raven.js, so mark them as in_app later by setting
1272 // trimHeadFrames
1273 trimHeadFrames: (options.trimHeadFrames || 0) + 1
1274 },
1275 options
1276 );
1277
1278 var frames = this._prepareFrames(stack, options);
1279 data.stacktrace = {
1280 // Sentry expects frames oldest to newest
1281 frames: frames.reverse()
1282 };
1283 }
1284
1285 // Fire away!
1286 this._send(data);
1287
1288 return this;
1289 },
1290
1291 captureBreadcrumb: function(obj) {
1292 var crumb = objectMerge(
1293 {
1294 timestamp: now() / 1000
1295 },
1296 obj
1297 );
1298
1299 if (isFunction(this._globalOptions.breadcrumbCallback)) {
1300 var result = this._globalOptions.breadcrumbCallback(crumb);
1301
1302 if (isObject(result) && !isEmptyObject(result)) {
1303 crumb = result;
1304 } else if (result === false) {
1305 return this;
1306 }
1307 }
1308
1309 this._breadcrumbs.push(crumb);
1310 if (this._breadcrumbs.length > this._globalOptions.maxBreadcrumbs) {
1311 this._breadcrumbs.shift();
1312 }
1313 return this;
1314 },
1315
1316 addPlugin: function(plugin /*arg1, arg2, ... argN*/) {
1317 var pluginArgs = [].slice.call(arguments, 1);
1318
1319 this._plugins.push([plugin, pluginArgs]);
1320 if (this._isRavenInstalled) {
1321 this._drainPlugins();
1322 }
1323
1324 return this;
1325 },
1326
1327 /*
1328 * Set/clear a user to be sent along with the payload.
1329 *
1330 * @param {object} user An object representing user data [optional]
1331 * @return {Raven}
1332 */
1333 setUserContext: function(user) {
1334 // Intentionally do not merge here since that's an unexpected behavior.
1335 this._globalContext.user = user;
1336
1337 return this;
1338 },
1339
1340 /*
1341 * Merge extra attributes to be sent along with the payload.
1342 *
1343 * @param {object} extra An object representing extra data [optional]
1344 * @return {Raven}
1345 */
1346 setExtraContext: function(extra) {
1347 this._mergeContext('extra', extra);
1348
1349 return this;
1350 },
1351
1352 /*
1353 * Merge tags to be sent along with the payload.
1354 *
1355 * @param {object} tags An object representing tags [optional]
1356 * @return {Raven}
1357 */
1358 setTagsContext: function(tags) {
1359 this._mergeContext('tags', tags);
1360
1361 return this;
1362 },
1363
1364 /*
1365 * Clear all of the context.
1366 *
1367 * @return {Raven}
1368 */
1369 clearContext: function() {
1370 this._globalContext = {};
1371
1372 return this;
1373 },
1374
1375 /*
1376 * Get a copy of the current context. This cannot be mutated.
1377 *
1378 * @return {object} copy of context
1379 */
1380 getContext: function() {
1381 // lol javascript
1382 return JSON.parse(stringify(this._globalContext));
1383 },
1384
1385 /*
1386 * Set environment of application
1387 *
1388 * @param {string} environment Typically something like 'production'.
1389 * @return {Raven}
1390 */
1391 setEnvironment: function(environment) {
1392 this._globalOptions.environment = environment;
1393
1394 return this;
1395 },
1396
1397 /*
1398 * Set release version of application
1399 *
1400 * @param {string} release Typically something like a git SHA to identify version
1401 * @return {Raven}
1402 */
1403 setRelease: function(release) {
1404 this._globalOptions.release = release;
1405
1406 return this;
1407 },
1408
1409 /*
1410 * Set the dataCallback option
1411 *
1412 * @param {function} callback The callback to run which allows the
1413 * data blob to be mutated before sending
1414 * @return {Raven}
1415 */
1416 setDataCallback: function(callback) {
1417 var original = this._globalOptions.dataCallback;
1418 this._globalOptions.dataCallback = keepOriginalCallback(original, callback);
1419 return this;
1420 },
1421
1422 /*
1423 * Set the breadcrumbCallback option
1424 *
1425 * @param {function} callback The callback to run which allows filtering
1426 * or mutating breadcrumbs
1427 * @return {Raven}
1428 */
1429 setBreadcrumbCallback: function(callback) {
1430 var original = this._globalOptions.breadcrumbCallback;
1431 this._globalOptions.breadcrumbCallback = keepOriginalCallback(original, callback);
1432 return this;
1433 },
1434
1435 /*
1436 * Set the shouldSendCallback option
1437 *
1438 * @param {function} callback The callback to run which allows
1439 * introspecting the blob before sending
1440 * @return {Raven}
1441 */
1442 setShouldSendCallback: function(callback) {
1443 var original = this._globalOptions.shouldSendCallback;
1444 this._globalOptions.shouldSendCallback = keepOriginalCallback(original, callback);
1445 return this;
1446 },
1447
1448 /**
1449 * Override the default HTTP transport mechanism that transmits data
1450 * to the Sentry server.
1451 *
1452 * @param {function} transport Function invoked instead of the default
1453 * `makeRequest` handler.
1454 *
1455 * @return {Raven}
1456 */
1457 setTransport: function(transport) {
1458 this._globalOptions.transport = transport;
1459
1460 return this;
1461 },
1462
1463 /*
1464 * Get the latest raw exception that was captured by Raven.
1465 *
1466 * @return {error}
1467 */
1468 lastException: function() {
1469 return this._lastCapturedException;
1470 },
1471
1472 /*
1473 * Get the last event id
1474 *
1475 * @return {string}
1476 */
1477 lastEventId: function() {
1478 return this._lastEventId;
1479 },
1480
1481 /*
1482 * Determine if Raven is setup and ready to go.
1483 *
1484 * @return {boolean}
1485 */
1486 isSetup: function() {
1487 if (!this._hasJSON) return false; // needs JSON support
1488 if (!this._globalServer) {
1489 if (!this.ravenNotConfiguredError) {
1490 this.ravenNotConfiguredError = true;
1491 this._logDebug('error', 'Error: Raven has not been configured.');
1492 }
1493 return false;
1494 }
1495 return true;
1496 },
1497
1498 afterLoad: function() {
1499 // TODO: remove window dependence?
1500
1501 // Attempt to initialize Raven on load
1502 var RavenConfig = _window.RavenConfig;
1503 if (RavenConfig) {
1504 this.config(RavenConfig.dsn, RavenConfig.config).install();
1505 }
1506 },
1507
1508 showReportDialog: function(options) {
1509 if (
1510 !_document // doesn't work without a document (React native)
1511 )
1512 return;
1513
1514 options = options || {};
1515
1516 var lastEventId = options.eventId || this.lastEventId();
1517 if (!lastEventId) {
1518 throw new RavenConfigError('Missing eventId');
1519 }
1520
1521 var dsn = options.dsn || this._dsn;
1522 if (!dsn) {
1523 throw new RavenConfigError('Missing DSN');
1524 }
1525
1526 var encode = encodeURIComponent;
1527 var qs = '';
1528 qs += '?eventId=' + encode(lastEventId);
1529 qs += '&dsn=' + encode(dsn);
1530
1531 var user = options.user || this._globalContext.user;
1532 if (user) {
1533 if (user.name) qs += '&name=' + encode(user.name);
1534 if (user.email) qs += '&email=' + encode(user.email);
1535 }
1536
1537 var globalServer = this._getGlobalServer(this._parseDSN(dsn));
1538
1539 var script = _document.createElement('script');
1540 script.async = true;
1541 script.src = globalServer + '/api/embed/error-page/' + qs;
1542 (_document.head || _document.body).appendChild(script);
1543 },
1544
1545 /**** Private functions ****/
1546 _ignoreNextOnError: function() {
1547 var self = this;
1548 this._ignoreOnError += 1;
1549 setTimeout(function() {
1550 // onerror should trigger before setTimeout
1551 self._ignoreOnError -= 1;
1552 });
1553 },
1554
1555 _triggerEvent: function(eventType, options) {
1556 // NOTE: `event` is a native browser thing, so let's avoid conflicting wiht it
1557 var evt, key;
1558
1559 if (!this._hasDocument) return;
1560
1561 options = options || {};
1562
1563 eventType = 'raven' + eventType.substr(0, 1).toUpperCase() + eventType.substr(1);
1564
1565 if (_document.createEvent) {
1566 evt = _document.createEvent('HTMLEvents');
1567 evt.initEvent(eventType, true, true);
1568 } else {
1569 evt = _document.createEventObject();
1570 evt.eventType = eventType;
1571 }
1572
1573 for (key in options)
1574 if (hasKey(options, key)) {
1575 evt[key] = options[key];
1576 }
1577
1578 if (_document.createEvent) {
1579 // IE9 if standards
1580 _document.dispatchEvent(evt);
1581 } else {
1582 // IE8 regardless of Quirks or Standards
1583 // IE9 if quirks
1584 try {
1585 _document.fireEvent('on' + evt.eventType.toLowerCase(), evt);
1586 } catch (e) {
1587 // Do nothing
1588 }
1589 }
1590 },
1591
1592 /**
1593 * Wraps addEventListener to capture UI breadcrumbs
1594 * @param evtName the event name (e.g. "click")
1595 * @returns {Function}
1596 * @private
1597 */
1598 _breadcrumbEventHandler: function(evtName) {
1599 var self = this;
1600 return function(evt) {
1601 // reset keypress timeout; e.g. triggering a 'click' after
1602 // a 'keypress' will reset the keypress debounce so that a new
1603 // set of keypresses can be recorded
1604 self._keypressTimeout = null;
1605
1606 // It's possible this handler might trigger multiple times for the same
1607 // event (e.g. event propagation through node ancestors). Ignore if we've
1608 // already captured the event.
1609 if (self._lastCapturedEvent === evt) return;
1610
1611 self._lastCapturedEvent = evt;
1612
1613 // try/catch both:
1614 // - accessing evt.target (see getsentry/raven-js#838, #768)
1615 // - `htmlTreeAsString` because it's complex, and just accessing the DOM incorrectly
1616 // can throw an exception in some circumstances.
1617 var target;
1618 try {
1619 target = htmlTreeAsString(evt.target);
1620 } catch (e) {
1621 target = '<unknown>';
1622 }
1623
1624 self.captureBreadcrumb({
1625 category: 'ui.' + evtName, // e.g. ui.click, ui.input
1626 message: target
1627 });
1628 };
1629 },
1630
1631 /**
1632 * Wraps addEventListener to capture keypress UI events
1633 * @returns {Function}
1634 * @private
1635 */
1636 _keypressEventHandler: function() {
1637 var self = this,
1638 debounceDuration = 1000; // milliseconds
1639
1640 // TODO: if somehow user switches keypress target before
1641 // debounce timeout is triggered, we will only capture
1642 // a single breadcrumb from the FIRST target (acceptable?)
1643 return function(evt) {
1644 var target;
1645 try {
1646 target = evt.target;
1647 } catch (e) {
1648 // just accessing event properties can throw an exception in some rare circumstances
1649 // see: https://github.com/getsentry/raven-js/issues/838
1650 return;
1651 }
1652 var tagName = target && target.tagName;
1653
1654 // only consider keypress events on actual input elements
1655 // this will disregard keypresses targeting body (e.g. tabbing
1656 // through elements, hotkeys, etc)
1657 if (
1658 !tagName ||
1659 (tagName !== 'INPUT' && tagName !== 'TEXTAREA' && !target.isContentEditable)
1660 )
1661 return;
1662
1663 // record first keypress in a series, but ignore subsequent
1664 // keypresses until debounce clears
1665 var timeout = self._keypressTimeout;
1666 if (!timeout) {
1667 self._breadcrumbEventHandler('input')(evt);
1668 }
1669 clearTimeout(timeout);
1670 self._keypressTimeout = setTimeout(function() {
1671 self._keypressTimeout = null;
1672 }, debounceDuration);
1673 };
1674 },
1675
1676 /**
1677 * Captures a breadcrumb of type "navigation", normalizing input URLs
1678 * @param to the originating URL
1679 * @param from the target URL
1680 * @private
1681 */
1682 _captureUrlChange: function(from, to) {
1683 var parsedLoc = parseUrl(this._location.href);
1684 var parsedTo = parseUrl(to);
1685 var parsedFrom = parseUrl(from);
1686
1687 // because onpopstate only tells you the "new" (to) value of location.href, and
1688 // not the previous (from) value, we need to track the value of the current URL
1689 // state ourselves
1690 this._lastHref = to;
1691
1692 // Use only the path component of the URL if the URL matches the current
1693 // document (almost all the time when using pushState)
1694 if (parsedLoc.protocol === parsedTo.protocol && parsedLoc.host === parsedTo.host)
1695 to = parsedTo.relative;
1696 if (parsedLoc.protocol === parsedFrom.protocol && parsedLoc.host === parsedFrom.host)
1697 from = parsedFrom.relative;
1698
1699 this.captureBreadcrumb({
1700 category: 'navigation',
1701 data: {
1702 to: to,
1703 from: from
1704 }
1705 });
1706 },
1707
1708 /**
1709 * Wrap timer functions and event targets to catch errors and provide
1710 * better metadata.
1711 */
1712 _instrumentTryCatch: function() {
1713 var self = this;
1714
1715 var wrappedBuiltIns = self._wrappedBuiltIns;
1716
1717 function wrapTimeFn(orig) {
1718 return function(fn, t) {
1719 // preserve arity
1720 // Make a copy of the arguments to prevent deoptimization
1721 // https://github.com/petkaantonov/bluebird/wiki/Optimization-killers#32-leaking-arguments
1722 var args = new Array(arguments.length);
1723 for (var i = 0; i < args.length; ++i) {
1724 args[i] = arguments[i];
1725 }
1726 var originalCallback = args[0];
1727 if (isFunction(originalCallback)) {
1728 args[0] = self.wrap(originalCallback);
1729 }
1730
1731 // IE < 9 doesn't support .call/.apply on setInterval/setTimeout, but it
1732 // also supports only two arguments and doesn't care what this is, so we
1733 // can just call the original function directly.
1734 if (orig.apply) {
1735 return orig.apply(this, args);
1736 } else {
1737 return orig(args[0], args[1]);
1738 }
1739 };
1740 }
1741
1742 var autoBreadcrumbs = this._globalOptions.autoBreadcrumbs;
1743
1744 function wrapEventTarget(global) {
1745 var proto = _window[global] && _window[global].prototype;
1746 if (proto && proto.hasOwnProperty && proto.hasOwnProperty('addEventListener')) {
1747 fill(
1748 proto,
1749 'addEventListener',
1750 function(orig) {
1751 return function(evtName, fn, capture, secure) {
1752 // preserve arity
1753 try {
1754 if (fn && fn.handleEvent) {
1755 fn.handleEvent = self.wrap(fn.handleEvent);
1756 }
1757 } catch (err) {
1758 // can sometimes get 'Permission denied to access property "handle Event'
1759 }
1760
1761 // More breadcrumb DOM capture ... done here and not in `_instrumentBreadcrumbs`
1762 // so that we don't have more than one wrapper function
1763 var before, clickHandler, keypressHandler;
1764
1765 if (
1766 autoBreadcrumbs &&
1767 autoBreadcrumbs.dom &&
1768 (global === 'EventTarget' || global === 'Node')
1769 ) {
1770 // NOTE: generating multiple handlers per addEventListener invocation, should
1771 // revisit and verify we can just use one (almost certainly)
1772 clickHandler = self._breadcrumbEventHandler('click');
1773 keypressHandler = self._keypressEventHandler();
1774 before = function(evt) {
1775 // need to intercept every DOM event in `before` argument, in case that
1776 // same wrapped method is re-used for different events (e.g. mousemove THEN click)
1777 // see #724
1778 if (!evt) return;
1779
1780 var eventType;
1781 try {
1782 eventType = evt.type;
1783 } catch (e) {
1784 // just accessing event properties can throw an exception in some rare circumstances
1785 // see: https://github.com/getsentry/raven-js/issues/838
1786 return;
1787 }
1788 if (eventType === 'click') return clickHandler(evt);
1789 else if (eventType === 'keypress') return keypressHandler(evt);
1790 };
1791 }
1792 return orig.call(
1793 this,
1794 evtName,
1795 self.wrap(fn, undefined, before),
1796 capture,
1797 secure
1798 );
1799 };
1800 },
1801 wrappedBuiltIns
1802 );
1803 fill(
1804 proto,
1805 'removeEventListener',
1806 function(orig) {
1807 return function(evt, fn, capture, secure) {
1808 try {
1809 fn = fn && (fn.__raven_wrapper__ ? fn.__raven_wrapper__ : fn);
1810 } catch (e) {
1811 // ignore, accessing __raven_wrapper__ will throw in some Selenium environments
1812 }
1813 return orig.call(this, evt, fn, capture, secure);
1814 };
1815 },
1816 wrappedBuiltIns
1817 );
1818 }
1819 }
1820
1821 fill(_window, 'setTimeout', wrapTimeFn, wrappedBuiltIns);
1822 fill(_window, 'setInterval', wrapTimeFn, wrappedBuiltIns);
1823 if (_window.requestAnimationFrame) {
1824 fill(
1825 _window,
1826 'requestAnimationFrame',
1827 function(orig) {
1828 return function(cb) {
1829 return orig(self.wrap(cb));
1830 };
1831 },
1832 wrappedBuiltIns
1833 );
1834 }
1835
1836 // event targets borrowed from bugsnag-js:
1837 // https://github.com/bugsnag/bugsnag-js/blob/master/src/bugsnag.js#L666
1838 var eventTargets = [
1839 'EventTarget',
1840 'Window',
1841 'Node',
1842 'ApplicationCache',
1843 'AudioTrackList',
1844 'ChannelMergerNode',
1845 'CryptoOperation',
1846 'EventSource',
1847 'FileReader',
1848 'HTMLUnknownElement',
1849 'IDBDatabase',
1850 'IDBRequest',
1851 'IDBTransaction',
1852 'KeyOperation',
1853 'MediaController',
1854 'MessagePort',
1855 'ModalWindow',
1856 'Notification',
1857 'SVGElementInstance',
1858 'Screen',
1859 'TextTrack',
1860 'TextTrackCue',
1861 'TextTrackList',
1862 'WebSocket',
1863 'WebSocketWorker',
1864 'Worker',
1865 'XMLHttpRequest',
1866 'XMLHttpRequestEventTarget',
1867 'XMLHttpRequestUpload'
1868 ];
1869 for (var i = 0; i < eventTargets.length; i++) {
1870 wrapEventTarget(eventTargets[i]);
1871 }
1872 },
1873
1874 /**
1875 * Instrument browser built-ins w/ breadcrumb capturing
1876 * - XMLHttpRequests
1877 * - DOM interactions (click/typing)
1878 * - window.location changes
1879 * - console
1880 *
1881 * Can be disabled or individually configured via the `autoBreadcrumbs` config option
1882 */
1883 _instrumentBreadcrumbs: function() {
1884 var self = this;
1885 var autoBreadcrumbs = this._globalOptions.autoBreadcrumbs;
1886
1887 var wrappedBuiltIns = self._wrappedBuiltIns;
1888
1889 function wrapProp(prop, xhr) {
1890 if (prop in xhr && isFunction(xhr[prop])) {
1891 fill(xhr, prop, function(orig) {
1892 return self.wrap(orig);
1893 }); // intentionally don't track filled methods on XHR instances
1894 }
1895 }
1896
1897 if (autoBreadcrumbs.xhr && 'XMLHttpRequest' in _window) {
1898 var xhrproto = XMLHttpRequest.prototype;
1899 fill(
1900 xhrproto,
1901 'open',
1902 function(origOpen) {
1903 return function(method, url) {
1904 // preserve arity
1905
1906 // if Sentry key appears in URL, don't capture
1907 if (isString(url) && url.indexOf(self._globalKey) === -1) {
1908 this.__raven_xhr = {
1909 method: method,
1910 url: url,
1911 status_code: null
1912 };
1913 }
1914
1915 return origOpen.apply(this, arguments);
1916 };
1917 },
1918 wrappedBuiltIns
1919 );
1920
1921 fill(
1922 xhrproto,
1923 'send',
1924 function(origSend) {
1925 return function(data) {
1926 // preserve arity
1927 var xhr = this;
1928
1929 function onreadystatechangeHandler() {
1930 if (xhr.__raven_xhr && xhr.readyState === 4) {
1931 try {
1932 // touching statusCode in some platforms throws
1933 // an exception
1934 xhr.__raven_xhr.status_code = xhr.status;
1935 } catch (e) {
1936 /* do nothing */
1937 }
1938
1939 self.captureBreadcrumb({
1940 type: 'http',
1941 category: 'xhr',
1942 data: xhr.__raven_xhr
1943 });
1944 }
1945 }
1946
1947 var props = ['onload', 'onerror', 'onprogress'];
1948 for (var j = 0; j < props.length; j++) {
1949 wrapProp(props[j], xhr);
1950 }
1951
1952 if ('onreadystatechange' in xhr && isFunction(xhr.onreadystatechange)) {
1953 fill(
1954 xhr,
1955 'onreadystatechange',
1956 function(orig) {
1957 return self.wrap(orig, undefined, onreadystatechangeHandler);
1958 } /* intentionally don't track this instrumentation */
1959 );
1960 } else {
1961 // if onreadystatechange wasn't actually set by the page on this xhr, we
1962 // are free to set our own and capture the breadcrumb
1963 xhr.onreadystatechange = onreadystatechangeHandler;
1964 }
1965
1966 return origSend.apply(this, arguments);
1967 };
1968 },
1969 wrappedBuiltIns
1970 );
1971 }
1972
1973 if (autoBreadcrumbs.xhr && 'fetch' in _window) {
1974 fill(
1975 _window,
1976 'fetch',
1977 function(origFetch) {
1978 return function(fn, t) {
1979 // preserve arity
1980 // Make a copy of the arguments to prevent deoptimization
1981 // https://github.com/petkaantonov/bluebird/wiki/Optimization-killers#32-leaking-arguments
1982 var args = new Array(arguments.length);
1983 for (var i = 0; i < args.length; ++i) {
1984 args[i] = arguments[i];
1985 }
1986
1987 var fetchInput = args[0];
1988 var method = 'GET';
1989 var url;
1990
1991 if (typeof fetchInput === 'string') {
1992 url = fetchInput;
1993 } else if ('Request' in _window && fetchInput instanceof _window.Request) {
1994 url = fetchInput.url;
1995 if (fetchInput.method) {
1996 method = fetchInput.method;
1997 }
1998 } else {
1999 url = '' + fetchInput;
2000 }
2001
2002 if (args[1] && args[1].method) {
2003 method = args[1].method;
2004 }
2005
2006 var fetchData = {
2007 method: method,
2008 url: url,
2009 status_code: null
2010 };
2011
2012 self.captureBreadcrumb({
2013 type: 'http',
2014 category: 'fetch',
2015 data: fetchData
2016 });
2017
2018 return origFetch.apply(this, args).then(function(response) {
2019 fetchData.status_code = response.status;
2020
2021 return response;
2022 });
2023 };
2024 },
2025 wrappedBuiltIns
2026 );
2027 }
2028
2029 // Capture breadcrumbs from any click that is unhandled / bubbled up all the way
2030 // to the document. Do this before we instrument addEventListener.
2031 if (autoBreadcrumbs.dom && this._hasDocument) {
2032 if (_document.addEventListener) {
2033 _document.addEventListener('click', self._breadcrumbEventHandler('click'), false);
2034 _document.addEventListener('keypress', self._keypressEventHandler(), false);
2035 } else {
2036 // IE8 Compatibility
2037 _document.attachEvent('onclick', self._breadcrumbEventHandler('click'));
2038 _document.attachEvent('onkeypress', self._keypressEventHandler());
2039 }
2040 }
2041
2042 // record navigation (URL) changes
2043 // NOTE: in Chrome App environment, touching history.pushState, *even inside
2044 // a try/catch block*, will cause Chrome to output an error to console.error
2045 // borrowed from: https://github.com/angular/angular.js/pull/13945/files
2046 var chrome = _window.chrome;
2047 var isChromePackagedApp = chrome && chrome.app && chrome.app.runtime;
2048 var hasPushAndReplaceState =
2049 !isChromePackagedApp &&
2050 _window.history &&
2051 history.pushState &&
2052 history.replaceState;
2053 if (autoBreadcrumbs.location && hasPushAndReplaceState) {
2054 // TODO: remove onpopstate handler on uninstall()
2055 var oldOnPopState = _window.onpopstate;
2056 _window.onpopstate = function() {
2057 var currentHref = self._location.href;
2058 self._captureUrlChange(self._lastHref, currentHref);
2059
2060 if (oldOnPopState) {
2061 return oldOnPopState.apply(this, arguments);
2062 }
2063 };
2064
2065 var historyReplacementFunction = function(origHistFunction) {
2066 // note history.pushState.length is 0; intentionally not declaring
2067 // params to preserve 0 arity
2068 return function(/* state, title, url */) {
2069 var url = arguments.length > 2 ? arguments[2] : undefined;
2070
2071 // url argument is optional
2072 if (url) {
2073 // coerce to string (this is what pushState does)
2074 self._captureUrlChange(self._lastHref, url + '');
2075 }
2076
2077 return origHistFunction.apply(this, arguments);
2078 };
2079 };
2080
2081 fill(history, 'pushState', historyReplacementFunction, wrappedBuiltIns);
2082 fill(history, 'replaceState', historyReplacementFunction, wrappedBuiltIns);
2083 }
2084
2085 if (autoBreadcrumbs.console && 'console' in _window && console.log) {
2086 // console
2087 var consoleMethodCallback = function(msg, data) {
2088 self.captureBreadcrumb({
2089 message: msg,
2090 level: data.level,
2091 category: 'console'
2092 });
2093 };
2094
2095 each(['debug', 'info', 'warn', 'error', 'log'], function(_, level) {
2096 wrapConsoleMethod(console, level, consoleMethodCallback);
2097 });
2098 }
2099 },
2100
2101 _restoreBuiltIns: function() {
2102 // restore any wrapped builtins
2103 var builtin;
2104 while (this._wrappedBuiltIns.length) {
2105 builtin = this._wrappedBuiltIns.shift();
2106
2107 var obj = builtin[0],
2108 name = builtin[1],
2109 orig = builtin[2];
2110
2111 obj[name] = orig;
2112 }
2113 },
2114
2115 _drainPlugins: function() {
2116 var self = this;
2117
2118 // FIX ME TODO
2119 each(this._plugins, function(_, plugin) {
2120 var installer = plugin[0];
2121 var args = plugin[1];
2122 installer.apply(self, [self].concat(args));
2123 });
2124 },
2125
2126 _parseDSN: function(str) {
2127 var m = dsnPattern.exec(str),
2128 dsn = {},
2129 i = 7;
2130
2131 try {
2132 while (i--) dsn[dsnKeys[i]] = m[i] || '';
2133 } catch (e) {
2134 throw new RavenConfigError('Invalid DSN: ' + str);
2135 }
2136
2137 if (dsn.pass && !this._globalOptions.allowSecretKey) {
2138 throw new RavenConfigError(
2139 'Do not specify your secret key in the DSN. See: http://bit.ly/raven-secret-key'
2140 );
2141 }
2142
2143 return dsn;
2144 },
2145
2146 _getGlobalServer: function(uri) {
2147 // assemble the endpoint from the uri pieces
2148 var globalServer = '//' + uri.host + (uri.port ? ':' + uri.port : '');
2149
2150 if (uri.protocol) {
2151 globalServer = uri.protocol + ':' + globalServer;
2152 }
2153 return globalServer;
2154 },
2155
2156 _handleOnErrorStackInfo: function() {
2157 // if we are intentionally ignoring errors via onerror, bail out
2158 if (!this._ignoreOnError) {
2159 this._handleStackInfo.apply(this, arguments);
2160 }
2161 },
2162
2163 _handleStackInfo: function(stackInfo, options) {
2164 var frames = this._prepareFrames(stackInfo, options);
2165
2166 this._triggerEvent('handle', {
2167 stackInfo: stackInfo,
2168 options: options
2169 });
2170
2171 this._processException(
2172 stackInfo.name,
2173 stackInfo.message,
2174 stackInfo.url,
2175 stackInfo.lineno,
2176 frames,
2177 options
2178 );
2179 },
2180
2181 _prepareFrames: function(stackInfo, options) {
2182 var self = this;
2183 var frames = [];
2184 if (stackInfo.stack && stackInfo.stack.length) {
2185 each(stackInfo.stack, function(i, stack) {
2186 var frame = self._normalizeFrame(stack, stackInfo.url);
2187 if (frame) {
2188 frames.push(frame);
2189 }
2190 });
2191
2192 // e.g. frames captured via captureMessage throw
2193 if (options && options.trimHeadFrames) {
2194 for (var j = 0; j < options.trimHeadFrames && j < frames.length; j++) {
2195 frames[j].in_app = false;
2196 }
2197 }
2198 }
2199 frames = frames.slice(0, this._globalOptions.stackTraceLimit);
2200 return frames;
2201 },
2202
2203 _normalizeFrame: function(frame, stackInfoUrl) {
2204 // normalize the frames data
2205 var normalized = {
2206 filename: frame.url,
2207 lineno: frame.line,
2208 colno: frame.column,
2209 function: frame.func || '?'
2210 };
2211
2212 // Case when we don't have any information about the error
2213 // E.g. throwing a string or raw object, instead of an `Error` in Firefox
2214 // Generating synthetic error doesn't add any value here
2215 //
2216 // We should probably somehow let a user know that they should fix their code
2217 if (!frame.url) {
2218 normalized.filename = stackInfoUrl; // fallback to whole stacks url from onerror handler
2219 }
2220
2221 normalized.in_app = !// determine if an exception came from outside of our app
2222 // first we check the global includePaths list.
2223 (
2224 (!!this._globalOptions.includePaths.test &&
2225 !this._globalOptions.includePaths.test(normalized.filename)) ||
2226 // Now we check for fun, if the function name is Raven or TraceKit
2227 /(Raven|TraceKit)\./.test(normalized['function']) ||
2228 // finally, we do a last ditch effort and check for raven.min.js
2229 /raven\.(min\.)?js$/.test(normalized.filename)
2230 );
2231
2232 return normalized;
2233 },
2234
2235 _processException: function(type, message, fileurl, lineno, frames, options) {
2236 var prefixedMessage = (type ? type + ': ' : '') + (message || '');
2237 if (
2238 !!this._globalOptions.ignoreErrors.test &&
2239 (this._globalOptions.ignoreErrors.test(message) ||
2240 this._globalOptions.ignoreErrors.test(prefixedMessage))
2241 ) {
2242 return;
2243 }
2244
2245 var stacktrace;
2246
2247 if (frames && frames.length) {
2248 fileurl = frames[0].filename || fileurl;
2249 // Sentry expects frames oldest to newest
2250 // and JS sends them as newest to oldest
2251 frames.reverse();
2252 stacktrace = {frames: frames};
2253 } else if (fileurl) {
2254 stacktrace = {
2255 frames: [
2256 {
2257 filename: fileurl,
2258 lineno: lineno,
2259 in_app: true
2260 }
2261 ]
2262 };
2263 }
2264
2265 if (
2266 !!this._globalOptions.ignoreUrls.test &&
2267 this._globalOptions.ignoreUrls.test(fileurl)
2268 ) {
2269 return;
2270 }
2271
2272 if (
2273 !!this._globalOptions.whitelistUrls.test &&
2274 !this._globalOptions.whitelistUrls.test(fileurl)
2275 ) {
2276 return;
2277 }
2278
2279 var data = objectMerge(
2280 {
2281 // sentry.interfaces.Exception
2282 exception: {
2283 values: [
2284 {
2285 type: type,
2286 value: message,
2287 stacktrace: stacktrace
2288 }
2289 ]
2290 },
2291 culprit: fileurl
2292 },
2293 options
2294 );
2295
2296 // Fire away!
2297 this._send(data);
2298 },
2299
2300 _trimPacket: function(data) {
2301 // For now, we only want to truncate the two different messages
2302 // but this could/should be expanded to just trim everything
2303 var max = this._globalOptions.maxMessageLength;
2304 if (data.message) {
2305 data.message = truncate(data.message, max);
2306 }
2307 if (data.exception) {
2308 var exception = data.exception.values[0];
2309 exception.value = truncate(exception.value, max);
2310 }
2311
2312 var request = data.request;
2313 if (request) {
2314 if (request.url) {
2315 request.url = truncate(request.url, this._globalOptions.maxUrlLength);
2316 }
2317 if (request.Referer) {
2318 request.Referer = truncate(request.Referer, this._globalOptions.maxUrlLength);
2319 }
2320 }
2321
2322 if (data.breadcrumbs && data.breadcrumbs.values)
2323 this._trimBreadcrumbs(data.breadcrumbs);
2324
2325 return data;
2326 },
2327
2328 /**
2329 * Truncate breadcrumb values (right now just URLs)
2330 */
2331 _trimBreadcrumbs: function(breadcrumbs) {
2332 // known breadcrumb properties with urls
2333 // TODO: also consider arbitrary prop values that start with (https?)?://
2334 var urlProps = ['to', 'from', 'url'],
2335 urlProp,
2336 crumb,
2337 data;
2338
2339 for (var i = 0; i < breadcrumbs.values.length; ++i) {
2340 crumb = breadcrumbs.values[i];
2341 if (
2342 !crumb.hasOwnProperty('data') ||
2343 !isObject(crumb.data) ||
2344 objectFrozen(crumb.data)
2345 )
2346 continue;
2347
2348 data = objectMerge({}, crumb.data);
2349 for (var j = 0; j < urlProps.length; ++j) {
2350 urlProp = urlProps[j];
2351 if (data.hasOwnProperty(urlProp) && data[urlProp]) {
2352 data[urlProp] = truncate(data[urlProp], this._globalOptions.maxUrlLength);
2353 }
2354 }
2355 breadcrumbs.values[i].data = data;
2356 }
2357 },
2358
2359 _getHttpData: function() {
2360 if (!this._hasNavigator && !this._hasDocument) return;
2361 var httpData = {};
2362
2363 if (this._hasNavigator && _navigator.userAgent) {
2364 httpData.headers = {
2365 'User-Agent': navigator.userAgent
2366 };
2367 }
2368
2369 if (this._hasDocument) {
2370 if (_document.location && _document.location.href) {
2371 httpData.url = _document.location.href;
2372 }
2373 if (_document.referrer) {
2374 if (!httpData.headers) httpData.headers = {};
2375 httpData.headers.Referer = _document.referrer;
2376 }
2377 }
2378
2379 return httpData;
2380 },
2381
2382 _resetBackoff: function() {
2383 this._backoffDuration = 0;
2384 this._backoffStart = null;
2385 },
2386
2387 _shouldBackoff: function() {
2388 return this._backoffDuration && now() - this._backoffStart < this._backoffDuration;
2389 },
2390
2391 /**
2392 * Returns true if the in-process data payload matches the signature
2393 * of the previously-sent data
2394 *
2395 * NOTE: This has to be done at this level because TraceKit can generate
2396 * data from window.onerror WITHOUT an exception object (IE8, IE9,
2397 * other old browsers). This can take the form of an "exception"
2398 * data object with a single frame (derived from the onerror args).
2399 */
2400 _isRepeatData: function(current) {
2401 var last = this._lastData;
2402
2403 if (
2404 !last ||
2405 current.message !== last.message || // defined for captureMessage
2406 current.culprit !== last.culprit // defined for captureException/onerror
2407 )
2408 return false;
2409
2410 // Stacktrace interface (i.e. from captureMessage)
2411 if (current.stacktrace || last.stacktrace) {
2412 return isSameStacktrace(current.stacktrace, last.stacktrace);
2413 } else if (current.exception || last.exception) {
2414 // Exception interface (i.e. from captureException/onerror)
2415 return isSameException(current.exception, last.exception);
2416 }
2417
2418 return true;
2419 },
2420
2421 _setBackoffState: function(request) {
2422 // If we are already in a backoff state, don't change anything
2423 if (this._shouldBackoff()) {
2424 return;
2425 }
2426
2427 var status = request.status;
2428
2429 // 400 - project_id doesn't exist or some other fatal
2430 // 401 - invalid/revoked dsn
2431 // 429 - too many requests
2432 if (!(status === 400 || status === 401 || status === 429)) return;
2433
2434 var retry;
2435 try {
2436 // If Retry-After is not in Access-Control-Expose-Headers, most
2437 // browsers will throw an exception trying to access it
2438 retry = request.getResponseHeader('Retry-After');
2439 retry = parseInt(retry, 10) * 1000; // Retry-After is returned in seconds
2440 } catch (e) {
2441 /* eslint no-empty:0 */
2442 }
2443
2444 this._backoffDuration = retry
2445 ? // If Sentry server returned a Retry-After value, use it
2446 retry
2447 : // Otherwise, double the last backoff duration (starts at 1 sec)
2448 this._backoffDuration * 2 || 1000;
2449
2450 this._backoffStart = now();
2451 },
2452
2453 _send: function(data) {
2454 var globalOptions = this._globalOptions;
2455
2456 var baseData = {
2457 project: this._globalProject,
2458 logger: globalOptions.logger,
2459 platform: 'javascript'
2460 },
2461 httpData = this._getHttpData();
2462
2463 if (httpData) {
2464 baseData.request = httpData;
2465 }
2466
2467 // HACK: delete `trimHeadFrames` to prevent from appearing in outbound payload
2468 if (data.trimHeadFrames) delete data.trimHeadFrames;
2469
2470 data = objectMerge(baseData, data);
2471
2472 // Merge in the tags and extra separately since objectMerge doesn't handle a deep merge
2473 data.tags = objectMerge(objectMerge({}, this._globalContext.tags), data.tags);
2474 data.extra = objectMerge(objectMerge({}, this._globalContext.extra), data.extra);
2475
2476 // Send along our own collected metadata with extra
2477 data.extra['session:duration'] = now() - this._startTime;
2478
2479 if (this._breadcrumbs && this._breadcrumbs.length > 0) {
2480 // intentionally make shallow copy so that additions
2481 // to breadcrumbs aren't accidentally sent in this request
2482 data.breadcrumbs = {
2483 values: [].slice.call(this._breadcrumbs, 0)
2484 };
2485 }
2486
2487 // If there are no tags/extra, strip the key from the payload alltogther.
2488 if (isEmptyObject(data.tags)) delete data.tags;
2489
2490 if (this._globalContext.user) {
2491 // sentry.interfaces.User
2492 data.user = this._globalContext.user;
2493 }
2494
2495 // Include the environment if it's defined in globalOptions
2496 if (globalOptions.environment) data.environment = globalOptions.environment;
2497
2498 // Include the release if it's defined in globalOptions
2499 if (globalOptions.release) data.release = globalOptions.release;
2500
2501 // Include server_name if it's defined in globalOptions
2502 if (globalOptions.serverName) data.server_name = globalOptions.serverName;
2503
2504 if (isFunction(globalOptions.dataCallback)) {
2505 data = globalOptions.dataCallback(data) || data;
2506 }
2507
2508 // Why??????????
2509 if (!data || isEmptyObject(data)) {
2510 return;
2511 }
2512
2513 // Check if the request should be filtered or not
2514 if (
2515 isFunction(globalOptions.shouldSendCallback) &&
2516 !globalOptions.shouldSendCallback(data)
2517 ) {
2518 return;
2519 }
2520
2521 // Backoff state: Sentry server previously responded w/ an error (e.g. 429 - too many requests),
2522 // so drop requests until "cool-off" period has elapsed.
2523 if (this._shouldBackoff()) {
2524 this._logDebug('warn', 'Raven dropped error due to backoff: ', data);
2525 return;
2526 }
2527
2528 if (typeof globalOptions.sampleRate === 'number') {
2529 if (Math.random() < globalOptions.sampleRate) {
2530 this._sendProcessedPayload(data);
2531 }
2532 } else {
2533 this._sendProcessedPayload(data);
2534 }
2535 },
2536
2537 _getUuid: function() {
2538 return uuid4();
2539 },
2540
2541 _sendProcessedPayload: function(data, callback) {
2542 var self = this;
2543 var globalOptions = this._globalOptions;
2544
2545 if (!this.isSetup()) return;
2546
2547 // Try and clean up the packet before sending by truncating long values
2548 data = this._trimPacket(data);
2549
2550 // ideally duplicate error testing should occur *before* dataCallback/shouldSendCallback,
2551 // but this would require copying an un-truncated copy of the data packet, which can be
2552 // arbitrarily deep (extra_data) -- could be worthwhile? will revisit
2553 if (!this._globalOptions.allowDuplicates && this._isRepeatData(data)) {
2554 this._logDebug('warn', 'Raven dropped repeat event: ', data);
2555 return;
2556 }
2557
2558 // Send along an event_id if not explicitly passed.
2559 // This event_id can be used to reference the error within Sentry itself.
2560 // Set lastEventId after we know the error should actually be sent
2561 this._lastEventId = data.event_id || (data.event_id = this._getUuid());
2562
2563 // Store outbound payload after trim
2564 this._lastData = data;
2565
2566 this._logDebug('debug', 'Raven about to send:', data);
2567
2568 var auth = {
2569 sentry_version: '7',
2570 sentry_client: 'raven-js/' + this.VERSION,
2571 sentry_key: this._globalKey
2572 };
2573
2574 if (this._globalSecret) {
2575 auth.sentry_secret = this._globalSecret;
2576 }
2577
2578 var exception = data.exception && data.exception.values[0];
2579 this.captureBreadcrumb({
2580 category: 'sentry',
2581 message: exception
2582 ? (exception.type ? exception.type + ': ' : '') + exception.value
2583 : data.message,
2584 event_id: data.event_id,
2585 level: data.level || 'error' // presume error unless specified
2586 });
2587
2588 var url = this._globalEndpoint;
2589 (globalOptions.transport || this._makeRequest).call(this, {
2590 url: url,
2591 auth: auth,
2592 data: data,
2593 options: globalOptions,
2594 onSuccess: function success() {
2595 self._resetBackoff();
2596
2597 self._triggerEvent('success', {
2598 data: data,
2599 src: url
2600 });
2601 callback && callback();
2602 },
2603 onError: function failure(error) {
2604 self._logDebug('error', 'Raven transport failed to send: ', error);
2605
2606 if (error.request) {
2607 self._setBackoffState(error.request);
2608 }
2609
2610 self._triggerEvent('failure', {
2611 data: data,
2612 src: url
2613 });
2614 error = error || new Error('Raven send failed (no additional details provided)');
2615 callback && callback(error);
2616 }
2617 });
2618 },
2619
2620 _makeRequest: function(opts) {
2621 var request = _window.XMLHttpRequest && new _window.XMLHttpRequest();
2622 if (!request) return;
2623
2624 // if browser doesn't support CORS (e.g. IE7), we are out of luck
2625 var hasCORS = 'withCredentials' in request || typeof XDomainRequest !== 'undefined';
2626
2627 if (!hasCORS) return;
2628
2629 var url = opts.url;
2630
2631 if ('withCredentials' in request) {
2632 request.onreadystatechange = function() {
2633 if (request.readyState !== 4) {
2634 return;
2635 } else if (request.status === 200) {
2636 opts.onSuccess && opts.onSuccess();
2637 } else if (opts.onError) {
2638 var err = new Error('Sentry error code: ' + request.status);
2639 err.request = request;
2640 opts.onError(err);
2641 }
2642 };
2643 } else {
2644 request = new XDomainRequest();
2645 // xdomainrequest cannot go http -> https (or vice versa),
2646 // so always use protocol relative
2647 url = url.replace(/^https?:/, '');
2648
2649 // onreadystatechange not supported by XDomainRequest
2650 if (opts.onSuccess) {
2651 request.onload = opts.onSuccess;
2652 }
2653 if (opts.onError) {
2654 request.onerror = function() {
2655 var err = new Error('Sentry error code: XDomainRequest');
2656 err.request = request;
2657 opts.onError(err);
2658 };
2659 }
2660 }
2661
2662 // NOTE: auth is intentionally sent as part of query string (NOT as custom
2663 // HTTP header) so as to avoid preflight CORS requests
2664 request.open('POST', url + '?' + urlencode(opts.auth));
2665 request.send(stringify(opts.data));
2666 },
2667
2668 _logDebug: function(level) {
2669 if (this._originalConsoleMethods[level] && this.debug) {
2670 // In IE<10 console methods do not have their own 'apply' method
2671 Function.prototype.apply.call(
2672 this._originalConsoleMethods[level],
2673 this._originalConsole,
2674 [].slice.call(arguments, 1)
2675 );
2676 }
2677 },
2678
2679 _mergeContext: function(key, context) {
2680 if (isUndefined(context)) {
2681 delete this._globalContext[key];
2682 } else {
2683 this._globalContext[key] = objectMerge(this._globalContext[key] || {}, context);
2684 }
2685 }
2686 };
2687
2688 // Deprecations
2689 Raven.prototype.setUser = Raven.prototype.setUserContext;
2690 Raven.prototype.setReleaseContext = Raven.prototype.setRelease;
2691
2692 module.exports = Raven;
2693
2694
2695 /***/ }),
2696
2697 /***/ "./node_modules/raven-js/src/singleton.js":
2698 /*!************************************************!*\
2699 !*** ./node_modules/raven-js/src/singleton.js ***!
2700 \************************************************/
2701 /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
2702
2703 /**
2704 * Enforces a single instance of the Raven client, and the
2705 * main entry point for Raven. If you are a consumer of the
2706 * Raven library, you SHOULD load this file (vs raven.js).
2707 **/
2708
2709 var RavenConstructor = __webpack_require__(/*! ./raven */ "./node_modules/raven-js/src/raven.js");
2710
2711 // This is to be defensive in environments where window does not exist (see https://github.com/getsentry/raven-js/pull/785)
2712 var _window =
2713 typeof window !== 'undefined'
2714 ? window
2715 : typeof __webpack_require__.g !== 'undefined' ? __webpack_require__.g : typeof self !== 'undefined' ? self : {};
2716 var _Raven = _window.Raven;
2717
2718 var Raven = new RavenConstructor();
2719
2720 /*
2721 * Allow multiple versions of Raven to be installed.
2722 * Strip Raven from the global context and returns the instance.
2723 *
2724 * @return {Raven}
2725 */
2726 Raven.noConflict = function() {
2727 _window.Raven = _Raven;
2728 return Raven;
2729 };
2730
2731 Raven.afterLoad();
2732
2733 module.exports = Raven;
2734
2735
2736 /***/ }),
2737
2738 /***/ "./node_modules/raven-js/src/utils.js":
2739 /*!********************************************!*\
2740 !*** ./node_modules/raven-js/src/utils.js ***!
2741 \********************************************/
2742 /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
2743
2744 var _window =
2745 typeof window !== 'undefined'
2746 ? window
2747 : typeof __webpack_require__.g !== 'undefined' ? __webpack_require__.g : typeof self !== 'undefined' ? self : {};
2748
2749 function isObject(what) {
2750 return typeof what === 'object' && what !== null;
2751 }
2752
2753 // Yanked from https://git.io/vS8DV re-used under CC0
2754 // with some tiny modifications
2755 function isError(value) {
2756 switch ({}.toString.call(value)) {
2757 case '[object Error]':
2758 return true;
2759 case '[object Exception]':
2760 return true;
2761 case '[object DOMException]':
2762 return true;
2763 default:
2764 return value instanceof Error;
2765 }
2766 }
2767
2768 function isErrorEvent(value) {
2769 return supportsErrorEvent() && {}.toString.call(value) === '[object ErrorEvent]';
2770 }
2771
2772 function isUndefined(what) {
2773 return what === void 0;
2774 }
2775
2776 function isFunction(what) {
2777 return typeof what === 'function';
2778 }
2779
2780 function isString(what) {
2781 return Object.prototype.toString.call(what) === '[object String]';
2782 }
2783
2784 function isEmptyObject(what) {
2785 for (var _ in what) return false; // eslint-disable-line guard-for-in, no-unused-vars
2786 return true;
2787 }
2788
2789 function supportsErrorEvent() {
2790 try {
2791 new ErrorEvent(''); // eslint-disable-line no-new
2792 return true;
2793 } catch (e) {
2794 return false;
2795 }
2796 }
2797
2798 function wrappedCallback(callback) {
2799 function dataCallback(data, original) {
2800 var normalizedData = callback(data) || data;
2801 if (original) {
2802 return original(normalizedData) || normalizedData;
2803 }
2804 return normalizedData;
2805 }
2806
2807 return dataCallback;
2808 }
2809
2810 function each(obj, callback) {
2811 var i, j;
2812
2813 if (isUndefined(obj.length)) {
2814 for (i in obj) {
2815 if (hasKey(obj, i)) {
2816 callback.call(null, i, obj[i]);
2817 }
2818 }
2819 } else {
2820 j = obj.length;
2821 if (j) {
2822 for (i = 0; i < j; i++) {
2823 callback.call(null, i, obj[i]);
2824 }
2825 }
2826 }
2827 }
2828
2829 function objectMerge(obj1, obj2) {
2830 if (!obj2) {
2831 return obj1;
2832 }
2833 each(obj2, function(key, value) {
2834 obj1[key] = value;
2835 });
2836 return obj1;
2837 }
2838
2839 /**
2840 * This function is only used for react-native.
2841 * react-native freezes object that have already been sent over the
2842 * js bridge. We need this function in order to check if the object is frozen.
2843 * So it's ok that objectFrozen returns false if Object.isFrozen is not
2844 * supported because it's not relevant for other "platforms". See related issue:
2845 * https://github.com/getsentry/react-native-sentry/issues/57
2846 */
2847 function objectFrozen(obj) {
2848 if (!Object.isFrozen) {
2849 return false;
2850 }
2851 return Object.isFrozen(obj);
2852 }
2853
2854 function truncate(str, max) {
2855 return !max || str.length <= max ? str : str.substr(0, max) + '\u2026';
2856 }
2857
2858 /**
2859 * hasKey, a better form of hasOwnProperty
2860 * Example: hasKey(MainHostObject, property) === true/false
2861 *
2862 * @param {Object} host object to check property
2863 * @param {string} key to check
2864 */
2865 function hasKey(object, key) {
2866 return Object.prototype.hasOwnProperty.call(object, key);
2867 }
2868
2869 function joinRegExp(patterns) {
2870 // Combine an array of regular expressions and strings into one large regexp
2871 // Be mad.
2872 var sources = [],
2873 i = 0,
2874 len = patterns.length,
2875 pattern;
2876
2877 for (; i < len; i++) {
2878 pattern = patterns[i];
2879 if (isString(pattern)) {
2880 // If it's a string, we need to escape it
2881 // Taken from: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions
2882 sources.push(pattern.replace(/([.*+?^=!:${}()|\[\]\/\\])/g, '\\$1'));
2883 } else if (pattern && pattern.source) {
2884 // If it's a regexp already, we want to extract the source
2885 sources.push(pattern.source);
2886 }
2887 // Intentionally skip other cases
2888 }
2889 return new RegExp(sources.join('|'), 'i');
2890 }
2891
2892 function urlencode(o) {
2893 var pairs = [];
2894 each(o, function(key, value) {
2895 pairs.push(encodeURIComponent(key) + '=' + encodeURIComponent(value));
2896 });
2897 return pairs.join('&');
2898 }
2899
2900 // borrowed from https://tools.ietf.org/html/rfc3986#appendix-B
2901 // intentionally using regex and not <a/> href parsing trick because React Native and other
2902 // environments where DOM might not be available
2903 function parseUrl(url) {
2904 var match = url.match(/^(([^:\/?#]+):)?(\/\/([^\/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?$/);
2905 if (!match) return {};
2906
2907 // coerce to undefined values to empty string so we don't get 'undefined'
2908 var query = match[6] || '';
2909 var fragment = match[8] || '';
2910 return {
2911 protocol: match[2],
2912 host: match[4],
2913 path: match[5],
2914 relative: match[5] + query + fragment // everything minus origin
2915 };
2916 }
2917 function uuid4() {
2918 var crypto = _window.crypto || _window.msCrypto;
2919
2920 if (!isUndefined(crypto) && crypto.getRandomValues) {
2921 // Use window.crypto API if available
2922 // eslint-disable-next-line no-undef
2923 var arr = new Uint16Array(8);
2924 crypto.getRandomValues(arr);
2925
2926 // set 4 in byte 7
2927 arr[3] = (arr[3] & 0xfff) | 0x4000;
2928 // set 2 most significant bits of byte 9 to '10'
2929 arr[4] = (arr[4] & 0x3fff) | 0x8000;
2930
2931 var pad = function(num) {
2932 var v = num.toString(16);
2933 while (v.length < 4) {
2934 v = '0' + v;
2935 }
2936 return v;
2937 };
2938
2939 return (
2940 pad(arr[0]) +
2941 pad(arr[1]) +
2942 pad(arr[2]) +
2943 pad(arr[3]) +
2944 pad(arr[4]) +
2945 pad(arr[5]) +
2946 pad(arr[6]) +
2947 pad(arr[7])
2948 );
2949 } else {
2950 // http://stackoverflow.com/questions/105034/how-to-create-a-guid-uuid-in-javascript/2117523#2117523
2951 return 'xxxxxxxxxxxx4xxxyxxxxxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
2952 var r = (Math.random() * 16) | 0,
2953 v = c === 'x' ? r : (r & 0x3) | 0x8;
2954 return v.toString(16);
2955 });
2956 }
2957 }
2958
2959 /**
2960 * Given a child DOM element, returns a query-selector statement describing that
2961 * and its ancestors
2962 * e.g. [HTMLElement] => body > div > input#foo.btn[name=baz]
2963 * @param elem
2964 * @returns {string}
2965 */
2966 function htmlTreeAsString(elem) {
2967 /* eslint no-extra-parens:0*/
2968 var MAX_TRAVERSE_HEIGHT = 5,
2969 MAX_OUTPUT_LEN = 80,
2970 out = [],
2971 height = 0,
2972 len = 0,
2973 separator = ' > ',
2974 sepLength = separator.length,
2975 nextStr;
2976
2977 while (elem && height++ < MAX_TRAVERSE_HEIGHT) {
2978 nextStr = htmlElementAsString(elem);
2979 // bail out if
2980 // - nextStr is the 'html' element
2981 // - the length of the string that would be created exceeds MAX_OUTPUT_LEN
2982 // (ignore this limit if we are on the first iteration)
2983 if (
2984 nextStr === 'html' ||
2985 (height > 1 && len + out.length * sepLength + nextStr.length >= MAX_OUTPUT_LEN)
2986 ) {
2987 break;
2988 }
2989
2990 out.push(nextStr);
2991
2992 len += nextStr.length;
2993 elem = elem.parentNode;
2994 }
2995
2996 return out.reverse().join(separator);
2997 }
2998
2999 /**
3000 * Returns a simple, query-selector representation of a DOM element
3001 * e.g. [HTMLElement] => input#foo.btn[name=baz]
3002 * @param HTMLElement
3003 * @returns {string}
3004 */
3005 function htmlElementAsString(elem) {
3006 var out = [],
3007 className,
3008 classes,
3009 key,
3010 attr,
3011 i;
3012
3013 if (!elem || !elem.tagName) {
3014 return '';
3015 }
3016
3017 out.push(elem.tagName.toLowerCase());
3018 if (elem.id) {
3019 out.push('#' + elem.id);
3020 }
3021
3022 className = elem.className;
3023 if (className && isString(className)) {
3024 classes = className.split(/\s+/);
3025 for (i = 0; i < classes.length; i++) {
3026 out.push('.' + classes[i]);
3027 }
3028 }
3029 var attrWhitelist = ['type', 'name', 'title', 'alt'];
3030 for (i = 0; i < attrWhitelist.length; i++) {
3031 key = attrWhitelist[i];
3032 attr = elem.getAttribute(key);
3033 if (attr) {
3034 out.push('[' + key + '="' + attr + '"]');
3035 }
3036 }
3037 return out.join('');
3038 }
3039
3040 /**
3041 * Returns true if either a OR b is truthy, but not both
3042 */
3043 function isOnlyOneTruthy(a, b) {
3044 return !!(!!a ^ !!b);
3045 }
3046
3047 /**
3048 * Returns true if the two input exception interfaces have the same content
3049 */
3050 function isSameException(ex1, ex2) {
3051 if (isOnlyOneTruthy(ex1, ex2)) return false;
3052
3053 ex1 = ex1.values[0];
3054 ex2 = ex2.values[0];
3055
3056 if (ex1.type !== ex2.type || ex1.value !== ex2.value) return false;
3057
3058 return isSameStacktrace(ex1.stacktrace, ex2.stacktrace);
3059 }
3060
3061 /**
3062 * Returns true if the two input stack trace interfaces have the same content
3063 */
3064 function isSameStacktrace(stack1, stack2) {
3065 if (isOnlyOneTruthy(stack1, stack2)) return false;
3066
3067 var frames1 = stack1.frames;
3068 var frames2 = stack2.frames;
3069
3070 // Exit early if frame count differs
3071 if (frames1.length !== frames2.length) return false;
3072
3073 // Iterate through every frame; bail out if anything differs
3074 var a, b;
3075 for (var i = 0; i < frames1.length; i++) {
3076 a = frames1[i];
3077 b = frames2[i];
3078 if (
3079 a.filename !== b.filename ||
3080 a.lineno !== b.lineno ||
3081 a.colno !== b.colno ||
3082 a['function'] !== b['function']
3083 )
3084 return false;
3085 }
3086 return true;
3087 }
3088
3089 /**
3090 * Polyfill a method
3091 * @param obj object e.g. `document`
3092 * @param name method name present on object e.g. `addEventListener`
3093 * @param replacement replacement function
3094 * @param track {optional} record instrumentation to an array
3095 */
3096 function fill(obj, name, replacement, track) {
3097 var orig = obj[name];
3098 obj[name] = replacement(orig);
3099 if (track) {
3100 track.push([obj, name, orig]);
3101 }
3102 }
3103
3104 module.exports = {
3105 isObject: isObject,
3106 isError: isError,
3107 isErrorEvent: isErrorEvent,
3108 isUndefined: isUndefined,
3109 isFunction: isFunction,
3110 isString: isString,
3111 isEmptyObject: isEmptyObject,
3112 supportsErrorEvent: supportsErrorEvent,
3113 wrappedCallback: wrappedCallback,
3114 each: each,
3115 objectMerge: objectMerge,
3116 truncate: truncate,
3117 objectFrozen: objectFrozen,
3118 hasKey: hasKey,
3119 joinRegExp: joinRegExp,
3120 urlencode: urlencode,
3121 uuid4: uuid4,
3122 htmlTreeAsString: htmlTreeAsString,
3123 htmlElementAsString: htmlElementAsString,
3124 isSameException: isSameException,
3125 isSameStacktrace: isSameStacktrace,
3126 parseUrl: parseUrl,
3127 fill: fill
3128 };
3129
3130
3131 /***/ }),
3132
3133 /***/ "./node_modules/raven-js/vendor/TraceKit/tracekit.js":
3134 /*!***********************************************************!*\
3135 !*** ./node_modules/raven-js/vendor/TraceKit/tracekit.js ***!
3136 \***********************************************************/
3137 /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
3138
3139 var utils = __webpack_require__(/*! ../../src/utils */ "./node_modules/raven-js/src/utils.js");
3140
3141 /*
3142 TraceKit - Cross brower stack traces
3143
3144 This was originally forked from github.com/occ/TraceKit, but has since been
3145 largely re-written and is now maintained as part of raven-js. Tests for
3146 this are in test/vendor.
3147
3148 MIT license
3149 */
3150
3151 var TraceKit = {
3152 collectWindowErrors: true,
3153 debug: false
3154 };
3155
3156 // This is to be defensive in environments where window does not exist (see https://github.com/getsentry/raven-js/pull/785)
3157 var _window =
3158 typeof window !== 'undefined'
3159 ? window
3160 : typeof __webpack_require__.g !== 'undefined' ? __webpack_require__.g : typeof self !== 'undefined' ? self : {};
3161
3162 // global reference to slice
3163 var _slice = [].slice;
3164 var UNKNOWN_FUNCTION = '?';
3165
3166 // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error#Error_types
3167 var ERROR_TYPES_RE = /^(?:[Uu]ncaught (?:exception: )?)?(?:((?:Eval|Internal|Range|Reference|Syntax|Type|URI|)Error): )?(.*)$/;
3168
3169 function getLocationHref() {
3170 if (typeof document === 'undefined' || document.location == null) return '';
3171
3172 return document.location.href;
3173 }
3174
3175 /**
3176 * TraceKit.report: cross-browser processing of unhandled exceptions
3177 *
3178 * Syntax:
3179 * TraceKit.report.subscribe(function(stackInfo) { ... })
3180 * TraceKit.report.unsubscribe(function(stackInfo) { ... })
3181 * TraceKit.report(exception)
3182 * try { ...code... } catch(ex) { TraceKit.report(ex); }
3183 *
3184 * Supports:
3185 * - Firefox: full stack trace with line numbers, plus column number
3186 * on top frame; column number is not guaranteed
3187 * - Opera: full stack trace with line and column numbers
3188 * - Chrome: full stack trace with line and column numbers
3189 * - Safari: line and column number for the top frame only; some frames
3190 * may be missing, and column number is not guaranteed
3191 * - IE: line and column number for the top frame only; some frames
3192 * may be missing, and column number is not guaranteed
3193 *
3194 * In theory, TraceKit should work on all of the following versions:
3195 * - IE5.5+ (only 8.0 tested)
3196 * - Firefox 0.9+ (only 3.5+ tested)
3197 * - Opera 7+ (only 10.50 tested; versions 9 and earlier may require
3198 * Exceptions Have Stacktrace to be enabled in opera:config)
3199 * - Safari 3+ (only 4+ tested)
3200 * - Chrome 1+ (only 5+ tested)
3201 * - Konqueror 3.5+ (untested)
3202 *
3203 * Requires TraceKit.computeStackTrace.
3204 *
3205 * Tries to catch all unhandled exceptions and report them to the
3206 * subscribed handlers. Please note that TraceKit.report will rethrow the
3207 * exception. This is REQUIRED in order to get a useful stack trace in IE.
3208 * If the exception does not reach the top of the browser, you will only
3209 * get a stack trace from the point where TraceKit.report was called.
3210 *
3211 * Handlers receive a stackInfo object as described in the
3212 * TraceKit.computeStackTrace docs.
3213 */
3214 TraceKit.report = (function reportModuleWrapper() {
3215 var handlers = [],
3216 lastArgs = null,
3217 lastException = null,
3218 lastExceptionStack = null;
3219
3220 /**
3221 * Add a crash handler.
3222 * @param {Function} handler
3223 */
3224 function subscribe(handler) {
3225 installGlobalHandler();
3226 handlers.push(handler);
3227 }
3228
3229 /**
3230 * Remove a crash handler.
3231 * @param {Function} handler
3232 */
3233 function unsubscribe(handler) {
3234 for (var i = handlers.length - 1; i >= 0; --i) {
3235 if (handlers[i] === handler) {
3236 handlers.splice(i, 1);
3237 }
3238 }
3239 }
3240
3241 /**
3242 * Remove all crash handlers.
3243 */
3244 function unsubscribeAll() {
3245 uninstallGlobalHandler();
3246 handlers = [];
3247 }
3248
3249 /**
3250 * Dispatch stack information to all handlers.
3251 * @param {Object.<string, *>} stack
3252 */
3253 function notifyHandlers(stack, isWindowError) {
3254 var exception = null;
3255 if (isWindowError && !TraceKit.collectWindowErrors) {
3256 return;
3257 }
3258 for (var i in handlers) {
3259 if (handlers.hasOwnProperty(i)) {
3260 try {
3261 handlers[i].apply(null, [stack].concat(_slice.call(arguments, 2)));
3262 } catch (inner) {
3263 exception = inner;
3264 }
3265 }
3266 }
3267
3268 if (exception) {
3269 throw exception;
3270 }
3271 }
3272
3273 var _oldOnerrorHandler, _onErrorHandlerInstalled;
3274
3275 /**
3276 * Ensures all global unhandled exceptions are recorded.
3277 * Supported by Gecko and IE.
3278 * @param {string} message Error message.
3279 * @param {string} url URL of script that generated the exception.
3280 * @param {(number|string)} lineNo The line number at which the error
3281 * occurred.
3282 * @param {?(number|string)} colNo The column number at which the error
3283 * occurred.
3284 * @param {?Error} ex The actual Error object.
3285 */
3286 function traceKitWindowOnError(message, url, lineNo, colNo, ex) {
3287 var stack = null;
3288
3289 if (lastExceptionStack) {
3290 TraceKit.computeStackTrace.augmentStackTraceWithInitialElement(
3291 lastExceptionStack,
3292 url,
3293 lineNo,
3294 message
3295 );
3296 processLastException();
3297 } else if (ex && utils.isError(ex)) {
3298 // non-string `ex` arg; attempt to extract stack trace
3299
3300 // New chrome and blink send along a real error object
3301 // Let's just report that like a normal error.
3302 // See: https://mikewest.org/2013/08/debugging-runtime-errors-with-window-onerror
3303 stack = TraceKit.computeStackTrace(ex);
3304 notifyHandlers(stack, true);
3305 } else {
3306 var location = {
3307 url: url,
3308 line: lineNo,
3309 column: colNo
3310 };
3311
3312 var name = undefined;
3313 var msg = message; // must be new var or will modify original `arguments`
3314 var groups;
3315 if ({}.toString.call(message) === '[object String]') {
3316 var groups = message.match(ERROR_TYPES_RE);
3317 if (groups) {
3318 name = groups[1];
3319 msg = groups[2];
3320 }
3321 }
3322
3323 location.func = UNKNOWN_FUNCTION;
3324
3325 stack = {
3326 name: name,
3327 message: msg,
3328 url: getLocationHref(),
3329 stack: [location]
3330 };
3331 notifyHandlers(stack, true);
3332 }
3333
3334 if (_oldOnerrorHandler) {
3335 return _oldOnerrorHandler.apply(this, arguments);
3336 }
3337
3338 return false;
3339 }
3340
3341 function installGlobalHandler() {
3342 if (_onErrorHandlerInstalled) {
3343 return;
3344 }
3345 _oldOnerrorHandler = _window.onerror;
3346 _window.onerror = traceKitWindowOnError;
3347 _onErrorHandlerInstalled = true;
3348 }
3349
3350 function uninstallGlobalHandler() {
3351 if (!_onErrorHandlerInstalled) {
3352 return;
3353 }
3354 _window.onerror = _oldOnerrorHandler;
3355 _onErrorHandlerInstalled = false;
3356 _oldOnerrorHandler = undefined;
3357 }
3358
3359 function processLastException() {
3360 var _lastExceptionStack = lastExceptionStack,
3361 _lastArgs = lastArgs;
3362 lastArgs = null;
3363 lastExceptionStack = null;
3364 lastException = null;
3365 notifyHandlers.apply(null, [_lastExceptionStack, false].concat(_lastArgs));
3366 }
3367
3368 /**
3369 * Reports an unhandled Error to TraceKit.
3370 * @param {Error} ex
3371 * @param {?boolean} rethrow If false, do not re-throw the exception.
3372 * Only used for window.onerror to not cause an infinite loop of
3373 * rethrowing.
3374 */
3375 function report(ex, rethrow) {
3376 var args = _slice.call(arguments, 1);
3377 if (lastExceptionStack) {
3378 if (lastException === ex) {
3379 return; // already caught by an inner catch block, ignore
3380 } else {
3381 processLastException();
3382 }
3383 }
3384
3385 var stack = TraceKit.computeStackTrace(ex);
3386 lastExceptionStack = stack;
3387 lastException = ex;
3388 lastArgs = args;
3389
3390 // If the stack trace is incomplete, wait for 2 seconds for
3391 // slow slow IE to see if onerror occurs or not before reporting
3392 // this exception; otherwise, we will end up with an incomplete
3393 // stack trace
3394 setTimeout(function() {
3395 if (lastException === ex) {
3396 processLastException();
3397 }
3398 }, stack.incomplete ? 2000 : 0);
3399
3400 if (rethrow !== false) {
3401 throw ex; // re-throw to propagate to the top level (and cause window.onerror)
3402 }
3403 }
3404
3405 report.subscribe = subscribe;
3406 report.unsubscribe = unsubscribe;
3407 report.uninstall = unsubscribeAll;
3408 return report;
3409 })();
3410
3411 /**
3412 * TraceKit.computeStackTrace: cross-browser stack traces in JavaScript
3413 *
3414 * Syntax:
3415 * s = TraceKit.computeStackTrace(exception) // consider using TraceKit.report instead (see below)
3416 * Returns:
3417 * s.name - exception name
3418 * s.message - exception message
3419 * s.stack[i].url - JavaScript or HTML file URL
3420 * s.stack[i].func - function name, or empty for anonymous functions (if guessing did not work)
3421 * s.stack[i].args - arguments passed to the function, if known
3422 * s.stack[i].line - line number, if known
3423 * s.stack[i].column - column number, if known
3424 *
3425 * Supports:
3426 * - Firefox: full stack trace with line numbers and unreliable column
3427 * number on top frame
3428 * - Opera 10: full stack trace with line and column numbers
3429 * - Opera 9-: full stack trace with line numbers
3430 * - Chrome: full stack trace with line and column numbers
3431 * - Safari: line and column number for the topmost stacktrace element
3432 * only
3433 * - IE: no line numbers whatsoever
3434 *
3435 * Tries to guess names of anonymous functions by looking for assignments
3436 * in the source code. In IE and Safari, we have to guess source file names
3437 * by searching for function bodies inside all page scripts. This will not
3438 * work for scripts that are loaded cross-domain.
3439 * Here be dragons: some function names may be guessed incorrectly, and
3440 * duplicate functions may be mismatched.
3441 *
3442 * TraceKit.computeStackTrace should only be used for tracing purposes.
3443 * Logging of unhandled exceptions should be done with TraceKit.report,
3444 * which builds on top of TraceKit.computeStackTrace and provides better
3445 * IE support by utilizing the window.onerror event to retrieve information
3446 * about the top of the stack.
3447 *
3448 * Note: In IE and Safari, no stack trace is recorded on the Error object,
3449 * so computeStackTrace instead walks its *own* chain of callers.
3450 * This means that:
3451 * * in Safari, some methods may be missing from the stack trace;
3452 * * in IE, the topmost function in the stack trace will always be the
3453 * caller of computeStackTrace.
3454 *
3455 * This is okay for tracing (because you are likely to be calling
3456 * computeStackTrace from the function you want to be the topmost element
3457 * of the stack trace anyway), but not okay for logging unhandled
3458 * exceptions (because your catch block will likely be far away from the
3459 * inner function that actually caused the exception).
3460 *
3461 */
3462 TraceKit.computeStackTrace = (function computeStackTraceWrapper() {
3463 // Contents of Exception in various browsers.
3464 //
3465 // SAFARI:
3466 // ex.message = Can't find variable: qq
3467 // ex.line = 59
3468 // ex.sourceId = 580238192
3469 // ex.sourceURL = http://...
3470 // ex.expressionBeginOffset = 96
3471 // ex.expressionCaretOffset = 98
3472 // ex.expressionEndOffset = 98
3473 // ex.name = ReferenceError
3474 //
3475 // FIREFOX:
3476 // ex.message = qq is not defined
3477 // ex.fileName = http://...
3478 // ex.lineNumber = 59
3479 // ex.columnNumber = 69
3480 // ex.stack = ...stack trace... (see the example below)
3481 // ex.name = ReferenceError
3482 //
3483 // CHROME:
3484 // ex.message = qq is not defined
3485 // ex.name = ReferenceError
3486 // ex.type = not_defined
3487 // ex.arguments = ['aa']
3488 // ex.stack = ...stack trace...
3489 //
3490 // INTERNET EXPLORER:
3491 // ex.message = ...
3492 // ex.name = ReferenceError
3493 //
3494 // OPERA:
3495 // ex.message = ...message... (see the example below)
3496 // ex.name = ReferenceError
3497 // ex.opera#sourceloc = 11 (pretty much useless, duplicates the info in ex.message)
3498 // ex.stacktrace = n/a; see 'opera:config#UserPrefs|Exceptions Have Stacktrace'
3499
3500 /**
3501 * Computes stack trace information from the stack property.
3502 * Chrome and Gecko use this property.
3503 * @param {Error} ex
3504 * @return {?Object.<string, *>} Stack trace information.
3505 */
3506 function computeStackTraceFromStackProp(ex) {
3507 if (typeof ex.stack === 'undefined' || !ex.stack) return;
3508
3509 var chrome = /^\s*at (.*?) ?\(((?:file|https?|blob|chrome-extension|native|eval|webpack|<anonymous>|[a-z]:|\/).*?)(?::(\d+))?(?::(\d+))?\)?\s*$/i,
3510 gecko = /^\s*(.*?)(?:\((.*?)\))?(?:^|@)((?:file|https?|blob|chrome|webpack|resource|\[native).*?|[^@]*bundle)(?::(\d+))?(?::(\d+))?\s*$/i,
3511 winjs = /^\s*at (?:((?:\[object object\])?.+) )?\(?((?:file|ms-appx|https?|webpack|blob):.*?):(\d+)(?::(\d+))?\)?\s*$/i,
3512 // Used to additionally parse URL/line/column from eval frames
3513 geckoEval = /(\S+) line (\d+)(?: > eval line \d+)* > eval/i,
3514 chromeEval = /\((\S*)(?::(\d+))(?::(\d+))\)/,
3515 lines = ex.stack.split('\n'),
3516 stack = [],
3517 submatch,
3518 parts,
3519 element,
3520 reference = /^(.*) is undefined$/.exec(ex.message);
3521
3522 for (var i = 0, j = lines.length; i < j; ++i) {
3523 if ((parts = chrome.exec(lines[i]))) {
3524 var isNative = parts[2] && parts[2].indexOf('native') === 0; // start of line
3525 var isEval = parts[2] && parts[2].indexOf('eval') === 0; // start of line
3526 if (isEval && (submatch = chromeEval.exec(parts[2]))) {
3527 // throw out eval line/column and use top-most line/column number
3528 parts[2] = submatch[1]; // url
3529 parts[3] = submatch[2]; // line
3530 parts[4] = submatch[3]; // column
3531 }
3532 element = {
3533 url: !isNative ? parts[2] : null,
3534 func: parts[1] || UNKNOWN_FUNCTION,
3535 args: isNative ? [parts[2]] : [],
3536 line: parts[3] ? +parts[3] : null,
3537 column: parts[4] ? +parts[4] : null
3538 };
3539 } else if ((parts = winjs.exec(lines[i]))) {
3540 element = {
3541 url: parts[2],
3542 func: parts[1] || UNKNOWN_FUNCTION,
3543 args: [],
3544 line: +parts[3],
3545 column: parts[4] ? +parts[4] : null
3546 };
3547 } else if ((parts = gecko.exec(lines[i]))) {
3548 var isEval = parts[3] && parts[3].indexOf(' > eval') > -1;
3549 if (isEval && (submatch = geckoEval.exec(parts[3]))) {
3550 // throw out eval line/column and use top-most line number
3551 parts[3] = submatch[1];
3552 parts[4] = submatch[2];
3553 parts[5] = null; // no column when eval
3554 } else if (i === 0 && !parts[5] && typeof ex.columnNumber !== 'undefined') {
3555 // FireFox uses this awesome columnNumber property for its top frame
3556 // Also note, Firefox's column number is 0-based and everything else expects 1-based,
3557 // so adding 1
3558 // NOTE: this hack doesn't work if top-most frame is eval
3559 stack[0].column = ex.columnNumber + 1;
3560 }
3561 element = {
3562 url: parts[3],
3563 func: parts[1] || UNKNOWN_FUNCTION,
3564 args: parts[2] ? parts[2].split(',') : [],
3565 line: parts[4] ? +parts[4] : null,
3566 column: parts[5] ? +parts[5] : null
3567 };
3568 } else {
3569 continue;
3570 }
3571
3572 if (!element.func && element.line) {
3573 element.func = UNKNOWN_FUNCTION;
3574 }
3575
3576 stack.push(element);
3577 }
3578
3579 if (!stack.length) {
3580 return null;
3581 }
3582
3583 return {
3584 name: ex.name,
3585 message: ex.message,
3586 url: getLocationHref(),
3587 stack: stack
3588 };
3589 }
3590
3591 /**
3592 * Adds information about the first frame to incomplete stack traces.
3593 * Safari and IE require this to get complete data on the first frame.
3594 * @param {Object.<string, *>} stackInfo Stack trace information from
3595 * one of the compute* methods.
3596 * @param {string} url The URL of the script that caused an error.
3597 * @param {(number|string)} lineNo The line number of the script that
3598 * caused an error.
3599 * @param {string=} message The error generated by the browser, which
3600 * hopefully contains the name of the object that caused the error.
3601 * @return {boolean} Whether or not the stack information was
3602 * augmented.
3603 */
3604 function augmentStackTraceWithInitialElement(stackInfo, url, lineNo, message) {
3605 var initial = {
3606 url: url,
3607 line: lineNo
3608 };
3609
3610 if (initial.url && initial.line) {
3611 stackInfo.incomplete = false;
3612
3613 if (!initial.func) {
3614 initial.func = UNKNOWN_FUNCTION;
3615 }
3616
3617 if (stackInfo.stack.length > 0) {
3618 if (stackInfo.stack[0].url === initial.url) {
3619 if (stackInfo.stack[0].line === initial.line) {
3620 return false; // already in stack trace
3621 } else if (
3622 !stackInfo.stack[0].line &&
3623 stackInfo.stack[0].func === initial.func
3624 ) {
3625 stackInfo.stack[0].line = initial.line;
3626 return false;
3627 }
3628 }
3629 }
3630
3631 stackInfo.stack.unshift(initial);
3632 stackInfo.partial = true;
3633 return true;
3634 } else {
3635 stackInfo.incomplete = true;
3636 }
3637
3638 return false;
3639 }
3640
3641 /**
3642 * Computes stack trace information by walking the arguments.caller
3643 * chain at the time the exception occurred. This will cause earlier
3644 * frames to be missed but is the only way to get any stack trace in
3645 * Safari and IE. The top frame is restored by
3646 * {@link augmentStackTraceWithInitialElement}.
3647 * @param {Error} ex
3648 * @return {?Object.<string, *>} Stack trace information.
3649 */
3650 function computeStackTraceByWalkingCallerChain(ex, depth) {
3651 var functionName = /function\s+([_$a-zA-Z\xA0-\uFFFF][_$a-zA-Z0-9\xA0-\uFFFF]*)?\s*\(/i,
3652 stack = [],
3653 funcs = {},
3654 recursion = false,
3655 parts,
3656 item,
3657 source;
3658
3659 for (
3660 var curr = computeStackTraceByWalkingCallerChain.caller;
3661 curr && !recursion;
3662 curr = curr.caller
3663 ) {
3664 if (curr === computeStackTrace || curr === TraceKit.report) {
3665 // console.log('skipping internal function');
3666 continue;
3667 }
3668
3669 item = {
3670 url: null,
3671 func: UNKNOWN_FUNCTION,
3672 line: null,
3673 column: null
3674 };
3675
3676 if (curr.name) {
3677 item.func = curr.name;
3678 } else if ((parts = functionName.exec(curr.toString()))) {
3679 item.func = parts[1];
3680 }
3681
3682 if (typeof item.func === 'undefined') {
3683 try {
3684 item.func = parts.input.substring(0, parts.input.indexOf('{'));
3685 } catch (e) {}
3686 }
3687
3688 if (funcs['' + curr]) {
3689 recursion = true;
3690 } else {
3691 funcs['' + curr] = true;
3692 }
3693
3694 stack.push(item);
3695 }
3696
3697 if (depth) {
3698 // console.log('depth is ' + depth);
3699 // console.log('stack is ' + stack.length);
3700 stack.splice(0, depth);
3701 }
3702
3703 var result = {
3704 name: ex.name,
3705 message: ex.message,
3706 url: getLocationHref(),
3707 stack: stack
3708 };
3709 augmentStackTraceWithInitialElement(
3710 result,
3711 ex.sourceURL || ex.fileName,
3712 ex.line || ex.lineNumber,
3713 ex.message || ex.description
3714 );
3715 return result;
3716 }
3717
3718 /**
3719 * Computes a stack trace for an exception.
3720 * @param {Error} ex
3721 * @param {(string|number)=} depth
3722 */
3723 function computeStackTrace(ex, depth) {
3724 var stack = null;
3725 depth = depth == null ? 0 : +depth;
3726
3727 try {
3728 stack = computeStackTraceFromStackProp(ex);
3729 if (stack) {
3730 return stack;
3731 }
3732 } catch (e) {
3733 if (TraceKit.debug) {
3734 throw e;
3735 }
3736 }
3737
3738 try {
3739 stack = computeStackTraceByWalkingCallerChain(ex, depth + 1);
3740 if (stack) {
3741 return stack;
3742 }
3743 } catch (e) {
3744 if (TraceKit.debug) {
3745 throw e;
3746 }
3747 }
3748 return {
3749 name: ex.name,
3750 message: ex.message,
3751 url: getLocationHref()
3752 };
3753 }
3754
3755 computeStackTrace.augmentStackTraceWithInitialElement = augmentStackTraceWithInitialElement;
3756 computeStackTrace.computeStackTraceFromStackProp = computeStackTraceFromStackProp;
3757
3758 return computeStackTrace;
3759 })();
3760
3761 module.exports = TraceKit;
3762
3763
3764 /***/ }),
3765
3766 /***/ "./node_modules/raven-js/vendor/json-stringify-safe/stringify.js":
3767 /*!***********************************************************************!*\
3768 !*** ./node_modules/raven-js/vendor/json-stringify-safe/stringify.js ***!
3769 \***********************************************************************/
3770 /***/ ((module, exports) => {
3771
3772 /*
3773 json-stringify-safe
3774 Like JSON.stringify, but doesn't throw on circular references.
3775
3776 Originally forked from https://github.com/isaacs/json-stringify-safe
3777 version 5.0.1 on 3/8/2017 and modified to handle Errors serialization
3778 and IE8 compatibility. Tests for this are in test/vendor.
3779
3780 ISC license: https://github.com/isaacs/json-stringify-safe/blob/master/LICENSE
3781 */
3782
3783 exports = module.exports = stringify;
3784 exports.getSerialize = serializer;
3785
3786 function indexOf(haystack, needle) {
3787 for (var i = 0; i < haystack.length; ++i) {
3788 if (haystack[i] === needle) return i;
3789 }
3790 return -1;
3791 }
3792
3793 function stringify(obj, replacer, spaces, cycleReplacer) {
3794 return JSON.stringify(obj, serializer(replacer, cycleReplacer), spaces);
3795 }
3796
3797 // https://github.com/ftlabs/js-abbreviate/blob/fa709e5f139e7770a71827b1893f22418097fbda/index.js#L95-L106
3798 function stringifyError(value) {
3799 var err = {
3800 // These properties are implemented as magical getters and don't show up in for in
3801 stack: value.stack,
3802 message: value.message,
3803 name: value.name
3804 };
3805
3806 for (var i in value) {
3807 if (Object.prototype.hasOwnProperty.call(value, i)) {
3808 err[i] = value[i];
3809 }
3810 }
3811
3812 return err;
3813 }
3814
3815 function serializer(replacer, cycleReplacer) {
3816 var stack = [];
3817 var keys = [];
3818
3819 if (cycleReplacer == null) {
3820 cycleReplacer = function(key, value) {
3821 if (stack[0] === value) {
3822 return '[Circular ~]';
3823 }
3824 return '[Circular ~.' + keys.slice(0, indexOf(stack, value)).join('.') + ']';
3825 };
3826 }
3827
3828 return function(key, value) {
3829 if (stack.length > 0) {
3830 var thisPos = indexOf(stack, this);
3831 ~thisPos ? stack.splice(thisPos + 1) : stack.push(this);
3832 ~thisPos ? keys.splice(thisPos, Infinity, key) : keys.push(key);
3833
3834 if (~indexOf(stack, value)) {
3835 value = cycleReplacer.call(this, key, value);
3836 }
3837 } else {
3838 stack.push(value);
3839 }
3840
3841 return replacer == null
3842 ? value instanceof Error ? stringifyError(value) : value
3843 : replacer.call(this, key, value);
3844 };
3845 }
3846
3847
3848 /***/ }),
3849
3850 /***/ "jquery":
3851 /*!*************************!*\
3852 !*** external "jQuery" ***!
3853 \*************************/
3854 /***/ ((module) => {
3855
3856 "use strict";
3857 module.exports = window["jQuery"];
3858
3859 /***/ })
3860
3861 /******/ });
3862 /************************************************************************/
3863 /******/ // The module cache
3864 /******/ var __webpack_module_cache__ = {};
3865 /******/
3866 /******/ // The require function
3867 /******/ function __webpack_require__(moduleId) {
3868 /******/ // Check if module is in cache
3869 /******/ var cachedModule = __webpack_module_cache__[moduleId];
3870 /******/ if (cachedModule !== undefined) {
3871 /******/ return cachedModule.exports;
3872 /******/ }
3873 /******/ // Create a new module (and put it into the cache)
3874 /******/ var module = __webpack_module_cache__[moduleId] = {
3875 /******/ // no module.id needed
3876 /******/ // no module.loaded needed
3877 /******/ exports: {}
3878 /******/ };
3879 /******/
3880 /******/ // Execute the module function
3881 /******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__);
3882 /******/
3883 /******/ // Return the exports of the module
3884 /******/ return module.exports;
3885 /******/ }
3886 /******/
3887 /************************************************************************/
3888 /******/ /* webpack/runtime/compat get default export */
3889 /******/ (() => {
3890 /******/ // getDefaultExport function for compatibility with non-harmony modules
3891 /******/ __webpack_require__.n = (module) => {
3892 /******/ var getter = module && module.__esModule ?
3893 /******/ () => (module['default']) :
3894 /******/ () => (module);
3895 /******/ __webpack_require__.d(getter, { a: getter });
3896 /******/ return getter;
3897 /******/ };
3898 /******/ })();
3899 /******/
3900 /******/ /* webpack/runtime/define property getters */
3901 /******/ (() => {
3902 /******/ // define getter functions for harmony exports
3903 /******/ __webpack_require__.d = (exports, definition) => {
3904 /******/ for(var key in definition) {
3905 /******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
3906 /******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
3907 /******/ }
3908 /******/ }
3909 /******/ };
3910 /******/ })();
3911 /******/
3912 /******/ /* webpack/runtime/global */
3913 /******/ (() => {
3914 /******/ __webpack_require__.g = (function() {
3915 /******/ if (typeof globalThis === 'object') return globalThis;
3916 /******/ try {
3917 /******/ return this || new Function('return this')();
3918 /******/ } catch (e) {
3919 /******/ if (typeof window === 'object') return window;
3920 /******/ }
3921 /******/ })();
3922 /******/ })();
3923 /******/
3924 /******/ /* webpack/runtime/hasOwnProperty shorthand */
3925 /******/ (() => {
3926 /******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))
3927 /******/ })();
3928 /******/
3929 /******/ /* webpack/runtime/make namespace object */
3930 /******/ (() => {
3931 /******/ // define __esModule on exports
3932 /******/ __webpack_require__.r = (exports) => {
3933 /******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
3934 /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
3935 /******/ }
3936 /******/ Object.defineProperty(exports, '__esModule', { value: true });
3937 /******/ };
3938 /******/ })();
3939 /******/
3940 /************************************************************************/
3941 var __webpack_exports__ = {};
3942 // This entry need to be wrapped in an IIFE because it need to be in strict mode.
3943 (() => {
3944 "use strict";
3945 /*!*************************************!*\
3946 !*** ./scripts/entries/feedback.ts ***!
3947 \*************************************/
3948 __webpack_require__.r(__webpack_exports__);
3949 /* harmony import */ var jquery__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! jquery */ "jquery");
3950 /* harmony import */ var jquery__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(jquery__WEBPACK_IMPORTED_MODULE_0__);
3951 /* harmony import */ var _lib_Raven__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../lib/Raven */ "./scripts/lib/Raven.ts");
3952 /* harmony import */ var _constants_selectors__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../constants/selectors */ "./scripts/constants/selectors.ts");
3953 /* harmony import */ var _feedback_ThickBoxModal__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../feedback/ThickBoxModal */ "./scripts/feedback/ThickBoxModal.ts");
3954 /* harmony import */ var _feedback_feedbackFormApi__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../feedback/feedbackFormApi */ "./scripts/feedback/feedbackFormApi.ts");
3955 /* harmony import */ var _utils_backgroundAppUtils__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../utils/backgroundAppUtils */ "./scripts/utils/backgroundAppUtils.ts");
3956 /* harmony import */ var _iframe_integratedMessages__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../iframe/integratedMessages */ "./scripts/iframe/integratedMessages/index.ts");
3957
3958
3959
3960
3961
3962
3963
3964 var embedder;
3965 function deactivatePlugin() {
3966 var href = jquery__WEBPACK_IMPORTED_MODULE_0___default()(_constants_selectors__WEBPACK_IMPORTED_MODULE_2__.domElements.deactivatePluginButton).attr('href');
3967 if (href) {
3968 window.location.href = href;
3969 }
3970 }
3971 function setLoadingState() {
3972 jquery__WEBPACK_IMPORTED_MODULE_0___default()(_constants_selectors__WEBPACK_IMPORTED_MODULE_2__.domElements.deactivateFeedbackSubmit).addClass('loading');
3973 }
3974 function submitAndDeactivate(e) {
3975 e.preventDefault();
3976 setLoadingState();
3977 var feedback = jquery__WEBPACK_IMPORTED_MODULE_0___default()(_constants_selectors__WEBPACK_IMPORTED_MODULE_2__.domElements.deactivateFeedbackForm).serializeArray().find(function (field) {
3978 return field.name === 'feedback';
3979 });
3980 (0,_feedback_feedbackFormApi__WEBPACK_IMPORTED_MODULE_4__.submitFeedbackForm)(_constants_selectors__WEBPACK_IMPORTED_MODULE_2__.domElements.deactivateFeedbackForm).then(function () {
3981 if (feedback) {
3982 embedder.postMessage({
3983 key: _iframe_integratedMessages__WEBPACK_IMPORTED_MODULE_6__.ProxyMessages.TrackPluginDeactivation,
3984 payload: {
3985 type: feedback.value.trim().replace(/[\s']+/g, '_')
3986 }
3987 });
3988 }
3989 })["catch"](function (err) {
3990 _lib_Raven__WEBPACK_IMPORTED_MODULE_1__["default"].captureException(err);
3991 })["finally"](function () {
3992 deactivatePlugin();
3993 });
3994 }
3995 function init() {
3996 embedder = (0,_utils_backgroundAppUtils__WEBPACK_IMPORTED_MODULE_5__.getOrCreateBackgroundApp)();
3997 // eslint-disable-next-line no-new
3998 new _feedback_ThickBoxModal__WEBPACK_IMPORTED_MODULE_3__["default"](_constants_selectors__WEBPACK_IMPORTED_MODULE_2__.domElements.deactivatePluginButton, 'leadin-feedback-container', 'leadin-feedback-window', 'leadin-feedback-content');
3999 jquery__WEBPACK_IMPORTED_MODULE_0___default()(_constants_selectors__WEBPACK_IMPORTED_MODULE_2__.domElements.deactivateFeedbackForm).off('submit').on('submit', submitAndDeactivate);
4000 jquery__WEBPACK_IMPORTED_MODULE_0___default()(_constants_selectors__WEBPACK_IMPORTED_MODULE_2__.domElements.deactivateFeedbackSkip).off('click').on('click', deactivatePlugin);
4001 }
4002 (0,_utils_backgroundAppUtils__WEBPACK_IMPORTED_MODULE_5__.initBackgroundApp)(init);
4003 })();
4004
4005 /******/ })()
4006 ;
4007 //# sourceMappingURL=feedback.js.map