vitest-plugin-vis 1.0.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.
- package/esm/client/ctx.d.ts +6 -0
- package/esm/client/ctx.d.ts.map +1 -0
- package/esm/client/ctx.js +7 -0
- package/esm/client/expect/expectation_result.d.ts +3 -0
- package/esm/client/expect/expectation_result.d.ts.map +1 -0
- package/esm/client/expect/expectation_result.js +5 -0
- package/esm/client/expect/extend.d.ts +8 -0
- package/esm/client/expect/extend.d.ts.map +1 -0
- package/esm/client/expect/extend.js +3 -0
- package/esm/client/expect/to_match_image_snapshot.d.ts +9 -0
- package/esm/client/expect/to_match_image_snapshot.d.ts.map +1 -0
- package/esm/client/expect/to_match_image_snapshot.js +32 -0
- package/esm/client/expect/to_match_image_snapshot.logic.d.ts +2 -0
- package/esm/client/expect/to_match_image_snapshot.logic.d.ts.map +1 -0
- package/esm/client/expect/to_match_image_snapshot.logic.js +11 -0
- package/esm/client/expect/to_match_image_snapshot.types.d.ts +7 -0
- package/esm/client/expect/to_match_image_snapshot.types.d.ts.map +1 -0
- package/esm/client/expect/to_match_image_snapshot.types.js +1 -0
- package/esm/client/page/extend.d.ts +6 -0
- package/esm/client/page/extend.d.ts.map +1 -0
- package/esm/client/page/extend.js +3 -0
- package/esm/client/page/has_image_snapshot.d.ts +10 -0
- package/esm/client/page/has_image_snapshot.d.ts.map +1 -0
- package/esm/client/page/has_image_snapshot.js +23 -0
- package/esm/client/selector.d.ts +9 -0
- package/esm/client/selector.d.ts.map +1 -0
- package/esm/client/selector.js +104 -0
- package/esm/client/should_take_snapshot.d.ts +10 -0
- package/esm/client/should_take_snapshot.d.ts.map +1 -0
- package/esm/client/should_take_snapshot.js +13 -0
- package/esm/client/snapshot_options.d.ts +34 -0
- package/esm/client/snapshot_options.d.ts.map +1 -0
- package/esm/client/snapshot_options.internal.d.ts +3 -0
- package/esm/client/snapshot_options.internal.d.ts.map +1 -0
- package/esm/client/snapshot_options.internal.js +20 -0
- package/esm/client/snapshot_options.js +16 -0
- package/esm/client/task_id.d.ts +7 -0
- package/esm/client/task_id.d.ts.map +1 -0
- package/esm/client/task_id.js +10 -0
- package/esm/client.d.ts +8 -0
- package/esm/client.d.ts.map +1 -0
- package/esm/client.js +5 -0
- package/esm/commands.d.ts +5 -0
- package/esm/commands.d.ts.map +1 -0
- package/esm/commands.js +4 -0
- package/esm/config/types.d.ts +35 -0
- package/esm/config/types.d.ts.map +1 -0
- package/esm/config/types.js +1 -0
- package/esm/config/vis.d.ts +25 -0
- package/esm/config/vis.d.ts.map +1 -0
- package/esm/config/vis.js +27 -0
- package/esm/config.d.ts +4 -0
- package/esm/config.d.ts.map +1 -0
- package/esm/config.js +2 -0
- package/esm/index.d.ts +2 -0
- package/esm/index.d.ts.map +1 -0
- package/esm/index.js +2 -0
- package/esm/presets/auto.d.ts +2 -0
- package/esm/presets/auto.d.ts.map +1 -0
- package/esm/presets/auto.js +3 -0
- package/esm/presets/manual.d.ts +2 -0
- package/esm/presets/manual.d.ts.map +1 -0
- package/esm/presets/manual.js +3 -0
- package/esm/server/browser_provider/browser_api.d.ts +3 -0
- package/esm/server/browser_provider/browser_api.d.ts.map +1 -0
- package/esm/server/browser_provider/browser_api.js +11 -0
- package/esm/server/browser_provider/playwright.d.ts +4 -0
- package/esm/server/browser_provider/playwright.d.ts.map +1 -0
- package/esm/server/browser_provider/playwright.js +13 -0
- package/esm/server/browser_provider/types.d.ts +6 -0
- package/esm/server/browser_provider/types.d.ts.map +1 -0
- package/esm/server/browser_provider/types.js +1 -0
- package/esm/server/browser_provider/webdriverio.d.ts +4 -0
- package/esm/server/browser_provider/webdriverio.d.ts.map +1 -0
- package/esm/server/browser_provider/webdriverio.js +10 -0
- package/esm/server/commands/extend.d.ts +15 -0
- package/esm/server/commands/extend.d.ts.map +1 -0
- package/esm/server/commands/extend.js +10 -0
- package/esm/server/commands/has_image_snapshot.d.ts +6 -0
- package/esm/server/commands/has_image_snapshot.d.ts.map +1 -0
- package/esm/server/commands/has_image_snapshot.js +7 -0
- package/esm/server/commands/image_snapshot_next_index.d.ts +9 -0
- package/esm/server/commands/image_snapshot_next_index.d.ts.map +1 -0
- package/esm/server/commands/image_snapshot_next_index.js +7 -0
- package/esm/server/commands/is_ci.d.ts +2 -0
- package/esm/server/commands/is_ci.d.ts.map +1 -0
- package/esm/server/commands/is_ci.js +6 -0
- package/esm/server/commands/match_image_snapshot.d.ts +17 -0
- package/esm/server/commands/match_image_snapshot.d.ts.map +1 -0
- package/esm/server/commands/match_image_snapshot.js +88 -0
- package/esm/server/commands/setup_vis_suite.d.ts +13 -0
- package/esm/server/commands/setup_vis_suite.d.ts.map +1 -0
- package/esm/server/commands/setup_vis_suite.js +4 -0
- package/esm/server/compare_image.d.ts +8 -0
- package/esm/server/compare_image.d.ts.map +1 -0
- package/esm/server/compare_image.js +16 -0
- package/esm/server/file.d.ts +6 -0
- package/esm/server/file.d.ts.map +1 -0
- package/esm/server/file.js +14 -0
- package/esm/server/snapshot_path.d.ts +4 -0
- package/esm/server/snapshot_path.d.ts.map +1 -0
- package/esm/server/snapshot_path.js +9 -0
- package/esm/server/vis_context.ctx.d.ts +29 -0
- package/esm/server/vis_context.ctx.d.ts.map +1 -0
- package/esm/server/vis_context.ctx.js +11 -0
- package/esm/server/vis_context.d.ts +33 -0
- package/esm/server/vis_context.d.ts.map +1 -0
- package/esm/server/vis_context.js +2 -0
- package/esm/server/vis_context.logic.d.ts +63 -0
- package/esm/server/vis_context.logic.d.ts.map +1 -0
- package/esm/server/vis_context.logic.js +116 -0
- package/esm/server/vis_context.types.d.ts +20 -0
- package/esm/server/vis_context.types.d.ts.map +1 -0
- package/esm/server/vis_context.types.js +1 -0
- package/esm/setup/create_vis.d.ts +39 -0
- package/esm/setup/create_vis.d.ts.map +1 -0
- package/esm/setup/create_vis.js +96 -0
- package/esm/setup/vis.d.ts +18 -0
- package/esm/setup/vis.d.ts.map +1 -0
- package/esm/setup/vis.js +6 -0
- package/esm/setup.d.ts +5 -0
- package/esm/setup.d.ts.map +1 -0
- package/esm/setup.js +7 -0
- package/esm/shared/base64.d.ts +2 -0
- package/esm/shared/base64.d.ts.map +1 -0
- package/esm/shared/base64.js +3 -0
- package/esm/shared/constants.d.ts +5 -0
- package/esm/shared/constants.d.ts.map +1 -0
- package/esm/shared/constants.js +4 -0
- package/esm/shared/convert_threshold_unit.d.ts +6 -0
- package/esm/shared/convert_threshold_unit.d.ts.map +1 -0
- package/esm/shared/convert_threshold_unit.js +10 -0
- package/esm/shared/get_max_size.d.ts +11 -0
- package/esm/shared/get_max_size.d.ts.map +1 -0
- package/esm/shared/get_max_size.js +5 -0
- package/esm/shared/is_same_size.d.ts +8 -0
- package/esm/shared/is_same_size.d.ts.map +1 -0
- package/esm/shared/is_same_size.js +3 -0
- package/esm/shared/trim_common_folder.d.ts +6 -0
- package/esm/shared/trim_common_folder.d.ts.map +1 -0
- package/esm/shared/trim_common_folder.js +10 -0
- package/esm/shared/types.d.ts +37 -0
- package/esm/shared/types.d.ts.map +1 -0
- package/esm/shared/types.js +1 -0
- package/esm/testing/constants.d.ts +9 -0
- package/esm/testing/constants.d.ts.map +1 -0
- package/esm/testing/constants.js +1933 -0
- package/esm/testing.d.ts +2 -0
- package/esm/testing.d.ts.map +1 -0
- package/esm/testing.js +1 -0
- package/package.json +115 -0
- package/readme.md +264 -0
- package/src/client/ctx.ts +8 -0
- package/src/client/expect/expectation_result.ts +7 -0
- package/src/client/expect/extend.ts +12 -0
- package/src/client/expect/to_match_image_snapshot.logic.ts +11 -0
- package/src/client/expect/to_match_image_snapshot.ts +43 -0
- package/src/client/expect/to_match_image_snapshot.types.ts +14 -0
- package/src/client/page/extend.ts +8 -0
- package/src/client/page/has_image_snapshot.ts +33 -0
- package/src/client/selector.ts +118 -0
- package/src/client/should_take_snapshot.ts +15 -0
- package/src/client/snapshot_options.internal.ts +22 -0
- package/src/client/snapshot_options.ts +53 -0
- package/src/client/task_id.ts +16 -0
- package/src/client.ts +7 -0
- package/src/commands.ts +4 -0
- package/src/config/readme.md +4 -0
- package/src/config/types.ts +35 -0
- package/src/config/vis.ts +30 -0
- package/src/config.ts +3 -0
- package/src/index.ts +2 -0
- package/src/presets/auto.ts +4 -0
- package/src/presets/manual.ts +4 -0
- package/src/server/browser_provider/browser_api.ts +13 -0
- package/src/server/browser_provider/playwright.ts +16 -0
- package/src/server/browser_provider/types.ts +11 -0
- package/src/server/browser_provider/webdriverio.ts +13 -0
- package/src/server/commands/extend.ts +19 -0
- package/src/server/commands/has_image_snapshot.ts +18 -0
- package/src/server/commands/image_snapshot_next_index.ts +17 -0
- package/src/server/commands/is_ci.ts +7 -0
- package/src/server/commands/match_image_snapshot.ts +139 -0
- package/src/server/commands/setup_vis_suite.ts +17 -0
- package/src/server/compare_image.ts +34 -0
- package/src/server/file.ts +15 -0
- package/src/server/readme.md +5 -0
- package/src/server/snapshot_path.ts +12 -0
- package/src/server/vis_context.ctx.ts +12 -0
- package/src/server/vis_context.logic.ts +141 -0
- package/src/server/vis_context.ts +3 -0
- package/src/server/vis_context.types.ts +25 -0
- package/src/setup/create_vis.ts +98 -0
- package/src/setup/vis.ts +7 -0
- package/src/setup.ts +9 -0
- package/src/shared/base64.ts +3 -0
- package/src/shared/constants.ts +4 -0
- package/src/shared/convert_threshold_unit.ts +13 -0
- package/src/shared/get_max_size.ts +5 -0
- package/src/shared/is_same_size.ts +3 -0
- package/src/shared/trim_common_folder.ts +10 -0
- package/src/shared/types.ts +39 -0
- package/src/testing/constants.ts +1936 -0
- package/src/testing.ts +1 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manual.d.ts","sourceRoot":"","sources":["../../src/presets/manual.ts"],"names":[],"mappings":"AAAA,OAAO,sBAAsB,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"browser_api.d.ts","sourceRoot":"","sources":["../../../src/server/browser_provider/browser_api.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAA;AAIxD,wBAAgB,UAAU,CAAC,OAAO,EAAE,qBAAqB,mCAQxD"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { playwright } from "./playwright.js";
|
|
2
|
+
import { webdriverio } from "./webdriverio.js";
|
|
3
|
+
export function browserApi(context) {
|
|
4
|
+
if (context.provider.name === 'playwright') {
|
|
5
|
+
return playwright(context);
|
|
6
|
+
}
|
|
7
|
+
if (context.provider.name === 'webdriverio') {
|
|
8
|
+
return webdriverio(context);
|
|
9
|
+
}
|
|
10
|
+
throw new Error(`Unsupported provider: ${context.provider.name}`);
|
|
11
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"playwright.d.ts","sourceRoot":"","sources":["../../../src/server/browser_provider/playwright.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAA;AACxD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AAE5C,wBAAgB,UAAU,CAAC,OAAO,EAAE,qBAAqB,GAAG,UAAU,CAYrE"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export function playwright(context) {
|
|
2
|
+
return {
|
|
3
|
+
async takeScreenshot(filePath, selector, options) {
|
|
4
|
+
// The `Locator` type from `vitest` has less props than the `Locator` in `playwright`
|
|
5
|
+
const subject = context.iframe.locator(selector ?? 'body');
|
|
6
|
+
const buffer = await subject.screenshot({
|
|
7
|
+
timeout: options?.timeout,
|
|
8
|
+
path: filePath,
|
|
9
|
+
});
|
|
10
|
+
return buffer.toString('base64');
|
|
11
|
+
},
|
|
12
|
+
};
|
|
13
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/server/browser_provider/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,UAAU;IAC1B,cAAc,CACb,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,OAAO,EACJ;QACA,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;KAC3B,GACD,SAAS,GACV,OAAO,CAAC,MAAM,CAAC,CAAA;CAClB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"webdriverio.d.ts","sourceRoot":"","sources":["../../../src/server/browser_provider/webdriverio.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAA;AACxD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AAE5C,wBAAgB,WAAW,CAAC,OAAO,EAAE,qBAAqB,GAAG,UAAU,CAStE"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export function webdriverio(context) {
|
|
2
|
+
const page = context.provider.browser;
|
|
3
|
+
return {
|
|
4
|
+
async takeScreenshot(filePath, selector) {
|
|
5
|
+
const element = await page.$(`${selector ?? 'body'}`);
|
|
6
|
+
const buffer = await element.saveScreenshot(filePath);
|
|
7
|
+
return buffer.toString('base64');
|
|
8
|
+
},
|
|
9
|
+
};
|
|
10
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { type HasImageSnapshotCommand } from './has_image_snapshot.ts';
|
|
2
|
+
import { type ImageSnapshotNextIndexCommand } from './image_snapshot_next_index.ts';
|
|
3
|
+
import { type MatchImageSnapshotCommand } from './match_image_snapshot.ts';
|
|
4
|
+
import { type SetupVisSuiteCommand } from './setup_vis_suite.ts';
|
|
5
|
+
declare module '@vitest/browser/context' {
|
|
6
|
+
interface BrowserCommands extends SetupVisSuiteCommand, ImageSnapshotNextIndexCommand, HasImageSnapshotCommand, MatchImageSnapshotCommand {
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
export declare const commands: {
|
|
10
|
+
setupVisSuite: import("vitest/node").BrowserCommand<[]>;
|
|
11
|
+
imageSnapshotNextIndex: import("vitest/node").BrowserCommand<[taskId: string]>;
|
|
12
|
+
hasImageSnapshot: import("vitest/node").BrowserCommand<[taskId: string, snapshotId?: string | undefined]>;
|
|
13
|
+
matchImageSnapshot: import("vitest/node").BrowserCommand<[taskId: string, subject: string, options?: import("./match_image_snapshot.ts").MatchImageSnapshotOptions | undefined]>;
|
|
14
|
+
};
|
|
15
|
+
//# sourceMappingURL=extend.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"extend.d.ts","sourceRoot":"","sources":["../../../src/server/commands/extend.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,uBAAuB,EAAoB,MAAM,yBAAyB,CAAA;AACxF,OAAO,EAAE,KAAK,6BAA6B,EAA0B,MAAM,gCAAgC,CAAA;AAC3G,OAAO,EAAE,KAAK,yBAAyB,EAAsB,MAAM,2BAA2B,CAAA;AAC9F,OAAO,EAAE,KAAK,oBAAoB,EAAiB,MAAM,sBAAsB,CAAA;AAE/E,OAAO,QAAQ,yBAAyB,CAAC;IACxC,UAAU,eACT,SAAQ,oBAAoB,EAC3B,6BAA6B,EAC7B,uBAAuB,EACvB,yBAAyB;KAAG;CAC9B;AAED,eAAO,MAAM,QAAQ;;;;;CAKpB,CAAA"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { hasImageSnapshot } from "./has_image_snapshot.js";
|
|
2
|
+
import { imageSnapshotNextIndex } from "./image_snapshot_next_index.js";
|
|
3
|
+
import { matchImageSnapshot } from "./match_image_snapshot.js";
|
|
4
|
+
import { setupVisSuite } from "./setup_vis_suite.js";
|
|
5
|
+
export const commands = {
|
|
6
|
+
setupVisSuite,
|
|
7
|
+
imageSnapshotNextIndex,
|
|
8
|
+
hasImageSnapshot,
|
|
9
|
+
matchImageSnapshot,
|
|
10
|
+
};
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { BrowserCommand } from 'vitest/node';
|
|
2
|
+
export interface HasImageSnapshotCommand {
|
|
3
|
+
hasImageSnapshot(taskId: string, snapshotId?: string | undefined): Promise<boolean>;
|
|
4
|
+
}
|
|
5
|
+
export declare const hasImageSnapshot: BrowserCommand<[taskId: string, snapshotId?: string | undefined]>;
|
|
6
|
+
//# sourceMappingURL=has_image_snapshot.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"has_image_snapshot.d.ts","sourceRoot":"","sources":["../../../src/server/commands/has_image_snapshot.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AAGjD,MAAM,WAAW,uBAAuB;IACvC,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAAC,OAAO,CAAC,CAAA;CACnF;AAED,eAAO,MAAM,gBAAgB,EAAE,cAAc,CAAC,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC,CAU9F,CAAA"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { visContext } from "../vis_context.js";
|
|
2
|
+
export const hasImageSnapshot = async (context, taskId, snapshotId) => {
|
|
3
|
+
if (!context.testPath) {
|
|
4
|
+
throw new Error('Cannot take snapshot without testPath');
|
|
5
|
+
}
|
|
6
|
+
return visContext.hasImageSnapshot(context.testPath, taskId, snapshotId);
|
|
7
|
+
};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { BrowserCommand } from 'vitest/node';
|
|
2
|
+
export interface ImageSnapshotNextIndexCommand {
|
|
3
|
+
/**
|
|
4
|
+
* Get the index of the snapshot image to be created.
|
|
5
|
+
*/
|
|
6
|
+
imageSnapshotNextIndex(taskId: string): Promise<number>;
|
|
7
|
+
}
|
|
8
|
+
export declare const imageSnapshotNextIndex: BrowserCommand<[taskId: string]>;
|
|
9
|
+
//# sourceMappingURL=image_snapshot_next_index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"image_snapshot_next_index.d.ts","sourceRoot":"","sources":["../../../src/server/commands/image_snapshot_next_index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AAGjD,MAAM,WAAW,6BAA6B;IAC7C;;OAEG;IACH,sBAAsB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAA;CACvD;AAED,eAAO,MAAM,sBAAsB,EAAE,cAAc,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,CAMnE,CAAA"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { visContext } from "../vis_context.js";
|
|
2
|
+
export const imageSnapshotNextIndex = async (context, taskId) => {
|
|
3
|
+
if (!context.testPath) {
|
|
4
|
+
throw new Error('Cannot take snapshot without testPath');
|
|
5
|
+
}
|
|
6
|
+
return visContext.getTaskCount(context.testPath, taskId);
|
|
7
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"is_ci.d.ts","sourceRoot":"","sources":["../../../src/server/commands/is_ci.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { BrowserCommand } from 'vitest/node';
|
|
2
|
+
import type { ImageSnapshotCompareOptions, ImageSnapshotIdOptions, ImageSnapshotTimeoutOptions } from '../../shared/types.ts';
|
|
3
|
+
export interface MatchImageSnapshotCommand {
|
|
4
|
+
matchImageSnapshot: (taskId: string | undefined, subject: string, options?: MatchImageSnapshotOptions | undefined) => Promise<void>;
|
|
5
|
+
}
|
|
6
|
+
export interface MatchImageSnapshotOptions extends ImageSnapshotTimeoutOptions, ImageSnapshotIdOptions, ImageSnapshotCompareOptions {
|
|
7
|
+
/**
|
|
8
|
+
* The snapshot file id calculated on the client side.
|
|
9
|
+
*/
|
|
10
|
+
snapshotFileId?: string | undefined;
|
|
11
|
+
}
|
|
12
|
+
export declare const matchImageSnapshot: BrowserCommand<[
|
|
13
|
+
taskId: string,
|
|
14
|
+
subject: string,
|
|
15
|
+
options?: MatchImageSnapshotOptions | undefined
|
|
16
|
+
]>;
|
|
17
|
+
//# sourceMappingURL=match_image_snapshot.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"match_image_snapshot.d.ts","sourceRoot":"","sources":["../../../src/server/commands/match_image_snapshot.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,cAAc,EAAyB,MAAM,aAAa,CAAA;AAIxE,OAAO,KAAK,EACX,2BAA2B,EAC3B,sBAAsB,EACtB,2BAA2B,EAC3B,MAAM,uBAAuB,CAAA;AAM9B,MAAM,WAAW,yBAAyB;IACzC,kBAAkB,EAAE,CACnB,MAAM,EAAE,MAAM,GAAG,SAAS,EAC1B,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE,yBAAyB,GAAG,SAAS,KAC3C,OAAO,CAAC,IAAI,CAAC,CAAA;CAClB;AAED,MAAM,WAAW,yBAChB,SAAQ,2BAA2B,EAClC,sBAAsB,EACtB,2BAA2B;IAC5B;;OAEG;IACH,cAAc,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CACnC;AAED,eAAO,MAAM,kBAAkB,EAAE,cAAc,CAC9C;IAAC,MAAM,EAAE,MAAM;IAAE,OAAO,EAAE,MAAM;IAAE,OAAO,CAAC,EAAE,yBAAyB,GAAG,SAAS;CAAC,CA2DlF,CAAA"}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import dedent from 'dedent';
|
|
2
|
+
import ci from 'is-ci';
|
|
3
|
+
import { mkdirp } from 'mkdirp';
|
|
4
|
+
import { dirname, resolve } from 'pathe';
|
|
5
|
+
import { PNG } from 'pngjs';
|
|
6
|
+
import { isBase64String } from "../../shared/base64.js";
|
|
7
|
+
import { getMaxSize } from "../../shared/get_max_size.js";
|
|
8
|
+
import { isSameSize } from "../../shared/is_same_size.js";
|
|
9
|
+
import { browserApi } from "../browser_provider/browser_api.js";
|
|
10
|
+
import { compareImage } from "../compare_image.js";
|
|
11
|
+
import { file } from "../file.js";
|
|
12
|
+
import { visContext } from "../vis_context.js";
|
|
13
|
+
export const matchImageSnapshot = async (context, taskId, subject, options) => {
|
|
14
|
+
if (!context.testPath) {
|
|
15
|
+
throw new Error('Cannot match snapshot without testPath');
|
|
16
|
+
}
|
|
17
|
+
// vitest:browser passes in `null` when not defined
|
|
18
|
+
if (!options)
|
|
19
|
+
options = {};
|
|
20
|
+
options.timeout = options.timeout ?? (ci ? 30000 : 5000);
|
|
21
|
+
const info = visContext.getSnapshotInfo(context.testPath, taskId, options);
|
|
22
|
+
const baselineBase64 = await file.tryReadFileBase64(info.baselinePath);
|
|
23
|
+
if (!baselineBase64) {
|
|
24
|
+
await takeSnapshot(context, subject, info.baselinePath, options);
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
const resultBase64 = await takeSnapshot(context, subject, info.resultPath, options);
|
|
28
|
+
const baselineImage = PNG.sync.read(Buffer.from(baselineBase64, 'base64'));
|
|
29
|
+
const resultImage = PNG.sync.read(Buffer.from(resultBase64, 'base64'));
|
|
30
|
+
const [baselineAlignedImage, resultAlignedImage] = isSameSize(baselineImage, resultImage)
|
|
31
|
+
? [baselineImage, resultImage]
|
|
32
|
+
: alignImageSizes(baselineImage, resultImage);
|
|
33
|
+
const { pass, diffAmount, diffImage } = compareImage(baselineAlignedImage, resultAlignedImage, options);
|
|
34
|
+
if (pass) {
|
|
35
|
+
if (sizeNotChanged(baselineImage, baselineAlignedImage)) {
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
throw new Error(dedent `Snapshot \`${taskId}\` mismatched
|
|
39
|
+
|
|
40
|
+
The image size changed form ${baselineImage.width}x${baselineImage.height} to ${resultImage.width}x${resultImage.height}
|
|
41
|
+
|
|
42
|
+
Expected: ${resolve(context.project.runner.root, info.baselinePath)}
|
|
43
|
+
Actual: ${resolve(context.project.runner.root, info.resultPath)}`);
|
|
44
|
+
}
|
|
45
|
+
const diffBase64 = PNG.sync.write(diffImage).toString('base64');
|
|
46
|
+
await writeSnapshot(diffBase64, info.diffPath);
|
|
47
|
+
throw new Error(dedent `Snapshot \`${taskId}\` mismatched
|
|
48
|
+
|
|
49
|
+
${options?.failureThreshold
|
|
50
|
+
? options?.failureThresholdType === 'percent'
|
|
51
|
+
? `Expected image to match within ${options.failureThreshold}% but was differ by ${diffAmount}%.`
|
|
52
|
+
: `Expected image to match within ${options.failureThreshold} pixels but was differ by ${diffAmount} pixels.`
|
|
53
|
+
: `Expected image to match but was differ by ${options?.failureThresholdType === 'percent' ? `${diffAmount}%` : `${diffAmount} pixels`}.`}
|
|
54
|
+
|
|
55
|
+
Options: ${JSON.stringify(options)}
|
|
56
|
+
|
|
57
|
+
Expected: ${resolve(context.project.runner.root, info.baselinePath)}
|
|
58
|
+
Actual: ${resolve(context.project.runner.root, info.resultPath)}
|
|
59
|
+
Difference: ${resolve(context.project.runner.root, info.diffPath)}`);
|
|
60
|
+
};
|
|
61
|
+
async function takeSnapshot(context, subject, filePath, options) {
|
|
62
|
+
if (isBase64String(subject)) {
|
|
63
|
+
return writeSnapshot(subject, filePath);
|
|
64
|
+
}
|
|
65
|
+
await mkdirp(dirname(filePath));
|
|
66
|
+
const browser = browserApi(context);
|
|
67
|
+
return browser.takeScreenshot(filePath, subject, {
|
|
68
|
+
timeout: options?.timeout,
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
async function writeSnapshot(subject, filePath) {
|
|
72
|
+
await mkdirp(dirname(filePath));
|
|
73
|
+
await file.writeFileBase64(filePath, subject);
|
|
74
|
+
return subject;
|
|
75
|
+
}
|
|
76
|
+
function alignImageSizes(baseline, result) {
|
|
77
|
+
const size = getMaxSize(baseline, result);
|
|
78
|
+
const baselineAligned = new PNG(size);
|
|
79
|
+
const resultAligned = new PNG(size);
|
|
80
|
+
baselineAligned.data.fill(0);
|
|
81
|
+
resultAligned.data.fill(0);
|
|
82
|
+
PNG.bitblt(baseline, baselineAligned, 0, 0, baseline.width, baseline.height);
|
|
83
|
+
PNG.bitblt(result, resultAligned, 0, 0, result.width, result.height);
|
|
84
|
+
return [baselineAligned, resultAligned];
|
|
85
|
+
}
|
|
86
|
+
function sizeNotChanged(baselineImage, baselineAlignedImage) {
|
|
87
|
+
return baselineImage === baselineAlignedImage;
|
|
88
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { BrowserCommand } from 'vitest/node';
|
|
2
|
+
export interface SetupVisSuiteCommand {
|
|
3
|
+
/**
|
|
4
|
+
* Sets up the visual testing suite by cleaning up previous snapshot and diff output directories.
|
|
5
|
+
* When this command is run for the first time,
|
|
6
|
+
* it will remove the results and diffs directory of all suites.
|
|
7
|
+
*
|
|
8
|
+
* In subsequent runs, it will only remove the results and diffs directory of the current suite.
|
|
9
|
+
*/
|
|
10
|
+
setupVisSuite: () => Promise<void>;
|
|
11
|
+
}
|
|
12
|
+
export declare const setupVisSuite: BrowserCommand<[]>;
|
|
13
|
+
//# sourceMappingURL=setup_vis_suite.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"setup_vis_suite.d.ts","sourceRoot":"","sources":["../../../src/server/commands/setup_vis_suite.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AAGjD,MAAM,WAAW,oBAAoB;IACpC;;;;;;OAMG;IACH,aAAa,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;CAClC;AAED,eAAO,MAAM,aAAa,EAAE,cAAc,CAAC,EAAE,CAE5C,CAAA"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { PNG } from 'pngjs';
|
|
2
|
+
import type { ImageSnapshotCompareOptions } from '../shared/types.ts';
|
|
3
|
+
export declare function compareImage(baselineImage: PNG, resultImage: PNG, { failureThreshold, failureThresholdType, diffOptions }?: ImageSnapshotCompareOptions): {
|
|
4
|
+
pass: boolean;
|
|
5
|
+
diffAmount: number;
|
|
6
|
+
diffImage: PNG;
|
|
7
|
+
};
|
|
8
|
+
//# sourceMappingURL=compare_image.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compare_image.d.ts","sourceRoot":"","sources":["../../src/server/compare_image.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,GAAG,EAAE,MAAM,OAAO,CAAA;AAE3B,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,oBAAoB,CAAA;AAErE,wBAAgB,YAAY,CAC3B,aAAa,EAAE,GAAG,EAClB,WAAW,EAAE,GAAG,EAChB,EAAE,gBAAoB,EAAE,oBAA8B,EAAE,WAAW,EAAE,GAAE,2BAAgC;;;;EAyBvG"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import pixelmatch from 'pixelmatch';
|
|
2
|
+
import { PNG } from 'pngjs';
|
|
3
|
+
import { convertThresholdUnit } from "../shared/convert_threshold_unit.js";
|
|
4
|
+
export function compareImage(baselineImage, resultImage, { failureThreshold = 0, failureThresholdType = 'pixel', diffOptions } = {}) {
|
|
5
|
+
const diffImage = new PNG({
|
|
6
|
+
width: baselineImage.width,
|
|
7
|
+
height: baselineImage.height,
|
|
8
|
+
});
|
|
9
|
+
const pixelDiff = pixelmatch(resultImage.data, baselineImage.data, diffImage.data, baselineImage.width, baselineImage.height, diffOptions);
|
|
10
|
+
const diffAmount = convertThresholdUnit({ failureThresholdType, width: baselineImage.width, height: baselineImage.height }, pixelDiff);
|
|
11
|
+
return {
|
|
12
|
+
pass: diffAmount <= failureThreshold,
|
|
13
|
+
diffAmount,
|
|
14
|
+
diffImage,
|
|
15
|
+
};
|
|
16
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file.d.ts","sourceRoot":"","sources":["../../src/server/file.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,IAAI;gCACkB,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC;8BAG5C,MAAM,QAAQ,MAAM;wBAG1B,MAAM;CAK1B,CAAA"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { readFile, stat, writeFile } from 'node:fs/promises';
|
|
2
|
+
export const file = {
|
|
3
|
+
async tryReadFileBase64(filePath) {
|
|
4
|
+
return readFile(filePath, { encoding: 'base64' }).catch(() => undefined);
|
|
5
|
+
},
|
|
6
|
+
writeFileBase64(filePath, data) {
|
|
7
|
+
return writeFile(filePath, data, { encoding: 'base64' });
|
|
8
|
+
},
|
|
9
|
+
existFile(filePath) {
|
|
10
|
+
return stat(filePath)
|
|
11
|
+
.then((s) => s.isFile())
|
|
12
|
+
.catch(() => false);
|
|
13
|
+
},
|
|
14
|
+
};
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { VisOptions } from '../config/types.ts';
|
|
2
|
+
export declare function resolveSnapshotRootDir(options: VisOptions | undefined): string;
|
|
3
|
+
export declare function getSnapshotSubpath(suiteName: string, options: VisOptions): string;
|
|
4
|
+
//# sourceMappingURL=snapshot_path.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"snapshot_path.d.ts","sourceRoot":"","sources":["../../src/server/snapshot_path.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAA;AAIpD,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,UAAU,GAAG,SAAS,UAErE;AAED,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,UAAU,UAGxE"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { SNAPSHOT_ROOT_DIR } from "../shared/constants.js";
|
|
2
|
+
import { trimCommonFolder } from "../shared/trim_common_folder.js";
|
|
3
|
+
export function resolveSnapshotRootDir(options) {
|
|
4
|
+
return options?.snapshotRootDir ?? SNAPSHOT_ROOT_DIR;
|
|
5
|
+
}
|
|
6
|
+
export function getSnapshotSubpath(suiteName, options) {
|
|
7
|
+
const customizeSnapshotSubpath = options.customizeSnapshotSubpath ?? trimCommonFolder;
|
|
8
|
+
return customizeSnapshotSubpath(suiteName);
|
|
9
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
export declare const ctx: {
|
|
2
|
+
rimraf: ((path: string | string[], opt?: import("rimraf").RimrafAsyncOptions) => Promise<boolean>) & {
|
|
3
|
+
rimraf: (path: string | string[], opt?: import("rimraf").RimrafAsyncOptions) => Promise<boolean>;
|
|
4
|
+
sync: (path: string | string[], opt?: import("rimraf").RimrafSyncOptions) => boolean;
|
|
5
|
+
rimrafSync: (path: string | string[], opt?: import("rimraf").RimrafSyncOptions) => boolean;
|
|
6
|
+
manual: ((path: string | string[], opt?: import("rimraf").RimrafAsyncOptions) => Promise<boolean>) & {
|
|
7
|
+
sync: (path: string | string[], opt?: import("rimraf").RimrafSyncOptions) => boolean;
|
|
8
|
+
};
|
|
9
|
+
manualSync: (path: string | string[], opt?: import("rimraf").RimrafSyncOptions) => boolean;
|
|
10
|
+
native: ((path: string | string[], opt?: import("rimraf").RimrafAsyncOptions) => Promise<boolean>) & {
|
|
11
|
+
sync: (path: string | string[], opt?: import("rimraf").RimrafSyncOptions) => boolean;
|
|
12
|
+
};
|
|
13
|
+
nativeSync: (path: string | string[], opt?: import("rimraf").RimrafSyncOptions) => boolean;
|
|
14
|
+
posix: ((path: string | string[], opt?: import("rimraf").RimrafAsyncOptions) => Promise<boolean>) & {
|
|
15
|
+
sync: (path: string | string[], opt?: import("rimraf").RimrafSyncOptions) => boolean;
|
|
16
|
+
};
|
|
17
|
+
posixSync: (path: string | string[], opt?: import("rimraf").RimrafSyncOptions) => boolean;
|
|
18
|
+
windows: ((path: string | string[], opt?: import("rimraf").RimrafAsyncOptions) => Promise<boolean>) & {
|
|
19
|
+
sync: (path: string | string[], opt?: import("rimraf").RimrafSyncOptions) => boolean;
|
|
20
|
+
};
|
|
21
|
+
windowsSync: (path: string | string[], opt?: import("rimraf").RimrafSyncOptions) => boolean;
|
|
22
|
+
moveRemove: ((path: string | string[], opt?: import("rimraf").RimrafAsyncOptions) => Promise<boolean>) & {
|
|
23
|
+
sync: (path: string | string[], opt?: import("rimraf").RimrafSyncOptions) => boolean;
|
|
24
|
+
};
|
|
25
|
+
moveRemoveSync: (path: string | string[], opt?: import("rimraf").RimrafSyncOptions) => boolean;
|
|
26
|
+
};
|
|
27
|
+
getSnapshotPlatform(): NodeJS.Platform | "local";
|
|
28
|
+
};
|
|
29
|
+
//# sourceMappingURL=vis_context.ctx.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vis_context.ctx.d.ts","sourceRoot":"","sources":["../../src/server/vis_context.ctx.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,GAAG;;6CAQ2qD,CAAC;2CAAkF,CAAC;iDAA8E,CAAC;8CAA2E,CAAC;+CAA0F,CAAC;;iDAAqF,CAAC;8CAA2E,CAAC;+CAA0F,CAAC;;iDAAqF,CAAC;6CAA0E,CAAC;+CAA0F,CAAC;;gDAAoF,CAAC;+CAA4E,CAAC;+CAA0F,CAAC;;kDAAsF,CAAC;kDAA+E,CAAC;+CAA0F,CAAC;;qDAAyF,CAAC;;;CAFtlG,CAAA"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
export declare const visContext: {
|
|
2
|
+
setOptions(options?: import("../config.ts").VisOptions): void;
|
|
3
|
+
__test__getOptions(): import("../config.ts").VisOptions;
|
|
4
|
+
__test__reset(): void;
|
|
5
|
+
__test__getState(): import("./vis_context.types.ts").VisState;
|
|
6
|
+
setupSuite(context: import("./vis_context.logic.ts").PartialBrowserCommandContext): Promise<void>;
|
|
7
|
+
getSnapshotInfo(testPath: string, name: string, options?: {
|
|
8
|
+
snapshotFileId?: string | undefined;
|
|
9
|
+
}): {
|
|
10
|
+
baselinePath: string;
|
|
11
|
+
resultPath: string;
|
|
12
|
+
diffPath: string;
|
|
13
|
+
};
|
|
14
|
+
getTaskCount(testPath: string, taskId: string): number;
|
|
15
|
+
hasImageSnapshot(testPath: string, taskId: string, snapshotFileId: string | undefined): Promise<boolean>;
|
|
16
|
+
getSnapshotFilename(info: {
|
|
17
|
+
taskId: string;
|
|
18
|
+
task: {
|
|
19
|
+
count: number;
|
|
20
|
+
};
|
|
21
|
+
}, snapshotFileId: string | undefined): string;
|
|
22
|
+
getSuiteInfo(testPath: string, taskId: string): {
|
|
23
|
+
suiteId: string;
|
|
24
|
+
taskId: string;
|
|
25
|
+
baselineDir: string;
|
|
26
|
+
resultDir: string;
|
|
27
|
+
diffDir: string;
|
|
28
|
+
task: {
|
|
29
|
+
count: number;
|
|
30
|
+
};
|
|
31
|
+
};
|
|
32
|
+
};
|
|
33
|
+
//# sourceMappingURL=vis_context.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vis_context.d.ts","sourceRoot":"","sources":["../../src/server/vis_context.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,UAAU;;;;;;;sBAC4iD,CAAC;;;;;;;;;;;;;;;;;;;;;;;;CADxhD,CAAA"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import type { VisOptions } from '../config/types.ts';
|
|
2
|
+
import type { VisState } from './vis_context.types.ts';
|
|
3
|
+
export type PartialBrowserCommandContext = {
|
|
4
|
+
project: {
|
|
5
|
+
config: {
|
|
6
|
+
root: string;
|
|
7
|
+
snapshotOptions: {
|
|
8
|
+
updateSnapshot: 'all' | 'new' | 'none';
|
|
9
|
+
};
|
|
10
|
+
testTimeout: number;
|
|
11
|
+
hookTimeout: number;
|
|
12
|
+
};
|
|
13
|
+
};
|
|
14
|
+
testPath: string | undefined;
|
|
15
|
+
};
|
|
16
|
+
export declare function createVisContext(): {
|
|
17
|
+
setOptions(options?: VisOptions): void;
|
|
18
|
+
__test__getOptions(): VisOptions;
|
|
19
|
+
__test__reset(): void;
|
|
20
|
+
__test__getState(): VisState;
|
|
21
|
+
/**
|
|
22
|
+
* Setup suite is called on each test file's beforeAll hook.
|
|
23
|
+
* Test files include vitest test files and storybook story files.
|
|
24
|
+
* It needs to make sure there is no race condition between the test files.
|
|
25
|
+
*/
|
|
26
|
+
setupSuite(context: PartialBrowserCommandContext): Promise<void>;
|
|
27
|
+
getSnapshotInfo(testPath: string, name: string, options?: {
|
|
28
|
+
snapshotFileId?: string | undefined;
|
|
29
|
+
}): {
|
|
30
|
+
baselinePath: string;
|
|
31
|
+
resultPath: string;
|
|
32
|
+
diffPath: string;
|
|
33
|
+
};
|
|
34
|
+
getTaskCount(testPath: string, taskId: string): number;
|
|
35
|
+
hasImageSnapshot(testPath: string, taskId: string, snapshotFileId: string | undefined): Promise<boolean>;
|
|
36
|
+
getSnapshotFilename(info: {
|
|
37
|
+
taskId: string;
|
|
38
|
+
task: {
|
|
39
|
+
count: number;
|
|
40
|
+
};
|
|
41
|
+
}, snapshotFileId: string | undefined): string;
|
|
42
|
+
getSuiteInfo(testPath: string, taskId: string): {
|
|
43
|
+
suiteId: string;
|
|
44
|
+
taskId: string;
|
|
45
|
+
baselineDir: string;
|
|
46
|
+
resultDir: string;
|
|
47
|
+
diffDir: string;
|
|
48
|
+
task: {
|
|
49
|
+
count: number;
|
|
50
|
+
};
|
|
51
|
+
};
|
|
52
|
+
};
|
|
53
|
+
export declare function getSuiteId(state: VisState, testPath: string, options: VisOptions): string;
|
|
54
|
+
export declare function createSuite(state: VisState, testPath: string, options: VisOptions): {
|
|
55
|
+
suiteId: string;
|
|
56
|
+
suite: {
|
|
57
|
+
baselineDir: string;
|
|
58
|
+
resultDir: string;
|
|
59
|
+
diffDir: string;
|
|
60
|
+
tasks: {};
|
|
61
|
+
};
|
|
62
|
+
};
|
|
63
|
+
//# sourceMappingURL=vis_context.logic.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vis_context.logic.d.ts","sourceRoot":"","sources":["../../src/server/vis_context.logic.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAA;AAKpD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAA;AAEtD,MAAM,MAAM,4BAA4B,GAAG;IAC1C,OAAO,EAAE;QACR,MAAM,EAAE;YACP,IAAI,EAAE,MAAM,CAAA;YACZ,eAAe,EAAE;gBAChB,cAAc,EAAE,KAAK,GAAG,KAAK,GAAG,MAAM,CAAA;aACtC,CAAA;YACD,WAAW,EAAE,MAAM,CAAA;YACnB,WAAW,EAAE,MAAM,CAAA;SACnB,CAAA;KACD,CAAA;IACD,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAA;CAC5B,CAAA;AAED,wBAAgB,gBAAgB;yBAMV,UAAU;;;;IAY9B;;;;OAIG;wBACuB,4BAA4B;8BAY5B,MAAM,QAAQ,MAAM,YAAY;QAAE,cAAc,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;KAAE;;;;;2BAiB1E,MAAM,UAAU,MAAM;+BAGlB,MAAM,UAAU,MAAM,kBAAkB,MAAM,GAAG,SAAS;8BAI3D;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE;YAAE,KAAK,EAAE,MAAM,CAAA;SAAE,CAAA;KAAE,kBAAkB,MAAM,GAAG,SAAS;2BAMlF,MAAM,UAAU,MAAM;;;;;;;;;;EAe9C;AAuBD,wBAAgB,UAAU,CAAC,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,UAAU,UAEhF;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,UAAU;;;;;;;;EAWjF"}
|