PageSourceSearch

https://www.ssd20.org/detailed-program/js/detikLiveUserCounterResponse.js

js ssd20.org collected 2026-10-08 20:30:58 UTC 38,613 bytes, 1,005 lines download raw bytes

1/*
2   detikLiveUserCounterResponse Object for Core-Developers
3*/
4
5// Chapter 1: Beginning
6if (typeof jQuery !== 'function') {
7  var warnJQueryUndefinedStr = 'detikLiveUserCounterResponse.js needs jQuery 1.1x.x to run properly!';
8  console.log(warnJQueryUndefinedStr);
9  throw new Error(warnJQueryUndefinedStr); // this line will stop the script
10};
11
12// Chapter 2: Load External Libraries
13
14var MD5 = function(d){var r = M(V(Y(X(d),8*d.length)));return r.toLowerCase()};function M(d){for(var _,m="0123456789ABCDEF",f="",r=0;r<d.length;r++)_=d.charCodeAt(r),f+=m.charAt(_>>>4&15)+m.charAt(15&_);return f}function X(d){for(var _=Array(d.length>>2),m=0;m<_.length;m++)_[m]=0;for(m=0;m<8*d.length;m+=8)_[m>>5]|=(255&d.charCodeAt(m/8))<<m%32;return _}function V(d){for(var _="",m=0;m<32*d.length;m+=8)_+=String.fromCharCode(d[m>>5]>>>m%32&255);return _}function Y(d,_){d[_>>5]|=128<<_%32,d[14+(_+64>>>9<<4)]=_;for(var m=1732584193,f=-271733879,r=-1732584194,i=271733878,n=0;n<d.length;n+=16){var h=m,t=f,g=r,e=i;f=md5_ii(f=md5_ii(f=md5_ii(f=md5_ii(f=md5_hh(f=md5_hh(f=md5_hh(f=md5_hh(f=md5_gg(f=md5_gg(f=md5_gg(f=md5_gg(f=md5_ff(f=md5_ff(f=md5_ff(f=md5_ff(f,r=md5_ff(r,i=md5_ff(i,m=md5_ff(m,f,r,i,d[n+0],7,-680876936),f,r,d[n+1],12,-389564586),m,f,d[n+2],17,606105819),i,m,d[n+3],22,-1044525330),r=md5_ff(r,i=md5_ff(i,m=md5_ff(m,f,r,i,d[n+4],7,-176418897),f,r,d[n+5],12,1200080426),m,f,d[n+6],17,-1473231341),i,m,d[n+7],22,-45705983),r=md5_ff(r,i=md5_ff(i,m=md5_ff(m,f,r,i,d[n+8],7,1770035416),f,r,d[n+9],12,-1958414417),m,f,d[n+10],17,-42063),i,m,d[n+11],22,-1990404162),r=md5_ff(r,i=md5_ff(i,m=md5_ff(m,f,r,i,d[n+12],7,1804603682),f,r,d[n+13],12,-40341101),m,f,d[n+14],17,-1502002290),i,m,d[n+15],22,1236535329),r=md5_gg(r,i=md5_gg(i,m=md5_gg(m,f,r,i,d[n+1],5,-165796510),f,r,d[n+6],9,-1069501632),m,f,d[n+11],14,643717713),i,m,d[n+0],20,-373897302),r=md5_gg(r,i=md5_gg(i,m=md5_gg(m,f,r,i,d[n+5],5,-701558691),f,r,d[n+10],9,38016083),m,f,d[n+15],14,-660478335),i,m,d[n+4],20,-405537848),r=md5_gg(r,i=md5_gg(i,m=md5_gg(m,f,r,i,d[n+9],5,568446438),f,r,d[n+14],9,-1019803690),m,f,d[n+3],14,-187363961),i,m,d[n+8],20,1163531501),r=md5_gg(r,i=md5_gg(i,m=md5_gg(m,f,r,i,d[n+13],5,-1444681467),f,r,d[n+2],9,-51403784),m,f,d[n+7],14,1735328473),i,m,d[n+12],20,-1926607734),r=md5_hh(r,i=md5_hh(i,m=md5_hh(m,f,r,i,d[n+5],4,-378558),f,r,d[n+8],11,-2022574463),m,f,d[n+11],16,1839030562),i,m,d[n+14],23,-35309556),r=md5_hh(r,i=md5_hh(i,m=md5_hh(m,f,r,i,d[n+1],4,-1530992060),f,r,d[n+4],11,1272893353),m,f,d[n+7],16,-155497632),i,m,d[n+10],23,-1094730640),r=md5_hh(r,i=md5_hh(i,m=md5_hh(m,f,r,i,d[n+13],4,681279174),f,r,d[n+0],11,-358537222),m,f,d[n+3],16,-722521979),i,m,d[n+6],23,76029189),r=md5_hh(r,i=md5_hh(i,m=md5_hh(m,f,r,i,d[n+9],4,-640364487),f,r,d[n+12],11,-421815835),m,f,d[n+15],16,530742520),i,m,d[n+2],23,-995338651),r=md5_ii(r,i=md5_ii(i,m=md5_ii(m,f,r,i,d[n+0],6,-198630844),f,r,d[n+7],10,1126891415),m,f,d[n+14],15,-1416354905),i,m,d[n+5],21,-57434055),r=md5_ii(r,i=md5_ii(i,m=md5_ii(m,f,r,i,d[n+12],6,1700485571),f,r,d[n+3],10,-1894986606),m,f,d[n+10],15,-1051523),i,m,d[n+1],21,-2054922799),r=md5_ii(r,i=md5_ii(i,m=md5_ii(m,f,r,i,d[n+8],6,1873313359),f,r,d[n+15],10,-30611744),m,f,d[n+6],15,-1560198380),i,m,d[n+13],21,1309151649),r=md5_ii(r,i=md5_ii(i,m=md5_ii(m,f,r,i,d[n+4],6,-145523070),f,r,d[n+11],10,-1120210379),m,f,d[n+2],15,718787259),i,m,d[n+9],21,-343485551),m=safe_add(m,h),f=safe_add(f,t),r=safe_add(r,g),i=safe_add(i,e)}return Array(m,f,r,i)}function md5_cmn(d,_,m,f,r,i){return safe_add(bit_rol(safe_add(safe_add(_,d),safe_add(f,i)),r),m)}function md5_ff(d,_,m,f,r,i,n){return md5_cmn(_&m|~_&f,d,_,r,i,n)}function md5_gg(d,_,m,f,r,i,n){return md5_cmn(_&f|m&~f,d,_,r,i,n)}function md5_hh(d,_,m,f,r,i,n){return md5_cmn(_^m^f,d,_,r,i,n)}function md5_ii(d,_,m,f,r,i,n){return md5_cmn(m^(_|~f),d,_,r,i,n)}function safe_add(d,_){var m=(65535&d)+(65535&_);return(d>>16)+(_>>16)+(m>>16)<<16|65535&m}function bit_rol(d,_){return d<<_|d>>>32-_};
15
16;(function(factory) {
17    if (typeof define === 'function' && define.amd) {
18        define(factory);
19    } else {
20        window.purl = factory();
21    }
22})(function() {
23
24    var tag2attr = {
25            a       : 'href',
26            img     : 'src',
27            form    : 'action',
28            base    : 'href',
29            script  : 'src',
30            iframe  : 'src',
31            link    : 'href',
32            embed   : 'src',
33            object  : 'data'
34        },
35
36        key = ['source', 'protocol', 'authority', 'userInfo', 'user', 'password', 'host', 'port', 'relative', 'path', 'directory', 'file', 'query', 'fragment'], // keys available to query
37
38        aliases = { 'anchor' : 'fragment' }, // aliases for backwards compatability
39
40        parser = {
41            strict : /^(?:([^:\/?#]+):)?(?:\/\/((?:(([^:@]*):?([^:@]*))?@)?([^:\/?#]*)(?::(\d*))?))?((((?:[^?#\/]*\/)*)([^?#]*))(?:\?([^#]*))?(?:#(.*))?)/,  //less intuitive, more accurate to the specs
42            loose :  /^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@]*):?([^:@]*))?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/ // more intuitive, fails on relative paths and deviates from specs
43        },
44
45        isint = /^[0-9]+$/;
46
47    function parseUri( url, strictMode ) {
48        var str = decodeURI( url ),
49        res   = parser[ strictMode || false ? 'strict' : 'loose' ].exec( str ),
50        uri = { attr : {}, param : {}, seg : {} },
51        i   = 14;
52
53        while ( i-- ) {
54            uri.attr[ key[i] ] = res[i] || '';
55        }
56
57        // build query and fragment parameters
58        uri.param['query'] = parseString(uri.attr['query']);
59        uri.param['fragment'] = parseString(uri.attr['fragment']);
60
61        // split path and fragement into segments
62        uri.seg['path'] = uri.attr.path.replace(/^\/+|\/+$/g,'').split('/');
63        uri.seg['fragment'] = uri.attr.fragment.replace(/^\/+|\/+$/g,'').split('/');
64
65        // compile a 'base' domain attribute
66        uri.attr['base'] = uri.attr.host ? (uri.attr.protocol ?  uri.attr.protocol+'://'+uri.attr.host : uri.attr.host) + (uri.attr.port ? ':'+uri.attr.port : '') : '';
67
68        return uri;
69    }
70
71    function getAttrName( elm ) {
72        var tn = elm.tagName;
73        if ( typeof tn !== 'undefined' ) return tag2attr[tn.toLowerCase()];
74        return tn;
75    }
76
77    function promote(parent, key) {
78        if (parent[key].length === 0) return parent[key] = {};
79        var t = {};
80        for (var i in parent[key]) t[i] = parent[key][i];
81        parent[key] = t;
82        return t;
83    }
84
85    function parse(parts, parent, key, val) {
86        var part = parts.shift();
87        if (!part) {
88            if (isArray(parent[key])) {
89                parent[key].push(val);
90            } else if ('object' == typeof parent[key]) {
91                parent[key] = val;
92            } else if ('undefined' == typeof parent[key]) {
93                parent[key] = val;
94            } else {
95                parent[key] = [parent[key], val];
96            }
97        } else {
98            var obj = parent[key] = parent[key] || [];
99            if (']' == part) {
100                if (isArray(obj)) {
101                    if ('' !== val) obj.push(val);
102                } else if ('object' == typeof obj) {
103                    obj[keys(obj).length] = val;
104                } else {
105                    obj = parent[key] = [parent[key], val];
106                }
107            } else if (~part.indexOf(']')) {
108                part = part.substr(0, part.length - 1);
109                if (!isint.test(part) && isArray(obj)) obj = promote(parent, key);
110                parse(parts, obj, part, val);
111                // key
112            } else {
113                if (!isint.test(part) && isArray(obj)) obj = promote(parent, key);
114                parse(parts, obj, part, val);
115            }
116        }
117    }
118
119    function merge(parent, key, val) {
120        if (~key.indexOf(']')) {
121            var parts = key.split('[');
122            parse(parts, parent, 'base', val);
123        } else {
124            if (!isint.test(key) && isArray(parent.base)) {
125                var t = {};
126                for (var k in parent.base) t[k] = parent.base[k];
127                parent.base = t;
128            }
129            if (key !== '') {
130                set(parent.base, key, val);
131            }
132        }
133        return parent;
134    }
135
136    function parseString(str) {
137        return reduce(String(str).split(/&|;/), function(ret, pair) {
138            try {
139                pair = decodeURIComponent(pair.replace(/\+/g, ' '));
140            } catch(e) {
141                // ignore
142            }
143            var eql = pair.indexOf('='),
144                brace = lastBraceInKey(pair),
145                key = pair.substr(0, brace || eql),
146                val = pair.substr(brace || eql, pair.length);
147
148            val = val.substr(val.indexOf('=') + 1, val.length);
149
150            if (key === '') {
151                key = pair;
152                val = '';
153            }
154
155            return merge(ret, key, val);
156        }, { base: {} }).base;
157    }
158
159    function set(obj, key, val) {
160        var v = obj[key];
161        if (typeof v === 'undefined') {
162            obj[key] = val;
163        } else if (isArray(v)) {
164            v.push(val);
165        } else {
166            obj[key] = [v, val];
167        }
168    }
169
170    function lastBraceInKey(str) {
171        var len = str.length,
172            brace,
173            c;
174        for (var i = 0; i < len; ++i) {
175            c = str[i];
176            if (']' == c) brace = false;
177            if ('[' == c) brace = true;
178            if ('=' == c && !brace) return i;
179        }
180    }
181
182    function reduce(obj, accumulator){
183        var i = 0,
184            l = obj.length >> 0,
185            curr = arguments[2];
186        while (i < l) {
187            if (i in obj) curr = accumulator.call(undefined, curr, obj[i], i, obj);
188            ++i;
189        }
190        return curr;
191    }
192
193    function isArray(vArg) {
194        return Object.prototype.toString.call(vArg) === "[object Array]";
195    }
196
197    function keys(obj) {
198        var key_array = [];
199        for ( var prop in obj ) {
200            if ( obj.hasOwnProperty(prop) ) key_array.push(prop);
201        }
202        return key_array;
203    }
204
205    function purl( url, strictMode ) {
206        if ( arguments.length === 1 && url === true ) {
207            strictMode = true;
208            url = undefined;
209        }
210        strictMode = strictMode || false;
211        url = url || window.location.toString();
212
213        return {
214
215            data : parseUri(url, strictMode),
216
217            // get various attributes from the URI
218            attr : function( attr ) {
219                attr = aliases[attr] || attr;
220                return typeof attr !== 'undefined' ? this.data.attr[attr] : this.data.attr;
221            },
222
223            // return query string parameters
224            param : function( param ) {
225                return typeof param !== 'undefined' ? this.data.param.query[param] : this.data.param.query;
226            },
227
228            // return fragment parameters
229            fparam : function( param ) {
230                return typeof param !== 'undefined' ? this.data.param.fragment[param] : this.data.param.fragment;
231            },
232
233            // return path segments
234            segment : function( seg ) {
235                if ( typeof seg === 'undefined' ) {
236                    return this.data.seg.path;
237                } else {
238                    seg = seg < 0 ? this.data.seg.path.length + seg : seg - 1; // negative segments count from the end
239                    return this.data.seg.path[seg];
240                }
241            },
242
243            // return fragment segments
244            fsegment : function( seg ) {
245                if ( typeof seg === 'undefined' ) {
246                    return this.data.seg.fragment;
247                } else {
248                    seg = seg < 0 ? this.data.seg.fragment.length + seg : seg - 1; // negative segments count from the end
249                    return this.data.seg.fragment[seg];
250                }
251            }
252
253        };
254
255    }
256
257    purl.jQuery = function($){
258        if ($ != null) {
259            $.fn.url = function( strictMode ) {
260                var url = '';
261                if ( this.length ) {
262                    url = $(this).attr( getAttrName(this[0]) ) || '';
263                }
264                return purl( url, strictMode );
265            };
266
267            $.url = purl;
268        }
269    };
270
271    purl.jQuery(window.jQuery);
272
273    return purl;
274
275});
276
277;(function (factory) {
278	var registeredInModuleLoader;
279	if (typeof define === 'function' && define.amd) {
280		define(factory);
281		registeredInModuleLoader = true;
282	}
283	if (typeof exports === 'object') {
284		module.exports = factory();
285		registeredInModuleLoader = true;
286	}
287	if (!registeredInModuleLoader) {
288		var OldCookies = window.Cookies;
289		var api = window.Cookies = factory();
290		api.noConflict = function () {
291			window.Cookies = OldCookies;
292			return api;
293		};
294	}
295}(function () {
296	function extend () {
297		var i = 0;
298		var result = {};
299		for (; i < arguments.length; i++) {
300			var attributes = arguments[ i ];
301			for (var key in attributes) {
302				result[key] = attributes[key];
303			}
304		}
305		return result;
306	}
307
308	function decode (s) {
309		return s.replace(/(%[0-9A-Z]{2})+/g, decodeURIComponent);
310	}
311
312	function init (converter) {
313		function api() {}
314
315		function set (key, value, attributes) {
316			if (typeof document === 'undefined') {
317				return;
318			}
319
320			attributes = extend({
321				path: '/'
322			}, api.defaults, attributes);
323
324			if (typeof attributes.expires === 'number') {
325				attributes.expires = new Date(new Date() * 1 + attributes.expires * 864e+5);
326			}
327
328			// We're using "expires" because "max-age" is not supported by IE
329			attributes.expires = attributes.expires ? attributes.expires.toUTCString() : '';
330
331			try {
332				var result = JSON.stringify(value);
333				if (/^[\{\[]/.test(result)) {
334					value = result;
335				}
336			} catch (e) {}
337
338			value = converter.write ?
339				converter.write(value, key) :
340				encodeURIComponent(String(value))
341					.replace(/%(23|24|26|2B|3A|3C|3E|3D|2F|3F|40|5B|5D|5E|60|7B|7D|7C)/g, decodeURIComponent);
342
343			key = encodeURIComponent(String(key))
344				.replace(/%(23|24|26|2B|5E|60|7C)/g, decodeURIComponent)
345				.replace(/[\(\)]/g, escape);
346
347			var stringifiedAttributes = '';
348			for (var attributeName in attributes) {
349				if (!attributes[attributeName]) {
350					continue;
351				}
352				stringifiedAttributes += '; ' + attributeName;
353				if (attributes[attributeName] === true) {
354					continue;
355				}
356
357				// Considers RFC 6265 section 5.2:
358				// ...
359				// 3.  If the remaining unparsed-attributes contains a %x3B (";")
360				//     character:
361				// Consume the characters of the unparsed-attributes up to,
362				// not including, the first %x3B (";") character.
363				// ...
364				stringifiedAttributes += '=' + attributes[attributeName].split(';')[0];
365			}
366
367			return (document.cookie = key + '=' + value + stringifiedAttributes);
368		}
369
370		function get (key, json) {
371			if (typeof document === 'undefined') {
372				return;
373			}
374
375			var jar = {};
376			// To prevent the for loop in the first place assign an empty array
377			// in case there are no cookies at all.
378			var cookies = document.cookie ? document.cookie.split('; ') : [];
379			var i = 0;
380
381			for (; i < cookies.length; i++) {
382				var parts = cookies[i].split('=');
383				var cookie = parts.slice(1).join('=');
384
385				if (!json && cookie.charAt(0) === '"') {
386					cookie = cookie.slice(1, -1);
387				}
388
389				try {
390					var name = decode(parts[0]);
391					cookie = (converter.read || converter)(cookie, name) ||
392						decode(cookie);
393
394					if (json) {
395						try {
396							cookie = JSON.parse(cookie);
397						} catch (e) {}
398					}
399
400					jar[name] = cookie;
401
402					if (key === name) {
403						break;
404					}
405				} catch (e) {}
406			}
407
408			return key ? jar[key] : jar;
409		}
410
411		api.set = set;
412		api.get = function (key) {
413			return get(key, false /* read as raw */);
414		};
415		api.getJSON = function (key) {
416			return get(key, true /* read as json */);
417		};
418		api.remove = function (key, attributes) {
419			set(key, '', extend(attributes, {
420				expires: -1
421			}));
422		};
423
424		api.defaults = {};
425
426		api.withConverter = init;
427
428		return api;
429	}
430
431	return init(function () {});
432}));
433
434// Chapter 3: detikLiveUserCounterResponse Context as ctx
435var detikLiveUserCounterResponse = {};
436
437(function(ctx) {
438
439  ctx.headerInfo = '[detikLiveUserCounterResponse]';
440  ctx.version    = 'v1.13';
441
442  ctx.baseDomain = function() {
443    result = '';
444    var hostname = window.location.hostname;
445    var perdots = hostname.split('.');
446    if (perdots.length >= 3) {
447      result = '.' + perdots[1] + '.' + perdots[2];
448    } else {
449      result = '.' + hostname;
450   }
451    return result;
452  }
453
454  ctx.config = {
455    enableConsoleLog: false,
456    timeInterval: 30000,
457    channel: 'counterview',
458    domain: window.location.hostname,
459    user: '',
460    trackerid: '',
461    enableGetCounter: true,
462    getCounterUrl: 'https://parsley.detik.com/dtnct',
463    getCounterReadOnlyUrl: 'https://parsley.detik.com/dtnctv',
464    successCallback: null,
465    errorCallback: null,
466    enableTheTracker: false,
467    theTrackerUrl: 'https://cdn.detik.net.id/loganalysistracker/thetracker-detik-v3.min.js',
468    persistentMode: true,
469    userPrefix: 'gen_',
470    mobilePrefix: 'genm_',
471    dtmaCookieName: '__dtma',
472    dtklucCookieName: 'dtklucx',
473    dtklucCookieAttribute: { domain: ctx.baseDomain(), path: '/', expires: 365 }, // satuan expires adalah Hari
474    dtklucCookieAttributeRead: { domain: ctx.baseDomain(), path: '/' },
475    dtklucDbgCookieName: 'dtklucdbg',
476    dtklucDbgCookieAttributeRead: { domain: ctx.baseDomain(), path: '/' },    
477    startDelay: 6000,
478    startDelayForResponse: 1000, // parent
479    startDelayForRequest: 2000, // embed
480    readOnly: false,
481    requestWinPostMsg: true,
482    responseWinPostMsg: true,
483    requestWinPostData: { dtklucreq: 1 },
484    responseWinPostData: { dtklucuser: null, dtkluctrackerid: null, dtklucdomain: null, dtklucchannel: null },
485    requestWinPostTargetWindow: '*',
486    responseWinPostTargetWindow: '*',
487    winPostDataRewriteUserId: true,
488    winPostDataRewriteTrackerId: true,
489    winPostDataRewriteDomain: true,
490    winPostDataRewriteChannel: false,
491    waitingResponseWinPostMsg: 6000,
492    ajaxSetupCache: false,
493    ajaxSetupASync: true,
494    noHit: true,
495    sendJsUrl: false,
496    bodyLogger: false,
497    scriptMarker: 'detikLiveUserCounter',
498    mobileIdAvoidingMarker: 'ADVERTISING_IDENTIFIER_PLAIN'
499  };
500
501  ctx.inputConfig = {};
502
503  ctx.vars = {
504    timeIntervalHandler: null,
505    getCounterData: null,
506    isTheTrackerHasBeenLoaded: false,
507    startDelayNow: false,
508    messageAddListenerLock: false,
509    dataWinPostMsgIsOK: false,
510    haltedRequestWinPostMsg: false,
511    firstStart: false,
512    playIsSent: false,
513    playIsOccur: false,
514    mobileId: '',
515    mobileType: '',
516    mobileLat: '',
517    scriptSrcUrl: null,
518    isMobileMacrosExist: false
519  };
520
521  ctx.log = function(txtLog, txtVal) {
522    if (ctx.config.enableConsoleLog === true) {
523      try {
524        if (((typeof txtVal) === 'undefined') || (txtVal === null)) {
525          console.log(ctx.headerInfo + ' ' + txtLog);
526          if (ctx.config.bodyLogger === true) {
527            var nodeP = document.createElement('p');
528            var textNodeP = document.createTextNode(ctx.headerInfo + ' ' + txtLog);
529            nodeP.appendChild(textNodeP);
530            document.body.appendChild(nodeP);
531          }
532        } else {
533          console.log(ctx.headerInfo + ' ' + txtLog, txtVal);
534          if (ctx.config.bodyLogger === true) {
535            var nodeP = document.createElement('p');
536            var textNodeP = document.createTextNode(ctx.headerInfo + ' ' + txtLog + ' , ' + JSON.stringify(txtVal));
537            nodeP.appendChild(textNodeP);
538            document.body.appendChild(nodeP);
539          }
540        }
541      } catch (ex) {
542      }
543    }
544  };
545
546  ctx.logx = function(txtLog, txtVal) {
547    try {
548      if (((typeof txtVal) === 'undefined') || (txtVal === null)) {
549        console.log(ctx.headerInfo + ' ' + txtLog);
550        if (ctx.config.bodyLogger === true) {
551          var nodeP = document.createElement('p');
552          var textNodeP = document.createTextNode(ctx.headerInfo + ' ' + txtLog);
553          nodeP.appendChild(textNodeP);
554          document.body.appendChild(nodeP);
555        }
556      } else {
557        console.log(ctx.headerInfo + ' ' + txtLog, txtVal);
558        if (ctx.config.bodyLogger === true) {
559          var nodeP = document.createElement('p');
560          var textNodeP = document.createTextNode(ctx.headerInfo + ' ' + txtLog + ' , ' + JSON.stringify(txtVal));
561          nodeP.appendChild(textNodeP);
562          document.body.appendChild(nodeP);
563        }
564      }
565    } catch (ex) {
566    }
567  };
568
569  ctx.uniqueId = function (prefix) {
570    // https://gist.github.com/gordonbrander/2230317
571    // NOTE: This format of 8 chars, followed by 3 groups of 4 chars, followed by 12 chars
572    //       is known as a UUID and is defined in RFC4122 and is a standard for generating unique IDs.
573    //       This function DOES NOT implement this standard. It simply outputs a string
574    //       that looks similar. The standard is found here: https://www.ietf.org/rfc/rfc4122.txt
575    if (prefix === null) {
576      prefix = '_';
577    }
578    function chr4(){
579      return Math.random().toString(16).slice(-4);
580    }
581    return prefix + chr4() + chr4() +
582      '-' + chr4() +
583      '-' + chr4() +
584      '-' + chr4() +
585      '-' + chr4() + chr4() + chr4();
586  };
587
588  ctx.getScriptSrc = function() {
589    var result = null;
590    $.each($('script'), function(i, v) {
591      if (v.src.indexOf(ctx.config.scriptMarker) !== -1) {
592        result = v.src;
593      };
594    });
595    return result;
596  };
597
598  ctx.getMobileMacros = function() {
599    try {
600      if (ctx.vars.scriptSrcUrl !== null) {
601        //ctx.log('re-announcement, version is', ctx.version);
602        var mobileIdCheck = $.url(ctx.vars.scriptSrcUrl).param('mobileid');
603        var mobileIdCheck2 = $.url(ctx.vars.scriptSrcUrl).fparam('mobileid');
604        if ( ((typeof mobileIdCheck) === 'string') && (mobileIdCheck !== '') && (mobileIdCheck.indexOf(ctx.config.mobileIdAvoidingMarker) === -1 ) ) {
605          ctx.vars.mobileId   = mobileIdCheck;
606          ctx.vars.mobileType = $.url(ctx.vars.scriptSrcUrl).param('mobiletype');
607          ctx.vars.mobileLat  = $.url(ctx.vars.scriptSrcUrl).param('mobilelat');
608          ctx.config.user     = ctx.config.mobilePrefix + MD5(ctx.vars.mobileId + ';' + ctx.vars.mobileType + ';' + ctx.vars.mobileLat);
609          ctx.vars.isMobileMacrosExist = true;
610          ctx.log('getMobileMacros param mobileid is', ctx.vars.mobileId);
611          ctx.log('getMobileMacros param mobiletype is', ctx.vars.mobileType);
612          ctx.log('getMobileMacros param mobilelat is', ctx.vars.mobileLat);
613          ctx.log('getMobileMacros param user is', ctx.config.user);
614        } else if ( ((typeof mobileIdCheck2) === 'string') && (mobileIdCheck2 !== '') && (mobileIdCheck2.indexOf(ctx.config.mobileIdAvoidingMarker) === -1 ) ) {
615          ctx.vars.mobileId   = mobileIdCheck2;
616          ctx.vars.mobileType = $.url(ctx.vars.scriptSrcUrl).fparam('mobiletype');
617          ctx.vars.mobileLat  = $.url(ctx.vars.scriptSrcUrl).fparam('mobilelat');
618          ctx.config.user     = ctx.config.mobilePrefix + MD5(ctx.vars.mobileId + ';' + ctx.vars.mobileType + ';' + ctx.vars.mobileLat);
619          ctx.vars.isMobileMacrosExist = true;
620          ctx.log('getMobileMacros fparam mobileid is', ctx.vars.mobileId);
621          ctx.log('getMobileMacros fparam mobiletype is', ctx.vars.mobileType);
622          ctx.log('getMobileMacros fparam mobilelat is', ctx.vars.mobileLat);
623          ctx.log('getMobileMacros fparam user is', ctx.config.user);
624        }
625      }
626    } catch (ex) {
627    };
628  };
629
630  ctx.configProcess = function() {
631    $.each(ctx.config, function (idx, val) {
632      if (((typeof ctx.inputConfig) !== 'undefined') && (ctx.inputConfig !== null)) {
633        if ((typeof ctx.inputConfig[idx]) !== 'undefined') {
634          ctx.config[idx] = ctx.inputConfig[idx];
635        }
636      }
637    });
638    //ctx.log('configProcess config is', ctx.config);
639  };
640
641  ctx.readBodyLoggerMarker = function() {
642    try {
643      if (ctx.vars.scriptSrcUrl !== null) {
644        var bodyLogger = $.url(ctx.vars.scriptSrcUrl).param('bodylogger');
645        var bodyLogger2 = $.url(ctx.vars.scriptSrcUrl).fparam('bodylogger');
646        if ( (typeof bodyLogger === 'string') && (bodyLogger === 'true') ) {
647          ctx.config.bodyLogger = true;
648          ctx.log('readBodyLoggerMarker param got the mark, we work as Body Logger now', null);
649        } else if ( (typeof bodyLogger2 === 'string') && (bodyLogger2 === 'true') ) {
650          ctx.config.bodyLogger = true;
651          ctx.log('readBodyLoggerMarker fparam got the mark, we work as Body Logger now', null);
652        }
653      }
654    } catch (ex) {
655    }
656  }
657
658  ctx.setConfig = function(config) {
659    if ($.type(config) === 'object') {
660      ctx.log('setConfig is working', null);
661      ctx.vars.scriptSrcUrl = ctx.getScriptSrc();
662      ctx.readBodyLoggerMarker();
663      ctx.inputConfig = config;
664      ctx.configProcess();
665      ctx.config.user = ctx.uniqueId(ctx.config.userPrefix);
666      ctx.getMobileMacros();
667      if (ctx.config.requestWinPostMsg === true) {
668        ctx.config.startDelay = ctx.config.startDelayForRequest;
669      }
670      if (ctx.config.responseWinPostMsg === true) {
671        ctx.config.startDelay = ctx.config.startDelayForResponse;
672      }
673    }
674  };
675
676  ctx.getScriptTemplate = function(gsUrl, gsNextFunction, gsStatusOK) {
677    $.ajaxSetup( { async: true , cache: true } );
678    $.getScript(gsUrl, function() {
679      if ((typeof gsStatusOK) === 'function') {
680        gsStatusOK();
681      }
682      if ((typeof gsNextFunction) === 'function') {
683        gsNextFunction();
684      }
685      $.ajaxSetup( { async: true , cache: false } ); // reset ajax config
686    }).fail(function() {
687      ctx.log('calls failed', gsUrl);
688      if ((typeof gsStatusOK) === 'function') {
689        gsStatusOK();
690      }
691      $.ajaxSetup( { async: true , cache: false } ); // reset ajax config
692      if ((typeof gsNextFunction) === 'function') {
693        gsNextFunction();
694      }
695    });
696  };
697
698  ctx.gsTheTracker = function() {
699    if ((ctx.config.enableTheTracker === true) && (ctx.vars.isTheTrackerHasBeenLoaded === false)) {
700      ctx.log('gsTheTracker lib caller', null);
701      ctx.getScriptTemplate(ctx.config.theTrackerUrl, ctx.start2, null);
702    }
703  };
704
705  ctx.start2 = function() {
706    if ((ctx.config.enableTheTracker === true) && (ctx.vars.isTheTrackerHasBeenLoaded === false)) {
707      ctx.vars.isTheTrackerHasBeenLoaded = true;
708      ctx.log('start2 is working', null);
709      var metas = document.getElementsByTagName("meta");
710      try {
711        detikTracker.call(null, metas);
712        ctx.log('start2 detikTracker call is running', null);
713        var dtma = Cookies.get(ctx.config.dtmaCookieName, ctx.config.dtklucCookieAttributeRead);
714        if ((typeof dtma === 'string') && (dtma !== '')) {
715          ctx.config.trackerid = dtma;
716          ctx.log('start2 got __dtma', ctx.config.trackerid);
717          ctx.start1();
718        } else {
719          if (ctx.config.persistentMode === true) {
720            ctx.start1();
721          } else {
722            ctx.log('start2 didnt get __dtma, halted', null);
723          }
724        }
725      } catch (error) {
726        ctx.log('start2 detikTracker call got an error', null);
727        if (ctx.config.persistentMode === true) {
728          ctx.start1();
729        } else {
730          ctx.log('start2 didnt get __dtma, halted', null);
731        }
732      }
733    }
734  };
735
736  ctx.start1 = function() {
737    if (ctx.config.noHit === false) {
738      if (ctx.vars.timeIntervalHandler === null) {
739        ctx.log('start1 is working', null);
740        var domain2 = '';
741        try {
742          if ((document.referrer !== null) && (document.referrer !== undefined)) {
743            var referrer = document.referrer;
744            domain2 = (new URL(referrer)).hostname;
745          }
746        } catch (ex) {
747        }
748        var embedUrl = '';
749        if (ctx.config.sendJsUrl === true) {
750          embedUrl = '&url=' + encodeURIComponent(window.location);
751        }
752        ctx.vars.getCounterData = 
753          'chanel=' + encodeURIComponent(ctx.config.channel) + 
754          '&user=' + encodeURIComponent(ctx.config.user) +
755          '&trackerid=' + encodeURIComponent(ctx.config.trackerid) +
756          '&domain=' + encodeURIComponent(ctx.config.domain) +
757          '&domain2=' + encodeURIComponent(domain2) + 
758          embedUrl;
759        //ctx.log('getCounterData', ctx.vars.getCounterData);
760        ctx.getCounter(); // first encounter !
761        if ((ctx.vars.playIsOccur === true) && (ctx.vars.playIsSent === false)) {
762          ctx.getCounter(); // sent immediately play event
763        }
764        ctx.vars.timeIntervalHandler = setInterval(function() {
765          ctx.getCounter();
766          if ((ctx.vars.playIsOccur === true) && (ctx.vars.playIsSent === false)) {
767            ctx.getCounter(); // sent immediately play event
768          }
769        }, ctx.config.timeInterval);
770      }
771    } else {
772      ctx.log('start1 uses noHit, only responseWinPostMsg (if it is true) will run in message listener', null);
773    }
774  };
775
776  ctx.start0 = function() {
777    // get dtkluc if failed then use generated userid
778    if ((ctx.config.enableTheTracker === true) && (ctx.vars.isTheTrackerHasBeenLoaded === false)) {
779      ctx.log('start0 load theTracker to create __dtma', null);
780      ctx.gsTheTracker();
781    } else {
782      ctx.log('start0 read __dtma as trackerid', null);
783      var dtma = Cookies.get(ctx.config.dtmaCookieName, ctx.config.dtklucCookieAttributeRead);
784      if ((typeof dtma === 'string') && (dtma !== '')) {
785        ctx.config.trackerid = dtma;
786        ctx.log('start0 got __dtma, trackerid value is', ctx.config.trackerid);
787      }
788      ctx.log('start0 read dtkluc', null);
789      var dtkluc = Cookies.get(ctx.config.dtklucCookieName, ctx.config.dtklucCookieAttributeRead);
790      if ((typeof dtkluc === 'string') && (dtkluc !== '')) {
791        ctx.config.user = dtkluc;
792        ctx.log('start0 got dtkluc, user value is', ctx.config.user);
793        if (ctx.config.requestWinPostMsg === true) {
794          // get ctx.config.user and ctx.config.domain from parent iframe
795          ctx.requestWinPostMsg();
796        } else {
797          ctx.start1();
798        }
799      } else {
800        ctx.log('start0 unable to read dtkluc, user value is', ctx.config.user);
801        Cookies.set(ctx.config.dtklucCookieName, ctx.config.user, ctx.config.dtklucCookieAttribute);
802        if (ctx.config.requestWinPostMsg === true) {
803          // get ctx.config.user and ctx.config.domain from parent iframe
804          ctx.requestWinPostMsg();
805        } else {
806          ctx.start1();
807        }
808      }
809    }
810  };
811
812  ctx.start = function() {
813    ctx.logx('start is working, version is', ctx.version);
814    // read dbg sign
815    var dbgSign = Cookies.get(ctx.config.dtklucDbgCookieName, ctx.config.dtklucDbgCookieAttributeRead);
816    if (dbgSign === '1') {
817      ctx.config.enableConsoleLog = true;
818    }
819    // end read dbg sign
820    if (ctx.vars.startDelayNow === false) {
821      ctx.vars.startDelayNow = true;
822      ctx.log('start uses startDelay', ctx.config.startDelay);
823      setTimeout(function() {
824        ctx.vars.startDelayNow = false;
825        ctx.log('start uses startDelay is over', null);
826        ctx.log('start config is', ctx.config);
827        ctx.messageAddListenerInit();
828        ctx.start0();
829      }, ctx.config.startDelay);
830    } else {
831      ctx.log('start said that startDelay is busy!', null);
832    }
833  };
834
835  ctx.messageAddListenerInit = function() {
836    if (ctx.vars.messageAddListenerLock === false) {
837      ctx.log('messageAddListenerInit is working', null);
838      ctx.vars.messageAddListenerLock = true;
839      if (ctx.config.requestWinPostMsg === true) {
840        window.addEventListener('message', function(event) {
841          if (ctx.vars.haltedRequestWinPostMsg === false) {
842            ctx.log('messageAddListenerInit requestWinPostMsg window listener is working', null);
843            var responseData = event.data;
844            if ((ctx.config.winPostDataRewriteUserId === true) && (typeof responseData === 'object') && (responseData !== null) && (responseData.hasOwnProperty('dtklucuser')) ) {
845              ctx.config.user = responseData.dtklucuser;
846              ctx.vars.dataWinPostMsgIsOK = true;
847              ctx.vars.haltedRequestWinPostMsg = true;
848            }
849            if ((ctx.config.winPostDataRewriteTrackerId === true) && (typeof responseData === 'object') && (responseData !== null) && (responseData.hasOwnProperty('dtkluctrackerid')) ) {
850              ctx.config.trackerid = responseData.dtkluctrackerid;
851            }
852            if ((ctx.config.winPostDataRewriteDomain === true) && (typeof responseData === 'object') && (responseData !== null) && (responseData.hasOwnProperty('dtklucdomain')) ) {
853              ctx.config.domain = responseData.dtklucdomain;
854            }
855            if ((ctx.config.winPostDataRewriteChannel === true) && (typeof responseData === 'object') && (responseData !== null) && (responseData.hasOwnProperty('dtklucchannel')) ) {
856              ctx.config.channel = responseData.dtklucchannel;
857            }
858            if (ctx.vars.dataWinPostMsgIsOK === true) {
859              ctx.log('messageAddListenerInit requestWinPostMsg got responseData',  responseData);
860              setTimeout(function() {
861                ctx.start1();
862              }, 0);
863            }
864          }
865        });
866      }
867      if (ctx.config.responseWinPostMsg === true) {
868        window.addEventListener('message', function(event) {
869          //ctx.log('messageAddListenerInit responseWinPostMsg window listener is working', null);
870          var requestData = event.data;
871          if ((typeof requestData === 'object') && (requestData !== null) && (requestData.hasOwnProperty('dtklucreq') === true) && (requestData.dtklucreq === 1)) {
872            var responseData = ctx.config.responseWinPostData;
873            responseData.dtklucuser = ctx.config.user;
874            responseData.dtkluctrackerid = ctx.config.trackerid;
875            responseData.dtklucdomain = ctx.config.domain;
876            responseData.dtklucchannel = ctx.config.channel;
877            var iframes = document.getElementsByTagName('iframe');
878            ctx.log('messageAddListenerInit responseWinPostMsg iframes', iframes);
879            $.each(iframes, function(idx, val) {
880              try { 
881                val.contentWindow.postMessage(responseData, ctx.config.responseWinPostTargetWindow);
882                ctx.log('messageAddListenerInit responseWinPostMsg already sent', null);
883              } catch (ex) {
884                ctx.log('messageAddListenerInit responseWinPostMsg is failed!', null);
885              }
886            });
887          }
888        });
889      }
890    }
891  };
892
893  ctx.requestWinPostMsg = function() {
894    if (ctx.config.requestWinPostMsg === true) {
895      try {
896        ctx.log('requestWinPostMsg is working', null);
897        window.parent.postMessage(ctx.config.requestWinPostData, ctx.config.requestWinPostTargetWindow);
898      } catch (ex) {
899        ctx.log('requestWinPostMsg is failed!', null);
900      }
901      setTimeout(function() {
902        if (ctx.vars.dataWinPostMsgIsOK === false) {
903          ctx.log('requestWinPostMsg no-more waiting window.postMessage, get cookie now!', null);
904          ctx.vars.haltedRequestWinPostMsg = true;
905          ctx.start1();
906        }
907      }, ctx.config.waitingResponseWinPostMsg);
908    }
909  };
910
911  ctx.getCounter = function() {
912    if (ctx.config.enableGetCounter === true) {
913      var getCounterUrl = null;
914      var ajaxType = null;
915      var ajaxContentType = null;
916      var ajaxData = null;
917      var playingData = '';
918      if (ctx.vars.playIsSent === true) {
919        playingData = '&event=playing';
920      }
921      var firstPlayData = '';
922      if ((ctx.vars.firstStart === true) && (ctx.vars.playIsOccur === true) && (ctx.vars.playIsSent === false)) {
923        ctx.vars.playIsSent = true;
924        firstPlayData = '&event=play';
925      }
926      var firstStartData = '';
927      if (ctx.vars.firstStart === false) {
928        ctx.vars.firstStart = true;
929        firstStartData = '&event=start';
930      }
931      if (ctx.config.readOnly === true) {
932        ajaxType = 'GET';
933        ajaxContentType = 'application/x-www-form-urlencoded';
934        ajaxData = ctx.vars.getCounterData + firstStartData + firstPlayData + playingData;
935        getCounterUrl = ctx.config.getCounterReadOnlyUrl;
936      } else {
937        ajaxType = 'POST';
938        ajaxContentType = 'application/x-www-form-urlencoded';
939        ajaxData = ctx.vars.getCounterData + firstStartData + firstPlayData + playingData;
940        getCounterUrl = ctx.config.getCounterUrl;
941      }
942      ctx.log('getCounter is working', getCounterUrl);
943      ctx.log('getCounter ajaxData', ajaxData);
944      $.ajaxSetup( { async: ctx.config.ajaxSetupASync , cache: ctx.config.ajaxSetupCache } );
945      $.ajax({
946        type: ajaxType,
947        url: getCounterUrl,
948        data: ajaxData,
949        contentType: ajaxContentType,
950        success: function(successMsg) {
951          ctx.log('getCounter success-event', successMsg);
952          if (typeof ctx.config.successCallback === 'function') {
953            ctx.config.successCallback(successMsg);
954          }
955        },
956        error: function(errorMsg) {
957          ctx.log('getCounter error-event', errorMsg);
958          if (typeof ctx.config.errorCallback === 'function') {
959            ctx.config.errorCallback(errorMsg);
960          }
961        }
962      });
963    }
964  };
965  
966  ctx.stop = function() {
967    if (ctx.vars.timeIntervalHandler !== null) {
968      ctx.log('stop is working', null);
969      clearInterval(ctx.vars.timeIntervalHandler);
970      ctx.vars.timeIntervalHandler = null;
971    }
972  };
973
974  ctx.pause = function() {
975    ctx.log('pause is working', null);
976    ctx.config.enableGetCounter = false;
977  };
978
979  ctx.resume = function() {
980    ctx.log('resume is working', null);
981    ctx.config.enableGetCounter = true;
982  };
983
984  ctx.play = function() {
985    ctx.log('play is working', null);
986    ctx.vars.playIsOccur = true;
987  };
988
989})(detikLiveUserCounterResponse);
990
991// for using it, please call these lines :
992// detikLiveUserCounterResponse.setConfig({ .. });
993// detikLiveUserCounterResponse.start();
994
995//autorun config and start
996
997detikLiveUserCounterResponse.setConfig({
998  enableConsoleLog: false,
999  requestWinPostMsg: true,  // requestWinPostMsg true and responseWinPostMsg true means PROXY
1000  responseWinPostMsg: true, // requestWinPostMsg true and responseWinPostMsg true means PROXY
1001  noHit: true
1002});
1003
1004detikLiveUserCounterResponse.start();
1005

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.