@decencia/ch-cli 1.22.0 → 1.24.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 (33) hide show
  1. package/agent/2t-decencia-channel-issue-coder.md +1 -1
  2. package/agent/2t-decencia-channel-pr-merger.md +1 -1
  3. package/agent/2t-decencia-channel-terraformer.md +1 -1
  4. package/dist/commands/backup.d.ts.map +1 -1
  5. package/dist/commands/backup.js +8 -0
  6. package/dist/commands/backup.js.map +1 -1
  7. package/dist/commands/handoff.d.ts +19 -0
  8. package/dist/commands/handoff.d.ts.map +1 -0
  9. package/dist/commands/handoff.js +206 -0
  10. package/dist/commands/handoff.js.map +1 -0
  11. package/dist/commands/requests.d.ts +25 -0
  12. package/dist/commands/requests.d.ts.map +1 -0
  13. package/dist/commands/requests.js +369 -0
  14. package/dist/commands/requests.js.map +1 -0
  15. package/dist/commands/sprints.d.ts.map +1 -1
  16. package/dist/commands/sprints.js +48 -0
  17. package/dist/commands/sprints.js.map +1 -1
  18. package/dist/index.js +4 -0
  19. package/dist/index.js.map +1 -1
  20. package/package.json +1 -1
  21. package/skill/2t-decencia-channel-change-manager/SKILL.md +2 -1
  22. package/skill/2t-decencia-channel-change-propagation-v2/SKILL.md +1 -1
  23. package/skill/2t-decencia-channel-cli-v2/SKILL.md +47 -1
  24. package/skill/2t-decencia-channel-db-schema-v2/SKILL.md +1 -1
  25. package/skill/2t-decencia-channel-github-issue/SKILL.md +1 -1
  26. package/skill/2t-decencia-channel-orchestrator/SKILL.md +2 -1
  27. package/skill/2t-decencia-channel-prd-v2/SKILL.md +1 -1
  28. package/skill/2t-decencia-channel-project-bootstrap/SKILL.md +1 -1
  29. package/skill/2t-decencia-channel-spec-v2/SKILL.md +1 -1
  30. package/skill/2t-decencia-channel-sprint-builder-v2/SKILL.md +14 -2
  31. package/skill/2t-decencia-channel-sprint-runner/SKILL.md +36 -2
  32. package/skill/2t-decencia-channel-sqa-v2/SKILL.md +1 -1
  33. package/skill/2t-decencia-channel-work-status-v2/SKILL.md +1 -1
@@ -3,7 +3,7 @@ name: 2t-decencia-channel-issue-coder
3
3
  description: GitHub issue 1개를 입력으로 받아 끝까지 처리하는 코딩 에이전트. 이슈 읽기 → 소통채널 spec/SQA 확인 → git worktree+브랜치에서 구현 → 자체 소프트리뷰 루프 → unittest + SQA → PR 생성 → 소통채널 workStatus·이슈 기록. 다수 병렬 실행 전제, PR까지만(머지·base 브랜치 직접 push·이슈 close는 사람).
4
4
  tools: Read, Write, Edit, Grep, Glob, Bash, Agent
5
5
  model: opus
6
- version: 1.22.0
6
+ version: 1.24.0
7
7
  ---
8
8
 
9
9
  ## 역할
@@ -3,7 +3,7 @@ name: 2t-decencia-channel-pr-merger
3
3
  description: issue-coder가 낸 PR을 기본 완전 자율로 base 브랜치(기본 브랜치 또는 sprint 통합 브랜치)에 머지하는 에이전트. 핵심 역량은 다수 병렬 worktree가 만든 충돌을 작업 의도 기반(semantic)으로 해결하는 것. CI green+충돌없음이면 바로 squash 머지, 충돌이면 의도대로 해결 후 테스트로 검증하여 머지. 재SQA·전면 재리뷰는 하지 않음. 다수 PR은 직렬 머지.
4
4
  tools: Read, Write, Edit, Grep, Glob, Bash
5
5
  model: opus
6
- version: 1.22.0
6
+ version: 1.24.0
7
7
  ---
8
8
 
9
9
  ## 역할
@@ -3,7 +3,7 @@ name: 2t-decencia-channel-terraformer
3
3
  description: 소통채널을 쓰지 않던 기존 코드베이스를 역분석하여 소통채널 프로젝트로 편입(terraforming)하는 자율 에이전트. 코드가 single source of truth — 코드를 읽어 DB 스키마 → 기능명세(spec) → PRD를 bottom-up으로 역생성한다(SQA 제외). 대량 분석은 서브에이전트 병렬, 코드로 못 메우는 의도는 [추정]으로 채우고 "사람확인 질문 리스트"를 산출물로 남긴다. PR/머지·이슈 발행은 하지 않음.
4
4
  tools: Read, Write, Edit, Grep, Glob, Bash, Agent
5
5
  model: opus
6
- version: 1.22.0
6
+ version: 1.24.0
7
7
  ---
8
8
 
9
9
  ## 역할
@@ -1 +1 @@
1
- {"version":3,"file":"backup.d.ts","sourceRoot":"","sources":["../../src/commands/backup.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AA0EpC;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CA0H5D"}
1
+ {"version":3,"file":"backup.d.ts","sourceRoot":"","sources":["../../src/commands/backup.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AA0EpC;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAsI5D"}
@@ -190,6 +190,14 @@ function registerBackupCommand(program) {
190
190
  else {
191
191
  (0, output_1.printSuccess)(`가져오기 완료 — ${parts.join(', ')}`);
192
192
  }
193
+ // 요청사항 seq 충돌(같은 번호 중복)은 복원을 막지 않지만 별도로 경고한다.
194
+ const seqConflicts = Array.isArray(data?.seqConflicts) ? data.seqConflicts : [];
195
+ if (seqConflicts.length > 0) {
196
+ (0, output_1.printWarning)(`요청사항 seq 충돌 ${seqConflicts.length}건 감지 — 복원은 seq를 재발급하지 않습니다. 중복 번호를 확인하세요:`);
197
+ for (const c of seqConflicts) {
198
+ (0, output_1.printWarning)(` · seq ${c.seq} ← ${c.ids.join(', ')}`);
199
+ }
200
+ }
193
201
  }
194
202
  catch (error) {
195
203
  if (error?.message && !error?.response)
@@ -1 +1 @@
1
- {"version":3,"file":"backup.js","sourceRoot":"","sources":["../../src/commands/backup.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"backup.js","sourceRoot":"","sources":["../../src/commands/backup.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ import { Command } from 'commander';
2
+ /**
3
+ * export 대상 폴더를 엄격 검증한다(파괴적 교체 앞단 안전장치).
4
+ * backup export의 `resolveSafeExportDir` 규칙을 복제하되 **번들 마커만 바꾼다**.
5
+ * - cwd 하위(strict descendant)만 허용 → `..`·절대경로 거부
6
+ * - 심볼릭/junction 우회 차단 → realpath도 cwd 하위여야
7
+ * - 이미 존재하면 비어있거나 이전 핸드오프 번들(01-화면지도.md 보유)일 때만 교체 허용
8
+ *
9
+ * ⚠️ backup은 비어있지 않은 폴더를 manifest.json 유무로 판정하지만 핸드오프 번들에는
10
+ * 매니페스트가 없다. resolveSafeExportDir를 문자 그대로 재사용하면 두 번째 export부터
11
+ * manifest.json 부재로 거부되므로, 마커를 01-화면지도.md로 바꾼 전용 복제본을 쓴다 —
12
+ * 화면이 바뀔 때마다 같은 폴더로 재export하는 흐름(E16 재생성 원칙)이 거부되지 않게.
13
+ */
14
+ export declare function resolveSafeHandoffDir(dir: string): string;
15
+ /**
16
+ * ch handoff — 디자인 handoff 배달 (읽기 전용, ch-api 엔진 호출)
17
+ */
18
+ export declare function registerHandoffCommand(program: Command): void;
19
+ //# sourceMappingURL=handoff.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"handoff.d.ts","sourceRoot":"","sources":["../../src/commands/handoff.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AA4CpC;;;;;;;;;;;GAWG;AACH,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CA0BzD;AA8ID;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAS7D"}
@@ -0,0 +1,206 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.resolveSafeHandoffDir = resolveSafeHandoffDir;
37
+ exports.registerHandoffCommand = registerHandoffCommand;
38
+ const fs = __importStar(require("fs"));
39
+ const path = __importStar(require("path"));
40
+ const client_1 = require("../client");
41
+ const output_1 = require("../output");
42
+ // export/screen은 읽기 전용 왕복이지만 번들 생성(PRD·화면·명세 읽어 마크다운 조립)이
43
+ // 다소 무거울 수 있어 기본 30s보다 넉넉히 잡는다.
44
+ const HANDOFF_TIMEOUT = 120000;
45
+ // 통합 번들이 항상 포함하는 파일 — 이전 핸드오프 번들 폴더인지 식별하는 마커.
46
+ // (backup export의 manifest.json 역할. 핸드오프 번들에는 매니페스트가 없다 —
47
+ // 서버 파일 세트는 00-제품개요.md·01-화면지도.md·02-{NN}-{epic}.md 뿐이다.)
48
+ const BUNDLE_MARKER = '01-화면지도.md';
49
+ /**
50
+ * export 대상 폴더를 엄격 검증한다(파괴적 교체 앞단 안전장치).
51
+ * backup export의 `resolveSafeExportDir` 규칙을 복제하되 **번들 마커만 바꾼다**.
52
+ * - cwd 하위(strict descendant)만 허용 → `..`·절대경로 거부
53
+ * - 심볼릭/junction 우회 차단 → realpath도 cwd 하위여야
54
+ * - 이미 존재하면 비어있거나 이전 핸드오프 번들(01-화면지도.md 보유)일 때만 교체 허용
55
+ *
56
+ * ⚠️ backup은 비어있지 않은 폴더를 manifest.json 유무로 판정하지만 핸드오프 번들에는
57
+ * 매니페스트가 없다. resolveSafeExportDir를 문자 그대로 재사용하면 두 번째 export부터
58
+ * manifest.json 부재로 거부되므로, 마커를 01-화면지도.md로 바꾼 전용 복제본을 쓴다 —
59
+ * 화면이 바뀔 때마다 같은 폴더로 재export하는 흐름(E16 재생성 원칙)이 거부되지 않게.
60
+ */
61
+ function resolveSafeHandoffDir(dir) {
62
+ const cwd = process.cwd();
63
+ const resolved = path.resolve(cwd, dir);
64
+ const rel = path.relative(cwd, resolved);
65
+ if (rel === '' || rel.startsWith('..') || path.isAbsolute(rel)) {
66
+ throw new Error(`--dir 은 현재 작업 폴더 하위의 전용 폴더여야 합니다: "${dir}"`);
67
+ }
68
+ if (fs.existsSync(resolved)) {
69
+ const realCwd = fs.realpathSync(cwd);
70
+ const real = fs.realpathSync(resolved);
71
+ const realRel = path.relative(realCwd, real);
72
+ if (realRel === '' || realRel.startsWith('..') || path.isAbsolute(realRel)) {
73
+ throw new Error(`--dir 이 작업 폴더 밖을 가리킵니다(symlink?): "${dir}"`);
74
+ }
75
+ const entries = fs.readdirSync(real);
76
+ // 한글 파일명의 유니코드 정규화(NFC/NFD) 차이에 견고하게 비교한다.
77
+ const hasMarker = entries.some((e) => e.normalize('NFC') === BUNDLE_MARKER.normalize('NFC'));
78
+ if (entries.length > 0 && !hasMarker) {
79
+ throw new Error(`--dir "${dir}" 은 비어있지 않고 핸드오프 번들 폴더(${BUNDLE_MARKER})도 아닙니다. 덮어쓰기를 거부합니다.`);
80
+ }
81
+ }
82
+ return resolved;
83
+ }
84
+ function registerHandoffExport(handoff, program) {
85
+ handoff
86
+ .command('export')
87
+ .description('디자인 handoff 통합 번들을 폴더에 개별 .md 파일로 기록 (zip 아님)')
88
+ .option('--dir <dir>', '대상 폴더 (cwd 하위 전용)', 'design-handoff')
89
+ .addHelpText('after', `
90
+ 서버(ch-api SCREEN-023)가 낸 파일 세트를 폴더에 그대로 기록한다:
91
+ 00-제품개요.md · 01-화면지도.md · 02-{NN}-{epic}.md × N
92
+
93
+ 임시 폴더에 먼저 쓰고 원자적으로 교체하므로 쓰다 실패해도 기존 번들이 보존된다.
94
+ 같은 폴더로 재export(화면이 바뀔 때마다)는 허용된다. 화면 0개(레거시) 프로젝트면
95
+ 빈 폴더를 만들지 않고 안내 후 중단한다. --dry-run은 서버를 호출하지 않는다.
96
+ `)
97
+ .action(async (options) => {
98
+ const globalOpts = program.opts();
99
+ try {
100
+ // 로컬 입력 검증을 먼저: 작업 폴더 밖·남의 폴더면 요청을 보내지 않고 종료코드를 세운다.
101
+ let target;
102
+ try {
103
+ target = resolveSafeHandoffDir(options.dir);
104
+ }
105
+ catch (e) {
106
+ (0, output_1.failInput)(e?.message ?? String(e));
107
+ return;
108
+ }
109
+ if (globalOpts.dryRun) {
110
+ (0, output_1.printInfo)(`[DRY-RUN] 디자인 handoff 번들을 "${options.dir}/" 로 내보내기 (서버 미호출)`);
111
+ return;
112
+ }
113
+ const client = (0, client_1.createClient)({
114
+ projectId: globalOpts.project,
115
+ verbose: globalOpts.verbose,
116
+ });
117
+ const { data } = await client.get('/handoff/export', {
118
+ timeout: HANDOFF_TIMEOUT,
119
+ });
120
+ const files = data?.files ?? [];
121
+ const screenCount = data?.screenCount ?? 0;
122
+ // 화면 0개 가드(레거시·screensEnabled 미설정, 절대 제약): 폴더·파일을 만들지 않고
123
+ // 안내만 남긴다. backup의 "내보낼 문서가 없습니다" 선례처럼 경고 후 종료한다.
124
+ if (screenCount === 0 || files.length === 0) {
125
+ (0, output_1.printWarning)('화면이 없어 디자인 handoff를 생성하지 않았습니다. (빈 폴더를 만들지 않았습니다)');
126
+ return;
127
+ }
128
+ // 임시 폴더에 먼저 기록 후 원자적 교체 → 쓰기 실패해도 기존 번들 보존.
129
+ const tmp = `${target}.tmp-${process.pid}`;
130
+ if (fs.existsSync(tmp))
131
+ fs.rmSync(tmp, { recursive: true, force: true });
132
+ for (const f of files) {
133
+ const full = path.join(tmp, ...f.path.split('/'));
134
+ fs.mkdirSync(path.dirname(full), { recursive: true });
135
+ fs.writeFileSync(full, f.content, 'utf-8');
136
+ }
137
+ if (fs.existsSync(target))
138
+ fs.rmSync(target, { recursive: true, force: true });
139
+ fs.renameSync(tmp, target);
140
+ // 기계 모드: stdout에 요약 JSON 하나, 성공 메시지는 stderr로 분리(PLAT-003).
141
+ if ((0, output_1.isMachineMode)()) {
142
+ console.log(JSON.stringify({
143
+ screenCount,
144
+ dir: options.dir,
145
+ files: files.map((f) => ({ path: f.path })),
146
+ }, null, 2));
147
+ }
148
+ (0, output_1.printSuccess)(`디자인 handoff 내보내기 완료 — 화면 ${screenCount}개, 파일 ${files.length}개 → ${options.dir}/`);
149
+ (0, output_1.printInfo)('폴더를 열어 .md 파일을 Claude Design 대화에 드래그하세요 (한 채팅 최대 20개).');
150
+ }
151
+ catch (error) {
152
+ // HTTP 4xx/5xx·연결 실패는 client 인터셉터가 처리(stderr + exitCode).
153
+ }
154
+ });
155
+ }
156
+ function registerHandoffScreen(handoff, program) {
157
+ // 로컬 --json은 두지 않는다. commander가 부모(program)의 전역 옵션을 서브커맨드
158
+ // 뒤에서도 해석하므로 `ch handoff screen <id> --json`이 그대로 동작한다.
159
+ handoff
160
+ .command('screen <screenId>')
161
+ .description('화면 하나의 핸드오프 카드 마크다운을 stdout으로 (Claude Design 붙여넣기용)')
162
+ .action(async (screenId) => {
163
+ const globalOpts = program.opts();
164
+ try {
165
+ const client = (0, client_1.createClient)({
166
+ projectId: globalOpts.project,
167
+ verbose: globalOpts.verbose,
168
+ });
169
+ const { data } = await client.get(`/handoff/screen/${encodeURIComponent(screenId)}`);
170
+ const content = data?.content ?? null;
171
+ // 서버는 없는 화면·화면 0개 프로젝트에 404가 아니라 200 + content:null로 답한다
172
+ // (SCREEN-023 계약). 배달물(카드)이 없으므로 실패로 다룬다 — stderr 안내 +
173
+ // 종료코드 ≠ 0, stdout은 비운다(기계 모드 stdout 오염 방지).
174
+ if (content === null) {
175
+ const screenCount = data?.screenCount ?? 0;
176
+ (0, output_1.failInput)(screenCount === 0
177
+ ? '이 프로젝트에는 화면이 없어 카드를 생성할 수 없습니다. (screensEnabled 미설정)'
178
+ : `화면을 찾을 수 없습니다: ${screenId}`);
179
+ return;
180
+ }
181
+ // 기계 모드: 서버 응답 {content, screenName, screenCount}(SCREEN-023 계약)를
182
+ // 재명명·스트립 없이 그대로 순수 JSON으로 stdout에 낸다(SSOT 드리프트 금지).
183
+ if ((0, output_1.isMachineMode)()) {
184
+ console.log(JSON.stringify(data, null, 2));
185
+ return;
186
+ }
187
+ // 기본: 카드 마크다운 본문 자체가 배달물이라 stdout으로 낸다(붙여넣기용).
188
+ // 컨텍스트·성공 고지는 이미 stderr로 분리돼 있다.
189
+ console.log(content);
190
+ }
191
+ catch (error) {
192
+ // HTTP 4xx/5xx·연결 실패는 client 인터셉터가 처리(stderr + exitCode).
193
+ }
194
+ });
195
+ }
196
+ /**
197
+ * ch handoff — 디자인 handoff 배달 (읽기 전용, ch-api 엔진 호출)
198
+ */
199
+ function registerHandoffCommand(program) {
200
+ const handoff = program
201
+ .command('handoff')
202
+ .description('디자인 handoff 번들 배달 (읽기 전용 — ch-api 엔진 호출, 개발자·에이전트용 부차 경로)');
203
+ registerHandoffExport(handoff, program);
204
+ registerHandoffScreen(handoff, program);
205
+ }
206
+ //# sourceMappingURL=handoff.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"handoff.js","sourceRoot":"","sources":["../../src/commands/handoff.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ import { Command } from 'commander';
2
+ /**
3
+ * 첨부 허용 확장자 — 서버(requests.constants isAllowedRequestMime: `image/*` |
4
+ * `video/mp4`)의 클라이언트측 사전 게이트다. 서버가 최종 SSOT지만, 허용 외 파일을
5
+ * 업로드 스트림에 태우기 전에 여기서 먼저 거부해 헛수고(부분 전송·400)를 막는다.
6
+ * 확장자 기준이라 서버가 받아줄 희귀 이미지 타입을 놓칠 수 있으나, 흔한 이미지와
7
+ * mp4는 모두 포함한다.
8
+ */
9
+ export declare const ALLOWED_ATTACH_EXTENSIONS: ReadonlySet<string>;
10
+ /** 첨부 경로의 확장자가 허용 목록(이미지·gif·mp4)에 드는지. */
11
+ export declare function isAllowedAttachFile(filePath: string): boolean;
12
+ /** `a.png, b.mp4` → ['a.png', 'b.mp4'] (공백 trim·빈 항목 제거). */
13
+ export declare function parseAttachList(attach: string): string[];
14
+ /**
15
+ * 표시 번호 REQ-###(seq 3자리 0패딩). 서버가 얹어주는 displayNumber 를 우선 쓰고,
16
+ * 없으면 seq 로 계산한다(둘 다 없으면 물음표 표시).
17
+ */
18
+ export declare function requestDisplayNumber(req: {
19
+ displayNumber?: unknown;
20
+ seq?: unknown;
21
+ }): string;
22
+ /** 목록 한 줄을 사람 표시용 압축 행으로 — 번호(REQ-###)를 맨 앞에 둔다. */
23
+ export declare function toRequestRow(r: any): Record<string, unknown>;
24
+ export declare function registerRequestsCommand(program: Command): void;
25
+ //# sourceMappingURL=requests.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"requests.d.ts","sourceRoot":"","sources":["../../src/commands/requests.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAUpC;;;;;;GAMG;AACH,eAAO,MAAM,yBAAyB,EAAE,WAAW,CAAC,MAAM,CAqBxD,CAAC;AAEH,2CAA2C;AAC3C,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAG7D;AAED,6DAA6D;AAC7D,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAKxD;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,GAAG,EAAE;IACxC,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,GAAG,CAAC,EAAE,OAAO,CAAC;CACf,GAAG,MAAM,CAQT;AAED,oDAAoD;AACpD,wBAAgB,YAAY,CAAC,CAAC,EAAE,GAAG,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAS5D;AAmCD,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CA+P9D"}