#!/usr/bin/env node
// Generated by Haxe 4.3.1
(function ($hx_exports, $global) { "use strict";
$hx_exports["coopy"] = $hx_exports["coopy"] || {};
var $estr = function() { return js_Boot.__string_rec(this,''); },$hxEnums = $hxEnums || {},$_;
function $extend(from, fields) {
	var proto = Object.create(from);
	for (var name in fields) proto[name] = fields[name];
	if( fields.toString !== Object.prototype.toString ) proto.toString = fields.toString;
	return proto;
}
var HxOverrides = function() { };
HxOverrides.__name__ = true;
HxOverrides.dateStr = function(date) {
	var m = date.getMonth() + 1;
	var d = date.getDate();
	var h = date.getHours();
	var mi = date.getMinutes();
	var s = date.getSeconds();
	return date.getFullYear() + "-" + (m < 10 ? "0" + m : "" + m) + "-" + (d < 10 ? "0" + d : "" + d) + " " + (h < 10 ? "0" + h : "" + h) + ":" + (mi < 10 ? "0" + mi : "" + mi) + ":" + (s < 10 ? "0" + s : "" + s);
};
HxOverrides.cca = function(s,index) {
	var x = s.charCodeAt(index);
	if(x != x) {
		return undefined;
	}
	return x;
};
HxOverrides.substr = function(s,pos,len) {
	if(len == null) {
		len = s.length;
	} else if(len < 0) {
		if(pos == 0) {
			len = s.length + len;
		} else {
			return "";
		}
	}
	return s.substr(pos,len);
};
HxOverrides.remove = function(a,obj) {
	var i = a.indexOf(obj);
	if(i == -1) {
		return false;
	}
	a.splice(i,1);
	return true;
};
HxOverrides.now = function() {
	return Date.now();
};
var Lambda = function() { };
Lambda.__name__ = true;
Lambda.array = function(it) {
	var a = [];
	var i = $getIterator(it);
	while(i.hasNext()) {
		var i1 = i.next();
		a.push(i1);
	}
	return a;
};
Lambda.has = function(it,elt) {
	var x = $getIterator(it);
	while(x.hasNext()) {
		var x1 = x.next();
		if(x1 == elt) {
			return true;
		}
	}
	return false;
};
Math.__name__ = true;
var Reflect = function() { };
Reflect.__name__ = true;
Reflect.field = function(o,field) {
	try {
		return o[field];
	} catch( _g ) {
		return null;
	}
};
Reflect.fields = function(o) {
	var a = [];
	if(o != null) {
		var hasOwnProperty = Object.prototype.hasOwnProperty;
		for( var f in o ) {
		if(f != "__id__" && f != "hx__closures__" && hasOwnProperty.call(o,f)) {
			a.push(f);
		}
		}
	}
	return a;
};
Reflect.isFunction = function(f) {
	if(typeof(f) == "function") {
		return !(f.__name__ || f.__ename__);
	} else {
		return false;
	}
};
Reflect.compare = function(a,b) {
	if(a == b) {
		return 0;
	} else if(a > b) {
		return 1;
	} else {
		return -1;
	}
};
var Std = function() { };
Std.__name__ = true;
Std.string = function(s) {
	return js_Boot.__string_rec(s,"");
};
Std.parseInt = function(x) {
	var v = parseInt(x);
	if(isNaN(v)) {
		return null;
	}
	return v;
};
var StringBuf = function() {
	this.b = "";
};
StringBuf.__name__ = true;
StringBuf.prototype = {
	b: null
	,__class__: StringBuf
};
var StringTools = function() { };
StringTools.__name__ = true;
StringTools.htmlEscape = function(s,quotes) {
	var buf_b = "";
	var _g_offset = 0;
	var _g_s = s;
	while(_g_offset < _g_s.length) {
		var s = _g_s;
		var index = _g_offset++;
		var c = s.charCodeAt(index);
		if(c >= 55296 && c <= 56319) {
			c = c - 55232 << 10 | s.charCodeAt(index + 1) & 1023;
		}
		var c1 = c;
		if(c1 >= 65536) {
			++_g_offset;
		}
		var code = c1;
		switch(code) {
		case 34:
			if(quotes) {
				buf_b += "&quot;";
			} else {
				buf_b += String.fromCodePoint(code);
			}
			break;
		case 38:
			buf_b += "&amp;";
			break;
		case 39:
			if(quotes) {
				buf_b += "&#039;";
			} else {
				buf_b += String.fromCodePoint(code);
			}
			break;
		case 60:
			buf_b += "&lt;";
			break;
		case 62:
			buf_b += "&gt;";
			break;
		default:
			buf_b += String.fromCodePoint(code);
		}
	}
	return buf_b;
};
StringTools.isSpace = function(s,pos) {
	var c = HxOverrides.cca(s,pos);
	if(!(c > 8 && c < 14)) {
		return c == 32;
	} else {
		return true;
	}
};
StringTools.ltrim = function(s) {
	var l = s.length;
	var r = 0;
	while(r < l && StringTools.isSpace(s,r)) ++r;
	if(r > 0) {
		return HxOverrides.substr(s,r,l - r);
	} else {
		return s;
	}
};
StringTools.rtrim = function(s) {
	var l = s.length;
	var r = 0;
	while(r < l && StringTools.isSpace(s,l - r - 1)) ++r;
	if(r > 0) {
		return HxOverrides.substr(s,0,l - r);
	} else {
		return s;
	}
};
StringTools.trim = function(s) {
	return StringTools.ltrim(StringTools.rtrim(s));
};
StringTools.lpad = function(s,c,l) {
	if(c.length <= 0) {
		return s;
	}
	var buf_b = "";
	l -= s.length;
	while(buf_b.length < l) buf_b += c == null ? "null" : "" + c;
	buf_b += s == null ? "null" : "" + s;
	return buf_b;
};
StringTools.replace = function(s,sub,by) {
	return s.split(sub).join(by);
};
var ValueType = $hxEnums["ValueType"] = { __ename__:true,__constructs__:null
	,TNull: {_hx_name:"TNull",_hx_index:0,__enum__:"ValueType",toString:$estr}
	,TInt: {_hx_name:"TInt",_hx_index:1,__enum__:"ValueType",toString:$estr}
	,TFloat: {_hx_name:"TFloat",_hx_index:2,__enum__:"ValueType",toString:$estr}
	,TBool: {_hx_name:"TBool",_hx_index:3,__enum__:"ValueType",toString:$estr}
	,TObject: {_hx_name:"TObject",_hx_index:4,__enum__:"ValueType",toString:$estr}
	,TFunction: {_hx_name:"TFunction",_hx_index:5,__enum__:"ValueType",toString:$estr}
	,TClass: ($_=function(c) { return {_hx_index:6,c:c,__enum__:"ValueType",toString:$estr}; },$_._hx_name="TClass",$_.__params__ = ["c"],$_)
	,TEnum: ($_=function(e) { return {_hx_index:7,e:e,__enum__:"ValueType",toString:$estr}; },$_._hx_name="TEnum",$_.__params__ = ["e"],$_)
	,TUnknown: {_hx_name:"TUnknown",_hx_index:8,__enum__:"ValueType",toString:$estr}
};
ValueType.__constructs__ = [ValueType.TNull,ValueType.TInt,ValueType.TFloat,ValueType.TBool,ValueType.TObject,ValueType.TFunction,ValueType.TClass,ValueType.TEnum,ValueType.TUnknown];
var Type = function() { };
Type.__name__ = true;
Type.getInstanceFields = function(c) {
	var a = [];
	for(var i in c.prototype) a.push(i);
	HxOverrides.remove(a,"__class__");
	HxOverrides.remove(a,"__properties__");
	return a;
};
Type.typeof = function(v) {
	switch(typeof(v)) {
	case "boolean":
		return ValueType.TBool;
	case "function":
		if(v.__name__ || v.__ename__) {
			return ValueType.TObject;
		}
		return ValueType.TFunction;
	case "number":
		if(Math.ceil(v) == v % 2147483648.0) {
			return ValueType.TInt;
		}
		return ValueType.TFloat;
	case "object":
		if(v == null) {
			return ValueType.TNull;
		}
		var e = v.__enum__;
		if(e != null) {
			return ValueType.TEnum($hxEnums[e]);
		}
		var c = js_Boot.getClass(v);
		if(c != null) {
			return ValueType.TClass(c);
		}
		return ValueType.TObject;
	case "string":
		return ValueType.TClass(String);
	case "undefined":
		return ValueType.TNull;
	default:
		return ValueType.TUnknown;
	}
};
var coopy_Alignment = function() {
	this.map_a2b = new haxe_ds_IntMap();
	this.map_b2a = new haxe_ds_IntMap();
	this.ha = this.hb = 0;
	this.map_count = 0;
	this.reference = null;
	this.meta = null;
	this.comp = null;
	this.order_cache_has_reference = false;
	this.ia = -1;
	this.ib = -1;
	this.marked_as_identical = false;
};
coopy_Alignment.__name__ = true;
coopy_Alignment.prototype = {
	map_a2b: null
	,map_b2a: null
	,ha: null
	,hb: null
	,ta: null
	,tb: null
	,ia: null
	,ib: null
	,map_count: null
	,order_cache: null
	,order_cache_has_reference: null
	,index_columns: null
	,marked_as_identical: null
	,reference: null
	,meta: null
	,comp: null
	,has_addition: null
	,has_removal: null
	,range: function(ha,hb) {
		this.ha = ha;
		this.hb = hb;
	}
	,tables: function(ta,tb) {
		this.ta = ta;
		this.tb = tb;
	}
	,headers: function(ia,ib) {
		this.ia = ia;
		this.ib = ib;
	}
	,setRowlike: function(flag) {
	}
	,link: function(a,b) {
		if(a != -1) {
			this.map_a2b.h[a] = b;
		} else {
			this.has_addition = true;
		}
		if(b != -1) {
			this.map_b2a.h[b] = a;
		} else {
			this.has_removal = true;
		}
		this.map_count++;
	}
	,addIndexColumns: function(unit) {
		if(this.index_columns == null) {
			this.index_columns = [];
		}
		this.index_columns.push(unit);
	}
	,getIndexColumns: function() {
		return this.index_columns;
	}
	,a2b: function(a) {
		return this.map_a2b.h[a];
	}
	,b2a: function(b) {
		return this.map_b2a.h[b];
	}
	,count: function() {
		return this.map_count;
	}
	,toString: function() {
		var result = "" + (this.map_a2b == null ? "null" : this.map_a2b.toString()) + " // " + (this.map_b2a == null ? "null" : this.map_b2a.toString());
		if(this.reference != null) {
			result += " (" + Std.string(this.reference) + ")";
		}
		return result;
	}
	,toOrder: function() {
		if(this.order_cache != null) {
			if(this.reference != null) {
				if(!this.order_cache_has_reference) {
					this.order_cache = null;
				}
			}
		}
		if(this.order_cache == null) {
			this.order_cache = this.toOrder3();
		}
		if(this.reference != null) {
			this.order_cache_has_reference = true;
		}
		return this.order_cache;
	}
	,addToOrder: function(l,r,p) {
		if(p == null) {
			p = -2;
		}
		if(this.order_cache == null) {
			this.order_cache = new coopy_Ordering();
		}
		this.order_cache.add(l,r,p);
		this.order_cache_has_reference = p != -2;
	}
	,getSource: function() {
		return this.ta;
	}
	,getTarget: function() {
		return this.tb;
	}
	,getSourceHeader: function() {
		return this.ia;
	}
	,getTargetHeader: function() {
		return this.ib;
	}
	,toOrder3: function() {
		var order = [];
		if(this.reference == null) {
			var k = this.map_a2b.keys();
			while(k.hasNext()) {
				var k1 = k.next();
				var unit = new coopy_Unit();
				unit.l = k1;
				unit.r = this.a2b(k1);
				order.push(unit);
			}
			var k = this.map_b2a.keys();
			while(k.hasNext()) {
				var k1 = k.next();
				if(this.b2a(k1) == -1) {
					var unit = new coopy_Unit();
					unit.l = -1;
					unit.r = k1;
					order.push(unit);
				}
			}
		} else {
			var k = this.map_a2b.keys();
			while(k.hasNext()) {
				var k1 = k.next();
				var unit = new coopy_Unit();
				unit.p = k1;
				unit.l = this.reference.a2b(k1);
				unit.r = this.a2b(k1);
				order.push(unit);
			}
			var k = this.reference.map_b2a.keys();
			while(k.hasNext()) {
				var k1 = k.next();
				if(this.reference.b2a(k1) == -1) {
					var unit = new coopy_Unit();
					unit.p = -1;
					unit.l = k1;
					unit.r = -1;
					order.push(unit);
				}
			}
			var k = this.map_b2a.keys();
			while(k.hasNext()) {
				var k1 = k.next();
				if(this.b2a(k1) == -1) {
					var unit = new coopy_Unit();
					unit.p = -1;
					unit.l = -1;
					unit.r = k1;
					order.push(unit);
				}
			}
		}
		var top = order.length;
		var remotes = [];
		var locals = [];
		var _g = 0;
		var _g1 = top;
		while(_g < _g1) {
			var o = _g++;
			if(order[o].r >= 0) {
				remotes.push(o);
			} else {
				locals.push(o);
			}
		}
		var remote_sort = function(a,b) {
			return order[a].r - order[b].r;
		};
		var local_sort = function(a,b) {
			if(a == b) {
				return 0;
			}
			if(order[a].l >= 0 && order[b].l >= 0) {
				return order[a].l - order[b].l;
			}
			if(order[a].l >= 0) {
				return 1;
			}
			if(order[b].l >= 0) {
				return -1;
			}
			return a - b;
		};
		if(this.reference != null) {
			remote_sort = function(a,b) {
				if(a == b) {
					return 0;
				}
				var o1 = order[a].r - order[b].r;
				if(order[a].p >= 0 && order[b].p >= 0) {
					var o2 = order[a].p - order[b].p;
					if(o1 * o2 < 0) {
						return o1;
					}
					var o3 = order[a].l - order[b].l;
					return o3;
				}
				return o1;
			};
			local_sort = function(a,b) {
				if(a == b) {
					return 0;
				}
				if(order[a].l >= 0 && order[b].l >= 0) {
					var o1 = order[a].l - order[b].l;
					if(order[a].p >= 0 && order[b].p >= 0) {
						var o2 = order[a].p - order[b].p;
						if(o1 * o2 < 0) {
							return o1;
						}
						return o2;
					}
				}
				if(order[a].l >= 0) {
					return 1;
				}
				if(order[b].l >= 0) {
					return -1;
				}
				return a - b;
			};
		}
		remotes.sort(remote_sort);
		locals.sort(local_sort);
		var revised_order = [];
		var at_r = 0;
		var at_l = 0;
		var _g = 0;
		var _g1 = top;
		while(_g < _g1) {
			var o = _g++;
			if(at_r < remotes.length && at_l < locals.length) {
				var ur = order[remotes[at_r]];
				var ul = order[locals[at_l]];
				if(ul.l == -1 && ul.p >= 0 && ur.p >= 0) {
					if(ur.p > ul.p) {
						revised_order.push(ul);
						++at_l;
						continue;
					}
				} else if(ur.l > ul.l) {
					revised_order.push(ul);
					++at_l;
					continue;
				}
				revised_order.push(ur);
				++at_r;
				continue;
			}
			if(at_r < remotes.length) {
				var ur1 = order[remotes[at_r]];
				revised_order.push(ur1);
				++at_r;
				continue;
			}
			if(at_l < locals.length) {
				var ul1 = order[locals[at_l]];
				revised_order.push(ul1);
				++at_l;
				continue;
			}
		}
		order = revised_order;
		var result = new coopy_Ordering();
		result.setList(order);
		if(this.reference == null) {
			result.ignoreParent();
		}
		return result;
	}
	,markIdentical: function() {
		this.marked_as_identical = true;
	}
	,isMarkedAsIdentical: function() {
		return this.marked_as_identical;
	}
	,__class__: coopy_Alignment
};
var coopy_CellBuilder = function() { };
coopy_CellBuilder.__name__ = true;
coopy_CellBuilder.prototype = {
	needSeparator: null
	,setSeparator: null
	,setConflictSeparator: null
	,setView: null
	,update: null
	,conflict: null
	,marker: null
	,links: null
	,__class__: coopy_CellBuilder
};
var coopy_CellInfo = $hx_exports["coopy"]["CellInfo"] = function() {
};
coopy_CellInfo.__name__ = true;
coopy_CellInfo.prototype = {
	raw: null
	,value: null
	,pretty_value: null
	,category: null
	,category_given_tr: null
	,separator: null
	,pretty_separator: null
	,updated: null
	,conflicted: null
	,pvalue: null
	,lvalue: null
	,rvalue: null
	,meta: null
	,toString: function() {
		if(!this.updated) {
			return this.value;
		}
		if(!this.conflicted) {
			return this.lvalue + "::" + this.rvalue;
		}
		return this.pvalue + "||" + this.lvalue + "::" + this.rvalue;
	}
	,__class__: coopy_CellInfo
};
var coopy_ColumnChange = $hx_exports["coopy"]["ColumnChange"] = function() {
};
coopy_ColumnChange.__name__ = true;
coopy_ColumnChange.prototype = {
	prevName: null
	,name: null
	,props: null
	,__class__: coopy_ColumnChange
};
var coopy_Table = function() { };
coopy_Table.__name__ = true;
coopy_Table.prototype = {
	getCell: null
	,setCell: null
	,getCellView: null
	,isResizable: null
	,resize: null
	,clear: null
	,insertOrDeleteRows: null
	,insertOrDeleteColumns: null
	,trimBlank: null
	,get_width: null
	,get_height: null
	,getData: null
	,clone: null
	,create: null
	,getMeta: null
	,__class__: coopy_Table
};
var coopy_CombinedTable = $hx_exports["coopy"]["CombinedTable"] = function(t) {
	this.t = t;
	this.dx = 0;
	this.dy = 0;
	this.core = t;
	this.head = null;
	if(t.get_width() < 1 || t.get_height() < 1) {
		return;
	}
	var v = t.getCellView();
	if(v.toString(t.getCell(0,0)) != "@@") {
		return;
	}
	this.dx = 1;
	this.dy = 0;
	var _g = 0;
	var _g1 = t.get_height();
	while(_g < _g1) {
		var y = _g++;
		var txt = v.toString(t.getCell(0,y));
		if(txt == null || txt == "" || txt == "null") {
			break;
		}
		this.dy++;
	}
	this.head = new coopy_CombinedTableHead(this,this.dx,this.dy);
	this.body = new coopy_CombinedTableBody(this,this.dx,this.dy);
	this.core = this.body;
	this.meta = new coopy_SimpleMeta(this.head);
};
coopy_CombinedTable.__name__ = true;
coopy_CombinedTable.__interfaces__ = [coopy_Table];
coopy_CombinedTable.prototype = {
	t: null
	,body: null
	,head: null
	,dx: null
	,dy: null
	,core: null
	,meta: null
	,all: function() {
		return this.t;
	}
	,getTable: function() {
		return this;
	}
	,get_width: function() {
		return this.core.get_width();
	}
	,get_height: function() {
		return this.core.get_height();
	}
	,getCell: function(x,y) {
		return this.core.getCell(x,y);
	}
	,setCell: function(x,y,c) {
		this.core.setCell(x,y,c);
	}
	,toString: function() {
		return coopy_SimpleTable.tableToString(this);
	}
	,getCellView: function() {
		return this.t.getCellView();
	}
	,isResizable: function() {
		return this.core.isResizable();
	}
	,resize: function(w,h) {
		return this.core.resize(h,w);
	}
	,clear: function() {
		this.core.clear();
	}
	,insertOrDeleteRows: function(fate,hfate) {
		return this.core.insertOrDeleteRows(fate,hfate);
	}
	,insertOrDeleteColumns: function(fate,wfate) {
		return this.core.insertOrDeleteColumns(fate,wfate);
	}
	,trimBlank: function() {
		return this.core.trimBlank();
	}
	,getData: function() {
		return null;
	}
	,clone: function() {
		return this.core.clone();
	}
	,create: function() {
		return this.t.create();
	}
	,getMeta: function() {
		return this.meta;
	}
	,__class__: coopy_CombinedTable
};
var coopy_CombinedTableBody = function(parent,dx,dy) {
	this.parent = parent;
	this.dx = dx;
	this.dy = dy;
	this.all = parent.all();
};
coopy_CombinedTableBody.__name__ = true;
coopy_CombinedTableBody.__interfaces__ = [coopy_Table];
coopy_CombinedTableBody.prototype = {
	parent: null
	,dx: null
	,dy: null
	,all: null
	,meta: null
	,getTable: function() {
		return this;
	}
	,get_width: function() {
		return this.all.get_width() - 1;
	}
	,get_height: function() {
		return this.all.get_height() - this.dy + 1;
	}
	,getCell: function(x,y) {
		if(y == 0) {
			if(this.meta == null) {
				this.meta = this.parent.getMeta().asTable();
			}
			return this.meta.getCell(x + this.dx,0);
		}
		return this.all.getCell(x + this.dx,y + this.dy - 1);
	}
	,setCell: function(x,y,c) {
		if(y == 0) {
			this.all.setCell(x + this.dx,0,c);
			return;
		}
		this.all.setCell(x + this.dx,y + this.dy - 1,c);
	}
	,toString: function() {
		return coopy_SimpleTable.tableToString(this);
	}
	,getCellView: function() {
		return this.all.getCellView();
	}
	,isResizable: function() {
		return this.all.isResizable();
	}
	,resize: function(w,h) {
		return this.all.resize(w + 1,h + this.dy);
	}
	,clear: function() {
		this.all.clear();
		this.dx = 0;
		this.dy = 0;
	}
	,insertOrDeleteRows: function(fate,hfate) {
		var fate2 = [];
		var _g = 0;
		var _g1 = this.dy;
		while(_g < _g1) {
			var y = _g++;
			fate2.push(y);
		}
		var hdr = true;
		var _g = 0;
		while(_g < fate.length) {
			var f = fate[_g];
			++_g;
			if(hdr) {
				hdr = false;
				continue;
			}
			fate2.push(f >= 0 ? f + this.dy - 1 : f);
		}
		return this.all.insertOrDeleteRows(fate2,hfate + this.dy - 1);
	}
	,insertOrDeleteColumns: function(fate,wfate) {
		var fate2 = [];
		var _g = 0;
		var _g1 = this.dx + 1;
		while(_g < _g1) {
			var x = _g++;
			fate2.push(x);
		}
		var _g = 0;
		while(_g < fate.length) {
			var f = fate[_g];
			++_g;
			fate2.push(f >= 0 ? f + this.dx + 1 : f);
		}
		return this.all.insertOrDeleteColumns(fate2,wfate + this.dx);
	}
	,trimBlank: function() {
		return this.all.trimBlank();
	}
	,getData: function() {
		return null;
	}
	,clone: function() {
		return new coopy_CombinedTable(this.all.clone());
	}
	,create: function() {
		return new coopy_CombinedTable(this.all.create());
	}
	,getMeta: function() {
		return this.parent.getMeta();
	}
	,__class__: coopy_CombinedTableBody
};
var coopy_CombinedTableHead = function(parent,dx,dy) {
	this.parent = parent;
	this.dx = dx;
	this.dy = dy;
	this.all = parent.all();
};
coopy_CombinedTableHead.__name__ = true;
coopy_CombinedTableHead.__interfaces__ = [coopy_Table];
coopy_CombinedTableHead.prototype = {
	parent: null
	,dx: null
	,dy: null
	,all: null
	,getTable: function() {
		return this;
	}
	,get_width: function() {
		return this.all.get_width();
	}
	,get_height: function() {
		return this.dy;
	}
	,getCell: function(x,y) {
		if(x == 0) {
			var v = this.getCellView();
			var txt = v.toString(this.all.getCell(x,y));
			if(txt.charAt(0) == "@") {
				return HxOverrides.substr(txt,1,txt.length);
			}
		}
		return this.all.getCell(x,y);
	}
	,setCell: function(x,y,c) {
		this.all.setCell(x,y,c);
	}
	,toString: function() {
		return coopy_SimpleTable.tableToString(this);
	}
	,getCellView: function() {
		return this.all.getCellView();
	}
	,isResizable: function() {
		return false;
	}
	,resize: function(w,h) {
		return false;
	}
	,clear: function() {
	}
	,insertOrDeleteRows: function(fate,hfate) {
		return false;
	}
	,insertOrDeleteColumns: function(fate,wfate) {
		return this.all.insertOrDeleteColumns(fate,wfate);
	}
	,trimBlank: function() {
		return false;
	}
	,getData: function() {
		return null;
	}
	,clone: function() {
		return null;
	}
	,create: function() {
		return null;
	}
	,getMeta: function() {
		return null;
	}
	,__class__: coopy_CombinedTableHead
};
var coopy_CompareFlags = $hx_exports["coopy"]["CompareFlags"] = function() {
	this.ordered = true;
	this.show_unchanged = false;
	this.unchanged_context = 1;
	this.always_show_order = false;
	this.never_show_order = true;
	this.show_unchanged_columns = false;
	this.unchanged_column_context = 1;
	this.always_show_header = true;
	this.acts = null;
	this.ids = null;
	this.columns_to_ignore = null;
	this.allow_nested_cells = false;
	this.warnings = null;
	this.diff_strategy = null;
	this.show_meta = true;
	this.show_unchanged_meta = false;
	this.tables = null;
	this.parent = null;
	this.count_like_a_spreadsheet = true;
	this.ignore_whitespace = false;
	this.ignore_case = false;
	this.ignore_epsilon = -1;
	this.terminal_format = null;
	this.use_glyphs = true;
	this.quote_html = true;
};
coopy_CompareFlags.__name__ = true;
coopy_CompareFlags.prototype = {
	ordered: null
	,show_unchanged: null
	,unchanged_context: null
	,always_show_order: null
	,never_show_order: null
	,show_unchanged_columns: null
	,unchanged_column_context: null
	,always_show_header: null
	,acts: null
	,ids: null
	,columns_to_ignore: null
	,tables: null
	,allow_nested_cells: null
	,warnings: null
	,diff_strategy: null
	,padding_strategy: null
	,show_meta: null
	,show_unchanged_meta: null
	,parent: null
	,count_like_a_spreadsheet: null
	,ignore_whitespace: null
	,ignore_case: null
	,ignore_epsilon: null
	,terminal_format: null
	,use_glyphs: null
	,quote_html: null
	,filter: function(act,allow) {
		if(this.acts == null) {
			this.acts = new haxe_ds_StringMap();
			this.acts.h["update"] = !allow;
			this.acts.h["insert"] = !allow;
			this.acts.h["delete"] = !allow;
			this.acts.h["column"] = !allow;
		}
		if(!Object.prototype.hasOwnProperty.call(this.acts.h,act)) {
			return false;
		}
		this.acts.h[act] = allow;
		return true;
	}
	,allowUpdate: function() {
		if(this.acts == null) {
			return true;
		}
		if(Object.prototype.hasOwnProperty.call(this.acts.h,"update")) {
			return this.acts.h["update"];
		} else {
			return false;
		}
	}
	,allowInsert: function() {
		if(this.acts == null) {
			return true;
		}
		if(Object.prototype.hasOwnProperty.call(this.acts.h,"insert")) {
			return this.acts.h["insert"];
		} else {
			return false;
		}
	}
	,allowDelete: function() {
		if(this.acts == null) {
			return true;
		}
		if(Object.prototype.hasOwnProperty.call(this.acts.h,"delete")) {
			return this.acts.h["delete"];
		} else {
			return false;
		}
	}
	,allowColumn: function() {
		if(this.acts == null) {
			return true;
		}
		if(Object.prototype.hasOwnProperty.call(this.acts.h,"column")) {
			return this.acts.h["column"];
		} else {
			return false;
		}
	}
	,getIgnoredColumns: function() {
		if(this.columns_to_ignore == null) {
			return null;
		}
		var ignore = new haxe_ds_StringMap();
		var _g = 0;
		var _g1 = this.columns_to_ignore.length;
		while(_g < _g1) {
			var i = _g++;
			ignore.h[this.columns_to_ignore[i]] = true;
		}
		return ignore;
	}
	,addPrimaryKey: function(column) {
		if(this.ids == null) {
			this.ids = [];
		}
		this.ids.push(column);
	}
	,ignoreColumn: function(column) {
		if(this.columns_to_ignore == null) {
			this.columns_to_ignore = [];
		}
		this.columns_to_ignore.push(column);
	}
	,addTable: function(table) {
		if(this.tables == null) {
			this.tables = [];
		}
		this.tables.push(table);
	}
	,addWarning: function(warn) {
		if(this.warnings == null) {
			this.warnings = [];
		}
		this.warnings.push(warn);
	}
	,getWarning: function() {
		return this.warnings.join("\n");
	}
	,getNameByRole: function(name,role) {
		var parts = name.split(":");
		if(parts.length <= 1) {
			return name;
		}
		if(role == "parent") {
			return parts[0];
		}
		if(role == "local") {
			return parts[parts.length - 2];
		}
		return parts[parts.length - 1];
	}
	,getCanonicalName: function(name) {
		return this.getNameByRole(name,"local");
	}
	,getIdsByRole: function(role) {
		var result = [];
		if(this.ids == null) {
			return result;
		}
		var _g = 0;
		var _g1 = this.ids;
		while(_g < _g1.length) {
			var name = _g1[_g];
			++_g;
			result.push(this.getNameByRole(name,role));
		}
		return result;
	}
	,__class__: coopy_CompareFlags
};
var coopy_CompareTable = $hx_exports["coopy"]["CompareTable"] = function(comp) {
	this.comp = comp;
	if(comp.compare_flags != null) {
		if(comp.compare_flags.parent != null) {
			comp.p = comp.compare_flags.parent;
		}
	}
};
coopy_CompareTable.__name__ = true;
coopy_CompareTable.prototype = {
	comp: null
	,indexes: null
	,run: function() {
		if(this.useSql()) {
			this.comp.completed = true;
			return false;
		}
		var more = this.compareCore();
		while(more && this.comp.run_to_completion) more = this.compareCore();
		return !more;
	}
	,align: function() {
		while(!this.comp.completed) this.run();
		var alignment = new coopy_Alignment();
		this.alignCore(alignment);
		alignment.comp = this.comp;
		this.comp.alignment = alignment;
		return alignment;
	}
	,getComparisonState: function() {
		return this.comp;
	}
	,alignCore: function(align) {
		if(this.useSql()) {
			var tab1 = null;
			var tab2 = null;
			var tab3 = null;
			if(this.comp.p == null) {
				tab1 = this.comp.a;
				tab2 = this.comp.b;
			} else {
				align.reference = new coopy_Alignment();
				tab1 = this.comp.p;
				tab2 = this.comp.b;
				tab3 = this.comp.a;
			}
			var db = null;
			if(tab1 != null) {
				db = tab1.getDatabase();
			}
			if(db == null && tab2 != null) {
				db = tab2.getDatabase();
			}
			if(db == null && tab3 != null) {
				db = tab3.getDatabase();
			}
			var sc = new coopy_SqlCompare(db,tab1,tab2,tab3,align,this.comp.compare_flags);
			sc.apply();
			if(this.comp.p != null) {
				align.meta.reference = align.reference.meta;
			}
			return;
		}
		if(this.comp.p == null) {
			this.alignCore2(align,this.comp.a,this.comp.b);
			return;
		}
		align.reference = new coopy_Alignment();
		this.alignCore2(align,this.comp.p,this.comp.b);
		this.alignCore2(align.reference,this.comp.p,this.comp.a);
		align.meta.reference = align.reference.meta;
	}
	,alignCore2: function(align,a,b) {
		if(align.meta == null) {
			align.meta = new coopy_Alignment();
		}
		this.alignColumns(align.meta,a,b);
		var column_order = align.meta.toOrder();
		align.range(a.get_height(),b.get_height());
		align.tables(a,b);
		align.setRowlike(true);
		var w = a.get_width();
		var ha = a.get_height();
		var hb = b.get_height();
		var av = a.getCellView();
		var ids = null;
		var ignore = null;
		var ordered = true;
		if(this.comp.compare_flags != null) {
			ids = this.comp.compare_flags.ids;
			ignore = this.comp.compare_flags.getIgnoredColumns();
			ordered = this.comp.compare_flags.ordered;
		}
		var common_units = [];
		var ra_header = align.getSourceHeader();
		var rb_header = align.getSourceHeader();
		var _g = 0;
		var _g1 = column_order.getList();
		while(_g < _g1.length) {
			var unit = _g1[_g];
			++_g;
			if(unit.l >= 0 && unit.r >= 0 && unit.p != -1) {
				if(ignore != null) {
					if(unit.l >= 0 && ra_header >= 0 && ra_header < a.get_height()) {
						var name = av.toString(a.getCell(unit.l,ra_header));
						if(Object.prototype.hasOwnProperty.call(ignore.h,name)) {
							continue;
						}
					}
					if(unit.r >= 0 && rb_header >= 0 && rb_header < b.get_height()) {
						var name1 = av.toString(b.getCell(unit.r,rb_header));
						if(Object.prototype.hasOwnProperty.call(ignore.h,name1)) {
							continue;
						}
					}
				}
				common_units.push(unit);
			}
		}
		var index_top = null;
		var pending_ct = ha;
		var reverse_pending_ct = hb;
		var used_h = { };
		var used_reverse_h = { };
		if(ids != null) {
			index_top = new coopy_IndexPair(this.comp.compare_flags);
			var ids_as_map_h = Object.create(null);
			var _g = 0;
			while(_g < ids.length) {
				var id = ids[_g];
				++_g;
				ids_as_map_h[id] = true;
			}
			var _g = 0;
			while(_g < common_units.length) {
				var unit = common_units[_g];
				++_g;
				var na = av.toString(a.getCell(unit.l,0));
				var nb = av.toString(b.getCell(unit.r,0));
				if(Object.prototype.hasOwnProperty.call(ids_as_map_h,na) || Object.prototype.hasOwnProperty.call(ids_as_map_h,nb)) {
					index_top.addColumns(unit.l,unit.r);
					align.addIndexColumns(unit);
				}
			}
			index_top.indexTables(a,b,1);
			if(this.indexes != null) {
				this.indexes.push(index_top);
			}
			var _g = 0;
			var _g1 = ha;
			while(_g < _g1) {
				var j = _g++;
				var cross = index_top.queryLocal(j);
				var spot_a = cross.spot_a;
				var spot_b = cross.spot_b;
				if(spot_a != 1 || spot_b != 1) {
					continue;
				}
				var jb = cross.item_b.lst[0];
				align.link(j,jb);
				used_h[jb] = 1;
				if(!used_reverse_h.hasOwnProperty(j)) {
					--reverse_pending_ct;
				}
				used_reverse_h[j] = 1;
			}
		} else {
			var N = 5;
			var columns = [];
			if(common_units.length > N) {
				var columns_eval = [];
				var _g = 0;
				var _g1 = common_units.length;
				while(_g < _g1) {
					var i = _g++;
					var ct = 0;
					var mem_h = Object.create(null);
					var mem2_h = Object.create(null);
					var ca = common_units[i].l;
					var cb = common_units[i].r;
					var _g2 = 0;
					var _g3 = ha;
					while(_g2 < _g3) {
						var j = _g2++;
						var key = av.toString(a.getCell(ca,j));
						if(!Object.prototype.hasOwnProperty.call(mem_h,key)) {
							mem_h[key] = 1;
							++ct;
						}
					}
					var _g4 = 0;
					var _g5 = hb;
					while(_g4 < _g5) {
						var j1 = _g4++;
						var key1 = av.toString(b.getCell(cb,j1));
						if(!Object.prototype.hasOwnProperty.call(mem2_h,key1)) {
							mem2_h[key1] = 1;
							++ct;
						}
					}
					columns_eval.push([i,ct]);
				}
				var sorter = function(a,b) {
					if(a[1] < b[1]) {
						return 1;
					}
					if(a[1] > b[1]) {
						return -1;
					}
					if(a[0] > b[0]) {
						return 1;
					}
					if(a[0] < b[0]) {
						return -1;
					}
					return 0;
				};
				columns_eval.sort(sorter);
				var _g = [];
				var _g_current = 0;
				var _g_array = columns_eval;
				while(_g_current < _g_array.length) {
					var x = _g_array[_g_current++];
					_g.push(x[0]);
				}
				columns = Lambda.array(_g);
				columns = columns.slice(0,N);
			} else {
				var _g = 0;
				var _g1 = common_units.length;
				while(_g < _g1) {
					var i = _g++;
					columns.push(i);
				}
			}
			var top = Math.round(Math.pow(2,columns.length));
			var pending = new haxe_ds_IntMap();
			var _g = 0;
			var _g1 = ha;
			while(_g < _g1) {
				var j = _g++;
				pending.h[j] = j;
			}
			var added_columns_h = { };
			var index_ct = 0;
			var _g = 0;
			var _g1 = top;
			while(_g < _g1) {
				var k = _g++;
				if(k == 0) {
					continue;
				}
				if(pending_ct == 0) {
					break;
				}
				var active_columns = [];
				var kk = k;
				var at = 0;
				while(kk > 0) {
					if(kk % 2 == 1) {
						active_columns.push(columns[at]);
					}
					kk >>= 1;
					++at;
				}
				var index = new coopy_IndexPair(this.comp.compare_flags);
				var _g2 = 0;
				var _g3 = active_columns.length;
				while(_g2 < _g3) {
					var k1 = _g2++;
					var col = active_columns[k1];
					var unit = common_units[col];
					index.addColumns(unit.l,unit.r);
					if(!added_columns_h.hasOwnProperty(col)) {
						align.addIndexColumns(unit);
						added_columns_h[col] = true;
					}
				}
				index.indexTables(a,b,1);
				if(k == top - 1) {
					index_top = index;
				}
				var h = a.get_height();
				if(b.get_height() > h) {
					h = b.get_height();
				}
				if(h < 1) {
					h = 1;
				}
				var wide_top_freq = index.getTopFreq();
				var ratio = wide_top_freq;
				ratio /= h + 20;
				if(ratio >= 0.1) {
					if(index_ct > 0 || k < top - 1) {
						continue;
					}
				}
				++index_ct;
				if(this.indexes != null) {
					this.indexes.push(index);
				}
				var fixed = [];
				var j = pending.keys();
				while(j.hasNext()) {
					var j1 = j.next();
					var cross = index.queryLocal(j1);
					var spot_a = cross.spot_a;
					var spot_b = cross.spot_b;
					if(spot_a != 1 || spot_b != 1) {
						continue;
					}
					var val = cross.item_b.lst[0];
					if(!used_h.hasOwnProperty(val)) {
						fixed.push(j1);
						align.link(j1,val);
						used_h[val] = 1;
						if(!used_reverse_h.hasOwnProperty(j1)) {
							--reverse_pending_ct;
						}
						used_reverse_h[j1] = 1;
					}
				}
				var _g4 = 0;
				var _g5 = fixed.length;
				while(_g4 < _g5) {
					var j2 = _g4++;
					pending.remove(fixed[j2]);
					--pending_ct;
				}
			}
		}
		if(index_top != null) {
			var offset = 0;
			var scale = 1;
			var _g = 0;
			while(_g < 2) {
				var sgn = _g++;
				if(pending_ct > 0) {
					var xb = null;
					if(scale == -1 && hb > 0) {
						xb = hb - 1;
					}
					var _g1 = 0;
					var _g2 = ha;
					while(_g1 < _g2) {
						var xa0 = _g1++;
						var xa = xa0 * scale + offset;
						var xb2 = align.a2b(xa);
						if(xb2 != null) {
							xb = xb2 + scale;
							if(xb >= hb || xb < 0) {
								break;
							}
							continue;
						}
						if(xb == null) {
							continue;
						}
						var ka = index_top.localKey(xa);
						var kb = index_top.remoteKey(xb);
						if(ka != kb) {
							continue;
						}
						if(used_h.hasOwnProperty(xb)) {
							continue;
						}
						align.link(xa,xb);
						used_h[xb] = 1;
						used_reverse_h[xa] = 1;
						--pending_ct;
						xb += scale;
						if(xb >= hb || xb < 0) {
							break;
						}
						if(pending_ct == 0) {
							break;
						}
					}
				}
				offset = ha - 1;
				scale = -1;
			}
			offset = 0;
			scale = 1;
			var _g = 0;
			while(_g < 2) {
				var sgn = _g++;
				if(reverse_pending_ct > 0) {
					var xa = null;
					if(scale == -1 && ha > 0) {
						xa = ha - 1;
					}
					var _g1 = 0;
					var _g2 = hb;
					while(_g1 < _g2) {
						var xb0 = _g1++;
						var xb = xb0 * scale + offset;
						var xa2 = align.b2a(xb);
						if(xa2 != null) {
							xa = xa2 + scale;
							if(xa >= ha || xa < 0) {
								break;
							}
							continue;
						}
						if(xa == null) {
							continue;
						}
						var ka = index_top.localKey(xa);
						var kb = index_top.remoteKey(xb);
						if(ka != kb) {
							continue;
						}
						if(used_reverse_h.hasOwnProperty(xa)) {
							continue;
						}
						align.link(xa,xb);
						used_h[xb] = 1;
						used_reverse_h[xa] = 1;
						--reverse_pending_ct;
						xa += scale;
						if(xa >= ha || xa < 0) {
							break;
						}
						if(reverse_pending_ct == 0) {
							break;
						}
					}
				}
				offset = hb - 1;
				scale = -1;
			}
		}
		var _g = 1;
		var _g1 = ha;
		while(_g < _g1) {
			var i = _g++;
			if(!used_reverse_h.hasOwnProperty(i)) {
				align.link(i,-1);
			}
		}
		var _g = 1;
		var _g1 = hb;
		while(_g < _g1) {
			var i = _g++;
			if(!used_h.hasOwnProperty(i)) {
				align.link(-1,i);
			}
		}
		if(ha > 0 && hb > 0) {
			align.link(0,0);
			align.headers(0,0);
		}
	}
	,alignColumns: function(align,a,b) {
		align.range(a.get_width(),b.get_width());
		align.tables(a,b);
		align.setRowlike(false);
		var slop = 5;
		var va = a.getCellView();
		var vb = b.getCellView();
		var ra_best = 0;
		var rb_best = 0;
		var ct_best = -1;
		var ma_best = null;
		var mb_best = null;
		var ra_header = 0;
		var rb_header = 0;
		var ra_uniques = 0;
		var rb_uniques = 0;
		var _g = 0;
		var _g1 = slop;
		while(_g < _g1) {
			var ra = _g++;
			var _g2 = 0;
			var _g3 = slop;
			while(_g2 < _g3) {
				var rb = _g2++;
				var ma = new haxe_ds_StringMap();
				var mb = new haxe_ds_StringMap();
				var ct = 0;
				var uniques = 0;
				if(ra < a.get_height()) {
					var _g4 = 0;
					var _g5 = a.get_width();
					while(_g4 < _g5) {
						var ca = _g4++;
						var key = va.toString(a.getCell(ca,ra));
						if(Object.prototype.hasOwnProperty.call(ma.h,key)) {
							ma.h[key] = -1;
							--uniques;
						} else {
							ma.h[key] = ca;
							++uniques;
						}
					}
					if(uniques > ra_uniques) {
						ra_header = ra;
						ra_uniques = uniques;
					}
				}
				uniques = 0;
				if(rb < b.get_height()) {
					var _g6 = 0;
					var _g7 = b.get_width();
					while(_g6 < _g7) {
						var cb = _g6++;
						var key1 = vb.toString(b.getCell(cb,rb));
						if(Object.prototype.hasOwnProperty.call(mb.h,key1)) {
							mb.h[key1] = -1;
							--uniques;
						} else {
							mb.h[key1] = cb;
							++uniques;
						}
					}
					if(uniques > rb_uniques) {
						rb_header = rb;
						rb_uniques = uniques;
					}
				}
				var h = ma.h;
				var key_h = h;
				var key_keys = Object.keys(h);
				var key_length = key_keys.length;
				var key_current = 0;
				while(key_current < key_length) {
					var key2 = key_keys[key_current++];
					var i0 = ma.h[key2];
					var i1 = mb.h[key2];
					if(i1 != null) {
						if(i1 >= 0 && i0 >= 0) {
							++ct;
						}
					}
				}
				if(ct > ct_best) {
					ct_best = ct;
					ma_best = ma;
					mb_best = mb;
					ra_best = ra;
					rb_best = rb;
				}
			}
		}
		if(ma_best == null) {
			if(a.get_height() > 0 && b.get_height() == 0) {
				align.headers(0,-1);
			} else if(a.get_height() == 0 && b.get_height() > 0) {
				align.headers(-1,0);
			}
			return;
		}
		var h = ma_best.h;
		var key_h = h;
		var key_keys = Object.keys(h);
		var key_length = key_keys.length;
		var key_current = 0;
		while(key_current < key_length) {
			var key = key_keys[key_current++];
			var i0 = ma_best.h[key];
			var i1 = mb_best.h[key];
			if(i0 != null && i1 != null) {
				align.link(i0,i1);
			} else if(i0 != null) {
				align.link(i0,-1);
			} else if(i1 != null) {
				align.link(-1,i1);
			}
		}
		var h = mb_best.h;
		var key_h = h;
		var key_keys = Object.keys(h);
		var key_length = key_keys.length;
		var key_current = 0;
		while(key_current < key_length) {
			var key = key_keys[key_current++];
			var i0 = ma_best.h[key];
			var i1 = mb_best.h[key];
			if(i0 == null && i1 != null) {
				align.link(-1,i1);
			}
		}
		align.headers(ra_header,rb_header);
	}
	,testHasSameColumns: function() {
		var p = this.comp.p;
		var a = this.comp.a;
		var b = this.comp.b;
		var eq = this.hasSameColumns2(a,b);
		if(eq && p != null) {
			eq = this.hasSameColumns2(p,a);
		}
		this.comp.has_same_columns = eq;
		this.comp.has_same_columns_known = true;
		return true;
	}
	,hasSameColumns2: function(a,b) {
		if(a.get_width() != b.get_width()) {
			return false;
		}
		if(a.get_height() == 0 || b.get_height() == 0) {
			return true;
		}
		var av = a.getCellView();
		var _g = 0;
		var _g1 = a.get_width();
		while(_g < _g1) {
			var i = _g++;
			var _g2 = i + 1;
			var _g3 = a.get_width();
			while(_g2 < _g3) {
				var j = _g2++;
				if(av.equals(a.getCell(i,0),a.getCell(j,0))) {
					return false;
				}
			}
			if(!av.equals(a.getCell(i,0),b.getCell(i,0))) {
				return false;
			}
		}
		return true;
	}
	,testIsEqual: function() {
		var p = this.comp.p;
		var a = this.comp.a;
		var b = this.comp.b;
		this.comp.getMeta();
		var nested = false;
		if(this.comp.p_meta != null) {
			if(this.comp.p_meta.isNested()) {
				nested = true;
			}
		}
		if(this.comp.a_meta != null) {
			if(this.comp.a_meta.isNested()) {
				nested = true;
			}
		}
		if(this.comp.b_meta != null) {
			if(this.comp.b_meta.isNested()) {
				nested = true;
			}
		}
		if(nested) {
			this.comp.is_equal = false;
			this.comp.is_equal_known = true;
			return true;
		}
		var eq = this.isEqual2(a,b);
		if(eq && p != null) {
			eq = this.isEqual2(p,a);
		}
		this.comp.is_equal = eq;
		this.comp.is_equal_known = true;
		return true;
	}
	,isEqual2: function(a,b) {
		if(a.get_width() != b.get_width() || a.get_height() != b.get_height()) {
			return false;
		}
		var av = a.getCellView();
		var _g = 0;
		var _g1 = a.get_height();
		while(_g < _g1) {
			var i = _g++;
			var _g2 = 0;
			var _g3 = a.get_width();
			while(_g2 < _g3) {
				var j = _g2++;
				if(!av.equals(a.getCell(j,i),b.getCell(j,i))) {
					return false;
				}
			}
		}
		return true;
	}
	,compareCore: function() {
		if(this.comp.completed) {
			return false;
		}
		if(!this.comp.is_equal_known) {
			return this.testIsEqual();
		}
		if(!this.comp.has_same_columns_known) {
			return this.testHasSameColumns();
		}
		this.comp.completed = true;
		return false;
	}
	,storeIndexes: function() {
		this.indexes = [];
	}
	,getIndexes: function() {
		return this.indexes;
	}
	,useSql: function() {
		if(this.comp.compare_flags == null) {
			return false;
		}
		this.comp.getMeta();
		var sql = true;
		if(this.comp.p_meta != null) {
			if(!this.comp.p_meta.isSql()) {
				sql = false;
			}
		}
		if(this.comp.a_meta != null) {
			if(!this.comp.a_meta.isSql()) {
				sql = false;
			}
		}
		if(this.comp.b_meta != null) {
			if(!this.comp.b_meta.isSql()) {
				sql = false;
			}
		}
		if(this.comp.p != null && this.comp.p_meta == null) {
			sql = false;
		}
		if(this.comp.a != null && this.comp.a_meta == null) {
			sql = false;
		}
		if(this.comp.b != null && this.comp.b_meta == null) {
			sql = false;
		}
		return sql;
	}
	,__class__: coopy_CompareTable
};
var coopy_ConflictInfo = function(row,col,pvalue,lvalue,rvalue) {
	this.row = row;
	this.col = col;
	this.pvalue = pvalue;
	this.lvalue = lvalue;
	this.rvalue = rvalue;
};
coopy_ConflictInfo.__name__ = true;
coopy_ConflictInfo.prototype = {
	row: null
	,col: null
	,pvalue: null
	,lvalue: null
	,rvalue: null
	,__class__: coopy_ConflictInfo
};
var coopy_Coopy = $hx_exports["coopy"]["Coopy"] = function(io) {
	this.init();
	this.io = io;
};
coopy_Coopy.__name__ = true;
coopy_Coopy.diffAsHtml = function(local,remote,flags) {
	var comp = new coopy_TableComparisonState();
	var td = coopy_Coopy.align(local,remote,flags,comp);
	var o = coopy_Coopy.getBlankTable(td,comp);
	if(comp.a != null) {
		o = comp.a.create();
	}
	if(o == null && comp.b != null) {
		o = comp.b.create();
	}
	if(o == null) {
		o = new coopy_SimpleTable(0,0);
	}
	var os = new coopy_Tables(o);
	td.hiliteWithNesting(os);
	var render = new coopy_DiffRender();
	return render.renderTables(os).html();
};
coopy_Coopy.diffAsAnsi = function(local,remote,flags) {
	var tool = new coopy_Coopy(new coopy_TableIO());
	tool.cache_txt = "";
	if(flags == null) {
		flags = new coopy_CompareFlags();
	}
	tool.output_format = "csv";
	tool.runDiff(flags.parent,local,remote,flags,null);
	return tool.cache_txt;
};
coopy_Coopy.diff = function(local,remote,flags) {
	var comp = new coopy_TableComparisonState();
	var td = coopy_Coopy.align(local,remote,flags,comp);
	var o = coopy_Coopy.getBlankTable(td,comp);
	if(comp.a != null) {
		o = comp.a.create();
	}
	if(o == null && comp.b != null) {
		o = comp.b.create();
	}
	if(o == null) {
		o = new coopy_SimpleTable(0,0);
	}
	td.hilite(o);
	return o;
};
coopy_Coopy.getBlankTable = function(td,comp) {
	var o = null;
	if(comp.a != null) {
		o = comp.a.create();
	}
	if(o == null && comp.b != null) {
		o = comp.b.create();
	}
	if(o == null) {
		o = new coopy_SimpleTable(0,0);
	}
	return o;
};
coopy_Coopy.align = function(local,remote,flags,comp) {
	comp.a = coopy_Coopy.tablify(local);
	comp.b = coopy_Coopy.tablify(remote);
	if(flags == null) {
		flags = new coopy_CompareFlags();
	}
	comp.compare_flags = flags;
	var ct = new coopy_CompareTable(comp);
	var align = ct.align();
	var td = new coopy_TableDiff(align,flags);
	return td;
};
coopy_Coopy.patch = function(local,patch,flags) {
	var patcher = new coopy_HighlightPatch(coopy_Coopy.tablify(local),coopy_Coopy.tablify(patch));
	return patcher.apply();
};
coopy_Coopy.compareTables = function(local,remote,flags) {
	var comp = new coopy_TableComparisonState();
	comp.a = coopy_Coopy.tablify(local);
	comp.b = coopy_Coopy.tablify(remote);
	comp.compare_flags = flags;
	var ct = new coopy_CompareTable(comp);
	return ct;
};
coopy_Coopy.compareTables3 = function(parent,local,remote,flags) {
	var comp = new coopy_TableComparisonState();
	comp.p = coopy_Coopy.tablify(parent);
	comp.a = coopy_Coopy.tablify(local);
	comp.b = coopy_Coopy.tablify(remote);
	comp.compare_flags = flags;
	var ct = new coopy_CompareTable(comp);
	return ct;
};
coopy_Coopy.keepAround = function() {
	var st = new coopy_SimpleTable(1,1);
	var v = new coopy_Viterbi();
	var td = new coopy_TableDiff(null,null);
	var cf = new coopy_CompareFlags();
	var idx = new coopy_Index(cf);
	var dr = new coopy_DiffRender();
	var hp = new coopy_HighlightPatch(null,null);
	var csv = new coopy_Csv();
	var tm = new coopy_TableModifier(null);
	var sc = new coopy_SqlCompare(null,null,null,null,null);
	var sq = new coopy_SqliteHelper();
	var sm = new coopy_SimpleMeta(null);
	var ct = new coopy_CombinedTable(null);
	return 0;
};
coopy_Coopy.cellFor = function(x) {
	return x;
};
coopy_Coopy.main = function() {
};
coopy_Coopy.show = function(t) {
	var w = t.get_width();
	var h = t.get_height();
	var txt = "";
	var _g = 0;
	var _g1 = h;
	while(_g < _g1) {
		var y = _g++;
		var _g2 = 0;
		var _g3 = w;
		while(_g2 < _g3) {
			var x = _g2++;
			txt += Std.string(t.getCell(x,y));
			txt += " ";
		}
		txt += "\n";
	}
	console.log("coopy/Coopy.hx:1191:",txt);
};
coopy_Coopy.jsonify = function(t) {
	var workbook = new haxe_ds_StringMap();
	var sheet = [];
	var w = t.get_width();
	var h = t.get_height();
	var txt = "";
	var _g = 0;
	var _g1 = h;
	while(_g < _g1) {
		var y = _g++;
		var row = [];
		var _g2 = 0;
		var _g3 = w;
		while(_g2 < _g3) {
			var x = _g2++;
			var v = t.getCell(x,y);
			row.push(v);
		}
		sheet.push(row);
	}
	workbook.h["sheet"] = sheet;
	return workbook;
};
coopy_Coopy.tablify = function(data) {
	if(data == null) {
		return data;
	}
	var get_cell_view = Reflect.field(data,"getCellView");
	if(get_cell_view != null) {
		return data;
	}
	return new daff.TableView(data);
};
coopy_Coopy.prototype = {
	format_preference: null
	,delim_preference: null
	,csv_eol_preference: null
	,extern_preference: null
	,output_format: null
	,output_format_set: null
	,nested_output: null
	,order_set: null
	,order_preference: null
	,io: null
	,strategy: null
	,css_output: null
	,fragment: null
	,flags: null
	,cache_txt: null
	,fail_if_diff: null
	,diffs_found: null
	,mv: null
	,init: function() {
		this.extern_preference = false;
		this.format_preference = null;
		this.delim_preference = null;
		this.csv_eol_preference = null;
		this.output_format = "copy";
		this.output_format_set = false;
		this.nested_output = false;
		this.order_set = false;
		this.order_preference = false;
		this.strategy = null;
		this.css_output = null;
		this.fragment = false;
		this.flags = null;
		this.cache_txt = null;
		this.fail_if_diff = false;
		this.diffs_found = false;
	}
	,checkFormat: function(name) {
		if(this.extern_preference) {
			return this.format_preference;
		}
		var ext = "";
		if(name != null) {
			var pt = name.lastIndexOf(".");
			if(pt >= 0) {
				ext = HxOverrides.substr(name,pt + 1,null).toLowerCase();
				switch(ext) {
				case "csv":
					this.format_preference = "csv";
					this.delim_preference = ",";
					break;
				case "htm":case "html":
					this.format_preference = "html";
					break;
				case "json":
					this.format_preference = "json";
					break;
				case "ndjson":
					this.format_preference = "ndjson";
					break;
				case "psv":
					this.format_preference = "csv";
					this.delim_preference = String.fromCharCode(0xD83D, 0xDCA9);
					break;
				case "sqlite":
					this.format_preference = "sqlite";
					break;
				case "sqlite3":
					this.format_preference = "sqlite";
					break;
				case "ssv":
					this.format_preference = "csv";
					this.delim_preference = ";";
					this.format_preference = "csv";
					break;
				case "tsv":
					this.format_preference = "csv";
					this.delim_preference = "\t";
					break;
				case "www":
					this.format_preference = "www";
					break;
				default:
					ext = "";
				}
			}
		}
		this.nested_output = this.format_preference == "json" || this.format_preference == "ndjson";
		this.order_preference = !this.nested_output;
		return ext;
	}
	,setFormat: function(name) {
		this.extern_preference = false;
		this.checkFormat("." + name);
		this.extern_preference = true;
	}
	,getRenderer: function() {
		var renderer = new coopy_DiffRender();
		renderer.usePrettyArrows(this.flags.use_glyphs);
		renderer.quoteHtml(this.flags.quote_html);
		return renderer;
	}
	,applyRenderer: function(name,renderer) {
		if(!this.fragment) {
			renderer.completeHtml();
		}
		if(this.format_preference == "www") {
			this.io.sendToBrowser(renderer.html());
		} else {
			this.saveText(name,renderer.html());
		}
		if(this.css_output != null) {
			this.saveText(this.css_output,renderer.sampleCss());
		}
		return true;
	}
	,renderTable: function(name,t) {
		var renderer = this.getRenderer();
		renderer.render(t);
		return this.applyRenderer(name,renderer);
	}
	,renderTables: function(name,t) {
		var renderer = this.getRenderer();
		renderer.renderTables(t);
		return this.applyRenderer(name,renderer);
	}
	,saveTable: function(name,t,render) {
		var txt = this.encodeTable(name,t,render);
		if(txt == null) {
			return true;
		}
		return this.saveText(name,txt);
	}
	,encodeTable: function(name,t,render) {
		if(this.output_format != "copy") {
			this.setFormat(this.output_format);
		}
		var txt = "";
		this.checkFormat(name);
		if(this.format_preference == "sqlite" && !this.extern_preference) {
			this.format_preference = "csv";
		}
		if(render == null) {
			if(this.format_preference == "csv") {
				var csv = new coopy_Csv(this.delim_preference,this.csv_eol_preference);
				txt = csv.renderTable(t);
			} else if(this.format_preference == "ndjson") {
				txt = new coopy_Ndjson(t).render();
			} else if(this.format_preference == "html" || this.format_preference == "www") {
				this.renderTable(name,t);
				return null;
			} else if(this.format_preference == "sqlite") {
				this.io.writeStderr("! Cannot yet output to sqlite, aborting\n");
				return "";
			} else {
				txt = haxe_format_JsonPrinter.print(coopy_Coopy.jsonify(t),null,"  ");
			}
		} else {
			txt = render.render(t);
		}
		return txt;
	}
	,saveTables: function(name,os,use_color,is_diff) {
		if(this.output_format != "copy") {
			this.setFormat(this.output_format);
		}
		var txt = "";
		this.checkFormat(name);
		var render = null;
		if(use_color) {
			render = new coopy_TerminalDiffRender(this.flags,this.delim_preference,is_diff);
		}
		var order = os.getOrder();
		if(order.length == 1) {
			return this.saveTable(name,os.one(),render);
		}
		if(this.format_preference == "html" || this.format_preference == "www") {
			return this.renderTables(name,os);
		}
		var need_blank = false;
		if(order.length == 0 || os.hasInsDel()) {
			txt += this.encodeTable(name,os.one(),render);
			need_blank = true;
		}
		if(order.length > 1) {
			var _g = 1;
			var _g1 = order.length;
			while(_g < _g1) {
				var i = _g++;
				var t = os.get(order[i]);
				if(t != null) {
					if(need_blank) {
						txt += "\n";
					}
					need_blank = true;
					txt += order[i] + "\n";
					var line = "";
					var _g2 = 0;
					var _g3 = order[i].length;
					while(_g2 < _g3) {
						var i1 = _g2++;
						line += "=";
					}
					txt += line + "\n";
					txt += this.encodeTable(name,os.get(order[i]),render);
				}
			}
		}
		return this.saveText(name,txt);
	}
	,saveText: function(name,txt) {
		if(name == null) {
			this.cache_txt += txt;
		} else if(name != "-") {
			this.io.saveContent(name,txt);
		} else {
			this.io.writeStdout(txt);
		}
		return true;
	}
	,jsonToTables: function(json) {
		var tables = Reflect.field(json,"tables");
		if(tables == null) {
			return this.jsonToTable(json);
		}
		return new coopy_JsonTables(json,this.flags);
	}
	,jsonToTable: function(json) {
		var output = null;
		var _g = 0;
		var _g1 = Reflect.fields(json);
		while(_g < _g1.length) {
			var name = _g1[_g];
			++_g;
			var t = Reflect.field(json,name);
			var columns = Reflect.field(t,"columns");
			if(columns == null) {
				continue;
			}
			var rows = Reflect.field(t,"rows");
			if(rows == null) {
				continue;
			}
			output = new coopy_SimpleTable(columns.length,rows.length);
			var has_hash = false;
			var has_hash_known = false;
			var _g2 = 0;
			var _g3 = rows.length;
			while(_g2 < _g3) {
				var i = _g2++;
				var row = rows[i];
				if(!has_hash_known) {
					if(Reflect.fields(row).length == columns.length) {
						has_hash = true;
					}
					has_hash_known = true;
				}
				if(!has_hash) {
					var lst = row;
					var _g4 = 0;
					var _g5 = columns.length;
					while(_g4 < _g5) {
						var j = _g4++;
						var val = lst[j];
						output.setCell(j,i,coopy_Coopy.cellFor(val));
					}
				} else {
					var _g6 = 0;
					var _g7 = columns.length;
					while(_g6 < _g7) {
						var j1 = _g6++;
						var val1 = Reflect.field(row,columns[j1]);
						output.setCell(j1,i,coopy_Coopy.cellFor(val1));
					}
				}
			}
		}
		if(output != null) {
			output.trimBlank();
		}
		return output;
	}
	,useColor: function(flags,output) {
		var use_color = flags.terminal_format == "ansi";
		if(flags.terminal_format == null) {
			if((output == null || output == "-") && (this.output_format == "copy" || this.output_format == "csv" || this.output_format == "psv")) {
				if(this.io != null) {
					if(this.io.isTtyKnown()) {
						use_color = this.io.isTty();
					}
				}
			}
		}
		return use_color;
	}
	,runDiff: function(parent,a,b,flags,output) {
		var ct = coopy_Coopy.compareTables3(parent,a,b,flags);
		var align = ct.align();
		var td = new coopy_TableDiff(align,flags);
		var o = new coopy_SimpleTable(0,0);
		var os = new coopy_Tables(o);
		td.hiliteWithNesting(os);
		var use_color = this.useColor(flags,output);
		this.saveTables(output,os,use_color,true);
		if(this.fail_if_diff) {
			var summary = td.getSummary();
			if(summary.different) {
				this.diffs_found = true;
			}
		}
	}
	,loadTable: function(name,role) {
		var ext = this.checkFormat(name);
		if(ext == "sqlite") {
			var sql = this.io.openSqliteDatabase(name);
			if(sql == null) {
				this.io.writeStderr("! Cannot open database, aborting\n");
				return null;
			}
			var tab = new coopy_SqlTables(sql,this.flags,role);
			return tab;
		}
		var txt = this.io.getContent(name);
		if(ext == "ndjson") {
			var t = new coopy_SimpleTable(0,0);
			var ndjson = new coopy_Ndjson(t);
			ndjson.parse(txt);
			return t;
		}
		if(ext == "json" || ext == "") {
			try {
				var json = new haxe_format_JsonParser(txt).doParse();
				this.format_preference = "json";
				var t = this.jsonToTables(json);
				if(t == null) {
					throw haxe_Exception.thrown("JSON failed");
				}
				return t;
			} catch( _g ) {
				var e = haxe_Exception.caught(_g).unwrap();
				if(ext == "json") {
					throw haxe_Exception.thrown(e);
				}
			}
		}
		this.format_preference = "csv";
		var csv = new coopy_Csv(this.delim_preference);
		var output = new coopy_SimpleTable(0,0);
		csv.parseTable(txt,output);
		if(this.csv_eol_preference == null) {
			this.csv_eol_preference = csv.getDiscoveredEol();
		}
		if(output != null) {
			output.trimBlank();
		}
		return output;
	}
	,status: null
	,daff_cmd: null
	,command: function(io,cmd,args) {
		var r = 0;
		if(io.hasAsync()) {
			r = io.command(cmd,args);
		}
		if(r != 999) {
			io.writeStdout("$ " + cmd);
			var _g = 0;
			while(_g < args.length) {
				var arg = args[_g];
				++_g;
				io.writeStdout(" ");
				var spaced = arg.indexOf(" ") >= 0;
				if(spaced) {
					io.writeStdout("\"");
				}
				io.writeStdout(arg);
				if(spaced) {
					io.writeStdout("\"");
				}
			}
			io.writeStdout("\n");
		}
		if(!io.hasAsync()) {
			r = io.command(cmd,args);
		}
		return r;
	}
	,installGitDriver: function(io,formats) {
		var r = 0;
		if(this.status == null) {
			this.status = new haxe_ds_StringMap();
			this.daff_cmd = "";
		}
		var key = "hello";
		if(!Object.prototype.hasOwnProperty.call(this.status.h,key)) {
			io.writeStdout("Setting up git to use daff on");
			var _g = 0;
			while(_g < formats.length) {
				var format = formats[_g];
				++_g;
				io.writeStdout(" *." + format);
			}
			io.writeStdout(" files\n");
			this.status.h[key] = r;
		}
		key = "can_run_git";
		if(!Object.prototype.hasOwnProperty.call(this.status.h,key)) {
			r = this.command(io,"git",["--version"]);
			if(r == 999) {
				return r;
			}
			this.status.h[key] = r;
			if(r != 0) {
				io.writeStderr("! Cannot run git, aborting\n");
				return 1;
			}
			io.writeStdout("- Can run git\n");
		}
		var daffs = ["daff","daff.rb","daff.py"];
		if(this.daff_cmd == "") {
			var _g = 0;
			while(_g < daffs.length) {
				var daff = daffs[_g];
				++_g;
				var key1 = "can_run_" + daff;
				if(!Object.prototype.hasOwnProperty.call(this.status.h,key1)) {
					r = this.command(io,daff,["version"]);
					if(r == 999) {
						return r;
					}
					this.status.h[key1] = r;
					if(r == 0) {
						this.daff_cmd = daff;
						io.writeStdout("- Can run " + daff + " as \"" + daff + "\"\n");
						break;
					}
				}
			}
			if(this.daff_cmd == "") {
				io.writeStderr("! Cannot find daff, is it in your path?\n");
				return 1;
			}
		}
		var _g = 0;
		while(_g < formats.length) {
			var format = formats[_g];
			++_g;
			key = "have_diff_driver_" + format;
			if(!Object.prototype.hasOwnProperty.call(this.status.h,key)) {
				r = this.command(io,"git",["config","--global","--get","diff.daff-" + format + ".command"]);
				if(r == 999) {
					return r;
				}
				this.status.h[key] = r;
			}
			var have_diff_driver = this.status.h[key] == 0;
			key = "add_diff_driver_" + format;
			if(!Object.prototype.hasOwnProperty.call(this.status.h,key)) {
				r = this.command(io,"git",["config","--global","diff.daff-" + format + ".command",this.daff_cmd + " diff --git"]);
				if(r == 999) {
					return r;
				}
				if(have_diff_driver) {
					io.writeStdout("- Cleared existing daff diff driver for " + format + "\n");
				}
				io.writeStdout("- Added diff driver for " + format + "\n");
				this.status.h[key] = r;
			}
			key = "have_merge_driver_" + format;
			if(!Object.prototype.hasOwnProperty.call(this.status.h,key)) {
				r = this.command(io,"git",["config","--global","--get","merge.daff-" + format + ".driver"]);
				if(r == 999) {
					return r;
				}
				this.status.h[key] = r;
			}
			var have_merge_driver = this.status.h[key] == 0;
			key = "name_merge_driver_" + format;
			if(!Object.prototype.hasOwnProperty.call(this.status.h,key)) {
				if(!have_merge_driver) {
					r = this.command(io,"git",["config","--global","merge.daff-" + format + ".name","daff tabular " + format + " merge"]);
					if(r == 999) {
						return r;
					}
				} else {
					r = 0;
				}
				this.status.h[key] = r;
			}
			key = "add_merge_driver_" + format;
			if(!Object.prototype.hasOwnProperty.call(this.status.h,key)) {
				r = this.command(io,"git",["config","--global","merge.daff-" + format + ".driver",this.daff_cmd + " merge --output %A %O %A %B"]);
				if(r == 999) {
					return r;
				}
				if(have_merge_driver) {
					io.writeStdout("- Cleared existing daff merge driver for " + format + "\n");
				}
				io.writeStdout("- Added merge driver for " + format + "\n");
				this.status.h[key] = r;
			}
		}
		if(!io.exists(".git/config")) {
			io.writeStderr("! This next part needs to happen in a git repository.\n");
			io.writeStderr("! Please run again from the root of a git repository.\n");
			return 1;
		}
		var attr = ".gitattributes";
		var txt = "";
		var post = "";
		if(!io.exists(attr)) {
			io.writeStdout("- No .gitattributes file\n");
		} else {
			io.writeStdout("- You have a .gitattributes file\n");
			txt = io.getContent(attr);
		}
		var need_update = false;
		var _g = 0;
		while(_g < formats.length) {
			var format = formats[_g];
			++_g;
			if(txt.indexOf("*." + format) >= 0) {
				io.writeStderr("- Your .gitattributes file already mentions *." + format + "\n");
			} else {
				post += "*." + format + " diff=daff-" + format + "\n";
				post += "*." + format + " merge=daff-" + format + "\n";
				io.writeStdout("- Placing the following lines in .gitattributes:\n");
				io.writeStdout(post);
				if(txt != "" && !need_update) {
					txt += "\n";
				}
				txt += post;
				need_update = true;
			}
		}
		if(need_update) {
			io.saveContent(attr,txt);
		}
		io.writeStdout("- Done!\n");
		return 0;
	}
	,run: function(args,io) {
		if(io == null) {
			console.log("coopy/Coopy.hx:725:","No system interface available");
			return 1;
		}
		this.init();
		this.io = io;
		var more = true;
		var output = null;
		var inplace = false;
		var git = false;
		var help = false;
		this.flags = new coopy_CompareFlags();
		this.flags.always_show_header = true;
		while(more) {
			more = false;
			var _g = 0;
			var _g1 = args.length;
			while(_g < _g1) {
				var i = _g++;
				var tag = args[i];
				if(tag == "--output") {
					more = true;
					output = args[i + 1];
					args.splice(i,2);
					break;
				} else if(tag == "--css") {
					more = true;
					this.fragment = true;
					this.css_output = args[i + 1];
					args.splice(i,2);
					break;
				} else if(tag == "--fragment") {
					more = true;
					this.fragment = true;
					args.splice(i,1);
					break;
				} else if(tag == "--plain") {
					more = true;
					this.flags.use_glyphs = false;
					args.splice(i,1);
					break;
				} else if(tag == "--unquote") {
					more = true;
					this.flags.quote_html = false;
					args.splice(i,1);
					break;
				} else if(tag == "--all") {
					more = true;
					this.flags.show_unchanged = true;
					this.flags.show_unchanged_columns = true;
					args.splice(i,1);
					break;
				} else if(tag == "--all-rows") {
					more = true;
					this.flags.show_unchanged = true;
					args.splice(i,1);
					break;
				} else if(tag == "--all-columns") {
					more = true;
					this.flags.show_unchanged_columns = true;
					args.splice(i,1);
					break;
				} else if(tag == "--act") {
					more = true;
					if(this.flags.acts == null) {
						this.flags.acts = new haxe_ds_StringMap();
					}
					this.flags.acts.h[args[i + 1]] = true;
					args.splice(i,2);
					break;
				} else if(tag == "--context") {
					more = true;
					var context = Std.parseInt(args[i + 1]);
					if(context >= 0) {
						this.flags.unchanged_context = context;
					}
					args.splice(i,2);
					break;
				} else if(tag == "--context-columns") {
					more = true;
					var context1 = Std.parseInt(args[i + 1]);
					if(context1 >= 0) {
						this.flags.unchanged_column_context = context1;
					}
					args.splice(i,2);
					break;
				} else if(tag == "--inplace") {
					more = true;
					inplace = true;
					args.splice(i,1);
					break;
				} else if(tag == "--git") {
					more = true;
					git = true;
					args.splice(i,1);
					break;
				} else if(tag == "--unordered") {
					more = true;
					this.flags.ordered = false;
					this.flags.unchanged_context = 0;
					this.order_set = true;
					args.splice(i,1);
					break;
				} else if(tag == "--ordered") {
					more = true;
					this.flags.ordered = true;
					this.order_set = true;
					args.splice(i,1);
					break;
				} else if(tag == "--color") {
					more = true;
					this.flags.terminal_format = "ansi";
					args.splice(i,1);
					break;
				} else if(tag == "--no-color") {
					more = true;
					this.flags.terminal_format = "plain";
					args.splice(i,1);
					break;
				} else if(tag == "--input-format") {
					more = true;
					this.setFormat(args[i + 1]);
					args.splice(i,2);
					break;
				} else if(tag == "--output-format") {
					more = true;
					this.output_format = args[i + 1];
					this.output_format_set = true;
					args.splice(i,2);
					break;
				} else if(tag == "--id") {
					more = true;
					if(this.flags.ids == null) {
						this.flags.ids = [];
					}
					this.flags.ids.push(args[i + 1]);
					args.splice(i,2);
					break;
				} else if(tag == "--ignore") {
					more = true;
					this.flags.ignoreColumn(args[i + 1]);
					args.splice(i,2);
					break;
				} else if(tag == "--index") {
					more = true;
					this.flags.always_show_order = true;
					this.flags.never_show_order = false;
					args.splice(i,1);
					break;
				} else if(tag == "--www") {
					more = true;
					this.output_format = "www";
					this.output_format_set = true;
					args.splice(i,1);
				} else if(tag == "--table") {
					more = true;
					this.flags.addTable(args[i + 1]);
					args.splice(i,2);
					break;
				} else if(tag == "-w" || tag == "--ignore-whitespace") {
					more = true;
					this.flags.ignore_whitespace = true;
					args.splice(i,1);
					break;
				} else if(tag == "-i" || tag == "--ignore-case") {
					more = true;
					this.flags.ignore_case = true;
					args.splice(i,1);
					break;
				} else if(tag == "-d" || tag == "--ignore-epsilon") {
					more = true;
					var eps = args[i + 1];
					this.flags.ignore_epsilon = parseFloat(eps);
					var f = this.flags.ignore_epsilon;
					if(isNaN(f)) {
						io.writeStderr("Epsilon for numeric comparison must be numeric\n");
						return 1;
					}
					args.splice(i,2);
					break;
				} else if(tag == "--padding") {
					more = true;
					this.flags.padding_strategy = args[i + 1];
					args.splice(i,2);
					break;
				} else if(tag == "-e" || tag == "--eol") {
					more = true;
					var ending = args[i + 1];
					if(ending == "crlf") {
						ending = "\r\n";
					} else if(ending == "lf") {
						ending = "\n";
					} else if(ending == "cr") {
						ending = "\r";
					} else if(ending == "auto") {
						ending = null;
					} else {
						io.writeStderr("Expected line ending of either 'crlf' or 'lf' but got " + ending + "\n");
						return 1;
					}
					this.csv_eol_preference = ending;
					args.splice(i,2);
					break;
				} else if(tag == "--fail-if-diff") {
					more = true;
					this.fail_if_diff = true;
					args.splice(i,1);
					break;
				} else if(tag == "help" || tag == "-h" || tag == "--help") {
					more = true;
					args.splice(i,1);
					help = true;
					break;
				}
			}
		}
		var cmd = args[0];
		var ok = true;
		if(help) {
			cmd = "";
			args = [];
		}
		try {
			if(args.length < 2) {
				if(cmd == "version") {
					io.writeStdout(coopy_Coopy.VERSION + "\n");
					return 0;
				}
				if(cmd == "git") {
					io.writeStdout("You can use daff to improve git's handling of csv files, by using it as a\ndiff driver (for showing what has changed) and as a merge driver (for merging\nchanges between multiple versions).\n");
					io.writeStdout("\n");
					io.writeStdout("Automatic setup\n");
					io.writeStdout("---------------\n\n");
					io.writeStdout("Run:\n");
					io.writeStdout("  daff git csv\n");
					io.writeStdout("\n");
					io.writeStdout("Manual setup\n");
					io.writeStdout("------------\n\n");
					io.writeStdout("Create and add a file called .gitattributes in the root directory of your\nrepository, containing:\n\n");
					io.writeStdout("  *.csv diff=daff-csv\n");
					io.writeStdout("  *.csv merge=daff-csv\n");
					io.writeStdout("\nCreate a file called .gitconfig in your home directory (or alternatively\nopen .git/config for a particular repository) and add:\n\n");
					io.writeStdout("  [diff \"daff-csv\"]\n");
					io.writeStdout("  command = daff diff --git\n");
					io.writeStderr("\n");
					io.writeStdout("  [merge \"daff-csv\"]\n");
					io.writeStdout("  name = daff tabular merge\n");
					io.writeStdout("  driver = daff merge --output %A %O %A %B\n\n");
					io.writeStderr("Make sure you can run daff from the command-line as just \"daff\" - if not,\nreplace \"daff\" in the driver and command lines above with the correct way\nto call it. Add --no-color if your terminal does not support ANSI colors.");
					io.writeStderr("\n");
					return 0;
				}
				if(args.length < 1) {
					io.writeStderr("daff can produce and apply tabular diffs.\n");
					io.writeStderr("Call as:\n");
					io.writeStderr("  daff a.csv b.csv\n");
					io.writeStderr("  daff [--color] [--no-color] [--output OUTPUT.csv] a.csv b.csv\n");
					io.writeStderr("  daff [--output OUTPUT.html] a.csv b.csv\n");
					io.writeStderr("  daff [--www] a.csv b.csv\n");
					io.writeStderr("  daff parent.csv a.csv b.csv\n");
					io.writeStderr("  daff --input-format sqlite a.db b.db\n");
					io.writeStderr("  daff patch [--inplace] a.csv patch.csv\n");
					io.writeStderr("  daff merge [--inplace] parent.csv a.csv b.csv\n");
					io.writeStderr("  daff trim [--output OUTPUT.csv] source.csv\n");
					io.writeStderr("  daff render [--output OUTPUT.html] diff.csv\n");
					io.writeStderr("  daff copy in.csv out.tsv\n");
					io.writeStderr("  daff in.csv\n");
					io.writeStderr("  daff git\n");
					io.writeStderr("  daff version\n");
					io.writeStderr("\n");
					io.writeStderr("The --inplace option to patch and merge will result in modification of a.csv.\n");
					io.writeStderr("\n");
					io.writeStderr("If you need more control, here is the full list of flags:\n");
					io.writeStderr("  daff diff [--output OUTPUT.csv] [--context NUM] [--all] [--act ACT] a.csv b.csv\n");
					io.writeStderr("     --act ACT:     show only a certain kind of change (update, insert, delete, column)\n");
					io.writeStderr("     --all:         do not prune unchanged rows or columns\n");
					io.writeStderr("     --all-rows:    do not prune unchanged rows\n");
					io.writeStderr("     --all-columns: do not prune unchanged columns\n");
					io.writeStderr("     --color:       highlight changes with terminal colors (default in terminals)\n");
					io.writeStderr("     --context NUM: show NUM rows of context (0=none)\n");
					io.writeStderr("     --context-columns NUM: show NUM columns of context (0=none)\n");
					io.writeStderr("     --fail-if-diff: return status is 0 if equal, 1 if different, 2 if problem\n");
					io.writeStderr("     --id:          specify column name to use as primary key (repeat for multi-column key)\n");
					io.writeStderr("     --ignore:      specify column name to ignore completely (can repeat)\n");
					io.writeStderr("     --index:       include row/columns numbers from original tables\n");
					io.writeStderr("     --input-format [csv|tsv|ssv|psv|json|sqlite]: set format to expect for input\n");
					io.writeStderr("     --eol [crlf|lf|cr|auto]: separator between rows of csv output.\n");
					io.writeStderr("     --no-color:    make sure terminal colors are not used\n");
					io.writeStderr("     --ordered:     assume row order is meaningful (default for CSV)\n");
					io.writeStderr("     --output-format [csv|tsv|ssv|psv|json|copy|html]: set format for output\n");
					io.writeStderr("     --padding [dense|sparse|smart]: set padding method for aligning columns\n");
					io.writeStderr("     --table NAME:  compare the named table, used with SQL sources. If name changes, use 'n1:n2'\n");
					io.writeStderr("     --unordered:   assume row order is meaningless (default for json formats)\n");
					io.writeStderr("     -w / --ignore-whitespace: ignore changes in leading/trailing whitespace\n");
					io.writeStderr("     -i / --ignore-case: ignore differences in case\n");
					io.writeStderr("     -d EPS / --ignore-epsilon EPS: ignore small floating point differences\n");
					io.writeStderr("\n");
					io.writeStderr("  daff render [--output OUTPUT.html] [--css CSS.css] [--fragment] [--plain] diff.csv\n");
					io.writeStderr("     --css CSS.css: generate a suitable css file to go with the html\n");
					io.writeStderr("     --fragment:    generate just a html fragment rather than a page\n");
					io.writeStderr("     --plain:       do not use fancy utf8 characters to make arrows prettier\n");
					io.writeStderr("     --unquote:     do not quote html characters in html diffs\n");
					io.writeStderr("     --www:         send output to a browser\n");
					return 1;
				}
			}
			var cmd = args[0];
			var offset = 1;
			if(!Lambda.has(["diff","patch","merge","trim","render","git","version","copy"],cmd)) {
				if(cmd.indexOf("--") == 0) {
					cmd = "diff";
					offset = 0;
				} else if(cmd.indexOf(".") != -1) {
					if(args.length == 2) {
						cmd = "diff";
						offset = 0;
					} else if(args.length == 1) {
						cmd = "copy";
						offset = 0;
					}
				}
			}
			if(cmd == "git") {
				var types = args.splice(offset,args.length - offset);
				return this.installGitDriver(io,types);
			}
			if(git) {
				var ct = args.length - offset;
				if(ct != 7 && ct != 9) {
					io.writeStderr("Expected 7 or 9 parameters from git, but got " + ct + "\n");
					return 1;
				}
				var git_args = args.splice(offset,ct);
				args.splice(0,args.length);
				offset = 0;
				var old_display_path = git_args[0];
				var new_display_path = git_args[0];
				var old_file = git_args[1];
				var new_file = git_args[4];
				if(ct == 9) {
					io.writeStdout(git_args[8]);
					new_display_path = git_args[7];
				}
				io.writeStdout("--- a/" + old_display_path + "\n");
				io.writeStdout("+++ b/" + new_display_path + "\n");
				args.push(old_file);
				args.push(new_file);
			}
			var parent = null;
			if(args.length - offset >= 3) {
				parent = this.loadTable(args[offset],"parent");
				++offset;
			}
			var aname = args[offset];
			var a = this.loadTable(aname,"local");
			var b = null;
			if(args.length - offset >= 2) {
				if(cmd != "copy") {
					b = this.loadTable(args[1 + offset],"remote");
				} else {
					output = args[1 + offset];
				}
			}
			this.flags.diff_strategy = this.strategy;
			if(inplace) {
				if(output != null) {
					io.writeStderr("Please do not use --inplace when specifying an output.\n");
				}
				output = aname;
				return 1;
			}
			if(output == null) {
				output = "-";
			}
			if(cmd == "diff") {
				if(!this.order_set) {
					this.flags.ordered = this.order_preference;
					if(!this.flags.ordered) {
						this.flags.unchanged_context = 0;
					}
				}
				this.flags.allow_nested_cells = this.nested_output;
				if(this.fail_if_diff) {
					try {
						this.runDiff(parent,a,b,this.flags,output);
					} catch( _g ) {
						return 2;
					}
					if(this.diffs_found) {
						return 1;
					}
				} else {
					this.runDiff(parent,a,b,this.flags,output);
				}
			} else if(cmd == "patch") {
				var patcher = new coopy_HighlightPatch(a,b);
				patcher.apply();
				this.saveTable(output,a);
			} else if(cmd == "merge") {
				var merger = new coopy_Merger(parent,a,b,this.flags);
				var conflicts = merger.apply();
				ok = conflicts == 0;
				if(conflicts > 0) {
					io.writeStderr(conflicts + " conflict" + (conflicts > 1 ? "s" : "") + "\n");
				}
				this.saveTable(output,a);
			} else if(cmd == "trim") {
				this.saveTable(output,a);
			} else if(cmd == "render") {
				this.renderTable(output,a);
			} else if(cmd == "copy") {
				var os = new coopy_Tables(a);
				os.add("untitled");
				this.saveTables(output,os,this.useColor(this.flags,output),false);
			}
		} catch( _g ) {
			var e = haxe_Exception.caught(_g).unwrap();
			if(!this.fail_if_diff) {
				throw haxe_Exception.thrown(e);
			}
			return 2;
		}
		if(ok) {
			return 0;
		} else if(this.fail_if_diff) {
			return 2;
		} else {
			return 1;
		}
	}
	,coopyhx: function(io) {
		var args = io.args();
		if(args[0] == "--keep") {
			return coopy_Coopy.keepAround();
		}
		return this.run(args,io);
	}
	,__class__: coopy_Coopy
};
var coopy_CrossMatch = function() {
};
coopy_CrossMatch.__name__ = true;
coopy_CrossMatch.prototype = {
	spot_a: null
	,spot_b: null
	,item_a: null
	,item_b: null
	,__class__: coopy_CrossMatch
};
var coopy_Csv = $hx_exports["coopy"]["Csv"] = function(delim,eol) {
	if(delim == null) {
		delim = ",";
	}
	this.cursor = 0;
	this.row_ended = false;
	this.delim = delim == null ? "," : delim;
	this.discovered_eol = null;
	this.preferred_eol = eol;
};
coopy_Csv.__name__ = true;
coopy_Csv.prototype = {
	cursor: null
	,row_ended: null
	,has_structure: null
	,delim: null
	,discovered_eol: null
	,preferred_eol: null
	,renderTable: function(t) {
		var eol = this.preferred_eol;
		if(eol == null) {
			eol = "\r\n";
		}
		var result = "";
		var v = t.getCellView();
		var stream = new coopy_TableStream(t);
		var w = stream.width();
		var txts = [];
		while(stream.fetch()) {
			var _g = 0;
			var _g1 = w;
			while(_g < _g1) {
				var x = _g++;
				if(x > 0) {
					txts.push(this.delim);
				}
				txts.push(this.renderCell(v,stream.getCell(x)));
			}
			txts.push(eol);
		}
		return txts.join("");
	}
	,renderCell: function(v,d,force_quote) {
		if(force_quote == null) {
			force_quote = false;
		}
		if(d == null) {
			return "NULL";
		}
		var str = v.toString(d);
		var need_quote = force_quote;
		if(!need_quote) {
			if(str.length > 0) {
				if(str.charAt(0) == " " || str.charAt(str.length - 1) == " ") {
					need_quote = true;
				}
			}
		}
		if(!need_quote) {
			var _g = 0;
			var _g1 = str.length;
			while(_g < _g1) {
				var i = _g++;
				var ch = str.charAt(i);
				if(ch == "\"" || ch == "\r" || ch == "\n" || ch == "\t") {
					need_quote = true;
					break;
				}
				if(ch == this.delim.charAt(0)) {
					if(this.delim.length == 1) {
						need_quote = true;
						break;
					}
					if(i + this.delim.length <= str.length) {
						var match = true;
						var _g2 = 1;
						var _g3 = this.delim.length;
						while(_g2 < _g3) {
							var j = _g2++;
							if(str.charAt(i + j) != this.delim.charAt(j)) {
								match = false;
								break;
							}
						}
						if(match) {
							need_quote = true;
							break;
						}
					}
				}
			}
		}
		var result = "";
		if(need_quote) {
			result += "\"";
		}
		var line_buf = "";
		var _g = 0;
		var _g1 = str.length;
		while(_g < _g1) {
			var i = _g++;
			var ch = str.charAt(i);
			if(ch == "\"") {
				result += "\"";
			}
			if(ch != "\r" && ch != "\n") {
				if(line_buf.length > 0) {
					result += line_buf;
					line_buf = "";
				}
				result += ch;
			} else {
				line_buf += ch;
			}
		}
		if(line_buf.length > 0) {
			result += line_buf;
		}
		if(need_quote) {
			result += "\"";
		}
		return result;
	}
	,parseTable: function(txt,tab) {
		if(!tab.isResizable()) {
			return false;
		}
		this.cursor = 0;
		this.row_ended = false;
		this.has_structure = true;
		tab.resize(0,0);
		var w = 0;
		var h = 0;
		var at = 0;
		var yat = 0;
		while(this.cursor < txt.length) {
			var cell = this.parseCellPart(txt);
			if(yat >= h) {
				h = yat + 1;
				tab.resize(w,h);
			}
			if(at >= w) {
				if(yat > 0) {
					if(cell != "" && cell != null) {
						var context = "";
						var _g = 0;
						var _g1 = w;
						while(_g < _g1) {
							var i = _g++;
							if(i > 0) {
								context += ",";
							}
							context += Std.string(tab.getCell(i,yat));
						}
						console.log("coopy/Csv.hx:179:","Ignored overflowing row " + yat + " with cell '" + cell + "' after: " + context);
					}
				} else {
					w = at + 1;
					tab.resize(w,h);
				}
			}
			tab.setCell(at,h - 1,cell);
			++at;
			if(this.row_ended) {
				at = 0;
				++yat;
			}
			this.cursor++;
		}
		return true;
	}
	,makeTable: function(txt) {
		var tab = new coopy_SimpleTable(0,0);
		this.parseTable(txt,tab);
		return tab;
	}
	,parseCellPart: function(txt) {
		if(txt == null) {
			return null;
		}
		this.row_ended = false;
		var first_non_underscore = txt.length;
		var last_processed = 0;
		var quoting = false;
		var quote = 0;
		var result = "";
		var start = this.cursor;
		var _g = this.cursor;
		var _g1 = txt.length;
		while(_g < _g1) {
			var i = _g++;
			var ch = HxOverrides.cca(txt,i);
			last_processed = i;
			if(ch != 95 && i < first_non_underscore) {
				first_non_underscore = i;
			}
			if(this.has_structure) {
				if(!quoting) {
					if(ch == HxOverrides.cca(this.delim,0)) {
						if(this.delim.length == 1) {
							break;
						}
						if(i + this.delim.length <= txt.length) {
							var match = true;
							var _g2 = 1;
							var _g3 = this.delim.length;
							while(_g2 < _g3) {
								var j = _g2++;
								if(txt.charAt(i + j) != this.delim.charAt(j)) {
									match = false;
									break;
								}
							}
							if(match) {
								last_processed += this.delim.length - 1;
								break;
							}
						}
					}
					if(ch == 13 || ch == 10) {
						var ch2 = HxOverrides.cca(txt,i + 1);
						if(ch2 != null) {
							if(ch2 != ch) {
								if(ch2 == 13 || ch2 == 10) {
									if(this.discovered_eol == null) {
										this.discovered_eol = String.fromCodePoint(ch) + String.fromCodePoint(ch2);
									}
									++last_processed;
								}
							}
						}
						if(this.discovered_eol == null) {
							this.discovered_eol = String.fromCodePoint(ch);
						}
						this.row_ended = true;
						break;
					}
					if(ch == 34) {
						if(i == this.cursor) {
							quoting = true;
							quote = ch;
							if(i != start) {
								result += String.fromCodePoint(ch);
							}
							continue;
						} else if(ch == quote) {
							quoting = true;
						}
					}
					result += String.fromCodePoint(ch);
					continue;
				}
				if(ch == quote) {
					quoting = false;
					continue;
				}
			}
			result += String.fromCodePoint(ch);
		}
		this.cursor = last_processed;
		if(quote == 0) {
			if(result == "NULL") {
				return null;
			}
			if(first_non_underscore > start) {
				var del = first_non_underscore - start;
				if(HxOverrides.substr(result,del,null) == "NULL") {
					return HxOverrides.substr(result,1,null);
				}
			}
		}
		return result;
	}
	,parseCell: function(txt) {
		this.cursor = 0;
		this.row_ended = false;
		this.has_structure = false;
		return this.parseCellPart(txt);
	}
	,getDiscoveredEol: function() {
		return this.discovered_eol;
	}
	,setPreferredEol: function(eol) {
		this.preferred_eol = eol;
	}
	,__class__: coopy_Csv
};
var coopy_DiffRender = $hx_exports["coopy"]["DiffRender"] = function() {
	this.text_to_insert = [];
	this.open = false;
	this.pretty_arrows = true;
	this.quote_html = true;
};
coopy_DiffRender.__name__ = true;
coopy_DiffRender.examineCell = function(x,y,view,raw,vcol,vrow,vcorner,cell,offset) {
	if(offset == null) {
		offset = 0;
	}
	var nested = view.isHash(raw);
	cell.category = "";
	cell.category_given_tr = "";
	cell.separator = "";
	cell.pretty_separator = "";
	cell.conflicted = false;
	cell.updated = false;
	cell.meta = cell.pvalue = cell.lvalue = cell.rvalue = null;
	cell.value = raw;
	cell.pretty_value = cell.value;
	if(vrow == null) {
		vrow = "";
	}
	if(vcol == null) {
		vcol = "";
	}
	if(vrow.length >= 3 && vrow.charAt(0) == "@" && vrow.charAt(1) != "@") {
		var idx = vrow.indexOf("@",1);
		if(idx >= 0) {
			cell.meta = HxOverrides.substr(vrow,1,idx - 1);
			vrow = HxOverrides.substr(vrow,idx + 1,vrow.length);
			cell.category = "meta";
		}
	}
	var removed_column = false;
	if(vrow == ":") {
		cell.category = "move";
	}
	if(vrow == "" && offset == 1 && y == 0) {
		cell.category = "index";
	}
	if(vcol.indexOf("+++") >= 0) {
		cell.category_given_tr = cell.category = "add";
	} else if(vcol.indexOf("---") >= 0) {
		cell.category_given_tr = cell.category = "remove";
		removed_column = true;
	}
	if(vrow == "!") {
		cell.category = "spec";
	} else if(vrow == "@@") {
		cell.category = "header";
	} else if(vrow == "...") {
		cell.category = "gap";
	} else if(vrow == "+++") {
		if(!removed_column) {
			cell.category = "add";
		}
	} else if(vrow == "---") {
		cell.category = "remove";
	} else if(vrow.indexOf("->") >= 0) {
		if(!removed_column) {
			var tokens = vrow.split("!");
			var full = vrow;
			var part = tokens[1];
			if(part == null) {
				part = full;
			}
			var str = view.toString(cell.value);
			if(str == null) {
				str = "";
			}
			if(nested || str.indexOf(part) >= 0) {
				var cat = "modify";
				var div = part;
				if(part != full) {
					if(nested) {
						cell.conflicted = view.hashExists(raw,"theirs");
					} else {
						cell.conflicted = str.indexOf(full) >= 0;
					}
					if(cell.conflicted) {
						div = full;
						cat = "conflict";
					}
				}
				cell.updated = true;
				cell.separator = div;
				cell.pretty_separator = div;
				if(nested) {
					if(cell.conflicted) {
						tokens = [view.hashGet(raw,"before"),view.hashGet(raw,"ours"),view.hashGet(raw,"theirs")];
					} else {
						tokens = [view.hashGet(raw,"before"),view.hashGet(raw,"after")];
					}
				} else {
					cell.pretty_value = view.toString(cell.pretty_value);
					if(cell.pretty_value == null) {
						cell.pretty_value = "";
					}
					if(cell.pretty_value == div) {
						tokens = ["",""];
					} else {
						tokens = cell.pretty_value.split(div);
					}
				}
				var pretty_tokens = tokens;
				if(tokens.length >= 2) {
					pretty_tokens[0] = coopy_DiffRender.markSpaces(tokens[0],tokens[1]);
					pretty_tokens[1] = coopy_DiffRender.markSpaces(tokens[1],tokens[0]);
				}
				if(tokens.length >= 3) {
					var ref = pretty_tokens[0];
					pretty_tokens[0] = coopy_DiffRender.markSpaces(ref,tokens[2]);
					pretty_tokens[2] = coopy_DiffRender.markSpaces(tokens[2],ref);
				}
				cell.pretty_separator = String.fromCodePoint(8594);
				cell.pretty_value = pretty_tokens.join(cell.pretty_separator);
				cell.category_given_tr = cell.category = cat;
				var offset1 = cell.conflicted ? 1 : 0;
				cell.lvalue = tokens[offset1];
				cell.rvalue = tokens[offset1 + 1];
				if(cell.conflicted) {
					cell.pvalue = tokens[0];
				}
			}
		}
	}
	if(x == 0 && offset > 0) {
		cell.category_given_tr = cell.category = "index";
	}
};
coopy_DiffRender.markSpaces = function(sl,sr) {
	if(sl == sr) {
		return sl;
	}
	if(sl == null || sr == null) {
		return sl;
	}
	var slc = StringTools.replace(sl," ","");
	var src = StringTools.replace(sr," ","");
	if(slc != src) {
		return sl;
	}
	var slo = new String("");
	var il = 0;
	var ir = 0;
	while(il < sl.length) {
		var cl = sl.charAt(il);
		var cr = "";
		if(ir < sr.length) {
			cr = sr.charAt(ir);
		}
		if(cl == cr) {
			slo += cl;
			++il;
			++ir;
		} else if(cr == " ") {
			++ir;
		} else {
			slo += String.fromCodePoint(9251);
			++il;
		}
	}
	return slo;
};
coopy_DiffRender.renderCell = function(tab,view,x,y) {
	var cell = new coopy_CellInfo();
	var corner = view.toString(tab.getCell(0,0));
	var off = corner == "@:@" ? 1 : 0;
	coopy_DiffRender.examineCell(x,y,view,tab.getCell(x,y),view.toString(tab.getCell(x,off)),view.toString(tab.getCell(off,y)),corner,cell,off);
	return cell;
};
coopy_DiffRender.prototype = {
	text_to_insert: null
	,td_open: null
	,td_close: null
	,open: null
	,pretty_arrows: null
	,quote_html: null
	,section: null
	,usePrettyArrows: function(flag) {
		this.pretty_arrows = flag;
	}
	,quoteHtml: function(flag) {
		this.quote_html = flag;
	}
	,insert: function(str) {
		this.text_to_insert.push(str);
	}
	,beginTable: function() {
		this.insert("<table>\n");
		this.section = null;
	}
	,setSection: function(str) {
		if(str == this.section) {
			return;
		}
		if(this.section != null) {
			this.insert("</t");
			this.insert(this.section);
			this.insert(">\n");
		}
		this.section = str;
		if(this.section != null) {
			this.insert("<t");
			this.insert(this.section);
			this.insert(">\n");
		}
	}
	,beginRow: function(mode) {
		this.td_open = "<td";
		this.td_close = "</td>";
		var row_class = "";
		if(mode == "header") {
			this.td_open = "<th";
			this.td_close = "</th>";
		}
		row_class = mode;
		var tr = "<tr>";
		if(row_class != "") {
			tr = "<tr class=\"" + row_class + "\">";
		}
		this.insert(tr);
	}
	,insertCell: function(txt,mode) {
		var cell_decorate = "";
		if(mode != "") {
			cell_decorate = " class=\"" + mode + "\"";
		}
		this.insert(this.td_open + cell_decorate + ">");
		if(txt != null) {
			this.insert(txt);
		} else {
			this.insert("null");
		}
		this.insert(this.td_close);
	}
	,endRow: function() {
		this.insert("</tr>\n");
	}
	,endTable: function() {
		this.setSection(null);
		this.insert("</table>\n");
	}
	,html: function() {
		return this.text_to_insert.join("");
	}
	,toString: function() {
		return this.html();
	}
	,render: function(tab) {
		tab = coopy_Coopy.tablify(tab);
		if(tab.get_width() == 0 || tab.get_height() == 0) {
			return this;
		}
		var render = this;
		render.beginTable();
		var change_row = -1;
		var cell = new coopy_CellInfo();
		var view = tab.getCellView();
		var corner = view.toString(tab.getCell(0,0));
		var off = corner == "@:@" ? 1 : 0;
		if(off > 0) {
			if(tab.get_width() <= 1 || tab.get_height() <= 1) {
				return this;
			}
		}
		var _g = 0;
		var _g1 = tab.get_height();
		while(_g < _g1) {
			var row = _g++;
			var open = false;
			var txt = view.toString(tab.getCell(off,row));
			if(txt == null) {
				txt = "";
			}
			coopy_DiffRender.examineCell(off,row,view,txt,"",txt,corner,cell,off);
			var row_mode = cell.category;
			if(row_mode == "spec") {
				change_row = row;
			}
			if(row_mode == "header" || row_mode == "spec" || row_mode == "index" || row_mode == "meta") {
				this.setSection("head");
			} else {
				this.setSection("body");
			}
			render.beginRow(row_mode);
			var _g2 = 0;
			var _g3 = tab.get_width();
			while(_g2 < _g3) {
				var c = _g2++;
				coopy_DiffRender.examineCell(c,row,view,tab.getCell(c,row),change_row >= 0 ? view.toString(tab.getCell(c,change_row)) : "",txt,corner,cell,off);
				var val = this.pretty_arrows ? cell.pretty_value : cell.value;
				if(this.quote_html) {
					val = StringTools.htmlEscape(view.toString(val));
				}
				render.insertCell(val,cell.category_given_tr);
			}
			render.endRow();
		}
		render.endTable();
		return this;
	}
	,renderTables: function(tabs) {
		var order = tabs.getOrder();
		var start = 0;
		if(order.length <= 1 || tabs.hasInsDel()) {
			this.render(tabs.one());
			start = 1;
		}
		var _g = start;
		var _g1 = order.length;
		while(_g < _g1) {
			var i = _g++;
			var name = order[i];
			var tab = tabs.get(name);
			if(tab.get_height() <= 1) {
				continue;
			}
			this.insert("<h3>");
			this.insert(name);
			this.insert("</h3>\n");
			this.render(tab);
		}
		return this;
	}
	,sampleCss: function() {
		return ".highlighter .add { \n  background-color: #7fff7f;\n}\n\n.highlighter .remove { \n  background-color: #ff7f7f;\n}\n\n.highlighter td.modify { \n  background-color: #7f7fff;\n}\n\n.highlighter td.conflict { \n  background-color: #f00;\n}\n\n.highlighter .spec { \n  background-color: #aaa;\n}\n\n.highlighter .move { \n  background-color: #ffa;\n}\n\n.highlighter .null { \n  color: #888;\n}\n\n.highlighter table { \n  border-collapse:collapse;\n}\n\n.highlighter td, .highlighter th {\n  border: 1px solid #2D4068;\n  padding: 3px 7px 2px;\n}\n\n.highlighter th, .highlighter .header, .highlighter .meta {\n  background-color: #aaf;\n  font-weight: bold;\n  padding-bottom: 4px;\n  padding-top: 5px;\n  text-align:left;\n}\n\n.highlighter tr.header th {\n  border-bottom: 2px solid black;\n}\n\n.highlighter tr.index td, .highlighter .index, .highlighter tr.header th.index {\n  background-color: white;\n  border: none;\n}\n\n.highlighter .gap {\n  color: #888;\n}\n\n.highlighter td {\n  empty-cells: show;\n  white-space: pre-wrap;\n}\n";
	}
	,completeHtml: function() {
		this.text_to_insert.splice(0,0,"<!DOCTYPE html>\n<html>\n<head>\n<meta charset='utf-8'>\n<style TYPE='text/css'>\n");
		var _this = this.text_to_insert;
		var x = this.sampleCss();
		_this.splice(1,0,x);
		this.text_to_insert.splice(2,0,"</style>\n</head>\n<body>\n<div class='highlighter'>\n");
		this.text_to_insert.push("</div>\n</body>\n</html>\n");
	}
	,__class__: coopy_DiffRender
};
var coopy_DiffSummary = $hx_exports["coopy"]["DiffSummary"] = function() {
};
coopy_DiffSummary.__name__ = true;
coopy_DiffSummary.prototype = {
	row_deletes: null
	,row_inserts: null
	,row_updates: null
	,row_reorders: null
	,col_deletes: null
	,col_inserts: null
	,col_updates: null
	,col_renames: null
	,col_reorders: null
	,row_count_initial_with_header: null
	,row_count_final_with_header: null
	,row_count_initial: null
	,row_count_final: null
	,col_count_initial: null
	,col_count_final: null
	,different: null
	,__class__: coopy_DiffSummary
};
var coopy_FlatCellBuilder = function(flags) {
	this.flags = flags;
};
coopy_FlatCellBuilder.__name__ = true;
coopy_FlatCellBuilder.__interfaces__ = [coopy_CellBuilder];
coopy_FlatCellBuilder.quoteForDiff = function(v,d) {
	var nil = "NULL";
	if(v.equals(d,null)) {
		return nil;
	}
	var str = v.toString(d);
	var score = 0;
	var _g = 0;
	var _g1 = str.length;
	while(_g < _g1) {
		var i = _g++;
		if(HxOverrides.cca(str,score) != 95) {
			break;
		}
		++score;
	}
	if(HxOverrides.substr(str,score,null) == nil) {
		str = "_" + str;
	}
	return str;
};
coopy_FlatCellBuilder.prototype = {
	view: null
	,separator: null
	,conflict_separator: null
	,flags: null
	,needSeparator: function() {
		return true;
	}
	,setSeparator: function(separator) {
		this.separator = separator;
	}
	,setConflictSeparator: function(separator) {
		this.conflict_separator = separator;
	}
	,setView: function(view) {
		this.view = view;
	}
	,update: function(local,remote) {
		return this.view.toDatum(coopy_FlatCellBuilder.quoteForDiff(this.view,local) + this.separator + coopy_FlatCellBuilder.quoteForDiff(this.view,remote));
	}
	,conflict: function(parent,local,remote) {
		return this.view.toString(parent) + this.conflict_separator + this.view.toString(local) + this.conflict_separator + this.view.toString(remote);
	}
	,marker: function(label) {
		return this.view.toDatum(label);
	}
	,links: function(unit,row_like) {
		if(this.flags.count_like_a_spreadsheet && !row_like) {
			return this.view.toDatum(unit.toBase26String());
		}
		return this.view.toDatum(unit.toString());
	}
	,__class__: coopy_FlatCellBuilder
};
var coopy_Row = function() { };
coopy_Row.__name__ = true;
coopy_Row.prototype = {
	getRowString: null
	,isPreamble: null
	,__class__: coopy_Row
};
var coopy_HighlightPatch = $hx_exports["coopy"]["HighlightPatch"] = function(source,patch,flags) {
	this.source = source;
	this.patch = patch;
	this.flags = flags;
	if(flags == null) {
		this.flags = new coopy_CompareFlags();
	}
	this.view = patch.getCellView();
	this.sourceView = source.getCellView();
	this.meta = source.getMeta();
};
coopy_HighlightPatch.__name__ = true;
coopy_HighlightPatch.__interfaces__ = [coopy_Row];
coopy_HighlightPatch.prototype = {
	source: null
	,patch: null
	,view: null
	,sourceView: null
	,csv: null
	,header: null
	,headerPre: null
	,headerPost: null
	,headerRename: null
	,headerMove: null
	,modifier: null
	,currentRow: null
	,payloadCol: null
	,payloadTop: null
	,mods: null
	,cmods: null
	,rowInfo: null
	,cellInfo: null
	,rcOffset: null
	,indexes: null
	,sourceInPatchCol: null
	,patchInSourceCol: null
	,destInPatchCol: null
	,patchInDestCol: null
	,patchInSourceRow: null
	,lastSourceRow: null
	,actions: null
	,rowPermutation: null
	,rowPermutationRev: null
	,colPermutation: null
	,colPermutationRev: null
	,haveDroppedColumns: null
	,headerRow: null
	,preambleRow: null
	,flags: null
	,meta_change: null
	,process_meta: null
	,prev_meta: null
	,next_meta: null
	,finished_columns: null
	,meta: null
	,reset: function() {
		this.header = new haxe_ds_IntMap();
		this.headerPre = new haxe_ds_StringMap();
		this.headerPost = new haxe_ds_StringMap();
		this.headerRename = new haxe_ds_StringMap();
		this.headerMove = null;
		this.modifier = new haxe_ds_IntMap();
		this.mods = [];
		this.cmods = [];
		this.csv = new coopy_Csv();
		this.rcOffset = 0;
		this.currentRow = -1;
		this.rowInfo = new coopy_CellInfo();
		this.cellInfo = new coopy_CellInfo();
		this.sourceInPatchCol = this.patchInSourceCol = this.patchInDestCol = null;
		this.patchInSourceRow = new haxe_ds_IntMap();
		this.indexes = null;
		this.lastSourceRow = -1;
		this.actions = [];
		this.rowPermutation = null;
		this.rowPermutationRev = null;
		this.colPermutation = null;
		this.colPermutationRev = null;
		this.haveDroppedColumns = false;
		this.headerRow = 0;
		this.preambleRow = 0;
		this.meta_change = false;
		this.process_meta = false;
		this.prev_meta = null;
		this.next_meta = null;
		this.finished_columns = false;
	}
	,processMeta: function() {
		this.process_meta = true;
	}
	,apply: function() {
		this.reset();
		if(this.patch.get_width() < 2) {
			return true;
		}
		if(this.patch.get_height() < 1) {
			return true;
		}
		this.payloadCol = 1 + this.rcOffset;
		this.payloadTop = this.patch.get_width();
		var corner = this.patch.getCellView().toString(this.patch.getCell(0,0));
		this.rcOffset = corner == "@:@" ? 1 : 0;
		var _g = 0;
		var _g1 = this.patch.get_height();
		while(_g < _g1) {
			var r = _g++;
			var str = this.view.toString(this.patch.getCell(this.rcOffset,r));
			this.actions.push(str != null ? str : "");
		}
		this.preambleRow = this.headerRow = this.rcOffset;
		var _g = 0;
		var _g1 = this.patch.get_height();
		while(_g < _g1) {
			var r = _g++;
			this.applyRow(r);
		}
		this.finishColumns();
		this.finishRows();
		return true;
	}
	,needSourceColumns: function() {
		if(this.sourceInPatchCol != null) {
			return;
		}
		this.sourceInPatchCol = new haxe_ds_IntMap();
		this.patchInSourceCol = new haxe_ds_IntMap();
		var av = this.source.getCellView();
		var _g = 0;
		var _g1 = this.source.get_width();
		while(_g < _g1) {
			var i = _g++;
			var name = av.toString(this.source.getCell(i,0));
			var at = this.headerPre.h[name];
			if(at == null) {
				continue;
			}
			this.sourceInPatchCol.h[i] = at;
			this.patchInSourceCol.h[at] = i;
		}
	}
	,needDestColumns: function() {
		if(this.patchInDestCol != null) {
			return;
		}
		this.patchInDestCol = new haxe_ds_IntMap();
		this.destInPatchCol = new haxe_ds_IntMap();
		var _g = 0;
		var _g1 = this.cmods;
		while(_g < _g1.length) {
			var cmod = _g1[_g];
			++_g;
			if(cmod.patchRow != -1) {
				this.patchInDestCol.h[cmod.patchRow] = cmod.destRow;
				this.destInPatchCol.h[cmod.destRow] = cmod.patchRow;
			}
		}
	}
	,needSourceIndex: function() {
		if(this.indexes != null) {
			return;
		}
		var state = new coopy_TableComparisonState();
		state.a = this.source;
		state.b = this.source;
		var comp = new coopy_CompareTable(state);
		comp.storeIndexes();
		comp.run();
		comp.align();
		this.indexes = comp.getIndexes();
		this.needSourceColumns();
	}
	,setMetaProp: function(target,column_name,prop_name,value) {
		if(column_name == null) {
			return;
		}
		if(prop_name == null) {
			return;
		}
		if(!Object.prototype.hasOwnProperty.call(target.h,column_name)) {
			var value1 = [];
			target.h[column_name] = value1;
		}
		var change = new coopy_PropertyChange();
		change.prevName = prop_name;
		change.name = prop_name;
		if(value == "") {
			value = null;
		}
		change.val = value;
		target.h[column_name].push(change);
	}
	,applyMetaRow: function(code) {
		this.needSourceColumns();
		var codes = code.split("@");
		var prop_name = "";
		if(codes.length > 1) {
			prop_name = codes[codes.length - 2];
		}
		if(codes.length > 0) {
			code = codes[codes.length - 1];
		}
		if(this.prev_meta == null) {
			this.prev_meta = new haxe_ds_StringMap();
		}
		if(this.next_meta == null) {
			this.next_meta = new haxe_ds_StringMap();
		}
		var _g = this.payloadCol;
		var _g1 = this.payloadTop;
		while(_g < _g1) {
			var i = _g++;
			var txt = this.getDatum(i);
			var idx_patch = i;
			var idx_src = this.patchInSourceCol.h.hasOwnProperty(idx_patch) ? this.patchInSourceCol.h[idx_patch] : -1;
			var prev_name = null;
			var name = null;
			if(idx_src != -1) {
				prev_name = this.source.getCell(idx_src,0);
			}
			if(this.header.h.hasOwnProperty(idx_patch)) {
				name = this.header.h[idx_patch];
			}
			coopy_DiffRender.examineCell(0,0,this.view,txt,"",code,"",this.cellInfo);
			if(this.cellInfo.updated) {
				this.setMetaProp(this.prev_meta,prev_name,prop_name,this.cellInfo.lvalue);
				this.setMetaProp(this.next_meta,name,prop_name,this.cellInfo.rvalue);
			} else {
				this.setMetaProp(this.prev_meta,prev_name,prop_name,this.cellInfo.value);
				this.setMetaProp(this.next_meta,name,prop_name,this.cellInfo.value);
			}
		}
	}
	,applyRow: function(r) {
		this.currentRow = r;
		var code = this.actions[r];
		var done = false;
		if(r == 0 && this.rcOffset > 0) {
			done = true;
		} else if(code == "@@") {
			this.preambleRow = this.headerRow = r;
			this.applyHeader();
			this.applyAction("@@");
			done = true;
		} else if(code == "!") {
			this.preambleRow = this.headerRow = r;
			this.applyMeta();
			done = true;
		} else if(code.indexOf("@") == 0) {
			this.flags.addWarning("cannot usefully apply diffs with metadata yet: '" + code + "'");
			this.preambleRow = r;
			this.applyMetaRow(code);
			if(this.process_meta) {
				var codes = code.split("@");
				if(codes.length > 0) {
					code = codes[codes.length - 1];
				}
			} else {
				this.meta_change = true;
				done = true;
			}
			this.meta_change = true;
			done = true;
		}
		if(this.process_meta) {
			return;
		}
		if(!done) {
			this.finishColumns();
			if(code == "+++") {
				this.applyAction(code);
			} else if(code == "---") {
				this.applyAction(code);
			} else if(code == "+" || code == ":") {
				this.applyAction(code);
			} else if(code.indexOf("->") >= 0) {
				this.applyAction("->");
			} else {
				this.lastSourceRow = -1;
			}
		}
	}
	,getDatum: function(c) {
		return this.patch.getCell(c,this.currentRow);
	}
	,getString: function(c) {
		return this.view.toString(this.getDatum(c));
	}
	,getStringNull: function(c) {
		var d = this.getDatum(c);
		if(d == null) {
			return null;
		}
		return this.view.toString(d);
	}
	,applyMeta: function() {
		var _g = this.payloadCol;
		var _g1 = this.payloadTop;
		while(_g < _g1) {
			var i = _g++;
			var name = this.getString(i);
			if(name == "") {
				continue;
			}
			this.modifier.h[i] = name;
		}
	}
	,applyHeader: function() {
		var _g = this.payloadCol;
		var _g1 = this.payloadTop;
		while(_g < _g1) {
			var i = _g++;
			var name = this.getString(i);
			if(name == "...") {
				this.modifier.h[i] = "...";
				this.haveDroppedColumns = true;
				continue;
			}
			var mod = this.modifier.h[i];
			var move = false;
			if(mod != null) {
				if(HxOverrides.cca(mod,0) == 58) {
					move = true;
					mod = HxOverrides.substr(mod,1,mod.length);
				}
			}
			this.header.h[i] = name;
			if(mod != null) {
				if(HxOverrides.cca(mod,0) == 40) {
					var prev_name = HxOverrides.substr(mod,1,mod.length - 2);
					this.headerPre.h[prev_name] = i;
					this.headerPost.h[name] = i;
					this.headerRename.h[prev_name] = name;
					continue;
				}
			}
			if(mod != "+++") {
				this.headerPre.h[name] = i;
			}
			if(mod != "---") {
				this.headerPost.h[name] = i;
			}
			if(move) {
				if(this.headerMove == null) {
					this.headerMove = new haxe_ds_StringMap();
				}
				this.headerMove.h[name] = 1;
			}
		}
		if(!this.useMetaForRowChanges()) {
			if(this.source.get_height() == 0) {
				this.applyAction("+++");
			}
		}
	}
	,lookUp: function(del) {
		if(del == null) {
			del = 0;
		}
		if(this.patchInSourceRow.h.hasOwnProperty(this.currentRow + del)) {
			return this.patchInSourceRow.h[this.currentRow + del];
		}
		var result = -1;
		this.currentRow += del;
		if(this.currentRow >= 0 && this.currentRow < this.patch.get_height()) {
			var _g = 0;
			var _g1 = this.indexes;
			while(_g < _g1.length) {
				var idx = _g1[_g];
				++_g;
				var match = idx.queryByContent(this);
				if(match.spot_a == 0) {
					continue;
				}
				if(match.spot_a == 1) {
					result = match.item_a.lst[0];
					break;
				}
				if(this.currentRow > 0) {
					var prev = this.patchInSourceRow.h[this.currentRow - 1];
					if(prev != null) {
						var lst = match.item_a.lst;
						var _g2 = 0;
						while(_g2 < lst.length) {
							var row = lst[_g2];
							++_g2;
							if(row == prev + 1) {
								result = row;
								break;
							}
						}
					}
				}
			}
		}
		this.patchInSourceRow.h[this.currentRow] = result;
		this.currentRow -= del;
		return result;
	}
	,applyActionExternal: function(code) {
		if(code == "@@") {
			return;
		}
		var rc = new coopy_RowChange();
		rc.action = code;
		this.checkAct();
		if(code != "+++") {
			rc.cond = new haxe_ds_StringMap();
		}
		if(code != "---") {
			rc.val = new haxe_ds_StringMap();
		}
		var have_column = false;
		var _g = this.payloadCol;
		var _g1 = this.payloadTop;
		while(_g < _g1) {
			var i = _g++;
			var prev_name = this.header.h[i];
			var name = prev_name;
			if(Object.prototype.hasOwnProperty.call(this.headerRename.h,prev_name)) {
				name = this.headerRename.h[prev_name];
			}
			var cact = this.modifier.h[i];
			if(cact == "...") {
				continue;
			}
			if(name == null || name == "") {
				continue;
			}
			var txt = this.csv.parseCell(this.getStringNull(i));
			var updated = false;
			if(this.rowInfo.updated) {
				this.getPreString(txt);
				updated = this.cellInfo.updated;
			}
			if(cact == "+++" && code != "---") {
				if(txt != null && txt != "") {
					if(rc.val == null) {
						rc.val = new haxe_ds_StringMap();
					}
					rc.val.h[name] = txt;
					have_column = true;
				}
			}
			if(updated) {
				var this1 = rc.cond;
				var value = this.csv.parseCell(this.cellInfo.lvalue);
				this1.h[name] = value;
				var this2 = rc.val;
				var value1 = this.csv.parseCell(this.cellInfo.rvalue);
				this2.h[name] = value1;
			} else if(code == "+++") {
				if(cact != "---") {
					rc.val.h[name] = txt;
				}
			} else if(cact != "+++" && cact != "---") {
				rc.cond.h[name] = txt;
			}
		}
		if(rc.action == "+") {
			if(!have_column) {
				return;
			}
			rc.action = "->";
		}
		this.meta.changeRow(rc);
	}
	,applyAction: function(code) {
		if(this.useMetaForRowChanges()) {
			this.applyActionExternal(code);
			return;
		}
		var mod = new coopy_HighlightPatchUnit();
		mod.code = code;
		mod.add = code == "+++";
		mod.rem = code == "---";
		mod.update = code == "->";
		this.needSourceIndex();
		if(this.lastSourceRow == -1) {
			this.lastSourceRow = this.lookUp(-1);
		}
		mod.sourcePrevRow = this.lastSourceRow;
		var nextAct = this.actions[this.currentRow + 1];
		if(nextAct != "+++" && nextAct != "...") {
			mod.sourceNextRow = this.lookUp(1);
		}
		if(mod.add) {
			if(this.actions[this.currentRow - 1] != "+++") {
				if(this.actions[this.currentRow - 1] == "@@") {
					mod.sourcePrevRow = 0;
					this.lastSourceRow = 0;
				} else {
					mod.sourcePrevRow = this.lookUp(-1);
				}
			}
			mod.sourceRow = mod.sourcePrevRow;
			if(mod.sourceRow != -1) {
				mod.sourceRowOffset = 1;
			}
		} else {
			mod.sourceRow = this.lastSourceRow = this.lookUp();
		}
		if(this.actions[this.currentRow + 1] == "") {
			this.lastSourceRow = mod.sourceNextRow;
		}
		mod.patchRow = this.currentRow;
		if(code == "@@") {
			mod.sourceRow = 0;
		}
		this.mods.push(mod);
	}
	,checkAct: function() {
		var act = this.getString(this.rcOffset);
		if(this.rowInfo.value != act) {
			coopy_DiffRender.examineCell(0,0,this.view,act,"",act,"",this.rowInfo);
		}
	}
	,getPreString: function(txt) {
		this.checkAct();
		if(!this.rowInfo.updated) {
			return txt;
		}
		coopy_DiffRender.examineCell(0,0,this.view,txt,"",this.rowInfo.value,"",this.cellInfo);
		if(!this.cellInfo.updated) {
			return txt;
		}
		return this.cellInfo.lvalue;
	}
	,getRowString: function(c) {
		var at = this.sourceInPatchCol.h[c];
		if(at == null) {
			return "NOT_FOUND";
		}
		return this.getPreString(this.getString(at));
	}
	,isPreamble: function() {
		return this.currentRow <= this.preambleRow;
	}
	,sortMods: function(a,b) {
		if(b.code == "@@" && a.code != "@@") {
			return 1;
		}
		if(a.code == "@@" && b.code != "@@") {
			return -1;
		}
		if(a.sourceRow == -1 && !a.add && b.sourceRow != -1) {
			return 1;
		}
		if(a.sourceRow != -1 && !b.add && b.sourceRow == -1) {
			return -1;
		}
		if(a.sourceRow + a.sourceRowOffset > b.sourceRow + b.sourceRowOffset) {
			return 1;
		}
		if(a.sourceRow + a.sourceRowOffset < b.sourceRow + b.sourceRowOffset) {
			return -1;
		}
		if(a.patchRow > b.patchRow) {
			return 1;
		}
		if(a.patchRow < b.patchRow) {
			return -1;
		}
		return 0;
	}
	,processMods: function(rmods,fate,len) {
		rmods.sort($bind(this,this.sortMods));
		var offset = 0;
		var last = -1;
		var target = 0;
		if(rmods.length > 0) {
			if(rmods[0].sourcePrevRow == -1) {
				last = 0;
			}
		}
		var _g = 0;
		while(_g < rmods.length) {
			var mod = rmods[_g];
			++_g;
			if(last != -1) {
				var _g1 = last;
				var _g2 = mod.sourceRow + mod.sourceRowOffset;
				while(_g1 < _g2) {
					var i = _g1++;
					fate.push(i + offset);
					++target;
					++last;
				}
			}
			if(mod.rem) {
				fate.push(-1);
				--offset;
			} else if(mod.add) {
				mod.destRow = target;
				++target;
				++offset;
			} else {
				mod.destRow = target;
			}
			if(mod.sourceRow >= 0) {
				last = mod.sourceRow + mod.sourceRowOffset;
				if(mod.rem) {
					++last;
				}
			} else if(mod.add && mod.sourceNextRow != -1) {
				last = mod.sourceNextRow + mod.sourceRowOffset;
			} else if(mod.rem || mod.add) {
				last = -1;
			}
		}
		if(last != -1) {
			var _g = last;
			var _g1 = len;
			while(_g < _g1) {
				var i = _g++;
				fate.push(i + offset);
				++target;
				++last;
			}
		}
		return len + offset;
	}
	,useMetaForColumnChanges: function() {
		if(this.meta == null) {
			return false;
		}
		return this.meta.useForColumnChanges();
	}
	,useMetaForRowChanges: function() {
		if(this.meta == null) {
			return false;
		}
		return this.meta.useForRowChanges();
	}
	,computeOrdering: function(mods,permutation,permutationRev,dim) {
		var to_unit_h = { };
		var from_unit_h = { };
		var meta_from_unit_h = { };
		var ct = 0;
		var _g = 0;
		while(_g < mods.length) {
			var mod = mods[_g];
			++_g;
			if(mod.add || mod.rem) {
				continue;
			}
			if(mod.sourceRow < 0) {
				continue;
			}
			if(mod.sourcePrevRow >= 0) {
				var v = mod.sourceRow;
				to_unit_h[mod.sourcePrevRow] = v;
				var v1 = mod.sourcePrevRow;
				from_unit_h[mod.sourceRow] = v1;
				if(mod.sourcePrevRow + 1 != mod.sourceRow) {
					++ct;
				}
			}
			if(mod.sourceNextRow >= 0) {
				var v2 = mod.sourceNextRow;
				to_unit_h[mod.sourceRow] = v2;
				var v3 = mod.sourceRow;
				from_unit_h[mod.sourceNextRow] = v3;
				if(mod.sourceRow + 1 != mod.sourceNextRow) {
					++ct;
				}
			}
		}
		if(ct > 0) {
			var cursor = null;
			var logical = null;
			var starts = [];
			var _g = 0;
			var _g1 = dim;
			while(_g < _g1) {
				var i = _g++;
				var u = from_unit_h[i];
				if(u != null) {
					meta_from_unit_h[u] = i;
				} else {
					starts.push(i);
				}
			}
			var used_h = { };
			var len = 0;
			var _g = 0;
			var _g1 = dim;
			while(_g < _g1) {
				var i = _g++;
				if(logical != null && meta_from_unit_h.hasOwnProperty(logical)) {
					cursor = meta_from_unit_h[logical];
				} else {
					cursor = null;
				}
				if(cursor == null) {
					var v = starts.shift();
					cursor = v;
					logical = v;
				}
				if(cursor == null) {
					cursor = 0;
				}
				while(used_h.hasOwnProperty(cursor)) cursor = (cursor + 1) % dim;
				logical = cursor;
				permutationRev.push(cursor);
				used_h[cursor] = 1;
			}
			var _g = 0;
			var _g1 = permutationRev.length;
			while(_g < _g1) {
				var i = _g++;
				permutation[i] = -1;
			}
			var _g = 0;
			var _g1 = permutation.length;
			while(_g < _g1) {
				var i = _g++;
				permutation[permutationRev[i]] = i;
			}
		}
	}
	,permuteRows: function() {
		this.rowPermutation = [];
		this.rowPermutationRev = [];
		this.computeOrdering(this.mods,this.rowPermutation,this.rowPermutationRev,this.source.get_height());
	}
	,fillInNewColumns: function() {
		var _g = 0;
		var _g1 = this.cmods;
		while(_g < _g1.length) {
			var cmod = _g1[_g];
			++_g;
			if(!cmod.rem) {
				if(cmod.add) {
					var _g2 = 0;
					var _g3 = this.mods;
					while(_g2 < _g3.length) {
						var mod = _g3[_g2];
						++_g2;
						if(mod.patchRow != -1 && mod.destRow != -1) {
							var d = this.patch.getCell(cmod.patchRow,mod.patchRow);
							this.source.setCell(cmod.destRow,mod.destRow,d);
						}
					}
					var hdr = this.header.h[cmod.patchRow];
					this.source.setCell(cmod.destRow,0,this.view.toDatum(hdr));
				}
			}
		}
	}
	,finishRows: function() {
		if(this.useMetaForRowChanges()) {
			return;
		}
		if(this.source.get_width() == 0) {
			if(this.source.get_height() != 0) {
				this.source.resize(0,0);
			}
			return;
		}
		var fate = [];
		this.permuteRows();
		if(this.rowPermutation.length > 0) {
			var _g = 0;
			var _g1 = this.mods;
			while(_g < _g1.length) {
				var mod = _g1[_g];
				++_g;
				if(mod.sourceRow >= 0) {
					mod.sourceRow = this.rowPermutation[mod.sourceRow];
				}
			}
		}
		if(this.rowPermutation.length > 0) {
			this.source.insertOrDeleteRows(this.rowPermutation,this.rowPermutation.length);
		}
		var len = this.processMods(this.mods,fate,this.source.get_height());
		this.source.insertOrDeleteRows(fate,len);
		this.needDestColumns();
		var _g = 0;
		var _g1 = this.mods;
		while(_g < _g1.length) {
			var mod = _g1[_g];
			++_g;
			if(!mod.rem) {
				if(mod.add) {
					var h = this.headerPost.h;
					var c_h = h;
					var c_keys = Object.keys(h);
					var c_length = c_keys.length;
					var c_current = 0;
					while(c_current < c_length) {
						var c = c_h[c_keys[c_current++]];
						var offset = this.patchInDestCol.h[c];
						if(offset != null && offset >= 0) {
							this.source.setCell(offset,mod.destRow,this.patch.getCell(c,mod.patchRow));
						}
					}
				} else if(mod.update) {
					this.currentRow = mod.patchRow;
					this.checkAct();
					if(!this.rowInfo.updated) {
						continue;
					}
					var h1 = this.headerPre.h;
					var c_h1 = h1;
					var c_keys1 = Object.keys(h1);
					var c_length1 = c_keys1.length;
					var c_current1 = 0;
					while(c_current1 < c_length1) {
						var c1 = c_h1[c_keys1[c_current1++]];
						var txt = this.view.toString(this.patch.getCell(c1,mod.patchRow));
						coopy_DiffRender.examineCell(0,0,this.view,txt,"",this.rowInfo.value,"",this.cellInfo);
						if(!this.cellInfo.updated) {
							continue;
						}
						if(this.cellInfo.conflicted) {
							continue;
						}
						var d = this.view.toDatum(this.csv.parseCell(this.cellInfo.rvalue));
						var offset1 = this.patchInDestCol.h[c1];
						if(offset1 != null && offset1 >= 0) {
							this.source.setCell(this.patchInDestCol.h[c1],mod.destRow,d);
						}
					}
				}
			}
		}
		this.fillInNewColumns();
		var _g = 0;
		var _g1 = this.source.get_width();
		while(_g < _g1) {
			var i = _g++;
			var name = this.view.toString(this.source.getCell(i,0));
			var next_name = this.headerRename.h[name];
			if(next_name == null) {
				continue;
			}
			this.source.setCell(i,0,this.view.toDatum(next_name));
		}
	}
	,permuteColumns: function() {
		if(this.headerMove == null) {
			return;
		}
		this.colPermutation = [];
		this.colPermutationRev = [];
		this.computeOrdering(this.cmods,this.colPermutation,this.colPermutationRev,this.source.get_width());
		if(this.colPermutation.length == 0) {
			return;
		}
	}
	,finishColumns: function() {
		if(this.finished_columns) {
			return;
		}
		this.finished_columns = true;
		this.needSourceColumns();
		var _g = this.payloadCol;
		var _g1 = this.payloadTop;
		while(_g < _g1) {
			var i = _g++;
			var act = this.modifier.h[i];
			var hdr = this.header.h[i];
			if(act == null) {
				act = "";
			}
			if(act == "---") {
				var at = -1;
				if(this.patchInSourceCol.h.hasOwnProperty(i)) {
					at = this.patchInSourceCol.h[i];
				}
				var mod = new coopy_HighlightPatchUnit();
				mod.code = act;
				mod.rem = true;
				mod.sourceRow = at;
				mod.patchRow = i;
				this.cmods.push(mod);
			} else if(act == "+++") {
				var mod1 = new coopy_HighlightPatchUnit();
				mod1.code = act;
				mod1.add = true;
				var prev = -1;
				var cont = false;
				mod1.sourceRow = -1;
				if(this.cmods.length > 0) {
					mod1.sourceRow = this.cmods[this.cmods.length - 1].sourceRow;
				}
				if(mod1.sourceRow != -1) {
					mod1.sourceRowOffset = 1;
				}
				mod1.patchRow = i;
				this.cmods.push(mod1);
			} else if(act != "...") {
				var at1 = -1;
				if(this.patchInSourceCol.h.hasOwnProperty(i)) {
					at1 = this.patchInSourceCol.h[i];
				}
				var mod2 = new coopy_HighlightPatchUnit();
				mod2.code = act;
				mod2.patchRow = i;
				mod2.sourceRow = at1;
				this.cmods.push(mod2);
			}
		}
		var at = -1;
		var rat = -1;
		var _g = 0;
		var _g1 = this.cmods.length - 1;
		while(_g < _g1) {
			var i = _g++;
			var icode = this.cmods[i].code;
			if(icode != "+++" && icode != "---") {
				at = this.cmods[i].sourceRow;
			}
			this.cmods[i + 1].sourcePrevRow = at;
			var j = this.cmods.length - 1 - i;
			var jcode = this.cmods[j].code;
			if(jcode != "+++" && jcode != "---") {
				rat = this.cmods[j].sourceRow;
			}
			this.cmods[j - 1].sourceNextRow = rat;
		}
		var fate = [];
		this.permuteColumns();
		if(this.headerMove != null) {
			if(this.colPermutation.length > 0) {
				var _g = 0;
				var _g1 = this.cmods;
				while(_g < _g1.length) {
					var mod = _g1[_g];
					++_g;
					if(mod.sourceRow >= 0) {
						mod.sourceRow = this.colPermutation[mod.sourceRow];
					}
				}
				if(!this.useMetaForColumnChanges()) {
					this.source.insertOrDeleteColumns(this.colPermutation,this.colPermutation.length);
				}
			}
		}
		var len = this.processMods(this.cmods,fate,this.source.get_width());
		if(!this.useMetaForColumnChanges()) {
			this.source.insertOrDeleteColumns(fate,len);
			return;
		}
		var changed = false;
		var _g = 0;
		var _g1 = this.cmods;
		while(_g < _g1.length) {
			var mod = _g1[_g];
			++_g;
			if(mod.code != "") {
				changed = true;
				break;
			}
		}
		if(!changed) {
			return;
		}
		var columns = [];
		var target_h = { };
		var inc = function(x) {
			if(x < 0) {
				return x;
			} else {
				return x + 1;
			}
		};
		var _g = 0;
		var _g1 = fate.length;
		while(_g < _g1) {
			var i = _g++;
			target_h[i] = inc(fate[i]);
		}
		this.needSourceColumns();
		this.needDestColumns();
		var _g = 1;
		var _g1 = this.patch.get_width();
		while(_g < _g1) {
			var idx_patch = _g++;
			var change = new coopy_ColumnChange();
			var idx_src = this.patchInSourceCol.h.hasOwnProperty(idx_patch) ? this.patchInSourceCol.h[idx_patch] : -1;
			var prev_name = null;
			var name = null;
			if(idx_src != -1) {
				prev_name = this.source.getCell(idx_src,0);
			}
			if(this.modifier.h[idx_patch] != "---") {
				if(this.header.h.hasOwnProperty(idx_patch)) {
					name = this.header.h[idx_patch];
				}
			}
			change.prevName = prev_name;
			change.name = name;
			if(this.next_meta != null) {
				if(Object.prototype.hasOwnProperty.call(this.next_meta.h,name)) {
					change.props = this.next_meta.h[name];
				}
			}
			columns.push(change);
		}
		this.meta.alterColumns(columns);
	}
	,__class__: coopy_HighlightPatch
};
var coopy_HighlightPatchUnit = $hx_exports["coopy"]["HighlightPatchUnit"] = function() {
	this.add = false;
	this.rem = false;
	this.update = false;
	this.sourceRow = -1;
	this.sourceRowOffset = 0;
	this.sourcePrevRow = -1;
	this.sourceNextRow = -1;
	this.destRow = -1;
	this.patchRow = -1;
	this.code = "";
};
coopy_HighlightPatchUnit.__name__ = true;
coopy_HighlightPatchUnit.prototype = {
	add: null
	,rem: null
	,update: null
	,code: null
	,sourceRow: null
	,sourceRowOffset: null
	,sourcePrevRow: null
	,sourceNextRow: null
	,destRow: null
	,patchRow: null
	,toString: function() {
		return "(" + this.code + " patch " + this.patchRow + " source " + this.sourcePrevRow + ":" + this.sourceRow + ":" + this.sourceNextRow + "+" + this.sourceRowOffset + " dest " + this.destRow + ")";
	}
	,__class__: coopy_HighlightPatchUnit
};
var coopy_Index = function(flags) {
	this.items = new haxe_ds_StringMap();
	this.cols = [];
	this.keys = [];
	this.top_freq = 0;
	this.height = 0;
	this.hdr = 0;
	this.ignore_whitespace = false;
	this.ignore_case = false;
	if(flags != null) {
		this.ignore_whitespace = flags.ignore_whitespace;
		this.ignore_case = flags.ignore_case;
	}
};
coopy_Index.__name__ = true;
coopy_Index.prototype = {
	items: null
	,keys: null
	,top_freq: null
	,height: null
	,cols: null
	,v: null
	,indexed_table: null
	,hdr: null
	,ignore_whitespace: null
	,ignore_case: null
	,addColumn: function(i) {
		this.cols.push(i);
	}
	,indexTable: function(t,hdr) {
		this.indexed_table = t;
		this.hdr = hdr;
		if(this.keys.length != t.get_height() && t.get_height() > 0) {
			this.keys[t.get_height() - 1] = null;
		}
		var _g = 0;
		var _g1 = t.get_height();
		while(_g < _g1) {
			var i = _g++;
			var key = this.keys[i];
			if(key == null) {
				key = this.toKey(t,i);
				this.keys[i] = key;
			}
			var item = this.items.h[key];
			if(item == null) {
				item = new coopy_IndexItem();
				this.items.h[key] = item;
			}
			if(item.lst == null) {
				item.lst = [];
			}
			item.lst.push(i);
			var ct = item.lst.length;
			if(ct > this.top_freq) {
				this.top_freq = ct;
			}
		}
		this.height = t.get_height();
	}
	,toKey: function(t,i) {
		var wide = i < this.hdr ? "_" : "";
		if(this.v == null) {
			this.v = t.getCellView();
		}
		var _g = 0;
		var _g1 = this.cols.length;
		while(_g < _g1) {
			var k = _g++;
			var d = t.getCell(this.cols[k],i);
			var txt = this.v.toString(d);
			if(this.ignore_whitespace) {
				txt = StringTools.trim(txt);
			}
			if(this.ignore_case) {
				txt = txt.toLowerCase();
			}
			if(k > 0) {
				wide += " // ";
			}
			if(txt == null || txt == "" || txt == "null" || txt == "undefined") {
				continue;
			}
			wide += txt;
		}
		return wide;
	}
	,toKeyByContent: function(row) {
		var wide = row.isPreamble() ? "_" : "";
		var _g = 0;
		var _g1 = this.cols.length;
		while(_g < _g1) {
			var k = _g++;
			var txt = row.getRowString(this.cols[k]);
			if(this.ignore_whitespace) {
				txt = StringTools.trim(txt);
			}
			if(this.ignore_case) {
				txt = txt.toLowerCase();
			}
			if(k > 0) {
				wide += " // ";
			}
			if(txt == null || txt == "" || txt == "null" || txt == "undefined") {
				continue;
			}
			wide += txt;
		}
		return wide;
	}
	,getTable: function() {
		return this.indexed_table;
	}
	,__class__: coopy_Index
};
var coopy_IndexItem = function() {
};
coopy_IndexItem.__name__ = true;
coopy_IndexItem.prototype = {
	lst: null
	,add: function(i) {
		if(this.lst == null) {
			this.lst = [];
		}
		this.lst.push(i);
		return this.lst.length;
	}
	,length: function() {
		return this.lst.length;
	}
	,value: function() {
		return this.lst[0];
	}
	,asList: function() {
		return this.lst;
	}
	,__class__: coopy_IndexItem
};
var coopy_IndexPair = function(flags) {
	this.flags = flags;
	this.ia = new coopy_Index(flags);
	this.ib = new coopy_Index(flags);
	this.quality = 0;
	this.hdr = 0;
};
coopy_IndexPair.__name__ = true;
coopy_IndexPair.prototype = {
	ia: null
	,ib: null
	,hdr: null
	,quality: null
	,flags: null
	,addColumns: function(ca,cb) {
		this.ia.addColumn(ca);
		this.ib.addColumn(cb);
	}
	,indexTables: function(a,b,hdr) {
		this.ia.indexTable(a,hdr);
		this.ib.indexTable(b,hdr);
		this.hdr = hdr;
		var good = 0;
		var h = this.ia.items.h;
		var key_h = h;
		var key_keys = Object.keys(h);
		var key_length = key_keys.length;
		var key_current = 0;
		while(key_current < key_length) {
			var key = key_keys[key_current++];
			var item_a = this.ia.items.h[key];
			var spot_a = item_a.lst.length;
			var item_b = this.ib.items.h[key];
			var spot_b = 0;
			if(item_b != null) {
				spot_b = item_b.lst.length;
			}
			if(spot_a == 1 && spot_b == 1) {
				++good;
			}
		}
		this.quality = good / Math.max(1.0,a.get_height());
	}
	,queryByKey: function(ka) {
		var result = new coopy_CrossMatch();
		result.item_a = this.ia.items.h[ka];
		result.item_b = this.ib.items.h[ka];
		result.spot_a = result.spot_b = 0;
		if(ka != "") {
			if(result.item_a != null) {
				result.spot_a = result.item_a.lst.length;
			}
			if(result.item_b != null) {
				result.spot_b = result.item_b.lst.length;
			}
		}
		return result;
	}
	,queryByContent: function(row) {
		var result = new coopy_CrossMatch();
		var ka = this.ia.toKeyByContent(row);
		return this.queryByKey(ka);
	}
	,queryLocal: function(row) {
		var ka = this.ia.toKey(this.ia.getTable(),row);
		return this.queryByKey(ka);
	}
	,localKey: function(row) {
		return this.ia.toKey(this.ia.getTable(),row);
	}
	,remoteKey: function(row) {
		return this.ib.toKey(this.ib.getTable(),row);
	}
	,getTopFreq: function() {
		if(this.ib.top_freq > this.ia.top_freq) {
			return this.ib.top_freq;
		}
		return this.ia.top_freq;
	}
	,getQuality: function() {
		return this.quality;
	}
	,__class__: coopy_IndexPair
};
var coopy_Meta = function() { };
coopy_Meta.__name__ = true;
coopy_Meta.prototype = {
	alterColumns: null
	,changeRow: null
	,applyFlags: null
	,asTable: null
	,cloneMeta: null
	,useForColumnChanges: null
	,useForRowChanges: null
	,getRowStream: null
	,isNested: null
	,isSql: null
	,getName: null
	,__class__: coopy_Meta
};
var coopy_JsonTable = function(data,name) {
	this.data = data;
	this.columns = Reflect.field(data,"columns");
	this.rows = Reflect.field(data,"rows");
	this.w = this.columns.length;
	this.h = this.rows.length;
	this.idx2col = new haxe_ds_IntMap();
	var _g = 0;
	var _g1 = this.columns.length;
	while(_g < _g1) {
		var idx = _g++;
		var v = this.columns[idx];
		this.idx2col.h[idx] = v;
	}
	this.name = name;
};
coopy_JsonTable.__name__ = true;
coopy_JsonTable.__interfaces__ = [coopy_Meta,coopy_Table];
coopy_JsonTable.prototype = {
	w: null
	,h: null
	,columns: null
	,rows: null
	,data: null
	,idx2col: null
	,name: null
	,getTable: function() {
		return this;
	}
	,get_width: function() {
		return this.w;
	}
	,get_height: function() {
		return this.h + 1;
	}
	,getCell: function(x,y) {
		if(y == 0) {
			return this.idx2col.h[x];
		}
		return Reflect.field(this.rows[y - 1],this.idx2col.h[x]);
	}
	,setCell: function(x,y,c) {
		console.log("coopy/JsonTable.hx:52:","JsonTable is read-only");
	}
	,toString: function() {
		return "";
	}
	,getCellView: function() {
		return new coopy_SimpleView();
	}
	,isResizable: function() {
		return false;
	}
	,resize: function(w,h) {
		return false;
	}
	,clear: function() {
	}
	,insertOrDeleteRows: function(fate,hfate) {
		return false;
	}
	,insertOrDeleteColumns: function(fate,wfate) {
		return false;
	}
	,trimBlank: function() {
		return false;
	}
	,getData: function() {
		return null;
	}
	,clone: function() {
		return null;
	}
	,setMeta: function(meta) {
	}
	,getMeta: function() {
		return this;
	}
	,create: function() {
		return null;
	}
	,alterColumns: function(columns) {
		return false;
	}
	,changeRow: function(rc) {
		return false;
	}
	,applyFlags: function(flags) {
		return false;
	}
	,asTable: function() {
		return null;
	}
	,cloneMeta: function(table) {
		return null;
	}
	,useForColumnChanges: function() {
		return false;
	}
	,useForRowChanges: function() {
		return false;
	}
	,getRowStream: function() {
		return null;
	}
	,isNested: function() {
		return false;
	}
	,isSql: function() {
		return false;
	}
	,getName: function() {
		return this.name;
	}
	,__class__: coopy_JsonTable
};
var coopy_JsonTables = function(json,flags) {
	this.db = json;
	var names = Reflect.field(json,"names");
	var allowed = null;
	var count = names.length;
	if(flags != null && flags.tables != null) {
		allowed = new haxe_ds_StringMap();
		var _g = 0;
		var _g1 = flags.tables;
		while(_g < _g1.length) {
			var name = _g1[_g];
			++_g;
			allowed.h[name] = true;
		}
		count = 0;
		var _g = 0;
		while(_g < names.length) {
			var name = names[_g];
			++_g;
			if(Object.prototype.hasOwnProperty.call(allowed.h,name)) {
				++count;
			}
		}
	}
	this.t = new coopy_SimpleTable(2,count + 1);
	this.t.setCell(0,0,"name");
	this.t.setCell(1,0,"table");
	var v = this.t.getCellView();
	var at = 1;
	var _g = 0;
	while(_g < names.length) {
		var name = names[_g];
		++_g;
		if(allowed != null) {
			if(!Object.prototype.hasOwnProperty.call(allowed.h,name)) {
				continue;
			}
		}
		this.t.setCell(0,at,name);
		var tab = Reflect.field(this.db,"tables");
		tab = Reflect.field(tab,name);
		this.t.setCell(1,at,v.wrapTable(new coopy_JsonTable(tab,name)));
		++at;
	}
};
coopy_JsonTables.__name__ = true;
coopy_JsonTables.__interfaces__ = [coopy_Table];
coopy_JsonTables.prototype = {
	db: null
	,t: null
	,flags: null
	,getCell: function(x,y) {
		return this.t.getCell(x,y);
	}
	,setCell: function(x,y,c) {
	}
	,getCellView: function() {
		return this.t.getCellView();
	}
	,isResizable: function() {
		return false;
	}
	,resize: function(w,h) {
		return false;
	}
	,clear: function() {
	}
	,insertOrDeleteRows: function(fate,hfate) {
		return false;
	}
	,insertOrDeleteColumns: function(fate,wfate) {
		return false;
	}
	,trimBlank: function() {
		return false;
	}
	,get_width: function() {
		return this.t.get_width();
	}
	,get_height: function() {
		return this.t.get_height();
	}
	,getData: function() {
		return null;
	}
	,clone: function() {
		return null;
	}
	,getMeta: function() {
		return new coopy_SimpleMeta(this,true,true);
	}
	,create: function() {
		return null;
	}
	,__class__: coopy_JsonTables
};
var coopy_Merger = $hx_exports["coopy"]["Merger"] = function(parent,local,remote,flags) {
	this.parent = parent;
	this.local = local;
	this.remote = remote;
	this.flags = flags;
};
coopy_Merger.__name__ = true;
coopy_Merger.makeConflictedCell = function(view,pcell,lcell,rcell) {
	return view.toDatum("((( " + view.toString(pcell) + " ))) " + view.toString(lcell) + " /// " + view.toString(rcell));
};
coopy_Merger.prototype = {
	parent: null
	,local: null
	,remote: null
	,flags: null
	,order: null
	,units: null
	,column_order: null
	,column_units: null
	,row_mix_local: null
	,row_mix_remote: null
	,column_mix_local: null
	,column_mix_remote: null
	,conflicts: null
	,conflict_infos: null
	,shuffleDimension: function(dim_units,len,fate,cl,cr) {
		var at = 0;
		var _g = 0;
		while(_g < dim_units.length) {
			var cunit = dim_units[_g];
			++_g;
			if(cunit.p < 0) {
				if(cunit.l < 0) {
					if(cunit.r >= 0) {
						cr.h[cunit.r] = at;
						++at;
					}
				} else {
					cl.h[cunit.l] = at;
					++at;
				}
			} else if(cunit.l >= 0) {
				if(cunit.r >= 0) {
					cl.h[cunit.l] = at;
					++at;
				}
			}
		}
		var _g = 0;
		var _g1 = len;
		while(_g < _g1) {
			var x = _g++;
			var idx = cl.h[x];
			if(idx == null) {
				fate.push(-1);
			} else {
				fate.push(idx);
			}
		}
		return at;
	}
	,shuffleColumns: function() {
		this.column_mix_local = new haxe_ds_IntMap();
		this.column_mix_remote = new haxe_ds_IntMap();
		var fate = [];
		var wfate = this.shuffleDimension(this.column_units,this.local.get_width(),fate,this.column_mix_local,this.column_mix_remote);
		this.local.insertOrDeleteColumns(fate,wfate);
	}
	,shuffleRows: function() {
		this.row_mix_local = new haxe_ds_IntMap();
		this.row_mix_remote = new haxe_ds_IntMap();
		var fate = [];
		var hfate = this.shuffleDimension(this.units,this.local.get_height(),fate,this.row_mix_local,this.row_mix_remote);
		this.local.insertOrDeleteRows(fate,hfate);
	}
	,apply: function() {
		this.conflicts = 0;
		this.conflict_infos = [];
		var ct = coopy_Coopy.compareTables3(this.parent,this.local,this.remote);
		var align = ct.align();
		this.order = align.toOrder();
		this.units = this.order.getList();
		this.column_order = align.meta.toOrder();
		this.column_units = this.column_order.getList();
		var allow_insert = this.flags.allowInsert();
		var allow_delete = this.flags.allowDelete();
		var allow_update = this.flags.allowUpdate();
		var view = this.parent.getCellView();
		var _g = 0;
		var _g1 = this.units;
		while(_g < _g1.length) {
			var row = _g1[_g];
			++_g;
			if(row.l >= 0 && row.r >= 0 && row.p >= 0) {
				var _g2 = 0;
				var _g3 = this.column_units;
				while(_g2 < _g3.length) {
					var col = _g3[_g2];
					++_g2;
					if(col.l >= 0 && col.r >= 0 && col.p >= 0) {
						var pcell = this.parent.getCell(col.p,row.p);
						var rcell = this.remote.getCell(col.r,row.r);
						if(!view.equals(pcell,rcell)) {
							var lcell = this.local.getCell(col.l,row.l);
							if(view.equals(pcell,lcell)) {
								this.local.setCell(col.l,row.l,rcell);
							} else if(!view.equals(rcell,lcell)) {
								this.local.setCell(col.l,row.l,coopy_Merger.makeConflictedCell(view,pcell,lcell,rcell));
								this.conflicts++;
								this.addConflictInfo(row.l,col.l,view,pcell,lcell,rcell);
							}
						}
					}
				}
			}
		}
		this.shuffleColumns();
		this.shuffleRows();
		var x = this.column_mix_remote.keys();
		while(x.hasNext()) {
			var x1 = x.next();
			var x2 = this.column_mix_remote.h[x1];
			var _g = 0;
			var _g1 = this.units;
			while(_g < _g1.length) {
				var unit = _g1[_g];
				++_g;
				if(unit.l >= 0 && unit.r >= 0) {
					this.local.setCell(x2,this.row_mix_local.h[unit.l],this.remote.getCell(x1,unit.r));
				} else if(unit.p < 0 && unit.r >= 0) {
					this.local.setCell(x2,this.row_mix_remote.h[unit.r],this.remote.getCell(x1,unit.r));
				}
			}
		}
		var y = this.row_mix_remote.keys();
		while(y.hasNext()) {
			var y1 = y.next();
			var y2 = this.row_mix_remote.h[y1];
			var _g = 0;
			var _g1 = this.column_units;
			while(_g < _g1.length) {
				var unit = _g1[_g];
				++_g;
				if(unit.l >= 0 && unit.r >= 0) {
					this.local.setCell(this.column_mix_local.h[unit.l],y2,this.remote.getCell(unit.r,y1));
				}
			}
		}
		return this.conflicts;
	}
	,getConflictInfos: function() {
		return this.conflict_infos;
	}
	,addConflictInfo: function(row,col,view,pcell,lcell,rcell) {
		this.conflict_infos.push(new coopy_ConflictInfo(row,col,view.toString(pcell),view.toString(lcell),view.toString(rcell)));
	}
	,__class__: coopy_Merger
};
var coopy_Mover = $hx_exports["coopy"]["Mover"] = function() { };
coopy_Mover.__name__ = true;
coopy_Mover.moveUnits = function(units) {
	var isrc = [];
	var idest = [];
	var len = units.length;
	var ltop = -1;
	var rtop = -1;
	var in_src_h = { };
	var in_dest_h = { };
	var _g = 0;
	var _g1 = len;
	while(_g < _g1) {
		var i = _g++;
		var unit = units[i];
		if(unit.l >= 0 && unit.r >= 0) {
			if(ltop < unit.l) {
				ltop = unit.l;
			}
			if(rtop < unit.r) {
				rtop = unit.r;
			}
			in_src_h[unit.l] = i;
			in_dest_h[unit.r] = i;
		}
	}
	var v;
	var _g = 0;
	var _g1 = ltop + 1;
	while(_g < _g1) {
		var i = _g++;
		v = in_src_h[i];
		if(v != null) {
			isrc.push(v);
		}
	}
	var _g = 0;
	var _g1 = rtop + 1;
	while(_g < _g1) {
		var i = _g++;
		v = in_dest_h[i];
		if(v != null) {
			idest.push(v);
		}
	}
	return coopy_Mover.moveWithoutExtras(isrc,idest);
};
coopy_Mover.move = function(isrc,idest) {
	var len = isrc.length;
	var len2 = idest.length;
	var in_src_h = { };
	var in_dest_h = { };
	var _g = 0;
	var _g1 = len;
	while(_g < _g1) {
		var i = _g++;
		in_src_h[isrc[i]] = i;
	}
	var _g = 0;
	var _g1 = len2;
	while(_g < _g1) {
		var i = _g++;
		in_dest_h[idest[i]] = i;
	}
	var src = [];
	var dest = [];
	var v;
	var _g = 0;
	var _g1 = len;
	while(_g < _g1) {
		var i = _g++;
		v = isrc[i];
		if(in_dest_h.hasOwnProperty(v)) {
			src.push(v);
		}
	}
	var _g = 0;
	var _g1 = len2;
	while(_g < _g1) {
		var i = _g++;
		v = idest[i];
		if(in_src_h.hasOwnProperty(v)) {
			dest.push(v);
		}
	}
	return coopy_Mover.moveWithoutExtras(src,dest);
};
coopy_Mover.moveWithoutExtras = function(src,dest) {
	if(src.length != dest.length) {
		return null;
	}
	if(src.length <= 1) {
		return [];
	}
	var len = src.length;
	var in_src_h = { };
	var blk_len = new haxe_ds_IntMap();
	var blk_src_loc_h = { };
	var blk_dest_loc_h = { };
	var _g = 0;
	var _g1 = len;
	while(_g < _g1) {
		var i = _g++;
		in_src_h[src[i]] = i;
	}
	var ct = 0;
	var in_cursor = -2;
	var out_cursor = 0;
	var next;
	var blk = -1;
	var v;
	while(out_cursor < len) {
		v = dest[out_cursor];
		next = in_src_h[v];
		if(next != in_cursor + 1) {
			blk = v;
			ct = 1;
			blk_src_loc_h[blk] = next;
			blk_dest_loc_h[blk] = out_cursor;
		} else {
			++ct;
		}
		blk_len.h[blk] = ct;
		in_cursor = next;
		++out_cursor;
	}
	var blks = [];
	var k = blk_len.keys();
	while(k.hasNext()) {
		var k1 = k.next();
		blks.push(k1);
	}
	blks.sort(function(a,b) {
		var diff = blk_len.h[b] - blk_len.h[a];
		if(diff == 0) {
			diff = a - b;
		}
		return diff;
	});
	var moved = [];
	while(blks.length > 0) {
		var blk = blks.shift();
		var blen = blks.length;
		var ref_src_loc = blk_src_loc_h[blk];
		var ref_dest_loc = blk_dest_loc_h[blk];
		var i = blen - 1;
		while(i >= 0) {
			var blki = blks[i];
			var blki_src_loc = blk_src_loc_h[blki];
			var to_left_src = blki_src_loc < ref_src_loc;
			var to_left_dest = blk_dest_loc_h[blki] < ref_dest_loc;
			if(to_left_src != to_left_dest) {
				var ct = blk_len.h[blki];
				var _g = 0;
				var _g1 = ct;
				while(_g < _g1) {
					var j = _g++;
					moved.push(src[blki_src_loc]);
					++blki_src_loc;
				}
				blks.splice(i,1);
			}
			--i;
		}
	}
	return moved;
};
var coopy_Ndjson = $hx_exports["coopy"]["Ndjson"] = function(tab) {
	this.tab = tab;
	this.view = tab.getCellView();
	this.header_row = 0;
};
coopy_Ndjson.__name__ = true;
coopy_Ndjson.prototype = {
	tab: null
	,view: null
	,columns: null
	,header_row: null
	,renderRow: function(r) {
		var row = new haxe_ds_StringMap();
		var _g = 0;
		var _g1 = this.tab.get_width();
		while(_g < _g1) {
			var c = _g++;
			var key = this.view.toString(this.tab.getCell(c,this.header_row));
			if(c == 0 && this.header_row == 1) {
				key = "@:@";
			}
			var value = this.tab.getCell(c,r);
			row.h[key] = value;
		}
		return haxe_format_JsonPrinter.print(row,null,null);
	}
	,render: function() {
		var txt = "";
		var offset = 0;
		if(this.tab.get_height() == 0) {
			return txt;
		}
		if(this.tab.get_width() == 0) {
			return txt;
		}
		if(this.tab.getCell(0,0) == "@:@") {
			offset = 1;
		}
		this.header_row = offset;
		var _g = this.header_row + 1;
		var _g1 = this.tab.get_height();
		while(_g < _g1) {
			var r = _g++;
			txt += this.renderRow(r);
			txt += "\n";
		}
		return txt;
	}
	,addRow: function(r,txt) {
		var json = new haxe_format_JsonParser(txt).doParse();
		if(this.columns == null) {
			this.columns = new haxe_ds_StringMap();
		}
		var w = this.tab.get_width();
		var h = this.tab.get_height();
		var resize = false;
		var _g = 0;
		var _g1 = Reflect.fields(json);
		while(_g < _g1.length) {
			var name = _g1[_g];
			++_g;
			if(!Object.prototype.hasOwnProperty.call(this.columns.h,name)) {
				this.columns.h[name] = w;
				++w;
				resize = true;
			}
		}
		if(r >= h) {
			h = r + 1;
			resize = true;
		}
		if(resize) {
			this.tab.resize(w,h);
		}
		var _g = 0;
		var _g1 = Reflect.fields(json);
		while(_g < _g1.length) {
			var name = _g1[_g];
			++_g;
			var v = Reflect.field(json,name);
			var c = this.columns.h[name];
			this.tab.setCell(c,r,v);
		}
	}
	,addHeaderRow: function(r) {
		var h = this.columns.h;
		var n_h = h;
		var n_keys = Object.keys(h);
		var n_length = n_keys.length;
		var n_current = 0;
		while(n_current < n_length) {
			var n = n_keys[n_current++];
			this.tab.setCell(this.columns.h[n],r,this.view.toDatum(n));
		}
	}
	,parse: function(txt) {
		this.columns = null;
		var rows = txt.split("\n");
		var h = rows.length;
		if(h == 0) {
			this.tab.clear();
			return;
		}
		if(rows[h - 1] == "") {
			--h;
		}
		var _g = 0;
		var _g1 = h;
		while(_g < _g1) {
			var i = _g++;
			var at = h - i - 1;
			this.addRow(at + 1,rows[at]);
		}
		this.addHeaderRow(0);
	}
	,__class__: coopy_Ndjson
};
var coopy_NestedCellBuilder = function() {
};
coopy_NestedCellBuilder.__name__ = true;
coopy_NestedCellBuilder.__interfaces__ = [coopy_CellBuilder];
coopy_NestedCellBuilder.prototype = {
	view: null
	,needSeparator: function() {
		return false;
	}
	,setSeparator: function(separator) {
	}
	,setConflictSeparator: function(separator) {
	}
	,setView: function(view) {
		this.view = view;
	}
	,update: function(local,remote) {
		var h = this.view.makeHash();
		this.view.hashSet(h,"before",local);
		this.view.hashSet(h,"after",remote);
		return h;
	}
	,conflict: function(parent,local,remote) {
		var h = this.view.makeHash();
		this.view.hashSet(h,"before",parent);
		this.view.hashSet(h,"ours",local);
		this.view.hashSet(h,"theirs",remote);
		return h;
	}
	,marker: function(label) {
		return this.view.toDatum(label);
	}
	,negToNull: function(x) {
		if(x < 0) {
			return null;
		}
		return x;
	}
	,links: function(unit,row_like) {
		var h = this.view.makeHash();
		if(unit.p >= -1) {
			this.view.hashSet(h,"before",this.negToNull(unit.p));
			this.view.hashSet(h,"ours",this.negToNull(unit.l));
			this.view.hashSet(h,"theirs",this.negToNull(unit.r));
			return h;
		}
		this.view.hashSet(h,"before",this.negToNull(unit.l));
		this.view.hashSet(h,"after",this.negToNull(unit.r));
		return h;
	}
	,__class__: coopy_NestedCellBuilder
};
var coopy_Ordering = function() {
	this.order = [];
	this.ignore_parent = false;
};
coopy_Ordering.__name__ = true;
coopy_Ordering.prototype = {
	order: null
	,ignore_parent: null
	,add: function(l,r,p) {
		if(p == null) {
			p = -2;
		}
		if(this.ignore_parent) {
			p = -2;
		}
		this.order.push(new coopy_Unit(l,r,p));
	}
	,getList: function() {
		return this.order;
	}
	,setList: function(lst) {
		this.order = lst;
	}
	,toString: function() {
		var txt = "";
		var _g = 0;
		var _g1 = this.order.length;
		while(_g < _g1) {
			var i = _g++;
			if(i > 0) {
				txt += ", ";
			}
			txt += Std.string(this.order[i]);
		}
		return txt;
	}
	,ignoreParent: function() {
		this.ignore_parent = true;
	}
	,__class__: coopy_Ordering
};
var coopy_PropertyChange = function() {
};
coopy_PropertyChange.__name__ = true;
coopy_PropertyChange.prototype = {
	prevName: null
	,name: null
	,val: null
	,__class__: coopy_PropertyChange
};
var coopy_RowChange = $hx_exports["coopy"]["RowChange"] = function() {
};
coopy_RowChange.__name__ = true;
coopy_RowChange.prototype = {
	cond: null
	,val: null
	,conflicting_val: null
	,conflicting_parent_val: null
	,conflicted: null
	,is_key: null
	,action: null
	,showMap: function(m) {
		if(m == null) {
			return "{}";
		}
		var txt = "";
		var h = m.h;
		var k_h = h;
		var k_keys = Object.keys(h);
		var k_length = k_keys.length;
		var k_current = 0;
		while(k_current < k_length) {
			var k = k_keys[k_current++];
			if(txt != "") {
				txt += ", ";
			}
			var v = m.h[k];
			txt += k + "=" + Std.string(v);
		}
		return "{ " + txt + " }";
	}
	,toString: function() {
		return this.action + " " + this.showMap(this.cond) + " : " + this.showMap(this.val);
	}
	,__class__: coopy_RowChange
};
var coopy_RowStream = function() { };
coopy_RowStream.__name__ = true;
coopy_RowStream.prototype = {
	fetchColumns: null
	,fetchRow: null
	,__class__: coopy_RowStream
};
var coopy_SimpleMeta = $hx_exports["coopy"]["SimpleMeta"] = function(t,has_properties,may_be_nested) {
	if(may_be_nested == null) {
		may_be_nested = false;
	}
	if(has_properties == null) {
		has_properties = true;
	}
	this.t = t;
	this.rowChange();
	this.colChange();
	this.has_properties = has_properties;
	this.may_be_nested = may_be_nested;
	this.metadata = null;
	this.keys = null;
	this.row_active = false;
	this.row_change_cache = null;
};
coopy_SimpleMeta.__name__ = true;
coopy_SimpleMeta.__interfaces__ = [coopy_Meta];
coopy_SimpleMeta.prototype = {
	t: null
	,name2row: null
	,name2col: null
	,has_properties: null
	,metadata: null
	,keys: null
	,row_active: null
	,row_change_cache: null
	,may_be_nested: null
	,storeRowChanges: function(changes) {
		this.row_change_cache = changes;
		this.row_active = true;
	}
	,rowChange: function() {
		this.name2row = null;
	}
	,colChange: function() {
		this.name2col = null;
	}
	,col: function(key) {
		if(this.t.get_height() < 1) {
			return -1;
		}
		if(this.name2col == null) {
			this.name2col = new haxe_ds_StringMap();
			var w = this.t.get_width();
			var _g = 0;
			var _g1 = w;
			while(_g < _g1) {
				var c = _g++;
				var this1 = this.name2col;
				var key1 = this.t.getCell(c,0);
				this1.h[key1] = c;
			}
		}
		if(!Object.prototype.hasOwnProperty.call(this.name2col.h,key)) {
			return -1;
		}
		return this.name2col.h[key];
	}
	,row: function(key) {
		if(this.t.get_width() < 1) {
			return -1;
		}
		if(this.name2row == null) {
			this.name2row = new haxe_ds_StringMap();
			var h = this.t.get_height();
			var _g = 1;
			var _g1 = h;
			while(_g < _g1) {
				var r = _g++;
				var this1 = this.name2row;
				var key1 = this.t.getCell(0,r);
				this1.h[key1] = r;
			}
		}
		if(!Object.prototype.hasOwnProperty.call(this.name2row.h,key)) {
			return -1;
		}
		return this.name2row.h[key];
	}
	,alterColumns: function(columns) {
		var target_h = Object.create(null);
		var wfate = 0;
		if(this.has_properties) {
			target_h["@"] = wfate;
			++wfate;
		}
		var _g = 0;
		var _g1 = columns.length;
		while(_g < _g1) {
			var i = _g++;
			var col = columns[i];
			if(col.prevName != null) {
				target_h[col.prevName] = wfate;
			}
			if(col.name != null) {
				++wfate;
			}
		}
		var fate = [];
		var _g = 0;
		var _g1 = this.t.get_width();
		while(_g < _g1) {
			var i = _g++;
			var targeti = -1;
			var name = this.t.getCell(i,0);
			if(Object.prototype.hasOwnProperty.call(target_h,name)) {
				targeti = target_h[name];
			}
			fate.push(targeti);
		}
		this.t.insertOrDeleteColumns(fate,wfate);
		var start = this.has_properties ? 1 : 0;
		var at = start;
		var _g = 0;
		var _g1 = columns.length;
		while(_g < _g1) {
			var i = _g++;
			var col = columns[i];
			if(col.name != null) {
				if(col.name != col.prevName) {
					this.t.setCell(at,0,col.name);
				}
			}
			if(col.name != null) {
				++at;
			}
		}
		if(!this.has_properties) {
			return true;
		}
		this.colChange();
		at = start;
		var _g = 0;
		var _g1 = columns.length;
		while(_g < _g1) {
			var i = _g++;
			var col = columns[i];
			if(col.name != null) {
				var _g2 = 0;
				var _g3 = col.props;
				while(_g2 < _g3.length) {
					var prop = _g3[_g2];
					++_g2;
					this.setCell(col.name,prop.name,prop.val);
				}
			}
			if(col.name != null) {
				++at;
			}
		}
		return true;
	}
	,setCell: function(c,r,val) {
		var ri = this.row(r);
		if(ri == -1) {
			return false;
		}
		var ci = this.col(c);
		if(ci == -1) {
			return false;
		}
		this.t.setCell(ci,ri,val);
		return true;
	}
	,addMetaData: function(column,property,val) {
		if(this.metadata == null) {
			this.metadata = new haxe_ds_StringMap();
			this.keys = new haxe_ds_StringMap();
		}
		if(!Object.prototype.hasOwnProperty.call(this.metadata.h,column)) {
			var this1 = this.metadata;
			var value = new haxe_ds_StringMap();
			this1.h[column] = value;
		}
		var props = this.metadata.h[column];
		props.h[property] = val;
		this.keys.h[property] = true;
	}
	,asTable: function() {
		if(this.has_properties && this.metadata == null) {
			return this.t;
		}
		if(this.metadata == null) {
			return null;
		}
		var w = this.t.get_width();
		var props = [];
		var h = this.keys.h;
		var k_h = h;
		var k_keys = Object.keys(h);
		var k_length = k_keys.length;
		var k_current = 0;
		while(k_current < k_length) {
			var k = k_keys[k_current++];
			props.push(k);
		}
		props.sort(Reflect.compare);
		var mt = new coopy_SimpleTable(w + 1,props.length + 1);
		mt.setCell(0,0,"@");
		var _g = 0;
		var _g1 = w;
		while(_g < _g1) {
			var x = _g++;
			var name = this.t.getCell(x,0);
			mt.setCell(1 + x,0,name);
			if(!Object.prototype.hasOwnProperty.call(this.metadata.h,name)) {
				continue;
			}
			var vals = this.metadata.h[name];
			var _g2 = 0;
			var _g3 = props.length;
			while(_g2 < _g3) {
				var i = _g2++;
				if(Object.prototype.hasOwnProperty.call(vals.h,props[i])) {
					mt.setCell(1 + x,i + 1,vals.h[props[i]]);
				}
			}
		}
		var _g = 0;
		var _g1 = props.length;
		while(_g < _g1) {
			var y = _g++;
			mt.setCell(0,y + 1,props[y]);
		}
		return mt;
	}
	,cloneMeta: function(table) {
		var result = new coopy_SimpleMeta(table);
		if(this.metadata != null) {
			result.keys = new haxe_ds_StringMap();
			var h = this.keys.h;
			var k_h = h;
			var k_keys = Object.keys(h);
			var k_length = k_keys.length;
			var k_current = 0;
			while(k_current < k_length) {
				var k = k_keys[k_current++];
				result.keys.h[k] = true;
			}
			result.metadata = new haxe_ds_StringMap();
			var h = this.metadata.h;
			var k_h = h;
			var k_keys = Object.keys(h);
			var k_length = k_keys.length;
			var k_current = 0;
			while(k_current < k_length) {
				var k = k_keys[k_current++];
				if(!Object.prototype.hasOwnProperty.call(this.metadata.h,k)) {
					continue;
				}
				var vals = this.metadata.h[k];
				var nvals = new haxe_ds_StringMap();
				var h = vals.h;
				var p_h = h;
				var p_keys = Object.keys(h);
				var p_length = p_keys.length;
				var p_current = 0;
				while(p_current < p_length) {
					var p = p_keys[p_current++];
					nvals.h[p] = vals.h[p];
				}
				result.metadata.h[k] = nvals;
			}
		}
		return result;
	}
	,useForColumnChanges: function() {
		return true;
	}
	,useForRowChanges: function() {
		return this.row_active;
	}
	,changeRow: function(rc) {
		this.row_change_cache.push(rc);
		return false;
	}
	,applyFlags: function(flags) {
		return false;
	}
	,getRowStream: function() {
		return new coopy_TableStream(this.t);
	}
	,isNested: function() {
		return this.may_be_nested;
	}
	,isSql: function() {
		return false;
	}
	,getName: function() {
		return null;
	}
	,__class__: coopy_SimpleMeta
};
var coopy_SimpleTable = $hx_exports["coopy"]["SimpleTable"] = function(w,h) {
	this.data = new haxe_ds_IntMap();
	this.w = w;
	this.h = h;
	this.meta = null;
};
coopy_SimpleTable.__name__ = true;
coopy_SimpleTable.__interfaces__ = [coopy_Table];
coopy_SimpleTable.tableToString = function(tab) {
	var meta = tab.getMeta();
	if(meta != null) {
		var stream = meta.getRowStream();
		if(stream != null) {
			var x = "";
			var cols = stream.fetchColumns();
			var _g = 0;
			var _g1 = cols.length;
			while(_g < _g1) {
				var i = _g++;
				if(i > 0) {
					x += ",";
				}
				x += cols[i];
			}
			x += "\n";
			var row = stream.fetchRow();
			while(row != null) {
				var _g = 0;
				var _g1 = cols.length;
				while(_g < _g1) {
					var i = _g++;
					if(i > 0) {
						x += ",";
					}
					x += Std.string(row.h[cols[i]]);
				}
				x += "\n";
				row = stream.fetchRow();
			}
			return x;
		}
	}
	var x = "";
	var _g = 0;
	var _g1 = tab.get_height();
	while(_g < _g1) {
		var i = _g++;
		var _g2 = 0;
		var _g3 = tab.get_width();
		while(_g2 < _g3) {
			var j = _g2++;
			if(j > 0) {
				x += ",";
			}
			x += Std.string(tab.getCell(j,i));
		}
		x += "\n";
	}
	return x;
};
coopy_SimpleTable.tableIsSimilar = function(tab1,tab2) {
	if(tab1.get_height() == -1 || tab2.get_height() == -1) {
		var txt1 = coopy_SimpleTable.tableToString(tab1);
		var txt2 = coopy_SimpleTable.tableToString(tab2);
		return txt1 == txt2;
	}
	if(tab1.get_width() != tab2.get_width()) {
		return false;
	}
	if(tab1.get_height() != tab2.get_height()) {
		return false;
	}
	var v = tab1.getCellView();
	var _g = 0;
	var _g1 = tab1.get_height();
	while(_g < _g1) {
		var i = _g++;
		var _g2 = 0;
		var _g3 = tab1.get_width();
		while(_g2 < _g3) {
			var j = _g2++;
			if(!v.equals(tab1.getCell(j,i),tab2.getCell(j,i))) {
				return false;
			}
		}
	}
	return true;
};
coopy_SimpleTable.prototype = {
	data: null
	,w: null
	,h: null
	,meta: null
	,getTable: function() {
		return this;
	}
	,get_width: function() {
		return this.w;
	}
	,get_height: function() {
		return this.h;
	}
	,getCell: function(x,y) {
		return this.data.h[x + y * this.w];
	}
	,setCell: function(x,y,c) {
		this.data.h[x + y * this.w] = c;
	}
	,toString: function() {
		return coopy_SimpleTable.tableToString(this);
	}
	,getCellView: function() {
		return new coopy_SimpleView();
	}
	,isResizable: function() {
		return true;
	}
	,resize: function(w,h) {
		this.w = w;
		this.h = h;
		return true;
	}
	,clear: function() {
		this.data = new haxe_ds_IntMap();
	}
	,insertOrDeleteRows: function(fate,hfate) {
		var data2 = new haxe_ds_IntMap();
		var _g = 0;
		var _g1 = fate.length;
		while(_g < _g1) {
			var i = _g++;
			var j = fate[i];
			if(j != -1) {
				var _g2 = 0;
				var _g3 = this.w;
				while(_g2 < _g3) {
					var c = _g2++;
					var idx = i * this.w + c;
					if(this.data.h.hasOwnProperty(idx)) {
						data2.h[j * this.w + c] = this.data.h[idx];
					}
				}
			}
		}
		this.h = hfate;
		this.data = data2;
		return true;
	}
	,insertOrDeleteColumns: function(fate,wfate) {
		var data2 = new haxe_ds_IntMap();
		var _g = 0;
		var _g1 = fate.length;
		while(_g < _g1) {
			var i = _g++;
			var j = fate[i];
			if(j != -1) {
				var _g2 = 0;
				var _g3 = this.h;
				while(_g2 < _g3) {
					var r = _g2++;
					var idx = r * this.w + i;
					if(this.data.h.hasOwnProperty(idx)) {
						data2.h[r * wfate + j] = this.data.h[idx];
					}
				}
			}
		}
		this.w = wfate;
		this.data = data2;
		return true;
	}
	,trimBlank: function() {
		if(this.h == 0) {
			return true;
		}
		var h_test = this.h;
		if(h_test >= 3) {
			h_test = 3;
		}
		var view = this.getCellView();
		var space = view.toDatum("");
		var more = true;
		while(more) {
			var _g = 0;
			var _g1 = this.get_width();
			while(_g < _g1) {
				var i = _g++;
				var c = this.getCell(i,this.h - 1);
				if(!(view.equals(c,space) || c == null)) {
					more = false;
					break;
				}
			}
			if(more) {
				this.h--;
			}
		}
		more = true;
		var nw = this.w;
		while(more) {
			if(this.w == 0) {
				break;
			}
			var _g = 0;
			var _g1 = h_test;
			while(_g < _g1) {
				var i = _g++;
				var c = this.getCell(nw - 1,i);
				if(!(view.equals(c,space) || c == null)) {
					more = false;
					break;
				}
			}
			if(more) {
				--nw;
			}
		}
		if(nw == this.w) {
			return true;
		}
		var data2 = new haxe_ds_IntMap();
		var _g = 0;
		var _g1 = nw;
		while(_g < _g1) {
			var i = _g++;
			var _g2 = 0;
			var _g3 = this.h;
			while(_g2 < _g3) {
				var r = _g2++;
				var idx = r * this.w + i;
				if(this.data.h.hasOwnProperty(idx)) {
					data2.h[r * nw + i] = this.data.h[idx];
				}
			}
		}
		this.w = nw;
		this.data = data2;
		return true;
	}
	,getData: function() {
		return null;
	}
	,clone: function() {
		var result = new coopy_SimpleTable(this.get_width(),this.get_height());
		var _g = 0;
		var _g1 = this.get_height();
		while(_g < _g1) {
			var i = _g++;
			var _g2 = 0;
			var _g3 = this.get_width();
			while(_g2 < _g3) {
				var j = _g2++;
				result.setCell(j,i,this.getCell(j,i));
			}
		}
		if(this.meta != null) {
			result.meta = this.meta.cloneMeta(result);
		}
		return result;
	}
	,create: function() {
		return new coopy_SimpleTable(this.get_width(),this.get_height());
	}
	,setMeta: function(meta) {
		this.meta = meta;
	}
	,getMeta: function() {
		return this.meta;
	}
	,__class__: coopy_SimpleTable
};
var coopy_View = function() { };
coopy_View.__name__ = true;
coopy_View.prototype = {
	toString: null
	,equals: null
	,toDatum: null
	,makeHash: null
	,hashSet: null
	,isHash: null
	,hashExists: null
	,hashGet: null
	,isTable: null
	,getTable: null
	,wrapTable: null
	,__class__: coopy_View
};
var coopy_SimpleView = $hx_exports["coopy"]["SimpleView"] = function() {
};
coopy_SimpleView.__name__ = true;
coopy_SimpleView.__interfaces__ = [coopy_View];
coopy_SimpleView.prototype = {
	toString: function(d) {
		if(d == null) {
			return "";
		}
		return "" + Std.string(d);
	}
	,equals: function(d1,d2) {
		if(d1 == null && d2 == null) {
			return true;
		}
		if(d1 == null || d2 == null) {
			return false;
		}
		return "" + Std.string(d1) == "" + Std.string(d2);
	}
	,toDatum: function(x) {
		return x;
	}
	,makeHash: function() {
		return new haxe_ds_StringMap();
	}
	,hashSet: function(h,str,d) {
		var hh = h;
		hh.h[str] = d;
	}
	,hashExists: function(h,str) {
		var hh = h;
		return Object.prototype.hasOwnProperty.call(hh.h,str);
	}
	,hashGet: function(h,str) {
		var hh = h;
		return hh.h[str];
	}
	,isHash: function(h) {
		return ((h) instanceof haxe_ds_StringMap);
	}
	,isTable: function(t) {
		return js_Boot.__implements(t,coopy_Table);
	}
	,getTable: function(t) {
		return t;
	}
	,wrapTable: function(t) {
		return t;
	}
	,__class__: coopy_SimpleView
};
var coopy_SparseSheet = function() {
	this.h = this.w = 0;
};
coopy_SparseSheet.__name__ = true;
coopy_SparseSheet.prototype = {
	h: null
	,w: null
	,row: null
	,zero: null
	,resize: function(w,h,zero) {
		this.row = new haxe_ds_IntMap();
		this.nonDestructiveResize(w,h,zero);
	}
	,nonDestructiveResize: function(w,h,zero) {
		this.w = w;
		this.h = h;
		this.zero = zero;
	}
	,get: function(x,y) {
		var cursor = this.row.h[y];
		if(cursor == null) {
			return this.zero;
		}
		var val = cursor.h[x];
		if(val == null) {
			return this.zero;
		}
		return val;
	}
	,set: function(x,y,val) {
		var cursor = this.row.h[y];
		if(cursor == null) {
			cursor = new haxe_ds_IntMap();
			this.row.h[y] = cursor;
		}
		cursor.h[x] = val;
	}
	,__class__: coopy_SparseSheet
};
var coopy_SqlColumn = $hx_exports["coopy"]["SqlColumn"] = function() {
	this.name = "";
	this.primary = false;
	this.type_value = null;
	this.type_family = null;
};
coopy_SqlColumn.__name__ = true;
coopy_SqlColumn.prototype = {
	name: null
	,primary: null
	,type_value: null
	,type_family: null
	,setName: function(name) {
		this.name = name;
	}
	,setPrimaryKey: function(primary) {
		this.primary = primary;
	}
	,setType: function(value,family) {
		this.type_value = value;
		this.type_family = family;
	}
	,getName: function() {
		return this.name;
	}
	,isPrimaryKey: function() {
		return this.primary;
	}
	,toString: function() {
		return (this.primary ? "*" : "") + this.name;
	}
	,__class__: coopy_SqlColumn
};
var coopy_SqlCompare = $hx_exports["coopy"]["SqlCompare"] = function(db,local,remote,alt,align,flags) {
	this.db = db;
	this.local = local;
	this.remote = remote;
	this.alt = alt;
	this.align = align;
	this.flags = flags;
	if(this.flags == null) {
		this.flags = new coopy_CompareFlags();
	}
	this.peered = false;
	this.alt_peered = false;
	if(local != null && remote != null) {
		if(this.remote.getDatabase().getNameForAttachment() != null) {
			if(this.remote.getDatabase().getNameForAttachment() != this.local.getDatabase().getNameForAttachment()) {
				local.getDatabase().getHelper().attach(db,"__peer__",this.remote.getDatabase().getNameForAttachment());
				this.peered = true;
			}
		}
	}
	if(this.alt != null && local != null) {
		if(this.alt.getDatabase().getNameForAttachment() != null) {
			if(this.alt.getDatabase().getNameForAttachment() != this.local.getDatabase().getNameForAttachment()) {
				local.getDatabase().getHelper().attach(db,"__alt__",this.alt.getDatabase().getNameForAttachment());
				this.alt_peered = true;
			}
		}
	}
};
coopy_SqlCompare.__name__ = true;
coopy_SqlCompare.prototype = {
	db: null
	,local: null
	,remote: null
	,alt: null
	,at0: null
	,at1: null
	,at2: null
	,diff_ct: null
	,align: null
	,peered: null
	,alt_peered: null
	,needed: null
	,flags: null
	,equalArray: function(a1,a2) {
		if(a1.length != a2.length) {
			return false;
		}
		var _g = 0;
		var _g1 = a1.length;
		while(_g < _g1) {
			var i = _g++;
			if(a1[i] != a2[i]) {
				return false;
			}
		}
		return true;
	}
	,validateSchema: function() {
		var all_cols1 = [];
		var key_cols1 = [];
		var access_error = false;
		var pk_missing = false;
		if(this.local != null) {
			all_cols1 = this.local.getColumnNames();
			key_cols1 = this.local.getPrimaryKey();
			if(all_cols1.length == 0) {
				access_error = true;
			}
			if(this.flags.ids != null) {
				key_cols1 = this.flags.getIdsByRole("local");
			}
			if(key_cols1.length == 0) {
				pk_missing = true;
			}
		}
		var all_cols2 = [];
		var key_cols2 = [];
		if(this.remote != null) {
			all_cols2 = this.remote.getColumnNames();
			key_cols2 = this.remote.getPrimaryKey();
			if(all_cols2.length == 0) {
				access_error = true;
			}
			if(this.flags.ids != null) {
				key_cols2 = this.flags.getIdsByRole("remote");
			}
			if(key_cols2.length == 0) {
				pk_missing = true;
			}
		}
		var all_cols3 = all_cols2;
		var key_cols3 = key_cols2;
		if(this.alt != null) {
			all_cols3 = this.alt.getColumnNames();
			key_cols3 = this.alt.getPrimaryKey();
			if(all_cols3.length == 0) {
				access_error = true;
			}
			if(this.flags.ids != null) {
				key_cols3 = this.flags.getIdsByRole("parent");
			}
			if(key_cols3.length == 0) {
				pk_missing = true;
			}
		}
		if(access_error) {
			throw haxe_Exception.thrown("Error accessing SQL table");
		}
		if(pk_missing) {
			throw haxe_Exception.thrown("sql diff not possible when primary key not available");
		}
		var pk_change = false;
		if(this.local != null && this.remote != null) {
			if(!this.equalArray(key_cols1,key_cols2)) {
				pk_change = true;
			}
		}
		if(this.local != null && this.alt != null) {
			if(!this.equalArray(key_cols1,key_cols3)) {
				pk_change = true;
			}
		}
		if(pk_change) {
			throw haxe_Exception.thrown("sql diff not possible when primary key changes: " + Std.string([key_cols1,key_cols2,key_cols3]));
		}
		return true;
	}
	,denull: function(x) {
		if(x == null) {
			return -1;
		}
		return x;
	}
	,link: function() {
		this.diff_ct++;
		var mode = this.db.get(0);
		var i0 = this.denull(this.db.get(1));
		var i1 = this.denull(this.db.get(2));
		var i2 = this.denull(this.db.get(3));
		if(i0 == -3) {
			i0 = this.at0;
			this.at0++;
		}
		if(i1 == -3) {
			i1 = this.at1;
			this.at1++;
		}
		if(i2 == -3) {
			i2 = this.at2;
			this.at2++;
		}
		var offset = 4;
		if(i0 >= 0) {
			var _g = 0;
			var _g1 = this.local.get_width();
			while(_g < _g1) {
				var x = _g++;
				this.local.setCellCache(x,i0,this.db.get(x + offset));
			}
			offset += this.local.get_width();
		}
		if(i1 >= 0) {
			var _g = 0;
			var _g1 = this.remote.get_width();
			while(_g < _g1) {
				var x = _g++;
				this.remote.setCellCache(x,i1,this.db.get(x + offset));
			}
			offset += this.remote.get_width();
		}
		if(i2 >= 0) {
			var _g = 0;
			var _g1 = this.alt.get_width();
			while(_g < _g1) {
				var x = _g++;
				this.alt.setCellCache(x,i2,this.db.get(x + offset));
			}
		}
		if(mode == 0 || mode == 2) {
			this.align.link(i0,i1);
			this.align.addToOrder(i0,i1);
		}
		if(this.alt != null) {
			if(mode == 1 || mode == 2) {
				this.align.reference.link(i0,i2);
				this.align.reference.addToOrder(i0,i2);
			}
		}
	}
	,linkQuery: function(query,order) {
		if(this.db.begin(query,null,order)) {
			while(this.db.read()) this.link();
			this.db.end();
		}
	}
	,where: function(txt) {
		if(txt == "") {
			return " WHERE 1 = 0";
		}
		return " WHERE " + txt;
	}
	,scanColumns: function(all_cols1,all_cols2,key_cols,present1,present2,align) {
		align.meta = new coopy_Alignment();
		var _g = 0;
		var _g1 = all_cols1.length;
		while(_g < _g1) {
			var i = _g++;
			var key = all_cols1[i];
			if(Object.prototype.hasOwnProperty.call(present2.h,key)) {
				align.meta.link(i,present2.h[key]);
			} else {
				align.meta.link(i,-1);
			}
		}
		var _g = 0;
		var _g1 = all_cols2.length;
		while(_g < _g1) {
			var i = _g++;
			var key = all_cols2[i];
			if(!Object.prototype.hasOwnProperty.call(present1.h,key)) {
				align.meta.link(-1,i);
			}
		}
		align.meta.range(all_cols1.length,all_cols2.length);
		var _g = 0;
		while(_g < key_cols.length) {
			var key = key_cols[_g];
			++_g;
			var unit = new coopy_Unit(present1.h[key],present2.h[key]);
			align.addIndexColumns(unit);
		}
	}
	,apply: function() {
		if(this.db == null) {
			return null;
		}
		if(this.align == null) {
			this.align = new coopy_Alignment();
		}
		if(!this.validateSchema()) {
			return null;
		}
		var rowid_name = this.db.rowid();
		var key_cols = [];
		var data_cols = [];
		var all_cols = [];
		var all_cols1 = [];
		var all_cols2 = [];
		var all_cols3 = [];
		var common = this.local;
		if(this.local != null) {
			key_cols = this.local.getPrimaryKey();
			data_cols = this.local.getAllButPrimaryKey();
			all_cols = this.local.getColumnNames();
			all_cols1 = this.local.getColumnNames();
			if(this.flags.ids != null) {
				key_cols = this.flags.getIdsByRole("local");
				data_cols = [];
				var pks_h = Object.create(null);
				var _g = 0;
				while(_g < key_cols.length) {
					var col = key_cols[_g];
					++_g;
					pks_h[col] = true;
				}
				var _g = 0;
				while(_g < all_cols.length) {
					var col = all_cols[_g];
					++_g;
					if(!Object.prototype.hasOwnProperty.call(pks_h,col)) {
						data_cols.push(col);
					}
				}
			}
		}
		if(this.remote != null) {
			all_cols2 = this.remote.getColumnNames();
			if(common == null) {
				common = this.remote;
			}
		}
		if(this.alt != null) {
			all_cols3 = this.alt.getColumnNames();
			if(common == null) {
				common = this.alt;
			}
		} else {
			all_cols3 = all_cols2;
		}
		var all_common_cols = [];
		var data_common_cols = [];
		var present1 = new haxe_ds_StringMap();
		var present2 = new haxe_ds_StringMap();
		var present3 = new haxe_ds_StringMap();
		var present_primary_h = Object.create(null);
		var has_column_add = false;
		var _g = 0;
		var _g1 = key_cols.length;
		while(_g < _g1) {
			var i = _g++;
			present_primary_h[key_cols[i]] = i;
		}
		var _g = 0;
		var _g1 = all_cols1.length;
		while(_g < _g1) {
			var i = _g++;
			var key = all_cols1[i];
			present1.h[key] = i;
		}
		var _g = 0;
		var _g1 = all_cols2.length;
		while(_g < _g1) {
			var i = _g++;
			var key = all_cols2[i];
			if(!Object.prototype.hasOwnProperty.call(present1.h,key)) {
				has_column_add = true;
			}
			present2.h[key] = i;
		}
		var _g = 0;
		var _g1 = all_cols3.length;
		while(_g < _g1) {
			var i = _g++;
			var key = all_cols3[i];
			if(!Object.prototype.hasOwnProperty.call(present1.h,key)) {
				has_column_add = true;
			}
			present3.h[key] = i;
			if(Object.prototype.hasOwnProperty.call(present1.h,key)) {
				if(Object.prototype.hasOwnProperty.call(present2.h,key)) {
					all_common_cols.push(key);
					if(!Object.prototype.hasOwnProperty.call(present_primary_h,key)) {
						data_common_cols.push(key);
					}
				}
			}
		}
		this.align.meta = new coopy_Alignment();
		var _g = 0;
		var _g1 = all_cols1.length;
		while(_g < _g1) {
			var i = _g++;
			var key = all_cols1[i];
			if(Object.prototype.hasOwnProperty.call(present2.h,key)) {
				this.align.meta.link(i,present2.h[key]);
			} else {
				this.align.meta.link(i,-1);
			}
		}
		var _g = 0;
		var _g1 = all_cols2.length;
		while(_g < _g1) {
			var i = _g++;
			var key = all_cols2[i];
			if(!Object.prototype.hasOwnProperty.call(present1.h,key)) {
				this.align.meta.link(-1,i);
			}
		}
		this.scanColumns(all_cols1,all_cols2,key_cols,present1,present2,this.align);
		this.align.tables(this.local,this.remote);
		if(this.alt != null) {
			this.scanColumns(all_cols1,all_cols3,key_cols,present1,present3,this.align.reference);
			this.align.reference.tables(this.local,this.alt);
		}
		var sql_table1 = "";
		var sql_table2 = "";
		var sql_table3 = "";
		if(this.local != null) {
			sql_table1 = this.local.getQuotedTableName();
		}
		if(this.remote != null) {
			sql_table2 = this.remote.getQuotedTableName();
		}
		if(this.alt != null) {
			sql_table3 = this.alt.getQuotedTableName();
		}
		if(this.peered) {
			sql_table1 = "main." + sql_table1;
			sql_table2 = "__peer__." + sql_table2;
		}
		if(this.alt_peered) {
			sql_table2 = "__alt__." + sql_table3;
		}
		var sql_key_cols = "";
		var _g = 0;
		var _g1 = key_cols.length;
		while(_g < _g1) {
			var i = _g++;
			if(i > 0) {
				sql_key_cols += ",";
			}
			sql_key_cols += common.getQuotedColumnName(key_cols[i]);
		}
		var sql_all_cols = "";
		var _g = 0;
		var _g1 = all_common_cols.length;
		while(_g < _g1) {
			var i = _g++;
			if(i > 0) {
				sql_all_cols += ",";
			}
			sql_all_cols += common.getQuotedColumnName(all_common_cols[i]);
		}
		var sql_all_cols1 = "";
		var _g = 0;
		var _g1 = all_cols1.length;
		while(_g < _g1) {
			var i = _g++;
			if(i > 0) {
				sql_all_cols1 += ",";
			}
			sql_all_cols1 += sql_table1 + "." + this.local.getQuotedColumnName(all_cols1[i]);
		}
		var sql_all_cols2 = "";
		var _g = 0;
		var _g1 = all_cols2.length;
		while(_g < _g1) {
			var i = _g++;
			if(i > 0) {
				sql_all_cols2 += ",";
			}
			sql_all_cols2 += sql_table2 + "." + this.remote.getQuotedColumnName(all_cols2[i]);
		}
		var sql_all_cols3 = "";
		if(this.alt != null) {
			var _g = 0;
			var _g1 = all_cols3.length;
			while(_g < _g1) {
				var i = _g++;
				if(i > 0) {
					sql_all_cols3 += ",";
				}
				sql_all_cols3 += sql_table3 + "." + this.alt.getQuotedColumnName(all_cols3[i]);
			}
		}
		var sql_key_null = "";
		var _g = 0;
		var _g1 = key_cols.length;
		while(_g < _g1) {
			var i = _g++;
			if(i > 0) {
				sql_key_null += " AND ";
			}
			var n = common.getQuotedColumnName(key_cols[i]);
			sql_key_null += sql_table1 + "." + n + " IS NULL";
		}
		var sql_key_null2 = "";
		var _g = 0;
		var _g1 = key_cols.length;
		while(_g < _g1) {
			var i = _g++;
			if(i > 0) {
				sql_key_null2 += " AND ";
			}
			var n = common.getQuotedColumnName(key_cols[i]);
			sql_key_null2 += sql_table2 + "." + n + " IS NULL";
		}
		var sql_key_match2 = "";
		var _g = 0;
		var _g1 = key_cols.length;
		while(_g < _g1) {
			var i = _g++;
			if(i > 0) {
				sql_key_match2 += " AND ";
			}
			var n = common.getQuotedColumnName(key_cols[i]);
			sql_key_match2 += sql_table1 + "." + n + " IS " + sql_table2 + "." + n;
		}
		var sql_key_match3 = "";
		if(this.alt != null) {
			var _g = 0;
			var _g1 = key_cols.length;
			while(_g < _g1) {
				var i = _g++;
				if(i > 0) {
					sql_key_match3 += " AND ";
				}
				var n = common.getQuotedColumnName(key_cols[i]);
				sql_key_match3 += sql_table1 + "." + n + " IS " + sql_table3 + "." + n;
			}
		}
		var sql_data_mismatch = "";
		var _g = 0;
		var _g1 = data_common_cols.length;
		while(_g < _g1) {
			var i = _g++;
			if(i > 0) {
				sql_data_mismatch += " OR ";
			}
			var n = common.getQuotedColumnName(data_common_cols[i]);
			sql_data_mismatch += sql_table1 + "." + n + " IS NOT " + sql_table2 + "." + n;
		}
		var _g = 0;
		var _g1 = all_cols2.length;
		while(_g < _g1) {
			var i = _g++;
			var key = all_cols2[i];
			if(!Object.prototype.hasOwnProperty.call(present1.h,key)) {
				if(sql_data_mismatch != "") {
					sql_data_mismatch += " OR ";
				}
				var n = common.getQuotedColumnName(key);
				sql_data_mismatch += sql_table2 + "." + n + " IS NOT NULL";
			}
		}
		if(this.alt != null) {
			var _g = 0;
			var _g1 = data_common_cols.length;
			while(_g < _g1) {
				var i = _g++;
				if(sql_data_mismatch.length > 0) {
					sql_data_mismatch += " OR ";
				}
				var n = common.getQuotedColumnName(data_common_cols[i]);
				sql_data_mismatch += sql_table1 + "." + n + " IS NOT " + sql_table3 + "." + n;
			}
			var _g = 0;
			var _g1 = all_cols3.length;
			while(_g < _g1) {
				var i = _g++;
				var key = all_cols3[i];
				if(!Object.prototype.hasOwnProperty.call(present1.h,key)) {
					if(sql_data_mismatch != "") {
						sql_data_mismatch += " OR ";
					}
					var n = common.getQuotedColumnName(key);
					sql_data_mismatch += sql_table3 + "." + n + " IS NOT NULL";
				}
			}
		}
		var sql_dbl_cols = "";
		var dbl_cols = [];
		var _g = 0;
		var _g1 = all_cols1.length;
		while(_g < _g1) {
			var i = _g++;
			if(sql_dbl_cols != "") {
				sql_dbl_cols += ",";
			}
			var buf = "__coopy_" + i;
			var n = common.getQuotedColumnName(all_cols1[i]);
			sql_dbl_cols += sql_table1 + "." + n + " AS " + buf;
			dbl_cols.push(buf);
		}
		var _g = 0;
		var _g1 = all_cols2.length;
		while(_g < _g1) {
			var i = _g++;
			if(sql_dbl_cols != "") {
				sql_dbl_cols += ",";
			}
			var buf = "__coopy_" + i + "b";
			var n = common.getQuotedColumnName(all_cols2[i]);
			sql_dbl_cols += sql_table2 + "." + n + " AS " + buf;
			dbl_cols.push(buf);
		}
		if(this.alt != null) {
			var _g = 0;
			var _g1 = all_cols3.length;
			while(_g < _g1) {
				var i = _g++;
				if(sql_dbl_cols != "") {
					sql_dbl_cols += ",";
				}
				var buf = "__coopy_" + i + "c";
				var n = common.getQuotedColumnName(all_cols3[i]);
				sql_dbl_cols += sql_table3 + "." + n + " AS " + buf;
				dbl_cols.push(buf);
			}
		}
		var sql_order = "";
		var _g = 0;
		var _g1 = key_cols.length;
		while(_g < _g1) {
			var i = _g++;
			if(i > 0) {
				sql_order += ",";
			}
			var n = common.getQuotedColumnName(key_cols[i]);
			sql_order += n;
		}
		var rowid = "-3";
		var rowid1 = "-3";
		var rowid2 = "-3";
		var rowid3 = "-3";
		if(rowid_name != null) {
			rowid = rowid_name;
			if(this.local != null) {
				rowid1 = sql_table1 + "." + rowid_name;
			}
			if(this.remote != null) {
				rowid2 = sql_table2 + "." + rowid_name;
			}
			if(this.alt != null) {
				rowid3 = sql_table3 + "." + rowid_name;
			}
		}
		this.at0 = 1;
		this.at1 = 1;
		this.at2 = 1;
		this.diff_ct = 0;
		if(this.remote != null) {
			var sql_inserts = "SELECT DISTINCT 0 AS __coopy_code, NULL, " + rowid2 + " AS rowid, NULL, " + sql_all_cols2 + " FROM " + sql_table2;
			if(this.local != null) {
				sql_inserts += " LEFT JOIN " + sql_table1;
				sql_inserts += " ON " + sql_key_match2 + this.where(sql_key_null);
			}
			if(sql_table1 != sql_table2) {
				var sql_inserts_order = ["__coopy_code","NULL","rowid","NULL"].concat(all_cols2);
				this.linkQuery(sql_inserts,sql_inserts_order);
			}
		}
		if(this.alt != null) {
			var sql_inserts = "SELECT DISTINCT 0 AS __coopy_code, NULL, NULL, " + rowid3 + " AS rowid, " + sql_all_cols3 + " FROM " + sql_table3;
			if(this.local != null) {
				sql_inserts += " LEFT JOIN " + sql_table1;
				sql_inserts += " ON " + sql_key_match3 + this.where(sql_key_null);
			}
			if(sql_table1 != sql_table3) {
				var sql_inserts_order = ["__coopy_code","NULL","NULL","rowid"].concat(all_cols3);
				this.linkQuery(sql_inserts,sql_inserts_order);
			}
		}
		if(this.local != null && this.remote != null) {
			var sql_updates = "SELECT DISTINCT 2 AS __coopy_code, " + rowid1 + " AS __coopy_rowid0, " + rowid2 + " AS __coopy_rowid1, ";
			if(this.alt != null) {
				sql_updates += rowid3 + " AS __coopy_rowid2,";
			} else {
				sql_updates += " NULL,";
			}
			sql_updates += sql_dbl_cols + " FROM " + sql_table1;
			if(sql_table1 != sql_table2) {
				sql_updates += " INNER JOIN " + sql_table2 + " ON " + sql_key_match2;
			}
			if(this.alt != null && sql_table1 != sql_table3) {
				sql_updates += " INNER JOIN " + sql_table3 + " ON " + sql_key_match3;
			}
			sql_updates += this.where(sql_data_mismatch);
			var sql_updates_order = ["__coopy_code","__coopy_rowid0","__coopy_rowid1","__coopy_rowid2"].concat(dbl_cols);
			this.linkQuery(sql_updates,sql_updates_order);
		}
		if(this.alt == null) {
			if(this.local != null) {
				var sql_deletes = "SELECT DISTINCT 0 AS __coopy_code, " + rowid1 + " AS rowid, NULL, NULL, " + sql_all_cols1 + " FROM " + sql_table1;
				if(this.remote != null) {
					sql_deletes += " LEFT JOIN " + sql_table2;
					sql_deletes += " ON " + sql_key_match2 + this.where(sql_key_null2);
				}
				if(sql_table1 != sql_table2) {
					var sql_deletes_order = ["__coopy_code","rowid","NULL","NULL"].concat(all_cols1);
					this.linkQuery(sql_deletes,sql_deletes_order);
				}
			}
		}
		if(this.alt != null) {
			var sql_deletes = "SELECT 2 AS __coopy_code, " + rowid1 + " AS __coopy_rowid0, " + rowid2 + " AS __coopy_rowid1, ";
			sql_deletes += rowid3 + " AS __coopy_rowid2, ";
			sql_deletes += sql_dbl_cols;
			sql_deletes += " FROM " + sql_table1;
			if(this.remote != null) {
				sql_deletes += " LEFT OUTER JOIN " + sql_table2 + " ON " + sql_key_match2;
			}
			sql_deletes += " LEFT OUTER JOIN " + sql_table3 + " ON " + sql_key_match3;
			sql_deletes += " WHERE __coopy_rowid1 IS NULL OR __coopy_rowid2 IS NULL";
			var sql_deletes_order = ["__coopy_code","__coopy_rowid0","__coopy_rowid1","__coopy_rowid2"].concat(dbl_cols);
			this.linkQuery(sql_deletes,sql_deletes_order);
		}
		if(this.diff_ct == 0) {
			this.align.markIdentical();
		}
		return this.align;
	}
	,__class__: coopy_SqlCompare
};
var coopy_SqlDatabase = function() { };
coopy_SqlDatabase.__name__ = true;
coopy_SqlDatabase.prototype = {
	getColumns: null
	,getQuotedTableName: null
	,getQuotedColumnName: null
	,begin: null
	,beginRow: null
	,read: null
	,get: null
	,end: null
	,width: null
	,rowid: null
	,getHelper: null
	,getNameForAttachment: null
	,__class__: coopy_SqlDatabase
};
var coopy_SqlHelper = function() { };
coopy_SqlHelper.__name__ = true;
coopy_SqlHelper.prototype = {
	getTableNames: null
	,countRows: null
	,getRowIDs: null
	,insert: null
	,'delete': null
	,update: null
	,attach: null
	,alterColumns: null
	,__class__: coopy_SqlHelper
};
var coopy_SqlTable = $hx_exports["coopy"]["SqlTable"] = function(db,name,helper) {
	this.db = db;
	this.name = name;
	this.helper = helper;
	if(helper == null) {
		this.helper = db.getHelper();
	}
	this.cache = new haxe_ds_IntMap();
	this.h = -1;
	this.id2rid = null;
	this.getColumns();
};
coopy_SqlTable.__name__ = true;
coopy_SqlTable.__interfaces__ = [coopy_RowStream,coopy_Meta,coopy_Table];
coopy_SqlTable.prototype = {
	db: null
	,columns: null
	,name: null
	,quotedTableName: null
	,cache: null
	,columnNames: null
	,h: null
	,helper: null
	,id2rid: null
	,getColumns: function() {
		if(this.columns != null) {
			return;
		}
		if(this.db == null) {
			return;
		}
		this.columns = this.db.getColumns(this.name);
		this.columnNames = [];
		var _g = 0;
		var _g1 = this.columns;
		while(_g < _g1.length) {
			var col = _g1[_g];
			++_g;
			this.columnNames.push(col.getName());
		}
	}
	,getPrimaryKey: function() {
		this.getColumns();
		var result = [];
		var _g = 0;
		var _g1 = this.columns;
		while(_g < _g1.length) {
			var col = _g1[_g];
			++_g;
			if(!col.isPrimaryKey()) {
				continue;
			}
			result.push(col.getName());
		}
		return result;
	}
	,getAllButPrimaryKey: function() {
		this.getColumns();
		var result = [];
		var _g = 0;
		var _g1 = this.columns;
		while(_g < _g1.length) {
			var col = _g1[_g];
			++_g;
			if(col.isPrimaryKey()) {
				continue;
			}
			result.push(col.getName());
		}
		return result;
	}
	,getColumnNames: function() {
		this.getColumns();
		return this.columnNames;
	}
	,getQuotedTableName: function() {
		if(this.quotedTableName != null) {
			return this.quotedTableName;
		}
		this.quotedTableName = this.db.getQuotedTableName(this.name);
		return this.quotedTableName;
	}
	,getQuotedColumnName: function(name) {
		return this.db.getQuotedColumnName(name);
	}
	,getCell: function(x,y) {
		if(this.h >= 0) {
			--y;
			if(y >= 0) {
				y = this.id2rid[y];
			}
		} else if(y == 0) {
			y = -1;
		}
		if(y < 0) {
			this.getColumns();
			return this.columns[x].name;
		}
		var row = this.cache.h[y];
		if(row == null) {
			row = new haxe_ds_IntMap();
			this.getColumns();
			this.db.beginRow(this.name,y,this.columnNames);
			while(this.db.read()) {
				var _g = 0;
				var _g1 = this.get_width();
				while(_g < _g1) {
					var i = _g++;
					var v = this.db.get(i);
					row.h[i] = v;
				}
			}
			this.db.end();
			this.cache.h[y] = row;
		}
		return this.cache.h[y].h[x];
	}
	,setCellCache: function(x,y,c) {
		var row = this.cache.h[y];
		if(row == null) {
			row = new haxe_ds_IntMap();
			this.getColumns();
			this.cache.h[y] = row;
		}
		var v = c;
		row.h[x] = v;
	}
	,setCell: function(x,y,c) {
		console.log("coopy/SqlTable.hx:115:","SqlTable cannot set cells yet");
	}
	,getCellView: function() {
		return new coopy_SimpleView();
	}
	,isResizable: function() {
		return false;
	}
	,resize: function(w,h) {
		return false;
	}
	,clear: function() {
	}
	,insertOrDeleteRows: function(fate,hfate) {
		return false;
	}
	,insertOrDeleteColumns: function(fate,wfate) {
		return false;
	}
	,trimBlank: function() {
		return false;
	}
	,get_width: function() {
		this.getColumns();
		return this.columns.length;
	}
	,get_height: function() {
		if(this.h >= 0) {
			return this.h;
		}
		return -1;
	}
	,getData: function() {
		return null;
	}
	,clone: function() {
		return null;
	}
	,create: function() {
		return null;
	}
	,getMeta: function() {
		return this;
	}
	,alterColumns: function(columns) {
		var result = this.helper.alterColumns(this.db,this.name,columns);
		this.columns = null;
		return result;
	}
	,changeRow: function(rc) {
		if(this.helper == null) {
			console.log("coopy/SqlTable.hx:183:","No sql helper");
			return false;
		}
		if(rc.action == "+++") {
			return this.helper.insert(this.db,this.name,rc.val);
		} else if(rc.action == "---") {
			return this.helper.delete(this.db,this.name,rc.cond);
		} else if(rc.action == "->") {
			return this.helper.update(this.db,this.name,rc.cond,rc.val);
		}
		return false;
	}
	,asTable: function() {
		var pct = 3;
		this.getColumns();
		var w = this.columnNames.length;
		var mt = new coopy_SimpleTable(w + 1,pct);
		mt.setCell(0,0,"@");
		mt.setCell(0,1,"type");
		mt.setCell(0,2,"key");
		var _g = 0;
		var _g1 = w;
		while(_g < _g1) {
			var x = _g++;
			var i = x + 1;
			mt.setCell(i,0,this.columnNames[x]);
			mt.setCell(i,1,this.columns[x].type_value);
			mt.setCell(i,2,this.columns[x].primary ? "primary" : "");
		}
		return mt;
	}
	,useForColumnChanges: function() {
		return true;
	}
	,useForRowChanges: function() {
		return true;
	}
	,cloneMeta: function(table) {
		return null;
	}
	,applyFlags: function(flags) {
		return false;
	}
	,getDatabase: function() {
		return this.db;
	}
	,getRowStream: function() {
		this.getColumns();
		this.db.begin("SELECT * FROM " + this.getQuotedTableName() + " ORDER BY ?",[this.db.rowid()],this.columnNames);
		return this;
	}
	,isNested: function() {
		return false;
	}
	,isSql: function() {
		return true;
	}
	,fetchRow: function() {
		if(this.db.read()) {
			var row = new haxe_ds_StringMap();
			var _g = 0;
			var _g1 = this.columnNames.length;
			while(_g < _g1) {
				var i = _g++;
				var k = this.columnNames[i];
				var v = this.db.get(i);
				row.h[k] = v;
			}
			return row;
		}
		this.db.end();
		return null;
	}
	,fetchColumns: function() {
		this.getColumns();
		return this.columnNames;
	}
	,getName: function() {
		return this.name.toString();
	}
	,__class__: coopy_SqlTable
};
var coopy_SqlTableName = $hx_exports["coopy"]["SqlTableName"] = function(name,prefix) {
	if(prefix == null) {
		prefix = "";
	}
	if(name == null) {
		name = "";
	}
	this.name = name;
	this.prefix = prefix;
};
coopy_SqlTableName.__name__ = true;
coopy_SqlTableName.prototype = {
	name: null
	,prefix: null
	,toString: function() {
		if(this.prefix == "") {
			return this.name;
		}
		return this.prefix + "." + this.name;
	}
	,__class__: coopy_SqlTableName
};
var coopy_SqlTables = $hx_exports["coopy"]["SqlTables"] = function(db,flags,role) {
	this.db = db;
	var helper = this.db.getHelper();
	var names = helper.getTableNames(db);
	var allowed = null;
	var count = names.length;
	if(flags.tables != null) {
		allowed = new haxe_ds_StringMap();
		var _g = 0;
		var _g1 = flags.tables;
		while(_g < _g1.length) {
			var name = _g1[_g];
			++_g;
			var key = flags.getNameByRole(name,role);
			var value = flags.getCanonicalName(name);
			allowed.h[key] = value;
		}
		count = 0;
		var _g = 0;
		while(_g < names.length) {
			var name = names[_g];
			++_g;
			if(Object.prototype.hasOwnProperty.call(allowed.h,name)) {
				++count;
			}
		}
	}
	this.t = new coopy_SimpleTable(2,count + 1);
	this.t.setCell(0,0,"name");
	this.t.setCell(1,0,"table");
	var v = this.t.getCellView();
	var at = 1;
	var _g = 0;
	while(_g < names.length) {
		var name = names[_g];
		++_g;
		var cname = name;
		if(allowed != null) {
			if(!Object.prototype.hasOwnProperty.call(allowed.h,name)) {
				continue;
			}
			cname = allowed.h[name];
		}
		this.t.setCell(0,at,cname);
		this.t.setCell(1,at,v.wrapTable(new coopy_SqlTable(db,new coopy_SqlTableName(name))));
		++at;
	}
};
coopy_SqlTables.__name__ = true;
coopy_SqlTables.__interfaces__ = [coopy_Table];
coopy_SqlTables.prototype = {
	db: null
	,t: null
	,flags: null
	,getCell: function(x,y) {
		return this.t.getCell(x,y);
	}
	,setCell: function(x,y,c) {
	}
	,getCellView: function() {
		return this.t.getCellView();
	}
	,isResizable: function() {
		return false;
	}
	,resize: function(w,h) {
		return false;
	}
	,clear: function() {
	}
	,insertOrDeleteRows: function(fate,hfate) {
		return false;
	}
	,insertOrDeleteColumns: function(fate,wfate) {
		return false;
	}
	,trimBlank: function() {
		return false;
	}
	,get_width: function() {
		return this.t.get_width();
	}
	,get_height: function() {
		return this.t.get_height();
	}
	,getData: function() {
		return null;
	}
	,clone: function() {
		return null;
	}
	,create: function() {
		return null;
	}
	,getMeta: function() {
		return new coopy_SimpleMeta(this,true,true);
	}
	,__class__: coopy_SqlTables
};
var coopy_SqliteHelper = $hx_exports["coopy"]["SqliteHelper"] = function() {
};
coopy_SqliteHelper.__name__ = true;
coopy_SqliteHelper.__interfaces__ = [coopy_SqlHelper];
coopy_SqliteHelper.prototype = {
	getTableNames: function(db) {
		var q = "SELECT name FROM sqlite_master WHERE type='table' ORDER BY name";
		if(!db.begin(q,null,["name"])) {
			return null;
		}
		var names = [];
		while(db.read()) names.push(db.get(0));
		db.end();
		return names;
	}
	,countRows: function(db,name) {
		var q = "SELECT COUNT(*) AS ct FROM " + db.getQuotedTableName(name);
		if(!db.begin(q,null,["ct"])) {
			return -1;
		}
		var ct = -1;
		while(db.read()) ct = db.get(0);
		db.end();
		return ct;
	}
	,getRowIDs: function(db,name) {
		var result = [];
		var q = "SELECT ROWID AS r FROM " + db.getQuotedTableName(name) + " ORDER BY ROWID";
		if(!db.begin(q,null,["r"])) {
			return null;
		}
		while(db.read()) {
			var c = db.get(0);
			result.push(c);
		}
		db.end();
		return result;
	}
	,update: function(db,name,conds,vals) {
		var q = "UPDATE " + db.getQuotedTableName(name) + " SET ";
		var lst = [];
		var h = vals.h;
		var k_h = h;
		var k_keys = Object.keys(h);
		var k_length = k_keys.length;
		var k_current = 0;
		while(k_current < k_length) {
			var k = k_keys[k_current++];
			if(lst.length > 0) {
				q += ", ";
			}
			q += db.getQuotedColumnName(k);
			q += " = ?";
			lst.push(vals.h[k]);
		}
		var val_len = lst.length;
		q += " WHERE ";
		var h = conds.h;
		var k_h = h;
		var k_keys = Object.keys(h);
		var k_length = k_keys.length;
		var k_current = 0;
		while(k_current < k_length) {
			var k = k_keys[k_current++];
			if(lst.length > val_len) {
				q += " and ";
			}
			q += db.getQuotedColumnName(k);
			q += " IS ?";
			lst.push(conds.h[k]);
		}
		if(!db.begin(q,lst,[])) {
			console.log("coopy/SqliteHelper.hx:71:","Problem with database update");
			return false;
		}
		db.end();
		return true;
	}
	,'delete': function(db,name,conds) {
		var q = "DELETE FROM " + db.getQuotedTableName(name) + " WHERE ";
		var lst = [];
		var h = conds.h;
		var k_h = h;
		var k_keys = Object.keys(h);
		var k_length = k_keys.length;
		var k_current = 0;
		while(k_current < k_length) {
			var k = k_keys[k_current++];
			if(lst.length > 0) {
				q += " and ";
			}
			q += db.getQuotedColumnName(k);
			q += " = ?";
			lst.push(conds.h[k]);
		}
		if(!db.begin(q,lst,[])) {
			console.log("coopy/SqliteHelper.hx:90:","Problem with database delete");
			return false;
		}
		db.end();
		return true;
	}
	,insert: function(db,name,vals) {
		var q = "INSERT INTO " + db.getQuotedTableName(name) + " (";
		var lst = [];
		var h = vals.h;
		var k_h = h;
		var k_keys = Object.keys(h);
		var k_length = k_keys.length;
		var k_current = 0;
		while(k_current < k_length) {
			var k = k_keys[k_current++];
			if(lst.length > 0) {
				q += ",";
			}
			q += db.getQuotedColumnName(k);
			lst.push(vals.h[k]);
		}
		q += ") VALUES(";
		var need_comma = false;
		var h = vals.h;
		var k_h = h;
		var k_keys = Object.keys(h);
		var k_length = k_keys.length;
		var k_current = 0;
		while(k_current < k_length) {
			var k = k_keys[k_current++];
			if(need_comma) {
				q += ",";
			}
			q += "?";
			need_comma = true;
		}
		q += ")";
		if(!db.begin(q,lst,[])) {
			console.log("coopy/SqliteHelper.hx:118:","Problem with database insert");
			return false;
		}
		db.end();
		return true;
	}
	,attach: function(db,tag,resource_name) {
		var tag_present = false;
		var tag_correct = false;
		var result = [];
		var q = "PRAGMA database_list";
		if(!db.begin(q,null,["seq","name","file"])) {
			return false;
		}
		while(db.read()) {
			var name = db.get(1);
			if(name == tag) {
				tag_present = true;
				var file = db.get(2);
				if(file == resource_name) {
					tag_correct = true;
				}
			}
		}
		db.end();
		if(tag_present) {
			if(tag_correct) {
				return true;
			}
			if(!db.begin("DETACH `" + tag + "`",null,[])) {
				console.log("coopy/SqliteHelper.hx:147:","Failed to detach " + tag);
				return false;
			}
			db.end();
		}
		if(!db.begin("ATTACH ? AS `" + tag + "`",[resource_name],[])) {
			console.log("coopy/SqliteHelper.hx:154:","Failed to attach " + resource_name + " as " + tag);
			return false;
		}
		db.end();
		return true;
	}
	,columnListSql: function(x) {
		return x.join(",");
	}
	,fetchSchema: function(db,name) {
		var tname = db.getQuotedTableName(name);
		var query = "select sql from sqlite_master where name = " + tname;
		if(!db.begin(query,null,["sql"])) {
			console.log("coopy/SqliteHelper.hx:169:","Cannot find schema for table " + tname);
			return null;
		}
		var sql = "";
		if(db.read()) {
			sql = db.get(0);
		}
		db.end();
		return sql;
	}
	,splitSchema: function(db,name,sql) {
		var preamble = "";
		var parts = [];
		var double_quote = false;
		var single_quote = false;
		var token = "";
		var nesting = 0;
		var _g = 0;
		var _g1 = sql.length;
		while(_g < _g1) {
			var i = _g++;
			var ch = sql.charAt(i);
			if(double_quote || single_quote) {
				if(double_quote) {
					if(ch == "\"") {
						double_quote = false;
					}
				}
				if(single_quote) {
					if(ch == "'") {
						single_quote = false;
					}
				}
				token += ch;
				continue;
			}
			var brk = false;
			if(ch == "(") {
				++nesting;
				if(nesting == 1) {
					brk = true;
				}
			} else if(ch == ")") {
				--nesting;
				if(nesting == 0) {
					brk = true;
				}
			}
			if(ch == ",") {
				brk = true;
				var tmp = nesting == 1;
			}
			if(brk) {
				if(token.charAt(0) == " ") {
					token = HxOverrides.substr(token,1,token.length);
				}
				if(preamble == "") {
					preamble = token;
				} else {
					parts.push(token);
				}
				token = "";
			} else {
				token += ch;
			}
		}
		var cols = db.getColumns(name);
		var name2part = new haxe_ds_StringMap();
		var name2col = new haxe_ds_StringMap();
		var _g = 0;
		var _g1 = cols.length;
		while(_g < _g1) {
			var i = _g++;
			var col = cols[i];
			name2part.h[col.name] = parts[i];
			name2col.h[col.name] = cols[i];
		}
		return { "preamble" : preamble, "parts" : parts, "name2part" : name2part, "columns" : cols, "name2column" : name2col};
	}
	,exec: function(db,query) {
		if(!db.begin(query)) {
			console.log("coopy/SqliteHelper.hx:250:","database problem");
			return false;
		}
		db.end();
		return true;
	}
	,alterColumns: function(db,name,columns) {
		var notBlank = function(x) {
			if(x == null || x == "" || x == "null") {
				return false;
			}
			return true;
		};
		var sql = this.fetchSchema(db,name);
		var schema = this.splitSchema(db,name,sql);
		var parts = schema.parts;
		var nparts = [];
		var new_column_list = [];
		var ins_column_list = [];
		var sel_column_list = [];
		var meta = schema.columns;
		var _g = 0;
		var _g1 = columns.length;
		while(_g < _g1) {
			var i = _g++;
			var c = columns[i];
			if(c.name != null) {
				if(c.prevName != null) {
					sel_column_list.push(c.prevName);
					ins_column_list.push(c.name);
				}
				var orig_type = "";
				var orig_primary = false;
				if(Object.prototype.hasOwnProperty.call(schema.name2column.h,c.name)) {
					var m = schema.name2column.h[c.name];
					orig_type = m.type_value;
					orig_primary = m.primary;
				}
				var next_type = orig_type;
				var next_primary = orig_primary;
				if(c.props != null) {
					var _g2 = 0;
					var _g3 = c.props;
					while(_g2 < _g3.length) {
						var p = _g3[_g2];
						++_g2;
						if(p.name == "type") {
							next_type = p.val;
						}
						if(p.name == "key") {
							next_primary = "" + Std.string(p.val) == "primary";
						}
					}
				}
				var part = "" + c.name;
				if(notBlank(next_type)) {
					part += " " + next_type;
				}
				if(next_primary) {
					part += " PRIMARY KEY";
				}
				nparts.push(part);
				new_column_list.push(c.name);
			}
		}
		if(!this.exec(db,"BEGIN TRANSACTION")) {
			return false;
		}
		var c1 = this.columnListSql(ins_column_list);
		var tname = db.getQuotedTableName(name);
		if(!this.exec(db,"CREATE TEMPORARY TABLE __coopy_backup(" + c1 + ")")) {
			return false;
		}
		if(!this.exec(db,"INSERT INTO __coopy_backup (" + c1 + ") SELECT " + c1 + " FROM " + tname)) {
			return false;
		}
		if(!this.exec(db,"DROP TABLE " + tname)) {
			return false;
		}
		if(!this.exec(db,schema.preamble + "(" + nparts.join(", ") + ")")) {
			return false;
		}
		if(!this.exec(db,"INSERT INTO " + tname + " (" + c1 + ") SELECT " + c1 + " FROM __coopy_backup")) {
			return false;
		}
		if(!this.exec(db,"DROP TABLE __coopy_backup")) {
			return false;
		}
		if(!this.exec(db,"COMMIT")) {
			return false;
		}
		return true;
	}
	,__class__: coopy_SqliteHelper
};
var coopy_TableComparisonState = $hx_exports["coopy"]["TableComparisonState"] = function() {
	this.reset();
};
coopy_TableComparisonState.__name__ = true;
coopy_TableComparisonState.prototype = {
	p: null
	,a: null
	,b: null
	,completed: null
	,run_to_completion: null
	,is_equal: null
	,is_equal_known: null
	,has_same_columns: null
	,has_same_columns_known: null
	,compare_flags: null
	,p_meta: null
	,a_meta: null
	,b_meta: null
	,alignment: null
	,children: null
	,child_order: null
	,reset: function() {
		this.completed = false;
		this.run_to_completion = true;
		this.is_equal_known = false;
		this.is_equal = false;
		this.has_same_columns = false;
		this.has_same_columns_known = false;
		this.compare_flags = null;
		this.alignment = null;
		this.children = null;
		this.child_order = null;
	}
	,getMeta: function() {
		if(this.p != null && this.p_meta == null) {
			this.p_meta = this.p.getMeta();
		}
		if(this.a != null && this.a_meta == null) {
			this.a_meta = this.a.getMeta();
		}
		if(this.b != null && this.b_meta == null) {
			this.b_meta = this.b.getMeta();
		}
	}
	,__class__: coopy_TableComparisonState
};
var coopy_TableDiff = $hx_exports["coopy"]["TableDiff"] = function(align,flags) {
	this.align = align;
	this.flags = flags;
	this.builder = null;
	this.preserve_columns = false;
};
coopy_TableDiff.__name__ = true;
coopy_TableDiff.prototype = {
	align: null
	,flags: null
	,builder: null
	,row_map: null
	,col_map: null
	,has_parent: null
	,a: null
	,b: null
	,p: null
	,rp_header: null
	,ra_header: null
	,rb_header: null
	,is_index_p: null
	,is_index_a: null
	,is_index_b: null
	,order: null
	,row_units: null
	,column_units: null
	,show_rc_numbers: null
	,row_moves: null
	,col_moves: null
	,active_row: null
	,active_column: null
	,allow_insert: null
	,allow_delete: null
	,allow_update: null
	,allow_column: null
	,v: null
	,sep: null
	,conflict_sep: null
	,schema: null
	,have_schema: null
	,top_line_done: null
	,have_addition: null
	,act: null
	,publish: null
	,diff_found: null
	,schema_diff_found: null
	,preserve_columns: null
	,row_deletes: null
	,row_inserts: null
	,row_updates: null
	,row_reorders: null
	,col_deletes: null
	,col_inserts: null
	,col_updates: null
	,col_renames: null
	,col_reorders: null
	,column_units_updated: null
	,nested: null
	,nesting_present: null
	,setCellBuilder: function(builder) {
		this.builder = builder;
	}
	,getSeparator: function(t,t2,root) {
		var sep = root;
		var w = t.get_width();
		var h = t.get_height();
		var view = t.getCellView();
		var _g = 0;
		var _g1 = h;
		while(_g < _g1) {
			var y = _g++;
			var _g2 = 0;
			var _g3 = w;
			while(_g2 < _g3) {
				var x = _g2++;
				var txt = view.toString(t.getCell(x,y));
				if(txt == null) {
					continue;
				}
				while(txt.indexOf(sep) >= 0) sep = "-" + sep;
			}
		}
		if(t2 != null) {
			w = t2.get_width();
			h = t2.get_height();
			var _g = 0;
			var _g1 = h;
			while(_g < _g1) {
				var y = _g++;
				var _g2 = 0;
				var _g3 = w;
				while(_g2 < _g3) {
					var x = _g2++;
					var txt = view.toString(t2.getCell(x,y));
					if(txt == null) {
						continue;
					}
					while(txt.indexOf(sep) >= 0) sep = "-" + sep;
				}
			}
		}
		return sep;
	}
	,isReordered: function(m,ct) {
		var reordered = false;
		var l = -1;
		var r = -1;
		var _g = 0;
		var _g1 = ct;
		while(_g < _g1) {
			var i = _g++;
			var unit = m.h[i];
			if(unit == null) {
				continue;
			}
			if(unit.l >= 0) {
				if(unit.l < l) {
					reordered = true;
					break;
				}
				l = unit.l;
			}
			if(unit.r >= 0) {
				if(unit.r < r) {
					reordered = true;
					break;
				}
				r = unit.r;
			}
		}
		return reordered;
	}
	,spreadContext: function(units,del,active) {
		if(del > 0 && active != null) {
			var mark = -del - 1;
			var skips = 0;
			var _g = 0;
			var _g1 = units.length;
			while(_g < _g1) {
				var i = _g++;
				if(active[i] == -3) {
					++skips;
					continue;
				}
				if(active[i] == 0 || active[i] == 3) {
					if(i - mark <= del + skips) {
						active[i] = 2;
					} else if(i - mark == del + 1 + skips) {
						active[i] = 3;
					}
				} else if(active[i] == 1) {
					mark = i;
					skips = 0;
				}
			}
			mark = units.length + del + 1;
			skips = 0;
			var _g = 0;
			var _g1 = units.length;
			while(_g < _g1) {
				var j = _g++;
				var i = units.length - 1 - j;
				if(active[i] == -3) {
					++skips;
					continue;
				}
				if(active[i] == 0 || active[i] == 3) {
					if(mark - i <= del + skips) {
						active[i] = 2;
					} else if(mark - i == del + 1 + skips) {
						active[i] = 3;
					}
				} else if(active[i] == 1) {
					mark = i;
					skips = 0;
				}
			}
		}
	}
	,setIgnore: function(ignore,idx_ignore,tab,r_header) {
		var v = tab.getCellView();
		if(tab.get_height() >= r_header) {
			var _g = 0;
			var _g1 = tab.get_width();
			while(_g < _g1) {
				var i = _g++;
				var name = v.toString(tab.getCell(i,r_header));
				if(!Object.prototype.hasOwnProperty.call(ignore.h,name)) {
					continue;
				}
				idx_ignore.h[i] = true;
			}
		}
	}
	,countActive: function(active) {
		var ct = 0;
		var showed_dummy = false;
		var _g = 0;
		var _g1 = active.length;
		while(_g < _g1) {
			var i = _g++;
			var publish = active[i] > 0;
			var dummy = active[i] == 3;
			if(dummy && showed_dummy) {
				continue;
			}
			if(!publish) {
				continue;
			}
			showed_dummy = dummy;
			++ct;
		}
		return ct;
	}
	,reset: function() {
		this.has_parent = false;
		this.rp_header = this.ra_header = this.rb_header = 0;
		this.is_index_p = new haxe_ds_IntMap();
		this.is_index_a = new haxe_ds_IntMap();
		this.is_index_b = new haxe_ds_IntMap();
		this.row_map = new haxe_ds_IntMap();
		this.col_map = new haxe_ds_IntMap();
		this.show_rc_numbers = false;
		this.row_moves = null;
		this.col_moves = null;
		this.allow_insert = this.allow_delete = this.allow_update = this.allow_column = true;
		this.sep = "";
		this.conflict_sep = "";
		this.top_line_done = false;
		this.diff_found = false;
		this.schema_diff_found = false;
		this.row_deletes = 0;
		this.row_inserts = 0;
		this.row_updates = 0;
		this.row_reorders = 0;
		this.col_deletes = 0;
		this.col_inserts = 0;
		this.col_updates = 0;
		this.col_renames = 0;
		this.col_reorders = 0;
		this.column_units_updated = new haxe_ds_IntMap();
	}
	,setupTables: function() {
		this.order = this.align.toOrder();
		this.row_units = this.order.getList();
		this.has_parent = this.align.reference != null;
		if(this.has_parent) {
			this.p = this.align.getSource();
			this.a = this.align.reference.getTarget();
			this.b = this.align.getTarget();
			this.rp_header = this.align.reference.meta.getSourceHeader();
			this.ra_header = this.align.reference.meta.getTargetHeader();
			this.rb_header = this.align.meta.getTargetHeader();
			if(this.align.getIndexColumns() != null) {
				var _g = 0;
				var _g1 = this.align.getIndexColumns();
				while(_g < _g1.length) {
					var p2b = _g1[_g];
					++_g;
					if(p2b.l >= 0) {
						this.is_index_p.h[p2b.l] = true;
					}
					if(p2b.r >= 0) {
						this.is_index_b.h[p2b.r] = true;
					}
				}
			}
			if(this.align.reference.getIndexColumns() != null) {
				var _g = 0;
				var _g1 = this.align.reference.getIndexColumns();
				while(_g < _g1.length) {
					var p2a = _g1[_g];
					++_g;
					if(p2a.l >= 0) {
						this.is_index_p.h[p2a.l] = true;
					}
					if(p2a.r >= 0) {
						this.is_index_a.h[p2a.r] = true;
					}
				}
			}
		} else {
			this.a = this.align.getSource();
			this.b = this.align.getTarget();
			this.p = this.a;
			this.ra_header = this.align.meta.getSourceHeader();
			this.rp_header = this.ra_header;
			this.rb_header = this.align.meta.getTargetHeader();
			if(this.align.getIndexColumns() != null) {
				var _g = 0;
				var _g1 = this.align.getIndexColumns();
				while(_g < _g1.length) {
					var a2b = _g1[_g];
					++_g;
					if(a2b.l >= 0) {
						this.is_index_a.h[a2b.l] = true;
					}
					if(a2b.r >= 0) {
						this.is_index_b.h[a2b.r] = true;
					}
				}
			}
		}
		this.allow_insert = this.flags.allowInsert();
		this.allow_delete = this.flags.allowDelete();
		this.allow_update = this.flags.allowUpdate();
		this.allow_column = this.flags.allowColumn();
		var common = this.a;
		if(common == null) {
			common = this.b;
		}
		if(common == null) {
			common = this.p;
		}
		this.v = common.getCellView();
		this.builder.setView(this.v);
		this.nested = false;
		var meta = common.getMeta();
		if(meta != null) {
			this.nested = meta.isNested();
		}
		this.nesting_present = false;
	}
	,scanActivity: function() {
		this.active_row = [];
		this.active_column = null;
		if(!this.flags.show_unchanged) {
			var _g = 0;
			var _g1 = this.row_units.length;
			while(_g < _g1) {
				var i = _g++;
				this.active_row[this.row_units.length - 1 - i] = 0;
			}
		}
		if(!this.flags.show_unchanged_columns) {
			this.active_column = [];
			var _g = 0;
			var _g1 = this.column_units.length;
			while(_g < _g1) {
				var i = _g++;
				var v = 0;
				var unit = this.column_units[i];
				if(unit.l >= 0 && this.is_index_a.h[unit.l]) {
					v = 1;
				}
				if(unit.r >= 0 && this.is_index_b.h[unit.r]) {
					v = 1;
				}
				if(unit.p >= 0 && this.is_index_p.h[unit.p]) {
					v = 1;
				}
				this.active_column[i] = v;
			}
		}
	}
	,setupColumns: function() {
		var column_order = this.align.meta.toOrder();
		this.column_units = column_order.getList();
		var ignore = this.flags.getIgnoredColumns();
		if(ignore != null) {
			var p_ignore = new haxe_ds_IntMap();
			var a_ignore = new haxe_ds_IntMap();
			var b_ignore = new haxe_ds_IntMap();
			this.setIgnore(ignore,p_ignore,this.p,this.rp_header);
			this.setIgnore(ignore,a_ignore,this.a,this.ra_header);
			this.setIgnore(ignore,b_ignore,this.b,this.rb_header);
			var ncolumn_units = [];
			var _g = 0;
			var _g1 = this.column_units.length;
			while(_g < _g1) {
				var j = _g++;
				var cunit = this.column_units[j];
				if(p_ignore.h.hasOwnProperty(cunit.p) || a_ignore.h.hasOwnProperty(cunit.l) || b_ignore.h.hasOwnProperty(cunit.r)) {
					continue;
				}
				ncolumn_units.push(cunit);
			}
			this.column_units = ncolumn_units;
		}
	}
	,setupMoves: function() {
		if(this.flags.ordered) {
			this.row_moves = new haxe_ds_IntMap();
			var moves = coopy_Mover.moveUnits(this.row_units);
			var _g = 0;
			var _g1 = moves.length;
			while(_g < _g1) {
				var i = _g++;
				this.row_moves.h[moves[i]] = i;
			}
			this.col_moves = new haxe_ds_IntMap();
			moves = coopy_Mover.moveUnits(this.column_units);
			var _g = 0;
			var _g1 = moves.length;
			while(_g < _g1) {
				var i = _g++;
				this.col_moves.h[moves[i]] = i;
			}
		}
	}
	,scanSchema: function() {
		this.schema = [];
		this.have_schema = false;
		var _g = 0;
		var _g1 = this.column_units.length;
		while(_g < _g1) {
			var j = _g++;
			var cunit = this.column_units[j];
			var reordered = false;
			if(this.flags.ordered) {
				if(this.col_moves.h.hasOwnProperty(j)) {
					reordered = true;
				}
				if(reordered) {
					this.show_rc_numbers = true;
				}
			}
			var act = "";
			if(cunit.r >= 0 && cunit.lp() == -1) {
				this.have_schema = true;
				act = "+++";
				if(this.active_column != null) {
					if(this.allow_column) {
						this.active_column[j] = 1;
					}
				}
				if(this.allow_column) {
					this.col_inserts++;
				}
			}
			if(cunit.r < 0 && cunit.lp() >= 0) {
				this.have_schema = true;
				act = "---";
				if(this.active_column != null) {
					if(this.allow_column) {
						this.active_column[j] = 1;
					}
				}
				if(this.allow_column) {
					this.col_deletes++;
				}
			}
			if(cunit.r >= 0 && cunit.lp() >= 0) {
				if(this.p.get_height() >= this.rp_header && this.b.get_height() >= this.rb_header) {
					var pp = this.p.getCell(cunit.lp(),this.rp_header);
					var bb = this.b.getCell(cunit.r,this.rb_header);
					if(!this.isEqual(this.v,pp,bb)) {
						this.have_schema = true;
						act = "(";
						act += this.v.toString(pp);
						act += ")";
						if(this.active_column != null) {
							this.active_column[j] = 1;
							this.col_renames++;
						}
					}
				}
			}
			if(reordered) {
				act = ":" + act;
				this.have_schema = true;
				if(this.active_column != null) {
					this.active_column = null;
				}
				this.col_reorders++;
			}
			this.schema.push(act);
		}
	}
	,checkRcNumbers: function(w,h) {
		if(!this.show_rc_numbers) {
			if(this.flags.always_show_order) {
				this.show_rc_numbers = true;
			} else if(this.flags.ordered) {
				this.show_rc_numbers = this.isReordered(this.row_map,h);
				if(!this.show_rc_numbers) {
					this.show_rc_numbers = this.isReordered(this.col_map,w);
				}
			}
		}
	}
	,addRcNumbers: function(output) {
		var admin_w = 1;
		if(this.show_rc_numbers && !this.flags.never_show_order) {
			++admin_w;
			var target = [];
			var _g = 0;
			var _g1 = output.get_width();
			while(_g < _g1) {
				var i = _g++;
				target.push(i + 1);
			}
			output.insertOrDeleteColumns(target,output.get_width() + 1);
			var _g = 0;
			var _g1 = output.get_height();
			while(_g < _g1) {
				var i = _g++;
				var unit = this.row_map.h[i];
				if(unit == null) {
					output.setCell(0,i,"");
					continue;
				}
				output.setCell(0,i,this.builder.links(unit,true));
			}
			target = [];
			var _g = 0;
			var _g1 = output.get_height();
			while(_g < _g1) {
				var i = _g++;
				target.push(i + 1);
			}
			output.insertOrDeleteRows(target,output.get_height() + 1);
			var _g = 1;
			var _g1 = output.get_width();
			while(_g < _g1) {
				var i = _g++;
				var unit = this.col_map.h[i - 1];
				if(unit == null) {
					output.setCell(i,0,"");
					continue;
				}
				output.setCell(i,0,this.builder.links(unit,false));
			}
			output.setCell(0,0,this.builder.marker("@:@"));
		}
		return admin_w;
	}
	,elideColumns: function(output,admin_w) {
		if(this.active_column != null) {
			var all_active = true;
			var _g = 0;
			var _g1 = this.active_column.length;
			while(_g < _g1) {
				var i = _g++;
				if(this.active_column[i] == 0) {
					all_active = false;
					break;
				}
			}
			if(!all_active) {
				var fate = [];
				var _g = 0;
				var _g1 = admin_w;
				while(_g < _g1) {
					var i = _g++;
					fate.push(i);
				}
				var at = admin_w;
				var ct = 0;
				var dots = [];
				var _g = 0;
				var _g1 = this.active_column.length;
				while(_g < _g1) {
					var i = _g++;
					var off = this.active_column[i] == 0;
					if(off) {
						++ct;
					} else {
						ct = 0;
					}
					if(off && ct > 1) {
						fate.push(-1);
					} else {
						if(off) {
							dots.push(at);
						}
						fate.push(at);
						++at;
					}
				}
				output.insertOrDeleteColumns(fate,at);
				var _g = 0;
				while(_g < dots.length) {
					var d = dots[_g];
					++_g;
					var _g1 = 0;
					var _g2 = output.get_height();
					while(_g1 < _g2) {
						var j = _g1++;
						output.setCell(d,j,this.builder.marker("..."));
					}
				}
			}
		}
	}
	,addSchema: function(output) {
		if(this.have_schema) {
			var at = output.get_height();
			output.resize(this.column_units.length + 1,at + 1);
			output.setCell(0,at,this.builder.marker("!"));
			var _g = 0;
			var _g1 = this.column_units.length;
			while(_g < _g1) {
				var j = _g++;
				output.setCell(j + 1,at,this.v.toDatum(this.schema[j]));
			}
			this.schema_diff_found = true;
		}
	}
	,addHeader: function(output) {
		if(this.flags.always_show_header) {
			var at = output.get_height();
			output.resize(this.column_units.length + 1,at + 1);
			output.setCell(0,at,this.builder.marker("@@"));
			var _g = 0;
			var _g1 = this.column_units.length;
			while(_g < _g1) {
				var j = _g++;
				var cunit = this.column_units[j];
				if(cunit.r >= 0) {
					if(this.b.get_height() != 0) {
						output.setCell(j + 1,at,this.b.getCell(cunit.r,this.rb_header));
					}
				} else if(cunit.l >= 0) {
					if(this.a.get_height() != 0) {
						output.setCell(j + 1,at,this.a.getCell(cunit.l,this.ra_header));
					}
				} else if(cunit.lp() >= 0) {
					if(this.p.get_height() != 0) {
						output.setCell(j + 1,at,this.p.getCell(cunit.lp(),this.rp_header));
					}
				}
				this.col_map.h[j + 1] = cunit;
			}
			this.top_line_done = true;
		}
	}
	,checkMeta: function(t,meta) {
		if(meta == null) {
			return false;
		}
		if(t == null) {
			if(meta.get_width() == 1) {
				return meta.get_height() == 1;
			} else {
				return false;
			}
		}
		if(meta.get_width() != t.get_width() + 1) {
			return false;
		}
		if(meta.get_width() == 0 || meta.get_height() == 0) {
			return false;
		}
		return true;
	}
	,getMetaTable: function(t) {
		if(t == null) {
			var result = new coopy_SimpleTable(1,1);
			result.setCell(0,0,"@");
			return result;
		}
		var meta = t.getMeta();
		if(meta == null) {
			return null;
		}
		return meta.asTable();
	}
	,addMeta: function(output) {
		if(this.a == null && this.b == null && this.p == null) {
			return false;
		}
		if(!this.flags.show_meta) {
			return false;
		}
		var a_meta = this.getMetaTable(this.a);
		var b_meta = this.getMetaTable(this.b);
		var p_meta = this.getMetaTable(this.p);
		if(!this.checkMeta(this.a,a_meta)) {
			return false;
		}
		if(!this.checkMeta(this.b,b_meta)) {
			return false;
		}
		if(!this.checkMeta(this.p,p_meta)) {
			return false;
		}
		var meta_diff = new coopy_SimpleTable(0,0);
		var meta_flags = new coopy_CompareFlags();
		meta_flags.addPrimaryKey("@@");
		meta_flags.addPrimaryKey("@");
		meta_flags.unchanged_column_context = 65536;
		meta_flags.unchanged_context = 0;
		var meta_align = coopy_Coopy.compareTables3(a_meta == p_meta ? null : p_meta,a_meta,b_meta,meta_flags).align();
		var td = new coopy_TableDiff(meta_align,meta_flags);
		td.preserve_columns = true;
		td.hilite(meta_diff);
		if(td.hasDifference() || td.hasSchemaDifference()) {
			var h = output.get_height();
			var dh = meta_diff.get_height();
			var offset = td.hasSchemaDifference() ? 2 : 1;
			output.resize(output.get_width(),h + dh - offset);
			var v = meta_diff.getCellView();
			var _g = offset;
			var _g1 = dh;
			while(_g < _g1) {
				var y = _g++;
				var _g2 = 1;
				var _g3 = meta_diff.get_width();
				while(_g2 < _g3) {
					var x = _g2++;
					var c = meta_diff.getCell(x,y);
					if(x == 1) {
						c = "@" + v.toString(c) + "@" + v.toString(meta_diff.getCell(0,y));
					}
					output.setCell(x - 1,h + y - offset,c);
				}
			}
			if(this.active_column != null) {
				if(td.active_column.length == meta_diff.get_width()) {
					var _g = 1;
					var _g1 = meta_diff.get_width();
					while(_g < _g1) {
						var i = _g++;
						if(td.active_column[i] >= 0) {
							this.active_column[i - 1] = 1;
						}
					}
				}
			}
		}
		return false;
	}
	,refineActivity: function() {
		this.spreadContext(this.row_units,this.flags.unchanged_context,this.active_row);
		this.spreadContext(this.column_units,this.flags.unchanged_column_context,this.active_column);
		if(this.active_column != null) {
			var _g = 0;
			var _g1 = this.column_units.length;
			while(_g < _g1) {
				var i = _g++;
				if(this.active_column[i] == 3) {
					this.active_column[i] = 0;
				}
			}
		}
	}
	,normalizeString: function(v,str) {
		if(str == null) {
			return str;
		}
		if(!(this.flags.ignore_whitespace || this.flags.ignore_case)) {
			return str;
		}
		var txt = v.toString(str);
		if(this.flags.ignore_whitespace) {
			txt = StringTools.trim(txt);
		}
		if(this.flags.ignore_case) {
			txt = txt.toLowerCase();
		}
		return txt;
	}
	,isEqual: function(v,aa,bb) {
		if(this.flags.ignore_epsilon > 0) {
			var fa = parseFloat(aa);
			if(!isNaN(fa)) {
				var fb = parseFloat(bb);
				if(!isNaN(fb)) {
					if(Math.abs(fa - fb) < this.flags.ignore_epsilon) {
						return true;
					}
				}
			}
		}
		if(this.flags.ignore_whitespace || this.flags.ignore_case) {
			return this.normalizeString(v,aa) == this.normalizeString(v,bb);
		}
		return v.equals(aa,bb);
	}
	,checkNesting: function(v,have_ll,ll,have_rr,rr,have_pp,pp,x,y) {
		var all_tables = true;
		if(have_ll) {
			all_tables = all_tables && v.isTable(ll);
		}
		if(have_rr) {
			all_tables = all_tables && v.isTable(rr);
		}
		if(have_pp) {
			all_tables = all_tables && v.isTable(pp);
		}
		if(!all_tables) {
			return [ll,rr,pp];
		}
		var ll_table = null;
		var rr_table = null;
		var pp_table = null;
		if(have_ll) {
			ll_table = v.getTable(ll);
		}
		if(have_rr) {
			rr_table = v.getTable(rr);
		}
		if(have_pp) {
			pp_table = v.getTable(pp);
		}
		var compare = false;
		var comp = new coopy_TableComparisonState();
		comp.a = ll_table;
		comp.b = rr_table;
		comp.p = pp_table;
		comp.compare_flags = this.flags;
		comp.getMeta();
		var key = null;
		if(comp.a_meta != null) {
			key = comp.a_meta.getName();
		}
		if(key == null && comp.b_meta != null) {
			key = comp.b_meta.getName();
		}
		if(key == null) {
			key = x + "_" + y;
		}
		if(this.align.comp != null) {
			if(this.align.comp.children == null) {
				this.align.comp.children = new haxe_ds_StringMap();
				this.align.comp.child_order = [];
				compare = true;
			} else {
				compare = !Object.prototype.hasOwnProperty.call(this.align.comp.children.h,key);
			}
		}
		if(compare) {
			this.nesting_present = true;
			this.align.comp.children.h[key] = comp;
			this.align.comp.child_order.push(key);
			var ct = new coopy_CompareTable(comp);
			ct.align();
		} else {
			comp = this.align.comp.children.h[key];
		}
		var ll_out = null;
		var rr_out = null;
		var pp_out = null;
		if(comp.alignment.isMarkedAsIdentical() || have_ll && !have_rr || have_rr && !have_ll) {
			ll_out = "[" + key + "]";
			rr_out = ll_out;
			pp_out = ll_out;
		} else {
			if(ll != null) {
				ll_out = "[a." + key + "]";
			}
			if(rr != null) {
				rr_out = "[b." + key + "]";
			}
			if(pp != null) {
				pp_out = "[p." + key + "]";
			}
		}
		return [ll_out,rr_out,pp_out];
	}
	,scanRow: function(unit,output,at,i,out) {
		var row_update = false;
		var _g = 0;
		var _g1 = this.column_units.length;
		while(_g < _g1) {
			var j = _g++;
			var cunit = this.column_units[j];
			var pp = null;
			var ll = null;
			var rr = null;
			var dd = null;
			var dd_to = null;
			var have_dd_to = false;
			var dd_to_alt = null;
			var have_dd_to_alt = false;
			var have_pp = false;
			var have_ll = false;
			var have_rr = false;
			if(cunit.p >= 0 && unit.p >= 0) {
				pp = this.p.getCell(cunit.p,unit.p);
				have_pp = true;
			}
			if(cunit.l >= 0 && unit.l >= 0) {
				ll = this.a.getCell(cunit.l,unit.l);
				have_ll = true;
			}
			if(cunit.r >= 0 && unit.r >= 0) {
				rr = this.b.getCell(cunit.r,unit.r);
				have_rr = true;
				if((have_pp ? cunit.p : cunit.l) < 0) {
					if(rr != null) {
						if(this.v.toString(rr) != "") {
							if(this.allow_column) {
								this.have_addition = true;
							}
						}
					}
				}
			}
			if(this.nested) {
				var ndiff = this.checkNesting(this.v,have_ll,ll,have_rr,rr,have_pp,pp,i,j);
				ll = ndiff[0];
				rr = ndiff[1];
				pp = ndiff[2];
			}
			if(have_pp) {
				if(!have_rr) {
					dd = pp;
				} else if(this.isEqual(this.v,pp,rr)) {
					dd = ll;
				} else {
					dd = pp;
					dd_to = rr;
					have_dd_to = true;
					if(!this.isEqual(this.v,pp,ll)) {
						if(!this.isEqual(this.v,pp,rr)) {
							dd_to_alt = ll;
							have_dd_to_alt = true;
						}
					}
				}
			} else if(have_ll) {
				if(!have_rr) {
					dd = ll;
				} else if(this.isEqual(this.v,ll,rr)) {
					dd = ll;
				} else {
					dd = ll;
					dd_to = rr;
					have_dd_to = true;
				}
			} else {
				dd = rr;
			}
			var cell = dd;
			if(have_dd_to && (dd != null && this.allow_update || this.allow_column)) {
				if(!row_update) {
					if(out == 0) {
						this.row_updates++;
					}
					row_update = true;
				}
				if(this.active_column != null) {
					this.active_column[j] = 1;
				}
				if(this.sep == "") {
					if(this.builder.needSeparator()) {
						this.sep = this.getSeparator(this.a,this.b,"->");
						this.builder.setSeparator(this.sep);
					} else {
						this.sep = "->";
					}
				}
				var is_conflict = false;
				if(have_dd_to_alt) {
					if(!this.isEqual(this.v,dd_to,dd_to_alt)) {
						is_conflict = true;
					}
				}
				if(!is_conflict) {
					cell = this.builder.update(dd,dd_to);
					if(this.sep.length > this.act.length) {
						this.act = this.sep;
					}
				} else {
					if(this.conflict_sep == "") {
						if(this.builder.needSeparator()) {
							this.conflict_sep = this.getSeparator(this.p,this.a,"!") + this.sep;
							this.builder.setConflictSeparator(this.conflict_sep);
						} else {
							this.conflict_sep = "!->";
						}
					}
					cell = this.builder.conflict(dd,dd_to_alt,dd_to);
					this.act = this.conflict_sep;
				}
				if(!this.column_units_updated.h.hasOwnProperty(j)) {
					this.column_units_updated.h[j] = true;
					this.col_updates++;
				}
			}
			if(this.act == "" && this.have_addition) {
				this.act = "+";
			}
			if(this.act == "+++") {
				if(have_rr) {
					if(this.active_column != null) {
						this.active_column[j] = 1;
					}
				}
			}
			if(this.publish) {
				if(this.active_column == null || this.active_column[j] > 0) {
					output.setCell(j + 1,at,cell);
				}
			}
		}
		if(this.publish) {
			output.setCell(0,at,this.builder.marker(this.act));
			this.row_map.h[at] = unit;
		}
		if(this.act != "") {
			this.diff_found = true;
			if(!this.publish) {
				if(this.active_row != null) {
					this.active_row[i] = 1;
				}
			}
		}
	}
	,hilite: function(output) {
		output = coopy_Coopy.tablify(output);
		return this.hiliteSingle(output);
	}
	,hiliteSingle: function(output) {
		if(!output.isResizable()) {
			return false;
		}
		if(this.builder == null) {
			if(this.flags.allow_nested_cells) {
				this.builder = new coopy_NestedCellBuilder();
			} else {
				this.builder = new coopy_FlatCellBuilder(this.flags);
			}
		}
		output.resize(0,0);
		output.clear();
		this.reset();
		this.setupTables();
		this.setupColumns();
		this.setupMoves();
		this.scanActivity();
		this.scanSchema();
		this.addSchema(output);
		this.addHeader(output);
		this.addMeta(output);
		var outer_reps_needed = this.flags.show_unchanged && this.flags.show_unchanged_columns ? 1 : 2;
		var output_height = output.get_height();
		var output_height_init = output.get_height();
		var _g = 0;
		var _g1 = outer_reps_needed;
		while(_g < _g1) {
			var out = _g++;
			if(out == 1) {
				this.refineActivity();
				var rows = this.countActive(this.active_row) + output_height_init;
				if(this.top_line_done) {
					--rows;
				}
				output_height = output_height_init;
				if(rows > output.get_height()) {
					output.resize(this.column_units.length + 1,rows);
				}
			}
			var showed_dummy = false;
			var l = -1;
			var r = -1;
			var _g2 = 0;
			var _g3 = this.row_units.length;
			while(_g2 < _g3) {
				var i = _g2++;
				var unit = this.row_units[i];
				var reordered = false;
				if(this.flags.ordered) {
					if(this.row_moves.h.hasOwnProperty(i)) {
						reordered = true;
					}
					if(reordered) {
						this.show_rc_numbers = true;
					}
				}
				if(unit.r < 0 && unit.l < 0) {
					continue;
				}
				if(unit.r == 0 && unit.lp() <= 0 && this.top_line_done) {
					continue;
				}
				this.publish = this.flags.show_unchanged;
				var dummy = false;
				if(out == 1) {
					var value = this.active_row[i];
					this.publish = value != null && value > 0;
					dummy = value != null && value == 3;
					if(dummy && showed_dummy) {
						continue;
					}
					if(!this.publish) {
						continue;
					}
				}
				if(!dummy) {
					showed_dummy = false;
				}
				var at = output_height;
				if(this.publish) {
					++output_height;
					if(output.get_height() < output_height) {
						output.resize(this.column_units.length + 1,output_height);
					}
				}
				if(dummy) {
					var _g4 = 0;
					var _g5 = this.column_units.length + 1;
					while(_g4 < _g5) {
						var j = _g4++;
						output.setCell(j,at,this.v.toDatum("..."));
					}
					showed_dummy = true;
					continue;
				}
				this.have_addition = false;
				var skip = false;
				this.act = "";
				if(reordered) {
					this.act = ":";
					if(out == 0) {
						this.row_reorders++;
					}
				}
				if(unit.p < 0 && unit.l < 0 && unit.r >= 0) {
					if(!this.allow_insert) {
						skip = true;
					}
					this.act = "+++";
					if(out == 0 && !skip) {
						this.row_inserts++;
					}
				}
				if((unit.p >= 0 || !this.has_parent) && unit.l >= 0 && unit.r < 0) {
					if(!this.allow_delete) {
						skip = true;
					}
					this.act = "---";
					if(out == 0 && !skip) {
						this.row_deletes++;
					}
				}
				if(skip) {
					if(!this.publish) {
						if(this.active_row != null) {
							this.active_row[i] = -3;
						}
					}
					continue;
				}
				this.scanRow(unit,output,at,i,out);
			}
		}
		this.checkRcNumbers(output.get_width(),output.get_height());
		var admin_w = this.addRcNumbers(output);
		if(!this.preserve_columns) {
			this.elideColumns(output,admin_w);
		}
		return true;
	}
	,hiliteWithNesting: function(output) {
		var base = output.add("base");
		var result = this.hiliteSingle(base);
		if(!result) {
			return false;
		}
		if(this.align.comp == null) {
			return true;
		}
		var order = this.align.comp.child_order;
		if(order == null) {
			return true;
		}
		output.alignment = this.align;
		var _g = 0;
		while(_g < order.length) {
			var name = order[_g];
			++_g;
			var child = this.align.comp.children.h[name];
			var alignment = child.alignment;
			if(alignment.isMarkedAsIdentical()) {
				this.align.comp.children.h[name] = null;
				continue;
			}
			var td = new coopy_TableDiff(alignment,this.flags);
			var child_output = output.add(name);
			result = result && td.hiliteSingle(child_output);
		}
		return result;
	}
	,hasDifference: function() {
		return this.diff_found;
	}
	,hasSchemaDifference: function() {
		return this.schema_diff_found;
	}
	,isNested: function() {
		return this.nesting_present;
	}
	,getComparisonState: function() {
		if(this.align == null) {
			return null;
		}
		return this.align.comp;
	}
	,getSummary: function() {
		var ds = new coopy_DiffSummary();
		ds.row_deletes = this.row_deletes;
		ds.row_inserts = this.row_inserts;
		ds.row_updates = this.row_updates;
		ds.row_reorders = this.row_reorders;
		ds.col_deletes = this.col_deletes;
		ds.col_inserts = this.col_inserts;
		ds.col_updates = this.col_updates;
		ds.col_renames = this.col_renames;
		ds.col_reorders = this.col_reorders;
		ds.row_count_initial_with_header = this.align.getSource().get_height();
		ds.row_count_final_with_header = this.align.getTarget().get_height();
		ds.row_count_initial = this.align.getSource().get_height() - this.align.getSourceHeader() - 1;
		ds.row_count_final = this.align.getTarget().get_height() - this.align.getTargetHeader() - 1;
		ds.col_count_initial = this.align.getSource().get_width();
		ds.col_count_final = this.align.getTarget().get_width();
		ds.different = this.row_deletes + this.row_inserts + this.row_updates + this.row_reorders + this.col_deletes + this.col_inserts + this.col_updates + this.col_renames + this.col_reorders > 0;
		return ds;
	}
	,__class__: coopy_TableDiff
};
var coopy_TableIO = $hx_exports["coopy"]["TableIO"] = function() {
};
coopy_TableIO.__name__ = true;
coopy_TableIO.prototype = {
	valid: function() {
		return false;
	}
	,getContent: function(name) {
		return "";
	}
	,saveContent: function(name,txt) {
		return false;
	}
	,args: function() {
		return [];
	}
	,writeStdout: function(txt) {
	}
	,writeStderr: function(txt) {
	}
	,command: function(cmd,args) {
		return 1;
	}
	,hasAsync: function() {
		return false;
	}
	,exists: function(path) {
		return false;
	}
	,isTtyKnown: function() {
		return false;
	}
	,isTty: function() {
		return true;
	}
	,openSqliteDatabase: function(path) {
		return null;
	}
	,sendToBrowser: function(html) {
		console.log("coopy/TableIO.hx:200:","do not know how to send to browser in this language");
	}
	,__class__: coopy_TableIO
};
var coopy_TableModifier = $hx_exports["coopy"]["TableModifier"] = function(t) {
	this.t = t;
};
coopy_TableModifier.__name__ = true;
coopy_TableModifier.prototype = {
	t: null
	,removeColumn: function(at) {
		var fate = [];
		var _g = 0;
		var _g1 = this.t.get_width();
		while(_g < _g1) {
			var i = _g++;
			if(i < at) {
				fate.push(i);
			} else if(i > at) {
				fate.push(i - 1);
			} else {
				fate.push(-1);
			}
		}
		return this.t.insertOrDeleteColumns(fate,this.t.get_width() - 1);
	}
	,__class__: coopy_TableModifier
};
var coopy_TableStream = function(t) {
	this.t = t;
	this.at = -1;
	this.h = t.get_height();
	this.src = null;
	if(this.h < 0) {
		var meta = t.getMeta();
		if(meta == null) {
			throw haxe_Exception.thrown("Cannot get meta information for table");
		}
		this.src = meta.getRowStream();
		if(this.src == null) {
			throw haxe_Exception.thrown("Cannot iterate table");
		}
	}
};
coopy_TableStream.__name__ = true;
coopy_TableStream.__interfaces__ = [coopy_RowStream];
coopy_TableStream.prototype = {
	t: null
	,at: null
	,h: null
	,src: null
	,columns: null
	,row: null
	,fetchColumns: function() {
		if(this.columns != null) {
			return this.columns;
		}
		if(this.src != null) {
			this.columns = this.src.fetchColumns();
			return this.columns;
		}
		this.columns = [];
		var _g = 0;
		var _g1 = this.t.get_width();
		while(_g < _g1) {
			var i = _g++;
			this.columns.push(this.t.getCell(i,0));
		}
		return this.columns;
	}
	,fetchRow: function() {
		if(this.src != null) {
			return this.src.fetchRow();
		}
		if(this.at >= this.h) {
			return null;
		}
		var row = new haxe_ds_StringMap();
		var _g = 0;
		var _g1 = this.columns.length;
		while(_g < _g1) {
			var i = _g++;
			var k = this.columns[i];
			var v = this.t.getCell(i,this.at);
			row.h[k] = v;
		}
		return row;
	}
	,fetch: function() {
		if(this.at == -1) {
			this.at++;
			if(this.src != null) {
				this.fetchColumns();
			}
			return true;
		}
		if(this.src != null) {
			this.at = 1;
			this.row = this.fetchRow();
			return this.row != null;
		}
		this.at++;
		return this.at < this.h;
	}
	,getCell: function(x) {
		if(this.at == 0) {
			return this.columns[x];
		}
		if(this.row != null) {
			return this.row.h[this.columns[x]];
		}
		return this.t.getCell(x,this.at);
	}
	,width: function() {
		this.fetchColumns();
		return this.columns.length;
	}
	,__class__: coopy_TableStream
};
var coopy_Tables = $hx_exports["coopy"]["Tables"] = function(template) {
	this.template = template;
	this.tables = new haxe_ds_StringMap();
	this.table_order = [];
};
coopy_Tables.__name__ = true;
coopy_Tables.prototype = {
	template: null
	,tables: null
	,table_order: null
	,alignment: null
	,add: function(name) {
		var t = this.template.clone();
		this.tables.h[name] = t;
		this.table_order.push(name);
		return t;
	}
	,getOrder: function() {
		return this.table_order;
	}
	,get: function(name) {
		return this.tables.h[name];
	}
	,one: function() {
		return this.tables.h[this.table_order[0]];
	}
	,hasInsDel: function() {
		if(this.alignment == null) {
			return false;
		}
		if(this.alignment.has_addition) {
			return true;
		}
		if(this.alignment.has_removal) {
			return true;
		}
		return false;
	}
	,__class__: coopy_Tables
};
var coopy_TerminalDiffRender = $hx_exports["coopy"]["TerminalDiffRender"] = function(flags,delim,diff) {
	if(diff == null) {
		diff = true;
	}
	this.align_columns = true;
	this.wide_columns = false;
	this.use_glyphs = true;
	this.flags = flags;
	if(flags != null) {
		if(flags.padding_strategy == "dense") {
			this.align_columns = false;
		}
		if(flags.padding_strategy == "sparse") {
			this.wide_columns = true;
		}
		this.use_glyphs = flags.use_glyphs;
	}
	this.delim = delim != null ? delim : ",";
	this.diff = diff;
};
coopy_TerminalDiffRender.__name__ = true;
coopy_TerminalDiffRender.prototype = {
	codes: null
	,t: null
	,csv: null
	,v: null
	,align_columns: null
	,wide_columns: null
	,use_glyphs: null
	,flags: null
	,delim: null
	,diff: null
	,alignColumns: function(enable) {
		this.align_columns = enable;
	}
	,render: function(t) {
		this.csv = new coopy_Csv();
		var result = "";
		var w = t.get_width();
		var h = t.get_height();
		this.t = t;
		this.v = t.getCellView();
		this.codes = new haxe_ds_StringMap();
		this.codes.h["header"] = "\x1B[0;1m";
		this.codes.h["minor"] = "\x1B[33m";
		this.codes.h["done"] = "\x1B[0m";
		this.codes.h["meta"] = "\x1B[0;1m";
		this.codes.h["spec"] = "\x1B[35;1m";
		this.codes.h["add"] = "\x1B[32;1m";
		this.codes.h["conflict"] = "\x1B[33;1m";
		this.codes.h["modify"] = "\x1B[34;1m";
		this.codes.h["remove"] = "\x1B[31;1m";
		var sizes = null;
		if(this.align_columns) {
			sizes = this.pickSizes(t);
		}
		var txts = [];
		var _g = 0;
		var _g1 = h;
		while(_g < _g1) {
			var y = _g++;
			var target = 0;
			var at = 0;
			var _g2 = 0;
			var _g3 = w;
			while(_g2 < _g3) {
				var x = _g2++;
				if(sizes != null) {
					var spaces = target - at;
					var _g4 = 0;
					var _g5 = spaces;
					while(_g4 < _g5) {
						var i = _g4++;
						txts.push(" ");
						++at;
					}
				}
				if(x > 0) {
					txts.push(this.codes.h["minor"]);
					txts.push(this.delim);
					txts.push(this.codes.h["done"]);
				}
				txts.push(this.getText(x,y,true));
				if(sizes != null) {
					var bit = this.getText(x,y,false);
					at += bit.length;
					target += sizes[x];
				}
			}
			txts.push("\r\n");
		}
		this.t = null;
		this.v = null;
		this.csv = null;
		this.codes = null;
		return txts.join("");
	}
	,getText: function(x,y,color) {
		var val = this.t.getCell(x,y);
		var cell = coopy_DiffRender.renderCell(this.t,this.v,x,y);
		if(color && this.diff) {
			var code = null;
			if(cell.category != null) {
				code = this.codes.h[cell.category];
			}
			if(cell.category_given_tr != null) {
				var code_tr = this.codes.h[cell.category_given_tr];
				if(code_tr != null) {
					code = code_tr;
				}
			}
			if(code != null) {
				var separator = this.use_glyphs ? cell.pretty_separator : cell.separator;
				if(cell.rvalue != null) {
					val = this.codes.h["remove"] + cell.lvalue + this.codes.h["modify"] + separator + this.codes.h["add"] + cell.rvalue + this.codes.h["done"];
					if(cell.pvalue != null) {
						val = this.codes.h["conflict"] + cell.pvalue + this.codes.h["modify"] + separator + Std.string(val);
					}
				} else {
					val = this.use_glyphs ? cell.pretty_value : cell.value;
					val = code + Std.string(val) + this.codes.h["done"];
				}
			}
		} else if(color && !this.diff) {
			if(y == 0) {
				val = this.codes.h["header"] + Std.string(val) + this.codes.h["done"];
			}
		} else {
			val = this.use_glyphs ? cell.pretty_value : cell.value;
		}
		return this.csv.renderCell(this.v,val);
	}
	,pickSizes: function(t) {
		var w = t.get_width();
		var h = t.get_height();
		var v = t.getCellView();
		var csv = new coopy_Csv();
		var sizes = [];
		var row = -1;
		var total = w - 1;
		var _g = 0;
		var _g1 = w;
		while(_g < _g1) {
			var x = _g++;
			var m = 0;
			var m2 = 0;
			var mmax = 0;
			var mmostmax = 0;
			var mmin = -1;
			var _g2 = 0;
			var _g3 = h;
			while(_g2 < _g3) {
				var y = _g2++;
				var txt = this.getText(x,y,false);
				if(txt == "@@" && row == -1 && this.diff) {
					row = y;
				}
				if(row == -1 && !this.diff) {
					row = y;
				}
				var len = txt.length;
				if(y == row) {
					mmin = len;
				}
				m += len;
				m2 += len * len;
				if(len > mmax) {
					mmax = len;
				}
			}
			var mean = m / h;
			var stddev = Math.sqrt(m2 / h - mean * mean);
			var most = mean + stddev * 2 + 0.5 | 0;
			var _g4 = 0;
			var _g5 = h;
			while(_g4 < _g5) {
				var y1 = _g4++;
				var txt1 = this.getText(x,y1,false);
				var len1 = txt1.length;
				if(len1 <= most) {
					if(len1 > mmostmax) {
						mmostmax = len1;
					}
				}
			}
			var full = mmax;
			most = mmostmax;
			if(mmin != -1) {
				if(most < mmin) {
					most = mmin;
				}
			}
			if(this.wide_columns) {
				most = full;
			}
			sizes.push(most);
			total += most;
		}
		if(total > 130 && !this.wide_columns) {
			return null;
		}
		return sizes;
	}
	,__class__: coopy_TerminalDiffRender
};
var coopy_Unit = function(l,r,p) {
	if(p == null) {
		p = -2;
	}
	if(r == null) {
		r = -2;
	}
	if(l == null) {
		l = -2;
	}
	this.l = l;
	this.r = r;
	this.p = p;
};
coopy_Unit.__name__ = true;
coopy_Unit.describe = function(i) {
	if(i >= 0) {
		return "" + i;
	} else {
		return "-";
	}
};
coopy_Unit.prototype = {
	l: null
	,r: null
	,p: null
	,lp: function() {
		if(this.p == -2) {
			return this.l;
		} else {
			return this.p;
		}
	}
	,toString: function() {
		if(this.p >= -1) {
			return coopy_Unit.describe(this.p) + "|" + coopy_Unit.describe(this.l) + ":" + coopy_Unit.describe(this.r);
		}
		return coopy_Unit.describe(this.l) + ":" + coopy_Unit.describe(this.r);
	}
	,fromString: function(txt) {
		txt += "]";
		var at = 0;
		var _g = 0;
		var _g1 = txt.length;
		while(_g < _g1) {
			var i = _g++;
			var ch = HxOverrides.cca(txt,i);
			if(ch >= 48 && ch <= 57) {
				at *= 10;
				at += ch - 48;
			} else if(ch == 45) {
				at = -1;
			} else if(ch == 124) {
				this.p = at;
				at = 0;
			} else if(ch == 58) {
				this.l = at;
				at = 0;
			} else if(ch == 93) {
				this.r = at;
				return true;
			}
		}
		return false;
	}
	,base26: function(num) {
		var alpha = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
		if(num < 0) {
			return "-";
		}
		var out = "";
		do {
			out += alpha.charAt(num % 26);
			num = Math.floor(num / 26) - 1;
		} while(num >= 0);
		return out;
	}
	,toBase26String: function() {
		if(this.p >= -1) {
			return this.base26(this.p) + "|" + this.base26(this.l) + ":" + this.base26(this.r);
		}
		return this.base26(this.l) + ":" + this.base26(this.r);
	}
	,__class__: coopy_Unit
};
var coopy_Viterbi = $hx_exports["coopy"]["Viterbi"] = function() {
	this.K = this.T = 0;
	this.reset();
	this.cost = new coopy_SparseSheet();
	this.src = new coopy_SparseSheet();
	this.path = new coopy_SparseSheet();
};
coopy_Viterbi.__name__ = true;
coopy_Viterbi.prototype = {
	K: null
	,T: null
	,index: null
	,mode: null
	,path_valid: null
	,best_cost: null
	,cost: null
	,src: null
	,path: null
	,reset: function() {
		this.index = 0;
		this.mode = 0;
		this.path_valid = false;
		this.best_cost = 0;
	}
	,setSize: function(states,sequence_length) {
		this.K = states;
		this.T = sequence_length;
		this.cost.resize(this.K,this.T,0);
		this.src.resize(this.K,this.T,-1);
		this.path.resize(1,this.T,-1);
	}
	,assertMode: function(next) {
		if(next == 0 && this.mode == 1) {
			this.index++;
		}
		this.mode = next;
	}
	,addTransition: function(s0,s1,c) {
		var resize = false;
		if(s0 >= this.K) {
			this.K = s0 + 1;
			resize = true;
		}
		if(s1 >= this.K) {
			this.K = s1 + 1;
			resize = true;
		}
		if(resize) {
			this.cost.nonDestructiveResize(this.K,this.T,0);
			this.src.nonDestructiveResize(this.K,this.T,-1);
			this.path.nonDestructiveResize(1,this.T,-1);
		}
		this.path_valid = false;
		this.assertMode(1);
		if(this.index >= this.T) {
			this.T = this.index + 1;
			this.cost.nonDestructiveResize(this.K,this.T,0);
			this.src.nonDestructiveResize(this.K,this.T,-1);
			this.path.nonDestructiveResize(1,this.T,-1);
		}
		var sourced = false;
		if(this.index > 0) {
			c += this.cost.get(s0,this.index - 1);
			sourced = this.src.get(s0,this.index - 1) != -1;
		} else {
			sourced = true;
		}
		if(sourced) {
			if(c < this.cost.get(s1,this.index) || this.src.get(s1,this.index) == -1) {
				this.cost.set(s1,this.index,c);
				this.src.set(s1,this.index,s0);
			}
		}
	}
	,endTransitions: function() {
		this.path_valid = false;
		this.assertMode(0);
	}
	,beginTransitions: function() {
		this.path_valid = false;
		this.assertMode(1);
	}
	,calculatePath: function() {
		if(this.path_valid) {
			return;
		}
		this.endTransitions();
		var best = 0;
		var bestj = -1;
		if(this.index <= 0) {
			this.path_valid = true;
			return;
		}
		var _g = 0;
		var _g1 = this.K;
		while(_g < _g1) {
			var j = _g++;
			if((this.cost.get(j,this.index - 1) < best || bestj == -1) && this.src.get(j,this.index - 1) != -1) {
				best = this.cost.get(j,this.index - 1);
				bestj = j;
			}
		}
		this.best_cost = best;
		var _g = 0;
		var _g1 = this.index;
		while(_g < _g1) {
			var j = _g++;
			var i = this.index - 1 - j;
			this.path.set(0,i,bestj);
			if(!(bestj != -1 && (bestj >= 0 && bestj < this.K))) {
				console.log("coopy/Viterbi.hx:167:","Problem in Viterbi");
			}
			bestj = this.src.get(bestj,i);
		}
		this.path_valid = true;
	}
	,toString: function() {
		this.calculatePath();
		var txt = "";
		var _g = 0;
		var _g1 = this.index;
		while(_g < _g1) {
			var i = _g++;
			if(this.path.get(0,i) == -1) {
				txt += "*";
			} else {
				txt += this.path.get(0,i);
			}
			if(this.K >= 10) {
				txt += " ";
			}
		}
		txt += " costs " + this.getCost();
		return txt;
	}
	,length: function() {
		if(this.index > 0) {
			this.calculatePath();
		}
		return this.index;
	}
	,get: function(i) {
		this.calculatePath();
		return this.path.get(0,i);
	}
	,getCost: function() {
		this.calculatePath();
		return this.best_cost;
	}
	,__class__: coopy_Viterbi
};
var haxe_IMap = function() { };
haxe_IMap.__name__ = true;
var haxe_Exception = function(message,previous,native) {
	Error.call(this,message);
	this.message = message;
	this.__previousException = previous;
	this.__nativeException = native != null ? native : this;
};
haxe_Exception.__name__ = true;
haxe_Exception.caught = function(value) {
	if(((value) instanceof haxe_Exception)) {
		return value;
	} else if(((value) instanceof Error)) {
		return new haxe_Exception(value.message,null,value);
	} else {
		return new haxe_ValueException(value,null,value);
	}
};
haxe_Exception.thrown = function(value) {
	if(((value) instanceof haxe_Exception)) {
		return value.get_native();
	} else if(((value) instanceof Error)) {
		return value;
	} else {
		var e = new haxe_ValueException(value);
		return e;
	}
};
haxe_Exception.__super__ = Error;
haxe_Exception.prototype = $extend(Error.prototype,{
	__skipStack: null
	,__nativeException: null
	,__previousException: null
	,unwrap: function() {
		return this.__nativeException;
	}
	,get_native: function() {
		return this.__nativeException;
	}
	,__class__: haxe_Exception
});
var haxe_ValueException = function(value,previous,native) {
	haxe_Exception.call(this,String(value),previous,native);
	this.value = value;
};
haxe_ValueException.__name__ = true;
haxe_ValueException.__super__ = haxe_Exception;
haxe_ValueException.prototype = $extend(haxe_Exception.prototype,{
	value: null
	,unwrap: function() {
		return this.value;
	}
	,__class__: haxe_ValueException
});
var haxe_ds_IntMap = function() {
	this.h = { };
};
haxe_ds_IntMap.__name__ = true;
haxe_ds_IntMap.__interfaces__ = [haxe_IMap];
haxe_ds_IntMap.prototype = {
	h: null
	,remove: function(key) {
		if(!this.h.hasOwnProperty(key)) {
			return false;
		}
		delete(this.h[key]);
		return true;
	}
	,keys: function() {
		var a = [];
		for( var key in this.h ) if(this.h.hasOwnProperty(key)) a.push(+key);
		return new haxe_iterators_ArrayIterator(a);
	}
	,toString: function() {
		var s_b = "";
		s_b += "[";
		var it = this.keys();
		var i = it;
		while(i.hasNext()) {
			var i1 = i.next();
			s_b += i1 == null ? "null" : "" + i1;
			s_b += " => ";
			s_b += Std.string(Std.string(this.h[i1]));
			if(it.hasNext()) {
				s_b += ", ";
			}
		}
		s_b += "]";
		return s_b;
	}
	,__class__: haxe_ds_IntMap
};
var haxe_ds_StringMap = function() {
	this.h = Object.create(null);
};
haxe_ds_StringMap.__name__ = true;
haxe_ds_StringMap.__interfaces__ = [haxe_IMap];
haxe_ds_StringMap.prototype = {
	h: null
	,__class__: haxe_ds_StringMap
};
var haxe_format_JsonParser = function(str) {
	this.str = str;
	this.pos = 0;
};
haxe_format_JsonParser.__name__ = true;
haxe_format_JsonParser.prototype = {
	str: null
	,pos: null
	,doParse: function() {
		var result = this.parseRec();
		var c;
		while(true) {
			c = this.str.charCodeAt(this.pos++);
			var c1 = c;
			if(!(c1 == c1)) {
				break;
			}
			switch(c) {
			case 9:case 10:case 13:case 32:
				break;
			default:
				this.invalidChar();
			}
		}
		return result;
	}
	,parseRec: function() {
		while(true) {
			var c = this.str.charCodeAt(this.pos++);
			switch(c) {
			case 9:case 10:case 13:case 32:
				break;
			case 34:
				return this.parseString();
			case 45:case 48:case 49:case 50:case 51:case 52:case 53:case 54:case 55:case 56:case 57:
				var c1 = c;
				var start = this.pos - 1;
				var minus = c1 == 45;
				var digit = !minus;
				var zero = c1 == 48;
				var point = false;
				var e = false;
				var pm = false;
				var end = false;
				do {
					c1 = this.str.charCodeAt(this.pos++);
					switch(c1) {
					case 43:case 45:
						if(!e || pm) {
							this.invalidNumber(start);
						}
						digit = false;
						pm = true;
						break;
					case 46:
						if(minus || point || e) {
							this.invalidNumber(start);
						}
						digit = false;
						point = true;
						break;
					case 48:
						if(zero && !point) {
							this.invalidNumber(start);
						}
						if(minus) {
							minus = false;
							zero = true;
						}
						digit = true;
						break;
					case 49:case 50:case 51:case 52:case 53:case 54:case 55:case 56:case 57:
						if(zero && !point) {
							this.invalidNumber(start);
						}
						if(minus) {
							minus = false;
						}
						digit = true;
						zero = false;
						break;
					case 69:case 101:
						if(minus || zero || e) {
							this.invalidNumber(start);
						}
						digit = false;
						e = true;
						break;
					default:
						if(!digit) {
							this.invalidNumber(start);
						}
						this.pos--;
						end = true;
					}
				} while(!end);
				var f = parseFloat(HxOverrides.substr(this.str,start,this.pos - start));
				if(point) {
					return f;
				} else {
					var i = f | 0;
					if(i == f) {
						return i;
					} else {
						return f;
					}
				}
				break;
			case 91:
				var arr = [];
				var comma = null;
				while(true) {
					var c2 = this.str.charCodeAt(this.pos++);
					switch(c2) {
					case 9:case 10:case 13:case 32:
						break;
					case 44:
						if(comma) {
							comma = false;
						} else {
							this.invalidChar();
						}
						break;
					case 93:
						if(comma == false) {
							this.invalidChar();
						}
						return arr;
					default:
						if(comma) {
							this.invalidChar();
						}
						this.pos--;
						arr.push(this.parseRec());
						comma = true;
					}
				}
				break;
			case 102:
				var save = this.pos;
				if(this.str.charCodeAt(this.pos++) != 97 || this.str.charCodeAt(this.pos++) != 108 || this.str.charCodeAt(this.pos++) != 115 || this.str.charCodeAt(this.pos++) != 101) {
					this.pos = save;
					this.invalidChar();
				}
				return false;
			case 110:
				var save1 = this.pos;
				if(this.str.charCodeAt(this.pos++) != 117 || this.str.charCodeAt(this.pos++) != 108 || this.str.charCodeAt(this.pos++) != 108) {
					this.pos = save1;
					this.invalidChar();
				}
				return null;
			case 116:
				var save2 = this.pos;
				if(this.str.charCodeAt(this.pos++) != 114 || this.str.charCodeAt(this.pos++) != 117 || this.str.charCodeAt(this.pos++) != 101) {
					this.pos = save2;
					this.invalidChar();
				}
				return true;
			case 123:
				var obj = { };
				var field = null;
				var comma1 = null;
				while(true) {
					var c3 = this.str.charCodeAt(this.pos++);
					switch(c3) {
					case 9:case 10:case 13:case 32:
						break;
					case 34:
						if(field != null || comma1) {
							this.invalidChar();
						}
						field = this.parseString();
						break;
					case 44:
						if(comma1) {
							comma1 = false;
						} else {
							this.invalidChar();
						}
						break;
					case 58:
						if(field == null) {
							this.invalidChar();
						}
						obj[field] = this.parseRec();
						field = null;
						comma1 = true;
						break;
					case 125:
						if(field != null || comma1 == false) {
							this.invalidChar();
						}
						return obj;
					default:
						this.invalidChar();
					}
				}
				break;
			default:
				this.invalidChar();
			}
		}
	}
	,parseString: function() {
		var start = this.pos;
		var buf = null;
		var prev = -1;
		while(true) {
			var c = this.str.charCodeAt(this.pos++);
			if(c == 34) {
				break;
			}
			if(c == 92) {
				if(buf == null) {
					buf = new StringBuf();
				}
				var s = this.str;
				var len = this.pos - start - 1;
				buf.b += len == null ? HxOverrides.substr(s,start,null) : HxOverrides.substr(s,start,len);
				c = this.str.charCodeAt(this.pos++);
				if(c != 117 && prev != -1) {
					buf.b += String.fromCodePoint(65533);
					prev = -1;
				}
				switch(c) {
				case 34:case 47:case 92:
					buf.b += String.fromCodePoint(c);
					break;
				case 98:
					buf.b += String.fromCodePoint(8);
					break;
				case 102:
					buf.b += String.fromCodePoint(12);
					break;
				case 110:
					buf.b += String.fromCodePoint(10);
					break;
				case 114:
					buf.b += String.fromCodePoint(13);
					break;
				case 116:
					buf.b += String.fromCodePoint(9);
					break;
				case 117:
					var uc = Std.parseInt("0x" + HxOverrides.substr(this.str,this.pos,4));
					this.pos += 4;
					if(prev != -1) {
						if(uc < 56320 || uc > 57343) {
							buf.b += String.fromCodePoint(65533);
							prev = -1;
						} else {
							buf.b += String.fromCodePoint(((prev - 55296 << 10) + (uc - 56320) + 65536));
							prev = -1;
						}
					} else if(uc >= 55296 && uc <= 56319) {
						prev = uc;
					} else {
						buf.b += String.fromCodePoint(uc);
					}
					break;
				default:
					throw haxe_Exception.thrown("Invalid escape sequence \\" + String.fromCodePoint(c) + " at position " + (this.pos - 1));
				}
				start = this.pos;
			} else if(c != c) {
				throw haxe_Exception.thrown("Unclosed string");
			}
		}
		if(prev != -1) {
			buf.b += String.fromCodePoint(65533);
			prev = -1;
		}
		if(buf == null) {
			return HxOverrides.substr(this.str,start,this.pos - start - 1);
		} else {
			var s = this.str;
			var len = this.pos - start - 1;
			buf.b += len == null ? HxOverrides.substr(s,start,null) : HxOverrides.substr(s,start,len);
			return buf.b;
		}
	}
	,invalidChar: function() {
		this.pos--;
		throw haxe_Exception.thrown("Invalid char " + this.str.charCodeAt(this.pos) + " at position " + this.pos);
	}
	,invalidNumber: function(start) {
		throw haxe_Exception.thrown("Invalid number at position " + start + ": " + HxOverrides.substr(this.str,start,this.pos - start));
	}
	,__class__: haxe_format_JsonParser
};
var haxe_format_JsonPrinter = function(replacer,space) {
	this.replacer = replacer;
	this.indent = space;
	this.pretty = space != null;
	this.nind = 0;
	this.buf = new StringBuf();
};
haxe_format_JsonPrinter.__name__ = true;
haxe_format_JsonPrinter.print = function(o,replacer,space) {
	var printer = new haxe_format_JsonPrinter(replacer,space);
	printer.write("",o);
	return printer.buf.b;
};
haxe_format_JsonPrinter.prototype = {
	buf: null
	,replacer: null
	,indent: null
	,pretty: null
	,nind: null
	,write: function(k,v) {
		if(this.replacer != null) {
			v = this.replacer(k,v);
		}
		var _g = Type.typeof(v);
		switch(_g._hx_index) {
		case 0:
			this.buf.b += "null";
			break;
		case 1:
			this.buf.b += Std.string(v);
			break;
		case 2:
			var v1 = isFinite(v) ? Std.string(v) : "null";
			this.buf.b += Std.string(v1);
			break;
		case 3:
			this.buf.b += Std.string(v);
			break;
		case 4:
			this.fieldsString(v,Reflect.fields(v));
			break;
		case 5:
			this.buf.b += "\"<fun>\"";
			break;
		case 6:
			var c = _g.c;
			if(c == String) {
				this.quote(v);
			} else if(c == Array) {
				var v1 = v;
				this.buf.b += String.fromCodePoint(91);
				var len = v1.length;
				var last = len - 1;
				var _g1 = 0;
				var _g2 = len;
				while(_g1 < _g2) {
					var i = _g1++;
					if(i > 0) {
						this.buf.b += String.fromCodePoint(44);
					} else {
						this.nind++;
					}
					if(this.pretty) {
						this.buf.b += String.fromCodePoint(10);
					}
					if(this.pretty) {
						var v2 = StringTools.lpad("",this.indent,this.nind * this.indent.length);
						this.buf.b += Std.string(v2);
					}
					this.write(i,v1[i]);
					if(i == last) {
						this.nind--;
						if(this.pretty) {
							this.buf.b += String.fromCodePoint(10);
						}
						if(this.pretty) {
							var v3 = StringTools.lpad("",this.indent,this.nind * this.indent.length);
							this.buf.b += Std.string(v3);
						}
					}
				}
				this.buf.b += String.fromCodePoint(93);
			} else if(c == haxe_ds_StringMap) {
				var v1 = v;
				var o = { };
				var h = v1.h;
				var _g_h = h;
				var _g_keys = Object.keys(h);
				var _g_length = _g_keys.length;
				var _g_current = 0;
				while(_g_current < _g_length) {
					var k = _g_keys[_g_current++];
					o[k] = v1.h[k];
				}
				var v1 = o;
				this.fieldsString(v1,Reflect.fields(v1));
			} else if(c == Date) {
				var v1 = v;
				this.quote(HxOverrides.dateStr(v1));
			} else {
				this.classString(v);
			}
			break;
		case 7:
			var _g1 = _g.e;
			var i = v._hx_index;
			this.buf.b += Std.string(i == null ? "null" : "" + i);
			break;
		case 8:
			this.buf.b += "\"???\"";
			break;
		}
	}
	,classString: function(v) {
		this.fieldsString(v,Type.getInstanceFields(js_Boot.getClass(v)));
	}
	,fieldsString: function(v,fields) {
		this.buf.b += String.fromCodePoint(123);
		var len = fields.length;
		var last = len - 1;
		var first = true;
		var _g = 0;
		var _g1 = len;
		while(_g < _g1) {
			var i = _g++;
			var f = fields[i];
			var value = Reflect.field(v,f);
			if(Reflect.isFunction(value)) {
				continue;
			}
			if(first) {
				this.nind++;
				first = false;
			} else {
				this.buf.b += String.fromCodePoint(44);
			}
			if(this.pretty) {
				this.buf.b += String.fromCodePoint(10);
			}
			if(this.pretty) {
				var v1 = StringTools.lpad("",this.indent,this.nind * this.indent.length);
				this.buf.b += Std.string(v1);
			}
			this.quote(f);
			this.buf.b += String.fromCodePoint(58);
			if(this.pretty) {
				this.buf.b += String.fromCodePoint(32);
			}
			this.write(f,value);
			if(i == last) {
				this.nind--;
				if(this.pretty) {
					this.buf.b += String.fromCodePoint(10);
				}
				if(this.pretty) {
					var v2 = StringTools.lpad("",this.indent,this.nind * this.indent.length);
					this.buf.b += Std.string(v2);
				}
			}
		}
		this.buf.b += String.fromCodePoint(125);
	}
	,quote: function(s) {
		this.buf.b += String.fromCodePoint(34);
		var i = 0;
		var length = s.length;
		while(i < length) {
			var c = s.charCodeAt(i++);
			switch(c) {
			case 8:
				this.buf.b += "\\b";
				break;
			case 9:
				this.buf.b += "\\t";
				break;
			case 10:
				this.buf.b += "\\n";
				break;
			case 12:
				this.buf.b += "\\f";
				break;
			case 13:
				this.buf.b += "\\r";
				break;
			case 34:
				this.buf.b += "\\\"";
				break;
			case 92:
				this.buf.b += "\\\\";
				break;
			default:
				this.buf.b += String.fromCodePoint(c);
			}
		}
		this.buf.b += String.fromCodePoint(34);
	}
	,__class__: haxe_format_JsonPrinter
};
var haxe_iterators_ArrayIterator = function(array) {
	this.current = 0;
	this.array = array;
};
haxe_iterators_ArrayIterator.__name__ = true;
haxe_iterators_ArrayIterator.prototype = {
	array: null
	,current: null
	,hasNext: function() {
		return this.current < this.array.length;
	}
	,next: function() {
		return this.array[this.current++];
	}
	,__class__: haxe_iterators_ArrayIterator
};
var js_Boot = function() { };
js_Boot.__name__ = true;
js_Boot.getClass = function(o) {
	if(o == null) {
		return null;
	} else if(((o) instanceof Array)) {
		return Array;
	} else {
		var cl = o.__class__;
		if(cl != null) {
			return cl;
		}
		var name = js_Boot.__nativeClassName(o);
		if(name != null) {
			return js_Boot.__resolveNativeClass(name);
		}
		return null;
	}
};
js_Boot.__string_rec = function(o,s) {
	if(o == null) {
		return "null";
	}
	if(s.length >= 5) {
		return "<...>";
	}
	var t = typeof(o);
	if(t == "function" && (o.__name__ || o.__ename__)) {
		t = "object";
	}
	switch(t) {
	case "function":
		return "<function>";
	case "object":
		if(o.__enum__) {
			var e = $hxEnums[o.__enum__];
			var con = e.__constructs__[o._hx_index];
			var n = con._hx_name;
			if(con.__params__) {
				s = s + "\t";
				return n + "(" + ((function($this) {
					var $r;
					var _g = [];
					{
						var _g1 = 0;
						var _g2 = con.__params__;
						while(true) {
							if(!(_g1 < _g2.length)) {
								break;
							}
							var p = _g2[_g1];
							_g1 = _g1 + 1;
							_g.push(js_Boot.__string_rec(o[p],s));
						}
					}
					$r = _g;
					return $r;
				}(this))).join(",") + ")";
			} else {
				return n;
			}
		}
		if(((o) instanceof Array)) {
			var str = "[";
			s += "\t";
			var _g = 0;
			var _g1 = o.length;
			while(_g < _g1) {
				var i = _g++;
				str += (i > 0 ? "," : "") + js_Boot.__string_rec(o[i],s);
			}
			str += "]";
			return str;
		}
		var tostr;
		try {
			tostr = o.toString;
		} catch( _g ) {
			return "???";
		}
		if(tostr != null && tostr != Object.toString && typeof(tostr) == "function") {
			var s2 = o.toString();
			if(s2 != "[object Object]") {
				return s2;
			}
		}
		var str = "{\n";
		s += "\t";
		var hasp = o.hasOwnProperty != null;
		var k = null;
		for( k in o ) {
		if(hasp && !o.hasOwnProperty(k)) {
			continue;
		}
		if(k == "prototype" || k == "__class__" || k == "__super__" || k == "__interfaces__" || k == "__properties__") {
			continue;
		}
		if(str.length != 2) {
			str += ", \n";
		}
		str += s + k + " : " + js_Boot.__string_rec(o[k],s);
		}
		s = s.substring(1);
		str += "\n" + s + "}";
		return str;
	case "string":
		return o;
	default:
		return String(o);
	}
};
js_Boot.__interfLoop = function(cc,cl) {
	if(cc == null) {
		return false;
	}
	if(cc == cl) {
		return true;
	}
	var intf = cc.__interfaces__;
	if(intf != null) {
		var _g = 0;
		var _g1 = intf.length;
		while(_g < _g1) {
			var i = _g++;
			var i1 = intf[i];
			if(i1 == cl || js_Boot.__interfLoop(i1,cl)) {
				return true;
			}
		}
	}
	return js_Boot.__interfLoop(cc.__super__,cl);
};
js_Boot.__implements = function(o,iface) {
	return js_Boot.__interfLoop(js_Boot.getClass(o),iface);
};
js_Boot.__nativeClassName = function(o) {
	var name = js_Boot.__toStr.call(o).slice(8,-1);
	if(name == "Object" || name == "Function" || name == "Math" || name == "JSON") {
		return null;
	}
	return name;
};
js_Boot.__resolveNativeClass = function(name) {
	return $global[name];
};
function $getIterator(o) { if( o instanceof Array ) return new haxe_iterators_ArrayIterator(o); else return o.iterator(); }
function $bind(o,m) { if( m == null ) return null; if( m.__id__ == null ) m.__id__ = $global.$haxeUID++; var f; if( o.hx__closures__ == null ) o.hx__closures__ = {}; else f = o.hx__closures__[m.__id__]; if( f == null ) { f = m.bind(o); o.hx__closures__[m.__id__] = f; } return f; }
$global.$haxeUID |= 0;
if(typeof(performance) != "undefined" ? typeof(performance.now) == "function" : false) {
	HxOverrides.now = performance.now.bind(performance);
}
if( String.fromCodePoint == null ) String.fromCodePoint = function(c) { return c < 0x10000 ? String.fromCharCode(c) : String.fromCharCode((c>>10)+0xD7C0)+String.fromCharCode((c&0x3FF)+0xDC00); }
Object.defineProperty(String.prototype,"__class__",{ value : String, enumerable : false, writable : true});
String.__name__ = true;
Array.__name__ = true;
Date.prototype.__class__ = Date;
Date.__name__ = "Date";
js_Boot.__toStr = ({ }).toString;
coopy_Coopy.VERSION = "1.3.48";
coopy_Coopy.main();
})(typeof exports != "undefined" ? exports : typeof window != "undefined" ? window : typeof self != "undefined" ? self : this, typeof window != "undefined" ? window : typeof global != "undefined" ? global : typeof self != "undefined" ? self : this);
let daff = null;
if (typeof exports !== "undefined" && exports.coopy) {
	// avoid having excess nesting (coopy.coopy) when using node
	for (const f in exports.coopy) {
		if (exports.coopy.hasOwnProperty(f)) {
			exports[f] = exports.coopy[f];
		}
	}
	// promote methods of coopy.Coopy
	for (const f in exports.Coopy) {
		if (exports.Coopy.hasOwnProperty(f)) {
			exports[f] = exports.Coopy[f];
		}
	}
	daff = exports;
} else {
	// promote methods of coopy.Coopy
	for (const f in coopy.Coopy) {
		if (coopy.Coopy.hasOwnProperty(f)) {
			coopy[f] = coopy.Coopy[f];
		}
	}
	window.daff = daff = coopy;
}
(function() {

var CellView = function() {
}

CellView.prototype.toString = function(d) {
    return ""+d;
}

CellView.prototype.equals = function(d1,d2) {
    return d1==d2;
}

CellView.prototype.toDatum = function(d) {
    return d;
}

CellView.prototype.makeHash = function() {
    return {};
}

CellView.prototype.hashSet = function(d,k,v) {
    d[k] = v;
}

CellView.prototype.hashGet = function(d,k) {
    return d[k];
}

CellView.prototype.hashExists = function(d,k) {
    return k in d;
}

CellView.prototype.isHash = function(d) {
    return d && (typeof d  === "object");
}

var TableView = function(data) {
    // variant constructor (cols, rows)
    if (arguments.length==2) {
	var lst = [];
	for (var i=0; i<arguments[1]; i++) {
	    var row = [];
	    for (var j=0; j<arguments[0]; j++) {
		row.push(null);
	    }
	    lst.push(row);
	}
	data = lst;
    }
    this.data = data;
    this.height = data.length;
    this.width = 0;
    if (this.height>0) {
	this.width = data[0].length;
    }
}

TableView.prototype.get_width = function() {
    return this.width;
}

TableView.prototype.get_height = function() {
    return this.height;
}

TableView.prototype.getCell = function(x,y) {
    return this.data[y][x];
}

TableView.prototype.setCell = function(x,y,c) {
    this.data[y][x] = c;
}

TableView.prototype.toString = function() {
    return daff.SimpleTable.tableToString(this);
}

TableView.prototype.getCellView = function() {
    return new CellView();
}

TableView.prototype.isResizable = function() {
    return true;
}

TableView.prototype.resize = function(w,h) {
    this.width = w;
    this.height = h;
    for (var i=0; i<this.data.length; i++) {
	var row = this.data[i];
	if (row==null) {
	    row = this.data[i] = [];
	}
	while (row.length<this.width) {
	    row.push(null);
	}
    }
    if (this.data.length<this.height) {
	while (this.data.length<this.height) {
	    var row = [];
	    for (var i=0; i<this.width; i++) {
		row.push(null);
	    }
	    this.data.push(row);
	}
    }
    return true;
}

TableView.prototype.clear = function() {
    for (var i=0; i<this.data.length; i++) {
	var row = this.data[i];
	for (var j=0; j<row.length; j++) {
	    row[j] = null;
	}
    }
}

TableView.prototype.trim = function() {
    var changed = this.trimRows();
    changed = changed || this.trimColumns();
    return changed;
}

TableView.prototype.trimRows = function() {
    var changed = false;
    while (true) {
	if (this.height==0) return changed;
	var row = this.data[this.height-1];
	for (var i=0; i<this.width; i++) {
	    var c = row[i];
	    if (c!=null && c!="") return changed;
	}
	this.height--;
    }
}

TableView.prototype.trimColumns = function() {
    var top_content = 0;
    for (var i=0; i<this.height; i++) {
	if (top_content>=this.width) break;
	var row = this.data[i];
	for (var j=0; j<this.width; j++) {
	    var c = row[j];
	    if (c!=null && c!="") {
		if (j>top_content) {
		    top_content = j;
		}
	    }
	}
    }
    if (this.height==0 || top_content+1==this.width) return false;
    this.width = top_content+1;
    return true;
}

TableView.prototype.getData = function() {
    return this.data;
}

TableView.prototype.clone = function() {
    var ndata = [];
    for (var i=0; i<this.get_height(); i++) {
	ndata[i] = this.data[i].slice();
    }
    return new TableView(ndata);
}

TableView.prototype.create = function() {
    return new TableView([]);
}

TableView.prototype.insertOrDeleteRows = function(fate, hfate) {
    var ndata = [];
    for (var i=0; i<fate.length; i++) {
        var j = fate[i];
        if (j!=-1) {
	    ndata[j] = this.data[i];
        }
    }
    // let's preserve data
    //this.data = ndata;
    this.data.length = 0;
    for (var i=0; i<ndata.length; i++) {
	this.data[i] = ndata[i];
    }
    this.resize(this.width,hfate);
    return true;
}

TableView.prototype.insertOrDeleteColumns = function(fate, wfate) {
    if (wfate==this.width && wfate==fate.length) {
	var eq = true;
	for (var i=0; i<wfate; i++) {
	    if (fate[i]!=i) {
		eq = false;
		break;
	    }
	}
	if (eq) return true;
    }
    for (var i=0; i<this.height; i++) {
	var row = this.data[i];
	var nrow = [];
	for (var j=0; j<this.width; j++) {
	    if (fate[j]==-1) continue;
	    nrow[fate[j]] = row[j];
	}
	while (nrow.length<wfate) {
	    nrow.push(null);
	}
	this.data[i] = nrow;
    }
    this.width = wfate;
    return true;
}

TableView.prototype.isSimilar = function(alt) {
    if (alt.get_width()!=this.get_width()) return false;
    if (alt.get_height()!=this.get_height()) return false;
    for (var c=0; c<this.width; c++) {
	for (var r=0; r<this.height; r++) {
	    var v1 = "" + this.getCell(c,r);
	    var v2 = "" + alt.getCell(c,r); 
	    if (v1!=v2) {
		console.log("MISMATCH "+ v1 + " " + v2);
		return false;
	    }
	}
    }
    return true;
}

TableView.prototype.getMeta = function() {
    return null;
}

daff.TableView = TableView;

daff.CellView = CellView;
daff.TableView = TableView;

})();
(function() {

/**
 *
 * Wrapper around a table expressed as rows of hashes.  A mapping function can be passed if the
 * representation needs to be adapted a little.  The function will be passed data[i] and should
 * return a simple hash of { "col1": "val1", "col2": "val2", ... }
 *
 */
var NdjsonTable = function(data,mapping) {
    this.data = data;
    this.height = data.length;
    this.width = 0;
    this.columns = [];
    this.hasMapping = (mapping!=null);
    if (mapping==null) {
        mapping = function(x) { return x };
    }
    this.mapping = mapping;
    var column_name_to_number = {};
    if (this.height>0) {
        // We scan all rows to find all fields in use.
        for (var i=0; i<this.height; i++) {
            var row = mapping(data[i]);
            for (var key in row) {
                if (key in column_name_to_number) continue;
                if (!row.hasOwnProperty(key)) continue;
                this.width++;
                column_name_to_number[key] = this.columns.length;
                this.columns.push(key);
            }
        }
    }
    this.columns.sort(); // make order deterministic
    if (this.height>0) this.height++;
}

NdjsonTable.prototype.get_width = function() {
    return this.width;
}

NdjsonTable.prototype.get_height = function() {
    return this.height;
}

NdjsonTable.prototype.getCell = function(x,y) {
    var key = this.columns[x];
    if (key == null) throw Error("bad key");
    if (y==0) return key;
    return this.mapping(this.data[y-1])[key];
}

NdjsonTable.prototype.setCell = function(x,y,c) {
    var key = this.columns[x];
    if (key == null && y!=0) throw Error("bad key");
    if (y==0) {
        if (key!=null) throw Error("cannot yet change column set in this type of table");
        this.columns[x] = c;
    } else {
        this.mapping(this.data[y-1])[key] = c;
    }
}

NdjsonTable.prototype.toString = function() {
    return daff.SimpleTable.tableToString(this);
}

NdjsonTable.prototype.getCellView = function() {
    return new daff.CellView();
}

NdjsonTable.prototype.isResizable = function() {
    // Ndjson wrapper can't usefully cope with schema changes.
    return false;
}

NdjsonTable.prototype.resize = function(w,h) {
    return false;
}

NdjsonTable.prototype.clear = function() {
    return false;
}

NdjsonTable.prototype.getData = function() {
    return this.data;
}

NdjsonTable.prototype.clone = function() {
    var ndata = [];
    for (var i=0; i<this.data.length; i++) {
        var row = ndata[i] = {};
        for (var c=0; c<this.columns; c++) {
            var key = this.columns[c];
	    row[key] = this.data[i][key];
        }
    }
    return new NdjsonTable(ndata,this.hasMapping?this.mapping:null);
}

NdjsonTable.prototype.insertOrDeleteRows = function(fate, hfate) {
    return false;
}

NdjsonTable.prototype.insertOrDeleteColumns = function(fate, wfate) {
    return false;
}

NdjsonTable.prototype.getMeta = function() {
    return null;
}


daff.NdjsonTable = NdjsonTable;

})();
if (typeof exports !== "undefined" && typeof window !== "undefined") {
	// looking at you webpack
	for (const f in daff) {
		if (daff.hasOwnProperty(f)) {
			exports[f] = daff[f];
		}
	}
}
    (function() {

	SqliteDatabase = function(db,fname,Fiber) {
	    this.db = db;
            this.fname = fname;
	    this.row = null;
	    this.active = false;
	    this.index2name = {};
	    this.Fiber = Fiber;
            // quoting rule for CSV is compatible with Sqlite
            this.quoter = new daff.Csv();
            this.view = new daff.SimpleView();
	}

        SqliteDatabase.prototype.getHelper = function() {
            return new daff.SqliteHelper();
        }
	
	SqliteDatabase.prototype.getQuotedColumnName = function (name) {
	    return this.quoter.renderCell(this.view, name, true);
	}
	
	SqliteDatabase.prototype.getQuotedTableName = function (name) {
	    return this.quoter.renderCell(this.view, name.toString(), true);
	}
	
	SqliteDatabase.prototype.getColumns = function(name) {
	    var fiber = this.Fiber.current;
	    var qname = this.getQuotedColumnName(name);
	    var self = this;
	    this.db.all("pragma table_info("+qname+")", function(err,rows) {
		var lst = [];
		for (var i in rows) {
		    var x = rows[i];
                    var col = new daff.SqlColumn();
                    col.setName(x['name']);
                    col.setPrimaryKey(x['pk']>0);
                    if (x['type']) {
                        col.setType(x['type'],'sqlite');
                    }
		    lst.push(col);
		    self.index2name[i] = x['name'];
		}
		fiber.run(lst);
	    });
	    return this.Fiber.yield();
	}
	
	SqliteDatabase.prototype.exec = function(query,args) {
	    var fiber = this.Fiber.current;
	    if (args==null) {
		this.db.run(query,function(err) {
		    if (err) console.log(err);
		    fiber.run(err==null);
		});
		return this.Fiber.yield();
	    }
	    var statement = this.db.run(query,args,function(err) {
		if (err) console.log(err);
		fiber.run(err==null);
	    });
	    return this.Fiber.yield();
	}
	
	SqliteDatabase.prototype.beginRow = function(tab,row,order) {
	    return this.begin("SELECT * FROM " + this.getQuotedColumnName(tab) + " WHERE rowid = ?",
			      [row],
			      order);
	}
	
	SqliteDatabase.prototype.begin = function(query,args,order) {
	    if (order!=null) {
		this.index2name = {};
		var len = order.length;
		for (var i=0; i<len; i++) {
		    this.index2name[i] = order[i];
		}
	    }
	    var fiber = this.Fiber.current;
	    this.active = true;
	    var self = this;
	    this.db.each(query,(args==null)?[]:args,function(err,row) {
                var keys = Object.keys(row);
                for (var i=0; i<keys.length; i++) {
                    var val = row[keys[i]];
                    // cannot do much with blobs - replace them with a short hash.
                    if (Buffer.isBuffer(val)) {
                        var crypto = require('crypto');
                        var hash = crypto.createHash('md5').update(val).digest('hex');
                        row[keys[i]] = '[buffer:' + hash + ']';
                    }
                }
		if (err) {
		    fiber.run([false,0]);
		} else {
		    fiber.run([true,row]);
		}
	    },function(err,n) {
                if (err) {
                    console.log(err);
                }
		fiber.run([false,n]);
	    });
	    return true;
	}

	SqliteDatabase.prototype.read = function() {
	    if (!this.active) return false;
	    var v = this.Fiber.yield();
	    if (v[0]) {
		this.row = v[1];
		return true;
	    }
	    this.row = null;
	    this.active = false;
	    return false;
	}

	SqliteDatabase.prototype.get = function(index) {
	    return this.row[this.index2name[index]];
	}

	SqliteDatabase.prototype.end = function() {
	    while (this.active) {
		this.read();
	    }
	}

	SqliteDatabase.prototype.rowid = function() {
	    return "rowid";
	}

	SqliteDatabase.prototype.getNameForAttachment = function() {
	    return this.fname;
	}

        if (typeof exports !== 'undefined') {
            exports.SqliteDatabase = SqliteDatabase;
        }

    })();
if (typeof exports !== 'undefined') {
    
    var tio = {};
    var tio_args = [];

    var coopy = exports;
    var fs = require('fs');
    var exec = require('child_process').exec;
    var readline = null;
    var Fiber = null;
    var sqlite3 = null;
    var tty = null;
    
    tio.valid = function() {
        return true;
    }

    tio.getContent = function(name) {
        var txt = "";
	if (name=="-") {
	    // only works on Linux, all other solutions seem broken
	    txt = fs.readFileSync('/dev/stdin',"utf8");
	} else {
	    txt = fs.readFileSync(name,"utf8");
        }
        if (txt.charCodeAt(0) === 0xFEFF) {
	    return txt.slice(1);
	}
        return txt;
    }
    
    tio.saveContent = function(name,txt) {
	return fs.writeFileSync(name,txt,"utf8");
    }
    
    tio.args = function() {
	return tio_args;
    }
    
    tio.writeStdout = function(txt) {
	process.stdout.write(txt);
    }
    
    tio.writeStderr = function(txt) {
	process.stderr.write(txt);
    }
    
    tio.hasAsync = function() {
	return true;
    }

    tio.exists = function(path) {
	return fs.existsSync(path);
    }

    tio.isTtyKnown = function() {
        return true;
    }

    tio.isTty = function() {
        if (typeof process.stdout.isTTY !== 'undefined') {
            if (process.stdout.isTTY) return true;
        } else {
            // fall back on tty api
            if (tty==null) tty = require('tty');
            if (tty.isatty(process.stdout.fd)) return true;
        }
        // There's a wrinkle when called from git.  Git may have started a pager that
        // respects color but which will not be detected as a terminal.  In this case,
        // it appears that git defines GIT_PAGER_IN_USE, so we watch out for that.
        if (process.env.GIT_PAGER_IN_USE == 'true') return true;
        return false;
    }

    tio.openSqliteDatabase = function(path) {
	if (Fiber) {
	    return new coopy.SqliteDatabase(new sqlite3.Database(path),path,Fiber);
	}
	throw("run inside Fiber plz");
	return null;
    }

    tio.sendToBrowser = function(html) {
        var http = require("http");
	var shutdown = null;
        var server = http.createServer(function(request, response) {
            response.writeHead(200, 
                               {
                                   "Content-Type": "text/html; charset=UTF-8",
                                   "Connection": "close"
                               });
            response.write(html);
            response.end();
	    setTimeout(function() { shutdown(); }, 0);
        });
	var sockets = {}, nextSocketId = 0;
	server.on('connection', function (socket) {
	    var socketId = nextSocketId++;
	    sockets[socketId] = socket;
	    socket.on('close', function () {
		delete sockets[socketId];
	    });
	});
	shutdown = function() {
	    server.close();
	    for (var socketId in sockets) {
		sockets[socketId].destroy();
	    }
	};
        server.listen(0,null,null,function() {
            var target = "http://localhost:" + server.address().port;
            var exec = require('child_process').exec;
            var cmd = "xdg-open";
            switch (process.platform) {
            case 'darwin':
		cmd = 'open';
		break;
            case 'win32':
		cmd = 'start ""';
		break;
            }
            exec(cmd + ' "' + target + '"', function(error) { 
		if (error) {
                    console.error(error);
                    server.close();
		}
            });
	});
    }

    var cmd_result = 1;
    var cmd_pending = null;

    tio.command = function(cmd,args) {
	// we promise not to use any arguments with quotes in them
	for (var i=0; i<args.length; i++) {
	    var argi = args[i];
	    if (argi.indexOf(" ")>=0) {
		argi = "\"" + argi + "\"";
	    }
	    cmd += " " + argi;
	}
	if (cmd == cmd_pending) {
	    cmd_pending = null;
	    return cmd_result;
	} else if (cmd_pending!=null) {
	    return 998; // "hack not working correctly"
	}
	cmd_pending = cmd;
	return 999; // "cannot be executed synchronously"
    }

    function run_daff_base(main,args) {
	tio_args = args.slice();
	var code = main.coopyhx(tio);
	if (code==999) {
	    if (cmd_pending!=null) {
		exec(cmd_pending,function(error,stdout,stderr) {
		    cmd_result = 0;
		    if (error!=null) {
			cmd_result = error.code;
		    }
		    return run_daff_base(main,args);
		});
	    }
	} 
	return code;
    }
    
    daff.run_daff_main = function() {
	var main = new daff.Coopy();
	var code = run_daff_base(main,process.argv.slice(2));
	if (code!=999) {
            if (code!=0) {
	        process.exit(code);
            }
	}
    }

    daff.cmd = function(args) {
	var main = new daff.Coopy();
	var code = run_daff_base(main,args);
	return code;
    }
}

if (typeof require != "undefined") {
    if (require.main === module) {
	try {
	    daff.run_daff_main();
	} catch (e) {
	    if (("" + e).indexOf("run inside Fiber plz") !== -1) {
		try {
		    Fiber = require('fibers');
		    sqlite3 = require('sqlite3');
		} catch (err) {
		    // We don't have what we need for accessing the sqlite database.
		    console.log("No sqlite3/fibers");
		}
		Fiber(function() {
		    daff.run_daff_main();
		}).run();
            } else {
                throw(e);
            }
	}
    }
}
