@jbrowse/plugin-alignments 2.16.0 → 2.17.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 (221) hide show
  1. package/dist/AlignmentsFeatureDetail/AlignmentsFeatureDetail.js +2 -3
  2. package/dist/AlignmentsFeatureDetail/Flags.js +2 -2
  3. package/dist/AlignmentsFeatureDetail/LinkedPairedAlignments.js +2 -2
  4. package/dist/AlignmentsFeatureDetail/SupplementaryAlignments.js +2 -2
  5. package/dist/AlignmentsFeatureDetail/getSAFeatures.js +2 -2
  6. package/dist/AlignmentsFeatureDetail/stateModelFactory.d.ts +1 -1
  7. package/dist/BamAdapter/BamAdapter.d.ts +3 -2
  8. package/dist/BamAdapter/BamAdapter.js +34 -11
  9. package/dist/BamAdapter/BamSlightlyLazyFeature.d.ts +3 -17
  10. package/dist/BamAdapter/BamSlightlyLazyFeature.js +42 -72
  11. package/dist/CramAdapter/CramAdapter.d.ts +4 -3
  12. package/dist/CramAdapter/CramAdapter.js +24 -7
  13. package/dist/CramAdapter/CramSlightlyLazyFeature.d.ts +21 -27
  14. package/dist/CramAdapter/CramSlightlyLazyFeature.js +74 -73
  15. package/dist/CramAdapter/util.d.ts +1 -10
  16. package/dist/LinearAlignmentsDisplay/components/AlignmentsDisplay.d.ts +1 -1
  17. package/dist/LinearAlignmentsDisplay/index.js +2 -2
  18. package/dist/LinearAlignmentsDisplay/{models/model.d.ts → model.d.ts} +6 -3
  19. package/dist/LinearAlignmentsDisplay/{models/model.js → model.js} +11 -7
  20. package/dist/LinearPileupDisplay/SharedLinearPileupDisplayMixin.d.ts +6 -27
  21. package/dist/LinearPileupDisplay/SharedLinearPileupDisplayMixin.js +43 -21
  22. package/dist/LinearPileupDisplay/components/ColorByTagDialog.d.ts +5 -4
  23. package/dist/LinearPileupDisplay/components/ColorByTagDialog.js +3 -1
  24. package/dist/LinearPileupDisplay/components/GroupByDialog.js +8 -6
  25. package/dist/LinearPileupDisplay/components/SortByTagDialog.js +6 -4
  26. package/dist/LinearPileupDisplay/model.d.ts +41 -45
  27. package/dist/LinearPileupDisplay/model.js +118 -41
  28. package/dist/LinearReadArcsDisplay/components/ReactComponent.js +1 -1
  29. package/dist/LinearReadArcsDisplay/model.d.ts +22 -21
  30. package/dist/LinearReadArcsDisplay/model.js +13 -14
  31. package/dist/LinearReadCloudDisplay/components/ReactComponent.js +1 -1
  32. package/dist/LinearReadCloudDisplay/model.d.ts +14 -22
  33. package/dist/LinearReadCloudDisplay/model.js +12 -13
  34. package/dist/LinearSNPCoverageDisplay/components/Tooltip.js +49 -19
  35. package/dist/LinearSNPCoverageDisplay/index.js +3 -2
  36. package/dist/LinearSNPCoverageDisplay/{models/model.d.ts → model.d.ts} +3 -13
  37. package/dist/LinearSNPCoverageDisplay/{models/model.js → model.js} +71 -45
  38. package/dist/MismatchParser/cigarToMismatches.d.ts +3 -0
  39. package/dist/MismatchParser/cigarToMismatches.js +94 -0
  40. package/dist/MismatchParser/getNextRefPos.d.ts +4 -0
  41. package/dist/MismatchParser/getNextRefPos.js +40 -0
  42. package/dist/MismatchParser/index.d.ts +4 -29
  43. package/dist/MismatchParser/index.js +10 -321
  44. package/dist/MismatchParser/mdToMismatches.d.ts +3 -0
  45. package/dist/MismatchParser/mdToMismatches.js +80 -0
  46. package/dist/ModificationParser/index.d.ts +19 -0
  47. package/dist/ModificationParser/index.js +144 -0
  48. package/dist/PileupRPC/methods/GetGlobalValueForTag.js +1 -2
  49. package/dist/PileupRPC/methods/GetReducedFeatures.d.ts +1 -1
  50. package/dist/PileupRPC/methods/GetReducedFeatures.js +19 -16
  51. package/dist/PileupRPC/methods/GetVisibleModifications.d.ts +2 -1
  52. package/dist/PileupRPC/methods/GetVisibleModifications.js +9 -6
  53. package/dist/PileupRenderer/PileupLayoutSession.d.ts +8 -7
  54. package/dist/PileupRenderer/PileupRenderer.d.ts +6 -14
  55. package/dist/PileupRenderer/PileupRenderer.js +7 -5
  56. package/dist/PileupRenderer/renderAlignment.js +17 -4
  57. package/dist/PileupRenderer/renderAlignmentShape.js +102 -21
  58. package/dist/PileupRenderer/renderMethylation.d.ts +2 -1
  59. package/dist/PileupRenderer/renderMethylation.js +17 -9
  60. package/dist/PileupRenderer/renderMismatches.js +19 -19
  61. package/dist/PileupRenderer/renderModifications.d.ts +3 -2
  62. package/dist/PileupRenderer/renderModifications.js +31 -34
  63. package/dist/PileupRenderer/renderPerBaseLettering.d.ts +2 -1
  64. package/dist/PileupRenderer/renderPerBaseLettering.js +1 -3
  65. package/dist/PileupRenderer/renderPerBaseQuality.d.ts +2 -1
  66. package/dist/PileupRenderer/renderPerBaseQuality.js +1 -3
  67. package/dist/PileupRenderer/renderSoftClipping.js +6 -6
  68. package/dist/PileupRenderer/sortUtil.d.ts +2 -7
  69. package/dist/PileupRenderer/sortUtil.js +13 -13
  70. package/dist/SNPCoverageAdapter/SNPCoverageAdapter.js +10 -5
  71. package/dist/SNPCoverageAdapter/generateCoverageBins.d.ts +13 -9
  72. package/dist/SNPCoverageAdapter/generateCoverageBins.js +269 -166
  73. package/dist/SNPCoverageRenderer/SNPCoverageRenderer.d.ts +2 -1
  74. package/dist/SNPCoverageRenderer/SNPCoverageRenderer.js +171 -54
  75. package/dist/shared/color.d.ts +0 -10
  76. package/dist/shared/color.js +1 -7
  77. package/{esm/shared → dist/shared/components}/BaseDisplayComponent.d.ts +2 -2
  78. package/{esm/shared → dist/shared/components}/FilterByTagDialog.d.ts +3 -3
  79. package/dist/shared/{FilterByTagDialog.js → components/FilterByTagDialog.js} +5 -1
  80. package/dist/shared/fetchChains.js +1 -2
  81. package/dist/shared/getMaximumModificationAtEachPosition.d.ts +8 -0
  82. package/dist/shared/getMaximumModificationAtEachPosition.js +42 -0
  83. package/dist/shared/getUniqueModifications.d.ts +14 -0
  84. package/dist/shared/getUniqueModifications.js +16 -0
  85. package/dist/shared/getUniqueTags.d.ts +15 -0
  86. package/dist/shared/getUniqueTags.js +18 -0
  87. package/dist/shared/types.d.ts +94 -0
  88. package/dist/shared/util.d.ts +8 -0
  89. package/dist/shared/util.js +26 -0
  90. package/dist/util.d.ts +7 -4
  91. package/dist/util.js +30 -30
  92. package/esm/AlignmentsFeatureDetail/AlignmentsFeatureDetail.js +2 -3
  93. package/esm/AlignmentsFeatureDetail/Flags.js +1 -1
  94. package/esm/AlignmentsFeatureDetail/LinkedPairedAlignments.js +1 -1
  95. package/esm/AlignmentsFeatureDetail/SupplementaryAlignments.js +1 -1
  96. package/esm/AlignmentsFeatureDetail/getSAFeatures.js +2 -2
  97. package/esm/AlignmentsFeatureDetail/stateModelFactory.d.ts +1 -1
  98. package/esm/BamAdapter/BamAdapter.d.ts +3 -2
  99. package/esm/BamAdapter/BamAdapter.js +31 -8
  100. package/esm/BamAdapter/BamSlightlyLazyFeature.d.ts +3 -17
  101. package/esm/BamAdapter/BamSlightlyLazyFeature.js +43 -73
  102. package/esm/CramAdapter/CramAdapter.d.ts +4 -3
  103. package/esm/CramAdapter/CramAdapter.js +22 -5
  104. package/esm/CramAdapter/CramSlightlyLazyFeature.d.ts +21 -27
  105. package/esm/CramAdapter/CramSlightlyLazyFeature.js +74 -73
  106. package/esm/CramAdapter/util.d.ts +1 -10
  107. package/esm/LinearAlignmentsDisplay/components/AlignmentsDisplay.d.ts +1 -1
  108. package/esm/LinearAlignmentsDisplay/index.js +2 -2
  109. package/esm/LinearAlignmentsDisplay/{models/model.d.ts → model.d.ts} +6 -3
  110. package/esm/LinearAlignmentsDisplay/{models/model.js → model.js} +11 -7
  111. package/esm/LinearPileupDisplay/SharedLinearPileupDisplayMixin.d.ts +6 -27
  112. package/esm/LinearPileupDisplay/SharedLinearPileupDisplayMixin.js +45 -23
  113. package/esm/LinearPileupDisplay/components/ColorByTagDialog.d.ts +5 -4
  114. package/esm/LinearPileupDisplay/components/ColorByTagDialog.js +3 -1
  115. package/esm/LinearPileupDisplay/components/GroupByDialog.js +8 -6
  116. package/esm/LinearPileupDisplay/components/SortByTagDialog.js +6 -4
  117. package/esm/LinearPileupDisplay/model.d.ts +41 -45
  118. package/esm/LinearPileupDisplay/model.js +119 -42
  119. package/esm/LinearReadArcsDisplay/components/ReactComponent.js +1 -1
  120. package/esm/LinearReadArcsDisplay/model.d.ts +22 -21
  121. package/esm/LinearReadArcsDisplay/model.js +14 -15
  122. package/esm/LinearReadCloudDisplay/components/ReactComponent.js +1 -1
  123. package/esm/LinearReadCloudDisplay/model.d.ts +14 -22
  124. package/esm/LinearReadCloudDisplay/model.js +13 -14
  125. package/esm/LinearSNPCoverageDisplay/components/Tooltip.js +49 -19
  126. package/esm/LinearSNPCoverageDisplay/index.js +3 -2
  127. package/esm/LinearSNPCoverageDisplay/{models/model.d.ts → model.d.ts} +3 -13
  128. package/esm/LinearSNPCoverageDisplay/{models/model.js → model.js} +72 -46
  129. package/esm/MismatchParser/cigarToMismatches.d.ts +3 -0
  130. package/esm/MismatchParser/cigarToMismatches.js +91 -0
  131. package/esm/MismatchParser/getNextRefPos.d.ts +4 -0
  132. package/esm/MismatchParser/getNextRefPos.js +37 -0
  133. package/esm/MismatchParser/index.d.ts +4 -29
  134. package/esm/MismatchParser/index.js +5 -311
  135. package/esm/MismatchParser/mdToMismatches.d.ts +3 -0
  136. package/esm/MismatchParser/mdToMismatches.js +77 -0
  137. package/esm/ModificationParser/index.d.ts +19 -0
  138. package/esm/ModificationParser/index.js +138 -0
  139. package/esm/PileupRPC/methods/GetGlobalValueForTag.js +1 -2
  140. package/esm/PileupRPC/methods/GetReducedFeatures.d.ts +1 -1
  141. package/esm/PileupRPC/methods/GetReducedFeatures.js +19 -16
  142. package/esm/PileupRPC/methods/GetVisibleModifications.d.ts +2 -1
  143. package/esm/PileupRPC/methods/GetVisibleModifications.js +9 -6
  144. package/esm/PileupRenderer/PileupLayoutSession.d.ts +8 -7
  145. package/esm/PileupRenderer/PileupRenderer.d.ts +6 -14
  146. package/esm/PileupRenderer/PileupRenderer.js +8 -6
  147. package/esm/PileupRenderer/renderAlignment.js +17 -4
  148. package/esm/PileupRenderer/renderAlignmentShape.js +102 -21
  149. package/esm/PileupRenderer/renderMethylation.d.ts +2 -1
  150. package/esm/PileupRenderer/renderMethylation.js +17 -9
  151. package/esm/PileupRenderer/renderMismatches.js +19 -19
  152. package/esm/PileupRenderer/renderModifications.d.ts +3 -2
  153. package/esm/PileupRenderer/renderModifications.js +30 -33
  154. package/esm/PileupRenderer/renderPerBaseLettering.d.ts +2 -1
  155. package/esm/PileupRenderer/renderPerBaseLettering.js +1 -3
  156. package/esm/PileupRenderer/renderPerBaseQuality.d.ts +2 -1
  157. package/esm/PileupRenderer/renderPerBaseQuality.js +1 -3
  158. package/esm/PileupRenderer/renderSoftClipping.js +6 -6
  159. package/esm/PileupRenderer/sortUtil.d.ts +2 -7
  160. package/esm/PileupRenderer/sortUtil.js +13 -13
  161. package/esm/SNPCoverageAdapter/SNPCoverageAdapter.js +10 -5
  162. package/esm/SNPCoverageAdapter/generateCoverageBins.d.ts +13 -9
  163. package/esm/SNPCoverageAdapter/generateCoverageBins.js +269 -166
  164. package/esm/SNPCoverageRenderer/SNPCoverageRenderer.d.ts +2 -1
  165. package/esm/SNPCoverageRenderer/SNPCoverageRenderer.js +171 -54
  166. package/esm/shared/color.d.ts +0 -10
  167. package/esm/shared/color.js +0 -6
  168. package/{dist/shared → esm/shared/components}/BaseDisplayComponent.d.ts +2 -2
  169. package/{dist/shared → esm/shared/components}/FilterByTagDialog.d.ts +3 -3
  170. package/esm/shared/{FilterByTagDialog.js → components/FilterByTagDialog.js} +5 -1
  171. package/esm/shared/fetchChains.js +1 -2
  172. package/esm/shared/getMaximumModificationAtEachPosition.d.ts +8 -0
  173. package/esm/shared/getMaximumModificationAtEachPosition.js +39 -0
  174. package/esm/shared/getUniqueModifications.d.ts +14 -0
  175. package/esm/shared/getUniqueModifications.js +13 -0
  176. package/esm/shared/getUniqueTags.d.ts +15 -0
  177. package/esm/shared/getUniqueTags.js +15 -0
  178. package/esm/shared/types.d.ts +94 -0
  179. package/esm/shared/util.d.ts +8 -0
  180. package/esm/shared/util.js +23 -0
  181. package/esm/util.d.ts +7 -4
  182. package/esm/util.js +28 -27
  183. package/package.json +4 -4
  184. package/dist/LinearPileupDisplay/components/ColorByModificationsDialog.d.ts +0 -15
  185. package/dist/LinearPileupDisplay/components/ColorByModificationsDialog.js +0 -41
  186. package/dist/LinearPileupDisplay/components/ModificationsTable.d.ts +0 -4
  187. package/dist/LinearPileupDisplay/components/ModificationsTable.js +0 -28
  188. package/dist/SNPCoverageAdapter/util.d.ts +0 -25
  189. package/dist/shared/index.d.ts +0 -49
  190. package/dist/shared/index.js +0 -41
  191. package/esm/LinearPileupDisplay/components/ColorByModificationsDialog.d.ts +0 -15
  192. package/esm/LinearPileupDisplay/components/ColorByModificationsDialog.js +0 -36
  193. package/esm/LinearPileupDisplay/components/ModificationsTable.d.ts +0 -4
  194. package/esm/LinearPileupDisplay/components/ModificationsTable.js +0 -22
  195. package/esm/SNPCoverageAdapter/util.d.ts +0 -25
  196. package/esm/shared/index.d.ts +0 -49
  197. package/esm/shared/index.js +0 -36
  198. /package/dist/LinearAlignmentsDisplay/{models/alignmentsModel.d.ts → alignmentsModel.d.ts} +0 -0
  199. /package/dist/LinearAlignmentsDisplay/{models/alignmentsModel.js → alignmentsModel.js} +0 -0
  200. /package/dist/LinearAlignmentsDisplay/{models/configSchema.d.ts → configSchema.d.ts} +0 -0
  201. /package/dist/LinearAlignmentsDisplay/{models/configSchema.js → configSchema.js} +0 -0
  202. /package/dist/LinearAlignmentsDisplay/{models/util.d.ts → util.d.ts} +0 -0
  203. /package/dist/LinearAlignmentsDisplay/{models/util.js → util.js} +0 -0
  204. /package/dist/LinearSNPCoverageDisplay/{models/configSchema.d.ts → configSchema.d.ts} +0 -0
  205. /package/dist/LinearSNPCoverageDisplay/{models/configSchema.js → configSchema.js} +0 -0
  206. /package/dist/shared/{BaseDisplayComponent.js → components/BaseDisplayComponent.js} +0 -0
  207. /package/dist/shared/{renderSvg.d.ts → renderSvgUtil.d.ts} +0 -0
  208. /package/dist/shared/{renderSvg.js → renderSvgUtil.js} +0 -0
  209. /package/dist/{SNPCoverageAdapter/util.js → shared/types.js} +0 -0
  210. /package/esm/LinearAlignmentsDisplay/{models/alignmentsModel.d.ts → alignmentsModel.d.ts} +0 -0
  211. /package/esm/LinearAlignmentsDisplay/{models/alignmentsModel.js → alignmentsModel.js} +0 -0
  212. /package/esm/LinearAlignmentsDisplay/{models/configSchema.d.ts → configSchema.d.ts} +0 -0
  213. /package/esm/LinearAlignmentsDisplay/{models/configSchema.js → configSchema.js} +0 -0
  214. /package/esm/LinearAlignmentsDisplay/{models/util.d.ts → util.d.ts} +0 -0
  215. /package/esm/LinearAlignmentsDisplay/{models/util.js → util.js} +0 -0
  216. /package/esm/LinearSNPCoverageDisplay/{models/configSchema.d.ts → configSchema.d.ts} +0 -0
  217. /package/esm/LinearSNPCoverageDisplay/{models/configSchema.js → configSchema.js} +0 -0
  218. /package/esm/shared/{BaseDisplayComponent.js → components/BaseDisplayComponent.js} +0 -0
  219. /package/esm/shared/{renderSvg.d.ts → renderSvgUtil.d.ts} +0 -0
  220. /package/esm/shared/{renderSvg.js → renderSvgUtil.js} +0 -0
  221. /package/esm/{SNPCoverageAdapter/util.js → shared/types.js} +0 -0
@@ -5,7 +5,7 @@ import { firstValueFrom } from 'rxjs';
5
5
  // locals
6
6
  import { filterForPairs, getInsertSizeStats } from '../util';
7
7
  import PileupBaseRPC from '../base';
8
- import { getTag } from '../../util';
8
+ import { getClip } from '../../MismatchParser';
9
9
  // specialized get features to return limited data about alignments
10
10
  export default class PileupGetReducedFeatures extends PileupBaseRPC {
11
11
  constructor() {
@@ -17,21 +17,24 @@ export default class PileupGetReducedFeatures extends PileupBaseRPC {
17
17
  const { adapterConfig, sessionId, regions } = des;
18
18
  const dataAdapter = (await getAdapter(this.pluginManager, sessionId, adapterConfig)).dataAdapter;
19
19
  const featuresArray = await firstValueFrom(dataAdapter.getFeaturesInMultipleRegions(regions, des).pipe(toArray()));
20
- const reduced = dedupe(featuresArray.map(f => ({
21
- id: f.id(),
22
- refName: f.get('refName'),
23
- name: f.get('name'),
24
- start: f.get('start'),
25
- strand: f.get('strand'),
26
- end: f.get('end'),
27
- flags: f.get('flags'),
28
- tlen: f.get('template_length'),
29
- pair_orientation: f.get('pair_orientation'),
30
- next_ref: f.get('next_ref'),
31
- next_pos: f.get('next_pos'),
32
- clipPos: f.get('clipPos'),
33
- SA: getTag(f, 'SA'),
34
- })), f => f.id);
20
+ const reduced = dedupe(featuresArray.map(f => {
21
+ var _a;
22
+ return ({
23
+ id: f.id(),
24
+ refName: f.get('refName'),
25
+ name: f.get('name'),
26
+ start: f.get('start'),
27
+ strand: f.get('strand'),
28
+ end: f.get('end'),
29
+ flags: f.get('flags'),
30
+ tlen: f.get('template_length'),
31
+ pair_orientation: f.get('pair_orientation'),
32
+ next_ref: f.get('next_ref'),
33
+ next_pos: f.get('next_pos'),
34
+ clipPos: getClip(f.get('CIGAR'), f.get('strand')),
35
+ SA: (_a = f.get('tags')) === null || _a === void 0 ? void 0 : _a.SA,
36
+ });
37
+ }), f => f.id);
35
38
  const filtered = filterForPairs(reduced);
36
39
  const stats = filtered.length ? getInsertSizeStats(filtered) : undefined;
37
40
  const chains = groupBy(reduced, f => f.name);
@@ -1,5 +1,6 @@
1
1
  import { RemoteAbortSignal } from '@jbrowse/core/rpc/remoteAbortSignals';
2
2
  import { Region } from '@jbrowse/core/util';
3
+ import { ModificationType } from '../../shared/types';
3
4
  import PileupBaseRPC from '../base';
4
5
  export default class PileupGetVisibleModifications extends PileupBaseRPC {
5
6
  name: string;
@@ -10,5 +11,5 @@ export default class PileupGetVisibleModifications extends PileupBaseRPC {
10
11
  regions: Region[];
11
12
  sessionId: string;
12
13
  tag: string;
13
- }, rpcDriver: string): Promise<string[]>;
14
+ }, rpcDriver: string): Promise<ModificationType[]>;
14
15
  }
@@ -1,10 +1,9 @@
1
1
  import { getAdapter } from '@jbrowse/core/data_adapters/dataAdapterCache';
2
2
  import { toArray } from 'rxjs/operators';
3
3
  import { firstValueFrom } from 'rxjs';
4
- // locals
5
- import { getModificationTypes } from '../../MismatchParser';
6
- import PileupBaseRPC from '../base';
4
+ import { getModTypes } from '../../ModificationParser';
7
5
  import { getTagAlt } from '../../util';
6
+ import PileupBaseRPC from '../base';
8
7
  export default class PileupGetVisibleModifications extends PileupBaseRPC {
9
8
  constructor() {
10
9
  super(...arguments);
@@ -14,10 +13,14 @@ export default class PileupGetVisibleModifications extends PileupBaseRPC {
14
13
  const { adapterConfig, sessionId, regions } = await this.deserializeArguments(args, rpcDriver);
15
14
  const dataAdapter = (await getAdapter(this.pluginManager, sessionId, adapterConfig)).dataAdapter;
16
15
  const featuresArray = await firstValueFrom(dataAdapter.getFeaturesInMultipleRegions(regions).pipe(toArray()));
17
- const uniqueValues = new Set();
16
+ const uniqueModifications = new Map();
18
17
  featuresArray.forEach(f => {
19
- getModificationTypes(getTagAlt(f, 'MM', 'Mm') || '').forEach(t => uniqueValues.add(t));
18
+ for (const mod of getModTypes(getTagAlt(f, 'MM', 'Mm') || '')) {
19
+ if (!uniqueModifications.has(mod.type)) {
20
+ uniqueModifications.set(mod.type, mod);
21
+ }
22
+ }
20
23
  });
21
- return [...uniqueValues];
24
+ return [...uniqueModifications.values()];
22
25
  }
23
26
  }
@@ -3,26 +3,27 @@ import { AnyConfigurationModel } from '@jbrowse/core/configuration';
3
3
  import SerializableFilterChain from '@jbrowse/core/pluggableElementTypes/renderers/util/serializableFilterChain';
4
4
  import GranularRectLayout from '@jbrowse/core/util/layouts/GranularRectLayout';
5
5
  import MultiLayout from '@jbrowse/core/util/layouts/MultiLayout';
6
+ import { FilterBy, SortedBy } from '../shared/types';
6
7
  export interface PileupLayoutSessionProps {
7
8
  config: AnyConfigurationModel;
8
9
  bpPerPx: number;
9
10
  filters: SerializableFilterChain;
10
- filterBy: unknown;
11
- sortedBy: unknown;
12
- showSoftClip: unknown;
11
+ filterBy: FilterBy;
12
+ sortedBy: SortedBy;
13
+ showSoftClip: boolean;
13
14
  }
14
15
  type MyMultiLayout = MultiLayout<GranularRectLayout<unknown>, unknown>;
15
16
  interface CachedPileupLayout {
16
17
  layout: MyMultiLayout;
17
18
  config: AnyConfigurationModel;
18
19
  filters?: SerializableFilterChain;
19
- filterBy: unknown;
20
- sortedBy: unknown;
20
+ filterBy?: FilterBy;
21
+ sortedBy?: SortedBy;
21
22
  showSoftClip: boolean;
22
23
  }
23
24
  export declare class PileupLayoutSession extends LayoutSession {
24
- sortedBy: unknown;
25
- filterBy: unknown;
25
+ sortedBy?: SortedBy;
26
+ filterBy?: FilterBy;
26
27
  showSoftClip: boolean;
27
28
  constructor(args: PileupLayoutSessionProps);
28
29
  cachedLayoutIsValid(cachedLayout: CachedPileupLayout): boolean;
@@ -2,20 +2,12 @@ import BoxRendererType, { RenderArgsDeserialized as BoxRenderArgsDeserialized }
2
2
  import { Feature, Region } from '@jbrowse/core/util';
3
3
  import { BaseLayout } from '@jbrowse/core/util/layouts/BaseLayout';
4
4
  import { PileupLayoutSession, PileupLayoutSessionProps } from './PileupLayoutSession';
5
+ import { ColorBy, ModificationTypeWithColor, SortedBy } from '../shared/types';
5
6
  export interface RenderArgsDeserialized extends BoxRenderArgsDeserialized {
6
- colorBy?: {
7
- type: string;
8
- tag?: string;
9
- };
7
+ colorBy?: ColorBy;
10
8
  colorTagMap?: Record<string, string>;
11
- modificationTagMap?: Record<string, string>;
12
- sortedBy?: {
13
- type: string;
14
- pos: number;
15
- refName: string;
16
- assemblyName: string;
17
- tag?: string;
18
- };
9
+ visibleModifications?: Record<string, ModificationTypeWithColor>;
10
+ sortedBy?: SortedBy;
19
11
  showSoftClip: boolean;
20
12
  highResolutionScaling: number;
21
13
  }
@@ -30,8 +22,8 @@ export default class PileupRenderer extends BoxRendererType {
30
22
  getExpandedRegion(region: Region, renderArgs: RenderArgsDeserialized): {
31
23
  start: number;
32
24
  end: number;
33
- refName: string;
34
25
  reversed?: boolean | undefined;
26
+ refName: string;
35
27
  assemblyName: string;
36
28
  };
37
29
  render(renderProps: RenderArgsDeserialized): Promise<{
@@ -63,4 +55,4 @@ export default class PileupRenderer extends BoxRendererType {
63
55
  }>;
64
56
  createSession(args: PileupLayoutSessionProps): PileupLayoutSession;
65
57
  }
66
- export { type RenderArgs, type RenderResults, type RenderArgsSerialized, type ResultsSerialized, type ResultsDeserialized, } from '@jbrowse/core/pluggableElementTypes/renderers/BoxRendererType';
58
+ export type { RenderArgs, RenderResults, RenderArgsSerialized, ResultsSerialized, ResultsDeserialized, } from '@jbrowse/core/pluggableElementTypes/renderers/BoxRendererType';
@@ -4,7 +4,7 @@ import { readConfObject } from '@jbrowse/core/configuration';
4
4
  import { getAdapter } from '@jbrowse/core/data_adapters/dataAdapterCache';
5
5
  import { PileupLayoutSession, } from './PileupLayoutSession';
6
6
  // locals
7
- import { fetchSequence, shouldFetchReferenceSequence } from '../util';
7
+ import { fetchSequence } from '../util';
8
8
  import { layoutFeats } from './layoutFeatures';
9
9
  export default class PileupRenderer extends BoxRendererType {
10
10
  constructor() {
@@ -17,10 +17,13 @@ export default class PileupRenderer extends BoxRendererType {
17
17
  if (!sequenceAdapter) {
18
18
  return undefined;
19
19
  }
20
- const pm = this.pluginManager;
21
- const { dataAdapter } = await getAdapter(pm, sessionId, sequenceAdapter);
20
+ const { dataAdapter } = await getAdapter(this.pluginManager, sessionId, sequenceAdapter);
22
21
  const region = regions[0];
23
- return fetchSequence(region, dataAdapter);
22
+ return fetchSequence({
23
+ ...region,
24
+ start: Math.max(0, region.start - 1),
25
+ end: region.end + 1,
26
+ }, dataAdapter);
24
27
  }
25
28
  getExpandedRegion(region, renderArgs) {
26
29
  const { config, showSoftClip } = renderArgs;
@@ -35,7 +38,6 @@ export default class PileupRenderer extends BoxRendererType {
35
38
  };
36
39
  }
37
40
  async render(renderProps) {
38
- var _a;
39
41
  const features = await this.getFeatures(renderProps);
40
42
  const layout = this.createLayoutInWorker(renderProps);
41
43
  const { regions, bpPerPx } = renderProps;
@@ -47,7 +49,7 @@ export default class PileupRenderer extends BoxRendererType {
47
49
  });
48
50
  // only need reference sequence if there are features and only for some
49
51
  // cases
50
- const regionSequence = features.size && shouldFetchReferenceSequence((_a = renderProps.colorBy) === null || _a === void 0 ? void 0 : _a.type)
52
+ const regionSequence = features.size
51
53
  ? await this.fetchSequence(renderProps)
52
54
  : undefined;
53
55
  const width = (region.end - region.start) / bpPerPx;
@@ -4,6 +4,7 @@ import { renderPerBaseQuality } from './renderPerBaseQuality';
4
4
  import { renderPerBaseLettering } from './renderPerBaseLettering';
5
5
  import { renderModifications } from './renderModifications';
6
6
  import { renderMethylation } from './renderMethylation';
7
+ import { parseCigar } from '../MismatchParser';
7
8
  export function renderAlignment({ ctx, feat, renderArgs, colorForBase, contrastForBase, charWidth, charHeight, defaultColor, canvasWidth, }) {
8
9
  const { config, bpPerPx, regions, colorBy, colorTagMap = {} } = renderArgs;
9
10
  const { tag = '', type: colorType = '' } = colorBy || {};
@@ -21,16 +22,20 @@ export function renderAlignment({ ctx, feat, renderArgs, colorForBase, contrastF
21
22
  // second pass for color types that render per-base things that go over the
22
23
  // existing drawing
23
24
  switch (colorType) {
24
- case 'perBaseQuality':
25
+ case 'perBaseQuality': {
26
+ const cigarOps = parseCigar(feature.get('CIGAR'));
25
27
  renderPerBaseQuality({
26
28
  ctx,
27
29
  feat,
28
30
  region,
29
31
  bpPerPx,
30
32
  canvasWidth,
33
+ cigarOps,
31
34
  });
32
35
  break;
33
- case 'perBaseLettering':
36
+ }
37
+ case 'perBaseLettering': {
38
+ const cigarOps = parseCigar(feature.get('CIGAR'));
34
39
  renderPerBaseLettering({
35
40
  ctx,
36
41
  feat,
@@ -41,9 +46,12 @@ export function renderAlignment({ ctx, feat, renderArgs, colorForBase, contrastF
41
46
  charWidth,
42
47
  charHeight,
43
48
  canvasWidth,
49
+ cigarOps,
44
50
  });
45
51
  break;
46
- case 'modifications':
52
+ }
53
+ case 'modifications': {
54
+ const cigarOps = parseCigar(feature.get('CIGAR'));
47
55
  renderModifications({
48
56
  ctx,
49
57
  feat,
@@ -51,9 +59,12 @@ export function renderAlignment({ ctx, feat, renderArgs, colorForBase, contrastF
51
59
  bpPerPx,
52
60
  renderArgs,
53
61
  canvasWidth,
62
+ cigarOps,
54
63
  });
55
64
  break;
56
- case 'methylation':
65
+ }
66
+ case 'methylation': {
67
+ const cigarOps = parseCigar(feature.get('CIGAR'));
57
68
  renderMethylation({
58
69
  ctx,
59
70
  feat,
@@ -61,7 +72,9 @@ export function renderAlignment({ ctx, feat, renderArgs, colorForBase, contrastF
61
72
  bpPerPx,
62
73
  renderArgs,
63
74
  canvasWidth,
75
+ cigarOps,
64
76
  });
65
77
  break;
78
+ }
66
79
  }
67
80
  }
@@ -1,36 +1,117 @@
1
1
  import { bpSpanPx } from '@jbrowse/core/util';
2
+ import { parseCigar } from '../MismatchParser';
2
3
  export function renderAlignmentShape({ ctx, feat, renderArgs, }) {
3
4
  const { regions, bpPerPx } = renderArgs;
4
5
  const { heightPx, topPx, feature } = feat;
5
6
  const region = regions[0];
6
7
  const s = feature.get('start');
7
8
  const e = feature.get('end');
8
- const [leftPx, rightPx] = bpSpanPx(s, e, region, bpPerPx);
9
+ const CIGAR = feature.get('CIGAR');
9
10
  const flip = region.reversed ? -1 : 1;
10
11
  const strand = feature.get('strand') * flip;
11
- if (bpPerPx < 10 && heightPx > 5) {
12
- if (strand === -1) {
13
- ctx.beginPath();
14
- ctx.moveTo(leftPx - 5, topPx + heightPx / 2);
15
- ctx.lineTo(leftPx, topPx + heightPx);
16
- ctx.lineTo(rightPx, topPx + heightPx);
17
- ctx.lineTo(rightPx, topPx);
18
- ctx.lineTo(leftPx, topPx);
19
- ctx.closePath();
20
- ctx.fill();
12
+ const renderChevrons = bpPerPx < 10 && heightPx > 5;
13
+ if (CIGAR.includes('N')) {
14
+ const cigarOps = parseCigar(CIGAR);
15
+ if (strand === 1) {
16
+ let drawLen = 0;
17
+ let drawStart = s;
18
+ for (let i = 0; i < cigarOps.length; i += 2) {
19
+ const opLen = +cigarOps[i];
20
+ const op = cigarOps[i + 1];
21
+ if (op === 'M' || op === 'X' || op === '=' || op === 'D') {
22
+ drawLen += opLen;
23
+ }
24
+ else if (op === 'N') {
25
+ if (drawStart !== drawLen) {
26
+ const [leftPx, rightPx] = bpSpanPx(drawStart, drawStart + drawLen, region, bpPerPx);
27
+ const w = rightPx - leftPx;
28
+ ctx.fillRect(leftPx, topPx, w, heightPx);
29
+ }
30
+ drawStart += drawLen + opLen;
31
+ drawLen = 0;
32
+ }
33
+ }
34
+ if (drawStart !== drawLen) {
35
+ const [leftPx, rightPx] = bpSpanPx(drawStart, drawStart + drawLen, region, bpPerPx);
36
+ const w = rightPx - leftPx;
37
+ if (renderChevrons) {
38
+ ctx.beginPath();
39
+ ctx.moveTo(leftPx, topPx);
40
+ ctx.lineTo(leftPx, topPx + heightPx);
41
+ ctx.lineTo(rightPx, topPx + heightPx);
42
+ ctx.lineTo(rightPx + 5, topPx + heightPx / 2);
43
+ ctx.lineTo(rightPx, topPx);
44
+ ctx.closePath();
45
+ ctx.fill();
46
+ }
47
+ else {
48
+ ctx.fillRect(leftPx, topPx, w, heightPx);
49
+ }
50
+ }
21
51
  }
22
- else {
23
- ctx.beginPath();
24
- ctx.moveTo(leftPx, topPx);
25
- ctx.lineTo(leftPx, topPx + heightPx);
26
- ctx.lineTo(rightPx, topPx + heightPx);
27
- ctx.lineTo(rightPx + 5, topPx + heightPx / 2);
28
- ctx.lineTo(rightPx, topPx);
29
- ctx.closePath();
30
- ctx.fill();
52
+ else if (strand === -1) {
53
+ let drawLen = 0;
54
+ let drawStart = e;
55
+ for (let i = cigarOps.length - 2; i >= 0; i -= 2) {
56
+ const opLen = +cigarOps[i];
57
+ const op = cigarOps[i + 1];
58
+ if (op === 'M' || op === 'X' || op === '=' || op === 'D') {
59
+ drawLen += opLen;
60
+ }
61
+ else if (op === 'N') {
62
+ if (drawLen !== 0) {
63
+ const [leftPx, rightPx] = bpSpanPx(drawStart - drawLen, drawStart, region, bpPerPx);
64
+ ctx.fillRect(leftPx, topPx, rightPx - leftPx, heightPx);
65
+ }
66
+ drawStart -= drawLen + opLen;
67
+ drawLen = 0;
68
+ }
69
+ }
70
+ if (drawLen !== 0) {
71
+ const [leftPx, rightPx] = bpSpanPx(drawStart - drawLen, drawStart, region, bpPerPx);
72
+ const w = rightPx - leftPx;
73
+ if (renderChevrons) {
74
+ ctx.beginPath();
75
+ ctx.moveTo(leftPx - 5, topPx + heightPx / 2);
76
+ ctx.lineTo(leftPx, topPx + heightPx);
77
+ ctx.lineTo(rightPx, topPx + heightPx);
78
+ ctx.lineTo(rightPx, topPx);
79
+ ctx.lineTo(leftPx, topPx);
80
+ ctx.closePath();
81
+ ctx.fill();
82
+ }
83
+ else {
84
+ ctx.fillRect(leftPx, topPx, w, heightPx);
85
+ }
86
+ }
31
87
  }
32
88
  }
33
89
  else {
34
- ctx.fillRect(leftPx, topPx, rightPx - leftPx, heightPx);
90
+ const [leftPx, rightPx] = bpSpanPx(s, e, region, bpPerPx);
91
+ if (bpPerPx < 10 && heightPx > 5) {
92
+ if (strand === -1) {
93
+ ctx.beginPath();
94
+ ctx.moveTo(leftPx - 5, topPx + heightPx / 2);
95
+ ctx.lineTo(leftPx, topPx + heightPx);
96
+ ctx.lineTo(rightPx, topPx + heightPx);
97
+ ctx.lineTo(rightPx, topPx);
98
+ ctx.lineTo(leftPx, topPx);
99
+ ctx.closePath();
100
+ ctx.fill();
101
+ }
102
+ else {
103
+ ctx.beginPath();
104
+ ctx.moveTo(leftPx, topPx);
105
+ ctx.lineTo(leftPx, topPx + heightPx);
106
+ ctx.lineTo(rightPx, topPx + heightPx);
107
+ ctx.lineTo(rightPx + 5, topPx + heightPx / 2);
108
+ ctx.lineTo(rightPx, topPx);
109
+ ctx.closePath();
110
+ ctx.fill();
111
+ }
112
+ }
113
+ else {
114
+ ctx.fillRect(leftPx, topPx, rightPx - leftPx, heightPx);
115
+ }
35
116
  }
36
117
  }
@@ -1,11 +1,12 @@
1
1
  import { Region } from '@jbrowse/core/util';
2
2
  import { LayoutFeature } from './util';
3
3
  import { RenderArgsWithColor } from './makeImageData';
4
- export declare function renderMethylation({ ctx, feat, region, bpPerPx, renderArgs, canvasWidth, }: {
4
+ export declare function renderMethylation({ ctx, feat, region, bpPerPx, renderArgs, canvasWidth, cigarOps, }: {
5
5
  ctx: CanvasRenderingContext2D;
6
6
  feat: LayoutFeature;
7
7
  region: Region;
8
8
  bpPerPx: number;
9
9
  renderArgs: RenderArgsWithColor;
10
10
  canvasWidth: number;
11
+ cigarOps: string[];
11
12
  }): void;
@@ -1,11 +1,12 @@
1
1
  import { bpSpanPx } from '@jbrowse/core/util';
2
- import { getMethBins } from '../MismatchParser';
3
- import { fillRect } from './util';
4
2
  import { colord } from '@jbrowse/core/util/colord';
5
- // Color by methylation is slightly modified version of color by
6
- // modifications that focuses on CpG sites, with non-methylated CpG colored
7
- export function renderMethylation({ ctx, feat, region, bpPerPx, renderArgs, canvasWidth, }) {
8
- var _a, _b;
3
+ // locals
4
+ import { fillRect } from './util';
5
+ import { getMethBins } from '../ModificationParser';
6
+ // Color by methylation is slightly modified version of color by modifications
7
+ // at reference CpG sites, with non-methylated CpG colored (looking only at the
8
+ // MM tag can not tell you where reference CpG sites are)
9
+ export function renderMethylation({ ctx, feat, region, bpPerPx, renderArgs, canvasWidth, cigarOps, }) {
9
10
  const { regionSequence } = renderArgs;
10
11
  const { feature, topPx, heightPx } = feat;
11
12
  if (!regionSequence) {
@@ -17,7 +18,7 @@ export function renderMethylation({ ctx, feat, region, bpPerPx, renderArgs, canv
17
18
  }
18
19
  const fstart = feature.get('start');
19
20
  const fend = feature.get('end');
20
- const { methBins, methProbs } = getMethBins(feature);
21
+ const { methBins, methProbs, hydroxyMethBins, hydroxyMethProbs } = getMethBins(feature, cigarOps);
21
22
  function getCol(k) {
22
23
  if (methBins[k]) {
23
24
  const p = methProbs[k] || 0;
@@ -25,12 +26,19 @@ export function renderMethylation({ ctx, feat, region, bpPerPx, renderArgs, canv
25
26
  ? colord('red').alpha((p - 0.5) * 2)
26
27
  : colord('blue').alpha(1 - p * 2)).toHslString();
27
28
  }
29
+ if (hydroxyMethBins[k]) {
30
+ const p = hydroxyMethProbs[k] || 0;
31
+ return (p > 0.5
32
+ ? colord('pink').alpha((p - 0.5) * 2)
33
+ : colord('purple').alpha(1 - p * 2)).toHslString();
34
+ }
28
35
  return undefined;
29
36
  }
37
+ const r = regionSequence.toLowerCase();
30
38
  for (let i = 0; i < fend - fstart; i++) {
31
39
  const j = i + fstart;
32
- const l1 = (_a = regionSequence[j - region.start + 1]) === null || _a === void 0 ? void 0 : _a.toLowerCase();
33
- const l2 = (_b = regionSequence[j - region.start + 2]) === null || _b === void 0 ? void 0 : _b.toLowerCase();
40
+ const l1 = r[j - region.start + 1];
41
+ const l2 = r[j - region.start + 2];
34
42
  if (l1 === 'c' && l2 === 'g') {
35
43
  if (bpPerPx > 2) {
36
44
  const [leftPx, rightPx] = bpSpanPx(j, j + 2, region, bpPerPx);
@@ -9,8 +9,8 @@ export function renderMismatches({ ctx, feat, renderArgs, minSubfeatureWidth, la
9
9
  const pxPerBp = Math.min(1 / bpPerPx, 2);
10
10
  const mismatches = feature.get('mismatches');
11
11
  const heightLim = charHeight - 2;
12
- // extraHorizontallyFlippedOffset is used to draw interbase items, which
13
- // are located to the left when forward and right when reversed
12
+ // extraHorizontallyFlippedOffset is used to draw interbase items, which are
13
+ // located to the left when forward and right when reversed
14
14
  const extraHorizontallyFlippedOffset = region.reversed ? 1 / bpPerPx + 1 : -1;
15
15
  if (!mismatches) {
16
16
  return;
@@ -22,16 +22,14 @@ export function renderMismatches({ ctx, feat, renderArgs, minSubfeatureWidth, la
22
22
  const mlen = mismatch.length;
23
23
  const mbase = mismatch.base;
24
24
  const [leftPx, rightPx] = bpSpanPx(mstart, mstart + mlen, region, bpPerPx);
25
- const widthPx = Math.max(minSubfeatureWidth, Math.abs(leftPx - rightPx));
25
+ const widthPx = Math.max(minSubfeatureWidth, rightPx - leftPx);
26
26
  if (mismatch.type === 'mismatch') {
27
27
  if (!drawSNPsMuted) {
28
28
  const baseColor = colorForBase[mismatch.base] || '#888';
29
- const c = mismatchAlpha
30
- ? mismatch.qual === undefined
31
- ? baseColor
32
- : colord(baseColor)
33
- .alpha(Math.min(1, mismatch.qual / 50))
34
- .toHslString()
29
+ const c = mismatchAlpha && mismatch.qual !== undefined
30
+ ? colord(baseColor)
31
+ .alpha(Math.min(1, mismatch.qual / 50))
32
+ .toHslString()
35
33
  : baseColor;
36
34
  fillRect(ctx, Math.round(leftPx), topPx, widthPx, heightPx, canvasWidth, c);
37
35
  }
@@ -40,13 +38,12 @@ export function renderMismatches({ ctx, feat, renderArgs, minSubfeatureWidth, la
40
38
  const contrastColor = drawSNPsMuted
41
39
  ? 'black'
42
40
  : contrastForBase[mismatch.base] || 'black';
43
- ctx.fillStyle = mismatchAlpha
44
- ? mismatch.qual === undefined
45
- ? contrastColor
46
- : colord(contrastColor)
41
+ ctx.fillStyle =
42
+ mismatchAlpha && mismatch.qual !== undefined
43
+ ? colord(contrastColor)
47
44
  .alpha(Math.min(1, mismatch.qual / 50))
48
45
  .toHslString()
49
- : contrastColor;
46
+ : contrastColor;
50
47
  ctx.fillText(mbase, leftPx + (widthPx - charWidth) / 2 + 1, topPx + heightPx);
51
48
  }
52
49
  }
@@ -60,7 +57,6 @@ export function renderMismatches({ ctx, feat, renderArgs, minSubfeatureWidth, la
60
57
  }
61
58
  }
62
59
  else if (mismatch.type === 'insertion' && drawIndels) {
63
- ctx.fillStyle = 'purple';
64
60
  const pos = leftPx + extraHorizontallyFlippedOffset;
65
61
  const len = +mismatch.base || mismatch.length;
66
62
  const insW = Math.max(0, Math.min(1.2, 1 / bpPerPx));
@@ -89,12 +85,16 @@ export function renderMismatches({ ctx, feat, renderArgs, minSubfeatureWidth, la
89
85
  else if (mismatch.type === 'skip') {
90
86
  // fix to avoid bad rendering note that this was also related to chrome
91
87
  // bug https://bugs.chromium.org/p/chromium/issues/detail?id=1131528
88
+ //
92
89
  // also affected firefox ref #1236 #2750
93
90
  if (leftPx + widthPx > 0) {
94
91
  // make small exons more visible when zoomed far out
95
92
  const adjustPx = widthPx - (bpPerPx > 10 ? 1.5 : 0);
96
- ctx.clearRect(leftPx, topPx, adjustPx, heightPx);
97
- fillRect(ctx, Math.max(0, leftPx), topPx + heightPx / 2 - 1, adjustPx + Math.min(leftPx, 0), 2, canvasWidth, '#333');
93
+ const l = Math.max(0, leftPx);
94
+ const t = topPx + heightPx / 2 - 1;
95
+ const w = adjustPx + Math.min(leftPx, 0);
96
+ const h = 1;
97
+ fillRect(ctx, l, t, w, h, canvasWidth, 'rgb(151,184,201)');
98
98
  }
99
99
  }
100
100
  }
@@ -103,10 +103,10 @@ export function renderMismatches({ ctx, feat, renderArgs, minSubfeatureWidth, la
103
103
  for (const mismatch of mismatches) {
104
104
  const mstart = start + mismatch.start;
105
105
  const mlen = mismatch.length;
106
- const [leftPx] = bpSpanPx(mstart, mstart + mlen, region, bpPerPx);
107
106
  const len = +mismatch.base || mismatch.length;
108
- const txt = `${len}`;
109
107
  if (mismatch.type === 'insertion' && len >= 10) {
108
+ const [leftPx] = bpSpanPx(mstart, mstart + mlen, region, bpPerPx);
109
+ const txt = `${len}`;
110
110
  if (bpPerPx > largeInsertionIndicatorScale) {
111
111
  fillRect(ctx, leftPx - 1, topPx, 2, heightPx, canvasWidth, 'purple');
112
112
  }
@@ -1,11 +1,12 @@
1
- import { Region } from '@jbrowse/core/util';
1
+ import type { Region } from '@jbrowse/core/util';
2
2
  import { LayoutFeature } from './util';
3
3
  import { RenderArgsWithColor } from './makeImageData';
4
- export declare function renderModifications({ ctx, feat, region, bpPerPx, renderArgs, canvasWidth, }: {
4
+ export declare function renderModifications({ ctx, feat, region, bpPerPx, renderArgs, canvasWidth, cigarOps, }: {
5
5
  ctx: CanvasRenderingContext2D;
6
6
  feat: LayoutFeature;
7
7
  region: Region;
8
8
  bpPerPx: number;
9
9
  renderArgs: RenderArgsWithColor;
10
10
  canvasWidth: number;
11
+ cigarOps: string[];
11
12
  }): void;