<commit_before>/* global define: false */
define([
	'lodash', 
	'microevent',
	'app/model/chord'
], function(_, MicroEvent, Chord) {
	"use strict";

	// Collection of chords (i.e. a chord bank).
	//
	// Responsible for knowing the current chord and the rest that are in the
	// bank. The current chord is the one that is currently active or being
	// played. The rest may be accessed for later review, analysis, display,
	// etc.
	//
	// Events:
	// - Triggers a "change" event when the current chord changes.
	// - Triggers a "bank" event when the current chord is banked.
	//

	var ChordBank = function() {
		this.init();
	};

	_.extend(ChordBank.prototype, {
		// initializes the collection with a single chord
		init: function() {
			var chord = new Chord();

			_.bindAll(this, ['onChangeCurrent']);

			this._addListeners(chord);

			this._limit = 10; // limit number of chords in the bank
			this._items = [chord];
		},
		// banks the current chord and replaces it with a new one
		bank: function() {
			var chord = new Chord();
			var current = this.current();
			chord.copyTranspose(current);
			chord.copySustain(current);

			// re-wire listeners because we only care about changes to the current chord
			this._removeListeners(current);
			this._addListeners(chord);
			this._add(chord);

			this.trigger('bank');

			return this;
		},
		// returns all items in the chord bank
		items: function(config) {
			config = config || {};
			var items = this._items;
			if(config.limit) {
				items = this._items.slice(0, config.limit);
			}
			if(config.reverse) {
				items.reverse();
			}
			return items;
		},
		// returns the number of items in the chord bank
		size: function() {
			return this._items.length;
		},
		// clears the chord bank
		clear: function() {
			if(this.current()) {
				this._removeListeners(this.current());
			}
			this._resetItems();
		},
		// returns the first chord - aliased to current()
		current: function() {
			return this._items[0];
		},
		// event handler that relays a change event from
		// a source object to this object
		onChangeCurrent: function() {
			var args = Array.prototype.slice.call(arguments, 0);
			args.unshift("change");
			this.trigger.apply(this, args);
		},

		//--------------------------------------------------
		// Private methods
		_add: function(chord) {
			if(this._limit !== null && this._items.length > this._limit) {
				this._items.pop();
			}
			this._items.unshift(chord);
			return this;
		},
		_addListeners: function(chord) {
			chord.bind('change', this.onChangeCurrent);
			return this;
		},
		_removeListeners: function(chord) {
			chord.unbind('change', this.onChangeCurrent);
			return this;
		},
		_resetItems: function() {
			this._items = [];
		}
	});

	MicroEvent.mixin(ChordBank); // make object observable
	
	return ChordBank;
});
<commit_msg>add jsdoc to chord bank model<commit_after>/**
 * @fileoverview Defines the chord bank class.
 */
define([
	'lodash', 
	'microevent',
	'app/model/chord'
], function(
	_, 
	MicroEvent, 
	Chord
) {
	"use strict";

	/**
	 * Creates an instance of a chord bank.
	 *
	 * A chord bank is a collection of chords.  The purpose of the chord bank is
	 * to maintain a history of chords that have been played and relay events
	 * that bubble up from the currently active chord. It should know how to
	 * "bank" the current chord and add it to the history and know how to create
	 * a new chord.
	 *
	 * The current chord is the one that is being manipulated by MIDI NOTE
	 * ON/OFF events, while the banked chords are essentially read-only. The
	 * banked chords are primiarily of interest to the notation renderer which
	 * is responsible for rendering all or part of the chord bank and analyzing
	 * its contents.
	 *
	 * Change events from the current chord are relayed to any listeners on the
	 * chord bank itself. When a chord is banked, it also fires a bank event.
	 *
	 * @constructor
	 * @fires change
	 * @fires bank
	 */
	var ChordBank = function() {
		this.init();
	};

	_.extend(ChordBank.prototype, {
		/**
		 * Initializes the object
		 *
		 * @return 
		 */
		init: function() {
			var chord = new Chord();

			_.bindAll(this, ['onChangeCurrent']);

			this._addListeners(chord);

			this._limit = 10; // limit number of chords in the bank
			this._items = [chord];
		},
		/**
		 * Banks the current chord and generates a new chord that becomes the
		 * active chord.
		 *
		 * @fires bank
		 * @return
		 */
		bank: function() {
			var chord = new Chord();
			var current = this.current();
			chord.copyTranspose(current);
			chord.copySustain(current);

			// re-wire listeners because we only care about changes to the current chord
			this._removeListeners(current);
			this._addListeners(chord);
			this._add(chord);

			this.trigger('bank');
		},
		/**
		 * Returns a list of chords in the chord bank.
		 *
		 * @param {object} config
		 * @param {number} config.limit Will return items up to the limit.
		 * @param {boolean} config.reverse Will reverse the order of items after
		 * retrieving them up to the limit.
		 * @return
		 */
		items: function(config) {
			config = config || {};
			var items = this._items;
			if(config.limit) {
				items = this._items.slice(0, config.limit);
			}
			if(config.reverse) {
				items.reverse();
			}
			return items;
		},
		/**
		 * Returns the total number of items in the chord bank..
		 *
		 * @return {number} 
		 */
		size: function() {
			return this._items.length;
		},
		/**
		 * Clears the chord bank.
		 *
		 * @return
		 */
		clear: function() {
			if(this.current()) {
				this._removeListeners(this.current());
			}
			this._resetItems();
		},
		/**
		 * Returns the currently active chord.
		 *
		 * @return {Chord}
		 */
		current: function() {
			return this._items[0];
		},
		/**
		 * Handles change events from the currently active chord
		 * and relays them to the chord bank. 
		 *
		 * Listeners who want to be notified when the active chord changes
		 * should listen to the chord bank, *not* the active chord itself.
		 *
		 * @return
		 */
		onChangeCurrent: function() {
			var args = Array.prototype.slice.call(arguments, 0);
			args.unshift("change");
			this.trigger.apply(this, args);
		},

		//--------------------------------------------------

		/**
		 * Adds a chord to the bank.
		 *
		 * @private
		 */
		_add: function(chord) {
			if(this._limit !== null && this._items.length > this._limit) {
				this._items.pop();
			}
			this._items.unshift(chord);
		},
		/**
		 * Adds listeners to the chord.
		 * Used to setup the active chord.
		 *
		 * @private
		 * @param chord
		 * @return
		 */
		_addListeners: function(chord) {
			chord.bind('change', this.onChangeCurrent);
		},
		/**
		 * Removes listeners from a chord.
		 * Used when banking the active chord.
		 *
		 * @private
		 * @param chord
		 * @return
		 */
		_removeListeners: function(chord) {
			chord.unbind('change', this.onChangeCurrent);
		},
		/**
		 * Resets the items.
		 * Used when clearing the bank.
		 *
		 * @private
		 * @return
		 */
		_resetItems: function() {
			this._items = [];
		}
	});

	/**
	 * The chord bank is observable.
	 */
	MicroEvent.mixin(ChordBank); 
	
	return ChordBank;
});

{'fraction_non_alphanumeric': 0.1388464211257818, 'fraction_numerical': 0.001389854065323141, 'mean_word_length': 2.6380182002022243, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6258946', 'n_tokens_mistral': 2656, 'n_tokens_neox': 2176, 'n_words': 714}