python-hwpx 2.29.1__py3-none-any.whl → 3.0.0__py3-none-any.whl

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 (44) hide show
  1. hwpx/agent/blueprint/dump.py +0 -1
  2. hwpx/agent/blueprint/native.py +0 -1
  3. hwpx/benchmark/blind_eval.py +1 -1
  4. hwpx/conformance/corpus/meeting_summary.hwpx +0 -0
  5. hwpx/conformance/corpus/notice.hwpx +0 -0
  6. hwpx/conformance/corpus/report_table.hwpx +0 -0
  7. hwpx/data/Skeleton.hwpx +0 -0
  8. hwpx/design/profiles/official_notice/profile.json +2 -2
  9. hwpx/document.py +4 -4
  10. hwpx/evalplan_fill.py +3 -5
  11. hwpx/form_fit/seal.py +2 -3
  12. hwpx/formfill_quality.py +0 -1
  13. hwpx/oxml/__init__.py +2 -0
  14. hwpx/oxml/_document_impl.py +6 -1
  15. hwpx/oxml/body.py +1 -1
  16. hwpx/oxml/document.py +0 -1
  17. hwpx/oxml/header.py +2 -2
  18. hwpx/table_patch.py +23 -1
  19. hwpx/tools/fuzz/runner.py +0 -1
  20. hwpx/tools/toc_fidelity.py +1 -1
  21. hwpx/visual/detectors.py +1 -2
  22. hwpx/visual/hancom_worker.py +0 -1
  23. {python_hwpx-2.29.1.dist-info → python_hwpx-3.0.0.dist-info}/METADATA +3 -2
  24. {python_hwpx-2.29.1.dist-info → python_hwpx-3.0.0.dist-info}/RECORD +29 -44
  25. hwpx/practice/__init__.py +0 -277
  26. hwpx/practice/aggregate.py +0 -947
  27. hwpx/practice/campaign.py +0 -296
  28. hwpx/practice/domain.py +0 -3137
  29. hwpx/practice/dossier.py +0 -78
  30. hwpx/practice/evaluator.py +0 -2359
  31. hwpx/practice/forge.py +0 -436
  32. hwpx/practice/intake.py +0 -230
  33. hwpx/practice/lineage.py +0 -113
  34. hwpx/practice/mutations.py +0 -168
  35. hwpx/practice/registry.py +0 -322
  36. hwpx/practice/run.py +0 -757
  37. hwpx/practice/sanitize.py +0 -154
  38. hwpx/practice/scenario.py +0 -146
  39. hwpx/practice/split.py +0 -249
  40. {python_hwpx-2.29.1.dist-info → python_hwpx-3.0.0.dist-info}/WHEEL +0 -0
  41. {python_hwpx-2.29.1.dist-info → python_hwpx-3.0.0.dist-info}/entry_points.txt +0 -0
  42. {python_hwpx-2.29.1.dist-info → python_hwpx-3.0.0.dist-info}/licenses/LICENSE +0 -0
  43. {python_hwpx-2.29.1.dist-info → python_hwpx-3.0.0.dist-info}/licenses/NOTICE +0 -0
  44. {python_hwpx-2.29.1.dist-info → python_hwpx-3.0.0.dist-info}/top_level.txt +0 -0
@@ -16,7 +16,6 @@ from ..document import HwpxAgentDocument, NodeRecord
16
16
  from ..model import AGENT_CATALOG_SCHEMA, NODE_KINDS, AgentContractError
17
17
  from .bundle import (
18
18
  ALLOWED_MEDIA_TYPES,
19
- BlueprintBundle,
20
19
  build_blueprint_bundle,
21
20
  read_blueprint_bundle,
22
21
  write_blueprint_bundle,
@@ -11,7 +11,6 @@ from dataclasses import dataclass
11
11
  from typing import Any
12
12
 
13
13
  from hwpx.document import HwpxDocument
14
- from hwpx.oxml import HwpxOxmlTable
15
14
  from hwpx.oxml.namespaces import HH, HP
16
15
 
17
16
  from ..commands import _add, _insert_direct_child, _insert_inline, _remove_inline_element, _table_caption
@@ -12,7 +12,7 @@ import json
12
12
  import math
13
13
  from collections import Counter, defaultdict
14
14
  from pathlib import Path
15
- from typing import Any, Mapping, Sequence
15
+ from typing import Any, Mapping
16
16
 
17
17
  BENCHMARK_SCHEMA = "hwpx.blind-real-work-eval/v1"
18
18
  RESULT_SCHEMA = "hwpx.blind-real-work-eval-result/v1"
Binary file
Binary file
hwpx/data/Skeleton.hwpx CHANGED
Binary file
@@ -21,5 +21,5 @@
21
21
  },
22
22
  "char_pr_count": 65,
23
23
  "style_coverage_threshold": 0.98,
24
- "source_basename": "경기도교육청 미래교육담당관_교육용 상용클라우드서비스 이용 안내.hwpx"
25
- }
24
+ "source_basename": "synthetic_official_notice_source.hwpx"
25
+ }
hwpx/document.py CHANGED
@@ -5,19 +5,16 @@ from __future__ import annotations
5
5
 
6
6
  import xml.etree.ElementTree as ET
7
7
  import io
8
- import os
9
8
  import re
10
- import tempfile
11
9
  import warnings
12
10
  from datetime import datetime
13
11
  import logging
14
12
  import uuid
15
13
 
16
14
  from os import PathLike
17
- from pathlib import Path, PurePosixPath
15
+ from pathlib import PurePosixPath
18
16
  from typing import TYPE_CHECKING, Any, BinaryIO, Iterator, Mapping, Sequence, overload
19
17
 
20
- from lxml import etree
21
18
 
22
19
  from .oxml import (
23
20
  Bullet,
@@ -65,6 +62,9 @@ _HWP_UNITS_PER_PT = 100
65
62
  logger = logging.getLogger(__name__)
66
63
 
67
64
  if TYPE_CHECKING:
65
+ from .form_fit.policy import FitPolicy
66
+ from .form_fit.report import FitResult
67
+ from .tools.validator import ValidationReport
68
68
  from .tools.table_navigation import TableFillResult, TableLabelSearchResult, TableMapResult
69
69
 
70
70
 
hwpx/evalplan_fill.py CHANGED
@@ -18,7 +18,7 @@ from __future__ import annotations
18
18
 
19
19
  import re
20
20
  from dataclasses import dataclass, field
21
- from typing import Any
21
+ from typing import Any, Sequence
22
22
 
23
23
  _CIRCLED = "①②③④⑤⑥⑦⑧⑨⑩⑪⑫⑬⑭⑮"
24
24
 
@@ -327,7 +327,7 @@ def _pick_achieve_rate(tabs, want_bands: int | None) -> int | None:
327
327
 
328
328
  def _regular_exam_cols(table) -> list[int]:
329
329
  """Logical column indices of the 정기시험 span in a 반영비율 table header."""
330
- from .table_patch import build_grid, _direct_cells, _text_of
330
+ from .table_patch import build_grid, _text_of
331
331
  tb = table.bytes
332
332
  grid, rep = build_grid(tb)
333
333
  cols: list[int] = []
@@ -1084,7 +1084,7 @@ def fill_rubrics(data: bytes, content: EvalPlanContent) -> tuple[bytes, dict[str
1084
1084
  cells (title / points / 성취기준 / A~E / 수행과제 / 평가요소 leaders / 기본점수 배점),
1085
1085
  reshapes+fills the 수행수준 채점기준 ladder, and rewrites each rubric's ordinal
1086
1086
  heading paragraph (가./나./다. + sample project title) to the review 영역명."""
1087
- from .table_patch import apply_table_ops, fill_cells, _text_of, _all_paragraph_spans
1087
+ from .table_patch import apply_table_ops, fill_cells, _all_paragraph_spans
1088
1088
 
1089
1089
  report: dict[str, Any] = {"rubrics": len(content.rubrics), "filled": 0, "skipped": []}
1090
1090
  levels = content.levels
@@ -1122,7 +1122,6 @@ def fill_rubrics(data: bytes, content: EvalPlanContent) -> tuple[bytes, dict[str
1122
1122
  if hdr is None or base is None:
1123
1123
  report["skipped"].append(f"rubric {i}: could not bound item block")
1124
1124
  continue
1125
- item_rows = base - (hdr + 1) # blank example block height (7)
1126
1125
  first_item = hdr + 1
1127
1126
  todel = list(range(first_item + n, base)) # keep n, drop the surplus
1128
1127
  if todel:
@@ -1471,7 +1470,6 @@ def fill_ratio(data: bytes, content: EvalPlanContent) -> tuple[bytes, dict[str,
1471
1470
  return data, report
1472
1471
  _sp, tb, grid, rep = _grid_of(data, ti)
1473
1472
  label_col, area_cols, total_col = _ratio_columns(tb, grid, rep)
1474
- areas = _area_names(content)
1475
1473
  if not area_cols:
1476
1474
  report["skipped"].append(f"no area columns detected (label_col={label_col}, total_col={total_col})")
1477
1475
  return data, report
hwpx/form_fit/seal.py CHANGED
@@ -32,7 +32,7 @@ point is exactly ``100`` HWPUNIT (``7200 / 72``).
32
32
  from __future__ import annotations
33
33
 
34
34
  import math
35
- from dataclasses import dataclass, field
35
+ from dataclasses import dataclass
36
36
  from typing import Any, Sequence
37
37
 
38
38
  from .wordbox import Rect, WordBox
@@ -219,8 +219,7 @@ def check_seal_placement(
219
219
  offset = math.hypot(scx - acx, scy - acy)
220
220
  centered = offset <= tol_pt
221
221
 
222
- # Glyphs the seal sits on top of, excluding the anchor's own line (intended).
223
- anchor_line = set(_norm(anchor.line_text)) # cheap line-membership proxy by text
222
+ # Glyphs the seal sits on top of, excluding the anchor's own baseline.
224
223
  anchor_cy = anchor.center[1]
225
224
  occluded = 0
226
225
  for g in boxes:
hwpx/formfill_quality.py CHANGED
@@ -36,7 +36,6 @@ from pathlib import Path
36
36
  from typing import Any, Sequence
37
37
 
38
38
  from .table_patch import (
39
- _direct_cells,
40
39
  _iter_table_spans,
41
40
  _read_source_bytes,
42
41
  _sections,
hwpx/oxml/__init__.py CHANGED
@@ -135,11 +135,13 @@ __all__ = [
135
135
  "HwpxOxmlMasterPage",
136
136
  "HwpxOxmlMemo",
137
137
  "HwpxOxmlMemoGroup",
138
+ "HwpxOxmlNote",
138
139
  "HwpxOxmlParagraph",
139
140
  "HwpxOxmlRun",
140
141
  "HwpxOxmlSection",
141
142
  "HwpxOxmlSectionHeaderFooter",
142
143
  "HwpxOxmlSectionProperties",
144
+ "HwpxOxmlShape",
143
145
  "HwpxOxmlTable",
144
146
  "HwpxOxmlTableCell",
145
147
  "HwpxTableGridPosition",
@@ -7,7 +7,7 @@ import logging
7
7
  import re as _re
8
8
  from copy import deepcopy
9
9
  from dataclasses import dataclass
10
- from typing import Any, Callable, Iterable, Iterator, Mapping, Optional, Sequence, TypeVar
10
+ from typing import TYPE_CHECKING, Any, Callable, Iterable, Iterator, Mapping, Optional, Sequence, TypeVar
11
11
  from uuid import uuid4
12
12
  import xml.etree.ElementTree as ET
13
13
 
@@ -52,6 +52,11 @@ from .namespaces import (
52
52
  )
53
53
  from .utils import parse_int
54
54
 
55
+ if TYPE_CHECKING:
56
+ from hwpx.form_fit.policy import FitPolicy
57
+ from hwpx.form_fit.report import FitResult
58
+ from hwpx.opc.package import HwpxPackage
59
+
55
60
  register_owpml_namespaces(ET.register_namespace)
56
61
  logger = logging.getLogger(__name__)
57
62
 
hwpx/oxml/body.py CHANGED
@@ -7,7 +7,7 @@ from typing import Dict, List, Optional, Union
7
7
 
8
8
  from lxml import etree
9
9
 
10
- from .common import GenericElement, parse_generic_element
10
+ from .common import GenericElement
11
11
  from .namespaces import HP
12
12
  from .utils import local_name, parse_bool, parse_int
13
13
 
hwpx/oxml/document.py CHANGED
@@ -13,7 +13,6 @@ from types import ModuleType
13
13
 
14
14
  from . import _document_impl as _impl
15
15
  from ._document_impl import * # noqa: F401,F403
16
- from ._document_impl import _memo_id, _object_id, _paragraph_id
17
16
 
18
17
  __all__ = [name for name in dir(_impl) if not name.startswith("_")]
19
18
 
hwpx/oxml/header.py CHANGED
@@ -1480,7 +1480,7 @@ def track_change_to_xml(change: TrackChange) -> etree._Element:
1480
1480
  _set_optional_int_attr(attributes, "id", change.id)
1481
1481
  if change.raw_id is not None and change.id is None:
1482
1482
  attributes["id"] = change.raw_id
1483
- return etree.Element(f"{{http://www.hancom.co.kr/hwpml/2011/head}}trackChange", attributes)
1483
+ return etree.Element("{http://www.hancom.co.kr/hwpml/2011/head}trackChange", attributes)
1484
1484
 
1485
1485
 
1486
1486
  def track_change_author_to_xml(author: TrackChangeAuthor) -> etree._Element:
@@ -1496,7 +1496,7 @@ def track_change_author_to_xml(author: TrackChangeAuthor) -> etree._Element:
1496
1496
  attributes["id"] = author.raw_id
1497
1497
  _set_optional_str_attr(attributes, "color", author.color)
1498
1498
  return etree.Element(
1499
- f"{{http://www.hancom.co.kr/hwpml/2011/head}}trackChangeAuthor",
1499
+ "{http://www.hancom.co.kr/hwpml/2011/head}trackChangeAuthor",
1500
1500
  attributes,
1501
1501
  )
1502
1502
 
hwpx/table_patch.py CHANGED
@@ -840,6 +840,25 @@ def _collapse_empty_rows(table: str) -> str:
840
840
  return _rebuild(prefix, rows, suffix, rowcnt=rowcnt)
841
841
 
842
842
 
843
+ def _physical_row_height(rows: Sequence[str], row: int) -> int | None:
844
+ """Return the exact height of a physical row when direct cells expose it.
845
+
846
+ A physical row can contain several ``rowSpan==1`` cells with different
847
+ ``cellSz`` heights. Hancom uses the tallest direct cell as the row height;
848
+ shorter values can belong to sparse/covered-looking cells. ``None`` means
849
+ the row is covered entirely by vertical merges and remains underivable.
850
+ """
851
+ heights: list[int] = []
852
+ for physical_row in rows:
853
+ for tc in _S_TC.findall(physical_row):
854
+ ra = _si(tc, "cellAddr", "rowAddr")
855
+ rs = _si(tc, "cellSpan", "rowSpan") or 1
856
+ height = _si(tc, "cellSz", "height")
857
+ if ra == row and rs == 1 and height is not None and height > 0:
858
+ heights.append(height)
859
+ return max(heights) if heights else None
860
+
861
+
843
862
  def _delete_rows(table: str, del_rows: Iterable[int]) -> str:
844
863
  """Delete physical rows by index, reconciling rowAddr/rowSpan and covering
845
864
  cells' height."""
@@ -849,6 +868,7 @@ def _delete_rows(table: str, del_rows: Iterable[int]) -> str:
849
868
  for empty in del_rows:
850
869
  if empty >= len(rows):
851
870
  raise TableStructureError(f"row index {empty} out of range")
871
+ exact_height = _physical_row_height(rows, empty)
852
872
  heights = []
853
873
  for r in rows:
854
874
  for tc in _S_TC.findall(r):
@@ -857,7 +877,9 @@ def _delete_rows(table: str, del_rows: Iterable[int]) -> str:
857
877
  h = _si(tc, "cellSz", "height")
858
878
  if h:
859
879
  heights.append(h // rs)
860
- drop_h = min(heights) if heights else 0
880
+ # Prefer the exact physical-row height. Fully merged rows expose no
881
+ # rowSpan==1 cell, so preserve the previous conservative estimate there.
882
+ drop_h = exact_height if exact_height is not None else (min(heights) if heights else 0)
861
883
 
862
884
  def fix(tc: str):
863
885
  ra, rs = _si(tc, "cellAddr", "rowAddr"), _si(tc, "cellSpan", "rowSpan") or 1
hwpx/tools/fuzz/runner.py CHANGED
@@ -8,7 +8,6 @@ import logging
8
8
  import shutil
9
9
  import tempfile
10
10
  from contextlib import contextmanager
11
- from copy import deepcopy
12
11
  from dataclasses import dataclass
13
12
  from pathlib import Path
14
13
  from random import Random
@@ -24,7 +24,7 @@ from __future__ import annotations
24
24
  import re
25
25
  from dataclasses import dataclass, field
26
26
  from pathlib import Path
27
- from typing import Any, Sequence
27
+ from typing import Any
28
28
 
29
29
  from hwpx.document import HwpxDocument
30
30
 
hwpx/visual/detectors.py CHANGED
@@ -14,7 +14,7 @@ gate on :func:`imaging_available` and degrade otherwise.
14
14
  """
15
15
  from __future__ import annotations
16
16
 
17
- from typing import TYPE_CHECKING, Any
17
+ from typing import TYPE_CHECKING
18
18
 
19
19
  if TYPE_CHECKING: # pragma: no cover - typing only
20
20
  from PIL import Image
@@ -88,7 +88,6 @@ def new_ink_ratio_outside_mask(before: "Image.Image", after: "Image.Image", rect
88
88
  output but not the original, in a region the edit was not allowed to paint.
89
89
  """
90
90
 
91
- import numpy as np
92
91
 
93
92
  before, after = _match_size(before, after)
94
93
  new_ink = _ink_mask(after) & ~_ink_mask(before)
@@ -5,7 +5,6 @@ from __future__ import annotations
5
5
 
6
6
  import hashlib
7
7
  import json
8
- import os
9
8
  import shutil
10
9
  import subprocess
11
10
  import tempfile
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: python-hwpx
3
- Version: 2.29.1
3
+ Version: 3.0.0
4
4
  Summary: 한글 없이 HWPX 문서를 열고, 편집하고, 생성하고, 검증하는 Python 자동화 라이브러리
5
5
  Author: python-hwpx Maintainers
6
6
  License-Expression: Apache-2.0
@@ -37,6 +37,7 @@ Requires-Dist: numpy>=1.26; extra == "test"
37
37
  Requires-Dist: pillow>=10.0; extra == "test"
38
38
  Requires-Dist: pytest>=7.4; extra == "test"
39
39
  Requires-Dist: pytest-cov>=5.0; extra == "test"
40
+ Requires-Dist: ruff>=0.12; extra == "test"
40
41
  Provides-Extra: typecheck
41
42
  Requires-Dist: mypy>=1.10; extra == "typecheck"
42
43
  Requires-Dist: pyright>=1.1.390; extra == "typecheck"
@@ -219,7 +220,7 @@ Apache License 2.0. See LICENSE and NOTICE.
219
220
 
220
221
  ## Maintainer
221
222
 
222
- Primary maintainer/contact: **고규현** — 광교고등학교 정보·컴퓨터 교사
223
+ Primary maintainer/contact: **Kohkyuhyun** ([@airmang](https://github.com/airmang))
223
224
 
224
225
  - ✉️ [kokyuhyun@hotmail.com](mailto:kokyuhyun@hotmail.com)
225
226
  - 🐙 [@airmang](https://github.com/airmang)
@@ -1,16 +1,16 @@
1
1
  hwpx/__init__.py,sha256=L8u0myEm2NuGawIEmGjqtFVJ2C-rIUYDjQR1s-V9Pps,5494
2
2
  hwpx/authoring.py,sha256=_AUGOzwmiHHuO08HZhGCEd6eCHCZV0yXeBaYKMsJJ34,125020
3
3
  hwpx/body_patch.py,sha256=1jV0yQ4KrVmWfblY6Sx95DV6crP1TTEDPO-Ddphw7C0,25007
4
- hwpx/document.py,sha256=NZBmKBRs43FdsF1-XygGWxJwNp8GtBEywM89YqmWdj8,107728
5
- hwpx/evalplan_fill.py,sha256=LXa25_eZYVyoBnweaHvlN2M1--fgundYj2J3ZUrPasg,78678
4
+ hwpx/document.py,sha256=RaitWdElNVF0839jOKrVXoIIVC642odzePVPX--Ca5k,107809
5
+ hwpx/evalplan_fill.py,sha256=lXughCi0Lgw3knQAy4gxmtx5CYTOAa-kFk9ddc0ONKg,78551
6
6
  hwpx/fill_residue.py,sha256=il3QNgNIru9VZcP36vtKS5MpKZNLXS4dYlMIeToACaM,6970
7
7
  hwpx/form_fill.py,sha256=VUIU53Qa9Ho2aP72biDvJwnDW7ngdAzu3PSd5A7d1JM,9908
8
- hwpx/formfill_quality.py,sha256=XNh70qsDva5RGNJuWJ9Ne5Ve5RW1GkGVkag6sr0rgNc,38540
8
+ hwpx/formfill_quality.py,sha256=pRxZYb1cg95F2O78va5glMJ3UqPh1rewJB1Qz-LOlsc,38521
9
9
  hwpx/guidance_scan.py,sha256=lN7wMUz0BaAgHCXdfK1CPEEmIqaFCuwpyL6XAQH6mqE,22921
10
10
  hwpx/package.py,sha256=0rKjGCJbPQvrVBIy07Jpjsu3fI7HhbqFCGWTiTDsJpo,1141
11
11
  hwpx/patch.py,sha256=8G1wgGVgCp0KyhQb-y0ZI2FJEatCwLt_JpepHJmYhYQ,23799
12
12
  hwpx/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
13
- hwpx/table_patch.py,sha256=FCpCNQSX9jta12gmmSyDshB-okANYSL3O5YS0Rr1mX4,72358
13
+ hwpx/table_patch.py,sha256=lAHhtWiwIbJPJ6Jr68OgLnnxfUQevrfC7KIXqZHn5UU,73506
14
14
  hwpx/template_formfit.py,sha256=dlxf98FatT5Nl4hN15TuMXqj5NlDTGSnLaqXVo_PoBo,23424
15
15
  hwpx/templates.py,sha256=28bYqeJVeDb1Cq8G9NZG9Mhnu4K2GamAKC4QhxvUZyA,1187
16
16
  hwpx/agent/__init__.py,sha256=2pjX3M6SM3XnS6IsYjc64Jrm3YdbzsZPjbx7hBHMEl0,2665
@@ -24,13 +24,13 @@ hwpx/agent/query.py,sha256=m4h_vRAnYAGMmh9j85hovuSIMjRwsAfIp2LY428KoGo,7907
24
24
  hwpx/agent/blueprint/__init__.py,sha256=72KfSaJOcJcR66TjoLpKUUZve55c0JM2E1Zs1PfilA8,1507
25
25
  hwpx/agent/blueprint/bundle.py,sha256=K9-lcCgx2j1EsHzdP0cFn3ejn-YcLQ1NnNiPZNjq25Q,11544
26
26
  hwpx/agent/blueprint/catalog.py,sha256=D2ax7gQxhoqqtL70LWjcUME6I9TMb2Q7MqR48c19_tc,4669
27
- hwpx/agent/blueprint/dump.py,sha256=AQuH7jk2XTzmKaKfW4yFDTG-nllc5qqKtUo5G4D33aw,21766
27
+ hwpx/agent/blueprint/dump.py,sha256=HgEMr5dI5ozXwZn9tH-2IlFtWphxT_qz7hlZmSn49MU,21745
28
28
  hwpx/agent/blueprint/mapping.py,sha256=bzSYbTrNEumBkP74nEY5M20-BEC4rBGCRvo3QZNQKxc,12761
29
29
  hwpx/agent/blueprint/model.py,sha256=U1CykldrtKWRXntb6cJxJjs-mGOVFN4jroBbcaQNoTk,28096
30
- hwpx/agent/blueprint/native.py,sha256=h2JmmMA4IBb_NPJbUXUeL4lQyLDxd19aeGuwLn7OT90,28797
30
+ hwpx/agent/blueprint/native.py,sha256=O6ZyBmKMw-O-SoEzlWkIgA4E7zXog1Ba9-4Ug5AekpM,28761
31
31
  hwpx/agent/blueprint/replay.py,sha256=EzkjGsFCYkjADZVaX1V8g4LAlZIXOFn7cZJmmCNNpSY,20047
32
32
  hwpx/benchmark/__init__.py,sha256=7CfgxEQ6nUrKHy3-V9VkeaMoGrb12QA8mHzpcfF2ItE,623
33
- hwpx/benchmark/blind_eval.py,sha256=nh-p6yZ61_7IkyTIMZLH7Mn4U6CCtBP2kpPmtb5iyQY,13241
33
+ hwpx/benchmark/blind_eval.py,sha256=4_HEpx6FzlYzoochnXEUhbe57as4-f4GOO14F0lOyA4,13231
34
34
  hwpx/builder/__init__.py,sha256=8tcxClbeuNle_R_2nDAauyy518OCegG8qVPjwIKRUZA,849
35
35
  hwpx/builder/core.py,sha256=gwLIW8wYVG09TRhtP5O6k9bAN3KEmChgLMYK5Q8ELzY,32589
36
36
  hwpx/builder/report.py,sha256=nPzxADknM1oT4mS908uUU_WVZgtcW_HBpaIUnnMPgcI,8269
@@ -41,10 +41,10 @@ hwpx/conformance/report.py,sha256=_C9vr9ZQQfbcH5acmTCyFOvnK2bwyIMi4dpdhijbEVM,76
41
41
  hwpx/conformance/roundtrip_batch.py,sha256=4M49ccn7Lb4WMaByye1EGqYLjfJemwlX9iQFZXBFPW4,5681
42
42
  hwpx/conformance/runner.py,sha256=4ilHShwEHJ8FtJ50UzFf4OOQv5io6yb2F9A76wgDuJo,14455
43
43
  hwpx/conformance/corpus/corpus.json,sha256=rl811sFYEtH8ezyisGFDhLMROsmmqwDvZT2OynjTya0,1101
44
- hwpx/conformance/corpus/meeting_summary.hwpx,sha256=s0pNaYtdHWLum7T5Y5g6kXjBiSht7gc3iyUo6BKGdtQ,7554
45
- hwpx/conformance/corpus/notice.hwpx,sha256=HWGRtK0WXNcnt_za2NCmMj4YaL_tKMgjoDbYmhXbva8,7616
46
- hwpx/conformance/corpus/report_table.hwpx,sha256=kKP3cD0nsFdgBIDLu99iOTmU3y-uFJUK7aLFowCI05c,8123
47
- hwpx/data/Skeleton.hwpx,sha256=K0EdMIs33s1dTTWMd-pE1ZQGChFkBcJvJh6OPqk078w,7474
44
+ hwpx/conformance/corpus/meeting_summary.hwpx,sha256=wuI7Fhp5CeRZ3LsqFHIAsRLyOik7m9f-qB6ION1oTBo,7570
45
+ hwpx/conformance/corpus/notice.hwpx,sha256=JgY_ZU9QN7bigu7fXQQH9ZaayGHbwqRhE1iSpTvYhMU,7632
46
+ hwpx/conformance/corpus/report_table.hwpx,sha256=Qv07K5YtA5q8rKrAOek18VeWVb6KwNOOH3SbmFe1oeI,8139
47
+ hwpx/data/Skeleton.hwpx,sha256=yR-3epkzo-VkWiV3ji0rmemBN-2ZVypdHdKe8MD9TJg,7490
48
48
  hwpx/design/__init__.py,sha256=JpJRF6Z21H4x8mx2j-jKP-1kijQ05aP-BMgICpLcdnE,1101
49
49
  hwpx/design/_support.py,sha256=qqWwyvlguHIWpkdsPdkXxY6tZ9xJyEBG8Q3a_7wAb2I,4586
50
50
  hwpx/design/composer.py,sha256=8U6F6PfWLaGusMdzR3jHlFZIA-Cxfg3gnEOINS5BZfw,10803
@@ -63,7 +63,7 @@ hwpx/design/profiles/home_notice/template.hwpx,sha256=TZeOV77NrhB9kVdUasXweKSSlQ
63
63
  hwpx/design/profiles/home_notice/fragments/body.xml,sha256=A8M2S1fe7QIdyl5KK0tg6HjbksBD5hioOl8tOM25if0,212
64
64
  hwpx/design/profiles/home_notice/fragments/heading.xml,sha256=FWPCjuAbsR7j6qYVd1-8c0sxyo6JDY5vkM-LV3ZWzEw,215
65
65
  hwpx/design/profiles/home_notice/fragments/title.xml,sha256=6BybxZE8h4h370iB-ZJzM7fKqw1M_Y_J_TGuTzXEIRM,214
66
- hwpx/design/profiles/official_notice/profile.json,sha256=Q9WQBnH9ukgPhMCyxluDbxPfqNmxyz_6tO9hADxyGnk,654
66
+ hwpx/design/profiles/official_notice/profile.json,sha256=pk3aFFW7d35SNwxhFXuj4GYHFxMMpGHS1JjdYIdmeaM,595
67
67
  hwpx/design/profiles/official_notice/template.hwpx,sha256=y84XEouqC9SMVW7hMucsiYBp9zg2OdzlIgVy0i81Nr8,10343
68
68
  hwpx/design/profiles/official_notice/fragments/body.xml,sha256=nEWh0GQfbtOKpu3NkjULZ72t7va7rNHxU4QG0LN6OLg,213
69
69
  hwpx/design/profiles/official_notice/fragments/heading.xml,sha256=OUlxKAhHt3Dg55HMyZ-4C1L36dLx_1Ta-MFezipsQhI,207
@@ -87,7 +87,7 @@ hwpx/form_fit/engine.py,sha256=6E_OItLwd9k8670bEKlqVQPGjtl3EyRzYdbmSVllvqo,11088
87
87
  hwpx/form_fit/measure.py,sha256=NZYa6GkoHOf_CIennIrYmuyWltPVh4p6u4_eBuiTb8M,12792
88
88
  hwpx/form_fit/policy.py,sha256=iXAatjS7ZycOdKgMCL4Q_kYg0qnogFPdRNlr_ecOvjc,3106
89
89
  hwpx/form_fit/report.py,sha256=h1NzQfbj1JYvZtKUi0DckJNWGnUHMZtQ3iCzbUxUjHA,3305
90
- hwpx/form_fit/seal.py,sha256=rQ2HvVXw7vHjBEa5wj3Aa5KjX2dkWSSpnzqKEvNJDj4,17740
90
+ hwpx/form_fit/seal.py,sha256=QsPzFagaEi7UKAXS-iFwiZs8rLG-_Fo9RixLc2OaqbU,17640
91
91
  hwpx/form_fit/wordbox.py,sha256=bStyzpcK4PF3pihRUSKiStwW_XwYHDeU0D3Or_Eh0nM,48301
92
92
  hwpx/ingest/__init__.py,sha256=cjDQwMdaqbq2xiD32zmaFAyzZbENga_6MLbgo0sLGZE,636
93
93
  hwpx/ingest/base.py,sha256=95jXJ70Hkay70BgyryGOzI3UVTixUpR-6f71iF3eqn4,8134
@@ -99,13 +99,13 @@ hwpx/opc/package.py,sha256=4Ydaw-1uyTZ7DwNZ89ICJ7CHYwUGzeGR-FbZiyJ5XWk,35484
99
99
  hwpx/opc/relationships.py,sha256=tPWLHRMlw0Spvtwou2jCDRfHdcm9FEKKLd95YVHLwYI,6971
100
100
  hwpx/opc/security.py,sha256=hsA73sZxUoGIgy2zue9EnV7ChHMfasnplmqzxFs3Mp4,4419
101
101
  hwpx/opc/xml_utils.py,sha256=L_fHY1-D5I_TfdRkDQV-bn55EnXc6AqEDWItfMpawVs,3840
102
- hwpx/oxml/__init__.py,sha256=7koxG5Xc6ia1dWmAqUJJETkAL5wzamSrNVcKuiUH58I,5466
103
- hwpx/oxml/_document_impl.py,sha256=poecP3lZ9I_SPKUBfiLIvjl1G6vmYFNv-WecXNhX714,250495
104
- hwpx/oxml/body.py,sha256=3PzGiYmm03si5OVjGtS-R_tT1rWmsYwE8Ds8ZLhIIio,30609
102
+ hwpx/oxml/__init__.py,sha256=pqHqOK2snS74U_mkmkFcgyCUCLiGmbS84TKFBrwxF5I,5507
103
+ hwpx/oxml/_document_impl.py,sha256=K5W3Kf6nLWogJ2ENLWaKJTwt0V8VnTNzseYhv4QU3c0,250668
104
+ hwpx/oxml/body.py,sha256=j-MJFHgInfOuFYYf-tsjFXvzPvKLt7HqUvc5Lhmp0is,30586
105
105
  hwpx/oxml/canonical_defaults.py,sha256=WHAK7u_W-PDv3P3N1-1-aWAoiUgBh4x-UybFL4NqW-w,3791
106
106
  hwpx/oxml/common.py,sha256=TJkafzg7x4T3J29tZchRZk57ZTsrM9PEiqGT3rX3w5o,1044
107
- hwpx/oxml/document.py,sha256=9_gJgk-Zyoeqft3OB-sce4MQLo-UejR79e1fDEsC7b0,1154
108
- hwpx/oxml/header.py,sha256=m878yWuMv9dRA4enaHHBjPEsL6QECBJLhfsQetJ7l2I,50017
107
+ hwpx/oxml/document.py,sha256=_YQ5gNN_Hh3mcjRvs3ZKzaGfr5Zvl4DH0Y5sV27f1cw,1090
108
+ hwpx/oxml/header.py,sha256=4LtTDPe7YW0o_4jPv3Rd-vyv5suRfebecxtTWbF65Uw,50011
109
109
  hwpx/oxml/header_part.py,sha256=nIMsH3gHdKP_BB5g4LwFwCqmMzjnyY5y40vitQMSPwc,237
110
110
  hwpx/oxml/memo.py,sha256=BxfNt8k7_A0eUcZ3uu97t5rM5OA315pR7lCEHVkS8b8,304
111
111
  hwpx/oxml/namespaces.py,sha256=c7JfdOdJbzrhyHvjbxoeeeloRE3xPuoB7v3YI8SmKDk,6524
@@ -119,21 +119,6 @@ hwpx/oxml/section.py,sha256=CRb4rlPPAifaOfHGZZUrdJJ8yZisUuuOqqd-FHmO0vk,359
119
119
  hwpx/oxml/simple_parts.py,sha256=wZ7HfmfpiSpCgZ-H5fMOS4xFq47jgpE3ssZm24pMvbQ,264
120
120
  hwpx/oxml/table.py,sha256=UaPS_HpFj91OQ5GQ5_DO8IzHe6fCx5mEwqElDkstYdI,363
121
121
  hwpx/oxml/utils.py,sha256=2L9au3SD_MFkFt2DXx3udXBT5caYuYO623lhGhgldVo,2972
122
- hwpx/practice/__init__.py,sha256=d0sAHfEeGJYo7V5whc_KOSzLqDZIsxuX-l60eDTun5g,8473
123
- hwpx/practice/aggregate.py,sha256=1VuK4qs3Pof2vCtNZlS1R9vEPMx-SKZ86dOwl74Bpd4,37441
124
- hwpx/practice/campaign.py,sha256=Gdy5Y7WJxNsE-bMRh4HaAcZg8xw6veCDu1kbHkI282E,11126
125
- hwpx/practice/domain.py,sha256=sGCof2R-i-0KNpwirzzCfGrV1T2zQs5m1biUKypFJ2g,122700
126
- hwpx/practice/dossier.py,sha256=NpVKttRlaSilYD2JejK4i8ZrXfEV1ISPX3Qf2oU49pI,3175
127
- hwpx/practice/evaluator.py,sha256=fACv3eBq4XMyXqOq0COcbz2Hr_oaK71bS4i6CaOzLTM,90618
128
- hwpx/practice/forge.py,sha256=J4705KDntaQXA9Ew8ro5wbhiqqz4LEtmtmXSS4fuXIA,19704
129
- hwpx/practice/intake.py,sha256=L7kVGPM3QRhPKfQNXlR1upCg_pm_telEPvp4jkfimMA,8383
130
- hwpx/practice/lineage.py,sha256=lw4w2gPX42OZ0O2CG2DZI6vWivNretLHIoRQoIIB2x0,4003
131
- hwpx/practice/mutations.py,sha256=5B2fG6Q5inObUYpoa_EWU937FqTthD0P_LzrJLQSX8I,6901
132
- hwpx/practice/registry.py,sha256=ZCIo7lazoaiXFaKjUPHogc7N0C2u7EA_UnJJF91E2dc,12990
133
- hwpx/practice/run.py,sha256=kfj5vGsQsfRdzqBpjWi0IEbSbpGGQv44N87HqhG967Y,29681
134
- hwpx/practice/sanitize.py,sha256=F2eVfK5HVSAKN3IE7VdpmlU_TeQ1MCEL8Ab1sci43ik,5827
135
- hwpx/practice/scenario.py,sha256=Wc7ctGiBVDRgVWlcNGT7v6pXI-aLfOPfarOO3c7ku6g,6434
136
- hwpx/practice/split.py,sha256=D43WH2n9lRofBRJTK6kG2BfHAzrKMwvnakkVzsgbhfU,9650
137
122
  hwpx/presets/__init__.py,sha256=I3gSJDT2tuvxXbw3FOmI3CnbxvjDMPZfppyg6OlMHOI,535
138
123
  hwpx/presets/proposal.py,sha256=2yzLfDxOAT0P19dPX1RBWh56_AIOMsWqINDadtnKQoc,21176
139
124
  hwpx/quality/__init__.py,sha256=zvOvfOYh0nlKH5ywpj9ZQHov0sdRIouicv9DamKmHLU,1478
@@ -174,7 +159,7 @@ hwpx/tools/template_analyzer.py,sha256=LEc5xazy0YwPCY5sLycSvOk3U8NRMKWDYDu_rz1WZ
174
159
  hwpx/tools/text_extract_cli.py,sha256=BmsDAwNXpDPhEayb9ez2ORtGNzPd_Xxduy4_cLXhnUw,2188
175
160
  hwpx/tools/text_extractor.py,sha256=m9OSBd4FjZrzlMP8b4uS2Lnmjp-u-t7EBKFDF3P1bTM,25514
176
161
  hwpx/tools/toc_author.py,sha256=vkAwMO6uTR9Rk8Sy5h6Zvx8uYb_vbptr7bBi2EBLfNI,11932
177
- hwpx/tools/toc_fidelity.py,sha256=POljSwcjFFmLMtXH5WVmzGA03aBMLcN39hg52DpdRzM,17336
162
+ hwpx/tools/toc_fidelity.py,sha256=WqVhUaA84yyLCbF1GZpezV4E8H7rez8pX8kMokxH86k,17326
178
163
  hwpx/tools/validator.py,sha256=U856izL9NcJZOiKDYoCpwOSaFNQ2Un8Jn4pzL20A96Q,7100
179
164
  hwpx/tools/_schemas/header.xsd,sha256=mJXuFMuHGT1JnFFaluUpYUglwjMCNlfbFCRVM26eHXE,664
180
165
  hwpx/tools/_schemas/section.xsd,sha256=MgvavVHG05RDfUnVPxVU10H4FQOja5ON04_m9Uk_m7E,522
@@ -183,26 +168,26 @@ hwpx/tools/fuzz/__main__.py,sha256=02fWzRj-6Gp4YS8PcXVa5UCcUBYfrqyu5aGBS7URITk,3
183
168
  hwpx/tools/fuzz/catalog.py,sha256=Cdc8qKeYy32cDMC6ULqAnlxv8BIlY83ZBe7xFCiiUQs,10303
184
169
  hwpx/tools/fuzz/generator.py,sha256=G2tGmo4-i-i0v_-rqHsNKZjfpD5wAJZRMsLTPu_KZfg,7381
185
170
  hwpx/tools/fuzz/minimize.py,sha256=gv9fEU1PsmpXR-Z6wiejMC0umHV90GYhtO2Ht8x2__Y,1055
186
- hwpx/tools/fuzz/runner.py,sha256=NkSrlWUf813SqEwkhi05LmusMgM9r2j2JiPCqzzvPN8,17906
171
+ hwpx/tools/fuzz/runner.py,sha256=a-_AwZ6MGjsGnceCUl6XO5H1W96zUgr2pmR6TmuOjNI,17880
187
172
  hwpx/visual/__init__.py,sha256=vb2Ythl2c1Ju3OzwIprb9GD6MqIMeIE2Er4I_z2mfGk,3310
188
173
  hwpx/visual/_hancom_open_rate.ps1,sha256=stgE7ID2DuIpHWZHi414hmPuvPKnbecPO-oLrFWYBSg,16016
189
174
  hwpx/visual/_refresh_hwpx_mac.applescript,sha256=N26GN5hYjXUwhh_LYI-wt3DWTFwshUX4hBpCDrODEXc,4684
190
175
  hwpx/visual/_render_hwpx.ps1,sha256=r7bUPQvMMwVhz5YiUIEZPSAO18GbPPfnaK8iZb67d3w,2412
191
176
  hwpx/visual/_render_hwpx_mac.applescript,sha256=6iCabMkPmuXmff6ydb7UfF7QKEhFD2JSM86S9R9535s,8807
192
- hwpx/visual/detectors.py,sha256=WySbPnhyp4vTZWtkHoAiNY9G9AoZbVNgVgwaEZzt1R0,4853
177
+ hwpx/visual/detectors.py,sha256=k7t79nWIBSqStNNdwPohmUG2zwr12Mz-JG22jHlsGdA,4825
193
178
  hwpx/visual/diff.py,sha256=0X5T9IgwRZU3td-7vnPrlowovtGud7P_ymq0KVehlKk,5677
194
179
  hwpx/visual/fixture_corpus.py,sha256=Bcy7nscf6RY7sHemGKaqzsyRrWp5ioQdP2wQFFoY20A,6676
195
- hwpx/visual/hancom_worker.py,sha256=Lmz65ySOAZCcWw_7l2MB2CRq0XRlqiRaP3pedoNt2Ts,10171
180
+ hwpx/visual/hancom_worker.py,sha256=r70lUnHSdIF4h3plIk_SIkoXpzuACJp1FBE1WMBt5Ic,10161
196
181
  hwpx/visual/masks.py,sha256=oXhgynAb4uKjJtZ2BGHHdAjyvWGqSFlZFQ-iJxzHiuo,1832
197
182
  hwpx/visual/oracle.py,sha256=VNO-tAB-lzTdW5XtSELxg_Aau369qRFBsJvNryHF_D8,31319
198
183
  hwpx/visual/page_qa.py,sha256=AuJCySfLIdXjPeekhAc3YnrIWOsN0sI35Pnz8BZ6Pro,7278
199
184
  hwpx/visual/qa_contracts.py,sha256=1cjoiRTAWgi7NgE8SPc6bKxdoUfKx9nyou1mgC47TxY,10506
200
185
  hwpx/visual/qa_metrics.py,sha256=I7RdybN-f1Fvcv2j-ceDPoek51nOkMui1Zrd7TEX_C8,9838
201
186
  hwpx/visual/report.py,sha256=2RhXN1KBYOZTim9FNpeUhaaDHR7oFxI6Z2DLUkDIiwE,1717
202
- python_hwpx-2.29.1.dist-info/licenses/LICENSE,sha256=_ubz4wv-BkkT3l3gu-QuH7JGeVjuRYGZoZK95eNsCHU,9688
203
- python_hwpx-2.29.1.dist-info/licenses/NOTICE,sha256=k48h6EaGQE8Y1c0dS9sIOOcz4YqkbcImWClF7pBOgsg,2473
204
- python_hwpx-2.29.1.dist-info/METADATA,sha256=JyAUvxHOObBI4FscI_LBA48ay_CIz4LNJ2hd4iqDRpk,11488
205
- python_hwpx-2.29.1.dist-info/WHEEL,sha256=K260EYznzXsJYBQGqmI8VTxEdiZYNvDZwW9cBh9-_MA,91
206
- python_hwpx-2.29.1.dist-info/entry_points.txt,sha256=PVUBTBQtBHiflQ9XBjfd004w-LrDibgZjwzxgu8Tx7w,480
207
- python_hwpx-2.29.1.dist-info/top_level.txt,sha256=R1iToqDh80Nf2oQhRjTN0rbN2X6kyDUizIocZjkhuxc,5
208
- python_hwpx-2.29.1.dist-info/RECORD,,
187
+ python_hwpx-3.0.0.dist-info/licenses/LICENSE,sha256=_ubz4wv-BkkT3l3gu-QuH7JGeVjuRYGZoZK95eNsCHU,9688
188
+ python_hwpx-3.0.0.dist-info/licenses/NOTICE,sha256=k48h6EaGQE8Y1c0dS9sIOOcz4YqkbcImWClF7pBOgsg,2473
189
+ python_hwpx-3.0.0.dist-info/METADATA,sha256=PXiYH9Ww3e5uadTiTp_UN0xb6QR4L9CzBzmtYNy878U,11524
190
+ python_hwpx-3.0.0.dist-info/WHEEL,sha256=K260EYznzXsJYBQGqmI8VTxEdiZYNvDZwW9cBh9-_MA,91
191
+ python_hwpx-3.0.0.dist-info/entry_points.txt,sha256=PVUBTBQtBHiflQ9XBjfd004w-LrDibgZjwzxgu8Tx7w,480
192
+ python_hwpx-3.0.0.dist-info/top_level.txt,sha256=R1iToqDh80Nf2oQhRjTN0rbN2X6kyDUizIocZjkhuxc,5
193
+ python_hwpx-3.0.0.dist-info/RECORD,,