genoverse 3.2.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 (148) hide show
  1. package/.eslintrc.js +197 -0
  2. package/.github/workflows/test.yml +24 -0
  3. package/LICENSE.TXT +24 -0
  4. package/README.md +11 -0
  5. package/css/controlPanel.css +200 -0
  6. package/css/fileDrop.css +22 -0
  7. package/css/font-awesome.css +3 -0
  8. package/css/fullscreen.css +19 -0
  9. package/css/genoverse.css +466 -0
  10. package/css/karyotype.css +85 -0
  11. package/css/resizer.css +36 -0
  12. package/css/tooltips.css +26 -0
  13. package/css/trackControls.css +111 -0
  14. package/expanded.html +120 -0
  15. package/fontawesome/css/fontawesome.min.css +5 -0
  16. package/fontawesome/css/regular.min.css +5 -0
  17. package/fontawesome/css/solid.min.css +5 -0
  18. package/fontawesome/webfonts/fa-brands-400.ttf +0 -0
  19. package/fontawesome/webfonts/fa-brands-400.woff +0 -0
  20. package/fontawesome/webfonts/fa-brands-400.woff2 +0 -0
  21. package/fontawesome/webfonts/fa-regular-400.ttf +0 -0
  22. package/fontawesome/webfonts/fa-regular-400.woff +0 -0
  23. package/fontawesome/webfonts/fa-regular-400.woff2 +0 -0
  24. package/fontawesome/webfonts/fa-solid-900.ttf +0 -0
  25. package/fontawesome/webfonts/fa-solid-900.woff +0 -0
  26. package/fontawesome/webfonts/fa-solid-900.woff2 +0 -0
  27. package/help.pdf +0 -0
  28. package/i/sort_handle.png +0 -0
  29. package/index.html +68 -0
  30. package/index.js +83 -0
  31. package/jest.config.js +4 -0
  32. package/js/Genoverse.js +1681 -0
  33. package/js/Track/Controller/Sequence.js +17 -0
  34. package/js/Track/Controller/Stranded.js +73 -0
  35. package/js/Track/Controller.js +620 -0
  36. package/js/Track/Model/File/BAM.js +44 -0
  37. package/js/Track/Model/File/BED.js +116 -0
  38. package/js/Track/Model/File/GFF.js +40 -0
  39. package/js/Track/Model/File/VCF.js +101 -0
  40. package/js/Track/Model/File/WIG.js +67 -0
  41. package/js/Track/Model/File.js +36 -0
  42. package/js/Track/Model/Gene/Ensembl.js +22 -0
  43. package/js/Track/Model/Gene.js +5 -0
  44. package/js/Track/Model/Sequence/Ensembl.js +4 -0
  45. package/js/Track/Model/Sequence/Fasta.js +60 -0
  46. package/js/Track/Model/Sequence.js +50 -0
  47. package/js/Track/Model/SequenceVariation.js +41 -0
  48. package/js/Track/Model/Stranded.js +28 -0
  49. package/js/Track/Model/Transcript/Ensembl.js +67 -0
  50. package/js/Track/Model/Transcript.js +5 -0
  51. package/js/Track/Model.js +303 -0
  52. package/js/Track/View/Gene/Ensembl.js +46 -0
  53. package/js/Track/View/Gene.js +6 -0
  54. package/js/Track/View/Sequence/Variation.js +115 -0
  55. package/js/Track/View/Sequence.js +63 -0
  56. package/js/Track/View/Transcript/Ensembl.js +12 -0
  57. package/js/Track/View/Transcript.js +28 -0
  58. package/js/Track/View.js +566 -0
  59. package/js/Track/library/Chromosome.js +145 -0
  60. package/js/Track/library/File/BAM.js +30 -0
  61. package/js/Track/library/File/BED.js +24 -0
  62. package/js/Track/library/File/BIGBED.js +47 -0
  63. package/js/Track/library/File/BIGWIG.js +52 -0
  64. package/js/Track/library/File/GFF.js +9 -0
  65. package/js/Track/library/File/VCF.js +71 -0
  66. package/js/Track/library/File/WIG.js +5 -0
  67. package/js/Track/library/File.js +10 -0
  68. package/js/Track/library/Gene.js +37 -0
  69. package/js/Track/library/Graph/Bar.js +235 -0
  70. package/js/Track/library/Graph/Line.js +296 -0
  71. package/js/Track/library/Graph.js +355 -0
  72. package/js/Track/library/HighlightRegion.js +292 -0
  73. package/js/Track/library/Legend.js +224 -0
  74. package/js/Track/library/Scalebar.js +227 -0
  75. package/js/Track/library/Scaleline.js +91 -0
  76. package/js/Track/library/Static.js +78 -0
  77. package/js/Track/library/dbSNP.js +142 -0
  78. package/js/Track.js +632 -0
  79. package/js/genomes/grch37.js +990 -0
  80. package/js/genomes/grch38.js +990 -0
  81. package/js/genoverse.min.js +2 -0
  82. package/js/genoverse.min.js.map +1 -0
  83. package/js/lib/BWReader.js +578 -0
  84. package/js/lib/Base.js +145 -0
  85. package/js/lib/VCFReader.js +286 -0
  86. package/js/lib/dalliance/js/bam.js +494 -0
  87. package/js/lib/dalliance/js/bin.js +185 -0
  88. package/js/lib/dalliance/js/das.js +749 -0
  89. package/js/lib/dalliance/js/utils.js +370 -0
  90. package/js/lib/dalliance-lib.js +3594 -0
  91. package/js/lib/dalliance-lib.min.js +68 -0
  92. package/js/lib/jDataView.js +2 -0
  93. package/js/lib/jParser.js +192 -0
  94. package/js/lib/jquery-ui.js +8 -0
  95. package/js/lib/jquery.js +2 -0
  96. package/js/lib/jquery.mousehold.js +53 -0
  97. package/js/lib/jquery.mousewheel.js +84 -0
  98. package/js/lib/jquery.tipsy.js +258 -0
  99. package/js/lib/rtree.js +1 -0
  100. package/js/plugins/controlPanel.js +395 -0
  101. package/js/plugins/fileDrop.js +62 -0
  102. package/js/plugins/focusRegion.js +12 -0
  103. package/js/plugins/fullscreen.js +77 -0
  104. package/js/plugins/karyotype.js +210 -0
  105. package/js/plugins/resizer.js +45 -0
  106. package/js/plugins/tooltips.js +94 -0
  107. package/js/plugins/trackControls.js +143 -0
  108. package/package.json +43 -0
  109. package/test/View/__snapshots__/render-bar-graph.test.js.snap +111 -0
  110. package/test/View/__snapshots__/render-blocks.test.js.snap +105 -0
  111. package/test/View/__snapshots__/render-chromosome.test.js.snap +5 -0
  112. package/test/View/__snapshots__/render-highlights.test.js.snap +73 -0
  113. package/test/View/__snapshots__/render-insert-variants.test.js.snap +9 -0
  114. package/test/View/__snapshots__/render-labels.test.js.snap +241 -0
  115. package/test/View/__snapshots__/render-legends.test.js.snap +13 -0
  116. package/test/View/__snapshots__/render-line-graph.test.js.snap +349 -0
  117. package/test/View/__snapshots__/render-scalebar.test.js.snap +49 -0
  118. package/test/View/__snapshots__/render-scaleline.test.js.snap +31 -0
  119. package/test/View/__snapshots__/render-sequence.test.js.snap +23 -0
  120. package/test/View/__snapshots__/render-stranded.test.js.snap +5 -0
  121. package/test/View/__snapshots__/render-transcripts.test.js.snap +193 -0
  122. package/test/View/render-bar-graph.test.js +87 -0
  123. package/test/View/render-blocks.test.js +171 -0
  124. package/test/View/render-chromosome.test.js +40 -0
  125. package/test/View/render-highlights.test.js +67 -0
  126. package/test/View/render-insert-variants.test.js +11 -0
  127. package/test/View/render-labels.test.js +266 -0
  128. package/test/View/render-legends.test.js +31 -0
  129. package/test/View/render-line-graph.test.js +169 -0
  130. package/test/View/render-scalebar.test.js +36 -0
  131. package/test/View/render-scaleline.test.js +28 -0
  132. package/test/View/render-sequence.test.js +49 -0
  133. package/test/View/render-stranded.test.js +10 -0
  134. package/test/View/render-transcripts.test.js +165 -0
  135. package/test/create-and-destroy.test.js +63 -0
  136. package/test/track-ordering.test.js +514 -0
  137. package/test/track_config/__snapshots__/config-settings.test.js.snap +23 -0
  138. package/test/track_config/config-settings.test.js +321 -0
  139. package/test/track_config/zoom-level-settings.test.js +98 -0
  140. package/test/utils.js +80 -0
  141. package/utils/createGenome.js +52 -0
  142. package/utils/devServer.js +36 -0
  143. package/utils/expandedTemplate.html +46 -0
  144. package/utils/git-hooks/post-commit +9 -0
  145. package/utils/git-hooks/pre-commit +7 -0
  146. package/utils/git-hooks/setup +6 -0
  147. package/utils/makeExpanded.js +19 -0
  148. package/webpack.config.js +39 -0
@@ -0,0 +1,514 @@
1
+ const { Genoverse, afterTest } = require('./utils');
2
+
3
+ // TODO: unsortable, particularly with unsortable order=9e99, then adding another track
4
+
5
+ describe('Track ordering', () => {
6
+ afterAll(afterTest);
7
+
8
+ // Want saveable to be able to run resetConfig, but don't actually want to be able to save anything
9
+ window.sessionStorage = {
10
+ setItem : () => {},
11
+ getItem : () => {},
12
+ removeItem : () => {},
13
+ };
14
+
15
+ const newGenoverse = (tracks) => {
16
+ const g = new Genoverse({
17
+ start : 1,
18
+ end : 1,
19
+ chromosomeSize : 1,
20
+ isStatic : true,
21
+ saveable : true,
22
+ tracks : tracks.map(t => Genoverse.Track.extend({ url: false, ...t })),
23
+ _initDeferred : $.Deferred(),
24
+ saveConfig : () => {},
25
+ loadGenome : () => {},
26
+ loadPlugins : () => {},
27
+ });
28
+
29
+ setTimeout(g._initDeferred.resolve, 1);
30
+
31
+ return g;
32
+ };
33
+
34
+ const doTest = (...args) => {
35
+ const [ g, expected ] = args;
36
+
37
+ let [ , , addTracks, after ] = args;
38
+
39
+ const msg = args.length > 2 && typeof args[args.length - 1] === 'string' ? args[args.length - 1] : '';
40
+ const deferred = $.Deferred();
41
+ const genoverse = g instanceof Genoverse ? g : newGenoverse(g);
42
+
43
+ if (addTracks === msg) addTracks = undefined;
44
+ if (after === msg) after = undefined;
45
+
46
+ genoverse._initDeferred.done(() => {
47
+ if (Array.isArray(addTracks)) {
48
+ genoverse.addTracks(addTracks.map(t => Genoverse.Track.extend({ url: false, ...t })), after);
49
+ } else if (addTracks) {
50
+ genoverse.addTrack(Genoverse.Track.extend({ url: false, ...addTracks }), after);
51
+ }
52
+
53
+ setTimeout(() => {
54
+ const orderedIds = genoverse.tracks.map(t => t.id).join(' ');
55
+
56
+ if (addTracks) {
57
+ addTracks = [].concat(addTracks);
58
+ genoverse.removeTracks(addTracks.map(t => genoverse.tracksById[t.id]));
59
+ }
60
+
61
+ expect(orderedIds).toBe(expected); // Test must be after removing tracks, since if the test fails, nothing else executes
62
+
63
+ deferred.resolve();
64
+ }, 1);
65
+ });
66
+
67
+ return deferred;
68
+ };
69
+
70
+ const resetConfig = (g, reorder, expected) => {
71
+ let order = 0;
72
+
73
+ const newId = reorder.length + 1;
74
+ const deferred = $.Deferred();
75
+ const genoverse = newGenoverse(g);
76
+
77
+ genoverse._initDeferred.done(() => {
78
+ reorder.forEach((i) => { genoverse.tracksById[i].order = order++; });
79
+
80
+ genoverse.addTrack(Genoverse.Track.extend({ id: newId }));
81
+
82
+ setTimeout($.Deferred().done(() => {
83
+ doTest(genoverse, reorder.concat(newId).join(' ')).done(() => {
84
+ genoverse.resetConfig();
85
+
86
+ setTimeout($.Deferred().done(() => {
87
+ doTest(genoverse, expected).done(() => { deferred.resolve(); });
88
+ }).resolve, 1);
89
+ });
90
+ }).resolve, 1);
91
+ });
92
+
93
+ return deferred;
94
+ };
95
+
96
+ const moveTrack = (genoverse, id, afterId) => {
97
+ const track = genoverse.tracksById[id];
98
+
99
+ if (afterId) {
100
+ track.prop('label').insertAfter(genoverse.tracksById[afterId].prop('label'));
101
+ } else {
102
+ track.prop('label').prependTo(genoverse.labelContainer);
103
+ }
104
+
105
+ genoverse.updateTrackOrder({}, { item: track.prop('label') });
106
+ };
107
+
108
+ const legendTrack = (id, legendConf) => ({
109
+ id : id,
110
+ legend : legendConf ? Genoverse.Track.Legend.extend(legendConf) : true,
111
+ });
112
+
113
+ describe('Simple tracks', () => {
114
+ describe('Without explicit order', () => {
115
+ const tracks = [{ id: 1 }, { id: 2 }, { id: 3 }];
116
+
117
+ it('initial track order', () => doTest(tracks, '1 2 3'));
118
+
119
+ describe('After adding a track', () => {
120
+ it('without an after argument', () => doTest(tracks, '1 2 3 4', { id: 4 }));
121
+ it('with an after argument', () => doTest(tracks, '1 2 4 3', { id: 4 }, 2));
122
+ });
123
+
124
+ describe('After adding multiple tracks', () => {
125
+ it('without an after argument', () => doTest(tracks, '1 2 3 4 5 6', [{ id: 4 }, { id: 5 }, { id: 6 }]));
126
+ it('with an after argument', () => doTest(tracks, '1 4 5 6 2 3', [{ id: 4 }, { id: 5 }, { id: 6 }], 1));
127
+ });
128
+
129
+ describe('After reset config', () => {
130
+ it('initial track order restored', () => resetConfig(tracks, [ 2, 3, 1 ], '1 2 3'));
131
+ });
132
+ });
133
+
134
+ describe('With explicit order', () => {
135
+ const tracks = [
136
+ { id: 1 },
137
+ { id: 2, order: 3 },
138
+ { id: 3, order: 2 },
139
+ { id: 4, order: 9e99 },
140
+ { id: 5 },
141
+ { id: 6, order: -1 },
142
+ ];
143
+
144
+ it('initial track order', () => doTest(tracks, '6 1 3 2 5 4'));
145
+
146
+ describe('After adding a track', () => {
147
+ it('without an after argument', () => doTest(tracks, '6 1 3 2 5 4 7', { id: 7 }));
148
+ it('without an after argument, with track.order', () => doTest(tracks, '6 1 3 2 7 5 4', { id: 7, order: 3 })); // order after initialization is used as a 0-based index, with the track being inserted after existing track [order + 1]
149
+ it('with an after argument', () => doTest(tracks, '6 1 3 7 2 5 4', { id: 7 }, 3));
150
+ it('with an after argument and track.order', () => doTest(tracks, '6 1 3 2 5 7 4', { id: 7, order: 4 }, 2, 'Track order should take precedence over after argument'));
151
+ });
152
+
153
+ describe('After adding multiple tracks', () => {
154
+ it('without an after argument', () => doTest(tracks, '6 1 3 2 5 4 7 8', [{ id: 7 }, { id: 8 }]));
155
+ it('without an after argument, with track.order', () => doTest(tracks, '6 1 3 8 2 5 7 4', [{ id: 7, order: 4 }, { id: 8, order: 2 }]));
156
+ it('with an after argument', () => doTest(tracks, '6 1 3 2 7 8 5 4', [{ id: 7 }, { id: 8 }], 4));
157
+ it('with an after argument and track.order', () => doTest(tracks, '6 1 7 3 2 5 8 4', [{ id: 7, order: 1 }, { id: 8, order: 4 }], 2, 'Track order should take precedence over after argument'));
158
+ });
159
+
160
+ describe('After reset config', () => {
161
+ it('initial track order restored', () => resetConfig(tracks, [ 4, 2, 5, 1, 3, 6 ], '6 1 3 2 5 4'));
162
+ });
163
+ });
164
+ });
165
+
166
+ describe('Tracks with legends', () => {
167
+ describe('Legend locked to track', () => {
168
+ describe('Legend unsortable', () => {
169
+ const tracks = [{ id: 1 }, legendTrack(2), { id: 3 }];
170
+
171
+ it('initial track order', () => doTest(tracks, '1 2 2Legend 3'));
172
+
173
+ describe('After adding a track', () => {
174
+ it('before the track with the legend', () => doTest(tracks, '1 4 2 2Legend 3', { id: 4 }, 1));
175
+ it('between the track and its legend', () => doTest(tracks, '1 2 2Legend 4 3', { id: 4 }, 2, 'The legend is locked to its track, so adding between 2 and 2Legend is impossible'));
176
+ it('after the legend', () => doTest(tracks, '1 2 2Legend 4 3', { id: 4 }, 3));
177
+ it('with a legend', () => doTest(tracks, '1 2 2Legend 4 4Legend 3', legendTrack(4), 3));
178
+ });
179
+
180
+ describe('After adding multiple tracks', () => {
181
+ it('before the track with the legend', () => doTest(tracks, '1 4 5 2 2Legend 3', [{ id: 4 }, { id: 5 }], 1));
182
+ it('between the track and its legend', () => doTest(tracks, '1 2 2Legend 4 5 3', [{ id: 4 }, { id: 5 }], 2, 'The legend is locked to its track, so adding between 2 and 2Legend is impossible'));
183
+ it('after the legend', () => doTest(tracks, '1 2 2Legend 4 5 3', [{ id: 4 }, { id: 5 }], 3));
184
+ it('with legends', () => doTest(tracks, '1 2 2Legend 4 4Legend 5 5Legend 3', [ legendTrack(4), legendTrack(5) ], 3)); // FIXME track 5 gets added before track 4
185
+ });
186
+
187
+ describe('After sorting tracks', () => {
188
+ it('moving the track with the legend', () => {
189
+ const genoverse = newGenoverse.call(this, tracks);
190
+ const deferred = $.Deferred();
191
+
192
+ genoverse._initDeferred.done(() => {
193
+ moveTrack(genoverse, 3, 2);
194
+
195
+ doTest(genoverse, '1 2 2Legend 3', 'The legend is locked to its track, so moving a track between 2 and 2Legend is impossible').done(() => {
196
+ moveTrack(genoverse, 2);
197
+
198
+ doTest(genoverse, '2 2Legend 1 3', 'The legend should still be after its track').done(() => {
199
+ doTest(genoverse, '2 2Legend 4 1 3', { id: 4 }, 1, 'Adding a new track between 2 and 2Legend should still be impossible').done(deferred.resolve);
200
+ });
201
+ });
202
+ });
203
+
204
+ return deferred;
205
+ });
206
+
207
+ it('moving the legend', () => {
208
+ const genoverse = newGenoverse.call(this, tracks);
209
+ const deferred = $.Deferred();
210
+
211
+ genoverse._initDeferred.done(() => {
212
+ moveTrack(genoverse, 3, 2);
213
+
214
+ doTest(genoverse, '1 2 2Legend 3', 'The legend is locked to its track, so moving a track between 2 and 2Legend is impossible').done(() => {
215
+ moveTrack(genoverse, '2Legend', 3);
216
+
217
+ doTest(genoverse, '1 2 2Legend 3', 'Trying to move an unsortable track should have no effect').done(() => {
218
+ doTest(genoverse, '1 2 2Legend 4 3', { id: 4 }, 2, 'Adding a new track between 2 and 2Legend should still be impossible').done(deferred.resolve);
219
+ });
220
+ });
221
+ });
222
+
223
+ return deferred;
224
+ });
225
+ });
226
+
227
+ describe('After reset config', () => {
228
+ it('initial track order restored', () => resetConfig(tracks, [ 3, 1, 2, '2Legend' ], '1 2 2Legend 3'));
229
+ });
230
+
231
+ describe('Legend with order', () => {
232
+ it('initial track order', () => doTest([{ id: 1 }, legendTrack(2, { order: 9e99 }), { id: 3 }], '1 2 2Legend 3', 'Legend order property should be ignored'));
233
+ });
234
+ });
235
+
236
+ describe('Legend sortable', () => {
237
+ const tracks = [{ id: 1 }, legendTrack(2, { unsortable: false }), { id: 3 }];
238
+
239
+ it('initial track order', () => doTest(tracks, '1 2 2Legend 3'));
240
+
241
+ describe('After adding a track', () => {
242
+ it('before the track with the legend', () => doTest(tracks, '1 4 2 2Legend 3', { id: 4 }, 1));
243
+ it('between the track and its legend', () => doTest(tracks, '1 2 2Legend 4 3', { id: 4 }, 2, 'The legend is locked to its track, so adding between 2 and 2Legend is impossible'));
244
+ it('after the legend', () => doTest(tracks, '1 2 2Legend 4 3', { id: 4 }, 3));
245
+ });
246
+
247
+ describe('After adding multiple tracks', () => {
248
+ it('before the track with the legend', () => doTest(tracks, '1 4 5 2 2Legend 3', [{ id: 4 }, { id: 5 }], 1));
249
+ it('between the track and its legend', () => doTest(tracks, '1 2 2Legend 4 5 3', [{ id: 4 }, { id: 5 }], 2, 'The legend is locked to its track, so adding between 2 and 2Legend is impossible'));
250
+ it('after the legend', () => doTest(tracks, '1 2 2Legend 4 5 3', [{ id: 4 }, { id: 5 }], 3));
251
+ });
252
+
253
+ describe('After sorting tracks', () => {
254
+ it('moving the track with the legend', () => {
255
+ const genoverse = newGenoverse.call(this, tracks);
256
+ const deferred = $.Deferred();
257
+
258
+ genoverse._initDeferred.done(() => {
259
+ moveTrack(genoverse, 3, 2);
260
+
261
+ doTest(genoverse, '1 2 2Legend 3', 'The legend is locked to its track, so moving a track between 2 and 2Legend is impossible').done(() => {
262
+ moveTrack(genoverse, 2);
263
+
264
+ doTest(genoverse, '2 1 2Legend 3', 'Once the track has been moved, its legend is no longer locked to it, and should be unaffected').done(() => {
265
+ doTest(genoverse, '2 1 4 2Legend 3', { id: 4 }, 2, 'Adding a new track between 2 and 2Legend should now be possible').done(deferred.resolve);
266
+ });
267
+ });
268
+ });
269
+
270
+ return deferred;
271
+ });
272
+
273
+ it('moving the legend', () => {
274
+ const genoverse = newGenoverse.call(this, tracks);
275
+ const deferred = $.Deferred();
276
+
277
+ genoverse._initDeferred.done(() => {
278
+ moveTrack(genoverse, 3, 2);
279
+
280
+ doTest(genoverse, '1 2 2Legend 3', 'The legend is locked to its track, so moving a track between 2 and 2Legend is impossible').done(() => {
281
+ moveTrack(genoverse, '2Legend', 3);
282
+
283
+ doTest(genoverse, '1 2 3 2Legend', 'The legend should be movable').done(() => {
284
+ moveTrack(genoverse, 2);
285
+
286
+ doTest(genoverse, '2 1 3 2Legend', 'Once the legend has been moved, it is no longer locked to its track, and should be unaffected by moving its track').done(() => {
287
+ doTest(genoverse, '2 1 4 3 2Legend', { id: 4 }, 2, 'Adding a new track between 2 and 2Legend should now be possible').done(deferred.resolve);
288
+ });
289
+ });
290
+ });
291
+ });
292
+
293
+ return deferred;
294
+ });
295
+ });
296
+
297
+ describe('After reset config', () => {
298
+ it('initial track order restored', () => resetConfig(tracks, [ 3, 1, 2, '2Legend' ], '1 2 2Legend 3'));
299
+ });
300
+
301
+ describe('Legend with order', () => {
302
+ it('initial track order', () => doTest([{ id: 1 }, legendTrack(2, { unsortable: false, order: 9e99 }), { id: 3 }], '1 2 2Legend 3', 'Legend order property should be ignored'));
303
+ });
304
+ });
305
+ });
306
+
307
+ describe('Legend not locked to track', () => {
308
+ describe('Legend unsortable', () => {
309
+ const tracks = [{ id: 1 }, legendTrack(2, { lockToTrack: false }), { id: 3 }];
310
+
311
+ it('initial track order', () => doTest(tracks, '1 2 3 2Legend'));
312
+
313
+ describe('After adding a track', () => {
314
+ it('before the track with the legend', () => doTest(tracks, '1 4 2 3 2Legend', { id: 4 }, 1));
315
+ it('between the track and its legend', () => doTest(tracks, '1 2 4 3 2Legend', { id: 4 }, 2));
316
+ it('after the legend', () => doTest(tracks, '1 2 3 2Legend 4', { id: 4 }, 4));
317
+
318
+ it('with an ordered legend', () => doTest(tracks, '4Legend 1 2 3 4 2Legend', legendTrack(4, { lockToTrack: false, order: -1 }), 3));
319
+ });
320
+
321
+ describe('After adding multiple tracks', () => {
322
+ it('before the track with the legend', () => doTest(tracks, '1 4 5 2 3 2Legend', [{ id: 4 }, { id: 5 }], 1));
323
+ it('between the track and its legend', () => doTest(tracks, '1 2 4 5 3 2Legend', [{ id: 4 }, { id: 5 }], 2));
324
+ it('after the legend', () => doTest(tracks, '1 2 3 2Legend 4 5', [{ id: 4 }, { id: 5 }], 4));
325
+
326
+ it('with ordered legends', () => doTest(tracks, '4Legend 1 2 4 5 3 2Legend 5Legend', [
327
+ legendTrack(4, { lockToTrack: false, order: -1 }),
328
+ legendTrack(5, { lockToTrack: false, order: 9e99 }),
329
+ ], 2, 'New tracks should be added between 2Legend and 3, new legends at the start and end'));
330
+ });
331
+
332
+ describe('After sorting tracks', () => {
333
+ it('moving the track with the legend', () => {
334
+ const genoverse = newGenoverse.call(this, tracks);
335
+ const deferred = $.Deferred();
336
+
337
+ genoverse._initDeferred.done(() => {
338
+ moveTrack(genoverse, 1, 2);
339
+
340
+ doTest(genoverse, '2 1 3 2Legend', 'The legend is not locked to its track, so moving a track between 2 and 2Legend is possible').done(() => {
341
+ moveTrack(genoverse, 2, 1);
342
+
343
+ doTest(genoverse, '1 2 3 2Legend', 'The legend should be unaffected by moving its track').done(() => {
344
+ doTest(genoverse, '1 2 4 3 2Legend', { id: 4 }, 2, 'Adding a new track between 2 and 2Legend should be possible').done(deferred.resolve);
345
+ });
346
+ });
347
+ });
348
+
349
+ return deferred;
350
+ });
351
+
352
+ it('moving the legend', () => {
353
+ const genoverse = newGenoverse.call(this, tracks);
354
+ const deferred = $.Deferred();
355
+
356
+ genoverse._initDeferred.done(() => {
357
+ moveTrack(genoverse, 1, 2);
358
+
359
+ doTest(genoverse, '2 1 3 2Legend', 'The legend is not locked to its track, so moving a track between 2 and 2Legend is possible').done(() => {
360
+ moveTrack(genoverse, '2Legend', 1);
361
+
362
+ doTest(genoverse, '2 1 3 2Legend', 'Trying to move an unsortable track should have no effect').done(() => {
363
+ doTest(genoverse, '2 4 1 3 2Legend', { id: 4 }, 1, 'Adding a new track between 2 and 2Legend should be possible').done(deferred.resolve);
364
+ });
365
+ });
366
+ });
367
+
368
+ return deferred;
369
+ });
370
+ });
371
+
372
+ describe('After reset config', () => {
373
+ it('initial track order restored', () => resetConfig(tracks, [ 3, '2Legend', 1, 2 ], '1 2 3 2Legend'));
374
+ });
375
+
376
+ describe('Legend with order', () => {
377
+ it('initial track order', () => doTest([{ id: 1 }, legendTrack(2, { lockToTrack: false, order: -1 }), { id: 3 }], '2Legend 1 2 3', 'Legend should be at the start'));
378
+ });
379
+ });
380
+
381
+ describe('Legend sortable', () => {
382
+ const tracks = [{ id: 1 }, legendTrack(2, { lockToTrack: false, unsortable: false }), { id: 3 }];
383
+
384
+ it('initial track order', () => doTest(tracks, '1 2 3 2Legend'));
385
+
386
+ describe('After adding a track', () => {
387
+ it('before the track with the legend', () => doTest(tracks, '1 4 2 3 2Legend', { id: 4 }, 1));
388
+ it('between the track and its legend', () => doTest(tracks, '1 2 4 3 2Legend', { id: 4 }, 2));
389
+ it('after the legend', () => doTest(tracks, '1 2 3 2Legend 4', { id: 4 }, 4));
390
+ });
391
+
392
+ describe('After adding multiple tracks', () => {
393
+ it('before the track with the legend', () => doTest(tracks, '1 4 5 2 3 2Legend', [{ id: 4 }, { id: 5 }], 1));
394
+ it('between the track and its legend', () => doTest(tracks, '1 2 4 5 3 2Legend', [{ id: 4 }, { id: 5 }], 2));
395
+ it('after the legend', () => doTest(tracks, '1 2 3 2Legend 4 5', [{ id: 4 }, { id: 5 }], 4));
396
+ });
397
+
398
+ describe('After sorting tracks', () => {
399
+ it('moving the track with the legend', () => {
400
+ const genoverse = newGenoverse.call(this, tracks);
401
+ const deferred = $.Deferred();
402
+
403
+ genoverse._initDeferred.done(() => {
404
+ moveTrack(genoverse, 1, 2);
405
+
406
+ doTest(genoverse, '2 1 3 2Legend', 'The legend is not locked to its track, so moving a track between 2 and 2Legend is possible').done(() => {
407
+ moveTrack(genoverse, 2, 1);
408
+
409
+ doTest(genoverse, '1 2 3 2Legend', 'The legend should be unaffected by moving its track').done(() => {
410
+ doTest(genoverse, '1 2 4 3 2Legend', { id: 4 }, 2, 'Adding a new track between 2 and 2Legend should be possible').done(deferred.resolve);
411
+ });
412
+ });
413
+ });
414
+
415
+ return deferred;
416
+ });
417
+
418
+ it('moving the legend', () => {
419
+ const genoverse = newGenoverse.call(this, tracks);
420
+ const deferred = $.Deferred();
421
+
422
+ genoverse._initDeferred.done(() => {
423
+ moveTrack(genoverse, 1, 2);
424
+
425
+ doTest(genoverse, '2 1 3 2Legend', 'The legend is not locked to its track, so moving a track between 2 and 2Legend is possible').done(() => {
426
+ moveTrack(genoverse, '2Legend', 1);
427
+
428
+ doTest(genoverse, '2 1 2Legend 3', 'Legend should be between 1 and 3').done(() => {
429
+ doTest(genoverse, '2 4 1 2Legend 3', { id: 4 }, 1, 'Adding a new track between 2 and 2Legend should be possible').done(deferred.resolve);
430
+ });
431
+ });
432
+ });
433
+
434
+ return deferred;
435
+ });
436
+ });
437
+
438
+ describe('After reset config', () => {
439
+ it('initial track order restored', () => resetConfig(tracks, [ 3, '2Legend', 1, 2 ], '1 2 3 2Legend'));
440
+ });
441
+
442
+ describe('Legend with order', () => {
443
+ it('initial track order', () => doTest([{ id: 1 }, legendTrack(2, { lockToTrack: false, unsortable: false, order: -1 }), { id: 3 }], '2Legend 1 2 3', 'Legend should be at the start'));
444
+ });
445
+ });
446
+ });
447
+ });
448
+
449
+ describe('Stranded tracks', () => {
450
+ describe('Without explicit order', () => {
451
+ const tracks = [{ id: 1 }, { id: 2, stranded: true }, { id: 3 }];
452
+
453
+ it('initial track order', () => doTest(tracks, '1 2 2Reverse 3'));
454
+
455
+ describe('After adding a track', () => {
456
+ it('without an after argument', () => doTest(tracks, '1 2 2Reverse 3 4 4Reverse', { id: 4, stranded: true }));
457
+ it('with an after argument', () => doTest(tracks, '1 2 4 4Reverse 2Reverse 3', { id: 4, stranded: true }, 2));
458
+ });
459
+
460
+ describe('After adding multiple tracks', () => {
461
+ it('without an after argument', () => doTest(tracks, '1 2 2Reverse 3 4 4Reverse 5 5Reverse', [{ id: 4, stranded: true }, { id: 5, stranded: true }]));
462
+ it('with an after argument', () => doTest(tracks, '1 2 4 4Reverse 5 5Reverse 2Reverse 3', [{ id: 4, stranded: true }, { id: 5, stranded: true }], 2));
463
+ });
464
+
465
+ describe('After reset config', () => {
466
+ it('initial track order restored', () => resetConfig(tracks, [ 2, 3, 1, '2Reverse' ], '1 2 2Reverse 3'));
467
+ });
468
+ });
469
+
470
+ describe('With explicit order', () => {
471
+ const tracks = [{ id: 1 }, { id: 2, stranded: true, order: -1 }, { id: 3 }];
472
+
473
+ it('initial track order', () => doTest(tracks, '2 2Reverse 1 3'));
474
+
475
+ describe('After adding a track', () => {
476
+ it('without an after argument', () => doTest(tracks, '2 2Reverse 1 4 4Reverse 3', { id: 4, stranded: true, order: 2 }));
477
+ it('with an after argument', () => doTest(tracks, '2 2Reverse 1 4 4Reverse 3', { id: 4, stranded: true, order: 2 }, 1, 'Track order should take precedence over after argument'));
478
+ });
479
+
480
+ describe('After adding multiple tracks', () => {
481
+ const add = [{ id: 4, stranded: true, order: 2 }, { id: 5, stranded: true, order: -1 }];
482
+
483
+ it('without an after argument', () => doTest(tracks, '5 5Reverse 2 2Reverse 1 4 4Reverse 3', add));
484
+ it('with an after argument', () => doTest(tracks, '5 5Reverse 2 2Reverse 1 4 4Reverse 3', add, 1, 'Track order should take precedence over after argument'));
485
+ });
486
+
487
+ describe('After reset config', () => {
488
+ it('initial track order restored', () => resetConfig(tracks, [ 3, 2, 1, '2Reverse' ], '2 2Reverse 1 3'));
489
+ });
490
+ });
491
+
492
+ describe('With explicit order and orderReverse', () => {
493
+ const tracks = [{ id: 1 }, { id: 2, stranded: true, order: -1, orderReverse: 9e99 }, { id: 3 }];
494
+
495
+ it('initial track order', () => doTest(tracks, '2 1 3 2Reverse'));
496
+
497
+ describe('After adding a track', () => {
498
+ it('without an after argument', () => doTest(tracks, '2 1 4Reverse 3 4 2Reverse', { id: 4, stranded: true, order: 2, orderReverse: 1 }));
499
+ it('with an after argument', () => doTest(tracks, '2 1 4Reverse 3 4 2Reverse', { id: 4, stranded: true, order: 2, orderReverse: 1 }, 1, 'Track order should take precedence over after argument'));
500
+ });
501
+
502
+ describe('After adding multiple tracks', () => {
503
+ const add = [{ id: 4, stranded: true, order: 2, orderReverse: 9e99 }, { id: 5, stranded: true, order: -1, orderReverse: 1 }];
504
+
505
+ it('without an after argument', () => doTest(tracks, '5 2 5Reverse 1 3 4 2Reverse 4Reverse', add));
506
+ it('with an after argument', () => doTest(tracks, '5 2 5Reverse 1 3 4 2Reverse 4Reverse', add, 1, 'Track order should take precedence over after argument'));
507
+ });
508
+
509
+ describe('After reset config', () => {
510
+ it('initial track order restored', () => resetConfig(tracks, [ 3, 2, 1, '2Reverse' ], '2 1 3 2Reverse'));
511
+ });
512
+ });
513
+ });
514
+ });
@@ -0,0 +1,23 @@
1
+ // Jest Snapshot v1, https://goo.gl/fbAQLP
2
+
3
+ exports[`Config settings Features are drawn correctly when squish = false, colorscheme = green 1`] = `"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGQAAAAaCAYAAABByvnlAAAABmJLR0QA/wD/AP+gvaeTAAABKUlEQVRoge3XvStFYRwH8M+9rnQnYfM2sMhqsjL6T9hMBvEkxUTKzCQyYTKYMPgLZJHBxGAQ6UoYvFwlZdA5N+f3Gc/z1PPtfHtOv0MI4WelvANkLnn55b5c3k05j0PDz6KQBhOFNJgopMFEISGEEMI/UcQ/9QoecfH+5F7ZhBlH5vV4so4B1LAsWc0yXlGnrJqkX9KPGc8Wv6zNSboxjCnJYJbBilpIXUkVN2DapeQQJNc4Q2eWcSpZHtZAWiTnaPaiFaPfdrzdjD6cZBmsqDfk45PVizFs2Nb0ubqgDZsYl9xlGayohdQlx+hwqgssqarZwYpkP+s4UcicITRrdyWpuLWlZF+ylkecoo+9ZTx4m6b2JCM4UB+JKZk0azePqCGEEEII4a+8Ajr+OQqmnqEWAAAAAElFTkSuQmCC"`;
4
+
5
+ exports[`Config settings Features are drawn correctly when squish = true 1`] = `"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGQAAAAOCAYAAADZjbloAAAABmJLR0QA/wD/AP+gvaeTAAAAMUlEQVRYhe3QsQ0AIBACQHTy31xXMBa+xV1NAiHhK6N7wGuVWoe5lm9mRykAAAAAXNhqIQMEUroGNQAAAABJRU5ErkJggg=="`;
6
+
7
+ exports[`Config settings Features are drawn correctly when squish = true, colorscheme = red 1`] = `"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGQAAAAOCAYAAADZjbloAAAABmJLR0QA/wD/AP+gvaeTAAAAMklEQVRYhe3QsQ0AIAwDsJT/fy4vIAbKYM+REiXhKzU94LVO+iRXQ9+siVIAAAAAuLABJtwCBO+3j10AAAAASUVORK5CYII="`;
8
+
9
+ exports[`Config settings Features are drawn correctly when type = a, subtype = 1 1`] = `"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGQAAAAaCAYAAABByvnlAAAABmJLR0QA/wD/AP+gvaeTAAAA3UlEQVRoge3XIU4DQRQG4I/6Kg5ACCXBYzkAwVCBqeQAnAeDIpg9ARLDDXAQaCCpqidBgdht0hYQJDC7Yf/PzGR2xZ+8vLezRMT3NvD+g3fjjw3aDhCrUpCOSUE6JgXpmBQkIiLiHxqr/9r31s6vMMdd8UQ9tHzLmuC2WZdd4KhYogBDzLCL+y+ej6RDilh0yDGu8aAeT/utJeq5RUEmqJp95fPYioI28YopHvGMF6vfl4ysQgY4wSW2sYMtPOGgxVy9doPDtbMznDf7St0xb+oOOi0XLSIiIiLiN3wASXQc9dTYvxkAAAAASUVORK5CYII="`;
10
+
11
+ exports[`Config settings Features are drawn correctly when type = a, subtype = 2 1`] = `"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGQAAAAaCAYAAABByvnlAAAABmJLR0QA/wD/AP+gvaeTAAABDklEQVRoge3XLUsEURiG4Xs1CRYRbFsMIlvtBlGwrb/BYnG71W7Xv2CwWYQFFYvVJoKIotFq9DbsiOsufgR3Z2SeCwYO7xzmPPBy5nAgIr7W+PtP6i+XHsHa/99E2QHiszSkYtKQiklDKiYNiYiIiJ+40bu1u9hXa4Jd8BG8BbfLy1c7HoIX4G5frQkuF+O5ojGtcvLVitPgE7gAXn8zrwuuji9X9Y3qHtIGTqBxAzyDS8NTbAHzwOWIMsQHj8G1YtwB9wbez4BX4Pr4s9WOs+ALeFcc3PfgA1jsRqfAc3Cz3Jy14RZ4MFA76x3mToJH4E452WrJ0+FfkR1wH1wBX4ud8/60y8kZEREREfXxBqGPXOs0NnobAAAAAElFTkSuQmCC"`;
12
+
13
+ exports[`Config settings Features are drawn correctly when type = a, subtype = all 1`] = `"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGQAAAAaCAYAAABByvnlAAAABmJLR0QA/wD/AP+gvaeTAAABgUlEQVRoge3XMWsUQRgG4OdMJWgRAnZpREXSim0QsbC7tFdqExDT2/orkh8gmCtSixBIJI29jURCSDCV2EkgjZ/FzsFljcdtNuCx+R5YdnZ2eXeWj5llSCn9Ww/R4NkpxJR5vSnzrpcb/3sA6bwsyIzJgsyYLMiMyYKklFJKHbSi2rU/rPW/ww98aRYXK9WuPcbyYpHYJr4TB8TrViPuuCH28LbW/wSPNS/IkNgjxvJikVgu7TulMEuXHnGH3cYJ7mP/gvv3NCpI3CJOiAfE1wnPbRPPGo2040b7kD4+4JtqeXrUMrePj/T28ZO4IC+WcBefW76rU0YFGaiWLOU8aJk7wPvS3vw7L+bL/Vf0frV8V+cs4BSHOMARjp3fxTdYsmKBOCUOy4/7iDgmSl7cJD4RL6/uE7plFRu1vl0sj103KcgqUcuL3epnHnPEFvHm0qO9BnbwvNa3hvXSHqpmzJlqBr2YHBc7RC0v1oh14inxu8yc0dFv/wkppZRSSilN8gcDVXYqnpp7DQAAAABJRU5ErkJggg=="`;
14
+
15
+ exports[`Config settings Features are drawn correctly when type = all, subtype = 1 1`] = `"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGQAAAAaCAYAAABByvnlAAAABmJLR0QA/wD/AP+gvaeTAAABiElEQVRoge3Xv2vUYBjA8c8brxQHcaiboMhBQcGpq4s4CHXQwcH2uEFXd0dn/4hO2ggniG5utWBXd0HOgoNUBJ0E63CvQ3P2tBUV75Igz2dJ8ibDFx7yixDCryXkv7i2drn8s77Ua6Zv2oqmA8KPYiAtEwNpmRhIy8RAQgghhP/E5N/tNTzBWbyaWF/HZezgfH1pe/JzHe98xXa19NnI7dT3AnJZ9SU7abX+vmmb/MpawVa1nbSG5dqKDreberqppyu5K7n3/czImtx439SMB3IMF3DLwYFs4lOdUb9xVPJxfJD6NuVW9f2TTrW9imd4jQ9Ywsumog4xn0tDzMmOK1xqOmhWxnfICgbV/sDBu6Rp40fWKckVI2V+5EjTUbPQwQIu4hxG1VrCneq4VdKqrVxa8MVJvG26Z9oKXMd9nEEXp/HG3juldXJpCXNOeN90yywUuIGnP60/tv/YGmADixjiZm11++ZzaZhL27IHRvpp2S7kdQOFDdliLg3zw0b6QgghhBBCq30D6/ZWOtSjL1sAAAAASUVORK5CYII="`;
16
+
17
+ exports[`Config settings Features are drawn correctly when type = all, subtype = all, colorscheme = default 1`] = `"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGQAAAAaCAYAAABByvnlAAAABmJLR0QA/wD/AP+gvaeTAAAC2ElEQVRoge3XP4gcVQCA8d/b3BEOlGBOEIyJxG30wOqqgI2xEEwRC1Hujmu00mATLVKEy+M4SGwiASsJCpLF3FkY0ySCkJBcYWMbRDktIpIoKgQlroR9Fju7mbtjz9k/4Cnva2aYWb79dt+8mTdkMpneBKQ+PluBVNEXKvlSo1pfmKvWF8VKvihW/L2jpfZvfGmmN3lAthl5QLYZeUC2GXlAMplMJpP5n1B+G30Rn+IpfF06fg7P4xaerq5OJV8ofGkvPsSTaOJdwntbWq4Y86O/8H1x6A8tR8K865AaRV9wK8z+c18Ux1jvq6kdWbBwfcnS3nvureuL4pZ9o6a8yprBarEtcxYvDODu5VskPIYDOEaaquBqhjn1MKcuWBCc6p5pOSv13deMYj2KdSy0tE6Vzi1GsdsXxSp9I6MzIA/iGbxq8x94Fb/1p00PFL7X8Mr94+Em4Vqx/5P2THy0z+YJwa9d47yrUr99pSJhgrbvuOM3o3gNojho31CMFdvDuIRv8TOm8dUQ3sP4nPAN6RfSNGGDL03hCXxZwbczNaxhXLJLzXNDtMHOKK5hPEm72OwrZkbVvpHRmSEzWC72l22eJf0yg4+L/fObfemh4vwbhN8r+Dq3rH2CQ1oaacWOIfo6t6x9OITGipWu76ST3b4oVukbGTVM4lm8jzW8hZcN/BafJnGw7UtreLvtS4UvTeACzhAu92sPs1Yx6U97ButbTxRXMXnDjT1w2umJpuYFnIli333DUsNL+Aj7Ucfj+E77GTAIhS/sJ9QJJV/aob1qu0T4YBB5apjGuIfdHrBvHYsWpzG+2+7bURy74875IFyO4kB9wxJwBe+gfDW8iSm8rn0LO4BH8AOWtJeuPUiFr3z1p47vE3zh/pITjhI+28JWXvbWJHclx8K8i5DOWRZKfcFSmO3dt2HZW8Nd7dXUxSge3NgXhKMnnOjZl8lkMplMJpP5L/A3+PfT6KCa/bcAAAAASUVORK5CYII="`;
18
+
19
+ exports[`Config settings Features are drawn correctly when type = b, subtype = 1 1`] = `"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGQAAAAaCAYAAABByvnlAAAABmJLR0QA/wD/AP+gvaeTAAABFElEQVRoge3XsUrDUBiG4fePLdLJQcFBcOns5OTsINQ7SMgVeA9ODl6E4NIz6E1U0NsobqKLTqJ1yO9iiw5ihoRzjnzP1qTDGz6StCAiv7PYAX/xgLf5nlXpX0sbRewA+UmDJEaDJEaDJEaDiIiI/BPJ/7v1GQMe+ADuvw690nBiNbcAHpgCRxiPVrIXLbQjufzKWljF2CrGGKcY56szDRc4k4htncplkO9GGM/LD1Zzg/MSM6hLg9gBLa17YA4McTYoOIwd1Jdc7pDlI2sX45iG4NesxY7qQy6DrFjJHbDJOzuxW/qQ3SAe2AeGbPEUu6UPub1DCpw3nNomLAB8yhXGAc62B+YYZ1ZyGblXRERERJLyCTOxNkzPojUJAAAAAElFTkSuQmCC"`;
20
+
21
+ exports[`Config settings Features are drawn correctly when type = b, subtype = 2 1`] = `"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGQAAAAaCAYAAABByvnlAAAABmJLR0QA/wD/AP+gvaeTAAABRUlEQVRoge3Xr0tDURjG8e+5bsiSOJu/gitiNVk1+p9oMxnG9jAGM00EsyZRltS0YFKDf8GwiMGkwTAUuTI2g9sUYWCQcy+e9xPvOXAe7sO5vBeMMaO5pAP4JtT75b5E3k2UxKFmNCskZayQlLFCUsYKMcYYY/6JEP/UM8A7cN9/9BoRbZYoXVWpznXoHAKLQAzsCu37zBfqlBULFYQKQKlLd+fbWkVoFlgBtoWWfAYLtZAhh8sBzwBFig9ClwBCT8AtMO0zT8bnYSkyLnQHZHv0JoC1nxv6N2MBuPEZLNQbMvhkzQPrwFGDxthgsUZtEjgGNoRefAYLtZAhoWtgqkVrBqBOPRcTnwJ7Qk3feYIvpEJlGcjmyT8KZdq0TxyuKXSQRJ7Qx94IeONzmjoXWgUu+BqJcbitMuWzRMIaY4wxxpg/8gEQ8k4ZTEcv+AAAAABJRU5ErkJggg=="`;
22
+
23
+ exports[`Config settings Features are drawn correctly when type = b, subtype = all 1`] = `"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGQAAAAaCAYAAABByvnlAAAABmJLR0QA/wD/AP+gvaeTAAAB5UlEQVRoge3Xv0uVURgH8M+5KeEkaRBkOeQSQZOTaw1B/QeK/0BuTQ6iDyLoZASNkYuXyqmcHIIiHfoLpEUaisiGAinMkPs2+CMrzHu7N/XG+Wzve16+55z34bw8L1mW7S8d9QIOUpQV1TyXBqrbS4iq8kIcybspHcWk2f5yQY6ZXJBjJhfkmMkFybIsy7L/xPH/U3+mxTvf8Hr71hcVQ2nQIhRls7gmeZ/6XT4oL0QLP+eVlIZGjS5OmDi/aXMGF7GB2yHuNnxTf9AsXdZGGtCTBvRIRiVTuyMV9xSu15oXoidED0YrKlN7xsZDnEMfhkNcqn/51WuWguzVJvm4c5EGPVf49LdhSWpjK2/EyJsQLyDEB7zC2TrXW5OWw5ysDieLshW0KrQruVpvXogVtBaKdn7P2z4ZF/Cyzrlq0iwnZOeT1S25oaJczDlRT972J6sbN1CeM7ebN2nyFB7gZojPda69Js1SkF2p3xI6fdXViLwQS+hcttwF06bbNmw8xp0QC42YoxZNV5CirBetTlttRN648V60duhYDdGyZu1hkhZC3G9Efq2are0tKawrDKdB81DMeiTpwxm8lUykfjP75f3S9pawbqubmg9xBU/9aIkl6daYsSf/bINZlmVZlmXZIfgOYVyDipGMt8MAAAAASUVORK5CYII="`;