@payloadcms/plugin-multi-tenant 4.0.0-internal.9496957 → 4.0.0-internal.970009e

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 (49) hide show
  1. package/dist/components/TenantSelector/index.css +4 -4
  2. package/dist/fields/tenantField/index.d.ts +4 -2
  3. package/dist/fields/tenantField/index.d.ts.map +1 -1
  4. package/dist/fields/tenantField/index.js +36 -9
  5. package/dist/fields/tenantField/index.js.map +1 -1
  6. package/dist/filters/filterDocumentsByTenants.js.map +1 -1
  7. package/dist/hooks/afterTenantDelete.d.ts.map +1 -1
  8. package/dist/hooks/afterTenantDelete.js +3 -0
  9. package/dist/hooks/afterTenantDelete.js.map +1 -1
  10. package/dist/hooks/enforceTenantMembership.d.ts +15 -0
  11. package/dist/hooks/enforceTenantMembership.d.ts.map +1 -0
  12. package/dist/hooks/enforceTenantMembership.js +39 -0
  13. package/dist/hooks/enforceTenantMembership.js.map +1 -0
  14. package/dist/index.d.ts.map +1 -1
  15. package/dist/index.js +13 -1
  16. package/dist/index.js.map +1 -1
  17. package/dist/providers/TenantSelectionProvider/index.client.d.ts.map +1 -1
  18. package/dist/providers/TenantSelectionProvider/index.client.js +22 -24
  19. package/dist/providers/TenantSelectionProvider/index.client.js.map +1 -1
  20. package/dist/types.d.ts +4 -3
  21. package/dist/types.d.ts.map +1 -1
  22. package/dist/types.js.map +1 -1
  23. package/dist/utilities/addCollectionAccess.d.ts.map +1 -1
  24. package/dist/utilities/addCollectionAccess.js +10 -3
  25. package/dist/utilities/addCollectionAccess.js.map +1 -1
  26. package/dist/utilities/addFilterOptionsToFields.js.map +1 -1
  27. package/dist/utilities/getGlobalViewRedirect.d.ts.map +1 -1
  28. package/dist/utilities/getGlobalViewRedirect.js +2 -0
  29. package/dist/utilities/getGlobalViewRedirect.js.map +1 -1
  30. package/dist/utilities/getTenantIDsFromValue.d.ts +2 -0
  31. package/dist/utilities/getTenantIDsFromValue.d.ts.map +1 -0
  32. package/dist/utilities/getTenantIDsFromValue.js +14 -0
  33. package/dist/utilities/getTenantIDsFromValue.js.map +1 -0
  34. package/dist/utilities/getUserTenantIDs.d.ts.map +1 -1
  35. package/dist/utilities/getUserTenantIDs.js +3 -2
  36. package/dist/utilities/getUserTenantIDs.js.map +1 -1
  37. package/dist/utilities/isValidTenantAssignment.d.ts +13 -0
  38. package/dist/utilities/isValidTenantAssignment.d.ts.map +1 -0
  39. package/dist/utilities/isValidTenantAssignment.js +28 -0
  40. package/dist/utilities/isValidTenantAssignment.js.map +1 -0
  41. package/dist/utilities/shouldRefreshTenantSelection.d.ts +5 -0
  42. package/dist/utilities/shouldRefreshTenantSelection.d.ts.map +1 -0
  43. package/dist/utilities/shouldRefreshTenantSelection.js +3 -0
  44. package/dist/utilities/shouldRefreshTenantSelection.js.map +1 -0
  45. package/package.json +24 -27
  46. package/dist/index.spec.js +0 -70
  47. package/dist/index.spec.js.map +0 -1
  48. package/dist/utilities/addCollectionAccess.spec.js +0 -134
  49. package/dist/utilities/addCollectionAccess.spec.js.map +0 -1
package/package.json CHANGED
@@ -1,21 +1,16 @@
1
1
  {
2
2
  "name": "@payloadcms/plugin-multi-tenant",
3
- "version": "4.0.0-internal.9496957",
3
+ "version": "4.0.0-internal.970009e",
4
4
  "description": "Multi Tenant plugin for Payload",
5
5
  "keywords": [
6
- "payload",
7
6
  "cms",
7
+ "multi-tenant",
8
+ "nextjs",
9
+ "payload",
8
10
  "plugin",
9
- "typescript",
10
11
  "react",
11
- "multi-tenant",
12
- "nextjs"
12
+ "typescript"
13
13
  ],
14
- "repository": {
15
- "type": "git",
16
- "url": "https://github.com/payloadcms/payload.git",
17
- "directory": "packages/plugin-multi-tenant"
18
- },
19
14
  "license": "MIT",
20
15
  "author": "Payload <dev@payloadcms.com> (https://payloadcms.com)",
21
16
  "maintainers": [
@@ -25,10 +20,22 @@
25
20
  "url": "https://payloadcms.com"
26
21
  }
27
22
  ],
23
+ "repository": {
24
+ "type": "git",
25
+ "url": "https://github.com/payloadcms/payload.git",
26
+ "directory": "packages/plugin-multi-tenant"
27
+ },
28
+ "files": [
29
+ "dist",
30
+ "types.js",
31
+ "types.d.ts"
32
+ ],
33
+ "type": "module",
28
34
  "sideEffects": [
29
35
  "*.css"
30
36
  ],
31
- "type": "module",
37
+ "main": "./dist/index.js",
38
+ "types": "./dist/index.d.ts",
32
39
  "exports": {
33
40
  ".": {
34
41
  "import": "./dist/index.js",
@@ -71,22 +78,14 @@
71
78
  "default": "./dist/translations/languages/*.js"
72
79
  }
73
80
  },
74
- "main": "./dist/index.js",
75
- "types": "./dist/index.d.ts",
76
- "files": [
77
- "dist",
78
- "types.js",
79
- "types.d.ts"
80
- ],
81
81
  "devDependencies": {
82
- "@payloadcms/eslint-config": "3.28.0",
83
- "@payloadcms/ui": "4.0.0-internal.9496957",
84
- "payload": "4.0.0-internal.9496957",
85
- "@payloadcms/translations": "4.0.0-internal.9496957"
82
+ "@payloadcms/translations": "4.0.0-internal.970009e",
83
+ "@payloadcms/ui": "4.0.0-internal.970009e",
84
+ "payload": "4.0.0-internal.970009e"
86
85
  },
87
86
  "peerDependencies": {
88
- "@payloadcms/ui": "4.0.0-internal.9496957",
89
- "payload": "4.0.0-internal.9496957"
87
+ "@payloadcms/ui": "4.0.0-internal.970009e",
88
+ "payload": "4.0.0-internal.970009e"
90
89
  },
91
90
  "homepage:": "https://payloadcms.com",
92
91
  "scripts": {
@@ -95,9 +94,7 @@
95
94
  "build:swc": "swc ./src -d ./dist --config-file .swcrc --strip-leading-paths",
96
95
  "build:types": "tsc --emitDeclarationOnly --outDir dist",
97
96
  "clean": "rimraf {dist,*.tsbuildinfo}",
98
- "copyfiles": "copyfiles -u 1 \"src/**/*.{html,css,scss,ttf,woff,woff2,eot,svg,jpg,png,json}\" dist/",
99
- "lint": "eslint .",
100
- "lint:fix": "eslint . --fix",
97
+ "copyfiles": "copyfiles -u 1 -e \"**/*.spec.*\" \"src/**/*.{html,css,scss,ttf,woff,woff2,eot,svg,jpg,png,json}\" dist/",
101
98
  "pack:plugin": "pnpm build && pnpm pack"
102
99
  }
103
100
  }
@@ -1,70 +0,0 @@
1
- import { describe, expect, it } from 'vitest';
2
- import { multiTenantPlugin } from './index.js';
3
- describe('multiTenantPlugin', ()=>{
4
- it('applies tenant assignment access defaults', async ()=>{
5
- let hasAllTenantAccess = false;
6
- const plugin = multiTenantPlugin({
7
- collections: {},
8
- userHasAccessToAllTenants: ()=>hasAllTenantAccess
9
- });
10
- const config = await plugin({
11
- collections: [
12
- {
13
- slug: 'users',
14
- auth: true,
15
- fields: []
16
- },
17
- {
18
- slug: 'tenants',
19
- fields: []
20
- }
21
- ]
22
- });
23
- const usersCollection = config.collections?.find(({ slug })=>slug === 'users');
24
- const tenantsField = usersCollection?.fields.find((field)=>'name' in field && field.name === 'tenants');
25
- const accessArgs = {
26
- req: {
27
- user: {
28
- id: 'test-user'
29
- }
30
- }
31
- };
32
- expect(await tenantsField?.access?.create?.(accessArgs)).toBe(false);
33
- expect(await tenantsField?.access?.update?.(accessArgs)).toBe(false);
34
- hasAllTenantAccess = true;
35
- expect(await tenantsField?.access?.create?.(accessArgs)).toBe(true);
36
- expect(await tenantsField?.access?.update?.(accessArgs)).toBe(true);
37
- });
38
- it('retains configured tenant assignment access callbacks', async ()=>{
39
- const createAccess = ()=>false;
40
- const updateAccess = ()=>true;
41
- const plugin = multiTenantPlugin({
42
- collections: {},
43
- tenantsArrayField: {
44
- arrayFieldAccess: {
45
- create: createAccess,
46
- update: updateAccess
47
- }
48
- }
49
- });
50
- const config = await plugin({
51
- collections: [
52
- {
53
- slug: 'users',
54
- auth: true,
55
- fields: []
56
- },
57
- {
58
- slug: 'tenants',
59
- fields: []
60
- }
61
- ]
62
- });
63
- const usersCollection = config.collections?.find(({ slug })=>slug === 'users');
64
- const tenantsField = usersCollection?.fields.find((field)=>'name' in field && field.name === 'tenants');
65
- expect(tenantsField?.access?.create).toBe(createAccess);
66
- expect(tenantsField?.access?.update).toBe(updateAccess);
67
- });
68
- });
69
-
70
- //# sourceMappingURL=index.spec.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/index.spec.ts"],"sourcesContent":["import type { ArrayField, Config } from 'payload'\n\nimport { describe, expect, it } from 'vitest'\n\nimport { multiTenantPlugin } from './index.js'\n\ndescribe('multiTenantPlugin', () => {\n it('applies tenant assignment access defaults', async () => {\n let hasAllTenantAccess = false\n const plugin = multiTenantPlugin({\n collections: {},\n userHasAccessToAllTenants: () => hasAllTenantAccess,\n })\n const config = await plugin({\n collections: [\n { slug: 'users', auth: true, fields: [] },\n { slug: 'tenants', fields: [] },\n ],\n } as Config)\n const usersCollection = config.collections?.find(({ slug }) => slug === 'users')\n const tenantsField = usersCollection?.fields.find(\n (field): field is ArrayField => 'name' in field && field.name === 'tenants',\n )\n const accessArgs = { req: { user: { id: 'test-user' } } } as never\n\n expect(await tenantsField?.access?.create?.(accessArgs)).toBe(false)\n expect(await tenantsField?.access?.update?.(accessArgs)).toBe(false)\n\n hasAllTenantAccess = true\n\n expect(await tenantsField?.access?.create?.(accessArgs)).toBe(true)\n expect(await tenantsField?.access?.update?.(accessArgs)).toBe(true)\n })\n\n it('retains configured tenant assignment access callbacks', async () => {\n const createAccess = () => false\n const updateAccess = () => true\n const plugin = multiTenantPlugin({\n collections: {},\n tenantsArrayField: {\n arrayFieldAccess: {\n create: createAccess,\n update: updateAccess,\n },\n },\n })\n const config = await plugin({\n collections: [\n { slug: 'users', auth: true, fields: [] },\n { slug: 'tenants', fields: [] },\n ],\n } as Config)\n const usersCollection = config.collections?.find(({ slug }) => slug === 'users')\n const tenantsField = usersCollection?.fields.find(\n (field): field is ArrayField => 'name' in field && field.name === 'tenants',\n )\n\n expect(tenantsField?.access?.create).toBe(createAccess)\n expect(tenantsField?.access?.update).toBe(updateAccess)\n })\n})\n"],"names":["describe","expect","it","multiTenantPlugin","hasAllTenantAccess","plugin","collections","userHasAccessToAllTenants","config","slug","auth","fields","usersCollection","find","tenantsField","field","name","accessArgs","req","user","id","access","create","toBe","update","createAccess","updateAccess","tenantsArrayField","arrayFieldAccess"],"mappings":"AAEA,SAASA,QAAQ,EAAEC,MAAM,EAAEC,EAAE,QAAQ,SAAQ;AAE7C,SAASC,iBAAiB,QAAQ,aAAY;AAE9CH,SAAS,qBAAqB;IAC5BE,GAAG,6CAA6C;QAC9C,IAAIE,qBAAqB;QACzB,MAAMC,SAASF,kBAAkB;YAC/BG,aAAa,CAAC;YACdC,2BAA2B,IAAMH;QACnC;QACA,MAAMI,SAAS,MAAMH,OAAO;YAC1BC,aAAa;gBACX;oBAAEG,MAAM;oBAASC,MAAM;oBAAMC,QAAQ,EAAE;gBAAC;gBACxC;oBAAEF,MAAM;oBAAWE,QAAQ,EAAE;gBAAC;aAC/B;QACH;QACA,MAAMC,kBAAkBJ,OAAOF,WAAW,EAAEO,KAAK,CAAC,EAAEJ,IAAI,EAAE,GAAKA,SAAS;QACxE,MAAMK,eAAeF,iBAAiBD,OAAOE,KAC3C,CAACE,QAA+B,UAAUA,SAASA,MAAMC,IAAI,KAAK;QAEpE,MAAMC,aAAa;YAAEC,KAAK;gBAAEC,MAAM;oBAAEC,IAAI;gBAAY;YAAE;QAAE;QAExDnB,OAAO,MAAMa,cAAcO,QAAQC,SAASL,aAAaM,IAAI,CAAC;QAC9DtB,OAAO,MAAMa,cAAcO,QAAQG,SAASP,aAAaM,IAAI,CAAC;QAE9DnB,qBAAqB;QAErBH,OAAO,MAAMa,cAAcO,QAAQC,SAASL,aAAaM,IAAI,CAAC;QAC9DtB,OAAO,MAAMa,cAAcO,QAAQG,SAASP,aAAaM,IAAI,CAAC;IAChE;IAEArB,GAAG,yDAAyD;QAC1D,MAAMuB,eAAe,IAAM;QAC3B,MAAMC,eAAe,IAAM;QAC3B,MAAMrB,SAASF,kBAAkB;YAC/BG,aAAa,CAAC;YACdqB,mBAAmB;gBACjBC,kBAAkB;oBAChBN,QAAQG;oBACRD,QAAQE;gBACV;YACF;QACF;QACA,MAAMlB,SAAS,MAAMH,OAAO;YAC1BC,aAAa;gBACX;oBAAEG,MAAM;oBAASC,MAAM;oBAAMC,QAAQ,EAAE;gBAAC;gBACxC;oBAAEF,MAAM;oBAAWE,QAAQ,EAAE;gBAAC;aAC/B;QACH;QACA,MAAMC,kBAAkBJ,OAAOF,WAAW,EAAEO,KAAK,CAAC,EAAEJ,IAAI,EAAE,GAAKA,SAAS;QACxE,MAAMK,eAAeF,iBAAiBD,OAAOE,KAC3C,CAACE,QAA+B,UAAUA,SAASA,MAAMC,IAAI,KAAK;QAGpEf,OAAOa,cAAcO,QAAQC,QAAQC,IAAI,CAACE;QAC1CxB,OAAOa,cAAcO,QAAQG,QAAQD,IAAI,CAACG;IAC5C;AACF"}
@@ -1,134 +0,0 @@
1
- import { describe, expect, it, vi } from 'vitest';
2
- import { addCollectionAccess } from './addCollectionAccess.js';
3
- const createScope = (collection, accessResultCallback)=>({
4
- accessResultCallback,
5
- adminUsersSlug: 'users',
6
- collection,
7
- fieldName: 'tenant',
8
- userHasAccessToAllTenants: ()=>false
9
- });
10
- const createArgs = (slug = 'posts')=>({
11
- req: {
12
- user: {
13
- collection: 'users',
14
- id: 'user-1',
15
- tenants: [
16
- {
17
- tenant: 'tenant-1'
18
- }
19
- ]
20
- }
21
- },
22
- slug
23
- });
24
- describe('addCollectionAccess', ()=>{
25
- it('adds tenant constraints through base access without replacing collection access', async ()=>{
26
- const documentRead = vi.fn(()=>({
27
- published: {
28
- equals: true
29
- }
30
- }));
31
- const collection = {
32
- slug: 'posts',
33
- access: {
34
- read: documentRead
35
- },
36
- fields: []
37
- };
38
- const config = {
39
- baseAccess: {
40
- collections: {
41
- read: ()=>({
42
- archived: {
43
- not_equals: true
44
- }
45
- })
46
- }
47
- }
48
- };
49
- addCollectionAccess({
50
- config,
51
- scopes: [
52
- createScope(collection)
53
- ]
54
- });
55
- expect(collection.access?.read).toBe(documentRead);
56
- await expect(config.baseAccess?.collections?.read?.(createArgs())).resolves.toEqual({
57
- and: [
58
- {
59
- archived: {
60
- not_equals: true
61
- }
62
- },
63
- {
64
- tenant: {
65
- in: [
66
- 'tenant-1'
67
- ]
68
- }
69
- }
70
- ]
71
- });
72
- await expect(config.baseAccess?.collections?.read?.(createArgs('pages'))).resolves.toEqual({
73
- archived: {
74
- not_equals: true
75
- }
76
- });
77
- expect(documentRead).not.toHaveBeenCalled();
78
- });
79
- it('returns a boolean tenant result for collection create access', async ()=>{
80
- const collection = {
81
- slug: 'posts',
82
- fields: []
83
- };
84
- const config = {};
85
- addCollectionAccess({
86
- config,
87
- scopes: [
88
- createScope(collection)
89
- ]
90
- });
91
- await expect(config.baseAccess?.collections?.create?.(createArgs())).resolves.toBe(true);
92
- });
93
- it('keeps callback wrapping when an access result override is configured', async ()=>{
94
- const documentResult = {
95
- published: {
96
- equals: true
97
- }
98
- };
99
- const documentRead = vi.fn(()=>documentResult);
100
- const accessResultCallback = vi.fn(({ accessResult })=>accessResult);
101
- const collection = {
102
- slug: 'posts',
103
- access: {
104
- read: documentRead
105
- },
106
- fields: []
107
- };
108
- const config = {};
109
- addCollectionAccess({
110
- config,
111
- scopes: [
112
- createScope(collection, accessResultCallback)
113
- ]
114
- });
115
- expect(config.baseAccess).toBeUndefined();
116
- await expect(collection.access?.read?.(createArgs())).resolves.toEqual({
117
- and: [
118
- documentResult,
119
- {
120
- tenant: {
121
- in: [
122
- 'tenant-1'
123
- ]
124
- }
125
- }
126
- ]
127
- });
128
- expect(accessResultCallback).toHaveBeenCalledWith(expect.objectContaining({
129
- accessKey: 'read'
130
- }));
131
- });
132
- });
133
-
134
- //# sourceMappingURL=addCollectionAccess.spec.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../src/utilities/addCollectionAccess.spec.ts"],"sourcesContent":["import type { AccessArgs, CollectionConfig, Config } from 'payload'\n\nimport { describe, expect, it, vi } from 'vitest'\n\nimport type { TenantAccessConfig } from './addCollectionAccess.js'\n\nimport { addCollectionAccess } from './addCollectionAccess.js'\n\nconst createScope = (\n collection: CollectionConfig,\n accessResultCallback?: TenantAccessConfig['accessResultCallback'],\n): TenantAccessConfig => ({\n accessResultCallback,\n adminUsersSlug: 'users',\n collection,\n fieldName: 'tenant',\n userHasAccessToAllTenants: () => false,\n})\n\nconst createArgs = (slug = 'posts'): AccessArgs => ({\n req: {\n user: {\n collection: 'users',\n id: 'user-1',\n tenants: [{ tenant: 'tenant-1' }],\n },\n } as unknown as AccessArgs['req'],\n slug,\n})\n\ndescribe('addCollectionAccess', () => {\n it('adds tenant constraints through base access without replacing collection access', async () => {\n const documentRead = vi.fn(() => ({ published: { equals: true } }))\n const collection: CollectionConfig = {\n slug: 'posts',\n access: { read: documentRead },\n fields: [],\n }\n const config = {\n baseAccess: {\n collections: {\n read: () => ({ archived: { not_equals: true } }),\n },\n },\n } as Config\n\n addCollectionAccess({ config, scopes: [createScope(collection)] })\n\n expect(collection.access?.read).toBe(documentRead)\n await expect(config.baseAccess?.collections?.read?.(createArgs())).resolves.toEqual({\n and: [{ archived: { not_equals: true } }, { tenant: { in: ['tenant-1'] } }],\n })\n await expect(config.baseAccess?.collections?.read?.(createArgs('pages'))).resolves.toEqual({\n archived: { not_equals: true },\n })\n expect(documentRead).not.toHaveBeenCalled()\n })\n\n it('returns a boolean tenant result for collection create access', async () => {\n const collection: CollectionConfig = { slug: 'posts', fields: [] }\n const config = {} as Config\n\n addCollectionAccess({ config, scopes: [createScope(collection)] })\n\n await expect(config.baseAccess?.collections?.create?.(createArgs())).resolves.toBe(true)\n })\n\n it('keeps callback wrapping when an access result override is configured', async () => {\n const documentResult = { published: { equals: true } }\n const documentRead = vi.fn(() => documentResult)\n const accessResultCallback = vi.fn(({ accessResult }) => accessResult)\n const collection: CollectionConfig = {\n slug: 'posts',\n access: { read: documentRead },\n fields: [],\n }\n const config = {} as Config\n\n addCollectionAccess({\n config,\n scopes: [createScope(collection, accessResultCallback)],\n })\n\n expect(config.baseAccess).toBeUndefined()\n await expect(collection.access?.read?.(createArgs())).resolves.toEqual({\n and: [documentResult, { tenant: { in: ['tenant-1'] } }],\n })\n expect(accessResultCallback).toHaveBeenCalledWith(\n expect.objectContaining({ accessKey: 'read' }),\n )\n })\n})\n"],"names":["describe","expect","it","vi","addCollectionAccess","createScope","collection","accessResultCallback","adminUsersSlug","fieldName","userHasAccessToAllTenants","createArgs","slug","req","user","id","tenants","tenant","documentRead","fn","published","equals","access","read","fields","config","baseAccess","collections","archived","not_equals","scopes","toBe","resolves","toEqual","and","in","not","toHaveBeenCalled","create","documentResult","accessResult","toBeUndefined","toHaveBeenCalledWith","objectContaining","accessKey"],"mappings":"AAEA,SAASA,QAAQ,EAAEC,MAAM,EAAEC,EAAE,EAAEC,EAAE,QAAQ,SAAQ;AAIjD,SAASC,mBAAmB,QAAQ,2BAA0B;AAE9D,MAAMC,cAAc,CAClBC,YACAC,uBACwB,CAAA;QACxBA;QACAC,gBAAgB;QAChBF;QACAG,WAAW;QACXC,2BAA2B,IAAM;IACnC,CAAA;AAEA,MAAMC,aAAa,CAACC,OAAO,OAAO,GAAkB,CAAA;QAClDC,KAAK;YACHC,MAAM;gBACJR,YAAY;gBACZS,IAAI;gBACJC,SAAS;oBAAC;wBAAEC,QAAQ;oBAAW;iBAAE;YACnC;QACF;QACAL;IACF,CAAA;AAEAZ,SAAS,uBAAuB;IAC9BE,GAAG,mFAAmF;QACpF,MAAMgB,eAAef,GAAGgB,EAAE,CAAC,IAAO,CAAA;gBAAEC,WAAW;oBAAEC,QAAQ;gBAAK;YAAE,CAAA;QAChE,MAAMf,aAA+B;YACnCM,MAAM;YACNU,QAAQ;gBAAEC,MAAML;YAAa;YAC7BM,QAAQ,EAAE;QACZ;QACA,MAAMC,SAAS;YACbC,YAAY;gBACVC,aAAa;oBACXJ,MAAM,IAAO,CAAA;4BAAEK,UAAU;gCAAEC,YAAY;4BAAK;wBAAE,CAAA;gBAChD;YACF;QACF;QAEAzB,oBAAoB;YAAEqB;YAAQK,QAAQ;gBAACzB,YAAYC;aAAY;QAAC;QAEhEL,OAAOK,WAAWgB,MAAM,EAAEC,MAAMQ,IAAI,CAACb;QACrC,MAAMjB,OAAOwB,OAAOC,UAAU,EAAEC,aAAaJ,OAAOZ,eAAeqB,QAAQ,CAACC,OAAO,CAAC;YAClFC,KAAK;gBAAC;oBAAEN,UAAU;wBAAEC,YAAY;oBAAK;gBAAE;gBAAG;oBAAEZ,QAAQ;wBAAEkB,IAAI;4BAAC;yBAAW;oBAAC;gBAAE;aAAE;QAC7E;QACA,MAAMlC,OAAOwB,OAAOC,UAAU,EAAEC,aAAaJ,OAAOZ,WAAW,WAAWqB,QAAQ,CAACC,OAAO,CAAC;YACzFL,UAAU;gBAAEC,YAAY;YAAK;QAC/B;QACA5B,OAAOiB,cAAckB,GAAG,CAACC,gBAAgB;IAC3C;IAEAnC,GAAG,gEAAgE;QACjE,MAAMI,aAA+B;YAAEM,MAAM;YAASY,QAAQ,EAAE;QAAC;QACjE,MAAMC,SAAS,CAAC;QAEhBrB,oBAAoB;YAAEqB;YAAQK,QAAQ;gBAACzB,YAAYC;aAAY;QAAC;QAEhE,MAAML,OAAOwB,OAAOC,UAAU,EAAEC,aAAaW,SAAS3B,eAAeqB,QAAQ,CAACD,IAAI,CAAC;IACrF;IAEA7B,GAAG,wEAAwE;QACzE,MAAMqC,iBAAiB;YAAEnB,WAAW;gBAAEC,QAAQ;YAAK;QAAE;QACrD,MAAMH,eAAef,GAAGgB,EAAE,CAAC,IAAMoB;QACjC,MAAMhC,uBAAuBJ,GAAGgB,EAAE,CAAC,CAAC,EAAEqB,YAAY,EAAE,GAAKA;QACzD,MAAMlC,aAA+B;YACnCM,MAAM;YACNU,QAAQ;gBAAEC,MAAML;YAAa;YAC7BM,QAAQ,EAAE;QACZ;QACA,MAAMC,SAAS,CAAC;QAEhBrB,oBAAoB;YAClBqB;YACAK,QAAQ;gBAACzB,YAAYC,YAAYC;aAAsB;QACzD;QAEAN,OAAOwB,OAAOC,UAAU,EAAEe,aAAa;QACvC,MAAMxC,OAAOK,WAAWgB,MAAM,EAAEC,OAAOZ,eAAeqB,QAAQ,CAACC,OAAO,CAAC;YACrEC,KAAK;gBAACK;gBAAgB;oBAAEtB,QAAQ;wBAAEkB,IAAI;4BAAC;yBAAW;oBAAC;gBAAE;aAAE;QACzD;QACAlC,OAAOM,sBAAsBmC,oBAAoB,CAC/CzC,OAAO0C,gBAAgB,CAAC;YAAEC,WAAW;QAAO;IAEhD;AACF"}