@tienne/gestalt 0.69.0 → 0.71.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 (52) hide show
  1. package/CLAUDE.md +1 -0
  2. package/README.md +1 -1
  3. package/dist/package.json +1 -1
  4. package/dist/plugin/role-agents/_shared/references/README.md +1 -1
  5. package/dist/plugin/role-agents/_shared/references/ai-tell-quick-rules.md +13 -9
  6. package/dist/plugin/role-agents/_shared/references/author-voice.md +8 -8
  7. package/dist/plugin/role-agents/_shared/references/style-guide.md +13 -0
  8. package/dist/plugin/role-agents/humanize-monolith/AGENT.md +89 -11
  9. package/dist/src/cli/commands/humanize-check.d.ts +2 -0
  10. package/dist/src/cli/commands/humanize-check.d.ts.map +1 -1
  11. package/dist/src/cli/commands/humanize-check.js +16 -11
  12. package/dist/src/cli/commands/humanize-check.js.map +1 -1
  13. package/dist/src/cli/commands/humanize-scan.d.ts +25 -0
  14. package/dist/src/cli/commands/humanize-scan.d.ts.map +1 -0
  15. package/dist/src/cli/commands/humanize-scan.js +36 -0
  16. package/dist/src/cli/commands/humanize-scan.js.map +1 -0
  17. package/dist/src/cli/index.d.ts.map +1 -1
  18. package/dist/src/cli/index.js +11 -0
  19. package/dist/src/cli/index.js.map +1 -1
  20. package/dist/src/core/types.d.ts +1 -1
  21. package/dist/src/humanize/check.d.ts +75 -7
  22. package/dist/src/humanize/check.d.ts.map +1 -1
  23. package/dist/src/humanize/check.js +241 -30
  24. package/dist/src/humanize/check.js.map +1 -1
  25. package/dist/src/humanize/detectors.d.ts +31 -2
  26. package/dist/src/humanize/detectors.d.ts.map +1 -1
  27. package/dist/src/humanize/detectors.js +197 -13
  28. package/dist/src/humanize/detectors.js.map +1 -1
  29. package/dist/src/humanize/index.d.ts +4 -3
  30. package/dist/src/humanize/index.d.ts.map +1 -1
  31. package/dist/src/humanize/index.js +4 -3
  32. package/dist/src/humanize/index.js.map +1 -1
  33. package/dist/src/humanize/read-input.d.ts +21 -0
  34. package/dist/src/humanize/read-input.d.ts.map +1 -0
  35. package/dist/src/humanize/read-input.js +51 -0
  36. package/dist/src/humanize/read-input.js.map +1 -0
  37. package/dist/src/humanize/rules.d.ts +12 -0
  38. package/dist/src/humanize/rules.d.ts.map +1 -1
  39. package/dist/src/humanize/rules.js +4 -0
  40. package/dist/src/humanize/rules.js.map +1 -1
  41. package/dist/src/humanize/scan.d.ts +37 -0
  42. package/dist/src/humanize/scan.d.ts.map +1 -0
  43. package/dist/src/humanize/scan.js +76 -0
  44. package/dist/src/humanize/scan.js.map +1 -0
  45. package/dist/src/mcp/schemas.js +1 -1
  46. package/package.json +1 -1
  47. package/plugin/.codex-plugin/plugin.json +1 -1
  48. package/plugin/role-agents/_shared/references/README.md +1 -1
  49. package/plugin/role-agents/_shared/references/ai-tell-quick-rules.md +13 -9
  50. package/plugin/role-agents/_shared/references/author-voice.md +8 -8
  51. package/plugin/role-agents/_shared/references/style-guide.md +13 -0
  52. package/plugin/role-agents/humanize-monolith/AGENT.md +89 -11
@@ -1,13 +1,30 @@
1
- import { type Register, type RuleBook } from './rules.js';
1
+ import { type Register, type RuleScanOptions } from './rules.js';
2
2
  export type Verdict = 'pass' | 'warn' | 'abort';
3
3
  export declare const EXIT_CODE: Record<Verdict | 'unknown', number>;
4
4
  export declare const THRESHOLD: {
5
5
  readonly changeWarn: 0.3;
6
6
  readonly changeAbort: 0.5;
7
7
  readonly sentenceDrop: 0.25;
8
+ /** S1을 이만큼도 못 줄이면 경고. 한 건도 못 줄인 쪽은 아래 idleChange 와 함께 본다 */
9
+ readonly s1RemovalWarn: 0.5;
10
+ /**
11
+ * 손을 대긴 했다고 볼 최소 변경률.
12
+ *
13
+ * 제거율만 보면 탐지기가 가리는 룰만 세게 된다. 탐지기 없는 S1(doc 기준 일곱 개)만
14
+ * 제대로 고친 윤문본은 제거율이 0이라 채택 금지로 떨어진다. 원문을 그대로 돌려준
15
+ * 것과 같은 판정을 받는 셈인데, 그쪽은 변경률도 0이라 여기서 갈린다.
16
+ *
17
+ * 이 값으로 가르는 건 "윤문을 아예 안 했나"까지다. 문턱을 넘었다고 제대로 고쳤다는
18
+ * 뜻은 아니다 — 그건 이 검사의 판정 범위 밖이라 경고로 넘긴다.
19
+ *
20
+ * 변경률은 비율이라 문서가 길수록 같은 양의 교정이 낮은 값으로 나온다. 실측하면
21
+ * 한 곳을 고칠 때 2문단에서 20%, 50문단에서 0.75%다. 그래서 문턱 아래라는 게 안
22
+ * 고쳤다는 뜻이 아니다. 문구도 "텍스트가 그대로다"가 아니라 "변경이 문턱 아래다"이다.
23
+ */
24
+ readonly idleChange: 0.05;
8
25
  };
9
26
  export interface AxisResult {
10
- axis: 'change-rate' | 'residual-s1' | 'preservation' | 'structure' | 'report-register';
27
+ axis: 'change-rate' | 'residual-s1' | 'preservation' | 'structure' | 'introduced' | 'report-register';
11
28
  verdict: Verdict;
12
29
  detail: string;
13
30
  evidence?: string[];
@@ -18,6 +35,10 @@ export interface CheckReport {
18
35
  exitCode: number;
19
36
  changeRate: number;
20
37
  changeRateNoMarkup: number;
38
+ /** 원문 대비 S1을 얼마나 걷어냈나. 원문에 S1이 없었으면 1 */
39
+ s1Removal: number;
40
+ s1Before: number;
41
+ s1After: number;
21
42
  axes: AxisResult[];
22
43
  residualS1: {
23
44
  ruleId: string;
@@ -30,10 +51,57 @@ export interface CheckReport {
30
51
  after: number;
31
52
  }[];
32
53
  }
33
- export interface RunCheckOptions {
34
- register?: Register;
35
- book?: RuleBook;
54
+ export interface PrescanReport {
55
+ register: Register;
56
+ /** 이 말투 기준 S1 총 건수 */
57
+ s1Total: number;
58
+ /** 룰 ID별 건수. runCheck 에 그대로 넘겨 기준선으로 쓴다 */
59
+ s1ByRule: Map<string, number>;
60
+ /** 걸리는 게 없으면 윤문할 이유도 없다 */
61
+ worthHumanizing: boolean;
62
+ }
63
+ /**
64
+ * 윤문 전에 원문을 훑는다.
65
+ *
66
+ * 두 가지를 한다. 첫째, S1이 0건이면 윤문 자체를 건너뛴다 — 고칠 게 없는 글에
67
+ * 윤문을 돌리면 남는 건 과윤문뿐이다. 둘째, 여기서 센 건수를 runCheck의 prescanned로
68
+ * 넘기면 그 값이 제거율의 기준선이 된다.
69
+ *
70
+ * 비용은 문서 크기가 아니라 걸린 룰 종류 수에 비례한다. scan 을 거치며 라벨과 처방을
71
+ * 조회하지만 그건 걸린 룰마다 한 번씩이라, 2.5KB 와 5MB 사이에서 오버헤드가 커지지 않는다.
72
+ * 룰북이 수백 룰로 자라면 그때 다시 본다.
73
+ *
74
+ * 기준선이 실제로 의미를 가지려면 윤문 전에 불러 그 값을 들고 있어야 한다. 원문과
75
+ * 윤문본을 한꺼번에 받는 자리(예: humanize-check CLI)에서는 검사 시점에 다시 세는
76
+ * 것과 결과가 같다. 그 자리에서 이 함수는 편의일 뿐이다. 기준선이 갈릴 수 있는
77
+ * 흐름은 윤문 파이프라인이 원문을 먼저 훑는 경우다.
78
+ */
79
+ export declare function prescan(text: string, options?: RuleScanOptions): PrescanReport;
80
+ /** @deprecated rules.ts 의 RuleScanOptions 를 쓴다. 이름이 runCheck 전용처럼 보인다 */
81
+ export type RunCheckOptions = RuleScanOptions;
82
+ export interface RunCheckWithPrescan extends RuleScanOptions {
83
+ /** prescan() 이 센 원문 기준선. 안 넘기면 여기서 다시 센다 */
84
+ prescanned?: ReadonlyMap<string, number>;
85
+ }
86
+ export declare function runCheck(before: string, after: string, options?: RunCheckWithPrescan): CheckReport;
87
+ /** 검사 결과가 지시하는 다음 행동 */
88
+ export type NextAction = 'accept' | 'accept-with-warning' | 'retry' | 'fallback';
89
+ export interface Decision {
90
+ action: NextAction;
91
+ message: string;
36
92
  }
37
- export declare function runCheck(before: string, after: string, options?: RunCheckOptions): CheckReport;
38
- export declare function formatReport(report: CheckReport): string;
93
+ /** 윤문은 번만 다시 시킨다. 번째도 막히면 원문이 답이다 */
94
+ export declare const MAX_ATTEMPTS = 2;
95
+ /**
96
+ * 검사 결과를 다음 행동으로 옮긴다.
97
+ *
98
+ * "exit 2면 채택하지 않는다"를 문서에만 적어두면 모델이 자기 결과를 스스로
99
+ * 버려야 성립한다. 그건 지켜지지 않는다. 판정과 지시를 코드가 같이 낸다.
100
+ * 실행하는 쪽은 따르기만 한다.
101
+ *
102
+ * 재시도가 소진되면 윤문본을 버리고 원문을 낸다. 윤문이 원문보다 나아졌다고
103
+ * 증명하지 못했으니, 남는 선택지는 원문뿐이다.
104
+ */
105
+ export declare function decide(report: CheckReport, attempt?: number, maxAttempts?: number): Decision;
106
+ export declare function formatReport(report: CheckReport, attempt?: number): string;
39
107
  //# sourceMappingURL=check.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"check.d.ts","sourceRoot":"","sources":["../../../src/humanize/check.ts"],"names":[],"mappings":"AAcA,OAAO,EAAmC,KAAK,QAAQ,EAAE,KAAK,QAAQ,EAAE,MAAM,YAAY,CAAC;AAE3F,MAAM,MAAM,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;AAEhD,eAAO,MAAM,SAAS,EAAE,MAAM,CAAC,OAAO,GAAG,SAAS,EAAE,MAAM,CAKzD,CAAC;AAEF,eAAO,MAAM,SAAS;;;;CAIZ,CAAC;AAEX,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,aAAa,GAAG,aAAa,GAAG,cAAc,GAAG,WAAW,GAAG,iBAAiB,CAAC;IACvF,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;CACrB;AAED,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,QAAQ,CAAC;IACnB,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,IAAI,EAAE,UAAU,EAAE,CAAC;IACnB,UAAU,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAChE,UAAU,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;CACjE;AA0ID,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,EAAE,QAAQ,CAAC;IACpB,IAAI,CAAC,EAAE,QAAQ,CAAC;CACjB;AAED,wBAAgB,QAAQ,CACtB,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM,EACb,OAAO,GAAE,eAAoB,GAC5B,WAAW,CA2Bb;AAED,wBAAgB,YAAY,CAAC,MAAM,EAAE,WAAW,GAAG,MAAM,CAaxD"}
1
+ {"version":3,"file":"check.d.ts","sourceRoot":"","sources":["../../../src/humanize/check.ts"],"names":[],"mappings":"AAwBA,OAAO,EAIL,KAAK,QAAQ,EAEb,KAAK,eAAe,EACrB,MAAM,YAAY,CAAC;AAGpB,MAAM,MAAM,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;AAEhD,eAAO,MAAM,SAAS,EAAE,MAAM,CAAC,OAAO,GAAG,SAAS,EAAE,MAAM,CAKzD,CAAC;AAEF,eAAO,MAAM,SAAS;;;;IAIpB,4DAA4D;;IAE5D;;;;;;;;;;;;;OAaG;;CAEK,CAAC;AAEX,MAAM,WAAW,UAAU;IACzB,IAAI,EACA,aAAa,GACb,aAAa,GACb,cAAc,GACd,WAAW,GACX,YAAY,GACZ,iBAAiB,CAAC;IACtB,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;CACrB;AAED,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,QAAQ,CAAC;IACnB,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,yCAAyC;IACzC,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,UAAU,EAAE,CAAC;IACnB,UAAU,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAChE,UAAU,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;CACjE;AA0OD,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,QAAQ,CAAC;IACnB,sBAAsB;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,2CAA2C;IAC3C,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC9B,2BAA2B;IAC3B,eAAe,EAAE,OAAO,CAAC;CAC1B;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,eAAoB,GAAG,aAAa,CAWlF;AAED,yEAAyE;AACzE,MAAM,MAAM,eAAe,GAAG,eAAe,CAAC;AAE9C,MAAM,WAAW,mBAAoB,SAAQ,eAAe;IAC1D,4CAA4C;IAC5C,UAAU,CAAC,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC1C;AAED,wBAAgB,QAAQ,CACtB,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM,EACb,OAAO,GAAE,mBAAwB,GAChC,WAAW,CA4Db;AAED,wBAAwB;AACxB,MAAM,MAAM,UAAU,GAAG,QAAQ,GAAG,qBAAqB,GAAG,OAAO,GAAG,UAAU,CAAC;AAEjF,MAAM,WAAW,QAAQ;IACvB,MAAM,EAAE,UAAU,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,yCAAyC;AACzC,eAAO,MAAM,YAAY,IAAI,CAAC;AAE9B;;;;;;;;;GASG;AACH,wBAAgB,MAAM,CACpB,MAAM,EAAE,WAAW,EACnB,OAAO,GAAE,MAAU,EACnB,WAAW,GAAE,MAAqB,GACjC,QAAQ,CA8BV;AAED,wBAAgB,YAAY,CAAC,MAAM,EAAE,WAAW,EAAE,OAAO,GAAE,MAAU,GAAG,MAAM,CAgB7E"}
@@ -3,11 +3,22 @@
3
3
  *
4
4
  * 모델이 스스로 매긴 변경률·등급은 참고값이다. 문자 기반 변경률 하나로는
5
5
  * 구조 편집이 안 보인다 — 변경률 2.8%인데 문장 3할이 갈려나간 사례가 있다.
6
- * 그래서 변경률, 잔존, 보존, 구조 4가지 측면에서 각각 측정하고, 판단한다.
6
+ * 그래서 변경률, 잔존, 보존, 구조, 유입 다섯 측면에서 각각 측정하고, 판단한다.
7
+ *
8
+ * 채택 금지(abort)는 양방향이다. 너무 많이 바꾼 쪽(변경률 50%, 보호 토큰 유실)만
9
+ * 막으면 아무것도 안 고친 윤문이 그대로 통과한다 — 원문을 그대로 돌려줘도
10
+ * 변경률 0%에 유실 0건이라 경고 하나로 끝났다. 그래서 못 줄인 쪽과 새로 심은 쪽도
11
+ * 막는다. 다만 두 쪽의 조건이 다르다. 신규 유입은 그 말투의 S1이 새로 생겼을 때
12
+ * 채택 금지이고 S2 이하는 경고다. 제거율 0은 변경까지 문턱 아래일 때만 채택 금지다.
13
+ *
14
+ * 잔존 축의 판정 근거는 탐지기가 있는 룰의 건수다. 제거율이 0인 자리에서만 변경률을
15
+ * 문턱으로 함께 보는데, 그건 change-rate 축이 계산한 값을 빌려 쓰는 것이다. 그 밖에서
16
+ * 무엇을 고쳤는지는 판정 범위에 없다. 그 자리는 사람에게 넘긴다.
7
17
  */
8
18
  import { changeRate } from './change-rate.js';
9
19
  import { countByRule, missingProtectedTokens, reportRegisterStats, structureStats, } from './detectors.js';
10
- import { parseRuleBook, ruleLabel, s1Ids } from './rules.js';
20
+ import { parseRuleBook, ruleLabel, s1Ids, } from './rules.js';
21
+ import { scan } from './scan.js';
11
22
  export const EXIT_CODE = {
12
23
  pass: 0,
13
24
  warn: 1,
@@ -18,6 +29,23 @@ export const THRESHOLD = {
18
29
  changeWarn: 0.3,
19
30
  changeAbort: 0.5,
20
31
  sentenceDrop: 0.25,
32
+ /** S1을 이만큼도 못 줄이면 경고. 한 건도 못 줄인 쪽은 아래 idleChange 와 함께 본다 */
33
+ s1RemovalWarn: 0.5,
34
+ /**
35
+ * 손을 대긴 했다고 볼 최소 변경률.
36
+ *
37
+ * 제거율만 보면 탐지기가 가리는 룰만 세게 된다. 탐지기 없는 S1(doc 기준 일곱 개)만
38
+ * 제대로 고친 윤문본은 제거율이 0이라 채택 금지로 떨어진다. 원문을 그대로 돌려준
39
+ * 것과 같은 판정을 받는 셈인데, 그쪽은 변경률도 0이라 여기서 갈린다.
40
+ *
41
+ * 이 값으로 가르는 건 "윤문을 아예 안 했나"까지다. 문턱을 넘었다고 제대로 고쳤다는
42
+ * 뜻은 아니다 — 그건 이 검사의 판정 범위 밖이라 경고로 넘긴다.
43
+ *
44
+ * 변경률은 비율이라 문서가 길수록 같은 양의 교정이 낮은 값으로 나온다. 실측하면
45
+ * 한 곳을 고칠 때 2문단에서 20%, 50문단에서 0.75%다. 그래서 문턱 아래라는 게 안
46
+ * 고쳤다는 뜻이 아니다. 문구도 "텍스트가 그대로다"가 아니라 "변경이 문턱 아래다"이다.
47
+ */
48
+ idleChange: 0.05,
21
49
  };
22
50
  const WORST = { pass: 0, warn: 1, abort: 2 };
23
51
  function worst(verdicts) {
@@ -36,38 +64,123 @@ function checkChangeRate(rate, rateNoMarkup) {
36
64
  }
37
65
  return { axis: 'change-rate', verdict: 'pass', detail };
38
66
  }
39
- function checkResidualS1(book, register, before, after) {
67
+ /**
68
+ * S1을 얼마나 걷어냈는지 본다.
69
+ *
70
+ * 잔존 건수만 보면 "5건 → 5건"과 "5건 → 1건"이 같은 경고로 끝난다. 앞은 윤문이
71
+ * 아무 일도 안 한 것이고 뒤는 8할을 걷어낸 것이라, 같은 판정을 받을 수 없다.
72
+ * 원문 건수를 기준선으로 두고 제거율로 가른다.
73
+ *
74
+ * 세는 대상은 탐지기가 있는 룰뿐이다. 그래서 제거율 0이 곧 "아무것도 안 했다"는
75
+ * 아니다 — 탐지기 없는 S1만 고친 윤문본도 여기서는 0으로 보인다.
76
+ *
77
+ * 그래서 제거율이 0일 때 여기서 확정되는 건 하나다 — 변경까지 문턱 아래면 윤문을 안
78
+ * 한 것이다. 변경이 문턱을 넘었으면 탐지기 밖에서 고쳤을 수 있고 그건 이 코드로
79
+ * 확인되지 않으므로 경고로 넘긴다.
80
+ */
81
+ function checkResidualS1(book, register, counts, rate) {
40
82
  const targets = s1Ids(book, register);
41
- const beforeCounts = countByRule(before, targets);
42
- const afterCounts = countByRule(after, targets);
43
- const residual = targets
44
- .map((ruleId) => ({
83
+ const beforeCounts = counts.before;
84
+ const afterCounts = counts.after;
85
+ const rows = targets.map((ruleId) => ({
45
86
  ruleId,
46
87
  before: beforeCounts.get(ruleId) ?? 0,
47
88
  after: afterCounts.get(ruleId) ?? 0,
48
- }))
49
- .filter((row) => row.after > 0);
50
- if (residual.length === 0) {
89
+ }));
90
+ const beforeTotal = rows.reduce((sum, row) => sum + row.before, 0);
91
+ const afterTotal = rows.reduce((sum, row) => sum + row.after, 0);
92
+ const residual = rows.filter((row) => row.after > 0);
93
+ // 원문에 S1이 없었으면 줄일 것도 없다. 그 자리에 새로 심었다면 아래에서 걸린다
94
+ const removal = beforeTotal === 0 ? 1 : (beforeTotal - afterTotal) / beforeTotal;
95
+ const base = { residual, removal, beforeTotal, afterTotal };
96
+ if (afterTotal === 0) {
97
+ return { ...base, axis: { axis: 'residual-s1', verdict: 'pass', detail: 'S1 잔존 0건' } };
98
+ }
99
+ const evidence = residual.map((row) => `${ruleLabel(book, row.ruleId)}: ${row.before} → ${row.after}`);
100
+ const scale = `S1 ${beforeTotal} → ${afterTotal}건`;
101
+ // 원문에 없던 S1이 생긴 경우는 introduced 축이 판정한다. 여기서 함께 abort를 내면
102
+ // 같은 사실을 두 축이 각자 판단하는 꼴이라, 한쪽이 회귀해도 다른 쪽이 가려서 안 잡힌다.
103
+ if (beforeTotal === 0) {
51
104
  return {
52
- axis: { axis: 'residual-s1', verdict: 'pass', detail: 'S1 잔존 0건' },
53
- residual,
105
+ ...base,
106
+ axis: {
107
+ axis: 'residual-s1',
108
+ verdict: 'warn',
109
+ detail: `원문에 없던 S1이 ${afterTotal}건 생김 — 유입 측면을 본다`,
110
+ evidence,
111
+ },
112
+ };
113
+ }
114
+ if (removal <= 0) {
115
+ // 확정할 수 있는 데까지만 간다. 변경이 문턱 아래면 윤문을 안 한 것이다. 문턱을
116
+ // 넘었으면 탐지기 밖에서 고쳤을 수도 있다. 그 자리는 이 검사의 범위 밖이다.
117
+ const idle = rate < THRESHOLD.idleChange;
118
+ const grew = afterTotal > beforeTotal;
119
+ return {
120
+ ...base,
121
+ axis: {
122
+ axis: 'residual-s1',
123
+ verdict: idle ? 'abort' : 'warn',
124
+ detail: idle
125
+ ? `${scale}, 한 건도 못 줄이고 변경도 문턱 아래다 (변경률 ${pct(rate)}) — 채택 금지`
126
+ : `${scale}, ${grew ? '탐지 가능한 룰이 오히려 늘었다' : '탐지 가능한 룰은 안 줄었다'} (변경률 ${pct(rate)}) — 탐지기 밖 룰은 이 검사로 확인되지 않는다`,
127
+ evidence,
128
+ },
129
+ };
130
+ }
131
+ if (removal < THRESHOLD.s1RemovalWarn) {
132
+ return {
133
+ ...base,
134
+ axis: {
135
+ axis: 'residual-s1',
136
+ verdict: 'warn',
137
+ detail: `${scale} (제거율 ${pct(removal)}) — 절반도 못 줄임`,
138
+ evidence,
139
+ },
54
140
  };
55
141
  }
56
- const evidence = residual.map((row) => `${ruleLabel(book, row.ruleId)}: ${row.before} → ${row.after}`);
57
142
  return {
143
+ ...base,
58
144
  axis: {
59
145
  axis: 'residual-s1',
60
146
  verdict: 'warn',
61
- detail: `S1 ${residual.length}종 잔존`,
147
+ detail: `${scale} (제거율 ${pct(removal)}), ${residual.length}종 잔존`,
62
148
  evidence,
63
149
  },
64
- residual,
65
150
  };
66
151
  }
67
- /** 철칙 — AI 티는 빼기만 하고 넣지 않는다. 늘어난 룰이 있으면 윤문이 새 티를 심은 것이다 */
68
- function findIntroduced(before, after) {
69
- const beforeCounts = countByRule(before);
70
- const afterCounts = countByRule(after);
152
+ /**
153
+ * 철칙 — AI 티는 빼기만 하고 넣지 않는다.
154
+ *
155
+ * 구조 이상의 한 항목으로 묻어두면 새 티를 심어도 경고에서 그친다. 심각도가
156
+ * S1인 룰이 새로 들어왔으면 그건 윤문이 원문을 나쁘게 만든 것이라 채택하지 않는다.
157
+ */
158
+ function checkIntroduced(book, register, introduced) {
159
+ if (introduced.length === 0) {
160
+ return { axis: 'introduced', verdict: 'pass', detail: '새로 심은 AI-tell 없음' };
161
+ }
162
+ const evidence = introduced
163
+ .slice(0, 5)
164
+ .map((row) => `${ruleLabel(book, row.ruleId)} ${row.before} → ${row.after}`);
165
+ const s1 = new Set(s1Ids(book, register));
166
+ const s1Rows = introduced.filter((row) => s1.has(row.ruleId));
167
+ if (s1Rows.length > 0) {
168
+ return {
169
+ axis: 'introduced',
170
+ verdict: 'abort',
171
+ detail: `S1 ${s1Rows.length}종을 새로 심음 — 채택 금지`,
172
+ evidence,
173
+ };
174
+ }
175
+ return {
176
+ axis: 'introduced',
177
+ verdict: 'warn',
178
+ detail: `${introduced.length}종 신규 유입`,
179
+ evidence,
180
+ };
181
+ }
182
+ /** 늘어난 룰을 추린다. 판정은 checkIntroduced가 한다 */
183
+ function findIntroduced(beforeCounts, afterCounts) {
71
184
  return [...afterCounts.entries()]
72
185
  .map(([ruleId, count]) => ({ ruleId, before: beforeCounts.get(ruleId) ?? 0, after: count }))
73
186
  .filter((row) => row.after > row.before)
@@ -85,7 +198,7 @@ function checkPreservation(before, after) {
85
198
  evidence: missing.slice(0, 10),
86
199
  };
87
200
  }
88
- function checkStructure(book, before, after, introduced) {
201
+ function checkStructure(before, after) {
89
202
  const a = structureStats(before);
90
203
  const b = structureStats(after);
91
204
  const problems = [];
@@ -99,9 +212,6 @@ function checkStructure(book, before, after, introduced) {
99
212
  if (b.links < a.links) {
100
213
  problems.push(`링크 ${a.links} → ${b.links}`);
101
214
  }
102
- for (const row of introduced.slice(0, 5)) {
103
- problems.push(`${ruleLabel(book, row.ruleId)} 신규 유입 ${row.before} → ${row.after}`);
104
- }
105
215
  if (problems.length === 0) {
106
216
  return { axis: 'structure', verdict: 'pass', detail: '구조·정보량 보존' };
107
217
  }
@@ -128,18 +238,73 @@ function checkReportRegister(after) {
128
238
  detail: '보고 본문 어미 일관',
129
239
  };
130
240
  }
241
+ /**
242
+ * 윤문 전에 원문을 훑는다.
243
+ *
244
+ * 두 가지를 한다. 첫째, S1이 0건이면 윤문 자체를 건너뛴다 — 고칠 게 없는 글에
245
+ * 윤문을 돌리면 남는 건 과윤문뿐이다. 둘째, 여기서 센 건수를 runCheck의 prescanned로
246
+ * 넘기면 그 값이 제거율의 기준선이 된다.
247
+ *
248
+ * 비용은 문서 크기가 아니라 걸린 룰 종류 수에 비례한다. scan 을 거치며 라벨과 처방을
249
+ * 조회하지만 그건 걸린 룰마다 한 번씩이라, 2.5KB 와 5MB 사이에서 오버헤드가 커지지 않는다.
250
+ * 룰북이 수백 룰로 자라면 그때 다시 본다.
251
+ *
252
+ * 기준선이 실제로 의미를 가지려면 윤문 전에 불러 그 값을 들고 있어야 한다. 원문과
253
+ * 윤문본을 한꺼번에 받는 자리(예: humanize-check CLI)에서는 검사 시점에 다시 세는
254
+ * 것과 결과가 같다. 그 자리에서 이 함수는 편의일 뿐이다. 기준선이 갈릴 수 있는
255
+ * 흐름은 윤문 파이프라인이 원문을 먼저 훑는 경우다.
256
+ */
257
+ export function prescan(text, options = {}) {
258
+ // 세는 일은 scan 한 곳에만 둔다. 여기서 다시 세면 같은 집계가 두 벌이 된다.
259
+ // 룰북 해석이 갈리는 날 어느 쪽이 맞는지 알 수 없게 된다.
260
+ const report = scan(text, options);
261
+ return {
262
+ register: report.register,
263
+ s1Total: report.s1Total,
264
+ s1ByRule: new Map(report.hits.map((hit) => [hit.ruleId, hit.count])),
265
+ worthHumanizing: report.worthHumanizing,
266
+ };
267
+ }
131
268
  export function runCheck(before, after, options = {}) {
132
269
  const register = options.register ?? 'doc';
133
270
  const book = options.book ?? parseRuleBook();
134
271
  const rate = changeRate(before, after);
135
272
  const rateNoMarkup = changeRate(before, after, { ignoreMarkup: true });
273
+ // 탐지기는 텍스트당 한 번만 돌린다. 잔존 축은 S1 부분집합을, 유입 축은 전체를 보는데
274
+ // 룰 필터만 다른 같은 순회라, 따로 부르면 같은 문자열에 정규식이 두 번씩 돌아간다.
275
+ //
276
+ // 다만 이 절약은 detect 안에서만이다. 아래 checkStructure의 structureStats가
277
+ // proseOnly를 다시 계산한다. report 말투면 reportRegisterStats가 한 번 더 한다.
278
+ //
279
+ // 안 건드리는 근거는 실측으로 확인했다. 그 중복이 차지하는 비중이 1KB에서 1MB까지
280
+ // 어느 구간에서도 7퍼센트를 안 넘는다. changeRate가 지배한다는 말은 어절 6000개
281
+ // 이하에서만 맞고 그 위로는 절반으로 준다. 다만 그 자리를 메우는 건 detect 본연의
282
+ // 계산이지 이 중복이 아니라, 결론은 전 구간에서 같다.
283
+ const beforeAll = countByRule(before);
284
+ const afterAll = countByRule(after);
285
+ // prescanned는 윤문에 들어가기 전에 확정한 기준선이라 지금 센 값보다 우선한다
286
+ const counts = { before: options.prescanned ?? beforeAll, after: afterAll };
287
+ // 유입 축도 잔존 축과 같은 기준선을 봐야 한다. 잔존 축이 prescanned 기준으로
288
+ // "원문에 S1이 없었다"며 유입 축에 판정을 넘겼는데, 유입 축이 지금 센 원문을 보고
289
+ // "안 늘었다"고 하면 두 축 사이로 빠져나가는 자리가 생긴다.
290
+ const introducedBase = options.prescanned
291
+ ? new Map([...beforeAll, ...options.prescanned])
292
+ : beforeAll;
136
293
  const changeAxis = checkChangeRate(rate, rateNoMarkup);
137
- const { axis: s1Axis, residual } = checkResidualS1(book, register, before, after);
294
+ const s1 = checkResidualS1(book, register, counts, rate);
138
295
  const preservationAxis = checkPreservation(before, after);
139
- const introduced = findIntroduced(before, after);
140
- const structureAxis = checkStructure(book, before, after, introduced);
296
+ const introduced = findIntroduced(introducedBase, afterAll);
297
+ const introducedAxis = checkIntroduced(book, register, introduced);
298
+ const structureAxis = checkStructure(before, after);
141
299
  const reportAxis = register === 'report' ? [checkReportRegister(after)] : [];
142
- const axes = [changeAxis, s1Axis, preservationAxis, structureAxis, ...reportAxis];
300
+ const axes = [
301
+ changeAxis,
302
+ s1.axis,
303
+ preservationAxis,
304
+ structureAxis,
305
+ introducedAxis,
306
+ ...reportAxis,
307
+ ];
143
308
  const verdict = worst(axes.map((a) => a.verdict));
144
309
  return {
145
310
  register,
@@ -147,13 +312,57 @@ export function runCheck(before, after, options = {}) {
147
312
  exitCode: EXIT_CODE[verdict],
148
313
  changeRate: rate,
149
314
  changeRateNoMarkup: rateNoMarkup,
315
+ s1Removal: s1.removal,
316
+ s1Before: s1.beforeTotal,
317
+ s1After: s1.afterTotal,
150
318
  axes,
151
- residualS1: residual,
319
+ residualS1: s1.residual,
152
320
  introduced,
153
321
  };
154
322
  }
155
- export function formatReport(report) {
156
- const head = `검사 ${report.verdict.toUpperCase()} (exit ${report.exitCode}) / 말투 ${report.register}`;
323
+ /** 윤문은 번만 다시 시킨다. 두 번째도 막히면 원문이 답이다 */
324
+ export const MAX_ATTEMPTS = 2;
325
+ /**
326
+ * 검사 결과를 다음 행동으로 옮긴다.
327
+ *
328
+ * "exit 2면 채택하지 않는다"를 문서에만 적어두면 모델이 자기 결과를 스스로
329
+ * 버려야 성립한다. 그건 지켜지지 않는다. 판정과 지시를 코드가 같이 낸다.
330
+ * 실행하는 쪽은 따르기만 한다.
331
+ *
332
+ * 재시도가 소진되면 윤문본을 버리고 원문을 낸다. 윤문이 원문보다 나아졌다고
333
+ * 증명하지 못했으니, 남는 선택지는 원문뿐이다.
334
+ */
335
+ export function decide(report, attempt = 1, maxAttempts = MAX_ATTEMPTS) {
336
+ if (report.verdict === 'pass') {
337
+ return { action: 'accept', message: '검사 통과. 윤문본을 채택한다.' };
338
+ }
339
+ if (report.verdict === 'warn') {
340
+ const flagged = report.axes
341
+ .filter((axis) => axis.verdict === 'warn')
342
+ .map((axis) => axis.axis)
343
+ .join(', ');
344
+ return {
345
+ action: 'accept-with-warning',
346
+ message: `윤문본을 채택하되 걸린 측면을 요약에 적는다: ${flagged}`,
347
+ };
348
+ }
349
+ const blocking = report.axes
350
+ .filter((axis) => axis.verdict === 'abort')
351
+ .map((axis) => axis.detail)
352
+ .join(' / ');
353
+ if (attempt < maxAttempts) {
354
+ return {
355
+ action: 'retry',
356
+ message: `${blocking} — 윤문본을 버리고 원문에서 한 번 더 윤문한 뒤 --attempt ${attempt + 1}로 다시 검사한다.`,
357
+ };
358
+ }
359
+ return {
360
+ action: 'fallback',
361
+ message: `${blocking} — 재시도(${maxAttempts}회)를 소진했다. 윤문본을 버리고 원문을 그대로 낸다.`,
362
+ };
363
+ }
364
+ export function formatReport(report, attempt = 1) {
365
+ const head = `검사 ${report.verdict.toUpperCase()} (exit ${report.exitCode}) / 말투 ${report.register} / 시도 ${attempt}`;
157
366
  const lines = [head, ''];
158
367
  for (const axis of report.axes) {
159
368
  const mark = axis.verdict === 'pass' ? 'OK' : axis.verdict === 'warn' ? '경고' : '중단';
@@ -162,6 +371,8 @@ export function formatReport(report) {
162
371
  lines.push(` ${item}`);
163
372
  }
164
373
  }
374
+ const decision = decide(report, attempt);
375
+ lines.push('', `[다음] ${decision.action} — ${decision.message}`);
165
376
  return lines.join('\n');
166
377
  }
167
378
  //# sourceMappingURL=check.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"check.js","sourceRoot":"","sources":["../../../src/humanize/check.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"check.js","sourceRoot":"","sources":["../../../src/humanize/check.ts"],"names":[],"mappings":"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"}
@@ -1,8 +1,11 @@
1
1
  /**
2
2
  * 룰 ID별 결정적 탐지기.
3
3
  *
4
- * 여기 있는 건 정규식만으로 오탐 없이 셀 수 있는 룰뿐이다. D-5 의인화 주어처럼
5
- * 뜻을 봐야 판단되는 룰은 일부러 뺐다 — 검사가 오탐으로 멈추면 아무도 안 쓴다.
4
+ * 여기 있는 건 정규식으로 셀 수 있는 룰뿐이다. D-5 의인화 주어처럼 뜻을 봐야 판단되는
5
+ * 룰은 일부러 뺐다 — 멀쩡한 문장에서 검사가 멈추면 아무도 안 쓴다.
6
+ *
7
+ * 전부 정확히 걸러내지는 못한다. 잘못 감지가 남는 갈래는 그 자리 주석이 어디까지 새는지 적고
8
+ * 코퍼스가 그 경계를 잡는다.
6
9
  * 탐지기가 없는 룰은 모델이 자체검증으로 본다.
7
10
  */
8
11
  export interface Detection {
@@ -30,6 +33,21 @@ export declare function proseLines(text: string, options?: ProseOptions): ProseL
30
33
  export declare function splitSentences(text: string): string[];
31
34
  export declare const DETECTABLE_RULE_IDS: string[];
32
35
  export declare function detect(text: string, ruleIds?: readonly string[]): Detection[];
36
+ /** 맞춤법 한 건. 무엇이 틀렸고 무엇으로 고치는지, 몇 건인지와 실제 사례를 담는다 */
37
+ export interface SpacingIssue {
38
+ label: string;
39
+ fix: string;
40
+ count: number;
41
+ samples: string[];
42
+ }
43
+ /**
44
+ * 어투가 아니라 맞춤법인 자리를 센다. 등급과 따로 가는 값이다.
45
+ *
46
+ * 리뷰 코멘트는 커밋 해시나 브랜치명을 문장에 그대로 섞기 때문에 조사 처리가 반복해서
47
+ * 어긋난다 (author-voice.md §「기계적 점검 (어투는 아니지만 자주 틀리는 것)」).
48
+ * S1 총계에 섞으면 윤문 등급이 맞춤법 때문에 떨어지므로 ScanReport가 이 값을 따로 들고 간다.
49
+ */
50
+ export declare function spacingIssues(text: string): SpacingIssue[];
33
51
  export declare function countByRule(text: string, ruleIds?: readonly string[]): Map<string, number>;
34
52
  export interface ReportRegisterStats {
35
53
  plainEndings: number;
@@ -51,4 +69,15 @@ export interface StructureStats {
51
69
  links: number;
52
70
  }
53
71
  export declare function structureStats(text: string): StructureStats;
72
+ /**
73
+ * 어투와 맞춤법을 한 산문 위에서 함께 본다.
74
+ *
75
+ * detect 와 spacingIssues 를 따로 부르면 줄 분할과 인용 제거가 두 번 돈다. 비용은 작지만
76
+ * (500KB 입력에서 12%) 진짜 문제는 나중에 한쪽만 산문 기준이 바뀌면 어투와 맞춤법이 서로
77
+ * 다른 텍스트를 보게 되는 것이다. 산문 정의를 여기 한 군데로 모은다.
78
+ */
79
+ export declare function scanProse(text: string, ruleIds?: readonly string[]): {
80
+ detections: Detection[];
81
+ spacing: SpacingIssue[];
82
+ };
54
83
  //# sourceMappingURL=detectors.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"detectors.d.ts","sourceRoot":"","sources":["../../../src/humanize/detectors.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,MAAM,WAAW,SAAS;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AASD,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,YAAY;IAC3B,+CAA+C;IAC/C,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAED;;;;;;;GAOG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,YAAiB,GAAG,SAAS,EAAE,CAyBhF;AAoCD,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAKrD;AAqDD,eAAO,MAAM,mBAAmB,EAAE,MAAM,EAAmC,CAAC;AAE5E,wBAAgB,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,EAAE,CAgB7E;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAE1F;AAED,MAAM,WAAW,mBAAmB;IAClC,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;CACvB;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,mBAAmB,CAcrE;AAeD,kCAAkC;AAClC,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAStD;AAED,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CAE9E;AAID,MAAM,WAAW,cAAc;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,cAAc,CAS3D"}
1
+ {"version":3,"file":"detectors.d.ts","sourceRoot":"","sources":["../../../src/humanize/detectors.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,MAAM,WAAW,SAAS;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAgBD,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,YAAY;IAC3B,+CAA+C;IAC/C,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAED;;;;;;;GAOG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,YAAiB,GAAG,SAAS,EAAE,CAyBhF;AAgDD,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAKrD;AA4KD,eAAO,MAAM,mBAAmB,EAAE,MAAM,EAAmC,CAAC;AAE5E,wBAAgB,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,EAAE,CAE7E;AAoBD,oDAAoD;AACpD,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AA2BD;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,YAAY,EAAE,CAE1D;AAiBD,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAE1F;AAED,MAAM,WAAW,mBAAmB;IAClC,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;CACvB;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,mBAAmB,CAcrE;AAeD,kCAAkC;AAClC,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAStD;AAED,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CAE9E;AAID,MAAM,WAAW,cAAc;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,cAAc,CAS3D;AAED;;;;;;GAMG;AACH,wBAAgB,SAAS,CACvB,IAAI,EAAE,MAAM,EACZ,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,GAC1B;IAAE,UAAU,EAAE,SAAS,EAAE,CAAC;IAAC,OAAO,EAAE,YAAY,EAAE,CAAA;CAAE,CAGtD"}