@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.
- package/CHANGELOG.md +13 -0
- package/CLAUDE.md +78 -92
- package/dist/489.js +2 -0
- package/dist/489.js.map +1 -0
- package/dist/package-test.js +1 -1
- package/dist/package-test.js.map +1 -1
- package/dist/package.js +1 -1
- package/dist/package.js.map +1 -1
- package/files/samples/helm-showcase.csv +7 -9
- package/package.json +12 -9
- package/src/helm-helper.ts +3 -0
- package/src/package-api.ts +1 -0
- package/src/package-test.ts +0 -4
- package/src/package.g.ts +2 -0
- package/src/package.ts +4 -1
- package/src/tests/helm-input-tests.ts +3 -3
- package/src/utils/helm-grid-cell-renderer.ts +3 -0
- package/test-console-output-1.log +344 -0
- package/test-playwright-report.json +118 -0
- package/test-record-1.mp4 +0 -0
- package/test-report-playwright.csv +1 -0
- package/tsconfig.json +2 -1
- package/dist/137.js +0 -2
- package/dist/137.js.map +0 -1
- package/dist/323.js +0 -2
- package/dist/323.js.map +0 -1
- package/dist/455.js +0 -2
- package/dist/455.js.map +0 -1
- package/dist/657.js +0 -2
- package/dist/657.js.map +0 -1
- package/dist/782.js +0 -2
- package/dist/782.js.map +0 -1
- package/dist/884.js +0 -2
- package/dist/884.js.map +0 -1
- package/dist/94.js +0 -2
- package/dist/94.js.map +0 -1
- package/dist/libraries_bio_src_monomer-works_seq-to-molfile-worker_ts.js +0 -16420
- package/dist/libraries_bio_src_monomer-works_seq-to-molfile-worker_ts.js.map +0 -1
- package/dist/package-dojo.js +0 -2
- package/dist/package-dojo.js.map +0 -1
- package/dist/vendors-HELM_node_modules_lru-cache_dist_esm_index_js.js +0 -1560
- 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
|
|
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
|
|
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
|
|
18
|
-
- `openEditor` (`Edit Helm...`) — `@func` (action): context-menu editor for Macromolecule columns
|
|
19
|
-
- `propertiesWidget` (`Properties`) — `@panel`:
|
|
20
|
-
- `getMolfiles` — `@func`: converts a Macromolecule column to molfile strings
|
|
21
|
-
- `helmInput` — `@func` (role: `valueEditor`): creates `HelmInput` widget for Macromolecule/HELM
|
|
22
|
-
- `getHelmHelper` — `@func`: returns `IHelmHelper` singleton
|
|
23
|
-
- `measureCellRenderer` — `@func`: performance
|
|
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
|
|
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
|
-
- `
|
|
39
|
-
- `
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
67
|
-
|
|
68
|
-
-
|
|
69
|
-
|
|
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`:
|
|
76
|
-
| `
|
|
77
|
-
| `
|
|
78
|
-
| `
|
|
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
|
|
87
|
-
| `properties-widget.ts` | `getPropertiesWidget()`: property panel
|
|
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_
|
|
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
|
-
|
|
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` |
|
|
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()`
|
|
137
|
-
3. `
|
|
138
|
-
4.
|
|
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/
|
|
145
|
-
- `@datagrok-libraries/
|
|
146
|
-
- `@datagrok-libraries/chem-meta` —
|
|
147
|
-
- `@datagrok-libraries/utils` —
|
|
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,
|
|
159
|
-
| HELM helper (parse, convert, getMolfiles) | `src/helm-helper.ts` |
|
|
160
|
-
|
|
|
161
|
-
| Grid cell renderer (
|
|
162
|
-
|
|
|
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
|
-
|
|
|
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,"&").replace(/"/g,""").replace(/'/g,"'").replace(/</g,"<").replace(/>/g,">"):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
|