PluginProbe
HubSpot All-In-One Marketing – Forms, Popups, Live Chat / 11.3.56
HubSpot All-In-One Marketing – Forms, Popups, Live Chat v11.3.56
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.56, at build/feedback.js

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