react-msaview 4.4.5 → 4.5.0

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 (129) hide show
  1. package/bundle/index.js +9 -9
  2. package/bundle/index.js.LICENSE.txt +8 -8
  3. package/bundle/index.js.map +1 -1
  4. package/dist/colorSchemes.d.ts +0 -6
  5. package/dist/colorSchemes.js +1 -119
  6. package/dist/colorSchemes.js.map +1 -1
  7. package/dist/components/ConservationTrack.d.ts +8 -0
  8. package/dist/components/ConservationTrack.js +54 -0
  9. package/dist/components/ConservationTrack.js.map +1 -0
  10. package/dist/components/Loading.js +14 -2
  11. package/dist/components/Loading.js.map +1 -1
  12. package/dist/components/MSAView.js +36 -0
  13. package/dist/components/MSAView.js.map +1 -1
  14. package/dist/components/SequenceTextArea.js +3 -2
  15. package/dist/components/SequenceTextArea.js.map +1 -1
  16. package/dist/components/TextTrack.d.ts +3 -3
  17. package/dist/components/TextTrack.js +4 -1
  18. package/dist/components/TextTrack.js.map +1 -1
  19. package/dist/components/Track.js +21 -8
  20. package/dist/components/Track.js.map +1 -1
  21. package/dist/components/dialogs/ExportSVGDialog.js +19 -3
  22. package/dist/components/dialogs/ExportSVGDialog.js.map +1 -1
  23. package/dist/components/header/GappynessSlider.d.ts +6 -0
  24. package/dist/components/header/GappynessSlider.js +19 -0
  25. package/dist/components/header/GappynessSlider.js.map +1 -0
  26. package/dist/components/header/Header.js +3 -1
  27. package/dist/components/header/Header.js.map +1 -1
  28. package/dist/components/header/HeaderMenu.js +30 -14
  29. package/dist/components/header/HeaderMenu.js.map +1 -1
  30. package/dist/components/minimap/MinimapSVG.js +4 -3
  31. package/dist/components/minimap/MinimapSVG.js.map +1 -1
  32. package/dist/components/msa/MSACanvasBlock.js +56 -42
  33. package/dist/components/msa/MSACanvasBlock.js.map +1 -1
  34. package/dist/components/msa/renderMSABlock.js +53 -10
  35. package/dist/components/msa/renderMSABlock.js.map +1 -1
  36. package/dist/components/tracks/renderTracksSvg.d.ts +29 -0
  37. package/dist/components/tracks/renderTracksSvg.js +83 -0
  38. package/dist/components/tracks/renderTracksSvg.js.map +1 -0
  39. package/dist/components/tree/TreeCanvasBlock.js +1 -1
  40. package/dist/components/tree/TreeCanvasBlock.js.map +1 -1
  41. package/dist/components/tree/TreeNodeMenu.js +2 -2
  42. package/dist/components/tree/TreeNodeMenu.js.map +1 -1
  43. package/dist/components/tree/renderTreeCanvas.js +1 -1
  44. package/dist/components/tree/renderTreeCanvas.js.map +1 -1
  45. package/dist/constants.d.ts +22 -0
  46. package/dist/constants.js +26 -0
  47. package/dist/constants.js.map +1 -0
  48. package/dist/layout.js.map +1 -1
  49. package/dist/model/msaModel.js +3 -2
  50. package/dist/model/msaModel.js.map +1 -1
  51. package/dist/model/treeModel.js +9 -8
  52. package/dist/model/treeModel.js.map +1 -1
  53. package/dist/model.d.ts +256 -15
  54. package/dist/model.js +408 -128
  55. package/dist/model.js.map +1 -1
  56. package/dist/neighborJoining.d.ts +1 -0
  57. package/dist/neighborJoining.js +839 -0
  58. package/dist/neighborJoining.js.map +1 -0
  59. package/dist/neighborJoining.test.d.ts +1 -0
  60. package/dist/neighborJoining.test.js +110 -0
  61. package/dist/neighborJoining.test.js.map +1 -0
  62. package/dist/parsers/A3mMSA.d.ts +43 -0
  63. package/dist/parsers/A3mMSA.js +277 -0
  64. package/dist/parsers/A3mMSA.js.map +1 -0
  65. package/dist/parsers/A3mMSA.test.d.ts +1 -0
  66. package/dist/parsers/A3mMSA.test.js +138 -0
  67. package/dist/parsers/A3mMSA.test.js.map +1 -0
  68. package/dist/parsers/ClustalMSA.d.ts +4 -4
  69. package/dist/parsers/ClustalMSA.js +3 -1
  70. package/dist/parsers/ClustalMSA.js.map +1 -1
  71. package/dist/parsers/FastaMSA.js +17 -16
  72. package/dist/parsers/FastaMSA.js.map +1 -1
  73. package/dist/renderToSvg.d.ts +1 -0
  74. package/dist/renderToSvg.js +48 -18
  75. package/dist/renderToSvg.js.map +1 -1
  76. package/dist/rowCoordinateCalculations.js +3 -5
  77. package/dist/rowCoordinateCalculations.js.map +1 -1
  78. package/dist/rowCoordinateCalculations.test.js +14 -2
  79. package/dist/rowCoordinateCalculations.test.js.map +1 -1
  80. package/dist/seqCoordToRowSpecificGlobalCoord.js +9 -5
  81. package/dist/seqCoordToRowSpecificGlobalCoord.js.map +1 -1
  82. package/dist/seqCoordToRowSpecificGlobalCoord.test.js +6 -6
  83. package/dist/types.d.ts +2 -3
  84. package/dist/util.js +17 -9
  85. package/dist/util.js.map +1 -1
  86. package/dist/version.d.ts +1 -1
  87. package/dist/version.js +1 -1
  88. package/package.json +6 -6
  89. package/src/colorSchemes.ts +1 -179
  90. package/src/components/ConservationTrack.tsx +104 -0
  91. package/src/components/Loading.tsx +44 -2
  92. package/src/components/MSAView.tsx +68 -0
  93. package/src/components/SequenceTextArea.tsx +3 -2
  94. package/src/components/TextTrack.tsx +7 -4
  95. package/src/components/Track.tsx +25 -9
  96. package/src/components/dialogs/ExportSVGDialog.tsx +25 -1
  97. package/src/components/header/GappynessSlider.tsx +35 -0
  98. package/src/components/header/Header.tsx +3 -1
  99. package/src/components/header/HeaderMenu.tsx +36 -15
  100. package/src/components/minimap/MinimapSVG.tsx +6 -3
  101. package/src/components/msa/MSACanvasBlock.tsx +66 -48
  102. package/src/components/msa/renderMSABlock.ts +82 -22
  103. package/src/components/tracks/renderTracksSvg.ts +157 -0
  104. package/src/components/tree/TreeCanvasBlock.tsx +1 -1
  105. package/src/components/tree/TreeNodeMenu.tsx +2 -2
  106. package/src/components/tree/renderTreeCanvas.ts +1 -1
  107. package/src/constants.ts +27 -0
  108. package/src/layout.ts +1 -6
  109. package/src/model/msaModel.ts +4 -2
  110. package/src/model/treeModel.ts +19 -8
  111. package/src/model.ts +496 -140
  112. package/src/neighborJoining.test.ts +129 -0
  113. package/src/neighborJoining.ts +885 -0
  114. package/src/parsers/A3mMSA.test.ts +164 -0
  115. package/src/parsers/A3mMSA.ts +321 -0
  116. package/src/parsers/ClustalMSA.ts +7 -5
  117. package/src/parsers/FastaMSA.ts +17 -17
  118. package/src/renderToSvg.tsx +105 -26
  119. package/src/rowCoordinateCalculations.test.ts +15 -2
  120. package/src/rowCoordinateCalculations.ts +3 -5
  121. package/src/seqCoordToRowSpecificGlobalCoord.test.ts +6 -6
  122. package/src/seqCoordToRowSpecificGlobalCoord.ts +9 -4
  123. package/src/types.ts +2 -4
  124. package/src/util.ts +21 -8
  125. package/src/version.ts +1 -1
  126. package/dist/components/dialogs/TracklistDialog.d.ts +0 -7
  127. package/dist/components/dialogs/TracklistDialog.js +0 -23
  128. package/dist/components/dialogs/TracklistDialog.js.map +0 -1
  129. package/src/components/dialogs/TracklistDialog.tsx +0 -73
@@ -7,6 +7,7 @@ import { when } from 'mobx'
7
7
  import MinimapSVG from './components/minimap/MinimapSVG'
8
8
  import { renderBoxFeatureCanvasBlock } from './components/msa/renderBoxFeatureCanvasBlock'
9
9
  import { renderMSABlock } from './components/msa/renderMSABlock'
10
+ import { renderAllTracks } from './components/tracks/renderTracksSvg'
10
11
  import { renderTreeCanvas } from './components/tree/renderTreeCanvas'
11
12
  import { colorContrast } from './util'
12
13
 
@@ -16,33 +17,41 @@ import type { Theme } from '@mui/material'
16
17
  export interface ExportSvgOptions {
17
18
  theme: Theme
18
19
  includeMinimap?: boolean
20
+ includeTracks?: boolean
19
21
  exportType: string
20
22
  }
21
23
  export async function renderToSvg(model: MsaViewModel, opts: ExportSvgOptions) {
22
24
  await when(() => !!model.dataInitialized)
23
- const { width, height, scrollX, scrollY } = model
24
- const { exportType, theme, includeMinimap } = opts
25
+ const { width, height, scrollX, scrollY, totalTrackAreaHeight } = model
26
+ const { exportType, theme, includeMinimap, includeTracks } = opts
27
+ const trackHeight = includeTracks ? totalTrackAreaHeight : 0
25
28
 
26
29
  if (exportType === 'entire') {
27
30
  return render({
28
31
  width: model.totalWidth + model.treeAreaWidth,
29
- height: model.totalHeight,
32
+ height: model.totalHeight + trackHeight,
33
+ contentHeight: model.totalHeight,
34
+ trackHeight,
30
35
  theme,
31
36
  model,
32
37
  offsetY: 0,
33
38
  offsetX: 0,
34
39
  includeMinimap,
40
+ includeTracks,
35
41
  })
36
42
  }
37
43
  if (exportType === 'viewport') {
38
44
  return render({
39
45
  width,
40
- height,
46
+ height: height + (includeMinimap ? model.minimapHeight : 0) + trackHeight,
47
+ contentHeight: height,
48
+ trackHeight,
41
49
  theme,
42
50
  model,
43
- offsetY: scrollY,
51
+ offsetY: -scrollY,
44
52
  offsetX: -scrollX,
45
53
  includeMinimap,
54
+ includeTracks,
46
55
  })
47
56
  }
48
57
  throw new Error('unknown export type')
@@ -51,19 +60,25 @@ export async function renderToSvg(model: MsaViewModel, opts: ExportSvgOptions) {
51
60
  async function render({
52
61
  width,
53
62
  height,
63
+ contentHeight,
64
+ trackHeight,
54
65
  offsetX,
55
66
  offsetY,
56
67
  theme,
57
68
  model,
58
69
  includeMinimap,
70
+ includeTracks,
59
71
  }: {
60
72
  width: number
61
73
  height: number
74
+ contentHeight: number
75
+ trackHeight: number
62
76
  offsetX: number
63
77
  offsetY: number
64
78
  theme: Theme
65
79
  model: MsaViewModel
66
80
  includeMinimap?: boolean
81
+ includeTracks?: boolean
67
82
  }) {
68
83
  const { Context } = await import('svgcanvas')
69
84
  const Wrapper = includeMinimap ? MinimapWrapper : NullWrapper
@@ -71,15 +86,31 @@ async function render({
71
86
  return renderToStaticMarkup(
72
87
  <SvgWrapper width={width} height={height}>
73
88
  <Wrapper model={model}>
74
- <CoreRendering
75
- Context={Context}
76
- model={model}
77
- theme={theme}
78
- offsetX={offsetX}
79
- offsetY={offsetY}
80
- width={width}
81
- height={height}
82
- />
89
+ {includeTracks && trackHeight > 0 ? (
90
+ <TrackRendering
91
+ Context={Context}
92
+ model={model}
93
+ theme={theme}
94
+ offsetX={offsetX}
95
+ width={width}
96
+ trackHeight={trackHeight}
97
+ />
98
+ ) : null}
99
+ <g
100
+ transform={
101
+ trackHeight > 0 ? `translate(0 ${trackHeight})` : undefined
102
+ }
103
+ >
104
+ <CoreRendering
105
+ Context={Context}
106
+ model={model}
107
+ theme={theme}
108
+ offsetX={offsetX}
109
+ offsetY={offsetY}
110
+ width={width}
111
+ contentHeight={contentHeight}
112
+ />
113
+ </g>
83
114
  </Wrapper>
84
115
  </SvgWrapper>,
85
116
  )
@@ -89,7 +120,7 @@ function CoreRendering({
89
120
  model,
90
121
  theme,
91
122
  width,
92
- height,
123
+ contentHeight,
93
124
  offsetX,
94
125
  offsetY,
95
126
  Context,
@@ -97,7 +128,7 @@ function CoreRendering({
97
128
  model: MsaViewModel
98
129
  theme: Theme
99
130
  width: number
100
- height: number
131
+ contentHeight: number
101
132
  offsetX: number
102
133
  offsetY: number
103
134
  Context: (
@@ -105,18 +136,18 @@ function CoreRendering({
105
136
  height: number,
106
137
  ) => CanvasRenderingContext2D & { getSvg: () => { innerHTML: string } }
107
138
  }) {
108
- const clipId1 = 'tree'
109
- const clipId2 = 'msa'
110
- const { treeAreaWidth, colorScheme } = model
139
+ const { treeAreaWidth, colorScheme, id } = model
140
+ const clipId1 = `tree-${id}`
141
+ const clipId2 = `msa-${id}`
111
142
  const contrastScheme = colorContrast(colorScheme, theme)
112
- const ctx1 = Context(width, height)
113
- const ctx2 = Context(width, height)
143
+ const ctx1 = Context(width, contentHeight)
144
+ const ctx2 = Context(width, contentHeight)
114
145
  renderBoxFeatureCanvasBlock({
115
146
  ctx: ctx2,
116
147
  offsetX,
117
148
  offsetY,
118
149
  model,
119
- blockSizeYOverride: height,
150
+ blockSizeYOverride: contentHeight,
120
151
  highResScaleFactorOverride: 1,
121
152
  })
122
153
  const msaAreaWidth = width - treeAreaWidth
@@ -125,7 +156,7 @@ function CoreRendering({
125
156
  offsetY,
126
157
  ctx: ctx1,
127
158
  theme,
128
- blockSizeYOverride: height,
159
+ blockSizeYOverride: contentHeight,
129
160
  highResScaleFactorOverride: 1,
130
161
  })
131
162
  renderMSABlock({
@@ -136,19 +167,19 @@ function CoreRendering({
136
167
  contrastScheme,
137
168
  ctx: ctx2,
138
169
  blockSizeXOverride: msaAreaWidth,
139
- blockSizeYOverride: height,
170
+ blockSizeYOverride: contentHeight,
140
171
  highResScaleFactorOverride: 1,
141
172
  })
142
173
  return (
143
174
  <>
144
175
  <defs>
145
176
  <clipPath id={clipId1}>
146
- <rect x={0} y={0} width={treeAreaWidth} height={height} />
177
+ <rect x={0} y={0} width={treeAreaWidth} height={contentHeight} />
147
178
  </clipPath>
148
179
  </defs>
149
180
  <defs>
150
181
  <clipPath id={clipId2}>
151
- <rect x={0} y={0} width={msaAreaWidth} height={height} />
182
+ <rect x={0} y={0} width={msaAreaWidth} height={contentHeight} />
152
183
  </clipPath>
153
184
  </defs>
154
185
 
@@ -165,6 +196,54 @@ function CoreRendering({
165
196
  )
166
197
  }
167
198
 
199
+ function TrackRendering({
200
+ model,
201
+ theme,
202
+ width,
203
+ trackHeight,
204
+ offsetX,
205
+ Context,
206
+ }: {
207
+ model: MsaViewModel
208
+ theme: Theme
209
+ width: number
210
+ trackHeight: number
211
+ offsetX: number
212
+ Context: (
213
+ width: number,
214
+ height: number,
215
+ ) => CanvasRenderingContext2D & { getSvg: () => { innerHTML: string } }
216
+ }) {
217
+ const { treeAreaWidth, colorScheme, id } = model
218
+ const clipId = `tracks-${id}`
219
+ const contrastScheme = colorContrast(colorScheme, theme)
220
+ const msaAreaWidth = width - treeAreaWidth
221
+ const ctx = Context(msaAreaWidth, trackHeight)
222
+
223
+ renderAllTracks({
224
+ model,
225
+ ctx,
226
+ offsetX,
227
+ contrastScheme,
228
+ blockSizeXOverride: msaAreaWidth,
229
+ highResScaleFactorOverride: 1,
230
+ })
231
+
232
+ return (
233
+ <g transform={`translate(${treeAreaWidth} 0)`}>
234
+ <defs>
235
+ <clipPath id={clipId}>
236
+ <rect x={0} y={0} width={msaAreaWidth} height={trackHeight} />
237
+ </clipPath>
238
+ </defs>
239
+ <g
240
+ clipPath={`url(#${clipId})`}
241
+ dangerouslySetInnerHTML={{ __html: ctx.getSvg().innerHTML }}
242
+ />
243
+ </g>
244
+ )
245
+ }
246
+
168
247
  function MinimapWrapper({
169
248
  model,
170
249
  children,
@@ -90,11 +90,24 @@ test('with gaps in sequence', () => {
90
90
  expect(globalCoordToRowSpecificCoord(sequence, 0)).toBe(0)
91
91
  expect(globalCoordToRowSpecificCoord(sequence, 1)).toBe(1)
92
92
  expect(globalCoordToRowSpecificCoord(sequence, 2)).toBe(2)
93
- // Position 3 in global coordinates is after the gap
93
+ // Position 2 is a gap, so count before it is 2
94
94
  expect(globalCoordToRowSpecificCoord(sequence, 3)).toBe(2)
95
95
  expect(globalCoordToRowSpecificCoord(sequence, 4)).toBe(3)
96
96
  expect(globalCoordToRowSpecificCoord(sequence, 5)).toBe(4)
97
- // Position 6 in global coordinates is after the gap
97
+ // Position 5 is a gap, so count before it is 4
98
+ expect(globalCoordToRowSpecificCoord(sequence, 6)).toBe(4)
99
+ })
100
+
101
+ test('with mixed gap characters (- and .)', () => {
102
+ const sequence = 'AC.GT-A'
103
+ expect(globalCoordToRowSpecificCoord(sequence, 0)).toBe(0)
104
+ expect(globalCoordToRowSpecificCoord(sequence, 1)).toBe(1)
105
+ // Position 2 is a gap (.), so count before it is 2
106
+ expect(globalCoordToRowSpecificCoord(sequence, 2)).toBe(2)
107
+ expect(globalCoordToRowSpecificCoord(sequence, 3)).toBe(2)
108
+ expect(globalCoordToRowSpecificCoord(sequence, 4)).toBe(3)
109
+ // Position 5 is a gap (-), so count before it is 4
110
+ expect(globalCoordToRowSpecificCoord(sequence, 5)).toBe(4)
98
111
  expect(globalCoordToRowSpecificCoord(sequence, 6)).toBe(4)
99
112
  })
100
113
 
@@ -12,6 +12,8 @@ export function mouseOverCoordToGlobalCoord(
12
12
  // Iterate until we reach the target mouse position
13
13
  while (mousePosition < position) {
14
14
  // Skip any blank positions in the sequence
15
+ // Check if the next position (globalPosition + 1) is blank by comparing
16
+ // blanks[blankArrayIndex] - 1 with current globalPosition
15
17
  while (
16
18
  blankArrayIndex < blanksLen &&
17
19
  blanks[blankArrayIndex]! - 1 === globalPosition
@@ -38,13 +40,9 @@ export function globalCoordToRowSpecificCoord(seq: string, position: number) {
38
40
  // Iterate until we reach the target position or end of sequence
39
41
  while (currentPosition < position && currentPosition < sequenceLength) {
40
42
  // If current character is not a gap, increment the non-gap counter
41
- if (seq[currentPosition] !== '-') {
43
+ if (!isBlank(seq[currentPosition])) {
42
44
  nonGapCount++
43
45
  }
44
- // If we've reached the target position in non-gap coordinates, break
45
- else if (nonGapCount >= position) {
46
- break
47
- }
48
46
  currentPosition++
49
47
  }
50
48
 
@@ -19,13 +19,13 @@ describe('seqCoordToRowSpecificGlobalCoord', () => {
19
19
  expect(seqCoordToRowSpecificGlobalCoord({ row, position: 0 })).toBe(0)
20
20
 
21
21
  // Position 1 (T after first gap) -> Global index 2
22
- expect(seqCoordToRowSpecificGlobalCoord({ row, position: 1 })).toBe(1)
22
+ expect(seqCoordToRowSpecificGlobalCoord({ row, position: 1 })).toBe(2)
23
23
 
24
24
  // Position 3 (C after second gap) -> Global index 5
25
- expect(seqCoordToRowSpecificGlobalCoord({ row, position: 3 })).toBe(4)
25
+ expect(seqCoordToRowSpecificGlobalCoord({ row, position: 3 })).toBe(5)
26
26
 
27
27
  // Position 5 (T after third gap) -> Global index 8
28
- expect(seqCoordToRowSpecificGlobalCoord({ row, position: 5 })).toBe(7)
28
+ expect(seqCoordToRowSpecificGlobalCoord({ row, position: 5 })).toBe(8)
29
29
 
30
30
  // Position 8 (end of sequence) -> Global index 11
31
31
  expect(seqCoordToRowSpecificGlobalCoord({ row, position: 8 })).toBe(11)
@@ -46,8 +46,8 @@ describe('seqCoordToRowSpecificGlobalCoord', () => {
46
46
  // Sequence positions: A(0) G(1) C(2)
47
47
 
48
48
  expect(seqCoordToRowSpecificGlobalCoord({ row, position: 0 })).toBe(0)
49
- expect(seqCoordToRowSpecificGlobalCoord({ row, position: 1 })).toBe(1)
50
- expect(seqCoordToRowSpecificGlobalCoord({ row, position: 2 })).toBe(4)
51
- expect(seqCoordToRowSpecificGlobalCoord({ row, position: 3 })).toBe(6)
49
+ expect(seqCoordToRowSpecificGlobalCoord({ row, position: 1 })).toBe(3)
50
+ expect(seqCoordToRowSpecificGlobalCoord({ row, position: 2 })).toBe(5)
51
+ expect(seqCoordToRowSpecificGlobalCoord({ row, position: 3 })).toBe(7)
52
52
  })
53
53
  })
@@ -9,12 +9,17 @@ export function seqCoordToRowSpecificGlobalCoord({
9
9
  }) {
10
10
  let k = 0
11
11
  let i = 0
12
- for (; k < position; i++) {
12
+ // Find the position-th non-gap character
13
+ while (i < row.length) {
13
14
  if (!isBlank(row[i])) {
15
+ if (k === position) {
16
+ return i
17
+ }
14
18
  k++
15
- } else if (k >= position) {
16
- break
17
19
  }
20
+ i++
18
21
  }
19
- return i
22
+ // If position is 0 and we didn't find any non-gap character, return 0
23
+ // Otherwise return i (which is row.length at this point)
24
+ return position === 0 ? 0 : i
20
25
  }
package/src/types.ts CHANGED
@@ -12,16 +12,14 @@ export interface BasicTrackModel {
12
12
 
13
13
  export interface TextTrackModel extends BasicTrackModel {
14
14
  customColorScheme?: Record<string, string>
15
- data: string
15
+ data?: string
16
16
  }
17
17
 
18
- export interface ITextTrack {
18
+ export interface BasicTrack {
19
19
  ReactComponent: React.FC<any>
20
20
  model: TextTrackModel
21
21
  }
22
22
 
23
- export type BasicTrack = ITextTrack
24
-
25
23
  export interface Node {
26
24
  children?: Node[]
27
25
  name?: string
package/src/util.ts CHANGED
@@ -44,16 +44,29 @@ export function colorContrast(
44
44
  }
45
45
 
46
46
  export function skipBlanks(blanks: number[], arg: string | string[]) {
47
- let s = ''
48
- let b = 0
49
- for (let j = 0, l = arg.length; j < l; j++) {
50
- if (j === blanks[b]) {
51
- b++
52
- } else {
53
- s += arg[j]
47
+ if (blanks.length === 0) {
48
+ return typeof arg === 'string' ? arg : arg.join('')
49
+ }
50
+ const chunks = []
51
+ let lastEnd = 0
52
+ for (const blankIdx of blanks) {
53
+ if (blankIdx > lastEnd) {
54
+ chunks.push(
55
+ typeof arg === 'string'
56
+ ? arg.slice(lastEnd, blankIdx)
57
+ : arg.slice(lastEnd, blankIdx).join(''),
58
+ )
54
59
  }
60
+ lastEnd = blankIdx + 1
61
+ }
62
+ if (lastEnd < arg.length) {
63
+ chunks.push(
64
+ typeof arg === 'string'
65
+ ? arg.slice(lastEnd)
66
+ : arg.slice(lastEnd).join(''),
67
+ )
55
68
  }
56
- return s
69
+ return chunks.join('')
57
70
  }
58
71
 
59
72
  // basically same as setRadius from https://observablehq.com/@d3/tree-of-life
package/src/version.ts CHANGED
@@ -1 +1 @@
1
- export const version = '4.4.5'
1
+ export const version = '4.4.7'
@@ -1,7 +0,0 @@
1
- import React from 'react';
2
- import type { MsaViewModel } from '../../model';
3
- declare const TracklistDialog: ({ model, onClose, }: {
4
- model: MsaViewModel;
5
- onClose: () => void;
6
- }) => React.JSX.Element;
7
- export default TracklistDialog;
@@ -1,23 +0,0 @@
1
- import React from 'react';
2
- import { Dialog } from '@jbrowse/core/ui';
3
- import { Button, Checkbox, DialogActions, DialogContent, FormControlLabel, FormGroup, Typography, } from '@mui/material';
4
- import { observer } from 'mobx-react';
5
- const TracklistDialog = observer(function ({ model, onClose, }) {
6
- const { tracks } = model;
7
- return (React.createElement(Dialog, { onClose: () => {
8
- onClose();
9
- }, open: true, title: "Add track" },
10
- React.createElement(DialogContent, null,
11
- React.createElement(Typography, null, "Open relevant per-alignment tracks e.g. protein domains"),
12
- React.createElement(FormGroup, null, tracks.map(track => {
13
- return (React.createElement(FormControlLabel, { key: track.model.id, control: React.createElement(Checkbox, { checked: !model.turnedOffTracks.has(track.model.id), onChange: () => {
14
- model.toggleTrack(track.model.id);
15
- } }), label: track.model.name }));
16
- })),
17
- React.createElement(DialogActions, null,
18
- React.createElement(Button, { onClick: () => {
19
- onClose();
20
- }, variant: "contained", color: "primary" }, "Close")))));
21
- });
22
- export default TracklistDialog;
23
- //# sourceMappingURL=TracklistDialog.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"TracklistDialog.js","sourceRoot":"","sources":["../../../src/components/dialogs/TracklistDialog.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAEzB,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAA;AACzC,OAAO,EACL,MAAM,EACN,QAAQ,EACR,aAAa,EACb,aAAa,EACb,gBAAgB,EAChB,SAAS,EACT,UAAU,GACX,MAAM,eAAe,CAAA;AACtB,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;AAIrC,MAAM,eAAe,GAAG,QAAQ,CAAC,UAAU,EACzC,KAAK,EACL,OAAO,GAIR;IACC,MAAM,EAAE,MAAM,EAAE,GAAG,KAAK,CAAA;IAExB,OAAO,CACL,oBAAC,MAAM,IACL,OAAO,EAAE,GAAG,EAAE;YACZ,OAAO,EAAE,CAAA;QACX,CAAC,EACD,IAAI,QACJ,KAAK,EAAC,WAAW;QAEjB,oBAAC,aAAa;YACZ,oBAAC,UAAU,kEAEE;YAEb,oBAAC,SAAS,QACP,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE;gBAClB,OAAO,CACL,oBAAC,gBAAgB,IACf,GAAG,EAAE,KAAK,CAAC,KAAK,CAAC,EAAE,EACnB,OAAO,EACL,oBAAC,QAAQ,IACP,OAAO,EAAE,CAAC,KAAK,CAAC,eAAe,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC,EACnD,QAAQ,EAAE,GAAG,EAAE;4BACb,KAAK,CAAC,WAAW,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC,CAAA;wBACnC,CAAC,GACD,EAEJ,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC,IAAI,GACvB,CACH,CAAA;YACH,CAAC,CAAC,CACQ;YACZ,oBAAC,aAAa;gBACZ,oBAAC,MAAM,IACL,OAAO,EAAE,GAAG,EAAE;wBACZ,OAAO,EAAE,CAAA;oBACX,CAAC,EACD,OAAO,EAAC,WAAW,EACnB,KAAK,EAAC,SAAS,YAGR,CACK,CACF,CACT,CACV,CAAA;AACH,CAAC,CAAC,CAAA;AAEF,eAAe,eAAe,CAAA"}
@@ -1,73 +0,0 @@
1
- import React from 'react'
2
-
3
- import { Dialog } from '@jbrowse/core/ui'
4
- import {
5
- Button,
6
- Checkbox,
7
- DialogActions,
8
- DialogContent,
9
- FormControlLabel,
10
- FormGroup,
11
- Typography,
12
- } from '@mui/material'
13
- import { observer } from 'mobx-react'
14
-
15
- import type { MsaViewModel } from '../../model'
16
-
17
- const TracklistDialog = observer(function ({
18
- model,
19
- onClose,
20
- }: {
21
- model: MsaViewModel
22
- onClose: () => void
23
- }) {
24
- const { tracks } = model
25
-
26
- return (
27
- <Dialog
28
- onClose={() => {
29
- onClose()
30
- }}
31
- open
32
- title="Add track"
33
- >
34
- <DialogContent>
35
- <Typography>
36
- Open relevant per-alignment tracks e.g. protein domains
37
- </Typography>
38
-
39
- <FormGroup>
40
- {tracks.map(track => {
41
- return (
42
- <FormControlLabel
43
- key={track.model.id}
44
- control={
45
- <Checkbox
46
- checked={!model.turnedOffTracks.has(track.model.id)}
47
- onChange={() => {
48
- model.toggleTrack(track.model.id)
49
- }}
50
- />
51
- }
52
- label={track.model.name}
53
- />
54
- )
55
- })}
56
- </FormGroup>
57
- <DialogActions>
58
- <Button
59
- onClick={() => {
60
- onClose()
61
- }}
62
- variant="contained"
63
- color="primary"
64
- >
65
- Close
66
- </Button>
67
- </DialogActions>
68
- </DialogContent>
69
- </Dialog>
70
- )
71
- })
72
-
73
- export default TracklistDialog