1/** 2 * DSAC_V2 ë¡ê¹ ì ê°í¸íê² ì¬ì©í기 ìí ëí¼ ì¤í¬ë¦½í¸ (íì´ë¡ë 기ë°) 3 * @author Danawa 4 * @version 2.0.0 5 * @description JSON + Base64 ì¸ì½ë© ë°©ìì¼ë¡ ìì í ë¡ê¹ ë°ì´í° ì ì¡ 6 */ 7 8(function (window) { 9 'use strict'; 10 11 // ì¤í¬ë¦½í¸ ë¡ë ìì ì ë²ì íë¼ë¯¸í° ìº¡ì² (document.currentScriptë ì¦ì ì¤íë ëë§ ì í¨) 12 const currentScript = document.currentScript || document.querySelector('script[src*="priceCompareUxlog.js"]'); 13 const scriptSrc = currentScript?.src || ''; 14 const versionMatch = scriptSrc.match(/[?&]v=([^&]+)/); 15 const SCRIPT_VERSION = versionMatch ? versionMatch[1] : ''; 16 17 /** 18 * @typedef {Object} LogPayload 19 * @property {'pv'|'c'} action - ì¡ì íì 20 * @property {string} [page] - íì´ì§ ì½ë (ì: 'AAA') 21 * @property {string} [mid] - ë©¤ë² ID 22 * @property {string} [area] - ìì ì½ë (í´ë¦ ë¡ê¹ ì íì, ì: 'aa1', 'button', 'link') 23 * @property {Params} [params] - ì ë íë¼ë¯¸í° 24 */ 25 26 /** 27 * @typedef {Object} Params 28 * @property {string} [click_name] - ë´ë¶í´ë¦ì´ë²¤í¸ëª 29 * @property {string|number} [productId] - ìí ID 30 * @property {number} [category1_seq] - 물리카í ê³ ë¦¬ ëë¶ë¥ ì½ë 31 * @property {number} [category2_seq] - 물리카í ê³ ë¦¬ ì¤ë¶ë¥ ì½ë 32 * @property {number} [category3_seq] - 물리카í ê³ ë¦¬ ìë¶ë¥ ì½ë 33 * @property {number} [category4_seq] - 물리카í ê³ ë¦¬ ì¸ë¶ë¥ ì½ë 34 */ 35 36 /** 37 * PriceCompareUxlog í´ëì¤ 38 * DSAC_V2 ë¡ê¹ ì ê°í¸íê² ì¬ì©í ì ìëë¡ ëì주ë ì í¸ë¦¬í° 39 */ 40 function PriceCompareUxlog() { 41 this.defaultMemberCode = null; 42 this.defaultTrackingId = null; 43 this.defaultPageCode = null; 44 this.isDebugMode = false; 45 this.isInitialized = false; 46 this.eventDelegationEnabled = false; 47 this.eventListenerAttached = false; 48 this.eventListeners = []; // ì´ë²¤í¸ 리ì¤ë ì ì¥ì© 49 this.delegationContainer = null; // ìì 컨í ì´ë ì ì¥ì© 50 this.scriptVersion = SCRIPT_VERSION; // ì¤í¬ë¦½í¸ ë²ì ì ì¥ 51 } 52 53 /** 54 * 기본 ë©¤ë² ì½ë ì¤ì 55 * @param {number|string} memberCode ë©¤ë² ì½ë 56 */ 57 PriceCompareUxlog.prototype.setDefaultMemberCode = function (memberCode) { 58 this.defaultMemberCode = memberCode ? parseInt(memberCode) : null; 59 return this; 60 }; 61 62 /** 63 * 기본 í¸ëí¹ ID ì¤ì 64 * @param {string} trackingId í¸ëí¹ ID 65 */ 66 PriceCompareUxlog.prototype.setDefaultTrackingId = function (trackingId) { 67 this.defaultTrackingId = typeof trackingId === 'string' ? trackingId : null; 68 return this; 69 }; 70 71 /** 72 * 기본 íì´ì§ ì½ë ì¤ì 73 * @param {string} pageCode íì´ì§ ì½ë 74 */ 75 PriceCompareUxlog.prototype.setDefaultPageCode = function (pageCode) { 76 this.defaultPageCode = pageCode || null; 77 return this; 78 }; 79 80 /** 81 * ëë²ê·¸ 모ë ì¤ì 82 * @param {boolean} debug ëë²ê·¸ 모ë ì¬ë¶ 83 */ 84 PriceCompareUxlog.prototype.setDebugMode = function (debug) { 85 this.isDebugMode = !!debug; 86 return this; 87 }; 88 // DSAC ë¡ë ìí ê´ë¦¬ (모ë ë 벨 ë³ì) 89 let dsacLoadingPromise = null; 90 91 /** 92 * DSAC_V2 ëì ë¡ë ë° ì´ê¸°í 93 */ 94 PriceCompareUxlog.prototype.loadDSAC = function () { 95 const self = this; 96 97 // ì´ë¯¸ ë¡ëëì´ ìë ê²½ì° 98 if (typeof DSAC_V2 === 'object' && DSAC_V2 !== null) { 99 self.isInitialized = true; 100 return Promise.resolve(true); 101 } 102 103 // ì´ë¯¸ ë¡ë ì¤ì¸ ê²½ì° ëì¼í Promise ë°í (ì¤ë³µ í¸ì¶ ë°©ì§) 104 if (dsacLoadingPromise) { 105 if (self.isDebugMode) { 106 console.log('PriceCompareUxlog: DSAC_V2 ë¡ë ì¤ - 기존 Promise ë°í'); 107 } 108 return dsacLoadingPromise; 109 } 110 111 // ìë¡ì´ ë¡ë Promise ìì± 112 dsacLoadingPromise = new Promise((resolve) => { 113 // ì¤í¬ë¦½í¸ ë¡ë ìì ì 캡ì²ë ë²ì ì¬ì© 114 const versionParam = self.scriptVersion ? '?v=' + self.scriptVersion : ''; 115 116 // íê²½ì ë°ë¥¸ DSAC URL ê²°ì
117 const isDevEnvironment = 118 window.location.hostname.includes('localhost') || 119 window.location.hostname.includes('-t') || 120 window.location.hostname.includes('-local'); 121 const isStagingEnvironment = 122 window.location.hostname.includes('-s') || window.location.hostname.includes('-stg'); 123 124 const dsacUrl = isDevEnvironment 125 ? 'https://static-t.danawa.com/globaljs/static/bdl/dsac.min.js' + versionParam 126 : isStagingEnvironment 127 ? 'https://static-s.danawa.com/globaljs/static/bdl/dsac.min.js' + versionParam 128 : 'https://static.danawa.com/globaljs/static/bdl/dsac.min.js' + versionParam; 129 130 if (self.isDebugMode) { 131 console.log('PriceCompareUxlog: DSAC_V2 ë¡ë ìì:', { 132 url: dsacUrl, 133 version: self.scriptVersion || '(ë²ì ìì)' 134 }); 135 } 136 137 // ëì ì¤í¬ë¦½í¸ ë¡ë 138 const script = document.createElement('script'); 139 script.src = dsacUrl; 140 script.async = true; 141 142 script.onload = function () { 143 // ë¡ë ìë£ í DSAC_V2 ê°ì²´ íì¸ 144 let attempts = 0; 145 const maxAttempts = 20; // 2ì´ ë기 146 const checkInterval = setInterval(() => { 147 attempts++; 148 if (typeof DSAC_V2 === 'object' && DSAC_V2 !== null) { 149 self.isInitialized = true; 150 clearInterval(checkInterval); 151 dsacLoadingPromise = null; // Promise ìë£ í ì´ê¸°í 152 if (self.isDebugMode) { 153 console.log('PriceCompareUxlog: DSAC_V2 ë¡ë ìë£'); 154 } 155 resolve(true); 156 } else if (attempts >= maxAttempts) { 157 clearInterval(checkInterval); 158 dsacLoadingPromise = null; // Promise ìë£ í ì´ê¸°í 159 if (self.isDebugMode) { 160 console.warn('PriceCompareUxlog: DSAC_V2 ê°ì²´ ì´ê¸°í íììì'); 161 } 162 resolve(false); 163 } 164 }, 100); 165 }; 166 167 script.onerror = function () { 168 dsacLoadingPromise = null; // Promise ìë£ í ì´ê¸°í 169 if (self.isDebugMode) { 170 console.error('PriceCompareUxlog: DSAC_V2 ì¤í¬ë¦½í¸ ë¡ë ì¤í¨:', dsacUrl); 171 } 172 resolve(false); 173 }; 174 175 document.head.appendChild(script); 176 }); 177 178 return dsacLoadingPromise; 179 }; 180 181 /** 182 * DSAC_V2 ì´ê¸°í ë기 (íì í¸íì±ì ìí ë³ì¹) 183 * @deprecated loadDSAC() ì¬ì© ê¶ì¥ 184 */ 185 PriceCompareUxlog.prototype.waitForDSAC = function () { 186 return this.loadDSAC(); 187 }; 188 /** 189 * DSAC_V2 ë¡ê¹ ì¤í (Base64 íì´ë¡ë ëì½ë©) 190 * @param {LogPayload|string} payload Base64 ì¸ì½ë©ë íì´ë¡ë 문ìì´ ëë íì´ë¡ë ê°ì²´ 191 */ 192 PriceCompareUxlog.prototype.log = function (payload) { 193 if (!payload) { 194 if (this.isDebugMode) console.warn('PriceCompareUxlog: ë¡ê¹ íì´ë¡ëê° íìí©ëë¤.'); 195 return false; 196 } 197 198 const self = this; 199 200 // DSAC_V2ê° ìì¼ë©´ ìëì¼ë¡ ë¡ë í ì¬ìë 201 if (typeof DSAC_V2 !== 'object' || DSAC_V2 === null) { 202 if (this.isDebugMode) console.log('PriceCompareUxlog: DSAC_V2 ìë ë¡ë ìì'); 203 204 this.loadDSAC() 205 .then((loaded) => { 206 if (loaded) { 207 // ë¡ë ìë£ í ë¤ì ë¡ê¹ ìë 208 self._executeLog(payload); 209 } else { 210 if (self.isDebugMode) console.warn('PriceCompareUxlog: DSAC_V2 ë¡ë ì¤í¨ - ë¡ê¹ ê±´ëë'); 211 } 212 }) 213 .catch((error) => { 214 if (self.isDebugMode) console.error('PriceCompareUxlog: DSAC_V2 ë¡ë ì¤ë¥:', error); 215 }); 216 217 return true; // ë¹ë기 ì²ë¦¬ ì¤ì´ë¯ë¡ true ë°í 218 } 219 220 // DSAC_V2ê° ì´ë¯¸ ë¡ëë ê²½ì° ë°ë¡ ì¤í 221 return this._executeLog(payload); 222 }; 223 224 /** 225 * ì¤ì ë¡ê¹ ì¤í í¨ì (ë´ë¶ì©) 226 * @param {LogPayload|string} payload íì´ë¡ë 227 */ 228 PriceCompareUxlog.prototype._executeLog = function (payload) { 229 if (typeof DSAC_V2 !== 'object' || DSAC_V2 === null) { 230 if (this.isDebugMode) console.warn('PriceCompareUxlog: DSAC_V2 ê°ì²´ê° ììµëë¤.'); 231 return false;
232 } 233 234 let finalPayload; 235 236 try { 237 // payloadê° ë¬¸ìì´ì´ë©´ Base64 ëì½ë©, ê°ì²´ë©´ ê·¸ëë¡ ì¬ì© 238 if (typeof payload === 'string') { 239 finalPayload = this.decodePayload(payload); 240 241 if (!finalPayload) { 242 if (this.isDebugMode) console.warn('PriceCompareUxlog: íì´ë¡ë ëì½ë© ì¤í¨'); 243 return false; 244 } 245 246 if (this.isDebugMode) { 247 console.log('PriceCompareUxlog: Base64 íì´ë¡ë ëì½ë©:', { 248 base64: payload, 249 decoded: finalPayload 250 }); 251 } 252 } else if (typeof payload === 'object') { 253 finalPayload = { ...payload }; 254 } else { 255 if (this.isDebugMode) console.warn('PriceCompareUxlog: ì못ë íì´ë¡ë íìì ëë¤.'); 256 return false; 257 } 258 // 기본 íì´ì§ ì½ëê° ì¤ì ëì´ ìë¤ë©´ payload ê° ë¬´ìíê³ ê¸°ë³¸ íì´ì§ ì½ë ì¬ì© 259 if (this.defaultPageCode) { 260 finalPayload.page = this.defaultPageCode; 261 } else if (!finalPayload.page) { 262 if (this.isDebugMode) console.warn('PriceCompareUxlog: page ê°ì´ ììµëë¤.'); 263 return false; 264 } 265 266 // 기본 í¸ëí¹ IDê° ì¤ì ëì´ ìê³ midê° ìì¼ë©´ ì¶ê° 267 if (typeof this.defaultTrackingId === 'string' && !finalPayload.mid) { 268 finalPayload.mid = this.defaultTrackingId; 269 } 270 271 // 기존 ë°©ìì¼ë¡ DSAC_V2.execute í¸ì¶ 272 DSAC_V2.execute(finalPayload); 273 274 if (this.isDebugMode) { 275 console.log('PriceCompareUxlog V2 sent:', finalPayload); 276 } 277 return true; 278 } catch (error) { 279 if (this.isDebugMode) { 280 console.error('PriceCompareUxlog V2 error:', error); 281 } 282 return false; 283 } 284 }; 285 /** 286 * íì´ì§ë·° ë¡ê¹ (ê°í¸ ë©ìë) 287 * @param {object} payload íì´ì§ë·° ë¡ê¹ íì´ë¡ë 288 */ 289 PriceCompareUxlog.prototype.logPageView = function (payload = {}) { 290 if (this.isDebugMode) { 291 console.log('PriceCompareUxlog.logPageView í¸ì¶:', { 292 payload: payload, 293 defaultPageCode: this.defaultPageCode 294 }); 295 } 296 297 const finalPayload = { 298 action: 'pv', 299 ...payload 300 }; 301 302 return this.log(finalPayload); 303 }; 304 /** 305 * í´ë¦ ë¡ê¹ (ê°í¸ ë©ìë) 306 * @param {object} payload í´ë¦ ë¡ê¹ íì´ë¡ë (areaë íì) 307 */ 308 PriceCompareUxlog.prototype.logClick = function (payload = {}) { 309 if (!payload.area) { 310 if (this.isDebugMode) { 311 console.warn('PriceCompareUxlog: í´ë¦ ë¡ê¹ ìë areaê° íìí©ëë¤.'); 312 } 313 return false; 314 } 315 316 const finalPayload = { 317 action: 'c', 318 ...payload 319 }; 320 321 return this.log(finalPayload); 322 }; 323 /** 324 * ì¡°ê±´ë¶ ë¡ê¹ (ì¡°ê±´ì ë§ì¡±í ëë§ ë¡ê¹ ) 325 * @param {function|boolean} condition ì¡°ê±´ (í¨ì ëë boolean) 326 * @param {object} payload ë¡ê¹ íì´ë¡ë 327 */ 328 PriceCompareUxlog.prototype.logIf = function (condition, payload) { 329 let shouldLog = false; 330 331 if (typeof condition === 'function') { 332 try { 333 shouldLog = condition(); 334 } catch (error) { 335 if (this.isDebugMode) { 336 console.error('PriceCompareUxlog condition error:', error); 337 } 338 return false; 339 } 340 } else { 341 shouldLog = !!condition; 342 } 343 344 if (shouldLog) { 345 return this.log(payload); 346 } 347 348 return false; 349 }; 350 351 /** 352 * ì§ì° ë¡ê¹ (ì¼ì ìê° í ë¡ê¹ ) 353 * @param {number} delay ì§ì° ìê° (ë°ë¦¬ì´) 354 * @param {object} payload ë¡ê¹ íì´ë¡ë 355 */ 356 PriceCompareUxlog.prototype.logDelay = function (delay, payload) { 357 const self = this; 358 const timeoutId = setTimeout(() => { 359 self.log(payload); 360 }, delay || 0); 361 362 // ì·¨ìí ì ìëë¡ timeout ID ë°í 363 return timeoutId; 364 }; 365 /** 366 * ë°°ì¹ ë¡ê¹ (ì¬ë¬ ë¡ê·¸ë¥¼ íë²ì) 367 * @param {Array} payloads íì´ë¡ë ë°°ì´ 368 */ 369 PriceCompareUxlog.prototype.logBatch = function (payloads) { 370 if (!Array.isArray(payloads)) { 371 if (this.isDebugMode) { 372 console.warn('PriceCompareUxlog: payloadsë ë°°ì´ì´ì
372´ì¼ í©ëë¤.'); 373 } 374 return false; 375 } 376 377 let successCount = 0; 378 379 payloads.forEach((payload) => { 380 if (payload && typeof payload === 'object') { 381 if (this.log(payload)) { 382 successCount++; 383 } 384 } 385 }); 386 387 return successCount; 388 }; 389 390 /** 391 * ë©¤ë² ë¡ê·¸ì¸ ìíì ë°ë¥¸ ë¡ê¹ 392 * @param {object} loggedInPayload ë¡ê·¸ì¸ ì ë¡ê¹ íì´ë¡ë 393 * @param {object} loggedOutPayload ë¹ë¡ê·¸ì¸ ì ë¡ê¹ íì´ë¡ë (ì íì¬í) 394 */ 395 PriceCompareUxlog.prototype.logByLoginStatus = function (loggedInPayload, loggedOutPayload = null) { 396 if (this.defaultMemberCode) { 397 return this.log(loggedInPayload); 398 } else if (loggedOutPayload) { 399 return this.log(loggedOutPayload); 400 } 401 return false; 402 }; 403 /** 404 * ê°í¸ íì´ì§ë·° ë¡ê¹ (기본 íì´ì§ ì½ë ì¬ì©) 405 * @param {object} payload ì¶ê° íì´ë¡ë (기본ê°: {}) 406 */ 407 PriceCompareUxlog.prototype.logPV = function (payload = {}) { 408 if (this.isDebugMode) { 409 console.log('PriceCompareUxlog.logPV í¸ì¶:', { 410 payload: payload, 411 defaultPageCode: this.defaultPageCode 412 }); 413 } 414 return this.logPageView(payload); 415 }; 416 417 /** 418 * ê°í¸ í´ë¦ ë¡ê¹ (기본 íì´ì§ ì½ë ì¬ì©) 419 * @param {string} area ìì ì½ë 420 * @param {object} additionalPayload ì¶ê° íì´ë¡ë 421 */ 422 PriceCompareUxlog.prototype.logC = function (area, additionalPayload = {}) { 423 if (!area) { 424 if (this.isDebugMode) { 425 console.warn('PriceCompareUxlog: areaê° íìí©ëë¤.'); 426 } 427 return false; 428 } 429 430 return this.logClick({ 431 area: area, 432 ...additionalPayload 433 }); 434 }; 435 436 /** 437 * ê°í¸ ë¡ê¹ (기본 íì´ì§ ì½ë ì¬ì©) 438 * @param {string} action ì¡ì 439 * @param {object} additionalPayload ì¶ê° íì´ë¡ë 440 */ 441 PriceCompareUxlog.prototype.quickLog = function (action, additionalPayload = {}) { 442 return this.log({ 443 action: action, 444 ...additionalPayload 445 }); 446 }; 447 /** 448 * ì¤ìì§ì¤ì ì´ë²¤í¸ ìì íì±í 449 * HTML ììì data-uxlog-payload ìì±ì¼ë¡ Base64 ì¸ì½ë©ë ë¡ê¹ ì 보를 ì¤ì íë©´ ìëì¼ë¡ ë¡ê¹ ë©ëë¤ 450 * @param {string|Element} container ì´ë²¤í¸ë¥¼ ììí 컨í ì´ë (기본: document) 451 */ 452 PriceCompareUxlog.prototype.enableEventDelegation = function (container = document) { 453 // ì´ë¯¸ íì±íëì´ ìì¼ë©´ ì¤ë³µ ë°©ì§ 454 if (this.eventDelegationEnabled && this.eventListeners.length > 0) { 455 if (this.isDebugMode) { 456 console.log('PriceCompareUxlog: ì´ë²¤í¸ ììì´ ì´ë¯¸ íì±íëì´ ììµëë¤.'); 457 } 458 return this; 459 } 460 461 // 기존 ì´ë²¤í¸ 리ì¤ë ì 리 462 this.disableEventDelegation(); 463 464 this.eventDelegationEnabled = true; 465 const targetContainer = typeof container === 'string' ? document.querySelector(container) : container; 466 467 if (!targetContainer) { 468 if (this.isDebugMode) { 469 console.warn('PriceCompareUxlog: 컨í ì´ë를 ì°¾ì ì ììµëë¤.'); 470 } 471 return this; 472 } 473 474 this.delegationContainer = targetContainer; 475 476 // í´ë¦ ì´ë²¤í¸ë§ ë±ë¡ (mousedownì ì ê±° - ì¤ë³µ ë°©ì§) 477 const clickHandler = (event) => { 478 if (!this.eventDelegationEnabled) return; // ë¹íì±í ìí ì²´í¬ 479 this._handleDelegatedEvent(event, 'click'); 480 }; 481 482 targetContainer.addEventListener('click', clickHandler); 483 484 // ì´ë²¤í¸ 리ì¤ë ì ì¥ (ëì¤ì ì ê±°í기 ìí´) 485 this.eventListeners.push({ 486 element: targetContainer, 487 event: 'click', 488 handler: clickHandler 489 }); 490 491 if (this.isDebugMode) { 492 console.log('PriceCompareUxlog: ì´ë²¤í¸ ììì´ íì
492±íëììµëë¤.', { 493 container: targetContainer, 494 eventListeners: this.eventListeners.length 495 }); 496 } 497 498 return this; 499 }; 500 /** 501 * ììë ì´ë²¤í¸ ì²ë¦¬ 502 * @param {Event} event ì´ë²¤í¸ ê°ì²´ 503 * @param {string} eventType ì´ë²¤í¸ íì 504 */ 505 PriceCompareUxlog.prototype._handleDelegatedEvent = function (event, eventType) { 506 // ì´ë²¤í¸ ììì´ ë¹íì±íëì´ ìì¼ë©´ 무ì 507 if (!this.eventDelegationEnabled) return; 508 509 const target = event.target.closest('[data-uxlog-payload]'); 510 if (!target) return; 511 512 // ì¤ë³µ í¸ì¶ ë°©ì§ë¥¼ ìí íëê·¸ ì²´í¬ 513 if (target._uxlogProcessing) return; 514 target._uxlogProcessing = true; 515 516 // ì§§ì ìê° í íëê·¸ í´ì (ëì¼í ì´ë²¤í¸ ì¤ë³µ ë°©ì§) 517 setTimeout(() => { 518 delete target._uxlogProcessing; 519 }, 50); 520 try { 521 // data-uxlog-payloadìì Base64 ëì½ë© í JSON íì± 522 const base64Payload = target.dataset.uxlogPayload; 523 if (!base64Payload) return; 524 525 const payload = this.decodePayload(base64Payload); 526 if (!payload) { 527 if (this.isDebugMode) { 528 console.error('PriceCompareUxlog: ì´ë²¤í¸ ìì íì´ë¡ë ëì½ë© ì¤í¨:', target); 529 } 530 return; 531 } 532 533 if (this.isDebugMode) { 534 console.log(`PriceCompareUxlog: ${eventType} ì´ë²¤í¸ ìì ë¡ê¹ :`, { 535 base64: base64Payload, 536 payload: payload, 537 target: target 538 }); 539 } 540 541 this.logClick(payload); 542 } catch (error) { 543 if (this.isDebugMode) { 544 console.error('PriceCompareUxlog: ì´ë²¤í¸ ìì ì²ë¦¬ ì¤ë¥:', error, target); 545 } 546 } 547 }; 548 /** 549 * ì´ë²¤í¸ ìì ë¹íì±í 550 */ 551 PriceCompareUxlog.prototype.disableEventDelegation = function () { 552 this.eventDelegationEnabled = false; 553 554 // ì ì¥ë ì´ë²¤í¸ 리ì¤ëë¤ì 모ë ì ê±° 555 this.eventListeners.forEach((listener) => { 556 if (listener.element && typeof listener.element.removeEventListener === 'function') { 557 listener.element.removeEventListener(listener.event, listener.handler); 558 if (this.isDebugMode) { 559 console.log(`PriceCompareUxlog: ${listener.event} ì´ë²¤í¸ 리ì¤ë ì ê±°ë¨`); 560 } 561 } 562 }); 563 564 // ì´ë²¤í¸ 리ì¤ë ë°°ì´ ì´ê¸°í 565 this.eventListeners = []; 566 this.delegationContainer = null; 567 if (this.isDebugMode) { 568 console.log('PriceCompareUxlog: ì´ë²¤í¸ ììì´ ë¹íì±íëììµëë¤.'); 569 } 570 571 return this; 572 }; 573 /** 574 * íì´ë¡ë를 Base64ë¡ ì¸ì½ë©íë ì í¸ë¦¬í° í¨ì (ì ëì½ë ìì ) 575 * @param {LogPayload} payload íì´ë¡ë ê°ì²´ 576 * @returns {string} Base64 ì¸ì½ë©ë 문ìì´ 577 */ 578 PriceCompareUxlog.prototype.encodePayload = function (payload) { 579 try { 580 const jsonPayload = JSON.stringify(payload); 581 // ì ëì½ë ìì ì¸ì½ë©: UTF-8 ë°ì´í¸ ìíì¤ë¡ ë³í í Base64 ì¸ì½ë© 582 const utf8Bytes = new TextEncoder().encode(jsonPayload); 583 const binaryString = Array.from(utf8Bytes, (byte) => String.fromCharCode(byte)).join(''); 584 return btoa(binaryString); 585 } catch (error) { 586 if (this.isDebugMode) { 587 console.error('PriceCompareUxlog: íì´ë¡ë ì¸ì½ë© ì¤ë¥:', error); 588 } 589 return null; 590 } 591 }; 592 593 /** 594 * Base64 ì¸ì½ë©ë 문ìì´ì íì´ë¡ëë¡ ëì½ë©íë ì í¸ë¦¬í° í¨ì (ì ëì½ë ìì ) 595 * @param {string} base64String Base64 ì¸ì½ë©ë 문ìì´ 596 * @returns {object|null} ëì½ë©ë íì´ë¡ë ê°ì²´ 597 */ 598 PriceCompareUxlog.prototype.decodePayload = function (base64String) { 599 try { 600 // ì ëì½ë ìì ëì½ë©: Base64 ëì½ë© í UTF-8 ë°ì´í¸ ìíì¤ë¡ ë³µ
600ì 601 const binaryString = atob(base64String); 602 const utf8Bytes = new Uint8Array(binaryString.length); 603 for (let i = 0; i < binaryString.length; i++) { 604 utf8Bytes[i] = binaryString.charCodeAt(i); 605 } 606 const jsonPayload = new TextDecoder().decode(utf8Bytes); 607 return JSON.parse(jsonPayload); 608 } catch (error) { 609 if (this.isDebugMode) { 610 console.error('PriceCompareUxlog: íì´ë¡ë ëì½ë© ì¤ë¥:', error); 611 } 612 return null; 613 } 614 }; 615 /** 616 * ì´ê¸°í ë° ìë ì¤ì 617 */ 618 PriceCompareUxlog.prototype.init = function () { 619 // ì ì ì¤ì ìì ë©¤ë² ì½ë ìë ì¤ì 620 if (typeof window.oGlobalSetting === 'object' && window.oGlobalSetting && window.oGlobalSetting.memberSeq) { 621 this.setDefaultMemberCode(window.oGlobalSetting.memberSeq); 622 } 623 624 // ì ì ì¤ì ìì í¸ëí¹ ID ìë ì¤ì 625 if (typeof window.oGlobalSetting === 'object' && window.oGlobalSetting && window.oGlobalSetting.trackingId) { 626 this.setDefaultMemberCode(window.oGlobalSetting.trackingId); 627 } 628 629 // ì ì ì¤ì ìì íì´ì§ ì½ë ìë ì¤ì 630 if (typeof window.oGlobalSetting === 'object' && window.oGlobalSetting && window.oGlobalSetting.pageCode) { 631 this.setDefaultPageCode(window.oGlobalSetting.pageCode); 632 } 633 634 // ê°ë° íê²½ììë ëë²ê·¸ 모ë íì±í 635 if ( 636 typeof window.location === 'object' && 637 window.location.hostname && 638 (window.location.hostname.includes('localhost') || 639 window.location.hostname.includes('-t') || 640 window.location.hostname.includes('-local')) 641 ) { 642 this.setDebugMode(true); 643 } 644 645 // DSAC_V2 ë¡ë ë기 646 this.waitForDSAC().then((loaded) => { 647 if (loaded && this.isDebugMode) { 648 console.log('PriceCompareUxlog: DSAC_V2 ì´ê¸°í ìë£'); 649 console.log('PriceCompareUxlog ìí:', { 650 defaultPageCode: this.defaultPageCode, 651 defaultMemberCode: this.defaultMemberCode, 652 defaultTrackingId: this.defaultTrackingId, 653 eventDelegationEnabled: this.eventDelegationEnabled 654 }); 655 } 656 }); 657 658 // ìëì¼ë¡ ì´ë²¤í¸ ìì íì±í (data-uxlog-auto="true"ì¸ ê²½ì°) 659 if (document.documentElement.dataset.uxlogAuto === 'true') { 660 this.enableEventDelegation(); 661 } 662 }; 663 664 // ì ì ì¸ì¤í´ì¤ ìì± 665 window.PriceCompareUxlog = PriceCompareUxlog; 666 667 // 기본 ì¸ì¤í´ì¤ ìì± (ë°ë¡ ì¬ì© ê°ë¥) 668 window.pcUxlog = new PriceCompareUxlog(); 669 670 // ìë ì´ê¸°í 671 if (document.readyState === 'loading') { 672 document.addEventListener('DOMContentLoaded', () => { 673 window.pcUxlog.init(); 674 }); 675 } else { 676 window.pcUxlog.init(); 677 } 678})(window);
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.