@juangadm/pre-post 0.2.0 → 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.
Files changed (125) hide show
  1. package/README.md +102 -222
  2. package/dist/bin/cli.js +199 -347
  3. package/dist/bin/cli.js.map +1 -1
  4. package/dist/browser.d.ts +42 -11
  5. package/dist/browser.d.ts.map +1 -1
  6. package/dist/browser.js +371 -94
  7. package/dist/browser.js.map +1 -1
  8. package/dist/capture.d.ts +1 -6
  9. package/dist/capture.d.ts.map +1 -1
  10. package/dist/capture.js +12 -35
  11. package/dist/capture.js.map +1 -1
  12. package/dist/commands/compare.d.ts +18 -0
  13. package/dist/commands/compare.d.ts.map +1 -0
  14. package/dist/commands/compare.js +64 -0
  15. package/dist/commands/compare.js.map +1 -0
  16. package/dist/commands/detect.d.ts +20 -0
  17. package/dist/commands/detect.d.ts.map +1 -0
  18. package/dist/commands/detect.js +19 -0
  19. package/dist/commands/detect.js.map +1 -0
  20. package/dist/commands/doctor.d.ts +10 -0
  21. package/dist/commands/doctor.d.ts.map +1 -0
  22. package/dist/commands/doctor.js +38 -0
  23. package/dist/commands/doctor.js.map +1 -0
  24. package/dist/commands/login.d.ts +6 -0
  25. package/dist/commands/login.d.ts.map +1 -0
  26. package/dist/commands/login.js +34 -0
  27. package/dist/commands/login.js.map +1 -0
  28. package/dist/commands/pr.d.ts +28 -0
  29. package/dist/commands/pr.d.ts.map +1 -0
  30. package/dist/commands/pr.js +159 -0
  31. package/dist/commands/pr.js.map +1 -0
  32. package/dist/commands/prune.d.ts +10 -0
  33. package/dist/commands/prune.d.ts.map +1 -0
  34. package/dist/commands/prune.js +13 -0
  35. package/dist/commands/prune.js.map +1 -0
  36. package/dist/config.d.ts +36 -0
  37. package/dist/config.d.ts.map +1 -0
  38. package/dist/config.js +60 -0
  39. package/dist/config.js.map +1 -0
  40. package/dist/diff-pool.d.ts +17 -0
  41. package/dist/diff-pool.d.ts.map +1 -0
  42. package/dist/diff-pool.js +89 -0
  43. package/dist/diff-pool.js.map +1 -0
  44. package/dist/diff-worker.d.ts +29 -0
  45. package/dist/diff-worker.d.ts.map +1 -0
  46. package/dist/diff-worker.js +38 -0
  47. package/dist/diff-worker.js.map +1 -0
  48. package/dist/diff.d.ts +37 -0
  49. package/dist/diff.d.ts.map +1 -0
  50. package/dist/diff.js +171 -0
  51. package/dist/diff.js.map +1 -0
  52. package/dist/doctor.d.ts +38 -0
  53. package/dist/doctor.d.ts.map +1 -0
  54. package/dist/doctor.js +72 -0
  55. package/dist/doctor.js.map +1 -0
  56. package/dist/errors.d.ts +38 -0
  57. package/dist/errors.d.ts.map +1 -0
  58. package/dist/errors.js +59 -0
  59. package/dist/errors.js.map +1 -0
  60. package/dist/filename.d.ts +2 -0
  61. package/dist/filename.d.ts.map +1 -1
  62. package/dist/filename.js +2 -1
  63. package/dist/filename.js.map +1 -1
  64. package/dist/git.d.ts +23 -0
  65. package/dist/git.d.ts.map +1 -0
  66. package/dist/git.js +86 -0
  67. package/dist/git.js.map +1 -0
  68. package/dist/github.d.ts +73 -0
  69. package/dist/github.d.ts.map +1 -0
  70. package/dist/github.js +240 -0
  71. package/dist/github.js.map +1 -0
  72. package/dist/index.d.ts +22 -22
  73. package/dist/index.d.ts.map +1 -1
  74. package/dist/index.js +17 -66
  75. package/dist/index.js.map +1 -1
  76. package/dist/pkg.d.ts +8 -0
  77. package/dist/pkg.d.ts.map +1 -0
  78. package/dist/pkg.js +35 -0
  79. package/dist/pkg.js.map +1 -0
  80. package/dist/report.d.ts +20 -0
  81. package/dist/report.d.ts.map +1 -0
  82. package/dist/report.js +107 -0
  83. package/dist/report.js.map +1 -0
  84. package/dist/routes/imports.d.ts +46 -0
  85. package/dist/routes/imports.d.ts.map +1 -0
  86. package/dist/routes/imports.js +208 -0
  87. package/dist/routes/imports.js.map +1 -0
  88. package/dist/routes/vite.d.ts +15 -0
  89. package/dist/routes/vite.d.ts.map +1 -0
  90. package/dist/routes/vite.js +130 -0
  91. package/dist/routes/vite.js.map +1 -0
  92. package/dist/routes.d.ts +41 -14
  93. package/dist/routes.d.ts.map +1 -1
  94. package/dist/routes.js +271 -141
  95. package/dist/routes.js.map +1 -1
  96. package/dist/run.d.ts +36 -0
  97. package/dist/run.d.ts.map +1 -0
  98. package/dist/run.js +128 -0
  99. package/dist/run.js.map +1 -0
  100. package/dist/sessions.d.ts +50 -0
  101. package/dist/sessions.d.ts.map +1 -0
  102. package/dist/sessions.js +74 -0
  103. package/dist/sessions.js.map +1 -0
  104. package/dist/types.d.ts +118 -41
  105. package/dist/types.d.ts.map +1 -1
  106. package/dist/types.js +1 -0
  107. package/dist/types.js.map +1 -1
  108. package/dist/viewport.d.ts +6 -1
  109. package/dist/viewport.d.ts.map +1 -1
  110. package/dist/viewport.js +13 -7
  111. package/dist/viewport.js.map +1 -1
  112. package/package.json +21 -13
  113. package/skill/SKILL.md +31 -229
  114. package/dist/clipboard.d.ts +0 -9
  115. package/dist/clipboard.d.ts.map +0 -1
  116. package/dist/clipboard.js +0 -26
  117. package/dist/clipboard.js.map +0 -1
  118. package/dist/upload.d.ts +0 -39
  119. package/dist/upload.d.ts.map +0 -1
  120. package/dist/upload.js +0 -149
  121. package/dist/upload.js.map +0 -1
  122. package/skill/scripts/adapters/0x0st.sh +0 -36
  123. package/skill/scripts/adapters/blob.sh +0 -55
  124. package/skill/scripts/adapters/git-native.sh +0 -51
  125. package/skill/scripts/upload-and-copy.sh +0 -230
package/dist/index.d.ts CHANGED
@@ -1,25 +1,25 @@
1
+ /**
2
+ * Public API. Everything else under src/ is internal and may change.
3
+ */
1
4
  export * from './types.js';
2
- export { resolveViewport } from './viewport.js';
3
- export { captureScreenshot, captureBeforeAfter, captureResponsive } from './capture.js';
5
+ export type { Settings } from './config.js';
6
+ export { loadConfig, resolveSettings, CONFIG_DEFAULTS } from './config.js';
7
+ export { NeedsHumanError, HttpStatusError, NavigationError, BrowserNotFoundError, GitHubError } from './errors.js';
8
+ export { captureScreenshot, captureBeforeAfter } from './capture.js';
9
+ export { closeBrowser } from './browser.js';
10
+ export { diffImages } from './diff.js';
11
+ export type { DiffOptions } from './diff.js';
12
+ export { parseViewport, resolveViewport } from './viewport.js';
4
13
  export { generateFilename } from './filename.js';
5
- export { closeBrowser, readScreenshot } from './browser.js';
6
- export { detectRoutes, detectFramework, getChangedFiles } from './routes.js';
7
- import { BeforeAndAfterOptions, CaptureOptions, CaptureResult, BeforeAfterCaptureOptions, BeforeAfterCaptureResult, ViewportSize, FromImagesOptions, FromImagesResult, ImageInput } from './types.js';
8
- export declare class BeforeAndAfter {
9
- private options;
10
- constructor(options?: BeforeAndAfterOptions);
11
- get viewport(): ViewportSize;
12
- capture(options: CaptureOptions): Promise<CaptureResult>;
13
- captureBeforeAfter(options: BeforeAfterCaptureOptions): Promise<BeforeAfterCaptureResult>;
14
- /**
15
- * Create output from existing images (no browser capture needed).
16
- * Outputs GitHub-flavored markdown table.
17
- */
18
- fromImages(options: FromImagesOptions): Promise<FromImagesResult>;
19
- /**
20
- * Generate GitHub-flavored markdown table for before/after images.
21
- */
22
- generateMarkdown(beforeLabel: string, afterLabel: string, beforePath: ImageInput, afterPath: ImageInput): string;
23
- private resolveImageInput;
24
- }
14
+ export { detectRoutes, detectRoutesForRepo, detectFramework, getChangedFiles } from './routes.js';
15
+ export type { RepoRouteDetection, RepoDetectionOptions } from './routes.js';
16
+ export { buildComment, buildSummary, STICKY_MARKER } from './report.js';
17
+ export { runPr } from './commands/pr.js';
18
+ export type { PrCommandOptions } from './commands/pr.js';
19
+ export { runCompare } from './commands/compare.js';
20
+ export type { CompareOptions } from './commands/compare.js';
21
+ export { runLogin } from './commands/login.js';
22
+ export { runPrune } from './commands/prune.js';
23
+ export { runDoctor } from './commands/doctor.js';
24
+ export { runDetect } from './commands/detect.js';
25
25
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AACxF,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACjD,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC5D,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAI7E,OAAO,EACL,qBAAqB,EACrB,cAAc,EACd,aAAa,EACb,yBAAyB,EACzB,wBAAwB,EACxB,YAAY,EACZ,iBAAiB,EACjB,gBAAgB,EAChB,UAAU,EACX,MAAM,YAAY,CAAC;AAKpB,qBAAa,cAAc;IACzB,OAAO,CAAC,OAAO,CAAwB;gBAE3B,OAAO,GAAE,qBAA0B;IAI/C,IAAI,QAAQ,IAAI,YAAY,CAE3B;IAEK,OAAO,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,aAAa,CAAC;IAOxD,kBAAkB,CAAC,OAAO,EAAE,yBAAyB,GAAG,OAAO,CAAC,wBAAwB,CAAC;IAO/F;;;OAGG;IACG,UAAU,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAevE;;OAEG;IACH,gBAAgB,CACd,WAAW,EAAE,MAAM,EACnB,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,UAAU,EACtB,SAAS,EAAE,UAAU,GACpB,MAAM;IAYT,OAAO,CAAC,iBAAiB;CAQ1B"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,cAAc,YAAY,CAAC;AAC3B,YAAY,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,UAAU,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC3E,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,eAAe,EAAE,oBAAoB,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AACnH,OAAO,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AACrE,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AACvC,YAAY,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAC/D,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACjD,OAAO,EAAE,YAAY,EAAE,mBAAmB,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAClG,YAAY,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAC5E,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACxE,OAAO,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AACzC,YAAY,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACzD,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACnD,YAAY,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAC/C,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAC/C,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACjD,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC"}
package/dist/index.js CHANGED
@@ -1,69 +1,20 @@
1
+ /**
2
+ * Public API. Everything else under src/ is internal and may change.
3
+ */
1
4
  export * from './types.js';
2
- export { resolveViewport } from './viewport.js';
3
- export { captureScreenshot, captureBeforeAfter, captureResponsive } from './capture.js';
5
+ export { loadConfig, resolveSettings, CONFIG_DEFAULTS } from './config.js';
6
+ export { NeedsHumanError, HttpStatusError, NavigationError, BrowserNotFoundError, GitHubError } from './errors.js';
7
+ export { captureScreenshot, captureBeforeAfter } from './capture.js';
8
+ export { closeBrowser } from './browser.js';
9
+ export { diffImages } from './diff.js';
10
+ export { parseViewport, resolveViewport } from './viewport.js';
4
11
  export { generateFilename } from './filename.js';
5
- export { closeBrowser, readScreenshot } from './browser.js';
6
- export { detectRoutes, detectFramework, getChangedFiles } from './routes.js';
7
- import fs from 'fs';
8
- import path from 'path';
9
- import { resolveViewport } from './viewport.js';
10
- import { captureScreenshot, captureBeforeAfter } from './capture.js';
11
- export class BeforeAndAfter {
12
- options;
13
- constructor(options = {}) {
14
- this.options = options;
15
- }
16
- get viewport() {
17
- return resolveViewport(this.options.viewport);
18
- }
19
- async capture(options) {
20
- return captureScreenshot({
21
- viewport: this.options.viewport,
22
- ...options,
23
- });
24
- }
25
- async captureBeforeAfter(options) {
26
- return captureBeforeAfter({
27
- viewport: this.options.viewport,
28
- ...options,
29
- });
30
- }
31
- /**
32
- * Create output from existing images (no browser capture needed).
33
- * Outputs GitHub-flavored markdown table.
34
- */
35
- async fromImages(options) {
36
- const beforeImage = this.resolveImageInput(options.before);
37
- const afterImage = this.resolveImageInput(options.after);
38
- const beforeLabel = options.labels?.before || 'Before';
39
- const afterLabel = options.labels?.after || 'After';
40
- const markdown = this.generateMarkdown(beforeLabel, afterLabel, options.before, options.after);
41
- return {
42
- markdown,
43
- beforeImage,
44
- afterImage,
45
- };
46
- }
47
- /**
48
- * Generate GitHub-flavored markdown table for before/after images.
49
- */
50
- generateMarkdown(beforeLabel, afterLabel, beforePath, afterPath) {
51
- // For markdown, we use the path if it's a string, otherwise a placeholder
52
- const beforeSrc = typeof beforePath === 'string' ? beforePath : 'before.png';
53
- const afterSrc = typeof afterPath === 'string' ? afterPath : 'after.png';
54
- return [
55
- `| ${beforeLabel} | ${afterLabel} |`,
56
- `|:------:|:-----:|`,
57
- `| ![${beforeLabel}](${beforeSrc}) | ![${afterLabel}](${afterSrc}) |`,
58
- ].join('\n');
59
- }
60
- resolveImageInput(input) {
61
- if (Buffer.isBuffer(input)) {
62
- return input;
63
- }
64
- // It's a file path
65
- const resolvedPath = path.isAbsolute(input) ? input : path.resolve(process.cwd(), input);
66
- return fs.readFileSync(resolvedPath);
67
- }
68
- }
12
+ export { detectRoutes, detectRoutesForRepo, detectFramework, getChangedFiles } from './routes.js';
13
+ export { buildComment, buildSummary, STICKY_MARKER } from './report.js';
14
+ export { runPr } from './commands/pr.js';
15
+ export { runCompare } from './commands/compare.js';
16
+ export { runLogin } from './commands/login.js';
17
+ export { runPrune } from './commands/prune.js';
18
+ export { runDoctor } from './commands/doctor.js';
19
+ export { runDetect } from './commands/detect.js';
69
20
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,cAAc,YAAY,CAAC;AAE3B,OAAO,EAAE,UAAU,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC3E,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,eAAe,EAAE,oBAAoB,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AACnH,OAAO,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AACrE,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAEvC,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAC/D,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACjD,OAAO,EAAE,YAAY,EAAE,mBAAmB,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAElG,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACxE,OAAO,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAEzC,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAEnD,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAC/C,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAC/C,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACjD,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC"}
package/dist/pkg.d.ts ADDED
@@ -0,0 +1,8 @@
1
+ /**
2
+ * package.json access, shared by route detection and the pr command.
3
+ * Parsed once per file version (keyed by path + mtime), since detection asks
4
+ * the same question about the same root several times per run.
5
+ */
6
+ export declare function readPackage(root: string): Record<string, any> | null;
7
+ export declare function hasDependency(root: string, name: string): boolean;
8
+ //# sourceMappingURL=pkg.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pkg.d.ts","sourceRoot":"","sources":["../src/pkg.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAOH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI,CAkBpE;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAGjE"}
package/dist/pkg.js ADDED
@@ -0,0 +1,35 @@
1
+ /**
2
+ * package.json access, shared by route detection and the pr command.
3
+ * Parsed once per file version (keyed by path + mtime), since detection asks
4
+ * the same question about the same root several times per run.
5
+ */
6
+ import fs from 'fs';
7
+ import path from 'path';
8
+ const cache = new Map();
9
+ export function readPackage(root) {
10
+ const file = path.join(root, 'package.json');
11
+ let mtimeMs;
12
+ try {
13
+ mtimeMs = fs.statSync(file).mtimeMs;
14
+ }
15
+ catch {
16
+ return null;
17
+ }
18
+ const hit = cache.get(file);
19
+ if (hit && hit.mtimeMs === mtimeMs)
20
+ return hit.pkg;
21
+ let pkg = null;
22
+ try {
23
+ pkg = JSON.parse(fs.readFileSync(file, 'utf-8'));
24
+ }
25
+ catch {
26
+ pkg = null;
27
+ }
28
+ cache.set(file, { mtimeMs, pkg });
29
+ return pkg;
30
+ }
31
+ export function hasDependency(root, name) {
32
+ const pkg = readPackage(root);
33
+ return Boolean(pkg?.dependencies?.[name] || pkg?.devDependencies?.[name]);
34
+ }
35
+ //# sourceMappingURL=pkg.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pkg.js","sourceRoot":"","sources":["../src/pkg.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,IAAI,MAAM,MAAM,CAAC;AAExB,MAAM,KAAK,GAAG,IAAI,GAAG,EAAgE,CAAC;AAEtF,MAAM,UAAU,WAAW,CAAC,IAAY;IACtC,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,cAAc,CAAC,CAAC;IAC7C,IAAI,OAAe,CAAC;IACpB,IAAI,CAAC;QACH,OAAO,GAAG,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC;IACtC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;IACD,MAAM,GAAG,GAAG,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAC5B,IAAI,GAAG,IAAI,GAAG,CAAC,OAAO,KAAK,OAAO;QAAE,OAAO,GAAG,CAAC,GAAG,CAAC;IACnD,IAAI,GAAG,GAA+B,IAAI,CAAC;IAC3C,IAAI,CAAC;QACH,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC;IACnD,CAAC;IAAC,MAAM,CAAC;QACP,GAAG,GAAG,IAAI,CAAC;IACb,CAAC;IACD,KAAK,CAAC,GAAG,CAAC,IAAI,EAAE,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC,CAAC;IAClC,OAAO,GAAG,CAAC;AACb,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,IAAY,EAAE,IAAY;IACtD,MAAM,GAAG,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC;IAC9B,OAAO,OAAO,CAAC,GAAG,EAAE,YAAY,EAAE,CAAC,IAAI,CAAC,IAAI,GAAG,EAAE,eAAe,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC;AAC5E,CAAC"}
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Output formatting: the PR comment (for humans) and the terminal summary
3
+ * (for the developer or the agent that invoked the CLI).
4
+ */
5
+ import { PrRunResult } from './types.js';
6
+ export declare const STICKY_MARKER = "<!-- pre-post:visual-changes -->";
7
+ export interface CommentOptions {
8
+ version?: string;
9
+ headSha?: string | null;
10
+ now?: Date;
11
+ }
12
+ /**
13
+ * Markdown body for the sticky PR comment.
14
+ */
15
+ export declare function buildComment(result: PrRunResult, options?: CommentOptions): string;
16
+ /**
17
+ * Compact terminal summary — designed to be the only thing an agent reads.
18
+ */
19
+ export declare function buildSummary(result: PrRunResult): string;
20
+ //# sourceMappingURL=report.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"report.d.ts","sourceRoot":"","sources":["../src/report.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,WAAW,EAAuB,MAAM,YAAY,CAAC;AAG9D,eAAO,MAAM,aAAa,qCAAqC,CAAC;AAuBhE,MAAM,WAAW,cAAc;IAC7B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,GAAG,CAAC,EAAE,IAAI,CAAC;CACZ;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,WAAW,EAAE,OAAO,GAAE,cAAmB,GAAG,MAAM,CAqDtF;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,WAAW,GAAG,MAAM,CAyBxD"}
package/dist/report.js ADDED
@@ -0,0 +1,107 @@
1
+ /**
2
+ * Output formatting: the PR comment (for humans) and the terminal summary
3
+ * (for the developer or the agent that invoked the CLI).
4
+ */
5
+ import { hostOf } from './run.js';
6
+ export const STICKY_MARKER = '<!-- pre-post:visual-changes -->';
7
+ function pct(ratio) {
8
+ if (ratio === undefined)
9
+ return '';
10
+ if (ratio === 0)
11
+ return '0%';
12
+ if (ratio < 0.0001)
13
+ return '<0.01%';
14
+ return `${(ratio * 100).toFixed(ratio < 0.01 ? 2 : 1)}%`;
15
+ }
16
+ function code(s) {
17
+ return `\`${s}\``;
18
+ }
19
+ function viewportLabel(v) {
20
+ return v.charAt(0).toUpperCase() + v.slice(1);
21
+ }
22
+ function groupByRoute(outcomes) {
23
+ const map = new Map();
24
+ for (const o of outcomes)
25
+ map.set(o.route, [...(map.get(o.route) ?? []), o]);
26
+ return map;
27
+ }
28
+ /**
29
+ * Markdown body for the sticky PR comment.
30
+ */
31
+ export function buildComment(result, options = {}) {
32
+ const lines = [STICKY_MARKER, '## Visual changes', ''];
33
+ const routes = groupByRoute(result.outcomes);
34
+ const viewportCount = new Set(result.outcomes.map(o => o.viewport)).size;
35
+ const changed = result.outcomes.filter(o => o.status === 'changed');
36
+ const unchanged = result.outcomes.filter(o => o.status === 'unchanged');
37
+ const errors = result.outcomes.filter(o => o.status === 'error');
38
+ const summary = changed.length === 0
39
+ ? `No visual changes detected across ${routes.size} route${routes.size === 1 ? '' : 's'} and ${viewportCount} viewport${viewportCount === 1 ? '' : 's'}.`
40
+ : `${changed.length} of ${result.outcomes.length} captures changed across ${routes.size} route${routes.size === 1 ? '' : 's'}.`;
41
+ lines.push(`**Pre** = ${hostOf(result.beforeBase)} · **Post** = this branch · ${summary}`, '');
42
+ for (const [route, outcomes] of routes) {
43
+ const changedHere = outcomes.filter(o => o.status === 'changed' && (o.urls || o.files));
44
+ if (changedHere.length === 0)
45
+ continue;
46
+ for (const o of changedHere) {
47
+ const u = o.urls ?? o.files;
48
+ const note = [o.sizeChanged ? 'page height changed' : '', o.note || ''].filter(Boolean).map(n => ` · ${n}`).join('');
49
+ lines.push(`### ${code(route)} — ${viewportLabel(o.viewport)} · ${pct(o.changedRatio)} of pixels changed${note}`, '');
50
+ const pre = u.cropBefore ?? u.before;
51
+ const post = u.cropAfter ?? u.after;
52
+ lines.push('| Pre | Post |', '|:---:|:---:|', `| ![Pre](${pre}) | ![Post](${post}) |`, '');
53
+ lines.push('<details>', `<summary>Full page and diff</summary>`, '');
54
+ const diffCol = u.diff ? ` ![Diff](${u.diff}) |` : '';
55
+ lines.push(`| Pre (full) | Post (full) |${u.diff ? ' Diff |' : ''}`, `|:---:|:---:|${u.diff ? ':---:|' : ''}`, `| ![Pre full](${u.before}) | ![Post full](${u.after}) |${diffCol}`, '');
56
+ lines.push('</details>', '');
57
+ }
58
+ }
59
+ if (unchanged.length) {
60
+ const byRoute = groupByRoute(unchanged);
61
+ const parts = Array.from(byRoute.entries()).map(([route, os]) => `${code(route)} (${os.map(o => o.viewport).join(', ')})`);
62
+ lines.push(`**No visual change:** ${parts.join(' · ')}`, '');
63
+ }
64
+ if (errors.length) {
65
+ lines.push('**Could not capture:**');
66
+ for (const o of errors)
67
+ lines.push(`- ${code(o.route)} ${o.viewport}: ${o.error}`);
68
+ lines.push('');
69
+ }
70
+ if (result.skippedDynamic.length) {
71
+ lines.push(`**Needs a sample URL:** ${result.skippedDynamic.map(code).join(', ')} — add them under ${code('"samples"')} in ${code('.pre-post.json')}.`, '');
72
+ }
73
+ const stamp = (options.now ?? new Date()).toISOString().replace('T', ' ').slice(0, 16) + ' UTC';
74
+ const sha = options.headSha ? ` · ${code(options.headSha.slice(0, 7))}` : '';
75
+ lines.push('---', `<sub>Captured by <a href="https://github.com/juangadm/pre-post">pre-post</a>${options.version ? ` v${options.version}` : ''}${sha} · ${stamp} · ${(result.durationMs / 1000).toFixed(1)}s</sub>`);
76
+ return lines.join('\n');
77
+ }
78
+ /**
79
+ * Compact terminal summary — designed to be the only thing an agent reads.
80
+ */
81
+ export function buildSummary(result) {
82
+ const lines = [];
83
+ const header = [
84
+ result.prNumber ? `PR #${result.prNumber}` : 'no PR',
85
+ `${new Set(result.outcomes.map(o => o.route)).size} route(s)`,
86
+ `${new Set(result.outcomes.map(o => o.viewport)).size} viewport(s)`,
87
+ `${(result.durationMs / 1000).toFixed(1)}s`,
88
+ ];
89
+ lines.push(`pre-post · ${header.join(' · ')}`);
90
+ const rows = result.outcomes.map(o => [
91
+ o.route,
92
+ o.viewport,
93
+ o.status === 'error' ? 'error' : o.status === 'changed' ? `${pct(o.changedRatio)} changed` : 'no change',
94
+ o.status === 'error' ? (o.error ?? '') : [o.sizeChanged ? 'height changed' : '', o.note || ''].filter(Boolean).join(', '),
95
+ ]);
96
+ const widths = [0, 1, 2].map(i => Math.max(...rows.map(r => r[i].length), 0));
97
+ for (const r of rows) {
98
+ lines.push(` ${r[0].padEnd(widths[0])} ${r[1].padEnd(widths[1])} ${r[2].padEnd(widths[2])} ${r[3]}`.trimEnd());
99
+ }
100
+ if (result.skippedDynamic.length) {
101
+ lines.push(` needs sample URL: ${result.skippedDynamic.join(', ')} (add to .pre-post.json "samples")`);
102
+ }
103
+ if (result.commentUrl)
104
+ lines.push(`Comment: ${result.commentUrl}`);
105
+ return lines.join('\n');
106
+ }
107
+ //# sourceMappingURL=report.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"report.js","sourceRoot":"","sources":["../src/report.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,46 @@
1
+ /**
2
+ * Lightweight import graph. Regex-based (no TypeScript compiler), fast enough
3
+ * to scan a few thousand files in well under a second, and good enough to
4
+ * answer "which page files transitively import this changed file?".
5
+ */
6
+ export declare const SOURCE_EXTENSIONS: string[];
7
+ export declare const SKIP_DIRS: Set<string>;
8
+ export declare function toPosix(p: string): string;
9
+ export interface ImportGraph {
10
+ /** Absolute paths of every scanned source file */
11
+ files: Set<string>;
12
+ /** file → files that import it (absolute paths) */
13
+ importers: Map<string, Set<string>>;
14
+ }
15
+ export interface Alias {
16
+ /** Prefix such as "@/" or "~/" */
17
+ prefix: string;
18
+ /** Absolute directories to try, in order */
19
+ targets: string[];
20
+ }
21
+ /**
22
+ * Read path aliases from tsconfig.json / jsconfig.json (one level of `extends`).
23
+ */
24
+ export declare function readAliases(appRoot: string): Alias[];
25
+ export declare function resolveSpecifier(spec: string, fromFile: string, files: Set<string>, aliases: Alias[]): string | null;
26
+ export declare function walkSourceFiles(root: string, maxFiles?: number): string[];
27
+ export declare function extractSpecifiers(source: string): string[];
28
+ /**
29
+ * Build the reverse import graph for every source file under `appRoot`.
30
+ */
31
+ export declare function buildImportGraph(appRoot: string, options?: {
32
+ files?: string[];
33
+ aliases?: Alias[];
34
+ }): ImportGraph;
35
+ export interface AffectedEntry {
36
+ /** The changed file that led here */
37
+ via: string;
38
+ /** Number of import hops from the changed file (0 = the entry itself changed) */
39
+ depth: number;
40
+ }
41
+ /**
42
+ * Walk importers from each changed file until entry files are reached.
43
+ * Returns entry → closest (changed file, depth).
44
+ */
45
+ export declare function findAffectedEntries(graph: ImportGraph, changed: string[], isEntry: (file: string) => boolean, maxDepth?: number): Map<string, AffectedEntry>;
46
+ //# sourceMappingURL=imports.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"imports.d.ts","sourceRoot":"","sources":["../../src/routes/imports.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAKH,eAAO,MAAM,iBAAiB,UAA6G,CAAC;AAG5I,eAAO,MAAM,SAAS,aAGpB,CAAC;AAEH,wBAAgB,OAAO,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAEzC;AAED,MAAM,WAAW,WAAW;IAC1B,kDAAkD;IAClD,KAAK,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IACnB,mDAAmD;IACnD,SAAS,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC;CACrC;AAED,MAAM,WAAW,KAAK;IACpB,kCAAkC;IAClC,MAAM,EAAE,MAAM,CAAC;IACf,4CAA4C;IAC5C,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAqBD;;GAEG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,KAAK,EAAE,CAuCpD;AAcD,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,CAAC,MAAM,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,GAAG,MAAM,GAAG,IAAI,CAiBpH;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,SAAO,GAAG,MAAM,EAAE,CAoBvE;AAED,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAQ1D;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,GAAE;IAAE,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IAAC,OAAO,CAAC,EAAE,KAAK,EAAE,CAAA;CAAO,GAAG,WAAW,CAsBpH;AAED,MAAM,WAAW,aAAa;IAC5B,qCAAqC;IACrC,GAAG,EAAE,MAAM,CAAC;IACZ,iFAAiF;IACjF,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,WAAW,EAClB,OAAO,EAAE,MAAM,EAAE,EACjB,OAAO,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,EAClC,QAAQ,SAAI,GACX,GAAG,CAAC,MAAM,EAAE,aAAa,CAAC,CAyB5B"}
@@ -0,0 +1,208 @@
1
+ /**
2
+ * Lightweight import graph. Regex-based (no TypeScript compiler), fast enough
3
+ * to scan a few thousand files in well under a second, and good enough to
4
+ * answer "which page files transitively import this changed file?".
5
+ */
6
+ import fs from 'fs';
7
+ import path from 'path';
8
+ export const SOURCE_EXTENSIONS = ['.ts', '.tsx', '.js', '.jsx', '.mjs', '.cjs', '.mts', '.cts', '.vue', '.svelte', '.astro', '.mdx', '.md'];
9
+ const RESOLVE_EXTENSIONS = ['.tsx', '.ts', '.jsx', '.js', '.mjs', '.cjs', '.mts', '.cts', '.vue', '.svelte', '.astro', '.mdx', '.md', '.css', '.scss', '.json'];
10
+ export const SKIP_DIRS = new Set([
11
+ '.git', '.next', '.nuxt', '.svelte-kit', '.turbo', '.vercel', '.cache', 'node_modules',
12
+ 'dist', 'build', 'out', 'coverage', 'public', 'storybook-static', '.storybook', '__snapshots__',
13
+ ]);
14
+ export function toPosix(p) {
15
+ return p.split(path.sep).join('/');
16
+ }
17
+ const SPECIFIER_PATTERNS = [
18
+ /(?:^|[^\w$.])(?:import|export)\s+(?:type\s+)?(?:[\w*{}\s,$]+?\s+from\s+)?['"]([^'"\n]+)['"]/g,
19
+ /import\s*\(\s*['"]([^'"\n]+)['"]\s*\)/g,
20
+ /require\s*\(\s*['"]([^'"\n]+)['"]\s*\)/g,
21
+ ];
22
+ /** Very lenient JSON parse for tsconfig/jsconfig (comments + trailing commas). */
23
+ function parseJsonc(text) {
24
+ const stripped = text
25
+ .replace(/\/\*[\s\S]*?\*\//g, '')
26
+ .replace(/(^|[^:\\])\/\/.*$/gm, '$1')
27
+ .replace(/,\s*([}\]])/g, '$1');
28
+ try {
29
+ return JSON.parse(stripped);
30
+ }
31
+ catch {
32
+ return null;
33
+ }
34
+ }
35
+ /**
36
+ * Read path aliases from tsconfig.json / jsconfig.json (one level of `extends`).
37
+ */
38
+ export function readAliases(appRoot) {
39
+ const aliases = [];
40
+ const seen = new Set();
41
+ const visit = (file, depth) => {
42
+ if (depth > 2 || seen.has(file) || !fs.existsSync(file))
43
+ return;
44
+ seen.add(file);
45
+ const cfg = parseJsonc(fs.readFileSync(file, 'utf-8'));
46
+ if (!cfg)
47
+ return;
48
+ const dir = path.dirname(file);
49
+ const baseUrl = cfg.compilerOptions?.baseUrl ? path.resolve(dir, cfg.compilerOptions.baseUrl) : dir;
50
+ const paths = cfg.compilerOptions?.paths || {};
51
+ for (const [pattern, targets] of Object.entries(paths)) {
52
+ const prefix = pattern.replace(/\*$/, '');
53
+ aliases.push({
54
+ prefix,
55
+ targets: (targets || []).map(t => path.resolve(baseUrl, t.replace(/\*$/, ''))),
56
+ });
57
+ }
58
+ if (cfg.compilerOptions?.baseUrl) {
59
+ aliases.push({ prefix: '', targets: [baseUrl] });
60
+ }
61
+ if (typeof cfg.extends === 'string' && cfg.extends.startsWith('.')) {
62
+ visit(path.resolve(dir, cfg.extends.endsWith('.json') ? cfg.extends : `${cfg.extends}.json`), depth + 1);
63
+ }
64
+ };
65
+ visit(path.join(appRoot, 'tsconfig.json'), 0);
66
+ visit(path.join(appRoot, 'jsconfig.json'), 0);
67
+ // Common conventions even without tsconfig paths.
68
+ for (const conv of ['@/', '~/']) {
69
+ if (!aliases.some(a => a.prefix === conv)) {
70
+ const targets = [path.join(appRoot, 'src'), appRoot].filter(d => fs.existsSync(d));
71
+ aliases.push({ prefix: conv, targets });
72
+ }
73
+ }
74
+ // Longest prefix first; the bare baseUrl fallback last.
75
+ return aliases.sort((a, b) => b.prefix.length - a.prefix.length);
76
+ }
77
+ function resolveFile(base, files) {
78
+ if (files.has(base))
79
+ return base;
80
+ for (const ext of RESOLVE_EXTENSIONS) {
81
+ if (files.has(base + ext))
82
+ return base + ext;
83
+ }
84
+ for (const ext of RESOLVE_EXTENSIONS) {
85
+ const idx = path.join(base, `index${ext}`);
86
+ if (files.has(idx))
87
+ return idx;
88
+ }
89
+ return null;
90
+ }
91
+ export function resolveSpecifier(spec, fromFile, files, aliases) {
92
+ const clean = spec.split('?')[0].split('#')[0];
93
+ if (!clean)
94
+ return null;
95
+ if (clean.startsWith('.') || clean.startsWith('/')) {
96
+ const base = clean.startsWith('/') ? clean : path.resolve(path.dirname(fromFile), clean);
97
+ return resolveFile(base, files);
98
+ }
99
+ for (const alias of aliases) {
100
+ if (alias.prefix && !clean.startsWith(alias.prefix))
101
+ continue;
102
+ if (!alias.prefix && (clean.startsWith('@') || !/^[\w-]+[/]/.test(clean) && !/^[\w-]+$/.test(clean)))
103
+ continue;
104
+ const rest = clean.slice(alias.prefix.length);
105
+ for (const target of alias.targets) {
106
+ const found = resolveFile(path.join(target, rest), files);
107
+ if (found)
108
+ return found;
109
+ }
110
+ }
111
+ return null;
112
+ }
113
+ export function walkSourceFiles(root, maxFiles = 8000) {
114
+ const out = [];
115
+ const stack = [root];
116
+ while (stack.length && out.length < maxFiles) {
117
+ const dir = stack.pop();
118
+ let entries;
119
+ try {
120
+ entries = fs.readdirSync(dir, { withFileTypes: true });
121
+ }
122
+ catch {
123
+ continue;
124
+ }
125
+ for (const entry of entries) {
126
+ if (entry.isDirectory()) {
127
+ if (!SKIP_DIRS.has(entry.name) && !entry.name.startsWith('.'))
128
+ stack.push(path.join(dir, entry.name));
129
+ }
130
+ else if (entry.isFile() && SOURCE_EXTENSIONS.includes(path.extname(entry.name))) {
131
+ out.push(path.join(dir, entry.name));
132
+ }
133
+ }
134
+ }
135
+ return out;
136
+ }
137
+ export function extractSpecifiers(source) {
138
+ const specs = [];
139
+ for (const pattern of SPECIFIER_PATTERNS) {
140
+ pattern.lastIndex = 0;
141
+ let m;
142
+ while ((m = pattern.exec(source)))
143
+ specs.push(m[1]);
144
+ }
145
+ return specs;
146
+ }
147
+ /**
148
+ * Build the reverse import graph for every source file under `appRoot`.
149
+ */
150
+ export function buildImportGraph(appRoot, options = {}) {
151
+ const list = options.files ?? walkSourceFiles(appRoot);
152
+ const files = new Set(list);
153
+ const aliases = options.aliases ?? readAliases(appRoot);
154
+ const importers = new Map();
155
+ for (const file of list) {
156
+ let source;
157
+ try {
158
+ source = fs.readFileSync(file, 'utf-8');
159
+ }
160
+ catch {
161
+ continue;
162
+ }
163
+ for (const spec of extractSpecifiers(source)) {
164
+ const target = resolveSpecifier(spec, file, files, aliases);
165
+ if (!target || target === file)
166
+ continue;
167
+ let set = importers.get(target);
168
+ if (!set)
169
+ importers.set(target, (set = new Set()));
170
+ set.add(file);
171
+ }
172
+ }
173
+ return { files, importers };
174
+ }
175
+ /**
176
+ * Walk importers from each changed file until entry files are reached.
177
+ * Returns entry → closest (changed file, depth).
178
+ */
179
+ export function findAffectedEntries(graph, changed, isEntry, maxDepth = 8) {
180
+ const result = new Map();
181
+ const record = (entry, via, depth) => {
182
+ const existing = result.get(entry);
183
+ if (!existing || depth < existing.depth)
184
+ result.set(entry, { via, depth });
185
+ };
186
+ for (const origin of changed) {
187
+ const visited = new Set([origin]);
188
+ let frontier = [origin];
189
+ if (isEntry(origin))
190
+ record(origin, origin, 0);
191
+ for (let depth = 1; depth <= maxDepth && frontier.length; depth++) {
192
+ const next = [];
193
+ for (const file of frontier) {
194
+ for (const importer of graph.importers.get(file) ?? []) {
195
+ if (visited.has(importer))
196
+ continue;
197
+ visited.add(importer);
198
+ if (isEntry(importer))
199
+ record(importer, origin, depth);
200
+ next.push(importer);
201
+ }
202
+ }
203
+ frontier = next;
204
+ }
205
+ }
206
+ return result;
207
+ }
208
+ //# sourceMappingURL=imports.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"imports.js","sourceRoot":"","sources":["../../src/routes/imports.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,IAAI,MAAM,MAAM,CAAC;AAExB,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC;AAC5I,MAAM,kBAAkB,GAAG,CAAC,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;AAEhK,MAAM,CAAC,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC;IAC/B,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,SAAS,EAAE,QAAQ,EAAE,cAAc;IACtF,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,QAAQ,EAAE,kBAAkB,EAAE,YAAY,EAAE,eAAe;CAChG,CAAC,CAAC;AAEH,MAAM,UAAU,OAAO,CAAC,CAAS;IAC/B,OAAO,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AACrC,CAAC;AAgBD,MAAM,kBAAkB,GAAG;IACzB,8FAA8F;IAC9F,wCAAwC;IACxC,yCAAyC;CAC1C,CAAC;AAEF,kFAAkF;AAClF,SAAS,UAAU,CAAC,IAAY;IAC9B,MAAM,QAAQ,GAAG,IAAI;SAClB,OAAO,CAAC,mBAAmB,EAAE,EAAE,CAAC;SAChC,OAAO,CAAC,qBAAqB,EAAE,IAAI,CAAC;SACpC,OAAO,CAAC,cAAc,EAAE,IAAI,CAAC,CAAC;IACjC,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;IAC9B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,WAAW,CAAC,OAAe;IACzC,MAAM,OAAO,GAAY,EAAE,CAAC;IAC5B,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAE/B,MAAM,KAAK,GAAG,CAAC,IAAY,EAAE,KAAa,EAAE,EAAE;QAC5C,IAAI,KAAK,GAAG,CAAC,IAAI,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC;YAAE,OAAO;QAChE,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACf,MAAM,GAAG,GAAG,UAAU,CAAC,EAAE,CAAC,YAAY,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC;QACvD,IAAI,CAAC,GAAG;YAAE,OAAO;QACjB,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QAC/B,MAAM,OAAO,GAAG,GAAG,CAAC,eAAe,EAAE,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;QACpG,MAAM,KAAK,GAA6B,GAAG,CAAC,eAAe,EAAE,KAAK,IAAI,EAAE,CAAC;QACzE,KAAK,MAAM,CAAC,OAAO,EAAE,OAAO,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;YACvD,MAAM,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;YAC1C,OAAO,CAAC,IAAI,CAAC;gBACX,MAAM;gBACN,OAAO,EAAE,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,CAAC;aAC/E,CAAC,CAAC;QACL,CAAC;QACD,IAAI,GAAG,CAAC,eAAe,EAAE,OAAO,EAAE,CAAC;YACjC,OAAO,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,OAAO,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;QACnD,CAAC;QACD,IAAI,OAAO,GAAG,CAAC,OAAO,KAAK,QAAQ,IAAI,GAAG,CAAC,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;YACnE,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,OAAO,OAAO,CAAC,EAAE,KAAK,GAAG,CAAC,CAAC,CAAC;QAC3G,CAAC;IACH,CAAC,CAAC;IAEF,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,eAAe,CAAC,EAAE,CAAC,CAAC,CAAC;IAC9C,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,eAAe,CAAC,EAAE,CAAC,CAAC,CAAC;IAE9C,kDAAkD;IAClD,KAAK,MAAM,IAAI,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,CAAC;QAChC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,IAAI,CAAC,EAAE,CAAC;YAC1C,MAAM,OAAO,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,KAAK,CAAC,EAAE,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;YACnF,OAAO,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC;QAC1C,CAAC;IACH,CAAC;IACD,wDAAwD;IACxD,OAAO,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;AACnE,CAAC;AAED,SAAS,WAAW,CAAC,IAAY,EAAE,KAAkB;IACnD,IAAI,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IACjC,KAAK,MAAM,GAAG,IAAI,kBAAkB,EAAE,CAAC;QACrC,IAAI,KAAK,CAAC,GAAG,CAAC,IAAI,GAAG,GAAG,CAAC;YAAE,OAAO,IAAI,GAAG,GAAG,CAAC;IAC/C,CAAC;IACD,KAAK,MAAM,GAAG,IAAI,kBAAkB,EAAE,CAAC;QACrC,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,QAAQ,GAAG,EAAE,CAAC,CAAC;QAC3C,IAAI,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC;YAAE,OAAO,GAAG,CAAC;IACjC,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,IAAY,EAAE,QAAgB,EAAE,KAAkB,EAAE,OAAgB;IACnG,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IAC/C,IAAI,CAAC,KAAK;QAAE,OAAO,IAAI,CAAC;IACxB,IAAI,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QACnD,MAAM,IAAI,GAAG,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,KAAK,CAAC,CAAC;QACzF,OAAO,WAAW,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IAClC,CAAC;IACD,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC5B,IAAI,KAAK,CAAC,MAAM,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,KAAK,CAAC,MAAM,CAAC;YAAE,SAAS;QAC9D,IAAI,CAAC,KAAK,CAAC,MAAM,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAAE,SAAS;QAC/G,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QAC9C,KAAK,MAAM,MAAM,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC;YACnC,MAAM,KAAK,GAAG,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,EAAE,KAAK,CAAC,CAAC;YAC1D,IAAI,KAAK;gBAAE,OAAO,KAAK,CAAC;QAC1B,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,IAAY,EAAE,QAAQ,GAAG,IAAI;IAC3D,MAAM,GAAG,GAAa,EAAE,CAAC;IACzB,MAAM,KAAK,GAAG,CAAC,IAAI,CAAC,CAAC;IACrB,OAAO,KAAK,CAAC,MAAM,IAAI,GAAG,CAAC,MAAM,GAAG,QAAQ,EAAE,CAAC;QAC7C,MAAM,GAAG,GAAG,KAAK,CAAC,GAAG,EAAG,CAAC;QACzB,IAAI,OAAoB,CAAC;QACzB,IAAI,CAAC;YACH,OAAO,GAAG,EAAE,CAAC,WAAW,CAAC,GAAG,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;QACzD,CAAC;QAAC,MAAM,CAAC;YACP,SAAS;QACX,CAAC;QACD,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;YAC5B,IAAI,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC;gBACxB,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;oBAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC;YACxG,CAAC;iBAAM,IAAI,KAAK,CAAC,MAAM,EAAE,IAAI,iBAAiB,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC;gBAClF,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC;YACvC,CAAC;QACH,CAAC;IACH,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,MAAc;IAC9C,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,KAAK,MAAM,OAAO,IAAI,kBAAkB,EAAE,CAAC;QACzC,OAAO,CAAC,SAAS,GAAG,CAAC,CAAC;QACtB,IAAI,CAAyB,CAAC;QAC9B,OAAO,CAAC,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YAAE,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACtD,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,gBAAgB,CAAC,OAAe,EAAE,UAAmD,EAAE;IACrG,MAAM,IAAI,GAAG,OAAO,CAAC,KAAK,IAAI,eAAe,CAAC,OAAO,CAAC,CAAC;IACvD,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,CAAC;IAC5B,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,IAAI,WAAW,CAAC,OAAO,CAAC,CAAC;IACxD,MAAM,SAAS,GAAG,IAAI,GAAG,EAAuB,CAAC;IAEjD,KAAK,MAAM,IAAI,IAAI,IAAI,EAAE,CAAC;QACxB,IAAI,MAAc,CAAC;QACnB,IAAI,CAAC;YACH,MAAM,GAAG,EAAE,CAAC,YAAY,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QAC1C,CAAC;QAAC,MAAM,CAAC;YACP,SAAS;QACX,CAAC;QACD,KAAK,MAAM,IAAI,IAAI,iBAAiB,CAAC,MAAM,CAAC,EAAE,CAAC;YAC7C,MAAM,MAAM,GAAG,gBAAgB,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC;YAC5D,IAAI,CAAC,MAAM,IAAI,MAAM,KAAK,IAAI;gBAAE,SAAS;YACzC,IAAI,GAAG,GAAG,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;YAChC,IAAI,CAAC,GAAG;gBAAE,SAAS,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC,GAAG,GAAG,IAAI,GAAG,EAAE,CAAC,CAAC,CAAC;YACnD,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAChB,CAAC;IACH,CAAC;IACD,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC;AAC9B,CAAC;AASD;;;GAGG;AACH,MAAM,UAAU,mBAAmB,CACjC,KAAkB,EAClB,OAAiB,EACjB,OAAkC,EAClC,QAAQ,GAAG,CAAC;IAEZ,MAAM,MAAM,GAAG,IAAI,GAAG,EAAyB,CAAC;IAChD,MAAM,MAAM,GAAG,CAAC,KAAa,EAAE,GAAW,EAAE,KAAa,EAAE,EAAE;QAC3D,MAAM,QAAQ,GAAG,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QACnC,IAAI,CAAC,QAAQ,IAAI,KAAK,GAAG,QAAQ,CAAC,KAAK;YAAE,MAAM,CAAC,GAAG,CAAC,KAAK,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC,CAAC;IAC7E,CAAC,CAAC;IAEF,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;QAC7B,MAAM,OAAO,GAAG,IAAI,GAAG,CAAS,CAAC,MAAM,CAAC,CAAC,CAAC;QAC1C,IAAI,QAAQ,GAAG,CAAC,MAAM,CAAC,CAAC;QACxB,IAAI,OAAO,CAAC,MAAM,CAAC;YAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC;QAC/C,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,IAAI,QAAQ,IAAI,QAAQ,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE,CAAC;YAClE,MAAM,IAAI,GAAa,EAAE,CAAC;YAC1B,KAAK,MAAM,IAAI,IAAI,QAAQ,EAAE,CAAC;gBAC5B,KAAK,MAAM,QAAQ,IAAI,KAAK,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,CAAC;oBACvD,IAAI,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC;wBAAE,SAAS;oBACpC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;oBACtB,IAAI,OAAO,CAAC,QAAQ,CAAC;wBAAE,MAAM,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC;oBACvD,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;gBACtB,CAAC;YACH,CAAC;YACD,QAAQ,GAAG,IAAI,CAAC;QAClB,CAAC;IACH,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC"}