cjm-transcript-segmentation 0.0.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- cjm_transcript_segmentation/__init__.py +1 -0
- cjm_transcript_segmentation/_modidx.py +150 -0
- cjm_transcript_segmentation/components/__init__.py +0 -0
- cjm_transcript_segmentation/components/callbacks.py +56 -0
- cjm_transcript_segmentation/components/card_stack_config.py +36 -0
- cjm_transcript_segmentation/components/helpers.py +83 -0
- cjm_transcript_segmentation/components/keyboard_config.py +165 -0
- cjm_transcript_segmentation/components/segment_card.py +310 -0
- cjm_transcript_segmentation/components/step_renderer.py +253 -0
- cjm_transcript_segmentation/html_ids.py +48 -0
- cjm_transcript_segmentation/models.py +79 -0
- cjm_transcript_segmentation/routes/__init__.py +0 -0
- cjm_transcript_segmentation/routes/card_stack.py +306 -0
- cjm_transcript_segmentation/routes/core.py +178 -0
- cjm_transcript_segmentation/routes/handlers.py +512 -0
- cjm_transcript_segmentation/routes/init.py +93 -0
- cjm_transcript_segmentation/services/__init__.py +0 -0
- cjm_transcript_segmentation/services/segmentation.py +207 -0
- cjm_transcript_segmentation/utils.py +61 -0
- cjm_transcript_segmentation-0.0.1.dist-info/LICENSE +201 -0
- cjm_transcript_segmentation-0.0.1.dist-info/METADATA +1104 -0
- cjm_transcript_segmentation-0.0.1.dist-info/RECORD +25 -0
- cjm_transcript_segmentation-0.0.1.dist-info/WHEEL +5 -0
- cjm_transcript_segmentation-0.0.1.dist-info/entry_points.txt +2 -0
- cjm_transcript_segmentation-0.0.1.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.0.1"
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
# Autogenerated by nbdev
|
|
2
|
+
|
|
3
|
+
d = { 'settings': { 'branch': 'main',
|
|
4
|
+
'doc_baseurl': '/cjm-transcript-segmentation',
|
|
5
|
+
'doc_host': 'https://cj-mills.github.io',
|
|
6
|
+
'git_url': 'https://github.com/cj-mills/cjm-transcript-segmentation',
|
|
7
|
+
'lib_path': 'cjm_transcript_segmentation'},
|
|
8
|
+
'syms': { 'cjm_transcript_segmentation.components.callbacks': { 'cjm_transcript_segmentation.components.callbacks._generate_focus_change_script': ( 'components/callbacks.html#_generate_focus_change_script',
|
|
9
|
+
'cjm_transcript_segmentation/components/callbacks.py'),
|
|
10
|
+
'cjm_transcript_segmentation.components.callbacks.generate_seg_callbacks_script': ( 'components/callbacks.html#generate_seg_callbacks_script',
|
|
11
|
+
'cjm_transcript_segmentation/components/callbacks.py')},
|
|
12
|
+
'cjm_transcript_segmentation.components.card_stack_config': {},
|
|
13
|
+
'cjm_transcript_segmentation.components.helpers': { 'cjm_transcript_segmentation.components.helpers._get_card_width': ( 'components/helpers.html#_get_card_width',
|
|
14
|
+
'cjm_transcript_segmentation/components/helpers.py'),
|
|
15
|
+
'cjm_transcript_segmentation.components.helpers._get_focused_index': ( 'components/helpers.html#_get_focused_index',
|
|
16
|
+
'cjm_transcript_segmentation/components/helpers.py'),
|
|
17
|
+
'cjm_transcript_segmentation.components.helpers._get_history': ( 'components/helpers.html#_get_history',
|
|
18
|
+
'cjm_transcript_segmentation/components/helpers.py'),
|
|
19
|
+
'cjm_transcript_segmentation.components.helpers._get_is_auto_mode': ( 'components/helpers.html#_get_is_auto_mode',
|
|
20
|
+
'cjm_transcript_segmentation/components/helpers.py'),
|
|
21
|
+
'cjm_transcript_segmentation.components.helpers._get_segmentation_state': ( 'components/helpers.html#_get_segmentation_state',
|
|
22
|
+
'cjm_transcript_segmentation/components/helpers.py'),
|
|
23
|
+
'cjm_transcript_segmentation.components.helpers._get_segments': ( 'components/helpers.html#_get_segments',
|
|
24
|
+
'cjm_transcript_segmentation/components/helpers.py'),
|
|
25
|
+
'cjm_transcript_segmentation.components.helpers._get_visible_count': ( 'components/helpers.html#_get_visible_count',
|
|
26
|
+
'cjm_transcript_segmentation/components/helpers.py'),
|
|
27
|
+
'cjm_transcript_segmentation.components.helpers._is_initialized': ( 'components/helpers.html#_is_initialized',
|
|
28
|
+
'cjm_transcript_segmentation/components/helpers.py')},
|
|
29
|
+
'cjm_transcript_segmentation.components.keyboard_config': { 'cjm_transcript_segmentation.components.keyboard_config.create_seg_kb_parts': ( 'components/keyboard_config.html#create_seg_kb_parts',
|
|
30
|
+
'cjm_transcript_segmentation/components/keyboard_config.py')},
|
|
31
|
+
'cjm_transcript_segmentation.components.segment_card': { 'cjm_transcript_segmentation.components.segment_card._render_card_actions': ( 'components/segment_card.html#_render_card_actions',
|
|
32
|
+
'cjm_transcript_segmentation/components/segment_card.py'),
|
|
33
|
+
'cjm_transcript_segmentation.components.segment_card._render_card_metadata': ( 'components/segment_card.html#_render_card_metadata',
|
|
34
|
+
'cjm_transcript_segmentation/components/segment_card.py'),
|
|
35
|
+
'cjm_transcript_segmentation.components.segment_card._render_split_mode_content': ( 'components/segment_card.html#_render_split_mode_content',
|
|
36
|
+
'cjm_transcript_segmentation/components/segment_card.py'),
|
|
37
|
+
'cjm_transcript_segmentation.components.segment_card._render_view_mode_content': ( 'components/segment_card.html#_render_view_mode_content',
|
|
38
|
+
'cjm_transcript_segmentation/components/segment_card.py'),
|
|
39
|
+
'cjm_transcript_segmentation.components.segment_card.create_segment_card_renderer': ( 'components/segment_card.html#create_segment_card_renderer',
|
|
40
|
+
'cjm_transcript_segmentation/components/segment_card.py'),
|
|
41
|
+
'cjm_transcript_segmentation.components.segment_card.render_segment_card': ( 'components/segment_card.html#render_segment_card',
|
|
42
|
+
'cjm_transcript_segmentation/components/segment_card.py')},
|
|
43
|
+
'cjm_transcript_segmentation.components.step_renderer': { 'cjm_transcript_segmentation.components.step_renderer.render_seg_column_body': ( 'components/step_renderer.html#render_seg_column_body',
|
|
44
|
+
'cjm_transcript_segmentation/components/step_renderer.py'),
|
|
45
|
+
'cjm_transcript_segmentation.components.step_renderer.render_seg_footer_content': ( 'components/step_renderer.html#render_seg_footer_content',
|
|
46
|
+
'cjm_transcript_segmentation/components/step_renderer.py'),
|
|
47
|
+
'cjm_transcript_segmentation.components.step_renderer.render_seg_mini_stats_text': ( 'components/step_renderer.html#render_seg_mini_stats_text',
|
|
48
|
+
'cjm_transcript_segmentation/components/step_renderer.py'),
|
|
49
|
+
'cjm_transcript_segmentation.components.step_renderer.render_seg_stats': ( 'components/step_renderer.html#render_seg_stats',
|
|
50
|
+
'cjm_transcript_segmentation/components/step_renderer.py'),
|
|
51
|
+
'cjm_transcript_segmentation.components.step_renderer.render_toolbar': ( 'components/step_renderer.html#render_toolbar',
|
|
52
|
+
'cjm_transcript_segmentation/components/step_renderer.py')},
|
|
53
|
+
'cjm_transcript_segmentation.html_ids': { 'cjm_transcript_segmentation.html_ids.SegmentationHtmlIds': ( 'html_ids.html#segmentationhtmlids',
|
|
54
|
+
'cjm_transcript_segmentation/html_ids.py'),
|
|
55
|
+
'cjm_transcript_segmentation.html_ids.SegmentationHtmlIds.as_selector': ( 'html_ids.html#segmentationhtmlids.as_selector',
|
|
56
|
+
'cjm_transcript_segmentation/html_ids.py'),
|
|
57
|
+
'cjm_transcript_segmentation.html_ids.SegmentationHtmlIds.segment_card': ( 'html_ids.html#segmentationhtmlids.segment_card',
|
|
58
|
+
'cjm_transcript_segmentation/html_ids.py')},
|
|
59
|
+
'cjm_transcript_segmentation.models': { 'cjm_transcript_segmentation.models.SegmentationStepState': ( 'models.html#segmentationstepstate',
|
|
60
|
+
'cjm_transcript_segmentation/models.py'),
|
|
61
|
+
'cjm_transcript_segmentation.models.SegmentationUrls': ( 'models.html#segmentationurls',
|
|
62
|
+
'cjm_transcript_segmentation/models.py'),
|
|
63
|
+
'cjm_transcript_segmentation.models.TextSegment': ( 'models.html#textsegment',
|
|
64
|
+
'cjm_transcript_segmentation/models.py'),
|
|
65
|
+
'cjm_transcript_segmentation.models.TextSegment.from_dict': ( 'models.html#textsegment.from_dict',
|
|
66
|
+
'cjm_transcript_segmentation/models.py'),
|
|
67
|
+
'cjm_transcript_segmentation.models.TextSegment.to_dict': ( 'models.html#textsegment.to_dict',
|
|
68
|
+
'cjm_transcript_segmentation/models.py')},
|
|
69
|
+
'cjm_transcript_segmentation.routes.card_stack': { 'cjm_transcript_segmentation.routes.card_stack._build_nav_response': ( 'routes/card_stack.html#_build_nav_response',
|
|
70
|
+
'cjm_transcript_segmentation/routes/card_stack.py'),
|
|
71
|
+
'cjm_transcript_segmentation.routes.card_stack._build_slots_oob': ( 'routes/card_stack.html#_build_slots_oob',
|
|
72
|
+
'cjm_transcript_segmentation/routes/card_stack.py'),
|
|
73
|
+
'cjm_transcript_segmentation.routes.card_stack._handle_seg_enter_split_mode': ( 'routes/card_stack.html#_handle_seg_enter_split_mode',
|
|
74
|
+
'cjm_transcript_segmentation/routes/card_stack.py'),
|
|
75
|
+
'cjm_transcript_segmentation.routes.card_stack._handle_seg_exit_split_mode': ( 'routes/card_stack.html#_handle_seg_exit_split_mode',
|
|
76
|
+
'cjm_transcript_segmentation/routes/card_stack.py'),
|
|
77
|
+
'cjm_transcript_segmentation.routes.card_stack._handle_seg_navigate': ( 'routes/card_stack.html#_handle_seg_navigate',
|
|
78
|
+
'cjm_transcript_segmentation/routes/card_stack.py'),
|
|
79
|
+
'cjm_transcript_segmentation.routes.card_stack._handle_seg_save_width': ( 'routes/card_stack.html#_handle_seg_save_width',
|
|
80
|
+
'cjm_transcript_segmentation/routes/card_stack.py'),
|
|
81
|
+
'cjm_transcript_segmentation.routes.card_stack._handle_seg_update_viewport': ( 'routes/card_stack.html#_handle_seg_update_viewport',
|
|
82
|
+
'cjm_transcript_segmentation/routes/card_stack.py'),
|
|
83
|
+
'cjm_transcript_segmentation.routes.card_stack._make_renderer': ( 'routes/card_stack.html#_make_renderer',
|
|
84
|
+
'cjm_transcript_segmentation/routes/card_stack.py'),
|
|
85
|
+
'cjm_transcript_segmentation.routes.card_stack.init_card_stack_router': ( 'routes/card_stack.html#init_card_stack_router',
|
|
86
|
+
'cjm_transcript_segmentation/routes/card_stack.py')},
|
|
87
|
+
'cjm_transcript_segmentation.routes.core': { 'cjm_transcript_segmentation.routes.core.SegContext': ( 'routes/core.html#segcontext',
|
|
88
|
+
'cjm_transcript_segmentation/routes/core.py'),
|
|
89
|
+
'cjm_transcript_segmentation.routes.core._build_card_stack_state': ( 'routes/core.html#_build_card_stack_state',
|
|
90
|
+
'cjm_transcript_segmentation/routes/core.py'),
|
|
91
|
+
'cjm_transcript_segmentation.routes.core._get_seg_state': ( 'routes/core.html#_get_seg_state',
|
|
92
|
+
'cjm_transcript_segmentation/routes/core.py'),
|
|
93
|
+
'cjm_transcript_segmentation.routes.core._get_selection_state': ( 'routes/core.html#_get_selection_state',
|
|
94
|
+
'cjm_transcript_segmentation/routes/core.py'),
|
|
95
|
+
'cjm_transcript_segmentation.routes.core._load_seg_context': ( 'routes/core.html#_load_seg_context',
|
|
96
|
+
'cjm_transcript_segmentation/routes/core.py'),
|
|
97
|
+
'cjm_transcript_segmentation.routes.core._push_history': ( 'routes/core.html#_push_history',
|
|
98
|
+
'cjm_transcript_segmentation/routes/core.py'),
|
|
99
|
+
'cjm_transcript_segmentation.routes.core._to_segments': ( 'routes/core.html#_to_segments',
|
|
100
|
+
'cjm_transcript_segmentation/routes/core.py'),
|
|
101
|
+
'cjm_transcript_segmentation.routes.core._update_seg_state': ( 'routes/core.html#_update_seg_state',
|
|
102
|
+
'cjm_transcript_segmentation/routes/core.py')},
|
|
103
|
+
'cjm_transcript_segmentation.routes.handlers': { 'cjm_transcript_segmentation.routes.handlers.SegInitResult': ( 'routes/handlers.html#seginitresult',
|
|
104
|
+
'cjm_transcript_segmentation/routes/handlers.py'),
|
|
105
|
+
'cjm_transcript_segmentation.routes.handlers._build_mutation_response': ( 'routes/handlers.html#_build_mutation_response',
|
|
106
|
+
'cjm_transcript_segmentation/routes/handlers.py'),
|
|
107
|
+
'cjm_transcript_segmentation.routes.handlers._handle_seg_ai_split': ( 'routes/handlers.html#_handle_seg_ai_split',
|
|
108
|
+
'cjm_transcript_segmentation/routes/handlers.py'),
|
|
109
|
+
'cjm_transcript_segmentation.routes.handlers._handle_seg_init': ( 'routes/handlers.html#_handle_seg_init',
|
|
110
|
+
'cjm_transcript_segmentation/routes/handlers.py'),
|
|
111
|
+
'cjm_transcript_segmentation.routes.handlers._handle_seg_merge': ( 'routes/handlers.html#_handle_seg_merge',
|
|
112
|
+
'cjm_transcript_segmentation/routes/handlers.py'),
|
|
113
|
+
'cjm_transcript_segmentation.routes.handlers._handle_seg_reset': ( 'routes/handlers.html#_handle_seg_reset',
|
|
114
|
+
'cjm_transcript_segmentation/routes/handlers.py'),
|
|
115
|
+
'cjm_transcript_segmentation.routes.handlers._handle_seg_split': ( 'routes/handlers.html#_handle_seg_split',
|
|
116
|
+
'cjm_transcript_segmentation/routes/handlers.py'),
|
|
117
|
+
'cjm_transcript_segmentation.routes.handlers._handle_seg_undo': ( 'routes/handlers.html#_handle_seg_undo',
|
|
118
|
+
'cjm_transcript_segmentation/routes/handlers.py'),
|
|
119
|
+
'cjm_transcript_segmentation.routes.handlers.init_workflow_router': ( 'routes/handlers.html#init_workflow_router',
|
|
120
|
+
'cjm_transcript_segmentation/routes/handlers.py')},
|
|
121
|
+
'cjm_transcript_segmentation.routes.init': { 'cjm_transcript_segmentation.routes.init.init_segmentation_routers': ( 'routes/init.html#init_segmentation_routers',
|
|
122
|
+
'cjm_transcript_segmentation/routes/init.py')},
|
|
123
|
+
'cjm_transcript_segmentation.services.segmentation': { 'cjm_transcript_segmentation.services.segmentation.SegmentationService': ( 'services/segmentation.html#segmentationservice',
|
|
124
|
+
'cjm_transcript_segmentation/services/segmentation.py'),
|
|
125
|
+
'cjm_transcript_segmentation.services.segmentation.SegmentationService.__init__': ( 'services/segmentation.html#segmentationservice.__init__',
|
|
126
|
+
'cjm_transcript_segmentation/services/segmentation.py'),
|
|
127
|
+
'cjm_transcript_segmentation.services.segmentation.SegmentationService.ensure_loaded': ( 'services/segmentation.html#segmentationservice.ensure_loaded',
|
|
128
|
+
'cjm_transcript_segmentation/services/segmentation.py'),
|
|
129
|
+
'cjm_transcript_segmentation.services.segmentation.SegmentationService.is_available': ( 'services/segmentation.html#segmentationservice.is_available',
|
|
130
|
+
'cjm_transcript_segmentation/services/segmentation.py'),
|
|
131
|
+
'cjm_transcript_segmentation.services.segmentation.SegmentationService.split_combined_sources_async': ( 'services/segmentation.html#segmentationservice.split_combined_sources_async',
|
|
132
|
+
'cjm_transcript_segmentation/services/segmentation.py'),
|
|
133
|
+
'cjm_transcript_segmentation.services.segmentation.SegmentationService.split_sentences': ( 'services/segmentation.html#segmentationservice.split_sentences',
|
|
134
|
+
'cjm_transcript_segmentation/services/segmentation.py'),
|
|
135
|
+
'cjm_transcript_segmentation.services.segmentation.SegmentationService.split_sentences_async': ( 'services/segmentation.html#segmentationservice.split_sentences_async',
|
|
136
|
+
'cjm_transcript_segmentation/services/segmentation.py'),
|
|
137
|
+
'cjm_transcript_segmentation.services.segmentation.merge_text_segments': ( 'services/segmentation.html#merge_text_segments',
|
|
138
|
+
'cjm_transcript_segmentation/services/segmentation.py'),
|
|
139
|
+
'cjm_transcript_segmentation.services.segmentation.reconstruct_source_blocks': ( 'services/segmentation.html#reconstruct_source_blocks',
|
|
140
|
+
'cjm_transcript_segmentation/services/segmentation.py'),
|
|
141
|
+
'cjm_transcript_segmentation.services.segmentation.reindex_segments': ( 'services/segmentation.html#reindex_segments',
|
|
142
|
+
'cjm_transcript_segmentation/services/segmentation.py'),
|
|
143
|
+
'cjm_transcript_segmentation.services.segmentation.split_segment_at_position': ( 'services/segmentation.html#split_segment_at_position',
|
|
144
|
+
'cjm_transcript_segmentation/services/segmentation.py')},
|
|
145
|
+
'cjm_transcript_segmentation.utils': { 'cjm_transcript_segmentation.utils.calculate_segment_stats': ( 'utils.html#calculate_segment_stats',
|
|
146
|
+
'cjm_transcript_segmentation/utils.py'),
|
|
147
|
+
'cjm_transcript_segmentation.utils.count_words': ( 'utils.html#count_words',
|
|
148
|
+
'cjm_transcript_segmentation/utils.py'),
|
|
149
|
+
'cjm_transcript_segmentation.utils.word_index_to_char_position': ( 'utils.html#word_index_to_char_position',
|
|
150
|
+
'cjm_transcript_segmentation/utils.py')}}}
|
|
File without changes
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
"""JavaScript callback generators for Phase 2 segmentation keyboard interaction"""
|
|
2
|
+
|
|
3
|
+
# AUTOGENERATED! DO NOT EDIT! File to edit: ../../nbs/components/callbacks.ipynb.
|
|
4
|
+
|
|
5
|
+
# %% auto #0
|
|
6
|
+
__all__ = ['generate_seg_callbacks_script']
|
|
7
|
+
|
|
8
|
+
# %% ../../nbs/components/callbacks.ipynb #9c3ae2f7
|
|
9
|
+
from cjm_fasthtml_card_stack.core.config import CardStackConfig
|
|
10
|
+
from cjm_fasthtml_card_stack.core.html_ids import CardStackHtmlIds
|
|
11
|
+
from cjm_fasthtml_card_stack.core.button_ids import CardStackButtonIds
|
|
12
|
+
from cjm_fasthtml_card_stack.core.models import CardStackUrls
|
|
13
|
+
from cjm_fasthtml_card_stack.js.core import generate_card_stack_js
|
|
14
|
+
|
|
15
|
+
# %% ../../nbs/components/callbacks.ipynb #eee98aa2
|
|
16
|
+
def _generate_focus_change_script(
|
|
17
|
+
focus_input_id: str, # ID of hidden input for focused segment index
|
|
18
|
+
) -> str: # JavaScript code for focus change callback
|
|
19
|
+
"""Generate JavaScript for card focus change handling."""
|
|
20
|
+
return f"""
|
|
21
|
+
// Called when card focus changes (from keyboard navigation library)
|
|
22
|
+
window.onCardFocusChange = function(item, index, zoneId) {{
|
|
23
|
+
// Update hidden input with focused segment index
|
|
24
|
+
const input = document.getElementById('{focus_input_id}');
|
|
25
|
+
if (input && item) {{
|
|
26
|
+
input.value = item.dataset.segmentIndex || index;
|
|
27
|
+
}}
|
|
28
|
+
}};
|
|
29
|
+
"""
|
|
30
|
+
|
|
31
|
+
# %% ../../nbs/components/callbacks.ipynb #328ed0e1
|
|
32
|
+
def generate_seg_callbacks_script(
|
|
33
|
+
ids:CardStackHtmlIds, # Card stack HTML IDs
|
|
34
|
+
button_ids:CardStackButtonIds, # Card stack button IDs
|
|
35
|
+
config:CardStackConfig, # Card stack configuration
|
|
36
|
+
urls:CardStackUrls, # Card stack URL bundle
|
|
37
|
+
container_id:str, # ID of the segmentation container (parent of card stack)
|
|
38
|
+
focus_input_id:str, # ID of hidden input for focused segment index
|
|
39
|
+
) -> any: # Script element with all JavaScript callbacks
|
|
40
|
+
"""Generate JavaScript for segmentation keyboard interaction.
|
|
41
|
+
|
|
42
|
+
Delegates card-stack-generic JS to the library and injects the
|
|
43
|
+
focus change callback via extra_scripts.
|
|
44
|
+
"""
|
|
45
|
+
seg_scripts = (
|
|
46
|
+
_generate_focus_change_script(focus_input_id),
|
|
47
|
+
)
|
|
48
|
+
|
|
49
|
+
return generate_card_stack_js(
|
|
50
|
+
ids=ids,
|
|
51
|
+
button_ids=button_ids,
|
|
52
|
+
config=config,
|
|
53
|
+
urls=urls,
|
|
54
|
+
container_id=container_id,
|
|
55
|
+
extra_scripts=seg_scripts
|
|
56
|
+
)
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"""Card stack configuration constants for the Phase 2 segmentation UI"""
|
|
2
|
+
|
|
3
|
+
# AUTOGENERATED! DO NOT EDIT! File to edit: ../../nbs/components/card_stack_config.ipynb.
|
|
4
|
+
|
|
5
|
+
# %% auto #0
|
|
6
|
+
__all__ = ['SEG_CS_CONFIG', 'SEG_CS_IDS', 'SEG_CS_BTN_IDS', 'SEG_TS_CONFIG', 'SEG_TS_IDS']
|
|
7
|
+
|
|
8
|
+
# %% ../../nbs/components/card_stack_config.ipynb #cs-cfg-constants
|
|
9
|
+
from cjm_fasthtml_card_stack.core.config import CardStackConfig, CardStackStyleConfig
|
|
10
|
+
from cjm_fasthtml_card_stack.core.html_ids import CardStackHtmlIds
|
|
11
|
+
from cjm_fasthtml_card_stack.core.button_ids import CardStackButtonIds
|
|
12
|
+
|
|
13
|
+
from cjm_fasthtml_token_selector.core.config import TokenSelectorConfig
|
|
14
|
+
from cjm_fasthtml_token_selector.core.html_ids import TokenSelectorHtmlIds
|
|
15
|
+
|
|
16
|
+
SEG_CS_CONFIG = CardStackConfig(
|
|
17
|
+
prefix="sd-seg",
|
|
18
|
+
disable_scroll_in_modes=("split",),
|
|
19
|
+
style=CardStackStyleConfig(
|
|
20
|
+
viewport_padding_x='0.0rem',
|
|
21
|
+
viewport_padding_y='0.0rem'
|
|
22
|
+
)
|
|
23
|
+
)
|
|
24
|
+
|
|
25
|
+
SEG_CS_IDS = CardStackHtmlIds(prefix=SEG_CS_CONFIG.prefix)
|
|
26
|
+
SEG_CS_BTN_IDS = CardStackButtonIds(prefix=SEG_CS_CONFIG.prefix)
|
|
27
|
+
|
|
28
|
+
SEG_TS_CONFIG = TokenSelectorConfig(
|
|
29
|
+
prefix="sd-seg-ts",
|
|
30
|
+
selection_mode="gap",
|
|
31
|
+
initial_delay=200,
|
|
32
|
+
repeat_interval=90,
|
|
33
|
+
throttle_floor=50,
|
|
34
|
+
)
|
|
35
|
+
|
|
36
|
+
SEG_TS_IDS = TokenSelectorHtmlIds(prefix=SEG_TS_CONFIG.prefix)
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
"""Shared helper functions for the segmentation module"""
|
|
2
|
+
|
|
3
|
+
# AUTOGENERATED! DO NOT EDIT! File to edit: ../../nbs/components/helpers.ipynb.
|
|
4
|
+
|
|
5
|
+
# %% auto #0
|
|
6
|
+
__all__ = []
|
|
7
|
+
|
|
8
|
+
# %% ../../nbs/components/helpers.ipynb #c3d4e5f6
|
|
9
|
+
from typing import Any, Dict, List
|
|
10
|
+
|
|
11
|
+
from cjm_fasthtml_interactions.core.context import InteractionContext
|
|
12
|
+
|
|
13
|
+
from cjm_transcript_segmentation.models import (
|
|
14
|
+
TextSegment, SegmentationStepState
|
|
15
|
+
)
|
|
16
|
+
|
|
17
|
+
# %% ../../nbs/components/helpers.ipynb #e5f6a7b8
|
|
18
|
+
def _get_segmentation_state(
|
|
19
|
+
ctx: InteractionContext # Interaction context with state
|
|
20
|
+
) -> SegmentationStepState: # Typed segmentation step state
|
|
21
|
+
"""Get the full segmentation step state from context."""
|
|
22
|
+
step_states = ctx.state.get("step_states", {})
|
|
23
|
+
return step_states.get("segmentation", {})
|
|
24
|
+
|
|
25
|
+
# %% ../../nbs/components/helpers.ipynb #rvxle78vfj
|
|
26
|
+
def _get_segments(
|
|
27
|
+
ctx: InteractionContext # Interaction context with state
|
|
28
|
+
) -> List[TextSegment]: # List of TextSegment objects
|
|
29
|
+
"""Get the list of segments from step state as TextSegment objects."""
|
|
30
|
+
state = _get_segmentation_state(ctx)
|
|
31
|
+
segment_dicts = state.get("segments", [])
|
|
32
|
+
return [TextSegment.from_dict(s) for s in segment_dicts]
|
|
33
|
+
|
|
34
|
+
# %% ../../nbs/components/helpers.ipynb #2dliq35ph
|
|
35
|
+
def _is_initialized(
|
|
36
|
+
ctx: InteractionContext # Interaction context with state
|
|
37
|
+
) -> bool: # True if segments have been initialized
|
|
38
|
+
"""Check if segments have been initialized."""
|
|
39
|
+
state = _get_segmentation_state(ctx)
|
|
40
|
+
return state.get("is_initialized", False)
|
|
41
|
+
|
|
42
|
+
# %% ../../nbs/components/helpers.ipynb #1zg9dsfg9za
|
|
43
|
+
def _get_visible_count(
|
|
44
|
+
ctx: InteractionContext, # Interaction context with state
|
|
45
|
+
default: int = 3, # Default visible card count
|
|
46
|
+
) -> int: # Number of visible cards in viewport
|
|
47
|
+
"""Get the stored visible card count."""
|
|
48
|
+
state = _get_segmentation_state(ctx)
|
|
49
|
+
return state.get("visible_count", default)
|
|
50
|
+
|
|
51
|
+
# %% ../../nbs/components/helpers.ipynb #ev9120vz98m
|
|
52
|
+
def _get_card_width(
|
|
53
|
+
ctx: InteractionContext, # Interaction context with state
|
|
54
|
+
default: int = 80, # Default card width in rem
|
|
55
|
+
) -> int: # Card stack width in rem
|
|
56
|
+
"""Get the stored card stack width."""
|
|
57
|
+
state = _get_segmentation_state(ctx)
|
|
58
|
+
return state.get("card_width", default)
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
#| export
|
|
62
|
+
def _get_is_auto_mode(
|
|
63
|
+
ctx: InteractionContext, # Interaction context with state
|
|
64
|
+
) -> bool: # Whether card count is in auto-adjust mode
|
|
65
|
+
"""Get whether the card count is in auto-adjust mode."""
|
|
66
|
+
state = _get_segmentation_state(ctx)
|
|
67
|
+
return state.get("is_auto_mode", False)
|
|
68
|
+
|
|
69
|
+
# %% ../../nbs/components/helpers.ipynb #5qlapc1birw
|
|
70
|
+
def _get_history(
|
|
71
|
+
ctx: InteractionContext # Interaction context with state
|
|
72
|
+
) -> List[List[Dict[str, Any]]]: # Stack of segment snapshots
|
|
73
|
+
"""Get the undo history stack."""
|
|
74
|
+
state = _get_segmentation_state(ctx)
|
|
75
|
+
return state.get("history", [])
|
|
76
|
+
|
|
77
|
+
# %% ../../nbs/components/helpers.ipynb #nnrf1g1wu5h
|
|
78
|
+
def _get_focused_index(
|
|
79
|
+
ctx: InteractionContext # Interaction context with state
|
|
80
|
+
) -> int: # Currently focused segment index
|
|
81
|
+
"""Get the currently focused segment index."""
|
|
82
|
+
state = _get_segmentation_state(ctx)
|
|
83
|
+
return state.get("focused_index", 0)
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
"""Segmentation-specific keyboard actions, modes, and zone configuration"""
|
|
2
|
+
|
|
3
|
+
# AUTOGENERATED! DO NOT EDIT! File to edit: ../../nbs/components/keyboard_config.ipynb.
|
|
4
|
+
|
|
5
|
+
# %% auto #0
|
|
6
|
+
__all__ = ['SD_SEG_ENTER_SPLIT_BTN', 'SD_SEG_EXIT_SPLIT_BTN', 'SD_SEG_SPLIT_BTN', 'SD_SEG_MERGE_BTN', 'SD_SEG_UNDO_BTN',
|
|
7
|
+
'create_seg_kb_parts']
|
|
8
|
+
|
|
9
|
+
# %% ../../nbs/components/keyboard_config.ipynb #c3d4e5f6
|
|
10
|
+
from typing import Tuple
|
|
11
|
+
|
|
12
|
+
# Keyboard navigation library
|
|
13
|
+
from cjm_fasthtml_keyboard_navigation.core.actions import KeyAction
|
|
14
|
+
from cjm_fasthtml_keyboard_navigation.core.focus_zone import FocusZone
|
|
15
|
+
|
|
16
|
+
# Card stack library
|
|
17
|
+
from cjm_fasthtml_card_stack.core.config import CardStackConfig
|
|
18
|
+
from cjm_fasthtml_card_stack.core.html_ids import CardStackHtmlIds
|
|
19
|
+
from cjm_fasthtml_card_stack.core.button_ids import CardStackButtonIds
|
|
20
|
+
from cjm_fasthtml_card_stack.keyboard.actions import (
|
|
21
|
+
create_card_stack_focus_zone, create_card_stack_nav_actions,
|
|
22
|
+
)
|
|
23
|
+
|
|
24
|
+
# Token selector library
|
|
25
|
+
from cjm_fasthtml_token_selector.keyboard.actions import (
|
|
26
|
+
create_token_selector_mode, create_token_nav_actions,
|
|
27
|
+
)
|
|
28
|
+
from cjm_transcript_segmentation.components.card_stack_config import (
|
|
29
|
+
SEG_TS_CONFIG,
|
|
30
|
+
)
|
|
31
|
+
|
|
32
|
+
# %% ../../nbs/components/keyboard_config.ipynb #e5f6a7b8
|
|
33
|
+
# Button IDs for keyboard actions — segmentation operations (workflow-specific)
|
|
34
|
+
SD_SEG_ENTER_SPLIT_BTN = "sd-seg-enter-split-btn"
|
|
35
|
+
SD_SEG_EXIT_SPLIT_BTN = "sd-seg-exit-split-btn"
|
|
36
|
+
SD_SEG_SPLIT_BTN = "sd-seg-split-btn"
|
|
37
|
+
SD_SEG_MERGE_BTN = "sd-seg-merge-btn"
|
|
38
|
+
SD_SEG_UNDO_BTN = "sd-seg-undo-btn"
|
|
39
|
+
|
|
40
|
+
# %% ../../nbs/components/keyboard_config.ipynb #a7b8c9d0
|
|
41
|
+
def create_seg_kb_parts(
|
|
42
|
+
ids:CardStackHtmlIds, # Card stack HTML IDs
|
|
43
|
+
button_ids:CardStackButtonIds, # Card stack button IDs for navigation
|
|
44
|
+
config:CardStackConfig, # Card stack configuration
|
|
45
|
+
) -> Tuple[FocusZone, tuple, tuple]: # (zone, actions, modes)
|
|
46
|
+
"""Create segmentation-specific keyboard building blocks.
|
|
47
|
+
|
|
48
|
+
Returns a zone, actions tuple, and modes tuple for assembly into a shared
|
|
49
|
+
ZoneManager by the combined-level keyboard config.
|
|
50
|
+
"""
|
|
51
|
+
# Card stack zone from library — no data_attributes needed since
|
|
52
|
+
# onCardFocusChange callback updates the card stack's hidden input directly
|
|
53
|
+
card_zone = create_card_stack_focus_zone(
|
|
54
|
+
ids=ids,
|
|
55
|
+
on_focus_change="onCardFocusChange",
|
|
56
|
+
)
|
|
57
|
+
zone_id = card_zone.id
|
|
58
|
+
|
|
59
|
+
# Card stack navigation actions from library (arrows, page jump, first/last, width)
|
|
60
|
+
nav_actions = create_card_stack_nav_actions(
|
|
61
|
+
zone_id=zone_id,
|
|
62
|
+
button_ids=button_ids,
|
|
63
|
+
config=config,
|
|
64
|
+
disable_in_modes=("split",),
|
|
65
|
+
)
|
|
66
|
+
|
|
67
|
+
# --- Token selector: split mode definition (library factory) ---
|
|
68
|
+
split_mode = create_token_selector_mode(
|
|
69
|
+
SEG_TS_CONFIG,
|
|
70
|
+
mode_name="split",
|
|
71
|
+
indicator_text="Split Mode",
|
|
72
|
+
exit_key="",
|
|
73
|
+
exit_on_zone_change=False,
|
|
74
|
+
)
|
|
75
|
+
|
|
76
|
+
# --- Token selector: Home/End navigation in split mode ---
|
|
77
|
+
token_nav_actions = create_token_nav_actions(
|
|
78
|
+
SEG_TS_CONFIG,
|
|
79
|
+
zone_id=zone_id,
|
|
80
|
+
mode_name="split",
|
|
81
|
+
)
|
|
82
|
+
|
|
83
|
+
# --- Consumer-specific: segmentation operation actions ---
|
|
84
|
+
# All seg actions are zone-restricted to prevent firing when alignment zone is active
|
|
85
|
+
seg_zone_ids = (zone_id,)
|
|
86
|
+
|
|
87
|
+
seg_actions = (
|
|
88
|
+
# Enter split mode (Enter or Space when NOT in split mode)
|
|
89
|
+
KeyAction(
|
|
90
|
+
key="Enter",
|
|
91
|
+
htmx_trigger=SD_SEG_ENTER_SPLIT_BTN,
|
|
92
|
+
zone_ids=seg_zone_ids,
|
|
93
|
+
mode_enter="split",
|
|
94
|
+
not_modes=("split",),
|
|
95
|
+
description="Enter split mode",
|
|
96
|
+
hint_group="Segmentation",
|
|
97
|
+
),
|
|
98
|
+
KeyAction(
|
|
99
|
+
key=" ",
|
|
100
|
+
htmx_trigger=SD_SEG_ENTER_SPLIT_BTN,
|
|
101
|
+
zone_ids=seg_zone_ids,
|
|
102
|
+
mode_enter="split",
|
|
103
|
+
not_modes=("split",),
|
|
104
|
+
description="Enter split mode",
|
|
105
|
+
hint_group="Segmentation",
|
|
106
|
+
show_in_hints=False,
|
|
107
|
+
),
|
|
108
|
+
|
|
109
|
+
# Execute split (Enter or Space when IN split mode)
|
|
110
|
+
KeyAction(
|
|
111
|
+
key="Enter",
|
|
112
|
+
htmx_trigger=SD_SEG_SPLIT_BTN,
|
|
113
|
+
zone_ids=seg_zone_ids,
|
|
114
|
+
mode_exit=True,
|
|
115
|
+
mode_names=("split",),
|
|
116
|
+
description="Split at caret",
|
|
117
|
+
hint_group="Split Mode",
|
|
118
|
+
),
|
|
119
|
+
KeyAction(
|
|
120
|
+
key=" ",
|
|
121
|
+
htmx_trigger=SD_SEG_SPLIT_BTN,
|
|
122
|
+
zone_ids=seg_zone_ids,
|
|
123
|
+
mode_exit=True,
|
|
124
|
+
mode_names=("split",),
|
|
125
|
+
description="Split at caret",
|
|
126
|
+
hint_group="Split Mode",
|
|
127
|
+
show_in_hints=False,
|
|
128
|
+
),
|
|
129
|
+
|
|
130
|
+
# Exit split mode (Escape when IN split mode)
|
|
131
|
+
KeyAction(
|
|
132
|
+
key="Escape",
|
|
133
|
+
htmx_trigger=SD_SEG_EXIT_SPLIT_BTN,
|
|
134
|
+
zone_ids=seg_zone_ids,
|
|
135
|
+
mode_exit=True,
|
|
136
|
+
mode_names=("split",),
|
|
137
|
+
description="Exit split mode",
|
|
138
|
+
hint_group="Split Mode",
|
|
139
|
+
),
|
|
140
|
+
|
|
141
|
+
# Merge with previous (Backspace when NOT in split mode)
|
|
142
|
+
KeyAction(
|
|
143
|
+
key="Backspace",
|
|
144
|
+
htmx_trigger=SD_SEG_MERGE_BTN,
|
|
145
|
+
zone_ids=seg_zone_ids,
|
|
146
|
+
not_modes=("split",),
|
|
147
|
+
description="Merge with previous",
|
|
148
|
+
hint_group="Segmentation",
|
|
149
|
+
),
|
|
150
|
+
|
|
151
|
+
# Undo (Ctrl+Z in any mode, but zone-restricted)
|
|
152
|
+
KeyAction(
|
|
153
|
+
key="z",
|
|
154
|
+
modifiers=frozenset({"ctrl"}),
|
|
155
|
+
htmx_trigger=SD_SEG_UNDO_BTN,
|
|
156
|
+
zone_ids=seg_zone_ids,
|
|
157
|
+
description="Undo",
|
|
158
|
+
hint_group="General",
|
|
159
|
+
),
|
|
160
|
+
)
|
|
161
|
+
|
|
162
|
+
actions = (*nav_actions, *seg_actions, *token_nav_actions)
|
|
163
|
+
modes = (split_mode,)
|
|
164
|
+
|
|
165
|
+
return card_zone, actions, modes
|