PluginProbe
HubSpot All-In-One Marketing – Forms, Popups, Live Chat / 11.3.61
HubSpot All-In-One Marketing – Forms, Popups, Live Chat v11.3.61
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.61, at build/reviewBanner.js

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