<commit_before>var Overprint = {
	Char: {
		NULL: ' ',
		SPACE: ' '	
	},
	Color: {
		BLACK: '#000',
		WHITE: '#fff'
	},
	Cell: {
		WIDTH: 18,
		HEIGHT: 18
	}
};

Overprint.Glyph = function(character, color, bgColor) {
	return {
		char: character || Overprint.Char.NULL,
		color: color || Overprint.Color.WHITE,
		bgColor: bgColor || Overprint.Color.BLACK
	}
}

Overprint.Font = function(family, weight) {
	return font = {
		family: family,
		weight: weight,
		toCSS: function() {
			return weight + ' 18px ' + family;
		}
	}
}

Overprint.Terminal = function(width, height, canvas, font) {
	this._width = width;
	this._height = height;
	this._font = font || Overprint.Font('inconsolata', 'normal');

	var cell = this._emptyCell = Overprint.Glyph();

	canvas.width =  Overprint.Cell.WIDTH * this._width;
	canvas.height = Overprint.Cell.HEIGHT * this._height;

	this._context = canvas.getContext('2d');

	this._context.font = this._font.toCSS();
	this._context.textAlign = 'center';
	this._context.textBaseline = 'middle';

	this._display = new Overprint.DisplayState(width, height, cell);
}

Overprint.Terminal.prototype.clear = function() {
	for (var col=0; col<this._width; col++) {
		for (var row=0; row<this._height; row++) {
			this._display.setCell(col, row, Overprint.Glyph());
		}
	}
}

Overprint.Terminal.prototype.writeGlyph = function(x, y, glyph) {
	this._display.setCell(x, y, glyph);
}

Overprint.Terminal.prototype.render = function() {
	var cellWidth = Overprint.Cell.WIDTH;
	var cellHeight = Overprint.Cell.HEIGHT;

	this._display.render(function(x, y, glyph){
		this._context.fillStyle = glyph.bgColor;
		this._context.fillRect(x * cellWidth, y * cellHeight, cellWidth, cellHeight);

		if (glyph.char == Overprint.Char.NULL) return;

		this._context.fillStyle = glyph.color;
		this._context.fillText(glyph.char, (x+0.5) * cellWidth, Math.ceil((y+0.5) * cellHeight));
	}.bind(this));
}

Overprint.DisplayState = function(width, height, cell) {
	function fillArray2D(width, height, fill) {
		var list = new Array(width);
		for (var col=0; col<width; col++) {
			list[col] = new Array(height);
			for (var row=0; row<height; row++) {
				list[col][row] = fill;
			}<commit_msg>Pass optional background glyph when clearing the terminal<commit_after>var Overprint = {
	Char: {
		NULL: ' ',
		SPACE: ' '	
	},
	Color: {
		BLACK: '#000',
		WHITE: '#fff'
	},
	Cell: {
		WIDTH: 18,
		HEIGHT: 18
	}
};

Overprint.Glyph = function(character, color, bgColor) {
	return {
		char: character || Overprint.Char.NULL,
		color: color || Overprint.Color.WHITE,
		bgColor: bgColor || Overprint.Color.BLACK
	}
}

Overprint.Font = function(family, weight) {
	return font = {
		family: family,
		weight: weight,
		toCSS: function() {
			return weight + ' 18px ' + family;
		}
	}
}

Overprint.Terminal = function(width, height, canvas, font) {
	this._width = width;
	this._height = height;
	this._font = font || Overprint.Font('inconsolata', 'normal');

	var cell = this._emptyCell = Overprint.Glyph();

	canvas.width =  Overprint.Cell.WIDTH * this._width;
	canvas.height = Overprint.Cell.HEIGHT * this._height;

	this._context = canvas.getContext('2d');

	this._context.font = this._font.toCSS();
	this._context.textAlign = 'center';
	this._context.textBaseline = 'middle';

	this._display = new Overprint.DisplayState(width, height, cell);
}

Overprint.Terminal.prototype.clear = function(glyph) {
	var bgGlyph = glyph ? glyph : Overprint.Glyph();
	for (var col=0; col<this._width; col++) {
		for (var row=0; row<this._height; row++) {
			this._display.setCell(col, row, bgGlyph);
		}
	}
}

Overprint.Terminal.prototype.writeGlyph = function(x, y, glyph) {
	this._display.setCell(x, y, glyph);
}

Overprint.Terminal.prototype.render = function() {
	var cellWidth = Overprint.Cell.WIDTH;
	var cellHeight = Overprint.Cell.HEIGHT;

	this._display.render(function(x, y, glyph){
		this._context.fillStyle = glyph.bgColor;
		this._context.fillRect(x * cellWidth, y * cellHeight, cellWidth, cellHeight);

		if (glyph.char == Overprint.Char.NULL) return;

		this._context.fillStyle = glyph.color;
		this._context.fillText(glyph.char, (x+0.5) * cellWidth, Math.ceil((y+0.5) * cellHeight));
	}.bind(this));
}

Overprint.DisplayState = function(width, height, cell) {
	function fillArray2D(width, height, fill) {
		var list = new Array(width);
		for (var col=0; col<width; col++) {
			list[col] = new Array(height);
			for (var row=0; row<height; row++) {
				list[col][row] = fill;
			}
{'fraction_non_alphanumeric': 0.16021481315730587, 'fraction_numerical': 0.008503020810024613, 'mean_word_length': 4.143843498273878, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 3, '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': '559352', 'n_tokens_mistral': 1711, 'n_tokens_neox': 1591, 'n_words': 332}