@datagrok/helm 3.0.1 → 3.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/CLAUDE.md +78 -92
  3. package/dist/489.js +2 -0
  4. package/dist/489.js.map +1 -0
  5. package/dist/package-test.js +1 -1
  6. package/dist/package-test.js.map +1 -1
  7. package/dist/package.js +1 -1
  8. package/dist/package.js.map +1 -1
  9. package/files/samples/helm-showcase.csv +7 -9
  10. package/package.json +12 -9
  11. package/src/helm-helper.ts +3 -0
  12. package/src/package-api.ts +1 -0
  13. package/src/package-test.ts +0 -4
  14. package/src/package.g.ts +2 -0
  15. package/src/package.ts +4 -1
  16. package/src/tests/helm-input-tests.ts +3 -3
  17. package/src/utils/helm-grid-cell-renderer.ts +3 -0
  18. package/test-console-output-1.log +344 -0
  19. package/test-playwright-report.json +118 -0
  20. package/test-record-1.mp4 +0 -0
  21. package/test-report-playwright.csv +1 -0
  22. package/tsconfig.json +2 -1
  23. package/dist/137.js +0 -2
  24. package/dist/137.js.map +0 -1
  25. package/dist/323.js +0 -2
  26. package/dist/323.js.map +0 -1
  27. package/dist/455.js +0 -2
  28. package/dist/455.js.map +0 -1
  29. package/dist/657.js +0 -2
  30. package/dist/657.js.map +0 -1
  31. package/dist/782.js +0 -2
  32. package/dist/782.js.map +0 -1
  33. package/dist/884.js +0 -2
  34. package/dist/884.js.map +0 -1
  35. package/dist/94.js +0 -2
  36. package/dist/94.js.map +0 -1
  37. package/dist/libraries_bio_src_monomer-works_seq-to-molfile-worker_ts.js +0 -16420
  38. package/dist/libraries_bio_src_monomer-works_seq-to-molfile-worker_ts.js.map +0 -1
  39. package/dist/package-dojo.js +0 -2
  40. package/dist/package-dojo.js.map +0 -1
  41. package/dist/vendors-HELM_node_modules_lru-cache_dist_esm_index_js.js +0 -1560
  42. package/dist/vendors-HELM_node_modules_lru-cache_dist_esm_index_js.js.map +0 -1
package/CHANGELOG.md CHANGED
@@ -1,10 +1,23 @@
1
1
  # Helm changelog
2
2
 
3
+ ## 3.0.3
4
+
5
+ * Moved the Helm Playwright E2E suite into the package (playwright/); helpers from @datagrok-libraries/test/src/playwright
6
+ * Improved HELM layout engine for conjugate cases
7
+
3
8
  ## 3.0.1 (2026-06-20)
4
9
 
10
+ ### Features
11
+
5
12
  * Migration to Datagrok Helm Web Editor
6
13
  * Support for new Helm Service, editor, parsing and rendering
7
14
  * Helm editor panes including molecular structure, composition and conversion
15
+ * Monomer highlighting in HELM grid cells: cells respond to macromolecule highlight events, drawing a translucent overlay around the highlighted monomers
16
+ * Improved RNA splitting: support for complex RNA and complex triplets, and more inclusive matching
17
+
18
+ ### Bug Fixes
19
+
20
+ * Fixed async renderer invalidation
8
21
 
9
22
  ## 2.13.4 (2026-03-31)
10
23
 
package/CLAUDE.md CHANGED
@@ -2,111 +2,102 @@
2
2
 
3
3
  ## Overview
4
4
 
5
- **Helm** (`@datagrok/helm`) is a Datagrok plugin providing full support for **HELM notation** (Hierarchical Editing Language for Macromolecules) — importing, detecting, rendering, editing, and conversion. It wraps the Pistoia HELM Web Editor and Scilligence JSDraw2 libraries, integrating them into the Datagrok platform with custom cell renderers, input widgets, and monomer library management.
5
+ **Helm** (`@datagrok/helm`) is a Datagrok plugin providing full support for **HELM notation** (Hierarchical Editing Language for Macromolecules) — importing, detecting, rendering, editing, and conversion. It is built on the **standalone Datagrok HELM Web Editor** (`@datagrok-libraries/hwe`), integrating it into the platform with a custom grid cell renderer, an input widget, a property panel, and HELM↔other-notation conversion.
6
+
7
+ The legacy forked Pistoia HELM Web Editor + Scilligence JSDraw2 + Dojo toolkit stack has been **fully removed** (HWE migration, package v3.0). There are no more bundled `vendor/dojo-1.10.10/` or `helm/JSDraw/` sources and no `org.helm.webeditor` / `JSDraw2` / `scil` / `dojo` globals.
6
8
 
7
9
  Category: **Bioinformatics**.
8
10
 
11
+ ## The hwe library — `@datagrok-libraries/hwe`
12
+
13
+ Every editor / parse / render / calculation path routes through the self-contained `@datagrok-libraries/hwe` package. It is an **external npm dependency** (not under this repo's `libraries/`) and injects no global scripts. The package consumes from it:
14
+
15
+ | Export | Purpose |
16
+ |---|---|
17
+ | `HelmService` | Parses HELM, renders **synchronously** to a canvas (`renderToCanvas`), and computes molfiles / molecular properties. Reads monomers through `bridgeMonomerLib(...)` |
18
+ | `HelmHelperAdapter` | Wraps a `HelmService` to expose Datagrok's `IHelmHelper` plus a legacy-compatible Pistoia `App` shape (`createWebEditorApp`), so existing dialog consumers swap in unchanged |
19
+ | `bridgeMonomerLib(lib)` | Adapts Bio's `IMonomerLib` so the editor resolves exactly the same monomers as the rest of the platform |
20
+ | `buildHelmMolView(mol)` | Builds a legacy-shaped (`atoms[].p` in model space) laid-out molecule used for hover hit-testing and the highlight overlay |
21
+ | `PolymerTypes`; types `IMonomerLibBaseLike`, `MonomersFuncsLike`, `CanvasBounds` | Constants / type shims for the adapter and renderer |
22
+ | `@datagrok-libraries/hwe/styles.css` | The editor's `.hw-*` stylesheet. **Must be imported** (hwe ships CSS as a bundler import only — no runtime injection) or the editor renders unstyled. Imported once in `src/package.ts` |
23
+
9
24
  ## Architecture
10
25
 
11
26
  ### Entry Point — `src/package.ts`
12
27
 
13
- `PackageFunctions` class registers all platform-visible functions via `@grok.decorators`:
14
- - `initHelm` — `@init`: loads RdKit, SeqHelper, MonomerLibHelper, initializes HELMWebEditor, creates `HelmHelper` singleton, patches Pistoia monomer system
15
- - `getHelmService` — `@func`: returns `HelmServiceBase` singleton for off-screen HELM rendering
28
+ Imports `@datagrok-libraries/hwe/styles.css`. `PackageFunctions` class registers all platform-visible functions via `@grok.decorators`:
29
+ - `initHelm` — `@init`: loads the RDKit module, `SeqHelper`, `MonomerLibHelper`; creates the `HelmHelper` singleton (passing `seqHelper`, logger, `rdKitModule`); then `_package.completeInit(helmHelper, libHelper)`. No Dojo/editor bootstrapping or Pistoia monomer patching.
16
30
  - `helmCellRenderer` — `@func` (role: `cellRenderer`): returns `HelmGridCellRenderer` for columns with `quality=Macromolecule, units=helm`
17
- - `editMoleculeCell` — `@func` (role: `cellEditor`): opens full-screen HELM Web Editor dialog for cell editing
18
- - `openEditor` (`Edit Helm...`) — `@func` (action): context-menu editor for Macromolecule columns, converts non-HELM notations to HELM before editing
19
- - `propertiesWidget` (`Properties`) — `@panel`: shows molecular formula, weight, extinction coefficient for Macromolecule values
20
- - `getMolfiles` — `@func`: converts a Macromolecule column to molfile strings
21
- - `helmInput` — `@func` (role: `valueEditor`): creates `HelmInput` widget for Macromolecule/HELM semtype
22
- - `getHelmHelper` — `@func`: returns `IHelmHelper` singleton
23
- - `measureCellRenderer` — `@func`: performance measurement utility for cell rendering
24
- - `highlightMonomers` — `@func`: test app that loads peptide data and calls `Bio:toAtomicLevel` with highlight
31
+ - `editMoleculeCell` — `@func` (role: `cellEditor`): opens the full-screen HELM editor app dialog for cell editing (`openWebEditor`)
32
+ - `openEditor` (`Edit Helm...`) — `@func` (action): context-menu editor for Macromolecule columns; converts non-HELM notations to HELM first, then writes the edited value back in the column's original notation
33
+ - `propertiesWidget` (`Properties`) — `@panel`: molecular formula, weight, extinction coefficient for a Macromolecule value
34
+ - `getMolfiles` — `@func`: converts a Macromolecule column to molfile strings via `helmHelper.getMolfiles()`
35
+ - `helmInput` — `@func` (role: `valueEditor`): creates the `HelmInput` widget for Macromolecule/HELM semType
36
+ - `getHelmHelper` — `@func`: returns the `IHelmHelper` singleton
37
+ - `measureCellRenderer` — `@func`: cell-render performance benchmark
38
+ - `highlightMonomers` (`Highlight Monomers`) — `@func`: test app that loads peptide data and calls `Bio:toAtomicLevel` with `highlight: true`
39
+
40
+ > The legacy `getHelmService` function is **gone** — the off-screen render service now lives inside hwe and is owned by the helper's adapter.
25
41
 
26
42
  **Exports**: `_package` (instance of `HelmPackage`), auto-generated function wrappers from `package.g.ts`
27
43
 
28
44
  ### Detector — `detectors.js`
29
45
 
30
46
  `HelmPackageDetectors` class:
31
- - `autostart` — registers `ui.input.helmAsync` polyfill so other packages can create HELM inputs before this package fully loads
47
+ - `autostart` (meta.role: autostart) Helm bootstrap; registers the `ui.input.helmAsync` polyfill (delegates to `Helm:helmInput`) so other packages can create HELM inputs before this package fully loads. No semantic-type detector — HELM detection lives in Bio's `detectMacromolecule`.
32
48
 
33
- ### Package Utilities — `src/package-utils.ts`
49
+ ### Package Singleton — `src/package-utils.ts`
34
50
 
35
51
  `HelmPackage` class (extends `DG.Package`) — the package singleton managing:
36
- - `helmHelper` / `seqHelper` — accessors for initialized helpers
37
- - `_libHelper` — monomer library helper
38
- - `monomerLib` — accessor for current `IMonomerLib`
39
- - `initHELMWebEditor()` — loads Dojo toolkit (bundled), JSDraw2 + HELM Web Editor, patches `dojox.gfx.svg.Text.getTextWidth` for hang prevention
40
- - `initHelmPatchScilAlert()` — suppresses Scilligence alert popups for missing monomers
41
- - `initHelmPatchPistoia()` — overrides `org.helm.webeditor.Monomers.getMonomer` to use Datagrok's monomer library instead of built-in dictionaries
42
- - `completeInit()` — ties helmHelper + libHelper together, rewrites Pistoia monomer dictionaries, subscribes to monomer lib changes
43
- - `monomerLibOnChangedHandler()` — resyncs Pistoia dictionaries when monomer library updates
44
-
45
- `initHelmLoadAndPatchDojo()` — complex initialization:
46
- 1. Configures and loads bundled Dojo 1.10.10 with custom `loaderPatch.injectUrl`
47
- 2. Requires Dojo modules (dojo/window, dojox/gfx, dijit/*, etc.)
48
- 3. Waits for all modules to be ready
49
- 4. Patches `dojox.gfx.svg.Text.prototype.getTextWidth` to prevent infinite loops
52
+ - `helmHelper` / `seqHelper` — accessors for the initialized helpers
53
+ - `_libHelper` — monomer library helper; `monomerLib` — accessor for the current `IMonomerLib`
54
+ - `completeInit(helmHelper, libHelper)` — stores the helpers and subscribes to `monomerLib.onChanged`
55
+ - `monomerLibOnChangedHandler()` — logs the new library summary and shows a "Monomer lib updated" info toast
50
56
 
51
- ### HELM Helper `src/helm-helper.ts`
57
+ The legacy Dojo/JSDraw2 loader (`initHELMWebEditor`, `initHelmLoadAndPatchDojo`) and the `org.helm.webeditor.Monomers` patching (`initHelmPatchScilAlert`, `initHelmPatchPistoia`) are **gone** — hwe is self-contained and reads Bio's monomer library directly via `bridgeMonomerLib`.
52
58
 
53
- `HelmHelper` (implements `IHelmHelper`)singleton providing:
54
- - `createHelmInput()` — creates `HelmInput` widget
55
- - `createHelmWebEditor()` — creates `HelmWebEditor` viewer instance
56
- - `createWebEditorApp()` — creates full HELM Web Editor app (with monomer explorer, tabs, sequence/notation views) for dialog-based editing. Includes custom "Placeholders" tab
57
- - `overrideMonomersFuncs()` / `revertOriginalMonomersFuncs()` — swap Pistoia's `getMonomer`/`getMonomerSet` with custom implementations
58
- - `buildMonomersFuncsFromLib()` — builds `getMonomer` function that reads from Datagrok's `IMonomerLib`
59
- - `getMolfiles()` — batch converts HELM strings to molfile format using a cached off-screen JSDraw2 editor
60
- - `parse()` — parses HELM string into `HelmMol` object model
61
- - `removeGaps()` — removes gap monomers from HELM, re-links bonds, returns mapping of old→new monomer positions
62
- - `getHoveredAtom()` — hit-tests a point against a `HelmMol` to find the nearest atom
59
+ ### HELM Helper`src/helm-helper.ts`
63
60
 
64
- ### HELM Web Editor Wrapper `src/helm-web-editor.ts`
61
+ `HelmHelper` (implements `IHelmHelper`) singleton. Every editor / parse / calculation path runs through hwe via a lazily-built `HelmHelperAdapter` over a `HelmService` (the `editorAdapter` getter). The service is constructed with `bridgeMonomerLib(monomerLib)`, the RDKit module (for monomer-structure rendering), and an `extraPanes` map providing the editor's package-contributed tabs:
65
62
 
66
- `HelmWebEditor` (implements `IHelmWebEditor`) lightweight wrapper around `JSDraw2.Editor`:
67
- - Creates a viewonly editor in a host div
68
- - Handles resize events to keep editor synced with container size
69
- - Exposes `editor` (the JSDraw2 `HelmEditor` instance) and `host` div
63
+ | Pane | Source |
64
+ |---|---|
65
+ | **FASTA** / **BILN** | Read-only converted text via the seq handler's notation converters (BILN only for peptide chains; FASTA only for a single linear chain) |
66
+ | **Molecular Structure** | `Bio:toAtomicLevelPanel` widget |
67
+ | **Composition Analysis** | `Bio:compositionAnalysisWidget` widget |
68
+
69
+ Methods:
70
+ - `createHelmInput()` — creates the `HelmInput` widget
71
+ - `createHelmWebEditor(host, options)` — view-only editor instance (`IHelmWebEditor`) from the adapter
72
+ - `createWebEditorApp(host, helm)` — full editor app (palette + toolbar + canvas + built-in tabs + the extra panes above), wrapped in hwe's `LegacyAppWrapper` so it presents the legacy Pistoia `App` shape (`canvas.getHelm(true)`, `canvas.helm.jsd.m.atoms[i].selected`, …) — existing dialog consumers work unchanged
73
+ - `getMolfiles()`, `parse(helm, origin)`, `removeGaps(srcHelm)` — delegate to the adapter
74
+ - `getHoveredAtom(x, y, mol, height)` — delegates to `getHoveredMonomerFromEditorMol`
75
+ - `originalMonomersFuncs` / `revertOriginalMonomersFuncs()` / `overrideMonomersFuncs()` / `buildMonomersFuncsFromLib()` — thin pass-throughs to the adapter, kept only for the `IHelmHelper` contract (hwe reads `bridgeMonomerLib(...)` directly, so there is no global monomer registry to patch)
76
+ - private `_getSingleHelmDf()` / `_getSingleHelmDfSh()` — build a cached single-row HELM dataframe (tagged Macromolecule/helm; sets `.toAtomicWidgetWidth` to ~60% of window width) used by the Molecular-Structure / Composition / FASTA / BILN pane providers
70
77
 
71
78
  ## Utilities (`src/utils/`)
72
79
 
73
80
  | File | Purpose |
74
81
  |---|---|
75
- | `helm-grid-cell-renderer.ts` | `HelmGridCellRenderer` + `HelmGridCellRendererBack`: async cell renderer using SVG→image pipeline. Renders HELM structures in grid cells with LRU caching, handles mouse hover for monomer tooltips and hover links |
76
- | `helm-service.ts` | `HelmService` (extends `HelmServiceBase`): off-screen rendering service. Uses hidden JSDraw2 editors (LRU-cached per monomer lib) to render HELM→SVG→ImageData. Handles scaling/fitting within cell bounds |
77
- | `get-monomer.ts` | `rewriteLibraries()`: syncs Datagrok monomer library Pistoia `org.helm.webeditor.Monomers` dictionary. `getMonomerOverrideAndLogAlert()`: temporary getMonomer override with alert suppression |
78
- | `get-hovered.ts` | `getHoveredMonomerFromEditorMol()`: nearest-atom hit testing in editor molecule coordinates. `getSeqMonomerFromHelmAtom()`: converts `HelmAtom` to `ISeqMonomer` with canonical symbol |
79
- | `index.ts` | HELM string parsing utilities: `parseHelm()` (extracts monomer symbols), `removeGapsFromHelm()` (regex gap removal), `findMonomers()` (finds missing monomers), `split()` / `detachAnnotation()` (HELM section tokenizer) |
80
- | `err-info.ts` | `defaultErrorHandler()`: logs errors via package logger + `grok.shell.error` |
82
+ | `helm-grid-cell-renderer.ts` | `HelmGridCellRenderer` + `HelmGridCellRendererBack`: **synchronous** grid cell renderer painting straight into the grid canvas via hwe `HelmService.renderToCanvas` (no async SVG→image / ImageData round-trip). Keeps one hwe service per monomer-library source (`serviceByLib`) and per-cell-value layout bookkeeping (`auxList`) for hover + highlight. Subscribes to monomer-lib changes (invalidate all) and to `MACROMOLECULE_HIGHLIGHT_EVENT_ID`; `drawHighlightOverlay` paints translucent rings around highlighted monomers. `onMouseMove` hit-tests the laid-out mol and shows the monomer tooltip + hover links |
83
+ | `get-hovered.ts` | `getHoveredMonomerFromEditorMol()`: nearest-atom hit testing (model coordinates) against a `HelmMol`. `getSeqMonomerFromHelmAtom()`: converts a `HelmAtom` to `ISeqMonomer` with canonical symbol (DNA/RNA sugar + phosphate aware) |
84
+ | `index.ts` | HELM string utilities: `parseHelm()` (extracts monomer symbols, bracket/paren aware), `removeGapsFromHelm()` (regex gap removal), `findMonomers()` (resolves via `monomerLib.getMonomer`), `getParts()`, and the `split()` / `detachAnnotation()` HELM section tokenizer |
85
+ | `err-info.ts` | `defaultErrorHandler()`: logs via the package logger + `grok.shell.error` |
81
86
 
82
87
  ## Widgets (`src/widgets/`)
83
88
 
84
89
  | File | Purpose |
85
90
  |---|---|
86
- | `helm-input.ts` | `HelmInput` (extends `HelmInputBase`): interactive HELM sequence input widget. Embeds a viewonly `HelmWebEditor`, shows monomer tooltips on hover, "Click to edit" hint opens full editor dialog. Supports `SeqValueBase` get/set, string get/set, `molValue` access. Handles mouse events for hover/click/tooltip |
87
- | `properties-widget.ts` | `getPropertiesWidget()`: property panel showing molecular formula, weight, and extinction coefficient. Uses off-screen JSDraw2 editor to compute properties. Limits to sequences <1000 chars |
91
+ | `helm-input.ts` | `HelmInput` (extends `HelmInputBase`): interactive HELM input widget embedding a **view-only hwe editor** (`IHelmWebEditor`). Defaults to a compact 250×250 box; shows monomer tooltips on hover; "Click to edit" opens the full hwe editor app in a full-screen dialog and reads back the edited HELM + monomer selection (via the legacy `App` canvas shape). Re-fits the canvas on resize (`ui.onSizeChanged`). Supports `SeqValueBase`/string get/set and `molValue` |
92
+ | `properties-widget.ts` | `getPropertiesWidget()` / `getPropertiesDict()`: **async** property panel molecular formula, weight, extinction coefficient computed from an off-screen hwe editor (obtained via the async `getHelmHelper()` factory, replacing the old off-screen JSDraw2 editor). Limited to sequences <1000 chars |
88
93
 
89
94
  ## Constants — `src/constants.ts`
90
95
 
91
96
  - `jsonSdfMonomerLibDict` — mapping between SDF monomer fields and internal property names
92
- - `SMILES`, `RGROUPS`, `MONOMER_SYMBOL`, `RGROUP_*` — field name constants for monomer data
93
- - `SDF_MONOMER_NAME` — SDF field name
97
+ - `SMILES`, `RGROUPS`, `MONOMER_SYMBOL`, `RGROUP_*`, `SDF_MONOMER_NAME` — field-name constants for monomer data
94
98
  - `TAGS.cellRendererRenderError` — tag for tracking render errors
95
99
 
96
- ## Types `src/types/index.ts`
97
-
98
- Re-exports from `@datagrok-libraries/bio/src/helm/types`:
99
- - `ScilModule` — Scilligence utility module (`scil.*`)
100
- - `JSDraw2Module` — JSDraw2 editor module (`JSDraw2.*`)
101
- - `OrgHelmModule` — Pistoia HELM module (`org.helm.*`)
102
-
103
- ## Vendor Libraries
104
-
105
- ### `vendor/dojo-1.10.10/`
106
- Bundled Dojo Toolkit (dijit, dojo, dojox) required by JSDraw2 and HELM Web Editor. Loaded via custom `dojoConfig.loaderPatch.injectUrl` to work within webpack bundle.
107
-
108
- ### `helm/JSDraw/`
109
- Legacy uncompressed sources of Scilligence JSDraw2 Lite and Pistoia HELM Web Editor. Currently replaced by `@datagrok-libraries/helm-web-editor` npm package.
100
+ > HELM types (`HelmType`, `HelmMol`, `HelmAtom`, `App`, `Point`, `MonomersFuncs`, `IHelmWebEditor`, …) are imported directly from `@datagrok-libraries/bio/src/helm/types`. The old `src/types/` re-export module (`ScilModule` / `JSDraw2Module` / `OrgHelmModule`) was removed in the migration.
110
101
 
111
102
  ## Tests (`src/tests/`)
112
103
 
@@ -115,38 +106,34 @@ Test entry point: `src/package-test.ts` — imports all test files, exports `tes
115
106
  | File | What it tests |
116
107
  |---|---|
117
108
  | `_first-tests.ts` | Package import sanity check |
118
- | `helm-tests.ts` | HELM parsing, parseHelm utility |
109
+ | `helm-tests.ts` | HELM parsing, `parseHelm` utility |
119
110
  | `findMonomers-tests.ts` | Missing monomer detection |
120
- | `helm-service-tests.ts` | HelmService rendering |
121
111
  | `renderers-tests.ts` | Cell renderer behavior |
122
112
  | `get-molfiles-tests.ts` | HELM → molfile conversion |
123
113
  | `properties-widget-tests.ts` | Properties panel (formula, MW, ext. coeff.) |
124
- | `get-monomer-tests.ts` | Monomer lookup and library integration |
125
114
  | `parse-helm-tests.ts` | HELM string parsing edge cases |
126
- | `helm-web-editor-tests.ts` | Web editor widget creation |
127
- | `helm-input-tests.ts` | HelmInput widget behavior |
128
- | `helm-helper-tests.ts` | HelmHelper methods (parse, removeGaps, getMolfiles) |
115
+ | `helm-web-editor-tests.ts` | hwe editor / web-editor widget creation |
116
+ | `helm-input-tests.ts` | `HelmInput` widget behavior |
117
+ | `helm-helper-tests.ts` | `HelmHelper` methods (parse, removeGaps, getMolfiles) |
129
118
  | `helm-substructure-filter.ts` | Substructure filtering for HELM |
130
119
  | `helm-activity-cliffs.ts` | Activity cliffs computation for HELM |
131
120
  | `to-atomic-level-ui-non-linear.ts` | Non-linear HELM → atomic level conversion |
121
+ | `utils.ts` | Shared test helpers (not a `test()` suite) |
132
122
 
133
123
  ## Initialization Flow
134
124
 
135
- 1. `detectors.js` `autostart` runs first — registers `ui.input.helmAsync` polyfill
136
- 2. `initHelm()` called on package init → loads RdKit, SeqHelper, MonomerLibHelper
137
- 3. `initHELMWebEditor()` → loads bundled Dojo, waits for all Dojo modules, patches SVG text width
138
- 4. Loads `@datagrok-libraries/helm-web-editor` bundle, waits for `helmWebEditor$.initPromise`
139
- 5. Creates `HelmHelper` singleton
140
- 6. `completeInit()` → rewrites Pistoia monomer dictionaries from Datagrok lib, patches `getMonomer`, subscribes to lib changes
125
+ 1. `detectors.js` `autostart` runs first — registers the `ui.input.helmAsync` polyfill
126
+ 2. `initHelm()` on package init → loads the RDKit module, `SeqHelper`, `MonomerLibHelper`; creates `HelmHelper(seqHelper, logger, rdKitModule)`
127
+ 3. `completeInit(helmHelper, libHelper)` → wires the helpers and subscribes to monomer-library changes
128
+ 4. The hwe `HelmHelperAdapter` / `HelmService` is built **lazily** on first editor / parse / calculation use (after the library is available), reading Bio's monomer library via `bridgeMonomerLib`
141
129
 
142
130
  ## Key Dependencies
143
131
 
144
- - `@datagrok-libraries/bio` — macromolecule types, HELM types (`HelmType`, `HelmAtom`, `HelmMol`, `IHelmHelper`, `ISeqHelper`, `IMonomerLib`), cell renderer base classes, monomer hover links
145
- - `@datagrok-libraries/helm-web-editor` — bundled JSDraw2 + Pistoia HELM Web Editor
146
- - `@datagrok-libraries/chem-meta` — chemistry metadata
147
- - `@datagrok-libraries/utils` — SVG utilities (`svgToImage`), console helpers
132
+ - `@datagrok-libraries/hwe` — the standalone Datagrok HELM Web Editor: HELM parsing, synchronous canvas rendering, molfile / property calculators, and the editor app (`HelmService`, `HelmHelperAdapter`, `bridgeMonomerLib`, `buildHelmMolView`, `PolymerTypes`, `styles.css`)
133
+ - `@datagrok-libraries/bio` — macromolecule + HELM types (`HelmType`, `HelmAtom`, `HelmMol`, `IHelmHelper`, `ISeqHelper`, `IMonomerLib`), cell-renderer base classes, monomer hover links, macromolecule-highlight events/consts
134
+ - `@datagrok-libraries/chem-meta` — RDKit API types (`RDModule`)
135
+ - `@datagrok-libraries/utils` — error / console helpers
148
136
  - `cash-dom` — jQuery-like DOM manipulation
149
- - `lru-cache` — LRU caching for editors and rendered images
150
137
  - `wu` — lazy iteration
151
138
  - `rxjs` — reactive subscriptions
152
139
 
@@ -155,18 +142,17 @@ Test entry point: `src/package-test.ts` — imports all test files, exports `tes
155
142
  | Looking for... | Check first |
156
143
  |---|---|
157
144
  | Function/panel/renderer registration | `src/package.ts` |
158
- | Package singleton, Dojo/HWE loading | `src/package-utils.ts` (`HelmPackage`) |
159
- | HELM helper (parse, convert, getMolfiles) | `src/helm-helper.ts` |
160
- | Web editor wrapper | `src/helm-web-editor.ts` |
161
- | Grid cell renderer (async SVG→image) | `src/utils/helm-grid-cell-renderer.ts` |
162
- | Off-screen render service | `src/utils/helm-service.ts` |
163
- | Monomer library sync with Pistoia | `src/utils/get-monomer.ts` |
145
+ | Package singleton, init wiring | `src/package-utils.ts` (`HelmPackage`) |
146
+ | HELM helper + hwe adapter (parse, convert, getMolfiles, editor app, panes) | `src/helm-helper.ts` (`HelmHelper.editorAdapter`) |
147
+ | The hwe editor / service / adapter | `@datagrok-libraries/hwe` (external) |
148
+ | Grid cell renderer (synchronous canvas) | `src/utils/helm-grid-cell-renderer.ts` |
149
+ | Monomer highlight overlay (event-driven) | `src/utils/helm-grid-cell-renderer.ts` (`handleHighlightEvent` / `drawHighlightOverlay`) |
164
150
  | Mouse hover / hit testing | `src/utils/get-hovered.ts` |
165
151
  | HELM string parsing | `src/utils/index.ts` |
166
152
  | HELM input widget | `src/widgets/helm-input.ts` |
167
153
  | Properties panel (MW, formula) | `src/widgets/properties-widget.ts` |
168
154
  | Constants (field names, tags) | `src/constants.ts` |
169
- | Type re-exports (Scil, JSDraw2, Org) | `src/types/index.ts` |
155
+ | HELM types (`HelmMol`, `HelmAtom`, `App`, …) | `@datagrok-libraries/bio/src/helm/types` |
170
156
  | Auto-generated function wrappers | `src/package.g.ts` / `src/package-api.ts` |
171
157
  | Autostart / input polyfill | `detectors.js` |
172
158
  | Test entry point | `src/package-test.ts` |
package/dist/489.js ADDED
@@ -0,0 +1,2 @@
1
+ var helm;(()=>{"use strict";"object"==typeof performance&&performance&&"function"==typeof performance.now?performance:Date,new Set;const t="object"==typeof process&&process?process:{};let e=globalThis.AbortController,i=globalThis.AbortSignal;if(void 0===e){i=class{onabort;_onabort=[];reason;aborted=!1;addEventListener(t,e){this._onabort.push(e)}},e=class{constructor(){s()}signal=new i;abort(t){if(!this.signal.aborted){this.signal.reason=t,this.signal.aborted=!0;for(const e of this.signal._onabort)e(t);this.signal.onabort?.(t)}}};let r="1"!==t.env?.LRU_CACHE_IGNORE_AC_WARNING;const s=()=>{r&&(r=!1,((e,i,r,s)=>{"function"==typeof t.emitWarning?t.emitWarning(e,i,r,s):console.error(`[${r}] ${i}: ${e}`)})("AbortController is not defined. If using lru-cache in node 14, load an AbortController polyfill from the `node-abort-controller` package. A minimal polyfill is provided for use by LRUCache.fetch(), but it should not be relied upon in other contexts (eg, passing it to other APIs that use AbortController/AbortSignal might have undesirable effects). You may disable this with LRU_CACHE_IGNORE_AC_WARNING=1 in the env.","NO_ABORT_CONTROLLER","ENOTSUP",s))}}Symbol("type"),Symbol.iterator,Symbol.toStringTag;Error;new Map([[123,"lbrace"],[125,"rbrace"],[40,"lparen"],[41,"rparen"],[93,"rbracket"],[124,"pipe"],[46,"dot"],[44,"comma"],[43,"plus"],[58,"colon"],[45,"dash"],[36,"dollar"],[62,"gt"],[63,"question"],[42,"asterisk"],[95,"underscore"],[39,"apos"]]);new Map;var r="HELM_AA",s="HELM_SUGAR",l="HELM_BASE",o="HELM_LINKER",n="HELM_CHEM",a="HELM_BLOB",h="HELM_NUCLEOTIDE",d={PEPTIDE:"PEPTIDE",RNA:"RNA",CHEM:"CHEM",BLOB:"BLOB",G:"G"};var u=class{constructor(){this._listeners=new Set,this._completed=!1}subscribe(t){return this._completed?()=>{}:(this._listeners.add(t),()=>{this._listeners.delete(t)})}next(t){if(!this._completed)for(let e of[...this._listeners])e(t)}complete(){this._completed=!0,this._listeners.clear()}get observerCount(){return this._listeners.size}};function c(t){return{line:"#202020",text:"#000000",background:t}}function p(t){return{line:"#e0e0e0",text:"#ffffff",background:C(t,.25)}}function _(t){let e=/^#([0-9a-fA-F]{6})$/.exec(t),i=/^#([0-9a-fA-F]{3})$/.exec(t);if(null!==e){let t=e[1];return[parseInt(t.slice(0,2),16),parseInt(t.slice(2,4),16),parseInt(t.slice(4,6),16)]}if(null!==i){let t=i[1];return[parseInt(t[0]+t[0],16),parseInt(t[1]+t[1],16),parseInt(t[2]+t[2],16)]}return null}function b(t){return t.toString(16).padStart(2,"0")}function f(t,e,i){return`#${b(t)}${b(e)}${b(i)}`}function m(t,e,i){let r=t/255,s=e/255,l=i/255,o=Math.max(r,s,l),n=Math.min(r,s,l),a=(o+n)/2;if(o===n)return[0,0,a];let h,d=o-n;return h=o===r?60*((s-l)/d+(s<l?6:0)):o===s?60*((l-r)/d+2):60*((r-s)/d+4),[h,a>.5?d/(2-o-n):d/(o+n),a]}function g(t,e,i){let r=i;return r<0&&(r+=1),r>1&&(r-=1),r<1/6?t+6*(e-t)*r:r<.5?e:r<2/3?t+(e-t)*(2/3-r)*6:t}function y(t,e,i){if(0===e){let t=Math.round(255*i);return[t,t,t]}let r=i<.5?i*(1+e):i+e-i*e,s=2*i-r,l=t/360;return[Math.round(255*g(s,r,l+1/3)),Math.round(255*g(s,r,l)),Math.round(255*g(s,r,l-1/3))]}function v(t,e=.3,i=.1){let r=_(t);if(null===r)return t;let[s,l,o]=m(r[0],r[1],r[2]),n=Math.max(0,Math.min(1,l*(1-e))),a=Math.max(0,Math.min(.95,o+i*(1-o))),[h,d,u]=y(s,n,a);return f(h,d,u)}function w(t){let e=_(t);if(null===e)return 0;let i=t=>{let e=t/255;return e<=.03928?e/12.92:Math.pow((e+.055)/1.055,2.4)};return.2126*i(e[0])+.7152*i(e[1])+.0722*i(e[2])}function A(t){let e=_(t);if(null===e)return"#1f2937";let[i,r,s]=m(e[0],e[1],e[2]);if(s>.85||r<.15&&s>.7)return"#1f2937";let l=Math.max(.08,s-.3);return function(t){let e=(t.h%360+360)%360,i=Math.max(0,Math.min(1,t.s)),r=Math.max(0,Math.min(1,t.l)),[s,l,o]=y(e,i,r);return f(s,l,o)}({h:i,s:Math.min(1,r+.1),l})}function S(t){let e=function(t){let e=_(t);return null===e?null:{r:e[0]/255,g:e[1]/255,b:e[2]/255}}(t);if(null===e)return"#1f2937";let i=t=>t<=.03928?t/12.92:Math.pow((t+.055)/1.055,2.4),r=.2126*i(e.r)+.7152*i(e.g)+.0722*i(e.b);return 1.05/(r+.05)>(r+.05)/.05?"#ffffff":"#1f2937"}function C(t,e){let i=_(t);if(null===i)return t;let r=1-e;return f(Math.max(0,Math.min(255,Math.round(i[0]*r))),Math.max(0,Math.min(255,Math.round(i[1]*r))),Math.max(0,Math.min(255,Math.round(i[2]*r))))}var k={A:c("#A0A0FF"),G:c("#FF7070"),T:c("#A0FFA0"),C:c("#FF8C4B"),U:c("#FF8080")},T={R:c("#7a85c1"),r:c("#7a85c1")},E={P:c("#9aa5e1"),p:c("#9aa5e1")},N={A:c("#C8C8C8"),R:c("#145AFF"),N:c("#00DCDC"),D:c("#E60A0A"),C:c("#E6E600"),E:c("#00DCDC"),Q:c("#E60A0A"),G:c("#EBEBEB"),H:c("#8282D2"),I:c("#0F820F"),L:c("#0F820F"),K:c("#145AFF"),M:c("#E6E600"),F:c("#3232AA"),P:c("#DC9682"),S:c("#FA9600"),T:c("#FA9600"),W:c("#B45AB4"),Y:c("#3232AA"),V:c("#0F820F")},M={R:c("#eeeeee")},I={B:c("#999999"),G:c("#e2e2e2")},B={P:c("#9aa5e1")},x={name:"light",fallback:{line:"#202020",text:"#000000",background:"#eeeeee"},errorTriple:{line:"#cc0000",text:"#000000",background:"#FFFF00"},palette:{[l]:k,[s]:T,[o]:E,[r]:N,[n]:M,[a]:I,[h]:B}};function L(t){let e={};for(let[i,r]of Object.entries(t))e[i]=p(r.background);return e}var P={name:"dark",fallback:{line:"#e0e0e0",text:"#ffffff",background:C("#eeeeee",.5)},errorTriple:{line:"#ff5050",text:"#ffffff",background:C("#FFFF00",.4)},palette:{[l]:L(k),[s]:L(T),[o]:L(E),[r]:L(N),[n]:L(M),[a]:L(I),[h]:L(B)}};function F(t,e,i=x){if(null===t)return{...i.errorTriple};let r=t.meta?.colors;if(void 0!==r){let t="light"===i.name?r.light:"dark"===i.name?r.dark:void 0;if(void 0!==t)return{...t,line:A(t.background)};if(void 0!==r.default)return{...r.default,line:A(r.default.background)}}let s=t.naturalAnalog;if(void 0!==s&&""!==s){let t=i.palette[e];if(void 0!==t){let e=t[s];if(void 0!==e)return{...e,line:A(e.background),text:S(e.background)}}}return{...i.fallback,line:A(i.fallback.background),text:S(i.fallback.background)}}function $(t){switch(t.polymerType){case d.PEPTIDE:return r;case d.CHEM:return n;case d.BLOB:return a;case d.RNA:if("Branch"===t.monomerType)return l;if("Backbone"===t.monomerType){let e=t.naturalAnalog;return"P"===e||"p"===e?o:s}return null;default:return null}}new Set(["PEPTIDE","RNA","CHEM","BLOB"]),new Set(["Backbone","Branch","Terminal","Undefined"]);new Set(["?","*","_","X","N"]);Math.PI;function R(t,e){let i=Math.min(t.x,e.x),r=Math.min(t.y,e.y);return{x:i,y:r,width:Math.max(t.x+t.width,e.x+e.width)-i,height:Math.max(t.y+t.height,e.y+e.height)-r}}function O(t){if(Number.isInteger(t))return 0===t?"0":t.toString();if(!Number.isFinite(t)||Object.is(t,-0))return"0";let e=Math.round(1e3*t)/1e3;return 0===e?"0":e.toString()}function D(t){if(0===t.length)return"";let e=t[0],i=`M ${O(e.x)} ${O(e.y)}`;for(let e=1;e<t.length;e++){let r=t[e];i+=` L ${O(r.x)} ${O(r.y)}`}return i+=` L ${O(e.x)} ${O(e.y)} Z`,i}function V(t,e,i,r){let s=[],l=360/e;for(let o=0;o<e;o++){let e=(r+o*l)*Math.PI/180;s.push({x:t.x+i*Math.cos(e),y:t.y+i*Math.sin(e)})}return s}function K(t,e,i,r){let s=Math.abs(e)/2,l=Math.abs(i)/2,o=Math.max(0,Math.min(r,s,l)),n=t.x-s,a=t.y-l,h=n+2*s,d=a+2*l,u=`M ${O(n+o)} ${O(a)}`;return u+=` L ${O(h-o)} ${O(a)}`,u+=` A ${O(o)} ${O(o)} 0 0 1 ${O(h)} ${O(a+o)}`,u+=` L ${O(h)} ${O(d-o)}`,u+=` A ${O(o)} ${O(o)} 0 0 1 ${O(h-o)} ${O(d)}`,u+=` L ${O(n+o)} ${O(d)}`,u+=` A ${O(o)} ${O(o)} 0 0 1 ${O(n)} ${O(d-o)}`,u+=` L ${O(n)} ${O(a+o)}`,u+=` A ${O(o)} ${O(o)} 0 0 1 ${O(n+o)} ${O(a)}`,u+=" Z",u}function H(t,e,i){let r=Math.abs(e),s=Math.abs(i);return`M ${O(t.x-r)} ${O(t.y)} A ${O(r)} ${O(s)} 0 1 0 ${O(t.x+r)} ${O(t.y)} A ${O(r)} ${O(s)} 0 1 0 ${O(t.x-r)} ${O(t.y)} Z`}function G(t,e,i,r){switch(t){case"hexagon":{let t=i*Math.sqrt(3)/2,r=i;return{x:e.x-t,y:e.y-r,width:2*t,height:2*r}}case"diamond":return{x:e.x-i,y:e.y-i,width:2*i,height:2*i};case"pentagon":{let t=Math.cos(18*Math.PI/180)*i,r=-i,s=Math.sin(54*Math.PI/180)*i;return{x:e.x-t,y:e.y+r,width:2*t,height:s-r}}case"rounded-rect":case"blob":{let t=r??i,s=Math.abs(i)/2,l=Math.abs(t)/2;return{x:e.x-s,y:e.y-l,width:2*s,height:2*l}}case"ellipse":{let t=Math.abs(i),s=Math.abs(r??i);return{x:e.x-t,y:e.y-s,width:2*t,height:2*s}}case"circle":{let t=Math.abs(i);return{x:e.x-t,y:e.y-t,width:2*t,height:2*t}}}}var z='"Helvetica Neue", Helvetica, Arial, sans-serif';function U(t){return{aa:{size:.72*t,strokeWidth:5},sugar:{size:1.39*t,strokeWidth:5,cornerRadius:.3*t},base:{size:.88*t,strokeWidth:5},linker:{size:.63*t,strokeWidth:5},chem:{size:1.49*t,strokeWidth:5,cornerRadius:.5*t},blob:{size:1.64*t,strokeWidth:5,cornerRadius:.8*t},nucleotide:{size:.98*t,strokeWidth:5}}}var q={name:"light",background:"#ffffff",defaultStroke:"#202020",defaultFill:"#ffffff",selectionColor:"#FFC107",highlightColor:"#A4E2DC",errorColor:"#cc0000",fontSize:14,fontFamily:z,bondLength:28,textColor:"#000000",idColor:"#00aa00",annotationColor:"#FFA500",tagDotColor:"#dd2222",hbondColor:"#888888",nonCanonicalHbondColor:"#cc8800",crossPolymerBondColor:"#1f5fcd",colorTheme:x,palette:{softenCanvas:!1},shapes:U(14)};U(14);function j(t,e){switch(e){case r:return t.shapes.aa;case s:return t.shapes.sugar;case l:return t.shapes.base;case o:return t.shapes.linker;case n:return t.shapes.chem;case a:return t.shapes.blob;case h:return t.shapes.nucleotide}}function Y(t){switch(t){case r:return"hexagon";case s:return"rounded-rect";case l:return"diamond";case o:return"circle";case n:return"rounded-rect";case a:return"blob";case h:return"pentagon"}}function W(t,e,i=0){let r=j(e,t.biotype);if("*"===t.symbol)return function(t,e){return H(t,e,e)}(t.p,r.size+i);switch(Y(t.biotype)){case"hexagon":{let e=0===i?0:i/Math.cos(Math.PI/6);return function(t,e,i=-30){return D(V(t,6,e,i))}(t.p,r.size+e)}case"diamond":{let e=0===i?0:i/Math.cos(Math.PI/4);return function(t,e){return D([{x:t.x,y:t.y-e},{x:t.x+e,y:t.y},{x:t.x,y:t.y+e},{x:t.x-e,y:t.y}])}(t.p,r.size+e)}case"pentagon":{let e=0===i?0:i/Math.cos(Math.PI/5);return function(t,e,i=-90){return D(V(t,5,e,i))}(t.p,r.size+e)}case"rounded-rect":return K(t.p,r.size+2*i,r.size+2*i,(r.cornerRadius??0)+i);case"blob":return function(t,e,i,r){return K(t,e,i,r)}(t.p,r.size+2*i,r.size+2*i,(r.cornerRadius??0)+i);case"circle":return H(t.p,r.size+i,r.size+i)}}function X(t,e){let i,r=j(e,t.biotype),s="*"===t.symbol?"circle":Y(t.biotype);switch(s){case"hexagon":case"diamond":case"pentagon":case"circle":i=G(s,t.p,r.size);break;case"rounded-rect":case"blob":i=G(s,t.p,r.size,r.size)}let l=r.strokeWidth/2;return{x:i.x-l,y:i.y-l,width:i.width+2*l,height:i.height+2*l}}function Z(t,e){return j(e,t.biotype)}var J=/[&"'<>]/;function Q(t){return J.test(t)?t.replace(/&/g,"&amp;").replace(/"/g,"&quot;").replace(/'/g,"&apos;").replace(/</g,"&lt;").replace(/>/g,"&gt;"):t}function tt(t){if(Number.isInteger(t))return 0===t?"0":t.toString();if(!Number.isFinite(t)||Object.is(t,-0))return"0";let e=Math.round(1e3*t)/1e3;return 0===e?"0":e.toString()}function et(t,e,i){let r=`<${t}`;if(void 0!==e)for(let t in e){let i=e[t];if(void 0!==i&&!1!==i){if(!0===i){r+=` ${t}`;continue}r+="number"==typeof i?` ${t}="${tt(i)}"`:` ${t}="${Q(i)}"`}}return void 0===i?`${r}/>`:"string"==typeof i?`${r}>${i}</${t}>`:`${r}>${i.join("")}</${t}>`}function it(t,e,i){if(0===i.size)return et("g",{class:"hw-layer hw-highlights"},"");let r=[];for(let s of t.atoms){if(!i.has(s.id))continue;let t=W(s,e,(Z(s,e).strokeWidth+3)/2);r.push(et("path",{d:t,class:"hw-highlight",fill:"none",stroke:e.highlightColor,"stroke-width":3,"stroke-linejoin":"round","stroke-linecap":"round","data-symbol":s.symbol,"data-ring-atom-id":s.id,"data-testid":`highlight-ring-${s.id}`}))}return et("g",{class:"hw-layer hw-highlights"},r.join(""))}function rt(t,e,i){if(0===i.size)return et("g",{class:"hw-layer hw-selections"},"");let r=[];for(let s of t.atoms){if(!i.has(s.id))continue;let t=W(s,e,(Z(s,e).strokeWidth+3)/2);r.push(et("path",{d:t,class:"hw-selection",fill:"none",stroke:e.selectionColor,"stroke-width":3,"stroke-linejoin":"round","stroke-linecap":"round","data-symbol":s.symbol,"data-ring-atom-id":s.id,"data-testid":`selection-ring-${s.id}`}))}return et("g",{class:"hw-layer hw-selections"},r.join(""))}new WeakMap;new Map;var st=class{constructor(t,e){this.atoms=t,this.bonds=e,this.isEmpty=0===t.size&&0===e.size,Object.freeze(this)}};new st(new Set,new Set);function lt(t){let e=t.ownerDocument;if(null!=e)return e;let i=globalThis;if(void 0!==i.document)return i.document;throw new Error("EditorView: no Document available (host.ownerDocument is null).")}function ot(t,e,i,r){let s=t.createElement(e);if(void 0!==i)for(let t of Object.keys(i)){let e=i[t];!1===e||void 0===e||s.setAttribute(t,!0===e?"":String(e))}if(void 0!==r)for(let e of r)"string"==typeof e?s.appendChild(t.createTextNode(e)):s.appendChild(e);return s}function nt(t,e,i=220,r=140){if(null==t||""===e)return null;try{let s=t.get_mol(e);if(null===s)return null;let l=s.get_svg(i,r);return s.delete(),l}catch{return null}}function at(t,e,i){let r="data-testid";for(let i=0;i<t.body.children.length;i++){let s=t.body.children[i];if(void 0!==s&&s.getAttribute(r)===e)return s}let s=ot(t,"div",{class:i,[r]:e});return s.style.display="none",t.body.appendChild(s),s}function ht(t,e,i){for(;null!==e.firstChild;)e.removeChild(e.firstChild);if(e.appendChild(ot(t,"div",{class:"hw-tooltip__symbol"},[i.symbol])),void 0!==i.name&&""!==i.name&&i.name!==i.symbol&&e.appendChild(ot(t,"div",{class:"hw-tooltip__name"},[i.name])),void 0!==i.rdkitSvg&&null!==i.rdkitSvg&&""!==i.rdkitSvg){let r={class:"hw-tooltip__rdkit"};void 0!==i.rdkitTestid&&(r["data-testid"]=i.rdkitTestid);let s=ot(t,"div",r);s.innerHTML=i.rdkitSvg,e.appendChild(s)}void 0!==i.hint&&""!==i.hint&&e.appendChild(ot(t,"div",{class:"hw-tooltip__hint"},[i.hint]))}function dt(t,e,i){let r=t.style;r.display="block",r.left=`${e+12}px`,r.top=`${i+12}px`}function ut(t){null!==t&&(t.style.display="none")}function ct(t){let e=t.body;if(null!=e)for(let t=0;t<e.children.length;t++){let i=e.children[t];if(void 0===i)continue;let r=void 0===i.getAttribute?null:i.getAttribute("data-testid");null!=r&&r.endsWith("-tooltip")&&ut(i)}}var pt=class t{constructor(t,e,i){this._baseTransform="",this._viewport={scale:1,offset:{x:0,y:0}},this._pinnedBbox=null,this._tooltip=null,this._bondTooltip=null,this._rdkitSvgCache=new Map,this._unsubs=[],this._destroyed=!1,this.host=t,this._editor=e,this._doc=i?.documentImpl??lt(t),this._width=i?.width??400,this._height=i?.height??200,function(t){let e=lt(t);if(null!==e.querySelector("style[data-hw-editor-view-styles]"))return;let i=e.createElement("style");i.setAttribute("data-hw-editor-view-styles",""),i.textContent=".hw-editor-view{position:relative;display:block;overflow:hidden;outline:none;}.hw-editor-view svg{display:block;user-select:none;}.hw-editor-view.hw-view-only{cursor:default;}";let r=e.head??e.documentElement;null!==r&&r.appendChild(i)}(t);let r=this._doc.createElement("div");r.setAttribute("class","hw-editor-view"),t.appendChild(r),this._tooltip=at(this._doc,"atom-tooltip","hw-atom-tooltip"),this._bondTooltip=at(this._doc,"bond-tooltip","hw-bond-tooltip"),this._svgRoot=this._renderFresh(),this._unsubs.push(e.on("mol:changed",t=>{this._hideTooltip(),this._hideBondTooltip(),("setHelm"===t.reason||"cleanLayout"===t.reason||"initial"===t.reason)&&(this._pinnedBbox=null),this._renderFresh()})),this._unsubs.push(e.on("selection:change",t=>{this._refreshOverlays(t)})),this._unsubs.push(e.on("highlight:change",t=>{this._refreshOverlays(t)})),this._unsubs.push(e.on("theme:change",()=>{this._renderFresh()})),this._unsubs.push(e.on("view:resize",t=>{this._applyResize(t.width,t.height)})),this._unsubs.push(e.on("view:viewport-change",t=>{this._viewport=t.viewport,this._applyViewport(t.viewport)})),this._unsubs.push(e.on("view:fit-to-content",()=>{this._pinnedBbox=null,this._renderFresh()})),this._unsubs.push(e.on("monomer:hover",t=>{this._showTooltip(t.atom,t.clientX,t.clientY)})),this._unsubs.push(e.on("monomer:hover-end",()=>{this._hideTooltip()})),this._unsubs.push(e.on("bond:hover",t=>{this._showBondTooltip(t.bond,t.clientX,t.clientY)})),this._unsubs.push(e.on("bond:hover-end",()=>{this._hideBondTooltip()})),this._unsubs.push(e.on("bond:preview",t=>{this._paintBondPreview(t.start.p,t.cursor,null!==t.candidate)})),this._unsubs.push(e.on("bond:preview-end",()=>{this._clearBondPreview()})),this._unsubs.push(e.on("bond:cancel",()=>{this._clearBondPreview()})),this._unsubs.push(e.on("selection:rectangle-start",t=>{this._paintSelectionRect(t.origin,t.origin)})),this._unsubs.push(e.on("selection:rectangle-update",t=>{this._paintSelectionRectFromRect(t.rect)})),this._unsubs.push(e.on("selection:rectangle-end",()=>{this._clearSelectionRect()}))}get svgRoot(){return this._svgRoot}get width(){return this._width}get height(){return this._height}resize(t,e){this._destroyed||(this._width=t,this._height=e,this._renderFresh())}redraw(){this._destroyed||this._renderFresh()}destroy(){if(this._destroyed)return;this._destroyed=!0;for(let t of this._unsubs)t();this._unsubs.length=0;let t=this.host.querySelector(".hw-editor-view");null!==t&&null!==t.parentNode&&t.parentNode.removeChild(t),ut(this._tooltip),ut(this._bondTooltip),this._tooltip=null,this._bondTooltip=null}_renderFresh(){let t=this._editor.getService(),e=this._currentTheme(),i=this._editor.getMol();null===this._pinnedBbox&&(this._pinnedBbox=function(t,e=q){if(0===t.atoms.length)return{x:0,y:0,width:0,height:0};let i=X(t.atoms[0],e);for(let r=1;r<t.atoms.length;r++)i=R(i,X(t.atoms[r],e));return i}(i,e));let r=t.renderMol(i,{width:this._width,height:this._height,theme:e,fixedModelBbox:this._pinnedBbox});this._svgRoot=function(t,e){let i=lt(t),r=t.querySelector(".hw-editor-view");if(null===r)throw new Error("EditorView.replaceSvg: missing .hw-editor-view wrapper.");let s=i.createElement("div");s.innerHTML=e;let l=s.querySelector("svg");if(null===l)throw new Error("EditorView.replaceSvg: rendered output contained no <svg>.");for(;null!==r.firstChild;)r.removeChild(r.firstChild);return r.appendChild(l),l}(this.host,r);let s=this._svgRoot.querySelector(".hw-content");return this._baseTransform=null!==s?s.getAttribute("transform")??"":"",this._svgRoot.setAttribute("data-testid","editor-svg"),this._applyOverlaysToCurrent(),(1!==this._viewport.scale||0!==this._viewport.offset.x||0!==this._viewport.offset.y)&&this._applyViewport(this._viewport),this._svgRoot}_refreshOverlays(t){this._applyOverlaysToCurrent()}_applyOverlaysToCurrent(){let t=this._editor.getMol(),e=this._editor.getSelection(),i=function(t,e={}){let i=e.theme??q,r=e.selectedAtomIds??new Set;return{highlightLayer:it(t,i,e.highlightedAtomIds??new Set),selectionLayer:rt(t,i,r)}}(t,{theme:this._currentTheme(),selectedAtomIds:e.atoms,highlightedAtomIds:this._editorHighlights()});this._spliceLayer("hw-highlights",i.highlightLayer),this._spliceLayer("hw-selections",i.selectionLayer)}_spliceLayer(t,e){let i=this._svgRoot.querySelector(`.${t}`);if(null===i||null===i.parentNode)return;let r=this._doc.createElementNS("http://www.w3.org/2000/svg","svg");r.innerHTML=e;let s=r.querySelector(`.${t}`);null!==s&&i.parentNode.replaceChild(s,i)}_editorHighlights(){let t=this._editor;return"function"==typeof t._currentHighlights?t._currentHighlights():new Set}_currentTheme(){let t=this._editor;return"function"==typeof t._currentTheme?t._currentTheme():this._editor.getService().theme}_applyResize(t,e){this._width=t,this._height=e,this._pinnedBbox=null,this._renderFresh()}_applyViewport(t){let e=this._svgRoot.querySelector(".hw-content");if(null===e)return;let i=`translate(${t.offset.x} ${t.offset.y}) scale(${t.scale})`,r=""===this._baseTransform?i:`${i} ${this._baseTransform}`;e.setAttribute("transform",r)}_showTooltip(t,e,i){let r=this._tooltip;if(null===r)return;let s=""===t.symbol?"?":t.symbol,l=t.monomer?.name??"",o=t.bio.positionInChain,n=""===t.bio.chainId?"?":t.bio.chainId,a=""!==l&&l!==s?`${l} @ ${n}:${o}`:`${s} @ ${n}:${o}`,h=this._renderRdkitTooltipSvg(t);ht(this._doc,r,{symbol:s,name:a,rdkitSvg:h,rdkitTestid:"atom-tooltip-rdkit-svg"});let d=""!==l&&l!==s?`${s} — ${l} @ ${n}:${o}`:`${s} @ ${n}:${o}`,u=this._doc.createElement("div");u.setAttribute("class","hw-atom-tooltip__text"),u.style.display="none",u.appendChild(this._doc.createTextNode(d)),r.appendChild(u),dt(r,e,i)}_renderRdkitTooltipSvg(e){let i=this._editor.getService().options.rdkitModule;if(null==i)return null;let r=e.monomer;if(null===r)return null;let s=r.smiles;if(void 0===s||""===s)return null;let l=`${r.polymerType}:${r.symbol}`;if(this._rdkitSvgCache.has(l))return this._rdkitSvgCache.get(l)??null;let o=nt(i,s,220,140);if(this._rdkitSvgCache.size>=t._RDKIT_CACHE_LIMIT){let t=this._rdkitSvgCache.keys().next().value;void 0!==t&&this._rdkitSvgCache.delete(t)}return this._rdkitSvgCache.set(l,o),o}_hideTooltip(){ut(this._tooltip)}_showBondTooltip(t,e,i){let r=this._bondTooltip;if(null===r)return;let s=_t(t.r1),l=_t(t.r2),o=`${t.a1.symbol}@${t.a1.bio.chainId}:${t.a1.bio.positionInChain}`,n=`${t.a2.symbol}@${t.a2.bio.chainId}:${t.a2.bio.positionInChain}`;ht(this._doc,r,{symbol:`${s}-${l} (${t.kind})`,name:`${o} ↔ ${n}`}),dt(r,e,i)}_hideBondTooltip(){ut(this._bondTooltip)}_paintBondPreview(t,e,i){let r=this._svgRoot.querySelector(".hw-content");if(null===r)return;let s=r.querySelector(".hw-bond-preview");null===s&&(s=this._doc.createElementNS("http://www.w3.org/2000/svg","line"),s.setAttribute("class","hw-bond-preview"),s.setAttribute("data-testid","bond-preview"),s.setAttribute("stroke-dasharray","6 4"),s.setAttribute("stroke-width","2"),s.setAttribute("fill","none"),s.setAttribute("pointer-events","none"),r.appendChild(s)),s.setAttribute("x1",String(t.x)),s.setAttribute("y1",String(t.y)),s.setAttribute("x2",String(e.x)),s.setAttribute("y2",String(e.y)),s.setAttribute("stroke",i?"#1f5fcd":"#999999")}_clearBondPreview(){let t=this._svgRoot.querySelector(".hw-bond-preview");null!==t&&null!==t.parentNode&&t.parentNode.removeChild(t)}_paintSelectionRect(t,e){let i=Math.min(t.x,e.x),r=Math.min(t.y,e.y),s=Math.abs(t.x-e.x),l=Math.abs(t.y-e.y);this._paintSelectionRectAt(i,r,s,l)}_paintSelectionRectFromRect(t){this._paintSelectionRectAt(t.x,t.y,t.width,t.height)}_paintSelectionRectAt(t,e,i,r){let s=this._svgRoot.querySelector(".hw-content");if(null===s)return;let l=s.querySelector(".hw-selection-rect");null===l&&(l=this._doc.createElementNS("http://www.w3.org/2000/svg","rect"),l.setAttribute("class","hw-selection-rect"),l.setAttribute("data-testid","selection-rect"),l.setAttribute("fill","rgba(31, 95, 205, 0.08)"),l.setAttribute("stroke","#1f5fcd"),l.setAttribute("stroke-width","1"),l.setAttribute("stroke-dasharray","4 3"),l.setAttribute("pointer-events","none"),s.appendChild(l)),l.setAttribute("x",String(t)),l.setAttribute("y",String(e)),l.setAttribute("width",String(i)),l.setAttribute("height",String(r))}_clearSelectionRect(){let t=this._svgRoot.querySelector(".hw-selection-rect");null!==t&&null!==t.parentNode&&t.parentNode.removeChild(t)}};pt._RDKIT_CACHE_LIMIT=256;function _t(t){switch(t.kind){case"numeric":return`R${t.r}`;case"unspecified":return"?";case"wildcard":return"*";case"pair":return"pair";case"positional":return`${t.position}pos:R${t.r}`}}var bt=class t{constructor(t,e){this._onClose=null,this._primaryAction=null,this._host=t,this._doc=e.documentImpl??lt(t);let i=this._doc,r={class:"hw-modal-backdrop",role:"presentation"};void 0!==e.testId&&(r["data-testid"]=`dialog-${e.testId}`);let s=ot(i,"div",r),l={class:"hw-modal",role:"dialog","aria-modal":"true","aria-label":e.title};void 0!==e.testId&&(l["data-testid"]=`dialog-${e.testId}-frame`);let o=ot(i,"div",l),n=ot(i,"div",{class:"hw-modal__header"},[e.title]),a=ot(i,"div",{class:"hw-modal__body"});o.appendChild(n),o.appendChild(a),s.appendChild(o);let h=t=>{t.stopPropagation()};for(let t of["mousedown","mousemove","mouseup","mouseover","mouseenter","mouseleave","wheel","contextmenu","dblclick","keydown","keyup","keypress"])s.addEventListener(t,h);o.addEventListener("keydown",t=>{let e=t;if("Enter"!==e.key||"TEXTAREA"===e.target?.tagName)return;let i=this._primaryAction;null!==i&&(e.preventDefault?.(),e.stopImmediatePropagation?.(),i())}),s.addEventListener("click",t=>{t.target!==s?t.stopPropagation():this.close()}),this.root=s,this.body=a}static anyOpen(){return t._openStack.length>0}static closeTopmost(){let e=t._openStack[t._openStack.length-1];return void 0!==e&&(e.close(),!0)}open(e){this._onClose=e??null,null===this.root.parentNode&&this._host.appendChild(this.root),t._openStack.includes(this)||t._openStack.push(this),ct(this._doc)}close(){let e=t._openStack.indexOf(this);e>=0&&t._openStack.splice(e,1),null!==this.root.parentNode&&this.root.parentNode.removeChild(this.root);let i=this._onClose;this._onClose=null,null!==i&&i()}setPrimaryAction(t){this._primaryAction=t}get isOpen(){return null!==this.root.parentNode}};bt._openStack=[];Object.freeze(new Set);function ft(t){return t.startsWith("[")&&t.endsWith("]")||1===t.length&&/^[A-Za-z]$/.test(t)?t:`[${t}]`}function mt(t,e,i){return`${ft(t)}(${ft(e)})${ft(i)}`}var gt="http://www.w3.org/2000/svg",yt={sugar:s,base:l,linker:o},vt={sugar:["r","R"],base:["A"],linker:["p","P"]},wt={x:70,y:60},At={x:140,y:60},St={x:70,y:130},Ct=class t{constructor(t,e,i){this.onValueSet=new u,this.onPickModeChange=new u,this._slots=new Map,this._favStar=null,this._pickMode=null,this._destroyed=!1,this._builderRdkitCache=new Map,this._editor=e,this._doc=i?.documentImpl??lt(t),this._hooks=i?.paletteHooks??null,this._favHooks=i?.favoriteHooks??null,this.element=ot(this._doc,"div",{class:"hw-rna-builder","data-testid":"rna-builder"});let r=ot(this._doc,"div",{class:"hw-rna-builder__header"});if(r.appendChild(ot(this._doc,"div",{class:"hw-rna-builder__title"},["RNA builder"])),null!==this._favHooks){let t=ot(this._doc,"span",{class:"hw-rna-builder__fav hw-rna-builder__fav--disabled",role:"button",tabindex:"0","data-testid":"rna-builder-fav-star",title:"Favorite this triplet","aria-pressed":"false","aria-disabled":"true"},["☆"]),e=t=>{t.stopPropagation();let e=this.getSelection();""===e.preview||null===this._favHooks||this._favHooks.toggleFavoriteTriplet(e.sugar,e.base,e.linker)};t.addEventListener("click",e),t.addEventListener("keydown",t=>{let i=t;("Enter"===i.key||" "===i.key)&&e(t)}),this._favStar=t,r.appendChild(t)}this.element.appendChild(r),this._hintEl=ot(this._doc,"div",{class:"hw-rna-builder__hint","data-testid":"rna-builder-hint",hidden:!0}),this.element.appendChild(this._hintEl);let s=this._buildSvg();this.element.appendChild(s),this._preview=ot(this._doc,"div",{class:"hw-rna-builder__preview","data-testid":"rna-builder-preview"}),this.element.appendChild(this._preview),this._addBtn=ot(this._doc,"button",{class:"hw-rna-builder__add",type:"button","data-testid":"rna-builder-add-btn"},["Add triplet"]),this._addBtn.addEventListener("click",()=>this._onAddClicked()),this.element.appendChild(this._addBtn),t.appendChild(this.element);let l=e.getService().monomerLib.onChanged.subscribe(()=>{this._destroyed||this.refresh()}),o=e.on("theme:change",()=>{this._destroyed||this._repaintSlotColors()});this._libUnsub=()=>{try{l()}catch{}try{o()}catch{}},this._populateDefaults(),this._updatePreview(),this._repaintSlotColors()}refresh(){this._populateDefaults(),this._updatePreview(),this._repaintSlotColors()}getSelection(){let t=this._slots.get("sugar")?.value??"",e=this._slots.get("base")?.value??"",i=this._slots.get("linker")?.value??"";return{sugar:t,base:e,linker:i,preview:""!==t&&""!==e&&""!==i?mt(t,e,i):""}}setField(t,e){let i=this._slots.get(t);void 0!==i&&(i.value=e,this._setLabelText(i.labelEl,e),this._repaintSlot(i),this._updatePreview(),this.onValueSet.next({field:t,symbol:e}))}startPickMode(t){this._pickMode!==t?(null!==this._pickMode&&this._setSlotPressed(this._pickMode,!1),this._pickMode=t,this._setSlotPressed(t,!0),this._setHintActive(t),this.onPickModeChange.next({field:t}),null!==this._hooks&&this._hooks.beginBiotypeFilter(yt[t],e=>{this.setField(t,e),this._exitPickMode()},()=>{this._exitPickMode()})):this.cancelPickMode()}cancelPickMode(){null!==this._pickMode&&(null!==this._hooks&&this._hooks.endBiotypeFilter(),this._exitPickMode())}getPickMode(){return this._pickMode}triggerAdd(){this._onAddClicked()}destroy(){this._destroyed||(this._destroyed=!0,null!==this._pickMode&&null!==this._hooks&&this._hooks.endBiotypeFilter(),this._libUnsub(),this.onValueSet.complete(),this.onPickModeChange.complete(),null!==this.element.parentNode&&this.element.parentNode.removeChild(this.element))}_buildSvg(){let t=this._doc.createElementNS(gt,"svg");t.setAttribute("class","hw-rna-builder__triplet"),t.setAttribute("viewBox","0 0 200 180"),t.setAttribute("data-testid","rna-builder-triplet-svg"),t.setAttribute("role","group"),t.setAttribute("aria-label","Triplet preview");let e=this._doc.createElementNS(gt,"line");e.setAttribute("class","hw-rna-builder__bond"),e.setAttribute("x1",String(wt.x+18)),e.setAttribute("y1",String(wt.y)),e.setAttribute("x2",String(At.x-18)),e.setAttribute("y2",String(At.y)),t.appendChild(e);let i=this._doc.createElementNS(gt,"line");i.setAttribute("class","hw-rna-builder__bond"),i.setAttribute("x1",String(wt.x)),i.setAttribute("y1",String(wt.y+18)),i.setAttribute("x2",String(St.x)),i.setAttribute("y2",String(St.y-22)),t.appendChild(i);let r=this._doc.createElementNS(gt,"rect");r.setAttribute("class","hw-rna-builder__slot-shape"),r.setAttribute("x",String(-18)),r.setAttribute("y",String(-18)),r.setAttribute("width",String(36)),r.setAttribute("height",String(36)),r.setAttribute("rx","8"),r.setAttribute("ry","8");let s=this._buildSlot("sugar","Pick sugar (backbone)",wt,r),l=this._doc.createElementNS(gt,"circle");l.setAttribute("class","hw-rna-builder__slot-shape"),l.setAttribute("cx","0"),l.setAttribute("cy","0"),l.setAttribute("r",String(18));let o=this._buildSlot("linker","Pick linker",At,l),n=this._doc.createElementNS(gt,"path");n.setAttribute("class","hw-rna-builder__slot-shape"),n.setAttribute("d","M -22 0 L 0 -22 L 22 0 L 0 22 Z");let a=this._buildSlot("base","Pick base",St,n);return t.appendChild(o.groupEl),t.appendChild(s.groupEl),t.appendChild(a.groupEl),this._slots.set("sugar",s),this._slots.set("linker",o),this._slots.set("base",a),t}_buildSlot(t,e,i,r){let s=this._doc.createElementNS(gt,"g");s.setAttribute("class","hw-rna-builder__slot"),s.setAttribute("data-slot",t),s.setAttribute("data-testid",`rna-builder-slot-${t}`),s.setAttribute("role","button"),s.setAttribute("tabindex","0"),s.setAttribute("aria-label",e),s.setAttribute("aria-pressed","false"),s.setAttribute("transform",`translate(${i.x} ${i.y})`),s.appendChild(r);let l=this._doc.createElementNS(gt,"text");l.setAttribute("class","hw-rna-builder__slot-label"),l.setAttribute("data-testid",`rna-builder-${t}-value`),l.setAttribute("x","0"),l.setAttribute("y","0"),l.setAttribute("text-anchor","middle"),l.setAttribute("dominant-baseline","central"),s.appendChild(l);let o=e=>{e.stopPropagation(),this.startPickMode(t)};return s.addEventListener("click",o),s.addEventListener("keydown",t=>{let e=t;("Enter"===e.key||" "===e.key)&&o(t)}),s.addEventListener("mouseenter",e=>this._showSlotTooltip(t,e)),s.addEventListener("mouseleave",()=>this._hideSlotTooltip()),s.addEventListener("focus",()=>this._showSlotTooltip(t,null)),s.addEventListener("blur",()=>this._hideSlotTooltip()),{id:t,biotype:yt[t],groupEl:s,shapeEl:r,labelEl:l,value:""}}_setLabelText(t,e){let i=[];for(let e=t.firstChild;null!==e;e=e.nextSibling)"title"===e.nodeName||"TITLE"===e.nodeName||i.push(e);for(let e of i)t.removeChild(e);let r=function(t){let e=t.length;return e<=2?16:e<=4?11:e<=7?8:e<=10?6:5}(e);t.setAttribute("font-size",String(r)),t.setAttribute("text-anchor","middle"),t.setAttribute("dominant-baseline","central");let s=e.length>10?`${e.slice(0,9)}…`:e;t.appendChild(this._doc.createTextNode(s));let l=t.parentNode;if(null!==l){let t=null;for(let e=l.firstChild;null!==e;e=e.nextSibling)if("title"===e.nodeName||"TITLE"===e.nodeName){t=e;break}for(null===t&&(t=this._doc.createElementNS(gt,"title"),l.insertBefore(t,l.firstChild));null!==t.firstChild;)t.removeChild(t.firstChild);t.appendChild(this._doc.createTextNode(e))}}_repaintSlotColors(){for(let t of this._slots.values())this._repaintSlot(t)}_repaintSlot(t){let e=this._editor.getService().monomerLib,i=this._theme(),r=""===t.value?null:function(t,e,i){return t.getMonomerSet(e).get(i)??null}(e,t.biotype,t.value),s=F(r,t.biotype,i.colorTheme);t.shapeEl.style.fill=s.background,t.shapeEl.style.stroke=s.line,t.labelEl.style.fill=s.text}_populateDefaults(){let t=this._editor.getService().monomerLib;for(let[e,i]of this._slots.entries()){let r=Tt(t,i.biotype),s=Et(r,vt[e]),l=""!==i.value&&r.some(t=>t.symbol===i.value)?i.value:s??r[0]?.symbol??"";i.value=l,this._setLabelText(i.labelEl,l)}}_updatePreview(){let t=this.getSelection();for(;null!==this._preview.firstChild;)this._preview.removeChild(this._preview.firstChild);this._preview.appendChild(this._doc.createTextNode(""===t.preview?"-":t.preview)),this._updateFavStar(t)}_updateFavStar(t){if(null===this._favStar||null===this._favHooks)return;let e=""!==t.preview,i=e&&this._favHooks.isFavoriteTriplet(t.sugar,t.base,t.linker);for(;null!==this._favStar.firstChild;)this._favStar.removeChild(this._favStar.firstChild);this._favStar.appendChild(this._doc.createTextNode(i?"★":"☆")),this._favStar.setAttribute("aria-pressed",i?"true":"false"),e?this._favStar.removeAttribute("aria-disabled"):this._favStar.setAttribute("aria-disabled","true");let r="hw-rna-builder__fav"+(i?" hw-rna-builder__fav--active":"")+(e?"":" hw-rna-builder__fav--disabled");this._favStar.setAttribute("class",r)}_onAddClicked(){let t=this.getSelection();""!==t.preview&&this._editor.placeRnaTriplet(t.sugar,t.base,t.linker)}_exitPickMode(){if(null===this._pickMode)return;let t=this._pickMode;this._setSlotPressed(t,!1),this._pickMode=null,this._setHintActive(null),this.onPickModeChange.next({field:null})}_setHintActive(t){let e=this._hintEl;for(;null!==e.firstChild;)e.removeChild(e.firstChild);if(null===t)return void e.setAttribute("hidden","");e.removeAttribute("hidden");let i="sugar"===t?"sugar":"base"===t?"base":"linker";e.appendChild(this._doc.createTextNode(`Pick ${i} from palette`))}_setSlotPressed(t,e){let i=this._slots.get(t);if(void 0===i)return;i.groupEl.setAttribute("aria-pressed",e?"true":"false");let r=(i.groupEl.getAttribute("class")??"").split(/\s+/).filter(t=>"hw-rna-builder__slot--active"!==t).join(" ");i.groupEl.setAttribute("class",e?`${r} hw-rna-builder__slot--active`:r)}_theme(){let t=this._editor;return"function"==typeof t._currentTheme?t._currentTheme():this._editor.getService().theme}_rdkit(){let t=this._editor.getService().options?.rdkitModule;return t??null}_builderRdkitSvgFor(e){if(null===e)return null;let i=e.smiles;if(void 0===i||""===i)return null;let r=this._rdkit();if(null===r)return null;let s=`${e.polymerType}:${e.symbol}`;if(this._builderRdkitCache.has(s))return this._builderRdkitCache.get(s)??null;let l=nt(r,i,220,140);if(this._builderRdkitCache.size>=t._BUILDER_RDKIT_CACHE_LIMIT){let t=this._builderRdkitCache.keys().next().value;void 0!==t&&this._builderRdkitCache.delete(t)}return this._builderRdkitCache.set(s,l),l}_slotHint(t){switch(t){case"sugar":return"Click to choose a different sugar";case"base":return"Click to choose a different base";case"linker":return"Click to choose a different linker"}}_slotTitle(t,e){let i=""===e?"?":e;switch(t){case"sugar":return`Sugar: ${i}`;case"base":return`Base: ${i}`;case"linker":return`Linker: ${i}`}}_showSlotTooltip(t,e){let i=this._slots.get(t);if(void 0===i)return;let r=this._editor.getService().monomerLib.getMonomerSet(i.biotype),s=""===i.value?null:r.get(i.value)??null,l=at(this._doc,"builder-tooltip","hw-builder-tooltip");ht(this._doc,l,{symbol:this._slotTitle(t,i.value),name:s?.name??"",rdkitSvg:this._builderRdkitSvgFor(s),rdkitTestid:"builder-tooltip-rdkit-svg",hint:this._slotHint(t)});let o=e;if(null!==o&&"number"==typeof o.clientX&&"number"==typeof o.clientY)dt(l,o.clientX,o.clientY);else{let t=i.groupEl,e="function"==typeof t.getBoundingClientRect?t.getBoundingClientRect():null;null!==e?dt(l,e.left+e.width/2,e.top+e.height/2):dt(l,0,0)}}_hideSlotTooltip(){ut(this._doc.body.querySelector('[data-testid="builder-tooltip"]'))}};Ct._BUILDER_RDKIT_CACHE_LIMIT=256;var kt=Ct;function Tt(t,e){let i=t.getMonomerSet(e),r=[];for(let t of i.values())r.push(t);return r.sort((t,e)=>t.symbol.localeCompare(e.symbol)),r}function Et(t,e){let i=new Set;for(let e of t)i.add(e.symbol);for(let t of e)if(i.has(t))return t;return null}var Nt="Favorites",Mt={[Nt]:"★ Favorites",[d.PEPTIDE]:"Peptides",[d.RNA]:"RNA",[d.CHEM]:"CHEM",[d.BLOB]:"BLOB",G:"G"},It=[Nt,d.PEPTIDE,d.RNA,d.CHEM,d.BLOB,"G"],Bt="hwe:palette:favorites",xt="hwe:palette:active-tab";function Lt(t){return`${t.sugar}|${t.base}|${t.linker}`}var Pt=class t{constructor(t,e,i){this.favoritesChanged=new u,this._nextAddUnsub=()=>{},this._favorites=new Set,this._favoriteTriplets=[],this._pendingRnaSelection=null,this._visibleTabs=[Nt],this._activeTab=Nt,this._searchInput=null,this._filter="",this._destroyed=!1,this._rnaBuilder=null,this._activeBiotypeFilter=null,this._pickResolver=null,this._pickCanceller=null,this._pickEscapeListener=null,this._pickOutsideClickListener=null,this._paletteRdkitCache=new Map,this._editor=e,this._doc=i?.documentImpl??lt(t),this._opts={documentImpl:this._doc,groupByNaturalAnalog:i?.groupByNaturalAnalog??!0,allowFavorites:i?.allowFavorites??!0},this._loadFavorites(),this._activeTab=this._resolveInitialTab(i?.initialTab),this.element=ot(this._doc,"div",{class:"hw-palette","data-testid":"palette"}),t.appendChild(this.element),this._render(),this._libUnsub=e.getService().monomerLib.onChanged.subscribe(()=>{this._destroyed||this.refresh()}),this._themeUnsub=e.on("theme:change",()=>{this._destroyed||this.refresh()}),this._nextAddUnsub=e.on("option:change",t=>{this._destroyed||"nextAdd"===t.key&&this._updatePrimedClasses()})}refresh(){this._render()}setFilter(t){this._filter=t.trim().toLowerCase(),null!==this._searchInput&&this._searchInput.value!==t&&(this._searchInput.value=t),this._applyFilter()}setActiveTab(t){this._visibleTabs.includes(t)&&(this._activeTab=t,this._persistActiveTab(),this._applyActiveTabClasses(),this._applyFilter())}getActiveTab(){return this._activeTab}getFavorites(){let t=this._editor.getService().monomerLib,e=[];for(let i of this._favorites)null!==this._findMonomer(t,i)&&e.push(i);return e}setFavorite(t,e){e!==this._favorites.has(t)&&(e?this._favorites.add(t):this._favorites.delete(t),this._saveFavorites(),this._hidePaletteTooltips(),this._render(),this._emitFavoritesChanged())}clearFavorites(){0===this._favorites.size&&0===this._favoriteTriplets.length||(this._favorites.clear(),this._favoriteTriplets.length=0,this._saveFavorites(),this._render(),this._emitFavoritesChanged())}getFavoriteTriplets(){return this._favoriteTriplets.map(t=>({...t}))}isFavoriteTriplet(t,e,i){let r=Lt({sugar:t,base:e,linker:i});return this._favoriteTriplets.some(t=>Lt(t)===r)}setFavoriteTriplet(t,e,i,r){let s=Lt({sugar:t,base:e,linker:i}),l=this._favoriteTriplets.findIndex(t=>Lt(t)===s);r!==l>=0&&(r?this._favoriteTriplets.push({sugar:t,base:e,linker:i}):this._favoriteTriplets.splice(l,1),this._saveFavorites(),this._hidePaletteTooltips(),this._render(),this._emitFavoritesChanged())}_hidePaletteTooltips(){let t=this._doc.body;ut(t.querySelector('[data-testid="palette-tooltip"]')),ut(t.querySelector('[data-testid="palette-triplet-tooltip"]'))}_emitFavoritesChanged(){this.favoritesChanged.next({favorites:this.getFavorites(),triplets:this.getFavoriteTriplets()})}destroy(){this._destroyed||(this._destroyed=!0,null!==this._rnaBuilder&&(this._rnaBuilder.destroy(),this._rnaBuilder=null),this._libUnsub(),this._themeUnsub(),this._nextAddUnsub(),null!==this.element.parentNode&&this.element.parentNode.removeChild(this.element))}getRnaBuilder(){return this._rnaBuilder}hasActiveBiotypeFilter(){return null!==this._activeBiotypeFilter}getActiveBiotypeFilter(){return this._activeBiotypeFilter}cancelBiotypeFilter(){if(null===this._activeBiotypeFilter)return;let t=this._pickCanceller;this._teardownPickMode(),t?.()}_buildPaletteFilterHooks(){return{beginBiotypeFilter:(t,e,i)=>{null!==this._activeBiotypeFilter&&this._teardownPickMode(),this._activeBiotypeFilter=t,this._pickResolver=e,this._pickCanceller=i,this._applyFilter();let r=t=>{"Escape"===t.key&&this.cancelBiotypeFilter()};this._pickEscapeListener=r,this._doc.defaultView?.addEventListener("keydown",r);let s=t=>{if(null===this._activeBiotypeFilter)return;let e=t.target;if(null==e)return;let i=this._activeBiotypeFilter,r=e;for(;null!==r;){let t=void 0===r.getAttribute?null:r.getAttribute("class");if(null!==t){let e=t.split(/\s+/);if(e.includes("hw-palette__tile")){if((r.getAttribute("data-biotype")??"")===i)return;break}if(e.includes("hw-rna-builder__slot")){if(this._isInsideOwnPalette(r))return;break}}r=r.parentElement}this.cancelBiotypeFilter()};this._pickOutsideClickListener=s,this._doc.addEventListener("mousedown",s,!0)},endBiotypeFilter:()=>this._teardownPickMode()}}_scrollActivePaneToTop(){let t=this.element.querySelector(`.hw-palette__pane[data-tab="${this._activeTab}"]`);if(null===t)return;let e=t;try{if("function"==typeof e.scrollTo)return void e.scrollTo({top:0,behavior:"smooth"})}catch{}"number"==typeof e.scrollTop&&(e.scrollTop=0)}_isInsideOwnPalette(t){let e=t;for(;null!==e;){if(e===this.element)return!0;e=e.parentElement}return!1}_teardownPickMode(){null!==this._activeBiotypeFilter&&(this._activeBiotypeFilter=null,this._pickResolver=null,this._pickCanceller=null,null!==this._pickEscapeListener&&(this._doc.defaultView?.removeEventListener("keydown",this._pickEscapeListener),this._pickEscapeListener=null),null!==this._pickOutsideClickListener&&(this._doc.removeEventListener("mousedown",this._pickOutsideClickListener,!0),this._pickOutsideClickListener=null),this._applyFilter())}_render(){for(null!==this._rnaBuilder&&(this._pendingRnaSelection=this._rnaBuilder.getSelection(),this._rnaBuilder.destroy(),this._rnaBuilder=null);null!==this.element.firstChild;)this.element.removeChild(this.element.firstChild);let t=this._doc.createElement("input");t.setAttribute("type","search"),t.setAttribute("class","hw-palette__search"),t.setAttribute("placeholder","Search monomers..."),t.setAttribute("data-testid","palette-search"),""!==this._filter&&(t.value=this._filter),t.addEventListener("input",()=>this.setFilter(t.value)),this._searchInput=t,this.element.appendChild(t),this._visibleTabs=this._computeVisibleTabs(),this._visibleTabs.includes(this._activeTab)||(this._activeTab=Nt);let e=ot(this._doc,"div",{class:"hw-palette__tabs",role:"tablist","data-testid":"palette-tabs"});for(let t of this._visibleTabs){let i=t===this._activeTab,r=ot(this._doc,"button",{class:"hw-palette__tab",type:"button",role:"tab","aria-controls":`hw-palette-pane-${t}`,"aria-selected":i?"true":"false","data-testid":`palette-tab-${t}`,"data-tab":t,title:Mt[t]},[Mt[t]]);r.addEventListener("click",()=>this.setActiveTab(t)),e.appendChild(r)}this.element.appendChild(e);let i=ot(this._doc,"div",{class:"hw-palette__panes"}),r=this._theme(),s=this._editor.getService().monomerLib;for(let t of this._visibleTabs){let e=t===this._activeTab,l=ot(this._doc,"div",{class:"hw-palette__pane",id:`hw-palette-pane-${t}`,role:"tabpanel","data-testid":`palette-pane-${t}`,"data-tab":t,hidden:!e});t===Nt?this._buildFavoritesPane(l,s,r):this._buildPolymerPane(l,t,s,r),i.appendChild(l)}this.element.appendChild(i),this._applyFilter()}_computeVisibleTabs(){let t=this._editor.getService().monomerLib,e=new Set;for(let i of t.getPolymerTypes())e.add(i);let i=[];i.push(Nt);for(let t of It)t!==Nt&&e.has(t)&&i.push(t);return i}_buildFavoritesPane(t,e,i){let r=this._resolveFavoriteMonomers(e),s=this._favoriteTriplets;if(0===r.length&&0===s.length){let e=ot(this._doc,"div",{class:"hw-palette__placeholder","data-testid":"palette-favorites-empty"},["No favorites yet — click the ☆ on any tile to add one."]);return void t.appendChild(e)}for(let[e,i]of this._groupByPolymerAndType(r))t.appendChild(this._renderGroup(e,i));s.length>0&&t.appendChild(this._renderTripletGroup("RNA · Triplets",s,e))}_groupByPolymerAndType(t){let e=new Map;for(let i of t){let t=i.polymerType,r=i.monomerType??"Undefined",s=`${t}|${r}`,l=e.get(s);void 0===l&&(l={pt:t,mt:r,list:[]},e.set(s,l)),l.list.push(i)}let i=t=>{let e=It.indexOf(t);return e<0?99:e},r={Backbone:0,Branch:1,Terminal:2,Undefined:3};return Array.from(e.values()).sort((t,e)=>i(t.pt)-i(e.pt)||(r[t.mt]??9)-(r[e.mt]??9)||t.mt.localeCompare(e.mt)).map(t=>[`${this._polymerLabel(t.pt)} · ${t.mt}`,t.list])}_polymerLabel(t){return Mt[t]??t}_renderTripletGroup(t,e,i){let r=ot(this._doc,"div",{class:"hw-palette__group","data-natural-analog":t}),s=ot(this._doc,"div",{class:"hw-palette__group-header","data-testid":`palette-group-${t}`},[t]),l=ot(this._doc,"div",{class:"hw-triplet-chips","data-testid":"palette-triplet-favorites"});for(let t of e)l.appendChild(this._renderTripletChip(t,i));return r.appendChild(s),r.appendChild(l),r}_renderTripletChip(t,e){let i=mt(t.sugar,t.base,t.linker),r=e.getMonomerSet(l).get(t.base)??null,s=F(r,l,this._theme().colorTheme),o=this.isFavoriteTriplet(t.sugar,t.base,t.linker),n=void 0!==r?.name&&""!==r.name?`${i} — ${r.name}`:i,{root:a}=function(t,e){let i=!1!==e.showStar,r=ot(t,"span",{class:"hw-triplet-chip__star"},[e.favorite?"★":"☆"]),s=ot(t,"span",{class:"hw-triplet-chip__label"},[e.label]),l=["hw-triplet-chip"];e.favorite&&l.push("hw-triplet-chip--favorite");let o=i?[r,s]:[s];return{root:ot(t,"div",{class:l.join(" "),role:"button",tabindex:"0","aria-label":e.title,"data-sugar":e.sugar,"data-base":e.base,"data-linker":e.linker,"data-triplet":e.label,"data-testid":`palette-triplet-${e.label}`,title:e.title,style:`background:${e.background};color:${e.textColor};`},o),star:r}}(this._doc,{sugar:t.sugar,base:t.base,linker:t.linker,label:i,title:n,background:v(s.background),textColor:s.text,favorite:o,showStar:this._opts.allowFavorites});return this._wireTripletChip(a,t),a}_wireTripletChip(t,e){t.addEventListener("mouseenter",t=>{let i=t,r=at(this._doc,"palette-triplet-tooltip","hw-palette-tooltip hw-triplet-tooltip");(function(t,e,i){for(;null!==e.firstChild;)e.removeChild(e.firstChild);e.appendChild(ot(t,"div",{class:"hw-tooltip__symbol"},[i.title]));let r=ot(t,"div",{class:"hw-tooltip__triplet"});for(let e of i.parts){let s=ot(t,"div",{class:"hw-tooltip__triplet-part"});if(s.appendChild(ot(t,"div",{class:"hw-tooltip__triplet-role"},[`${e.role}: ${e.symbol}`])),void 0!==e.name&&""!==e.name&&e.name!==e.symbol&&s.appendChild(ot(t,"div",{class:"hw-tooltip__name"},[e.name])),void 0!==e.rdkitSvg&&null!==e.rdkitSvg&&""!==e.rdkitSvg){let r={class:"hw-tooltip__rdkit"};void 0!==i.rdkitTestid&&(r["data-testid"]=i.rdkitTestid);let l=ot(t,"div",r);l.innerHTML=e.rdkitSvg,s.appendChild(l)}r.appendChild(s)}e.appendChild(r),void 0!==i.hint&&""!==i.hint&&e.appendChild(ot(t,"div",{class:"hw-tooltip__hint"},[i.hint]))})(this._doc,r,{title:mt(e.sugar,e.base,e.linker),parts:this._tripletTooltipParts(e),hint:"Click to add this triplet",rdkitTestid:"palette-triplet-tooltip-rdkit-svg"}),dt(r,"number"==typeof i.clientX?i.clientX:0,"number"==typeof i.clientY?i.clientY:0)}),t.addEventListener("mouseleave",()=>{ut(this._doc.body.querySelector('[data-testid="palette-triplet-tooltip"]'))}),t.addEventListener("click",t=>{let i=t.target;if(this._opts.allowFavorites&&!0===i?.classList?.contains("hw-triplet-chip__star"))return this.setFavoriteTriplet(e.sugar,e.base,e.linker,!this.isFavoriteTriplet(e.sugar,e.base,e.linker)),void t.stopPropagation();this._editor.placeRnaTriplet(e.sugar,e.base,e.linker)}),t.addEventListener("keydown",t=>{let i=t;("Enter"===i.key||" "===i.key)&&this._editor.placeRnaTriplet(e.sugar,e.base,e.linker)})}_buildRnaDefaultChips(e){let i=this._pickSymbol(e.getMonomerSet(s),["r","R"]),r=this._pickSymbol(e.getMonomerSet(o),["p","P"]),n=e.getMonomerSet(l);if(null===i||null===r)return null;let a=t._DEFAULT_TRIPLET_BASES.filter(t=>n.has(t));if(0===a.length)return null;let h=ot(this._doc,"div",{class:"hw-triplet-chips hw-triplet-chips--defaults","data-testid":"rna-default-triplets"});for(let t of a)h.appendChild(this._renderTripletChip({sugar:i,base:t,linker:r},e));return h}_tripletTooltipParts(t){let e=this._editor.getService().monomerLib,i=(t,i,r)=>{let s=e.getMonomerSet(i).get(r)??null;return{role:t,symbol:r,...void 0!==s?.name?{name:s.name}:{},rdkitSvg:null===s?null:this._paletteRdkitSvg(s)}};return[i("Sugar",s,t.sugar),i("Base",l,t.base),i("Linker",o,t.linker)]}_pickSymbol(t,e){for(let i of e)if(t.has(i))return i;let i=t.keys().next();return!0===i.done?null:i.value}_restoreRnaSelection(){let t=this._pendingRnaSelection;if(this._pendingRnaSelection=null,null===t||null===this._rnaBuilder)return;let e=this._editor.getService().monomerLib;""!==t.sugar&&e.getMonomerSet(s).has(t.sugar)&&this._rnaBuilder.setField("sugar",t.sugar),""!==t.base&&e.getMonomerSet(l).has(t.base)&&this._rnaBuilder.setField("base",t.base),""!==t.linker&&e.getMonomerSet(o).has(t.linker)&&this._rnaBuilder.setField("linker",t.linker)}_resolveFavoriteMonomers(t){let e=[];for(let i of this._favorites){let r=this._findMonomer(t,i);null!==r&&e.push(r)}return e}_findMonomer(t,e){for(let i of t.getPolymerTypes()){let r=t.getMonomer(i,e);if(null!==r)return r}return null}_buildPolymerPane(t,e,i,r){let s=e,l=this._monomersForPolymer(s,i);if(0===l.length)return;if(s===d.RNA){this._rnaBuilder=new kt(t,this._editor,{documentImpl:this._doc,paletteHooks:this._buildPaletteFilterHooks(),favoriteHooks:this._opts.allowFavorites?{isFavoriteTriplet:(t,e,i)=>this.isFavoriteTriplet(t,e,i),toggleFavoriteTriplet:(t,e,i)=>this.setFavoriteTriplet(t,e,i,!this.isFavoriteTriplet(t,e,i))}:null}),this._restoreRnaSelection();let e=this._buildRnaDefaultChips(i);null!==e&&t.appendChild(e);let r=this._groupRna(l);for(let[e,i]of r)0!==i.length&&t.appendChild(this._renderGroup(e,i));return}if(s===d.PEPTIDE&&this._opts.groupByNaturalAnalog){let e=this._groupByAnalog(l);for(let[i,r]of e){let e=""===i?"Other":i;t.appendChild(this._renderGroup(e,r))}return}let o=ot(this._doc,"div",{class:"hw-palette__group-tiles"}),n=this._editor.getNextAddSymbol(),a=this._sortByColor(l);for(let t of a){let e=this._biotype(t,s);o.appendChild(this._renderTile(t,e,n))}t.appendChild(o)}_renderGroup(t,e){let i=ot(this._doc,"div",{class:"hw-palette__group","data-natural-analog":t}),r=ot(this._doc,"div",{class:"hw-palette__group-header","data-testid":`palette-group-${t}`},[t]),s=ot(this._doc,"div",{class:"hw-palette__group-tiles"}),l=this._editor.getNextAddSymbol(),o=this._sortByColor(e);for(let t of o){let e=this._biotype(t,t.polymerType);s.appendChild(this._renderTile(t,e,l))}return i.appendChild(r),i.appendChild(s),i}_sortByColor(t){let e=this._theme(),i=t.map((t,i)=>{let r=function(t){let e=_(t);if(null===e)return{h:0,s:0,l:0};let[i,r,s]=m(e[0],e[1],e[2]);return{h:i,s:r,l:s}}(F(t,this._biotype(t,t.polymerType),e.colorTheme).background),s=0===r.s?1:0;return{m:t,idx:i,h:r.h,s:r.s,l:r.l,isGrey:s}});return i.sort((t,e)=>t.isGrey!==e.isGrey?t.isGrey-e.isGrey:t.h!==e.h?t.h-e.h:t.s!==e.s?t.s-e.s:t.l!==e.l?t.l-e.l:t.idx-e.idx),i.map(t=>t.m)}_monomersForPolymer(t,e){let i=e.getMonomerSymbolsByType(t),r=[];for(let s of i){let i=e.getMonomer(t,s);null!==i&&r.push(i)}return r.sort((t,e)=>t.symbol.localeCompare(e.symbol)),r}_groupByAnalog(t){let e=new Map;for(let i of t){let t=i.naturalAnalog??"",r=e.get(t);void 0===r&&(r=[],e.set(t,r)),r.push(i)}let i=[],r=Array.from(e.keys()).sort((t,e)=>""===t&&""!==e?1:""===e&&""!==t?-1:t.localeCompare(e));for(let t of r)i.push([t,e.get(t)]);return new Map(i)}_groupRna(t){let e=[],i=[],r=[],n=[];for(let a of t){let t=$(a);t===s?e.push(a):t===l?i.push(a):t===o?r.push(a):n.push(a)}let a=new Map;return a.set("Backbones",e),a.set("Bases",i),a.set("Linkers",r),n.length>0&&a.set("Other",n),a}_renderTile(t,e,i){let r=this._favorites.has(t.symbol),s=null!==i&&i.symbol===t.symbol&&i.biotype===e,{root:l,star:o}=function(t,e){let i=F(e.monomer,e.biotype,e.theme.colorTheme),r=v(i.background),s=i.text,l=function(t,e){let i=w(t),r=w(e);return(Math.max(i,r)+.05)/(Math.min(i,r)+.05)}(s,r)<5,o=e.monomer.symbol,n=function(t){return t<=3?14:t<=6?11:t<=9?9:8}(o.length),a=`font-size:${n}px;${o.length>=10?"line-height:1.1;letter-spacing:-0.02em;":""}white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:80px;display:inline-block;`,h=ot(t,"span",{class:"hw-palette__star"},[e.favorite?"★":"☆"]),d=ot(t,"span",{class:"hw-palette__label",style:a},[o]),u=["hw-palette__tile"];e.primed&&u.push("hw-palette__tile--primed"),e.favorite&&u.push("hw-palette__tile--favorite"),l&&u.push("hw-palette__tile--low-contrast");let c=void 0!==e.monomer.name?`${o} — ${e.monomer.name}`:o,p=`background:${r};color:${s};width:100%;min-width:48px;padding:4px 6px;height:40px;box-sizing:border-box;overflow:hidden;text-overflow:ellipsis;`;return{root:ot(t,"div",{class:u.join(" "),draggable:"true",role:"button","aria-pressed":e.primed?"true":"false","aria-label":c,"data-symbol":o,"data-biotype":e.biotype,"data-bg":r,"data-raw-bg":i.background,"data-testid":`palette-tile-${o}`,title:c,style:p},[h,d]),star:h}}(this._doc,{monomer:t,biotype:e,theme:this._theme(),favorite:r,primed:s});return this._wireTile(l,o,t,e),l}_rdkit(){let t=this._editor.getService().options?.rdkitModule;return t??null}_paletteRdkitSvg(e){let i=e.smiles;if(void 0===i||""===i)return null;let r=this._rdkit();if(null===r)return null;let s=`${e.polymerType}:${e.symbol}`;if(this._paletteRdkitCache.has(s))return this._paletteRdkitCache.get(s)??null;let l=nt(r,i,220,140);if(this._paletteRdkitCache.size>=t._PALETTE_RDKIT_CACHE_LIMIT){let t=this._paletteRdkitCache.keys().next().value;void 0!==t&&this._paletteRdkitCache.delete(t)}return this._paletteRdkitCache.set(s,l),l}_wireTile(t,e,i,r){t.addEventListener("mouseenter",t=>{let e=t,r=at(this._doc,"palette-tooltip","hw-palette-tooltip");ht(this._doc,r,{symbol:i.symbol,name:i.name??"",rdkitSvg:this._paletteRdkitSvg(i),rdkitTestid:"palette-tooltip-rdkit-svg"}),dt(r,"number"==typeof e.clientX?e.clientX:0,"number"==typeof e.clientY?e.clientY:0)}),t.addEventListener("mouseleave",()=>{ut(this._doc.body.querySelector('[data-testid="palette-tooltip"]'))}),t.addEventListener("click",t=>{let e=t.target;if(this._opts.allowFavorites&&void 0!==e&&!0===e?.classList?.contains("hw-palette__star"))return this.setFavorite(i.symbol,!this._favorites.has(i.symbol)),void t.stopPropagation();if(null!==this._activeBiotypeFilter&&this._activeBiotypeFilter===r){let e=this._pickResolver;return this._teardownPickMode(),e?.(i.symbol),this._scrollActivePaneToTop(),void t.stopPropagation()}let s=this._editor.getSelection();if(s.atoms.size>0){let e=this._editor.getMol(),l=[];for(let t of s.atoms){let i=e.atoms.find(e=>e.id===t);void 0!==i&&l.push(i)}return l.length>0&&l.every(t=>t.biotype===r)?(this._editor.replaceMonomers(l,i.symbol),void t.stopPropagation()):(this._editor.fire("editor:status",{message:`Cannot bulk-replace ${l.length} selected atom(s) with ${i.symbol}: selection contains incompatible biotypes for ${r}.`,severity:"warn",durationMs:3e3}),void t.stopPropagation())}let l=this._editor.getNextAddSymbol();if(null!==l&&l.symbol===i.symbol&&l.biotype===r)return this._editor.setNextAddSymbol(null),void this._updatePrimedClasses();this._editor.setNextAddSymbol(i.symbol,r),this._updatePrimedClasses()}),t.addEventListener("dragstart",t=>{let e=t.dataTransfer;if(null!=e)try{e.setData("application/x-hwe-monomer",JSON.stringify({symbol:i.symbol,biotype:r})),e.effectAllowed="copy"}catch{}ut(this._doc.body.querySelector('[data-testid="palette-tooltip"]')),this._editor.startPaletteDrag(i.symbol,r)})}_biotype(t,e){let i=$(t);if(null!==i)return i;switch(e){case d.PEPTIDE:return r;case d.RNA:return s;case d.CHEM:return n;case d.BLOB:return a;default:return n}}_theme(){let t=this._editor;return"function"==typeof t._currentTheme?t._currentTheme():this._editor.getService().theme}_applyFilter(){let t=this._filter,e=this._activeBiotypeFilter,i=this.element.querySelector(`.hw-palette__pane[data-tab="${this._activeTab}"]`),r=(i??this.element).querySelectorAll(".hw-palette__tile");for(let i=0;i<r.length;i++){let s=r[i],l=(s.getAttribute("data-symbol")??"").toLowerCase(),o=(s.getAttribute("title")??"").toLowerCase(),n=s.getAttribute("data-biotype")??"",a=(""===t||l.indexOf(t)>=0||o.indexOf(t)>=0)&&(null===e||n===e);s.style.display=a?"":"none"}let s=(i??this.element).querySelectorAll(".hw-triplet-chip");for(let i=0;i<s.length;i++){let r=s[i],l=[r.getAttribute("data-triplet")??"",r.getAttribute("data-sugar")??"",r.getAttribute("data-base")??"",r.getAttribute("data-linker")??""].join(" ").toLowerCase(),o=(""===t||l.indexOf(t)>=0)&&null===e;r.style.display=o?"":"none"}let l=(i??this.element).querySelectorAll(".hw-palette__group");for(let t=0;t<l.length;t++){let e=l[t],i=e.querySelectorAll(".hw-palette__tile, .hw-triplet-chip"),r=!1;for(let t=0;t<i.length;t++)if("none"!==i[t].style.display){r=!0;break}r?(e.removeAttribute("hidden"),e.removeAttribute("data-section-empty")):(e.setAttribute("hidden",""),e.setAttribute("data-section-empty","true"))}}_updatePrimedClasses(){let t=this._editor.getNextAddSymbol(),e=this.element.querySelectorAll(".hw-palette__tile");for(let i=0;i<e.length;i++){let r=e[i],s=r.getAttribute("data-symbol")??"",l=r.getAttribute("data-biotype")??"",o=null!==t&&t.symbol===s&&t.biotype===l,n=(r.getAttribute("class")??"").split(/\s+/).filter(t=>"hw-palette__tile--primed"!==t).join(" ");r.setAttribute("class",o?`${n} hw-palette__tile--primed`:n),r.setAttribute("aria-pressed",o?"true":"false")}}_applyActiveTabClasses(){let t=this.element.querySelectorAll(".hw-palette__tab");for(let e=0;e<t.length;e++){let i=t[e],r=i.getAttribute("data-tab")??"";i.setAttribute("aria-selected",r===this._activeTab?"true":"false")}let e=this.element.querySelectorAll(".hw-palette__pane");for(let t=0;t<e.length;t++){let i=e[t];(i.getAttribute("data-tab")??"")===this._activeTab?i.removeAttribute("hidden"):i.setAttribute("hidden","")}}_localStorage(){if(!this._opts.allowFavorites)return null;let t=this._doc.defaultView;if(null==t)return null;try{return t.localStorage??null}catch{return null}}_resolveInitialTab(t){if(void 0!==t&&It.includes(t))return t;let e=this._localStorage();if(null!==e)try{let t=e.getItem(xt);if(null!==t&&It.includes(t))return t}catch{}return Nt}_persistActiveTab(){let t=this._localStorage();if(null!==t)try{t.setItem(xt,this._activeTab)}catch{}}_loadFavorites(){let t=this._localStorage();if(null!==t){try{let e=t.getItem(Bt);if(null!==e&&""!==e){let t=JSON.parse(e),i=this._extractSymbols(t);for(let t of i)this._favorites.add(t);for(let e of this._extractTriplets(t))this._favoriteTriplets.push(e);return}}catch{}try{let e=t.getItem("hwe.palette.favorites");if(null===e||""===e)return;let i=JSON.parse(e);if(Array.isArray(i)){for(let t of i){if("string"!=typeof t)continue;let e=t.indexOf("|"),i=e>=0?t.slice(e+1):t;""!==i&&this._favorites.add(i)}this._saveFavorites()}}catch{}}}_extractSymbols(t){if(Array.isArray(t)){let e=[];for(let i of t)"string"==typeof i&&e.push(i);return e}if(null!==t&&"object"==typeof t){let e=t;if(Array.isArray(e.symbols)){let t=[];for(let i of e.symbols)"string"==typeof i&&t.push(i);return t}}return[]}_extractTriplets(t){if(null===t||"object"!=typeof t)return[];let e=t;if(!Array.isArray(e.triplets))return[];let i=[];for(let t of e.triplets){if(null===t||"object"!=typeof t)continue;let e=t;"string"==typeof e.sugar&&"string"==typeof e.base&&"string"==typeof e.linker&&i.push({sugar:e.sugar,base:e.base,linker:e.linker})}return i}_saveFavorites(){let t=this._localStorage();if(null!==t)try{let e={symbols:Array.from(this._favorites)};this._favoriteTriplets.length>0&&(e.triplets=this._favoriteTriplets.map(t=>({...t}))),t.setItem(Bt,JSON.stringify(e))}catch{}}};Pt._DEFAULT_TRIPLET_BASES=["A","C","G","U","T"],Pt._PALETTE_RDKIT_CACHE_LIMIT=256;new Set([d.PEPTIDE,d.RNA,d.CHEM,d.BLOB]),new Set(["Backbone","Branch","Terminal","Undefined"]);var Ft,$t;!function(t){t[t.default=0]="default",t[t.continuous=1]="continuous"}(Ft||(Ft={})),function(t){t.Sequence="sequence",t.Helm="notation",t.Properties="properties",t.StructureView="structureview"}($t||($t={}));const Rt={V2K_RGP_SHIFT:8,V2K_RGP_LINE:"M RGP",V2K_A_LINE:"A ",V3K_COUNTS_SHIFT:14,V3K_IDX_SHIFT:7,V3K_HEADER_FIRST_LINE:"\nDatagrok macromolecule handler\n\n",V3K_HEADER_SECOND_LINE:" 0 0 0 0 0 0 999 V3000\n",V3K_BEGIN_CTAB_BLOCK:"M V30 BEGIN CTAB\n",V3K_END_CTAB_BLOCK:"M V30 END CTAB\n",V3K_BEGIN_COUNTS_LINE:"M V30 COUNTS ",V3K_COUNTS_LINE_ENDING:" 0 0 0\n",V3K_BEGIN_ATOM_BLOCK:"M V30 BEGIN ATOM\n",V3K_END_ATOM_BLOCK:"M V30 END ATOM\n",V3K_BEGIN_BOND_BLOCK:"M V30 BEGIN BOND\n",V3K_END_BOND_BLOCK:"M V30 END BOND\n",V3K_BOND_CONFIG:" CFG=",V3K_BEGIN_DATA_LINE:"M V30 ",V3K_END:"M END",PRECISION_FACTOR:1e4,DEOXYRIBOSE:{polymerType:d.RNA,symbol:"d"},RIBOSE:{polymerType:d.RNA,symbol:"r"},PHOSPHATE:{polymerType:d.RNA,symbol:"p"},OXYGEN:"O",HYDROGEN:"H"};function Ot(t,e){return t[e.polymerType]?.[e.symbol]}var Dt;!function(t){t[t.SUGAR=0]="SUGAR",t[t.BASE=1]="BASE",t[t.PHOSPHATE=2]="PHOSPHATE",t[t.TERMINAL_5P=3]="TERMINAL_5P",t[t.TERMINAL_3P=4]="TERMINAL_3P"}(Dt||(Dt={}));class Vt extends Map{constructor(t){super(t)}}class Kt{constructor(t,e){this.molfile=t,this.monomers=e}static createEmpty(){return new Kt("",new Vt(null))}}const Ht=d;var Gt,zt,Ut;new RegExp("[rd]\\((\\w)\\)p?","g");class qt{constructor(t,e,i){this.name=t,this.alphabet=e,this.cutoff=i}}!function(t){t.FASTA="fasta",t.SEPARATOR="separator",t.HELM="helm",t.CUSTOM="custom",t.BILN="biln"}(Gt||(Gt={})),function(t){t.DNA="DNA",t.RNA="RNA",t.PT="PT",t.UN="UN"}(zt||(zt={})),function(t){t.aligned="aligned",t.alphabet="alphabet",t.alphabetSize=".alphabetSize",t.alphabetIsMultichar=".alphabetIsMultichar",t.separator="separator",t.isHelmCompatible=".isHelmCompatible",t.positionNames=".positionNames",t.positionLabels=".positionLabels",t.regions=".regions",t.positionShift=".positionShift",t.selectedPosition=".selectedPosition",t.polymerTypeColumnName=".polymerTypeColumnName",t.annotations=".annotations",t.numberingScheme=".numberingScheme",t.annotationColumnName=".annotationColumnName"}(Ut||(Ut={}));const jt=new class{constructor(){this.fasta={peptide:new Set(["G","L","Y","S","E","Q","D","N","F","A","K","R","H","C","V","P","W","I","M","T"]),dna:new Set(["A","C","G","T"]),rna:new Set(["A","C","G","U"])}}};function Yt(t){let e;switch(t){case l:case s:case o:case h:case"nucleotide":e=d.RNA;break;case r:e=d.PEPTIDE;break;case n:e=d.CHEM;break;case a:e=d.BLOB;break;default:e=d.PEPTIDE,console.warn(`Unexpected HelmType '${t}'`)}return e}function Wt(t,e,i,r,s,l){if(0===t.length)return Kt.createEmpty();if(l&&l.length>1){const o=new Array(l.length);for(let n=0;n<l.length;++n){const a=l[n],h=n+1<l.length?l[n+1]:t.length,d=t.slice(a,h),u=s?s.slice(a,h):void 0;o[n]=Wt(d,e,i,r,u)}return function(t,e){const i=[],r=[],s=[],l=new Vt;let o=0,n=0,a=Number.POSITIVE_INFINITY,h=!1;for(let d=0;d<t.length;++d){const u=t[d];if(!u||!u.molfile)continue;const c=ne(u.molfile);if(0===c.atoms.length)continue;let p=Number.POSITIVE_INFINITY,_=Number.NEGATIVE_INFINITY;for(const t of c.atoms)t.y<p&&(p=t.y),t.y>_&&(_=t.y);const b=h?ie(a-re-_):0;for(let t=0;t<c.atoms.length;++t){const e=c.atoms[t],r=o+t+1,s=ie(e.y+b);i.push(Rt.V3K_BEGIN_DATA_LINE+r+" "+e.type+" "+e.xStr+" "+s+" "+e.tail+"\n")}for(let t=0;t<c.bonds.length;++t){const e=c.bonds[t],i=n+t+1,s=e.tail?" "+e.tail:"";r.push(Rt.V3K_BEGIN_DATA_LINE+i+" "+e.btype+" "+(e.a1+o)+" "+(e.a2+o)+s+"\n")}for(const t of c.steabs)s.push(t+o);const f=e[d]??0;for(const[t,e]of u.monomers)l.set(f+t,{biotype:e.biotype,symbol:e.symbol,atoms:e.atoms.map(t=>t+o),bonds:e.bonds.map(t=>t+n)});const m=ie(p+b);a=h?Math.min(a,m):m,h=!0,o+=c.atoms.length,n+=c.bonds.length}if(!h)return Kt.createEmpty();let d="";return d+=Rt.V3K_HEADER_FIRST_LINE,d+=Rt.V3K_HEADER_SECOND_LINE,d+=Rt.V3K_BEGIN_CTAB_BLOCK,d+=Rt.V3K_BEGIN_COUNTS_LINE+o+" "+n+Rt.V3K_COUNTS_LINE_ENDING,d+=Rt.V3K_BEGIN_ATOM_BLOCK,d+=i.join(""),d+=Rt.V3K_END_ATOM_BLOCK,d+=Rt.V3K_BEGIN_BOND_BLOCK,d+=r.join(""),d+=Rt.V3K_END_BOND_BLOCK,s.length>0&&(d+=Xt(s)),d+=Rt.V3K_END_CTAB_BLOCK,d+=Rt.V3K_END,{molfile:d,monomers:l}}(o,l)}const o=r===Ht.RNA&&!!s&&s.length===t.length,{atomCount:n,bondCount:a,needsCapping:h}=function(t,e,i,r,s,l){let o=0,n=0,a=0,h=!0,d=null,u=null;for(let i=0;i<t.length;++i){const r=t[i];if(""!==r.symbol){if("*"==r.symbol)throw new Error("Gap canonical symbol is '', not '*");d=Ot(e,{symbol:r.symbol,polymerType:Yt(r.biotype)}),o+=d.atoms.x.length,n+=d.bonds.bondTypes.length,a++,s&&i%3==2&&(u=d)}}if(r===Ht.PEPTIDE)o+=1,n+=a,a>0&&((d?.meta?.rNodes?.length??0)<2||d?.terminalR2Atom?.toLowerCase()===Rt.HYDROGEN.toLowerCase())&&(h=!1,o-=1,n-=1);else if(s)n+=a,l&&l.length>0&&l[l.length-1]===Dt.TERMINAL_3P?(h=!1,n-=1):o+=1;else{const r=i===zt.DNA?Ot(e,Rt.DEOXYRIBOSE):Ot(e,Rt.RIBOSE),s=Ot(e,Rt.PHOSPHATE);o+=(t.length-1)*s.atoms.x.length,o+=t.length*r.atoms.x.length,o+=1,n+=(t.length-1)*s.bonds.bondTypes.length,n+=t.length*r.bonds.bondTypes.length,n-=1,n+=3*t.length}return{atomCount:o,bondCount:n,needsCapping:h}}(t,e,i,r,o,s),d=new Array(n),u=new Array(a);let c,p=null,_=null;r===Ht.PEPTIDE?c=Zt:(c=Qt,o||(p=i===zt.DNA?Ot(e,Rt.DEOXYRIBOSE):Ot(e,Rt.RIBOSE),_=Ot(e,Rt.PHOSPHATE)));const b={i:0,nodeShift:0,bondShift:0,backbonePositionShift:new Array(2).fill(0),branchPositionShift:new Array(2).fill(0),backboneAttachNode:0,branchAttachNode:0,flipFactor:1},f={sugar:p,phosphate:_,seqLength:o?Math.ceil(t.length/3):t.length,atomCount:n,bondCount:a},m=new Vt,g=[];let y,v=0;if(o)!function(t,e,i,r,s,l,o,n,a,h){for(let o=0;o<t.length;++o){const d=t[o];if(""===d.symbol)continue;const u=e[o],c=Ot(i,{symbol:d.symbol,polymerType:Yt(d.biotype)}),p=l.nodeShift,_=l.bondShift;l.i=o,u===Dt.BASE?te(c,r,s,l):Jt(c,r,s,l),c.stereoAtoms?.forEach(t=>a.push(t+v)),h(c.atoms.x.length);const b=[];for(let t=p;t<l.nodeShift;++t)b.push(t);const f=[];for(let t=_;t<l.bondShift;++t)f.push(t);n.set(o,{biotype:d.biotype,symbol:d.symbol,atoms:b,bonds:f})}}(t,s,e,d,u,b,0,m,g,t=>{v+=t});else for(b.i=0;b.i<f.seqLength;++b.i){const i=t[b.i];if(""===i.symbol)continue;const r=Ot(e,{symbol:i.symbol,polymerType:Yt(i.biotype)});y=r.terminalR2Atom;const s=b.nodeShift,l=b.bondShift;c(r,d,u,b,f),r.stereoAtoms?.forEach(t=>g.push(t+v)),v+=r.atoms.x.length;const o=b.nodeShift-s,n=new Array(o);for(let t=0;t<o;++t)n[t]=s+t;const a=b.bondShift-l,h=new Array(a);for(let t=0;t<a;++t)h[t]=l+t;m.set(b.i,{biotype:i.biotype,symbol:i.symbol,atoms:n,bonds:h})}h&&function(t,e,i,r,s=Rt.OXYGEN){const l=i.nodeShift+1;t[r.atomCount]=Rt.V3K_BEGIN_DATA_LINE+l+" "+(s??Rt.OXYGEN)+" "+ie(i.backbonePositionShift[0])+" "+i.flipFactor*ie(i.backbonePositionShift[1])+" 0.000000 0\n";const o=i.backboneAttachNode,n=l;e[r.bondCount]=Rt.V3K_BEGIN_DATA_LINE+i.bondShift+" 1 "+o+" "+n+"\n"}(d,u,b,f,y??Rt.OXYGEN);const w=Rt.V3K_BEGIN_COUNTS_LINE+n+" "+a+Rt.V3K_COUNTS_LINE_ENDING;let A="";return A+=Rt.V3K_HEADER_FIRST_LINE,A+=Rt.V3K_HEADER_SECOND_LINE,A+=Rt.V3K_BEGIN_CTAB_BLOCK,A+=w,A+=Rt.V3K_BEGIN_ATOM_BLOCK,A+=d.join(""),A+=Rt.V3K_END_ATOM_BLOCK,A+=Rt.V3K_BEGIN_BOND_BLOCK,A+=u.join(""),A+=Rt.V3K_END_BOND_BLOCK,g.length>0&&(A+=Xt(g)),A+=Rt.V3K_END_CTAB_BLOCK,A+=Rt.V3K_END,{molfile:A,monomers:m}}function Xt(t){const e=[];let i=`M V30 MDLV30/STEABS ATOMS=(${t.length}`;for(let r=0;r<t.length;r++){const s=`${i} ${t[r]}`;s.length>76?(e.push(`${i} -\n`),i=`M V30 ${t[r]}`):i=s,r===t.length-1&&e.push(`${i})\n`)}return`M V30 BEGIN COLLECTION\n${e.join("")}M V30 END COLLECTION\n`}function Zt(t,e,i,r){r.flipFactor=(-1)**(r.i%2),Jt(t,e,i,r)}function Jt(t,e,i,r){!function(t,e,i){for(let r=0;r<t.atoms.atomTypes.length;++r){const s=i.nodeShift+r+1;e[i.nodeShift+r]=Rt.V3K_BEGIN_DATA_LINE+s+" "+t.atoms.atomTypes[r]+" "+ie(i.backbonePositionShift[0]+t.atoms.x[r])+" "+ie(i.backbonePositionShift[1]+i.flipFactor*t.atoms.y[r])+" "+t.atoms.kwargs[r]}}(t,e,r),ee(t,i,r),function(t,e,i){if(0!==i.backboneAttachNode){const r=i.bondShift,s=i.backboneAttachNode,l=t.meta.terminalNodes[0]+i.nodeShift;e[i.bondShift-1]=Rt.V3K_BEGIN_DATA_LINE+r+" 1 "+s+" "+l+"\n"}}(t,i,r),null!==t.meta.branchShift&&t.meta.terminalNodes.length>2&&function(t,e){e.branchAttachNode=e.nodeShift+t.meta.terminalNodes[2];for(let i=0;i<2;++i)e.branchPositionShift[i]=e.backbonePositionShift[i]+t.meta.branchShift[i]}(t,r),function(t,e){e.backboneAttachNode=e.nodeShift+t.meta.terminalNodes[1],e.bondShift+=t.bonds.atomPairs.length+1,e.nodeShift+=t.atoms.atomTypes.length,e.backbonePositionShift[0]+=t.meta.backboneShift?.[0]??0,e.backbonePositionShift[1]+=e.flipFactor*(t.meta.backboneShift?.[1]??0)}(t,r)}function Qt(t,e,i,r,s){if(0===r.i)Jt(s.sugar,e,i,r);else for(const t of[s.phosphate,s.sugar])Jt(t,e,i,r);te(t,e,i,r)}function te(t,e,i,r){!function(t,e,i){for(let r=0;r<t.atoms.atomTypes.length;++r){const s=i.nodeShift+r+1;e[i.nodeShift+r]=Rt.V3K_BEGIN_DATA_LINE+s+" "+t.atoms.atomTypes[r]+" "+ie(i.branchPositionShift[0]+t.atoms.x[r])+" "+ie(i.branchPositionShift[1]+i.flipFactor*t.atoms.y[r])+" "+t.atoms.kwargs[r]}}(t,e,r),ee(t,i,r),function(t,e,i){const r=i.bondShift,s=i.branchAttachNode,l=t.meta.terminalNodes[0]+i.nodeShift;e[r-1]=Rt.V3K_BEGIN_DATA_LINE+r+" 1 "+s+" "+l+"\n"}(t,i,r);const s=r.bondShift,l=r.branchAttachNode,o=t.meta.terminalNodes[0]+r.nodeShift;i[s-1]=Rt.V3K_BEGIN_DATA_LINE+s+" 1 "+l+" "+o+"\n",r.bondShift+=t.bonds.atomPairs.length+1,r.nodeShift+=t.atoms.atomTypes.length}function ee(t,e,i){for(let r=0;r<t.bonds.atomPairs.length;++r){const s=i.bondShift+r+1,l=t.bonds.atomPairs[r][0]+i.nodeShift,o=t.bonds.atomPairs[r][1]+i.nodeShift;let n="";if(t.bonds.bondConfiguration.has(r)){let e=t.bonds.bondConfiguration.get(r);i.flipFactor<0&&(e=1===e?3:1),n=" CFG="+e}const a=t.bonds.kwargs.has(r)?" "+t.bonds.kwargs.get(r):"";e[i.bondShift+r]=Rt.V3K_BEGIN_DATA_LINE+s+" "+t.bonds.bondTypes[r]+" "+l+" "+o+n+a+"\n"}}function ie(t){return Math.round(Rt.PRECISION_FACTOR*t)/Rt.PRECISION_FACTOR}new qt(zt.PT,jt.fasta.peptide,.5),new qt(zt.DNA,jt.fasta.dna,.55),new qt(zt.RNA,jt.fasta.rna,.55),Gt.FASTA,Gt.SEPARATOR,Gt.HELM,Gt.BILN;const re=3,se="M V30 MDLV30/STEABS ATOMS=(";function le(t,e){const i=[];let r=t;for(let t=0;t<e;++t){const t=r.indexOf(" ");-1!==t?(i.push(r.substring(0,t)),r=r.substring(t+1)):(i.push(r),r="")}return i.push(r),i}function oe(t,e,i){const r=t.indexOf(e);if(-1===r)return[];const s=t.indexOf("\n",r)+1,l=t.indexOf(i,s);return t.substring(s,-1===l?t.length:l).split("\n").filter(t=>t.startsWith(Rt.V3K_BEGIN_DATA_LINE)).map(t=>t.substring(Rt.V3K_BEGIN_DATA_LINE.length))}function ne(t){const e=[];for(const i of oe(t,Rt.V3K_BEGIN_ATOM_BLOCK,Rt.V3K_END_ATOM_BLOCK)){const t=le(i,4);e.push({type:t[1],xStr:t[2],y:parseFloat(t[3]),tail:t[4]})}const i=[];for(const e of oe(t,Rt.V3K_BEGIN_BOND_BLOCK,Rt.V3K_END_BOND_BLOCK)){const t=le(e,4);i.push({btype:t[1],a1:parseInt(t[2]),a2:parseInt(t[3]),tail:t[4]})}const r=[];let s=t.indexOf(se);for(;-1!==s;){s+=se.length;const e=t.indexOf(")",s);r.push(...t.substring(s,e).split(" ").slice(1).map(t=>parseInt(t)).filter(t=>!Number.isNaN(t))),s=t.indexOf(se,e)}return{atoms:e,bonds:i,steabs:r}}onmessage=t=>{const{seqList:e,rolesList:i,chainStartsList:r,monomersDict:s,alphabet:l,polymerType:o,start:n,end:a}=t.data,h=new Array(a-n),d=new Array(0);for(let t=n;t<a;++t)try{const a=e[t],d=i?i[t]:void 0,u=r?r[t]:void 0;h[t-n]=Wt(a,s,l,o,d,u)}catch(e){const i=`Cannot get molfile of row #${t}: ${e instanceof Error?e.message:e.toString()}.`;d.push(i)}postMessage({molfiles:h,warnings:d})},helm={}})();
2
+ //# sourceMappingURL=489.js.map