1window.IMWEB_SHOP_FREE_SHIP_NOTIFY_SDK = (function () { 2 3 // magnet-shell custom element를 íì´ì§ ë¡ë ìì ì 미리 ë±ë¡íë¤. 4 // ëì 주ì ëë ëª¨ë¬ HTML(get_order_alarm_modal / get_add_cart_alarm_modal / get_product_option_modal) ìì 5 // ê°ì import ì¤í¬ë¦½í¸ê° ìì§ë§ innerHTML/appendë¡ ë¤ì´ê°ë©´ ë¸ë¼ì°ì ê° <script>를 ì¤ííì§ ìì¼ë¯ë¡, 6 // SDK ì§ì ìì ì í ë² registeríì¬ ëì magnet-shellì´ ìë upgradeëëë¡ ë³´ì¥íë¤. 7 // customElements.defineì idempotentíì¬ ëª¨ë¬ ì¸¡ ì¸ë¼ì¸ importê° ë¤ì í¸ì¶ëì´ë 무í´. 8 function patchMagnetShell(MagnetShellClass) { 9 if (!MagnetShellClass || MagnetShellClass.__imwebManifestUrlPatched) { 10 return; 11 } 12 13 var proto = MagnetShellClass.prototype; 14 var connectedCallback = proto.connectedCallback; 15 var resetMangetNode = proto.resetMangetNode; 16 var attributeChangedCallback = proto.attributeChangedCallback; 17 18 function syncManifestUrl(element) { 19 element.manifestUrl = element.manifestUrl || element.getAttribute('data-manifest-url') || element.getAttribute('manifest-url') || ''; 20 } 21 22 function executeProductRecommendationModuleScripts(element) { 23 if (!element.classList || !element.classList.contains('foProductRecommendationMagnet')) { 24 return; 25 } 26 27 var scripts = element.querySelectorAll('script[type="module"][src]'); 28 Array.prototype.forEach.call(scripts, function (script) { 29 var src = script.getAttribute('src') || ''; 30 if (!src || src.indexOf('/_/fo-shopping/assets/product-recommendation-') === -1 || script.getAttribute('data-imweb-executed') === 'Y') { 31 return; 32 } 33 34 script.setAttribute('data-imweb-executed', 'Y'); 35 36 var executedScript = document.createElement('script'); 37 executedScript.type = 'module'; 38 executedScript.src = src; 39 if (script.getAttribute('crossorigin') !== null) { 40 executedScript.setAttribute('crossorigin', script.getAttribute('crossorigin') || ''); 41 } 42 document.head.appendChild(executedScript); 43 }); 44 } 45 46 proto.connectedCallback = function () { 47 syncManifestUrl(this); 48 return connectedCallback.apply(this, arguments); 49 }; 50 51 proto.resetMangetNode = function () { 52 syncManifestUrl(this); 53 var result = resetMangetNode.apply(this, arguments); 54 if (result && typeof result.then === 'function') { 55 return result.then(function (value) { 56 executeProductRecommendationModuleScripts(this); 57 return value; 58 }.bind(this)); 59 } 60 61 executeProductRecommendationModuleScripts(this); 62 return result; 63 }; 64 65 proto.attributeChangedCallback = function (name, oldValue, newValue) { 66 if (name === 'data-manifest-url' || name === 'manifest-url') { 67 this.manifestUrl = newValue || this.getAttribute('data-manifest-url') || this.getAttribute('manifest-url') || ''; 68 if (typeof this.clearManifest === 'function') { 69 this.clearManifest(); 70 } 71 return; 72 } 73 if (typeof attributeChangedCallback === 'function') { 74 return attributeChangedCallback.apply(this, arguments); 75 } 76 }; 77 78 MagnetShellClass.__imwebManifestUrlPatched = true; 79 } 80 81 if (typeof customElements !== 'undefined') { 82 var registeredMagnetShell = customElements.get('magnet-shell'); 83 if (registeredMagnetShell) { 84 patchMagnetShell(registeredMagnetShell); 85 } else { 86 import('https://static.imweb.me/design-system/magnet/magnet-shell.js') 87 .then(function (module) { 88 var currentMagnetShell = customElements.get('magnet-shell'); 89 if (currentMagnetShell) { 90 patchMagnetShell(currentMagnetShell); 91 return; 92 } 93 94 var BaseMagnetShell = module.MagnetShell; 95 class ImwebMagnetShell extends BaseMagnetShell { 96 static get observedAttributes() { 97 var observedAttributes = BaseMagnetShell.observedAttributes || []; 98 return observedAttributes.indexOf('data-manifest-url') === -1 99 ? observedAttributes.concat('data-manifest-url') 100 : observedAttributes; 101 } 102 } 103 104 customElements.define('magnet-shell', ImwebMagnetShell); 105 patchMagnetShell(ImwebMagnetShell); 106 }) 107 .catch(console.warn); 108 } 109 } 110 111 // ì¥ë°êµ¬ë íì´ì§ì 주문 ì림 모ë¬(get_order_alarm_modal)ì ë¸ë¼ì°ì ì
111¸ì 1íë§ ë ¸ì¶íë¤. 112 // IMWEB_SESSIONSTORAGE(vendor/js/common.js) ë ê°ì íì íì´ì§ ì´ëìë ì´ìë¨ì¼ë¯ë¡ ì¬ì§ì í´ë ë¤ì ë¨ì§ ìì. 113 // í ì¢ ë£ / ì í ì§ì / ìí¬ë¦¿ì°½ ì¢ ë£ ìì ì ìì°ì¤ë½ê² 리ì ëê³ , ë¡ê·¸ìì/ë¡ê·¸ì¸ ì logout.cm / backpg/login.cm ìì ëª ìì ì¼ë¡ ì ê±°ëë¤. 114 // ì¤í 리ì§ê° ë§í íê²½(IMWEB_SESSIONSTORAGE 미íê° ë±)ììë ë ¸ì¶íì§ ìëë¤ â ì´ë¯¸ 본 ê²ì¼ë¡ ê°ì£¼. 115 // 116 // íí¸ ìí ìì¸ì ì¥ë°êµ¬ë ë´ê¸° ì림 모ë¬(get_add_cart_alarm_modal)ì ìëì ì¼ë¡ íì´ì§ë·° 1í ì ì± ì ì ì§ â 117 // ìíì ëë¬ë³´ë©° ì¬ë¬ ë² ë´ë íë¦ìì ë§¤ë² ì림ì 주ë ì¬ì©ì±ì´ íìíë¤. 118 var _SESSION_KEY_ORDER_ALARM_SHOWN = 'imweb:freeShipNotify:orderAlarmShown'; 119 var _addCartAlarmShownInThisPageview = false; 120 121 // SDK ë ì¼ë° script ë¡ ì¦ì íê°ëì§ë§ mfe ë²ë¤ì module ë¡ defer ë¡ëëì´, 122 // POPUP ë¨ë 모ëììë cart_list_make ìëµì cartTotal:update / cartFreeShippingRemainingPrice:update 123 // dispatch ê° mfe 모ë íê°ë³´ë¤ 먼ì ë°ìí´ mfe store ê° ì´ë²¤í¸ë¥¼ ëì¹ë ì¼ì´ì¤ê° ìë¤. 124 // SDK ê° ë ì´ë²¤í¸ë¥¼ listen í´ ë§ì§ë§ ê°ì ìºì±íê³ , mfe store ê° ëª¨ë íê° ìì ì 125 // ì´ ìºììì ì´ê¸°ê°ì hydrate íì¬ dispatch ëë½ìë ì¼ê´ë ê°ì ê°ëë¡ íë¤. 126 var _cachedCartTotal = null; 127 var _cachedCartFreeShippingRemainingPrice = null; 128 var _cachedSelectedOptionsTotal = null; 129 var _cachedFreeShipNotifySettings = null; 130 window.addEventListener('imweb:freeShipNotify:cartTotal:update', function (e) { 131 var detail = e && e.detail ? e.detail : {}; 132 if (typeof detail.totalPrice === 'number') { 133 _cachedCartTotal = detail.totalPrice; 134 } 135 }); 136 window.addEventListener('imweb:freeShipNotify:cartFreeShippingRemainingPrice:update', function (e) { 137 var detail = e && e.detail ? e.detail : {}; 138 if (typeof detail.remainingPrice === 'number') { 139 _cachedCartFreeShippingRemainingPrice = detail.remainingPrice; 140 } 141 }); 142 // ìí ìì¸ ì§ì ì site_shop.js ì initDetail ì´ ìµì ìë ìíì íí´ 143 // 무ë£ë°°ì¡ ê¸°ì¤ ìí ê¸ì¡ì selectedOptions:update ë¡ ì¦ì dispatch íë¤. 144 // ì´ dispatch ê° mfe 모ë íê°ë³´ë¤ ë¹ ë¥¼ ì ìì´ cartTotal ê³¼ ëì¼íê² SDK ê° ìºì±íë¤. 145 window.addEventListener('imweb:freeShipNotify:selectedOptions:update', function (e) { 146 var detail = e && e.detail ? e.detail : {}; 147 if (typeof detail.totalPrice === 'number') { 148 _cachedSelectedOptionsTotal = detail.totalPrice; 149 } 150 }); 151 152 /** 153 * mfe store ê° ëª¨ë íê° ìì ì í¸ì¶. dispatch ëë½ ì¼ì´ì¤ì ì´ê¸°ê°ì¼ë¡ ì¬ì©ëë¤. 154 * @returns {number|null} 155 */ 156 function getCachedCartTotal() { 157 return _cachedCartTotal; 158 } 159 /** 160 * mfe store ê° ëª¨ë íê° ìì ì í¸ì¶. dispatch ëë½ ì¼ì´ì¤ì ì´ê¸°ê°ì¼ë¡ ì¬ì©ëë¤. 161 * @returns {number|null} 162 */ 163 function getCachedCartFreeShippingRemainingPrice() { 164 return _cachedCartFreeShippingRemainingPrice; 165 } 166 /** 167 * mfe store ê° ëª¨ë íê° ìì ì í¸ì¶. dispatch ëë½ ì¼ì´ì¤ì ì´ê¸°ê°ì¼ë¡ ì¬ì©ëë¤. 168 * @returns {number|null} 169 */ 170 function getCachedSelectedOptionsTotal() { 171 return _cachedSelectedOptionsTotal; 172 } 173 /** 174 * mfe store ê° ëª¨ë íê° ìì ì í¸ì¶. BO 미리보기 settings:update ê° MFE ë§ì´í¸ë³´ë¤ 먼ì ë°ìí ê²½ì°ì ì´ê¸°ê°ì¼ë¡ ì¬ì©ëë¤. 175 * @returns {object|null} 176 */ 177 function getCachedFreeShipNotifySettings() { 178 return _cachedFreeShipNotifySettings; 179 } 180 181 // 매ì¶ìì¹ë구 미리보기(sales_tool_preview=freeShipNotify) ì§ì ììë íì´ì§ë·° 1í ì íì ì°ííë¤. 182 // BOìì ëª¨ë¬ ë¯¸ë¦¬ë³´ê¸°ë¥¼ ë°ë³µ íì¸í ì ìì´ì¼ íë¯ë¡ has*AlarmShownì íì false를 ë°í. 183 // ì´ê¸°í ìì ì 1í íê°í´ closureì ë³´ê´íë©´ 매 í¸ì¶ë§ë¤ URL íì± ë¹ì©ì ë¤ì´ì§ ììë ëë¤. 184 var _isSalesToolFreeShipNotifyPreview = (function () { 185 try { 186 var params = new URLSearchParams(window.location.search); 187 return params.get('sales_tool_preview') === 'freeShipNotify'; 188 } catch (e) { 189 return false;
190 } 191 })(); 192 193 if (_isSalesToolFreeShipNotifyPreview) { 194 var isAllowedSalesToolPreviewOrigin = function (origin) { 195 if (origin === window.location.origin) return true; 196 return /^https:\/\/[a-z0-9-]+\.crm\.(imweb|imtest)\.me$/.test(origin); 197 }; 198 199 // ëì íê² ìì¹ë¥¼ ëê³ RAF ë§ë¤ ìì¬ ê±°ë¦¬ì ì¼ë¶ì© ì¢íë ease-out ë°©ì. 200 // wheel ì´ ë¹ ë¥´ê² ì°ìì¼ë¡ ë¤ì´ìë ë§¤ë² ì¦ì scrollBy íì§ ìê³ target ì ëì ë§ íë¯ë¡ 201 // behavior:'smooth' ê° ë§ëë íì/ëê¹ ìì´ ë§¤ëë¬ì´ ê´ì± ì¤í¬ë¡¤ë¡ ë³´ì¸ë¤. 202 // ì ëë©ì´ì ì´ ë©ì¶°ì target=null ì´ ëë©´ ë¤ì wheel ìì íì¬ ì¤í¬ë¡¤ ìì¹ë¡ ì¬ë기í â ì¸ë¶ ì¤í¬ë¡¤ ë³ê²½(ìµì»¤ ì´ë ë±)ê³¼ ìì°ì¤ë½ê² ì í©. 203 var smoothScrollState = { targetX: null, targetY: null, rafId: 0 }; 204 var SMOOTH_SCROLL_EASE = 0.2; 205 206 var tickSmoothScroll = function () { 207 var s = smoothScrollState; 208 var dy = s.targetY - window.scrollY; 209 var dx = s.targetX - window.scrollX; 210 if (Math.abs(dy) < 0.5 && Math.abs(dx) < 0.5) { 211 window.scrollTo(s.targetX, s.targetY); 212 s.rafId = 0; 213 s.targetX = null; 214 s.targetY = null; 215 return; 216 } 217 window.scrollBy(dx * SMOOTH_SCROLL_EASE, dy * SMOOTH_SCROLL_EASE); 218 s.rafId = requestAnimationFrame(tickSmoothScroll); 219 }; 220 221 window.addEventListener('message', function (event) { 222 if (!isAllowedSalesToolPreviewOrigin(event.origin)) return; 223 var data = event.data; 224 if (!data || typeof data !== 'object') return; 225 if (data.type !== 'sales-tool-preview:wheel') return; 226 var deltaY = typeof data.deltaY === 'number' ? data.deltaY : 0; 227 var deltaX = typeof data.deltaX === 'number' ? data.deltaX : 0; 228 229 var s = smoothScrollState; 230 if (s.targetY === null) { 231 s.targetY = window.scrollY; 232 s.targetX = window.scrollX; 233 } 234 var maxY = Math.max(0, (document.documentElement.scrollHeight || 0) - window.innerHeight); 235 var maxX = Math.max(0, (document.documentElement.scrollWidth || 0) - window.innerWidth); 236 s.targetY = Math.max(0, Math.min(maxY, s.targetY + deltaY)); 237 s.targetX = Math.max(0, Math.min(maxX, s.targetX + deltaX)); 238 if (!s.rafId) { 239 s.rafId = requestAnimationFrame(tickSmoothScroll); 240 } 241 }); 242 } 243 244 /** 245 * ì¥ë°êµ¬ë 주문 ì림 모ë¬ì´ ì´ë² ë¸ë¼ì°ì ì¸ì (ê°ì íì íì´ì§ ì´ë í¬í¨) ììì ì´ë¯¸ ë ¸ì¶ëëì§ ì¬ë¶. 246 * IMWEB_SESSIONSTORAGE 미íê° ë± ì¤í ë¦¬ì§ ì ê·¼ ë¶ê° ììë ë ¸ì¶ì ë³´ë¥íë¤ (ì´ë¯¸ 본 ê²ì¼ë¡ ê°ì£¼). 247 * 미리보기 모ëììë ë§¤ë² false를 ë°íí´ 1í ì íì ì°ííë¤. 248 * @returns {boolean} 249 */ 250 function hasOrderAlarmShown() { 251 if (_isSalesToolFreeShipNotifyPreview) return false; 252 if (typeof IMWEB_SESSIONSTORAGE === 'undefined') return true; 253 return IMWEB_SESSIONSTORAGE.get(_SESSION_KEY_ORDER_ALARM_SHOWN) === true; 254 } 255 256 /** 257 * ì¥ë°êµ¬ë 주문 ì림 모ë¬ì´ ë ¸ì¶ëìì 기ë¡. AJAXë¡ ëª¨ë¬ HTMLì fetchí기 ì§ì ì í¸ì¶íë¤. 258 * sessionStorage ì 기ë¡í´ ê°ì íì ë¤ë¥¸ íì´ì§ë¡ ì´ëí´ë ì¬ë ¸ì¶ëì§ ìê² íë¤. 259 */ 260 function markOrderAlarmShown() { 261 if (typeof IMWEB_SESSIONSTORAGE === 'undefined') return; 262 try { 263 IMWEB_SESSIONSTORAGE.set(_SESSION_KEY_ORDER_ALARM_SHOWN, true); 264 } catch (e) { 265 // sessionStorage quota ì´ê³¼ ë± â 무ì. 1í ë ¸ì¶ ì¶ì ì´ ë¶ìì í´ì§ ë¿ ì¬ì©ì íë¦ìë ìí¥ ìì. 266 } 267 } 268 269 /** 270 * ìí ìì¸ ì¥ë°êµ¬ë ë´ê¸° ì림 모ë¬ì´ ì´ë² íì´ì§ë·°ìì ì´ë¯¸ ë ¸ì¶ëëì§ ì¬ë¶. 271 * 미리보기 모ëììë ë§¤ë² false를 ë°íí´ 1í ì íì ì°ííë
271¤. 272 * @returns {boolean} 273 */ 274 function hasAddCartAlarmShown() { 275 if (_isSalesToolFreeShipNotifyPreview) return false; 276 return _addCartAlarmShownInThisPageview; 277 } 278 279 /** 280 * ìí ìì¸ ì¥ë°êµ¬ë ë´ê¸° ì림 모ë¬ì´ ë ¸ì¶ëìì 기ë¡. AJAXë¡ ëª¨ë¬ HTMLì fetchí기 ì§ì ì í¸ì¶íë¤. 281 */ 282 function markAddCartAlarmShown() { 283 _addCartAlarmShownInThisPageview = true; 284 } 285 286 /** 287 * ì¥ë°êµ¬ë íì´ì§ 무ë£ë°°ì¡ ìë´ ë§ê·¸ë·ì 무ë£ë°°ì¡ê¹ì§ ë¨ì ê¸ì¡(remainingPrice)ì ì í íê³ 288 * wrapper(magnet-shellì parent)ì tw-hiddenì í ê¸íë¤. 289 * 290 * cart.subì ì´ê¸° ë ë ì ì¤ ë°ì´í°ê° ìì´ wrapperê° tw-hidden ìíë¡ ììíê³ , 291 * get_cart_price.cm / OMS_change_cart_item.cm ìëµì free_shipping_remaining_priceê° í¬í¨ëë©´ ì´ í¨ì를 íµí´ ë ¸ì¶ëë¤. 292 * MFEìë CustomEventë¡ ê°ì ì ë¬íì¬ ìì²´ state를 ê°±ì íëë¡ íë¤. 293 * MFEë ì´ ê°ì¼ë¡ ê²ì´ì§/ë©ìì§ë¥¼ íìíê³ , ì§íë ê³ì°ì íìí thresholdë (remainingPrice + currentTotal)ë¡ ìì°íë¤. 294 * @param {number|string|null|undefined} remainingPrice - 무ë£ë°°ì¡ê¹ì§ ë¨ì ê¸ì¡. ì í¨ ë²ì(>=0)ì¼ ëë§ ë ¸ì¶. 295 */ 296 function setCartFreeShippingRemainingPrice(remainingPrice) { 297 // TOP_FIXED ë§ê·¸ë·ê³¼ POPUP ë§ì»¤ë BO ì¤ì (shopCartStyle)ì ë°ë¼ ë 립ì ì¼ë¡ ì¡´ì¬íë¤. 298 // - TOP_FIXED 모ë: ë§ê·¸ë· wrapë§ ì¶ë ¥ (POPUP ë§ì»¤ ìì) 299 // - POPUP 모ë: POPUP ë§ì»¤ë§ ì¶ë ¥ (TOP_FIXED ë§ê·¸ë· ìì) 300 // ì´ë í ìª½ë§ ìì ë ë¤ë¥¸ 쪽 ì²ë¦¬ê° ìí¥ë°ì§ ìëë¡ ë ìì를 ë 립ì ì¼ë¡ ë¤ë£¬ë¤. 301 var magnet = document.getElementById('foFreeShipNotifyCartPageMagnet'); 302 var magnetWrap = magnet ? magnet.parentElement : null; 303 var popupMarker = document.getElementById('shop_cart_order_alarm_with_free_ship_notify'); 304 305 // ìëµ ëë½/ë¬´í¨ ê°: wrapperì POPUP ë§ì»¤ë¥¼ í¨ê» ë¹íì±íí´ ì´ì ì íê°ì´ ë¨ì§ ìê² íë¤. 306 if (remainingPrice === undefined || remainingPrice === null) { 307 if (magnetWrap) magnetWrap.classList.add('tw-hidden'); 308 if (popupMarker) popupMarker.setAttribute('data-init-deliv-price-flexable-key', '0'); 309 return; 310 } 311 // ë¬ë¬ ë± ììì íµí ì§ìì ìí´ parseFloat ì¬ì©. 312 var numericRemaining = typeof remainingPrice === 'number' ? remainingPrice : parseFloat(remainingPrice); 313 if (isNaN(numericRemaining) || numericRemaining < 0) { 314 if (magnetWrap) magnetWrap.classList.add('tw-hidden'); 315 if (popupMarker) popupMarker.setAttribute('data-init-deliv-price-flexable-key', '0'); 316 return; 317 } 318 319 if (magnetWrap) magnetWrap.classList.remove('tw-hidden'); 320 321 // POPUP ë§ì»¤ì data-init-deliv-price-flexable-key를 ì¤ ë°ì´í°ë¡ ë기í. 322 // site_shop.js:addOrderWithCartê° ë§ì»¤ê° > 0ì¼ ëë§ ëª¨ë¬ì ëì°ë¯ë¡, ì¤ ë°ì´í°ë¥¼ ë°ìí´ 323 // ì¼ë° 모ëììë ì ìì ì¼ë¡ 모ë¬ì´ ë ¸ì¶ëëë¡ íë¤. 무ë£ë°°ì¡ 충족(0)ì´ë©´ ìì°ì¤ë½ê² 모ë¬ì´ ë¨ì§ ìëë¤. 324 if (popupMarker) { 325 popupMarker.setAttribute('data-init-deliv-price-flexable-key', String(numericRemaining)); 326 } 327 328 window.dispatchEvent(new CustomEvent('imweb:freeShipNotify:cartFreeShippingRemainingPrice:update', { 329 detail: { remainingPrice: numericRemaining } 330 })); 331 } 332 333 /** 334 * ìí ìì¸ ì¸ë¼ì¸ ë§ê·¸ë·ì ë ¸ì¶ ì¬ë¶ë¥¼ íì ìµì ì í ìë£ ìíì ë°ë¼ í ê¸íë¤. 335 * shopDetailStyle === 'require_option'ì¼ë¡ ë ëë wrapperë§ ëì. site_shop.jsì 336 * updateSelectedOptionsìì ìµì ì í/í´ì ìë§ë¤ í¸ì¶íë¤. ë¤ë¥¸ ì¤íì¼ììë wrapperì 337 * data-shop-detail-styleì´ ë¤ë¥´ê±°ë wrapper ìì²´ê° ìì´ no-opë¡ ìì íê² ëìíë¤. 338 * @param {boolean} isCompleted - íì ìµì ì´ ëª¨ë ì íëìëì§ ì¬ë¶ 339 */ 340 function setRequireOptionCompleted(isCompleted) { 341 var wrap = document.querySelector('._free_ship_notify_detail_magnet_wrap[data-shop-detail-style="require_option"]'); 342 if (!wrap) return; 343 wrap.style.display = isCompleted ? '' : 'none'; 344 } 345 346 /** 347 * 무ë£ë°°ì¡ ìë´ ëª¨ë¬ ë²í¼ ë± PHPìì ë ëë ììì ê°ì¡° ììì CSS ë³ì 348 * --free-ship-notify-accent ë¡ inline 참조íë¤. PHPê° íì´ì§ ë ë ìì ì BO ì¤ì ê°ì ì¸ìë¡ ë겨 í¸ì¶íë©´ 349 * documentElementì ì¸í ë¼ AJAXë¡ ëì¤ì 주ì ëë 모ë¬ê¹ì§ 모ë cascadeë¡ ë°ëë¤. 350 * 351 * ë¹ ë¬¸ìì´ì´ ë¤ì´ì¤ë©´ ë³ì를 ì ê±°(removeProperty)íì¬ `var(--free-ship-notify-accent, ...)`ì 352 * í´ë°± ì²´ì¸(ë¸ëë ì»¬ë¬ ë±)ì´ ëìíëë¡ íë¤. ë¹ ë¬¸ìì´ë¡ setPropertyíë©´ ë¹ ê°ì´ ì ì©ëì´ 353 * í´ë°±ì´ ëìíì§ ìì¼ë¯ë¡ ëª ìì ì¼ë¡ ì ê±°íë ê²ì´ ì¤ìíë¤. 354 * @param {string} accentColor - BO ì¤ì ì accentColor. ë¹ ë¬¸ìì´ì´ë©´ ë³ì ì ê±°. 355 */ 356 function setAccentColor(accentColor) { 357 if (typeof accentColor !== 'string') return; 358 if (accentColor.length === 0) { 359 document.documentElement.style.removeProperty('--free-ship-notify-accent'); 360 return; 361 } 362 document.documentElement.style.setProperty('--free-ship-notify-accent', accentColor); 363 } 364 365 // settings:update ì´ë²¤í¸(BO sales-tool-preview ë± ëì ê°±ì )ë ê°ì ë³ì를 ë®ì´ì´ë¤. 366 window.addEventListener('imweb:freeShipNotify:settings:update', function (event) { 367 var detail = (event && event.detail) || {}; 368 _cachedFreeShipNotifySettings = Object.assign({}, _cachedFreeShipNotifySettings || {}, detail);
369 setAccentColor(detail.accentColor); 370 }); 371 372 /** 373 * MFE ì»´í¬ëí¸ë¡ ì íë ìí ìµì ì´ì¡ ì ë³´ ì ì¡ 374 * @param {number} totalPrice - ì íë ìµì ì´ ê¸ì¡ 375 */ 376 function sendSelectedOptionsUpdate(totalPrice) { 377 try { 378 const event = new CustomEvent('imweb:freeShipNotify:selectedOptions:update', { 379 detail: { 380 totalPrice: totalPrice || 0 381 } 382 }); 383 384 // ì ìì¼ë¡ ì´ë²¤í¸ ë°ì¡ 385 window.dispatchEvent(event); 386 387 } catch (error) { 388 } 389 } 390 391 /** 392 * ìí ìì¸ íì´ì§ìì ì íë ìµì ì´ì¡ ì ë°ì´í¸ ì ì¡ 393 * @param {number} total_price - ì íë ìµì ì´ ê¸ì¡ 394 */ 395 function updateSelectedOptionsTotal(total_price) { 396 sendSelectedOptionsUpdate(total_price || 0); 397 } 398 399 // load_state.cm ìëµì ë¬¶ì¬ ì¤ë BO ì ì config ì ìºì. 400 // mfe 모ë íê° ìì ì´ SDK fetch ë³´ë¤ ë¦ì ì ìì´ listener 미ë±ë¡ 구ê°ì ëë½ì ë³´ì í기 ìí¨. 401 // sharedCurrentTotal ì getCachedCartTotal í¨í´ê³¼ ëì¼. 402 var _cachedFreeShipNotifyConfig = null; 403 404 /** 405 * MFE ì»´í¬ëí¸ë¡ ìí ì¶ì² ëª©ë¡ + BO ì ì config ì ì¡. 406 * 407 * ìëµ ìì config ë detail ì sibling í¤ë¡ ë¶ë¦¬ëì´ dispatch ëë¤ (ì미ì ë³ê° ëë©ì¸). 408 * 기존 consumer ë detail.recommendations.prod_list ë§ ì½ê³ ìì´ sibling ì¶ê°ë í¸íë¨. 409 * 410 * @param {object} recommendations - { prod_list, config } shape (load_state.cm ìëµì prod_recommendation) 411 */ 412 function sendProductRecommendations(recommendations) { 413 try { 414 var payload = recommendations || {}; 415 var config = payload.config || null; 416 if (config) { 417 _cachedFreeShipNotifyConfig = config; 418 // PHP ëª¨ë¬ ë²í¼ ë± magnet-shell ë°ì DOM ì´ var(--free-ship-notify-accent, ...) ë¡ ì°¸ì¡°íë¯ë¡ 419 // ajax ìëµì¼ë¡ config ê° ë¤ì´ì¤ë©´ documentElement ì CSS ë³ìë ê°ì´ ê°±ì í´ PHP 쪽 setAccentColor í¸ì¶ ìì¡´ì ì ê±°. 420 if (typeof config.accentColor === 'string') {
421 setAccentColor(config.accentColor); 422 } 423 } 424 const event = new CustomEvent('imweb:freeShipNotify:recommendations:update', { 425 detail: { 426 recommendations: { prod_list: payload.prod_list || [] }, 427 config: config, 428 } 429 }); 430 431 // ì ìì¼ë¡ ì´ë²¤í¸ ë°ì¡ 432 window.dispatchEvent(event); 433 434 } catch (error) { 435 } 436 } 437 438 /** 439 * ì¶ì² ìí ì¹´í¸ ì¶ê° ìë£ ì í¸ â MFE ê° BrandScope click_complete_add_free_shipping_upsell ë°íì ì¬ì©. 440 * ìµì ìì / ìì, prod / cart 4 ì¼ì´ì¤ 모ë ëì¼ ì´ë²¤í¸ë¡ íµí©. 441 */ 442 function dispatchAdditionalProductAdded(prodIdx, result) { 443 try { 444 var cartCode = result && typeof result.cart_code === 'string' ? result.cart_code : ''; 445 window.dispatchEvent(new CustomEvent('imweb:freeShipNotify:additionalProductAdded', { 446 detail: { prodIdx: prodIdx, cartCode: cartCode, cart_code: cartCode } 447 })); 448 } catch (e) { 449 } 450 } 451 452 var _inlineMagnetCodeByIdx = {}; 453 454 function dispatchInlineMagnetItemCounts() { 455 if (typeof window.__imwebFreeShipInlineItemCounts !== 'object' || window.__imwebFreeShipInlineItemCounts === null) { 456 window.__imwebFreeShipInlineItemCounts = {}; 457 } 458 window.dispatchEvent(new CustomEvent('imweb:freeShipNotify:cartItems:update', { 459 detail: { counts: Object.assign({}, window.__imwebFreeShipInlineItemCounts) } 460 })); 461 } 462 463 function incrementInlineMagnetItemCount(code, idx) { 464 if (typeof code !== 'string' || code === '') return; 465 if (typeof window.__imwebFreeShipInlineItemCounts !== 'object' || window.__imwebFreeShipInlineItemCounts === null) { 466 window.__imwebFreeShipInlineItemCounts = {}; 467 } 468 window.__imwebFreeShipInlineItemCounts[code] = (window.__imwebFreeShipInlineItemCounts[code] || 0) + 1; 469 if (typeof idx === 'number' && idx > 0) { 470 _inlineMagnetCodeByIdx[idx] = code; 471 } 472 dispatchInlineMagnetItemCounts(); 473 } 474 475 function resetInlineMagnetItemCounts() { 476 window.__imwebFreeShipInlineItemCounts = {}; 477 dispatchInlineMagnetItemCounts(); 478 } 479 480 function getInlineMagnetCodeByIdx() { 481 return Object.assign({}, _inlineMagnetCodeByIdx); 482 } 483 484 function syncInlineMagnetItemCountsFromAdditionals(additionalsList) { 485 if (!Array.isArray(additionalsList)) return; 486 var nextCounts = {}; 487 for (var i = 0; i < additionalsList.length; i++) { 488 var item = additionalsList[i]; 489 if (!item || typeof item.idx !== 'number') continue;
490 var code = _inlineMagnetCodeByIdx[item.idx]; 491 if (typeof code !== 'string' || code === '') continue; 492 var count = (typeof item.count === 'number' && item.count > 0) ? item.count : 0; 493 if (count > 0) { 494 nextCounts[code] = count; 495 } 496 } 497 window.__imwebFreeShipInlineItemCounts = nextCounts; 498 dispatchInlineMagnetItemCounts(); 499 } 500 501 /** 502 * 모ë íê° ìì hydration ì© â ë§ì§ë§ì¼ë¡ ë°ì BO ì ì config ì¤ë ì·ì ëê¸°ë¡ ë°í. 503 * @returns {object|null} 504 */ 505 function getCachedFreeShipNotifyConfig() { 506 return _cachedFreeShipNotifyConfig; 507 } 508 509 function getProductRecommendationElement() { 510 return document.querySelector('fo-shopping-product-recommendation'); 511 } 512 513 function isProductRecommendationContext() { 514 return !!( 515 document.getElementById('foProductRecommendationAddCartAlertMagnet') 516 || document.getElementById('foProductRecommendationCartPageMagnet') 517 || getProductRecommendationElement() 518 ); 519 } 520 521 function getProductRecommendationContext(fallback_context) { 522 if (fallback_context === 'cart' || fallback_context === 'prod') { 523 return fallback_context; 524 } 525 526 var productRecommendationElement = getProductRecommendationElement(); 527 var productRecommendationShell = productRecommendationElement 528 ? productRecommendationElement.closest('magnet-shell') 529 : ( 530 document.getElementById('foProductRecommendationCartPageMagnet') 531 || document.getElementById('foProductRecommendationAddCartAlertMagnet') 532 ); 533 var context = productRecommendationShell ? productRecommendationShell.getAttribute('data-type') : null; 534 return context === 'cart' ? 'cart' : 'prod'; 535 } 536 537 /** 538 * MFE ì»´í¬ëí¸ë¡ ìí ìµì HTML ì ë³´ ì ì¡ 539 * @param {object} optionData - ìí ìµì HTML ë° ê´ë ¨ ì ë³´ 540 */ 541 function sendProductOptionHtml(optionData) { 542 try { 543 const event = new CustomEvent('imweb:freeShipNotify:optionHtml:update', { 544 detail: optionData || {} 545 }); 546 547 // ì ìì¼ë¡ ì´ë²¤í¸ ë°ì¡ 548 window.dispatchEvent(event); 549 550 } catch (error) { 551 } 552 } 553 554 /** 555 * 무ë£ë°°ì¡ ìë´ ìì ¯ì ì´ê¸° ìí(ì¶ì² ìí + BO ì ì config)를 í ìì²ì¼ë¡ ë¡ë. 556 * @param {number} [prod_idx] - ìí ì¸ë±ì¤. ìëµ ì cart ë§¥ë½ì¼ë¡ ê°ì£¼íì¬ ì¤ë³µ ìí ì ì¸ ìì´ ì¶ì² 목ë¡ì ë°ííë¤. 557 */ 558 function loadState(prod_idx, context, prod_code, prod_codes) { 559 var hasProdIdx = !!prod_idx && prod_idx > 0; 560 var hasProductRecommendationContext = context === 'cart' || context === 'prod'; 561 var isProductRecommendation = hasProductRecommendationContext && isProductRecommendationContext(); 562 var url = isProductRecommendation 563 ? '/shop/product_recommendation/load_state.cm' 564 : '/shop/free_ship_notify/load_state.cm'; 565 var requestData = hasProdIdx ? {'prod_idx': prod_idx} : {}; 566 567 if (isProductRecommendation) { 568 requestData.context = getProductRecommendationContext(context); 569 if (typeof prod_code === 'string' && prod_code !== '') { 570 requestData.prod_code = prod_code; 571 } 572 if (Array.isArray(prod_codes) && prod_codes.length > 0) { 573 requestData.prod_codes = prod_codes; 574 } 575 } 576 577 $.ajax({ 578 type: 'POST', 579 // prod_idxë íì¬ ì¶í ì¤ë³µ ìí ì ì¸ ì©ëë¡ë§ ì¬ì©ëë¯ë¡ ì í¨í ëë§ ì ì¡ 580 data: requestData, 581 url: url, 582 dataType: 'json', 583 cache: false, 584 success: function(result) { 585 586 if (result.msg === 'SUCCESS') { 587 588 // MFE ì»´í¬ëí¸ë¡ ë°ì´í° ì ì¡ (prod_list + config 묶ì) 589 sendProductRecommendations(result.prod_recommendation); 590 } 591 }, 592 error: function(xhr, status, error) { 593 } 594 }); 595 } 596 597 /** 598 * BO 미리보기 ì ì© â ìí ì½ë ë°°ì´ì ë°ì í´ë¹ ìíë¤ì full ë°ì´í° + config 를 fetch. 599 * ì ì¥ë config ì 무ê´íê² í¸ì§ ì¤ì¸ ì í ìí를 ì¦ì 미리보기ì ë°ìí기 ìí ê²½ë¡. 600 * ìëµ ëª¨ìì load_state.cm ê³¼ ëì¼ (prod_recommendation: { prod_list, config }). 601 * í¸ì§ ì¤ì¸ settings ë ë³ë postMessage â settings ì¤í ì´ê° ajax config 를 ì°ì ë®ì´ì´ë¤. 602 * @param {string[]} prod_codes - 미리보기ì ë ¸ì¶í ìí ì½ë 목ë¡. 603 */ 604 function loadStateByCodes(prod_codes) { 605 if (!Array.isArray(prod_codes) || prod_codes.length === 0) { 606 sendProductRecommendations({ prod_list: [] }); 607 return; 608 } 609 610 $.ajax({ 611 type: 'POST', 612 data: { 'prod_codes': prod_codes }, 613 // jQuery ê° prod_codes[]=... ííë¡ ì§ë ¬ííëë¡ traditional: false (
613default) ì ì§. 614 url: '/shop/free_ship_notify/load_state_by_codes.cm', 615 dataType: 'json', 616 cache: false, 617 success: function(result) { 618 619 if (result.msg === 'SUCCESS') { 620 sendProductRecommendations(result.prod_recommendation); 621 } 622 }, 623 error: function(xhr, status, error) { 624 } 625 }); 626 } 627 628 /** 629 * ìí ì¸ë±ì¤ë¥¼ íµí´ ì¶ê° ìí ì í 630 * @param {number} product_idx - ìí ì¸ë±ì¤ 631 * @param {'prod'|'cart'} context - í¸ì¶ ë§¥ë½. 'prod'(ìí ìì¸)ì SITE_SHOP_DETAIL, 'cart'(ì¥ë°êµ¬ë)ë SITE_SHOP_CART ê²½ë¡ë¡ ë¶ê¸°íë¤. 632 * @param {function} callback - ìë£ ì½ë°± í¨ì (ì íì¬í) 633 */ 634 function selectAdditionalProductByIdx(product_idx, context, callback) { 635 if (!product_idx || product_idx <= 0) { 636 if (callback) callback(false, getLocalizeString('ì¤ëª _ì¤ë¥ê°ë°ìíìµëë¤', '', 'ì¤ë¥ê° ë°ìíìµëë¤.')); 637 return; 638 } 639 640 // 미ì§ì /미ì§ì ê°ì¸ ê²½ì° ê¸°ì¡´ ëì í¸íì ìí´ 'prod'ë¡ fallback 641 if (context !== 'prod' && context !== 'cart') { 642 context = 'prod'; 643 } 644 645 // contextë³ë¡ íìí ì ì ê°ì²´ê° ë¡ëëì´ ìëì§ íì¸ 646 if (context === 'prod') { 647 if (typeof window.SITE_SHOP_DETAIL === 'undefined' || typeof window.SITE_SHOP_DETAIL.selectAdditionalProduct !== 'function') { 648 if (callback) callback(false, getLocalizeString('ì¤ëª _ì¤ë¥ê°ë°ìíìµëë¤', '', 'ì¤ë¥ê° ë°ìíìµëë¤.')); 649 return; 650 } 651 } else {
652 // cart ê²½ë¡ë SITE_SHOP_CARTì ëì í¨ìê° ì¶ê°ë ì´íì ëìíë¤. 653 if (typeof window.SITE_SHOP_CART === 'undefined') { 654 if (callback) callback(false, getLocalizeString('ì¤ëª _ì¤ë¥ê°ë°ìíìµëë¤', '', 'ì¤ë¥ê° ë°ìíìµëë¤.')); 655 return; 656 } 657 } 658 659 // ìí ì ë³´ ì¡°í Ajax í¸ì¶ 660 $.ajax({ 661 type: 'POST', 662 data: {'product_idx': product_idx}, 663 url: '/shop/free_ship_notify/get_additional_product_info.cm', 664 dataType: 'json', 665 cache: false, 666 success: function(result) { 667 668 if (result.msg === 'SUCCESS' && result.product_info) { 669 const info = result.product_info; 670 671 if (typeof info.code === 'string' && info.code !== '' 672 && typeof info.product_idx === 'number' && info.product_idx > 0) { 673 _inlineMagnetCodeByIdx[info.product_idx] = info.code; 674 } 675 676 try { 677 if (info.has_required_options) { 678 // íì ìµì ì´ ìë ê²½ì° getProductOptionHtml í¸ì¶íì¬ ëª¨ë¬ íì 679 getProductOptionHtml(product_idx, info, context, callback); 680 } else if (context === 'cart') { 681 // cart ë§¥ë½: íì ìµì ì´ ìì¼ë¯ë¡ ì¹´í¸ì ì¦ì ë´ê¸° 682 if (typeof window.SITE_SHOP_CART.addCart !== 'function') { 683 if (callback) callback(false, getLocalizeString('ì¤ëª _ì¤ë¥ê°ë°ìíìµëë¤', '', 'ì¤ë¥ê° ë°ìíìµëë¤.')); 684 return; 685 } 686 var addCartRequestOptions = { 687 shipping_template_code: info.shipping_template_code || '' 688 }; 689 if (info.is_regularly_prod === true || info.is_regularly_prod === 'Y' || info.only_regularly === true || info.only_regularly === 'Y') { 690 addCartRequestOptions.cart_type = 'regularly'; 691 } 692 window.SITE_SHOP_CART.addCart(info.product_idx, [], 1, function(success, message, addCartResult) { 693 if (success) { 694 dispatchAdditionalProductAdded(product_idx, addCartResult); 695 if (callback) callback(true, 'ì¹´í¸ ë´ê¸°ê° ìë£ëììµëë¤.', addCartResult); 696 } else { 697 if (callback) callback(false, message || getLocalizeString('ì¤ëª _ì¤ë¥ê°ë°ìíìµëë¤', '', 'ì¤ë¥ê° ë°ìíìµëë¤.')); 698 } 699 }, addCartRequestOptions); 700 } else { 701 // prod ë§¥ë½: íì ìµì ì´ ìë ê²½ì° ì§ì selectAdditionalProduct í¸ì¶ 702 if (typeof window.SITE_SHOP_DETAIL.setFreeShipNotifyProdAdditionalRegularPrice === 'function') { 703 window.SITE_SHOP_DETAIL.setFreeShipNotifyProdAdditionalRegularPrice(info.product_idx, info.regular_price || info.price || 0); 704 } 705 window.SITE_SHOP_DETAIL.selectAdditionalProduct( 706 info.product_idx, 707 info.price, 708 info.name, 709 info.maximum_purchase_quantity, 710 info.member_maximum_purchase_quantity, 711 info.maximum_purchase_quantity_type, 712 info.optional_limit, 713 info.optional_limit_type, 714 info.stock_use, 715 info.stock, 716 info.stock_unlimit, 717 info.option_mix_type, 718 info.prod_type,
719 info.period_discount_flag, 720 info.period_discount_data, 721 info.period_discout_group_list, 722 info.membership_discount, 723 info.additional_creator_discount_data || null, 724 true 725 ); 726 727 incrementInlineMagnetItemCount(info.code, info.product_idx); 728 729 dispatchAdditionalProductAdded(product_idx); 730 if (callback) callback(true, 'ì¶ê° ìí ì íì´ ìë£ëììµëë¤.'); 731 } 732 733 } catch (error) { 734 if (callback) callback(false, getLocalizeString('ì¤ëª _ì¤ë¥ê°ë°ìíìµëë¤', '', 'ì¤ë¥ê° ë°ìíìµëë¤.')); 735 } 736 } else { 737 alert(getLocalizeString('ì¤ëª _ì¤ë¥ê°ë°ìíìµëë¤', '', 'ì¤ë¥ê° ë°ìíìµëë¤.')); 738 if (callback) callback(false, result.error_msg || getLocalizeString('ì¤ëª _ì¤ë¥ê°ë°ìíìµëë¤', '', 'ì¤ë¥ê° ë°ìíìµëë¤.')); 739 } 740 }, 741 error: function(xhr, status, error) { 742 alert(getLocalizeString('ì¤ëª _ì¤ë¥ê°ë°ìíìµëë¤', '', 'ì¤ë¥ê° ë°ìíìµëë¤.')); 743 if (callback) callback(false, getLocalizeString('ì¤ëª _ì¤ë¥ê°ë°ìíìµëë¤', '', 'ì¤ë¥ê° ë°ìíìµëë¤.')); 744 } 745 }); 746 } 747 748 /** 749 * ìí ìµì HTMLì ê°ì ¸ìì MFE 모ë¬ì ì ì¡ 750 * @param {number} product_idx - ìí ì¸ë±ì¤ 751 * @param {object} product_info - ìí ì ë³´ 752 * @param {'prod'|'cart'} context - í¸ì¶ ë§¥ë½ 753 * @param {function} callback - ìë£ ì½ë°± í¨ì (ì íì¬í) 754 */ 755 function getProductOptionHtml(product_idx, product_info, context, callback) { 756 if (!product_idx || product_idx <= 0) { 757 if (callback) callback(false, getLocalizeString('ì¤ëª _ì¤ë¥ê°ë°ìíìµëë¤', '', 'ì¤ë¥ê° ë°ìíìµëë¤.')); 758 return; 759 } 760 761 // 미ì§ì /미ì§ì ê°ì¸ ê²½ì° ê¸°ì¡´ ëì í¸íì ìí´ 'prod'ë¡ fallback 762 if (context !== 'prod' && context !== 'cart') { 763 context = 'prod'; 764 } 765 766 // 1ë¨ê³: 기본 ëª¨ë¬ HTML 구조 ê°ì ¸ì¤ê¸° 767 $.ajax({ 768 type: 'POST', 769 data: { 770 'prod_idx': product_idx, 771 'product_name': product_info.name, 772 'product_price_text': product_info.price_text, 773 'product_thumb_url': product_info.thumb_url 774 }, 775 url: '/shop/free_ship_notify/get_product_option_modal.cm', 776 dataType: 'html', 777 cache: false, 778 success: function(modalHtml) { 779 780 // 2ë¨ê³: ìµì HTML ê°ì ¸ì¤ê¸° (context를 ì ë¬íì¬ cart 컨í ì¤í¸ììë cart í¸ë¤ë¬ê° emit ëëë¡ íë¤) 781 $.ajax({ 782 type: 'POST', 783 data: { 784 'prod_idx': product_idx, 785 'selected_require_options': [], 786 '__': '', 787 'is_additional': true, 788 'context': context 789 }, 790 url: '/shop/load_prod_additional_option.cm', 791 dataType: 'json', 792 cache: false, 793 success: function(optionResult) { 794 795 if (optionResult.msg === 'SUCCESS') { 796 if (typeof SITE_SHOP_DETAIL !== 'undefined' && typeof SITE_SHOP_DETAIL.setProdAdditionalRequireOptionCount === 'function') { 797 SITE_SHOP_DETAIL.setProdAdditionalRequireOptionCount( 798 optionResult.require_option_count, 799 optionResult.require_input_option_count 800 ); 801 } 802 803 // ëª¨ë¬ HTMLì ìµì HTML ì½ì 804 var finalHtml = insertOptionHtml(modalHtml, optionResult.option_html); 805 806 // cocoaDialogë¡ ëª¨ë¬ íì (cart 컨í ì¤í¸ììë initDetail ë±ì ë©íë°ì´í°ë¥¼ ì ë¬) 807 showProductOptionModal(finalHtml, product_idx, product_info, context, optionResult, callback); 808 } else { 809 if (callback) callback(false, getLocalizeString('ì¤ëª _ì¤ë¥ê°ë°ìíìµëë¤', '', 'ì¤ë¥ê° ë°ìíìµëë¤.')); 810 } 811 }, 812 error: function(xhr, status, error) { 813 if (callback) callback(false, getLocalizeString('ì¤ëª _ì¤ë¥ê°ë°ìíìµëë¤', '', 'ì¤ë¥ê° ë°ìíìµëë¤.')); 814 } 815 }); 816 }, 817 error: function(xhr, status, error) { 818 if (callback) callback(false, getLocalizeString('ì¤ëª _ì¤ë¥ê°ë°ìíìµëë¤', '', 'ì¤ë¥ê° ë°ìíìµëë¤.')); 819 } 820 }); 821 } 822 823 /** 824 * ëª¨ë¬ HTMLì ìµì HTMLì ì½ì 825 * @param {string} modalHtml - 기본 ëª¨ë¬ HTML 826 * @param {string} optionHtml - ìµì HTML 827 * @returns {string} ìì±ë HTML 828 */ 829 function insertOptionHtml(modalHtml, optionHtml) { 830 // ìì divì modalHtmlì ë¡ëí´ì DOM ì¡°ì 831 var tempDiv = document.createElement('div'); 832 tempDiv.innerHTML = modalHtml; 833 834 // #prod_free_ship_notify_additional_options를 ì°¾ìì innerHTML ì¤ì 835 var optionContainer = tempDiv.querySelector('#prod_free_ship_notify_additional_options'); 836 if (optionContainer) { 837 optionContainer.innerHTML = optionHtml; 838 } 839 840 return tempDiv.innerHTML; 841 } 842 843 // 모ë¬ì ëì´ ë§ì§ë§ ë§¥ë½. ëª¨ë¬ HTMLì submit ë²í¼ì´ completeAdditionalProductSelection()ì ì¸ì ìì´ í¸ì¶íë¯ë¡ 844 // ì´ë ë§¥ë½ìì 모ë¬ì´ ë´ëì§ ê¸°ìµí´ëë¤. 845 var currentSelectionContext = 'prod'; 846 // cart ë§¥ë½ìì submit ì ì´ë ìíì ì¹´í¸ì ë´ìì§ ê¸°ìµ (SITE_SHOP_DETAIL.initDetailì ë긴 prod_idx) 847 var currentSelectionProductIdx = 0; 848 // prod ë§¥ë½ completeAdditionalProductSelection ìì cartItems:update dispatch ì© prod_code ì¶ì 849 var currentSelectionProductCode = ''; 850 var currentSelectionShippingTemplateCode = ''; 851 var currentSelectionCartType = ''; 852 // íì¬ íì± ëª¨ë¬ì cleanup/resolve í¸ë¤. ê° showProductOptionModal í¸ì¶ë§ë¤ closureë¡ ìì±ëì´ 853 // ìì ì product_idxì snapshotì 묶ì¸ë¤. complete/cancel/implicit closeê° ì´ í¸ë¤ì íµí´ 854 // ì íí ëª¨ë¬ ì¸ì¤í´ì¤ì ëí´ìë§ ëìíëë¡ ë³´ì¥. 855 var _currentModalCleanup = null; // ëª ìì cancel / ììì closeìì í¸ì¶ â snapshotì¼ë¡ restore
856 var _currentModalMarkResolved = null; // ëª ìì completeìì í¸ì¶ â íì implicit cleanup ì°¨ë¨ 857 858 /** 859 * SITE_SHOP_DETAILì ìµì ê´ë¦¬ 기ê³ë¥¼ cart ë§¥ë½ìì ì´ê¸°ííë¤. 860 * showChangeCartItemê³¼ ëì¼í í¨í´ - load_prod_additional_option.cm ìëµ ë©íë°ì´í°ë¥¼ ê·¸ëë¡ ì¬ì©. 861 * @param {object} optionResult load_prod_additional_option.cm ìëµ 862 */ 863 function initDetailForCartContext(optionResult) { 864 if (typeof SITE_SHOP_DETAIL === 'undefined') { 865 return; 866 } 867 868 if (window.innerWidth < 768 869 && typeof SITE_SHOP_DETAIL.resetSelectedRequireOptions === 'function') { 870 SITE_SHOP_DETAIL.resetSelectedRequireOptions(); 871 } 872 873 if (typeof SITE_SHOP_DETAIL.initDetail === 'function') { 874 SITE_SHOP_DETAIL.initDetail({ 875 prod_idx: optionResult.prod_idx, 876 prod_price: optionResult.prod_price, 877 require_option_count: optionResult.require_option_count_total || 0, 878 use_image_optimizer_on_product_detail_markup: false, 879 shop_use_full_load: false 880 }); 881 } 882 883 if (typeof SITE_SHOP_DETAIL.initProdStock === 'function' && optionResult.prod_stock) { 884 SITE_SHOP_DETAIL.initProdStock( 885 optionResult.prod_stock.stock_use, 886 optionResult.prod_stock.stock_no_option, 887 optionResult.prod_stock.stock_unlimit 888 ); 889 } 890 891 if (typeof SITE_SHOP_DETAIL.setMaxPurchaseQuantity === 'function' && optionResult.max_prod_quantity !== undefined) { 892 SITE_SHOP_DETAIL.setMaxPurchaseQuantity( 893 optionResult.max_prod_quantity, 894 optionResult.max_member_quantity, 895 optionResult.maximum_purchase_quantity_type, 896 optionResult.optional_limit, 897 optionResult.optional_limit_type, 898 optionResult.prod_name 899 ); 900 } 901 902 } 903 904 /** 905 * cocoaDialogë¡ ìí ìµì ëª¨ë¬ íì 906 * @param {string} html - ìì±ë ëª¨ë¬ HTML 907 * @param {number} product_idx - ìí ì¸ë±ì¤ 908 * @param {object} product_info - ìí ì ë³´ (get_additional_product_info.cm ìëµ) 909 * @param {'prod'|'cart'} context - í¸ì¶ ë§¥ë½ 910 * @param {object} optionResult - load_prod_additional_option.cm ìëµ (cart 컨í ì¤í¸ ì´ê¸°íì© ë©íë°ì´í° í¬í¨) 911 * @param {function} callback - ìë£ ì½ë°± í¨ì 912 */ 913 function showProductOptionModal(html, product_idx, product_info, context, optionResult, callback) { 914 try { 915 // ì´ ëª¨ë¬ ì¸ì¤í´ì¤ ì ì© closure ë³ìë¤. ì 모ë¬ë§ë¤ ë 립 ìì±ëì´ hide_event/backdrop clickì´ 916 // ìì ì product_idxì ì§ì ìì snapshotìë§ ì ì©ëëë¡ ê²©ë¦¬íë¤. 917 var modalContext = (context === 'cart') ? 'cart' : 'prod'; 918 var modalProductIdx = product_idx; 919 var modalResolved = false; 920 // prod ë§¥ë½ììë§ ì§ì ì§ì ìí snapshotì ë°ìë . cart ë§¥ë½ì ì¹´í¸ë¡ ì§ì ë´ë íë¦ì´ë¼ ë¶íì. 921 var modalSnapshot = null; 922 if (modalContext === 'prod' 923 && typeof window.SITE_SHOP_DETAIL !== 'undefined' 924 && typeof window.SITE_SHOP_DETAIL.snapshotProdAdditionalForModal === 'function') { 925 modalSnapshot = window.SITE_SHOP_DETAIL.snapshotProdAdditionalForModal(modalProductIdx); 926 } 927 928 currentSelectionContext = modalContext; 929 currentSelectionProductIdx = modalProductIdx; 930 currentSelectionProductCode = (product_info && typeof product_info.code === 'string') ? product_info.code : ''; 931 currentSelectionShippingTemplateCode = (product_info && typeof product_info.shipping_template_code === 'string') ? product_info.shipping_template_code : ''; 932 currentSelectionCartType = (product_info && ( 933 product_info.is_regularly_prod === true || 934 product_info.is_regularly_prod === 'Y' || 935 product_info.only_regularly === true || 936 product_info.only_regularly === 'Y' 937 )) ? 'regularly' : ''; 938 939 // íì¬ ëª¨ë¬ì cleanup í¸ë¤ â snapshot ê¸°ë° restore. ì§ì ì§ì ìíë¡ ëëë ¤ 940 // "ì´ë² 모ë¬ì´ ì¶ê°í ë§í¼ë§" revert (기존ì ë´ê²¨ìë ìµì /í목ì ë³´ì¡´). 941 var cleanupForThisModal = function () { 942 if (modalResolved) return; 943 modalResolved = true; 944 if (modalContext === 'prod' && modalProductIdx > 0 945 && modalSnapshot 946 && typeof window.SITE_SHOP_DETAIL !== 'undefined' 947 && typeof window.SITE_SHOP_DETAIL.restoreProdAdditionalForModal === 'function') { 948 window.SITE_SHOP_DETAIL.restoreProdAdditionalForModal(modalProductIdx, modalSnapshot); 949 } 950 if (modalProductIdx === currentSelectionProductIdx) { 951 currentSelectionProductIdx = 0; 952 } 953 }; 954 // ëª ìì completeìì í¸ì¶ â restore ìì´ resolvedë§ íìí´ íì implicit cleanup ì°¨ë¨. 955 var markResolvedForThisModal = function () { 956 modalResolved = true; 957 }; 958 _currentModalCleanup = cleanupForThisModal;
959 _currentModalMarkResolved = markResolvedForThisModal; 960 961 // prod ë§¥ë½ììë§ SITE_SHOP_DETAILì ì¶ê°ìí ëª¨ë¬ ìí ì´ê¸°í ìí. 962 // cart ë§¥ë½ì "ì¶ê°ìí ì í" ê°ë ìì´ ë°ë¡ ì¹´í¸ì ë´ì¼ë¯ë¡ ë¤ë¥¸ ì´ê¸°í(initDetailForCartContext)를 ì¬ì©íë¤. 963 if (currentSelectionContext === 'prod' 964 && typeof SITE_SHOP_DETAIL !== 'undefined' 965 && typeof SITE_SHOP_DETAIL.selectAdditionalProductForModal === 'function') { 966 if (typeof SITE_SHOP_DETAIL.setFreeShipNotifyProdAdditionalRegularPrice === 'function') { 967 SITE_SHOP_DETAIL.setFreeShipNotifyProdAdditionalRegularPrice(product_idx, product_info.regular_price || product_info.price || 0); 968 } 969 SITE_SHOP_DETAIL.selectAdditionalProductForModal( 970 product_idx, 971 product_info.price || 0, 972 product_info.name || '', 973 product_info.maximum_purchase_quantity || 0, 974 product_info.member_maximum_purchase_quantity || 0, 975 product_info.maximum_purchase_quantity_type || '', 976 product_info.optional_limit || 0, 977 product_info.optional_limit_type || '', 978 product_info.stock_use || 0, 979 product_info.stock || 0, 980 product_info.stock_unlimit || 0, 981 product_info.option_mix_type || '', 982 product_info.prod_type || '', 983 product_info.period_discount_flag || 0, 984 product_info.period_discount_data || {}, 985 product_info.period_discout_group_list || [], 986 product_info.membership_discount || 0, 987 product_info.additional_creator_discount_data || null 988 ); 989 } 990 991 var $staleOptionModal = $('.modal_site_shop_free_ship_notify_option.in'); 992 if ($staleOptionModal.length > 0) { 993 $staleOptionModal.modal('hide'); 994 } 995 996 var is_mobile_width = (window.innerWidth < 768); 997 if(is_mobile_width){ 998 // ì¶ê° ìí ìí¸ì ìí ì ê³µì íë¯ë¡ ID를 ê°ì´ ì¬ì© 999 imSheet.close('prod_additional_sheet', () => { 1000 imSheet.open({ 1001 id: 'prod_additional_sheet', 1002 html: html, 1003 backdrop: 'rgba(0, 0, 0, 0.15)', 1004 zIndex: 17001, 1005 onShow: function() { 1006 // cart 컨í ì¤í¸ë 모ë¬ì´ DOMì ë¤ì´ê° ë¤ SITE_SHOP_DETAIL ì´ê¸°í 1007 // (initDetailì´ ëª¨ë¬ ìì #prod_options ë±ì ì°¾ìì¼ íë¯ë¡ mount ì´íì í¸ì¶) 1008 if (currentSelectionContext === 'cart') { 1009 initDetailForCartContext(optionResult); 1010 } 1011 } 1012 }); 1013 1014 // backdrop ìì í´ë¦ì¼ë¡ ë«ì ëë cleanupì´ ëìíëë¡ ì¶ê° click í¸ë¤ë¬ ë±ë¡. 1015 // closureë¡ ìº¡ì³ë cleanupForThisModalì ì§ì í¸ì¶ â ìì ì product_idxì snapshot 기ì¤ì¼ë¡ ìì íê² restore. 1016 $('#prod_additional_sheet').on('click', function(e) { 1017 if ($(e.target).parents('.im-sheet-content').length === 0) { 1018 cleanupForThisModal(); 1019 } 1020 }); 1021 1022 // MFE ì¶ì² ììì ë´ê¸° ë²í¼ ë¡ë© í´ì ê° ì´ ì½ë°±ì ê±¸ë ¤ ìì¼ë¯ë¡ PC ë¶ê¸°ì ëì¼íê² í¸ì¶ 1023 if (callback) callback(true, 'ìí ìµì 모ë¬ì íìíìµëë¤.'); 1024 }); 1025 }else{ 1026 $.cocoaDialog.open({ 1027 type: 'site_shop_free_ship_notify_option', 1028 custom_popup: html, 1029 pc_width: 440, 1030 // ì¸ë¶ í´ë¦/ESC ë±ì¼ë¡ cocoaDialogê° ë«í ëë cleanupì´ ëìíëë¡ hide_event ë±ë¡. 1031 // closureë¡ ìº¡ì³ë cleanupForThisModal â ìì ì product_idxì snapshot 기ì¤ì¼ë¡ ìì íê² restore. 1032 // ëª ìì complete/cancelì modalResolved=trueë¡ íìíë¯ë¡ ì¤ë³µ cleanup ì ë¨. 1033 hide_event: cleanupForThisModal 1034 }); 1035 1036 // PC 모ë¬ì ë기 mountì´ë¯ë¡ ë°ë¡ ì´ê¸°í 1037 if (currentSelectionContext === 'cart') { 1038 initDetailForCartContext(optionResult); 1039 } 1040 1041 if (callback) callback(true, 'ìí ìµì 모ë¬ì íìíìµëë¤.'); 1042 } 1043 } catch (error) { 1044 if (callback) callback(false, getLocalizeString('ì¤ëª _ì¤ë¥ê°ë°ìíìµëë¤', '', 'ì¤ë¥ê° ë°ìíìµëë¤.')); 1045 } 1046 } 1047 1048 /** 1049 * ì¶ê° ìí ì í ì·¨ì ì²ë¦¬ ë° ëª¨ë¬ ë«ê¸°. 1050 * ëª¨ë¬ HTMLì ì·¨ì ë²í¼/X ë²í¼ìì í¸ì¶. prod ë§¥ë½ì selectAdditionalProductForModalì´ 1051 * ëª¨ë¬ ë ¸ì¶ ìì ì ì´ë¯¸ selected_prod_additionalsì pushíì¼ë¯ë¡ ëª ìì cleanupì´ íìíë¤. 1052 * cart ë§¥ë½ì ë¤ì 모ë¬ì´ ì´ë¦´ ë initDetailì´ ëª¨ë ìí를 resetíë¯ë¡ ë³ë cleanup ë¶íì. 1053 */ 1054 function cancelAdditionalProductSelection() { 1055 // íì¬ íì± ëª¨ë¬ì cleanup í¸ì¶ â snapshot ê¸°ë° restoreë¡ ì§ì ì§ì ìíë¡ ë³µ
1055ì. 1056 // ì´ í¸ì¶ì´ modalResolved=trueë¡ íìíë¯ë¡ íì hide_event / backdrop clickì´ ì¤ë³µ cleanupíì§ ìëë¤. 1057 if (typeof _currentModalCleanup === 'function') { 1058 _currentModalCleanup(); 1059 } 1060 1061 var is_mobile_width = (window.innerWidth < 768); 1062 if (is_mobile_width) { 1063 if (typeof imSheet !== 'undefined' && typeof imSheet.close === 'function') { 1064 imSheet.close('prod_additional_sheet'); 1065 } 1066 } else if (typeof $ !== 'undefined' && typeof $.cocoaDialog === 'object' && typeof $.cocoaDialog.close === 'function') { 1067 var $optionModal = $('.modal_site_shop_free_ship_notify_option.in'); 1068 if ($optionModal.length > 0) { 1069 $optionModal.modal('hide'); 1070 } else { 1071 $.cocoaDialog.close(); 1072 } 1073 } 1074 } 1075 1076 /** 1077 * ì¶ê° ìí ì í ìë£ ì²ë¦¬ ë° ëª¨ë¬ ë«ê¸°. 1078 * ëª¨ë¬ HTMLì submit ë²í¼ìì í¸ì¶ëë©° ì¸ì를 ë°ì§ ìëë¤. ì§ì showProductOptionModalìì ì ì¥í 1079 * currentSelectionContext를 ì½ì´ contextë³ë¡ ë¶ê¸°íë¤. 1080 */ 1081 function completeAdditionalProductSelection() { 1082 try { 1083 // ì ì ìë£ íë¦ íì. íì hide_event / backdrop clickì´ snapshot 기ì¤ì¼ë¡ ëëë¦¬ì§ ìëë¡ resolved íëê·¸ë§ set. 1084 if (typeof _currentModalMarkResolved === 'function') { 1085 _currentModalMarkResolved(); 1086 } 1087 if (currentSelectionContext === 'cart') { 1088 // cart ë§¥ë½: 무ë£ë°°ì¡ 모ë¬ììë selectRequireOptionì´ selectOptionì í¸ì¶íì§ ìê³ ì í ìíë§ ì ì§íë¯ë¡ 1089 // (selectProdAdditionalRequireOption í¨í´ê³¼ ëì¼) ì¬ê¸°ì selected_require_options를 ì§ì ì½ì´ addCart í¬ë§·ì¼ë¡ ë³ííë¤. 1090 if (typeof window.SITE_SHOP_CART === 'undefined' || typeof window.SITE_SHOP_CART.addCart !== 'function') { 1091 return; 1092 } 1093 if (typeof SITE_SHOP_DETAIL === 'undefined' || typeof SITE_SHOP_DETAIL.getSelectedRequireOptions !== 'function') { 1094 return; 1095 } 1096 1097 var requireOptions = SITE_SHOP_DETAIL.getSelectedRequireOptions(); 1098 var requireCount = (typeof SITE_SHOP_DETAIL.getRequireOptionCount === 'function') 1099 ? (SITE_SHOP_DETAIL.getRequireOptionCount() || 0) 1100 : 0; 1101 if (!requireOptions || requireOptions.length < requireCount) { 1102 alert(typeof LOCALIZE !== 'undefined' && typeof LOCALIZE.ì¤ëª _íììµì ì´ëª¨ëì íëì´ìì§ììµëë¤ === 'function' 1103 ? LOCALIZE.ì¤ëª _íììµì ì´ëª¨ëì íëì´ìì§ììµëë¤() 1104 : 'íì ìµì ì 모ë ì íí´ì£¼ì¸ì.'); 1105 return; 1106 } 1107 1108 var prodIdx = currentSelectionProductIdx; 1109 1110 $.ajax({ 1111 type: 'POST', 1112 url: '/shop/select_option.cm', 1113 data: { 1114 'prod_idx': prodIdx, 1115 'count': 1, 1116 'require': 'Y', 1117 'options': requireOptions 1118 }, 1119 dataType: 'json', 1120 cache: false, 1121 success: function (selectOptionResult) { 1122 if (!selectOptionResult || selectOptionResult.msg !== 'SUCCESS') { 1123 alert((selectOptionResult && selectOptionResult.msg) || getLocalizeString('ì¤ëª _ì¤ë¥ê°ë°ìíìµëë¤', '', 'ì¤ë¥ê° ë°ìíìµëë¤.')); 1124 return; 1125 } 1126 1127 var optionPrice = (selectOptionResult.selected_option && typeof selectOptionResult.selected_option.price === 'number') 1128 ? selectOptionResult.selected_option.price 1129 : 0; 1130 1131 // add_cart.cmì´ ê¸°ëíë í¬ë§·: [{ options, require, count, price }] 1132 var addCartPayload = [{ 1133 options: requireOptions, 1134 require: true, 1135 count: 1, 1136 price: optionPrice 1137 }]; 1138 1139 window.SITE_SHOP_CART.addCart(prodIdx, addCartPayload, 1, function(success, message, addCartResult) { 1140 if (success) { 1141 dispatchAdditionalProductAdded(prodIdx, addCartResult); 1142 var is_mobile_width = (window.innerWidth < 768); 1143 if (is_mobile_width) { 1144 if (typeof SITE_SHOP_DETAIL !== 'undefined' 1145 && typeof SITE_SHOP_DETAIL.resetSelectedRequireOptions === 'function') { 1146 SITE_SHOP_DETAIL.resetSelectedRequireOptions(); 1147 } 1148 currentSelectionProductIdx = 0; 1149 currentSelectionContext = 'prod'; 1150 imSheet.close('prod_additional_sheet'); 1151 } else { 1152 $('.modal_site_shop_free_ship_notify_option.in').modal('hide'); 1153 } 1154 } else { 1155 alert(message || getLocalizeString('ì¤ëª _ì¤ë¥ê°ë°ìíìµëë¤', '', 'ì¤ë¥ê° ë°ìíìµëë¤.')); 1156 } 1157 }, { 1158 shipping_template_code: currentSelectionShippingTemplateCode, 1159 cart_type: currentSelectionCartType 1160 }); 1161 }, 1162 error: function () { 1163 alert(getLocalizeString('ì¤ëª _ì¤ë¥ê°ë°ìíìµëë¤', '', 'ì¤ë¥ê° ë°ìíìµëë¤.')); 1164 } 1165 }); 1166 return; 1167 } 1168 1169 if (typeof window.SITE_SHOP_DETAIL === 'undefined') { 1170 return; 1171 } 1172 1173 // SITE_SHOP_DETAILì completeAdditionalProductSelection í¨ì í¸ì¶ 1174 if (typeof window.SITE_SHOP_DETAIL.completeAdditionalProductSelection === 'function') { 1175 window.SITE_SHOP_DETAIL.completeAdditionalProductSelection(); 1176 dispatchAdditionalProductAdded(currentSelectionProductIdx); 1177 } 1178 1179 } catch (error) { 1180 } 1181 } 1182 1183 // 모ë¬ì close/continue ë²í¼ í¸ëí¹ â MFE ê° modal placement ë§ì´í¸ ì setCloseTracker ë¡ 1184 // ë¹ë기 í¸ë¤ë¬ë¥¼ ë±ë¡. PHP ì close ë²í¼ onclick ì´ trackCloseAndContinue(afterAction) í¸ì¶ ì 1185 // í¸ë¤ë¬ë¥¼ ìµë 500ms 기ë¤ë¦° í afterAction ì ì¤í (íì´ì§ ì´ë race ìµìí). 1186 var _closeTracker = null; 1187 1188 function setCloseTracker(tracker) { 1189 _closeTracker = typeof tracker === 'function' ? tracker : null; 1190 } 1191 1192 function trackCloseAndContinue(afterAction) { 1193 var done = false;
1194 function runAfter() { 1195 if (done) return; 1196 done = true; 1197 if (typeof afterAction !== 'function') return; 1198 try { 1199 afterAction(); 1200 } catch (e) { 1201 // afterAction throw ê° Promise unhandled rejection ì¼ë¡ 묶ì´ì§ ìëë¡ ë§ì´í¬ë¡íì¤í¬ ë°ì¼ë¡ ì¬ëì§. 1202 // 기존 ë기 onclick ëìê³¼ ëë±í ìë¬ surface ì ì§ (window.onerror ì¡í). 1203 setTimeout(function () { throw e; }, 0); 1204 } 1205 } 1206 1207 if (typeof _closeTracker !== 'function') { 1208 runAfter(); 1209 return Promise.resolve(); 1210 } 1211 1212 var trackerPromise; 1213 try { 1214 trackerPromise = _closeTracker(); 1215 } catch (e) { 1216 runAfter(); 1217 return Promise.resolve(); 1218 } 1219 if (!trackerPromise || typeof trackerPromise.then !== 'function') { 1220 runAfter(); 1221 return Promise.resolve(); 1222 } 1223 1224 var timeoutPromise = new Promise(function (resolve) { setTimeout(resolve, 500); }); 1225 return Promise.race([trackerPromise.catch(function () {}), timeoutPromise]) 1226 .then(runAfter, runAfter); 1227 } 1228 1229 // ê³µê° API 1230 return { 1231 setAccentColor: setAccentColor, 1232 sendSelectedOptionsUpdate: sendSelectedOptionsUpdate, 1233 updateSelectedOptionsTotal: updateSelectedOptionsTotal, 1234 loadState: loadState, 1235 loadStateByCodes: loadStateByCodes, 1236 selectAdditionalProductByIdx: selectAdditionalProductByIdx, 1237 getProductOptionHtml: getProductOptionHtml, 1238 completeAdditionalProductSelection: completeAdditionalProductSelection, 1239 hasOrderAlarmShown: hasOrderAlarmShown, 1240 markOrderAlarmShown: markOrderAlarmShown, 1241 hasAddCartAlarmShown: hasAddCartAlarmShown, 1242 markAddCartAlarmShown: markAddCartAlarmShown, 1243 setRequireOptionCompleted: setRequireOptionCompleted, 1244 setCartFreeShippingRemainingPrice: setCartFreeShippingRemainingPrice, 1245 resetInlineMagnetItemCounts: resetInlineMagnetItemCounts, 1246 dispatchInlineMagnetItemCounts: dispatchInlineMagnetItemCounts, 1247 getInlineMagnetCodeByIdx: getInlineMagnetCodeByIdx, 1248 syncInlineMagnetItemCountsFromAdditionals: syncInlineMagnetItemCountsFromAdditionals, 1249 cancelAdditionalProductSelection: cancelAdditionalProductSelection, 1250 getCachedCartTotal: getCachedCartTotal, 1251 getCachedCartFreeShippingRemainingPrice: getCachedCartFreeShippingRemainingPrice, 1252 getCachedSelectedOptionsTotal: getCachedSelectedOptionsTotal, 1253 getCachedFreeShipNotifySettings: getCachedFreeShipNotifySettings, 1254 getCachedFreeShipNotifyConfig: getCachedFreeShipNotifyConfig, 1255 setCloseTracker: setCloseTracker, 1256 trackCloseAndContinue: trackCloseAndContinue 1257 }; 1258 1259})(); 1260 1261try { 1262 window.dispatchEvent(new CustomEvent('imweb:freeShipNotify:sdk-ready')); 1263} catch (e) {}
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.