@teselagen/ove 0.7.26 → 0.7.28

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 (304) hide show
  1. package/AASliver.js +187 -0
  2. package/AddLaddersDialog.js +82 -0
  3. package/AdditionalCutsiteInfoDialog.js +599 -0
  4. package/AlignmentView/Mismatches.d.ts +3 -3
  5. package/AlignmentVisibilityTool.js +105 -0
  6. package/AnnotationContainerHolder.js +20 -0
  7. package/AnnotationPositioner.js +27 -0
  8. package/AutoAnnotate.js +501 -0
  9. package/AutoAnnotateBpMatchingDialog.js +208 -0
  10. package/Axis.js +151 -0
  11. package/AxisNumbers.js +35 -0
  12. package/Browser.js +106 -0
  13. package/Caret.js +63 -0
  14. package/Chromatogram.js +293 -0
  15. package/CircularDnaSequence.js +73 -0
  16. package/CircularView/Labels/index.d.ts +1 -1
  17. package/CircularView/index.d.ts +0 -1
  18. package/CircularZoomMinimap.js +16 -0
  19. package/ColorPicker.js +30 -0
  20. package/CommandHotkeyHandler.js +44 -0
  21. package/CreateAnnotationsPage.d.ts +4 -4
  22. package/CreateAnnotationsPage.js +98 -0
  23. package/Cutsite.js +18 -0
  24. package/CutsiteProperties.js +176 -0
  25. package/CutsiteSelectionLayers.js +47 -0
  26. package/Cutsites.js +271 -0
  27. package/DeletionLayer.js +28 -0
  28. package/DigestTool/Ladder.d.ts +1 -1
  29. package/DropHandler.css +21 -0
  30. package/DropHandler.js +64 -0
  31. package/EditCaretPosition.js +234 -0
  32. package/EditTrackNameDialog.js +30 -0
  33. package/Feature.js +83 -0
  34. package/FeatureProperties.js +6 -0
  35. package/FillWindow.js +47 -0
  36. package/GenbankView.js +74 -0
  37. package/GeneralProperties.js +117 -0
  38. package/GenericAnnotationProperties.js +406 -0
  39. package/GlobalDialog.js +73 -0
  40. package/GlobalDialogUtils.js +110 -0
  41. package/GoToDialog.js +25 -0
  42. package/HorizontalPanelDragHandle.js +35 -0
  43. package/Keyboard.js +85 -0
  44. package/Labels.js +327 -0
  45. package/Ladder.css +20 -0
  46. package/Ladder.js +303 -0
  47. package/MeltingTemp.js +85 -0
  48. package/Menlo.ttf +0 -0
  49. package/Minimap.js +515 -0
  50. package/Mismatches.js +134 -0
  51. package/Monaco.ttf +0 -0
  52. package/MultipleSeqsDetectedOnImportDialog.js +74 -0
  53. package/Orf.js +109 -0
  54. package/OrfProperties.js +117 -0
  55. package/Orfs.js +35 -0
  56. package/PCRTool.js +179 -0
  57. package/PairwiseAlignmentView.js +68 -0
  58. package/Part.js +34 -0
  59. package/PartProperties.js +9 -0
  60. package/PassThrough.js +3 -0
  61. package/PerformantSelectionLayer.js +32 -0
  62. package/PinchHelper.js +24 -0
  63. package/PointedAnnotation.js +347 -0
  64. package/PositionAnnotationOnCircle.js +26 -0
  65. package/Primer.js +41 -0
  66. package/PrimerProperties.js +19 -0
  67. package/Reflex/index.d.ts +0 -1
  68. package/ReflexContainer.js +802 -0
  69. package/ReflexElement.js +160 -0
  70. package/ReflexEvents.js +77 -0
  71. package/ReflexSplitter.js +205 -0
  72. package/RenameSequenceDialog.js +7 -0
  73. package/RotateCircularViewSlider.js +93 -0
  74. package/RowView/index.d.ts +0 -1
  75. package/SelectDialog.js +150 -0
  76. package/SequenceName.js +15 -0
  77. package/SimpleCircularOrLinearView.js +381 -0
  78. package/SimpleOligoPreview.js +39 -0
  79. package/SingleEnzymeCutsiteInfo.js +139 -0
  80. package/ToolBar/ToolbarItem.d.ts +1 -3
  81. package/ToolbarItem.js +192 -0
  82. package/Translation.js +198 -0
  83. package/TranslationProperties.js +149 -0
  84. package/UncontrolledSliderWithPlusMinusBtns.css +5 -0
  85. package/UncontrolledSliderWithPlusMinusBtns.js +134 -0
  86. package/VeTopRightContainer.js +12 -0
  87. package/ZoomCircularViewSlider.js +62 -0
  88. package/ZoomLinearView.js +47 -0
  89. package/addAlignment.js +6 -0
  90. package/addMetaToActionCreators.js +12 -0
  91. package/addWrappedAddons.js +20 -0
  92. package/alignmentTool.js +503 -0
  93. package/alignments.js +379 -0
  94. package/annotationLabelVisibility.js +2 -0
  95. package/annotationSearchSelector.js +24 -0
  96. package/annotationTypes.js +35 -0
  97. package/annotationVisibility.js +196 -0
  98. package/annotationsToSupport.js +104 -0
  99. package/arrayToObjWithIds.js +17 -0
  100. package/arrayUtils.js +19 -0
  101. package/array_move.js +10 -0
  102. package/calculateTickMarkPositionsForGivenRange.js +47 -0
  103. package/caretPosition.js +27 -0
  104. package/cdsFeaturesSelector.js +9 -0
  105. package/charWidth.js +22 -0
  106. package/circular.js +19 -0
  107. package/circularSelector.js +4 -0
  108. package/clickAndDragUtils.js +576 -0
  109. package/coerceInitialValue.js +7 -0
  110. package/combineReducersDontIgnoreKeys.js +12 -0
  111. package/commandUtils.js +20 -0
  112. package/constants.js +2 -0
  113. package/copyOptions.js +34 -0
  114. package/createFragmentLines.js +120 -0
  115. package/createMergedDefaultStateReducer.js +30 -0
  116. package/createMetaAction.js +12 -0
  117. package/createSequenceInputPopup.js +290 -0
  118. package/createSequenceInputPopupStyle.css +87 -0
  119. package/createSimpleDialog.js +89 -0
  120. package/createYourOwnEnzyme.js +39 -0
  121. package/cutsiteLabelColorSelector.js +6 -0
  122. package/cutsiteTool.js +88 -0
  123. package/cutsitesByRangeSelector.js +5 -0
  124. package/cutsitesSelector.js +61 -0
  125. package/darkmode.css +98 -0
  126. package/defaultConfig.js +150 -0
  127. package/deletionLayers.js +36 -0
  128. package/description.js +21 -0
  129. package/digestTool.js +34 -0
  130. package/dnaToColor.js +17 -0
  131. package/downloadTool.js +39 -0
  132. package/draggableClassnames.js +5 -0
  133. package/drawAnnotations.js +440 -0
  134. package/drawDirectedPiePiece.js +142 -0
  135. package/editTool.js +49 -0
  136. package/editorSelector.js +2 -0
  137. package/editorUtils.js +205 -0
  138. package/estimateRowHeight.js +184 -0
  139. package/featureLengthsToHide.js +27 -0
  140. package/featureTool.js +34 -0
  141. package/features.js +19 -0
  142. package/featuresSelector.js +8 -0
  143. package/filteredCutsitesSelector.js +136 -0
  144. package/filteredFeaturesSelector.js +32 -0
  145. package/filteredPartsSelector.js +57 -0
  146. package/filteredPrimersSelector.js +27 -0
  147. package/filteredRestrictionEnzymesSelector.js +1 -0
  148. package/find.png +0 -0
  149. package/findTool.js +79 -0
  150. package/findToolConstants.js +1 -0
  151. package/frameTranslations.js +52 -0
  152. package/fullscreen.png +0 -0
  153. package/getAdditionalEnzymesSelector.js +46 -0
  154. package/getAngleForPositionMidpoint.js +3 -0
  155. package/getAnnotationClassnames.js +12 -0
  156. package/getAnnotationNameAndStartStopString.js +61 -0
  157. package/getBpsPerRow.js +19 -0
  158. package/getCutsiteLabelHeights.js +56 -0
  159. package/getGapMap.js +12 -0
  160. package/getGaps.js +27 -0
  161. package/getInternalLabel.js +40 -0
  162. package/getOveHotkeyDefs.js +12 -0
  163. package/getPairwiseOverviewLinearViewOptions.js +38 -0
  164. package/getRangeAnglesSpecial.js +12 -0
  165. package/getStructuredBases.js +97 -0
  166. package/getTrackFromEvent.js +25 -0
  167. package/getVisibleStartEnd.js +7 -0
  168. package/getXStartAndWidthFromNonCircularRange.js +12 -0
  169. package/getXStartAndWidthOfRangeWrtRow.js +27 -0
  170. package/getXStartAndWidthOfRowAnnotation.js +19 -0
  171. package/getYOffset.js +15 -0
  172. package/hoveredAnnotation.js +24 -0
  173. package/{html2canvas.esm--JN4fLQL.js → html2canvas.esm-DiGWN1gP.js} +187 -229
  174. package/{html2canvas.esm-B7d7VJmQ.cjs → html2canvas.esm-J1esNpMJ.cjs} +187 -229
  175. package/importTool.js +27 -0
  176. package/index.cjs.js +48165 -47142
  177. package/index.es.js +47699 -46676
  178. package/index.js +71 -0
  179. package/inlineFindTool.js +38 -0
  180. package/isElementInViewport.js +29 -0
  181. package/isEnzymeFilterAndSelector.js +1 -0
  182. package/isTargetWithinEl.js +6 -0
  183. package/labelLineIntensity.js +25 -0
  184. package/labelSize.js +23 -0
  185. package/ladderDefaults.js +25 -0
  186. package/lastSavedId.js +20 -0
  187. package/lineageLines.js +11 -0
  188. package/linear.png +0 -0
  189. package/makeStore.js +34 -0
  190. package/massageTickSpacing.js +19 -0
  191. package/materiallyAvailable.js +19 -0
  192. package/middleware.js +112 -0
  193. package/minimumOrfSize.js +24 -0
  194. package/minimumOrfSizeSelector.js +2 -0
  195. package/modalActions.js +3 -0
  196. package/moveCaret.js +58 -0
  197. package/name.js +19 -0
  198. package/normalizeAngle.js +3 -0
  199. package/normalizeAngleRange.js +9 -0
  200. package/oligoTool.js +30 -0
  201. package/onlyUpdateForKeysDeep.js +31 -0
  202. package/orfFrameToColorMap.js +10 -0
  203. package/orfTool.js +136 -0
  204. package/orfsSelector.js +15 -0
  205. package/ove.css +12107 -0
  206. package/package.json +8 -7
  207. package/panelsShown.js +294 -0
  208. package/partLengthsToHide.js +23 -0
  209. package/partOverhangs.js +6 -0
  210. package/partTagSearch.js +69 -0
  211. package/partTool.js +45 -0
  212. package/parts.js +19 -0
  213. package/partsSelector.js +8 -0
  214. package/pie.png +0 -0
  215. package/polarToSpecialCartesian.js +7 -0
  216. package/positionCutsites.js +6 -0
  217. package/prepareRowData.js +64 -0
  218. package/primerBases.js +221 -0
  219. package/primerLengthsToHide.js +27 -0
  220. package/primers.js +19 -0
  221. package/primersSelector.js +8 -0
  222. package/print.png +0 -0
  223. package/printTool.js +31 -0
  224. package/propertiesTool.js +40 -0
  225. package/proteinUtils.js +3 -0
  226. package/pureNoFunc.js +18 -0
  227. package/readOnly.js +25 -0
  228. package/redoTool.js +30 -0
  229. package/reflex-styles.css +128 -0
  230. package/reflex-styles.css.map +9 -0
  231. package/relaxLabelAngles.js +157 -0
  232. package/relaxLabels_DEPRECATED.js +105 -0
  233. package/replacementLayers.js +36 -0
  234. package/restrictionEnzymes.js +52 -0
  235. package/restrictionEnzymesSelector.js +34 -0
  236. package/rowviewContants.js +3 -0
  237. package/ruler.css +89 -0
  238. package/save.png +0 -0
  239. package/saveTool.js +44 -0
  240. package/searchLayersSelector.js +71 -0
  241. package/selectedAnnotations.js +89 -0
  242. package/selectedAnnotationsSelector.js +1 -0
  243. package/selectedCutsitesSelector.js +21 -0
  244. package/selectedPartTags.js +21 -0
  245. package/selectionLayer.js +25 -0
  246. package/selectors/annotationSearchSelector.d.ts +1 -1
  247. package/sequence.js +12 -0
  248. package/sequenceDataHistory.js +43 -0
  249. package/sequenceDataSelector.js +2 -0
  250. package/sequenceLengthSelector.js +5 -0
  251. package/sequenceSelector.js +4 -0
  252. package/sharedActionCreators.js +0 -0
  253. package/shouldFlipText.js +4 -0
  254. package/shouldRerender.js +27 -0
  255. package/showFileDialog.js +25 -0
  256. package/showGCContent.js +23 -0
  257. package/show_cut_sites.png +0 -0
  258. package/show_features.png +0 -0
  259. package/show_orfs.png +0 -0
  260. package/show_primers.png +0 -0
  261. package/simpleDialog.css +13 -0
  262. package/specialCutsiteFilterOptions.js +22 -0
  263. package/src/Editor/DropHandler.js +2 -1
  264. package/src/Editor/index.js +0 -2
  265. package/src/RowItem/StackedAnnotations/getStructuredBases.js +20 -6
  266. package/src/ToolBar/cutsiteTool.js +1 -1
  267. package/src/helperComponents/PropertiesDialog/TranslationProperties.js +2 -1
  268. package/style.css +3 -12100
  269. package/tagsToBoldSelector.js +2 -0
  270. package/toggle_views.svg +1 -0
  271. package/toolBar.js +23 -0
  272. package/translationSearchMatchesSelector.js +14 -0
  273. package/translations.js +20 -0
  274. package/translationsRawSelector.js +8 -0
  275. package/translationsSelector.js +137 -0
  276. package/typeField.js +24 -0
  277. package/undoTool.js +30 -0
  278. package/updateEditor.d.ts +1 -3
  279. package/updateEditor.js +200 -0
  280. package/updateLabelsForInViewFeatures.js +55 -0
  281. package/updateLabelsForInViewFeaturesCircView.js +41 -0
  282. package/updateTrackHelper.js +58 -0
  283. package/uppercaseSequenceMapFont.js +25 -0
  284. package/upsertDeleteActionGenerator.js +31 -0
  285. package/useAAColorType.js +8 -0
  286. package/useAdditionalOrfStartCodons.js +24 -0
  287. package/useAnnotationLimits.js +42 -0
  288. package/useChromatogramPrefs.js +31 -0
  289. package/useFormValue.js +7 -0
  290. package/useLadders.js +6 -0
  291. package/useMeltingTemp.js +7 -0
  292. package/useTmType.js +10 -0
  293. package/userDefinedHandlersAndOpts.js +61 -0
  294. package/utils/getAnnotationNameAndStartStopString.d.ts +1 -5
  295. package/utils/selectionLayer.d.ts +2 -2
  296. package/utils.js +37 -0
  297. package/versionHistory.js +26 -0
  298. package/versionHistoryTool.js +21 -0
  299. package/viewSubmenu.js +479 -0
  300. package/visibilityTool.js +39 -0
  301. package/withEditorInteractions/getBpsPerRow.d.ts +1 -3
  302. package/withHover.js +113 -0
  303. package/withRestrictionEnzymes.js +15 -0
  304. package/index.umd.js +0 -188322
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@teselagen/ove",
3
- "version": "0.7.26",
3
+ "version": "0.7.28",
4
4
  "main": "./src/index.js",
5
5
  "type": "module",
6
6
  "exports": {
@@ -11,11 +11,11 @@
11
11
  "./*": "./*"
12
12
  },
13
13
  "dependencies": {
14
- "@teselagen/sequence-utils": "file:../sequence-utils",
15
- "@teselagen/range-utils": "file:../range-utils",
16
- "@teselagen/ui": "file:../ui",
17
- "@teselagen/file-utils": "file:../file-utils",
18
- "@teselagen/bio-parsers": "file:../bio-parsers",
14
+ "@teselagen/sequence-utils": "0.3.31",
15
+ "@teselagen/range-utils": "0.3.13",
16
+ "@teselagen/ui": "0.8.6",
17
+ "@teselagen/file-utils": "0.3.20",
18
+ "@teselagen/bio-parsers": "0.4.28",
19
19
  "@blueprintjs/core": "3.54.0",
20
20
  "@hello-pangea/dnd": "16.2.0",
21
21
  "@risingstack/react-easy-state": "^6.3.0",
@@ -65,7 +65,8 @@
65
65
  "vite": "^5.2.11",
66
66
  "@vitejs/plugin-react": "^4.3.0",
67
67
  "vite-plugin-libcss": "^1.1.1",
68
- "vite-tsconfig-paths": "^4.3.2"
68
+ "vite-tsconfig-paths": "^4.3.2",
69
+ "@playwright/test": "^1.44.1"
69
70
  },
70
71
  "license": "MIT"
71
72
  }
package/panelsShown.js ADDED
@@ -0,0 +1,294 @@
1
+ import { map, flatMap } from "lodash-es";
2
+ import { createReducer } from "redux-act";
3
+ import createAction from "./utils/createMetaAction";
4
+ import { removeItem } from "../utils/arrayUtils";
5
+ import immer from "immer";
6
+
7
+ //manages which tab panels are shown in the editor
8
+
9
+ // ------------------------------------
10
+ // Actions
11
+ // ------------------------------------
12
+ export const panelsShownUpdate = createAction("PANELS_SHOWN_UPDATE");
13
+ export const addPanelIfItDoesntAlreadyExist = createAction(
14
+ "addPanelIfItDoesntAlreadyExist"
15
+ );
16
+ export const togglePanelFullScreen = createAction("togglePanelFullScreen");
17
+ export const collapsePanel = createAction("collapsePanel");
18
+ export const closePanel = createAction("closePanel");
19
+ export const _collapseSplitScreen = createAction("_collapseSplitScreen");
20
+ export const setPanelAsActive = createAction("setPanelAsActive");
21
+ export const flipActiveTabFromLinearOrCircularIfNecessary = createAction(
22
+ "flipActiveTabFromLinearOrCircularIfNecessary"
23
+ );
24
+ export const expandTabToSplitScreen = createAction("expandTabToSplitScreen");
25
+ export const propertiesViewOpen = (unused, meta) => {
26
+ return setPanelAsActive("properties", meta);
27
+ };
28
+ export const createNewDigest = (unused, meta) => {
29
+ return dispatch => {
30
+ dispatch(
31
+ addPanelIfItDoesntAlreadyExist(
32
+ {
33
+ id: "digestTool",
34
+ name: "New Digest",
35
+ active: true,
36
+ canClose: true
37
+ },
38
+ meta
39
+ )
40
+ );
41
+ dispatch(setPanelAsActive("digestTool", meta));
42
+ };
43
+ };
44
+ export const createNewPCR = (unused, meta) => {
45
+ return dispatch => {
46
+ dispatch(
47
+ addPanelIfItDoesntAlreadyExist(
48
+ {
49
+ id: "pcrTool",
50
+ name: "New PCR",
51
+ active: true,
52
+ canClose: true
53
+ },
54
+ meta
55
+ )
56
+ );
57
+ dispatch(setPanelAsActive("pcrTool", meta));
58
+ };
59
+ };
60
+
61
+ export const createNewAlignment = (payload, meta) => {
62
+ return dispatch => {
63
+ dispatch(
64
+ addPanelIfItDoesntAlreadyExist(
65
+ {
66
+ type: "alignment",
67
+ name: "New Alignment",
68
+ active: true,
69
+ canClose: true,
70
+ ...payload
71
+ },
72
+ meta
73
+ )
74
+ );
75
+ dispatch(setPanelAsActive(payload.id, meta));
76
+ };
77
+ };
78
+
79
+ export const createNewMismatchesList = (payload, meta) => {
80
+ return dispatch => {
81
+ dispatch(
82
+ addPanelIfItDoesntAlreadyExist(
83
+ {
84
+ type: "mismatches",
85
+ name: "Mismatches",
86
+ active: true,
87
+ canClose: true,
88
+ ...payload
89
+ },
90
+ meta
91
+ )
92
+ );
93
+ dispatch(setPanelAsActive(payload.id, meta));
94
+ };
95
+ };
96
+
97
+ export const collapseSplitScreen = (activePanelId, meta) => {
98
+ return dispatch => {
99
+ dispatch(_collapseSplitScreen(activePanelId, meta));
100
+ activePanelId && dispatch(setPanelAsActive(activePanelId, meta));
101
+ };
102
+ };
103
+
104
+ // ------------------------------------
105
+ // Reducer
106
+ // ------------------------------------
107
+ const reducer = createReducer(
108
+ {
109
+ [addPanelIfItDoesntAlreadyExist]: (state, panelToAdd) => {
110
+ if (
111
+ !state.some(panelGroup => {
112
+ return panelGroup.some(({ id }) => {
113
+ return id === panelToAdd.id;
114
+ });
115
+ })
116
+ ) {
117
+ return state.map((panelGroup, index) => {
118
+ if (index === 0) return [panelToAdd, ...panelGroup];
119
+ return panelGroup;
120
+ });
121
+ }
122
+ return state;
123
+ },
124
+ [panelsShownUpdate]: (state, payload) => {
125
+ return payload.filter(group => group.length); //filter out any empty groups
126
+ },
127
+ [flipActiveTabFromLinearOrCircularIfNecessary]: (state, setCircActive) => {
128
+ const newState = immer(state, s => {
129
+ s.forEach(g => {
130
+ flipActiveForGroup(g, setCircActive);
131
+ });
132
+ });
133
+
134
+ return newState;
135
+ },
136
+ [closePanel]: (state, idToClose) => {
137
+ const newState = state.map(group => {
138
+ let indexToClose;
139
+ group.forEach(({ id }, i) => {
140
+ if (id === idToClose) indexToClose = i;
141
+ });
142
+ if (indexToClose > -1) {
143
+ const newPanels = removeItem(group, indexToClose);
144
+ let mostRecentIndex = 0;
145
+ newPanels.forEach(p => {
146
+ if (
147
+ (p.lastActive || 0) > (newPanels[mostRecentIndex].lastActive || 0)
148
+ ) {
149
+ mostRecentIndex = newPanels.indexOf(p);
150
+ }
151
+ });
152
+
153
+ return newPanels.map((tab, i) => {
154
+ if (i === mostRecentIndex) return { ...tab, active: true };
155
+ else {
156
+ return tab;
157
+ }
158
+ });
159
+ }
160
+ return group;
161
+ });
162
+ return newState.filter(group => group.length); //filter out any empty groups
163
+ },
164
+ [_collapseSplitScreen]: state => {
165
+ return [flatMap(state)];
166
+ },
167
+ [expandTabToSplitScreen]: (state, activePanelId) => {
168
+ let panelToMove;
169
+ return [
170
+ state[0]
171
+ .filter(panel => {
172
+ if (panel.id === activePanelId) {
173
+ panelToMove = panel;
174
+ return false;
175
+ }
176
+ return true;
177
+ })
178
+ .map((panel, i) => {
179
+ return i === 0 ? { ...panel, active: true } : panel;
180
+ }),
181
+ [{ ...panelToMove, active: true }]
182
+ ];
183
+ },
184
+ [setPanelAsActive]: (state, panelId) => {
185
+ return map(state, panelGroup => {
186
+ const isPanelInGroup = panelGroup.some(({ id }) => {
187
+ return panelId === id;
188
+ });
189
+ return panelGroup.map(panel => {
190
+ return {
191
+ ...panel,
192
+ active:
193
+ panelId === panel.id
194
+ ? true
195
+ : isPanelInGroup
196
+ ? false
197
+ : panel.active
198
+ };
199
+ });
200
+ });
201
+ },
202
+ [togglePanelFullScreen]: (state, panelId) => {
203
+ return map(state, panelGroup => {
204
+ const isPanelInGroup = panelGroup.some(({ id }) => {
205
+ return panelId === id;
206
+ });
207
+ return panelGroup.map(panel => {
208
+ return {
209
+ ...panel,
210
+ active:
211
+ panelId === panel.id
212
+ ? true
213
+ : isPanelInGroup
214
+ ? false
215
+ : panel.active,
216
+ fullScreen:
217
+ panelId === panel.id
218
+ ? !panel.fullScreen
219
+ : isPanelInGroup
220
+ ? false
221
+ : panel.fullScreen
222
+ };
223
+ });
224
+ });
225
+ },
226
+ [collapsePanel]: (state, panelToCloseId) => {
227
+ return [
228
+ flatMap(state, panelGroup => {
229
+ return panelGroup;
230
+ }).map(panel => {
231
+ if (panel.id === panelToCloseId) {
232
+ return {
233
+ ...panel,
234
+ active: false
235
+ };
236
+ }
237
+ return panel;
238
+ })
239
+ ];
240
+ }
241
+ },
242
+ [
243
+ [
244
+ {
245
+ id: "circular",
246
+ name: "Circular Map",
247
+ active: true
248
+ // canClose: true
249
+ },
250
+ {
251
+ id: "rail",
252
+ name: "Linear Map",
253
+ active: false
254
+ }
255
+ ],
256
+ [
257
+ {
258
+ id: "sequence",
259
+ name: "Sequence Map",
260
+ active: true
261
+ },
262
+ {
263
+ id: "properties",
264
+ name: "Properties",
265
+ active: false
266
+ }
267
+ ]
268
+ ]
269
+ );
270
+
271
+ export default (state, action) => {
272
+ const nextState = reducer(state, action);
273
+ nextState.forEach(pg => {
274
+ pg.forEach(p => {
275
+ if (p.active) {
276
+ p.lastActive = Date.now();
277
+ }
278
+ });
279
+ });
280
+ return nextState;
281
+ };
282
+ function flipActiveForGroup(group, setCircActive) {
283
+ const activeTab = group.find(({ active }) => active);
284
+ if (activeTab?.id === (setCircActive ? "rail" : "circular")) {
285
+ //we're on the wrong tab type so check if the other tab is in
286
+ const newTabToActivate = group.find(
287
+ ({ id }) => id === (setCircActive ? "circular" : "rail")
288
+ );
289
+ if (newTabToActivate) {
290
+ newTabToActivate.active = true;
291
+ activeTab.active = false;
292
+ }
293
+ }
294
+ }
@@ -0,0 +1,23 @@
1
+ import createMergedDefaultStateReducer from "./utils/createMergedDefaultStateReducer";
2
+ import createAction from "./utils/createMetaAction";
3
+
4
+ // ------------------------------------
5
+ // Actions
6
+ // ------------------------------------
7
+ export const updatePartLengthsToHide = createAction("updatePartLengthsToHide");
8
+ export const togglePartLengthsToHide = createAction("togglePartLengthsToHide");
9
+
10
+ // ------------------------------------
11
+ // Reducer
12
+ // ------------------------------------
13
+ export default createMergedDefaultStateReducer(
14
+ {
15
+ [updatePartLengthsToHide]: (state, payload) => {
16
+ return { ...state, ...payload };
17
+ },
18
+ [togglePartLengthsToHide]: state => {
19
+ return { ...state, enabled: !state["enabled"] };
20
+ }
21
+ },
22
+ { enabled: false, min: 0, max: 800 }
23
+ );
@@ -0,0 +1,6 @@
1
+ export const partOverhangs = [
2
+ "fivePrimeOverhang",
3
+ "fivePrimeUnderhang",
4
+ "threePrimeOverhang",
5
+ "threePrimeUnderhang"
6
+ ];
@@ -0,0 +1,69 @@
1
+ import React from "react";
2
+ import withEditorProps from "../withEditorProps";
3
+ import { TgSelect, getKeyedTagsAndTagOptions } from "@teselagen/ui";
4
+ import { flatMap } from "lodash-es";
5
+ import { uniqBy } from "lodash-es";
6
+
7
+ export const PartTagSearch = withEditorProps(PartToolDropdown);
8
+
9
+ function PartToolDropdown({
10
+ sequenceData,
11
+ updateSelectedPartTags,
12
+ selectedPartTags,
13
+ allPartTags,
14
+ annotationVisibilityShow,
15
+ editTagsLink,
16
+ dontAutoOpen
17
+ }) {
18
+ if (!sequenceData) return <div>No Parts Present</div>;
19
+ const keyedTags = getKeyedTagsAndTagOptions(allPartTags);
20
+
21
+ // this is what keyedTags looks like:
22
+ // keyedTags = {
23
+ // '12:4': {label,value,id},
24
+ // '12:1': {label,value,id},
25
+ // '44': {label,value,id},
26
+ // }
27
+
28
+ const tags = uniqBy(
29
+ flatMap(sequenceData.parts, ({ tags }) => {
30
+ return flatMap(tags, t => {
31
+ const tag = keyedTags[t];
32
+ if (!tag) return [];
33
+ return tag;
34
+ });
35
+ }),
36
+ "value"
37
+ );
38
+ return (
39
+ <div style={{ width: "100%" }}>
40
+ <div>Search Parts By Tag: </div>
41
+ <div style={{ display: "flex" }}>
42
+ <TgSelect
43
+ value={selectedPartTags.parts}
44
+ onChange={(...args) => {
45
+ annotationVisibilityShow("parts");
46
+ updateSelectedPartTags(...args);
47
+ }}
48
+ isTagSelect
49
+ multi
50
+ popoverProps={{
51
+ usePortal: false,
52
+ modifiers: {
53
+ preventOverflow: { enabled: false },
54
+ hide: {
55
+ enabled: false
56
+ },
57
+ flip: {
58
+ boundariesElement: "viewport"
59
+ }
60
+ }
61
+ }}
62
+ options={tags}
63
+ autoOpen={!dontAutoOpen}
64
+ ></TgSelect>
65
+ {editTagsLink || null}
66
+ </div>
67
+ </div>
68
+ );
69
+ }
package/partTool.js ADDED
@@ -0,0 +1,45 @@
1
+ import { Icon } from "@blueprintjs/core";
2
+ // import { Checkbox, Button } from "@blueprintjs/core";
3
+ import React from "react";
4
+ // import { connect } from "react-redux";
5
+ // import { convertRangeTo1Based } from "@teselagen/range-utils";
6
+ //import { partIcon } from "@teselagen/ui";
7
+ import ToolbarItem from "./ToolbarItem";
8
+ import { connectToEditor } from "../withEditorProps";
9
+ import { PartTagSearch } from "../helperComponents/partTagSearch";
10
+
11
+ export default connectToEditor(
12
+ ({ annotationVisibility = {}, toolBar = {} }) => {
13
+ return {
14
+ toggled: annotationVisibility.parts,
15
+ isOpen: toolBar.openItem === "partTool"
16
+ };
17
+ }
18
+ )(({
19
+ allPartTags,
20
+ editTagsLink,
21
+ toolbarItemProps,
22
+ toggled,
23
+ annotationVisibilityToggle,
24
+ isOpen
25
+ }) => {
26
+ return (
27
+ <ToolbarItem
28
+ {...{
29
+ Icon: <Icon icon="doughnut-chart" />,
30
+ onIconClick: function () {
31
+ annotationVisibilityToggle("parts");
32
+ },
33
+ toggled,
34
+ editTagsLink,
35
+ allPartTags,
36
+ tooltip: "Show parts",
37
+ tooltipToggled: "Hide parts",
38
+ noDropdownIcon: !allPartTags,
39
+ Dropdown: PartTagSearch,
40
+ dropdowntooltip: (!isOpen ? "Show" : "Hide") + " Part Options",
41
+ ...toolbarItemProps
42
+ }}
43
+ />
44
+ );
45
+ });
package/parts.js ADDED
@@ -0,0 +1,19 @@
1
+ import { createReducer } from "redux-act";
2
+ import createAction from "../utils/createMetaAction";
3
+ import upsertDeleteActionGenerator from "./upsertDeleteActionGenerator";
4
+
5
+ // ------------------------------------
6
+ // Actions
7
+ // ------------------------------------
8
+ export const upsertPart = createAction("UPSERT_PART");
9
+ export const deletePart = createAction("DELETE_PART");
10
+
11
+ // ------------------------------------
12
+ // Reducer
13
+ // ------------------------------------
14
+ export default createReducer(
15
+ {
16
+ ...upsertDeleteActionGenerator(upsertPart, deletePart)
17
+ },
18
+ {}
19
+ );
@@ -0,0 +1,8 @@
1
+ import { createSelector } from "reselect";
2
+ import sequenceDataSelector from "./sequenceDataSelector";
3
+
4
+ function partsRawSelector(sequenceData) {
5
+ return sequenceData.parts;
6
+ }
7
+
8
+ export default createSelector(sequenceDataSelector, partsRawSelector);
package/pie.png ADDED
Binary file
@@ -0,0 +1,7 @@
1
+ export default function polarToSpecialCartesian(radius, angle) {
2
+ //the 0 angle returns the 0,1 point on the unit circle instead of the 1,0 point like normal
3
+ return {
4
+ x: radius * Math.cos(angle - Math.PI / 2),
5
+ y: radius * Math.sin(angle - Math.PI / 2)
6
+ };
7
+ }
@@ -0,0 +1,6 @@
1
+ export function positionCutsites(annotation) {
2
+ return {
3
+ start: annotation.topSnipPosition,
4
+ end: annotation.topSnipPosition
5
+ };
6
+ }
@@ -0,0 +1,64 @@
1
+ import { mapAnnotationsToRows } from "@teselagen/sequence-utils";
2
+ import { annotationTypes } from "@teselagen/sequence-utils";
3
+ export default function prepareRowData(sequenceData, bpsPerRow) {
4
+ const sequenceLength = sequenceData.noSequence
5
+ ? sequenceData.size
6
+ : sequenceData.sequence.length;
7
+ const totalRows = Math.ceil(sequenceLength / bpsPerRow) || 1; //this check makes sure there is always at least 1 row!
8
+ const rows = [];
9
+ const rowMap = {};
10
+ if (sequenceData.isProtein) {
11
+ rowMap.primaryProteinSequence = mapAnnotationsToRows(
12
+ [
13
+ {
14
+ id: "primaryProteinSequence",
15
+ forward: true,
16
+ start: 0,
17
+ end: sequenceLength - 1,
18
+ proteinSequence: sequenceData.proteinSequence,
19
+ aminoAcids: sequenceData.aminoAcidDataForEachBaseOfDNA
20
+ }
21
+ ],
22
+ sequenceLength,
23
+ bpsPerRow
24
+ );
25
+ }
26
+ annotationTypes.forEach(function (type) {
27
+ rowMap[type] = mapAnnotationsToRows(
28
+ sequenceData[type],
29
+ sequenceLength,
30
+ bpsPerRow,
31
+ { splitForwardReverse: type === "primers" }
32
+ );
33
+ });
34
+
35
+ for (let rowNumber = 0; rowNumber < totalRows; rowNumber++) {
36
+ const row = {};
37
+ row.rowNumber = rowNumber;
38
+ row.start = rowNumber * bpsPerRow;
39
+ row.end =
40
+ (rowNumber + 1) * bpsPerRow - 1 < sequenceLength
41
+ ? (rowNumber + 1) * bpsPerRow - 1
42
+ : sequenceLength - 1;
43
+ if (row.end < 0) {
44
+ row.end = 0;
45
+ }
46
+ annotationTypes.forEach(function (type) {
47
+ row[type] = rowMap[type][rowNumber] || [];
48
+ });
49
+ if (sequenceData.isProtein) {
50
+ row.isProtein = true;
51
+ row.primaryProteinSequence =
52
+ rowMap.primaryProteinSequence &&
53
+ (rowMap.primaryProteinSequence[rowNumber] || []);
54
+ }
55
+ row.sequence = sequenceData.noSequence
56
+ ? {
57
+ length: row.end + 1 - row.start
58
+ }
59
+ : sequenceData.sequence.slice(row.start, row.end + 1);
60
+
61
+ rows[rowNumber] = row;
62
+ }
63
+ return rows;
64
+ }