PageSourceSearch

https://zdorovoe-pohudenie.ru/pl/nassets/b9c49911/js/main.js?v=1791371895

js zdorovoe-pohudenie.ru collected 2026-10-07 23:27:22 UTC 37,254 bytes, 1,236 lines download raw bytes

1var ajaxCallAutoCsrfRoutes = [
2	'/teach/control/stream/saveChanges',
3	'/teach/control/stream',
4	'/teach/control',
5];
6
7function ajaxCall(url, data, options, successCallback, completeCallback, errorCallback) {
8    if ( ! options ) {
9        options = {};
10    }
11    if (options.useQueue) {
12        ajaxCallQueue.request(url, data, options, successCallback, completeCallback);
13        return;
14    }
15
16    var suppressErrors = undefined === options.suppressErrors ? false :options.suppressErrors;
17	var enableSimpleSign = undefined === options.enableSimpleSign ? false :options.enableSimpleSign;
18	const suppressNotify = options.suppressNotify || false;
19
20    if ( options.btn ) {
21        options.btn.attr( 'disabled', 'disabled' );
22    }
23    var method = "post";
24    if ( options.method ) {
25        method = options.method;
26    }
27
28	var enableCsrf = options.enableCsrf === undefined ? false : options.enableCsrf;
29	if (typeof options.enableCsrf === 'undefined' && String(method).toLowerCase() !== 'get') {
30		var csrfPath = String(url).split('#')[0].split('?')[0];
31		var csrfOriginMatch = csrfPath.match(/^https?:\/\/[^\/]+(\/.*)$/);
32		if (csrfOriginMatch) {
33			csrfPath = csrfOriginMatch[1];
34		}
35		for (var csrfRouteIndex = 0; csrfRouteIndex < ajaxCallAutoCsrfRoutes.length; csrfRouteIndex++) {
36			var csrfRoute = ajaxCallAutoCsrfRoutes[csrfRouteIndex];
37			if (csrfPath === csrfRoute || csrfPath.indexOf(csrfRoute + '/') === 0) {
38				enableCsrf = true;
39				break;
40			}
41		}
42	}
43
44    if (enableCsrf && window.csrfToken !== undefined) {
45		if (typeof data === 'object') {
46			data['_csrf'] = window.csrfToken;
47		}
48		else if (typeof data === 'string') {
49			data += '&_csrf='+window.csrfToken;
50        }
51    }
52	if (enableSimpleSign && window.requestTime !== undefined && window.requestSimpleSign !== undefined) {
53		if (typeof data === 'object') {
54			data['requestTime'] = window.requestTime;
55			data['requestSimpleSign'] = window.requestSimpleSign;
56		}
57		else if (typeof data === 'string') {
58			data += '&requestTime='+window.requestTime;
59			data += '&requestSimpleSign='+window.requestSimpleSign;
60		}
61	}
62	if ( typeof(Storage) !== 'undefined' ) {
63		try {
64			var session = localStorage.getItem('session');
65			var visit = localStorage.getItem('visit');
66			var visitor = localStorage.getItem('visitor');
67			var hash = localStorage.getItem('hash');
68			if (session && hash) {
69				if (typeof data === 'object') {
70					data['gcSession'] = session;
71					data['gcVisit'] = visit;
72					data['gcVisitor'] = visitor;
73					data['gcSessionHash'] = hash;
74				} else if (typeof data === 'string') {
75					data += '&gcSession=' + session;
76					data += '&gcVisit=' + visit;
77					data += '&gcVisitor=' + visitor;
78					data += '&gcSessionHash=' + hash;
79				}
80			}
81		} catch (e) {
82			// В режиме блокирования кук (как минимум хром) бросает ошибку при доступе к
83			// localStorage, хотя объект определен
84		}
85	}
86
87    var async = true;
88    if (options.async === false) {
89        async = false;
90    }
91
92    var params = {
93        url: url,
94        type: method,
95        data: data,
96        async: async,
97        complete: function ( jqResponse, status ) {
98
99            error_text_value = 'Ошибка';
100            if (typeof Yii != 'undefined') {
101                error_text_value = Yii.t( "common", "Error" );
102            }
103
104            if ( options.btn ) {
105                options.btn.removeAttr( 'disabled' );
106            }
107
108            try {
109                response = $.parseJSON(jqResponse.responseText);
110            } catch (exception) {
111                response = jqResponse;
112                response.success = false;
113                response.message = "Неизвестная ошибка";
114            }
115
116			if (status === 'success') {
117                if ( response.success ) {
118					if (!suppressNotify && response.message && response.message.length > 0) {
119                        var message = response.message;
120                        var messageOptions = { type: "success" };
121                        if (window.isPageRedesigned) {
122                            showRedesignAlert('success', message)
123                        } else {
124                            if ( $.toast ) {
125                                $.toast.config.width = Math.min(500, $(window).width() * 0.95);
126                                $.toast(message, messageOptions);
127                            }
128                            else {
129                                console.log(message);
130                            }
131                        }
132                    }
133                    if ( successCallback ) {
134                        successCallback( response );
135                    }
136                }
137                else {
138                    if ( !suppressErrors ) {
139                        if (window.isPageRedesigned && typeof showRedesignAlert === 'function') {
140                            showRedesignAlert('danger', response.message)
141                        } else {
142                            if ( $.toast ) {
143                                $.toast.config.width = Math.min(500, $(window).width() * 0.95);
144                                if (response.only_last_error) {
145                                    $('.toast .danger').remove();
146                                }
147                                $.toast(error_text_value + ": " + response.message, {
148                                    type: "danger",
149                                    sticky: response.toast_sticky === true,
150                                });
151                            } else {
152                                alert(response.message);
153                            }
154                        }
155
156                    }
157                    if (errorCallback) {
158                        errorCallback(response);
159                    }
160                }
161            }
162            else {
163                if ( jqResponse.readyState == 0 ) {
164                    return;
165                }
166                if ( !suppressErrors ) {
167                    if ($.toast) {
168                        $.toast.config.width = Math.min(500, $(window).width() * 0.95);
169                        $.toast(  error_text_value + ": " + jqResponse.statusText, {type: "danger"});
170                    } else {
171						alert(response.message);
172                    }
173                }
174				console.error('error', jqResponse.statusText);
175				console.error(jqResponse.responseText);
176                if (errorCallback) {
177                    errorCallback(response);
178                }
179            }
180            if (completeCallback) {
181                completeCallback(response);
182            }
183        }
184    };
185
186    if (options.crossDomain) {
187        params.crossDomain = true;
188    }
189
190    $.ajax(params);
191}
192
193var ajaxCallQueue = new (function () {
194    /** @private */
195    let self = this;
196
197    this.limit = 4;
198    /** @private */
199    this.active = 0;
200    /** @private */
201    this.queue = [];
202
203    this.request = function (url, data, options, successCallback, completeCallback) {
204        this.queue.push({
205            url: url,
206            data: data,
207            options: options,
208            successCallback: successCallback,
209            completeCallback: completeCallback
210        });
211        this.processQueue();
212    }
213
214    /**
215     * @private
216     */
217    this.processQueue = function () {
218        if (this.queue.length === 0) {
219            return;
220        }
221
222        if (this.active >= this.limit) {
223            return;
224        }
225
226        this.active++;
227        let request = this.queue.shift();
228        request.options.useQueue = false;
229
230        ajaxCall(
231            request.url,
232            request.data,
233            request.options,
234            function (response) {
235                try {
236                    request.successCallback(response);
237                } catch ($e) {
238                    console.error($e);
239                }
240            },
241            function () {
242                if (request.completeCallback) {
243                    try {
244                        request.completeCallback();
245                    } catch ($e) {
246                        console.error($e);
247                    }
248                }
249                self.active--;
250                self.processQueue();
251            },
252        );
253    }
254})();
255
256function bodyScrollTo( $el, padding ) {
257    if (  padding  == null ) {
258        padding = 400;
259    }
260    $( "body,html" ).animate({
261        scrollTop: Math.round( $el.offset().top ) - padding
262    }, 200 );
263}
264
265
266
267function initUploadify( $fileElem, options ) {
268
269    var defaultButtonText = Yii.t('common', 'Добавить файлы');
270    if ( $fileElem.attr( 'title') ) {
271        defaultButtonText = $fileElem.attr( 'title');
272    }
273    var url = options.url ? options.url : (
274        '/fileservice/widget/upload?deprecated=17'
275            + '&secure=' + window.isEnabledSecureUpload
276            + '&host=' + window.fileserviceUploadHost
277    );
278    var finalOptions = {
279        auto: true,
280        buttonText: options.buttonText ? options.buttonText : defaultButtonText,
281        width: options.width ? options.width : 200,
282        itemTemplate: options.itemTemplate ? options.itemTemplate : false,
283        fileSizeLimit: options.fileSizeLimit ? options.fileSizeLimit : '2GB',
284        formData: {
285            userId: options.userId
286        },
287        uploadScript: url,
288        onUploadError: function (file, errorCode, errorMsg) {
289            alert("ERROR");
290        },
291        onUploadComplete: options.onUploadComplete ? options.onUploadComplete : function (e, res) {
292            $hiddenInputEl = $(options.valueElemSelector);
293            oldVal = $hiddenInputEl.val();
294            newVal = oldVal;
295            if (newVal && newVal.length > 0) {
296                newVal += ",";
297            }
298            newVal += res;
299
300            $hiddenInputEl.val(newVal);
301            //location.href = location.href;
302        },
303        multi: options.hasOwnProperty('multi') ? options.multi : true
304    };
305    if (options.onQueueComplete) {
306        finalOptions.onQueueComplete = options.onQueueComplete;
307    }
308    if (options.onUpload) {
309        finalOptions.onUpload = options.onUpload;
310    } else if (window.isEnabledSecureUpload && window.fileserviceUploadHost) {
311        finalOptions.onUpload = getUploadifySecretLink;
312    }
313
314    if (options.other) {
315        $.each(options.other, function(key, callback) {
316            finalOptions[key] = callback;
317        });
318    }
319    $fileElem.uploadifive(finalOptions);
320
321    if ( options.fileSizeLimit ) {
322        var fileSizeLimitWarning = options.fileSizeLimitWarning ? options.fileSizeLimitWarning : Yii.t('common', 'Макс. размер 2 ГБ');
323        var warning = $("<p class='text-muted'>" + fileSizeLimitWarning + "</p>");
324        $fileElem.parent().after(warning);
325    }
326}
327
328window.errCount = 0;
329
330function sendError(message) {
331    window.errCount++;
332    if (window.errCount <= 10) {
333        $.ajax({
334            url: '/pl/gc/log',
335            method: 'POST',
336            data: {data:  message}
337        });
338    }
339}
340
341function sendCreateLinkError(http, message, exc) {
342    var postMessage = '';
343    var toastMessage = '';
344    if (http.responseJSON) {
345        postMessage += (http.responseJSON ? ('json: ' + JSON.stringify(http.responseJSON)) : '');
346    }
347
348    toastMessage += 'status: ' + http.status + '; ';
349    toastMessage += (http.statusText ? ('statusText: ' +  http.statusText + '; ') : '');
350    postMessage += toastMessage;
351
352    postMessage += (message ? ('message: ' + message + ' /// ') : '');
353
354    postMessage += (exc ? ('exc: ' + exc + ' /// ') : '');
355
356    if ($.isFunction($.fn.toast)) {
357        $.toast(toastMessage, {type: "danger"});
358    }
359    console.log(postMessage);
360    sendError(postMessage);
361}
362
363function getUploadifySecretLink(filesToUpload, settings) {
364    var secureDirectUploadUri = '/fileservice/widget/secure-direct-upload';
365    try {
366        var session = localStorage.getItem('session');
367        var requestParams = {"fs_ref": window.location.href};
368
369        if (session !== undefined && session != null){
370            var objSession = jQuery.parseJSON(session);
371
372            if (objSession.hasOwnProperty('user_id') && objSession.user_id != null) {
373                requestParams.fs_u = objSession.user_id;
374            } else {
375                requestParams.fs_u = -1;
376            }
377        }
378
379        secureDirectUploadUri += '?' + jQuery.param(requestParams);
380    } catch (err) {
381    }
382
383    if (typeof settings !== 'undefined' && settings !== null) {
384        delete settings.uploadScript;
385    }
386
387    $.ajax({
388        url: '/fileservice/widget/create-secret-link',
389        method: 'GET',
390        data: {
391            host: window.fileserviceUploadHost,
392            uri: secureDirectUploadUri,
393            expires: 600
394        },
395        success: function (data) {
396            if (data.link) {
397                if (typeof settings !== 'undefined' && settings !== null) {
398                    settings.uploadScript = data.link;
399                }
400            } else {
401                ajaxCall('/fileservice/widget/log-error', {m:  'No link'}, {});
402            }
403        },
404        error: function (http, message, exc) {
405            sendCreateLinkError(http, message, exc);
406        },
407        async: false
408    });
409}
410
411function panelPutTaskAside( task_id ) {
412    $('.aside-loading').css('opacity', 1);
413    $('.aside-link').css('opacity', 0).css('cursor', 'default');
414    $.ajax({
415        url: '/tasks/control/task/setNew',
416        method: 'post',
417        data: {'id': task_id },
418        success: function(data) {
419            panelLoad();
420        }
421    });
422}
423function panelFinishTask( task_id, result ) {
424    $('.aside-loading').css('opacity', 1);
425    $.ajax({
426        url: '/tasks/control/task/setCompleted',
427        method: 'post',
428        data: {'id': task_id, result: result },
429        success: function(data) {
430            panelLoad();
431        }
432    });
433
434    return false;
435}
436
437function panelLoad() {
438    $.ajax({
439        url: '/tasks/control/task/getPanel',
440    success: function(data) {
441        $('#task-panel-placeholder').html( data );
442        }
443    });
444}
445
446function setElLoading( el ) {
447    $(el).html('<div class="text-center padding-10"><img src="/public/img/loading.gif"></div>');
448}
449
450
451$( function() {
452    $('.editable .edit-link').click( function() {
453        $(this).parents('.editable').toggleClass('edit');
454        $(this).parents('.editable').find( 'input').focus();
455    });
456})
457
458$( function() {
459	$( '.action-link').click( function() {
460		if ( $(this).data('gc-confirm' ) ) {
461			if ( ! confirm( $(this).data('gc-confirm' ) ) ) {
462				return false;
463			}
464		}
465		$( '.page-main-form' ).find( 'input[name=action]').val( $(this).data('action' ) );
466		$( '.page-main-form' ).submit();
467	});
468})
469
470
471function extend(Child, Parent) {
472    var F = function() { }
473    F.prototype = Parent.prototype
474    Child.prototype = new F()
475    Child.prototype.constructor = Child
476    Child.superclass = Parent.prototype
477}
478
479function mixin(cls, mixin) {
480	for (var key in mixin) {
481		if (cls.prototype[key]) {
482			// console.log("Class " + cls + " already has a method named " + key + "!");
483		}
484		else {
485			cls.prototype[key] = mixin[key];
486		}
487	}
488}
489
490
491$( function() {
492	if ( $('.date-input').datetimepicker ) {
493		$('.date-input').datetimepicker({
494			timepicker: false, closeOnDateSelect: true, format:'d.m.Y',
495			step: 20, lang:'ru', dayOfWeekStart: 1, todayButton: false, validateOnBlur: true, allowBlank: true, yearStart: '2013', yearEnd: '2020', lazyInit: false
496		});
497
498		$('.date-time-input').datetimepicker({
499			timepicker: true, closeOnDateSelect: false, format:'d.m.Y H:i',
500			step: 20, lang:'ru', dayOfWeekStart: 1, todayButton: false, validateOnBlur: true, allowBlank: true, yearStart: '2013', yearEnd: '2020', lazyInit: false
501		});
502	}
503});
504
505
506$.fn.scrollTo = function( target, options, callback ){
507    if(typeof options == 'function' && arguments.length == 2){ callback = options; options = target; }
508    var settings = $.extend({
509        scrollTarget  : target,
510        offsetTop     : 50,
511        duration      : 500,
512        easing        : 'swing'
513    }, options);
514    return this.each(function(){
515        var scrollPane = $(this);
516        var scrollTarget = (typeof settings.scrollTarget == "number") ? settings.scrollTarget : $(settings.scrollTarget);
517        var scrollY = (typeof scrollTarget == "number") ? scrollTarget : scrollTarget.offset().top + scrollPane.scrollTop() - parseInt(settings.offsetTop);
518        scrollPane.animate({scrollTop : scrollY }, parseInt(settings.duration), settings.easing, function(){
519            if (typeof callback == 'function') { callback.call(this); }
520        });
521    });
522};
523
524function getThumbnailUrl( hash, width, height ) {
525    var result = "/fileservice/file/thumbnail/h/" +  hash + "/s/" + width + "x" + height;
526    if (window.accountId) {
527        result += '/a/'+window.accountId;
528    }
529    if ( window.fileserviceThumbnailHost ) {
530        result = "//" + window.fileserviceThumbnailHost + result;
531    }
532    return result;
533}
534function getBorderedThumbnailUrl( hash, width, height, borderName) {
535
536    if ( borderName == "" ) {
537        return getThumbnailUrl(hash, width, height);
538    }
539
540    var result = "/fileservice/file/bordered/h/" +  hash + "/s/" + width + "x" + height + "/b/" + borderName;
541    if (window.accountId) {
542        result += '/a/'+window.accountId;
543    }
544    if ( window.fileserviceThumbnailHost ) {
545        result = "//" + window.fileserviceThumbnailHost + result;
546    }
547    return result;
548}
549function getDownloadUrl( hash ) {
550	var result = "/pl/fileservice/user/file/download?h=" + hash;
551
552    return result;
553}
554
555function isImage(hash) {
556    let hashParts = hash.split(".");
557	if (hashParts.length === 2) {
558		let imgExts = ['jpeg', 'jpg', 'gif', 'png', 'heic'];
559		return imgExts.includes(hashParts[1]);
560	} else {
561		return false;
562	}
563}
564
565function isVideo(hash) {
566    var hashParts = hash.toLowerCase().split(".");
567    if (hashParts.length === 2) {
568        var imgExts = ['mp4', 'mov'];
569        return imgExts.includes(hashParts[1]);
570    } else {
571        return false;
572    }
573}
574
575/**
576 * Когда нужно обновить картинку в обход кэша браузера
577 */
578function updateThumbnailVersion(hash, version) {
579    if (!window.thumbnailVersions) {
580        window.thumbnailVersions = {};
581    }
582    window.thumbnailVersions[hash] = version;
583}
584
585function getVideoThumbnailUrl( hash, width, height ) {
586    var url = "/pl/fileservice/video/preview-redirect/?file-hash=" + hash;
587    if (window.thumbnailVersions && hash in window.thumbnailVersions) {
588        url += '&v=' + window.thumbnailVersions[hash];
589    }
590    return url;
591}
592
593function gcGetFileObj( row ) {
594    var title = row.title;
595    if ( ! title ) title = row.filename;
596    if ( ! title ) title = row.hash;
597
598    var result = {
599        hash: row.hash,
600        title: title,
601        description: row.description,
602        getThumbnailUrl: function( width, height ) {
603            return "/fileservice/file/thumbnail/h/" + this.hash + "/s/" + width + "x" + height;
604        },
605        getDownloadUrl: function() {
606            return "/pl/fileservice/user/file/download?h=" + this.hash;
607        }
608    };
609    return result;
610}
611
612var getProp = function(o, name, defaultValue) {
613    return undefined === o[name] ? defaultValue : o[name];
614};
615
616$(function () {
617    if ($('#blueimp-gallery').length == 0) {
618        var $el = $('<div id="blueimp-gallery" class="blueimp-gallery blueimp-gallery-controls"><div class="slides next-click"></div><h3 class="title"></h3><a class="prev">‹</a><a class="next next-click">›</a><a class="play-pause"></a><ol class="indicator"></ol></div>')
619        $el.hide();
620        $el.appendTo($(document.body));
621    }
622});
623
624$(function () {
625    function handleAction(href, target) {
626        var accountDomains = window.accountDomains || [];
627        var pathsToWrap = window.pathsToWrap || [];
628        var authingUrl = window.authingUrl || '';
629        var openInExternalApp = target === '_blank';
630        var mainDomain = window.mainDomain || '';
631        if (!href.startsWith('https://') && !href.startsWith('http://')) {
632            const locationHref = new URL(location.href);
633            href = locationHref.origin + href;
634            openInExternalApp = false;
635        }
636        if (accountDomains.includes((new URL(href)).host)) {
637            openInExternalApp = false;
638        }
639
640        var url = new URL(href);
641        for (var path of pathsToWrap) {
642            if (url.pathname.startsWith(path)) {
643                openInExternalApp = true;
644                href = authingUrl !== '' && mainDomain === url.host
645                    ? authingUrl + '&redirectUrl=' + encodeURIComponent(url.href)
646                    : url.href;
647                break;
648            }
649        }
650
651        window.appHandleAction({
652            type: "navigate",
653            url: href,
654            openInExternalApp: openInExternalApp
655        });
656    }
657    $(".lt-block-wrapper a:visible, .xdget-block.xdget-html a:visible, .xdget-block.xdget-lessonContent a:visible, .lite-page a:visible")
658        .on('click', function (event) {
659            const elem = event.currentTarget;
660
661            if (
662                !elem ||
663                !elem.href
664            ) {
665                return;
666            }
667
668            if (
669                elem &&
670                elem.href &&
671                typeof elem.href === 'string' &&
672                elem.href.indexOf('#') >= 0
673            ) {
674                const cleanThisHref = document.location.href.replace(/\#.*$/, '');
675                const cleanAnchorHref = elem.href.replace(/\#.*$/, '');
676                if (cleanThisHref === cleanAnchorHref) {
677                    return;
678                }
679            }
680
681            if (!elem.href.startsWith('#') && !elem.href.startsWith('javascript:') && window.appHandleAction) {
682                event.preventDefault();
683                handleAction(elem.href, elem.target);
684                return false;
685            }
686        });
687});
688
689$( function() {
690    $('.editable-link').each( function( index, el ) {
691        $el = $(el)
692        $wrapper = $el.parents('.editable-link-wrapper')
693
694        if ( $wrapper.length == 0 ) {
695            $wrapper = $('<span class="editable-link-wrapper"/>')
696            $el.replaceWith( $wrapper )
697            $el.appendTo( $wrapper )
698        }
699
700        $link = $('<a class="link"/>')
701        if ( $el.data('header')) {
702            $header = $('<h1/>')
703            $link.appendTo( $header )
704            $header.appendTo( $wrapper )
705        }
706        else {
707            $link.appendTo( $wrapper )
708        }
709
710        var value = null;
711
712        if ( $el.val() != "" ) {
713            value = $el.val();
714        } else if ( $el.attr("placeholder") && $el.attr("placeholder") != "" ) {
715            if(!window.isPageRedesigned) {
716                value = $el.attr("placeholder");
717            } else {
718                value = Yii.t( "common", "change" );
719                $link.addClass('rd-fake-link rd-first-letter-up');
720            }
721        } else {
722            value = 'изменить';
723
724            if (typeof Yii != 'undefined') {
725                value = Yii.t( "common", "change" );
726            }
727            $wrapper.addClass( 'no-value' );
728            if(window.isPageRedesigned) {
729                $link.addClass('rd-fake-link rd-first-letter-up');
730            }
731        }
732
733        if (window.isPageRedesigned && typeof Yii != 'undefined') {
734            if (value === 'male') {
735                value = Yii.t("user", "Male");
736            }
737            if (value === 'female') {
738                value = Yii.t("user", "Female");
739            }
740        }
741
742        $link.html(value);
743
744        $link.click( function() {
745            $(this).parents('.editable-link-wrapper').addClass('edit-mode')
746        })
747
748    })
749})
750
751window.runOneTimeOnElement = function($el, key, callback) {
752    if ($el.data(key)) {
753        return;
754    }
755    $el.data(key, callback($el));
756};
757window.eachAndRunOneTimeOnElement = function($each, key, callback) {
758    $each.each(function(index, el) {
759        runOneTimeOnElement($(el), key, callback);
760    });
761}
762
763function objectToQueryString (a) {
764    var prefix, s, add, name, r20, output;
765    s = [];
766    r20 = /%20/g;
767    add = function (key, value) {
768        // If value is a function, invoke it and return its value
769        value = ( typeof value == 'function' ) ? value() : ( value == null ? "" : value );
770        s[ s.length ] = encodeURIComponent(key) + "=" + encodeURIComponent(value);
771    };
772    if (a instanceof Array) {
773        for (name in a) {
774            add(name, a[name]);
775        }
776    } else {
777        for (prefix in a) {
778            buildParams(prefix, a[ prefix ], add);
779        }
780    }
781    output = s.join("&").replace(r20, "+");
782    return output;
783};
784function buildParams(prefix, obj, add) {
785    var name, i, l, rbracket;
786    rbracket = /\[\]$/;
787    if (obj instanceof Array) {
788        for (i = 0, l = obj.length; i < l; i++) {
789            if (rbracket.test(prefix)) {
790                add(prefix, obj[i]);
791            } else {
792                buildParams(prefix + "[" + ( typeof obj[i] === "object" ? i : "" ) + "]", obj[i], add);
793            }
794        }
795    } else if (typeof obj == "object") {
796        // Serialize object item.
797        for (name in obj) {
798            buildParams(prefix + "[" + name + "]", obj[ name ], add);
799        }
800    } else {
801        // Serialize scalar item.
802        add(prefix, obj);
803    }
804}
805
806$.fn.serializeObject = function()
807{
808    var o = {};
809    var a = this.serializeArray();
810    $.each(a, function() {
811        if (o[this.name] !== undefined) {
812            if (!o[this.name].push) {
813                o[this.name] = [o[this.name]];
814            }
815            o[this.name].push(this.value || '');
816        } else {
817            o[this.name] = this.value || '';
818        }
819    });
820    return o;
821};
822
823window.gcIsHiddenTab = function(){
824    var hidden, state;
825
826    if (typeof document.hidden !== "undefined") {
827        state = "visibilityState";
828    } else if (typeof document.mozHidden !== "undefined") {
829        state = "mozVisibilityState";
830    } else if (typeof document.msHidden !== "undefined") {
831        state = "msVisibilityState";
832    } else if (typeof document.webkitHidden !== "undefined") {
833        state = "webkitVisibilityState";
834    }
835
836    return document[state] == "hidden";
837};
838window.gcIsActiveTab = !window.gcIsHiddenTab();
839$(window).focus(function() {
840    window.gcIsActiveTab = true;
841});
842
843$(window).blur(function() {
844    window.gcIsActiveTab = false;
845});
846
847window.gcGetCookie = function(name) {
848    var matches = document.cookie.match(new RegExp(
849        "(?:^|; )" + name.replace(/([\.$?*|{}\(\)\[\]\\\/\+^])/g, '\\$1') + "=([^;]*)"
850    ));
851    return matches ? decodeURIComponent(matches[1]) : undefined;
852};
853
854window.gcSetCookie = function gcSetCookie(name, value, options) {
855    options = options || {};
856
857    var expires = options.expires;
858
859    if (typeof expires == "number" && expires) {
860        var d = new Date();
861        d.setTime(d.getTime() + expires * 1000);
862        expires = options.expires = d;
863    }
864    if (expires && expires.toUTCString) {
865        options.expires = expires.toUTCString();
866    }
867
868    value = encodeURIComponent(value);
869
870    var updatedCookie = name + "=" + value;
871
872    for (var propName in options) {
873        updatedCookie += "; " + propName;
874        var propValue = options[propName];
875        if (propValue !== true) {
876            updatedCookie += "=" + propValue;
877        }
878    }
879
880    document.cookie = updatedCookie;
881};
882
883
884function addParamToLocation( key, value)
885{
886    key = encodeURI(key); value = encodeURI(value);
887
888    var kvp = document.location.search.substr(1).split('&');
889
890    var i=kvp.length; var x; while(i--)
891    {
892        x = kvp[i].split('=');
893
894        if (x[0]==key)
895        {
896            x[1] = value;
897            kvp[i] = x.join('=');
898            break;
899        }
900    }
901
902    if(i<0) {kvp[kvp.length] = [key,value].join('=');}
903
904    //this will reload the page, it's likely better to store this until finished
905    document.location.search = kvp.join('&');
906}
907
908function removeParamFromLocation( key )
909{
910    key = encodeURI(key);
911
912    var kvp = document.location.search.substr(1).split('&');
913
914    var i=kvp.length; var x; while(i--)
915    {
916        x = kvp[i].split('=');
917
918
919        if (x[0]==key)
920        {
921            kvp[i] = null
922            break;
923        }
924    }
925    var search = kvp.join("&") != "&" ? kvp.join('&') : "";
926//alert(kvp.length > 0 kvp.join('&') : "")
927    //this will reload the page, it's likely better to store this until finished
928    document.location.search = search;
929}
930
931
932function escapeDoubleQuotes(str) {
933	return str.replace(/\\([\s\S])|(")/g,"\\$1$2");
934}
935
936function setVisibilityRelation( checkboxSelector, paramsSelector ) {
937    var $checkboxSelector = $(checkboxSelector)
938    var $paramsSelector = $(paramsSelector)
939    var changed = function() {
940        var checked = $checkboxSelector.prop('checked');
941        if ( checked ) $paramsSelector.show(); else $paramsSelector.hide();
942    }
943    $checkboxSelector.click( changed )
944    changed();
945}
946
947function getParamFromLocation( key )
948{
949    key = encodeURI(key);
950
951    var kvp = document.location.search.substr(1).split('&');
952
953    var i=kvp.length; var x; while(i--)
954    {
955        x = kvp[i].split('=');
956
957
958        if (x[0]==key)
959        {
960            return x[1];
961        }
962    }
963    return null;
964}
965
966function getParamFromHash( key )
967{
968    key = encodeURI(key);
969
970    var kvp = document.location.hash.substr(1).split('&');
971
972    var i=kvp.length; var x; while(i--)
973{
974    x = kvp[i].split('=');
975
976
977    if (x[0]==key)
978    {
979		var res = x[1];
980		return res;
981    }
982}
983    return null;
984}
985
986var gcParseUrl = function(url) {
987    var urlEl = document.createElement('a');
988    urlEl.href = url;
989    return urlEl;
990};
991
992var gcAddResourceElement = function(tag, attr, createElementCallback) {
993    var resources = {};
994
995    return function(resourceUrl) {
996        if (!resources.hasOwnProperty(resourceUrl)) {
997            var list = document.getElementsByTagName(tag);
998            var i = list.length, exists = false;
999            while (i--) {
1000                var url = gcParseUrl(list[i][attr]);
1001                if (url.pathname+url.search == resourceUrl) {
1002                    exists = true;
1003                    break;
1004                }
1005            }
1006            if (!exists) {
1007                resources[resourceUrl] = createElementCallback(resourceUrl);
1008                console.log('loaded '+resourceUrl);
1009            }
1010        }
1011    };
1012};
1013
1014var gcAddScriptElement = (function() {
1015    return gcAddResourceElement('script', 'src', function (resourceUrl) {
1016        var script = document.createElement("script");
1017        script.type = "text/javascript";
1018        script.src = resourceUrl;
1019        document.getElementsByTagName('head')[0].appendChild(script);
1020        return script;
1021    });
1022})();
1023
1024var gcAddLinkElement = (function() {
1025    return gcAddResourceElement('link', 'href', function (resourceUrl) {
1026        var link = document.createElement("link");
1027        link.rel = "stylesheet";
1028        link.src = resourceUrl;
1029        document.getElementsByTagName('head')[0].appendChild(link);
1030        return link;
1031    });
1032})();
1033
1034
1035
1036function replaceAll(str, find, replace) {
1037    return str.replace(new RegExp(find, 'g'), replace);
1038}
1039
1040serializeObj = function(obj, prefix) {
1041    var str = [], p;
1042    for(p in obj) {
1043        if (obj.hasOwnProperty(p)) {
1044            var k = prefix ? prefix + "[" + p + "]" : p, v = obj[p];
1045            if ( typeof v === "undefined" ) {
1046                continue;
1047            }
1048            if ( v == null ) {
1049                continue;
1050            }
1051            str.push((v !== null && typeof v === "object") ?
1052                serializeObj(v, k) :
1053            encodeURIComponent(k) + "=" + encodeURIComponent(v));
1054        }
1055    }
1056    return str.join("&");
1057};
1058
1059function initListSearch( element, selector ) {
1060
1061    var filter = function( value ) {
1062        value = value.toLowerCase();
1063        var found = false;
1064        element.find(selector).each(function () {
1065            var text = $(this).html().toLowerCase();
1066            if (value == "") {
1067                $(this).show();
1068                found = true;
1069            }
1070            else {
1071                if (text.indexOf(value) > -1) {
1072                    $(this).show();
1073                    found = true;
1074                }
1075                else {
1076                    $(this).hide();
1077                }
1078            }
1079
1080        })
1081        return found;
1082    };
1083
1084    var placeholderValue = window.isPageRedesigned ? 'Поиск' : 'поиск';
1085    var notFound = 'ничего не найдено';
1086    if (typeof Yii != 'undefined') {
1087        placeholderValue = window.isPageRedesigned ? Yii.t("common", "Поиск") : Yii.t("common", "search");
1088        notFound = Yii.t("common", "ничего не найдено");
1089    }
1090
1091    var liStyle = window.isPageRedesigned ? 'margin: 0; list-style: none; padding: 8px 12px;' : 'margin: 0; list-style: none; padding: 5px 3px;';
1092
1093    var $searchRuleBlock = $("<li style='" + liStyle + "'><input class='search-input' placeholder='" + placeholderValue + "' type='text'/><div class='nothing-found-label' style='padding-top: 10px; background: lightyellow; display:none'>" + notFound + "</div></li>")
1094    if(window.isPageRedesigned) {
1095        if(element.find('li:not(.hidden):not(:has(input))').length >= 5) {
1096            $searchRuleBlock.prependTo ( element )
1097        }
1098    } else {
1099        $searchRuleBlock.prependTo ( element )
1100    }
1101    var searchRuleInput = $searchRuleBlock.find('input')
1102    searchRuleInput.keyup( function() {
1103        if ( filter( $(this).val() ) ) {
1104            $searchRuleBlock.find('.nothing-found-label').hide()
1105        }
1106        else {
1107            $searchRuleBlock.find('.nothing-found-label').show()
1108        }
1109    });
1110}
1111
1112function initDropdownSearch( $dropdownMenu ) {
1113
1114    $dropdownMenu = $dropdownMenu.find('.dropdown-menu')
1115
1116    initListSearch( $dropdownMenu, 'a' );
1117
1118    $dropdownMenu.parent().on( 'show.bs.dropdown', function() {
1119        setTimeout( function() {
1120            $dropdownMenu.find('.search-input').focus();
1121        })
1122    })
1123
1124
1125
1126
1127}
1128
1129
1130function number_format( number, decimals, dec_point, thousands_sep ) {	// Format a number with grouped thousands
1131    //
1132    // +   original by: Jonas Raoni Soares Silva (http://www.jsfromhell.com)
1133    // +   improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
1134    // +	 bugfix by: Michael White (http://crestidg.com)
1135
1136    var i, j, kw, kd, km;
1137
1138    // input sanitation & defaults
1139    if( isNaN(decimals = Math.abs(decimals)) ){
1140        decimals = 2;
1141    }
1142    if( dec_point == undefined ){
1143        dec_point = ",";
1144    }
1145    if( thousands_sep == undefined ){
1146        thousands_sep = ".";
1147    }
1148
1149    i = parseInt(number = (+number || 0).toFixed(decimals)) + "";
1150
1151    if( (j = i.length) > 3 ){
1152        j = j % 3;
1153    } else{
1154        j = 0;
1155    }
1156
1157    km = (j ? i.substr(0, j) + thousands_sep : "");
1158    kw = i.substr(j).replace(/(\d{3})(?=\d)/g, "$1" + thousands_sep);
1159    //kd = (decimals ? dec_point + Math.abs(number - i).toFixed(decimals).slice(2) : "");
1160    kd = (decimals ? dec_point + Math.abs(number - i).toFixed(decimals).replace(/-/, 0).slice(2) : "");
1161
1162
1163    return km + kw + kd;
1164}
1165
1166
1167function onTelegramAuth(user) {
1168    ajaxCall( "/pl/user/profile/login-with-telegram", { user: user }, {method: 'get'}, function( response ) {
1169        if ( window.afterTelegramAuthCallback ) {
1170            window.afterTelegramAuthCallback();
1171        }
1172        //alert( response )
1173    });
1174}
1175
1176window.phoneChecked = false;
1177window.checkFormPhone = function(form) {
1178    var phoneInput = $(form).find('input.phone-input')
1179    if ( phoneInput.length > 0 && ! window.phoneChecked ) {
1180        ajaxCall( "/pl/user/profile/set-phone", { phone: phoneInput.val() }, {}, function( response ) {
1181            if ( response.data.success) {
1182                window.phoneChecked = true;
1183                $(form).submit()
1184            }
1185            else {
1186                alert( response.data.error )
1187            }
1188        } );
1189        return false;
1190    }
1191    else {
1192        return true;
1193    }
1194
1195};
1196window.tt = function(category, text, params) {
1197    return (typeof Yii != 'undefined') ? Yii.t(category,  text, params) : text;
1198};
1199
1200
1201window.renderIcon = function( icon, $parentEl ) {
1202
1203    let $el = $parentEl.find('.chatium-icon');
1204    if ( $el.length == 0 ) {
1205        $el = $('<div class="chatium-icon"/>').appendTo( $parentEl );
1206    }
1207
1208    let url = icon.url;
1209    if ( ! url && icon.image ) {
1210        url = icon.image;
1211    }
1212    if ( icon.hash ) {
1213        url = getThumbnailUrl(icon.hash, 100, 100);
1214    }
1215    if ( url ) {
1216        $el.empty();
1217        $('<img/>').attr( 'src', url ).appendTo( $el );
1218    }
1219    else if ( icon.iconCssClass ) {
1220        $el.html("<div class='chatium-icon-text'><span class='" + icon.iconCssClass + "'></span></div>")
1221        $el.addClass('icon-type-icon' );
1222    }
1223    else {
1224        $el.html( "<div class='chatium-icon-text'>" + ( icon.text ? icon.text : "" ) + "</div>" );
1225        if ( icon.type ) {
1226            $el.addClass('icon-type-' + icon.type );
1227        }
1228
1229    }
1230    if ( icon.color ) {
1231        $el.css('color', icon.color)
1232    }
1233    if ( icon.bgColor && !url) {
1234        $el.css('background-color', icon.bgColor)
1235    }
1236};

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.