Option I: add per-viewport Arc wire cache so paper-space viewport rendering
no longer re-tessellates model content every frame.
Option J: hit_test_wires() returns Arc<Vec<WireModel>> — O(1) pointer copy
in model space instead of a full Vec clone on every mouse move during commands.
paper_canvas_hatches/wipeouts() now route through the epoch caches added in F.
Option K: add world_snap_r + wire_in_range() pre-check to Snapper::snap().
All Endpoint/Midpoint/Nearest/Perpendicular/Intersection loops skip wires
whose chord sphere is outside the snap circle using O(1) scalar comparisons,
eliminating O(entities × vertices) matrix multiply cost when zoomed in.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add two complementary render caches that make mouse navigation essentially
free regardless of file size:
Option A – Wire tessellation cache: entity_wires_arc() caches the
tessellated Vec<WireModel> keyed by geometry_epoch and returns an Arc,
so navigation frames (no preview wires) incur zero Vec clones and zero
tessellation work. Primitive::wires changed to Arc<Vec<WireModel>>.
Option B – GPU buffer cache: Pipeline stores cached_epoch; prepare()
skips all upload_wires/hatches/images/meshes calls when the epoch is
unchanged, writing only the 192-byte camera uniform instead.
geometry_epoch is a process-wide AtomicU64 incremented by every Scene
mutation (add/erase entity, selection, layer visibility, layout switch,
populate_*, grip, transform, copy, clear, preview wires). Using a global
counter rather than a per-scene counter prevents two tabs that happen to
have the same local bump count from sharing a cached_epoch value, which
was causing the first file's geometry to remain on screen after opening a
second file.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Integrate NAVVCUBE, NAVBAR, PROPERTIES, FILETAB, LAYOUTTAB, TOOLPALETTES
and SHEETSET commands to toggle UI widgets at runtime. Add 15 new SVG icons
for view module tools previously using glyph fallbacks. Restyle all SVG
icons to use the established two-color scheme: #e0e0e0 for passive geometry,
#4cc9f0 for active/accent elements.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- paper_entity_extents() computes the bounding box of actual DXF entities
so the white fill always matches the drawn title-block / frame borders,
regardless of whether Layout min/max_limits match entity positions
- Falls back to paper_limits() (→ A4 297×210) when layout has no entities
- Removed paper_boundary_wire: the white fill now acts as the visual paper
edge so the near-white wire (invisible on white) was redundant
- LayoutCreate sets limits to A4 landscape immediately after add_layout()
to override acadrust's imperial default (12×9)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add orbit_active_viewport(), snap_active_viewport_to_angles(),
active_view_rotation_mat(), active_viewport_yaw_pitch() helpers so
navigation gestures modify the DXF viewport entity's view_direction
instead of the paper-space camera.
- Fix "already there → flip opposite" check: the previous code used
rot * Vec4::W (always (0,0,0,1) for a rotation matrix); now reads
(yaw, pitch) directly from camera_for_viewport() via the new helper.
- MSPACE right-drag orbit early-returns after writing the viewport
entity, preventing the paper-space camera from also being modified.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- REPORT opens GitHub new-issue page
- ABOUT opens a dialog window with version, OS and arch info + Copy Info button
- CHANGELOG opens GitHub releases page
- Fix Windows build: add windows-sys as target-specific dependency for PRINT command
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
New StyleComboGroup RibbonItem renders a dropdown combobox for selecting
text style, dimension style, multileader style, or table style. Ribbon
groups in the Annotate tab now match the reference layout: each group
has a large tool on the left and a style combobox with tool rows on the
right.
Each combobox shows the active style name, opens a scrollable item list
on click, and has an optional "Manage…" row that fires the style manager
command (STYLE / DIMSTYLE / MLEADERSTYLE / TABLESTYLE).
Style state is synced from the document on every layer refresh via
sync_ribbon_styles(). RibbonStyleChanged message propagates selections
back to the acadrust document header and the active_mleader_style field.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
New dimension commands: QDIM, DIMEDIT, DIMTEDIT, DIMBREAK, DIMSPACE,
DIMJOGLINE with full command workflows and SVG icons.
New multileader commands: MLEADERADD, MLEADERREMOVE, MLEADERALIGN,
MLEADERCOLLECT with entity injection pattern for in-place editing.
Updated annotate ribbon: all tools exposed across Text, Dimensions,
Leaders, Tables, Markup, and Annotation Scaling groups. Added STYLE,
FIND, DIMSTYLE shortcut buttons.
Added `inject_picked_entity` to the CadCommand trait for commands that
need a cloned copy of the picked entity to modify (DIMTEDIT, MLEADERADD,
MLEADERREMOVE). Sentinel-based dispatch in cmd_result.rs handles
DIMBREAK, DIMSPACE, DIMJOGLINE, MLEADERALIGN, and MLEADERCOLLECT.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Every dialog panel that previously rendered as an in-viewport overlay is
now opened as its own OS window, matching the behaviour of the Layer
Properties Manager:
• Page Setup (520×460, non-resizable)
• Text Style (620×460)
• Table Style (620×420)
• Multiline Style (620×420)
• Layout Manager (640×320)
• Plot Style Editor (780×540)
• Dimension Style Mgr (720×560)
• Keyboard Shortcuts (720×520)
Changes:
- mod.rs: replace *_open: bool fields with *_window: Option<window::Id>;
add window IDs to OsWindowClosed tracker; add per-window title strings.
- update.rs: Open handlers call window::open(); if already open, call
window::gain_focus() instead of reopening. Close handlers call
window::close(). OsWindowClosed clears all panel window IDs.
- view.rs: each window_id is matched at the top of view() and returns
the panel content directly. All overlay let-bindings and stack![]
references removed.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds STEPOUT / STPOUT / EXPORTSTEP command that exports all tessellated
Solid3D / Region / Body meshes to an ISO 10303-21 (STEP AP203) file.
Each triangle is encoded as a minimal ADVANCED_FACE with a PLANE surface
and CLOSED_SHELL topology — sufficient for import into all major CAD systems.
A file-save dialog picks the output path; the command line reports success or
errors. Requires at least one tessellated solid in the drawing.
Closes ROADMAP 14.10.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The PRINT command renders the current layout to a temporary PDF (reusing
the existing PDF export pipeline) and dispatches it to the OS default
printer:
- Linux/macOS: `lp` (CUPS) with `lpr` as fallback.
- Windows: ShellExecute "print" verb (compiled-in, unused on Linux).
PLOT and EXPORT still open the save-file dialog as before.
Status messages are shown in the command line during the async job.
Closes ROADMAP 1.8.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Opens a reference panel listing all built-in keyboard shortcuts
(F3-F12, Ctrl+N/O/S/Z/C/X/V, etc.) and any user-defined overrides.
SHORTCUTS LIST — open the panel
SHORTCUTS SET <k> <c> — add/update a custom shortcut label
SHORTCUTS CLEAR <k> — remove a custom entry
Custom shortcuts are stored in app state (runtime only) and shown
in the panel alongside the hardcoded bindings.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds active_theme: Theme field to app state and wires the daemon's
.theme() callback to use it dynamically. COLORSCHEME <name> switches
among all 19 built-in iced themes (Dark, Light, Dracula, Nord, Tokyo
Night, Gruvbox, Kanagawa, Moonfly, Nightfly, etc.).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Panel overlay showing all layouts with their active status.
Supports: select, rename, new, delete, reorder (◀▶), set current.
Also adds Scene::swap_layout_order() for tab-order resequencing.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Opens a panel overlay showing all 255 ACI entries with their current
overrides (color, lineweight, screening). Allows editing entries
interactively, creating a new identity table when none is loaded,
and saving the modified table back to a CTB/STB file.
Commands: PLOTSTYLEPANEL, PLOTSTYLEEDITOR, STYLESMANAGER
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Parses Wavefront OBJ files (v/vn/f, fan-triangulation, face normals
fallback) and inserts the result as a Solid3D placeholder + MeshModel
visible in the 3D viewport.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Exports all tessellated 3D mesh models in the current drawing to a
binary STL file via a save-file dialog. Normals are taken from the
MeshModel where available, otherwise computed from triangle vertices.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Viewport right-click now shows a proper widget-based context menu:
- When a command is active: Cancel / Enter
- Otherwise: Repeat last commands, Delete/Move/Copy (if selected),
Select All, Zoom Extents
CONSTRUCTIONLINE added as an alias for XLINE (XL).
Canvas-drawn placeholder removed; context menu closes on Escape,
click-outside, or when any action is taken.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- snap/mod.rs: Snapper gains otrack_enabled, tracking_points, dwell state;
update_otrack_dwell() acquires a snap point after DWELL_THRESHOLD=4
consecutive moves near the same position; otrack_snap() returns an
H/V alignment snap position; clear_tracking() resets state on command end
- overlay.rs: selection_overlay accepts ost_points + cursor_screen;
draws light-blue dashed H/V lines from acquired points + small cross marker
- statusbar.rs: OTRACK pill (F11) added next to DYN
- view.rs: projects tracking_points to screen, passes to selection_overlay
- update.rs: calls update_otrack_dwell + otrack_snap in ViewportMove;
overrides effective point with OST alignment when no normal snap is active
- ROADMAP.md: Object Snap Tracking marked ✅
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- overlay.rs: dynamic_input_overlay() canvas widget draws a semi-transparent
coordinate tooltip near the cursor; shows X/Y in absolute mode or
dist/angle relative to last_point when a command base point exists
- statusbar: DYN toggle pill with F12 tooltip (calls ToggleDynInput)
- app/mod.rs: dyn_input: bool field (default true), ToggleDynInput message
- view.rs: builds DYN label and pushes overlay into viewport_stack when
dyn_input=true and a command is active
- document.rs: last_cursor_screen: iced::Point — updated on every ViewportMove
- ROADMAP.md: Dynamic Input overlay marked ✅
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- src/modules/insert/wblock.rs: extract_block_to_doc() copies a named
block's entities into a fresh CadDocument; extract_entities_to_doc()
does the same for a selection set; layer definitions are carried over
- WBLOCK <name> writes the named block; WBLOCK * writes selected entities
- WblockSave / WblockSaveResult messages drive the async save-dialog flow
- ROADMAP.md: 1.10 WBLOCK marked ✅
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Grid snap (F9):
• snap spacing now tracks the visible grid zoom level — computed via
compute_grid_step() (same adaptive pow-of-5 logic as draw_grid),
updated on every ViewportMove so zooming in/out keeps snap aligned
with the grid lines on screen
Polar tracking (F10):
• configurable angle increment stored in polar_increment_deg (default 45°)
• right-click the POLAR pill to cycle through 15 → 30 → 45 → 90°
• pill label shows current angle ("POLAR 45°")
• visual guide line: while drawing with polar on, a dashed cyan line is
drawn from last_point along the snapped direction across the viewport
• SetPolarAngle message + handler; all polar_constrain() calls use the
stored increment instead of the hardcoded 45°
ROADMAP updated: Grid snap and Polar tracking marked ✅.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add HATCHEDIT (HE alias) command. Works on pre-selected hatch or via
entity pick. Accepts text options: P <pattern>, S <scale>, A <angle>.
Enter applies changes; rebuilds hatch entity and GPU model via add_hatch.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add DDEDIT (ED alias) command that edits Text/MText/Attribute entities
in-place via the command line. Double-clicking a text entity in model space
now auto-launches DDEDIT for that entity. Supports Text, MText,
AttributeDefinition, and AttributeEntity types.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
CommandLine now records every submitted command in a recall list (up to
50 entries). Pressing ↑ in the command input walks back through the
list, ↓ moves forward, and returning to the newest position restores
the draft text the user had typed before navigating.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add VP freeze/thaw toggle columns to the layer panel when in a paper
space layout. Each viewport gets its own column (VP 1, VP 2, …) showing
a freeze icon per layer. Clicking toggles frozen_layers on the Viewport
entity and syncs back to the panel.
- scene: viewport_list() → [(handle, label, frozen_handles)]
- LayerPanel: VpCol + vp_frozen per layer, sync_with_viewports()
- Message::LayerToggleVpFreeze(layer_idx, vp_col_idx)
- Sync VP columns on layout switch, VPLAYER cmd, undo/redo, layer ops
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- STYLE DIALOG / TEXTSTYLE DIALOG opens the Text Style Font Browser
- Three-panel dialog: style list | built-in CXF font list | properties
- Properties panel: font file text field, width factor, oblique angle
- Apply button commits edits; Set Current sets the active text style
- Built-in font picker (20 CXF fonts from assets/fonts/) auto-applies
font to the selected style on click
- Preview pane shows "AaBbCc 0123" sample text
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- TABLESTYLE/TS command: LIST, NEW subcommands for managing table styles
- Table Style Manager dialog: style list with details panel showing
name, margins, suppression flags, and row styles (data/header/title)
with text style, height, and alignment per row type
- New / Delete buttons in the dialog
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- MLSTYLE command: LIST, NEW, SET, DEL subcommands
- Multiline Style Manager dialog: style list, element details (offset,
color, linetype), Set Current / New / Delete buttons
- MLINE/ML command now reads document header.multiline_style to apply
the current style to newly created MLine entities
- MlineCommand.with_style() constructor for style-aware multiline drawing
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- src/io/plot_style.rs: PlotStyleTable and PlotStyleEntry data structures;
CTB reader (deflate/zlib decompressed text format) with ACI→RGB and
ACI→lineweight lookup; CTB writer (zlib compressed); LW_TABLE constant
- src/io/pdf_export.rs: accept optional PlotStyleTable; apply ACI color
and lineweight overrides during PDF rendering
- src/scene/wire_model.rs: add `aci: u8` field to carry ACI index
- src/scene/render.rs: render_style() now returns ACI alongside RGBA
- src/scene/mod.rs + tessellate.rs: propagate aci through wire building
- app: PlotStyleLoad/Loaded/Clear messages and handlers;
PLOTSTYLE LOAD | CLEAR | STATUS command; active_plot_style state on H7CAD
- flate2 added as dependency
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add DimStyleDialogOpen/Close/Apply/Select/Tab/New/SetCurrent/Delete
messages and DsEdit/DsToggle with DsField enum for fine-grained edits
- Store active dialog state (selected style, current tab, edit buffers)
directly on H7CAD for all 28 most-used DimStyle properties
- dimstyle_overlay: 5-tab modal panel (Lines, Arrows, Text,
Scale/Units, Tolerances) with style list, Apply and Close buttons
- DIMSTYLE / DDIM with no sub-command now opens the dialog;
DIMSTYLE LIST / NEW / SET sub-commands remain available
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add `active_ucs: Option<Ucs>` per-tab state to DocumentTab
- Add `ucs_to_wcs`, `wcs_to_ucs`, `ucs_z_axis`, `ucs_rotated_z` helpers
- Add `Camera::pick_on_plane` for ray–plane intersection against any plane
- Mouse picks project onto the active UCS XY plane instead of world XY
- Typed coordinates are converted from UCS space to WCS before dispatch
- UCS command now really activates/deactivates a UCS:
- `UCS W` resets to WCS (clears active_ucs)
- `UCS <name>` activates a named UCS
- `UCS SAVE <name>` saves the current active UCS
- `UCS ORIGIN x,y,z` shifts origin (in current UCS space)
- `UCS X/Y/Z <angle>` rotates the UCS around its own axes
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- properties.rs: inject 'UCS Name' Choice property for viewports when
document.ucss is non-empty; resolves current handle to display name
- update.rs: intercept PropGeomChoiceChanged for 'vp_ucs_name'; clones
UCS origin/x_axis/y_axis into viewport and sets ucs_handle — no
trait signature change required
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
PageSetup panel:
- Paper size presets (A4/A3/A2/A1/A0 portrait+landscape, Letter)
- Plot area selector: Layout vs Extents
- Center-on-page toggle
- Plot offset X/Y fields
- Rotation picker: 0° / 90° / 180° / 270°
PlotSettings (acadrust object):
- PageSetupCommit finds or creates a PlotSettings object in the document
- Writes paper size, plot type, centering, offset, rotation to it
- DXF round-trip: PlotSettings persisted to file
PDF export:
- Reads PlotSettings for the active layout
- Applies centering (auto-computes offset from wire extents)
- Applies offset X/Y from PlotSettings
- Applies rotation via PDF CTM transformation matrix
- Swaps paper dimensions for 90°/270° rotation
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Snap is now suppressed (both cursor indicator and coordinate snapping)
when a command is in entity-pick mode (needs_entity_pick) or
selection-gathering mode (is_selection_gathering), and restored
automatically when the mode ends.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Selection, snapping and editing are now mode-aware:
PSPACE (paper layout, no active viewport)
- Only paper-space entities (viewport borders, title blocks, etc.) are
hit-testable and selectable. Viewport content wires are invisible to
the interaction layer.
- Drawing commands add entities to the paper-space layout block so
annotations/title blocks land on the sheet, not in model space.
MSPACE (active viewport entered)
- Only model-space entities visible through the active viewport are
hit-testable. Other viewports' content and paper entities are ignored.
- Drawing commands add entities to model space (correct DXF block).
- Snap results from projected viewport-content wires are converted from
paper-space back to model-space via paper_to_model so that placed
coordinates and command previews are consistent.
Entering/exiting MSPACE clears the current selection so no stale
cross-space selection is carried over.
Implementation:
- Scene::hit_test_wires() returns mode-filtered wires for all
hit-tests, snaps, and selections (entity_wires() still returns
everything for rendering and PDF export).
- viewport_content_wires() gains an Option<Handle> filter to render
only the active viewport's content for MSPACE hit-testing.
- Scene::add_entity() routes to the paper-layout block or model-space
block depending on current_layout / active_viewport.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Four bugs prevented viewports from working like AutoCAD model-space windows:
1. Dead-code double-click block: `!is_down2` was always false because
`is_down2 = sel.left_down` is captured while the button is still held
(before the selection block clears it). Changed to `is_down` so the
double-click handler actually fires.
2. Inverted pan direction: pan_active_viewport used `-=` on the delta
returned by screen_delta_to_world, which is the same delta that cam.pan
*adds* to its target — causing reversed drag. Changed to `+=`.
3. Zoom not cursor-centered: zoom_active_viewport now accepts an optional
paper-space cursor position and adjusts view_target so the model point
under the cursor stays fixed (same as cam.zoom_about_point).
4. ESC did not exit MSPACE: CommandEscape now calls ExitViewport when
active_viewport is set and no command is running.
Also added MS/MSPACE and PSPACE command aliases, and MspaceCommand /
PspaceCommand messages so MS auto-enters the first viewport.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Paper limits:
- Change A4 fallback from 12×9 to 297×210 mm in paper_limits()
Context menu:
- Translate layout context menu labels to English (Rename / Delete)
Viewport clipping:
- Replace AABB-only culling with proper Cohen-Sutherland line clipping
in viewport_content_wires(); each projected segment is now clipped at
the exact viewport boundary instead of being included or discarded whole
- Add cs_clip() and clip_polyline_to_rect() free functions in scene/mod.rs
Frozen layers per-viewport UI:
- Inject a "Frozen Layers" EditText property in the Properties panel for
viewport entities (layer names resolved from handles at display time)
- Handle "frozen_layers" in PropGeomCommit: parse comma-separated names,
resolve to layer handles, update vp.frozen_layers in-place
PDF export improvements:
- Add offset_x/offset_y params to export_pdf() for model-space normalization:
coordinates are shifted so the drawing origin maps to the page origin
- Model space export computes extents via model_space_extents() (now public)
and adds a 5 % margin; falls back to A4 landscape for empty drawings
- Skip __paper_boundary__ wire in PDF (white background covers it)
- Map yellow (active viewport border) → black and cyan (vp border) → dark
blue for print-friendly output
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add printpdf 0.9.1 dependency for native PDF generation.
- New src/io/pdf_export.rs: converts paper-space WireModels to a PDF
page (per-wire stroke color, line weight in Pt, NaN-split segments).
White/near-white colors are inverted to black for print output.
- Add PlotExport / PlotExportPath messages: opens a save-file dialog
and writes a .pdf next to the drawing file.
- Add PageSetupOpen/Close/WidthEdit/HeightEdit/Commit messages: a
centered modal panel lets the user enter paper width and height (mm);
on commit the Layout object's min/max_limits are updated in-place.
- Register PRINT / PLOT / EXPORT and PAGESETUP (PS) commands in
dispatch_command; fix MVIEW error message to English.
- Layout ribbon gains a "Plot" group with Page Setup and Export PDF
ribbon buttons.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add active_viewport: Option<Handle> field to Scene
- Add EnterViewport(Handle) and ExitViewport messages
- Double-click on a user viewport (id > 1) enters MSPACE;
double-click on empty area while in MSPACE exits to PSPACE
- MSPACE middle-drag pans the viewport's model-space view (view_target)
- MSPACE scroll zooms the viewport's view_height / custom_scale
- Drawing commands inside MSPACE receive model-space coordinates
via paper_to_model() coordinate transform
- Active viewport rendered with yellow dashed border (vs. cyan solid)
- Camera screen_delta_to_world helper for MSPACE pan conversion
- LayoutSwitch clears active_viewport
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Layout sekme sağ-tıklamasında context menüsü (Yeniden Adlandır / Sil)
- Inline rename: sekme metin-giriş alanına dönüşür, Enter ile commit, ✕ ile iptal
- LayoutDelete: layout ve sahip olduğu tüm entity'leri kaldırır
- LayoutRename: Layout nesnesinin adını yerinde günceller
- LayoutCreate çakışma koruması: mevcut isimler arasında benzersiz ad bulur
- Escape tuşu açık rename/context menüsünü kapatır
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>