PluginProbe
HubSpot All-In-One Marketing – Forms, Popups, Live Chat / 11.3.75
HubSpot All-In-One Marketing – Forms, Popups, Live Chat v11.3.75
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 / reviewBanner.js

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

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