@snabcentr/client-core 2.50.0 → 2.52.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -3,7 +3,7 @@ import { InjectionToken, inject, PLATFORM_ID, Injectable, Inject, Optional, LOCA
3
3
  import { WA_LOCAL_STORAGE, WA_USER_AGENT, WA_WINDOW } from '@ng-web-apis/common';
4
4
  import { filterByKey, toValue, WA_STORAGE_EVENT, StorageService } from '@ng-web-apis/storage';
5
5
  import * as i1 from 'rxjs';
6
- import { startWith, Subject, ReplaySubject, partition, combineLatest, map, debounceTime, switchMap, of, tap, shareReplay, BehaviorSubject, distinctUntilKeyChanged, skip, first, distinctUntilChanged, filter, expand, takeWhile, toArray, catchError, concatMap, throwError, finalize, takeUntil, interval, share, scan } from 'rxjs';
6
+ import { startWith, Subject, ReplaySubject, partition, combineLatest, map, debounceTime, switchMap, of, tap, shareReplay, BehaviorSubject, distinctUntilKeyChanged, skip, first, distinctUntilChanged, filter, expand, takeWhile, toArray, catchError, throwError, concatMap, finalize, takeUntil, interval, share, scan } from 'rxjs';
7
7
  import { isPlatformBrowser, isPlatformServer, DOCUMENT, formatDate } from '@angular/common';
8
8
  import { tuiCreateTokenFromFactory, tuiCreateToken, TuiDay, tuiIsPresent, tuiPure } from '@taiga-ui/cdk';
9
9
  import * as i1$1 from '@angular/common/http';
@@ -12,9 +12,9 @@ import { tuiCleanObject } from '@taiga-ui/addon-doc/utils';
12
12
  import { __decorate } from 'tslib';
13
13
  import * as i2 from '@angular/router';
14
14
  import { ActivatedRoute, Router, NavigationEnd } from '@angular/router';
15
+ import { isString, isMatch } from 'lodash-es';
15
16
  import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
16
17
  import { objectToSnake, objectToCamel, toSnake } from 'ts-case-convert';
17
- import { isString, isMatch } from 'lodash-es';
18
18
  import { format, parse } from 'date-fns';
19
19
  import * as i1$2 from '@angular/platform-browser';
20
20
  import { Meta, Title } from '@angular/platform-browser';
@@ -1176,6 +1176,7 @@ class ScProduct extends ScSeoResource {
1176
1176
  this.properties = productDTO.properties;
1177
1177
  this.discount = productDTO.discount;
1178
1178
  this.ord = ord;
1179
+ this.isHidden = productDTO.isHidden;
1179
1180
  }
1180
1181
  }
1181
1182
  /**
@@ -2957,18 +2958,6 @@ class ScCatalogService {
2957
2958
  * {@link Map} коллекция пар ключ-значение для кэшированных товаров категории каталога.
2958
2959
  */
2959
2960
  this.categoryProductsMap = new Map();
2960
- /**
2961
- * {@link Map} коллекция пар ключ-значение для кэшированных рекомендуемых товаров категории.
2962
- *
2963
- * @deprecated
2964
- */
2965
- this.recommendedProductsByCategoryMap = new Map();
2966
- /**
2967
- * {@link Map} коллекция пар ключ-значение для кэшированных рекомендуемых товаров товара.
2968
- *
2969
- * @deprecated
2970
- */
2971
- this.recommendedProductsByProductMap = new Map();
2972
2961
  /**
2973
2962
  * {@link Map} коллекция пар ключ-значение для кэширования истории цен.
2974
2963
  */
@@ -2978,9 +2967,13 @@ class ScCatalogService {
2978
2967
  */
2979
2968
  this.idOrSlugPipe = inject(ScIdOrSlugPipe);
2980
2969
  /**
2981
- * {@link Map} коллекция пар ключ-значение для сопоставления slug и id категорий при кеширование запросов, если идентификатор отличаться от установленного в проекте (slug/id).
2970
+ * {@link Map} коллекция пар ключ-значение для сопоставления slug и id категорий при кешировании запросов, если идентификатор отличается от установленного в проекте (slug/id).
2982
2971
  */
2983
2972
  this.categoryIdOrSlugMap = new Map();
2973
+ /**
2974
+ * {@link Map} коллекция пар ключ-значение для сопоставления slug и id товаров при кешировании запросов, если идентификатор отличается от установленного в проекте (slug/id).
2975
+ */
2976
+ this.productIdOrSlugMap = new Map();
2984
2977
  /**
2985
2978
  * Число первых записей товаров со скидкой.
2986
2979
  */
@@ -3009,7 +3002,6 @@ class ScCatalogService {
3009
3002
  .subscribe(() => {
3010
3003
  this.idCategoryMap.clear();
3011
3004
  this.categoryMap.clear();
3012
- this.productMap.clear();
3013
3005
  this.productHistoryMap.clear();
3014
3006
  });
3015
3007
  }
@@ -3028,21 +3020,6 @@ class ScCatalogService {
3028
3020
  this.idCategoryMap.delete(categoryIdOrSlug?.toString());
3029
3021
  return undefined;
3030
3022
  }
3031
- /**
3032
- * Возвращает товар из коллекции каталога.
3033
- *
3034
- * @deprecated Удалить в рамках задачи TASK[#10153].
3035
- *
3036
- * @param productIdOrSlug Идентификатор или slug товара/услуги.
3037
- */
3038
- getProductFromMap(productIdOrSlug) {
3039
- const product = this.productMap.get(productIdOrSlug.toString());
3040
- if (product) {
3041
- return product;
3042
- }
3043
- this.productMap.delete(productIdOrSlug.toString());
3044
- return undefined;
3045
- }
3046
3023
  /**
3047
3024
  * Создает запрос получения списка категорий товаров или список корневых категорий, если идентификатор категории не указан.
3048
3025
  *
@@ -3192,12 +3169,28 @@ class ScCatalogService {
3192
3169
  *
3193
3170
  * @param productIdOrSlug Идентификатор или slug товара/услуги.
3194
3171
  */
3195
- getProductInfo$(productIdOrSlug) {
3196
- const productMap = this.productMap.get(productIdOrSlug.toString());
3197
- if (productMap) {
3198
- return of(productMap);
3172
+ getProductData$(productIdOrSlug) {
3173
+ return this.http.get(`${this.urls.apiUrl}/catalog/products/${productIdOrSlug}`).pipe(map((productDTO) => new ScProduct(productDTO)), tap((product) => {
3174
+ if (productIdOrSlug && typeof this.idOrSlugPipe.transform(product) !== typeof productIdOrSlug) {
3175
+ this.productIdOrSlugMap.set(this.idOrSlugPipe.transform(product), productIdOrSlug);
3176
+ }
3177
+ }));
3178
+ }
3179
+ getProductDataCached$(productIdOrSlug) {
3180
+ const valueFromMap = this.productIdOrSlugMap.get(productIdOrSlug);
3181
+ if (valueFromMap) {
3182
+ // eslint-disable-next-line no-param-reassign
3183
+ productIdOrSlug = valueFromMap;
3184
+ }
3185
+ let cachedItem = this.productMap.get(productIdOrSlug.toString());
3186
+ if (!cachedItem) {
3187
+ cachedItem = new ScCachedItem(this.cacheLifeTime.categoryData, this.getProductData$(productIdOrSlug));
3188
+ this.productMap.set(productIdOrSlug.toString(), cachedItem);
3189
+ }
3190
+ if (!cachedItem.cachedDataIsActual()) {
3191
+ cachedItem.update();
3199
3192
  }
3200
- return this.http.get(`${this.urls.apiUrl}/catalog/products/${productIdOrSlug}`).pipe(map((productDTO) => new ScProduct(productDTO)), tap((product) => this.productMap.set(product.id.toString(), product)));
3193
+ return cachedItem.item$;
3201
3194
  }
3202
3195
  /**
3203
3196
  * Создаёт запрос на получение генерируемого файла прайс-листа в формате {@link Blob}, и выгружает пользователю в браузер.
@@ -3220,51 +3213,6 @@ class ScCatalogService {
3220
3213
  });
3221
3214
  }));
3222
3215
  }
3223
- /**
3224
- * Создает запрос получения списка ранее заказанных товаров.
3225
- *
3226
- * @deprecated Удалить в рамках задачи TASK[#10155].
3227
- */
3228
- getPreviouslyOrderedProducts$() {
3229
- if (!this.currentUserPreviouslyOrdered.cachedDataIsActual()) {
3230
- this.currentUserPreviouslyOrdered.update();
3231
- }
3232
- return this.currentUserPreviouslyOrdered.item$;
3233
- }
3234
- /**
3235
- * Создает запрос на получение списка рекомендованных товаров для категории.
3236
- *
3237
- * @param categoryIdOrSlug Идентификатор или slug категории товаров.
3238
- * @deprecated
3239
- */
3240
- getRecommendedProductsByCategory$(categoryIdOrSlug) {
3241
- let cachedItem = this.recommendedProductsByCategoryMap.get(categoryIdOrSlug.toString());
3242
- if (!cachedItem) {
3243
- // Устанавливаем время жизни cachedItem равное, потому что нам не важно время жизни. Нам нужен функционал update().
3244
- cachedItem = new ScCachedItem(0, this.http
3245
- .get(`${this.urls.apiUrl}/catalog/categories/${categoryIdOrSlug}/recommendations`)
3246
- .pipe(map((productsDTO) => productsDTO.map((product) => new ScProduct(product)))));
3247
- this.recommendedProductsByCategoryMap.set(categoryIdOrSlug.toString(), cachedItem);
3248
- }
3249
- return cachedItem.item$;
3250
- }
3251
- /**
3252
- * Создает запрос на получение списка рекомендованных товаров для продукта.
3253
- *
3254
- * @param productIdOrSlug Идентификатор или slug товара/услуги.
3255
- * @deprecated
3256
- */
3257
- getRecommendedProductsByProduct$(productIdOrSlug) {
3258
- let cachedItem = this.recommendedProductsByProductMap.get(productIdOrSlug.toString());
3259
- if (!cachedItem) {
3260
- // Устанавливаем время жизни cachedItem равное, потому что нам не важно время жизни. Нам нужен функционал update().
3261
- cachedItem = new ScCachedItem(0, this.http
3262
- .get(`${this.urls.apiUrl}/catalog/products/${productIdOrSlug}/recommendations`)
3263
- .pipe(map((productsDTO) => productsDTO.map((product) => new ScProduct(product)))));
3264
- this.recommendedProductsByProductMap.set(productIdOrSlug.toString(), cachedItem);
3265
- }
3266
- return cachedItem.item$;
3267
- }
3268
3216
  /**
3269
3217
  * Запрос на уведомление пользователя о поступлении продукта.
3270
3218
  *
@@ -3587,6 +3535,37 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.12", ngImpo
3587
3535
  args: [SC_URLS]
3588
3536
  }] }, { type: ScCatalogService }] });
3589
3537
 
3538
+ /**
3539
+ * Перечисление, представляющее различные формы обратной связи.
3540
+ */
3541
+ var ScFeedbackForms;
3542
+ (function (ScFeedbackForms) {
3543
+ /**
3544
+ * Пожелания и предложения по улучшению сайта.
3545
+ */
3546
+ ScFeedbackForms["suggest"] = "suggest";
3547
+ /**
3548
+ * Оставить заявку на получение бесплатных образцов.
3549
+ */
3550
+ ScFeedbackForms["samples"] = "samples";
3551
+ /**
3552
+ * Форма обратной связи со страницы контактов.
3553
+ */
3554
+ ScFeedbackForms["contacts"] = "contacts";
3555
+ /**
3556
+ * Форма обратной связи со страницы вакансий.
3557
+ */
3558
+ ScFeedbackForms["vacancies"] = "vacancies";
3559
+ /**
3560
+ * Задать вопрос.
3561
+ */
3562
+ ScFeedbackForms["questions"] = "questions";
3563
+ /**
3564
+ * Заказать изготовление москитной сетки.
3565
+ */
3566
+ ScFeedbackForms["mosquitoes"] = "mosquitoes";
3567
+ })(ScFeedbackForms || (ScFeedbackForms = {}));
3568
+
3590
3569
  /**
3591
3570
  * Перечисление типов контактов по социальным сетям.
3592
3571
  */
@@ -3633,119 +3612,107 @@ class ScUploadedFile {
3633
3612
  const SC_IS_HEADER_REQUIRED = new HttpContextToken(() => true);
3634
3613
 
3635
3614
  /**
3636
- * Сервис обратной связи.
3615
+ * Значения пагинации списка товаров категории по умолчанию.
3637
3616
  */
3638
- class ScFeedbackService {
3617
+ const SC_PRODUCT_PAGINATION_DEFAULT_OPTIONS = {
3618
+ perPage: 20,
3619
+ page: 0,
3620
+ };
3621
+ /**
3622
+ * Токен значений пагинации списка товаров в каталоге по умолчанию.
3623
+ */
3624
+ const SC_PRODUCT_PAGINATION_OPTIONS = tuiCreateToken(SC_PRODUCT_PAGINATION_DEFAULT_OPTIONS);
3625
+ /**
3626
+ * Токен {@link EventEmitter} событие нажатия на кнопку "Показать следующие позиции категории".
3627
+ */
3628
+ const SC_NEXT_PAGE_PAGINATION_CLICK = tuiCreateToken(new EventEmitter());
3629
+
3630
+ /**
3631
+ * Сервис поиска по каталогу.
3632
+ */
3633
+ class ScSearchService {
3639
3634
  /**
3640
- * Инициализирует экземпляр класса {@link ScFeedbackService}.
3635
+ * Инициализирует экземпляр класса {@link ScSearchService}.
3641
3636
  *
3642
3637
  * @param http HTTP-клиент.
3638
+ * @param urls Список ссылок на разделы backend'a.
3643
3639
  * @param userMetrikaService Сервис для сбора метрик о действиях пользователей.
3644
- * @param feedbackApi Данные для взаимодействия с API обратной связи.
3645
3640
  */
3646
- constructor(http, userMetrikaService, feedbackApi) {
3641
+ constructor(http, urls, userMetrikaService) {
3647
3642
  this.http = http;
3643
+ this.urls = urls;
3648
3644
  this.userMetrikaService = userMetrikaService;
3649
- this.feedbackApi = feedbackApi;
3650
3645
  /**
3651
- * Список форм обратной связи.
3646
+ * {@link BehaviorSubject} поискового запрос.
3652
3647
  */
3653
- this.feedbackForms$ = this.http
3654
- .get(`${this.feedbackApi.apiUrl}/feedback/forms`, {
3655
- context: new HttpContext().set(SC_AUTH_ADD_HEADER_REQUIRED, false).set(SC_IS_HEADER_REQUIRED, false),
3656
- headers: {
3657
- [this.feedbackApi.authTokenName]: this.feedbackApi.authToken,
3658
- },
3659
- })
3660
- .pipe(shareReplay(1));
3648
+ this.searchTerm$ = new BehaviorSubject(null);
3661
3649
  }
3662
3650
  /**
3663
- * Отправляет сообщение обратной связи.
3651
+ * Выполняет упрощенный поиск товаров и категорий. Возвращает ограниченное количество записей.
3664
3652
  *
3665
- * @param formSlug Символьное обозначение (slug) формы.
3666
- * @param feedbackMessage Объект сообщения обратной связи.
3653
+ * @param term Поисковый запрос.
3667
3654
  */
3668
- sendFeedback(formSlug, feedbackMessage) {
3669
- return this.http
3670
- .post(`${this.feedbackApi.apiUrl}/feedback/${formSlug}`, feedbackMessage, {
3671
- context: new HttpContext().set(SC_AUTH_ADD_HEADER_REQUIRED, false).set(SC_IS_HEADER_REQUIRED, false),
3672
- headers: {
3673
- [this.feedbackApi.authTokenName]: this.feedbackApi.authToken,
3674
- },
3675
- })
3676
- .pipe(tap(() => {
3655
+ simple$(term) {
3656
+ return this.http.get(`${this.urls.apiUrl}/catalog/search/simple`, { params: { term: term } }).pipe(tap(() => {
3677
3657
  this.userMetrikaService.emitUserMetrikaEvent({
3678
- target: ScUserMetrikaGoalsEnum.feedbackSent,
3658
+ target: ScUserMetrikaGoalsEnum.catalogSearch,
3659
+ params: {
3660
+ search_type: 'simple',
3661
+ term: term,
3662
+ },
3679
3663
  });
3680
3664
  }));
3681
3665
  }
3682
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.12", ngImport: i0, type: ScFeedbackService, deps: [{ token: i1$1.HttpClient }, { token: ScUserMetrikaService }, { token: SC_FEEDBACK_API }], target: i0.ɵɵFactoryTarget.Injectable }); }
3683
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.12", ngImport: i0, type: ScFeedbackService, providedIn: 'root' }); }
3684
- }
3685
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.12", ngImport: i0, type: ScFeedbackService, decorators: [{
3686
- type: Injectable,
3687
- args: [{
3688
- providedIn: 'root',
3689
- }]
3690
- }], ctorParameters: () => [{ type: i1$1.HttpClient }, { type: ScUserMetrikaService }, { type: undefined, decorators: [{
3691
- type: Inject,
3692
- args: [SC_FEEDBACK_API]
3693
- }] }] });
3694
-
3695
- /**
3696
- * Сервис для работы с реквизитами и с обойной связью.
3697
- */
3698
- class ScRequisitesService {
3699
3666
  /**
3700
- * Инициализирует экземпляр класса {@link ScRequisitesService}.
3667
+ * Выполняет поиск категорий в каталоге.
3701
3668
  *
3702
- * @param http HTTP-клиент.
3703
- * @param urls Список ссылок на разделы backend'a.
3704
- * @param authService Сервис аутентификации.
3669
+ * @param term Поисковый запрос.
3705
3670
  */
3706
- constructor(http, urls, authService) {
3707
- this.http = http;
3708
- this.urls = urls;
3709
- this.authService = authService;
3710
- /**
3711
- * {@link BehaviorSubject} поискового запроса на странице контактов.
3712
- */
3713
- this.searchTerm$ = new BehaviorSubject(null);
3714
- /**
3715
- * {@link Map} коллекция пар ключ-значение для контактов менеджера по направлению продаж.
3716
- */
3717
- this.idManagerMap = new Map();
3718
- /**
3719
- * Создаёт запрос получения списка всех контактов.
3720
- */
3721
- this.contacts$ = this.authService.getAuthChange().pipe(switchMap(() => this.http.get(`${this.urls.apiUrl}/contacts`)), shareReplay(1));
3722
- /**
3723
- * Создаёт запрос получения списка контактов для решения возникающих вопросов.
3724
- */
3725
- this.personal$ = this.contacts$.pipe(map((contacts) => contacts.personal));
3726
- /**
3727
- * Создаёт запрос получения списка контактов розничных магазинов.
3728
- */
3729
- this.retail$ = this.contacts$.pipe(map((contacts) => contacts.retail), first(), shareReplay(1));
3730
- /**
3731
- * Создаёт запрос получения списка ссылок на социальные сети и другие каналы коммуникации.
3732
- */
3733
- this.socialMedia$ = this.contacts$.pipe(map((contacts) => contacts.socialMedia), first(), shareReplay(1));
3734
- /**
3735
- * Создаёт запрос получения списка контактов менеджеров по направлениям продаж.
3736
- */
3737
- this.directions$ = this.contacts$.pipe(map((contacts) => contacts.directions), tap((directions) => {
3738
- // eslint-disable-next-line guard-for-in,no-restricted-syntax
3739
- for (const key in directions) {
3740
- directions[Number.parseFloat(key)]?.forEach((manager) => {
3741
- this.mapManagers(Number.parseFloat(key), manager);
3671
+ categories$(term) {
3672
+ return this.http.get(`${this.urls.apiUrl}/catalog/search/categories`, { params: { term: term } }).pipe(tap(() => {
3673
+ this.userMetrikaService.emitUserMetrikaEvent({
3674
+ target: ScUserMetrikaGoalsEnum.catalogSearch,
3675
+ params: {
3676
+ search_type: 'categories',
3677
+ term: term,
3678
+ },
3679
+ });
3680
+ }), map((categories) => categories.map((item) => new ScCategory(item))));
3681
+ }
3682
+ /**
3683
+ * Выполняет полный поиск по всему прайс-листу.
3684
+ *
3685
+ * @param term Поисковый запрос.
3686
+ * @param showOrderedProducts Признак того, что необходимо вернуть ранее заказанные продукты.
3687
+ * @param showFavoriteProducts Признак того, что необходимо вернуть избранные продукты.
3688
+ * @param showDiscountedProducts Признак того, что необходимо вернуть продукты со скидкой.
3689
+ */
3690
+ full$(term, showOrderedProducts, showFavoriteProducts, showDiscountedProducts) {
3691
+ const params = {};
3692
+ if (term) {
3693
+ params['term'] = term;
3694
+ }
3695
+ if (showOrderedProducts) {
3696
+ params['show_ordered_products'] = Number(showOrderedProducts);
3697
+ }
3698
+ if (showFavoriteProducts) {
3699
+ params['show_favorite_products'] = Number(showFavoriteProducts);
3700
+ }
3701
+ if (showDiscountedProducts) {
3702
+ params['show_discounted_products'] = Number(showDiscountedProducts);
3703
+ }
3704
+ if (Object.keys(params).length > 0) {
3705
+ return this.http.get(`${this.urls.apiUrl}/catalog/search/full`, { params: params }).pipe(tap(() => {
3706
+ this.userMetrikaService.emitUserMetrikaEvent({
3707
+ target: ScUserMetrikaGoalsEnum.catalogSearch,
3708
+ params: {
3709
+ search_type: 'full',
3710
+ term: term,
3711
+ },
3742
3712
  });
3743
- }
3744
- }), first(), shareReplay(1));
3745
- /**
3746
- * Создаёт запрос получения списка реквизитов компании.
3747
- */
3748
- this.requisites$ = this.http.get(`${this.urls.apiUrl}/requisites`).pipe(shareReplay(1));
3713
+ }));
3714
+ }
3715
+ return throwError(() => new Error('Необходимо указать хотя бы один параметр.'));
3749
3716
  }
3750
3717
  /**
3751
3718
  * Устанавливает поисковый запрос в {@link BehaviorSubject}.
@@ -3761,16 +3728,373 @@ class ScRequisitesService {
3761
3728
  getSearchTermChange$() {
3762
3729
  return this.searchTerm$.asObservable();
3763
3730
  }
3764
- /**
3765
- * Возвращает поисковый запрос.
3766
- */
3767
- getCurrentSearchTerm() {
3768
- return this.searchTerm$.getValue();
3769
- }
3770
- /**
3771
- * Проходит по древовидному представлению контактов менеджеров и записывает каждого менеджера в {@link Map} по ключу идентификатора.
3772
- *
3773
- * @param directionId Идентификатор направления продаж.
3731
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.12", ngImport: i0, type: ScSearchService, deps: [{ token: i1$1.HttpClient }, { token: SC_URLS }, { token: ScUserMetrikaService }], target: i0.ɵɵFactoryTarget.Injectable }); }
3732
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.12", ngImport: i0, type: ScSearchService, providedIn: 'root' }); }
3733
+ }
3734
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.12", ngImport: i0, type: ScSearchService, decorators: [{
3735
+ type: Injectable,
3736
+ args: [{
3737
+ providedIn: 'root',
3738
+ }]
3739
+ }], ctorParameters: () => [{ type: i1$1.HttpClient }, { type: undefined, decorators: [{
3740
+ type: Inject,
3741
+ args: [SC_URLS]
3742
+ }] }, { type: ScUserMetrikaService }] });
3743
+
3744
+ /**
3745
+ * Токен поиска введенного терма.
3746
+ */
3747
+ const SEARCH_TERM = new InjectionToken('SEARCH_TERM');
3748
+ /**
3749
+ * Токен минимального количества введенных символов в поле поиска.
3750
+ */
3751
+ const SC_MIN_LENGTH_SEARCH_TERM = new InjectionToken('SC_MIN_LENGTH_SEARCH_TERM');
3752
+ /**
3753
+ * Токен максимального количества введенных символов в поле поиска.
3754
+ */
3755
+ const SC_MAX_LENGTH_SEARCH_TERM = new InjectionToken('SC_MAX_LENGTH_SEARCH_TERM');
3756
+ /**
3757
+ * Возвращает введенный терм для поиска.
3758
+ *
3759
+ * @param searchService Сервис поиска по каталогу.
3760
+ * @param minLengthSearchTerm Минимальное количество введенных символов в поле поиска.
3761
+ * @param maxLengthSearchTerm Максимальное количество введенных символов в поле поиска.
3762
+ */
3763
+ function searchTermFactory(searchService, minLengthSearchTerm, maxLengthSearchTerm) {
3764
+ return searchService
3765
+ .getSearchTermChange$()
3766
+ .pipe(map((searchTerm) => (searchTerm && searchTerm.length >= minLengthSearchTerm && searchTerm.length <= maxLengthSearchTerm ? searchTerm : '')));
3767
+ }
3768
+ /**
3769
+ * Провайдеры данных о поиске введенного терма.
3770
+ */
3771
+ const SEARCH_TERM_PROVIDERS = [
3772
+ {
3773
+ provide: SEARCH_TERM,
3774
+ deps: [ScSearchService, SC_MIN_LENGTH_SEARCH_TERM, SC_MAX_LENGTH_SEARCH_TERM],
3775
+ useFactory: searchTermFactory,
3776
+ },
3777
+ ];
3778
+
3779
+ /* eslint-disable no-param-reassign,no-return-assign,jsdoc/check-param-names */
3780
+ /**
3781
+ * Токен потока данных о виртуальной категории.
3782
+ */
3783
+ const SC_VIRTUAL_CATEGORY_INFO = new InjectionToken('A stream with current virtual category information');
3784
+ /**
3785
+ * Фабрика создания потока данных виртуальной категории.
3786
+ *
3787
+ * @param paramMap Параметры.
3788
+ * @param paramMap.paramMap Параметры.
3789
+ * @param catalogService.paramMap Параметры маршрута.
3790
+ * @param catalogService Сервис для работы с каталогом.
3791
+ */
3792
+ function virtualCategoryFactory({ paramMap }, catalogService) {
3793
+ return paramMap.pipe(map((params) => params.get('categorySlug')), filter(tuiIsPresent), switchMap((categorySlug) => catalogService.getVirtualCategoryCached$(categorySlug).pipe(shareReplay())), takeUntilDestroyed());
3794
+ }
3795
+ /**
3796
+ * Провайдеры потока данных о виртуальной категории.
3797
+ */
3798
+ const SC_VIRTUAL_CATEGORY_PROVIDERS = [
3799
+ {
3800
+ provide: SC_VIRTUAL_CATEGORY_INFO,
3801
+ deps: [ActivatedRoute, ScCatalogService],
3802
+ useFactory: virtualCategoryFactory,
3803
+ },
3804
+ ];
3805
+
3806
+ /**
3807
+ * Сервис для работы с UTM-меткой страницы.
3808
+ */
3809
+ class ScUTMService {
3810
+ /**
3811
+ * Инициализирует экземпляр класса {@link ScUTMService}.
3812
+ */
3813
+ constructor() {
3814
+ /**
3815
+ * Список ссылок на разделы backend.
3816
+ */
3817
+ this.urls = inject(SC_URLS);
3818
+ /**
3819
+ * Сервис для выполнения HTTP-запросов.
3820
+ */
3821
+ this.http = inject(HttpClient);
3822
+ /**
3823
+ * Сервис аутентификации пользователей.
3824
+ */
3825
+ this.authService = inject(ScAuthService);
3826
+ /**
3827
+ * Сервис предоставляющий доступ к данным о маршруте.
3828
+ */
3829
+ this.activatedRoute = inject(ActivatedRoute);
3830
+ /**
3831
+ * Сервис маршрутизации.
3832
+ */
3833
+ this.router = inject(Router);
3834
+ /**
3835
+ * Сервис для работы с {@link Storage} и внедрению его через DI.
3836
+ */
3837
+ this.storageService = inject(StorageService);
3838
+ /**
3839
+ * Признак, что скрипт выполняется в браузере.
3840
+ */
3841
+ this.isBrowser = inject(IS_BROWSER);
3842
+ /**
3843
+ * Хранилище {@link Storage}.
3844
+ */
3845
+ this.storage = inject(WA_LOCAL_STORAGE, { optional: true });
3846
+ /**
3847
+ * Время жизни UTM метки (ms).
3848
+ */
3849
+ this.utmLifeTime = inject(SC_CACHE_LIFETIME).utm;
3850
+ /**
3851
+ * {@link Observable} UTM-метка страницы.
3852
+ */
3853
+ this.utm$ = inject(WA_STORAGE_EVENT).pipe(filterByKey('utm'), toValue(), startWith(this.getUTMParams()), map((utmString) => (utmString === null ? utmString : JSON.parse(utmString))));
3854
+ /**
3855
+ * {@link Observable} timestamp сохранения UTM в {@link Storage}.
3856
+ */
3857
+ this.utmTimestamp$ = inject(WA_STORAGE_EVENT).pipe(filterByKey('utmTimestamp'), toValue(), startWith(this.getUTMTimestamp()), map((timestamp) => (isString(timestamp) ? Number(timestamp) : timestamp)));
3858
+ /**
3859
+ * {@link Observable} UTM-метки страницы из параметров роутинга.
3860
+ */
3861
+ this.utmParamsFromRoute$ = this.router.events.pipe(filter((event) => Boolean(this.storage) && this.isBrowser && event instanceof NavigationEnd), map(() => this.activatedRoute), startWith(this.activatedRoute), map((route) => route.snapshot.queryParams),
3862
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-return
3863
+ filter((params) => params['utm_source'] && params['utm_medium'] && params['utm_campaign']), map((params) => {
3864
+ return {
3865
+ source: params.utm_source,
3866
+ medium: params.utm_medium,
3867
+ campaign: params.utm_campaign,
3868
+ content: params.utm_content,
3869
+ term: params.utm_term,
3870
+ };
3871
+ }));
3872
+ // При получении UTM-метки сохраняем ее в Storage и создаём запрос сохранения метки за клиентом.
3873
+ this.authService
3874
+ .getAuthChange()
3875
+ .pipe(switchMap(() => this.utmParamsFromRoute$), tap(() => {
3876
+ this.updateTimestamp();
3877
+ }), filter((utm) => !this.isExistingUTM(utm)), tap((utm) => {
3878
+ this.setUTM(utm);
3879
+ }), switchMap((utm) => this.saveUTM$(utm)))
3880
+ .subscribe();
3881
+ }
3882
+ /**
3883
+ * Возвращает строчное представление параметров UTM из {@link Storage}.
3884
+ */
3885
+ getUTMParams() {
3886
+ return Boolean(this.storage) && this.isBrowser ? this.storageService.getItem('utm') : null;
3887
+ }
3888
+ /**
3889
+ * Возвращает строчное представление timestamp сохранения UTM из {@link Storage}.
3890
+ */
3891
+ getUTMTimestamp() {
3892
+ return Boolean(this.storage) && this.isBrowser ? this.storageService.getItem('utmTimestamp') : null;
3893
+ }
3894
+ /**
3895
+ * Устанавливает UTM-метку страницы в {@link Storage}.
3896
+ *
3897
+ * @param utm Данные о UTM-метке.
3898
+ */
3899
+ setUTM(utm) {
3900
+ if (this.storage && this.isBrowser && !this.isExistingUTM(utm)) {
3901
+ this.storageService.setItem('utm', JSON.stringify(utm));
3902
+ }
3903
+ }
3904
+ /**
3905
+ * Удаляет UTM-метку страницы из {@link Storage}.
3906
+ */
3907
+ removeUTM() {
3908
+ if (this.storage && this.isBrowser) {
3909
+ this.storageService.removeItem('utm');
3910
+ this.storageService.removeItem('utmTimestamp');
3911
+ }
3912
+ }
3913
+ /**
3914
+ * Возвращает {@link Observable} данных о UTM-метке.
3915
+ */
3916
+ getUTM$() {
3917
+ return combineLatest({
3918
+ utm: this.utm$,
3919
+ timestamp: this.utmTimestamp$,
3920
+ }).pipe(map(({ utm, timestamp }) => (!this.utmLifeTime || (timestamp && timestamp + this.utmLifeTime > Date.now()) ? utm : null)));
3921
+ }
3922
+ /**
3923
+ * Возвращает {@link Observable} сохранения {@link ScUTM}.
3924
+ *
3925
+ * @param utm Данные о UTM-метке.
3926
+ */
3927
+ saveUTM$(utm) {
3928
+ return this.http.post(`${this.urls.apiUrl}/utm`, utm);
3929
+ }
3930
+ /**
3931
+ * Проверяет, существует ли уже сохраненная UTM-метка.
3932
+ *
3933
+ * @param utm Данные о UTM-метке.
3934
+ */
3935
+ isExistingUTM(utm) {
3936
+ const existingUTM = this.getUTMParams();
3937
+ return existingUTM ? isMatch(utm, JSON.parse(existingUTM)) : false;
3938
+ }
3939
+ /**
3940
+ * Обновляет timestamp сохранения UTM в {@link Storage}.
3941
+ */
3942
+ updateTimestamp() {
3943
+ if (this.getUTMParams()) {
3944
+ this.storageService.setItem('utmTimestamp', JSON.stringify(Date.now()));
3945
+ }
3946
+ }
3947
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.12", ngImport: i0, type: ScUTMService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
3948
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.12", ngImport: i0, type: ScUTMService, providedIn: 'root' }); }
3949
+ }
3950
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.12", ngImport: i0, type: ScUTMService, decorators: [{
3951
+ type: Injectable,
3952
+ args: [{
3953
+ providedIn: 'root',
3954
+ }]
3955
+ }], ctorParameters: () => [] });
3956
+
3957
+ /**
3958
+ * Сервис обратной связи.
3959
+ */
3960
+ class ScFeedbackService {
3961
+ /**
3962
+ * Инициализирует экземпляр класса {@link ScFeedbackService}.
3963
+ *
3964
+ * @param http HTTP-клиент.
3965
+ * @param userMetrikaService Сервис для сбора метрик о действиях пользователей.
3966
+ * @param feedbackApi Данные для взаимодействия с API обратной связи.
3967
+ */
3968
+ constructor(http, userMetrikaService, feedbackApi) {
3969
+ this.http = http;
3970
+ this.userMetrikaService = userMetrikaService;
3971
+ this.feedbackApi = feedbackApi;
3972
+ /**
3973
+ * Сервис для работы с UTM-метками.
3974
+ */
3975
+ this.utmService = inject(ScUTMService);
3976
+ /**
3977
+ * Список форм обратной связи.
3978
+ */
3979
+ this.feedbackForms$ = this.http
3980
+ .get(`${this.feedbackApi.apiUrl}/feedback/forms`, {
3981
+ context: new HttpContext().set(SC_AUTH_ADD_HEADER_REQUIRED, false).set(SC_IS_HEADER_REQUIRED, false),
3982
+ headers: {
3983
+ [this.feedbackApi.authTokenName]: this.feedbackApi.authToken,
3984
+ },
3985
+ })
3986
+ .pipe(shareReplay(1));
3987
+ }
3988
+ /**
3989
+ * Отправляет сообщение обратной связи.
3990
+ *
3991
+ * @param formSlug Символьное обозначение (slug) формы.
3992
+ * @param feedbackMessage Объект сообщения обратной связи.
3993
+ */
3994
+ sendFeedback(formSlug, feedbackMessage) {
3995
+ return this.utmService.getUTM$().pipe(first(), map((utm) => (utm ? { ...feedbackMessage, utm } : feedbackMessage)), switchMap((data) => this.http.post(`${this.feedbackApi.apiUrl}/feedback/${formSlug}`, data, {
3996
+ context: new HttpContext().set(SC_AUTH_ADD_HEADER_REQUIRED, false).set(SC_IS_HEADER_REQUIRED, false),
3997
+ headers: {
3998
+ [this.feedbackApi.authTokenName]: this.feedbackApi.authToken,
3999
+ },
4000
+ })), tap(() => {
4001
+ this.userMetrikaService.emitUserMetrikaEvent({
4002
+ target: ScUserMetrikaGoalsEnum.feedbackSent,
4003
+ });
4004
+ }));
4005
+ }
4006
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.12", ngImport: i0, type: ScFeedbackService, deps: [{ token: i1$1.HttpClient }, { token: ScUserMetrikaService }, { token: SC_FEEDBACK_API }], target: i0.ɵɵFactoryTarget.Injectable }); }
4007
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.12", ngImport: i0, type: ScFeedbackService, providedIn: 'root' }); }
4008
+ }
4009
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.12", ngImport: i0, type: ScFeedbackService, decorators: [{
4010
+ type: Injectable,
4011
+ args: [{
4012
+ providedIn: 'root',
4013
+ }]
4014
+ }], ctorParameters: () => [{ type: i1$1.HttpClient }, { type: ScUserMetrikaService }, { type: undefined, decorators: [{
4015
+ type: Inject,
4016
+ args: [SC_FEEDBACK_API]
4017
+ }] }] });
4018
+
4019
+ /**
4020
+ * Сервис для работы с реквизитами и с обойной связью.
4021
+ */
4022
+ class ScRequisitesService {
4023
+ /**
4024
+ * Инициализирует экземпляр класса {@link ScRequisitesService}.
4025
+ *
4026
+ * @param http HTTP-клиент.
4027
+ * @param urls Список ссылок на разделы backend'a.
4028
+ * @param authService Сервис аутентификации.
4029
+ */
4030
+ constructor(http, urls, authService) {
4031
+ this.http = http;
4032
+ this.urls = urls;
4033
+ this.authService = authService;
4034
+ /**
4035
+ * {@link BehaviorSubject} поискового запроса на странице контактов.
4036
+ */
4037
+ this.searchTerm$ = new BehaviorSubject(null);
4038
+ /**
4039
+ * {@link Map} коллекция пар ключ-значение для контактов менеджера по направлению продаж.
4040
+ */
4041
+ this.idManagerMap = new Map();
4042
+ /**
4043
+ * Создаёт запрос получения списка всех контактов.
4044
+ */
4045
+ this.contacts$ = this.authService.getAuthChange().pipe(switchMap(() => this.http.get(`${this.urls.apiUrl}/contacts`)), shareReplay(1));
4046
+ /**
4047
+ * Создаёт запрос получения списка контактов для решения возникающих вопросов.
4048
+ */
4049
+ this.personal$ = this.contacts$.pipe(map((contacts) => contacts.personal));
4050
+ /**
4051
+ * Создаёт запрос получения списка контактов розничных магазинов.
4052
+ */
4053
+ this.retail$ = this.contacts$.pipe(map((contacts) => contacts.retail), first(), shareReplay(1));
4054
+ /**
4055
+ * Создаёт запрос получения списка ссылок на социальные сети и другие каналы коммуникации.
4056
+ */
4057
+ this.socialMedia$ = this.contacts$.pipe(map((contacts) => contacts.socialMedia), first(), shareReplay(1));
4058
+ /**
4059
+ * Создаёт запрос получения списка контактов менеджеров по направлениям продаж.
4060
+ */
4061
+ this.directions$ = this.contacts$.pipe(map((contacts) => contacts.directions), tap((directions) => {
4062
+ // eslint-disable-next-line guard-for-in,no-restricted-syntax
4063
+ for (const key in directions) {
4064
+ directions[Number.parseFloat(key)]?.forEach((manager) => {
4065
+ this.mapManagers(Number.parseFloat(key), manager);
4066
+ });
4067
+ }
4068
+ }), first(), shareReplay(1));
4069
+ /**
4070
+ * Создаёт запрос получения списка реквизитов компании.
4071
+ */
4072
+ this.requisites$ = this.http.get(`${this.urls.apiUrl}/requisites`).pipe(shareReplay(1));
4073
+ }
4074
+ /**
4075
+ * Устанавливает поисковый запрос в {@link BehaviorSubject}.
4076
+ *
4077
+ * @param term Поисковый запрос.
4078
+ */
4079
+ setSearchTermChange(term) {
4080
+ this.searchTerm$.next(term);
4081
+ }
4082
+ /**
4083
+ * Возвращает {@link Observable} поискового запроса.
4084
+ */
4085
+ getSearchTermChange$() {
4086
+ return this.searchTerm$.asObservable();
4087
+ }
4088
+ /**
4089
+ * Возвращает поисковый запрос.
4090
+ */
4091
+ getCurrentSearchTerm() {
4092
+ return this.searchTerm$.getValue();
4093
+ }
4094
+ /**
4095
+ * Проходит по древовидному представлению контактов менеджеров и записывает каждого менеджера в {@link Map} по ключу идентификатора.
4096
+ *
4097
+ * @param directionId Идентификатор направления продаж.
3774
4098
  * @param manager Контакты менеджера по направлению продаж.
3775
4099
  */
3776
4100
  mapManagers(directionId, manager) {
@@ -4262,199 +4586,19 @@ class ScFilesService {
4262
4586
  case 'jpg':
4263
4587
  case 'png':
4264
4588
  case 'gif':
4265
- case 'bmp':
4266
- case 'tiff':
4267
- document.icon = ScIconTypesEnum.iconImage;
4268
- break;
4269
- default:
4270
- document.icon = ScIconTypesEnum.iconFile;
4271
- break;
4272
- }
4273
- }
4274
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.12", ngImport: i0, type: ScFilesService, deps: [{ token: i1$1.HttpClient }, { token: SC_URLS }], target: i0.ɵɵFactoryTarget.Injectable }); }
4275
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.12", ngImport: i0, type: ScFilesService, providedIn: 'root' }); }
4276
- }
4277
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.12", ngImport: i0, type: ScFilesService, decorators: [{
4278
- type: Injectable,
4279
- args: [{
4280
- providedIn: 'root',
4281
- }]
4282
- }], ctorParameters: () => [{ type: i1$1.HttpClient }, { type: undefined, decorators: [{
4283
- type: Inject,
4284
- args: [SC_URLS]
4285
- }] }] });
4286
-
4287
- /**
4288
- * Сервис аутентификации пользователя на основе ключей, переданных в параметрах запроса.
4289
- */
4290
- class ScAuthAsClientGuard {
4291
- /**
4292
- * Инициализирует экземпляр класса {@link AuthAsClientGuard}.
4293
- *
4294
- * @param authService Сервис аутентификации.
4295
- * @param router Сервис маршрутизации.
4296
- * @param options Параметры авторизации под клиентом.
4297
- */
4298
- constructor(authService, router, options) {
4299
- this.authService = authService;
4300
- this.router = router;
4301
- this.options = options;
4302
- }
4303
- /**
4304
- * Разрешает/запрещает доступ к маршруту.
4305
- *
4306
- * @param route Данные о текущем маршруте.
4307
- */
4308
- // eslint-disable-next-line sonarjs/function-return-type
4309
- canActivate(route) {
4310
- const expiredAt = new Date();
4311
- expiredAt.setMinutes(new Date().getMinutes() + this.options.expiredAtMinute);
4312
- return this.authService.getAuthChange().pipe(first(),
4313
- // Если пользователь авторизирован, то завершаем сеанс.
4314
- concatMap((state) => (state ? this.authService.getSignOut$(false) : of(null))),
4315
- // Обновляем полученные ключи, чтобы они перестали действовать. getRefreshTokenObservable() запишет новые ключи в систему, после чего проложение само запросит нового пользователя.
4316
- concatMap(() => this.authService.getRefreshToken$({
4317
- access: {
4318
- token: route.paramMap.get('atoken') ?? '',
4319
- expiredAt: expiredAt,
4320
- },
4321
- refresh: {
4322
- token: route.paramMap.get('rtoken') ?? '',
4323
- expiredAt: expiredAt,
4324
- },
4325
- })), first(), map(() => this.router.createUrlTree(this.options.urlTree)));
4326
- }
4327
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.12", ngImport: i0, type: ScAuthAsClientGuard, deps: [{ token: ScAuthService }, { token: i2.Router }, { token: SC_AUTH_AS_CLIENT_OPTIONS }], target: i0.ɵɵFactoryTarget.Injectable }); }
4328
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.12", ngImport: i0, type: ScAuthAsClientGuard }); }
4329
- }
4330
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.12", ngImport: i0, type: ScAuthAsClientGuard, decorators: [{
4331
- type: Injectable
4332
- }], ctorParameters: () => [{ type: ScAuthService }, { type: i2.Router }, { type: undefined, decorators: [{
4333
- type: Inject,
4334
- args: [SC_AUTH_AS_CLIENT_OPTIONS]
4335
- }] }] });
4336
-
4337
- /**
4338
- * Значения пагинации списка товаров категории по умолчанию.
4339
- */
4340
- const SC_PRODUCT_PAGINATION_DEFAULT_OPTIONS = {
4341
- perPage: 20,
4342
- page: 0,
4343
- };
4344
- /**
4345
- * Токен значений пагинации списка товаров в каталоге по умолчанию.
4346
- */
4347
- const SC_PRODUCT_PAGINATION_OPTIONS = tuiCreateToken(SC_PRODUCT_PAGINATION_DEFAULT_OPTIONS);
4348
- /**
4349
- * Токен {@link EventEmitter} событие нажатия на кнопку "Показать следующие позиции категории".
4350
- */
4351
- const SC_NEXT_PAGE_PAGINATION_CLICK = tuiCreateToken(new EventEmitter());
4352
-
4353
- /**
4354
- * Сервис поиска по каталогу.
4355
- */
4356
- class ScSearchService {
4357
- /**
4358
- * Инициализирует экземпляр класса {@link ScSearchService}.
4359
- *
4360
- * @param http HTTP-клиент.
4361
- * @param urls Список ссылок на разделы backend'a.
4362
- * @param userMetrikaService Сервис для сбора метрик о действиях пользователей.
4363
- */
4364
- constructor(http, urls, userMetrikaService) {
4365
- this.http = http;
4366
- this.urls = urls;
4367
- this.userMetrikaService = userMetrikaService;
4368
- /**
4369
- * {@link BehaviorSubject} поискового запрос.
4370
- */
4371
- this.searchTerm$ = new BehaviorSubject(null);
4372
- }
4373
- /**
4374
- * Выполняет упрощенный поиск товаров и категорий. Возвращает ограниченное количество записей.
4375
- *
4376
- * @param term Поисковый запрос.
4377
- */
4378
- simple$(term) {
4379
- return this.http.get(`${this.urls.apiUrl}/catalog/search/simple`, { params: { term: term } }).pipe(tap(() => {
4380
- this.userMetrikaService.emitUserMetrikaEvent({
4381
- target: ScUserMetrikaGoalsEnum.catalogSearch,
4382
- params: {
4383
- search_type: 'simple',
4384
- term: term,
4385
- },
4386
- });
4387
- }));
4388
- }
4389
- /**
4390
- * Выполняет поиск категорий в каталоге.
4391
- *
4392
- * @param term Поисковый запрос.
4393
- */
4394
- categories$(term) {
4395
- return this.http.get(`${this.urls.apiUrl}/catalog/search/categories`, { params: { term: term } }).pipe(tap(() => {
4396
- this.userMetrikaService.emitUserMetrikaEvent({
4397
- target: ScUserMetrikaGoalsEnum.catalogSearch,
4398
- params: {
4399
- search_type: 'categories',
4400
- term: term,
4401
- },
4402
- });
4403
- }), map((categories) => categories.map((item) => new ScCategory(item))));
4404
- }
4405
- /**
4406
- * Выполняет полный поиск по всему прайс-листу.
4407
- *
4408
- * @param term Поисковый запрос.
4409
- * @param showOrderedProducts Признак того, что необходимо вернуть ранее заказанные продукты.
4410
- * @param showFavoriteProducts Признак того, что необходимо вернуть избранные продукты.
4411
- * @param showDiscountedProducts Признак того, что необходимо вернуть продукты со скидкой.
4412
- */
4413
- full$(term, showOrderedProducts, showFavoriteProducts, showDiscountedProducts) {
4414
- const params = {};
4415
- if (term) {
4416
- params['term'] = term;
4417
- }
4418
- if (showOrderedProducts) {
4419
- params['show_ordered_products'] = Number(showOrderedProducts);
4420
- }
4421
- if (showFavoriteProducts) {
4422
- params['show_favorite_products'] = Number(showFavoriteProducts);
4423
- }
4424
- if (showDiscountedProducts) {
4425
- params['show_discounted_products'] = Number(showDiscountedProducts);
4426
- }
4427
- if (Object.keys(params).length > 0) {
4428
- return this.http.get(`${this.urls.apiUrl}/catalog/search/full`, { params: params }).pipe(tap(() => {
4429
- this.userMetrikaService.emitUserMetrikaEvent({
4430
- target: ScUserMetrikaGoalsEnum.catalogSearch,
4431
- params: {
4432
- search_type: 'full',
4433
- term: term,
4434
- },
4435
- });
4436
- }));
4437
- }
4438
- return throwError(() => new Error('Необходимо указать хотя бы один параметр.'));
4439
- }
4440
- /**
4441
- * Устанавливает поисковый запрос в {@link BehaviorSubject}.
4442
- *
4443
- * @param term Поисковый запрос.
4444
- */
4445
- setSearchTermChange(term) {
4446
- this.searchTerm$.next(term);
4447
- }
4448
- /**
4449
- * Возвращает {@link Observable} поискового запроса.
4450
- */
4451
- getSearchTermChange$() {
4452
- return this.searchTerm$.asObservable();
4589
+ case 'bmp':
4590
+ case 'tiff':
4591
+ document.icon = ScIconTypesEnum.iconImage;
4592
+ break;
4593
+ default:
4594
+ document.icon = ScIconTypesEnum.iconFile;
4595
+ break;
4596
+ }
4453
4597
  }
4454
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.12", ngImport: i0, type: ScSearchService, deps: [{ token: i1$1.HttpClient }, { token: SC_URLS }, { token: ScUserMetrikaService }], target: i0.ɵɵFactoryTarget.Injectable }); }
4455
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.12", ngImport: i0, type: ScSearchService, providedIn: 'root' }); }
4598
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.12", ngImport: i0, type: ScFilesService, deps: [{ token: i1$1.HttpClient }, { token: SC_URLS }], target: i0.ɵɵFactoryTarget.Injectable }); }
4599
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.12", ngImport: i0, type: ScFilesService, providedIn: 'root' }); }
4456
4600
  }
4457
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.12", ngImport: i0, type: ScSearchService, decorators: [{
4601
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.12", ngImport: i0, type: ScFilesService, decorators: [{
4458
4602
  type: Injectable,
4459
4603
  args: [{
4460
4604
  providedIn: 'root',
@@ -4462,69 +4606,57 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.12", ngImpo
4462
4606
  }], ctorParameters: () => [{ type: i1$1.HttpClient }, { type: undefined, decorators: [{
4463
4607
  type: Inject,
4464
4608
  args: [SC_URLS]
4465
- }] }, { type: ScUserMetrikaService }] });
4466
-
4467
- /**
4468
- * Токен поиска введенного терма.
4469
- */
4470
- const SEARCH_TERM = new InjectionToken('SEARCH_TERM');
4471
- /**
4472
- * Токен минимального количества введенных символов в поле поиска.
4473
- */
4474
- const SC_MIN_LENGTH_SEARCH_TERM = new InjectionToken('SC_MIN_LENGTH_SEARCH_TERM');
4475
- /**
4476
- * Токен максимального количества введенных символов в поле поиска.
4477
- */
4478
- const SC_MAX_LENGTH_SEARCH_TERM = new InjectionToken('SC_MAX_LENGTH_SEARCH_TERM');
4479
- /**
4480
- * Возвращает введенный терм для поиска.
4481
- *
4482
- * @param searchService Сервис поиска по каталогу.
4483
- * @param minLengthSearchTerm Минимальное количество введенных символов в поле поиска.
4484
- * @param maxLengthSearchTerm Максимальное количество введенных символов в поле поиска.
4485
- */
4486
- function searchTermFactory(searchService, minLengthSearchTerm, maxLengthSearchTerm) {
4487
- return searchService
4488
- .getSearchTermChange$()
4489
- .pipe(map((searchTerm) => (searchTerm && searchTerm.length >= minLengthSearchTerm && searchTerm.length <= maxLengthSearchTerm ? searchTerm : '')));
4490
- }
4491
- /**
4492
- * Провайдеры данных о поиске введенного терма.
4493
- */
4494
- const SEARCH_TERM_PROVIDERS = [
4495
- {
4496
- provide: SEARCH_TERM,
4497
- deps: [ScSearchService, SC_MIN_LENGTH_SEARCH_TERM, SC_MAX_LENGTH_SEARCH_TERM],
4498
- useFactory: searchTermFactory,
4499
- },
4500
- ];
4609
+ }] }] });
4501
4610
 
4502
- /* eslint-disable no-param-reassign,no-return-assign,jsdoc/check-param-names */
4503
- /**
4504
- * Токен потока данных о виртуальной категории.
4505
- */
4506
- const SC_VIRTUAL_CATEGORY_INFO = new InjectionToken('A stream with current virtual category information');
4507
4611
  /**
4508
- * Фабрика создания потока данных виртуальной категории.
4509
- *
4510
- * @param paramMap Параметры.
4511
- * @param paramMap.paramMap Параметры.
4512
- * @param catalogService.paramMap Параметры маршрута.
4513
- * @param catalogService Сервис для работы с каталогом.
4612
+ * Сервис аутентификации пользователя на основе ключей, переданных в параметрах запроса.
4514
4613
  */
4515
- function virtualCategoryFactory({ paramMap }, catalogService) {
4516
- return paramMap.pipe(map((params) => params.get('categorySlug')), filter(tuiIsPresent), switchMap((categorySlug) => catalogService.getVirtualCategoryCached$(categorySlug).pipe(shareReplay())), takeUntilDestroyed());
4614
+ class ScAuthAsClientGuard {
4615
+ /**
4616
+ * Инициализирует экземпляр класса {@link AuthAsClientGuard}.
4617
+ *
4618
+ * @param authService Сервис аутентификации.
4619
+ * @param router Сервис маршрутизации.
4620
+ * @param options Параметры авторизации под клиентом.
4621
+ */
4622
+ constructor(authService, router, options) {
4623
+ this.authService = authService;
4624
+ this.router = router;
4625
+ this.options = options;
4626
+ }
4627
+ /**
4628
+ * Разрешает/запрещает доступ к маршруту.
4629
+ *
4630
+ * @param route Данные о текущем маршруте.
4631
+ */
4632
+ // eslint-disable-next-line sonarjs/function-return-type
4633
+ canActivate(route) {
4634
+ const expiredAt = new Date();
4635
+ expiredAt.setMinutes(new Date().getMinutes() + this.options.expiredAtMinute);
4636
+ return this.authService.getAuthChange().pipe(first(),
4637
+ // Если пользователь авторизирован, то завершаем сеанс.
4638
+ concatMap((state) => (state ? this.authService.getSignOut$(false) : of(null))),
4639
+ // Обновляем полученные ключи, чтобы они перестали действовать. getRefreshTokenObservable() запишет новые ключи в систему, после чего проложение само запросит нового пользователя.
4640
+ concatMap(() => this.authService.getRefreshToken$({
4641
+ access: {
4642
+ token: route.paramMap.get('atoken') ?? '',
4643
+ expiredAt: expiredAt,
4644
+ },
4645
+ refresh: {
4646
+ token: route.paramMap.get('rtoken') ?? '',
4647
+ expiredAt: expiredAt,
4648
+ },
4649
+ })), first(), map(() => this.router.createUrlTree(this.options.urlTree)));
4650
+ }
4651
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.12", ngImport: i0, type: ScAuthAsClientGuard, deps: [{ token: ScAuthService }, { token: i2.Router }, { token: SC_AUTH_AS_CLIENT_OPTIONS }], target: i0.ɵɵFactoryTarget.Injectable }); }
4652
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.12", ngImport: i0, type: ScAuthAsClientGuard }); }
4517
4653
  }
4518
- /**
4519
- * Провайдеры потока данных о виртуальной категории.
4520
- */
4521
- const SC_VIRTUAL_CATEGORY_PROVIDERS = [
4522
- {
4523
- provide: SC_VIRTUAL_CATEGORY_INFO,
4524
- deps: [ActivatedRoute, ScCatalogService],
4525
- useFactory: virtualCategoryFactory,
4526
- },
4527
- ];
4654
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.12", ngImport: i0, type: ScAuthAsClientGuard, decorators: [{
4655
+ type: Injectable
4656
+ }], ctorParameters: () => [{ type: ScAuthService }, { type: i2.Router }, { type: undefined, decorators: [{
4657
+ type: Inject,
4658
+ args: [SC_AUTH_AS_CLIENT_OPTIONS]
4659
+ }] }] });
4528
4660
 
4529
4661
  /**
4530
4662
  * Страж выполняющий проверку маршрута товара и категории, и редиректа в зависимости от настроек окружения.
@@ -4547,7 +4679,7 @@ const ScIdOrSlugGuard = (route) => {
4547
4679
  }
4548
4680
  if (productIdOrSlug && /^\d+$/.test(productIdOrSlug) !== (idOrSlug === 'id')) {
4549
4681
  return inject(ScCatalogService)
4550
- .getProductInfo$(productIdOrSlug)
4682
+ .getProductData$(productIdOrSlug)
4551
4683
  .pipe(filter(tuiIsPresent),
4552
4684
  // eslint-disable-next-line security/detect-object-injection
4553
4685
  map((product) => router.createUrlTree(['/catalog', 'product', product[idOrSlug]])));
@@ -5575,146 +5707,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.12", ngImpo
5575
5707
  args: [SC_UPDATE_INTERVAL]
5576
5708
  }] }] });
5577
5709
 
5578
- /**
5579
- * Сервис для работы с UTM-меткой страницы.
5580
- */
5581
- class ScUTMService {
5582
- /**
5583
- * Инициализирует экземпляр класса {@link ScUTMService}.
5584
- */
5585
- constructor() {
5586
- /**
5587
- * Список ссылок на разделы backend.
5588
- */
5589
- this.urls = inject(SC_URLS);
5590
- /**
5591
- * Сервис для выполнения HTTP-запросов.
5592
- */
5593
- this.http = inject(HttpClient);
5594
- /**
5595
- * Сервис аутентификации пользователей.
5596
- */
5597
- this.authService = inject(ScAuthService);
5598
- /**
5599
- * Сервис предоставляющий доступ к данным о маршруте.
5600
- */
5601
- this.activatedRoute = inject(ActivatedRoute);
5602
- /**
5603
- * Сервис маршрутизации.
5604
- */
5605
- this.router = inject(Router);
5606
- /**
5607
- * Сервис для работы с {@link Storage} и внедрению его через DI.
5608
- */
5609
- this.storageService = inject(StorageService);
5610
- /**
5611
- * Признак, что скрипт выполняется в браузере.
5612
- */
5613
- this.isBrowser = inject(IS_BROWSER);
5614
- /**
5615
- * Хранилище {@link Storage}.
5616
- */
5617
- this.storage = inject(WA_LOCAL_STORAGE, { optional: true });
5618
- /**
5619
- * Время жизни UTM метки (ms).
5620
- */
5621
- this.utmLifeTime = inject(SC_CACHE_LIFETIME).utm;
5622
- /**
5623
- * {@link Observable} UTM-метка страницы.
5624
- */
5625
- this.utm$ = inject(WA_STORAGE_EVENT).pipe(filterByKey('utm'), toValue(), startWith(this.getUTMParams()), map((utmString) => (utmString === null ? utmString : JSON.parse(utmString))));
5626
- /**
5627
- * {@link Observable} timestamp сохранения UTM в {@link Storage}.
5628
- */
5629
- this.utmTimestamp$ = inject(WA_STORAGE_EVENT).pipe(filterByKey('utmTimestamp'), toValue(), startWith(this.getUTMTimestamp()), map((timestamp) => (isString(timestamp) ? Number(timestamp) : timestamp)));
5630
- /**
5631
- * {@link Observable} UTM-метки страницы из параметров роутинга.
5632
- */
5633
- this.utmParamsFromRoute$ = this.router.events.pipe(filter((event) => Boolean(this.storage) && this.isBrowser && event instanceof NavigationEnd), map(() => this.activatedRoute), startWith(this.activatedRoute), map((route) => route.snapshot.queryParams),
5634
- // eslint-disable-next-line @typescript-eslint/no-unsafe-return
5635
- filter((params) => params['utm_source'] && params['utm_medium'] && params['utm_campaign']), map((params) => {
5636
- return {
5637
- source: params.utm_source,
5638
- medium: params.utm_medium,
5639
- campaign: params.utm_campaign,
5640
- content: params.utm_content,
5641
- term: params.utm_term,
5642
- };
5643
- }));
5644
- // При получении UTM-метки сохраняем ее в Storage и создаём запрос сохранения метки за клиентом.
5645
- this.authService
5646
- .getAuthChange()
5647
- .pipe(switchMap(() => this.utmParamsFromRoute$.pipe(distinctUntilChanged((previous, current) => isMatch(previous, current)))), tap((utm) => {
5648
- this.setUTM(utm);
5649
- }), switchMap((utm) => this.saveUTM$(utm)))
5650
- .subscribe();
5651
- // Удаляем UTM при выходе из аккаунта.
5652
- this.authService
5653
- .getAuthChange()
5654
- .pipe(skip(1), filter((state) => !state))
5655
- .subscribe(() => {
5656
- this.removeUTM();
5657
- });
5658
- }
5659
- /**
5660
- * Возвращает строчное представление параметров UTM из {@link Storage}.
5661
- */
5662
- getUTMParams() {
5663
- return Boolean(this.storage) && this.isBrowser ? this.storageService.getItem('utm') : null;
5664
- }
5665
- /**
5666
- * Возвращает строчное представление timestamp сохранения UTM из {@link Storage}.
5667
- */
5668
- getUTMTimestamp() {
5669
- return Boolean(this.storage) && this.isBrowser ? this.storageService.getItem('utmTimestamp') : null;
5670
- }
5671
- /**
5672
- * Устанавливает UTM-метку страницы в {@link Storage}.
5673
- *
5674
- * @param utm Данные о UTM-метке.
5675
- */
5676
- setUTM(utm) {
5677
- if (this.storage && this.isBrowser) {
5678
- this.storageService.setItem('utm', JSON.stringify(utm));
5679
- this.storageService.setItem('utmTimestamp', JSON.stringify(Date.now()));
5680
- }
5681
- }
5682
- /**
5683
- * Удаляет UTM-метку страницы из {@link Storage}.
5684
- */
5685
- removeUTM() {
5686
- if (this.storage && this.isBrowser) {
5687
- this.storageService.removeItem('utm');
5688
- this.storageService.removeItem('utmTimestamp');
5689
- }
5690
- }
5691
- /**
5692
- * Возвращает {@link Observable} данных о UTM-метке.
5693
- */
5694
- getUTM$() {
5695
- return combineLatest({
5696
- utm: this.utm$,
5697
- timestamp: this.utmTimestamp$,
5698
- }).pipe(map(({ utm, timestamp }) => (!this.utmLifeTime || (timestamp && timestamp + this.utmLifeTime > Date.now()) ? utm : null)));
5699
- }
5700
- /**
5701
- * Возвращает {@link Observable} сохранения {@link ScUTM}.
5702
- *
5703
- * @param utm Данные о UTM-метке.
5704
- */
5705
- saveUTM$(utm) {
5706
- return this.http.post(`${this.urls.apiUrl}/utm`, utm);
5707
- }
5708
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.12", ngImport: i0, type: ScUTMService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
5709
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.12", ngImport: i0, type: ScUTMService, providedIn: 'root' }); }
5710
- }
5711
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.12", ngImport: i0, type: ScUTMService, decorators: [{
5712
- type: Injectable,
5713
- args: [{
5714
- providedIn: 'root',
5715
- }]
5716
- }], ctorParameters: () => [] });
5717
-
5718
5710
  /**
5719
5711
  * Модель данных о бесплатной доставке.
5720
5712
  */
@@ -7159,5 +7151,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.12", ngImpo
7159
7151
  * Generated bundle index. Do not edit.
7160
7152
  */
7161
7153
 
7162
- export { EMPTY_CART, IS_BROWSER, IS_RUNNING_ON_TERMINAL, IS_SERVER, RESPONSE, SC_ACCESS_AUTH_TOKEN_STORAGE_KEY, SC_API_KEYS, SC_AUTH_ADD_HEADER_REQUIRED, SC_AUTH_AS_CLIENT_DEFAULT_OPTIONS, SC_AUTH_AS_CLIENT_OPTIONS, SC_CACHE_LIFETIME, SC_CACHE_SETTINGS, SC_COMPANY_NAME, SC_CONFIGURATOR_COMPONENTS, SC_CONFIGURATOR_SETTINGS, SC_COUNT_FIRST_DISCOUNTED_PRODUCTS, SC_COUNT_LAST_NEWS, SC_DATE_FORMAT, SC_DEFAULT_PAGE_META, SC_FEEDBACK_API, SC_GUEST_ENDPOINTS_TOKEN, SC_GUEST_PARAMETER_NAME_TOKEN, SC_GUEST_TOKEN_STORAGE_KEY, SC_ID_OR_SLUG_IN_ROUTE, SC_IS_HEADER_REQUIRED, SC_IS_HIDDEN_ERROR_ALERT, SC_IS_HIDDEN_ERROR_ALERT_HTTP_CONTEXT, SC_IS_LOGOUT_REQUEST, SC_IS_REFRESH_REQUIRED, SC_LINEAR_VALUES, SC_LINEAR_VALUES_TOKEN, SC_MAX_LENGTH_SEARCH_TERM, SC_MIN_LENGTH_SEARCH_TERM, SC_NEXT_PAGE_PAGINATION_CLICK, SC_PATH_IMAGE_NOT_FOUND, SC_PRODUCT_PAGINATION_DEFAULT_OPTIONS, SC_PRODUCT_PAGINATION_OPTIONS, SC_REFRESH_AUTH_TOKEN_STORAGE_KEY, SC_RELEASE, SC_UPDATE_INTERVAL, SC_URLS, SC_VACANCIES_DATA_SOURCE, SC_VIRTUAL_CATEGORY_INFO, SC_VIRTUAL_CATEGORY_PROVIDERS, SEARCH_TERM, SEARCH_TERM_PROVIDERS, ScAuthAsClientGuard, ScAuthInterceptor, ScAuthService, ScBannerService, ScCacheInterceptor, ScCacheSettings, ScCachedData, ScCachedItem, ScCart, ScCartItem, ScCartService, ScCatalogFormat, ScCatalogService, ScCategory, ScClientType, ScConfiguratorService, ScContactsService, ScContragentService, ScConvertInterceptor, ScConvertersService, ScDeliveryAddressService, ScDeliveryCost, ScDeliveryType, ScDocumentInfoNode, ScDocumentInfoTypesEnum, ScErrorsInterceptor, ScFavoriteService, ScFeedbackService, ScFilesService, ScFrequentlyAskedQuestionsService, ScGuestInterceptor, ScISalesDirectionCart, ScISuggestionType, ScIconTypesEnum, ScIdOrSlugGuard, ScIdOrSlugPipe, ScImageHelper, ScJsonLdComponent, ScJsonLdModule, ScLocationsService, ScMimeTypes, ScNews, ScNewsService, ScNotificationActionTypes, ScNotificationLevelNames, ScNotificationsService, ScOpfList, ScOptionsInterceptor, ScOrder, ScOrderShort, ScOrderStateStatus, ScOrdersService, ScPaginationService, ScPaymentStatus, ScPaymentType, ScPhoneService, ScProduct, ScProductTileType, ScQuestionnaireService, ScQuestionnaireStatusEnum, ScReclamationService, ScReclamationStatus, ScRecommendationService, ScReferenceName, ScReferencesService, ScRequisitesService, ScSearchService, ScSeoResource, ScSeoService, ScSocialType, ScSuggestionService, ScSum, ScTokenService, ScUIService, ScUTMService, ScUnitsHelper, ScUploadedFile, ScUser, ScUserMetadata, ScUserMetrikaGoalsEnum, ScUserMetrikaService, ScUserService, ScUserType, ScVCardService, ScVacanciesList, ScVacanciesService, ScVacancy, ScVerificationService, ScVirtualCategory, ScWarehouseService, TERMINAL_PROVIDERS, USER_AGENT_TERMINAL, filterChangedByKey, runningOnTerminalFactory, searchTermFactory };
7154
+ export { EMPTY_CART, IS_BROWSER, IS_RUNNING_ON_TERMINAL, IS_SERVER, RESPONSE, SC_ACCESS_AUTH_TOKEN_STORAGE_KEY, SC_API_KEYS, SC_AUTH_ADD_HEADER_REQUIRED, SC_AUTH_AS_CLIENT_DEFAULT_OPTIONS, SC_AUTH_AS_CLIENT_OPTIONS, SC_CACHE_LIFETIME, SC_CACHE_SETTINGS, SC_COMPANY_NAME, SC_CONFIGURATOR_COMPONENTS, SC_CONFIGURATOR_SETTINGS, SC_COUNT_FIRST_DISCOUNTED_PRODUCTS, SC_COUNT_LAST_NEWS, SC_DATE_FORMAT, SC_DEFAULT_PAGE_META, SC_FEEDBACK_API, SC_GUEST_ENDPOINTS_TOKEN, SC_GUEST_PARAMETER_NAME_TOKEN, SC_GUEST_TOKEN_STORAGE_KEY, SC_ID_OR_SLUG_IN_ROUTE, SC_IS_HEADER_REQUIRED, SC_IS_HIDDEN_ERROR_ALERT, SC_IS_HIDDEN_ERROR_ALERT_HTTP_CONTEXT, SC_IS_LOGOUT_REQUEST, SC_IS_REFRESH_REQUIRED, SC_LINEAR_VALUES, SC_LINEAR_VALUES_TOKEN, SC_MAX_LENGTH_SEARCH_TERM, SC_MIN_LENGTH_SEARCH_TERM, SC_NEXT_PAGE_PAGINATION_CLICK, SC_PATH_IMAGE_NOT_FOUND, SC_PRODUCT_PAGINATION_DEFAULT_OPTIONS, SC_PRODUCT_PAGINATION_OPTIONS, SC_REFRESH_AUTH_TOKEN_STORAGE_KEY, SC_RELEASE, SC_UPDATE_INTERVAL, SC_URLS, SC_VACANCIES_DATA_SOURCE, SC_VIRTUAL_CATEGORY_INFO, SC_VIRTUAL_CATEGORY_PROVIDERS, SEARCH_TERM, SEARCH_TERM_PROVIDERS, ScAuthAsClientGuard, ScAuthInterceptor, ScAuthService, ScBannerService, ScCacheInterceptor, ScCacheSettings, ScCachedData, ScCachedItem, ScCart, ScCartItem, ScCartService, ScCatalogFormat, ScCatalogService, ScCategory, ScClientType, ScConfiguratorService, ScContactsService, ScContragentService, ScConvertInterceptor, ScConvertersService, ScDeliveryAddressService, ScDeliveryCost, ScDeliveryType, ScDocumentInfoNode, ScDocumentInfoTypesEnum, ScErrorsInterceptor, ScFavoriteService, ScFeedbackForms, ScFeedbackService, ScFilesService, ScFrequentlyAskedQuestionsService, ScGuestInterceptor, ScISalesDirectionCart, ScISuggestionType, ScIconTypesEnum, ScIdOrSlugGuard, ScIdOrSlugPipe, ScImageHelper, ScJsonLdComponent, ScJsonLdModule, ScLocationsService, ScMimeTypes, ScNews, ScNewsService, ScNotificationActionTypes, ScNotificationLevelNames, ScNotificationsService, ScOpfList, ScOptionsInterceptor, ScOrder, ScOrderShort, ScOrderStateStatus, ScOrdersService, ScPaginationService, ScPaymentStatus, ScPaymentType, ScPhoneService, ScProduct, ScProductTileType, ScQuestionnaireService, ScQuestionnaireStatusEnum, ScReclamationService, ScReclamationStatus, ScRecommendationService, ScReferenceName, ScReferencesService, ScRequisitesService, ScSearchService, ScSeoResource, ScSeoService, ScSocialType, ScSuggestionService, ScSum, ScTokenService, ScUIService, ScUTMService, ScUnitsHelper, ScUploadedFile, ScUser, ScUserMetadata, ScUserMetrikaGoalsEnum, ScUserMetrikaService, ScUserService, ScUserType, ScVCardService, ScVacanciesList, ScVacanciesService, ScVacancy, ScVerificationService, ScVirtualCategory, ScWarehouseService, TERMINAL_PROVIDERS, USER_AGENT_TERMINAL, filterChangedByKey, runningOnTerminalFactory, searchTermFactory };
7163
7155
  //# sourceMappingURL=snabcentr-client-core.mjs.map