murlock 1.0.0 → 1.1.0

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.
Files changed (41) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +38 -8
  3. package/dist/constants/index.js.map +1 -1
  4. package/dist/decorators/murlock.decorator.d.ts +0 -1
  5. package/dist/decorators/murlock.decorator.js +54 -26
  6. package/dist/decorators/murlock.decorator.js.map +1 -1
  7. package/dist/index.d.ts +2 -0
  8. package/dist/index.js +2 -0
  9. package/dist/index.js.map +1 -1
  10. package/dist/interfaces/murlock-options.interface.d.ts +1 -1
  11. package/dist/murlock.module.js +2 -0
  12. package/dist/murlock.module.js.map +1 -1
  13. package/dist/murlock.service.d.ts +11 -3
  14. package/dist/murlock.service.js +54 -16
  15. package/dist/murlock.service.js.map +1 -1
  16. package/dist/tsconfig.tsbuildinfo +1 -1
  17. package/package.json +2 -1
  18. package/dist/decorators/lock.decorator.d.ts +0 -1
  19. package/dist/decorators/lock.decorator.js +0 -11
  20. package/dist/decorators/lock.decorator.js.map +0 -1
  21. package/dist/interceptors/index.d.ts +0 -1
  22. package/dist/interceptors/index.js +0 -18
  23. package/dist/interceptors/index.js.map +0 -1
  24. package/dist/interceptors/lock.interceptor.d.ts +0 -12
  25. package/dist/interceptors/lock.interceptor.js +0 -66
  26. package/dist/interceptors/lock.interceptor.js.map +0 -1
  27. package/dist/interfaces/lock-meta-data.interface.d.ts +0 -4
  28. package/dist/interfaces/lock-meta-data.interface.js +0 -3
  29. package/dist/interfaces/lock-meta-data.interface.js.map +0 -1
  30. package/dist/interfaces/lock-options.interface.d.ts +0 -4
  31. package/dist/interfaces/lock-options.interface.js +0 -3
  32. package/dist/interfaces/lock-options.interface.js.map +0 -1
  33. package/dist/lock.module.d.ts +0 -5
  34. package/dist/lock.module.js +0 -40
  35. package/dist/lock.module.js.map +0 -1
  36. package/dist/lock.service.d.ts +0 -9
  37. package/dist/lock.service.js +0 -58
  38. package/dist/lock.service.js.map +0 -1
  39. package/dist/lock.spec.d.ts +0 -1
  40. package/dist/lock.spec.js +0 -53
  41. package/dist/lock.spec.js.map +0 -1
@@ -1,12 +0,0 @@
1
- import { CallHandler, ExecutionContext, NestInterceptor } from '@nestjs/common';
2
- import { Reflector } from '@nestjs/core';
3
- import { LockService } from '../lock.service';
4
- import { PinoLogger } from 'nestjs-pino';
5
- import { Observable } from 'rxjs';
6
- export declare class LockInterceptor implements NestInterceptor {
7
- private readonly lockService;
8
- private readonly reflector;
9
- private readonly logger;
10
- constructor(lockService: LockService, reflector: Reflector, logger: PinoLogger);
11
- intercept(context: ExecutionContext, next: CallHandler): Promise<Observable<any>>;
12
- }
@@ -1,66 +0,0 @@
1
- "use strict";
2
- var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
- else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
- return c > 3 && r && Object.defineProperty(target, key, r), r;
7
- };
8
- var __metadata = (this && this.__metadata) || function (k, v) {
9
- if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
- };
11
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
12
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
13
- return new (P || (P = Promise))(function (resolve, reject) {
14
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
15
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
16
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
17
- step((generator = generator.apply(thisArg, _arguments || [])).next());
18
- });
19
- };
20
- var LockInterceptor_1;
21
- Object.defineProperty(exports, "__esModule", { value: true });
22
- exports.LockInterceptor = void 0;
23
- const common_1 = require("@nestjs/common");
24
- const core_1 = require("@nestjs/core");
25
- const constants_1 = require("../constants");
26
- const lock_service_1 = require("../lock.service");
27
- const nestjs_pino_1 = require("nestjs-pino");
28
- const rxjs_1 = require("rxjs");
29
- let LockInterceptor = exports.LockInterceptor = LockInterceptor_1 = class LockInterceptor {
30
- constructor(lockService, reflector, logger) {
31
- this.lockService = lockService;
32
- this.reflector = reflector;
33
- this.logger = logger;
34
- this.logger.setContext(LockInterceptor_1.name);
35
- }
36
- intercept(context, next) {
37
- return __awaiter(this, void 0, void 0, function* () {
38
- const lockMetadata = this.reflector.get(constants_1.LOCK_KEY_METADATA, context.getHandler());
39
- if (!lockMetadata) {
40
- return next.handle();
41
- }
42
- const { releaseTime, params } = lockMetadata;
43
- const request = context.switchToHttp().getRequest();
44
- const lockKey = params
45
- .map((param) => request.params[param] || request.body[param])
46
- .join(':');
47
- const isLockSuccessful = yield this.lockService.lock(lockKey, releaseTime);
48
- if (!isLockSuccessful) {
49
- throw new common_1.InternalServerErrorException('Could not obtain lock');
50
- }
51
- return next.handle().pipe((0, rxjs_1.tap)(() => this.logger.info(`Processing complete, releasing lock for key ${lockKey}`)), (0, rxjs_1.catchError)((error) => {
52
- this.logger.error(`Error processing request: ${error.message}`);
53
- return (0, rxjs_1.throwError)(error);
54
- }), (0, rxjs_1.finalize)(() => __awaiter(this, void 0, void 0, function* () {
55
- yield this.lockService.unlock(lockKey);
56
- })));
57
- });
58
- }
59
- };
60
- exports.LockInterceptor = LockInterceptor = LockInterceptor_1 = __decorate([
61
- (0, common_1.Injectable)(),
62
- __metadata("design:paramtypes", [lock_service_1.LockService,
63
- core_1.Reflector,
64
- nestjs_pino_1.PinoLogger])
65
- ], LockInterceptor);
66
- //# sourceMappingURL=lock.interceptor.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"lock.interceptor.js","sourceRoot":"","sources":["../../lib/interceptors/lock.interceptor.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;AAAA,2CAMwB;AACxB,uCAAyC;AACzC,4CAAiD;AAEjD,kDAA8C;AAC9C,6CAAyC;AACzC,+BAAyE;AAGlE,IAAM,eAAe,iDAArB,MAAM,eAAe;IAC1B,YACmB,WAAwB,EACxB,SAAoB,EACpB,MAAkB;QAFlB,gBAAW,GAAX,WAAW,CAAa;QACxB,cAAS,GAAT,SAAS,CAAW;QACpB,WAAM,GAAN,MAAM,CAAY;QAEnC,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,iBAAe,CAAC,IAAI,CAAC,CAAC;IAC/C,CAAC;IAEK,SAAS,CACb,OAAyB,EACzB,IAAiB;;YAEjB,MAAM,YAAY,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CACrC,6BAAiB,EACjB,OAAO,CAAC,UAAU,EAAE,CACrB,CAAC;YAEF,IAAI,CAAC,YAAY,EAAE;gBACjB,OAAO,IAAI,CAAC,MAAM,EAAE,CAAC;aACtB;YAED,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,GAAG,YAAY,CAAC;YAC7C,MAAM,OAAO,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,UAAU,EAAE,CAAC;YACpD,MAAM,OAAO,GAAG,MAAM;iBACnB,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;iBAC5D,IAAI,CAAC,GAAG,CAAC,CAAC;YAEb,MAAM,gBAAgB,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC;YAE3E,IAAI,CAAC,gBAAgB,EAAE;gBACrB,MAAM,IAAI,qCAA4B,CAAC,uBAAuB,CAAC,CAAC;aACjE;YAED,OAAO,IAAI,CAAC,MAAM,EAAE,CAAC,IAAI,CACvB,IAAA,UAAG,EAAC,GAAG,EAAE,CACP,IAAI,CAAC,MAAM,CAAC,IAAI,CACd,+CAA+C,OAAO,EAAE,CACzD,CACF,EACD,IAAA,iBAAU,EAAC,CAAC,KAAK,EAAE,EAAE;gBACnB,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,6BAA6B,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;gBAChE,OAAO,IAAA,iBAAU,EAAC,KAAK,CAAC,CAAC;YAC3B,CAAC,CAAC,EACF,IAAA,eAAQ,EAAC,GAAS,EAAE;gBAClB,MAAM,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;YACzC,CAAC,CAAA,CAAC,CACH,CAAC;QACJ,CAAC;KAAA;CACF,CAAA;0BAjDY,eAAe;IAD3B,IAAA,mBAAU,GAAE;qCAGqB,0BAAW;QACb,gBAAS;QACZ,wBAAU;GAJ1B,eAAe,CAiD3B"}
@@ -1,4 +0,0 @@
1
- export interface LockMetadata {
2
- releaseTime: number;
3
- params: string[];
4
- }
@@ -1,3 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- //# sourceMappingURL=lock-meta-data.interface.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"lock-meta-data.interface.js","sourceRoot":"","sources":["../../lib/interfaces/lock-meta-data.interface.ts"],"names":[],"mappings":""}
@@ -1,4 +0,0 @@
1
- import * as Redis from 'ioredis';
2
- export interface LockModuleOptions {
3
- redisOptions: Redis.RedisOptions;
4
- }
@@ -1,3 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- //# sourceMappingURL=lock-options.interface.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"lock-options.interface.js","sourceRoot":"","sources":["../../lib/interfaces/lock-options.interface.ts"],"names":[],"mappings":""}
@@ -1,5 +0,0 @@
1
- import { DynamicModule } from '@nestjs/common';
2
- import { LockModuleOptions } from './interfaces';
3
- export declare class LockModule {
4
- static register(options: LockModuleOptions): DynamicModule;
5
- }
@@ -1,40 +0,0 @@
1
- "use strict";
2
- var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
- else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
- return c > 3 && r && Object.defineProperty(target, key, r), r;
7
- };
8
- var LockModule_1;
9
- Object.defineProperty(exports, "__esModule", { value: true });
10
- exports.LockModule = void 0;
11
- const common_1 = require("@nestjs/common");
12
- const Redis = require("ioredis");
13
- const lock_service_1 = require("./lock.service");
14
- const interceptors_1 = require("./interceptors");
15
- const nestjs_pino_1 = require("nestjs-pino");
16
- let LockModule = exports.LockModule = LockModule_1 = class LockModule {
17
- static register(options) {
18
- const redisClientProvider = {
19
- provide: 'REDIS_CLIENT',
20
- useFactory: () => {
21
- return new Redis.Redis(options.redisOptions);
22
- },
23
- };
24
- return {
25
- module: LockModule_1,
26
- providers: [
27
- lock_service_1.LockService,
28
- interceptors_1.LockInterceptor,
29
- redisClientProvider,
30
- nestjs_pino_1.PinoLogger,
31
- ],
32
- exports: [lock_service_1.LockService, interceptors_1.LockInterceptor],
33
- };
34
- }
35
- };
36
- exports.LockModule = LockModule = LockModule_1 = __decorate([
37
- (0, common_1.Global)(),
38
- (0, common_1.Module)({})
39
- ], LockModule);
40
- //# sourceMappingURL=lock.module.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"lock.module.js","sourceRoot":"","sources":["../lib/lock.module.ts"],"names":[],"mappings":";;;;;;;;;;AAAA,2CAA+D;AAC/D,iCAAiC;AACjC,iDAA6C;AAC7C,iDAAiD;AACjD,6CAAyC;AAOlC,IAAM,UAAU,uCAAhB,MAAM,UAAU;IACrB,MAAM,CAAC,QAAQ,CAAC,OAA0B;QACxC,MAAM,mBAAmB,GAAG;YAC1B,OAAO,EAAE,cAAc;YACvB,UAAU,EAAE,GAAgB,EAAE;gBAC5B,OAAO,IAAI,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;YAC/C,CAAC;SACF,CAAC;QAEF,OAAO;YACL,MAAM,EAAE,YAAU;YAClB,SAAS,EAAE;gBACT,0BAAW;gBACX,8BAAe;gBACf,mBAAmB;gBACnB,wBAAU;aACX;YACD,OAAO,EAAE,CAAC,0BAAW,EAAE,8BAAe,CAAC;SACxC,CAAC;IACJ,CAAC;CACF,CAAA;qBApBY,UAAU;IAFtB,IAAA,eAAM,GAAE;IACR,IAAA,eAAM,EAAC,EAAE,CAAC;GACE,UAAU,CAoBtB"}
@@ -1,9 +0,0 @@
1
- import { PinoLogger } from 'nestjs-pino';
2
- import * as Redis from 'ioredis';
3
- export declare class LockService {
4
- private readonly redisClient;
5
- private readonly logger;
6
- constructor(redisClient: Redis.Redis, logger: PinoLogger);
7
- lock(lockKey: string, releaseTime: number): Promise<boolean>;
8
- unlock(lockKey: string): Promise<void>;
9
- }
@@ -1,58 +0,0 @@
1
- "use strict";
2
- var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
- else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
- return c > 3 && r && Object.defineProperty(target, key, r), r;
7
- };
8
- var __metadata = (this && this.__metadata) || function (k, v) {
9
- if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
- };
11
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
12
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
13
- return new (P || (P = Promise))(function (resolve, reject) {
14
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
15
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
16
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
17
- step((generator = generator.apply(thisArg, _arguments || [])).next());
18
- });
19
- };
20
- var LockService_1;
21
- Object.defineProperty(exports, "__esModule", { value: true });
22
- exports.LockService = void 0;
23
- const common_1 = require("@nestjs/common");
24
- const nestjs_pino_1 = require("nestjs-pino");
25
- const Redis = require("ioredis");
26
- let LockService = exports.LockService = LockService_1 = class LockService {
27
- constructor(redisClient, logger) {
28
- this.redisClient = redisClient;
29
- this.logger = logger;
30
- this.logger.setContext(LockService_1.name);
31
- }
32
- lock(lockKey, releaseTime) {
33
- return __awaiter(this, void 0, void 0, function* () {
34
- try {
35
- const isLockSuccessful = yield this.redisClient.set(lockKey, 'LOCKED', 'EX', releaseTime);
36
- if (isLockSuccessful) {
37
- this.logger.info(`Successfully obtained lock for key ${lockKey}`);
38
- return true;
39
- }
40
- }
41
- catch (error) {
42
- this.logger.error(`Could not obtain lock for key ${lockKey}`, error);
43
- }
44
- return false;
45
- });
46
- }
47
- unlock(lockKey) {
48
- return __awaiter(this, void 0, void 0, function* () {
49
- yield this.redisClient.del(lockKey);
50
- this.logger.info(`Lock released for key ${lockKey}`);
51
- });
52
- }
53
- };
54
- exports.LockService = LockService = LockService_1 = __decorate([
55
- (0, common_1.Injectable)(),
56
- __metadata("design:paramtypes", [Redis.Redis, nestjs_pino_1.PinoLogger])
57
- ], LockService);
58
- //# sourceMappingURL=lock.service.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"lock.service.js","sourceRoot":"","sources":["../lib/lock.service.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;AAAA,2CAA4C;AAC5C,6CAAyC;AACzC,iCAAiC;AAG1B,IAAM,WAAW,yCAAjB,MAAM,WAAW;IACtB,YACmB,WAAwB,EACxB,MAAkB;QADlB,gBAAW,GAAX,WAAW,CAAa;QACxB,WAAM,GAAN,MAAM,CAAY;QAEnC,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,aAAW,CAAC,IAAI,CAAC,CAAC;IAC3C,CAAC;IAEK,IAAI,CAAC,OAAe,EAAE,WAAmB;;YAC7C,IAAI;gBACF,MAAM,gBAAgB,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,GAAG,CACjD,OAAO,EACP,QAAQ,EACR,IAAI,EACJ,WAAW,CACZ,CAAC;gBACF,IAAI,gBAAgB,EAAE;oBACpB,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,sCAAsC,OAAO,EAAE,CAAC,CAAC;oBAClE,OAAO,IAAI,CAAC;iBACb;aACF;YAAC,OAAO,KAAK,EAAE;gBACd,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,iCAAiC,OAAO,EAAE,EAAE,KAAK,CAAC,CAAC;aACtE;YACD,OAAO,KAAK,CAAC;QACf,CAAC;KAAA;IAEK,MAAM,CAAC,OAAe;;YAC1B,MAAM,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;YACpC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,yBAAyB,OAAO,EAAE,CAAC,CAAC;QACvD,CAAC;KAAA;CACF,CAAA;sBA9BY,WAAW;IADvB,IAAA,mBAAU,GAAE;qCAGqB,KAAK,CAAC,KAAK,EAChB,wBAAU;GAH1B,WAAW,CA8BvB"}
@@ -1 +0,0 @@
1
- export {};
package/dist/lock.spec.js DELETED
@@ -1,53 +0,0 @@
1
- "use strict";
2
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
- return new (P || (P = Promise))(function (resolve, reject) {
5
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
- step((generator = generator.apply(thisArg, _arguments || [])).next());
9
- });
10
- };
11
- Object.defineProperty(exports, "__esModule", { value: true });
12
- const lock_service_1 = require("./lock.service");
13
- const ioredis_mock_1 = require("ioredis-mock");
14
- describe('LockService', () => {
15
- let lockService;
16
- let redisClient;
17
- let logger;
18
- beforeEach(() => {
19
- redisClient = new ioredis_mock_1.default();
20
- logger = { setContext: jest.fn(), error: jest.fn(), info: jest.fn() };
21
- lockService = new lock_service_1.LockService(redisClient, logger);
22
- });
23
- it('should be defined', () => {
24
- expect(lockService).toBeDefined();
25
- });
26
- describe('lock', () => {
27
- it('should successfully lock', () => __awaiter(void 0, void 0, void 0, function* () {
28
- const lockKey = 'testKey';
29
- const releaseTime = 1500;
30
- const result = yield lockService.lock(lockKey, releaseTime);
31
- expect(result).toBe(true);
32
- expect(yield redisClient.get(lockKey)).toBe('LOCKED');
33
- }));
34
- it('should handle error while locking', () => __awaiter(void 0, void 0, void 0, function* () {
35
- const lockKey = 'testKey';
36
- const releaseTime = 1500;
37
- redisClient.set = jest.fn(() => {
38
- throw new Error('Redis error');
39
- });
40
- const result = yield lockService.lock(lockKey, releaseTime);
41
- expect(result).toBe(false);
42
- }));
43
- });
44
- describe('unlock', () => {
45
- it('should successfully unlock', () => __awaiter(void 0, void 0, void 0, function* () {
46
- const lockKey = 'testKey';
47
- yield redisClient.set(lockKey, 'LOCKED');
48
- yield lockService.unlock(lockKey);
49
- expect(yield redisClient.get(lockKey)).toBe(null);
50
- }));
51
- });
52
- });
53
- //# sourceMappingURL=lock.spec.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"lock.spec.js","sourceRoot":"","sources":["../lib/lock.spec.ts"],"names":[],"mappings":";;;;;;;;;;;AAAA,iDAA6C;AAE7C,+CAAqC;AAGrC,QAAQ,CAAC,aAAa,EAAE,GAAG,EAAE;IAC3B,IAAI,WAAwB,CAAC;IAC7B,IAAI,WAAkB,CAAC;IACvB,IAAI,MAAkB,CAAC;IAEvB,UAAU,CAAC,GAAG,EAAE;QACd,WAAW,GAAI,IAAI,sBAAS,EAAuB,CAAC;QACpD,MAAM,GAAG,EAAE,UAAU,EAAE,IAAI,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,EAAE,EAAS,CAAC;QAC7E,WAAW,GAAG,IAAI,0BAAW,CAAC,WAAkB,EAAE,MAAM,CAAC,CAAC;IAC5D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,mBAAmB,EAAE,GAAG,EAAE;QAC3B,MAAM,CAAC,WAAW,CAAC,CAAC,WAAW,EAAE,CAAC;IACpC,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,MAAM,EAAE,GAAG,EAAE;QACpB,EAAE,CAAC,0BAA0B,EAAE,GAAS,EAAE;YACxC,MAAM,OAAO,GAAG,SAAS,CAAC;YAC1B,MAAM,WAAW,GAAG,IAAI,CAAC;YAEzB,MAAM,MAAM,GAAG,MAAM,WAAW,CAAC,IAAI,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC;YAE5D,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAC1B,MAAM,CAAC,MAAM,WAAW,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACxD,CAAC,CAAA,CAAC,CAAC;QAEH,EAAE,CAAC,mCAAmC,EAAE,GAAS,EAAE;YACjD,MAAM,OAAO,GAAG,SAAS,CAAC;YAC1B,MAAM,WAAW,GAAG,IAAI,CAAC;YAEzB,WAAW,CAAC,GAAG,GAAG,IAAI,CAAC,EAAE,CAAC,GAAG,EAAE;gBAC7B,MAAM,IAAI,KAAK,CAAC,aAAa,CAAC,CAAC;YACjC,CAAC,CAAC,CAAC;YAEH,MAAM,MAAM,GAAG,MAAM,WAAW,CAAC,IAAI,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC;YAE5D,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC7B,CAAC,CAAA,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,QAAQ,EAAE,GAAG,EAAE;QACtB,EAAE,CAAC,4BAA4B,EAAE,GAAS,EAAE;YAC1C,MAAM,OAAO,GAAG,SAAS,CAAC;YAC1B,MAAM,WAAW,CAAC,GAAG,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;YAEzC,MAAM,WAAW,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;YAElC,MAAM,CAAC,MAAM,WAAW,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACpD,CAAC,CAAA,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}