openms-insight 0.1.6__py3-none-any.whl → 0.1.8__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.
@@ -12,6 +12,8 @@ import streamlit as st
12
12
 
13
13
  # Configure debug logging for hash tracking
14
14
  _DEBUG_HASH_TRACKING = os.environ.get("SVC_DEBUG_HASH", "").lower() == "true"
15
+ # Debug logging for page navigation / state sync issues
16
+ _DEBUG_STATE_SYNC = os.environ.get("SVC_DEBUG_STATE", "").lower() == "true"
15
17
  _logger = logging.getLogger(__name__)
16
18
 
17
19
 
@@ -56,6 +58,11 @@ _COMPONENT_DATA_CACHE_KEY = "_svc_component_data_cache"
56
58
  # Stores annotation dataframes returned by components like SequenceView
57
59
  _COMPONENT_ANNOTATIONS_KEY = "_svc_component_annotations"
58
60
 
61
+ # Session state key for batch resend flag
62
+ # When any component requests data (e.g., after page navigation), we clear
63
+ # ALL hashes on the next render so all components get data in one rerun
64
+ _BATCH_RESEND_KEY = "_svc_batch_resend"
65
+
59
66
 
60
67
  def _get_component_cache() -> Dict[str, Any]:
61
68
  """Get per-component data cache from session state."""
@@ -203,6 +210,12 @@ def _prepare_vue_data_cached(
203
210
  # Try cache first (works for ALL components now)
204
211
  cached = _get_cached_vue_data(component_id, filter_state_hashable)
205
212
 
213
+ if _DEBUG_HASH_TRACKING:
214
+ cache_hit = cached is not None
215
+ _logger.warning(
216
+ f"[CacheDebug] {component._cache_id}: cache_hit={cache_hit}"
217
+ )
218
+
206
219
  if cached is not None:
207
220
  cached_data, cached_hash = cached
208
221
 
@@ -298,14 +311,17 @@ def render_component(
298
311
  """
299
312
  Render a component in Streamlit.
300
313
 
301
- This function:
302
- 1. Gets current state from StateManager
303
- 2. Calls component._prepare_vue_data() to get filtered data (cached!)
304
- 3. Computes hash for change detection
305
- 4. Only sends data if hash changed from last render (optimization)
306
- 5. Calls the Vue component with data payload
307
- 6. Updates StateManager from Vue response
308
- 7. Triggers st.rerun() if state changed
314
+ This function uses a two-phase approach to handle state synchronization:
315
+
316
+ Phase 1: Call vue_func with CACHED data to get Vue's request
317
+ Phase 2: Apply Vue's request, then prepare UPDATED data for next render
318
+
319
+ This order is critical because Vue's request (e.g., page change, sort) is only
320
+ available after calling vue_func(). By calling it first with cached data, we:
321
+ 1. Get Vue's request immediately
322
+ 2. Apply it to state BEFORE preparing data
323
+ 3. Prepare correct data for the next render
324
+ 4. Rerun to send the correct data
309
325
 
310
326
  Args:
311
327
  component: The component to render
@@ -316,140 +332,101 @@ def render_component(
316
332
  Returns:
317
333
  The value returned by the Vue component
318
334
  """
319
- # Get current state
320
- state = state_manager.get_state_for_vue()
321
-
322
- # Generate unique key if not provided (needed for cache)
323
- # Use cache_id instead of id(component) since components are recreated each rerun
324
- # Use JSON serialization for deterministic key generation (hash() can vary)
335
+ # === PHASE 0: Generate key and get component info ===
325
336
  if key is None:
326
337
  interactivity_str = json.dumps(component._interactivity or {}, sort_keys=True)
327
338
  key = f"svc_{component._cache_id}_{hashlib.md5(interactivity_str.encode()).hexdigest()[:8]}"
328
339
 
329
- # Check if component has required filters without values
330
- # Don't send potentially huge unfiltered datasets - wait for filter selection
331
- filters = getattr(component, "_filters", None) or {}
332
- filter_defaults = getattr(component, "_filter_defaults", None) or {}
333
-
334
- awaiting_filter = False
335
- if filters:
336
- # Check each filter - if no value AND no default, we're waiting
337
- for identifier in filters.keys():
338
- filter_value = state.get(identifier)
339
- has_default = identifier in filter_defaults
340
- if filter_value is None and not has_default:
341
- awaiting_filter = True
342
- break
343
-
344
- # Extract state keys that affect this component's data for cache key
345
- # This includes filters and any additional dependencies (e.g., zoom for heatmaps)
346
- # Uses get_state_dependencies() which can be overridden by subclasses
347
- state_keys = set(component.get_state_dependencies())
348
-
349
- # Build hashable version for cache key (converts dicts/lists to JSON strings)
350
- filter_state_hashable = tuple(
351
- sorted((k, _make_hashable(state.get(k))) for k in state_keys)
352
- )
353
-
354
- # Build original state dict for passing to _prepare_vue_data
355
- # (contains actual values, not JSON strings)
356
- relevant_state = {k: state.get(k) for k in state_keys}
357
-
358
- # Build component ID for cache (includes type to avoid collisions)
359
340
  component_type = component._get_vue_component_name()
360
341
  component_id = f"{component_type}:{key}"
361
-
362
- # Skip data preparation if awaiting required filter selection
363
- # This prevents sending huge unfiltered datasets
364
- if awaiting_filter:
365
- vue_data = {}
366
- data_hash = "awaiting_filter"
367
- else:
368
- # Get component data using per-component cache
369
- # Each component stores exactly one entry (current filter state)
370
- # - Filterless components: filter_state=() always → always cache hit
371
- # - Filtered components: cache hit when filter values unchanged
372
- vue_data, data_hash = _prepare_vue_data_cached(
373
- component, component_id, filter_state_hashable, relevant_state
374
- )
375
-
376
342
  component_args = component._get_component_args()
343
+ if height is not None:
344
+ component_args["height"] = height
345
+
346
+ # Batch resend: if any component requested data in previous run, clear ALL hashes
347
+ if st.session_state.get(_BATCH_RESEND_KEY):
348
+ st.session_state[_VUE_ECHOED_HASH_KEY] = {}
349
+ st.session_state.pop(_BATCH_RESEND_KEY, None)
377
350
 
378
351
  # Initialize hash cache in session state if needed
379
352
  if _VUE_ECHOED_HASH_KEY not in st.session_state:
380
353
  st.session_state[_VUE_ECHOED_HASH_KEY] = {}
381
354
 
382
- # Hash tracking key includes filter state so different filter values have separate tracking
383
- # This ensures data is re-sent when filters change (e.g., different spectrum selected)
384
- hash_tracking_key = f"{key}:{filter_state_hashable}"
355
+ # === PHASE 1: Get CACHED data from previous render ===
356
+ cache = _get_component_cache()
357
+ cached_entry = cache.get(component_id)
385
358
 
386
- # Get Vue's last-echoed hash for this component + filter state
387
- # This is what Vue reported having in its last response for this exact filter state
388
- vue_echoed_hash = st.session_state[_VUE_ECHOED_HASH_KEY].get(hash_tracking_key)
359
+ # Get current state for initial render (may be stale until we apply Vue's request)
360
+ initial_state = state_manager.get_state_for_vue()
389
361
 
390
- # Send data if Vue's hash doesn't match current hash
391
- # This handles: first render, data change, browser refresh, Vue hot reload
392
- # Vue echoes null/None if it has no data, so mismatch triggers send
393
- # IMPORTANT: Also send data if vue_echoed_hash is None - this means Vue
394
- # hasn't confirmed receipt yet (e.g., after page navigation destroys Vue component)
395
- # NOTE: Hash now correctly reflects annotation state (annotations included in hash),
396
- # so normal comparison works for all components including those with dynamic annotations
397
- data_changed = (vue_echoed_hash is None) or (vue_echoed_hash != data_hash)
362
+ # Pre-compute initial selections BEFORE Vue renders (for first render only)
363
+ if hasattr(component, "get_initial_selection"):
364
+ initial_selection = component.get_initial_selection(initial_state)
365
+ if initial_selection:
366
+ for identifier, value in initial_selection.items():
367
+ state_manager.set_selection(identifier, value)
368
+ initial_state = state_manager.get_state_for_vue()
398
369
 
399
- # Debug logging for hash tracking issues
400
- if _DEBUG_HASH_TRACKING:
401
- _logger.warning(
402
- f"[HashTrack] {component._cache_id}: "
403
- f"data_changed={data_changed}, "
404
- f"vue_echoed={vue_echoed_hash[:8] if vue_echoed_hash else 'None'}, "
405
- f"data_hash={data_hash[:8] if data_hash else 'None'}, "
406
- f"key={hash_tracking_key[:50]}..."
407
- )
370
+ # Compute current filter state for cache validity check
371
+ # This tells us what state the component SHOULD have data for
372
+ state_keys = set(component.get_state_dependencies())
373
+ current_filter_state = tuple(
374
+ sorted((k, _make_hashable(initial_state.get(k))) for k in state_keys)
375
+ )
408
376
 
409
- # Only include full data if hash changed
410
- if data_changed:
411
- # Convert any non-pandas data to pandas for Arrow serialization
412
- # pandas DataFrames are passed through (already optimal for Arrow)
413
- # Filter out _hash (internal metadata) but keep _plotConfig (needed by Vue)
414
- converted_data = {}
415
- for data_key, value in vue_data.items():
416
- if data_key == "_hash":
417
- # Skip internal hash metadata
418
- continue
419
- if isinstance(value, pl.LazyFrame):
420
- converted_data[data_key] = value.collect().to_pandas()
421
- elif isinstance(value, pl.DataFrame):
422
- converted_data[data_key] = value.to_pandas()
423
- else:
424
- converted_data[data_key] = value
425
- # pandas DataFrames pass through unchanged (optimal for Arrow)
377
+ # Check if cached data is VALID for current state
378
+ # KEY FIX: Only send data when cache matches current state
379
+ # - Before: Always sent cached data, even if stale (page 38 when Vue wants page 1)
380
+ # - Now: Only send if cache matches current state
381
+ cache_valid = False
382
+ if cached_entry is not None:
383
+ cached_state, cached_data, cached_hash = cached_entry
384
+ cache_valid = (cached_state == current_filter_state)
385
+ if _DEBUG_STATE_SYNC:
386
+ _logger.warning(
387
+ f"[Bridge:{component._cache_id}] Phase1: cache_valid={cache_valid}, "
388
+ f"cached_state={cached_state[:2] if cached_state else None}..., "
389
+ f"current_state={current_filter_state[:2] if current_filter_state else None}..."
390
+ )
391
+
392
+ # Build payload - only send data if cache is valid for current state
393
+ if cache_valid:
394
+ # Cache HIT - send cached data (it's correct for current state)
426
395
  data_payload = {
427
- **converted_data,
428
- "selection_store": state,
429
- "hash": data_hash,
396
+ **cached_data,
397
+ "selection_store": initial_state,
398
+ "hash": cached_hash,
430
399
  "dataChanged": True,
431
- "awaitingFilter": awaiting_filter,
400
+ "awaitingFilter": False,
432
401
  }
433
- # Note: We don't pre-set the hash here anymore. We trust Vue's echo
434
- # at the end of the render cycle. This ensures we detect when Vue
435
- # loses its data (e.g., page navigation) and needs it resent.
402
+ if _DEBUG_STATE_SYNC:
403
+ # Log pagination state for debugging
404
+ pagination_key = next((k for k in state_keys if "page" in k.lower()), None)
405
+ if pagination_key:
406
+ _logger.warning(
407
+ f"[Bridge:{component._cache_id}] Phase1: Cache HIT, "
408
+ f"sending data with hash={cached_hash[:8]}, "
409
+ f"pagination={initial_state.get(pagination_key)}"
410
+ )
436
411
  else:
437
- # Data unchanged - only send hash and state, Vue will use cached data
412
+ # Cache MISS (no cache, or state mismatch) - don't send stale data
413
+ # Vue will show loading or use its local cache
438
414
  data_payload = {
439
- "selection_store": state,
440
- "hash": data_hash,
415
+ "selection_store": initial_state,
416
+ "hash": "",
441
417
  "dataChanged": False,
442
- "awaitingFilter": awaiting_filter,
418
+ "awaitingFilter": False,
443
419
  }
444
-
445
- # Add height to component args if specified
446
- if height is not None:
447
- component_args["height"] = height
420
+ if _DEBUG_STATE_SYNC:
421
+ _logger.warning(
422
+ f"[Bridge:{component._cache_id}] Phase1: Cache MISS, "
423
+ f"not sending data (cached_entry={cached_entry is not None})"
424
+ )
448
425
 
449
426
  # Component layout: [[{componentArgs: {...}}]]
450
427
  components = [[{"componentArgs": component_args}]]
451
428
 
452
- # Call Vue component
429
+ # === PHASE 2: Call vue_func to get Vue's request ===
453
430
  vue_func = get_vue_component_function()
454
431
 
455
432
  kwargs = {
@@ -460,36 +437,141 @@ def render_component(
460
437
  if height is not None:
461
438
  kwargs["height"] = height
462
439
 
440
+ if _DEBUG_STATE_SYNC:
441
+ _logger.warning(
442
+ f"[Bridge:{component._cache_id}] Phase2: Calling vue_func to get request"
443
+ )
444
+
463
445
  result = vue_func(**kwargs)
464
446
 
465
- # Update state from Vue response
447
+ # === PHASE 3: Apply Vue's request FIRST ===
448
+ state_changed = False
466
449
  if result is not None:
467
- # Store Vue's echoed hash for next render comparison
468
- # Only store non-None hashes - Vue echoes None during initialization
469
- # before receiving data, which would corrupt our tracking. Preserving
470
- # the previous valid hash prevents unnecessary data resends.
450
+ # Debug logging: what we received from Vue
451
+ if _DEBUG_STATE_SYNC:
452
+ vue_counter = result.get("counter")
453
+ vue_keys = [k for k in result.keys() if not k.startswith("_")]
454
+ _logger.warning(
455
+ f"[Bridge:{component._cache_id}] Phase3: Received counter={vue_counter}, "
456
+ f"keys={vue_keys}, _requestData={result.get('_requestData', False)}"
457
+ )
458
+
459
+ # Store Vue's echoed hash
471
460
  vue_hash = result.get("_vueDataHash")
472
461
  if vue_hash is not None:
473
- st.session_state[_VUE_ECHOED_HASH_KEY][hash_tracking_key] = vue_hash
462
+ st.session_state[_VUE_ECHOED_HASH_KEY][key] = vue_hash
463
+
464
+ # Apply Vue's state update FIRST - this is the key fix!
465
+ state_changed = state_manager.update_from_vue(result)
466
+
467
+ # Check if Vue is requesting data resend
468
+ if result.get("_requestData", False):
469
+ st.session_state[_BATCH_RESEND_KEY] = True
470
+
471
+ # === PHASE 4: Get UPDATED state and prepare data ===
472
+ # Now state reflects Vue's request (e.g., new page number after click)
473
+ state = state_manager.get_state_for_vue()
474
474
 
475
- # Check if Vue is requesting data due to cache miss (e.g., after page navigation)
476
- # Vue's cache was empty when it received dataChanged=false, so it needs data resent
477
- request_data = result.get("_requestData", False)
478
- if request_data:
479
- # Clear our stored hash to force data resend on next render
480
- st.session_state[_VUE_ECHOED_HASH_KEY].pop(hash_tracking_key, None)
475
+ # Check if component has required filters without values
476
+ filters = getattr(component, "_filters", None) or {}
477
+ filter_defaults = getattr(component, "_filter_defaults", None) or {}
481
478
 
482
- # Capture annotations from Vue (e.g., from SequenceView)
483
- # Use hash-based change detection for robustness
479
+ awaiting_filter = False
480
+ for identifier in filters.keys():
481
+ if state.get(identifier) is None and identifier not in filter_defaults:
482
+ awaiting_filter = True
483
+ break
484
+
485
+ if not awaiting_filter:
486
+ # Extract state keys that affect this component's data
487
+ state_keys = set(component.get_state_dependencies())
488
+ relevant_state = {k: state.get(k) for k in state_keys}
489
+
490
+ # Build hashable version for cache key
491
+ filter_state_hashable = tuple(
492
+ sorted((k, _make_hashable(state.get(k))) for k in state_keys)
493
+ )
494
+
495
+ if _DEBUG_HASH_TRACKING:
496
+ _logger.warning(
497
+ f"[CacheKey] {component._cache_id}: state_keys={list(state_keys)}"
498
+ )
499
+ for k in state_keys:
500
+ if "page" in k.lower():
501
+ _logger.warning(
502
+ f"[CacheKey] {component._cache_id}: {k}={state.get(k)}"
503
+ )
504
+
505
+ # Prepare data with UPDATED state (includes Vue's request)
506
+ # This may also call set_selection() to override (e.g., sort resets page)
507
+ vue_data, data_hash = _prepare_vue_data_cached(
508
+ component, component_id, filter_state_hashable, relevant_state
509
+ )
510
+
511
+ # Check if Python overrode state during _prepare_vue_data
512
+ # (e.g., table.py sets page to last page after sort)
513
+ final_state = state_manager.get_state_for_vue()
514
+ if final_state != state:
515
+ state_changed = True
516
+ if _DEBUG_STATE_SYNC:
517
+ _logger.warning(
518
+ f"[Bridge:{component._cache_id}] Phase4: Python overrode state"
519
+ )
520
+ else:
521
+ vue_data = {}
522
+ data_hash = "awaiting_filter"
523
+ filter_state_hashable = ()
524
+
525
+ _logger.info(f"[bridge] Phase4: {component._cache_id} prepared data, hash={data_hash[:8] if data_hash else 'None'}")
526
+
527
+ # === PHASE 5: Cache data for next render ===
528
+ if vue_data:
529
+ # Convert for caching (Arrow serialization requires pandas)
530
+ converted_data = {}
531
+ for data_key, value in vue_data.items():
532
+ if data_key == "_hash":
533
+ continue
534
+ if isinstance(value, pl.LazyFrame):
535
+ converted_data[data_key] = value.collect().to_pandas()
536
+ elif isinstance(value, pl.DataFrame):
537
+ converted_data[data_key] = value.to_pandas()
538
+ else:
539
+ converted_data[data_key] = value
540
+
541
+ # Store in cache for next render
542
+ cache[component_id] = (filter_state_hashable, converted_data, data_hash)
543
+
544
+ # If cache was invalid at Phase 1, we didn't send data to Vue (dataChanged=False).
545
+ # Trigger a rerun so the newly cached data gets sent on the next render.
546
+ # This handles cross-component filter changes where the affected component
547
+ # needs to receive updated data (e.g., new total_rows/total_pages).
548
+ if not cache_valid:
549
+ state_changed = True
550
+ if _DEBUG_STATE_SYNC:
551
+ _logger.warning(
552
+ f"[Bridge:{component._cache_id}] Phase5: Cache was invalid, "
553
+ f"triggering rerun to send newly cached data"
554
+ )
555
+
556
+ if _DEBUG_STATE_SYNC:
557
+ # Log what we're caching for debugging
558
+ pagination_key = next((k for k, v in filter_state_hashable if "page" in k.lower()), None)
559
+ if pagination_key:
560
+ pagination_val = next((v for k, v in filter_state_hashable if k == pagination_key), None)
561
+ _logger.warning(
562
+ f"[Bridge:{component._cache_id}] Phase5: Cached data with hash={data_hash[:8]}, "
563
+ f"filter_state includes {pagination_key}={pagination_val}"
564
+ )
565
+
566
+ # Handle annotations from Vue (e.g., from SequenceView)
567
+ if result is not None:
484
568
  annotations = result.get("_annotations")
485
569
  annotations_changed = False
486
570
 
487
571
  if annotations is not None:
488
- # Compute hash of new annotations
489
572
  peak_ids = annotations.get("peak_id", [])
490
573
  new_hash = hash(tuple(peak_ids)) if peak_ids else 0
491
574
 
492
- # Compare with stored hash
493
575
  ann_hash_key = f"_svc_ann_hash_{key}"
494
576
  old_hash = st.session_state.get(ann_hash_key)
495
577
 
@@ -499,17 +581,27 @@ def render_component(
499
581
 
500
582
  _store_component_annotations(key, annotations)
501
583
  else:
502
- # Annotations cleared - check if we had annotations before
503
584
  ann_hash_key = f"_svc_ann_hash_{key}"
504
585
  if st.session_state.get(ann_hash_key) is not None:
505
586
  annotations_changed = True
506
587
  st.session_state[ann_hash_key] = None
507
588
 
508
- # Update state and rerun if state changed OR annotations changed OR data requested
509
- # Hash comparison will naturally detect changes on the next render
510
- state_changed = state_manager.update_from_vue(result)
511
- if state_changed or annotations_changed or request_data:
512
- st.rerun()
589
+ if annotations_changed:
590
+ state_changed = True
591
+
592
+ # === PHASE 6: Rerun if state changed ===
593
+ # This will send the UPDATED data (now in cache) to Vue
594
+ if state_changed:
595
+ if _DEBUG_STATE_SYNC:
596
+ _logger.warning(
597
+ f"[Bridge:{component._cache_id}] Phase6: RERUN triggered, "
598
+ f"next render will have cache HIT"
599
+ )
600
+ st.rerun()
601
+ elif _DEBUG_STATE_SYNC:
602
+ _logger.warning(
603
+ f"[Bridge:{component._cache_id}] Phase6: No rerun needed, state_changed=False"
604
+ )
513
605
 
514
606
  return result
515
607
 
@@ -531,8 +623,8 @@ def _hash_data(data: Dict[str, Any]) -> str:
531
623
 
532
624
  hash_parts = []
533
625
  for key, value in sorted(data.items()):
534
- # Skip internal metadata but NOT dynamic annotation columns
535
- if key.startswith("_") and not key.startswith("_dynamic"):
626
+ # Skip internal metadata but NOT dynamic annotation columns or pagination
627
+ if key.startswith("_") and not key.startswith("_dynamic") and not key.startswith("_pagination"):
536
628
  continue
537
629
  if isinstance(value, pd.DataFrame):
538
630
  # Efficient hash for DataFrames
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: openms-insight
3
- Version: 0.1.6
3
+ Version: 0.1.8
4
4
  Summary: Interactive visualization components for mass spectrometry data in Streamlit
5
5
  Project-URL: Homepage, https://github.com/t0mdavid-m/OpenMS-Insight
6
6
  Project-URL: Documentation, https://github.com/t0mdavid-m/OpenMS-Insight#readme
@@ -47,7 +47,7 @@ Interactive visualization components for mass spectrometry data in Streamlit, ba
47
47
  - **Memory-efficient preprocessing** via subprocess isolation
48
48
  - **Automatic disk caching** with config-based invalidation
49
49
  - **Cache reconstruction** - components can be restored from cache without re-specifying configuration
50
- - **Table component** (Tabulator.js) with filtering, sorting, go-to, pagination, CSV export
50
+ - **Table component** (Tabulator.js) with server-side pagination, filtering, sorting, go-to, CSV export
51
51
  - **Line plot component** (Plotly.js) with highlighting, annotations, zoom
52
52
  - **Heatmap component** (Plotly scattergl) with multi-resolution downsampling for millions of points
53
53
  - **Volcano plot component** for differential expression visualization with significance thresholds
@@ -167,7 +167,7 @@ Table(
167
167
  - `index_field`: Column used as unique row identifier (default: 'id')
168
168
  - `go_to_fields`: Columns available in "Go to" navigation
169
169
  - `initial_sort`: Default sort configuration
170
- - `pagination`: Enable pagination for large tables (default: True)
170
+ - `pagination`: Enable server-side pagination (default: True). Only the current page of data is sent to the browser, dramatically reducing memory usage for large datasets.
171
171
  - `page_size`: Rows per page (default: 100)
172
172
 
173
173
  **Custom formatters:**
@@ -1,30 +1,30 @@
1
- openms_insight/__init__.py,sha256=fqk7DwB4PY-BOi2-uT9FCARBYen_3SPmnSnScVKBnQY,1111
1
+ openms_insight/__init__.py,sha256=b4H9k0fPVZ6jCiJ4QVSwzlUQnyElF6ZwAlDI8fdPMJE,1111
2
2
  openms_insight/components/__init__.py,sha256=Lcg-D0FILta-YVgMJBlWMKLKC5G5kXOqdy9hBOENABw,233
3
3
  openms_insight/components/heatmap.py,sha256=psrdW4gNzZR1jAIox9YS9EHaZaTRrDHFR0t2_0APU9Y,47214
4
4
  openms_insight/components/lineplot.py,sha256=I-JPvDzCr3Nu8Boc1V4D8QQ1bHgTqvM6CbeoIe7zJ-s,30896
5
5
  openms_insight/components/sequenceview.py,sha256=0pDOE0xeoc1-85QZNGdNwwoBwXi-5MFfeb9pCcOi6rc,30274
6
- openms_insight/components/table.py,sha256=wmq1rjGVe4Ef0SAf5p85pfVCeyLlVevZnxBc9EIg2uk,16458
6
+ openms_insight/components/table.py,sha256=6r0SiWTDSJS6AHNCy4jTxByY9aCt4ussCQFKKrEg77U,36955
7
7
  openms_insight/components/volcanoplot.py,sha256=F-cmYxJMKXVK-aYJpifp8be7nB8hkQd2kLi9DrBElD8,15155
8
8
  openms_insight/core/__init__.py,sha256=EPjKX_FFQRgO8mWHs59I-o0BiuzEMzEU1Pfu9YOfLC4,338
9
- openms_insight/core/base.py,sha256=6hxmII90LlbwTy06BJvUdJjXpd8Oqjqdt452AJixJSs,19742
9
+ openms_insight/core/base.py,sha256=h0OaubHLky8mk7Yfy3HTIimsz-DfuNRgLfotJu3pZVw,20517
10
10
  openms_insight/core/cache.py,sha256=3fnPDWjuWUnxazK2XflcUIeRZZPQ3N45kAKYu-xGBKw,1197
11
11
  openms_insight/core/registry.py,sha256=Hak80Jqhx0qa4gbd1YolNZnM6xBrS8I4U_X7zC0bQ8Y,2108
12
- openms_insight/core/state.py,sha256=_vNYxYHYFgIigbkqYwkIO6cBGFJyF2VN9dr7CBEAQbY,6873
12
+ openms_insight/core/state.py,sha256=CMToxxNyGnqxMccwOcn7FwABNTzjjTsgsMrJCZOZc2o,12438
13
13
  openms_insight/core/subprocess_preprocess.py,sha256=m9FbAAFy9Do1Exlh-m4Wo-LDwv6yHlEI4klz5OVwemc,3133
14
14
  openms_insight/preprocessing/__init__.py,sha256=xoGdhNVrX8Ty3ywmyaCcWAO3a6QlKceO1xxsy1C8ZTI,596
15
15
  openms_insight/preprocessing/compression.py,sha256=T4YbX9PUlfTfPit_kpuLZn8hYpqLYu3xtTme_CG2ymc,12241
16
16
  openms_insight/preprocessing/filtering.py,sha256=fkmaIXfR5hfjyWfaMYqaeybMHaZjvUZYaKCqvxPOWMQ,14152
17
17
  openms_insight/preprocessing/scatter.py,sha256=2ifCNTUKHEW9UVpv4z9c5GaLnz5zw9o1119IenzAe9s,4703
18
18
  openms_insight/rendering/__init__.py,sha256=ApHvKeh87yY4GTIEai-tCeIXpNbwOXWlmcmIwMMRZYc,198
19
- openms_insight/rendering/bridge.py,sha256=Z8njsnVI-TCE6Beep7b2him-Hy8o2eYVDD-RxiHWDXo,20727
19
+ openms_insight/rendering/bridge.py,sha256=3FiMlNL3hBHue28-0RWP9pt7GaNeczZbQwZl4cupXlc,23935
20
20
  openms_insight/js-component/dist/index.html,sha256=LSJ3B_YmGUrCCdZ1UaZO2p6Wqsih6nTH62Z_0uZxpD8,430
21
21
  openms_insight/js-component/dist/assets/index.css,sha256=wFvo7FbG132LL7uw0slXfrL_oSQ8u2RKL1DW9hD9-kk,884264
22
- openms_insight/js-component/dist/assets/index.js,sha256=lgH9C14vHdrRN48hjcHhjCRqOIJlHq3zduFveW7jSnE,6075088
22
+ openms_insight/js-component/dist/assets/index.js,sha256=aqGc3g7XLTRr7ptEgoA3XDu5oMS47yxxjUBXgansIo0,6091480
23
23
  openms_insight/js-component/dist/assets/materialdesignicons-webfont.eot,sha256=CxgxBNL8XyYZbnc8d72vLgVQn9QlnS0V7O3Kebh-hPk,1307880
24
24
  openms_insight/js-component/dist/assets/materialdesignicons-webfont.ttf,sha256=YeirpaTpgf4iz3yOi82-oAR251xiw38Bv37jM2HWhCg,1307660
25
25
  openms_insight/js-component/dist/assets/materialdesignicons-webfont.woff,sha256=pZKKDVwvYk5G-Y2bFcL2AEU3f3xZTdeKF1kTLqO0Y-s,587984
26
26
  openms_insight/js-component/dist/assets/materialdesignicons-webfont.woff2,sha256=Zi_vqPL4qVwYWI0hd0eJwQfGTnccvmWmmvRikcQxGvw,403216
27
- openms_insight-0.1.6.dist-info/METADATA,sha256=S--OtU9cCzBuY9UaIaDNuMivpOMPQaXwSZEAXqFpQu8,16670
28
- openms_insight-0.1.6.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
29
- openms_insight-0.1.6.dist-info/licenses/LICENSE,sha256=INFF4rOMmpah7Oi14hLqu7NTOsx56KRRNChAAUcfh2E,1823
30
- openms_insight-0.1.6.dist-info/RECORD,,
27
+ openms_insight-0.1.8.dist-info/METADATA,sha256=l5aHKdSHf5z046vRxq8xJLDN7UywXFfLEcLTxfEEn4Q,16787
28
+ openms_insight-0.1.8.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
29
+ openms_insight-0.1.8.dist-info/licenses/LICENSE,sha256=INFF4rOMmpah7Oi14hLqu7NTOsx56KRRNChAAUcfh2E,1823
30
+ openms_insight-0.1.8.dist-info/RECORD,,