PageSourceSearch

https://www.faber-castell.us/extensions/019e59ec-ba32-7efd-8c73-45…/assets/restock-sdk-loader_v-1779625125.js

js faber-castell.us collected 2026-10-02 11:53:03 UTC 8,190 bytes, 211 lines download raw bytes

1(function () {
2  window._ReStockConfig = window._ReStockConfig || {};
3  var _ReStockConfig = window._ReStockConfig;
4
5  var metafieldConfigData = _ReStockConfig._metafields ? _ReStockConfig._metafields.sdkConfig : null;
6  var metafieldPreOrderData = _ReStockConfig._metafields ? _ReStockConfig._metafields.preOrderConfig : null;
7  var metafieldWishlistData = _ReStockConfig._metafields ? _ReStockConfig._metafields.wishlistConfig : undefined;
8  var metafieldFlagsData = _ReStockConfig._metafields ? _ReStockConfig._metafields.featureFlags : null;
9
10  delete window._ReStockConfig._metafields;
11
12  function createRestockScript() {
13    const restockSdkElement = document.createElement('script');
14    restockSdkElement.setAttribute('defer', 'defer');
15    restockSdkElement.src = "https://cdn.notify-me.io/sdk.js";
16    document.body.appendChild(restockSdkElement);
17  }
18
19  function processNotifyMeConfigData(configData) {
20    if (!configData.app_enabled) {
21      return;
22    }
23    if (configData.is_suspended) {
24      return;
25    }
26
27    _ReStockConfig = { ..._ReStockConfig, ...configData };
28    window._ReStockConfig = _ReStockConfig;
29
30    if (_ReStockConfig.wishlist?.is_service_active) {
31      createRestockScript();
32      return;
33    }
34
35    if (['collection', 'list-collections', 'search', 'page'].includes(_ReStockConfig.templateName)) {
36      const collectionDisplayMode = configData.ui_style?.notify_me_styles?.find(config => config.page === 'COLLECTION_PAGE')?.inline_display_mode;
37      const preOrderCollectionDisplayMode = configData.pre_order?.collection_page?.ui_styles?.display_mode;
38
39      if ((!configData.is_back_in_stock_active || collectionDisplayMode === 'NOT_DISPLAYED') &&
40        (!configData.pre_order?.is_service_active || preOrderCollectionDisplayMode === 'NOT_DISPLAYED')) {
41        return;
42      }
43    }
44
45    if (_ReStockConfig.templateName === 'index') {
46      const landingDisplayMode = configData.ui_style?.notify_me_styles?.find(config => config.page === 'LANDING_PAGES')?.inline_display_mode;
47      const preOrderLandingDisplayMode = configData.pre_order?.landing_page?.ui_styles?.display_mode;
48
49      if ((!configData.is_back_in_stock_active || landingDisplayMode === 'NOT_DISPLAYED') &&
50        (!configData.pre_order?.is_service_active || preOrderLandingDisplayMode === 'NOT_DISPLAYED')) {
51        return;
52      }
53    }
54
55    createRestockScript();
56  }
57
58  function hashDomain(domain) {
59    let hash = 5381;
60    for (let i = 0; i < domain.length; i++) {
61      hash = ((hash << 5) + hash + domain.charCodeAt(i)) >>> 0;
62    }
63    return hash;
64  }
65
66  function assignGroup(shopifyDomain) {
67    const DOBBY_USAGE_PERCENTAGE = 0;
68    if (DOBBY_USAGE_PERCENTAGE <= 0) {
69      return "A";
70    } else if (DOBBY_USAGE_PERCENTAGE >= 100) {
71      return "B";
72    }
73    const hashValue = hashDomain(shopifyDomain);
74    const normalized = (hashValue / 0x100000000) * 100;
75    return normalized <= DOBBY_USAGE_PERCENTAGE ? "B" : "A";
76  }
77
78  try {
79
80    try {
81      const searchParams = new URLSearchParams(window.location.search);
82      const shopDomain = searchParams.get('SHOP_DOMAIN') || window.Shopify?.shop || window.location.host;
83
84      const abTestGroup = assignGroup(shopDomain);
85      window._ReStockConfig.ab_test_group = abTestGroup;
86
87      if (abTestGroup === "B") {
88        const dobbyApiUrl = `https://dobby.notify-me.app/sdk/${shopDomain}`;
89
90        fetch(dobbyApiUrl)
91          .then(response => {
92            if (!response.ok) {
93              throw new Error(`Dobby API returned status ${response.status}`);
94            }
95            return response.json();
96          })
97          .then(data => {
98            const wishlistConfig = data.wishlist ?? null;
99
100            const { wishlist, ...sdkConfig } = data;
101
102            if (!sdkConfig || !sdkConfig.shop_id) {
103              throw new Error('Invalid Dobby API response');
104            }
105
106            window._ReStockConfig.wishlist = wishlistConfig !== null ? wishlistConfig : (metafieldWishlistData ?? undefined);
107
108            processNotifyMeConfigData(sdkConfig);
109          })
110          .catch(error => {
111            window._ReStockConfig.wishlist = metafieldWishlistData ?? undefined;
112            window._ReStockConfig.pre_order = metafieldPreOrderData;
113            window._ReStockConfig.feature_flags = metafieldFlagsData;
114
115            if (metafieldConfigData && metafieldConfigData.shop_id) {
116              processNotifyMeConfigData(metafieldConfigData);
117            } else {
118              createRestockScript();
119            }
120          });
121      } else {
122        const hasSdkMetafield = metafieldConfigData && metafieldConfigData.shop_id;
123        const hasPreOrderMetafield = metafieldPreOrderData && typeof metafieldPreOrderData === 'object' && Object.keys(metafieldPreOrderData).length > 0;
124        const hasFlagsMetafield = metafieldFlagsData && typeof metafieldFlagsData === 'object';
125
126        const fallbackApiUrl = `https://api.notify-me.app/sdk/${shopDomain}`;
127        const preOrderFallbackApiUrl = `https://api.notify-me.app/pre-order/sdk/${shopDomain}`;
128        const flagsFallbackApiUrl = `https://api.notify-me.app/feature-flags/sdk/${shopDomain}`;
129
130        const fetchSdkConfig = () => {
131          return fetch(fallbackApiUrl)
132            .then(response => {
133              if (!response.ok) throw new Error(`SDK API returned status ${response.status}`);
134              return response.json();
135            })
136            .then(data => {
137              const { wishlist, ...sdkConfig } = data;
138              if (!sdkConfig || !sdkConfig.shop_id) throw new Error('Invalid SDK API response');
139              return { sdkConfig, wishlistConfig: wishlist ?? null };
140            });
141        };
142
143        const fetchPreOrderConfig = () => {
144          return fetch(preOrderFallbackApiUrl)
145            .then(response => {
146              if (!response.ok) throw new Error(`Pre-order API returned status ${response.status}`);
147              return response.json();
148            })
149            .then(data => {
150              return data;
151            });
152        };
153
154        const fetchFlagsConfig = () => {
155          return fetch(flagsFallbackApiUrl)
156            .then(response => {
157              if (!response.ok) throw new Error(`Flags API returned status ${response.status}`);
158              return response.json();
159            });
160        };
161
162        const sdkPromise = hasSdkMetafield
163          ? Promise.resolve({ sdkConfig: metafieldConfigData, wishlistConfig: null })
164          : fetchSdkConfig().catch(err => {
165            return null;
166          });
167
168        const preOrderPromise = hasPreOrderMetafield
169          ? Promise.resolve(metafieldPreOrderData)
170          : fetchPreOrderConfig().catch(err => {
171            return null;
172          });
173
174        const flagsPromise = hasFlagsMetafield
175          ? Promise.resolve(metafieldFlagsData)
176          : fetchFlagsConfig().catch(err => {
177            return null;
178          });
179
180        Promise.all([sdkPromise, preOrderPromise, flagsPromise])
181          .then(([sdkResult, preOrderConfig, flagsConfig]) => {
182            if (sdkResult) {
183              window._ReStockConfig.wishlist = sdkResult.wishlistConfig !== null
184                ? sdkResult.wishlistConfig
185                : (metafieldWishlistData ?? undefined);
186              const combinedConfig = { ...sdkResult.sdkConfig, pre_order: preOrderConfig, feature_flags: flagsConfig };
187              processNotifyMeConfigData(combinedConfig);
188            } else {
189              window._ReStockConfig.wishlist = metafieldWishlistData ?? undefined;
190              window._ReStockConfig.pre_order = preOrderConfig;
191              window._ReStockConfig.feature_flags = flagsConfig;
192              createRestockScript();
193            }
194          });
195      }
196    }
197    catch (e) {
198      window._ReStockConfig.wishlist = metafieldWishlistData ?? undefined;
199      window._ReStockConfig.pre_order = metafieldPreOrderData;
200      window._ReStockConfig.feature_flags = metafieldFlagsData;
201
202      if (metafieldConfigData && metafieldConfigData.shop_id) {
203        processNotifyMeConfigData(metafieldConfigData);
204      } else {
205        createRestockScript();
206      }
207    }
208  } catch (error) {
209    createRestockScript();
210  }
211})();

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.