legal-doc-editor 0.2.0 → 0.4.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 +33 -2
- package/dist/LegalEditor.d.ts +8 -2
- package/dist/citation.d.ts +18 -0
- package/dist/clauses.d.ts +8 -0
- package/dist/fees.d.ts +12 -2
- package/dist/index.d.ts +5 -3
- package/dist/index.js +309 -140
- package/dist/style.css +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
- 저장은 `.docx`와 `.hwpx`예요. `.hwpx`는 한글 2014 이상에서 열리고, 한글에서 `.hwp`로 다시 저장할 수 있어요
|
|
11
11
|
- 파일 변환 라이브러리는 필요할 때만 불러와서 에디터 본체 번들은 가벼워요
|
|
12
12
|
- **판례·법령 인용 링크**: 본문의 `민법 제750조`, `대법원 2016. 4. 28. 선고 2015다12345 판결`, `2024가단157033` 같은 인용을 알아보고 [국가법령정보센터](https://www.law.go.kr) 링크를 붙여요 (API 키가 필요 없어요)
|
|
13
|
+
- **조항 라이브러리**: 비밀유지·계약해지·관할법원 같은 자주 쓰는 조항을 골라 커서 위치에 넣어요. 조 번호는 알아서 다시 매겨져요
|
|
13
14
|
- **문서 템플릿**: 소장(대여금)·고소장(사기)·내용증명·지급명령 신청서를 `{{변수}}` 빈칸이 들어간 상태로 바로 시작해요
|
|
14
15
|
- **금액 표기**: 선택한 숫자를 `금 37,200,000원`이나 `금 삼천칠백이십만 원정(₩37,200,000)`으로 바꿔요
|
|
15
16
|
- **인쇄·PDF**: 비어 있는 변수는 손으로 쓰는 밑줄 칸으로 인쇄돼요
|
|
@@ -67,15 +68,42 @@ export default function Page() {
|
|
|
67
68
|
|
|
68
69
|
날짜(`2026. 9. 2.`), 전화번호, 계좌번호는 인용으로 보지 않아요. 다만 인용 인식은 글자 모양만 보는 것이라 놓치거나 잘못 잡을 수 있고, 링크가 가리키는 조문이 실제로 맞는지는 직접 확인해 주세요.
|
|
69
70
|
|
|
71
|
+
### 조항 라이브러리
|
|
72
|
+
|
|
73
|
+
`clauses`를 넘기면 오른쪽 패널에 조항 목록이 생겨요. 검색칸에서 제목이나 분류로 찾고, 누르면 커서 위치에 조항이 들어가요. 조항 안의 `{{변수}}`는 입력칸에 바로 나타나고 뒤쪽 조 번호는 알아서 밀려요.
|
|
74
|
+
|
|
75
|
+
```tsx
|
|
76
|
+
import { LegalEditor, clauses } from 'legal-doc-editor'
|
|
77
|
+
|
|
78
|
+
<LegalEditor clauses={clauses} />
|
|
79
|
+
// 내 조항 더하기
|
|
80
|
+
<LegalEditor clauses={[...clauses, { id: 'my-sla', title: '서비스 수준', category: '의무', html: '<h2>(서비스 수준)</h2><p>…</p>' }]} />
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
기본 조항: 목적, 계약기간(자동 연장), 비밀유지, 손해배상, 계약의 해제·해지, 불가항력, 권리·의무의 양도 금지, 통지, 분쟁 해결(관할법원), 완전합의 및 계약의 변경, 계약의 해석. 일반적인 경우를 위한 예시 문장이니 계약에 맞게 고쳐 쓰세요.
|
|
84
|
+
|
|
85
|
+
### 판례 검색
|
|
86
|
+
|
|
87
|
+
`searchCases`에 검색 함수를 넘기면 오른쪽 패널에 **판례 검색** 칸이 생겨요. 결과를 누르면 커서 위치에 `대법원 2016. 4. 28. 선고 2015다12345 판결` 같은 인용 문구가 들어가고, 인용 링크도 자동으로 붙어요.
|
|
88
|
+
|
|
89
|
+
```tsx
|
|
90
|
+
<LegalEditor searchCases={async (q) => (await fetch(`/api/cases?q=${encodeURIComponent(q)}`)).json()} />
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
라이브러리는 검색을 직접 부르지 않아요. 국가법령정보 공동활용 API는 발급받은 인증값이 필요해서 서버를 거쳐야 하거든요. 연결 예제는 [`examples/law-go-kr-proxy`](./examples/law-go-kr-proxy)에 있어요.
|
|
94
|
+
|
|
70
95
|
### 인지액·송달료 자동 계산
|
|
71
96
|
|
|
72
97
|
`<LegalEditor autoFees />`로 켜면, 입력값 `소가`(또는 `소송목적의 값`)를 넣었을 때 이름이 `인지액`·`송달료`로 시작하는 변수(예: `{{인지액 산정 필요}}`)를 계산해서 채워요. 직접 입력한 값이 있으면 그 값을 써요.
|
|
98
|
+
지급명령 신청서(`payment-order` 템플릿)는 `청구금액`을 넣으면 `{{독촉절차 인지대}}`·`{{독촉절차 송달료}}`·`{{독촉절차비용}}`(두 금액 합계)을 채워요.
|
|
73
99
|
|
|
74
100
|
| 항목 | 기준 | 근거 |
|
|
75
101
|
| --- | --- | --- |
|
|
76
102
|
| 인지액 | 1천만원 미만 × 0.5% / 1억원 미만 × 0.45% + 5천원 / 10억원 미만 × 0.4% + 5만5천원 / 그 이상 × 0.35% + 55만5천원. 100원 미만 버림, 최저 1천원 | 「민사소송 등 인지법」 제2조 |
|
|
77
103
|
| 전자소송 인지액 | 위 계산식 × 0.9 후 100원 미만 버림, 최저 900원 — `autoFees={{ electronic: true }}` | 인지법 제16조, [전자소송포털](https://ecfs.scourt.go.kr/psp/link.on?m=PSP007P01) |
|
|
78
104
|
| 송달료 | 당사자 수 × 회분 × 1회 송달료. 소가 3천만원 이하(소액) 10회분, 넘으면 15회분. 당사자 수 기본 2 — `autoFees={{ parties: 3 }}` | 「송달료규칙의 시행에 따른 업무처리요령」 별표 1, 「소액사건심판규칙」 제1조의2 |
|
|
105
|
+
| 지급명령 인지대 | 소장 인지액 계산식 × 1/10 후 같은 끝자리 처리 (예: 청구금액 300만원 → 1,500원). **전자신청 감액은 아직 반영하지 않음** | 인지법 제7조제2항·제4항 |
|
|
106
|
+
| 지급명령 송달료 | 당사자 수 × 6회분 × 1회 송달료 | 업무처리요령 별표 1 |
|
|
79
107
|
| 1회 송달료 | 5,500원 (2025. 6. 1.부터). 바뀌면 `autoFees={{ unitFee: 5600 }}`처럼 덮어쓰기 | 법원 공지 |
|
|
80
108
|
|
|
81
109
|
> 계산 결과는 **참고용**이에요. 제1심 소장 기준이고 항소·상고·반소는 계산하지 않아요. 실제 납부액은 법원 안내를 확인하세요.
|
|
@@ -95,9 +123,12 @@ export default function Page() {
|
|
|
95
123
|
|
|
96
124
|
| 이름 | 설명 |
|
|
97
125
|
| --- | --- |
|
|
98
|
-
| `<LegalEditor content values onChange onValuesChange editable autoFees />` | 에디터 컴포넌트 |
|
|
126
|
+
| `<LegalEditor content values onChange onValuesChange editable autoFees searchCases clauses />` | 에디터 컴포넌트 |
|
|
127
|
+
| `clauses` | 기본 조항 목록 `{ id, title, category, html }[]` |
|
|
128
|
+
| `formatCaseCitation(result)` | 판례 검색 결과 → `대법원 2016. 4. 28. 선고 2015다12345 판결` |
|
|
99
129
|
| `calcStampFee(소가, { electronic })` | 소장 인지액(원) |
|
|
100
|
-
| `
|
|
130
|
+
| `calcPaymentOrderStampFee(청구금액)` | 지급명령 신청서 인지대(원) — 종이 신청 기준 |
|
|
131
|
+
| `calcServiceFee({ parties, procedure, unitFee })` | 송달료(원). `procedure`: 소액·단독·합의·항소·상고·조정·독촉 |
|
|
101
132
|
| `withCourtFees(names, values, options)` | 비어 있는 `인지액…`·`송달료…` 변수를 계산값으로 채운 입력값 |
|
|
102
133
|
| `templates` | 기본 문서 템플릿 `{ id, title, description, html }[]` — `<LegalEditor content={templates[0].html} />` |
|
|
103
134
|
| `toKoreanAmount(n)` | `37200000` → `삼천칠백이십만` |
|
package/dist/LegalEditor.d.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { type Values } from './variable';
|
|
2
|
+
import { type CaseResult } from './citation';
|
|
3
|
+
import type { Clause } from './clauses';
|
|
2
4
|
import { type CourtFeeOptions } from './fees';
|
|
3
5
|
import './legal.css';
|
|
4
6
|
export interface LegalEditorProps {
|
|
@@ -9,7 +11,11 @@ export interface LegalEditorProps {
|
|
|
9
11
|
onChange?: (html: string) => void;
|
|
10
12
|
onValuesChange?: (values: Values) => void;
|
|
11
13
|
editable?: boolean;
|
|
12
|
-
/** 입력값에
|
|
14
|
+
/** 입력값에 `소가`(소장)나 `청구금액`(지급명령)이 있으면 인지액·송달료 변수를 계산해 채움 (직접 입력한 값이 우선, 참고용) */
|
|
13
15
|
autoFees?: boolean | CourtFeeOptions;
|
|
16
|
+
/** 판례 검색 함수. 넘기면 오른쪽에 판례 검색 칸이 생기고, 결과를 누르면 인용 문구가 커서 위치에 들어감 */
|
|
17
|
+
searchCases?: (query: string) => Promise<CaseResult[]>;
|
|
18
|
+
/** 조항 목록. 넘기면 오른쪽에 조항 라이브러리가 생기고, 누르면 커서 위치에 조항이 들어감 (기본 제공 목록: `clauses`) */
|
|
19
|
+
clauses?: Clause[];
|
|
14
20
|
}
|
|
15
|
-
export declare function LegalEditor({ content, values: initial, onChange, onValuesChange, editable, autoFees }: LegalEditorProps): import("react").JSX.Element;
|
|
21
|
+
export declare function LegalEditor({ content, values: initial, onChange, onValuesChange, editable, autoFees, searchCases, clauses }: LegalEditorProps): import("react").JSX.Element;
|
package/dist/citation.d.ts
CHANGED
|
@@ -11,5 +11,23 @@ export interface Citation {
|
|
|
11
11
|
}
|
|
12
12
|
/** 본문 글에서 판례·법령 인용을 찾음. 문서를 바꾸지 않고 위치만 알려줌 */
|
|
13
13
|
export declare function findCitations(text: string): Citation[];
|
|
14
|
+
/** 판례 검색 결과 한 건 — LegalEditor의 `searchCases`가 돌려주는 모양 */
|
|
15
|
+
export interface CaseResult {
|
|
16
|
+
/** 법원명: 대법원, 서울고등법원 … */
|
|
17
|
+
court: string;
|
|
18
|
+
/** 선고일자: "20160428", "2016-04-28", "2016.04.28" 모두 받음 */
|
|
19
|
+
date: string;
|
|
20
|
+
/** 사건번호: 2015다12345 */
|
|
21
|
+
caseNo: string;
|
|
22
|
+
/** 사건명 */
|
|
23
|
+
title: string;
|
|
24
|
+
/** 판결·결정·명령 (없으면 판결) */
|
|
25
|
+
kind?: string;
|
|
26
|
+
summary?: string;
|
|
27
|
+
/** 원문 보기 주소 */
|
|
28
|
+
url: string;
|
|
29
|
+
}
|
|
30
|
+
/** 검색 결과 → 본문 인용 문구: "대법원 2016. 4. 28. 선고 2015다12345 판결", 결정은 "대법원 2020. 1. 9.자 2019마123 결정" */
|
|
31
|
+
export declare function formatCaseCitation({ court, date, caseNo, kind }: CaseResult): string;
|
|
14
32
|
/** 판례·법령 인용에 밑줄과 국가법령정보센터 링크를 덧입힘. 문서 데이터(HTML·JSON)는 그대로 */
|
|
15
33
|
export declare const CitationLink: Extension<any, any>;
|
package/dist/fees.d.ts
CHANGED
|
@@ -8,9 +8,17 @@ import type { Values } from './variable';
|
|
|
8
8
|
export declare function calcStampFee(amount: number, opts?: {
|
|
9
9
|
electronic?: boolean;
|
|
10
10
|
}): number;
|
|
11
|
+
/**
|
|
12
|
+
* 지급명령 신청서 인지대. 「민사소송 등 인지법」 제7조제2항(제2조 금액의 10분의 1)·제4항(제2조제2항 준용)
|
|
13
|
+
* 예: 청구금액 3,000,000원 → (3,000,000 × 0.005) × 0.1 = 1,500원
|
|
14
|
+
* 출처: https://easylaw.go.kr/CSP/CnpClsMain.laf?popMenu=ov&csmSeq=568&ccfNo=3&cciNo=3&cnpClsNo=3 (확인 2026-09-15)
|
|
15
|
+
* ponytail: 종이 신청 기준. 전자신청 10분의 9 감액과 끝자리 처리 순서는 공식 안내로 확인하지 못해 아직 넣지 않음
|
|
16
|
+
*/
|
|
17
|
+
export declare function calcPaymentOrderStampFee(amount: number): number;
|
|
11
18
|
/**
|
|
12
19
|
* 송달료 회분. 「송달료규칙의 시행에 따른 업무처리요령」(재판예규 재일 87-4) 별표 1
|
|
13
20
|
* 출처: https://www.easylaw.go.kr/CSP/CnpClsMain.laf?csmSeq=568&ccfNo=2&cciNo=4&cnpClsNo=3 (확인 2026-09-15)
|
|
21
|
+
* 독촉(지급명령) 6회분: 생활법령정보 지급명령 신청서 작성 (위 calcPaymentOrderStampFee 출처와 같음)
|
|
14
22
|
*/
|
|
15
23
|
export declare const SERVICE_ROUNDS: {
|
|
16
24
|
readonly 소액: 10;
|
|
@@ -19,6 +27,7 @@ export declare const SERVICE_ROUNDS: {
|
|
|
19
27
|
readonly 항소: 12;
|
|
20
28
|
readonly 상고: 8;
|
|
21
29
|
readonly 조정: 5;
|
|
30
|
+
readonly 독촉: 6;
|
|
22
31
|
};
|
|
23
32
|
export type Procedure = keyof typeof SERVICE_ROUNDS;
|
|
24
33
|
/**
|
|
@@ -42,7 +51,8 @@ export interface CourtFeeOptions {
|
|
|
42
51
|
unitFee?: number;
|
|
43
52
|
}
|
|
44
53
|
/**
|
|
45
|
-
*
|
|
46
|
-
*
|
|
54
|
+
* 비어 있는 비용 변수를 계산값으로 채움. 직접 입력한 값은 덮어쓰지 않음.
|
|
55
|
+
* - 소장: `소가`(또는 `소송목적의 값`) → 이름이 `인지액`·`송달료`로 시작하는 변수 (소가 3천만원 이하 소액 10회분, 넘으면 15회분)
|
|
56
|
+
* - 지급명령: `청구금액` → `독촉절차 인지대`(소장의 10분의 1)·`독촉절차 송달료`(6회분)·`독촉절차비용`(두 금액 합계)
|
|
47
57
|
*/
|
|
48
58
|
export declare function withCourtFees(names: string[], values: Values, opts?: CourtFeeOptions): Values;
|
package/dist/index.d.ts
CHANGED
|
@@ -2,12 +2,14 @@ export { LegalEditor } from './LegalEditor';
|
|
|
2
2
|
export type { LegalEditorProps } from './LegalEditor';
|
|
3
3
|
export { Variable, fillTemplate, toChips } from './variable';
|
|
4
4
|
export { Numbering } from './numbering';
|
|
5
|
-
export { CitationLink, findCitations } from './citation';
|
|
6
|
-
export type { Citation } from './citation';
|
|
7
|
-
export { calcStampFee, calcServiceFee, withCourtFees, SERVICE_ROUNDS, SERVICE_UNIT_FEE, SMALL_CLAIM_LIMIT } from './fees';
|
|
5
|
+
export { CitationLink, findCitations, formatCaseCitation } from './citation';
|
|
6
|
+
export type { Citation, CaseResult } from './citation';
|
|
7
|
+
export { calcStampFee, calcPaymentOrderStampFee, calcServiceFee, withCourtFees, SERVICE_ROUNDS, SERVICE_UNIT_FEE, SMALL_CLAIM_LIMIT } from './fees';
|
|
8
8
|
export type { CourtFeeOptions, Procedure } from './fees';
|
|
9
9
|
export { toKoreanAmount, formatAmount, parseAmount } from './amount';
|
|
10
10
|
export { templates } from './templates';
|
|
11
|
+
export { clauses } from './clauses';
|
|
12
|
+
export type { Clause } from './clauses';
|
|
11
13
|
export type { Template } from './templates';
|
|
12
14
|
export type { Values } from './variable';
|
|
13
15
|
export { toDocx, toHwpx, toPlainHtml, fromDocx, fromHwp, fromFile, normalizeLegalHtml } from './io';
|
package/dist/index.js
CHANGED
|
@@ -7,7 +7,7 @@ import { Plugin as u, PluginKey as d } from "@tiptap/pm/state";
|
|
|
7
7
|
import { Decoration as f, DecorationSet as p } from "@tiptap/pm/view";
|
|
8
8
|
import { jsx as m, jsxs as h } from "react/jsx-runtime";
|
|
9
9
|
//#region src/variable.ts
|
|
10
|
-
var
|
|
10
|
+
var g = s.create({
|
|
11
11
|
name: "variable",
|
|
12
12
|
group: "inline",
|
|
13
13
|
inline: !0,
|
|
@@ -61,9 +61,9 @@ var ee = s.create({
|
|
|
61
61
|
getAttributes: (e) => ({ name: e[0].slice(2, -2).trim() })
|
|
62
62
|
})];
|
|
63
63
|
}
|
|
64
|
-
}),
|
|
65
|
-
function
|
|
66
|
-
let n = new DOMParser().parseFromString(
|
|
64
|
+
}), _ = (e) => e.replace(/\{\{([^{}<>"]+)\}\}/g, (e, t) => `<span data-var="${t.trim().replace(/&/g, "&")}"></span>`);
|
|
65
|
+
function v(e, t) {
|
|
66
|
+
let n = new DOMParser().parseFromString(_(e), "text/html");
|
|
67
67
|
return n.querySelectorAll("span[data-var]").forEach((e) => {
|
|
68
68
|
let n = e.getAttribute("data-var");
|
|
69
69
|
e.replaceWith(t[n] || `[${n}]`);
|
|
@@ -71,7 +71,7 @@ function _(e, t) {
|
|
|
71
71
|
}
|
|
72
72
|
//#endregion
|
|
73
73
|
//#region src/numbering.ts
|
|
74
|
-
var
|
|
74
|
+
var y = 4, b = o.create({
|
|
75
75
|
name: "numbering",
|
|
76
76
|
priority: 1e3,
|
|
77
77
|
addGlobalAttributes() {
|
|
@@ -81,7 +81,7 @@ var v = 4, y = o.create({
|
|
|
81
81
|
default: null,
|
|
82
82
|
parseHTML: (e) => {
|
|
83
83
|
let t = Number(e.getAttribute("data-num"));
|
|
84
|
-
return t >= 1 && t <=
|
|
84
|
+
return t >= 1 && t <= y ? t : null;
|
|
85
85
|
},
|
|
86
86
|
renderHTML: (e) => e.num ? { "data-num": e.num } : {}
|
|
87
87
|
} }
|
|
@@ -93,7 +93,7 @@ var v = 4, y = o.create({
|
|
|
93
93
|
addKeyboardShortcuts() {
|
|
94
94
|
let e = () => this.editor.getAttributes("paragraph").num, t = (t) => () => {
|
|
95
95
|
let n = e();
|
|
96
|
-
return !!n && this.editor.commands.setNumbering(Math.min(
|
|
96
|
+
return !!n && this.editor.commands.setNumbering(Math.min(y, Math.max(1, n + t)));
|
|
97
97
|
};
|
|
98
98
|
return {
|
|
99
99
|
Tab: t(1),
|
|
@@ -105,8 +105,8 @@ var v = 4, y = o.create({
|
|
|
105
105
|
Enter: () => !!e() && this.editor.state.selection.$from.parent.content.size === 0 && this.editor.commands.setNumbering(null)
|
|
106
106
|
};
|
|
107
107
|
}
|
|
108
|
-
}),
|
|
109
|
-
function
|
|
108
|
+
}), x = String.raw`(?<!\d)\d{4}(?![만억천년월일원])[가-힣]{1,3}\d{1,6}(?!\d)`, S = String.raw`(?:[가-힣]{0,6}법원(?:\s*[가-힣]{2,6}지원)?|헌법재판소)`, C = String.raw`\d{4}\.\s*\d{1,2}\.\s*\d{1,2}\.`, ee = String.raw`${S}\s*${C}\s*(?:선고|자)\s*(?<caseNo>${x})(?:\s*[,·]\s*${x})*\s*(?:전원합의체\s*)?(?:판결|결정|명령)`, w = String.raw`(?:[가-힣]+(?<![은는이가을를와과로며고여하한된])\s+){0,4}[가-힣]+에\s*관한\s*[가-힣]*법률?|[가-힣]+법률?`, T = String.raw`(?<lawName>${w})\s*제\s*(?<jo>\d+)\s*조(?:\s*의\s*(?<ui>\d+))?(?:\s*제\s*\d+\s*(?:항|호))*`, E = new RegExp(String.raw`${ee}|${T}|(?<bare>${x})`, "g"), D = /^[방불합위적탈편문어용수요기비사입공]법$/, O = (...e) => `https://www.law.go.kr/${e.map(encodeURIComponent).join("/")}`;
|
|
109
|
+
function k(e) {
|
|
110
110
|
let t = [];
|
|
111
111
|
for (let n of e.matchAll(E)) {
|
|
112
112
|
let e = n.groups, r = e.caseNo ?? e.bare;
|
|
@@ -122,10 +122,14 @@ function te(e) {
|
|
|
122
122
|
}
|
|
123
123
|
return t;
|
|
124
124
|
}
|
|
125
|
-
|
|
125
|
+
function A({ court: e, date: t, caseNo: n, kind: r = "" }) {
|
|
126
|
+
let i = t.match(/(\d{4})\D*(\d{1,2})\D*(\d{1,2})/), a = i ? `${i[1]}. ${+i[2]}. ${+i[3]}.` : t, o = /결정/.test(r) ? "결정" : /명령/.test(r) ? "명령" : "판결";
|
|
127
|
+
return o === "판결" ? `${e} ${a} 선고 ${n} 판결` : `${e} ${a}자 ${n} ${o}`;
|
|
128
|
+
}
|
|
129
|
+
var j = new d("citation"), M = (e) => {
|
|
126
130
|
let t = [];
|
|
127
131
|
return e.descendants((e, n) => {
|
|
128
|
-
if (e.isText) for (let r of
|
|
132
|
+
if (e.isText) for (let r of k(e.text)) t.push(f.inline(n + r.from, n + r.to, {
|
|
129
133
|
nodeName: "a",
|
|
130
134
|
class: "le-cite",
|
|
131
135
|
href: r.url,
|
|
@@ -134,17 +138,17 @@ var ne = new d("citation"), k = (e) => {
|
|
|
134
138
|
rel: "noopener noreferrer"
|
|
135
139
|
}));
|
|
136
140
|
}), p.create(e, t);
|
|
137
|
-
},
|
|
141
|
+
}, N = o.create({
|
|
138
142
|
name: "citationLink",
|
|
139
143
|
addProseMirrorPlugins() {
|
|
140
144
|
return [new u({
|
|
141
|
-
key:
|
|
145
|
+
key: j,
|
|
142
146
|
state: {
|
|
143
|
-
init: (e, { doc: t }) =>
|
|
144
|
-
apply: (e, t) => e.docChanged ?
|
|
147
|
+
init: (e, { doc: t }) => M(t),
|
|
148
|
+
apply: (e, t) => e.docChanged ? M(e.doc) : t
|
|
145
149
|
},
|
|
146
150
|
props: {
|
|
147
|
-
decorations: (e) =>
|
|
151
|
+
decorations: (e) => j.getState(e),
|
|
148
152
|
handleClick: (e, t, n) => {
|
|
149
153
|
let r = n.target.closest?.("a.le-cite");
|
|
150
154
|
return !r || e.editable && !n.ctrlKey && !n.metaKey ? !1 : (window.open(r.getAttribute("href"), "_blank", "noopener,noreferrer"), !0);
|
|
@@ -155,80 +159,99 @@ var ne = new d("citation"), k = (e) => {
|
|
|
155
159
|
});
|
|
156
160
|
//#endregion
|
|
157
161
|
//#region src/fees.ts
|
|
158
|
-
function
|
|
162
|
+
function P(e, t = {}) {
|
|
159
163
|
if (!(e > 0)) return 0;
|
|
160
|
-
let
|
|
161
|
-
return t.electronic ?
|
|
164
|
+
let n = F(e);
|
|
165
|
+
return t.electronic ? n < 1e7 ? 900 : Math.floor(n * 9 / 1e7) * 100 : n < 1e7 ? 1e3 : Math.floor(n / 1e6) * 100;
|
|
166
|
+
}
|
|
167
|
+
function F(e) {
|
|
168
|
+
let [t, n] = e < 1e7 ? [50, 0] : e < 1e8 ? [45, 5e3] : e < 1e9 ? [40, 55e3] : [35, 555e3];
|
|
169
|
+
return e * t + n * 1e4;
|
|
162
170
|
}
|
|
163
|
-
|
|
171
|
+
function I(e) {
|
|
172
|
+
if (!(e > 0)) return 0;
|
|
173
|
+
let t = F(e);
|
|
174
|
+
return t < 1e8 ? 1e3 : Math.floor(t / 1e7) * 100;
|
|
175
|
+
}
|
|
176
|
+
var L = {
|
|
164
177
|
소액: 10,
|
|
165
178
|
단독: 15,
|
|
166
179
|
합의: 15,
|
|
167
180
|
항소: 12,
|
|
168
181
|
상고: 8,
|
|
169
|
-
조정: 5
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
182
|
+
조정: 5,
|
|
183
|
+
독촉: 6
|
|
184
|
+
}, R = 5500;
|
|
185
|
+
function z({ parties: e, procedure: t, unitFee: n = R }) {
|
|
186
|
+
return e * L[t] * n;
|
|
173
187
|
}
|
|
174
|
-
var
|
|
175
|
-
function
|
|
176
|
-
let r = e.find((e) =>
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
188
|
+
var te = 3e7, B = (e) => `${e.toLocaleString("ko-KR")}원`, ne = (e = "") => Number(e.replace(/[^\d]/g, "")) || 0;
|
|
189
|
+
function re(e, t, n = {}) {
|
|
190
|
+
let r = (n) => ne(t[e.find((e) => n.test(e)) ?? ""]), i = { ...t }, a = (n, r) => {
|
|
191
|
+
for (let a of e) n.test(a) && !t[a]?.trim() && (i[a] = B(r));
|
|
192
|
+
}, o = n.parties ?? 2, s = r(/^(소가|소송목적의\s*값)/);
|
|
193
|
+
s && (a(/^인지(액|대)/, P(s, n)), a(/^송달료/, z({
|
|
194
|
+
parties: o,
|
|
195
|
+
procedure: s <= 3e7 ? "소액" : "단독",
|
|
181
196
|
unitFee: n.unitFee
|
|
182
|
-
}))
|
|
183
|
-
|
|
184
|
-
|
|
197
|
+
})));
|
|
198
|
+
let c = r(/^청구금액/);
|
|
199
|
+
if (c && e.some((e) => /^독촉절차/.test(e))) {
|
|
200
|
+
let e = /^독촉절차\s*인지(액|대)/, t = /^독촉절차\s*송달료/, i = I(c), s = z({
|
|
201
|
+
parties: o,
|
|
202
|
+
procedure: "독촉",
|
|
203
|
+
unitFee: n.unitFee
|
|
204
|
+
});
|
|
205
|
+
a(e, i), a(t, s), a(/^독촉절차\s*비용/, (r(e) || i) + (r(t) || s));
|
|
206
|
+
}
|
|
207
|
+
return s || c ? i : t;
|
|
185
208
|
}
|
|
186
209
|
//#endregion
|
|
187
210
|
//#region src/amount.ts
|
|
188
|
-
var
|
|
211
|
+
var ie = "영일이삼사오육칠팔구", ae = [
|
|
189
212
|
"천",
|
|
190
213
|
"백",
|
|
191
214
|
"십",
|
|
192
215
|
""
|
|
193
|
-
],
|
|
216
|
+
], oe = [
|
|
194
217
|
"",
|
|
195
218
|
"만",
|
|
196
219
|
"억",
|
|
197
220
|
"조",
|
|
198
221
|
"경"
|
|
199
222
|
];
|
|
200
|
-
function
|
|
223
|
+
function V(e) {
|
|
201
224
|
if (!Number.isSafeInteger(e)) throw RangeError(`금액은 정수여야 해요: ${e}`);
|
|
202
225
|
if (e === 0) return "영";
|
|
203
|
-
if (e < 0) return `마이너스 ${
|
|
226
|
+
if (e < 0) return `마이너스 ${V(-e)}`;
|
|
204
227
|
let t = "", n = String(e).padStart(Math.ceil(String(e).length / 4) * 4, "0");
|
|
205
228
|
for (let e = 0; e < n.length / 4; e++) {
|
|
206
229
|
let r = n.slice(e * 4, e * 4 + 4);
|
|
207
230
|
if (r !== "0000") {
|
|
208
|
-
for (let e = 0; e < 4; e++) r[e] !== "0" && (t +=
|
|
209
|
-
t +=
|
|
231
|
+
for (let e = 0; e < 4; e++) r[e] !== "0" && (t += ie[+r[e]] + ae[e]);
|
|
232
|
+
t += oe[n.length / 4 - 1 - e];
|
|
210
233
|
}
|
|
211
234
|
}
|
|
212
235
|
return t;
|
|
213
236
|
}
|
|
214
|
-
var
|
|
215
|
-
function
|
|
237
|
+
var H = (e) => Number(e.replace(/[^\d]/g, "")) || 0;
|
|
238
|
+
function U(e, t = "소장") {
|
|
216
239
|
let n = e.toLocaleString("ko-KR");
|
|
217
|
-
return t === "소장" ? `금 ${n}원` : `금 ${
|
|
240
|
+
return t === "소장" ? `금 ${n}원` : `금 ${V(e)} 원정(₩${n})`;
|
|
218
241
|
}
|
|
219
242
|
//#endregion
|
|
220
243
|
//#region src/io.ts
|
|
221
|
-
var
|
|
244
|
+
var se = (e) => e < 20 ? String.fromCharCode(9312 + e) : `${e + 1}.`, W = "가나다라마바사아자차카타파하", G = (e) => {
|
|
222
245
|
let t = "";
|
|
223
|
-
for (; e > 0; e = Math.floor(e / 14)) t =
|
|
246
|
+
for (; e > 0; e = Math.floor(e / 14)) t = W[--e % 14] + t;
|
|
224
247
|
return t;
|
|
225
|
-
},
|
|
248
|
+
}, ce = (e, t) => [
|
|
226
249
|
`${t}.`,
|
|
227
|
-
`${
|
|
250
|
+
`${G(t)}.`,
|
|
228
251
|
`(${t})`,
|
|
229
|
-
`(${
|
|
252
|
+
`(${G(t)})`
|
|
230
253
|
][e - 1];
|
|
231
|
-
function
|
|
254
|
+
function K(e, t) {
|
|
232
255
|
let n = [], r = 0, i = (e = []) => e.map((e) => {
|
|
233
256
|
if (e.type === "hardBreak") return {
|
|
234
257
|
text: "",
|
|
@@ -248,7 +271,7 @@ function H(e, t) {
|
|
|
248
271
|
bold: !0
|
|
249
272
|
})), o = (e, t) => e.content?.forEach((r, a) => r.content?.forEach((r, s) => {
|
|
250
273
|
if (r.type === "orderedList" || r.type === "bulletList") return o(r, t + 1);
|
|
251
|
-
let c = a + (e.attrs?.start ?? 1), l = s > 0 ? "" : e.type === "bulletList" ? "•" : t === 0 ?
|
|
274
|
+
let c = a + (e.attrs?.start ?? 1), l = s > 0 ? "" : e.type === "bulletList" ? "•" : t === 0 ? se(c - 1) : `${c}.`;
|
|
252
275
|
n.push({
|
|
253
276
|
kind: "para",
|
|
254
277
|
label: l,
|
|
@@ -281,7 +304,7 @@ function H(e, t) {
|
|
|
281
304
|
runs: a(i(t.content))
|
|
282
305
|
}) : t.type === "orderedList" || t.type === "bulletList" ? o(t, 0) : l ? (s[l]++, s.fill(0, l + 1), n.push({
|
|
283
306
|
kind: "para",
|
|
284
|
-
label:
|
|
307
|
+
label: ce(l, s[l]),
|
|
285
308
|
depth: l,
|
|
286
309
|
runs: i(t.content)
|
|
287
310
|
})) : t.type === "paragraph" ? n.push({
|
|
@@ -304,29 +327,29 @@ function H(e, t) {
|
|
|
304
327
|
};
|
|
305
328
|
return c(e.content), n;
|
|
306
329
|
}
|
|
307
|
-
var
|
|
330
|
+
var le = (e) => e.replace(/[&<>"]/g, (e) => `&#${e.charCodeAt(0)};`), q = (e) => e.map((e) => {
|
|
308
331
|
if (e.br) return "<br>";
|
|
309
|
-
let t =
|
|
332
|
+
let t = le(e.text);
|
|
310
333
|
return e.bold && (t = `<b>${t}</b>`), e.italics && (t = `<i>${t}</i>`), e.underline && (t = `<u>${t}</u>`), e.strike && (t = `<s>${t}</s>`), t;
|
|
311
334
|
}).join("");
|
|
312
|
-
function
|
|
313
|
-
return
|
|
335
|
+
function ue(e, t) {
|
|
336
|
+
return K(e, t).map((e) => {
|
|
314
337
|
if (e.kind === "table") {
|
|
315
|
-
let t = (e) => `<td${e.colspan > 1 ? ` colspan="${e.colspan}"` : ""}${e.rowspan > 1 ? ` rowspan="${e.rowspan}"` : ""}>${
|
|
338
|
+
let t = (e) => `<td${e.colspan > 1 ? ` colspan="${e.colspan}"` : ""}${e.rowspan > 1 ? ` rowspan="${e.rowspan}"` : ""}>${q(e.runs)}</td>`;
|
|
316
339
|
return `<table>${e.rows.map((e) => `<tr>${e.map(t).join("")}</tr>`).join("")}</table>`;
|
|
317
340
|
}
|
|
318
|
-
let t = (e.label ? e.kind === "article" ? `<b>${e.label}</b> ` : `${e.label} ` : "") +
|
|
341
|
+
let t = (e.label ? e.kind === "article" ? `<b>${e.label}</b> ` : `${e.label} ` : "") + q(e.runs);
|
|
319
342
|
if (e.kind === "title") return `<h1>${t}</h1>`;
|
|
320
343
|
if (e.kind === "section") return `<h3>${t}</h3>`;
|
|
321
344
|
let n = e.label ? e.depth - 1 : e.depth;
|
|
322
345
|
return n > 0 ? `<p style="margin-left:${n * 2}em">${t}</p>` : `<p>${t}</p>`;
|
|
323
346
|
}).join("\n");
|
|
324
347
|
}
|
|
325
|
-
function
|
|
326
|
-
for (let n of
|
|
348
|
+
function de(e, t) {
|
|
349
|
+
for (let n of K(e, t)) if (n.kind === "title") return n.runs.map((e) => e.text).join("").trim() || "문서";
|
|
327
350
|
return "문서";
|
|
328
351
|
}
|
|
329
|
-
async function
|
|
352
|
+
async function fe(e, t) {
|
|
330
353
|
let { AlignmentType: n, Document: r, HeadingLevel: i, Packer: a, Paragraph: o, Table: s, TableCell: c, TableRow: l, TextRun: u, WidthType: d } = await import("docx"), f = (e) => new u({
|
|
331
354
|
text: e.text,
|
|
332
355
|
break: e.br ? 1 : void 0,
|
|
@@ -334,7 +357,7 @@ async function K(e, t) {
|
|
|
334
357
|
italics: e.italics,
|
|
335
358
|
strike: e.strike,
|
|
336
359
|
underline: e.underline ? {} : void 0
|
|
337
|
-
}), p =
|
|
360
|
+
}), p = K(e, t).map((e) => e.kind === "table" ? new s({
|
|
338
361
|
width: {
|
|
339
362
|
size: 100,
|
|
340
363
|
type: d.PERCENTAGE
|
|
@@ -358,7 +381,7 @@ async function K(e, t) {
|
|
|
358
381
|
})] : [], ...e.runs.map(f)]
|
|
359
382
|
}));
|
|
360
383
|
return a.toBlob(new r({
|
|
361
|
-
title:
|
|
384
|
+
title: de(e, t),
|
|
362
385
|
styles: {
|
|
363
386
|
default: { document: { run: {
|
|
364
387
|
font: "바탕",
|
|
@@ -383,18 +406,18 @@ async function K(e, t) {
|
|
|
383
406
|
sections: [{ children: p }]
|
|
384
407
|
}));
|
|
385
408
|
}
|
|
386
|
-
async function
|
|
387
|
-
let { htmlToHwpx: n } = await import("hwp-convert"), r = await n(
|
|
409
|
+
async function pe(e, t) {
|
|
410
|
+
let { htmlToHwpx: n } = await import("hwp-convert"), r = await n(ue(e, t), { title: de(e, t) });
|
|
388
411
|
return new Blob([r], { type: "application/hwp+zip" });
|
|
389
412
|
}
|
|
390
|
-
var J = /^\s*제\s*\d+\s*조(?:의\s*\d+)?\s*/,
|
|
413
|
+
var J = /^\s*제\s*\d+\s*조(?:의\s*\d+)?\s*/, me = /^\s*[①-⑳]\s*/, Y = /^\s*(\d+)\.\s*/, he = /^(청구취지|청구원인|신청취지|신청이유|고소취지|고소이유|고발취지|고발이유|입증방법|증명방법|증거방법|증거서류|첨부서류|당사자관계|사건개요|고소인|피고소인|범죄사실|증거자료|관련사건의수사및재판여부|기타)$/, ge = (e) => e.length <= 20 && (/^[가-힣](\s+[가-힣]){3,7}$/.test(e) || he.test(e.replace(/\s/g, ""))), _e = /\[\s*([^[\]{}<>"\d=]{1,20}?)\s*\]/g, ve = [
|
|
391
414
|
[/^\s*(\d{1,2})\.(?!\d)\s*/, Number],
|
|
392
|
-
[/^\s*([가나다라마바사아자차카타파하])\.\s*/, (e) =>
|
|
415
|
+
[/^\s*([가나다라마바사아자차카타파하])\.\s*/, (e) => W.indexOf(e) + 1],
|
|
393
416
|
[/^\s*\((\d{1,2})\)\s*/, Number],
|
|
394
|
-
[/^\s*\(([가나다라마바사아자차카타파하])\)\s*/, (e) =>
|
|
417
|
+
[/^\s*\(([가나다라마바사아자차카타파하])\)\s*/, (e) => W.indexOf(e) + 1]
|
|
395
418
|
];
|
|
396
|
-
function
|
|
397
|
-
for (let [t, [n, r]] of
|
|
419
|
+
function ye(e) {
|
|
420
|
+
for (let [t, [n, r]] of ve.entries()) {
|
|
398
421
|
let i = e.match(n);
|
|
399
422
|
if (i) return {
|
|
400
423
|
level: t + 1,
|
|
@@ -404,20 +427,20 @@ function he(e) {
|
|
|
404
427
|
}
|
|
405
428
|
return null;
|
|
406
429
|
}
|
|
407
|
-
function
|
|
430
|
+
function X(e, t) {
|
|
408
431
|
let n = typeof t == "number" ? t : e.textContent.match(t)[0].length, r = e.ownerDocument.createTreeWalker(e, NodeFilter.SHOW_TEXT);
|
|
409
432
|
for (let e = r.nextNode(); e && n > 0; e = r.nextNode()) {
|
|
410
433
|
let t = Math.min(n, e.data.length);
|
|
411
434
|
e.data = e.data.slice(t), n -= t;
|
|
412
435
|
}
|
|
413
436
|
}
|
|
414
|
-
function
|
|
437
|
+
function Z(e) {
|
|
415
438
|
let t = new DOMParser().parseFromString(e, "text/html");
|
|
416
439
|
for (let e of [...t.body.children]) e.tagName === "P" && !e.textContent.trim() && !e.querySelector("img") && e.remove();
|
|
417
440
|
let n = t.createTreeWalker(t.body, NodeFilter.SHOW_TEXT);
|
|
418
441
|
for (let e = n.nextNode(); e; e = n.nextNode()) {
|
|
419
442
|
let t = e.parentElement?.closest("p,li,td,th,h1,h2,h3")?.textContent?.trim();
|
|
420
|
-
e.data = e.data.replace(
|
|
443
|
+
e.data = e.data.replace(_e, (e, n) => e.trim() === t ? e : `{{${n.trim()}}}`);
|
|
421
444
|
}
|
|
422
445
|
let r = t.body.firstElementChild, i = r?.textContent.trim() ?? "";
|
|
423
446
|
if (!t.querySelector("h1") && r?.tagName === "P" && i.length <= 30 && !/[.다]$/.test(i) && !J.test(i)) {
|
|
@@ -439,62 +462,62 @@ function Q(e) {
|
|
|
439
462
|
];
|
|
440
463
|
for (let e of [...t.body.children]) {
|
|
441
464
|
let n = e.textContent ?? "", r = n.replace(/\s+/g, " ").trim();
|
|
442
|
-
if (e.tagName === "P" &&
|
|
465
|
+
if (e.tagName === "P" && ge(r)) {
|
|
443
466
|
let n = t.createElement("h3");
|
|
444
467
|
n.textContent = r, e.replaceWith(n), a = null, o.fill(0), s.fill(0);
|
|
445
468
|
} else if (e.tagName === "P" && J.test(n)) {
|
|
446
469
|
let n = t.createElement("h2");
|
|
447
|
-
n.innerHTML = e.innerHTML,
|
|
448
|
-
} else if (e.tagName === "P" &&
|
|
470
|
+
n.innerHTML = e.innerHTML, X(n, J), e.replaceWith(n), a = null, o.fill(0), s.fill(0);
|
|
471
|
+
} else if (e.tagName === "P" && me.test(n)) {
|
|
449
472
|
let r = n.trim().charCodeAt(0) - 9311;
|
|
450
|
-
(!a || a.children.length + Number(a.getAttribute("start") ?? 1) !== r) && (e.before(a = t.createElement("ol")), r > 1 && a.setAttribute("start", String(r))),
|
|
473
|
+
(!a || a.children.length + Number(a.getAttribute("start") ?? 1) !== r) && (e.before(a = t.createElement("ol")), r > 1 && a.setAttribute("start", String(r))), X(e, me);
|
|
451
474
|
let i = t.createElement("li");
|
|
452
475
|
i.append(e), a.append(i);
|
|
453
|
-
} else if (e.tagName === "P" && a &&
|
|
476
|
+
} else if (e.tagName === "P" && a && Y.test(n) && Number(n.match(Y)[1]) === (a.lastElementChild.querySelector(":scope > ol")?.children.length ?? 0) + 1) {
|
|
454
477
|
let n = a.lastElementChild, r = n.querySelector(":scope > ol") ?? n.appendChild(t.createElement("ol"));
|
|
455
|
-
|
|
478
|
+
X(e, Y);
|
|
456
479
|
let i = t.createElement("li");
|
|
457
480
|
i.append(e), r.append(i);
|
|
458
481
|
} else {
|
|
459
482
|
a = null;
|
|
460
|
-
let t = e.tagName === "P" ?
|
|
483
|
+
let t = e.tagName === "P" ? ye(n) : null;
|
|
461
484
|
if (!t) continue;
|
|
462
|
-
s[t.level] && t.n === s[t.level] + 1 ? s[t.level]++ : t.n === o[t.level] + 1 ? (o[t.level]++, o.fill(0, t.level + 1), s.fill(0),
|
|
485
|
+
s[t.level] && t.n === s[t.level] + 1 ? s[t.level]++ : t.n === o[t.level] + 1 ? (o[t.level]++, o.fill(0, t.level + 1), s.fill(0), X(e, t.length), e.setAttribute("data-num", String(t.level))) : s[t.level] = +(t.n === 1);
|
|
463
486
|
}
|
|
464
487
|
}
|
|
465
488
|
return t.body.innerHTML;
|
|
466
489
|
}
|
|
467
|
-
async function
|
|
490
|
+
async function be(e) {
|
|
468
491
|
let { default: t } = await import("mammoth"), { value: n } = await t.convertToHtml({ arrayBuffer: await e.arrayBuffer() });
|
|
469
|
-
return
|
|
492
|
+
return Z(n);
|
|
470
493
|
}
|
|
471
|
-
async function
|
|
494
|
+
async function xe(e) {
|
|
472
495
|
let { detectFormat: t, hwpToHwpx: n, HwpxReader: r } = await import("hwp-convert"), i = new Uint8Array(await e.arrayBuffer());
|
|
473
496
|
t(i) === "hwp" && (i = new Uint8Array(await n(i)));
|
|
474
497
|
let a = new r();
|
|
475
|
-
return await a.loadFromArrayBuffer(i.buffer),
|
|
498
|
+
return await a.loadFromArrayBuffer(i.buffer), Z(await a.extractHtml());
|
|
476
499
|
}
|
|
477
|
-
function
|
|
478
|
-
return /\.docx$/i.test(e.name) ?
|
|
500
|
+
function Q(e) {
|
|
501
|
+
return /\.docx$/i.test(e.name) ? be(e) : /\.hwpx?$/i.test(e.name) ? xe(e) : Promise.reject(/* @__PURE__ */ Error(".docx, .hwp, .hwpx 파일만 열 수 있어요"));
|
|
479
502
|
}
|
|
480
503
|
//#endregion
|
|
481
504
|
//#region src/LegalEditor.tsx
|
|
482
|
-
function
|
|
505
|
+
function $(e) {
|
|
483
506
|
let t = /* @__PURE__ */ new Set();
|
|
484
507
|
return e.state.doc.descendants((e) => {
|
|
485
508
|
e.type.name === "variable" && t.add(e.attrs.name);
|
|
486
509
|
}), [...t];
|
|
487
510
|
}
|
|
488
|
-
function
|
|
511
|
+
function Se() {
|
|
489
512
|
let e = document.documentElement;
|
|
490
513
|
e.classList.add("le-printing"), window.addEventListener("afterprint", () => e.classList.remove("le-printing"), { once: !0 }), window.print();
|
|
491
514
|
}
|
|
492
|
-
function
|
|
515
|
+
function Ce(e, t) {
|
|
493
516
|
let n = document.createElement("a");
|
|
494
517
|
n.href = URL.createObjectURL(e), n.download = t, n.click(), setTimeout(() => URL.revokeObjectURL(n.href), 1e3);
|
|
495
518
|
}
|
|
496
|
-
function
|
|
497
|
-
let [
|
|
519
|
+
function we({ content: o = "", values: s = {}, onChange: c, onValuesChange: l, editable: u = !0, autoFees: d, searchCases: f, clauses: p }) {
|
|
520
|
+
let [v, y] = t(s), [x, S] = t([]), [C, ee] = t(""), [w, T] = t(null), [E, D] = t(""), [O, k] = t(""), j = d ? re(x, v, d === !0 ? {} : d) : v, M = r({
|
|
498
521
|
extensions: [
|
|
499
522
|
i.configure({ heading: { levels: [
|
|
500
523
|
1,
|
|
@@ -502,71 +525,81 @@ function xe({ content: o = "", values: s = {}, onChange: c, onValuesChange: l, e
|
|
|
502
525
|
3
|
|
503
526
|
] } }),
|
|
504
527
|
a,
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
528
|
+
g,
|
|
529
|
+
b,
|
|
530
|
+
N
|
|
508
531
|
],
|
|
509
|
-
content:
|
|
532
|
+
content: _(o),
|
|
510
533
|
editable: u,
|
|
511
534
|
immediatelyRender: !1,
|
|
512
535
|
editorProps: { attributes: { class: "legal-doc" } },
|
|
513
|
-
onCreate: ({ editor: e }) =>
|
|
536
|
+
onCreate: ({ editor: e }) => S($(e)),
|
|
514
537
|
onUpdate: ({ editor: e }) => {
|
|
515
|
-
|
|
538
|
+
S($(e)), c?.(e.getHTML());
|
|
516
539
|
}
|
|
517
540
|
});
|
|
518
541
|
e(() => {
|
|
519
|
-
|
|
520
|
-
}, [
|
|
521
|
-
let
|
|
542
|
+
M && (M.storage.variable.values = j, M.storage.variable.views.forEach((e) => e()));
|
|
543
|
+
}, [M, j]);
|
|
544
|
+
let P = (e, t) => {
|
|
522
545
|
let n = {
|
|
523
|
-
...
|
|
546
|
+
...v,
|
|
524
547
|
[e]: t
|
|
525
548
|
};
|
|
526
|
-
|
|
527
|
-
},
|
|
549
|
+
y(n), l?.(n);
|
|
550
|
+
}, F = () => {
|
|
528
551
|
let e = window.prompt("변수 이름 (예: 갑, 계약일)")?.replace(/[{}<>"]/g, "").trim();
|
|
529
|
-
e &&
|
|
552
|
+
e && M?.chain().focus().insertContent({
|
|
530
553
|
type: "variable",
|
|
531
554
|
attrs: { name: e }
|
|
532
555
|
}).run();
|
|
533
|
-
},
|
|
556
|
+
}, I = async (e) => {
|
|
534
557
|
let t = e.target.files?.[0];
|
|
535
|
-
if (e.target.value = "", t &&
|
|
536
|
-
|
|
558
|
+
if (e.target.value = "", t && M) try {
|
|
559
|
+
M.commands.setContent(_(await Q(t)), { emitUpdate: !0 });
|
|
537
560
|
} catch (e) {
|
|
538
561
|
window.alert(`파일을 열 수 없어요: ${e.message}`);
|
|
539
562
|
}
|
|
540
|
-
},
|
|
541
|
-
let n =
|
|
542
|
-
|
|
543
|
-
},
|
|
544
|
-
let
|
|
545
|
-
|
|
563
|
+
}, L = async (e, t) => {
|
|
564
|
+
let n = M.state.doc.firstChild?.textContent.trim() || "문서";
|
|
565
|
+
Ce(await e(M.getJSON(), j), `${n}.${t}`);
|
|
566
|
+
}, R = async () => {
|
|
567
|
+
let e = C.trim();
|
|
568
|
+
if (f && e) {
|
|
569
|
+
D("검색 중…");
|
|
570
|
+
try {
|
|
571
|
+
T(await f(e)), D("");
|
|
572
|
+
} catch (e) {
|
|
573
|
+
T(null), D(`검색하지 못했어요: ${e.message}`);
|
|
574
|
+
}
|
|
575
|
+
}
|
|
576
|
+
}, z = () => M.chain().focus(), te = (e) => z().setNumbering(M.getAttributes("paragraph").num === e ? null : e).run(), B = (e) => {
|
|
577
|
+
let { from: t, to: n } = M.state.selection, r = H(M.state.doc.textBetween(t, n));
|
|
578
|
+
r && z().insertContentAt({
|
|
546
579
|
from: t,
|
|
547
580
|
to: n
|
|
548
|
-
},
|
|
581
|
+
}, U(r, e)).run();
|
|
549
582
|
};
|
|
550
583
|
return /* @__PURE__ */ h("div", {
|
|
551
584
|
className: "le-root",
|
|
552
585
|
children: [/* @__PURE__ */ h("div", {
|
|
553
586
|
className: "le-main",
|
|
554
|
-
children: [u &&
|
|
587
|
+
children: [u && M && /* @__PURE__ */ h("div", {
|
|
555
588
|
className: "le-toolbar",
|
|
556
589
|
children: [
|
|
557
590
|
/* @__PURE__ */ m("button", {
|
|
558
591
|
type: "button",
|
|
559
|
-
onClick: () =>
|
|
592
|
+
onClick: () => z().toggleHeading({ level: 1 }).run(),
|
|
560
593
|
children: "제목"
|
|
561
594
|
}),
|
|
562
595
|
/* @__PURE__ */ m("button", {
|
|
563
596
|
type: "button",
|
|
564
|
-
onClick: () =>
|
|
597
|
+
onClick: () => z().toggleHeading({ level: 3 }).run(),
|
|
565
598
|
children: "소제목"
|
|
566
599
|
}),
|
|
567
600
|
/* @__PURE__ */ m("button", {
|
|
568
601
|
type: "button",
|
|
569
|
-
onClick: () =>
|
|
602
|
+
onClick: () => z().toggleHeading({ level: 2 }).run(),
|
|
570
603
|
children: "조"
|
|
571
604
|
}),
|
|
572
605
|
[
|
|
@@ -577,37 +610,37 @@ function xe({ content: o = "", values: s = {}, onChange: c, onValuesChange: l, e
|
|
|
577
610
|
].map((e, t) => /* @__PURE__ */ m("button", {
|
|
578
611
|
type: "button",
|
|
579
612
|
title: "번호 문단 — Tab·Shift+Tab 단계 변경, 맨 앞 Backspace 해제",
|
|
580
|
-
onClick: () =>
|
|
613
|
+
onClick: () => te(t + 1),
|
|
581
614
|
children: e
|
|
582
615
|
}, e)),
|
|
583
616
|
/* @__PURE__ */ m("button", {
|
|
584
617
|
type: "button",
|
|
585
|
-
onClick: () =>
|
|
618
|
+
onClick: () => z().toggleOrderedList().run(),
|
|
586
619
|
children: "항"
|
|
587
620
|
}),
|
|
588
621
|
/* @__PURE__ */ m("button", {
|
|
589
622
|
type: "button",
|
|
590
|
-
onClick: () =>
|
|
623
|
+
onClick: () => z().sinkListItem("listItem").run(),
|
|
591
624
|
children: "호 →"
|
|
592
625
|
}),
|
|
593
626
|
/* @__PURE__ */ m("button", {
|
|
594
627
|
type: "button",
|
|
595
|
-
onClick: () =>
|
|
628
|
+
onClick: () => z().liftListItem("listItem").run(),
|
|
596
629
|
children: "← 내어쓰기"
|
|
597
630
|
}),
|
|
598
631
|
/* @__PURE__ */ m("button", {
|
|
599
632
|
type: "button",
|
|
600
|
-
onClick: () =>
|
|
633
|
+
onClick: () => z().toggleBold().run(),
|
|
601
634
|
children: /* @__PURE__ */ m("b", { children: "B" })
|
|
602
635
|
}),
|
|
603
636
|
/* @__PURE__ */ h("button", {
|
|
604
637
|
type: "button",
|
|
605
|
-
onClick:
|
|
638
|
+
onClick: F,
|
|
606
639
|
children: ["{{ }}", " 변수"]
|
|
607
640
|
}),
|
|
608
641
|
/* @__PURE__ */ m("button", {
|
|
609
642
|
type: "button",
|
|
610
|
-
onClick: () =>
|
|
643
|
+
onClick: () => z().insertTable({
|
|
611
644
|
rows: 3,
|
|
612
645
|
cols: 3,
|
|
613
646
|
withHeaderRow: !1
|
|
@@ -617,13 +650,13 @@ function xe({ content: o = "", values: s = {}, onChange: c, onValuesChange: l, e
|
|
|
617
650
|
/* @__PURE__ */ m("button", {
|
|
618
651
|
type: "button",
|
|
619
652
|
title: "선택한 금액 → 금 37,200,000원",
|
|
620
|
-
onClick: () =>
|
|
653
|
+
onClick: () => B("소장"),
|
|
621
654
|
children: "금액"
|
|
622
655
|
}),
|
|
623
656
|
/* @__PURE__ */ m("button", {
|
|
624
657
|
type: "button",
|
|
625
658
|
title: "선택한 금액 → 금 삼천칠백이십만 원정(₩37,200,000)",
|
|
626
|
-
onClick: () =>
|
|
659
|
+
onClick: () => B("계약서"),
|
|
627
660
|
children: "금액(한글)"
|
|
628
661
|
}),
|
|
629
662
|
/* @__PURE__ */ m("span", { className: "le-spacer" }),
|
|
@@ -633,31 +666,31 @@ function xe({ content: o = "", values: s = {}, onChange: c, onValuesChange: l, e
|
|
|
633
666
|
type: "file",
|
|
634
667
|
accept: ".docx,.hwp,.hwpx",
|
|
635
668
|
hidden: !0,
|
|
636
|
-
onChange:
|
|
669
|
+
onChange: I
|
|
637
670
|
})]
|
|
638
671
|
}),
|
|
639
672
|
/* @__PURE__ */ m("button", {
|
|
640
673
|
type: "button",
|
|
641
|
-
onClick: () =>
|
|
674
|
+
onClick: () => L(fe, "docx"),
|
|
642
675
|
children: "Word 저장"
|
|
643
676
|
}),
|
|
644
677
|
/* @__PURE__ */ m("button", {
|
|
645
678
|
type: "button",
|
|
646
|
-
onClick: () =>
|
|
679
|
+
onClick: () => L(pe, "hwpx"),
|
|
647
680
|
children: "한글 저장"
|
|
648
681
|
}),
|
|
649
682
|
/* @__PURE__ */ m("button", {
|
|
650
683
|
type: "button",
|
|
651
|
-
onClick:
|
|
684
|
+
onClick: Se,
|
|
652
685
|
children: "인쇄 · PDF"
|
|
653
686
|
})
|
|
654
687
|
]
|
|
655
|
-
}), /* @__PURE__ */ m(n, { editor:
|
|
688
|
+
}), /* @__PURE__ */ m(n, { editor: M })]
|
|
656
689
|
}), /* @__PURE__ */ h("aside", {
|
|
657
690
|
className: "le-panel",
|
|
658
691
|
children: [
|
|
659
692
|
/* @__PURE__ */ m("h3", { children: "입력값" }),
|
|
660
|
-
|
|
693
|
+
x.length === 0 && /* @__PURE__ */ h("p", {
|
|
661
694
|
className: "le-hint",
|
|
662
695
|
children: [
|
|
663
696
|
"본문에 ",
|
|
@@ -665,18 +698,87 @@ function xe({ content: o = "", values: s = {}, onChange: c, onValuesChange: l, e
|
|
|
665
698
|
"처럼 입력하면 변수가 생겨요."
|
|
666
699
|
]
|
|
667
700
|
}),
|
|
668
|
-
|
|
669
|
-
value:
|
|
670
|
-
placeholder:
|
|
671
|
-
onChange: (t) =>
|
|
672
|
-
})] }, e))
|
|
701
|
+
x.map((e) => /* @__PURE__ */ h("label", { children: [e, /* @__PURE__ */ m("input", {
|
|
702
|
+
value: v[e] ?? "",
|
|
703
|
+
placeholder: v[e] ? void 0 : j[e],
|
|
704
|
+
onChange: (t) => P(e, t.target.value)
|
|
705
|
+
})] }, e)),
|
|
706
|
+
p && /* @__PURE__ */ h("section", {
|
|
707
|
+
className: "le-clauses",
|
|
708
|
+
children: [
|
|
709
|
+
/* @__PURE__ */ m("h3", { children: "조항 라이브러리" }),
|
|
710
|
+
/* @__PURE__ */ m("input", {
|
|
711
|
+
value: O,
|
|
712
|
+
placeholder: "조항 찾기 (예: 해지)",
|
|
713
|
+
onChange: (e) => k(e.target.value)
|
|
714
|
+
}),
|
|
715
|
+
/* @__PURE__ */ m("ul", {
|
|
716
|
+
className: "le-clause-list",
|
|
717
|
+
children: p.filter((e) => `${e.category} ${e.title}`.includes(O.trim())).map((e) => /* @__PURE__ */ m("li", { children: /* @__PURE__ */ h("button", {
|
|
718
|
+
type: "button",
|
|
719
|
+
disabled: !u,
|
|
720
|
+
title: "커서 위치에 조항 넣기",
|
|
721
|
+
onClick: () => M?.chain().focus().insertContent(_(e.html), { parseOptions: { preserveWhitespace: !1 } }).run(),
|
|
722
|
+
children: [/* @__PURE__ */ m("small", { children: e.category }), e.title]
|
|
723
|
+
}) }, e.id))
|
|
724
|
+
})
|
|
725
|
+
]
|
|
726
|
+
}),
|
|
727
|
+
f && /* @__PURE__ */ h("section", {
|
|
728
|
+
className: "le-cases",
|
|
729
|
+
children: [
|
|
730
|
+
/* @__PURE__ */ m("h3", { children: "판례 검색" }),
|
|
731
|
+
/* @__PURE__ */ h("div", {
|
|
732
|
+
className: "le-cases-bar",
|
|
733
|
+
children: [/* @__PURE__ */ m("input", {
|
|
734
|
+
value: C,
|
|
735
|
+
placeholder: "사건명·사건번호·키워드",
|
|
736
|
+
onChange: (e) => ee(e.target.value),
|
|
737
|
+
onKeyDown: (e) => {
|
|
738
|
+
e.key === "Enter" && !e.nativeEvent.isComposing && (e.preventDefault(), R());
|
|
739
|
+
}
|
|
740
|
+
}), /* @__PURE__ */ m("button", {
|
|
741
|
+
type: "button",
|
|
742
|
+
onClick: R,
|
|
743
|
+
children: "검색"
|
|
744
|
+
})]
|
|
745
|
+
}),
|
|
746
|
+
E && /* @__PURE__ */ m("p", {
|
|
747
|
+
className: "le-hint",
|
|
748
|
+
children: E
|
|
749
|
+
}),
|
|
750
|
+
!E && w?.length === 0 && /* @__PURE__ */ m("p", {
|
|
751
|
+
className: "le-hint",
|
|
752
|
+
children: "결과가 없어요."
|
|
753
|
+
}),
|
|
754
|
+
/* @__PURE__ */ m("ul", {
|
|
755
|
+
className: "le-case-list",
|
|
756
|
+
children: w?.map((e) => /* @__PURE__ */ h("li", { children: [/* @__PURE__ */ h("button", {
|
|
757
|
+
type: "button",
|
|
758
|
+
disabled: !u,
|
|
759
|
+
title: "커서 위치에 인용 넣기",
|
|
760
|
+
onClick: () => M?.chain().focus().insertContent(A(e)).run(),
|
|
761
|
+
children: [
|
|
762
|
+
/* @__PURE__ */ m("strong", { children: e.title }),
|
|
763
|
+
/* @__PURE__ */ m("span", { children: A(e) }),
|
|
764
|
+
e.summary && /* @__PURE__ */ m("small", { children: e.summary })
|
|
765
|
+
]
|
|
766
|
+
}), /* @__PURE__ */ m("a", {
|
|
767
|
+
href: e.url,
|
|
768
|
+
target: "_blank",
|
|
769
|
+
rel: "noopener noreferrer",
|
|
770
|
+
children: "원문"
|
|
771
|
+
})] }, `${e.caseNo}-${e.date}`))
|
|
772
|
+
})
|
|
773
|
+
]
|
|
774
|
+
})
|
|
673
775
|
]
|
|
674
776
|
})]
|
|
675
777
|
});
|
|
676
778
|
}
|
|
677
779
|
//#endregion
|
|
678
780
|
//#region src/templates.ts
|
|
679
|
-
var
|
|
781
|
+
var Te = [
|
|
680
782
|
{
|
|
681
783
|
id: "complaint-loan",
|
|
682
784
|
title: "소장 (대여금)",
|
|
@@ -701,6 +803,73 @@ var Se = [
|
|
|
701
803
|
description: "재판 없이 법원의 지급명령을 받는 독촉절차 신청서. 인지대는 소장의 10분의 1, 송달료는 당사자 수 × 6회분",
|
|
702
804
|
html: "\n<h1>지 급 명 령 신 청 서</h1>\n<p>채 권 자 {{채권자 이름}}</p>\n<p>주소 {{채권자 주소}}</p>\n<p>연락처 {{채권자 연락처}}</p>\n<p>채 무 자 {{채무자 이름}}</p>\n<p>주소 {{채무자 주소}}</p>\n<p>대여금 청구 독촉사건</p>\n<p>청구금액 {{청구금액}}</p>\n<h3>신 청 취 지</h3>\n<p>채무자는 채권자에게 아래 청구금액 및 독촉절차비용을 지급하라는 명령을 구합니다.</p>\n<p data-num=\"1\">{{청구금액}}</p>\n<p data-num=\"1\">위 금액에 대하여 {{변제기 다음 날}}부터 이 사건 지급명령정본을 송달받은 날까지는 연 5%의, 그 다음 날부터 다 갚는 날까지는 연 12%의 각 비율로 계산한 돈</p>\n<p data-num=\"1\">독촉절차비용 {{독촉절차비용}} (인지대 {{독촉절차 인지대}}, 송달료 {{독촉절차 송달료}})</p>\n<h3>신 청 이 유</h3>\n<p data-num=\"1\">채권자는 {{대여일}} 채무자에게 {{청구금액}}을 변제기 {{변제기}}로 정하여 빌려주었습니다.</p>\n<p data-num=\"1\">그러나 채무자는 변제기가 지났는데도 위 돈을 갚지 않고 있습니다.</p>\n<p data-num=\"1\">따라서 채권자는 채무자에게 위 청구금액과 지연손해금 및 독촉절차비용의 지급을 구하기 위하여 이 신청에 이르렀습니다.</p>\n<h3>첨 부 서 류</h3>\n<p data-num=\"1\">차용증 사본 1통</p>\n<p data-num=\"1\">송달료 납부서 1통</p>\n<p>{{작성일}}</p>\n<p>채권자 {{채권자 이름}} (서명 또는 날인)</p>\n<p>{{관할 법원}} 귀중</p>\n"
|
|
703
805
|
}
|
|
806
|
+
], Ee = [
|
|
807
|
+
{
|
|
808
|
+
id: "purpose",
|
|
809
|
+
title: "목적",
|
|
810
|
+
category: "일반",
|
|
811
|
+
html: "<h2>(목적)</h2>\n<p>이 계약은 {{갑}}과 {{을}} 사이의 {{계약 대상}}에 관한 권리와 의무를 정하는 것을 목적으로 한다.</p>"
|
|
812
|
+
},
|
|
813
|
+
{
|
|
814
|
+
id: "term",
|
|
815
|
+
title: "계약기간",
|
|
816
|
+
category: "기간",
|
|
817
|
+
html: "<h2>(계약기간)</h2>\n<ol>\n <li><p>이 계약의 기간은 {{시작일}}부터 {{종료일}}까지로 한다.</p></li>\n <li><p>기간 만료 {{통지 기한}} 전까지 어느 당사자도 서면으로 종료 의사를 알리지 않으면, 이 계약은 같은 조건으로 {{연장 기간}} 연장된 것으로 본다.</p></li>\n</ol>"
|
|
818
|
+
},
|
|
819
|
+
{
|
|
820
|
+
id: "confidentiality",
|
|
821
|
+
title: "비밀유지",
|
|
822
|
+
category: "의무",
|
|
823
|
+
html: "<h2>(비밀유지)</h2>\n<ol>\n <li><p>각 당사자는 이 계약과 관련하여 알게 된 상대방의 기술상·경영상 정보를 상대방의 사전 서면 동의 없이 제3자에게 공개하거나 이 계약의 목적 외에 사용하지 아니한다.</p></li>\n <li><p>제1항의 의무는 이 계약이 끝난 뒤에도 {{비밀유지 기간}} 동안 유지된다.</p></li>\n</ol>"
|
|
824
|
+
},
|
|
825
|
+
{
|
|
826
|
+
id: "damages",
|
|
827
|
+
title: "손해배상",
|
|
828
|
+
category: "책임",
|
|
829
|
+
html: "<h2>(손해배상)</h2>\n<p>어느 당사자가 이 계약을 위반하여 상대방에게 손해를 입힌 경우 그 손해를 배상하여야 한다.</p>"
|
|
830
|
+
},
|
|
831
|
+
{
|
|
832
|
+
id: "termination",
|
|
833
|
+
title: "계약의 해제·해지",
|
|
834
|
+
category: "종료",
|
|
835
|
+
html: "<h2>(계약의 해제·해지)</h2>\n<ol>\n <li><p>어느 당사자가 이 계약을 위반한 경우 상대방은 {{시정 기간}} 이상의 기간을 정하여 서면으로 시정을 요구하고, 그 기간 안에 시정되지 않으면 이 계약을 해제 또는 해지할 수 있다.</p></li>\n <li><p>다음 각 호의 어느 하나에 해당하면 상대방은 최고 없이 이 계약을 해제 또는 해지할 수 있다.</p>\n <ol>\n <li><p>어음·수표가 부도 처리되거나 파산·회생절차 개시 신청이 있는 경우</p></li>\n <li><p>강제집행, 가압류 또는 가처분을 받아 이 계약을 이행하기 어려운 경우</p></li>\n </ol>\n </li>\n <li><p>제1항 및 제2항에 따른 해제 또는 해지는 손해배상 청구에 영향을 미치지 아니한다.</p></li>\n</ol>"
|
|
836
|
+
},
|
|
837
|
+
{
|
|
838
|
+
id: "force-majeure",
|
|
839
|
+
title: "불가항력",
|
|
840
|
+
category: "책임",
|
|
841
|
+
html: "<h2>(불가항력)</h2>\n<p>천재지변, 전쟁, 감염병 확산, 정부의 조치 등 당사자가 통제할 수 없는 사유로 이 계약을 이행하지 못한 경우 그 당사자는 이행 지체나 불이행에 대한 책임을 지지 아니한다. 다만, 그 사유가 생긴 사실을 지체 없이 상대방에게 알려야 한다.</p>"
|
|
842
|
+
},
|
|
843
|
+
{
|
|
844
|
+
id: "no-assignment",
|
|
845
|
+
title: "권리·의무의 양도 금지",
|
|
846
|
+
category: "일반",
|
|
847
|
+
html: "<h2>(권리·의무의 양도 금지)</h2>\n<p>어느 당사자도 상대방의 사전 서면 동의 없이 이 계약상의 권리나 의무의 전부 또는 일부를 제3자에게 양도하거나 담보로 제공할 수 없다.</p>"
|
|
848
|
+
},
|
|
849
|
+
{
|
|
850
|
+
id: "notice",
|
|
851
|
+
title: "통지",
|
|
852
|
+
category: "일반",
|
|
853
|
+
html: "<h2>(통지)</h2>\n<ol>\n <li><p>이 계약에 따른 통지는 서면으로 하며, 각 당사자가 이 계약서에 적은 주소나 {{통지 받을 이메일}}로 보내어 상대방에게 도달한 때에 효력이 생긴다.</p></li>\n <li><p>주소나 연락처가 바뀐 당사자는 지체 없이 상대방에게 알려야 한다.</p></li>\n</ol>"
|
|
854
|
+
},
|
|
855
|
+
{
|
|
856
|
+
id: "dispute",
|
|
857
|
+
title: "분쟁 해결 (관할법원)",
|
|
858
|
+
category: "분쟁",
|
|
859
|
+
html: "<h2>(분쟁 해결)</h2>\n<ol>\n <li><p>이 계약과 관련하여 분쟁이 생기면 당사자는 먼저 성실히 협의하여 해결한다.</p></li>\n <li><p>협의로 해결되지 않은 분쟁에 관한 소송은 {{관할 법원}}을 제1심 관할법원으로 한다.</p></li>\n</ol>"
|
|
860
|
+
},
|
|
861
|
+
{
|
|
862
|
+
id: "entire-agreement",
|
|
863
|
+
title: "완전합의 및 계약의 변경",
|
|
864
|
+
category: "일반",
|
|
865
|
+
html: "<h2>(완전합의 및 계약의 변경)</h2>\n<ol>\n <li><p>이 계약은 계약 대상에 관한 당사자 사이의 완전한 합의이며, 이 계약 전에 있었던 구두 또는 서면의 합의보다 우선한다.</p></li>\n <li><p>이 계약의 변경은 당사자가 서명 또는 날인한 서면으로만 할 수 있다.</p></li>\n</ol>"
|
|
866
|
+
},
|
|
867
|
+
{
|
|
868
|
+
id: "interpretation",
|
|
869
|
+
title: "계약의 해석",
|
|
870
|
+
category: "일반",
|
|
871
|
+
html: "<h2>(계약의 해석)</h2>\n<p>이 계약에서 정하지 않은 사항이나 해석에 다툼이 있는 사항은 당사자가 서로 협의하여 정하고, 협의가 되지 않으면 관계 법령과 일반 거래 관행에 따른다.</p>"
|
|
872
|
+
}
|
|
704
873
|
];
|
|
705
874
|
//#endregion
|
|
706
|
-
export {
|
|
875
|
+
export { N as CitationLink, we as LegalEditor, b as Numbering, L as SERVICE_ROUNDS, R as SERVICE_UNIT_FEE, te as SMALL_CLAIM_LIMIT, g as Variable, I as calcPaymentOrderStampFee, z as calcServiceFee, P as calcStampFee, Ee as clauses, v as fillTemplate, k as findCitations, U as formatAmount, A as formatCaseCitation, be as fromDocx, Q as fromFile, xe as fromHwp, Z as normalizeLegalHtml, H as parseAmount, Te as templates, _ as toChips, fe as toDocx, pe as toHwpx, V as toKoreanAmount, ue as toPlainHtml, re as withCourtFees };
|
package/dist/style.css
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
@counter-style le-circled{system:fixed;symbols:"①" "②" "③" "④" "⑤" "⑥" "⑦" "⑧" "⑨" "⑩" "⑪" "⑫" "⑬" "⑭" "⑮" "⑯" "⑰" "⑱" "⑲" "⑳";suffix:" "}.legal-doc{counter-reset:le-article le-n1 le-n2 le-n3 le-n4;color:#111;background:#fff;outline:none;max-width:760px;margin:0 auto;padding:56px 64px;font-family:Noto Serif KR,Nanum Myeongjo,Batang,serif;font-size:15px;line-height:1.85}.legal-doc h1{text-align:center;letter-spacing:.25em;margin:0 0 1.6em;font-size:1.6em}.legal-doc h2{counter-increment:le-article;margin:1.6em 0 .3em;font-size:1em}.legal-doc h2:before{content:"제" counter(le-article) "조 "}.legal-doc p{margin:0 0 .4em}.legal-doc ol{margin:0 0 .4em;padding-left:1.8em;list-style:le-circled}.legal-doc ol ol{list-style:decimal}.legal-doc li p{margin:0}.legal-doc h3{text-align:center;letter-spacing:.3em;margin:1.8em 0 .8em;font-size:1.05em}.legal-doc>h1,.legal-doc>h2,.legal-doc>h3{counter-set:le-n1 le-n2 le-n3 le-n4}.legal-doc>p[data-num]{padding-left:calc(var(--le-num-indent,0em) + 2em);text-indent:-2em}.legal-doc>p[data-num]:before{text-indent:0;min-width:2em;display:inline-block}.legal-doc>p[data-num="1"]{counter-increment:le-n1;counter-set:le-n2 le-n3 le-n4}.legal-doc>p[data-num="2"]{counter-increment:le-n2;counter-set:le-n3 le-n4;--le-num-indent:1.2em}.legal-doc>p[data-num="3"]{counter-increment:le-n3;counter-set:le-n4;--le-num-indent:2.4em}.legal-doc>p[data-num="4"]{counter-increment:le-n4;--le-num-indent:3.6em}.legal-doc>p[data-num="1"]:before{content:counter(le-n1) "."}.legal-doc>p[data-num="2"]:before{content:counter(le-n2, hangul) "."}.legal-doc>p[data-num="3"]:before{content:"(" counter(le-n3) ")"}.legal-doc>p[data-num="4"]:before{content:"(" counter(le-n4, hangul) ")"}.legal-doc .le-cite{color:inherit;text-underline-offset:3px;cursor:pointer;-webkit-text-decoration:underline dotted #3a56b4;text-decoration:underline dotted #3a56b4}.legal-doc .le-cite:hover{background:#eef2ff}.legal-doc .tableWrapper{overflow-x:auto}.legal-doc table{border-collapse:collapse;width:100%;margin:.6em 0;font-size:.93em}.legal-doc td,.legal-doc th{vertical-align:top;border:1px solid #555;padding:3px 6px}.legal-doc td p,.legal-doc th p{margin:0}.legal-doc .selectedCell{background:#e5edff}.le-root{background:#eef0f3;grid-template-columns:minmax(0,1fr) 260px;gap:16px;padding:16px;font:14px/1.5 system-ui,sans-serif;display:grid}.le-main{min-width:0}.le-toolbar{z-index:1;background:#fff;border-radius:8px;flex-wrap:wrap;gap:4px;max-width:760px;margin:0 auto 8px;padding:6px;display:flex;position:sticky;top:0;box-shadow:0 1px 2px #0001}.le-toolbar button,.le-toolbar .le-btn{cursor:pointer;font:inherit;background:#fff;border:1px solid #d0d4da;border-radius:6px;padding:4px 10px}.le-toolbar button:hover{background:#f3f5f8}.le-spacer{flex:1}.le-main .legal-doc{min-height:900px;box-shadow:0 1px 4px #0002}.le-var{color:#1d3f94;background:#e5edff;border-radius:3px;padding:0 3px}.le-var--empty{color:#8a5a00;background:#fff1c2}.le-panel{background:#fff;border-radius:8px;align-self:start;padding:14px;position:sticky;top:16px;box-shadow:0 1px 2px #0001}.le-panel h3{margin:0 0 10px;font-size:14px}.le-panel label{color:#444;gap:3px;margin-bottom:10px;font-size:13px;display:grid}.le-panel input{font:inherit;border:1px solid #d0d4da;border-radius:6px;padding:6px 8px}.le-hint{color:#777;margin:0;font-size:13px}@media (width<=800px){.le-root{grid-template-columns:1fr}.legal-doc{padding:32px 24px}}@media print{.le-printing body *{visibility:hidden}.le-printing .legal-doc,.le-printing .legal-doc *{visibility:visible}.le-printing .legal-doc{width:100%;max-width:none;box-shadow:none;padding:0;position:absolute;top:0;left:0}.le-printing .le-var{color:inherit;background:0 0;padding:0}.le-printing .le-cite{background:0 0;text-decoration:none}.le-printing .le-var--empty{color:#0000;border-bottom:1px solid #000}}
|
|
1
|
+
@counter-style le-circled{system:fixed;symbols:"①" "②" "③" "④" "⑤" "⑥" "⑦" "⑧" "⑨" "⑩" "⑪" "⑫" "⑬" "⑭" "⑮" "⑯" "⑰" "⑱" "⑲" "⑳";suffix:" "}.legal-doc{counter-reset:le-article le-n1 le-n2 le-n3 le-n4;color:#111;background:#fff;outline:none;max-width:760px;margin:0 auto;padding:56px 64px;font-family:Noto Serif KR,Nanum Myeongjo,Batang,serif;font-size:15px;line-height:1.85}.legal-doc h1{text-align:center;letter-spacing:.25em;margin:0 0 1.6em;font-size:1.6em}.legal-doc h2{counter-increment:le-article;margin:1.6em 0 .3em;font-size:1em}.legal-doc h2:before{content:"제" counter(le-article) "조 "}.legal-doc p{margin:0 0 .4em}.legal-doc ol{margin:0 0 .4em;padding-left:1.8em;list-style:le-circled}.legal-doc ol ol{list-style:decimal}.legal-doc li p{margin:0}.legal-doc h3{text-align:center;letter-spacing:.3em;margin:1.8em 0 .8em;font-size:1.05em}.legal-doc>h1,.legal-doc>h2,.legal-doc>h3{counter-set:le-n1 le-n2 le-n3 le-n4}.legal-doc>p[data-num]{padding-left:calc(var(--le-num-indent,0em) + 2em);text-indent:-2em}.legal-doc>p[data-num]:before{text-indent:0;min-width:2em;display:inline-block}.legal-doc>p[data-num="1"]{counter-increment:le-n1;counter-set:le-n2 le-n3 le-n4}.legal-doc>p[data-num="2"]{counter-increment:le-n2;counter-set:le-n3 le-n4;--le-num-indent:1.2em}.legal-doc>p[data-num="3"]{counter-increment:le-n3;counter-set:le-n4;--le-num-indent:2.4em}.legal-doc>p[data-num="4"]{counter-increment:le-n4;--le-num-indent:3.6em}.legal-doc>p[data-num="1"]:before{content:counter(le-n1) "."}.legal-doc>p[data-num="2"]:before{content:counter(le-n2, hangul) "."}.legal-doc>p[data-num="3"]:before{content:"(" counter(le-n3) ")"}.legal-doc>p[data-num="4"]:before{content:"(" counter(le-n4, hangul) ")"}.legal-doc .le-cite{color:inherit;text-underline-offset:3px;cursor:pointer;-webkit-text-decoration:underline dotted #3a56b4;text-decoration:underline dotted #3a56b4}.legal-doc .le-cite:hover{background:#eef2ff}.legal-doc .tableWrapper{overflow-x:auto}.legal-doc table{border-collapse:collapse;width:100%;margin:.6em 0;font-size:.93em}.legal-doc td,.legal-doc th{vertical-align:top;border:1px solid #555;padding:3px 6px}.legal-doc td p,.legal-doc th p{margin:0}.legal-doc .selectedCell{background:#e5edff}.le-root{background:#eef0f3;grid-template-columns:minmax(0,1fr) 260px;gap:16px;padding:16px;font:14px/1.5 system-ui,sans-serif;display:grid}.le-main{min-width:0}.le-toolbar{z-index:1;background:#fff;border-radius:8px;flex-wrap:wrap;gap:4px;max-width:760px;margin:0 auto 8px;padding:6px;display:flex;position:sticky;top:0;box-shadow:0 1px 2px #0001}.le-toolbar button,.le-toolbar .le-btn{cursor:pointer;font:inherit;background:#fff;border:1px solid #d0d4da;border-radius:6px;padding:4px 10px}.le-toolbar button:hover{background:#f3f5f8}.le-spacer{flex:1}.le-main .legal-doc{min-height:900px;box-shadow:0 1px 4px #0002}.le-var{color:#1d3f94;background:#e5edff;border-radius:3px;padding:0 3px}.le-var--empty{color:#8a5a00;background:#fff1c2}.le-panel{background:#fff;border-radius:8px;align-self:start;padding:14px;position:sticky;top:16px;box-shadow:0 1px 2px #0001}.le-panel h3{margin:0 0 10px;font-size:14px}.le-panel label{color:#444;gap:3px;margin-bottom:10px;font-size:13px;display:grid}.le-panel input{font:inherit;border:1px solid #d0d4da;border-radius:6px;padding:6px 8px}.le-hint{color:#777;margin:0;font-size:13px}.le-cases{border-top:1px solid #e3e6ea;margin-top:16px;padding-top:12px}.le-cases-bar{gap:4px;margin-bottom:8px;display:flex}.le-cases-bar input{flex:1;min-width:0}.le-cases-bar button,.le-case-list button{cursor:pointer;font:inherit;background:#fff;border:1px solid #d0d4da;border-radius:6px;padding:4px 8px}.le-case-list{gap:6px;margin:8px 0 0;padding:0;list-style:none;display:grid}.le-case-list li{gap:2px;display:grid}.le-case-list button{text-align:left;gap:2px;font-size:12px;display:grid}.le-case-list button:hover:not(:disabled){background:#f3f5f8}.le-case-list span,.le-case-list small{color:#555}.le-case-list a{color:#3a56b4;justify-self:end;font-size:12px}.le-clauses{border-top:1px solid #e3e6ea;margin-top:16px;padding-top:12px}.le-clauses>input{box-sizing:border-box;width:100%;margin-bottom:6px}.le-clause-list{gap:4px;max-height:280px;margin:0;padding:0;list-style:none;display:grid;overflow-y:auto}.le-clause-list button{cursor:pointer;text-align:left;width:100%;font:inherit;background:#fff;border:1px solid #d0d4da;border-radius:6px;padding:4px 8px;font-size:12px}.le-clause-list button:hover:not(:disabled){background:#f3f5f8}.le-clause-list small{color:#3a56b4;margin-right:6px}@media (width<=800px){.le-root{grid-template-columns:1fr}.legal-doc{padding:32px 24px}}@media print{.le-printing body *{visibility:hidden}.le-printing .legal-doc,.le-printing .legal-doc *{visibility:visible}.le-printing .legal-doc{width:100%;max-width:none;box-shadow:none;padding:0;position:absolute;top:0;left:0}.le-printing .le-var{color:inherit;background:0 0;padding:0}.le-printing .le-cite{background:0 0;text-decoration:none}.le-printing .le-var--empty{color:#0000;border-bottom:1px solid #000}}
|
|
2
2
|
/*$vite$:1*/
|