@platforma-sdk/ui-vue 1.45.34 → 1.45.36

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (150) hide show
  1. package/.turbo/turbo-build.log +216 -222
  2. package/.turbo/turbo-type-check.log +1 -1
  3. package/CHANGELOG.md +16 -0
  4. package/dist/AgGridVue/useAgGridOptions.js +2 -3
  5. package/dist/AgGridVue/useAgGridOptions.js.map +1 -1
  6. package/dist/components/{PlMultiSequenceAlignment/Legend.vue.d.ts → PlAdvancedFilter/OperandButton.vue.d.ts} +4 -2
  7. package/dist/components/{PlMultiSequenceAlignment/Toolbar.vue.js → PlAdvancedFilter/OperandButton.vue.js} +3 -3
  8. package/dist/components/PlAdvancedFilter/OperandButton.vue.js.map +1 -0
  9. package/dist/components/PlAdvancedFilter/OperandButton.vue2.js +25 -0
  10. package/dist/components/PlAdvancedFilter/OperandButton.vue2.js.map +1 -0
  11. package/dist/components/PlAdvancedFilter/OperandButton.vue3.js +13 -0
  12. package/dist/components/PlAdvancedFilter/OperandButton.vue3.js.map +1 -0
  13. package/dist/components/PlAdvancedFilter/PlAdvancedFilter.vue.d.ts +39 -0
  14. package/dist/components/PlAdvancedFilter/PlAdvancedFilter.vue.js +10 -0
  15. package/dist/components/PlAdvancedFilter/PlAdvancedFilter.vue.js.map +1 -0
  16. package/dist/components/PlAdvancedFilter/PlAdvancedFilter.vue2.js +199 -0
  17. package/dist/components/PlAdvancedFilter/PlAdvancedFilter.vue2.js.map +1 -0
  18. package/dist/components/PlAdvancedFilter/PlAdvancedFilter.vue3.js +17 -0
  19. package/dist/components/PlAdvancedFilter/PlAdvancedFilter.vue3.js.map +1 -0
  20. package/dist/components/PlAdvancedFilter/SingleFilter.vue.d.ts +37 -0
  21. package/dist/components/{PlMultiSequenceAlignment/PlMultiSequenceAlignment.vue.js → PlAdvancedFilter/SingleFilter.vue.js} +3 -3
  22. package/dist/components/PlAdvancedFilter/SingleFilter.vue.js.map +1 -0
  23. package/dist/components/PlAdvancedFilter/SingleFilter.vue2.js +306 -0
  24. package/dist/components/PlAdvancedFilter/SingleFilter.vue2.js.map +1 -0
  25. package/dist/components/PlAdvancedFilter/SingleFilter.vue3.js +35 -0
  26. package/dist/components/PlAdvancedFilter/SingleFilter.vue3.js.map +1 -0
  27. package/dist/components/PlAdvancedFilter/constants.d.ts +4 -0
  28. package/dist/components/PlAdvancedFilter/constants.js +41 -0
  29. package/dist/components/PlAdvancedFilter/constants.js.map +1 -0
  30. package/dist/components/PlAdvancedFilter/index.d.ts +1 -0
  31. package/dist/components/PlAdvancedFilter/types.d.ts +57 -0
  32. package/dist/components/PlAdvancedFilter/types.js +8 -0
  33. package/dist/components/PlAdvancedFilter/types.js.map +1 -0
  34. package/dist/components/PlAdvancedFilter/utils.js +150 -0
  35. package/dist/components/PlAdvancedFilter/utils.js.map +1 -0
  36. package/dist/components/PlAgDataTable/PlAgRowCount.vue.js +7 -8
  37. package/dist/components/PlAgDataTable/PlAgRowCount.vue.js.map +1 -1
  38. package/dist/components/PlAgRowNumCheckbox/PlAgRowNumCheckbox.vue.js +9 -10
  39. package/dist/components/PlAgRowNumCheckbox/PlAgRowNumCheckbox.vue.js.map +1 -1
  40. package/dist/components/PlAgRowNumHeader.vue.js +2 -3
  41. package/dist/components/PlAgRowNumHeader.vue.js.map +1 -1
  42. package/dist/index.js +32 -32
  43. package/dist/lib.d.ts +1 -1
  44. package/package.json +6 -7
  45. package/src/components/PlAdvancedFilter/OperandButton.vue +53 -0
  46. package/src/components/PlAdvancedFilter/PlAdvancedFilter.vue +209 -0
  47. package/src/components/PlAdvancedFilter/SingleFilter.vue +425 -0
  48. package/src/components/PlAdvancedFilter/constants.ts +42 -0
  49. package/src/components/PlAdvancedFilter/index.ts +1 -0
  50. package/src/components/PlAdvancedFilter/types.ts +77 -0
  51. package/src/components/PlAdvancedFilter/utils.ts +215 -0
  52. package/src/lib.ts +2 -2
  53. package/dist/assets/multi-sequence-alignment.worker-Cm0gZp19.js +0 -6
  54. package/dist/assets/multi-sequence-alignment.worker-Cm0gZp19.js.map +0 -1
  55. package/dist/assets/phylogenetic-tree.worker-4CrExYEo.js +0 -5
  56. package/dist/assets/phylogenetic-tree.worker-4CrExYEo.js.map +0 -1
  57. package/dist/components/PlMultiSequenceAlignment/Consensus.vue.d.ts +0 -9
  58. package/dist/components/PlMultiSequenceAlignment/Consensus.vue.js +0 -10
  59. package/dist/components/PlMultiSequenceAlignment/Consensus.vue.js.map +0 -1
  60. package/dist/components/PlMultiSequenceAlignment/Consensus.vue2.js +0 -122
  61. package/dist/components/PlMultiSequenceAlignment/Consensus.vue2.js.map +0 -1
  62. package/dist/components/PlMultiSequenceAlignment/Consensus.vue3.js +0 -9
  63. package/dist/components/PlMultiSequenceAlignment/Consensus.vue3.js.map +0 -1
  64. package/dist/components/PlMultiSequenceAlignment/Legend.vue.js +0 -10
  65. package/dist/components/PlMultiSequenceAlignment/Legend.vue.js.map +0 -1
  66. package/dist/components/PlMultiSequenceAlignment/Legend.vue2.js +0 -28
  67. package/dist/components/PlMultiSequenceAlignment/Legend.vue2.js.map +0 -1
  68. package/dist/components/PlMultiSequenceAlignment/Legend.vue3.js +0 -13
  69. package/dist/components/PlMultiSequenceAlignment/Legend.vue3.js.map +0 -1
  70. package/dist/components/PlMultiSequenceAlignment/MultiSequenceAlignmentView.vue.d.ts +0 -25
  71. package/dist/components/PlMultiSequenceAlignment/MultiSequenceAlignmentView.vue.js +0 -10
  72. package/dist/components/PlMultiSequenceAlignment/MultiSequenceAlignmentView.vue.js.map +0 -1
  73. package/dist/components/PlMultiSequenceAlignment/MultiSequenceAlignmentView.vue2.js +0 -138
  74. package/dist/components/PlMultiSequenceAlignment/MultiSequenceAlignmentView.vue2.js.map +0 -1
  75. package/dist/components/PlMultiSequenceAlignment/MultiSequenceAlignmentView.vue3.js +0 -31
  76. package/dist/components/PlMultiSequenceAlignment/MultiSequenceAlignmentView.vue3.js.map +0 -1
  77. package/dist/components/PlMultiSequenceAlignment/PhylogeneticTree.vue.d.ts +0 -8
  78. package/dist/components/PlMultiSequenceAlignment/PhylogeneticTree.vue.js +0 -10
  79. package/dist/components/PlMultiSequenceAlignment/PhylogeneticTree.vue.js.map +0 -1
  80. package/dist/components/PlMultiSequenceAlignment/PhylogeneticTree.vue2.js +0 -77
  81. package/dist/components/PlMultiSequenceAlignment/PhylogeneticTree.vue2.js.map +0 -1
  82. package/dist/components/PlMultiSequenceAlignment/PhylogeneticTree.vue3.js +0 -9
  83. package/dist/components/PlMultiSequenceAlignment/PhylogeneticTree.vue3.js.map +0 -1
  84. package/dist/components/PlMultiSequenceAlignment/PlMultiSequenceAlignment.vue.d.ts +0 -71
  85. package/dist/components/PlMultiSequenceAlignment/PlMultiSequenceAlignment.vue.js.map +0 -1
  86. package/dist/components/PlMultiSequenceAlignment/PlMultiSequenceAlignment.vue2.js +0 -224
  87. package/dist/components/PlMultiSequenceAlignment/PlMultiSequenceAlignment.vue2.js.map +0 -1
  88. package/dist/components/PlMultiSequenceAlignment/PlMultiSequenceAlignment.vue3.js +0 -9
  89. package/dist/components/PlMultiSequenceAlignment/PlMultiSequenceAlignment.vue3.js.map +0 -1
  90. package/dist/components/PlMultiSequenceAlignment/SeqLogo.vue.d.ts +0 -8
  91. package/dist/components/PlMultiSequenceAlignment/SeqLogo.vue.js +0 -10
  92. package/dist/components/PlMultiSequenceAlignment/SeqLogo.vue.js.map +0 -1
  93. package/dist/components/PlMultiSequenceAlignment/SeqLogo.vue2.js +0 -127
  94. package/dist/components/PlMultiSequenceAlignment/SeqLogo.vue2.js.map +0 -1
  95. package/dist/components/PlMultiSequenceAlignment/SeqLogo.vue3.js +0 -9
  96. package/dist/components/PlMultiSequenceAlignment/SeqLogo.vue3.js.map +0 -1
  97. package/dist/components/PlMultiSequenceAlignment/Toolbar.vue.d.ts +0 -16
  98. package/dist/components/PlMultiSequenceAlignment/Toolbar.vue.js.map +0 -1
  99. package/dist/components/PlMultiSequenceAlignment/Toolbar.vue2.js +0 -228
  100. package/dist/components/PlMultiSequenceAlignment/Toolbar.vue2.js.map +0 -1
  101. package/dist/components/PlMultiSequenceAlignment/Toolbar.vue3.js +0 -19
  102. package/dist/components/PlMultiSequenceAlignment/Toolbar.vue3.js.map +0 -1
  103. package/dist/components/PlMultiSequenceAlignment/cell-size.d.ts +0 -4
  104. package/dist/components/PlMultiSequenceAlignment/cell-size.js +0 -8
  105. package/dist/components/PlMultiSequenceAlignment/cell-size.js.map +0 -1
  106. package/dist/components/PlMultiSequenceAlignment/chemical-properties.d.ts +0 -44
  107. package/dist/components/PlMultiSequenceAlignment/chemical-properties.js +0 -132
  108. package/dist/components/PlMultiSequenceAlignment/chemical-properties.js.map +0 -1
  109. package/dist/components/PlMultiSequenceAlignment/data.d.ts +0 -61
  110. package/dist/components/PlMultiSequenceAlignment/data.js +0 -370
  111. package/dist/components/PlMultiSequenceAlignment/data.js.map +0 -1
  112. package/dist/components/PlMultiSequenceAlignment/index.d.ts +0 -1
  113. package/dist/components/PlMultiSequenceAlignment/markup.d.ts +0 -16
  114. package/dist/components/PlMultiSequenceAlignment/markup.js +0 -84
  115. package/dist/components/PlMultiSequenceAlignment/markup.js.map +0 -1
  116. package/dist/components/PlMultiSequenceAlignment/migrations.d.ts +0 -3
  117. package/dist/components/PlMultiSequenceAlignment/migrations.js +0 -24
  118. package/dist/components/PlMultiSequenceAlignment/migrations.js.map +0 -1
  119. package/dist/components/PlMultiSequenceAlignment/multi-sequence-alignment.worker.d.ts +0 -6
  120. package/dist/components/PlMultiSequenceAlignment/phylogenetic-tree.worker.d.ts +0 -7
  121. package/dist/components/PlMultiSequenceAlignment/residue-counts.d.ts +0 -2
  122. package/dist/components/PlMultiSequenceAlignment/residue-counts.js +0 -13
  123. package/dist/components/PlMultiSequenceAlignment/residue-counts.js.map +0 -1
  124. package/dist/components/PlMultiSequenceAlignment/settings.d.ts +0 -2
  125. package/dist/components/PlMultiSequenceAlignment/settings.js +0 -9
  126. package/dist/components/PlMultiSequenceAlignment/settings.js.map +0 -1
  127. package/dist/components/PlMultiSequenceAlignment/types.d.ts +0 -5
  128. package/dist/components/PlMultiSequenceAlignment/useMiPlots.d.ts +0 -4
  129. package/dist/components/PlMultiSequenceAlignment/useMiPlots.js +0 -19
  130. package/dist/components/PlMultiSequenceAlignment/useMiPlots.js.map +0 -1
  131. package/src/components/PlMultiSequenceAlignment/Consensus.vue +0 -165
  132. package/src/components/PlMultiSequenceAlignment/Legend.vue +0 -44
  133. package/src/components/PlMultiSequenceAlignment/MultiSequenceAlignmentView.vue +0 -299
  134. package/src/components/PlMultiSequenceAlignment/PhylogeneticTree.vue +0 -110
  135. package/src/components/PlMultiSequenceAlignment/PlMultiSequenceAlignment.vue +0 -314
  136. package/src/components/PlMultiSequenceAlignment/README.md +0 -216
  137. package/src/components/PlMultiSequenceAlignment/SeqLogo.vue +0 -166
  138. package/src/components/PlMultiSequenceAlignment/Toolbar.vue +0 -228
  139. package/src/components/PlMultiSequenceAlignment/cell-size.ts +0 -4
  140. package/src/components/PlMultiSequenceAlignment/chemical-properties.ts +0 -199
  141. package/src/components/PlMultiSequenceAlignment/data.ts +0 -661
  142. package/src/components/PlMultiSequenceAlignment/index.ts +0 -1
  143. package/src/components/PlMultiSequenceAlignment/markup.ts +0 -141
  144. package/src/components/PlMultiSequenceAlignment/migrations.ts +0 -46
  145. package/src/components/PlMultiSequenceAlignment/multi-sequence-alignment.worker.ts +0 -54
  146. package/src/components/PlMultiSequenceAlignment/phylogenetic-tree.worker.ts +0 -89
  147. package/src/components/PlMultiSequenceAlignment/residue-counts.ts +0 -124
  148. package/src/components/PlMultiSequenceAlignment/settings.ts +0 -7
  149. package/src/components/PlMultiSequenceAlignment/types.ts +0 -3
  150. package/src/components/PlMultiSequenceAlignment/useMiPlots.ts +0 -23
@@ -1,228 +0,0 @@
1
- <script setup lang="ts">
2
- import { isJsonEqual } from '@milaboratories/helpers';
3
- import {
4
- type ListOptionNormalized,
5
- PlBtnGhost,
6
- PlBtnPrimary,
7
- PlBtnSecondary,
8
- PlCheckbox,
9
- PlDropdown,
10
- PlDropdownMulti,
11
- PlNumberField,
12
- PlSlideModal,
13
- } from '@milaboratories/uikit';
14
- import type {
15
- PlMultiSequenceAlignmentColorSchemeOption as ColorSchemeOption,
16
- PlMultiSequenceAlignmentSettings as Settings,
17
- PlMultiSequenceAlignmentWidget,
18
- PObjectId,
19
- PTableColumnId,
20
- } from '@platforma-sdk/model';
21
- import { computed, ref, useCssModule, watchEffect } from 'vue';
22
- import { defaultSettings } from './settings';
23
-
24
- const props = defineProps<{
25
- settings: Settings;
26
- sequenceColumnOptions: ListOptionNormalized<PObjectId>[] | undefined;
27
- labelColumnOptions: ListOptionNormalized<PTableColumnId>[] | undefined;
28
- colorSchemeOptions: ListOptionNormalized<ColorSchemeOption>[];
29
- }>();
30
-
31
- const emit = defineEmits<{
32
- updateSettings: [Partial<Settings>];
33
- export: [];
34
- }>();
35
-
36
- const classes = useCssModule();
37
-
38
- const settingsOpen = ref(false);
39
-
40
- function updateSetting<K extends keyof Settings>(
41
- key: K,
42
- value: Settings[K] | undefined,
43
- ) {
44
- emit('updateSettings', { [key]: value });
45
- }
46
-
47
- function toggleWidget(
48
- widget: PlMultiSequenceAlignmentWidget,
49
- checked: boolean,
50
- ) {
51
- updateSetting(
52
- 'widgets',
53
- checked
54
- ? [...props.settings.widgets, widget]
55
- : props.settings.widgets.filter((w) => widget !== w),
56
- );
57
- }
58
-
59
- const alignmentParams = ref({ ...props.settings.alignmentParams });
60
- watchEffect(() => {
61
- alignmentParams.value = { ...props.settings.alignmentParams };
62
- });
63
-
64
- const alignmentParamsChangesPending = computed(() =>
65
- !isJsonEqual(props.settings.alignmentParams, alignmentParams.value),
66
- );
67
-
68
- const canResetAlignmentParams = computed(() =>
69
- !isJsonEqual(props.settings.alignmentParams, defaultSettings.alignmentParams),
70
- );
71
- </script>
72
-
73
- <template>
74
- <div :class="classes.container">
75
- <div :class="classes.line">
76
- <div :class="classes.section">
77
- <PlDropdownMulti
78
- label="Sequence Columns"
79
- :model-value="props.settings.sequenceColumnIds ?? []"
80
- :options="props.sequenceColumnOptions"
81
- clearable
82
- @update:model-value="event => updateSetting('sequenceColumnIds', event)"
83
- />
84
- <PlDropdownMulti
85
- :model-value="props.settings.labelColumnIds ?? []"
86
- label="Label Columns"
87
- :options="props.labelColumnOptions"
88
- clearable
89
- @update:model-value="event => updateSetting('labelColumnIds', event)"
90
- />
91
- <PlDropdown
92
- :model-value="props.settings.colorScheme"
93
- label="Color Scheme"
94
- :options="props.colorSchemeOptions"
95
- @update:model-value="event => updateSetting('colorScheme', event)"
96
- />
97
- </div>
98
- <div :class="classes.buttons">
99
- <PlBtnGhost icon="settings" @click.stop="settingsOpen = true">
100
- Settings
101
- </PlBtnGhost>
102
- <PlBtnGhost icon="export" @click.stop="emit('export')">
103
- Export
104
- </PlBtnGhost>
105
- </div>
106
- </div>
107
- <div :class="classes.line">
108
- <div :class="classes.section">
109
- <PlCheckbox
110
- :model-value="props.settings.widgets.includes('seqLogo')"
111
- @update:model-value="event => toggleWidget('seqLogo', event)"
112
- >
113
- Seq logo
114
- </PlCheckbox>
115
- <PlCheckbox
116
- :model-value="props.settings.widgets.includes('consensus')"
117
- @update:model-value="event => toggleWidget('consensus', event)"
118
- >
119
- Consensus
120
- </PlCheckbox>
121
- <PlCheckbox :model-value="false" disabled>Navigator</PlCheckbox>
122
- <PlCheckbox
123
- :model-value="props.settings.widgets.includes('tree')"
124
- @update:model-value="event => toggleWidget('tree', event)"
125
- >
126
- Tree
127
- </PlCheckbox>
128
- <PlCheckbox
129
- :model-value="props.settings.widgets.includes('legend')"
130
- :disabled="props.settings.colorScheme.type === 'no-color'"
131
- @update:model-value="event => toggleWidget('legend', event)"
132
- >
133
- Legend
134
- </PlCheckbox>
135
- </div>
136
- </div>
137
- </div>
138
- <PlSlideModal v-model="settingsOpen">
139
- <template #title>Settings</template>
140
- <PlNumberField
141
- v-model="alignmentParams.gpo"
142
- label="Gap open penalty"
143
- :step="0.1"
144
- @keyup.enter="updateSetting('alignmentParams', alignmentParams)"
145
- >
146
- <template #tooltip>
147
- Penalty score assigned to the introduction of a gap in the alignment
148
- </template>
149
- </PlNumberField>
150
- <PlNumberField
151
- v-model="alignmentParams.gpe"
152
- label="Gap extension penalty"
153
- :step="0.1"
154
- @keyup.enter="updateSetting('alignmentParams', alignmentParams)"
155
- >
156
- <template #tooltip>
157
- Penalty score assigned to each additional residue added to an existing
158
- gap
159
- </template>
160
- </PlNumberField>
161
- <PlNumberField
162
- v-model="alignmentParams.tgpe"
163
- label="Terminal gap extension penalty"
164
- :step="0.1"
165
- @keyup.enter="updateSetting('alignmentParams', alignmentParams)"
166
- >
167
- <template #tooltip>
168
- Penalty score assigned to extending gaps at the ends of sequences
169
- </template>
170
- </PlNumberField>
171
- <div
172
- v-if="alignmentParamsChangesPending"
173
- :class="classes.pendingChanges"
174
- >
175
- <PlBtnPrimary @click="updateSetting('alignmentParams', alignmentParams)">
176
- Apply
177
- </PlBtnPrimary>
178
- <PlBtnGhost @click="alignmentParams = props.settings.alignmentParams">
179
- Cancel
180
- </PlBtnGhost>
181
- </div>
182
- <PlBtnSecondary
183
- v-if="canResetAlignmentParams"
184
- :class="classes.resetButton"
185
- icon="reverse"
186
- @click="updateSetting('alignmentParams', undefined)"
187
- >
188
- Reset to Default
189
- </PlBtnSecondary>
190
- </PlSlideModal>
191
- </template>
192
-
193
- <style module>
194
- .container {
195
- display: flex;
196
- flex-direction: column;
197
- gap: 24px;
198
- }
199
-
200
- .line {
201
- display: flex;
202
- justify-content: space-between;
203
- }
204
-
205
- .section {
206
- display: flex;
207
- flex-wrap: wrap;
208
- gap: 24px;
209
- }
210
-
211
- .buttons {
212
- display: flex;
213
- }
214
-
215
- .pendingChanges {
216
- display: flex;
217
- button {
218
- min-width: 160px;
219
- }
220
- }
221
-
222
- .resetButton {
223
- margin-block-start: auto;
224
- span {
225
- text-transform: none;
226
- }
227
- }
228
- </style>
@@ -1,4 +0,0 @@
1
- export const cellSize = {
2
- inline: 20,
3
- block: 24,
4
- };
@@ -1,199 +0,0 @@
1
- import type { HighlightLegend, ResidueCounts } from './types';
2
-
3
- export function highlightByChemicalProperties(
4
- { sequences, residueCounts }: {
5
- sequences: string[];
6
- residueCounts: ResidueCounts;
7
- },
8
- ): { blob: Blob; legend: HighlightLegend } {
9
- const lines: {
10
- category: ChemicalCategory;
11
- column: number;
12
- start: number;
13
- length: number;
14
- }[] = [];
15
- const chemicalProperties = getAlignmentChemicalProperties({
16
- residueCounts,
17
- rowCount: sequences.length,
18
- });
19
- const width = sequences.at(0)?.length ?? 0;
20
- const height = sequences.length;
21
- for (let column = 0; column < width; column += 1) {
22
- for (let row = 0; row < height; row += 1) {
23
- const residue = sequences[row][column];
24
- const category = chemicalProperties
25
- .at(column)
26
- ?.find(({ residues }) => residues.includes(residue))
27
- ?.category;
28
- if (!category) continue;
29
- const lastLine = lines.at(-1);
30
- if (
31
- lastLine
32
- && lastLine.category === category
33
- && lastLine.column === column
34
- && lastLine.start + lastLine.length === row
35
- ) {
36
- lastLine.length += 1;
37
- } else {
38
- lines.push({ category, column, start: row, length: 1 });
39
- }
40
- }
41
- }
42
- const linesByCategory = Map.groupBy(lines, ({ category }) => category);
43
- const blob = new Blob(
44
- (function*() {
45
- const viewBox = `0 0 ${width * 2} ${height}`;
46
- yield `<svg xmlns="http://www.w3.org/2000/svg" viewBox="${viewBox}" stroke-width="2" preserveAspectRatio="none">`;
47
- for (const [category, lines] of linesByCategory) {
48
- const color = chemicalPropertiesColorScheme[category]?.color;
49
- if (!color) continue;
50
- yield `<path stroke="${color}" d="`;
51
- let x = 0, y = 0;
52
- for (const { column, start, length } of lines) {
53
- yield `m${column * 2 + 1 - x},${start - y}v${length}`;
54
- x = column * 2 + 1;
55
- y = start + length;
56
- }
57
- yield '"/>';
58
- }
59
- yield '</svg>';
60
- })().toArray(),
61
- { type: 'image/svg+xml' },
62
- );
63
- const legend = Object.fromEntries(
64
- Object.entries(chemicalPropertiesColorScheme)
65
- .filter(([color]) => linesByCategory.has(color as ChemicalCategory)),
66
- );
67
- return { blob, legend };
68
- }
69
-
70
- const getAlignmentChemicalProperties = (
71
- { residueCounts, rowCount }: {
72
- residueCounts: ResidueCounts;
73
- rowCount: number;
74
- },
75
- ): ColumnChemicalProperties[] =>
76
- residueCounts.map((column) => {
77
- const matchedRules = new Set<string>();
78
- return categoryCriterion.filter(({ residues, rules }) =>
79
- residues.split('').some((residue) => residue in column)
80
- && (!rules || rules.split('').map((ruleName) =>
81
- [ruleName, ruleDefinitions[ruleName as RuleName]] as const,
82
- ).some(([ruleName, { residues, threshold }]) => {
83
- if (matchedRules.has(ruleName)) return true;
84
- const groupCount = residues.split('')
85
- .reduce((acc, residue) => acc + (column[residue] ?? 0), 0);
86
- const matches = groupCount >= rowCount * threshold;
87
- if (matches) matchedRules.add(ruleName);
88
- return matches;
89
- })),
90
- );
91
- });
92
-
93
- type ColumnChemicalProperties = {
94
- residues: string;
95
- category: ChemicalCategory;
96
- }[];
97
-
98
- const chemicalPropertiesColorScheme = {
99
- hydrophobic: {
100
- label: 'Hydrophobic',
101
- color: '#99CCFF',
102
- },
103
- positiveCharge: {
104
- label: 'Positive Charged',
105
- color: '#FFA2A3',
106
- },
107
- negativeCharge: {
108
- label: 'Negative Charged',
109
- color: '#C1ADFF',
110
- },
111
- polar: {
112
- label: 'Polar',
113
- color: '#99E099',
114
- },
115
- cysteine: {
116
- label: 'Cysteines',
117
- color: '#FAAAFA',
118
- },
119
- glycine: {
120
- label: 'Glycines',
121
- color: '#F7BC5D',
122
- },
123
- proline: {
124
- label: 'Prolines',
125
- color: '#FFFF8F',
126
- },
127
- aromatic: {
128
- label: 'Aromatic',
129
- color: '#A2F5FA',
130
- },
131
- } satisfies HighlightLegend;
132
-
133
- export type ChemicalCategory = keyof typeof chemicalPropertiesColorScheme;
134
-
135
- /*
136
- * Below taken mostly from
137
- * https://www.rbvi.ucsf.edu/chimera/1.2065/docs/ContributedSoftware/multalignviewer/colprot.par}
138
- */
139
-
140
- const ruleDefinitions = {
141
- '%': { residues: 'WLVIMAFCYHP', threshold: 0.6 },
142
- '#': { residues: 'WLVIMAFCYHP', threshold: 0.8 },
143
- '-': { residues: 'ED', threshold: 0.5 },
144
- '+': { residues: 'KR', threshold: 0.6 },
145
- 'g': { residues: 'G', threshold: 0.5 },
146
- 'n': { residues: 'N', threshold: 0.5 },
147
- 'q': { residues: 'QE', threshold: 0.5 },
148
- 'p': { residues: 'P', threshold: 0.5 },
149
- 't': { residues: 'TS', threshold: 0.5 },
150
- 'A': { residues: 'A', threshold: 0.85 },
151
- 'C': { residues: 'C', threshold: 0.85 },
152
- 'D': { residues: 'D', threshold: 0.85 },
153
- 'E': { residues: 'E', threshold: 0.85 },
154
- 'F': { residues: 'F', threshold: 0.85 },
155
- 'G': { residues: 'G', threshold: 0.85 },
156
- 'H': { residues: 'H', threshold: 0.85 },
157
- 'I': { residues: 'I', threshold: 0.85 },
158
- 'K': { residues: 'K', threshold: 0.85 },
159
- 'L': { residues: 'L', threshold: 0.85 },
160
- 'M': { residues: 'M', threshold: 0.85 },
161
- 'N': { residues: 'N', threshold: 0.85 },
162
- 'P': { residues: 'P', threshold: 0.85 },
163
- 'Q': { residues: 'Q', threshold: 0.85 },
164
- 'R': { residues: 'R', threshold: 0.85 },
165
- 'S': { residues: 'S', threshold: 0.85 },
166
- 'T': { residues: 'T', threshold: 0.85 },
167
- 'V': { residues: 'V', threshold: 0.85 },
168
- 'W': { residues: 'W', threshold: 0.85 },
169
- 'Y': { residues: 'Y', threshold: 0.85 },
170
- };
171
-
172
- type RuleName = keyof typeof ruleDefinitions;
173
-
174
- const categoryCriterion: Criteria[] = [
175
- { residues: 'G', category: 'glycine', rules: '' },
176
- { residues: 'P', category: 'proline', rules: '' },
177
- { residues: 'T', category: 'polar', rules: 'tST%#' },
178
- { residues: 'S', category: 'polar', rules: 'tST#' },
179
- { residues: 'N', category: 'polar', rules: 'nND' },
180
- { residues: 'Q', category: 'polar', rules: 'qQE+KR' },
181
- // criteria below has to go before the other criteria for C,
182
- // otherwise it will never match
183
- { residues: 'C', category: 'cysteine', rules: 'C' },
184
- { residues: 'WLVIMF', category: 'hydrophobic', rules: '%#ACFHILMVWYPp' },
185
- // below there was an 's' rule too,
186
- // but no definition of such rule was provided
187
- { residues: 'A', category: 'hydrophobic', rules: '%#ACFHILMVWYPpTSG' },
188
- { residues: 'C', category: 'hydrophobic', rules: '%#AFHILMVWYSPp' },
189
- { residues: 'HY', category: 'aromatic', rules: '%#ACFHILMVWYPp' },
190
- { residues: 'E', category: 'negativeCharge', rules: '-DEqQ' },
191
- { residues: 'D', category: 'negativeCharge', rules: '-DEnN' },
192
- { residues: 'KR', category: 'positiveCharge', rules: '+KRQ' },
193
- ];
194
-
195
- type Criteria = {
196
- residues: string;
197
- category: ChemicalCategory;
198
- rules: string;
199
- };