notations 0.0.63 → 0.0.65

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.
@@ -1 +1 @@
1
- {"version":3,"file":"cycle.js","sourceRoot":"","sources":["../../src/cycle.ts"],"names":[],"mappings":"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","sourcesContent":["import * as TSU from \"@panyam/tsutils\";\nimport { Entity, TimedEntity } from \"./entity\";\n\n/**\n * Alias to TSU.Num.Fraction in tsutils.\n */\ntype Fraction = TSU.Num.Fraction;\nexport type CyclePosition = [number, number, number];\nexport type CycleIterator = Generator<[CyclePosition, Fraction]>;\n\nconst ZERO = TSU.Num.Fraction.ZERO;\nconst ONE = TSU.Num.Fraction.ONE;\n\nexport class CycleCursor {\n constructor(public readonly cycle: Cycle, public barIndex = 0, public beatIndex = 0, public instance = 0) {}\n\n get next(): [CyclePosition, Fraction] {\n const currBar = this.cycle.bars[this.barIndex];\n const result: [CyclePosition, Fraction] = [\n [this.barIndex, this.beatIndex, this.instance],\n currBar.beatLengths[this.beatIndex],\n ];\n this.instance++;\n if (!currBar.beatCounts[this.beatIndex] || this.instance >= currBar.beatCounts[this.beatIndex]) {\n this.instance = 0;\n this.beatIndex++;\n if (this.beatIndex >= currBar.beatLengths.length) {\n this.beatIndex = 0;\n this.barIndex++;\n if (this.barIndex >= this.cycle.bars.length) {\n this.barIndex = 0;\n }\n }\n }\n return result;\n }\n\n get prev(): [CyclePosition, Fraction] {\n const currBar = this.cycle.bars[this.barIndex];\n const result: [CyclePosition, Fraction] = [\n [this.barIndex, this.beatIndex, this.instance],\n currBar.beatLengths[this.beatIndex],\n ];\n // TODO - result should be set *after* decrementing if we had already\n // done a \"next\" before this otherwise user may have to do a prev twice\n this.instance--;\n if (this.instance < 0) {\n this.beatIndex--;\n if (this.beatIndex < 0) {\n this.barIndex--;\n if (this.barIndex < 0) {\n this.barIndex = this.cycle.bars.length - 1;\n }\n this.beatIndex = this.cycle.bars[this.barIndex].beatCount - 1;\n }\n this.instance = (this.cycle.bars[this.barIndex].beatCounts[this.beatIndex] || 1) - 1;\n }\n return result;\n }\n}\n\nexport class Bar extends TimedEntity {\n readonly TYPE: string = \"Bar\";\n\n name: string;\n // Length/Duration of each beat.\n beatLengths: Fraction[] = [];\n\n // How many times should a beat be repeated - the Kalai!\n beatCounts: number[] = [];\n\n constructor(config: any = null) {\n super((config = config || {}));\n this.name = config.name || \"\";\n for (const bl of config.beatLengths || []) {\n if (typeof bl === \"number\") {\n this.beatLengths.push(TSU.Num.Frac(bl));\n } else {\n this.beatLengths.push(bl);\n }\n }\n for (const bc of config.beatCounts || []) {\n this.beatCounts.push(bc);\n }\n while (this.beatCounts.length < this.beatLengths.length) {\n this.beatCounts.push(1);\n }\n }\n\n debugValue(): any {\n return { ...super.debugValue(), name: name, beatLengths: this.beatLengths };\n }\n\n equals(another: this): boolean {\n if (!super.equals(another)) return false;\n if (this.beatLengths.length != another.beatLengths.length) return false;\n if (this.beatCounts.length != another.beatCounts.length) return false;\n for (let i = 0; i < this.beatLengths.length; i++) {\n if (!this.beatLengths[i].equals(another.beatLengths[i])) return false;\n }\n for (let i = 0; i < this.beatCounts.length; i++) {\n if (this.beatCounts[i] != another.beatCounts[i]) return false;\n }\n return true;\n }\n\n copyTo(another: this): void {\n super.copyTo(another);\n another.name = this.name;\n another.beatLengths = [...this.beatLengths];\n another.beatCounts = [...this.beatCounts];\n }\n\n instanceCount(beatIndex: number): number {\n if (beatIndex > this.beatCounts.length) {\n // by default each beat has 1 instance?\n return 1;\n } else {\n return this.beatCounts[beatIndex];\n }\n }\n\n get beatCount(): number {\n return this.beatLengths.length;\n }\n\n get totalBeatCount(): number {\n let out = 0;\n for (let i = 0; i < this.beatLengths.length; i++) {\n out += this.beatCounts[i] || 1;\n }\n return out;\n }\n\n /**\n * Total duration (of time) across all beats in this bar.\n */\n get duration(): Fraction {\n let total = ZERO;\n for (let i = 0; i < this.beatLengths.length; i++) {\n total = total.plus(this.beatLengths[i].timesNum(this.beatCounts[i] || 1));\n }\n return total;\n }\n}\n\n// Describes the cycle pattern\nexport class Cycle extends TimedEntity {\n readonly TYPE: string = \"Cycle\";\n\n name: string;\n bars: Bar[];\n\n static readonly DEFAULT = new Cycle({\n name: \"Adi Thalam\",\n bars: [\n new Bar({ name: \"Laghu\", beatLengths: [1, 1, 1, 1] }),\n new Bar({ name: \"Dhrutam\", beatLengths: [1, 1] }),\n new Bar({ name: \"Dhrutam\", beatLengths: [1, 1] }),\n ],\n });\n\n constructor(config: null | { name?: string; bars?: Bar[] } = null) {\n super((config = config || {}));\n this.name = config.name || \"\";\n this.bars = config.bars || [];\n }\n\n debugValue(): any {\n return { ...super.debugValue(), name: name, bars: this.bars.map((p) => p.debugValue()) };\n }\n\n children(): Entity[] {\n return this.bars;\n }\n\n equals(another: this): boolean {\n if (!super.equals(another)) {\n return false;\n }\n if (this.bars.length != another.bars.length) return false;\n for (let i = 0; i < this.bars.length; i++) {\n if (!this.bars[i].equals(another.bars[i])) return false;\n }\n return true;\n }\n\n /**\n * Given a global beat index returns four values [cycle,bar,beat,instance] where:\n *\n * cycle - The nth cycle in which the beat lies. Since the global beat\n * index can be greater the number of beats in this cycle this\n * allows us to wrap around. Similarly if beatindex is less than\n * 0 then we can also go behind a cycle.\n * bar - The mth bar in the nth cycle which the offset exists\n * beat - The beat within the mth bar in the nth cycle where the\n * offset lies\n * instance - The beat instance where the offset lies.\n * startOffset - Offset of the beat at this global index.\n */\n getAtIndex(globalIndex: number): [number, CyclePosition, Fraction] {\n let cycle = 0;\n while (globalIndex < 0) {\n globalIndex += this.totalBeatCount;\n cycle--;\n }\n if (globalIndex >= this.totalBeatCount) {\n cycle = Math.floor(globalIndex / this.totalBeatCount);\n }\n globalIndex = globalIndex % this.totalBeatCount;\n let offset = ZERO;\n for (let barIndex = 0; barIndex < this.bars.length; barIndex++) {\n const bar = this.bars[barIndex];\n if (globalIndex >= bar.totalBeatCount) {\n globalIndex -= bar.totalBeatCount;\n offset = offset.plus(bar.duration);\n } else {\n // this is the bar!\n for (let beatIndex = 0; beatIndex < bar.beatCount; beatIndex++) {\n const beatLength = bar.beatLengths[beatIndex];\n const beatCount = bar.beatCounts[beatIndex] || 1;\n if (globalIndex >= beatCount) {\n globalIndex -= beatCount;\n offset = offset.plus(beatLength.timesNum(beatCount));\n } else {\n // this is it\n const instance = globalIndex;\n return [cycle, [barIndex, beatIndex, instance], offset.plus(beatLength.timesNum(instance))];\n }\n }\n }\n }\n throw new Error(\"Should not be here!\");\n }\n\n /**\n * Given a global offset returns five values [cycle, bar,beat,instance,offset] where:\n *\n * cycle - The nth cycle in which the beat lies. Since the global offset can be\n * greater the duration of the cycle this allows us to wrap around.\n * Similarly if globalOffset is less than 0 then we can also go behind a cycle.\n * bar - The mth bar in the nth cycle which the offset exists\n * beat - The beat within the mth bar in the nth cycle where the offset lies\n * instance - The beat instance where the offset lies.\n * startOffset - The note offset within the beat where the global offset lies.\n * globalIndex - The beat index within the entire cycle and not just within the bar.\n */\n getPosition(globalOffset: Fraction): [number, CyclePosition, Fraction, number] {\n const duration = this.duration;\n let cycleNum = 0;\n if (globalOffset.isLT(ZERO)) {\n while (globalOffset.isLT(ZERO)) {\n cycleNum--;\n globalOffset = globalOffset.plus(duration);\n }\n } else if (globalOffset.isGTE(duration)) {\n const realOffset = globalOffset.mod(duration);\n globalOffset = globalOffset.minus(realOffset).divby(duration);\n TSU.assert(globalOffset.isWhole);\n cycleNum = globalOffset.floor;\n globalOffset = realOffset;\n }\n\n // here globalOffset is positive and >= 0 and < this.duration\n let globalIndex = 0;\n for (let barIndex = 0; barIndex < this.bars.length; barIndex++) {\n const bar = this.bars[barIndex];\n const barDuration = bar.duration;\n if (globalOffset.isGTE(barDuration)) {\n globalOffset = globalOffset.minus(barDuration);\n } else {\n // this is the bar!\n for (let beatIndex = 0; beatIndex < bar.beatCount; beatIndex++) {\n const beatLength = bar.beatLengths[beatIndex];\n const beatCount = bar.beatCounts[beatIndex] || 1;\n for (let instance = 0; instance < beatCount; instance++, globalIndex++) {\n if (globalOffset.isGTE(beatLength)) {\n globalOffset = globalOffset.minus(beatLength);\n } else {\n // this is it\n return [cycleNum, [barIndex, beatIndex, instance], globalOffset, globalIndex];\n }\n }\n }\n }\n globalIndex += bar.totalBeatCount;\n }\n\n throw new Error(\"Should not be here!\");\n }\n\n *iterateBeats(startBar = 0, startBeat = 0, startInstance = 0): CycleIterator {\n let barIndex = startBar;\n let beatIndex = startBeat;\n let instanceIndex = startInstance;\n while (true) {\n const currBar = this.bars[barIndex];\n yield [[barIndex, beatIndex, instanceIndex], currBar.beatLengths[beatIndex]];\n instanceIndex++;\n if (!currBar.beatCounts[beatIndex] || instanceIndex >= currBar.beatCounts[beatIndex]) {\n instanceIndex = 0;\n beatIndex++;\n if (beatIndex >= currBar.beatLengths.length) {\n beatIndex = 0;\n barIndex++;\n if (barIndex >= this.bars.length) {\n barIndex = 0;\n }\n }\n }\n }\n }\n\n copyTo(another: this): void {\n super.copyTo(another);\n another.name = this.name;\n another.bars = this.bars.map((x) => x.clone());\n }\n\n get beatCount(): number {\n let out = 0;\n for (const bar of this.bars) out += bar.beatCount;\n return out;\n }\n\n get totalBeatCount(): number {\n let out = 0;\n for (const bar of this.bars) out += bar.totalBeatCount;\n return out;\n }\n\n /**\n * Total duration (of time) across all bars in this cycle.\n */\n get duration(): Fraction {\n return this.bars.reduce((x, y) => x.plus(y.duration), ZERO);\n }\n}\n"]}
1
+ {"version":3,"file":"cycle.js","sourceRoot":"","sources":["../../src/cycle.ts"],"names":[],"mappings":"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","sourcesContent":["import * as TSU from \"@panyam/tsutils\";\nimport { Entity, TimedEntity } from \"./entity\";\n\n/**\n * Alias to TSU.Num.Fraction in tsutils.\n */\ntype Fraction = TSU.Num.Fraction;\nexport type CyclePosition = [number, number, number];\nexport type CycleIterator = Generator<[CyclePosition, Fraction]>;\n\nconst ZERO = TSU.Num.Fraction.ZERO;\nconst ONE = TSU.Num.Fraction.ONE;\n\n/**\n * A cursor that traverses through a Cycle's beats in a controlled manner.\n * Allows forward and backward navigation through the cycle.\n */\nexport class CycleCursor {\n /**\n * Creates a new CycleCursor.\n * @param cycle The Cycle to traverse\n * @param barIndex The starting bar index, defaults to 0\n * @param beatIndex The starting beat index within the bar, defaults to 0\n * @param instance The starting instance index within the beat, defaults to 0\n */\n constructor(public readonly cycle: Cycle, public barIndex = 0, public beatIndex = 0, public instance = 0) {}\n\n /**\n * Advances the cursor to the next beat and returns the current position and beat length.\n * @returns A tuple containing the current position and beat length\n */\n get next(): [CyclePosition, Fraction] {\n const currBar = this.cycle.bars[this.barIndex];\n const result: [CyclePosition, Fraction] = [\n [this.barIndex, this.beatIndex, this.instance],\n currBar.beatLengths[this.beatIndex],\n ];\n this.instance++;\n if (!currBar.beatCounts[this.beatIndex] || this.instance >= currBar.beatCounts[this.beatIndex]) {\n this.instance = 0;\n this.beatIndex++;\n if (this.beatIndex >= currBar.beatLengths.length) {\n this.beatIndex = 0;\n this.barIndex++;\n if (this.barIndex >= this.cycle.bars.length) {\n this.barIndex = 0;\n }\n }\n }\n return result;\n }\n\n /**\n * Moves the cursor to the previous beat and returns the current position and beat length.\n * @returns A tuple containing the current position and beat length\n */\n get prev(): [CyclePosition, Fraction] {\n const currBar = this.cycle.bars[this.barIndex];\n const result: [CyclePosition, Fraction] = [\n [this.barIndex, this.beatIndex, this.instance],\n currBar.beatLengths[this.beatIndex],\n ];\n // TODO - result should be set *after* decrementing if we had already\n // done a \"next\" before this otherwise user may have to do a prev twice\n this.instance--;\n if (this.instance < 0) {\n this.beatIndex--;\n if (this.beatIndex < 0) {\n this.barIndex--;\n if (this.barIndex < 0) {\n this.barIndex = this.cycle.bars.length - 1;\n }\n this.beatIndex = this.cycle.bars[this.barIndex].beatCount - 1;\n }\n this.instance = (this.cycle.bars[this.barIndex].beatCounts[this.beatIndex] || 1) - 1;\n }\n return result;\n }\n}\n\n/**\n * Represents a bar in a musical cycle.\n * A bar consists of beats with specific lengths and counts.\n */\nexport class Bar extends TimedEntity {\n readonly TYPE: string = \"Bar\";\n\n /** Name of the bar (e.g., \"Laghu\", \"Dhrutam\") */\n name: string;\n \n /** Length/Duration of each beat in the bar */\n beatLengths: Fraction[] = [];\n\n /** How many times each beat should be repeated (the Kalai) */\n beatCounts: number[] = [];\n\n /**\n * Creates a new Bar.\n * @param config Configuration object containing name, beatLengths, and beatCounts\n */\n constructor(config: any = null) {\n super((config = config || {}));\n this.name = config.name || \"\";\n for (const bl of config.beatLengths || []) {\n if (typeof bl === \"number\") {\n this.beatLengths.push(TSU.Num.Frac(bl));\n } else {\n this.beatLengths.push(bl);\n }\n }\n for (const bc of config.beatCounts || []) {\n this.beatCounts.push(bc);\n }\n while (this.beatCounts.length < this.beatLengths.length) {\n this.beatCounts.push(1);\n }\n }\n\n /**\n * Returns a debug-friendly representation of this Bar.\n * @returns An object containing debug information\n */\n debugValue(): any {\n return { ...super.debugValue(), name: name, beatLengths: this.beatLengths };\n }\n\n /**\n * Checks if this Bar is equal to another Bar.\n * @param another The Bar to compare with\n * @returns True if the Bars are equal, false otherwise\n */\n equals(another: this): boolean {\n if (!super.equals(another)) return false;\n if (this.beatLengths.length != another.beatLengths.length) return false;\n if (this.beatCounts.length != another.beatCounts.length) return false;\n for (let i = 0; i < this.beatLengths.length; i++) {\n if (!this.beatLengths[i].equals(another.beatLengths[i])) return false;\n }\n for (let i = 0; i < this.beatCounts.length; i++) {\n if (this.beatCounts[i] != another.beatCounts[i]) return false;\n }\n return true;\n }\n\n /**\n * Copies the properties of this Bar to another Bar.\n * @param another The target Bar to copy properties to\n */\n copyTo(another: this): void {\n super.copyTo(another);\n another.name = this.name;\n another.beatLengths = [...this.beatLengths];\n another.beatCounts = [...this.beatCounts];\n }\n\n /**\n * Gets the instance count for a specific beat in the bar.\n * @param beatIndex The index of the beat\n * @returns The number of instances for the specified beat\n */\n instanceCount(beatIndex: number): number {\n if (beatIndex > this.beatCounts.length) {\n // by default each beat has 1 instance?\n return 1;\n } else {\n return this.beatCounts[beatIndex];\n }\n }\n\n /**\n * Gets the number of unique beats in this bar (irrespective of instances).\n */\n get beatCount(): number {\n return this.beatLengths.length;\n }\n\n /**\n * Gets the total number of beat instances in this bar.\n */\n get totalBeatCount(): number {\n let out = 0;\n for (let i = 0; i < this.beatLengths.length; i++) {\n out += this.beatCounts[i] || 1;\n }\n return out;\n }\n\n /**\n * Gets the total duration of time across all beats in this bar.\n */\n get duration(): Fraction {\n let total = ZERO;\n for (let i = 0; i < this.beatLengths.length; i++) {\n total = total.plus(this.beatLengths[i].timesNum(this.beatCounts[i] || 1));\n }\n return total;\n }\n}\n\n/**\n * Represents a complete rhythmic cycle pattern composed of bars.\n * In carnatic music, this typically represents a tala.\n */\nexport class Cycle extends TimedEntity {\n readonly TYPE: string = \"Cycle\";\n\n /** Name of the cycle (e.g., \"Adi Thalam\") */\n name: string;\n \n /** The bars that make up this cycle */\n bars: Bar[];\n\n /**\n * Default cycle representing Adi Thalam (4+2+2 structure).\n */\n static readonly DEFAULT = new Cycle({\n name: \"Adi Thalam\",\n bars: [\n new Bar({ name: \"Laghu\", beatLengths: [1, 1, 1, 1] }),\n new Bar({ name: \"Dhrutam\", beatLengths: [1, 1] }),\n new Bar({ name: \"Dhrutam\", beatLengths: [1, 1] }),\n ],\n });\n\n /**\n * Creates a new Cycle.\n * @param config Configuration object containing name and bars\n */\n constructor(config: null | { name?: string; bars?: Bar[] } = null) {\n super((config = config || {}));\n this.name = config.name || \"\";\n this.bars = config.bars || [];\n }\n\n /**\n * Returns a debug-friendly representation of this Cycle.\n * @returns An object containing debug information\n */\n debugValue(): any {\n return { ...super.debugValue(), name: name, bars: this.bars.map((p) => p.debugValue()) };\n }\n\n /**\n * Gets all child entities of this Cycle.\n * @returns An array of child entities (bars)\n */\n children(): Entity[] {\n return this.bars;\n }\n\n /**\n * Checks if this Cycle is equal to another Cycle.\n * @param another The Cycle to compare with\n * @returns True if the Cycles are equal, false otherwise\n */\n equals(another: this): boolean {\n if (!super.equals(another)) {\n return false;\n }\n if (this.bars.length != another.bars.length) return false;\n for (let i = 0; i < this.bars.length; i++) {\n if (!this.bars[i].equals(another.bars[i])) return false;\n }\n return true;\n }\n\n /**\n * Given a global beat index, returns the position within the cycle.\n * \n * @param globalIndex The global beat index\n * @returns A tuple containing [cycle number, position, start offset]\n * - cycle: The nth cycle in which the beat lies\n * - position: [barIndex, beatIndex, instance] within the cycle\n * - startOffset: Offset of the beat at this global index\n */\n getAtIndex(globalIndex: number): [number, CyclePosition, Fraction] {\n let cycle = 0;\n while (globalIndex < 0) {\n globalIndex += this.totalBeatCount;\n cycle--;\n }\n if (globalIndex >= this.totalBeatCount) {\n cycle = Math.floor(globalIndex / this.totalBeatCount);\n }\n globalIndex = globalIndex % this.totalBeatCount;\n let offset = ZERO;\n for (let barIndex = 0; barIndex < this.bars.length; barIndex++) {\n const bar = this.bars[barIndex];\n if (globalIndex >= bar.totalBeatCount) {\n globalIndex -= bar.totalBeatCount;\n offset = offset.plus(bar.duration);\n } else {\n // this is the bar!\n for (let beatIndex = 0; beatIndex < bar.beatCount; beatIndex++) {\n const beatLength = bar.beatLengths[beatIndex];\n const beatCount = bar.beatCounts[beatIndex] || 1;\n if (globalIndex >= beatCount) {\n globalIndex -= beatCount;\n offset = offset.plus(beatLength.timesNum(beatCount));\n } else {\n // this is it\n const instance = globalIndex;\n return [cycle, [barIndex, beatIndex, instance], offset.plus(beatLength.timesNum(instance))];\n }\n }\n }\n }\n throw new Error(\"Should not be here!\");\n }\n\n /**\n * Given a global offset, returns the position within the cycle.\n * \n * @param globalOffset The global time offset\n * @returns A tuple containing [cycle number, position, note offset, global index]\n * - cycle: The nth cycle in which the offset lies\n * - position: [barIndex, beatIndex, instance] within the cycle\n * - startOffset: The note offset within the beat\n * - globalIndex: The beat index within the entire cycle\n */\n getPosition(globalOffset: Fraction): [number, CyclePosition, Fraction, number] {\n const duration = this.duration;\n let cycleNum = 0;\n if (globalOffset.isLT(ZERO)) {\n while (globalOffset.isLT(ZERO)) {\n cycleNum--;\n globalOffset = globalOffset.plus(duration);\n }\n } else if (globalOffset.isGTE(duration)) {\n const realOffset = globalOffset.mod(duration);\n globalOffset = globalOffset.minus(realOffset).divby(duration);\n TSU.assert(globalOffset.isWhole);\n cycleNum = globalOffset.floor;\n globalOffset = realOffset;\n }\n\n // here globalOffset is positive and >= 0 and < this.duration\n let globalIndex = 0;\n for (let barIndex = 0; barIndex < this.bars.length; barIndex++) {\n const bar = this.bars[barIndex];\n const barDuration = bar.duration;\n if (globalOffset.isGTE(barDuration)) {\n globalOffset = globalOffset.minus(barDuration);\n } else {\n // this is the bar!\n for (let beatIndex = 0; beatIndex < bar.beatCount; beatIndex++) {\n const beatLength = bar.beatLengths[beatIndex];\n const beatCount = bar.beatCounts[beatIndex] || 1;\n for (let instance = 0; instance < beatCount; instance++, globalIndex++) {\n if (globalOffset.isGTE(beatLength)) {\n globalOffset = globalOffset.minus(beatLength);\n } else {\n // this is it\n return [cycleNum, [barIndex, beatIndex, instance], globalOffset, globalIndex];\n }\n }\n }\n }\n globalIndex += bar.totalBeatCount;\n }\n\n throw new Error(\"Should not be here!\");\n }\n\n /**\n * Creates an iterator that yields beats in sequence from a starting position.\n * \n * @param startBar The starting bar index, defaults to 0\n * @param startBeat The starting beat index, defaults to 0\n * @param startInstance The starting instance index, defaults to 0\n * @returns A generator that yields [position, beat length] pairs\n */\n *iterateBeats(startBar = 0, startBeat = 0, startInstance = 0): CycleIterator {\n let barIndex = startBar;\n let beatIndex = startBeat;\n let instanceIndex = startInstance;\n while (true) {\n const currBar = this.bars[barIndex];\n yield [[barIndex, beatIndex, instanceIndex], currBar.beatLengths[beatIndex]];\n instanceIndex++;\n if (!currBar.beatCounts[beatIndex] || instanceIndex >= currBar.beatCounts[beatIndex]) {\n instanceIndex = 0;\n beatIndex++;\n if (beatIndex >= currBar.beatLengths.length) {\n beatIndex = 0;\n barIndex++;\n if (barIndex >= this.bars.length) {\n barIndex = 0;\n }\n }\n }\n }\n }\n\n /**\n * Copies the properties of this Cycle to another Cycle.\n * @param another The target Cycle to copy properties to\n */\n copyTo(another: this): void {\n super.copyTo(another);\n another.name = this.name;\n another.bars = this.bars.map((x) => x.clone());\n }\n\n /**\n * Gets the number of unique beats in this cycle (irrespective of instances).\n */\n get beatCount(): number {\n let out = 0;\n for (const bar of this.bars) out += bar.beatCount;\n return out;\n }\n\n /**\n * Gets the total number of beat instances in this cycle.\n */\n get totalBeatCount(): number {\n let out = 0;\n for (const bar of this.bars) out += bar.totalBeatCount;\n return out;\n }\n\n /**\n * Gets the total duration of time across all bars in this cycle.\n */\n get duration(): Fraction {\n return this.bars.reduce((x, y) => x.plus(y.duration), ZERO);\n }\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"entity.js","sourceRoot":"","sources":["../../src/entity.ts"],"names":[],"mappings":";;;AAMA,MAAa,MAAM;IASjB,YAAY,SAAc,IAAI;QARrB,SAAI,GAAW,QAAQ,CAAC;QAIxB,SAAI,GAAG,MAAM,CAAC,OAAO,EAAE,CAAC;QAK/B,MAAM,GAAG,MAAM,IAAI,EAAE,CAAC;QACtB,IAAI,MAAM,CAAC,QAAQ;YAAE,MAAM,IAAI,KAAK,CAAC,oCAAoC,CAAC,CAAC;IAE7E,CAAC;IAMD,UAAU;QAER,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC;IAC7B,CAAC;IAKD,QAAQ;QACN,OAAO,EAAE,CAAC;IACZ,CAAC;IAKD,IAAI,UAAU;QACZ,OAAO,IAAI,CAAC,QAAQ,EAAE,CAAC,MAAM,CAAC;IAChC,CAAC;IAOD,QAAQ,CAAC,KAAa,EAAE,KAAK,GAAG,CAAC,CAAC;QAChC,IAAI,KAAK,GAAG,CAAC,EAAE,CAAC;YACd,IAAI,CAAC,QAAQ,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC9B,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,QAAQ,EAAE,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,EAAE,KAAK,CAAC,CAAC;QAC1C,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAKD,OAAO,CAAC,KAAa;QACnB,OAAO,IAAI,CAAC,QAAQ,EAAE,CAAC,KAAK,CAAC,CAAC;IAChC,CAAC;IAOD,YAAY,CAAC,MAAc;QACzB,IAAI,CAAC,GAAG,CAAC,CAAC;QACV,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,QAAQ,EAAE,EAAE,CAAC;YACpC,IAAI,KAAK,IAAI,MAAM;gBAAE,OAAO,CAAC,CAAC;YAC9B,CAAC,EAAE,CAAC;QACN,CAAC;QACD,OAAO,CAAC,CAAC,CAAC;IACZ,CAAC;IAED,aAAa,CAAC,KAAa;QACzB,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC;QACjC,MAAM,GAAG,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;QAC5B,QAAQ,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;QAC1B,OAAO,GAAG,CAAC;IACb,CAAC;IAED,UAAU,CAAC,KAAa,EAAE,MAAc;QACtC,IAAI,CAAC,QAAQ,EAAE,CAAC,KAAK,CAAC,GAAG,MAAM,CAAC;QAChC,OAAO,IAAI,CAAC;IACd,CAAC;IAsBD,QAAQ;QACN,OAAO,eAAe,IAAI,CAAC,IAAI,GAAG,CAAC;IACrC,CAAC;IAED,MAAM,CAAC,OAAa,EAAE,MAAM,GAAG,KAAK;QAClC,IAAI,IAAI,CAAC,IAAI,IAAI,OAAO,CAAC,IAAI;YAAE,OAAO,KAAK,CAAC;QAE5C,OAAO,IAAI,CAAC;IACd,CAAC;IAYD,KAAK;QACH,MAAM,GAAG,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;QAC/B,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QACjB,OAAO,GAAG,CAAC;IACb,CAAC;IAKD,MAAM,CAAC,OAAa;IAEpB,CAAC;IAKS,WAAW;QACnB,OAAO,IAAK,IAAI,CAAC,WAAmB,EAAE,CAAC;IACzC,CAAC;;AA/IH,wBAgJC;AA5IgB,cAAO,GAAG,CAAC,AAAJ,CAAK;AAkJ7B,MAAsB,WAAY,SAAQ,MAAM;IAAhD;;QACW,SAAI,GAAW,aAAa,CAAC;IAWxC,CAAC;IAHC,MAAM,CAAC,OAAa;QAClB,OAAO,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IACzE,CAAC;CACF;AAZD,kCAYC","sourcesContent":["import * as TSU from \"@panyam/tsutils\";\n\n/**\n * A common Entity base class with support for unique IDs, copying, children and\n * debug info.\n */\nexport class Entity {\n readonly TYPE: string = \"Entity\";\n\n // readonly TYPE:string = \"Entity\";\n private static counter = 0;\n readonly uuid = Entity.counter++;\n // private metadata: TSU.StringMap<any>;\n // parent: TSU.Nullable<Entity> = null;\n\n constructor(config: any = null) {\n config = config || {};\n if (config.metadata) throw new Error(\"See where metadata is being passed\");\n // this.metadata = config.metadata || {};\n }\n\n /**\n * debugValue returns information about this entity to be printed during a debug.\n * Usually overridden by children to add more debug info.\n */\n debugValue(): any {\n // if (Object.keys(this.metadata).length > 0) return { metadata: this.metadata, type: this.type };\n return { type: this.TYPE };\n }\n\n /**\n * Children of this entity.\n */\n children(): Entity[] {\n return [];\n }\n\n /**\n * Property returning the count of child entities.\n */\n get childCount(): number {\n return this.children().length;\n }\n\n /**\n * Adds a child entity at a given index.\n * @param child Child entity to be aded.\n * @param index Index where the child is to be inserted. -1 to append at the end.\n */\n addChild(child: Entity, index = -1): this {\n if (index < 0) {\n this.children().push(child);\n } else {\n this.children().splice(index, 0, child);\n }\n return this;\n }\n\n /**\n * Returns the child at a given index.\n */\n childAt(index: number): Entity {\n return this.children()[index];\n }\n\n /**\n * Returns the index of a given child entity.\n *\n * @return the index where child exists otherwise -1.\n */\n indexOfChild(entity: Entity): number {\n let i = 0;\n for (const child of this.children()) {\n if (child == entity) return i;\n i++;\n }\n return -1;\n }\n\n removeChildAt(index: number): Entity {\n const children = this.children();\n const out = children[index];\n children.splice(index, 1);\n return out;\n }\n\n setChildAt(index: number, entity: Entity): this {\n this.children()[index] = entity;\n return this;\n }\n\n /*\n setMetadata(key: string, value: any): this {\n this.metadata[key] = value;\n return this;\n }\n\n getMetadata(key: string, recurse = true): any {\n if (key in this.metadata) {\n return this.metadata[key];\n }\n if (recurse && this.parent) {\n return this.parent.getMetadata(key);\n }\n return null;\n }\n */\n\n /**\n * Simple string representation of this Entity.\n */\n toString(): string {\n return `Entity(id = ${this.uuid})`;\n }\n\n equals(another: this, expect = false): boolean {\n if (this.TYPE != another.TYPE) return false;\n // check metadata too\n return true;\n }\n\n /**\n * All entities allow cloning in a way that is specific to the entity.\n * This allows application level \"copy/pasting\" of entities. Cloning\n * is a two part process:\n *\n * * Creation of a new instance of the same type via this.newInstance()\n * * Copying of data into the new instance.\n *\n * Both of these can be overridden.\n */\n clone(): this {\n const out = this.newInstance();\n this.copyTo(out);\n return out;\n }\n\n /**\n * Copies information about this instance into another instance of the same type.\n */\n copyTo(another: this): void {\n // another.metadata = { ...this.metadata };\n }\n\n /**\n * First part of the cloning process where the instance is created.\n */\n protected newInstance(): this {\n return new (this.constructor as any)();\n }\n}\n\n/**\n * Music is all about timing! TimedEntities are base of all entities that\n * have a duration.\n */\nexport abstract class TimedEntity extends Entity {\n readonly TYPE: string = \"TimedEntity\";\n\n /**\n * Duration of this entity in beats.\n * By default entities durations are readonly\n */\n abstract get duration(): TSU.Num.Fraction;\n\n equals(another: this): boolean {\n return super.equals(another) && this.duration.equals(another.duration);\n }\n}\n"]}
1
+ {"version":3,"file":"entity.js","sourceRoot":"","sources":["../../src/entity.ts"],"names":[],"mappings":";;;AAMA,MAAa,MAAM;IAcjB,YAAY,SAAc,IAAI;QAbrB,SAAI,GAAW,QAAQ,CAAC;QAKxB,SAAI,GAAG,MAAM,CAAC,OAAO,EAAE,CAAC;QAS/B,MAAM,GAAG,MAAM,IAAI,EAAE,CAAC;QACtB,IAAI,MAAM,CAAC,QAAQ;YAAE,MAAM,IAAI,KAAK,CAAC,oCAAoC,CAAC,CAAC;IAE7E,CAAC;IAOD,UAAU;QAER,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC;IAC7B,CAAC;IAMD,QAAQ;QACN,OAAO,EAAE,CAAC;IACZ,CAAC;IAKD,IAAI,UAAU;QACZ,OAAO,IAAI,CAAC,QAAQ,EAAE,CAAC,MAAM,CAAC;IAChC,CAAC;IAQD,QAAQ,CAAC,KAAa,EAAE,KAAK,GAAG,CAAC,CAAC;QAChC,IAAI,KAAK,GAAG,CAAC,EAAE,CAAC;YACd,IAAI,CAAC,QAAQ,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC9B,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,QAAQ,EAAE,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,EAAE,KAAK,CAAC,CAAC;QAC1C,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAOD,OAAO,CAAC,KAAa;QACnB,OAAO,IAAI,CAAC,QAAQ,EAAE,CAAC,KAAK,CAAC,CAAC;IAChC,CAAC;IAOD,YAAY,CAAC,MAAc;QACzB,IAAI,CAAC,GAAG,CAAC,CAAC;QACV,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,QAAQ,EAAE,EAAE,CAAC;YACpC,IAAI,KAAK,IAAI,MAAM;gBAAE,OAAO,CAAC,CAAC;YAC9B,CAAC,EAAE,CAAC;QACN,CAAC;QACD,OAAO,CAAC,CAAC,CAAC;IACZ,CAAC;IAOD,aAAa,CAAC,KAAa;QACzB,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC;QACjC,MAAM,GAAG,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;QAC5B,QAAQ,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;QAC1B,OAAO,GAAG,CAAC;IACb,CAAC;IAQD,UAAU,CAAC,KAAa,EAAE,MAAc;QACtC,IAAI,CAAC,QAAQ,EAAE,CAAC,KAAK,CAAC,GAAG,MAAM,CAAC;QAChC,OAAO,IAAI,CAAC;IACd,CAAC;IAuBD,QAAQ;QACN,OAAO,eAAe,IAAI,CAAC,IAAI,GAAG,CAAC;IACrC,CAAC;IAQD,MAAM,CAAC,OAAa,EAAE,MAAM,GAAG,KAAK;QAClC,IAAI,IAAI,CAAC,IAAI,IAAI,OAAO,CAAC,IAAI;YAAE,OAAO,KAAK,CAAC;QAE5C,OAAO,IAAI,CAAC;IACd,CAAC;IAUD,KAAK;QACH,MAAM,GAAG,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;QAC/B,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QACjB,OAAO,GAAG,CAAC;IACb,CAAC;IAMD,MAAM,CAAC,OAAa;IAEpB,CAAC;IAMS,WAAW;QACnB,OAAO,IAAK,IAAI,CAAC,WAAmB,EAAE,CAAC;IACzC,CAAC;;AA3KH,wBA4KC;AAxKgB,cAAO,GAAG,CAAC,AAAJ,CAAK;AA8K7B,MAAsB,WAAY,SAAQ,MAAM;IAAhD;;QACW,SAAI,GAAW,aAAa,CAAC;IAgBxC,CAAC;IAHC,MAAM,CAAC,OAAa;QAClB,OAAO,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IACzE,CAAC;CACF;AAjBD,kCAiBC","sourcesContent":["import * as TSU from \"@panyam/tsutils\";\n\n/**\n * A common Entity base class with support for unique IDs, copying, children and\n * debug info. This serves as the foundation for all entities in the notation system.\n */\nexport class Entity {\n readonly TYPE: string = \"Entity\";\n\n // readonly TYPE:string = \"Entity\";\n private static counter = 0;\n /** Unique identifier for this entity */\n readonly uuid = Entity.counter++;\n // private metadata: TSU.StringMap<any>;\n // parent: TSU.Nullable<Entity> = null;\n\n /**\n * Creates a new Entity.\n * @param config Optional configuration object\n */\n constructor(config: any = null) {\n config = config || {};\n if (config.metadata) throw new Error(\"See where metadata is being passed\");\n // this.metadata = config.metadata || {};\n }\n\n /**\n * Returns a debug-friendly representation of this entity.\n * Usually overridden by children to add more debug info.\n * @returns An object containing debug information\n */\n debugValue(): any {\n // if (Object.keys(this.metadata).length > 0) return { metadata: this.metadata, type: this.type };\n return { type: this.TYPE };\n }\n\n /**\n * Gets all child entities of this entity.\n * @returns An array of child entities\n */\n children(): Entity[] {\n return [];\n }\n\n /**\n * Gets the count of child entities.\n */\n get childCount(): number {\n return this.children().length;\n }\n\n /**\n * Adds a child entity at a given index.\n * @param child Child entity to be added\n * @param index Index where the child is to be inserted, -1 to append at the end\n * @returns This entity instance for method chaining\n */\n addChild(child: Entity, index = -1): this {\n if (index < 0) {\n this.children().push(child);\n } else {\n this.children().splice(index, 0, child);\n }\n return this;\n }\n\n /**\n * Returns the child at a given index.\n * @param index The index of the child to retrieve\n * @returns The child entity at the specified index\n */\n childAt(index: number): Entity {\n return this.children()[index];\n }\n\n /**\n * Returns the index of a given child entity.\n * @param entity The child entity to find\n * @returns The index where the child exists, or -1 if not found\n */\n indexOfChild(entity: Entity): number {\n let i = 0;\n for (const child of this.children()) {\n if (child == entity) return i;\n i++;\n }\n return -1;\n }\n\n /**\n * Removes and returns the child entity at the specified index.\n * @param index The index of the child to remove\n * @returns The removed child entity\n */\n removeChildAt(index: number): Entity {\n const children = this.children();\n const out = children[index];\n children.splice(index, 1);\n return out;\n }\n\n /**\n * Sets a child entity at the specified index.\n * @param index The index where to set the child\n * @param entity The entity to set at the index\n * @returns This entity instance for method chaining\n */\n setChildAt(index: number, entity: Entity): this {\n this.children()[index] = entity;\n return this;\n }\n\n /*\n setMetadata(key: string, value: any): this {\n this.metadata[key] = value;\n return this;\n }\n\n getMetadata(key: string, recurse = true): any {\n if (key in this.metadata) {\n return this.metadata[key];\n }\n if (recurse && this.parent) {\n return this.parent.getMetadata(key);\n }\n return null;\n }\n */\n\n /**\n * Returns a simple string representation of this Entity.\n * @returns A string representation\n */\n toString(): string {\n return `Entity(id = ${this.uuid})`;\n }\n\n /**\n * Checks if this Entity is equal to another Entity.\n * @param another The Entity to compare with\n * @param expect Optional parameter\n * @returns True if the Entities are equal, false otherwise\n */\n equals(another: this, expect = false): boolean {\n if (this.TYPE != another.TYPE) return false;\n // check metadata too\n return true;\n }\n\n /**\n * Creates a clone of this entity.\n * Cloning is a two-part process:\n * 1. Creation of a new instance via this.newInstance()\n * 2. Copying of data into the new instance via this.copyTo()\n * \n * @returns A new instance of the same type with the same properties\n */\n clone(): this {\n const out = this.newInstance();\n this.copyTo(out);\n return out;\n }\n\n /**\n * Copies information about this instance into another instance of the same type.\n * @param another The target instance to copy properties to\n */\n copyTo(another: this): void {\n // another.metadata = { ...this.metadata };\n }\n\n /**\n * First part of the cloning process where the instance is created.\n * @returns A new instance of the same type\n */\n protected newInstance(): this {\n return new (this.constructor as any)();\n }\n}\n\n/**\n * Music is all about timing! TimedEntities are base of all entities that\n * have a duration. This is an abstract class that all timed entities inherit from.\n */\nexport abstract class TimedEntity extends Entity {\n readonly TYPE: string = \"TimedEntity\";\n\n /**\n * Gets the duration of this entity in terms of beats.\n * By default, entity durations are readonly.\n */\n abstract get duration(): TSU.Num.Fraction;\n\n /**\n * Checks if this TimedEntity is equal to another TimedEntity.\n * @param another The TimedEntity to compare with\n * @returns True if the TimedEntities are equal, false otherwise\n */\n equals(another: this): boolean {\n return super.equals(another) && this.duration.equals(another.duration);\n }\n}\n"]}
@@ -96,6 +96,8 @@ export declare abstract class AlignedLine {
96
96
  addSuccessor(next: this): void;
97
97
  }
98
98
  export declare class ColAlign extends AlignedLine {
99
+ paddingBefore: number;
100
+ paddingAfter: number;
99
101
  setOffset(val: number): void;
100
102
  evalMaxLength(changedCells?: GridCell[]): number;
101
103
  protected beforeAddingCell(cell: GridCell): boolean;
package/lib/cjs/grids.js CHANGED
@@ -279,8 +279,8 @@ class AlignedLine {
279
279
  this.needsLayout = false;
280
280
  this._coordOffset = 0;
281
281
  this._maxLength = 0;
282
- this.paddingBefore = 15;
283
- this.paddingAfter = 15;
282
+ this.paddingBefore = 5;
283
+ this.paddingAfter = 5;
284
284
  this.cells = [];
285
285
  this.prevLines = [];
286
286
  this.nextLines = [];
@@ -331,6 +331,11 @@ class AlignedLine {
331
331
  exports.AlignedLine = AlignedLine;
332
332
  AlignedLine.idCounter = 0;
333
333
  class ColAlign extends AlignedLine {
334
+ constructor() {
335
+ super(...arguments);
336
+ this.paddingBefore = 10;
337
+ this.paddingAfter = 10;
338
+ }
334
339
  setOffset(val) {
335
340
  this._coordOffset = val;
336
341
  for (const cell of this.cells) {
@@ -1 +1 @@
1
- {"version":3,"file":"grids.js","sourceRoot":"","sources":["../../src/grids.ts"],"names":[],"mappings":"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","sourcesContent":["import * as TSU from \"@panyam/tsutils\";\n// import * as kiwi from \"@lume/kiwi\";\n\n/**\n * A generic way to host child views in a grid (very similar to gridbag\n * layout) This allows us to have a framework for hosting BeatViews instead\n * of mucking about with beat rows and beat columns etc.\n *\n * Grid \"cells\" can be referred by cell indexes. Additionally we want our\n * grid rows and columns to have names (like in Spreadsheets) so that even\n * when rows and columns are inserted, though indexes may change, the\n * \"addresses\" will be fixed and immovable. This helps us do things like\n * insert a new new column (say for markers) and not have to worry other\n * columns index changes impacting us.\n */\nexport class GridModel extends TSU.Events.EventEmitter {\n private static idCounter = 0;\n readonly uuid = GridModel.idCounter++;\n lastUpdatedAt = 0;\n // cells = new SparseArray<SparseArray<GridCell>>();\n rows: GridRow[] = [];\n rowAligns = new Map<number, RowAlign>();\n colAligns = new Map<number, ColAlign>();\n\n debugValue() {\n const out = {\n rows: this.rows.map((r) => r.debugValue()),\n lastUpdatedAt: this.lastUpdatedAt,\n } as any;\n return out;\n }\n\n get firstRow(): number {\n for (const gr of this.rows) {\n if (gr.numCells > 0) return gr.rowIndex;\n }\n return -1;\n }\n\n get firstCol(): number {\n let minCol = -1;\n for (const gr of this.rows) {\n const fc = gr.firstCol;\n if (fc >= 0) {\n if (minCol < 0 || fc < minCol) {\n minCol = fc;\n }\n }\n }\n return minCol;\n }\n\n cellsInRow(row: number): GridCell[] {\n const out = [] as GridCell[];\n const gr = this.rows[row];\n if (gr) {\n for (const cell of gr.cells) {\n if (cell?.value) out.push(cell);\n }\n }\n return out;\n }\n\n cellsInCol(col: number): GridCell[] {\n const out = [] as GridCell[];\n for (const gr of this.rows) {\n const cell = gr.cellAt(col);\n if (cell?.value) out.push(cell);\n }\n return out;\n }\n\n addRowAlign(align: RowAlign): void {\n this.rowAligns.set(align.uuid, align);\n }\n\n addColAlign(align: ColAlign): void {\n this.colAligns.set(align.uuid, align);\n }\n\n addRows(insertBefore = -1, numRows = 1): this {\n if (insertBefore < 0) {\n insertBefore = this.rows.length;\n }\n let next = this.rows[insertBefore] || null;\n const prev = this.rows[insertBefore - 1] || null;\n for (let i = numRows - 1; i >= 0; i--) {\n const newRow = new GridRow(this, insertBefore + i);\n this.rows.splice(insertBefore, 0, newRow);\n if (next != null) {\n newRow.defaultRowAlign.addSuccessor(next.defaultRowAlign);\n }\n if (i == 0 && insertBefore > 0) {\n prev.defaultRowAlign.addSuccessor(newRow.defaultRowAlign);\n }\n next = newRow;\n }\n for (let i = insertBefore + numRows; i < this.rows.length; i++) {\n this.rows[i].rowIndex += numRows;\n }\n return this;\n }\n\n getRow(row: number): GridRow {\n if (row >= this.rows.length) {\n this.addRows(-1, 1 + row - this.rows.length);\n }\n return this.rows[row];\n }\n\n setValue(row: number, col: number, value: any, cellCreator?: (row: GridRow, col: number) => GridCell): any {\n const grow = this.getRow(row);\n if (!cellCreator) {\n cellCreator = (row: GridRow, col: number) => {\n return new GridCell(row, col);\n };\n }\n if (value == null) {\n const out = grow.clearCellAt(col);\n if (out != null) {\n this.eventHub?.emit(GridCellEvent.CLEARED, this, {\n loc: out.location,\n });\n }\n return out;\n } else {\n const cell = grow.cellAt(col, cellCreator) as GridCell;\n const oldValue = cell.value;\n this.eventHub?.emit(GridCellEvent.UPDATED, this, {\n loc: cell.location,\n cell: cell,\n oldValue: cell.value,\n });\n cell.value = value;\n return oldValue;\n }\n }\n\n protected eventHubChanged(): void {\n console.log(\"Event Hub Changed for GridModel\");\n }\n}\n\nexport interface GridCellView {\n readonly cell: GridCell;\n x: number;\n y: number;\n width: number;\n height: number;\n setBounds(\n x: number | null,\n y: number | null,\n w: number | null,\n h: number | null,\n applyLayout: boolean,\n ): [number | null, number | null, number | null, number | null];\n readonly needsLayout: boolean;\n readonly minSize: TSU.Geom.Size;\n readonly bbox: TSU.Geom.Rect;\n}\n\nexport enum GridCellEvent {\n ADDED = \"CellAdded\",\n CLEARED = \"CellCleared\",\n REMOVED = \"CellRemoved\",\n UPDATED = \"CellUpdated\",\n MOVED = \"CellMoved\",\n}\n\n/**\n * Interface for a view for a given cell in the grid.\n */\nexport class GridCell {\n private static idCounter = 0;\n readonly uuid = GridCell.idCounter++;\n cellView: GridCellView | null;\n private _rowAlign: RowAlign;\n private _colAlign: ColAlign;\n\n constructor(public gridRow: GridRow, public colIndex: number, public value: any = null) {\n this.rowAlign = gridRow.defaultRowAlign;\n }\n\n get rowAlign(): RowAlign {\n return this._rowAlign;\n }\n\n set rowAlign(val: RowAlign) {\n val.addCell(this);\n this._rowAlign = val;\n }\n\n get colAlign(): ColAlign {\n return this._colAlign;\n }\n\n set colAlign(val: ColAlign) {\n val.addCell(this);\n this._colAlign = val;\n }\n\n get location(): string {\n return this.gridRow.rowIndex + \":\" + this.colIndex;\n }\n\n get grid(): GridModel {\n return this.gridRow.grid;\n }\n\n get rowIndex(): number {\n return this.gridRow.rowIndex;\n }\n\n debugValue() {\n const out = {\n r: this.gridRow.rowIndex,\n c: this.colIndex,\n value: this.value,\n y: this.rowAlign.coordOffset,\n h: this.rowAlign.maxLength,\n } as any;\n if (this.colAlign) {\n out.x = this.colAlign.coordOffset;\n out.w = this.colAlign.maxLength;\n }\n return out;\n }\n}\n\n/**\n * Represents a row of grid cells in a GridModel\n */\nexport class GridRow {\n cells: (null | GridCell)[] = [];\n // The default vertical alignment manager for all cells in this row\n defaultRowAlign: RowAlign;\n\n constructor(public grid: GridModel, public rowIndex: number) {\n this.defaultRowAlign = new RowAlign();\n this.grid.addRowAlign(this.defaultRowAlign);\n }\n\n get firstCol() {\n for (let i = 0; i < this.cells.length; i++) {\n if (this.cells[i]?.value) {\n return i;\n }\n }\n return -1;\n }\n\n get numCols() {\n return this.cells.length;\n }\n\n /**\n * Returns the number of cells that contain values.\n */\n get numCells() {\n let i = 0;\n for (const cell of this.cells) {\n if (cell != null && cell.value != null) i++;\n }\n return i;\n }\n\n cellAt(col: number, creator?: (row: GridRow, col: number) => GridCell): GridCell | null {\n let out = this.cells[col] || null;\n if (!out && creator) {\n this.cells[col] = out = creator(this, col);\n out.gridRow = this;\n out.colIndex = col;\n if (out.rowAlign) {\n this.grid.addRowAlign(out.rowAlign);\n }\n if (out.colAlign) {\n this.grid.addColAlign(out.colAlign);\n }\n }\n return out;\n }\n\n // Clears the cell at the given column.\n // Note this is not the same as \"removing\" a cell.\n // Removing a cell needs all cells to the \"right\" to be shifted left.\n // We wont support removing yet.\n clearCellAt(col: number): GridCell | null {\n const out = this.cells[col] || null;\n if (out) {\n this.cells[col] = null;\n }\n return out;\n }\n\n debugValue() {\n return {\n r: this.rowIndex,\n cells: this.cells.filter((c) => c).map((c) => c?.debugValue()),\n };\n }\n}\n\nexport abstract class AlignedLine {\n private static idCounter = 0;\n readonly uuid = AlignedLine.idCounter++;\n needsLayout = false;\n protected _coordOffset = 0;\n protected _maxLength = 0;\n paddingBefore = 15;\n paddingAfter = 15;\n // All the cells that belong in this column\n cells: GridCell[] = [];\n getCellView: (value: any) => GridCellView;\n\n abstract setOffset(val: number): void;\n abstract evalMaxLength(changedCells: GridCell[]): number;\n\n get coordOffset(): number {\n return this._coordOffset;\n }\n\n /**\n * Return the maximum width of a particular column.\n */\n get maxLength(): number {\n return this._maxLength + this.paddingBefore + this.paddingAfter;\n }\n\n setMaxLength(length: number) {\n this._maxLength = length;\n }\n\n setPadding(before: number, after: number): void {\n if (before >= 0) {\n this.paddingBefore = before;\n }\n if (after >= 0) {\n this.paddingAfter = after;\n }\n }\n\n addCell(cell: GridCell): this {\n if (this.beforeAddingCell(cell)) {\n this.cells.push(cell);\n }\n return this;\n }\n\n protected abstract beforeAddingCell(cell: GridCell): boolean;\n\n removeCell(cell: GridCell): this {\n if (this.beforeRemovingCell(cell)) {\n for (let i = 0; i < this.cells.length; i++) {\n if (this.cells[i].uuid == cell.uuid) {\n this.cells.splice(i, 1);\n break;\n }\n }\n }\n return this;\n }\n\n protected abstract beforeRemovingCell(cell: GridCell): boolean;\n\n // The \"neighboring\" columns that depend on this column to be placed\n // before they are placed\n prevLines = [] as this[];\n nextLines = [] as this[];\n addSuccessor(next: this): void {\n // Set nextCol as a successor of this col\n // TODO - Ensure no cycles\n for (const c of this.nextLines) {\n if (c == next) return;\n }\n this.nextLines.push(next);\n next.prevLines.push(this);\n }\n\n /* TODO: Disabling only to improve test coverage as this method is\n * not used.\n * When we have mutable grids where we can insert/remove neighbors\n * we can enable this again.\n */\n /*\n removeSuccessor(next: this): void {\n // Set nextCol as a successor of this col\n // TODO - Ensure no cycles\n for (let i = 0; i < this.nextLines.length; i++) {\n if (this.nextLines[i] == next) {\n this.nextLines.splice(i, 1);\n break;\n }\n }\n for (let i = 0; i < next.prevLines.length; i++) {\n if (next.prevLines[i] == this) {\n next.prevLines.splice(i, 1);\n break;\n }\n }\n }\n */\n}\n\nexport class ColAlign extends AlignedLine {\n setOffset(val: number): void {\n this._coordOffset = val;\n for (const cell of this.cells) {\n if (cell.value) {\n const cellView = this.getCellView(cell);\n if (this._maxLength <= 0) {\n // this hasnt been evaluated yet so do it!\n this.evalMaxLength();\n }\n cellView.setBounds(val, null, this.maxLength, null, true);\n }\n }\n }\n\n evalMaxLength(changedCells: GridCell[] = []): number {\n this._maxLength = 0;\n for (const cell of this.cells) {\n if (cell.value) {\n const cellView = this.getCellView(cell);\n this._maxLength = Math.max(cellView.minSize.width, this._maxLength);\n }\n }\n return this._maxLength;\n }\n\n protected beforeAddingCell(cell: GridCell): boolean {\n if (cell.colAlign && cell.colAlign != this) {\n cell.colAlign.removeCell(cell);\n }\n return cell.colAlign != this;\n }\n\n beforeRemovingCell(cell: GridCell): boolean {\n return cell.colAlign == this;\n }\n}\n\nexport class RowAlign extends AlignedLine {\n /**\n * Sets the Y coordinate of all cells in this row.\n */\n setOffset(val: number): void {\n this._coordOffset = val;\n for (const cell of this.cells) {\n if (cell.value) {\n const cellView = this.getCellView(cell);\n if (this._maxLength <= 0) {\n // this hasnt been evaluated yet so do it!\n this.evalMaxLength();\n }\n cellView.setBounds(null, val, null, this.maxLength, true);\n }\n }\n }\n\n evalMaxLength(changedCells: GridCell[] = []): number {\n this._maxLength = 0;\n for (const cell of this.cells) {\n if (cell.value) {\n const cellView = this.getCellView(cell);\n this._maxLength = Math.max(cellView.minSize.height, this._maxLength);\n }\n }\n return this._maxLength;\n }\n\n protected beforeAddingCell(cell: GridCell): boolean {\n if (cell.rowAlign && cell.rowAlign != this) {\n cell.rowAlign.removeCell(cell);\n }\n return cell.rowAlign != this;\n }\n\n beforeRemovingCell(cell: GridCell): boolean {\n return cell.rowAlign == this;\n }\n}\n\n/**\n * The layout manager for a collection of GridViews bound by common\n * alignment objects.\n */\nexport class GridLayoutGroup {\n // rowAligns = new Map<number, RowAlign>();\n // colAligns = new Map<number, ColAlign>();\n gridModels = [] as GridModel[];\n\n private eventHandler = (event: TSU.Events.TEvent) => {\n this.applyModelEvents(event.payload);\n };\n\n addGridModel(gridModel: GridModel): boolean {\n gridModel.eventHub?.on(TSU.Events.EventHub.BATCH_EVENTS, this.eventHandler);\n this.gridModels.push(gridModel);\n return true;\n }\n\n startingRowAligns(): RowAlign[] {\n const out = [] as RowAlign[];\n const visited = {} as any;\n for (const gm of this.gridModels) {\n for (const cell of gm.cellsInRow(gm.firstRow)) {\n if (cell.rowAlign && !visited[cell.rowAlign.uuid]) {\n visited[cell.rowAlign.uuid] = true;\n out.push(cell.rowAlign);\n }\n }\n }\n return out;\n }\n\n startingColAligns(): ColAlign[] {\n const out = [] as ColAlign[];\n const visited = {} as any;\n for (const gm of this.gridModels) {\n for (const cell of gm.cellsInCol(gm.firstCol)) {\n if (cell.colAlign && !visited[cell.colAlign.uuid]) {\n visited[cell.colAlign.uuid] = true;\n out.push(cell.colAlign);\n }\n }\n }\n return out;\n }\n\n removeGridModel(gridModel: GridModel): void {\n gridModel.eventHub?.removeOn(TSU.Events.EventHub.BATCH_EVENTS, this.eventHandler);\n }\n\n getCellView: (cell: GridCell) => GridCellView;\n\n get startingRows(): RowAlign[] {\n return this.startingRowAligns();\n }\n\n get startingCols(): ColAlign[] {\n return this.startingColAligns();\n }\n\n /**\n * Forces a full refresh.\n */\n refreshLayout() {\n const changedRowAligns = {} as any;\n const changedColAligns = {} as any;\n\n for (const rowAlign of this.startingRowAligns()) {\n if (!(rowAlign.uuid in changedRowAligns)) {\n changedRowAligns[rowAlign.uuid] = {\n align: rowAlign,\n cells: [],\n };\n }\n }\n\n for (const colAlign of this.startingColAligns()) {\n if (!(colAlign.uuid in changedColAligns)) {\n changedColAligns[colAlign.uuid] = {\n align: colAlign,\n cells: [],\n };\n }\n }\n\n this.doBfsLayout(this.startingRows, changedRowAligns);\n this.doBfsLayout(this.startingCols, changedColAligns);\n }\n\n /**\n * As the grid model changes (cell content changed, cleared etc) we need\n * to refresh our layout based on this.\n * As a first step the new height and width of all changed cells is\n * evaluted to see which rows and/or columns are affected (and need to be\n * resized/repositioned).\n */\n protected applyModelEvents(events: TSU.Events.TEvent[]) {\n const [changedRowAligns, changedColAligns] = this.changesForEvents(events);\n this.doBfsLayout(this.startingRows, changedRowAligns);\n this.doBfsLayout(this.startingCols, changedColAligns);\n }\n\n protected changesForEvents(events: TSU.Events.TEvent[]): [any, any] {\n // Step 1 - topologically sort RowAligns of changed cells\n // Step 2 - topologically sort ColAligns of changed cells\n // Step 3 -\n const cellVisited = {} as any;\n const changedRowAligns = {} as any;\n const changedColAligns = {} as any;\n // Going in reverse means we only get the latest event affecting a cell\n // instead of going through every change.\n // Later on we can revisit this if the events are edge triggered instead\n // of level triggered\n for (let i = events.length - 1; i >= 0; i--) {\n const event = events[i];\n const loc = event.payload.loc;\n if (cellVisited[loc]) continue;\n cellVisited[loc] = true;\n const [row, col] = loc.split(\":\").map((x: string) => parseInt(x));\n const gridModel = event.source;\n const cell = gridModel.getRow(row).cellAt(col);\n if (cell) {\n // TODO - For now we are marking both row and col as having\n // changed for a cell. We can optimize this to only row or\n // col based on whether height or width has changed.\n if (!(cell.rowAlign.uuid in changedRowAligns)) {\n changedRowAligns[cell.rowAlign.uuid] = {\n align: cell.rowAlign,\n cells: [],\n };\n }\n changedRowAligns[cell.rowAlign.uuid][\"cells\"].push(cell);\n\n if (!(cell.colAlign.uuid in changedColAligns)) {\n changedColAligns[cell.colAlign.uuid] = {\n align: cell.colAlign,\n cells: [],\n };\n }\n changedColAligns[cell.colAlign.uuid][\"cells\"].push(cell);\n }\n }\n return [changedRowAligns, changedColAligns];\n }\n\n protected ensureGetCellView(align: AlignedLine) {\n if (!align.getCellView) {\n if (!this.getCellView) {\n return null;\n }\n align.getCellView = this.getCellView;\n }\n return align.getCellView;\n }\n\n // 1. start from the starting lines and do a BF traversal\n // 2. If a line not visited (ie laid out):\n // if it is in the changedAlign list then reval its length (w/h)\n // set its offset and length if either width or offset has changed\n // offset can be thought of changed if the preceding line's offset has changed\n // first do above for rows\n protected doBfsLayout<T extends AlignedLine>(startingLines: T[], changedAligns: any) {\n // Eval max lengths for all changed aligns\n if (!this.getCellView) return;\n for (const alignId in changedAligns) {\n const val = changedAligns[alignId];\n this.ensureGetCellView(val.align);\n val.align.evalMaxLength(val.cells);\n }\n let lineQueue = [] as [null | T, T][];\n const visitedLines = {} as any;\n for (const line of startingLines) lineQueue.push([null, line]);\n const lineOffsetChanged = {} as any;\n while (lineQueue.length > 0) {\n const nextQueue = [] as [null | T, T][];\n for (let i = 0; i < lineQueue.length; i++) {\n const [prevLineAlign, lineAlign] = lineQueue[i];\n visitedLines[lineAlign.uuid] = true;\n let newOffset = lineAlign.coordOffset;\n let lineChanged = lineAlign.uuid in changedAligns;\n if (prevLineAlign) {\n if (lineOffsetChanged[prevLineAlign.uuid]) {\n newOffset = prevLineAlign.coordOffset + prevLineAlign.maxLength;\n lineChanged = true;\n }\n }\n if (lineChanged) {\n this.ensureGetCellView(lineAlign);\n lineAlign.setOffset(newOffset);\n lineOffsetChanged[lineAlign.uuid] = true;\n }\n\n // Add next neighbors now\n for (const next of lineAlign.nextLines) {\n if (!visitedLines[next.uuid]) {\n nextQueue.push([lineAlign, next]);\n }\n }\n }\n lineQueue = nextQueue;\n }\n }\n}\n"]}
1
+ {"version":3,"file":"grids.js","sourceRoot":"","sources":["../../src/grids.ts"],"names":[],"mappings":"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","sourcesContent":["import * as TSU from \"@panyam/tsutils\";\n// import * as kiwi from \"@lume/kiwi\";\n\n/**\n * A generic grid layout system for hosting child views (similar to GridBagLayout).\n * This provides a framework for hosting BeatViews in a structured grid arrangement,\n * with support for rows, columns, and alignment.\n * \n * Grid \"cells\" can be referred to by cell indexes. Additionally, grid rows and\n * columns can have names (like in spreadsheets) so that even when rows and columns\n * are inserted, though indexes may change, the \"addresses\" remain fixed and immovable.\n */\nexport class GridModel extends TSU.Events.EventEmitter {\n private static idCounter = 0;\n readonly uuid = GridModel.idCounter++;\n /** Timestamp of the last update to this grid */\n lastUpdatedAt = 0;\n // cells = new SparseArray<SparseArray<GridCell>>();\n /** The rows in this grid */\n rows: GridRow[] = [];\n /** Mapping of row indices to row alignment objects */\n rowAligns = new Map<number, RowAlign>();\n /** Mapping of column indices to column alignment objects */\n colAligns = new Map<number, ColAlign>();\n\n /**\n * Returns a debug-friendly representation of this GridModel.\n * @returns An object containing debug information\n */\n debugValue() {\n const out = {\n rows: this.rows.map((r) => r.debugValue()),\n lastUpdatedAt: this.lastUpdatedAt,\n } as any;\n return out;\n }\n\n /**\n * Gets the index of the first non-empty row.\n * @returns The index of the first row containing cells, or -1 if none\n */\n get firstRow(): number {\n for (const gr of this.rows) {\n if (gr.numCells > 0) return gr.rowIndex;\n }\n return -1;\n }\n\n /**\n * Gets the index of the leftmost column containing cells.\n * @returns The index of the first column containing cells, or -1 if none\n */\n get firstCol(): number {\n let minCol = -1;\n for (const gr of this.rows) {\n const fc = gr.firstCol;\n if (fc >= 0) {\n if (minCol < 0 || fc < minCol) {\n minCol = fc;\n }\n }\n }\n return minCol;\n }\n\n /**\n * Gets all non-empty cells in a specific row.\n * @param row The index of the row\n * @returns An array of cells in the row\n */\n cellsInRow(row: number): GridCell[] {\n const out = [] as GridCell[];\n const gr = this.rows[row];\n if (gr) {\n for (const cell of gr.cells) {\n if (cell?.value) out.push(cell);\n }\n }\n return out;\n }\n\n /**\n * Gets all non-empty cells in a specific column.\n * @param col The index of the column\n * @returns An array of cells in the column\n */\n cellsInCol(col: number): GridCell[] {\n const out = [] as GridCell[];\n for (const gr of this.rows) {\n const cell = gr.cellAt(col);\n if (cell?.value) out.push(cell);\n }\n return out;\n }\n\n /**\n * Adds a row alignment object to the grid.\n * @param align The row alignment to add\n */\n addRowAlign(align: RowAlign): void {\n this.rowAligns.set(align.uuid, align);\n }\n\n /**\n * Adds a column alignment object to the grid.\n * @param align The column alignment to add\n */\n addColAlign(align: ColAlign): void {\n this.colAligns.set(align.uuid, align);\n }\n\n /**\n * Adds rows to the grid.\n * @param insertBefore The index before which to insert the rows, or -1 to append\n * @param numRows The number of rows to add\n * @returns This grid instance for method chaining\n */\n addRows(insertBefore = -1, numRows = 1): this {\n if (insertBefore < 0) {\n insertBefore = this.rows.length;\n }\n let next = this.rows[insertBefore] || null;\n const prev = this.rows[insertBefore - 1] || null;\n for (let i = numRows - 1; i >= 0; i--) {\n const newRow = new GridRow(this, insertBefore + i);\n this.rows.splice(insertBefore, 0, newRow);\n if (next != null) {\n newRow.defaultRowAlign.addSuccessor(next.defaultRowAlign);\n }\n if (i == 0 && insertBefore > 0) {\n prev.defaultRowAlign.addSuccessor(newRow.defaultRowAlign);\n }\n next = newRow;\n }\n for (let i = insertBefore + numRows; i < this.rows.length; i++) {\n this.rows[i].rowIndex += numRows;\n }\n return this;\n }\n\n /**\n * Gets a row at the specified index, creating it if necessary.\n * @param row The index of the row to get\n * @returns The row at the specified index\n */\n getRow(row: number): GridRow {\n if (row >= this.rows.length) {\n this.addRows(-1, 1 + row - this.rows.length);\n }\n return this.rows[row];\n }\n\n /**\n * Sets a value in a cell at the specified row and column.\n * @param row The row index\n * @param col The column index\n * @param value The value to set\n * @param cellCreator Optional function to create a custom cell\n * @returns The previous value of the cell\n */\n setValue(row: number, col: number, value: any, cellCreator?: (row: GridRow, col: number) => GridCell): any {\n const grow = this.getRow(row);\n if (!cellCreator) {\n cellCreator = (row: GridRow, col: number) => {\n return new GridCell(row, col);\n };\n }\n if (value == null) {\n const out = grow.clearCellAt(col);\n if (out != null) {\n this.eventHub?.emit(GridCellEvent.CLEARED, this, {\n loc: out.location,\n });\n }\n return out;\n } else {\n const cell = grow.cellAt(col, cellCreator) as GridCell;\n const oldValue = cell.value;\n this.eventHub?.emit(GridCellEvent.UPDATED, this, {\n loc: cell.location,\n cell: cell,\n oldValue: cell.value,\n });\n cell.value = value;\n return oldValue;\n }\n }\n\n /**\n * Handles changes to the event hub.\n */\n protected eventHubChanged(): void {\n console.log(\"Event Hub Changed for GridModel\");\n }\n}\n\n/**\n * Interface for a view associated with a grid cell.\n * GridCellView defines the contract for views that can be placed in grid cells.\n */\nexport interface GridCellView {\n /** The grid cell this view is associated with */\n readonly cell: GridCell;\n /** X-coordinate of the view */\n x: number;\n /** Y-coordinate of the view */\n y: number;\n /** Width of the view */\n width: number;\n /** Height of the view */\n height: number;\n \n /**\n * Sets the bounds of the view.\n * @param x New x-coordinate, or null to keep current value\n * @param y New y-coordinate, or null to keep current value\n * @param w New width, or null to keep current value\n * @param h New height, or null to keep current value\n * @param applyLayout Whether to apply layout immediately\n * @returns The new bounds values\n */\n setBounds(\n x: number | null,\n y: number | null,\n w: number | null,\n h: number | null,\n applyLayout: boolean,\n ): [number | null, number | null, number | null, number | null];\n \n /** Whether this view needs layout */\n readonly needsLayout: boolean;\n \n /** The minimum size this view requires */\n readonly minSize: TSU.Geom.Size;\n \n /** The bounding box of this view */\n readonly bbox: TSU.Geom.Rect;\n}\n\n/**\n * Enum defining the events that can occur on grid cells.\n */\nexport enum GridCellEvent {\n ADDED = \"CellAdded\",\n CLEARED = \"CellCleared\",\n REMOVED = \"CellRemoved\",\n UPDATED = \"CellUpdated\",\n MOVED = \"CellMoved\",\n}\n\n/**\n * Represents a cell in the grid.\n * GridCell holds a value and manages alignment with rows and columns.\n */\nexport class GridCell {\n private static idCounter = 0;\n readonly uuid = GridCell.idCounter++;\n /** The view associated with this cell */\n cellView: GridCellView | null;\n private _rowAlign: RowAlign;\n private _colAlign: ColAlign;\n\n /**\n * Creates a new GridCell.\n * @param gridRow The row this cell belongs to\n * @param colIndex The column index of this cell\n * @param value Optional initial value for the cell\n */\n constructor(public gridRow: GridRow, public colIndex: number, public value: any = null) {\n this.rowAlign = gridRow.defaultRowAlign;\n }\n\n /**\n * Gets the row alignment for this cell.\n */\n get rowAlign(): RowAlign {\n return this._rowAlign;\n }\n\n /**\n * Sets the row alignment for this cell.\n */\n set rowAlign(val: RowAlign) {\n val.addCell(this);\n this._rowAlign = val;\n }\n\n /**\n * Gets the column alignment for this cell.\n */\n get colAlign(): ColAlign {\n return this._colAlign;\n }\n\n /**\n * Sets the column alignment for this cell.\n */\n set colAlign(val: ColAlign) {\n val.addCell(this);\n this._colAlign = val;\n }\n\n /**\n * Gets the location string for this cell (rowIndex:colIndex).\n */\n get location(): string {\n return this.gridRow.rowIndex + \":\" + this.colIndex;\n }\n\n /**\n * Gets the grid this cell belongs to.\n */\n get grid(): GridModel {\n return this.gridRow.grid;\n }\n\n /**\n * Gets the row index of this cell.\n */\n get rowIndex(): number {\n return this.gridRow.rowIndex;\n }\n\n /**\n * Returns a debug-friendly representation of this GridCell.\n * @returns An object containing debug information\n */\n debugValue() {\n const out = {\n r: this.gridRow.rowIndex,\n c: this.colIndex,\n value: this.value,\n y: this.rowAlign.coordOffset,\n h: this.rowAlign.maxLength,\n } as any;\n if (this.colAlign) {\n out.x = this.colAlign.coordOffset;\n out.w = this.colAlign.maxLength;\n }\n return out;\n }\n}\n\n/**\n * Represents a row of grid cells in a GridModel.\n */\nexport class GridRow {\n /** The cells in this row */\n cells: (null | GridCell)[] = [];\n /** The default vertical alignment for all cells in this row */\n defaultRowAlign: RowAlign;\n\n /**\n * Creates a new GridRow.\n * @param grid The grid this row belongs to\n * @param rowIndex The index of this row\n */\n constructor(public grid: GridModel, public rowIndex: number) {\n this.defaultRowAlign = new RowAlign();\n this.grid.addRowAlign(this.defaultRowAlign);\n }\n\n /**\n * Gets the index of the first non-empty column in this row.\n */\n get firstCol() {\n for (let i = 0; i < this.cells.length; i++) {\n if (this.cells[i]?.value) {\n return i;\n }\n }\n return -1;\n }\n\n /**\n * Gets the number of columns in this row.\n */\n get numCols() {\n return this.cells.length;\n }\n\n /**\n * Gets the number of cells that contain values.\n */\n get numCells() {\n let i = 0;\n for (const cell of this.cells) {\n if (cell != null && cell.value != null) i++;\n }\n return i;\n }\n\n /**\n * Gets the cell at the specified column index, optionally creating it if it doesn't exist.\n * @param col The column index\n * @param creator Optional function to create the cell if it doesn't exist\n * @returns The cell at the specified index, or null if it doesn't exist and no creator was provided\n */\n cellAt(col: number, creator?: (row: GridRow, col: number) => GridCell): GridCell | null {\n let out = this.cells[col] || null;\n if (!out && creator) {\n this.cells[col] = out = creator(this, col);\n out.gridRow = this;\n out.colIndex = col;\n if (out.rowAlign) {\n this.grid.addRowAlign(out.rowAlign);\n }\n if (out.colAlign) {\n this.grid.addColAlign(out.colAlign);\n }\n }\n return out;\n }\n\n /**\n * Clears the cell at the given column.\n * Note this is not the same as \"removing\" a cell.\n * Removing a cell would require all cells to the \"right\" to be shifted left.\n * @param col The column index\n * @returns The cell that was cleared, or null if none existed\n */\n clearCellAt(col: number): GridCell | null {\n const out = this.cells[col] || null;\n if (out) {\n this.cells[col] = null;\n }\n return out;\n }\n\n /**\n * Returns a debug-friendly representation of this GridRow.\n * @returns An object containing debug information\n */\n debugValue() {\n return {\n r: this.rowIndex,\n cells: this.cells.filter((c) => c).map((c) => c?.debugValue()),\n };\n }\n}\n\n/**\n * Base class for row and column alignment objects.\n * AlignedLine manages the alignment of cells along a line (row or column).\n */\nexport abstract class AlignedLine {\n private static idCounter = 0;\n readonly uuid = AlignedLine.idCounter++;\n /** Whether this line needs layout */\n needsLayout = false;\n /** The coordinate offset of this line */\n protected _coordOffset = 0;\n /** The maximum length of this line */\n protected _maxLength = 0;\n /** Padding before this line */\n paddingBefore = 5;\n /** Padding after this line */\n paddingAfter = 5;\n /** The cells that belong to this line */\n cells: GridCell[] = [];\n /** Function to get a view for a cell value */\n getCellView: (value: any) => GridCellView;\n\n /**\n * Sets the offset of this line.\n * @param val The new offset value\n */\n abstract setOffset(val: number): void;\n \n /**\n * Evaluates the maximum length required for this line.\n * @param changedCells Cells that have changed and need re-evaluation\n * @returns The maximum length\n */\n abstract evalMaxLength(changedCells: GridCell[]): number;\n\n /**\n * Gets the coordinate offset of this line.\n */\n get coordOffset(): number {\n return this._coordOffset;\n }\n\n /**\n * Gets the maximum length of this line, including padding.\n */\n get maxLength(): number {\n return this._maxLength + this.paddingBefore + this.paddingAfter;\n }\n\n /**\n * Sets the maximum length of this line.\n * @param length The new maximum length\n */\n setMaxLength(length: number) {\n this._maxLength = length;\n }\n\n /**\n * Sets the padding before and after this line.\n * @param before Padding before the line\n * @param after Padding after the line\n */\n setPadding(before: number, after: number): void {\n if (before >= 0) {\n this.paddingBefore = before;\n }\n if (after >= 0) {\n this.paddingAfter = after;\n }\n }\n\n /**\n * Adds a cell to this line.\n * @param cell The cell to add\n * @returns This line instance for method chaining\n */\n addCell(cell: GridCell): this {\n if (this.beforeAddingCell(cell)) {\n this.cells.push(cell);\n }\n return this;\n }\n\n /**\n * Called before adding a cell to perform validation or preparation.\n * @param cell The cell to be added\n * @returns Whether the cell should be added\n */\n protected abstract beforeAddingCell(cell: GridCell): boolean;\n\n /**\n * Removes a cell from this line.\n * @param cell The cell to remove\n * @returns This line instance for method chaining\n */\n removeCell(cell: GridCell): this {\n if (this.beforeRemovingCell(cell)) {\n for (let i = 0; i < this.cells.length; i++) {\n if (this.cells[i].uuid == cell.uuid) {\n this.cells.splice(i, 1);\n break;\n }\n }\n }\n return this;\n }\n\n /**\n * Called before removing a cell to perform validation.\n * @param cell The cell to be removed\n * @returns Whether the cell should be removed\n */\n protected abstract beforeRemovingCell(cell: GridCell): boolean;\n\n // The \"neighboring\" lines that depend on this line to be placed\n // before they are placed\n /** Lines that must be positioned before this line */\n prevLines = [] as this[];\n /** Lines that must be positioned after this line */\n nextLines = [] as this[];\n \n /**\n * Adds a successor line to this line.\n * @param next The line to add as a successor\n */\n addSuccessor(next: this): void {\n // Set nextCol as a successor of this col\n // TODO - Ensure no cycles\n for (const c of this.nextLines) {\n if (c == next) return;\n }\n this.nextLines.push(next);\n next.prevLines.push(this);\n }\n\n /* TODO: Disabling only to improve test coverage as this method is\n * not used.\n * When we have mutable grids where we can insert/remove neighbors\n * we can enable this again.\n */\n /*\n removeSuccessor(next: this): void {\n // Set nextCol as a successor of this col\n // TODO - Ensure no cycles\n for (let i = 0; i < this.nextLines.length; i++) {\n if (this.nextLines[i] == next) {\n this.nextLines.splice(i, 1);\n break;\n }\n }\n for (let i = 0; i < next.prevLines.length; i++) {\n if (next.prevLines[i] == this) {\n next.prevLines.splice(i, 1);\n break;\n }\n }\n }\n */\n}\n\n/**\n * Manages the alignment of cells in a column.\n */\nexport class ColAlign extends AlignedLine {\n paddingBefore = 10;\n /** Padding after this line */\n paddingAfter = 10;\n\n /**\n * Sets the offset of this column and updates all associated cells.\n * @param val The new offset value\n */\n setOffset(val: number): void {\n this._coordOffset = val;\n for (const cell of this.cells) {\n if (cell.value) {\n const cellView = this.getCellView(cell);\n if (this._maxLength <= 0) {\n // this hasnt been evaluated yet so do it!\n this.evalMaxLength();\n }\n cellView.setBounds(val, null, this.maxLength, null, true);\n }\n }\n }\n\n /**\n * Evaluates the maximum width required for this column.\n * @param changedCells Cells that have changed and need re-evaluation\n * @returns The maximum width\n */\n evalMaxLength(changedCells: GridCell[] = []): number {\n this._maxLength = 0;\n for (const cell of this.cells) {\n if (cell.value) {\n const cellView = this.getCellView(cell);\n this._maxLength = Math.max(cellView.minSize.width, this._maxLength);\n }\n }\n return this._maxLength;\n }\n\n /**\n * Called before adding a cell to perform validation or preparation.\n * @param cell The cell to be added\n * @returns Whether the cell should be added\n */\n protected beforeAddingCell(cell: GridCell): boolean {\n if (cell.colAlign && cell.colAlign != this) {\n cell.colAlign.removeCell(cell);\n }\n return cell.colAlign != this;\n }\n\n /**\n * Called before removing a cell to perform validation.\n * @param cell The cell to be removed\n * @returns Whether the cell should be removed\n */\n beforeRemovingCell(cell: GridCell): boolean {\n return cell.colAlign == this;\n }\n}\n\n/**\n * Manages the alignment of cells in a row.\n */\nexport class RowAlign extends AlignedLine {\n /**\n * Sets the Y coordinate of all cells in this row.\n * @param val The new Y coordinate\n */\n setOffset(val: number): void {\n this._coordOffset = val;\n for (const cell of this.cells) {\n if (cell.value) {\n const cellView = this.getCellView(cell);\n if (this._maxLength <= 0) {\n // this hasnt been evaluated yet so do it!\n this.evalMaxLength();\n }\n cellView.setBounds(null, val, null, this.maxLength, true);\n }\n }\n }\n\n /**\n * Evaluates the maximum height required for this row.\n * @param changedCells Cells that have changed and need re-evaluation\n * @returns The maximum height\n */\n evalMaxLength(changedCells: GridCell[] = []): number {\n this._maxLength = 0;\n for (const cell of this.cells) {\n if (cell.value) {\n const cellView = this.getCellView(cell);\n this._maxLength = Math.max(cellView.minSize.height, this._maxLength);\n }\n }\n return this._maxLength;\n }\n\n /**\n * Called before adding a cell to perform validation or preparation.\n * @param cell The cell to be added\n * @returns Whether the cell should be added\n */\n protected beforeAddingCell(cell: GridCell): boolean {\n if (cell.rowAlign && cell.rowAlign != this) {\n cell.rowAlign.removeCell(cell);\n }\n return cell.rowAlign != this;\n }\n\n /**\n * Called before removing a cell to perform validation.\n * @param cell The cell to be removed\n * @returns Whether the cell should be removed\n */\n beforeRemovingCell(cell: GridCell): boolean {\n return cell.rowAlign == this;\n }\n}\n\n/**\n * The layout manager for a collection of GridViews bound by common alignment objects.\n * Manages the layout of multiple grid models, ensuring proper alignment between them.\n */\nexport class GridLayoutGroup {\n // rowAligns = new Map<number, RowAlign>();\n // colAligns = new Map<number, ColAlign>();\n /** The grid models managed by this layout group */\n gridModels = [] as GridModel[];\n\n /**\n * Event handler for processing events from grid models.\n */\n private eventHandler = (event: TSU.Events.TEvent) => {\n this.applyModelEvents(event.payload);\n };\n\n /**\n * Adds a grid model to this layout group.\n * @param gridModel The grid model to add\n * @returns True if the model was added successfully\n */\n addGridModel(gridModel: GridModel): boolean {\n gridModel.eventHub?.on(TSU.Events.EventHub.BATCH_EVENTS, this.eventHandler);\n this.gridModels.push(gridModel);\n return true;\n }\n\n /**\n * Gets all row alignment objects that have no predecessors.\n * @returns An array of starting row alignments\n */\n startingRowAligns(): RowAlign[] {\n const out = [] as RowAlign[];\n const visited = {} as any;\n for (const gm of this.gridModels) {\n for (const cell of gm.cellsInRow(gm.firstRow)) {\n if (cell.rowAlign && !visited[cell.rowAlign.uuid]) {\n visited[cell.rowAlign.uuid] = true;\n out.push(cell.rowAlign);\n }\n }\n }\n return out;\n }\n\n /**\n * Gets all column alignment objects that have no predecessors.\n * @returns An array of starting column alignments\n */\n startingColAligns(): ColAlign[] {\n const out = [] as ColAlign[];\n const visited = {} as any;\n for (const gm of this.gridModels) {\n for (const cell of gm.cellsInCol(gm.firstCol)) {\n if (cell.colAlign && !visited[cell.colAlign.uuid]) {\n visited[cell.colAlign.uuid] = true;\n out.push(cell.colAlign);\n }\n }\n }\n return out;\n }\n\n /**\n * Removes a grid model from this layout group.\n * @param gridModel The grid model to remove\n */\n removeGridModel(gridModel: GridModel): void {\n gridModel.eventHub?.removeOn(TSU.Events.EventHub.BATCH_EVENTS, this.eventHandler);\n }\n\n /**\n * Function to get a view for a cell value.\n */\n getCellView: (cell: GridCell) => GridCellView;\n\n /**\n * Gets the starting row alignments.\n */\n get startingRows(): RowAlign[] {\n return this.startingRowAligns();\n }\n\n /**\n * Gets the starting column alignments.\n */\n get startingCols(): ColAlign[] {\n return this.startingColAligns();\n }\n\n /**\n * Forces a full refresh of the layout.\n * This recalculates all row and column sizes and positions.\n */\n refreshLayout() {\n const changedRowAligns = {} as any;\n const changedColAligns = {} as any;\n\n for (const rowAlign of this.startingRowAligns()) {\n if (!(rowAlign.uuid in changedRowAligns)) {\n changedRowAligns[rowAlign.uuid] = {\n align: rowAlign,\n cells: [],\n };\n }\n }\n\n for (const colAlign of this.startingColAligns()) {\n if (!(colAlign.uuid in changedColAligns)) {\n changedColAligns[colAlign.uuid] = {\n align: colAlign,\n cells: [],\n };\n }\n }\n\n this.doBfsLayout(this.startingRows, changedRowAligns);\n this.doBfsLayout(this.startingCols, changedColAligns);\n }\n\n /**\n * Applies model events to update the layout.\n * @param events The events to process\n */\n protected applyModelEvents(events: TSU.Events.TEvent[]) {\n // As the grid model changes (cell content changed, cleared etc) we need\n // to refresh our layout based on this.\n // As a first step the new height and width of all changed cells is\n // evaluted to see which rows and/or columns are affected (and need to be\n // resized/repositioned).\n const [changedRowAligns, changedColAligns] = this.changesForEvents(events);\n this.doBfsLayout(this.startingRows, changedRowAligns);\n this.doBfsLayout(this.startingCols, changedColAligns);\n }\n\n /**\n * Determines which rows and columns need to be updated based on events.\n * @param events The events to process\n * @returns A tuple containing the changed row and column alignments\n */\n protected changesForEvents(events: TSU.Events.TEvent[]): [any, any] {\n // Step 1 - topologically sort RowAligns of changed cells\n // Step 2 - topologically sort ColAligns of changed cells\n // Step 3 -\n const cellVisited = {} as any;\n const changedRowAligns = {} as any;\n const changedColAligns = {} as any;\n // Going in reverse means we only get the latest event affecting a cell\n // instead of going through every change.\n // Later on we can revisit this if the events are edge triggered instead\n // of level triggered\n for (let i = events.length - 1; i >= 0; i--) {\n const event = events[i];\n const loc = event.payload.loc;\n if (cellVisited[loc]) continue;\n cellVisited[loc] = true;\n const [row, col] = loc.split(\":\").map((x: string) => parseInt(x));\n const gridModel = event.source;\n const cell = gridModel.getRow(row).cellAt(col);\n if (cell) {\n // TODO - For now we are marking both row and col as having\n // changed for a cell. We can optimize this to only row or\n // col based on whether height or width has changed.\n if (!(cell.rowAlign.uuid in changedRowAligns)) {\n changedRowAligns[cell.rowAlign.uuid] = {\n align: cell.rowAlign,\n cells: [],\n };\n }\n changedRowAligns[cell.rowAlign.uuid][\"cells\"].push(cell);\n\n if (!(cell.colAlign.uuid in changedColAligns)) {\n changedColAligns[cell.colAlign.uuid] = {\n align: cell.colAlign,\n cells: [],\n };\n }\n changedColAligns[cell.colAlign.uuid][\"cells\"].push(cell);\n }\n }\n return [changedRowAligns, changedColAligns];\n }\n\n /**\n * Ensures that a cell view getter function is available for an alignment.\n * @param align The alignment to check\n * @returns The cell view getter function\n */\n protected ensureGetCellView(align: AlignedLine) {\n if (!align.getCellView) {\n if (!this.getCellView) {\n return null;\n }\n align.getCellView = this.getCellView;\n }\n return align.getCellView;\n }\n\n /**\n * Performs a breadth-first layout of aligned lines.\n * @param startingLines The lines to start from\n * @param changedAligns Map of alignment IDs to changed alignments\n */\n protected doBfsLayout<T extends AlignedLine>(startingLines: T[], changedAligns: any) {\n // 1. start from the starting lines and do a BF traversal\n // 2. If a line not visited (ie laid out):\n // if it is in the changedAlign list then reval its length (w/h)\n // set its offset and length if either width or offset has changed\n // offset can be thought of changed if the preceding line's offset has changed\n // first do above for rows\n if (!this.getCellView) return;\n for (const alignId in changedAligns) {\n const val = changedAligns[alignId];\n this.ensureGetCellView(val.align);\n val.align.evalMaxLength(val.cells);\n }\n let lineQueue = [] as [null | T, T][];\n const visitedLines = {} as any;\n for (const line of startingLines) lineQueue.push([null, line]);\n const lineOffsetChanged = {} as any;\n while (lineQueue.length > 0) {\n const nextQueue = [] as [null | T, T][];\n for (let i = 0; i < lineQueue.length; i++) {\n const [prevLineAlign, lineAlign] = lineQueue[i];\n visitedLines[lineAlign.uuid] = true;\n let newOffset = lineAlign.coordOffset;\n let lineChanged = lineAlign.uuid in changedAligns;\n if (prevLineAlign) {\n if (lineOffsetChanged[prevLineAlign.uuid]) {\n newOffset = prevLineAlign.coordOffset + prevLineAlign.maxLength;\n lineChanged = true;\n }\n }\n if (lineChanged) {\n this.ensureGetCellView(lineAlign);\n lineAlign.setOffset(newOffset);\n lineOffsetChanged[lineAlign.uuid] = true;\n }\n\n // Add next neighbors now\n for (const next of lineAlign.nextLines) {\n if (!visitedLines[next.uuid]) {\n nextQueue.push([lineAlign, next]);\n }\n }\n }\n lineQueue = nextQueue;\n }\n }\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"iterators.js","sourceRoot":"","sources":["../../src/iterators.ts"],"names":[],"mappings":"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","sourcesContent":["import * as TSU from \"@panyam/tsutils\";\nimport { TimedEntity } from \"./entity\";\nimport { Atom, LeafAtom, Space, Group, AtomType } from \"./core\";\n\ntype Fraction = TSU.Num.Fraction;\n// type FlatAtom2 = [atom: Atom, duration: TSU.Num.Fraction, offset: TSU.Num.Fraction];\n\nexport class FlatAtom extends TimedEntity {\n readonly TYPE = \"FlatAtom\";\n\n depth: number;\n duration: TSU.Num.Fraction;\n offset: TSU.Num.Fraction;\n private isContinuation: boolean;\n\n constructor(public atom: LeafAtom, config: any = null) {\n super((config = config || {}));\n this.depth = config.depth || 0;\n this.duration = config.duration || atom.duration;\n this.offset = config.offset || TSU.Num.Fraction.ZERO;\n this.isContinuation = \"isContinuation\" in config ? config.isContinuation : false;\n }\n\n get endOffset(): TSU.Num.Fraction {\n return this.offset.plus(this.duration);\n }\n\n debugValue(): any {\n const out = {\n ...super.debugValue(),\n atom: this.atom.debugValue(),\n duration: this.duration.toString(),\n offset: this.offset.toString(),\n depth: this.depth,\n };\n if (this.isContinuation) out.isContinuation = true;\n return out;\n }\n}\n\n/**\n * A nested atom iterator that returns one atom at a time at the leaf-most level.\n * If we have a Group (or nested Groups) only the leaf atoms are returned as if\n * in an in order traversal thus ensuring time order of atoms.\n */\nexport class AtomIterator {\n private atomQueue = new TSU.Lists.List<[Atom, number, Fraction]>();\n private currOffset = TSU.Num.Fraction.ZERO;\n private peeked: TSU.Nullable<FlatAtom> = null;\n\n constructor(...atoms: Atom[]) {\n this.push(...atoms);\n }\n\n /**\n * Push atoms to be flattened and served by this iterator.\n */\n push(...atoms: Atom[]): this {\n for (const atom of atoms) {\n this.atomQueue.add([atom, 0, atom.duration]);\n }\n return this;\n }\n\n next(): TSU.Nullable<FlatAtom> {\n const out = this.peek();\n this.peeked = null;\n if (out != null) {\n this.currOffset = this.currOffset.plus(out.duration).factorized;\n }\n return out;\n }\n\n peek(): TSU.Nullable<FlatAtom> {\n if (this.peeked == null) {\n if (this.hasNext) {\n const [nextAtom, nextDepth, nextDuration] = this.atomQueue.popFront();\n this.peeked = new FlatAtom(nextAtom as LeafAtom, {\n depth: nextDepth,\n offset: this.currOffset,\n duration: nextDuration,\n });\n }\n }\n return this.peeked;\n }\n\n get hasNext(): boolean {\n while (this.atomQueue.first != null) {\n // Get from front of queue\n const [nextAtom, nextDepth, nextDuration] = this.atomQueue.first.value;\n if (nextAtom.TYPE != AtomType.GROUP) {\n return true;\n } else {\n this.atomQueue.popFront();\n const group = nextAtom as Group;\n for (const child of group.atoms.reversedValues()) {\n this.atomQueue.pushFront([\n child,\n nextDepth + 1,\n nextDuration.times(child.duration).divby(group.totalChildDuration).factorized,\n ]);\n }\n }\n }\n return false;\n }\n\n static getMin(iterators: AtomIterator[]): [number, FlatAtom] {\n let currRole = -1;\n let currAtom: TSU.Nullable<FlatAtom> = null;\n for (let ri = 0; ri < iterators.length; ri++) {\n const flatAtom = iterators[ri].peek();\n if (flatAtom != null) {\n if (currAtom == null || flatAtom.offset.cmp(currAtom.offset) < 0) {\n currRole = ri;\n currAtom = flatAtom;\n }\n }\n }\n if (currRole >= 0) {\n iterators[currRole].next();\n }\n return [currRole, currAtom!];\n }\n}\n\nexport class WindowIterator {\n private atomQueue = new TSU.Lists.List<Atom>();\n private currOffset = TSU.Num.Fraction.ZERO;\n private peeked: TSU.Nullable<Atom> = null;\n\n constructor(...atoms: Atom[]) {\n this.push(...atoms);\n }\n\n /**\n * Push atoms to be flattened and served by this iterator.\n */\n push(...atoms: Atom[]): this {\n for (const atom of atoms) {\n this.atomQueue.add(atom);\n }\n return this;\n }\n\n next(): TSU.Nullable<Atom> {\n const out = this.peek();\n this.peeked = null;\n if (out != null) {\n this.currOffset = this.currOffset.plus(out.duration, true);\n }\n return out;\n }\n\n peek(): TSU.Nullable<Atom> {\n if (this.peeked == null && this.hasMore) {\n this.peeked = this.atomQueue.popFront();\n }\n return this.peeked;\n }\n\n get hasMore(): boolean {\n return !this.atomQueue.isEmpty;\n }\n\n /**\n * Gets the atoms to cover the given duration.\n *\n * If the number of atoms left in the iterator is 0 then an empty list\n * is returned. Otherwise the duration of atoms returned will cover\n * the given duration even if padding with Space atoms is necessary.\n */\n get(duration: TSU.Num.Fraction): [Atom[], boolean] {\n const out: Atom[] = [];\n let remaining = duration;\n while (remaining.isGTNum(0) && this.hasMore) {\n const next = this.next();\n TSU.assert(next != null, \"Next cannot be null here\");\n out.push(next);\n const spillOver = next.splitAt(remaining);\n remaining = remaining.minus(next.duration);\n if (spillOver != null) {\n // push the spill over to the front of the queue to be\n // picked up on the next \"get\" call\n this.atomQueue.pushFront(spillOver);\n }\n }\n return [out, remaining.isZero];\n }\n}\n\n/**\n * Duration Iterators take a tree of Atoms and return atoms in given windowed\n * durations. This also ensures that a leaf atom can be further split if it is\n * larger than the required duration.\n */\nexport class DurationIterator {\n private atomIterator: AtomIterator;\n private spillOver: TSU.Nullable<FlatAtom> = null;\n\n constructor(atomIterator: AtomIterator) {\n this.atomIterator = atomIterator;\n }\n\n get hasMore(): boolean {\n if (this.spillOver != null) {\n return true;\n }\n return this.atomIterator.hasNext;\n }\n\n /**\n * Gets the atoms to cover the given duration.\n *\n * If the number of atoms left in the iterator is 0 then an empty list\n * is returned. Otherwise the duration of atoms returned will cover\n * the given duration even if padding with Space atoms is necessary.\n */\n get(duration: TSU.Num.Fraction): [FlatAtom[], boolean] {\n const iter = this.atomIterator;\n const out: FlatAtom[] = [];\n let remaining = duration;\n while (remaining.isGTNum(0)) {\n const next = this.spillOver == null ? iter.next() : this.spillOver;\n this.spillOver = null;\n if (next == null) {\n // stop here\n break;\n } else {\n out.push(next);\n if (next.duration.cmp(remaining) <= 0) {\n remaining = remaining.minus(next.duration);\n } else {\n // Next leaf atm is > duration\n // so split it into two\n this.spillOver = new FlatAtom(new Space(next.duration.minus(remaining)));\n next.duration = remaining;\n remaining = TSU.Num.Fraction.ZERO;\n }\n }\n }\n return [out, remaining.isZero];\n }\n}\n"]}
1
+ {"version":3,"file":"iterators.js","sourceRoot":"","sources":["../../src/iterators.ts"],"names":[],"mappings":"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","sourcesContent":["import * as TSU from \"@panyam/tsutils\";\nimport { TimedEntity } from \"./entity\";\nimport { Atom, LeafAtom, Space, Group, AtomType } from \"./core\";\n\ntype Fraction = TSU.Num.Fraction;\n// type FlatAtom2 = [atom: Atom, duration: TSU.Num.Fraction, offset: TSU.Num.Fraction];\n\n/**\n * Represents a flattened atom with timing information.\n * FlatAtom is used to process nested atom structures in a flat, sequential manner\n * with proper timing information.\n */\nexport class FlatAtom extends TimedEntity {\n readonly TYPE = \"FlatAtom\";\n\n /** Nesting depth of this atom in the original structure */\n depth: number;\n \n /** Duration of this atom */\n duration: TSU.Num.Fraction;\n \n /** Time offset of this atom */\n offset: TSU.Num.Fraction;\n \n /** Whether this atom is a continuation of a previous atom */\n private isContinuation: boolean;\n\n /**\n * Creates a new FlatAtom.\n * @param atom The leaf atom this flat atom represents\n * @param config Optional configuration with depth, duration, offset, and continuation info\n */\n constructor(public atom: LeafAtom, config: any = null) {\n super((config = config || {}));\n this.depth = config.depth || 0;\n this.duration = config.duration || atom.duration;\n this.offset = config.offset || TSU.Num.Fraction.ZERO;\n this.isContinuation = \"isContinuation\" in config ? config.isContinuation : false;\n }\n\n /**\n * Gets the end offset of this atom (offset + duration).\n */\n get endOffset(): TSU.Num.Fraction {\n return this.offset.plus(this.duration);\n }\n\n /**\n * Returns a debug-friendly representation of this FlatAtom.\n * @returns An object containing debug information\n */\n debugValue(): any {\n const out = {\n ...super.debugValue(),\n atom: this.atom.debugValue(),\n duration: this.duration.toString(),\n offset: this.offset.toString(),\n depth: this.depth,\n };\n if (this.isContinuation) out.isContinuation = true;\n return out;\n }\n}\n\n/**\n * A nested atom iterator that returns one atom at a time at the leaf-most level.\n * If we have a Group (or nested Groups) only the leaf atoms are returned as if\n * in an in-order traversal, thus ensuring time order of atoms.\n */\nexport class AtomIterator {\n private atomQueue = new TSU.Lists.List<[Atom, number, Fraction]>();\n private currOffset = TSU.Num.Fraction.ZERO;\n private peeked: TSU.Nullable<FlatAtom> = null;\n\n /**\n * Creates a new AtomIterator with optional initial atoms.\n * @param atoms Initial atoms to iterate through\n */\n constructor(...atoms: Atom[]) {\n this.push(...atoms);\n }\n\n /**\n * Push atoms to be flattened and served by this iterator.\n * @param atoms The atoms to add to the queue\n * @returns This iterator instance for method chaining\n */\n push(...atoms: Atom[]): this {\n for (const atom of atoms) {\n this.atomQueue.add([atom, 0, atom.duration]);\n }\n return this;\n }\n\n /**\n * Gets the next atom in the sequence and advances the iterator.\n * @returns The next FlatAtom, or null if no more atoms are available\n */\n next(): TSU.Nullable<FlatAtom> {\n const out = this.peek();\n this.peeked = null;\n if (out != null) {\n this.currOffset = this.currOffset.plus(out.duration).factorized;\n }\n return out;\n }\n\n /**\n * Peeks at the next atom without advancing the iterator.\n * @returns The next FlatAtom, or null if no more atoms are available\n */\n peek(): TSU.Nullable<FlatAtom> {\n if (this.peeked == null) {\n if (this.hasNext) {\n const [nextAtom, nextDepth, nextDuration] = this.atomQueue.popFront();\n this.peeked = new FlatAtom(nextAtom as LeafAtom, {\n depth: nextDepth,\n offset: this.currOffset,\n duration: nextDuration,\n });\n }\n }\n return this.peeked;\n }\n\n /**\n * Checks if more atoms are available in this iterator.\n * This may process group atoms to find the next leaf atom.\n */\n get hasNext(): boolean {\n while (this.atomQueue.first != null) {\n // Get from front of queue\n const [nextAtom, nextDepth, nextDuration] = this.atomQueue.first.value;\n if (nextAtom.TYPE != AtomType.GROUP) {\n return true;\n } else {\n this.atomQueue.popFront();\n const group = nextAtom as Group;\n for (const child of group.atoms.reversedValues()) {\n this.atomQueue.pushFront([\n child,\n nextDepth + 1,\n nextDuration.times(child.duration).divby(group.totalChildDuration).factorized,\n ]);\n }\n }\n }\n return false;\n }\n\n /**\n * Gets the atom with the minimum offset from multiple iterators.\n * @param iterators An array of AtomIterators to compare\n * @returns A tuple containing the index of the selected iterator and its next atom\n */\n static getMin(iterators: AtomIterator[]): [number, FlatAtom] {\n let currRole = -1;\n let currAtom: TSU.Nullable<FlatAtom> = null;\n for (let ri = 0; ri < iterators.length; ri++) {\n const flatAtom = iterators[ri].peek();\n if (flatAtom != null) {\n if (currAtom == null || flatAtom.offset.cmp(currAtom.offset) < 0) {\n currRole = ri;\n currAtom = flatAtom;\n }\n }\n }\n if (currRole >= 0) {\n iterators[currRole].next();\n }\n return [currRole, currAtom!];\n }\n}\n\n/**\n * An iterator that provides atoms within specified time windows.\n * WindowIterator allows fetching atoms to cover a specific duration,\n * handling the splitting of atoms if necessary.\n */\nexport class WindowIterator {\n private atomQueue = new TSU.Lists.List<Atom>();\n private currOffset = TSU.Num.Fraction.ZERO;\n private peeked: TSU.Nullable<Atom> = null;\n\n /**\n * Creates a new WindowIterator with optional initial atoms.\n * @param atoms Initial atoms to iterate through\n */\n constructor(...atoms: Atom[]) {\n this.push(...atoms);\n }\n\n /**\n * Push atoms to be served by this iterator.\n * @param atoms The atoms to add to the queue\n * @returns This iterator instance for method chaining\n */\n push(...atoms: Atom[]): this {\n for (const atom of atoms) {\n this.atomQueue.add(atom);\n }\n return this;\n }\n\n /**\n * Gets the next atom in the sequence and advances the iterator.\n * @returns The next Atom, or null if no more atoms are available\n */\n next(): TSU.Nullable<Atom> {\n const out = this.peek();\n this.peeked = null;\n if (out != null) {\n this.currOffset = this.currOffset.plus(out.duration, true);\n }\n return out;\n }\n\n /**\n * Peeks at the next atom without advancing the iterator.\n * @returns The next Atom, or null if no more atoms are available\n */\n peek(): TSU.Nullable<Atom> {\n if (this.peeked == null && this.hasMore) {\n this.peeked = this.atomQueue.popFront();\n }\n return this.peeked;\n }\n\n /**\n * Checks if more atoms are available in this iterator.\n */\n get hasMore(): boolean {\n return !this.atomQueue.isEmpty;\n }\n\n /**\n * Gets atoms to cover the specified duration.\n * \n * If the number of atoms left in the iterator is 0, an empty list\n * is returned. Otherwise, the duration of atoms returned will cover\n * the given duration even if padding with Space atoms is necessary.\n * \n * @param duration The duration to cover\n * @returns A tuple containing the array of atoms and whether the full duration was filled\n */\n get(duration: TSU.Num.Fraction): [Atom[], boolean] {\n const out: Atom[] = [];\n let remaining = duration;\n while (remaining.isGTNum(0) && this.hasMore) {\n const next = this.next();\n TSU.assert(next != null, \"Next cannot be null here\");\n out.push(next);\n const spillOver = next.splitAt(remaining);\n remaining = remaining.minus(next.duration);\n if (spillOver != null) {\n // push the spill over to the front of the queue to be\n // picked up on the next \"get\" call\n this.atomQueue.pushFront(spillOver);\n }\n }\n return [out, remaining.isZero];\n }\n}\n\n/**\n * An iterator that provides atoms with specific durations.\n * DurationIterator ensures that atoms fit within specified duration windows,\n * splitting atoms if necessary to fit.\n */\nexport class DurationIterator {\n private atomIterator: AtomIterator;\n private spillOver: TSU.Nullable<FlatAtom> = null;\n\n /**\n * Creates a new DurationIterator.\n * @param atomIterator The AtomIterator to use as a source of atoms\n */\n constructor(atomIterator: AtomIterator) {\n this.atomIterator = atomIterator;\n }\n\n /**\n * Checks if more atoms are available in this iterator.\n */\n get hasMore(): boolean {\n if (this.spillOver != null) {\n return true;\n }\n return this.atomIterator.hasNext;\n }\n\n /**\n * Gets atoms to cover the specified duration.\n * \n * If the number of atoms left in the iterator is 0, an empty list\n * is returned. Otherwise, the duration of atoms returned will cover\n * the given duration even if padding with Space atoms is necessary.\n * \n * @param duration The duration to cover\n * @returns A tuple containing the array of FlatAtoms and whether the full duration was filled\n */\n get(duration: TSU.Num.Fraction): [FlatAtom[], boolean] {\n const iter = this.atomIterator;\n const out: FlatAtom[] = [];\n let remaining = duration;\n while (remaining.isGTNum(0)) {\n const next = this.spillOver == null ? iter.next() : this.spillOver;\n this.spillOver = null;\n if (next == null) {\n // stop here\n break;\n } else {\n out.push(next);\n if (next.duration.cmp(remaining) <= 0) {\n remaining = remaining.minus(next.duration);\n } else {\n // Next leaf atom is > duration\n // so split it into two\n this.spillOver = new FlatAtom(new Space(next.duration.minus(remaining)));\n next.duration = remaining;\n remaining = TSU.Num.Fraction.ZERO;\n }\n }\n }\n return [out, remaining.isZero];\n }\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"layouts.js","sourceRoot":"","sources":["../../src/layouts.ts"],"names":[],"mappings":"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","sourcesContent":["import * as TSU from \"@panyam/tsutils\";\nimport { Cycle, CyclePosition, CycleCursor } from \"./cycle\";\n\ntype Fraction = TSU.Num.Fraction;\nconst ZERO = TSU.Num.Fraction.ZERO;\n\nexport class LayoutParams {\n private static counter = 0;\n readonly uuid = LayoutParams.counter++;\n beatDuration: number;\n cycle: Cycle;\n protected _lineBreaks: number[];\n private _rowStartOffsets: Fraction[];\n private _rowEndOffsets: Fraction[];\n private _rowDurations: Fraction[];\n private _totalLayoutDuration;\n private _beatLayouts: [CyclePosition, Fraction][][];\n private _totalBeats: number;\n\n constructor(config?: any) {\n config = config || {};\n this.beatDuration = config.beatDuration || 1;\n if (\"cycle\" in config) this.cycle = config.cycle;\n if (!this.cycle || this.cycle.duration.isZero) {\n this.cycle = Cycle.DEFAULT;\n }\n\n this._rowStartOffsets = [];\n this._rowEndOffsets = [];\n this._rowDurations = [];\n this._totalLayoutDuration = ZERO;\n this._totalBeats = 0;\n this._beatLayouts = [];\n this.lineBreaks = config.lineBreaks || config.layout || [];\n }\n\n equals(another: this): boolean {\n return (\n // super.equals(another) &&\n this.beatDuration == another.beatDuration &&\n this.cycle.equals(another.cycle) &&\n this.lineBreaksEqual(another._lineBreaks)\n );\n }\n\n lineBreaksEqual(another: number[]): boolean {\n return this._lineBreaks.length == another.length && this._lineBreaks.every((x, i) => x == another[i]);\n }\n\n debugValue(): any {\n return {\n // ...super.debugValue(),\n cycle: this.cycle?.debugValue(),\n beatDuration: this.beatDuration,\n lineBreaks: this._lineBreaks,\n };\n }\n\n /**\n * Returns the \"location\" of a beat within a layout.\n *\n * Lines are broken into beats of notes and those beats are aligned as per\n * the specs in the LayoutParams (breaks). For example if the breaks param\n * stipulates [5, 5, 4] then we have 5 beats in the first 2 lines and 4 in\n * the last line.\n *\n * If a line contains say 50 beats (B1 - B50), then it is laid out as:\n *\n * C0 C1 C2 C3 C4\n * ---------------------\n * L0 | B1 B2 B3 B4 B5\n * L1 | B6 B7 B8 B9 B10\n * L2 | B11 B12 B13 B14\n * L0 | B15 B16 B17 B18 B19\n * L1 | B20 B21 B22 B23 B24\n * L2 | B25 B26 B27 B28\n * L0 | B29 B30 B31 B32 B33\n * L1 | B34 B35 B36 B37 B38\n * L2 | B39 B40 B41 B42\n * L0 | B43 B44 B45 B46 B47\n * L1 | B48 B49 B50\n *\n * This methods returns the triple: [layoutLine, layoutColumn, rowOffset]\n * where\n *\n * layoutLine: The particular line in the layout break spec this index falls in.\n * *Note*: Since lines can start with negative offsets, we can\n * even return a layoutLine that is towards the end and then go\n * back to 0, eg 4, 0, 1, 2, 3, 4, 0, 1, 2, 3, 4 ...\n * (eg returns L0 or L1 ... Ln)\n * layoutColumn: The column within the layoutLine line where this beat falls.\n * (eg C0 - C4 above - or depending on how many columns exist\n * in the particular layout line).\n * rowOffset: The note offset of the beat from the start of the row/line\n * (not from the start of the cycle).\n *\n * Note the beatIndex can also be negative so we can return a beat\n * starting from before the cycle starting point.\n *\n * To calculate the \"real\" line globally simply do:\n *\n * realLine = lineBreaks.length * Math.floor(beatIndex / this.totalBeats) + layoutLine;\n *\n * Some examples here are (using B1-B50 above):\n */\n getBeatLocation(beat: {\n index: number;\n barIndex: number;\n beatIndex: number;\n instance: number;\n }): [number, number, Fraction] {\n const modIndex = beat.index % this.totalBeats;\n let total = 0;\n for (let i = 0; i < this._lineBreaks.length; i++) {\n if (modIndex < total + this._lineBreaks[i]) {\n // TODO: What is the right offset here?\n let offset = ZERO;\n if (modIndex > total) {\n const cursor = new CycleCursor(this.cycle, beat.barIndex, beat.beatIndex, beat.instance);\n let [, duration] = cursor.prev;\n for (let i = total; i < modIndex; i++) {\n [, duration] = cursor.prev;\n offset = offset.plus(duration.timesNum(this.beatDuration));\n }\n }\n return [i, modIndex - total, offset];\n }\n total += this._lineBreaks[i];\n }\n throw new Error(\"Invalid beat index: \" + beat.index);\n return [-1, -1, ZERO];\n }\n\n /**\n * Return the line layout - ie number of beats in each line - as a\n * repeating pattern.\n *\n * For example 4,2,4 indicates that the notes in our song should be\n * laid out 4 beats in line 1, 2 beats in line 2, 4 beats in line 3 and\n * 4 beats in line 4 and so on as long as there are more notes available\n * in this line.\n */\n get lineBreaks(): number[] {\n if (!this._lineBreaks || this._lineBreaks.length == 0) {\n // trigger a refresh\n this.lineBreaks = [this.cycle.beatCount];\n }\n return this._lineBreaks;\n }\n\n /**\n * Sets the line layout pattern.\n */\n set lineBreaks(val: number[]) {\n this._lineBreaks = val;\n this.refreshLayout();\n }\n\n /**\n * Returns the number of beats in each line based on the line layout\n * after taking beatDuration into account.\n */\n get beatLayouts(): ReadonlyArray<ReadonlyArray<[CyclePosition, Fraction]>> {\n if (!this._beatLayouts || this._beatLayouts.length < this.lineBreaks.length) {\n this.refreshLayout();\n }\n return this._beatLayouts;\n }\n\n /**\n * Total duration of all beats across all lines in our line layout.\n */\n get totalBeats(): number {\n this.beatLayouts;\n return this._totalBeats;\n }\n\n /**\n * Total duration of all beats across all lines in our line layout.\n */\n get totalLayoutDuration(): Fraction {\n this.beatLayouts;\n return this._totalLayoutDuration;\n }\n\n protected refreshLayout(): void {\n const cycleIter = this.cycle.iterateBeats();\n const akb = this.beatDuration;\n this._beatLayouts = this.lineBreaks.map((numBeats, index) => {\n const beats: [CyclePosition, Fraction][] = [];\n // see what the beat lengths are here\n for (let i = 0; i < numBeats; i++) {\n const nextCP = cycleIter.next().value;\n nextCP[1] = nextCP[1].timesNum(akb);\n beats.push(nextCP);\n }\n return beats;\n });\n this._totalBeats = this.lineBreaks.reduce((a, b) => a + b, 0);\n this._rowDurations = this._beatLayouts.map((beats) => beats.reduce((x, y) => x.plus(y[1]), ZERO));\n this._rowDurations.forEach((rd, index) => {\n this._rowStartOffsets[index] = index == 0 ? ZERO : this._rowStartOffsets[index - 1].plus(rd);\n });\n this._rowEndOffsets = this._rowDurations.map((rd, index) => {\n return this._rowStartOffsets[index].plus(rd);\n });\n this._totalLayoutDuration = this._rowDurations.reduce((x, y) => x.plus(y), ZERO);\n }\n}\n"]}
1
+ {"version":3,"file":"layouts.js","sourceRoot":"","sources":["../../src/layouts.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,qDAAuC;AACvC,mCAA4D;AAG5D,MAAM,IAAI,GAAG,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC;AAOnC,MAAa,YAAY;IAoCvB,YAAY,MAAY;QAjCf,SAAI,GAAG,YAAY,CAAC,OAAO,EAAE,CAAC;QAkCrC,MAAM,GAAG,MAAM,IAAI,EAAE,CAAC;QACtB,IAAI,CAAC,YAAY,GAAG,MAAM,CAAC,YAAY,IAAI,CAAC,CAAC;QAC7C,IAAI,OAAO,IAAI,MAAM;YAAE,IAAI,CAAC,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC;QACjD,IAAI,CAAC,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC;YAC9C,IAAI,CAAC,KAAK,GAAG,aAAK,CAAC,OAAO,CAAC;QAC7B,CAAC;QAED,IAAI,CAAC,gBAAgB,GAAG,EAAE,CAAC;QAC3B,IAAI,CAAC,cAAc,GAAG,EAAE,CAAC;QACzB,IAAI,CAAC,aAAa,GAAG,EAAE,CAAC;QACxB,IAAI,CAAC,oBAAoB,GAAG,IAAI,CAAC;QACjC,IAAI,CAAC,WAAW,GAAG,CAAC,CAAC;QACrB,IAAI,CAAC,YAAY,GAAG,EAAE,CAAC;QACvB,IAAI,CAAC,UAAU,GAAG,MAAM,CAAC,UAAU,IAAI,MAAM,CAAC,MAAM,IAAI,EAAE,CAAC;IAC7D,CAAC;IAOD,MAAM,CAAC,OAAa;QAClB,OAAO,CAEL,IAAI,CAAC,YAAY,IAAI,OAAO,CAAC,YAAY;YACzC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC;YAChC,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,WAAW,CAAC,CAC1C,CAAC;IACJ,CAAC;IAOD,eAAe,CAAC,OAAiB;QAC/B,OAAO,IAAI,CAAC,WAAW,CAAC,MAAM,IAAI,OAAO,CAAC,MAAM,IAAI,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;IACxG,CAAC;IAMD,UAAU;;QACR,OAAO;YAEL,KAAK,EAAE,MAAA,IAAI,CAAC,KAAK,0CAAE,UAAU,EAAE;YAC/B,YAAY,EAAE,IAAI,CAAC,YAAY;YAC/B,UAAU,EAAE,IAAI,CAAC,WAAW;SAC7B,CAAC;IACJ,CAAC;IAgBD,eAAe,CAAC,IAKf;QAwCC,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,UAAU,CAAC;QAC9C,IAAI,KAAK,GAAG,CAAC,CAAC;QACd,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACjD,IAAI,QAAQ,GAAG,KAAK,GAAG,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC;gBAE3C,IAAI,MAAM,GAAG,IAAI,CAAC;gBAClB,IAAI,QAAQ,GAAG,KAAK,EAAE,CAAC;oBACrB,MAAM,MAAM,GAAG,IAAI,mBAAW,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;oBACzF,IAAI,CAAC,EAAE,QAAQ,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC;oBAC/B,KAAK,IAAI,CAAC,GAAG,KAAK,EAAE,CAAC,GAAG,QAAQ,EAAE,CAAC,EAAE,EAAE,CAAC;wBACtC,CAAC,EAAE,QAAQ,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC;wBAC3B,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC;oBAC7D,CAAC;gBACH,CAAC;gBACD,OAAO,CAAC,CAAC,EAAE,QAAQ,GAAG,KAAK,EAAE,MAAM,CAAC,CAAC;YACvC,CAAC;YACD,KAAK,IAAI,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;QAC/B,CAAC;QACD,MAAM,IAAI,KAAK,CAAC,sBAAsB,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC;QACrD,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;IACxB,CAAC;IAWD,IAAI,UAAU;QACZ,IAAI,CAAC,IAAI,CAAC,WAAW,IAAI,IAAI,CAAC,WAAW,CAAC,MAAM,IAAI,CAAC,EAAE,CAAC;YAEtD,IAAI,CAAC,UAAU,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;QAC3C,CAAC;QACD,OAAO,IAAI,CAAC,WAAW,CAAC;IAC1B,CAAC;IAKD,IAAI,UAAU,CAAC,GAAa;QAC1B,IAAI,CAAC,WAAW,GAAG,GAAG,CAAC;QACvB,IAAI,CAAC,aAAa,EAAE,CAAC;IACvB,CAAC;IAMD,IAAI,WAAW;QACb,IAAI,CAAC,IAAI,CAAC,YAAY,IAAI,IAAI,CAAC,YAAY,CAAC,MAAM,GAAG,IAAI,CAAC,UAAU,CAAC,MAAM,EAAE,CAAC;YAC5E,IAAI,CAAC,aAAa,EAAE,CAAC;QACvB,CAAC;QACD,OAAO,IAAI,CAAC,YAAY,CAAC;IAC3B,CAAC;IAKD,IAAI,UAAU;QACZ,IAAI,CAAC,WAAW,CAAC;QACjB,OAAO,IAAI,CAAC,WAAW,CAAC;IAC1B,CAAC;IAKD,IAAI,mBAAmB;QACrB,IAAI,CAAC,WAAW,CAAC;QACjB,OAAO,IAAI,CAAC,oBAAoB,CAAC;IACnC,CAAC;IAMS,aAAa;QACrB,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,EAAE,CAAC;QAC5C,MAAM,GAAG,GAAG,IAAI,CAAC,YAAY,CAAC;QAC9B,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,KAAK,EAAE,EAAE;YAC1D,MAAM,KAAK,GAAgC,EAAE,CAAC;YAE9C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,QAAQ,EAAE,CAAC,EAAE,EAAE,CAAC;gBAClC,MAAM,MAAM,GAAG,SAAS,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC;gBACtC,MAAM,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;gBACpC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YACrB,CAAC;YACD,OAAO,KAAK,CAAC;QACf,CAAC,CAAC,CAAC;QACH,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;QAC9D,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC;QAClG,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC,EAAE,EAAE,KAAK,EAAE,EAAE;YACvC,IAAI,CAAC,gBAAgB,CAAC,KAAK,CAAC,GAAG,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,gBAAgB,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAC/F,CAAC,CAAC,CAAC;QACH,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,KAAK,EAAE,EAAE;YACzD,OAAO,IAAI,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAC/C,CAAC,CAAC,CAAC;QACH,IAAI,CAAC,oBAAoB,GAAG,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;IACnF,CAAC;;AAxPH,oCAyPC;AAxPgB,oBAAO,GAAG,CAAC,AAAJ,CAAK","sourcesContent":["import * as TSU from \"@panyam/tsutils\";\nimport { Cycle, CyclePosition, CycleCursor } from \"./cycle\";\n\ntype Fraction = TSU.Num.Fraction;\nconst ZERO = TSU.Num.Fraction.ZERO;\n\n/**\n * Manages layout parameters for arranging beats and notes in the notation.\n * LayoutParams determines how beats are organized into lines and rows based on\n * cycle patterns and line breaks.\n */\nexport class LayoutParams {\n private static counter = 0;\n /** Unique identifier for this layout parameters instance */\n readonly uuid = LayoutParams.counter++;\n \n /** Duration of a single beat (multiplier for beat lengths) */\n beatDuration: number;\n \n /** The cycle pattern to use for this layout */\n cycle: Cycle;\n \n /** The pattern of line breaks to apply */\n protected _lineBreaks: number[];\n \n /** Cache of row start offsets */\n private _rowStartOffsets: Fraction[];\n \n /** Cache of row end offsets */\n private _rowEndOffsets: Fraction[];\n \n /** Cache of row durations */\n private _rowDurations: Fraction[];\n \n /** Total duration of the layout pattern */\n private _totalLayoutDuration;\n \n /** Cached beat layout information */\n private _beatLayouts: [CyclePosition, Fraction][][];\n \n /** Total number of beats across all layout lines */\n private _totalBeats: number;\n\n /**\n * Creates a new LayoutParams instance.\n * @param config Configuration object containing beatDuration, cycle, and lineBreaks\n */\n constructor(config?: any) {\n config = config || {};\n this.beatDuration = config.beatDuration || 1;\n if (\"cycle\" in config) this.cycle = config.cycle;\n if (!this.cycle || this.cycle.duration.isZero) {\n this.cycle = Cycle.DEFAULT;\n }\n\n this._rowStartOffsets = [];\n this._rowEndOffsets = [];\n this._rowDurations = [];\n this._totalLayoutDuration = ZERO;\n this._totalBeats = 0;\n this._beatLayouts = [];\n this.lineBreaks = config.lineBreaks || config.layout || [];\n }\n\n /**\n * Checks if this LayoutParams is equal to another LayoutParams.\n * @param another The LayoutParams to compare with\n * @returns True if the LayoutParams are equal, false otherwise\n */\n equals(another: this): boolean {\n return (\n // super.equals(another) &&\n this.beatDuration == another.beatDuration &&\n this.cycle.equals(another.cycle) &&\n this.lineBreaksEqual(another._lineBreaks)\n );\n }\n\n /**\n * Checks if the line breaks pattern is equal to another pattern.\n * @param another The line breaks pattern to compare with\n * @returns True if the patterns are equal, false otherwise\n */\n lineBreaksEqual(another: number[]): boolean {\n return this._lineBreaks.length == another.length && this._lineBreaks.every((x, i) => x == another[i]);\n }\n\n /**\n * Returns a debug-friendly representation of this LayoutParams.\n * @returns An object containing debug information\n */\n debugValue(): any {\n return {\n // ...super.debugValue(),\n cycle: this.cycle?.debugValue(),\n beatDuration: this.beatDuration,\n lineBreaks: this._lineBreaks,\n };\n }\n\n /**\n * Returns the \"location\" of a beat within a layout.\n * \n * Lines are broken into beats of notes and those beats are aligned as per\n * the specs in the LayoutParams (breaks). For example if the breaks param\n * stipulates [5, 5, 4] then we have 5 beats in the first 2 lines and 4 in\n * the last line.\n * \n * @param beat The beat to locate\n * @returns A tuple containing [layoutLine, layoutColumn, rowOffset]\n * - layoutLine: The line in the layout break spec this beat falls in\n * - layoutColumn: The column within the layoutLine\n * - rowOffset: The offset of the beat from the start of the row/line\n */\n getBeatLocation(beat: {\n index: number;\n barIndex: number;\n beatIndex: number;\n instance: number;\n }): [number, number, Fraction] {\n //\n // If a line contains say 50 beats (B1 - B50), then it is laid out as:\n //\n // C0 C1 C2 C3 C4\n // ---------------------\n // L0 | B1 B2 B3 B4 B5\n // L1 | B6 B7 B8 B9 B10\n // L2 | B11 B12 B13 B14\n // L0 | B15 B16 B17 B18 B19\n // L1 | B20 B21 B22 B23 B24\n // L2 | B25 B26 B27 B28\n // L0 | B29 B30 B31 B32 B33\n // L1 | B34 B35 B36 B37 B38\n // L2 | B39 B40 B41 B42\n // L0 | B43 B44 B45 B46 B47\n // L1 | B48 B49 B50\n //\n // This methods returns the triple: [layoutLine, layoutColumn, rowOffset]\n // where\n //\n // layoutLine: The particular line in the layout break spec this index falls in.\n // *Note*: Since lines can start with negative offsets, we can\n // even return a layoutLine that is towards the end and then go\n // back to 0, eg 4, 0, 1, 2, 3, 4, 0, 1, 2, 3, 4 ...\n // (eg returns L0 or L1 ... Ln)\n // layoutColumn: The column within the layoutLine line where this beat falls.\n // (eg C0 - C4 above - or depending on how many columns exist\n // in the particular layout line).\n // rowOffset: The note offset of the beat from the start of the row/line\n // (not from the start of the cycle).\n //\n // Note the beatIndex can also be negative so we can return a beat\n // starting from before the cycle starting point.\n //\n // To calculate the \"real\" line globally simply do:\n //\n // realLine = lineBreaks.length // Math.floor(beatIndex / this.totalBeats) + layoutLine;\n //\n // Some examples here are (using B1-B50 above):\n const modIndex = beat.index % this.totalBeats;\n let total = 0;\n for (let i = 0; i < this._lineBreaks.length; i++) {\n if (modIndex < total + this._lineBreaks[i]) {\n // TODO: What is the right offset here?\n let offset = ZERO;\n if (modIndex > total) {\n const cursor = new CycleCursor(this.cycle, beat.barIndex, beat.beatIndex, beat.instance);\n let [, duration] = cursor.prev;\n for (let i = total; i < modIndex; i++) {\n [, duration] = cursor.prev;\n offset = offset.plus(duration.timesNum(this.beatDuration));\n }\n }\n return [i, modIndex - total, offset];\n }\n total += this._lineBreaks[i];\n }\n throw new Error(\"Invalid beat index: \" + beat.index);\n return [-1, -1, ZERO];\n }\n\n /**\n * Gets the line layout pattern - i.e., number of beats in each line - as a\n * repeating pattern.\n * \n * For example 4,2,4 indicates that the notes in our song should be\n * laid out 4 beats in line 1, 2 beats in line 2, 4 beats in line 3 and\n * 4 beats in line 4 and so on as long as there are more notes available\n * in this line.\n */\n get lineBreaks(): number[] {\n if (!this._lineBreaks || this._lineBreaks.length == 0) {\n // trigger a refresh\n this.lineBreaks = [this.cycle.beatCount];\n }\n return this._lineBreaks;\n }\n\n /**\n * Sets the line layout pattern.\n */\n set lineBreaks(val: number[]) {\n this._lineBreaks = val;\n this.refreshLayout();\n }\n\n /**\n * Returns the number of beats in each line based on the line layout\n * after taking beatDuration into account.\n */\n get beatLayouts(): ReadonlyArray<ReadonlyArray<[CyclePosition, Fraction]>> {\n if (!this._beatLayouts || this._beatLayouts.length < this.lineBreaks.length) {\n this.refreshLayout();\n }\n return this._beatLayouts;\n }\n\n /**\n * Gets the total number of beats across all lines in the layout pattern.\n */\n get totalBeats(): number {\n this.beatLayouts;\n return this._totalBeats;\n }\n\n /**\n * Gets the total duration of all beats across all lines in the layout pattern.\n */\n get totalLayoutDuration(): Fraction {\n this.beatLayouts;\n return this._totalLayoutDuration;\n }\n\n /**\n * Refreshes the layout calculations based on the current cycle and line breaks.\n * This rebuilds the beat layouts, row durations, and offset information.\n */\n protected refreshLayout(): void {\n const cycleIter = this.cycle.iterateBeats();\n const akb = this.beatDuration;\n this._beatLayouts = this.lineBreaks.map((numBeats, index) => {\n const beats: [CyclePosition, Fraction][] = [];\n // see what the beat lengths are here\n for (let i = 0; i < numBeats; i++) {\n const nextCP = cycleIter.next().value;\n nextCP[1] = nextCP[1].timesNum(akb);\n beats.push(nextCP);\n }\n return beats;\n });\n this._totalBeats = this.lineBreaks.reduce((a, b) => a + b, 0);\n this._rowDurations = this._beatLayouts.map((beats) => beats.reduce((x, y) => x.plus(y[1]), ZERO));\n this._rowDurations.forEach((rd, index) => {\n this._rowStartOffsets[index] = index == 0 ? ZERO : this._rowStartOffsets[index - 1].plus(rd);\n });\n this._rowEndOffsets = this._rowDurations.map((rd, index) => {\n return this._rowStartOffsets[index].plus(rd);\n });\n this._totalLayoutDuration = this._rowDurations.reduce((x, y) => x.plus(y), ZERO);\n }\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"loader.js","sourceRoot":"","sources":["../../src/loader.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAOA,sBAEC;AAED,oBAkCC;AA7CD,qDAAuC;AAGvC,mCAA2C;AAC3C,qCAAkC;AAGlC,SAAgB,KAAK,CAAC,KAAa;IACjC,OAAO,IAAI,eAAM,EAAE,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;AAC3C,CAAC;AAED,SAAgB,IAAI,CAClB,QAAgB,EAChB,SAAc,EAAE;IAEhB,QAAQ,GAAG,QAAQ,IAAI,EAAE,CAAC;IAC1B,MAAM,UAAU,GAAG,IAAI,wBAAgB,EAAE,CAAC;IAC1C,MAAM,SAAS,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC;IACpC,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAC,CAAC;IAC3C,MAAM,SAAS,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC;IAGpC,KAAK,MAAM,KAAK,IAAI,QAAQ,CAAC,MAAM,EAAE,CAAC;QACpC,IAAI,KAAK,CAAC,IAAI,IAAI,MAAM,IAAI,CAAE,KAAc,CAAC,OAAO,EAAE,CAAC;YACrD,MAAM,IAAI,GAAG,KAAa,CAAC;YAG3B,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,YAAY,IAAI,IAAI,EAAE,mDAAmD,CAAC,CAAC;YAC3F,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QAC3B,CAAC;IACH,CAAC;IAED,MAAM,SAAS,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC;IACpC,IAAI,MAAM,CAAC,GAAG,EAAE,CAAC;QACf,OAAO,CAAC,GAAG,CAAC,4BAA4B,SAAS,GAAG,SAAS,mBAAmB,SAAS,GAAG,SAAS,IAAI,CAAC,CAAC;IAC7G,CAAC;IACD,OAAO;QACL,QAAQ;QACR,UAAU;QACV,MAAM;QACN;YACE,SAAS,EAAE,SAAS,GAAG,SAAS;YAChC,SAAS,EAAE,SAAS,GAAG,SAAS;SACjC;KACF,CAAC;AACJ,CAAC","sourcesContent":["import * as TSU from \"@panyam/tsutils\";\nimport * as G from \"galore\";\nimport { Line } from \"./core\";\nimport { GlobalBeatLayout } from \"./beats\";\nimport { Parser } from \"./parser\";\nimport { Notation } from \"./notation\";\n\nexport function parse(input: string): [Notation, G.ParseError[]] {\n return new Parser().parseAndBuild(input);\n}\n\nexport function load(\n codeText: string,\n config: any = {},\n): [Notation, GlobalBeatLayout, G.ParseError[], TSU.StringMap<number>] {\n codeText = codeText || \"\";\n const beatLayout = new GlobalBeatLayout();\n const startTime = performance.now();\n const [notation, errors] = parse(codeText);\n const parseTime = performance.now();\n\n // Create Line Beats\n for (const block of notation.blocks) {\n if (block.TYPE == \"Line\" && !(block as Line).isEmpty) {\n const line = block as Line;\n // LP should exist by now\n // Probably because this is an empty line and AddAtoms was not called\n TSU.assert(line.layoutParams != null, \"Layout params for a non empty line *SHOULD* exist\");\n beatLayout.addLine(line);\n }\n }\n\n const buildTime = performance.now();\n if (config.log) {\n console.log(`V4 Document, Parse Time: ${parseTime - startTime}ms, Build Time: ${buildTime - parseTime}ms`);\n }\n return [\n notation,\n beatLayout,\n errors,\n {\n parseTime: parseTime - startTime,\n buildTime: buildTime - parseTime,\n },\n ];\n}\n"]}
1
+ {"version":3,"file":"loader.js","sourceRoot":"","sources":["../../src/loader.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAaA,sBAEC;AASD,oBAkCC;AA1DD,qDAAuC;AAGvC,mCAA2C;AAC3C,qCAAkC;AASlC,SAAgB,KAAK,CAAC,KAAa;IACjC,OAAO,IAAI,eAAM,EAAE,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;AAC3C,CAAC;AASD,SAAgB,IAAI,CAClB,QAAgB,EAChB,SAAc,EAAE;IAEhB,QAAQ,GAAG,QAAQ,IAAI,EAAE,CAAC;IAC1B,MAAM,UAAU,GAAG,IAAI,wBAAgB,EAAE,CAAC;IAC1C,MAAM,SAAS,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC;IACpC,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAC,CAAC;IAC3C,MAAM,SAAS,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC;IAGpC,KAAK,MAAM,KAAK,IAAI,QAAQ,CAAC,MAAM,EAAE,CAAC;QACpC,IAAI,KAAK,CAAC,IAAI,IAAI,MAAM,IAAI,CAAE,KAAc,CAAC,OAAO,EAAE,CAAC;YACrD,MAAM,IAAI,GAAG,KAAa,CAAC;YAG3B,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,YAAY,IAAI,IAAI,EAAE,mDAAmD,CAAC,CAAC;YAC3F,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QAC3B,CAAC;IACH,CAAC;IAED,MAAM,SAAS,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC;IACpC,IAAI,MAAM,CAAC,GAAG,EAAE,CAAC;QACf,OAAO,CAAC,GAAG,CAAC,4BAA4B,SAAS,GAAG,SAAS,mBAAmB,SAAS,GAAG,SAAS,IAAI,CAAC,CAAC;IAC7G,CAAC;IACD,OAAO;QACL,QAAQ;QACR,UAAU;QACV,MAAM;QACN;YACE,SAAS,EAAE,SAAS,GAAG,SAAS;YAChC,SAAS,EAAE,SAAS,GAAG,SAAS;SACjC;KACF,CAAC;AACJ,CAAC","sourcesContent":["import * as TSU from \"@panyam/tsutils\";\nimport * as G from \"galore\";\nimport { Line } from \"./core\";\nimport { GlobalBeatLayout } from \"./beats\";\nimport { Parser } from \"./parser\";\nimport { Notation } from \"./notation\";\n\n/**\n * Parses a notation string into a Notation object.\n * \n * @param input The notation string to parse\n * @returns A tuple containing the parsed Notation and any parsing errors\n */\nexport function parse(input: string): [Notation, G.ParseError[]] {\n return new Parser().parseAndBuild(input);\n}\n\n/**\n * Loads a notation from a string and builds the beat layout.\n * \n * @param codeText The notation string to load\n * @param config Optional configuration object\n * @returns A tuple containing the Notation, GlobalBeatLayout, parsing errors, and timing information\n */\nexport function load(\n codeText: string,\n config: any = {},\n): [Notation, GlobalBeatLayout, G.ParseError[], TSU.StringMap<number>] {\n codeText = codeText || \"\";\n const beatLayout = new GlobalBeatLayout();\n const startTime = performance.now();\n const [notation, errors] = parse(codeText);\n const parseTime = performance.now();\n\n // Create Line Beats\n for (const block of notation.blocks) {\n if (block.TYPE == \"Line\" && !(block as Line).isEmpty) {\n const line = block as Line;\n // LP should exist by now\n // Probably because this is an empty line and AddAtoms was not called\n TSU.assert(line.layoutParams != null, \"Layout params for a non empty line *SHOULD* exist\");\n beatLayout.addLine(line);\n }\n }\n\n const buildTime = performance.now();\n if (config.log) {\n console.log(`V4 Document, Parse Time: ${parseTime - startTime}ms, Build Time: ${buildTime - parseTime}ms`);\n }\n return [\n notation,\n beatLayout,\n errors,\n {\n parseTime: parseTime - startTime,\n buildTime: buildTime - parseTime,\n },\n ];\n}\n"]}