draftwright 0.4.23__tar.gz → 0.4.24__tar.gz

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 (562) hide show
  1. {draftwright-0.4.23 → draftwright-0.4.24}/CHANGELOG.md +4 -0
  2. {draftwright-0.4.23 → draftwright-0.4.24}/PKG-INFO +1 -1
  3. {draftwright-0.4.23 → draftwright-0.4.24}/pyproject.toml +1 -1
  4. {draftwright-0.4.23 → draftwright-0.4.24}/src/draftwright/annotations/from_model.py +3 -4
  5. {draftwright-0.4.23 → draftwright-0.4.24}/src/draftwright/compose.py +41 -6
  6. {draftwright-0.4.23 → draftwright-0.4.24}/src/draftwright/drawing.py +1 -3
  7. {draftwright-0.4.23 → draftwright-0.4.24}/src/draftwright/model/compiled.py +128 -10
  8. {draftwright-0.4.23 → draftwright-0.4.24}/src/draftwright/model/planner.py +120 -28
  9. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_declared_recognition_gate.py +2 -3
  10. draftwright-0.4.24/tests/test_issue_1511_turned_boss_heights.py +340 -0
  11. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_issue_740_leader_assignment.py +6 -0
  12. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_make_drawing.py +12 -0
  13. draftwright-0.4.24/tests/test_overall_height_coverage.py +199 -0
  14. {draftwright-0.4.23 → draftwright-0.4.24}/.gitignore +0 -0
  15. {draftwright-0.4.23 → draftwright-0.4.24}/LICENSE +0 -0
  16. {draftwright-0.4.23 → draftwright-0.4.24}/README.md +0 -0
  17. {draftwright-0.4.23 → draftwright-0.4.24}/docs/adr/README.md +0 -0
  18. {draftwright-0.4.23 → draftwright-0.4.24}/docs/reference/recogniser-capabilities.md +0 -0
  19. {draftwright-0.4.23 → draftwright-0.4.24}/docs/reference/sheet.md +0 -0
  20. {draftwright-0.4.23 → draftwright-0.4.24}/docs/research/1062-repeating-radial-profile-evidence.md +0 -0
  21. {draftwright-0.4.23 → draftwright-0.4.24}/skills/SKILL.md +0 -0
  22. {draftwright-0.4.23 → draftwright-0.4.24}/src/draftwright/__init__.py +0 -0
  23. {draftwright-0.4.23 → draftwright-0.4.24}/src/draftwright/_build_profile.py +0 -0
  24. {draftwright-0.4.23 → draftwright-0.4.24}/src/draftwright/_core.py +0 -0
  25. {draftwright-0.4.23 → draftwright-0.4.24}/src/draftwright/_geometry.py +0 -0
  26. {draftwright-0.4.23 → draftwright-0.4.24}/src/draftwright/_pmi_part21.py +0 -0
  27. {draftwright-0.4.23 → draftwright-0.4.24}/src/draftwright/_warnings.py +0 -0
  28. {draftwright-0.4.23 → draftwright-0.4.24}/src/draftwright/analysis.py +0 -0
  29. {draftwright-0.4.23 → draftwright-0.4.24}/src/draftwright/angular_geometry.py +0 -0
  30. {draftwright-0.4.23 → draftwright-0.4.24}/src/draftwright/annotate.py +0 -0
  31. {draftwright-0.4.23 → draftwright-0.4.24}/src/draftwright/annotations/__init__.py +0 -0
  32. {draftwright-0.4.23 → draftwright-0.4.24}/src/draftwright/annotations/_common.py +0 -0
  33. {draftwright-0.4.23 → draftwright-0.4.24}/src/draftwright/annotations/angular.py +0 -0
  34. {draftwright-0.4.23 → draftwright-0.4.24}/src/draftwright/annotations/balloons.py +0 -0
  35. {draftwright-0.4.23 → draftwright-0.4.24}/src/draftwright/annotations/gears.py +0 -0
  36. {draftwright-0.4.23 → draftwright-0.4.24}/src/draftwright/annotations/holes.py +0 -0
  37. {draftwright-0.4.23 → draftwright-0.4.24}/src/draftwright/annotations/leaders.py +0 -0
  38. {draftwright-0.4.23 → draftwright-0.4.24}/src/draftwright/annotations/orchestrator.py +0 -0
  39. {draftwright-0.4.23 → draftwright-0.4.24}/src/draftwright/annotations/sections.py +0 -0
  40. {draftwright-0.4.23 → draftwright-0.4.24}/src/draftwright/audit.py +0 -0
  41. {draftwright-0.4.23 → draftwright-0.4.24}/src/draftwright/blend_contract.py +0 -0
  42. {draftwright-0.4.23 → draftwright-0.4.24}/src/draftwright/builder.py +0 -0
  43. {draftwright-0.4.23 → draftwright-0.4.24}/src/draftwright/cli.py +0 -0
  44. {draftwright-0.4.23 → draftwright-0.4.24}/src/draftwright/evaluation/__init__.py +0 -0
  45. {draftwright-0.4.23 → draftwright-0.4.24}/src/draftwright/evaluation/step_analysis.py +0 -0
  46. {draftwright-0.4.23 → draftwright-0.4.24}/src/draftwright/export.py +0 -0
  47. {draftwright-0.4.23 → draftwright-0.4.24}/src/draftwright/feature_identity.py +0 -0
  48. {draftwright-0.4.23 → draftwright-0.4.24}/src/draftwright/fits.py +0 -0
  49. {draftwright-0.4.23 → draftwright-0.4.24}/src/draftwright/fonts/IBMPlexMono-Regular.ttf +0 -0
  50. {draftwright-0.4.23 → draftwright-0.4.24}/src/draftwright/fonts/IBMPlexSansCondensed-Regular.ttf +0 -0
  51. {draftwright-0.4.23 → draftwright-0.4.24}/src/draftwright/fonts/LICENSE-IBMPlexMono-OFL.txt +0 -0
  52. {draftwright-0.4.23 → draftwright-0.4.24}/src/draftwright/fonts/LICENSE-IBMPlexSansCondensed-OFL.txt +0 -0
  53. {draftwright-0.4.23 → draftwright-0.4.24}/src/draftwright/fonts/__init__.py +0 -0
  54. {draftwright-0.4.23 → draftwright-0.4.24}/src/draftwright/inspection.py +0 -0
  55. {draftwright-0.4.23 → draftwright-0.4.24}/src/draftwright/inspection_contract.py +0 -0
  56. {draftwright-0.4.23 → draftwright-0.4.24}/src/draftwright/intents.py +0 -0
  57. {draftwright-0.4.23 → draftwright-0.4.24}/src/draftwright/layout.py +0 -0
  58. {draftwright-0.4.23 → draftwright-0.4.24}/src/draftwright/linting/__init__.py +0 -0
  59. {draftwright-0.4.23 → draftwright-0.4.24}/src/draftwright/linting/_registry.py +0 -0
  60. {draftwright-0.4.23 → draftwright-0.4.24}/src/draftwright/linting/angled_step_coverage.py +0 -0
  61. {draftwright-0.4.23 → draftwright-0.4.24}/src/draftwright/linting/angular.py +0 -0
  62. {draftwright-0.4.23 → draftwright-0.4.24}/src/draftwright/linting/blend_coverage.py +0 -0
  63. {draftwright-0.4.23 → draftwright-0.4.24}/src/draftwright/linting/chamfer_coverage.py +0 -0
  64. {draftwright-0.4.23 → draftwright-0.4.24}/src/draftwright/linting/channel_coverage.py +0 -0
  65. {draftwright-0.4.23 → draftwright-0.4.24}/src/draftwright/linting/circular_blind_step_coverage.py +0 -0
  66. {draftwright-0.4.23 → draftwright-0.4.24}/src/draftwright/linting/coverage.py +0 -0
  67. {draftwright-0.4.23 → draftwright-0.4.24}/src/draftwright/linting/evidence.py +0 -0
  68. {draftwright-0.4.23 → draftwright-0.4.24}/src/draftwright/linting/fillet_coverage.py +0 -0
  69. {draftwright-0.4.23 → draftwright-0.4.24}/src/draftwright/linting/flat_coverage.py +0 -0
  70. {draftwright-0.4.23 → draftwright-0.4.24}/src/draftwright/linting/gear_coverage.py +0 -0
  71. {draftwright-0.4.23 → draftwright-0.4.24}/src/draftwright/linting/groove_coverage.py +0 -0
  72. {draftwright-0.4.23 → draftwright-0.4.24}/src/draftwright/linting/hole_coverage.py +0 -0
  73. {draftwright-0.4.23 → draftwright-0.4.24}/src/draftwright/linting/ink_overlap.py +0 -0
  74. {draftwright-0.4.23 → draftwright-0.4.24}/src/draftwright/linting/issues.py +0 -0
  75. {draftwright-0.4.23 → draftwright-0.4.24}/src/draftwright/linting/oriented_slot_coverage.py +0 -0
  76. {draftwright-0.4.23 → draftwright-0.4.24}/src/draftwright/linting/pad_coverage.py +0 -0
  77. {draftwright-0.4.23 → draftwright-0.4.24}/src/draftwright/linting/paired_ramp_step_coverage.py +0 -0
  78. {draftwright-0.4.23 → draftwright-0.4.24}/src/draftwright/linting/passage_coverage.py +0 -0
  79. {draftwright-0.4.23 → draftwright-0.4.24}/src/draftwright/linting/plate_coverage.py +0 -0
  80. {draftwright-0.4.23 → draftwright-0.4.24}/src/draftwright/linting/pmi_coverage.py +0 -0
  81. {draftwright-0.4.23 → draftwright-0.4.24}/src/draftwright/linting/pocket_coverage.py +0 -0
  82. {draftwright-0.4.23 → draftwright-0.4.24}/src/draftwright/linting/pocket_pattern_coverage.py +0 -0
  83. {draftwright-0.4.23 → draftwright-0.4.24}/src/draftwright/linting/polygonal_boss_coverage.py +0 -0
  84. {draftwright-0.4.23 → draftwright-0.4.24}/src/draftwright/linting/polygonal_stock_coverage.py +0 -0
  85. {draftwright-0.4.23 → draftwright-0.4.24}/src/draftwright/linting/prismatic_pocket_coverage.py +0 -0
  86. {draftwright-0.4.23 → draftwright-0.4.24}/src/draftwright/linting/profiled_bore_coverage.py +0 -0
  87. {draftwright-0.4.23 → draftwright-0.4.24}/src/draftwright/linting/quality.py +0 -0
  88. {draftwright-0.4.23 → draftwright-0.4.24}/src/draftwright/linting/rectangular_blind_slot_coverage.py +0 -0
  89. {draftwright-0.4.23 → draftwright-0.4.24}/src/draftwright/linting/requirements.py +0 -0
  90. {draftwright-0.4.23 → draftwright-0.4.24}/src/draftwright/linting/round_bottom_blind_slot_coverage.py +0 -0
  91. {draftwright-0.4.23 → draftwright-0.4.24}/src/draftwright/linting/section_recess_coverage.py +0 -0
  92. {draftwright-0.4.23 → draftwright-0.4.24}/src/draftwright/linting/slot_coverage.py +0 -0
  93. {draftwright-0.4.23 → draftwright-0.4.24}/src/draftwright/linting/structural.py +0 -0
  94. {draftwright-0.4.23 → draftwright-0.4.24}/src/draftwright/linting/suggest.py +0 -0
  95. {draftwright-0.4.23 → draftwright-0.4.24}/src/draftwright/linting/through_step_coverage.py +0 -0
  96. {draftwright-0.4.23 → draftwright-0.4.24}/src/draftwright/linting/turned_step_coverage.py +0 -0
  97. {draftwright-0.4.23 → draftwright-0.4.24}/src/draftwright/make_drawing.py +0 -0
  98. {draftwright-0.4.23 → draftwright-0.4.24}/src/draftwright/model/__init__.py +0 -0
  99. {draftwright-0.4.23 → draftwright-0.4.24}/src/draftwright/model/callout.py +0 -0
  100. {draftwright-0.4.23 → draftwright-0.4.24}/src/draftwright/model/declare.py +0 -0
  101. {draftwright-0.4.23 → draftwright-0.4.24}/src/draftwright/model/detect.py +0 -0
  102. {draftwright-0.4.23 → draftwright-0.4.24}/src/draftwright/model/ir.py +0 -0
  103. {draftwright-0.4.23 → draftwright-0.4.24}/src/draftwright/model/pmi_lowering.py +0 -0
  104. {draftwright-0.4.23 → draftwright-0.4.24}/src/draftwright/oriented_slot_contract.py +0 -0
  105. {draftwright-0.4.23 → draftwright-0.4.24}/src/draftwright/plate_correspondence.py +0 -0
  106. {draftwright-0.4.23 → draftwright-0.4.24}/src/draftwright/pmi.py +0 -0
  107. {draftwright-0.4.23 → draftwright-0.4.24}/src/draftwright/profile_angles.py +0 -0
  108. {draftwright-0.4.23 → draftwright-0.4.24}/src/draftwright/projection.py +0 -0
  109. {draftwright-0.4.23 → draftwright-0.4.24}/src/draftwright/py.typed +0 -0
  110. {draftwright-0.4.23 → draftwright-0.4.24}/src/draftwright/recogniser_contract.py +0 -0
  111. {draftwright-0.4.23 → draftwright-0.4.24}/src/draftwright/recogniser_policy.py +0 -0
  112. {draftwright-0.4.23 → draftwright-0.4.24}/src/draftwright/recogniser_schema.py +0 -0
  113. {draftwright-0.4.23 → draftwright-0.4.24}/src/draftwright/recognition/__init__.py +0 -0
  114. {draftwright-0.4.23 → draftwright-0.4.24}/src/draftwright/recognition_cache.py +0 -0
  115. {draftwright-0.4.23 → draftwright-0.4.24}/src/draftwright/recognition_frame.py +0 -0
  116. {draftwright-0.4.23 → draftwright-0.4.24}/src/draftwright/recognition_ownership.py +0 -0
  117. {draftwright-0.4.23 → draftwright-0.4.24}/src/draftwright/registry.py +0 -0
  118. {draftwright-0.4.23 → draftwright-0.4.24}/src/draftwright/repair.py +0 -0
  119. {draftwright-0.4.23 → draftwright-0.4.24}/src/draftwright/reporting.py +0 -0
  120. {draftwright-0.4.23 → draftwright-0.4.24}/src/draftwright/score.py +0 -0
  121. {draftwright-0.4.23 → draftwright-0.4.24}/src/draftwright/section_recess_contract.py +0 -0
  122. {draftwright-0.4.23 → draftwright-0.4.24}/src/draftwright/sheet.py +0 -0
  123. {draftwright-0.4.23 → draftwright-0.4.24}/src/draftwright/sheet_emit.py +0 -0
  124. {draftwright-0.4.23 → draftwright-0.4.24}/src/draftwright/view_plan.py +0 -0
  125. {draftwright-0.4.23 → draftwright-0.4.24}/tests/_evidence_contract.py +0 -0
  126. {draftwright-0.4.23 → draftwright-0.4.24}/tests/_kernel.py +0 -0
  127. {draftwright-0.4.23 → draftwright-0.4.24}/tests/_layout_sig.py +0 -0
  128. {draftwright-0.4.23 → draftwright-0.4.24}/tests/_mutation_corpus.py +0 -0
  129. {draftwright-0.4.23 → draftwright-0.4.24}/tests/_recogniser_public_contract.py +0 -0
  130. {draftwright-0.4.23 → draftwright-0.4.24}/tests/_section_recess_cases.py +0 -0
  131. {draftwright-0.4.23 → draftwright-0.4.24}/tests/conftest.py +0 -0
  132. {draftwright-0.4.23 → draftwright-0.4.24}/tests/fixtures/ap242_single_cylinder_diameter.step +0 -0
  133. {draftwright-0.4.23 → draftwright-0.4.24}/tests/fixtures/evaluation/README.md +0 -0
  134. {draftwright-0.4.23 → draftwright-0.4.24}/tests/fixtures/evaluation/ambiguous-open-semicircle.step +0 -0
  135. {draftwright-0.4.23 → draftwright-0.4.24}/tests/fixtures/evaluation/blind-hole.step +0 -0
  136. {draftwright-0.4.23 → draftwright-0.4.24}/tests/fixtures/evaluation/chamfer-asymmetric.step +0 -0
  137. {draftwright-0.4.23 → draftwright-0.4.24}/tests/fixtures/evaluation/chamfer-compound.step +0 -0
  138. {draftwright-0.4.23 → draftwright-0.4.24}/tests/fixtures/evaluation/chamfer-overlap.step +0 -0
  139. {draftwright-0.4.23 → draftwright-0.4.24}/tests/fixtures/evaluation/chamfer-plain.step +0 -0
  140. {draftwright-0.4.23 → draftwright-0.4.24}/tests/fixtures/evaluation/chamfer-planar-x.step +0 -0
  141. {draftwright-0.4.23 → draftwright-0.4.24}/tests/fixtures/evaluation/chamfer-planar-y.step +0 -0
  142. {draftwright-0.4.23 → draftwright-0.4.24}/tests/fixtures/evaluation/chamfer-planar-z.step +0 -0
  143. {draftwright-0.4.23 → draftwright-0.4.24}/tests/fixtures/evaluation/chamfer-topology-a.step +0 -0
  144. {draftwright-0.4.23 → draftwright-0.4.24}/tests/fixtures/evaluation/chamfer-topology-b.step +0 -0
  145. {draftwright-0.4.23 → draftwright-0.4.24}/tests/fixtures/evaluation/chamfer-turned.step +0 -0
  146. {draftwright-0.4.23 → draftwright-0.4.24}/tests/fixtures/evaluation/corpus-chamfers-v1.json +0 -0
  147. {draftwright-0.4.23 → draftwright-0.4.24}/tests/fixtures/evaluation/corpus-countersinks-v1.json +0 -0
  148. {draftwright-0.4.23 → draftwright-0.4.24}/tests/fixtures/evaluation/corpus-double-d-bores-v1.json +0 -0
  149. {draftwright-0.4.23 → draftwright-0.4.24}/tests/fixtures/evaluation/corpus-fillets-v1.json +0 -0
  150. {draftwright-0.4.23 → draftwright-0.4.24}/tests/fixtures/evaluation/corpus-flats-v1.json +0 -0
  151. {draftwright-0.4.23 → draftwright-0.4.24}/tests/fixtures/evaluation/corpus-grooves-v1.json +0 -0
  152. {draftwright-0.4.23 → draftwright-0.4.24}/tests/fixtures/evaluation/corpus-hole-patterns-v1.json +0 -0
  153. {draftwright-0.4.23 → draftwright-0.4.24}/tests/fixtures/evaluation/corpus-plates-v1.json +0 -0
  154. {draftwright-0.4.23 → draftwright-0.4.24}/tests/fixtures/evaluation/corpus-pocket-patterns-v1.json +0 -0
  155. {draftwright-0.4.23 → draftwright-0.4.24}/tests/fixtures/evaluation/corpus-pockets-v1.json +0 -0
  156. {draftwright-0.4.23 → draftwright-0.4.24}/tests/fixtures/evaluation/corpus-polygonal-bosses-v1.json +0 -0
  157. {draftwright-0.4.23 → draftwright-0.4.24}/tests/fixtures/evaluation/corpus-polygonal-stock-v1.json +0 -0
  158. {draftwright-0.4.23 → draftwright-0.4.24}/tests/fixtures/evaluation/corpus-rectangular-pads-v1.json +0 -0
  159. {draftwright-0.4.23 → draftwright-0.4.24}/tests/fixtures/evaluation/corpus-turned-steps-v1.json +0 -0
  160. {draftwright-0.4.23 → draftwright-0.4.24}/tests/fixtures/evaluation/corpus-v1.json +0 -0
  161. {draftwright-0.4.23 → draftwright-0.4.24}/tests/fixtures/evaluation/countersink-deburr.step +0 -0
  162. {draftwright-0.4.23 → draftwright-0.4.24}/tests/fixtures/evaluation/countersink-external-cone.step +0 -0
  163. {draftwright-0.4.23 → draftwright-0.4.24}/tests/fixtures/evaluation/countersink-mixed-pair.step +0 -0
  164. {draftwright-0.4.23 → draftwright-0.4.24}/tests/fixtures/evaluation/countersink-single.step +0 -0
  165. {draftwright-0.4.23 → draftwright-0.4.24}/tests/fixtures/evaluation/countersink-topology-a.step +0 -0
  166. {draftwright-0.4.23 → draftwright-0.4.24}/tests/fixtures/evaluation/countersink-topology-b.step +0 -0
  167. {draftwright-0.4.23 → draftwright-0.4.24}/tests/fixtures/evaluation/double-d-axis-x.step +0 -0
  168. {draftwright-0.4.23 → draftwright-0.4.24}/tests/fixtures/evaluation/double-d-axis-y.step +0 -0
  169. {draftwright-0.4.23 → draftwright-0.4.24}/tests/fixtures/evaluation/double-d-blind.step +0 -0
  170. {draftwright-0.4.23 → draftwright-0.4.24}/tests/fixtures/evaluation/double-d-coaxial-compound.step +0 -0
  171. {draftwright-0.4.23 → draftwright-0.4.24}/tests/fixtures/evaluation/double-d-opposed-blind.step +0 -0
  172. {draftwright-0.4.23 → draftwright-0.4.24}/tests/fixtures/evaluation/double-d-roll-30.step +0 -0
  173. {draftwright-0.4.23 → draftwright-0.4.24}/tests/fixtures/evaluation/double-d-round-bore.step +0 -0
  174. {draftwright-0.4.23 → draftwright-0.4.24}/tests/fixtures/evaluation/double-d-single-z.step +0 -0
  175. {draftwright-0.4.23 → draftwright-0.4.24}/tests/fixtures/evaluation/double-d-topology-a.step +0 -0
  176. {draftwright-0.4.23 → draftwright-0.4.24}/tests/fixtures/evaluation/double-d-topology-b.step +0 -0
  177. {draftwright-0.4.23 → draftwright-0.4.24}/tests/fixtures/evaluation/fillet-compound.step +0 -0
  178. {draftwright-0.4.23 → draftwright-0.4.24}/tests/fixtures/evaluation/fillet-overlap.step +0 -0
  179. {draftwright-0.4.23 → draftwright-0.4.24}/tests/fixtures/evaluation/fillet-plain.step +0 -0
  180. {draftwright-0.4.23 → draftwright-0.4.24}/tests/fixtures/evaluation/fillet-planar-x.step +0 -0
  181. {draftwright-0.4.23 → draftwright-0.4.24}/tests/fixtures/evaluation/fillet-planar-y.step +0 -0
  182. {draftwright-0.4.23 → draftwright-0.4.24}/tests/fixtures/evaluation/fillet-planar-z.step +0 -0
  183. {draftwright-0.4.23 → draftwright-0.4.24}/tests/fixtures/evaluation/fillet-repeated.step +0 -0
  184. {draftwright-0.4.23 → draftwright-0.4.24}/tests/fixtures/evaluation/fillet-topology-a.step +0 -0
  185. {draftwright-0.4.23 → draftwright-0.4.24}/tests/fixtures/evaluation/fillet-topology-b.step +0 -0
  186. {draftwright-0.4.23 → draftwright-0.4.24}/tests/fixtures/evaluation/fillet-turned.step +0 -0
  187. {draftwright-0.4.23 → draftwright-0.4.24}/tests/fixtures/evaluation/flat-coaxial.step +0 -0
  188. {draftwright-0.4.23 → draftwright-0.4.24}/tests/fixtures/evaluation/flat-double-d.step +0 -0
  189. {draftwright-0.4.23 → draftwright-0.4.24}/tests/fixtures/evaluation/flat-lone-d.step +0 -0
  190. {draftwright-0.4.23 → draftwright-0.4.24}/tests/fixtures/evaluation/flat-nonround.step +0 -0
  191. {draftwright-0.4.23 → draftwright-0.4.24}/tests/fixtures/evaluation/flat-slanted-double-d.step +0 -0
  192. {draftwright-0.4.23 → draftwright-0.4.24}/tests/fixtures/evaluation/flat-topology-a.step +0 -0
  193. {draftwright-0.4.23 → draftwright-0.4.24}/tests/fixtures/evaluation/flat-topology-b.step +0 -0
  194. {draftwright-0.4.23 → draftwright-0.4.24}/tests/fixtures/evaluation/groove-compound.step +0 -0
  195. {draftwright-0.4.23 → draftwright-0.4.24}/tests/fixtures/evaluation/groove-lone-x.step +0 -0
  196. {draftwright-0.4.23 → draftwright-0.4.24}/tests/fixtures/evaluation/groove-lone-y.step +0 -0
  197. {draftwright-0.4.23 → draftwright-0.4.24}/tests/fixtures/evaluation/groove-lone-z.step +0 -0
  198. {draftwright-0.4.23 → draftwright-0.4.24}/tests/fixtures/evaluation/groove-monotonic-negative.step +0 -0
  199. {draftwright-0.4.23 → draftwright-0.4.24}/tests/fixtures/evaluation/groove-narrow.step +0 -0
  200. {draftwright-0.4.23 → draftwright-0.4.24}/tests/fixtures/evaluation/groove-topology-a.step +0 -0
  201. {draftwright-0.4.23 → draftwright-0.4.24}/tests/fixtures/evaluation/groove-topology-b.step +0 -0
  202. {draftwright-0.4.23 → draftwright-0.4.24}/tests/fixtures/evaluation/pad-compound-equal.step +0 -0
  203. {draftwright-0.4.23 → draftwright-0.4.24}/tests/fixtures/evaluation/pad-detached-body-negative.step +0 -0
  204. {draftwright-0.4.23 → draftwright-0.4.24}/tests/fixtures/evaluation/pad-full-span-ledge-negative.step +0 -0
  205. {draftwright-0.4.23 → draftwright-0.4.24}/tests/fixtures/evaluation/pad-nested-staircase-negative.step +0 -0
  206. {draftwright-0.4.23 → draftwright-0.4.24}/tests/fixtures/evaluation/pad-topology-a.step +0 -0
  207. {draftwright-0.4.23 → draftwright-0.4.24}/tests/fixtures/evaluation/pad-topology-b.step +0 -0
  208. {draftwright-0.4.23 → draftwright-0.4.24}/tests/fixtures/evaluation/pad-x-negative.step +0 -0
  209. {draftwright-0.4.23 → draftwright-0.4.24}/tests/fixtures/evaluation/pad-x-positive.step +0 -0
  210. {draftwright-0.4.23 → draftwright-0.4.24}/tests/fixtures/evaluation/pad-y-negative.step +0 -0
  211. {draftwright-0.4.23 → draftwright-0.4.24}/tests/fixtures/evaluation/pad-y-positive.step +0 -0
  212. {draftwright-0.4.23 → draftwright-0.4.24}/tests/fixtures/evaluation/pad-z-negative.step +0 -0
  213. {draftwright-0.4.23 → draftwright-0.4.24}/tests/fixtures/evaluation/pad-z-positive.step +0 -0
  214. {draftwright-0.4.23 → draftwright-0.4.24}/tests/fixtures/evaluation/pattern-ambiguous.step +0 -0
  215. {draftwright-0.4.23 → draftwright-0.4.24}/tests/fixtures/evaluation/pattern-grid.step +0 -0
  216. {draftwright-0.4.23 → draftwright-0.4.24}/tests/fixtures/evaluation/pattern-topology-a.step +0 -0
  217. {draftwright-0.4.23 → draftwright-0.4.24}/tests/fixtures/evaluation/pattern-topology-b.step +0 -0
  218. {draftwright-0.4.23 → draftwright-0.4.24}/tests/fixtures/evaluation/plain-block.step +0 -0
  219. {draftwright-0.4.23 → draftwright-0.4.24}/tests/fixtures/evaluation/plate-compound-equal.step +0 -0
  220. {draftwright-0.4.23 → draftwright-0.4.24}/tests/fixtures/evaluation/plate-cross-topology-a.step +0 -0
  221. {draftwright-0.4.23 → draftwright-0.4.24}/tests/fixtures/evaluation/plate-cross-topology-b.step +0 -0
  222. {draftwright-0.4.23 → draftwright-0.4.24}/tests/fixtures/evaluation/plate-detached-negative.step +0 -0
  223. {draftwright-0.4.23 → draftwright-0.4.24}/tests/fixtures/evaluation/plate-rotational-negative.step +0 -0
  224. {draftwright-0.4.23 → draftwright-0.4.24}/tests/fixtures/evaluation/plate-single-negative.step +0 -0
  225. {draftwright-0.4.23 → draftwright-0.4.24}/tests/fixtures/evaluation/plate-t-xz.step +0 -0
  226. {draftwright-0.4.23 → draftwright-0.4.24}/tests/fixtures/evaluation/plate-t-yz.step +0 -0
  227. {draftwright-0.4.23 → draftwright-0.4.24}/tests/fixtures/evaluation/plate-thick-negative.step +0 -0
  228. {draftwright-0.4.23 → draftwright-0.4.24}/tests/fixtures/evaluation/plate-u-additive.step +0 -0
  229. {draftwright-0.4.23 → draftwright-0.4.24}/tests/fixtures/evaluation/plate-u-cut.step +0 -0
  230. {draftwright-0.4.23 → draftwright-0.4.24}/tests/fixtures/evaluation/pocket-compound.step +0 -0
  231. {draftwright-0.4.23 → draftwright-0.4.24}/tests/fixtures/evaluation/pocket-edge-anchored.step +0 -0
  232. {draftwright-0.4.23 → draftwright-0.4.24}/tests/fixtures/evaluation/pocket-lone.step +0 -0
  233. {draftwright-0.4.23 → draftwright-0.4.24}/tests/fixtures/evaluation/pocket-opposed.step +0 -0
  234. {draftwright-0.4.23 → draftwright-0.4.24}/tests/fixtures/evaluation/pocket-pattern-ambiguous.step +0 -0
  235. {draftwright-0.4.23 → draftwright-0.4.24}/tests/fixtures/evaluation/pocket-pattern-grid.step +0 -0
  236. {draftwright-0.4.23 → draftwright-0.4.24}/tests/fixtures/evaluation/pocket-pattern-linear.step +0 -0
  237. {draftwright-0.4.23 → draftwright-0.4.24}/tests/fixtures/evaluation/pocket-pattern-pair.step +0 -0
  238. {draftwright-0.4.23 → draftwright-0.4.24}/tests/fixtures/evaluation/pocket-pattern-topology-a.step +0 -0
  239. {draftwright-0.4.23 → draftwright-0.4.24}/tests/fixtures/evaluation/pocket-pattern-topology-b.step +0 -0
  240. {draftwright-0.4.23 → draftwright-0.4.24}/tests/fixtures/evaluation/pocket-prismatic-negative.step +0 -0
  241. {draftwright-0.4.23 → draftwright-0.4.24}/tests/fixtures/evaluation/pocket-side.step +0 -0
  242. {draftwright-0.4.23 → draftwright-0.4.24}/tests/fixtures/evaluation/pocket-through-negative.step +0 -0
  243. {draftwright-0.4.23 → draftwright-0.4.24}/tests/fixtures/evaluation/pocket-topology-a.step +0 -0
  244. {draftwright-0.4.23 → draftwright-0.4.24}/tests/fixtures/evaluation/pocket-topology-b.step +0 -0
  245. {draftwright-0.4.23 → draftwright-0.4.24}/tests/fixtures/evaluation/pocket-two-equal.step +0 -0
  246. {draftwright-0.4.23 → draftwright-0.4.24}/tests/fixtures/evaluation/polygonal-boss-compound-equal.step +0 -0
  247. {draftwright-0.4.23 → draftwright-0.4.24}/tests/fixtures/evaluation/polygonal-boss-detached-negative.step +0 -0
  248. {draftwright-0.4.23 → draftwright-0.4.24}/tests/fixtures/evaluation/polygonal-boss-in-plane-rotated.step +0 -0
  249. {draftwright-0.4.23 → draftwright-0.4.24}/tests/fixtures/evaluation/polygonal-boss-other-protrusions-negative.step +0 -0
  250. {draftwright-0.4.23 → draftwright-0.4.24}/tests/fixtures/evaluation/polygonal-boss-recess-negative.step +0 -0
  251. {draftwright-0.4.23 → draftwright-0.4.24}/tests/fixtures/evaluation/polygonal-boss-stock-negative.step +0 -0
  252. {draftwright-0.4.23 → draftwright-0.4.24}/tests/fixtures/evaluation/polygonal-boss-topology-a.step +0 -0
  253. {draftwright-0.4.23 → draftwright-0.4.24}/tests/fixtures/evaluation/polygonal-boss-topology-b.step +0 -0
  254. {draftwright-0.4.23 → draftwright-0.4.24}/tests/fixtures/evaluation/polygonal-boss-x.step +0 -0
  255. {draftwright-0.4.23 → draftwright-0.4.24}/tests/fixtures/evaluation/polygonal-boss-y.step +0 -0
  256. {draftwright-0.4.23 → draftwright-0.4.24}/tests/fixtures/evaluation/polygonal-boss-z.step +0 -0
  257. {draftwright-0.4.23 → draftwright-0.4.24}/tests/fixtures/evaluation/polygonal-stock-compound-negative.step +0 -0
  258. {draftwright-0.4.23 → draftwright-0.4.24}/tests/fixtures/evaluation/polygonal-stock-cylinder-negative.step +0 -0
  259. {draftwright-0.4.23 → draftwright-0.4.24}/tests/fixtures/evaluation/polygonal-stock-irregular-negative.step +0 -0
  260. {draftwright-0.4.23 → draftwright-0.4.24}/tests/fixtures/evaluation/polygonal-stock-octagon-negative.step +0 -0
  261. {draftwright-0.4.23 → draftwright-0.4.24}/tests/fixtures/evaluation/polygonal-stock-recess-negative.step +0 -0
  262. {draftwright-0.4.23 → draftwright-0.4.24}/tests/fixtures/evaluation/polygonal-stock-roll17.step +0 -0
  263. {draftwright-0.4.23 → draftwright-0.4.24}/tests/fixtures/evaluation/polygonal-stock-topology-a.step +0 -0
  264. {draftwright-0.4.23 → draftwright-0.4.24}/tests/fixtures/evaluation/polygonal-stock-topology-b.step +0 -0
  265. {draftwright-0.4.23 → draftwright-0.4.24}/tests/fixtures/evaluation/polygonal-stock-translated.step +0 -0
  266. {draftwright-0.4.23 → draftwright-0.4.24}/tests/fixtures/evaluation/polygonal-stock-x.step +0 -0
  267. {draftwright-0.4.23 → draftwright-0.4.24}/tests/fixtures/evaluation/polygonal-stock-y.step +0 -0
  268. {draftwright-0.4.23 → draftwright-0.4.24}/tests/fixtures/evaluation/topology-a.step +0 -0
  269. {draftwright-0.4.23 → draftwright-0.4.24}/tests/fixtures/evaluation/topology-b.step +0 -0
  270. {draftwright-0.4.23 → draftwright-0.4.24}/tests/fixtures/evaluation/turned-step-axis-x.step +0 -0
  271. {draftwright-0.4.23 → draftwright-0.4.24}/tests/fixtures/evaluation/turned-step-axis-y.step +0 -0
  272. {draftwright-0.4.23 → draftwright-0.4.24}/tests/fixtures/evaluation/turned-step-axis-z.step +0 -0
  273. {draftwright-0.4.23 → draftwright-0.4.24}/tests/fixtures/evaluation/turned-step-compound.step +0 -0
  274. {draftwright-0.4.23 → draftwright-0.4.24}/tests/fixtures/evaluation/turned-step-repeated-lengths.step +0 -0
  275. {draftwright-0.4.23 → draftwright-0.4.24}/tests/fixtures/evaluation/turned-step-through-bore.step +0 -0
  276. {draftwright-0.4.23 → draftwright-0.4.24}/tests/fixtures/evaluation/turned-step-topology-a.step +0 -0
  277. {draftwright-0.4.23 → draftwright-0.4.24}/tests/fixtures/evaluation/turned-step-topology-b.step +0 -0
  278. {draftwright-0.4.23 → draftwright-0.4.24}/tests/fixtures/evaluation/turned-step-translated-blind-bore.step +0 -0
  279. {draftwright-0.4.23 → draftwright-0.4.24}/tests/fixtures/grm03_thumbwheel_drive_screw.step +0 -0
  280. {draftwright-0.4.23 → draftwright-0.4.24}/tests/fixtures/grm03_thumbwheel_drive_screw_ap242_pmi.step +0 -0
  281. {draftwright-0.4.23 → draftwright-0.4.24}/tests/fixtures/grm04_drive_plate.step +0 -0
  282. {draftwright-0.4.23 → draftwright-0.4.24}/tests/fixtures/if_step_flat_across_cylinder.step +0 -0
  283. {draftwright-0.4.23 → draftwright-0.4.24}/tests/fixtures/issue_1058_wheel_rh.step +0 -0
  284. {draftwright-0.4.23 → draftwright-0.4.24}/tests/fixtures/issue_1247_angled_blind_step.step +0 -0
  285. {draftwright-0.4.23 → draftwright-0.4.24}/tests/fixtures/issue_909_basic_part_design_017_body.step +0 -0
  286. {draftwright-0.4.23 → draftwright-0.4.24}/tests/fixtures/issue_915_case_study_2.step +0 -0
  287. {draftwright-0.4.23 → draftwright-0.4.24}/tests/fixtures/nist_ctc_01_asme1_ap203.stp +0 -0
  288. {draftwright-0.4.23 → draftwright-0.4.24}/tests/fixtures/nist_ctc_01_asme1_ap242.stp +0 -0
  289. {draftwright-0.4.23 → draftwright-0.4.24}/tests/fixtures/nist_ctc_02_asme1_ap203.stp +0 -0
  290. {draftwright-0.4.23 → draftwright-0.4.24}/tests/fixtures/nist_ctc_02_asme1_ap242.stp +0 -0
  291. {draftwright-0.4.23 → draftwright-0.4.24}/tests/fixtures/nist_ctc_03_asme1_ap203.stp +0 -0
  292. {draftwright-0.4.23 → draftwright-0.4.24}/tests/fixtures/nist_ctc_03_asme1_ap242.stp +0 -0
  293. {draftwright-0.4.23 → draftwright-0.4.24}/tests/fixtures/nist_ctc_04_asme1_ap203.stp +0 -0
  294. {draftwright-0.4.23 → draftwright-0.4.24}/tests/fixtures/nist_ctc_04_asme1_ap242.stp +0 -0
  295. {draftwright-0.4.23 → draftwright-0.4.24}/tests/fixtures/nist_ctc_05_asme1_ap203.stp +0 -0
  296. {draftwright-0.4.23 → draftwright-0.4.24}/tests/fixtures/nist_ctc_05_asme1_ap242.stp +0 -0
  297. {draftwright-0.4.23 → draftwright-0.4.24}/tests/fixtures/tuner_jig_blind_obround_pockets.step +0 -0
  298. {draftwright-0.4.23 → draftwright-0.4.24}/tests/refactor_golden/bracket_section.json +0 -0
  299. {draftwright-0.4.23 → draftwright-0.4.24}/tests/refactor_golden/centered_rebate.json +0 -0
  300. {draftwright-0.4.23 → draftwright-0.4.24}/tests/refactor_golden/chamfered.json +0 -0
  301. {draftwright-0.4.23 → draftwright-0.4.24}/tests/refactor_golden/filleted.json +0 -0
  302. {draftwright-0.4.23 → draftwright-0.4.24}/tests/refactor_golden/flange_dense.json +0 -0
  303. {draftwright-0.4.23 → draftwright-0.4.24}/tests/refactor_golden/grid_plate.json +0 -0
  304. {draftwright-0.4.23 → draftwright-0.4.24}/tests/refactor_golden/grooved_shaft.json +0 -0
  305. {draftwright-0.4.23 → draftwright-0.4.24}/tests/refactor_golden/hex_bar.json +0 -0
  306. {draftwright-0.4.23 → draftwright-0.4.24}/tests/refactor_golden/holed_slot.json +0 -0
  307. {draftwright-0.4.23 → draftwright-0.4.24}/tests/refactor_golden/pocketed.json +0 -0
  308. {draftwright-0.4.23 → draftwright-0.4.24}/tests/refactor_golden/prismatic_ladder.json +0 -0
  309. {draftwright-0.4.23 → draftwright-0.4.24}/tests/refactor_golden/scattered_plate.json +0 -0
  310. {draftwright-0.4.23 → draftwright-0.4.24}/tests/refactor_golden/side_drilled.json +0 -0
  311. {draftwright-0.4.23 → draftwright-0.4.24}/tests/refactor_golden/turned_stepped.json +0 -0
  312. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_add_dimension.py +0 -0
  313. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_adr0018_arrangement_gate.py +0 -0
  314. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_adr0018_view_routing.py +0 -0
  315. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_adr0018_view_selection.py +0 -0
  316. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_adr_corpus.py +0 -0
  317. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_agents_guide.py +0 -0
  318. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_api_docs.py +0 -0
  319. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_architecture_docs.py +0 -0
  320. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_audit_differential.py +0 -0
  321. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_balloon_ring_standoff.py +0 -0
  322. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_build_profile_harness.py +0 -0
  323. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_carve_free_position_callers.py +0 -0
  324. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_clone_budget.py +0 -0
  325. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_compiled_plan_boundary.py +0 -0
  326. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_counting_calls.py +0 -0
  327. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_declare.py +0 -0
  328. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_dense_sheet_canary.py +0 -0
  329. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_deprecation_dates.py +0 -0
  330. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_detect_once.py +0 -0
  331. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_detect_registry.py +0 -0
  332. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_dimension_role_vocabulary.py +0 -0
  333. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_drawing_encapsulation.py +0 -0
  334. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_e2e_slice.py +0 -0
  335. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_e2e_standards.py +0 -0
  336. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_export_dxf_curves.py +0 -0
  337. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_export_dxf_zoom.py +0 -0
  338. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_export_reproducible.py +0 -0
  339. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_external_recognition_boundary.py +0 -0
  340. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_fillets_adjacency.py +0 -0
  341. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_fits.py +0 -0
  342. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_flat_completeness.py +0 -0
  343. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_flat_stock_identity.py +0 -0
  344. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_flat_stock_opposition.py +0 -0
  345. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_gdt_placement.py +0 -0
  346. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_geometry_graph_spike.py +0 -0
  347. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_grid_lattice_convention.py +0 -0
  348. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_import_boundaries.py +0 -0
  349. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_inspection_contract.py +0 -0
  350. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_iso_nts_caption_placement.py +0 -0
  351. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_issue_1000_envelope_reuse.py +0 -0
  352. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_issue_1006_measurement_comparison.py +0 -0
  353. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_issue_1058_wheel_profile.py +0 -0
  354. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_issue_1073_cross_body_patterns.py +0 -0
  355. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_issue_1082_polygonal_stock.py +0 -0
  356. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_issue_1086_declared_gears.py +0 -0
  357. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_issue_1116_ap242_hole_tolerance_lowering.py +0 -0
  358. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_issue_1130_view_planning_evidence.py +0 -0
  359. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_issue_1142_hole_leader_labels.py +0 -0
  360. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_issue_1143_hole_completeness.py +0 -0
  361. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_issue_1144_transactional_hole_table.py +0 -0
  362. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_issue_1146_scale_completeness.py +0 -0
  363. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_issue_1147_legibility_pair_aggregation.py +0 -0
  364. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_issue_1153_contradictory_dimensions.py +0 -0
  365. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_issue_1154_one_owner_per_measurement.py +0 -0
  366. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_issue_1155_grm04_sheet_use.py +0 -0
  367. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_issue_1166_cross_pass_feature_leaders.py +0 -0
  368. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_issue_1176_quality_fidelity.py +0 -0
  369. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_issue_1177_angular_dimensions.py +0 -0
  370. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_issue_1187_unroutable_leaders.py +0 -0
  371. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_issue_1188_per_view_assignment.py +0 -0
  372. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_issue_1190_section_decision.py +0 -0
  373. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_issue_1196_deterministic_view_names.py +0 -0
  374. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_issue_1202_observed_drawing_consumer.py +0 -0
  375. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_issue_1204_multiscale_view_issues.py +0 -0
  376. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_issue_1209_linear_pmi_witnesses.py +0 -0
  377. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_issue_1215_envelope_tolerance.py +0 -0
  378. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_issue_1215_no_approved_tolerance_is_dropped.py +0 -0
  379. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_issue_1216_callout_reservation_measures_ink.py +0 -0
  380. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_issue_1216_pairwise_across_scale_groups.py +0 -0
  381. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_issue_1217_claimed_representations.py +0 -0
  382. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_issue_1217_the_facility_is_shared.py +0 -0
  383. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_issue_1219_location_claims_its_own_axis.py +0 -0
  384. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_issue_1229_ledger_member_keying.py +0 -0
  385. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_issue_1240_iso_above_strip_visibility.py +0 -0
  386. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_issue_1245_passage_disposition.py +0 -0
  387. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_issue_1246_prismatic_pocket_disposition.py +0 -0
  388. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_issue_1247_angled_step_disposition.py +0 -0
  389. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_issue_1254_turned_chamfers.py +0 -0
  390. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_issue_1260_view_constraints.py +0 -0
  391. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_issue_1262_automatic_turned_views.py +0 -0
  392. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_issue_1276_turned_leader_targets.py +0 -0
  393. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_issue_1281_turned_fillets.py +0 -0
  394. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_issue_1296_cylindrical_diameter_pmi.py +0 -0
  395. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_issue_1298_manufacturing_requirements.py +0 -0
  396. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_issue_1299_page_escalation.py +0 -0
  397. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_issue_1308_machined_leader_analytics.py +0 -0
  398. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_issue_1312_engine_costs.py +0 -0
  399. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_issue_1325_nominal_agreement.py +0 -0
  400. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_issue_1332_overlap_remedy.py +0 -0
  401. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_issue_1332_zone_labels.py +0 -0
  402. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_issue_1333_bounded_ink_repair.py +0 -0
  403. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_issue_1334_prevent_ink.py +0 -0
  404. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_issue_1336_grm03_ap242_pmi_fixture.py +0 -0
  405. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_issue_1338_scale_before_page_escalation.py +0 -0
  406. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_issue_1349_precision_display.py +0 -0
  407. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_issue_1350_detected_takeover.py +0 -0
  408. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_issue_1351_structured_note_coverage.py +0 -0
  409. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_issue_1352_searchable_pdf_text.py +0 -0
  410. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_issue_1353_cnc_authoritative_workflow.py +0 -0
  411. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_issue_1357_framed_activation.py +0 -0
  412. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_issue_1357_framed_boundary.py +0 -0
  413. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_issue_1357_plural_turned_profiles.py +0 -0
  414. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_issue_1357_pmi_frame.py +0 -0
  415. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_issue_1360_thread_depth.py +0 -0
  416. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_issue_1369_hole_completeness_evidence.py +0 -0
  417. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_issue_1370_countersink_completeness_evidence.py +0 -0
  418. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_issue_1370_double_d_completeness_evidence.py +0 -0
  419. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_issue_1370_hole_pattern_completeness_evidence.py +0 -0
  420. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_issue_1371_flat_completeness_evidence.py +0 -0
  421. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_issue_1371_polygonal_stock_completeness_evidence.py +0 -0
  422. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_issue_1372_groove_completeness_evidence.py +0 -0
  423. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_issue_1372_pad_completeness_evidence.py +0 -0
  424. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_issue_1372_pocket_completeness_evidence.py +0 -0
  425. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_issue_1372_pocket_pattern_completeness_evidence.py +0 -0
  426. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_issue_1372_polygonal_boss_completeness_evidence.py +0 -0
  427. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_issue_1373_plate_completeness_evidence.py +0 -0
  428. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_issue_1374_chamfer_completeness_evidence.py +0 -0
  429. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_issue_1374_fillet_completeness_evidence.py +0 -0
  430. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_issue_1374_turned_step_completeness_evidence.py +0 -0
  431. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_issue_1378_diameter_leader_targets.py +0 -0
  432. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_issue_1382_046_step_inventory.py +0 -0
  433. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_issue_1382_circular_blind_step_semantics.py +0 -0
  434. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_issue_1382_framed_step_family_evidence.py +0 -0
  435. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_issue_1382_paired_ramp_semantics.py +0 -0
  436. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_issue_1382_through_step_semantics.py +0 -0
  437. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_issue_1390_sheet_registration.py +0 -0
  438. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_issue_1392_recognisers_048.py +0 -0
  439. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_issue_1395_degenerate_iso_region.py +0 -0
  440. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_issue_1396_layout_advisories.py +0 -0
  441. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_issue_1397_unverifiable_requirement_message.py +0 -0
  442. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_issue_1421_rectangular_blind_slot_completeness.py +0 -0
  443. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_issue_1421_rectangular_blind_slot_semantics.py +0 -0
  444. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_issue_1421_round_bottom_blind_slot_completeness.py +0 -0
  445. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_issue_1421_round_bottom_blind_slot_semantics.py +0 -0
  446. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_issue_1432_adoption.py +0 -0
  447. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_issue_1432_boundary_failures.py +0 -0
  448. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_issue_1432_oriented_slot_semantics.py +0 -0
  449. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_issue_1433_blend_semantics.py +0 -0
  450. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_issue_1438_boss_ownership.py +0 -0
  451. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_issue_1438_channel_ownership.py +0 -0
  452. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_issue_1438_cli_report_sidecar.py +0 -0
  453. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_issue_1438_generation_snapshot.py +0 -0
  454. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_issue_1438_nested_ownership.py +0 -0
  455. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_issue_1438_occurrence_ownership.py +0 -0
  456. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_issue_1438_pattern_ownership.py +0 -0
  457. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_issue_1438_plate_ownership.py +0 -0
  458. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_issue_1438_policy_dispositions.py +0 -0
  459. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_issue_1438_report_projection.py +0 -0
  460. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_issue_1438_report_writer.py +0 -0
  461. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_issue_1438_through_step_ownership.py +0 -0
  462. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_issue_1438_turned_step_ownership.py +0 -0
  463. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_issue_1450_boss_blend_ownership.py +0 -0
  464. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_issue_1460_step_inspection.py +0 -0
  465. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_issue_1466_dimension_options.py +0 -0
  466. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_issue_1466_semantic_sides.py +0 -0
  467. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_issue_1471_boundary_failures.py +0 -0
  468. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_issue_1471_evidence_schema.py +0 -0
  469. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_issue_1471_groove_profile.py +0 -0
  470. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_issue_1471_section_recess_contract.py +0 -0
  471. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_issue_1471_section_recess_pockets.py +0 -0
  472. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_issue_1479_radius_leader_targets.py +0 -0
  473. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_issue_1485_curved_pockets.py +0 -0
  474. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_issue_1485_quiddity_024_boundary.py +0 -0
  475. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_issue_1485_rounded_pockets.py +0 -0
  476. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_issue_1504_angle_patterns.py +0 -0
  477. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_issue_1504_angular_references.py +0 -0
  478. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_issue_1504_angular_rendering.py +0 -0
  479. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_issue_1504_canonical_angles.py +0 -0
  480. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_issue_1504_profile_angles.py +0 -0
  481. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_issue_1505_diameter_coverage.py +0 -0
  482. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_issue_1505_short_axial_chains.py +0 -0
  483. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_issue_367_leader_ink.py +0 -0
  484. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_issue_443_grm03_axial_coverage.py +0 -0
  485. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_issue_563_placement_intent.py +0 -0
  486. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_issue_676_polygonal_boss.py +0 -0
  487. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_issue_676_polygonal_boss_declare.py +0 -0
  488. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_issue_798_floor_cardinality.py +0 -0
  489. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_issue_798_material_field.py +0 -0
  490. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_issue_798_silhouette_lint.py +0 -0
  491. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_issue_827_real_part_canary.py +0 -0
  492. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_issue_883_location_identity.py +0 -0
  493. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_issue_885_prismatic_coverage.py +0 -0
  494. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_issue_909_sloped_profile.py +0 -0
  495. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_issue_915_dense_case.py +0 -0
  496. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_issue_916_pocket_leader.py +0 -0
  497. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_issue_917_open_channel.py +0 -0
  498. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_issue_924_zero_length_shoulders.py +0 -0
  499. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_issue_955_height_contingency.py +0 -0
  500. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_issue_958_cross_solid_recognition.py +0 -0
  501. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_label_provenance.py +0 -0
  502. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_layout.py +0 -0
  503. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_layout_cleanliness.py +0 -0
  504. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_layout_hypothesis.py +0 -0
  505. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_layout_property.py +0 -0
  506. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_leader_footprint.py +0 -0
  507. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_lint_box_cache.py +0 -0
  508. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_lint_ink_overlap.py +0 -0
  509. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_lint_reconciliation.py +0 -0
  510. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_lint_structural.py +0 -0
  511. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_linting.py +0 -0
  512. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_location_vocabulary.py +0 -0
  513. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_note_verb.py +0 -0
  514. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_object_aspects.py +0 -0
  515. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_occupancy_boxes.py +0 -0
  516. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_parameter_id.py +0 -0
  517. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_part_model.py +0 -0
  518. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_pitch_dim_footprint.py +0 -0
  519. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_pmi.py +0 -0
  520. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_pmi_datum_lowering.py +0 -0
  521. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_pmi_gtol_lowering.py +0 -0
  522. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_pmi_part21.py +0 -0
  523. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_pocket_pattern.py +0 -0
  524. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_pocket_pattern_recognition.py +0 -0
  525. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_principal_profile_classifier.py +0 -0
  526. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_private_test_attr_reads.py +0 -0
  527. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_private_test_imports.py +0 -0
  528. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_quality_components.py +0 -0
  529. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_recogniser_adoption.py +0 -0
  530. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_recogniser_capabilities.py +0 -0
  531. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_recogniser_contract.py +0 -0
  532. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_recognition_result.py +0 -0
  533. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_refactor_golden.py +0 -0
  534. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_registry.py +0 -0
  535. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_render_seam.py +0 -0
  536. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_repack_geometry_seam.py +0 -0
  537. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_score.py +0 -0
  538. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_script_detail_parity.py +0 -0
  539. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_shared_box_memo.py +0 -0
  540. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_sheet_emit.py +0 -0
  541. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_sheet_gdt.py +0 -0
  542. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_sheet_identity_invariant.py +0 -0
  543. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_sheet_notes.py +0 -0
  544. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_sheet_of.py +0 -0
  545. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_sheet_section.py +0 -0
  546. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_sheet_tables.py +0 -0
  547. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_slanted_blind_step.py +0 -0
  548. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_slot_completeness.py +0 -0
  549. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_slot_pattern.py +0 -0
  550. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_slot_pattern_recognition.py +0 -0
  551. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_soft_deprecation.py +0 -0
  552. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_solve_trace.py +0 -0
  553. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_step_analysis_evaluation.py +0 -0
  554. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_strip_layout.py +0 -0
  555. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_suppression_ledger.py +0 -0
  556. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_suppression_marks.py +0 -0
  557. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_tolerances.py +0 -0
  558. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_turned_steps.py +0 -0
  559. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_version_bump_ci.py +0 -0
  560. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_view_plan.py +0 -0
  561. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_witness_label_reconciliation.py +0 -0
  562. {draftwright-0.4.23 → draftwright-0.4.24}/tests/test_workflows.py +0 -0
@@ -478,6 +478,10 @@
478
478
 
479
479
  ### Fixed
480
480
 
481
+ - Overall height and envelope width remain dimensioned when approved turned-step lengths
482
+ cover only part of the respective extent. Redundancy suppression now requires adjoining
483
+ measurements on one profile to reach both overall endpoints; STC618 retains its missing
484
+ 62 mm height (#1509).
481
485
  - Non-1:1 orthographic and isometric projection now scales extracted solids about the world
482
486
  origin, matching the view-coordinate mapper and solver zones. Solids carrying a non-zero
483
487
  build123d `Location` no longer shift their silhouette away from dimensions and callouts.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: draftwright
3
- Version: 0.4.23
3
+ Version: 0.4.24
4
4
  Summary: Automated technical-drawing generation for build123d
5
5
  Project-URL: Homepage, https://github.com/pzfreo/draftwright
6
6
  Project-URL: Repository, https://github.com/pzfreo/draftwright
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "draftwright"
7
- version = "0.4.23"
7
+ version = "0.4.24"
8
8
  description = "Automated technical-drawing generation for build123d"
9
9
  readme = "README.md"
10
10
  license = { file = "LICENSE" }
@@ -1790,7 +1790,8 @@ def render_diameters(dwg, plan, a, *, ctx, only=None) -> int:
1790
1790
  # to the clear side (the margin the feature sits at). Auto-pass only: the finalize
1791
1791
  # (only=) path replays recorded verbs and must not disturb pinned user dims.
1792
1792
  if only is None:
1793
- _reroute_crossing_diameters(dwg, ctx=ctx)
1793
+ # Rerouting must see the principal dimensions that registered before this pass.
1794
+ ctx.post_drain.append(lambda: _reroute_crossing_diameters(dwg, ctx=ctx))
1794
1795
  return placed
1795
1796
 
1796
1797
 
@@ -4123,9 +4124,7 @@ def render_polygonal_stock(dwg, plan, a, *, ctx) -> int:
4123
4124
 
4124
4125
 
4125
4126
  def render_boss_heights(dwg, plan, a, *, ctx) -> int:
4126
- """Queue prismatic boss heights and polygonal-stock lengths in a profile corridor."""
4127
- if a.is_rotational or a.profiles:
4128
- return 0
4127
+ """Queue approved boss heights and polygonal-stock lengths in a profile corridor."""
4129
4128
  tier = dwg.draft.font_size + 2 * dwg.draft.pad_around_text
4130
4129
  specs = {
4131
4130
  "z": ("front", "right", a.fv_zones.right, "x"),
@@ -96,13 +96,9 @@ def _n_right_strip_boss_heights(model) -> int:
96
96
  declared path (#1022) removed that accident — a declared model that states a boss but no
97
97
  height ladder reserved one slot, needed two, and the height was dropped silently.
98
98
 
99
- Mirrors ``render_boss_heights``' own guards: a turned model (any declared step) renders no
100
- boss heights at all, and only the Z-axis ones land right — X/Y bosses go to the *above*
101
- strips. A rotational part that declares a Z boss over-reserves by one slot; that is the
102
- conservative direction, and the same call the authored-Z-dim branch below makes.
99
+ Z-axis boss heights share this corridor even when a turned step chain is present.
100
+ X/Y heights reserve their profile-view above strips in ``_compose_anno_boxes``.
103
101
  """
104
- if any(getattr(f, "kind", None) == "step" for f in model.features):
105
- return 0
106
102
  occupants = [
107
103
  f
108
104
  for f in model.features
@@ -448,6 +444,14 @@ def _compose_anno_boxes(
448
444
  n_boss_h = _n_right_strip_boss_heights(model)
449
445
  # FV right dim ladder + the boss heights that share the strip with it
450
446
  boxes = [AnnoBox("right", _est_right_strip_depth(n_steps, n_boss_h))]
447
+ if any(
448
+ feature.kind in ("boss", "step") and feature.frame.axis == "y"
449
+ for feature in model.features
450
+ ):
451
+ # The end-on radial fan needs clearance alongside the overall-height slot.
452
+ # This is a minimum band; deeper ladder/bore reservations still win by max.
453
+ radial_reach = font_size + 6 * pad_around_text
454
+ boxes.append(AnnoBox("right", _est_right_strip_depth(0) + radial_reach))
451
455
  requests = (
452
456
  model.authored_dimensions
453
457
  if model.authored_dimensions is not None
@@ -597,6 +601,37 @@ def _compose_anno_boxes(
597
601
  _reserve(view, "above")
598
602
  _reserve(view, "right")
599
603
 
604
+ # Axial boss sizes occupy the same profile corridors on detected and declared parts.
605
+ # Include them before view packing; a turned chain does not convey its end caps.
606
+ axial_corridors = set()
607
+ axial_features = [
608
+ feature
609
+ for feature in model.features
610
+ if feature.kind in ("boss", "polygonal_boss", "polygonal_stock")
611
+ and feature.frame.axis in ("x", "y")
612
+ ]
613
+ for group in plan_dimensions(model) if axial_features else ():
614
+ feature = group.feature
615
+ if feature.kind not in ("boss", "polygonal_boss", "polygonal_stock"):
616
+ continue
617
+ if feature.frame.axis not in ("x", "y"):
618
+ continue
619
+ view = "front" if feature.frame.axis == "x" else "side"
620
+ for dimension in group.dims:
621
+ if not dimension.suppressed and dimension.param.role in (
622
+ "boss_height",
623
+ "stock_length",
624
+ ):
625
+ _reserve(view, "above")
626
+ axial_corridors.add(view)
627
+ # The existing axial step chain already consumes one row in these corridors.
628
+ for view in sorted(axial_corridors):
629
+ axis = "x" if view == "front" else "y"
630
+ if any(
631
+ feature.kind == "step" and feature.frame.axis == axis for feature in model.features
632
+ ):
633
+ _reserve(view, "above")
634
+
600
635
  slot = _SLOT_DIM_STEP + _STRIP_SPACING
601
636
  # Front and plan occupy disjoint vertical ranges, so their left/right tiers are
602
637
  # reusable. Reserve the deepest one-view stack, not the sum of independent corridors.
@@ -3985,9 +3985,7 @@ class Drawing:
3985
3985
  issues += lint_claimed_representations(self._registry, dimension_plan)
3986
3986
  else:
3987
3987
  dimension_plan = None
3988
- # Turned bosses/bands remain in the OD + axial-step policy; this check is
3989
- # specifically for a prismatic boss's independent projection height.
3990
- if model is not None and (a is None or (not a.is_rotational and not a.profiles)):
3988
+ if model is not None:
3991
3989
  issues += lint_boss_height_coverage(
3992
3990
  working_part,
3993
3991
  self,
@@ -72,9 +72,14 @@ from draftwright.model.ir import (
72
72
  )
73
73
  from draftwright.model.planner import (
74
74
  _AUTHORED_OMISSION,
75
+ _CONSOLIDATED,
75
76
  DimensionId,
77
+ _authored_for,
76
78
  _decorated,
79
+ _extent_can_convey,
77
80
  _is_zero_step_position,
81
+ _request_for,
82
+ _selected_chain_covers_extent,
78
83
  angular_pattern_label,
79
84
  authored_location_axis_omitted,
80
85
  authored_location_omitted,
@@ -1049,6 +1054,21 @@ def _compile_step_ladders(model: PartModel, marked) -> tuple[list[ApprovedLadder
1049
1054
  return approved, omissions
1050
1055
 
1051
1056
 
1057
+ def _step_chain_covers_extent(
1058
+ model: PartModel, groups: list[ApprovedGroup], axis: Literal["x", "z"]
1059
+ ) -> bool:
1060
+ return _selected_chain_covers_extent(
1061
+ model,
1062
+ [
1063
+ (resolve_feature(group.ref), length)
1064
+ for group in groups
1065
+ if group.feature_kind in ("step", "groove")
1066
+ and (length := group.dim(kind="length")) is not None
1067
+ ],
1068
+ axis,
1069
+ )
1070
+
1071
+
1052
1072
  def _compile_overall_height(
1053
1073
  model: PartModel, marked, *, planned, include_overall: bool, step_chain_approved: bool
1054
1074
  ) -> tuple[ApprovedLadder | None, ApprovedContingency | None, list[Omission]]:
@@ -1585,7 +1605,22 @@ def _compile_slot_positions(model: PartModel) -> tuple[list[ApprovedDimension],
1585
1605
  return approved, omissions
1586
1606
 
1587
1607
 
1588
- def _compile_groups(planned) -> tuple[list[ApprovedGroup], list[Omission]]:
1608
+ def _dimension_witness_span(feature, parameter):
1609
+ """Carry a boss's axial stations at its cylindrical silhouette, even without a diameter mark."""
1610
+ span = parameter.span
1611
+ if feature.kind != "boss" or parameter.parameter_id != "boss_height.length" or span is None:
1612
+ return span
1613
+ radial = 0 if feature.frame.axis == "z" else 2
1614
+ rim = feature.frame.origin[radial] + feature.diameter / 2
1615
+ return tuple(
1616
+ tuple(rim if index == radial else value for index, value in enumerate(point))
1617
+ for point in span
1618
+ )
1619
+
1620
+
1621
+ def _compile_groups(
1622
+ planned, *, restore_width: bool = False
1623
+ ) -> tuple[list[ApprovedGroup], list[Omission]]:
1589
1624
  """Every planned group, reduced to what the compiler approved, plus what it withheld.
1590
1625
 
1591
1626
  The general path all remaining renderers migrate onto: same per-feature shape they
@@ -1602,6 +1637,17 @@ def _compile_groups(planned) -> tuple[list[ApprovedGroup], list[Omission]]:
1602
1637
  out: list[ApprovedGroup] = []
1603
1638
  omissions: list[Omission] = []
1604
1639
  for g in planned:
1640
+ # The planner's X-chain redundancy decision precedes chain approval.
1641
+ # Restore only that reason, preserving authored and unrelated omissions.
1642
+ dims = tuple(
1643
+ replace(pd, suppressed=False, reason=None)
1644
+ if restore_width
1645
+ and isinstance(g.feature, EnvelopeFeature)
1646
+ and pd.param.parameter_id == "width.length"
1647
+ and pd.reason == "X-turned (step-length chain conveys the length)"
1648
+ else pd
1649
+ for pd in g.dims
1650
+ )
1605
1651
  omissions.extend(
1606
1652
  Omission(
1607
1653
  g.feature,
@@ -1610,7 +1656,7 @@ def _compile_groups(planned) -> tuple[list[ApprovedGroup], list[Omission]]:
1610
1656
  pd.reason or "suppressed",
1611
1657
  conveyed_by=pd.conveyed_by,
1612
1658
  )
1613
- for pd in g.dims
1659
+ for pd in dims
1614
1660
  if pd.suppressed
1615
1661
  )
1616
1662
  approved = tuple(
@@ -1620,7 +1666,7 @@ def _compile_groups(planned) -> tuple[list[ApprovedGroup], list[Omission]]:
1620
1666
  # the boundary instead of implying a nullable state renderers cannot handle.
1621
1667
  value_text=_fmt(pd.param.value, pd.display_decimals),
1622
1668
  value=float(pd.param.value),
1623
- span=pd.param.span,
1669
+ span=_dimension_witness_span(g.feature, pd.param),
1624
1670
  ref=FeatureRef(g.feature),
1625
1671
  kind=pd.param.kind,
1626
1672
  role=pd.param.role,
@@ -1636,7 +1682,7 @@ def _compile_groups(planned) -> tuple[list[ApprovedGroup], list[Omission]]:
1636
1682
  view=pd.view,
1637
1683
  side=pd.side,
1638
1684
  )
1639
- for pd in g.dims
1685
+ for pd in dims
1640
1686
  if not pd.suppressed
1641
1687
  # A datum-coincident shoulder is not a zero-valued dimension the general group
1642
1688
  # may keep after the dedicated ladder rejected its identical endpoints. It is
@@ -1709,13 +1755,10 @@ def compile_dimensions(
1709
1755
  marked = _suppressed_dims(model, planned)
1710
1756
  ladders, omissions = _compile_step_ladders(model, marked)
1711
1757
  groups_out, group_omissions = _compile_groups(planned)
1758
+ if model.orientation == "x" and not _step_chain_covers_extent(model, groups_out, "x"):
1759
+ groups_out, group_omissions = _compile_groups(planned, restore_width=True)
1712
1760
  groups_out = _share_unique_outer_diameter(groups_out, planned)
1713
- step_chain_approved = any(
1714
- group.feature_kind == "step"
1715
- and group.facts.frame.axis == "z"
1716
- and group.dim(kind="length") is not None
1717
- for group in groups_out
1718
- )
1761
+ step_chain_approved = _step_chain_covers_extent(model, groups_out, "z")
1719
1762
  overall, contingency, height_omissions = _compile_overall_height(
1720
1763
  model,
1721
1764
  marked,
@@ -1737,6 +1780,9 @@ def compile_dimensions(
1737
1780
  omission.feature is overall_feature and omission.parameter_id == "height.length"
1738
1781
  )
1739
1782
  ]
1783
+ groups_out, group_omissions = _consolidate_boss_heights(
1784
+ model, planned, groups_out, group_omissions, overall
1785
+ )
1740
1786
  if overall is not None:
1741
1787
  ladders.append(overall)
1742
1788
  locations, location_omissions = _compile_locations(model)
@@ -1757,6 +1803,78 @@ def compile_dimensions(
1757
1803
  )
1758
1804
 
1759
1805
 
1806
+ def _consolidate_boss_heights(model, planned, groups, omissions, overall):
1807
+ """Reconcile boss heights with active extent owners, including synthetic and restored ones."""
1808
+ owners = [
1809
+ dimension
1810
+ for group in groups
1811
+ if group.feature_kind == "envelope"
1812
+ for dimension in group.dims
1813
+ if dimension.kind == "length" and dimension.role in ("width", "depth")
1814
+ ]
1815
+ if overall is not None:
1816
+ owners.extend(overall.rungs)
1817
+ extents = []
1818
+ for owner in owners:
1819
+ assert owner.id is not None
1820
+ extent = replace(
1821
+ next(
1822
+ parameter
1823
+ for parameter in owner.id.feature.parameters()
1824
+ if parameter.parameter_id == owner.id.parameter
1825
+ ),
1826
+ value=owner.value,
1827
+ span=owner.span,
1828
+ )
1829
+ extents.append((extent, owner.id))
1830
+ shared = {}
1831
+ for group in planned:
1832
+ if group.feature.kind != "boss":
1833
+ continue
1834
+ for dimension in group.dims:
1835
+ parameter = dimension.param
1836
+ if (
1837
+ parameter.parameter_id != "boss_height.length"
1838
+ or _request_for(model, group.feature, parameter) is not None
1839
+ or _authored_for(model, group.feature, parameter) is not None
1840
+ ):
1841
+ continue
1842
+ for extent, owner_id in extents:
1843
+ if _extent_can_convey(extent, parameter):
1844
+ shared[DimensionId(group.feature, parameter.parameter_id)] = (
1845
+ parameter,
1846
+ owner_id,
1847
+ )
1848
+ break
1849
+ if not shared:
1850
+ return groups, omissions
1851
+ retained = []
1852
+ for group in groups:
1853
+ dims = tuple(dimension for dimension in group.dims if dimension.id not in shared)
1854
+ if dims:
1855
+ retained.append(replace(group, dims=dims))
1856
+ updated = []
1857
+ recorded = set()
1858
+ for omission in omissions:
1859
+ identity = _dim_id(omission.feature, omission.parameter_id)
1860
+ if identity in shared:
1861
+ omission = replace(omission, conveyed_by=shared[identity][1])
1862
+ recorded.add(identity)
1863
+ updated.append(omission)
1864
+ for identity, (parameter, owner_id) in shared.items():
1865
+ if identity not in recorded:
1866
+ updated.append(
1867
+ Omission(
1868
+ identity.feature,
1869
+ identity.parameter,
1870
+ parameter.value,
1871
+ _CONSOLIDATED,
1872
+ conveyed_by=owner_id,
1873
+ )
1874
+ )
1875
+ return retained, updated
1876
+
1877
+
1760
1878
  def _share_unique_outer_diameter(groups: list[ApprovedGroup], planned) -> list[ApprovedGroup]:
1761
1879
  """Let a global OD carry one unique coaxial maximum band's approved identity.
1762
1880
 
@@ -474,6 +474,17 @@ def polygonal_stock_conveys_height(model: PartModel) -> bool:
474
474
  return any(f.kind == "polygonal_stock" for f in model.features)
475
475
 
476
476
 
477
+ def _extent_can_convey(extent: DimParameter, parameter: DimParameter) -> bool:
478
+ """An overall extent may replace an untoleranced local measurement of the same planes.
479
+
480
+ A tolerance on the owner is acceptable; a toleranced local requirement stays explicit.
481
+ Owner availability is decided by the caller, not by geometric coincidence.
482
+ """
483
+ return parameter.tolerance is None and _same_support_planes(
484
+ _support_planes(extent), _support_planes(parameter)
485
+ )
486
+
487
+
477
488
  def rotational_od_conveys_height(model: PartModel) -> bool:
478
489
  """An X/Y rotational OD conveys the overall height, so it is not drawn separately."""
479
490
  rot = next((f for f in model.features if f.kind == "rotational"), None)
@@ -586,31 +597,10 @@ def _consolidated_owner(model: PartModel, feature: Feature, param: DimParameter)
586
597
  if envelope.kind != "envelope":
587
598
  continue
588
599
  for extent in envelope.parameters():
589
- if not _same_support_planes(_support_planes(extent), planes):
600
+ if not _extent_can_convey(extent, param):
590
601
  continue
591
602
  if not _owner_drawn(model, envelope, extent):
592
603
  continue
593
- if param.tolerance is not None:
594
- # A toleranced dimension and an untoleranced one are not the same
595
- # requirement, so the overall extent cannot state this fact on its behalf.
596
- # Consolidating anyway DELETED a ±0.05 the author had written, silently and
597
- # with nothing in lint (#1154 review) — the one case where the feature-local
598
- # dimension is the one a machinist needs.
599
- #
600
- # ASYMMETRIC, and about the YIELDER alone. A tolerance on the OWNER is not a
601
- # problem — it is the same two faces, so it is the same requirement and one
602
- # dimension states it. The first cut refused whenever the two DIFFERED, which
603
- # brought the duplicate `8` back for anyone who toleranced the overall
604
- # thickness: this issue's own defect, re-opened by its fix (review r2).
605
- #
606
- # The correction then went one step too far and admitted "equal tolerances on
607
- # both sides", on the premise that the receiving extent states the same
608
- # requirement. It does not, ever: measured, an envelope decoration is not
609
- # rendered on any axis, while `render_boss_heights` appends `_tol_suffix`, so
610
- # a boss height toleranced identically to its envelope lost its ± anyway
611
- # (review r3). Whether the owner happens to print a tolerance is not this
612
- # rule's business — a toleranced measurement is simply never handed over.
613
- continue
614
604
  return DimensionId(envelope, extent.parameter_id)
615
605
  return None
616
606
 
@@ -1659,6 +1649,101 @@ def angular_pattern_label(group: DimensionGroup) -> str | None:
1659
1649
  return f"{len(dimensions)}× {next(iter(labels))}"
1660
1650
 
1661
1651
 
1652
+ def _selected_chain_covers_extent(model, selected, axis) -> bool:
1653
+ """Require adjoining approved measurements between both overall ends of one profile."""
1654
+ axis_index = "xyz".index(axis)
1655
+ intervals: dict[tuple[tuple[float, ...], object], list[tuple[float, float]]] = {}
1656
+ step_profiles = set()
1657
+ for feature, length in selected:
1658
+ if feature.kind not in ("step", "groove") or feature.frame.axis != axis:
1659
+ continue
1660
+ frame = feature.frame
1661
+ key = (
1662
+ tuple(
1663
+ round(float(value), 6) for i, value in enumerate(frame.origin) if i != axis_index
1664
+ ),
1665
+ feature.profile or feature.profile_group,
1666
+ )
1667
+ if feature.kind == "step":
1668
+ if length.span is None:
1669
+ continue
1670
+ lo, hi = sorted(float(point[axis_index]) for point in length.span)
1671
+ step_profiles.add(key)
1672
+ else:
1673
+ centre = float(frame.origin[axis_index])
1674
+ lo, hi = centre - length.value / 2, centre + length.value / 2
1675
+ intervals.setdefault(key, []).append((lo, hi))
1676
+
1677
+ # Emitted declarations round supports to 0.001 mm. Keep that numerical seam
1678
+ # tolerance, but do not join different bodies or merely overlapping spans:
1679
+ # 0..40 and 20..60 do not tell the reader the overall length.
1680
+ tolerance = 1e-3 + 1e-9
1681
+ bb = model.bbox
1682
+ for key in step_profiles:
1683
+ reachable = [float(tuple(bb.min)[axis_index])]
1684
+ for lo, hi in sorted(intervals[key]):
1685
+ if any(abs(lo - station) <= tolerance for station in reachable):
1686
+ reachable.append(hi)
1687
+ if any(
1688
+ abs(station - float(tuple(bb.max)[axis_index])) <= tolerance for station in reachable
1689
+ ):
1690
+ return True
1691
+ return False
1692
+
1693
+
1694
+ def _restore_uncovered_x_extent(model, groups):
1695
+ """Settle X-width ownership after the complete selected chain is known, before sizing."""
1696
+ if model.orientation != "x" or not any(group.feature.kind == "envelope" for group in groups):
1697
+ return groups
1698
+ if _selected_chain_covers_extent(
1699
+ model,
1700
+ [
1701
+ (group.feature, dimension.param)
1702
+ for group in groups
1703
+ if group.feature.kind in ("step", "groove")
1704
+ for dimension in group.dims
1705
+ if not dimension.suppressed and dimension.param.kind == "length"
1706
+ ],
1707
+ "x",
1708
+ ):
1709
+ return groups
1710
+ restored = []
1711
+ widths = []
1712
+ for group in groups:
1713
+ dimensions = []
1714
+ for dimension in group.dims:
1715
+ if group.feature.kind == "envelope" and dimension.param.parameter_id == "width.length":
1716
+ if dimension.reason == "X-turned (step-length chain conveys the length)":
1717
+ dimension = replace(dimension, suppressed=False, reason=None)
1718
+ if not dimension.suppressed:
1719
+ widths.append((dimension.param, DimensionId(group.feature, "width.length")))
1720
+ dimensions.append(dimension)
1721
+ restored.append(replace(group, units=_addressable(group.feature, dimensions)))
1722
+ result = []
1723
+ for group in restored:
1724
+ dimensions = []
1725
+ for dimension in group.dims:
1726
+ parameter = dimension.param
1727
+ if (
1728
+ group.feature.kind == "boss"
1729
+ and parameter.parameter_id == "boss_height.length"
1730
+ and _request_for(model, group.feature, parameter) is None
1731
+ and _authored_for(model, group.feature, parameter) is None
1732
+ ):
1733
+ for extent, owner in widths:
1734
+ if _extent_can_convey(extent, parameter):
1735
+ dimension = replace(
1736
+ dimension,
1737
+ suppressed=True,
1738
+ reason=dimension.reason if dimension.suppressed else _CONSOLIDATED,
1739
+ conveyed_by=owner,
1740
+ )
1741
+ break
1742
+ dimensions.append(dimension)
1743
+ result.append(replace(group, units=_addressable(group.feature, dimensions)))
1744
+ return result
1745
+
1746
+
1662
1747
  def plan_dimensions(model: PartModel, *, planned_views=None) -> list[DimensionGroup]:
1663
1748
  """Plan each feature's parameters into one `DimensionGroup` (anchor + single
1664
1749
  view + planned dims, each carrying its render intent — convention, model-level
@@ -1725,18 +1810,25 @@ def plan_dimensions(model: PartModel, *, planned_views=None) -> list[DimensionGr
1725
1810
  )
1726
1811
  )
1727
1812
  if dims:
1728
- selected_view, selected_side = _group_placement(feature, dims, planned_views)
1729
1813
  groups.append(
1730
1814
  DimensionGroup(
1731
1815
  feature=feature,
1732
- # Preserve a total internal record while collecting every uncovered
1733
- # identity below. The exception prevents this preferred fallback from
1734
- # crossing the planner boundary when it is not actually selected.
1735
- view=selected_view or _preferred_group_view(feature),
1816
+ view=_preferred_group_view(feature),
1736
1817
  units=_addressable(feature, dims),
1737
- side=selected_side,
1738
1818
  )
1739
1819
  )
1820
+ groups = _restore_uncovered_x_extent(model, groups)
1821
+ for index, group in enumerate(groups):
1822
+ # Validate the final content: a consolidated height must not reject a
1823
+ # supported end-on view requested for the remaining diameter.
1824
+ selected_view, selected_side = _group_placement(
1825
+ group.feature, list(group.dims), planned_views
1826
+ )
1827
+ groups[index] = replace(
1828
+ group,
1829
+ view=selected_view or _preferred_group_view(group.feature),
1830
+ side=selected_side,
1831
+ )
1740
1832
  if planned_views is not None:
1741
1833
  uncovered = _uncovered_group_requirements(model, groups, planned_views)
1742
1834
  uncovered.extend(_uncovered_location_requirements(model, planned_views))
@@ -333,9 +333,8 @@ def test_only_the_bosses_that_land_right_are_counted(declare, expected, why):
333
333
  assert _n_right_strip_boss_heights(model) == expected, why
334
334
 
335
335
 
336
- def test_a_turned_model_reserves_no_boss_height_slots():
337
- """``render_boss_heights`` returns early for a turned part, so reserving for one there
338
- would be dead page space."""
336
+ def test_a_turned_model_without_bosses_reserves_no_boss_height_slots():
337
+ """A declared step chain without bosses needs no additional boss-height slots."""
339
338
  a, b, c = _turned_shaft_parts()
340
339
  sheet = Sheet(a + b + c).auto_dimensions()
341
340
  sheet.step(a)