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 skip_content_tab_init: true 882 }); 883 } 884 885 if (typeof SITE_SHOP_DETAIL.initProdStock === 'function' && optionResult.prod_stock) { 886 SITE_SHOP_DETAIL.initProdStock( 887 optionResult.prod_stock.stock_use, 888 optionResult.prod_stock.stock_no_option, 889 optionResult.prod_stock.stock_unlimit 890 ); 891 } 892 893 if (typeof SITE_SHOP_DETAIL.setMaxPurchaseQuantity === 'function' && optionResult.max_prod_quantity !== undefined) { 894 SITE_SHOP_DETAIL.setMaxPurchaseQuantity( 895 optionResult.max_prod_quantity, 896 optionResult.max_member_quantity, 897 optionResult.maximum_purchase_quantity_type, 898 optionResult.optional_limit, 899 optionResult.optional_limit_type, 900 optionResult.prod_name 901 ); 902 } 903 904 } 905 906 /** 907 * cocoaDialogë¡ ìí ìµì ëª¨ë¬ íì 908 * @param {string} html - ìì±ë ëª¨ë¬ HTML 909 * @param {number} product_idx - ìí ì¸ë±ì¤ 910 * @param {object} product_info - ìí ì ë³´ (get_additional_product_info.cm ìëµ) 911 * @param {'prod'|'cart'} context - í¸ì¶ ë§¥ë½ 912 * @param {object} optionResult - load_prod_additional_option.cm ìëµ (cart 컨í ì¤í¸ ì´ê¸°íì© ë©íë°ì´í° í¬í¨) 913 * @param {function} callback - ìë£ ì½ë°± í¨ì 914 */ 915 function showProductOptionModal(html, product_idx, product_info, context, optionResult, callback) { 916 try { 917 // ì´ ëª¨ë¬ ì¸ì¤í´ì¤ ì ì© closure ë³ìë¤. ì 모ë¬ë§ë¤ ë 립 ìì±ëì´ hide_event/backdrop clickì´ 918 // ìì ì product_idxì ì§ì ìì snapshotìë§ ì ì©ëëë¡ ê²©ë¦¬íë¤. 919 var modalContext = (context === 'cart') ? 'cart' : 'prod'; 920 var modalProductIdx = product_idx; 921 var modalResolved = false; 922 // prod ë§¥ë½ììë§ ì§ì ì§ì ìí snapshotì ë°ìë . cart ë§¥ë½ì ì¹´í¸ë¡ ì§ì ë´ë íë¦ì´ë¼ ë¶íì. 923 var modalSnapshot = null; 924 if (modalContext === 'prod' 925 && typeof window.SITE_SHOP_DETAIL !== 'undefined' 926 && typeof window.SITE_SHOP_DETAIL.snapshotProdAdditionalForModal === 'function') { 927 modalSnapshot = window.SITE_SHOP_DETAIL.snapshotProdAdditionalForModal(modalProductIdx); 928 } 929 930 currentSelectionContext = modalContext; 931 currentSelectionProductIdx = modalProductIdx; 932 currentSelectionProductCode = (product_info && typeof product_info.code === 'string') ? product_info.code : ''; 933 currentSelectionShippingTemplateCode = (product_info && typeof product_info.shipping_template_code === 'string') ? product_info.shipping_template_code : ''; 934 currentSelectionCartType = (product_info && ( 935 product_info.is_regularly_prod === true || 936 product_info.is_regularly_prod === 'Y' || 937 product_info.only_regularly === true || 938 product_info.only_regularly === 'Y' 939 )) ? 'regularly' : ''; 940 941 // íì¬ ëª¨ë¬ì cleanup í¸ë¤ â snapshot ê¸°ë° restore. ì§ì ì§ì ìíë¡ ëëë ¤ 942 // "ì´ë² 모ë¬ì´ ì¶ê°í ë§í¼ë§" revert (기존ì ë´ê²¨ìë ìµì /í목ì ë³´ì¡´). 943 var cleanupForThisModal = function () { 944 if (modalResolved) return; 945 modalResolved = true; 946 if (modalContext === 'prod' && modalProductIdx > 0 947 && modalSnapshot 948 && typeof window.SITE_SHOP_DETAIL !== 'undefined' 949 && typeof window.SITE_SHOP_DETAIL.restoreProdAdditionalForModal === 'function') { 950 window.SITE_SHOP_DETAIL.restoreProdAdditionalForModal(modalProductIdx, modalSnapshot); 951 } 952 if (modalProductIdx === currentSelectionProductIdx) { 953 currentSelectionProductIdx = 0; 954 } 955 }; 956 // ëª ìì completeìì í¸ì¶ â restore ìì´ resolvedë§ íìí´ íì implicit cleanup ì°¨ë¨. 957 var markResolvedForThisModal = function () { 958 modalResolved = true; 959 }; 960 _currentModalCleanup = cleanupForThisModal;
961 _currentModalMarkResolved = markResolvedForThisModal; 962 963 // prod ë§¥ë½ììë§ SITE_SHOP_DETAILì ì¶ê°ìí ëª¨ë¬ ìí ì´ê¸°í ìí. 964 // cart ë§¥ë½ì "ì¶ê°ìí ì í" ê°ë ìì´ ë°ë¡ ì¹´í¸ì ë´ì¼ë¯ë¡ ë¤ë¥¸ ì´ê¸°í(initDetailForCartContext)를 ì¬ì©íë¤. 965 if (currentSelectionContext === 'prod' 966 && typeof SITE_SHOP_DETAIL !== 'undefined' 967 && typeof SITE_SHOP_DETAIL.selectAdditionalProductForModal === 'function') { 968 if (typeof SITE_SHOP_DETAIL.setFreeShipNotifyProdAdditionalRegularPrice === 'function') { 969 SITE_SHOP_DETAIL.setFreeShipNotifyProdAdditionalRegularPrice(product_idx, product_info.regular_price || product_info.price || 0); 970 } 971 SITE_SHOP_DETAIL.selectAdditionalProductForModal( 972 product_idx, 973 product_info.price || 0, 974 product_info.name || '', 975 product_info.maximum_purchase_quantity || 0, 976 product_info.member_maximum_purchase_quantity || 0, 977 product_info.maximum_purchase_quantity_type || '', 978 product_info.optional_limit || 0, 979 product_info.optional_limit_type || '', 980 product_info.stock_use || 0, 981 product_info.stock || 0, 982 product_info.stock_unlimit || 0, 983 product_info.option_mix_type || '', 984 product_info.prod_type || '', 985 product_info.period_discount_flag || 0, 986 product_info.period_discount_data || {}, 987 product_info.period_discout_group_list || [], 988 product_info.membership_discount || 0, 989 product_info.additional_creator_discount_data || null 990 ); 991 } 992 993 var $staleOptionModal = $('.modal_site_shop_free_ship_notify_option.in'); 994 if ($staleOptionModal.length > 0) { 995 $staleOptionModal.modal('hide'); 996 } 997 998 var is_mobile_width = (window.innerWidth < 768); 999 if(is_mobile_width){ 1000 // ì¶ê° ìí ìí¸ì ìí ì ê³µì íë¯ë¡ ID를 ê°ì´ ì¬ì© 1001 imSheet.close('prod_additional_sheet', () => { 1002 imSheet.open({ 1003 id: 'prod_additional_sheet', 1004 html: html, 1005 backdrop: 'rgba(0, 0, 0, 0.15)', 1006 zIndex: 17001, 1007 onShow: function() { 1008 // cart 컨í ì¤í¸ë 모ë¬ì´ DOMì ë¤ì´ê° ë¤ SITE_SHOP_DETAIL ì´ê¸°í 1009 // (initDetailì´ ëª¨ë¬ ìì #prod_options ë±ì ì°¾ìì¼ íë¯ë¡ mount ì´íì í¸ì¶) 1010 if (currentSelectionContext === 'cart') { 1011 initDetailForCartContext(optionResult); 1012 } 1013 } 1014 }); 1015 1016 // backdrop ìì í´ë¦ì¼ë¡ ë«ì ëë cleanupì´ ëìíëë¡ ì¶ê° click í¸ë¤ë¬ ë±ë¡. 1017 // closureë¡ ìº¡ì³ë cleanupForThisModalì ì§ì í¸ì¶ â ìì ì product_idxì snapshot 기ì¤ì¼ë¡ ìì íê² restore. 1018 $('#prod_additional_sheet').on('click', function(e) { 1019 if ($(e.target).parents('.im-sheet-content').length === 0) { 1020 cleanupForThisModal(); 1021 } 1022 }); 1023 1024 // MFE ì¶ì² ììì ë´ê¸° ë²í¼ ë¡ë© í´ì ê° ì´ ì½ë°±ì ê±¸ë ¤ ìì¼ë¯ë¡ PC ë¶ê¸°ì ëì¼íê² í¸ì¶ 1025 if (callback) callback(true, 'ìí ìµì 모ë¬ì íìíìµëë¤.'); 1026 }); 1027 }else{ 1028 $.cocoaDialog.open({ 1029 type: 'site_shop_free_ship_notify_option', 1030 custom_popup: html, 1031 pc_width: 440, 1032 // ì¸ë¶ í´ë¦/ESC ë±ì¼ë¡ cocoaDialogê° ë«í ëë cleanupì´ ëìíëë¡ hide_event ë±ë¡. 1033 // closureë¡ ìº¡ì³ë cleanupForThisModal â ìì ì product_idxì snapshot 기ì¤ì¼ë¡ ìì íê² restore. 1034 // ëª ìì complete/cancelì modalResolved=trueë¡ íìíë¯ë¡ ì¤ë³µ cleanup ì ë¨. 1035 hide_event: cleanupForThisModal 1036 }); 1037 1038 // PC 모ë¬ì ë기 mountì´ë¯ë¡ ë°ë¡ ì´ê¸°í 1039 if (currentSelectionContext === 'cart') { 1040 initDetailForCartContext(optionResult); 1041 } 1042 1043 if (callback) callback(true, 'ìí ìµì 모ë¬ì íìíìµëë¤.'); 1044 } 1045 } catch (error) { 1046 if (callback) callback(false, getLocalizeString('ì¤ëª _ì¤ë¥ê°ë°ìíìµëë¤', '', 'ì¤ë¥ê° ë°ìíìµëë¤.')); 1047 } 1048 } 1049 1050 /** 1051 * ì¶ê° ìí ì í ì·¨ì ì²ë¦¬ ë° ëª¨ë¬ ë«ê¸°. 1052 * ëª¨ë¬ HTMLì ì·¨ì ë²í¼/X ë²í¼ìì í¸ì¶. prod ë§¥ë½ì selectAdditionalProductForModalì´ 1053 * ëª¨ë¬ ë ¸ì¶ ìì ì ì´ë¯¸ selected_prod_additionalsì pushíì¼ë¯ë¡ ëª ìì cleanupì´ íìíë¤. 1054 * cart ë§¥ë½ì ë¤ì 모ë¬ì´ ì´ë¦´ ë initDetailì´ ëª¨ë ìí를 resetíë¯ë¡ ë³ë cleanup ë¶íì. 1055 */ 1056 function cancelAdditionalProductSelection() { 1057 // íì¬ íì± ëª¨ë¬ì cleanup í¸ì¶ â snapshot ê¸°ë° restoreë¡ ì§ì ì§ì ìíë¡ ë³µ
1057ì. 1058 // ì´ í¸ì¶ì´ modalResolved=trueë¡ íìíë¯ë¡ íì hide_event / backdrop clickì´ ì¤ë³µ cleanupíì§ ìëë¤. 1059 if (typeof _currentModalCleanup === 'function') { 1060 _currentModalCleanup(); 1061 } 1062 1063 var is_mobile_width = (window.innerWidth < 768); 1064 if (is_mobile_width) { 1065 if (typeof imSheet !== 'undefined' && typeof imSheet.close === 'function') { 1066 imSheet.close('prod_additional_sheet'); 1067 } 1068 } else if (typeof $ !== 'undefined' && typeof $.cocoaDialog === 'object' && typeof $.cocoaDialog.close === 'function') { 1069 var $optionModal = $('.modal_site_shop_free_ship_notify_option.in'); 1070 if ($optionModal.length > 0) { 1071 $optionModal.modal('hide'); 1072 } else { 1073 $.cocoaDialog.close(); 1074 } 1075 } 1076 } 1077 1078 /** 1079 * ì¶ê° ìí ì í ìë£ ì²ë¦¬ ë° ëª¨ë¬ ë«ê¸°. 1080 * ëª¨ë¬ HTMLì submit ë²í¼ìì í¸ì¶ëë©° ì¸ì를 ë°ì§ ìëë¤. ì§ì showProductOptionModalìì ì ì¥í 1081 * currentSelectionContext를 ì½ì´ contextë³ë¡ ë¶ê¸°íë¤. 1082 */ 1083 function completeAdditionalProductSelection() { 1084 try { 1085 // ì ì ìë£ íë¦ íì. íì hide_event / backdrop clickì´ snapshot 기ì¤ì¼ë¡ ëëë¦¬ì§ ìëë¡ resolved íëê·¸ë§ set. 1086 if (typeof _currentModalMarkResolved === 'function') { 1087 _currentModalMarkResolved(); 1088 } 1089 if (currentSelectionContext === 'cart') { 1090 // cart ë§¥ë½: 무ë£ë°°ì¡ 모ë¬ììë selectRequireOptionì´ selectOptionì í¸ì¶íì§ ìê³ ì í ìíë§ ì ì§íë¯ë¡ 1091 // (selectProdAdditionalRequireOption í¨í´ê³¼ ëì¼) ì¬ê¸°ì selected_require_options를 ì§ì ì½ì´ addCart í¬ë§·ì¼ë¡ ë³ííë¤. 1092 if (typeof window.SITE_SHOP_CART === 'undefined' || typeof window.SITE_SHOP_CART.addCart !== 'function') { 1093 return; 1094 } 1095 if (typeof SITE_SHOP_DETAIL === 'undefined' || typeof SITE_SHOP_DETAIL.getSelectedRequireOptions !== 'function') { 1096 return; 1097 } 1098 1099 var requireOptions = SITE_SHOP_DETAIL.getSelectedRequireOptions(); 1100 var requireCount = (typeof SITE_SHOP_DETAIL.getRequireOptionCount === 'function') 1101 ? (SITE_SHOP_DETAIL.getRequireOptionCount() || 0) 1102 : 0; 1103 if (!requireOptions || requireOptions.length < requireCount) { 1104 alert(typeof LOCALIZE !== 'undefined' && typeof LOCALIZE.ì¤ëª _íììµì ì´ëª¨ëì íëì´ìì§ììµëë¤ === 'function' 1105 ? LOCALIZE.ì¤ëª _íììµì ì´ëª¨ëì íëì´ìì§ììµëë¤() 1106 : 'íì ìµì ì 모ë ì íí´ì£¼ì¸ì.'); 1107 return; 1108 } 1109 1110 var prodIdx = currentSelectionProductIdx; 1111 1112 $.ajax({ 1113 type: 'POST', 1114 url: '/shop/select_option.cm', 1115 data: { 1116 'prod_idx': prodIdx, 1117 'count': 1, 1118 'require': 'Y', 1119 'options': requireOptions 1120 }, 1121 dataType: 'json', 1122 cache: false, 1123 success: function (selectOptionResult) { 1124 if (!selectOptionResult || selectOptionResult.msg !== 'SUCCESS') { 1125 alert((selectOptionResult && selectOptionResult.msg) || getLocalizeString('ì¤ëª _ì¤ë¥ê°ë°ìíìµëë¤', '', 'ì¤ë¥ê° ë°ìíìµëë¤.')); 1126 return; 1127 } 1128 1129 var optionPrice = (selectOptionResult.selected_option && typeof selectOptionResult.selected_option.price === 'number') 1130 ? selectOptionResult.selected_option.price 1131 : 0; 1132 1133 // add_cart.cmì´ ê¸°ëíë í¬ë§·: [{ options, require, count, price }] 1134 var addCartPayload = [{ 1135 options: requireOptions, 1136 require: true, 1137 count: 1, 1138 price: optionPrice 1139 }]; 1140 1141 window.SITE_SHOP_CART.addCart(prodIdx, addCartPayload, 1, function(success, message, addCartResult) { 1142 if (success) { 1143 dispatchAdditionalProductAdded(prodIdx, addCartResult); 1144 var is_mobile_width = (window.innerWidth < 768); 1145 if (is_mobile_width) { 1146 if (typeof SITE_SHOP_DETAIL !== 'undefined' 1147 && typeof SITE_SHOP_DETAIL.resetSelectedRequireOptions === 'function') { 1148 SITE_SHOP_DETAIL.resetSelectedRequireOptions(); 1149 } 1150 currentSelectionProductIdx = 0; 1151 currentSelectionContext = 'prod'; 1152 imSheet.close('prod_additional_sheet'); 1153 } else { 1154 $('.modal_site_shop_free_ship_notify_option.in').modal('hide'); 1155 } 1156 } else { 1157 alert(message || getLocalizeString('ì¤ëª _ì¤ë¥ê°ë°ìíìµëë¤', '', 'ì¤ë¥ê° ë°ìíìµëë¤.')); 1158 } 1159 }, { 1160 shipping_template_code: currentSelectionShippingTemplateCode, 1161 cart_type: currentSelectionCartType 1162 }); 1163 }, 1164 error: function () { 1165 alert(getLocalizeString('ì¤ëª _ì¤ë¥ê°ë°ìíìµëë¤', '', 'ì¤ë¥ê° ë°ìíìµëë¤.')); 1166 } 1167 }); 1168 return; 1169 } 1170 1171 if (typeof window.SITE_SHOP_DETAIL === 'undefined') { 1172 return; 1173 } 1174 1175 // SITE_SHOP_DETAILì completeAdditionalProductSelection í¨ì í¸ì¶ 1176 if (typeof window.SITE_SHOP_DETAIL.completeAdditionalProductSelection === 'function') { 1177 window.SITE_SHOP_DETAIL.completeAdditionalProductSelection(); 1178 dispatchAdditionalProductAdded(currentSelectionProductIdx); 1179 } 1180 1181 } catch (error) { 1182 } 1183 } 1184 1185 // 모ë¬ì close/continue ë²í¼ í¸ëí¹ â MFE ê° modal placement ë§ì´í¸ ì setCloseTracker ë¡ 1186 // ë¹ë기 í¸ë¤ë¬ë¥¼ ë±ë¡. PHP ì close ë²í¼ onclick ì´ trackCloseAndContinue(afterAction) í¸ì¶ ì 1187 // í¸ë¤ë¬ë¥¼ ìµë 500ms 기ë¤ë¦° í afterAction ì ì¤í (íì´ì§ ì´ë race ìµìí). 1188 var _closeTracker = null; 1189 1190 function setCloseTracker(tracker) { 1191 _closeTracker = typeof tracker === 'function' ? tracker : null; 1192 } 1193 1194 function trackCloseAndContinue(afterAction) { 1195 var done = false;
1196 function runAfter() { 1197 if (done) return; 1198 done = true; 1199 if (typeof afterAction !== 'function') return; 1200 try { 1201 afterAction(); 1202 } catch (e) { 1203 // afterAction throw ê° Promise unhandled rejection ì¼ë¡ 묶ì´ì§ ìëë¡ ë§ì´í¬ë¡íì¤í¬ ë°ì¼ë¡ ì¬ëì§. 1204 // 기존 ë기 onclick ëìê³¼ ëë±í ìë¬ surface ì ì§ (window.onerror ì¡í). 1205 setTimeout(function () { throw e; }, 0); 1206 } 1207 } 1208 1209 if (typeof _closeTracker !== 'function') { 1210 runAfter(); 1211 return Promise.resolve(); 1212 } 1213 1214 var trackerPromise; 1215 try { 1216 trackerPromise = _closeTracker(); 1217 } catch (e) { 1218 runAfter(); 1219 return Promise.resolve(); 1220 } 1221 if (!trackerPromise || typeof trackerPromise.then !== 'function') { 1222 runAfter(); 1223 return Promise.resolve(); 1224 } 1225 1226 var timeoutPromise = new Promise(function (resolve) { setTimeout(resolve, 500); }); 1227 return Promise.race([trackerPromise.catch(function () {}), timeoutPromise]) 1228 .then(runAfter, runAfter); 1229 } 1230 1231 // ê³µê° API 1232 return { 1233 setAccentColor: setAccentColor, 1234 sendSelectedOptionsUpdate: sendSelectedOptionsUpdate, 1235 updateSelectedOptionsTotal: updateSelectedOptionsTotal, 1236 loadState: loadState, 1237 loadStateByCodes: loadStateByCodes, 1238 selectAdditionalProductByIdx: selectAdditionalProductByIdx, 1239 getProductOptionHtml: getProductOptionHtml, 1240 completeAdditionalProductSelection: completeAdditionalProductSelection, 1241 hasOrderAlarmShown: hasOrderAlarmShown, 1242 markOrderAlarmShown: markOrderAlarmShown, 1243 hasAddCartAlarmShown: hasAddCartAlarmShown, 1244 markAddCartAlarmShown: markAddCartAlarmShown, 1245 setRequireOptionCompleted: setRequireOptionCompleted, 1246 setCartFreeShippingRemainingPrice: setCartFreeShippingRemainingPrice, 1247 resetInlineMagnetItemCounts: resetInlineMagnetItemCounts, 1248 dispatchInlineMagnetItemCounts: dispatchInlineMagnetItemCounts, 1249 getInlineMagnetCodeByIdx: getInlineMagnetCodeByIdx, 1250 syncInlineMagnetItemCountsFromAdditionals: syncInlineMagnetItemCountsFromAdditionals, 1251 cancelAdditionalProductSelection: cancelAdditionalProductSelection, 1252 getCachedCartTotal: getCachedCartTotal, 1253 getCachedCartFreeShippingRemainingPrice: getCachedCartFreeShippingRemainingPrice, 1254 getCachedSelectedOptionsTotal: getCachedSelectedOptionsTotal, 1255 getCachedFreeShipNotifySettings: getCachedFreeShipNotifySettings, 1256 getCachedFreeShipNotifyConfig: getCachedFreeShipNotifyConfig, 1257 setCloseTracker: setCloseTracker, 1258 trackCloseAndContinue: trackCloseAndContinue 1259 }; 1260 1261})(); 1262 1263try { 1264 window.dispatchEvent(new CustomEvent('imweb:freeShipNotify:sdk-ready')); 1265} 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.