@jameslnewell/git-diff 0.1.1 → 0.2.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/README.md +73 -23
- package/dist/diff.d.ts +14 -45
- package/dist/diff.js +84 -100
- package/dist/diff.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -16,50 +16,103 @@ npm install @jameslnewell/git-diff
|
|
|
16
16
|
- `base?: string` The base commit or branch to compare from
|
|
17
17
|
- `head?: string` The head commit or branch to compare to
|
|
18
18
|
|
|
19
|
-
### Async
|
|
19
|
+
### Async
|
|
20
20
|
|
|
21
21
|
```typescript
|
|
22
|
-
import
|
|
22
|
+
import * as Diff from '@jameslnewell/git-diff';
|
|
23
23
|
|
|
24
|
-
const diff = await diffAsync({
|
|
24
|
+
const diff = await Diff.diffAsync({
|
|
25
25
|
base: 'main',
|
|
26
26
|
head: 'feature-branch',
|
|
27
27
|
});
|
|
28
28
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
if (match.added || match.modified) {
|
|
29
|
+
if (Diff.added(diff, 'prisma/*') || Diff.modified(diff, 'prisma/*')) {
|
|
32
30
|
// do something
|
|
33
31
|
// e.g. prisma generate && prisma migrate
|
|
34
32
|
}
|
|
35
33
|
```
|
|
36
34
|
|
|
37
|
-
### Sync
|
|
35
|
+
### Sync
|
|
38
36
|
|
|
39
37
|
```typescript
|
|
40
|
-
import
|
|
38
|
+
import * as Diff from '@jameslnewell/git-diff';
|
|
41
39
|
|
|
42
|
-
const diff = diffSync({
|
|
40
|
+
const diff = Diff.diffSync({
|
|
43
41
|
base: 'main',
|
|
44
42
|
head: 'feature-branch',
|
|
45
43
|
});
|
|
46
44
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
if (match.added || match.modified) {
|
|
45
|
+
if (Diff.added(diff, 'prisma/*') || Diff.modified(diff, 'prisma/*')) {
|
|
50
46
|
// do something
|
|
51
|
-
// e.g. prisma generate && prisma migrate
|
|
52
47
|
}
|
|
53
48
|
```
|
|
54
49
|
|
|
50
|
+
### Predicates
|
|
51
|
+
|
|
52
|
+
Each predicate returns `true` when at least one path matches. The optional second argument is a path or glob (or array of either) to scope the check.
|
|
53
|
+
|
|
54
|
+
- `Diff.any(diff, paths?)` — any file at all
|
|
55
|
+
- `Diff.added(diff, paths?)`
|
|
56
|
+
- `Diff.changed(diff, paths?)`
|
|
57
|
+
- `Diff.deleted(diff, paths?)`
|
|
58
|
+
- `Diff.modified(diff, paths?)`
|
|
59
|
+
- `Diff.renamed(diff, paths?)`
|
|
60
|
+
- `Diff.unknown(diff, paths?)`
|
|
61
|
+
|
|
62
|
+
```ts
|
|
63
|
+
if (Diff.added(diff)) {
|
|
64
|
+
/* any added */
|
|
65
|
+
}
|
|
66
|
+
if (Diff.added(diff, 'src/**')) {
|
|
67
|
+
/* any added under src/ */
|
|
68
|
+
}
|
|
69
|
+
if (Diff.any(diff, ['prisma/*', 'src/db/**'])) {
|
|
70
|
+
/* anything touched */
|
|
71
|
+
}
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### Filters and views
|
|
75
|
+
|
|
76
|
+
- `Diff.filterByPaths(diff, paths)` — returns a new `Diff` containing only entries whose path matches one of the globs (array required).
|
|
77
|
+
- `Diff.filterByStatuses(diff, statuses)` — returns a new `Diff` containing only entries with one of the given statuses (array required).
|
|
78
|
+
- `Diff.paths(diff)` — returns the paths as an array.
|
|
79
|
+
- `Diff.statuses(diff)` — returns the statuses as an array.
|
|
80
|
+
|
|
81
|
+
Compose to build more specific queries:
|
|
82
|
+
|
|
83
|
+
```ts
|
|
84
|
+
import * as Diff from '@jameslnewell/git-diff';
|
|
85
|
+
|
|
86
|
+
// All added file paths under src/
|
|
87
|
+
const newSourceFiles = Diff.paths(
|
|
88
|
+
Diff.filterByPaths(Diff.filterByStatuses(diff, [Diff.Status.Added]), [
|
|
89
|
+
'src/**',
|
|
90
|
+
]),
|
|
91
|
+
);
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
### Faking a diff in tests
|
|
95
|
+
|
|
96
|
+
`Diff` is just `Record<Path, Status>`, so a test fixture is a plain object literal:
|
|
97
|
+
|
|
98
|
+
```ts
|
|
99
|
+
import {added, Status, type Diff} from '@jameslnewell/git-diff';
|
|
100
|
+
|
|
101
|
+
const diff: Diff = {
|
|
102
|
+
'src/main.ts': Status.Added,
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
added(diff, 'src/**'); // true
|
|
106
|
+
```
|
|
107
|
+
|
|
55
108
|
### Handling a non-existent `base`
|
|
56
109
|
|
|
57
110
|
A common use case is diffing against a mutable tag on CI/CD.
|
|
58
111
|
|
|
59
112
|
```ts
|
|
60
|
-
import
|
|
113
|
+
import * as Diff from '@jameslnewell/git-diff';
|
|
61
114
|
|
|
62
|
-
const diff = await diffAsync({
|
|
115
|
+
const diff = await Diff.diffAsync({
|
|
63
116
|
base: 'last-deployment',
|
|
64
117
|
head: 'HEAD',
|
|
65
118
|
});
|
|
@@ -70,21 +123,18 @@ On the initial CI/CD run the mutable tag may not yet exist and `git diff` will e
|
|
|
70
123
|
In order to handle this case its recommended you diff against the first commit instead.
|
|
71
124
|
|
|
72
125
|
```ts
|
|
73
|
-
import
|
|
126
|
+
import * as Diff from '@jameslnewell/git-diff';
|
|
74
127
|
|
|
75
128
|
const base = 'last-deployment';
|
|
76
129
|
const head = 'HEAD';
|
|
77
130
|
|
|
78
|
-
let diff: Diff;
|
|
131
|
+
let diff: Diff.Diff;
|
|
79
132
|
try {
|
|
80
|
-
diff = await diffAsync({
|
|
81
|
-
base,
|
|
82
|
-
head,
|
|
83
|
-
});
|
|
133
|
+
diff = await Diff.diffAsync({base, head});
|
|
84
134
|
} catch (error) {
|
|
85
135
|
if (error.code === 'BAD_REVISION') {
|
|
86
|
-
diff = await diffAsync({
|
|
87
|
-
base: await firstCommitAsync({ref: head}),
|
|
136
|
+
diff = await Diff.diffAsync({
|
|
137
|
+
base: await Diff.firstCommitAsync({ref: head}),
|
|
88
138
|
head,
|
|
89
139
|
});
|
|
90
140
|
} else {
|
package/dist/diff.d.ts
CHANGED
|
@@ -8,49 +8,18 @@ export declare const Status: {
|
|
|
8
8
|
Renamed: "R";
|
|
9
9
|
Unknown: "X";
|
|
10
10
|
};
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
export declare function
|
|
23
|
-
/**
|
|
24
|
-
* A git diff result
|
|
25
|
-
*/
|
|
26
|
-
export declare class Diff implements Iterable<[Path, Status]> {
|
|
27
|
-
#private;
|
|
28
|
-
/**
|
|
29
|
-
* Constructs a diff
|
|
30
|
-
*/
|
|
31
|
-
constructor(diff?: Map<Path, Status> | Iterable<readonly [Path, Status]>);
|
|
32
|
-
[Symbol.iterator](): IterableIterator<[Path, Status]>;
|
|
33
|
-
/**
|
|
34
|
-
* Get the number of files in the diff
|
|
35
|
-
*/
|
|
36
|
-
size(): number;
|
|
37
|
-
/**
|
|
38
|
-
* Get the status and path for each entry in the diff
|
|
39
|
-
*/
|
|
40
|
-
entries(): MapIterator<[Path, Status]>;
|
|
41
|
-
/**
|
|
42
|
-
* Get the paths in the diff
|
|
43
|
-
*/
|
|
44
|
-
paths(): MapIterator<Path>;
|
|
45
|
-
/**
|
|
46
|
-
* Get the statuses in the diff
|
|
47
|
-
*/
|
|
48
|
-
statuses(): MapIterator<Status>;
|
|
49
|
-
/**
|
|
50
|
-
* Match the path(s)
|
|
51
|
-
*/
|
|
52
|
-
match(pathOrPaths: Path | Path[]): Match;
|
|
53
|
-
}
|
|
11
|
+
export type Diff = Record<Path, Status>;
|
|
12
|
+
export declare function filterByPaths(diff: Diff, paths: Path[]): Diff;
|
|
13
|
+
export declare function filterByStatuses(diff: Diff, statuses: Status[]): Diff;
|
|
14
|
+
export declare function paths(diff: Diff): Path[];
|
|
15
|
+
export declare function statuses(diff: Diff): Status[];
|
|
16
|
+
export declare function any(diff: Diff, paths?: Path | Path[]): boolean;
|
|
17
|
+
export declare function added(diff: Diff, paths?: Path | Path[]): boolean;
|
|
18
|
+
export declare function changed(diff: Diff, paths?: Path | Path[]): boolean;
|
|
19
|
+
export declare function deleted(diff: Diff, paths?: Path | Path[]): boolean;
|
|
20
|
+
export declare function modified(diff: Diff, paths?: Path | Path[]): boolean;
|
|
21
|
+
export declare function renamed(diff: Diff, paths?: Path | Path[]): boolean;
|
|
22
|
+
export declare function unknown(diff: Diff, paths?: Path | Path[]): boolean;
|
|
54
23
|
export interface DiffOptions {
|
|
55
24
|
cwd?: string | undefined;
|
|
56
25
|
base?: string | undefined;
|
|
@@ -69,11 +38,11 @@ interface FirstCommitOptions {
|
|
|
69
38
|
ref?: string | undefined;
|
|
70
39
|
}
|
|
71
40
|
/**
|
|
72
|
-
* Get
|
|
41
|
+
* Get the SHA of the first commit in the repository
|
|
73
42
|
*/
|
|
74
43
|
export declare function firstCommitAsync(options?: FirstCommitOptions): Promise<string>;
|
|
75
44
|
/**
|
|
76
|
-
* Get
|
|
45
|
+
* Get the SHA of the first commit in the repository
|
|
77
46
|
*/
|
|
78
47
|
export declare function firstCommitSync(options?: FirstCommitOptions): string;
|
|
79
48
|
export {};
|
package/dist/diff.js
CHANGED
|
@@ -5,7 +5,6 @@ import debug from 'debug';
|
|
|
5
5
|
const execAsyncLog = debug('git-diff:execAsync');
|
|
6
6
|
const execSyncLog = debug('git-diff:execSync');
|
|
7
7
|
const execFileAsync = promisify(execFile);
|
|
8
|
-
const errorName = 'GitDiffError';
|
|
9
8
|
const badRevisionErrorCode = 'BAD_REVISION';
|
|
10
9
|
export const Status = {
|
|
11
10
|
Added: 'A',
|
|
@@ -15,11 +14,76 @@ export const Status = {
|
|
|
15
14
|
Renamed: 'R',
|
|
16
15
|
Unknown: 'X',
|
|
17
16
|
};
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
17
|
+
function toArray(value) {
|
|
18
|
+
return Array.isArray(value) ? value : [value];
|
|
19
|
+
}
|
|
20
|
+
function empty(diff) {
|
|
21
|
+
for (const _ in diff)
|
|
22
|
+
return false;
|
|
23
|
+
return true;
|
|
24
|
+
}
|
|
25
|
+
export function filterByPaths(diff, paths) {
|
|
26
|
+
const matcher = glob(paths);
|
|
27
|
+
const out = {};
|
|
28
|
+
for (const [p, status] of Object.entries(diff)) {
|
|
29
|
+
if (matcher(p))
|
|
30
|
+
out[p] = status;
|
|
31
|
+
}
|
|
32
|
+
return out;
|
|
33
|
+
}
|
|
34
|
+
export function filterByStatuses(diff, statuses) {
|
|
35
|
+
const allowed = new Set(statuses);
|
|
36
|
+
const out = {};
|
|
37
|
+
for (const [p, status] of Object.entries(diff)) {
|
|
38
|
+
if (allowed.has(status))
|
|
39
|
+
out[p] = status;
|
|
40
|
+
}
|
|
41
|
+
return out;
|
|
42
|
+
}
|
|
43
|
+
export function paths(diff) {
|
|
44
|
+
return Object.keys(diff);
|
|
45
|
+
}
|
|
46
|
+
export function statuses(diff) {
|
|
47
|
+
return Object.values(diff);
|
|
48
|
+
}
|
|
49
|
+
function containsPathsWithStatus(diff, status, paths) {
|
|
50
|
+
const matcher = paths !== undefined ? glob(toArray(paths)) : null;
|
|
51
|
+
for (const [p, s] of Object.entries(diff)) {
|
|
52
|
+
if (s !== status)
|
|
53
|
+
continue;
|
|
54
|
+
if (matcher && !matcher(p))
|
|
55
|
+
continue;
|
|
56
|
+
return true;
|
|
57
|
+
}
|
|
58
|
+
return false;
|
|
59
|
+
}
|
|
60
|
+
export function any(diff, paths) {
|
|
61
|
+
if (paths === undefined)
|
|
62
|
+
return !empty(diff);
|
|
63
|
+
const matcher = glob(toArray(paths));
|
|
64
|
+
for (const p in diff) {
|
|
65
|
+
if (matcher(p))
|
|
66
|
+
return true;
|
|
67
|
+
}
|
|
68
|
+
return false;
|
|
69
|
+
}
|
|
70
|
+
export function added(diff, paths) {
|
|
71
|
+
return containsPathsWithStatus(diff, Status.Added, paths);
|
|
72
|
+
}
|
|
73
|
+
export function changed(diff, paths) {
|
|
74
|
+
return containsPathsWithStatus(diff, Status.Changed, paths);
|
|
75
|
+
}
|
|
76
|
+
export function deleted(diff, paths) {
|
|
77
|
+
return containsPathsWithStatus(diff, Status.Deleted, paths);
|
|
78
|
+
}
|
|
79
|
+
export function modified(diff, paths) {
|
|
80
|
+
return containsPathsWithStatus(diff, Status.Modified, paths);
|
|
81
|
+
}
|
|
82
|
+
export function renamed(diff, paths) {
|
|
83
|
+
return containsPathsWithStatus(diff, Status.Renamed, paths);
|
|
84
|
+
}
|
|
85
|
+
export function unknown(diff, paths) {
|
|
86
|
+
return containsPathsWithStatus(diff, Status.Unknown, paths);
|
|
23
87
|
}
|
|
24
88
|
async function execAsync(cmd, args, options) {
|
|
25
89
|
execAsyncLog('exec: %s %s %o', cmd, args.join(' '), options);
|
|
@@ -37,107 +101,28 @@ function execSync(cmd, args, options) {
|
|
|
37
101
|
execSyncLog('exec: %s %s %o', cmd, args.join(' '), options);
|
|
38
102
|
return execFileSync(cmd, args, options).toString();
|
|
39
103
|
}
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
* Constructs a diff
|
|
47
|
-
*/
|
|
48
|
-
constructor(diff = new Map()) {
|
|
49
|
-
this.#diff = diff instanceof Map ? diff : new Map(diff);
|
|
50
|
-
}
|
|
51
|
-
[Symbol.iterator]() {
|
|
52
|
-
return this.#diff[Symbol.iterator]();
|
|
53
|
-
}
|
|
54
|
-
/**
|
|
55
|
-
* Get the number of files in the diff
|
|
56
|
-
*/
|
|
57
|
-
size() {
|
|
58
|
-
return this.#diff.size;
|
|
59
|
-
}
|
|
60
|
-
/**
|
|
61
|
-
* Get the status and path for each entry in the diff
|
|
62
|
-
*/
|
|
63
|
-
entries() {
|
|
64
|
-
return this.#diff.entries();
|
|
65
|
-
}
|
|
66
|
-
/**
|
|
67
|
-
* Get the paths in the diff
|
|
68
|
-
*/
|
|
69
|
-
paths() {
|
|
70
|
-
return this.#diff.keys();
|
|
71
|
-
}
|
|
72
|
-
/**
|
|
73
|
-
* Get the statuses in the diff
|
|
74
|
-
*/
|
|
75
|
-
statuses() {
|
|
76
|
-
return this.#diff.values();
|
|
77
|
-
}
|
|
78
|
-
/**
|
|
79
|
-
* Match the path(s)
|
|
80
|
-
*/
|
|
81
|
-
match(pathOrPaths) {
|
|
82
|
-
const diff = this.#diff;
|
|
83
|
-
const matcher = glob(toArray(pathOrPaths));
|
|
84
|
-
return {
|
|
85
|
-
get added() {
|
|
86
|
-
return diff.entries().some(([path, status]) => {
|
|
87
|
-
return status === Status.Added && matcher(path);
|
|
88
|
-
});
|
|
89
|
-
},
|
|
90
|
-
get changed() {
|
|
91
|
-
return diff.entries().some(([path, status]) => {
|
|
92
|
-
return status === Status.Changed && matcher(path);
|
|
93
|
-
});
|
|
94
|
-
},
|
|
95
|
-
get deleted() {
|
|
96
|
-
return diff.entries().some(([path, status]) => {
|
|
97
|
-
return status === Status.Deleted && matcher(path);
|
|
98
|
-
});
|
|
99
|
-
},
|
|
100
|
-
get modified() {
|
|
101
|
-
return diff.entries().some(([path, status]) => {
|
|
102
|
-
return status === Status.Modified && matcher(path);
|
|
103
|
-
});
|
|
104
|
-
},
|
|
105
|
-
get renamed() {
|
|
106
|
-
return diff.entries().some(([path, status]) => {
|
|
107
|
-
return status === Status.Renamed && matcher(path);
|
|
108
|
-
});
|
|
109
|
-
},
|
|
110
|
-
get unknown() {
|
|
111
|
-
return diff.entries().some(([path, status]) => {
|
|
112
|
-
return status === Status.Unknown && matcher(path);
|
|
113
|
-
});
|
|
114
|
-
},
|
|
115
|
-
};
|
|
104
|
+
class GitDiffError extends Error {
|
|
105
|
+
name = 'GitDiffError';
|
|
106
|
+
code;
|
|
107
|
+
constructor(message, code) {
|
|
108
|
+
super(message);
|
|
109
|
+
this.code = code;
|
|
116
110
|
}
|
|
117
111
|
}
|
|
118
|
-
/**
|
|
119
|
-
* Chceks whether the error has a `stderr` property
|
|
120
|
-
*/
|
|
121
112
|
function isErrorWithStderr(error) {
|
|
122
113
|
return error instanceof Error && !!error.stderr;
|
|
123
114
|
}
|
|
124
|
-
/**
|
|
125
|
-
* Throws a git diff error
|
|
126
|
-
*/
|
|
127
115
|
function throwGitDiffError(error) {
|
|
128
116
|
if (isErrorWithStderr(error)) {
|
|
129
117
|
const match = /fatal: bad revision '(.*)'/.exec(error.stderr);
|
|
130
118
|
if (match) {
|
|
131
|
-
|
|
132
|
-
error.name = errorName;
|
|
133
|
-
error.code = badRevisionErrorCode;
|
|
134
|
-
throw error;
|
|
119
|
+
throw new GitDiffError(`The ref does not exist: ${match[1]}`, badRevisionErrorCode);
|
|
135
120
|
}
|
|
136
121
|
}
|
|
137
122
|
}
|
|
138
|
-
/** Parse the stdout of `git diff`
|
|
123
|
+
/** Parse the stdout of `git diff` into a Diff record */
|
|
139
124
|
function parse(stdout) {
|
|
140
|
-
const
|
|
125
|
+
const diff = {};
|
|
141
126
|
for (const line of stdout.split('\n')) {
|
|
142
127
|
if (!line)
|
|
143
128
|
continue;
|
|
@@ -146,13 +131,13 @@ function parse(stdout) {
|
|
|
146
131
|
const status = match[1]?.trim();
|
|
147
132
|
const path = match[2]?.trim();
|
|
148
133
|
if (status && path) {
|
|
149
|
-
|
|
134
|
+
diff[path] = status;
|
|
150
135
|
continue;
|
|
151
136
|
}
|
|
152
137
|
}
|
|
153
138
|
throw new Error(`Invalid line in diff output: ${line}`);
|
|
154
139
|
}
|
|
155
|
-
return
|
|
140
|
+
return diff;
|
|
156
141
|
}
|
|
157
142
|
/**
|
|
158
143
|
* Executes `git diff` to get the diff status of files
|
|
@@ -189,8 +174,7 @@ function diffArgs(options) {
|
|
|
189
174
|
'--name-status',
|
|
190
175
|
...(options.base ? [options.base] : []),
|
|
191
176
|
...(options.head ? [options.head] : []),
|
|
192
|
-
'--', // this is required to avoid
|
|
193
|
-
// ...(options.paths || []),
|
|
177
|
+
'--', // this is required to avoid ambiguous revision errors
|
|
194
178
|
],
|
|
195
179
|
{ encoding: 'utf8', cwd: options.cwd },
|
|
196
180
|
];
|
|
@@ -203,14 +187,14 @@ function firstCommitArgs(options) {
|
|
|
203
187
|
];
|
|
204
188
|
}
|
|
205
189
|
/**
|
|
206
|
-
* Get
|
|
190
|
+
* Get the SHA of the first commit in the repository
|
|
207
191
|
*/
|
|
208
192
|
export async function firstCommitAsync(options = {}) {
|
|
209
193
|
const { stdout } = await execAsync(...firstCommitArgs(options));
|
|
210
194
|
return stdout.trim();
|
|
211
195
|
}
|
|
212
196
|
/**
|
|
213
|
-
* Get
|
|
197
|
+
* Get the SHA of the first commit in the repository
|
|
214
198
|
*/
|
|
215
199
|
export function firstCommitSync(options = {}) {
|
|
216
200
|
const stdout = execSync(...firstCommitArgs(options));
|
package/dist/diff.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"diff.js","sourceRoot":"","sources":["../src/diff.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,SAAS,EAAC,MAAM,WAAW,CAAC;AACpC,OAAO,EAAC,QAAQ,EAAE,YAAY,EAAC,MAAM,oBAAoB,CAAC;AAC1D,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,MAAM,YAAY,GAAG,KAAK,CAAC,oBAAoB,CAAC,CAAC;AACjD,MAAM,WAAW,GAAG,KAAK,CAAC,mBAAmB,CAAC,CAAC;AAE/C,MAAM,aAAa,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAC;AAE1C,MAAM,
|
|
1
|
+
{"version":3,"file":"diff.js","sourceRoot":"","sources":["../src/diff.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,SAAS,EAAC,MAAM,WAAW,CAAC;AACpC,OAAO,EAAC,QAAQ,EAAE,YAAY,EAAC,MAAM,oBAAoB,CAAC;AAC1D,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,MAAM,YAAY,GAAG,KAAK,CAAC,oBAAoB,CAAC,CAAC;AACjD,MAAM,WAAW,GAAG,KAAK,CAAC,mBAAmB,CAAC,CAAC;AAE/C,MAAM,aAAa,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAC;AAE1C,MAAM,oBAAoB,GAAG,cAAc,CAAC;AAI5C,MAAM,CAAC,MAAM,MAAM,GAAG;IACpB,KAAK,EAAE,GAAY;IACnB,OAAO,EAAE,GAAY;IACrB,OAAO,EAAE,GAAY;IACrB,QAAQ,EAAE,GAAY;IACtB,OAAO,EAAE,GAAY;IACrB,OAAO,EAAE,GAAY;CACtB,CAAC;AAIF,SAAS,OAAO,CAAI,KAAc;IAChC,OAAO,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;AAChD,CAAC;AAED,SAAS,KAAK,CAAC,IAAU;IACvB,KAAK,MAAM,CAAC,IAAI,IAAI;QAAE,OAAO,KAAK,CAAC;IACnC,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,IAAU,EAAE,KAAa;IACrD,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC;IAC5B,MAAM,GAAG,GAAS,EAAE,CAAC;IACrB,KAAK,MAAM,CAAC,CAAC,EAAE,MAAM,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;QAC/C,IAAI,OAAO,CAAC,CAAC,CAAC;YAAE,GAAG,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC;IAClC,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,IAAU,EAAE,QAAkB;IAC7D,MAAM,OAAO,GAAG,IAAI,GAAG,CAAS,QAAQ,CAAC,CAAC;IAC1C,MAAM,GAAG,GAAS,EAAE,CAAC;IACrB,KAAK,MAAM,CAAC,CAAC,EAAE,MAAM,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;QAC/C,IAAI,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC;YAAE,GAAG,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC;IAC3C,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,MAAM,UAAU,KAAK,CAAC,IAAU;IAC9B,OAAO,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC3B,CAAC;AAED,MAAM,UAAU,QAAQ,CAAC,IAAU;IACjC,OAAO,MAAM,CAAC,MAAM,CAAC,IAAI,CAAa,CAAC;AACzC,CAAC;AAED,SAAS,uBAAuB,CAC9B,IAAU,EACV,MAAc,EACd,KAAqB;IAErB,MAAM,OAAO,GAAG,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAClE,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;QAC1C,IAAI,CAAC,KAAK,MAAM;YAAE,SAAS;QAC3B,IAAI,OAAO,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC;YAAE,SAAS;QACrC,OAAO,IAAI,CAAC;IACd,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,UAAU,GAAG,CAAC,IAAU,EAAE,KAAqB;IACnD,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC7C,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC;IACrC,KAAK,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC;QACrB,IAAI,OAAO,CAAC,CAAC,CAAC;YAAE,OAAO,IAAI,CAAC;IAC9B,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,UAAU,KAAK,CAAC,IAAU,EAAE,KAAqB;IACrD,OAAO,uBAAuB,CAAC,IAAI,EAAE,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;AAC5D,CAAC;AAED,MAAM,UAAU,OAAO,CAAC,IAAU,EAAE,KAAqB;IACvD,OAAO,uBAAuB,CAAC,IAAI,EAAE,MAAM,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;AAC9D,CAAC;AAED,MAAM,UAAU,OAAO,CAAC,IAAU,EAAE,KAAqB;IACvD,OAAO,uBAAuB,CAAC,IAAI,EAAE,MAAM,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;AAC9D,CAAC;AAED,MAAM,UAAU,QAAQ,CAAC,IAAU,EAAE,KAAqB;IACxD,OAAO,uBAAuB,CAAC,IAAI,EAAE,MAAM,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;AAC/D,CAAC;AAED,MAAM,UAAU,OAAO,CAAC,IAAU,EAAE,KAAqB;IACvD,OAAO,uBAAuB,CAAC,IAAI,EAAE,MAAM,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;AAC9D,CAAC;AAED,MAAM,UAAU,OAAO,CAAC,IAAU,EAAE,KAAqB;IACvD,OAAO,uBAAuB,CAAC,IAAI,EAAE,MAAM,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;AAC9D,CAAC;AAED,KAAK,UAAU,SAAS,CACtB,GAAW,EACX,IAAc,EACd,OAAqD;IAErD,YAAY,CAAC,gBAAgB,EAAE,GAAG,EAAE,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,OAAO,CAAC,CAAC;IAC7D,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,aAAa,CAAC,GAAG,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;QACvD,YAAY,CAAC,iBAAiB,EAAE,MAAM,CAAC,CAAC;QACxC,OAAO,MAAM,CAAC;IAChB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,YAAY,CAAC,gBAAgB,EAAE,KAAK,CAAC,CAAC;QACtC,MAAM,KAAK,CAAC;IACd,CAAC;AACH,CAAC;AAED,SAAS,QAAQ,CACf,GAAW,EACX,IAAc,EACd,OAAqD;IAErD,WAAW,CAAC,gBAAgB,EAAE,GAAG,EAAE,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,OAAO,CAAC,CAAC;IAC5D,OAAO,YAAY,CAAC,GAAG,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC,QAAQ,EAAE,CAAC;AACrD,CAAC;AAED,MAAM,YAAa,SAAQ,KAAK;IACZ,IAAI,GAAG,cAAc,CAAC;IAC/B,IAAI,CAAS;IACtB,YAAY,OAAe,EAAE,IAAY;QACvC,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;IACnB,CAAC;CACF;AAED,SAAS,iBAAiB,CAAC,KAAc;IACvC,OAAO,KAAK,YAAY,KAAK,IAAI,CAAC,CAAE,KAA2B,CAAC,MAAM,CAAC;AACzE,CAAC;AAED,SAAS,iBAAiB,CAAC,KAAc;IACvC,IAAI,iBAAiB,CAAC,KAAK,CAAC,EAAE,CAAC;QAC7B,MAAM,KAAK,GAAG,4BAA4B,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QAC9D,IAAI,KAAK,EAAE,CAAC;YACV,MAAM,IAAI,YAAY,CACpB,2BAA2B,KAAK,CAAC,CAAC,CAAC,EAAE,EACrC,oBAAoB,CACrB,CAAC;QACJ,CAAC;IACH,CAAC;AACH,CAAC;AAED,wDAAwD;AACxD,SAAS,KAAK,CAAC,MAAc;IAC3B,MAAM,IAAI,GAAS,EAAE,CAAC;IAEtB,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;QACtC,IAAI,CAAC,IAAI;YAAE,SAAS;QACpB,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,mBAAmB,CAAC,CAAC;QAC9C,IAAI,KAAK,EAAE,CAAC;YACV,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC;YAChC,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC;YAC9B,IAAI,MAAM,IAAI,IAAI,EAAE,CAAC;gBACnB,IAAI,CAAC,IAAI,CAAC,GAAG,MAAgB,CAAC;gBAC9B,SAAS;YACX,CAAC;QACH,CAAC;QACD,MAAM,IAAI,KAAK,CAAC,gCAAgC,IAAI,EAAE,CAAC,CAAC;IAC1D,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAQD;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,UAAuB,EAAE;IACvD,IAAI,CAAC;QACH,MAAM,EAAC,MAAM,EAAC,GAAG,MAAM,SAAS,CAAC,GAAG,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC;QACvD,OAAO,KAAK,CAAC,MAAM,CAAC,CAAC;IACvB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,iBAAiB,CAAC,KAAK,CAAC,CAAC;QACzB,MAAM,KAAK,CAAC;IACd,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,QAAQ,CAAC,UAAuB,EAAE;IAChD,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,QAAQ,CAAC,GAAG,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC;QAC9C,OAAO,KAAK,CAAC,MAAM,CAAC,CAAC;IACvB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,iBAAiB,CAAC,KAAK,CAAC,CAAC;QACzB,MAAM,KAAK,CAAC;IACd,CAAC;AACH,CAAC;AAED,qCAAqC;AACrC,SAAS,QAAQ,CACf,OAAoB;IAEpB,OAAO;QACL,KAAK;QACL;YACE,MAAM;YACN,eAAe;YACf,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YACvC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YACvC,IAAI,EAAE,sDAAsD;SAC7D;QACD,EAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,CAAC,GAAG,EAAC;KACrC,CAAC;AACJ,CAAC;AAOD,SAAS,eAAe,CACtB,OAA2B;IAE3B,OAAO;QACL,KAAK;QACL,CAAC,UAAU,EAAE,iBAAiB,EAAE,OAAO,CAAC,GAAG,IAAI,MAAM,CAAC;QACtD,EAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,CAAC,GAAG,EAAC;KACrC,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,UAA8B,EAAE;IAEhC,MAAM,EAAC,MAAM,EAAC,GAAG,MAAM,SAAS,CAAC,GAAG,eAAe,CAAC,OAAO,CAAC,CAAC,CAAC;IAC9D,OAAO,MAAM,CAAC,IAAI,EAAE,CAAC;AACvB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,eAAe,CAAC,UAA8B,EAAE;IAC9D,MAAM,MAAM,GAAG,QAAQ,CAAC,GAAG,eAAe,CAAC,OAAO,CAAC,CAAC,CAAC;IACrD,OAAO,MAAM,CAAC,IAAI,EAAE,CAAC;AACvB,CAAC"}
|