PageSourceSearch

https://sumitec.ru/local/templates/main/components/bxmaker/geoip.city/sumitec/script.js?177573025752713

js sumitec.ru collected 2026-10-05 21:57:39 UTC 52,713 bytes, 1,286 lines download raw bytes

1if (window.frameCacheVars !== undefined) {
2    if (!!window.frameCacheVars.AUTO_UPDATE) {
3        BX.addCustomEvent("onFrameDataReceived", function (json) {
4            window.BXmakerGeoIPCity.init($('.js-bxmaker__geoip__city'));
5        });
6    }
7    else {
8        BX.ready(function () {
9            window.BXmakerGeoIPCity.init($('.js-bxmaker__geoip__city'), true);
10        });
11    }
12} else {
13    BX.ready(function () {
14        window.BXmakerGeoIPCity.init($('.js-bxmaker__geoip__city'));
15    });
16}
17
18if (!!window.BXmakerGeoIPCity === false) {
19
20    (function () {
21        /**
22         * Класс для работы с комопнентом bxmaker:geoip.city, отвечает за показ, смену города
23         * такой комопнент на странице должен быть 1, если больше, то остальные будут проигнорирвоаны
24         * @constructor
25         */
26        var BXmakerGeoIPCityConstructor = function () {
27            var that = this;
28            that.baseParams = {};
29            that.params = {};
30            that.box = null;
31            that.popup = null;
32            that.bInit = false;
33            that.yandexGeoLibLoaded = false; //  загружена ли библиотека для поиска или уточнения
34        };
35
36        /**
37         * Вклчюено ли использвоание поиска адреса через яндекс
38         * @returns {*}
39         */
40        BXmakerGeoIPCityConstructor.prototype.isUseYandexSearch = function(){
41            return this.params.useYandexSearch;
42        };
43
44        /**
45         * Загружана ли библиотека и проинициализирована ли
46         * @returns {*}
47         */
48        BXmakerGeoIPCityConstructor.prototype.isYandexLibLoaded= function(){
49            return this.yandexGeoLibLoaded;
50        };
51
52
53        /**
54         * После получения данных от фонового запроса при композите, происходит подготовка блока, замена названия города на актуальный вызов событий и тп
55         * @param box
56         * @returns {boolean}
57         */
58        BXmakerGeoIPCityConstructor.prototype.init = function (box, bNeedRequest) {
59            var that = this;
60            var bNeedRequest = bNeedRequest || false;
61
62            if (!box.length) return false;
63            if (box.filter('.js-bxmaker__geoip__city--init').length) return false;
64
65            that.box = box.eq(0); // здесь как раз и происходит отбор первого блока, остальные игнорируются
66
67            that.box.addClass('js-bxmaker__geoip__city--init');
68	        that.popup = $('.modal#geo-target').detach();
69            that.rand = that.box.attr('data-rand');
70
71
72            //базовые парамтеры ------
73            if (!window.BxmakerGeoipCityDataBase || !window.BxmakerGeoipCityDataBase[that.rand]) {
74                return false;
75            }
76            that.baseParams = window.BxmakerGeoipCityDataBase[that.rand];
77
78            if (bNeedRequest) {
79                // [-] В это условие не попадаем..
80                // кэшируем данные
81                var cache = that.storageTest() ? that.storageGet('jsParams') : {};
82
83                if (!!cache.cookiePrefix) {
84                    that.params = cache;
85                    that.execute();
86                }
87                else {
88                    $.ajax({
89                        type: 'POST',
90                        url: that.baseParams.ajaxUrl,
91                        dataType: 'json',
92                        data: {
93                            method: 'getJsParams',
94                            parameters: that.baseParams.parameters,
95                            template: that.baseParams.template,
96                            siteId: that.baseParams.siteId,
97                        },
98                        error: function (r) {
99                            that.logError('Error connection', r);
100                        },
101                        success: function (r) {
102                            if (!!r.response) {
103
104                                that.params = r.response.params;
105
106                                //в кэш
107                                (that.storageTest() && that.storageSet('jsParams', that.params));
108
109                                that.execute();
110
111                            }
112                            else if (!!r.error) {
113                                that.logError('Error', r);
114                            }
115                        }
116                    });
117                }
118
119            }
120            else {
121                // [+] В это условие попадаем..
122                that.params = window.BxmakerGeoipCityData[that.rand];
123                that.execute();
124            }
125
126        };
127
128        /**
129         * Выполнение когда есть уже все параметры работы
130         * @returns {boolean}
131         */
132        BXmakerGeoIPCityConstructor.prototype.execute = function () {
133            var that = this;
134
135            if (!!(that.getCityId()) == false) {
136                // [-] Не попадаем в это условие
137                setTimeout(function () {
138                    that.execute();
139                }, 400);
140                return false;
141            }
142
143            // проверка включена ли отладка вручную
144            if (this.cookie('debug') == 'Y') {
145                // [-] Не попадаем в это условие
146                that.baseParams.debug = true;
147            }
148
149            that.initEvent();
150            that.bInit = true;
151
152
153            $(document).trigger('bxmaker.geoip.city.inited', {});
154
155            that.showCity();
156
157
158            // уточнение включено, поиск включено
159            if (that.params.useYandex && that.isUseYandexSearch()) {
160                 // [-] Не попадаем в это условие
161                window.BXmakerGeoIPYandexGeo.init(that.params);
162            }
163            // уточнение вклчюено, поиск выключено
164            else if (that.params.useYandex && !that.isUseYandexSearch()) {
165                // [-] Не попадаем в это условие
166                // местоположение уже определяелось , повторно не нужно ---
167                if (that.cookie('yandex_location_defined') == 'Y' && that.cookie('yandex_location_defined_check') == '1') {
168                    that.checkRedirect();
169                }
170                else {
171                    window.BXmakerGeoIPYandexGeo.init(that.params);
172                }
173            }
174            //уточненеи выключено, поиск включен
175            else if (!that.params.useYandex && that.isUseYandexSearch()) {
176                // [-] Не попадаем в это условие
177                window.BXmakerGeoIPYandexGeo.init(that.params);
178            }
179            // и поиск и уточнение отключены
180            else {
181                // [+] Попадаем сюда
182                that.checkRedirect();
183            }
184
185        };
186
187        /**
188         * Проверка, инициализирован ли компонент
189         * @returns {boolean}
190         */
191        BXmakerGeoIPCityConstructor.prototype.isInit = function () {
192            return this.bInit;
193        };
194
195        /**
196         * Включение/отклчюение режима отладки
197         * @param flag
198         */
199        BXmakerGeoIPCityConstructor.prototype.setDebug = function (flag) {
200            this.params.debug = flag;
201            if (flag) {
202                this.cookie('debug', 'Y');
203            }
204            else {
205                this.cookie('debug', 'N');
206            }
207        };
208
209
210        /**
211         * Лог действий при отладке
212         */
213        BXmakerGeoIPCityConstructor.prototype.log = function () {
214            if (this.params.debug) {
215                var args = Array.prototype.slice.call(arguments);
216                args.unshift('bxmaker:geoip.city: ');
217                console.log.apply(console, args);
218            }
219        };
220
221        /**
222         * Лог ошибок при отладке
223         */
224        BXmakerGeoIPCityConstructor.prototype.logError = function () {
225            if (this.params.debug) {
226                var args = Array.prototype.slice.call(arguments);
227                args.unshift('bxmaker:geoip.city: ');
228                console.error.apply(console, args);
229            }
230        };
231
232        /**
233         * Вернет домен, для которого устаналвиваются куки
234         * @returns {*}
235         */
236        BXmakerGeoIPCityConstructor.prototype.getCookieDomain = function () {
237            // [+] попадаем сюда, когда нажимаем на выборо города
238            var that = this;
239            return that.params.cookieDomain;
240        };
241
242
243        /**
244         * Преобразование к числу
245         * @param num
246         * @returns {number}
247         */
248        BXmakerGeoIPCityConstructor.prototype.intval = function (num) {
249            if (typeof num == 'number' || typeof num == 'string') {
250                num = num.toString();
251                var dotLocation = num.indexOf('.');
252                if (dotLocation > 0) {
253                    num = num.substr(0, dotLocation);
254                }
255                if (isNaN(Number(num))) {
256                    num = parseInt(num);
257                }
258                if (isNaN(num)) {
259                    return 0;
260                }
261                return Number(num);
262            }
263            else if (typeof num == 'object' && num.length != null && num.length > 0) {//Непустой массив/объект -> 1
264                return 1;
265            }
266            else if (typeof num == 'boolean' && num === true) {//true -> 1
267                return 1;
268            }
269            return 0;//Чуть что не так - сразу в ноль
270        };
271
272        /**
273         * Получение, запись кук
274         * @param name
275         * @param value
276         * @param params
277         * @returns {any}
278         */
279        BXmakerGeoIPCityConstructor.prototype.cookie = function (name, value, params) {
280            var that = this;
281            var d = new Date();
282            var name = that.params.cookiePrefix + name;
283            var params = params || {};
284            var parts = [];
285            var currentValue, matches;
286
287
288            if (value === undefined) {
289                // [+] попадаем в это
290                matches = document.cookie.match(new RegExp(
291                    "(?:^|; )" + name.replace(/([\.$?*|{}\(\)\[\]\\\/\+^])/g, '\\$1') + "=([^;]*)"
292                ));
293                currentValue = matches ? decodeURIComponent(matches[1].replace(/\+/g, ' ')) : undefined;
294                that.log('cookie get: ' + name + ' = ' + currentValue);
295
296                return currentValue;
297            }
298            else {
299                // [+] попадаем сюда, когда выбираем город
300                value = encodeURIComponent(value);
301                d.setTime(d.getTime() + ((!!params.expires ? params.expires : 365) * 24 * 60 * 60 * 1000));
302
303                parts.push(name + "=" + value);// todo  parts.push(name + "=" + encodeURIComponent(value));
304                parts.push("expires=" + d.toUTCString());
305                parts.push("path=" + (!!params.path ? params.path : '/'));
306                parts.push("domain=" + that.getCookieDomain());
307                //parts.push("domain=sumitec.ru");
308
309                document.cookie = parts.join('; ');
310                that.log('cookie: ' + parts.join('; '), parts);
311            }
312        };
313
314        /**
315         * Получение параметров url  страницы в формате json для удобства
316         * @param hashBased
317         * @returns {Array}
318         */
319        BXmakerGeoIPCityConstructor.prototype.getJsonFromUrl = function (hashBased) {
320            var query;
321            if (hashBased) {
322                var pos = location.href.indexOf("?");
323                if (pos == -1) return [];
324                query = location.href.substr(pos + 1);
325            } else {
326                query = location.search.substr(1);
327            }
328            var result = {};
329            query.split("&").forEach(function (part) {
330                if (!part) return;
331                part = part.split("+").join(" "); // replace every + with space, regexp-free version
332                var eq = part.indexOf("=");
333                var key = eq > -1 ? part.substr(0, eq) : part;
334                var val = eq > -1 ? decodeURIComponent(part.substr(eq + 1)) : "";
335                var from = key.indexOf("[");
336                if (from == -1) result[decodeURIComponent(key)] = val;
337                else {
338                    var to = key.indexOf("]", from);
339                    var index = decodeURIComponent(key.substring(from + 1, to));
340                    key = decodeURIComponent(key.substring(0, from));
341                    if (!result[key]) result[key] = [];
342                    if (!index) result[key].push(val);
343                    else result[key][index] = val;
344                }
345            });
346            return result;
347        };
348
349        /**
350         * Инициализаци событий, для отслеживания кликов, набора текста и тп
351         */
352        BXmakerGeoIPCityConstructor.prototype.initEvent = function () {
353            var that = this;
354            var searchTimeout = false;
355
356            // после того как местоположение было уточнено через яндекс ------------
357            $(document).on('bxmaker.geoip.city.yandex.defined', function (event, params) {
358                // [-] Не попадаем сюда
359                that.log('save user location defined by yandex');
360                that.selectLocation(false, params);
361                that.cookie('yandex_location_defined', 'Y');
362                that.cookie('yandex_location_defined_check', '1');
363                that.checkRedirect();
364            });
365
366            //библиотека яндекс карт для работы с геолокацией польвзователя загружена ------
367            $(document).on('bxmaker.geoip.yandex.geo.loaded', function () {
368
369                that.yandexGeoLibLoaded = true;
370
371                //уточнение через яндекс выклчюено --
372                if (!that.params.useYandex) {
373                    that.cookie('yandex_location_defined_check', '0');
374                    return true;
375                }
376
377                // местоположение уже определяелось , повторно не нужно ---
378                if (that.cookie('yandex_location_defined') == 'Y' && that.cookie('yandex_location_defined_check') == '1') {
379                    that.checkRedirect();
380                    return true;
381                }
382
383                that.log('Yandex geocoder find user location');
384
385                window.BXmakerGeoIPYandexGeo.getConnection().geolocation.get({
386                    provider: 'yandex',
387                    timeout: 5000,
388                    autoReverseGeocode: true
389                })
390                    .then(function (res) {
391
392                    that.log('Yandex geocoder success', res);
393
394                    var boundedBy = res.geoObjects.get(0).properties.get('boundedBy');
395                    var responseItem = res.geoObjects.get(0).properties.get('metaDataProperty').GeocoderMetaData;
396                    var responseItemAddress = responseItem.Address.Components;
397                    var item = {};
398                    var bSkip = false;
399
400
401                    item = {
402                        'location': responseItem.id,
403                        'city': '',
404                        'city_id': responseItem.id,
405                        'country': '',
406                        'country_id': 0,
407                        'region': '',
408                        'region_id': 0,
409                        'area': '',
410                        'zip': '000000',
411                        'range': 0,
412                        'lng': 0,
413                        'lat': 0,
414                        'yandex': 1
415                    };
416
417                    for (var ai in responseItemAddress) {
418                        switch (responseItemAddress[ai].kind) {
419                            case 'locality': {
420                                item['city'] = responseItemAddress[ai].name;
421                                break;
422                            }
423                            case 'area': {
424                                item['area'] = responseItemAddress[ai].name;
425                                break;
426                            }
427                            case 'province': {
428                                item['region'] = responseItemAddress[ai].name;
429                                break;
430                            }
431                            case 'country': {
432                                item['country'] = responseItemAddress[ai].name;
433                                break;
434                            }
435                        }
436                    }
437
438                    bSkip = false;
439                    for (var ci = 0; ci < that.params.yandexSearchSkipWords.length; ci++) {
440                        if (that.params.yandexSearchSkipWords[ci].replace(/^\s+/, '').replace(/\s+$/).length > 0 && item['city'].indexOf(that.params.yandexSearchSkipWords[ci].replace(/^\s+/, '').replace(/\s+$/)) != -1) {
441                            that.log('Skip location ' + item['city'] + ': skip word = ' + that.params.yandexSearchSkipWords[ci]);
442                            bSkip = true;
443                        }
444                    }
445
446                    item['lng'] = (boundedBy[1][0] - boundedBy[0][0]);
447                    item['lat'] = (boundedBy[1][1] - boundedBy[0][1]);
448
449                    if (responseItem.kind == 'locality' || (responseItem.kind == 'province' && item['city'] == item['region'])) {
450                        if (!bSkip) {
451                            that.log('location is defined');
452                            that.log('trigger:bxmaker.geoip.city.yandex.defined', item);
453                            $(document).trigger('bxmaker.geoip.city.yandex.defined', item);
454                        }
455                    }
456                    else {
457                        that.logError('location is not defined');
458                    }
459
460
461                }, function (e) {
462                    that.logError('location is not defined');
463                });
464            });
465
466            $(document).on('bxmaker.geoip.city.search.start', function () {
467                that.popupShow();
468            });
469
470            $(document).on('click', '.js-bxmaker__geoip__city-name-global', function () {
471                that.popupShow();
472            });
473
474
475            // click po knopke zakryt ocno dlya smeny goroda
476            that.popup.on("click", '.js-bxmaker__geoip__popup-close', function () {
477                that.log('click by close popup btn');
478                that.popupHide();
479            });
480
481            //click po fonu
482            that.popup.on("click", '.js-bxmaker__geoip__popup-background', function () {
483                that.log('click by popup background');
484                that.popupHide();
485            });
486
487            //clear input
488            that.popup.on("click", '.js-bxmaker__geoip__popup-search-clean', function () {
489                if ($(this).hasClass('preloader')) return false;
490                that.log('Search input clean');
491                that.popup.find('input[name="city"]').val('').focus();
492                that.popup.find('.js-bxmaker__geoip__popup-search-options').hide();
493            });
494
495            that.popup.on("click", '.js-bxmaker__geoip__popup-option', function () {
496                var item = $(this);
497
498                that.popup.find('.js-bxmaker__geoip__popup-search-options').hide();
499
500                if (that.isUseYandexSearch()) {
501                    that.popup.find('input[name="city"]').val(item.text()).keyup();
502                }
503                else {
504                    that.selectLocation(item.attr('data-id'));
505                    that.popupHide();
506                }
507            });
508
509            that.popup.on("keyup", 'input[name="city"]', function () {
510
511                var adres = $(this).val().trim();
512
513                if (adres.length < 2) return;
514                if (!!searchTimeout) clearTimeout(searchTimeout);
515
516                searchTimeout = setTimeout(function () {
517
518                    that.log('Search adress:' + adres);
519                    that.popup.find('.js-bxmaker__geoip__popup-search-clean').addClass('preloader');
520                    that.popup.find('.js-bxmaker__geoip__popup-search-search').hide();
521
522                    that.search(adres, function (r) {
523
524                        that.log('count search results:' + r.response.count);
525
526                        that.popup.find('.js-bxmaker__geoip__popup-search-clean').removeClass('preloader');
527
528                        var searchOptions = that.popup.find('.js-bxmaker__geoip__popup-search-options');
529                        searchOptions.empty();
530
531
532                        if (!!r.response) {
533                            if (r.response.count <= 0) {
534                                searchOptions.append($('<div class="bxmaker__geoip__popup-search-option bxmaker__geoip__popup-search-option--empty" >' + that.params.messages.emptyResult + '</div>'));
535                            }
536                            else {
537                                for (var i = 0; i < r.response.count; i++) {
538                                    var item = r.response.items[i];
539
540                                    var itemName = ('<span>' + item.city + '</span>' + (!!item.district ? ', ' + item.district : '') + (!!item.region && item.region != item.city ? ', ' + item.region : '') + (!!item.country ? ', ' + item.country : ''));
541                                    var itemHtml = '<div class="bxmaker__geoip__popup-search-option js-bxmaker__geoip__popup-search-option" ';
542
543                                    itemHtml += (' data-location="' + item.location + '" ');
544                                    itemHtml += (' data-city="' + item.city + '" ');
545                                    itemHtml += (' data-city_id="' + item.city_id + '" ');
546                                    itemHtml += (' data-country="' + item.country + '" ');
547                                    itemHtml += (' data-country_id="' + item.country_id + '" ');
548                                    itemHtml += (' data-region="' + item.region + '" ');
549                                    itemHtml += (' data-region_id="' + item.region_id + '" ');
550                                    itemHtml += (' data-area="' + item.area + '" ');
551                                    itemHtml += (' data-zip="' + item.zip + '" ');
552                                    itemHtml += (' data-range="' + item.range + '" ');
553                                    itemHtml += (' data-lng="' + item.lng + '" ');
554                                    itemHtml += (' data-lat="' + item.lat + '" ');
555                                    itemHtml += (' data-yandex="' + item.yandex + '" ');
556                                    itemHtml += ' >';
557
558                                    itemHtml += itemName;
559                                    itemHtml += '</div>';
560
561                                    searchOptions.append($(itemHtml));
562                                }
563                            }
564                        }
565                        else if (!!r.error) {
566                            searchOptions.append('<div class="bxmaker__geoip__popup-search-option bxmaker__geoip__popup-search-option--empty" >' + r.error.msg + '</div>');
567                        }
568
569                        searchOptions.show();
570
571
572                    }, function (r) {
573                        that.logError('Error search adress:', r);
574
575                        that.popup.find('.js-bxmaker__geoip__popup-search-clean').removeClass('preloader');
576                        that.popup.find('.js-bxmaker__geoip__popup-search-search').empty().append($('<div class="bxmaker__geoip__popup-search-option bxmaker__geoip__popup-search-option--empty" >' + that.params.messages.emptyResult + '</div>'));
577                    });
578                }, that.params.searchTimeout);
579            });
580
581            that.popup.on("click", '.js-bxmaker__geoip__popup-search-option', function () {
582                var item = $(this);
583
584                that.popup.find('input[name="city"]').val(item.find('span').text());
585                that.popup.find('.js-bxmaker__geoip__popup-search-options').hide();
586
587                if (that.isUseYandexSearch()) {
588                    // сохраняем на сервере
589                    that.selectLocation(false, {
590                        location: item.attr('data-location'),
591                        city: item.attr('data-city'),
592                        city_id: item.attr('data-city_id'),
593                        region: item.attr('data-region'),
594                        region_id: item.attr('data-region_id'),
595                        country: item.attr('data-country'),
596                        country_id: item.attr('data-country_id'),
597                        area: item.attr('data-area'),
598                        zip: item.attr('data-zip'),
599                        range: item.attr('data-range'),
600                        lng: item.attr('data-lng'),
601                        lat: item.attr('data-lat'),
602                        yandex: item.attr('data-yandex')
603                    });
604                }
605                else {
606                    that.selectLocation(item.attr('data-location'));
607                }
608                that.popupHide();
609            });
610        };
611
612        /**
613         * Скрытие окна с поиском города или выбором из списка избранных
614         */
615        BXmakerGeoIPCityConstructor.prototype.popupHide = function () {
616            var that = this;
617            that.log('trigger:bxmaker.geoip.popup.hide.before');
618            $(document).trigger('bxmaker.geoip.popup.hide.before');
619
620            that.log('popup hide');
621            that.popup.find('.js-bxmaker__geoip__popup-background').animate({'opacity': '0'}, that.params.animateTimeout);
622            that.popup.find('.js-bxmaker__geoip__popup-content').animate({'opacity': '0'}, {
623                duration: that.params.animateTimeout,
624                complete: function () {
625                    that.popup.hide();
626                    that.popup.detach();
627                    that.log('trigger:bxmaker.geoip.popup.hide.after', {
628                        'popup': that.popup
629                    });
630                    $(document).trigger('bxmaker.geoip.popup.hide.after', {
631                        'popup': that.popup
632                    });
633                }
634            });
635        };
636
637        /**
638         * Показ окна с выбором, поиском города
639         */
640        BXmakerGeoIPCityConstructor.prototype.popupShow = function () {
641            var that = this;
642            that.log('trigger:bxmaker.geoip.popup.show.before');
643            $(document).trigger('bxmaker.geoip.popup.show.before');
644
645            that.log('popup show');
646
647            $('body').append(that.popup);
648            that.popup.show();
649            that.popup.find('.js-bxmaker__geoip__popup-background').animate({'opacity': '1'}, that.params.animateTimeout);
650            that.popup.find('.js-bxmaker__geoip__popup-content').animate({'opacity': '1'}, {
651                duration: that.params.animateTimeout,
652                complete: function () {
653                    that.log('trigger:bxmaker.geoip.popup.show.after', {
654                        'popup': that.popup
655                    });
656                    $(document).trigger('bxmaker.geoip.popup.show.after', {
657                        'popup': that.popup
658                    });
659                }
660            });
661        };
662
663
664        BXmakerGeoIPCityConstructor.prototype.search = function (query, success, error) {
665            var that = this;
666
667            var urlparams = that.getJsonFromUrl();
668
669            that.log('trigger:bxmaker.geoip.search.before', {
670                'query': query,
671                'success': success,
672                'error': error
673            });
674            $(document).trigger('bxmaker.geoip.search.before', {
675                'query': query,
676                'success': success,
677                'error': error
678            });
679
680            if (that.isUseYandexSearch()) {
681                that.log('search in yandex - ' + query);
682
683
684                window.BXmakerGeoIPYandexGeo.getConnection().geocode(query, {
685                    'kind': 'locality',
686                    'results': 100,
687                    'json': true
688                })
689                    .then(function (result) {
690
691                        that.log('Yandex geocoder success', result);
692
693                        var collection = result.GeoObjectCollection;
694                        var items = [];
695
696                        var responseItems = result.GeoObjectCollection.featureMember;
697                        var responseItem = false;
698                        var responseItemAddress = [];
699                        var item = {};
700                        var bSkip = false;
701                        var arLngLat = [0, 0];
702
703                        for (var i in responseItems) {
704                            responseItem = responseItems[i];
705                            responseItemAddress = responseItem.GeoObject.metaDataProperty.GeocoderMetaData.Address.Components;
706
707                            if (responseItem.GeoObject.metaDataProperty.GeocoderMetaData.kind != 'locality' && responseItem.GeoObject.metaDataProperty.GeocoderMetaData.kind != 'province') continue;
708
709                            item = {
710                                'location': responseItem.GeoObject.metaDataProperty.GeocoderMetaData.id,
711                                'city': responseItem.GeoObject.name,
712                                'city_id': responseItem.GeoObject.metaDataProperty.GeocoderMetaData.id,
713                                'country': '',
714                                'country_id': 0,
715                                'region': '',
716                                'region_id': 0,
717                                'area': '',
718                                'zip': '000000',
719                                'range': 0,
720                                'lng': 0,
721                                'lat': 0,
722                                'yandex': 1
723                            };
724
725                            bSkip = false;
726                            for (var ci = 0; ci < that.params.yandexSearchSkipWords.length; ci++) {
727                                if (item['city'].indexOf(that.params.yandexSearchSkipWords[ci].replace(/^\s+/, '').replace(/\s+$/)) != -1) {
728                                    that.log('Skip location ' + item['city'] + ': skip word = ' + that.params.yandexSearchSkipWords[ci]);
729                                    bSkip = true;
730                                }
731                            }
732
733                            if (bSkip) continue;
734
735                            arLngLat = responseItem.GeoObject.Point.pos.split(' ');
736                            item['lng'] = arLngLat[0];
737                            item['lat'] = arLngLat[1];
738
739                            for (var ai in responseItemAddress) {
740                                switch (responseItemAddress[ai].kind) {
741                                    case 'locality': {
742                                        item['city'] = responseItemAddress[ai].name;
743                                        break;
744                                    }
745                                    case 'area': {
746                                        item['area'] = responseItemAddress[ai].name;
747                                        break;
748                                    }
749                                    case 'province': {
750                                        item['region'] = responseItemAddress[ai].name;
751                                        break;
752                                    }
753                                    case 'country': {
754                                        item['country'] = responseItemAddress[ai].name;
755                                        break;
756                                    }
757                                }
758                            }
759
760                            items.push(item);
761                        }
762
763                        items.splice(10);
764
765                        success({
766                            response: {
767                                items: items,
768                                count: items.length
769                            }
770                        });
771
772                        that.log('trigger:bxmaker.geoip.search.after', {
773                            response: {
774                                items: items,
775                                count: items.length
776                            }
777                        });
778                        $(document).trigger('bxmaker.geoip.search.after', {
779                            response: {
780                                items: items,
781                                count: items.length
782                            }
783                        });
784
785                    }, function (r) {
786                        that.logError('Yandex geocoder error', r);
787
788                        error(r);
789                        that.log('trigger:bxmaker.geoip.search.after', {
790                            'error': {
791                                'code': 'error_ajax',
792                                'msg': 'error response',
793                                'more': r
794                            }
795                        });
796                        $(document).trigger('bxmaker.geoip.search.after', {
797                            'error': {
798                                'code': 'error_ajax',
799                                'msg': 'error response',
800                                'more': r
801                            }
802                        });
803                    });
804            }
805            else {
806                that.log('search in bitrix - ' + query);
807
808                $.ajax({
809                    type: 'POST',
810                    url: that.baseParams.ajaxUrl + (!!urlparams && !!urlparams.clear_cache ? '?clear_cache=' + urlparams.clear_cache : ''),
811                    dataType: 'json',
812                    data: {
813                        method: 'search',
814                        parameters: that.baseParams.parameters,
815                        template: that.baseParams.template,
816                        siteId: that.baseParams.siteId,
817                        query: query
818                    },
819                    error: function (r) {
820                        if (typeof error == 'function') {
821                            that.logError('Error connection', r);
822
823                            error(r);
824                        }
825                        that.log('trigger:bxmaker.geoip.search.after', {
826                            'error': {
827                                'code': 'error_ajax',
828                                'msg': 'error response',
829                                'more': r
830                            }
831                        });
832                        $(document).trigger('bxmaker.geoip.search.after', {
833                            'error': {
834                                'code': 'error_ajax',
835                                'msg': 'error response',
836                                'more': r
837                            }
838                        });
839                    },
840                    success: function (r) {
841                        if (!!r.response) {
842                            if (typeof success == 'function') {
843                                that.log('Search success', r);
844
845                                success(r);
846                            }
847                        }
848                        else if (!!r.error) {
849                            if (typeof error == 'function') {
850                                that.logError('Error', r);
851
852                                error(r);
853                            }
854                        }
855                        that.log('trigger:bxmaker.geoip.search.after', r);
856                        $(document).trigger('bxmaker.geoip.search.after', r);
857                    }
858                });
859            }
860            return true;
861        };
862
863        /**
864         * Установка в качестве текущего Ð
864½Ð¾Ð²Ð¾Ð³Ð¾ местоположения
865         * @param id - идентификатор нового местоположения
866         * @param params
867         *
868         * @event "bxmaker.geoip.select.location.before"
869         * @event "bxmaker.geoip.select.location.after"
870         * @returns {boolean}
871         */
872        BXmakerGeoIPCityConstructor.prototype.selectLocation = function (id, params) {
873            var that = this;
874            var params = params || {};
875            var currentLocation = that.getLocation();
876            var currentCity = that.getCity();
877            var urlparams = that.getJsonFromUrl();
878
879            that.log('trigger:bxmaker.geoip.select.location.before', {
880                id: id,
881                params: params
882            });
883            $(document).trigger('bxmaker.geoip.select.location.before', {
884                id: id,
885                params: params
886            });
887
888            that.log('select location ', id, params);
889
890            params['parameters'] = that.baseParams.parameters;
891            params['template'] = that.baseParams.template;
892            params['siteId'] = that.baseParams.siteId;
893
894            if (id) {
895                params['method'] = 'selectLocation';
896                params['id'] = id;
897            }
898            else {
899                params['method'] = 'selectYandexLocation';
900            }
901
902            $.ajax({
903                type: 'POST',
904                url: that.baseParams.ajaxUrl + (!!urlparams && !!urlparams.clear_cache ? '?clear_cache=' + urlparams.clear_cache : ''),
905                dataType: 'json',
906                data: params,
907                error: function (r) {
908                    that.logError('error ajax select location', r);
909
910                    that.log('trigger: bxmaker.geoip.select.location.after', {
911                        'error': {
912                            'code': 'error_ajax',
913                            'msg': 'error response',
914                            'more': r
915                        }
916                    });
917                    $(document).trigger('bxmaker.geoip.select.location.after', {
918                        'error': {
919                            'code': 'error_ajax',
920                            'msg': 'error response',
921                            'more': r
922                        }
923                    });
924                },
925                success: function (r) {
926                    // 1. Читаем город (используем встроенную функцию или правильную куку с точками!)
927                    var newCity = that.getCity();
928
929                    if (!newCity) {
930                        var matches = document.cookie.match(/(?:^|; )bxmaker\.geoip\.2\.8\.1_s1_city=([^;]*)/);
931                        if (matches) {
932                            try { newCity = decodeURIComponent(matches[1].replace(/\+/g, ' ')).trim(); } catch(e) {}
933                        }
934                    }
935
936                    if (newCity) {
937                        var cityRedirects = {};
938                        try {
939                            var request = new XMLHttpRequest();
940                            // Антикэш параметр, чтобы всегда получать свежий JSON
941                            request.open('GET', '/local/configs/city_mapping.json?t=' + new Date().getTime(), false);
942                            request.send(null);
943
944                            if (request.status === 200) {
945                                cityRedirects = JSON.parse(request.responseText);
946                            }
947                        } catch (e) {}
948
949                        if (cityRedirects.hasOwnProperty(newCity)) {
950                            var subdomain = cityRedirects[newCity];
951                            var targetDomain = subdomain ? subdomain + '.sumitec.ru' : 'sumitec.ru';
952
953                            if (location.hostname !== targetDomain) {
954                                location.replace(
955                                    location.protocol + '//' +
956                                    targetDomain +
957                                    location.pathname +
958                                    location.search
959                                );
960                                return; // Успех! Уходим на другой домен и прерываем скрипт
961                            }
962                        }
963                    }
964
965                    // Если домен менять не нужно (или мы уже на нем) — просто обновляем страницу
966                    window.location.reload();
967                }
968            });
969
970            return true;
971        };
972
973        /**
974         * Расставляет название города в размеченные места, вызывает осбытие
975         * @event "bxmaker.geoip.city.show"
976         */
977        BXmakerGeoIPCityConstructor.prototype.showCity = function () {
978            var that = this;
979
980            var params = that.getFullData();
981
982            that.log('show city', params);
983
984            $('.js-bxmaker__geoip__city-name-global').text(params['city']);
985
986            //событие показа текущего города, после простановки в размеченных местах
987            that.log('trigger: bxmaker.geoip.city.show', params);
988            $(document).trigger('bxmaker.geoip.city.show', params);
989        };
990
991        /**
992         * Возврашщает массив с описание местоположения пользователя
993         * @returns {mixed}
994         */
995        BXmakerGeoIPCityConstructor.prototype.getFullData = function () {
996            var that = this;
997
998            return {
999                'location': that.getLocation(),
1000                'location_code': that.getLocationCode(),
1001                'city': that.getCity(),
1002                'city_id': that.getLocation(),
1003                'country': that.getCountry(),
1004                'country_id': that.getCountryId(),
1005                'region': that.getRegion(),
1006                'region_id': that.getRegionId(),
1007                'area': that.getArea(),
1008                'zip': that.getZip(),
1009                'range': that.getRange(),
1010                'lng': that.getLng(),
1011                'lat': that.getLat(),
1012                'yandex': that.getYandex()
1013            };
1014        };
1015
1016
1017        /**
1018         * Возвращает идентификатор местоположения
1019         * @returns {number}
1020         */
1021        BXmakerGeoIPCityConstructor.prototype.getLocation = function () {
1022            var that = this;
1023            return that.cookie('location') || 0;
1024        };
1025
1026        /**
1027         * Возвращает код местоположения, например 000001256
1028         * @returns {string}
1029         */
1030        BXmakerGeoIPCityConstructor.prototype.getLocationCode = function () {
1031            var that = this;
1032            return that.cookie('location_code') || '';
1033        };
1034
1035        BXmakerGeoIPCityConstructor.prototype.getCity = function () {
1036            var that = this;
1037            return that.cookie('city') || '';
1038        };
1039
1040        BXmakerGeoIPCityConstructor.prototype.getCityId = function () {
1041            var that = this;
1042            return that.cookie('city_id') || 0;
1043        };
1044
1045        BXmakerGeoIPCityConstructor.prototype.getCountry = function () {
1046            var that = this;
1047            return that.cookie('country') || false;
1048        };
1049
1050        BXmakerGeoIPCityConstructor.prototype.getCountryId = function () {
1051            var that = this;
1052            return that.cookie('country_id') || 0;
1053        };
1054
1055        BXmakerGeoIPCityConstructor.prototype.getRegion = function () {
1056            var that = this;
1057            return that.cookie('region') || false;
1058        };
1059
1060        BXmakerGeoIPCityConstructor.prototype.getRegionId = function () {
1061            var that = this;
1062            return that.cookie('region_id') || 0;
1063        };
1064
1065        BXmakerGeoIPCityConstructor.prototype.getArea = function () {
1066            var that = this;
1067            return that.cookie('area') || false;
1068        };
1069
1070        /**
1071         * Возвращает индекс местоположения если он есть
1072         * @returns {string}
1073         */
1074        BXmakerGeoIPCityConstructor.prototype.getZip = function () {
1075            var that = this;
1076            return that.cookie('zip') || '';
1077        };
1078
1079        BXmakerGeoIPCityConstructor.prototype.getLng = function () {
1080            var that = this;
1081            return that.cookie('lng') || 0;
1082        };
1083
1084        BXmakerGeoIPCityConstructor.prototype.getLat = function () {
1085            var that = this;
1086            return that.cookie('lat') || 0;
1087        };
1088
1089        BXmakerGeoIPCityConstructor.prototype.getRange = function () {
1090            var that = this;
1091            return that.cookie('range') || false;
1092        };
1093
1094        /**
1095         * Возвращает флаг включен ли поиск города через яндекс
1096         * @returns {boolean}
1097         */
1098        BXmakerGeoIPCityConstructor.prototype.getYandex = function () {
1099            var that = this;
1100            return !!(that.cookie('yandex') || that.isUseYandexSearch());
1101        };
1102
1103        /**
1104         * Проверка необходимости в редиректе и переадресация в случае необходимости
1105         */
1106        BXmakerGeoIPCityConstructor.prototype.checkRedirect = function () {
1107        /*
1108            var that = this;
1109            var currentCity = that.getCity();
1110            
1111            var cityRedirects = {};
1112            try {
1113                var request = new XMLHttpRequest();
1114                request.open('GET', '/local/configs/city_mapping.json', false);
1115                request.send(null);
1116                
1117                if (request.status === 200) {
1118                    cityRedirects = JSON.parse(request.responseText);
1119                }
1120            } catch (e) {
1121                console.error('Error loading city mapping:', e);
1122            }
1123            
1124            if (cityRedirects.hasOwnProperty(currentCity)) {
1125                var subdomain = cityRedirects[currentCity];
1126                var targetDomain = subdomain ? subdomain + '.sumitec.ru' : 'sumitec.ru';
1127                
1128                if (location.hostname !== targetDomain) {
1129                    location.replace(
1130                        location.protocol + '//' + 
1131                        targetDomain + 
1132                        location.pathname + 
1133                        location.search
1134                    );
1135                }
1136            }
1137            */
1138        };
1139        
1140        /**
1141         * Проверка возможности исопльзовать локальные хранилища
1142         * @returns {boolean}
1143         */
1144        BXmakerGeoIPCityConstructor.prototype.storageTest = function () {
1145            try {
1146                return 'localStorage' in window && window['localStorage'] !== null;
1147            } catch (e) {
1148                return false;
1149            }
1150        };
1151
1152        /**
1153         * Сохраняет данные в локальном хранилище
1154         * @param key
1155         * @param value
1156         * @returns {*}
1157         */
1158        BXmakerGeoIPCityConstructor.prototype.storageSet = function (key, value) {
1159            var that = this;
1160            key = that.baseParams.version + '|' + key;
1161            try {
1162                if (value === null) {
1163                    return window.localStorage.removeItem(key);
1164                }
1165                else {
1166                    return window.localStorage.setItem(key, JSON.stringify({
1167                        "data": value,
1168                        "time": (new Date()).getTime()
1169                    }));
1170                }
1171            } catch (e) {
1172                if (e == QUOTA_EXCEEDED_ERR) {
1173                    that.logError('LocalStorage limit exceeded');
1174                }
1175                else {
1176                    that.logError('localStorage:', e);
1177                }
1178                return false;
1179            }
1180        };
1181
1182        /**
1183         * Возвращает данные из локального хранилища
1184         * @param key
1185         * @returns {*}
1186         */
1187        BXmakerGeoIPCityConstructor.prototype.storageGet = function (key) {
1188            var that = this;
1189            var time = (new Date()).getTime();
1190            key = that.baseParams.version + '|' + key;
1191            try {
1192                var obj = JSON.parse(window.localStorage.getItem(key));
1193                if (!!obj) {
1194                    if (!!obj['time'] && obj['time'] > (time - 60 * 60 * 24 * 3)) {
1195                        return obj['data'];
1196                    }
1197                }
1198                return false;
1199            } catch (e) {
1200                that.logError('localStorage:', e);
1201                return false;
1202            }
1203        };
1204
1205        window.BXmakerGeoIPCity = new BXmakerGeoIPCityConstructor();
1206
1207    })();
1208}
1209
1210
1211if (!!window.BXmakerGeoIPYandexGeo === false) {
1212
1213    (function () {
1214
1215        var GeoIPYandexGeo = function () {
1216            var that = this;
1217
1218            that.bInit = false;
1219            that.ymap = false;
1220            that.params = {};
1221            that.debug = false;
1222            that.cb = [];
1223        };
1224
1225        GeoIPYandexGeo.prototype.log = function () {
1226            if (this.debug) {
1227                var args = Array.prototype.slice.call(arguments);
1228                args.unshift('bxmaker:geoip.city.yandex.geo: ');
1229                console.log.apply(console, args);
1230            }
1231        };
1232        GeoIPYandexGeo.prototype.logError = function () {
1233            if (this.debug) {
1234                var args = Array.prototype.slice.call(arguments);
1235                args.unshift('bxmaker:geoip.city.yandex.geo: ');
1236                console.error.apply(console, args);
1237            }
1238        };
1239
1240
1241        GeoIPYandexGeo.prototype.init = function (params) {
1242            var that = this;
1243            var link = 'https://api-maps.yandex.ru/2.1/?lang=ru_RU&load=geolocation,geocode&onload=BXmakerGeoIPYandexGeo.onload&ns=';
1244
1245            if (that.bInit) return true;
1246
1247            //парамтеры
1248            that.params = params;
1249
1250            // проверка включена ли отладка вручную
1251            if (!!window.BXmakerGeoIPCity && window.BXmakerGeoIPCity.cookie('debug') == 'Y') {
1252                that.debug = true;
1253            }
1254
1255            that.bInit = true; //&ns=BXmakerGeoIPYandexMap
1256
1257            if (that.params.yandexApiKey) {
1258                link += '&apikey=' + that.params.yandexApiKey;
1259            }
1260            else {
1261                that.logError('Api key for yandex map is not set');
1262            }
1263
1264            $('head').append($('<script id="BXmakerGeoIPYandexGeo" type="text/javascript" src="' + link + '" />'));
1265        };
1266
1267        GeoIPYandexGeo.prototype.onload = function (ym) {
1268            var that = this;
1269            that.ymap = ym;
1270
1271            that.log('API is loaded');
1272
1273            that.log('trigger: bxmaker.geoip.yandex.geo.loaded');
1274            $(document).trigger('bxmaker.geoip.yandex.geo.loaded');
1275        };
1276
1277        GeoIPYandexGeo.prototype.getConnection = function () {
1278            var that = this;
1279            return that.ymap;
1280        };
1281
1282
1283        window.BXmakerGeoIPYandexGeo = new GeoIPYandexGeo();
1284    })();
1285
1286}

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.