mcp-test-timebox 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +192 -0
- package/dist/executor/index.d.ts +8 -0
- package/dist/executor/index.d.ts.map +1 -0
- package/dist/executor/index.js +8 -0
- package/dist/executor/index.js.map +1 -0
- package/dist/executor/process-executor.d.ts +93 -0
- package/dist/executor/process-executor.d.ts.map +1 -0
- package/dist/executor/process-executor.js +161 -0
- package/dist/executor/process-executor.js.map +1 -0
- package/dist/executor/timebox-controller.d.ts +109 -0
- package/dist/executor/timebox-controller.d.ts.map +1 -0
- package/dist/executor/timebox-controller.js +140 -0
- package/dist/executor/timebox-controller.js.map +1 -0
- package/dist/report/index.d.ts +8 -0
- package/dist/report/index.d.ts.map +1 -0
- package/dist/report/index.js +12 -0
- package/dist/report/index.js.map +1 -0
- package/dist/report/log-extractor.d.ts +125 -0
- package/dist/report/log-extractor.d.ts.map +1 -0
- package/dist/report/log-extractor.js +213 -0
- package/dist/report/log-extractor.js.map +1 -0
- package/dist/report/report-generator.d.ts +148 -0
- package/dist/report/report-generator.d.ts.map +1 -0
- package/dist/report/report-generator.js +261 -0
- package/dist/report/report-generator.js.map +1 -0
- package/dist/server.d.ts +27 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +150 -0
- package/dist/server.js.map +1 -0
- package/dist/tools/index.d.ts +7 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +7 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/run-test.d.ts +80 -0
- package/dist/tools/run-test.d.ts.map +1 -0
- package/dist/tools/run-test.js +178 -0
- package/dist/tools/run-test.js.map +1 -0
- package/dist/utils/path-validator.d.ts +52 -0
- package/dist/utils/path-validator.d.ts.map +1 -0
- package/dist/utils/path-validator.js +128 -0
- package/dist/utils/path-validator.js.map +1 -0
- package/dist/validation/command-builder.d.ts +52 -0
- package/dist/validation/command-builder.d.ts.map +1 -0
- package/dist/validation/command-builder.js +143 -0
- package/dist/validation/command-builder.js.map +1 -0
- package/dist/validation/index.d.ts +8 -0
- package/dist/validation/index.d.ts.map +1 -0
- package/dist/validation/index.js +12 -0
- package/dist/validation/index.js.map +1 -0
- package/dist/validation/input-schema.d.ts +85 -0
- package/dist/validation/input-schema.d.ts.map +1 -0
- package/dist/validation/input-schema.js +113 -0
- package/dist/validation/input-schema.js.map +1 -0
- package/package.json +57 -0
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TimeboxController - タイムアウト監視コンポーネント
|
|
3
|
+
*
|
|
4
|
+
* プロセス実行のタイムアウトを管理する。
|
|
5
|
+
* - ハードタイムアウト: 指定時間経過で強制終了
|
|
6
|
+
* - 無出力タイムアウト: 出力がない状態が続くと強制終了
|
|
7
|
+
*
|
|
8
|
+
* Requirements:
|
|
9
|
+
* - 3.2: timeout_ms で指定された時間が経過したらプロセスを強制終了
|
|
10
|
+
* - 3.3: no_output_timeout_ms で指定された時間、出力がなければ強制終了
|
|
11
|
+
*/
|
|
12
|
+
/**
|
|
13
|
+
* TimeboxController - タイムアウト監視の実装
|
|
14
|
+
*
|
|
15
|
+
* 2種類のタイムアウトを管理:
|
|
16
|
+
* 1. ハードタイムアウト: 設定後、指定時間で必ず発火
|
|
17
|
+
* 2. 無出力タイムアウト: 出力があるたびにリセットされる
|
|
18
|
+
*/
|
|
19
|
+
export class TimeboxController {
|
|
20
|
+
/** ハードタイムアウトのタイマーID */
|
|
21
|
+
hardTimeoutId = null;
|
|
22
|
+
/** 無出力タイムアウトのタイマーID */
|
|
23
|
+
noOutputTimeoutId = null;
|
|
24
|
+
/** 無出力タイムアウトの設定値(リセット用) */
|
|
25
|
+
noOutputTimeoutMs = null;
|
|
26
|
+
/** 無出力タイムアウトのコールバック(リセット用) */
|
|
27
|
+
noOutputCallback = null;
|
|
28
|
+
/** タイムアウトが発生したかどうか */
|
|
29
|
+
timedOut = false;
|
|
30
|
+
/** 発生したタイムアウトの種類 */
|
|
31
|
+
timeoutType = null;
|
|
32
|
+
/**
|
|
33
|
+
* ハードタイムアウトを設定する
|
|
34
|
+
*
|
|
35
|
+
* 指定時間経過後、コールバックを呼び出す。
|
|
36
|
+
* 一度設定すると、clear()が呼ばれるまでリセットされない。
|
|
37
|
+
*
|
|
38
|
+
* @param ms - タイムアウト時間(ミリ秒)
|
|
39
|
+
* @param onTimeout - タイムアウト時のコールバック
|
|
40
|
+
*/
|
|
41
|
+
setHardTimeout(ms, onTimeout) {
|
|
42
|
+
// 既存のタイマーをクリア
|
|
43
|
+
if (this.hardTimeoutId !== null) {
|
|
44
|
+
clearTimeout(this.hardTimeoutId);
|
|
45
|
+
}
|
|
46
|
+
// 新しいタイマーを設定
|
|
47
|
+
this.hardTimeoutId = setTimeout(() => {
|
|
48
|
+
this.timedOut = true;
|
|
49
|
+
this.timeoutType = 'hard';
|
|
50
|
+
this.clear();
|
|
51
|
+
onTimeout('hard');
|
|
52
|
+
}, ms);
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* 無出力タイムアウトを設定する
|
|
56
|
+
*
|
|
57
|
+
* 指定時間、stdout/stderrに出力がない場合にコールバックを呼び出す。
|
|
58
|
+
* notifyOutput()が呼ばれるとタイマーがリセットされる。
|
|
59
|
+
*
|
|
60
|
+
* @param ms - タイムアウト時間(ミリ秒)
|
|
61
|
+
* @param onTimeout - タイムアウト時のコールバック
|
|
62
|
+
*/
|
|
63
|
+
setNoOutputTimeout(ms, onTimeout) {
|
|
64
|
+
// 設定値を保存(リセット用)
|
|
65
|
+
this.noOutputTimeoutMs = ms;
|
|
66
|
+
this.noOutputCallback = onTimeout;
|
|
67
|
+
// タイマーを開始
|
|
68
|
+
this.resetNoOutputTimer();
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* 出力があったことを通知する
|
|
72
|
+
*
|
|
73
|
+
* 無出力タイマーをリセットする。
|
|
74
|
+
* ハードタイムアウトには影響しない。
|
|
75
|
+
*/
|
|
76
|
+
notifyOutput() {
|
|
77
|
+
// 無出力タイマーが設定されている場合のみリセット
|
|
78
|
+
if (this.noOutputTimeoutMs !== null && this.noOutputCallback !== null) {
|
|
79
|
+
this.resetNoOutputTimer();
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* すべてのタイマーをクリアする
|
|
84
|
+
*
|
|
85
|
+
* プロセス終了時や、タイムアウト発生時に呼び出す。
|
|
86
|
+
*/
|
|
87
|
+
clear() {
|
|
88
|
+
// ハードタイムアウトをクリア
|
|
89
|
+
if (this.hardTimeoutId !== null) {
|
|
90
|
+
clearTimeout(this.hardTimeoutId);
|
|
91
|
+
this.hardTimeoutId = null;
|
|
92
|
+
}
|
|
93
|
+
// 無出力タイムアウトをクリア
|
|
94
|
+
if (this.noOutputTimeoutId !== null) {
|
|
95
|
+
clearTimeout(this.noOutputTimeoutId);
|
|
96
|
+
this.noOutputTimeoutId = null;
|
|
97
|
+
}
|
|
98
|
+
// 設定値はクリアしない(状態確認用に保持)
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* タイムアウトが発生したかどうかを返す
|
|
102
|
+
*/
|
|
103
|
+
isTimedOut() {
|
|
104
|
+
return this.timedOut;
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* 発生したタイムアウトの種類を返す
|
|
108
|
+
*/
|
|
109
|
+
getTimeoutType() {
|
|
110
|
+
return this.timeoutType;
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* 無出力タイマーをリセットする(内部メソッド)
|
|
114
|
+
*/
|
|
115
|
+
resetNoOutputTimer() {
|
|
116
|
+
// 既存のタイマーをクリア
|
|
117
|
+
if (this.noOutputTimeoutId !== null) {
|
|
118
|
+
clearTimeout(this.noOutputTimeoutId);
|
|
119
|
+
}
|
|
120
|
+
// 新しいタイマーを設定
|
|
121
|
+
if (this.noOutputTimeoutMs !== null && this.noOutputCallback !== null) {
|
|
122
|
+
const callback = this.noOutputCallback;
|
|
123
|
+
this.noOutputTimeoutId = setTimeout(() => {
|
|
124
|
+
this.timedOut = true;
|
|
125
|
+
this.timeoutType = 'no_output';
|
|
126
|
+
this.clear();
|
|
127
|
+
callback('no_output');
|
|
128
|
+
}, this.noOutputTimeoutMs);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* TimeboxControllerのファクトリ関数
|
|
134
|
+
*
|
|
135
|
+
* @returns 新しいTimeboxControllerインスタンス
|
|
136
|
+
*/
|
|
137
|
+
export function createTimeboxController() {
|
|
138
|
+
return new TimeboxController();
|
|
139
|
+
}
|
|
140
|
+
//# sourceMappingURL=timebox-controller.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"timebox-controller.js","sourceRoot":"","sources":["../../src/executor/timebox-controller.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AA8BH;;;;;;GAMG;AACH,MAAM,OAAO,iBAAiB;IAC5B,uBAAuB;IACf,aAAa,GAAyC,IAAI,CAAC;IAEnE,uBAAuB;IACf,iBAAiB,GAAyC,IAAI,CAAC;IAEvE,2BAA2B;IACnB,iBAAiB,GAAkB,IAAI,CAAC;IAEhD,8BAA8B;IACtB,gBAAgB,GAA2B,IAAI,CAAC;IAExD,sBAAsB;IACd,QAAQ,GAAG,KAAK,CAAC;IAEzB,oBAAoB;IACZ,WAAW,GAAuB,IAAI,CAAC;IAE/C;;;;;;;;OAQG;IACH,cAAc,CAAC,EAAU,EAAE,SAA0B;QACnD,cAAc;QACd,IAAI,IAAI,CAAC,aAAa,KAAK,IAAI,EAAE,CAAC;YAChC,YAAY,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;QACnC,CAAC;QAED,aAAa;QACb,IAAI,CAAC,aAAa,GAAG,UAAU,CAAC,GAAG,EAAE;YACnC,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;YACrB,IAAI,CAAC,WAAW,GAAG,MAAM,CAAC;YAC1B,IAAI,CAAC,KAAK,EAAE,CAAC;YACb,SAAS,CAAC,MAAM,CAAC,CAAC;QACpB,CAAC,EAAE,EAAE,CAAC,CAAC;IACT,CAAC;IAED;;;;;;;;OAQG;IACH,kBAAkB,CAAC,EAAU,EAAE,SAA0B;QACvD,gBAAgB;QAChB,IAAI,CAAC,iBAAiB,GAAG,EAAE,CAAC;QAC5B,IAAI,CAAC,gBAAgB,GAAG,SAAS,CAAC;QAElC,UAAU;QACV,IAAI,CAAC,kBAAkB,EAAE,CAAC;IAC5B,CAAC;IAED;;;;;OAKG;IACH,YAAY;QACV,0BAA0B;QAC1B,IAAI,IAAI,CAAC,iBAAiB,KAAK,IAAI,IAAI,IAAI,CAAC,gBAAgB,KAAK,IAAI,EAAE,CAAC;YACtE,IAAI,CAAC,kBAAkB,EAAE,CAAC;QAC5B,CAAC;IACH,CAAC;IAED;;;;OAIG;IACH,KAAK;QACH,gBAAgB;QAChB,IAAI,IAAI,CAAC,aAAa,KAAK,IAAI,EAAE,CAAC;YAChC,YAAY,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;YACjC,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC;QAC5B,CAAC;QAED,gBAAgB;QAChB,IAAI,IAAI,CAAC,iBAAiB,KAAK,IAAI,EAAE,CAAC;YACpC,YAAY,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;YACrC,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC;QAChC,CAAC;QAED,uBAAuB;IACzB,CAAC;IAED;;OAEG;IACH,UAAU;QACR,OAAO,IAAI,CAAC,QAAQ,CAAC;IACvB,CAAC;IAED;;OAEG;IACH,cAAc;QACZ,OAAO,IAAI,CAAC,WAAW,CAAC;IAC1B,CAAC;IAED;;OAEG;IACK,kBAAkB;QACxB,cAAc;QACd,IAAI,IAAI,CAAC,iBAAiB,KAAK,IAAI,EAAE,CAAC;YACpC,YAAY,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;QACvC,CAAC;QAED,aAAa;QACb,IAAI,IAAI,CAAC,iBAAiB,KAAK,IAAI,IAAI,IAAI,CAAC,gBAAgB,KAAK,IAAI,EAAE,CAAC;YACtE,MAAM,QAAQ,GAAG,IAAI,CAAC,gBAAgB,CAAC;YACvC,IAAI,CAAC,iBAAiB,GAAG,UAAU,CAAC,GAAG,EAAE;gBACvC,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;gBACrB,IAAI,CAAC,WAAW,GAAG,WAAW,CAAC;gBAC/B,IAAI,CAAC,KAAK,EAAE,CAAC;gBACb,QAAQ,CAAC,WAAW,CAAC,CAAC;YACxB,CAAC,EAAE,IAAI,CAAC,iBAAiB,CAAC,CAAC;QAC7B,CAAC;IACH,CAAC;CACF;AAED;;;;GAIG;AACH,MAAM,UAAU,uBAAuB;IACrC,OAAO,IAAI,iBAAiB,EAAE,CAAC;AACjC,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Report モジュール
|
|
3
|
+
*
|
|
4
|
+
* ログ抽出とレポート生成に関するコンポーネントをエクスポート
|
|
5
|
+
*/
|
|
6
|
+
export { LogExtractor, createLogExtractor, extractImportantLines, getTailLines, getTailBytes, formatExtractedBlocks, IMPORTANT_PATTERNS, type ExtractedBlock, type ExtractOptions, } from './log-extractor.js';
|
|
7
|
+
export { ReportGenerator, createReportGenerator, type Summary, type GeneratedArtifacts, type IReportGenerator, } from './report-generator.js';
|
|
8
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/report/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAEL,YAAY,EACZ,kBAAkB,EAClB,qBAAqB,EACrB,YAAY,EACZ,YAAY,EACZ,qBAAqB,EACrB,kBAAkB,EAClB,KAAK,cAAc,EACnB,KAAK,cAAc,GACpB,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EAEL,eAAe,EACf,qBAAqB,EACrB,KAAK,OAAO,EACZ,KAAK,kBAAkB,EACvB,KAAK,gBAAgB,GACtB,MAAM,uBAAuB,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Report モジュール
|
|
3
|
+
*
|
|
4
|
+
* ログ抽出とレポート生成に関するコンポーネントをエクスポート
|
|
5
|
+
*/
|
|
6
|
+
export {
|
|
7
|
+
// LogExtractor
|
|
8
|
+
LogExtractor, createLogExtractor, extractImportantLines, getTailLines, getTailBytes, formatExtractedBlocks, IMPORTANT_PATTERNS, } from './log-extractor.js';
|
|
9
|
+
export {
|
|
10
|
+
// ReportGenerator
|
|
11
|
+
ReportGenerator, createReportGenerator, } from './report-generator.js';
|
|
12
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/report/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO;AACL,eAAe;AACf,YAAY,EACZ,kBAAkB,EAClB,qBAAqB,EACrB,YAAY,EACZ,YAAY,EACZ,qBAAqB,EACrB,kBAAkB,GAGnB,MAAM,oBAAoB,CAAC;AAE5B,OAAO;AACL,kBAAkB;AAClB,eAAe,EACf,qBAAqB,GAItB,MAAM,uBAAuB,CAAC"}
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* LogExtractor - ログ抽出ユーティリティ
|
|
3
|
+
*
|
|
4
|
+
* ログから重要な行を抽出し、要約生成を支援する。
|
|
5
|
+
* 正規表現パターンによるマッチングと前後コンテキストの付与を行う。
|
|
6
|
+
*
|
|
7
|
+
* Requirements:
|
|
8
|
+
* - 5.1: raw.log の末尾 max_output_bytes バイトを対象とする
|
|
9
|
+
* - 5.2: 正規表現パターンにマッチする行を抽出する
|
|
10
|
+
* - 5.3: 前後N行のコンテキストを付与する
|
|
11
|
+
*/
|
|
12
|
+
/**
|
|
13
|
+
* 重要行抽出パターン
|
|
14
|
+
*
|
|
15
|
+
* テスト失敗やエラーを示す一般的なパターン
|
|
16
|
+
*/
|
|
17
|
+
export declare const IMPORTANT_PATTERNS: RegExp[];
|
|
18
|
+
/**
|
|
19
|
+
* 抽出された重要行とそのコンテキスト
|
|
20
|
+
*/
|
|
21
|
+
export interface ExtractedBlock {
|
|
22
|
+
/** マッチした行番号(0始まり) */
|
|
23
|
+
lineNumber: number;
|
|
24
|
+
/** マッチした行の内容 */
|
|
25
|
+
matchedLine: string;
|
|
26
|
+
/** マッチしたパターン */
|
|
27
|
+
pattern: string;
|
|
28
|
+
/** 前後コンテキストを含む行の配列 */
|
|
29
|
+
contextLines: string[];
|
|
30
|
+
/** コンテキストの開始行番号(0始まり) */
|
|
31
|
+
contextStartLine: number;
|
|
32
|
+
/** コンテキストの終了行番号(0始まり) */
|
|
33
|
+
contextEndLine: number;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* ログ抽出オプション
|
|
37
|
+
*/
|
|
38
|
+
export interface ExtractOptions {
|
|
39
|
+
/** 対象とする末尾バイト数 */
|
|
40
|
+
maxBytes?: number;
|
|
41
|
+
/** 前後に付与するコンテキスト行数 */
|
|
42
|
+
contextLines?: number;
|
|
43
|
+
/** 使用するパターン(デフォルトはIMPORTANT_PATTERNS) */
|
|
44
|
+
patterns?: RegExp[];
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* ログの末尾から指定バイト数を取得する
|
|
48
|
+
*
|
|
49
|
+
* @param log - 対象のログ文字列
|
|
50
|
+
* @param maxBytes - 取得する最大バイト数
|
|
51
|
+
* @returns 末尾のログ文字列
|
|
52
|
+
*/
|
|
53
|
+
export declare function getTailBytes(log: string, maxBytes: number): string;
|
|
54
|
+
/**
|
|
55
|
+
* ログの末尾N行を取得する
|
|
56
|
+
*
|
|
57
|
+
* @param log - 対象のログ文字列
|
|
58
|
+
* @param lineCount - 取得する行数
|
|
59
|
+
* @returns 末尾の行の配列
|
|
60
|
+
*/
|
|
61
|
+
export declare function getTailLines(log: string, lineCount: number): string[];
|
|
62
|
+
/**
|
|
63
|
+
* 重要行を抽出する
|
|
64
|
+
*
|
|
65
|
+
* 正規表現パターンにマッチする行を抽出し、
|
|
66
|
+
* 前後のコンテキスト行を付与する。
|
|
67
|
+
*
|
|
68
|
+
* @param log - 対象のログ文字列
|
|
69
|
+
* @param options - 抽出オプション
|
|
70
|
+
* @returns 抽出されたブロックの配列
|
|
71
|
+
*/
|
|
72
|
+
export declare function extractImportantLines(log: string, options?: ExtractOptions): ExtractedBlock[];
|
|
73
|
+
/**
|
|
74
|
+
* 抽出結果を文字列に整形する
|
|
75
|
+
*
|
|
76
|
+
* @param blocks - 抽出されたブロックの配列
|
|
77
|
+
* @returns 整形された文字列
|
|
78
|
+
*/
|
|
79
|
+
export declare function formatExtractedBlocks(blocks: ExtractedBlock[]): string;
|
|
80
|
+
/**
|
|
81
|
+
* LogExtractorクラス(オブジェクト指向インターフェース)
|
|
82
|
+
*
|
|
83
|
+
* ログ抽出の設定を保持し、抽出操作を行う
|
|
84
|
+
*/
|
|
85
|
+
export declare class LogExtractor {
|
|
86
|
+
private readonly patterns;
|
|
87
|
+
private readonly contextLines;
|
|
88
|
+
/**
|
|
89
|
+
* @param patterns - 使用するパターン(デフォルトはIMPORTANT_PATTERNS)
|
|
90
|
+
* @param contextLines - 前後に付与するコンテキスト行数
|
|
91
|
+
*/
|
|
92
|
+
constructor(patterns?: RegExp[], contextLines?: number);
|
|
93
|
+
/**
|
|
94
|
+
* 重要行を抽出する
|
|
95
|
+
*
|
|
96
|
+
* @param log - 対象のログ文字列
|
|
97
|
+
* @param maxBytes - 対象とする末尾バイト数(省略時は全体)
|
|
98
|
+
* @returns 抽出されたブロックの配列
|
|
99
|
+
*/
|
|
100
|
+
extractImportantLines(log: string, maxBytes?: number): ExtractedBlock[];
|
|
101
|
+
/**
|
|
102
|
+
* 末尾N行を取得する
|
|
103
|
+
*
|
|
104
|
+
* @param log - 対象のログ文字列
|
|
105
|
+
* @param lineCount - 取得する行数
|
|
106
|
+
* @returns 末尾の行の配列
|
|
107
|
+
*/
|
|
108
|
+
getTailLines(log: string, lineCount: number): string[];
|
|
109
|
+
/**
|
|
110
|
+
* 抽出結果を文字列に整形する
|
|
111
|
+
*
|
|
112
|
+
* @param blocks - 抽出されたブロックの配列
|
|
113
|
+
* @returns 整形された文字列
|
|
114
|
+
*/
|
|
115
|
+
formatBlocks(blocks: ExtractedBlock[]): string;
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* LogExtractorのファクトリ関数
|
|
119
|
+
*
|
|
120
|
+
* @param patterns - 使用するパターン
|
|
121
|
+
* @param contextLines - 前後に付与するコンテキスト行数
|
|
122
|
+
* @returns 新しいLogExtractorインスタンス
|
|
123
|
+
*/
|
|
124
|
+
export declare function createLogExtractor(patterns?: RegExp[], contextLines?: number): LogExtractor;
|
|
125
|
+
//# sourceMappingURL=log-extractor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"log-extractor.d.ts","sourceRoot":"","sources":["../../src/report/log-extractor.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,EAAE,MAAM,EAStC,CAAC;AAEF;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,qBAAqB;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,gBAAgB;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,gBAAgB;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,sBAAsB;IACtB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,yBAAyB;IACzB,gBAAgB,EAAE,MAAM,CAAC;IACzB,yBAAyB;IACzB,cAAc,EAAE,MAAM,CAAC;CACxB;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,kBAAkB;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,sBAAsB;IACtB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,yCAAyC;IACzC,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;CACrB;AAOD;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAqBlE;AAED;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,EAAE,CAcrE;AAED;;;;;;;;;GASG;AACH,wBAAgB,qBAAqB,CACnC,GAAG,EAAE,MAAM,EACX,OAAO,GAAE,cAAmB,GAC3B,cAAc,EAAE,CA2DlB;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,cAAc,EAAE,GAAG,MAAM,CAsBtE;AAED;;;;GAIG;AACH,qBAAa,YAAY;IACvB,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAW;IACpC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAS;IAEtC;;;OAGG;gBAED,QAAQ,GAAE,MAAM,EAAuB,EACvC,YAAY,GAAE,MAA8B;IAM9C;;;;;;OAMG;IACH,qBAAqB,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,cAAc,EAAE;IAQvE;;;;;;OAMG;IACH,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,EAAE;IAItD;;;;;OAKG;IACH,YAAY,CAAC,MAAM,EAAE,cAAc,EAAE,GAAG,MAAM;CAG/C;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAChC,QAAQ,CAAC,EAAE,MAAM,EAAE,EACnB,YAAY,CAAC,EAAE,MAAM,GACpB,YAAY,CAEd"}
|
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* LogExtractor - ログ抽出ユーティリティ
|
|
3
|
+
*
|
|
4
|
+
* ログから重要な行を抽出し、要約生成を支援する。
|
|
5
|
+
* 正規表現パターンによるマッチングと前後コンテキストの付与を行う。
|
|
6
|
+
*
|
|
7
|
+
* Requirements:
|
|
8
|
+
* - 5.1: raw.log の末尾 max_output_bytes バイトを対象とする
|
|
9
|
+
* - 5.2: 正規表現パターンにマッチする行を抽出する
|
|
10
|
+
* - 5.3: 前後N行のコンテキストを付与する
|
|
11
|
+
*/
|
|
12
|
+
/**
|
|
13
|
+
* 重要行抽出パターン
|
|
14
|
+
*
|
|
15
|
+
* テスト失敗やエラーを示す一般的なパターン
|
|
16
|
+
*/
|
|
17
|
+
export const IMPORTANT_PATTERNS = [
|
|
18
|
+
/FAIL/i,
|
|
19
|
+
/FAILED/i,
|
|
20
|
+
/ERROR/i,
|
|
21
|
+
/FATAL/i,
|
|
22
|
+
/Exception/,
|
|
23
|
+
/Traceback/,
|
|
24
|
+
/panic/,
|
|
25
|
+
/AssertionError/,
|
|
26
|
+
];
|
|
27
|
+
/**
|
|
28
|
+
* デフォルトのコンテキスト行数
|
|
29
|
+
*/
|
|
30
|
+
const DEFAULT_CONTEXT_LINES = 3;
|
|
31
|
+
/**
|
|
32
|
+
* ログの末尾から指定バイト数を取得する
|
|
33
|
+
*
|
|
34
|
+
* @param log - 対象のログ文字列
|
|
35
|
+
* @param maxBytes - 取得する最大バイト数
|
|
36
|
+
* @returns 末尾のログ文字列
|
|
37
|
+
*/
|
|
38
|
+
export function getTailBytes(log, maxBytes) {
|
|
39
|
+
// バイト数でカット
|
|
40
|
+
const encoder = new TextEncoder();
|
|
41
|
+
const encoded = encoder.encode(log);
|
|
42
|
+
if (encoded.length <= maxBytes) {
|
|
43
|
+
return log;
|
|
44
|
+
}
|
|
45
|
+
// 末尾からmaxBytesを取得
|
|
46
|
+
const tailBytes = encoded.slice(-maxBytes);
|
|
47
|
+
const decoder = new TextDecoder('utf-8', { fatal: false });
|
|
48
|
+
let result = decoder.decode(tailBytes);
|
|
49
|
+
// 先頭の不完全な文字を除去(改行まで読み飛ばす)
|
|
50
|
+
const firstNewline = result.indexOf('\n');
|
|
51
|
+
if (firstNewline > 0) {
|
|
52
|
+
result = result.slice(firstNewline + 1);
|
|
53
|
+
}
|
|
54
|
+
return result;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* ログの末尾N行を取得する
|
|
58
|
+
*
|
|
59
|
+
* @param log - 対象のログ文字列
|
|
60
|
+
* @param lineCount - 取得する行数
|
|
61
|
+
* @returns 末尾の行の配列
|
|
62
|
+
*/
|
|
63
|
+
export function getTailLines(log, lineCount) {
|
|
64
|
+
if (!log || lineCount <= 0) {
|
|
65
|
+
return [];
|
|
66
|
+
}
|
|
67
|
+
const lines = log.split('\n');
|
|
68
|
+
// 末尾の空行を除去
|
|
69
|
+
while (lines.length > 0 && lines[lines.length - 1] === '') {
|
|
70
|
+
lines.pop();
|
|
71
|
+
}
|
|
72
|
+
// 末尾N行を返す
|
|
73
|
+
return lines.slice(-lineCount);
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* 重要行を抽出する
|
|
77
|
+
*
|
|
78
|
+
* 正規表現パターンにマッチする行を抽出し、
|
|
79
|
+
* 前後のコンテキスト行を付与する。
|
|
80
|
+
*
|
|
81
|
+
* @param log - 対象のログ文字列
|
|
82
|
+
* @param options - 抽出オプション
|
|
83
|
+
* @returns 抽出されたブロックの配列
|
|
84
|
+
*/
|
|
85
|
+
export function extractImportantLines(log, options = {}) {
|
|
86
|
+
const { maxBytes, contextLines = DEFAULT_CONTEXT_LINES, patterns = IMPORTANT_PATTERNS, } = options;
|
|
87
|
+
// maxBytesが指定されている場合、末尾を切り出す
|
|
88
|
+
const targetLog = maxBytes !== undefined ? getTailBytes(log, maxBytes) : log;
|
|
89
|
+
if (!targetLog) {
|
|
90
|
+
return [];
|
|
91
|
+
}
|
|
92
|
+
const lines = targetLog.split('\n');
|
|
93
|
+
const results = [];
|
|
94
|
+
const matchedLineNumbers = new Set();
|
|
95
|
+
// 各行をパターンでチェック
|
|
96
|
+
for (let i = 0; i < lines.length; i++) {
|
|
97
|
+
const line = lines[i];
|
|
98
|
+
// undefinedチェック
|
|
99
|
+
if (line === undefined) {
|
|
100
|
+
continue;
|
|
101
|
+
}
|
|
102
|
+
for (const pattern of patterns) {
|
|
103
|
+
if (pattern.test(line)) {
|
|
104
|
+
// 既にマッチ済みの行はスキップ
|
|
105
|
+
if (matchedLineNumbers.has(i)) {
|
|
106
|
+
continue;
|
|
107
|
+
}
|
|
108
|
+
matchedLineNumbers.add(i);
|
|
109
|
+
// コンテキスト範囲を計算
|
|
110
|
+
const contextStart = Math.max(0, i - contextLines);
|
|
111
|
+
const contextEnd = Math.min(lines.length - 1, i + contextLines);
|
|
112
|
+
// コンテキスト行を取得
|
|
113
|
+
const contextLinesArray = lines.slice(contextStart, contextEnd + 1);
|
|
114
|
+
results.push({
|
|
115
|
+
lineNumber: i,
|
|
116
|
+
matchedLine: line,
|
|
117
|
+
pattern: pattern.source,
|
|
118
|
+
contextLines: contextLinesArray,
|
|
119
|
+
contextStartLine: contextStart,
|
|
120
|
+
contextEndLine: contextEnd,
|
|
121
|
+
});
|
|
122
|
+
// 1つのパターンにマッチしたら次の行へ
|
|
123
|
+
break;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
return results;
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* 抽出結果を文字列に整形する
|
|
131
|
+
*
|
|
132
|
+
* @param blocks - 抽出されたブロックの配列
|
|
133
|
+
* @returns 整形された文字列
|
|
134
|
+
*/
|
|
135
|
+
export function formatExtractedBlocks(blocks) {
|
|
136
|
+
if (blocks.length === 0) {
|
|
137
|
+
return '';
|
|
138
|
+
}
|
|
139
|
+
const parts = [];
|
|
140
|
+
for (const block of blocks) {
|
|
141
|
+
// ヘッダー
|
|
142
|
+
parts.push(`--- Line ${block.lineNumber + 1} (matched: ${block.pattern}) ---`);
|
|
143
|
+
// コンテキスト行(行番号付き)
|
|
144
|
+
for (let i = 0; i < block.contextLines.length; i++) {
|
|
145
|
+
const lineNum = block.contextStartLine + i + 1;
|
|
146
|
+
const marker = (block.contextStartLine + i === block.lineNumber) ? '>' : ' ';
|
|
147
|
+
parts.push(`${marker} ${lineNum}: ${block.contextLines[i]}`);
|
|
148
|
+
}
|
|
149
|
+
parts.push('');
|
|
150
|
+
}
|
|
151
|
+
return parts.join('\n');
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* LogExtractorクラス(オブジェクト指向インターフェース)
|
|
155
|
+
*
|
|
156
|
+
* ログ抽出の設定を保持し、抽出操作を行う
|
|
157
|
+
*/
|
|
158
|
+
export class LogExtractor {
|
|
159
|
+
patterns;
|
|
160
|
+
contextLines;
|
|
161
|
+
/**
|
|
162
|
+
* @param patterns - 使用するパターン(デフォルトはIMPORTANT_PATTERNS)
|
|
163
|
+
* @param contextLines - 前後に付与するコンテキスト行数
|
|
164
|
+
*/
|
|
165
|
+
constructor(patterns = IMPORTANT_PATTERNS, contextLines = DEFAULT_CONTEXT_LINES) {
|
|
166
|
+
this.patterns = patterns;
|
|
167
|
+
this.contextLines = contextLines;
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* 重要行を抽出する
|
|
171
|
+
*
|
|
172
|
+
* @param log - 対象のログ文字列
|
|
173
|
+
* @param maxBytes - 対象とする末尾バイト数(省略時は全体)
|
|
174
|
+
* @returns 抽出されたブロックの配列
|
|
175
|
+
*/
|
|
176
|
+
extractImportantLines(log, maxBytes) {
|
|
177
|
+
return extractImportantLines(log, {
|
|
178
|
+
maxBytes,
|
|
179
|
+
contextLines: this.contextLines,
|
|
180
|
+
patterns: this.patterns,
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* 末尾N行を取得する
|
|
185
|
+
*
|
|
186
|
+
* @param log - 対象のログ文字列
|
|
187
|
+
* @param lineCount - 取得する行数
|
|
188
|
+
* @returns 末尾の行の配列
|
|
189
|
+
*/
|
|
190
|
+
getTailLines(log, lineCount) {
|
|
191
|
+
return getTailLines(log, lineCount);
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* 抽出結果を文字列に整形する
|
|
195
|
+
*
|
|
196
|
+
* @param blocks - 抽出されたブロックの配列
|
|
197
|
+
* @returns 整形された文字列
|
|
198
|
+
*/
|
|
199
|
+
formatBlocks(blocks) {
|
|
200
|
+
return formatExtractedBlocks(blocks);
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
/**
|
|
204
|
+
* LogExtractorのファクトリ関数
|
|
205
|
+
*
|
|
206
|
+
* @param patterns - 使用するパターン
|
|
207
|
+
* @param contextLines - 前後に付与するコンテキスト行数
|
|
208
|
+
* @returns 新しいLogExtractorインスタンス
|
|
209
|
+
*/
|
|
210
|
+
export function createLogExtractor(patterns, contextLines) {
|
|
211
|
+
return new LogExtractor(patterns, contextLines);
|
|
212
|
+
}
|
|
213
|
+
//# sourceMappingURL=log-extractor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"log-extractor.js","sourceRoot":"","sources":["../../src/report/log-extractor.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ReportGenerator - レポート生成コンポーネント
|
|
3
|
+
*
|
|
4
|
+
* テスト実行結果から成果物(raw.log, summary.md, summary.json)を生成する。
|
|
5
|
+
*
|
|
6
|
+
* Requirements:
|
|
7
|
+
* - 4.1: report_dir に raw.log を生成する
|
|
8
|
+
* - 4.2: report_dir に summary.md を生成する
|
|
9
|
+
* - 4.3: report_dir に summary.json を生成する
|
|
10
|
+
* - 4.4: raw.log は stdout/stderr の出力元を区別して記録する
|
|
11
|
+
* - 4.5: report_dir が未指定の場合、デフォルトパスを使用する
|
|
12
|
+
* - 5.4: summary.json に必須フィールドを含める
|
|
13
|
+
* - 5.5: summary.md に人間が読みやすい形式で情報を含める
|
|
14
|
+
*/
|
|
15
|
+
import type { LogEntry } from '../executor/process-executor.js';
|
|
16
|
+
/**
|
|
17
|
+
* 要約情報
|
|
18
|
+
*/
|
|
19
|
+
export interface Summary {
|
|
20
|
+
/** 実行コマンド */
|
|
21
|
+
command: string;
|
|
22
|
+
/** コマンド引数 */
|
|
23
|
+
args: string[];
|
|
24
|
+
/** 実行ステータス */
|
|
25
|
+
status: string;
|
|
26
|
+
/** 終了コード */
|
|
27
|
+
exitCode: number | null;
|
|
28
|
+
/** 実行時間(ミリ秒) */
|
|
29
|
+
durationMs: number;
|
|
30
|
+
/** 抜粋ブロック */
|
|
31
|
+
excerpts: string[];
|
|
32
|
+
/** 末尾N行 */
|
|
33
|
+
tailLines: string[];
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* 生成された成果物のパス
|
|
37
|
+
*/
|
|
38
|
+
export interface GeneratedArtifacts {
|
|
39
|
+
/** raw.log のパス */
|
|
40
|
+
rawLog: string;
|
|
41
|
+
/** summary.md のパス */
|
|
42
|
+
summaryMd: string;
|
|
43
|
+
/** summary.json のパス */
|
|
44
|
+
summaryJson: string;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* ReportGeneratorインターフェース
|
|
48
|
+
*/
|
|
49
|
+
export interface IReportGenerator {
|
|
50
|
+
/**
|
|
51
|
+
* レポートディレクトリを作成する
|
|
52
|
+
*
|
|
53
|
+
* @param basePath - ベースパス(省略時はデフォルトパス)
|
|
54
|
+
* @returns 作成されたディレクトリのパス
|
|
55
|
+
*/
|
|
56
|
+
createReportDir(basePath?: string): Promise<string>;
|
|
57
|
+
/**
|
|
58
|
+
* raw.log を生成する(stdout/stderr を区別して記録)
|
|
59
|
+
*
|
|
60
|
+
* @param reportDir - レポートディレクトリ
|
|
61
|
+
* @param entries - ログエントリの配列
|
|
62
|
+
* @returns 生成されたファイルのパス
|
|
63
|
+
*/
|
|
64
|
+
writeRawLog(reportDir: string, entries: LogEntry[]): Promise<string>;
|
|
65
|
+
/**
|
|
66
|
+
* summary.md を生成する
|
|
67
|
+
*
|
|
68
|
+
* @param reportDir - レポートディレクトリ
|
|
69
|
+
* @param summary - 要約情報
|
|
70
|
+
* @returns 生成されたファイルのパス
|
|
71
|
+
*/
|
|
72
|
+
writeSummaryMd(reportDir: string, summary: Summary): Promise<string>;
|
|
73
|
+
/**
|
|
74
|
+
* summary.json を生成する
|
|
75
|
+
*
|
|
76
|
+
* @param reportDir - レポートディレクトリ
|
|
77
|
+
* @param summary - 要約情報
|
|
78
|
+
* @returns 生成されたファイルのパス
|
|
79
|
+
*/
|
|
80
|
+
writeSummaryJson(reportDir: string, summary: Summary): Promise<string>;
|
|
81
|
+
/**
|
|
82
|
+
* すべての成果物を生成する
|
|
83
|
+
*
|
|
84
|
+
* @param reportDir - レポートディレクトリ
|
|
85
|
+
* @param entries - ログエントリの配列
|
|
86
|
+
* @param summary - 要約情報
|
|
87
|
+
* @returns 生成された成果物のパス
|
|
88
|
+
*/
|
|
89
|
+
writeAll(reportDir: string, entries: LogEntry[], summary: Summary): Promise<GeneratedArtifacts>;
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* ReportGenerator - レポート生成の実装
|
|
93
|
+
*/
|
|
94
|
+
export declare class ReportGenerator implements IReportGenerator {
|
|
95
|
+
/**
|
|
96
|
+
* 古いレポートを削除して最新N件のみ保持する
|
|
97
|
+
*
|
|
98
|
+
* @param basePath - レポートのベースパス
|
|
99
|
+
*/
|
|
100
|
+
private cleanupOldReports;
|
|
101
|
+
/**
|
|
102
|
+
* レポートディレクトリを作成する
|
|
103
|
+
*
|
|
104
|
+
* @param basePath - ベースパス(省略時はデフォルトパス)
|
|
105
|
+
* @returns 作成されたディレクトリのパス
|
|
106
|
+
*/
|
|
107
|
+
createReportDir(basePath?: string): Promise<string>;
|
|
108
|
+
/**
|
|
109
|
+
* raw.log を生成する(stdout/stderr を区別して記録)
|
|
110
|
+
*
|
|
111
|
+
* @param reportDir - レポートディレクトリ
|
|
112
|
+
* @param entries - ログエントリの配列
|
|
113
|
+
* @returns 生成されたファイルのパス
|
|
114
|
+
*/
|
|
115
|
+
writeRawLog(reportDir: string, entries: LogEntry[]): Promise<string>;
|
|
116
|
+
/**
|
|
117
|
+
* summary.md を生成する
|
|
118
|
+
*
|
|
119
|
+
* @param reportDir - レポートディレクトリ
|
|
120
|
+
* @param summary - 要約情報
|
|
121
|
+
* @returns 生成されたファイルのパス
|
|
122
|
+
*/
|
|
123
|
+
writeSummaryMd(reportDir: string, summary: Summary): Promise<string>;
|
|
124
|
+
/**
|
|
125
|
+
* summary.json を生成する
|
|
126
|
+
*
|
|
127
|
+
* @param reportDir - レポートディレクトリ
|
|
128
|
+
* @param summary - 要約情報
|
|
129
|
+
* @returns 生成されたファイルのパス
|
|
130
|
+
*/
|
|
131
|
+
writeSummaryJson(reportDir: string, summary: Summary): Promise<string>;
|
|
132
|
+
/**
|
|
133
|
+
* すべての成果物を生成する
|
|
134
|
+
*
|
|
135
|
+
* @param reportDir - レポートディレクトリ
|
|
136
|
+
* @param entries - ログエントリの配列
|
|
137
|
+
* @param summary - 要約情報
|
|
138
|
+
* @returns 生成された成果物のパス
|
|
139
|
+
*/
|
|
140
|
+
writeAll(reportDir: string, entries: LogEntry[], summary: Summary): Promise<GeneratedArtifacts>;
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* ReportGeneratorのファクトリ関数
|
|
144
|
+
*
|
|
145
|
+
* @returns 新しいReportGeneratorインスタンス
|
|
146
|
+
*/
|
|
147
|
+
export declare function createReportGenerator(): IReportGenerator;
|
|
148
|
+
//# sourceMappingURL=report-generator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"report-generator.d.ts","sourceRoot":"","sources":["../../src/report/report-generator.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAIH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,iCAAiC,CAAC;AAOhE;;GAEG;AACH,MAAM,WAAW,OAAO;IACtB,aAAa;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa;IACb,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,cAAc;IACd,MAAM,EAAE,MAAM,CAAC;IACf,YAAY;IACZ,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,gBAAgB;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa;IACb,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,WAAW;IACX,SAAS,EAAE,MAAM,EAAE,CAAC;CACrB;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,kBAAkB;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,qBAAqB;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,uBAAuB;IACvB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B;;;;;OAKG;IACH,eAAe,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAEpD;;;;;;OAMG;IACH,WAAW,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAErE;;;;;;OAMG;IACH,cAAc,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAErE;;;;;;OAMG;IACH,gBAAgB,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAEvE;;;;;;;OAOG;IACH,QAAQ,CACN,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,QAAQ,EAAE,EACnB,OAAO,EAAE,OAAO,GACf,OAAO,CAAC,kBAAkB,CAAC,CAAC;CAChC;AAgFD;;GAEG;AACH,qBAAa,eAAgB,YAAW,gBAAgB;IACtD;;;;OAIG;YACW,iBAAiB;IAuB/B;;;;;OAKG;IACG,eAAe,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAezD;;;;;;OAMG;IACG,WAAW,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC;IAgB1E;;;;;;OAMG;IACG,cAAc,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC;IAqD1E;;;;;;OAMG;IACG,gBAAgB,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC;IAsB5E;;;;;;;OAOG;IACG,QAAQ,CACZ,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,QAAQ,EAAE,EACnB,OAAO,EAAE,OAAO,GACf,OAAO,CAAC,kBAAkB,CAAC;CAa/B;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,IAAI,gBAAgB,CAExD"}
|