stimeo-ui 0.17.0 → 0.18.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +106 -1
- package/README.md +19 -10
- package/dist/cable/index.d.ts +9 -8
- package/dist/cable/index.js +22 -14
- package/dist/cable/index.js.map +1 -1
- package/dist/coerce-JtZVNG5h.d.ts +20 -0
- package/dist/controllers/accordion_controller.js +14 -6
- package/dist/controllers/accordion_controller.js.map +1 -1
- package/dist/controllers/alert_dialog_controller.js +145 -118
- package/dist/controllers/alert_dialog_controller.js.map +1 -1
- package/dist/controllers/announcer_controller.d.ts +5 -3
- package/dist/controllers/announcer_controller.js +113 -17
- package/dist/controllers/announcer_controller.js.map +1 -1
- package/dist/controllers/auto_submit_controller.js +185 -60
- package/dist/controllers/auto_submit_controller.js.map +1 -1
- package/dist/controllers/avatar_controller.js +55 -43
- package/dist/controllers/avatar_controller.js.map +1 -1
- package/dist/controllers/breadcrumb_controller.js.map +1 -1
- package/dist/controllers/bulk_select_controller.d.ts +3 -3
- package/dist/controllers/bulk_select_controller.js +64 -50
- package/dist/controllers/bulk_select_controller.js.map +1 -1
- package/dist/controllers/calendar_controller.d.ts +15 -12
- package/dist/controllers/calendar_controller.js +55 -53
- package/dist/controllers/calendar_controller.js.map +1 -1
- package/dist/controllers/carousel_controller.d.ts +9 -5
- package/dist/controllers/carousel_controller.js +124 -86
- package/dist/controllers/carousel_controller.js.map +1 -1
- package/dist/controllers/character_counter_controller.d.ts +27 -6
- package/dist/controllers/character_counter_controller.js +291 -95
- package/dist/controllers/character_counter_controller.js.map +1 -1
- package/dist/controllers/checkbox_controller.js +6 -0
- package/dist/controllers/checkbox_controller.js.map +1 -1
- package/dist/controllers/clipboard_controller.js +118 -27
- package/dist/controllers/clipboard_controller.js.map +1 -1
- package/dist/controllers/collapsible_controller.d.ts +1 -1
- package/dist/controllers/collapsible_controller.js +52 -49
- package/dist/controllers/collapsible_controller.js.map +1 -1
- package/dist/controllers/color_picker_controller.js +29 -7
- package/dist/controllers/color_picker_controller.js.map +1 -1
- package/dist/controllers/combobox_controller.d.ts +1 -1
- package/dist/controllers/combobox_controller.js +210 -71
- package/dist/controllers/combobox_controller.js.map +1 -1
- package/dist/controllers/command_palette_controller.d.ts +9 -9
- package/dist/controllers/command_palette_controller.js +289 -140
- package/dist/controllers/command_palette_controller.js.map +1 -1
- package/dist/controllers/conditional_fields_controller.js +145 -58
- package/dist/controllers/conditional_fields_controller.js.map +1 -1
- package/dist/controllers/confirm_controller.js +145 -118
- package/dist/controllers/confirm_controller.js.map +1 -1
- package/dist/controllers/context_menu_controller.d.ts +49 -14
- package/dist/controllers/context_menu_controller.js +138 -73
- package/dist/controllers/context_menu_controller.js.map +1 -1
- package/dist/controllers/count_up_controller.js.map +1 -1
- package/dist/controllers/countdown_controller.d.ts +2 -2
- package/dist/controllers/countdown_controller.js +109 -21
- package/dist/controllers/countdown_controller.js.map +1 -1
- package/dist/controllers/currency_input_controller.d.ts +75 -11
- package/dist/controllers/currency_input_controller.js +446 -72
- package/dist/controllers/currency_input_controller.js.map +1 -1
- package/dist/controllers/data_grid_controller.d.ts +10 -8
- package/dist/controllers/data_grid_controller.js +134 -28
- package/dist/controllers/data_grid_controller.js.map +1 -1
- package/dist/controllers/date_range_picker_controller.d.ts +12 -9
- package/dist/controllers/date_range_picker_controller.js +93 -72
- package/dist/controllers/date_range_picker_controller.js.map +1 -1
- package/dist/controllers/dialog_controller.d.ts +4 -5
- package/dist/controllers/dialog_controller.js +145 -118
- package/dist/controllers/dialog_controller.js.map +1 -1
- package/dist/controllers/direct_upload_controller.d.ts +1 -1
- package/dist/controllers/direct_upload_controller.js +24 -14
- package/dist/controllers/direct_upload_controller.js.map +1 -1
- package/dist/controllers/dirty_form_controller.d.ts +6 -1
- package/dist/controllers/dirty_form_controller.js +68 -31
- package/dist/controllers/dirty_form_controller.js.map +1 -1
- package/dist/controllers/dismissible_controller.js +64 -46
- package/dist/controllers/dismissible_controller.js.map +1 -1
- package/dist/controllers/drawer_controller.js +145 -118
- package/dist/controllers/drawer_controller.js.map +1 -1
- package/dist/controllers/dropdown_controller.js +76 -63
- package/dist/controllers/dropdown_controller.js.map +1 -1
- package/dist/controllers/editable_controller.js +199 -62
- package/dist/controllers/editable_controller.js.map +1 -1
- package/dist/controllers/empty_state_controller.js +13 -6
- package/dist/controllers/empty_state_controller.js.map +1 -1
- package/dist/controllers/file_dropzone_controller.d.ts +3 -0
- package/dist/controllers/file_dropzone_controller.js +55 -48
- package/dist/controllers/file_dropzone_controller.js.map +1 -1
- package/dist/controllers/filter_controller.js +9 -2
- package/dist/controllers/filter_controller.js.map +1 -1
- package/dist/controllers/flash_controller.d.ts +4 -4
- package/dist/controllers/flash_controller.js +66 -33
- package/dist/controllers/flash_controller.js.map +1 -1
- package/dist/controllers/focus_controller.d.ts +3 -3
- package/dist/controllers/focus_controller.js +39 -14
- package/dist/controllers/focus_controller.js.map +1 -1
- package/dist/controllers/form_field_controller.js +52 -43
- package/dist/controllers/form_field_controller.js.map +1 -1
- package/dist/controllers/form_validation_controller.d.ts +3 -3
- package/dist/controllers/form_validation_controller.js +18 -11
- package/dist/controllers/form_validation_controller.js.map +1 -1
- package/dist/controllers/frame_loading_controller.d.ts +13 -12
- package/dist/controllers/frame_loading_controller.js +55 -48
- package/dist/controllers/frame_loading_controller.js.map +1 -1
- package/dist/controllers/highlight_controller.d.ts +5 -4
- package/dist/controllers/highlight_controller.js.map +1 -1
- package/dist/controllers/hover_card_controller.d.ts +4 -1
- package/dist/controllers/hover_card_controller.js +67 -61
- package/dist/controllers/hover_card_controller.js.map +1 -1
- package/dist/controllers/idle_controller.d.ts +6 -5
- package/dist/controllers/idle_controller.js +10 -6
- package/dist/controllers/idle_controller.js.map +1 -1
- package/dist/controllers/input_mask_controller.d.ts +30 -13
- package/dist/controllers/input_mask_controller.js +411 -24
- package/dist/controllers/input_mask_controller.js.map +1 -1
- package/dist/controllers/intersection_controller.js +3 -0
- package/dist/controllers/intersection_controller.js.map +1 -1
- package/dist/controllers/lazy_frame_controller.d.ts +3 -2
- package/dist/controllers/lazy_frame_controller.js +15 -3
- package/dist/controllers/lazy_frame_controller.js.map +1 -1
- package/dist/controllers/listbox_controller.d.ts +10 -7
- package/dist/controllers/listbox_controller.js +260 -79
- package/dist/controllers/listbox_controller.js.map +1 -1
- package/dist/controllers/local_time_controller.d.ts +8 -6
- package/dist/controllers/local_time_controller.js +48 -13
- package/dist/controllers/local_time_controller.js.map +1 -1
- package/dist/controllers/masonry_controller.js +11 -4
- package/dist/controllers/masonry_controller.js.map +1 -1
- package/dist/controllers/menu_controller.d.ts +24 -5
- package/dist/controllers/menu_controller.js +138 -82
- package/dist/controllers/menu_controller.js.map +1 -1
- package/dist/controllers/menubar_controller.d.ts +49 -7
- package/dist/controllers/menubar_controller.js +65 -19
- package/dist/controllers/menubar_controller.js.map +1 -1
- package/dist/controllers/meter_controller.d.ts +13 -20
- package/dist/controllers/meter_controller.js +270 -24
- package/dist/controllers/meter_controller.js.map +1 -1
- package/dist/controllers/multi_select_controller.d.ts +17 -15
- package/dist/controllers/multi_select_controller.js +251 -94
- package/dist/controllers/multi_select_controller.js.map +1 -1
- package/dist/controllers/navigation_menu_controller.d.ts +19 -5
- package/dist/controllers/navigation_menu_controller.js +67 -19
- package/dist/controllers/navigation_menu_controller.js.map +1 -1
- package/dist/controllers/nested_form_controller.js +98 -64
- package/dist/controllers/nested_form_controller.js.map +1 -1
- package/dist/controllers/network_status_controller.js +70 -52
- package/dist/controllers/network_status_controller.js.map +1 -1
- package/dist/controllers/number_input_controller.d.ts +24 -6
- package/dist/controllers/number_input_controller.js +344 -94
- package/dist/controllers/number_input_controller.js.map +1 -1
- package/dist/controllers/optimistic_controller.d.ts +8 -5
- package/dist/controllers/optimistic_controller.js +29 -11
- package/dist/controllers/optimistic_controller.js.map +1 -1
- package/dist/controllers/otp_controller.d.ts +35 -4
- package/dist/controllers/otp_controller.js +502 -104
- package/dist/controllers/otp_controller.js.map +1 -1
- package/dist/controllers/overflow_indicator_controller.js +6 -0
- package/dist/controllers/overflow_indicator_controller.js.map +1 -1
- package/dist/controllers/overflow_menu_controller.d.ts +10 -9
- package/dist/controllers/overflow_menu_controller.js +136 -21
- package/dist/controllers/overflow_menu_controller.js.map +1 -1
- package/dist/controllers/pagination_controller.d.ts +3 -2
- package/dist/controllers/pagination_controller.js +47 -14
- package/dist/controllers/pagination_controller.js.map +1 -1
- package/dist/controllers/password_reveal_controller.d.ts +5 -4
- package/dist/controllers/password_reveal_controller.js +52 -49
- package/dist/controllers/password_reveal_controller.js.map +1 -1
- package/dist/controllers/password_strength_controller.d.ts +1 -1
- package/dist/controllers/password_strength_controller.js +13 -6
- package/dist/controllers/password_strength_controller.js.map +1 -1
- package/dist/controllers/persist_controller.js +48 -128
- package/dist/controllers/persist_controller.js.map +1 -1
- package/dist/controllers/pointer_drag_controller.d.ts +19 -8
- package/dist/controllers/pointer_drag_controller.js +249 -23
- package/dist/controllers/pointer_drag_controller.js.map +1 -1
- package/dist/controllers/popover_controller.d.ts +3 -3
- package/dist/controllers/popover_controller.js +82 -65
- package/dist/controllers/popover_controller.js.map +1 -1
- package/dist/controllers/portal_controller.js +6 -0
- package/dist/controllers/portal_controller.js.map +1 -1
- package/dist/controllers/preview_guard_controller.js +14 -3
- package/dist/controllers/preview_guard_controller.js.map +1 -1
- package/dist/controllers/progress_controller.d.ts +9 -19
- package/dist/controllers/progress_controller.js +271 -27
- package/dist/controllers/progress_controller.js.map +1 -1
- package/dist/controllers/radio_group_controller.d.ts +11 -8
- package/dist/controllers/radio_group_controller.js +167 -80
- package/dist/controllers/radio_group_controller.js.map +1 -1
- package/dist/controllers/range_slider_controller.d.ts +4 -3
- package/dist/controllers/range_slider_controller.js +27 -7
- package/dist/controllers/range_slider_controller.js.map +1 -1
- package/dist/controllers/rating_controller.js +93 -57
- package/dist/controllers/rating_controller.js.map +1 -1
- package/dist/controllers/read_more_controller.js +10 -6
- package/dist/controllers/read_more_controller.js.map +1 -1
- package/dist/controllers/reading_progress_controller.js +22 -5
- package/dist/controllers/reading_progress_controller.js.map +1 -1
- package/dist/controllers/relative_time_controller.d.ts +4 -4
- package/dist/controllers/relative_time_controller.js +75 -11
- package/dist/controllers/relative_time_controller.js.map +1 -1
- package/dist/controllers/reset_on_restore_controller.d.ts +3 -3
- package/dist/controllers/reset_on_restore_controller.js +6 -0
- package/dist/controllers/reset_on_restore_controller.js.map +1 -1
- package/dist/controllers/resizable_controller.d.ts +3 -0
- package/dist/controllers/resizable_controller.js +55 -22
- package/dist/controllers/resizable_controller.js.map +1 -1
- package/dist/controllers/roving_controller.d.ts +3 -3
- package/dist/controllers/roving_controller.js +10 -4
- package/dist/controllers/roving_controller.js.map +1 -1
- package/dist/controllers/scroll_area_controller.js +129 -88
- package/dist/controllers/scroll_area_controller.js.map +1 -1
- package/dist/controllers/scroll_restore_controller.d.ts +3 -3
- package/dist/controllers/scroll_restore_controller.js +14 -2
- package/dist/controllers/scroll_restore_controller.js.map +1 -1
- package/dist/controllers/scroll_visibility_controller.js +93 -60
- package/dist/controllers/scroll_visibility_controller.js.map +1 -1
- package/dist/controllers/scrollspy_controller.js +11 -5
- package/dist/controllers/scrollspy_controller.js.map +1 -1
- package/dist/controllers/separator_controller.d.ts +1 -1
- package/dist/controllers/separator_controller.js +59 -43
- package/dist/controllers/separator_controller.js.map +1 -1
- package/dist/controllers/sidebar_controller.d.ts +1 -1
- package/dist/controllers/sidebar_controller.js +150 -122
- package/dist/controllers/sidebar_controller.js.map +1 -1
- package/dist/controllers/skeleton_controller.js +55 -48
- package/dist/controllers/skeleton_controller.js.map +1 -1
- package/dist/controllers/slider_controller.d.ts +2 -1
- package/dist/controllers/slider_controller.js +27 -6
- package/dist/controllers/slider_controller.js.map +1 -1
- package/dist/controllers/smart_sticky_header_controller.d.ts +1 -1
- package/dist/controllers/smart_sticky_header_controller.js +13 -5
- package/dist/controllers/smart_sticky_header_controller.js.map +1 -1
- package/dist/controllers/sortable_controller.d.ts +4 -4
- package/dist/controllers/sortable_controller.js +27 -14
- package/dist/controllers/sortable_controller.js.map +1 -1
- package/dist/controllers/spinner_controller.js +55 -48
- package/dist/controllers/spinner_controller.js.map +1 -1
- package/dist/controllers/step_indicator_controller.d.ts +4 -4
- package/dist/controllers/step_indicator_controller.js +6 -0
- package/dist/controllers/step_indicator_controller.js.map +1 -1
- package/dist/controllers/stepper_controller.d.ts +2 -3
- package/dist/controllers/stepper_controller.js +6 -0
- package/dist/controllers/stepper_controller.js.map +1 -1
- package/dist/controllers/stick_to_bottom_controller.d.ts +3 -1
- package/dist/controllers/stick_to_bottom_controller.js +19 -8
- package/dist/controllers/stick_to_bottom_controller.js.map +1 -1
- package/dist/controllers/sticky_observer_controller.js +49 -43
- package/dist/controllers/sticky_observer_controller.js.map +1 -1
- package/dist/controllers/submit_once_controller.d.ts +2 -1
- package/dist/controllers/submit_once_controller.js +145 -85
- package/dist/controllers/submit_once_controller.js.map +1 -1
- package/dist/controllers/switch_controller.d.ts +7 -4
- package/dist/controllers/switch_controller.js +172 -28
- package/dist/controllers/switch_controller.js.map +1 -1
- package/dist/controllers/tabs_controller.d.ts +7 -4
- package/dist/controllers/tabs_controller.js +6 -1
- package/dist/controllers/tabs_controller.js.map +1 -1
- package/dist/controllers/tags_input_controller.d.ts +4 -3
- package/dist/controllers/tags_input_controller.js +157 -28
- package/dist/controllers/tags_input_controller.js.map +1 -1
- package/dist/controllers/textarea_autosize_controller.d.ts +1 -1
- package/dist/controllers/textarea_autosize_controller.js +40 -19
- package/dist/controllers/textarea_autosize_controller.js.map +1 -1
- package/dist/controllers/theme_controller.d.ts +3 -2
- package/dist/controllers/theme_controller.js +10 -4
- package/dist/controllers/theme_controller.js.map +1 -1
- package/dist/controllers/time_picker_controller.d.ts +38 -5
- package/dist/controllers/time_picker_controller.js +192 -54
- package/dist/controllers/time_picker_controller.js.map +1 -1
- package/dist/controllers/toast_controller.d.ts +4 -5
- package/dist/controllers/toast_controller.js +58 -27
- package/dist/controllers/toast_controller.js.map +1 -1
- package/dist/controllers/toggle_group_controller.d.ts +2 -3
- package/dist/controllers/toggle_group_controller.js +158 -56
- package/dist/controllers/toggle_group_controller.js.map +1 -1
- package/dist/controllers/toolbar_controller.d.ts +8 -6
- package/dist/controllers/toolbar_controller.js +150 -21
- package/dist/controllers/toolbar_controller.js.map +1 -1
- package/dist/controllers/tooltip_controller.d.ts +4 -1
- package/dist/controllers/tooltip_controller.js.map +1 -1
- package/dist/controllers/transition_controller.js.map +1 -1
- package/dist/controllers/tree_view_controller.d.ts +1 -1
- package/dist/controllers/tree_view_controller.js +134 -25
- package/dist/controllers/tree_view_controller.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.js +2451 -1312
- package/dist/index.js.map +1 -1
- package/dist/inspector/cli.d.ts +15 -11
- package/dist/inspector/cli.js +16 -3
- package/dist/inspector/cli.js.map +1 -1
- package/dist/inspector/cli_bin.js +53 -8
- package/dist/inspector/cli_bin.js.map +1 -1
- package/dist/inspector/examples.json +13 -13
- package/dist/inspector/manifest.json +19 -5
- package/dist/positioning/index.d.ts +7 -7
- package/dist/positioning/index.js +6 -0
- package/dist/positioning/index.js.map +1 -1
- package/package.json +10 -9
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/utils/composition_tracker.ts","../../src/utils/half_width.ts","../../src/utils/intl_format.ts","../../src/utils/locale.ts","../../src/utils/listener_set.ts","../../src/utils/microtask_coalescer.ts","../../src/utils/morph_render_watcher.ts","../../src/utils/number_bounds.ts","../../src/utils/coerce.ts","../../src/utils/number_value.ts","../../src/controllers/currency_input_controller.ts"],"names":[],"mappings":";;AAeA,IAAM,uBAAA,uBAA8B,GAAA,CAAI;AAAA,EACtC,uBAAA;AAAA,EACA,uBAAA;AAAA,EACA,uBAAA;AAAA,EACA;AACF,CAAC,CAAA;AAyDM,IAAM,qBAAN,MAAyB;AAAA,EACrB,gBAAA,uBAAuB,GAAA,EAAiB;AAAA,EACxC,cAAA,uBAAqB,GAAA,EAAiB;AAAA,EACtC,QAAA;AAAA,EACA,MAAA;AAAA,EAET,gBAAA,GAAuC,IAAA;AAAA,EAEvC,WAAA,CAAY,OAAA,GAAqC,EAAC,EAAG;AACnD,IAAA,IAAA,CAAK,WAAW,OAAA,CAAQ,OAAA;AACxB,IAAA,IAAA,CAAK,SAAS,OAAA,CAAQ,KAAA;AAAA,EACxB;AAAA,EAGA,QAAQ,MAAA,EAA2B;AACjC,IAAA,IAAI,IAAA,CAAK,gBAAA,CAAiB,GAAA,CAAI,MAAM,CAAA,EAAG;AACvC,IAAA,MAAA,CAAO,gBAAA,CAAiB,kBAAA,EAAoB,IAAA,CAAK,YAAY,CAAA;AAC7D,IAAA,MAAA,CAAO,gBAAA,CAAiB,gBAAA,EAAkB,IAAA,CAAK,UAAU,CAAA;AACzD,IAAA,MAAA,CAAO,gBAAA,CAAiB,SAAA,EAAW,IAAA,CAAK,cAAc,CAAA;AACtD,IAAA,IAAA,CAAK,gBAAA,CAAiB,IAAI,MAAM,CAAA;AAAA,EAClC;AAAA,EAGA,UAAU,MAAA,EAA2B;AACnC,IAAA,IAAI,CAAC,IAAA,CAAK,gBAAA,CAAiB,MAAA,CAAO,MAAM,CAAA,EAAG;AAC3C,IAAA,MAAA,CAAO,mBAAA,CAAoB,kBAAA,EAAoB,IAAA,CAAK,YAAY,CAAA;AAChE,IAAA,MAAA,CAAO,mBAAA,CAAoB,gBAAA,EAAkB,IAAA,CAAK,UAAU,CAAA;AAC5D,IAAA,MAAA,CAAO,mBAAA,CAAoB,SAAA,EAAW,IAAA,CAAK,cAAc,CAAA;AACzD,IAAA,IAAA,CAAK,cAAA,CAAe,OAAO,MAAM,CAAA;AACjC,IAAA,IAAI,IAAA,CAAK,gBAAA,KAAqB,MAAA,EAAQ,IAAA,CAAK,gBAAA,GAAmB,IAAA;AAAA,EAChE;AAAA,EAGA,UAAA,GAAmB;AACjB,IAAA,KAAA,MAAW,MAAA,IAAU,KAAK,gBAAA,EAAkB;AAC1C,MAAA,MAAA,CAAO,mBAAA,CAAoB,kBAAA,EAAoB,IAAA,CAAK,YAAY,CAAA;AAChE,MAAA,MAAA,CAAO,mBAAA,CAAoB,gBAAA,EAAkB,IAAA,CAAK,UAAU,CAAA;AAC5D,MAAA,MAAA,CAAO,mBAAA,CAAoB,SAAA,EAAW,IAAA,CAAK,cAAc,CAAA;AAAA,IAC3D;AACA,IAAA,IAAA,CAAK,iBAAiB,KAAA,EAAM;AAC5B,IAAA,IAAA,CAAK,eAAe,KAAA,EAAM;AAC1B,IAAA,IAAA,CAAK,gBAAA,GAAmB,IAAA;AAAA,EAC1B;AAAA,EAGA,YAAY,KAAA,EAAoC;AAC9C,IAAA,OAAO,IAAA,CAAK,cAAA,CAAe,IAAA,GAAO,CAAA,IAAK,OAAO,WAAA,KAAgB,IAAA;AAAA,EAChE;AAAA,EAQA,uBAAuB,KAAA,EAAsC;AAC3D,IAAA,MAAM,YAAY,IAAA,CAAK,gBAAA;AACvB,IAAA,IAAA,CAAK,gBAAA,GAAmB,IAAA;AACxB,IAAA,IAAI,SAAA,KAAc,IAAA,IAAQ,SAAA,KAAc,KAAA,CAAM,QAAQ,OAAO,KAAA;AAG7D,IAAA,MAAM,YAAY,KAAA,CAAM,SAAA;AACxB,IAAA,OAAO,CAAC,SAAA,IAAa,uBAAA,CAAwB,GAAA,CAAI,SAAS,CAAA;AAAA,EAC5D;AAAA,EAES,YAAA,GAAe,CAAC,KAAA,KAAuB;AAC9C,IAAA,IAAA,CAAK,gBAAA,GAAmB,IAAA;AACxB,IAAA,IAAI,MAAM,aAAA,EAAe,IAAA,CAAK,cAAA,CAAe,GAAA,CAAI,MAAM,aAAa,CAAA;AACpE,IAAA,IAAA,CAAK,WAAW,KAAK,CAAA;AAAA,EACvB,CAAA;AAAA,EAES,UAAA,GAAa,CAAC,KAAA,KAAuB;AAC5C,IAAA,IAAI,MAAM,aAAA,EAAe,IAAA,CAAK,cAAA,CAAe,MAAA,CAAO,MAAM,aAAa,CAAA;AACvE,IAAA,IAAA,CAAK,mBAAmB,KAAA,CAAM,MAAA;AAC9B,IAAA,IAAA,CAAK,SAAS,KAAK,CAAA;AAAA,EACrB,CAAA;AAAA,EAGS,iBAAiB,MAAY;AACpC,IAAA,IAAA,CAAK,gBAAA,GAAmB,IAAA;AAAA,EAC1B,CAAA;AACF,CAAA;;AC7JA,IAAM,gBAAA,GAAmB,KAAA;AAYlB,SAAS,cAAc,IAAA,EAAsB;AAClD,EAAA,IAAI,IAAA,IAAQ,QAAA,IAAO,IAAA,IAAQ,QAAA,EAAK;AAC9B,IAAA,OAAO,OAAO,YAAA,CAAa,IAAA,CAAK,UAAA,CAAW,CAAC,IAAI,gBAAgB,CAAA;AAAA,EAClE;AACA,EAAA,OAAO,IAAA,KAAS,WAAM,GAAA,GAAM,IAAA;AAC9B;;ACEA,IAAM,UAAA,uBAAiB,OAAA,EAAsC;AAyBtD,SAAS,aAAA,CACd,OAAA,EACA,MAAA,EACA,OAAA,EACA,cAAA,EACU;AACV,EAAA,MAAM,KAAA,GAAQ,SAAS,OAAO,CAAA;AAC9B,EAAA,MAAM,GAAA,GAAM,QAAA,CAAS,MAAA,EAAQ,OAAA,EAAS,cAAc,CAAA;AACpD,EAAA,IAAI,MAAM,GAAA,CAAI,GAAG,GAAG,OAAO,KAAA,CAAM,IAAI,GAAG,CAAA;AACxC,EAAA,MAAM,SAAA,GAAY,SAAA,CAAU,OAAA,EAAS,MAAA,EAAQ,SAAS,cAAc,CAAA;AACpE,EAAA,KAAA,CAAM,GAAA,CAAI,KAAK,SAAS,CAAA;AACxB,EAAA,OAAO,SAAA;AACT;AAGA,SAAS,SAAS,OAAA,EAAuC;AACvD,EAAA,MAAM,QAAA,GAAW,UAAA,CAAW,GAAA,CAAI,OAAO,CAAA;AACvC,EAAA,IAAI,UAAU,OAAO,QAAA;AACrB,EAAA,MAAM,OAAA,uBAAc,GAAA,EAAqB;AACzC,EAAA,UAAA,CAAW,GAAA,CAAI,SAAS,OAAO,CAAA;AAC/B,EAAA,OAAO,OAAA;AACT;AAQA,SAAS,QAAA,CACP,MAAA,EACA,OAAA,EACA,cAAA,EACQ;AACR,EAAA,OAAO,KAAK,SAAA,CAAU,CAAC,MAAA,EAAQ,OAAA,EAAS,cAAc,CAAC,CAAA;AACzD;AAGA,SAAS,SAAA,CACP,OAAA,EACA,MAAA,EACA,OAAA,EACA,cAAA,EACU;AACV,EAAA,IAAI;AACF,IAAA,OAAO,IAAI,OAAA,CAAQ,MAAA,EAAQ,OAAO,CAAA;AAAA,EACpC,SAAS,KAAA,EAAO;AACd,IAAA,IAAI,EAAE,KAAA,YAAiB,UAAA,CAAA,EAAa,MAAM,KAAA;AAC1C,IAAA,IAAI,cAAA,KAAmB,QAAW,OAAO,IAAA;AACzC,IAAA,OAAO,IAAI,OAAA,CAAQ,cAAA,EAAgB,OAAO,CAAA;AAAA,EAC5C;AACF;;AC9EO,SAAS,aAAA,CAAc,OAAA,EAAkB,QAAA,GAAW,EAAA,EAAwB;AACjF,EAAA,OAAO,YAAY,OAAA,CAAQ,OAAA,CAAQ,QAAQ,CAAA,EAAG,YAAA,CAAa,MAAM,CAAA,IAAK,MAAA;AACxE;;AC8BO,IAAM,cAAN,MAAkB;AAAA,EAEvB,MAAA,GAAS,IAAI,eAAA,EAAgB;AAAA,EAS7B,GAAA,CACE,MAAA,EACA,IAAA,EACA,OAAA,EACA,OAAA,EACM;AACN,IAAA,MAAA,CAAO,gBAAA,CAAiB,IAAA,EAAM,OAAA,EAAS,EAAE,GAAG,SAAS,MAAA,EAAQ,IAAA,CAAK,MAAA,CAAO,MAAA,EAAQ,CAAA;AAAA,EACnF;AAAA,EAMA,OAAA,GAAgB;AACd,IAAA,IAAA,CAAK,OAAO,KAAA,EAAM;AAClB,IAAA,IAAA,CAAK,MAAA,GAAS,IAAI,eAAA,EAAgB;AAAA,EACpC;AACF,CAAA;;AC7BO,IAAM,qBAAN,MAAyB;AAAA,EACrB,IAAA;AAAA,EACT,OAAA,GAAU,KAAA;AAAA,EACV,OAAA,GAAU,KAAA;AAAA,EACV,WAAA,GAAc,CAAA;AAAA,EAGd,YAAY,GAAA,EAAiB;AAC3B,IAAA,IAAA,CAAK,IAAA,GAAO,GAAA;AAAA,EACd;AAAA,EAGA,QAAA,GAAiB;AACf,IAAA,IAAA,CAAK,OAAA,GAAU,IAAA;AAAA,EACjB;AAAA,EAGA,MAAA,GAAe;AACb,IAAA,IAAA,CAAK,OAAA,GAAU,KAAA;AACf,IAAA,IAAA,CAAK,OAAA,GAAU,KAAA;AACf,IAAA,IAAA,CAAK,WAAA,IAAe,CAAA;AAAA,EACtB;AAAA,EAGA,QAAA,GAAiB;AACf,IAAA,IAAI,CAAC,IAAA,CAAK,OAAA,IAAW,IAAA,CAAK,OAAA,EAAS;AACnC,IAAA,IAAA,CAAK,OAAA,GAAU,IAAA;AACf,IAAA,MAAM,aAAa,IAAA,CAAK,WAAA;AACxB,IAAA,cAAA,CAAe,MAAM;AAEnB,MAAA,IAAI,UAAA,KAAe,KAAK,WAAA,IAAe,CAAC,KAAK,OAAA,IAAW,CAAC,KAAK,OAAA,EAAS;AACvE,MAAA,IAAA,CAAK,OAAA,GAAU,KAAA;AACf,MAAA,IAAA,CAAK,IAAA,EAAK;AAAA,IACZ,CAAC,CAAA;AAAA,EACH;AACF,CAAA;;ACxEO,IAAM,qBAAN,MAAyB;AAAA,EACrB,UAAA,GAAa,IAAI,WAAA,EAAY;AAAA,EAC7B,KAAA;AAAA,EACT,QAAA,GAA2B,IAAA;AAAA,EAClB,QAAA,GAAW,MAAY,IAAA,CAAK,KAAA,CAAM,QAAA,EAAS;AAAA,EAGpD,YAAY,GAAA,EAAiB;AAC3B,IAAA,IAAA,CAAK,KAAA,GAAQ,IAAI,kBAAA,CAAmB,GAAG,CAAA;AAAA,EACzC;AAAA,EAGA,QAAQ,OAAA,EAAwB;AAC9B,IAAA,IAAI,IAAA,CAAK,aAAa,OAAA,EAAS;AAC/B,IAAA,IAAA,CAAK,UAAA,EAAW;AAChB,IAAA,IAAA,CAAK,QAAA,GAAW,OAAA;AAChB,IAAA,IAAA,CAAK,MAAM,QAAA,EAAS;AACpB,IAAA,IAAA,CAAK,UAAA,CAAW,GAAA,CAAI,OAAA,EAAS,qBAAA,EAAuB,KAAK,QAAQ,CAAA;AAAA,EACnE;AAAA,EAGA,QAAA,GAAiB;AACf,IAAA,IAAA,CAAK,MAAM,QAAA,EAAS;AAAA,EACtB;AAAA,EAGA,UAAA,GAAmB;AACjB,IAAA,IAAA,CAAK,WAAW,OAAA,EAAQ;AACxB,IAAA,IAAA,CAAK,MAAM,MAAA,EAAO;AAClB,IAAA,IAAA,CAAK,QAAA,GAAW,IAAA;AAAA,EAClB;AACF,CAAA;;ACGO,SAAS,mBAAA,CAAoB,OAAe,MAAA,EAA+B;AAChF,EAAA,IAAI,CAAC,MAAA,CAAO,QAAA,CAAS,KAAK,CAAA,EAAG;AAC3B,IAAA,MAAM,YAAY,KAAA,KAAU,QAAA,GAAW,UAAA,GAAa,KAAA,KAAU,YAAY,UAAA,GAAa,IAAA;AACvF,IAAA,IAAI,SAAA,KAAc,MAAM,OAAO,KAAA;AAC/B,IAAA,IAAI,OAAO,aAAA,KAAkB,MAAA,IAAU,MAAA,CAAO,aAAA,KAAkB,WAAW,OAAO,KAAA;AAAA,EACpF;AACA,EAAA,IAAI,OAAO,GAAA,KAAQ,MAAA,IAAa,KAAA,GAAQ,MAAA,CAAO,KAAK,OAAO,KAAA;AAC3D,EAAA,IAAI,OAAO,GAAA,KAAQ,MAAA,IAAa,KAAA,GAAQ,MAAA,CAAO,KAAK,OAAO,KAAA;AAC3D,EAAA,IAAI,OAAO,YAAA,KAAiB,MAAA,IAAa,KAAA,IAAS,MAAA,CAAO,cAAc,OAAO,KAAA;AAC9E,EAAA,IAAI,OAAO,OAAA,IAAW,CAAC,OAAO,SAAA,CAAU,KAAK,GAAG,OAAO,KAAA;AACvD,EAAA,IAAI,MAAA,CAAO,kBAAkB,MAAA,IAAa,CAAC,OAAO,aAAA,CAAc,QAAA,CAAS,KAAK,CAAA,EAAG,OAAO,KAAA;AACxF,EAAA,OAAO,IAAA;AACT;;AChCO,SAAS,UAAA,CAAW,GAAA,EAAa,QAAA,EAAkB,MAAA,EAA8B;AACtF,EAAA,OAAO,mBAAA,CAAoB,GAAA,EAAK,MAAM,CAAA,GAAI,GAAA,GAAM,QAAA;AAClD;;AClBO,IAAM,oBAAN,MAAwB;AAAA,EAEpB,aAAA,uBAAoB,GAAA,EAAoB;AAAA,EAGjD,IAAA,CACE,KAAA,EACA,IAAA,EACA,GAAA,EACA,UACA,MAAA,EACQ;AACR,IAAA,MAAM,QAAA,GAAW,UAAA,CAAW,GAAA,EAAK,QAAA,EAAU,MAAM,CAAA;AACjD,IAAA,IAAI,mBAAA,CAAoB,GAAA,EAAK,MAAM,CAAA,EAAG;AACpC,MAAA,IAAA,CAAK,aAAA,CAAc,OAAO,IAAI,CAAA;AAC9B,MAAA,OAAO,QAAA;AAAA,IACT;AACA,IAAA,MAAM,SAAA,GAAY,CAAA,KAAA,EAAQ,KAAA,CAAM,UAAU,IAAI,IAAA,CAAK,OAAA,CAAQ,QAAA,EAAU,CAAC,WAAW,CAAA,CAAA,EAAI,MAAA,CAAO,WAAA,EAAa,EAAE,CAAC,CAAA,MAAA,CAAA;AAC5G,IAAA,MAAM,OAAA,GAAU,KAAA,CAAM,OAAA,CAAQ,YAAA,CAAa,SAAS,CAAA;AACpD,IAAA,IAAI,YAAY,IAAA,EAAM;AACpB,MAAA,IAAA,CAAK,aAAA,CAAc,OAAO,IAAI,CAAA;AAC9B,MAAA,OAAO,QAAA;AAAA,IACT;AACA,IAAA,IAAI,IAAA,CAAK,aAAA,CAAc,GAAA,CAAI,IAAI,MAAM,OAAA,EAAS;AAC5C,MAAA,IAAA,CAAK,aAAA,CAAc,GAAA,CAAI,IAAA,EAAM,OAAO,CAAA;AACpC,MAAA,OAAA,CAAQ,IAAA;AAAA,QACN,CAAA,YAAA,EAAe,KAAA,CAAM,UAAU,CAAA,+BAAA,EAAkC,IAAI,CAAA,cAAA,EAAiB,IAAA,CAAK,SAAA,CAAU,OAAO,CAAC,CAAA,QAAA,EAAW,QAAQ,CAAA,CAAA;AAAA,OAClI;AAAA,IACF;AACA,IAAA,OAAO,QAAA;AAAA,EACT;AACF,CAAA;;ACNA,IAAM,eAAA,GAAkB,OAAA;AA4FjB,IAAM,uBAAA,GAAN,MAAM,wBAAA,SAAgC,UAAA,CAAwB;AAAA,EAE1D,QAAA,GAAW,IAAI,iBAAA,EAAkB;AAAA,EAE1C,OAAgB,OAAA,GAAU,CAAC,SAAA,EAAW,SAAS,SAAS,CAAA;AAAA,EACxD,OAAgB,MAAA,GAAS;AAAA,IACvB,MAAA,EAAQ,EAAE,IAAA,EAAM,MAAA,EAAQ,SAAS,EAAA,EAAG;AAAA,IACpC,QAAA,EAAU,EAAE,IAAA,EAAM,MAAA,EAAQ,SAAS,EAAA,EAAG;AAAA,IACtC,SAAA,EAAW,EAAE,IAAA,EAAM,MAAA,EAAQ,SAAS,CAAA;AAAE,GACxC;AAAA,EAEA,OAAO,gBAAA,GAAmB;AAAA,IACxB,SAAA,EAAW,EAAE,MAAA,EAAQ,IAAA,EAAM,SAAS,IAAA,EAAM,GAAA,EAAK,CAAA,EAAG,GAAA,EAAK,GAAA;AAAI,GAC7D;AAAA,EACA,OAAO,OAAA,GAAU,CAAC,QAAA,EAAU,SAAS,CAAA;AAAA,EACrC,OAAO,MAAA,GAAS,CAAC,QAAA,EAAU,WAAW,CAAA;AAAA,EAatC,UAAA,GAA4B,IAAA;AAAA,EAC5B,QAAA,GAAW,KAAA;AAAA,EAEX,WAAA,GAAc,KAAA;AAAA,EAEd,UAAA,GAAiC,IAAA;AAAA,EAKjC,SAAA,GAA2B,IAAA;AAAA,EAG3B,OAAA;AAAA,EACA,SAAA,GAAY,EAAA;AAAA,EACZ,UAAA,GAAa,CAAA;AAAA,EAGb,SAAA;AAAA,EACA,MAAA;AAAA,EACA,WAAA;AAAA,EACA,MAAA,GAAS,GAAA;AAAA,EACT,QAAA,GAAW,GAAA;AAAA,EAEF,OAAA,uBAAc,GAAA,EAAoB;AAAA,EAOlC,YAAA,GAAe,IAAI,kBAAA,CAAmB;AAAA,IAC7C,OAAA,EAAS,CAAC,KAAA,KAAU;AAClB,MAAA,IAAA,CAAK,aAAa,KAAA,CAAM,aAAA;AAAA,IAC1B,CAAA;AAAA,IACA,OAAO,MAAM;AACX,MAAA,IAAA,CAAK,UAAA,GAAa,IAAA;AAClB,MAAA,IAAA,CAAK,SAAA,CAAU,OAAO,MAAM,CAAA;AAC5B,MAAA,IAAA,CAAK,gBAAA,EAAiB;AAAA,IACxB;AAAA,GACD,CAAA;AAAA,EAMD,kBAAA,GAA2B;AACzB,IAAA,IAAA,CAAK,iBAAA,EAAkB;AAAA,EACzB;AAAA,EAEA,oBAAA,GAA6B;AAC3B,IAAA,IAAA,CAAK,iBAAA,EAAkB;AAAA,EACzB;AAAA,EAEA,qBAAA,GAA8B;AAC5B,IAAA,IAAA,CAAK,iBAAA,EAAkB;AAAA,EACzB;AAAA,EAcA,iBAAA,GAA0B;AACxB,IAAA,IAAI,IAAA,CAAK,YAAA,CAAa,WAAA,EAAY,EAAG;AACnC,MAAA,IAAA,CAAK,WAAA,GAAc,IAAA;AACnB,MAAA;AAAA,IACF;AAGA,IAAA,IAAI,CAAC,IAAA,CAAK,QAAA,IAAY,CAAC,KAAK,gBAAA,EAAkB;AAC9C,IAAA,MAAM,IAAA,GAAO,KAAK,YAAA,EAAa;AAC/B,IAAA,IAAI,QAAA,CAAS,aAAA,KAAkB,IAAA,CAAK,aAAA,EAAe;AACjD,MAAA,MAAM,SAAA,GAAY,IAAA,CAAK,OAAA,CAAQ,IAAA,CAAK,KAAK,CAAA;AACzC,MAAA,IAAA,CAAK,MAAM,SAAS,CAAA;AACpB,MAAA,IAAA,CAAK,QAAA,CAAS,IAAA,CAAK,KAAA,EAAO,SAAA,EAAW,WAAW,CAAA;AAAA,IAClD,CAAA,MAAO;AACL,MAAA,IAAA,CAAK,YAAA,CAAa,IAAA,CAAK,KAAA,EAAO,WAAW,CAAA;AAAA,IAC3C;AAAA,EACF;AAAA,EAGA,gBAAA,GAAyB;AACvB,IAAA,IAAI,CAAC,KAAK,WAAA,EAAa;AACvB,IAAA,IAAA,CAAK,WAAA,GAAc,KAAA;AACnB,IAAA,IAAA,CAAK,iBAAA,EAAkB;AAAA,EACzB;AAAA,EAQA,YAAA,GAAqB;AACnB,IAAA,MAAM,IAAA,GAAO,KAAK,aAAA,CAAc,KAAA;AAChC,IAAA,MAAM,MAAM,IAAA,KAAS,IAAA,CAAK,YAAY,IAAA,CAAK,KAAA,CAAM,IAAI,CAAA,GAAI,IAAA;AACzD,IAAA,IAAA,CAAK,mBAAA,EAAoB;AACzB,IAAA,OAAO,GAAA,IAAO,IAAA,CAAK,KAAA,CAAM,IAAI,CAAA;AAAA,EAC/B;AAAA,EAGA,mBAAA,GAA4B;AAC1B,IAAA,IAAA,CAAK,WAAA,GAAc,KAAA;AACnB,IAAA,IAAA,CAAK,WAAA,EAAY;AAAA,EACnB;AAAA,EAES,SAAS,IAAI,kBAAA,CAAmB,MAAM,IAAA,CAAK,mBAAmB,CAAA;AAAA,EAc9D,OAAA,GAAgB;AACvB,IAAA,IAAA,CAAK,MAAA,CAAO,OAAA,CAAQ,IAAA,CAAK,OAAO,CAAA;AAChC,IAAA,IAAA,CAAK,QAAA,GAAW,IAAA;AAChB,IAAA,IAAA,CAAK,mBAAA,EAAoB;AACzB,IAAA,IAAI,CAAC,KAAK,gBAAA,EAAkB;AAC5B,IAAA,IAAI,IAAA,CAAK,aAAA,CAAc,KAAA,KAAU,IAAA,CAAK,SAAA,EAAW;AAC/C,MAAA,IAAA,CAAK,YAAA,CAAa,IAAA,CAAK,UAAA,EAAY,WAAW,CAAA;AAC9C,MAAA;AAAA,IACF;AAIA,IAAA,MAAM,EAAE,KAAA,EAAM,GAAI,KAAK,KAAA,CAAM,IAAA,CAAK,cAAc,KAAK,CAAA;AACrD,IAAA,IAAA,CAAK,aAAa,KAAA,KAAU,IAAA,GAAO,OAAO,KAAA,CAAM,KAAA,EAAO,KAAK,UAAU,CAAA;AACtE,IAAA,IAAA,CAAK,YAAA,CAAa,OAAO,WAAW,CAAA;AAAA,EACtC;AAAA,EAOS,UAAA,GAAmB;AAC1B,IAAA,IAAA,CAAK,OAAO,UAAA,EAAW;AACvB,IAAA,IAAA,CAAK,wBAAA,EAAyB;AAC9B,IAAA,IAAA,CAAK,aAAa,UAAA,EAAW;AAC7B,IAAA,IAAA,CAAK,QAAA,GAAW,KAAA;AAAA,EAClB;AAAA,EAWA,uBAAuB,MAAA,EAAgC;AACrD,IAAA,IAAA,CAAK,YAAA,CAAa,QAAQ,MAAM,CAAA;AAChC,IAAA,IAAI,CAAC,KAAK,QAAA,IAAY,CAAC,KAAK,gBAAA,IAAoB,IAAA,CAAK,kBAAkB,MAAA,EAAQ;AAC/E,IAAA,IAAA,CAAK,YAAA,CAAa,IAAA,CAAK,YAAA,EAAa,CAAE,OAAO,WAAW,CAAA;AAAA,EAC1D;AAAA,EAUA,0BAA0B,MAAA,EAAgC;AACxD,IAAA,IAAA,CAAK,YAAA,CAAa,UAAU,MAAM,CAAA;AAClC,IAAA,IAAI,MAAA,KAAW,IAAA,CAAK,UAAA,EAAY,IAAA,CAAK,wBAAA,EAAyB;AAC9D,IAAA,IAAA,CAAK,iBAAA,EAAkB;AAAA,EACzB;AAAA,EAUA,wBAAA,GAAiC;AAC/B,IAAA,MAAM,UAAU,IAAA,CAAK,UAAA;AACrB,IAAA,IAAA,CAAK,UAAA,GAAa,IAAA;AAClB,IAAA,IAAI,IAAA,CAAK,gBAAA,IAAoB,IAAA,CAAK,aAAA,KAAkB,OAAA,EAAS;AAC3D,MAAA,IAAA,CAAK,SAAA,CAAU,OAAO,WAAW,CAAA;AAAA,IACnC;AAAA,EACF;AAAA,EAGA,oBAAA,GAA6B;AAC3B,IAAA,IAAI,IAAA,CAAK,QAAA,EAAU,IAAA,CAAK,OAAA,EAAQ;AAAA,EAClC;AAAA,EAGA,uBAAA,GAAgC;AAC9B,IAAA,IAAI,IAAA,CAAK,QAAA,EAAU,IAAA,CAAK,OAAA,EAAQ;AAAA,EAClC;AAAA,EAGA,sBAAA,GAA+B;AAC7B,IAAA,IAAI,IAAA,CAAK,QAAA,EAAU,IAAA,CAAK,OAAA,EAAQ;AAAA,EAClC;AAAA,EAGA,yBAAA,GAAkC;AAChC,IAAA,IAAI,IAAA,CAAK,QAAA,EAAU,IAAA,CAAK,OAAA,EAAQ;AAAA,EAClC;AAAA,EAGA,QAAQ,KAAA,EAAoB;AAC1B,IAAA,IAAI,IAAA,CAAK,YAAA,CAAa,WAAA,CAAY,KAAmB,CAAA,EAAG;AACxD,IAAA,IAAA,CAAK,SAAA,CAAU,OAAO,MAAM,CAAA;AAAA,EAC9B;AAAA,EAGA,MAAA,GAAe;AACb,IAAA,IAAA,CAAK,SAAA,CAAU,MAAM,MAAM,CAAA;AAAA,EAC7B;AAAA,EAOA,SAAA,CAAU,gBAAyB,KAAA,EAAoB;AACrD,IAAA,IAAI,CAAC,KAAK,gBAAA,EAAkB;AAC5B,IAAA,MAAM,GAAA,GAAM,KAAK,aAAA,CAAc,KAAA;AAC/B,IAAA,MAAM,EAAE,KAAA,EAAO,KAAA,EAAM,GAAI,IAAA,CAAK,MAAM,GAAG,CAAA;AAEvC,IAAA,IAAI,cAAA,EAAgB;AAElB,MAAA,IAAA,CAAK,YAAA,CAAa,OAAO,KAAK,CAAA;AAC9B,MAAA;AAAA,IACF;AAEA,IAAA,MAAM,SAAA,GAAY,IAAA,CAAK,OAAA,CAAQ,KAAK,CAAA;AACpC,IAAA,IAAI,cAAc,GAAA,EAAK;AACrB,MAAA,MAAM,KAAA,GAAQ,KAAK,aAAA,CAAc,cAAA;AACjC,MAAA,MAAM,SAAS,KAAA,KAAU,IAAA,GAAO,OAAO,IAAA,CAAK,kBAAA,CAAmB,KAAK,KAAK,CAAA;AACzE,MAAA,IAAA,CAAK,cAAc,KAAA,GAAQ,SAAA;AAC3B,MAAA,IAAI,MAAA,KAAW,IAAA,EAAM,IAAA,CAAK,aAAA,CAAc,WAAW,MAAM,CAAA;AAAA,IAC3D;AACA,IAAA,IAAA,CAAK,SAAA,GAAY,SAAA;AACjB,IAAA,IAAA,CAAK,QAAA,CAAS,KAAA,EAAO,SAAA,EAAW,KAAK,CAAA;AAAA,EACvC;AAAA,EAMA,YAAA,CAAa,OAAsB,KAAA,EAAoB;AACrD,IAAA,IAAI,UAAU,IAAA,EAAM;AAClB,MAAA,IAAA,CAAK,MAAM,EAAE,CAAA;AACb,MAAA,IAAA,CAAK,QAAA,CAAS,IAAA,EAAM,EAAA,EAAI,KAAK,CAAA;AAC7B,MAAA;AAAA,IACF;AACA,IAAA,MAAM,OAAA,GAAU,KAAA,CAAM,KAAA,EAAO,IAAA,CAAK,UAAU,CAAA;AAC5C,IAAA,MAAM,SAAA,GAAY,IAAA,CAAK,MAAA,CAAO,MAAA,CAAO,OAAO,CAAA;AAC5C,IAAA,IAAA,CAAK,MAAM,SAAS,CAAA;AACpB,IAAA,IAAA,CAAK,QAAA,CAAS,OAAA,EAAS,SAAA,EAAW,KAAK,CAAA;AAAA,EACzC;AAAA,EAGA,MAAM,IAAA,EAAoB;AACxB,IAAA,IAAI,KAAK,aAAA,CAAc,KAAA,KAAU,IAAA,EAAM,IAAA,CAAK,cAAc,KAAA,GAAQ,IAAA;AAClE,IAAA,IAAA,CAAK,SAAA,GAAY,IAAA;AAAA,EACnB;AAAA,EAKA,QAAQ,KAAA,EAA2B;AACjC,IAAA,MAAM,GAAA,GAAM,KAAA,CAAM,GAAA,KAAQ,EAAA,GAAK,EAAA,GAAK,IAAA,CAAK,SAAA,CAAU,MAAA,CAAO,MAAA,CAAO,KAAA,CAAM,GAAG,CAAC,CAAA;AAC3E,IAAA,MAAM,OAAO,KAAA,CAAM,MAAA,GAAS,IAAA,CAAK,QAAA,GAAW,MAAM,IAAA,GAAO,EAAA;AACzD,IAAA,OAAO,KAAA,CAAM,OAAO,GAAA,GAAM,IAAA;AAAA,EAC5B;AAAA,EAGA,aAAA,CAAc,WAAmB,iBAAA,EAAiC;AAChE,IAAA,IAAI,IAAA,GAAO,CAAA;AACX,IAAA,IAAI,WAAW,SAAA,CAAU,MAAA;AACzB,IAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,SAAA,CAAU,QAAQ,CAAA,EAAA,EAAK;AACzC,MAAA,IAAI,QAAQ,iBAAA,EAAmB;AAC7B,QAAA,QAAA,GAAW,CAAA;AACX,QAAA;AAAA,MACF;AACA,MAAA,IAAI,KAAK,cAAA,CAAe,SAAA,CAAU,CAAC,CAAW,GAAG,IAAA,IAAQ,CAAA;AAAA,IAC3D;AACA,IAAA,IAAI;AACF,MAAA,IAAA,CAAK,aAAA,CAAc,iBAAA,CAAkB,QAAA,EAAU,QAAQ,CAAA;AAAA,IACzD,CAAA,CAAA,MAAQ;AAAA,IAGR;AAAA,EACF;AAAA,EAOA,kBAAA,CAAmB,MAAc,KAAA,EAAuB;AACtD,IAAA,IAAI,KAAA,GAAQ,CAAA;AACZ,IAAA,IAAI,OAAA,GAAU,KAAA;AACd,IAAA,IAAI,QAAA,GAAW,KAAA;AACf,IAAA,IAAI,MAAA,GAAS,KAAA;AACb,IAAA,KAAA,MAAW,EAAA,IAAM,KAAK,UAAA,CAAW,IAAA,CAAK,MAAM,CAAA,EAAG,KAAK,CAAC,CAAA,EAAG;AACtD,MAAA,IAAI,EAAA,IAAM,GAAA,IAAO,EAAA,IAAM,GAAA,EAAK;AAC1B,QAAA,KAAA,IAAS,CAAA;AACT,QAAA,QAAA,GAAW,IAAA;AAAA,MACb,CAAA,MAAA,IAAA,CAAY,EAAA,KAAO,GAAA,IAAO,EAAA,KAAO,GAAA,KAAQ,CAAC,OAAA,IAAW,CAAC,QAAA,IAAY,CAAC,MAAA,EAAQ;AACzE,QAAA,KAAA,IAAS,CAAA;AACT,QAAA,OAAA,GAAU,IAAA;AAAA,MACZ,WAAW,IAAA,CAAK,cAAA,CAAe,EAAE,CAAA,IAAK,CAAC,MAAA,EAAQ;AAC7C,QAAA,KAAA,IAAS,CAAA;AACT,QAAA,MAAA,GAAS,IAAA;AAAA,MACX;AAAA,IACF;AACA,IAAA,OAAO,KAAA;AAAA,EACT;AAAA,EAGA,eAAe,EAAA,EAAqB;AAClC,IAAA,IAAI,EAAA,IAAM,GAAA,IAAO,EAAA,IAAM,GAAA,EAAK,OAAO,IAAA;AACnC,IAAA,IAAI,EAAA,KAAO,GAAA,IAAO,EAAA,KAAO,GAAA,EAAK,OAAO,IAAA;AACrC,IAAA,OAAO,OAAO,IAAA,CAAK,QAAA,IAAa,EAAA,KAAO,GAAA,IAAO,KAAK,MAAA,KAAW,GAAA;AAAA,EAChE;AAAA,EAGA,OAAO,KAAA,EAA4B;AACjC,IAAA,MAAM,UAAU,KAAA,KAAU,IAAA;AAC1B,IAAA,IAAI,IAAA,CAAK,gBAAgB,IAAA,CAAK,WAAA,CAAY,QAAQ,OAAA,GAAU,EAAA,GAAK,OAAO,KAAK,CAAA;AAC7E,IAAA,IAAI,KAAK,gBAAA,EAAkB;AACzB,MAAA,IAAA,CAAK,cAAc,WAAA,GAAc,OAAA,GAAU,KAAK,IAAA,CAAK,WAAA,CAAY,OAAO,KAAK,CAAA;AAAA,IAC/E;AACA,IAAA,IAAA,CAAK,QAAQ,eAAA,CAAgB,CAAA,KAAA,EAAQ,IAAA,CAAK,UAAU,UAAU,OAAO,CAAA;AAAA,EACvE;AAAA,EASA,QAAA,CAAS,KAAA,EAAsB,SAAA,EAAmB,KAAA,EAAoB;AACpE,IAAA,IAAA,CAAK,OAAO,KAAK,CAAA;AACjB,IAAA,IAAI,KAAA,KAAU,KAAK,UAAA,EAAY;AAC/B,IAAA,IAAA,CAAK,UAAA,GAAa,KAAA;AAClB,IAAA,MAAM,SAAS,EAAE,KAAA,EAAO,WAAW,KAAA,KAAU,IAAA,GAAO,KAAK,SAAA,EAAU;AACnE,IAAA,IAAI,UAAU,MAAA,EAAQ,IAAA,CAAK,SAAS,QAAA,EAAU,EAAE,QAAQ,CAAA;AAAA,SACnD,IAAA,CAAK,QAAA,CAAS,WAAA,EAAa,EAAE,QAAQ,CAAA;AAAA,EAC5C;AAAA,EASA,MAAM,IAAA,EAAoB;AACxB,IAAA,IAAI,IAAA,GAA2B,EAAA;AAC/B,IAAA,IAAI,GAAA,GAAM,EAAA;AACV,IAAA,IAAI,MAAA,GAAS,KAAA;AACb,IAAA,IAAI,IAAA,GAAO,EAAA;AACX,IAAA,KAAA,MAAW,EAAA,IAAM,IAAA,CAAK,UAAA,CAAW,IAAI,CAAA,EAAG;AACtC,MAAA,IAAI,EAAA,IAAM,GAAA,IAAO,EAAA,IAAM,GAAA,EAAK;AAC1B,QAAA,IAAI,QAAQ,IAAA,IAAQ,EAAA;AAAA,aACf,GAAA,IAAO,EAAA;AAAA,MACd,CAAA,MAAA,IAAA,CAAY,EAAA,KAAO,GAAA,IAAO,EAAA,KAAO,GAAA,KAAQ,SAAS,EAAA,IAAM,GAAA,KAAQ,EAAA,IAAM,CAAC,MAAA,EAAQ;AAC7E,QAAA,IAAA,GAAO,EAAA;AAAA,MACT,WAAW,IAAA,CAAK,cAAA,CAAe,EAAE,CAAA,IAAK,CAAC,MAAA,EAAQ;AAC7C,QAAA,MAAA,GAAS,IAAA;AAAA,MACX;AAAA,IACF;AACA,IAAA,MAAM,KAAA,GAAoB,EAAE,IAAA,EAAM,GAAA,EAAK,QAAQ,IAAA,EAAK;AAGpD,IAAA,MAAM,KAAA,GAAQ,OAAO,CAAA,EAAG,IAAI,GAAG,GAAG,CAAA,CAAA,EAAI,IAAI,CAAA,CAAE,CAAA;AAC5C,IAAA,OAAO,EAAE,OAAO,KAAA,EAAO,MAAA,CAAO,SAAS,KAAK,CAAA,GAAI,QAAQ,IAAA,EAAK;AAAA,EAC/D;AAAA,EAGA,eAAe,EAAA,EAAqB;AAClC,IAAA,OAAO,OAAO,IAAA,CAAK,QAAA,IAAa,EAAA,KAAO,GAAA,IAAO,KAAK,MAAA,KAAW,GAAA;AAAA,EAChE;AAAA,EAOA,OAAA,GAAgB;AACd,IAAA,IAAI,CAAC,KAAK,gBAAA,EAAkB;AAC5B,IAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,YAAA,CAAa,WAAA,EAAY,GACxC,IAAA,CAAK,UAAA,GACL,IAAA,CAAK,KAAA,CAAM,IAAA,CAAK,aAAA,CAAc,KAAK,CAAA,CAAE,KAAA;AACzC,IAAA,IAAA,CAAK,OAAO,KAAK,CAAA;AAAA,EACnB;AAAA,EAQA,WAAA,GAAoB;AAClB,IAAA,MAAM,QAAA,GAAW,aAAA,CAAc,IAAA,CAAK,OAAA,EAAS,KAAK,WAAW,CAAA;AAC7D,IAAA,MAAM,SAAS,aAAA,CAAc,IAAA,CAAK,YAAA,EAAc,QAAA,EAAU,EAAE,CAAA;AAC5D,IAAA,IAAA,CAAK,OAAA,GAAU,MAAA,KAAW,IAAA,GAAO,eAAA,GAAkB,QAAA;AAEnD,IAAA,IAAA,CAAK,aAAa,IAAA,CAAK,cAAA;AAEvB,IAAA,IAAA,CAAK,SAAA,GAAY,EAAA;AACjB,IAAA,IAAI,IAAA,CAAK,kBAAkB,EAAA,EAAI;AAC7B,MAAA,MAAM,gBAAA,GAAmB,aAAA,CAAc,IAAA,CAAK,YAAA,EAAc,KAAK,OAAA,EAAS;AAAA,QACtE,KAAA,EAAO,UAAA;AAAA,QACP,UAAU,IAAA,CAAK;AAAA,OAChB,CAAA;AAED,MAAA,IAAI,gBAAA,KAAqB,IAAA,EAAM,IAAA,CAAK,SAAA,GAAY,IAAA,CAAK,aAAA;AAAA,IACvD;AAEA,IAAA,IAAA,CAAK,SAAA,GAAY,aAAA;AAAA,MACf,IAAA,CAAK,YAAA;AAAA,MACL,IAAA,CAAK,OAAA;AAAA,MACL,EAAE,WAAA,EAAa,IAAA,EAAM,qBAAA,EAAuB,CAAA,EAAE;AAAA,MAC9C;AAAA,KACF;AACA,IAAA,IAAA,CAAK,MAAA,GAAS,aAAA;AAAA,MACZ,IAAA,CAAK,YAAA;AAAA,MACL,IAAA,CAAK,OAAA;AAAA,MACL;AAAA,QACE,WAAA,EAAa,IAAA;AAAA,QACb,uBAAuB,IAAA,CAAK,UAAA;AAAA,QAC5B,uBAAuB,IAAA,CAAK;AAAA,OAC9B;AAAA,MACA;AAAA,KACF;AACA,IAAA,IAAA,CAAK,WAAA,GAAc,KAAK,SAAA,GACpB,aAAA;AAAA,MACE,IAAA,CAAK,YAAA;AAAA,MACL,IAAA,CAAK,OAAA;AAAA,MACL,EAAE,KAAA,EAAO,UAAA,EAAY,QAAA,EAAU,KAAK,SAAA,EAAU;AAAA,MAC9C;AAAA,QAEF,IAAA,CAAK,MAAA;AAET,IAAA,MAAM,KAAA,GAAQ,cAAc,IAAA,CAAK,YAAA,EAAc,KAAK,OAAA,EAAS,EAAC,EAAG,eAAe,CAAA,CAAE,aAAA;AAAA,MAChF;AAAA,KACF;AACA,IAAA,IAAA,CAAK,MAAA,GAAS,MAAM,IAAA,CAAK,CAAC,MAAM,CAAA,CAAE,IAAA,KAAS,OAAO,CAAA,EAAG,KAAA,IAAS,GAAA;AAC9D,IAAA,IAAA,CAAK,QAAA,GAAW,MAAM,IAAA,CAAK,CAAC,MAAM,CAAA,CAAE,IAAA,KAAS,SAAS,CAAA,EAAG,KAAA,IAAS,GAAA;AAKlE,IAAA,IAAA,CAAK,QAAQ,KAAA,EAAM;AACnB,IAAA,MAAM,cAAA,GAAiB,aAAA;AAAA,MACrB,IAAA,CAAK,YAAA;AAAA,MACL,IAAA,CAAK,OAAA;AAAA,MACL,EAAE,aAAa,KAAA,EAAM;AAAA,MACrB;AAAA,KACF;AACA,IAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,IAAK,CAAA,EAAG,CAAA,EAAA,EAAK;AAC3B,MAAA,MAAM,KAAA,GAAQ,cAAA,CAAe,MAAA,CAAO,CAAC,CAAA;AACrC,MAAA,IAAI,KAAA,KAAU,MAAA,CAAO,CAAC,CAAA,EAAG,IAAA,CAAK,QAAQ,GAAA,CAAI,KAAA,EAAO,MAAA,CAAO,CAAC,CAAC,CAAA;AAAA,IAC5D;AAAA,EACF;AAAA,EAQA,WAAW,IAAA,EAAsB;AAC/B,IAAA,IAAI,GAAA,GAAM,EAAA;AACV,IAAA,KAAA,MAAW,MAAM,IAAA,EAAM;AACrB,MAAA,MAAM,MAAA,GAAS,IAAA,CAAK,OAAA,CAAQ,GAAA,CAAI,EAAE,CAAA;AAClC,MAAA,IAAI,WAAW,MAAA,EAAW;AACxB,QAAA,GAAA,IAAO,MAAA;AAAA,MACT,CAAA,MAAA,IAAW,OAAO,QAAA,EAAK;AACrB,QAAA,GAAA,IAAO,GAAA;AAAA,MACT,CAAA,MAAO;AACL,QAAA,GAAA,IAAO,cAAc,EAAE,CAAA;AAAA,MACzB;AAAA,IACF;AACA,IAAA,OAAO,GAAA;AAAA,EACT;AAAA,EAEA,IAAI,cAAA,GAAyB;AAC3B,IAAA,OAAO,KAAK,QAAA,CAAS,IAAA;AAAA,MACnB,IAAA;AAAA,MACA,WAAA;AAAA,MACA,IAAA,CAAK,cAAA;AAAA,MACL,wBAAA,CAAwB,OAAO,SAAA,CAAU,OAAA;AAAA,MACzC,yBAAwB,gBAAA,CAAiB;AAAA,KAC3C;AAAA,EACF;AACF;AAGA,SAAS,KAAA,CAAM,OAAe,SAAA,EAA2B;AACvD,EAAA,MAAM,MAAA,GAAS,EAAA,IAAM,IAAA,CAAK,GAAA,CAAI,GAAG,SAAS,CAAA;AAC1C,EAAA,MAAM,OAAA,GAAU,IAAA,CAAK,KAAA,CAAM,KAAA,GAAQ,MAAM,CAAA,GAAI,MAAA;AAC7C,EAAA,IAAI,CAAC,MAAA,CAAO,QAAA,CAAS,OAAO,GAAG,OAAO,KAAA;AACtC,EAAA,OAAO,OAAA,KAAY,IAAI,CAAA,GAAI,OAAA;AAC7B","file":"currency_input_controller.js","sourcesContent":["/** Minimal event shape carrying the platform's per-event composition signal. */\nexport interface CompositionSignal {\n readonly isComposing?: boolean;\n}\n\n/** Minimal `input` shape needed to tell a composition echo from a fresh edit. */\nexport interface ConfirmedInputSignal {\n readonly target: EventTarget | null;\n readonly inputType?: string;\n}\n\n/**\n * The `inputType` values an engine reports on an `input` that belongs to a\n * composition rather than to an edit the user just made.\n */\nconst COMPOSITION_INPUT_TYPES = new Set([\n \"insertCompositionText\",\n \"insertFromComposition\",\n \"deleteCompositionText\",\n \"deleteByComposition\",\n]);\n\n/** Hooks that keep component-specific work outside {@link CompositionTracker}. */\nexport interface CompositionTrackerOptions {\n /** Runs after lifecycle state is set for a `compositionstart` event. */\n readonly onStart?: (event: Event) => void;\n /** Runs after lifecycle state is cleared for a `compositionend` event. */\n readonly onEnd?: (event: Event) => void;\n}\n\n/**\n * Owns IME composition listeners and transient state for one or more event targets.\n *\n * Some browsers omit `KeyboardEvent.isComposing` on the keydown that confirms a\n * conversion. Tracking `compositionstart` through `compositionend` supplies the\n * missing lifecycle signal without relying on deprecated numeric key codes.\n * Component policy stays with the consumer: filtering, validation, and submission\n * belong in the optional {@link CompositionTrackerOptions.onEnd} callback.\n *\n * The tracker also owns the other half of that lifecycle: **the `input` some\n * engines send after `compositionend` to echo the text just confirmed.** A\n * consumer that ran `onEnd` and then handled the echo would commit the same\n * confirmation twice, so {@link CompositionTracker.consumesConfirmedInput} tells\n * the echo apart and the consumer returns early on it.\n *\n * **What the echo is not, is the harder half.** Not every engine sends one —\n * Chromium ends a confirmation at `compositionend` with no `input` after it — so\n * a window that waits for the echo and only closes on the next key would swallow\n * the first edit that arrives without one: dictation, autofill, a drop,\n * `insertText`. Two things keep that from happening. The window closes on the\n * next anything — a key, a new composition, any `input`, losing the field — and\n * an `input` that reports an `inputType` outside {@link COMPOSITION_INPUT_TYPES}\n * is an edit, so it is never folded. Only an engine that reports no `inputType`\n * at all is left relying on the window alone.\n *\n * @example\n * ```ts\n * #composition = new CompositionTracker({ onEnd: () => this.filter() });\n *\n * connect(): void {\n * this.#composition.observe(this.inputTarget);\n * }\n *\n * disconnect(): void {\n * this.#composition.disconnect();\n * }\n *\n * onInput(event: InputEvent): void {\n * if (this.#composition.consumesConfirmedInput(event)) return;\n * if (this.#composition.isComposing(event)) return;\n * }\n *\n * onKeydown(event: KeyboardEvent): void {\n * if (this.#composition.isComposing(event)) return;\n * }\n * ```\n */\nexport class CompositionTracker {\n readonly #observedTargets = new Set<EventTarget>();\n readonly #activeTargets = new Set<EventTarget>();\n readonly #onStart: ((event: Event) => void) | undefined;\n readonly #onEnd: ((event: Event) => void) | undefined;\n /** The field whose confirming `input` is still owed, while the window is open. */\n #confirmedTarget: EventTarget | null = null;\n\n constructor(options: CompositionTrackerOptions = {}) {\n this.#onStart = options.onStart;\n this.#onEnd = options.onEnd;\n }\n\n /** Starts lifecycle tracking for `target`; repeated calls are idempotent. */\n observe(target: EventTarget): void {\n if (this.#observedTargets.has(target)) return;\n target.addEventListener(\"compositionstart\", this.#handleStart);\n target.addEventListener(\"compositionend\", this.#handleEnd);\n target.addEventListener(\"keydown\", this.#handleKeydown);\n this.#observedTargets.add(target);\n }\n\n /** Stops tracking one target and clears any active composition it owned. */\n unobserve(target: EventTarget): void {\n if (!this.#observedTargets.delete(target)) return;\n target.removeEventListener(\"compositionstart\", this.#handleStart);\n target.removeEventListener(\"compositionend\", this.#handleEnd);\n target.removeEventListener(\"keydown\", this.#handleKeydown);\n this.#activeTargets.delete(target);\n if (this.#confirmedTarget === target) this.#confirmedTarget = null;\n }\n\n /** Releases every listener and clears state so reconnect starts cleanly. */\n disconnect(): void {\n for (const target of this.#observedTargets) {\n target.removeEventListener(\"compositionstart\", this.#handleStart);\n target.removeEventListener(\"compositionend\", this.#handleEnd);\n target.removeEventListener(\"keydown\", this.#handleKeydown);\n }\n this.#observedTargets.clear();\n this.#activeTargets.clear();\n this.#confirmedTarget = null;\n }\n\n /** True when lifecycle tracking or the current event reports composition. */\n isComposing(event?: CompositionSignal): boolean {\n return this.#activeTargets.size > 0 || event?.isComposing === true;\n }\n\n /**\n * Whether `event` is the `input` echoing the composition just confirmed.\n *\n * Asking closes the window either way, so one confirmation is folded at most\n * once and a consumer asks once per `input`.\n */\n consumesConfirmedInput(event: ConfirmedInputSignal): boolean {\n const confirmed = this.#confirmedTarget;\n this.#confirmedTarget = null;\n if (confirmed === null || confirmed !== event.target) return false;\n // An engine that reports no kind at all leaves `inputType` empty, and the\n // window is then the only signal there is.\n const inputType = event.inputType;\n return !inputType || COMPOSITION_INPUT_TYPES.has(inputType);\n }\n\n readonly #handleStart = (event: Event): void => {\n this.#confirmedTarget = null;\n if (event.currentTarget) this.#activeTargets.add(event.currentTarget);\n this.#onStart?.(event);\n };\n\n readonly #handleEnd = (event: Event): void => {\n if (event.currentTarget) this.#activeTargets.delete(event.currentTarget);\n this.#confirmedTarget = event.target;\n this.#onEnd?.(event);\n };\n\n /** A key on an observed field opens an edit of its own, so no echo is owed. */\n readonly #handleKeydown = (): void => {\n this.#confirmedTarget = null;\n };\n}\n","/** The distance between a full-width ASCII code point and its half-width twin. */\nconst FULL_WIDTH_SHIFT = 0xfee0;\n\n/**\n * The half-width form of `char`, or `char` itself when it has none.\n *\n * An IME confirming in full-width mode produces U+FF01–U+FF5E (and U+3000 for\n * the space) where the page means ASCII — the digits of a phone number, the\n * letters of a code, the separators between them. Reading those as their ASCII\n * equivalents keeps confirmed text usable instead of discarding it. Characters\n * outside that block, including kana and astral code points, are returned\n * unchanged, so this never rewrites text a consumer meant to keep as typed.\n */\nexport function halfWidthChar(char: string): string {\n if (char >= \"!\" && char <= \"~\") {\n return String.fromCharCode(char.charCodeAt(0) - FULL_WIDTH_SHIFT);\n }\n return char === \" \" ? \" \" : char;\n}\n\n/** Every full-width ASCII character in `text` rewritten by {@link halfWidthChar}. */\nexport function toHalfWidth(text: string): string {\n let out = \"\";\n for (const char of text) out += halfWidthChar(char);\n return out;\n}\n","/**\n * Construction of `Intl` formatters for the controllers that take a locale, and\n * the options that go with it, from a declaration.\n *\n * Every `Intl` constructor resolves locale data on the way in, which makes it\n * too costly to rebuild on a hot path, and rejects a malformed language tag,\n * currency code, time zone or digit count with a `RangeError`. Both concerns are\n * handled here once. A formatter is built at most once per distinct request and\n * shared by every caller that asks for the same one. A `RangeError` is caught\n * and answered the way the caller asked: by rebuilding under a fallback locale,\n * or by returning `null` so the caller can leave its authored text alone. Any\n * other failure is a programming fault and propagates.\n */\n\n/** The constructor shape the `Intl` formatter classes share. */\nexport interface IntlFormatterConstructor<F, O extends object> {\n new (locales?: string | string[], options?: O): F;\n}\n\n/** Built formatters, and refusals, per constructor; see `cacheKey` for the key. */\nconst formatters = new WeakMap<object, Map<string, unknown>>();\n\n/**\n * A formatter for `locale` with `options`.\n *\n * With `fallbackLocale`, a `RangeError` from the constructor is answered by\n * building the same options under the fallback instead, so the result is never\n * `null`; the fallback's own failure propagates. Without it, a `RangeError`\n * yields `null` and the caller decides what to show. Errors of any other kind\n * propagate in both forms.\n *\n * Results are cached per constructor and `(locale, options, fallback)`, `null`\n * included, so asking again on every render costs one map lookup.\n */\nexport function intlFormatter<F, O extends object>(\n factory: IntlFormatterConstructor<F, O>,\n locale: string | undefined,\n options: O,\n fallbackLocale: string,\n): F;\nexport function intlFormatter<F, O extends object>(\n factory: IntlFormatterConstructor<F, O>,\n locale: string | undefined,\n options: O,\n): F | null;\nexport function intlFormatter<F, O extends object>(\n factory: IntlFormatterConstructor<F, O>,\n locale: string | undefined,\n options: O,\n fallbackLocale?: string,\n): F | null {\n const cache = cacheFor(factory);\n const key = cacheKey(locale, options, fallbackLocale);\n if (cache.has(key)) return cache.get(key) as F | null;\n const formatter = construct(factory, locale, options, fallbackLocale);\n cache.set(key, formatter);\n return formatter;\n}\n\n/** The cache for one constructor, created on first use. */\nfunction cacheFor(factory: object): Map<string, unknown> {\n const existing = formatters.get(factory);\n if (existing) return existing;\n const created = new Map<string, unknown>();\n formatters.set(factory, created);\n return created;\n}\n\n/**\n * One key per distinct request. `JSON.stringify` drops an option left\n * `undefined`, which is how the constructor reads it too. Two spellings of the\n * same options differing only in key order key separately; that costs one extra\n * formatter, never a wrong one, and call sites pass a fixed literal anyway.\n */\nfunction cacheKey(\n locale: string | undefined,\n options: object,\n fallbackLocale: string | undefined,\n): string {\n return JSON.stringify([locale, options, fallbackLocale]);\n}\n\n/** Builds the formatter under the `RangeError` contract described on `intlFormatter`. */\nfunction construct<F, O extends object>(\n factory: IntlFormatterConstructor<F, O>,\n locale: string | undefined,\n options: O,\n fallbackLocale: string | undefined,\n): F | null {\n try {\n return new factory(locale, options);\n } catch (error) {\n if (!(error instanceof RangeError)) throw error;\n if (fallbackLocale === undefined) return null;\n return new factory(fallbackLocale, options);\n }\n}\n","/**\n * The locale a component formats in: its own declaration, else the language of\n * the text around it, else the runtime default.\n *\n * `lang` is inherited in HTML, so the language that applies to an element is the\n * nearest one on the element itself or on an ancestor — not the document\n * element's, which is only the farthest of them. An empty `lang` there means the\n * language is unknown and stops the inheritance at that point, so it resolves to\n * the runtime default rather than to a `lang` further up.\n *\n * Resolution only, and the value is passed through as authored. Whether `Intl`\n * accepts the tag, and what to show when it does not, is the caller's contract.\n *\n * @example\n * ```ts\n * intlFormatter(Intl.DateTimeFormat, resolveLocale(this.element, this.localeValue), options);\n * ```\n */\nexport function resolveLocale(element: Element, declared = \"\"): string | undefined {\n return declared || element.closest(\"[lang]\")?.getAttribute(\"lang\") || undefined;\n}\n","/**\n * Owns every listener a controller attaches for one connected lifetime and\n * releases them together, so an event name is spelled once and the release\n * cannot drift from the registration.\n *\n * Detaching by hand repeats three things at the release site — the type, the\n * handler reference and the capture flag — and any one of them drifting leaves\n * a listener alive on an element the controller no longer drives. Aborting the\n * signal a registration was created with releases it whatever it was made of,\n * so the release site names nothing.\n *\n * One set per lifetime, held as a field and never rebuilt. {@link\n * ListenerSet.dispose} is the only thing that closes a generation, and it opens\n * the next one in the same step, so the lifecycle hooks can call `add` and\n * `dispose` in any order any number of times, and no `add` ever meets an\n * already aborted signal — a DOM that registers a listener on such a signal\n * would keep it forever. Rebuilding the set instead would leak:\n * `addEventListener` matches an existing registration on target, type, callback\n * and capture alone, so re-adding the same handler while the first registration\n * is live is discarded, and that live registration keeps the signal it was\n * attached with — a set built by a second `connect()` can never release what it\n * appears to own.\n *\n * Scope is the registration only. Timers, observers, leases and the order they\n * are unwound in stay with the controller, which places `dispose()` in its\n * cleanup sequence. A receiver that changes at runtime (a\n * swapped target) is rebound by calling `dispose()` and then `add()` again from\n * the rebind, not by a second set.\n *\n * The set must own every registration of a tuple it holds: a listener the same\n * target already carries for the same type, callback and capture flag keeps the\n * right to remove it, and this set's `add` for that tuple is discarded. A\n * subscription shared between instances behind a participant count, or one that\n * lives for less than the connection, keeps its own pair of calls.\n *\n * @example\n * ```ts\n * readonly #listeners = new ListenerSet();\n *\n * connect(): void {\n * this.#listeners.add(this.element, \"submit\", this.#onNativeSubmit, { capture: true });\n * this.#listeners.add(this.element, \"turbo:submit-start\", this.#onSubmitStart);\n * this.#listeners.add(this.element, \"turbo:submit-end\", this.#onSubmitEnd);\n * }\n *\n * disconnect(): void {\n * this.#listeners.dispose();\n * }\n * ```\n */\nexport class ListenerSet {\n /** The generation every `add` joins until the next `dispose()`. */\n #abort = new AbortController();\n\n /**\n * Attaches `handler` to the open generation, exactly as the caller spelled it.\n *\n * The set supplies the signal, so `options` carries everything else the DOM\n * accepts — `capture` included, which has to match at release time and no\n * longer has a second place to drift from.\n */\n add(\n target: EventTarget,\n type: string,\n handler: EventListener,\n options?: Omit<AddEventListenerOptions, \"signal\">,\n ): void {\n target.addEventListener(type, handler, { ...options, signal: this.#abort.signal });\n }\n\n /**\n * Releases every listener of the open generation, synchronously, and opens the\n * next one. Idempotent, and safe before anything has been added.\n */\n dispose(): void {\n this.#abort.abort();\n this.#abort = new AbortController();\n }\n}\n","/**\n * Collapses many Stimulus lifecycle callbacks from one DOM mutation into a\n * single pass.\n *\n * Stimulus fires `<name>TargetConnected` / `Disconnected` once per element and\n * `<name>ValueChanged` once per changed attribute. Replacing a list of N options\n * or morphing several render Values therefore delivers N callbacks — but the\n * useful unit of work is \"reconcile against the resulting declarative input\",\n * once, after the batch has settled. Every controller with reconcilable targets\n * or render Values needs the same shape: a `queued` flag plus `queueMicrotask`.\n *\n * **A microtask is the right horizon, and the reason is specific.** Stimulus\n * drives these callbacks from a `MutationObserver`, whose own callback already\n * runs as a microtask with the whole batch in hand; scheduling one more lands\n * after the last sibling callback of that batch and still before paint or any\n * event handler. A timer would be later than it needs to be, and reconciling\n * synchronously would run once per element against a half-applied DOM.\n *\n * **The two guards are not the same guard.** Scheduling is refused before the\n * controller connects, and running is refused after it disconnects:\n *\n * - **Before `connect()`** — Stimulus delivers initial target and Value callbacks\n * ahead of `connect()`. Reconciling there would compute output against a\n * controller whose own state has not been initialised, and `connect()` is\n * about to do a full pass anyway.\n * - **After `disconnect()`** — Stimulus fires a callback for **every** target\n * during teardown, and a microtask queued just before it would otherwise run\n * against a detached tree. {@link MicrotaskCoalescer.cancel} exists for the\n * teardown path to drop the pending pass outright.\n *\n * Both guards are part of one contract here rather than something each consumer\n * has to remember separately.\n *\n * Scope is the scheduling only. *What* to reconcile — keep the surviving active\n * option, fall back to the next / previous / first visible one, rebuild derived\n * chips or hidden fields — stays in the controller, because no two consumers\n * answer it the same way.\n *\n * @example\n * ```ts\n * readonly #reconcile = new MicrotaskCoalescer(() => this.#reconcileOptions());\n *\n * connect() { this.#reconcile.activate(); }\n * disconnect() { this.#reconcile.cancel(); }\n *\n * optionTargetConnected() { this.#reconcile.schedule(); }\n * optionTargetDisconnected() { this.#reconcile.schedule(); }\n * ```\n */\nexport class MicrotaskCoalescer {\n readonly #run: () => void;\n #queued = false;\n #active = false;\n #generation = 0;\n\n /** @param run - the single reconciliation pass, invoked at most once per batch. */\n constructor(run: () => void) {\n this.#run = run;\n }\n\n /** Opens the window in which {@link schedule} is honoured; call from `connect()`. */\n activate(): void {\n this.#active = true;\n }\n\n /** Closes the window and drops any pending pass; call from `disconnect()`. */\n cancel(): void {\n this.#active = false;\n this.#queued = false;\n this.#generation += 1;\n }\n\n /** Requests one pass after the batch settles. Idempotent; inert outside the window. */\n schedule(): void {\n if (!this.#active || this.#queued) return;\n this.#queued = true;\n const generation = this.#generation;\n queueMicrotask(() => {\n // A cancelled callback must not consume a pass queued after reconnect.\n if (generation !== this.#generation || !this.#queued || !this.#active) return;\n this.#queued = false;\n this.#run();\n });\n }\n}\n","import { ListenerSet } from \"./listener_set\";\nimport { MicrotaskCoalescer } from \"./microtask_coalescer\";\n\n/**\n * Coalesces retained-element morphs and explicit lifecycle requests into one pass.\n *\n * Observe the controller's element after its initial state is settled. Morphs on\n * that element and bubbling morphs on its descendants share the same microtask\n * as {@link schedule}. The callback repairs derived output; the controller owns\n * any logical transition reporting. {@link disconnect} releases the listener and\n * cancels pending work, including work from an earlier connected lifetime.\n */\nexport class MorphRenderWatcher {\n readonly #listeners = new ListenerSet();\n readonly #pass: MicrotaskCoalescer;\n #element: Element | null = null;\n readonly #onMorph = (): void => this.#pass.schedule();\n\n /** @param run - the single pass that repairs the settled controller's output. */\n constructor(run: () => void) {\n this.#pass = new MicrotaskCoalescer(run);\n }\n\n /** Opens observation; observing the same element again preserves queued work. */\n observe(element: Element): void {\n if (this.#element === element) return;\n this.disconnect();\n this.#element = element;\n this.#pass.activate();\n this.#listeners.add(element, \"turbo:morph-element\", this.#onMorph);\n }\n\n /** Requests one pass; requests outside an observed lifetime are ignored. */\n schedule(): void {\n this.#pass.schedule();\n }\n\n /** Releases observation and pending work synchronously; safe to repeat. */\n disconnect(): void {\n this.#listeners.dispose();\n this.#pass.cancel();\n this.#element = null;\n }\n}\n","import { MAX_TIMER_DELAY_MS } from \"./timer_bounds\";\n\n/** Semantic constraints on an already decoded number, independent of the DOM. */\nexport interface NumberBounds {\n /** Finite numbers are required, including when this field is omitted. */\n readonly finite?: true;\n /** Inclusive lower endpoint. */\n readonly min?: number;\n /** Inclusive upper endpoint. */\n readonly max?: number;\n /** Exclusive lower endpoint. */\n readonly exclusiveMin?: number;\n /** Require a number without a fractional part. */\n readonly integer?: boolean;\n /** Exact decoded numbers accepted by a discrete contract. */\n readonly allowedValues?: readonly number[];\n /** JSON-safe exceptions to finite-number checking for unbounded endpoints. */\n readonly allowInfinity?: \"negative\" | \"positive\" | \"both\";\n}\n\n/** One constraint for each Number Value, including shorthand declarations. */\nexport type NumberValueConstraints<Values> = {\n readonly [Key in keyof Values as Values[Key] extends\n | NumberConstructor\n | { type: NumberConstructor }\n ? Key\n : never]: NumberBounds;\n};\n\n/** Reusable semantic domains; fractional inputs remain fractional unless excluded. */\nexport const NUMBER_BOUNDS = {\n finite: { finite: true },\n nonNegative: { finite: true, min: 0 },\n positive: { finite: true, exclusiveMin: 0 },\n nonNegativeInteger: { finite: true, min: 0, integer: true },\n positiveInteger: { finite: true, exclusiveMin: 0, integer: true },\n lowerBound: { finite: true, allowInfinity: \"negative\" },\n upperBound: { finite: true, allowInfinity: \"positive\" },\n timer: { finite: true, min: 0, max: MAX_TIMER_DELAY_MS },\n positiveTimer: { finite: true, exclusiveMin: 0, max: MAX_TIMER_DELAY_MS },\n} as const satisfies Record<string, NumberBounds>;\n\n/**\n * Checks all declared bounds without rounding, clamping, or coercing the input.\n * Infinity exceptions relax only finite checking; every other bound still applies.\n */\nexport function matchesNumberBounds(value: number, bounds: NumberBounds): boolean {\n if (!Number.isFinite(value)) {\n const direction = value === Infinity ? \"positive\" : value === -Infinity ? \"negative\" : null;\n if (direction === null) return false;\n if (bounds.allowInfinity !== \"both\" && bounds.allowInfinity !== direction) return false;\n }\n if (bounds.min !== undefined && value < bounds.min) return false;\n if (bounds.max !== undefined && value > bounds.max) return false;\n if (bounds.exclusiveMin !== undefined && value <= bounds.exclusiveMin) return false;\n if (bounds.integer && !Number.isInteger(value)) return false;\n if (bounds.allowedValues !== undefined && !bounds.allowedValues.includes(value)) return false;\n return true;\n}\n\n/** Decodes a Number Value literal; action params use their own JSON decoder. */\nexport function decodeNumberValue(raw: string): number {\n return Number(raw.replace(/_/g, \"\"));\n}\n","/**\n * Numeric coercion for controllers that accept a number through a Value, an action\n * param, or an event detail.\n *\n * Stimulus decodes action params as JSON when possible and leaves other text\n * untouched. CustomEvent detail can also supply a number or numeric string.\n * The reader accepts those two types while rejecting blank and non-finite input.\n */\n\nimport { matchesNumberBounds, type NumberBounds } from \"./number_bounds\";\n\n/**\n * Reads a finite number or nonblank numeric string; other input returns `null`.\n * Blank strings cannot silently reset a value to zero.\n */\nexport function toFiniteNumber(raw: unknown): number | null {\n if (typeof raw !== \"number\" && typeof raw !== \"string\") return null;\n if (typeof raw === \"string\" && raw.trim().length === 0) return null;\n const value = Number(raw);\n return Number.isFinite(value) ? value : null;\n}\n\n/**\n * Returns an accepted decoded Number Value or the caller's fallback unchanged.\n * The caller owns the fallback contract; this reader does not parse or write a Value.\n */\nexport function readNumber(raw: number, fallback: number, bounds: NumberBounds): number {\n return matchesNumberBounds(raw, bounds) ? raw : fallback;\n}\n","import { readNumber } from \"./coerce\";\nimport { matchesNumberBounds, type NumberBounds } from \"./number_bounds\";\n\n/** The instance identity carried by a Number Value read. */\nexport interface NumberValueOwner {\n readonly identifier: string;\n readonly element: Element;\n}\n\n/** Reads current declarations at the point of use without rewriting their attributes. */\nexport class NumberValueReader {\n /** The last rejected literal per Value; no history grows for an unchanged instance. */\n readonly #lastRejected = new Map<string, string>();\n\n /** Resolves the declared number using its own fallback and shared class contract. */\n read(\n owner: NumberValueOwner,\n name: string,\n raw: number,\n fallback: number,\n bounds: NumberBounds,\n ): number {\n const resolved = readNumber(raw, fallback, bounds);\n if (matchesNumberBounds(raw, bounds)) {\n this.#lastRejected.delete(name);\n return resolved;\n }\n const attribute = `data-${owner.identifier}-${name.replace(/[A-Z]/g, (letter) => `-${letter.toLowerCase()}`)}-value`;\n const literal = owner.element.getAttribute(attribute);\n if (literal === null) {\n this.#lastRejected.delete(name);\n return resolved;\n }\n if (this.#lastRejected.get(name) !== literal) {\n this.#lastRejected.set(name, literal);\n console.warn(\n `Stimeo UI: \"${owner.identifier}\" has an invalid number Value \"${name}\" declaration ${JSON.stringify(literal)}; using ${fallback}.`,\n );\n }\n return resolved;\n }\n}\n","import { Controller } from \"@hotwired/stimulus\";\nimport { CompositionTracker } from \"../utils/composition_tracker\";\nimport { halfWidthChar } from \"../utils/half_width\";\nimport { intlFormatter } from \"../utils/intl_format\";\nimport { resolveLocale } from \"../utils/locale\";\nimport { MorphRenderWatcher } from \"../utils/morph_render_watcher\";\nimport type { NumberValueConstraints } from \"../utils/number_bounds\";\nimport { NumberValueReader } from \"../utils/number_value\";\n\n/** The number-shaped pieces of an in-progress entry, in typing order. */\ninterface EntryParts {\n /** The leading sign exactly as typed (`\"\"` when none). */\n sign: \"\" | \"-\" | \"+\";\n /** Integer digits with grouping stripped (may be empty mid-entry). */\n int: string;\n /** Whether a decimal mark was typed. */\n hasDot: boolean;\n /** Fraction digits exactly as typed; rounding happens only on blur. */\n frac: string;\n}\n\n/** One scan of the display text: its structure and the numeric value it holds. */\ninterface Scan {\n parts: EntryParts;\n /** The finite value, or `null` while no digit has been typed yet. */\n value: number | null;\n}\n\n/** Who moved the value: the user editing the display, or the page. */\ntype Cause = \"edit\" | \"reconcile\";\n\n/**\n * The locale a declaration falls back to when `Intl` rejects it, so a broken tag\n * still leaves a field that formats and parses the same way every time.\n */\nconst FALLBACK_LOCALE = \"en-US\";\n\n/**\n * Headless currency / amount input behavior: groups digits for display while\n * keeping a machine-readable number in a hidden field, and mirrors the\n * normalized value to a visually-hidden span so assistive tech reads the real\n * amount rather than the grouped display string.\n *\n * Markup contract (identifier: `stimeo--currency-input`):\n * <div data-controller=\"stimeo--currency-input\"\n * data-stimeo--currency-input-locale-value=\"en-US\"\n * data-stimeo--currency-input-currency-value=\"USD\"\n * data-stimeo--currency-input-precision-value=\"2\">\n * <input type=\"text\" inputmode=\"decimal\"\n * aria-describedby=\"amt-sr\"\n * data-stimeo--currency-input-target=\"display\"\n * data-action=\"input->stimeo--currency-input#onInput\n * blur->stimeo--currency-input#format\" />\n * <span id=\"amt-sr\" class=\"visually-hidden\"\n * data-stimeo--currency-input-target=\"srValue\"></span>\n * <input type=\"hidden\" data-stimeo--currency-input-target=\"field\" />\n * </div>\n *\n * `change` and `reconcile` dispatch `{ value: number | null, formatted: string }`\n * — `null` (with an empty `formatted`) when the amount is cleared, so consumers\n * hear every transition of the numeric value, including back to empty. `change`\n * is the user's edit: typing, or the rounding applied on `blur`. `reconcile` is a\n * value the page moved: a `locale`, `currency` or `precision` change that\n * re-rounds the committed amount, a display target swapped in holding another\n * amount, a reconnect that rounds an entry left unrounded mid-typing, or a move\n * that ends a composition before its `compositionend`. Connecting over a\n * server-rendered value reports neither.\n *\n * @remarks\n * Behavior only — no styling, no validation (range/required belong to the\n * consumer or `stimeo--form-field`). The display field is the sole Tab stop and keeps its\n * native text-editing behavior; this controller never steals focus.\n *\n * While typing, the entry is preserved as typed: grouping is applied to the\n * integer digits per locale, a leading sign and a trailing decimal mark stay in\n * place, fraction digits are kept verbatim, and the caret is restored after the\n * same significant character it followed. Negative amounts are in scope. The\n * fixed-precision rounding is applied on `blur`, never mid-entry.\n * Full-width digits, signs, and marks (an IME confirming 0-9/./-) are\n * normalized to their ASCII forms rather than stripped; the locale's own\n * digits (a non-Latin default numbering system such as ar-EG's) are mapped\n * back the same way; and U+2212 MINUS SIGN is read as a sign. An ASCII \".\"\n * only counts as a decimal mark in locales where it is not the grouping\n * separator. Together these keep the controller's own output re-parseable to\n * the same value in every locale. Events fired mid-IME-composition are\n * ignored; the confirmed text is formatted once on `compositionend`. A\n * `locale` / `currency` / `precision` change that arrives mid-composition\n * leaves the uncommitted text alone and applies right after that confirmed\n * text has been read. A composition this controller stops hearing — its display\n * leaves, or the controller disconnects, before `compositionend` — ends there:\n * a display still in place is read as `compositionend` would read it, and a\n * value that moves is reported as `reconcile`. A field or screen-reader span\n * arriving mid-composition takes the committed value.\n *\n * Display text is read with the declarations it was written for. This\n * controller's own rendering was written with the separators in force, so a\n * declaration change reads it before they change. Any other text is the page's\n * — a display swapped in, or text written into the display alongside a\n * declaration change — written for the declarations the page carries, so it is\n * read with those.\n *\n * With no `locale` declared the field formats in the nearest `lang` up the\n * ancestor chain, else in the runtime default. A malformed `locale` falls back\n * to `en-US`, and a malformed `currency` or `precision` to that Value's default,\n * instead of throwing. The declarations, the nearest `lang` among them, are\n * read and validated before a display is read after they may have moved — on a\n * Value change, when the controller connects, and when a display arrives; the\n * hot path only ever sees validated values through cached `Intl.NumberFormat`\n * instances, never built per keystroke. Late-arriving or swapped `field` /\n * `srValue` / `display` targets are re-synced on connection; one that arrives\n * behind the target in charge is re-synced when that target leaves.\n *\n * Reconnecting starts from the committed value: a display still showing this\n * controller's own rendering is not read back but re-rendered from that value\n * under the current declarations, so a `locale` changed while the element was\n * away never re-reads its separators. The re-render is the fixed-precision\n * form, so it rounds whenever the value has more places than the current\n * `precision` allows — because `precision` changed while the element was away,\n * or because the entry was left unrounded mid-typing (`1.555` becomes `1.56`) —\n * and a value it moves is reported as `reconcile`. The composition listeners\n * are released on `disconnect()`.\n *\n * Honest a11y note: a hidden `<input>` is not exposed to assistive tech, so the\n * normalized value is *also* published as text in the `srValue` span referenced\n * by the display's `aria-describedby` — that, not the hidden field, is what a\n * screen reader announces.\n */\nexport class CurrencyInputController extends Controller<HTMLElement> {\n /** Numeric read boundaries share one reader for this controller instance. */\n readonly #numbers = new NumberValueReader();\n\n static override targets = [\"display\", \"field\", \"srValue\"];\n static override values = {\n locale: { type: String, default: \"\" },\n currency: { type: String, default: \"\" },\n precision: { type: Number, default: 2 },\n };\n\n static valueConstraints = {\n precision: { finite: true, integer: true, min: 0, max: 100 },\n } satisfies NumberValueConstraints<typeof CurrencyInputController.values>;\n static actions = [\"format\", \"onInput\"] as const;\n static events = [\"change\", \"reconcile\"] as const;\n\n declare readonly displayTarget: HTMLInputElement;\n declare readonly fieldTarget: HTMLInputElement;\n declare readonly srValueTarget: HTMLElement;\n declare readonly hasDisplayTarget: boolean;\n declare readonly hasFieldTarget: boolean;\n declare readonly hasSrValueTarget: boolean;\n declare localeValue: string;\n declare currencyValue: string;\n declare precisionValue: number;\n\n /** The numeric value last committed; both events report only a move away from it. */\n #lastValue: number | null = null;\n #started = false;\n /** A declaration change that arrived mid-composition, applied once nothing composes. */\n #changeHeld = false;\n /** The display a composition is running on, until that composition ends. */\n #composing: EventTarget | null = null;\n /**\n * The display text this controller last rendered. It tells this controller's own\n * text, written with the separators in force, from text the page wrote.\n */\n #rendered: string | null = null;\n\n /** Validated mirrors of the Values; the hot path never reads a raw Value. */\n #locale: string | undefined;\n #currency = \"\";\n #precision = 2;\n\n /** Formatters rebuilt when the declarations are taken in, never per keystroke. */\n #grouping!: Intl.NumberFormat;\n #fixed!: Intl.NumberFormat;\n #accessible!: Intl.NumberFormat;\n #group = \",\";\n #decimal = \".\";\n /** The locale's non-Latin digits mapped back to ASCII (empty for Latin locales). */\n readonly #digits = new Map<string, string>();\n\n /**\n * Holds mid-composition input so the IME's uncommitted text is never rewritten.\n * The confirmed text is formatted once, and a declaration change the composition\n * held back is applied after it.\n */\n readonly #composition = new CompositionTracker({\n onStart: (event) => {\n this.#composing = event.currentTarget;\n },\n onEnd: () => {\n this.#composing = null;\n this.#reformat(false, \"edit\");\n this.#applyHeldChange();\n },\n });\n\n /**\n * Re-validates on declaration changes and re-renders the committed display,\n * reporting a value the re-render moved as `reconcile`.\n */\n localeValueChanged(): void {\n this.#applyValueChange();\n }\n\n currencyValueChanged(): void {\n this.#applyValueChange();\n }\n\n precisionValueChanged(): void {\n this.#applyValueChange();\n }\n\n /**\n * Reads the display with the declarations its text was written for, then\n * re-renders it under the new ones — so a locale switch re-interprets the\n * value, never the old text with new separators, and text the page wrote for\n * the declarations it changes is never read with the old ones.\n *\n * While the display is composing, its text is the IME's: the change is held,\n * configuration and all, until the composition ends, so the confirmed text is\n * read with the separators it was typed against before the change applies.\n *\n * @stimeoRenderRoot\n */\n #applyValueChange(): void {\n if (this.#composition.isComposing()) {\n this.#changeHeld = true;\n return;\n }\n // With nothing to read, the next display or the next connect takes the\n // declarations in before reading.\n if (!this.#started || !this.hasDisplayTarget) return;\n const scan = this.#readDisplay();\n if (document.activeElement === this.displayTarget) {\n const formatted = this.#render(scan.parts);\n this.#show(formatted);\n this.#reflect(scan.value, formatted, \"reconcile\");\n } else {\n this.#renderFixed(scan.value, \"reconcile\");\n }\n }\n\n /** Applies a declaration change a composition held back. */\n #applyHeldChange(): void {\n if (!this.#changeHeld) return;\n this.#changeHeld = false;\n this.#applyValueChange();\n }\n\n /**\n * Reads the display and takes in the declarations the page carries now. This\n * controller's own rendering was written with the separators in force, so it\n * is read before they change; any other text is the page's, written for the\n * declarations it carries, so it is read after.\n */\n #readDisplay(): Scan {\n const text = this.displayTarget.value;\n const own = text === this.#rendered ? this.#scan(text) : null;\n this.#takeInDeclarations();\n return own ?? this.#scan(text);\n }\n\n /** Takes in the declarations the page carries now, a change a composition held among them. */\n #takeInDeclarations(): void {\n this.#changeHeld = false;\n this.#revalidate();\n }\n\n readonly #morph = new MorphRenderWatcher(() => this.#applyValueChange());\n\n /**\n * Takes in the declarations the page carries now and normalizes the display\n * to its fixed-precision form.\n *\n * A display still showing this controller's own last rendering is not read\n * back: its separators may belong to declarations that changed while the\n * controller was away, and the committed value is known anyway. That value is\n * re-rendered at the current fixed precision, which rounds it whether\n * `precision` changed meanwhile or the entry was left unrounded mid-typing, and\n * a move the rounding causes is reported as `reconcile`. Any other text is the\n * page's, written for the declarations it carries, so it is read with them.\n */\n override connect(): void {\n this.#morph.observe(this.element);\n this.#started = true;\n this.#takeInDeclarations();\n if (!this.hasDisplayTarget) return;\n if (this.displayTarget.value === this.#rendered) {\n this.#renderFixed(this.#lastValue, \"reconcile\");\n return;\n }\n // Seed the baseline with the *rounded* initial value: the idempotent\n // connect-time reformat describes the value the page rendered, so it\n // reports nothing.\n const { value } = this.#scan(this.displayTarget.value);\n this.#lastValue = value === null ? null : round(value, this.#precision);\n this.#renderFixed(value, \"reconcile\");\n }\n\n /**\n * Releases the composition listeners. A composition still running hears no\n * `compositionend` once they are gone, so it ends here; a change it held is\n * taken in on the next `connect()`.\n */\n override disconnect(): void {\n this.#morph.disconnect();\n this.#endUntrackedComposition();\n this.#composition.disconnect();\n this.#started = false;\n }\n\n /**\n * Tracks composition on an arriving (or swapped-in) display and normalizes it\n * under the declarations the page carries now, reading this controller's own\n * rendering with the separators it was written under; an amount that differs\n * from the committed one is the page's, so it is reported as `reconcile`.\n * A display that arrives behind the one in charge is only tracked: the one\n * ahead may be composing against the declarations in force, and the arrival\n * is read when that one leaves.\n */\n displayTargetConnected(target: HTMLInputElement): void {\n this.#composition.observe(target);\n if (!this.#started || !this.hasDisplayTarget || this.displayTarget !== target) return;\n this.#renderFixed(this.#readDisplay().value, \"reconcile\");\n }\n\n /**\n * Stops tracking a display that leaves. A composition running on it hears no\n * `compositionend` any more, so it ends here; a change it held waits for the\n * next display to be read. A composition running on another display still hears\n * its own `compositionend`, so its text is left to it. A display that stays is\n * read again as a declaration change reads it, so an amount it holds that\n * differs from the committed one is the page's and is reported as `reconcile`.\n */\n displayTargetDisconnected(target: HTMLInputElement): void {\n this.#composition.unobserve(target);\n if (target === this.#composing) this.#endUntrackedComposition();\n this.#applyValueChange();\n }\n\n /**\n * Ends a composition no `compositionend` will reach. A display still in place —\n * one a move re-inserted, or the display of a controller that moves — holds the\n * text the composition left, typed against the declarations in force, so it is\n * read as `compositionend` would read it and becomes this controller's own\n * rendering. The page's move ended the composition, so a value it moves is\n * reported as `reconcile`. A display that left takes its composition along.\n */\n #endUntrackedComposition(): void {\n const display = this.#composing;\n this.#composing = null;\n if (this.hasDisplayTarget && this.displayTarget === display) {\n this.#reformat(false, \"reconcile\");\n }\n }\n\n /** Syncs a late-arriving hidden field without touching the display or events. */\n fieldTargetConnected(): void {\n if (this.#started) this.#resync();\n }\n\n /** Syncs the hidden field that stays when an earlier one leaves, silently. */\n fieldTargetDisconnected(): void {\n if (this.#started) this.#resync();\n }\n\n /** Syncs a late-arriving screen-reader span the same way. */\n srValueTargetConnected(): void {\n if (this.#started) this.#resync();\n }\n\n /** Syncs the screen-reader span that stays when an earlier one leaves, silently. */\n srValueTargetDisconnected(): void {\n if (this.#started) this.#resync();\n }\n\n /** Re-groups digits as the user types, preserving the caret position. */\n onInput(event: Event): void {\n if (this.#composition.isComposing(event as InputEvent)) return;\n this.#reformat(false, \"edit\");\n }\n\n /** Applies the fixed-precision rounding on blur. */\n format(): void {\n this.#reformat(true, \"edit\");\n }\n\n /**\n * Parses the display value, rewrites it grouped (optionally at fixed\n * precision), keeps the caret stable by significant characters, and syncs the\n * field, the screen-reader span, and the event `cause` selects.\n */\n #reformat(fixedPrecision: boolean, cause: Cause): void {\n if (!this.hasDisplayTarget) return;\n const raw = this.displayTarget.value;\n const { parts, value } = this.#scan(raw);\n\n if (fixedPrecision) {\n // Blur with no digits (an abandoned sign or dot) clears the entry.\n this.#renderFixed(value, cause);\n return;\n }\n\n const formatted = this.#render(parts);\n if (formatted !== raw) {\n const caret = this.displayTarget.selectionStart;\n const anchor = caret === null ? null : this.#significantBefore(raw, caret);\n this.displayTarget.value = formatted;\n if (anchor !== null) this.#restoreCaret(formatted, anchor);\n }\n this.#rendered = formatted;\n this.#reflect(value, formatted, cause);\n }\n\n /**\n * Shows `value` at the fixed precision — an empty display for no value — and\n * reports a move under the event `cause` selects.\n */\n #renderFixed(value: number | null, cause: Cause): void {\n if (value === null) {\n this.#show(\"\");\n this.#reflect(null, \"\", cause);\n return;\n }\n const rounded = round(value, this.#precision);\n const formatted = this.#fixed.format(rounded);\n this.#show(formatted);\n this.#reflect(rounded, formatted, cause);\n }\n\n /** Writes `text` to the display as this controller's own rendering. */\n #show(text: string): void {\n if (this.displayTarget.value !== text) this.displayTarget.value = text;\n this.#rendered = text;\n }\n\n /**\n * The in-progress rendering: grouped integer, sign and fraction as typed.\n */\n #render(parts: EntryParts): string {\n const int = parts.int === \"\" ? \"\" : this.#grouping.format(BigInt(parts.int));\n const frac = parts.hasDot ? this.#decimal + parts.frac : \"\";\n return parts.sign + int + frac;\n }\n\n /** Restores the caret to sit just after the n-th significant character. */\n #restoreCaret(formatted: string, significantBefore: number): void {\n let seen = 0;\n let position = formatted.length;\n for (let i = 0; i < formatted.length; i++) {\n if (seen >= significantBefore) {\n position = i;\n break;\n }\n if (this.#isSignificant(formatted[i] as string)) seen += 1;\n }\n try {\n this.displayTarget.setSelectionRange(position, position);\n } catch {\n // Some hosts disallow selection on certain input states; the value is\n // already correct, so a failed caret restore is non-fatal.\n }\n }\n\n /**\n * Counts the characters before `caret` that survive into the rendering,\n * applying the same acceptance rules as {@link #scan} — a rejected keystroke\n * (a mid-string sign, a second decimal mark) must not shift the anchor.\n */\n #significantBefore(text: string, caret: number): number {\n let count = 0;\n let sawSign = false;\n let sawDigit = false;\n let sawDot = false;\n for (const ch of this.#normalize(text.slice(0, caret))) {\n if (ch >= \"0\" && ch <= \"9\") {\n count += 1;\n sawDigit = true;\n } else if ((ch === \"-\" || ch === \"+\") && !sawSign && !sawDigit && !sawDot) {\n count += 1;\n sawSign = true;\n } else if (this.#isDecimalMark(ch) && !sawDot) {\n count += 1;\n sawDot = true;\n }\n }\n return count;\n }\n\n /** Digits, signs, and the decimal mark anchor the caret; grouping does not. */\n #isSignificant(ch: string): boolean {\n if (ch >= \"0\" && ch <= \"9\") return true;\n if (ch === \"-\" || ch === \"+\") return true;\n return ch === this.#decimal || (ch === \".\" && this.#group !== \".\");\n }\n\n /** Writes the normalized value to the field, the SR span, and the empty hook. */\n #write(value: number | null): void {\n const isEmpty = value === null;\n if (this.hasFieldTarget) this.fieldTarget.value = isEmpty ? \"\" : String(value);\n if (this.hasSrValueTarget) {\n this.srValueTarget.textContent = isEmpty ? \"\" : this.#accessible.format(value);\n }\n this.element.toggleAttribute(`data-${this.identifier}-empty`, isEmpty);\n }\n\n /**\n * {@link #write}, then reports a moved value under the event `cause` selects:\n * `change` for the user's edit, `reconcile` for a move the page caused. The\n * display may hold an in-progress `-`, but a `null` value always rides with an\n * empty `formatted`, whichever event reports it, so consumers can treat the\n * pair as cleared.\n */\n #reflect(value: number | null, formatted: string, cause: Cause): void {\n this.#write(value);\n if (value === this.#lastValue) return;\n this.#lastValue = value;\n const detail = { value, formatted: value === null ? \"\" : formatted };\n if (cause === \"edit\") this.dispatch(\"change\", { detail });\n else this.dispatch(\"reconcile\", { detail });\n }\n\n /**\n * Scans arbitrary input text into its number-shaped parts and value. Keeps\n * digits, one leading sign, one decimal mark, and the fraction verbatim;\n * everything else (grouping, symbols, words) is dropped. An ASCII \".\" is only\n * a decimal mark where it is not the locale's grouping separator. Precision\n * plays no part here — rounding belongs to the blur-time format.\n */\n #scan(text: string): Scan {\n let sign: EntryParts[\"sign\"] = \"\";\n let int = \"\";\n let hasDot = false;\n let frac = \"\";\n for (const ch of this.#normalize(text)) {\n if (ch >= \"0\" && ch <= \"9\") {\n if (hasDot) frac += ch;\n else int += ch;\n } else if ((ch === \"-\" || ch === \"+\") && sign === \"\" && int === \"\" && !hasDot) {\n sign = ch;\n } else if (this.#isDecimalMark(ch) && !hasDot) {\n hasDot = true;\n }\n }\n const parts: EntryParts = { sign, int, hasDot, frac };\n // `Number` accepts \"12.\" and \".5\" alike, so one dotted form covers every\n // shape — and a digit-less entry (\"\", \"-\", \".\") reads as NaN, hence null.\n const value = Number(`${sign}${int}.${frac}`);\n return { parts, value: Number.isFinite(value) ? value : null };\n }\n\n /** Whether `ch` reads as this locale's decimal mark. */\n #isDecimalMark(ch: string): boolean {\n return ch === this.#decimal || (ch === \".\" && this.#group !== \".\");\n }\n\n /**\n * Re-syncs field / srValue / hook without dispatching: from the display, or —\n * while it is composing, when its text is not committed yet — from the value\n * last committed.\n */\n #resync(): void {\n if (!this.hasDisplayTarget) return;\n const value = this.#composition.isComposing()\n ? this.#lastValue\n : this.#scan(this.displayTarget.value).value;\n this.#write(value);\n }\n\n /**\n * Validates the declared Values, falling back to each Value's default when a\n * declaration cannot be interpreted (a malformed locale or currency tag, a\n * precision outside `Intl`'s 0–100 integer range), and rebuilds the cached\n * formatters from the validated set.\n */\n #revalidate(): void {\n const resolved = resolveLocale(this.element, this.localeValue);\n const usable = intlFormatter(Intl.NumberFormat, resolved, {});\n this.#locale = usable === null ? FALLBACK_LOCALE : resolved;\n\n this.#precision = this.#safePrecision;\n\n this.#currency = \"\";\n if (this.currencyValue !== \"\") {\n const declaredCurrency = intlFormatter(Intl.NumberFormat, this.#locale, {\n style: \"currency\",\n currency: this.currencyValue,\n });\n // An unknown code falls through to the plain-number accessible text.\n if (declaredCurrency !== null) this.#currency = this.currencyValue;\n }\n\n this.#grouping = intlFormatter(\n Intl.NumberFormat,\n this.#locale,\n { useGrouping: true, maximumFractionDigits: 0 },\n FALLBACK_LOCALE,\n );\n this.#fixed = intlFormatter(\n Intl.NumberFormat,\n this.#locale,\n {\n useGrouping: true,\n minimumFractionDigits: this.#precision,\n maximumFractionDigits: this.#precision,\n },\n FALLBACK_LOCALE,\n );\n this.#accessible = this.#currency\n ? intlFormatter(\n Intl.NumberFormat,\n this.#locale,\n { style: \"currency\", currency: this.#currency },\n FALLBACK_LOCALE,\n )\n : this.#fixed;\n\n const parts = intlFormatter(Intl.NumberFormat, this.#locale, {}, FALLBACK_LOCALE).formatToParts(\n 11111.1,\n );\n this.#group = parts.find((p) => p.type === \"group\")?.value ?? \",\";\n this.#decimal = parts.find((p) => p.type === \"decimal\")?.value ?? \".\";\n\n // Locales whose default numbering system is not Latin (ar-EG, fa-IR, …)\n // format with their own digits; mapping them back keeps the controller's\n // own output re-parseable to the same value.\n this.#digits.clear();\n const digitFormatter = intlFormatter(\n Intl.NumberFormat,\n this.#locale,\n { useGrouping: false },\n FALLBACK_LOCALE,\n );\n for (let i = 0; i <= 9; i++) {\n const digit = digitFormatter.format(i);\n if (digit !== String(i)) this.#digits.set(digit, String(i));\n }\n }\n\n /**\n * Maps the locale's own digits to ASCII, folds full-width forms (the digits,\n * signs, and marks an IME confirms as 0-9+-.,) through the shared\n * half-width mapping, and reads U+2212 MINUS SIGN as \"-\", which some locales'\n * formatted output uses for negatives.\n */\n #normalize(text: string): string {\n let out = \"\";\n for (const ch of text) {\n const mapped = this.#digits.get(ch);\n if (mapped !== undefined) {\n out += mapped;\n } else if (ch === \"−\") {\n out += \"-\";\n } else {\n out += halfWidthChar(ch);\n }\n }\n return out;\n }\n /** Current `precision` declaration resolved against its numeric contract. */\n get #safePrecision(): number {\n return this.#numbers.read(\n this,\n \"precision\",\n this.precisionValue,\n CurrencyInputController.values.precision.default,\n CurrencyInputController.valueConstraints.precision,\n );\n }\n}\n\n/** Rounds `value` to `precision` decimal places, avoiding `-0`; overflow keeps `value`. */\nfunction round(value: number, precision: number): number {\n const factor = 10 ** Math.max(0, precision);\n const rounded = Math.round(value * factor) / factor;\n if (!Number.isFinite(rounded)) return value;\n return rounded === 0 ? 0 : rounded;\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../../src/utils/composition_tracker.ts","../../src/utils/half_width.ts","../../src/utils/intl_format.ts","../../src/utils/listener_set.ts","../../src/utils/locale.ts","../../src/utils/microtask_coalescer.ts","../../src/utils/morph_render_watcher.ts","../../src/utils/number_bounds.ts","../../src/utils/coerce.ts","../../src/utils/number_value.ts","../../src/utils/attribute_write.ts","../../src/utils/owned_text.ts","../../src/controllers/currency_input_controller.ts"],"names":["round"],"mappings":"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","file":"currency_input_controller.js","sourcesContent":["/** Minimal event shape carrying the platform's per-event composition signal. */\nexport interface CompositionSignal {\n readonly isComposing?: boolean;\n}\n\n/** Minimal `input` shape needed to tell a composition echo from a fresh edit. */\nexport interface ConfirmedInputSignal {\n readonly target: EventTarget | null;\n readonly inputType?: string;\n}\n\n/**\n * The `inputType` values an engine reports on an `input` that belongs to a\n * composition rather than to an edit the user just made.\n */\nconst COMPOSITION_INPUT_TYPES = new Set([\n \"insertCompositionText\",\n \"insertFromComposition\",\n \"deleteCompositionText\",\n \"deleteByComposition\",\n]);\n\n/** Whether a platform input kind belongs to composition rather than ordinary editing. */\nexport function isCompositionInputType(inputType: string | undefined): boolean {\n return inputType !== undefined && COMPOSITION_INPUT_TYPES.has(inputType);\n}\n\n/** The cancelable notice Turbo dispatches before a morph writes one attribute. */\nconst BEFORE_MORPH_ATTRIBUTE = \"turbo:before-morph-attribute\";\n\n/** Hooks that keep component-specific work outside {@link CompositionTracker}. */\nexport interface CompositionTrackerOptions {\n /** Runs after lifecycle state is set for a `compositionstart` event. */\n readonly onStart?: (event: Event) => void;\n /** Runs after lifecycle state is cleared for a `compositionend` event. */\n readonly onEnd?: (event: Event) => void;\n /**\n * Runs once lifecycle state is cleared for a composition that ended without\n * `compositionend`, with the `element` it ran in. Nothing was confirmed: the\n * element holds what a write left (`inPlace` false), or still holds the text the\n * composition left, which the engine stopped composing (`inPlace` true) — text\n * typed against whatever the page declared while it ran.\n *\n * A hook applies the work the composition held back — and only that — at once,\n * keeping the caret where it was. The event that showed the end is then handled as\n * it would be with no composition: the text the element holds is read by whatever\n * reads it next, as the user's edit if an edit reads it. A consumer whose contract\n * judges what an interrupted conversion leaves may also settle that text here, as\n * `stimeo--otp` returns a residual its `pattern` rejects to the prior character: it reports\n * that as a reconciliation, never as the user's edit, and keeps the selection.\n *\n * When the tracker sees the end in an event it hears — a key, an edit, a focus\n * change, the next `compositionstart` — the hook runs there, in the capture phase,\n * ahead of that event's own handlers and of the edit it announces, whoever\n * dispatched it. When a question ({@link CompositionTracker.isComposing},\n * {@link CompositionTracker.composingElement}) or a Turbo morph's notice for one\n * attribute shows the end, the hook runs in a microtask after them, never inside\n * its caller or a half-applied morph, unless an event the tracker hears comes\n * first. On `compositionstart` it runs after the new composition is set and before\n * `onStart`: {@link CompositionTracker.isComposing} is true again, so work held for\n * the old composition stays held for the new.\n */\n readonly onAbandon?: (element: EventTarget, inPlace: boolean) => void;\n}\n\n/** One composition in progress. */\ninterface Composition {\n /** The observed target the composition was heard on. */\n readonly target: EventTarget;\n /** The element composing: the observed field itself, or a field inside an observed ancestor. */\n readonly element: EventTarget;\n /** The value the composition last left in the element; `undefined` for an element with none. */\n text: unknown;\n}\n\n/**\n * The element's live value; `undefined` for an element without one, which a write never\n * changes.\n */\nconst textOf = (element: EventTarget): unknown => (element as { value?: unknown }).value;\n\n/** Whether `element` is the focused element of the document or shadow root it is in. */\nconst holdsFocus = (element: EventTarget): boolean =>\n element instanceof Node &&\n (element.getRootNode() as Partial<DocumentOrShadowRoot>).activeElement === element;\n\n/**\n * Owns IME composition listeners and transient state for one or more event targets.\n *\n * Some browsers omit `KeyboardEvent.isComposing` on the keydown that confirms a\n * conversion. Tracking `compositionstart` through `compositionend` supplies the\n * missing lifecycle signal without relying on deprecated numeric key codes.\n * Component policy stays with the consumer: filtering, validation, and submission\n * belong in the optional {@link CompositionTrackerOptions.onEnd} callback.\n *\n * The tracker also owns the other half of that lifecycle: **the `input` some\n * engines send after `compositionend` to echo the text just confirmed.** A\n * consumer that ran `onEnd` and then handled the echo would commit the same\n * confirmation twice, so {@link CompositionTracker.consumesConfirmedInput} tells\n * the echo apart and the consumer returns early on it.\n *\n * **What the echo is not, is the harder half.** Not every engine sends one —\n * Chromium ends a confirmation at `compositionend` with no `input` after it — so\n * a window that waits for the echo and only closes on the next key would swallow\n * the first edit that arrives without one: dictation, autofill, a drop,\n * `insertText`. Two things keep that from happening. The window closes on the\n * next anything — a key, a new composition, any `input`, losing the field — and\n * an `input` that reports an `inputType` outside {@link COMPOSITION_INPUT_TYPES}\n * is an edit, so it is never folded. Only an engine that reports no `inputType`\n * at all is left relying on the window alone.\n *\n * **A composition can also end without `compositionend`.** Chromium drops the\n * conversion silently when something other than the IME writes a different value\n * into its field — a Turbo morph, a form reset, a script — and when the field\n * moves or leaves the page, leaving the text it composed. The tracker reads the end\n * from what the engine and the field still say:\n *\n * - **The field holds other text than the composition left.** The IME's edits, and\n * the user's own between them, arrive as an `input` the engine dispatched\n * (`isTrusted`) or one that reports the composition, and the tracker takes the\n * field's text from those. A write by anything else changes the text with no such\n * `input` — at most a synthetic one — so the composition is over, ended with\n * {@link CompositionTrackerOptions.onAbandon}, before anyone acts on the field.\n * Writing the same text keeps the conversion, and the match.\n * - **The engine edits outside a composition.** A `beforeinput` reporting\n * `isComposing: false` with an `inputType` outside {@link COMPOSITION_INPUT_TYPES}\n * is an edit the engine no longer counts as composition — unless the `keydown`\n * right before it reported `isComposing: true`: a key the IME lets through, such\n * as Backspace, edits the field while the conversion goes on. This is what shows\n * a composition that ended with its text in place. Only one field composes at a\n * time, so such an edit on any observed target ends the composition held, with\n * `onAbandon`. A `keydown` can hold this back but never starts it: the keydown\n * that confirms a conversion may carry no `isComposing`, and dictation and\n * autofill edit with no key at all.\n * - **The field stays where it was heard.** A field the consumer observes itself is\n * the consumer's to release when it moves or leaves, which reads what it holds;\n * one that keeps focus through the move keeps composing\n * ({@link CompositionTracker.disconnect}). A field inside an observed ancestor\n * that leaves the ancestor, or loses focus within its document, ends its\n * composition quietly; one that stays the document's active element — the window\n * lost focus — keeps composing.\n * - **No other field composes**: a `compositionstart` ends any composition the\n * tracker still holds, with `onAbandon`, before the new one starts.\n *\n * The tracker checks this before it answers {@link CompositionTracker.isComposing}\n * or {@link CompositionTracker.composingElement}, and at every key, edit, blur,\n * `compositionstart` and morph it hears — keys, edits and blurs in the capture\n * phase, ahead of the consumer's own handlers. While\n * a composition is live, a Turbo morph leaves its field's value alone: Idiomorph\n * asks through `turbo:before-morph-attribute` before it writes `value`, as an\n * attribute or as the live text, and the tracker cancels that one notice for the\n * element composing, so the morph keeps the conversion, as it keeps focus. Every\n * other attribute, and every other element, still morphs.\n *\n * A consumer that observes several fields tells the conversion's own events from\n * edits in the other fields with {@link CompositionTracker.owns}, which holds even\n * while the tracker keeps a composition whose end no event has shown yet.\n *\n * @example\n * ```ts\n * #composition = new CompositionTracker({ onEnd: () => this.filter() });\n *\n * connect(): void {\n * this.#composition.observe(this.inputTarget);\n * }\n *\n * disconnect(): void {\n * this.#composition.disconnect();\n * }\n *\n * onInput(event: InputEvent): void {\n * if (this.#composition.consumesConfirmedInput(event)) return;\n * if (this.#composition.isComposing(event)) return;\n * }\n *\n * onKeydown(event: KeyboardEvent): void {\n * if (this.#composition.isComposing(event)) return;\n * }\n * ```\n */\nexport class CompositionTracker {\n readonly #observedTargets = new Set<EventTarget>();\n /** The composition in progress, if any: only one field composes at a time. */\n #composition: Composition | null = null;\n readonly #onStart: ((event: Event) => void) | undefined;\n readonly #onEnd: ((event: Event) => void) | undefined;\n readonly #onAbandon: ((element: EventTarget, inPlace: boolean) => void) | undefined;\n /** The field whose confirming `input` is still owed, while the window is open. */\n #confirmedTarget: EventTarget | null = null;\n /**\n * Whether the last `keydown` reported a composition, until the `beforeinput`\n * after it: the edit that key announces lands inside the composition.\n */\n #keyComposing = false;\n /** Whether the consumer is connected: from `observe()` until `disconnect()`. */\n #connected = false;\n /** A composition that ended without `compositionend` and whose `onAbandon` has not run yet. */\n #abandoned: { readonly element: EventTarget; readonly inPlace: boolean } | null = null;\n\n constructor(options: CompositionTrackerOptions = {}) {\n this.#onStart = options.onStart;\n this.#onEnd = options.onEnd;\n this.#onAbandon = options.onAbandon;\n }\n\n /**\n * Starts lifecycle tracking for `target`; repeated calls are idempotent. The\n * targets one tracker observes do not contain one another: a composition event\n * reaching two of them would be counted as two.\n */\n observe(target: EventTarget): void {\n this.#connected = true;\n if (this.#observedTargets.has(target)) return;\n target.addEventListener(\"compositionstart\", this.#handleStart);\n target.addEventListener(\"compositionend\", this.#handleEnd);\n target.addEventListener(\"keydown\", this.#handleKeydown, true);\n target.addEventListener(\"beforeinput\", this.#handleBeforeInput, true);\n target.addEventListener(\"input\", this.#handleInput, true);\n target.addEventListener(\"blur\", this.#handleBlur, true);\n target.addEventListener(BEFORE_MORPH_ATTRIBUTE, this.#handleBeforeMorphAttribute);\n this.#observedTargets.add(target);\n }\n\n /**\n * Stops tracking one target. A composition it held ends quietly, unless its element\n * still holds focus — see {@link CompositionTracker.disconnect}.\n */\n unobserve(target: EventTarget): void {\n if (!this.#observedTargets.delete(target)) return;\n this.#release(target);\n if (this.#composition?.target === target) this.#letGo();\n if (this.#confirmedTarget === target) this.#confirmedTarget = null;\n }\n\n /**\n * Releases every listener and clears state so reconnect starts cleanly.\n *\n * A composition whose element still holds focus is the exception. A move that\n * keeps focus — `moveBefore`, which Turbo's morph uses where the browser provides\n * it — can leave the conversion running, and Stimulus releases the moved target, or\n * the controller around it, and observes it again within the one mutation batch. So\n * the composition waits for its target to be observed again before the turn ends,\n * and goes on; otherwise it ends then — quietly once disconnected, and with\n * {@link CompositionTrackerOptions.onAbandon} for a consumer that only let that one\n * target go. A move without `moveBefore`, or a removal, takes focus away.\n */\n disconnect(): void {\n this.#connected = false;\n for (const target of this.#observedTargets) this.#release(target);\n this.#observedTargets.clear();\n this.#letGo();\n this.#confirmedTarget = null;\n this.#keyComposing = false;\n this.#abandoned = null;\n }\n\n /**\n * True when a composition is live or the current event reports one. A\n * composition that ended without `compositionend` ends here first.\n */\n isComposing(event?: CompositionSignal): boolean {\n this.#settle();\n return event?.isComposing === true || this.#composition !== null;\n }\n\n /**\n * The element a live composition is running in, or `null`. A composition that\n * ended without `compositionend` ends here first.\n */\n composingElement(): EventTarget | null {\n this.#settle();\n return this.#composition?.element ?? null;\n }\n\n /**\n * Whether `event` belongs to a composition: it reports one, or it is in the element a\n * live composition runs in. An event in another element — a key there, or a script's\n * write reported with a bare `input` — is an edit outside the composition, even while\n * the tracker holds one whose end it has not seen: only one element composes at a\n * time, and the IME edits nothing else. The composition held stays, since such an\n * event does not show its end. A consumer that observes several fields asks this of\n * each event; {@link CompositionTracker.isComposing} asks of the targets as a whole.\n * A composition that ended without `compositionend` ends here first.\n */\n owns(event: CompositionSignal & { readonly target: EventTarget | null }): boolean {\n const element = this.composingElement();\n return event.isComposing === true || (element !== null && element === event.target);\n }\n\n /**\n * Whether `event` is the `input` echoing the composition just confirmed.\n *\n * Asking closes the window either way, so one confirmation is folded at most\n * once and a consumer asks once per `input`.\n */\n consumesConfirmedInput(event: ConfirmedInputSignal): boolean {\n const confirmed = this.#confirmedTarget;\n this.#confirmedTarget = null;\n if (confirmed === null || confirmed !== event.target) return false;\n // An engine that reports no kind at all leaves `inputType` empty, and the\n // window is then the only signal there is.\n const inputType = event.inputType;\n return !inputType || isCompositionInputType(inputType);\n }\n\n /** Removes every listener {@link CompositionTracker.observe} added to `target`. */\n #release(target: EventTarget): void {\n target.removeEventListener(\"compositionstart\", this.#handleStart);\n target.removeEventListener(\"compositionend\", this.#handleEnd);\n target.removeEventListener(\"keydown\", this.#handleKeydown, true);\n target.removeEventListener(\"beforeinput\", this.#handleBeforeInput, true);\n target.removeEventListener(\"input\", this.#handleInput, true);\n target.removeEventListener(\"blur\", this.#handleBlur, true);\n target.removeEventListener(BEFORE_MORPH_ATTRIBUTE, this.#handleBeforeMorphAttribute);\n }\n\n /**\n * Lets go of the composition held once its target is no longer observed: it is over\n * unless its element kept focus and its target is observed again this turn.\n */\n #letGo(): void {\n const composition = this.#composition;\n if (composition === null) return;\n if (!holdsFocus(composition.element)) {\n this.#composition = null;\n return;\n }\n queueMicrotask(() => {\n if (this.#composition !== composition || this.#observedTargets.has(composition.target)) {\n return;\n }\n this.#composition = null;\n if (!this.#connected) return;\n this.#abandoned = { element: composition.element, inPlace: true };\n this.#runAbandon();\n });\n }\n\n /**\n * Ends the composition held if its field left the observed target, taking the\n * composition's text along, or holds text a write left.\n */\n #settle(): void {\n const composition = this.#composition;\n if (composition === null) return;\n const { target, element, text } = composition;\n if (target instanceof Node && element instanceof Node && !target.contains(element)) {\n this.#composition = null;\n } else if (textOf(element) !== text) {\n this.#abandon(false);\n }\n }\n\n /**\n * Ends the composition held, unconfirmed. Its `onAbandon` runs in a microtask,\n * unless an event the tracker hears runs it first.\n */\n #abandon(inPlace: boolean): void {\n this.#owe(inPlace);\n this.#composition = null;\n queueMicrotask(this.#runAbandon);\n }\n\n /** Records the `onAbandon` the composition held owes. */\n #owe(inPlace: boolean): void {\n const composition = this.#composition;\n if (composition !== null) this.#abandoned = { element: composition.element, inPlace };\n }\n\n /** Runs the `onAbandon` an ended composition owes, once. */\n readonly #runAbandon = (): void => {\n const abandoned = this.#abandoned;\n if (abandoned === null) return;\n this.#abandoned = null;\n this.#onAbandon?.(abandoned.element, abandoned.inPlace);\n };\n\n /** A composition starting while one is held ends the held one, unconfirmed. */\n readonly #handleStart = (event: Event): void => {\n this.#confirmedTarget = null;\n this.#settle();\n this.#owe(true);\n // A listener runs while the event is dispatched, so both targets are set.\n const target = event.currentTarget as EventTarget;\n const element = event.target as EventTarget;\n this.#composition = { target, element, text: textOf(element) };\n this.#runAbandon();\n this.#onStart?.(event);\n };\n\n readonly #handleEnd = (event: Event): void => {\n this.#runAbandon();\n if (this.#composition?.target === event.currentTarget) this.#composition = null;\n this.#confirmedTarget = event.target;\n this.#onEnd?.(event);\n };\n\n /**\n * A key on an observed field opens an edit of its own, so no echo is owed; it\n * also says whether the edit it announces lands inside a composition.\n */\n readonly #handleKeydown = (event: Event): void => {\n this.#settle();\n this.#runAbandon();\n this.#confirmedTarget = null;\n this.#keyComposing = (event as KeyboardEvent).isComposing === true;\n };\n\n /** An edit is about to land: a composition the engine no longer runs ends first. */\n readonly #handleBeforeInput = (event: Event): void => {\n const keyComposing = this.#keyComposing;\n this.#keyComposing = false;\n this.#settle();\n const { isComposing, inputType } = event as InputEvent;\n if (\n this.#composition !== null &&\n !keyComposing &&\n !isComposing &&\n inputType &&\n !isCompositionInputType(inputType)\n ) {\n this.#abandon(true);\n }\n this.#runAbandon();\n };\n\n /**\n * Takes the composing field's text from an `input` the engine dispatched or one\n * that reports the composition; any other `input` follows a write the\n * composition did not make.\n */\n readonly #handleInput = (event: Event): void => {\n const composition = this.#composition;\n const { isTrusted, isComposing, inputType } = event as InputEvent;\n if (\n composition !== null &&\n event.target === composition.element &&\n (isTrusted || isComposing || isCompositionInputType(inputType))\n ) {\n composition.text = textOf(composition.element);\n } else {\n this.#settle();\n }\n this.#runAbandon();\n };\n\n /**\n * Checks the composition as a field loses focus, ahead of the consumer's own blur\n * handlers. A field inside an observed ancestor that loses focus within its\n * document keeps its text and composes no more.\n */\n readonly #handleBlur = (event: Event): void => {\n this.#settle();\n this.#runAbandon();\n const composition = this.#composition;\n if (composition === null || composition.target === composition.element) return;\n const { element } = composition;\n if (!(element instanceof Node) || event.target !== element) return;\n const root = element.getRootNode() as Document | ShadowRoot;\n if (root.activeElement !== element) this.#composition = null;\n };\n\n /** Keeps a Turbo morph from writing the value of the element composing. */\n readonly #handleBeforeMorphAttribute = (event: Event): void => {\n this.#settle();\n const composition = this.#composition;\n if (composition?.target !== event.currentTarget || event.target !== composition.element) return;\n const detail: { readonly attributeName?: unknown } | null = (event as CustomEvent).detail;\n if (detail?.attributeName === \"value\") event.preventDefault();\n };\n}\n","/** The distance between a full-width ASCII code point and its half-width twin. */\nconst FULL_WIDTH_SHIFT = 0xfee0;\n\n/**\n * The half-width form of `char`, or `char` itself when it has none.\n *\n * An IME confirming in full-width mode produces U+FF01–U+FF5E (and U+3000 for\n * the space) where the page means ASCII — the digits of a phone number, the\n * letters of a code, the separators between them. Reading those as their ASCII\n * equivalents keeps confirmed text usable instead of discarding it. Characters\n * outside that block, including kana and astral code points, are returned\n * unchanged, so this never rewrites text a consumer meant to keep as typed.\n */\nexport function halfWidthChar(char: string): string {\n if (char >= \"!\" && char <= \"~\") {\n return String.fromCharCode(char.charCodeAt(0) - FULL_WIDTH_SHIFT);\n }\n return char === \" \" ? \" \" : char;\n}\n\n/** Every full-width ASCII character in `text` rewritten by {@link halfWidthChar}. */\nexport function toHalfWidth(text: string): string {\n let out = \"\";\n for (const char of text) out += halfWidthChar(char);\n return out;\n}\n","/**\n * Construction of `Intl` formatters for the controllers that take a locale, and\n * the options that go with it, from a declaration.\n *\n * Every `Intl` constructor resolves locale data on the way in, which makes it\n * too costly to rebuild on a hot path, and rejects a malformed language tag,\n * currency code, time zone or digit count with a `RangeError`. Both concerns are\n * handled here once. A formatter is built at most once per distinct request and\n * shared by every caller that asks for the same one. A `RangeError` is caught\n * and answered the way the caller asked: by rebuilding under a fallback locale,\n * or by returning `null` so the caller can leave its authored text alone. Any\n * other failure is a programming fault and propagates.\n */\n\n/** The constructor shape the `Intl` formatter classes share. */\nexport interface IntlFormatterConstructor<F, O extends object> {\n new (locales?: string | string[], options?: O): F;\n}\n\n/** Built formatters, and refusals, per constructor; see `cacheKey` for the key. */\nconst formatters = new WeakMap<object, Map<string, unknown>>();\n\n/**\n * A formatter for `locale` with `options`.\n *\n * With `fallbackLocale`, a `RangeError` from the constructor is answered by\n * building the same options under the fallback instead, so the result is never\n * `null`; the fallback's own failure propagates. Without it, a `RangeError`\n * yields `null` and the caller decides what to show. Errors of any other kind\n * propagate in both forms.\n *\n * Results are cached per constructor and `(locale, options, fallback)`, `null`\n * included, so asking again on every render costs one map lookup.\n */\nexport function intlFormatter<F, O extends object>(\n factory: IntlFormatterConstructor<F, O>,\n locale: string | undefined,\n options: O,\n fallbackLocale: string,\n): F;\nexport function intlFormatter<F, O extends object>(\n factory: IntlFormatterConstructor<F, O>,\n locale: string | undefined,\n options: O,\n): F | null;\nexport function intlFormatter<F, O extends object>(\n factory: IntlFormatterConstructor<F, O>,\n locale: string | undefined,\n options: O,\n fallbackLocale?: string,\n): F | null {\n const cache = cacheFor(factory);\n const key = cacheKey(locale, options, fallbackLocale);\n if (cache.has(key)) return cache.get(key) as F | null;\n const formatter = construct(factory, locale, options, fallbackLocale);\n cache.set(key, formatter);\n return formatter;\n}\n\n/** The cache for one constructor, created on first use. */\nfunction cacheFor(factory: object): Map<string, unknown> {\n const existing = formatters.get(factory);\n if (existing) return existing;\n const created = new Map<string, unknown>();\n formatters.set(factory, created);\n return created;\n}\n\n/**\n * One key per distinct request. `JSON.stringify` drops an option left\n * `undefined`, which is how the constructor reads it too. Two spellings of the\n * same options differing only in key order key separately; that costs one extra\n * formatter, never a wrong one, and call sites pass a fixed literal anyway.\n */\nfunction cacheKey(\n locale: string | undefined,\n options: object,\n fallbackLocale: string | undefined,\n): string {\n return JSON.stringify([locale, options, fallbackLocale]);\n}\n\n/** Builds the formatter under the `RangeError` contract described on `intlFormatter`. */\nfunction construct<F, O extends object>(\n factory: IntlFormatterConstructor<F, O>,\n locale: string | undefined,\n options: O,\n fallbackLocale: string | undefined,\n): F | null {\n try {\n return new factory(locale, options);\n } catch (error) {\n if (!(error instanceof RangeError)) throw error;\n if (fallbackLocale === undefined) return null;\n return new factory(fallbackLocale, options);\n }\n}\n","/** What {@link ListenerSet.add} passes on besides the signal it supplies itself. */\nexport type ListenerOptions = Omit<AddEventListenerOptions, \"signal\">;\n\n/**\n * The event map a target's own `addEventListener` types its handlers with: the\n * window's, a document's, an HTML or SVG element's, any other element's, or a\n * media query list's. Other targets name none.\n */\ntype EventMapOf<T extends EventTarget> = T extends Window\n ? WindowEventMap\n : T extends Document\n ? DocumentEventMap\n : T extends HTMLElement\n ? HTMLElementEventMap\n : T extends SVGElement\n ? SVGElementEventMap\n : T extends Element\n ? ElementEventMap\n : T extends MediaQueryList\n ? MediaQueryListEventMap\n : Record<never, never>;\n\n/**\n * Owns every listener a controller attaches for one connected lifetime and\n * releases them together, so an event name is spelled once and the release\n * cannot drift from the registration.\n *\n * Detaching by hand repeats three things at the release site — the type, the\n * handler reference and the capture flag — and any one of them drifting leaves\n * a listener alive on an element the controller no longer drives. Aborting the\n * signal a registration was created with releases it whatever it was made of,\n * so the release site names nothing.\n *\n * One set per lifetime, held as a field and never rebuilt.\n * {@link ListenerSet.dispose} is the only thing that closes a generation, and it opens\n * the next one in the same step, so the lifecycle hooks can call `add` and\n * `dispose` in any order any number of times, and no `add` ever meets an\n * already aborted signal — a DOM that registers a listener on such a signal\n * would keep it forever. Rebuilding the set instead would leak:\n * `addEventListener` matches an existing registration on target, type, callback\n * and capture alone, so re-adding the same handler while the first registration\n * is live is discarded, and that live registration keeps the signal it was\n * attached with — a set built by a second `connect()` can never release what it\n * appears to own.\n *\n * Scope is the registration only. Timers, observers, leases and the order they\n * are unwound in stay with the controller, which places `dispose()` in its\n * cleanup sequence. A receiver that changes at runtime (a\n * swapped target) is rebound by calling `dispose()` and then `add()` again from\n * the rebind, not by a second set.\n *\n * A lifetime shorter than the connection — while a Value holds, until a first\n * load, while a subscription is open — gets a set of its own, which the end of\n * that lifetime disposes. A controller therefore holds one set per lifetime: the\n * connection's, and one for each swapped receiver or shorter span.\n *\n * The set must own every registration of a tuple it holds: a listener the same\n * target already carries for the same type, callback and capture flag keeps the\n * right to remove it, and this set's `add` for that tuple is discarded. A\n * subscription shared between instances behind a participant count, listeners of\n * several elements that come and go one at a time, and those one gesture holds\n * keep their own pair of calls or a signal of their own.\n *\n * @example\n * ```ts\n * readonly #listeners = new ListenerSet();\n *\n * connect(): void {\n * this.#listeners.add(this.element, \"submit\", this.#onNativeSubmit, { capture: true });\n * this.#listeners.add(this.element, \"turbo:submit-start\", this.#onSubmitStart);\n * this.#listeners.add(this.element, \"turbo:submit-end\", this.#onSubmitEnd);\n * }\n *\n * disconnect(): void {\n * this.#listeners.dispose();\n * }\n * ```\n */\nexport class ListenerSet {\n /** The generation every `add` joins until the next `dispose()`. */\n #abort = new AbortController();\n\n /**\n * Attaches `handler` to the open generation, exactly as the caller spelled it.\n *\n * The set supplies the signal, so `options` carries everything else the DOM\n * accepts — `capture` included. A removal by hand would have to repeat that\n * flag; aborting the signal releases the listener without it.\n *\n * A `type` the target's own event map names types `handler` with that event,\n * as the target's `addEventListener` does, so a handler written for a\n * `KeyboardEvent` is passed as it is; any other `type` takes an\n * `EventListener`.\n */\n add<T extends EventTarget, K extends keyof EventMapOf<T> & string>(\n target: T,\n type: K,\n handler: (event: EventMapOf<T>[K]) => void,\n options?: ListenerOptions,\n ): void;\n add(target: EventTarget, type: string, handler: EventListener, options?: ListenerOptions): void;\n add(target: EventTarget, type: string, handler: EventListener, options?: ListenerOptions): void {\n target.addEventListener(type, handler, { ...options, signal: this.#abort.signal });\n }\n\n /**\n * Releases every listener of the open generation, synchronously, and opens the\n * next one. Idempotent, and safe before anything has been added.\n */\n dispose(): void {\n this.#abort.abort();\n this.#abort = new AbortController();\n }\n}\n","/**\n * The locale a component formats in: its own declaration, else the language of\n * the text around it, else the runtime default.\n *\n * `lang` is inherited in HTML, so the language that applies to an element is the\n * nearest one on the element itself or on an ancestor — not the document\n * element's, which is only the farthest of them. An empty `lang` there means the\n * language is unknown and stops the inheritance at that point, so it resolves to\n * the runtime default rather than to a `lang` further up.\n *\n * Resolution only, and the value is passed through as authored. Whether `Intl`\n * accepts the tag, and what to show when it does not, is the caller's contract.\n *\n * @example\n * ```ts\n * intlFormatter(Intl.DateTimeFormat, resolveLocale(this.element, this.localeValue), options);\n * ```\n */\nexport function resolveLocale(element: Element, declared = \"\"): string | undefined {\n return declared || element.closest(\"[lang]\")?.getAttribute(\"lang\") || undefined;\n}\n","/**\n * Collapses many Stimulus lifecycle callbacks from one DOM mutation into a\n * single pass.\n *\n * Stimulus fires `<name>TargetConnected` / `Disconnected` once per element and\n * `<name>ValueChanged` once per changed attribute. Replacing a list of N options\n * or morphing several render Values therefore delivers N callbacks — but the\n * useful unit of work is \"reconcile against the resulting declarative input\",\n * once, after the batch has settled. Every controller with reconcilable targets\n * or render Values needs the same shape: a `queued` flag plus `queueMicrotask`.\n *\n * **A microtask is the right horizon, and the reason is specific.** Stimulus\n * drives these callbacks from a `MutationObserver`, whose own callback already\n * runs as a microtask with the whole batch in hand; scheduling one more lands\n * after the last sibling callback of that batch and still before paint or any\n * event handler. A timer would be later than it needs to be, and reconciling\n * synchronously would run once per element against a half-applied DOM.\n *\n * **The two guards are not the same guard.** Scheduling is refused before the\n * controller connects, and running is refused after it disconnects:\n *\n * - **Before `connect()`** — Stimulus delivers initial target and Value callbacks\n * ahead of `connect()`. Reconciling there would compute output against a\n * controller whose own state has not been initialised, and `connect()` is\n * about to do a full pass anyway.\n * - **After `disconnect()`** — Stimulus fires a callback for **every** target\n * during teardown, and a microtask queued just before it would otherwise run\n * against a detached tree. {@link MicrotaskCoalescer.cancel} exists for the\n * teardown path to drop the pending pass outright.\n *\n * Both guards are part of one contract here rather than something each consumer\n * has to remember separately.\n *\n * Scope is the scheduling only. *What* to reconcile — keep the surviving active\n * option, fall back to the next / previous / first visible one, rebuild derived\n * chips or hidden fields — stays in the controller, because no two consumers\n * answer it the same way.\n *\n * @example\n * ```ts\n * readonly #reconcile = new MicrotaskCoalescer(() => this.#reconcileOptions());\n *\n * connect() { this.#reconcile.activate(); }\n * disconnect() { this.#reconcile.cancel(); }\n *\n * optionTargetConnected() { this.#reconcile.schedule(); }\n * optionTargetDisconnected() { this.#reconcile.schedule(); }\n * ```\n */\nexport class MicrotaskCoalescer {\n readonly #run: () => void;\n #queued = false;\n #active = false;\n #generation = 0;\n\n /** @param run - the single reconciliation pass, invoked at most once per batch. */\n constructor(run: () => void) {\n this.#run = run;\n }\n\n /** Opens the window in which {@link schedule} is honoured; call from `connect()`. */\n activate(): void {\n this.#active = true;\n }\n\n /** Closes the window and drops any pending pass; call from `disconnect()`. */\n cancel(): void {\n this.#active = false;\n this.#queued = false;\n this.#generation += 1;\n }\n\n /** Whether a requested pass has yet to run. */\n get pending(): boolean {\n return this.#queued;\n }\n\n /** Requests one pass after the batch settles. Idempotent; inert outside the window. */\n schedule(): void {\n if (!this.#active || this.#queued) return;\n this.#queued = true;\n const generation = this.#generation;\n queueMicrotask(() => {\n // A cancelled callback must not consume a pass queued after reconnect.\n if (generation !== this.#generation || !this.#queued || !this.#active) return;\n this.#queued = false;\n this.#run();\n });\n }\n}\n","import { ListenerSet } from \"./listener_set\";\nimport { MicrotaskCoalescer } from \"./microtask_coalescer\";\n\n/**\n * Coalesces retained-element morphs and explicit lifecycle requests into one pass.\n *\n * Observe the controller's element after its initial state is settled. Morphs on\n * that element and bubbling morphs on its descendants share the same microtask\n * as {@link schedule}. The callback repairs derived output; the controller owns\n * any logical transition reporting. {@link disconnect} releases the listener and\n * cancels pending work, including work from an earlier connected lifetime.\n */\nexport class MorphRenderWatcher {\n readonly #listeners = new ListenerSet();\n readonly #pass: MicrotaskCoalescer;\n #element: Element | null = null;\n readonly #onMorph = (): void => this.#pass.schedule();\n\n /** @param run - the single pass that repairs the settled controller's output. */\n constructor(run: () => void) {\n this.#pass = new MicrotaskCoalescer(run);\n }\n\n /** Opens observation; observing the same element again preserves queued work. */\n observe(element: Element): void {\n if (this.#element === element) return;\n this.disconnect();\n this.#element = element;\n this.#pass.activate();\n this.#listeners.add(element, \"turbo:morph-element\", this.#onMorph);\n }\n\n /** Requests one pass; requests outside an observed lifetime are ignored. */\n schedule(): void {\n this.#pass.schedule();\n }\n\n /** Whether a pass requested by a morph or {@link schedule} has yet to run. */\n get pending(): boolean {\n return this.#pass.pending;\n }\n\n /** Releases observation and pending work synchronously; safe to repeat. */\n disconnect(): void {\n this.#listeners.dispose();\n this.#pass.cancel();\n this.#element = null;\n }\n}\n","import { MAX_TIMER_DELAY_MS } from \"./timer_bounds\";\n\n/** Semantic constraints on an already decoded number, independent of the DOM. */\nexport interface NumberBounds {\n /** Finite numbers are required, including when this field is omitted. */\n readonly finite?: true;\n /** Inclusive lower endpoint. */\n readonly min?: number;\n /** Inclusive upper endpoint. */\n readonly max?: number;\n /** Exclusive lower endpoint. */\n readonly exclusiveMin?: number;\n /** Require a number without a fractional part. */\n readonly integer?: boolean;\n /** Exact decoded numbers accepted by a discrete contract. */\n readonly allowedValues?: readonly number[];\n /** JSON-safe exceptions to finite-number checking for unbounded endpoints. */\n readonly allowInfinity?: \"negative\" | \"positive\" | \"both\";\n}\n\n/** One constraint for each Number Value, including shorthand declarations. */\nexport type NumberValueConstraints<Values> = {\n readonly [Key in keyof Values as Values[Key] extends\n | NumberConstructor\n | { type: NumberConstructor }\n ? Key\n : never]: NumberBounds;\n};\n\n/** Reusable semantic domains; fractional inputs remain fractional unless excluded. */\nexport const NUMBER_BOUNDS = {\n finite: { finite: true },\n nonNegative: { finite: true, min: 0 },\n positive: { finite: true, exclusiveMin: 0 },\n nonNegativeInteger: { finite: true, min: 0, integer: true },\n positiveInteger: { finite: true, exclusiveMin: 0, integer: true },\n lowerBound: { finite: true, allowInfinity: \"negative\" },\n upperBound: { finite: true, allowInfinity: \"positive\" },\n timer: { finite: true, min: 0, max: MAX_TIMER_DELAY_MS },\n positiveTimer: { finite: true, exclusiveMin: 0, max: MAX_TIMER_DELAY_MS },\n} as const satisfies Record<string, NumberBounds>;\n\n/**\n * Checks all declared bounds without rounding, clamping, or coercing the input.\n * Infinity exceptions relax only finite checking; every other bound still applies.\n */\nexport function matchesNumberBounds(value: number, bounds: NumberBounds): boolean {\n if (!Number.isFinite(value)) {\n const direction = value === Infinity ? \"positive\" : value === -Infinity ? \"negative\" : null;\n if (direction === null) return false;\n if (bounds.allowInfinity !== \"both\" && bounds.allowInfinity !== direction) return false;\n }\n if (bounds.min !== undefined && value < bounds.min) return false;\n if (bounds.max !== undefined && value > bounds.max) return false;\n if (bounds.exclusiveMin !== undefined && value <= bounds.exclusiveMin) return false;\n if (bounds.integer && !Number.isInteger(value)) return false;\n if (bounds.allowedValues !== undefined && !bounds.allowedValues.includes(value)) return false;\n return true;\n}\n\n/** Decodes a Number Value literal; action params use their own JSON decoder. */\nexport function decodeNumberValue(raw: string): number {\n return Number(raw.replace(/_/g, \"\"));\n}\n","/**\n * Numeric coercion for controllers that accept a number through a Value, an action\n * param, or an event detail.\n *\n * Stimulus decodes action params as JSON when possible and leaves other text\n * untouched. CustomEvent detail can also supply a number or numeric string.\n * The reader accepts those two types while rejecting blank and non-finite input.\n */\n\nimport { matchesNumberBounds, type NumberBounds } from \"./number_bounds\";\n\n/** Numeric update input, accepting decoded action params before CustomEvent detail. */\nexport type NumericValueEvent = Event & {\n params?: { amount?: unknown };\n detail?: { value?: unknown };\n};\n\n/** Reads the nullish action-param/detail precedence without falling back from invalid input. */\nexport function eventNumber(event: NumericValueEvent): number | null {\n return toFiniteNumber(event.params?.amount ?? event.detail?.value);\n}\n\n/**\n * Reads a finite number or nonblank numeric string; other input returns `null`.\n * Blank strings cannot silently reset a value to zero.\n */\nexport function toFiniteNumber(raw: unknown): number | null {\n if (typeof raw !== \"number\" && typeof raw !== \"string\") return null;\n if (typeof raw === \"string\" && raw.trim().length === 0) return null;\n const value = Number(raw);\n return Number.isFinite(value) ? value : null;\n}\n\n/**\n * Returns an accepted decoded Number Value or the caller's fallback unchanged.\n * The caller owns the fallback contract; this reader does not parse or write a Value.\n */\nexport function readNumber(raw: number, fallback: number, bounds: NumberBounds): number {\n return matchesNumberBounds(raw, bounds) ? raw : fallback;\n}\n","import { readNumber } from \"./coerce\";\nimport { matchesNumberBounds, type NumberBounds } from \"./number_bounds\";\n\n/** The instance identity carried by a Number Value read. */\nexport interface NumberValueOwner {\n readonly identifier: string;\n readonly element: Element;\n}\n\n/** Reads current declarations at the point of use without rewriting their attributes. */\nexport class NumberValueReader {\n /** The last rejected literal per Value; no history grows for an unchanged instance. */\n readonly #lastRejected = new Map<string, string>();\n\n /** Resolves the declared number using its own fallback and shared class contract. */\n read(\n owner: NumberValueOwner,\n name: string,\n raw: number,\n fallback: number,\n bounds: NumberBounds,\n ): number {\n const resolved = readNumber(raw, fallback, bounds);\n if (matchesNumberBounds(raw, bounds)) {\n this.#lastRejected.delete(name);\n return resolved;\n }\n const attribute = `data-${owner.identifier}-${name.replace(/[A-Z]/g, (letter) => `-${letter.toLowerCase()}`)}-value`;\n const literal = owner.element.getAttribute(attribute);\n if (literal === null) {\n this.#lastRejected.delete(name);\n return resolved;\n }\n if (this.#lastRejected.get(name) !== literal) {\n this.#lastRejected.set(name, literal);\n console.warn(\n `Stimeo UI: \"${owner.identifier}\" has an invalid number Value \"${name}\" declaration ${JSON.stringify(literal)}; using ${fallback}.`,\n );\n }\n return resolved;\n }\n}\n","/**\n * Reflects a serialized attribute value only when the current value differs.\n *\n * A same-value `setAttribute` still queues a mutation record for every observer, so an\n * unchanged value writes nothing.\n *\n * @param element - The element whose attribute is reflected.\n * @param name - The attribute name, using the non-namespaced DOM API.\n * @param value - The serialized value, or null to remove the attribute.\n * @param beforeWrite - Called only for a change, before the DOM mutation, so the\n * caller can record ownership or identify its own observer records.\n * @returns Whether an attribute was written or removed.\n */\nexport function setAttributeIfChanged(\n element: Element,\n name: string,\n value: string | null,\n beforeWrite?: () => void,\n): boolean {\n if (element.getAttribute(name) === value) return false;\n beforeWrite?.();\n if (value === null) element.removeAttribute(name);\n else element.setAttribute(name, value);\n return true;\n}\n","import { setAttributeIfChanged } from \"./attribute_write\";\n\n/** The original string and the last string written through one channel. */\nexport interface TextWrite {\n readonly original: string;\n readonly written: string;\n}\n\n/** Live evidence is tied to this instance and this exact element. */\nexport type TextEvidence =\n | { readonly source?: \"dom\" }\n | { readonly source: \"live\"; readonly allowOriginal?: boolean };\n\n/**\n * Records plain text or an input's value as `[channel, original, written]` in\n * an identifier-derived attribute supplied by the caller. Ownership requires a\n * valid record and the same current string; text containing an element is never\n * owned. The caller decides when to acquire, clear, restore, or forget a slot.\n *\n * DOM evidence survives a clone. Live evidence only describes writes made by\n * this instance to that element, so it can preserve a caller's held semantic\n * state or repair a morph that omitted the record. Neither proves who last\n * wrote an identical string. An optional guard protects other authored state.\n */\nexport class OwnedText<T extends HTMLElement = HTMLElement> {\n readonly #attribute: string;\n readonly #channel: \"text\" | \"value\";\n readonly #guard: (element: T) => boolean;\n readonly #writes = new WeakMap<T, TextWrite>();\n\n constructor(\n attribute: string,\n channel: \"text\" | \"value\" = \"text\",\n guard: (element: T) => boolean = () => true,\n ) {\n this.#attribute = attribute;\n this.#channel = channel;\n this.#guard = guard;\n }\n\n /** Whether the slot carries a record, including an invalid one. */\n hasRecord(element: T): boolean {\n return element.hasAttribute(this.#attribute);\n }\n\n /** Reads validated DOM evidence, or explicitly requested instance evidence. */\n read(element: T, evidence: TextEvidence = {}): TextWrite | null {\n if (evidence.source === \"live\") return this.#writes.get(element) ?? null;\n const raw = element.getAttribute(this.#attribute);\n if (raw === null) return null;\n try {\n const record: unknown = JSON.parse(raw);\n if (\n !Array.isArray(record) ||\n record.length !== 3 ||\n record[0] !== this.#channel ||\n typeof record[1] !== \"string\" ||\n typeof record[2] !== \"string\"\n )\n return null;\n return { original: record[1], written: record[2] };\n } catch {\n return null;\n }\n }\n\n /** Checks the current string, the text structure, and the caller's guard. */\n owns(element: T, evidence: TextEvidence = {}): boolean {\n return this.#ownedRecord(element, evidence) !== null;\n }\n\n /** Returns the matching evidence after checking structure and the caller's guard. */\n #ownedRecord(element: T, evidence: TextEvidence): TextWrite | null {\n const record = this.read(element, evidence);\n if (record === null || !this.#guard(element)) return null;\n if (this.#channel === \"text\" && element.firstElementChild !== null) return null;\n const current = this.#current(element);\n return current === record.written ||\n (evidence.source === \"live\" && evidence.allowOriginal === true && current === record.original)\n ? record\n : null;\n }\n\n /** Acquires the slot, preserving the first original unless the caller supplies one. */\n write(element: T, written: string, original?: string, force = false): void {\n const current = this.#current(element);\n if (current === null) return;\n const before =\n original ?? this.#writes.get(element)?.original ?? this.read(element)?.original ?? current;\n if (force || current !== written) this.#put(element, written);\n this.remember(element, written, before);\n }\n\n /** Records a write whose property assignment, such as caret handling, the caller owns. */\n remember(element: T, written: string, original?: string): void {\n const current = this.#current(element);\n if (current === null) return;\n const before =\n original ?? this.#writes.get(element)?.original ?? this.read(element)?.original ?? current;\n this.#writes.set(element, { original: before, written });\n setAttributeIfChanged(\n element,\n this.#attribute,\n JSON.stringify([this.#channel, before, written]),\n );\n }\n\n /** Empties an owned slot and releases its evidence. */\n clear(element: T, evidence: TextEvidence = {}): boolean {\n if (!this.owns(element, evidence)) return false;\n if (this.#current(element) !== \"\") this.#put(element, \"\");\n this.forget(element);\n return true;\n }\n\n /** Restores an owned slot's original string and releases its evidence. */\n restore(element: T, evidence: TextEvidence = {}): boolean {\n const record = this.#ownedRecord(element, evidence);\n if (record === null) return false;\n if (this.#current(element) !== record.original) this.#put(element, record.original);\n this.forget(element);\n return true;\n }\n\n /** Drops evidence without changing the slot, including an invalid DOM record. */\n forget(element: T): void {\n setAttributeIfChanged(element, this.#attribute, null);\n this.#writes.delete(element);\n }\n\n /** Reads the property belonging to this channel. */\n #current(element: T): string | null {\n if (this.#channel === \"text\") return element.textContent ?? \"\";\n return element instanceof HTMLInputElement ? element.value : null;\n }\n\n /** Writes the property belonging to this channel. */\n #put(element: T, text: string): void {\n if (this.#channel === \"text\") element.textContent = text;\n else if (element instanceof HTMLInputElement) element.value = text;\n }\n}\n","import { Controller } from \"@hotwired/stimulus\";\nimport {\n type CompositionSignal,\n CompositionTracker,\n isCompositionInputType,\n} from \"../utils/composition_tracker\";\nimport { halfWidthChar } from \"../utils/half_width\";\nimport { intlFormatter } from \"../utils/intl_format\";\nimport { ListenerSet } from \"../utils/listener_set\";\nimport { resolveLocale } from \"../utils/locale\";\nimport { MorphRenderWatcher } from \"../utils/morph_render_watcher\";\nimport type { NumberValueConstraints } from \"../utils/number_bounds\";\nimport { NumberValueReader } from \"../utils/number_value\";\nimport { OwnedText } from \"../utils/owned_text\";\n\n/** The number-shaped pieces of an in-progress entry, in typing order. */\ninterface EntryParts {\n /** The leading sign exactly as typed (`\"\"` when none). */\n sign: \"\" | \"-\" | \"+\";\n /** Integer digits with grouping stripped (may be empty mid-entry). */\n int: string;\n /** Whether a decimal mark was typed. */\n hasDot: boolean;\n /** Fraction digits exactly as typed; rounding happens only on blur. */\n frac: string;\n}\n\n/** One scan of the display text: its structure and the numeric value it holds. */\ninterface Scan {\n parts: EntryParts;\n /** The finite value, or `null` while no digit has been typed yet. */\n value: number | null;\n}\n\n/** The display's text read with the separators it was written in. */\ninterface Reading {\n scan: Scan;\n /** The significant characters before the caret, counted with the same separators. */\n anchor: number | null;\n}\n\n/** Who moved the value: the user editing the display, or the page. */\ntype Cause = \"edit\" | \"reconcile\";\n\n/**\n * The locale a declaration falls back to when `Intl` rejects it, so a broken tag\n * still leaves a field that formats and parses the same way every time.\n */\nconst FALLBACK_LOCALE = \"en-US\";\n\n/**\n * Headless currency / amount input behavior: groups digits for display while\n * keeping a machine-readable number in a hidden field, and mirrors the\n * normalized value to a visually-hidden span so assistive tech reads the real\n * amount rather than the grouped display string.\n *\n * Markup contract (identifier: `stimeo--currency-input`):\n * <div data-controller=\"stimeo--currency-input\"\n * data-stimeo--currency-input-locale-value=\"en-US\"\n * data-stimeo--currency-input-currency-value=\"USD\"\n * data-stimeo--currency-input-precision-value=\"2\">\n * <input type=\"text\" inputmode=\"decimal\"\n * aria-describedby=\"amt-sr\"\n * data-stimeo--currency-input-target=\"display\"\n * data-action=\"input->stimeo--currency-input#onInput\n * blur->stimeo--currency-input#format\" />\n * <span id=\"amt-sr\" class=\"visually-hidden\"\n * data-stimeo--currency-input-target=\"srValue\"></span>\n * <input type=\"hidden\" data-stimeo--currency-input-target=\"field\" />\n * </div>\n *\n * `change` and `reconcile` dispatch `{ value: number | null, formatted: string }`\n * — `null` (with an empty `formatted`) when the amount is cleared, so consumers\n * hear every transition of the numeric value, including back to empty. `change`\n * is the user's edit: typing, or the rounding applied on `blur`. `reconcile` is a\n * value the page moved: a `locale`, `currency` or `precision` change that\n * re-rounds the committed amount, a display target swapped in holding another\n * amount, a reconnect that rounds an entry left unrounded mid-typing, or a move\n * that ends a composition before its `compositionend`. Connecting over a\n * server-rendered value reports neither.\n *\n * @remarks\n * Behavior only — no styling, no validation (range/required belong to the\n * consumer or `stimeo--form-field`). The display field is the sole Tab stop and keeps its\n * native text-editing behavior; this controller never steals focus.\n *\n * While typing, the entry is preserved as typed: grouping is applied to the\n * integer digits per locale, a leading sign and a trailing decimal mark stay in\n * place, fraction digits are kept verbatim, and the caret is restored after the\n * same significant character it followed. Negative amounts are in scope. The\n * fixed-precision rounding is applied on `blur`, never mid-entry; one asked for\n * mid-composition is applied with the text the composition confirms or leaves.\n * Full-width digits, signs, and marks (an IME confirming 0-9/./-) are\n * normalized to their ASCII forms rather than stripped; the locale's own\n * digits (a non-Latin default numbering system such as ar-EG's) are mapped\n * back the same way; and U+2212 MINUS SIGN is read as a sign. An ASCII \".\"\n * only counts as a decimal mark in locales where it is not the grouping\n * separator. Together these keep the controller's own output re-parseable to\n * the same value in every locale. Events fired mid-IME-composition are\n * ignored; the confirmed text is formatted once on `compositionend`. A\n * `locale` / `currency` / `precision` change that arrives mid-composition\n * leaves the uncommitted text alone and applies right after that confirmed\n * text has been read. A composition this controller stops hearing — its display\n * leaves, or the controller disconnects, before `compositionend` — ends there:\n * a display still in place is read as `compositionend` would read it, and a\n * value that moves is reported as `reconcile`. A field or screen-reader span\n * arriving mid-composition takes the committed value.\n *\n * Display text is read with the declarations it was written for. This\n * controller's own rendering was written with the separators in force, so a\n * declaration change reads it before they change. Any other text is the page's\n * — a display swapped in, or text written into the display alongside a\n * declaration change — written for the declarations the page carries, so it is\n * read with those.\n *\n * With no `locale` declared the field formats in the nearest `lang` up the\n * ancestor chain, else in the runtime default. A malformed `locale` falls back\n * to `en-US`, and a malformed `currency` or `precision` to that Value's default,\n * instead of throwing. The declarations, the nearest `lang` among them, are\n * read and validated before a display is read after they may have moved — on a\n * Value change, when the controller connects, and when a display arrives; the\n * hot path only ever sees validated values through cached `Intl.NumberFormat`\n * instances, never built per keystroke. Late-arriving or swapped `field` /\n * `srValue` / `display` targets are re-synced on connection; one that arrives\n * behind the target in charge is re-synced when that target leaves. Only the\n * display in charge — the first `display` target — is read: an input, blur or\n * composition in a display behind it is never taken as the user's edit.\n *\n * Reconnecting starts from the committed value: a display still showing this\n * controller's own rendering is not read back but re-rendered from that value\n * under the current declarations, so a `locale` changed while the element was\n * away never re-reads its separators. The re-render is the fixed-precision\n * form, so it rounds whenever the value has more places than the current\n * `precision` allows — because `precision` changed while the element was away,\n * or because the entry was left unrounded mid-typing (`1.555` becomes `1.56`) —\n * and a value it moves is reported as `reconcile`. The composition listeners\n * are released on `disconnect()`.\n *\n * A display already focused when first acquired or reconnected may carry a\n * composition whose start was missed. Its text and selection stay untouched,\n * including non-IME autofocus, until its `compositionend` or a non-composing\n * `input` with a non-composition `inputType`. A bare input, a direct `onInput()`\n * call, and blur alone provide no confirmation. While held, submission and the\n * accessible output retain this instance's accepted value; with no accepted value,\n * the page's hidden field and accessible text stay unchanged, even when empty.\n * Neither the draft nor the hidden field seeds the comparison baseline. Connect\n * before focusing if synchronous initialization is needed, and provide initial\n * submission and accessible values in markup when early focus is possible.\n *\n * Honest a11y note: a hidden `<input>` is not exposed to assistive tech, so the\n * normalized value is *also* published as text in the `srValue` span referenced\n * by the display's `aria-describedby` — that, not the hidden field, is what a\n * screen reader announces.\n */\nexport class CurrencyInputController extends Controller<HTMLElement> {\n /** Numeric read boundaries share one reader for this controller instance. */\n readonly #numbers = new NumberValueReader();\n\n static override targets = [\"display\", \"field\", \"srValue\"];\n static override values = {\n locale: { type: String, default: \"\" },\n currency: { type: String, default: \"\" },\n precision: { type: Number, default: 2 },\n };\n\n static valueConstraints = {\n precision: { finite: true, integer: true, min: 0, max: 100 },\n } satisfies NumberValueConstraints<typeof CurrencyInputController.values>;\n static actions = [\"format\", \"onInput\"] as const;\n static events = [\"change\", \"reconcile\"] as const;\n\n declare readonly displayTarget: HTMLInputElement;\n declare readonly displayTargets: HTMLInputElement[];\n declare readonly fieldTarget: HTMLInputElement;\n declare readonly srValueTarget: HTMLElement;\n declare readonly hasDisplayTarget: boolean;\n declare readonly hasFieldTarget: boolean;\n declare readonly hasSrValueTarget: boolean;\n declare localeValue: string;\n declare currencyValue: string;\n declare precisionValue: number;\n\n /** The numeric value last committed; both events report only a move away from it. */\n #lastValue: number | null = null;\n #started = false;\n /** A focused arrival whose text has not supplied a non-composing edit or an end. */\n #unsettled: HTMLInputElement | null = null;\n /** Formatter preparation is independent of accepting the display's text. */\n #configured = false;\n readonly #listeners = new ListenerSet();\n /**\n * Whether the declarations the page carries differ, by value, from the ones taken in,\n * as the last mid-composition pass read them. Passes read the declarations, the end\n * of a composition does not, so the language around an empty locale is read only\n * where it always is. Taking the declarations in clears it.\n */\n #declarationsHeld = false;\n /** Only live evidence can accompany this instance's held number and separators. */\n readonly #displayText = new OwnedText<HTMLInputElement>(\n `data-${this.identifier}-display-text`,\n \"value\",\n );\n /** The display associated with the committed value and active separators. */\n #renderedDisplay: HTMLInputElement | null = null;\n /**\n * The display rendered last, once it has left the display targets. The first\n * classification after it is back in charge, whichever entry point runs it, treats it\n * as an arrival when it shows other text than that rendering, and forgets it.\n */\n #departed: HTMLInputElement | null = null;\n /**\n * A rounding `format` asked for while a composition ran, held for that composition. Its\n * owner is the display the composition runs in: the one the tracker follows when it\n * heard the composition start (`heard`), else the display the event reporting the\n * composition came from, or the display in charge for an event with no target.\n *\n * It is applied once, by the owner's `compositionend` (confirming or cancelling), or by\n * the reading of the text the owner's composition leaves when a move or disconnect ends\n * it or the user starts composing in another display. It lapses, never applied, at any\n * other end: a `compositionend` in another display (one composition runs at a time),\n * the owner leaving the display targets with no composition the tracker follows going on\n * in it, an end with no `compositionend`, a connection, a rounding applied at once, and\n * — for one the tracker never heard start — the next start the tracker hears.\n */\n #formatHeld: { readonly display: EventTarget; readonly heard: boolean } | null = null;\n\n /** Validated mirrors of the Values; the hot path never reads a raw Value. */\n #locale: string | undefined;\n #currency = \"\";\n #precision = 2;\n\n /** Formatters rebuilt when the declarations are taken in, never per keystroke. */\n #grouping!: Intl.NumberFormat;\n #fixed!: Intl.NumberFormat;\n #accessible!: Intl.NumberFormat;\n #group = \",\";\n #decimal = \".\";\n /** The locale's non-Latin digits mapped back to ASCII (empty for Latin locales). */\n readonly #digits = new Map<string, string>();\n\n /**\n * Holds mid-composition input so the IME's uncommitted text is never rewritten.\n * The confirmed text is formatted once, and what the composition held back is\n * applied after it.\n *\n * When it ends, what is owed is read from what differs from the last rendering\n * ({@link #owed}): only the declarations are compared on each pass, by value, so a pass\n * that changed nothing can never discard a change, and a change taken back owes\n * nothing.\n *\n * Only the display in charge holds the user's confirmed text. A composition that\n * ends on a display behind it confirms nothing this controller reads: what is owed\n * is applied, and the display in charge is never reported as that user's edit.\n *\n * A composition that ends without `compositionend` confirmed nothing; what is owed\n * applies before the key, edit or blur that showed the end is handled, and waits on\n * for a composition that has started since. Text a write left in the display is the\n * page's, read with the declarations the page carries. Text the composition left in\n * place was typed against the declarations in force, so it is read as a move leaves\n * it before the change applies.\n *\n * When a composition starts before the one before it was heard ending, what that\n * one owes is read before the new draft arrives, so the new one confirms the user's\n * edit alone. Text it left in place in the display in charge was typed against the\n * declarations in force: it is read now, unless the new one goes on in that same\n * display, which carries it to its own end. Text the page wrote into the display in\n * charge is read as the page's ({@link #readPageText}).\n *\n * A rounding `format` asked for meanwhile ({@link #formatHeld}) is applied by the\n * `compositionend` itself, with the confirmed text or the text a cancel left, in\n * one reading of the display in charge — or, for a composition in a display behind\n * it, after what is owed. A move or disconnect, or a composition the user starts in\n * another display, rounds what it reads ({@link #endUntrackedComposition}); any other\n * end with no `compositionend` drops it — the user may go on typing in place, and the\n * next blur rounds.\n */\n readonly #composition = new CompositionTracker({\n onEnd: (event) => {\n const display = event.currentTarget;\n if (this.#unsettled === display) this.#unsettled = null;\n const round = this.#takeFormatHeld(display);\n if (this.#inCharge(display)) this.#reformat(round, \"edit\");\n if (this.#owed(display)) this.#applyValueChange();\n if (round && !this.#inCharge(display)) this.#reformat(true, \"edit\");\n },\n onAbandon: (display, inPlace) => {\n const next = this.#composition.composingElement();\n // What was held for the composition that ended is settled before anything is\n // reported, so a rounding asked for in response is held for the next one.\n if (inPlace && next !== null && next !== display) {\n // The user composes in another display now and will not edit this one further.\n this.#endUntrackedComposition(display);\n } else {\n this.#formatHeld = null;\n }\n if ((next === display && inPlace) || !this.#owed(display)) return;\n if (next !== null) {\n this.#readPageText(next);\n return;\n }\n if (inPlace) this.#endUntrackedComposition(display);\n if (this.#owed(display)) this.#applyValueChange();\n },\n // A start the tracker hears ends any composition it never heard start.\n onStart: (event) => {\n if (this.#unsettled === event.target) this.#unsettled = null;\n if (this.#formatHeld?.heard === false) this.#formatHeld = null;\n },\n });\n\n /**\n * Re-validates on declaration changes and re-renders the committed display,\n * reporting a value the re-render moved as `reconcile`.\n */\n localeValueChanged(): void {\n this.#applyValueChange();\n }\n\n currencyValueChanged(): void {\n this.#applyValueChange();\n }\n\n precisionValueChanged(): void {\n this.#applyValueChange();\n }\n\n /**\n * Reads the display with the declarations its text was written for, then\n * re-renders it under the new ones — so a locale switch re-interprets the\n * value, never the old text with new separators, and text the page wrote for\n * the declarations it changes is never read with the old ones.\n *\n * While any display is composing, its text is the IME's: the pass reads no display\n * and takes no declaration in, so the confirmed text is read with the separators\n * it was typed against. It only notes, by value, whether the declarations moved, and\n * the end of the composition applies whatever is owed ({@link #owed}). The pass\n * restores the derived output from the last committed value in the declarations\n * still in force, without touching the composing display or caret.\n *\n * A display the user is in keeps its caret by significant characters. The\n * re-render can land right before an edit — a composition the page's write\n * ended shows only then — and the edit lands where the user put the caret.\n *\n * @stimeoRenderRoot\n */\n #applyValueChange(): void {\n // The next connect takes the declarations in before reading, or waits for the end\n // of a conversion a display moved here with.\n if (!this.#started) return;\n if (this.#holdUnsettled(false)) return;\n if (this.#composition.isComposing()) {\n this.#declarationsHeld = this.#declarationsChanged();\n this.#resync();\n return;\n }\n // With nothing to read, the next display takes the declarations in before reading.\n if (!this.hasDisplayTarget) return;\n const { scan, anchor } = this.#readDisplay();\n if (document.activeElement === this.displayTarget) {\n const formatted = this.#render(scan.parts);\n this.#showAtCaret(formatted, anchor);\n this.#reflect(scan.value, formatted, \"reconcile\");\n } else {\n this.#renderFixed(scan.value, \"reconcile\");\n }\n }\n\n /**\n * Reads the display and takes in the declarations the page carries now. This\n * controller's own rendering was written with the separators in force, so it\n * is read before they change; any other text is the page's, written for the\n * declarations it carries, so it is read after.\n */\n #readDisplay(): Reading {\n const text = this.displayTarget.value;\n const own = this.#showsOwnRendering(this.displayTarget) ? this.#read(text) : null;\n this.#revalidate();\n return own ?? this.#read(text);\n }\n\n /** Whether `display` is the one this controller rendered last and still shows that text. */\n #showsOwnRendering(display: HTMLInputElement): boolean {\n return display === this.#renderedDisplay && this.#displayText.owns(display, { source: \"live\" });\n }\n\n /**\n * Whether an event from `source` speaks for the display in charge — the first display\n * target. One with no source, such as a direct call, acts on the display in charge.\n */\n #inCharge(source: EventTarget | null): boolean {\n return source === null || (this.hasDisplayTarget && source === this.displayTarget);\n }\n\n /** Scans `text` and counts the caret's significant characters with the separators in force. */\n #read(text: string): Reading {\n return {\n scan: this.#scan(text),\n anchor: this.#significantBefore(text, this.displayTarget.selectionStart),\n };\n }\n\n readonly #morph = new MorphRenderWatcher(() => this.#applyValueChange());\n\n /**\n * Takes in the declarations the page carries now and normalizes the display\n * to its fixed-precision form.\n *\n * A display still showing this controller's own last rendering is not read\n * back: its separators may belong to declarations that changed while the\n * controller was away, and the committed value is known anyway. That value is\n * re-rendered at the current fixed precision, which rounds it whether\n * `precision` changed meanwhile or the entry was left unrounded mid-typing, and\n * a move the rounding causes is reported as `reconcile`. Any other text is the\n * page's, written for the declarations it carries, so it is read with them.\n */\n override connect(): void {\n this.#morph.observe(this.element);\n this.#listeners.add(this.element, \"turbo:before-morph-attribute\", this.#protectUnsettled);\n this.#started = true;\n if (!this.#configured) this.#revalidate();\n // A display that moved here with its conversion keeps it; a change the move carried\n // in waits for the conversion's end, which reads what was typed against the\n // declarations in force before it applies.\n if (this.#composition.isComposing()) {\n this.#applyValueChange();\n return;\n }\n // The fixed-precision rendering below rounds whatever `format` asked for.\n this.#formatHeld = null;\n if (this.#holdUnsettled(true)) return;\n this.#revalidate();\n if (!this.hasDisplayTarget) return;\n if (this.#showsOwnRendering(this.displayTarget)) {\n this.#renderFixed(this.#lastValue, \"reconcile\");\n return;\n }\n // Seed the baseline with the *rounded* initial value: the idempotent\n // connect-time reformat describes the value the page rendered, so it\n // reports nothing.\n const { value } = this.#scan(this.displayTarget.value);\n this.#lastValue = value === null ? null : round(value, this.#precision);\n this.#renderFixed(value, \"reconcile\");\n }\n\n /**\n * Releases the composition listeners. A composition still running hears no\n * `compositionend` once they are gone, so it ends here; what it held back is\n * taken in on the next `connect()`. A display that keeps focus through the move\n * keeps its conversion for the reconnect, and its text is left alone.\n */\n override disconnect(): void {\n this.#morph.disconnect();\n this.#listeners.dispose();\n const composing = this.#composition.composingElement();\n this.#composition.disconnect();\n if (this.#composition.composingElement() !== composing) {\n this.#endUntrackedComposition(composing);\n }\n this.#started = false;\n }\n\n /**\n * Tracks composition on an arriving (or swapped-in) display and normalizes it\n * under the declarations the page carries now, reading this controller's own\n * rendering with the separators it was written under; an amount that differs\n * from the committed one is the page's, so it is reported as `reconcile`.\n * A display that arrives behind the one in charge is only tracked: the one\n * ahead may be composing against the declarations in force, and the arrival\n * is read when that one leaves. One that arrives in charge while a display\n * composes is a mid-composition pass: it is read once the conversion ends,\n * however it ends, because it is not the display rendered last. One moved with\n * its conversion is the one rendered last, so it owes nothing.\n *\n * One that arrives in charge already focused, with no composition the tracker\n * follows in it, may carry a composition whose start was missed, so it is held\n * instead of read: another element, or the display rendered last coming back\n * without that rendering. Its text and selection stay as they are, it is not\n * rounded, and the hidden field and the accessible text keep the committed value\n * (the page's own while none was committed); its own `compositionend`, or an\n * ordinary `input` that releases it, reads it as the user's edit, reported as\n * `change`. The display rendered last coming back with that rendering is read as\n * above. The arrival is held by whichever reading notices it first, so a declaration\n * change, a morph, `format()` or a blur that runs before this callback holds it too:\n * one that blurs before this callback keeps its rounding for its own `compositionend`.\n */\n displayTargetConnected(target: HTMLInputElement): void {\n this.#composition.observe(target);\n if (!this.#started || !this.hasDisplayTarget || this.displayTarget !== target) return;\n this.#applyValueChange();\n }\n\n /**\n * Stops tracking a display that leaves. A composition running on it hears no\n * `compositionend` any more, so it ends here — unless the display kept focus\n * through a move, which keeps the conversion; a change it held waits for the\n * next display to be read. A composition running on another display still hears\n * its own `compositionend`, so its text is left to it. A display that stays is\n * read again as a declaration change reads it, so an amount it holds that\n * differs from the committed one is the page's and is reported as `reconcile`;\n * one still composing is read when the conversion ends if it is no longer the\n * display rendered last, and otherwise has nothing new to read. One left in charge\n * that is focused, is not the display rendered last and has no composition the\n * tracker follows in it is held as a focused arrival is: neither read nor rounded,\n * the hidden field and the accessible text keep the committed value, and its own\n * `compositionend`, or an ordinary `input` that releases it, reads it as `change`.\n * The display rendered last that leaves is remembered until it is next classified in\n * charge, so it comes back as an arrival whichever callback reads it first. One that only\n * moved within the same mutation batch while the controller stayed connected, already\n * back in charge, is not remembered; one that leaves with the controller element is.\n */\n displayTargetDisconnected(target: HTMLInputElement): void {\n if (\n target === this.#renderedDisplay &&\n !(this.#started && this.hasDisplayTarget && this.displayTarget === target)\n ) {\n this.#departed = target;\n }\n const composing = this.#composition.composingElement() === target;\n this.#composition.unobserve(target);\n if (composing && this.#composition.composingElement() !== target) {\n this.#endUntrackedComposition(target);\n }\n // A display that leaves takes the rounding asked of it along, unless it composes on.\n if (this.#formatHeld?.display === target && this.#composition.composingElement() !== target) {\n this.#formatHeld = null;\n }\n this.#applyValueChange();\n }\n\n /**\n * Ends a composition no `compositionend` will reach. A display still in place —\n * one a move re-inserted, the display of a controller that moves, or one whose\n * composition the engine stopped — holds the text the composition left, typed\n * against the declarations in force, so it is read as `compositionend` would read\n * it and becomes this controller's own rendering — rounded in the same reading when\n * a blur or `format()` asked for that meanwhile, since nothing else will. Nothing\n * confirmed that text, so a value it moves is reported as `reconcile`. A display\n * that left takes its composition, and the rounding asked of it, along.\n */\n #endUntrackedComposition(display: EventTarget | null): void {\n const round = this.#takeFormatHeld(display);\n if (this.hasDisplayTarget && this.displayTarget === display) {\n this.#reformat(round, \"reconcile\");\n }\n }\n\n /** Syncs a late-arriving hidden field without touching the display or events. */\n fieldTargetConnected(): void {\n if (this.#started) this.#resync();\n }\n\n /** Syncs the hidden field that stays when an earlier one leaves, silently. */\n fieldTargetDisconnected(): void {\n if (this.#started) this.#resync();\n }\n\n /** Syncs a late-arriving screen-reader span the same way. */\n srValueTargetConnected(): void {\n if (this.#started) this.#resync();\n }\n\n /** Syncs the screen-reader span that stays when an earlier one leaves, silently. */\n srValueTargetDisconnected(): void {\n if (this.#started) this.#resync();\n }\n\n /**\n * Re-groups digits as the user types, preserving the caret position. Only an edit\n * of the display in charge is the user's: a display behind it is not read, and the\n * end of a composition its edit shows was settled before this runs. An edit the\n * event or the tracker reports as composing is the IME's draft, read when the\n * composition ends. Called without an event, it re-groups the display in charge —\n * while a composition runs, it leaves the draft and caret alone, since the end of\n * the composition re-groups what it confirms.\n */\n onInput(event?: Event): void {\n const source = event?.target ?? null;\n if (!this.#inCharge(source)) return;\n this.#holdUnsettled(false);\n if (event && this.#composition.consumesConfirmedInput(event)) return;\n const input = event as InputEvent | undefined;\n if (this.#composition.isComposing(input) || isCompositionInputType(input?.inputType)) {\n if (this.#composition.composingElement() === null && this.hasDisplayTarget) {\n this.#beginUnsettled(this.displayTarget);\n }\n return;\n }\n const unsettled = this.#unsettled !== null;\n if (unsettled) {\n if (source !== this.#unsettled || input?.isComposing !== false || !input.inputType) return;\n this.#unsettled = null;\n this.#formatHeld = null;\n }\n this.#reformat(false, \"edit\");\n if (unsettled && this.#owed(source)) this.#applyValueChange();\n }\n\n /**\n * Applies the fixed-precision rounding on blur — of the display in charge only. Called\n * without an event, it rounds the display in charge. While a composition runs — the\n * event or the tracker says so — the draft, the caret and the committed outputs stay\n * as they are, and the rounding is held: the `compositionend` that confirms or\n * cancels the composition rounds once; a move or disconnect that ends it, or a\n * composition the user starts in another display, rounds the text it leaves in the\n * same reading, reported as `reconcile`; any other end no `compositionend` reports\n * drops the rounding, and the next blur rounds. The rounding is held for the composition\n * running when it was asked, in the display that composition runs in, and never rounds\n * another one: it lapses when another display's composition ends, and goes with its\n * display when that display leaves with no composition the tracker follows going on in\n * it. A rounding applied at once spends one held for a composition only the event\n * reported.\n */\n format(event?: Event): void {\n if (!this.#inCharge(event?.target ?? null)) return;\n // The classification below forgets the display rendered last once it is back in charge.\n const returned = this.hasDisplayTarget && this.displayTarget === this.#departed;\n this.#holdUnsettled(false);\n // A blur can precede the target callback that would notice this arrival.\n if (\n this.hasDisplayTarget &&\n (this.displayTarget !== this.#renderedDisplay ||\n (returned && !this.#showsOwnRendering(this.displayTarget))) &&\n (event?.type === \"blur\" || event?.type === \"focusout\") &&\n this.#composition.composingElement() !== this.displayTarget\n ) {\n this.#beginUnsettled(this.displayTarget);\n }\n if (this.#unsettled !== null) {\n this.#formatHeld = { display: this.#unsettled, heard: false };\n return;\n }\n if (this.#composition.isComposing(event as CompositionSignal | undefined)) {\n const composing = this.#composition.composingElement();\n const display =\n composing ?? event?.target ?? (this.hasDisplayTarget ? this.displayTarget : null);\n this.#formatHeld = display === null ? null : { display, heard: composing !== null };\n if (composing === null && this.hasDisplayTarget && display === this.displayTarget) {\n this.#beginUnsettled(this.displayTarget);\n }\n } else {\n this.#formatHeld = null;\n this.#reformat(true, \"edit\");\n }\n }\n\n /** Takes the rounding held for the composition in `display`, and drops one held for another. */\n #takeFormatHeld(display: EventTarget | null): boolean {\n const held = this.#formatHeld;\n this.#formatHeld = null;\n return held !== null && held.display === display;\n }\n\n /**\n * Reads the page's text in the display in charge as a composition starts in it,\n * before its draft arrives: the composition before ended unheard, while every read\n * was held back, and the page wrote the text meanwhile — into a display that came\n * in charge, or into the one the user composes in again. It is read with the\n * declarations the page carries and reported as `reconcile`, without writing the\n * display, so the new composition goes on. Text still showing this controller's own\n * rendering, or a composition in a display behind, waits for that composition's end.\n */\n #readPageText(composing: EventTarget): void {\n if (\n this.#unsettled !== null ||\n !this.#inCharge(composing) ||\n this.#showsOwnRendering(this.displayTarget)\n )\n return;\n const { scan } = this.#readDisplay();\n this.#displayText.remember(this.displayTarget, this.displayTarget.value);\n this.#renderedDisplay = this.displayTarget;\n this.#reflect(scan.value, this.#render(scan.parts), \"reconcile\");\n }\n\n /**\n * Parses the display value, rewrites it grouped (optionally at fixed\n * precision), keeps the caret stable by significant characters, and syncs the\n * field, the screen-reader span, and the event `cause` selects.\n */\n #reformat(fixedPrecision: boolean, cause: Cause): void {\n if (!this.hasDisplayTarget || this.#unsettled === this.displayTarget) return;\n const raw = this.displayTarget.value;\n const { parts, value } = this.#scan(raw);\n\n if (fixedPrecision) {\n // Blur with no digits (an abandoned sign or dot) clears the entry.\n this.#renderFixed(value, cause);\n return;\n }\n\n const formatted = this.#render(parts);\n this.#showAtCaret(formatted, this.#significantBefore(raw, this.displayTarget.selectionStart));\n this.#reflect(value, formatted, cause);\n }\n\n /**\n * Writes `formatted` to the display as this controller's own rendering. Text\n * that moves keeps the caret just after the `anchor`-th significant character;\n * text that stays leaves the caret and any selection alone.\n */\n #showAtCaret(formatted: string, anchor: number | null): void {\n if (formatted !== this.displayTarget.value) {\n this.displayTarget.value = formatted;\n if (anchor !== null) this.#restoreCaret(formatted, anchor);\n }\n this.#displayText.remember(this.displayTarget, formatted);\n this.#renderedDisplay = this.displayTarget;\n }\n\n /**\n * Shows `value` at the fixed precision — an empty display for no value — and\n * reports a move under the event `cause` selects.\n */\n #renderFixed(value: number | null, cause: Cause): void {\n if (value === null) {\n this.#show(\"\");\n this.#reflect(null, \"\", cause);\n return;\n }\n const rounded = round(value, this.#precision);\n const formatted = this.#fixed.format(rounded);\n this.#show(formatted);\n this.#reflect(rounded, formatted, cause);\n }\n\n /** Writes `text` to the display as this controller's own rendering. */\n #show(text: string): void {\n this.#displayText.write(this.displayTarget, text);\n this.#renderedDisplay = this.displayTarget;\n }\n\n /**\n * The in-progress rendering: grouped integer, sign and fraction as typed.\n */\n #render(parts: EntryParts): string {\n const int = parts.int === \"\" ? \"\" : this.#grouping.format(BigInt(parts.int));\n const frac = parts.hasDot ? this.#decimal + parts.frac : \"\";\n return parts.sign + int + frac;\n }\n\n /** Restores the caret to sit just after the n-th significant character. */\n #restoreCaret(formatted: string, significantBefore: number): void {\n let seen = 0;\n let position = formatted.length;\n for (let i = 0; i < formatted.length; i++) {\n if (seen >= significantBefore) {\n position = i;\n break;\n }\n if (this.#isSignificant(formatted[i] as string)) seen += 1;\n }\n try {\n this.displayTarget.setSelectionRange(position, position);\n } catch {\n // Some hosts disallow selection on certain input states; the value is\n // already correct, so a failed caret restore is non-fatal.\n }\n }\n\n /**\n * Counts the characters before `caret` that survive into the rendering,\n * applying the same acceptance rules as {@link #scan} — a rejected keystroke\n * (a mid-string sign, a second decimal mark) must not shift the anchor. A host\n * that exposes no caret has no anchor.\n */\n #significantBefore(text: string, caret: number | null): number | null {\n if (caret === null) return null;\n let count = 0;\n let sawSign = false;\n let sawDigit = false;\n let sawDot = false;\n for (const ch of this.#normalize(text.slice(0, caret))) {\n if (ch >= \"0\" && ch <= \"9\") {\n count += 1;\n sawDigit = true;\n } else if ((ch === \"-\" || ch === \"+\") && !sawSign && !sawDigit && !sawDot) {\n count += 1;\n sawSign = true;\n } else if (this.#isDecimalMark(ch) && !sawDot) {\n count += 1;\n sawDot = true;\n }\n }\n return count;\n }\n\n /** Digits, signs, and the decimal mark anchor the caret; grouping does not. */\n #isSignificant(ch: string): boolean {\n if (ch >= \"0\" && ch <= \"9\") return true;\n if (ch === \"-\" || ch === \"+\") return true;\n return ch === this.#decimal || (ch === \".\" && this.#group !== \".\");\n }\n\n /** Writes the normalized value to the field, the SR span, and the empty hook. */\n #write(value: number | null): void {\n const isEmpty = value === null;\n if (this.hasFieldTarget) this.fieldTarget.value = isEmpty ? \"\" : String(value);\n if (this.hasSrValueTarget) {\n this.srValueTarget.textContent = isEmpty ? \"\" : this.#accessible.format(value);\n }\n this.element.toggleAttribute(`data-${this.identifier}-empty`, isEmpty);\n }\n\n /**\n * {@link #write}, then reports a moved value under the event `cause` selects:\n * `change` for the user's edit, `reconcile` for a move the page caused. The\n * display may hold an in-progress `-`, but a `null` value always rides with an\n * empty `formatted`, whichever event reports it, so consumers can treat the\n * pair as cleared.\n */\n #reflect(value: number | null, formatted: string, cause: Cause): void {\n this.#write(value);\n if (value === this.#lastValue) return;\n this.#lastValue = value;\n const detail = { value, formatted: value === null ? \"\" : formatted };\n if (cause === \"edit\") this.dispatch(\"change\", { detail });\n else this.dispatch(\"reconcile\", { detail });\n }\n\n /**\n * Scans arbitrary input text into its number-shaped parts and value. Keeps\n * digits, one leading sign, one decimal mark, and the fraction verbatim;\n * everything else (grouping, symbols, words) is dropped. An ASCII \".\" is only\n * a decimal mark where it is not the locale's grouping separator. Precision\n * plays no part here — rounding belongs to the blur-time format.\n */\n #scan(text: string): Scan {\n let sign: EntryParts[\"sign\"] = \"\";\n let int = \"\";\n let hasDot = false;\n let frac = \"\";\n for (const ch of this.#normalize(text)) {\n if (ch >= \"0\" && ch <= \"9\") {\n if (hasDot) frac += ch;\n else int += ch;\n } else if ((ch === \"-\" || ch === \"+\") && sign === \"\" && int === \"\" && !hasDot) {\n sign = ch;\n } else if (this.#isDecimalMark(ch) && !hasDot) {\n hasDot = true;\n }\n }\n const parts: EntryParts = { sign, int, hasDot, frac };\n // `Number` accepts \"12.\" and \".5\" alike, so one dotted form covers every\n // shape — and a digit-less entry (\"\", \"-\", \".\") reads as NaN, hence null.\n const value = Number(`${sign}${int}.${frac}`);\n return { parts, value: Number.isFinite(value) ? value : null };\n }\n\n /** Whether `ch` reads as this locale's decimal mark. */\n #isDecimalMark(ch: string): boolean {\n return ch === this.#decimal || (ch === \".\" && this.#group !== \".\");\n }\n\n /**\n * Re-syncs field / srValue / hook without dispatching: from the display, or —\n * while it is composing, when its text is not committed yet — from the value\n * last committed.\n */\n #resync(): void {\n if (!this.hasDisplayTarget) return;\n const unsettled = this.#trackUnsettled(false);\n if (this.#renderedDisplay === null) return;\n const value =\n unsettled || this.#composition.isComposing()\n ? this.#lastValue\n : this.#scan(this.displayTarget.value).value;\n this.#write(value);\n }\n\n /**\n * Keeps an unknown focused arrival out of parsing and rendering. A known accepted\n * value can repair derived output; without one the page's output stays untouched.\n * Losing focus alone supplies no confirmation and keeps this quarantine in place.\n */\n #holdUnsettled(arriving: boolean): boolean {\n if (!this.#trackUnsettled(arriving)) return false;\n this.#declarationsHeld = this.#declarationsChanged();\n this.#resync();\n return true;\n }\n\n /**\n * Classifies the current owner before any entry point reads a focused arrival. The\n * display rendered last that has left and come back in charge is an arrival here,\n * once, when it shows other text than that rendering.\n */\n #trackUnsettled(arriving: boolean): boolean {\n this.#forgetUnsettledOwner();\n if (!this.hasDisplayTarget) return false;\n const display = this.displayTarget;\n const returned = display === this.#departed;\n if (returned) this.#departed = null;\n if (\n this.#unsettled === null &&\n document.activeElement === display &&\n (arriving ||\n display !== this.#renderedDisplay ||\n (returned && !this.#showsOwnRendering(display))) &&\n this.#composition.composingElement() !== display\n ) {\n this.#beginUnsettled(display);\n }\n return this.#unsettled !== null;\n }\n\n /** Prepares only a first unknown entry, preserving held or accepted separators. */\n #beginUnsettled(display: HTMLInputElement): void {\n if (this.#unsettled === null && this.#renderedDisplay === null && this.#declarationsChanged()) {\n this.#revalidate();\n }\n this.#unsettled = display;\n }\n\n /** Pending text and rounding belong to one display, never its successor. */\n #forgetUnsettledOwner(): void {\n if (\n this.#unsettled !== null &&\n this.hasDisplayTarget &&\n this.#unsettled !== this.displayTarget\n ) {\n if (this.#formatHeld?.display === this.#unsettled) this.#formatHeld = null;\n this.#unsettled = null;\n }\n }\n\n /** A pending entry owns its text even when its composition start was not heard. */\n readonly #protectUnsettled = (event: Event): void => {\n this.#holdUnsettled(false);\n if (this.#unsettled === null || event.target !== this.#unsettled) return;\n const detail: { readonly attributeName?: unknown } | null = (event as CustomEvent).detail;\n if (detail?.attributeName === \"value\") event.preventDefault();\n };\n\n /**\n * The declarations the page carries now, validated: each falls back to its Value's\n * default when it cannot be interpreted (a malformed locale or currency tag, a\n * precision outside `Intl`'s 0–100 integer range). An empty locale is the language\n * around the controller.\n */\n #declared(): { locale: string | undefined; currency: string; precision: number } {\n const resolved = resolveLocale(this.element, this.localeValue);\n const usable = intlFormatter(Intl.NumberFormat, resolved, {});\n const locale = usable === null ? FALLBACK_LOCALE : resolved;\n let currency = \"\";\n if (this.currencyValue !== \"\") {\n const declaredCurrency = intlFormatter(Intl.NumberFormat, locale, {\n style: \"currency\",\n currency: this.currencyValue,\n });\n // An unknown code falls through to the plain-number accessible text.\n if (declaredCurrency !== null) currency = this.currencyValue;\n }\n return { locale, currency, precision: this.#safePrecision };\n }\n\n /**\n * What the end of a composition owes: whether reading the display in charge would\n * change what the last rendering applied. It would when a pass found the declarations\n * changed, when the display in charge is not the one rendered last, or when it shows\n * other text than that rendering left — a write the page made while the composition\n * held every read back. The display `composed` in is exempt from that last check: its\n * text is the composition's, read by its end or left to the next edit. A change taken\n * back, or a display that left and came back untouched, owes nothing.\n */\n #owed(composed: EventTarget | null): boolean {\n if (this.#declarationsHeld) return true;\n if (!this.hasDisplayTarget) return false;\n const display = this.displayTarget;\n return (\n display !== this.#renderedDisplay ||\n (display !== composed && !this.#showsOwnRendering(display))\n );\n }\n\n /** Whether the declarations the page carries differ, by value, from the ones taken in. */\n #declarationsChanged(): boolean {\n const { locale, currency, precision } = this.#declared();\n return locale !== this.#locale || currency !== this.#currency || precision !== this.#precision;\n }\n\n /** Takes in the validated declarations and rebuilds the cached formatters from them. */\n #revalidate(): void {\n this.#configured = true;\n this.#declarationsHeld = false;\n const declared = this.#declared();\n this.#locale = declared.locale;\n this.#currency = declared.currency;\n this.#precision = declared.precision;\n\n this.#grouping = intlFormatter(\n Intl.NumberFormat,\n this.#locale,\n { useGrouping: true, maximumFractionDigits: 0 },\n FALLBACK_LOCALE,\n );\n this.#fixed = intlFormatter(\n Intl.NumberFormat,\n this.#locale,\n {\n useGrouping: true,\n minimumFractionDigits: this.#precision,\n maximumFractionDigits: this.#precision,\n },\n FALLBACK_LOCALE,\n );\n this.#accessible = this.#currency\n ? intlFormatter(\n Intl.NumberFormat,\n this.#locale,\n { style: \"currency\", currency: this.#currency },\n FALLBACK_LOCALE,\n )\n : this.#fixed;\n\n const parts = intlFormatter(Intl.NumberFormat, this.#locale, {}, FALLBACK_LOCALE).formatToParts(\n 11111.1,\n );\n this.#group = parts.find((p) => p.type === \"group\")?.value ?? \",\";\n this.#decimal = parts.find((p) => p.type === \"decimal\")?.value ?? \".\";\n\n // Locales whose default numbering system is not Latin (ar-EG, fa-IR, …)\n // format with their own digits; mapping them back keeps the controller's\n // own output re-parseable to the same value.\n this.#digits.clear();\n const digitFormatter = intlFormatter(\n Intl.NumberFormat,\n this.#locale,\n { useGrouping: false },\n FALLBACK_LOCALE,\n );\n for (let i = 0; i <= 9; i++) {\n const digit = digitFormatter.format(i);\n if (digit !== String(i)) this.#digits.set(digit, String(i));\n }\n }\n\n /**\n * Maps the locale's own digits to ASCII, folds full-width forms (the digits,\n * signs, and marks an IME confirms as 0-9+-.,) through the shared\n * half-width mapping, and reads U+2212 MINUS SIGN as \"-\", which some locales'\n * formatted output uses for negatives.\n */\n #normalize(text: string): string {\n let out = \"\";\n for (const ch of text) {\n const mapped = this.#digits.get(ch);\n if (mapped !== undefined) {\n out += mapped;\n } else if (ch === \"−\") {\n out += \"-\";\n } else {\n out += halfWidthChar(ch);\n }\n }\n return out;\n }\n /** Current `precision` declaration resolved against its numeric contract. */\n get #safePrecision(): number {\n return this.#numbers.read(\n this,\n \"precision\",\n this.precisionValue,\n CurrencyInputController.values.precision.default,\n CurrencyInputController.valueConstraints.precision,\n );\n }\n}\n\n/** Rounds `value` to `precision` decimal places, avoiding `-0`; overflow keeps `value`. */\nfunction round(value: number, precision: number): number {\n const factor = 10 ** Math.max(0, precision);\n const rounded = Math.round(value * factor) / factor;\n if (!Number.isFinite(rounded)) return value;\n return rounded === 0 ? 0 : rounded;\n}\n"]}
|
|
@@ -27,9 +27,10 @@ import { Controller } from '@hotwired/stimulus';
|
|
|
27
27
|
* `-1`); arrow keys move both DOM focus and that tabbable position. Sort state is
|
|
28
28
|
* exposed via `aria-sort` on headers, selection via `aria-selected` on rows.
|
|
29
29
|
*
|
|
30
|
-
* `selectionchange` dispatches `{ rows: HTMLElement[] }`
|
|
31
|
-
* selection
|
|
32
|
-
* `{ column: HTMLElement, direction: "ascending" | "descending" | "none" }
|
|
30
|
+
* `selectionchange` dispatches `{ rows: HTMLElement[], reason: StateReason }` whenever
|
|
31
|
+
* the controller changes the selection itself, and `sort` dispatches
|
|
32
|
+
* `{ column: HTMLElement, direction: "ascending" | "descending" | "none", reason: StateReason }`;
|
|
33
|
+
* `reason` tells a user's choice from an `api` call.
|
|
33
34
|
*
|
|
34
35
|
* `reconcile` dispatches `{ rows: HTMLElement[] }` — the selected rows, as
|
|
35
36
|
* `selectionchange` carries them — when the page moves the selection instead: a
|
|
@@ -38,16 +39,17 @@ import { Controller } from '@hotwired/stimulus';
|
|
|
38
39
|
* arrives ahead of the selection in `single` mode, or a runtime `selection` that
|
|
39
40
|
* collapses it. One batch of such changes reports once, and only when the
|
|
40
41
|
* selected rows or the values they submit differ from the selection last settled
|
|
41
|
-
* — on connect, by
|
|
42
|
-
* reports nothing.
|
|
42
|
+
* — on connect, by a toggle (a user's choice or a `toggleSelect()` call), or by
|
|
43
|
+
* the previous `reconcile` — so connecting reports nothing.
|
|
43
44
|
*
|
|
44
45
|
* With a `fields` target the selected rows are mirrored into `name`d hidden
|
|
45
46
|
* inputs so the selection can be submitted and read server-side — one per
|
|
46
47
|
* selected row that carries a `data-value`, in DOM order; a row without one
|
|
47
48
|
* submits nothing. `form` points them at a `<form>` by id when the container
|
|
48
|
-
* sits outside it.
|
|
49
|
-
*
|
|
50
|
-
*
|
|
49
|
+
* sits outside it. When a selection the controller changes — a user's choice or a
|
|
50
|
+
* `toggleSelect()` call — moves the values the fields submit, the container emits
|
|
51
|
+
* a native bubbling `change`, the way a form control does, so `stimeo--auto-submit`
|
|
52
|
+
* and form-level validation hear it. The mirror is refreshed silently on connect,
|
|
51
53
|
* on a replacement container, on row churn, and whenever `selection`, `name` or
|
|
52
54
|
* `form` changes; a selection the page moved is reported by `reconcile` alone.
|
|
53
55
|
*
|