git » sdk » compiled » tree

[compiled] / npm / snikket-browser.js

var exports = {};
// Generated by Haxe 4.3.2
import { sqlite3Worker1Promiser as snikket_persistence_Worker1 } from "@sqlite.org/sqlite-wasm";
import snikket_streams_XmppJsScramSha1 from "@xmpp/sasl-scram-sha-1";
import { client as snikket_streams_XmppJsClient } from "@xmpp/client";
import { jid as snikket_streams_XmppJsJID } from "@xmpp/jid";
import snikket_streams_XmppJsDebug from "@xmpp/debug";
import snikket_streams_XmppJsXml from "@xmpp/xml";
import * as snikket_streams_XmppJsLtx from "ltx";
import snikket_streams_XmppJsId from "@xmpp/id";
import snikket_streams_XmppJsError from "@xmpp/error";
;(function ($hx_exports, $global) { "use strict";
$hx_exports["snikket"] = $hx_exports["snikket"] || {};
$hx_exports["snikket"]["Push"] = $hx_exports["snikket"]["Push"] || {};
;$hx_exports["snikket"]["persistence"] = $hx_exports["snikket"]["persistence"] || {};
var $estr = function() { return js_Boot.__string_rec(this,''); },$hxEnums = $hxEnums || {},$_;
class DateTools {
	static __format_get(d,e) {
		switch(e) {
		case "%":
			return "%";
		case "A":
			return DateTools.DAY_NAMES[d.getDay()];
		case "B":
			return DateTools.MONTH_NAMES[d.getMonth()];
		case "C":
			return StringTools.lpad(Std.string(d.getFullYear() / 100 | 0),"0",2);
		case "D":
			return DateTools.__format(d,"%m/%d/%y");
		case "F":
			return DateTools.__format(d,"%Y-%m-%d");
		case "M":
			return StringTools.lpad(Std.string(d.getMinutes()),"0",2);
		case "R":
			return DateTools.__format(d,"%H:%M");
		case "S":
			return StringTools.lpad(Std.string(d.getSeconds()),"0",2);
		case "T":
			return DateTools.__format(d,"%H:%M:%S");
		case "Y":
			return Std.string(d.getFullYear());
		case "a":
			return DateTools.DAY_SHORT_NAMES[d.getDay()];
		case "d":
			return StringTools.lpad(Std.string(d.getDate()),"0",2);
		case "e":
			return Std.string(d.getDate());
		case "b":case "h":
			return DateTools.MONTH_SHORT_NAMES[d.getMonth()];
		case "H":case "k":
			return StringTools.lpad(Std.string(d.getHours()),e == "H" ? "0" : " ",2);
		case "I":case "l":
			let hour = d.getHours() % 12;
			return StringTools.lpad(Std.string(hour == 0 ? 12 : hour),e == "I" ? "0" : " ",2);
		case "m":
			return StringTools.lpad(Std.string(d.getMonth() + 1),"0",2);
		case "n":
			return "\n";
		case "p":
			if(d.getHours() > 11) {
				return "PM";
			} else {
				return "AM";
			}
			break;
		case "r":
			return DateTools.__format(d,"%I:%M:%S %p");
		case "s":
			return Std.string(d.getTime() / 1000 | 0);
		case "t":
			return "\t";
		case "u":
			let t = d.getDay();
			if(t == 0) {
				return "7";
			} else if(t == null) {
				return "null";
			} else {
				return "" + t;
			}
			break;
		case "w":
			return Std.string(d.getDay());
		case "y":
			return StringTools.lpad(Std.string(d.getFullYear() % 100),"0",2);
		default:
			throw new haxe_exceptions_NotImplementedException("Date.format %" + e + "- not implemented yet.",null,{ fileName : "DateTools.hx", lineNumber : 101, className : "DateTools", methodName : "__format_get"});
		}
	}
	static __format(d,f) {
		let r_b = "";
		let p = 0;
		while(true) {
			let np = f.indexOf("%",p);
			if(np < 0) {
				break;
			}
			let len = np - p;
			r_b += len == null ? HxOverrides.substr(f,p,null) : HxOverrides.substr(f,p,len);
			r_b += Std.string(DateTools.__format_get(d,HxOverrides.substr(f,np + 1,1)));
			p = np + 2;
		}
		let len = f.length - p;
		r_b += len == null ? HxOverrides.substr(f,p,null) : HxOverrides.substr(f,p,len);
		return r_b;
	}
	static format(d,f) {
		return DateTools.__format(d,f);
	}
}
DateTools.__name__ = "DateTools";
class EReg {
	constructor(r,opt) {
		this.r = new RegExp(r,opt.split("u").join(""));
	}
	match(s) {
		if(this.r.global) {
			this.r.lastIndex = 0;
		}
		this.r.m = this.r.exec(s);
		this.r.s = s;
		return this.r.m != null;
	}
	matched(n) {
		if(this.r.m != null && n >= 0 && n < this.r.m.length) {
			return this.r.m[n];
		} else {
			throw haxe_Exception.thrown("EReg::matched");
		}
	}
	matchedLeft() {
		if(this.r.m == null) {
			throw haxe_Exception.thrown("No string matched");
		}
		return HxOverrides.substr(this.r.s,0,this.r.m.index);
	}
	matchedRight() {
		if(this.r.m == null) {
			throw haxe_Exception.thrown("No string matched");
		}
		let sz = this.r.m.index + this.r.m[0].length;
		return HxOverrides.substr(this.r.s,sz,this.r.s.length - sz);
	}
	matchedPos() {
		if(this.r.m == null) {
			throw haxe_Exception.thrown("No string matched");
		}
		return { pos : this.r.m.index, len : this.r.m[0].length};
	}
	matchSub(s,pos,len) {
		if(len == null) {
			len = -1;
		}
		if(this.r.global) {
			this.r.lastIndex = pos;
			this.r.m = this.r.exec(len < 0 ? s : HxOverrides.substr(s,0,pos + len));
			let b = this.r.m != null;
			if(b) {
				this.r.s = s;
			}
			return b;
		} else {
			let b = this.match(len < 0 ? HxOverrides.substr(s,pos,null) : HxOverrides.substr(s,pos,len));
			if(b) {
				this.r.s = s;
				this.r.m.index += pos;
			}
			return b;
		}
	}
	split(s) {
		let d = "#__delim__#";
		return s.replace(this.r,d).split(d);
	}
	map(s,f) {
		let offset = 0;
		let buf_b = "";
		do {
			if(offset >= s.length) {
				break;
			} else if(!this.matchSub(s,offset)) {
				buf_b += Std.string(HxOverrides.substr(s,offset,null));
				break;
			}
			let p = this.matchedPos();
			buf_b += Std.string(HxOverrides.substr(s,offset,p.pos - offset));
			buf_b += Std.string(f(this));
			if(p.len == 0) {
				buf_b += Std.string(HxOverrides.substr(s,p.pos,1));
				offset = p.pos + 1;
			} else {
				offset = p.pos + p.len;
			}
		} while(this.r.global);
		if(!this.r.global && offset > 0 && offset < s.length) {
			buf_b += Std.string(HxOverrides.substr(s,offset,null));
		}
		return buf_b;
	}
}
EReg.__name__ = "EReg";
Object.assign(EReg.prototype, {
	__class__: EReg
});
class HxOverrides {
	static cca(s,index) {
		let x = s.charCodeAt(index);
		if(x != x) {
			return undefined;
		}
		return x;
	}
	static substr(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);
	}
	static remove(a,obj) {
		let i = a.indexOf(obj);
		if(i == -1) {
			return false;
		}
		a.splice(i,1);
		return true;
	}
	static now() {
		return Date.now();
	}
}
HxOverrides.__name__ = "HxOverrides";
class Lambda {
	static array(it) {
		let a = [];
		let i = $getIterator(it);
		while(i.hasNext()) {
			let i1 = i.next();
			a.push(i1);
		}
		return a;
	}
	static exists(it,f) {
		let x = $getIterator(it);
		while(x.hasNext()) {
			let x1 = x.next();
			if(f(x1)) {
				return true;
			}
		}
		return false;
	}
	static fold(it,f,first) {
		let x = $getIterator(it);
		while(x.hasNext()) {
			let x1 = x.next();
			first = f(x1,first);
		}
		return first;
	}
	static empty(it) {
		return !$getIterator(it).hasNext();
	}
	static indexOf(it,v) {
		let i = 0;
		let v2 = $getIterator(it);
		while(v2.hasNext()) {
			let v21 = v2.next();
			if(v == v21) {
				return i;
			}
			++i;
		}
		return -1;
	}
	static find(it,f) {
		let v = $getIterator(it);
		while(v.hasNext()) {
			let v1 = v.next();
			if(f(v1)) {
				return v1;
			}
		}
		return null;
	}
	static findIndex(it,f) {
		let i = 0;
		let v = $getIterator(it);
		while(v.hasNext()) {
			let v1 = v.next();
			if(f(v1)) {
				return i;
			}
			++i;
		}
		return -1;
	}
}
Lambda.__name__ = "Lambda";
Math.__name__ = "Math";
class Reflect {
	static field(o,field) {
		try {
			return o[field];
		} catch( _g ) {
			return null;
		}
	}
	static fields(o) {
		let a = [];
		if(o != null) {
			let hasOwnProperty = Object.prototype.hasOwnProperty;
			for( var f in o ) {
			if(f != "__id__" && f != "hx__closures__" && hasOwnProperty.call(o,f)) {
				a.push(f);
			}
			}
		}
		return a;
	}
	static compare(a,b) {
		if(a == b) {
			return 0;
		} else if(a > b) {
			return 1;
		} else {
			return -1;
		}
	}
	static isEnumValue(v) {
		if(v != null) {
			return v.__enum__ != null;
		} else {
			return false;
		}
	}
	static copy(o) {
		if(o == null) {
			return null;
		}
		let o2 = { };
		let _g = 0;
		let _g1 = Reflect.fields(o);
		while(_g < _g1.length) {
			let f = _g1[_g];
			++_g;
			o2[f] = Reflect.field(o,f);
		}
		return o2;
	}
}
Reflect.__name__ = "Reflect";
class Std {
	static string(s) {
		return js_Boot.__string_rec(s,"");
	}
	static parseInt(x) {
		let v = parseInt(x);
		if(isNaN(v)) {
			return null;
		}
		return v;
	}
	static random(x) {
		if(x <= 0) {
			return 0;
		} else {
			return Math.floor(Math.random() * x);
		}
	}
}
Std.__name__ = "Std";
class StringBuf {
	constructor() {
		this.b = "";
	}
}
StringBuf.__name__ = "StringBuf";
Object.assign(StringBuf.prototype, {
	__class__: StringBuf
});
class StringTools {
	static htmlEscape(s,quotes) {
		let buf_b = "";
		let _g_offset = 0;
		let _g_s = s;
		while(_g_offset < _g_s.length) {
			let s = _g_s;
			let index = _g_offset++;
			let c = s.charCodeAt(index);
			if(c >= 55296 && c <= 56319) {
				c = c - 55232 << 10 | s.charCodeAt(index + 1) & 1023;
			}
			let c1 = c;
			if(c1 >= 65536) {
				++_g_offset;
			}
			let 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;
	}
	static isSpace(s,pos) {
		let c = HxOverrides.cca(s,pos);
		if(!(c > 8 && c < 14)) {
			return c == 32;
		} else {
			return true;
		}
	}
	static ltrim(s) {
		let l = s.length;
		let r = 0;
		while(r < l && StringTools.isSpace(s,r)) ++r;
		if(r > 0) {
			return HxOverrides.substr(s,r,l - r);
		} else {
			return s;
		}
	}
	static rtrim(s) {
		let l = s.length;
		let 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;
		}
	}
	static trim(s) {
		return StringTools.ltrim(StringTools.rtrim(s));
	}
	static lpad(s,c,l) {
		if(c.length <= 0) {
			return s;
		}
		let 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;
	}
	static rpad(s,c,l) {
		if(c.length <= 0) {
			return s;
		}
		let buf_b = "";
		buf_b += s == null ? "null" : "" + s;
		while(buf_b.length < l) buf_b += c == null ? "null" : "" + c;
		return buf_b;
	}
	static replace(s,sub,by) {
		return s.split(sub).join(by);
	}
	static hex(n,digits) {
		let s = "";
		let hexChars = "0123456789ABCDEF";
		do {
			s = hexChars.charAt(n & 15) + s;
			n >>>= 4;
		} while(n > 0);
		if(digits != null) {
			while(s.length < digits) s = "0" + s;
		}
		return s;
	}
}
StringTools.__name__ = "StringTools";
class Type {
	static enumParameters(e) {
		let enm = $hxEnums[e.__enum__];
		let params = enm.__constructs__[e._hx_index].__params__;
		if(params != null) {
			let _g = [];
			let _g1 = 0;
			while(_g1 < params.length) {
				let p = params[_g1];
				++_g1;
				_g.push(e[p]);
			}
			return _g;
		} else {
			return [];
		}
	}
}
Type.__name__ = "Type";
class XmlType {
	static toString(this1) {
		switch(this1) {
		case 0:
			return "Element";
		case 1:
			return "PCData";
		case 2:
			return "CData";
		case 3:
			return "Comment";
		case 4:
			return "DocType";
		case 5:
			return "ProcessingInstruction";
		case 6:
			return "Document";
		}
	}
}
class Xml {
	constructor(nodeType) {
		this.nodeType = nodeType;
		this.children = [];
		this.attributeMap = new haxe_ds_StringMap();
	}
	get(att) {
		if(this.nodeType != Xml.Element) {
			throw haxe_Exception.thrown("Bad node type, expected Element but found " + (this.nodeType == null ? "null" : XmlType.toString(this.nodeType)));
		}
		return this.attributeMap.h[att];
	}
	set(att,value) {
		if(this.nodeType != Xml.Element) {
			throw haxe_Exception.thrown("Bad node type, expected Element but found " + (this.nodeType == null ? "null" : XmlType.toString(this.nodeType)));
		}
		this.attributeMap.h[att] = value;
	}
	exists(att) {
		if(this.nodeType != Xml.Element) {
			throw haxe_Exception.thrown("Bad node type, expected Element but found " + (this.nodeType == null ? "null" : XmlType.toString(this.nodeType)));
		}
		return Object.prototype.hasOwnProperty.call(this.attributeMap.h,att);
	}
	attributes() {
		if(this.nodeType != Xml.Element) {
			throw haxe_Exception.thrown("Bad node type, expected Element but found " + (this.nodeType == null ? "null" : XmlType.toString(this.nodeType)));
		}
		return new haxe_ds__$StringMap_StringMapKeyIterator(this.attributeMap.h);
	}
	firstElement() {
		if(this.nodeType != Xml.Document && this.nodeType != Xml.Element) {
			throw haxe_Exception.thrown("Bad node type, expected Element or Document but found " + (this.nodeType == null ? "null" : XmlType.toString(this.nodeType)));
		}
		let _g = 0;
		let _g1 = this.children;
		while(_g < _g1.length) {
			let child = _g1[_g];
			++_g;
			if(child.nodeType == Xml.Element) {
				return child;
			}
		}
		return null;
	}
	addChild(x) {
		if(this.nodeType != Xml.Document && this.nodeType != Xml.Element) {
			throw haxe_Exception.thrown("Bad node type, expected Element or Document but found " + (this.nodeType == null ? "null" : XmlType.toString(this.nodeType)));
		}
		if(x.parent != null) {
			x.parent.removeChild(x);
		}
		this.children.push(x);
		x.parent = this;
	}
	removeChild(x) {
		if(this.nodeType != Xml.Document && this.nodeType != Xml.Element) {
			throw haxe_Exception.thrown("Bad node type, expected Element or Document but found " + (this.nodeType == null ? "null" : XmlType.toString(this.nodeType)));
		}
		if(HxOverrides.remove(this.children,x)) {
			x.parent = null;
			return true;
		}
		return false;
	}
	toString() {
		return haxe_xml_Printer.print(this);
	}
	static parse(str) {
		return haxe_xml_Parser.parse(str);
	}
	static createElement(name) {
		let xml = new Xml(Xml.Element);
		if(xml.nodeType != Xml.Element) {
			throw haxe_Exception.thrown("Bad node type, expected Element but found " + (xml.nodeType == null ? "null" : XmlType.toString(xml.nodeType)));
		}
		xml.nodeName = name;
		return xml;
	}
	static createPCData(data) {
		let xml = new Xml(Xml.PCData);
		if(xml.nodeType == Xml.Document || xml.nodeType == Xml.Element) {
			throw haxe_Exception.thrown("Bad node type, unexpected " + (xml.nodeType == null ? "null" : XmlType.toString(xml.nodeType)));
		}
		xml.nodeValue = data;
		return xml;
	}
	static createCData(data) {
		let xml = new Xml(Xml.CData);
		if(xml.nodeType == Xml.Document || xml.nodeType == Xml.Element) {
			throw haxe_Exception.thrown("Bad node type, unexpected " + (xml.nodeType == null ? "null" : XmlType.toString(xml.nodeType)));
		}
		xml.nodeValue = data;
		return xml;
	}
	static createComment(data) {
		let xml = new Xml(Xml.Comment);
		if(xml.nodeType == Xml.Document || xml.nodeType == Xml.Element) {
			throw haxe_Exception.thrown("Bad node type, unexpected " + (xml.nodeType == null ? "null" : XmlType.toString(xml.nodeType)));
		}
		xml.nodeValue = data;
		return xml;
	}
	static createDocType(data) {
		let xml = new Xml(Xml.DocType);
		if(xml.nodeType == Xml.Document || xml.nodeType == Xml.Element) {
			throw haxe_Exception.thrown("Bad node type, unexpected " + (xml.nodeType == null ? "null" : XmlType.toString(xml.nodeType)));
		}
		xml.nodeValue = data;
		return xml;
	}
	static createProcessingInstruction(data) {
		let xml = new Xml(Xml.ProcessingInstruction);
		if(xml.nodeType == Xml.Document || xml.nodeType == Xml.Element) {
			throw haxe_Exception.thrown("Bad node type, unexpected " + (xml.nodeType == null ? "null" : XmlType.toString(xml.nodeType)));
		}
		xml.nodeValue = data;
		return xml;
	}
	static createDocument() {
		return new Xml(Xml.Document);
	}
}
Xml.__name__ = "Xml";
Object.assign(Xml.prototype, {
	__class__: Xml
});
var datetime_DTPeriod = $hxEnums["datetime.DTPeriod"] = { __ename__:true,__constructs__:null
	,Year: ($_=function(n) { return {_hx_index:0,n:n,__enum__:"datetime.DTPeriod",toString:$estr}; },$_._hx_name="Year",$_.__params__ = ["n"],$_)
	,Month: ($_=function(n) { return {_hx_index:1,n:n,__enum__:"datetime.DTPeriod",toString:$estr}; },$_._hx_name="Month",$_.__params__ = ["n"],$_)
	,Day: ($_=function(n) { return {_hx_index:2,n:n,__enum__:"datetime.DTPeriod",toString:$estr}; },$_._hx_name="Day",$_.__params__ = ["n"],$_)
	,Hour: ($_=function(n) { return {_hx_index:3,n:n,__enum__:"datetime.DTPeriod",toString:$estr}; },$_._hx_name="Hour",$_.__params__ = ["n"],$_)
	,Minute: ($_=function(n) { return {_hx_index:4,n:n,__enum__:"datetime.DTPeriod",toString:$estr}; },$_._hx_name="Minute",$_.__params__ = ["n"],$_)
	,Second: ($_=function(n) { return {_hx_index:5,n:n,__enum__:"datetime.DTPeriod",toString:$estr}; },$_._hx_name="Second",$_.__params__ = ["n"],$_)
	,Week: ($_=function(n) { return {_hx_index:6,n:n,__enum__:"datetime.DTPeriod",toString:$estr}; },$_._hx_name="Week",$_.__params__ = ["n"],$_)
};
datetime_DTPeriod.__constructs__ = [datetime_DTPeriod.Year,datetime_DTPeriod.Month,datetime_DTPeriod.Day,datetime_DTPeriod.Hour,datetime_DTPeriod.Minute,datetime_DTPeriod.Second,datetime_DTPeriod.Week];
var datetime_DTSnap = $hxEnums["datetime.DTSnap"] = { __ename__:true,__constructs__:null
	,Year: ($_=function(direction) { return {_hx_index:0,direction:direction,__enum__:"datetime.DTSnap",toString:$estr}; },$_._hx_name="Year",$_.__params__ = ["direction"],$_)
	,Month: ($_=function(direction) { return {_hx_index:1,direction:direction,__enum__:"datetime.DTSnap",toString:$estr}; },$_._hx_name="Month",$_.__params__ = ["direction"],$_)
	,Day: ($_=function(direction) { return {_hx_index:2,direction:direction,__enum__:"datetime.DTSnap",toString:$estr}; },$_._hx_name="Day",$_.__params__ = ["direction"],$_)
	,Hour: ($_=function(direction) { return {_hx_index:3,direction:direction,__enum__:"datetime.DTSnap",toString:$estr}; },$_._hx_name="Hour",$_.__params__ = ["direction"],$_)
	,Minute: ($_=function(direction) { return {_hx_index:4,direction:direction,__enum__:"datetime.DTSnap",toString:$estr}; },$_._hx_name="Minute",$_.__params__ = ["direction"],$_)
	,Second: ($_=function(direction) { return {_hx_index:5,direction:direction,__enum__:"datetime.DTSnap",toString:$estr}; },$_._hx_name="Second",$_.__params__ = ["direction"],$_)
	,Week: ($_=function(direction,day) { return {_hx_index:6,direction:direction,day:day,__enum__:"datetime.DTSnap",toString:$estr}; },$_._hx_name="Week",$_.__params__ = ["direction","day"],$_)
};
datetime_DTSnap.__constructs__ = [datetime_DTSnap.Year,datetime_DTSnap.Month,datetime_DTSnap.Day,datetime_DTSnap.Hour,datetime_DTSnap.Minute,datetime_DTSnap.Second,datetime_DTSnap.Week];
class datetime_DateTime {
	static now() {
		return Math.floor(new Date().getTime() / 1000) + 62135596800.0;
	}
	static local() {
		let utc = Math.floor(new Date().getTime() / 1000) + 62135596800.0;
		return utc - 62135596800.0 + datetime_DateTime.getLocalOffset() + 62135596800.0;
	}
	static make(year,month,day,hour,minute,second) {
		if(second == null) {
			second = 0;
		}
		if(minute == null) {
			minute = 0;
		}
		if(hour == null) {
			hour = 0;
		}
		if(day == null) {
			day = 1;
		}
		if(month == null) {
			month = 1;
		}
		if(year == null) {
			year = 1970;
		}
		return datetime_utils_DateTimeUtils.yearToStamp(year) + datetime_utils_DateTimeMonthUtils.toSeconds(month,year % 4 == 0 && (year % 100 == 0 ? year % 400 == 0 : true)) + (day - 1) * 86400 + hour * 3600 + minute * 60 + second - 62135596800.0 + 62135596800.0;
	}
	static fromTime(time) {
		return time + 62135596800.0;
	}
	static fromString(str) {
		return datetime_utils_DateTimeUtils.fromString(str);
	}
	static fromDate(date) {
		return Math.floor(date.getTime() / 1000) + 62135596800.0;
	}
	static daysInMonth(month,isLeapYear) {
		if(isLeapYear == null) {
			isLeapYear = false;
		}
		return datetime_utils_DateTimeMonthUtils.days(month,isLeapYear);
	}
	static weeksInYear(year) {
		let start = datetime_utils_DateTimeUtils.yearToStamp(year) - 62135596800.0 + 62135596800.0;
		let weekDay = datetime_DateTime.getWeekDay(start);
		if(weekDay == 4 || weekDay == 3 && datetime_DateTime.isLeapYear(start)) {
			return 53;
		} else {
			return 52;
		}
	}
	static isLeap(year) {
		if(year % 4 == 0) {
			if(year % 100 == 0) {
				return year % 400 == 0;
			} else {
				return true;
			}
		} else {
			return false;
		}
	}
	static getLocalOffset() {
		let now = new Date();
		let year = now.getFullYear();
		let month = now.getMonth() + 1;
		let day = now.getDate();
		let hour = now.getHours();
		let minute = now.getMinutes();
		let second = now.getSeconds();
		if(second == null) {
			second = 0;
		}
		if(minute == null) {
			minute = 0;
		}
		if(hour == null) {
			hour = 0;
		}
		if(day == null) {
			day = 1;
		}
		if(month == null) {
			month = 1;
		}
		if(year == null) {
			year = 1970;
		}
		let local = datetime_utils_DateTimeUtils.yearToStamp(year) + datetime_utils_DateTimeMonthUtils.toSeconds(month,year % 4 == 0 && (year % 100 == 0 ? year % 400 == 0 : true)) + (day - 1) * 86400 + hour * 3600 + minute * 60 + second - 62135596800.0 + 62135596800.0;
		return local - 62135596800.0 - (now.getTime() / 1000 | 0) | 0;
	}
	static _new(time) {
		return time + 62135596800.0;
	}
	static utc(this1) {
		return this1 - 62135596800.0 - datetime_DateTime.getLocalOffset() + 62135596800.0;
	}
	static getYear(this1) {
		let cquads = (this1 / 12622780800.0 | 0) * 12622780800.0;
		let centuries = ((this1 - cquads) / 3155673600.0 | 0) * 3155673600.0;
		if(centuries > 9467020800.) {
			centuries -= 3155673600.0;
		}
		let quads = ((this1 - cquads - centuries) / 126230400.0 | 0) * 126230400.0;
		let years = (this1 - cquads - centuries - quads) / 31536000 | 0;
		return (cquads / 12622780800.0 | 0) * 400 + (centuries / 3155673600.0 | 0) * 100 + (quads / 126230400.0 | 0) * 4 + (years == 4 ? years : years + 1);
	}
	static yearStart(this1) {
		let cquads = (this1 / 12622780800.0 | 0) * 12622780800.0;
		let centuries = ((this1 - cquads) / 3155673600.0 | 0) * 3155673600.0;
		if(centuries > 9467020800.) {
			centuries -= 3155673600.0;
		}
		let quads = ((this1 - cquads - centuries) / 126230400.0 | 0) * 126230400.0;
		let years = (this1 - cquads - centuries - quads) / 31536000 | 0;
		if(years == 4) {
			--years;
		}
		return cquads + centuries + quads + years * 31536000 - 62135596800.0;
	}
	static monthStart(this1,month) {
		if(month == null) {
			month = 0;
		}
		if(month == 0) {
			let days = ((this1 - 62135596800.0 - datetime_DateTime.yearStart(this1)) / 86400 | 0) + 1;
			month = datetime_utils_DateTimeMonthUtils.getMonth(days,datetime_DateTime.isLeapYear(this1));
		}
		return datetime_DateTime.yearStart(this1) + datetime_utils_DateTimeMonthUtils.toSeconds(month,datetime_DateTime.isLeapYear(this1));
	}
	static getMonthStart(this1,month) {
		return datetime_DateTime.monthStart(this1,month) + 62135596800.0;
	}
	static isLeapYear(this1) {
		let year = datetime_DateTime.getYear(this1);
		if(year % 4 == 0) {
			if(year % 100 == 0) {
				return year % 400 == 0;
			} else {
				return true;
			}
		} else {
			return false;
		}
	}
	static getMonth(this1) {
		let days = ((this1 - 62135596800.0 - datetime_DateTime.yearStart(this1)) / 86400 | 0) + 1;
		return datetime_utils_DateTimeMonthUtils.getMonth(days,datetime_DateTime.isLeapYear(this1));
	}
	static getDay(this1) {
		let days = ((this1 - 62135596800.0 - datetime_DateTime.yearStart(this1)) / 86400 | 0) + 1;
		return datetime_utils_DateTimeMonthUtils.getMonthDay(days,datetime_DateTime.isLeapYear(this1));
	}
	static daysInThisMonth(this1) {
		let days = ((this1 - 62135596800.0 - datetime_DateTime.yearStart(this1)) / 86400 | 0) + 1;
		let month = datetime_utils_DateTimeMonthUtils.getMonth(days,datetime_DateTime.isLeapYear(this1));
		return datetime_utils_DateTimeMonthUtils.days(month,month == 2 && datetime_DateTime.isLeapYear(this1));
	}
	static getYearDay(this1) {
		return ((this1 - 62135596800.0 - datetime_DateTime.yearStart(this1)) / 86400 | 0) + 1;
	}
	static weeksInThisYear(this1) {
		return datetime_DateTime.weeksInYear(datetime_DateTime.getYear(this1));
	}
	static getWeekDay(this1,mondayBased) {
		if(mondayBased == null) {
			mondayBased = false;
		}
		let days = ((this1 - 62135596800.0 - datetime_DateTime.yearStart(this1)) / 86400 | 0) + 1;
		let month = datetime_utils_DateTimeMonthUtils.getMonth(days,datetime_DateTime.isLeapYear(this1));
		let a = (14 - month) / 12 | 0;
		let y = datetime_DateTime.getYear(this1) - a;
		let m = month + 12 * a - 2;
		let days1 = ((this1 - 62135596800.0 - datetime_DateTime.yearStart(this1)) / 86400 | 0) + 1;
		let weekDay = (7000 + (datetime_utils_DateTimeMonthUtils.getMonthDay(days1,datetime_DateTime.isLeapYear(this1)) + y + (y / 4 | 0) - (y / 100 | 0) + (y / 400 | 0) + (31 * m / 12 | 0))) % 7;
		if(mondayBased && weekDay == 0) {
			return 7;
		} else {
			return weekDay;
		}
	}
	static getWeekDayNum(this1,weekDay,num) {
		if(num == null) {
			num = 1;
		}
		return datetime_utils_DateTimeUtils.getWeekDayNum(this1 - 62135596800.0 + 62135596800.0,weekDay,num) + 62135596800.0;
	}
	static getWeek(this1) {
		let week = (((this1 - 62135596800.0 - datetime_DateTime.yearStart(this1)) / 86400 | 0) + 1 - datetime_DateTime.getWeekDay(this1,true) + 10) / 7 | 0;
		let year = datetime_DateTime.getYear(this1);
		if(week < 1) {
			return datetime_DateTime.weeksInYear(year - 1);
		} else if(week > 52 && week > datetime_DateTime.weeksInYear(year)) {
			return 1;
		} else {
			return week;
		}
	}
	static getHour(this1) {
		return (this1 - Math.floor(this1 / 86400) * 86400) / 3600 | 0;
	}
	static getHour12(this1) {
		let hour = (this1 - Math.floor(this1 / 86400) * 86400) / 3600 | 0;
		if(hour == 0) {
			return 12;
		} else if(hour > 12) {
			return hour - 12;
		} else {
			return hour;
		}
	}
	static getMinute(this1) {
		return (this1 - Math.floor(this1 / 3600) * 3600) / 60 | 0;
	}
	static getSecond(this1) {
		return this1 - Math.floor(this1 / 60) * 60 | 0;
	}
	static add(this1,period) {
		let time;
		switch(period._hx_index) {
		case 0:
			let n = period.n;
			time = datetime_utils_DateTimeUtils.addYear(this1 - 62135596800.0 + 62135596800.0,n);
			break;
		case 1:
			let n1 = period.n;
			time = datetime_utils_DateTimeUtils.addMonth(this1 - 62135596800.0 + 62135596800.0,n1);
			break;
		case 2:
			let n2 = period.n;
			time = this1 - 62135596800.0 + n2 * 86400;
			break;
		case 3:
			let n3 = period.n;
			time = this1 - 62135596800.0 + n3 * 3600;
			break;
		case 4:
			let n4 = period.n;
			time = this1 - 62135596800.0 + n4 * 60;
			break;
		case 5:
			let n5 = period.n;
			time = this1 - 62135596800.0 + n5;
			break;
		case 6:
			let n6 = period.n;
			time = this1 - 62135596800.0 + n6 * 7 * 86400;
			break;
		}
		return time + 62135596800.0;
	}
	static sub(this1,period) {
		let time;
		switch(period._hx_index) {
		case 0:
			let n = period.n;
			time = datetime_utils_DateTimeUtils.addYear(this1 - 62135596800.0 + 62135596800.0,-n);
			break;
		case 1:
			let n1 = period.n;
			time = datetime_utils_DateTimeUtils.addMonth(this1 - 62135596800.0 + 62135596800.0,-n1);
			break;
		case 2:
			let n2 = period.n;
			time = this1 - 62135596800.0 - n2 * 86400;
			break;
		case 3:
			let n3 = period.n;
			time = this1 - 62135596800.0 - n3 * 3600;
			break;
		case 4:
			let n4 = period.n;
			time = this1 - 62135596800.0 - n4 * 60;
			break;
		case 5:
			let n5 = period.n;
			time = this1 - 62135596800.0 - n5;
			break;
		case 6:
			let n6 = period.n;
			time = this1 - 62135596800.0 - n6 * 7 * 86400;
			break;
		}
		return time + 62135596800.0;
	}
	static snap(this1,period) {
		let time;
		switch(period._hx_index) {
		case 0:
			let d = period.direction;
			time = datetime_utils_DateTimeSnapUtils.snapYear(this1 - 62135596800.0 + 62135596800.0,d);
			break;
		case 1:
			let d1 = period.direction;
			time = datetime_utils_DateTimeSnapUtils.snapMonth(this1 - 62135596800.0 + 62135596800.0,d1);
			break;
		case 2:
			let d2 = period.direction;
			time = datetime_utils_DateTimeSnapUtils.snapDay(this1 - 62135596800.0 + 62135596800.0,d2);
			break;
		case 3:
			let d3 = period.direction;
			time = datetime_utils_DateTimeSnapUtils.snapHour(this1 - 62135596800.0 + 62135596800.0,d3);
			break;
		case 4:
			let d4 = period.direction;
			time = datetime_utils_DateTimeSnapUtils.snapMinute(this1 - 62135596800.0 + 62135596800.0,d4);
			break;
		case 5:
			let d5 = period.direction;
			time = d5 == 1 ? this1 - 62135596800.0 + 1 : this1 - 62135596800.0;
			break;
		case 6:
			let d6 = period.direction;
			let day = period.day;
			time = datetime_utils_DateTimeSnapUtils.snapWeek(this1 - 62135596800.0 + 62135596800.0,d6,day);
			break;
		}
		return time + 62135596800.0;
	}
	static toString(this1) {
		let Y = datetime_DateTime.getYear(this1);
		let days = ((this1 - 62135596800.0 - datetime_DateTime.yearStart(this1)) / 86400 | 0) + 1;
		let M = datetime_utils_DateTimeMonthUtils.getMonth(days,datetime_DateTime.isLeapYear(this1));
		let days1 = ((this1 - 62135596800.0 - datetime_DateTime.yearStart(this1)) / 86400 | 0) + 1;
		let D = datetime_utils_DateTimeMonthUtils.getMonthDay(days1,datetime_DateTime.isLeapYear(this1));
		let h = (this1 - Math.floor(this1 / 86400) * 86400) / 3600 | 0;
		let m = (this1 - Math.floor(this1 / 3600) * 3600) / 60 | 0;
		let s = this1 - Math.floor(this1 / 60) * 60 | 0;
		return "" + Y + "-" + (M < 10 ? "0" + M : "" + M) + "-" + (D < 10 ? "0" + D : "" + D) + " " + (h < 10 ? "0" + h : "" + h) + ":" + (m < 10 ? "0" + m : "" + m) + ":" + (s < 10 ? "0" + s : "" + s);
	}
	static format(this1,format) {
		return datetime_utils_DateTimeUtils.strftime(this1 - 62135596800.0 + 62135596800.0,format);
	}
	static getTime(this1) {
		return this1 - 62135596800.0;
	}
	static getDate(this1) {
		return new Date((this1 - 62135596800.0) * 1000);
	}
	static gt(this1,dt) {
		return this1 - 62135596800.0 > dt - 62135596800.0;
	}
	static gte(this1,dt) {
		return this1 - 62135596800.0 >= dt - 62135596800.0;
	}
	static lt(this1,dt) {
		return this1 - 62135596800.0 < dt - 62135596800.0;
	}
	static lte(this1,dt) {
		return this1 - 62135596800.0 <= dt - 62135596800.0;
	}
	static eq(this1,dt) {
		return this1 - 62135596800.0 == dt - 62135596800.0;
	}
	static neq(this1,dt) {
		return this1 - 62135596800.0 != dt - 62135596800.0;
	}
	static mathPlus1(this1,period) {
		return datetime_DateTime.add(this1,period);
	}
	static mathPlus2(this1,period) {
		return datetime_DateTime.add(this1,period);
	}
	static mathPlus3(this1,period) {
		this1 = datetime_DateTime.add(this1,period) - 62135596800.0 + 62135596800.0;
		return this1 + 62135596800.0;
	}
	static mathMinus1(this1,period) {
		return datetime_DateTime.sub(this1,period);
	}
	static mathMinus2(this1,period) {
		this1 = datetime_DateTime.sub(this1,period) - 62135596800.0 + 62135596800.0;
		return this1 + 62135596800.0;
	}
	static dtiCreate(this1,begin) {
		return datetime_DateTimeInterval.create(begin,this1 - 62135596800.0 + 62135596800.0);
	}
	static dtiMinus(this1,dti) {
		return datetime_DateTimeInterval.subFrom(dti,this1 - 62135596800.0 + 62135596800.0);
	}
	static dtiPlus1(this1,dti) {
		return datetime_DateTimeInterval.addTo(dti,this1 - 62135596800.0 + 62135596800.0);
	}
	static dtiPlus2(this1,dti) {
		return datetime_DateTimeInterval.addTo(dti,this1 - 62135596800.0 + 62135596800.0);
	}
	static dtiMinus2(this1,dti) {
		this1 = datetime_DateTimeInterval.subFrom(dti,this1 - 62135596800.0 + 62135596800.0) - 62135596800.0 + 62135596800.0;
		return this1 + 62135596800.0;
	}
	static dtiPlus3(this1,dti) {
		this1 = datetime_DateTimeInterval.addTo(dti,this1 - 62135596800.0 + 62135596800.0) - 62135596800.0 + 62135596800.0;
		return this1 + 62135596800.0;
	}
}
class datetime_DateTimeInterval {
	static create(begin,end) {
		let dtic = new datetime_cores_DateTimeIntervalCore();
		dtic.begin = end - 62135596800.0 < begin - 62135596800.0 ? end : begin;
		dtic.end = end - 62135596800.0 < begin - 62135596800.0 ? begin : end;
		dtic.negative = end - 62135596800.0 < begin - 62135596800.0;
		return dtic;
	}
	static _new(dtic) {
		return dtic;
	}
	static invert(this1) {
		this1.negative = !this1.negative;
		return this1;
	}
	static addTo(this1,dt) {
		return dt - 62135596800.0 + (this1.negative ? -1 : 1) * (this1.end - 62135596800.0 - (this1.begin - 62135596800.0)) + 62135596800.0;
	}
	static subFrom(this1,dt) {
		return dt - 62135596800.0 - (this1.negative ? -1 : 1) * (this1.end - 62135596800.0 - (this1.begin - 62135596800.0)) + 62135596800.0;
	}
	static toString(this1) {
		let years = this1.getYears();
		let months = this1.getMonths();
		let days = this1.getDays();
		let hours = this1.getHours();
		let minutes = this1.getMinutes();
		let seconds = this1.getSeconds();
		let parts = [];
		if(years != 0) {
			parts.push("" + years + "y");
		}
		if(months != 0) {
			parts.push("" + months + "m");
		}
		if(days != 0) {
			parts.push("" + days + "d");
		}
		if(hours != 0) {
			parts.push("" + hours + "hrs");
		}
		if(minutes != 0) {
			parts.push("" + minutes + "min");
		}
		if(seconds != 0) {
			parts.push("" + seconds + "sec");
		}
		return (this1.negative ? "-" : "") + "(" + (parts.length == 0 ? "0sec" : parts.join(", ")) + ")";
	}
	static sign(this1) {
		if(this1.negative) {
			return -1;
		} else {
			return 1;
		}
	}
	static format(this1,format) {
		return datetime_utils_DateTimeIntervalUtils.strftime(this1,format);
	}
	static formatPartial(this1,format) {
		return datetime_utils_DateTimeIntervalUtils.formatPartial(this1,format);
	}
	static eq(this1,dtic) {
		if(this1.negative == dtic.negative) {
			return this1.getTotalSeconds() == dtic.getTotalSeconds();
		} else {
			return false;
		}
	}
	static gt(this1,dtic) {
		if(this1.negative != dtic.negative) {
			return dtic.negative;
		}
		let delta = this1.getTotalSeconds() - dtic.getTotalSeconds();
		if(this1.negative) {
			return delta < 0;
		} else {
			return delta > 0;
		}
	}
	static gte(this1,dtic) {
		if(!(this1.negative == dtic.negative && this1.getTotalSeconds() == dtic.getTotalSeconds())) {
			if(this1.negative != dtic.negative) {
				return dtic.negative;
			} else {
				let delta = this1.getTotalSeconds() - dtic.getTotalSeconds();
				if(this1.negative) {
					return delta < 0;
				} else {
					return delta > 0;
				}
			}
		} else {
			return true;
		}
	}
	static lt(this1,dtic) {
		let tmp;
		if(!(this1.negative == dtic.negative && this1.getTotalSeconds() == dtic.getTotalSeconds())) {
			if(this1.negative != dtic.negative) {
				tmp = dtic.negative;
			} else {
				let delta = this1.getTotalSeconds() - dtic.getTotalSeconds();
				tmp = this1.negative ? delta < 0 : delta > 0;
			}
		} else {
			tmp = true;
		}
		return !tmp;
	}
	static lte(this1,dtic) {
		let tmp;
		if(this1.negative != dtic.negative) {
			tmp = dtic.negative;
		} else {
			let delta = this1.getTotalSeconds() - dtic.getTotalSeconds();
			tmp = this1.negative ? delta < 0 : delta > 0;
		}
		return !tmp;
	}
	static neq(this1,dtic) {
		return !(this1.negative == dtic.negative && this1.getTotalSeconds() == dtic.getTotalSeconds());
	}
}
class datetime_cores_DateTimeIntervalCore {
	constructor() {
		this.seconds = -1;
		this.minutes = -1;
		this.hours = -1;
		this.days = -1;
		this.months = -1;
		this.years = -1;
		this.negative = false;
	}
	getYears() {
		if(this.years < 0) {
			this.years = datetime_DateTime.getYear(this.end) - datetime_DateTime.getYear(this.begin);
			let this1 = this.begin;
			let days = ((this1 - 62135596800.0 - datetime_DateTime.yearStart(this1)) / 86400 | 0) + 1;
			let m1 = datetime_utils_DateTimeMonthUtils.getMonth(days,datetime_DateTime.isLeapYear(this1));
			let this2 = this.end;
			let days1 = ((this2 - 62135596800.0 - datetime_DateTime.yearStart(this2)) / 86400 | 0) + 1;
			let m2 = datetime_utils_DateTimeMonthUtils.getMonth(days1,datetime_DateTime.isLeapYear(this2));
			if(m2 < m1) {
				this.years--;
			} else if(m1 == m2) {
				let this1 = this.begin;
				let days = ((this1 - 62135596800.0 - datetime_DateTime.yearStart(this1)) / 86400 | 0) + 1;
				let d1 = datetime_utils_DateTimeMonthUtils.getMonthDay(days,datetime_DateTime.isLeapYear(this1));
				let this2 = this.end;
				let days1 = ((this2 - 62135596800.0 - datetime_DateTime.yearStart(this2)) / 86400 | 0) + 1;
				let d2 = datetime_utils_DateTimeMonthUtils.getMonthDay(days1,datetime_DateTime.isLeapYear(this2));
				if(d2 < d1) {
					this.years--;
				} else if(d1 == d2) {
					let this1 = this.begin;
					let h1 = (this1 - Math.floor(this1 / 86400) * 86400) / 3600 | 0;
					let this2 = this.end;
					let h2 = (this2 - Math.floor(this2 / 86400) * 86400) / 3600 | 0;
					if(h2 < h1) {
						this.years--;
					} else if(h2 == h1) {
						let this1 = this.begin;
						let m1 = (this1 - Math.floor(this1 / 3600) * 3600) / 60 | 0;
						let this2 = this.end;
						let m2 = (this2 - Math.floor(this2 / 3600) * 3600) / 60 | 0;
						if(m2 < m1) {
							this.years--;
						} else {
							let tmp;
							if(m2 == m1) {
								let this1 = this.end;
								let this2 = this.begin;
								tmp = (this1 - Math.floor(this1 / 60) * 60 | 0) < (this2 - Math.floor(this2 / 60) * 60 | 0);
							} else {
								tmp = false;
							}
							if(tmp) {
								this.years--;
							}
						}
					}
				}
			}
		}
		return this.years;
	}
	getMonths() {
		if(this.months < 0) {
			let this1 = this.begin;
			let days = ((this1 - 62135596800.0 - datetime_DateTime.yearStart(this1)) / 86400 | 0) + 1;
			let monthBegin = datetime_utils_DateTimeMonthUtils.getMonth(days,datetime_DateTime.isLeapYear(this1));
			let this2 = this.end;
			let days1 = ((this2 - 62135596800.0 - datetime_DateTime.yearStart(this2)) / 86400 | 0) + 1;
			let monthEnd = datetime_utils_DateTimeMonthUtils.getMonth(days1,datetime_DateTime.isLeapYear(this2));
			this.months = monthBegin <= monthEnd ? monthEnd - monthBegin : 12 - monthBegin + monthEnd;
			let this3 = this.begin;
			let days2 = ((this3 - 62135596800.0 - datetime_DateTime.yearStart(this3)) / 86400 | 0) + 1;
			let d1 = datetime_utils_DateTimeMonthUtils.getMonthDay(days2,datetime_DateTime.isLeapYear(this3));
			let this4 = this.end;
			let days3 = ((this4 - 62135596800.0 - datetime_DateTime.yearStart(this4)) / 86400 | 0) + 1;
			let d2 = datetime_utils_DateTimeMonthUtils.getMonthDay(days3,datetime_DateTime.isLeapYear(this4));
			if(d2 < d1) {
				this.months--;
			} else if(d1 == d2) {
				let this1 = this.begin;
				let h1 = (this1 - Math.floor(this1 / 86400) * 86400) / 3600 | 0;
				let this2 = this.end;
				let h2 = (this2 - Math.floor(this2 / 86400) * 86400) / 3600 | 0;
				if(h2 < h1) {
					this.months--;
				} else if(h2 == h1) {
					let this1 = this.begin;
					let m1 = (this1 - Math.floor(this1 / 3600) * 3600) / 60 | 0;
					let this2 = this.end;
					let m2 = (this2 - Math.floor(this2 / 3600) * 3600) / 60 | 0;
					if(m2 < m1) {
						this.months--;
					} else {
						let tmp;
						if(m2 == m1) {
							let this1 = this.end;
							let this2 = this.begin;
							tmp = (this1 - Math.floor(this1 / 60) * 60 | 0) < (this2 - Math.floor(this2 / 60) * 60 | 0);
						} else {
							tmp = false;
						}
						if(tmp) {
							this.months--;
						}
					}
				}
			}
		}
		return this.months;
	}
	getTotalMonths() {
		return this.getYears() * 12 + this.getMonths();
	}
	getDays() {
		if(this.days < 0) {
			let this1 = this.begin;
			let days = ((this1 - 62135596800.0 - datetime_DateTime.yearStart(this1)) / 86400 | 0) + 1;
			let dayBegin = datetime_utils_DateTimeMonthUtils.getMonthDay(days,datetime_DateTime.isLeapYear(this1));
			let this2 = this.end;
			let days1 = ((this2 - 62135596800.0 - datetime_DateTime.yearStart(this2)) / 86400 | 0) + 1;
			let dayEnd = datetime_utils_DateTimeMonthUtils.getMonthDay(days1,datetime_DateTime.isLeapYear(this2));
			let tmp;
			if(dayBegin <= dayEnd) {
				tmp = dayEnd - dayBegin;
			} else {
				let this1 = this.begin;
				let days = ((this1 - 62135596800.0 - datetime_DateTime.yearStart(this1)) / 86400 | 0) + 1;
				tmp = datetime_utils_DateTimeMonthUtils.days(datetime_utils_DateTimeMonthUtils.getMonth(days,datetime_DateTime.isLeapYear(this1)),datetime_DateTime.isLeapYear(this.begin)) - dayBegin + dayEnd;
			}
			this.days = tmp;
			let this3 = this.begin;
			let h1 = (this3 - Math.floor(this3 / 86400) * 86400) / 3600 | 0;
			let this4 = this.end;
			let h2 = (this4 - Math.floor(this4 / 86400) * 86400) / 3600 | 0;
			if(h2 < h1) {
				this.days--;
			} else if(h2 == h1) {
				let this1 = this.begin;
				let m1 = (this1 - Math.floor(this1 / 3600) * 3600) / 60 | 0;
				let this2 = this.end;
				let m2 = (this2 - Math.floor(this2 / 3600) * 3600) / 60 | 0;
				if(m2 < m1) {
					this.days--;
				} else {
					let tmp;
					if(m2 == m1) {
						let this1 = this.end;
						let this2 = this.begin;
						tmp = (this1 - Math.floor(this1 / 60) * 60 | 0) < (this2 - Math.floor(this2 / 60) * 60 | 0);
					} else {
						tmp = false;
					}
					if(tmp) {
						this.days--;
					}
				}
			}
		}
		return this.days;
	}
	getTotalDays() {
		return (this.end - 62135596800.0 - (this.begin - 62135596800.0)) / 86400 | 0;
	}
	getHours() {
		if(this.hours < 0) {
			let this1 = this.begin;
			let hourBegin = (this1 - Math.floor(this1 / 86400) * 86400) / 3600 | 0;
			let this2 = this.end;
			let hourEnd = (this2 - Math.floor(this2 / 86400) * 86400) / 3600 | 0;
			this.hours = hourBegin <= hourEnd ? hourEnd - hourBegin : 24 - hourBegin + hourEnd;
			let this3 = this.begin;
			let m1 = (this3 - Math.floor(this3 / 3600) * 3600) / 60 | 0;
			let this4 = this.end;
			let m2 = (this4 - Math.floor(this4 / 3600) * 3600) / 60 | 0;
			if(m2 < m1) {
				this.hours--;
			} else {
				let tmp;
				if(m2 == m1) {
					let this1 = this.end;
					let this2 = this.begin;
					tmp = (this1 - Math.floor(this1 / 60) * 60 | 0) < (this2 - Math.floor(this2 / 60) * 60 | 0);
				} else {
					tmp = false;
				}
				if(tmp) {
					this.hours--;
				}
			}
		}
		return this.hours;
	}
	getTotalHours() {
		return (this.end - 62135596800.0 - (this.begin - 62135596800.0)) / 3600 | 0;
	}
	getMinutes() {
		if(this.minutes < 0) {
			let this1 = this.begin;
			let minuteBegin = (this1 - Math.floor(this1 / 3600) * 3600) / 60 | 0;
			let this2 = this.end;
			let minuteEnd = (this2 - Math.floor(this2 / 3600) * 3600) / 60 | 0;
			this.minutes = minuteBegin <= minuteEnd ? minuteEnd - minuteBegin : 60 - minuteBegin + minuteEnd;
			let this3 = this.end;
			let this4 = this.begin;
			if((this3 - Math.floor(this3 / 60) * 60 | 0) < (this4 - Math.floor(this4 / 60) * 60 | 0)) {
				this.minutes--;
			}
		}
		return this.minutes;
	}
	getTotalMinutes() {
		return (this.end - 62135596800.0 - (this.begin - 62135596800.0)) / 60 | 0;
	}
	getSeconds() {
		if(this.seconds < 0) {
			let this1 = this.begin;
			let secondBegin = this1 - Math.floor(this1 / 60) * 60 | 0;
			let this2 = this.end;
			let secondEnd = this2 - Math.floor(this2 / 60) * 60 | 0;
			this.seconds = secondBegin <= secondEnd ? secondEnd - secondBegin : 60 - secondBegin + secondEnd;
		}
		return this.seconds;
	}
	getTotalSeconds() {
		return this.end - 62135596800.0 - (this.begin - 62135596800.0);
	}
	getTotalWeeks() {
		return (this.end - 62135596800.0 - (this.begin - 62135596800.0)) / 604800 | 0;
	}
}
datetime_cores_DateTimeIntervalCore.__name__ = "datetime.cores.DateTimeIntervalCore";
Object.assign(datetime_cores_DateTimeIntervalCore.prototype, {
	__class__: datetime_cores_DateTimeIntervalCore
});
class datetime_utils_DateTimeIntervalUtils {
	constructor() {
	}
	static strftime(dti,format) {
		let prevPos = 0;
		let pos = format.indexOf("%");
		let str = "";
		while(pos >= 0) {
			str += format.substring(prevPos,pos);
			++pos;
			switch(format.charCodeAt(pos)) {
			case 37:
				str += "%";
				break;
			case 68:
				str += StringTools.lpad(dti.getDays() + "","0",2);
				break;
			case 72:
				str += StringTools.lpad(dti.getHours() + "","0",2);
				break;
			case 73:
				str += StringTools.lpad(dti.getMinutes() + "","0",2);
				break;
			case 77:
				str += StringTools.lpad(dti.getMonths() + "","0",2);
				break;
			case 82:
				str += dti.negative ? "-" : "+";
				break;
			case 83:
				str += StringTools.lpad(dti.getSeconds() + "","0",2);
				break;
			case 89:
				str += StringTools.lpad(dti.getYears() + "","0",2);
				break;
			case 97:
				str += dti.getTotalDays() + "";
				break;
			case 98:
				str += dti.getTotalMonths() + "";
				break;
			case 99:
				str += dti.getTotalHours() + "";
				break;
			case 100:
				str += dti.getDays() + "";
				break;
			case 101:
				str += dti.getTotalMinutes() + "";
				break;
			case 102:
				str += dti.getTotalSeconds() + "";
				break;
			case 104:
				str += dti.getHours() + "";
				break;
			case 105:
				str += dti.getMinutes() + "";
				break;
			case 109:
				str += dti.getMonths() + "";
				break;
			case 114:
				str += dti.negative ? "-" : "";
				break;
			case 115:
				str += dti.getSeconds() + "";
				break;
			case 121:
				str += dti.getYears() + "";
				break;
			}
			prevPos = pos + 1;
			pos = format.indexOf("%",pos + 1);
		}
		str += format.substring(prevPos);
		return str;
	}
	static formatPartial(dti,format) {
		let result = [];
		let pos = 0;
		let str = "";
		let _g = 0;
		let _g1 = format.length;
		while(_g < _g1) {
			let f = _g++;
			pos = format[f].indexOf("%");
			if(pos >= 0) {
				switch(format[f].charCodeAt(pos + 1)) {
				case 68:
					if(dti.getDays() == 0) {
						continue;
					}
					str = format[f].substring(0,pos) + StringTools.lpad(dti.getDays() + "","0",2) + format[f].substring(pos + 2);
					break;
				case 72:
					if(dti.getHours() == 0) {
						continue;
					}
					str = format[f].substring(0,pos) + StringTools.lpad(dti.getHours() + "","0",2) + format[f].substring(pos + 2);
					break;
				case 73:
					if(dti.getMinutes() == 0) {
						continue;
					}
					str = format[f].substring(0,pos) + StringTools.lpad(dti.getMinutes() + "","0",2) + format[f].substring(pos + 2);
					break;
				case 77:
					if(dti.getMonths() == 0) {
						continue;
					}
					str = format[f].substring(0,pos) + StringTools.lpad(dti.getMonths() + "","0",2) + format[f].substring(pos + 2);
					break;
				case 83:
					if(dti.getSeconds() == 0) {
						continue;
					}
					str = format[f].substring(0,pos) + StringTools.lpad(dti.getSeconds() + "","0",2) + format[f].substring(pos + 2);
					break;
				case 89:
					if(dti.getYears() == 0) {
						continue;
					}
					str = format[f].substring(0,pos) + StringTools.lpad(dti.getYears() + "","0",2) + format[f].substring(pos + 2);
					break;
				case 97:
					if(dti.getTotalDays() == 0) {
						continue;
					}
					str = format[f].substring(0,pos) + dti.getTotalDays() + format[f].substring(pos + 2);
					break;
				case 98:
					if(dti.getTotalMonths() == 0) {
						continue;
					}
					str = format[f].substring(0,pos) + dti.getTotalMonths() + format[f].substring(pos + 2);
					break;
				case 99:
					if(dti.getTotalHours() == 0) {
						continue;
					}
					str = format[f].substring(0,pos) + dti.getTotalHours() + format[f].substring(pos + 2);
					break;
				case 100:
					if(dti.getDays() == 0) {
						continue;
					}
					str = format[f].substring(0,pos) + dti.getDays() + format[f].substring(pos + 2);
					break;
				case 101:
					if(dti.getTotalMinutes() == 0) {
						continue;
					}
					str = format[f].substring(0,pos) + dti.getTotalMinutes() + format[f].substring(pos + 2);
					break;
				case 102:
					if(dti.getTotalSeconds() == 0) {
						continue;
					}
					str = format[f].substring(0,pos) + dti.getTotalSeconds() + format[f].substring(pos + 2);
					break;
				case 104:
					if(dti.getHours() == 0) {
						continue;
					}
					str = format[f].substring(0,pos) + dti.getHours() + format[f].substring(pos + 2);
					break;
				case 105:
					if(dti.getMinutes() == 0) {
						continue;
					}
					str = format[f].substring(0,pos) + dti.getMinutes() + format[f].substring(pos + 2);
					break;
				case 109:
					if(dti.getMonths() == 0) {
						continue;
					}
					str = format[f].substring(0,pos) + dti.getMonths() + format[f].substring(pos + 2);
					break;
				case 115:
					if(dti.getSeconds() == 0) {
						continue;
					}
					str = format[f].substring(0,pos) + dti.getSeconds() + format[f].substring(pos + 2);
					break;
				case 121:
					if(dti.getYears() == 0) {
						continue;
					}
					str = format[f].substring(0,pos) + dti.getYears() + format[f].substring(pos + 2);
					break;
				default:
					continue;
				}
				result.push(str);
			}
		}
		return result;
	}
}
datetime_utils_DateTimeIntervalUtils.__name__ = "datetime.utils.DateTimeIntervalUtils";
Object.assign(datetime_utils_DateTimeIntervalUtils.prototype, {
	__class__: datetime_utils_DateTimeIntervalUtils
});
class datetime_utils_DateTimeMonthUtils {
	constructor() {
	}
	static days(month,isLeapYear) {
		if(isLeapYear == null) {
			isLeapYear = false;
		}
		if(month == 1) {
			return 31;
		} else if(month == 2 && isLeapYear) {
			return 29;
		} else if(month == 2) {
			return 28;
		} else if(month == 3) {
			return 31;
		} else if(month == 4) {
			return 30;
		} else if(month == 5) {
			return 31;
		} else if(month == 6) {
			return 30;
		} else if(month == 7) {
			return 31;
		} else if(month == 8) {
			return 31;
		} else if(month == 9) {
			return 30;
		} else if(month == 10) {
			return 31;
		} else if(month == 11) {
			return 30;
		} else {
			return 31;
		}
	}
	static getMonth(days,isLeapYear) {
		if(isLeapYear == null) {
			isLeapYear = false;
		}
		if(days < 32) {
			return 1;
		} else if(isLeapYear) {
			if(days < 61) {
				return 2;
			} else if(days < 92) {
				return 3;
			} else if(days < 122) {
				return 4;
			} else if(days < 153) {
				return 5;
			} else if(days < 183) {
				return 6;
			} else if(days < 214) {
				return 7;
			} else if(days < 245) {
				return 8;
			} else if(days < 275) {
				return 9;
			} else if(days < 306) {
				return 10;
			} else if(days < 336) {
				return 11;
			} else {
				return 12;
			}
		} else if(days < 60) {
			return 2;
		} else if(days < 91) {
			return 3;
		} else if(days < 121) {
			return 4;
		} else if(days < 152) {
			return 5;
		} else if(days < 182) {
			return 6;
		} else if(days < 213) {
			return 7;
		} else if(days < 244) {
			return 8;
		} else if(days < 274) {
			return 9;
		} else if(days < 305) {
			return 10;
		} else if(days < 335) {
			return 11;
		} else {
			return 12;
		}
	}
	static getMonthDay(days,isLeapYear) {
		if(isLeapYear == null) {
			isLeapYear = false;
		}
		if(days < 32) {
			return days;
		} else if(isLeapYear) {
			if(days < 61) {
				return days - 31;
			} else if(days < 92) {
				return days - 60;
			} else if(days < 122) {
				return days - 91;
			} else if(days < 153) {
				return days - 121;
			} else if(days < 183) {
				return days - 152;
			} else if(days < 214) {
				return days - 182;
			} else if(days < 245) {
				return days - 213;
			} else if(days < 275) {
				return days - 244;
			} else if(days < 306) {
				return days - 274;
			} else if(days < 336) {
				return days - 305;
			} else {
				return days - 335;
			}
		} else if(days < 60) {
			return days - 31;
		} else if(days < 91) {
			return days - 59;
		} else if(days < 121) {
			return days - 90;
		} else if(days < 152) {
			return days - 120;
		} else if(days < 182) {
			return days - 151;
		} else if(days < 213) {
			return days - 181;
		} else if(days < 244) {
			return days - 212;
		} else if(days < 274) {
			return days - 243;
		} else if(days < 305) {
			return days - 273;
		} else if(days < 335) {
			return days - 304;
		} else {
			return days - 334;
		}
	}
	static toSeconds(month,isLeapYear) {
		if(isLeapYear == null) {
			isLeapYear = false;
		}
		return 86400 * (month == 1 ? 0 : isLeapYear ? month == 2 ? 31 : month == 3 ? 60 : month == 4 ? 91 : month == 5 ? 121 : month == 6 ? 152 : month == 7 ? 182 : month == 8 ? 213 : month == 9 ? 244 : month == 10 ? 274 : month == 11 ? 305 : 335 : month == 2 ? 31 : month == 3 ? 59 : month == 4 ? 90 : month == 5 ? 120 : month == 6 ? 151 : month == 7 ? 181 : month == 8 ? 212 : month == 9 ? 243 : month == 10 ? 273 : month == 11 ? 304 : 334);
	}
}
datetime_utils_DateTimeMonthUtils.__name__ = "datetime.utils.DateTimeMonthUtils";
Object.assign(datetime_utils_DateTimeMonthUtils.prototype, {
	__class__: datetime_utils_DateTimeMonthUtils
});
class datetime_utils_DateTimeSnapUtils {
	constructor() {
	}
	static snapYear(dt,direction) {
		switch(direction) {
		case -1:
			return datetime_DateTime.yearStart(dt);
		case 0:
			let next = datetime_DateTime.yearStart(datetime_utils_DateTimeUtils.addYear(dt,1) + 62135596800.0);
			let previous = datetime_DateTime.yearStart(dt);
			if(next - (dt - 62135596800.0) > dt - 62135596800.0 - previous) {
				return previous;
			} else {
				return next;
			}
			break;
		case 1:
			let next1 = datetime_utils_DateTimeUtils.addYear(dt,1) + 62135596800.0;
			return datetime_DateTime.yearStart(next1);
		}
	}
	static snapMonth(dt,direction) {
		let days = ((dt - 62135596800.0 - datetime_DateTime.yearStart(dt)) / 86400 | 0) + 1;
		let month = datetime_utils_DateTimeMonthUtils.getMonth(days,datetime_DateTime.isLeapYear(dt));
		let isLeap = datetime_DateTime.isLeapYear(dt);
		switch(direction) {
		case -1:
			return datetime_DateTime.yearStart(dt) + datetime_utils_DateTimeMonthUtils.toSeconds(month,isLeap);
		case 0:
			let previous = datetime_DateTime.yearStart(dt) + datetime_utils_DateTimeMonthUtils.toSeconds(month,isLeap);
			let next = datetime_DateTime.yearStart(dt) + datetime_utils_DateTimeMonthUtils.toSeconds(month,isLeap) + datetime_utils_DateTimeMonthUtils.days(month,isLeap) * 86400;
			if(next - (dt - 62135596800.0) > dt - 62135596800.0 - previous) {
				return previous;
			} else {
				return next;
			}
			break;
		case 1:
			return datetime_DateTime.yearStart(dt) + datetime_utils_DateTimeMonthUtils.toSeconds(month,isLeap) + datetime_utils_DateTimeMonthUtils.days(month,isLeap) * 86400;
		}
	}
	static snapDay(dt,direction) {
		let days = (dt - 62135596800.0) / 86400;
		switch(direction) {
		case -1:
			return Math.floor(days) * 86400;
		case 0:
			return Math.round(days) * 86400;
		case 1:
			return Math.ceil(days) * 86400;
		}
	}
	static snapHour(dt,direction) {
		let hours = (dt - 62135596800.0) / 3600;
		switch(direction) {
		case -1:
			return Math.floor(hours) * 3600;
		case 0:
			return Math.round(hours) * 3600;
		case 1:
			return Math.ceil(hours) * 3600;
		}
	}
	static snapMinute(dt,direction) {
		let minutes = (dt - 62135596800.0) / 60;
		switch(direction) {
		case -1:
			return Math.floor(minutes) * 60;
		case 0:
			return Math.round(minutes) * 60;
		case 1:
			return Math.ceil(minutes) * 60;
		}
	}
	static snapWeek(dt,direction,required) {
		let current = datetime_DateTime.getWeekDay(dt);
		let days = Math.floor((dt - 62135596800.0) / 86400);
		switch(direction) {
		case -1:
			let diff = current >= required ? current - required : current + 7 - required;
			return (days - diff) * 86400;
		case 0:
			let diff1 = current >= required ? current - required : current + 7 - required;
			let previous = (days - diff1) * 86400;
			let diff2 = required > current ? required - current : required + 7 - current;
			let next = (days + diff2) * 86400;
			if(next - (dt - 62135596800.0) > dt - 62135596800.0 - previous) {
				return previous;
			} else {
				return next;
			}
			break;
		case 1:
			let diff3 = required > current ? required - current : required + 7 - current;
			return (days + diff3) * 86400;
		}
	}
}
datetime_utils_DateTimeSnapUtils.__name__ = "datetime.utils.DateTimeSnapUtils";
Object.assign(datetime_utils_DateTimeSnapUtils.prototype, {
	__class__: datetime_utils_DateTimeSnapUtils
});
class datetime_utils_DateTimeUtils {
	constructor() {
	}
	static fromString(str) {
		if(str.length == 10 || str.charCodeAt(10) == 32) {
			return datetime_utils_DateTimeUtils.parse(str);
		} else if(str.charCodeAt(10) == 84) {
			return datetime_utils_DateTimeUtils.fromIsoString(str);
		} else {
			throw haxe_Exception.thrown("`" + str + "` - incorrect date/time format. Should be either `YYYY-MM-DD hh:mm:ss` or `YYYY-MM-DD` or `YYYY-MM-DDThh:mm:ss[.SSS]Z`");
		}
	}
	static parse(str) {
		let ylength = str.indexOf("-");
		if(ylength < 1 || str.length - ylength != 6 && str.length - ylength != 15) {
			throw haxe_Exception.thrown("`" + str + "` - incorrect date/time format. Should be either `YYYY-MM-DD hh:mm:ss` or `YYYY-MM-DD`");
		}
		if(str.length - ylength == 6) {
			str += " 00:00:00";
		}
		let year = Std.parseInt(HxOverrides.substr(str,0,ylength));
		let month = Std.parseInt(HxOverrides.substr(str,ylength + 1,2));
		let day = Std.parseInt(HxOverrides.substr(str,ylength + 4,2));
		let hour = Std.parseInt(HxOverrides.substr(str,ylength + 7,2));
		let minute = Std.parseInt(HxOverrides.substr(str,ylength + 10,2));
		let second = Std.parseInt(HxOverrides.substr(str,ylength + 13,2));
		if(year == null || month == null || day == null || hour == null || minute == null || second == null) {
			throw haxe_Exception.thrown("`" + str + "` - incorrect date/time format. Should be either `YYYY-MM-DD hh:mm:ss` or `YYYY-MM-DD`");
		}
		let year1 = year;
		let month1 = month;
		let day1 = day;
		let hour1 = hour;
		let minute1 = minute;
		let second1 = second;
		if(second1 == null) {
			second1 = 0;
		}
		if(minute1 == null) {
			minute1 = 0;
		}
		if(hour1 == null) {
			hour1 = 0;
		}
		if(day1 == null) {
			day1 = 1;
		}
		if(month1 == null) {
			month1 = 1;
		}
		if(year1 == null) {
			year1 = 1970;
		}
		return datetime_utils_DateTimeUtils.yearToStamp(year1) + datetime_utils_DateTimeMonthUtils.toSeconds(month1,year1 % 4 == 0 && (year1 % 100 == 0 ? year1 % 400 == 0 : true)) + (day1 - 1) * 86400 + hour1 * 3600 + minute1 * 60 + second1 - 62135596800.0 + 62135596800.0;
	}
	static fromIsoString(str) {
		let tz = null;
		let tzSep = str.charCodeAt(str.length - 6);
		if(str.charCodeAt(str.length - 1) == 90) {
			tz = 0;
		} else if(tzSep == 43 || tzSep == 45) {
			let tzHour = Std.parseInt(HxOverrides.substr(str,str.length - 5,2));
			let tzMin = Std.parseInt(HxOverrides.substr(str,str.length - 2,2));
			tz = tzHour * 60 + tzMin;
			if(tzSep == 43) {
				tz = -1 * tz;
			}
		}
		if(tz == null) {
			throw haxe_Exception.thrown("`" + str + "` - incorrect date/time format. Not an ISO 8601 string: No timezone.");
		}
		if(str.length > 20) {
			if(str.charCodeAt(19) != 46 && str.charCodeAt(19) != tzSep) {
				throw haxe_Exception.thrown("`" + str + "` - incorrect date/time format. Not an ISO 8601 string: Millisecond specification erroneous.");
			}
		}
		return datetime_DateTime.add(datetime_utils_DateTimeUtils.parse(HxOverrides.substr(str,0,10) + " " + HxOverrides.substr(str,11,8)),datetime_DTPeriod.Minute(tz));
	}
	static clamp(value,min,max) {
		if(value < min) {
			return min;
		} else if(value > max) {
			return max;
		} else {
			return value;
		}
	}
	static yearToStamp(year) {
		--year;
		let cquads = year / 400 | 0;
		let quads = (year - cquads * 400) / 4 | 0;
		let excessDays = quads / 25 | 0;
		return cquads * 12622780800.0 + quads * 126230400.0 - excessDays * 86400 + (year - cquads * 400 - quads * 4) * 31536000;
	}
	static addYear(dt,amount) {
		let year = datetime_DateTime.getYear(dt) + amount;
		let time = datetime_DateTime.yearStart(dt);
		let days = ((dt - 62135596800.0 - datetime_DateTime.yearStart(dt)) / 86400 | 0) + 1;
		let time1 = dt - 62135596800.0 - (time + datetime_utils_DateTimeMonthUtils.toSeconds(datetime_utils_DateTimeMonthUtils.getMonth(days,datetime_DateTime.isLeapYear(dt)),datetime_DateTime.isLeapYear(dt)));
		let tmp = datetime_utils_DateTimeUtils.yearToStamp(year);
		let days1 = ((dt - 62135596800.0 - datetime_DateTime.yearStart(dt)) / 86400 | 0) + 1;
		return tmp + datetime_utils_DateTimeMonthUtils.toSeconds(datetime_utils_DateTimeMonthUtils.getMonth(days1,datetime_DateTime.isLeapYear(dt)),year % 4 == 0 && (year % 100 == 0 ? year % 400 == 0 : true)) + time1 - 62135596800.0;
	}
	static addMonth(dt,amount) {
		let days = ((dt - 62135596800.0 - datetime_DateTime.yearStart(dt)) / 86400 | 0) + 1;
		let month = datetime_utils_DateTimeMonthUtils.getMonth(days,datetime_DateTime.isLeapYear(dt)) + amount;
		if(month > 12) {
			let years = month / 12 | 0;
			dt = datetime_utils_DateTimeUtils.addYear(dt,years) + 62135596800.0;
			month -= years * 12;
		} else if(month <= 0) {
			let years = (month / 12 | 0) - 1;
			dt = datetime_utils_DateTimeUtils.addYear(dt,years) + 62135596800.0;
			month -= years * 12;
		}
		let isLeap = datetime_DateTime.isLeapYear(dt);
		let days1 = ((dt - 62135596800.0 - datetime_DateTime.yearStart(dt)) / 86400 | 0) + 1;
		let value = datetime_utils_DateTimeMonthUtils.getMonthDay(days1,datetime_DateTime.isLeapYear(dt));
		let max = datetime_utils_DateTimeMonthUtils.days(month,isLeap);
		let day = value < 1 ? 1 : value > max ? max : value;
		return datetime_DateTime.yearStart(dt) + datetime_utils_DateTimeMonthUtils.toSeconds(month,isLeap) + (day - 1) * 86400 + ((dt - Math.floor(dt / 86400) * 86400) / 3600 | 0) * 3600 + ((dt - Math.floor(dt / 3600) * 3600) / 60 | 0) * 60 + (dt - Math.floor(dt / 60) * 60 | 0);
	}
	static getWeekDayNum(dt,weekDay,num) {
		let days = ((dt - 62135596800.0 - datetime_DateTime.yearStart(dt)) / 86400 | 0) + 1;
		let month = datetime_utils_DateTimeMonthUtils.getMonth(days,datetime_DateTime.isLeapYear(dt));
		if(num > 0) {
			let start = datetime_DateTime.monthStart(dt,month) - 1 + 62135596800.0;
			let first = datetime_DateTime.snap(start,datetime_DTSnap.Week(1,weekDay));
			return datetime_DateTime.add(first,datetime_DTPeriod.Week(num - 1)) - 62135596800.0;
		} else if(num < 0) {
			let start = datetime_DateTime.monthStart(dt,month + 1) - 1 + 62135596800.0;
			let first = datetime_DateTime.snap(start,datetime_DTSnap.Week(-1,weekDay));
			return datetime_DateTime.add(first,datetime_DTPeriod.Week(num + 1)) - 62135596800.0;
		} else {
			return dt - 62135596800.0;
		}
	}
	static strftime(dt,format) {
		let prevPos = 0;
		let pos = format.indexOf("%");
		let str = "";
		while(pos >= 0) {
			str += format.substring(prevPos,pos);
			++pos;
			switch(format.charCodeAt(pos)) {
			case 37:
				str += "%";
				break;
			case 67:
				str += StringTools.lpad((datetime_DateTime.getYear(dt) / 100 | 0) + "","0",2);
				break;
			case 68:
				let days = ((dt - 62135596800.0 - datetime_DateTime.yearStart(dt)) / 86400 | 0) + 1;
				let str1 = StringTools.lpad(datetime_utils_DateTimeMonthUtils.getMonth(days,datetime_DateTime.isLeapYear(dt)) + "/","0",3);
				let days1 = ((dt - 62135596800.0 - datetime_DateTime.yearStart(dt)) / 86400 | 0) + 1;
				str += str1 + StringTools.lpad(datetime_utils_DateTimeMonthUtils.getMonthDay(days1,datetime_DateTime.isLeapYear(dt)) + "/","0",3) + StringTools.lpad(HxOverrides.substr(datetime_DateTime.getYear(dt) + "",-2,null),"0",2);
				break;
			case 70:
				let str2 = datetime_DateTime.getYear(dt) + "-";
				let days2 = ((dt - 62135596800.0 - datetime_DateTime.yearStart(dt)) / 86400 | 0) + 1;
				let str3 = str2 + StringTools.lpad(datetime_utils_DateTimeMonthUtils.getMonth(days2,datetime_DateTime.isLeapYear(dt)) + "-","0",3);
				let days3 = ((dt - 62135596800.0 - datetime_DateTime.yearStart(dt)) / 86400 | 0) + 1;
				str += str3 + StringTools.lpad(datetime_utils_DateTimeMonthUtils.getMonthDay(days3,datetime_DateTime.isLeapYear(dt)) + "","0",2);
				break;
			case 72:
				str += StringTools.lpad(((dt - Math.floor(dt / 86400) * 86400) / 3600 | 0) + "","0",2);
				break;
			case 73:
				str += StringTools.lpad(datetime_DateTime.getHour12(dt) + "","0",2);
				break;
			case 77:
				str += StringTools.lpad(((dt - Math.floor(dt / 3600) * 3600) / 60 | 0) + "","0",2);
				break;
			case 80:
				str += ((dt - Math.floor(dt / 86400) * 86400) / 3600 | 0) < 12 ? "am" : "pm";
				break;
			case 82:
				str += StringTools.lpad(((dt - Math.floor(dt / 86400) * 86400) / 3600 | 0) + ":","0",3) + StringTools.lpad(((dt - Math.floor(dt / 3600) * 3600) / 60 | 0) + "","0",2);
				break;
			case 83:
				str += StringTools.lpad((dt - Math.floor(dt / 60) * 60 | 0) + "","0",2);
				break;
			case 84:
				str += StringTools.lpad(((dt - Math.floor(dt / 86400) * 86400) / 3600 | 0) + ":","0",3) + StringTools.lpad(((dt - Math.floor(dt / 3600) * 3600) / 60 | 0) + ":","0",3) + StringTools.lpad((dt - Math.floor(dt / 60) * 60 | 0) + "","0",2);
				break;
			case 86:
				str += StringTools.lpad(datetime_DateTime.getWeek(dt) + "","0",2);
				break;
			case 89:
				str += datetime_DateTime.getYear(dt) + "";
				break;
			case 100:
				let days4 = ((dt - 62135596800.0 - datetime_DateTime.yearStart(dt)) / 86400 | 0) + 1;
				str += StringTools.lpad(datetime_utils_DateTimeMonthUtils.getMonthDay(days4,datetime_DateTime.isLeapYear(dt)) + "","0",2);
				break;
			case 101:
				let days5 = ((dt - 62135596800.0 - datetime_DateTime.yearStart(dt)) / 86400 | 0) + 1;
				str += StringTools.lpad(datetime_utils_DateTimeMonthUtils.getMonthDay(days5,datetime_DateTime.isLeapYear(dt)) + ""," ",2);
				break;
			case 106:
				let day = ((dt - 62135596800.0 - datetime_DateTime.yearStart(dt)) / 86400 | 0) + 1;
				str += StringTools.lpad("" + day,"0",3);
				break;
			case 107:
				str += StringTools.lpad(((dt - Math.floor(dt / 86400) * 86400) / 3600 | 0) + ""," ",2);
				break;
			case 108:
				str += StringTools.lpad(datetime_DateTime.getHour12(dt) + ""," ",2);
				break;
			case 109:
				let days6 = ((dt - 62135596800.0 - datetime_DateTime.yearStart(dt)) / 86400 | 0) + 1;
				str += StringTools.lpad(datetime_utils_DateTimeMonthUtils.getMonth(days6,datetime_DateTime.isLeapYear(dt)) + "","0",2);
				break;
			case 112:
				str += ((dt - Math.floor(dt / 86400) * 86400) / 3600 | 0) < 12 ? "AM" : "PM";
				break;
			case 114:
				str += StringTools.lpad(datetime_DateTime.getHour12(dt) + ":","0",3) + StringTools.lpad(((dt - Math.floor(dt / 3600) * 3600) / 60 | 0) + ":","0",3) + StringTools.lpad((dt - Math.floor(dt / 60) * 60 | 0) + "","0",2);
				break;
			case 115:
				str += dt - 62135596800.0 + "";
				break;
			case 117:
				str += datetime_DateTime.getWeekDay(dt,true) + "";
				break;
			case 119:
				str += datetime_DateTime.getWeekDay(dt) + "";
				break;
			case 121:
				str += StringTools.lpad(HxOverrides.substr(datetime_DateTime.getYear(dt) + "",-2,null),"0",2);
				break;
			}
			prevPos = pos + 1;
			pos = format.indexOf("%",pos + 1);
		}
		str += format.substring(prevPos);
		return str;
	}
}
datetime_utils_DateTimeUtils.__name__ = "datetime.utils.DateTimeUtils";
Object.assign(datetime_utils_DateTimeUtils.prototype, {
	__class__: datetime_utils_DateTimeUtils
});
var haxe_StackItem = $hxEnums["haxe.StackItem"] = { __ename__:true,__constructs__:null
	,CFunction: {_hx_name:"CFunction",_hx_index:0,__enum__:"haxe.StackItem",toString:$estr}
	,Module: ($_=function(m) { return {_hx_index:1,m:m,__enum__:"haxe.StackItem",toString:$estr}; },$_._hx_name="Module",$_.__params__ = ["m"],$_)
	,FilePos: ($_=function(s,file,line,column) { return {_hx_index:2,s:s,file:file,line:line,column:column,__enum__:"haxe.StackItem",toString:$estr}; },$_._hx_name="FilePos",$_.__params__ = ["s","file","line","column"],$_)
	,Method: ($_=function(classname,method) { return {_hx_index:3,classname:classname,method:method,__enum__:"haxe.StackItem",toString:$estr}; },$_._hx_name="Method",$_.__params__ = ["classname","method"],$_)
	,LocalFunction: ($_=function(v) { return {_hx_index:4,v:v,__enum__:"haxe.StackItem",toString:$estr}; },$_._hx_name="LocalFunction",$_.__params__ = ["v"],$_)
};
haxe_StackItem.__constructs__ = [haxe_StackItem.CFunction,haxe_StackItem.Module,haxe_StackItem.FilePos,haxe_StackItem.Method,haxe_StackItem.LocalFunction];
class haxe_IMap {
}
haxe_IMap.__name__ = "haxe.IMap";
haxe_IMap.__isInterface__ = true;
Object.assign(haxe_IMap.prototype, {
	__class__: haxe_IMap
});
class haxe_Exception extends Error {
	constructor(message,previous,native) {
		super(message);
		this.message = message;
		this.__previousException = previous;
		this.__nativeException = native != null ? native : this;
	}
	unwrap() {
		return this.__nativeException;
	}
	toString() {
		return this.get_message();
	}
	get_message() {
		return this.message;
	}
	get_native() {
		return this.__nativeException;
	}
	static caught(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);
		}
	}
	static thrown(value) {
		if(((value) instanceof haxe_Exception)) {
			return value.get_native();
		} else if(((value) instanceof Error)) {
			return value;
		} else {
			let e = new haxe_ValueException(value);
			return e;
		}
	}
}
haxe_Exception.__name__ = "haxe.Exception";
haxe_Exception.__super__ = Error;
Object.assign(haxe_Exception.prototype, {
	__class__: haxe_Exception
});
class haxe__$Int64__$_$_$Int64 {
	constructor(high,low) {
		this.high = high;
		this.low = low;
	}
}
haxe__$Int64__$_$_$Int64.__name__ = "haxe._Int64.___Int64";
Object.assign(haxe__$Int64__$_$_$Int64.prototype, {
	__class__: haxe__$Int64__$_$_$Int64
});
class haxe_Log {
	static formatOutput(v,infos) {
		let str = Std.string(v);
		if(infos == null) {
			return str;
		}
		let pstr = infos.fileName + ":" + infos.lineNumber;
		if(infos.customParams != null) {
			let _g = 0;
			let _g1 = infos.customParams;
			while(_g < _g1.length) {
				let v = _g1[_g];
				++_g;
				str += ", " + Std.string(v);
			}
		}
		return pstr + ": " + str;
	}
	static trace(v,infos) {
		let str = haxe_Log.formatOutput(v,infos);
		if(typeof(console) != "undefined" && console.log != null) {
			console.log(str);
		}
	}
}
haxe_Log.__name__ = "haxe.Log";
class haxe_Timer {
	constructor(time_ms) {
		let me = this;
		this.id = setInterval(function() {
			me.run();
		},time_ms);
	}
	stop() {
		if(this.id == null) {
			return;
		}
		clearInterval(this.id);
		this.id = null;
	}
	run() {
	}
	static delay(f,time_ms) {
		let t = new haxe_Timer(time_ms);
		t.run = function() {
			t.stop();
			f();
		};
		return t;
	}
}
haxe_Timer.__name__ = "haxe.Timer";
Object.assign(haxe_Timer.prototype, {
	__class__: haxe_Timer
});
class haxe_ValueException extends haxe_Exception {
	constructor(value,previous,native) {
		super(String(value),previous,native);
		this.value = value;
	}
	unwrap() {
		return this.value;
	}
}
haxe_ValueException.__name__ = "haxe.ValueException";
haxe_ValueException.__super__ = haxe_Exception;
Object.assign(haxe_ValueException.prototype, {
	__class__: haxe_ValueException
});
class haxe_crypto_Adler32 {
	constructor() {
		this.a1 = 1;
		this.a2 = 0;
	}
	get() {
		return this.a2 << 16 | this.a1;
	}
	update(b,pos,len) {
		let a1 = this.a1;
		let a2 = this.a2;
		let _g = pos;
		let _g1 = pos + len;
		while(_g < _g1) {
			let p = _g++;
			let c = b.b[p];
			a1 = (a1 + c) % 65521;
			a2 = (a2 + a1) % 65521;
		}
		this.a1 = a1;
		this.a2 = a2;
	}
	static make(b) {
		let a = new haxe_crypto_Adler32();
		a.update(b,0,b.length);
		return a.get();
	}
}
haxe_crypto_Adler32.__name__ = "haxe.crypto.Adler32";
Object.assign(haxe_crypto_Adler32.prototype, {
	__class__: haxe_crypto_Adler32
});
class haxe_io_Bytes {
	constructor(data) {
		this.length = data.byteLength;
		this.b = new Uint8Array(data);
		this.b.bufferValue = data;
		data.hxBytes = this;
		data.bytes = this.b;
	}
	blit(pos,src,srcpos,len) {
		if(pos < 0 || srcpos < 0 || len < 0 || pos + len > this.length || srcpos + len > src.length) {
			throw haxe_Exception.thrown(haxe_io_Error.OutsideBounds);
		}
		if(srcpos == 0 && len == src.b.byteLength) {
			this.b.set(src.b,pos);
		} else {
			this.b.set(src.b.subarray(srcpos,srcpos + len),pos);
		}
	}
	fill(pos,len,value) {
		let _g = 0;
		let _g1 = len;
		while(_g < _g1) {
			let i = _g++;
			this.b[pos++] = value;
		}
	}
	sub(pos,len) {
		if(pos < 0 || len < 0 || pos + len > this.length) {
			throw haxe_Exception.thrown(haxe_io_Error.OutsideBounds);
		}
		return new haxe_io_Bytes(this.b.buffer.slice(pos + this.b.byteOffset,pos + this.b.byteOffset + len));
	}
	getUInt16(pos) {
		if(this.data == null) {
			this.data = new DataView(this.b.buffer,this.b.byteOffset,this.b.byteLength);
		}
		return this.data.getUint16(pos,true);
	}
	getString(pos,len,encoding) {
		if(pos < 0 || len < 0 || pos + len > this.length) {
			throw haxe_Exception.thrown(haxe_io_Error.OutsideBounds);
		}
		if(encoding == null) {
			encoding = haxe_io_Encoding.UTF8;
		}
		let s = "";
		let b = this.b;
		let i = pos;
		let max = pos + len;
		switch(encoding._hx_index) {
		case 0:
			let debug = pos > 0;
			while(i < max) {
				let c = b[i++];
				if(c < 128) {
					if(c == 0) {
						break;
					}
					s += String.fromCodePoint(c);
				} else if(c < 224) {
					let code = (c & 63) << 6 | b[i++] & 127;
					s += String.fromCodePoint(code);
				} else if(c < 240) {
					let c2 = b[i++];
					let code = (c & 31) << 12 | (c2 & 127) << 6 | b[i++] & 127;
					s += String.fromCodePoint(code);
				} else {
					let c2 = b[i++];
					let c3 = b[i++];
					let u = (c & 15) << 18 | (c2 & 127) << 12 | (c3 & 127) << 6 | b[i++] & 127;
					s += String.fromCodePoint(u);
				}
			}
			break;
		case 1:
			while(i < max) {
				let c = b[i++] | b[i++] << 8;
				s += String.fromCodePoint(c);
			}
			break;
		}
		return s;
	}
	toString() {
		return this.getString(0,this.length);
	}
	toHex() {
		let s_b = "";
		let chars = [];
		let str = "0123456789abcdef";
		let _g = 0;
		let _g1 = str.length;
		while(_g < _g1) {
			let i = _g++;
			chars.push(HxOverrides.cca(str,i));
		}
		let _g2 = 0;
		let _g3 = this.length;
		while(_g2 < _g3) {
			let i = _g2++;
			let c = this.b[i];
			s_b += String.fromCodePoint(chars[c >> 4]);
			s_b += String.fromCodePoint(chars[c & 15]);
		}
		return s_b;
	}
	static ofString(s,encoding) {
		if(encoding == haxe_io_Encoding.RawNative) {
			let buf = new Uint8Array(s.length << 1);
			let _g = 0;
			let _g1 = s.length;
			while(_g < _g1) {
				let i = _g++;
				let c = s.charCodeAt(i);
				buf[i << 1] = c & 255;
				buf[i << 1 | 1] = c >> 8;
			}
			return new haxe_io_Bytes(buf.buffer);
		}
		let a = [];
		let i = 0;
		while(i < s.length) {
			let c = s.charCodeAt(i++);
			if(55296 <= c && c <= 56319) {
				c = c - 55232 << 10 | s.charCodeAt(i++) & 1023;
			}
			if(c <= 127) {
				a.push(c);
			} else if(c <= 2047) {
				a.push(192 | c >> 6);
				a.push(128 | c & 63);
			} else if(c <= 65535) {
				a.push(224 | c >> 12);
				a.push(128 | c >> 6 & 63);
				a.push(128 | c & 63);
			} else {
				a.push(240 | c >> 18);
				a.push(128 | c >> 12 & 63);
				a.push(128 | c >> 6 & 63);
				a.push(128 | c & 63);
			}
		}
		return new haxe_io_Bytes(new Uint8Array(a).buffer);
	}
	static ofData(b) {
		let hb = b.hxBytes;
		if(hb != null) {
			return hb;
		}
		return new haxe_io_Bytes(b);
	}
	static ofHex(s) {
		if((s.length & 1) != 0) {
			throw haxe_Exception.thrown("Not a hex string (odd number of digits)");
		}
		let a = [];
		let i = 0;
		let len = s.length >> 1;
		while(i < len) {
			let high = s.charCodeAt(i * 2);
			let low = s.charCodeAt(i * 2 + 1);
			high = (high & 15) + ((high & 64) >> 6) * 9;
			low = (low & 15) + ((low & 64) >> 6) * 9;
			a.push((high << 4 | low) & 255);
			++i;
		}
		return new haxe_io_Bytes(new Uint8Array(a).buffer);
	}
}
haxe_io_Bytes.__name__ = "haxe.io.Bytes";
Object.assign(haxe_io_Bytes.prototype, {
	__class__: haxe_io_Bytes
});
var haxe_io_Encoding = $hxEnums["haxe.io.Encoding"] = { __ename__:true,__constructs__:null
	,UTF8: {_hx_name:"UTF8",_hx_index:0,__enum__:"haxe.io.Encoding",toString:$estr}
	,RawNative: {_hx_name:"RawNative",_hx_index:1,__enum__:"haxe.io.Encoding",toString:$estr}
};
haxe_io_Encoding.__constructs__ = [haxe_io_Encoding.UTF8,haxe_io_Encoding.RawNative];
class haxe_crypto_Base64 {
	static encode(bytes,complement) {
		if(complement == null) {
			complement = true;
		}
		let str = new haxe_crypto_BaseCode(haxe_crypto_Base64.BYTES).encodeBytes(bytes).toString();
		if(complement) {
			switch(bytes.length % 3) {
			case 1:
				str += "==";
				break;
			case 2:
				str += "=";
				break;
			default:
			}
		}
		return str;
	}
	static decode(str,complement) {
		if(complement == null) {
			complement = true;
		}
		if(complement) {
			while(HxOverrides.cca(str,str.length - 1) == 61) str = HxOverrides.substr(str,0,-1);
		}
		return new haxe_crypto_BaseCode(haxe_crypto_Base64.BYTES).decodeBytes(haxe_io_Bytes.ofString(str));
	}
	static urlEncode(bytes,complement) {
		if(complement == null) {
			complement = false;
		}
		let str = new haxe_crypto_BaseCode(haxe_crypto_Base64.URL_BYTES).encodeBytes(bytes).toString();
		if(complement) {
			switch(bytes.length % 3) {
			case 1:
				str += "==";
				break;
			case 2:
				str += "=";
				break;
			default:
			}
		}
		return str;
	}
	static urlDecode(str,complement) {
		if(complement == null) {
			complement = false;
		}
		if(complement) {
			while(HxOverrides.cca(str,str.length - 1) == 61) str = HxOverrides.substr(str,0,-1);
		}
		return new haxe_crypto_BaseCode(haxe_crypto_Base64.URL_BYTES).decodeBytes(haxe_io_Bytes.ofString(str));
	}
}
haxe_crypto_Base64.__name__ = "haxe.crypto.Base64";
class haxe_crypto_BaseCode {
	constructor(base) {
		let len = base.length;
		let nbits = 1;
		while(len > 1 << nbits) ++nbits;
		if(nbits > 8 || len != 1 << nbits) {
			throw haxe_Exception.thrown("BaseCode : base length must be a power of two.");
		}
		this.base = base;
		this.nbits = nbits;
	}
	encodeBytes(b) {
		let nbits = this.nbits;
		let base = this.base;
		let size = b.length * 8 / nbits | 0;
		let out = new haxe_io_Bytes(new ArrayBuffer(size + (b.length * 8 % nbits == 0 ? 0 : 1)));
		let buf = 0;
		let curbits = 0;
		let mask = (1 << nbits) - 1;
		let pin = 0;
		let pout = 0;
		while(pout < size) {
			while(curbits < nbits) {
				curbits += 8;
				buf <<= 8;
				buf |= b.b[pin++];
			}
			curbits -= nbits;
			out.b[pout++] = base.b[buf >> curbits & mask];
		}
		if(curbits > 0) {
			out.b[pout++] = base.b[buf << nbits - curbits & mask];
		}
		return out;
	}
	initTable() {
		let tbl = [];
		let _g = 0;
		while(_g < 256) {
			let i = _g++;
			tbl[i] = -1;
		}
		let _g1 = 0;
		let _g2 = this.base.length;
		while(_g1 < _g2) {
			let i = _g1++;
			tbl[this.base.b[i]] = i;
		}
		this.tbl = tbl;
	}
	decodeBytes(b) {
		let nbits = this.nbits;
		let base = this.base;
		if(this.tbl == null) {
			this.initTable();
		}
		let tbl = this.tbl;
		let size = b.length * nbits >> 3;
		let out = new haxe_io_Bytes(new ArrayBuffer(size));
		let buf = 0;
		let curbits = 0;
		let pin = 0;
		let pout = 0;
		while(pout < size) {
			while(curbits < 8) {
				curbits += nbits;
				buf <<= nbits;
				let i = tbl[b.b[pin++]];
				if(i == -1) {
					throw haxe_Exception.thrown("BaseCode : invalid encoded char");
				}
				buf |= i;
			}
			curbits -= 8;
			out.b[pout++] = buf >> curbits & 255;
		}
		return out;
	}
}
haxe_crypto_BaseCode.__name__ = "haxe.crypto.BaseCode";
Object.assign(haxe_crypto_BaseCode.prototype, {
	__class__: haxe_crypto_BaseCode
});
class haxe_crypto_Crc32 {
	static make(data) {
		let c_crc = -1;
		let b = data.b.bufferValue;
		let _g = 0;
		let _g1 = data.length;
		while(_g < _g1) {
			let i = _g++;
			let tmp = (c_crc ^ b.bytes[i]) & 255;
			tmp = tmp >>> 1 ^ -(tmp & 1) & -306674912;
			tmp = tmp >>> 1 ^ -(tmp & 1) & -306674912;
			tmp = tmp >>> 1 ^ -(tmp & 1) & -306674912;
			tmp = tmp >>> 1 ^ -(tmp & 1) & -306674912;
			tmp = tmp >>> 1 ^ -(tmp & 1) & -306674912;
			tmp = tmp >>> 1 ^ -(tmp & 1) & -306674912;
			tmp = tmp >>> 1 ^ -(tmp & 1) & -306674912;
			tmp = tmp >>> 1 ^ -(tmp & 1) & -306674912;
			c_crc = c_crc >>> 8 ^ tmp;
		}
		return c_crc ^ -1;
	}
}
haxe_crypto_Crc32.__name__ = "haxe.crypto.Crc32";
class haxe_crypto_Sha1 {
	constructor() {
	}
	doEncode(x) {
		let w = [];
		let a = 1732584193;
		let b = -271733879;
		let c = -1732584194;
		let d = 271733878;
		let e = -1009589776;
		let i = 0;
		while(i < x.length) {
			let olda = a;
			let oldb = b;
			let oldc = c;
			let oldd = d;
			let olde = e;
			let j = 0;
			while(j < 80) {
				if(j < 16) {
					w[j] = x[i + j];
				} else {
					let num = w[j - 3] ^ w[j - 8] ^ w[j - 14] ^ w[j - 16];
					w[j] = num << 1 | num >>> 31;
				}
				let t = (a << 5 | a >>> 27) + this.ft(j,b,c,d) + e + w[j] + this.kt(j);
				e = d;
				d = c;
				c = b << 30 | b >>> 2;
				b = a;
				a = t;
				++j;
			}
			a += olda;
			b += oldb;
			c += oldc;
			d += oldd;
			e += olde;
			i += 16;
		}
		return [a,b,c,d,e];
	}
	ft(t,b,c,d) {
		if(t < 20) {
			return b & c | ~b & d;
		}
		if(t < 40) {
			return b ^ c ^ d;
		}
		if(t < 60) {
			return b & c | b & d | c & d;
		}
		return b ^ c ^ d;
	}
	kt(t) {
		if(t < 20) {
			return 1518500249;
		}
		if(t < 40) {
			return 1859775393;
		}
		if(t < 60) {
			return -1894007588;
		}
		return -899497514;
	}
	static make(b) {
		let h = new haxe_crypto_Sha1().doEncode(haxe_crypto_Sha1.bytes2blks(b));
		let out = new haxe_io_Bytes(new ArrayBuffer(20));
		let p = 0;
		out.b[p++] = h[0] >>> 24;
		out.b[p++] = h[0] >> 16 & 255;
		out.b[p++] = h[0] >> 8 & 255;
		out.b[p++] = h[0] & 255;
		out.b[p++] = h[1] >>> 24;
		out.b[p++] = h[1] >> 16 & 255;
		out.b[p++] = h[1] >> 8 & 255;
		out.b[p++] = h[1] & 255;
		out.b[p++] = h[2] >>> 24;
		out.b[p++] = h[2] >> 16 & 255;
		out.b[p++] = h[2] >> 8 & 255;
		out.b[p++] = h[2] & 255;
		out.b[p++] = h[3] >>> 24;
		out.b[p++] = h[3] >> 16 & 255;
		out.b[p++] = h[3] >> 8 & 255;
		out.b[p++] = h[3] & 255;
		out.b[p++] = h[4] >>> 24;
		out.b[p++] = h[4] >> 16 & 255;
		out.b[p++] = h[4] >> 8 & 255;
		out.b[p++] = h[4] & 255;
		return out;
	}
	static bytes2blks(b) {
		let nblk = (b.length + 8 >> 6) + 1;
		let blks = [];
		let _g = 0;
		let _g1 = nblk * 16;
		while(_g < _g1) {
			let i = _g++;
			blks[i] = 0;
		}
		let _g2 = 0;
		let _g3 = b.length;
		while(_g2 < _g3) {
			let i = _g2++;
			let p = i >> 2;
			blks[p] |= b.b[i] << 24 - ((i & 3) << 3);
		}
		let i = b.length;
		let p = i >> 2;
		blks[p] |= 128 << 24 - ((i & 3) << 3);
		blks[nblk * 16 - 1] = b.length * 8;
		return blks;
	}
}
haxe_crypto_Sha1.__name__ = "haxe.crypto.Sha1";
Object.assign(haxe_crypto_Sha1.prototype, {
	__class__: haxe_crypto_Sha1
});
class haxe_crypto_Sha256 {
	constructor() {
	}
	doEncode(m,l) {
		let K = [1116352408,1899447441,-1245643825,-373957723,961987163,1508970993,-1841331548,-1424204075,-670586216,310598401,607225278,1426881987,1925078388,-2132889090,-1680079193,-1046744716,-459576895,-272742522,264347078,604807628,770255983,1249150122,1555081692,1996064986,-1740746414,-1473132947,-1341970488,-1084653625,-958395405,-710438585,113926993,338241895,666307205,773529912,1294757372,1396182291,1695183700,1986661051,-2117940946,-1838011259,-1564481375,-1474664885,-1035236496,-949202525,-778901479,-694614492,-200395387,275423344,430227734,506948616,659060556,883997877,958139571,1322822218,1537002063,1747873779,1955562222,2024104815,-2067236844,-1933114872,-1866530822,-1538233109,-1090935817,-965641998];
		let HASH = [1779033703,-1150833019,1013904242,-1521486534,1359893119,-1694144372,528734635,1541459225];
		let W = [];
		W[64] = 0;
		let a;
		let b;
		let c;
		let d;
		let e;
		let f;
		let g;
		let h;
		let T1;
		let T2;
		m[l >> 5] |= 128 << 24 - l % 32;
		m[(l + 64 >> 9 << 4) + 15] = l;
		let i = 0;
		while(i < m.length) {
			a = HASH[0];
			b = HASH[1];
			c = HASH[2];
			d = HASH[3];
			e = HASH[4];
			f = HASH[5];
			g = HASH[6];
			h = HASH[7];
			let _g = 0;
			while(_g < 64) {
				let j = _g++;
				if(j < 16) {
					W[j] = m[j + i];
				} else {
					let x = W[j - 2];
					let x1 = (x >>> 17 | x << 15) ^ (x >>> 19 | x << 13) ^ x >>> 10;
					let y = W[j - 7];
					let lsw = (x1 & 65535) + (y & 65535);
					let msw = (x1 >> 16) + (y >> 16) + (lsw >> 16);
					let x2 = msw << 16 | lsw & 65535;
					let x3 = W[j - 15];
					let y1 = (x3 >>> 7 | x3 << 25) ^ (x3 >>> 18 | x3 << 14) ^ x3 >>> 3;
					let lsw1 = (x2 & 65535) + (y1 & 65535);
					let msw1 = (x2 >> 16) + (y1 >> 16) + (lsw1 >> 16);
					let x4 = msw1 << 16 | lsw1 & 65535;
					let y2 = W[j - 16];
					let lsw2 = (x4 & 65535) + (y2 & 65535);
					let msw2 = (x4 >> 16) + (y2 >> 16) + (lsw2 >> 16);
					W[j] = msw2 << 16 | lsw2 & 65535;
				}
				let y = (e >>> 6 | e << 26) ^ (e >>> 11 | e << 21) ^ (e >>> 25 | e << 7);
				let lsw = (h & 65535) + (y & 65535);
				let msw = (h >> 16) + (y >> 16) + (lsw >> 16);
				let x = msw << 16 | lsw & 65535;
				let y1 = e & f ^ ~e & g;
				let lsw1 = (x & 65535) + (y1 & 65535);
				let msw1 = (x >> 16) + (y1 >> 16) + (lsw1 >> 16);
				let x1 = msw1 << 16 | lsw1 & 65535;
				let y2 = K[j];
				let lsw2 = (x1 & 65535) + (y2 & 65535);
				let msw2 = (x1 >> 16) + (y2 >> 16) + (lsw2 >> 16);
				let x2 = msw2 << 16 | lsw2 & 65535;
				let y3 = W[j];
				let lsw3 = (x2 & 65535) + (y3 & 65535);
				let msw3 = (x2 >> 16) + (y3 >> 16) + (lsw3 >> 16);
				T1 = msw3 << 16 | lsw3 & 65535;
				let x3 = (a >>> 2 | a << 30) ^ (a >>> 13 | a << 19) ^ (a >>> 22 | a << 10);
				let y4 = a & b ^ a & c ^ b & c;
				let lsw4 = (x3 & 65535) + (y4 & 65535);
				let msw4 = (x3 >> 16) + (y4 >> 16) + (lsw4 >> 16);
				T2 = msw4 << 16 | lsw4 & 65535;
				h = g;
				g = f;
				f = e;
				let lsw5 = (d & 65535) + (T1 & 65535);
				let msw5 = (d >> 16) + (T1 >> 16) + (lsw5 >> 16);
				e = msw5 << 16 | lsw5 & 65535;
				d = c;
				c = b;
				b = a;
				let lsw6 = (T1 & 65535) + (T2 & 65535);
				let msw6 = (T1 >> 16) + (T2 >> 16) + (lsw6 >> 16);
				a = msw6 << 16 | lsw6 & 65535;
			}
			let y = HASH[0];
			let lsw = (a & 65535) + (y & 65535);
			let msw = (a >> 16) + (y >> 16) + (lsw >> 16);
			HASH[0] = msw << 16 | lsw & 65535;
			let y1 = HASH[1];
			let lsw1 = (b & 65535) + (y1 & 65535);
			let msw1 = (b >> 16) + (y1 >> 16) + (lsw1 >> 16);
			HASH[1] = msw1 << 16 | lsw1 & 65535;
			let y2 = HASH[2];
			let lsw2 = (c & 65535) + (y2 & 65535);
			let msw2 = (c >> 16) + (y2 >> 16) + (lsw2 >> 16);
			HASH[2] = msw2 << 16 | lsw2 & 65535;
			let y3 = HASH[3];
			let lsw3 = (d & 65535) + (y3 & 65535);
			let msw3 = (d >> 16) + (y3 >> 16) + (lsw3 >> 16);
			HASH[3] = msw3 << 16 | lsw3 & 65535;
			let y4 = HASH[4];
			let lsw4 = (e & 65535) + (y4 & 65535);
			let msw4 = (e >> 16) + (y4 >> 16) + (lsw4 >> 16);
			HASH[4] = msw4 << 16 | lsw4 & 65535;
			let y5 = HASH[5];
			let lsw5 = (f & 65535) + (y5 & 65535);
			let msw5 = (f >> 16) + (y5 >> 16) + (lsw5 >> 16);
			HASH[5] = msw5 << 16 | lsw5 & 65535;
			let y6 = HASH[6];
			let lsw6 = (g & 65535) + (y6 & 65535);
			let msw6 = (g >> 16) + (y6 >> 16) + (lsw6 >> 16);
			HASH[6] = msw6 << 16 | lsw6 & 65535;
			let y7 = HASH[7];
			let lsw7 = (h & 65535) + (y7 & 65535);
			let msw7 = (h >> 16) + (y7 >> 16) + (lsw7 >> 16);
			HASH[7] = msw7 << 16 | lsw7 & 65535;
			i += 16;
		}
		return HASH;
	}
	static make(b) {
		let h = new haxe_crypto_Sha256().doEncode(haxe_crypto_Sha256.bytes2blks(b),b.length * 8);
		let out = new haxe_io_Bytes(new ArrayBuffer(32));
		let p = 0;
		let _g = 0;
		while(_g < 8) {
			let i = _g++;
			out.b[p++] = h[i] >>> 24;
			out.b[p++] = h[i] >> 16 & 255;
			out.b[p++] = h[i] >> 8 & 255;
			out.b[p++] = h[i] & 255;
		}
		return out;
	}
	static bytes2blks(b) {
		let nblk = (b.length + 8 >> 6) + 1;
		let blks = [];
		let _g = 0;
		let _g1 = nblk * 16;
		while(_g < _g1) {
			let i = _g++;
			blks[i] = 0;
		}
		let _g2 = 0;
		let _g3 = b.length;
		while(_g2 < _g3) {
			let i = _g2++;
			let p = i >> 2;
			blks[p] |= b.b[i] << 24 - ((i & 3) << 3);
		}
		let i = b.length;
		let p = i >> 2;
		blks[p] |= 128 << 24 - ((i & 3) << 3);
		blks[nblk * 16 - 1] = b.length * 8;
		return blks;
	}
}
haxe_crypto_Sha256.__name__ = "haxe.crypto.Sha256";
Object.assign(haxe_crypto_Sha256.prototype, {
	__class__: haxe_crypto_Sha256
});
class haxe_ds_BalancedTree {
	constructor() {
	}
	set(key,value) {
		this.root = this.setLoop(key,value,this.root);
	}
	get(key) {
		let node = this.root;
		while(node != null) {
			let c = this.compare(key,node.key);
			if(c == 0) {
				return node.value;
			}
			if(c < 0) {
				node = node.left;
			} else {
				node = node.right;
			}
		}
		return null;
	}
	exists(key) {
		let node = this.root;
		while(node != null) {
			let c = this.compare(key,node.key);
			if(c == 0) {
				return true;
			} else if(c < 0) {
				node = node.left;
			} else {
				node = node.right;
			}
		}
		return false;
	}
	iterator() {
		let ret = [];
		haxe_ds_BalancedTree.iteratorLoop(this.root,ret);
		return new haxe_iterators_ArrayIterator(ret);
	}
	keyValueIterator() {
		return new haxe_iterators_MapKeyValueIterator(this);
	}
	keys() {
		let ret = [];
		this.keysLoop(this.root,ret);
		return new haxe_iterators_ArrayIterator(ret);
	}
	setLoop(k,v,node) {
		if(node == null) {
			return new haxe_ds_TreeNode(null,k,v,null);
		}
		let c = this.compare(k,node.key);
		if(c == 0) {
			return new haxe_ds_TreeNode(node.left,k,v,node.right,node == null ? 0 : node._height);
		} else if(c < 0) {
			let nl = this.setLoop(k,v,node.left);
			return this.balance(nl,node.key,node.value,node.right);
		} else {
			let nr = this.setLoop(k,v,node.right);
			return this.balance(node.left,node.key,node.value,nr);
		}
	}
	keysLoop(node,acc) {
		if(node != null) {
			this.keysLoop(node.left,acc);
			acc.push(node.key);
			this.keysLoop(node.right,acc);
		}
	}
	balance(l,k,v,r) {
		let hl = l == null ? 0 : l._height;
		let hr = r == null ? 0 : r._height;
		if(hl > hr + 2) {
			let _this = l.left;
			let _this1 = l.right;
			if((_this == null ? 0 : _this._height) >= (_this1 == null ? 0 : _this1._height)) {
				return new haxe_ds_TreeNode(l.left,l.key,l.value,new haxe_ds_TreeNode(l.right,k,v,r));
			} else {
				return new haxe_ds_TreeNode(new haxe_ds_TreeNode(l.left,l.key,l.value,l.right.left),l.right.key,l.right.value,new haxe_ds_TreeNode(l.right.right,k,v,r));
			}
		} else if(hr > hl + 2) {
			let _this = r.right;
			let _this1 = r.left;
			if((_this == null ? 0 : _this._height) > (_this1 == null ? 0 : _this1._height)) {
				return new haxe_ds_TreeNode(new haxe_ds_TreeNode(l,k,v,r.left),r.key,r.value,r.right);
			} else {
				return new haxe_ds_TreeNode(new haxe_ds_TreeNode(l,k,v,r.left.left),r.left.key,r.left.value,new haxe_ds_TreeNode(r.left.right,r.key,r.value,r.right));
			}
		} else {
			return new haxe_ds_TreeNode(l,k,v,r,(hl > hr ? hl : hr) + 1);
		}
	}
	compare(k1,k2) {
		return Reflect.compare(k1,k2);
	}
	static iteratorLoop(node,acc) {
		if(node != null) {
			haxe_ds_BalancedTree.iteratorLoop(node.left,acc);
			acc.push(node.value);
			haxe_ds_BalancedTree.iteratorLoop(node.right,acc);
		}
	}
}
haxe_ds_BalancedTree.__name__ = "haxe.ds.BalancedTree";
haxe_ds_BalancedTree.__interfaces__ = [haxe_IMap];
Object.assign(haxe_ds_BalancedTree.prototype, {
	__class__: haxe_ds_BalancedTree
});
class haxe_ds_TreeNode {
	constructor(l,k,v,r,h) {
		if(h == null) {
			h = -1;
		}
		this.left = l;
		this.key = k;
		this.value = v;
		this.right = r;
		if(h == -1) {
			let tmp;
			let _this = this.left;
			let _this1 = this.right;
			if((_this == null ? 0 : _this._height) > (_this1 == null ? 0 : _this1._height)) {
				let _this = this.left;
				tmp = _this == null ? 0 : _this._height;
			} else {
				let _this = this.right;
				tmp = _this == null ? 0 : _this._height;
			}
			this._height = tmp + 1;
		} else {
			this._height = h;
		}
	}
}
haxe_ds_TreeNode.__name__ = "haxe.ds.TreeNode";
Object.assign(haxe_ds_TreeNode.prototype, {
	__class__: haxe_ds_TreeNode
});
var haxe_ds_Either = $hxEnums["haxe.ds.Either"] = { __ename__:true,__constructs__:null
	,Left: ($_=function(v) { return {_hx_index:0,v:v,__enum__:"haxe.ds.Either",toString:$estr}; },$_._hx_name="Left",$_.__params__ = ["v"],$_)
	,Right: ($_=function(v) { return {_hx_index:1,v:v,__enum__:"haxe.ds.Either",toString:$estr}; },$_._hx_name="Right",$_.__params__ = ["v"],$_)
};
haxe_ds_Either.__constructs__ = [haxe_ds_Either.Left,haxe_ds_Either.Right];
class haxe_ds_EnumValueMap extends haxe_ds_BalancedTree {
	constructor() {
		super();
	}
	compare(k1,k2) {
		let d = k1._hx_index - k2._hx_index;
		if(d != 0) {
			return d;
		}
		let p1 = Type.enumParameters(k1);
		let p2 = Type.enumParameters(k2);
		if(p1.length == 0 && p2.length == 0) {
			return 0;
		}
		return this.compareArgs(p1,p2);
	}
	compareArgs(a1,a2) {
		let ld = a1.length - a2.length;
		if(ld != 0) {
			return ld;
		}
		let _g = 0;
		let _g1 = a1.length;
		while(_g < _g1) {
			let i = _g++;
			let d = this.compareArg(a1[i],a2[i]);
			if(d != 0) {
				return d;
			}
		}
		return 0;
	}
	compareArg(v1,v2) {
		if(Reflect.isEnumValue(v1) && Reflect.isEnumValue(v2)) {
			return this.compare(v1,v2);
		} else if(((v1) instanceof Array) && ((v2) instanceof Array)) {
			return this.compareArgs(v1,v2);
		} else {
			return Reflect.compare(v1,v2);
		}
	}
}
haxe_ds_EnumValueMap.__name__ = "haxe.ds.EnumValueMap";
haxe_ds_EnumValueMap.__interfaces__ = [haxe_IMap];
haxe_ds_EnumValueMap.__super__ = haxe_ds_BalancedTree;
Object.assign(haxe_ds_EnumValueMap.prototype, {
	__class__: haxe_ds_EnumValueMap
});
class haxe_ds_IntMap {
	constructor() {
		this.h = { };
	}
	get(key) {
		return this.h[key];
	}
	exists(key) {
		return this.h.hasOwnProperty(key);
	}
	keys() {
		let a = [];
		for( var key in this.h ) if(this.h.hasOwnProperty(key)) a.push(+key);
		return new haxe_iterators_ArrayIterator(a);
	}
	iterator() {
		return { ref : this.h, it : this.keys(), hasNext : function() {
			return this.it.hasNext();
		}, next : function() {
			let i = this.it.next();
			return this.ref[i];
		}};
	}
	keyValueIterator() {
		return new haxe_iterators_MapKeyValueIterator(this);
	}
}
haxe_ds_IntMap.__name__ = "haxe.ds.IntMap";
haxe_ds_IntMap.__interfaces__ = [haxe_IMap];
Object.assign(haxe_ds_IntMap.prototype, {
	__class__: haxe_ds_IntMap
});
class haxe_ds_ObjectMap {
	constructor() {
		this.h = { __keys__ : { }};
	}
	get(key) {
		return this.h[key.__id__];
	}
	exists(key) {
		return this.h.__keys__[key.__id__] != null;
	}
	keys() {
		let a = [];
		for( var key in this.h.__keys__ ) {
		if(this.h.hasOwnProperty(key)) {
			a.push(this.h.__keys__[key]);
		}
		}
		return new haxe_iterators_ArrayIterator(a);
	}
	iterator() {
		return { ref : this.h, it : this.keys(), hasNext : function() {
			return this.it.hasNext();
		}, next : function() {
			let i = this.it.next();
			return this.ref[i.__id__];
		}};
	}
	keyValueIterator() {
		return new haxe_iterators_MapKeyValueIterator(this);
	}
}
haxe_ds_ObjectMap.__name__ = "haxe.ds.ObjectMap";
haxe_ds_ObjectMap.__interfaces__ = [haxe_IMap];
Object.assign(haxe_ds_ObjectMap.prototype, {
	__class__: haxe_ds_ObjectMap
});
var haxe_ds_Option = $hxEnums["haxe.ds.Option"] = { __ename__:true,__constructs__:null
	,Some: ($_=function(v) { return {_hx_index:0,v:v,__enum__:"haxe.ds.Option",toString:$estr}; },$_._hx_name="Some",$_.__params__ = ["v"],$_)
	,None: {_hx_name:"None",_hx_index:1,__enum__:"haxe.ds.Option",toString:$estr}
};
haxe_ds_Option.__constructs__ = [haxe_ds_Option.Some,haxe_ds_Option.None];
class haxe_ds_StringMap {
	constructor() {
		this.h = Object.create(null);
	}
	exists(key) {
		return Object.prototype.hasOwnProperty.call(this.h,key);
	}
	get(key) {
		return this.h[key];
	}
	keys() {
		return new haxe_ds__$StringMap_StringMapKeyIterator(this.h);
	}
	iterator() {
		return new haxe_ds__$StringMap_StringMapValueIterator(this.h);
	}
	keyValueIterator() {
		return new haxe_ds__$StringMap_StringMapKeyValueIterator(this.h);
	}
}
haxe_ds_StringMap.__name__ = "haxe.ds.StringMap";
haxe_ds_StringMap.__interfaces__ = [haxe_IMap];
Object.assign(haxe_ds_StringMap.prototype, {
	__class__: haxe_ds_StringMap
});
class haxe_ds__$StringMap_StringMapKeyIterator {
	constructor(h) {
		this.h = h;
		this.keys = Object.keys(h);
		this.length = this.keys.length;
		this.current = 0;
	}
	hasNext() {
		return this.current < this.length;
	}
	next() {
		return this.keys[this.current++];
	}
}
haxe_ds__$StringMap_StringMapKeyIterator.__name__ = "haxe.ds._StringMap.StringMapKeyIterator";
Object.assign(haxe_ds__$StringMap_StringMapKeyIterator.prototype, {
	__class__: haxe_ds__$StringMap_StringMapKeyIterator
});
class haxe_ds__$StringMap_StringMapValueIterator {
	constructor(h) {
		this.h = h;
		this.keys = Object.keys(h);
		this.length = this.keys.length;
		this.current = 0;
	}
	hasNext() {
		return this.current < this.length;
	}
	next() {
		return this.h[this.keys[this.current++]];
	}
}
haxe_ds__$StringMap_StringMapValueIterator.__name__ = "haxe.ds._StringMap.StringMapValueIterator";
Object.assign(haxe_ds__$StringMap_StringMapValueIterator.prototype, {
	__class__: haxe_ds__$StringMap_StringMapValueIterator
});
class haxe_ds__$StringMap_StringMapKeyValueIterator {
	constructor(h) {
		this.h = h;
		this.keys = Object.keys(h);
		this.length = this.keys.length;
		this.current = 0;
	}
	hasNext() {
		return this.current < this.length;
	}
	next() {
		let key = this.keys[this.current++];
		return { key : key, value : this.h[key]};
	}
}
haxe_ds__$StringMap_StringMapKeyValueIterator.__name__ = "haxe.ds._StringMap.StringMapKeyValueIterator";
Object.assign(haxe_ds__$StringMap_StringMapKeyValueIterator.prototype, {
	__class__: haxe_ds__$StringMap_StringMapKeyValueIterator
});
class haxe_exceptions_PosException extends haxe_Exception {
	constructor(message,previous,pos) {
		super(message,previous);
		if(pos == null) {
			this.posInfos = { fileName : "(unknown)", lineNumber : 0, className : "(unknown)", methodName : "(unknown)"};
		} else {
			this.posInfos = pos;
		}
	}
	toString() {
		return "" + super.toString() + " in " + this.posInfos.className + "." + this.posInfos.methodName + " at " + this.posInfos.fileName + ":" + this.posInfos.lineNumber;
	}
}
haxe_exceptions_PosException.__name__ = "haxe.exceptions.PosException";
haxe_exceptions_PosException.__super__ = haxe_Exception;
Object.assign(haxe_exceptions_PosException.prototype, {
	__class__: haxe_exceptions_PosException
});
class haxe_exceptions_NotImplementedException extends haxe_exceptions_PosException {
	constructor(message,previous,pos) {
		if(message == null) {
			message = "Not implemented";
		}
		super(message,previous,pos);
	}
}
haxe_exceptions_NotImplementedException.__name__ = "haxe.exceptions.NotImplementedException";
haxe_exceptions_NotImplementedException.__super__ = haxe_exceptions_PosException;
Object.assign(haxe_exceptions_NotImplementedException.prototype, {
	__class__: haxe_exceptions_NotImplementedException
});
class haxe_http_HttpBase {
	constructor(url) {
		if(haxe_http_HttpBase._hx_skip_constructor) {
			return;
		}
		this._hx_constructor(url);
	}
	_hx_constructor(url) {
		this.url = url;
		this.headers = [];
		this.params = [];
		this.emptyOnData = $bind(this,this.onData);
	}
	setHeader(name,value) {
		let _g = 0;
		let _g1 = this.headers.length;
		while(_g < _g1) {
			let i = _g++;
			if(this.headers[i].name == name) {
				this.headers[i] = { name : name, value : value};
				return;
			}
		}
		this.headers.push({ name : name, value : value});
	}
	setPostData(data) {
		this.postData = data;
		this.postBytes = null;
	}
	onData(data) {
	}
	onBytes(data) {
	}
	onError(msg) {
	}
	onStatus(status) {
	}
	hasOnData() {
		return $bind(this,this.onData) != this.emptyOnData;
	}
	success(data) {
		this.responseBytes = data;
		this.responseAsString = null;
		if(this.hasOnData()) {
			this.onData(this.get_responseData());
		}
		this.onBytes(this.responseBytes);
	}
	get_responseData() {
		if(this.responseAsString == null && this.responseBytes != null) {
			this.responseAsString = this.responseBytes.getString(0,this.responseBytes.length,haxe_io_Encoding.UTF8);
		}
		return this.responseAsString;
	}
}
haxe_http_HttpBase.__name__ = "haxe.http.HttpBase";
Object.assign(haxe_http_HttpBase.prototype, {
	__class__: haxe_http_HttpBase
});
class haxe_http_HttpJs extends haxe_http_HttpBase {
	constructor(url) {
		haxe_http_HttpBase._hx_skip_constructor = true;
		super();
		haxe_http_HttpBase._hx_skip_constructor = false;
		this._hx_constructor(url);
	}
	_hx_constructor(url) {
		this.async = true;
		this.withCredentials = false;
		super._hx_constructor(url);
	}
	request(post) {
		this.responseAsString = null;
		this.responseBytes = null;
		this.responseHeaders = null;
		let r = this.req = js_Browser.createXMLHttpRequest();
		let _gthis = this;
		let onreadystatechange = function(_) {
			if(r.readyState != 4) {
				return;
			}
			let s;
			try {
				s = r.status;
			} catch( _g ) {
				s = null;
			}
			if(s == 0 && js_Browser.get_supported() && $global.location != null) {
				let protocol = $global.location.protocol.toLowerCase();
				let rlocalProtocol = new EReg("^(?:about|app|app-storage|.+-extension|file|res|widget):$","");
				let isLocal = rlocalProtocol.match(protocol);
				if(isLocal) {
					s = r.response != null ? 200 : 404;
				}
			}
			if(s == undefined) {
				s = null;
			}
			if(s != null) {
				_gthis.onStatus(s);
			}
			if(s != null && s >= 200 && s < 400) {
				_gthis.req = null;
				let headers = r.getAllResponseHeaders().split("\r\n");
				let _g = [];
				let _g1 = 0;
				let _g2 = headers;
				while(_g1 < _g2.length) {
					let v = _g2[_g1];
					++_g1;
					if(v != "") {
						_g.push(v);
					}
				}
				headers = _g;
				let onreadystatechange = new haxe_ds_StringMap();
				_gthis.responseHeaders = onreadystatechange;
				let _g3 = 0;
				while(_g3 < headers.length) {
					let hline = headers[_g3];
					++_g3;
					let a = hline.split(": ");
					let hname = a.shift();
					let hval = a.length == 1 ? a[0] : a.join(": ");
					hval = StringTools.ltrim(StringTools.rtrim(hval));
					_gthis.responseHeaders.h[hname] = hval;
				}
				_gthis.success(haxe_io_Bytes.ofData(r.response));
			} else if(s == null || s == 0 && r.response == null) {
				_gthis.req = null;
				_gthis.onError("Failed to connect or resolve host");
			} else if(s == null) {
				_gthis.req = null;
				let onreadystatechange = r.response != null ? haxe_io_Bytes.ofData(r.response) : null;
				_gthis.responseBytes = onreadystatechange;
				_gthis.onError("Http Error #" + r.status);
			} else {
				switch(s) {
				case 12007:
					_gthis.req = null;
					_gthis.onError("Unknown host");
					break;
				case 12029:
					_gthis.req = null;
					_gthis.onError("Failed to connect to host");
					break;
				default:
					_gthis.req = null;
					let onreadystatechange = r.response != null ? haxe_io_Bytes.ofData(r.response) : null;
					_gthis.responseBytes = onreadystatechange;
					_gthis.onError("Http Error #" + r.status);
				}
			}
		};
		if(this.async) {
			r.onreadystatechange = onreadystatechange;
		}
		let uri;
		let _g = this.postData;
		let _g1 = this.postBytes;
		if(_g == null) {
			if(_g1 == null) {
				uri = null;
			} else {
				let bytes = _g1;
				uri = new Blob([bytes.b.bufferValue]);
			}
		} else if(_g1 == null) {
			let str = _g;
			uri = str;
		} else {
			uri = null;
		}
		if(uri != null) {
			post = true;
		} else {
			let _g = 0;
			let _g1 = this.params;
			while(_g < _g1.length) {
				let p = _g1[_g];
				++_g;
				if(uri == null) {
					uri = "";
				} else {
					uri = (uri == null ? "null" : Std.string(uri)) + "&";
				}
				let s = p.name;
				let uri1 = (uri == null ? "null" : Std.string(uri)) + encodeURIComponent(s) + "=";
				let s1 = p.value;
				uri = uri1 + encodeURIComponent(s1);
			}
		}
		try {
			if(post) {
				r.open("POST",this.url,this.async);
			} else if(uri != null) {
				let question = this.url.split("?").length <= 1;
				r.open("GET",this.url + (question ? "?" : "&") + (uri == null ? "null" : Std.string(uri)),this.async);
				uri = null;
			} else {
				r.open("GET",this.url,this.async);
			}
			r.responseType = "arraybuffer";
		} catch( _g ) {
			let e = haxe_Exception.caught(_g).unwrap();
			this.req = null;
			this.onError(e.toString());
			return;
		}
		r.withCredentials = this.withCredentials;
		if(!Lambda.exists(this.headers,function(h) {
			return h.name == "Content-Type";
		}) && post && this.postData == null) {
			r.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
		}
		let _g2 = 0;
		let _g3 = this.headers;
		while(_g2 < _g3.length) {
			let h = _g3[_g2];
			++_g2;
			r.setRequestHeader(h.name,h.value);
		}
		r.send(uri);
		if(!this.async) {
			onreadystatechange(null);
		}
	}
}
haxe_http_HttpJs.__name__ = "haxe.http.HttpJs";
haxe_http_HttpJs.__super__ = haxe_http_HttpBase;
Object.assign(haxe_http_HttpJs.prototype, {
	__class__: haxe_http_HttpJs
});
class haxe_io_BytesBuffer {
	constructor() {
		this.pos = 0;
		this.size = 0;
	}
	addByte(byte) {
		if(this.pos == this.size) {
			this.grow(1);
		}
		this.view.setUint8(this.pos++,byte);
	}
	addBytes(src,pos,len) {
		if(pos < 0 || len < 0 || pos + len > src.length) {
			throw haxe_Exception.thrown(haxe_io_Error.OutsideBounds);
		}
		if(this.pos + len > this.size) {
			this.grow(len);
		}
		if(this.size == 0) {
			return;
		}
		let sub = new Uint8Array(src.b.buffer,src.b.byteOffset + pos,len);
		this.u8.set(sub,this.pos);
		this.pos += len;
	}
	grow(delta) {
		let req = this.pos + delta;
		let nsize = this.size == 0 ? 16 : this.size;
		while(nsize < req) nsize = nsize * 3 >> 1;
		let nbuf = new ArrayBuffer(nsize);
		let nu8 = new Uint8Array(nbuf);
		if(this.size > 0) {
			nu8.set(this.u8);
		}
		this.size = nsize;
		this.buffer = nbuf;
		this.u8 = nu8;
		this.view = new DataView(this.buffer);
	}
	getBytes() {
		if(this.size == 0) {
			return new haxe_io_Bytes(new ArrayBuffer(0));
		}
		let b = new haxe_io_Bytes(this.buffer);
		b.length = this.pos;
		return b;
	}
}
haxe_io_BytesBuffer.__name__ = "haxe.io.BytesBuffer";
Object.assign(haxe_io_BytesBuffer.prototype, {
	__class__: haxe_io_BytesBuffer
});
class haxe_io_Input {
	readByte() {
		throw new haxe_exceptions_NotImplementedException(null,null,{ fileName : "haxe/io/Input.hx", lineNumber : 53, className : "haxe.io.Input", methodName : "readByte"});
	}
	readBytes(s,pos,len) {
		let k = len;
		let b = s.b;
		if(pos < 0 || len < 0 || pos + len > s.length) {
			throw haxe_Exception.thrown(haxe_io_Error.OutsideBounds);
		}
		try {
			while(k > 0) {
				b[pos] = this.readByte();
				++pos;
				--k;
			}
		} catch( _g ) {
			if(!((haxe_Exception.caught(_g).unwrap()) instanceof haxe_io_Eof)) {
				throw _g;
			}
		}
		return len - k;
	}
	close() {
	}
	set_bigEndian(b) {
		this.bigEndian = b;
		return b;
	}
	readUntil(end) {
		let buf = new haxe_io_BytesBuffer();
		let last;
		while(true) {
			last = this.readByte();
			if(!(last != end)) {
				break;
			}
			buf.addByte(last);
		}
		return buf.getBytes().toString();
	}
	readInt32() {
		let ch1 = this.readByte();
		let ch2 = this.readByte();
		let ch3 = this.readByte();
		let ch4 = this.readByte();
		if(this.bigEndian) {
			return ch4 | ch3 << 8 | ch2 << 16 | ch1 << 24;
		} else {
			return ch1 | ch2 << 8 | ch3 << 16 | ch4 << 24;
		}
	}
}
haxe_io_Input.__name__ = "haxe.io.Input";
Object.assign(haxe_io_Input.prototype, {
	__class__: haxe_io_Input
});
class haxe_io_BytesInput extends haxe_io_Input {
	constructor(b,pos,len) {
		super();
		if(pos == null) {
			pos = 0;
		}
		if(len == null) {
			len = b.length - pos;
		}
		if(pos < 0 || len < 0 || pos + len > b.length) {
			throw haxe_Exception.thrown(haxe_io_Error.OutsideBounds);
		}
		this.b = b.b;
		this.pos = pos;
		this.len = len;
		this.totlen = len;
	}
	readByte() {
		if(this.len == 0) {
			throw haxe_Exception.thrown(new haxe_io_Eof());
		}
		this.len--;
		return this.b[this.pos++];
	}
	readBytes(buf,pos,len) {
		if(pos < 0 || len < 0 || pos + len > buf.length) {
			throw haxe_Exception.thrown(haxe_io_Error.OutsideBounds);
		}
		if(this.len == 0 && len > 0) {
			throw haxe_Exception.thrown(new haxe_io_Eof());
		}
		if(this.len < len) {
			len = this.len;
		}
		let b1 = this.b;
		let b2 = buf.b;
		let _g = 0;
		let _g1 = len;
		while(_g < _g1) {
			let i = _g++;
			b2[pos + i] = b1[this.pos + i];
		}
		this.pos += len;
		this.len -= len;
		return len;
	}
}
haxe_io_BytesInput.__name__ = "haxe.io.BytesInput";
haxe_io_BytesInput.__super__ = haxe_io_Input;
Object.assign(haxe_io_BytesInput.prototype, {
	__class__: haxe_io_BytesInput
});
class haxe_io_Output {
	writeByte(c) {
		throw new haxe_exceptions_NotImplementedException(null,null,{ fileName : "haxe/io/Output.hx", lineNumber : 47, className : "haxe.io.Output", methodName : "writeByte"});
	}
	writeBytes(s,pos,len) {
		if(pos < 0 || len < 0 || pos + len > s.length) {
			throw haxe_Exception.thrown(haxe_io_Error.OutsideBounds);
		}
		let b = s.b;
		let k = len;
		while(k > 0) {
			this.writeByte(b[pos]);
			++pos;
			--k;
		}
		return len;
	}
	close() {
	}
}
haxe_io_Output.__name__ = "haxe.io.Output";
Object.assign(haxe_io_Output.prototype, {
	__class__: haxe_io_Output
});
class haxe_io_BytesOutput extends haxe_io_Output {
	constructor() {
		super();
		this.b = new haxe_io_BytesBuffer();
	}
	writeByte(c) {
		this.b.addByte(c);
	}
	writeBytes(buf,pos,len) {
		this.b.addBytes(buf,pos,len);
		return len;
	}
	getBytes() {
		return this.b.getBytes();
	}
}
haxe_io_BytesOutput.__name__ = "haxe.io.BytesOutput";
haxe_io_BytesOutput.__super__ = haxe_io_Output;
Object.assign(haxe_io_BytesOutput.prototype, {
	__class__: haxe_io_BytesOutput
});
class haxe_io_Eof {
	constructor() {
	}
	toString() {
		return "Eof";
	}
}
haxe_io_Eof.__name__ = "haxe.io.Eof";
Object.assign(haxe_io_Eof.prototype, {
	__class__: haxe_io_Eof
});
var haxe_io_Error = $hxEnums["haxe.io.Error"] = { __ename__:true,__constructs__:null
	,Blocked: {_hx_name:"Blocked",_hx_index:0,__enum__:"haxe.io.Error",toString:$estr}
	,Overflow: {_hx_name:"Overflow",_hx_index:1,__enum__:"haxe.io.Error",toString:$estr}
	,OutsideBounds: {_hx_name:"OutsideBounds",_hx_index:2,__enum__:"haxe.io.Error",toString:$estr}
	,Custom: ($_=function(e) { return {_hx_index:3,e:e,__enum__:"haxe.io.Error",toString:$estr}; },$_._hx_name="Custom",$_.__params__ = ["e"],$_)
};
haxe_io_Error.__constructs__ = [haxe_io_Error.Blocked,haxe_io_Error.Overflow,haxe_io_Error.OutsideBounds,haxe_io_Error.Custom];
class haxe_io_FPHelper {
	static i64ToDouble(low,high) {
		haxe_io_FPHelper.helper.setInt32(0,low,true);
		haxe_io_FPHelper.helper.setInt32(4,high,true);
		return haxe_io_FPHelper.helper.getFloat64(0,true);
	}
	static doubleToI64(v) {
		let i64 = haxe_io_FPHelper.i64tmp;
		haxe_io_FPHelper.helper.setFloat64(0,v,true);
		i64.low = haxe_io_FPHelper.helper.getInt32(0,true);
		i64.high = haxe_io_FPHelper.helper.getInt32(4,true);
		return i64;
	}
}
haxe_io_FPHelper.__name__ = "haxe.io.FPHelper";
class haxe_iterators_ArrayIterator {
	constructor(array) {
		this.current = 0;
		this.array = array;
	}
	hasNext() {
		return this.current < this.array.length;
	}
	next() {
		return this.array[this.current++];
	}
}
haxe_iterators_ArrayIterator.__name__ = "haxe.iterators.ArrayIterator";
Object.assign(haxe_iterators_ArrayIterator.prototype, {
	__class__: haxe_iterators_ArrayIterator
});
class haxe_iterators_MapKeyValueIterator {
	constructor(map) {
		this.map = map;
		this.keys = map.keys();
	}
	hasNext() {
		return this.keys.hasNext();
	}
	next() {
		let key = this.keys.next();
		return { value : this.map.get(key), key : key};
	}
}
haxe_iterators_MapKeyValueIterator.__name__ = "haxe.iterators.MapKeyValueIterator";
Object.assign(haxe_iterators_MapKeyValueIterator.prototype, {
	__class__: haxe_iterators_MapKeyValueIterator
});
class haxe_xml_XmlParserException {
	constructor(message,xml,position) {
		this.xml = xml;
		this.message = message;
		this.position = position;
		this.lineNumber = 1;
		this.positionAtLine = 0;
		let _g = 0;
		let _g1 = position;
		while(_g < _g1) {
			let i = _g++;
			let c = xml.charCodeAt(i);
			if(c == 10) {
				this.lineNumber++;
				this.positionAtLine = 0;
			} else if(c != 13) {
				this.positionAtLine++;
			}
		}
	}
	toString() {
		let c = js_Boot.getClass(this);
		return c.__name__ + ": " + this.message + " at line " + this.lineNumber + " char " + this.positionAtLine;
	}
}
haxe_xml_XmlParserException.__name__ = "haxe.xml.XmlParserException";
Object.assign(haxe_xml_XmlParserException.prototype, {
	__class__: haxe_xml_XmlParserException
});
class haxe_xml_Parser {
	static parse(str,strict) {
		if(strict == null) {
			strict = false;
		}
		let doc = Xml.createDocument();
		haxe_xml_Parser.doParse(str,strict,0,doc);
		return doc;
	}
	static doParse(str,strict,p,parent) {
		if(p == null) {
			p = 0;
		}
		let xml = null;
		let state = 1;
		let next = 1;
		let aname = null;
		let start = 0;
		let nsubs = 0;
		let nbrackets = 0;
		let buf = new StringBuf();
		let escapeNext = 1;
		let attrValQuote = -1;
		while(p < str.length) {
			let c = str.charCodeAt(p);
			switch(state) {
			case 0:
				switch(c) {
				case 9:case 10:case 13:case 32:
					break;
				default:
					state = next;
					continue;
				}
				break;
			case 1:
				if(c == 60) {
					state = 0;
					next = 2;
				} else {
					start = p;
					state = 13;
					continue;
				}
				break;
			case 2:
				switch(c) {
				case 33:
					if(str.charCodeAt(p + 1) == 91) {
						p += 2;
						if(HxOverrides.substr(str,p,6).toUpperCase() != "CDATA[") {
							throw haxe_Exception.thrown(new haxe_xml_XmlParserException("Expected <![CDATA[",str,p));
						}
						p += 5;
						state = 17;
						start = p + 1;
					} else if(str.charCodeAt(p + 1) == 68 || str.charCodeAt(p + 1) == 100) {
						if(HxOverrides.substr(str,p + 2,6).toUpperCase() != "OCTYPE") {
							throw haxe_Exception.thrown(new haxe_xml_XmlParserException("Expected <!DOCTYPE",str,p));
						}
						p += 8;
						state = 16;
						start = p + 1;
					} else if(str.charCodeAt(p + 1) != 45 || str.charCodeAt(p + 2) != 45) {
						throw haxe_Exception.thrown(new haxe_xml_XmlParserException("Expected <!--",str,p));
					} else {
						p += 2;
						state = 15;
						start = p + 1;
					}
					break;
				case 47:
					if(parent == null) {
						throw haxe_Exception.thrown(new haxe_xml_XmlParserException("Expected node name",str,p));
					}
					start = p + 1;
					state = 0;
					next = 10;
					break;
				case 63:
					state = 14;
					start = p;
					break;
				default:
					state = 3;
					start = p;
					continue;
				}
				break;
			case 3:
				if(!(c >= 97 && c <= 122 || c >= 65 && c <= 90 || c >= 48 && c <= 57 || c == 58 || c == 46 || c == 95 || c == 45)) {
					if(p == start) {
						throw haxe_Exception.thrown(new haxe_xml_XmlParserException("Expected node name",str,p));
					}
					xml = Xml.createElement(HxOverrides.substr(str,start,p - start));
					parent.addChild(xml);
					++nsubs;
					state = 0;
					next = 4;
					continue;
				}
				break;
			case 4:
				switch(c) {
				case 47:
					state = 11;
					break;
				case 62:
					state = 9;
					break;
				default:
					state = 5;
					start = p;
					continue;
				}
				break;
			case 5:
				if(!(c >= 97 && c <= 122 || c >= 65 && c <= 90 || c >= 48 && c <= 57 || c == 58 || c == 46 || c == 95 || c == 45)) {
					if(start == p) {
						throw haxe_Exception.thrown(new haxe_xml_XmlParserException("Expected attribute name",str,p));
					}
					let tmp = HxOverrides.substr(str,start,p - start);
					aname = tmp;
					if(xml.exists(aname)) {
						throw haxe_Exception.thrown(new haxe_xml_XmlParserException("Duplicate attribute [" + aname + "]",str,p));
					}
					state = 0;
					next = 6;
					continue;
				}
				break;
			case 6:
				if(c == 61) {
					state = 0;
					next = 7;
				} else {
					throw haxe_Exception.thrown(new haxe_xml_XmlParserException("Expected =",str,p));
				}
				break;
			case 7:
				switch(c) {
				case 34:case 39:
					buf = new StringBuf();
					state = 8;
					start = p + 1;
					attrValQuote = c;
					break;
				default:
					throw haxe_Exception.thrown(new haxe_xml_XmlParserException("Expected \"",str,p));
				}
				break;
			case 8:
				switch(c) {
				case 38:
					let len = p - start;
					buf.b += len == null ? HxOverrides.substr(str,start,null) : HxOverrides.substr(str,start,len);
					state = 18;
					escapeNext = 8;
					start = p + 1;
					break;
				case 60:case 62:
					if(strict) {
						throw haxe_Exception.thrown(new haxe_xml_XmlParserException("Invalid unescaped " + String.fromCodePoint(c) + " in attribute value",str,p));
					} else if(c == attrValQuote) {
						let len = p - start;
						buf.b += len == null ? HxOverrides.substr(str,start,null) : HxOverrides.substr(str,start,len);
						let val = buf.b;
						buf = new StringBuf();
						xml.set(aname,val);
						state = 0;
						next = 4;
					}
					break;
				default:
					if(c == attrValQuote) {
						let len = p - start;
						buf.b += len == null ? HxOverrides.substr(str,start,null) : HxOverrides.substr(str,start,len);
						let val = buf.b;
						buf = new StringBuf();
						xml.set(aname,val);
						state = 0;
						next = 4;
					}
				}
				break;
			case 9:
				p = haxe_xml_Parser.doParse(str,strict,p,xml);
				start = p;
				state = 1;
				break;
			case 10:
				if(!(c >= 97 && c <= 122 || c >= 65 && c <= 90 || c >= 48 && c <= 57 || c == 58 || c == 46 || c == 95 || c == 45)) {
					if(start == p) {
						throw haxe_Exception.thrown(new haxe_xml_XmlParserException("Expected node name",str,p));
					}
					let v = HxOverrides.substr(str,start,p - start);
					if(parent == null || parent.nodeType != 0) {
						throw haxe_Exception.thrown(new haxe_xml_XmlParserException("Unexpected </" + v + ">, tag is not open",str,p));
					}
					if(parent.nodeType != Xml.Element) {
						throw haxe_Exception.thrown("Bad node type, expected Element but found " + (parent.nodeType == null ? "null" : XmlType.toString(parent.nodeType)));
					}
					if(v != parent.nodeName) {
						if(parent.nodeType != Xml.Element) {
							throw haxe_Exception.thrown("Bad node type, expected Element but found " + (parent.nodeType == null ? "null" : XmlType.toString(parent.nodeType)));
						}
						throw haxe_Exception.thrown(new haxe_xml_XmlParserException("Expected </" + parent.nodeName + ">",str,p));
					}
					state = 0;
					next = 12;
					continue;
				}
				break;
			case 11:
				if(c == 62) {
					state = 1;
				} else {
					throw haxe_Exception.thrown(new haxe_xml_XmlParserException("Expected >",str,p));
				}
				break;
			case 12:
				if(c == 62) {
					if(nsubs == 0) {
						parent.addChild(Xml.createPCData(""));
					}
					return p;
				} else {
					throw haxe_Exception.thrown(new haxe_xml_XmlParserException("Expected >",str,p));
				}
				break;
			case 13:
				if(c == 60) {
					let len = p - start;
					buf.b += len == null ? HxOverrides.substr(str,start,null) : HxOverrides.substr(str,start,len);
					let child = Xml.createPCData(buf.b);
					buf = new StringBuf();
					parent.addChild(child);
					++nsubs;
					state = 0;
					next = 2;
				} else if(c == 38) {
					let len = p - start;
					buf.b += len == null ? HxOverrides.substr(str,start,null) : HxOverrides.substr(str,start,len);
					state = 18;
					escapeNext = 13;
					start = p + 1;
				}
				break;
			case 14:
				if(c == 63 && str.charCodeAt(p + 1) == 62) {
					++p;
					let str1 = HxOverrides.substr(str,start + 1,p - start - 2);
					parent.addChild(Xml.createProcessingInstruction(str1));
					++nsubs;
					state = 1;
				}
				break;
			case 15:
				if(c == 45 && str.charCodeAt(p + 1) == 45 && str.charCodeAt(p + 2) == 62) {
					parent.addChild(Xml.createComment(HxOverrides.substr(str,start,p - start)));
					++nsubs;
					p += 2;
					state = 1;
				}
				break;
			case 16:
				if(c == 91) {
					++nbrackets;
				} else if(c == 93) {
					--nbrackets;
				} else if(c == 62 && nbrackets == 0) {
					parent.addChild(Xml.createDocType(HxOverrides.substr(str,start,p - start)));
					++nsubs;
					state = 1;
				}
				break;
			case 17:
				if(c == 93 && str.charCodeAt(p + 1) == 93 && str.charCodeAt(p + 2) == 62) {
					let child = Xml.createCData(HxOverrides.substr(str,start,p - start));
					parent.addChild(child);
					++nsubs;
					p += 2;
					state = 1;
				}
				break;
			case 18:
				if(c == 59) {
					let s = HxOverrides.substr(str,start,p - start);
					if(s.charCodeAt(0) == 35) {
						let c = s.charCodeAt(1) == 120 ? Std.parseInt("0" + HxOverrides.substr(s,1,s.length - 1)) : Std.parseInt(HxOverrides.substr(s,1,s.length - 1));
						buf.b += String.fromCodePoint(c);
					} else if(!Object.prototype.hasOwnProperty.call(haxe_xml_Parser.escapes.h,s)) {
						if(strict) {
							throw haxe_Exception.thrown(new haxe_xml_XmlParserException("Undefined entity: " + s,str,p));
						}
						buf.b += Std.string("&" + s + ";");
					} else {
						buf.b += Std.string(haxe_xml_Parser.escapes.h[s]);
					}
					start = p + 1;
					state = escapeNext;
				} else if(!(c >= 97 && c <= 122 || c >= 65 && c <= 90 || c >= 48 && c <= 57 || c == 58 || c == 46 || c == 95 || c == 45) && c != 35) {
					if(strict) {
						throw haxe_Exception.thrown(new haxe_xml_XmlParserException("Invalid character in entity: " + String.fromCodePoint(c),str,p));
					}
					buf.b += String.fromCodePoint(38);
					let len = p - start;
					buf.b += len == null ? HxOverrides.substr(str,start,null) : HxOverrides.substr(str,start,len);
					--p;
					start = p + 1;
					state = escapeNext;
				}
				break;
			}
			++p;
		}
		if(state == 1) {
			start = p;
			state = 13;
		}
		if(state == 13) {
			if(parent.nodeType == 0) {
				if(parent.nodeType != Xml.Element) {
					throw haxe_Exception.thrown("Bad node type, expected Element but found " + (parent.nodeType == null ? "null" : XmlType.toString(parent.nodeType)));
				}
				throw haxe_Exception.thrown(new haxe_xml_XmlParserException("Unclosed node <" + parent.nodeName + ">",str,p));
			}
			if(p != start || nsubs == 0) {
				let len = p - start;
				buf.b += len == null ? HxOverrides.substr(str,start,null) : HxOverrides.substr(str,start,len);
				parent.addChild(Xml.createPCData(buf.b));
				++nsubs;
			}
			return p;
		}
		if(!strict && state == 18 && escapeNext == 13) {
			buf.b += String.fromCodePoint(38);
			let len = p - start;
			buf.b += len == null ? HxOverrides.substr(str,start,null) : HxOverrides.substr(str,start,len);
			parent.addChild(Xml.createPCData(buf.b));
			++nsubs;
			return p;
		}
		throw haxe_Exception.thrown(new haxe_xml_XmlParserException("Unexpected end",str,p));
	}
}
haxe_xml_Parser.__name__ = "haxe.xml.Parser";
class haxe_xml_Printer {
	constructor(pretty) {
		this.output = new StringBuf();
		this.pretty = pretty;
	}
	writeNode(value,tabs) {
		switch(value.nodeType) {
		case 0:
			this.output.b += Std.string(tabs + "<");
			if(value.nodeType != Xml.Element) {
				throw haxe_Exception.thrown("Bad node type, expected Element but found " + (value.nodeType == null ? "null" : XmlType.toString(value.nodeType)));
			}
			this.output.b += Std.string(value.nodeName);
			let attribute = value.attributes();
			while(attribute.hasNext()) {
				let attribute1 = attribute.next();
				this.output.b += Std.string(" " + attribute1 + "=\"");
				let input = StringTools.htmlEscape(value.get(attribute1),true);
				this.output.b += Std.string(input);
				this.output.b += "\"";
			}
			if(this.hasChildren(value)) {
				this.output.b += ">";
				if(this.pretty) {
					this.output.b += "\n";
				}
				if(value.nodeType != Xml.Document && value.nodeType != Xml.Element) {
					throw haxe_Exception.thrown("Bad node type, expected Element or Document but found " + (value.nodeType == null ? "null" : XmlType.toString(value.nodeType)));
				}
				let _g_current = 0;
				let _g_array = value.children;
				while(_g_current < _g_array.length) {
					let child = _g_array[_g_current++];
					this.writeNode(child,this.pretty ? tabs + "\t" : tabs);
				}
				this.output.b += Std.string(tabs + "</");
				if(value.nodeType != Xml.Element) {
					throw haxe_Exception.thrown("Bad node type, expected Element but found " + (value.nodeType == null ? "null" : XmlType.toString(value.nodeType)));
				}
				this.output.b += Std.string(value.nodeName);
				this.output.b += ">";
				if(this.pretty) {
					this.output.b += "\n";
				}
			} else {
				this.output.b += "/>";
				if(this.pretty) {
					this.output.b += "\n";
				}
			}
			break;
		case 1:
			if(value.nodeType == Xml.Document || value.nodeType == Xml.Element) {
				throw haxe_Exception.thrown("Bad node type, unexpected " + (value.nodeType == null ? "null" : XmlType.toString(value.nodeType)));
			}
			let nodeValue = value.nodeValue;
			if(nodeValue.length != 0) {
				let input = tabs + StringTools.htmlEscape(nodeValue);
				this.output.b += Std.string(input);
				if(this.pretty) {
					this.output.b += "\n";
				}
			}
			break;
		case 2:
			this.output.b += Std.string(tabs + "<![CDATA[");
			if(value.nodeType == Xml.Document || value.nodeType == Xml.Element) {
				throw haxe_Exception.thrown("Bad node type, unexpected " + (value.nodeType == null ? "null" : XmlType.toString(value.nodeType)));
			}
			this.output.b += Std.string(value.nodeValue);
			this.output.b += "]]>";
			if(this.pretty) {
				this.output.b += "\n";
			}
			break;
		case 3:
			if(value.nodeType == Xml.Document || value.nodeType == Xml.Element) {
				throw haxe_Exception.thrown("Bad node type, unexpected " + (value.nodeType == null ? "null" : XmlType.toString(value.nodeType)));
			}
			let commentContent = value.nodeValue;
			let _this_r = new RegExp("[\n\r\t]+","g".split("u").join(""));
			commentContent = commentContent.replace(_this_r,"");
			commentContent = "<!--" + commentContent + "-->";
			this.output.b += tabs == null ? "null" : "" + tabs;
			let input = StringTools.trim(commentContent);
			this.output.b += Std.string(input);
			if(this.pretty) {
				this.output.b += "\n";
			}
			break;
		case 4:
			if(value.nodeType == Xml.Document || value.nodeType == Xml.Element) {
				throw haxe_Exception.thrown("Bad node type, unexpected " + (value.nodeType == null ? "null" : XmlType.toString(value.nodeType)));
			}
			this.output.b += Std.string("<!DOCTYPE " + value.nodeValue + ">");
			if(this.pretty) {
				this.output.b += "\n";
			}
			break;
		case 5:
			if(value.nodeType == Xml.Document || value.nodeType == Xml.Element) {
				throw haxe_Exception.thrown("Bad node type, unexpected " + (value.nodeType == null ? "null" : XmlType.toString(value.nodeType)));
			}
			this.output.b += Std.string("<?" + value.nodeValue + "?>");
			if(this.pretty) {
				this.output.b += "\n";
			}
			break;
		case 6:
			if(value.nodeType != Xml.Document && value.nodeType != Xml.Element) {
				throw haxe_Exception.thrown("Bad node type, expected Element or Document but found " + (value.nodeType == null ? "null" : XmlType.toString(value.nodeType)));
			}
			let _g_current = 0;
			let _g_array = value.children;
			while(_g_current < _g_array.length) {
				let child = _g_array[_g_current++];
				this.writeNode(child,tabs);
			}
			break;
		}
	}
	hasChildren(value) {
		if(value.nodeType != Xml.Document && value.nodeType != Xml.Element) {
			throw haxe_Exception.thrown("Bad node type, expected Element or Document but found " + (value.nodeType == null ? "null" : XmlType.toString(value.nodeType)));
		}
		let _g_current = 0;
		let _g_array = value.children;
		while(_g_current < _g_array.length) {
			let child = _g_array[_g_current++];
			switch(child.nodeType) {
			case 0:case 1:
				return true;
			case 2:case 3:
				if(child.nodeType == Xml.Document || child.nodeType == Xml.Element) {
					throw haxe_Exception.thrown("Bad node type, unexpected " + (child.nodeType == null ? "null" : XmlType.toString(child.nodeType)));
				}
				if(StringTools.ltrim(child.nodeValue).length != 0) {
					return true;
				}
				break;
			default:
			}
		}
		return false;
	}
	static print(xml,pretty) {
		if(pretty == null) {
			pretty = false;
		}
		let printer = new haxe_xml_Printer(pretty);
		printer.writeNode(xml,"");
		return printer.output.b;
	}
}
haxe_xml_Printer.__name__ = "haxe.xml.Printer";
Object.assign(haxe_xml_Printer.prototype, {
	__class__: haxe_xml_Printer
});
class hsluv_Hsluv {
	constructor() {
	}
	rgbToHex() {
		this.hex = "#";
		this.hex += hsluv_Hsluv.rgbChannelToHex(this.rgb_r);
		this.hex += hsluv_Hsluv.rgbChannelToHex(this.rgb_g);
		this.hex += hsluv_Hsluv.rgbChannelToHex(this.rgb_b);
	}
	hexToRgb() {
		this.hex = this.hex.toLowerCase();
		this.rgb_r = hsluv_Hsluv.hexToRgbChannel(this.hex,1);
		this.rgb_g = hsluv_Hsluv.hexToRgbChannel(this.hex,3);
		this.rgb_b = hsluv_Hsluv.hexToRgbChannel(this.hex,5);
	}
	xyzToRgb() {
		this.rgb_r = hsluv_Hsluv.fromLinear(hsluv_Hsluv.m_r0 * this.xyz_x + hsluv_Hsluv.m_r1 * this.xyz_y + hsluv_Hsluv.m_r2 * this.xyz_z);
		this.rgb_g = hsluv_Hsluv.fromLinear(hsluv_Hsluv.m_g0 * this.xyz_x + hsluv_Hsluv.m_g1 * this.xyz_y + hsluv_Hsluv.m_g2 * this.xyz_z);
		this.rgb_b = hsluv_Hsluv.fromLinear(hsluv_Hsluv.m_b0 * this.xyz_x + hsluv_Hsluv.m_b1 * this.xyz_y + hsluv_Hsluv.m_b2 * this.xyz_z);
	}
	rgbToXyz() {
		let lr = hsluv_Hsluv.toLinear(this.rgb_r);
		let lg = hsluv_Hsluv.toLinear(this.rgb_g);
		let lb = hsluv_Hsluv.toLinear(this.rgb_b);
		this.xyz_x = 0.41239079926595 * lr + 0.35758433938387 * lg + 0.18048078840183 * lb;
		this.xyz_y = 0.21263900587151 * lr + 0.71516867876775 * lg + 0.072192315360733 * lb;
		this.xyz_z = 0.019330818715591 * lr + 0.11919477979462 * lg + 0.95053215224966 * lb;
	}
	xyzToLuv() {
		let divider = this.xyz_x + 15 * this.xyz_y + 3 * this.xyz_z;
		let varU = 4 * this.xyz_x;
		let varV = 9 * this.xyz_y;
		if(divider != 0) {
			varU /= divider;
			varV /= divider;
		} else {
			varU = NaN;
			varV = NaN;
		}
		this.luv_l = hsluv_Hsluv.yToL(this.xyz_y);
		if(this.luv_l == 0) {
			this.luv_u = 0;
			this.luv_v = 0;
		} else {
			this.luv_u = 13 * this.luv_l * (varU - hsluv_Hsluv.refU);
			this.luv_v = 13 * this.luv_l * (varV - hsluv_Hsluv.refV);
		}
	}
	luvToXyz() {
		if(this.luv_l == 0) {
			this.xyz_x = 0;
			this.xyz_y = 0;
			this.xyz_z = 0;
			return;
		}
		let varU = this.luv_u / (13 * this.luv_l) + hsluv_Hsluv.refU;
		let varV = this.luv_v / (13 * this.luv_l) + hsluv_Hsluv.refV;
		this.xyz_y = hsluv_Hsluv.lToY(this.luv_l);
		this.xyz_x = 0 - 9 * this.xyz_y * varU / ((varU - 4) * varV - varU * varV);
		this.xyz_z = (9 * this.xyz_y - 15 * varV * this.xyz_y - varV * this.xyz_x) / (3 * varV);
	}
	luvToLch() {
		this.lch_l = this.luv_l;
		this.lch_c = Math.sqrt(this.luv_u * this.luv_u + this.luv_v * this.luv_v);
		if(this.lch_c < 0.00000001) {
			this.lch_h = 0;
		} else {
			let Hrad = Math.atan2(this.luv_v,this.luv_u);
			this.lch_h = Hrad * 180.0 / Math.PI;
			if(this.lch_h < 0) {
				this.lch_h = 360 + this.lch_h;
			}
		}
	}
	lchToLuv() {
		let Hrad = this.lch_h / 180.0 * Math.PI;
		this.luv_l = this.lch_l;
		this.luv_u = Math.cos(Hrad) * this.lch_c;
		this.luv_v = Math.sin(Hrad) * this.lch_c;
	}
	calculateBoundingLines(l) {
		let sub1 = Math.pow(l + 16,3) / 1560896;
		let sub2 = sub1 > hsluv_Hsluv.epsilon ? sub1 : l / hsluv_Hsluv.kappa;
		let s1r = sub2 * (284517 * hsluv_Hsluv.m_r0 - 94839 * hsluv_Hsluv.m_r2);
		let s2r = sub2 * (838422 * hsluv_Hsluv.m_r2 + 769860 * hsluv_Hsluv.m_r1 + 731718 * hsluv_Hsluv.m_r0);
		let s3r = sub2 * (632260 * hsluv_Hsluv.m_r2 - 126452 * hsluv_Hsluv.m_r1);
		let s1g = sub2 * (284517 * hsluv_Hsluv.m_g0 - 94839 * hsluv_Hsluv.m_g2);
		let s2g = sub2 * (838422 * hsluv_Hsluv.m_g2 + 769860 * hsluv_Hsluv.m_g1 + 731718 * hsluv_Hsluv.m_g0);
		let s3g = sub2 * (632260 * hsluv_Hsluv.m_g2 - 126452 * hsluv_Hsluv.m_g1);
		let s1b = sub2 * (284517 * hsluv_Hsluv.m_b0 - 94839 * hsluv_Hsluv.m_b2);
		let s2b = sub2 * (838422 * hsluv_Hsluv.m_b2 + 769860 * hsluv_Hsluv.m_b1 + 731718 * hsluv_Hsluv.m_b0);
		let s3b = sub2 * (632260 * hsluv_Hsluv.m_b2 - 126452 * hsluv_Hsluv.m_b1);
		this.r0s = s1r / s3r;
		this.r0i = s2r * l / s3r;
		this.r1s = s1r / (s3r + 126452);
		this.r1i = (s2r - 769860) * l / (s3r + 126452);
		this.g0s = s1g / s3g;
		this.g0i = s2g * l / s3g;
		this.g1s = s1g / (s3g + 126452);
		this.g1i = (s2g - 769860) * l / (s3g + 126452);
		this.b0s = s1b / s3b;
		this.b0i = s2b * l / s3b;
		this.b1s = s1b / (s3b + 126452);
		this.b1i = (s2b - 769860) * l / (s3b + 126452);
	}
	calcMaxChromaHpluv() {
		let r0 = hsluv_Hsluv.distanceFromOrigin(this.r0s,this.r0i);
		let r1 = hsluv_Hsluv.distanceFromOrigin(this.r1s,this.r1i);
		let g0 = hsluv_Hsluv.distanceFromOrigin(this.g0s,this.g0i);
		let g1 = hsluv_Hsluv.distanceFromOrigin(this.g1s,this.g1i);
		let b0 = hsluv_Hsluv.distanceFromOrigin(this.b0s,this.b0i);
		let b1 = hsluv_Hsluv.distanceFromOrigin(this.b1s,this.b1i);
		return hsluv_Hsluv.min6(r0,r1,g0,g1,b0,b1);
	}
	calcMaxChromaHsluv(h) {
		let hueRad = h / 360 * Math.PI * 2;
		let r0 = hsluv_Hsluv.distanceFromOriginAngle(this.r0s,this.r0i,hueRad);
		let r1 = hsluv_Hsluv.distanceFromOriginAngle(this.r1s,this.r1i,hueRad);
		let g0 = hsluv_Hsluv.distanceFromOriginAngle(this.g0s,this.g0i,hueRad);
		let g1 = hsluv_Hsluv.distanceFromOriginAngle(this.g1s,this.g1i,hueRad);
		let b0 = hsluv_Hsluv.distanceFromOriginAngle(this.b0s,this.b0i,hueRad);
		let b1 = hsluv_Hsluv.distanceFromOriginAngle(this.b1s,this.b1i,hueRad);
		return hsluv_Hsluv.min6(r0,r1,g0,g1,b0,b1);
	}
	hsluvToLch() {
		if(this.hsluv_l > 99.9999999) {
			this.lch_l = 100;
			this.lch_c = 0;
		} else if(this.hsluv_l < 0.00000001) {
			this.lch_l = 0;
			this.lch_c = 0;
		} else {
			this.lch_l = this.hsluv_l;
			this.calculateBoundingLines(this.hsluv_l);
			let max = this.calcMaxChromaHsluv(this.hsluv_h);
			this.lch_c = max / 100 * this.hsluv_s;
		}
		this.lch_h = this.hsluv_h;
	}
	lchToHsluv() {
		if(this.lch_l > 99.9999999) {
			this.hsluv_s = 0;
			this.hsluv_l = 100;
		} else if(this.lch_l < 0.00000001) {
			this.hsluv_s = 0;
			this.hsluv_l = 0;
		} else {
			this.calculateBoundingLines(this.lch_l);
			let max = this.calcMaxChromaHsluv(this.lch_h);
			this.hsluv_s = this.lch_c / max * 100;
			this.hsluv_l = this.lch_l;
		}
		this.hsluv_h = this.lch_h;
	}
	hpluvToLch() {
		if(this.hpluv_l > 99.9999999) {
			this.lch_l = 100;
			this.lch_c = 0;
		} else if(this.hpluv_l < 0.00000001) {
			this.lch_l = 0;
			this.lch_c = 0;
		} else {
			this.lch_l = this.hpluv_l;
			this.calculateBoundingLines(this.hpluv_l);
			let max = this.calcMaxChromaHpluv();
			this.lch_c = max / 100 * this.hpluv_p;
		}
		this.lch_h = this.hpluv_h;
	}
	lchToHpluv() {
		if(this.lch_l > 99.9999999) {
			this.hpluv_p = 0;
			this.hpluv_l = 100;
		} else if(this.lch_l < 0.00000001) {
			this.hpluv_p = 0;
			this.hpluv_l = 0;
		} else {
			this.calculateBoundingLines(this.lch_l);
			let max = this.calcMaxChromaHpluv();
			this.hpluv_p = this.lch_c / max * 100;
			this.hpluv_l = this.lch_l;
		}
		this.hpluv_h = this.lch_h;
	}
	hsluvToRgb() {
		this.hsluvToLch();
		this.lchToLuv();
		this.luvToXyz();
		this.xyzToRgb();
	}
	hpluvToRgb() {
		this.hpluvToLch();
		this.lchToLuv();
		this.luvToXyz();
		this.xyzToRgb();
	}
	hsluvToHex() {
		this.hsluvToRgb();
		this.rgbToHex();
	}
	hpluvToHex() {
		this.hpluvToRgb();
		this.rgbToHex();
	}
	rgbToHsluv() {
		this.rgbToXyz();
		this.xyzToLuv();
		this.luvToLch();
		this.lchToHpluv();
		this.lchToHsluv();
	}
	rgbToHpluv() {
		this.rgbToXyz();
		this.xyzToLuv();
		this.luvToLch();
		this.lchToHpluv();
		this.lchToHpluv();
	}
	hexToHsluv() {
		this.hexToRgb();
		this.rgbToHsluv();
	}
	hexToHpluv() {
		this.hexToRgb();
		this.rgbToHpluv();
	}
	static fromLinear(c) {
		if(c <= 0.0031308) {
			return 12.92 * c;
		} else {
			return 1.055 * Math.pow(c,0.416666666666666685) - 0.055;
		}
	}
	static toLinear(c) {
		if(c > 0.04045) {
			return Math.pow((c + 0.055) / 1.055,2.4);
		} else {
			return c / 12.92;
		}
	}
	static yToL(Y) {
		if(Y <= hsluv_Hsluv.epsilon) {
			return Y / hsluv_Hsluv.refY * hsluv_Hsluv.kappa;
		} else {
			return 116 * Math.pow(Y / hsluv_Hsluv.refY,0.333333333333333315) - 16;
		}
	}
	static lToY(L) {
		if(L <= 8) {
			return hsluv_Hsluv.refY * L / hsluv_Hsluv.kappa;
		} else {
			return hsluv_Hsluv.refY * Math.pow((L + 16) / 116,3);
		}
	}
	static rgbChannelToHex(chan) {
		let c = Math.round(chan * 255);
		let digit2 = c % 16;
		let digit1 = (c - digit2) / 16 | 0;
		return hsluv_Hsluv.hexChars.charAt(digit1) + hsluv_Hsluv.hexChars.charAt(digit2);
	}
	static hexToRgbChannel(hex,offset) {
		let digit1 = hsluv_Hsluv.hexChars.indexOf(hex.charAt(offset));
		let digit2 = hsluv_Hsluv.hexChars.indexOf(hex.charAt(offset + 1));
		let n = digit1 * 16 + digit2;
		return n / 255.0;
	}
	static distanceFromOriginAngle(slope,intercept,angle) {
		let d = intercept / (Math.sin(angle) - slope * Math.cos(angle));
		if(d < 0) {
			return Infinity;
		} else {
			return d;
		}
	}
	static distanceFromOrigin(slope,intercept) {
		return Math.abs(intercept) / Math.sqrt(Math.pow(slope,2) + 1);
	}
	static min6(f1,f2,f3,f4,f5,f6) {
		return Math.min(f1,Math.min(f2,Math.min(f3,Math.min(f4,Math.min(f5,f6)))));
	}
}
hsluv_Hsluv.__name__ = "hsluv.Hsluv";
Object.assign(hsluv_Hsluv.prototype, {
	__class__: hsluv_Hsluv
});
class htmlparser_CssSelector {
	constructor(type) {
		this.classes = [];
		this.type = type;
	}
	static parse(selector) {
		let r = [];
		let selectors = new EReg("\\s*,\\s*","g").split(selector);
		let _g = 0;
		while(_g < selectors.length) {
			let s = selectors[_g];
			++_g;
			if(s != "") {
				r.push(htmlparser_CssSelector.parseInner(s));
			}
		}
		return r;
	}
	static parseInner(selector) {
		let rr = [];
		selector = " " + selector;
		let r = null;
		let re = new EReg(htmlparser_CssSelector.reSelector,"gi");
		let pos = 0;
		while(re.matchSub(selector,pos)) {
			let type1;
			try {
				type1 = re.matched(1);
			} catch( _g ) {
				type1 = null;
			}
			if(type1 == null) {
				type1 = "";
			}
			let type2;
			try {
				type2 = re.matched(2);
			} catch( _g ) {
				type2 = null;
			}
			if(type2 == null) {
				type2 = "";
			}
			if(type1.length > 0 || type2.length > 0) {
				if(r != null) {
					rr.push(r);
				}
				r = new htmlparser_CssSelector(type2.length > 0 ? ">" : " ");
			}
			let name = re.matched(4);
			if(name != "*") {
				let s = re.matched(3);
				if(s == "#") {
					r.id = name;
				} else if(s == ".") {
					r.classes.push(name);
				} else {
					r.tagNameLC = name.toLowerCase();
				}
				let sIndex;
				try {
					sIndex = re.matched(5);
				} catch( _g ) {
					sIndex = null;
				}
				if(sIndex != null && sIndex != "") {
					r.index = Std.parseInt(sIndex.substring(1,sIndex.length - 1));
					let f = r.index;
					if(isNaN(f)) {
						r.index = null;
					}
				}
			}
			let p = re.matchedPos();
			pos = p.pos + p.len;
		}
		if(r != null) {
			rr.push(r);
		}
		return rr;
	}
	static getMatched(re,n) {
		try {
			return re.matched(n);
		} catch( _g ) {
			return null;
		}
	}
}
htmlparser_CssSelector.__name__ = "htmlparser.CssSelector";
Object.assign(htmlparser_CssSelector.prototype, {
	__class__: htmlparser_CssSelector
});
class htmlparser_HtmlAttribute {
	constructor(name,value,quote) {
		this.name = name;
		this.value = value;
		this.quote = quote;
	}
	toString() {
		if(this.value != null && this.quote != null) {
			return this.name + "=" + this.quote + htmlparser_HtmlTools.escape(this.value,"\r\n" + (this.quote == "'" ? "\"" : "'")) + this.quote;
		} else {
			return this.name;
		}
	}
}
htmlparser_HtmlAttribute.__name__ = "htmlparser.HtmlAttribute";
Object.assign(htmlparser_HtmlAttribute.prototype, {
	__class__: htmlparser_HtmlAttribute
});
class htmlparser_HtmlNode {
	remove() {
		if(this.parent != null) {
			this.parent.removeChild(this);
		}
	}
	getPrevSiblingNode() {
		if(this.parent == null) {
			return null;
		}
		let siblings = this.parent.nodes;
		let n = Lambda.indexOf(siblings,this);
		if(n <= 0) {
			return null;
		}
		if(n > 0) {
			return siblings[n - 1];
		}
		return null;
	}
	getNextSiblingNode() {
		if(this.parent == null) {
			return null;
		}
		let siblings = this.parent.nodes;
		let n = Lambda.indexOf(siblings,this);
		if(n < 0) {
			return null;
		}
		if(n + 1 < siblings.length) {
			return siblings[n + 1];
		}
		return null;
	}
	toString() {
		return "";
	}
	toText() {
		return "";
	}
	hxSerialize(s) {
	}
	hxUnserialize(s) {
	}
}
htmlparser_HtmlNode.__name__ = "htmlparser.HtmlNode";
Object.assign(htmlparser_HtmlNode.prototype, {
	__class__: htmlparser_HtmlNode
});
class htmlparser_HtmlNodeElement extends htmlparser_HtmlNode {
	constructor(name,attributes) {
		super();
		this.name = name;
		this.attributes = attributes;
		this.nodes = [];
		this.children = [];
	}
	getPrevSiblingElement() {
		if(this.parent == null) {
			return null;
		}
		let n = this.parent.children.indexOf(this);
		if(n < 0) {
			return null;
		}
		if(n > 0) {
			return this.parent.children[n - 1];
		}
		return null;
	}
	getNextSiblingElement() {
		if(this.parent == null) {
			return null;
		}
		let n = this.parent.children.indexOf(this);
		if(n < 0) {
			return null;
		}
		if(n + 1 < this.parent.children.length) {
			return this.parent.children[n + 1];
		}
		return null;
	}
	addChild(node,beforeNode) {
		if(beforeNode == null) {
			this.nodes.push(node);
			node.parent = this;
			if(((node) instanceof htmlparser_HtmlNodeElement)) {
				this.children.push(node);
			}
		} else {
			let n = this.nodes.indexOf(beforeNode);
			if(n < 0) {
				throw new haxe_Exception("`beforeNode` is not found.");
			}
			this.nodes.splice(n,0,node);
			node.parent = this;
			let _g = [];
			let _g1 = 0;
			let _g2 = this.nodes;
			while(_g1 < _g2.length) {
				let v = _g2[_g1];
				++_g1;
				if(((v) instanceof htmlparser_HtmlNodeElement)) {
					_g.push(v);
				}
			}
			this.children = _g;
		}
	}
	addChildren(nodesToAdd,beforeNode) {
		let n = beforeNode != null ? this.nodes.indexOf(beforeNode) : 0;
		if(n < 0) {
			throw new haxe_Exception("`beforeNode` is not found.");
		}
		this.nodes = (n > 0 ? this.nodes.slice(0,n) : []).concat(nodesToAdd).concat(this.nodes.slice(n));
		let _g = 0;
		while(_g < nodesToAdd.length) {
			let node = nodesToAdd[_g];
			++_g;
			node.parent = this;
		}
		let _g1 = [];
		let _g2 = 0;
		let _g3 = this.nodes;
		while(_g2 < _g3.length) {
			let v = _g3[_g2];
			++_g2;
			if(((v) instanceof htmlparser_HtmlNodeElement)) {
				_g1.push(v);
			}
		}
		this.children = _g1;
	}
	toString() {
		let sAttrs_b = "";
		let _g = 0;
		let _g1 = this.attributes;
		while(_g < _g1.length) {
			let a = _g1[_g];
			++_g;
			sAttrs_b += " ";
			sAttrs_b += Std.string(a.toString());
		}
		let innerBuf_b = "";
		let _g2 = 0;
		let _g3 = this.nodes;
		while(_g2 < _g3.length) {
			let node = _g3[_g2];
			++_g2;
			innerBuf_b += Std.string(node.toString());
		}
		let inner = innerBuf_b;
		if(inner == "" && this.isSelfClosing()) {
			return "<" + this.name + sAttrs_b + " />";
		}
		if(this.name != null && this.name != "") {
			return "<" + this.name + sAttrs_b + ">" + inner + "</" + this.name + ">";
		} else {
			return inner;
		}
	}
	getAttribute(name) {
		let nameLC = name.toLowerCase();
		let _g = 0;
		let _g1 = this.attributes;
		while(_g < _g1.length) {
			let a = _g1[_g];
			++_g;
			if(a.name.toLowerCase() == nameLC) {
				return a.value;
			}
		}
		return null;
	}
	setAttribute(name,value) {
		let nameLC = name.toLowerCase();
		let _g = 0;
		let _g1 = this.attributes;
		while(_g < _g1.length) {
			let a = _g1[_g];
			++_g;
			if(a.name.toLowerCase() == nameLC) {
				a.value = value;
				return;
			}
		}
		this.attributes.push(new htmlparser_HtmlAttribute(name,value,"\""));
	}
	removeAttribute(name) {
		let nameLC = name.toLowerCase();
		let _g = 0;
		let _g1 = this.attributes.length;
		while(_g < _g1) {
			let i = _g++;
			let a = this.attributes[i];
			if(a.name.toLowerCase() == nameLC) {
				this.attributes.splice(i,1);
				return;
			}
		}
	}
	hasAttribute(name) {
		let nameLC = name.toLowerCase();
		let _g = 0;
		let _g1 = this.attributes;
		while(_g < _g1.length) {
			let a = _g1[_g];
			++_g;
			if(a.name.toLowerCase() == nameLC) {
				return true;
			}
		}
		return false;
	}
	get_innerHTML() {
		let r_b = "";
		let _g = 0;
		let _g1 = this.nodes;
		while(_g < _g1.length) {
			let node = _g1[_g];
			++_g;
			r_b += Std.string(node.toString());
		}
		return r_b;
	}
	set_innerHTML(value) {
		let newNodes = htmlparser_HtmlParser.run(value);
		this.nodes = [];
		this.children = [];
		let _g = 0;
		while(_g < newNodes.length) {
			let node = newNodes[_g];
			++_g;
			this.addChild(node);
		}
		return value;
	}
	get_innerText() {
		return this.toText();
	}
	set_innerText(text) {
		this.fastSetInnerHTML(htmlparser_HtmlTools.escape(text));
		return text;
	}
	fastSetInnerHTML(html) {
		this.nodes = [];
		this.children = [];
		this.addChild(new htmlparser_HtmlNodeText(html));
	}
	toText() {
		let r_b = "";
		let _g = 0;
		let _g1 = this.nodes;
		while(_g < _g1.length) {
			let node = _g1[_g];
			++_g;
			r_b += Std.string(node.toText());
		}
		return r_b;
	}
	find(selector) {
		let parsedSelectors = htmlparser_CssSelector.parse(selector);
		let resNodes = [];
		let _g = 0;
		while(_g < parsedSelectors.length) {
			let s = parsedSelectors[_g];
			++_g;
			let _g1 = 0;
			let _g2 = this.children;
			while(_g1 < _g2.length) {
				let node = _g2[_g1];
				++_g1;
				let nodesToAdd = node.findInner(s);
				let _g = 0;
				while(_g < nodesToAdd.length) {
					let nodeToAdd = nodesToAdd[_g];
					++_g;
					if(resNodes.indexOf(nodeToAdd) < 0) {
						resNodes.push(nodeToAdd);
					}
				}
			}
		}
		return resNodes;
	}
	findInner(selectors) {
		if(selectors.length == 0) {
			return [];
		}
		let nodes = [];
		if(selectors[0].type == " ") {
			let _g = 0;
			let _g1 = this.children;
			while(_g < _g1.length) {
				let child = _g1[_g];
				++_g;
				nodes = nodes.concat(child.findInner(selectors));
			}
		}
		if(this.isSelectorTrue(selectors[0])) {
			if(selectors.length > 1) {
				let subSelectors = selectors.slice(1);
				let _g = 0;
				let _g1 = this.children;
				while(_g < _g1.length) {
					let child = _g1[_g];
					++_g;
					nodes = nodes.concat(child.findInner(subSelectors));
				}
			} else if(selectors.length == 1) {
				if(this.parent != null) {
					nodes.push(this);
				}
			}
		}
		return nodes;
	}
	isSelectorTrue(selector) {
		if(selector.tagNameLC != null && this.name.toLowerCase() != selector.tagNameLC) {
			return false;
		}
		if(selector.id != null && this.getAttribute("id") != selector.id) {
			return false;
		}
		let _g = 0;
		let _g1 = selector.classes;
		while(_g < _g1.length) {
			let clas = _g1[_g];
			++_g;
			let reg = new EReg("(?:^|\\s)" + clas + "(?:$|\\s)","");
			let classAttr = this.getAttribute("class");
			if(classAttr == null || !reg.match(classAttr)) {
				return false;
			}
		}
		if(selector.index != null && (this.parent == null || this.parent.children.indexOf(this) + 1 != selector.index)) {
			return false;
		}
		return true;
	}
	replaceChild(node,newNode) {
		if(((newNode) instanceof Array)) {
			this.replaceChildByMany(node,newNode);
		} else {
			this.replaceChildByOne(node,newNode);
		}
	}
	replaceChildByOne(node,newNode) {
		let n = this.nodes.indexOf(node);
		if(n < 0) {
			throw new haxe_Exception("Node to replace is not found.");
		}
		this.nodes[n].parent = null;
		this.nodes[n] = newNode;
		newNode.parent = this;
		let _g = [];
		let _g1 = 0;
		let _g2 = this.nodes;
		while(_g1 < _g2.length) {
			let v = _g2[_g1];
			++_g1;
			if(((v) instanceof htmlparser_HtmlNodeElement)) {
				_g.push(v);
			}
		}
		this.children = _g;
	}
	replaceChildByMany(node,newNodes) {
		let n = this.nodes.indexOf(node);
		if(n < 0) {
			throw new haxe_Exception("Node to replace is not found.");
		}
		this.nodes[n].parent = null;
		let lastNodes = this.nodes.slice(n + 1,this.nodes.length);
		this.nodes = (n > 0 ? this.nodes.slice(0,n) : []).concat(newNodes).concat(lastNodes);
		let _g = 0;
		while(_g < newNodes.length) {
			let n = newNodes[_g];
			++_g;
			n.parent = this;
		}
		let _g1 = [];
		let _g2 = 0;
		let _g3 = this.nodes;
		while(_g2 < _g3.length) {
			let v = _g3[_g2];
			++_g2;
			if(((v) instanceof htmlparser_HtmlNodeElement)) {
				_g1.push(v);
			}
		}
		this.children = _g1;
	}
	removeChild(node) {
		let n = this.nodes.indexOf(node);
		if(n < 0) {
			throw new haxe_Exception("Node to remove is not found.");
		}
		this.nodes.splice(n,1);
		node.parent = null;
		if(((node) instanceof htmlparser_HtmlNodeElement)) {
			n = this.children.indexOf(node);
			if(n >= 0) {
				this.children.splice(n,1);
			}
		}
	}
	getAttributesAssoc() {
		let attrs = new haxe_ds_StringMap();
		let _g = 0;
		let _g1 = this.attributes;
		while(_g < _g1.length) {
			let attr = _g1[_g];
			++_g;
			attrs.h[attr.name] = attr.value;
		}
		return attrs;
	}
	getAttributesObject() {
		let attrs = { };
		let _g = 0;
		let _g1 = this.attributes;
		while(_g < _g1.length) {
			let attr = _g1[_g];
			++_g;
			attrs[attr.name] = attr.value;
		}
		return attrs;
	}
	isSelfClosing() {
		if(!Object.prototype.hasOwnProperty.call(htmlparser_HtmlParser.SELF_CLOSING_TAGS_HTML,this.name)) {
			return this.name.indexOf(":") >= 0;
		} else {
			return true;
		}
	}
	hxSerialize(s) {
		s.serialize(this.name);
		s.serialize(this.attributes);
		s.serialize(this.nodes);
	}
	hxUnserialize(s) {
		this.name = s.unserialize();
		this.attributes = s.unserialize();
		this.nodes = [];
		this.children = [];
		let ns = s.unserialize();
		let _g = 0;
		while(_g < ns.length) {
			let n = ns[_g];
			++_g;
			this.addChild(n);
		}
	}
}
htmlparser_HtmlNodeElement.__name__ = "htmlparser.HtmlNodeElement";
htmlparser_HtmlNodeElement.__super__ = htmlparser_HtmlNode;
Object.assign(htmlparser_HtmlNodeElement.prototype, {
	__class__: htmlparser_HtmlNodeElement
});
class htmlparser_HtmlNodeText extends htmlparser_HtmlNode {
	constructor(text) {
		super();
		this.text = text;
	}
	toString() {
		return this.text;
	}
	toText() {
		return htmlparser_HtmlTools.unescape(this.text);
	}
	hxSerialize(s) {
		s.serialize(this.text);
	}
	hxUnserialize(s) {
		this.text = s.unserialize();
	}
}
htmlparser_HtmlNodeText.__name__ = "htmlparser.HtmlNodeText";
htmlparser_HtmlNodeText.__super__ = htmlparser_HtmlNode;
Object.assign(htmlparser_HtmlNodeText.prototype, {
	__class__: htmlparser_HtmlNodeText
});
class htmlparser_HtmlParser {
	constructor() {
	}
	parse(str,tolerant) {
		if(tolerant == null) {
			tolerant = false;
		}
		this.tolerant = tolerant;
		this.matches = [];
		let pos = 0;
		while(pos < str.length && htmlparser_HtmlParser.reMain.matchSub(str,pos)) {
			let p = htmlparser_HtmlParser.reMain.matchedPos();
			let re = htmlparser_HtmlParser.reMain;
			let cdata;
			try {
				cdata = re.matched(1);
			} catch( _g ) {
				cdata = null;
			}
			if(cdata == null || cdata == "") {
				let r = htmlparser_HtmlParser.reMain.matched(0);
				let p1 = p.pos;
				let re = htmlparser_HtmlParser.reMain;
				let r1;
				try {
					r1 = re.matched(2);
				} catch( _g ) {
					r1 = null;
				}
				let re1 = htmlparser_HtmlParser.reMain;
				let r2;
				try {
					r2 = re1.matched(3);
				} catch( _g ) {
					r2 = null;
				}
				let re2 = htmlparser_HtmlParser.reMain;
				let r3;
				try {
					r3 = re2.matched(4);
				} catch( _g ) {
					r3 = null;
				}
				let re3 = htmlparser_HtmlParser.reMain;
				let r4;
				try {
					r4 = re3.matched(5);
				} catch( _g ) {
					r4 = null;
				}
				let re4 = htmlparser_HtmlParser.reMain;
				let r5;
				try {
					r5 = re4.matched(6);
				} catch( _g ) {
					r5 = null;
				}
				let re5 = htmlparser_HtmlParser.reMain;
				let r6;
				try {
					r6 = re5.matched(7);
				} catch( _g ) {
					r6 = null;
				}
				let re6 = htmlparser_HtmlParser.reMain;
				let r7;
				try {
					r7 = re6.matched(8);
				} catch( _g ) {
					r7 = null;
				}
				let re7 = htmlparser_HtmlParser.reMain;
				let r8;
				try {
					r8 = re7.matched(9);
				} catch( _g ) {
					r8 = null;
				}
				let re8 = htmlparser_HtmlParser.reMain;
				let r9;
				try {
					r9 = re8.matched(10);
				} catch( _g ) {
					r9 = null;
				}
				let re9 = htmlparser_HtmlParser.reMain;
				let r10;
				try {
					r10 = re9.matched(11);
				} catch( _g ) {
					r10 = null;
				}
				let re10 = htmlparser_HtmlParser.reMain;
				let r11;
				try {
					r11 = re10.matched(12);
				} catch( _g ) {
					r11 = null;
				}
				let re11 = htmlparser_HtmlParser.reMain;
				let r12;
				try {
					r12 = re11.matched(13);
				} catch( _g ) {
					r12 = null;
				}
				let re12 = htmlparser_HtmlParser.reMain;
				let r13;
				try {
					r13 = re12.matched(14);
				} catch( _g ) {
					r13 = null;
				}
				let r14 = { all : r, allPos : p1, script : r1, scriptAttrs : r2, scriptText : r3, style : r4, styleAttrs : r5, styleText : r6, elem : r7, tagOpen : r8, attrs : r9, tagEnd : r10, close : r11, tagClose : r12, comment : r13, tagOpenLC : null, tagCloseLC : null};
				if(r14.tagOpen != null) {
					r14.tagOpenLC = r14.tagOpen.toLowerCase();
				}
				if(r14.tagClose != null) {
					r14.tagCloseLC = r14.tagClose.toLowerCase();
				}
				this.matches.push(r14);
			}
			pos = p.pos + p.len;
		}
		if(this.matches.length > 0) {
			this.str = str;
			this.i = 0;
			let nodes = this.processMatches([]).nodes;
			if(this.i < this.matches.length) {
				throw haxe_Exception.thrown(new htmlparser_HtmlParserException("Not all nodes processed.",this.getPosition(this.i)));
			}
			return nodes;
		}
		if(str.length > 0) {
			return [new htmlparser_HtmlNodeText(str)];
		} else {
			return [];
		}
	}
	processMatches(openedTagsLC) {
		let nodes = [];
		let prevEnd = this.i > 0 ? this.matches[this.i - 1].allPos + this.matches[this.i - 1].all.length : 0;
		let curStart = this.matches[this.i].allPos;
		if(prevEnd < curStart) {
			nodes.push(new htmlparser_HtmlNodeText(HxOverrides.substr(this.str,prevEnd,curStart - prevEnd)));
		}
		while(this.i < this.matches.length) {
			let m = this.matches[this.i];
			if(m.elem != null && m.elem != "") {
				let ee = this.parseElement(openedTagsLC);
				nodes.push(ee.element);
				if(ee.closeTagLC != "") {
					return { nodes : nodes, closeTagLC : ee.closeTagLC};
				}
			} else if(m.script != null && m.script != "") {
				let scriptNode = this.newElement("script",htmlparser_HtmlParser.parseAttrs(m.scriptAttrs));
				scriptNode.addChild(new htmlparser_HtmlNodeText(m.scriptText));
				nodes.push(scriptNode);
			} else if(m.style != null && m.style != "") {
				let styleNode = this.newElement("style",htmlparser_HtmlParser.parseAttrs(m.styleAttrs));
				styleNode.addChild(new htmlparser_HtmlNodeText(m.styleText));
				nodes.push(styleNode);
			} else if(m.close != null && m.close != "") {
				if(m.tagCloseLC == openedTagsLC[openedTagsLC.length - 1]) {
					break;
				}
				if(this.tolerant) {
					if(openedTagsLC.lastIndexOf(m.tagCloseLC) >= 0) {
						break;
					}
				} else {
					throw haxe_Exception.thrown(new htmlparser_HtmlParserException("Closed tag <" + m.tagClose + "> don't match to open tag <" + openedTagsLC[openedTagsLC.length - 1] + ">.",this.getPosition(this.i)));
				}
			} else if(m.comment != null && m.comment != "") {
				nodes.push(new htmlparser_HtmlNodeText(m.comment));
			} else {
				throw haxe_Exception.thrown(new htmlparser_HtmlParserException("Unexpected XML node.",this.getPosition(this.i)));
			}
			if(this.tolerant && this.i >= this.matches.length) {
				break;
			}
			let curEnd = this.matches[this.i].allPos + this.matches[this.i].all.length;
			let nextStart = this.i + 1 < this.matches.length ? this.matches[this.i + 1].allPos : this.str.length;
			if(curEnd < nextStart) {
				nodes.push(new htmlparser_HtmlNodeText(HxOverrides.substr(this.str,curEnd,nextStart - curEnd)));
			}
			this.i++;
		}
		return { nodes : nodes, closeTagLC : ""};
	}
	parseElement(openedTagsLC) {
		let tag = this.matches[this.i].tagOpen;
		let tagLC = this.matches[this.i].tagOpenLC;
		let attrs = this.matches[this.i].attrs;
		let isWithClose = this.matches[this.i].tagEnd != null && this.matches[this.i].tagEnd != "" || this.isSelfClosingTag(tagLC);
		let elem = this.newElement(tag,htmlparser_HtmlParser.parseAttrs(attrs));
		let closeTagLC = "";
		if(!isWithClose) {
			this.i++;
			openedTagsLC.push(tagLC);
			let m = this.processMatches(openedTagsLC);
			let _g = 0;
			let _g1 = m.nodes;
			while(_g < _g1.length) {
				let node = _g1[_g];
				++_g;
				elem.addChild(node);
			}
			openedTagsLC.pop();
			closeTagLC = m.closeTagLC != tagLC ? m.closeTagLC : "";
			if(this.i < this.matches.length || !this.tolerant) {
				if(this.matches[this.i].close == null || this.matches[this.i].close == "" || this.matches[this.i].tagCloseLC != tagLC) {
					if(!this.tolerant) {
						throw haxe_Exception.thrown(new htmlparser_HtmlParserException("Tag <" + tag + "> not closed.",this.getPosition(this.i)));
					} else {
						closeTagLC = this.matches[this.i].tagCloseLC;
					}
				}
			}
		}
		return { element : elem, closeTagLC : closeTagLC};
	}
	isSelfClosingTag(tag) {
		return Object.prototype.hasOwnProperty.call(htmlparser_HtmlParser.SELF_CLOSING_TAGS_HTML,tag);
	}
	newElement(name,attributes) {
		return new htmlparser_HtmlNodeElement(name,attributes);
	}
	getPosition(matchIndex) {
		let m = this.matches[matchIndex];
		let line = 1;
		let lastNewLinePos = -1;
		let i = 0;
		while(i < m.allPos) {
			let chars = i + 1 < this.str.length ? this.str.substring(i,i + 2) : this.str.charAt(i);
			if(chars == "\r\n") {
				i += 2;
				lastNewLinePos = i;
				++line;
			} else if(chars.charAt(0) == "\n" || chars.charAt(0) == "\r") {
				++i;
				lastNewLinePos = i;
				++line;
			} else {
				++i;
			}
		}
		return { line : line, column : m.allPos - lastNewLinePos, length : m.all.length};
	}
	static run(str,tolerant) {
		if(tolerant == null) {
			tolerant = false;
		}
		return new htmlparser_HtmlParser().parse(str,tolerant);
	}
	static parseAttrs(str) {
		let attributes = [];
		let pos = 0;
		while(pos < str.length && htmlparser_HtmlParser.reParseAttrs.matchSub(str,pos)) {
			let name = htmlparser_HtmlParser.reParseAttrs.matched(1);
			let value = htmlparser_HtmlParser.reParseAttrs.matched(2);
			let quote = null;
			let unescaped = null;
			if(value != null) {
				quote = HxOverrides.substr(value,0,1);
				if(quote == "\"" || quote == "'") {
					value = HxOverrides.substr(value,1,value.length - 2);
				} else {
					quote = "";
				}
				unescaped = htmlparser_HtmlTools.unescape(value);
			}
			attributes.push(new htmlparser_HtmlAttribute(name,unescaped,quote));
			let p = htmlparser_HtmlParser.reParseAttrs.matchedPos();
			pos = p.pos + p.len;
		}
		return attributes;
	}
	static getMatched(re,n) {
		try {
			return re.matched(n);
		} catch( _g ) {
			return null;
		}
	}
}
htmlparser_HtmlParser.__name__ = "htmlparser.HtmlParser";
Object.assign(htmlparser_HtmlParser.prototype, {
	__class__: htmlparser_HtmlParser
});
class htmlparser_HtmlParserException {
	constructor(message,pos) {
		this.message = message;
		this.line = pos.line;
		this.column = pos.column;
		this.length = pos.length;
	}
	toString() {
		return "Parse error at " + this.line + ":" + this.column + ". " + this.message;
	}
}
htmlparser_HtmlParserException.__name__ = "htmlparser.HtmlParserException";
Object.assign(htmlparser_HtmlParserException.prototype, {
	__class__: htmlparser_HtmlParserException
});
class htmlparser_HtmlTools {
	static get_htmlUnescapeMap() {
		if(htmlparser_HtmlTools.htmlUnescapeMap == null) {
			let _g = new haxe_ds_StringMap();
			_g.h["nbsp"] = " ";
			_g.h["amp"] = "&";
			_g.h["lt"] = "<";
			_g.h["gt"] = ">";
			_g.h["quot"] = "\"";
			_g.h["apos"] = "'";
			_g.h["euro"] = "€";
			_g.h["iexcl"] = "¡";
			_g.h["cent"] = "¢";
			_g.h["pound"] = "£";
			_g.h["curren"] = "¤";
			_g.h["yen"] = "¥";
			_g.h["brvbar"] = "¦";
			_g.h["sect"] = "§";
			_g.h["uml"] = "¨";
			_g.h["copy"] = "©";
			_g.h["ordf"] = "ª";
			_g.h["not"] = "¬";
			_g.h["shy"] = "­";
			_g.h["reg"] = "®";
			_g.h["macr"] = "¯";
			_g.h["deg"] = "°";
			_g.h["plusmn"] = "±";
			_g.h["sup2"] = "²";
			_g.h["sup3"] = "³";
			_g.h["acute"] = "´";
			_g.h["micro"] = "µ";
			_g.h["para"] = "¶";
			_g.h["middot"] = "·";
			_g.h["cedil"] = "¸";
			_g.h["sup1"] = "¹";
			_g.h["ordm"] = "º";
			_g.h["raquo"] = "»";
			_g.h["frac14"] = "¼";
			_g.h["frac12"] = "½";
			_g.h["frac34"] = "¾";
			_g.h["iquest"] = "¿";
			_g.h["Agrave"] = "À";
			_g.h["Aacute"] = "Á";
			_g.h["Acirc"] = "Â";
			_g.h["Atilde"] = "Ã";
			_g.h["Auml"] = "Ä";
			_g.h["Aring"] = "Å";
			_g.h["AElig"] = "Æ";
			_g.h["Ccedil"] = "Ç";
			_g.h["Egrave"] = "È";
			_g.h["Eacute"] = "É";
			_g.h["Ecirc"] = "Ê";
			_g.h["Euml"] = "Ë";
			_g.h["Igrave"] = "Ì";
			_g.h["Iacute"] = "Í";
			_g.h["Icirc"] = "Î";
			_g.h["Iuml"] = "Ï";
			_g.h["ETH"] = "Ð";
			_g.h["Ntilde"] = "Ñ";
			_g.h["Ograve"] = "Ò";
			_g.h["Oacute"] = "Ó";
			_g.h["Ocirc"] = "Ô";
			_g.h["Otilde"] = "Õ";
			_g.h["Ouml"] = "Ö";
			_g.h["times"] = "×";
			_g.h["Oslash"] = "Ø";
			_g.h["Ugrave"] = "Ù";
			_g.h["Uacute"] = "Ú";
			_g.h["Ucirc"] = "Û";
			_g.h["Uuml"] = "Ü";
			_g.h["Yacute"] = "Ý";
			_g.h["THORN"] = "Þ";
			_g.h["szlig"] = "ß";
			_g.h["agrave"] = "à";
			_g.h["aacute"] = "á";
			_g.h["acirc"] = "â";
			_g.h["atilde"] = "ã";
			_g.h["auml"] = "ä";
			_g.h["aring"] = "å";
			_g.h["aelig"] = "æ";
			_g.h["ccedil"] = "ç";
			_g.h["egrave"] = "è";
			_g.h["eacute"] = "é";
			_g.h["ecirc"] = "ê";
			_g.h["euml"] = "ë";
			_g.h["igrave"] = "ì";
			_g.h["iacute"] = "í";
			_g.h["icirc"] = "î";
			_g.h["iuml"] = "ï";
			_g.h["eth"] = "ð";
			_g.h["ntilde"] = "ñ";
			_g.h["ograve"] = "ò";
			_g.h["oacute"] = "ó";
			_g.h["ocirc"] = "ô";
			_g.h["otilde"] = "õ";
			_g.h["ouml"] = "ö";
			_g.h["divide"] = "÷";
			_g.h["oslash"] = "ø";
			_g.h["ugrave"] = "ù";
			_g.h["uacute"] = "ú";
			_g.h["ucirc"] = "û";
			_g.h["uuml"] = "ü";
			_g.h["yacute"] = "ý";
			_g.h["thorn"] = "þ";
			htmlparser_HtmlTools.htmlUnescapeMap = _g;
		}
		return htmlparser_HtmlTools.htmlUnescapeMap;
	}
	static escape(text,chars) {
		if(chars == null) {
			chars = "";
		}
		let r = text.split("&").join("&amp;");
		r = r.split("<").join("&lt;");
		r = r.split(">").join("&gt;");
		if(chars.indexOf("\"") >= 0) {
			r = r.split("\"").join("&quot;");
		}
		if(chars.indexOf("'") >= 0) {
			r = r.split("'").join("&apos;");
		}
		if(chars.indexOf(" ") >= 0) {
			r = r.split(" ").join("&nbsp;");
		}
		if(chars.indexOf("\n") >= 0) {
			r = r.split("\n").join("&#xA;");
		}
		if(chars.indexOf("\r") >= 0) {
			r = r.split("\r").join("&#xD;");
		}
		return r;
	}
	static unescape(text) {
		return new EReg("[<]!\\[CDATA\\[((?:.|[\r\n])*?)\\]\\][>]|&[^;]+;","g").map(text,function(re) {
			let s = re.matched(0);
			if(s.charAt(0) == "&") {
				if(s.charAt(1) == "#") {
					let numbers = s.substring(2,s.length - 1);
					if(numbers.charAt(0) == "x") {
						numbers = "0" + numbers;
					}
					let code = Std.parseInt(numbers);
					if(code != null && code != 0) {
						return String.fromCodePoint(code);
					} else {
						return s;
					}
				} else {
					let r = htmlparser_HtmlTools.get_htmlUnescapeMap().h[s.substring(1,s.length - 1)];
					if(r != null) {
						return r;
					} else {
						return s;
					}
				}
			}
			return re.matched(1);
		});
	}
}
htmlparser_HtmlTools.__name__ = "htmlparser.HtmlTools";
class httpstatus_HttpStatusCode {
	static toMessage(this1) {
		return httpstatus_HttpStatusMessage.fromCode(this1);
	}
	static toInt(this1) {
		return this1;
	}
	static fromErrorCode(code) {
		return code;
	}
	static toOutgoingResponse(this1) {
		return new tink_http__$Response_OutgoingResponseData(new tink_http_ResponseHeaderBase(this1,httpstatus_HttpStatusMessage.fromCode(this1),[new tink_http_HeaderField("content-length","0")],"HTTP/1.1"),tink_io_Source.EMPTY);
	}
	static fromIncomingResponse(res) {
		return res.header.statusCode;
	}
}
class httpstatus_HttpStatusMessage {
	static _new(statusCode) {
		return httpstatus_HttpStatusMessage.fromCode(statusCode);
	}
	static fromCode(statusCode) {
		switch(statusCode) {
		case 100:
			return "Continue";
		case 101:
			return "Switching Protocols";
		case 102:
			return "Processing";
		case 200:
			return "OK";
		case 201:
			return "Created";
		case 202:
			return "Accepted";
		case 203:
			return "Non-Authoritative Information";
		case 204:
			return "No Content";
		case 205:
			return "Reset Content";
		case 206:
			return "Partial Content";
		case 207:
			return "Multi-Status";
		case 208:
			return "Already Reported";
		case 226:
			return "IM Used";
		case 300:
			return "Multiple Choices";
		case 301:
			return "Moved Permanently";
		case 302:
			return "Found";
		case 303:
			return "See Other";
		case 304:
			return "Not Modified";
		case 305:
			return "Use Proxy";
		case 306:
			return "Switch Proxy";
		case 307:
			return "Temporary Redirect";
		case 308:
			return "Permanent Redirect";
		case 400:
			return "Bad Request";
		case 401:
			return "Unauthorized";
		case 402:
			return "Payment Required";
		case 403:
			return "Forbidden";
		case 404:
			return "Not Found";
		case 405:
			return "Method Not Allowed";
		case 406:
			return "Not Acceptable";
		case 407:
			return "Proxy Authentication Required";
		case 408:
			return "Request Timeout";
		case 409:
			return "Conflict";
		case 410:
			return "Gone";
		case 411:
			return "Length Required";
		case 412:
			return "Precondition Failed";
		case 413:
			return "Payload Too Large";
		case 414:
			return "URI Too Long";
		case 415:
			return "Unsupported Media Type";
		case 416:
			return "Range Not Satisfiable";
		case 417:
			return "Expectation Failed";
		case 418:
			return "I'm a teapot";
		case 421:
			return "Misdirected Request";
		case 422:
			return "Unprocessable Entity";
		case 423:
			return "Locked";
		case 424:
			return "Failed Dependency";
		case 426:
			return "Upgrade Required";
		case 428:
			return "Precondition Required";
		case 429:
			return "Too Many Requests";
		case 431:
			return "Request Header Fields Too Large";
		case 451:
			return "Unavailable For Legal Reasons";
		case 500:
			return "Internal Server Error";
		case 501:
			return "Not Implemented";
		case 502:
			return "Bad Gateway";
		case 503:
			return "Service Unavailable";
		case 504:
			return "Gateway Timeout";
		case 505:
			return "HTTP Version Not Supported";
		case 506:
			return "Variant Also Negotiates";
		case 507:
			return "Insufficient Storage";
		case 508:
			return "Loop Detected";
		case 510:
			return "Not Extended";
		case 511:
			return "Network Authentication Required";
		default:
			return "Unknown Status";
		}
	}
}
class hx_strings_AnyAsString {
	static fromBool(value) {
		if(value) {
			return "true";
		} else {
			return "false";
		}
	}
	static fromAny(value) {
		return Std.string(value);
	}
}
class hx_strings__$Char_CharCaseMapper {
	constructor() {
		this.mapL2U = new haxe_ds_IntMap();
		this.mapU2L = new haxe_ds_IntMap();
		this._addCaseMapping(97,65);
		this._addCaseMapping(98,66);
		this._addCaseMapping(99,67);
		this._addCaseMapping(100,68);
		this._addCaseMapping(101,69);
		this._addCaseMapping(102,70);
		this._addCaseMapping(103,71);
		this._addCaseMapping(104,72);
		this._addCaseMapping(105,73);
		this._addCaseMapping(106,74);
		this._addCaseMapping(107,75);
		this._addCaseMapping(108,76);
		this._addCaseMapping(109,77);
		this._addCaseMapping(110,78);
		this._addCaseMapping(111,79);
		this._addCaseMapping(112,80);
		this._addCaseMapping(113,81);
		this._addCaseMapping(114,82);
		this._addCaseMapping(115,83);
		this._addCaseMapping(116,84);
		this._addCaseMapping(117,85);
		this._addCaseMapping(118,86);
		this._addCaseMapping(119,87);
		this._addCaseMapping(120,88);
		this._addCaseMapping(121,89);
		this._addCaseMapping(122,90);
		this._addCaseMapping(224,192);
		this._addCaseMapping(225,193);
		this._addCaseMapping(226,194);
		this._addCaseMapping(227,195);
		this._addCaseMapping(228,196);
		this._addCaseMapping(229,197);
		this._addCaseMapping(230,198);
		this._addCaseMapping(231,199);
		this._addCaseMapping(232,200);
		this._addCaseMapping(233,201);
		this._addCaseMapping(234,202);
		this._addCaseMapping(235,203);
		this._addCaseMapping(236,204);
		this._addCaseMapping(237,205);
		this._addCaseMapping(238,206);
		this._addCaseMapping(239,207);
		this._addCaseMapping(240,208);
		this._addCaseMapping(241,209);
		this._addCaseMapping(242,210);
		this._addCaseMapping(243,211);
		this._addCaseMapping(244,212);
		this._addCaseMapping(245,213);
		this._addCaseMapping(246,214);
		this._addCaseMapping(248,216);
		this._addCaseMapping(249,217);
		this._addCaseMapping(250,218);
		this._addCaseMapping(251,219);
		this._addCaseMapping(252,220);
		this._addCaseMapping(253,221);
		this._addCaseMapping(254,222);
		this._addCaseMapping(255,376);
		this._addCaseMapping(257,256);
		this._addCaseMapping(259,258);
		this._addCaseMapping(261,260);
		this._addCaseMapping(263,262);
		this._addCaseMapping(265,264);
		this._addCaseMapping(267,266);
		this._addCaseMapping(269,268);
		this._addCaseMapping(271,270);
		this._addCaseMapping(273,272);
		this._addCaseMapping(275,274);
		this._addCaseMapping(277,276);
		this._addCaseMapping(279,278);
		this._addCaseMapping(281,280);
		this._addCaseMapping(283,282);
		this._addCaseMapping(285,284);
		this._addCaseMapping(287,286);
		this._addCaseMapping(289,288);
		this._addCaseMapping(291,290);
		this._addCaseMapping(293,292);
		this._addCaseMapping(295,294);
		this._addCaseMapping(297,296);
		this._addCaseMapping(299,298);
		this._addCaseMapping(301,300);
		this._addCaseMapping(303,302);
		this._addCaseMapping(305,73);
		this._addCaseMapping(307,306);
		this._addCaseMapping(309,308);
		this._addCaseMapping(311,310);
		this._addCaseMapping(314,313);
		this._addCaseMapping(316,315);
		this._addCaseMapping(318,317);
		this._addCaseMapping(320,319);
		this._addCaseMapping(322,321);
		this._addCaseMapping(324,323);
		this._addCaseMapping(326,325);
		this._addCaseMapping(328,327);
		this._addCaseMapping(331,330);
		this._addCaseMapping(333,332);
		this._addCaseMapping(335,334);
		this._addCaseMapping(337,336);
		this._addCaseMapping(339,338);
		this._addCaseMapping(341,340);
		this._addCaseMapping(343,342);
		this._addCaseMapping(345,344);
		this._addCaseMapping(347,346);
		this._addCaseMapping(349,348);
		this._addCaseMapping(351,350);
		this._addCaseMapping(353,352);
		this._addCaseMapping(355,354);
		this._addCaseMapping(357,356);
		this._addCaseMapping(359,358);
		this._addCaseMapping(361,360);
		this._addCaseMapping(363,362);
		this._addCaseMapping(365,364);
		this._addCaseMapping(367,366);
		this._addCaseMapping(369,368);
		this._addCaseMapping(371,370);
		this._addCaseMapping(373,372);
		this._addCaseMapping(375,374);
		this._addCaseMapping(378,377);
		this._addCaseMapping(380,379);
		this._addCaseMapping(382,381);
		this._addCaseMapping(387,386);
		this._addCaseMapping(389,388);
		this._addCaseMapping(392,391);
		this._addCaseMapping(396,395);
		this._addCaseMapping(402,401);
		this._addCaseMapping(409,408);
		this._addCaseMapping(417,416);
		this._addCaseMapping(419,418);
		this._addCaseMapping(421,420);
		this._addCaseMapping(424,423);
		this._addCaseMapping(429,428);
		this._addCaseMapping(432,431);
		this._addCaseMapping(436,435);
		this._addCaseMapping(438,437);
		this._addCaseMapping(441,440);
		this._addCaseMapping(445,444);
		this._addCaseMapping(454,452);
		this._addCaseMapping(457,455);
		this._addCaseMapping(460,458);
		this._addCaseMapping(462,461);
		this._addCaseMapping(464,463);
		this._addCaseMapping(466,465);
		this._addCaseMapping(468,467);
		this._addCaseMapping(470,469);
		this._addCaseMapping(472,471);
		this._addCaseMapping(474,473);
		this._addCaseMapping(476,475);
		this._addCaseMapping(479,478);
		this._addCaseMapping(481,480);
		this._addCaseMapping(483,482);
		this._addCaseMapping(485,484);
		this._addCaseMapping(487,486);
		this._addCaseMapping(489,488);
		this._addCaseMapping(491,490);
		this._addCaseMapping(493,492);
		this._addCaseMapping(495,494);
		this._addCaseMapping(499,497);
		this._addCaseMapping(501,500);
		this._addCaseMapping(507,506);
		this._addCaseMapping(509,508);
		this._addCaseMapping(511,510);
		this._addCaseMapping(513,512);
		this._addCaseMapping(515,514);
		this._addCaseMapping(517,516);
		this._addCaseMapping(519,518);
		this._addCaseMapping(521,520);
		this._addCaseMapping(523,522);
		this._addCaseMapping(525,524);
		this._addCaseMapping(527,526);
		this._addCaseMapping(529,528);
		this._addCaseMapping(531,530);
		this._addCaseMapping(533,532);
		this._addCaseMapping(535,534);
		this._addCaseMapping(595,385);
		this._addCaseMapping(596,390);
		this._addCaseMapping(599,394);
		this._addCaseMapping(600,398);
		this._addCaseMapping(601,399);
		this._addCaseMapping(603,400);
		this._addCaseMapping(608,403);
		this._addCaseMapping(611,404);
		this._addCaseMapping(616,407);
		this._addCaseMapping(617,406);
		this._addCaseMapping(623,412);
		this._addCaseMapping(626,413);
		this._addCaseMapping(629,415);
		this._addCaseMapping(643,425);
		this._addCaseMapping(648,430);
		this._addCaseMapping(650,433);
		this._addCaseMapping(651,434);
		this._addCaseMapping(658,439);
		this._addCaseMapping(924,181);
		this._addCaseMapping(940,902);
		this._addCaseMapping(941,904);
		this._addCaseMapping(942,905);
		this._addCaseMapping(943,906);
		this._addCaseMapping(945,913);
		this._addCaseMapping(946,914);
		this._addCaseMapping(947,915);
		this._addCaseMapping(948,916);
		this._addCaseMapping(949,917);
		this._addCaseMapping(950,918);
		this._addCaseMapping(951,919);
		this._addCaseMapping(952,920);
		this._addCaseMapping(953,921);
		this._addCaseMapping(954,922);
		this._addCaseMapping(955,923);
		this._addCaseMapping(956,924);
		this._addCaseMapping(957,925);
		this._addCaseMapping(958,926);
		this._addCaseMapping(959,927);
		this._addCaseMapping(960,928);
		this._addCaseMapping(961,929);
		this._addCaseMapping(963,931);
		this._addCaseMapping(964,932);
		this._addCaseMapping(965,933);
		this._addCaseMapping(966,934);
		this._addCaseMapping(967,935);
		this._addCaseMapping(968,936);
		this._addCaseMapping(969,937);
		this._addCaseMapping(970,938);
		this._addCaseMapping(971,939);
		this._addCaseMapping(972,908);
		this._addCaseMapping(973,910);
		this._addCaseMapping(974,911);
		this._addCaseMapping(995,994);
		this._addCaseMapping(997,996);
		this._addCaseMapping(999,998);
		this._addCaseMapping(1001,1000);
		this._addCaseMapping(1003,1002);
		this._addCaseMapping(1005,1004);
		this._addCaseMapping(1007,1006);
		this._addCaseMapping(1072,1040);
		this._addCaseMapping(1073,1041);
		this._addCaseMapping(1074,1042);
		this._addCaseMapping(1075,1043);
		this._addCaseMapping(1076,1044);
		this._addCaseMapping(1077,1045);
		this._addCaseMapping(1078,1046);
		this._addCaseMapping(1079,1047);
		this._addCaseMapping(1080,1048);
		this._addCaseMapping(1081,1049);
		this._addCaseMapping(1082,1050);
		this._addCaseMapping(1083,1051);
		this._addCaseMapping(1084,1052);
		this._addCaseMapping(1085,1053);
		this._addCaseMapping(1086,1054);
		this._addCaseMapping(1087,1055);
		this._addCaseMapping(1088,1056);
		this._addCaseMapping(1089,1057);
		this._addCaseMapping(1090,1058);
		this._addCaseMapping(1091,1059);
		this._addCaseMapping(1092,1060);
		this._addCaseMapping(1093,1061);
		this._addCaseMapping(1094,1062);
		this._addCaseMapping(1095,1063);
		this._addCaseMapping(1096,1064);
		this._addCaseMapping(1097,1065);
		this._addCaseMapping(1098,1066);
		this._addCaseMapping(1099,1067);
		this._addCaseMapping(1100,1068);
		this._addCaseMapping(1101,1069);
		this._addCaseMapping(1102,1070);
		this._addCaseMapping(1103,1071);
		this._addCaseMapping(1105,1025);
		this._addCaseMapping(1106,1026);
		this._addCaseMapping(1107,1027);
		this._addCaseMapping(1108,1028);
		this._addCaseMapping(1109,1029);
		this._addCaseMapping(1110,1030);
		this._addCaseMapping(1111,1031);
		this._addCaseMapping(1112,1032);
		this._addCaseMapping(1113,1033);
		this._addCaseMapping(1114,1034);
		this._addCaseMapping(1115,1035);
		this._addCaseMapping(1116,1036);
		this._addCaseMapping(1118,1038);
		this._addCaseMapping(1119,1039);
		this._addCaseMapping(1121,1120);
		this._addCaseMapping(1123,1122);
		this._addCaseMapping(1125,1124);
		this._addCaseMapping(1127,1126);
		this._addCaseMapping(1129,1128);
		this._addCaseMapping(1131,1130);
		this._addCaseMapping(1133,1132);
		this._addCaseMapping(1135,1134);
		this._addCaseMapping(1137,1136);
		this._addCaseMapping(1139,1138);
		this._addCaseMapping(1141,1140);
		this._addCaseMapping(1143,1142);
		this._addCaseMapping(1145,1144);
		this._addCaseMapping(1147,1146);
		this._addCaseMapping(1149,1148);
		this._addCaseMapping(1151,1150);
		this._addCaseMapping(1153,1152);
		this._addCaseMapping(1169,1168);
		this._addCaseMapping(1171,1170);
		this._addCaseMapping(1173,1172);
		this._addCaseMapping(1175,1174);
		this._addCaseMapping(1177,1176);
		this._addCaseMapping(1179,1178);
		this._addCaseMapping(1181,1180);
		this._addCaseMapping(1183,1182);
		this._addCaseMapping(1185,1184);
		this._addCaseMapping(1187,1186);
		this._addCaseMapping(1189,1188);
		this._addCaseMapping(1191,1190);
		this._addCaseMapping(1193,1192);
		this._addCaseMapping(1195,1194);
		this._addCaseMapping(1197,1196);
		this._addCaseMapping(1199,1198);
		this._addCaseMapping(1201,1200);
		this._addCaseMapping(1203,1202);
		this._addCaseMapping(1205,1204);
		this._addCaseMapping(1207,1206);
		this._addCaseMapping(1209,1208);
		this._addCaseMapping(1211,1210);
		this._addCaseMapping(1213,1212);
		this._addCaseMapping(1215,1214);
		this._addCaseMapping(1218,1217);
		this._addCaseMapping(1220,1219);
		this._addCaseMapping(1224,1223);
		this._addCaseMapping(1228,1227);
		this._addCaseMapping(1233,1232);
		this._addCaseMapping(1235,1234);
		this._addCaseMapping(1237,1236);
		this._addCaseMapping(1239,1238);
		this._addCaseMapping(1241,1240);
		this._addCaseMapping(1243,1242);
		this._addCaseMapping(1245,1244);
		this._addCaseMapping(1247,1246);
		this._addCaseMapping(1249,1248);
		this._addCaseMapping(1251,1250);
		this._addCaseMapping(1253,1252);
		this._addCaseMapping(1255,1254);
		this._addCaseMapping(1257,1256);
		this._addCaseMapping(1259,1258);
		this._addCaseMapping(1263,1262);
		this._addCaseMapping(1265,1264);
		this._addCaseMapping(1267,1266);
		this._addCaseMapping(1269,1268);
		this._addCaseMapping(1273,1272);
		this._addCaseMapping(1377,1329);
		this._addCaseMapping(1378,1330);
		this._addCaseMapping(1379,1331);
		this._addCaseMapping(1380,1332);
		this._addCaseMapping(1381,1333);
		this._addCaseMapping(1382,1334);
		this._addCaseMapping(1383,1335);
		this._addCaseMapping(1384,1336);
		this._addCaseMapping(1385,1337);
		this._addCaseMapping(1386,1338);
		this._addCaseMapping(1387,1339);
		this._addCaseMapping(1388,1340);
		this._addCaseMapping(1389,1341);
		this._addCaseMapping(1390,1342);
		this._addCaseMapping(1391,1343);
		this._addCaseMapping(1392,1344);
		this._addCaseMapping(1393,1345);
		this._addCaseMapping(1394,1346);
		this._addCaseMapping(1395,1347);
		this._addCaseMapping(1396,1348);
		this._addCaseMapping(1397,1349);
		this._addCaseMapping(1398,1350);
		this._addCaseMapping(1399,1351);
		this._addCaseMapping(1400,1352);
		this._addCaseMapping(1401,1353);
		this._addCaseMapping(1402,1354);
		this._addCaseMapping(1403,1355);
		this._addCaseMapping(1404,1356);
		this._addCaseMapping(1405,1357);
		this._addCaseMapping(1406,1358);
		this._addCaseMapping(1407,1359);
		this._addCaseMapping(1408,1360);
		this._addCaseMapping(1409,1361);
		this._addCaseMapping(1410,1362);
		this._addCaseMapping(1411,1363);
		this._addCaseMapping(1412,1364);
		this._addCaseMapping(1413,1365);
		this._addCaseMapping(1414,1366);
		this._addCaseMapping(4304,4256);
		this._addCaseMapping(4305,4257);
		this._addCaseMapping(4306,4258);
		this._addCaseMapping(4307,4259);
		this._addCaseMapping(4308,4260);
		this._addCaseMapping(4309,4261);
		this._addCaseMapping(4310,4262);
		this._addCaseMapping(4311,4263);
		this._addCaseMapping(4312,4264);
		this._addCaseMapping(4313,4265);
		this._addCaseMapping(4314,4266);
		this._addCaseMapping(4315,4267);
		this._addCaseMapping(4316,4268);
		this._addCaseMapping(4317,4269);
		this._addCaseMapping(4318,4270);
		this._addCaseMapping(4319,4271);
		this._addCaseMapping(4320,4272);
		this._addCaseMapping(4321,4273);
		this._addCaseMapping(4322,4274);
		this._addCaseMapping(4323,4275);
		this._addCaseMapping(4324,4276);
		this._addCaseMapping(4325,4277);
		this._addCaseMapping(4326,4278);
		this._addCaseMapping(4327,4279);
		this._addCaseMapping(4328,4280);
		this._addCaseMapping(4329,4281);
		this._addCaseMapping(4330,4282);
		this._addCaseMapping(4331,4283);
		this._addCaseMapping(4332,4284);
		this._addCaseMapping(4333,4285);
		this._addCaseMapping(4334,4286);
		this._addCaseMapping(4335,4287);
		this._addCaseMapping(4336,4288);
		this._addCaseMapping(4337,4289);
		this._addCaseMapping(4338,4290);
		this._addCaseMapping(4339,4291);
		this._addCaseMapping(4340,4292);
		this._addCaseMapping(4341,4293);
		this._addCaseMapping(7681,7680);
		this._addCaseMapping(7683,7682);
		this._addCaseMapping(7685,7684);
		this._addCaseMapping(7687,7686);
		this._addCaseMapping(7689,7688);
		this._addCaseMapping(7691,7690);
		this._addCaseMapping(7693,7692);
		this._addCaseMapping(7695,7694);
		this._addCaseMapping(7697,7696);
		this._addCaseMapping(7699,7698);
		this._addCaseMapping(7701,7700);
		this._addCaseMapping(7703,7702);
		this._addCaseMapping(7705,7704);
		this._addCaseMapping(7707,7706);
		this._addCaseMapping(7709,7708);
		this._addCaseMapping(7711,7710);
		this._addCaseMapping(7713,7712);
		this._addCaseMapping(7715,7714);
		this._addCaseMapping(7717,7716);
		this._addCaseMapping(7719,7718);
		this._addCaseMapping(7721,7720);
		this._addCaseMapping(7723,7722);
		this._addCaseMapping(7725,7724);
		this._addCaseMapping(7727,7726);
		this._addCaseMapping(7729,7728);
		this._addCaseMapping(7731,7730);
		this._addCaseMapping(7733,7732);
		this._addCaseMapping(7735,7734);
		this._addCaseMapping(7737,7736);
		this._addCaseMapping(7739,7738);
		this._addCaseMapping(7741,7740);
		this._addCaseMapping(7743,7742);
		this._addCaseMapping(7745,7744);
		this._addCaseMapping(7747,7746);
		this._addCaseMapping(7749,7748);
		this._addCaseMapping(7751,7750);
		this._addCaseMapping(7753,7752);
		this._addCaseMapping(7755,7754);
		this._addCaseMapping(7757,7756);
		this._addCaseMapping(7759,7758);
		this._addCaseMapping(7761,7760);
		this._addCaseMapping(7763,7762);
		this._addCaseMapping(7765,7764);
		this._addCaseMapping(7767,7766);
		this._addCaseMapping(7769,7768);
		this._addCaseMapping(7771,7770);
		this._addCaseMapping(7773,7772);
		this._addCaseMapping(7775,7774);
		this._addCaseMapping(7777,7776);
		this._addCaseMapping(7779,7778);
		this._addCaseMapping(7781,7780);
		this._addCaseMapping(7783,7782);
		this._addCaseMapping(7785,7784);
		this._addCaseMapping(7787,7786);
		this._addCaseMapping(7789,7788);
		this._addCaseMapping(7791,7790);
		this._addCaseMapping(7793,7792);
		this._addCaseMapping(7795,7794);
		this._addCaseMapping(7797,7796);
		this._addCaseMapping(7799,7798);
		this._addCaseMapping(7801,7800);
		this._addCaseMapping(7803,7802);
		this._addCaseMapping(7805,7804);
		this._addCaseMapping(7807,7806);
		this._addCaseMapping(7809,7808);
		this._addCaseMapping(7811,7810);
		this._addCaseMapping(7813,7812);
		this._addCaseMapping(7815,7814);
		this._addCaseMapping(7817,7816);
		this._addCaseMapping(7819,7818);
		this._addCaseMapping(7821,7820);
		this._addCaseMapping(7823,7822);
		this._addCaseMapping(7825,7824);
		this._addCaseMapping(7827,7826);
		this._addCaseMapping(7829,7828);
		this._addCaseMapping(7841,7840);
		this._addCaseMapping(7843,7842);
		this._addCaseMapping(7845,7844);
		this._addCaseMapping(7847,7846);
		this._addCaseMapping(7849,7848);
		this._addCaseMapping(7851,7850);
		this._addCaseMapping(7853,7852);
		this._addCaseMapping(7855,7854);
		this._addCaseMapping(7857,7856);
		this._addCaseMapping(7859,7858);
		this._addCaseMapping(7861,7860);
		this._addCaseMapping(7863,7862);
		this._addCaseMapping(7865,7864);
		this._addCaseMapping(7867,7866);
		this._addCaseMapping(7869,7868);
		this._addCaseMapping(7871,7870);
		this._addCaseMapping(7873,7872);
		this._addCaseMapping(7875,7874);
		this._addCaseMapping(7877,7876);
		this._addCaseMapping(7879,7878);
		this._addCaseMapping(7881,7880);
		this._addCaseMapping(7883,7882);
		this._addCaseMapping(7885,7884);
		this._addCaseMapping(7887,7886);
		this._addCaseMapping(7889,7888);
		this._addCaseMapping(7891,7890);
		this._addCaseMapping(7893,7892);
		this._addCaseMapping(7895,7894);
		this._addCaseMapping(7897,7896);
		this._addCaseMapping(7899,7898);
		this._addCaseMapping(7901,7900);
		this._addCaseMapping(7903,7902);
		this._addCaseMapping(7905,7904);
		this._addCaseMapping(7907,7906);
		this._addCaseMapping(7909,7908);
		this._addCaseMapping(7911,7910);
		this._addCaseMapping(7913,7912);
		this._addCaseMapping(7915,7914);
		this._addCaseMapping(7917,7916);
		this._addCaseMapping(7919,7918);
		this._addCaseMapping(7921,7920);
		this._addCaseMapping(7923,7922);
		this._addCaseMapping(7925,7924);
		this._addCaseMapping(7927,7926);
		this._addCaseMapping(7929,7928);
		this._addCaseMapping(7936,7944);
		this._addCaseMapping(7937,7945);
		this._addCaseMapping(7938,7946);
		this._addCaseMapping(7939,7947);
		this._addCaseMapping(7940,7948);
		this._addCaseMapping(7941,7949);
		this._addCaseMapping(7942,7950);
		this._addCaseMapping(7943,7951);
		this._addCaseMapping(7952,7960);
		this._addCaseMapping(7953,7961);
		this._addCaseMapping(7954,7962);
		this._addCaseMapping(7955,7963);
		this._addCaseMapping(7956,7964);
		this._addCaseMapping(7957,7965);
		this._addCaseMapping(7968,7976);
		this._addCaseMapping(7969,7977);
		this._addCaseMapping(7970,7978);
		this._addCaseMapping(7971,7979);
		this._addCaseMapping(7972,7980);
		this._addCaseMapping(7973,7981);
		this._addCaseMapping(7974,7982);
		this._addCaseMapping(7975,7983);
		this._addCaseMapping(7984,7992);
		this._addCaseMapping(7985,7993);
		this._addCaseMapping(7986,7994);
		this._addCaseMapping(7987,7995);
		this._addCaseMapping(7988,7996);
		this._addCaseMapping(7989,7997);
		this._addCaseMapping(7990,7998);
		this._addCaseMapping(7991,7999);
		this._addCaseMapping(8000,8008);
		this._addCaseMapping(8001,8009);
		this._addCaseMapping(8002,8010);
		this._addCaseMapping(8003,8011);
		this._addCaseMapping(8004,8012);
		this._addCaseMapping(8005,8013);
		this._addCaseMapping(8017,8025);
		this._addCaseMapping(8019,8027);
		this._addCaseMapping(8021,8029);
		this._addCaseMapping(8023,8031);
		this._addCaseMapping(8032,8040);
		this._addCaseMapping(8033,8041);
		this._addCaseMapping(8034,8042);
		this._addCaseMapping(8035,8043);
		this._addCaseMapping(8036,8044);
		this._addCaseMapping(8037,8045);
		this._addCaseMapping(8038,8046);
		this._addCaseMapping(8039,8047);
		this._addCaseMapping(8064,8072);
		this._addCaseMapping(8065,8073);
		this._addCaseMapping(8066,8074);
		this._addCaseMapping(8067,8075);
		this._addCaseMapping(8068,8076);
		this._addCaseMapping(8069,8077);
		this._addCaseMapping(8070,8078);
		this._addCaseMapping(8071,8079);
		this._addCaseMapping(8080,8088);
		this._addCaseMapping(8081,8089);
		this._addCaseMapping(8082,8090);
		this._addCaseMapping(8083,8091);
		this._addCaseMapping(8084,8092);
		this._addCaseMapping(8085,8093);
		this._addCaseMapping(8086,8094);
		this._addCaseMapping(8087,8095);
		this._addCaseMapping(8096,8104);
		this._addCaseMapping(8097,8105);
		this._addCaseMapping(8098,8106);
		this._addCaseMapping(8099,8107);
		this._addCaseMapping(8100,8108);
		this._addCaseMapping(8101,8109);
		this._addCaseMapping(8102,8110);
		this._addCaseMapping(8103,8111);
		this._addCaseMapping(8112,8120);
		this._addCaseMapping(8113,8121);
		this._addCaseMapping(8144,8152);
		this._addCaseMapping(8145,8153);
		this._addCaseMapping(8160,8168);
		this._addCaseMapping(8161,8169);
		this._addCaseMapping(9424,9398);
		this._addCaseMapping(9425,9399);
		this._addCaseMapping(9426,9400);
		this._addCaseMapping(9427,9401);
		this._addCaseMapping(9428,9402);
		this._addCaseMapping(9429,9403);
		this._addCaseMapping(9430,9404);
		this._addCaseMapping(9431,9405);
		this._addCaseMapping(9432,9406);
		this._addCaseMapping(9433,9407);
		this._addCaseMapping(9434,9408);
		this._addCaseMapping(9435,9409);
		this._addCaseMapping(9436,9410);
		this._addCaseMapping(9437,9411);
		this._addCaseMapping(9438,9412);
		this._addCaseMapping(9439,9413);
		this._addCaseMapping(9440,9414);
		this._addCaseMapping(9441,9415);
		this._addCaseMapping(9442,9416);
		this._addCaseMapping(9443,9417);
		this._addCaseMapping(9444,9418);
		this._addCaseMapping(9445,9419);
		this._addCaseMapping(9446,9420);
		this._addCaseMapping(9447,9421);
		this._addCaseMapping(9448,9422);
		this._addCaseMapping(9449,9423);
		this._addCaseMapping(65345,65313);
		this._addCaseMapping(65346,65314);
		this._addCaseMapping(65347,65315);
		this._addCaseMapping(65348,65316);
		this._addCaseMapping(65349,65317);
		this._addCaseMapping(65350,65318);
		this._addCaseMapping(65351,65319);
		this._addCaseMapping(65352,65320);
		this._addCaseMapping(65353,65321);
		this._addCaseMapping(65354,65322);
		this._addCaseMapping(65355,65323);
		this._addCaseMapping(65356,65324);
		this._addCaseMapping(65357,65325);
		this._addCaseMapping(65358,65326);
		this._addCaseMapping(65359,65327);
		this._addCaseMapping(65360,65328);
		this._addCaseMapping(65361,65329);
		this._addCaseMapping(65362,65330);
		this._addCaseMapping(65363,65331);
		this._addCaseMapping(65364,65332);
		this._addCaseMapping(65365,65333);
		this._addCaseMapping(65366,65334);
		this._addCaseMapping(65367,65335);
		this._addCaseMapping(65368,65336);
		this._addCaseMapping(65369,65337);
		this._addCaseMapping(65370,65338);
	}
	_addCaseMapping(lowerChar,upperChar) {
		if(!this.mapU2L.h.hasOwnProperty(upperChar)) {
			this.mapU2L.h[upperChar] = lowerChar;
		}
		if(!this.mapL2U.h.hasOwnProperty(lowerChar)) {
			this.mapL2U.h[lowerChar] = upperChar;
		}
	}
	isLowerCase(ch) {
		return this.mapL2U.h.hasOwnProperty(ch);
	}
	isUpperCase(ch) {
		return this.mapU2L.h.hasOwnProperty(ch);
	}
	toLowerCase(ch) {
		let lowerChar = this.mapU2L.h[ch];
		if(lowerChar == null) {
			return ch;
		} else {
			return lowerChar;
		}
	}
	toUpperCase(ch) {
		let upperChar = this.mapL2U.h[ch];
		if(upperChar == null) {
			return ch;
		} else {
			return upperChar;
		}
	}
}
hx_strings__$Char_CharCaseMapper.__name__ = "hx.strings._Char.CharCaseMapper";
Object.assign(hx_strings__$Char_CharCaseMapper.prototype, {
	__class__: hx_strings__$Char_CharCaseMapper
});
class hx_strings_Char {
	static fromString(str) {
		return hx_strings_Strings.charCodeAt8(str,0);
	}
	static of(ch) {
		return ch;
	}
	static op_plus_string(ch,other) {
		return String.fromCodePoint(ch) + other;
	}
	static op_plus_string2(str,ch) {
		return str + String.fromCodePoint(ch);
	}
	static op_plus(ch,other) {
		return ch + other;
	}
	static isAscii(this1) {
		if(this1 > -1) {
			return this1 < 128;
		} else {
			return false;
		}
	}
	static isAsciiAlpha(this1) {
		if(!(this1 > 64 && this1 < 91)) {
			if(this1 > 96) {
				return this1 < 123;
			} else {
				return false;
			}
		} else {
			return true;
		}
	}
	static isAsciiAlphanumeric(this1) {
		if(!(this1 > 64 && this1 < 91 || this1 > 96 && this1 < 123)) {
			if(this1 > 47) {
				return this1 < 58;
			} else {
				return false;
			}
		} else {
			return true;
		}
	}
	static isAsciiControl(this1) {
		if(!(this1 > -1 && this1 < 32)) {
			return this1 == 127;
		} else {
			return true;
		}
	}
	static isAsciiPrintable(this1) {
		if(this1 > 31) {
			return this1 < 127;
		} else {
			return false;
		}
	}
	static isDigit(this1) {
		if(this1 > 47) {
			return this1 < 58;
		} else {
			return false;
		}
	}
	static isEOF(this1) {
		return this1 != this1;
	}
	static isSpace(this1) {
		return this1 == 32;
	}
	static isUTF8(this1) {
		if(this1 > -1) {
			return this1 < 1114112;
		} else {
			return false;
		}
	}
	static isWhitespace(this1) {
		if(!(this1 > 8 && this1 < 14)) {
			return this1 == 32;
		} else {
			return true;
		}
	}
	static isLowerCase(this1) {
		return hx_strings_Char.CHAR_CASE_MAPPER.mapL2U.h.hasOwnProperty(this1);
	}
	static isUpperCase(this1) {
		return hx_strings_Char.CHAR_CASE_MAPPER.mapU2L.h.hasOwnProperty(this1);
	}
	static toLowerCase(this1) {
		let lowerChar = hx_strings_Char.CHAR_CASE_MAPPER.mapU2L.h[this1];
		if(lowerChar == null) {
			return this1;
		} else {
			return lowerChar;
		}
	}
	static toUpperCase(this1) {
		let upperChar = hx_strings_Char.CHAR_CASE_MAPPER.mapL2U.h[this1];
		if(upperChar == null) {
			return this1;
		} else {
			return upperChar;
		}
	}
	static toInt(this1) {
		return this1;
	}
	static toString(this1) {
		return String.fromCodePoint(this1);
	}
}
class hx_strings_CharIterator {
	constructor(prevBufferSize) {
		if(hx_strings_CharIterator._hx_skip_constructor) {
			return;
		}
		this._hx_constructor(prevBufferSize);
	}
	_hx_constructor(prevBufferSize) {
		this.prevBufferNextIdx = -1;
		this.prevBufferPrevIdx = -1;
		this.currChar = -1;
		this.col = 0;
		this.line = 0;
		this.index = -1;
		this.prevBuffer = prevBufferSize > 0 ? new hx_strings_internal__$RingBuffer_RingBufferImpl(prevBufferSize + 1) : null;
	}
	get_prevBufferLength() {
		return this.prevBuffer.length;
	}
	get_current() {
		if(this.index > -1) {
			return this.currChar;
		} else {
			return null;
		}
	}
	get_pos() {
		return new hx_strings_CharPos(this.index,this.line,this.col);
	}
	hasPrev() {
		return this.prevBufferPrevIdx > -1;
	}
	prev() {
		if(this.prevBufferPrevIdx <= -1) {
			throw haxe_Exception.thrown(new haxe_io_Eof());
		}
		let prevChar = this.prevBuffer.get(this.prevBufferPrevIdx);
		this.currChar = prevChar.char;
		this.index = prevChar.index;
		this.line = prevChar.line;
		this.col = prevChar.col;
		this.prevBufferNextIdx = this.prevBufferPrevIdx + 1 < this.prevBuffer.length ? this.prevBufferPrevIdx + 1 : -1;
		this.prevBufferPrevIdx--;
		return this.currChar;
	}
	hasNext() {
		if(this.prevBufferNextIdx > -1) {
			return true;
		} else {
			return !this.isEOF();
		}
	}
	next() {
		if(this.prevBufferNextIdx > -1) {
			let prevChar = this.prevBuffer.get(this.prevBufferNextIdx);
			this.currChar = prevChar.char;
			this.index = prevChar.index;
			this.line = prevChar.line;
			this.col = prevChar.col;
			this.prevBufferPrevIdx = this.prevBufferNextIdx - 1;
			this.prevBufferNextIdx = this.prevBufferNextIdx + 1 < this.prevBuffer.length ? this.prevBufferNextIdx + 1 : -1;
			return this.currChar;
		}
		if(this.isEOF()) {
			throw haxe_Exception.thrown(new haxe_io_Eof());
		}
		if(this.currChar == 10 || this.currChar < 0) {
			this.line++;
			this.col = 0;
		}
		this.index++;
		this.col++;
		this.currChar = this.getChar();
		if(this.prevBuffer != null) {
			this.prevBuffer.add(new hx_strings__$CharIterator_CharWithPos(this.currChar,this.index,this.col,this.line));
			this.prevBufferPrevIdx = this.prevBuffer.length - 2;
			this.prevBufferNextIdx = -1;
		}
		return this.currChar;
	}
	getChar() {
		throw haxe_Exception.thrown("Not implemented");
	}
	isEOF() {
		throw haxe_Exception.thrown("Not implemented");
	}
	static fromString(chars,prevBufferSize) {
		if(prevBufferSize == null) {
			prevBufferSize = 0;
		}
		if(chars == null) {
			return hx_strings__$CharIterator_NullCharIterator.INSTANCE;
		}
		return new hx_strings__$CharIterator_StringCharIterator(chars,prevBufferSize);
	}
	static fromArray(chars,prevBufferSize) {
		if(prevBufferSize == null) {
			prevBufferSize = 0;
		}
		if(chars == null) {
			return hx_strings__$CharIterator_NullCharIterator.INSTANCE;
		}
		return new hx_strings__$CharIterator_ArrayCharIterator(chars,prevBufferSize);
	}
	static fromInput(chars,prevBufferSize) {
		if(prevBufferSize == null) {
			prevBufferSize = 0;
		}
		if(chars == null) {
			return hx_strings__$CharIterator_NullCharIterator.INSTANCE;
		}
		return new hx_strings__$CharIterator_InputCharIterator(chars,prevBufferSize);
	}
	static fromIterator(chars,prevBufferSize) {
		if(prevBufferSize == null) {
			prevBufferSize = 0;
		}
		if(chars == null) {
			return hx_strings__$CharIterator_NullCharIterator.INSTANCE;
		}
		return new hx_strings__$CharIterator_IteratorCharIterator(chars,prevBufferSize);
	}
}
hx_strings_CharIterator.__name__ = "hx.strings.CharIterator";
Object.assign(hx_strings_CharIterator.prototype, {
	__class__: hx_strings_CharIterator
});
class hx_strings_CharPos {
	constructor(index,line,col) {
		this.index = index;
		this.line = line;
		this.col = col;
	}
	toString() {
		return "CharPos[index=" + this.index + ", line=" + this.line + ", col=" + this.col + "]";
	}
}
hx_strings_CharPos.__name__ = "hx.strings.CharPos";
Object.assign(hx_strings_CharPos.prototype, {
	__class__: hx_strings_CharPos
});
class hx_strings__$CharIterator_CharWithPos extends hx_strings_CharPos {
	constructor(char,index,line,col) {
		super(index,line,col);
		this.char = char;
	}
}
hx_strings__$CharIterator_CharWithPos.__name__ = "hx.strings._CharIterator.CharWithPos";
hx_strings__$CharIterator_CharWithPos.__super__ = hx_strings_CharPos;
Object.assign(hx_strings__$CharIterator_CharWithPos.prototype, {
	__class__: hx_strings__$CharIterator_CharWithPos
});
class hx_strings_internal__$RingBuffer_RingBufferImpl {
	constructor(size) {
		this.length = 0;
		this.bufferEndIdx = -1;
		this.bufferStartIdx = 0;
		if(size < 1) {
			throw haxe_Exception.thrown("[size] must be > 0");
		}
		this.buffer = new Array(size);
		this.size = size;
		this.bufferMaxIdx = size - 1;
	}
	add(item) {
		if(this.length == this.size) {
			this.bufferEndIdx = this.bufferStartIdx;
			this.bufferStartIdx++;
			if(this.bufferStartIdx > this.bufferMaxIdx) {
				this.bufferStartIdx = 0;
			}
		} else {
			this.bufferEndIdx++;
			this.length++;
		}
		this.buffer[this.bufferEndIdx] = item;
	}
	get(index) {
		if(index < 0 || index > this.bufferMaxIdx) {
			throw haxe_Exception.thrown("[index] " + index + " is out of bound");
		}
		let realIdx = this.bufferStartIdx + index;
		if(realIdx > this.bufferMaxIdx) {
			realIdx -= this.length;
		}
		return this.buffer[realIdx];
	}
	iterator() {
		return new hx_strings_internal__$RingBuffer_RingBufferIterator(this);
	}
	toArray() {
		let arr = [];
		let i = this.iterator();
		while(i.hasNext()) {
			let i1 = i.next();
			arr.push(i1);
		}
		return arr;
	}
}
hx_strings_internal__$RingBuffer_RingBufferImpl.__name__ = "hx.strings.internal._RingBuffer.RingBufferImpl";
Object.assign(hx_strings_internal__$RingBuffer_RingBufferImpl.prototype, {
	__class__: hx_strings_internal__$RingBuffer_RingBufferImpl
});
class hx_strings__$CharIterator_NullCharIterator extends hx_strings_CharIterator {
	constructor() {
		super(0);
	}
	isEOF() {
		return true;
	}
}
hx_strings__$CharIterator_NullCharIterator.__name__ = "hx.strings._CharIterator.NullCharIterator";
hx_strings__$CharIterator_NullCharIterator.__super__ = hx_strings_CharIterator;
Object.assign(hx_strings__$CharIterator_NullCharIterator.prototype, {
	__class__: hx_strings__$CharIterator_NullCharIterator
});
class hx_strings__$CharIterator_ArrayCharIterator extends hx_strings_CharIterator {
	constructor(chars,prevBufferSize) {
		super(prevBufferSize);
		this.chars = chars;
		this.charsMaxIndex = chars.length - 1;
	}
	isEOF() {
		return this.index >= this.charsMaxIndex;
	}
	getChar() {
		return this.chars[this.index];
	}
}
hx_strings__$CharIterator_ArrayCharIterator.__name__ = "hx.strings._CharIterator.ArrayCharIterator";
hx_strings__$CharIterator_ArrayCharIterator.__super__ = hx_strings_CharIterator;
Object.assign(hx_strings__$CharIterator_ArrayCharIterator.prototype, {
	__class__: hx_strings__$CharIterator_ArrayCharIterator
});
class hx_strings__$CharIterator_IteratorCharIterator extends hx_strings_CharIterator {
	constructor(chars,prevBufferSize) {
		super(prevBufferSize);
		this.chars = chars;
	}
	isEOF() {
		return !this.chars.hasNext();
	}
	getChar() {
		return this.chars.next();
	}
}
hx_strings__$CharIterator_IteratorCharIterator.__name__ = "hx.strings._CharIterator.IteratorCharIterator";
hx_strings__$CharIterator_IteratorCharIterator.__super__ = hx_strings_CharIterator;
Object.assign(hx_strings__$CharIterator_IteratorCharIterator.prototype, {
	__class__: hx_strings__$CharIterator_IteratorCharIterator
});
class hx_strings__$CharIterator_InputCharIterator extends hx_strings_CharIterator {
	constructor(chars,prevBufferSize) {
		hx_strings_CharIterator._hx_skip_constructor = true;
		super();
		hx_strings_CharIterator._hx_skip_constructor = false;
		this._hx_constructor(chars,prevBufferSize);
	}
	_hx_constructor(chars,prevBufferSize) {
		this.nextCharAvailable = null;
		this.nextChar = -1;
		this.currCharIndex = -1;
		this.byteIndex = 0;
		super._hx_constructor(prevBufferSize);
		this.input = chars;
	}
	isEOF() {
		if(this.nextCharAvailable == null) {
			try {
				let byte1 = this.input.readByte();
				this.byteIndex++;
				let tmp;
				if(byte1 <= 127) {
					tmp = byte1;
				} else {
					byte1 &= -129;
					byte1 &= -65;
					let totalBytes = 2;
					let isBit6Set = 1 == (byte1 >> 5 & 1);
					let isBit5Set = false;
					if(isBit6Set) {
						byte1 &= -33;
						++totalBytes;
						isBit5Set = 1 == (byte1 >> 4 & 1);
						if(isBit5Set) {
							byte1 &= -17;
							++totalBytes;
							if(1 == (byte1 >> 3 & 1)) {
								throw haxe_Exception.thrown("Valid UTF-8 byte expected at position [" + this.byteIndex + "] but found byte with value [" + byte1 + "]!");
							}
						}
					}
					let result = byte1 << 6 * (totalBytes - 1);
					let byte = this.input.readByte();
					this.byteIndex++;
					if(1 != (byte >> 7 & 1)) {
						throw haxe_Exception.thrown("Valid UTF-8 multi-sequence byte expected at position [" + this.byteIndex + "] but found byte with value [" + byte + "]!");
					}
					if(1 == (byte >> 6 & 1)) {
						throw haxe_Exception.thrown("Valid UTF-8 multi-sequence byte expected at position [" + this.byteIndex + "] but found byte with value [" + byte + "]!");
					}
					let byte2 = byte & -129;
					result += byte2 << 6 * (totalBytes - 2);
					if(isBit6Set) {
						let byte = this.input.readByte();
						this.byteIndex++;
						if(1 != (byte >> 7 & 1)) {
							throw haxe_Exception.thrown("Valid UTF-8 multi-sequence byte expected at position [" + this.byteIndex + "] but found byte with value [" + byte + "]!");
						}
						if(1 == (byte >> 6 & 1)) {
							throw haxe_Exception.thrown("Valid UTF-8 multi-sequence byte expected at position [" + this.byteIndex + "] but found byte with value [" + byte + "]!");
						}
						let byte3 = byte & -129;
						result += byte3 << 6 * (totalBytes - 3);
						if(isBit5Set) {
							let byte = this.input.readByte();
							this.byteIndex++;
							if(1 != (byte >> 7 & 1)) {
								throw haxe_Exception.thrown("Valid UTF-8 multi-sequence byte expected at position [" + this.byteIndex + "] but found byte with value [" + byte + "]!");
							}
							if(1 == (byte >> 6 & 1)) {
								throw haxe_Exception.thrown("Valid UTF-8 multi-sequence byte expected at position [" + this.byteIndex + "] but found byte with value [" + byte + "]!");
							}
							let byte4 = byte & -129;
							result += byte4 << 6 * (totalBytes - 4);
						}
					}
					if(this.index == 0 && result == 65279) {
						let byte1 = this.input.readByte();
						this.byteIndex++;
						if(byte1 <= 127) {
							tmp = byte1;
						} else {
							byte1 &= -129;
							byte1 &= -65;
							let totalBytes = 2;
							let isBit6Set = 1 == (byte1 >> 5 & 1);
							let isBit5Set = false;
							if(isBit6Set) {
								byte1 &= -33;
								++totalBytes;
								isBit5Set = 1 == (byte1 >> 4 & 1);
								if(isBit5Set) {
									byte1 &= -17;
									++totalBytes;
									if(1 == (byte1 >> 3 & 1)) {
										throw haxe_Exception.thrown("Valid UTF-8 byte expected at position [" + this.byteIndex + "] but found byte with value [" + byte1 + "]!");
									}
								}
							}
							let result = byte1 << 6 * (totalBytes - 1);
							let byte = this.input.readByte();
							this.byteIndex++;
							if(1 != (byte >> 7 & 1)) {
								throw haxe_Exception.thrown("Valid UTF-8 multi-sequence byte expected at position [" + this.byteIndex + "] but found byte with value [" + byte + "]!");
							}
							if(1 == (byte >> 6 & 1)) {
								throw haxe_Exception.thrown("Valid UTF-8 multi-sequence byte expected at position [" + this.byteIndex + "] but found byte with value [" + byte + "]!");
							}
							let byte2 = byte & -129;
							result += byte2 << 6 * (totalBytes - 2);
							if(isBit6Set) {
								let byte = this.input.readByte();
								this.byteIndex++;
								if(1 != (byte >> 7 & 1)) {
									throw haxe_Exception.thrown("Valid UTF-8 multi-sequence byte expected at position [" + this.byteIndex + "] but found byte with value [" + byte + "]!");
								}
								if(1 == (byte >> 6 & 1)) {
									throw haxe_Exception.thrown("Valid UTF-8 multi-sequence byte expected at position [" + this.byteIndex + "] but found byte with value [" + byte + "]!");
								}
								let byte3 = byte & -129;
								result += byte3 << 6 * (totalBytes - 3);
								if(isBit5Set) {
									let byte = this.input.readByte();
									this.byteIndex++;
									if(1 != (byte >> 7 & 1)) {
										throw haxe_Exception.thrown("Valid UTF-8 multi-sequence byte expected at position [" + this.byteIndex + "] but found byte with value [" + byte + "]!");
									}
									if(1 == (byte >> 6 & 1)) {
										throw haxe_Exception.thrown("Valid UTF-8 multi-sequence byte expected at position [" + this.byteIndex + "] but found byte with value [" + byte + "]!");
									}
									let byte4 = byte & -129;
									result += byte4 << 6 * (totalBytes - 4);
								}
							}
							tmp = this.index == 0 && result == 65279 ? this.readUtf8Char() : result;
						}
					} else {
						tmp = result;
					}
				}
				this.nextChar = tmp;
				this.nextCharAvailable = true;
			} catch( _g ) {
				if(((haxe_Exception.caught(_g).unwrap()) instanceof haxe_io_Eof)) {
					this.nextCharAvailable = false;
				} else {
					throw _g;
				}
			}
		}
		return this.nextCharAvailable != true;
	}
	getChar() {
		if(this.index != this.currCharIndex) {
			this.currCharIndex = this.index;
			this.nextCharAvailable = null;
			return this.nextChar;
		}
		return this.currChar;
	}
	readUtf8Char() {
		let byte1 = this.input.readByte();
		this.byteIndex++;
		if(byte1 <= 127) {
			return byte1;
		}
		byte1 &= -129;
		byte1 &= -65;
		let totalBytes = 2;
		let isBit6Set = 1 == (byte1 >> 5 & 1);
		let isBit5Set = false;
		if(isBit6Set) {
			byte1 &= -33;
			++totalBytes;
			isBit5Set = 1 == (byte1 >> 4 & 1);
			if(isBit5Set) {
				byte1 &= -17;
				++totalBytes;
				if(1 == (byte1 >> 3 & 1)) {
					throw haxe_Exception.thrown("Valid UTF-8 byte expected at position [" + this.byteIndex + "] but found byte with value [" + byte1 + "]!");
				}
			}
		}
		let result = byte1 << 6 * (totalBytes - 1);
		let byte = this.input.readByte();
		this.byteIndex++;
		if(1 != (byte >> 7 & 1)) {
			throw haxe_Exception.thrown("Valid UTF-8 multi-sequence byte expected at position [" + this.byteIndex + "] but found byte with value [" + byte + "]!");
		}
		if(1 == (byte >> 6 & 1)) {
			throw haxe_Exception.thrown("Valid UTF-8 multi-sequence byte expected at position [" + this.byteIndex + "] but found byte with value [" + byte + "]!");
		}
		let byte2 = byte & -129;
		result += byte2 << 6 * (totalBytes - 2);
		if(isBit6Set) {
			let byte = this.input.readByte();
			this.byteIndex++;
			if(1 != (byte >> 7 & 1)) {
				throw haxe_Exception.thrown("Valid UTF-8 multi-sequence byte expected at position [" + this.byteIndex + "] but found byte with value [" + byte + "]!");
			}
			if(1 == (byte >> 6 & 1)) {
				throw haxe_Exception.thrown("Valid UTF-8 multi-sequence byte expected at position [" + this.byteIndex + "] but found byte with value [" + byte + "]!");
			}
			let byte3 = byte & -129;
			result += byte3 << 6 * (totalBytes - 3);
			if(isBit5Set) {
				let byte = this.input.readByte();
				this.byteIndex++;
				if(1 != (byte >> 7 & 1)) {
					throw haxe_Exception.thrown("Valid UTF-8 multi-sequence byte expected at position [" + this.byteIndex + "] but found byte with value [" + byte + "]!");
				}
				if(1 == (byte >> 6 & 1)) {
					throw haxe_Exception.thrown("Valid UTF-8 multi-sequence byte expected at position [" + this.byteIndex + "] but found byte with value [" + byte + "]!");
				}
				let byte4 = byte & -129;
				result += byte4 << 6 * (totalBytes - 4);
			}
		}
		if(this.index == 0 && result == 65279) {
			return this.readUtf8Char();
		}
		return result;
	}
	readUtf8MultiSequenceByte() {
		let byte = this.input.readByte();
		this.byteIndex++;
		if(1 != (byte >> 7 & 1)) {
			throw haxe_Exception.thrown("Valid UTF-8 multi-sequence byte expected at position [" + this.byteIndex + "] but found byte with value [" + byte + "]!");
		}
		if(1 == (byte >> 6 & 1)) {
			throw haxe_Exception.thrown("Valid UTF-8 multi-sequence byte expected at position [" + this.byteIndex + "] but found byte with value [" + byte + "]!");
		}
		return byte & -129;
	}
}
hx_strings__$CharIterator_InputCharIterator.__name__ = "hx.strings._CharIterator.InputCharIterator";
hx_strings__$CharIterator_InputCharIterator.__super__ = hx_strings_CharIterator;
Object.assign(hx_strings__$CharIterator_InputCharIterator.prototype, {
	__class__: hx_strings__$CharIterator_InputCharIterator
});
class hx_strings__$CharIterator_StringCharIterator extends hx_strings_CharIterator {
	constructor(chars,prevBufferSize) {
		super(prevBufferSize);
		this.chars = chars;
		this.charsMaxIndex = (chars == null ? 0 : chars.length) - 1;
	}
	isEOF() {
		return this.index >= this.charsMaxIndex;
	}
	getChar() {
		return HxOverrides.cca(this.chars,this.index);
	}
}
hx_strings__$CharIterator_StringCharIterator.__name__ = "hx.strings._CharIterator.StringCharIterator";
hx_strings__$CharIterator_StringCharIterator.__super__ = hx_strings_CharIterator;
Object.assign(hx_strings__$CharIterator_StringCharIterator.prototype, {
	__class__: hx_strings__$CharIterator_StringCharIterator
});
class hx_strings_Pattern {
	constructor(pattern,options) {
		this.pattern = pattern;
		this.options = options;
		this.ereg = new EReg(pattern,options);
		this.options += "u";
	}
	matcher(str) {
		return new hx_strings__$Pattern_MatcherImpl(this.ereg,this.pattern,this.options,str);
	}
	replace(str,replaceWith) {
		return str.replace(this.ereg.r,replaceWith);
	}
	remove(str) {
		return str.replace(this.ereg.r,"");
	}
	split(str) {
		return this.ereg.split(str);
	}
	static compile(pattern,options) {
		if(options == null) {
			return new hx_strings_Pattern(pattern,"");
		}
		let _g = options;
		let tmp;
		switch(_g._hx_index) {
		case 0:
			let str = _g.v;
			let str1 = hx_strings_Strings.toLowerCase8(str);
			if(str1 == null || str1.length == 0) {
				tmp = str1;
			} else {
				let _g = [];
				let _g1 = 0;
				let _g2 = hx_strings_Strings.toChars(str1);
				while(_g1 < _g2.length) {
					let v = _g2[_g1];
					++_g1;
					if(v == hx_strings_Strings.charCodeAt8("i",0) || v == hx_strings_Strings.charCodeAt8("m",0) || v == hx_strings_Strings.charCodeAt8("g",0)) {
						_g.push(v);
					}
				}
				let _this = _g;
				let result = new Array(_this.length);
				let _g3 = 0;
				let _g4 = _this.length;
				while(_g3 < _g4) {
					let i = _g3++;
					result[i] = String.fromCodePoint(_this[i]);
				}
				tmp = result.join("");
			}
			break;
		case 1:
			let opt = _g.v;
			tmp = Std.string(opt);
			break;
		case 2:
			let arr = _g.v;
			let _g1 = [];
			let _g2 = 0;
			let _g3 = arr;
			while(_g2 < _g3.length) {
				let v = _g3[_g2];
				++_g2;
				if(v != null) {
					_g1.push(v);
				}
			}
			tmp = _g1.join("");
			break;
		}
		return new hx_strings_Pattern(pattern,tmp);
	}
}
hx_strings_Pattern.__name__ = "hx.strings.Pattern";
Object.assign(hx_strings_Pattern.prototype, {
	__class__: hx_strings_Pattern
});
class hx_strings_Matcher {
}
hx_strings_Matcher.__name__ = "hx.strings.Matcher";
hx_strings_Matcher.__isInterface__ = true;
Object.assign(hx_strings_Matcher.prototype, {
	__class__: hx_strings_Matcher
});
class hx_strings__$Pattern_MatcherImpl {
	constructor(ereg,pattern,options,str) {
		let clone = new EReg(pattern,options);
		this.ereg = clone;
		this.str = str;
	}
	reset(str) {
		this.str = str;
		this.isMatch = null;
		return this;
	}
	iterate(onMatch) {
		let startAt = 0;
		while(this.ereg.matchSub(this.str,startAt)) {
			this.isMatch = true;
			let matchedPos = this.ereg.matchedPos();
			onMatch(this);
			startAt = matchedPos.pos + matchedPos.len;
		}
		this.isMatch = false;
	}
	map(mapper) {
		let _gthis = this;
		return this.ereg.map(this.str,function(ereg) {
			_gthis.isMatch = true;
			return mapper(_gthis);
		});
	}
	matched(n) {
		if(n == null) {
			n = 0;
		}
		if(!this.matches()) {
			throw haxe_Exception.thrown("No string matched");
		}
		let result = this.ereg.matched(n);
		return result;
	}
	matches() {
		if(this.isMatch == null) {
			this.isMatch = this.ereg.match(this.str);
		}
		return this.isMatch;
	}
	matchesInRegion(pos,len) {
		if(len == null) {
			len = -1;
		}
		return this.isMatch = this.ereg.matchSub(this.str,pos,len);
	}
	matchedPos() {
		if(!this.matches()) {
			throw haxe_Exception.thrown("No string matched");
		}
		return this.ereg.matchedPos();
	}
	substringAfterMatch() {
		if(!this.matches()) {
			return "";
		}
		return this.ereg.matchedRight();
	}
	substringBeforeMatch() {
		if(!this.matches()) {
			return "";
		}
		return this.ereg.matchedLeft();
	}
	_cloneEReg(from,pattern,options) {
		let clone = new EReg(pattern,options);
		return clone;
	}
}
hx_strings__$Pattern_MatcherImpl.__name__ = "hx.strings._Pattern.MatcherImpl";
hx_strings__$Pattern_MatcherImpl.__interfaces__ = [hx_strings_Matcher];
Object.assign(hx_strings__$Pattern_MatcherImpl.prototype, {
	__class__: hx_strings__$Pattern_MatcherImpl
});
class hx_strings_internal_OS {
}
hx_strings_internal_OS.__name__ = "hx.strings.internal.OS";
class js_Boot {
	static getClass(o) {
		if(o == null) {
			return null;
		} else if(((o) instanceof Array)) {
			return Array;
		} else {
			let cl = o.__class__;
			if(cl != null) {
				return cl;
			}
			let name = js_Boot.__nativeClassName(o);
			if(name != null) {
				return js_Boot.__resolveNativeClass(name);
			}
			return null;
		}
	}
	static __string_rec(o,s) {
		if(o == null) {
			return "null";
		}
		if(s.length >= 5) {
			return "<...>";
		}
		let t = typeof(o);
		if(t == "function" && (o.__name__ || o.__ename__)) {
			t = "object";
		}
		switch(t) {
		case "function":
			return "<function>";
		case "object":
			if(o.__enum__) {
				let e = $hxEnums[o.__enum__];
				let con = e.__constructs__[o._hx_index];
				let n = con._hx_name;
				if(con.__params__) {
					s = s + "\t";
					return n + "(" + ((function($this) {
						var $r;
						let _g = [];
						{
							let _g1 = 0;
							let _g2 = con.__params__;
							while(true) {
								if(!(_g1 < _g2.length)) {
									break;
								}
								let 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)) {
				let str = "[";
				s += "\t";
				let _g = 0;
				let _g1 = o.length;
				while(_g < _g1) {
					let i = _g++;
					str += (i > 0 ? "," : "") + js_Boot.__string_rec(o[i],s);
				}
				str += "]";
				return str;
			}
			let tostr;
			try {
				tostr = o.toString;
			} catch( _g ) {
				return "???";
			}
			if(tostr != null && tostr != Object.toString && typeof(tostr) == "function") {
				let s2 = o.toString();
				if(s2 != "[object Object]") {
					return s2;
				}
			}
			let str = "{\n";
			s += "\t";
			let hasp = o.hasOwnProperty != null;
			let 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);
		}
	}
	static __interfLoop(cc,cl) {
		if(cc == null) {
			return false;
		}
		if(cc == cl) {
			return true;
		}
		let intf = cc.__interfaces__;
		if(intf != null && (cc.__super__ == null || cc.__super__.__interfaces__ != intf)) {
			let _g = 0;
			let _g1 = intf.length;
			while(_g < _g1) {
				let i = _g++;
				let i1 = intf[i];
				if(i1 == cl || js_Boot.__interfLoop(i1,cl)) {
					return true;
				}
			}
		}
		return js_Boot.__interfLoop(cc.__super__,cl);
	}
	static __instanceof(o,cl) {
		if(cl == null) {
			return false;
		}
		switch(cl) {
		case Array:
			return ((o) instanceof Array);
		case Bool:
			return typeof(o) == "boolean";
		case Dynamic:
			return o != null;
		case Float:
			return typeof(o) == "number";
		case Int:
			if(typeof(o) == "number") {
				return ((o | 0) === o);
			} else {
				return false;
			}
			break;
		case String:
			return typeof(o) == "string";
		default:
			if(o != null) {
				if(typeof(cl) == "function") {
					if(js_Boot.__downcastCheck(o,cl)) {
						return true;
					}
				} else if(typeof(cl) == "object" && js_Boot.__isNativeObj(cl)) {
					if(((o) instanceof cl)) {
						return true;
					}
				}
			} else {
				return false;
			}
			if(cl == Class ? o.__name__ != null : false) {
				return true;
			}
			if(cl == Enum ? o.__ename__ != null : false) {
				return true;
			}
			return o.__enum__ != null ? $hxEnums[o.__enum__] == cl : false;
		}
	}
	static __downcastCheck(o,cl) {
		if(!((o) instanceof cl)) {
			if(cl.__isInterface__) {
				return js_Boot.__interfLoop(js_Boot.getClass(o),cl);
			} else {
				return false;
			}
		} else {
			return true;
		}
	}
	static __cast(o,t) {
		if(o == null || js_Boot.__instanceof(o,t)) {
			return o;
		} else {
			throw haxe_Exception.thrown("Cannot cast " + Std.string(o) + " to " + Std.string(t));
		}
	}
	static __nativeClassName(o) {
		let name = js_Boot.__toStr.call(o).slice(8,-1);
		if(name == "Object" || name == "Function" || name == "Math" || name == "JSON") {
			return null;
		}
		return name;
	}
	static __isNativeObj(o) {
		return js_Boot.__nativeClassName(o) != null;
	}
	static __resolveNativeClass(name) {
		return $global[name];
	}
}
js_Boot.__name__ = "js.Boot";
var hx_strings_internal__$Either3__$Either3 = $hxEnums["hx.strings.internal._Either3._Either3"] = { __ename__:true,__constructs__:null
	,a: ($_=function(v) { return {_hx_index:0,v:v,__enum__:"hx.strings.internal._Either3._Either3",toString:$estr}; },$_._hx_name="a",$_.__params__ = ["v"],$_)
	,b: ($_=function(v) { return {_hx_index:1,v:v,__enum__:"hx.strings.internal._Either3._Either3",toString:$estr}; },$_._hx_name="b",$_.__params__ = ["v"],$_)
	,c: ($_=function(v) { return {_hx_index:2,v:v,__enum__:"hx.strings.internal._Either3._Either3",toString:$estr}; },$_._hx_name="c",$_.__params__ = ["v"],$_)
};
hx_strings_internal__$Either3__$Either3.__constructs__ = [hx_strings_internal__$Either3__$Either3.a,hx_strings_internal__$Either3__$Either3.b,hx_strings_internal__$Either3__$Either3.c];
class hx_strings_Strings {
	static _length(str) {
		return str.length;
	}
	static _getNotFoundDefault(str,notFoundDefault) {
		switch(notFoundDefault) {
		case 1:
			return null;
		case 2:
			return "";
		case 3:
			return str;
		}
	}
	static _charCodeAt8Unsafe(str,pos) {
		return HxOverrides.cca(str,pos);
	}
	static _splitAsciiWordsUnsafe(str) {
		let words = [];
		let currentWord = new hx_strings_StringBuilder();
		let chars = hx_strings_Strings.toChars(str);
		let len = chars.length;
		let lastIndex = len - 1;
		let _g = 0;
		let _g1 = len;
		while(_g < _g1) {
			let i = _g++;
			let ch = chars[i];
			if(ch > 64 && ch < 91 || ch > 96 && ch < 123) {
				let chNext = i < lastIndex ? chars[i + 1] : -1;
				currentWord.addChar(ch);
				if(chNext > 47 && chNext < 58) {
					words.push(currentWord.toString());
					currentWord.clear();
				} else if(hx_strings_Char.CHAR_CASE_MAPPER.mapU2L.h.hasOwnProperty(ch)) {
					if(hx_strings_Char.CHAR_CASE_MAPPER.mapU2L.h.hasOwnProperty(chNext) && chars.length > i + 2) {
						if(!hx_strings_Char.CHAR_CASE_MAPPER.mapU2L.h.hasOwnProperty(chars[i + 2])) {
							words.push(currentWord.toString());
							currentWord.clear();
						}
					}
				} else if(hx_strings_Char.CHAR_CASE_MAPPER.mapU2L.h.hasOwnProperty(chNext)) {
					words.push(currentWord.toString());
					currentWord.clear();
				}
			} else if(ch > 47 && ch < 58) {
				currentWord.addChar(ch);
				let chNext = i < lastIndex ? chars[i + 1] : -1;
				if(!(chNext > 47 && chNext < 58)) {
					words.push(currentWord.toString());
					currentWord.clear();
				}
			} else if(currentWord.len > 0) {
				words.push(currentWord.toString());
				currentWord.clear();
			}
		}
		if(currentWord.len > 0) {
			words.push(currentWord.toString());
		}
		return words;
	}
	static ansiToHtml(str,renderMethod,initialState) {
		if(str == null || str.length == 0) {
			return str;
		}
		if(renderMethod == null) {
			renderMethod = hx_strings_AnsiToHtmlRenderMethod.StyleAttributes;
		}
		let styleOrClassAttribute;
		switch(renderMethod._hx_index) {
		case 0:
			styleOrClassAttribute = "style";
			break;
		case 1:
			styleOrClassAttribute = "class";
			break;
		case 2:
			let cb = renderMethod.func;
			styleOrClassAttribute = "class";
			break;
		}
		let sb = new hx_strings_StringBuilder();
		if(initialState != null && (initialState.fgcolor != null || initialState.bgcolor != null || initialState.bold || initialState.underline || initialState.blink)) {
			sb.add("<span " + styleOrClassAttribute + "=\"").add(initialState.toCSS(renderMethod)).add("\">");
		}
		let effectiveState = new hx_strings_AnsiState(initialState);
		let strLenMinus1 = (str == null ? 0 : str.length) - 1;
		let i = -1;
		let lookAhead = new hx_strings_StringBuilder();
		while(i < strLenMinus1) {
			++i;
			let ch = HxOverrides.cca(str,i);
			if(ch == 27 && i < strLenMinus1 && HxOverrides.cca(str,i + 1) == 91) {
				lookAhead.clear();
				let currentState = new hx_strings_AnsiState(effectiveState);
				let currentGraphicModeParam = 0;
				let isValidEscapeSequence = false;
				++i;
				_hx_loop2: while(i < strLenMinus1) {
					++i;
					let ch2 = HxOverrides.cca(str,i);
					lookAhead.addChar(ch2);
					switch(ch2) {
					case 48:
						currentGraphicModeParam *= 10;
						break;
					case 49:
						currentGraphicModeParam = currentGraphicModeParam * 10 + 1;
						break;
					case 50:
						currentGraphicModeParam = currentGraphicModeParam * 10 + 2;
						break;
					case 51:
						currentGraphicModeParam = currentGraphicModeParam * 10 + 3;
						break;
					case 52:
						currentGraphicModeParam = currentGraphicModeParam * 10 + 4;
						break;
					case 53:
						currentGraphicModeParam = currentGraphicModeParam * 10 + 5;
						break;
					case 54:
						currentGraphicModeParam = currentGraphicModeParam * 10 + 6;
						break;
					case 55:
						currentGraphicModeParam = currentGraphicModeParam * 10 + 7;
						break;
					case 56:
						currentGraphicModeParam = currentGraphicModeParam * 10 + 8;
						break;
					case 57:
						currentGraphicModeParam = currentGraphicModeParam * 10 + 9;
						break;
					case 59:
						currentState.setGraphicModeParameter(currentGraphicModeParam);
						currentGraphicModeParam = 0;
						break;
					case 109:
						currentState.setGraphicModeParameter(currentGraphicModeParam);
						if(effectiveState.fgcolor != null || effectiveState.bgcolor != null || effectiveState.bold || effectiveState.underline || effectiveState.blink) {
							sb.add("</span>");
						}
						if(currentState.fgcolor != null || currentState.bgcolor != null || currentState.bold || currentState.underline || currentState.blink) {
							sb.add("<span " + styleOrClassAttribute + "=\"").add(currentState.toCSS(renderMethod)).add("\">");
						}
						effectiveState = currentState;
						isValidEscapeSequence = true;
						break _hx_loop2;
					default:
						break _hx_loop2;
					}
				}
				if(!isValidEscapeSequence) {
					sb.addChar(27).add("[").add(Std.string(lookAhead));
				}
			} else {
				sb.addChar(ch);
			}
		}
		if(effectiveState.fgcolor != null || effectiveState.bgcolor != null || effectiveState.bold || effectiveState.underline || effectiveState.blink) {
			sb.add("</span>");
		}
		return sb.toString();
	}
	static appendIfMissing(str,suffix) {
		if(str == null) {
			return null;
		}
		if(str.length == 0) {
			return Std.string(str) + Std.string(suffix);
		}
		if(hx_strings_Strings.endsWith(str,suffix)) {
			return str;
		}
		return Std.string(str) + Std.string(suffix);
	}
	static base64Encode(plain) {
		if(plain == null) {
			return null;
		}
		return haxe_crypto_Base64.encode(plain == null ? null : haxe_io_Bytes.ofString(plain));
	}
	static base64Decode(encoded) {
		if(encoded == null) {
			return null;
		}
		return haxe_crypto_Base64.decode(encoded).toString();
	}
	static charAt8(str,pos,resultIfOutOfBound) {
		if(resultIfOutOfBound == null) {
			resultIfOutOfBound = "";
		}
		if(str == null || str.length == 0 || pos < 0 || pos >= (str == null ? 0 : str.length)) {
			return resultIfOutOfBound;
		}
		return str.charAt(pos);
	}
	static charCodeAt8(str,pos,resultIfOutOfBound) {
		if(resultIfOutOfBound == null) {
			resultIfOutOfBound = -1;
		}
		let strLen = str == null ? 0 : str.length;
		if(strLen == 0 || pos < 0 || pos >= strLen) {
			return resultIfOutOfBound;
		}
		return HxOverrides.cca(str,pos);
	}
	static compact(str) {
		if(str == null || str.length == 0) {
			return str;
		}
		let sb = new hx_strings_StringBuilder();
		let needWhiteSpace = false;
		let _g = 0;
		let _g1 = hx_strings_Strings.toChars(str);
		while(_g < _g1.length) {
			let char = _g1[_g];
			++_g;
			if(char > 8 && char < 14 || char == 32) {
				if(sb.len != 0) {
					needWhiteSpace = true;
				}
				continue;
			} else if(needWhiteSpace) {
				sb.addChar(32);
				needWhiteSpace = false;
			}
			sb.addChar(char);
		}
		return sb.toString();
	}
	static contains(searchIn,searchFor) {
		if(searchIn == null || searchFor == null) {
			return false;
		}
		if(searchFor == "") {
			return true;
		}
		return searchIn.indexOf(searchFor) > -1;
	}
	static containsOnly(searchIn,allowedChars) {
		if(searchIn == null || searchIn.length == 0) {
			return true;
		}
		if(allowedChars == null) {
			return false;
		}
		let allowedCharsArray;
		let _g = allowedChars;
		switch(_g._hx_index) {
		case 0:
			let str = _g.v;
			allowedCharsArray = hx_strings_Strings.toChars(str);
			break;
		case 1:
			let chars = _g.v;
			allowedCharsArray = chars;
			break;
		}
		let _g1 = 0;
		let _g2 = hx_strings_Strings.toChars(searchIn);
		while(_g1 < _g2.length) {
			let ch = _g2[_g1];
			++_g1;
			if(allowedCharsArray.indexOf(ch) < 0) {
				return false;
			}
		}
		return true;
	}
	static containsAll(searchIn,searchFor) {
		if(searchIn == null || searchFor == null) {
			return false;
		}
		let _g = 0;
		while(_g < searchFor.length) {
			let candidate = searchFor[_g];
			++_g;
			if(!(searchIn == null || candidate == null ? false : candidate == "" ? true : searchIn.indexOf(candidate) > -1)) {
				return false;
			}
		}
		return true;
	}
	static containsAllIgnoreCase(searchIn,searchFor) {
		if(searchIn == null || searchFor == null) {
			return false;
		}
		searchIn = searchIn.toLowerCase();
		let _g = 0;
		while(_g < searchFor.length) {
			let candidate = searchFor[_g];
			++_g;
			let searchFor1 = candidate.toLowerCase();
			if(!(searchIn == null || searchFor1 == null ? false : searchFor1 == "" ? true : searchIn.indexOf(searchFor1) > -1)) {
				return false;
			}
		}
		return true;
	}
	static containsAny(searchIn,searchFor) {
		if(searchIn == null || searchFor == null) {
			return false;
		}
		let _g = 0;
		while(_g < searchFor.length) {
			let candidate = searchFor[_g];
			++_g;
			if(searchIn == null || candidate == null ? false : candidate == "" ? true : searchIn.indexOf(candidate) > -1) {
				return true;
			}
		}
		return false;
	}
	static containsAnyIgnoreCase(searchIn,searchFor) {
		if(searchIn == null || searchFor == null) {
			return false;
		}
		searchIn = searchIn.toLowerCase();
		let _g = 0;
		while(_g < searchFor.length) {
			let candidate = searchFor[_g];
			++_g;
			let searchFor1 = candidate.toLowerCase();
			if(searchIn == null || searchFor1 == null ? false : searchFor1 == "" ? true : searchIn.indexOf(searchFor1) > -1) {
				return true;
			}
		}
		return false;
	}
	static containsNone(searchIn,searchFor) {
		return !hx_strings_Strings.containsAny(searchIn,searchFor);
	}
	static containsNoneIgnoreCase(searchIn,searchFor) {
		return !hx_strings_Strings.containsAnyIgnoreCase(searchIn,searchFor);
	}
	static containsWhitespaces(searchIn) {
		if(searchIn == null) {
			return false;
		}
		let _g = 0;
		let _g1 = hx_strings_Strings.toChars(searchIn);
		while(_g < _g1.length) {
			let ch = _g1[_g];
			++_g;
			if(ch > 8 && ch < 14 || ch == 32) {
				return true;
			}
		}
		return false;
	}
	static countMatches(searchIn,searchFor,startAt) {
		if(startAt == null) {
			startAt = 0;
		}
		if(searchIn == null || searchIn.length == 0 || (searchFor == null || searchFor.length == 0) || startAt >= searchIn.length) {
			return 0;
		}
		if(startAt < 0) {
			startAt = 0;
		}
		let count = 0;
		let foundAt = startAt > -1 ? startAt - 1 : 0;
		while(true) {
			foundAt = searchIn.indexOf(searchFor,foundAt + 1);
			if(!(foundAt > -1)) {
				break;
			}
			++count;
		}
		return count;
	}
	static countMatchesIgnoreCase(searchIn,searchFor,startAt) {
		if(startAt == null) {
			startAt = 0;
		}
		if(searchIn == null || searchIn.length == 0 || (searchFor == null || searchFor.length == 0) || startAt >= searchIn.length) {
			return 0;
		}
		if(startAt < 0) {
			startAt = 0;
		}
		searchIn = searchIn.toLowerCase();
		searchFor = searchFor.toLowerCase();
		let count = 0;
		let foundAt = startAt > -1 ? startAt - 1 : 0;
		while(true) {
			foundAt = searchIn.indexOf(searchFor,foundAt + 1);
			if(!(foundAt > -1)) {
				break;
			}
			++count;
		}
		return count;
	}
	static compare(str,other) {
		if(str == null) {
			if(other == null) {
				return 0;
			} else {
				return -1;
			}
		}
		if(other == null) {
			if(str == null) {
				return 0;
			} else {
				return 1;
			}
		}
		if(str > other) {
			return 1;
		} else if(str == other) {
			return 0;
		} else {
			return -1;
		}
	}
	static compareIgnoreCase(str,other) {
		if(str == null) {
			if(other == null) {
				return 0;
			} else {
				return -1;
			}
		}
		if(other == null) {
			if(str == null) {
				return 0;
			} else {
				return 1;
			}
		}
		let str1 = hx_strings_Strings.toLowerCase8(str);
		let other1 = hx_strings_Strings.toLowerCase8(other);
		if(str1 > other1) {
			return 1;
		} else if(str1 == other1) {
			return 0;
		} else {
			return -1;
		}
	}
	static diff(left,right) {
		let diff = new hx_strings_StringDiff();
		diff.at = hx_strings_Strings.diffAt(left,right);
		diff.left = hx_strings_Strings.substr8(left,diff.at);
		diff.right = hx_strings_Strings.substr8(right,diff.at);
		return diff;
	}
	static diffAt(str,other) {
		if(str == other) {
			return -1;
		}
		let strLen = str == null ? 0 : str.length;
		let otherLen = other == null ? 0 : other.length;
		if(strLen == 0 || otherLen == 0) {
			return 0;
		}
		let checkLen = strLen > otherLen ? otherLen : strLen;
		let _g = 0;
		let _g1 = checkLen;
		while(_g < _g1) {
			let i = _g++;
			if(HxOverrides.cca(str,i) != HxOverrides.cca(other,i)) {
				return i;
			}
		}
		return checkLen;
	}
	static ellipsizeLeft(str,maxLength,ellipsis) {
		if(ellipsis == null) {
			ellipsis = "...";
		}
		if((str == null ? 0 : str.length) <= maxLength) {
			return str;
		}
		let ellipsisLen = ellipsis == null ? 0 : ellipsis.length;
		if(maxLength < ellipsisLen) {
			throw haxe_Exception.thrown("[maxLength] must not be smaller than " + ellipsisLen);
		}
		return ellipsis + Std.string(hx_strings_Strings.right(str,maxLength - ellipsisLen));
	}
	static ellipsizeMiddle(str,maxLength,ellipsis) {
		if(ellipsis == null) {
			ellipsis = "...";
		}
		let strLen = str == null ? 0 : str.length;
		if(strLen <= maxLength) {
			return str;
		}
		let ellipsisLen = ellipsis == null ? 0 : ellipsis.length;
		if(maxLength < ellipsisLen) {
			throw haxe_Exception.thrown("[maxLength] must not be smaller than " + ellipsisLen);
		}
		let maxStrLen = maxLength - ellipsisLen;
		let leftLen = Math.round(maxStrLen / 2);
		let rightLen = maxStrLen - leftLen;
		return Std.string((str == null ? 0 : str.length) <= leftLen ? str : hx_strings_Strings.substring8(str,0,leftLen)) + ellipsis + Std.string(hx_strings_Strings.right(str,rightLen));
	}
	static ellipsizeRight(str,maxLength,ellipsis) {
		if(ellipsis == null) {
			ellipsis = "...";
		}
		if((str == null ? 0 : str.length) <= maxLength) {
			return str;
		}
		let ellipsisLen = ellipsis == null ? 0 : ellipsis.length;
		if(maxLength < ellipsisLen) {
			throw haxe_Exception.thrown("[maxLength] must not be smaller than " + ellipsisLen);
		}
		let len = maxLength - ellipsisLen;
		return Std.string((str == null ? 0 : str.length) <= len ? str : hx_strings_Strings.substring8(str,0,len)) + ellipsis;
	}
	static endsWith(searchIn,searchFor) {
		if(searchIn == null || searchFor == null) {
			return false;
		}
		return searchIn.endsWith(searchFor);
	}
	static endsWithAny(searchIn,searchFor) {
		if(searchIn == null || searchFor == null) {
			return false;
		}
		let _g = 0;
		while(_g < searchFor.length) {
			let candidate = searchFor[_g];
			++_g;
			if(candidate != null && hx_strings_Strings.endsWith(searchIn,candidate)) {
				return true;
			}
		}
		return false;
	}
	static endsWithAnyIgnoreCase(searchIn,searchFor) {
		if(searchIn == null || searchFor == null) {
			return false;
		}
		searchIn = hx_strings_Strings.toLowerCase8(searchIn);
		let _g = 0;
		while(_g < searchFor.length) {
			let candidate = searchFor[_g];
			++_g;
			if(candidate != null && hx_strings_Strings.endsWith(searchIn,hx_strings_Strings.toLowerCase8(candidate))) {
				return true;
			}
		}
		return false;
	}
	static endsWithIgnoreCase(searchIn,searchFor) {
		if(searchIn == null || searchFor == null) {
			return false;
		}
		return hx_strings_Strings.endsWith(searchIn.toLowerCase(),searchFor.toLowerCase());
	}
	static equals(str,other) {
		return str == other;
	}
	static equalsIgnoreCase(str,other) {
		return hx_strings_Strings.toLowerCase8(str) == hx_strings_Strings.toLowerCase8(other);
	}
	static filter(str,filter,separator) {
		if(separator == null) {
			separator = "";
		}
		if(str == null || str.length == 0) {
			return str;
		}
		let _g = [];
		let _g1 = 0;
		let _g2 = hx_strings_Strings.split8(str,[separator]);
		while(_g1 < _g2.length) {
			let v = _g2[_g1];
			++_g1;
			if(filter(v)) {
				_g.push(v);
			}
		}
		return _g.join(separator);
	}
	static filterChars(str,filter) {
		if(str == null || str.length == 0) {
			return str;
		}
		let _g = [];
		let _g1 = 0;
		let _g2 = hx_strings_Strings.toChars(str);
		while(_g1 < _g2.length) {
			let v = _g2[_g1];
			++_g1;
			if(filter(v)) {
				_g.push(v);
			}
		}
		let _this = _g;
		let result = new Array(_this.length);
		let _g3 = 0;
		let _g4 = _this.length;
		while(_g3 < _g4) {
			let i = _g3++;
			result[i] = String.fromCodePoint(_this[i]);
		}
		return result.join("");
	}
	static getFuzzyDistance(left,right) {
		if(left == null || left.length == 0 || (right == null || right.length == 0)) {
			return 0;
		}
		left = hx_strings_Strings.toLowerCase8(left);
		right = hx_strings_Strings.toLowerCase8(right);
		let leftChars = hx_strings_Strings.toChars(left);
		let rightChars = hx_strings_Strings.toChars(right);
		let leftLastMatchAt = -100;
		let rightLastMatchAt = -100;
		let score = 0;
		let _g = 0;
		let _g1 = leftChars.length;
		while(_g < _g1) {
			let leftIdx = _g++;
			let leftChar = leftChars[leftIdx];
			let _g1 = rightLastMatchAt > -1 ? rightLastMatchAt + 1 : 0;
			let _g2 = rightChars.length;
			while(_g1 < _g2) {
				let rightIdx = _g1++;
				let rightChar = rightChars[rightIdx];
				if(leftChar == rightChar) {
					++score;
					if(leftLastMatchAt == leftIdx - 1 && rightLastMatchAt == rightIdx - 1) {
						score += 2;
					}
					leftLastMatchAt = leftIdx;
					rightLastMatchAt = rightIdx;
					break;
				}
			}
		}
		return score;
	}
	static getLevenshteinDistance(left,right) {
		let leftLen = left == null ? 0 : left.length;
		let rightLen = right == null ? 0 : right.length;
		if(leftLen == 0) {
			return rightLen;
		}
		if(rightLen == 0) {
			return leftLen;
		}
		if(leftLen > rightLen) {
			let tmp = left;
			left = right;
			right = tmp;
			let tmpLen = leftLen;
			leftLen = rightLen;
			rightLen = tmpLen;
		}
		let prevCosts = [];
		let costs = [];
		let _g = 0;
		let _g1 = leftLen + 1;
		while(_g < _g1) {
			let leftIdx = _g++;
			prevCosts.push(leftIdx);
			costs.push(0);
		}
		let leftChars = hx_strings_Strings.toChars(left);
		let rightChars = hx_strings_Strings.toChars(right);
		let min = function(a,b) {
			if(a > b) {
				return b;
			} else {
				return a;
			}
		};
		let _g2 = 1;
		let _g3 = rightLen + 1;
		while(_g2 < _g3) {
			let rightIdx = _g2++;
			let rightChar = rightChars[rightIdx - 1];
			costs[0] = rightIdx;
			let _g = 1;
			let _g1 = leftLen + 1;
			while(_g < _g1) {
				let leftIdx = _g++;
				let leftIdxMinus1 = leftIdx - 1;
				let cost = leftChars[leftIdxMinus1] == rightChar ? 0 : 1;
				costs[leftIdx] = min(min(costs[leftIdxMinus1] + 1,prevCosts[leftIdx] + 1),prevCosts[leftIdxMinus1] + cost);
			}
			let tmp = prevCosts;
			prevCosts = costs;
			costs = tmp;
		}
		return prevCosts[leftLen];
	}
	static getLongestCommonSubstring(left,right) {
		if(left == null || right == null) {
			return null;
		}
		let leftLen = left == null ? 0 : left.length;
		let rightLen = right == null ? 0 : right.length;
		if(leftLen == 0 || rightLen == 0) {
			return "";
		}
		let leftChars = hx_strings_Strings.toChars(left);
		let rightChars = hx_strings_Strings.toChars(right);
		let leftSubStartAt = 0;
		let leftSubLen = 0;
		let _g = 0;
		let _g1 = leftLen;
		while(_g < _g1) {
			let leftIdx = _g++;
			let _g1 = 0;
			let _g2 = rightLen;
			while(_g1 < _g2) {
				let rightIdx = _g1++;
				let currLen = 0;
				while(leftChars[leftIdx + currLen] == rightChars[rightIdx + currLen]) {
					++currLen;
					if(leftIdx + currLen >= leftLen || rightIdx + currLen >= rightLen) {
						break;
					}
				}
				if(currLen > leftSubLen) {
					leftSubLen = currLen;
					leftSubStartAt = leftIdx;
				}
			}
		}
		return hx_strings_Strings.substr8(left,leftSubStartAt,leftSubLen);
	}
	static hashCode(str,algo) {
		if(str == null || str.length == 0) {
			return 0;
		}
		if(algo == null) {
			algo = hx_strings_HashCodeAlgorithm.PLATFORM_SPECIFIC;
		}
		if(algo == null) {
			return haxe_crypto_Crc32.make(str == null ? null : haxe_io_Bytes.ofString(str));
		} else {
			switch(algo._hx_index) {
			case 1:
				return haxe_crypto_Adler32.make(str == null ? null : haxe_io_Bytes.ofString(str));
			case 2:
				return haxe_crypto_Crc32.make(str == null ? null : haxe_io_Bytes.ofString(str));
			case 3:
				let hc = 5381;
				let _g = 0;
				let _g1 = hx_strings_Strings.toChars(str);
				while(_g < _g1.length) {
					let ch = _g1[_g];
					++_g;
					hc = ((hc << 5) + hc | 0) ^ ch;
				}
				return hc;
			case 4:
				let hc1 = 0;
				let _g2 = 0;
				let _g3 = hx_strings_Strings.toChars(str);
				while(_g2 < _g3.length) {
					let ch = _g3[_g2];
					++_g2;
					hc1 = ((hc1 << 5) - hc1 | 0) + ch | 0;
				}
				return hc1;
			case 5:
				let hc2 = 0;
				let _g4 = 0;
				let _g5 = hx_strings_Strings.toChars(str);
				while(_g4 < _g5.length) {
					let ch = _g5[_g4];
					++_g4;
					hc2 = (((hc2 << 6) + (hc2 << 16) | 0) - hc2 | 0) + ch | 0;
				}
				return hc2;
			default:
				return haxe_crypto_Crc32.make(str == null ? null : haxe_io_Bytes.ofString(str));
			}
		}
	}
	static htmlDecode(str) {
		if(str == null || str.length == 0) {
			return str;
		}
		let _this = hx_strings_Strings.REGEX_HTML_UNESCAPE;
		return new hx_strings__$Pattern_MatcherImpl(_this.ereg,_this.pattern,_this.options,str).map(function(m) {
			let match = m.matched();
			switch(match) {
			case "&amp;":
				return "&";
			case "&apos;":
				return "'";
			case "&gt;":
				return ">";
			case "&lt;":
				return "<";
			case "&nbsp;":
				return " ";
			case "&quot;":
				return "\"";
			default:
				let number = Std.parseInt(hx_strings_Strings.substr8(match,2,(match == null ? 0 : match.length) - 3));
				if(number == null) {
					throw haxe_Exception.thrown("Invalid HTML value " + match);
				}
				let this1 = number;
				return String.fromCodePoint(this1);
			}
		});
	}
	static htmlEncode(str,escapeQuotes) {
		if(escapeQuotes == null) {
			escapeQuotes = false;
		}
		if(str == null || str.length == 0) {
			return str;
		}
		let sb = new hx_strings_StringBuilder();
		let isFirstSpace = true;
		let _g = 0;
		let _g1 = str == null ? 0 : str.length;
		while(_g < _g1) {
			let i = _g++;
			let ch = HxOverrides.cca(str,i);
			switch(ch) {
			case 32:
				if(isFirstSpace) {
					sb.add(" ");
					isFirstSpace = false;
				} else {
					sb.add("&nbsp;");
				}
				break;
			case 34:
				sb.add(escapeQuotes ? "&quot;" : "\"");
				break;
			case 38:
				sb.add("&amp;");
				break;
			case 39:
				sb.add(escapeQuotes ? "&#039;" : "'");
				break;
			case 60:
				sb.add("&lt;");
				break;
			case 62:
				sb.add("&gt;");
				break;
			default:
				if(ch > 127) {
					sb.add("&#").add(Std.string(ch)).add(";");
				} else {
					sb.addChar(ch);
				}
			}
			if(ch != 32) {
				isFirstSpace = true;
			}
		}
		return sb.toString();
	}
	static insertAt(str,pos,insertion) {
		if(str == null) {
			return null;
		}
		let strLen = str == null ? 0 : str.length;
		if(pos < 0) {
			pos = strLen + pos;
		}
		if(pos < 0 || pos > strLen) {
			throw haxe_Exception.thrown("Absolute value of [pos] must be <= str.length");
		}
		if(insertion == null || insertion.length == 0) {
			return str;
		}
		return Std.string(hx_strings_Strings.substring8(str,0,pos)) + insertion + Std.string(hx_strings_Strings.substring8(str,pos));
	}
	static ifBlank(str,fallback) {
		if(str == null ? true : StringTools.trim(str).length == 0) {
			return fallback;
		} else {
			return str;
		}
	}
	static ifEmpty(str,fallback) {
		if(str == null || str.length == 0) {
			return fallback;
		} else {
			return str;
		}
	}
	static ifNull(str,fallback) {
		if(str == null) {
			return fallback;
		} else {
			return str;
		}
	}
	static indentLines(str,indentWith) {
		if(str == null) {
			return null;
		}
		if(str.length == 0 || (indentWith == null || indentWith.length == 0)) {
			return str;
		}
		let isFirstLine = true;
		let sb = new hx_strings_StringBuilder();
		let _g = 0;
		let _g1 = hx_strings_Strings.REGEX_SPLIT_LINES.ereg.split(str);
		while(_g < _g1.length) {
			let line = _g1[_g];
			++_g;
			if(isFirstLine) {
				isFirstLine = false;
			} else {
				sb.newLine();
			}
			sb.add(indentWith);
			sb.add(line);
		}
		return sb.toString();
	}
	static indexOf8(str,searchFor,startAt) {
		if(startAt == null) {
			startAt = 0;
		}
		if(str == null || searchFor == null) {
			return -1;
		}
		let strLen = str == null ? 0 : str.length;
		let searchForLen = searchFor == null ? 0 : searchFor.length;
		if(startAt < 0) {
			startAt = 0;
		}
		if(searchForLen == 0) {
			if(startAt == 0) {
				return 0;
			}
			if(startAt > 0 && startAt < strLen) {
				return startAt;
			}
			return strLen;
		}
		if(startAt >= strLen) {
			return -1;
		}
		return str.indexOf(searchFor,startAt);
	}
	static isBlank(str) {
		if(str == null) {
			return true;
		} else {
			return StringTools.trim(str).length == 0;
		}
	}
	static isDigits(str) {
		if(str == null || str.length == 0) {
			return false;
		}
		let _g = 0;
		let _g1 = str == null ? 0 : str.length;
		while(_g < _g1) {
			let i = _g++;
			let this1 = HxOverrides.cca(str,i);
			if(!(this1 > 47 && this1 < 58)) {
				return false;
			}
		}
		return true;
	}
	static isEmpty(str) {
		if(str != null) {
			return str.length == 0;
		} else {
			return true;
		}
	}
	static isNotBlank(str) {
		if(str != null) {
			return StringTools.trim(str).length > 0;
		} else {
			return false;
		}
	}
	static isNotEmpty(str) {
		if(str != null) {
			return str.length > 0;
		} else {
			return false;
		}
	}
	static isLowerCase(str) {
		if(str == null || str.length == 0) {
			return false;
		}
		return str == hx_strings_Strings.toLowerCase8(str);
	}
	static isUpperCase(str) {
		if(str == null || str.length == 0) {
			return false;
		}
		return str == hx_strings_Strings.toUpperCase8(str);
	}
	static iterate(str,callback,separator) {
		if(separator == null) {
			separator = "";
		}
		if(str == null || str.length == 0) {
			return;
		}
		let _g = 0;
		let _g1 = hx_strings_Strings.split8(str,[separator]);
		while(_g < _g1.length) {
			let sub = _g1[_g];
			++_g;
			callback(sub);
		}
	}
	static iterateChars(str,callback) {
		if(str == null || str.length == 0) {
			return;
		}
		let _g = 0;
		let _g1 = str == null ? 0 : str.length;
		while(_g < _g1) {
			let i = _g++;
			callback(HxOverrides.cca(str,i));
		}
	}
	static lastIndexOf8(str,searchFor,startAt) {
		if(str == null || searchFor == null) {
			return -1;
		}
		let strLen = str == null ? 0 : str.length;
		let searchForLen = searchFor == null ? 0 : searchFor.length;
		if(startAt == null) {
			startAt = strLen;
		}
		if(searchForLen == 0) {
			if(startAt < 0) {
				return 0;
			}
			if(startAt > strLen) {
				return strLen;
			}
			return startAt;
		}
		if(startAt < 0) {
			return -1;
		} else if(startAt >= strLen) {
			startAt = strLen - 1;
		}
		let strNeedsUTF8Workaround = str.length != strLen;
		let searchForNeedsUTF8Workaround = searchFor.length != searchForLen;
		if(!strNeedsUTF8Workaround && !searchForNeedsUTF8Workaround) {
			return str.lastIndexOf(searchFor,startAt);
		}
		if(searchForNeedsUTF8Workaround && !strNeedsUTF8Workaround) {
			return -1;
		}
		let searchForChars = hx_strings_Strings.toChars(searchFor);
		startAt += searchForLen - 1;
		let searchForPosToCheck = searchForLen - 1;
		let strPos = strLen;
		while(strPos-- > 0) {
			if(strPos > startAt) {
				continue;
			}
			let strCh = HxOverrides.cca(str,strPos);
			if(strCh == searchForChars[searchForPosToCheck]) {
				if(searchForPosToCheck == 0) {
					return strPos;
				}
				--searchForPosToCheck;
			} else {
				searchForPosToCheck = searchForLen - 1;
			}
		}
		return -1;
	}
	static length8(str) {
		if(str == null) {
			return 0;
		}
		return str.length;
	}
	static left(str,len) {
		if((str == null ? 0 : str.length) <= len) {
			return str;
		}
		return hx_strings_Strings.substring8(str,0,len);
	}
	static lpad(str,targetLength,padStr,canOverflow) {
		if(canOverflow == null) {
			canOverflow = true;
		}
		if(padStr == null) {
			padStr = " ";
		}
		let strLen = str == null ? 0 : str.length;
		if(str == null || strLen > targetLength) {
			return str;
		}
		if(padStr == null || padStr.length == 0) {
			padStr = " ";
		}
		let sb = [str];
		let padLen = padStr == null ? 0 : padStr.length;
		while(strLen < targetLength) {
			sb.unshift(padStr);
			strLen += padLen;
		}
		if(canOverflow) {
			return sb.join("");
		}
		return hx_strings_Strings.right(sb.join(""),targetLength);
	}
	static map(str,mapper,separator) {
		if(separator == null) {
			separator = "";
		}
		if(str == null) {
			return null;
		}
		if(separator == null) {
			throw haxe_Exception.thrown("[separator] must not be null");
		}
		let _this = hx_strings_Strings.split8(str,[separator]);
		let result = new Array(_this.length);
		let _g = 0;
		let _g1 = _this.length;
		while(_g < _g1) {
			let i = _g++;
			result[i] = mapper(_this[i]);
		}
		return result;
	}
	static prependIfMissing(str,suffix) {
		if(str == null) {
			return null;
		}
		if(str.length == 0) {
			return suffix + Std.string(str);
		}
		if(hx_strings_Strings.startsWith(str,suffix)) {
			return str;
		}
		return suffix + Std.string(str);
	}
	static quoteDouble(str) {
		if(str == null) {
			return null;
		}
		if(str.length == 0) {
			return "\"\"";
		}
		if(!(str == null ? false : str.indexOf("\"") > -1)) {
			return "\"" + Std.string(str) + "\"";
		}
		return "\"" + Std.string(hx_strings_Strings.replaceAll(str,"\"","\\\"")) + "\"";
	}
	static quoteSingle(str) {
		if(str == null) {
			return null;
		}
		if(str.length == 0) {
			return "''";
		}
		if(!(str == null ? false : str.indexOf("'") > -1)) {
			return "'" + Std.string(str) + "'";
		}
		return "'" + Std.string(hx_strings_Strings.replaceAll(str,"'","\\'")) + "'";
	}
	static removeAfter(str,searchFor) {
		return hx_strings_Strings.substringBefore(str,searchFor);
	}
	static removeAfterLast(str,searchFor) {
		return hx_strings_Strings.substringBeforeLast(str,searchFor);
	}
	static removeAfterIgnoreCase(str,searchFor) {
		return hx_strings_Strings.substringBeforeIgnoreCase(str,searchFor);
	}
	static removeAfterLastIgnoreCase(str,searchFor) {
		return hx_strings_Strings.substringBeforeLastIgnoreCase(str,searchFor);
	}
	static removeAt(str,pos,length) {
		if(str == null || str.length == 0 || length < 1) {
			return str;
		}
		let strLen = str == null ? 0 : str.length;
		if(pos < 0) {
			pos = strLen + pos;
		}
		if(pos < 0) {
			throw haxe_Exception.thrown("[pos] must be smaller than -1 * str.length");
		}
		if(pos + length >= strLen) {
			return hx_strings_Strings.substring8(str,0,pos);
		}
		return Std.string(hx_strings_Strings.substring8(str,0,pos)) + Std.string(hx_strings_Strings.substring8(str,pos + length));
	}
	static removeBefore(str,searchFor) {
		return hx_strings_Strings.substringAfter(str,searchFor);
	}
	static removeBeforeLast(str,searchFor) {
		return hx_strings_Strings.substringAfterLast(str,searchFor);
	}
	static removeBeforeIgnoreCase(str,searchFor) {
		return hx_strings_Strings.substringAfterIgnoreCase(str,searchFor);
	}
	static removeBeforeLastIgnoreCase(str,searchFor) {
		return hx_strings_Strings.substringAfterLastIgnoreCase(str,searchFor);
	}
	static removeAll(searchIn,searchFor) {
		return hx_strings_Strings.replaceAll(searchIn,searchFor,"");
	}
	static removeFirst(searchIn,searchFor) {
		return hx_strings_Strings.replaceFirst(searchIn,searchFor,"");
	}
	static removeFirstIgnoreCase(searchIn,searchFor) {
		return hx_strings_Strings.replaceFirstIgnoreCase(searchIn,searchFor,"");
	}
	static removeAnsi(str) {
		if(str == null || str.length == 0) {
			return str;
		}
		return str.replace(hx_strings_Strings.REGEX_ANSI_ESC.ereg.r,"");
	}
	static removeLeading(searchIn,searchFor) {
		if(searchIn == null || searchIn.length == 0 || (searchFor == null || searchFor.length == 0)) {
			return searchIn;
		}
		while(hx_strings_Strings.startsWith(searchIn,searchFor)) searchIn = searchIn.substring(searchFor.length,searchIn.length);
		return searchIn;
	}
	static removeTags(xml) {
		if(xml == null || xml.length == 0) {
			return xml;
		}
		return xml.replace(hx_strings_Strings.REGEX_REMOVE_XML_TAGS.ereg.r,"");
	}
	static removeTrailing(searchIn,searchFor) {
		if(searchIn == null || searchIn.length == 0 || (searchFor == null || searchFor.length == 0)) {
			return searchIn;
		}
		while(hx_strings_Strings.endsWith(searchIn,searchFor)) searchIn = searchIn.substring(0,searchIn.length - searchFor.length);
		return searchIn;
	}
	static repeat(str,count,separator) {
		if(separator == null) {
			separator = "";
		}
		if(str == null) {
			return null;
		}
		if(count < 1) {
			return "";
		}
		if(count == 1) {
			return str;
		}
		let _g = [];
		let _g1 = 0;
		let _g2 = count;
		while(_g1 < _g2) {
			let i = _g1++;
			_g.push(str);
		}
		return _g.join(separator);
	}
	static replaceAll(searchIn,searchFor,replaceWith) {
		if(searchIn == null || (searchIn == null || searchIn.length == 0) || searchFor == null) {
			return searchIn;
		}
		if(replaceWith == null) {
			replaceWith = "null";
		}
		return StringTools.replace(searchIn,searchFor,replaceWith);
	}
	static replaceFirst(searchIn,searchFor,replaceWith) {
		if(searchIn == null || (searchIn == null || searchIn.length == 0) || searchFor == null) {
			return searchIn;
		}
		if(replaceWith == null) {
			replaceWith = "null";
		}
		let foundAt;
		if(searchFor.length == 0) {
			if((searchIn == null ? 0 : searchIn.length) > 1) {
				foundAt = 1;
			} else {
				return searchIn;
			}
		} else {
			foundAt = hx_strings_Strings.indexOf8(searchIn,searchFor);
		}
		return Std.string(hx_strings_Strings.substr8(searchIn,0,foundAt)) + replaceWith + Std.string(hx_strings_Strings.substr8(searchIn,foundAt + (searchFor == null ? 0 : searchFor.length)));
	}
	static replaceFirstIgnoreCase(searchIn,searchFor,replaceWith) {
		if(searchIn == null || (searchIn == null || searchIn.length == 0) || searchFor == null) {
			return searchIn;
		}
		if(replaceWith == null) {
			replaceWith = "null";
		}
		searchFor = searchFor.toLowerCase();
		let foundAt;
		if(searchFor.length == 0) {
			if((searchIn == null ? 0 : searchIn.length) > 1) {
				foundAt = 1;
			} else {
				return searchIn;
			}
		} else {
			foundAt = hx_strings_Strings.indexOf8(searchIn.toLowerCase(),searchFor);
		}
		return Std.string(hx_strings_Strings.substr8(searchIn,0,foundAt)) + replaceWith + Std.string(hx_strings_Strings.substr8(searchIn,foundAt + (searchFor == null ? 0 : searchFor.length)));
	}
	static reverse(str) {
		if(str == null || str.length == 0) {
			return str;
		}
		let chars = hx_strings_Strings.split8(str,[""]);
		chars.reverse();
		return chars.join("");
	}
	static right(str,len) {
		if(str == null || str.length == 0) {
			return str;
		}
		return hx_strings_Strings.substring8(str,(str == null ? 0 : str.length) - len);
	}
	static rpad(str,targetLength,padStr,canOverflow) {
		if(canOverflow == null) {
			canOverflow = true;
		}
		if(padStr == null) {
			padStr = " ";
		}
		let strLen = str == null ? 0 : str.length;
		if(str == null || strLen > targetLength) {
			return str;
		}
		if(padStr == null || padStr.length == 0) {
			padStr = " ";
		}
		let padLen = padStr == null ? 0 : padStr.length;
		let sb = new hx_strings_StringBuilder(str);
		while(strLen < targetLength) {
			sb.add(padStr);
			strLen += padLen;
		}
		if(canOverflow) {
			return sb.toString();
		}
		let str1 = sb.toString();
		return (str1 == null ? 0 : str1.length) <= targetLength ? str1 : hx_strings_Strings.substring8(str1,0,targetLength);
	}
	static split8(str,separator,maxParts) {
		if(maxParts == null) {
			maxParts = 0;
		}
		if(str == null || separator == null) {
			return null;
		}
		let strLen = str == null ? 0 : str.length;
		if(strLen == 0) {
			return [];
		}
		let _g = [];
		let _g1 = 0;
		let _g2 = separator;
		while(_g1 < _g2.length) {
			let v = _g2[_g1];
			++_g1;
			if(v != null) {
				_g.push(v);
			}
		}
		let separators = _g;
		if(separators.length == 0) {
			return null;
		}
		if(maxParts <= 0 && separators.length == 1) {
			return str.split(separators[0]);
		}
		if(separators.indexOf("") > -1) {
			if(maxParts <= 0) {
				let _g = [];
				let _g1 = 0;
				let _g2 = strLen;
				while(_g1 < _g2) {
					let i = _g1++;
					_g.push(HxOverrides.substr(str,i,1));
				}
				return _g;
			}
			if(maxParts > strLen) {
				maxParts = strLen;
			}
			--maxParts;
			let _g = [];
			let _g1 = 0;
			let _g2 = maxParts;
			while(_g1 < _g2) {
				let i = _g1++;
				_g.push(HxOverrides.substr(str,i,1));
			}
			let result = _g;
			result.push(HxOverrides.substr(str,maxParts,strLen - maxParts));
			return result;
		}
		let _g3 = [];
		let _g4 = 0;
		while(_g4 < separators.length) {
			let sep = separators[_g4];
			++_g4;
			_g3.push(sep == null ? 0 : sep.length);
		}
		let separatorsLengths = _g3;
		let lastFoundAt = 0;
		let result = [];
		let resultCount = 0;
		while(true) {
			let separatorLen = 0;
			let foundAt = -1;
			let _g = 0;
			let _g1 = separators.length;
			while(_g < _g1) {
				let i = _g++;
				let sepFoundAt = hx_strings_Strings.indexOf8(str,separators[i],lastFoundAt);
				if(sepFoundAt != -1) {
					if(foundAt == -1 || sepFoundAt < foundAt) {
						foundAt = sepFoundAt;
						separatorLen = separatorsLengths[i];
					}
				}
			}
			++resultCount;
			if(foundAt == -1 || resultCount == maxParts) {
				result.push(HxOverrides.substr(str,lastFoundAt,strLen - lastFoundAt));
				break;
			}
			result.push(HxOverrides.substr(str,lastFoundAt,foundAt - lastFoundAt));
			lastFoundAt = foundAt + separatorLen;
		}
		return result;
	}
	static splitAt(str,splitPos) {
		if(str == null) {
			return null;
		}
		if(splitPos == null || splitPos.length == 0) {
			return [str];
		}
		let strLen = str == null ? 0 : str.length;
		if(strLen == 0) {
			return [str];
		}
		let pos = [];
		let _g = 0;
		let _g1 = splitPos;
		while(_g < _g1.length) {
			let p = _g1[_g];
			++_g;
			if(p < 0) {
				p = strLen + p;
			}
			if(p < 0 || p >= strLen) {
				continue;
			}
			if(pos.indexOf(p) > -1) {
				continue;
			}
			pos.push(p);
		}
		pos.sort(function(a,b) {
			if(a < b) {
				return -1;
			} else if(a > b) {
				return 1;
			} else {
				return 0;
			}
		});
		let result = [];
		let lastPos = 0;
		let _g2 = 0;
		while(_g2 < pos.length) {
			let p = pos[_g2];
			++_g2;
			let chunk = hx_strings_Strings.substring8(str,lastPos,p);
			if(chunk != null && chunk.length > 0) {
				result.push(chunk);
			}
			lastPos = p;
		}
		let chunk = hx_strings_Strings.substring8(str,lastPos);
		if(chunk != null && chunk.length > 0) {
			result.push(chunk);
		}
		return result;
	}
	static splitEvery(str,count) {
		if(str == null) {
			return null;
		}
		if(count < 1) {
			throw haxe_Exception.thrown("[count] must be greater than 0");
		}
		let strLen = str == null ? 0 : str.length;
		if(strLen == 0 || count >= strLen) {
			return [str];
		}
		let result = [];
		let pos = 0;
		while(true) {
			let chunk = hx_strings_Strings.substr8(str,pos,count);
			pos += count;
			if(chunk == null || chunk.length == 0) {
				break;
			}
			result.push(chunk);
		}
		return result;
	}
	static splitLines(str) {
		if(str == null || str.length == 0) {
			return [];
		} else {
			return hx_strings_Strings.REGEX_SPLIT_LINES.ereg.split(str);
		}
	}
	static startsWith(searchIn,searchFor) {
		if(searchIn == null || searchFor == null) {
			return false;
		}
		if(searchFor == null || searchFor.length == 0 || searchIn == searchFor) {
			return true;
		}
		return searchIn.startsWith(searchFor);
	}
	static startsWithAny(searchIn,searchFor) {
		if(searchIn == null || searchFor == null) {
			return false;
		}
		let _g = 0;
		while(_g < searchFor.length) {
			let candidate = searchFor[_g];
			++_g;
			if(candidate != null && hx_strings_Strings.startsWith(searchIn,candidate)) {
				return true;
			}
		}
		return false;
	}
	static startsWithAnyIgnoreCase(searchIn,searchFor) {
		if(searchIn == null || searchFor == null) {
			return false;
		}
		searchIn = hx_strings_Strings.toLowerCase8(searchIn);
		let _g = 0;
		while(_g < searchFor.length) {
			let candidate = searchFor[_g];
			++_g;
			if(candidate != null && hx_strings_Strings.startsWith(searchIn,hx_strings_Strings.toLowerCase8(candidate))) {
				return true;
			}
		}
		return false;
	}
	static startsWithIgnoreCase(searchIn,searchFor) {
		if(searchIn == null || searchFor == null) {
			return false;
		}
		if(searchFor == null || searchFor.length == 0) {
			return true;
		}
		return hx_strings_Strings.startsWith(searchIn.toLowerCase(),searchFor.toLowerCase());
	}
	static substr8(str,startAt,len) {
		if(str == null || str.length == 0) {
			return str;
		}
		if(len == null) {
			len = str == null ? 0 : str.length;
		}
		if(len <= 0) {
			return "";
		}
		if(startAt < 0) {
			startAt += str == null ? 0 : str.length;
			if(startAt < 0) {
				startAt = 0;
			}
		}
		return HxOverrides.substr(str,startAt,len);
	}
	static substring8(str,startAt,endAt) {
		if(str == null || str.length == 0) {
			return str;
		}
		if(endAt == null) {
			endAt = str == null ? 0 : str.length;
		}
		return str.substring(startAt,endAt);
	}
	static substringAfter(str,searchFor,notFoundDefault) {
		if(notFoundDefault == null) {
			notFoundDefault = 2;
		}
		if(str == null) {
			return str;
		}
		if(str == "" || searchFor == null || searchFor == "") {
			let tmp;
			switch(notFoundDefault) {
			case 1:
				tmp = null;
				break;
			case 2:
				tmp = "";
				break;
			case 3:
				tmp = str;
				break;
			}
			return tmp;
		}
		let foundAt = str.indexOf(searchFor);
		if(foundAt == -1) {
			let tmp;
			switch(notFoundDefault) {
			case 1:
				tmp = null;
				break;
			case 2:
				tmp = "";
				break;
			case 3:
				tmp = str;
				break;
			}
			return tmp;
		}
		return str.substring(foundAt + searchFor.length);
	}
	static substringAfterIgnoreCase(str,searchFor,notFoundDefault) {
		if(notFoundDefault == null) {
			notFoundDefault = 2;
		}
		if(str == null) {
			return null;
		}
		if(str == "" || (searchFor == null || searchFor.length == 0)) {
			let tmp;
			switch(notFoundDefault) {
			case 1:
				tmp = null;
				break;
			case 2:
				tmp = "";
				break;
			case 3:
				tmp = str;
				break;
			}
			return tmp;
		}
		searchFor = searchFor.toLowerCase();
		let foundAt = str.toLowerCase().indexOf(searchFor);
		if(foundAt == -1) {
			let tmp;
			switch(notFoundDefault) {
			case 1:
				tmp = null;
				break;
			case 2:
				tmp = "";
				break;
			case 3:
				tmp = str;
				break;
			}
			return tmp;
		}
		return str.substring(foundAt + searchFor.length);
	}
	static substringBetween(str,after,before,notFoundDefault) {
		if(notFoundDefault == null) {
			notFoundDefault = 2;
		}
		if(str == null) {
			return null;
		}
		if(before == null) {
			before = after;
		}
		if(str == "" || (after == null || after.length == 0) || (before == null || before.length == 0)) {
			let tmp;
			switch(notFoundDefault) {
			case 1:
				tmp = null;
				break;
			case 2:
				tmp = "";
				break;
			case 3:
				tmp = str;
				break;
			}
			return tmp;
		}
		let foundAfterAt = str.indexOf(after);
		if(foundAfterAt == -1) {
			let tmp;
			switch(notFoundDefault) {
			case 1:
				tmp = null;
				break;
			case 2:
				tmp = "";
				break;
			case 3:
				tmp = str;
				break;
			}
			return tmp;
		}
		let foundBeforeAt = str.indexOf(before,foundAfterAt + after.length);
		if(foundBeforeAt == -1) {
			let tmp;
			switch(notFoundDefault) {
			case 1:
				tmp = null;
				break;
			case 2:
				tmp = "";
				break;
			case 3:
				tmp = str;
				break;
			}
			return tmp;
		}
		return str.substring(foundAfterAt + after.length,foundBeforeAt);
	}
	static substringBetweenIgnoreCase(str,after,before,notFoundDefault) {
		if(notFoundDefault == null) {
			notFoundDefault = 2;
		}
		if(str == null) {
			return null;
		}
		if(before == null) {
			before = after;
		}
		if(str == "" || (after == null || after.length == 0) || (before == null || before.length == 0)) {
			let tmp;
			switch(notFoundDefault) {
			case 1:
				tmp = null;
				break;
			case 2:
				tmp = "";
				break;
			case 3:
				tmp = str;
				break;
			}
			return tmp;
		}
		let strLower = hx_strings_Strings.toLowerCase8(str);
		let after1 = hx_strings_Strings.toLowerCase8(after);
		let before1 = hx_strings_Strings.toLowerCase8(before);
		let foundAfterAt = strLower.indexOf(after1);
		if(foundAfterAt == -1) {
			let tmp;
			switch(notFoundDefault) {
			case 1:
				tmp = null;
				break;
			case 2:
				tmp = "";
				break;
			case 3:
				tmp = str;
				break;
			}
			return tmp;
		}
		let foundBeforeAt = strLower.indexOf(before1,foundAfterAt + after1.length);
		if(foundBeforeAt == -1) {
			let tmp;
			switch(notFoundDefault) {
			case 1:
				tmp = null;
				break;
			case 2:
				tmp = "";
				break;
			case 3:
				tmp = str;
				break;
			}
			return tmp;
		}
		return str.substring(foundAfterAt + after1.length,foundBeforeAt);
	}
	static substringAfterLast(str,searchFor,notFoundDefault) {
		if(notFoundDefault == null) {
			notFoundDefault = 2;
		}
		if(str == null) {
			return null;
		}
		if(str == "" || (searchFor == null || searchFor.length == 0)) {
			let tmp;
			switch(notFoundDefault) {
			case 1:
				tmp = null;
				break;
			case 2:
				tmp = "";
				break;
			case 3:
				tmp = str;
				break;
			}
			return tmp;
		}
		let foundAt = str.lastIndexOf(searchFor);
		if(foundAt == -1) {
			let tmp;
			switch(notFoundDefault) {
			case 1:
				tmp = null;
				break;
			case 2:
				tmp = "";
				break;
			case 3:
				tmp = str;
				break;
			}
			return tmp;
		}
		return str.substring(foundAt + searchFor.length);
	}
	static substringAfterLastIgnoreCase(str,searchFor,notFoundDefault) {
		if(notFoundDefault == null) {
			notFoundDefault = 2;
		}
		if(str == null) {
			return null;
		}
		if(str == "" || (searchFor == null || searchFor.length == 0)) {
			let tmp;
			switch(notFoundDefault) {
			case 1:
				tmp = null;
				break;
			case 2:
				tmp = "";
				break;
			case 3:
				tmp = str;
				break;
			}
			return tmp;
		}
		searchFor = searchFor.toLowerCase();
		let foundAt = str.toLowerCase().lastIndexOf(searchFor);
		if(foundAt == -1) {
			let tmp;
			switch(notFoundDefault) {
			case 1:
				tmp = null;
				break;
			case 2:
				tmp = "";
				break;
			case 3:
				tmp = str;
				break;
			}
			return tmp;
		}
		return str.substring(foundAt + searchFor.length);
	}
	static substringBefore(str,searchFor,notFoundDefault) {
		if(notFoundDefault == null) {
			notFoundDefault = 2;
		}
		if(str == null) {
			return null;
		}
		if(str == "" || (searchFor == null || searchFor.length == 0)) {
			let tmp;
			switch(notFoundDefault) {
			case 1:
				tmp = null;
				break;
			case 2:
				tmp = "";
				break;
			case 3:
				tmp = str;
				break;
			}
			return tmp;
		}
		let foundAt = str.indexOf(searchFor);
		if(foundAt == -1) {
			let tmp;
			switch(notFoundDefault) {
			case 1:
				tmp = null;
				break;
			case 2:
				tmp = "";
				break;
			case 3:
				tmp = str;
				break;
			}
			return tmp;
		}
		return str.substring(0,foundAt);
	}
	static substringBeforeIgnoreCase(str,searchFor,notFoundDefault) {
		if(notFoundDefault == null) {
			notFoundDefault = 2;
		}
		if(str == null) {
			return null;
		}
		if(str == "" || (searchFor == null || searchFor.length == 0)) {
			let tmp;
			switch(notFoundDefault) {
			case 1:
				tmp = null;
				break;
			case 2:
				tmp = "";
				break;
			case 3:
				tmp = str;
				break;
			}
			return tmp;
		}
		searchFor = searchFor.toLowerCase();
		let foundAt = str.toLowerCase().indexOf(searchFor);
		if(foundAt == -1) {
			let tmp;
			switch(notFoundDefault) {
			case 1:
				tmp = null;
				break;
			case 2:
				tmp = "";
				break;
			case 3:
				tmp = str;
				break;
			}
			return tmp;
		}
		return str.substring(0,foundAt);
	}
	static substringBeforeLast(str,searchFor,notFoundDefault) {
		if(notFoundDefault == null) {
			notFoundDefault = 2;
		}
		if(str == null) {
			return null;
		}
		if(str == "" || (searchFor == null || searchFor.length == 0)) {
			let tmp;
			switch(notFoundDefault) {
			case 1:
				tmp = null;
				break;
			case 2:
				tmp = "";
				break;
			case 3:
				tmp = str;
				break;
			}
			return tmp;
		}
		let foundAt = str.lastIndexOf(searchFor);
		if(foundAt == -1) {
			let tmp;
			switch(notFoundDefault) {
			case 1:
				tmp = null;
				break;
			case 2:
				tmp = "";
				break;
			case 3:
				tmp = str;
				break;
			}
			return tmp;
		}
		return str.substring(0,foundAt);
	}
	static substringBeforeLastIgnoreCase(str,searchFor,notFoundDefault) {
		if(notFoundDefault == null) {
			notFoundDefault = 2;
		}
		if(str == null) {
			return null;
		}
		if(str == "" || (searchFor == null || searchFor.length == 0)) {
			let tmp;
			switch(notFoundDefault) {
			case 1:
				tmp = null;
				break;
			case 2:
				tmp = "";
				break;
			case 3:
				tmp = str;
				break;
			}
			return tmp;
		}
		searchFor = searchFor.toLowerCase();
		let foundAt = str.toLowerCase().lastIndexOf(searchFor);
		if(foundAt == -1) {
			let tmp;
			switch(notFoundDefault) {
			case 1:
				tmp = null;
				break;
			case 2:
				tmp = "";
				break;
			case 3:
				tmp = str;
				break;
			}
			return tmp;
		}
		return str.substring(0,foundAt);
	}
	static toBool(str) {
		if(str == null || str.length == 0) {
			return false;
		}
		switch(str.toLowerCase()) {
		case "0":case "false":case "no":
			return false;
		default:
			return true;
		}
	}
	static toBytes(str) {
		if(str == null) {
			return null;
		}
		return haxe_io_Bytes.ofString(str);
	}
	static toChar(charCode) {
		return charCode;
	}
	static toCharIterator(str) {
		if(str == null) {
			return hx_strings__$CharIterator_NullCharIterator.INSTANCE;
		} else {
			return new hx_strings__$CharIterator_StringCharIterator(str,0);
		}
	}
	static toChars(str) {
		if(str == null) {
			return null;
		}
		let strLen = str == null ? 0 : str.length;
		if(strLen == 0) {
			return [];
		}
		let _g = [];
		let _g1 = 0;
		let _g2 = strLen;
		while(_g1 < _g2) {
			let i = _g1++;
			_g.push(HxOverrides.cca(str,i));
		}
		return _g;
	}
	static toPattern(str,options) {
		if(str == null) {
			return null;
		}
		return hx_strings_Pattern.compile(str,options);
	}
	static toEReg(str,opt) {
		if(opt == null) {
			opt = "";
		}
		if(str == null) {
			throw haxe_Exception.thrown("[str] must not be null");
		}
		return new EReg(str,opt);
	}
	static toFloat(str,ifUnparseable) {
		if(str == null) {
			return ifUnparseable;
		}
		let result = parseFloat(str);
		if(isNaN(result)) {
			return ifUnparseable;
		} else {
			return result;
		}
	}
	static toFloatOrNull(str,ifUnparseable) {
		if(str == null) {
			return ifUnparseable;
		}
		let result = parseFloat(str);
		if(isNaN(result)) {
			return ifUnparseable;
		} else {
			return result;
		}
	}
	static toHex(num,minDigits,upperCase) {
		if(upperCase == null) {
			upperCase = true;
		}
		if(minDigits == null) {
			minDigits = 0;
		}
		let hexed = StringTools.hex(num,0);
		if(!upperCase) {
			return hexed.toLowerCase();
		}
		if(hexed.length >= minDigits) {
			return hexed;
		}
		return hx_strings_Strings.lpad(hexed,minDigits,"0");
	}
	static toInt(str,ifUnparseable) {
		if(str == null) {
			return ifUnparseable;
		}
		let result = Std.parseInt(str);
		if(result == null) {
			return ifUnparseable;
		} else {
			return result;
		}
	}
	static toIntOrNull(str,ifUnparseable) {
		if(str == null) {
			return ifUnparseable;
		}
		let result = Std.parseInt(str);
		if(result == null) {
			return ifUnparseable;
		} else {
			return result;
		}
	}
	static toLowerCase8(str) {
		if(str == null || str.length == 0) {
			return str;
		}
		return str.toLowerCase();
	}
	static toLowerCaseFirstChar(str) {
		if(str == null || str.length == 0) {
			return str;
		}
		let this1 = HxOverrides.cca(str,0);
		let lowerChar = hx_strings_Char.CHAR_CASE_MAPPER.mapU2L.h[this1];
		let firstChar = lowerChar == null ? this1 : lowerChar;
		if(str.length == 1) {
			return String.fromCodePoint(firstChar);
		}
		let other = hx_strings_Strings.substr8(str,1);
		return String.fromCodePoint(firstChar) + other;
	}
	static toLowerCamel(str,keepUppercasedWords) {
		if(keepUppercasedWords == null) {
			keepUppercasedWords = true;
		}
		if(str == null || str.length == 0) {
			return str;
		}
		let sb = new hx_strings_StringBuilder();
		if(keepUppercasedWords) {
			let _g = 0;
			let _g1 = hx_strings_Strings._splitAsciiWordsUnsafe(str);
			while(_g < _g1.length) {
				let word = _g1[_g];
				++_g;
				sb.add(hx_strings_Strings.toUpperCaseFirstChar(word));
			}
		} else {
			let _g = 0;
			let _g1 = hx_strings_Strings._splitAsciiWordsUnsafe(str);
			while(_g < _g1.length) {
				let word = _g1[_g];
				++_g;
				sb.add(hx_strings_Strings.toUpperCaseFirstChar(hx_strings_Strings.toLowerCase8(word)));
			}
		}
		return hx_strings_Strings.toLowerCaseFirstChar(sb.toString());
	}
	static toLowerHyphen(str) {
		if(str == null || str.length == 0) {
			return str;
		}
		let _this = hx_strings_Strings._splitAsciiWordsUnsafe(str);
		let result = new Array(_this.length);
		let _g = 0;
		let _g1 = _this.length;
		while(_g < _g1) {
			let i = _g++;
			result[i] = hx_strings_Strings.toLowerCase8(_this[i]);
		}
		return result.join("-");
	}
	static toLowerUnderscore(str) {
		if(str == null || str.length == 0) {
			return str;
		}
		let _this = hx_strings_Strings._splitAsciiWordsUnsafe(str);
		let result = new Array(_this.length);
		let _g = 0;
		let _g1 = _this.length;
		while(_g < _g1) {
			let i = _g++;
			result[i] = hx_strings_Strings.toLowerCase8(_this[i]);
		}
		return result.join("_");
	}
	static toTitle(str,keepUppercasedWords) {
		if(keepUppercasedWords == null) {
			keepUppercasedWords = true;
		}
		if(str == null || str.length == 0) {
			return str;
		}
		if(keepUppercasedWords) {
			let _this = hx_strings_Strings._splitAsciiWordsUnsafe(str);
			let result = new Array(_this.length);
			let _g = 0;
			let _g1 = _this.length;
			while(_g < _g1) {
				let i = _g++;
				let s = _this[i];
				result[i] = hx_strings_Strings.toUpperCase8(s) == s ? s : hx_strings_Strings.toUpperCaseFirstChar(hx_strings_Strings.toLowerCase8(s));
			}
			return result.join(" ");
		}
		let _this = hx_strings_Strings._splitAsciiWordsUnsafe(str);
		let result = new Array(_this.length);
		let _g = 0;
		let _g1 = _this.length;
		while(_g < _g1) {
			let i = _g++;
			result[i] = hx_strings_Strings.toUpperCaseFirstChar(hx_strings_Strings.toLowerCase8(_this[i]));
		}
		return result.join(" ");
	}
	static toUpperCamel(str,keepUppercasedWords) {
		if(keepUppercasedWords == null) {
			keepUppercasedWords = true;
		}
		if(str == null || str.length == 0) {
			return str;
		}
		let sb = new hx_strings_StringBuilder();
		if(keepUppercasedWords) {
			let _g = 0;
			let _g1 = hx_strings_Strings._splitAsciiWordsUnsafe(str);
			while(_g < _g1.length) {
				let word = _g1[_g];
				++_g;
				sb.add(hx_strings_Strings.toUpperCaseFirstChar(word));
			}
		} else {
			let _g = 0;
			let _g1 = hx_strings_Strings._splitAsciiWordsUnsafe(str);
			while(_g < _g1.length) {
				let word = _g1[_g];
				++_g;
				sb.add(hx_strings_Strings.toUpperCaseFirstChar(hx_strings_Strings.toLowerCase8(word)));
			}
		}
		return sb.toString();
	}
	static toUpperUnderscore(str) {
		if(str == null || str.length == 0) {
			return str;
		}
		let _this = hx_strings_Strings._splitAsciiWordsUnsafe(str);
		let result = new Array(_this.length);
		let _g = 0;
		let _g1 = _this.length;
		while(_g < _g1) {
			let i = _g++;
			result[i] = hx_strings_Strings.toUpperCase8(_this[i]);
		}
		return result.join("_");
	}
	static toString(str) {
		if(str == null) {
			return "null";
		} else {
			return str;
		}
	}
	static toUpperCase8(str) {
		if(str == null || str.length == 0) {
			return str;
		}
		let sb = new hx_strings_StringBuilder();
		let _g = 0;
		let _g1 = str == null ? 0 : str.length;
		while(_g < _g1) {
			let i = _g++;
			let this1 = HxOverrides.cca(str,i);
			let upperChar = hx_strings_Char.CHAR_CASE_MAPPER.mapL2U.h[this1];
			sb.addChar(upperChar == null ? this1 : upperChar);
		}
		return sb.toString();
	}
	static toUpperCaseFirstChar(str) {
		if(str == null || str.length == 0) {
			return str;
		}
		let this1 = HxOverrides.cca(str,0);
		let upperChar = hx_strings_Char.CHAR_CASE_MAPPER.mapL2U.h[this1];
		let firstChar = upperChar == null ? this1 : upperChar;
		if(str.length == 1) {
			return String.fromCodePoint(firstChar);
		}
		let other = hx_strings_Strings.substr8(str,1);
		return String.fromCodePoint(firstChar) + other;
	}
	static trim(str,charsToRemove) {
		if(str == null || str.length == 0) {
			return str;
		}
		if(charsToRemove == null) {
			return StringTools.trim(str);
		}
		let removableChars;
		let _g = charsToRemove;
		switch(_g._hx_index) {
		case 0:
			let str1 = _g.v;
			removableChars = hx_strings_Strings.toChars(str1);
			break;
		case 1:
			let chars = _g.v;
			removableChars = chars;
			break;
		}
		return hx_strings_Strings.trimLeft(hx_strings_Strings.trimRight(str,hx_strings_internal__$Either2__$Either2.b(removableChars)),hx_strings_internal__$Either2__$Either2.b(removableChars));
	}
	static trimRight(str,charsToRemove) {
		if(str == null || str.length == 0) {
			return str;
		}
		if(charsToRemove == null) {
			return StringTools.rtrim(str);
		}
		let removableChars;
		let _g = charsToRemove;
		switch(_g._hx_index) {
		case 0:
			let str1 = _g.v;
			removableChars = hx_strings_Strings.toChars(str1);
			break;
		case 1:
			let chars = _g.v;
			removableChars = chars;
			break;
		}
		if(removableChars.length == 0) {
			return str;
		}
		let len = str == null ? 0 : str.length;
		let i = len - 1;
		while(i > -1 && removableChars.indexOf(hx_strings_Strings.charCodeAt8(hx_strings_Strings.charAt8(str,i),0)) > -1) --i;
		if(i < len - 1) {
			return hx_strings_Strings.substring8(str,0,i + 1);
		}
		return str;
	}
	static trimLeft(str,charsToRemove) {
		if(str == null) {
			return str;
		}
		if(charsToRemove == null) {
			return StringTools.ltrim(str);
		}
		let removableChars;
		let _g = charsToRemove;
		switch(_g._hx_index) {
		case 0:
			let str1 = _g.v;
			removableChars = hx_strings_Strings.toChars(str1);
			break;
		case 1:
			let chars = _g.v;
			removableChars = chars;
			break;
		}
		if(removableChars.length == 0) {
			return str;
		}
		let len = str == null ? 0 : str.length;
		let i = 0;
		while(i < len && removableChars.indexOf(hx_strings_Strings.charCodeAt8(hx_strings_Strings.charAt8(str,i),0)) > -1) ++i;
		if(i > 0) {
			return hx_strings_Strings.substring8(str,i,len);
		}
		return str;
	}
	static trimLines(str,charsToRemove) {
		if(str == null || str.length == 0) {
			return str;
		}
		let _this = hx_strings_Strings.REGEX_SPLIT_LINES.ereg.split(str);
		let result = new Array(_this.length);
		let _g = 0;
		let _g1 = _this.length;
		while(_g < _g1) {
			let i = _g++;
			result[i] = hx_strings_Strings.trim(_this[i],charsToRemove);
		}
		return result.join("\n");
	}
	static trimToNull(str) {
		if(str == null) {
			return null;
		}
		let trimmed = hx_strings_Strings.trim(str);
		if(trimmed == null || trimmed.length == 0) {
			return null;
		}
		return trimmed;
	}
	static trimToEmpty(str) {
		let trimmed = hx_strings_Strings.trim(str);
		if(trimmed == null || trimmed.length == 0) {
			return "";
		}
		return trimmed;
	}
	static truncate(str,maxLength) {
		if((str == null ? 0 : str.length) <= maxLength) {
			return str;
		} else {
			return hx_strings_Strings.substring8(str,0,maxLength);
		}
	}
	static urlDecode(str) {
		if(str == null || str.length == 0) {
			return str;
		}
		return decodeURIComponent(str.split("+").join(" "));
	}
	static urlEncode(str) {
		if(str == null || str.length == 0) {
			return str;
		}
		return encodeURIComponent(str);
	}
	static wrap(str,maxLineLength,splitLongWords,newLineSeparator) {
		if(newLineSeparator == null) {
			newLineSeparator = "\n";
		}
		if(splitLongWords == null) {
			splitLongWords = true;
		}
		if((str == null ? 0 : str.length) <= maxLineLength || maxLineLength < 1) {
			return str;
		}
		let sb = new hx_strings_StringBuilder();
		let wordChars = [];
		let currLineLength = 0;
		let _g = 0;
		let _g1 = hx_strings_Strings.toChars(str);
		while(_g < _g1.length) {
			let ch = _g1[_g];
			++_g;
			if(ch > 8 && ch < 14 || ch == 32) {
				if(wordChars.length > 0) {
					let _g = 0;
					while(_g < wordChars.length) {
						let wordCh = wordChars[_g];
						++_g;
						if(currLineLength == maxLineLength && splitLongWords) {
							sb.add(newLineSeparator);
							currLineLength = 0;
						}
						++currLineLength;
						sb.addChar(wordCh);
					}
					wordChars = [];
				}
				if(currLineLength >= maxLineLength) {
					sb.add(newLineSeparator);
					currLineLength = 0;
				}
				sb.addChar(ch);
				++currLineLength;
			} else {
				wordChars.push(ch);
			}
		}
		if(wordChars.length > 0) {
			let _g = 0;
			while(_g < wordChars.length) {
				let wordCh = wordChars[_g];
				++_g;
				if(currLineLength == maxLineLength && splitLongWords) {
					sb.add(newLineSeparator);
					currLineLength = 0;
				}
				++currLineLength;
				sb.addChar(wordCh);
			}
		}
		return sb.toString();
	}
}
hx_strings_Strings.__name__ = "hx.strings.Strings";
class hx_strings_RandomStrings {
	static _genAsciiAlpha() {
		let chars = [];
		chars.push(65);
		chars.push(66);
		chars.push(67);
		chars.push(68);
		chars.push(69);
		chars.push(70);
		chars.push(71);
		chars.push(72);
		chars.push(73);
		chars.push(74);
		chars.push(75);
		chars.push(76);
		chars.push(77);
		chars.push(78);
		chars.push(79);
		chars.push(80);
		chars.push(81);
		chars.push(82);
		chars.push(83);
		chars.push(84);
		chars.push(85);
		chars.push(86);
		chars.push(87);
		chars.push(88);
		chars.push(89);
		chars.push(90);
		chars.push(97);
		chars.push(98);
		chars.push(99);
		chars.push(100);
		chars.push(101);
		chars.push(102);
		chars.push(103);
		chars.push(104);
		chars.push(105);
		chars.push(106);
		chars.push(107);
		chars.push(108);
		chars.push(109);
		chars.push(110);
		chars.push(111);
		chars.push(112);
		chars.push(113);
		chars.push(114);
		chars.push(115);
		chars.push(116);
		chars.push(117);
		chars.push(118);
		chars.push(119);
		chars.push(120);
		chars.push(121);
		chars.push(122);
		return chars;
	}
	static randomAsciiAlpha(length) {
		return hx_strings_RandomStrings.random(length,hx_strings_internal__$Either2__$Either2.b(hx_strings_RandomStrings.ASCII_ALPHA));
	}
	static randomAsciiAlphaNumeric(length) {
		return hx_strings_RandomStrings.random(length,hx_strings_internal__$Either2__$Either2.b(hx_strings_RandomStrings.ASCII_ALPHA_NUMERIC));
	}
	static randomDigits(length) {
		return hx_strings_RandomStrings.random(length,hx_strings_internal__$Either2__$Either2.b(hx_strings_RandomStrings.DIGITS));
	}
	static random(length,chars) {
		if(length == 0) {
			return "";
		}
		if(length < 0) {
			throw haxe_Exception.thrown("[count] must be positive value");
		}
		if(chars == null) {
			throw haxe_Exception.thrown("[chars] must not be null");
		}
		let charsArray;
		let _g = chars;
		switch(_g._hx_index) {
		case 0:
			let str = _g.v;
			charsArray = hx_strings_Strings.toChars(str);
			break;
		case 1:
			let chars1 = _g.v;
			charsArray = chars1;
			break;
		}
		if(charsArray.length == 0) {
			throw haxe_Exception.thrown("[chars] must not be empty");
		}
		let result = new hx_strings_StringBuilder();
		let _g1 = 0;
		let _g2 = length;
		while(_g1 < _g2) {
			let i = _g1++;
			result.addChar(charsArray[Math.floor(charsArray.length * Math.random())]);
		}
		return result.toString();
	}
	static randomSubstring(str,substringLength) {
		if(substringLength == null) {
			substringLength = 1;
		}
		if(str == null || str.length == 0) {
			throw haxe_Exception.thrown("[str] must not be null or empty");
		}
		if(substringLength < 1) {
			throw haxe_Exception.thrown("[substringLength] must not be smaller than 1");
		}
		let len = str == null ? 0 : str.length;
		if(substringLength > len) {
			throw haxe_Exception.thrown("[substringLength] must not be larger than str.length");
		}
		if(substringLength == len) {
			return str;
		}
		let startAt = Math.floor((len - substringLength + 1) * Math.random());
		return hx_strings_Strings.substr8(str,startAt,substringLength);
	}
	static randomUUIDv4(separator) {
		if(separator == null) {
			separator = "-";
		}
		if(separator == null) {
			throw haxe_Exception.thrown("[separator] must not be null");
		}
		let variantByte = Math.floor(Math.random() * 16);
		variantByte |= 8;
		variantByte &= -5;
		return (StringTools.hex(Math.floor(Math.random() * 65536),4) + StringTools.hex(Math.floor(Math.random() * 65536),4) + separator + StringTools.hex(Math.floor(Math.random() * 65536),4) + separator + "4" + StringTools.hex(Math.floor(Math.random() * 4096),3) + separator + StringTools.hex(variantByte) + StringTools.hex(Math.floor(Math.random() * 4096),3) + separator + StringTools.hex(Math.floor(Math.random() * 65536),4) + StringTools.hex(Math.floor(Math.random() * 65536),4) + StringTools.hex(Math.floor(Math.random() * 65536),4)).toLowerCase();
	}
}
hx_strings_RandomStrings.__name__ = "hx.strings.RandomStrings";
class hx_strings_StringBuilder {
	constructor(initialContent) {
		this.len = 0;
		this.pre = null;
		this.sb = new StringBuf();
		if(initialContent != null) {
			this.add(initialContent);
		}
	}
	get_length() {
		return this.len;
	}
	add(item) {
		this.sb.b += Std.string(item == null ? "null" : item);
		this.len += item == null ? 0 : item.length;
		return this;
	}
	addChar(ch) {
		if(ch > -1 && ch < 128) {
			this.sb.b += String.fromCodePoint(ch);
		} else {
			let _this = this.sb;
			let x = String.fromCodePoint(ch);
			_this.b += Std.string(x);
		}
		this.len++;
		return this;
	}
	addAll(items) {
		let _g = 0;
		while(_g < items.length) {
			let item = items[_g];
			++_g;
			this.sb.b += Std.string(item);
			this.len += item == null ? 0 : item.length;
		}
		return this;
	}
	clear() {
		this.pre = null;
		this.sb = new StringBuf();
		this.len = 0;
		return this;
	}
	isEmpty() {
		return this.len == 0;
	}
	newLine() {
		this.sb.b += "\n";
		this.len++;
		return this;
	}
	insert(pos,item) {
		if(pos < 0) {
			throw haxe_Exception.thrown("[pos] must not be negative");
		}
		if(pos > this.len) {
			throw haxe_Exception.thrown("[pos] must not be greater than this.length");
		}
		if(pos == this.len) {
			this.add(item);
			return this;
		}
		if(pos == 0) {
			if(this.pre == null) {
				this.pre = [];
			}
			this.pre.unshift(item);
			this.len += item == null ? 0 : item.length;
			return this;
		}
		let pre_len = 0;
		if(this.pre != null) {
			let pre = this.pre;
			let i = pre.length;
			let _g = 0;
			let _g1 = pre.length;
			while(_g < _g1) {
				let i = _g++;
				let str = pre[i];
				let next_pre_len = pre_len + (str == null ? 0 : str.length);
				if(next_pre_len == pos) {
					pre.splice(i + 1,0,item);
					this.len += item == null ? 0 : item.length;
					return this;
				}
				if(next_pre_len > pos) {
					let preSplitted = hx_strings_Strings.splitAt(pre[i],[pos - pre_len]);
					pre[i] = preSplitted[0];
					pre.splice(i + 1,0,item);
					pre.splice(i + 2,0,preSplitted[1]);
					this.len += item == null ? 0 : item.length;
					return this;
				}
				pre_len = next_pre_len;
			}
		}
		if(this.sb.b.length == 0) {
			this.add(item);
			return this;
		}
		let sbSplitted = hx_strings_Strings.splitAt(this.sb.b,[pos - pre_len]);
		this.sb = new StringBuf();
		this.sb.b += Std.string(sbSplitted[0]);
		this.sb.b += Std.string(item);
		this.len += item == null ? 0 : item.length;
		this.sb.b += Std.string(sbSplitted[1]);
		return this;
	}
	insertChar(pos,ch) {
		if(pos < 0) {
			throw haxe_Exception.thrown("[pos] must not be negative");
		}
		if(pos > this.len) {
			throw haxe_Exception.thrown("[pos] must not be greater than this.length");
		}
		if(pos == this.len) {
			this.addChar(ch);
			return this;
		}
		if(pos == 0) {
			if(this.pre == null) {
				this.pre = [];
			}
			this.pre.unshift(String.fromCodePoint(ch));
			this.len++;
			return this;
		}
		let pre_len = 0;
		if(this.pre != null) {
			let pre = this.pre;
			let i = pre.length;
			let _g = 0;
			let _g1 = pre.length;
			while(_g < _g1) {
				let i = _g++;
				let str = pre[i];
				let next_pre_len = pre_len + (str == null ? 0 : str.length);
				if(next_pre_len == pos) {
					let x = String.fromCodePoint(ch);
					pre.splice(i + 1,0,x);
					this.len++;
					return this;
				}
				if(next_pre_len > pos) {
					let preSplitted = hx_strings_Strings.splitAt(pre[i],[pos - pre_len]);
					pre[i] = preSplitted[0];
					let x = String.fromCodePoint(ch);
					pre.splice(i + 1,0,x);
					pre.splice(i + 2,0,preSplitted[1]);
					this.len++;
					return this;
				}
				pre_len = next_pre_len;
			}
		}
		if(this.sb.b.length == 0) {
			this.addChar(ch);
			return this;
		}
		let sbSplitted = hx_strings_Strings.splitAt(this.sb.b,[pos - pre_len]);
		this.sb = new StringBuf();
		this.sb.b += Std.string(sbSplitted[0]);
		this.addChar(ch);
		this.sb.b += Std.string(sbSplitted[1]);
		return this;
	}
	insertAll(pos,items) {
		if(pos < 0) {
			throw haxe_Exception.thrown("[pos] must not be negative");
		}
		if(pos > this.len) {
			throw haxe_Exception.thrown("[pos] must not be greater than this.length");
		}
		if(pos == this.len) {
			this.addAll(items);
			return this;
		}
		if(pos == 0) {
			if(this.pre == null) {
				this.pre = [];
			}
			let pre = this.pre;
			let i = items.length;
			while(i-- > 0) {
				let item = items[i];
				pre.unshift(item);
				this.len += item == null ? 0 : item.length;
			}
			return this;
		}
		let pre_len = 0;
		if(this.pre != null) {
			let pre = this.pre;
			let i = pre.length;
			let _g = 0;
			let _g1 = pre.length;
			while(_g < _g1) {
				let i = _g++;
				let str = pre[i];
				let next_pre_len = pre_len + (str == null ? 0 : str.length);
				if(next_pre_len == pos) {
					let j = items.length;
					while(j-- > 0) {
						let item = items[j];
						pre.splice(i + 1,0,item);
						this.len += item == null ? 0 : item.length;
					}
					return this;
				}
				if(next_pre_len > pos) {
					let preSplitted = hx_strings_Strings.splitAt(pre[i],[pos - pre_len]);
					pre[i] = preSplitted[0];
					pre.splice(i + 1,0,preSplitted[1]);
					let j = items.length;
					while(j-- > 0) {
						let item = items[j];
						pre.splice(i + 1,0,item);
						this.len += item == null ? 0 : item.length;
					}
					return this;
				}
				pre_len = next_pre_len;
			}
		}
		if(this.sb.b.length == 0) {
			let _g = 0;
			while(_g < items.length) {
				let item = items[_g];
				++_g;
				this.add(item);
			}
			return this;
		}
		let sbSplitted = hx_strings_Strings.splitAt(this.sb.b,[pos - pre_len]);
		this.sb = new StringBuf();
		this.sb.b += Std.string(sbSplitted[0]);
		let _g = 0;
		while(_g < items.length) {
			let item = items[_g];
			++_g;
			this.sb.b += Std.string(item);
			this.len += item == null ? 0 : item.length;
		}
		this.sb.b += Std.string(sbSplitted[1]);
		return this;
	}
	asOutput() {
		return new hx_strings__$StringBuilder_OutputWrapper(this);
	}
	toString() {
		if(this.pre == null) {
			return this.sb.b;
		}
		let str = this.pre.join("") + this.sb.b;
		this.clear();
		this.add(str);
		return str;
	}
}
hx_strings_StringBuilder.__name__ = "hx.strings.StringBuilder";
Object.assign(hx_strings_StringBuilder.prototype, {
	__class__: hx_strings_StringBuilder
});
class hx_strings__$StringBuilder_OutputWrapper extends haxe_io_Output {
	constructor(sb) {
		super();
		this.sb = sb;
	}
	flush() {
		if(this.bo != null && this.bo.b.pos > 0) {
			this.sb.add(this.bo.getBytes().toString());
		}
	}
	writeByte(c) {
		if(this.bo == null) {
			this.bo = new haxe_io_BytesOutput();
		}
		this.bo.writeByte(c);
	}
	writeString(str,encoding) {
		this.flush();
		this.sb.add(str);
	}
}
hx_strings__$StringBuilder_OutputWrapper.__name__ = "hx.strings._StringBuilder.OutputWrapper";
hx_strings__$StringBuilder_OutputWrapper.__super__ = haxe_io_Output;
Object.assign(hx_strings__$StringBuilder_OutputWrapper.prototype, {
	__class__: hx_strings__$StringBuilder_OutputWrapper
});
class hx_strings_StringDiff {
	constructor() {
		this.at = -1;
	}
	toString() {
		return "StringDiff[at=" + this.at + ", left=" + this.left + ", right=" + this.right + "]";
	}
}
hx_strings_StringDiff.__name__ = "hx.strings.StringDiff";
Object.assign(hx_strings_StringDiff.prototype, {
	__class__: hx_strings_StringDiff
});
var hx_strings_HashCodeAlgorithm = $hxEnums["hx.strings.HashCodeAlgorithm"] = { __ename__:true,__constructs__:null
	,PLATFORM_SPECIFIC: {_hx_name:"PLATFORM_SPECIFIC",_hx_index:0,__enum__:"hx.strings.HashCodeAlgorithm",toString:$estr}
	,ADLER32: {_hx_name:"ADLER32",_hx_index:1,__enum__:"hx.strings.HashCodeAlgorithm",toString:$estr}
	,CRC32B: {_hx_name:"CRC32B",_hx_index:2,__enum__:"hx.strings.HashCodeAlgorithm",toString:$estr}
	,DJB2A: {_hx_name:"DJB2A",_hx_index:3,__enum__:"hx.strings.HashCodeAlgorithm",toString:$estr}
	,JAVA: {_hx_name:"JAVA",_hx_index:4,__enum__:"hx.strings.HashCodeAlgorithm",toString:$estr}
	,SDBM: {_hx_name:"SDBM",_hx_index:5,__enum__:"hx.strings.HashCodeAlgorithm",toString:$estr}
};
hx_strings_HashCodeAlgorithm.__constructs__ = [hx_strings_HashCodeAlgorithm.PLATFORM_SPECIFIC,hx_strings_HashCodeAlgorithm.ADLER32,hx_strings_HashCodeAlgorithm.CRC32B,hx_strings_HashCodeAlgorithm.DJB2A,hx_strings_HashCodeAlgorithm.JAVA,hx_strings_HashCodeAlgorithm.SDBM];
var hx_strings_AnsiToHtmlRenderMethod = $hxEnums["hx.strings.AnsiToHtmlRenderMethod"] = { __ename__:true,__constructs__:null
	,StyleAttributes: {_hx_name:"StyleAttributes",_hx_index:0,__enum__:"hx.strings.AnsiToHtmlRenderMethod",toString:$estr}
	,CssClasses: {_hx_name:"CssClasses",_hx_index:1,__enum__:"hx.strings.AnsiToHtmlRenderMethod",toString:$estr}
	,CssClassesCallback: ($_=function(func) { return {_hx_index:2,func:func,__enum__:"hx.strings.AnsiToHtmlRenderMethod",toString:$estr}; },$_._hx_name="CssClassesCallback",$_.__params__ = ["func"],$_)
};
hx_strings_AnsiToHtmlRenderMethod.__constructs__ = [hx_strings_AnsiToHtmlRenderMethod.StyleAttributes,hx_strings_AnsiToHtmlRenderMethod.CssClasses,hx_strings_AnsiToHtmlRenderMethod.CssClassesCallback];
class hx_strings_AnsiState {
	constructor(copyFrom) {
		this.underline = false;
		this.bold = false;
		this.blink = false;
		if(copyFrom == null) {
			this.reset();
		} else {
			this.copyFrom(copyFrom);
		}
	}
	isActive() {
		if(!(this.fgcolor != null || this.bgcolor != null || this.bold || this.underline)) {
			return this.blink;
		} else {
			return true;
		}
	}
	reset() {
		this.fgcolor = null;
		this.bgcolor = null;
		this.bold = false;
		this.underline = false;
		this.blink = false;
	}
	copyFrom(other) {
		this.fgcolor = other.fgcolor;
		this.bgcolor = other.bgcolor;
		this.bold = other.bold;
		this.underline = other.underline;
		this.blink = other.blink;
	}
	setGraphicModeParameter(param) {
		switch(param) {
		case 0:
			this.reset();
			break;
		case 1:
			this.bold = true;
			break;
		case 4:
			this.underline = true;
			break;
		case 5:
			this.blink = true;
			break;
		case 30:
			this.fgcolor = "black";
			break;
		case 31:
			this.fgcolor = "red";
			break;
		case 32:
			this.fgcolor = "green";
			break;
		case 33:
			this.fgcolor = "yellow";
			break;
		case 34:
			this.fgcolor = "blue";
			break;
		case 35:
			this.fgcolor = "magenta";
			break;
		case 36:
			this.fgcolor = "cyan";
			break;
		case 37:
			this.fgcolor = "white";
			break;
		case 40:
			this.bgcolor = "black";
			break;
		case 41:
			this.bgcolor = "red";
			break;
		case 42:
			this.bgcolor = "green";
			break;
		case 43:
			this.bgcolor = "yellow";
			break;
		case 44:
			this.bgcolor = "blue";
			break;
		case 45:
			this.bgcolor = "magenta";
			break;
		case 46:
			this.bgcolor = "cyan";
			break;
		case 47:
			this.bgcolor = "white";
			break;
		}
	}
	toCSS(renderMethod) {
		if(this.fgcolor != null || this.bgcolor != null || this.bold || this.underline || this.blink) {
			let sb = new hx_strings_StringBuilder();
			if(renderMethod == null) {
				renderMethod = hx_strings_AnsiToHtmlRenderMethod.StyleAttributes;
			}
			switch(renderMethod._hx_index) {
			case 0:
				if(this.fgcolor != null) {
					sb.add("color:").add(this.fgcolor).add(";");
				}
				if(this.bgcolor != null) {
					sb.add("background-color:").add(this.bgcolor).add(";");
				}
				if(this.bold) {
					sb.add("font-weight:bold;");
				}
				if(this.underline) {
					sb.add("text-decoration:underline;");
				}
				if(this.blink) {
					sb.add("text-decoration:blink;");
				}
				break;
			case 1:
				sb.add(hx_strings_AnsiState.defaultCssClassesCallback(this));
				break;
			case 2:
				let func = renderMethod.func;
				sb.add(func(this));
				break;
			}
			return sb.toString();
		}
		return "";
	}
	static defaultCssClassesCallback(state) {
		let classes = [];
		if(state.fgcolor != null) {
			classes.push("ansi_fg_" + state.fgcolor);
		}
		if(state.bgcolor != null) {
			classes.push("ansi_bg_" + state.bgcolor);
		}
		if(state.bold) {
			classes.push("ansi_bold");
		}
		if(state.underline) {
			classes.push("ansi_underline");
		}
		if(state.blink) {
			classes.push("ansi_blink");
		}
		return classes.join(" ");
	}
}
hx_strings_AnsiState.__name__ = "hx.strings.AnsiState";
Object.assign(hx_strings_AnsiState.prototype, {
	__class__: hx_strings_AnsiState
});
class hx_strings_internal_Bits {
	static clearBit(num,bitPos) {
		return num & ~(1 << bitPos - 1);
	}
	static setBit(num,bitPos) {
		return num | 1 << bitPos - 1;
	}
	static toggleBit(num,bitPos) {
		return num ^ 1 << bitPos - 1;
	}
	static getBit(num,bitPos) {
		return 1 == (num >> bitPos - 1 & 1);
	}
}
hx_strings_internal_Bits.__name__ = "hx.strings.internal.Bits";
class hx_strings_internal_Either2 {
	static _new(value) {
		return value;
	}
	static get_value(this1) {
		return this1;
	}
	static fromA(value) {
		return hx_strings_internal__$Either2__$Either2.a(value);
	}
	static fromB(value) {
		return hx_strings_internal__$Either2__$Either2.b(value);
	}
}
var hx_strings_internal__$Either2__$Either2 = $hxEnums["hx.strings.internal._Either2._Either2"] = { __ename__:true,__constructs__:null
	,a: ($_=function(v) { return {_hx_index:0,v:v,__enum__:"hx.strings.internal._Either2._Either2",toString:$estr}; },$_._hx_name="a",$_.__params__ = ["v"],$_)
	,b: ($_=function(v) { return {_hx_index:1,v:v,__enum__:"hx.strings.internal._Either2._Either2",toString:$estr}; },$_._hx_name="b",$_.__params__ = ["v"],$_)
};
hx_strings_internal__$Either2__$Either2.__constructs__ = [hx_strings_internal__$Either2__$Either2.a,hx_strings_internal__$Either2__$Either2.b];
class hx_strings_internal_Either3 {
	static _new(value) {
		return value;
	}
	static get_value(this1) {
		return this1;
	}
	static fromA(value) {
		return hx_strings_internal__$Either3__$Either3.a(value);
	}
	static fromB(value) {
		return hx_strings_internal__$Either3__$Either3.b(value);
	}
	static fromC(value) {
		return hx_strings_internal__$Either3__$Either3.c(value);
	}
}
class hx_strings_internal_OneOrMany {
	static fromSingle(value) {
		return [value];
	}
}
class hx_strings_internal_RingBuffer {
	static _new(size) {
		return new hx_strings_internal__$RingBuffer_RingBufferImpl(size);
	}
	static get(this1,index) {
		return this1.get(index);
	}
}
class hx_strings_internal__$RingBuffer_RingBufferIterator {
	constructor(buff) {
		this.idx = -1;
		this.buff = buff;
	}
	hasNext() {
		return this.idx + 1 < this.buff.length;
	}
	next() {
		this.idx++;
		return this.buff.get(this.idx);
	}
}
hx_strings_internal__$RingBuffer_RingBufferIterator.__name__ = "hx.strings.internal._RingBuffer.RingBufferIterator";
Object.assign(hx_strings_internal__$RingBuffer_RingBufferIterator.prototype, {
	__class__: hx_strings_internal__$RingBuffer_RingBufferIterator
});
class js_Browser {
	static get_supported() {
		if(typeof(window) != "undefined" && typeof(window.location) != "undefined") {
			return typeof(window.location.protocol) == "string";
		} else {
			return false;
		}
	}
	static createXMLHttpRequest() {
		if(typeof XMLHttpRequest != "undefined") {
			return new XMLHttpRequest();
		}
		if(typeof ActiveXObject != "undefined") {
			return new ActiveXObject("Microsoft.XMLHTTP");
		}
		throw haxe_Exception.thrown("Unable to create XMLHttpRequest object.");
	}
}
js_Browser.__name__ = "js.Browser";
class js_lib_HaxeIterator {
	constructor(jsIterator) {
		this.jsIterator = jsIterator;
		this.lastStep = jsIterator.next();
	}
	hasNext() {
		return !this.lastStep.done;
	}
	next() {
		let v = this.lastStep.value;
		this.lastStep = this.jsIterator.next();
		return v;
	}
}
js_lib_HaxeIterator.__name__ = "js.lib.HaxeIterator";
Object.assign(js_lib_HaxeIterator.prototype, {
	__class__: js_lib_HaxeIterator
});
class sha_Hash {
	constructor(blockSize,finalSize) {
		if(sha_Hash._hx_skip_constructor) {
			return;
		}
		this._hx_constructor(blockSize,finalSize);
	}
	_hx_constructor(blockSize,finalSize) {
		this.finalSize = finalSize;
		this.block = new haxe_io_Bytes(new ArrayBuffer(blockSize));
		this.length = 0;
	}
	min(a,b) {
		if(a < b) {
			return a;
		}
		return b;
	}
	writeInt(b,i,pos) {
		b.b[pos] = i >> 24;
		b.b[pos + 1] = i >> 16 & 255;
		b.b[pos + 2] = i >> 8 & 255;
		b.b[pos + 3] = i & 255;
	}
	update(data) {
		let accum = this.length;
		let offset = 0;
		while(offset < data.length) {
			let assigned = accum % this.block.length;
			let a = data.length - offset;
			let b = this.block.length - assigned;
			let remainder = a < b ? a : b;
			let _g = 0;
			let _g1 = remainder;
			while(_g < _g1) {
				let i = _g++;
				this.block.b[assigned + i] = data.b[offset + i];
			}
			accum += remainder;
			offset += remainder;
			if(accum % this.block.length == 0) {
				this._update(this.block);
			}
		}
		this.length += data.length;
		return this;
	}
	digest() {
		let rem = this.length % this.block.length;
		this.block.b[rem] = 128;
		this.block.fill(rem + 1,this.block.length - (rem + 1),0);
		if(rem >= this.finalSize) {
			this._update(this.block);
			this.block.fill(0,this.block.length,0);
		}
		let bits = this.length * 8;
		if(bits <= -1) {
			let b = this.block;
			let pos = this.block.length - 4;
			b.b[pos] = bits >> 24;
			b.b[pos + 1] = bits >> 16 & 255;
			b.b[pos + 2] = bits >> 8 & 255;
			b.b[pos + 3] = bits & 255;
		} else {
			let lowBits = (bits & -1) >>> 0;
			let highBits = (bits - lowBits) / 4294967296 | 0;
			let b = this.block;
			let pos = this.block.length - 8;
			b.b[pos] = highBits >> 24;
			b.b[pos + 1] = highBits >> 16 & 255;
			b.b[pos + 2] = highBits >> 8 & 255;
			b.b[pos + 3] = highBits & 255;
			let b1 = this.block;
			let pos1 = this.block.length - 4;
			b1.b[pos1] = lowBits >> 24;
			b1.b[pos1 + 1] = lowBits >> 16 & 255;
			b1.b[pos1 + 2] = lowBits >> 8 & 255;
			b1.b[pos1 + 3] = lowBits & 255;
		}
		this._update(this.block);
		return this._hash();
	}
}
sha_Hash.__name__ = "sha.Hash";
Object.assign(sha_Hash.prototype, {
	__class__: sha_Hash
});
class sha_SHA256 extends sha_Hash {
	constructor() {
		sha_Hash._hx_skip_constructor = true;
		super();
		sha_Hash._hx_skip_constructor = false;
		this._hx_constructor();
	}
	_hx_constructor() {
		this._w = [];
		this._h = 1541459225;
		this._g = 528734635;
		this._f = -1694144372;
		this._e = 1359893119;
		this._d = -1521486534;
		this._c = 1013904242;
		this._b = -1150833019;
		this._a = 1779033703;
		super._hx_constructor(64,56);
	}
	sigma0(x) {
		return (x >>> 2 | x << 30) ^ (x >>> 13 | x << 19) ^ (x >>> 22 | x << 10);
	}
	sigma1(x) {
		return (x >>> 6 | x << 26) ^ (x >>> 11 | x << 21) ^ (x >>> 25 | x << 7);
	}
	gamma0(x) {
		return (x >>> 7 | x << 25) ^ (x >>> 18 | x << 14) ^ x >>> 3;
	}
	gamma1(x) {
		return (x >>> 17 | x << 15) ^ (x >>> 19 | x << 13) ^ x >>> 10;
	}
	ch(x,y,z) {
		return z ^ x & (y ^ z);
	}
	maj(x,y,z) {
		return x & y | z & (x | y);
	}
	_update(data) {
		let W = this._w;
		let a = this._a | 0;
		let b = this._b | 0;
		let c = this._c | 0;
		let d = this._d | 0;
		let e = this._e | 0;
		let f = this._f | 0;
		let g = this._g | 0;
		let h = this._h | 0;
		let _g = 0;
		while(_g < 16) {
			let i = _g++;
			W[i] = data.b[i * 4] << 24 | data.b[i * 4 + 1] << 16 | data.b[i * 4 + 2] << 8 | data.b[i * 4 + 3];
		}
		let _g1 = 16;
		while(_g1 < 64) {
			let i = _g1++;
			W[i] = this.gamma1(W[i - 2]) + W[i - 7] + this.gamma0(W[i - 15]) + W[i - 16] | 0;
		}
		let _g2 = 0;
		while(_g2 < 64) {
			let j = _g2++;
			let T1 = h + this.sigma1(e) + this.ch(e,f,g) + sha_SHA256_K[j] + W[j] | 0;
			let T2 = this.sigma0(a) + this.maj(a,b,c) | 0;
			h = g;
			g = f;
			f = e;
			e = d + T1 | 0;
			d = c;
			c = b;
			b = a;
			a = T1 + T2 | 0;
		}
		this._a = a + this._a | 0;
		this._b = b + this._b | 0;
		this._c = c + this._c | 0;
		this._d = d + this._d | 0;
		this._e = e + this._e | 0;
		this._f = f + this._f | 0;
		this._g = g + this._g | 0;
		this._h = h + this._h | 0;
	}
	_hash() {
		let b = new haxe_io_Bytes(new ArrayBuffer(32));
		let i = this._a;
		b.b[0] = i >> 24;
		b.b[1] = i >> 16 & 255;
		b.b[2] = i >> 8 & 255;
		b.b[3] = i & 255;
		let i1 = this._b;
		b.b[4] = i1 >> 24;
		b.b[5] = i1 >> 16 & 255;
		b.b[6] = i1 >> 8 & 255;
		b.b[7] = i1 & 255;
		let i2 = this._c;
		b.b[8] = i2 >> 24;
		b.b[9] = i2 >> 16 & 255;
		b.b[10] = i2 >> 8 & 255;
		b.b[11] = i2 & 255;
		let i3 = this._d;
		b.b[12] = i3 >> 24;
		b.b[13] = i3 >> 16 & 255;
		b.b[14] = i3 >> 8 & 255;
		b.b[15] = i3 & 255;
		let i4 = this._e;
		b.b[16] = i4 >> 24;
		b.b[17] = i4 >> 16 & 255;
		b.b[18] = i4 >> 8 & 255;
		b.b[19] = i4 & 255;
		let i5 = this._f;
		b.b[20] = i5 >> 24;
		b.b[21] = i5 >> 16 & 255;
		b.b[22] = i5 >> 8 & 255;
		b.b[23] = i5 & 255;
		let i6 = this._g;
		b.b[24] = i6 >> 24;
		b.b[25] = i6 >> 16 & 255;
		b.b[26] = i6 >> 8 & 255;
		b.b[27] = i6 & 255;
		let i7 = this._h;
		b.b[28] = i7 >> 24;
		b.b[29] = i7 >> 16 & 255;
		b.b[30] = i7 >> 8 & 255;
		b.b[31] = i7 & 255;
		return b;
	}
}
sha_SHA256.__name__ = "sha.SHA256";
sha_SHA256.__super__ = sha_Hash;
Object.assign(sha_SHA256.prototype, {
	__class__: sha_SHA256
});
class snikket_AttachmentSource {
	static tinkSource(this1) {
		let options = null;
		let chunkSize = options == null || options.chunkSize == null ? 16777216 : options.chunkSize;
		return new tink_io_js_BlobSource(this1.name,this1,0,chunkSize);
	}
}
class snikket_Autolink {
	static one(s,start) {
		let matches = [snikket_Autolink.match(s,start,snikket_Autolink.XMPP_URI,false),snikket_Autolink.match(s,start,snikket_Autolink.TEL_URI,false),snikket_Autolink.match(s,start,snikket_Autolink.SMS_URI,false),snikket_Autolink.match(s,start,snikket_Autolink.AUTOLINK_WEB_URL,true)];
		matches.sort(function(x,y) {
			return x.start - y.start;
		});
		let tmp = Lambda.find(matches,function(match) {
			return match.span != null;
		});
		if(tmp != null) {
			return tmp;
		} else {
			return matches[0];
		}
	}
	static match(s,start,pattern,addHttps) {
		let pattern1 = new EReg(pattern,"u");
		if(pattern1.matchSub(s,start)) {
			let pos = pattern1.matchedPos();
			let link = pattern1.matched(0);
			let uri = !addHttps || link.includes("://") ? link : "https://" + link;
			return { span : snikket_Node.Element(new snikket_Stanza("a",{ href : uri}).text(link)), start : pos.pos, end : pos.pos + pos.len};
		} else {
			return { span : null, start : s.length, end : s.length};
		}
	}
}
snikket_Autolink.__name__ = "snikket.Autolink";
class snikket_Caps {
	constructor(node,identities,features) {
		this._ver = null;
		this.node = node;
		this.identities = identities;
		this.features = features;
	}
	isChannel(chatId) {
		if(chatId.indexOf("@") < 0) {
			return false;
		}
		if(this.features.includes("http://jabber.org/protocol/muc")) {
			return Lambda.find(this.identities,function(identity) {
				return identity.category == "conference";
			}) != null;
		} else {
			return false;
		}
	}
	discoReply() {
		let query = new snikket_Stanza("query",{ xmlns : "http://jabber.org/protocol/disco#info"});
		let _g = 0;
		let _g1 = this.identities;
		while(_g < _g1.length) {
			let identity = _g1[_g];
			++_g;
			identity.addToDisco(query);
		}
		let _g2 = 0;
		let _g3 = this.features;
		while(_g2 < _g3.length) {
			let feature = _g3[_g2];
			++_g2;
			query.tag("feature",{ "var" : feature}).up();
		}
		return query;
	}
	addC(stanza) {
		stanza.tag("c",{ xmlns : "http://jabber.org/protocol/caps", hash : "sha-1", node : this.node, ver : this.ver()}).up();
		return stanza;
	}
	computeVer() {
		this.features.sort(function(x,y) {
			if(x == y) {
				return 0;
			} else if(x < y) {
				return -1;
			} else {
				return 1;
			}
		});
		this.identities.sort(function(x,y) {
			if(x.ver() == y.ver()) {
				return 0;
			} else if(x.ver() < y.ver()) {
				return -1;
			} else {
				return 1;
			}
		});
		let s = "";
		let _g = 0;
		let _g1 = this.identities;
		while(_g < _g1.length) {
			let identity = _g1[_g];
			++_g;
			s += identity.ver() + "<";
		}
		let _g2 = 0;
		let _g3 = this.features;
		while(_g2 < _g3.length) {
			let feature = _g3[_g2];
			++_g2;
			s += feature + "<";
		}
		return snikket_Hash.sha1(haxe_io_Bytes.ofString(s));
	}
	verRaw() {
		if(this._ver == null) {
			this._ver = this.computeVer();
		}
		return this._ver;
	}
	ver() {
		return this.verRaw().toBase64();
	}
	static withIdentity(caps,category,type) {
		let result = [];
		let cap = caps;
		while(cap.hasNext()) {
			let cap1 = cap.next();
			if(cap1.value != null) {
				let _g = 0;
				let _g1 = cap1.value.identities;
				while(_g < _g1.length) {
					let identity = _g1[_g];
					++_g;
					if((category == null || category == identity.category) && (type == null || type == identity.type)) {
						result.push(cap1.key);
					}
				}
			}
		}
		return result;
	}
	static withFeature(caps,feature) {
		let result = [];
		let cap = caps;
		while(cap.hasNext()) {
			let cap1 = cap.next();
			if(cap1.value != null) {
				let _g = 0;
				let _g1 = cap1.value.features;
				while(_g < _g1.length) {
					let feat = _g1[_g];
					++_g;
					if(feature == feat) {
						result.push(cap1.key);
					}
				}
			}
		}
		return result;
	}
}
$hx_exports["snikket"]["Caps"] = snikket_Caps;
snikket_Caps.__name__ = "snikket.Caps";
Object.assign(snikket_Caps.prototype, {
	__class__: snikket_Caps
});
class snikket_Identity {
	constructor(category,type,name) {
		this.category = category;
		this.type = type;
		this.name = name;
	}
	addToDisco(stanza) {
		stanza.tag("identity",{ category : this.category, type : this.type, name : this.name}).up();
	}
	ver() {
		return this.category + "/" + this.type + "//" + this.name;
	}
}
$hx_exports["snikket"]["Identity"] = snikket_Identity;
snikket_Identity.__name__ = "snikket.Identity";
Object.assign(snikket_Identity.prototype, {
	__class__: snikket_Identity
});
class snikket_Chat {
	constructor(client,stream,persistence,chatId,uiState,isBlocked,extensions,readUpToId,readUpToBy) {
		if(snikket_Chat._hx_skip_constructor) {
			return;
		}
		this._hx_constructor(client,stream,persistence,chatId,uiState,isBlocked,extensions,readUpToId,readUpToBy);
	}
	_hx_constructor(client,stream,persistence,chatId,uiState,isBlocked,extensions,readUpToId,readUpToBy) {
		if(isBlocked == null) {
			isBlocked = false;
		}
		if(uiState == null) {
			uiState = 1;
		}
		this.activeThread = null;
		this.isActive = null;
		this.typingTimer = null;
		this.typingThread = null;
		this.isTyping = false;
		this._unreadCount = 0;
		this.isBlocked = false;
		this.uiState = 1;
		this.jingleSessions = new Map([]);
		this.trusted = false;
		this.presence = new Map([]);
		this.avatarSha1 = null;
		this.client = client;
		this.stream = stream;
		this.persistence = persistence;
		this.chatId = chatId;
		this.uiState = uiState;
		this.isBlocked = isBlocked;
		let tmp = extensions;
		this.extensions = tmp != null ? tmp : new snikket_Stanza("extensions",{ xmlns : "urn:xmpp:bookmarks:1"});
		this.readUpToId = readUpToId;
		this.readUpToBy = readUpToBy;
		this.displayName = chatId;
	}
	fetchFromSync(sync,callback) {
		let _gthis = this;
		sync.onMessages(function(messageList) {
			let chatMessages = [];
			let _g = 0;
			let _g1 = messageList.messages;
			while(_g < _g1.length) {
				let m = _g1[_g];
				++_g;
				switch(m._hx_index) {
				case 1:
					let message = m.message;
					chatMessages.push(message);
					break;
				case 2:
					let action = m.action;
					_gthis.client.moderateMessage(action);
					break;
				case 3:
					let update = m.update;
					_gthis.persistence.storeReaction(_gthis.client.accountId(),update,function(m) {
					});
					break;
				default:
				}
			}
			_gthis.client.storeMessages(chatMessages,function(chatMessages) {
				let callback1 = callback;
				let _g = [];
				let _g1 = 0;
				let _g2 = chatMessages;
				while(_g1 < _g2.length) {
					let v = _g2[_g1];
					++_g1;
					if(v != null && v.chatId() == _gthis.chatId) {
						_g.push(v);
					}
				}
				callback1(_g);
			});
		});
		sync.fetchNext();
	}
	addReaction(m,reaction) {
		let toSend = m.reply();
		toSend.localId = snikket_ID.long();
		reaction.render(function(text) {
			toSend.text = StringTools.replace(text,"️","");
		},function(text,uri) {
			let hash = snikket_Hash.fromUri(uri);
			toSend.setHtml("<img alt=\"" + snikket_Util_xmlEscape(text) + "\" src=\"" + snikket_Util_xmlEscape(hash == null ? uri : hash.bobUri()) + "\" />");
		});
		this.sendMessage(toSend);
	}
	typing(threadId,content) {
		if(threadId != this.typingThread && this.isTyping) {
			this.sendChatState("paused",this.typingThread);
			this.isTyping = false;
		}
		this.typingThread = threadId;
		if(this.typingTimer != null) {
			this.typingTimer.stop();
		}
		let _gthis = this;
		if(content == "") {
			this.isTyping = false;
			this.sendChatState("active",this.typingThread);
			if(this.isActive == null) {
				this.typingTimer = haxe_Timer.delay(function() {
					_gthis.sendChatState("inactive",_gthis.typingThread);
				},30000);
			}
			return;
		}
		this.typingTimer = haxe_Timer.delay(function() {
			_gthis.sendChatState("paused",_gthis.typingThread);
			_gthis.isTyping = false;
		},10000);
		if(this.isTyping) {
			return;
		}
		this.isTyping = true;
		this.sendChatState("composing",this.typingThread);
	}
	setActive(active,threadId) {
		if(this.typingTimer != null) {
			this.typingTimer.stop();
		}
		this.isTyping = false;
		if(this.isActive && active && threadId != this.activeThread) {
			this.sendChatState("inactive",this.activeThread);
			this.isActive = false;
		}
		if(this.isActive != null) {
			if(this.isActive && active) {
				return;
			}
			if(!this.isActive && !active) {
				return;
			}
		}
		this.isActive = active;
		this.activeThread = threadId;
		this.sendChatState(active ? "active" : "inactive",this.activeThread);
	}
	togglePinned() {
		this.uiState = this.uiState == 0 ? 1 : 0;
		this.persistence.storeChats(this.client.accountId(),[this]);
		this.client.sortChats();
		this.client.trigger("chats/update",[this]);
	}
	block(reportSpam,onServer) {
		if(reportSpam != null && !onServer) {
			throw haxe_Exception.thrown("Can't report SPAM if not sending to server");
		}
		this.isBlocked = true;
		if(this.uiState == 2) {
			this.persistence.storeChats(this.client.accountId(),[this]);
		} else {
			this.close();
		}
		if(onServer) {
			let iq = new snikket_Stanza("iq",{ type : "set", id : snikket_ID.short()}).tag("block",{ xmlns : "urn:xmpp:blocking"}).tag("item",{ jid : this.chatId});
			if(reportSpam != null) {
				iq.tag("report",{ xmlns : "urn:xmpp:reporting:1", reason : "urn:xmpp:reporting:spam"}).tag("stanza-id",{ xmlns : "urn:xmpp:sid:0", by : reportSpam.serverIdBy, id : reportSpam.serverId});
			}
			this.stream.sendIq(iq,function(response) {
			});
		}
	}
	unblock(onServer) {
		this.isBlocked = false;
		this.uiState = 1;
		this.persistence.storeChats(this.client.accountId(),[this]);
		this.client.trigger("chats/update",[this]);
		if(onServer) {
			this.stream.sendIq(new snikket_Stanza("iq",{ type : "set", id : snikket_ID.short()}).tag("unblock",{ xmlns : "urn:xmpp:blocking"}).tag("item",{ jid : this.chatId}).up().up(),function(response) {
			});
		}
	}
	lastMessageTimestamp() {
		let tmp = this.lastMessage;
		if(tmp != null) {
			return tmp.timestamp;
		} else {
			return null;
		}
	}
	updateFromBookmark(item) {
		let conf = item.getChild("conference","urn:xmpp:bookmarks:1");
		let fn = conf.attr["name"];
		if(fn != null) {
			this.displayName = fn;
		}
		this.uiState = conf.attr["autojoin"] == "1" || conf.attr["autojoin"] == "true" ? this.uiState == 0 ? 0 : 1 : 2;
		let tmp = conf.getChild("extensions");
		this.extensions = tmp != null ? tmp : new snikket_Stanza("extensions",{ xmlns : "urn:xmpp:bookmarks:1"});
	}
	updateFromRoster(item) {
		this.setTrusted(item.subscription == "both" || item.subscription == "from");
		if(item.fn != null && item.fn != "") {
			this.displayName = item.fn;
		}
	}
	getPhoto() {
		if(this.avatarSha1 == null || haxe_io_Bytes.ofData(this.avatarSha1).length < 1) {
			return null;
		}
		return new snikket_Hash("sha-1",this.avatarSha1).toUri();
	}
	getPlaceholder() {
		return snikket_Color.defaultPhoto(this.chatId,this.getDisplayName().charAt(0).toUpperCase());
	}
	readUpTo() {
		return this.readUpToId;
	}
	unreadCount() {
		return this._unreadCount;
	}
	setUnreadCount(count) {
		this._unreadCount = count;
	}
	preview() {
		if(this.lastMessage == null) {
			return "";
		}
		if(this.lastMessage.type == 1) {
			if(this.lastMessage.isIncoming()) {
				return "Incoming Call";
			} else {
				return "Outgoing Call";
			}
		} else {
			return this.lastMessage.text;
		}
	}
	setLastMessage(message) {
		this.lastMessage = message;
	}
	setDisplayName(fn) {
		this.displayName = fn;
		this.bookmark();
	}
	getDisplayName() {
		return this.displayName;
	}
	setPresence(resource,presence) {
		this.presence.set(resource,presence);
	}
	setCaps(resource,caps) {
		let presence = this.presence.get(resource);
		if(presence != null) {
			presence.caps = caps;
			this.setPresence(resource,presence);
		} else {
			this.setPresence(resource,new snikket_Presence(caps,null));
		}
	}
	removePresence(resource) {
		this.presence.delete(resource);
	}
	getCaps() {
		let iter = new snikket_HaxeKVIterator(this.presence.entries());
		return { hasNext : $bind(iter,iter.hasNext), next : function() {
			let n = iter.next();
			return { key : n.key, value : n.value.caps};
		}};
	}
	getResourceCaps(resource) {
		let tmp = this.presence.get(resource);
		let tmp1 = tmp != null ? tmp.caps : null;
		if(tmp1 != null) {
			return tmp1;
		} else {
			return new snikket_Caps("",[],[]);
		}
	}
	setAvatarSha1(sha1) {
		this.avatarSha1 = sha1;
	}
	setTrusted(trusted) {
		this.trusted = trusted;
	}
	isTrusted() {
		return this.trusted;
	}
	livePresence() {
		return true;
	}
	syncing() {
		return !this.client.inSync;
	}
	canAudioCall() {
		let jsIterator = this.presence.entries();
		let _g_jsIterator = jsIterator;
		let _g_lastStep = jsIterator.next();
		while(!_g_lastStep.done) {
			let v = _g_lastStep.value;
			_g_lastStep = _g_jsIterator.next();
			let _g_key = v[0];
			let _g_value = v[1];
			let resource = _g_key;
			let p = _g_value;
			let tmp = p.caps;
			let tmp1 = tmp != null ? tmp.features : null;
			let tmp2 = tmp1 != null ? tmp1.includes("urn:xmpp:jingle:apps:rtp:audio") : null;
			if(tmp2 != null && tmp2) {
				return true;
			}
		}
		return false;
	}
	canVideoCall() {
		let jsIterator = this.presence.entries();
		let _g_jsIterator = jsIterator;
		let _g_lastStep = jsIterator.next();
		while(!_g_lastStep.done) {
			let v = _g_lastStep.value;
			_g_lastStep = _g_jsIterator.next();
			let _g_key = v[0];
			let _g_value = v[1];
			let resource = _g_key;
			let p = _g_value;
			let tmp = p.caps;
			let tmp1 = tmp != null ? tmp.features : null;
			let tmp2 = tmp1 != null ? tmp1.includes("urn:xmpp:jingle:apps:rtp:video") : null;
			if(tmp2 != null && tmp2) {
				return true;
			}
		}
		return false;
	}
	startCall(audio,video) {
		let session = new snikket_jingle_OutgoingProposedSession(this.client,snikket_JID.parse(this.chatId));
		this.jingleSessions.set(session.get_sid(),session);
		session.propose(audio,video);
	}
	addMedia(streams) {
		if(this.callStatus() != "ongoing") {
			throw haxe_Exception.thrown("cannot add media when no call ongoing");
		}
		let jsIterator = this.jingleSessions.values();
		let inlHaxeIterator_jsIterator = jsIterator;
		let inlHaxeIterator_lastStep = jsIterator.next();
		let v = inlHaxeIterator_lastStep.value;
		inlHaxeIterator_lastStep = inlHaxeIterator_jsIterator.next();
		v.addMedia(streams);
	}
	acceptCall() {
		let jsIterator = this.jingleSessions.values();
		let session_jsIterator = jsIterator;
		let session_lastStep = jsIterator.next();
		while(!session_lastStep.done) {
			let v = session_lastStep.value;
			session_lastStep = session_jsIterator.next();
			let session = v;
			session.accept();
		}
	}
	hangup() {
		let jsIterator = this.jingleSessions.values();
		let session_jsIterator = jsIterator;
		let session_lastStep = jsIterator.next();
		while(!session_lastStep.done) {
			let v = session_lastStep.value;
			session_lastStep = session_jsIterator.next();
			let session = v;
			session.hangup();
			this.jingleSessions.delete(session.get_sid());
		}
	}
	callStatus() {
		let jsIterator = this.jingleSessions.values();
		let session_jsIterator = jsIterator;
		let session_lastStep = jsIterator.next();
		while(!session_lastStep.done) {
			let v = session_lastStep.value;
			session_lastStep = session_jsIterator.next();
			let session = v;
			return session.callStatus();
		}
		return "none";
	}
	dtmf() {
		let jsIterator = this.jingleSessions.values();
		let session_jsIterator = jsIterator;
		let session_lastStep = jsIterator.next();
		while(!session_lastStep.done) {
			let v = session_lastStep.value;
			session_lastStep = session_jsIterator.next();
			let session = v;
			let dtmf = session.dtmf();
			if(dtmf != null) {
				return dtmf;
			}
		}
		return null;
	}
	videoTracks() {
		let this1 = this.jingleSessions;
		let _g = [];
		let x = $getIterator({ iterator : function() {
			return new js_lib_HaxeIterator(this1.values());
		}});
		while(x.hasNext()) {
			let x1 = x.next();
			_g.push(x1.videoTracks());
		}
		let _g1 = [];
		let e = $getIterator(_g);
		while(e.hasNext()) {
			let e1 = e.next();
			let x = $getIterator(e1);
			while(x.hasNext()) {
				let x1 = x.next();
				_g1.push(x1);
			}
		}
		return _g1;
	}
	markReadUpToId(upTo,upToBy,callback) {
		if(upTo == null) {
			return;
		}
		if(this.readUpTo() == upTo) {
			return;
		}
		this.readUpToId = upTo;
		this.readUpToBy = upToBy;
		this.persistence.storeChats(this.client.accountId(),[this]);
		let _gthis = this;
		this.persistence.getMessagesBefore(this.client.accountId(),this.chatId,null,null,function(messages) {
			let i = messages.length;
			while(--i >= 0) if(messages[i].serverId == _gthis.readUpToId || !messages[i].isIncoming()) {
				break;
			}
			_gthis.setUnreadCount(messages.length - (i + 1));
			if(callback != null) {
				callback();
			}
		});
	}
	markReadUpToMessage(message,callback) {
		if(message.serverId == null || message.chatId() != this.chatId) {
			return;
		}
		if(this.readUpTo() == message.serverId) {
			return;
		}
		let _gthis = this;
		this.persistence.getMessage(this.client.accountId(),this.chatId,this.readUpTo(),null,function(readMessage) {
			if(readMessage != null && Reflect.compare(message.timestamp,readMessage.timestamp) <= 0) {
				return;
			}
			_gthis.markReadUpToId(message.serverId,message.serverIdBy,callback);
		});
	}
	publishMds() {
		let _gthis = this;
		this.stream.sendIq(new snikket_Stanza("iq",{ type : "set"}).tag("pubsub",{ xmlns : "http://jabber.org/protocol/pubsub"}).tag("publish",{ node : "urn:xmpp:mds:displayed:0"}).tag("item",{ id : this.chatId}).tag("displayed",{ xmlns : "urn:xmpp:mds:displayed:0"}).tag("stanza-id",{ xmlns : "urn:xmpp:sid:0", id : this.readUpTo(), by : this.readUpToBy}).up().up().up().tag("publish-options").tag("x",{ xmlns : "jabber:x:data", type : "submit"}).tag("field",{ "var" : "FORM_TYPE", type : "hidden"}).textTag("value","http://jabber.org/protocol/pubsub#publish-options").up().tag("field",{ "var" : "pubsub#persist_items"}).textTag("value","true").up().tag("field",{ "var" : "pubsub#max_items"}).textTag("value","max").up().tag("field",{ "var" : "pubsub#send_last_published_item"}).textTag("value","never").up().tag("field",{ "var" : "pubsub#access_model"}).textTag("value","whitelist").up().up().up(),function(response) {
			if(response.attr["type"] == "error") {
				let tmp = response.getChild("error");
				let preconditionError = tmp != null ? tmp.getChild("precondition-not-met","http://jabber.org/protocol/pubsub#errors") : null;
				if(preconditionError != null) {
					_gthis.stream.sendIq(new snikket_Stanza("iq",{ type : "set"}).tag("pubsub",{ xmlns : "http://jabber.org/protocol/pubsub#owner"}).tag("configure",{ node : "urn:xmpp:mds:displayed:0"}).tag("x",{ xmlns : "jabber:x:data", type : "submit"}).tag("field",{ "var" : "FORM_TYPE", type : "hidden"}).textTag("value","http://jabber.org/protocol/pubsub#publish-options").up().tag("field",{ "var" : "pubsub#persist_items"}).textTag("value","true").up().tag("field",{ "var" : "pubsub#max_items"}).textTag("value","max").up().tag("field",{ "var" : "pubsub#send_last_published_item"}).textTag("value","never").up().tag("field",{ "var" : "pubsub#access_model"}).textTag("value","whitelist").up().up().up().up(),function(response) {
						if(response.attr["type"] == "result") {
							_gthis.publishMds();
						}
					});
				}
			}
		});
	}
}
snikket_Chat.__name__ = "snikket.Chat";
Object.assign(snikket_Chat.prototype, {
	__class__: snikket_Chat
});
class snikket_DirectChat extends snikket_Chat {
	constructor(client,stream,persistence,chatId,uiState,isBlocked,extensions,readUpToId,readUpToBy) {
		if(isBlocked == null) {
			isBlocked = false;
		}
		if(uiState == null) {
			uiState = 1;
		}
		super(client,stream,persistence,chatId,uiState,isBlocked,extensions,readUpToId,readUpToBy);
	}
	getParticipants() {
		return this.chatId.split("\n");
	}
	getParticipantDetails(participantId) {
		let chat = this.client.getDirectChat(participantId);
		return new snikket_Participant(chat.getDisplayName(),chat.getPhoto(),chat.getPlaceholder(),chat.chatId == this.client.accountId());
	}
	getMessagesBefore(beforeId,beforeTime,handler) {
		let _gthis = this;
		this.persistence.getMessagesBefore(this.client.accountId(),this.chatId,beforeId,beforeTime,function(messages) {
			if(messages.length > 0) {
				handler(messages);
			} else {
				let filter = { 'with' : _gthis.chatId};
				if(beforeId != null) {
					filter.page = { before : beforeId};
				}
				let sync = new snikket_MessageSync(_gthis.client,_gthis.stream,filter);
				_gthis.fetchFromSync(sync,handler);
			}
		});
	}
	getMessagesAfter(afterId,afterTime,handler) {
		if(afterId == this.lastMessageId() && !this.syncing()) {
			handler([]);
			return;
		}
		let _gthis = this;
		this.persistence.getMessagesAfter(this.client.accountId(),this.chatId,afterId,afterTime,function(messages) {
			if(messages.length > 0) {
				handler(messages);
			} else {
				let filter = { 'with' : _gthis.chatId};
				if(afterId != null) {
					filter.page = { after : afterId};
				}
				let sync = new snikket_MessageSync(_gthis.client,_gthis.stream,filter);
				_gthis.fetchFromSync(sync,handler);
			}
		});
	}
	getMessagesAround(aroundId,aroundTime,handler) {
		this.persistence.getMessagesAround(this.client.accountId(),this.chatId,aroundId,aroundTime,function(messages) {
			if(messages.length > 0) {
				handler(messages);
			} else {
				handler([]);
			}
		});
	}
	prepareIncomingMessage(message,stanza) {
		message.syncPoint = !this.syncing();
		return message;
	}
	prepareOutgoingMessage(message) {
		let tmp = message.timestamp;
		message.timestamp = tmp != null ? tmp : snikket_Date.format(new Date());
		message.direction = 1;
		message.from = this.client.jid;
		message.sender = message.from.asBare();
		message.replyTo = [message.sender];
		let _this = this.getParticipants();
		let result = new Array(_this.length);
		let _g = 0;
		let _g1 = _this.length;
		while(_g < _g1) {
			let i = _g++;
			result[i] = snikket_JID.parse(_this[i]);
		}
		message.recipients = result;
		return message;
	}
	correctMessage(localId,message) {
		let toSendId = message.localId;
		message = this.prepareOutgoingMessage(message);
		let tmp = message.build();
		message.versions = [tmp];
		message.localId = localId;
		let _gthis = this;
		this.client.storeMessages([message.build()],function(corrected) {
			let tmp = corrected[0].versions[corrected[0].versions.length - 1];
			let tmp1 = (tmp != null ? tmp.localId : null) == localId ? corrected[0].versions : [message.build()];
			message.versions = tmp1;
			message.localId = toSendId;
			let _g = 0;
			let _g1 = message.recipients;
			while(_g < _g1.length) {
				let recipient = _g1[_g];
				++_g;
				message.to = recipient;
				_gthis.client.sendStanza(message.build().asStanza());
			}
			let tmp2 = _gthis.lastMessage;
			if(localId == (tmp2 != null ? tmp2.localId : null)) {
				_gthis.setLastMessage(corrected[0]);
				_gthis.client.trigger("chats/update",[_gthis]);
			}
			_gthis.client.notifyMessageHandlers(corrected[0],1);
		});
	}
	sendMessage(message) {
		if(this.typingTimer != null) {
			this.typingTimer.stop();
		}
		this.client.chatActivity(this);
		message = this.prepareOutgoingMessage(message);
		message.to = message.recipients[0];
		let fromStanza = snikket_Message.fromStanza(message.build().asStanza(),this.client.jid).parsed;
		let _gthis = this;
		switch(fromStanza._hx_index) {
		case 1:
			let _g = fromStanza.message;
			this.client.storeMessages([message.build()],function(stored) {
				let _g = 0;
				let _g1 = message.recipients;
				while(_g < _g1.length) {
					let recipient = _g1[_g];
					++_g;
					message.to = recipient;
					let stanza = message.build().asStanza();
					if(_gthis.isActive != null) {
						_gthis.isActive = true;
						_gthis.activeThread = message.threadId;
						stanza.tag("active",{ xmlns : "http://jabber.org/protocol/chatstates"}).up();
					}
					_gthis.client.sendStanza(stanza);
				}
				_gthis.setLastMessage(message.build());
				_gthis.client.trigger("chats/update",[_gthis]);
				_gthis.client.notifyMessageHandlers(stored[0],stored[0].versions.length > 1 ? 1 : 0);
			});
			break;
		case 3:
			let update = fromStanza.update;
			this.persistence.storeReaction(this.client.accountId(),update,function(stored) {
				let _g = 0;
				let _g1 = message.recipients;
				while(_g < _g1.length) {
					let recipient = _g1[_g];
					++_g;
					message.to = recipient;
					_gthis.client.sendStanza(message.build().asStanza());
				}
				if(stored != null) {
					_gthis.client.notifyMessageHandlers(stored,2);
				}
			});
			break;
		default:
			haxe_Log.trace("Invalid message",{ fileName : "snikket/Chat.hx", lineNumber : 797, className : "snikket.DirectChat", methodName : "sendMessage", customParams : [fromStanza]});
			throw haxe_Exception.thrown("Trying to send invalid message.");
		}
	}
	removeReaction(m,reaction) {
		if(((reaction) instanceof snikket_CustomEmojiReaction)) {
			if(reaction.envelopeId == null) {
				throw haxe_Exception.thrown("Cannot remove custom emoji reaction without envelopeId");
			}
			let correct = m.reply();
			correct.localId = snikket_ID.long();
			correct.setHtml("");
			correct.text = null;
			this.correctMessage(reaction.envelopeId,correct);
			return;
		}
		let reactions = [];
		let _gthis = this;
		let jsIterator = m.reactions.entries();
		let _g_jsIterator = jsIterator;
		let _g_lastStep = jsIterator.next();
		while(!_g_lastStep.done) {
			let v = _g_lastStep.value;
			_g_lastStep = _g_jsIterator.next();
			let _g_key = v[0];
			let _g_value = v[1];
			let areaction = _g_key;
			let reacts = _g_value;
			if(areaction != reaction.key) {
				let react = Lambda.find(reacts,function(r) {
					return r.senderId == _gthis.client.accountId();
				});
				if(react != null && !((react) instanceof snikket_CustomEmojiReaction)) {
					reactions.push(react);
				}
			}
		}
		let update = new snikket_ReactionUpdate(snikket_ID.long(),null,null,m.localId,m.chatId(),this.client.accountId(),snikket_Date.format(new Date()),reactions,0);
		this.persistence.storeReaction(this.client.accountId(),update,function(stored) {
			let stanza = update.asStanza();
			let _g = 0;
			let _g1 = _gthis.getParticipants();
			while(_g < _g1.length) {
				let recipient = _g1[_g];
				++_g;
				stanza.attr["to"] = recipient;
				_gthis.client.sendStanza(stanza);
			}
			if(stored != null) {
				_gthis.client.notifyMessageHandlers(stored,2);
			}
		});
	}
	lastMessageId() {
		let tmp = this.lastMessage;
		let tmp1 = tmp != null ? tmp.localId : null;
		if(tmp1 != null) {
			return tmp1;
		} else {
			let tmp = this.lastMessage;
			if(tmp != null) {
				return tmp.serverId;
			} else {
				return null;
			}
		}
	}
	markReadUpTo(message) {
		let _gthis = this;
		this.markReadUpToMessage(message,function() {
			if(message.isIncoming() && message.localId != null) {
				let _g = 0;
				let _g1 = _gthis.getParticipants();
				while(_g < _g1.length) {
					let recipient = _g1[_g];
					++_g;
					let stanza = new snikket_Stanza("message",{ to : recipient, id : snikket_ID.long()}).tag("displayed",{ xmlns : "urn:xmpp:chat-markers:0", id : message.localId}).up();
					if(message.threadId != null) {
						stanza.textTag("thread",message.threadId);
					}
					_gthis.client.sendStanza(stanza);
				}
			}
			_gthis.publishMds();
			_gthis.client.trigger("chats/update",[_gthis]);
		});
	}
	bookmark() {
		let attr = { jid : this.chatId};
		if(this.displayName != null && this.displayName != "" && this.displayName != this.chatId) {
			attr["name"] = this.displayName;
		}
		let _gthis = this;
		this.stream.sendIq(new snikket_Stanza("iq",{ type : "set"}).tag("query",{ xmlns : "jabber:iq:roster"}).tag("item",attr).up().up(),function(response) {
			if(response.attr["type"] == "error") {
				return;
			}
			_gthis.stream.sendStanza(new snikket_Stanza("presence",{ to : _gthis.chatId, type : "subscribe", id : snikket_ID.short()}));
			if(_gthis.isTrusted()) {
				_gthis.stream.sendStanza(new snikket_Stanza("presence",{ to : _gthis.chatId, type : "subscribed", id : snikket_ID.short()}));
			}
		});
	}
	sendChatState(state,threadId) {
		let _g = 0;
		let _g1 = this.getParticipants();
		while(_g < _g1.length) {
			let recipient = _g1[_g];
			++_g;
			let stanza = new snikket_Stanza("message",{ id : snikket_ID.long(), type : "chat", from : this.client.jid.asString(), to : recipient}).tag(state,{ xmlns : "http://jabber.org/protocol/chatstates"}).up();
			if(threadId != null) {
				stanza.textTag("thread",threadId);
			}
			this.stream.sendStanza(stanza);
		}
	}
	close() {
		if(this.typingTimer != null) {
			this.typingTimer.stop();
		}
		this.uiState = 2;
		this.persistence.storeChats(this.client.accountId(),[this]);
		if(!this.isBlocked) {
			this.sendChatState("gone",null);
		}
		this.client.trigger("chats/update",[this]);
	}
}
$hx_exports["snikket"]["DirectChat"] = snikket_DirectChat;
snikket_DirectChat.__name__ = "snikket.DirectChat";
snikket_DirectChat.__super__ = snikket_Chat;
Object.assign(snikket_DirectChat.prototype, {
	__class__: snikket_DirectChat
});
class snikket_Channel extends snikket_Chat {
	constructor(client,stream,persistence,chatId,uiState,isBlocked,extensions,readUpToId,readUpToBy,disco) {
		snikket_Chat._hx_skip_constructor = true;
		super();
		snikket_Chat._hx_skip_constructor = false;
		this._hx_constructor(client,stream,persistence,chatId,uiState,isBlocked,extensions,readUpToId,readUpToBy,disco);
	}
	_hx_constructor(client,stream,persistence,chatId,uiState,isBlocked,extensions,readUpToId,readUpToBy,disco) {
		if(isBlocked == null) {
			isBlocked = false;
		}
		if(uiState == null) {
			uiState = 1;
		}
		this._nickInUse = null;
		this.forceLive = false;
		this.sync = null;
		this.inSync = true;
		this.disco = new snikket_Caps("",[],["http://jabber.org/protocol/muc"]);
		super._hx_constructor(client,stream,persistence,chatId,uiState,isBlocked,extensions,readUpToId,readUpToBy);
		if(disco != null) {
			this.disco = disco;
			if(!disco.features.includes("http://jabber.org/protocol/muc")) {
				this.forceLive = true;
			}
		}
	}
	selfPing(refresh) {
		if(this.uiState == 2) {
			this.client.sendPresence(this.getFullJid().asString(),function(stanza) {
				stanza.attr["type"] = "unavailable";
				return stanza;
			});
			return;
		}
		let _gthis = this;
		(refresh ? $bind(this,this.refreshDisco) : function(cb) {
			cb();
		})(function() {
			if(!_gthis.disco.features.includes("http://jabber.org/protocol/muc")) {
				_gthis.forceLive = true;
				return;
			}
			_gthis.stream.sendIq(new snikket_Stanza("iq",{ type : "get", to : _gthis.getFullJid().asString()}).tag("ping",{ xmlns : "urn:xmpp:ping"}).up(),function(response) {
				if(response.attr["type"] == "error") {
					let tmp = response.getChild("error");
					let err = tmp != null ? tmp.getChild(null,"urn:ietf:params:xml:ns:xmpp-stanzas") : null;
					if(err.name == "service-unavailable" || err.name == "feature-not-implemented") {
						_gthis.selfPingSuccess();
						return;
					}
					if(err.name == "remote-server-not-found" || err.name == "remote-server-timeout") {
						_gthis.selfPingSuccess();
						return;
					}
					if(err.name == "item-not-found") {
						_gthis.selfPingSuccess();
						return;
					}
					_gthis.presence = new Map([]);
					_gthis._nickInUse = null;
					_gthis.inSync = false;
					_gthis.client.trigger("chats/update",[_gthis]);
					let desiredFullJid = snikket_JID.parse(_gthis.chatId).withResource(_gthis.client.displayName());
					_gthis.client.sendPresence(desiredFullJid.asString(),function(stanza) {
						stanza.tag("x",{ xmlns : "http://jabber.org/protocol/muc"});
						if(_gthis.disco.features.includes("urn:xmpp:mam:2")) {
							stanza.tag("history",{ maxchars : "0"}).up();
						}
						stanza.up();
						return stanza;
					});
				} else {
					_gthis.selfPingSuccess();
				}
			});
		});
	}
	selfPingSuccess() {
		if(this.nickInUse() != this.client.displayName()) {
			let desiredFullJid = snikket_JID.parse(this.chatId).withResource(this.client.displayName());
			this.client.sendPresence(desiredFullJid.asString());
		}
		this.inSync = false;
		this.persistence.lastId(this.client.accountId(),this.chatId,$bind(this,this.doSync));
	}
	setPresence(resource,presence) {
		let tmp = presence != null ? presence.mucUser : null;
		let oneTen = tmp != null ? Lambda.find(tmp.allTags("status"),function(status) {
			return status.attr["code"] == "110";
		}) : null;
		if(oneTen != null) {
			this._nickInUse = resource;
		} else if(resource == this._nickInUse) {
			this._nickInUse = null;
		}
		if(presence != null && presence.mucUser != null && oneTen == null) {
			let existing = this.presence.get(resource);
			let tmp;
			if(existing != null) {
				let tmp1 = existing != null ? existing.mucUser : null;
				tmp = (tmp1 != null ? Lambda.find(tmp1.allTags("status"),function(status) {
					return status.attr["code"] == "110";
				}) : null) != null;
			} else {
				tmp = false;
			}
			if(tmp) {
				presence.mucUser.tag("status",{ code : "110"});
				this.setPresence(resource,presence);
				return;
			}
		}
		super.setPresence(resource,presence);
		let tmp1 = presence != null ? presence.mucUser : null;
		let tripleThree = tmp1 != null ? Lambda.find(tmp1.allTags("status"),function(status) {
			return status.attr["code"] == "333";
		}) : null;
		if(!this.inSync && this.sync == null && oneTen != null) {
			this.persistence.lastId(this.client.accountId(),this.chatId,$bind(this,this.doSync));
		}
		if(oneTen != null && tripleThree != null) {
			this.selfPing(true);
		}
	}
	doSync(lastId) {
		if(!this.disco.features.includes("urn:xmpp:mam:2")) {
			this.inSync = true;
			return;
		}
		if(this.sync != null) {
			return;
		}
		let threeDaysAgo = snikket_Date.format(new Date(new Date().getTime() + (-259200000.)));
		this.sync = new snikket_MessageSync(this.client,this.stream,lastId == null ? { startTime : threeDaysAgo} : { page : { after : lastId}},this.chatId);
		this.sync.setNewestPageFirst(false);
		let _gthis = this;
		this.sync.addContext(function(builder,stanza) {
			builder = _gthis.prepareIncomingMessage(builder,stanza);
			builder.syncPoint = true;
			return builder;
		});
		let chatMessages = [];
		this.sync.onMessages(function(messageList) {
			let promises = [];
			let pageChatMessages = [];
			let _g = 0;
			let _g1 = messageList.messages;
			while(_g < _g1.length) {
				let m = _g1[_g];
				++_g;
				switch(m._hx_index) {
				case 1:
					let message = m.message;
					let _g2 = 0;
					let _g3 = message.inlineHashReferences();
					while(_g2 < _g3.length) {
						let hash = _g3[_g2];
						++_g2;
						_gthis.client.fetchMediaByHash([hash],[message.from]);
					}
					pageChatMessages.push(message);
					break;
				case 2:
					let action = m.action;
					promises.push(thenshim_Promise._new(function(resolve,reject) {
						_gthis.client.moderateMessage(action).then(function(_) {
							resolve(null);
						});
					}));
					break;
				case 3:
					let update = m.update;
					promises.push(thenshim_Promise._new(function(resolve,reject) {
						_gthis.persistence.storeReaction(_gthis.client.accountId(),update,function(_) {
							resolve(null);
						});
					}));
					break;
				default:
				}
			}
			promises.push(thenshim_Promise._new(function(resolve,reject) {
				_gthis.client.storeMessages(pageChatMessages,resolve);
			}));
			thenshim_Promise.then(thenshim_PromiseTools.all(promises),function(stored) {
				let _g = 0;
				while(_g < stored.length) {
					let messages = stored[_g];
					++_g;
					if(messages != null) {
						let _g = 0;
						while(_g < messages.length) {
							let message = messages[_g];
							++_g;
							_gthis.client.notifySyncMessageHandlers(message);
							if(message != null && message.chatId() == _gthis.chatId) {
								chatMessages.push(message);
							}
							if(chatMessages.length > 1000) {
								chatMessages.shift();
							}
						}
					}
				}
				if(_gthis.sync.hasMore()) {
					_gthis.sync.fetchNext();
				} else {
					_gthis.inSync = true;
					_gthis.sync = null;
					let lastFromSync = chatMessages[chatMessages.length - 1];
					if(lastFromSync != null && (_gthis.lastMessageTimestamp() == null || Reflect.compare(lastFromSync.timestamp,_gthis.lastMessageTimestamp()) > 0)) {
						_gthis.setLastMessage(lastFromSync);
						_gthis.client.sortChats();
					}
					let serverIds = new Map([]);
					let dedupedMessages = [];
					chatMessages.reverse();
					let _g = 0;
					while(_g < chatMessages.length) {
						let m = chatMessages[_g];
						++_g;
						let tmp = serverIds.get(m.serverId);
						if(!(tmp != null && tmp)) {
							dedupedMessages.unshift(m);
							serverIds.set(m.serverId,true);
						}
					}
					let readIndex = Lambda.findIndex(dedupedMessages,function(m) {
						if(m.serverId != _gthis.readUpTo()) {
							return !m.isIncoming();
						} else {
							return true;
						}
					});
					if(readIndex < 0) {
						_gthis.setUnreadCount(_gthis.unreadCount() + dedupedMessages.length);
					} else {
						_gthis.setUnreadCount(dedupedMessages.length - readIndex - 1);
					}
					_gthis.client.trigger("chats/update",[_gthis]);
				}
			});
		});
		this.sync.onError(function(stanza) {
			_gthis.sync = null;
			if(lastId != null) {
				_gthis.doSync(null);
			} else {
				haxe_Log.trace("SYNC failed",{ fileName : "snikket/Chat.hx", lineNumber : 1114, className : "snikket.Channel", methodName : "doSync", customParams : [_gthis.chatId,stanza]});
			}
		});
		this.sync.fetchNext();
	}
	isTrusted() {
		return this.uiState != 2;
	}
	refreshDisco(callback) {
		let discoGet = new snikket_queries_DiscoInfoGet(this.chatId);
		let _gthis = this;
		discoGet.onFinished(function() {
			if(discoGet.getResult() != null) {
				_gthis.disco = discoGet.getResult();
				_gthis.persistence.storeCaps(discoGet.getResult());
				_gthis.persistence.storeChats(_gthis.client.accountId(),[_gthis]);
			}
			if(callback != null) {
				callback();
			}
		});
		this.client.sendQuery(discoGet);
	}
	preview() {
		if(this.lastMessage == null) {
			return super.preview();
		}
		return this.getParticipantDetails(this.lastMessage.senderId).displayName + ": " + super.preview();
	}
	livePresence() {
		if(this.forceLive) {
			return true;
		}
		return this._nickInUse != null;
	}
	syncing() {
		if(this.inSync) {
			return !this.livePresence();
		} else {
			return true;
		}
	}
	canAudioCall() {
		let tmp = this.disco;
		let tmp1 = tmp != null ? tmp.features : null;
		let tmp2 = tmp1 != null ? tmp1.includes("urn:xmpp:jingle:apps:rtp:audio") : null;
		if(tmp2 != null) {
			return tmp2;
		} else {
			return false;
		}
	}
	canVideoCall() {
		let tmp = this.disco;
		let tmp1 = tmp != null ? tmp.features : null;
		let tmp2 = tmp1 != null ? tmp1.includes("urn:xmpp:jingle:apps:rtp:video") : null;
		if(tmp2 != null) {
			return tmp2;
		} else {
			return false;
		}
	}
	nickInUse() {
		let tmp = this._nickInUse;
		if(tmp != null) {
			return tmp;
		} else {
			return this.client.displayName();
		}
	}
	getFullJid() {
		return snikket_JID.parse(this.chatId).withResource(this.nickInUse());
	}
	getParticipants() {
		let jid = snikket_JID.parse(this.chatId);
		let _gthis = this;
		let _g = [];
		let inlobj_iterator = function() {
			return new js_lib_HaxeIterator(_gthis.presence.keys());
		};
		let x = inlobj_iterator();
		while(x.hasNext()) {
			let x1 = x.next();
			_g.push(new snikket_JID(jid.node,jid.domain,x1).asString());
		}
		return _g;
	}
	getParticipantDetails(participantId) {
		if(participantId == this.getFullJid().asString()) {
			let chat = this.client.getDirectChat(this.client.accountId(),false);
			return new snikket_Participant(this.client.displayName(),chat.getPhoto(),chat.getPlaceholder(),true);
		} else {
			let nick = snikket_JID.parse(participantId).resource;
			let placeholderUri = snikket_Color.defaultPhoto(participantId,nick == null ? " " : nick.charAt(0));
			return new snikket_Participant(nick,null,placeholderUri,false);
		}
	}
	getMessagesBefore(beforeId,beforeTime,handler) {
		let _gthis = this;
		this.persistence.getMessagesBefore(this.client.accountId(),this.chatId,beforeId,beforeTime,function(messages) {
			if(messages.length > 0) {
				handler(messages);
			} else {
				let filter = { };
				if(beforeId != null) {
					filter.page = { before : beforeId};
				}
				let sync = new snikket_MessageSync(_gthis.client,_gthis.stream,filter,_gthis.chatId);
				sync.addContext(function(builder,stanza) {
					builder = _gthis.prepareIncomingMessage(builder,stanza);
					builder.syncPoint = false;
					return builder;
				});
				_gthis.fetchFromSync(sync,handler);
			}
		});
	}
	getMessagesAfter(afterId,afterTime,handler) {
		if(afterId == this.lastMessageId() && !this.syncing()) {
			handler([]);
			return;
		}
		let _gthis = this;
		this.persistence.getMessagesAfter(this.client.accountId(),this.chatId,afterId,afterTime,function(messages) {
			if(messages.length > 0) {
				handler(messages);
			} else {
				let filter = { };
				if(afterId != null) {
					filter.page = { after : afterId};
				}
				let sync = new snikket_MessageSync(_gthis.client,_gthis.stream,filter,_gthis.chatId);
				sync.addContext(function(builder,stanza) {
					builder = _gthis.prepareIncomingMessage(builder,stanza);
					builder.syncPoint = false;
					return builder;
				});
				_gthis.fetchFromSync(sync,handler);
			}
		});
	}
	getMessagesAround(aroundId,aroundTime,handler) {
		this.persistence.getMessagesAround(this.client.accountId(),this.chatId,aroundId,aroundTime,function(messages) {
			if(messages.length > 0) {
				handler(messages);
			} else {
				handler([]);
			}
		});
	}
	prepareIncomingMessage(message,stanza) {
		message.syncPoint = !this.syncing();
		if(message.type == 0) {
			message.type = 3;
		}
		message.sender = snikket_JID.parse(stanza.attr["from"]);
		if(message.get_senderId() == this.getFullJid().asString()) {
			message.recipients = message.replyTo;
			message.direction = 1;
		}
		return message;
	}
	prepareOutgoingMessage(message) {
		message.type = 2;
		let tmp = message.timestamp;
		message.timestamp = tmp != null ? tmp : snikket_Date.format(new Date());
		message.direction = 1;
		message.from = this.client.jid;
		message.sender = this.getFullJid();
		message.replyTo = [message.sender];
		message.to = snikket_JID.parse(this.chatId);
		message.recipients = [message.to];
		return message;
	}
	correctMessage(localId,message) {
		let toSendId = message.localId;
		message = this.prepareOutgoingMessage(message);
		let tmp = message.build();
		message.versions = [tmp];
		message.localId = localId;
		let _gthis = this;
		this.client.storeMessages([message.build()],function(corrected) {
			let tmp = corrected[0].localId == localId ? corrected[0].versions : [message.build()];
			message.versions = tmp;
			message.localId = toSendId;
			_gthis.client.sendStanza(message.build().asStanza());
			_gthis.client.notifyMessageHandlers(corrected[0],1);
			let tmp1 = _gthis.lastMessage;
			if(localId == (tmp1 != null ? tmp1.localId : null)) {
				_gthis.setLastMessage(corrected[0]);
				_gthis.client.trigger("chats/update",[_gthis]);
			}
		});
	}
	sendMessage(message) {
		if(this.typingTimer != null) {
			this.typingTimer.stop();
		}
		this.client.chatActivity(this);
		message = this.prepareOutgoingMessage(message);
		let stanza = message.build().asStanza();
		stanza.attr["from"] = this.getFullJid().asString();
		let fromStanza = snikket_Message.fromStanza(stanza,this.client.jid).parsed;
		stanza.attr["from"] = this.client.jid.asString();
		let _gthis = this;
		switch(fromStanza._hx_index) {
		case 1:
			let _g = fromStanza.message;
			if(this.isActive != null) {
				this.isActive = true;
				this.activeThread = message.threadId;
				stanza.tag("active",{ xmlns : "http://jabber.org/protocol/chatstates"}).up();
			}
			this.client.storeMessages([message.build()],function(stored) {
				_gthis.client.sendStanza(stanza);
				_gthis.setLastMessage(stored[0]);
				_gthis.client.notifyMessageHandlers(stored[0],stored[0].versions.length > 1 ? 1 : 0);
				_gthis.client.trigger("chats/update",[_gthis]);
			});
			break;
		case 3:
			let update = fromStanza.update;
			this.persistence.storeReaction(this.client.accountId(),update,function(stored) {
				_gthis.client.sendStanza(stanza);
				if(stored != null) {
					_gthis.client.notifyMessageHandlers(stored,2);
				}
			});
			break;
		default:
			haxe_Log.trace("Invalid message",{ fileName : "snikket/Chat.hx", lineNumber : 1314, className : "snikket.Channel", methodName : "sendMessage", customParams : [fromStanza]});
			throw haxe_Exception.thrown("Trying to send invalid message.");
		}
	}
	removeReaction(m,reaction) {
		if(((reaction) instanceof snikket_CustomEmojiReaction)) {
			if(reaction.envelopeId == null) {
				throw haxe_Exception.thrown("Cannot remove custom emoji reaction without envelopeId");
			}
			let correct = m.reply();
			correct.localId = snikket_ID.long();
			correct.setHtml("");
			correct.text = null;
			this.correctMessage(reaction.envelopeId,correct);
			return;
		}
		let reactions = [];
		let _gthis = this;
		let jsIterator = m.reactions.entries();
		let _g_jsIterator = jsIterator;
		let _g_lastStep = jsIterator.next();
		while(!_g_lastStep.done) {
			let v = _g_lastStep.value;
			_g_lastStep = _g_jsIterator.next();
			let _g_key = v[0];
			let _g_value = v[1];
			let areaction = _g_key;
			let reacts = _g_value;
			if(areaction != reaction.key) {
				let react = Lambda.find(reacts,function(r) {
					return r.senderId == _gthis.getFullJid().asString();
				});
				if(react != null && !((react) instanceof snikket_CustomEmojiReaction)) {
					reactions.push(react);
				}
			}
		}
		let update = new snikket_ReactionUpdate(snikket_ID.long(),m.serverId,m.chatId(),null,m.chatId(),this.getFullJid().asString(),snikket_Date.format(new Date()),reactions,0);
		this.persistence.storeReaction(this.client.accountId(),update,function(stored) {
			let stanza = update.asStanza();
			stanza.attr["to"] = _gthis.chatId;
			_gthis.client.sendStanza(stanza);
			if(stored != null) {
				_gthis.client.notifyMessageHandlers(stored,2);
			}
		});
	}
	lastMessageId() {
		let tmp = this.lastMessage;
		if(tmp != null) {
			return tmp.serverId;
		} else {
			return null;
		}
	}
	markReadUpTo(message) {
		let _gthis = this;
		this.markReadUpToMessage(message,function() {
			let stanza = new snikket_Stanza("message",{ to : _gthis.chatId, id : snikket_ID.long(), type : "groupchat"}).tag("displayed",{ xmlns : "urn:xmpp:chat-markers:0", id : message.serverId}).up();
			if(message.threadId != null) {
				stanza.textTag("thread",message.threadId);
			}
			_gthis.client.sendStanza(stanza);
			_gthis.publishMds();
			_gthis.client.trigger("chats/update",[_gthis]);
		});
	}
	bookmark() {
		let _gthis = this;
		this.stream.sendIq(new snikket_Stanza("iq",{ type : "set"}).tag("pubsub",{ xmlns : "http://jabber.org/protocol/pubsub"}).tag("publish",{ node : "urn:xmpp:bookmarks:1"}).tag("item",{ id : this.chatId}).tag("conference",{ xmlns : "urn:xmpp:bookmarks:1", name : this.getDisplayName(), autojoin : this.uiState == 2 ? "false" : "true"}).textTag("nick",this.client.displayName()).addChild(this.extensions).up().up().tag("publish-options").tag("x",{ xmlns : "jabber:x:data", type : "submit"}).tag("field",{ "var" : "FORM_TYPE", type : "hidden"}).textTag("value","http://jabber.org/protocol/pubsub#publish-options").up().tag("field",{ "var" : "pubsub#persist_items"}).textTag("value","true").up().tag("field",{ "var" : "pubsub#max_items"}).textTag("value","max").up().tag("field",{ "var" : "pubsub#send_last_published_item"}).textTag("value","never").up().tag("field",{ "var" : "pubsub#access_model"}).textTag("value","whitelist").up().tag("field",{ "var" : "pubsub#notify_delete"}).textTag("value","true").up().tag("field",{ "var" : "pubsub#notify_retract"}).textTag("value","true").up().up().up().up().up(),function(response) {
			if(response.attr["type"] == "error") {
				let tmp = response.getChild("error");
				let preconditionError = tmp != null ? tmp.getChild("precondition-not-met","http://jabber.org/protocol/pubsub#errors") : null;
				if(preconditionError != null) {
					_gthis.stream.sendIq(new snikket_Stanza("iq",{ type : "set"}).tag("pubsub",{ xmlns : "http://jabber.org/protocol/pubsub#owner"}).tag("configure",{ node : "urn:xmpp:bookmarks:1"}).tag("x",{ xmlns : "jabber:x:data", type : "submit"}).tag("field",{ "var" : "FORM_TYPE", type : "hidden"}).textTag("value","http://jabber.org/protocol/pubsub#publish-options").up().tag("field",{ "var" : "pubsub#persist_items"}).textTag("value","true").up().tag("field",{ "var" : "pubsub#max_items"}).textTag("value","max").up().tag("field",{ "var" : "pubsub#send_last_published_item"}).textTag("value","never").up().tag("field",{ "var" : "pubsub#access_model"}).textTag("value","whitelist").up().tag("field",{ "var" : "pubsub#notify_delete"}).textTag("value","true").up().tag("field",{ "var" : "pubsub#notify_retract"}).textTag("value","true").up().up().up().up(),function(response) {
						if(response.attr["type"] == "result") {
							_gthis.bookmark();
						}
					});
				}
			}
		});
	}
	sendChatState(state,threadId) {
		let stanza = new snikket_Stanza("message",{ id : snikket_ID.long(), type : "groupchat", from : this.client.jid.asString(), to : this.chatId}).tag(state,{ xmlns : "http://jabber.org/protocol/chatstates"}).up();
		if(threadId != null) {
			stanza.textTag("thread",threadId);
		}
		this.stream.sendStanza(stanza);
	}
	close() {
		if(this.typingTimer != null) {
			this.typingTimer.stop();
		}
		this.uiState = 2;
		this.persistence.storeChats(this.client.accountId(),[this]);
		this.selfPing(false);
		this.bookmark();
		this.sendChatState("gone",null);
		this.client.trigger("chats/update",[this]);
	}
}
$hx_exports["snikket"]["Channel"] = snikket_Channel;
snikket_Channel.__name__ = "snikket.Channel";
snikket_Channel.__super__ = snikket_Chat;
Object.assign(snikket_Channel.prototype, {
	__class__: snikket_Channel
});
class snikket_AvailableChat {
	constructor(chatId,displayName,note,caps) {
		this.chatId = chatId;
		this.displayName = displayName;
		this.note = note;
		this.caps = caps;
	}
	isChannel() {
		return this.caps.isChannel(this.chatId);
	}
}
$hx_exports["snikket"]["AvailableChat"] = snikket_AvailableChat;
snikket_AvailableChat.__name__ = "snikket.AvailableChat";
Object.assign(snikket_AvailableChat.prototype, {
	__class__: snikket_AvailableChat
});
class snikket_SerializedChat {
	constructor(chatId,trusted,avatarSha1,presence,displayName,uiState,isBlocked,extensions,readUpToId,readUpToBy,disco,klass) {
		this.chatId = chatId;
		this.trusted = trusted;
		this.avatarSha1 = avatarSha1;
		this.presence = presence;
		this.displayName = displayName;
		let tmp = uiState;
		this.uiState = tmp != null ? tmp : 1;
		let tmp1 = isBlocked;
		this.isBlocked = tmp1 != null && tmp1;
		let tmp2 = extensions;
		this.extensions = tmp2 != null ? tmp2 : "<extensions xmlns='urn:app:bookmarks:1' />";
		this.readUpToId = readUpToId;
		this.readUpToBy = readUpToBy;
		this.disco = disco;
		this.klass = klass;
	}
	toChat(client,stream,persistence) {
		let extensionsStanza = snikket_Stanza.fromXml(Xml.parse(this.extensions));
		let chat;
		if(this.klass == "DirectChat") {
			chat = new snikket_DirectChat(client,stream,persistence,this.chatId,this.uiState,this.isBlocked,extensionsStanza,this.readUpToId,this.readUpToBy);
		} else if(this.klass == "Channel") {
			let channel = new snikket_Channel(client,stream,persistence,this.chatId,this.uiState,this.isBlocked,extensionsStanza,this.readUpToId,this.readUpToBy);
			let tmp = this.disco;
			channel.disco = tmp != null ? tmp : new snikket_Caps("",[],["http://jabber.org/protocol/muc"]);
			chat = channel;
		} else {
			throw haxe_Exception.thrown("Unknown class of " + this.chatId + ": " + this.klass);
		}
		if(this.displayName != null) {
			chat.displayName = this.displayName;
		}
		if(this.avatarSha1 != null) {
			chat.setAvatarSha1(this.avatarSha1);
		}
		chat.setTrusted(this.trusted);
		let jsIterator = this.presence.entries();
		let _g_jsIterator = jsIterator;
		let _g_lastStep = jsIterator.next();
		while(!_g_lastStep.done) {
			let v = _g_lastStep.value;
			_g_lastStep = _g_jsIterator.next();
			let _g_key = v[0];
			let _g_value = v[1];
			let resource = _g_key;
			let p = _g_value;
			chat.setPresence(resource,p);
		}
		return chat;
	}
}
$hx_exports["snikket"]["SerializedChat"] = snikket_SerializedChat;
snikket_SerializedChat.__name__ = "snikket.SerializedChat";
Object.assign(snikket_SerializedChat.prototype, {
	__class__: snikket_SerializedChat
});
class snikket_ChatAttachment {
	constructor(name,mime,size,uris,hashes) {
		this.name = name;
		this.mime = mime;
		this.size = size;
		this.uris = uris;
		this.hashes = hashes;
	}
}
$hx_exports["snikket"]["ChatAttachment"] = snikket_ChatAttachment;
snikket_ChatAttachment.__name__ = "snikket.ChatAttachment";
Object.assign(snikket_ChatAttachment.prototype, {
	__class__: snikket_ChatAttachment
});
class snikket_ChatMessage {
	constructor(params) {
		this.localId = params.localId;
		this.serverId = params.serverId;
		this.serverIdBy = params.serverIdBy;
		let tmp = params.type;
		this.type = tmp != null ? tmp : 0;
		let tmp1 = params.syncPoint;
		this.syncPoint = tmp1 != null && tmp1;
		this.replyId = params.replyId;
		this.timestamp = params.timestamp;
		this.to = params.to;
		this.from = params.from;
		this.senderId = params.senderId;
		let tmp2 = params.recipients;
		this.recipients = tmp2 != null ? tmp2 : [];
		let tmp3 = params.replyTo;
		this.replyTo = tmp3 != null ? tmp3 : [];
		this.replyToMessage = params.replyToMessage;
		this.threadId = params.threadId;
		let tmp4 = params.attachments;
		this.attachments = tmp4 != null ? tmp4 : [];
		let tmp5 = params.reactions;
		this.reactions = tmp5 != null ? tmp5 : new Map([]);
		this.text = params.text;
		this.lang = params.lang;
		let tmp6 = params.direction;
		this.direction = tmp6 != null ? tmp6 : 1;
		let tmp7 = params.status;
		this.status = tmp7 != null ? tmp7 : 0;
		let tmp8 = params.versions;
		this.versions = tmp8 != null ? tmp8 : [];
		let tmp9 = params.payloads;
		this.payloads = tmp9 != null ? tmp9 : [];
		this.stanza = params.stanza;
	}
	reply() {
		let m = new snikket_ChatMessageBuilder();
		m.type = this.type;
		let tmp = this.threadId;
		m.threadId = tmp != null ? tmp : snikket_ID.long();
		m.replyToMessage = this;
		return m;
	}
	getReplyId() {
		if(this.replyId != null) {
			return this.replyId;
		}
		if(this.type == 2 || this.type == 3) {
			return this.serverId;
		} else {
			return this.localId;
		}
	}
	set_replyToMessage(m) {
		let rtm = this.replyToMessage;
		if(rtm == null) {
			throw haxe_Exception.thrown("Cannot hydrate null replyToMessage");
		}
		if(rtm.serverId != null && rtm.serverId != m.serverId) {
			throw haxe_Exception.thrown("Hydrate serverId mismatch");
		}
		if(rtm.localId != null && rtm.localId != m.localId) {
			throw haxe_Exception.thrown("Hydrate localId mismatch");
		}
		return this.replyToMessage = m;
	}
	set_reactions(r) {
		let _gthis = this;
		if(this.reactions != null && !Lambda.empty({ iterator : function() {
			return new js_lib_HaxeIterator(_gthis.reactions.keys());
		}})) {
			throw haxe_Exception.thrown("Reactions already hydrated");
		}
		return this.reactions = r;
	}
	inlineHashReferences() {
		let result = [];
		let tmp = Lambda.find(this.payloads,function(p) {
			if(p.attr["xmlns"] == "http://jabber.org/protocol/xhtml-im") {
				return p.name == "html";
			} else {
				return false;
			}
		});
		let htmlBody = tmp != null ? tmp.getChild("body","http://www.w3.org/1999/xhtml") : null;
		if(htmlBody != null) {
			htmlBody.traverse(function(child) {
				if(child.name == "img") {
					let src = child.attr["src"];
					if(src != null) {
						let hash = snikket_Hash.fromUri(src);
						if(hash != null) {
							let x = hash;
							result.push(x);
						}
					}
					return true;
				}
				return false;
			});
		}
		return result;
	}
	html() {
		let tmp = Lambda.find(this.payloads,function(p) {
			if(p.attr["xmlns"] == "http://jabber.org/protocol/xhtml-im") {
				return p.name == "html";
			} else {
				return false;
			}
		});
		let htmlBody = tmp != null ? tmp.getChild("body","http://www.w3.org/1999/xhtml") : null;
		if(htmlBody != null) {
			let _this = htmlBody.getChildren();
			let result = new Array(_this.length);
			let _g = 0;
			let _g1 = _this.length;
			while(_g < _g1) {
				let i = _g++;
				result[i] = _this[i].traverse(function(child) {
					if(child.name == "img") {
						let src = child.attr["src"];
						if(src != null) {
							let hash = snikket_Hash.fromUri(src);
							if(hash != null) {
								child.attr["src"] = hash.toUri();
							}
						}
						return true;
					}
					return false;
				}).serialize();
			}
			return result.join("");
		}
		let tmp1 = this.text;
		let codepoints = snikket_StringUtil.codepointArray(tmp1 != null ? tmp1 : "");
		let _gthis = this;
		let _g = [];
		let _g1 = 0;
		let _g2 = this.payloads;
		while(_g1 < _g2.length) {
			let v = _g2[_g1];
			++_g1;
			if(v.attr["xmlns"] == "urn:xmpp:fallback:0" && ((v.attr["for"] == "jabber:x:oob" || v.attr["for"] == "urn:xmpp:sims:1") && _gthis.attachments.length > 0 || _gthis.replyToMessage != null && v.attr["for"] == "urn:xmpp:reply:0" || v.attr["for"] == "http://jabber.org/protocol/address")) {
				_g.push(v);
			}
		}
		let _this = _g;
		let result = new Array(_this.length);
		let _g3 = 0;
		let _g4 = _this.length;
		while(_g3 < _g4) {
			let i = _g3++;
			result[i] = _this[i].getChild("body");
		}
		let _this1 = result;
		let result1 = new Array(_this1.length);
		let _g5 = 0;
		let _g6 = _this1.length;
		while(_g5 < _g6) {
			let i = _g5++;
			let b = _this1[i];
			let fallbacks;
			if(b == null) {
				fallbacks = null;
			} else {
				let tmp = b.attr["start"];
				let tmp1 = Std.parseInt(tmp != null ? tmp : "0");
				let tmp2 = b.attr["end"];
				let tmp3 = Std.parseInt(tmp2 != null ? tmp2 : codepoints.length == null ? "null" : "" + codepoints.length);
				fallbacks = { start : tmp1 != null ? tmp1 : 0, end : tmp3 != null ? tmp3 : codepoints.length};
			}
			result1[i] = fallbacks;
		}
		let _g7 = [];
		let _g8 = 0;
		let _g9 = result1;
		while(_g8 < _g9.length) {
			let v = _g9[_g8];
			++_g8;
			if(v != null) {
				_g7.push(v);
			}
		}
		let fallbacks = _g7;
		fallbacks.sort(function(x,y) {
			return y.start - x.start;
		});
		let _g10 = 0;
		while(_g10 < fallbacks.length) {
			let fallback = fallbacks[_g10];
			++_g10;
			codepoints.splice(fallback.start,fallback.end - fallback.start);
		}
		let body = codepoints.join("");
		if(Lambda.find(this.payloads,function(p) {
			if(p.attr["xmlns"] == "urn:xmpp:styling:0") {
				return p.name == "unstyled";
			} else {
				return false;
			}
		}) == null) {
			let _g = [];
			let x = $getIterator(snikket_XEP0393.parse(body));
			while(x.hasNext()) {
				let x1 = x.next();
				_g.push(x1.toString());
			}
			return _g.join("");
		} else {
			return StringTools.htmlEscape(body);
		}
	}
	chatId() {
		if(this.isIncoming()) {
			let _this = this.replyTo;
			let result = new Array(_this.length);
			let _g = 0;
			let _g1 = _this.length;
			while(_g < _g1) {
				let i = _g++;
				result[i] = _this[i].asBare().asString();
			}
			return result.join("\n");
		} else {
			let _this = this.recipients;
			let result = new Array(_this.length);
			let _g = 0;
			let _g1 = _this.length;
			while(_g < _g1) {
				let i = _g++;
				result[i] = _this[i].asString();
			}
			return result.join("\n");
		}
	}
	account() {
		let tmp;
		if(!this.isIncoming()) {
			let tmp1 = this.from;
			let tmp2 = tmp1 != null ? tmp1.asBare() : null;
			tmp = tmp2 != null ? tmp2.asString() : null;
		} else {
			let tmp1 = this.to;
			let tmp2 = tmp1 != null ? tmp1.asBare() : null;
			tmp = tmp2 != null ? tmp2.asString() : null;
		}
		if(tmp != null) {
			return tmp;
		} else {
			throw haxe_Exception.thrown("from or to is null");
		}
	}
	isIncoming() {
		return this.direction == 0;
	}
	threadIcon() {
		if(this.threadId == null) {
			return null;
		} else {
			return snikket_Identicon.svg(this.threadId);
		}
	}
	callStatus() {
		let tmp = Lambda.find(this.payloads,function(el) {
			return el.attr["xmlns"] == "urn:xmpp:jingle-message:0";
		});
		if(tmp != null) {
			return tmp.name;
		} else {
			return null;
		}
	}
	callSid() {
		let tmp = Lambda.find(this.payloads,function(el) {
			return el.attr["xmlns"] == "urn:xmpp:jingle-message:0";
		});
		let tmp1 = tmp != null ? tmp.attr : null;
		if(tmp1 != null) {
			return tmp1["id"];
		} else {
			return null;
		}
	}
	callDuration() {
		if(this.versions.length < 2) {
			return null;
		}
		let startedStr = this.versions[this.versions.length - 1].timestamp;
		let _g = this.callStatus();
		if(_g == null) {
			return null;
		} else {
			switch(_g) {
			case "finish":
				let endedStr = this.versions[0].timestamp;
				if(startedStr == null || endedStr == null) {
					return null;
				}
				let started = datetime_utils_DateTimeUtils.fromString(startedStr);
				let ended = datetime_utils_DateTimeUtils.fromString(endedStr);
				let duration = datetime_DateTimeInterval.create(started,ended - 62135596800.0 + 62135596800.0);
				return datetime_utils_DateTimeIntervalUtils.strftime(duration,"%I:%S");
			case "proceed":
				if(startedStr == null) {
					return null;
				}
				let started1 = datetime_utils_DateTimeUtils.fromString(startedStr);
				let ended1 = Math.floor(new Date().getTime() / 1000) + 62135596800.0;
				let duration1 = datetime_DateTimeInterval.create(started1,ended1 - 62135596800.0 + 62135596800.0);
				return datetime_utils_DateTimeIntervalUtils.strftime(duration1,"%I:%S");
			default:
				return null;
			}
		}
	}
	asStanza() {
		if(this.stanza != null) {
			return this.stanza;
		}
		let body = this.text;
		let attrs = { type : this.type == 2 ? "groupchat" : "chat"};
		if(this.from != null) {
			attrs["from"] = this.from.asString();
		}
		if(this.to != null) {
			attrs["to"] = this.to.asString();
		}
		if(this.localId != null) {
			attrs["id"] = this.localId;
		}
		let stanza = new snikket_Stanza("message",attrs);
		if(this.versions.length > 0 && this.versions[this.versions.length - 1].localId != null) {
			stanza.tag("replace",{ xmlns : "urn:xmpp:message-correct:0", id : this.versions[this.versions.length - 1].localId}).up();
		}
		if(this.threadId != null) {
			stanza.textTag("thread",this.threadId);
		}
		if(this.recipients.length > 1) {
			let addresses = stanza.tag("addresses",{ xmlns : "http://jabber.org/protocol/address"});
			let _g = 0;
			let _g1 = this.recipients;
			while(_g < _g1.length) {
				let recipient = _g1[_g];
				++_g;
				addresses.tag("address",{ type : "to", jid : recipient.asString(), delivered : "true"}).up();
			}
			addresses.up();
		} else if(this.recipients.length == 1 && this.to == null) {
			attrs["to"] = this.recipients[0].asString();
		}
		let replyToM = this.replyToMessage;
		let _gthis = this;
		if(replyToM != null) {
			let replyId = replyToM.getReplyId();
			if(body != null) {
				let tmp = replyToM.text;
				let tmp1 = tmp != null ? tmp.split("\n") : null;
				let lines = tmp1 != null ? tmp1 : [];
				let quoteText = "";
				let _g = 0;
				while(_g < lines.length) {
					let line = lines[_g];
					++_g;
					if(!new EReg("^(?:> ?){3,}","").match(line)) {
						if(line.charAt(0) == ">") {
							quoteText += ">" + line + "\n";
						} else {
							quoteText += "> " + line + "\n";
						}
					}
				}
				let reaction = snikket_EmojiUtil.isEmoji(StringTools.trim(body)) ? StringTools.trim(body) : null;
				body = quoteText + body;
				if(replyId != null) {
					let codepoints = snikket_StringUtil.codepointArray(quoteText);
					if(reaction != null) {
						let addedReactions = new Map([]);
						stanza.tag("reactions",{ xmlns : "urn:xmpp:reactions:0", id : replyId});
						stanza.textTag("reaction",reaction);
						addedReactions.set(reaction,true);
						let jsIterator = replyToM.reactions.entries();
						let _g_jsIterator = jsIterator;
						let _g_lastStep = jsIterator.next();
						while(!_g_lastStep.done) {
							let v = _g_lastStep.value;
							_g_lastStep = _g_jsIterator.next();
							let _g_key = v[0];
							let _g_value = v[1];
							let areaction = _g_key;
							let reactions = _g_value;
							let tmp = addedReactions.get(areaction);
							if(!(tmp != null && tmp) && Lambda.find(reactions,function(r) {
								return r.senderId == _gthis.senderId;
							}) != null) {
								addedReactions.set(areaction,true);
								stanza.textTag("reaction",areaction);
							}
						}
						stanza.up();
						stanza.tag("fallback",{ xmlns : "urn:xmpp:fallback:0", "for" : "urn:xmpp:reactions:0"}).tag("body").up().up();
					}
					let tmp = codepoints.length == null ? "null" : "" + codepoints.length;
					stanza.tag("fallback",{ xmlns : "urn:xmpp:fallback:0", "for" : "urn:xmpp:reply:0"}).tag("body",{ start : "0", end : tmp}).up().up();
				}
			}
			if(replyId != null) {
				let tmp = replyToM.from;
				stanza.tag("reply",{ xmlns : "urn:xmpp:reply:0", to : tmp != null ? tmp.asString() : null, id : replyId}).up();
			}
		}
		let _g = 0;
		let _g1 = this.attachments;
		while(_g < _g1.length) {
			let attachment = _g1[_g];
			++_g;
			stanza.tag("reference",{ xmlns : "urn:xmpp:reference:0", type : "data"}).tag("media-sharing",{ xmlns : "urn:xmpp:sims:1"});
			stanza.tag("file",{ xmlns : "urn:xmpp:jingle:apps:file-transfer:5"});
			if(attachment.name != null) {
				stanza.textTag("name",attachment.name);
			}
			stanza.textTag("media-type",attachment.mime);
			if(attachment.size != null) {
				stanza.textTag("size",attachment.size == null ? "null" : "" + attachment.size);
			}
			let _g2 = 0;
			let _g3 = attachment.hashes;
			while(_g2 < _g3.length) {
				let hash = _g3[_g2];
				++_g2;
				stanza.textTag("hash",haxe_crypto_Base64.encode(haxe_io_Bytes.ofData(hash.hash)),{ xmlns : "urn:xmpp:hashes:2", algo : hash.algorithm});
			}
			stanza.up();
			stanza.tag("sources");
			let _g4 = 0;
			let _g5 = attachment.uris;
			while(_g4 < _g5.length) {
				let uri = _g5[_g4];
				++_g4;
				stanza.tag("reference",{ xmlns : "urn:xmpp:reference:0", type : "data", uri : uri}).up();
			}
			stanza.up().up().up();
			if(attachment.uris.length > 0) {
				stanza.tag("x",{ xmlns : "jabber:x:oob"}).textTag("url",attachment.uris[0]).up();
				if(body == null) {
					body = "";
				}
				let codepoints = snikket_StringUtil.codepointArray(body);
				let start = codepoints.length;
				let end = start + attachment.uris[0].length;
				if(body != "") {
					body += "\n";
					++end;
				}
				body += attachment.uris[0];
				stanza.tag("fallback",{ xmlns : "urn:xmpp:fallback:0", "for" : "jabber:x:oob"}).tag("body",{ start : start == null ? "null" : "" + start, end : end == null ? "null" : "" + end}).up().up();
			}
		}
		if(body != null) {
			stanza.textTag("body",body);
		}
		let _g2 = 0;
		let _g3 = this.payloads;
		while(_g2 < _g3.length) {
			let payload = _g3[_g2];
			++_g2;
			stanza.addDirectChild(snikket_Node.Element(payload));
		}
		return stanza;
	}
	static fromStanza(stanza,localJid,addContext) {
		let _g = snikket_Message.fromStanza(stanza,localJid,addContext).parsed;
		if(_g._hx_index == 1) {
			let message = _g.message;
			return message;
		} else {
			return null;
		}
	}
}
$hx_exports["snikket"]["ChatMessage"] = snikket_ChatMessage;
snikket_ChatMessage.__name__ = "snikket.ChatMessage";
Object.assign(snikket_ChatMessage.prototype, {
	__class__: snikket_ChatMessage
});
class snikket_ChatMessageBuilder {
	constructor(params) {
		this.stanza = null;
		this.payloads = [];
		this.versions = [];
		this.status = 0;
		this.direction = 0;
		this.lang = null;
		this.text = null;
		this.reactions = new Map([]);
		this.attachments = [];
		this.threadId = null;
		this.replyToMessage = null;
		this.senderId = null;
		this.replyTo = [];
		this.recipients = [];
		this.sender = null;
		this.from = null;
		this.to = null;
		this.timestamp = null;
		this.replyId = null;
		this.syncPoint = false;
		this.type = 0;
		this.serverIdBy = null;
		this.serverId = null;
		this.localId = null;
		this.localId = params != null ? params.localId : null;
		this.serverId = params != null ? params.serverId : null;
		this.serverIdBy = params != null ? params.serverIdBy : null;
		let tmp = params != null ? params.type : null;
		this.type = tmp != null ? tmp : 0;
		let tmp1 = params != null ? params.syncPoint : null;
		this.syncPoint = tmp1 != null && tmp1;
		this.replyId = params != null ? params.replyId : null;
		this.timestamp = params != null ? params.timestamp : null;
		this.senderId = params != null ? params.senderId : null;
		this.replyToMessage = params != null ? params.replyToMessage : null;
		this.threadId = params != null ? params.threadId : null;
		let tmp2 = params != null ? params.attachments : null;
		this.attachments = tmp2 != null ? tmp2 : [];
		let tmp3 = params != null ? params.reactions : null;
		this.reactions = tmp3 != null ? tmp3 : new Map([]);
		this.text = params != null ? params.text : null;
		this.lang = params != null ? params.lang : null;
		let tmp4 = params != null ? params.direction : null;
		this.direction = tmp4 != null ? tmp4 : 1;
		let tmp5 = params != null ? params.status : null;
		this.status = tmp5 != null ? tmp5 : 0;
		let tmp6 = params != null ? params.versions : null;
		this.versions = tmp6 != null ? tmp6 : [];
		let tmp7 = params != null ? params.payloads : null;
		this.payloads = tmp7 != null ? tmp7 : [];
		let html = params != null ? params.html : null;
		if(html != null) {
			this.setHtml(html);
		}
	}
	attachSims(sims) {
		let mime = sims.findText("{urn:xmpp:jingle:apps:file-transfer:5}/media-type#");
		if(mime == null) {
			mime = sims.findText("{urn:xmpp:jingle:apps:file-transfer:3}/media-type#");
		}
		if(mime == null) {
			mime = "application/octet-stream";
		}
		let name = sims.findText("{urn:xmpp:jingle:apps:file-transfer:5}/name#");
		if(name == null) {
			name = sims.findText("{urn:xmpp:jingle:apps:file-transfer:3}/name#");
		}
		let size = sims.findText("{urn:xmpp:jingle:apps:file-transfer:5}/size#");
		if(size == null) {
			size = sims.findText("{urn:xmpp:jingle:apps:file-transfer:3}/size#");
		}
		let tmp = sims.getChild("file","urn:xmpp:jingle:apps:file-transfer:5");
		let tmp1 = tmp != null ? tmp : sims.getChild("file","urn:xmpp:jingle:apps:file-transfer:3");
		let tmp2 = tmp1 != null ? tmp1.allTags("hash","urn:xmpp:hashes:2") : null;
		let _this = tmp2 != null ? tmp2 : [];
		let result = new Array(_this.length);
		let _g = 0;
		let _g1 = _this.length;
		while(_g < _g1) {
			let i = _g++;
			let hash = _this[i];
			let tmp = hash.attr["algo"];
			result[i] = new snikket_Hash(tmp != null ? tmp : "",haxe_crypto_Base64.decode(hash.getText()).b.bufferValue);
		}
		let hashes = result;
		let sources = sims.getChild("sources");
		let tmp3 = sources != null ? sources.allTags("reference","urn:xmpp:reference:0") : null;
		let _this1 = tmp3 != null ? tmp3 : [];
		let result1 = new Array(_this1.length);
		let _g2 = 0;
		let _g3 = _this1.length;
		while(_g2 < _g3) {
			let i = _g2++;
			let tmp = _this1[i].attr["uri"];
			result1[i] = tmp != null ? tmp : "";
		}
		let _g4 = [];
		let _g5 = 0;
		let _g6 = result1;
		while(_g5 < _g6.length) {
			let v = _g6[_g5];
			++_g5;
			if(v != "") {
				_g4.push(v);
			}
		}
		let uris = _g4;
		if(uris.length > 0) {
			this.attachments.push(new snikket_ChatAttachment(name,mime,size == null ? null : Std.parseInt(size),uris,hashes));
		}
	}
	addAttachment(attachment) {
		this.attachments.push(attachment);
	}
	setHtml(html) {
		let htmlEl = new snikket_Stanza("html",{ xmlns : "http://jabber.org/protocol/xhtml-im"});
		let body = new snikket_Stanza("body",{ xmlns : "http://www.w3.org/1999/xhtml"});
		htmlEl.addChild(body);
		let nodes = htmlparser_HtmlParser.run(html,true);
		let _g = 0;
		while(_g < nodes.length) {
			let node = nodes[_g];
			++_g;
			let el = snikket_Util_downcast(node,htmlparser_HtmlNodeElement);
			if(el != null && (el.name == "html" || el.name == "body")) {
				let _g = 0;
				let _g1 = el.nodes;
				while(_g < _g1.length) {
					let inner = _g1[_g];
					++_g;
					body.addDirectChild(this.htmlToNode(inner));
				}
			} else {
				body.addDirectChild(this.htmlToNode(node));
			}
		}
		let htmlIdx = Lambda.findIndex(this.payloads,function(p) {
			if(p.attr["xmlns"] == "http://jabber.org/protocol/xhtml-im") {
				return p.name == "html";
			} else {
				return false;
			}
		});
		if(htmlIdx >= 0) {
			this.payloads.splice(htmlIdx,1);
		}
		this.payloads.push(htmlEl);
		this.text = snikket_XEP0393.render(body);
	}
	htmlToNode(node) {
		let txt = snikket_Util_downcast(node,htmlparser_HtmlNodeText);
		if(txt != null) {
			return snikket_Node.CData(new snikket_TextNode(txt.toText()));
		}
		let el = snikket_Util_downcast(node,htmlparser_HtmlNodeElement);
		if(el != null) {
			let s = new snikket_Stanza(el.name,{ });
			let _g = 0;
			let _g1 = el.attributes;
			while(_g < _g1.length) {
				let attr = _g1[_g];
				++_g;
				s.attr[attr.name] = attr.value;
			}
			let _g2 = 0;
			let _g3 = el.nodes;
			while(_g2 < _g3.length) {
				let child = _g3[_g2];
				++_g2;
				s.addDirectChild(this.htmlToNode(child));
			}
			return snikket_Node.Element(s);
		}
		throw haxe_Exception.thrown("node was neither text nor element?");
	}
	chatId() {
		if(this.isIncoming()) {
			let _this = this.replyTo;
			let result = new Array(_this.length);
			let _g = 0;
			let _g1 = _this.length;
			while(_g < _g1) {
				let i = _g++;
				result[i] = _this[i].asBare().asString();
			}
			return result.join("\n");
		} else {
			let _this = this.recipients;
			let result = new Array(_this.length);
			let _g = 0;
			let _g1 = _this.length;
			while(_g < _g1) {
				let i = _g++;
				result[i] = _this[i].asString();
			}
			return result.join("\n");
		}
	}
	get_senderId() {
		let tmp = this.senderId;
		let tmp1;
		if(tmp != null) {
			tmp1 = tmp;
		} else {
			let tmp = this.sender;
			tmp1 = tmp != null ? tmp.asString() : null;
		}
		if(tmp1 != null) {
			return tmp1;
		} else {
			throw haxe_Exception.thrown("sender is null");
		}
	}
	isIncoming() {
		return this.direction == 0;
	}
	build() {
		if(this.serverId == null && this.localId == null) {
			throw haxe_Exception.thrown("Cannot build a ChatMessage with no id");
		}
		let to = this.to;
		if(to == null) {
			throw haxe_Exception.thrown("Cannot build a ChatMessage with no to");
		}
		let from = this.from;
		if(from == null) {
			throw haxe_Exception.thrown("Cannot build a ChatMessage with no from");
		}
		let tmp = this.sender;
		let sender = tmp != null ? tmp : from.asBare();
		let tmp1 = this.timestamp;
		return new snikket_ChatMessage({ localId : this.localId, serverId : this.serverId, serverIdBy : this.serverIdBy, type : this.type, syncPoint : this.syncPoint, replyId : this.replyId, timestamp : tmp1 != null ? tmp1 : snikket_Date.format(new Date()), to : to, from : from, senderId : this.get_senderId(), recipients : this.recipients, replyTo : this.replyTo, replyToMessage : this.replyToMessage, threadId : this.threadId, attachments : this.attachments, reactions : this.reactions, text : this.text, lang : this.lang, direction : this.direction, status : this.status, versions : this.versions, payloads : this.payloads, stanza : this.stanza});
	}
	static makeModerated(m,timestamp,moderatorId,reason) {
		let builder = new snikket_ChatMessageBuilder();
		builder.localId = m.localId;
		builder.serverId = m.serverId;
		builder.serverIdBy = m.serverIdBy;
		builder.type = m.type;
		builder.syncPoint = m.syncPoint;
		builder.replyId = m.replyId;
		builder.timestamp = m.timestamp;
		builder.to = m.to;
		builder.from = m.from;
		builder.senderId = m.senderId;
		builder.recipients = Lambda.array(m.recipients);
		builder.replyTo = Lambda.array(m.replyTo);
		builder.replyToMessage = m.replyToMessage;
		builder.threadId = m.threadId;
		builder.reactions = m.reactions;
		builder.direction = m.direction;
		builder.status = m.status;
		let cleanedStub = builder.build();
		let payload = new snikket_Stanza("retracted",{ xmlns : "urn:xmpp:message-retract:1", stamp : timestamp});
		if(reason != null) {
			payload.textTag("reason",reason);
		}
		payload.tag("moderated",{ by : moderatorId, xmlns : "urn:xmpp:message-moderate:1"}).up();
		builder.payloads.push(payload);
		builder.timestamp = timestamp;
		builder.versions = [builder.build(),cleanedStub];
		builder.timestamp = m.timestamp;
		return builder.build();
	}
}
$hx_exports["snikket"]["ChatMessageBuilder"] = snikket_ChatMessageBuilder;
snikket_ChatMessageBuilder.__name__ = "snikket.ChatMessageBuilder";
Object.assign(snikket_ChatMessageBuilder.prototype, {
	__class__: snikket_ChatMessageBuilder
});
class snikket_EventEmitter {
	constructor() {
		if(snikket_EventEmitter._hx_skip_constructor) {
			return;
		}
		this._hx_constructor();
	}
	_hx_constructor() {
		this.eventHandlers = new Map([]);
	}
	on(eventName,callback) {
		let handlers = this.eventHandlers.get(eventName);
		if(handlers == null) {
			handlers = [];
			this.eventHandlers.set(eventName,handlers);
		}
		let newHandler = new snikket_EventHandler(handlers,callback);
		handlers.push(newHandler);
		return newHandler;
	}
	once(eventName,callback) {
		return this.on(eventName,callback).once();
	}
	trigger(eventName,eventData) {
		let handlers = this.eventHandlers.get(eventName);
		if(handlers == null || handlers.length == 0) {
			haxe_Log.trace("no event handlers for " + eventName,{ fileName : "snikket/EventEmitter.hx", lineNumber : 29, className : "snikket.EventEmitter", methodName : "trigger"});
			return snikket_EventResult.EventUnhandled;
		}
		haxe_Log.trace("firing event: " + eventName,{ fileName : "snikket/EventEmitter.hx", lineNumber : 32, className : "snikket.EventEmitter", methodName : "trigger"});
		let handled = false;
		let _g = 0;
		while(_g < handlers.length) {
			let handler = handlers[_g];
			++_g;
			let ret = handler.call(eventData);
			switch(ret._hx_index) {
			case 0:
				handled = true;
				break;
			case 1:
				continue;
			case 2:
				return ret;
			case 3:
				let _g1 = ret.result;
				return ret;
			}
		}
		if(handled) {
			return snikket_EventResult.EventHandled;
		} else {
			return snikket_EventResult.EventUnhandled;
		}
	}
}
snikket_EventEmitter.__name__ = "snikket.EventEmitter";
Object.assign(snikket_EventEmitter.prototype, {
	__class__: snikket_EventEmitter
});
class snikket_Client extends snikket_EventEmitter {
	constructor(address,persistence) {
		snikket_EventEmitter._hx_skip_constructor = true;
		super();
		snikket_EventEmitter._hx_skip_constructor = false;
		this._hx_constructor(address,persistence);
	}
	_hx_constructor(address,persistence) {
		this.inSync = false;
		this.pendingCaps = new Map([]);
		this.token = null;
		this.fastMechanism = null;
		this.caps = new snikket_Caps("https://sdk.snikket.org",[],["http://jabber.org/protocol/disco#info","http://jabber.org/protocol/caps","urn:xmpp:avatar:metadata+notify","http://jabber.org/protocol/nick+notify","urn:xmpp:bookmarks:1+notify","urn:xmpp:mds:displayed:0+notify","urn:xmpp:jingle-message:0","urn:xmpp:jingle:1","urn:xmpp:jingle:apps:dtls:0","urn:xmpp:jingle:apps:rtp:1","urn:xmpp:jingle:apps:rtp:audio","urn:xmpp:jingle:apps:rtp:video","urn:xmpp:jingle:transports:ice-udp:1"]);
		this.chats = [];
		this.chatStateHandlers = [];
		this.syncMessageHandlers = [];
		this.chatMessageHandlers = [];
		this.sendAvailable = true;
		snikket_Util_setupTrace();
		super._hx_constructor();
		this.jid = snikket_JID.parse(address);
		this._displayName = this.jid.node;
		this.persistence = persistence;
		this.stream = new snikket_streams_XmppJsStream();
		this.stream.on("status/online",$bind(this,this.onConnected));
		let _gthis = this;
		this.stream.on("status/offline",function(data) {
			return _gthis.trigger("status/offline",{ });
		});
		this.stream.on("fast-token",function(data) {
			_gthis.token = data.token;
			let persistence1 = persistence;
			let tmp = _gthis.jid.asBare().asString();
			let tmp1 = _gthis.stream.clientId;
			persistence1.storeLogin(tmp,tmp1 != null ? tmp1 : _gthis.jid.resource,_gthis.displayName(),_gthis.token);
			return snikket_EventResult.EventHandled;
		});
		this.stream.on("sm/update",function(data) {
			let anySyncHappening = Lambda.exists(_gthis.chats,function(chat) {
				if(chat.uiState != 2) {
					return chat.syncing();
				} else {
					return false;
				}
			});
			persistence.storeStreamManagement(_gthis.accountId(),anySyncHappening ? null : data.sm);
			return snikket_EventResult.EventHandled;
		});
		this.stream.on("sm/ack",function(data) {
			persistence.updateMessageStatus(_gthis.accountId(),data.id,1,function(m) {
				_gthis.notifyMessageHandlers(m,3);
			});
			return snikket_EventResult.EventHandled;
		});
		this.stream.on("sm/fail",function(data) {
			persistence.updateMessageStatus(_gthis.accountId(),data.id,3,function(m) {
				_gthis.notifyMessageHandlers(m,3);
			});
			return snikket_EventResult.EventHandled;
		});
		this.stream.on("message",function(event) {
			let stanza = event.stanza;
			if(stanza.getChild("result","urn:xmpp:mam:2") != null) {
				return snikket_EventResult.EventUnhandled;
			}
			let from = stanza.attr["from"] == null ? null : snikket_JID.parse(stanza.attr["from"]);
			if(stanza.attr["type"] == "error" && from != null) {
				let chat = _gthis.getChat(from.asBare().asString());
				let channel = ((chat) instanceof snikket_Channel) ? chat : null;
				if(channel != null) {
					channel.selfPing(true);
				}
			}
			let fwd = null;
			if(from != null && from.asBare().asString() == _gthis.accountId()) {
				let carbon = stanza.getChild("received","urn:xmpp:carbons:2");
				if(carbon == null) {
					carbon = stanza.getChild("sent","urn:xmpp:carbons:2");
				}
				if(carbon != null) {
					let tmp = carbon.getChild("forwarded","urn:xmpp:forward:0");
					fwd = tmp != null ? tmp.getFirstChild() : null;
				}
			}
			let message = snikket_Message.fromStanza(stanza,_gthis.jid,function(builder,stanza) {
				let chat = _gthis.getChat(builder.chatId());
				if(chat == null && stanza.attr["type"] != "groupchat") {
					chat = _gthis.getDirectChat(builder.chatId());
				}
				if(chat == null) {
					return builder;
				}
				return chat.prepareIncomingMessage(builder,stanza);
			});
			let _g = message.parsed;
			switch(_g._hx_index) {
			case 1:
				let chatMessage = _g.message;
				let _g1 = 0;
				let _g2 = chatMessage.inlineHashReferences();
				while(_g1 < _g2.length) {
					let hash = _g2[_g1];
					++_g1;
					_gthis.fetchMediaByHash([hash],[chatMessage.from]);
				}
				let chat = _gthis.getChat(chatMessage.chatId());
				if(chat != null) {
					let updateChat = function(chatMessage) {
						_gthis.notifyMessageHandlers(chatMessage,chatMessage.versions.length > 1 ? 1 : 0);
						if(chatMessage.versions.length < 1 || chat.lastMessageId() == chatMessage.serverId || chat.lastMessageId() == chatMessage.localId) {
							chat.setLastMessage(chatMessage);
							if(chatMessage.versions.length < 1) {
								chat.setUnreadCount(chatMessage.isIncoming() ? chat.unreadCount() + 1 : 0);
							}
							_gthis.chatActivity(chat);
						}
					};
					if(chatMessage.serverId == null) {
						updateChat(chatMessage);
					} else {
						_gthis.storeMessages([chatMessage],function(stored) {
							updateChat(stored[0]);
						});
					}
				}
				break;
			case 2:
				let action = _g.action;
				_gthis.moderateMessage(action).then(function(stored) {
					if(stored != null) {
						_gthis.notifyMessageHandlers(stored,1);
					}
				});
				break;
			case 3:
				let update = _g.update;
				let _g3 = 0;
				let _g4 = update.inlineHashReferences();
				while(_g3 < _g4.length) {
					let hash = _g4[_g3];
					++_g3;
					_gthis.fetchMediaByHash([hash],[from]);
				}
				persistence.storeReaction(_gthis.accountId(),update,function(stored) {
					if(stored != null) {
						_gthis.notifyMessageHandlers(stored,2);
					}
				});
				break;
			default:
			}
			let jmiP = stanza.getChild("propose","urn:xmpp:jingle-message:0");
			if(jmiP != null && jmiP.attr["id"] != null) {
				let session = new snikket_jingle_IncomingProposedSession(_gthis,from,jmiP.attr["id"]);
				let chat = _gthis.getDirectChat(from.asBare().asString());
				if(!chat.jingleSessions.has(session.get_sid())) {
					chat.jingleSessions.set(session.get_sid(),session);
					_gthis.chatActivity(chat);
					session.ring();
				}
			}
			let jmiR = stanza.getChild("retract","urn:xmpp:jingle-message:0");
			if(jmiR != null && jmiR.attr["id"] != null) {
				let chat = _gthis.getDirectChat(from.asBare().asString());
				let session = chat.jingleSessions.get(jmiR.attr["id"]);
				if(session != null) {
					session.retract();
					chat.jingleSessions.delete(session.get_sid());
				}
			}
			let jmiProFwd = fwd != null ? fwd.getChild("proceed","urn:xmpp:jingle-message:0") : null;
			if(jmiProFwd != null && jmiProFwd.attr["id"] != null) {
				let chat = _gthis.getDirectChat(snikket_JID.parse(fwd.attr["to"]).asBare().asString());
				let session = chat.jingleSessions.get(jmiProFwd.attr["id"]);
				if(session != null) {
					session.retract();
					chat.jingleSessions.delete(session.get_sid());
				}
			}
			let jmiPro = stanza.getChild("proceed","urn:xmpp:jingle-message:0");
			if(jmiPro != null && jmiPro.attr["id"] != null) {
				let chat = _gthis.getDirectChat(from.asBare().asString());
				let session = chat.jingleSessions.get(jmiPro.attr["id"]);
				if(session != null) {
					try {
						chat.jingleSessions.set(session.get_sid(),session.initiate(stanza));
					} catch( _g ) {
						let e = haxe_Exception.caught(_g);
						haxe_Log.trace("JMI proceed failed",{ fileName : "snikket/Client.hx", lineNumber : 243, className : "snikket.Client", methodName : "new", customParams : [e]});
					}
				}
			}
			let jmiRej = stanza.getChild("reject","urn:xmpp:jingle-message:0");
			if(jmiRej != null && jmiRej.attr["id"] != null) {
				let chat = _gthis.getDirectChat(from.asBare().asString());
				let session = chat.jingleSessions.get(jmiRej.attr["id"]);
				if(session != null) {
					session.retract();
					chat.jingleSessions.delete(session.get_sid());
				}
			}
			if(stanza.attr["type"] != "error") {
				let chatState = stanza.getChild(null,"http://jabber.org/protocol/chatstates");
				let userState;
				let _g = chatState != null ? chatState.name : null;
				if(_g == null) {
					userState = null;
				} else {
					switch(_g) {
					case "active":
						userState = 2;
						break;
					case "composing":
						userState = 3;
						break;
					case "gone":
						userState = 0;
						break;
					case "inactive":
						userState = 1;
						break;
					case "paused":
						userState = 4;
						break;
					default:
						userState = null;
					}
				}
				if(userState != null) {
					let chat = _gthis.getChat(from.asBare().asString());
					if(chat == null || !chat.getParticipantDetails(message.senderId).isSelf) {
						let _g = 0;
						let _g1 = _gthis.chatStateHandlers;
						while(_g < _g1.length) {
							let handler = _g1[_g];
							++_g;
							handler(message.senderId,message.chatId,message.threadId,userState);
						}
					}
				}
			}
			let pubsubEvent = snikket_PubsubEvent.fromStanza(stanza);
			if(pubsubEvent != null && pubsubEvent.getFrom() != null && pubsubEvent.getNode() == "urn:xmpp:avatar:metadata" && pubsubEvent.getItems().length > 0) {
				let item = pubsubEvent.getItems()[0];
				let avatarSha1Hex = pubsubEvent.getItems()[0].attr["id"];
				let tmp = snikket_Hash.fromHex("sha-1",avatarSha1Hex);
				let avatarSha1 = tmp != null ? tmp.hash : null;
				let metadata = item.getChild("metadata","urn:xmpp:avatar:metadata");
				let mime = "image/png";
				if(metadata != null) {
					let info = metadata.getChild("info");
					if(info != null && info.attr["type"] != null) {
						mime = info.attr["type"];
					}
				}
				if(avatarSha1 != null) {
					let chat = _gthis.getDirectChat(snikket_JID.parse(pubsubEvent.getFrom()).asBare().asString(),false);
					chat.setAvatarSha1(avatarSha1);
					persistence.storeChats(_gthis.accountId(),[chat]);
					persistence.hasMedia("sha-1",avatarSha1,function(has) {
						if(has) {
							_gthis.trigger("chats/update",[chat]);
						} else {
							let pubsubGet = new snikket_queries_PubsubGet(pubsubEvent.getFrom(),"urn:xmpp:avatar:data",avatarSha1Hex);
							pubsubGet.onFinished(function() {
								let item = pubsubGet.getResult()[0];
								if(item == null) {
									return;
								}
								let dataNode = item.getChild("data","urn:xmpp:avatar:data");
								if(dataNode == null) {
									return;
								}
								persistence.storeMedia(mime,haxe_crypto_Base64.decode(StringTools.replace(dataNode.getText(),"\n","")).b.bufferValue,function() {
									_gthis.trigger("chats/update",[chat]);
								});
							});
							_gthis.sendQuery(pubsubGet);
						}
					});
				}
			}
			if(pubsubEvent != null && pubsubEvent.getFrom() != null && snikket_JID.parse(pubsubEvent.getFrom()).asBare().asString() == _gthis.accountId() && pubsubEvent.getNode() == "http://jabber.org/protocol/nick" && pubsubEvent.getItems().length > 0) {
				_gthis.updateDisplayName(pubsubEvent.getItems()[0].getChildText("nick","http://jabber.org/protocol/nick"));
			}
			if(pubsubEvent != null && pubsubEvent.getFrom() != null && snikket_JID.parse(pubsubEvent.getFrom()).asBare().asString() == _gthis.accountId() && pubsubEvent.getNode() == "urn:xmpp:mds:displayed:0" && pubsubEvent.getItems().length > 0) {
				let _g = 0;
				let _g1 = pubsubEvent.getItems();
				while(_g < _g1.length) {
					let item = _g1[_g];
					++_g;
					if(item.attr["id"] != null) {
						let tmp = item.getChild("displayed","urn:xmpp:mds:displayed:0");
						let upTo = tmp != null ? tmp.getChild("stanza-id","urn:xmpp:sid:0") : null;
						let chat = _gthis.getChat(item.attr["id"]);
						if(chat == null) {
							_gthis.startChatWith(item.attr["id"],function(caps) {
								return 2;
							},function(chat) {
								chat.markReadUpToId(upTo.attr["id"],upTo.attr["by"]);
							});
						} else {
							chat.markReadUpToId(upTo.attr["id"],upTo.attr["by"],function() {
								persistence.storeChats(_gthis.accountId(),[chat]);
								_gthis.trigger("chats/update",[chat]);
							});
						}
					}
				}
			}
			return snikket_EventResult.EventUnhandled;
		});
		this.stream.onIq(snikket_IqRequestType.Set,"jingle","urn:xmpp:jingle:1",function(stanza) {
			let from = stanza.attr["from"] == null ? null : snikket_JID.parse(stanza.attr["from"]);
			let jingle = stanza.getChild("jingle","urn:xmpp:jingle:1");
			let chat = _gthis.getDirectChat(from.asBare().asString());
			let session = chat.jingleSessions.get(jingle.attr["sid"]);
			if(jingle.attr["action"] == "session-initiate") {
				if(session != null) {
					try {
						chat.jingleSessions.set(session.get_sid(),session.initiate(stanza));
					} catch( _g ) {
						let e = haxe_Exception.caught(_g);
						haxe_Log.trace("Bad session-inititate",{ fileName : "snikket/Client.hx", lineNumber : 350, className : "snikket.Client", methodName : "new", customParams : [e]});
						chat.jingleSessions.delete(session.get_sid());
					}
				} else {
					let newSession = snikket_jingle_InitiatedSession.fromSessionInitiate(_gthis,stanza);
					chat.jingleSessions.set(newSession.get_sid(),newSession);
					_gthis.chatActivity(chat);
					newSession.ring();
				}
			}
			if(session != null && jingle.attr["action"] == "session-accept") {
				try {
					chat.jingleSessions.set(session.get_sid(),session.initiate(stanza));
				} catch( _g ) {
					let e = haxe_Exception.caught(_g);
					haxe_Log.trace("session-accept failed",{ fileName : "snikket/Client.hx", lineNumber : 365, className : "snikket.Client", methodName : "new", customParams : [e]});
				}
			}
			if(session != null && jingle.attr["action"] == "session-terminate") {
				session.terminate();
				chat.jingleSessions.delete(jingle.attr["sid"]);
			}
			if(session != null && jingle.attr["action"] == "content-add") {
				session.contentAdd(stanza);
			}
			if(session != null && jingle.attr["action"] == "content-accept") {
				session.contentAccept(stanza);
			}
			if(session != null && jingle.attr["action"] == "transport-info") {
				session.transportInfo(stanza);
			}
			return snikket_IqResult.IqResult;
		});
		this.stream.onIq(snikket_IqRequestType.Get,"query","http://jabber.org/protocol/disco#info",function(stanza) {
			return snikket_IqResult.IqResultElement(_gthis.caps.discoReply());
		});
		this.stream.onIq(snikket_IqRequestType.Set,"query","jabber:iq:roster",function(stanza) {
			if(stanza.attr["from"] != null && stanza.attr["from"] != _gthis.jid.domain) {
				return snikket_IqResult.IqNoResult;
			}
			let roster = new snikket_queries_RosterGet();
			roster.handleResponse(stanza);
			let items = roster.getResult();
			if(items.length == 0) {
				return snikket_IqResult.IqNoResult;
			}
			let chatsToUpdate = [];
			let _g = 0;
			while(_g < items.length) {
				let item = items[_g];
				++_g;
				if(item.subscription != "remove") {
					let chat = _gthis.getDirectChat(item.jid,false);
					chat.updateFromRoster(item);
					chatsToUpdate.push(js_Boot.__cast(chat , snikket_Chat));
				}
			}
			persistence.storeChats(_gthis.accountId(),chatsToUpdate);
			_gthis.trigger("chats/update",chatsToUpdate);
			return snikket_IqResult.IqResult;
		});
		this.stream.onIq(snikket_IqRequestType.Set,"block","urn:xmpp:blocking",function(stanza) {
			if(stanza.attr["from"] != null && stanza.attr["from"] != _gthis.jid.domain) {
				return snikket_IqResult.IqNoResult;
			}
			let _g = 0;
			let tmp = stanza.getChild("block","urn:xmpp:blocking");
			let tmp1 = tmp != null ? tmp.allTags("item") : null;
			let _g1 = tmp1 != null ? tmp1 : [];
			while(_g < _g1.length) {
				let item = _g1[_g];
				++_g;
				if(item.attr["jid"] != null) {
					_gthis.serverBlocked(item.attr["jid"]);
				}
			}
			return snikket_IqResult.IqResult;
		});
		this.stream.onIq(snikket_IqRequestType.Set,"unblock","urn:xmpp:blocking",function(stanza) {
			if(stanza.attr["from"] != null && stanza.attr["from"] != _gthis.jid.domain) {
				return snikket_IqResult.IqNoResult;
			}
			let tmp = stanza.getChild("unblock","urn:xmpp:blocking");
			let unblocks = tmp != null ? tmp.allTags("item") : null;
			if(unblocks == null) {
				let _g = 0;
				let _g1 = _gthis.chats;
				while(_g < _g1.length) {
					let chat = _g1[_g];
					++_g;
					if(chat.isBlocked) {
						chat.unblock(false);
					}
				}
			} else {
				let _g = 0;
				while(_g < unblocks.length) {
					let item = unblocks[_g];
					++_g;
					if(item.attr["jid"] != null) {
						let tmp = _gthis.getChat(item.attr["jid"]);
						if(tmp != null) {
							tmp.unblock(false);
						}
					}
				}
			}
			return snikket_IqResult.IqResult;
		});
		this.stream.on("presence",function(event) {
			let stanza = event.stanza;
			let c = stanza.getChild("c","http://jabber.org/protocol/caps");
			let mucUser = stanza.getChild("x","http://jabber.org/protocol/muc#user");
			if(stanza.attr["from"] != null && stanza.attr["type"] == null) {
				let from = snikket_JID.parse(stanza.attr["from"]);
				let chat = _gthis.getChat(from.asBare().asString());
				if(chat == null) {
					haxe_Log.trace("Presence for unknown JID: " + stanza.attr["from"],{ fileName : "snikket/Client.hx", lineNumber : 467, className : "snikket.Client", methodName : "new"});
					return snikket_EventResult.EventUnhandled;
				}
				if(c == null) {
					chat.setPresence(snikket_JID.parse(stanza.attr["from"]).resource,new snikket_Presence(null,mucUser));
					persistence.storeChats(_gthis.accountId(),[chat]);
					if(chat.livePresence()) {
						_gthis.trigger("chats/update",[chat]);
					}
				} else {
					let handleCaps = function(caps) {
						chat.setPresence(snikket_JID.parse(stanza.attr["from"]).resource,new snikket_Presence(caps,mucUser));
						if(mucUser == null || chat.livePresence()) {
							persistence.storeChats(_gthis.accountId(),[chat]);
						}
						return chat;
					};
					persistence.getCaps(c.attr["ver"],function(caps) {
						if(caps == null) {
							let pending = _gthis.pendingCaps.get(c.attr["ver"]);
							if(pending == null) {
								_gthis.pendingCaps.set(c.attr["ver"],[handleCaps]);
								let discoGet = new snikket_queries_DiscoInfoGet(stanza.attr["from"],c.attr["node"] + "#" + c.attr["ver"]);
								discoGet.onFinished(function() {
									let chatsToUpdate = new Map([]);
									let tmp = _gthis.pendingCaps.get(c.attr["ver"]);
									let handlers = tmp != null ? tmp : [];
									_gthis.pendingCaps.delete(c.attr["ver"]);
									if(discoGet.getResult() != null) {
										persistence.storeCaps(discoGet.getResult());
									}
									let _g = 0;
									while(_g < handlers.length) {
										let handler = handlers[_g];
										++_g;
										let c = handler(discoGet.getResult());
										if(c.livePresence()) {
											chatsToUpdate.set(c.chatId,c);
										}
									}
									_gthis.trigger("chats/update",Lambda.array({ iterator : function() {
										return new js_lib_HaxeIterator(chatsToUpdate.values());
									}}));
								});
								_gthis.sendQuery(discoGet);
							} else {
								pending.push(handleCaps);
							}
						} else {
							handleCaps(caps);
						}
					});
				}
				if(from.isBare()) {
					let avatarSha1Hex = stanza.findText("{vcard-temp:x:update}x/photo#");
					if(avatarSha1Hex != null) {
						let tmp = snikket_Hash.fromHex("sha-1",avatarSha1Hex);
						let avatarSha1 = tmp != null ? tmp.hash : null;
						chat.setAvatarSha1(avatarSha1);
						persistence.storeChats(_gthis.accountId(),[chat]);
						persistence.hasMedia("sha-1",avatarSha1,function(has) {
							if(has) {
								if(chat.livePresence()) {
									_gthis.trigger("chats/update",[chat]);
								}
							} else {
								let vcardGet = new snikket_queries_VcardTempGet(from);
								vcardGet.onFinished(function() {
									let vcard = vcardGet.getResult();
									if(vcard.photo == null) {
										return;
									}
									persistence.storeMedia(vcard.photo.mime,vcard.photo.data.b.bufferValue,function() {
										_gthis.trigger("chats/update",[chat]);
									});
								});
								_gthis.sendQuery(vcardGet);
							}
						});
					}
				}
				return snikket_EventResult.EventHandled;
			}
			if(stanza.attr["from"] != null && stanza.attr["type"] == "unavailable") {
				let chat = _gthis.getChat(snikket_JID.parse(stanza.attr["from"]).asBare().asString());
				if(chat == null) {
					haxe_Log.trace("Presence for unknown JID: " + stanza.attr["from"],{ fileName : "snikket/Client.hx", lineNumber : 536, className : "snikket.Client", methodName : "new"});
					return snikket_EventResult.EventUnhandled;
				}
				chat.removePresence(snikket_JID.parse(stanza.attr["from"]).resource);
				persistence.storeChats(_gthis.accountId(),[chat]);
				_gthis.trigger("chats/update",[chat]);
			}
			return snikket_EventResult.EventUnhandled;
		});
	}
	start() {
		let _gthis = this;
		this.persistence.getLogin(this.accountId(),function(clientId,loadedToken,fastCount,displayName) {
			_gthis.token = loadedToken;
			_gthis.persistence.getStreamManagement(_gthis.accountId(),function(sm) {
				let tmp = clientId;
				let tmp1 = tmp != null ? tmp : snikket_ID.long();
				_gthis.stream.clientId = tmp1;
				_gthis.jid = _gthis.jid.withResource(_gthis.stream.clientId);
				if(!_gthis.updateDisplayName(displayName) && clientId == null) {
					_gthis.persistence.storeLogin(_gthis.jid.asBare().asString(),_gthis.stream.clientId,_gthis.displayName(),null);
				}
				_gthis.persistence.getChats(_gthis.accountId(),function(protoChats) {
					let _g = 0;
					while(_g < protoChats.length) {
						let protoChat = protoChats[_g];
						++_g;
						_gthis.chats.push(protoChat.toChat(_gthis,_gthis.stream,_gthis.persistence));
					}
					_gthis.persistence.getChatsUnreadDetails(_gthis.accountId(),_gthis.chats,function(details) {
						let _g = 0;
						while(_g < details.length) {
							let detail = details[_g];
							++_g;
							let chat = _gthis.getChat(detail.chatId);
							if(chat != null) {
								chat.setLastMessage(detail.message);
								chat.setUnreadCount(detail.unreadCount);
							}
						}
						_gthis.sortChats();
						_gthis.trigger("chats/update",_gthis.chats);
						_gthis.stream.on("auth/password-needed",function(data) {
							let tmp = data.mechanisms;
							let tmp1 = tmp != null ? tmp.find(function(mech) {
								return mech.canFast;
							}) : null;
							_gthis.fastMechanism = tmp1 != null ? tmp1.name : null;
							if(_gthis.token == null || _gthis.fastMechanism == null && data.mechanimsms != null) {
								return _gthis.trigger("auth/password-needed",{ accountId : _gthis.accountId()});
							} else {
								return _gthis.stream.trigger("auth/password",{ password : _gthis.token, mechanism : _gthis.fastMechanism, fastCount : fastCount});
							}
						});
						_gthis.stream.on("auth/fail",function(data) {
							if(_gthis.token != null) {
								_gthis.token = null;
								_gthis.stream.connect(_gthis.jid.asString(),sm);
							} else {
								_gthis.stream.connect(_gthis.jid.asString(),sm);
							}
							return snikket_EventResult.EventHandled;
						});
						_gthis.stream.connect(_gthis.jid.asString(),sm);
					});
				});
			});
		});
	}
	logout(completely) {
		this.persistence.removeAccount(this.accountId(),completely);
		let disable = new snikket_queries_Push2Disable(this.jid.asBare().asString());
		let _gthis = this;
		disable.onFinished(function() {
			_gthis.stream.disconnect();
		});
		this.sendQuery(disable);
	}
	usePassword(password) {
		this.stream.trigger("auth/password",{ password : password, requestToken : this.fastMechanism});
	}
	accountId() {
		return this.jid.asBare().asString();
	}
	displayName() {
		return this._displayName;
	}
	setDisplayName(displayName) {
		if(displayName == null || displayName == "" || displayName == this.displayName()) {
			return;
		}
		this.stream.sendIq(new snikket_Stanza("iq",{ type : "set"}).tag("pubsub",{ xmlns : "http://jabber.org/protocol/pubsub"}).tag("publish",{ node : "http://jabber.org/protocol/nick"}).tag("item").textTag("nick",displayName,{ xmlns : "http://jabber.org/protocol/nick"}).up().up().up(),function(response) {
		});
	}
	updateDisplayName(fn) {
		if(fn == null || fn == "" || fn == this.displayName()) {
			return false;
		}
		this._displayName = fn;
		let tmp = this.persistence;
		let tmp1 = this.jid.asBare().asString();
		let tmp2 = this.stream.clientId;
		tmp.storeLogin(tmp1,tmp2 != null ? tmp2 : this.jid.resource,fn,null);
		this.pingAllChannels(false);
		return true;
	}
	onConnected(data) {
		if(data != null && data.jid != null) {
			this.jid = snikket_JID.parse(data.jid);
			if(this.stream.clientId == null && !this.jid.isBare()) {
				this.persistence.storeLogin(this.jid.asBare().asString(),this.jid.resource,this.displayName(),null);
			}
		}
		if(data.resumed) {
			this.inSync = true;
			this.trigger("status/online",{ });
			return snikket_EventResult.EventHandled;
		}
		let _gthis = this;
		this.discoverServices(new snikket_JID(null,this.jid.domain),null,function(service,caps) {
			_gthis.persistence.storeService(_gthis.accountId(),service.jid.asString(),service.name,service.node,caps);
		});
		this.rosterGet();
		haxe_Log.trace("SYNC: bookmarks",{ fileName : "snikket/Client.hx", lineNumber : 687, className : "snikket.Client", methodName : "onConnected"});
		this.bookmarksGet(function() {
			haxe_Log.trace("SYNC: MAM",{ fileName : "snikket/Client.hx", lineNumber : 689, className : "snikket.Client", methodName : "onConnected"});
			_gthis.sync(function(syncFinished) {
				if(!syncFinished) {
					haxe_Log.trace("SYNC: failed",{ fileName : "snikket/Client.hx", lineNumber : 692, className : "snikket.Client", methodName : "onConnected"});
					_gthis.inSync = false;
					_gthis.stream.disconnect();
					return;
				}
				haxe_Log.trace("SYNC: details",{ fileName : "snikket/Client.hx", lineNumber : 699, className : "snikket.Client", methodName : "onConnected"});
				_gthis.inSync = true;
				_gthis.persistence.getChatsUnreadDetails(_gthis.accountId(),_gthis.chats,function(details) {
					let _g = 0;
					while(_g < details.length) {
						let detail = details[_g];
						++_g;
						let tmp = _gthis.getChat(detail.chatId);
						let chat = tmp != null ? tmp : _gthis.getDirectChat(detail.chatId,false);
						let initialLastId = chat.lastMessageId();
						chat.setLastMessage(detail.message);
						chat.setUnreadCount(detail.unreadCount);
						if(detail.unreadCount > 0 && initialLastId != chat.lastMessageId()) {
							_gthis.chatActivity(chat,false);
						}
					}
					_gthis.sortChats();
					_gthis.trigger("chats/update",_gthis.chats);
					if(_gthis.sendAvailable) {
						_gthis.sendStanza(new snikket_Stanza("iq",{ type : "set", id : snikket_ID.short()}).tag("enable",{ xmlns : "urn:xmpp:carbons:2"}).up());
						_gthis.sendPresence();
						_gthis.pingAllChannels(true);
					}
					_gthis.trigger("status/online",{ });
					haxe_Log.trace("SYNC: done",{ fileName : "snikket/Client.hx", lineNumber : 725, className : "snikket.Client", methodName : "onConnected"});
				});
			});
		});
		this.trigger("session-started",{ });
		return snikket_EventResult.EventHandled;
	}
	prepareAttachment(source,callback) {
		let _gthis = this;
		this.persistence.findServicesWithFeature(this.accountId(),"urn:xmpp:http:upload:0",function(services) {
			let sha256 = new sha_SHA256();
			let options = null;
			let chunkSize = options == null || options.chunkSize == null ? 16777216 : options.chunkSize;
			tink_io_Source.chunked(new tink_io_js_BlobSource(source.name,source,0,chunkSize)).forEach(tink_streams_Handler.ofSafeSync(function(chunk) {
				sha256.update(chunk.toBytes());
				return tink_streams_Handled.Resume;
			})).handle(function(o) {
				if(o._hx_index == 3) {
					_gthis.prepareAttachmentFor(source,services,[new snikket_Hash("sha-256",sha256.digest().b.bufferValue)],callback);
				} else {
					haxe_Log.trace("Error computing attachment hash",{ fileName : "snikket/Client.hx", lineNumber : 748, className : "snikket.Client", methodName : "prepareAttachment", customParams : [o]});
					callback(null);
				}
			});
		});
	}
	prepareAttachmentFor(source,services,hashes,callback) {
		if(services.length < 1) {
			callback(null);
			return;
		}
		let httpUploadSlot = new snikket_queries_HttpUploadSlot(services[0].serviceId,source.name,source.size,source.type,hashes);
		let _gthis = this;
		httpUploadSlot.onFinished(function() {
			let slot = httpUploadSlot.getResult();
			if(slot == null) {
				_gthis.prepareAttachmentFor(source,services.slice(1),hashes,callback);
			} else {
				let url = tink_Url.fromString(slot.put);
				let options = null;
				let chunkSize = options == null || options.chunkSize == null ? 16777216 : options.chunkSize;
				tink_http_FetchResponse.all(tink_http_Fetch.fetch(url,{ method : "PUT", headers : slot.putHeaders, body : tink_io_RealSourceTools.idealize(new tink_io_js_BlobSource(source.name,source,0,chunkSize),function(e) {
					throw haxe_Exception.thrown(e);
				})})).handle(function(o) {
					if(o._hx_index == 0) {
						let res = o.data;
						if(res.header.statusCode == 201) {
							callback(new snikket_ChatAttachment(source.name,source.type,source.size,[slot.get],hashes));
						} else {
							_gthis.prepareAttachmentFor(source,services.slice(1),hashes,callback);
						}
					} else {
						_gthis.prepareAttachmentFor(source,services.slice(1),hashes,callback);
					}
				});
			}
		});
		this.sendQuery(httpUploadSlot);
	}
	getChats() {
		let _g = [];
		let _g1 = 0;
		let _g2 = this.chats;
		while(_g1 < _g2.length) {
			let v = _g2[_g1];
			++_g1;
			if(v.uiState != 2) {
				_g.push(v);
			}
		}
		return _g;
	}
	findAvailableChats(q,callback) {
		let results = [];
		let query = StringTools.trim(q);
		let _gthis = this;
		let checkAndAdd = function(jid,prepend) {
			if(prepend == null) {
				prepend = false;
			}
			let add = function(item) {
				if(prepend) {
					results.unshift(item);
				} else {
					results.push(item);
				}
			};
			let discoGet = new snikket_queries_DiscoInfoGet(jid.asString());
			discoGet.onFinished(function() {
				let resultCaps = discoGet.getResult();
				if(resultCaps == null) {
					let tmp = discoGet.responseStanza;
					let tmp1 = tmp != null ? tmp.getChild("error") : null;
					let err = tmp1 != null ? tmp1.getChild(null,"urn:ietf:params:xml:ns:xmpp-stanzas") : null;
					if(err == null || (err != null ? err.name : null) == "service-unavailable" || (err != null ? err.name : null) == "feature-not-implemented") {
						add(new snikket_AvailableChat(jid.asString(),query,jid.asString(),new snikket_Caps("",[],[])));
					}
				} else {
					_gthis.persistence.storeCaps(resultCaps);
					let identity = resultCaps.identities[0];
					let tmp = identity != null ? identity.name : null;
					let displayName = tmp != null ? tmp : query;
					let note = jid.asString() + (identity == null ? "" : " (" + identity.type + ")");
					add(new snikket_AvailableChat(jid.asString(),displayName,note,resultCaps));
				}
				callback(q,results);
			});
			_gthis.sendQuery(discoGet);
		};
		let jid = query.startsWith("xmpp:") ? snikket_JID.parse(HxOverrides.substr(query,5,null)) : snikket_JID.parse(query);
		if(jid.isValid()) {
			checkAndAdd(jid,true);
		}
		let _g = 0;
		let _g1 = this.chats;
		while(_g < _g1.length) {
			let chat = _g1[_g];
			++_g;
			if(chat.chatId != jid.asBare().asString()) {
				if(chat.chatId.includes(query.toLowerCase()) || chat.getDisplayName().toLowerCase().includes(query.toLowerCase())) {
					let channel = snikket_Util_downcast(chat,snikket_Channel);
					results.push(new snikket_AvailableChat(chat.chatId,chat.getDisplayName(),chat.chatId,channel == null || channel.disco == null ? new snikket_Caps("",[],[]) : channel.disco));
				}
			}
			if(chat.isTrusted()) {
				let resources = new Map([]);
				let _g = 0;
				let _g1 = snikket_Caps.withIdentity(chat.getCaps(),"gateway",null);
				while(_g < _g1.length) {
					let resource = _g1[_g];
					++_g;
					resources.set(resource,true);
				}
				let _g2 = 0;
				let _g3 = snikket_Caps.withFeature(chat.getCaps(),"jabber:iq:gateway");
				while(_g2 < _g3.length) {
					let resource = _g3[_g2];
					++_g2;
					resources.set(resource,true);
				}
				if(!this.sendAvailable && snikket_JID.parse(chat.chatId).isDomain()) {
					resources.set(null,true);
				}
				let jsIterator = resources.keys();
				let _g_jsIterator = jsIterator;
				let _g_lastStep = jsIterator.next();
				while(!_g_lastStep.done) {
					let v = _g_lastStep.value;
					_g_lastStep = _g_jsIterator.next();
					let resource = v;
					let bareJid = snikket_JID.parse(chat.chatId);
					let fullJid = new snikket_JID(bareJid.node,bareJid.domain,resource);
					let jigGet = new snikket_queries_JabberIqGatewayGet(fullJid.asString(),query);
					jigGet.onFinished(function() {
						if(jigGet.getResult() == null) {
							let caps = chat.getResourceCaps(resource);
							if(bareJid.isDomain() && caps.features.includes("jid\\20escaping")) {
								checkAndAdd(new snikket_JID(query,bareJid.domain));
							} else if(bareJid.isDomain()) {
								checkAndAdd(new snikket_JID(StringTools.replace(query,"@","%"),bareJid.domain));
							}
						} else {
							let _g = jigGet.getResult();
							switch(_g._hx_index) {
							case 0:
								let error = _g.v;
								return;
							case 1:
								let result = _g.v;
								checkAndAdd(snikket_JID.parse(result));
								break;
							}
						}
					});
					this.sendQuery(jigGet);
				}
			}
		}
		if(!jid.isValid() && results.length > 0) {
			callback(q,results);
		}
	}
	startChat(availableChat) {
		let existingChat = this.getChat(availableChat.chatId);
		if(existingChat != null) {
			let channel = ((existingChat) instanceof snikket_Channel) ? existingChat : null;
			if(channel == null && availableChat.isChannel() || channel != null && !availableChat.isChannel()) {
				let _g = [];
				let _g1 = 0;
				let _g2 = this.chats;
				while(_g1 < _g2.length) {
					let v = _g2[_g1];
					++_g1;
					if(v.chatId != availableChat.chatId) {
						_g.push(v);
					}
				}
				this.chats = _g;
			} else {
				if(existingChat.uiState == 2) {
					existingChat.uiState = 1;
				}
				if(channel != null) {
					channel.selfPing(true);
				}
				this.persistence.storeChats(this.accountId(),[existingChat]);
				this.trigger("chats/update",[existingChat]);
				return existingChat;
			}
		}
		let chat;
		if(availableChat.isChannel()) {
			let channel = new snikket_Channel(this,this.stream,this.persistence,availableChat.chatId,1,false,null,null,null,availableChat.caps);
			this.chats.unshift(channel);
			channel.selfPing(false);
			chat = channel;
		} else {
			chat = this.getDirectChat(availableChat.chatId,false);
		}
		this.persistence.storeChats(this.accountId(),[chat]);
		this.trigger("chats/update",[chat]);
		return chat;
	}
	getChat(chatId) {
		return Lambda.find(this.chats,function(chat) {
			return chat.chatId == chatId;
		});
	}
	moderateMessage(action) {
		let _gthis = this;
		return thenshim_Promise._new(function(resolve,reject) {
			_gthis.persistence.getMessage(_gthis.accountId(),action.chatId,action.moderateServerId,null,function(moderateMessage) {
				if(moderateMessage == null) {
					resolve(null);
					return;
				}
				let _g = 0;
				let _g1 = moderateMessage.attachments;
				while(_g < _g1.length) {
					let attachment = _g1[_g];
					++_g;
					let _g2 = 0;
					let _g3 = attachment.hashes;
					while(_g2 < _g3.length) {
						let hash = _g3[_g2];
						++_g2;
						_gthis.persistence.removeMedia(hash.algorithm,hash.hash);
					}
				}
				moderateMessage = snikket_ChatMessageBuilder.makeModerated(moderateMessage,action.timestamp,action.moderatorId,action.reason);
				_gthis.persistence.updateMessage(_gthis.accountId(),moderateMessage);
				resolve(moderateMessage);
			});
		});
	}
	getDirectChat(chatId,triggerIfNew) {
		if(triggerIfNew == null) {
			triggerIfNew = true;
		}
		let _g = 0;
		let _g1 = this.chats;
		while(_g < _g1.length) {
			let chat = _g1[_g];
			++_g;
			if(((chat) instanceof snikket_DirectChat) && chat.chatId == chatId) {
				if(((chat) instanceof snikket_DirectChat)) {
					return chat;
				} else {
					return null;
				}
			}
		}
		let chat = new snikket_DirectChat(this,this.stream,this.persistence,chatId);
		this.persistence.storeChats(this.accountId(),[chat]);
		this.chats.unshift(chat);
		if(triggerIfNew) {
			this.trigger("chats/update",[chat]);
		}
		return chat;
	}
	subscribePush(reg,push_service,vapid_key) {
		let _gthis = this;
		window.crypto.subtle.exportKey("raw",vapid_key.publicKey).then(function(vapid_public_raw) {
			return reg.pushManager.subscribe({ userVisibleOnly : true, applicationServerKey : vapid_public_raw}).then(function(pushSubscription) {
				if(pushSubscription == null) {
					haxe_Log.trace("WebPush subscription failed",{ fileName : "snikket/Client.hx", lineNumber : 950, className : "snikket.Client", methodName : "subscribePush"});
					return;
				}
				_gthis.enablePush(push_service,vapid_key.privateKey,pushSubscription.endpoint,pushSubscription.getKey("p256dh"),pushSubscription.getKey("auth"));
			});
		});
	}
	enablePush(push_service,vapid_private_key,endpoint,p256dh,auth) {
		let _gthis = this;
		window.crypto.subtle.exportKey("pkcs8",vapid_private_key).then(function(vapid_private_pkcs8) {
			let _gthis1 = _gthis;
			let tmp = _gthis.jid.asBare().asString();
			let push_service1 = push_service;
			let endpoint1 = endpoint;
			let tmp1 = haxe_io_Bytes.ofData(p256dh);
			let tmp2 = haxe_io_Bytes.ofData(auth);
			let tmp3 = haxe_io_Bytes.ofData(vapid_private_pkcs8);
			let _g = new haxe_ds_StringMap();
			let value = new URL(endpoint).origin;
			_g.h["aud"] = value;
			_gthis1.sendQuery(new snikket_queries_Push2Enable(tmp,push_service1,endpoint1,tmp1,tmp2,"ES256",tmp3,snikket_Map.fromMap(_g)));
		});
	}
	addPasswordNeededListener(handler) {
		let _gthis = this;
		this.on("auth/password-needed",function(data) {
			handler(_gthis);
			return snikket_EventResult.EventHandled;
		});
	}
	addStatusOnlineListener(handler) {
		this.on("status/online",function(data) {
			handler();
			return snikket_EventResult.EventHandled;
		});
	}
	addStatusOfflineListener(handler) {
		this.on("status/offline",function(data) {
			handler();
			return snikket_EventResult.EventHandled;
		});
	}
	addConnectionFailedListener(handler) {
		this.stream.on("status/error",function(data) {
			handler();
			return snikket_EventResult.EventHandled;
		});
	}
	addUserStateListener(handler) {
		this.chatStateHandlers.push(handler);
	}
	addChatMessageListener(handler) {
		this.chatMessageHandlers.push(handler);
	}
	addSyncMessageListener(handler) {
		this.syncMessageHandlers.push(handler);
	}
	addChatsUpdatedListener(handler) {
		this.on("chats/update",function(data) {
			handler(data);
			return snikket_EventResult.EventHandled;
		});
	}
	addCallRingListener(handler) {
		this.on("call/ring",function(data) {
			handler(data.session,data.chatId);
			return snikket_EventResult.EventHandled;
		});
	}
	addCallRetractListener(handler) {
		this.on("call/retract",function(data) {
			handler(data.chatId);
			return snikket_EventResult.EventHandled;
		});
	}
	addCallRingingListener(handler) {
		this.on("call/ringing",function(data) {
			handler(data.chatId);
			return snikket_EventResult.EventHandled;
		});
	}
	addCallMediaListener(handler) {
		this.on("call/media",function(data) {
			handler(data.session,data.audio,data.video);
			return snikket_EventResult.EventHandled;
		});
	}
	addCallTrackListener(handler) {
		this.on("call/track",function(data) {
			handler(data.chatId,data.track,data.streams);
			return snikket_EventResult.EventHandled;
		});
	}
	setInForeground() {
		if(!this.stream.csi) {
			return;
		}
		this.stream.sendStanza(new snikket_Stanza("active",{ xmlns : "urn:xmpp:csi:0"}));
	}
	setNotInForeground() {
		if(!this.stream.csi) {
			return;
		}
		this.stream.sendStanza(new snikket_Stanza("inactive",{ xmlns : "urn:xmpp:csi:0"}));
	}
	fetchMediaByHash(hashes,counterparts) {
		if(hashes.length < 1 || counterparts.length < 1) {
			return thenshim_Promise.reject("no counterparts left");
		}
		let _gthis = this;
		return thenshim_Promise.then(this.fetchMediaByHashOneCounterpart(hashes,counterparts[0]),function(x) {
			return x;
		},function(_) {
			return _gthis.fetchMediaByHash(hashes,counterparts.slice(1));
		});
	}
	fetchMediaByHashOneCounterpart(hashes,counterpart) {
		if(hashes.length < 1) {
			return thenshim_Promise.reject("no hashes left");
		}
		let _gthis = this;
		return thenshim_Promise.then(thenshim_Promise._new(function(resolve,reject) {
			_gthis.persistence.hasMedia(hashes[0].algorithm,hashes[0].hash,resolve);
		}),function(has) {
			if(has) {
				return thenshim_Promise.resolve(null);
			}
			return thenshim_Promise.then(thenshim_Promise._new(function(resolve,reject) {
				let q = snikket_queries_BoB.forHash(counterpart.asString(),hashes[0]);
				q.onFinished(function() {
					let r = q.getResult();
					if(r == null) {
						reject("bad or no result from BoB query");
					} else {
						_gthis.persistence.storeMedia(r.type,r.bytes.b.bufferValue,function() {
							resolve(null);
						});
					}
				});
				_gthis.sendQuery(q);
			}),function(x) {
				return x;
			},function(_) {
				return _gthis.fetchMediaByHashOneCounterpart(hashes.slice(1),counterpart);
			});
		});
	}
	chatActivity(chat,trigger) {
		if(trigger == null) {
			trigger = true;
		}
		if(chat.isBlocked) {
			return;
		}
		if(chat.uiState == 2) {
			chat.uiState = 1;
			this.persistence.storeChats(this.accountId(),[chat]);
		}
		let pinnedCount = chat.uiState == 0 ? 0 : Lambda.fold(this.chats,function(item,result) {
			return result + (item.uiState == 0 ? 1 : 0);
		},0);
		let idx = this.chats.indexOf(chat);
		if(idx > pinnedCount) {
			this.chats.splice(idx,1);
			this.chats.splice(pinnedCount,0,chat);
		}
		if(trigger) {
			this.trigger("chats/update",[chat]);
		}
	}
	sortChats() {
		this.chats.sort(function(a,b) {
			if(a.uiState == 0 && b.uiState != 0) {
				return -1;
			}
			if(b.uiState == 0 && a.uiState != 0) {
				return 1;
			}
			let tmp = a.lastMessageTimestamp();
			let tmp1 = b.lastMessageTimestamp();
			return -Reflect.compare(tmp != null ? tmp : "0",tmp1 != null ? tmp1 : "0");
		});
	}
	storeMessages(messages,callback) {
		let tmp = callback;
		this.persistence.storeMessages(this.accountId(),messages,tmp != null ? tmp : function(_) {
		});
	}
	sendQuery(query) {
		this.stream.sendIq(query.getQueryStanza(),$bind(query,query.handleResponse));
	}
	sendStanza(stanza) {
		if(stanza.attr["id"] == null) {
			stanza.attr["id"] = snikket_ID.long();
		}
		this.stream.sendStanza(stanza);
	}
	sendPresence(to,augment) {
		let tmp = augment;
		this.sendStanza((tmp != null ? tmp : function(s) {
			return s;
		})(this.caps.addC(new snikket_Stanza("presence",to == null ? { } : { to : to})).textTag("nick",this.displayName(),{ xmlns : "http://jabber.org/protocol/nick"})));
	}
	getIceServers(callback) {
		let extDiscoGet = new snikket_queries_ExtDiscoGet(this.jid.domain);
		extDiscoGet.onFinished(function() {
			let didUrl = new Map([]);
			let servers = [];
			let _g = 0;
			let tmp = extDiscoGet.getResult();
			let _g1 = tmp != null ? tmp : [];
			while(_g < _g1.length) {
				let service = _g1[_g];
				++_g;
				if(!["stun","stuns","turn","turns"].includes(service.attr["type"])) {
					continue;
				}
				let host = service.attr["host"];
				if(host == null || host == "") {
					continue;
				}
				let port = Std.parseInt(service.attr["port"]);
				if(port == null || port < 1 || port > 65535) {
					continue;
				}
				let isTurn = ["turn","turns"].includes(service.attr["type"]);
				let url = service.attr["type"] + ":" + (host.indexOf(":") >= 0 ? "[" + host + "]" : host) + ":" + port + (isTurn ? "?transport=" + service.attr["transport"] : "");
				if(!didUrl.has(url)) {
					servers.push({ username : service.attr["username"], credential : service.attr["password"], urls : [url]});
					didUrl.set(url,true);
				}
			}
			callback(servers);
		});
		this.sendQuery(extDiscoGet);
	}
	discoverServices(target,node,callback) {
		let itemsGet = new snikket_queries_DiscoItemsGet(target.asString(),node);
		let _gthis = this;
		itemsGet.onFinished(function() {
			let _g = 0;
			let tmp = itemsGet.getResult();
			let _g1 = tmp != null ? tmp : [];
			while(_g < _g1.length) {
				let item = _g1[_g];
				++_g;
				let infoGet = new snikket_queries_DiscoInfoGet(item.jid.asString(),item.node);
				infoGet.onFinished(function() {
					callback(item,infoGet.getResult());
				});
				_gthis.sendQuery(infoGet);
			}
		});
		this.sendQuery(itemsGet);
	}
	notifyMessageHandlers(message,event) {
		let chat = this.getChat(message.chatId());
		if(chat != null && chat.isBlocked) {
			return;
		}
		let _g = 0;
		let _g1 = this.chatMessageHandlers;
		while(_g < _g1.length) {
			let handler = _g1[_g];
			++_g;
			handler(message,event);
		}
	}
	notifySyncMessageHandlers(message) {
		if(message == null || message.versions.length > 1) {
			return;
		}
		let chat = this.getChat(message.chatId());
		if(chat != null && chat.isBlocked) {
			return;
		}
		let _g = 0;
		let _g1 = this.syncMessageHandlers;
		while(_g < _g1.length) {
			let handler = _g1[_g];
			++_g;
			handler(message);
		}
	}
	rosterGet() {
		let rosterGet = new snikket_queries_RosterGet();
		let _gthis = this;
		rosterGet.onFinished(function() {
			let chatsToUpdate = [];
			let _g = 0;
			let _g1 = rosterGet.getResult();
			while(_g < _g1.length) {
				let item = _g1[_g];
				++_g;
				let chat = _gthis.getDirectChat(item.jid,false);
				chat.updateFromRoster(item);
				chatsToUpdate.push(js_Boot.__cast(chat , snikket_Chat));
			}
			_gthis.persistence.storeChats(_gthis.accountId(),chatsToUpdate);
			_gthis.trigger("chats/update",chatsToUpdate);
		});
		this.sendQuery(rosterGet);
	}
	startChatWith(jid,handleCaps,handleChat) {
		let discoGet = new snikket_queries_DiscoInfoGet(jid);
		let _gthis = this;
		discoGet.onFinished(function() {
			let resultCaps = discoGet.getResult();
			if(resultCaps == null) {
				let tmp = discoGet.responseStanza;
				let tmp1 = tmp != null ? tmp.getChild("error") : null;
				let err = tmp1 != null ? tmp1.getChild(null,"urn:ietf:params:xml:ns:xmpp-stanzas") : null;
				if(err == null || (err != null ? err.name : null) == "service-unavailable" || (err != null ? err.name : null) == "feature-not-implemented") {
					let chat = _gthis.getDirectChat(jid,false);
					handleChat(chat);
					_gthis.persistence.storeChats(_gthis.accountId(),[chat]);
				}
			} else {
				_gthis.persistence.storeCaps(resultCaps);
				let uiState = handleCaps(resultCaps);
				if(resultCaps.isChannel(jid)) {
					let chat = new snikket_Channel(_gthis,_gthis.stream,_gthis.persistence,jid,uiState,false,null,null,null,resultCaps);
					handleChat(chat);
					_gthis.chats.unshift(chat);
					_gthis.persistence.storeChats(_gthis.accountId(),[chat]);
				} else {
					let chat = _gthis.getDirectChat(jid,false);
					handleChat(chat);
					_gthis.persistence.storeChats(_gthis.accountId(),[chat]);
				}
			}
		});
		this.sendQuery(discoGet);
	}
	serverBlocked(blocked) {
		let tmp = this.getChat(blocked);
		let chat = tmp != null ? tmp : this.getDirectChat(blocked,false);
		chat.block(null,false);
	}
	bookmarksGet(callback) {
		let blockingGet = new snikket_queries_BlocklistGet();
		let _gthis = this;
		blockingGet.onFinished(function() {
			let _g = 0;
			let _g1 = blockingGet.getResult();
			while(_g < _g1.length) {
				let blocked = _g1[_g];
				++_g;
				_gthis.serverBlocked(blocked);
			}
		});
		this.sendQuery(blockingGet);
		let mdsGet = new snikket_queries_PubsubGet(null,"urn:xmpp:mds:displayed:0");
		mdsGet.onFinished(function() {
			let chatsToUpdate = [];
			let _g = 0;
			let _g1 = mdsGet.getResult();
			while(_g < _g1.length) {
				let item = _g1[_g];
				++_g;
				if(item.attr["id"] != null) {
					let tmp = item.getChild("displayed","urn:xmpp:mds:displayed:0");
					let upTo = tmp != null ? tmp.getChild("stanza-id","urn:xmpp:sid:0") : null;
					let chat = _gthis.getChat(item.attr["id"]);
					if(chat == null) {
						_gthis.startChatWith(item.attr["id"],function(caps) {
							return 2;
						},function(chat) {
							chat.markReadUpToId(upTo.attr["id"],upTo.attr["by"]);
						});
					} else {
						chat.markReadUpToId(upTo.attr["id"],upTo.attr["by"]);
						chatsToUpdate.push(chat);
					}
				}
			}
			_gthis.persistence.storeChats(_gthis.accountId(),chatsToUpdate);
		});
		this.sendQuery(mdsGet);
		let pubsubGet = new snikket_queries_PubsubGet(null,"urn:xmpp:bookmarks:1");
		pubsubGet.onFinished(function() {
			let chatsToUpdate = [];
			let _g = 0;
			let _g1 = pubsubGet.getResult();
			while(_g < _g1.length) {
				let item = _g1[_g];
				++_g;
				if(item.attr["id"] != null) {
					let chat = _gthis.getChat(item.attr["id"]);
					if(chat == null) {
						_gthis.startChatWith(item.attr["id"],function(caps) {
							let identity = caps.identities[0];
							let conf = item.getChild("conference","urn:xmpp:bookmarks:1");
							if(conf.attr["name"] == null) {
								conf.attr["name"] = identity != null ? identity.name : null;
							}
							if(conf.attr["autojoin"] == "1" || conf.attr["autojoin"] == "true" || !caps.isChannel(item.attr["id"])) {
								return 1;
							} else {
								return 2;
							}
						},function(chat) {
							chat.updateFromBookmark(item);
						});
					} else {
						chat.updateFromBookmark(item);
						chatsToUpdate.push(chat);
					}
				}
			}
			_gthis.persistence.storeChats(_gthis.accountId(),chatsToUpdate);
			callback();
		});
		this.sendQuery(pubsubGet);
	}
	sync(callback) {
		let _gthis = this;
		if(((this.persistence) instanceof snikket_persistence_Dummy)) {
			callback(true);
		} else {
			this.persistence.lastId(this.accountId(),null,function(lastId) {
				_gthis.doSync(callback,lastId);
			});
		}
	}
	onMAMJMI(sid,stanza) {
		if(stanza.attr["from"] == null) {
			return;
		}
		let from = snikket_JID.parse(stanza.attr["from"]);
		let chat = this.getDirectChat(from.asBare().asString());
		if(chat.jingleSessions.has(sid)) {
			return;
		}
		let jmiP = stanza.getChild("propose","urn:xmpp:jingle-message:0");
		if(jmiP == null) {
			return;
		}
		let session = new snikket_jingle_IncomingProposedSession(this,from,sid);
		chat.jingleSessions.set(session.get_sid(),session);
		this.chatActivity(chat);
		session.ring();
	}
	doSync(callback,lastId) {
		let thirtyDaysAgo = snikket_Date.format(new Date(new Date().getTime() + (-2592000000.)));
		let sync = new snikket_MessageSync(this,this.stream,lastId == null ? { startTime : thirtyDaysAgo} : { page : { after : lastId}});
		sync.setNewestPageFirst(false);
		sync.addContext(function(builder,stanza) {
			builder.syncPoint = true;
			return builder;
		});
		let _gthis = this;
		sync.onMessages(function(messageList) {
			let promises = [];
			let chatMessages = [];
			let _g = 0;
			let _g1 = messageList.messages;
			while(_g < _g1.length) {
				let m = _g1[_g];
				++_g;
				switch(m._hx_index) {
				case 1:
					let message = m.message;
					chatMessages.push(message);
					break;
				case 2:
					let action = m.action;
					promises.push(thenshim_Promise._new(function(resolve,reject) {
						_gthis.moderateMessage(action).then(function(_) {
							resolve(null);
						});
					}));
					break;
				case 3:
					let update = m.update;
					promises.push(thenshim_Promise._new(function(resolve,reject) {
						_gthis.persistence.storeReaction(_gthis.accountId(),update,function(_) {
							resolve(null);
						});
					}));
					break;
				default:
				}
			}
			promises.push(thenshim_Promise._new(function(resolve,reject) {
				_gthis.persistence.storeMessages(_gthis.accountId(),chatMessages,resolve);
			}));
			haxe_Log.trace("SYNC: MAM page wait for writes",{ fileName : "snikket/Client.hx", lineNumber : 1467, className : "snikket.Client", methodName : "doSync"});
			thenshim_Promise.then(thenshim_PromiseTools.all(promises),function(results) {
				if(_gthis.syncMessageHandlers.length > 0) {
					let _g = 0;
					while(_g < results.length) {
						let messages = results[_g];
						++_g;
						if(messages != null) {
							let _g = 0;
							while(_g < messages.length) {
								let message = messages[_g];
								++_g;
								_gthis.notifySyncMessageHandlers(message);
							}
						}
					}
				}
				if(sync.hasMore()) {
					sync.fetchNext();
				} else {
					let jsIterator = sync.jmi.entries();
					let _g_jsIterator = jsIterator;
					let _g_lastStep = jsIterator.next();
					while(!_g_lastStep.done) {
						let v = _g_lastStep.value;
						_g_lastStep = _g_jsIterator.next();
						let _g_key = v[0];
						let _g_value = v[1];
						let sid = _g_key;
						let stanza = _g_value;
						_gthis.onMAMJMI(sid,stanza);
					}
					if(callback != null) {
						callback(true);
					}
				}
			},function(e) {
				haxe_Log.trace("SYNC: error",{ fileName : "snikket/Client.hx", lineNumber : 1489, className : "snikket.Client", methodName : "doSync", customParams : [e == null ? "null" : Std.string(e)]});
				callback(false);
			});
		});
		sync.onError(function(stanza) {
			if(lastId != null) {
				_gthis.doSync(callback,null);
			} else {
				haxe_Log.trace("SYNC: error",{ fileName : "snikket/Client.hx", lineNumber : 1498, className : "snikket.Client", methodName : "doSync", customParams : [stanza]});
				if(callback != null) {
					callback(false);
				}
			}
		});
		sync.fetchNext();
	}
	pingAllChannels(refresh) {
		let _g = 0;
		let _g1 = this.getChats();
		while(_g < _g1.length) {
			let chat = _g1[_g];
			++_g;
			let channel = ((chat) instanceof snikket_Channel) ? chat : null;
			if(channel != null) {
				channel.selfPing(refresh || (channel != null ? channel.disco : null) == null);
			}
		}
	}
}
$hx_exports["snikket"]["Client"] = snikket_Client;
snikket_Client.__name__ = "snikket.Client";
snikket_Client.__super__ = snikket_EventEmitter;
Object.assign(snikket_Client.prototype, {
	__class__: snikket_Client
});
class snikket_Color {
	static forString(s) {
		let hash = haxe_crypto_Sha1.make(haxe_io_Bytes.ofString(s));
		let hue = hash.getUInt16(0) / 65536.0 * 360;
		let color = new hsluv_Hsluv();
		color.hsluv_h = hue;
		color.hsluv_s = 100;
		color.hsluv_l = 50;
		color.hsluvToHex();
		return color.hex;
	}
	static defaultPhoto(input,letter) {
		let hex = HxOverrides.substr(snikket_Color.forString(input),1,null);
		return "data:image/svg+xml,<svg%20xmlns=\"http://www.w3.org/2000/svg\"%20version=\"1.1\"%20width=\"15\"%20height=\"15\"%20viewBox=\"0%200%2015%2015\">" + "<rect%20style=\"fill:%23" + hex + ";\"%20width=\"15\"%20height=\"15\"%20x=\"0\"%20y=\"0\"%20/>" + "<text%20style=\"fill:%23ffffff;font-size:8px;font-family:sans-serif;\"%20text-anchor=\"middle\"%20dominant-baseline=\"central\"%20x=\"50%25\"%20y=\"50%25\">" + encodeURIComponent(letter) + "</text>" + "</svg>";
	}
}
snikket_Color.__name__ = "snikket.Color";
class snikket_Config {
}
$hx_exports["snikket"]["Config"] = snikket_Config;
snikket_Config.__name__ = "snikket.Config";
class snikket_Date {
	static format(d) {
		let millis = d.getTime();
		let frac = millis - (millis / 1000 | 0) * 1000.0 | 0;
		return Std.string(d.getUTCFullYear()) + "-" + StringTools.lpad(Std.string(d.getUTCMonth() + 1),"0",2) + "-" + StringTools.lpad(Std.string(d.getUTCDate()),"0",2) + "T" + StringTools.lpad(Std.string(d.getUTCHours()),"0",2) + ":" + StringTools.lpad(Std.string(d.getUTCMinutes()),"0",2) + ":" + StringTools.lpad(Std.string(d.getUTCSeconds()),"0",2) + "." + StringTools.lpad(frac == null ? "null" : "" + frac,"0",3) + "Z";
	}
}
snikket_Date.__name__ = "snikket.Date";
class snikket_UnicodeSet {
}
snikket_UnicodeSet.__name__ = "snikket.UnicodeSet";
snikket_UnicodeSet.__isInterface__ = true;
Object.assign(snikket_UnicodeSet.prototype, {
	__class__: snikket_UnicodeSet
});
class snikket_UnicodeList {
	constructor(...codes) {
		this.list = codes.slice();
	}
	contains(codepoint) {
		return this.list.includes(codepoint);
	}
}
snikket_UnicodeList.__name__ = "snikket.UnicodeList";
snikket_UnicodeList.__interfaces__ = [snikket_UnicodeSet];
Object.assign(snikket_UnicodeList.prototype, {
	__class__: snikket_UnicodeList
});
class snikket_UnicodeRange {
	constructor(lower,upper) {
		this.lower = lower;
		this.upper = upper;
	}
	contains(codePoint) {
		if(codePoint >= this.lower) {
			return codePoint <= this.upper;
		} else {
			return false;
		}
	}
}
snikket_UnicodeRange.__name__ = "snikket.UnicodeRange";
snikket_UnicodeRange.__interfaces__ = [snikket_UnicodeSet];
Object.assign(snikket_UnicodeRange.prototype, {
	__class__: snikket_UnicodeRange
});
class snikket_UnicodeBlocks {
	constructor(...sets) {
		this.unicodeSets = sets.slice();
	}
	contains(codepoint) {
		let _g = 0;
		let _g1 = this.unicodeSets;
		while(_g < _g1.length) {
			let unicodeSet = _g1[_g];
			++_g;
			if(unicodeSet.contains(codepoint)) {
				return true;
			}
		}
		return false;
	}
}
snikket_UnicodeBlocks.__name__ = "snikket.UnicodeBlocks";
snikket_UnicodeBlocks.__interfaces__ = [snikket_UnicodeSet];
Object.assign(snikket_UnicodeBlocks.prototype, {
	__class__: snikket_UnicodeBlocks
});
class snikket_EmojiUtil {
	static parse(str) {
		let symbols = [];
		let builder = new snikket_Builder();
		let needsFinalBuild = false;
		let input = snikket_StringUtil.rawCodepointArray(str);
		let _g = 0;
		let _g1 = input.length;
		while(_g < _g1) {
			let i = _g++;
			let cp = input[i];
			if(builder.offer(cp)) {
				needsFinalBuild = true;
			} else {
				symbols.push(builder.build());
				builder = new snikket_Builder();
				if(builder.offer(cp)) {
					needsFinalBuild = true;
				}
			}
		}
		if(needsFinalBuild) {
			symbols.push(builder.build());
		}
		return symbols;
	}
	static isEmoji(input) {
		let symbols = snikket_EmojiUtil.parse(input);
		if(symbols.length == 1) {
			return symbols[0].isEmoji();
		} else {
			return false;
		}
	}
	static isOnlyEmoji(input) {
		let symbols = snikket_EmojiUtil.parse(input);
		let _g = 0;
		while(_g < symbols.length) {
			let symbol = symbols[_g];
			++_g;
			if(!symbol.isEmoji()) {
				return false;
			}
		}
		return symbols.length > 0;
	}
}
snikket_EmojiUtil.__name__ = "snikket.EmojiUtil";
class snikket_Symbol {
	constructor(codepoints) {
		let builder_b = "";
		let _g = 0;
		while(_g < codepoints.length) {
			let codepoint = codepoints[_g];
			++_g;
			builder_b += String.fromCodePoint(codepoint);
		}
		this.value = builder_b;
	}
	toString() {
		return this.value;
	}
}
snikket_Symbol.__name__ = "snikket.Symbol";
Object.assign(snikket_Symbol.prototype, {
	__class__: snikket_Symbol
});
class snikket_Emoji extends snikket_Symbol {
	constructor(codepoints) {
		super(codepoints);
	}
	isEmoji() {
		return true;
	}
}
snikket_Emoji.__name__ = "snikket.Emoji";
snikket_Emoji.__super__ = snikket_Symbol;
Object.assign(snikket_Emoji.prototype, {
	__class__: snikket_Emoji
});
class snikket_Other extends snikket_Symbol {
	constructor(codepoints) {
		super(codepoints);
	}
	isEmoji() {
		return false;
	}
}
snikket_Other.__name__ = "snikket.Other";
snikket_Other.__super__ = snikket_Symbol;
Object.assign(snikket_Other.prototype, {
	__class__: snikket_Other
});
class snikket_Builder {
	constructor() {
		this.codepoints = [];
	}
	offer(codepoint) {
		let add = false;
		if(this.codepoints.length == 0) {
			if(snikket_EmojiUtil.SYMBOLIZE.contains(codepoint)) {
				add = true;
			} else if(snikket_EmojiUtil.REGIONAL_INDICATORS.contains(codepoint)) {
				add = true;
			} else if(snikket_EmojiUtil.EMOJIS.contains(codepoint) && !snikket_EmojiUtil.FITZPATRICK.contains(codepoint) && codepoint != snikket_EmojiUtil.ZWJ) {
				add = true;
			}
		} else {
			let previous = this.codepoints[this.codepoints.length - 1];
			if(this.codepoints[0] == snikket_EmojiUtil.BLACK_FLAG) {
				add = snikket_EmojiUtil.TAGS.contains(codepoint);
			} else if(snikket_EmojiUtil.COMBINING_ENCLOSING_KEYCAP == codepoint) {
				add = snikket_EmojiUtil.KEYCAP_COMBINEABLE.contains(previous) || previous == snikket_EmojiUtil.VARIATION_16;
			} else if(snikket_EmojiUtil.SYMBOLIZE.contains(previous)) {
				add = codepoint == snikket_EmojiUtil.VARIATION_16;
			} else if(snikket_EmojiUtil.REGIONAL_INDICATORS.contains(previous) && snikket_EmojiUtil.REGIONAL_INDICATORS.contains(codepoint)) {
				add = this.codepoints.length == 1;
			} else if(previous == snikket_EmojiUtil.VARIATION_16) {
				add = snikket_Builder.isMerger(codepoint) || codepoint == snikket_EmojiUtil.VARIATION_16;
			} else if(snikket_EmojiUtil.FITZPATRICK.contains(previous)) {
				add = codepoint == snikket_EmojiUtil.ZWJ;
			} else if(snikket_EmojiUtil.ZWJ == previous) {
				add = snikket_EmojiUtil.EMOJIS.contains(codepoint);
			} else if(snikket_Builder.isMerger(codepoint)) {
				add = true;
			} else if(codepoint == snikket_EmojiUtil.VARIATION_16 && snikket_EmojiUtil.EMOJIS.contains(previous)) {
				add = true;
			}
		}
		if(add) {
			this.codepoints.push(codepoint);
			return true;
		} else {
			return false;
		}
	}
	build() {
		if(this.codepoints.length > 0 && snikket_EmojiUtil.SYMBOLIZE.contains(this.codepoints[this.codepoints.length - 1])) {
			return new snikket_Other(this.codepoints);
		} else if(this.codepoints.length > 1 && snikket_EmojiUtil.KEYCAP_COMBINEABLE.contains(this.codepoints[0]) && this.codepoints[this.codepoints.length - 1] != snikket_EmojiUtil.COMBINING_ENCLOSING_KEYCAP) {
			return new snikket_Other(this.codepoints);
		}
		if(this.codepoints.length == 0) {
			return new snikket_Other(this.codepoints);
		} else {
			return new snikket_Emoji(this.codepoints);
		}
	}
	static isMerger(codepoint) {
		if(codepoint != snikket_EmojiUtil.ZWJ) {
			return snikket_EmojiUtil.FITZPATRICK.contains(codepoint);
		} else {
			return true;
		}
	}
}
snikket_Builder.__name__ = "snikket.Builder";
Object.assign(snikket_Builder.prototype, {
	__class__: snikket_Builder
});
var snikket_EventResult = $hxEnums["snikket.EventResult"] = { __ename__:true,__constructs__:null
	,EventHandled: {_hx_name:"EventHandled",_hx_index:0,__enum__:"snikket.EventResult",toString:$estr}
	,EventUnhandled: {_hx_name:"EventUnhandled",_hx_index:1,__enum__:"snikket.EventResult",toString:$estr}
	,EventStop: {_hx_name:"EventStop",_hx_index:2,__enum__:"snikket.EventResult",toString:$estr}
	,EventValue: ($_=function(result) { return {_hx_index:3,result:result,__enum__:"snikket.EventResult",toString:$estr}; },$_._hx_name="EventValue",$_.__params__ = ["result"],$_)
};
snikket_EventResult.__constructs__ = [snikket_EventResult.EventHandled,snikket_EventResult.EventUnhandled,snikket_EventResult.EventStop,snikket_EventResult.EventValue];
class snikket_EventHandler {
	constructor(handlers,callback,onlyOnce) {
		this.onlyOnce = false;
		this.callback = null;
		this.handlers = null;
		this.handlers = handlers;
		this.callback = callback;
		if(onlyOnce != null) {
			this.onlyOnce = onlyOnce;
		}
	}
	call(data) {
		if(this.onlyOnce) {
			this.unsubscribe();
		}
		return this.callback(data);
	}
	once() {
		this.onlyOnce = true;
		return this;
	}
	unsubscribe() {
		HxOverrides.remove(this.handlers,this);
	}
}
snikket_EventHandler.__name__ = "snikket.EventHandler";
Object.assign(snikket_EventHandler.prototype, {
	__class__: snikket_EventHandler
});
class snikket_FSM extends snikket_EventEmitter {
	constructor(desc,initialState,initialAttr) {
		snikket_EventEmitter._hx_skip_constructor = true;
		super();
		snikket_EventEmitter._hx_skip_constructor = false;
		this._hx_constructor(desc,initialState,initialAttr);
	}
	_hx_constructor(desc,initialState,initialAttr) {
		this.currentStateAttributes = null;
		this.currentState = null;
		this.states = new Map([]);
		super._hx_constructor();
		let _g = 0;
		let _g1 = desc.transitions;
		while(_g < _g1.length) {
			let transition = _g1[_g];
			++_g;
			let from_states = transition.from;
			let _g2 = 0;
			while(_g2 < from_states.length) {
				let from_state = from_states[_g2];
				++_g2;
				let from_state_def = this.states.get(from_state);
				if(from_state_def == null) {
					from_state_def = new Map([]);
					this.states.set(from_state,from_state_def);
				}
				let to_state_def = this.states.get(transition.to);
				if(to_state_def == null) {
					to_state_def = new Map([]);
					this.states.set(transition.to,to_state_def);
				}
				if(this.states.get(from_state).get(transition.name) != null) {
					throw new haxe_Exception("Duplicate transition in FSM specification: " + transition.name + " from " + from_state);
				}
				this.states.get(from_state).set(transition.name,transition.to);
			}
		}
		if(desc.state_handlers != null) {
			let jsIterator = desc.state_handlers.entries();
			let _g_jsIterator = jsIterator;
			let _g_lastStep = jsIterator.next();
			while(!_g_lastStep.done) {
				let v = _g_lastStep.value;
				_g_lastStep = _g_jsIterator.next();
				let _g_key = v[0];
				let _g_value = v[1];
				let state = _g_key;
				let handler = _g_value;
				this.on("enter/" + state,function(data) {
					handler(data);
					return snikket_EventResult.EventHandled;
				});
			}
		}
		if(desc.transition_handlers != null) {
			let jsIterator = desc.transition_handlers.entries();
			let _g_jsIterator = jsIterator;
			let _g_lastStep = jsIterator.next();
			while(!_g_lastStep.done) {
				let v = _g_lastStep.value;
				_g_lastStep = _g_jsIterator.next();
				let _g_key = v[0];
				let _g_value = v[1];
				let transition = _g_key;
				let handler = _g_value;
				this.on("transition/" + transition,function(data) {
					if(handler(data) == false) {
						return snikket_EventResult.EventStop;
					}
					return snikket_EventResult.EventHandled;
				});
			}
		}
		this.currentState = initialState;
		this.currentStateAttributes = initialAttr;
		let initialEvent = { fsm : this, to : initialState, toAttr : initialAttr};
		this.notifyTransitioned(initialEvent,true);
	}
	can(name) {
		return this.states.get(this.currentState).get(name) != null;
	}
	getState() {
		return this.currentState;
	}
	event(name,attr) {
		let newState = this.states.get(this.currentState).get(name);
		if(newState == null) {
			throw new haxe_Exception("Invalid state transition: " + this.currentState + " cannot " + name);
		}
		let event = { fsm : this, name : name, to : newState, toAttr : attr, from : this.currentState, fromAttr : this.currentStateAttributes};
		if(this.notifyTransition(event) == false) {
			return false;
		}
		this.currentState = newState;
		this.currentStateAttributes = attr;
		this.notifyTransitioned(event,false);
		return true;
	}
	notifyTransition(event) {
		let ret = this.trigger("transition",event);
		if(ret == snikket_EventResult.EventStop) {
			return false;
		}
		if(event.to != event.from) {
			ret = this.trigger("leave/" + event.from,event);
			if(ret == snikket_EventResult.EventStop) {
				return false;
			}
		}
		ret = this.trigger("transition/" + event.name,event);
		if(ret == snikket_EventResult.EventStop) {
			return false;
		}
		return true;
	}
	notifyTransitioned(event,isInitial) {
		if(event.to != event.from) {
			this.trigger("enter/" + event.to,event);
		}
		if(isInitial == false) {
			if(event.name != null) {
				this.trigger("transitioned/" + event.name,event);
			}
			this.trigger("transitioned",event);
		}
	}
}
snikket_FSM.__name__ = "snikket.FSM";
snikket_FSM.__super__ = snikket_EventEmitter;
Object.assign(snikket_FSM.prototype, {
	__class__: snikket_FSM
});
var snikket_IqResult = $hxEnums["snikket.IqResult"] = { __ename__:true,__constructs__:null
	,IqResultElement: ($_=function(element) { return {_hx_index:0,element:element,__enum__:"snikket.IqResult",toString:$estr}; },$_._hx_name="IqResultElement",$_.__params__ = ["element"],$_)
	,IqResult: {_hx_name:"IqResult",_hx_index:1,__enum__:"snikket.IqResult",toString:$estr}
	,IqNoResult: {_hx_name:"IqNoResult",_hx_index:2,__enum__:"snikket.IqResult",toString:$estr}
};
snikket_IqResult.__constructs__ = [snikket_IqResult.IqResultElement,snikket_IqResult.IqResult,snikket_IqResult.IqNoResult];
class snikket_GenericStream extends snikket_EventEmitter {
	constructor() {
		if(snikket_EventEmitter._hx_skip_constructor) {
			super();
			return;
		}
		snikket_EventEmitter._hx_skip_constructor = true;
		super();
		snikket_EventEmitter._hx_skip_constructor = false;
		this._hx_constructor();
	}
	_hx_constructor() {
		this.csi = false;
		this.clientId = null;
		super._hx_constructor();
	}
	sendIq(stanza,callback) {
		let id = this.newId();
		stanza.attr["id"] = id;
		this.once("iq-response/" + id,function(event) {
			callback(event.stanza);
			return snikket_EventResult.EventHandled;
		});
		this.sendStanza(stanza);
	}
	onStanza(stanza) {
		haxe_Log.trace("stanza received!",{ fileName : "snikket/GenericStream.hx", lineNumber : 40, className : "snikket.GenericStream", methodName : "onStanza"});
		let xmlns = stanza.attr["xmlns"];
		if(xmlns == "jabber:client") {
			let name = stanza.name;
			if(name == "iq") {
				let type = stanza.attr["type"];
				haxe_Log.trace("type: " + type,{ fileName : "snikket/GenericStream.hx", lineNumber : 46, className : "snikket.GenericStream", methodName : "onStanza"});
				if(type == "result" || type == "error") {
					let id = stanza.attr["id"];
					this.trigger("iq-response/" + id,{ stanza : stanza});
				}
			} else if(name == "message" || name == "presence") {
				this.trigger(name,{ stanza : stanza});
			}
		}
	}
}
snikket_GenericStream.__name__ = "snikket.GenericStream";
snikket_GenericStream.__super__ = snikket_EventEmitter;
Object.assign(snikket_GenericStream.prototype, {
	__class__: snikket_GenericStream
});
class snikket_Hash {
	constructor(algorithm,hash) {
		this.algorithm = algorithm;
		this.hash = hash;
	}
	toUri() {
		if(snikket_Config.relativeHashUri) {
			let s = this.algorithm;
			return "/.well-known/ni/" + encodeURIComponent(s) + "/" + this.toBase64Url();
		} else {
			return this.serializeUri();
		}
	}
	bobUri() {
		let tmp;
		if(this.algorithm == "sha-1") {
			tmp = "sha1";
		} else {
			let s = this.algorithm;
			tmp = encodeURIComponent(s);
		}
		return "cid:" + tmp + "+" + this.toHex() + "@bob.xmpp.org";
	}
	serializeUri() {
		let s = this.algorithm;
		return "ni:///" + encodeURIComponent(s) + ";" + this.toBase64Url();
	}
	toHex() {
		return haxe_io_Bytes.ofData(this.hash).toHex();
	}
	toBase64() {
		return haxe_crypto_Base64.encode(haxe_io_Bytes.ofData(this.hash),true);
	}
	toBase64Url() {
		return haxe_crypto_Base64.urlEncode(haxe_io_Bytes.ofData(this.hash));
	}
	static fromHex(algorithm,hash) {
		try {
			return new snikket_Hash(algorithm,haxe_io_Bytes.ofHex(hash).b.bufferValue);
		} catch( _g ) {
			return null;
		}
	}
	static fromUri(uri) {
		if(uri.startsWith("cid:") && uri.endsWith("@bob.xmpp.org") && uri.includes("+")) {
			let parts = HxOverrides.substr(uri,4,null).split("@")[0].split("+");
			let algo = parts[0] == "sha1" ? "sha-1" : parts[0];
			return snikket_Hash.fromHex(algo,parts[1]);
		}
		if(uri.startsWith("ni:///") && uri.includes(";")) {
			let parts = uri.substring(6).split(";");
			return new snikket_Hash(parts[0],haxe_crypto_Base64.urlDecode(parts[1]).b.bufferValue);
		} else if(uri.startsWith("/.well-known/ni/")) {
			let parts = uri.substring(16).split("/");
			return new snikket_Hash(parts[0],haxe_crypto_Base64.urlDecode(parts[1]).b.bufferValue);
		}
		return null;
	}
	static sha1(bytes) {
		return new snikket_Hash("sha-1",haxe_crypto_Sha1.make(bytes).b.bufferValue);
	}
	static sha256(bytes) {
		return new snikket_Hash("sha-256",haxe_crypto_Sha256.make(bytes).b.bufferValue);
	}
}
$hx_exports["snikket"]["Hash"] = snikket_Hash;
snikket_Hash.__name__ = "snikket.Hash";
Object.assign(snikket_Hash.prototype, {
	__class__: snikket_Hash
});
class snikket_ID {
	static tiny() {
		return hx_strings_RandomStrings.random(6,hx_strings_internal__$Either2__$Either2.b(hx_strings_RandomStrings.ASCII_ALPHA_NUMERIC));
	}
	static short() {
		return hx_strings_RandomStrings.random(18,hx_strings_internal__$Either2__$Either2.b(hx_strings_RandomStrings.ASCII_ALPHA_NUMERIC));
	}
	static medium() {
		return hx_strings_RandomStrings.random(32,hx_strings_internal__$Either2__$Either2.b(hx_strings_RandomStrings.ASCII_ALPHA_NUMERIC));
	}
	static long() {
		return hx_strings_RandomStrings.randomUUIDv4();
	}
}
snikket_ID.__name__ = "snikket.ID";
class snikket_Identicon {
	static svg(source) {
		let sha = haxe_crypto_Sha1.make(haxe_io_Bytes.ofString(source));
		let input = new haxe_io_BytesInput(sha);
		input.set_bigEndian(true);
		let hash = input.readInt32();
		let uri = "data:image/svg+xml,<svg%20xmlns=\"http://www.w3.org/2000/svg\"%20version=\"1.1\"%20width=\"5\"%20height=\"5\"%20viewBox=\"0%200%205%205\">";
		uri += "<style>rect{fill:%23" + HxOverrides.substr(snikket_Color.forString(source),1,null) + ";}</style>";
		let i = 0;
		let value = hash >> i++;
		if(value % 2 == 0) {
			uri += "<rect%20width=\"1\"%20height=\"1\"%20x=\"" + 0 + "\"%20y=\"" + 0 + "\"/>";
			uri += "<rect%20width=\"1\"%20height=\"1\"%20x=\"" + 4 + "\"%20y=\"" + 0 + "\"/>";
		}
		let value1 = hash >> i++;
		if(value1 % 2 == 0) {
			uri += "<rect%20width=\"1\"%20height=\"1\"%20x=\"" + 0 + "\"%20y=\"" + 1 + "\"/>";
			uri += "<rect%20width=\"1\"%20height=\"1\"%20x=\"" + 4 + "\"%20y=\"" + 1 + "\"/>";
		}
		let value2 = hash >> i++;
		if(value2 % 2 == 0) {
			uri += "<rect%20width=\"1\"%20height=\"1\"%20x=\"" + 0 + "\"%20y=\"" + 2 + "\"/>";
			uri += "<rect%20width=\"1\"%20height=\"1\"%20x=\"" + 4 + "\"%20y=\"" + 2 + "\"/>";
		}
		let value3 = hash >> i++;
		if(value3 % 2 == 0) {
			uri += "<rect%20width=\"1\"%20height=\"1\"%20x=\"" + 0 + "\"%20y=\"" + 3 + "\"/>";
			uri += "<rect%20width=\"1\"%20height=\"1\"%20x=\"" + 4 + "\"%20y=\"" + 3 + "\"/>";
		}
		let value4 = hash >> i++;
		if(value4 % 2 == 0) {
			uri += "<rect%20width=\"1\"%20height=\"1\"%20x=\"" + 0 + "\"%20y=\"" + 4 + "\"/>";
			uri += "<rect%20width=\"1\"%20height=\"1\"%20x=\"" + 4 + "\"%20y=\"" + 4 + "\"/>";
		}
		let value5 = hash >> i++;
		if(value5 % 2 == 0) {
			uri += "<rect%20width=\"1\"%20height=\"1\"%20x=\"" + 1 + "\"%20y=\"" + 0 + "\"/>";
			uri += "<rect%20width=\"1\"%20height=\"1\"%20x=\"" + 3 + "\"%20y=\"" + 0 + "\"/>";
		}
		let value6 = hash >> i++;
		if(value6 % 2 == 0) {
			uri += "<rect%20width=\"1\"%20height=\"1\"%20x=\"" + 1 + "\"%20y=\"" + 1 + "\"/>";
			uri += "<rect%20width=\"1\"%20height=\"1\"%20x=\"" + 3 + "\"%20y=\"" + 1 + "\"/>";
		}
		let value7 = hash >> i++;
		if(value7 % 2 == 0) {
			uri += "<rect%20width=\"1\"%20height=\"1\"%20x=\"" + 1 + "\"%20y=\"" + 2 + "\"/>";
			uri += "<rect%20width=\"1\"%20height=\"1\"%20x=\"" + 3 + "\"%20y=\"" + 2 + "\"/>";
		}
		let value8 = hash >> i++;
		if(value8 % 2 == 0) {
			uri += "<rect%20width=\"1\"%20height=\"1\"%20x=\"" + 1 + "\"%20y=\"" + 3 + "\"/>";
			uri += "<rect%20width=\"1\"%20height=\"1\"%20x=\"" + 3 + "\"%20y=\"" + 3 + "\"/>";
		}
		let value9 = hash >> i++;
		if(value9 % 2 == 0) {
			uri += "<rect%20width=\"1\"%20height=\"1\"%20x=\"" + 1 + "\"%20y=\"" + 4 + "\"/>";
			uri += "<rect%20width=\"1\"%20height=\"1\"%20x=\"" + 3 + "\"%20y=\"" + 4 + "\"/>";
		}
		let value10 = hash >> i++;
		if(value10 % 2 == 0) {
			uri += "<rect%20width=\"1\"%20height=\"1\"%20x=\"" + 2 + "\"%20y=\"" + 0 + "\"/>";
		}
		let value11 = hash >> i++;
		if(value11 % 2 == 0) {
			uri += "<rect%20width=\"1\"%20height=\"1\"%20x=\"" + 2 + "\"%20y=\"" + 1 + "\"/>";
		}
		let value12 = hash >> i++;
		if(value12 % 2 == 0) {
			uri += "<rect%20width=\"1\"%20height=\"1\"%20x=\"" + 2 + "\"%20y=\"" + 2 + "\"/>";
		}
		let value13 = hash >> i++;
		if(value13 % 2 == 0) {
			uri += "<rect%20width=\"1\"%20height=\"1\"%20x=\"" + 2 + "\"%20y=\"" + 3 + "\"/>";
		}
		let value14 = hash >> i++;
		if(value14 % 2 == 0) {
			uri += "<rect%20width=\"1\"%20height=\"1\"%20x=\"" + 2 + "\"%20y=\"" + 4 + "\"/>";
		}
		return uri + "</svg>";
	}
}
$hx_exports["snikket"]["Identicon"] = snikket_Identicon;
snikket_Identicon.__name__ = "snikket.Identicon";
class snikket_JID {
	constructor(node,domain,resource) {
		this.node = node == null ? null : StringTools.replace(StringTools.replace(StringTools.replace(StringTools.replace(StringTools.replace(StringTools.replace(StringTools.replace(StringTools.replace(StringTools.replace(StringTools.replace(StringTools.replace(StringTools.replace(StringTools.replace(StringTools.replace(StringTools.replace(StringTools.replace(StringTools.replace(StringTools.replace(StringTools.replace(StringTools.trim(node),"\\5c","\\5c5c"),"\\20","\\5c20"),"\\22","\\5c22"),"\\26","\\5c26"),"\\27","\\5c27"),"\\2f","\\5c2f"),"\\3a","\\5c3a"),"\\3c","\\5c3c"),"\\3e","\\5c3e"),"\\40","\\5c40")," ","\\20"),"\"","\\22"),"&","\\26"),"'","\\27"),"/","\\2f"),":","\\3a"),"<","\\3c"),">","\\3e"),"@","\\40");
		this.domain = domain;
		this.resource = resource;
	}
	asBare() {
		return new snikket_JID(this.node,this.domain);
	}
	withResource(resource) {
		return new snikket_JID(this.node,this.domain,resource);
	}
	isValid() {
		return this.domain.indexOf(".") >= 0;
	}
	isDomain() {
		return this.node == null;
	}
	isBare() {
		return this.resource == null;
	}
	equals(rhs) {
		if(this.node == rhs.node && this.domain == rhs.domain) {
			return this.resource == rhs.resource;
		} else {
			return false;
		}
	}
	asString() {
		return (this.node != null ? this.node + "@" : "") + this.domain + (this.resource != null ? "/" + this.resource : "");
	}
	static parse(jid) {
		let resourceDelimiter = jid.indexOf("/");
		let nodeDelimiter = jid.indexOf("@");
		if(resourceDelimiter > 0 && nodeDelimiter >= resourceDelimiter) {
			nodeDelimiter = -1;
		}
		return new snikket_JID(nodeDelimiter > 0 ? HxOverrides.substr(jid,0,nodeDelimiter) : null,jid.substring(nodeDelimiter == -1 ? 0 : nodeDelimiter + 1,resourceDelimiter == -1 ? jid.length + 1 : resourceDelimiter),resourceDelimiter == -1 ? null : jid.substring(resourceDelimiter + 1));
	}
}
$hx_exports["snikket"]["JID"] = snikket_JID;
snikket_JID.__name__ = "snikket.JID";
Object.assign(snikket_JID.prototype, {
	__class__: snikket_JID
});
class snikket_Map {
	static set(this1,k,v) {
		this1.set(k,v);
	}
	static get(this1,k) {
		return this1.get(k);
	}
	static exists(this1,k) {
		return this1.has(k);
	}
	static remove(this1,k) {
		return this1.delete(k);
	}
	static keys(this1) {
		return new js_lib_HaxeIterator(this1.keys());
	}
	static iterator(this1) {
		return new js_lib_HaxeIterator(this1.values());
	}
	static keyValueIterator(this1) {
		return new snikket_HaxeKVIterator(this1.entries());
	}
	static flatMap(this1,f) {
		let _g = [];
		let x = $getIterator({ iterator : function() {
			return new js_lib_HaxeIterator(this1.values());
		}});
		while(x.hasNext()) {
			let x1 = x.next();
			_g.push(f(x1));
		}
		let _g1 = [];
		let e = $getIterator(_g);
		while(e.hasNext()) {
			let e1 = e.next();
			let x = $getIterator(e1);
			while(x.hasNext()) {
				let x1 = x.next();
				_g1.push(x1);
			}
		}
		return _g1;
	}
	static arrayRead(this1,k) {
		return this1.get(k);
	}
	static arrayWrite(this1,k,v) {
		this1.set(k,v);
		return v;
	}
	static fromMap(map) {
		let result = new Map();
		let _g = map.keyValueIterator();
		while(_g.hasNext()) {
			let _g1 = _g.next();
			let k = _g1.key;
			let v = _g1.value;
			result.set(k,v);
		}
		return result;
	}
	static fromArray(iterable) {
		return new Map(iterable);
	}
}
class snikket_HaxeKVIterator {
	constructor(jsIterator) {
		this.jsIterator = jsIterator;
		this.lastStep = jsIterator.next();
	}
	hasNext() {
		return !this.lastStep.done;
	}
	next() {
		let v = this.lastStep.value;
		this.lastStep = this.jsIterator.next();
		return { key : v[0], value : v[1]};
	}
}
snikket_HaxeKVIterator.__name__ = "snikket.HaxeKVIterator";
Object.assign(snikket_HaxeKVIterator.prototype, {
	__class__: snikket_HaxeKVIterator
});
var snikket_MessageStanza = $hxEnums["snikket.MessageStanza"] = { __ename__:true,__constructs__:null
	,ErrorMessageStanza: ($_=function(stanza) { return {_hx_index:0,stanza:stanza,__enum__:"snikket.MessageStanza",toString:$estr}; },$_._hx_name="ErrorMessageStanza",$_.__params__ = ["stanza"],$_)
	,ChatMessageStanza: ($_=function(message) { return {_hx_index:1,message:message,__enum__:"snikket.MessageStanza",toString:$estr}; },$_._hx_name="ChatMessageStanza",$_.__params__ = ["message"],$_)
	,ModerateMessageStanza: ($_=function(action) { return {_hx_index:2,action:action,__enum__:"snikket.MessageStanza",toString:$estr}; },$_._hx_name="ModerateMessageStanza",$_.__params__ = ["action"],$_)
	,ReactionUpdateStanza: ($_=function(update) { return {_hx_index:3,update:update,__enum__:"snikket.MessageStanza",toString:$estr}; },$_._hx_name="ReactionUpdateStanza",$_.__params__ = ["update"],$_)
	,UnknownMessageStanza: ($_=function(stanza) { return {_hx_index:4,stanza:stanza,__enum__:"snikket.MessageStanza",toString:$estr}; },$_._hx_name="UnknownMessageStanza",$_.__params__ = ["stanza"],$_)
};
snikket_MessageStanza.__constructs__ = [snikket_MessageStanza.ErrorMessageStanza,snikket_MessageStanza.ChatMessageStanza,snikket_MessageStanza.ModerateMessageStanza,snikket_MessageStanza.ReactionUpdateStanza,snikket_MessageStanza.UnknownMessageStanza];
class snikket_Message {
	constructor(chatId,senderId,threadId,parsed) {
		this.chatId = chatId;
		this.senderId = senderId;
		this.threadId = threadId;
		this.parsed = parsed;
	}
	static fromStanza(stanza,localJid,addContext) {
		let fromAttr = stanza.attr["from"];
		let from = fromAttr == null ? localJid.domain : fromAttr;
		if(stanza.attr["type"] == "error") {
			return new snikket_Message(from,from,null,snikket_MessageStanza.ErrorMessageStanza(stanza));
		}
		let msg = new snikket_ChatMessageBuilder();
		msg.stanza = stanza;
		msg.timestamp = stanza.findText("{urn:xmpp:delay}delay@stamp");
		msg.threadId = stanza.getChildText("thread");
		msg.lang = stanza.attr["xml:lang"];
		msg.text = stanza.getChildText("body");
		if(msg.text != null && (msg.lang == null || msg.lang == "")) {
			let tmp = stanza.getChild("body");
			msg.lang = tmp != null ? tmp.attr["xml:lang"] : null;
		}
		msg.from = snikket_JID.parse(from);
		let isGroupchat = stanza.attr["type"] == "groupchat";
		msg.type = isGroupchat ? 2 : 0;
		let tmp;
		if(isGroupchat) {
			tmp = msg.from;
		} else {
			let tmp1 = msg.from;
			tmp = tmp1 != null ? tmp1.asBare() : null;
		}
		msg.senderId = tmp != null ? tmp.asString() : null;
		let localJidBare = localJid.asBare();
		let domain = localJid.domain;
		let to = stanza.attr["to"];
		msg.to = to == null ? localJid : snikket_JID.parse(to);
		if(msg.from != null && msg.from.equals(localJidBare)) {
			let carbon = stanza.getChild("received","urn:xmpp:carbons:2");
			if(carbon == null) {
				carbon = stanza.getChild("sent","urn:xmpp:carbons:2");
			}
			if(carbon != null) {
				let fwd = carbon.getChild("forwarded","urn:xmpp:forward:0");
				if(fwd != null) {
					return snikket_Message.fromStanza(fwd.getFirstChild(),localJid);
				}
			}
		}
		let localId = stanza.attr["id"];
		if(localId != null) {
			msg.localId = localId;
		}
		let altServerId = null;
		let _g = 0;
		let _g1 = stanza.allTags("stanza-id","urn:xmpp:sid:0");
		while(_g < _g1.length) {
			let stanzaId = _g1[_g];
			++_g;
			let id = stanzaId.attr["id"];
			if((stanzaId.attr["by"] == domain || stanzaId.attr["by"] == localJidBare.asString()) && id != null) {
				msg.serverIdBy = localJidBare.asString();
				msg.serverId = id;
				break;
			}
			altServerId = stanzaId;
		}
		if(msg.serverId == null && altServerId != null && stanza.attr["type"] != "error") {
			let id = altServerId.attr["id"];
			if(id != null) {
				msg.serverId = id;
				msg.serverIdBy = altServerId.attr["by"];
			}
		}
		if(msg.serverIdBy != null && msg.serverIdBy != localJid.asBare().asString()) {
			msg.replyId = msg.serverId;
		} else if(msg.serverIdBy == localJid.asBare().asString()) {
			msg.replyId = msg.localId;
		}
		msg.direction = msg.to == null || msg.to.asBare().equals(localJidBare) ? 0 : 1;
		if(msg.from != null && msg.from.asBare().equals(localJidBare)) {
			msg.direction = 1;
		}
		msg.status = msg.direction == 0 ? 2 : 1;
		let recipients = new Map([]);
		let replyTo = new Map([]);
		if(msg.to != null) {
			let k = msg.to.asBare().asString();
			recipients.set(k,true);
		}
		let from1 = msg.from;
		if(msg.direction == 0 && from1 != null) {
			let k = isGroupchat ? from1.asBare().asString() : from1.asString();
			replyTo.set(k,true);
		} else if(msg.to != null) {
			let k = msg.to.asString();
			replyTo.set(k,true);
		}
		let addresses = stanza.getChild("addresses","http://jabber.org/protocol/address");
		let anyExtendedReplyTo = false;
		if(addresses != null) {
			let _g = 0;
			let _g1 = addresses.allTags("address");
			while(_g < _g1.length) {
				let address = _g1[_g];
				++_g;
				let jid = address.attr["jid"];
				if(address.attr["type"] == "noreply") {
					replyTo.clear();
				} else if(jid == null) {
					haxe_Log.trace("No support for addressing to non-jid",{ fileName : "snikket/Message.hx", lineNumber : 128, className : "snikket.Message", methodName : "fromStanza", customParams : [address]});
					return new snikket_Message(msg.chatId(),msg.get_senderId(),msg.threadId,snikket_MessageStanza.UnknownMessageStanza(stanza));
				} else if(address.attr["type"] == "to" || address.attr["type"] == "cc") {
					let k = snikket_JID.parse(jid).asBare().asString();
					recipients.set(k,true);
					if(!anyExtendedReplyTo) {
						let k = snikket_JID.parse(jid).asString();
						replyTo.set(k,true);
					}
				} else if(address.attr["type"] == "replyto" || address.attr["type"] == "replyroom") {
					if(!anyExtendedReplyTo) {
						replyTo.clear();
						anyExtendedReplyTo = true;
					}
					let k = snikket_JID.parse(jid).asString();
					replyTo.set(k,true);
				} else if(address.attr["type"] == "ofrom") {
					let tmp = msg.from;
					let tmp1 = tmp != null ? tmp.domain : null;
					if(snikket_JID.parse(jid).domain == tmp1) {
						msg.senderId = snikket_JID.parse(jid).asBare().asString();
					}
				}
			}
		}
		let _g2 = [];
		let inlobj_iterator = function() {
			return new js_lib_HaxeIterator(recipients.keys());
		};
		let x = inlobj_iterator();
		while(x.hasNext()) {
			let x1 = x.next();
			_g2.push(snikket_JID.parse(x1));
		}
		msg.recipients = _g2;
		msg.recipients.sort(function(x,y) {
			return Reflect.compare(x.asString(),y.asString());
		});
		let _g3 = [];
		let inlobj_iterator1 = function() {
			return new js_lib_HaxeIterator(replyTo.keys());
		};
		let x1 = inlobj_iterator1();
		while(x1.hasNext()) {
			let x = x1.next();
			_g3.push(snikket_JID.parse(x));
		}
		msg.replyTo = _g3;
		msg.replyTo.sort(function(x,y) {
			return Reflect.compare(x.asString(),y.asString());
		});
		let msgFrom = msg.from;
		if(msg.direction == 0 && msgFrom != null && Lambda.find(msg.replyTo,function(r) {
			return r.asBare().equals(msgFrom.asBare());
		}) == null) {
			haxe_Log.trace("Don't know what chat message without from in replyTo belongs in",{ fileName : "snikket/Message.hx", lineNumber : 155, className : "snikket.Message", methodName : "fromStanza", customParams : [stanza]});
			return new snikket_Message(msg.chatId(),msg.get_senderId(),msg.threadId,snikket_MessageStanza.UnknownMessageStanza(stanza));
		}
		if(addContext != null) {
			msg = addContext(msg,stanza);
		}
		let tmp1 = msg.timestamp;
		let timestamp = tmp1 != null ? tmp1 : snikket_Date.format(new Date());
		msg.timestamp = timestamp;
		let reactionsEl = stanza.getChild("reactions","urn:xmpp:reactions:0");
		if(reactionsEl != null) {
			let _this = reactionsEl.allTags("reaction");
			let result = new Array(_this.length);
			let _g = 0;
			let _g1 = _this.length;
			while(_g < _g1) {
				let i = _g++;
				result[i] = _this[i].getText();
			}
			let reactions = result;
			let reactionId = reactionsEl.attr["id"];
			if(reactionId != null) {
				let tmp = msg.chatId();
				let tmp1 = msg.get_senderId();
				let msg1 = msg.threadId;
				let tmp2 = stanza.attr["id"];
				let tmp3 = tmp2 != null ? tmp2 : snikket_ID.long();
				let tmp4 = isGroupchat ? reactionId : null;
				let tmp5 = isGroupchat ? msg.chatId() : null;
				let tmp6 = isGroupchat ? null : reactionId;
				let tmp7 = msg.chatId();
				let tmp8 = msg.get_senderId();
				let result = new Array(reactions.length);
				let _g = 0;
				let _g1 = reactions.length;
				while(_g < _g1) {
					let i = _g++;
					result[i] = new snikket_Reaction(msg.get_senderId(),timestamp,reactions[i],msg.localId);
				}
				return new snikket_Message(tmp,tmp1,msg1,snikket_MessageStanza.ReactionUpdateStanza(new snikket_ReactionUpdate(tmp3,tmp4,tmp5,tmp6,tmp7,tmp8,timestamp,result,0)));
			}
		}
		let _g4 = 0;
		let _g5 = stanza.allTags("reference","urn:xmpp:reference:0");
		while(_g4 < _g5.length) {
			let ref = _g5[_g4];
			++_g4;
			if(ref.attr["begin"] == null && ref.attr["end"] == null) {
				let sims = ref.getChild("media-sharing","urn:xmpp:sims:1");
				if(sims != null) {
					msg.attachSims(sims);
				}
			}
		}
		let _g6 = 0;
		let _g7 = stanza.allTags("media-sharing","urn:xmpp:sims:1");
		while(_g6 < _g7.length) {
			let sims = _g7[_g6];
			++_g6;
			msg.attachSims(sims);
		}
		let jmi = stanza.getChild(null,"urn:xmpp:jingle-message:0");
		if(jmi != null) {
			msg.type = 1;
			msg.payloads.push(jmi);
			if(msg.text == null) {
				msg.text = "call " + jmi.name;
			}
			if(jmi.name != "propose") {
				msg.versions = [msg.build()];
			}
			msg.localId = jmi.attr["id"];
		}
		let retract = stanza.getChild("replace","urn:xmpp:message-retract:1");
		let fasten = stanza.getChild("apply-to","urn:xmpp:fasten:0");
		let tmp2 = retract != null ? retract.getChild("moderated","urn:xmpp:message-retract:1") : null;
		let moderated = tmp2 != null ? tmp2 : fasten != null ? fasten.getChild("moderated","urn:xmpp:message-moderate:0") : null;
		let moderateServerId;
		let tmp3 = retract != null ? retract.attr : null;
		let tmp4 = tmp3 != null ? tmp3["id"] : null;
		if(tmp4 != null) {
			moderateServerId = tmp4;
		} else {
			let tmp = fasten != null ? fasten.attr : null;
			moderateServerId = tmp != null ? tmp["id"] : null;
		}
		if(moderated != null && moderateServerId != null && isGroupchat && msg.from != null && msg.from.isBare() && msg.from.asString() == msg.chatId()) {
			let tmp = retract != null ? retract.getChildText("reason") : null;
			let reason = tmp != null ? tmp : moderated != null ? moderated.getChildText("reason") : null;
			let by = moderated.attr["by"];
			return new snikket_Message(msg.chatId(),msg.get_senderId(),msg.threadId,snikket_MessageStanza.ModerateMessageStanza(new snikket_ModerationAction(msg.chatId(),moderateServerId,timestamp,by,reason)));
		}
		let replace = stanza.getChild("replace","urn:xmpp:message-correct:0");
		let tmp5 = replace != null ? replace.attr : null;
		let replaceId = tmp5 != null ? tmp5["id"] : null;
		if(msg.text == null && msg.attachments.length < 1 && replaceId == null) {
			return new snikket_Message(msg.chatId(),msg.get_senderId(),msg.threadId,snikket_MessageStanza.UnknownMessageStanza(stanza));
		}
		let _g8 = 0;
		let _g9 = stanza.allTags("fallback","urn:xmpp:fallback:0");
		while(_g8 < _g9.length) {
			let fallback = _g9[_g8];
			++_g8;
			msg.payloads.push(fallback);
		}
		let unstyled = stanza.getChild("unstyled","urn:xmpp:styling:0");
		if(unstyled != null) {
			msg.payloads.push(unstyled);
		}
		let html = stanza.getChild("html","http://jabber.org/protocol/xhtml-im");
		if(html != null) {
			msg.payloads.push(html);
		}
		let reply = stanza.getChild("reply","urn:xmpp:reply:0");
		if(reply != null) {
			let replyToJid = reply.attr["to"];
			let replyToID = reply.attr["id"];
			let text = msg.text;
			if(text != null && snikket_EmojiUtil.isOnlyEmoji(StringTools.trim(text))) {
				let tmp = msg.chatId();
				let tmp1 = msg.get_senderId();
				let msg1 = msg.threadId;
				let tmp2 = stanza.attr["id"];
				let tmp3 = tmp2 != null ? tmp2 : snikket_ID.long();
				let tmp4 = isGroupchat ? msg.chatId() : null;
				let tmp5 = msg.chatId();
				let tmp6 = msg.get_senderId();
				return new snikket_Message(tmp,tmp1,msg1,snikket_MessageStanza.ReactionUpdateStanza(new snikket_ReactionUpdate(tmp3,isGroupchat ? replyToID : null,tmp4,isGroupchat ? null : replyToID,tmp5,tmp6,timestamp,[new snikket_Reaction(msg.get_senderId(),timestamp,StringTools.trim(text),msg.localId)],1)));
			}
			if(html != null) {
				let body = html.getChild("body","http://www.w3.org/1999/xhtml");
				if(body != null) {
					let els = body.allTags();
					if(els.length == 1 && els[0].name == "img") {
						let tmp = els[0].attr["src"];
						let hash = snikket_Hash.fromUri(tmp != null ? tmp : "");
						if(hash != null) {
							let tmp = msg.chatId();
							let tmp1 = msg.get_senderId();
							let msg1 = msg.threadId;
							let tmp2 = stanza.attr["id"];
							let tmp3 = tmp2 != null ? tmp2 : snikket_ID.long();
							let tmp4 = isGroupchat ? msg.chatId() : null;
							let tmp5 = msg.chatId();
							let tmp6 = msg.get_senderId();
							let tmp7 = msg.get_senderId();
							let tmp8 = els[0].attr["alt"];
							return new snikket_Message(tmp,tmp1,msg1,snikket_MessageStanza.ReactionUpdateStanza(new snikket_ReactionUpdate(tmp3,isGroupchat ? replyToID : null,tmp4,isGroupchat ? null : replyToID,tmp5,tmp6,timestamp,[new snikket_CustomEmojiReaction(tmp7,timestamp,tmp8 != null ? tmp8 : "",hash.serializeUri(),msg.localId)],1)));
						}
					}
				}
			}
			if(replyToID != null) {
				let replyToMessage = new snikket_ChatMessageBuilder();
				replyToMessage.to = replyToJid == msg.get_senderId() ? msg.to : msg.from;
				replyToMessage.from = replyToJid == null ? null : snikket_JID.parse(replyToJid);
				let tmp = replyToMessage.from;
				replyToMessage.senderId = tmp != null ? tmp.asString() : null;
				replyToMessage.replyId = replyToID;
				if(msg.serverIdBy != null && msg.serverIdBy != localJid.asBare().asString()) {
					replyToMessage.serverId = replyToID;
				} else {
					replyToMessage.localId = replyToID;
				}
				msg.replyToMessage = replyToMessage.build();
			}
		}
		if(replaceId != null) {
			msg.versions = [msg.build()];
			msg.localId = replaceId;
		}
		return new snikket_Message(msg.chatId(),msg.get_senderId(),msg.threadId,snikket_MessageStanza.ChatMessageStanza(msg.build()));
	}
}
snikket_Message.__name__ = "snikket.Message";
Object.assign(snikket_Message.prototype, {
	__class__: snikket_Message
});
class snikket_MessageSync {
	constructor(client,stream,filter,serviceJID) {
		this.jmi = new Map([]);
		this.newestPageFirst = true;
		this.complete = false;
		this.progress = 0;
		this.contextHandler = function(b,_) {
			return b;
		};
		this.client = client;
		this.stream = stream;
		this.filter = Reflect.copy(filter);
		this.serviceJID = serviceJID != null ? serviceJID : client.accountId();
	}
	fetchNext() {
		if(this.handler == null) {
			throw new haxe_Exception("Attempt to fetch messages, but no handler has been set");
		}
		if(this.complete) {
			throw new haxe_Exception("Attempt to fetch messages, but already complete");
		}
		let messages = [];
		if(this.lastPage == null) {
			if(this.newestPageFirst == true && (this.filter.page == null || this.filter.page.before == null && this.filter.page.after == null)) {
				if(this.filter.page == null) {
					this.filter.page = { };
				}
				this.filter.page.before = "";
			}
		} else {
			if(this.filter.page == null) {
				this.filter.page = { };
			}
			if(this.newestPageFirst == true) {
				this.filter.page.before = this.lastPage.first;
			} else {
				this.filter.page.after = this.lastPage.last;
			}
		}
		let query = new snikket_queries_MAMQuery(this.filter,this.serviceJID);
		let _gthis = this;
		let resultHandler = this.stream.on("message",function(event) {
			_gthis.progress++;
			let message = event.stanza;
			let from = Object.prototype.hasOwnProperty.call(message.attr,"from") ? message.attr["from"] : _gthis.client.accountId();
			if(from != _gthis.serviceJID) {
				return snikket_EventResult.EventUnhandled;
			}
			let result = message.getChild("result",query.xmlns);
			if(result == null || result.attr["queryid"] != query.queryId) {
				return snikket_EventResult.EventUnhandled;
			}
			let originalMessage = result.findChild("{urn:xmpp:forward:0}forwarded/{jabber:client}message");
			if(originalMessage == null) {
				return snikket_EventResult.EventHandled;
			}
			let timestamp = result.findText("{urn:xmpp:forward:0}forwarded/{urn:xmpp:delay}delay@stamp");
			let jmiChildren = originalMessage.allTags(null,"urn:xmpp:jingle-message:0");
			if(jmiChildren.length > 0) {
				_gthis.jmi.set(jmiChildren[0].attr["id"],originalMessage);
			}
			let msg = snikket_Message.fromStanza(originalMessage,_gthis.client.jid,function(builder,stanza) {
				builder.serverId = result.attr["id"];
				builder.serverIdBy = _gthis.serviceJID;
				if(timestamp != null && builder.timestamp == null) {
					builder.timestamp = timestamp;
				}
				return _gthis.contextHandler(builder,stanza);
			}).parsed;
			messages.push(msg);
			return snikket_EventResult.EventHandled;
		});
		query.onFinished(function() {
			resultHandler.unsubscribe();
			let result = query.getResult();
			if(result == null) {
				haxe_Log.trace("Error from MAM, stopping sync",{ fileName : "snikket/MessageSync.hx", lineNumber : 101, className : "snikket.MessageSync", methodName : "fetchNext"});
				_gthis.complete = true;
				if(_gthis.errorHandler != null) {
					_gthis.errorHandler(query.responseStanza);
				}
			} else {
				_gthis.complete = result.complete;
				_gthis.lastPage = result.page;
			}
			if(result != null || _gthis.errorHandler == null) {
				_gthis.handler({ sync : _gthis, messages : messages});
			}
		});
		this.client.sendQuery(query);
	}
	hasMore() {
		return !this.complete;
	}
	addContext(handler) {
		this.contextHandler = handler;
	}
	onMessages(handler) {
		this.handler = handler;
	}
	onError(handler) {
		this.errorHandler = handler;
	}
	setNewestPageFirst(newestPageFirst) {
		this.newestPageFirst = newestPageFirst;
	}
}
snikket_MessageSync.__name__ = "snikket.MessageSync";
Object.assign(snikket_MessageSync.prototype, {
	__class__: snikket_MessageSync
});
class snikket_ModerationAction {
	constructor(chatId,moderateServerId,timestamp,moderatorId,reason) {
		this.chatId = chatId;
		this.moderateServerId = moderateServerId;
		this.timestamp = timestamp;
		this.moderatorId = moderatorId;
		this.reason = reason;
	}
}
snikket_ModerationAction.__name__ = "snikket.ModerationAction";
Object.assign(snikket_ModerationAction.prototype, {
	__class__: snikket_ModerationAction
});
class snikket_Notification {
	constructor(title,body,accountId,chatId,messageId,type,callStatus,callSid,imageUri,lang,timestamp) {
		this.title = title;
		this.body = body;
		this.accountId = accountId;
		this.chatId = chatId;
		this.messageId = messageId;
		this.type = type;
		this.callStatus = callStatus;
		this.callSid = callSid;
		this.imageUri = imageUri;
		this.lang = lang;
		this.timestamp = timestamp;
	}
	static fromChatMessage(m) {
		let imageUri = null;
		let attachment = m.attachments[0];
		if(attachment != null) {
			imageUri = attachment.uris[0];
		}
		return new snikket_Notification(m.type == 1 ? "Incoming Call" : "New Message",m.text,m.account(),m.chatId(),m.serverId,m.type,m.callStatus(),m.callSid(),imageUri,m.lang,m.timestamp);
	}
	static fromThinStanza(stanza) {
		return new snikket_Notification("New Message","",snikket_JID.parse(stanza.attr["to"]).asBare().asString(),snikket_JID.parse(stanza.attr["from"]).asBare().asString(),stanza.getChildText("stanza-id","urn:xmpp:sid:0"),0,null,null,null,null,null);
	}
}
$hx_exports["snikket"]["Notification"] = snikket_Notification;
snikket_Notification.__name__ = "snikket.Notification";
Object.assign(snikket_Notification.prototype, {
	__class__: snikket_Notification
});
class snikket_Participant {
	constructor(displayName,photoUri,placeholderUri,isSelf) {
		this.displayName = displayName;
		this.photoUri = photoUri;
		this.placeholderUri = placeholderUri;
		this.isSelf = isSelf;
	}
}
$hx_exports["snikket"]["Participant"] = snikket_Participant;
snikket_Participant.__name__ = "snikket.Participant";
Object.assign(snikket_Participant.prototype, {
	__class__: snikket_Participant
});
class snikket_Persistence {
}
snikket_Persistence.__name__ = "snikket.Persistence";
snikket_Persistence.__isInterface__ = true;
Object.assign(snikket_Persistence.prototype, {
	__class__: snikket_Persistence
});
class snikket_Presence {
	constructor(caps,mucUser) {
		this.caps = caps;
		this.mucUser = mucUser;
	}
}
$hx_exports["snikket"]["Presence"] = snikket_Presence;
snikket_Presence.__name__ = "snikket.Presence";
Object.assign(snikket_Presence.prototype, {
	__class__: snikket_Presence
});
class snikket_PubsubEvent {
	constructor(from,to,node,items) {
		this.from = from;
		this.to = to;
		this.node = node;
		this.items = items;
	}
	getFrom() {
		return this.from;
	}
	getNode() {
		return this.node;
	}
	getItems() {
		return this.items;
	}
	static fromStanza(stanza) {
		let event = stanza.getChild("event","http://jabber.org/protocol/pubsub#event");
		if(event == null) {
			return null;
		}
		let items = event.getChild("items");
		if(items == null) {
			return null;
		}
		return new snikket_PubsubEvent(stanza.attr["from"],stanza.attr["to"],items.attr["node"],items.allTags("item"));
	}
}
snikket_PubsubEvent.__name__ = "snikket.PubsubEvent";
Object.assign(snikket_PubsubEvent.prototype, {
	__class__: snikket_PubsubEvent
});
function snikket_Push_receive(data,persistence) {
	let stanza = snikket_Stanza.parse(data);
	if(stanza == null) {
		return null;
	}
	if(stanza.name == "envelope" && stanza.attr["xmlns"] == "urn:xmpp:sce:1") {
		stanza = stanza.getChild("content").getFirstChild();
	}
	if(stanza.name == "forwarded" && stanza.attr["xmlns"] == "urn:xmpp:forward:0") {
		stanza = stanza.getChild("message","jabber:client");
	}
	if(stanza.attr["to"] == null) {
		return null;
	}
	let message = snikket_ChatMessage.fromStanza(stanza,snikket_JID.parse(stanza.attr["to"]).asBare());
	if(message != null) {
		return snikket_Notification.fromChatMessage(message);
	} else {
		return snikket_Notification.fromThinStanza(stanza);
	}
}
$hx_exports["snikket"]["Push"]["receive"] = snikket_Push_receive;
class snikket_Reaction {
	constructor(senderId,timestamp,text,envelopeId,key) {
		this.senderId = senderId;
		this.timestamp = timestamp;
		this.text = StringTools.replace(text,"️","");
		this.envelopeId = envelopeId;
		let tmp = key;
		this.key = tmp != null ? tmp : this.text;
	}
	render(forText,forImage) {
		return forText(this.text + "️");
	}
}
$hx_exports["snikket"]["Reaction"] = snikket_Reaction;
snikket_Reaction.__name__ = "snikket.Reaction";
Object.assign(snikket_Reaction.prototype, {
	__class__: snikket_Reaction
});
class snikket_CustomEmojiReaction extends snikket_Reaction {
	constructor(senderId,timestamp,text,uri,envelopeId) {
		super(senderId,timestamp,text,envelopeId,uri);
		this.uri = uri;
	}
	render(forText,forImage) {
		let hash = snikket_Hash.fromUri(this.uri);
		let tmp = this.text;
		let tmp1 = hash != null ? hash.toUri() : null;
		return forImage(tmp,tmp1 != null ? tmp1 : this.uri);
	}
}
$hx_exports["snikket"]["CustomEmojiReaction"] = snikket_CustomEmojiReaction;
snikket_CustomEmojiReaction.__name__ = "snikket.CustomEmojiReaction";
snikket_CustomEmojiReaction.__super__ = snikket_Reaction;
Object.assign(snikket_CustomEmojiReaction.prototype, {
	__class__: snikket_CustomEmojiReaction
});
class snikket_ReactionUpdate {
	constructor(updateId,serverId,serverIdBy,localId,chatId,senderId,timestamp,reactions,kind) {
		if(serverId == null && localId == null) {
			throw haxe_Exception.thrown("ReactionUpdate serverId and localId cannot both be null");
		}
		if(serverId != null && serverIdBy == null) {
			throw haxe_Exception.thrown("serverId requires serverIdBy");
		}
		this.updateId = updateId;
		this.serverId = serverId;
		this.serverIdBy = serverIdBy;
		this.localId = localId;
		this.chatId = chatId;
		this.senderId = senderId;
		this.timestamp = timestamp;
		this.reactions = reactions;
		this.kind = kind;
	}
	getReactions(existingReactions) {
		if(this.kind == 1) {
			let set = new Map([]);
			let list = [];
			let _g = 0;
			let tmp = existingReactions;
			let _g1 = tmp != null ? tmp : [];
			while(_g < _g1.length) {
				let r = _g1[_g];
				++_g;
				if(!set.has(r.key)) {
					list.push(r);
				}
				set.set(r.key,true);
			}
			let _g2 = 0;
			let _g3 = this.reactions;
			while(_g2 < _g3.length) {
				let r = _g3[_g2];
				++_g2;
				if(!set.has(r.key)) {
					list.push(r);
				}
				set.set(r.key,true);
			}
			return list;
		} else if(this.kind == 0) {
			let list = Lambda.array(this.reactions);
			let _g = 0;
			let tmp = existingReactions;
			let _g1 = tmp != null ? tmp : [];
			while(_g < _g1.length) {
				let r = _g1[_g];
				++_g;
				let custom = snikket_Util_downcast(r,snikket_CustomEmojiReaction);
				if(custom != null) {
					list.push(custom);
				}
			}
			return list;
		} else if(this.kind == 2) {
			return this.reactions;
		}
		throw haxe_Exception.thrown("Unknown kind of reaction update");
	}
	inlineHashReferences() {
		let hashes = [];
		let _g = 0;
		let _g1 = this.reactions;
		while(_g < _g1.length) {
			let r = _g1[_g];
			++_g;
			let custom = snikket_Util_downcast(r,snikket_CustomEmojiReaction);
			if(custom != null) {
				let hash = snikket_Hash.fromUri(custom.uri);
				if(hash != null) {
					hashes.push(hash);
				}
			}
		}
		return hashes;
	}
	asStanza() {
		if(this.kind != 0) {
			throw haxe_Exception.thrown("Cannot make a reaction XEP stanza for this kind");
		}
		let attrs = { type : this.serverId == null ? "chat" : "groupchat", id : this.updateId};
		let stanza = new snikket_Stanza("message",attrs);
		let tmp = this.localId;
		stanza.tag("reactions",{ xmlns : "urn:xmpp:reactions:0", id : tmp != null ? tmp : this.serverId});
		let _g = 0;
		let _g1 = this.reactions;
		while(_g < _g1.length) {
			let reaction = _g1[_g];
			++_g;
			if(!((reaction) instanceof snikket_CustomEmojiReaction)) {
				stanza.textTag("reaction",reaction.text);
			}
		}
		stanza.up();
		return stanza;
	}
}
$hx_exports["snikket"]["ReactionUpdate"] = snikket_ReactionUpdate;
snikket_ReactionUpdate.__name__ = "snikket.ReactionUpdate";
Object.assign(snikket_ReactionUpdate.prototype, {
	__class__: snikket_ReactionUpdate
});
var snikket_Node = $hxEnums["snikket.Node"] = { __ename__:true,__constructs__:null
	,Element: ($_=function(stanza) { return {_hx_index:0,stanza:stanza,__enum__:"snikket.Node",toString:$estr}; },$_._hx_name="Element",$_.__params__ = ["stanza"],$_)
	,CData: ($_=function(textNode) { return {_hx_index:1,textNode:textNode,__enum__:"snikket.Node",toString:$estr}; },$_._hx_name="CData",$_.__params__ = ["textNode"],$_)
};
snikket_Node.__constructs__ = [snikket_Node.Element,snikket_Node.CData];
class snikket__$Stanza_NodeInterface {
}
snikket__$Stanza_NodeInterface.__name__ = "snikket._Stanza.NodeInterface";
snikket__$Stanza_NodeInterface.__isInterface__ = true;
Object.assign(snikket__$Stanza_NodeInterface.prototype, {
	__class__: snikket__$Stanza_NodeInterface
});
class snikket_TextNode {
	constructor(content) {
		this.content = "";
		this.content = content;
	}
	serialize() {
		return snikket_Util_xmlEscape(this.content);
	}
	clone() {
		return new snikket_TextNode(this.content);
	}
	traverse(f) {
		return this;
	}
}
snikket_TextNode.__name__ = "snikket.TextNode";
snikket_TextNode.__interfaces__ = [snikket__$Stanza_NodeInterface];
Object.assign(snikket_TextNode.prototype, {
	__class__: snikket_TextNode
});
class snikket_StanzaError {
	constructor(type_,condition_,text_) {
		this.type = type_;
		this.condition = condition_;
		this.text = text_;
	}
}
snikket_StanzaError.__name__ = "snikket.StanzaError";
Object.assign(snikket_StanzaError.prototype, {
	__class__: snikket_StanzaError
});
class snikket_Stanza {
	constructor(name,attr) {
		this.last_added_stack = [];
		this.children = [];
		this.attr = { };
		this.name = null;
		this.name = name;
		if(attr != null) {
			this.attr = attr;
		}
		this.last_added = this;
	}
	serialize() {
		let el = Xml.createElement(this.name);
		let _g = 0;
		let _g1 = Reflect.fields(this.attr);
		while(_g < _g1.length) {
			let attr_k = _g1[_g];
			++_g;
			el.set(attr_k,this.attr[attr_k]);
		}
		if(this.children.length == 0) {
			return haxe_xml_Printer.print(el);
		}
		let serialized = haxe_xml_Printer.print(el);
		let buffer = [serialized.substring(0,serialized.length - 2) + ">"];
		let _g2 = 0;
		let _g3 = this.children;
		while(_g2 < _g3.length) {
			let child = _g3[_g2];
			++_g2;
			let tmp;
			switch(child._hx_index) {
			case 0:
				let c = child.stanza;
				tmp = c.serialize();
				break;
			case 1:
				let c1 = child.textNode;
				tmp = c1.serialize();
				break;
			}
			buffer.push(tmp);
		}
		buffer.push("</" + this.name + ">");
		return buffer.join("");
	}
	toString() {
		return this.serialize();
	}
	tag(name,attr) {
		let child = new snikket_Stanza(name,attr);
		this.last_added.addDirectChild(snikket_Node.Element(child));
		this.last_added_stack.push(this.last_added);
		this.last_added = child;
		return this;
	}
	text(content) {
		this.last_added.addDirectChild(snikket_Node.CData(new snikket_TextNode(content)));
		return this;
	}
	textTag(tagName,textContent,attr) {
		let tmp = attr;
		this.last_added.addDirectChild(snikket_Node.Element(new snikket_Stanza(tagName,tmp != null ? tmp : { }).text(textContent)));
		return this;
	}
	up() {
		if(this.last_added != this) {
			this.last_added = this.last_added_stack.pop();
		}
		return this;
	}
	reset() {
		this.last_added = this;
		return this;
	}
	addChildren(children) {
		let child = $getIterator(children);
		while(child.hasNext()) {
			let child1 = child.next();
			this.addChild(child1);
		}
		return this;
	}
	addChildNodes(children) {
		let child = $getIterator(children);
		while(child.hasNext()) {
			let child1 = child.next();
			this.addDirectChild(child1);
		}
		return this;
	}
	addChild(stanza) {
		this.last_added.children.push(snikket_Node.Element(stanza));
		return this;
	}
	addDirectChild(child) {
		this.children.push(child);
		return this;
	}
	clone() {
		let clone = new snikket_Stanza(this.name,this.attr);
		let _g = 0;
		let _g1 = this.children;
		while(_g < _g1.length) {
			let child = _g1[_g];
			++_g;
			let tmp;
			switch(child._hx_index) {
			case 0:
				let c = child.stanza;
				tmp = snikket_Node.Element(c.clone());
				break;
			case 1:
				let c1 = child.textNode;
				tmp = snikket_Node.CData(c1.clone());
				break;
			}
			clone.addDirectChild(tmp);
		}
		return clone;
	}
	allTags(name,xmlns) {
		let _g = [];
		let _g1 = 0;
		let _g2 = this.children;
		while(_g1 < _g2.length) {
			let v = _g2[_g1];
			++_g1;
			let tmp;
			if(v._hx_index == 0) {
				let _g = v.stanza;
				tmp = true;
			} else {
				tmp = false;
			}
			if(tmp) {
				_g.push(v);
			}
		}
		let _this = _g;
		let result = new Array(_this.length);
		let _g3 = 0;
		let _g4 = _this.length;
		while(_g3 < _g4) {
			let i = _g3++;
			let child = _this[i];
			let tmp;
			if(child._hx_index == 0) {
				let c = child.stanza;
				tmp = c;
			} else {
				tmp = null;
			}
			result[i] = tmp;
		}
		let tags = result;
		if(name != null || xmlns != null) {
			let ourXmlns = this.attr["xmlns"];
			let _g = [];
			let _g1 = 0;
			let _g2 = tags;
			while(_g1 < _g2.length) {
				let v = _g2[_g1];
				++_g1;
				let childXmlns = v.attr["xmlns"];
				if((name == null || v.name == name) && (xmlns == null && (ourXmlns == childXmlns || childXmlns == null) || childXmlns == xmlns)) {
					_g.push(v);
				}
			}
			tags = _g;
		}
		return tags;
	}
	allText() {
		let _g = [];
		let _g1 = 0;
		let _g2 = this.children;
		while(_g1 < _g2.length) {
			let v = _g2[_g1];
			++_g1;
			let tmp;
			if(v._hx_index == 1) {
				let _g = v.textNode;
				tmp = true;
			} else {
				tmp = false;
			}
			if(tmp) {
				_g.push(v);
			}
		}
		let _this = _g;
		let result = new Array(_this.length);
		let _g3 = 0;
		let _g4 = _this.length;
		while(_g3 < _g4) {
			let i = _g3++;
			let child = _this[i];
			let tmp;
			if(child._hx_index == 1) {
				let c = child.textNode;
				tmp = c.content;
			} else {
				tmp = null;
			}
			result[i] = tmp;
		}
		return result;
	}
	getFirstChild() {
		return this.allTags()[0];
	}
	getChildren() {
		let _this = this.children;
		let result = new Array(_this.length);
		let _g = 0;
		let _g1 = _this.length;
		while(_g < _g1) {
			let i = _g++;
			let child = _this[i];
			let tmp;
			switch(child._hx_index) {
			case 0:
				let el = child.stanza;
				tmp = el;
				break;
			case 1:
				let text = child.textNode;
				tmp = text;
				break;
			}
			result[i] = tmp;
		}
		return result;
	}
	getChild(name,xmlns) {
		let ourXmlns = this.attr["xmlns"];
		let tags = this.allTags(name,xmlns);
		if(tags.length == 0) {
			return null;
		}
		return tags[0];
	}
	getChildText(name,xmlns) {
		let child = this.getChild(name,xmlns);
		if(child == null) {
			return null;
		}
		return child.getText();
	}
	getText() {
		return this.allText().join("");
	}
	find(path) {
		let pos = 0;
		let len = path.length;
		let cursor = this;
		do {
			let xmlns = null;
			let name = null;
			let text = null;
			let char = path.charAt(pos);
			if(char == "@") {
				return snikket_Node.CData(new snikket_TextNode(cursor.attr[HxOverrides.substr(path,pos + 1,null)]));
			} else if(char == "{") {
				xmlns = path.substring(pos + 1,path.indexOf("}",pos + 1));
				pos += xmlns.length + 2;
			}
			let reName = new EReg("([^@/#]*)([/#]?)","");
			if(!reName.matchSub(path,pos)) {
				throw new haxe_Exception("Invalid path to Stanza.find(): " + path);
			}
			let name1 = reName.matched(1);
			let text1 = reName.matched(2);
			pos = reName.matchedPos().pos + reName.matchedPos().len;
			if(name1 == "") {
				name1 = null;
			}
			if(pos == len) {
				if(text1 == "#") {
					let text = cursor.getChildText(name1,xmlns);
					if(text == null) {
						return null;
					}
					return snikket_Node.CData(new snikket_TextNode(text));
				}
				return snikket_Node.Element(cursor.getChild(name1,xmlns));
			}
			cursor = cursor.getChild(name1,xmlns);
		} while(cursor != null);
		return null;
	}
	findChild(path) {
		let result = this.find(path);
		if(result == null) {
			return null;
		}
		if(result == null) {
			return null;
		} else if(result._hx_index == 0) {
			let stanza = result.stanza;
			return stanza;
		} else {
			return null;
		}
	}
	findText(path) {
		let result = this.find(path);
		if(result == null) {
			return null;
		}
		if(result == null) {
			return null;
		} else if(result._hx_index == 1) {
			let textNode = result.textNode;
			return textNode.content;
		} else {
			return null;
		}
	}
	traverse(f) {
		if(!f(this)) {
			let _g = 0;
			let _g1 = this.allTags();
			while(_g < _g1.length) {
				let child = _g1[_g];
				++_g;
				child.traverse(f);
			}
		}
		return this;
	}
	getError() {
		let errorTag = this.getChild("error");
		if(errorTag == null) {
			return null;
		}
		let errorTag1 = errorTag.attr["type"];
		let tmp = errorTag.getChild(null,"urn:ietf:params:xml:ns:xmpp-stanzas");
		return new snikket_StanzaError(errorTag1,tmp != null ? tmp.name : null,errorTag.getChildText("text","urn:ietf:params:xml:ns:xmpp-stanzas"));
	}
	removeChildren(name,xmlns_) {
		let tmp = xmlns_;
		let xmlns = tmp != null ? tmp : this.attr["xmlns"];
		let _g = [];
		let _g1 = 0;
		let _g2 = this.children;
		while(_g1 < _g2.length) {
			let v = _g2[_g1];
			++_g1;
			let tmp;
			if(v._hx_index == 0) {
				let c = v.stanza;
				let tmp1;
				if(name == null || c.name == name) {
					let tmp = c.attr["xmlns"];
					tmp1 = (tmp != null ? tmp : xmlns) == xmlns;
				} else {
					tmp1 = false;
				}
				tmp = !tmp1;
			} else {
				tmp = true;
			}
			if(tmp) {
				_g.push(v);
			}
		}
		this.children = _g;
	}
	static parse(s) {
		return snikket_Stanza.fromXml(Xml.parse(s));
	}
	static fromXml(el) {
		if(el.nodeType == 6) {
			return snikket_Stanza.fromXml(el.firstElement());
		}
		let attrs = { };
		let a = el.attributes();
		while(a.hasNext()) {
			let a1 = a.next();
			attrs[a1] = el.get(a1);
		}
		if(el.nodeType != Xml.Element) {
			throw haxe_Exception.thrown("Bad node type, expected Element but found " + (el.nodeType == null ? "null" : XmlType.toString(el.nodeType)));
		}
		let stanza = new snikket_Stanza(el.nodeName,attrs);
		if(el.nodeType != Xml.Document && el.nodeType != Xml.Element) {
			throw haxe_Exception.thrown("Bad node type, expected Element or Document but found " + (el.nodeType == null ? "null" : XmlType.toString(el.nodeType)));
		}
		let _g_current = 0;
		let _g_array = el.children;
		while(_g_current < _g_array.length) {
			let child = _g_array[_g_current++];
			if(child.nodeType == 0) {
				stanza.addChild(snikket_Stanza.fromXml(child));
			} else if(!(child.nodeType == 5 || child.nodeType == 4 || child.nodeType == 3)) {
				if(child.nodeType == Xml.Document || child.nodeType == Xml.Element) {
					throw haxe_Exception.thrown("Bad node type, unexpected " + (child.nodeType == null ? "null" : XmlType.toString(child.nodeType)));
				}
				stanza.text(child.nodeValue);
			}
		}
		return stanza;
	}
	static parseXmlBool(x) {
		if(x != "true") {
			return x == "1";
		} else {
			return true;
		}
	}
}
$hx_exports["snikket"]["Stanza"] = snikket_Stanza;
snikket_Stanza.__name__ = "snikket.Stanza";
snikket_Stanza.__interfaces__ = [snikket__$Stanza_NodeInterface];
Object.assign(snikket_Stanza.prototype, {
	__class__: snikket_Stanza
});
var snikket_IqRequestType = $hxEnums["snikket.IqRequestType"] = { __ename__:true,__constructs__:null
	,Get: {_hx_name:"Get",_hx_index:0,__enum__:"snikket.IqRequestType",toString:$estr}
	,Set: {_hx_name:"Set",_hx_index:1,__enum__:"snikket.IqRequestType",toString:$estr}
};
snikket_IqRequestType.__constructs__ = [snikket_IqRequestType.Get,snikket_IqRequestType.Set];
class snikket_StringUtil {
	static codepointArray(s) {
		let result = [];
		let offset = 0;
		while(offset < s.length) {
			let c = s.charCodeAt(offset);
			if(c >= 55296 && c <= 56319) {
				c = c - 55232 << 10 | s.charCodeAt(offset + 1) & 1023;
			}
			let c1 = c;
			if(c1 >= 65536) {
				result.push(HxOverrides.substr(s,offset,2));
				++offset;
			} else {
				result.push(HxOverrides.substr(s,offset,1));
			}
			++offset;
		}
		return result;
	}
	static rawCodepointArray(s) {
		let result = [];
		let offset = 0;
		while(offset < s.length) {
			let c = s.charCodeAt(offset);
			if(c >= 55296 && c <= 56319) {
				c = c - 55232 << 10 | s.charCodeAt(offset + 1) & 1023;
			}
			let c1 = c;
			if(c1 >= 65536) {
				result.push(c1);
				++offset;
			} else {
				result.push(c1);
			}
			++offset;
		}
		return result;
	}
}
snikket_StringUtil.__name__ = "snikket.StringUtil";
function snikket_Util_setupTrace() {
	haxe_Log.trace = function(v,infos) {
		if(typeof(console) != "undefined" && console.debug != null) {
			let tmp = infos.customParams;
			let params = tmp != null ? tmp : [];
			infos.customParams = [];
			let str = haxe_Log.formatOutput(v,infos);
			let tmp1 = [str].concat(params);
			console.debug.apply(null,tmp1);
		} else if(typeof(console) != "undefined" && console.log != null) {
			let str = haxe_Log.formatOutput(v,infos);
			console.log(str);
		}
	};
}
function snikket_Util_downcast(value,c) {
	let value1 = value;
	return js_Boot.__downcastCheck(value1,c) ? value1 : null;
}
function snikket_Util_xmlEscape(s) {
	return StringTools.replace(StringTools.replace(StringTools.replace(s,"&","&amp;"),"<","&lt;"),">","&gt;");
}
class snikket_Version {
}
$hx_exports["snikket"]["Version"] = snikket_Version;
snikket_Version.__name__ = "snikket.Version";
class snikket_XEP0393 {
	static parse(styled) {
		let blocks = [];
		while(styled.length > 0) {
			let result = snikket_XEP0393.parseBlock(styled);
			styled = result.rest;
			blocks.push(result.block);
		}
		return blocks;
	}
	static render(xhtml) {
		if(xhtml.name == "br") {
			return "\n";
		}
		if(xhtml.name == "img") {
			let tmp = xhtml.attr["alt"];
			if(tmp != null) {
				return tmp;
			} else {
				return "";
			}
		}
		let s_b = "";
		if(xhtml.name == "pre") {
			s_b += "\n```\n";
		}
		if(xhtml.name == "b" || xhtml.name == "strong") {
			s_b += "*";
		}
		if(xhtml.name == "i" || xhtml.name == "em") {
			s_b += "_";
		}
		if(xhtml.name == "s" || xhtml.name == "del") {
			s_b += "~";
		}
		if(xhtml.name == "tt") {
			s_b += "`";
		}
		let _g = 0;
		let _g1 = xhtml.children;
		while(_g < _g1.length) {
			let child = _g1[_g];
			++_g;
			s_b += Std.string(snikket_XEP0393.renderNode(child));
		}
		if(xhtml.name == "b" || xhtml.name == "strong") {
			s_b += "*";
		}
		if(xhtml.name == "i" || xhtml.name == "em") {
			s_b += "_";
		}
		if(xhtml.name == "s" || xhtml.name == "del") {
			s_b += "~";
		}
		if(xhtml.name == "tt") {
			s_b += "`";
		}
		if(xhtml.name == "blockquote" || xhtml.name == "p" || xhtml.name == "div" || xhtml.name == "pre") {
			s_b += "\n";
		}
		if(xhtml.name == "pre") {
			s_b += "```\n";
		}
		if(xhtml.name == "blockquote") {
			let _this_r = new RegExp("^","gm".split("u").join(""));
			return s_b.replace(_this_r,"> ");
		}
		return s_b;
	}
	static renderNode(xhtml) {
		switch(xhtml._hx_index) {
		case 0:
			let c = xhtml.stanza;
			return snikket_XEP0393.render(c);
		case 1:
			let c1 = xhtml.textNode;
			return c1.content;
		}
	}
	static parseSpans(styled) {
		let spans = [];
		let start = 0;
		let nextLink = null;
		while(start < styled.length) if(StringTools.isSpace(styled,start + 1)) {
			spans.push(snikket_Node.CData(new snikket_TextNode(HxOverrides.substr(styled,start,2))));
			start += 2;
		} else if(start != 0 && !StringTools.isSpace(styled,start - 1)) {
			spans.push(snikket_Node.CData(new snikket_TextNode(styled.charAt(start))));
			++start;
		} else if(styled.charAt(start) == "*") {
			let parsed = snikket_XEP0393.parseSpan("strong","*",styled,start);
			spans.push(parsed.span);
			start = parsed.end;
		} else if(styled.charAt(start) == "_") {
			let parsed = snikket_XEP0393.parseSpan("em","_",styled,start);
			spans.push(parsed.span);
			start = parsed.end;
		} else if(styled.charAt(start) == "~") {
			let parsed = snikket_XEP0393.parseSpan("s","~",styled,start);
			spans.push(parsed.span);
			start = parsed.end;
		} else if(styled.charAt(start) == "`") {
			let parsed = snikket_XEP0393.parseSpan("tt","`",styled,start);
			spans.push(parsed.span);
			start = parsed.end;
		} else {
			if(nextLink == null || start > nextLink.start) {
				nextLink = snikket_Autolink.one(styled,start);
			}
			if(nextLink != null && nextLink.start == start && nextLink.span != null) {
				spans.push(nextLink.span);
				start = nextLink.end;
			} else {
				spans.push(snikket_Node.CData(new snikket_TextNode(styled.charAt(start))));
				++start;
			}
		}
		return spans;
	}
	static parseSpan(tagName,marker,styled,start) {
		let end = start + 1;
		while(end < styled.length && styled.charAt(end) != marker) {
			if(StringTools.isSpace(styled,end)) {
				++end;
			}
			++end;
		}
		if(end == start + 1) {
			return { span : snikket_Node.CData(new snikket_TextNode(HxOverrides.substr(styled,start,2))), end : end + 1};
		} else if(styled.charAt(end) != marker) {
			return { span : snikket_Node.CData(new snikket_TextNode(HxOverrides.substr(styled,start,end - start))), end : end};
		} else if(marker == "`") {
			return { span : snikket_Node.Element(new snikket_Stanza(tagName).text(HxOverrides.substr(styled,start + 1,end - start - 1))), end : end + 1};
		} else {
			return { span : snikket_Node.Element(new snikket_Stanza(tagName).addChildNodes(snikket_XEP0393.parseSpans(HxOverrides.substr(styled,start + 1,end - start - 1)))), end : end + 1};
		}
	}
	static parseBlock(styled) {
		if(styled.charAt(0) == ">") {
			return snikket_XEP0393.parseQuote(styled);
		} else if(HxOverrides.substr(styled,0,3) == "```") {
			return snikket_XEP0393.parsePreformatted(styled);
		} else {
			let end = 0;
			while(end < styled.length && styled.charAt(end) != "\n") ++end;
			if(end < styled.length && styled.charAt(end) == "\n") {
				++end;
			}
			return { block : new snikket_Stanza("div").addChildNodes(snikket_XEP0393.parseSpans(HxOverrides.substr(styled,0,end))), rest : HxOverrides.substr(styled,end,null)};
		}
	}
	static parseQuote(styled) {
		let lines = [];
		let line = "";
		let end = 1;
		let spaceAfter = 0;
		while(end < styled.length) {
			if(styled.charAt(end) != "\n" && StringTools.isSpace(styled,end)) {
				++end;
			}
			while(end < styled.length && styled.charAt(end) != "\n") {
				line += styled.charAt(end);
				++end;
			}
			if(end < styled.length && styled.charAt(end) == "\n") {
				++end;
			}
			lines.push(line + "\n");
			line = "";
			if(styled.charAt(end) == ">") {
				++end;
			} else {
				break;
			}
		}
		return { block : new snikket_Stanza("blockquote").addChildren(snikket_XEP0393.parse(lines.join(""))), rest : HxOverrides.substr(styled,end,null)};
	}
	static parsePreformatted(styled) {
		let lines = [];
		let line = null;
		let end = 0;
		while(end < styled.length) {
			while(end < styled.length && styled.charAt(end) != "\n") {
				if(line != null) {
					line += styled.charAt(end);
				}
				++end;
			}
			if(end < styled.length && styled.charAt(end) == "\n") {
				++end;
			}
			if(line != null) {
				lines.push(line + "\n");
			}
			line = "";
			if(HxOverrides.substr(styled,end,4) == "```\n" || HxOverrides.substr(styled,end,null) == "```") {
				end += 4;
				break;
			}
		}
		return { block : new snikket_Stanza("pre").text(lines.join("")), rest : HxOverrides.substr(styled,end,null)};
	}
}
snikket_XEP0393.__name__ = "snikket.XEP0393";
class snikket_jingle_Group {
	constructor(semantics,identificationTags) {
		this.semantics = semantics;
		this.identificationTags = identificationTags;
	}
	toSdp() {
		if(this.semantics.indexOf(" ") >= 0) {
			throw haxe_Exception.thrown("Group semantics cannot contain a space in SDP");
		}
		return this.semantics + " " + this.identificationTags.join(" ");
	}
	toElement() {
		let group = new snikket_Stanza("group",{ xmlns : "urn:xmpp:jingle:apps:grouping:0", semantics : this.semantics});
		let _g = 0;
		let _g1 = this.identificationTags;
		while(_g < _g1.length) {
			let tag = _g1[_g];
			++_g;
			group.tag("content",{ name : tag}).up();
		}
		return group;
	}
	static parse(input) {
		let segments = input.split(" ");
		if(segments.length < 2) {
			return null;
		}
		return new snikket_jingle_Group(segments[0],segments.slice(1));
	}
	static fromElement(el) {
		let idTags = [];
		let _g = 0;
		let _g1 = el.allTags("content");
		while(_g < _g1.length) {
			let content = _g1[_g];
			++_g;
			if(content.attr["name"] != null) {
				idTags.push(content.attr["name"]);
			}
		}
		return new snikket_jingle_Group(el.attr["semantics"],idTags);
	}
}
snikket_jingle_Group.__name__ = "snikket.jingle.Group";
Object.assign(snikket_jingle_Group.prototype, {
	__class__: snikket_jingle_Group
});
class snikket_jingle_Session {
}
snikket_jingle_Session.__name__ = "snikket.jingle.Session";
snikket_jingle_Session.__isInterface__ = true;
Object.assign(snikket_jingle_Session.prototype, {
	__class__: snikket_jingle_Session
});
class snikket_jingle_IncomingProposedSession {
	constructor(client,from,sid) {
		this.accepted = false;
		this.client = client;
		this.from = from;
		this._sid = sid;
	}
	ring() {
		let event = new snikket_Stanza("ringing",{ xmlns : "urn:xmpp:jingle-message:0", id : this.get_sid()});
		let msg = snikket_jingle_Session_mkCallMessage(this.from,this.client.jid,event);
		let _gthis = this;
		this.client.storeMessages([msg],function(stored) {
			_gthis.client.notifyMessageHandlers(stored[0],1);
		});
		this.client.trigger("call/ring",{ chatId : this.from.asBare().asString(), session : this});
	}
	hangup() {
		let event = new snikket_Stanza("reject",{ xmlns : "urn:xmpp:jingle-message:0", id : this.get_sid()});
		let msg = snikket_jingle_Session_mkCallMessage(this.from,this.client.jid,event);
		let _gthis = this;
		this.client.storeMessages([msg],function(stored) {
			_gthis.client.notifyMessageHandlers(stored[0],1);
		});
		this.client.getDirectChat(this.from.asBare().asString(),false).jingleSessions.delete(this.get_sid());
	}
	retract() {
		this.client.trigger("call/retract",{ chatId : this.from.asBare().asString()});
	}
	terminate() {
		haxe_Log.trace("Tried to terminate before session-initiate: " + this.get_sid(),{ fileName : "snikket/jingle/Session.hx", lineNumber : 102, className : "snikket.jingle.IncomingProposedSession", methodName : "terminate", customParams : [this]});
	}
	contentAdd(_) {
		haxe_Log.trace("Got content-add before session-initiate: " + this.get_sid(),{ fileName : "snikket/jingle/Session.hx", lineNumber : 106, className : "snikket.jingle.IncomingProposedSession", methodName : "contentAdd", customParams : [this]});
	}
	contentAccept(_) {
		haxe_Log.trace("Got content-accept before session-initiate: " + this.get_sid(),{ fileName : "snikket/jingle/Session.hx", lineNumber : 110, className : "snikket.jingle.IncomingProposedSession", methodName : "contentAccept", customParams : [this]});
	}
	transportInfo(_) {
		haxe_Log.trace("Got transport-info before session-initiate: " + this.get_sid(),{ fileName : "snikket/jingle/Session.hx", lineNumber : 114, className : "snikket.jingle.IncomingProposedSession", methodName : "transportInfo", customParams : [this]});
		return Promise.resolve(null);
	}
	accept() {
		if(this.accepted) {
			return;
		}
		this.accepted = true;
		this.client.sendPresence(this.from.asString());
		let event = new snikket_Stanza("proceed",{ xmlns : "urn:xmpp:jingle-message:0", id : this.get_sid()});
		let msg = snikket_jingle_Session_mkCallMessage(this.from,this.client.jid,event);
		let _gthis = this;
		this.client.storeMessages([msg],function(stored) {
			_gthis.client.notifyMessageHandlers(stored[0],1);
			_gthis.client.sendStanza(new snikket_Stanza("message",{ to : _gthis.from.asString(), type : "chat", id : msg.versions[0].localId}).addChild(event).tag("store",{ xmlns : "urn:xmpp:hints"}));
		});
	}
	initiate(stanza) {
		let session = snikket_jingle_InitiatedSession.fromSessionInitiate(this.client,stanza);
		if(session.get_sid() != this.get_sid()) {
			throw haxe_Exception.thrown("id mismatch");
		}
		if(!this.accepted) {
			throw haxe_Exception.thrown("trying to initiate unaccepted session");
		}
		session.accept();
		return session;
	}
	addMedia(_) {
		throw haxe_Exception.thrown("Cannot add media before call starts");
	}
	callStatus() {
		return "incoming";
	}
	videoTracks() {
		return [];
	}
	dtmf() {
		return null;
	}
	get_sid() {
		return this._sid;
	}
}
snikket_jingle_IncomingProposedSession.__name__ = "snikket.jingle.IncomingProposedSession";
snikket_jingle_IncomingProposedSession.__interfaces__ = [snikket_jingle_Session];
Object.assign(snikket_jingle_IncomingProposedSession.prototype, {
	__class__: snikket_jingle_IncomingProposedSession
});
class snikket_jingle_OutgoingProposedSession {
	constructor(client,to) {
		this.video = false;
		this.audio = false;
		this.client = client;
		this.to = to;
		this._sid = snikket_ID.long();
	}
	propose(audio,video) {
		this.audio = audio;
		this.video = video;
		let event = new snikket_Stanza("propose",{ xmlns : "urn:xmpp:jingle-message:0", id : this.get_sid()});
		if(audio) {
			event.tag("description",{ xmlns : "urn:xmpp:jingle:apps:rtp:1", media : "audio"}).up();
		}
		if(video) {
			event.tag("description",{ xmlns : "urn:xmpp:jingle:apps:rtp:1", media : "video"}).up();
		}
		let msg = snikket_jingle_Session_mkCallMessage(this.to,this.client.jid,event);
		let _gthis = this;
		this.client.storeMessages([msg],function(stored) {
			let stanza = new snikket_Stanza("message",{ to : _gthis.to.asString(), type : "chat", id : msg.localId}).addChild(event).tag("store",{ xmlns : "urn:xmpp:hints"});
			_gthis.client.sendStanza(stanza);
			_gthis.client.notifyMessageHandlers(stored[0],0);
			_gthis.client.trigger("call/ringing",{ chatId : _gthis.to.asBare().asString()});
		});
	}
	ring() {
		haxe_Log.trace("Tried to accept before initiate: " + this.get_sid(),{ fileName : "snikket/jingle/Session.hx", lineNumber : 200, className : "snikket.jingle.OutgoingProposedSession", methodName : "ring", customParams : [this]});
	}
	hangup() {
		let event = new snikket_Stanza("retract",{ xmlns : "urn:xmpp:jingle-message:0", id : this.get_sid()});
		let msg = snikket_jingle_Session_mkCallMessage(this.to,this.client.jid,event);
		let _gthis = this;
		this.client.storeMessages([msg],function(stored) {
			_gthis.client.sendStanza(new snikket_Stanza("message",{ to : _gthis.to.asString(), type : "chat", id : msg.versions[0].localId}).addChild(event).tag("store",{ xmlns : "urn:xmpp:hints"}));
			_gthis.client.notifyMessageHandlers(stored[0],1);
		});
		this.client.getDirectChat(this.to.asBare().asString(),false).jingleSessions.delete(this.get_sid());
	}
	retract() {
		this.client.trigger("call/retract",{ chatId : this.to.asBare().asString()});
	}
	terminate() {
		haxe_Log.trace("Tried to terminate before session-initiate: " + this.get_sid(),{ fileName : "snikket/jingle/Session.hx", lineNumber : 223, className : "snikket.jingle.OutgoingProposedSession", methodName : "terminate", customParams : [this]});
	}
	contentAdd(_) {
		haxe_Log.trace("Got content-add before session-initiate: " + this.get_sid(),{ fileName : "snikket/jingle/Session.hx", lineNumber : 227, className : "snikket.jingle.OutgoingProposedSession", methodName : "contentAdd", customParams : [this]});
	}
	contentAccept(_) {
		haxe_Log.trace("Got content-accept before session-initiate: " + this.get_sid(),{ fileName : "snikket/jingle/Session.hx", lineNumber : 231, className : "snikket.jingle.OutgoingProposedSession", methodName : "contentAccept", customParams : [this]});
	}
	transportInfo(_) {
		haxe_Log.trace("Got transport-info before session-initiate: " + this.get_sid(),{ fileName : "snikket/jingle/Session.hx", lineNumber : 235, className : "snikket.jingle.OutgoingProposedSession", methodName : "transportInfo", customParams : [this]});
		return Promise.resolve(null);
	}
	accept() {
		haxe_Log.trace("Tried to accept before initiate: " + this.get_sid(),{ fileName : "snikket/jingle/Session.hx", lineNumber : 240, className : "snikket.jingle.OutgoingProposedSession", methodName : "accept", customParams : [this]});
	}
	initiate(stanza) {
		let jmi = stanza.getChild("proceed","urn:xmpp:jingle-message:0");
		if(jmi == null) {
			throw haxe_Exception.thrown("no jmi: " + Std.string(stanza));
		}
		if(jmi.attr["id"] != this.get_sid()) {
			throw haxe_Exception.thrown("sid doesn't match: " + jmi.attr["id"] + " vs " + this.get_sid());
		}
		this.client.sendPresence(this.to.asString());
		let session = new snikket_jingle_OutgoingSession(this.client,snikket_JID.parse(stanza.attr["from"]),this.get_sid());
		this.client.trigger("call/media",{ session : session, audio : this.audio, video : this.video});
		return session;
	}
	addMedia(_) {
		throw haxe_Exception.thrown("Cannot add media before call starts");
	}
	callStatus() {
		return "outgoing";
	}
	videoTracks() {
		return [];
	}
	dtmf() {
		return null;
	}
	get_sid() {
		return this._sid;
	}
}
snikket_jingle_OutgoingProposedSession.__name__ = "snikket.jingle.OutgoingProposedSession";
snikket_jingle_OutgoingProposedSession.__interfaces__ = [snikket_jingle_Session];
Object.assign(snikket_jingle_OutgoingProposedSession.prototype, {
	__class__: snikket_jingle_OutgoingProposedSession
});
class snikket_jingle_InitiatedSession {
	constructor(client,counterpart,sid,remoteDescription) {
		this.candidatesDone = null;
		this.afterMedia = null;
		this.accepted = false;
		this.queuedOutboundCandidate = [];
		this.queuedInboundTransportInfo = [];
		this.peerDtlsSetup = "actpass";
		this.pc = null;
		this.localDescription = null;
		this.remoteDescription = null;
		this.client = client;
		this.counterpart = counterpart;
		this._sid = sid;
		this.remoteDescription = remoteDescription;
		this.initiator = remoteDescription == null;
	}
	get_sid() {
		return this._sid;
	}
	ring() {
		this.client.trigger("call/ring",{ chatId : this.counterpart.asBare().asString(), session : this});
	}
	retract() {
		haxe_Log.trace("Tried to retract session in wrong state: " + this.get_sid(),{ fileName : "snikket/jingle/Session.hx", lineNumber : 327, className : "snikket.jingle.InitiatedSession", methodName : "retract", customParams : [this]});
	}
	accept() {
		if(this.accepted || this.remoteDescription == null) {
			return;
		}
		this.accepted = true;
		let audio = Lambda.find(this.remoteDescription.media,function(m) {
			return m.media == "audio";
		}) != null;
		let video = Lambda.find(this.remoteDescription.media,function(m) {
			return m.media == "video";
		}) != null;
		this.client.trigger("call/media",{ session : this, audio : audio, video : video});
	}
	hangup() {
		this.client.sendStanza(new snikket_Stanza("iq",{ to : this.counterpart.asString(), type : "set", id : snikket_ID.medium()}).tag("jingle",{ xmlns : "urn:xmpp:jingle:1", action : "session-terminate", sid : this.get_sid()}).tag("reason").tag("success").up().up().up());
		this.terminate();
	}
	initiate(stanza) {
		haxe_Log.trace("Trying to initiate already initiated session: " + this.get_sid(),{ fileName : "snikket/jingle/Session.hx", lineNumber : 350, className : "snikket.jingle.InitiatedSession", methodName : "initiate"});
		throw haxe_Exception.thrown("already initiated");
	}
	terminate() {
		if(this.pc == null) {
			return;
		}
		this.pc.close();
		let _g = 0;
		let _g1 = this.pc.getTransceivers();
		while(_g < _g1.length) {
			let tranceiver = _g1[_g];
			++_g;
			if(tranceiver.sender != null && tranceiver.sender.track != null) {
				tranceiver.sender.track.stop();
			}
		}
		this.pc = null;
		this.client.trigger("call/retract",{ chatId : this.counterpart.asBare().asString()});
		let event = new snikket_Stanza("finish",{ xmlns : "urn:xmpp:jingle-message:0", id : this.get_sid()});
		let msg = snikket_jingle_Session_mkCallMessage(this.counterpart,this.client.jid,event);
		let _gthis = this;
		this.client.storeMessages([msg],function(stored) {
			_gthis.client.notifyMessageHandlers(stored[0],1);
			_gthis.client.sendStanza(new snikket_Stanza("message",{ to : _gthis.counterpart.asString(), type : "chat", id : msg.versions[0].localId}).addChild(event).tag("store",{ xmlns : "urn:xmpp:hints"}));
		});
	}
	contentAdd(stanza) {
		if(this.remoteDescription == null) {
			throw haxe_Exception.thrown("Got content-add before session-accept");
		}
		let addThis = snikket_jingle_SessionDescription.fromStanza(stanza,this.initiator,this.remoteDescription);
		let video = false;
		let audio = false;
		let _g = 0;
		let _g1 = addThis.media;
		while(_g < _g1.length) {
			let m = _g1[_g];
			++_g;
			if(Lambda.exists(m.attributes,function(attr) {
				if(attr.key != "sendrecv") {
					return attr.key == "sendonly";
				} else {
					return true;
				}
			})) {
				if(m.media == "video") {
					video = true;
				}
				if(m.media == "audio") {
					audio = true;
				}
			}
			m.attributes.push(new snikket_jingle_Attribute("setup",this.peerDtlsSetup));
		}
		this.remoteDescription = this.remoteDescription.addContent(addThis);
		let _gthis = this;
		this.pc.setRemoteDescription({ type : "offer", sdp : this.remoteDescription.toSdp()}).then(function(_) {
			_gthis.afterMedia = function() {
				let _gthis1 = _gthis;
				let _this = addThis.media;
				let result = new Array(_this.length);
				let _g = 0;
				let _g1 = _this.length;
				while(_g < _g1) {
					let i = _g++;
					result[i] = _this[i].mid;
				}
				_gthis1.setupLocalDescription("content-accept",result,false,function(gonnaAccept) {
					if(Lambda.find(gonnaAccept.media,function(m) {
						return m.contentElement(false).attr["senders"] != Lambda.find(addThis.media,function(addM) {
							return addM.mid == m.mid;
						}).contentElement(false).attr["senders"];
					}) != null) {
						let modify = gonnaAccept.toStanza("content-modify",_gthis.get_sid(),_gthis.initiator);
						modify.attr["to"] = _gthis.counterpart.asString();
						modify.attr["id"] = snikket_ID.medium();
						_gthis.client.sendStanza(modify);
					}
				});
				_gthis.afterMedia = null;
			};
			return _gthis.client.trigger("call/media",{ session : _gthis, audio : audio, video : video});
		});
	}
	contentAccept(stanza) {
		if(this.remoteDescription == null) {
			throw haxe_Exception.thrown("Got content-accept before session-accept");
		}
		let addThis = snikket_jingle_SessionDescription.fromStanza(stanza,!this.initiator,this.remoteDescription);
		let _g = 0;
		let _g1 = addThis.media;
		while(_g < _g1.length) {
			let m = _g1[_g];
			++_g;
			m.attributes.push(new snikket_jingle_Attribute("setup",this.peerDtlsSetup));
		}
		this.remoteDescription = this.remoteDescription.addContent(addThis);
		this.pc.setRemoteDescription({ type : "answer", sdp : this.remoteDescription.toSdp()});
	}
	transportInfo(stanza) {
		if(this.pc == null || this.remoteDescription == null) {
			this.queuedInboundTransportInfo.push(stanza);
			return Promise.resolve(null);
		}
		let _gthis = this;
		let _this = snikket_jingle_IceCandidate.fromStanza(stanza);
		let result = new Array(_this.length);
		let _g = 0;
		let _g1 = _this.length;
		while(_g < _g1) {
			let i = _g++;
			let candidate = _this[i];
			let index = _gthis.remoteDescription.identificationTags.indexOf(candidate.sdpMid);
			result[i] = _gthis.pc.addIceCandidate({ candidate : candidate.toSdp(), sdpMid : candidate.sdpMid, sdpMLineIndex : index < 0 ? null : index, usernameFragment : candidate.ufrag});
		}
		return thenshim_Promise.then(thenshim_PromiseTools.all(result),function(_) {
			return;
		});
	}
	addMedia(streams) {
		if(this.pc == null) {
			throw haxe_Exception.thrown("tried to add media before PeerConnection exists");
		}
		let _this = this.localDescription.media;
		let result = new Array(_this.length);
		let _g = 0;
		let _g1 = _this.length;
		while(_g < _g1) {
			let i = _g++;
			result[i] = _this[i].mid;
		}
		let oldMids = result;
		let _g2 = 0;
		while(_g2 < streams.length) {
			let stream = streams[_g2];
			++_g2;
			let _g = 0;
			let _g1 = stream.getTracks();
			while(_g < _g1.length) {
				let track = _g1[_g];
				++_g;
				this.pc.addTrack(track,stream);
			}
		}
		this.setupLocalDescription("content-add",oldMids,true);
	}
	callStatus() {
		return "ongoing";
	}
	videoTracks() {
		if(this.pc == null) {
			return [];
		}
		let _g = [];
		let _g1 = 0;
		let _g2 = this.pc.getTransceivers();
		while(_g1 < _g2.length) {
			let v = _g2[_g1];
			++_g1;
			if(v.receiver != null && v.receiver.track != null && v.receiver.track.kind == "video" && !v.receiver.track.muted) {
				_g.push(v);
			}
		}
		let _this = _g;
		let result = new Array(_this.length);
		let _g3 = 0;
		let _g4 = _this.length;
		while(_g3 < _g4) {
			let i = _g3++;
			result[i] = _this[i].receiver.track;
		}
		return result;
	}
	dtmf() {
		if(this.pc == null) {
			return null;
		}
		let transceiver = Lambda.find(this.pc.getTransceivers(),function(t) {
			if(t.sender != null && t.sender.track != null && t.sender.track.kind == "audio") {
				return !t.sender.track.muted;
			} else {
				return false;
			}
		});
		if(transceiver == null) {
			return null;
		}
		return transceiver.sender.dtmf;
	}
	sendIceCandidate(candidate) {
		if(candidate == null || candidate.candidate == "") {
			if(this.candidatesDone != null) {
				this.candidatesDone();
			}
			return;
		}
		if(this.candidatesDone != null) {
			return;
		}
		if(this.localDescription == null) {
			this.queuedOutboundCandidate.push(candidate);
			return;
		}
		let media = Lambda.find(this.localDescription.media,function(media) {
			return media.mid == candidate.sdpMid;
		});
		if(media == null) {
			throw haxe_Exception.thrown("Unknown media: " + candidate.sdpMid);
		}
		let media1 = media.mid;
		let media2 = media.media;
		let media3 = media.connectionData;
		let media4 = media.port;
		let media5 = media.protocol;
		let transportInfo = snikket_jingle_Attribute.parse(candidate.candidate);
		let transportInfo1 = new snikket_jingle_Attribute("ice-ufrag",candidate.usernameFragment);
		let tmp = Lambda.find(media.attributes,function(attr) {
			return attr.key == "ice-pwd";
		});
		let transportInfo2 = new snikket_jingle_TransportInfo(new snikket_jingle_Media(media1,media2,media3,media4,media5,[transportInfo,transportInfo1,tmp != null ? tmp : Lambda.find(this.localDescription.attributes,function(attr) {
			return attr.key == "ice-pwd";
		})],media.formats),this.get_sid()).toStanza(this.initiator);
		transportInfo2.attr["to"] = this.counterpart.asString();
		transportInfo2.attr["id"] = snikket_ID.medium();
		this.client.sendStanza(transportInfo2);
	}
	supplyMedia(streams) {
		let _gthis = this;
		this.setupPeerConnection(function() {
			let _g = 0;
			while(_g < streams.length) {
				let stream = streams[_g];
				++_g;
				let _g1 = 0;
				let _g2 = stream.getTracks();
				while(_g1 < _g2.length) {
					let track = _g2[_g1];
					++_g1;
					_gthis.pc.addTrack(track,stream);
				}
			}
			if(_gthis.afterMedia == null) {
				_gthis.onPeerConnection().catch(function(e) {
					haxe_Log.trace("supplyMedia error",{ fileName : "snikket/jingle/Session.hx", lineNumber : 523, className : "snikket.jingle.InitiatedSession", methodName : "supplyMedia", customParams : [e]});
					_gthis.pc.close();
				});
			} else {
				_gthis.afterMedia();
			}
		});
	}
	setupPeerConnection(callback) {
		if(this.pc != null) {
			callback();
			return;
		}
		let _gthis = this;
		this.client.getIceServers(function(servers) {
			_gthis.pc = new RTCPeerConnection({ iceServers : servers},null);
			_gthis.pc.addEventListener("track",function(event) {
				return _gthis.client.trigger("call/track",{ chatId : _gthis.counterpart.asBare().asString(), track : event.track, streams : event.streams});
			});
			_gthis.pc.addEventListener("negotiationneeded",function(event) {
				haxe_Log.trace("renegotiate",{ fileName : "snikket/jingle/Session.hx", lineNumber : 542, className : "snikket.jingle.InitiatedSession", methodName : "setupPeerConnection", customParams : [event]});
			});
			_gthis.pc.addEventListener("icecandidate",function(event) {
				_gthis.sendIceCandidate(event.candidate);
			});
			_gthis.pc.addEventListener("connectionstatechange",function(event) {
				if(_gthis.pc != null && (_gthis.pc.connectionState == "closed" || _gthis.pc.connectionState == "failed")) {
					_gthis.terminate();
				}
			});
			callback();
		});
	}
	setupLocalDescription(type,filterMedia,filterOut,beforeSend) {
		if(filterOut == null) {
			filterOut = false;
		}
		let _gthis = this;
		return this.pc.setLocalDescription(null).then(function(_) {
			let caps = _gthis.client.getDirectChat(_gthis.counterpart.asBare().asString()).getResourceCaps(_gthis.counterpart.resource);
			if((type == "session-initiate" || type == "session-accept") && caps.features.includes("urn:ietf:rfc:3264")) {
				return new Promise(function(resolve,reject) {
					let timeout = haxe_Timer.delay(function() {
						_gthis.candidatesDone = function() {
						};
						resolve(false);
					},3000);
					_gthis.candidatesDone = function() {
						timeout.stop();
						resolve(true);
					};
				});
			} else {
				return null;
			}
		}).then(function(_) {
			_gthis.localDescription = snikket_jingle_SessionDescription.parse(_gthis.pc.localDescription.sdp);
			let descriptionToSend = _gthis.localDescription;
			if(filterMedia != null) {
				let descriptionToSend1 = descriptionToSend.version;
				let descriptionToSend2 = descriptionToSend.name;
				let _g = [];
				let _g1 = 0;
				let _g2 = descriptionToSend.media;
				while(_g1 < _g2.length) {
					let v = _g2[_g1];
					++_g1;
					if(filterOut ? !filterMedia.includes(v.mid) : filterMedia.includes(v.mid)) {
						_g.push(v);
					}
				}
				descriptionToSend = new snikket_jingle_SessionDescription(descriptionToSend1,descriptionToSend2,_g,descriptionToSend.attributes,descriptionToSend.identificationTags);
			}
			if(beforeSend != null) {
				beforeSend(descriptionToSend);
			}
			let sessionAccept = descriptionToSend.toStanza(type,_gthis.get_sid(),_gthis.initiator);
			sessionAccept.attr["to"] = _gthis.counterpart.asString();
			sessionAccept.attr["id"] = snikket_ID.medium();
			_gthis.client.sendStanza(sessionAccept);
			let outboundCandidate = _gthis.queuedOutboundCandidate.slice();
			_gthis.queuedOutboundCandidate.length = 0;
			let _g = 0;
			while(_g < outboundCandidate.length) {
				let candidate = outboundCandidate[_g];
				++_g;
				_gthis.sendIceCandidate(candidate);
			}
		});
	}
	onPeerConnection() {
		let _gthis = this;
		return this.pc.setRemoteDescription({ type : "offer", sdp : this.remoteDescription.toSdp()}).then(function(_) {
			let inboundTransportInfo = _gthis.queuedInboundTransportInfo.slice();
			_gthis.queuedInboundTransportInfo.length = 0;
			let f = $bind(_gthis,_gthis.transportInfo);
			let result = new Array(inboundTransportInfo.length);
			let _g = 0;
			let _g1 = inboundTransportInfo.length;
			while(_g < _g1) {
				let i = _g++;
				result[i] = f(inboundTransportInfo[i]);
			}
			return result;
		}).then(function(_) {
			return _gthis.setupLocalDescription("session-accept");
		}).then(function(_) {
			let tmp = _gthis.localDescription.getDtlsSetup() == "active" ? "passive" : "active";
			return _gthis.peerDtlsSetup = tmp;
		});
	}
	static fromSessionInitiate(client,stanza) {
		let jingle = stanza.getChild("jingle","urn:xmpp:jingle:1");
		let session = new snikket_jingle_InitiatedSession(client,snikket_JID.parse(stanza.attr["from"]),jingle.attr["sid"],snikket_jingle_SessionDescription.fromStanza(stanza,false));
		session.transportInfo(stanza);
		return session;
	}
}
snikket_jingle_InitiatedSession.__name__ = "snikket.jingle.InitiatedSession";
snikket_jingle_InitiatedSession.__interfaces__ = [snikket_jingle_Session];
Object.assign(snikket_jingle_InitiatedSession.prototype, {
	__class__: snikket_jingle_InitiatedSession
});
class snikket_jingle_OutgoingSession extends snikket_jingle_InitiatedSession {
	constructor(client,counterpart,sid) {
		super(client,counterpart,sid,null);
	}
	onPeerConnection() {
		return this.setupLocalDescription("session-initiate");
	}
	initiate(stanza) {
		this.remoteDescription = snikket_jingle_SessionDescription.fromStanza(stanza,true);
		this.peerDtlsSetup = this.remoteDescription.getDtlsSetup();
		let _gthis = this;
		this.pc.setRemoteDescription({ type : "answer", sdp : this.remoteDescription.toSdp()}).then(function(_) {
			return _gthis.transportInfo(stanza);
		});
		return this;
	}
}
snikket_jingle_OutgoingSession.__name__ = "snikket.jingle.OutgoingSession";
snikket_jingle_OutgoingSession.__super__ = snikket_jingle_InitiatedSession;
Object.assign(snikket_jingle_OutgoingSession.prototype, {
	__class__: snikket_jingle_OutgoingSession
});
function snikket_jingle_Session_mkCallMessage(to,from,event) {
	let m = new snikket_ChatMessageBuilder();
	m.type = 1;
	m.to = to;
	m.recipients = [to.asBare()];
	m.from = from;
	m.sender = m.from.asBare();
	m.replyTo = [m.sender];
	m.direction = 1;
	m.text = "call " + event.name;
	m.timestamp = snikket_Date.format(new Date());
	m.payloads.push(event);
	m.localId = snikket_ID.long();
	if(event.name != "propose") {
		m.versions = [m.build()];
	}
	m.localId = event.attr["id"];
	return m.build();
}
class snikket_jingle_SessionDescription {
	constructor(version,name,media,attributes,identificationTags) {
		this.version = version;
		this.name = name;
		this.media = media;
		this.attributes = attributes;
		this.identificationTags = identificationTags;
	}
	getUfragPwd() {
		let ufragPwd = null;
		let _g = 0;
		let _g1 = this.media;
		while(_g < _g1.length) {
			let m = _g1[_g];
			++_g;
			let mUfragPwd = m.getUfragPwd();
			if(ufragPwd != null && mUfragPwd.ufrag != ufragPwd.ufrag) {
				throw haxe_Exception.thrown("ufrag not unique");
			}
			if(ufragPwd != null && mUfragPwd.pwd != ufragPwd.pwd) {
				throw haxe_Exception.thrown("pwd not unique");
			}
			ufragPwd = mUfragPwd;
		}
		if(ufragPwd == null) {
			throw haxe_Exception.thrown("no ufrag or pwd found");
		}
		return ufragPwd;
	}
	getFingerprint() {
		let fingerprint = Lambda.find(this.attributes,function(attr) {
			return attr.key == "fingerprint";
		});
		if(fingerprint != null) {
			return fingerprint;
		}
		let _g = 0;
		let _g1 = this.media;
		while(_g < _g1.length) {
			let m = _g1[_g];
			++_g;
			let mFingerprint = Lambda.find(m.attributes,function(attr) {
				return attr.key == "fingerprint";
			});
			if(fingerprint != null && mFingerprint != null && fingerprint.value != mFingerprint.value) {
				throw haxe_Exception.thrown("fingerprint not unique");
			}
			fingerprint = mFingerprint;
		}
		if(fingerprint == null) {
			throw haxe_Exception.thrown("no fingerprint found");
		}
		return fingerprint;
	}
	getDtlsSetup() {
		let setup = Lambda.find(this.attributes,function(attr) {
			return attr.key == "setup";
		});
		if(setup != null) {
			return setup.value;
		}
		let _g = 0;
		let _g1 = this.media;
		while(_g < _g1.length) {
			let m = _g1[_g];
			++_g;
			let mSetup = Lambda.find(m.attributes,function(attr) {
				return attr.key == "setup";
			});
			if(setup != null && mSetup != null && setup.value != mSetup.value) {
				throw haxe_Exception.thrown("setup not unique");
			}
			setup = mSetup;
		}
		if(setup == null) {
			throw haxe_Exception.thrown("no setup found");
		}
		return setup.value;
	}
	addContent(newDescription) {
		let _g = 0;
		let _g1 = newDescription.media;
		while(_g < _g1.length) {
			let newM = _g1[_g];
			++_g;
			if(Lambda.find(this.media,function(m) {
				return m.mid == newM.mid;
			}) != null) {
				throw haxe_Exception.thrown("Media with id " + newM.mid + " already exists!");
			}
		}
		let tmp = this.version;
		let tmp1 = this.name;
		let tmp2 = this.media.concat(newDescription.media);
		let _g2 = [];
		let _g3 = 0;
		let _g4 = this.attributes;
		while(_g3 < _g4.length) {
			let v = _g4[_g3];
			++_g3;
			if(v.key != "group") {
				_g2.push(v);
			}
		}
		let tmp3 = _g2;
		let _g5 = [];
		let _g6 = 0;
		let _g7 = newDescription.attributes;
		while(_g6 < _g7.length) {
			let v = _g7[_g6];
			++_g6;
			if(v.key == "group") {
				_g5.push(v);
			}
		}
		return new snikket_jingle_SessionDescription(tmp,tmp1,tmp2,tmp3.concat(_g5),newDescription.identificationTags);
	}
	toSdp() {
		let tmp = "v=" + this.version + "\r\n" + "o=- 8770656990916039506 2 IN IP4 127.0.0.1\r\n" + "s=" + this.name + "\r\n" + "t=0 0\r\n";
		let _this = this.attributes;
		let result = new Array(_this.length);
		let _g = 0;
		let _g1 = _this.length;
		while(_g < _g1) {
			let i = _g++;
			result[i] = _this[i].toSdp();
		}
		let tmp1 = tmp + result.join("");
		let _this1 = this.media;
		let result1 = new Array(_this1.length);
		let _g2 = 0;
		let _g3 = _this1.length;
		while(_g2 < _g3) {
			let i = _g2++;
			result1[i] = _this1[i].toSdp();
		}
		return tmp1 + result1.join("");
	}
	toStanza(action,sid,initiator) {
		let iq = new snikket_Stanza("iq",{ type : "set"});
		let jingle = iq.tag("jingle",{ xmlns : "urn:xmpp:jingle:1", action : action, sid : sid});
		let group = Lambda.find(this.attributes,function(attr) {
			return attr.key == "group";
		});
		if(group != null) {
			jingle.addChild(snikket_jingle_Group.parse(group.value).toElement());
		}
		let _g = 0;
		let _g1 = this.media;
		while(_g < _g1.length) {
			let m = _g1[_g];
			++_g;
			jingle.addChild(m.toElement(this.attributes,initiator));
		}
		jingle.up();
		return iq;
	}
	static parse(input) {
		let version = 0;
		let name = "-";
		let attributes = [];
		let media = [];
		let currentAttributes = [];
		let currentMedia = null;
		let _g = 0;
		let _g1 = input.split("\r\n");
		while(_g < _g1.length) {
			let line = _g1[_g];
			++_g;
			if(line.indexOf("=") != 1) {
				continue;
			}
			let value = HxOverrides.substr(line,2,null);
			switch(line.charAt(0)) {
			case "a":
				currentAttributes.push(snikket_jingle_Attribute.parse(value));
				break;
			case "c":
				if(currentMedia != null) {
					currentMedia.connectionData = value;
				}
				break;
			case "m":
				if(currentMedia == null) {
					attributes = currentAttributes;
				} else {
					let mid = Lambda.find(currentAttributes,function(attr) {
						return attr.key == "mid";
					});
					media.push(new snikket_jingle_Media(mid == null ? null : mid.value,currentMedia.media,currentMedia.connectionData,currentMedia.port,currentMedia.protocol,currentAttributes,currentMedia.formats));
				}
				currentAttributes = [];
				let segments = value.split(" ");
				if(segments.length >= 3) {
					let segments1 = segments[0];
					let segments2 = segments[1];
					let segments3 = segments[2];
					let _this = segments.slice(3);
					let result = new Array(_this.length);
					let _g = 0;
					let _g1 = _this.length;
					while(_g < _g1) {
						let i = _g++;
						result[i] = Std.parseInt(_this[i]);
					}
					currentMedia = { media : segments1, port : segments2, protocol : segments3, formats : result};
				} else {
					currentMedia = { };
				}
				break;
			case "s":
				name = value;
				break;
			case "v":
				version = Std.parseInt(value);
				break;
			}
		}
		if(currentMedia != null) {
			let mid = Lambda.find(currentAttributes,function(attr) {
				return attr.key == "mid";
			});
			media.push(new snikket_jingle_Media(mid == null ? null : mid.value,currentMedia.media,currentMedia.connectionData,currentMedia.port,currentMedia.protocol,currentAttributes,currentMedia.formats));
		} else {
			attributes = currentAttributes;
		}
		let tags;
		let group = Lambda.find(attributes,function(attr) {
			return attr.key == "group";
		});
		if(group != null) {
			tags = snikket_jingle_Group.parse(group.value).identificationTags;
		} else {
			let result = new Array(media.length);
			let _g = 0;
			let _g1 = media.length;
			while(_g < _g1) {
				let i = _g++;
				result[i] = media[i].mid;
			}
			tags = result;
		}
		return new snikket_jingle_SessionDescription(version,name,media,attributes,tags);
	}
	static fromStanza(iq,initiator,existingDescription) {
		let attributes = [];
		let jingle = iq.getChild("jingle","urn:xmpp:jingle:1");
		let group = jingle.getChild("group","urn:xmpp:jingle:apps:grouping:0");
		let _this = jingle.allTags("content");
		let result = new Array(_this.length);
		let _g = 0;
		let _g1 = _this.length;
		while(_g < _g1) {
			let i = _g++;
			result[i] = snikket_jingle_Media.fromElement(_this[i],initiator,group != null,existingDescription);
		}
		let media = result;
		let tags;
		if(group != null) {
			let group1 = snikket_jingle_Group.fromElement(group);
			attributes.push(new snikket_jingle_Attribute("group",group1.toSdp()));
			tags = group1.identificationTags;
		} else {
			let result = new Array(media.length);
			let _g = 0;
			let _g1 = media.length;
			while(_g < _g1) {
				let i = _g++;
				result[i] = media[i].mid;
			}
			tags = result;
		}
		attributes.push(new snikket_jingle_Attribute("msid-semantic","WMS my-media-stream"));
		return new snikket_jingle_SessionDescription(0,"-",media,attributes,tags);
	}
}
snikket_jingle_SessionDescription.__name__ = "snikket.jingle.SessionDescription";
Object.assign(snikket_jingle_SessionDescription.prototype, {
	__class__: snikket_jingle_SessionDescription
});
class snikket_jingle_TransportInfo {
	constructor(media,sid) {
		this.media = media;
		this.sid = sid;
	}
	toStanza(initiator) {
		let iq = new snikket_Stanza("iq",{ type : "set"});
		let jingle = iq.tag("jingle",{ xmlns : "urn:xmpp:jingle:1", action : "transport-info", sid : this.sid});
		jingle.addChild(this.media.contentElement(initiator).addChild(this.media.toTransportElement([])).up());
		jingle.up();
		return iq;
	}
}
snikket_jingle_TransportInfo.__name__ = "snikket.jingle.TransportInfo";
Object.assign(snikket_jingle_TransportInfo.prototype, {
	__class__: snikket_jingle_TransportInfo
});
class snikket_jingle_Media {
	constructor(mid,media,connectionData,port,protocol,attributes,formats) {
		this.mid = mid;
		this.media = media;
		this.connectionData = connectionData;
		this.port = port;
		this.protocol = protocol;
		this.attributes = attributes;
		this.formats = formats;
	}
	toSdp() {
		let tmp = "m=" + this.media + " " + this.port + " " + this.protocol + " " + this.formats.join(" ") + "\r\n" + "c=" + this.connectionData + "\r\n";
		let _this = this.attributes;
		let result = new Array(_this.length);
		let _g = 0;
		let _g1 = _this.length;
		while(_g < _g1) {
			let i = _g++;
			result[i] = _this[i].toSdp();
		}
		return tmp + result.join("");
	}
	contentElement(initiator) {
		let attrs = { xmlns : "urn:xmpp:jingle:1", creator : "initiator", name : this.mid};
		if(Lambda.exists(this.attributes,function(attr) {
			return attr.key == "inactive";
		})) {
			attrs["senders"] = "none";
		} else if(Lambda.exists(this.attributes,function(attr) {
			return attr.key == "sendonly";
		})) {
			attrs["senders"] = initiator ? "initiator" : "responder";
		} else if(Lambda.exists(this.attributes,function(attr) {
			return attr.key == "recvonly";
		})) {
			attrs["senders"] = initiator ? "responder" : "initiator";
		}
		return new snikket_Stanza("content",attrs);
	}
	toElement(sessionAttributes,initiator) {
		let content = this.contentElement(initiator);
		let description = content.tag("description",{ xmlns : "urn:xmpp:jingle:apps:rtp:1", media : this.media});
		let _g = [];
		let _g1 = 0;
		let _g2 = this.attributes;
		while(_g1 < _g2.length) {
			let v = _g2[_g1];
			++_g1;
			if(v.key == "rtcp-fb") {
				_g.push(v);
			}
		}
		let _this = _g;
		let result = new Array(_this.length);
		let _g3 = 0;
		let _g4 = _this.length;
		while(_g3 < _g4) {
			let i = _g3++;
			let segments = _this[i].value.split(" ");
			let segments1 = segments[0];
			let tmp;
			if(segments[1] == "trr-int") {
				tmp = new snikket_Stanza("rtcp-fb-trr-int",{ xmlns : "urn:xmpp:jingle:apps:rtp:rtcp-fb:0", value : segments[2]});
			} else {
				let fbattrs = { xmlns : "urn:xmpp:jingle:apps:rtp:rtcp-fb:0", type : segments[1]};
				if(segments.length >= 3) {
					fbattrs["subtype"] = segments[2];
				}
				tmp = new snikket_Stanza("rtcp-fb",fbattrs);
			}
			result[i] = { id : segments1, el : tmp};
		}
		let fbs = result;
		let ssrc = new Map([]);
		let fmtp = new Map([]);
		let _g5 = 0;
		let _g6 = this.attributes;
		while(_g5 < _g6.length) {
			let attr = _g6[_g5];
			++_g5;
			if(attr.key == "fmtp") {
				let pos = attr.value.indexOf(" ");
				if(pos < 0) {
					continue;
				}
				let k = HxOverrides.substr(attr.value,0,pos);
				let _this = HxOverrides.substr(attr.value,pos + 1,null).split(";");
				let result = new Array(_this.length);
				let _g = 0;
				let _g1 = _this.length;
				while(_g < _g1) {
					let i = _g++;
					let param = _this[i];
					let eqPos = param.indexOf("=");
					let attrs = { value : eqPos > 0 ? HxOverrides.substr(param,eqPos + 1,null) : param};
					if(eqPos > 0) {
						attrs["name"] = HxOverrides.substr(param,0,eqPos);
					}
					result[i] = new snikket_Stanza("parameter",attrs);
				}
				fmtp.set(k,result);
			} else if(attr.key == "ssrc") {
				let pos = attr.value.indexOf(" ");
				if(pos < 0) {
					continue;
				}
				let id = HxOverrides.substr(attr.value,0,pos);
				if(ssrc.get(id) == null) {
					ssrc.set(id,[]);
				}
				let param = HxOverrides.substr(attr.value,pos + 1,null);
				let colonPos = param.indexOf(":");
				let attrs = { name : colonPos > 0 ? HxOverrides.substr(param,0,colonPos) : param};
				if(colonPos > 0) {
					attrs["value"] = HxOverrides.substr(param,colonPos + 1,null);
				}
				ssrc.get(id).push(new snikket_Stanza("parameter",attrs));
			} else if(attr.key == "extmap") {
				let pos = attr.value.indexOf(" ");
				if(pos < 0) {
					continue;
				}
				description.tag("rtp-hdrext",{ xmlns : "urn:xmpp:jingle:apps:rtp:rtp-hdrext:0", id : HxOverrides.substr(attr.value,0,pos), uri : HxOverrides.substr(attr.value,pos + 1,null)}).up();
			} else if(attr.key == "ssrc-group") {
				let segments = attr.value.split(" ");
				if(segments.length < 2) {
					continue;
				}
				let group = description.tag("ssrc-group",{ xmlns : "urn:xmpp:jingle:apps:rtp:ssma:0", semantics : segments[0]});
				let _g = 0;
				let _g1 = segments.slice(1);
				while(_g < _g1.length) {
					let seg = _g1[_g];
					++_g;
					group.tag("source",{ ssrc : seg}).up();
				}
				group.up();
			}
		}
		let _g7 = [];
		let _g8 = 0;
		let _g9 = fbs;
		while(_g8 < _g9.length) {
			let v = _g9[_g8];
			++_g8;
			if(v.id == "*") {
				_g7.push(v);
			}
		}
		let _this1 = _g7;
		let result1 = new Array(_this1.length);
		let _g10 = 0;
		let _g11 = _this1.length;
		while(_g10 < _g11) {
			let i = _g10++;
			result1[i] = _this1[i].el;
		}
		description.addChildren(result1);
		let _g12 = [];
		let _g13 = 0;
		let _g14 = this.attributes;
		while(_g13 < _g14.length) {
			let v = _g14[_g13];
			++_g13;
			if(v.key == "rtpmap") {
				_g12.push(v);
			}
		}
		let _this2 = _g12;
		let result2 = new Array(_this2.length);
		let _g15 = 0;
		let _g16 = _this2.length;
		while(_g15 < _g16) {
			let i = _g15++;
			let rtpmap = _this2[i];
			let pos = rtpmap.value.indexOf(" ");
			if(pos < 0) {
				throw haxe_Exception.thrown("invalid rtpmap");
			}
			let id = HxOverrides.substr(rtpmap.value,0,pos);
			let segments = HxOverrides.substr(rtpmap.value,pos + 1,null).split("/");
			let attrs = { id : id};
			if(segments.length > 0) {
				attrs["name"] = segments[0];
			}
			if(segments.length > 1) {
				attrs["clockrate"] = segments[1];
			}
			if(segments.length > 2 && segments[2] != "" && segments[2] != "1") {
				attrs["channels"] = segments[2];
			}
			let tmp = new snikket_Stanza("payload-type",attrs);
			let _g = [];
			let _g1 = 0;
			let _g2 = fbs;
			while(_g1 < _g2.length) {
				let v = _g2[_g1];
				++_g1;
				if(v.id == id) {
					_g.push(v);
				}
			}
			let _this = _g;
			let result = new Array(_this.length);
			let _g3 = 0;
			let _g4 = _this.length;
			while(_g3 < _g4) {
				let i = _g3++;
				result[i] = _this[i].el;
			}
			let tmp1 = fmtp.get(id) == null ? [] : fmtp.get(id);
			result2[i] = tmp.addChildren(result).addChildren(tmp1);
		}
		description.addChildren(result2);
		if(Lambda.exists(this.attributes,function(attr) {
			return attr.key == "extmap-allow-mixed";
		}) || Lambda.exists(sessionAttributes,function(attr) {
			return attr.key == "extmap-allow-mixed";
		})) {
			description.tag("extmap-allow-mixed",{ xmlns : "urn:xmpp:jingle:apps:rtp:rtp-hdrext:0"}).up();
		}
		let jsIterator = ssrc.entries();
		let _g_jsIterator = jsIterator;
		let _g_lastStep = jsIterator.next();
		while(!_g_lastStep.done) {
			let v = _g_lastStep.value;
			_g_lastStep = _g_jsIterator.next();
			let entry_key = v[0];
			let entry_value = v[1];
			let msid = Lambda.find(this.attributes,function(attr) {
				return attr.key == "msid";
			});
			if(msid != null && !Lambda.exists(entry_value,function(param) {
				return param.attr["name"] == "msid";
			})) {
				entry_value.push(new snikket_Stanza("parameter",{ name : "msid", value : msid.value}));
			}
			description.tag("source",{ xmlns : "urn:xmpp:jingle:apps:rtp:ssma:0", ssrc : entry_key}).addChildren(entry_value).up();
		}
		if(Lambda.exists(this.attributes,function(attr) {
			return attr.key == "rtcp-mux";
		})) {
			description.tag("rtcp-mux").up();
		}
		if(Lambda.exists(this.attributes,function(attr) {
			return attr.key == "ice-lite";
		})) {
			description.tag("ice-lite").up();
		}
		description.up();
		content.addChild(this.toTransportElement(sessionAttributes)).up();
		return content;
	}
	getUfragPwd(sessionAttributes) {
		let tmp = sessionAttributes;
		let allAttributes = this.attributes.concat(tmp != null ? tmp : []);
		let ufrag = Lambda.find(allAttributes,function(attr) {
			return attr.key == "ice-ufrag";
		});
		let pwd = Lambda.find(allAttributes,function(attr) {
			return attr.key == "ice-pwd";
		});
		if(ufrag == null || pwd == null) {
			throw haxe_Exception.thrown("transport is missing ufrag or pwd");
		}
		return { ufrag : ufrag.value, pwd : pwd.value};
	}
	toTransportElement(sessionAttributes) {
		let transportAttr = { xmlns : "urn:xmpp:jingle:transports:ice-udp:1"};
		let ufragPwd = this.getUfragPwd(sessionAttributes);
		transportAttr["ufrag"] = ufragPwd.ufrag;
		transportAttr["pwd"] = ufragPwd.pwd;
		let transport = new snikket_Stanza("transport",transportAttr);
		let fingerprint = Lambda.find(this.attributes.concat(sessionAttributes),function(attr) {
			return attr.key == "fingerprint";
		});
		let setup = Lambda.find(this.attributes.concat(sessionAttributes),function(attr) {
			return attr.key == "setup";
		});
		if(fingerprint != null && setup != null && fingerprint.value.indexOf(" ") > 0) {
			let pos = fingerprint.value.indexOf(" ");
			transport.textTag("fingerprint",HxOverrides.substr(fingerprint.value,pos + 1,null),{ xmlns : "urn:xmpp:jingle:apps:dtls:0", hash : HxOverrides.substr(fingerprint.value,0,pos), setup : setup.value});
		}
		let _gthis = this;
		let _g = [];
		let _g1 = 0;
		let _g2 = this.attributes;
		while(_g1 < _g2.length) {
			let v = _g2[_g1];
			++_g1;
			if(v.key == "candidate") {
				_g.push(v);
			}
		}
		let _this = _g;
		let result = new Array(_this.length);
		let _g3 = 0;
		let _g4 = _this.length;
		while(_g3 < _g4) {
			let i = _g3++;
			result[i] = snikket_jingle_IceCandidate.parse(_this[i].value,_gthis.mid,ufragPwd.ufrag).toElement();
		}
		transport.addChildren(result);
		transport.up();
		return transport;
	}
	static fromElement(content,initiator,hasGroup,existingDescription) {
		let mediaAttributes = [];
		let mediaFormats = [];
		let mid = content.attr["name"];
		let transport = content.getChild("transport","urn:xmpp:jingle:transports:ice-udp:1");
		if(transport == null) {
			throw haxe_Exception.thrown("ice-udp transport is missing");
		}
		let ufrag = transport.attr["ufrag"];
		let pwd = transport.attr["pwd"];
		if((ufrag == null || pwd == null) && existingDescription != null) {
			let ufragPwd = existingDescription.getUfragPwd();
			ufrag = ufragPwd.ufrag;
			pwd = ufragPwd.pwd;
		}
		if(ufrag == null) {
			throw haxe_Exception.thrown("transport is missing ufrag");
		}
		mediaAttributes.push(new snikket_jingle_Attribute("ice-ufrag",ufrag));
		if(pwd == null) {
			throw haxe_Exception.thrown("transport is missing pwd");
		}
		mediaAttributes.push(new snikket_jingle_Attribute("ice-pwd",pwd));
		mediaAttributes.push(new snikket_jingle_Attribute("ice-options","trickle"));
		let fingerprint = transport.getChild("fingerprint","urn:xmpp:jingle:apps:dtls:0");
		if(fingerprint == null) {
			if(existingDescription != null) {
				mediaAttributes.push(existingDescription.getFingerprint());
			}
		} else {
			mediaAttributes.push(new snikket_jingle_Attribute("fingerprint",fingerprint.attr["hash"] + " " + fingerprint.getText()));
			if(fingerprint.attr["setup"] != null) {
				mediaAttributes.push(new snikket_jingle_Attribute("setup",fingerprint.attr["setup"]));
			}
		}
		let description = content.getChild("description","urn:xmpp:jingle:apps:rtp:1");
		let _g = 0;
		let _g1 = description.allTags("payload-type");
		while(_g < _g1.length) {
			let payloadType = _g1[_g];
			++_g;
			let id = Std.parseInt(payloadType.attr["id"]);
			if(payloadType.attr["id"] == null) {
				throw haxe_Exception.thrown("payload-type missing or invalid id");
			}
			mediaFormats.push(id);
			let clockRate = Std.parseInt(payloadType.attr["clockrate"]);
			let channels = Std.parseInt(payloadType.attr["channels"]);
			mediaAttributes.push(new snikket_jingle_Attribute("rtpmap",id + " " + payloadType.attr["name"] + "/" + (clockRate == null ? 0 : clockRate) + (channels == null || channels == 1 ? "" : "/" + channels)));
			let _this = payloadType.allTags("parameter");
			let result = new Array(_this.length);
			let _g2 = 0;
			let _g3 = _this.length;
			while(_g2 < _g3) {
				let i = _g2++;
				let el = _this[i];
				result[i] = (el.attr["name"] == null ? "" : el.attr["name"] + "=") + el.attr["value"];
			}
			let parameters = result;
			if(parameters.length > 0) {
				mediaAttributes.push(new snikket_jingle_Attribute("fmtp",id + " " + parameters.join(";")));
			}
			let _g4 = 0;
			let _g5 = payloadType.allTags("rtcp-fb","urn:xmpp:jingle:apps:rtp:rtcp-fb:0");
			while(_g4 < _g5.length) {
				let feedbackNegotiation = _g5[_g4];
				++_g4;
				let subtype = feedbackNegotiation.attr["subtype"];
				mediaAttributes.push(new snikket_jingle_Attribute("rtcp-fb",id + " " + feedbackNegotiation.attr["type"] + (subtype == null || subtype == "" ? "" : " " + subtype)));
			}
			let _g6 = 0;
			let _g7 = payloadType.allTags("rtcp-fb-trr-int","urn:xmpp:jingle:apps:rtp:rtcp-fb:0");
			while(_g6 < _g7.length) {
				let trrInt = _g7[_g6];
				++_g6;
				mediaAttributes.push(new snikket_jingle_Attribute("rtcp-fb",id + " trr-int " + trrInt.attr["value"]));
			}
		}
		let _g2 = 0;
		let _g3 = description.allTags("rtcp-fb","urn:xmpp:jingle:apps:rtp:rtcp-fb:0");
		while(_g2 < _g3.length) {
			let feedbackNegotiation = _g3[_g2];
			++_g2;
			let subtype = feedbackNegotiation.attr["subtype"];
			mediaAttributes.push(new snikket_jingle_Attribute("rtcp-fb","* " + feedbackNegotiation.attr["type"] + (subtype == null || subtype == "" ? "" : " " + subtype)));
		}
		let _g4 = 0;
		let _g5 = description.allTags("rtcp-fb-trr-int","urn:xmpp:jingle:apps:rtp:rtcp-fb:0");
		while(_g4 < _g5.length) {
			let trrInt = _g5[_g4];
			++_g4;
			mediaAttributes.push(new snikket_jingle_Attribute("rtcp-fb","* trr-int " + trrInt.attr["value"]));
		}
		let _g6 = 0;
		let _g7 = description.allTags("rtp-hdrext","urn:xmpp:jingle:apps:rtp:rtp-hdrext:0");
		while(_g6 < _g7.length) {
			let headerExtension = _g7[_g6];
			++_g6;
			mediaAttributes.push(new snikket_jingle_Attribute("extmap",headerExtension.attr["id"] + " " + headerExtension.attr["uri"]));
		}
		if(description.getChild("extmap-allow-mixed","urn:xmpp:jingle:apps:rtp:rtp-hdrext:0") != null) {
			mediaAttributes.push(new snikket_jingle_Attribute("extmap-allow-mixed",""));
		}
		let _g8 = 0;
		let _g9 = description.allTags("ssrc-group","urn:xmpp:jingle:apps:rtp:ssma:0");
		while(_g8 < _g9.length) {
			let sourceGroup = _g9[_g8];
			++_g8;
			let tmp = sourceGroup.attr["semantics"] + " ";
			let _this = sourceGroup.allTags("source");
			let result = new Array(_this.length);
			let _g = 0;
			let _g1 = _this.length;
			while(_g < _g1) {
				let i = _g++;
				result[i] = _this[i].attr["ssrc"];
			}
			mediaAttributes.push(new snikket_jingle_Attribute("ssrc-group",tmp + result.join(" ")));
		}
		let _g10 = 0;
		let _g11 = description.allTags("source","urn:xmpp:jingle:apps:rtp:ssma:0");
		while(_g10 < _g11.length) {
			let source = _g11[_g10];
			++_g10;
			let _g = 0;
			let _g1 = source.allTags("parameter");
			while(_g < _g1.length) {
				let parameter = _g1[_g];
				++_g;
				mediaAttributes.push(new snikket_jingle_Attribute("ssrc",source.attr["ssrc"] + " " + parameter.attr["name"] + ":" + parameter.attr["value"]));
			}
		}
		mediaAttributes.push(new snikket_jingle_Attribute("mid",mid));
		let _g12 = content.attr["senders"];
		if(_g12 == null) {
			mediaAttributes.push(new snikket_jingle_Attribute("sendrecv",""));
		} else {
			switch(_g12) {
			case "initiator":
				if(initiator) {
					mediaAttributes.push(new snikket_jingle_Attribute("sendonly",""));
				} else {
					mediaAttributes.push(new snikket_jingle_Attribute("recvonly",""));
				}
				break;
			case "none":
				mediaAttributes.push(new snikket_jingle_Attribute("inactive",""));
				break;
			case "responder":
				if(initiator) {
					mediaAttributes.push(new snikket_jingle_Attribute("recvonly",""));
				} else {
					mediaAttributes.push(new snikket_jingle_Attribute("sendonly",""));
				}
				break;
			default:
				mediaAttributes.push(new snikket_jingle_Attribute("sendrecv",""));
			}
		}
		if(hasGroup || description.getChild("rtcp-mux") != null) {
			mediaAttributes.push(new snikket_jingle_Attribute("rtcp-mux",""));
		}
		if(description.getChild("ice-lite") != null) {
			mediaAttributes.push(new snikket_jingle_Attribute("ice-lite",""));
		}
		mediaAttributes.push(new snikket_jingle_Attribute("rtcp","9 IN IP4 0.0.0.0"));
		return new snikket_jingle_Media(mid,description == null ? "" : description.attr["media"],"IN IP4 0.0.0.0","9","UDP/TLS/RTP/SAVPF",mediaAttributes,mediaFormats);
	}
}
snikket_jingle_Media.__name__ = "snikket.jingle.Media";
Object.assign(snikket_jingle_Media.prototype, {
	__class__: snikket_jingle_Media
});
class snikket_jingle_IceCandidate {
	constructor(sdpMid,ufrag,foundation,component,transport,priority,connectionAddress,port,parameters) {
		this.sdpMid = sdpMid;
		this.ufrag = ufrag;
		this.foundation = foundation;
		this.component = component;
		this.transport = transport;
		this.priority = priority;
		this.connectionAddress = connectionAddress;
		this.port = port;
		this.parameters = parameters;
	}
	toElement() {
		let tmp = this.parameters.get("generation");
		let attrs = { xmlns : this.parameters.get("tcptype") == null ? "urn:xmpp:jingle:transports:ice-udp:1" : "urn:xmpp:jingle:transports:ice:0", foundation : this.foundation, component : this.component, protocol : this.transport.toLowerCase(), priority : this.priority, ip : this.connectionAddress, port : this.port, generation : tmp != null ? tmp : "0"};
		if(this.parameters.get("typ") != null) {
			attrs["type"] = this.parameters.get("typ");
		}
		if(this.parameters.get("raddr") != null) {
			attrs["rel-addr"] = this.parameters.get("raddr");
		}
		if(this.parameters.get("rport") != null) {
			attrs["rel-port"] = this.parameters.get("rport");
		}
		if(this.parameters.get("tcptype") != null) {
			attrs["tcptype"] = this.parameters.get("tcptype");
		}
		return new snikket_Stanza("candidate",attrs);
	}
	toSdp() {
		let result = "candidate:" + this.foundation + " " + this.component + " " + this.transport + " " + this.priority + " " + this.connectionAddress + " " + this.port;
		if(this.parameters.has("typ")) {
			result += " typ " + this.parameters.get("typ");
		}
		if(this.parameters.has("raddr")) {
			result += " raddr " + this.parameters.get("raddr");
		}
		if(this.parameters.has("rport")) {
			result += " rport " + this.parameters.get("rport");
		}
		let jsIterator = this.parameters.entries();
		let entry_jsIterator = jsIterator;
		let entry_lastStep = jsIterator.next();
		while(!entry_lastStep.done) {
			let v = entry_lastStep.value;
			entry_lastStep = entry_jsIterator.next();
			let entry_key = v[0];
			let entry_value = v[1];
			if(entry_key != "typ" && entry_key != "raddr" && entry_key != "rport") {
				result += " " + entry_key + " " + entry_value;
			}
		}
		return result;
	}
	static fromElement(candidate,sdpMid,ufrag) {
		let parameters = new Map([]);
		if(candidate.attr["type"] != null) {
			parameters.set("typ",candidate.attr["type"]);
		}
		if(candidate.attr["rel-addr"] != null) {
			parameters.set("raddr",candidate.attr["rel-addr"]);
		}
		if(candidate.attr["rel-port"] != null) {
			parameters.set("rport",candidate.attr["rel-port"]);
		}
		if(candidate.attr["generation"] != null) {
			parameters.set("generation",candidate.attr["generation"]);
		}
		if(candidate.attr["tcptype"] != null) {
			parameters.set("tcptype",candidate.attr["tcptype"]);
		}
		if(ufrag != null) {
			parameters.set("ufrag",ufrag);
		}
		return new snikket_jingle_IceCandidate(sdpMid,ufrag,candidate.attr["foundation"],candidate.attr["component"],candidate.attr["protocol"].toLowerCase(),candidate.attr["priority"],candidate.attr["ip"],candidate.attr["port"],parameters);
	}
	static fromTransport(transport,sdpMid) {
		let _this = transport.allTags("candidate");
		let result = new Array(_this.length);
		let _g = 0;
		let _g1 = _this.length;
		while(_g < _g1) {
			let i = _g++;
			result[i] = snikket_jingle_IceCandidate.fromElement(_this[i],sdpMid,transport.attr["ufrag"]);
		}
		return result;
	}
	static fromStanza(iq) {
		let jingle = iq.getChild("jingle","urn:xmpp:jingle:1");
		let _g = [];
		let x = $getIterator(jingle.allTags("content"));
		while(x.hasNext()) {
			let x1 = x.next();
			let transport = x1.getChild("transport","urn:xmpp:jingle:transports:ice-udp:1");
			_g.push(snikket_jingle_IceCandidate.fromTransport(transport,x1.attr["name"]));
		}
		let _g1 = [];
		let e = $getIterator(_g);
		while(e.hasNext()) {
			let e1 = e.next();
			let x = $getIterator(e1);
			while(x.hasNext()) {
				let x1 = x.next();
				_g1.push(x1);
			}
		}
		return _g1;
	}
	static parse(input,sdpMid,ufrag) {
		if(HxOverrides.substr(input,0,10) == "candidate:") {
			input = HxOverrides.substr(input,11,null);
		}
		let segments = input.split(" ");
		let paramSegs = segments.slice(6);
		let paramLength = paramSegs.length / 2 | 0;
		let parameters = new Map([]);
		let _g = 0;
		let _g1 = paramLength;
		while(_g < _g1) {
			let i = _g++;
			parameters.set(paramSegs[i * 2],paramSegs[i * 2 + 1]);
		}
		if(ufrag != null) {
			parameters.set("ufrag",ufrag);
		}
		return new snikket_jingle_IceCandidate(sdpMid,ufrag,segments[0],segments[1],segments[2],segments[3],segments[4],segments[5],parameters);
	}
}
snikket_jingle_IceCandidate.__name__ = "snikket.jingle.IceCandidate";
Object.assign(snikket_jingle_IceCandidate.prototype, {
	__class__: snikket_jingle_IceCandidate
});
class snikket_jingle_Attribute {
	constructor(key,value) {
		this.key = key;
		this.value = value;
	}
	toSdp() {
		return "a=" + this.key + (this.value == null || this.value == "" ? "" : ":" + this.value) + "\r\n";
	}
	toString() {
		return this.toSdp();
	}
	static parse(input) {
		let pos = input.indexOf(":");
		if(pos < 0) {
			return new snikket_jingle_Attribute(input,"");
		} else {
			return new snikket_jingle_Attribute(HxOverrides.substr(input,0,pos),HxOverrides.substr(input,pos + 1,null));
		}
	}
}
snikket_jingle_Attribute.__name__ = "snikket.jingle.Attribute";
Object.assign(snikket_jingle_Attribute.prototype, {
	__class__: snikket_jingle_Attribute
});
class snikket_persistence_Dummy {
	constructor() {
	}
	lastId(accountId,chatId,callback) {
		callback(null);
	}
	storeChats(accountId,chat) {
	}
	getChats(accountId,callback) {
		callback([]);
	}
	storeMessages(accountId,messages,callback) {
		callback(messages);
	}
	updateMessage(accountId,message) {
	}
	getMessage(accountId,chatId,serverId,localId,callback) {
		callback(null);
	}
	getMessagesBefore(accountId,chatId,beforeId,beforeTime,callback) {
		callback([]);
	}
	getMessagesAfter(accountId,chatId,afterId,afterTime,callback) {
		callback([]);
	}
	getMessagesAround(accountId,chatId,aroundId,aroundTime,callback) {
		callback([]);
	}
	getChatsUnreadDetails(accountId,chats,callback) {
		callback([]);
	}
	storeReaction(accountId,update,callback) {
		callback(null);
	}
	updateMessageStatus(accountId,localId,status,callback) {
		callback(null);
	}
	getMediaUri(hashAlgorithm,hash,callback) {
		callback(null);
	}
	hasMedia(hashAlgorithm,hash,callback) {
		callback(false);
	}
	storeMedia(mime,bd,callback) {
		callback();
	}
	removeMedia(hashAlgorithm,hash) {
	}
	storeCaps(caps) {
	}
	getCaps(ver,callback) {
		callback(null);
	}
	storeLogin(login,clientId,displayName,token) {
	}
	getLogin(login,callback) {
		callback(null,null,0,null);
	}
	removeAccount(accountId,completely) {
	}
	storeStreamManagement(accountId,sm) {
	}
	getStreamManagement(accountId,callback) {
		callback(null);
	}
	storeService(accountId,serviceId,name,node,caps) {
	}
	findServicesWithFeature(accountId,feature,callback) {
		callback([]);
	}
}
$hx_exports["snikket"]["persistence"]["Dummy"] = snikket_persistence_Dummy;
snikket_persistence_Dummy.__name__ = "snikket.persistence.Dummy";
snikket_persistence_Dummy.__interfaces__ = [snikket_Persistence];
Object.assign(snikket_persistence_Dummy.prototype, {
	__class__: snikket_persistence_Dummy
});
class snikket_persistence_KeyValueStore {
}
snikket_persistence_KeyValueStore.__name__ = "snikket.persistence.KeyValueStore";
snikket_persistence_KeyValueStore.__isInterface__ = true;
Object.assign(snikket_persistence_KeyValueStore.prototype, {
	__class__: snikket_persistence_KeyValueStore
});
class snikket_persistence_MediaStore {
}
snikket_persistence_MediaStore.__name__ = "snikket.persistence.MediaStore";
snikket_persistence_MediaStore.__isInterface__ = true;
Object.assign(snikket_persistence_MediaStore.prototype, {
	__class__: snikket_persistence_MediaStore
});
class snikket_persistence_Sqlite {
	constructor(dbfile,media) {
		this.smStoreNext = null;
		this.smStoreInProgress = false;
		this.storeChatTimer = null;
		this.storeChatBuffer = new Map([]);
		this.media = media;
		media.setKV(this);
		this.db = new snikket_persistence_SqliteDriver(dbfile);
		let _gthis = this;
		let version = thenshim_Promise.then(this.db.exec("PRAGMA user_version;"),function(iter) {
			let tmp = iter.array[iter.current++];
			let tmp1 = Std.parseInt(tmp != null ? tmp.user_version : null);
			let version = tmp1 != null ? tmp1 : 0;
			if(version < 1) {
				_gthis.db.exec("CREATE TABLE messages (\n\t\t\t\t\taccount_id TEXT NOT NULL,\n\t\t\t\t\tmam_id TEXT,\n\t\t\t\t\tmam_by TEXT,\n\t\t\t\t\tstanza_id TEXT,\n\t\t\t\t\tcorrection_id TEXT NOT NULL,\n\t\t\t\t\tsync_point INTEGER NOT NULL,\n\t\t\t\t\tchat_id TEXT NOT NULL,\n\t\t\t\t\tsender_id TEXT NOT NULL,\n\t\t\t\t\tcreated_at INTEGER NOT NULL,\n\t\t\t\t\tstatus INTEGER NOT NULL,\n\t\t\t\t\tdirection INTEGER NOT NULL,\n\t\t\t\t\ttype INTEGER NOT NULL,\n\t\t\t\t\tstanza TEXT NOT NULL,\n\t\t\t\t\tPRIMARY KEY (account_id, mam_id, mam_by, stanza_id)\n\t\t\t\t);\n\t\t\t\tCREATE INDEX messages_created_at ON messages (account_id, chat_id, created_at);\n\t\t\t\tCREATE INDEX messages_correction_id ON messages (correction_id);\n\t\t\t\tCREATE TABLE chats (\n\t\t\t\t\taccount_id TEXT NOT NULL,\n\t\t\t\t\tchat_id TEXT NOT NULL,\n\t\t\t\t\ttrusted INTEGER NOT NULL,\n\t\t\t\t\tavatar_sha1 BLOB,\n\t\t\t\t\tfn TEXT,\n\t\t\t\t\tui_state INTEGER NOT NULL,\n\t\t\t\t\tblocked INTEGER NOT NULL,\n\t\t\t\t\textensions TEXT,\n\t\t\t\t\tread_up_to_id TEXT,\n\t\t\t\t\tread_up_to_by TEXT,\n\t\t\t\t\tcaps_ver BLOB,\n\t\t\t\t\tpresence BLOB NOT NULL,\n\t\t\t\t\tclass TEXT NOT NULL,\n\t\t\t\t\tPRIMARY KEY (account_id, chat_id)\n\t\t\t\t) STRICT;\n\t\t\t\tCREATE TABLE keyvaluepairs (\n\t\t\t\t\tk TEXT NOT NULL PRIMARY KEY,\n\t\t\t\t\tv TEXT NOT NULL\n\t\t\t\t) STRICT;\n\t\t\t\tCREATE TABLE caps (\n\t\t\t\t\tsha1 BLOB NOT NULL PRIMARY KEY,\n\t\t\t\t\tcaps BLOB NOT NULL\n\t\t\t\t) STRICT;\n\t\t\t\tCREATE TABLE services (\n\t\t\t\t\taccount_id TEXT NOT NULL,\n\t\t\t\t\tservice_id TEXT NOT NULL,\n\t\t\t\t\tname TEXT,\n\t\t\t\t\tnode TEXT,\n\t\t\t\t\tcaps BLOB NOT NULL,\n\t\t\t\t\tPRIMARY KEY (account_id, service_id)\n\t\t\t\t) STRICT;\n\t\t\t\tCREATE TABLE accounts (\n\t\t\t\t\taccount_id TEXT NOT NULL,\n\t\t\t\t\tclient_id TEXT NOT NULL,\n\t\t\t\t\tdisplay_name TEXT,\n\t\t\t\t\ttoken TEXT,\n\t\t\t\t\tfast_count INTEGER NOT NULL DEFAULT 0,\n\t\t\t\t\tsm_state BLOB,\n\t\t\t\t\tPRIMARY KEY (account_id)\n\t\t\t\t) STRICT;\n\t\t\t\tCREATE TABLE reactions (\n\t\t\t\t\taccount_id TEXT NOT NULL,\n\t\t\t\t\tupdate_id TEXT NOT NULL,\n\t\t\t\t\tmam_id TEXT,\n\t\t\t\t\tmam_by TEXT,\n\t\t\t\t\tstanza_id TEXT,\n\t\t\t\t\tchat_id TEXT NOT NULL,\n\t\t\t\t\tsender_id TEXT NOT NULL,\n\t\t\t\t\tcreated_at INTEGER NOT NULL,\n\t\t\t\t\treactions BLOB NOT NULL,\n\t\t\t\t\tkind INTEGER NOT NULL,\n\t\t\t\t\tPRIMARY KEY (account_id, chat_id, sender_id, update_id)\n\t\t\t\t) STRICT;\n\t\t\t\tPRAGMA user_version = 1;");
			}
		});
	}
	get(k,callback) {
		thenshim_Promise.then(this.db.exec("SELECT v FROM keyvaluepairs WHERE k=? LIMIT 1",[k]),function(iter) {
			let _g = iter;
			while(_g.current < _g.array.length) {
				let row = _g.array[_g.current++];
				callback(row.v);
				return;
			}
			callback(null);
		});
	}
	set(k,v,callback) {
		if(v == null) {
			thenshim_Promise.then(this.db.exec("DELETE FROM keyvaluepairs WHERE k=?",[k]),function(_) {
				callback();
			});
		} else {
			thenshim_Promise.then(this.db.exec("INSERT OR REPLACE INTO keyvaluepairs VALUES (?,?)",[k,v]),function(_) {
				callback();
			});
		}
	}
	lastId(accountId,chatId,callback) {
		let params = [accountId];
		let q = "SELECT mam_id FROM messages WHERE mam_id IS NOT NULL AND sync_point AND account_id=?";
		if(chatId == null) {
			q += " AND mam_by=?";
			params.push(accountId);
		} else {
			q += " AND chat_id=?";
			params.push(chatId);
		}
		q += " ORDER BY ROWID DESC LIMIT 1";
		thenshim_Promise.then(this.db.exec(q,params),function(iter) {
			let callback1 = callback;
			let tmp = iter.array[iter.current++];
			callback1(tmp != null ? tmp.mam_id : null);
		},function(_) {
			callback(null);
		});
	}
	storeChats(accountId,chats) {
		if(this.storeChatTimer != null) {
			this.storeChatTimer.stop();
		}
		let _g = 0;
		while(_g < chats.length) {
			let chat = chats[_g];
			++_g;
			this.storeChatBuffer.set(accountId + "\n" + chat.chatId,chat);
		}
		let _gthis = this;
		this.storeChatTimer = haxe_Timer.delay(function() {
			let mapPresence = function(chat) {
				let storePresence = { };
				let jsIterator = chat.presence.entries();
				let _g_jsIterator = jsIterator;
				let _g_lastStep = jsIterator.next();
				while(!_g_lastStep.done) {
					let v = _g_lastStep.value;
					_g_lastStep = _g_jsIterator.next();
					let _g_key = v[0];
					let _g_value = v[1];
					let resource = _g_key;
					let presence = _g_value;
					storePresence[resource] = { };
					if(presence.caps != null) {
						_gthis.storeCaps(presence.caps);
						storePresence[resource].caps = presence.caps.ver();
					}
					if(presence.mucUser != null) {
						storePresence[resource].mucUser = presence.mucUser.toString();
					}
				}
				return storePresence;
			};
			let q_b = "";
			q_b += "INSERT OR REPLACE INTO chats VALUES ";
			let first = true;
			let jsIterator = _gthis.storeChatBuffer.values();
			let __jsIterator = jsIterator;
			let __lastStep = jsIterator.next();
			while(!__lastStep.done) {
				let v = __lastStep.value;
				__lastStep = __jsIterator.next();
				let _ = v;
				if(!first) {
					q_b += ",";
				}
				first = false;
				q_b += "(?,?,?,?,?,?,?,?,?,?,?,jsonb(?),?)";
			}
			let _gthis1 = _gthis.db;
			let this1 = _gthis.storeChatBuffer;
			let _g = [];
			let x = $getIterator({ iterator : function() {
				return new js_lib_HaxeIterator(this1.values());
			}});
			while(x.hasNext()) {
				let x1 = x.next();
				let channel = ((x1) instanceof snikket_Channel) ? x1 : null;
				if(channel != null) {
					_gthis.storeCaps(channel.disco);
				}
				let accountId1 = accountId;
				let x2 = x1.chatId;
				let row = x1.isTrusted();
				let x3 = x1.avatarSha1;
				let row1 = x1.getDisplayName();
				let x4 = x1.uiState;
				let x5 = x1.isBlocked;
				let row2 = x1.extensions.toString();
				let row3 = x1.readUpTo();
				let x6 = x1.readUpToBy;
				let tmp = channel != null ? channel.disco : null;
				let row4 = tmp != null ? tmp.verRaw().hash : null;
				let row5 = JSON.stringify(mapPresence(x1));
				let c = js_Boot.getClass(x1);
				let row6 = [accountId1,x2,row,x3,row1,x4,x5,row2,row3,x6,row4,row5,c.__name__.split(".").pop()];
				_g.push(row6);
			}
			let _g1 = [];
			let e = $getIterator(_g);
			while(e.hasNext()) {
				let e1 = e.next();
				let x = $getIterator(e1);
				while(x.hasNext()) {
					let x1 = x.next();
					_g1.push(x1);
				}
			}
			_gthis1.exec(q_b,_g1);
			_gthis.storeChatTimer = null;
			_gthis.storeChatBuffer.clear();
		},100);
	}
	getChats(accountId,callback) {
		let _gthis = this;
		thenshim_Promise.then(thenshim_Promise.then(this.db.exec("SELECT chat_id, trusted, avatar_sha1, fn, ui_state, blocked, extensions, read_up_to_id, read_up_to_by, json(caps) AS caps, json(presence) AS presence, class FROM chats LEFT JOIN caps ON chats.caps_ver=caps.sha1 WHERE account_id=?",[accountId]),function(result) {
			let fetchCaps = new Map([]);
			let chats = [];
			let _g = result;
			while(_g.current < _g.array.length) {
				let row = _g.array[_g.current++];
				let capsJson = row.caps == null ? null : JSON.parse(row.caps);
				row.capsObj = capsJson == null ? null : new snikket_Caps(capsJson.node,capsJson.identities.map(function(i) {
					return new snikket_Identity(i.category,i.type,i.name);
				}),capsJson.features);
				let presenceJson = JSON.parse(row.presence);
				row.presenceJson = presenceJson;
				let access = presenceJson;
				let _g_access = access;
				let _g_keys = Reflect.fields(access);
				let _g_index = 0;
				while(_g_index < _g_keys.length) {
					let key = _g_keys[_g_index++];
					let _g_value = _g_access[key];
					let _g_key = key;
					let resource = _g_key;
					let presence = _g_value;
					if(presence.caps) {
						let k = haxe_crypto_Base64.decode(presence.caps).b.bufferValue;
						fetchCaps.set(k,true);
					}
				}
				chats.push(row);
			}
			let fetchCapsSha1s = Lambda.array({ iterator : function() {
				return new js_lib_HaxeIterator(fetchCaps.keys());
			}});
			let _gthis1 = _gthis.db;
			let result1 = new Array(fetchCapsSha1s.length);
			let _g1 = 0;
			let _g2 = fetchCapsSha1s.length;
			while(_g1 < _g2) {
				let i = _g1++;
				result1[i] = "?";
			}
			return thenshim_Promise.then(_gthis1.exec("SELECT sha1, json(caps) AS caps FROM caps WHERE sha1 IN (" + result1.join(",") + ")",fetchCapsSha1s),function(capsResult) {
				return { chats : chats, caps : capsResult};
			});
		}),function(result) {
			let capsMap = new Map([]);
			let _g = result.caps;
			while(_g.current < _g.array.length) {
				let row = _g.array[_g.current++];
				let json = JSON.parse(row.caps);
				let k = haxe_crypto_Base64.encode(haxe_io_Bytes.ofData(row.sha1));
				let v = new snikket_Caps(json.node,json.identities.map(function(i) {
					return new snikket_Identity(i.category,i.type,i.name);
				}),json.features);
				capsMap.set(k,v);
			}
			let chats = [];
			let _g1 = 0;
			let _g2 = result.chats;
			while(_g1 < _g2.length) {
				let row = _g2[_g1];
				++_g1;
				let presenceMap = new Map([]);
				let presenceJson = row.presenceJson;
				let access = presenceJson;
				let _g_access = access;
				let _g_keys = Reflect.fields(access);
				let _g_index = 0;
				while(_g_index < _g_keys.length) {
					let key = _g_keys[_g_index++];
					let _g_value = _g_access[key];
					let _g_key = key;
					let resource = _g_key;
					let presence = _g_value;
					let v = new snikket_Presence(presence.caps == null ? null : capsMap.get(presence.caps),presence.mucUser == null ? null : snikket_Stanza.parse(presence.mucUser));
					presenceMap.set(resource,v);
				}
				chats.push(new snikket_SerializedChat(row.chat_id,row.trusted,row.avatar_sha1,presenceMap,row.fn,row.ui_state,row.blocked,row.extensions,row.read_up_to_id,row.read_up_to_by,row.capsObj,Reflect.field(row,"class")));
			}
			callback(chats);
		});
	}
	storeMessages(accountId,messages,callback) {
		if(messages.length < 1) {
			callback(messages);
			return;
		}
		let chatIds = [];
		let localIds = [];
		let replyTos = [];
		let _g = 0;
		while(_g < messages.length) {
			let message = messages[_g];
			++_g;
			if(message.serverId == null && message.localId == null) {
				throw haxe_Exception.thrown("Cannot store a message with no id");
			}
			if(message.serverId == null && message.isIncoming()) {
				throw haxe_Exception.thrown("Cannot store an incoming message with no server id");
			}
			if(message.serverId != null && message.serverIdBy == null) {
				throw haxe_Exception.thrown("Cannot store a message with a server id and no by");
			}
			if(!message.isIncoming() && message.versions.length < 1) {
				chatIds.push(message.chatId());
				localIds.push(message.localId);
			}
			if(message.replyToMessage != null && message.replyToMessage.serverIdBy == null) {
				replyTos.push({ chatId : message.chatId(), serverId : message.replyToMessage.serverId, localId : message.replyToMessage.localId});
			}
		}
		let _gthis = this;
		let tmp;
		if(chatIds.length > 0 && localIds.length > 0) {
			let q_b = "";
			q_b += "DELETE FROM messages WHERE account_id=? AND direction=? AND chat_id IN (";
			let result = new Array(chatIds.length);
			let _g = 0;
			let _g1 = chatIds.length;
			while(_g < _g1) {
				let i = _g++;
				result[i] = "?";
			}
			q_b += Std.string(result.join(","));
			q_b += ") AND stanza_id IN (";
			let result1 = new Array(localIds.length);
			let _g2 = 0;
			let _g3 = localIds.length;
			while(_g2 < _g3) {
				let i = _g2++;
				result1[i] = "?";
			}
			q_b += Std.string(result1.join(","));
			q_b += ")";
			tmp = this.db.exec(q_b,[accountId,1].concat(chatIds).concat(localIds));
		} else {
			tmp = thenshim_Promise.resolve(null);
		}
		thenshim_Promise.then(thenshim_Promise.then(tmp,function(_) {
			let _gthis1 = _gthis.db;
			let result = new Array(messages.length);
			let _g = 0;
			let _g1 = messages.length;
			while(_g < _g1) {
				let i = _g++;
				result[i] = "(?,?,?,?,?,?,?,?,CAST(unixepoch(?, 'subsec') * 1000 AS INTEGER),?,?,?,?)";
			}
			let tmp = "INSERT OR REPLACE INTO messages VALUES " + result.join(",");
			let _g2 = [];
			let _g_current = 0;
			let _g_array = messages;
			while(_g_current < _g_array.length) {
				let x = _g_array[_g_current++];
				let correctable = x;
				let message = x.versions.length == 1 ? x.versions[0] : x;
				let tmp = correctable.localId;
				_g2.push([accountId,message.serverId,message.serverIdBy,message.localId,tmp != null ? tmp : correctable.serverId,correctable.syncPoint,correctable.chatId(),correctable.senderId,message.timestamp,message.status,message.direction,message.type,message.asStanza().toString()]);
			}
			let _g3 = [];
			let e = $getIterator(_g2);
			while(e.hasNext()) {
				let e1 = e.next();
				let x = $getIterator(e1);
				while(x.hasNext()) {
					let x1 = x.next();
					_g3.push(x1);
				}
			}
			return _gthis1.exec(tmp,_g3);
		}),function(_) {
			return thenshim_Promise.then(thenshim_Promise.then(_gthis.hydrateReplyTo(accountId,messages,replyTos),function(ms) {
				return _gthis.hydrateReactions(accountId,ms);
			}),callback);
		});
	}
	updateMessage(accountId,message) {
		this.storeMessages(accountId,[message],function(_) {
		});
	}
	getMessage(accountId,chatId,serverId,localId,callback) {
		let q = "SELECT stanza, direction, type, strftime('%FT%H:%M:%fZ', created_at / 1000.0, 'unixepoch') AS timestamp, sender_id, mam_id, mam_by, sync_point FROM messages WHERE account_id=? AND chat_id=?";
		let params = [accountId,chatId];
		if(serverId != null) {
			q += " AND mam_id=?";
			params.push(serverId);
		} else if(localId != null) {
			q += " AND stanza_id=?";
			params.push(localId);
		}
		q += "LIMIT 1";
		let _gthis = this;
		thenshim_Promise.then(thenshim_Promise.then(this.db.exec(q,params),function(result) {
			return _gthis.hydrateMessages(accountId,result);
		}),function(messages) {
			let _g = 0;
			while(_g < messages.length) {
				let message = messages[_g];
				++_g;
				thenshim_Promise.then(thenshim_Promise.then(message.replyToMessage != null ? _gthis.hydrateReplyTo(accountId,[message],[{ chatId : chatId, serverId : message.replyToMessage.serverId, localId : message.replyToMessage.localId}]) : thenshim_Promise.resolve([message]),function(messages) {
					return _gthis.hydrateReactions(accountId,messages);
				}),function(hydrated) {
					callback(hydrated[0]);
				});
				return;
			}
			callback(null);
		});
	}
	getMessages(accountId,chatId,time,op) {
		let q = "SELECT\n\t\t\tcorrection_id AS stanza_id,\n\t\t\tversions.stanza,\n\t\t\tjson_group_object(COALESCE(versions.mam_id, versions.stanza_id), strftime('%FT%H:%M:%fZ', versions.created_at / 1000.0, 'unixepoch')) AS version_times,\n\t\t\tjson_group_object(COALESCE(versions.mam_id, versions.stanza_id), versions.stanza) AS versions,\n\t\t\tmessages.direction,\n\t\t\tmessages.type,\n\t\t\tstrftime('%FT%H:%M:%fZ', messages.created_at / 1000.0, 'unixepoch') AS timestamp,\n\t\t\tmessages.sender_id,\n\t\t\tmessages.mam_id,\n\t\t\tmessages.mam_by,\n\t\t\tmessages.sync_point,\n\t\t\tMAX(versions.created_at)\n\t\t\tFROM messages INNER JOIN messages versions USING (correction_id) WHERE messages.stanza_id=correction_id AND messages.account_id=? AND messages.chat_id=?";
		let params = [accountId,chatId];
		if(time != null) {
			q += " AND messages.created_at " + op + "CAST(unixepoch(?, 'subsec') * 1000 AS INTEGER)";
			params.push(time);
		}
		q += " GROUP BY correction_id ORDER BY messages.created_at";
		if(op == "<" || op == "<=") {
			q += " DESC";
		}
		q += ", messages.ROWID";
		if(op == "<" || op == "<=") {
			q += " DESC";
		}
		q += " LIMIT 50";
		let _gthis = this;
		return thenshim_Promise.then(thenshim_Promise.then(thenshim_Promise.then(this.db.exec(q,params),function(result) {
			return _gthis.hydrateMessages(accountId,result);
		}),function(iter) {
			let arr = [];
			let replyTos = [];
			let _g = 0;
			while(_g < iter.length) {
				let message = iter[_g];
				++_g;
				arr.push(message);
				if(message.replyToMessage != null && message.replyToMessage.serverIdBy == null) {
					replyTos.push({ chatId : message.chatId(), serverId : message.replyToMessage.serverId, localId : message.replyToMessage.localId});
				}
			}
			if(op == "<" || op == "<=") {
				arr.reverse();
			}
			return _gthis.hydrateReplyTo(accountId,arr,replyTos);
		}),function(messages) {
			return _gthis.hydrateReactions(accountId,messages);
		});
	}
	getMessagesBefore(accountId,chatId,beforeId,beforeTime,callback) {
		thenshim_Promise.then(this.getMessages(accountId,chatId,beforeTime,"<"),callback);
	}
	getMessagesAfter(accountId,chatId,afterId,afterTime,callback) {
		thenshim_Promise.then(this.getMessages(accountId,chatId,afterTime,">"),callback);
	}
	getMessagesAround(accountId,chatId,aroundId,aroundTime,callback) {
		let _gthis = this;
		thenshim_Promise.then(thenshim_Promise.then(aroundTime == null ? thenshim_Promise.then(thenshim_Promise._new(function(resolve,reject) {
			_gthis.getMessage(accountId,chatId,aroundId,null,resolve);
		}),function(m) {
			if(m != null) {
				return thenshim_Promise.resolve(m.timestamp);
			} else {
				return thenshim_Promise.then(thenshim_Promise._new(function(resolve,reject) {
					_gthis.getMessage(accountId,chatId,null,aroundId,resolve);
				}),function(m) {
					if(m != null) {
						return m.timestamp;
					} else {
						return null;
					}
				});
			}
		}) : thenshim_Promise.resolve(aroundTime),function(aroundTime) {
			return thenshim_PromiseTools.all([_gthis.getMessages(accountId,chatId,aroundTime,"<"),_gthis.getMessages(accountId,chatId,aroundTime,">=")]);
		}),function(results) {
			let callback1 = callback;
			let _g = [];
			let _g_current = 0;
			let _g_array = results;
			while(_g_current < _g_array.length) {
				let x = _g_array[_g_current++];
				_g.push(x);
			}
			let _g1 = [];
			let e = $getIterator(_g);
			while(e.hasNext()) {
				let e1 = e.next();
				let x = $getIterator(e1);
				while(x.hasNext()) {
					let x1 = x.next();
					_g1.push(x1);
				}
			}
			callback1(_g1);
		});
	}
	getChatsUnreadDetails(accountId,chats,callback) {
		if(chats == null || chats.length < 1) {
			callback([]);
			return;
		}
		let params = [accountId];
		let subq_b = "";
		subq_b += "SELECT chat_id, MAX(created_at) AS created_at FROM messages WHERE account_id=?";
		subq_b += " AND chat_id IN (";
		let _g_current = 0;
		let _g_array = chats;
		while(_g_current < _g_array.length) {
			let _g_value = _g_array[_g_current];
			let _g_key = _g_current++;
			let i = _g_key;
			let chat = _g_value;
			if(i != 0) {
				subq_b += ",";
			}
			subq_b += "?";
			params.push(chat.chatId);
		}
		subq_b += ") AND (mam_id IN (";
		let didOne = false;
		let _g = 0;
		while(_g < chats.length) {
			let chat = chats[_g];
			++_g;
			if(chat.readUpTo() != null) {
				if(didOne) {
					subq_b += ",";
				}
				subq_b += "?";
				params.push(chat.readUpTo());
				didOne = true;
			}
		}
		subq_b += ") OR direction=?) GROUP BY chat_id";
		params.push(1);
		let q_b = "";
		q_b += "SELECT chat_id AS chatId, stanza, direction, type, sender_id, mam_id, mam_by, sync_point, CASE WHEN subq.created_at IS NULL THEN COUNT(*) ELSE COUNT(*) - 1 END AS unreadCount, strftime('%FT%H:%M:%fZ', MAX(messages.created_at) / 1000.0, 'unixepoch') AS timestamp FROM messages LEFT JOIN (";
		q_b += Std.string(subq_b);
		q_b += ") subq USING (chat_id) WHERE account_id=? AND chat_id IN (";
		params.push(accountId);
		let _g_current1 = 0;
		let _g_array1 = chats;
		while(_g_current1 < _g_array1.length) {
			let _g_value = _g_array1[_g_current1];
			let _g_key = _g_current1++;
			let i = _g_key;
			let chat = _g_value;
			if(i != 0) {
				q_b += ",";
			}
			q_b += "?";
			params.push(chat.chatId);
		}
		q_b += ") AND (subq.created_at IS NULL OR messages.created_at >= subq.created_at) GROUP BY chat_id;";
		let _gthis = this;
		thenshim_Promise.then(this.db.exec(q_b,params),function(result) {
			let details = [];
			let rows = Lambda.array({ iterator : function() {
				return result;
			}});
			return thenshim_Promise.then(thenshim_Promise.resolve(_gthis.hydrateMessages(accountId,new haxe_iterators_ArrayIterator(rows))),function(messages) {
				let _g_current = 0;
				let _g_array = messages;
				while(_g_current < _g_array.length) {
					let _g_value = _g_array[_g_current];
					let _g_key = _g_current++;
					let i = _g_key;
					let m = _g_value;
					details.push({ unreadCount : rows[i].unreadCount, chatId : rows[i].chatId, message : m});
				}
				callback(details);
			});
		});
	}
	storeReaction(accountId,update,callback) {
		let _gthis = this;
		thenshim_Promise.then(this.db.exec("INSERT OR REPLACE INTO reactions VALUES (?,?,?,?,?,?,?,CAST(unixepoch(?, 'subsec') * 1000 AS INTEGER),jsonb(?),?)",[accountId,update.updateId,update.serverId,update.serverIdBy,update.localId,update.chatId,update.senderId,update.timestamp,JSON.stringify(update.reactions),update.kind]),function(_) {
			_gthis.getMessage(accountId,update.chatId,update.serverId,update.localId,callback);
		});
	}
	updateMessageStatus(accountId,localId,status,callback) {
		let _gthis = this;
		thenshim_Promise.then(thenshim_Promise.then(thenshim_Promise.then(this.db.exec("UPDATE messages SET status=? WHERE account_id=? AND stanza_id=? AND direction=? AND status <> ?",[status,accountId,localId,1,2]),function(_) {
			return _gthis.db.exec("SELECT stanza, direction, type, strftime('%FT%H:%M:%fZ', created_at / 1000.0, 'unixepoch') AS timestamp, sender_id, mam_id, mam_by, sync_point FROM messages WHERE account_id=? AND stanza_id=? AND direction=?",[accountId,localId,1]);
		}),function(result) {
			return _gthis.hydrateMessages(accountId,result);
		}),function(messages) {
			let _g = 0;
			while(_g < messages.length) {
				let message = messages[_g];
				++_g;
				thenshim_Promise.then(thenshim_Promise.then(message.replyToMessage != null ? _gthis.hydrateReplyTo(accountId,[message],[{ chatId : message.chatId(), serverId : message.replyToMessage.serverId, localId : message.replyToMessage.localId}]) : thenshim_Promise.resolve([message]),function(messages) {
					return _gthis.hydrateReactions(accountId,messages);
				}),function(hydrated) {
					callback(hydrated[0]);
				});
				return;
			}
		});
	}
	hasMedia(hashAlgorithm,hash,callback) {
		this.media.hasMedia(hashAlgorithm,hash,callback);
	}
	removeMedia(hashAlgorithm,hash) {
		this.media.removeMedia(hashAlgorithm,hash);
	}
	storeMedia(mime,bd,callback) {
		this.media.storeMedia(mime,bd,callback);
	}
	storeCaps(caps) {
		this.db.exec("INSERT OR IGNORE INTO caps VALUES (?,jsonb(?))",[caps.verRaw().hash,JSON.stringify({ node : caps.node, identities : caps.identities, features : caps.features})]);
	}
	getCaps(ver,callback) {
		let verData;
		try {
			verData = haxe_crypto_Base64.decode(ver).b.bufferValue;
		} catch( _g ) {
			callback(null);
			return;
		}
		thenshim_Promise.then(this.db.exec("SELECT json(caps) AS caps FROM caps WHERE sha1=? LIMIT 1",[verData]),function(result) {
			let _g = result;
			while(_g.current < _g.array.length) {
				let row = _g.array[_g.current++];
				let json = JSON.parse(row.caps);
				callback(new snikket_Caps(json.node,json.identities.map(function(i) {
					return new snikket_Identity(i.category,i.type,i.name);
				}),json.features));
				return;
			}
			callback(null);
		});
	}
	storeLogin(accountId,clientId,displayName,token) {
		let params = [accountId,clientId,displayName];
		let q_b = "";
		q_b += "INSERT INTO accounts (account_id, client_id, display_name";
		if(token != null) {
			q_b += ", token, fast_count";
		}
		q_b += ") VALUES (?,?,?";
		if(token != null) {
			q_b += ",?";
			params.push(token);
			q_b += ",0";
		}
		q_b += ") ON CONFLICT DO UPDATE SET client_id=?";
		params.push(clientId);
		q_b += ", display_name=?";
		params.push(displayName);
		if(token != null) {
			q_b += ", token=?";
			params.push(token);
			q_b += ", fast_count=0";
		}
		this.db.exec(q_b,params);
	}
	getLogin(accountId,callback) {
		let _gthis = this;
		thenshim_Promise.then(this.db.exec("SELECT client_id, display_name, token, fast_count FROM accounts WHERE account_id=? LIMIT 1",[accountId]),function(result) {
			let _g = result;
			while(_g.current < _g.array.length) {
				let row = _g.array[_g.current++];
				if(row.token != null) {
					_gthis.db.exec("UPDATE accounts SET fast_count=fast_count+1 WHERE account_id=?",[accountId]);
				}
				let tmp = row.fast_count;
				callback(row.client_id,row.token,tmp != null ? tmp : 0,row.display_name);
				return;
			}
			callback(null,null,0,null);
		});
	}
	removeAccount(accountId,completely) {
		this.db.exec("DELETE FROM accounts WHERE account_id=?",[accountId]);
		if(!completely) {
			return;
		}
		this.db.exec("DELETE FROM messages WHERE account_id=?",[accountId]);
		this.db.exec("DELETE FROM chats WHERE account_id=?",[accountId]);
		this.db.exec("DELETE FROM services WHERE account_id=?",[accountId]);
	}
	storeStreamManagement(accountId,sm) {
		this.smStoreNext = sm;
		let _gthis = this;
		if(!this.smStoreInProgress) {
			this.smStoreInProgress = true;
			thenshim_Promise.then(this.db.exec("UPDATE accounts SET sm_state=? WHERE account_id=?",[sm,accountId]),function(_) {
				_gthis.smStoreInProgress = false;
				if(_gthis.smStoreNext != sm) {
					_gthis.storeStreamManagement(accountId,sm);
				}
			});
		}
	}
	getStreamManagement(accountId,callback) {
		thenshim_Promise.then(this.db.exec("SELECT sm_state FROM accounts  WHERE account_id=?",[accountId]),function(result) {
			let _g = result;
			while(_g.current < _g.array.length) {
				let row = _g.array[_g.current++];
				callback(row.sm_state);
				return;
			}
			callback(null);
		});
	}
	storeService(accountId,serviceId,name,node,caps) {
		this.storeCaps(caps);
		this.db.exec("INSERT OR REPLACE INTO services VALUES (?,?,?,?,?)",[accountId,serviceId,name,node,caps.verRaw().hash]);
	}
	findServicesWithFeature(accountId,feature,callback) {
		thenshim_Promise.then(this.db.exec("SELECT service_id, name, node, json(caps.caps) AS caps FROM services INNER JOIN caps ON services.caps=caps.sha1 WHERE account_id=?",[accountId]),function(result) {
			let services = [];
			let _g = result;
			while(_g.current < _g.array.length) {
				let row = _g.array[_g.current++];
				let json = JSON.parse(row.caps);
				let features = json.features;
				if(features.contains(feature)) {
					let json1 = json.node;
					let tmp = json.identities.map(function(i) {
						return new snikket_Identity(i.category,i.type,i.name);
					});
					let tmp1 = features.array();
					row.set("caps",new snikket_Caps(json1,tmp,tmp1));
					services.push(row);
				}
			}
			callback(services);
		});
	}
	hydrateReactions(accountId,messages) {
		let result = new Array(messages.length);
		let _g = 0;
		let _g1 = messages.length;
		while(_g < _g1) {
			let i = _g++;
			let m = messages[i];
			result[i] = { chatId : m.chatId(), serverId : m.serverId, serverIdBy : m.serverIdBy, localId : m.localId};
		}
		return thenshim_Promise.then(this.fetchReactions(accountId,result),function(result) {
			let jsIterator = result.entries();
			let _g_jsIterator = jsIterator;
			let _g_lastStep = jsIterator.next();
			while(!_g_lastStep.done) {
				let v = _g_lastStep.value;
				_g_lastStep = _g_jsIterator.next();
				let _g_key = v[0];
				let _g_value = v[1];
				let id = _g_key;
				let reactions = _g_value;
				let m = Lambda.find(messages,function(m) {
					return (m.serverId == null ? m.localId : m.serverId + "\n" + m.serverIdBy) + "\n" + m.chatId() == id;
				});
				if(m != null) {
					m.set_reactions(reactions);
				}
			}
			return messages;
		});
	}
	fetchReactions(accountId,ids) {
		let q_b = "";
		q_b += "SELECT kind, chat_id, mam_id, mam_by, stanza_id, sender_id, json(reactions) AS reactions FROM reactions WHERE 1=0";
		let params = [];
		let _g = 0;
		while(_g < ids.length) {
			let item = ids[_g];
			++_g;
			if(item.serverId != null) {
				q_b += " OR (mam_id=? AND mam_by=?)";
				params.push(item.serverId);
				params.push(item.serverIdBy);
			} else {
				q_b += " OR stanza_id=?";
				params.push(item.localId);
			}
		}
		q_b += " ORDER BY created_at, ROWID";
		return thenshim_Promise.then(this.db.exec(q_b,params),function(rows) {
			let agg = new Map([]);
			let _g = rows;
			while(_g.current < _g.array.length) {
				let row = _g.array[_g.current++];
				let reactions = JSON.parse(row.reactions);
				let mapId = (row.mam_id == null ? row.stanza_id : row.mam_id + "\n" + row.mam_by) + "\n" + row.chat_id;
				if(!agg.has(mapId)) {
					agg.set(mapId,new Map([]));
				}
				let map = agg.get(mapId);
				if(!map.has(row.sender_id)) {
					let v = [];
					map.set(row.sender_id,v);
				}
				if(row.kind == 1) {
					let _g = 0;
					while(_g < reactions.length) {
						let reaction = reactions[_g];
						++_g;
						map.get(row.sender_id).push(reaction);
					}
				} else if(row.kind == 0) {
					let k = row.sender_id;
					let _g = [];
					let _g1 = 0;
					let _g2 = map.get(row.sender_id);
					while(_g1 < _g2.length) {
						let v = _g2[_g1];
						++_g1;
						if(v.uri != null) {
							_g.push(v);
						}
					}
					let v = reactions.concat(_g);
					map.set(k,v);
				} else if(row.kind == 2) {
					map.set(row.sender_id,reactions);
				}
			}
			let result = new Map([]);
			let jsIterator = agg.entries();
			let _g_jsIterator = jsIterator;
			let _g_lastStep = jsIterator.next();
			while(!_g_lastStep.done) {
				let v = _g_lastStep.value;
				_g_lastStep = _g_jsIterator.next();
				let _g_key = v[0];
				let _g_value = v[1];
				let id = _g_key;
				let reactions = _g_value;
				let map = new Map([]);
				let jsIterator = reactions.values();
				let _g_jsIterator1 = jsIterator;
				let _g_lastStep1 = jsIterator.next();
				while(!_g_lastStep1.done) {
					let v = _g_lastStep1.value;
					_g_lastStep1 = _g_jsIterator1.next();
					let reactionsBySender = v;
					let _g = 0;
					while(_g < reactionsBySender.length) {
						let reactionD = reactionsBySender[_g];
						++_g;
						let reaction = reactionD.uri == null ? new snikket_Reaction(reactionD.senderId,reactionD.timestamp,reactionD.text,reactionD.envelopeId,reactionD.key) : new snikket_CustomEmojiReaction(reactionD.senderId,reactionD.timestamp,reactionD.text,reactionD.uri,reactionD.envelopeId);
						if(!map.has(reaction.key)) {
							let v = [];
							map.set(reaction.key,v);
						}
						map.get(reaction.key).push(reaction);
					}
				}
				result.set(id,map);
			}
			return result;
		});
	}
	hydrateReplyTo(accountId,messages,replyTos) {
		let _gthis = this;
		let tmp;
		if(replyTos.length < 1) {
			tmp = thenshim_Promise.resolve(null);
		} else {
			let params = [accountId];
			let q_b = "";
			q_b += "SELECT chat_id, stanza_id, stanza, direction, type, strftime('%FT%H:%M:%fZ', created_at / 1000.0, 'unixepoch') AS timestamp, sender_id, mam_id, mam_by, sync_point FROM messages WHERE account_id=? AND (";
			let result = new Array(replyTos.length);
			let _g = 0;
			let _g1 = replyTos.length;
			while(_g < _g1) {
				let i = _g++;
				let parent = replyTos[i];
				let x;
				if(parent.serverId != null) {
					params.push(parent.chatId);
					params.push(parent.serverId);
					x = " (chat_id=? AND mam_id=?)";
				} else {
					params.push(parent.chatId);
					params.push(parent.localId);
					x = " (chat_id=? AND stanza_id=?)";
				}
				result[i] = x;
			}
			q_b += Std.string(result.join(" OR "));
			q_b += ")";
			tmp = this.db.exec(q_b,params);
		}
		return thenshim_Promise.then(tmp,function(iter) {
			if(iter != null) {
				let parents = Lambda.array({ iterator : function() {
					return iter;
				}});
				let _g = 0;
				while(_g < messages.length) {
					let message = messages[_g];
					++_g;
					if(message.replyToMessage != null) {
						let found = Lambda.find(parents,function(p) {
							if(p.chat_id == message.chatId() && (message.replyToMessage.serverId == null || p.mam_id == message.replyToMessage.serverId)) {
								if(message.replyToMessage.localId != null) {
									return p.stanza_id == message.replyToMessage.localId;
								} else {
									return true;
								}
							} else {
								return false;
							}
						});
						if(found != null) {
							message.set_replyToMessage(_gthis.hydrateMessages(accountId,new haxe_iterators_ArrayIterator([found]))[0]);
						}
					}
				}
			}
			return messages;
		});
	}
	hydrateMessages(accountId,rows) {
		let accountJid = snikket_JID.parse(accountId);
		let _g = [];
		let inlobj_iterator = function() {
			return rows;
		};
		let x = inlobj_iterator();
		while(x.hasNext()) {
			let x1 = x.next();
			let row = x1;
			_g.push(snikket_ChatMessage.fromStanza(snikket_Stanza.parse(row.stanza),accountJid,function(builder,_) {
				builder.syncPoint = row.sync_point;
				builder.timestamp = row.timestamp;
				builder.direction = row.direction;
				builder.type = row.type;
				builder.senderId = row.sender_id;
				builder.serverId = row.mam_id;
				builder.serverIdBy = row.mam_by;
				if(row.stanza_id != null) {
					builder.localId = row.stanza_id;
				}
				if(row.versions != null) {
					let versionTimes = JSON.parse(row.version_times);
					let versions = JSON.parse(row.versions);
					if(Reflect.fields(versions).length > 1) {
						let access = versions;
						let _g_access = access;
						let _g_keys = Reflect.fields(access);
						let _g_index = 0;
						while(_g_index < _g_keys.length) {
							let version = _g_access[_g_keys[_g_index++]];
							let versionM = snikket_ChatMessage.fromStanza(snikket_Stanza.parse(version),accountJid,function(toPushB,_) {
								let tmp = toPushB.serverId;
								toPushB.timestamp = versionTimes[tmp != null ? tmp : toPushB.localId];
								return toPushB;
							});
							let toPush = versionM == null || versionM.versions.length < 1 ? versionM : versionM.versions[0];
							if(toPush != null) {
								builder.versions.push(toPush);
							}
						}
						builder.versions.sort(function(a,b) {
							return Reflect.compare(b.timestamp,a.timestamp);
						});
					}
				}
				return builder;
			}));
		}
		return _g;
	}
}
$hx_exports["snikket"]["persistence"]["Sqlite"] = snikket_persistence_Sqlite;
snikket_persistence_Sqlite.__name__ = "snikket.persistence.Sqlite";
snikket_persistence_Sqlite.__interfaces__ = [snikket_persistence_KeyValueStore,snikket_Persistence];
Object.assign(snikket_persistence_Sqlite.prototype, {
	__class__: snikket_persistence_Sqlite
});
class snikket_persistence_SqliteDriver {
	constructor(dbfile) {
		let _gthis = this;
		thenshim_Promise.then(thenshim_Promise.then(snikket_persistence_Worker1.v2({ worker : function() {
			return new Worker(new URL("sqlite-worker1.mjs",import.meta.url),{ type : "module"});
		}}),function(promiser) {
			_gthis.sqlite = promiser;
			return _gthis.sqlite("open",{ filename : dbfile, vfs : "opfs-sahpool"});
		}),function(openResult) {
			return _gthis.dbId = openResult.dbId;
		});
	}
	exec(sql,params) {
		let _gthis = this;
		if(this.sqlite == null || this.dbId == null) {
			return thenshim_Promise.then(thenshim_Promise._new(function(resolve,reject) {
				haxe_Timer.delay(function() {
					resolve(null);
				},100);
			}),function(_) {
				return _gthis.exec(sql,params);
			});
		}
		let items = [];
		let signalAllDone;
		let allDone = thenshim_Promise._new(function(resolve,reject) {
			signalAllDone = resolve;
		});
		return thenshim_Promise.then(thenshim_Promise.then(this.sqlite("exec",{ dbId : this.dbId, sql : sql, bind : params, rowMode : "object", callback : function(r) {
			if(r.rowNumber == null) {
				signalAllDone(null);
			} else {
				items.push(r.row);
			}
			return null;
		}}),function(_) {
			return allDone;
		}),function(_) {
			return new haxe_iterators_ArrayIterator(items);
		});
	}
}
snikket_persistence_SqliteDriver.__name__ = "snikket.persistence.SqliteDriver";
Object.assign(snikket_persistence_SqliteDriver.prototype, {
	__class__: snikket_persistence_SqliteDriver
});
class snikket_queries_GenericQuery {
	constructor() {
		if(snikket_queries_GenericQuery._hx_skip_constructor) {
			return;
		}
		this._hx_constructor();
	}
	_hx_constructor() {
		this.isFinished = false;
	}
	getQueryStanza() {
		if(this.queryStanza == null) {
			throw new haxe_Exception("Query has not been initialized");
		}
		return this.queryStanza;
	}
	finish() {
		this.isFinished = true;
		if(this.handleFinished != null) {
			this.handleFinished();
		}
	}
	onFinished(handler) {
		this.handleFinished = handler;
		if(this.isFinished) {
			this.handleFinished();
		}
	}
}
snikket_queries_GenericQuery.__name__ = "snikket.queries.GenericQuery";
Object.assign(snikket_queries_GenericQuery.prototype, {
	__class__: snikket_queries_GenericQuery
});
class snikket_queries_BlocklistGet extends snikket_queries_GenericQuery {
	constructor() {
		snikket_queries_GenericQuery._hx_skip_constructor = true;
		super();
		snikket_queries_GenericQuery._hx_skip_constructor = false;
		this._hx_constructor();
	}
	_hx_constructor() {
		this.ver = null;
		this.queryId = null;
		this.xmlns = "urn:xmpp:blocking";
		super._hx_constructor();
		this.queryId = snikket_ID.short();
		this.queryStanza = new snikket_Stanza("iq",{ type : "get", id : this.queryId}).tag("blocklist",{ xmlns : this.xmlns}).up();
	}
	handleResponse(stanza) {
		this.responseStanza = stanza;
		this.finish();
	}
	getResult() {
		if(this.responseStanza == null) {
			return [];
		}
		if(this.result == null) {
			let q = this.responseStanza.getChild("blocklist",this.xmlns);
			if(q == null) {
				return [];
			}
			let _this = q.allTags("item");
			let result = new Array(_this.length);
			let _g = 0;
			let _g1 = _this.length;
			while(_g < _g1) {
				let i = _g++;
				result[i] = _this[i].attr["jid"];
			}
			this.result = result;
		}
		return this.result;
	}
}
snikket_queries_BlocklistGet.__name__ = "snikket.queries.BlocklistGet";
snikket_queries_BlocklistGet.__super__ = snikket_queries_GenericQuery;
Object.assign(snikket_queries_BlocklistGet.prototype, {
	__class__: snikket_queries_BlocklistGet
});
class snikket_queries_BoB extends snikket_queries_GenericQuery {
	constructor(to,uri) {
		snikket_queries_GenericQuery._hx_skip_constructor = true;
		super();
		snikket_queries_GenericQuery._hx_skip_constructor = false;
		this._hx_constructor(to,uri);
	}
	_hx_constructor(to,uri) {
		this.xmlns = "urn:xmpp:bob";
		super._hx_constructor();
		if(!uri.startsWith("cid:") || !uri.endsWith("@bob.xmpp.org") || !uri.includes("+")) {
			throw haxe_Exception.thrown("invalid BoB URI");
		}
		this.queryId = snikket_ID.short();
		let tmp = HxOverrides.substr(uri,4,null);
		this.queryStanza = new snikket_Stanza("iq",{ to : to, type : "get", id : this.queryId}).tag("data",{ xmlns : this.xmlns, cid : tmp}).up();
	}
	handleResponse(stanza) {
		this.responseStanza = stanza;
		this.finish();
	}
	getResult() {
		if(this.responseStanza == null) {
			return null;
		}
		if(this.result == null) {
			let data = this.responseStanza.getChild("data",this.xmlns);
			if(data == null) {
				return null;
			}
			let maxAge = data.attr["max-age"];
			this.result = { bytes : haxe_crypto_Base64.decode(StringTools.replace(data.getText(),"\n","")), type : data.attr["type"], maxAge : maxAge == null ? null : Std.parseInt(maxAge)};
		}
		return this.result;
	}
	static uri(hash) {
		let algo = hash.algorithm == "sha-1" ? "sha1" : hash.algorithm;
		return "cid:" + encodeURIComponent(algo) + "+" + hash.toHex() + "@bob.xmpp.org";
	}
	static forHash(to,hash) {
		let algo = hash.algorithm == "sha-1" ? "sha1" : hash.algorithm;
		return new snikket_queries_BoB(to,"cid:" + encodeURIComponent(algo) + "+" + hash.toHex() + "@bob.xmpp.org");
	}
}
snikket_queries_BoB.__name__ = "snikket.queries.BoB";
snikket_queries_BoB.__super__ = snikket_queries_GenericQuery;
Object.assign(snikket_queries_BoB.prototype, {
	__class__: snikket_queries_BoB
});
class snikket_queries_DiscoInfoGet extends snikket_queries_GenericQuery {
	constructor(to,node) {
		snikket_queries_GenericQuery._hx_skip_constructor = true;
		super();
		snikket_queries_GenericQuery._hx_skip_constructor = false;
		this._hx_constructor(to,node);
	}
	_hx_constructor(to,node) {
		this.ver = null;
		this.queryId = null;
		this.xmlns = "http://jabber.org/protocol/disco#info";
		super._hx_constructor();
		let attr = { xmlns : this.xmlns};
		if(node != null) {
			attr["node"] = node;
		}
		this.queryId = snikket_ID.short();
		this.queryStanza = new snikket_Stanza("iq",{ to : to, type : "get", id : this.queryId}).tag("query",attr).up();
	}
	handleResponse(stanza) {
		this.responseStanza = stanza;
		this.finish();
	}
	getResult() {
		if(this.responseStanza == null) {
			return null;
		}
		if(this.result == null) {
			let q = this.responseStanza.getChild("query",this.xmlns);
			if(q == null) {
				return null;
			}
			let identities = q.allTags("identity");
			let features = q.allTags("feature");
			let q1 = q.attr["node"];
			let result = new Array(identities.length);
			let _g = 0;
			let _g1 = identities.length;
			while(_g < _g1) {
				let i = _g++;
				let identity = identities[i];
				result[i] = new snikket_Identity(identity.attr["category"],identity.attr["type"],identity.attr["name"]);
			}
			let tmp = result;
			let result1 = new Array(features.length);
			let _g2 = 0;
			let _g3 = features.length;
			while(_g2 < _g3) {
				let i = _g2++;
				result1[i] = features[i].attr["var"];
			}
			this.result = new snikket_Caps(q1,tmp,result1);
		}
		return this.result;
	}
}
snikket_queries_DiscoInfoGet.__name__ = "snikket.queries.DiscoInfoGet";
snikket_queries_DiscoInfoGet.__super__ = snikket_queries_GenericQuery;
Object.assign(snikket_queries_DiscoInfoGet.prototype, {
	__class__: snikket_queries_DiscoInfoGet
});
class snikket_queries_DiscoItemsGet extends snikket_queries_GenericQuery {
	constructor(to,node) {
		snikket_queries_GenericQuery._hx_skip_constructor = true;
		super();
		snikket_queries_GenericQuery._hx_skip_constructor = false;
		this._hx_constructor(to,node);
	}
	_hx_constructor(to,node) {
		this.queryId = null;
		this.xmlns = "http://jabber.org/protocol/disco#items";
		super._hx_constructor();
		let attr = { xmlns : this.xmlns};
		if(node != null) {
			attr["node"] = node;
		}
		this.queryId = snikket_ID.short();
		this.queryStanza = new snikket_Stanza("iq",{ to : to, type : "get", id : this.queryId}).tag("query",attr).up();
	}
	handleResponse(stanza) {
		this.responseStanza = stanza;
		this.finish();
	}
	getResult() {
		if(this.responseStanza == null) {
			return null;
		}
		if(this.result == null) {
			let q = this.responseStanza.getChild("query",this.xmlns);
			if(q == null) {
				return null;
			}
			this.result = [];
			let _g = 0;
			let _g1 = q.allTags("item");
			while(_g < _g1.length) {
				let item = _g1[_g];
				++_g;
				let jid = item.attr["jid"];
				if(jid != null) {
					this.result.push({ jid : snikket_JID.parse(jid), name : item.attr["name"], node : item.attr["node"]});
				}
			}
		}
		return this.result;
	}
}
snikket_queries_DiscoItemsGet.__name__ = "snikket.queries.DiscoItemsGet";
snikket_queries_DiscoItemsGet.__super__ = snikket_queries_GenericQuery;
Object.assign(snikket_queries_DiscoItemsGet.prototype, {
	__class__: snikket_queries_DiscoItemsGet
});
class snikket_queries_ExtDiscoGet extends snikket_queries_GenericQuery {
	constructor(to) {
		snikket_queries_GenericQuery._hx_skip_constructor = true;
		super();
		snikket_queries_GenericQuery._hx_skip_constructor = false;
		this._hx_constructor(to);
	}
	_hx_constructor(to) {
		this.ver = null;
		this.queryId = null;
		this.xmlns = "urn:xmpp:extdisco:2";
		super._hx_constructor();
		this.queryId = snikket_ID.short();
		this.queryStanza = new snikket_Stanza("iq",{ to : to, type : "get", id : this.queryId}).tag("services",{ xmlns : this.xmlns}).up();
	}
	handleResponse(stanza) {
		this.responseStanza = stanza;
		this.finish();
	}
	getResult() {
		if(this.responseStanza == null) {
			return null;
		}
		if(this.result == null) {
			let q = this.responseStanza.getChild("services",this.xmlns);
			if(q == null) {
				return null;
			}
			this.result = q.allTags("service");
		}
		return this.result;
	}
}
snikket_queries_ExtDiscoGet.__name__ = "snikket.queries.ExtDiscoGet";
snikket_queries_ExtDiscoGet.__super__ = snikket_queries_GenericQuery;
Object.assign(snikket_queries_ExtDiscoGet.prototype, {
	__class__: snikket_queries_ExtDiscoGet
});
class snikket_queries_HttpUploadSlot extends snikket_queries_GenericQuery {
	constructor(to,filename,size,mime,hashes) {
		snikket_queries_GenericQuery._hx_skip_constructor = true;
		super();
		snikket_queries_GenericQuery._hx_skip_constructor = false;
		this._hx_constructor(to,filename,size,mime,hashes);
	}
	_hx_constructor(to,filename,size,mime,hashes) {
		this.queryId = null;
		this.xmlns = "urn:xmpp:http:upload:0";
		super._hx_constructor();
		this.queryId = snikket_ID.short();
		this.queryStanza = new snikket_Stanza("iq",{ to : to, type : "get", id : this.queryId}).tag("request",{ xmlns : this.xmlns, filename : filename, size : size == null ? "null" : "" + size, "content-type" : mime});
		let _g = 0;
		while(_g < hashes.length) {
			let hash = hashes[_g];
			++_g;
			this.queryStanza.textTag("hash",haxe_crypto_Base64.encode(haxe_io_Bytes.ofData(hash.hash)),{ xmlns : "urn:xmpp:hashes:2", algo : hash.algorithm});
		}
		this.queryStanza.up();
	}
	handleResponse(stanza) {
		this.responseStanza = stanza;
		this.finish();
	}
	getResult() {
		if(this.responseStanza == null) {
			return null;
		}
		if(this.result == null) {
			let q = this.responseStanza.getChild("slot",this.xmlns);
			if(q == null) {
				return null;
			}
			let get = q.findText("get@url");
			if(get == null) {
				return null;
			}
			let put = q.findText("put@url");
			if(put == null) {
				return null;
			}
			let headers = [];
			let _g = 0;
			let _g1 = q.getChild("put").allTags("header");
			while(_g < _g1.length) {
				let header = _g1[_g];
				++_g;
				headers.push(new tink_http_HeaderField(header.attr["name"].toLowerCase(),header.getText()));
			}
			this.result = { get : get, put : put, putHeaders : headers};
		}
		return this.result;
	}
}
snikket_queries_HttpUploadSlot.__name__ = "snikket.queries.HttpUploadSlot";
snikket_queries_HttpUploadSlot.__super__ = snikket_queries_GenericQuery;
Object.assign(snikket_queries_HttpUploadSlot.prototype, {
	__class__: snikket_queries_HttpUploadSlot
});
class snikket_queries_JabberIqGatewayGet extends snikket_queries_GenericQuery {
	constructor(to,prompt) {
		snikket_queries_GenericQuery._hx_skip_constructor = true;
		super();
		snikket_queries_GenericQuery._hx_skip_constructor = false;
		this._hx_constructor(to,prompt);
	}
	_hx_constructor(to,prompt) {
		this.ver = null;
		this.queryId = null;
		this.xmlns = "jabber:iq:gateway";
		super._hx_constructor();
		this.queryId = snikket_ID.short();
		this.queryStanza = new snikket_Stanza("iq",{ to : to, type : prompt == null ? "get" : "set", id : this.queryId});
		let query = this.queryStanza.tag("query",{ xmlns : this.xmlns});
		if(prompt != null) {
			query.textTag("prompt",prompt,{ });
		}
		query.up();
	}
	handleResponse(stanza) {
		this.responseStanza = stanza;
		this.finish();
	}
	getResult() {
		if(this.responseStanza == null) {
			return null;
		}
		if(this.result == null) {
			let error = this.responseStanza.getChild("error");
			if(error == null) {
				let q = this.responseStanza.getChild("query",this.xmlns);
				if(q == null) {
					return null;
				}
				let prompt = q.getChild("prompt");
				if(prompt == null) {
					let jid = q.getChild("jid");
					if(jid == null) {
						return null;
					}
					this.result = haxe_ds_Either.Right(jid.getText());
				} else {
					this.result = haxe_ds_Either.Right(prompt.getText());
				}
			} else {
				if(error.getChild("service-unavailable","urn:ietf:params:xml:ns:xmpp-stanzas") != null) {
					return null;
				}
				if(error.getChild("feature-not-implemented","urn:ietf:params:xml:ns:xmpp-stanzas") != null) {
					return null;
				}
				this.result = haxe_ds_Either.Left(error.getText());
			}
		}
		return this.result;
	}
}
snikket_queries_JabberIqGatewayGet.__name__ = "snikket.queries.JabberIqGatewayGet";
snikket_queries_JabberIqGatewayGet.__super__ = snikket_queries_GenericQuery;
Object.assign(snikket_queries_JabberIqGatewayGet.prototype, {
	__class__: snikket_queries_JabberIqGatewayGet
});
class snikket_queries_MAMQuery extends snikket_queries_GenericQuery {
	constructor(params,jid) {
		snikket_queries_GenericQuery._hx_skip_constructor = true;
		super();
		snikket_queries_GenericQuery._hx_skip_constructor = false;
		this._hx_constructor(params,jid);
	}
	_hx_constructor(params,jid) {
		this.queryId = null;
		this.xmlns = "urn:xmpp:mam:2";
		super._hx_constructor();
		this.queryId = snikket_ID.short();
		this.queryStanza = new snikket_Stanza("iq",{ type : "set", to : jid}).tag("query",{ xmlns : this.xmlns, queryid : this.queryId}).tag("x",{ xmlns : "jabber:x:data", type : "submit"}).tag("field",{ "var" : "FORM_TYPE", type : "hidden"}).textTag("value",this.xmlns).up();
		this.addStringField("start",params.startTime);
		this.addStringField("end",params.endTime);
		this.addStringField("with",params.with);
		this.addStringField("before-id",params.beforeId);
		this.addStringField("after-id",params.afterId);
		this.addArrayField("ids",params.ids);
		this.queryStanza.up();
		if(params.page != null) {
			let page = params.page;
			this.queryStanza.tag("set",{ xmlns : "http://jabber.org/protocol/rsm"});
			if(page.limit != null) {
				this.queryStanza.textTag("max",page.limit == null ? "null" : "" + page.limit);
			}
			if(page.before != null && page.after != null) {
				throw new haxe_Exception("It is not allowed to request a page before AND a page after");
			}
			if(page.before != null) {
				this.queryStanza.textTag("before",page.before);
			} else if(page.after != null) {
				this.queryStanza.textTag("after",page.after);
			}
			this.queryStanza.up();
		}
	}
	addStringField(name,value) {
		if(value == null) {
			return;
		}
		this.queryStanza.tag("field",{ "var" : name}).textTag("value",value).up();
	}
	addArrayField(name,values) {
		if(values == null) {
			return;
		}
		this.queryStanza.tag("field",{ "var" : name});
		let _g = 0;
		while(_g < values.length) {
			let value = values[_g];
			++_g;
			this.queryStanza.textTag("value",value);
		}
		this.queryStanza.up();
	}
	handleResponse(stanza) {
		this.responseStanza = stanza;
		this.finish();
	}
	getResult() {
		if(this.responseStanza == null) {
			return null;
		}
		if(this.result == null) {
			let fin = this.responseStanza.getFirstChild();
			if(fin == null || fin.name != "fin" || fin.attr["xmlns"] != this.xmlns) {
				return null;
			}
			let rsmInfo = fin.getChild("set","http://jabber.org/protocol/rsm");
			let count = rsmInfo.getChildText("count");
			this.result = { complete : fin.attr["complete"] == "true" || fin.attr["complete"] == "1", page : { first : rsmInfo.getChildText("first"), last : rsmInfo.getChildText("last"), count : count == null ? null : Std.parseInt(count)}};
		}
		return this.result;
	}
}
snikket_queries_MAMQuery.__name__ = "snikket.queries.MAMQuery";
snikket_queries_MAMQuery.__super__ = snikket_queries_GenericQuery;
Object.assign(snikket_queries_MAMQuery.prototype, {
	__class__: snikket_queries_MAMQuery
});
class snikket_queries_PubsubGet extends snikket_queries_GenericQuery {
	constructor(to,node,itemId) {
		snikket_queries_GenericQuery._hx_skip_constructor = true;
		super();
		snikket_queries_GenericQuery._hx_skip_constructor = false;
		this._hx_constructor(to,node,itemId);
	}
	_hx_constructor(to,node,itemId) {
		this.ver = null;
		this.queryId = null;
		this.xmlns = "http://jabber.org/protocol/pubsub";
		super._hx_constructor();
		let attr = { node : node};
		if(this.ver != null) {
			attr["ver"] = this.ver;
		}
		this.queryId = snikket_ID.short();
		this.queryStanza = new snikket_Stanza("iq",{ to : to, type : "get", id : this.queryId});
		let items = this.queryStanza.tag("pubsub",{ xmlns : this.xmlns}).tag("items",{ node : node});
		if(itemId != null) {
			items.tag("item",{ id : itemId}).up();
		}
		this.queryStanza.up().up();
	}
	handleResponse(stanza) {
		this.responseStanza = stanza;
		this.finish();
	}
	getResult() {
		if(this.responseStanza == null) {
			return [];
		}
		if(this.result == null) {
			let q = this.responseStanza.getChild("pubsub",this.xmlns);
			if(q == null) {
				return [];
			}
			let items = q.getChild("items");
			if(items == null) {
				return [];
			}
			if(items.attr["xmlns"] == null) {
				items.attr["xmlns"] = this.xmlns;
			}
			this.result = items.allTags("item");
		}
		return this.result;
	}
}
snikket_queries_PubsubGet.__name__ = "snikket.queries.PubsubGet";
snikket_queries_PubsubGet.__super__ = snikket_queries_GenericQuery;
Object.assign(snikket_queries_PubsubGet.prototype, {
	__class__: snikket_queries_PubsubGet
});
class snikket_queries_Push2Disable extends snikket_queries_GenericQuery {
	constructor(to) {
		snikket_queries_GenericQuery._hx_skip_constructor = true;
		super();
		snikket_queries_GenericQuery._hx_skip_constructor = false;
		this._hx_constructor(to);
	}
	_hx_constructor(to) {
		this.ver = null;
		this.queryId = null;
		this.xmlns = "urn:xmpp:push2:0";
		super._hx_constructor();
		this.queryId = snikket_ID.short();
		this.queryStanza = new snikket_Stanza("iq",{ to : to, type : "set", id : this.queryId});
		this.queryStanza.tag("disable",{ xmlns : this.xmlns});
	}
	handleResponse(stanza) {
		this.responseStanza = stanza;
		this.finish();
	}
	getResult() {
		if(this.responseStanza == null) {
			return null;
		}
		return { type : this.responseStanza.attr["type"]};
	}
}
snikket_queries_Push2Disable.__name__ = "snikket.queries.Push2Disable";
snikket_queries_Push2Disable.__super__ = snikket_queries_GenericQuery;
Object.assign(snikket_queries_Push2Disable.prototype, {
	__class__: snikket_queries_Push2Disable
});
class snikket_queries_Push2Enable extends snikket_queries_GenericQuery {
	constructor(to,service,client,ua_public,auth_secret,jwt_alg,jwt_key,jwt_claims) {
		snikket_queries_GenericQuery._hx_skip_constructor = true;
		super();
		snikket_queries_GenericQuery._hx_skip_constructor = false;
		this._hx_constructor(to,service,client,ua_public,auth_secret,jwt_alg,jwt_key,jwt_claims);
	}
	_hx_constructor(to,service,client,ua_public,auth_secret,jwt_alg,jwt_key,jwt_claims) {
		this.ver = null;
		this.queryId = null;
		this.xmlns = "urn:xmpp:push2:0";
		super._hx_constructor();
		this.queryId = snikket_ID.short();
		this.queryStanza = new snikket_Stanza("iq",{ to : to, type : "set", id : this.queryId});
		let enable = this.queryStanza.tag("enable",{ xmlns : this.xmlns});
		enable.textTag("service",service);
		enable.textTag("client",client);
		let match = enable.tag("match",{ profile : "urn:xmpp:push2:match:important"});
		let send = match.tag("send",{ xmlns : "urn:xmpp:push2:send:sce+rfc8291+rfc8292:0"});
		send.textTag("ua-public",haxe_crypto_Base64.encode(ua_public));
		send.textTag("auth-secret",haxe_crypto_Base64.encode(auth_secret));
		if(jwt_alg != null) {
			send.textTag("jwt-alg",jwt_alg);
			send.textTag("jwt-key",haxe_crypto_Base64.encode(jwt_key));
			let jsIterator = jwt_claims.entries();
			let _g_jsIterator = jsIterator;
			let _g_lastStep = jsIterator.next();
			while(!_g_lastStep.done) {
				let v = _g_lastStep.value;
				_g_lastStep = _g_jsIterator.next();
				let _g_key = v[0];
				let _g_value = v[1];
				let key = _g_key;
				let value = _g_value;
				send.textTag("jwt-claim",value,{ name : key});
			}
		}
		enable.up().up().up();
	}
	handleResponse(stanza) {
		this.responseStanza = stanza;
		this.finish();
	}
	getResult() {
		if(this.responseStanza == null) {
			return null;
		}
		return { type : this.responseStanza.attr["type"]};
	}
}
snikket_queries_Push2Enable.__name__ = "snikket.queries.Push2Enable";
snikket_queries_Push2Enable.__super__ = snikket_queries_GenericQuery;
Object.assign(snikket_queries_Push2Enable.prototype, {
	__class__: snikket_queries_Push2Enable
});
class snikket_queries_RosterGet extends snikket_queries_GenericQuery {
	constructor(ver) {
		snikket_queries_GenericQuery._hx_skip_constructor = true;
		super();
		snikket_queries_GenericQuery._hx_skip_constructor = false;
		this._hx_constructor(ver);
	}
	_hx_constructor(ver) {
		this.ver = null;
		this.queryId = null;
		this.xmlns = "jabber:iq:roster";
		super._hx_constructor();
		let attr = { xmlns : this.xmlns};
		if(ver != null) {
			attr["ver"] = ver;
		}
		this.queryId = snikket_ID.short();
		this.queryStanza = new snikket_Stanza("iq",{ type : "get"}).tag("query",attr).up();
	}
	handleResponse(stanza) {
		this.responseStanza = stanza;
		this.finish();
	}
	getResult() {
		if(this.responseStanza == null) {
			return [];
		}
		if(this.result == null) {
			let q = this.responseStanza.getChild("query","jabber:iq:roster");
			if(q == null) {
				return [];
			}
			this.ver = q.attr["ver"];
			let _this = q.allTags("item");
			let result = new Array(_this.length);
			let _g = 0;
			let _g1 = _this.length;
			while(_g < _g1) {
				let i = _g++;
				let item = _this[i];
				result[i] = { jid : item.attr["jid"], fn : item.attr["name"], subscription : item.attr["subscription"]};
			}
			this.result = result;
		}
		return this.result;
	}
}
snikket_queries_RosterGet.__name__ = "snikket.queries.RosterGet";
snikket_queries_RosterGet.__super__ = snikket_queries_GenericQuery;
Object.assign(snikket_queries_RosterGet.prototype, {
	__class__: snikket_queries_RosterGet
});
class snikket_queries_VcardTempGet extends snikket_queries_GenericQuery {
	constructor(to) {
		snikket_queries_GenericQuery._hx_skip_constructor = true;
		super();
		snikket_queries_GenericQuery._hx_skip_constructor = false;
		this._hx_constructor(to);
	}
	_hx_constructor(to) {
		this.ver = null;
		this.queryId = null;
		this.xmlns = "vcard-temp";
		super._hx_constructor();
		this.queryId = snikket_ID.short();
		this.queryStanza = new snikket_Stanza("iq",{ to : to.asString(), type : "get", id : this.queryId});
		this.queryStanza.tag("vCard",{ xmlns : this.xmlns}).up();
	}
	handleResponse(stanza) {
		this.responseStanza = stanza;
		this.finish();
	}
	getResult() {
		if(this.responseStanza == null) {
			return { photo : null};
		}
		if(this.result == null) {
			let vcard = this.responseStanza.getChild("vCard",this.xmlns);
			if(vcard == null) {
				return { photo : null};
			}
			let photoMime = vcard.findText("PHOTO/TYPE#");
			let photoBinval = vcard.findText("PHOTO/BINVAL#");
			if(photoMime != null && photoBinval != null) {
				this.result = { photo : { mime : photoMime, data : haxe_crypto_Base64.decode(StringTools.replace(photoBinval,"\n",""))}};
			} else {
				this.result = { photo : null};
			}
		}
		return this.result;
	}
}
snikket_queries_VcardTempGet.__name__ = "snikket.queries.VcardTempGet";
snikket_queries_VcardTempGet.__super__ = snikket_queries_GenericQuery;
Object.assign(snikket_queries_VcardTempGet.prototype, {
	__class__: snikket_queries_VcardTempGet
});
class snikket_streams_XmppJsStream extends snikket_GenericStream {
	constructor() {
		snikket_EventEmitter._hx_skip_constructor = true;
		super();
		snikket_EventEmitter._hx_skip_constructor = false;
		this._hx_constructor();
	}
	_hx_constructor() {
		this.everConnected = false;
		this.resumed = false;
		this.initialSM = null;
		this.pendingOnIq = [];
		this.pending = [];
		this.debug = true;
		super._hx_constructor();
		let _g = new haxe_ds_StringMap();
		_g.h["online"] = $bind(this,this.onOnline);
		_g.h["offline"] = $bind(this,this.onOffline);
		let tmp = snikket_Map.fromMap(_g);
		let _g1 = new haxe_ds_StringMap();
		_g1.h["connection-error"] = $bind(this,this.onError);
		this.state = new snikket_FSM({ transitions : [{ name : "connect-requested", from : ["offline"], to : "connecting"},{ name : "connection-success", from : ["connecting"], to : "online"},{ name : "connection-error", from : ["connecting"], to : "offline"},{ name : "connection-closed", from : ["connecting","online"], to : "offline"}], state_handlers : tmp, transition_handlers : snikket_Map.fromMap(_g1)},"offline");
	}
	connectWithURI(uri) {
		haxe_Log.trace("Got connection URI: " + uri,{ fileName : "snikket/streams/XmppJsStream.hx", lineNumber : 165, className : "snikket.streams.XmppJsStream", methodName : "connectWithURI"});
		if(uri == null) {
			this.state.event("connection-error");
			return;
		}
		this.connectionURI = uri;
		let _gthis = this;
		let waitForCreds = new Promise(function(resolve,reject) {
			_gthis.on("auth/password",function(event) {
				if(event.username == null) {
					event.username = _gthis.jid.local;
				}
				resolve(event);
				return snikket_EventResult.EventHandled;
			});
		});
		let clientId = this.jid.resource;
		let xmpp = new snikket_streams_XmppJsClient({ service : this.connectionURI, domain : this.jid.domain, resource : this.jid.resource, credentials : function(callback,mechanisms,fast) {
			_gthis.everConnected = true;
			_gthis.clientId = ((mechanisms) instanceof Array) ? clientId : null;
			let mechs = fast == null ? [] : [{ name : fast.mechanism, canFast : true, canOther : false}];
			let _this = ((mechanisms) instanceof Array) ? mechanisms : [mechanisms];
			let result = new Array(_this.length);
			let _g = 0;
			let _g1 = _this.length;
			while(_g < _g1) {
				let i = _g++;
				result[i] = { name : _this[i], canFast : false, canOther : true};
			}
			let mechs1 = mechs.concat(result);
			let tmp = Lambda.find(mechs1,function(m) {
				return m.canOther;
			});
			let mech = tmp != null ? tmp.name : null;
			_gthis.trigger("auth/password-needed",{ mechanisms : mechs1});
			return waitForCreds.then(function(creds) {
				creds.username = _gthis.jid.local;
				if(creds.fastCount != null) {
					try {
						creds = { username : _gthis.jid.local, token : JSON.parse(creds.password), mechanism : null};
					} catch( _g ) {
						creds = { password : null, fastCount : null, username : _gthis.jid.local, token : { token : "fail", mechanism : creds.mechanism}, mechanism : null};
					}
				}
				let tmp = creds.mechanism;
				return callback(creds,tmp != null ? tmp : mech,snikket_streams_XmppJsXml("user-agent",{ id : clientId}));
			});
		}});
		snikket_streams_XmppJsScramSha1(xmpp.saslFactory);
		xmpp.jid = this.jid;
		xmpp.streamFeatures.use("csi","urn:xmpp:csi:0",function(ctx,next,feature) {
			_gthis.csi = true;
			next();
		});
		if(this.debug) {
			snikket_streams_XmppJsDebug(xmpp,true);
		}
		if(this.initialSM != null) {
			let parsedSM = JSON.parse(haxe_io_Bytes.ofData(this.initialSM).toString());
			let parsedPending = parsedSM.pending;
			if(parsedPending != null) {
				let _g = 0;
				while(_g < parsedPending.length) {
					let item = parsedPending[_g];
					++_g;
					this.pending.push(snikket_streams_XmppJsLtx.parse(item));
				}
			}
			xmpp.streamManagement.id = parsedSM.id;
			xmpp.streamManagement.outbound = parsedSM.outbound;
			xmpp.streamManagement.inbound = parsedSM.inbound;
			let tmp = parsedSM.outbound_q;
			let _this = tmp != null ? tmp : [];
			let result = new Array(_this.length);
			let _g = 0;
			let _g1 = _this.length;
			while(_g < _g1) {
				let i = _g++;
				let item = _this[i];
				result[i] = { stanza : snikket_streams_XmppJsLtx.parse(item.stanza), stamp : item.stamp};
			}
			xmpp.streamManagement.outbound_q = result;
			this.initialSM = null;
		}
		this.client = xmpp;
		this.processPendingOnIq();
		xmpp.on("online",function(jid) {
			_gthis.resumed = false;
			_gthis.jid = jid;
			_gthis.state.event("connection-success");
		});
		xmpp.on("offline",function(data) {
			_gthis.state.event("connection-closed");
		});
		xmpp.streamManagement.on("resumed",function(_) {
			_gthis.resumed = true;
			if(xmpp.jid == null) {
				xmpp.jid = _gthis.jid;
			} else {
				_gthis.jid = xmpp.jid;
			}
			_gthis.state.event("connection-success");
		});
		xmpp.on("stanza",function(stanza) {
			_gthis.onStanza(snikket_streams_XmppJsStream.convertToStanza(stanza));
			_gthis.triggerSMupdate();
		});
		xmpp.streamManagement.on("ack",function(stanza) {
			let tmp;
			if((stanza != null ? stanza.name : null) == "message") {
				let tmp1 = stanza != null ? stanza.attrs : null;
				tmp = (tmp1 != null ? tmp1.id : null) != null;
			} else {
				tmp = false;
			}
			if(tmp) {
				_gthis.trigger("sm/ack",{ id : stanza.attrs.id});
			}
			_gthis.triggerSMupdate();
		});
		xmpp.streamManagement.on("fail",function(stanza) {
			if(stanza.name == "message" && stanza.attrs.id != null) {
				_gthis.trigger("sm/fail",{ id : stanza.attrs.id});
			}
			_gthis.triggerSMupdate();
		});
		xmpp.fast.saveToken = function(token) {
			token.token = JSON.stringify(token);
			_gthis.trigger("fast-token",token);
			return Promise.resolve(null);
		};
		xmpp.on("status",function(status) {
			if(status == "disconnect") {
				if(_gthis.state.can("connection-closed")) {
					_gthis.state.event("connection-closed");
				}
			} else if(status == "connecting") {
				if(_gthis.state.can("connect-requested")) {
					_gthis.state.event("connect-requested");
				}
			}
		});
		this.resumed = false;
		xmpp.start().catch(function(err) {
			if(_gthis.state.can("connection-error")) {
				_gthis.state.event("connection-error");
			}
			let xmppError = ((err) instanceof snikket_streams_XmppJsError) ? err : null;
			if((xmppError != null ? xmppError.name : null) == "SASLError") {
				_gthis.trigger("auth/fail",xmppError);
			} else {
				haxe_Log.trace(err,{ fileName : "snikket/streams/XmppJsStream.hx", lineNumber : 298, className : "snikket.streams.XmppJsStream", methodName : "connectWithURI"});
			}
		});
	}
	connect(jid,sm) {
		this.state.event("connect-requested");
		this.jid = new snikket_streams_XmppJsJID(jid);
		this.initialSM = sm;
		snikket_streams_XmppJsStream.resolveConnectionURI(this.jid.domain,$bind(this,this.connectWithURI));
	}
	disconnect() {
		if(this.client == null) {
			return;
		}
		this.client.stop();
	}
	convertFromStanza(el) {
		let xml = snikket_streams_XmppJsXml(el.name,el.attr);
		if(el.children.length > 0) {
			let _g = 0;
			let _g1 = el.children;
			while(_g < _g1.length) {
				let child = _g1[_g];
				++_g;
				switch(child._hx_index) {
				case 0:
					let stanza = child.stanza;
					xml.append(this.convertFromStanza(stanza));
					break;
				case 1:
					let text = child.textNode;
					xml.append(text.content);
					break;
				}
			}
		}
		return xml;
	}
	sendStanza(stanza) {
		if(this.client == null || this.client.status != "online") {
			this.pending.push(this.convertFromStanza(stanza));
		} else {
			this.client.send(this.convertFromStanza(stanza));
		}
		this.triggerSMupdate();
	}
	newId() {
		return snikket_streams_XmppJsId();
	}
	triggerSMupdate() {
		if(this.client == null || !this.client.streamManagement.enabled) {
			return;
		}
		let _this = this.client.streamManagement.id;
		let _this1 = this.client.streamManagement.outbound;
		let _this2 = this.client.streamManagement.inbound;
		let tmp = this.client.streamManagement.outbound_q;
		let _this3 = tmp != null ? tmp : [];
		let result = new Array(_this3.length);
		let _g = 0;
		let _g1 = _this3.length;
		while(_g < _g1) {
			let i = _g++;
			let item = _this3[i];
			result[i] = { stanza : item.stanza.toString(), stamp : item.stamp};
		}
		let _this4 = result;
		let _this5 = this.pending;
		let result1 = new Array(_this5.length);
		let _g2 = 0;
		let _g3 = _this5.length;
		while(_g2 < _g3) {
			let i = _g2++;
			result1[i] = _this5[i].toString();
		}
		this.trigger("sm/update",{ sm : haxe_io_Bytes.ofString(JSON.stringify({ id : _this, outbound : _this1, inbound : _this2, outbound_q : _this4, pending : result1})).b.bufferValue});
	}
	fromIqResult(result) {
		switch(result._hx_index) {
		case 0:
			let el = result.element;
			return this.convertFromStanza(el);
		case 1:
			return true;
		case 2:
			return false;
		}
	}
	onIq(type,tag,xmlns,handler) {
		let _gthis = this;
		if(this.client == null) {
			this.pendingOnIq.push({ type : type, tag : tag, xmlns : xmlns, handler : handler});
		} else {
			switch(type._hx_index) {
			case 0:
				this.client.iqCallee.get(xmlns,tag,function(el) {
					return _gthis.fromIqResult(handler(snikket_streams_XmppJsStream.convertToStanza(el.stanza)));
				});
				break;
			case 1:
				this.client.iqCallee.set(xmlns,tag,function(el) {
					return _gthis.fromIqResult(handler(snikket_streams_XmppJsStream.convertToStanza(el.stanza)));
				});
				break;
			}
		}
	}
	processPendingOnIq() {
		let item;
		while(true) {
			item = this.pendingOnIq.shift();
			if(!(item != null)) {
				break;
			}
			this.onIq(item.type,item.tag,item.xmlns,item.handler);
		}
	}
	onOnline(event) {
		this.everConnected = true;
		let item;
		while(true) {
			item = this.pending.shift();
			if(!(item != null)) {
				break;
			}
			this.client.send(item);
		}
		this.triggerSMupdate();
		this.trigger("status/online",{ jid : this.jid.toString(), resumed : this.resumed});
	}
	onOffline(event) {
		this.trigger("status/offline",{ });
	}
	onError(event) {
		if(!this.everConnected) {
			this.trigger("status/error",{ });
		}
		return true;
	}
	static resolveConnectionURI(domain,callback) {
		let request = new haxe_http_HttpJs("https://" + domain + "/.well-known/host-meta.json");
		request.onData = function(data) {
			let parsed = JSON.parse(data);
			let _g = [];
			let _g1 = 0;
			let _g2 = parsed.links;
			while(_g1 < _g2.length) {
				let v = _g2[_g1];
				++_g1;
				if(HxOverrides.substr(v.href,0,6) == "wss://") {
					_g.push(v);
				}
			}
			let links = _g;
			if(links.length > 0) {
				callback(links[0].href);
				return;
			}
			callback(null);
		};
		request.onError = function(msg) {
			callback(null);
		};
		request.request(false);
	}
	static convertToStanza(el) {
		let stanza = new snikket_Stanza(el.name,el.attrs);
		let _g = 0;
		let _g1 = el.children;
		while(_g < _g1.length) {
			let child = _g1[_g];
			++_g;
			if(snikket_streams_XmppJsLtx.isText(child)) {
				stanza.text(js_Boot.__cast(child , String));
			} else {
				stanza.addChild(snikket_streams_XmppJsStream.convertToStanza(child));
			}
		}
		return stanza;
	}
	static parse(input) {
		return snikket_streams_XmppJsStream.convertToStanza(snikket_streams_XmppJsLtx.parse(input));
	}
}
snikket_streams_XmppJsStream.__name__ = "snikket.streams.XmppJsStream";
snikket_streams_XmppJsStream.__super__ = snikket_GenericStream;
Object.assign(snikket_streams_XmppJsStream.prototype, {
	__class__: snikket_streams_XmppJsStream
});
class thenshim_PromiseFactory {
}
thenshim_PromiseFactory.__name__ = "thenshim.PromiseFactory";
thenshim_PromiseFactory.__isInterface__ = true;
Object.assign(thenshim_PromiseFactory.prototype, {
	__class__: thenshim_PromiseFactory
});
class thenshim_js_JSPromiseFactory {
	constructor() {
	}
	make(executor) {
		return new Promise(executor);
	}
	asResolved(object) {
		return Promise.resolve(object);
	}
	asRejected(reason) {
		return Promise.reject(reason);
	}
}
thenshim_js_JSPromiseFactory.__name__ = "thenshim.js.JSPromiseFactory";
thenshim_js_JSPromiseFactory.__interfaces__ = [thenshim_PromiseFactory];
Object.assign(thenshim_js_JSPromiseFactory.prototype, {
	__class__: thenshim_js_JSPromiseFactory
});
class thenshim_Promise {
	static _new(executor) {
		return thenshim_Promise.factory.make(executor);
	}
	static resolve(object) {
		return thenshim_Promise.factory.asResolved(object);
	}
	static reject(reason) {
		return thenshim_Promise.factory.asRejected(reason);
	}
	static then(this1,onFulfilled,onRejected) {
		return this1.then(onFulfilled,onRejected);
	}
}
class thenshim_PromiseTools {
	static all(promises) {
		return Promise.all(Lambda.array(promises));
	}
	static allSettled(promises) {
		return Promise.allSettled(Lambda.array(promises));
	}
	static race(promises) {
		return Promise.race(Lambda.array(promises));
	}
	static catch_(promise,onRejected) {
		return promise.catch(onRejected);
	}
	static catchError(promise,onRejected) {
		return thenshim_PromiseTools.catch_(promise,onRejected);
	}
	static finally(promise,onFinally) {
		return promise.finally(onFinally);
	}
}
thenshim_PromiseTools.__name__ = "thenshim.PromiseTools";
class thenshim_Thenable {
}
thenshim_Thenable.__name__ = "thenshim.Thenable";
thenshim_Thenable.__isInterface__ = true;
Object.assign(thenshim_Thenable.prototype, {
	__class__: thenshim_Thenable
});
class thenshim_ThenableCallback {
	static toJSPromiseHandler(this1) {
		return this1;
	}
}
class tink_Anon {
	static getExistentFields(o) {
		let ret = { };
		let _g = 0;
		let _g1 = Reflect.fields(o);
		while(_g < _g1.length) {
			let f = _g1[_g];
			++_g;
			ret[f] = true;
		}
		return ret;
	}
}
tink_Anon.__name__ = "tink.Anon";
class tink_chunk_ChunkBase {
	getCursor() {
		if(this.flattened == null) {
			this.flatten(this.flattened = []);
		}
		return tink_chunk_ChunkCursor.create(this.flattened.slice());
	}
	flatten(into) {
	}
}
tink_chunk_ChunkBase.__name__ = "tink.chunk.ChunkBase";
Object.assign(tink_chunk_ChunkBase.prototype, {
	__class__: tink_chunk_ChunkBase
});
class tink_chunk_ChunkObject {
}
tink_chunk_ChunkObject.__name__ = "tink.chunk.ChunkObject";
tink_chunk_ChunkObject.__isInterface__ = true;
Object.assign(tink_chunk_ChunkObject.prototype, {
	__class__: tink_chunk_ChunkObject
});
class tink__$Chunk_EmptyChunk extends tink_chunk_ChunkBase {
	constructor() {
		super();
	}
	getByte(i) {
		return 0;
	}
	getLength() {
		return 0;
	}
	slice(from,to) {
		return this;
	}
	blitTo(target,offset) {
	}
	toString() {
		return "";
	}
	toBytes() {
		return tink__$Chunk_EmptyChunk.EMPTY;
	}
}
tink__$Chunk_EmptyChunk.__name__ = "tink._Chunk.EmptyChunk";
tink__$Chunk_EmptyChunk.__interfaces__ = [tink_chunk_ChunkObject];
tink__$Chunk_EmptyChunk.__super__ = tink_chunk_ChunkBase;
Object.assign(tink__$Chunk_EmptyChunk.prototype, {
	__class__: tink__$Chunk_EmptyChunk
});
class tink_Chunk {
	static get_length(this1) {
		return this1.getLength();
	}
	static getByte(this1,i) {
		return this1.getByte(i);
	}
	static concat(this1,that) {
		return tink_chunk_CompoundChunk.cons(this1,that);
	}
	static cursor(this1) {
		return this1.getCursor();
	}
	static iterator(this1) {
		return new tink_chunk_ChunkIterator(this1.getCursor());
	}
	static sub(this1,pos,len) {
		return this1.slice(pos,pos + len);
	}
	static slice(this1,from,to) {
		return this1.slice(from,to);
	}
	static blitTo(this1,target,offset) {
		this1.blitTo(target,offset);
	}
	static toHex(this1) {
		return this1.toBytes().toHex();
	}
	static toString(this1) {
		return this1.toString();
	}
	static toBytes(this1) {
		return this1.toBytes();
	}
	static castToBlob(this1) {
		return new Blob([this1.toBytes().b.bufferValue],null);
	}
	static toBlob(this1,opt) {
		return new Blob([this1.toBytes().b.bufferValue],opt);
	}
	static join(chunks) {
		if(chunks == null) {
			return tink_Chunk.EMPTY;
		} else {
			switch(chunks.length) {
			case 0:
				return tink_Chunk.EMPTY;
			case 1:
				let v = chunks[0];
				return v;
			default:
				let v1 = chunks;
				let ret = tink_Chunk.concat(v1[0],v1[1]);
				let _g = 2;
				let _g1 = v1.length;
				while(_g < _g1) {
					let i = _g++;
					ret = tink_Chunk.concat(ret,v1[i]);
				}
				return ret;
			}
		}
	}
	static ofBytes(b) {
		return tink_chunk_ByteChunk.of(b);
	}
	static ofString(s) {
		return tink_chunk_ByteChunk.of(haxe_io_Bytes.ofString(s));
	}
	static ofUint8Array(b) {
		return tink_chunk_ByteChunk.of(haxe_io_Bytes.ofData(b.buffer.slice(b.byteOffset,b.byteOffset + b.byteLength)));
	}
	static ofByte(byte) {
		let bytes = new haxe_io_Bytes(new ArrayBuffer(1));
		bytes.b[0] = byte;
		return tink_chunk_ByteChunk.of(bytes);
	}
	static ofHex(s) {
		let length = s.length >> 1;
		let bytes = new haxe_io_Bytes(new ArrayBuffer(length));
		let _g = 0;
		let _g1 = length;
		while(_g < _g1) {
			let i = _g++;
			bytes.b[i] = Std.parseInt("0x" + HxOverrides.substr(s,i * 2,2));
		}
		return tink_chunk_ByteChunk.of(bytes);
	}
	static parseHex(v) {
		return Std.parseInt("0x" + v);
	}
	static catChunk(a,b) {
		return tink_Chunk.concat(a,b);
	}
	static rcatString(a,b) {
		return tink_Chunk.concat(a,tink_chunk_ByteChunk.of(haxe_io_Bytes.ofString(b)));
	}
	static lcatString(a,b) {
		return tink_Chunk.concat(tink_chunk_ByteChunk.of(haxe_io_Bytes.ofString(a)),b);
	}
	static lcatBytes(a,b) {
		return tink_Chunk.concat(tink_chunk_ByteChunk.of(a),b);
	}
	static rcatBytes(a,b) {
		return tink_Chunk.concat(a,tink_chunk_ByteChunk.of(b));
	}
	static eqChunk(a,b) {
		return a.toString() == b.toString();
	}
	static reqString(a,b) {
		return a.toString() == b.toString();
	}
	static leqString(a,b) {
		return a.toString() == b.toString();
	}
	static leqBytes(a,b) {
		return a.toString() == b.toString();
	}
	static reqBytes(a,b) {
		return a.toString() == b.toString();
	}
}
class tink_Stringly {
	static isNumber(s,allowFloat) {
		if(s.length == 0) {
			return false;
		}
		let pos = 0;
		let max = s.length;
		if(pos < max && s.charCodeAt(pos) == 45) {
			++pos;
		}
		if(!allowFloat) {
			if(pos < max && s.charCodeAt(pos) == 48 && pos++ > -1) {
				if(pos < max && s.charCodeAt(pos) == 120) {
					++pos;
				}
			}
		}
		while(pos < max && (s.charCodeAt(pos) ^ 48) < 10) ++pos;
		if(allowFloat && pos < max) {
			if(pos < max && s.charCodeAt(pos) == 46 && pos++ > -1) {
				while(pos < max && (s.charCodeAt(pos) ^ 48) < 10) ++pos;
			}
			if(pos < max && s.charCodeAt(pos) == 101 && pos++ > -1 || pos < max && s.charCodeAt(pos) == 69 && pos++ > -1) {
				if(!(pos < max && s.charCodeAt(pos) == 43 && pos++ > -1)) {
					if(pos < max && s.charCodeAt(pos) == 45) {
						++pos;
					}
				}
				while(pos < max && (s.charCodeAt(pos) ^ 48) < 10) ++pos;
			}
		}
		return pos == max;
	}
	static toBool(this1) {
		if(this1 != null) {
			switch(StringTools.trim(this1).toLowerCase()) {
			case "0":case "false":case "no":
				return false;
			default:
				return true;
			}
		} else {
			return false;
		}
	}
	static isFloat(this1) {
		return tink_Stringly.isNumber(StringTools.trim(this1),true);
	}
	static parseFloat(this1) {
		let _g = StringTools.trim(this1);
		let v = _g;
		if(tink_Stringly.isNumber(v,true)) {
			return tink_core_Outcome.Success(parseFloat(v));
		} else {
			let v = _g;
			return tink_core_Outcome.Failure(new tink_core_TypedError(422,"" + v + " (encoded as " + this1 + ") is not a valid float",{ fileName : "tink/Stringly.hx", lineNumber : 65, className : "tink._Stringly.Stringly_Impl_", methodName : "parseFloat"}));
		}
	}
	static toFloat(this1) {
		return tink_core_OutcomeTools.sure(tink_Stringly.parseFloat(this1));
	}
	static isInt(this1) {
		return tink_Stringly.isNumber(StringTools.trim(this1),false);
	}
	static parseInt(this1) {
		let _g = StringTools.trim(this1);
		let v = _g;
		if(tink_Stringly.isNumber(v,false)) {
			return tink_core_Outcome.Success(Std.parseInt(v));
		} else {
			let v = _g;
			return tink_core_Outcome.Failure(new tink_core_TypedError(422,"" + v + " (encoded as " + this1 + ") is not a valid integer",{ fileName : "tink/Stringly.hx", lineNumber : 80, className : "tink._Stringly.Stringly_Impl_", methodName : "parseInt"}));
		}
	}
	static toInt(this1) {
		return tink_core_OutcomeTools.sure(tink_Stringly.parseInt(this1));
	}
	static parseDate(this1) {
		let _g = tink_Stringly.parseFloat(this1);
		switch(_g._hx_index) {
		case 0:
			let f = _g.data;
			return tink_core_Outcome.Success(new Date(f));
		case 1:
			let _g1 = _g.failure;
			if(!tink_Stringly.SUPPORTED_DATE_REGEX.match(this1)) {
				return tink_core_Outcome.Failure(new tink_core_TypedError(422,"" + this1 + " is not a valid date",{ fileName : "tink/Stringly.hx", lineNumber : 101, className : "tink._Stringly.Stringly_Impl_", methodName : "parseDate"}));
			}
			let date = new Date(this1);
			let f1 = date.getTime();
			if(isNaN(f1)) {
				return tink_core_Outcome.Failure(new tink_core_TypedError(422,"" + this1 + " is not a valid date",{ fileName : "tink/Stringly.hx", lineNumber : 104, className : "tink._Stringly.Stringly_Impl_", methodName : "parseDate"}));
			} else {
				return tink_core_Outcome.Success(date);
			}
			break;
		}
	}
	static toDate(this1) {
		return tink_core_OutcomeTools.sure(tink_Stringly.parseDate(this1));
	}
	static parse(this1,f) {
		let _g = f;
		let a1 = this1;
		return tink_core_TypedError.catchExceptions(function() {
			return _g(a1);
		},null,{ fileName : "tink/Stringly.hx", lineNumber : 171, className : "tink._Stringly.Stringly_Impl_", methodName : "parse"});
	}
	static ofBool(b) {
		if(b) {
			return "true";
		} else {
			return "false";
		}
	}
	static ofInt(i) {
		if(i == null) {
			return "null";
		} else {
			return "" + i;
		}
	}
	static ofFloat(f) {
		if(f == null) {
			return "null";
		} else {
			return "" + f;
		}
	}
	static ofDate(d) {
		let f = d.getTime();
		if(f == null) {
			return "null";
		} else {
			return "" + f;
		}
	}
}
class tink_Url {
	static get_host(this1) {
		return this1.hosts[0];
	}
	static get_hosts(this1) {
		return this1.hosts;
	}
	static get_pathWithQuery(this1) {
		if(this1.query == null) {
			return this1.path;
		} else {
			return (this1.path == null ? "null" : this1.path) + "?" + (this1.query == null ? "null" : this1.query);
		}
	}
	static _new(parts) {
		return parts;
	}
	static resolve(this1,that) {
		if(that.scheme != null) {
			return that;
		} else if(that.hosts[0] != null) {
			if(that.scheme != null) {
				return that;
			} else {
				let copy = Reflect.copy(that);
				copy.scheme = this1.scheme;
				return copy;
			}
		} else {
			let parts = { path : tink_url_Path.join(this1.path,that.path), payload : "", scheme : this1.scheme, query : that.query, auth : this1.auth, hosts : this1.hosts, hash : that.hash};
			tink_Url.makePayload(parts);
			return parts;
		}
	}
	static makePayload(parts) {
		let payload = "";
		let _g = parts.auth;
		let _g1 = parts.hash;
		let _g2 = parts.hosts;
		let _g3 = parts.path;
		let _g4 = parts.payload;
		let _g5 = parts.query;
		let _g6 = parts.scheme;
		if(_g == null) {
			if(_g2.length != 0) {
				let v = _g2;
				payload += "//" + v.join(",");
			}
		} else if(_g2.length == 0) {
			let auth = _g;
			payload += "//" + (auth == null ? "null" : auth == null ? "" : "" + auth + "@");
		} else {
			let auth = _g;
			let v = _g2;
			payload += "//" + (auth == null ? "null" : auth == null ? "" : "" + auth + "@") + v.join(",");
		}
		payload += parts.path == null ? "null" : parts.path;
		let _g7 = parts.query;
		if(_g7 != null) {
			let v = _g7;
			payload += "?" + (v == null ? "null" : v);
		}
		let _g8 = parts.hash;
		if(_g8 != null) {
			let v = _g8;
			payload += "#" + v;
		}
		parts.payload = payload.toString();
	}
	static toString(this1) {
		if(this1.scheme == null) {
			return this1.payload;
		} else {
			return "" + this1.scheme + ":" + this1.payload;
		}
	}
	static fromString(s) {
		return tink_Url.parse(s);
	}
	static noop(_) {
	}
	static parse(s,onError) {
		if(s == null) {
			return tink_Url.parse("");
		}
		if(onError == null) {
			onError = tink_Url.noop;
		}
		s = StringTools.trim(s);
		if(s.startsWith("data:")) {
			return { scheme : "data", payload : HxOverrides.substr(s,5,null), hosts : []};
		}
		let FORMAT = new EReg("^(([a-zA-Z][a-zA-Z0-9\\-+.]*):)?((//(([^@/]+)@)?([^/?#]*))?([^?#]*)(\\?([^#]*))?(#(.*))?)$","");
		let HOST = new EReg("^(\\[(.*)\\]|([^:]*))(:(.*))?$","");
		FORMAT.match(s);
		let hosts;
		let _g = FORMAT.matched(7);
		if(_g == null) {
			hosts = [];
		} else {
			let v = _g;
			let _g1 = [];
			let _g2 = 0;
			let _g3 = v.split(",");
			while(_g2 < _g3.length) {
				let host = _g3[_g2];
				++_g2;
				HOST.match(host);
				let host1;
				let _g = HOST.matched(3);
				let _g4 = HOST.matched(2);
				if(_g4 == null) {
					let ipv4 = _g;
					host1 = ipv4;
				} else if(_g == null) {
					let ipv6 = _g4;
					host1 = "[" + ipv6 + "]";
				} else {
					onError("invalid host " + host);
					host1 = null;
				}
				let port;
				let _g5 = HOST.matched(5);
				if(_g5 == null) {
					port = null;
				} else {
					let v = _g5;
					let _g = Std.parseInt(v);
					if(_g == null) {
						onError("invalid port " + v);
						port = null;
					} else {
						let p = _g;
						port = p;
					}
				}
				_g1.push(tink_url_Host._new(host1,port));
			}
			hosts = _g1;
		}
		let path = FORMAT.matched(8);
		if(hosts.length > 0 && path.charAt(0) != "/") {
			path = "/" + path;
		}
		return { scheme : FORMAT.matched(2), payload : FORMAT.matched(3), hosts : hosts, auth : FORMAT.matched(6), path : tink_url_Path.ofString(path), query : FORMAT.matched(10), hash : FORMAT.matched(12)};
	}
	static make(parts) {
		let parts1 = { payload : "", path : parts.path, query : parts.query, hosts : parts.hosts, auth : parts.auth, scheme : parts.scheme, hash : parts.hash};
		tink_Url.makePayload(parts1);
		return parts1;
	}
}
class tink_SingleHostUrl {
	static _new(v) {
		return v;
	}
	static ofUrl(u) {
		let v;
		let _g = u.hosts;
		switch(_g.length) {
		case 0:
			v = u;
			break;
		case 1:
			let _g1 = _g[0];
			v = u;
			break;
		default:
			let v1 = _g;
			v = tink_Url.make({ path : u.path, query : u.query, hosts : [u.hosts[0]], auth : u.auth, scheme : u.scheme, hash : u.hash});
		}
		return v;
	}
	static ofString(s) {
		return tink_SingleHostUrl.ofUrl(tink_Url.fromString(s));
	}
}
class tink_chunk_ByteChunk extends tink_chunk_ChunkBase {
	constructor(data,from,to) {
		super();
		this.data = data;
		this.from = from;
		this.to = to;
	}
	get_wrapped() {
		if(this.wrapped == null) {
			this.wrapped = haxe_io_Bytes.ofData(this.data);
		}
		return this.wrapped;
	}
	getByte(index) {
		return this.data.bytes[this.from + index];
	}
	flatten(into) {
		into.push(this);
	}
	getLength() {
		return this.to - this.from;
	}
	getSlice(from,to) {
		if(to > this.to - this.from) {
			to = this.to - this.from;
		}
		if(from < 0) {
			from = 0;
		}
		if(to <= from) {
			return null;
		} else if(to == this.to - this.from && from == 0) {
			return this;
		} else {
			return new tink_chunk_ByteChunk(this.data,this.from + from,to + this.from);
		}
	}
	slice(from,to) {
		let _g = this.getSlice(from,to);
		if(_g == null) {
			return tink_Chunk.EMPTY;
		} else {
			let v = _g;
			return v;
		}
	}
	blitTo(target,offset) {
		if(this.wrapped == null) {
			this.wrapped = haxe_io_Bytes.ofData(this.data);
		}
		target.blit(offset,this.wrapped,this.from,this.to - this.from);
	}
	toBytes() {
		if(this.wrapped == null) {
			this.wrapped = haxe_io_Bytes.ofData(this.data);
		}
		return this.wrapped.sub(this.from,this.to - this.from);
	}
	toString() {
		if(this.wrapped == null) {
			this.wrapped = haxe_io_Bytes.ofData(this.data);
		}
		return this.wrapped.getString(this.from,this.to - this.from);
	}
	static of(b) {
		if(b.length == 0) {
			return tink_Chunk.EMPTY;
		}
		let ret = new tink_chunk_ByteChunk(b.b.bufferValue,0,b.length);
		ret.wrapped = b;
		return ret;
	}
}
tink_chunk_ByteChunk.__name__ = "tink.chunk.ByteChunk";
tink_chunk_ByteChunk.__interfaces__ = [tink_chunk_ChunkObject];
tink_chunk_ByteChunk.__super__ = tink_chunk_ChunkBase;
Object.assign(tink_chunk_ByteChunk.prototype, {
	__class__: tink_chunk_ByteChunk
});
class tink_chunk_ChunkCursor {
	constructor() {
		this.currentByte = -1;
		this.currentPos = 0;
		this.length = 0;
		this.curLength = 0;
		this.curOffset = 0;
		this.curPartIndex = 0;
	}
	clone() {
		let ret = new tink_chunk_ChunkCursor();
		ret.parts = this.parts.slice();
		ret.curPart = this.curPart;
		ret.curPartIndex = this.curPartIndex;
		ret.curOffset = this.curOffset;
		ret.curLength = this.curLength;
		ret.length = this.length;
		ret.currentPos = this.currentPos;
		ret.currentByte = this.currentByte;
		return ret;
	}
	reset() {
		this.length = 0;
		this.currentPos = 0;
		this.currentByte = -1;
		this.curOffset = 0;
		let _g = 0;
		let _g1 = this.parts;
		while(_g < _g1.length) {
			let p = _g1[_g];
			++_g;
			this.length += p.to - p.from;
		}
		this.curPart = this.parts[this.curPartIndex = 0];
		if(this.curPart != null) {
			let _this = this.curPart;
			this.curLength = _this.to - _this.from;
			let _this1 = this.curPart;
			this.currentByte = _this1.data.bytes[_this1.from];
		}
	}
	flush() {
		let ret = this.left();
		this.shift();
		return ret;
	}
	prune() {
		this.shift();
	}
	add(chunk) {
		chunk.flatten(this.parts);
		this.reset();
	}
	shift(chunk) {
		this.parts.splice(0,this.curPartIndex);
		let _g = this.parts[0];
		if(_g != null) {
			let chunk = _g;
			let _g1 = chunk.getSlice(this.curOffset,this.curLength);
			if(_g1 == null) {
				this.parts.shift();
			} else {
				let rest = _g1;
				this.parts[0] = rest;
			}
		}
		if(chunk != null) {
			this.add(chunk);
		} else {
			this.reset();
		}
	}
	clear() {
		this.parts = [];
		this.reset();
	}
	left() {
		if(this.curPart == null) {
			return tink_Chunk.EMPTY;
		}
		let _g = [];
		let _g1 = 0;
		let _g2 = this.curPartIndex;
		while(_g1 < _g2) {
			let i = _g1++;
			_g.push(this.parts[i]);
		}
		let left = _g;
		left.push(this.curPart.slice(0,this.curOffset));
		return tink_Chunk.join(left);
	}
	right() {
		if(this.curPart == null) {
			return tink_Chunk.EMPTY;
		}
		let _g = [];
		let _g1 = this.curPartIndex;
		let _g2 = this.parts.length;
		while(_g1 < _g2) {
			let i = _g1++;
			_g.push(this.parts[i]);
		}
		let right = _g;
		if(right.length > 0) {
			right[0] = this.curPart.slice(this.curOffset,this.curLength);
		}
		return tink_Chunk.join(right);
	}
	seek(seekable,options) {
		if(this.curPart == null || seekable == null || seekable.length == 0) {
			return haxe_ds_Option.None;
		}
		let max = seekable.length - 1;
		let first = seekable[0];
		let candidates = [];
		let count = 0;
		let copy = this.clone();
		copy.shift();
		let _gthis = this;
		let part = function(b,offset) {
			let data = b.data;
			let _g = b.from + offset;
			let _g1 = b.to;
			while(_g < _g1) {
				let i = _g++;
				let byte = data.bytes[i];
				if(candidates.length > 0) {
					let c = 0;
					while(c < count) {
						let pos = candidates[c];
						if(seekable[pos] == byte) {
							if(pos == max) {
								copy.moveTo(copy.currentPos + (i - (b.from + offset) - seekable.length + 1));
								let before = copy.left();
								let delta = before.getLength() + seekable.length;
								_gthis.moveTo(_gthis.currentPos + delta);
								if(options == null) {
									_gthis.shift();
								} else {
									let _g = options.withoutPruning;
									if(_g == null) {
										_gthis.shift();
									} else if(_g == false) {
										_gthis.shift();
									}
								}
								return haxe_ds_Option.Some(before);
							} else {
								candidates[c++] = pos + 1;
							}
						} else {
							count -= 1;
							let last = candidates.pop();
							if(count > c) {
								candidates[c] = last;
							}
						}
					}
				}
				if(byte == first) {
					count = candidates.push(1);
				}
			}
			copy.moveTo(copy.currentPos + (b.to - (b.from + offset)));
			return haxe_ds_Option.None;
		};
		let _g = part(this.curPart,this.curOffset);
		if(_g._hx_index == 1) {
			let _g = this.curPartIndex + 1;
			let _g1 = this.parts.length;
			while(_g < _g1) {
				let i = _g++;
				let _g1 = part(this.parts[i],0);
				switch(_g1._hx_index) {
				case 0:
					let v = _g1.v;
					return haxe_ds_Option.Some(v);
				case 1:
					break;
				}
			}
			return haxe_ds_Option.None;
		} else {
			let v = _g;
			return v;
		}
	}
	sweep(len) {
		let data = this.right().slice(0,len);
		this.moveTo(this.currentPos + len);
		return data;
	}
	sweepTo(pos) {
		return this.sweep(pos - this.currentPos);
	}
	moveBy(delta) {
		return this.moveTo(this.currentPos + delta);
	}
	moveTo(position) {
		if(this.length == 0) {
			return 0;
		}
		if(position > this.length) {
			position = this.length - 1;
		}
		if(position < 0) {
			position = 0;
		}
		this.currentPos = position;
		if(position == this.length) {
			this.ffwd();
		} else {
			let _g = 0;
			let _g1 = this.parts.length;
			while(_g < _g1) {
				let i = _g++;
				let c = this.parts[i];
				let _g1 = c.to - c.from;
				let enough = _g1;
				if(enough > position) {
					this.curPart = c;
					this.curPartIndex = i;
					this.curOffset = position;
					this.curLength = c.to - c.from;
					this.currentByte = c.data.bytes[c.from + position];
					break;
				} else {
					let v = _g1;
					position -= v;
				}
			}
		}
		return this.currentPos;
	}
	ffwd() {
		this.currentByte = -1;
		this.curLength = 0;
		this.curOffset = 0;
		this.curPart = null;
		this.curPartIndex = this.parts.length;
	}
	next() {
		if(this.currentPos == this.length) {
			return false;
		}
		this.currentPos++;
		if(this.currentPos == this.length) {
			this.ffwd();
			return false;
		}
		if(this.curOffset == this.curLength - 1) {
			this.curOffset = 0;
			this.curPart = this.parts[++this.curPartIndex];
			let _this = this.curPart;
			this.curLength = _this.to - _this.from;
			let _this1 = this.curPart;
			this.currentByte = _this1.data.bytes[_this1.from];
		} else {
			let _this = this.curPart;
			this.currentByte = _this.data.bytes[_this.from + ++this.curOffset];
		}
		return true;
	}
	static create(parts) {
		let ret = new tink_chunk_ChunkCursor();
		ret.parts = parts;
		ret.reset();
		return ret;
	}
}
tink_chunk_ChunkCursor.__name__ = "tink.chunk.ChunkCursor";
Object.assign(tink_chunk_ChunkCursor.prototype, {
	__class__: tink_chunk_ChunkCursor
});
class tink_chunk_ChunkIterator {
	constructor(target) {
		this.target = target;
		this._hasNext = target.length > target.currentPos;
	}
	hasNext() {
		return this._hasNext;
	}
	next() {
		let ret = this.target.currentByte;
		this._hasNext = this.target.next();
		return ret;
	}
}
tink_chunk_ChunkIterator.__name__ = "tink.chunk.ChunkIterator";
Object.assign(tink_chunk_ChunkIterator.prototype, {
	__class__: tink_chunk_ChunkIterator
});
class tink_chunk_ChunkTools {
	static readUInt8(chunk,offset) {
		if(chunk.getLength() < offset + 1) {
			throw haxe_Exception.thrown("Out of range (chunk length = " + chunk.getLength() + ", read offset = " + offset + ", read length = " + 1 + ")");
		}
		let val = chunk.getByte(offset);
		return val;
	}
	static readInt8(chunk,offset) {
		let val = tink_chunk_ChunkTools.readUInt8(chunk,offset);
		if(val > 127) {
			return val - 256;
		} else {
			return val;
		}
	}
	static readUInt16LE(chunk,offset) {
		if(chunk.getLength() < offset + 2) {
			throw haxe_Exception.thrown("Out of range (chunk length = " + chunk.getLength() + ", read offset = " + offset + ", read length = " + 2 + ")");
		}
		let first = chunk.getByte(offset);
		let last = chunk.getByte(offset + 1);
		return first + (last << 8);
	}
	static readInt16LE(chunk,offset) {
		let val = tink_chunk_ChunkTools.readUInt16LE(chunk,offset);
		if(val > 32767) {
			return val - 65536;
		} else {
			return val;
		}
	}
	static readUInt24LE(chunk,offset) {
		if(chunk.getLength() < offset + 3) {
			throw haxe_Exception.thrown("Out of range (chunk length = " + chunk.getLength() + ", read offset = " + offset + ", read length = " + 3 + ")");
		}
		let first = chunk.getByte(offset);
		let mid = chunk.getByte(offset + 1);
		let last = chunk.getByte(offset + 2);
		return first + (mid << 8) + (last << 16);
	}
	static readInt24LE(chunk,offset) {
		let val = tink_chunk_ChunkTools.readUInt24LE(chunk,offset);
		if(val > 8388607) {
			return val - 16777216;
		} else {
			return val;
		}
	}
	static readInt32LE(chunk,offset) {
		if(chunk.getLength() < offset + 4) {
			throw haxe_Exception.thrown("Out of range (chunk length = " + chunk.getLength() + ", read offset = " + offset + ", read length = " + 4 + ")");
		}
		let val = chunk.getByte(offset) + (chunk.getByte(offset + 1) << 8) + (chunk.getByte(offset + 2) << 16) + (chunk.getByte(offset + 3) << 24);
		return val;
	}
	static readDoubleLE(chunk,offset) {
		let l = tink_chunk_ChunkTools.readInt32LE(chunk,0);
		let h = tink_chunk_ChunkTools.readInt32LE(chunk,4);
		return haxe_io_FPHelper.i64ToDouble(l,h);
	}
	static readNullTerminatedString(chunk,offset) {
		try {
			return new haxe_io_BytesInput(chunk.toBytes(),offset).readUntil(0);
		} catch( _g ) {
			return chunk.toString();
		}
	}
	static writeUInt8(v) {
		let bytes = new haxe_io_Bytes(new ArrayBuffer(1));
		bytes.b[0] = v & 255;
		return tink_chunk_ByteChunk.of(bytes);
	}
	static writeInt8(v) {
		let bytes = new haxe_io_Bytes(new ArrayBuffer(1));
		v &= 255;
		if(v < 0) {
			v += 256;
		}
		bytes.b[0] = v;
		return tink_chunk_ByteChunk.of(bytes);
	}
	static writeUInt16LE(v) {
		let bytes = new haxe_io_Bytes(new ArrayBuffer(2));
		bytes.b[0] = v & 255;
		bytes.b[1] = v >>> 8 & 255;
		return tink_chunk_ByteChunk.of(bytes);
	}
	static writeInt16LE(v) {
		return tink_chunk_ChunkTools.writeUInt16LE(v);
	}
	static writeUInt24LE(v) {
		let bytes = new haxe_io_Bytes(new ArrayBuffer(3));
		bytes.b[0] = v & 255;
		bytes.b[1] = v >>> 8 & 255;
		bytes.b[2] = v >>> 16 & 255;
		return tink_chunk_ByteChunk.of(bytes);
	}
	static writeInt24LE(v) {
		return tink_chunk_ChunkTools.writeUInt24LE(v);
	}
	static writeInt32LE(v) {
		let bytes = new haxe_io_Bytes(new ArrayBuffer(4));
		bytes.b[0] = v & 255;
		bytes.b[1] = v >>> 8 & 255;
		bytes.b[2] = v >>> 16 & 255;
		bytes.b[3] = v >>> 24 & 255;
		return tink_chunk_ByteChunk.of(bytes);
	}
	static writeDoubleLE(v) {
		let bytes = new haxe_io_Bytes(new ArrayBuffer(8));
		let i64 = haxe_io_FPHelper.doubleToI64(v);
		let l = i64.low;
		let h = i64.high;
		bytes.b[0] = l & 255;
		bytes.b[1] = l >>> 8 & 255;
		bytes.b[2] = l >>> 16 & 255;
		bytes.b[3] = l >>> 24 & 255;
		bytes.b[4] = h & 255;
		bytes.b[5] = h >>> 8 & 255;
		bytes.b[6] = h >>> 16 & 255;
		bytes.b[7] = h >>> 24 & 255;
		return tink_chunk_ByteChunk.of(bytes);
	}
	static lpad(chunk,pad,length) {
		if(pad.getLength() != 0) {
			while(chunk.getLength() < length) chunk = tink_Chunk.concat(pad,chunk);
		}
		return chunk;
	}
	static rpad(chunk,pad,length) {
		if(pad.getLength() != 0) {
			while(chunk.getLength() < length) chunk = tink_Chunk.concat(chunk,pad);
		}
		return chunk;
	}
	static check(chunk,offset,length) {
		if(chunk.getLength() < offset + length) {
			throw haxe_Exception.thrown("Out of range (chunk length = " + chunk.getLength() + ", read offset = " + offset + ", read length = " + length + ")");
		}
	}
}
tink_chunk_ChunkTools.__name__ = "tink.chunk.ChunkTools";
class tink_chunk_CompoundChunk extends tink_chunk_ChunkBase {
	constructor() {
		super();
	}
	getByte(i) {
		let index = this.findChunk(i);
		return this.chunks[index].getByte(i - this.offsets[index]);
	}
	getLength() {
		return this.length;
	}
	findChunk(target) {
		let min = 0;
		let max = this.offsets.length - 1;
		while(min + 1 < max) {
			let guess = min + max >> 1;
			if(this.offsets[guess] > target) {
				max = guess;
			} else {
				min = guess;
			}
		}
		return min;
	}
	flatten(into) {
		let _g = 0;
		let _g1 = this.chunks;
		while(_g < _g1.length) {
			let c = _g1[_g];
			++_g;
			c.flatten(into);
		}
	}
	slice(from,to) {
		let idxFrom = this.findChunk(from);
		let idxTo = this.findChunk(to);
		if(idxFrom == idxTo) {
			let offset = this.offsets[idxFrom];
			return this.chunks[idxFrom].slice(from - offset,to - offset);
		}
		let ret = this.chunks.slice(idxFrom,idxTo + 1);
		let c = ret[0];
		ret[0] = c.slice(from - this.offsets[idxFrom],this.offsets[idxFrom + 1]);
		let c1 = ret[ret.length - 1];
		ret[ret.length - 1] = c1.slice(0,to - this.offsets[idxTo]);
		return tink_chunk_CompoundChunk.create(ret,this.depth);
	}
	blitTo(target,offset) {
		let _g = 0;
		let _g1 = this.chunks.length;
		while(_g < _g1) {
			let i = _g++;
			this.chunks[i].blitTo(target,offset + this.offsets[i]);
		}
	}
	toString() {
		return this.toBytes().toString();
	}
	toBytes() {
		let ret = new haxe_io_Bytes(new ArrayBuffer(this.length));
		this.blitTo(ret,0);
		return ret;
	}
	static asCompound(c) {
		if(((c) instanceof tink_chunk_CompoundChunk)) {
			return c;
		} else {
			return null;
		}
	}
	static cons(a,b) {
		let _g = a.getLength();
		let _g1 = b.getLength();
		if(_g == 0) {
			if(_g1 == 0) {
				return tink_Chunk.EMPTY;
			} else {
				return b;
			}
		} else if(_g1 == 0) {
			return a;
		} else {
			let la = _g;
			let lb = _g1;
			let _g2 = tink_chunk_CompoundChunk.asCompound(a);
			let _g3 = tink_chunk_CompoundChunk.asCompound(b);
			if(_g2 == null) {
				if(_g3 == null) {
					return tink_chunk_CompoundChunk.create([a,b],2);
				} else {
					let v = _g3;
					if(v.depth < 100) {
						return tink_chunk_CompoundChunk.create([a,b],v.depth + 1);
					} else {
						let flat = [];
						v.flatten(flat);
						b.flatten(flat);
						return tink_chunk_CompoundChunk.create(flat,2);
					}
				}
			} else if(_g3 == null) {
				let v = _g2;
				if(v.depth < 100) {
					return tink_chunk_CompoundChunk.create([a,b],v.depth + 1);
				} else {
					let flat = [];
					v.flatten(flat);
					b.flatten(flat);
					return tink_chunk_CompoundChunk.create(flat,2);
				}
			} else {
				let a = _g2;
				let b = _g3;
				let depth = a.depth > b.depth ? a.depth : b.depth;
				return tink_chunk_CompoundChunk.create(a.chunks.concat(b.chunks),depth);
			}
		}
	}
	static create(chunks,depth) {
		let ret = new tink_chunk_CompoundChunk();
		let offsets = [0];
		let length = 0;
		let _g = 0;
		while(_g < chunks.length) {
			let c = chunks[_g];
			++_g;
			offsets.push(length += c.getLength());
		}
		ret.chunks = chunks;
		ret.offsets = offsets;
		ret.length = length;
		ret.depth = depth;
		return ret;
	}
}
tink_chunk_CompoundChunk.__name__ = "tink.chunk.CompoundChunk";
tink_chunk_CompoundChunk.__interfaces__ = [tink_chunk_ChunkObject];
tink_chunk_CompoundChunk.__super__ = tink_chunk_ChunkBase;
Object.assign(tink_chunk_CompoundChunk.prototype, {
	__class__: tink_chunk_CompoundChunk
});
class tink_chunk_Seekable {
	static _new(a) {
		return a;
	}
	static get_length(this1) {
		return this1.length;
	}
	static get(this1,index) {
		return this1[index];
	}
	static ofChunk(c) {
		return tink_chunk_Seekable.ofBytes(c.toBytes());
	}
	static ofBytes(b) {
		let _g = [];
		let _g1 = 0;
		let _g2 = b.length;
		while(_g1 < _g2) {
			let i = _g1++;
			_g.push(b.b[i]);
		}
		return _g;
	}
	static ofString(s) {
		return tink_chunk_Seekable.ofBytes(haxe_io_Bytes.ofString(s));
	}
}
class tink_core_Annex {
	constructor(target) {
		this.target = target;
		this.registry = new haxe_ds_ObjectMap();
	}
}
tink_core_Annex.__name__ = "tink.core.Annex";
Object.assign(tink_core_Annex.prototype, {
	__class__: tink_core_Annex
});
class tink_core_Callback {
	static _new(f) {
		return f;
	}
	static toFunction(this1) {
		return this1;
	}
	static invoke(this1,data) {
		if(tink_core_Callback.depth < 500) {
			tink_core_Callback.depth++;
			this1(data);
			tink_core_Callback.depth--;
		} else {
			tink_core_Callback.defer(function() {
				this1(data);
			});
		}
	}
	static fromNiladic(f) {
		return f;
	}
	static fromMany(callbacks) {
		return function(v) {
			let _g = 0;
			while(_g < callbacks.length) {
				let callback = callbacks[_g];
				++_g;
				tink_core_Callback.invoke(callback,v);
			}
		};
	}
	static defer(f) {
		haxe_Timer.delay(f,0);
	}
}
class tink_core_LinkObject {
}
tink_core_LinkObject.__name__ = "tink.core.LinkObject";
tink_core_LinkObject.__isInterface__ = true;
Object.assign(tink_core_LinkObject.prototype, {
	__class__: tink_core_LinkObject
});
class tink_core_CallbackLinkRef {
	constructor() {
	}
	set_link(param) {
		let this1 = this.link;
		if(this1 != null) {
			this1.cancel();
		}
		return this.link = param;
	}
	cancel() {
		let this1 = this.link;
		if(this1 != null) {
			this1.cancel();
		}
	}
}
tink_core_CallbackLinkRef.__name__ = "tink.core.CallbackLinkRef";
tink_core_CallbackLinkRef.__interfaces__ = [tink_core_LinkObject];
Object.assign(tink_core_CallbackLinkRef.prototype, {
	__class__: tink_core_CallbackLinkRef
});
class tink_core_CallbackLink {
	static _new(link) {
		return new tink_core_SimpleLink(link);
	}
	static cancel(this1) {
		if(this1 != null) {
			this1.cancel();
		}
	}
	static dissolve(this1) {
		if(this1 != null) {
			this1.cancel();
		}
	}
	static noop() {
	}
	static toFunction(this1) {
		if(this1 == null) {
			return tink_core_CallbackLink.noop;
		} else {
			return $bind(this1,this1.cancel);
		}
	}
	static toCallback(this1) {
		if(this1 == null) {
			return tink_core_CallbackLink.noop;
		} else {
			return $bind(this1,this1.cancel);
		}
	}
	static fromFunction(f) {
		return new tink_core_SimpleLink(f);
	}
	static join(this1,b) {
		return new tink_core__$Callback_LinkPair(this1,b);
	}
	static fromMany(callbacks) {
		return new tink_core_SimpleLink(function() {
			if(callbacks != null) {
				let _g = 0;
				while(_g < callbacks.length) {
					let cb = callbacks[_g];
					++_g;
					if(cb != null) {
						cb.cancel();
					}
				}
			} else {
				callbacks = null;
			}
		});
	}
}
class tink_core_SimpleLink {
	constructor(f) {
		this.f = f;
	}
	cancel() {
		if(this.f != null) {
			this.f();
			this.f = null;
		}
	}
}
tink_core_SimpleLink.__name__ = "tink.core.SimpleLink";
tink_core_SimpleLink.__interfaces__ = [tink_core_LinkObject];
Object.assign(tink_core_SimpleLink.prototype, {
	__class__: tink_core_SimpleLink
});
class tink_core__$Callback_LinkPair {
	constructor(a,b) {
		this.dissolved = false;
		this.a = a;
		this.b = b;
	}
	cancel() {
		if(!this.dissolved) {
			this.dissolved = true;
			let this1 = this.a;
			if(this1 != null) {
				this1.cancel();
			}
			let this2 = this.b;
			if(this2 != null) {
				this2.cancel();
			}
			this.a = null;
			this.b = null;
		}
	}
}
tink_core__$Callback_LinkPair.__name__ = "tink.core._Callback.LinkPair";
tink_core__$Callback_LinkPair.__interfaces__ = [tink_core_LinkObject];
Object.assign(tink_core__$Callback_LinkPair.prototype, {
	__class__: tink_core__$Callback_LinkPair
});
class tink_core__$Callback_ListCell {
	constructor(cb,list) {
		if(cb == null) {
			throw haxe_Exception.thrown("callback expected but null received");
		}
		this.cb = cb;
		this.list = list;
	}
	invoke(data) {
		if(this.list != null) {
			this.cb(data);
		}
	}
	clear() {
		this.cb = null;
		this.list = null;
	}
	cancel() {
		if(this.list != null) {
			let list = this.list;
			this.cb = null;
			this.list = null;
			if(--list.used <= list.cells.length >> 1) {
				list.compact();
			}
		}
	}
}
tink_core__$Callback_ListCell.__name__ = "tink.core._Callback.ListCell";
tink_core__$Callback_ListCell.__interfaces__ = [tink_core_LinkObject];
Object.assign(tink_core__$Callback_ListCell.prototype, {
	__class__: tink_core__$Callback_ListCell
});
class tink_core_Disposable {
}
tink_core_Disposable.__name__ = "tink.core.Disposable";
tink_core_Disposable.__isInterface__ = true;
Object.assign(tink_core_Disposable.prototype, {
	__class__: tink_core_Disposable
});
class tink_core_OwnedDisposable {
}
tink_core_OwnedDisposable.__name__ = "tink.core.OwnedDisposable";
tink_core_OwnedDisposable.__isInterface__ = true;
tink_core_OwnedDisposable.__interfaces__ = [tink_core_Disposable];
Object.assign(tink_core_OwnedDisposable.prototype, {
	__class__: tink_core_OwnedDisposable
});
class tink_core_SimpleDisposable {
	constructor(dispose) {
		if(tink_core_SimpleDisposable._hx_skip_constructor) {
			return;
		}
		this._hx_constructor(dispose);
	}
	_hx_constructor(dispose) {
		this.disposeHandlers = [];
		this.f = dispose;
	}
	get_disposed() {
		return this.disposeHandlers == null;
	}
	ondispose(d) {
		let _g = this.disposeHandlers;
		if(_g == null) {
			d();
		} else {
			let v = _g;
			v.push(d);
		}
	}
	dispose() {
		let _g = this.disposeHandlers;
		if(_g != null) {
			let v = _g;
			this.disposeHandlers = null;
			let f = this.f;
			this.f = tink_core_SimpleDisposable.noop;
			f();
			let _g1 = 0;
			while(_g1 < v.length) {
				let h = v[_g1];
				++_g1;
				h();
			}
		}
	}
	static noop() {
	}
}
tink_core_SimpleDisposable.__name__ = "tink.core.SimpleDisposable";
tink_core_SimpleDisposable.__interfaces__ = [tink_core_OwnedDisposable];
Object.assign(tink_core_SimpleDisposable.prototype, {
	__class__: tink_core_SimpleDisposable
});
class tink_core_CallbackList extends tink_core_SimpleDisposable {
	constructor(destructive) {
		tink_core_SimpleDisposable._hx_skip_constructor = true;
		super();
		tink_core_SimpleDisposable._hx_skip_constructor = false;
		this._hx_constructor(destructive);
	}
	_hx_constructor(destructive) {
		if(destructive == null) {
			destructive = false;
		}
		this.onfill = function() {
		};
		this.ondrain = function() {
		};
		this.busy = false;
		this.queue = [];
		this.used = 0;
		let _gthis = this;
		super._hx_constructor(function() {
			if(!_gthis.busy) {
				_gthis.destroy();
			}
		});
		this.destructive = destructive;
		this.cells = [];
	}
	get_length() {
		return this.used;
	}
	release() {
		if(--this.used <= this.cells.length >> 1) {
			this.compact();
		}
	}
	destroy() {
		let _g = 0;
		let _g1 = this.cells;
		while(_g < _g1.length) {
			let c = _g1[_g];
			++_g;
			c.cb = null;
			c.list = null;
		}
		this.queue = null;
		this.cells = null;
		if(this.used > 0) {
			this.used = 0;
			let fn = this.ondrain;
			if(tink_core_Callback.depth < 500) {
				tink_core_Callback.depth++;
				fn();
				tink_core_Callback.depth--;
			} else {
				tink_core_Callback.defer(fn);
			}
		}
	}
	drain() {
		let fn = this.ondrain;
		if(tink_core_Callback.depth < 500) {
			tink_core_Callback.depth++;
			fn();
			tink_core_Callback.depth--;
		} else {
			tink_core_Callback.defer(fn);
		}
	}
	add(cb) {
		if(this.disposeHandlers == null) {
			return null;
		}
		let node = new tink_core__$Callback_ListCell(cb,this);
		this.cells.push(node);
		if(this.used++ == 0) {
			let fn = this.onfill;
			if(tink_core_Callback.depth < 500) {
				tink_core_Callback.depth++;
				fn();
				tink_core_Callback.depth--;
			} else {
				tink_core_Callback.defer(fn);
			}
		}
		return node;
	}
	invoke(data) {
		let _gthis = this;
		if(tink_core_Callback.depth < 500) {
			tink_core_Callback.depth++;
			if(_gthis.disposeHandlers != null) {
				if(_gthis.busy) {
					if(_gthis.destructive != true) {
						let _g = _gthis;
						let data1 = data;
						let tmp = function() {
							_g.invoke(data1);
						};
						_gthis.queue.push(tmp);
					}
				} else {
					_gthis.busy = true;
					if(_gthis.destructive) {
						_gthis.dispose();
					}
					let length = _gthis.cells.length;
					let _g = 0;
					let _g1 = length;
					while(_g < _g1) {
						let i = _g++;
						let _this = _gthis.cells[i];
						if(_this.list != null) {
							_this.cb(data);
						}
					}
					_gthis.busy = false;
					if(_gthis.disposeHandlers == null) {
						_gthis.destroy();
					} else {
						if(_gthis.used < _gthis.cells.length) {
							_gthis.compact();
						}
						if(_gthis.queue.length > 0) {
							(_gthis.queue.shift())();
						}
					}
				}
			}
			tink_core_Callback.depth--;
		} else {
			tink_core_Callback.defer(function() {
				if(_gthis.disposeHandlers != null) {
					if(_gthis.busy) {
						if(_gthis.destructive != true) {
							let _g = _gthis;
							let data1 = data;
							let tmp = function() {
								_g.invoke(data1);
							};
							_gthis.queue.push(tmp);
						}
					} else {
						_gthis.busy = true;
						if(_gthis.destructive) {
							_gthis.dispose();
						}
						let length = _gthis.cells.length;
						let _g = 0;
						let _g1 = length;
						while(_g < _g1) {
							let i = _g++;
							let _this = _gthis.cells[i];
							if(_this.list != null) {
								_this.cb(data);
							}
						}
						_gthis.busy = false;
						if(_gthis.disposeHandlers == null) {
							_gthis.destroy();
						} else {
							if(_gthis.used < _gthis.cells.length) {
								_gthis.compact();
							}
							if(_gthis.queue.length > 0) {
								(_gthis.queue.shift())();
							}
						}
					}
				}
			});
		}
	}
	compact() {
		if(this.busy) {
			return;
		} else if(this.used == 0) {
			this.resize(0);
			let fn = this.ondrain;
			if(tink_core_Callback.depth < 500) {
				tink_core_Callback.depth++;
				fn();
				tink_core_Callback.depth--;
			} else {
				tink_core_Callback.defer(fn);
			}
		} else {
			let compacted = 0;
			let _g = 0;
			let _g1 = this.cells.length;
			while(_g < _g1) {
				let i = _g++;
				let _g1 = this.cells[i];
				let _g2 = _g1.list;
				if(_g1.cb != null) {
					let v = _g1;
					if(compacted != i) {
						this.cells[compacted] = v;
					}
					if(++compacted == this.used) {
						break;
					}
				}
			}
			this.resize(this.used);
		}
	}
	resize(length) {
		this.cells.length = length;
	}
	clear() {
		if(this.busy) {
			this.queue.push($bind(this,this.clear));
		}
		let _g = 0;
		let _g1 = this.cells;
		while(_g < _g1.length) {
			let cell = _g1[_g];
			++_g;
			cell.cb = null;
			cell.list = null;
		}
		this.resize(0);
	}
}
tink_core_CallbackList.__name__ = "tink.core.CallbackList";
tink_core_CallbackList.__super__ = tink_core_SimpleDisposable;
Object.assign(tink_core_CallbackList.prototype, {
	__class__: tink_core_CallbackList
});
class tink_core_AlreadyDisposed {
	constructor() {
	}
	get_disposed() {
		return true;
	}
	ondispose(d) {
		d();
	}
	dispose() {
	}
}
tink_core_AlreadyDisposed.__name__ = "tink.core.AlreadyDisposed";
tink_core_AlreadyDisposed.__interfaces__ = [tink_core_OwnedDisposable];
Object.assign(tink_core_AlreadyDisposed.prototype, {
	__class__: tink_core_AlreadyDisposed
});
class tink_core_TypedError {
	constructor(code,message,pos) {
		if(code == null) {
			code = 500;
		}
		this.isTinkError = true;
		this.code = code;
		this.message = message;
		this.pos = pos;
		this.exceptionStack = [];
		this.callStack = [];
	}
	printPos() {
		return this.pos.className + "." + this.pos.methodName + ":" + this.pos.lineNumber;
	}
	toString() {
		let ret = "Error#" + this.code + ": " + this.message;
		if(this.pos != null) {
			ret += " @ " + this.printPos();
		}
		return ret;
	}
	toPromise() {
		return new tink_core__$Future_SyncFuture(new tink_core__$Lazy_LazyConst(tink_core_Outcome.Failure(this)));
	}
	throwSelf() {
		let any = this;
		throw haxe_Exception.thrown(any);
	}
	toJsError() {
		if(((this.data) instanceof Error)) {
			return this.data;
		} else {
			return new tink_core__$Error_TinkError(this);
		}
	}
	static withData(code,message,data,pos) {
		return tink_core_TypedError.typed(code,message,data,pos);
	}
	static typed(code,message,data,pos) {
		let ret = new tink_core_TypedError(code,message,pos);
		ret.data = data;
		return ret;
	}
	static ofJsError(e,pos) {
		return tink_core_TypedError.withData(500,e.message,e,pos);
	}
	static asError(v) {
		if(v != null && v.isTinkError) {
			return v;
		} else {
			return null;
		}
	}
	static catchExceptions(f,report,pos) {
		try {
			return tink_core_Outcome.Success(f());
		} catch( _g ) {
			let ex = haxe_Exception.caught(_g).unwrap();
			let e = tink_core_TypedError.asError(ex);
			let tmp;
			if(e == null) {
				tmp = report == null ? tink_core_TypedError.withData(null,"Unexpected Error",ex,pos) : report(ex);
			} else {
				let e1 = e;
				tmp = e1;
			}
			return tink_core_Outcome.Failure(tmp);
		}
	}
	static reporter(code,message,pos) {
		return function(e) {
			return tink_core_TypedError.withData(code,message,e,pos);
		};
	}
	static rethrow(any) {
		throw haxe_Exception.thrown(any);
	}
	static tryFinally(f,cleanup) {
		try { return f(); } finally { cleanup(); }
		return null;
	}
}
tink_core_TypedError.__name__ = "tink.core.TypedError";
Object.assign(tink_core_TypedError.prototype, {
	__class__: tink_core_TypedError
});
class tink_core_Stack {
	static toString(this1) {
		return "Error stack not available. Compile with -D error_stack.";
	}
}
class tink_core__$Error_TinkError extends Error {
	constructor(e) {
		super();
		this.message = e.message;
		this.data = e;
	}
}
tink_core__$Error_TinkError.__name__ = "tink.core._Error.TinkError";
tink_core__$Error_TinkError.__super__ = Error;
Object.assign(tink_core__$Error_TinkError.prototype, {
	__class__: tink_core__$Error_TinkError
});
class tink_core__$Future_FutureObject {
	constructor() {
		if(tink_core__$Future_FutureObject._hx_skip_constructor) {
			return;
		}
		this._hx_constructor();
	}
	_hx_constructor() {
	}
	getStatus() {
		return tink_core_FutureStatus.NeverEver;
	}
	handle(callback) {
		return null;
	}
	eager() {
	}
}
tink_core__$Future_FutureObject.__name__ = "tink.core._Future.FutureObject";
Object.assign(tink_core__$Future_FutureObject.prototype, {
	__class__: tink_core__$Future_FutureObject
});
class tink_core__$Lazy_Computable {
}
tink_core__$Lazy_Computable.__name__ = "tink.core._Lazy.Computable";
tink_core__$Lazy_Computable.__isInterface__ = true;
Object.assign(tink_core__$Lazy_Computable.prototype, {
	__class__: tink_core__$Lazy_Computable
});
class tink_core__$Lazy_LazyObject {
}
tink_core__$Lazy_LazyObject.__name__ = "tink.core._Lazy.LazyObject";
tink_core__$Lazy_LazyObject.__isInterface__ = true;
tink_core__$Lazy_LazyObject.__interfaces__ = [tink_core__$Lazy_Computable];
Object.assign(tink_core__$Lazy_LazyObject.prototype, {
	__class__: tink_core__$Lazy_LazyObject
});
class tink_core__$Lazy_LazyConst {
	constructor(value) {
		this.value = value;
	}
	isComputed() {
		return true;
	}
	get() {
		return this.value;
	}
	compute() {
	}
	underlying() {
		return null;
	}
}
tink_core__$Lazy_LazyConst.__name__ = "tink.core._Lazy.LazyConst";
tink_core__$Lazy_LazyConst.__interfaces__ = [tink_core__$Lazy_LazyObject];
Object.assign(tink_core__$Lazy_LazyConst.prototype, {
	__class__: tink_core__$Lazy_LazyConst
});
class tink_core__$Future_SyncFuture extends tink_core__$Future_FutureObject {
	constructor(value) {
		super();
		this.value = value;
	}
	getStatus() {
		return tink_core_FutureStatus.Ready(this.value);
	}
	handle(cb) {
		tink_core_Callback.invoke(cb,tink_core_Lazy.get(this.value));
		return null;
	}
	eager() {
		if(!this.value.isComputed()) {
			tink_core_Lazy.get(this.value);
		}
	}
}
tink_core__$Future_SyncFuture.__name__ = "tink.core._Future.SyncFuture";
tink_core__$Future_SyncFuture.__super__ = tink_core__$Future_FutureObject;
Object.assign(tink_core__$Future_SyncFuture.prototype, {
	__class__: tink_core__$Future_SyncFuture
});
class tink_core_Future {
	static never() {
		return tink_core_Future.NEVER_INST;
	}
	static get_status(this1) {
		return this1.getStatus();
	}
	static _new(wakeup) {
		return new tink_core__$Future_SuspendableFuture(wakeup);
	}
	static handle(this1,callback) {
		return this1.handle(callback);
	}
	static eager(this1) {
		this1.eager();
		return this1;
	}
	static noise(this1) {
		if(this1.getStatus()._hx_index == 4) {
			return tink_core_Future.never();
		} else {
			return tink_core_Future.map(this1,function(_) {
				return null;
			});
		}
	}
	static first(this1,that) {
		let _g = this1;
		let _g1 = _g.getStatus();
		switch(_g1._hx_index) {
		case 3:
			let _g2 = _g1.result;
			let _g3 = that.getStatus();
			switch(_g3._hx_index) {
			case 3:
				let _g4 = _g3.result;
				let v = _g;
				return v;
			case 4:
				let v1 = _g;
				return v1;
			default:
				let v2 = _g;
				return v2;
			}
			break;
		case 4:
			let v3 = that;
			return v3;
		default:
			let _g5 = that.getStatus();
			switch(_g5._hx_index) {
			case 3:
				let _g6 = _g5.result;
				let v4 = that;
				return v4;
			case 4:
				let v5 = _g;
				return v5;
			default:
				return new tink_core__$Future_SuspendableFuture(function(fire) {
					return new tink_core__$Callback_LinkPair(this1.handle(fire),that.handle(fire));
				});
			}
		}
	}
	static map(this1,f,gather) {
		let _g = this1.getStatus();
		switch(_g._hx_index) {
		case 3:
			let l = _g.result;
			let this2 = l;
			let f1 = f;
			return new tink_core__$Future_SyncFuture(new tink_core__$Lazy_LazyFunc(function() {
				return f1(this2.get());
			},this2));
		case 4:
			return tink_core_Future.never();
		default:
			return new tink_core__$Future_SuspendableFuture(function(fire) {
				return this1.handle(function(v) {
					fire(f(v));
				});
			});
		}
	}
	static flatMap(this1,next,gather) {
		let _g = this1.getStatus();
		switch(_g._hx_index) {
		case 3:
			let l = _g.result;
			return new tink_core__$Future_SuspendableFuture(function(fire) {
				return next(tink_core_Lazy.get(l)).handle(function(v) {
					fire(v);
				});
			});
		case 4:
			return tink_core_Future.never();
		default:
			return new tink_core__$Future_SuspendableFuture(function($yield) {
				let inner = new tink_core_CallbackLinkRef();
				let outer = this1.handle(function(v) {
					let param = next(v).handle($yield);
					let this1 = inner.link;
					if(this1 != null) {
						this1.cancel();
					}
					inner.link = param;
				});
				return new tink_core__$Callback_LinkPair(outer,inner);
			});
		}
	}
	static swap(this1,v) {
		return tink_core_Future.map(this1,function(_) {
			return v;
		});
	}
	static next(this1,n) {
		return tink_core_Future.flatMap(this1,n);
	}
	static withSideEffect(this1,c) {
		return tink_core_Future.map(this1,function(v) {
			tink_core_Callback.invoke(c,v);
			return v;
		});
	}
	static gather(this1) {
		return this1;
	}
	static merge(this1,that,combine) {
		let _g = this1.getStatus();
		let _g1 = that.getStatus();
		if(_g._hx_index == 4) {
			return tink_core_Future.never();
		} else if(_g1._hx_index == 4) {
			return tink_core_Future.never();
		} else {
			return new tink_core__$Future_SuspendableFuture(function($yield) {
				let check = function(v) {
					let _g = this1.getStatus();
					let _g1 = that.getStatus();
					if(_g._hx_index == 3) {
						if(_g1._hx_index == 3) {
							let b = _g1.result;
							let a = _g.result;
							$yield(combine(tink_core_Lazy.get(a),tink_core_Lazy.get(b)));
						}
					}
				};
				return new tink_core__$Callback_LinkPair(this1.handle(check),that.handle(check));
			});
		}
	}
	static flatten(f) {
		return tink_core_Future.flatMap(f,function(v) {
			return v;
		});
	}
	static ofJsPromise(promise,transformError) {
		return tink_core_Future.irreversible(function(cb) {
			promise.then(function(a) {
				let _g = cb;
				let a1 = tink_core_Outcome.Success(a);
				tink_core_Callback.defer(function() {
					_g(a1);
				});
			},function(e) {
				let cb1 = cb;
				let tmp;
				if(transformError == null) {
					let e1 = e;
					tmp = tink_core_TypedError.withData(500,e1.message,e1,{ fileName : "tink/core/Future.hx", lineNumber : 176, className : "tink.core._Future.Future_Impl_", methodName : "ofJsPromise"});
				} else {
					let f = transformError;
					tmp = f(e);
				}
				cb1(tink_core_Outcome.Failure(tmp));
			});
		});
	}
	static fromJsPromise(promise) {
		return tink_core_Future.ofJsPromise(promise);
	}
	static neverToAny(l) {
		return l;
	}
	static ofAny(v) {
		return new tink_core__$Future_SyncFuture(new tink_core__$Lazy_LazyConst(v));
	}
	static asPromise(s) {
		return s;
	}
	static ofMany(futures,gather) {
		return tink_core_Future.inSequence(futures);
	}
	static inParallel(futures,concurrency) {
		return tink_core_Future.many(futures,concurrency);
	}
	static inSequence(futures) {
		return tink_core_Future.many(futures,1);
	}
	static many(a,concurrency) {
		return tink_core_Future.processMany(a,concurrency,tink_core_Outcome.Success,function(o) {
			return tink_core_OutcomeTools.orNull(o);
		});
	}
	static processMany(a,concurrency,fn,lift) {
		if(a.length == 0) {
			return new tink_core__$Future_SyncFuture(new tink_core__$Lazy_LazyConst(lift(tink_core_Outcome.Success([]))));
		} else {
			return new tink_core__$Future_SuspendableFuture(function($yield) {
				let links = [];
				let _g = [];
				let _g1 = 0;
				while(_g1 < a.length) {
					let x = a[_g1];
					++_g1;
					_g.push(null);
				}
				let ret = _g;
				let index = 0;
				let pending = 0;
				let done = false;
				let concurrency1;
				if(concurrency == null) {
					concurrency1 = a.length;
				} else {
					let v = concurrency;
					concurrency1 = v < 1 ? 1 : v > a.length ? a.length : v;
				}
				let fireWhenReady = function() {
					if(index == ret.length) {
						if(pending == 0) {
							let v = lift(tink_core_Outcome.Success(ret));
							done = true;
							$yield(v);
							return true;
						} else {
							return false;
						}
					} else {
						return false;
					}
				};
				let step = null;
				step = function() {
					if(!done && !fireWhenReady()) {
						while(index < ret.length) {
							index += 1;
							let index1 = index - 1;
							let p = a[index1];
							let check = function(o) {
								let _g = fn(o);
								switch(_g._hx_index) {
								case 0:
									let v = _g.data;
									ret[index1] = v;
									fireWhenReady();
									break;
								case 1:
									let e = _g.failure;
									let _g1 = 0;
									while(_g1 < links.length) {
										let l = links[_g1];
										++_g1;
										if(l != null) {
											l.cancel();
										}
									}
									let v1 = lift(tink_core_Outcome.Failure(e));
									done = true;
									$yield(v1);
									break;
								}
							};
							let _g = p.getStatus();
							if(_g._hx_index == 3) {
								let _hx_tmp;
								_hx_tmp = tink_core_Lazy.get(_g.result);
								let v = _hx_tmp;
								check(v);
								if(!done) {
									continue;
								}
							} else {
								pending += 1;
								links.push(p.handle(function(o) {
									pending -= 1;
									check(o);
									if(!done) {
										step();
									}
								}));
							}
							break;
						}
					}
				};
				let _g2 = 0;
				let _g3 = concurrency1;
				while(_g2 < _g3) {
					let i = _g2++;
					step();
				}
				return tink_core_CallbackLink.fromMany(links);
			});
		}
	}
	static lazy(l) {
		return new tink_core__$Future_SyncFuture(l);
	}
	static sync(v) {
		return new tink_core__$Future_SyncFuture(new tink_core__$Lazy_LazyConst(v));
	}
	static isFuture(maybeFuture) {
		return ((maybeFuture) instanceof tink_core__$Future_FutureObject);
	}
	static async(init,lazy) {
		if(lazy == null) {
			lazy = false;
		}
		let ret = tink_core_Future.irreversible(init);
		if(lazy) {
			return ret;
		} else {
			ret.eager();
			return ret;
		}
	}
	static irreversible(init) {
		return new tink_core__$Future_SuspendableFuture(function($yield) {
			init($yield);
			return null;
		});
	}
	static or(a,b) {
		return tink_core_Future.first(a,b);
	}
	static either(a,b) {
		return tink_core_Future.first(tink_core_Future.map(a,haxe_ds_Either.Left),tink_core_Future.map(b,haxe_ds_Either.Right));
	}
	static and(a,b) {
		return tink_core_Future.merge(a,b,function(a,b) {
			return new tink_core_MPair(a,b);
		});
	}
	static _tryFailingFlatMap(f,map) {
		return tink_core_Future.flatMap(f,function(o) {
			switch(o._hx_index) {
			case 0:
				let d = o.data;
				return map(d);
			case 1:
				let f = o.failure;
				return new tink_core__$Future_SyncFuture(new tink_core__$Lazy_LazyConst(tink_core_Outcome.Failure(f)));
			}
		});
	}
	static _tryFlatMap(f,map) {
		return tink_core_Future.flatMap(f,function(o) {
			switch(o._hx_index) {
			case 0:
				let d = o.data;
				return tink_core_Future.map(map(d),tink_core_Outcome.Success);
			case 1:
				let f = o.failure;
				return new tink_core__$Future_SyncFuture(new tink_core__$Lazy_LazyConst(tink_core_Outcome.Failure(f)));
			}
		});
	}
	static _tryFailingMap(f,map) {
		return tink_core_Future.map(f,function(o) {
			return tink_core_OutcomeTools.flatMap(o,tink_core__$Outcome_OutcomeMapper.withSameError(map));
		});
	}
	static _tryMap(f,map) {
		return tink_core_Future.map(f,function(o) {
			return tink_core_OutcomeTools.map(o,map);
		});
	}
	static _flatMap(f,map) {
		return tink_core_Future.flatMap(f,map);
	}
	static _map(f,map) {
		return tink_core_Future.map(f,map);
	}
	static trigger() {
		return new tink_core_FutureTrigger();
	}
	static delay(ms,value) {
		let this1 = tink_core_Future.irreversible(function(cb) {
			haxe_Timer.delay(function() {
				cb(tink_core_Lazy.get(value));
			},ms);
		});
		this1.eager();
		return this1;
	}
}
var tink_core_FutureStatus = $hxEnums["tink.core.FutureStatus"] = { __ename__:true,__constructs__:null
	,Suspended: {_hx_name:"Suspended",_hx_index:0,__enum__:"tink.core.FutureStatus",toString:$estr}
	,Awaited: {_hx_name:"Awaited",_hx_index:1,__enum__:"tink.core.FutureStatus",toString:$estr}
	,EagerlyAwaited: {_hx_name:"EagerlyAwaited",_hx_index:2,__enum__:"tink.core.FutureStatus",toString:$estr}
	,Ready: ($_=function(result) { return {_hx_index:3,result:result,__enum__:"tink.core.FutureStatus",toString:$estr}; },$_._hx_name="Ready",$_.__params__ = ["result"],$_)
	,NeverEver: {_hx_name:"NeverEver",_hx_index:4,__enum__:"tink.core.FutureStatus",toString:$estr}
};
tink_core_FutureStatus.__constructs__ = [tink_core_FutureStatus.Suspended,tink_core_FutureStatus.Awaited,tink_core_FutureStatus.EagerlyAwaited,tink_core_FutureStatus.Ready,tink_core_FutureStatus.NeverEver];
class tink_core_FutureTrigger extends tink_core__$Future_FutureObject {
	constructor() {
		tink_core__$Future_FutureObject._hx_skip_constructor = true;
		super();
		tink_core__$Future_FutureObject._hx_skip_constructor = false;
		this._hx_constructor();
	}
	_hx_constructor() {
		this.status = tink_core_FutureStatus.Awaited;
		super._hx_constructor();
		this.list = new tink_core_CallbackList(true);
	}
	getStatus() {
		return this.status;
	}
	handle(callback) {
		let _g = this.status;
		if(_g._hx_index == 3) {
			let result = _g.result;
			tink_core_Callback.invoke(callback,tink_core_Lazy.get(result));
			return null;
		} else {
			let v = _g;
			let _this = this.list;
			if(_this.disposeHandlers == null) {
				return null;
			} else {
				let node = new tink_core__$Callback_ListCell(callback,_this);
				_this.cells.push(node);
				if(_this.used++ == 0) {
					let fn = _this.onfill;
					if(tink_core_Callback.depth < 500) {
						tink_core_Callback.depth++;
						fn();
						tink_core_Callback.depth--;
					} else {
						tink_core_Callback.defer(fn);
					}
				}
				return node;
			}
		}
	}
	asFuture() {
		return this;
	}
	trigger(result) {
		let _g = this.status;
		if(_g._hx_index == 3) {
			let _g1 = _g.result;
			return false;
		} else {
			this.status = tink_core_FutureStatus.Ready(new tink_core__$Lazy_LazyConst(result));
			this.list.invoke(result);
			return true;
		}
	}
}
tink_core_FutureTrigger.__name__ = "tink.core.FutureTrigger";
tink_core_FutureTrigger.__super__ = tink_core__$Future_FutureObject;
Object.assign(tink_core_FutureTrigger.prototype, {
	__class__: tink_core_FutureTrigger
});
class tink_core_JsPromiseTools {
	static toSurprise(promise) {
		return tink_core_Future.ofJsPromise(promise);
	}
	static toPromise(promise) {
		return tink_core_Future.ofJsPromise(promise);
	}
}
tink_core_JsPromiseTools.__name__ = "tink.core.JsPromiseTools";
class tink_core__$Future_SuspendableFuture extends tink_core__$Future_FutureObject {
	constructor(wakeup) {
		tink_core__$Future_FutureObject._hx_skip_constructor = true;
		super();
		tink_core__$Future_FutureObject._hx_skip_constructor = false;
		this._hx_constructor(wakeup);
	}
	_hx_constructor(wakeup) {
		this.status = tink_core_FutureStatus.Suspended;
		super._hx_constructor();
		this.wakeup = wakeup;
		this.callbacks = new tink_core_CallbackList(true);
		let _gthis = this;
		this.callbacks.ondrain = function() {
			if(_gthis.status == tink_core_FutureStatus.Awaited) {
				_gthis.status = tink_core_FutureStatus.Suspended;
				let this1 = _gthis.link;
				if(this1 != null) {
					this1.cancel();
				}
				_gthis.link = null;
			}
		};
		this.callbacks.onfill = function() {
			if(_gthis.status == tink_core_FutureStatus.Suspended) {
				_gthis.status = tink_core_FutureStatus.Awaited;
				_gthis.arm();
			}
		};
	}
	getStatus() {
		return this.status;
	}
	trigger(value) {
		let _g = this.status;
		if(_g._hx_index == 3) {
			let _g1 = _g.result;
		} else {
			this.status = tink_core_FutureStatus.Ready(new tink_core__$Lazy_LazyConst(value));
			let link = this.link;
			this.link = null;
			this.wakeup = null;
			this.callbacks.invoke(value);
			if(link != null) {
				link.cancel();
			}
		}
	}
	handle(callback) {
		let _g = this.status;
		if(_g._hx_index == 3) {
			let result = _g.result;
			tink_core_Callback.invoke(callback,tink_core_Lazy.get(result));
			return null;
		} else {
			let _this = this.callbacks;
			if(_this.disposeHandlers == null) {
				return null;
			} else {
				let node = new tink_core__$Callback_ListCell(callback,_this);
				_this.cells.push(node);
				if(_this.used++ == 0) {
					let fn = _this.onfill;
					if(tink_core_Callback.depth < 500) {
						tink_core_Callback.depth++;
						fn();
						tink_core_Callback.depth--;
					} else {
						tink_core_Callback.defer(fn);
					}
				}
				return node;
			}
		}
	}
	arm() {
		let _gthis = this;
		this.link = this.wakeup(function(x) {
			_gthis.trigger(x);
		});
	}
	eager() {
		switch(this.status._hx_index) {
		case 0:
			this.status = tink_core_FutureStatus.EagerlyAwaited;
			this.arm();
			break;
		case 1:
			this.status = tink_core_FutureStatus.EagerlyAwaited;
			break;
		default:
		}
	}
}
tink_core__$Future_SuspendableFuture.__name__ = "tink.core._Future.SuspendableFuture";
tink_core__$Future_SuspendableFuture.__super__ = tink_core__$Future_FutureObject;
Object.assign(tink_core__$Future_SuspendableFuture.prototype, {
	__class__: tink_core__$Future_SuspendableFuture
});
class tink_core_Lazy {
	static get_computed(this1) {
		return this1.isComputed();
	}
	static get(this1) {
		this1.compute();
		return this1.get();
	}
	static fromNoise(l) {
		return l;
	}
	static ofFunc(f) {
		return new tink_core__$Lazy_LazyFunc(f);
	}
	static map(this1,f) {
		return new tink_core__$Lazy_LazyFunc(function() {
			return f(this1.get());
		},this1);
	}
	static flatMap(this1,f) {
		return new tink_core__$Lazy_LazyFunc(function() {
			return tink_core_Lazy.get(f(this1.get()));
		},this1);
	}
	static ofConst(c) {
		return new tink_core__$Lazy_LazyConst(c);
	}
}
class tink_core__$Lazy_LazyFunc {
	constructor(f,from) {
		this.f = f;
		this.from = from;
	}
	underlying() {
		return this.from;
	}
	isComputed() {
		return this.f == null;
	}
	get() {
		return this.result;
	}
	compute() {
		let _g = this.f;
		if(_g != null) {
			let v = _g;
			this.f = null;
			let _g1 = this.from;
			if(_g1 != null) {
				let cur = _g1;
				this.from = null;
				let stack = [];
				while(cur != null && !cur.isComputed()) {
					stack.push(cur);
					cur = cur.underlying();
				}
				stack.reverse();
				let _g = 0;
				while(_g < stack.length) {
					let c = stack[_g];
					++_g;
					c.compute();
				}
			}
			this.result = v();
		}
	}
}
tink_core__$Lazy_LazyFunc.__name__ = "tink.core._Lazy.LazyFunc";
tink_core__$Lazy_LazyFunc.__interfaces__ = [tink_core__$Lazy_LazyObject];
Object.assign(tink_core__$Lazy_LazyFunc.prototype, {
	__class__: tink_core__$Lazy_LazyFunc
});
class tink_core_NamedWith {
	constructor(name,value) {
		this.name = name;
		this.value = value;
	}
}
tink_core_NamedWith.__name__ = "tink.core.NamedWith";
Object.assign(tink_core_NamedWith.prototype, {
	__class__: tink_core_NamedWith
});
class tink_core_Noise {
	static ofAny(t) {
		return null;
	}
}
class tink_core_OptionTools {
	static force(o,pos) {
		if(o._hx_index == 0) {
			let v = o.v;
			return v;
		} else {
			throw haxe_Exception.thrown(new tink_core_TypedError(404,"Some value expected but none found",pos));
		}
	}
	static sure(o,pos) {
		if(o._hx_index == 0) {
			let v = o.v;
			return v;
		} else {
			throw haxe_Exception.thrown(new tink_core_TypedError(404,"Some value expected but none found",pos));
		}
	}
	static toOutcome(o,pos) {
		switch(o._hx_index) {
		case 0:
			let value = o.v;
			return tink_core_Outcome.Success(value);
		case 1:
			return tink_core_Outcome.Failure(new tink_core_TypedError(404,"Some value expected but none found in " + pos.fileName + "@line " + pos.lineNumber,{ fileName : "tink/core/Option.hx", lineNumber : 31, className : "tink.core.OptionTools", methodName : "toOutcome"}));
		}
	}
	static or(o,l) {
		if(o._hx_index == 0) {
			let v = o.v;
			return v;
		} else {
			return tink_core_Lazy.get(l);
		}
	}
	static orTry(o,fallback) {
		if(o._hx_index == 0) {
			let v = o.v;
			return o;
		} else {
			return tink_core_Lazy.get(fallback);
		}
	}
	static orNull(o) {
		if(o._hx_index == 0) {
			let v = o.v;
			return v;
		} else {
			return null;
		}
	}
	static filter(o,f) {
		if(o._hx_index == 0) {
			if(f(o.v) == false) {
				return haxe_ds_Option.None;
			} else {
				return o;
			}
		} else {
			return o;
		}
	}
	static satisfies(o,f) {
		if(o._hx_index == 0) {
			let v = o.v;
			return f(v);
		} else {
			return false;
		}
	}
	static equals(o,v) {
		if(o._hx_index == 0) {
			let v1 = o.v;
			return v1 == v;
		} else {
			return false;
		}
	}
	static map(o,f) {
		if(o._hx_index == 0) {
			let v = o.v;
			return haxe_ds_Option.Some(f(v));
		} else {
			return haxe_ds_Option.None;
		}
	}
	static flatMap(o,f) {
		if(o._hx_index == 0) {
			let v = o.v;
			return f(v);
		} else {
			return haxe_ds_Option.None;
		}
	}
	static iterator(o) {
		return new tink_core_OptionIter(o);
	}
	static toArray(o) {
		if(o._hx_index == 0) {
			let v = o.v;
			return [v];
		} else {
			return [];
		}
	}
}
tink_core_OptionTools.__name__ = "tink.core.OptionTools";
class tink_core_OptionIter {
	constructor(o) {
		this.alive = true;
		if(o._hx_index == 0) {
			let v = o.v;
			this.value = v;
		} else {
			this.alive = false;
		}
	}
	hasNext() {
		return this.alive;
	}
	next() {
		this.alive = false;
		return this.value;
	}
}
tink_core_OptionIter.__name__ = "tink.core.OptionIter";
Object.assign(tink_core_OptionIter.prototype, {
	__class__: tink_core_OptionIter
});
var tink_core_Outcome = $hxEnums["tink.core.Outcome"] = { __ename__:true,__constructs__:null
	,Success: ($_=function(data) { return {_hx_index:0,data:data,__enum__:"tink.core.Outcome",toString:$estr}; },$_._hx_name="Success",$_.__params__ = ["data"],$_)
	,Failure: ($_=function(failure) { return {_hx_index:1,failure:failure,__enum__:"tink.core.Outcome",toString:$estr}; },$_._hx_name="Failure",$_.__params__ = ["failure"],$_)
};
tink_core_Outcome.__constructs__ = [tink_core_Outcome.Success,tink_core_Outcome.Failure];
class tink_core_OutcomeTools {
	static sure(outcome) {
		switch(outcome._hx_index) {
		case 0:
			let data = outcome.data;
			return data;
		case 1:
			let failure = outcome.failure;
			let _g = tink_core_TypedError.asError(failure);
			if(_g == null) {
				throw haxe_Exception.thrown(failure);
			} else {
				let e = _g;
				return e.throwSelf();
			}
			break;
		}
	}
	static toOption(outcome) {
		switch(outcome._hx_index) {
		case 0:
			let data = outcome.data;
			return haxe_ds_Option.Some(data);
		case 1:
			let _g = outcome.failure;
			return haxe_ds_Option.None;
		}
	}
	static orNull(outcome) {
		switch(outcome._hx_index) {
		case 0:
			let data = outcome.data;
			return data;
		case 1:
			let _g = outcome.failure;
			return null;
		}
	}
	static orUse(outcome,fallback) {
		return tink_core_OutcomeTools.or(outcome,fallback);
	}
	static or(outcome,fallback) {
		switch(outcome._hx_index) {
		case 0:
			let data = outcome.data;
			return data;
		case 1:
			let _g = outcome.failure;
			return tink_core_Lazy.get(fallback);
		}
	}
	static orTry(outcome,fallback) {
		switch(outcome._hx_index) {
		case 0:
			let _g = outcome.data;
			return outcome;
		case 1:
			let _g1 = outcome.failure;
			return tink_core_Lazy.get(fallback);
		}
	}
	static equals(outcome,to) {
		switch(outcome._hx_index) {
		case 0:
			let data = outcome.data;
			return data == to;
		case 1:
			let _g = outcome.failure;
			return false;
		}
	}
	static map(outcome,transform) {
		switch(outcome._hx_index) {
		case 0:
			let a = outcome.data;
			return tink_core_Outcome.Success(transform(a));
		case 1:
			let f = outcome.failure;
			return tink_core_Outcome.Failure(f);
		}
	}
	static isSuccess(outcome) {
		if(outcome._hx_index == 0) {
			let _g = outcome.data;
			return true;
		} else {
			return false;
		}
	}
	static flatMap(o,mapper) {
		return tink_core__$Outcome_OutcomeMapper.apply(mapper,o);
	}
	static swap(outcome,v) {
		switch(outcome._hx_index) {
		case 0:
			let a = outcome.data;
			return tink_core_Outcome.Success(v);
		case 1:
			let f = outcome.failure;
			return tink_core_Outcome.Failure(f);
		}
	}
	static next(outcome,f) {
		switch(outcome._hx_index) {
		case 0:
			let v = outcome.data;
			return f(v);
		case 1:
			let e = outcome.failure;
			return new tink_core__$Future_SyncFuture(new tink_core__$Lazy_LazyConst(tink_core_Outcome.Failure(e)));
		}
	}
	static attempt(f,report) {
		try {
			return tink_core_Outcome.Success(f());
		} catch( _g ) {
			let e = haxe_Exception.caught(_g).unwrap();
			return tink_core_Outcome.Failure(report(e));
		}
	}
	static satisfies(o,f) {
		if(o._hx_index == 0) {
			let d = o.data;
			return f(d);
		} else {
			return false;
		}
	}
	static flatten(o) {
		switch(o._hx_index) {
		case 0:
			let _g = o.data;
			switch(_g._hx_index) {
			case 0:
				let d = _g.data;
				return tink_core_Outcome.Success(d);
			case 1:
				let f = _g.failure;
				return tink_core_Outcome.Failure(f);
			}
			break;
		case 1:
			let f1 = o.failure;
			return tink_core_Outcome.Failure(f1);
		}
	}
}
tink_core_OutcomeTools.__name__ = "tink.core.OutcomeTools";
class tink_core__$Outcome_OutcomeMapper {
	static _new(f) {
		return { f : f};
	}
	static apply(this1,o) {
		return this1.f(o);
	}
	static withSameError(f) {
		return tink_core__$Outcome_OutcomeMapper._new(function(o) {
			switch(o._hx_index) {
			case 0:
				let d = o.data;
				return f(d);
			case 1:
				let f1 = o.failure;
				return tink_core_Outcome.Failure(f1);
			}
		});
	}
	static withEitherError(f) {
		return tink_core__$Outcome_OutcomeMapper._new(function(o) {
			switch(o._hx_index) {
			case 0:
				let d = o.data;
				let _g = f(d);
				switch(_g._hx_index) {
				case 0:
					let d1 = _g.data;
					return tink_core_Outcome.Success(d1);
				case 1:
					let f1 = _g.failure;
					return tink_core_Outcome.Failure(haxe_ds_Either.Right(f1));
				}
				break;
			case 1:
				let f2 = o.failure;
				return tink_core_Outcome.Failure(haxe_ds_Either.Left(f2));
			}
		});
	}
}
class tink_core_Pair {
	static _new(a,b) {
		return new tink_core_MPair(a,b);
	}
	static get_a(this1) {
		return this1.a;
	}
	static get_b(this1) {
		return this1.b;
	}
	static toBool(this1) {
		return this1 != null;
	}
	static isNil(this1) {
		return this1 == null;
	}
	static nil() {
		return null;
	}
}
class tink_core_MPair {
	constructor(a,b) {
		this.a = a;
		this.b = b;
	}
}
tink_core_MPair.__name__ = "tink.core.MPair";
Object.assign(tink_core_MPair.prototype, {
	__class__: tink_core_MPair
});
class tink_core_ProgressValue {
	static _new(value,total) {
		return new tink_core_MPair(value,total);
	}
	static normalize(this1) {
		let o = this1.b;
		if(o._hx_index == 0) {
			let v = o.v;
			return haxe_ds_Option.Some(this1.a / v);
		} else {
			return haxe_ds_Option.None;
		}
	}
	static get_value(this1) {
		return this1.a;
	}
	static get_total(this1) {
		return this1.b;
	}
}
class tink_core_Progress {
	static listen(this1,cb) {
		return this1.progressed.listen(cb);
	}
	static handle(this1,cb) {
		return this1.result.handle(cb);
	}
	static trigger() {
		return new tink_core_ProgressTrigger();
	}
	static make(f) {
		return new tink_core__$Progress_SuspendableProgress(function(fire) {
			return f(function(value,total) {
				fire(tink_core_ProgressStatus.InProgress(new tink_core_MPair(value,total)));
			},function(result) {
				fire(tink_core_ProgressStatus.Finished(result));
			});
		});
	}
	static map(this1,f) {
		return new tink_core__$Progress_ProgressObject(tink_core_Signal.map(this1.changed,function(s) {
			return tink_core_ProgressStatusTools.map(s,f);
		}),function() {
			return tink_core_ProgressStatusTools.map(this1.getStatus(),f);
		});
	}
	static asFuture(this1) {
		return this1.result;
	}
	static promise(v) {
		return new tink_core__$Progress_SuspendableProgress(function(fire) {
			let inner = new tink_core_CallbackLinkRef();
			return new tink_core__$Callback_LinkPair(v.handle(function(o) {
				switch(o._hx_index) {
				case 0:
					let p = o.data;
					let param = p.changed.listen(function(s) {
						fire(tink_core_ProgressStatusTools.map(s,tink_core_Outcome.Success));
					});
					let this1 = inner.link;
					if(this1 != null) {
						this1.cancel();
					}
					inner.link = param;
					break;
				case 1:
					let e = o.failure;
					fire(tink_core_ProgressStatus.Finished(tink_core_Outcome.Failure(e)));
					break;
				}
			}),inner);
		});
	}
	static flatten(v) {
		return tink_core_Progress.map(tink_core_Progress.promise(v),function(o) {
			switch(o._hx_index) {
			case 0:
				let _g = o.data;
				switch(_g._hx_index) {
				case 0:
					let v = _g.data;
					return tink_core_Outcome.Success(v);
				case 1:
					let e = _g.failure;
					return tink_core_Outcome.Failure(e);
				}
				break;
			case 1:
				let e1 = o.failure;
				return tink_core_Outcome.Failure(e1);
			}
		});
	}
	static future(v) {
		return new tink_core__$Progress_SuspendableProgress(function(fire) {
			let inner = new tink_core_CallbackLinkRef();
			return new tink_core__$Callback_LinkPair(v.handle(function(p) {
				let param = p.changed.listen(fire);
				let this1 = inner.link;
				if(this1 != null) {
					this1.cancel();
				}
				inner.link = param;
			}),inner);
		});
	}
	static next(this1,f) {
		return tink_core_Future.flatMap(this1.result,f);
	}
}
class tink_core__$Progress_ProgressObject {
	constructor(changed,getStatus) {
		if(tink_core__$Progress_ProgressObject._hx_skip_constructor) {
			return;
		}
		this._hx_constructor(changed,getStatus);
	}
	_hx_constructor(changed,getStatus) {
		this.changed = changed;
		this.progressed = new tink_core__$Signal_Suspendable(function(fire) {
			return changed.listen(function(s) {
				if(s._hx_index == 0) {
					let v = s.v;
					fire(v);
				}
			});
		},null);
		this.getStatus = getStatus;
		this.result = new tink_core__$Future_SuspendableFuture(function(fire) {
			let _g = getStatus();
			if(_g._hx_index == 1) {
				let v = _g.v;
				fire(v);
				return null;
			} else {
				return changed.listen(function(s) {
					if(s._hx_index == 1) {
						let v = s.v;
						fire(v);
					}
				});
			}
		});
	}
	get_status() {
		return this.getStatus();
	}
}
tink_core__$Progress_ProgressObject.__name__ = "tink.core._Progress.ProgressObject";
Object.assign(tink_core__$Progress_ProgressObject.prototype, {
	__class__: tink_core__$Progress_ProgressObject
});
class tink_core__$Progress_SuspendableProgress extends tink_core__$Progress_ProgressObject {
	constructor(wakeup,status) {
		if(status == null) {
			status = tink_core_ProgressStatus.InProgress(tink_core_ProgressValue.ZERO);
		}
		let disposable = tink_core_AlreadyDisposed.INST;
		let changed;
		switch(status._hx_index) {
		case 0:
			let _g = status.v;
			changed = new tink_core__$Signal_Suspendable(function(fire) {
				return wakeup(function(s) {
					status = s;
					fire(status);
				});
			},function(d) {
				disposable = d;
			});
			break;
		case 1:
			let _g1 = status.v;
			changed = tink_core_Signal.dead();
			break;
		}
		super(changed,function() {
			return status;
		});
	}
	noop(_,_1) {
		return null;
	}
}
tink_core__$Progress_SuspendableProgress.__name__ = "tink.core._Progress.SuspendableProgress";
tink_core__$Progress_SuspendableProgress.__super__ = tink_core__$Progress_ProgressObject;
Object.assign(tink_core__$Progress_SuspendableProgress.prototype, {
	__class__: tink_core__$Progress_SuspendableProgress
});
class tink_core_ProgressTrigger extends tink_core__$Progress_ProgressObject {
	constructor(status) {
		tink_core__$Progress_ProgressObject._hx_skip_constructor = true;
		super();
		tink_core__$Progress_ProgressObject._hx_skip_constructor = false;
		this._hx_constructor(status);
	}
	_hx_constructor(status) {
		this._changed = null;
		if(status == null) {
			status = tink_core_ProgressStatus.InProgress(tink_core_ProgressValue.ZERO);
			this._status = status;
		}
		let _gthis = this;
		let tmp;
		if(status == null) {
			tmp = false;
		} else if(status._hx_index == 1) {
			let _g = status.v;
			tmp = true;
		} else {
			tmp = false;
		}
		super._hx_constructor(tmp ? tink_core_Signal.dead() : this._changed = tink_core_Signal.trigger(),function() {
			return _gthis._status;
		});
	}
	asProgress() {
		return this;
	}
	progress(v,total) {
		let _g = this._status;
		let tmp;
		if(_g._hx_index == 1) {
			let _g1 = _g.v;
			tmp = true;
		} else {
			tmp = false;
		}
		if(!tmp) {
			let _this = this._changed;
			let this1 = new tink_core_MPair(v,total);
			_this.handlers.invoke(this._status = tink_core_ProgressStatus.InProgress(this1));
		}
	}
	finish(v) {
		let _g = this._status;
		let tmp;
		if(_g._hx_index == 1) {
			let _g1 = _g.v;
			tmp = true;
		} else {
			tmp = false;
		}
		if(!tmp) {
			this._changed.handlers.invoke(this._status = tink_core_ProgressStatus.Finished(v));
		}
	}
}
tink_core_ProgressTrigger.__name__ = "tink.core.ProgressTrigger";
tink_core_ProgressTrigger.__super__ = tink_core__$Progress_ProgressObject;
Object.assign(tink_core_ProgressTrigger.prototype, {
	__class__: tink_core_ProgressTrigger
});
class tink_core_UnitInterval {
	static toPercentageString(this1,dp) {
		let m = Math.pow(10,dp);
		let v = Math.round(this1 * m * 100) / m;
		let s = v == null ? "null" : "" + v;
		let _g = s.indexOf(".");
		if(_g == -1) {
			return s + "." + StringTools.lpad("","0",dp) + "%";
		} else {
			let i = _g;
			if(s.length - i > dp) {
				return HxOverrides.substr(s,0,dp + i + 1) + "%";
			} else {
				let i = _g;
				return StringTools.rpad(s,"0",i + dp + 1) + "%";
			}
		}
	}
}
var tink_core_ProgressStatus = $hxEnums["tink.core.ProgressStatus"] = { __ename__:true,__constructs__:null
	,InProgress: ($_=function(v) { return {_hx_index:0,v:v,__enum__:"tink.core.ProgressStatus",toString:$estr}; },$_._hx_name="InProgress",$_.__params__ = ["v"],$_)
	,Finished: ($_=function(v) { return {_hx_index:1,v:v,__enum__:"tink.core.ProgressStatus",toString:$estr}; },$_._hx_name="Finished",$_.__params__ = ["v"],$_)
};
tink_core_ProgressStatus.__constructs__ = [tink_core_ProgressStatus.InProgress,tink_core_ProgressStatus.Finished];
class tink_core_ProgressStatusTools {
	static map(p,f) {
		switch(p._hx_index) {
		case 0:
			let v = p.v;
			return tink_core_ProgressStatus.InProgress(v);
		case 1:
			let v1 = p.v;
			return tink_core_ProgressStatus.Finished(f(v1));
		}
	}
}
tink_core_ProgressStatusTools.__name__ = "tink.core.ProgressStatusTools";
class tink_core_TotalTools {
	static eq(a,b) {
		switch(a._hx_index) {
		case 0:
			if(b._hx_index == 0) {
				let t2 = b.v;
				let t1 = a.v;
				return t1 == t2;
			} else {
				return false;
			}
			break;
		case 1:
			if(b._hx_index == 1) {
				return true;
			} else {
				return false;
			}
			break;
		}
	}
}
tink_core_TotalTools.__name__ = "tink.core.TotalTools";
class tink_core_ProgressTools {
	static asPromise(p) {
		return p.result;
	}
}
tink_core_ProgressTools.__name__ = "tink.core.ProgressTools";
class tink_core_Promise {
	static never() {
		return tink_core_Future.never();
	}
	static _new(f) {
		return new tink_core__$Future_SuspendableFuture(function(cb) {
			return f(function(v) {
				cb(tink_core_Outcome.Success(v));
			},function(e) {
				cb(tink_core_Outcome.Failure(e));
			});
		});
	}
	static eager(this1) {
		this1.eager();
		return this1;
	}
	static map(this1,f) {
		return tink_core_Future.map(this1,f);
	}
	static flatMap(this1,f) {
		return tink_core_Future.flatMap(this1,f);
	}
	static tryRecover(this1,f) {
		return tink_core_Future.flatMap(this1,function(o) {
			switch(o._hx_index) {
			case 0:
				let d = o.data;
				return new tink_core__$Future_SyncFuture(new tink_core__$Lazy_LazyConst(o));
			case 1:
				let e = o.failure;
				return f(e);
			}
		});
	}
	static recover(this1,f) {
		return tink_core_Future.flatMap(this1,function(o) {
			switch(o._hx_index) {
			case 0:
				let d = o.data;
				return new tink_core__$Future_SyncFuture(new tink_core__$Lazy_LazyConst(d));
			case 1:
				let e = o.failure;
				return f(e);
			}
		});
	}
	static mapError(this1,f) {
		return tink_core_Future.map(this1,function(o) {
			switch(o._hx_index) {
			case 0:
				let _g = o.data;
				return o;
			case 1:
				let e = o.failure;
				return tink_core_Outcome.Failure(f(e));
			}
		});
	}
	static withSideEffect(this1,c) {
		let c1 = function(o) {
			if(o._hx_index == 0) {
				let data = o.data;
				tink_core_Callback.invoke(c,data);
			}
		};
		return tink_core_Future.map(this1,function(v) {
			tink_core_Callback.invoke(c1,v);
			return v;
		});
	}
	static handle(this1,cb) {
		return this1.handle(cb);
	}
	static noise(this1) {
		if(this1.getStatus()._hx_index == 4) {
			return tink_core_Promise.never();
		} else {
			return tink_core_Promise.next(this1,function(v) {
				return new tink_core__$Future_SyncFuture(new tink_core__$Lazy_LazyConst(tink_core_Outcome.Success(null)));
			});
		}
	}
	static isSuccess(this1) {
		return tink_core_Future.map(this1,function(o) {
			return tink_core_OutcomeTools.isSuccess(o);
		});
	}
	static next(this1,f,gather) {
		return tink_core_Future.flatMap(this1,function(o) {
			switch(o._hx_index) {
			case 0:
				let d = o.data;
				return f(d);
			case 1:
				let f1 = o.failure;
				return new tink_core__$Future_SyncFuture(new tink_core__$Lazy_LazyConst(tink_core_Outcome.Failure(f1)));
			}
		});
	}
	static swap(this1,v) {
		return tink_core_Promise.next(this1,function(_) {
			return new tink_core__$Future_SyncFuture(new tink_core__$Lazy_LazyConst(tink_core_Outcome.Success(v)));
		});
	}
	static swapError(this1,e) {
		return tink_core_Promise.mapError(this1,function(_) {
			return e;
		});
	}
	static merge(this1,other,merger,gather) {
		return tink_core_Future.flatMap(tink_core_Future.merge(this1,other,function(a,b) {
			switch(a._hx_index) {
			case 0:
				let _g = a.data;
				switch(b._hx_index) {
				case 0:
					let b1 = b.data;
					let a1 = _g;
					return merger(a1,b1);
				case 1:
					let e = b.failure;
					return new tink_core__$Future_SyncFuture(new tink_core__$Lazy_LazyConst(tink_core_Outcome.Failure(e)));
				}
				break;
			case 1:
				let e1 = a.failure;
				return new tink_core__$Future_SyncFuture(new tink_core__$Lazy_LazyConst(tink_core_Outcome.Failure(e1)));
			}
		}),function(o) {
			return o;
		});
	}
	static irreversible(f) {
		let f1 = function(res,rej) {
			f(res,rej);
			return null;
		};
		return new tink_core__$Future_SuspendableFuture(function(cb) {
			return f1(function(v) {
				cb(tink_core_Outcome.Success(v));
			},function(e) {
				cb(tink_core_Outcome.Failure(e));
			});
		});
	}
	static and(a,b) {
		return tink_core_Promise.merge(a,b,function(a,b) {
			return new tink_core__$Future_SyncFuture(new tink_core__$Lazy_LazyConst(tink_core_Outcome.Success(new tink_core_MPair(a,b))));
		});
	}
	static iterate(promises,$yield,fallback,fallThroughOnError) {
		if(fallThroughOnError == null) {
			fallThroughOnError = false;
		}
		return tink_core_Future.irreversible(function(cb) {
			let iter = $getIterator(promises);
			let next = null;
			next = function() {
				if(iter.hasNext()) {
					iter.next().handle(function(o) {
						switch(o._hx_index) {
						case 0:
							let v = o.data;
							$yield(v).handle(function(o) {
								switch(o._hx_index) {
								case 0:
									let _g = o.data;
									switch(_g._hx_index) {
									case 0:
										let ret = _g.v;
										cb(tink_core_Outcome.Success(ret));
										break;
									case 1:
										next();
										break;
									}
									break;
								case 1:
									let e = o.failure;
									cb(tink_core_Outcome.Failure(e));
									break;
								}
							});
							break;
						case 1:
							let e = o.failure;
							if(fallThroughOnError) {
								next();
							} else {
								cb(tink_core_Outcome.Failure(e));
							}
							break;
						}
					});
				} else {
					fallback.handle(cb);
				}
			};
			next();
		});
	}
	static retry(gen,next) {
		let stamp = function() {
			return HxOverrides.now() / 1000 * 1000;
		};
		let start = stamp();
		let attempt = null;
		attempt = function(count) {
			let f = function(error) {
				return tink_core_Promise.next(next({ attempt : count, error : error, elapsed : stamp() - start}),function(_) {
					return attempt(count + 1);
				});
			};
			return tink_core_Future.flatMap(gen(),function(o) {
				switch(o._hx_index) {
				case 0:
					let d = o.data;
					return new tink_core__$Future_SyncFuture(new tink_core__$Lazy_LazyConst(o));
				case 1:
					let e = o.failure;
					return f(e);
				}
			});
		};
		return attempt(1);
	}
	static ofJsPromise(promise,transformError) {
		return tink_core_Future.ofJsPromise(promise,transformError);
	}
	static fromJsPromise(promise) {
		return tink_core_Future.ofJsPromise(promise);
	}
	static toJsPromise(this1) {
		return new Promise(function(resolve,reject) {
			this1.handle(function(o) {
				switch(o._hx_index) {
				case 0:
					let v = o.data;
					resolve(v);
					break;
				case 1:
					let e = o.failure;
					reject(e.toJsError());
					break;
				}
			});
		});
	}
	static ofSpecific(s) {
		return s;
	}
	static fromNever(l) {
		return l;
	}
	static ofTrigger(f) {
		return f;
	}
	static ofHappyTrigger(f) {
		return tink_core_Future.map(f,tink_core_Outcome.Success);
	}
	static ofFuture(f) {
		return tink_core_Future.map(f,tink_core_Outcome.Success);
	}
	static ofOutcome(o) {
		return new tink_core__$Future_SyncFuture(new tink_core__$Lazy_LazyConst(o));
	}
	static ofError(e) {
		return new tink_core__$Future_SyncFuture(new tink_core__$Lazy_LazyConst(tink_core_Outcome.Failure(e)));
	}
	static ofData(d) {
		return new tink_core__$Future_SyncFuture(new tink_core__$Lazy_LazyConst(tink_core_Outcome.Success(d)));
	}
	static asFuture(this1) {
		return this1;
	}
	static lazy(p) {
		return new tink_core__$Future_SuspendableFuture(function(cb) {
			return tink_core_Lazy.get(p).handle(cb);
		});
	}
	static inParallel(a,concurrency) {
		return tink_core_Promise.many(a,concurrency);
	}
	static many(a,concurrency) {
		return tink_core_Future.processMany(a,concurrency,function(o) {
			return o;
		},function(o) {
			return o;
		});
	}
	static inSequence(a) {
		return tink_core_Promise.many(a,1);
	}
	static cache(gen) {
		let p = null;
		return function() {
			let ret = p;
			if(ret == null) {
				let sync = false;
				ret = tink_core_Promise.next(gen(),function(o) {
					o.b.handle(function(_) {
						sync = true;
						p = null;
					});
					return new tink_core__$Future_SyncFuture(new tink_core__$Lazy_LazyConst(tink_core_Outcome.Success(o.a)));
				});
				if(!sync) {
					p = ret;
				}
			}
			return tink_core_Future.map(ret,function(o) {
				if(!tink_core_OutcomeTools.isSuccess(o)) {
					p = null;
				}
				return o;
			});
		};
	}
	static lift(p) {
		return p;
	}
	static trigger() {
		return new tink_core_FutureTrigger();
	}
	static resolve(v) {
		return new tink_core__$Future_SyncFuture(new tink_core__$Lazy_LazyConst(tink_core_Outcome.Success(v)));
	}
	static reject(e) {
		return new tink_core__$Future_SyncFuture(new tink_core__$Lazy_LazyConst(tink_core_Outcome.Failure(e)));
	}
}
class tink_core_Next {
	static ofSafe(f) {
		return function(x) {
			return new tink_core__$Future_SyncFuture(new tink_core__$Lazy_LazyConst(f(x)));
		};
	}
	static ofSync(f) {
		return function(x) {
			return tink_core_Future.map(f(x),tink_core_Outcome.Success);
		};
	}
	static ofSafeSync(f) {
		return function(x) {
			return new tink_core__$Future_SyncFuture(new tink_core__$Lazy_LazyConst(tink_core_Outcome.Success(f(x))));
		};
	}
	static _chain(a,b) {
		return function(v) {
			return tink_core_Promise.next(a(v),b);
		};
	}
}
class tink_core_Recover {
	static ofSync(f) {
		return function(e) {
			return new tink_core__$Future_SyncFuture(new tink_core__$Lazy_LazyConst(f(e)));
		};
	}
}
class tink_core_Combiner {
	static ofSync(f) {
		return function(x1,x2) {
			return new tink_core__$Future_SyncFuture(new tink_core__$Lazy_LazyConst(f(x1,x2)));
		};
	}
	static ofSafe(f) {
		return function(x1,x2) {
			return tink_core_Future.map(f(x1,x2),tink_core_Outcome.Success);
		};
	}
	static ofSafeSync(f) {
		return function(x1,x2) {
			return new tink_core__$Future_SyncFuture(new tink_core__$Lazy_LazyConst(tink_core_Outcome.Success(f(x1,x2))));
		};
	}
}
class tink_core_PromiseTrigger {
	static _new() {
		return new tink_core_FutureTrigger();
	}
	static resolve(this1,v) {
		return this1.trigger(tink_core_Outcome.Success(v));
	}
	static reject(this1,e) {
		return this1.trigger(tink_core_Outcome.Failure(e));
	}
	static asPromise(this1) {
		return this1;
	}
}
class tink_core_Ref {
	static _new() {
		return new Array(1);
	}
	static get_value(this1) {
		return this1[0];
	}
	static set_value(this1,param) {
		return this1[0] = param;
	}
	static toString(this1) {
		return "@[" + Std.string(this1[0]) + "]";
	}
	static to(v) {
		let ret = new Array(1);
		ret[0] = v;
		return ret;
	}
}
class tink_core_Gather {
	static _new(v) {
		return v;
	}
	static ofBool(b) {
		return b;
	}
}
class tink_core_Signal {
	static _new(f,init) {
		return new tink_core__$Signal_Suspendable(f,init);
	}
	static handle(this1,handler) {
		return this1.listen(handler);
	}
	static map(this1,f,gather) {
		return tink_core__$Signal_Suspendable.over(this1,function(fire) {
			return this1.listen(function(v) {
				fire(f(v));
			});
		});
	}
	static flatMap(this1,f,gather) {
		return tink_core__$Signal_Suspendable.over(this1,function(fire) {
			return this1.listen(function(v) {
				f(v).handle(fire);
			});
		});
	}
	static filter(this1,f,gather) {
		return tink_core__$Signal_Suspendable.over(this1,function(fire) {
			return this1.listen(function(v) {
				if(f(v)) {
					fire(v);
				}
			});
		});
	}
	static select(this1,selector,gather) {
		return tink_core__$Signal_Suspendable.over(this1,function(fire) {
			return this1.listen(function(v) {
				let _g = selector(v);
				if(_g._hx_index == 0) {
					let v = _g.v;
					fire(v);
				}
			});
		});
	}
	static join(this1,that,gather) {
		if(this1.get_disposed()) {
			return that;
		} else if(that.get_disposed()) {
			return this1;
		} else {
			return new tink_core__$Signal_Suspendable(function(fire) {
				let cb = fire;
				return new tink_core__$Callback_LinkPair(this1.listen(cb),that.listen(cb));
			},function(self) {
				let release = function() {
					if(this1.get_disposed() && that.get_disposed()) {
						self.dispose();
					}
				};
				this1.ondispose(release);
				that.ondispose(release);
			});
		}
	}
	static nextTime(this1,condition) {
		return tink_core_Signal.pickNext(this1,function(v) {
			if(condition == null || condition(v)) {
				return haxe_ds_Option.Some(v);
			} else {
				return haxe_ds_Option.None;
			}
		});
	}
	static pickNext(this1,selector) {
		let ret = new tink_core_FutureTrigger();
		let link = null;
		link = this1.listen(function(v) {
			let _g = selector(v);
			switch(_g._hx_index) {
			case 0:
				let v1 = _g.v;
				ret.trigger(v1);
				break;
			case 1:
				break;
			}
		});
		ret.handle(link == null ? tink_core_CallbackLink.noop : ($_=link,$bind($_,$_.cancel)));
		return ret;
	}
	static until(this1,end) {
		return new tink_core__$Signal_Suspendable(function($yield) {
			return this1.listen($yield);
		},function(self) {
			end.handle($bind(self,self.dispose));
		});
	}
	static next(this1,condition) {
		return tink_core_Signal.nextTime(this1,condition);
	}
	static noise(this1) {
		return tink_core_Signal.map(this1,function(_) {
			return null;
		});
	}
	static gather(this1) {
		return this1;
	}
	static create(f) {
		return new tink_core__$Signal_Suspendable(f,null);
	}
	static generate(generator,init) {
		return new tink_core__$Signal_Suspendable(function(fire) {
			generator(fire);
			return null;
		},init);
	}
	static trigger() {
		return new tink_core_SignalTrigger();
	}
	static ofClassical(add,remove,gather) {
		return new tink_core__$Signal_Suspendable(function(fire) {
			add(fire);
			let _g = remove;
			let a1 = fire;
			return new tink_core_SimpleLink(function() {
				_g(a1);
			});
		});
	}
	static dead() {
		return tink_core__$Signal_Disposed.INST;
	}
}
class tink_core__$Signal_SignalObject {
}
tink_core__$Signal_SignalObject.__name__ = "tink.core._Signal.SignalObject";
tink_core__$Signal_SignalObject.__isInterface__ = true;
tink_core__$Signal_SignalObject.__interfaces__ = [tink_core_Disposable];
Object.assign(tink_core__$Signal_SignalObject.prototype, {
	__class__: tink_core__$Signal_SignalObject
});
class tink_core__$Signal_Disposed extends tink_core_AlreadyDisposed {
	constructor() {
		super();
	}
	listen(cb) {
		return null;
	}
}
tink_core__$Signal_Disposed.__name__ = "tink.core._Signal.Disposed";
tink_core__$Signal_Disposed.__interfaces__ = [tink_core__$Signal_SignalObject];
tink_core__$Signal_Disposed.__super__ = tink_core_AlreadyDisposed;
Object.assign(tink_core__$Signal_Disposed.prototype, {
	__class__: tink_core__$Signal_Disposed
});
class tink_core__$Signal_Suspendable {
	constructor(activate,init) {
		this.handlers = new tink_core_CallbackList();
		this.activate = activate;
		this.init = init;
		let _gthis = this;
		this.handlers.ondrain = function() {
			let this1 = _gthis.subscription;
			if(this1 != null) {
				this1.cancel();
			}
		};
		this.handlers.onfill = function() {
			if(init != null) {
				let f = init;
				init = null;
				f(_gthis);
			}
			_gthis.subscription = activate(($_=_gthis.handlers,$bind($_,$_.invoke)));
		};
	}
	get_disposed() {
		return this.handlers.disposeHandlers == null;
	}
	dispose() {
		this.handlers.dispose();
	}
	ondispose(handler) {
		this.handlers.ondispose(handler);
	}
	listen(cb) {
		let _this = this.handlers;
		if(_this.disposeHandlers == null) {
			return null;
		} else {
			let node = new tink_core__$Callback_ListCell(cb,_this);
			_this.cells.push(node);
			if(_this.used++ == 0) {
				let fn = _this.onfill;
				if(tink_core_Callback.depth < 500) {
					tink_core_Callback.depth++;
					fn();
					tink_core_Callback.depth--;
				} else {
					tink_core_Callback.defer(fn);
				}
			}
			return node;
		}
	}
	static over(s,activate) {
		if(s.get_disposed()) {
			return tink_core_Signal.dead();
		} else {
			let ret = new tink_core__$Signal_Suspendable(activate);
			s.ondispose($bind(ret,ret.dispose));
			return ret;
		}
	}
}
tink_core__$Signal_Suspendable.__name__ = "tink.core._Signal.Suspendable";
tink_core__$Signal_Suspendable.__interfaces__ = [tink_core_OwnedDisposable,tink_core__$Signal_SignalObject];
Object.assign(tink_core__$Signal_Suspendable.prototype, {
	__class__: tink_core__$Signal_Suspendable
});
class tink_core_SignalTrigger {
	constructor() {
		this.handlers = new tink_core_CallbackList();
	}
	get_disposed() {
		return this.handlers.disposeHandlers == null;
	}
	dispose() {
		this.handlers.dispose();
	}
	ondispose(d) {
		this.handlers.ondispose(d);
	}
	trigger(event) {
		this.handlers.invoke(event);
	}
	getLength() {
		return this.handlers.used;
	}
	listen(cb) {
		let _this = this.handlers;
		if(_this.disposeHandlers == null) {
			return null;
		} else {
			let node = new tink_core__$Callback_ListCell(cb,_this);
			_this.cells.push(node);
			if(_this.used++ == 0) {
				let fn = _this.onfill;
				if(tink_core_Callback.depth < 500) {
					tink_core_Callback.depth++;
					fn();
					tink_core_Callback.depth--;
				} else {
					tink_core_Callback.defer(fn);
				}
			}
			return node;
		}
	}
	clear() {
		this.handlers.clear();
	}
	asSignal() {
		return this;
	}
}
tink_core_SignalTrigger.__name__ = "tink.core.SignalTrigger";
tink_core_SignalTrigger.__interfaces__ = [tink_core_OwnedDisposable,tink_core__$Signal_SignalObject];
Object.assign(tink_core_SignalTrigger.prototype, {
	__class__: tink_core_SignalTrigger
});
class tink_http_Chunked {
	static encoder() {
		if(tink_http_Chunked._encoder == null) {
			tink_http_Chunked._encoder = new tink_http_ChunkedEncoder();
		}
		return tink_http_Chunked._encoder;
	}
	static decoder() {
		if(tink_http_Chunked._decoder == null) {
			tink_http_Chunked._decoder = new tink_http_ChunkedDecoder();
		}
		return tink_http_Chunked._decoder;
	}
	static encode(source) {
		return tink_http_Chunked.encoder().transform(source);
	}
	static decode(source) {
		return tink_http_Chunked.decoder().transform(source);
	}
}
tink_http_Chunked.__name__ = "tink.http.Chunked";
class tink_io_Transformer {
}
tink_io_Transformer.__name__ = "tink.io.Transformer";
tink_io_Transformer.__isInterface__ = true;
Object.assign(tink_io_Transformer.prototype, {
	__class__: tink_io_Transformer
});
class tink_http_ChunkedEncoder {
	constructor() {
	}
	transform(source) {
		return tink_io_Source.chunked(source).map(tink_streams_Mapping.ofPlain(function(chunk) {
			return tink_Chunk.concat(tink_Chunk.concat(tink_chunk_ByteChunk.of(haxe_io_Bytes.ofString("" + StringTools.hex(chunk.getLength()) + "\r\n")),chunk),tink_chunk_ByteChunk.of(haxe_io_Bytes.ofString("\r\n")));
		})).append(tink_streams_Stream.ofIterator(new haxe_iterators_ArrayIterator([tink_chunk_ByteChunk.of(haxe_io_Bytes.ofString("0\r\n"))])));
	}
}
tink_http_ChunkedEncoder.__name__ = "tink.http.ChunkedEncoder";
tink_http_ChunkedEncoder.__interfaces__ = [tink_io_Transformer];
Object.assign(tink_http_ChunkedEncoder.prototype, {
	__class__: tink_http_ChunkedEncoder
});
class tink_http_ChunkedDecoder {
	constructor() {
	}
	transform(source) {
		return tink_io_RealSourceTools.parseStream(source,new tink_http_ChunkedParser()).map(tink_streams_Mapping.ofPlain(function(v) {
			if(tink_Chunk.reqString(v,null.toString())) {
				return tink_Chunk.EMPTY;
			} else {
				return v;
			}
		}));
	}
}
tink_http_ChunkedDecoder.__name__ = "tink.http.ChunkedDecoder";
tink_http_ChunkedDecoder.__interfaces__ = [tink_io_Transformer];
Object.assign(tink_http_ChunkedDecoder.prototype, {
	__class__: tink_http_ChunkedDecoder
});
class tink_io_StreamParserObject {
}
tink_io_StreamParserObject.__name__ = "tink.io.StreamParserObject";
tink_io_StreamParserObject.__isInterface__ = true;
Object.assign(tink_io_StreamParserObject.prototype, {
	__class__: tink_io_StreamParserObject
});
class tink_http_ChunkedParser {
	constructor() {
		this.reset();
	}
	reset() {
		this.chunkSize = -1;
	}
	progress(cursor) {
		if(this.chunkSize < 0) {
			let _g = cursor.seek(tink_http_ChunkedParser.LINEBREAK);
			switch(_g._hx_index) {
			case 0:
				let v = _g.v;
				this.chunkSize = Std.parseInt("0x" + (v == null ? "null" : v.toString()));
				break;
			case 1:
				break;
			}
			return tink_io_ParseStep.Progressed;
		} else if(this.chunkSize == 0) {
			return tink_io_ParseStep.Progressed;
		} else if(cursor.length >= this.chunkSize + 2) {
			let _g = cursor.seek(tink_http_ChunkedParser.LINEBREAK);
			switch(_g._hx_index) {
			case 0:
				let v = _g.v;
				this.reset();
				return tink_io_ParseStep.Done(v);
			case 1:
				return tink_io_ParseStep.Failed(new tink_core_TypedError(null,"Invalid encoding",{ fileName : "tink/http/Chunked.hx", lineNumber : 82, className : "tink.http.ChunkedParser", methodName : "progress"}));
			}
		} else {
			return tink_io_ParseStep.Progressed;
		}
	}
	eof(rest) {
		if(this.chunkSize == 0) {
			return tink_core_Outcome.Success(tink_Chunk.EMPTY);
		} else {
			return tink_core_Outcome.Failure(new tink_core_TypedError(null,"Unexpected end of input",{ fileName : "tink/http/Chunked.hx", lineNumber : 89, className : "tink.http.ChunkedParser", methodName : "eof"}));
		}
	}
}
tink_http_ChunkedParser.__name__ = "tink.http.ChunkedParser";
tink_http_ChunkedParser.__interfaces__ = [tink_io_StreamParserObject];
Object.assign(tink_http_ChunkedParser.prototype, {
	__class__: tink_http_ChunkedParser
});
class tink_http_Client {
	static fetch(url,options) {
		return tink_http_Fetch.fetch(url,options);
	}
	static augment(this1,pipeline) {
		return tink_http__$Client_CustomClient.create(this1,pipeline.before,pipeline.after);
	}
}
class tink_http_ClientObject {
}
tink_http_ClientObject.__name__ = "tink.http.ClientObject";
tink_http_ClientObject.__isInterface__ = true;
Object.assign(tink_http_ClientObject.prototype, {
	__class__: tink_http_ClientObject
});
class tink_http__$Client_CustomClient {
	constructor(preprocessors,postprocessors,real) {
		this.preprocessors = preprocessors;
		this.postprocessors = postprocessors;
		this.real = real;
	}
	pipe(value,transforms,index) {
		if(index == null) {
			index = 0;
		}
		if(transforms != null && index < transforms.length) {
			let _g = this;
			let transforms1 = transforms;
			let index1 = index + 1;
			let tmp = function(value) {
				return _g.pipe(value,transforms1,index1);
			};
			return tink_core_Promise.next(transforms[index](value),tmp);
		} else {
			return new tink_core__$Future_SyncFuture(new tink_core__$Lazy_LazyConst(tink_core_Outcome.Success(value)));
		}
	}
	request(req) {
		let _gthis = this;
		return tink_core_Promise.next(this.pipe(req,this.preprocessors),function(req) {
			let tmp = _gthis.real.request(req);
			let _g = _gthis;
			let transforms;
			if(_gthis.postprocessors == null) {
				transforms = null;
			} else {
				let _g = [];
				let _g1 = 0;
				let _g2 = _gthis.postprocessors;
				while(_g1 < _g2.length) {
					let p = _g2[_g1];
					++_g1;
					_g.push(p(req));
				}
				transforms = _g;
			}
			return tink_core_Promise.next(tmp,function(value) {
				return _g.pipe(value,transforms);
			});
		});
	}
	static concat(a,b) {
		if(a == null) {
			let v = b;
			return v;
		} else if(b == null) {
			let v = a;
			return v;
		} else {
			return a.concat(b);
		}
	}
	static create(c,preprocessors,postprocessors) {
		let _g = ((c) instanceof tink_http__$Client_CustomClient) ? c : null;
		if(_g == null) {
			return new tink_http__$Client_CustomClient(preprocessors,postprocessors,c);
		} else {
			let v = _g;
			return new tink_http__$Client_CustomClient(tink_http__$Client_CustomClient.concat(preprocessors,v.preprocessors),tink_http__$Client_CustomClient.concat(v.postprocessors,postprocessors),v.real);
		}
	}
}
tink_http__$Client_CustomClient.__name__ = "tink.http._Client.CustomClient";
tink_http__$Client_CustomClient.__interfaces__ = [tink_http_ClientObject];
Object.assign(tink_http__$Client_CustomClient.prototype, {
	__class__: tink_http__$Client_CustomClient
});
class tink_http_Container {
}
tink_http_Container.__name__ = "tink.http.Container";
tink_http_Container.__isInterface__ = true;
Object.assign(tink_http_Container.prototype, {
	__class__: tink_http_Container
});
var tink_http_ContainerResult = $hxEnums["tink.http.ContainerResult"] = { __ename__:true,__constructs__:null
	,Running: ($_=function(running) { return {_hx_index:0,running:running,__enum__:"tink.http.ContainerResult",toString:$estr}; },$_._hx_name="Running",$_.__params__ = ["running"],$_)
	,Failed: ($_=function(e) { return {_hx_index:1,e:e,__enum__:"tink.http.ContainerResult",toString:$estr}; },$_._hx_name="Failed",$_.__params__ = ["e"],$_)
	,Shutdown: {_hx_name:"Shutdown",_hx_index:2,__enum__:"tink.http.ContainerResult",toString:$estr}
};
tink_http_ContainerResult.__constructs__ = [tink_http_ContainerResult.Running,tink_http_ContainerResult.Failed,tink_http_ContainerResult.Shutdown];
class tink_http_Fetch {
	static fetch(url,options) {
		return tink_core_Future.async(function(cb) {
			let uri = url.path;
			if(url.query != null) {
				uri += "?" + (url.query == null ? "null" : url.query);
			}
			let method = "GET";
			let headers = null;
			let body = tink_io_Source.EMPTY;
			let type = tink_http_ClientType.Default;
			let followRedirect = true;
			if(options != null) {
				if(options.method != null) {
					method = options.method;
				}
				if(options.headers != null) {
					headers = options.headers;
				}
				if(options.body != null) {
					body = options.body;
				}
				if(options.client != null) {
					type = options.client;
				}
				if(options.followRedirect == false) {
					followRedirect = false;
				}
			}
			let client = tink_http_Fetch.getClient(type);
			if(options != null && options.augment != null) {
				let pipeline = options.augment;
				client = tink_http__$Client_CustomClient.create(client,pipeline.before,pipeline.after);
			}
			client.request(new tink_http_OutgoingRequest(new tink_http_OutgoingRequestHeader(method,url,null,headers),body)).handle(function(res) {
				switch(res._hx_index) {
				case 0:
					let res1 = res.data;
					let _g = res1.header.statusCode;
					switch(_g) {
					case 301:case 302:case 303:case 307:case 308:
						let code = _g;
						if(followRedirect) {
							tink_core_Promise.next(new tink_core__$Future_SyncFuture(new tink_core__$Lazy_LazyConst(res1.header.byName("location".toLowerCase()))),function(location) {
								let this1 = tink_Url.resolve(url,tink_Url.fromString(location));
								let this2;
								if(code == 303) {
									let __o0 = options;
									let __tink_tmp0 = { method : "GET"};
									let _g = __o0.headers;
									if(_g != null) {
										let v = _g;
										__tink_tmp0.headers = v;
									}
									let _g1 = __o0.followRedirect;
									if(_g1 != null) {
										let v = _g1;
										__tink_tmp0.followRedirect = v;
									}
									let _g2 = __o0.client;
									if(_g2 != null) {
										let v = _g2;
										__tink_tmp0.client = v;
									}
									let _g3 = __o0.body;
									if(_g3 != null) {
										let v = _g3;
										__tink_tmp0.body = v;
									}
									let _g4 = __o0.augment;
									if(_g4 != null) {
										let v = _g4;
										__tink_tmp0.augment = v;
									}
									this2 = __tink_tmp0;
								} else {
									this2 = options;
								}
								return tink_http_Fetch.fetch(this1,this2);
							}).handle(cb);
						} else {
							cb(tink_core_Outcome.Success(res1));
						}
						break;
					default:
						cb(tink_core_Outcome.Success(res1));
					}
					break;
				case 1:
					let e = res.failure;
					cb(tink_core_Outcome.Failure(e));
					break;
				}
			});
		});
	}
	static getClient(type) {
		if(!tink_http_Fetch.cache.exists(type)) {
			let c;
			switch(type._hx_index) {
			case 0:
				c = new tink_http_clients_JsClient();
				break;
			case 1:
				let c1 = type.container;
				c = new tink_http_clients_LocalContainerClient(c1);
				break;
			case 2:
				c = new tink_http_clients_StdClient();
				break;
			case 3:
				let c2 = type.v;
				c = c2;
				break;
			}
			tink_http_Fetch.cache.set(type,c);
		}
		return tink_http_Fetch.cache.get(type);
	}
}
tink_http_Fetch.__name__ = "tink.http.Fetch";
var tink_http_ClientType = $hxEnums["tink.http.ClientType"] = { __ename__:true,__constructs__:null
	,Default: {_hx_name:"Default",_hx_index:0,__enum__:"tink.http.ClientType",toString:$estr}
	,Local: ($_=function(container) { return {_hx_index:1,container:container,__enum__:"tink.http.ClientType",toString:$estr}; },$_._hx_name="Local",$_.__params__ = ["container"],$_)
	,StdLib: {_hx_name:"StdLib",_hx_index:2,__enum__:"tink.http.ClientType",toString:$estr}
	,Custom: ($_=function(v) { return {_hx_index:3,v:v,__enum__:"tink.http.ClientType",toString:$estr}; },$_._hx_name="Custom",$_.__params__ = ["v"],$_)
};
tink_http_ClientType.__constructs__ = [tink_http_ClientType.Default,tink_http_ClientType.Local,tink_http_ClientType.StdLib,tink_http_ClientType.Custom];
class tink_http_FetchResponse {
	static all(this1) {
		return tink_core_Promise.next(this1,function(r) {
			return tink_core_Promise.next(tink_io_RealSourceTools.all(r.body),function(chunk) {
				if(r.header.statusCode >= 400) {
					return new tink_core__$Future_SyncFuture(new tink_core__$Lazy_LazyConst(tink_core_Outcome.Failure(tink_core_TypedError.withData(r.header.statusCode,r.header.reason,chunk.toString(),{ fileName : "tink/http/Fetch.hx", lineNumber : 125, className : "tink.http._Fetch.FetchResponse_Impl_", methodName : "all"}))));
				} else {
					return new tink_core__$Future_SyncFuture(new tink_core__$Lazy_LazyConst(tink_core_Outcome.Success(new tink_http_Message(r.header,chunk))));
				}
			});
		});
	}
	static progress(this1) {
		return tink_core_Promise.next(this1,function(r) {
			if(r.header.statusCode >= 400) {
				return tink_core_Promise.next(tink_io_RealSourceTools.all(r.body),function(chunk) {
					return new tink_core__$Future_SyncFuture(new tink_core__$Lazy_LazyConst(tink_core_Outcome.Failure(tink_core_TypedError.withData(r.header.statusCode,r.header.reason,chunk.toString(),{ fileName : "tink/http/Fetch.hx", lineNumber : 137, className : "tink.http._Fetch.FetchResponse_Impl_", methodName : "progress"}))));
				});
			} else {
				return new tink_core__$Future_SyncFuture(new tink_core__$Lazy_LazyConst(tink_core_Outcome.Success(new tink_http_Message(r.header,tink_core_Progress.make(function(progress,finish) {
					let total;
					let _g = r.header.getContentLength();
					switch(_g._hx_index) {
					case 0:
						let len = _g.data;
						total = haxe_ds_Option.Some(len);
						break;
					case 1:
						let _g1 = _g.failure;
						total = haxe_ds_Option.None;
						break;
					}
					let chunk = tink_Chunk.EMPTY;
					progress(chunk.getLength(),total);
					return tink_io_Source.chunked(r.body).forEach(tink_streams_Handler.ofSafeSync(function(part) {
						chunk = tink_Chunk.concat(chunk,part);
						progress(chunk.getLength(),total);
						return tink_streams_Handled.Resume;
					})).handle(function(o) {
						switch(o._hx_index) {
						case 0:
							let _g = o.rest;
							finish(tink_core_Outcome.Failure(new tink_core_TypedError(null,"unreachable",{ fileName : "tink/http/Fetch.hx", lineNumber : 157, className : "tink.http._Fetch.FetchResponse_Impl_", methodName : "progress"})));
							break;
						case 2:
							let e = o.error;
							finish(tink_core_Outcome.Failure(e));
							break;
						case 3:
							finish(tink_core_Outcome.Success(chunk));
							break;
						}
					});
				})))));
			}
		});
	}
}
class tink_http_Handler {
	static ofFunc(f) {
		return new tink_http_SimpleHandler(f);
	}
}
class tink_http_HandlerObject {
}
tink_http_HandlerObject.__name__ = "tink.http.HandlerObject";
tink_http_HandlerObject.__isInterface__ = true;
Object.assign(tink_http_HandlerObject.prototype, {
	__class__: tink_http_HandlerObject
});
class tink_http_SimpleHandler {
	constructor(f) {
		this.f = f;
	}
	process(req) {
		return this.f(req);
	}
}
tink_http_SimpleHandler.__name__ = "tink.http.SimpleHandler";
tink_http_SimpleHandler.__interfaces__ = [tink_http_HandlerObject];
Object.assign(tink_http_SimpleHandler.prototype, {
	__class__: tink_http_SimpleHandler
});
class tink_http_ReadonlyMap {
	static get(this1,key) {
		return this1.get(key);
	}
	static exists(this1,key) {
		return this1.exists(key);
	}
	static iterator(this1) {
		return this1.iterator();
	}
	static keys(this1) {
		return this1.keys();
	}
}
class tink_http_ContentType {
	constructor() {
		this.subtype = "*";
		this.type = "*";
		this.extensions = new haxe_ds_StringMap();
	}
	get_fullType() {
		return "" + this.type + "/" + this.subtype;
	}
	toString() {
		return this.raw;
	}
	static ofString(s) {
		let ret = new tink_http_ContentType();
		ret.raw = s;
		let parsed = tink_http_HeaderValue.parse(s);
		let value = parsed[0].value;
		let _g = value.indexOf("/");
		if(_g == -1) {
			ret.type = value;
		} else {
			let pos = _g;
			ret.type = value.substring(0,pos);
			ret.subtype = value.substring(pos + 1);
		}
		ret.extensions = parsed[0].extensions;
		return ret;
	}
}
tink_http_ContentType.__name__ = "tink.http.ContentType";
Object.assign(tink_http_ContentType.prototype, {
	__class__: tink_http_ContentType
});
class tink_http_Header {
	constructor(fields) {
		if(tink_http_Header._hx_skip_constructor) {
			return;
		}
		this._hx_constructor(fields);
	}
	_hx_constructor(fields) {
		let tmp;
		if(fields == null) {
			tmp = [];
		} else {
			let v = fields;
			tmp = v;
		}
		this.fields = tmp;
	}
	get(name) {
		let _g = [];
		let _g1 = 0;
		let _g2 = this.fields;
		while(_g1 < _g2.length) {
			let f = _g2[_g1];
			++_g1;
			if(f.name == name) {
				_g.push(f.value);
			}
		}
		return _g;
	}
	byName(name) {
		let _g = this.get(name);
		switch(_g.length) {
		case 0:
			return tink_core_Outcome.Failure(new tink_core_TypedError(422,"No " + name + " header found",{ fileName : "tink/http/Header.hx", lineNumber : 91, className : "tink.http.Header", methodName : "byName"}));
		case 1:
			let v = _g[0];
			return tink_core_Outcome.Success(v);
		default:
			let v1 = _g;
			return tink_core_Outcome.Failure(new tink_core_TypedError(422,"Multiple entries for " + name + " header",{ fileName : "tink/http/Header.hx", lineNumber : 95, className : "tink.http.Header", methodName : "byName"}));
		}
	}
	contentType() {
		return tink_core_OutcomeTools.map(this.byName("content-type"),tink_http_ContentType.ofString);
	}
	iterator() {
		return new haxe_iterators_ArrayIterator(this.fields);
	}
	concat(fields) {
		return new tink_http_Header(this.fields.concat(fields));
	}
	getContentLength() {
		let _g = this.byName("content-length");
		switch(_g._hx_index) {
		case 0:
			let _hx_tmp = Std.parseInt(_g.data);
			if(_hx_tmp == null) {
				return tink_core_Outcome.Failure(new tink_core_TypedError(422,"Invalid Content-Length Header",{ fileName : "tink/http/Header.hx", lineNumber : 120, className : "tink.http.Header", methodName : "getContentLength"}));
			} else {
				let v = _hx_tmp;
				return tink_core_Outcome.Success(v);
			}
			break;
		case 1:
			let e = _g.failure;
			return tink_core_Outcome.Failure(e);
		}
	}
	accepts(type) {
		let prefix = type.split("/")[0];
		return tink_core_OutcomeTools.map(this.byName("accept"),function(v) {
			let _g = 0;
			let _g1 = tink_http_HeaderValue.parse(v);
			while(_g < _g1.length) {
				let entry = _g1[_g];
				++_g;
				if(entry.value == "*/*" || entry.value == type) {
					return true;
				}
				let _g2 = entry.value.split("/");
				if(_g2.length == 2) {
					if(_g2[1] == "*") {
						let p = _g2[0];
						if(prefix == p) {
							return true;
						}
					}
				}
			}
			return false;
		});
	}
	get_LINEBREAK() {
		return "\r\n";
	}
	toString() {
		let _g = [];
		let _g1 = 0;
		let _g2 = this.fields;
		while(_g1 < _g2.length) {
			let f = _g2[_g1];
			++_g1;
			_g.push(f.toString());
		}
		return _g.join("\r\n") + "\r\n" + "\r\n";
	}
	headerNotFound(name) {
		return "No " + name + " header found";
	}
}
tink_http_Header.__name__ = "tink.http.Header";
Object.assign(tink_http_Header.prototype, {
	__class__: tink_http_Header
});
class tink_http_HeaderValue {
	static getExtension(this1) {
		return tink_http_HeaderValue.parse(this1)[0].extensions;
	}
	static parse(this1) {
		return tink_http_HeaderValue.parseWith(this1,function(_,params) {
			let _g = new haxe_ds_StringMap();
			let p = params;
			while(p.hasNext()) {
				let p1 = p.next();
				let key = p1.name;
				let value;
				let _g1 = tink_url_Portion.toString(p1.value);
				let quoted = _g1;
				if(HxOverrides.cca(quoted,0) == 34) {
					value = HxOverrides.substr(quoted,1,quoted.length - 2);
				} else {
					let v = _g1;
					value = v;
				}
				_g.h[key] = value;
			}
			return _g;
		});
	}
	static parseWith(this1,parseExtension) {
		let _g = [];
		let _g1 = 0;
		let _g2 = this1.split(",");
		while(_g1 < _g2.length) {
			let v = _g2[_g1];
			++_g1;
			v = StringTools.trim(v);
			let i;
			let _g3 = v.indexOf(";");
			if(_g3 == -1) {
				i = v.length;
			} else {
				let i1 = _g3;
				i = i1;
			}
			let value = HxOverrides.substr(v,0,i);
			let sep = ";";
			let pos = i + 1;
			if(pos == null) {
				pos = 0;
			}
			if(sep == null) {
				sep = "&";
			}
			_g.push({ value : value, extensions : parseExtension(value,new tink_url__$Query_QueryStringParser(v,sep,"=",pos))});
		}
		return _g;
	}
	static basicAuth(username,password) {
		return "Basic " + haxe_crypto_Base64.encode(haxe_io_Bytes.ofString("" + username + ":" + password)).toString();
	}
	static ofDate(d) {
		return DateTools.format(d,tink_http_HeaderValue.DAYS[d.getDay()] + ", %d " + tink_http_HeaderValue.MONTHS[d.getMonth()] + " %Y %H:%M:%S GMT");
	}
	static ofInt(i) {
		if(i == null) {
			return "null";
		} else {
			return "" + i;
		}
	}
}
class tink_http_HeaderName {
	static _new(s) {
		return s;
	}
	static ofString(s) {
		return s.toLowerCase();
	}
}
class tink_http_HeaderField extends tink_core_NamedWith {
	constructor(name,value) {
		super(name,value);
	}
	toString() {
		if(this.value == null) {
			return this.name;
		} else {
			return "" + this.name + ": " + this.value;
		}
	}
	static ofString(s) {
		let _g = s.indexOf(":");
		if(_g == -1) {
			return new tink_http_HeaderField(s.toLowerCase(),null);
		} else {
			let v = _g;
			return new tink_http_HeaderField(HxOverrides.substr(s,0,v).toLowerCase(),StringTools.trim(HxOverrides.substr(s,v + 1,null)));
		}
	}
	static setCookie(key,value,options) {
		if(options == null) {
			options = { };
		}
		let buf_b = "";
		buf_b += Std.string(encodeURIComponent(key) + "=" + encodeURIComponent(value));
		if(options.expires != null) {
			let value = tink_http_HeaderValue.ofDate(options.expires);
			if(value != null) {
				buf_b += "; ";
				buf_b += "expires=";
				buf_b += Std.string(value);
			}
		}
		let value1 = options.domain;
		if(value1 != null) {
			buf_b += "; ";
			buf_b += "domain=";
			buf_b += Std.string(value1);
		}
		let value2 = options.path;
		if(value2 != null) {
			buf_b += "; ";
			buf_b += "path=";
			buf_b += Std.string(value2);
		}
		if(options.secure) {
			buf_b += "; ";
			buf_b += "secure";
			buf_b += "";
		}
		if(options.scriptable != true) {
			buf_b += "; ";
			buf_b += "HttpOnly";
			buf_b += "";
		}
		return new tink_http_HeaderField("set-cookie",buf_b);
	}
}
tink_http_HeaderField.__name__ = "tink.http.HeaderField";
tink_http_HeaderField.__super__ = tink_core_NamedWith;
Object.assign(tink_http_HeaderField.prototype, {
	__class__: tink_http_HeaderField
});
class tink_io_BytewiseParser {
	read(char) {
		throw haxe_Exception.thrown("abstract");
	}
	progress(cursor) {
		do {
			let _g = this.read(cursor.currentByte);
			switch(_g._hx_index) {
			case 0:
				break;
			case 1:
				let r = _g.r;
				cursor.next();
				return tink_io_ParseStep.Done(r);
			case 2:
				let e = _g.e;
				return tink_io_ParseStep.Failed(e);
			}
		} while(cursor.next());
		return tink_io_ParseStep.Progressed;
	}
	eof(rest) {
		let _g = this.read(-1);
		switch(_g._hx_index) {
		case 0:
			return tink_core_Outcome.Failure(new tink_core_TypedError(422,"Unexpected end of input",{ fileName : "tink/io/StreamParser.hx", lineNumber : 180, className : "tink.io.BytewiseParser", methodName : "eof"}));
		case 1:
			let r = _g.r;
			return tink_core_Outcome.Success(r);
		case 2:
			let e = _g.e;
			return tink_core_Outcome.Failure(e);
		}
	}
}
tink_io_BytewiseParser.__name__ = "tink.io.BytewiseParser";
tink_io_BytewiseParser.__interfaces__ = [tink_io_StreamParserObject];
Object.assign(tink_io_BytewiseParser.prototype, {
	__class__: tink_io_BytewiseParser
});
var tink_io_ParseStep = $hxEnums["tink.io.ParseStep"] = { __ename__:true,__constructs__:null
	,Progressed: {_hx_name:"Progressed",_hx_index:0,__enum__:"tink.io.ParseStep",toString:$estr}
	,Done: ($_=function(r) { return {_hx_index:1,r:r,__enum__:"tink.io.ParseStep",toString:$estr}; },$_._hx_name="Done",$_.__params__ = ["r"],$_)
	,Failed: ($_=function(e) { return {_hx_index:2,e:e,__enum__:"tink.io.ParseStep",toString:$estr}; },$_._hx_name="Failed",$_.__params__ = ["e"],$_)
};
tink_io_ParseStep.__constructs__ = [tink_io_ParseStep.Progressed,tink_io_ParseStep.Done,tink_io_ParseStep.Failed];
class tink_http_HeaderParser extends tink_io_BytewiseParser {
	constructor(makeHeader) {
		super();
		this.last = -1;
		this.buf = new StringBuf();
		this.makeHeader = makeHeader;
	}
	read(c) {
		let _g = this.last;
		switch(c) {
		case -1:
			return this.nextLine();
		case 10:
			if(_g == 13) {
				return this.nextLine();
			} else {
				let other = c;
				this.last = other;
				this.buf.b += String.fromCodePoint(other);
				return tink_io_ParseStep.Progressed;
			}
			break;
		case 13:
			if(_g == 13) {
				let c = this.last;
				this.buf.b += String.fromCodePoint(c);
				return tink_io_ParseStep.Progressed;
			} else {
				this.last = 13;
				return tink_io_ParseStep.Progressed;
			}
			break;
		default:
			if(_g == 13) {
				let other = c;
				let c1 = this.last;
				this.buf.b += String.fromCodePoint(c1);
				this.buf.b += String.fromCodePoint(other);
				this.last = -1;
				return tink_io_ParseStep.Progressed;
			} else {
				let other = c;
				this.last = other;
				this.buf.b += String.fromCodePoint(other);
				return tink_io_ParseStep.Progressed;
			}
		}
	}
	nextLine() {
		let line = this.buf.b;
		this.buf = new StringBuf();
		this.last = -1;
		if(line == "") {
			if(this.header == null) {
				return tink_io_ParseStep.Progressed;
			} else {
				return tink_io_ParseStep.Done(this.header);
			}
		} else if(this.header == null) {
			let _g = this.makeHeader(line,this.fields = []);
			switch(_g._hx_index) {
			case 0:
				let _g1 = _g.data;
				if(_g1 == null) {
					return tink_io_ParseStep.Done(this.header = null);
				} else {
					let v = _g1;
					this.header = v;
					return tink_io_ParseStep.Progressed;
				}
				break;
			case 1:
				let e = _g.failure;
				return tink_io_ParseStep.Failed(e);
			}
		} else {
			this.fields.push(tink_http_HeaderField.ofString(line));
			return tink_io_ParseStep.Progressed;
		}
	}
}
tink_http_HeaderParser.__name__ = "tink.http.HeaderParser";
tink_http_HeaderParser.__super__ = tink_io_BytewiseParser;
Object.assign(tink_http_HeaderParser.prototype, {
	__class__: tink_http_HeaderParser
});
class tink_http_Message {
	constructor(header,body) {
		if(tink_http_Message._hx_skip_constructor) {
			return;
		}
		this._hx_constructor(header,body);
	}
	_hx_constructor(header,body) {
		this.header = header;
		this.body = body;
	}
}
tink_http_Message.__name__ = "tink.http.Message";
Object.assign(tink_http_Message.prototype, {
	__class__: tink_http_Message
});
class tink_http_Method {
	static ofString(s,fallback) {
		let _g = s.toUpperCase();
		switch(_g) {
		case "DELETE":
			return "DELETE";
		case "GET":
			return "GET";
		case "HEAD":
			return "HEAD";
		case "OPTIONS":
			return "OPTIONS";
		case "PATCH":
			return "PATCH";
		case "POST":
			return "POST";
		case "PUT":
			return "PUT";
		default:
			let v = _g;
			return fallback(v);
		}
	}
}
class tink_http_RequestHeader extends tink_http_Header {
	constructor(method,url,protocol,fields) {
		tink_http_Header._hx_skip_constructor = true;
		super();
		tink_http_Header._hx_skip_constructor = false;
		this._hx_constructor(method,url,protocol,fields);
	}
	_hx_constructor(method,url,protocol,fields) {
		if(protocol == null) {
			protocol = "HTTP/1.1";
		}
		this.method = method;
		this.url = url;
		this.protocol = protocol;
		super._hx_constructor(fields);
	}
	concat(fields) {
		return new tink_http_RequestHeader(this.method,this.url,this.protocol,this.fields.concat(fields));
	}
	toString() {
		let this1 = this.url;
		return "" + this.method + " " + (this1.query == null ? this1.path : (this1.path == null ? "null" : this1.path) + "?" + (this1.query == null ? "null" : this1.query)) + " " + this.protocol + "\r\n" + super.toString();
	}
}
tink_http_RequestHeader.__name__ = "tink.http.RequestHeader";
tink_http_RequestHeader.__super__ = tink_http_Header;
Object.assign(tink_http_RequestHeader.prototype, {
	__class__: tink_http_RequestHeader
});
class tink_http_IncomingRequestHeader extends tink_http_RequestHeader {
	constructor(method,url,protocol,fields) {
		super(method,url,protocol,fields);
	}
	getCookies() {
		if(this.cookies == null) {
			let _g = new haxe_ds_StringMap();
			let _g1 = 0;
			let _g2 = this.get("cookie".toLowerCase());
			while(_g1 < _g2.length) {
				let header = _g2[_g1];
				++_g1;
				let sep = ";";
				if(sep == null) {
					sep = "&";
				}
				let entry = new tink_url__$Query_QueryStringParser(header,sep,"=",0);
				while(entry.hasNext()) {
					let entry1 = entry.next();
					let key = entry1.name;
					let value = tink_url_Portion.toString(entry1.value);
					_g.h[key] = value;
				}
			}
			this.cookies = _g;
		}
		return this.cookies;
	}
	concat(fields) {
		return new tink_http_IncomingRequestHeader(this.method,this.url,this.protocol,this.fields.concat(fields));
	}
	cookieNames() {
		return new haxe_ds__$StringMap_StringMapKeyIterator(this.cookies.h);
	}
	getCookie(name) {
		return this.getCookies().h[name];
	}
	getAuth() {
		return this.getAuthWith(function(s,p) {
			switch(s) {
			case "Basic":
				let decoded;
				try {
					decoded = haxe_crypto_Base64.decode(p).toString();
				} catch( _g ) {
					let e = haxe_Exception.caught(_g).unwrap();
					return tink_core_Outcome.Failure(tink_core_TypedError.withData(null,"Error in decoding basic auth",e,{ fileName : "tink/http/Request.hx", lineNumber : 67, className : "tink.http.IncomingRequestHeader", methodName : "getAuth"}));
				}
				let _g = decoded.indexOf(":");
				if(_g == -1) {
					return tink_core_Outcome.Failure(new tink_core_TypedError(null,"Cannot parse username and password because \":\" is missing",{ fileName : "tink/http/Request.hx", lineNumber : 69, className : "tink.http.IncomingRequestHeader", methodName : "getAuth"}));
				} else {
					let i = _g;
					return tink_core_Outcome.Success(tink_http_Authorization.Basic(HxOverrides.substr(decoded,0,i),HxOverrides.substr(decoded,i + 1,null)));
				}
				break;
			case "Bearer":
				return tink_core_Outcome.Success(tink_http_Authorization.Bearer(p));
			default:
				let s1 = s;
				return tink_core_Outcome.Success(tink_http_Authorization.Others(s1,p));
			}
		});
	}
	getAuthWith(parser) {
		return tink_core_OutcomeTools.flatMap(this.byName("authorization"),tink_core__$Outcome_OutcomeMapper.withSameError(function(v) {
			let _g = v.indexOf(" ");
			if(_g == -1) {
				return tink_core_Outcome.Failure(new tink_core_TypedError(422,"Invalid Authorization Header",{ fileName : "tink/http/Request.hx", lineNumber : 81, className : "tink.http.IncomingRequestHeader", methodName : "getAuthWith"}));
			} else {
				let i = _g;
				return parser(HxOverrides.substr(v,0,i),HxOverrides.substr(v,i + 1,null));
			}
		}));
	}
	static parser() {
		return new tink_http_HeaderParser(function(line,headers) {
			let _g = line.split(" ");
			if(_g.length == 3) {
				let method = _g[0];
				let url = _g[1];
				let protocol = _g[2];
				return tink_core_Outcome.Success(new tink_http_IncomingRequestHeader(method,tink_Url.fromString(url),protocol,headers));
			} else {
				return tink_core_Outcome.Failure(new tink_core_TypedError(422,"Invalid HTTP header",{ fileName : "tink/http/Request.hx", lineNumber : 95, className : "tink.http.IncomingRequestHeader", methodName : "parser"}));
			}
		});
	}
}
tink_http_IncomingRequestHeader.__name__ = "tink.http.IncomingRequestHeader";
tink_http_IncomingRequestHeader.__super__ = tink_http_RequestHeader;
Object.assign(tink_http_IncomingRequestHeader.prototype, {
	__class__: tink_http_IncomingRequestHeader
});
class tink_http_OutgoingRequestHeader extends tink_http_RequestHeader {
	constructor(method,url,protocol,fields) {
		if(protocol == null) {
			protocol = "HTTP/1.1";
		}
		let _g = tink_http_OutgoingRequestHeader.extractAuth(url);
		if(_g._hx_index == 0) {
			let v = _g.v;
			url = v.url;
			fields = fields.concat(v.headers);
		}
		super(method,url,protocol,fields);
	}
	concat(fields) {
		return new tink_http_OutgoingRequestHeader(this.method,this.url,this.protocol,this.fields.concat(fields));
	}
	static extractAuth(url) {
		let _g = url.auth;
		if(_g == null) {
			return haxe_ds_Option.None;
		} else {
			let v = _g;
			let tmp = [new tink_http_HeaderField("authorization",tink_http_HeaderValue.basicAuth(v == null ? null : v.split(":")[0],v == null ? null : v.split(":")[1]))];
			let url1 = url.scheme;
			let _g1 = [];
			let _g2 = 0;
			let _g3 = url.hosts;
			while(_g2 < _g3.length) {
				let host = _g3[_g2];
				++_g2;
				_g1.push(host);
			}
			return haxe_ds_Option.Some({ headers : tmp, url : tink_Url.make({ scheme : url1, hosts : _g1, path : url.path, query : url.query})});
		}
	}
}
tink_http_OutgoingRequestHeader.__name__ = "tink.http.OutgoingRequestHeader";
tink_http_OutgoingRequestHeader.__super__ = tink_http_RequestHeader;
Object.assign(tink_http_OutgoingRequestHeader.prototype, {
	__class__: tink_http_OutgoingRequestHeader
});
class tink_http_OutgoingRequest extends tink_http_Message {
	constructor(header,body) {
		super(header,body);
	}
}
tink_http_OutgoingRequest.__name__ = "tink.http.OutgoingRequest";
tink_http_OutgoingRequest.__super__ = tink_http_Message;
Object.assign(tink_http_OutgoingRequest.prototype, {
	__class__: tink_http_OutgoingRequest
});
class tink_http_IncomingRequest extends tink_http_Message {
	constructor(clientIp,header,body) {
		tink_http_Message._hx_skip_constructor = true;
		super();
		tink_http_Message._hx_skip_constructor = false;
		this._hx_constructor(clientIp,header,body);
	}
	_hx_constructor(clientIp,header,body) {
		this.clientIp = clientIp;
		super._hx_constructor(header,body);
	}
	static parse(clientIp,source) {
		return tink_core_Promise.next(tink_io_RealSourceTools.parse(source,tink_http_IncomingRequestHeader.parser()),function(parts) {
			let clientIp1 = clientIp;
			let parts1 = parts.a;
			let _g = parts.a.getContentLength();
			let d;
			switch(_g._hx_index) {
			case 0:
				let len = _g.data;
				d = tink_io_Source.limit(parts.b,len);
				break;
			case 1:
				let _g1 = _g.failure;
				let _g2 = parts.a.method;
				let _g3 = parts.a.byName("transfer-encoding");
				switch(_g2) {
				case "GET":case "OPTIONS":
					d = tink_io_Source.EMPTY;
					break;
				default:
					if(_g3._hx_index == 0) {
						let _this = _g3.data.split(",");
						let f = StringTools.trim;
						let result = new Array(_this.length);
						let _g = 0;
						let _g1 = _this.length;
						while(_g < _g1) {
							let i = _g++;
							result[i] = f(_this[i]);
						}
						let encodings = result;
						if(encodings.indexOf("chunked") != -1) {
							let source = parts.b;
							d = tink_http_Chunked.decoder().transform(source);
						} else {
							return new tink_core__$Future_SyncFuture(new tink_core__$Lazy_LazyConst(tink_core_Outcome.Failure(new tink_core_TypedError(411,"Content-Length header missing",{ fileName : "tink/http/Request.hx", lineNumber : 171, className : "tink.http.IncomingRequest", methodName : "parse"}))));
						}
					} else {
						return new tink_core__$Future_SyncFuture(new tink_core__$Lazy_LazyConst(tink_core_Outcome.Failure(new tink_core_TypedError(411,"Content-Length header missing",{ fileName : "tink/http/Request.hx", lineNumber : 171, className : "tink.http.IncomingRequest", methodName : "parse"}))));
					}
				}
				break;
			}
			return new tink_core__$Future_SyncFuture(new tink_core__$Lazy_LazyConst(tink_core_Outcome.Success(new tink_http_IncomingRequest(clientIp1,parts1,tink_http_IncomingRequestBody.Plain(d)))));
		});
	}
}
tink_http_IncomingRequest.__name__ = "tink.http.IncomingRequest";
tink_http_IncomingRequest.__super__ = tink_http_Message;
Object.assign(tink_http_IncomingRequest.prototype, {
	__class__: tink_http_IncomingRequest
});
var tink_http_IncomingRequestBody = $hxEnums["tink.http.IncomingRequestBody"] = { __ename__:true,__constructs__:null
	,Plain: ($_=function(source) { return {_hx_index:0,source:source,__enum__:"tink.http.IncomingRequestBody",toString:$estr}; },$_._hx_name="Plain",$_.__params__ = ["source"],$_)
	,Parsed: ($_=function(parts) { return {_hx_index:1,parts:parts,__enum__:"tink.http.IncomingRequestBody",toString:$estr}; },$_._hx_name="Parsed",$_.__params__ = ["parts"],$_)
};
tink_http_IncomingRequestBody.__constructs__ = [tink_http_IncomingRequestBody.Plain,tink_http_IncomingRequestBody.Parsed];
var tink_http_Authorization = $hxEnums["tink.http.Authorization"] = { __ename__:true,__constructs__:null
	,Basic: ($_=function(user,pass) { return {_hx_index:0,user:user,pass:pass,__enum__:"tink.http.Authorization",toString:$estr}; },$_._hx_name="Basic",$_.__params__ = ["user","pass"],$_)
	,Bearer: ($_=function(token) { return {_hx_index:1,token:token,__enum__:"tink.http.Authorization",toString:$estr}; },$_._hx_name="Bearer",$_.__params__ = ["token"],$_)
	,Others: ($_=function(scheme,param) { return {_hx_index:2,scheme:scheme,param:param,__enum__:"tink.http.Authorization",toString:$estr}; },$_._hx_name="Others",$_.__params__ = ["scheme","param"],$_)
};
tink_http_Authorization.__constructs__ = [tink_http_Authorization.Basic,tink_http_Authorization.Bearer,tink_http_Authorization.Others];
class tink_http_ResponseHeader {
	static _new(statusCode,reason,fields,protocol) {
		if(protocol == null) {
			protocol = "HTTP/1.1";
		}
		return new tink_http_ResponseHeaderBase(statusCode,reason,fields,protocol);
	}
	static fromStatusCode(code) {
		return new tink_http_ResponseHeaderBase(code,null,null,"HTTP/1.1");
	}
	static fromHeaderFields(fields) {
		return new tink_http_ResponseHeaderBase(200,null,fields,"HTTP/1.1");
	}
	static parser() {
		return tink_http_ResponseHeaderBase.parser();
	}
}
class tink_http_ResponseHeaderBase extends tink_http_Header {
	constructor(statusCode,reason,fields,protocol) {
		tink_http_Header._hx_skip_constructor = true;
		super();
		tink_http_Header._hx_skip_constructor = false;
		this._hx_constructor(statusCode,reason,fields,protocol);
	}
	_hx_constructor(statusCode,reason,fields,protocol) {
		if(protocol == null) {
			protocol = "HTTP/1.1";
		}
		this.statusCode = statusCode;
		this.reason = reason == null ? httpstatus_HttpStatusMessage.fromCode(statusCode) : reason;
		this.protocol = protocol;
		super._hx_constructor(fields);
	}
	concat(fields) {
		let statusCode = this.statusCode;
		let reason = this.reason;
		let fields1 = this.fields.concat(fields);
		let protocol = this.protocol;
		if(protocol == null) {
			protocol = "HTTP/1.1";
		}
		return new tink_http_ResponseHeaderBase(statusCode,reason,fields1,protocol);
	}
	toString() {
		return "" + this.protocol + " " + this.statusCode + " " + this.reason + "\r\n" + super.toString();
	}
	static parser() {
		return new tink_http_HeaderParser(function(line,headers) {
			let v = line.split(" ");
			if(v.length >= 3) {
				let statusCode = Std.parseInt(v[1]);
				let reason = v.slice(2).join(" ");
				let protocol = v[0];
				if(protocol == null) {
					protocol = "HTTP/1.1";
				}
				return tink_core_Outcome.Success(new tink_http_ResponseHeaderBase(statusCode,reason,headers,protocol));
			} else {
				return tink_core_Outcome.Failure(new tink_core_TypedError(422,"Invalid HTTP response header",{ fileName : "tink/http/Response.hx", lineNumber : 56, className : "tink.http.ResponseHeaderBase", methodName : "parser"}));
			}
		});
	}
}
tink_http_ResponseHeaderBase.__name__ = "tink.http.ResponseHeaderBase";
tink_http_ResponseHeaderBase.__super__ = tink_http_Header;
Object.assign(tink_http_ResponseHeaderBase.prototype, {
	__class__: tink_http_ResponseHeaderBase
});
class tink_http__$Response_OutgoingResponseData extends tink_http_Message {
	constructor(header,body) {
		super(header,body);
	}
}
tink_http__$Response_OutgoingResponseData.__name__ = "tink.http._Response.OutgoingResponseData";
tink_http__$Response_OutgoingResponseData.__super__ = tink_http_Message;
Object.assign(tink_http__$Response_OutgoingResponseData.prototype, {
	__class__: tink_http__$Response_OutgoingResponseData
});
class tink_http_OutgoingResponse {
	static _new(header,body) {
		return new tink_http__$Response_OutgoingResponseData(header,body);
	}
	static blob(code,chunk,contentType,headers) {
		if(code == null) {
			code = 200;
		}
		let this1 = httpstatus_HttpStatusMessage.fromCode(code);
		let fields = new tink_http_HeaderField("Content-Type".toLowerCase(),contentType);
		let this2 = "Content-Length".toLowerCase();
		let fields1 = Std.string(chunk.getLength());
		let fields2;
		if(headers == null) {
			fields2 = [];
		} else {
			let v = headers;
			fields2 = v;
		}
		return new tink_http__$Response_OutgoingResponseData(new tink_http_ResponseHeaderBase(code,this1,[fields,new tink_http_HeaderField(this2,fields1)].concat(fields2),"HTTP/1.1"),new tink_streams_Single(new tink_core__$Lazy_LazyConst(chunk)));
	}
	static chunked(contentType,headers,source) {
	}
	static ofString(s) {
		return tink_http_OutgoingResponse.blob(null,tink_chunk_ByteChunk.of(haxe_io_Bytes.ofString(s)),"text/plain");
	}
	static ofChunk(c) {
		return tink_http_OutgoingResponse.blob(null,c,"application/octet-stream");
	}
	static reportError(e) {
		let code = e.code;
		if(code < 100 || code > 999) {
			code = 500;
		}
		return new tink_http__$Response_OutgoingResponseData(new tink_http_ResponseHeaderBase(code,httpstatus_HttpStatusMessage.fromCode(code),[new tink_http_HeaderField("Content-Type".toLowerCase(),"application/json")],"HTTP/1.1"),new tink_streams_Single(new tink_core__$Lazy_LazyConst(tink_chunk_ByteChunk.of(haxe_io_Bytes.ofString(JSON.stringify({ error : e.message, details : e.data}))))));
	}
}
class tink_http_IncomingResponse extends tink_http_Message {
	constructor(header,body) {
		super(header,body);
	}
	static readAll(res) {
		return tink_core_Promise.next(tink_io_RealSourceTools.all(res.body),function(b) {
			if(res.header.statusCode >= 400) {
				return new tink_core__$Future_SyncFuture(new tink_core__$Lazy_LazyConst(tink_core_Outcome.Failure(tink_core_TypedError.withData(res.header.statusCode,res.header.reason,b.toString(),{ fileName : "tink/http/Response.hx", lineNumber : 115, className : "tink.http.IncomingResponse", methodName : "readAll"}))));
			} else {
				return new tink_core__$Future_SyncFuture(new tink_core__$Lazy_LazyConst(tink_core_Outcome.Success(b)));
			}
		});
	}
	static reportError(e) {
		return new tink_http_IncomingResponse(new tink_http_ResponseHeaderBase(e.code,httpstatus_HttpStatusMessage.fromCode(e.code),[new tink_http_HeaderField("Content-Type".toLowerCase(),"application/json")],"HTTP/1.1"),new tink_streams_Single(new tink_core__$Lazy_LazyConst(tink_chunk_ByteChunk.of(haxe_io_Bytes.ofString(JSON.stringify({ error : e.message, details : e.data}))))));
	}
}
tink_http_IncomingResponse.__name__ = "tink.http.IncomingResponse";
tink_http_IncomingResponse.__super__ = tink_http_Message;
Object.assign(tink_http_IncomingResponse.prototype, {
	__class__: tink_http_IncomingResponse
});
var tink_http_BodyPart = $hxEnums["tink.http.BodyPart"] = { __ename__:true,__constructs__:null
	,Value: ($_=function(v) { return {_hx_index:0,v:v,__enum__:"tink.http.BodyPart",toString:$estr}; },$_._hx_name="Value",$_.__params__ = ["v"],$_)
	,File: ($_=function(handle) { return {_hx_index:1,handle:handle,__enum__:"tink.http.BodyPart",toString:$estr}; },$_._hx_name="File",$_.__params__ = ["handle"],$_)
};
tink_http_BodyPart.__constructs__ = [tink_http_BodyPart.Value,tink_http_BodyPart.File];
class tink_http_UploadedFile {
	static ofBlob(name,type,data) {
		return { fileName : name, mimeType : type, size : data.length, read : function() {
			return new tink_streams_Single(new tink_core__$Lazy_LazyConst(tink_chunk_ByteChunk.of(data)));
		}, saveTo : function(path) {
			let name = "File sink " + path;
			throw haxe_Exception.thrown("not implemented");
		}};
	}
}
class tink_http_clients_JsClient {
	constructor(credentials) {
		this.credentials = false;
		if(credentials) {
			this.credentials = true;
		}
	}
	request(req) {
		let _gthis = this;
		return tink_core_Future.async(function(cb) {
			let http = new XMLHttpRequest();
			http.open(req.header.method,tink_Url.toString(req.header.url));
			http.withCredentials = _gthis.credentials;
			http.responseType = "arraybuffer";
			let _g_current = 0;
			let _g_array = req.header.fields;
			while(_g_current < _g_array.length) {
				let header = _g_array[_g_current++];
				switch(header.name) {
				case "content-length":case "host":
					break;
				default:
					http.setRequestHeader(header.name,header.value);
				}
			}
			http.onreadystatechange = function() {
				if(http.readyState == 4) {
					if(http.status != 0) {
						let headers;
						let _g = http.getAllResponseHeaders();
						if(_g == null) {
							headers = [];
						} else {
							let v = _g;
							let _g1 = [];
							let _g2 = 0;
							let _g3 = v.split("\r\n");
							while(_g2 < _g3.length) {
								let line = _g3[_g2];
								++_g2;
								if(line != "") {
									_g1.push(tink_http_HeaderField.ofString(line));
								}
							}
							headers = _g1;
						}
						let header = new tink_http_ResponseHeaderBase(http.status,http.statusText,headers,"HTTP/1.1");
						let cb1 = cb;
						let this1 = new tink_http_ResponseHeaderBase(http.status,http.statusText,headers,"HTTP/1.1");
						let _g1 = http.response;
						let tmp;
						if(_g1 == null) {
							tmp = tink_io_Source.EMPTY;
						} else {
							let v = _g1;
							tmp = new tink_streams_Single(new tink_core__$Lazy_LazyConst(tink_chunk_ByteChunk.of(haxe_io_Bytes.ofData(v))));
						}
						cb1(tink_core_Outcome.Success(new tink_http_IncomingResponse(this1,tmp)));
					} else {
						let _g = cb;
						let a1 = tink_core_Outcome.Failure(tink_core_TypedError.withData(502,"XMLHttpRequest Error",{ request : req, error : "Status code is zero"},{ fileName : "tink/http/clients/JsClient.hx", lineNumber : 54, className : "tink.http.clients.JsClient", methodName : "request"}));
						haxe_Timer.delay(function() {
							_g(a1);
						},1);
					}
				}
			};
			http.onerror = function(e) {
				cb(tink_core_Outcome.Failure(tink_core_TypedError.withData(502,"XMLHttpRequest Error",{ request : req, error : e},{ fileName : "tink/http/clients/JsClient.hx", lineNumber : 60, className : "tink.http.clients.JsClient", methodName : "request"})));
			};
			if(req.header.method == "GET") {
				http.send();
			} else {
				tink_io_IdealSourceTools.all(req.body).handle(function(chunk) {
					http.send(new Int8Array(chunk.toBytes().b.bufferValue));
				});
			}
		});
	}
	getHttp() {
		return new XMLHttpRequest();
	}
}
tink_http_clients_JsClient.__name__ = "tink.http.clients.JsClient";
tink_http_clients_JsClient.__interfaces__ = [tink_http_ClientObject];
Object.assign(tink_http_clients_JsClient.prototype, {
	__class__: tink_http_clients_JsClient
});
class tink_http_clients_LocalContainerClient {
	constructor(container) {
		this.container = container;
	}
	request(req) {
		let this1 = req.header.url;
		return tink_core_Future.flatMap(this.container.serve(new tink_http_IncomingRequest("127.0.0.1",new tink_http_IncomingRequestHeader(req.header.method,tink_Url.fromString(this1.query == null ? this1.path : (this1.path == null ? "null" : this1.path) + "?" + (this1.query == null ? "null" : this1.query)),"HTTP/1.1",req.header.fields),tink_http_IncomingRequestBody.Plain(req.body))),function(res) {
			return new tink_core__$Future_SyncFuture(new tink_core__$Lazy_LazyConst(tink_core_Outcome.Success(new tink_http_IncomingResponse(res.header,res.body))));
		});
	}
}
tink_http_clients_LocalContainerClient.__name__ = "tink.http.clients.LocalContainerClient";
tink_http_clients_LocalContainerClient.__interfaces__ = [tink_http_ClientObject];
Object.assign(tink_http_clients_LocalContainerClient.prototype, {
	__class__: tink_http_clients_LocalContainerClient
});
class tink_http_clients_StdClient {
	constructor(worker) {
		this.worker = tink_io_Worker.ensure(worker);
	}
	request(req) {
		let _gthis = this;
		return tink_core_Future.async(function(cb) {
			let r = new haxe_http_HttpJs(tink_Url.toString(req.header.url));
			let send = function(post) {
				let code = 200;
				r.onStatus = function(c) {
					code = c;
				};
				let headers = function() {
					return [];
				};
				r.onError = function(msg) {
					if(code == 200) {
						code = 500;
					}
					tink_io_Worker.work(_gthis.worker,new tink_core__$Lazy_LazyConst(true)).handle(function() {
						cb(tink_core_Outcome.Failure(new tink_core_TypedError(code,msg,{ fileName : "tink/http/clients/StdClient.hx", lineNumber : 44, className : "tink.http.clients.StdClient", methodName : "request"})));
					});
				};
				r.onData = function(data) {
					tink_io_Worker.work(_gthis.worker,new tink_core__$Lazy_LazyConst(true)).handle(function() {
						let cb1 = cb;
						let fields = headers();
						cb1(tink_core_Outcome.Success(new tink_http_IncomingResponse(new tink_http_ResponseHeaderBase(code,"OK",fields,"HTTP/1.1"),new tink_streams_Single(new tink_core__$Lazy_LazyConst(tink_chunk_ByteChunk.of(haxe_io_Bytes.ofString(data)))))));
					});
				};
				tink_io_Worker.work(_gthis.worker,new tink_core__$Lazy_LazyFunc(function() {
					r.request(post);
				}));
			};
			let _g_current = 0;
			let _g_array = req.header.fields;
			while(_g_current < _g_array.length) {
				let h = _g_array[_g_current++];
				r.setHeader(h.name,h.value);
			}
			switch(req.header.method) {
			case "GET":case "HEAD":case "OPTIONS":
				send(false);
				break;
			default:
				tink_io_IdealSourceTools.all(req.body).handle(function(bytes) {
					r.setPostData(bytes.toString());
					send(true);
				});
			}
		});
	}
}
tink_http_clients_StdClient.__name__ = "tink.http.clients.StdClient";
tink_http_clients_StdClient.__interfaces__ = [tink_http_ClientObject];
Object.assign(tink_http_clients_StdClient.prototype, {
	__class__: tink_http_clients_StdClient
});
class tink_http_containers_LocalContainer {
	constructor() {
	}
	run(handler) {
		this.handler = handler;
		this.running = true;
		let _gthis = this;
		return new tink_core__$Future_SyncFuture(new tink_core__$Lazy_LazyConst(tink_http_ContainerResult.Running({ failures : new tink_core_SignalTrigger(), shutdown : function(hard) {
			_gthis.running = false;
			return tink_core_Future.map(new tink_core__$Future_SyncFuture(new tink_core__$Lazy_LazyConst(true)),tink_core_Outcome.Success);
		}})));
	}
	serve(req) {
		if(!this.running) {
			return new tink_core__$Future_SyncFuture(new tink_core__$Lazy_LazyConst(new tink_http__$Response_OutgoingResponseData(new tink_http_ResponseHeaderBase(503,"Server stopped",[],"HTTP/1.1"),tink_io_Source.EMPTY)));
		}
		return this.handler.process(req);
	}
}
tink_http_containers_LocalContainer.__name__ = "tink.http.containers.LocalContainer";
tink_http_containers_LocalContainer.__interfaces__ = [tink_http_Container];
Object.assign(tink_http_containers_LocalContainer.prototype, {
	__class__: tink_http_containers_LocalContainer
});
class tink_io_PipeOptions {
	static get_end(this1) {
		if(this1 != null) {
			return this1.end;
		} else {
			return false;
		}
	}
	static get_destructive(this1) {
		if(this1 != null) {
			return this1.destructive;
		} else {
			return false;
		}
	}
}
var tink_io_PipeResult = $hxEnums["tink.io.PipeResult"] = { __ename__:true,__constructs__:null
	,AllWritten: {_hx_name:"AllWritten",_hx_index:0,__enum__:"tink.io.PipeResult",toString:$estr}
	,SinkEnded: ($_=function(result,rest) { return {_hx_index:1,result:result,rest:rest,__enum__:"tink.io.PipeResult",toString:$estr}; },$_._hx_name="SinkEnded",$_.__params__ = ["result","rest"],$_)
	,SinkFailed: ($_=function(e,rest) { return {_hx_index:2,e:e,rest:rest,__enum__:"tink.io.PipeResult",toString:$estr}; },$_._hx_name="SinkFailed",$_.__params__ = ["e","rest"],$_)
	,SourceFailed: ($_=function(e) { return {_hx_index:3,e:e,__enum__:"tink.io.PipeResult",toString:$estr}; },$_._hx_name="SourceFailed",$_.__params__ = ["e"],$_)
};
tink_io_PipeResult.__constructs__ = [tink_io_PipeResult.AllWritten,tink_io_PipeResult.SinkEnded,tink_io_PipeResult.SinkFailed,tink_io_PipeResult.SourceFailed];
class tink_io_PipeResultTools {
	static toOutcome(result) {
		switch(result._hx_index) {
		case 0:
			return tink_core_Outcome.Success(haxe_ds_Option.None);
		case 1:
			let _g = result.rest;
			let result1 = result.result;
			return tink_core_Outcome.Success(haxe_ds_Option.Some(result1));
		case 2:
			let _g1 = result.rest;
			let e = result.e;
			return tink_core_Outcome.Failure(e);
		case 3:
			let e1 = result.e;
			return tink_core_Outcome.Failure(e1);
		}
	}
	static toResult(c,result,buffered) {
		let mk = function(s) {
			if(buffered == null) {
				return s;
			} else {
				let v = buffered;
				return s.prepend(new tink_streams_Single(new tink_core__$Lazy_LazyConst(v)));
			}
		};
		switch(c._hx_index) {
		case 0:
			let rest = c.rest;
			return tink_io_PipeResult.SinkEnded(result,mk(rest));
		case 1:
			let e = c.error;
			let rest1 = c.at;
			return tink_io_PipeResult.SinkFailed(e,mk(rest1));
		case 2:
			let e1 = c.error;
			return tink_io_PipeResult.SourceFailed(e1);
		case 3:
			return tink_io_PipeResult.AllWritten;
		}
	}
}
tink_io_PipeResultTools.__name__ = "tink.io.PipeResultTools";
class tink_io_SinkObject {
}
tink_io_SinkObject.__name__ = "tink.io.SinkObject";
tink_io_SinkObject.__isInterface__ = true;
Object.assign(tink_io_SinkObject.prototype, {
	__class__: tink_io_SinkObject
});
class tink_io_SinkBase {
	get_sealed() {
		return true;
	}
	consume(source,options) {
		throw haxe_Exception.thrown("not implemented");
	}
}
tink_io_SinkBase.__name__ = "tink.io.SinkBase";
tink_io_SinkBase.__interfaces__ = [tink_io_SinkObject];
Object.assign(tink_io_SinkBase.prototype, {
	__class__: tink_io_SinkBase
});
class tink_io__$Sink_Blackhole extends tink_io_SinkBase {
	constructor() {
		super();
	}
	consume(source,options) {
		return tink_core_Future.map(source.forEach(tink_streams_Handler.ofSafeSync(function(_) {
			return tink_streams_Handled.Resume;
		})),function(o) {
			switch(o._hx_index) {
			case 0:
				let _g = o.rest;
				throw haxe_Exception.thrown("unreachable");
			case 2:
				let e = o.error;
				return tink_io_PipeResult.SourceFailed(e);
			case 3:
				return tink_io_PipeResult.AllWritten;
			}
		});
	}
}
tink_io__$Sink_Blackhole.__name__ = "tink.io._Sink.Blackhole";
tink_io__$Sink_Blackhole.__super__ = tink_io_SinkBase;
Object.assign(tink_io__$Sink_Blackhole.prototype, {
	__class__: tink_io__$Sink_Blackhole
});
class tink_io_SinkYielding {
	static end(this1) {
		if(this1.get_sealed()) {
			return new tink_core__$Future_SyncFuture(new tink_core__$Lazy_LazyConst(tink_core_Outcome.Success(false)));
		} else {
			return tink_core_Future.map(this1.consume(tink_io_Source.EMPTY,{ end : true}),function(r) {
				switch(r._hx_index) {
				case 0:
					return tink_core_Outcome.Success(true);
				case 1:
					let _g = r.result;
					let _g1 = r.rest;
					return tink_core_Outcome.Success(true);
				case 2:
					let _g2 = r.rest;
					let e = r.e;
					return tink_core_Outcome.Failure(e);
				}
			});
		}
	}
	static dirty(this1) {
		return this1;
	}
	static ofError(e) {
		return new tink_io__$Sink_ErrorSink(e);
	}
	static ofPromised(p) {
		return new tink_io__$Sink_FutureSink(tink_core_Future.map(p,function(o) {
			switch(o._hx_index) {
			case 0:
				let v = o.data;
				return v;
			case 1:
				let e = o.failure;
				return tink_io_SinkYielding.ofError(e);
			}
		}));
	}
	static ofOutput(name,target,options) {
		let tmp;
		if(options == null) {
			tmp = tink_io_Worker.get();
		} else {
			let _g = options.worker;
			if(_g == null) {
				tmp = tink_io_Worker.get();
			} else {
				let w = _g;
				tmp = w;
			}
		}
		return new tink_io_std_OutputSink(name,target,tmp);
	}
}
class tink_io__$Sink_FutureSink extends tink_io_SinkBase {
	constructor(f) {
		super();
		this.f = f;
	}
	consume(source,options) {
		return tink_core_Future.flatMap(this.f,function(sink) {
			return sink.consume(source,options);
		});
	}
}
tink_io__$Sink_FutureSink.__name__ = "tink.io._Sink.FutureSink";
tink_io__$Sink_FutureSink.__super__ = tink_io_SinkBase;
Object.assign(tink_io__$Sink_FutureSink.prototype, {
	__class__: tink_io__$Sink_FutureSink
});
class tink_io__$Sink_ErrorSink extends tink_io_SinkBase {
	constructor(error) {
		super();
		this.error = error;
	}
	get_sealed() {
		return false;
	}
	consume(source,options) {
		return new tink_core__$Future_SyncFuture(new tink_core__$Lazy_LazyConst(tink_io_PipeResult.SinkFailed(this.error,source)));
	}
}
tink_io__$Sink_ErrorSink.__name__ = "tink.io._Sink.ErrorSink";
tink_io__$Sink_ErrorSink.__super__ = tink_io_SinkBase;
Object.assign(tink_io__$Sink_ErrorSink.prototype, {
	__class__: tink_io__$Sink_ErrorSink
});
class tink_streams_StreamObject {
}
tink_streams_StreamObject.__name__ = "tink.streams.StreamObject";
tink_streams_StreamObject.__isInterface__ = true;
Object.assign(tink_streams_StreamObject.prototype, {
	__class__: tink_streams_StreamObject
});
class tink_streams_StreamBase {
	constructor() {
		if(tink_streams_StreamBase._hx_skip_constructor) {
			return;
		}
		this._hx_constructor();
	}
	_hx_constructor() {
		this.retainCount = 0;
	}
	get_depleted() {
		return false;
	}
	retain() {
		this.retainCount++;
		let retained = true;
		let _gthis = this;
		return function() {
			if(retained) {
				retained = false;
				if(--_gthis.retainCount == 0) {
					_gthis.destroy();
				}
			}
		};
	}
	next() {
		throw haxe_Exception.thrown("not implemented");
	}
	regroup(f) {
		return new tink_streams__$Stream_RegroupStream(this,f);
	}
	map(f) {
		return this.regroup(f);
	}
	filter(f) {
		return this.regroup(f);
	}
	destroy() {
	}
	append(other) {
		if(this.get_depleted()) {
			return other;
		} else {
			return tink_streams__$Stream_CompoundStream.of([this,other]);
		}
	}
	prepend(other) {
		if(this.get_depleted()) {
			return other;
		} else {
			return tink_streams__$Stream_CompoundStream.of([other,this]);
		}
	}
	blend(other) {
		if(this.get_depleted()) {
			return other;
		} else {
			return new tink_streams_BlendStream(this,other);
		}
	}
	decompose(into) {
		if(!this.get_depleted()) {
			into.push(this);
		}
	}
	idealize(rescue) {
		if(this.get_depleted()) {
			return tink_streams_Empty.inst;
		} else {
			return new tink_streams_IdealizeStream(this,rescue);
		}
	}
	reduce(initial,reducer) {
		let _gthis = this;
		return tink_core_Future.async(function(cb) {
			_gthis.forEach(tink_streams_Handler.ofUnknown(function(item) {
				return tink_core_Future.map(reducer(initial,item),function(o) {
					switch(o._hx_index) {
					case 0:
						let v = o.result;
						initial = v;
						return tink_streams_Handled.Resume;
					case 1:
						let e = o.e;
						return tink_streams_Handled.Clog(e);
					}
				});
			})).handle(function(c) {
				switch(c._hx_index) {
				case 0:
					let _g = c.rest;
					throw haxe_Exception.thrown("assert");
				case 1:
					let e = c.error;
					let rest = c.at;
					cb(tink_streams_Reduction.Crashed(e,rest));
					break;
				case 2:
					let e1 = c.error;
					cb(tink_streams_Reduction.Failed(e1));
					break;
				case 3:
					cb(tink_streams_Reduction.Reduced(initial));
					break;
				}
			});
		});
	}
	forEach(handler) {
		throw haxe_Exception.thrown("not implemented");
	}
}
tink_streams_StreamBase.__name__ = "tink.streams.StreamBase";
tink_streams_StreamBase.__interfaces__ = [tink_streams_StreamObject];
Object.assign(tink_streams_StreamBase.prototype, {
	__class__: tink_streams_StreamBase
});
class tink_streams_Empty extends tink_streams_StreamBase {
	constructor() {
		super();
	}
	get_depleted() {
		return true;
	}
	next() {
		return new tink_core__$Future_SyncFuture(new tink_core__$Lazy_LazyConst(tink_streams_Step.End));
	}
	forEach(handler) {
		return new tink_core__$Future_SyncFuture(new tink_core__$Lazy_LazyConst(tink_streams_Conclusion.Depleted));
	}
	static make() {
		return tink_streams_Empty.inst;
	}
}
tink_streams_Empty.__name__ = "tink.streams.Empty";
tink_streams_Empty.__super__ = tink_streams_StreamBase;
Object.assign(tink_streams_Empty.prototype, {
	__class__: tink_streams_Empty
});
class tink_io_Source {
	static dirty(this1) {
		return this1;
	}
	static get_depleted(this1) {
		return this1.get_depleted();
	}
	static ofJsFile(name,file,options) {
		let chunkSize = options == null || options.chunkSize == null ? 16777216 : options.chunkSize;
		return new tink_io_js_BlobSource(name,file,0,chunkSize);
	}
	static ofJsBlob(name,blob,options) {
		let chunkSize = options == null || options.chunkSize == null ? 16777216 : options.chunkSize;
		return new tink_io_js_BlobSource(name,blob,0,chunkSize);
	}
	static ofInput(name,input,options) {
		if(options == null) {
			options = { };
		}
		let tmp = tink_io_Worker.ensure(options.worker);
		let length;
		let _g = options.chunkSize;
		if(_g == null) {
			length = 65536;
		} else {
			let v = _g;
			length = v;
		}
		return new tink_io_std_InputSource(name,input,tmp,new haxe_io_Bytes(new ArrayBuffer(length)),0);
	}
	static chunked(this1) {
		return this1;
	}
	static concatAll(s) {
		return s.reduce(tink_Chunk.EMPTY,tink_streams_Reducer.ofSafeSync(function(res,cur) {
			return tink_streams_ReductionStep.Progress(tink_Chunk.concat(res,cur));
		}));
	}
	static pipeTo(this1,target,options) {
		return target.consume(this1,options);
	}
	static append(this1,that) {
		return this1.append(that);
	}
	static prepend(this1,that) {
		return this1.prepend(that);
	}
	static transform(this1,transformer) {
		return transformer.transform(this1);
	}
	static skip(this1,len) {
		return this1.regroup(tink_streams_Regrouper.ofIgnoranceSync(function(chunks) {
			let chunk = chunks[0];
			if(len <= 0) {
				return tink_streams_RegroupResult.Converted(tink_streams_Stream.single(chunk));
			}
			let length = chunk.getLength();
			let out = tink_streams_RegroupResult.Converted(len < length ? tink_streams_Stream.single(chunk.slice(len,length)) : tink_streams_Empty.inst);
			len -= length;
			return out;
		}));
	}
	static limit(this1,len) {
		if(len == 0) {
			return tink_io_Source.EMPTY;
		}
		return this1.regroup(tink_streams_Regrouper.ofIgnoranceSync(function(chunks) {
			if(len <= 0) {
				return tink_streams_RegroupResult.Terminated(haxe_ds_Option.None);
			}
			let chunk = chunks[0];
			let length = chunk.getLength();
			let out = len == length ? tink_streams_RegroupResult.Terminated(haxe_ds_Option.Some(tink_streams_Stream.single(chunk))) : tink_streams_RegroupResult.Converted(tink_streams_Stream.single(len < length ? chunk.slice(0,len) : chunk));
			len -= length;
			return out;
		}));
	}
	static ofError(e) {
		return tink_streams_Stream.ofError(e);
	}
	static ofFuture(f) {
		return tink_streams_Stream.future(f);
	}
	static ofPromised(p) {
		return tink_streams_Stream.future(tink_core_Future.map(p,function(o) {
			switch(o._hx_index) {
			case 0:
				let s = o.data;
				return s;
			case 1:
				let e = o.failure;
				return tink_io_Source.ofError(e);
			}
		}));
	}
	static ofChunk(chunk) {
		return new tink_streams_Single(new tink_core__$Lazy_LazyConst(chunk));
	}
	static ofString(s) {
		return new tink_streams_Single(new tink_core__$Lazy_LazyConst(tink_chunk_ByteChunk.of(haxe_io_Bytes.ofString(s))));
	}
	static ofBytes(b) {
		return new tink_streams_Single(new tink_core__$Lazy_LazyConst(tink_chunk_ByteChunk.of(b)));
	}
	static ofFutureChunk(chunk) {
		return tink_io_Source.ofFuture(tink_core_Future.map(chunk,tink_io_Source.ofChunk));
	}
	static ofFutureString(s) {
		return tink_io_Source.ofFuture(tink_core_Future.map(s,tink_io_Source.ofString));
	}
	static ofFutureBytes(b) {
		return tink_io_Source.ofFuture(tink_core_Future.map(b,tink_io_Source.ofBytes));
	}
	static ofPromiseChunk(chunk) {
		return tink_io_Source.ofPromised(tink_core_Promise.next(chunk,tink_core_Next.ofSafeSync(tink_io_Source.ofChunk)));
	}
	static ofPromiseString(s) {
		return tink_io_Source.ofPromised(tink_core_Promise.next(s,tink_core_Next.ofSafeSync(tink_io_Source.ofString)));
	}
	static ofPromiseBytes(b) {
		return tink_io_Source.ofPromised(tink_core_Promise.next(b,tink_core_Next.ofSafeSync(tink_io_Source.ofBytes)));
	}
}
class tink_io_RealSourceTools {
	static all(s) {
		return tink_core_Future.map(tink_io_Source.concatAll(s),function(o) {
			switch(o._hx_index) {
			case 1:
				let e = o.error;
				return tink_core_Outcome.Failure(e);
			case 2:
				let c = o.result;
				return tink_core_Outcome.Success(c);
			}
		});
	}
	static parse(s,p) {
		return tink_core_Future.map(tink_io_StreamParser.parse(s,p),function(r) {
			switch(r._hx_index) {
			case 0:
				let data = r.data;
				let rest = r.rest;
				return tink_core_Outcome.Success(new tink_core_MPair(data,rest));
			case 1:
				let _g = r.rest;
				let e = r.e;
				return tink_core_Outcome.Failure(e);
			case 2:
				let e1 = r.e;
				return tink_core_Outcome.Failure(e1);
			}
		});
	}
	static split(src,delim) {
		let s = tink_io_RealSourceTools.parse(src,new tink_io_Splitter(delim));
		return { before : tink_streams_Stream.promise(tink_core_Promise.next(s,tink_core_Next.ofSafeSync(function(p) {
			let _g = p.a;
			switch(_g._hx_index) {
			case 0:
				let chunk = _g.v;
				return new tink_streams_Single(new tink_core__$Lazy_LazyConst(chunk));
			case 1:
				return src;
			}
		}))), delimiter : tink_core_Promise.next(s,function(p) {
			let _g = p.a;
			switch(_g._hx_index) {
			case 0:
				let _g1 = _g.v;
				return new tink_core__$Future_SyncFuture(new tink_core__$Lazy_LazyConst(tink_core_Outcome.Success(delim)));
			case 1:
				return new tink_core__$Future_SyncFuture(new tink_core__$Lazy_LazyConst(tink_core_Outcome.Failure(new tink_core_TypedError(404,"Delimiter not found",{ fileName : "tink/io/Source.hx", lineNumber : 213, className : "tink.io.RealSourceTools", methodName : "split"}))));
			}
		}), after : tink_streams_Stream.promise(tink_core_Promise.next(s,tink_core_Next.ofSafeSync(function(p) {
			return p.b;
		})))};
	}
	static parseStream(s,p) {
		return tink_io_StreamParser.parseStream(s,p);
	}
	static idealize(s,rescue) {
		return tink_io_Source.chunked(s).idealize(rescue);
	}
}
tink_io_RealSourceTools.__name__ = "tink.io.RealSourceTools";
class tink_io_IdealSourceTools {
	static all(s) {
		return tink_core_Future.map(tink_io_Source.concatAll(s),function(o) {
			let c = o.result;
			return c;
		});
	}
	static parse(s,p) {
		return tink_core_Future.map(tink_io_StreamParser.parse(s,p),function(r) {
			switch(r._hx_index) {
			case 0:
				let data = r.data;
				let rest = r.rest;
				return tink_core_Outcome.Success(new tink_core_MPair(data,rest));
			case 1:
				let _g = r.rest;
				let e = r.e;
				return tink_core_Outcome.Failure(e);
			}
		});
	}
	static parseStream(s,p) {
		return tink_io_StreamParser.parseStream(s,p);
	}
	static split(s,delim) {
		let s1 = tink_io_RealSourceTools.split(s,delim);
		return { before : tink_io_RealSourceTools.idealize(s1.before,function(e) {
			return tink_io_Source.EMPTY;
		}), delimiter : s1.delimiter, after : tink_io_RealSourceTools.idealize(s1.after,function(e) {
			return tink_io_Source.EMPTY;
		})};
	}
}
tink_io_IdealSourceTools.__name__ = "tink.io.IdealSourceTools";
var tink_io_ParseResult = $hxEnums["tink.io.ParseResult"] = { __ename__:true,__constructs__:null
	,Parsed: ($_=function(data,rest) { return {_hx_index:0,data:data,rest:rest,__enum__:"tink.io.ParseResult",toString:$estr}; },$_._hx_name="Parsed",$_.__params__ = ["data","rest"],$_)
	,Invalid: ($_=function(e,rest) { return {_hx_index:1,e:e,rest:rest,__enum__:"tink.io.ParseResult",toString:$estr}; },$_._hx_name="Invalid",$_.__params__ = ["e","rest"],$_)
	,Broke: ($_=function(e) { return {_hx_index:2,e:e,__enum__:"tink.io.ParseResult",toString:$estr}; },$_._hx_name="Broke",$_.__params__ = ["e"],$_)
};
tink_io_ParseResult.__constructs__ = [tink_io_ParseResult.Parsed,tink_io_ParseResult.Invalid,tink_io_ParseResult.Broke];
class tink_io_StreamParser {
	static doParse(source,p,consume,finish) {
		let cursor = tink_Chunk.EMPTY.getCursor();
		let resume = true;
		let mk = function(source) {
			if(cursor.currentPos < cursor.length) {
				return source.prepend(new tink_streams_Single(new tink_core__$Lazy_LazyConst(cursor.right())));
			} else {
				return source;
			}
		};
		let flush = function() {
			let _g = cursor.flush();
			let c = _g;
			if(c.getLength() == 0) {
				return tink_io_Source.EMPTY;
			} else {
				let c = _g;
				return new tink_streams_Single(new tink_core__$Lazy_LazyConst(c));
			}
		};
		return tink_core_Future.flatMap(source.forEach(tink_streams_Handler.ofUnknown(function(chunk) {
			if(chunk.getLength() == 0) {
				return new tink_core__$Future_SyncFuture(new tink_core__$Lazy_LazyConst(tink_streams_Handled.Resume));
			}
			cursor.shift(chunk);
			return tink_core_Future.async(function(cb) {
				let next = null;
				next = function() {
					cursor.shift();
					let lastPos = cursor.currentPos;
					let _g = p.progress(cursor);
					switch(_g._hx_index) {
					case 0:
						if(lastPos != cursor.currentPos && cursor.currentPos < cursor.length) {
							next();
						} else {
							cb(tink_streams_Handled.Resume);
						}
						break;
					case 1:
						let v = _g.r;
						consume(v).handle(function(o) {
							resume = o.resume;
							if(resume) {
								if(lastPos != cursor.currentPos && cursor.currentPos < cursor.length) {
									next();
								} else {
									cb(tink_streams_Handled.Resume);
								}
							} else {
								cb(tink_streams_Handled.Finish);
							}
						});
						break;
					case 2:
						let e = _g.e;
						cb(tink_streams_Handled.Clog(e));
						break;
					}
				};
				next();
			});
		})),function(c) {
			switch(c._hx_index) {
			case 0:
				let rest = c.rest;
				return new tink_core__$Future_SyncFuture(new tink_core__$Lazy_LazyConst(tink_io_ParseResult.Parsed(finish(),mk(rest))));
			case 1:
				let e = c.error;
				let rest1 = c.at;
				return new tink_core__$Future_SyncFuture(new tink_core__$Lazy_LazyConst(tink_io_ParseResult.Invalid(e,mk(rest1))));
			case 2:
				let e1 = c.error;
				return new tink_core__$Future_SyncFuture(new tink_core__$Lazy_LazyConst(tink_io_ParseResult.Broke(e1)));
			case 3:
				if(cursor.currentPos < cursor.length) {
					return new tink_core__$Future_SyncFuture(new tink_core__$Lazy_LazyConst(tink_io_ParseResult.Parsed(finish(),mk(new tink_streams_Single(new tink_core__$Lazy_LazyConst(tink_Chunk.EMPTY))))));
				} else if(!resume) {
					return new tink_core__$Future_SyncFuture(new tink_core__$Lazy_LazyConst(tink_io_ParseResult.Parsed(finish(),flush())));
				} else {
					let _g = p.eof(cursor);
					switch(_g._hx_index) {
					case 0:
						let result = _g.data;
						return tink_core_Future.map(consume(result),function(_) {
							return tink_io_ParseResult.Parsed(finish(),flush());
						});
					case 1:
						let e = _g.failure;
						return new tink_core__$Future_SyncFuture(new tink_core__$Lazy_LazyConst(tink_io_ParseResult.Invalid(e,flush())));
					}
				}
				break;
			}
		});
	}
	static parse(s,p) {
		let res = null;
		let onResult = function(r) {
			res = r;
			return new tink_core__$Future_SyncFuture(new tink_core__$Lazy_LazyConst({ resume : false}));
		};
		return tink_io_StreamParser.doParse(s,p,onResult,function() {
			return res;
		});
	}
	static parseStream(s,p) {
		let next = null;
		next = function(step) {
			if(s.get_depleted()) {
				step(tink_streams_Step.End);
			} else {
				tink_io_StreamParser.parse(s,p).handle(function(o) {
					switch(o._hx_index) {
					case 0:
						let result = o.data;
						let rest = o.rest;
						s = rest;
						step(tink_streams_Step.Link(result,tink_streams_Generator.stream(next)));
						break;
					case 1:
						let _g = o.rest;
						let e = o.e;
						step(tink_streams_Step.Fail(e));
						break;
					case 2:
						let e1 = o.e;
						step(tink_streams_Step.Fail(e1));
						break;
					}
				});
			}
		};
		return tink_streams_Generator.stream(next);
	}
}
class tink_io_Splitter extends tink_io_BytewiseParser {
	constructor(delim) {
		super();
		this.buf = tink_Chunk.EMPTY;
		this.delim = delim;
	}
	read(char) {
		if(char == -1) {
			return tink_io_ParseStep.Done(haxe_ds_Option.None);
		}
		this.buf = tink_Chunk.concat(this.buf,tink_chunk_ByteChunk.of(haxe_io_Bytes.ofString(String.fromCodePoint(char))));
		if(this.buf.getLength() >= this.delim.getLength()) {
			let bcursor = this.buf.getCursor();
			let delta = this.buf.getLength() - this.delim.getLength();
			bcursor.moveTo(bcursor.currentPos + delta);
			let dcursor = this.delim.getCursor();
			let _g = 0;
			let _g1 = this.delim.getLength();
			while(_g < _g1) {
				let i = _g++;
				if(bcursor.currentByte != dcursor.currentByte) {
					return tink_io_ParseStep.Progressed;
				} else {
					bcursor.next();
					dcursor.next();
				}
			}
			let out = tink_io_ParseStep.Done(haxe_ds_Option.Some(this.buf.slice(0,bcursor.currentPos - this.delim.getLength())));
			this.buf = tink_Chunk.EMPTY;
			return out;
		} else {
			return tink_io_ParseStep.Progressed;
		}
	}
}
tink_io_Splitter.__name__ = "tink.io.Splitter";
tink_io_Splitter.__super__ = tink_io_BytewiseParser;
Object.assign(tink_io_Splitter.prototype, {
	__class__: tink_io_Splitter
});
class tink_io_SimpleBytewiseParser extends tink_io_BytewiseParser {
	constructor(f) {
		super();
		this._read = f;
	}
	read(char) {
		return this._read(char);
	}
}
tink_io_SimpleBytewiseParser.__name__ = "tink.io.SimpleBytewiseParser";
tink_io_SimpleBytewiseParser.__super__ = tink_io_BytewiseParser;
Object.assign(tink_io_SimpleBytewiseParser.prototype, {
	__class__: tink_io_SimpleBytewiseParser
});
class tink_io_WorkerObject {
}
tink_io_WorkerObject.__name__ = "tink.io.WorkerObject";
tink_io_WorkerObject.__isInterface__ = true;
Object.assign(tink_io_WorkerObject.prototype, {
	__class__: tink_io_WorkerObject
});
class tink_io__$Worker_EagerWorker {
	constructor() {
	}
	work(task) {
		return new tink_core__$Future_SyncFuture(new tink_core__$Lazy_LazyConst(tink_core_Lazy.get(task)));
	}
}
tink_io__$Worker_EagerWorker.__name__ = "tink.io._Worker.EagerWorker";
tink_io__$Worker_EagerWorker.__interfaces__ = [tink_io_WorkerObject];
Object.assign(tink_io__$Worker_EagerWorker.prototype, {
	__class__: tink_io__$Worker_EagerWorker
});
class tink_io_Worker {
	static ensure(this1) {
		if(this1 == null) {
			return tink_io_Worker.get();
		} else {
			return this1;
		}
	}
	static get() {
		return tink_io_Worker.pool[Std.random(tink_io_Worker.pool.length)];
	}
	static work(this1,task) {
		return this1.work(task);
	}
}
class tink_streams_Generator extends tink_streams_StreamBase {
	constructor(upcoming) {
		if(tink_streams_StreamBase._hx_skip_constructor) {
			super();
			return;
		}
		tink_streams_StreamBase._hx_skip_constructor = true;
		super();
		tink_streams_StreamBase._hx_skip_constructor = false;
		this._hx_constructor(upcoming);
	}
	_hx_constructor(upcoming) {
		super._hx_constructor();
		this.upcoming = upcoming;
	}
	next() {
		return this.upcoming;
	}
	forEach(handler) {
		let _gthis = this;
		return tink_core_Future.async(function(cb) {
			_gthis.upcoming.handle(function(e) {
				switch(e._hx_index) {
				case 0:
					let v = e.value;
					let then = e.next;
					handler(v).handle(function(s) {
						switch(s._hx_index) {
						case 0:
							cb(tink_streams_Conclusion.Halted(_gthis));
							break;
						case 1:
							cb(tink_streams_Conclusion.Halted(then));
							break;
						case 2:
							then.forEach(handler).handle(cb);
							break;
						case 3:
							let e = s.e;
							cb(tink_streams_Conclusion.Clogged(e,_gthis));
							break;
						}
					});
					break;
				case 1:
					let e1 = e.e;
					cb(tink_streams_Conclusion.Failed(e1));
					break;
				case 2:
					cb(tink_streams_Conclusion.Depleted);
					break;
				}
			});
		});
	}
	static stream(step) {
		return new tink_streams_Generator(tink_core_Future.async(step));
	}
}
tink_streams_Generator.__name__ = "tink.streams.Generator";
tink_streams_Generator.__super__ = tink_streams_StreamBase;
Object.assign(tink_streams_Generator.prototype, {
	__class__: tink_streams_Generator
});
class tink_io_js_BlobSource extends tink_streams_Generator {
	constructor(name,blob,pos,chunkSize) {
		tink_streams_StreamBase._hx_skip_constructor = true;
		super();
		tink_streams_StreamBase._hx_skip_constructor = false;
		this._hx_constructor(name,blob,pos,chunkSize);
	}
	_hx_constructor(name,blob,pos,chunkSize) {
		this.name = name;
		super._hx_constructor(tink_core_Future.async(function(cb) {
			if(pos >= blob.size) {
				cb(tink_streams_Step.End);
			} else {
				let end = pos + chunkSize;
				if(end > blob.size) {
					end = blob.size;
				}
				let reader = new FileReader();
				reader.onload = function() {
					let chunk = tink_chunk_ByteChunk.of(haxe_io_Bytes.ofData(reader.result));
					cb(tink_streams_Step.Link(chunk,new tink_io_js_BlobSource(name,blob,end,chunkSize)));
				};
				reader.onerror = function(e) {
					cb(tink_streams_Step.Fail(tink_core_TypedError.withData(500,e.message,e,{ fileName : "tink/io/js/BlobSource.hx", lineNumber : 29, className : "tink.io.js.BlobSource", methodName : "new"})));
				};
				reader.readAsArrayBuffer(blob.slice(pos,end));
			}
		},true));
	}
	static wrap(name,blob,chunkSize) {
		return new tink_io_js_BlobSource(name,blob,0,chunkSize);
	}
}
tink_io_js_BlobSource.__name__ = "tink.io.js.BlobSource";
tink_io_js_BlobSource.__super__ = tink_streams_Generator;
Object.assign(tink_io_js_BlobSource.prototype, {
	__class__: tink_io_js_BlobSource
});
class tink_io_std_InputSource extends tink_streams_Generator {
	constructor(name,target,worker,buf,offset) {
		let next = function(buf,offset) {
			return new tink_io_std_InputSource(name,target,worker,buf,offset);
		};
		let free = buf.length - offset;
		super(tink_core_Future.async(function(cb) {
			tink_io_Worker.work(worker,new tink_core__$Lazy_LazyFunc(function() {
				try {
					let read = target.readBytes(buf,offset,free);
					if(read == 0) {
						return tink_streams_Step.Link(tink_Chunk.EMPTY,next(buf,offset));
					} else {
						let nextOffset = free - read < 1024 ? 0 : offset + read;
						let nextBuf = nextOffset == 0 ? new haxe_io_Bytes(new ArrayBuffer(buf.length)) : buf;
						return tink_streams_Step.Link(tink_chunk_ByteChunk.of(buf).slice(offset,offset + read),next(nextBuf,nextOffset));
					}
				} catch( _g ) {
					let _g1 = haxe_Exception.caught(_g).unwrap();
					if(((_g1) instanceof haxe_io_Eof)) {
						return tink_streams_Step.End;
					} else if(js_Boot.__instanceof(_g1,haxe_io_Error)) {
						let e = _g1;
						if(e._hx_index == 0) {
							return tink_streams_Step.Link(tink_Chunk.EMPTY,next(buf,offset));
						} else {
							return tink_streams_Step.Fail(tink_core_TypedError.withData(null,"Failed to read from " + name,e,{ fileName : "tink/io/std/InputSource.hx", lineNumber : 50, className : "tink.io.std.InputSource", methodName : "new"}));
						}
					} else {
						throw _g;
					}
				}
			})).handle(function(step) {
				switch(step._hx_index) {
				case 1:
					let _g = step.e;
					try {
						target.close();
					} catch( _g ) {
					}
					break;
				case 2:
					try {
						target.close();
					} catch( _g ) {
					}
					break;
				default:
				}
				cb(step);
			});
		},true));
	}
}
tink_io_std_InputSource.__name__ = "tink.io.std.InputSource";
tink_io_std_InputSource.__super__ = tink_streams_Generator;
Object.assign(tink_io_std_InputSource.prototype, {
	__class__: tink_io_std_InputSource
});
class tink_io_std_OutputSink extends tink_io_SinkBase {
	constructor(name,target,worker) {
		super();
		this.name = name;
		this.target = target;
		this.worker = worker;
	}
	consume(source,options) {
		let rest = tink_Chunk.EMPTY;
		let _gthis = this;
		let ret = source.forEach(tink_streams_Handler.ofUnknown(function(c) {
			return tink_core_Future.async(function(cb) {
				let pos = 0;
				let bytes = c.toBytes();
				let write = null;
				write = function() {
					if(pos == bytes.length) {
						cb(tink_streams_Handled.Resume);
					} else {
						tink_io_Worker.work(_gthis.worker,new tink_core__$Lazy_LazyFunc(function() {
							try {
								return tink_core_Outcome.Success(_gthis.target.writeBytes(bytes,pos,bytes.length - pos));
							} catch( _g ) {
								let _g1 = haxe_Exception.caught(_g).unwrap();
								if(((_g1) instanceof haxe_io_Eof)) {
									return tink_core_Outcome.Success(-1);
								} else if(js_Boot.__instanceof(_g1,haxe_io_Error)) {
									let e = _g1;
									if(e._hx_index == 0) {
										return tink_core_Outcome.Success(0);
									} else {
										return tink_core_Outcome.Failure(tink_core_TypedError.withData(null,"Error writing to " + _gthis.name,e,{ fileName : "tink/io/std/OutputSink.hx", lineNumber : 40, className : "tink.io.std.OutputSink", methodName : "consume"}));
									}
								} else if(((_g1) instanceof tink_core_TypedError)) {
									let e = _g1;
									return tink_core_Outcome.Failure(e);
								} else {
									let e = _g1;
									return tink_core_Outcome.Failure(tink_core_TypedError.withData(null,"Error writing to " + _gthis.name,e,{ fileName : "tink/io/std/OutputSink.hx", lineNumber : 46, className : "tink.io.std.OutputSink", methodName : "consume"}));
								}
							}
						})).handle(function(o) {
							switch(o._hx_index) {
							case 0:
								let _g = o.data;
								if(_g == -1) {
									rest = tink_chunk_ByteChunk.of(bytes).slice(pos,bytes.length);
									cb(tink_streams_Handled.Finish);
								} else {
									let v = _g;
									pos += v;
									if(pos == bytes.length) {
										cb(tink_streams_Handled.Resume);
									} else {
										write();
									}
								}
								break;
							case 1:
								let e = o.failure;
								cb(tink_streams_Handled.Clog(e));
								break;
							}
						});
					}
				};
				write();
			});
		}));
		if(options != null && options.end) {
			ret.handle(function(end) {
				try {
					_gthis.target.close();
				} catch( _g ) {
				}
			});
		}
		return tink_core_Future.map(ret,function(c) {
			return tink_io_PipeResultTools.toResult(c,null,rest);
		});
	}
}
tink_io_std_OutputSink.__name__ = "tink.io.std.OutputSink";
tink_io_std_OutputSink.__super__ = tink_io_SinkBase;
Object.assign(tink_io_std_OutputSink.prototype, {
	__class__: tink_io_std_OutputSink
});
class tink_streams_IdealStream {
	static promiseOfIdealStream(p) {
		return tink_streams_Stream.promise(p);
	}
	static promiseOfStreamNoise(p) {
		return tink_streams_Stream.promise(p);
	}
	static collect(this1) {
		let buf = [];
		return tink_core_Future.map(this1.forEach(tink_streams_Handler.ofSafeSync(function(x) {
			buf.push(x);
			return tink_streams_Handled.Resume;
		})),function(c) {
			return buf;
		});
	}
}
class tink_streams_IdealStreamBase extends tink_streams_StreamBase {
	constructor() {
		super();
	}
	idealize(rescue) {
		return this;
	}
}
tink_streams_IdealStreamBase.__name__ = "tink.streams.IdealStreamBase";
tink_streams_IdealStreamBase.__super__ = tink_streams_StreamBase;
Object.assign(tink_streams_IdealStreamBase.prototype, {
	__class__: tink_streams_IdealStreamBase
});
class tink_streams_RealStream {
	static promiseOfIdealStream(p) {
		return tink_streams_Stream.promise(p);
	}
	static promiseOfStreamNoise(p) {
		return tink_streams_Stream.promise(p);
	}
	static promiseOfRealStream(p) {
		return tink_streams_Stream.promise(p);
	}
	static promiseOfStreamError(p) {
		return tink_streams_Stream.promise(p);
	}
	static collect(this1) {
		let buf = [];
		return tink_core_Future.map(this1.forEach(tink_streams_Handler.ofSafeSync(function(x) {
			buf.push(x);
			return tink_streams_Handled.Resume;
		})),function(c) {
			switch(c._hx_index) {
			case 0:
				let _g = c.rest;
				throw haxe_Exception.thrown("unreachable");
			case 2:
				let e = c.error;
				return tink_core_Outcome.Failure(e);
			case 3:
				return tink_core_Outcome.Success(buf);
			}
		});
	}
}
class tink_streams_Stream {
	static get_depleted(this1) {
		return this1.get_depleted();
	}
	static dirty(this1) {
		return this1;
	}
	static single(i) {
		return new tink_streams_Single(new tink_core__$Lazy_LazyConst(i));
	}
	static ofIterator(i) {
		let next = null;
		next = function(step) {
			step(i.hasNext() ? tink_streams_Step.Link(i.next(),tink_streams_Generator.stream(next)) : tink_streams_Step.End);
		};
		return tink_streams_Generator.stream(next);
	}
	static flatten(stream) {
		return stream.regroup(tink_streams_Regrouper.ofIgnoranceSync(function(arr) {
			return tink_streams_RegroupResult.Converted(arr[0]);
		}));
	}
	static future(f) {
		return new tink_streams_FutureStream(f);
	}
	static promiseIdeal(f) {
		return tink_streams_Stream.promise(f);
	}
	static promiseReal(f) {
		return tink_streams_Stream.promise(f);
	}
	static promise(f) {
		return tink_streams_Stream.future(tink_core_Future.map(f,function(o) {
			switch(o._hx_index) {
			case 0:
				let s = o.data;
				return tink_streams_Stream.dirty(s);
			case 1:
				let e = o.failure;
				return tink_streams_Stream.ofError(e);
			}
		}));
	}
	static ofError(e) {
		return new tink_streams__$Stream_ErrorStream(e);
	}
}
var tink_streams_RegroupStatus = $hxEnums["tink.streams.RegroupStatus"] = { __ename__:true,__constructs__:null
	,Flowing: {_hx_name:"Flowing",_hx_index:0,__enum__:"tink.streams.RegroupStatus",toString:$estr}
	,Errored: ($_=function(e) { return {_hx_index:1,e:e,__enum__:"tink.streams.RegroupStatus",toString:$estr}; },$_._hx_name="Errored",$_.__params__ = ["e"],$_)
	,Ended: {_hx_name:"Ended",_hx_index:2,__enum__:"tink.streams.RegroupStatus",toString:$estr}
};
tink_streams_RegroupStatus.__constructs__ = [tink_streams_RegroupStatus.Flowing,tink_streams_RegroupStatus.Errored,tink_streams_RegroupStatus.Ended];
var tink_streams_RegroupResult = $hxEnums["tink.streams.RegroupResult"] = { __ename__:true,__constructs__:null
	,Converted: ($_=function(data,untouched) { return {_hx_index:0,data:data,untouched:untouched,__enum__:"tink.streams.RegroupResult",toString:$estr}; },$_._hx_name="Converted",$_.__params__ = ["data","untouched"],$_)
	,Terminated: ($_=function(data) { return {_hx_index:1,data:data,__enum__:"tink.streams.RegroupResult",toString:$estr}; },$_._hx_name="Terminated",$_.__params__ = ["data"],$_)
	,Untouched: {_hx_name:"Untouched",_hx_index:2,__enum__:"tink.streams.RegroupResult",toString:$estr}
	,Errored: ($_=function(e) { return {_hx_index:3,e:e,__enum__:"tink.streams.RegroupResult",toString:$estr}; },$_._hx_name="Errored",$_.__params__ = ["e"],$_)
};
tink_streams_RegroupResult.__constructs__ = [tink_streams_RegroupResult.Converted,tink_streams_RegroupResult.Terminated,tink_streams_RegroupResult.Untouched,tink_streams_RegroupResult.Errored];
class tink_streams_Regrouper {
	static ofIgnorance(f) {
		return { apply : function(i,_) {
			return f(i);
		}};
	}
	static ofIgnoranceSync(f) {
		return { apply : function(i,_) {
			return new tink_core__$Future_SyncFuture(new tink_core__$Lazy_LazyConst(f(i)));
		}};
	}
	static ofFunc(f) {
		return { apply : f};
	}
	static ofFuncSync(f) {
		return { apply : function(i,s) {
			return new tink_core__$Future_SyncFuture(new tink_core__$Lazy_LazyConst(f(i,s)));
		}};
	}
}
class tink_streams__$Stream_CompoundStream extends tink_streams_StreamBase {
	constructor(parts) {
		super();
		this.parts = parts;
	}
	get_depleted() {
		switch(this.parts.length) {
		case 0:
			return true;
		case 1:
			return this.parts[0].get_depleted();
		default:
			return false;
		}
	}
	next() {
		let _gthis = this;
		if(this.parts.length == 0) {
			return new tink_core__$Future_SyncFuture(new tink_core__$Lazy_LazyConst(tink_streams_Step.End));
		} else {
			return tink_core_Future.flatMap(this.parts[0].next(),function(v) {
				switch(v._hx_index) {
				case 0:
					let v1 = v.value;
					let rest = v.next;
					let copy = _gthis.parts.slice();
					copy[0] = rest;
					return new tink_core__$Future_SyncFuture(new tink_core__$Lazy_LazyConst(tink_streams_Step.Link(v1,new tink_streams__$Stream_CompoundStream(copy))));
				case 2:
					if(_gthis.parts.length > 1) {
						return _gthis.parts[1].next();
					} else {
						return new tink_core__$Future_SyncFuture(new tink_core__$Lazy_LazyConst(v));
					}
					break;
				default:
					return new tink_core__$Future_SyncFuture(new tink_core__$Lazy_LazyConst(v));
				}
			});
		}
	}
	decompose(into) {
		let _g = 0;
		let _g1 = this.parts;
		while(_g < _g1.length) {
			let p = _g1[_g];
			++_g;
			p.decompose(into);
		}
	}
	forEach(handler) {
		let parts = this.parts;
		let handler1 = handler;
		return tink_core_Future.async(function(cb) {
			tink_streams__$Stream_CompoundStream.consumeParts(parts,handler1,cb);
		});
	}
	static consumeParts(parts,handler,cb) {
		if(parts.length == 0) {
			cb(tink_streams_Conclusion.Depleted);
		} else {
			parts[0].forEach(handler).handle(function(o) {
				switch(o._hx_index) {
				case 0:
					let rest = o.rest;
					parts = parts.slice();
					parts[0] = rest;
					cb(tink_streams_Conclusion.Halted(new tink_streams__$Stream_CompoundStream(parts)));
					break;
				case 1:
					let e = o.error;
					let at = o.at;
					if(at.get_depleted()) {
						parts = parts.slice(1);
					} else {
						parts = parts.slice();
						parts[0] = at;
					}
					cb(tink_streams_Conclusion.Clogged(e,new tink_streams__$Stream_CompoundStream(parts)));
					break;
				case 2:
					let e1 = o.error;
					cb(tink_streams_Conclusion.Failed(e1));
					break;
				case 3:
					tink_streams__$Stream_CompoundStream.consumeParts(parts.slice(1),handler,cb);
					break;
				}
			});
		}
	}
	static of(streams) {
		let ret = [];
		let _g = 0;
		while(_g < streams.length) {
			let s = streams[_g];
			++_g;
			s.decompose(ret);
		}
		if(ret.length == 0) {
			return tink_streams_Empty.inst;
		} else {
			return new tink_streams__$Stream_CompoundStream(ret);
		}
	}
}
tink_streams__$Stream_CompoundStream.__name__ = "tink.streams._Stream.CompoundStream";
tink_streams__$Stream_CompoundStream.__super__ = tink_streams_StreamBase;
Object.assign(tink_streams__$Stream_CompoundStream.prototype, {
	__class__: tink_streams__$Stream_CompoundStream
});
class tink_streams__$Stream_RegroupStream extends tink_streams__$Stream_CompoundStream {
	constructor(source,f,prev,buf) {
		if(prev == null) {
			prev = tink_streams_Empty.inst;
		}
		if(buf == null) {
			buf = [];
		}
		let ret = null;
		let terminated = false;
		let next = tink_streams_Stream.future(tink_core_Future.map(source.forEach(tink_streams_Handler.ofUnknown(function(item) {
			buf.push(item);
			return tink_core_Future.map(f.apply(buf,tink_streams_RegroupStatus.Flowing),function(o) {
				switch(o._hx_index) {
				case 0:
					let v = o.data;
					let untouched = o.untouched;
					ret = v;
					buf = untouched;
					return tink_streams_Handled.Finish;
				case 1:
					let v1 = o.data;
					let l = new tink_core__$Lazy_LazyFunc(tink_streams_Empty.make);
					if(v1._hx_index == 0) {
						let v = v1.v;
						ret = v;
					} else {
						ret = tink_core_Lazy.get(l);
					}
					terminated = true;
					return tink_streams_Handled.Finish;
				case 2:
					return tink_streams_Handled.Resume;
				case 3:
					let e = o.e;
					return tink_streams_Handled.Clog(e);
				}
			});
		})),function(o) {
			switch(o._hx_index) {
			case 0:
				if(terminated) {
					return ret;
				} else {
					let rest = o.rest;
					return new tink_streams__$Stream_RegroupStream(rest,f,ret,buf);
				}
				break;
			case 1:
				let _g = o.at;
				let e = o.error;
				return new tink_streams__$Stream_ErrorStream(e);
			case 2:
				let e1 = o.error;
				return tink_streams_Stream.ofError(e1);
			case 3:
				if(buf.length == 0) {
					return tink_streams_Empty.inst;
				} else {
					return tink_streams_Stream.future(tink_core_Future.map(f.apply(buf,tink_streams_RegroupStatus.Ended),function(o) {
						switch(o._hx_index) {
						case 0:
							let _g = o.untouched;
							let v = o.data;
							return v;
						case 1:
							let v1 = o.data;
							let l = new tink_core__$Lazy_LazyFunc(tink_streams_Empty.make);
							if(v1._hx_index == 0) {
								let v = v1.v;
								return v;
							} else {
								return tink_core_Lazy.get(l);
							}
							break;
						case 2:
							return tink_streams_Empty.inst;
						case 3:
							let e = o.e;
							return tink_streams_Stream.ofError(e);
						}
					}));
				}
				break;
			}
		}));
		super([prev,next]);
	}
}
tink_streams__$Stream_RegroupStream.__name__ = "tink.streams._Stream.RegroupStream";
tink_streams__$Stream_RegroupStream.__super__ = tink_streams__$Stream_CompoundStream;
Object.assign(tink_streams__$Stream_RegroupStream.prototype, {
	__class__: tink_streams__$Stream_RegroupStream
});
var tink_streams_Handled = $hxEnums["tink.streams.Handled"] = { __ename__:true,__constructs__:null
	,BackOff: {_hx_name:"BackOff",_hx_index:0,__enum__:"tink.streams.Handled",toString:$estr}
	,Finish: {_hx_name:"Finish",_hx_index:1,__enum__:"tink.streams.Handled",toString:$estr}
	,Resume: {_hx_name:"Resume",_hx_index:2,__enum__:"tink.streams.Handled",toString:$estr}
	,Clog: ($_=function(e) { return {_hx_index:3,e:e,__enum__:"tink.streams.Handled",toString:$estr}; },$_._hx_name="Clog",$_.__params__ = ["e"],$_)
};
tink_streams_Handled.__constructs__ = [tink_streams_Handled.BackOff,tink_streams_Handled.Finish,tink_streams_Handled.Resume,tink_streams_Handled.Clog];
var tink_streams_Conclusion = $hxEnums["tink.streams.Conclusion"] = { __ename__:true,__constructs__:null
	,Halted: ($_=function(rest) { return {_hx_index:0,rest:rest,__enum__:"tink.streams.Conclusion",toString:$estr}; },$_._hx_name="Halted",$_.__params__ = ["rest"],$_)
	,Clogged: ($_=function(error,at) { return {_hx_index:1,error:error,at:at,__enum__:"tink.streams.Conclusion",toString:$estr}; },$_._hx_name="Clogged",$_.__params__ = ["error","at"],$_)
	,Failed: ($_=function(error) { return {_hx_index:2,error:error,__enum__:"tink.streams.Conclusion",toString:$estr}; },$_._hx_name="Failed",$_.__params__ = ["error"],$_)
	,Depleted: {_hx_name:"Depleted",_hx_index:3,__enum__:"tink.streams.Conclusion",toString:$estr}
};
tink_streams_Conclusion.__constructs__ = [tink_streams_Conclusion.Halted,tink_streams_Conclusion.Clogged,tink_streams_Conclusion.Failed,tink_streams_Conclusion.Depleted];
var tink_streams_ReductionStep = $hxEnums["tink.streams.ReductionStep"] = { __ename__:true,__constructs__:null
	,Progress: ($_=function(result) { return {_hx_index:0,result:result,__enum__:"tink.streams.ReductionStep",toString:$estr}; },$_._hx_name="Progress",$_.__params__ = ["result"],$_)
	,Crash: ($_=function(e) { return {_hx_index:1,e:e,__enum__:"tink.streams.ReductionStep",toString:$estr}; },$_._hx_name="Crash",$_.__params__ = ["e"],$_)
};
tink_streams_ReductionStep.__constructs__ = [tink_streams_ReductionStep.Progress,tink_streams_ReductionStep.Crash];
var tink_streams_Reduction = $hxEnums["tink.streams.Reduction"] = { __ename__:true,__constructs__:null
	,Crashed: ($_=function(error,at) { return {_hx_index:0,error:error,at:at,__enum__:"tink.streams.Reduction",toString:$estr}; },$_._hx_name="Crashed",$_.__params__ = ["error","at"],$_)
	,Failed: ($_=function(error) { return {_hx_index:1,error:error,__enum__:"tink.streams.Reduction",toString:$estr}; },$_._hx_name="Failed",$_.__params__ = ["error"],$_)
	,Reduced: ($_=function(result) { return {_hx_index:2,result:result,__enum__:"tink.streams.Reduction",toString:$estr}; },$_._hx_name="Reduced",$_.__params__ = ["result"],$_)
};
tink_streams_Reduction.__constructs__ = [tink_streams_Reduction.Crashed,tink_streams_Reduction.Failed,tink_streams_Reduction.Reduced];
class tink_streams__$Stream_CloggedStream extends tink_streams_StreamBase {
	constructor(rest,error) {
		super();
		this.rest = rest;
		this.error = error;
	}
	next() {
		return new tink_core__$Future_SyncFuture(new tink_core__$Lazy_LazyConst(tink_streams_Step.Fail(this.error)));
	}
	forEach(handler) {
		return new tink_core__$Future_SyncFuture(new tink_core__$Lazy_LazyConst(tink_streams_Conclusion.Clogged(this.error,this.rest)));
	}
}
tink_streams__$Stream_CloggedStream.__name__ = "tink.streams._Stream.CloggedStream";
tink_streams__$Stream_CloggedStream.__super__ = tink_streams_StreamBase;
Object.assign(tink_streams__$Stream_CloggedStream.prototype, {
	__class__: tink_streams__$Stream_CloggedStream
});
class tink_streams__$Stream_ErrorStream extends tink_streams_StreamBase {
	constructor(error) {
		super();
		this.error = error;
	}
	next() {
		return new tink_core__$Future_SyncFuture(new tink_core__$Lazy_LazyConst(tink_streams_Step.Fail(this.error)));
	}
	forEach(handler) {
		return new tink_core__$Future_SyncFuture(new tink_core__$Lazy_LazyConst(tink_streams_Conclusion.Failed(this.error)));
	}
}
tink_streams__$Stream_ErrorStream.__name__ = "tink.streams._Stream.ErrorStream";
tink_streams__$Stream_ErrorStream.__super__ = tink_streams_StreamBase;
Object.assign(tink_streams__$Stream_ErrorStream.prototype, {
	__class__: tink_streams__$Stream_ErrorStream
});
class tink_streams_Mapping {
	static _new(o) {
		return o;
	}
	static ofNext(n) {
		return { apply : function(i,_) {
			let this1 = tink_core_Promise.next(n(i[0]),function(o) {
				return new tink_core__$Future_SyncFuture(new tink_core__$Lazy_LazyConst(tink_core_Outcome.Success(tink_streams_RegroupResult.Converted(tink_streams_Stream.single(o)))));
			});
			let f = tink_core_Recover.ofSync(tink_streams_RegroupResult.Errored);
			return tink_core_Future.flatMap(this1,function(o) {
				switch(o._hx_index) {
				case 0:
					let d = o.data;
					return new tink_core__$Future_SyncFuture(new tink_core__$Lazy_LazyConst(d));
				case 1:
					let e = o.failure;
					return f(e);
				}
			});
		}};
	}
	static ofAsync(f) {
		return { apply : function(i,_) {
			return tink_core_Future.map(f(i[0]),function(o) {
				return tink_streams_RegroupResult.Converted(tink_streams_Stream.single(o));
			});
		}};
	}
	static ofSync(f) {
		return { apply : function(i,_) {
			let v;
			let _g = f(i[0]);
			switch(_g._hx_index) {
			case 0:
				let v1 = _g.data;
				v = tink_streams_RegroupResult.Converted(tink_streams_Stream.single(v1));
				break;
			case 1:
				let e = _g.failure;
				v = tink_streams_RegroupResult.Errored(e);
				break;
			}
			return new tink_core__$Future_SyncFuture(new tink_core__$Lazy_LazyConst(v));
		}};
	}
	static ofPlain(f) {
		return { apply : function(i,_) {
			return new tink_core__$Future_SyncFuture(new tink_core__$Lazy_LazyConst(tink_streams_RegroupResult.Converted(tink_streams_Stream.single(f(i[0])))));
		}};
	}
}
class tink_streams_Filter {
	static _new(o) {
		return o;
	}
	static ofNext(n) {
		return { apply : function(i,_) {
			let this1 = tink_core_Promise.next(n(i[0]),function(matched) {
				return new tink_core__$Future_SyncFuture(new tink_core__$Lazy_LazyConst(tink_core_Outcome.Success(tink_streams_RegroupResult.Converted(matched ? tink_streams_Stream.single(i[0]) : tink_streams_Empty.inst))));
			});
			let f = tink_core_Recover.ofSync(tink_streams_RegroupResult.Errored);
			return tink_core_Future.flatMap(this1,function(o) {
				switch(o._hx_index) {
				case 0:
					let d = o.data;
					return new tink_core__$Future_SyncFuture(new tink_core__$Lazy_LazyConst(d));
				case 1:
					let e = o.failure;
					return f(e);
				}
			});
		}};
	}
	static ofAsync(f) {
		return { apply : function(i,_) {
			return tink_core_Future.map(f(i[0]),function(matched) {
				return tink_streams_RegroupResult.Converted(matched ? tink_streams_Stream.single(i[0]) : tink_streams_Empty.inst);
			});
		}};
	}
	static ofSync(f) {
		return { apply : function(i,_) {
			let v;
			let _g = f(i[0]);
			switch(_g._hx_index) {
			case 0:
				let v1 = _g.data;
				v = tink_streams_RegroupResult.Converted(v1 ? tink_streams_Stream.single(i[0]) : tink_streams_Empty.inst);
				break;
			case 1:
				let e = _g.failure;
				v = tink_streams_RegroupResult.Errored(e);
				break;
			}
			return new tink_core__$Future_SyncFuture(new tink_core__$Lazy_LazyConst(v));
		}};
	}
	static ofPlain(f) {
		return { apply : function(i,_) {
			return new tink_core__$Future_SyncFuture(new tink_core__$Lazy_LazyConst(tink_streams_RegroupResult.Converted(f(i[0]) ? tink_streams_Stream.single(i[0]) : tink_streams_Empty.inst)));
		}};
	}
}
class tink_streams_IdealizeStream extends tink_streams_IdealStreamBase {
	constructor(target,rescue) {
		super();
		this.target = target;
		this.rescue = rescue;
	}
	get_depleted() {
		return this.target.get_depleted();
	}
	next() {
		let _gthis = this;
		return tink_core_Future.flatMap(this.target.next(),function(v) {
			if(v._hx_index == 1) {
				let e = v.e;
				return _gthis.rescue(e).idealize(_gthis.rescue).next();
			} else {
				return new tink_core__$Future_SyncFuture(new tink_core__$Lazy_LazyConst(v));
			}
		});
	}
	forEach(handler) {
		let _gthis = this;
		return tink_core_Future.async(function(cb) {
			_gthis.target.forEach(handler).handle(function(end) {
				switch(end._hx_index) {
				case 0:
					let rest = end.rest;
					cb(tink_streams_Conclusion.Halted(rest.idealize(_gthis.rescue)));
					break;
				case 1:
					let e = end.error;
					let at = end.at;
					cb(tink_streams_Conclusion.Clogged(e,at.idealize(_gthis.rescue)));
					break;
				case 2:
					let e1 = end.error;
					_gthis.rescue(e1).idealize(_gthis.rescue).forEach(handler).handle(cb);
					break;
				case 3:
					cb(tink_streams_Conclusion.Depleted);
					break;
				}
			});
		});
	}
}
tink_streams_IdealizeStream.__name__ = "tink.streams.IdealizeStream";
tink_streams_IdealizeStream.__super__ = tink_streams_IdealStreamBase;
Object.assign(tink_streams_IdealizeStream.prototype, {
	__class__: tink_streams_IdealizeStream
});
class tink_streams_Single extends tink_streams_StreamBase {
	constructor(value) {
		super();
		this.value = value;
	}
	next() {
		return new tink_core__$Future_SyncFuture(new tink_core__$Lazy_LazyConst(tink_streams_Step.Link(tink_core_Lazy.get(this.value),tink_streams_Empty.inst)));
	}
	forEach(handle) {
		let _gthis = this;
		return tink_core_Future.map(handle(tink_core_Lazy.get(this.value)),function(step) {
			switch(step._hx_index) {
			case 0:
				return tink_streams_Conclusion.Halted(_gthis);
			case 1:
				return tink_streams_Conclusion.Halted(tink_streams_Empty.inst);
			case 2:
				return tink_streams_Conclusion.Depleted;
			case 3:
				let e = step.e;
				return tink_streams_Conclusion.Clogged(e,_gthis);
			}
		});
	}
}
tink_streams_Single.__name__ = "tink.streams.Single";
tink_streams_Single.__super__ = tink_streams_StreamBase;
Object.assign(tink_streams_Single.prototype, {
	__class__: tink_streams_Single
});
class tink_streams_Handler {
	static _new(f) {
		return f;
	}
	static apply(this1,item) {
		return this1(item);
	}
	static ofSafeSync(f) {
		return function(i) {
			return new tink_core__$Future_SyncFuture(new tink_core__$Lazy_LazyConst(f(i)));
		};
	}
	static ofUnknownSync(f) {
		return function(i) {
			return new tink_core__$Future_SyncFuture(new tink_core__$Lazy_LazyConst(f(i)));
		};
	}
	static ofSafe(f) {
		return f;
	}
	static ofUnknown(f) {
		return f;
	}
}
class tink_streams_Reducer {
	static _new(f) {
		return f;
	}
	static apply(this1,res,item) {
		return this1(res,item);
	}
	static ofSafeSync(f) {
		return function(res,cur) {
			return new tink_core__$Future_SyncFuture(new tink_core__$Lazy_LazyConst(f(res,cur)));
		};
	}
	static ofUnknownSync(f) {
		return function(res,cur) {
			return new tink_core__$Future_SyncFuture(new tink_core__$Lazy_LazyConst(f(res,cur)));
		};
	}
	static ofSafe(f) {
		return f;
	}
	static ofPlainSync(f) {
		return function(res,cur) {
			return new tink_core__$Future_SyncFuture(new tink_core__$Lazy_LazyConst(tink_streams_ReductionStep.Progress(f(res,cur))));
		};
	}
	static ofUnknown(f) {
		return f;
	}
	static ofPromiseBased(f) {
		return function(res,cur) {
			return tink_core_Future.map(f(res,cur),function(s) {
				switch(s._hx_index) {
				case 0:
					let r = s.data;
					return tink_streams_ReductionStep.Progress(r);
				case 1:
					let e = s.failure;
					return tink_streams_ReductionStep.Crash(e);
				}
			});
		};
	}
}
class tink_streams_FutureStream extends tink_streams_StreamBase {
	constructor(f) {
		super();
		this.f = f;
	}
	next() {
		return tink_core_Future.flatMap(this.f,function(s) {
			return s.next();
		});
	}
	forEach(handler) {
		let _gthis = this;
		return tink_core_Future.async(function(cb) {
			_gthis.f.handle(function(s) {
				s.forEach(handler).handle(cb);
			});
		});
	}
}
tink_streams_FutureStream.__name__ = "tink.streams.FutureStream";
tink_streams_FutureStream.__super__ = tink_streams_StreamBase;
Object.assign(tink_streams_FutureStream.prototype, {
	__class__: tink_streams_FutureStream
});
class tink_streams_BlendStream extends tink_streams_Generator {
	constructor(a,b) {
		let first = null;
		let wait = function(s) {
			return tink_core_Future.map(s.next(),function(o) {
				if(first == null) {
					first = s;
				}
				return o;
			});
		};
		let n1 = wait(a);
		let n2 = wait(b);
		super(tink_core_Future.async(function(cb) {
			tink_core_Future.first(n1,n2).handle(function(o) {
				switch(o._hx_index) {
				case 0:
					let item = o.value;
					let rest = o.next;
					cb(tink_streams_Step.Link(item,new tink_streams_BlendStream(rest,first == a ? b : a)));
					break;
				case 1:
					let e = o.e;
					cb(tink_streams_Step.Fail(e));
					break;
				case 2:
					(first == a ? n2 : n1).handle(cb);
					break;
				}
			});
		}));
	}
}
tink_streams_BlendStream.__name__ = "tink.streams.BlendStream";
tink_streams_BlendStream.__super__ = tink_streams_Generator;
Object.assign(tink_streams_BlendStream.prototype, {
	__class__: tink_streams_BlendStream
});
var tink_streams_Step = $hxEnums["tink.streams.Step"] = { __ename__:true,__constructs__:null
	,Link: ($_=function(value,next) { return {_hx_index:0,value:value,next:next,__enum__:"tink.streams.Step",toString:$estr}; },$_._hx_name="Link",$_.__params__ = ["value","next"],$_)
	,Fail: ($_=function(e) { return {_hx_index:1,e:e,__enum__:"tink.streams.Step",toString:$estr}; },$_._hx_name="Fail",$_.__params__ = ["e"],$_)
	,End: {_hx_name:"End",_hx_index:2,__enum__:"tink.streams.Step",toString:$estr}
};
tink_streams_Step.__constructs__ = [tink_streams_Step.Link,tink_streams_Step.Fail,tink_streams_Step.End];
class tink_streams_SignalStream extends tink_streams_Generator {
	constructor(signal) {
		let this1 = tink_core_Future.map(tink_core_Signal.nextTime(signal),function(o) {
			switch(o._hx_index) {
			case 0:
				let data = o.data;
				return tink_streams_Step.Link(data,new tink_streams_SignalStream(signal));
			case 1:
				let e = o.e;
				return tink_streams_Step.Fail(e);
			case 2:
				return tink_streams_Step.End;
			}
		});
		this1.eager();
		super(this1);
	}
}
tink_streams_SignalStream.__name__ = "tink.streams.SignalStream";
tink_streams_SignalStream.__super__ = tink_streams_Generator;
Object.assign(tink_streams_SignalStream.prototype, {
	__class__: tink_streams_SignalStream
});
var tink_streams_Yield = $hxEnums["tink.streams.Yield"] = { __ename__:true,__constructs__:null
	,Data: ($_=function(data) { return {_hx_index:0,data:data,__enum__:"tink.streams.Yield",toString:$estr}; },$_._hx_name="Data",$_.__params__ = ["data"],$_)
	,Fail: ($_=function(e) { return {_hx_index:1,e:e,__enum__:"tink.streams.Yield",toString:$estr}; },$_._hx_name="Fail",$_.__params__ = ["e"],$_)
	,End: {_hx_name:"End",_hx_index:2,__enum__:"tink.streams.Yield",toString:$estr}
};
tink_streams_Yield.__constructs__ = [tink_streams_Yield.Data,tink_streams_Yield.Fail,tink_streams_Yield.End];
class tink_url_Auth {
	static _new(user,password) {
		return "" + user + ":" + password;
	}
	static get_user(this1) {
		if(this1 == null) {
			return null;
		} else {
			return this1.split(":")[0];
		}
	}
	static get_password(this1) {
		if(this1 == null) {
			return null;
		} else {
			return this1.split(":")[1];
		}
	}
	static toString(this1) {
		if(this1 == null) {
			return "";
		} else {
			return "" + this1 + "@";
		}
	}
}
class tink_url_Host {
	static _new(name,port) {
		let this1;
		if(port == null) {
			this1 = name;
		} else if(port > 65535 || port <= 0) {
			throw haxe_Exception.thrown("Invalid port");
		} else {
			this1 = "" + name + ":" + port;
		}
		return this1;
	}
	static get_name(this1) {
		if(this1 == null) {
			return null;
		} else {
			let _g = this1.split("]");
			switch(_g.length) {
			case 1:
				let v = _g[0];
				return v.split(":")[0];
			case 2:
				let _g1 = _g[1];
				let v1 = _g[0];
				return v1 + "]";
			default:
				throw haxe_Exception.thrown("assert");
			}
		}
	}
	static get_port(this1) {
		if(this1 == null) {
			return null;
		} else {
			let _g = this1.split("]");
			switch(_g.length) {
			case 1:
				let v = _g[0];
				let _g1 = v.split(":")[1];
				if(_g1 == null) {
					return null;
				} else {
					let p = _g1;
					return Std.parseInt(p);
				}
				break;
			case 2:
				let _g2 = _g[0];
				let v1 = _g[1];
				let _g3 = v1.split(":")[1];
				if(_g3 == null) {
					return null;
				} else {
					let p = _g3;
					return Std.parseInt(p);
				}
				break;
			default:
				throw haxe_Exception.thrown("assert");
			}
		}
	}
	static toString(this1) {
		return this1;
	}
}
class tink_url_Path {
	static parts(this1) {
		let _g = [];
		let _g1 = 0;
		let _g2 = this1.split("/");
		while(_g1 < _g2.length) {
			let p = _g2[_g1];
			++_g1;
			if(p != "") {
				_g.push(p);
			}
		}
		return _g;
	}
	static get_absolute(this1) {
		return this1.charAt(0) == "/";
	}
	static get_isDir(this1) {
		return this1.charAt(this1.length - 1) == "/";
	}
	static _new(s) {
		return s;
	}
	static join(this1,that) {
		if(that == "") {
			return this1;
		} else if(that.charAt(0) == "/") {
			return that;
		} else if(this1.charAt(this1.length - 1) == "/") {
			return tink_url_Path.ofString(this1 + that);
		} else {
			let _g = this1.lastIndexOf("/");
			if(_g == -1) {
				return that;
			} else {
				let v = _g;
				return tink_url_Path.ofString(HxOverrides.substr(this1,0,v + 1) + (that == null ? "null" : that));
			}
		}
	}
	static ofString(s) {
		return tink_url_Path.normalize(s);
	}
	static normalize(s) {
		s = StringTools.trim(StringTools.replace(s,"\\","/"));
		if(s == ".") {
			return "./";
		}
		let isDir = s.endsWith("/..") || s.endsWith("/") || s.endsWith("/.");
		let parts = [];
		let isAbsolute = s.startsWith("/");
		let up = 0;
		let _g = 0;
		let _g1 = s.split("/");
		while(_g < _g1.length) {
			let part = _g1[_g];
			++_g;
			let _g2 = StringTools.trim(part);
			switch(_g2) {
			case "":
				break;
			case ".":
				break;
			case "..":
				if(parts.pop() == null) {
					++up;
				}
				break;
			default:
				let v = _g2;
				parts.push(v);
			}
		}
		if(isAbsolute) {
			parts.unshift("");
		} else {
			let _g = 0;
			let _g1 = up;
			while(_g < _g1) {
				let i = _g++;
				parts.unshift("..");
			}
		}
		if(isDir) {
			parts.push("");
		}
		return parts.join("/");
	}
	static toString(this1) {
		return this1;
	}
}
class tink_url_Portion {
	static get_raw(this1) {
		return this1;
	}
	static isValid(this1) {
		if(this1 != null) {
			try {
				decodeURIComponent(this1.split("+").join(" "));
				return true;
			} catch( _g ) {
				return false;
			}
		} else {
			return true;
		}
	}
	static _new(v) {
		return v;
	}
	static stringly(this1) {
		return tink_url_Portion.toString(this1);
	}
	static toString(this1) {
		if(this1 == null) {
			return null;
		} else {
			try {
				return decodeURIComponent(this1.split("+").join(" "));
			} catch( _g ) {
				return "";
			}
		}
	}
	static ofString(s) {
		return s == null ? "" : encodeURIComponent(s);
	}
}
class tink_url_PortionArray {
	static toStringArray(this1) {
		let _g = [];
		let _g1 = 0;
		while(_g1 < this1.length) {
			let p = this1[_g1];
			++_g1;
			_g.push(tink_url_Portion.toString(p));
		}
		return _g;
	}
}
class tink_url_Query {
	static parse(this1) {
		return new tink_url__$Query_QueryStringParser(this1,"&","=",0);
	}
	static with(this1,values) {
		let ret = [];
		let _g = [];
		let key = new haxe_ds__$StringMap_StringMapKeyIterator(values.h);
		while(key.hasNext()) {
			let key1 = key.next();
			_g.push(key1);
		}
		let insert = _g;
		let p = new tink_url__$Query_QueryStringParser(this1,"&","=",0);
		while(p.hasNext()) {
			let p1 = p.next();
			let key = tink_url_Portion.ofString(p1.name);
			if(Object.prototype.hasOwnProperty.call(values.h,key)) {
				let name = tink_url_Portion.ofString(p1.name);
				let key = tink_url_Portion.ofString(p1.name);
				ret.push(name + "=" + values.h[key]);
				HxOverrides.remove(insert,tink_url_Portion.ofString(p1.name));
			} else {
				ret.push(tink_url_Portion.ofString(p1.name) + "=" + p1.value);
			}
		}
		let _g1 = 0;
		while(_g1 < insert.length) {
			let name = insert[_g1];
			++_g1;
			ret.push(name + "=" + values.h[name]);
		}
		return ret.join("&");
	}
	static iterator(this1) {
		return new tink_url__$Query_QueryStringParser(this1,"&","=",0);
	}
	static toMap(this1) {
		let _g = new haxe_ds_StringMap();
		let p = new tink_url__$Query_QueryStringParser(this1,"&","=",0);
		while(p.hasNext()) {
			let p1 = p.next();
			_g.h[p1.name.toString()] = p1.value;
		}
		return _g;
	}
	static ofObj(v) {
		let ret = [];
		let v1 = v;
		let _g = 0;
		let _g1 = Reflect.fields(v1);
		while(_g < _g1.length) {
			let k = _g1[_g];
			++_g;
			ret.push(tink_url_Portion.ofString(k) + "=" + tink_url_Portion.ofString(v1[k]));
		}
		return ret.join("&");
	}
	static toString(this1) {
		return this1;
	}
	static build() {
		return [];
	}
	static parseString(s,sep,set,pos) {
		if(pos == null) {
			pos = 0;
		}
		if(set == null) {
			set = "=";
		}
		if(sep == null) {
			sep = "&";
		}
		return new tink_url__$Query_QueryStringParser(s,sep,set,pos);
	}
}
class tink_url_QueryStringBuilder {
	static _new() {
		return [];
	}
	static add(this1,name,value) {
		this1.push(name + "=" + value);
		return this1;
	}
	static toString(this1,sep) {
		if(sep == null) {
			sep = "&";
		}
		return this1.join(sep);
	}
	static copy(this1) {
		return this1.slice();
	}
}
class tink_url__$Query_QueryStringParser {
	constructor(s,sep,set,pos) {
		this.s = s == null ? "" : s;
		this.sep = sep;
		this.set = set;
		this.pos = pos;
	}
	hasNext() {
		return this.pos < this.s.length;
	}
	next() {
		let next = this.s.indexOf(this.sep,this.pos);
		if(next == -1) {
			next = this.s.length;
		}
		let split = this.s.indexOf(this.set,this.pos);
		let start = this.pos;
		this.pos = next + this.sep.length;
		if(split == -1 || split > next) {
			return new tink_core_NamedWith(tink_url_Portion.toString(tink_url__$Query_QueryStringParser.trimmedSub(this.s,start,next)),tink_url_Portion.ofString(""));
		} else {
			return new tink_core_NamedWith(tink_url_Portion.toString(tink_url__$Query_QueryStringParser.trimmedSub(this.s,start,split)),tink_url__$Query_QueryStringParser.trimmedSub(this.s,split + this.set.length,next));
		}
	}
	static trimmedSub(s,start,end) {
		if(start >= s.length) {
			return "";
		}
		while(s.charCodeAt(start) < 33) ++start;
		if(end < s.length - 1) {
			while(s.charCodeAt(end - 1) < 33) --end;
		}
		return s.substring(start,end);
	}
}
tink_url__$Query_QueryStringParser.__name__ = "tink.url._Query.QueryStringParser";
Object.assign(tink_url__$Query_QueryStringParser.prototype, {
	__class__: tink_url__$Query_QueryStringParser
});
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__ = "String";
	Array.__name__ = "Array";
	Date.prototype.__class__ = Date;
	Date.__name__ = "Date";
	var Int = { };
	var Dynamic = { };
	var Float = Number;
	var Bool = Boolean;
	var Class = { };
	var Enum = { };
}
js_Boot.__toStr = ({ }).toString;
DateTools.DAY_SHORT_NAMES = ["Sun","Mon","Tue","Wed","Thu","Fri","Sat"];
DateTools.DAY_NAMES = ["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"];
DateTools.MONTH_SHORT_NAMES = ["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"];
DateTools.MONTH_NAMES = ["January","February","March","April","May","June","July","August","September","October","November","December"];
Xml.Element = 0;
Xml.PCData = 1;
Xml.CData = 2;
Xml.Comment = 3;
Xml.DocType = 4;
Xml.ProcessingInstruction = 5;
Xml.Document = 6;
datetime_DateTime.UNIX_EPOCH_DIFF = 62135596800.0;
datetime_DateTime.SECONDS_IN_MINUTE = 60;
datetime_DateTime.SECONDS_IN_HOUR = 3600;
datetime_DateTime.SECONDS_IN_DAY = 86400;
datetime_DateTime.SECONDS_IN_WEEK = 604800;
datetime_DateTime.SECONDS_IN_YEAR = 31536000;
datetime_DateTime.SECONDS_IN_LEAP_YEAR = 31622400;
datetime_DateTime.SECONDS_IN_3_YEARS = 94608000;
datetime_DateTime.SECONDS_IN_QUAD = 126230400.0;
datetime_DateTime.SECONDS_IN_HALF_QUAD = 63072000.0;
datetime_DateTime.SECONDS_IN_HALF_QUAD_LEAP = 63158400.0;
datetime_DateTime.SECONDS_IN_3_PART_QUAD = 94694400.0;
datetime_DateTime.SECONDS_IN_CQUAD = 12622780800.0;
datetime_DateTime.SECONDS_IN_CENTURY = 3155673600.0;
datetime_DateTime.SECONDS_IN_LEAP_CENTURY = 3155760000.0;
haxe_crypto_Base64.CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
haxe_crypto_Base64.BYTES = haxe_io_Bytes.ofString(haxe_crypto_Base64.CHARS);
haxe_crypto_Base64.URL_CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
haxe_crypto_Base64.URL_BYTES = haxe_io_Bytes.ofString(haxe_crypto_Base64.URL_CHARS);
haxe_http_HttpBase._hx_skip_constructor = false;
haxe_io_FPHelper.i64tmp = new haxe__$Int64__$_$_$Int64(0,0);
haxe_io_FPHelper.helper = new DataView(new ArrayBuffer(8));
haxe_xml_Parser.escapes = (function($this) {
	var $r;
	let h = new haxe_ds_StringMap();
	h.h["lt"] = "<";
	h.h["gt"] = ">";
	h.h["amp"] = "&";
	h.h["quot"] = "\"";
	h.h["apos"] = "'";
	$r = h;
	return $r;
}(this));
hsluv_Hsluv.hexChars = "0123456789abcdef";
hsluv_Hsluv.refY = 1.0;
hsluv_Hsluv.refU = 0.19783000664283;
hsluv_Hsluv.refV = 0.46831999493879;
hsluv_Hsluv.kappa = 903.2962962;
hsluv_Hsluv.epsilon = 0.0088564516;
hsluv_Hsluv.m_r0 = 3.240969941904521;
hsluv_Hsluv.m_r1 = -1.537383177570093;
hsluv_Hsluv.m_r2 = -0.498610760293;
hsluv_Hsluv.m_g0 = -0.96924363628087;
hsluv_Hsluv.m_g1 = 1.87596750150772;
hsluv_Hsluv.m_g2 = 0.041555057407175;
hsluv_Hsluv.m_b0 = 0.055630079696993;
hsluv_Hsluv.m_b1 = -0.20397695888897;
hsluv_Hsluv.m_b2 = 1.056971514242878;
htmlparser_CssSelector.reID = "[a-z](?:-?[_a-z0-9])*";
htmlparser_CssSelector.reNamespacedID = htmlparser_CssSelector.reID + "(?::" + htmlparser_CssSelector.reID + ")?";
htmlparser_CssSelector.reSelector = "(\\s*)((?:[>]\\s*)?)([.#]?)(" + htmlparser_CssSelector.reNamespacedID + "|[*])((?:\\[\\d+\\])?)";
htmlparser_HtmlParser.SELF_CLOSING_TAGS_HTML = { img : 1, br : 1, input : 1, meta : 1, link : 1, hr : 1, base : 1, embed : 1, spacer : 1, source : 1, param : 1};
htmlparser_HtmlParser.reID = "[a-z](?:-?[_a-z0-9])*";
htmlparser_HtmlParser.reNamespacedID = htmlparser_HtmlParser.reID + "(?::" + htmlparser_HtmlParser.reID + ")?";
htmlparser_HtmlParser.reCDATA = "[<]!\\[CDATA\\[[\\s\\S]*?\\]\\][>]";
htmlparser_HtmlParser.reScript = "[<]\\s*script\\s*([^>]*)>([\\s\\S]*?)<\\s*/\\s*script\\s*>";
htmlparser_HtmlParser.reStyle = "<\\s*style\\s*([^>]*)>([\\s\\S]*?)<\\s*/\\s*style\\s*>";
htmlparser_HtmlParser.reElementOpen = "<\\s*(" + htmlparser_HtmlParser.reNamespacedID + ")";
htmlparser_HtmlParser.reAttr = htmlparser_HtmlParser.reNamespacedID + "(?:\\s*=\\s*(?:'[^']*?'|\"[^\"]*?\"|[-_a-z0-9]+))?";
htmlparser_HtmlParser.reElementEnd = "(/)?\\s*>";
htmlparser_HtmlParser.reElementClose = "<\\s*/\\s*(" + htmlparser_HtmlParser.reNamespacedID + ")\\s*>";
htmlparser_HtmlParser.reComment = "<!--[\\s\\S]*?-->";
htmlparser_HtmlParser.reMain = new EReg("(" + htmlparser_HtmlParser.reCDATA + ")|(" + htmlparser_HtmlParser.reScript + ")|(" + htmlparser_HtmlParser.reStyle + ")|(" + htmlparser_HtmlParser.reElementOpen + "((?:\\s+" + htmlparser_HtmlParser.reAttr + ")*)\\s*" + htmlparser_HtmlParser.reElementEnd + ")|(" + htmlparser_HtmlParser.reElementClose + ")|(" + htmlparser_HtmlParser.reComment + ")","ig");
htmlparser_HtmlParser.reParseAttrs = new EReg("(" + htmlparser_HtmlParser.reNamespacedID + ")(?:\\s*=\\s*('[^']*'|\"[^\"]*\"|[-_a-z0-9]+))?","ig");
httpstatus_HttpStatusCode.Continue = 100;
httpstatus_HttpStatusCode.SwitchingProtocols = 101;
httpstatus_HttpStatusCode.Processing = 102;
httpstatus_HttpStatusCode.OK = 200;
httpstatus_HttpStatusCode.Created = 201;
httpstatus_HttpStatusCode.Accepted = 202;
httpstatus_HttpStatusCode.NonAuthoritativeInformation = 203;
httpstatus_HttpStatusCode.NoContent = 204;
httpstatus_HttpStatusCode.ResetContent = 205;
httpstatus_HttpStatusCode.PartialContent = 206;
httpstatus_HttpStatusCode.MultiStatus = 207;
httpstatus_HttpStatusCode.AlreadyReported = 208;
httpstatus_HttpStatusCode.IMUsed = 226;
httpstatus_HttpStatusCode.MultipleChoices = 300;
httpstatus_HttpStatusCode.MovedPermanently = 301;
httpstatus_HttpStatusCode.Found = 302;
httpstatus_HttpStatusCode.SeeOther = 303;
httpstatus_HttpStatusCode.NotModified = 304;
httpstatus_HttpStatusCode.UseProxy = 305;
httpstatus_HttpStatusCode.SwitchProxy = 306;
httpstatus_HttpStatusCode.TemporaryRedirect = 307;
httpstatus_HttpStatusCode.PermanentRedirect = 308;
httpstatus_HttpStatusCode.BadRequest = 400;
httpstatus_HttpStatusCode.Unauthorized = 401;
httpstatus_HttpStatusCode.PaymentRequired = 402;
httpstatus_HttpStatusCode.Forbidden = 403;
httpstatus_HttpStatusCode.NotFound = 404;
httpstatus_HttpStatusCode.MethodNotAllowed = 405;
httpstatus_HttpStatusCode.NotAcceptable = 406;
httpstatus_HttpStatusCode.ProxyAuthenticationRequired = 407;
httpstatus_HttpStatusCode.RequestTimeout = 408;
httpstatus_HttpStatusCode.Conflict = 409;
httpstatus_HttpStatusCode.Gone = 410;
httpstatus_HttpStatusCode.LengthRequired = 411;
httpstatus_HttpStatusCode.PreconditionFailed = 412;
httpstatus_HttpStatusCode.PayloadTooLarge = 413;
httpstatus_HttpStatusCode.URITooLong = 414;
httpstatus_HttpStatusCode.UnsupportedMediaType = 415;
httpstatus_HttpStatusCode.RangeNotSatisfiable = 416;
httpstatus_HttpStatusCode.ExpectationFailed = 417;
httpstatus_HttpStatusCode.ImATeapot = 418;
httpstatus_HttpStatusCode.MisdirectedRequest = 421;
httpstatus_HttpStatusCode.UnprocessableEntity = 422;
httpstatus_HttpStatusCode.Locked = 423;
httpstatus_HttpStatusCode.FailedDependency = 424;
httpstatus_HttpStatusCode.UpgradeRequired = 426;
httpstatus_HttpStatusCode.PreconditionRequired = 428;
httpstatus_HttpStatusCode.TooManyRequests = 429;
httpstatus_HttpStatusCode.RequestHeaderFieldsTooLarge = 431;
httpstatus_HttpStatusCode.UnavailableForLegalReasons = 451;
httpstatus_HttpStatusCode.InternalServerError = 500;
httpstatus_HttpStatusCode.NotImplemented = 501;
httpstatus_HttpStatusCode.BadGateway = 502;
httpstatus_HttpStatusCode.ServiceUnavailable = 503;
httpstatus_HttpStatusCode.GatewayTimeout = 504;
httpstatus_HttpStatusCode.HTTPVersionNotSupported = 505;
httpstatus_HttpStatusCode.VariantAlsoNegotiates = 506;
httpstatus_HttpStatusCode.InsufficientStorage = 507;
httpstatus_HttpStatusCode.LoopDetected = 508;
httpstatus_HttpStatusCode.NotExtended = 510;
httpstatus_HttpStatusCode.NetworkAuthenticationRequired = 511;
hx_strings_Char.CHAR_CASE_MAPPER = new hx_strings__$Char_CharCaseMapper();
hx_strings_Char.BACKSPACE = 8;
hx_strings_Char.TAB = 9;
hx_strings_Char.LF = 10;
hx_strings_Char.CR = 13;
hx_strings_Char.ESC = 27;
hx_strings_Char.SPACE = 32;
hx_strings_Char.EXCLAMATION_MARK = 33;
hx_strings_Char.DOUBLE_QUOTE = 34;
hx_strings_Char.HASH = 35;
hx_strings_Char.DOLLAR = 36;
hx_strings_Char.AMPERSAND = 38;
hx_strings_Char.SINGLE_QUOTE = 39;
hx_strings_Char.BRACKET_ROUND_LEFT = 40;
hx_strings_Char.BRACKET_ROUND_RIGHT = 41;
hx_strings_Char.ASTERISK = 42;
hx_strings_Char.PLUS = 43;
hx_strings_Char.COMMA = 44;
hx_strings_Char.MINUS = 45;
hx_strings_Char.DOT = 46;
hx_strings_Char.SLASH = 47;
hx_strings_Char.ZERO = 48;
hx_strings_Char.ONE = 49;
hx_strings_Char.TWO = 50;
hx_strings_Char.TRHEE = 51;
hx_strings_Char.FOUR = 52;
hx_strings_Char.FIVE = 53;
hx_strings_Char.SIX = 54;
hx_strings_Char.SEVEN = 55;
hx_strings_Char.EIGHT = 56;
hx_strings_Char.NINE = 57;
hx_strings_Char.COLON = 58;
hx_strings_Char.SEMICOLON = 59;
hx_strings_Char.LOWER_THAN = 60;
hx_strings_Char.EQUALS = 61;
hx_strings_Char.GREATER_THAN = 62;
hx_strings_Char.QUESTION_MARK = 63;
hx_strings_Char.BRACKET_SQUARE_LEFT = 91;
hx_strings_Char.BACKSLASH = 92;
hx_strings_Char.BRACKET_SQUARE_RIGHT = 93;
hx_strings_Char.CARET = 94;
hx_strings_Char.UNDERSCORE = 95;
hx_strings_Char.BRACKET_CURLY_LEFT = 123;
hx_strings_Char.PIPE = 124;
hx_strings_Char.BRACKET_CURLY_RIGHT = 125;
hx_strings_CharIterator._hx_skip_constructor = false;
hx_strings__$CharIterator_NullCharIterator.INSTANCE = new hx_strings__$CharIterator_NullCharIterator();
hx_strings_Pattern.__meta__ = { obj : { immutable : null, threadSafe : null}};
hx_strings_Matcher.__meta__ = { obj : { notThreadSafe : null}};
hx_strings_internal_OS.isNodeJS = (typeof process !== 'undefined') && (typeof process.release !== 'undefined') && (process.release.name === 'node');
hx_strings_internal_OS.isWindows = (function($this) {
	var $r;
	let os = hx_strings_internal_OS.isNodeJS ? process.platform : $global.navigator.platform;
	$r = new EReg("win","i").match(os);
	return $r;
}(this));
hx_strings_Strings.REGEX_ANSI_ESC = hx_strings_Pattern.compile(String.fromCodePoint(27) + "\\[[;\\d]*m",hx_strings_internal__$Either3__$Either3.b("g"));
hx_strings_Strings.REGEX_HTML_UNESCAPE = hx_strings_Pattern.compile("&(#\\d+|amp|nbsp|apos|lt|gt|quot);",hx_strings_internal__$Either3__$Either3.b("g"));
hx_strings_Strings.REGEX_SPLIT_LINES = hx_strings_Pattern.compile("\\r?\\n",hx_strings_internal__$Either3__$Either3.b("g"));
hx_strings_Strings.REGEX_REMOVE_XML_TAGS = hx_strings_Pattern.compile("<[!a-zA-Z\\/][^>]*>",hx_strings_internal__$Either3__$Either3.b("g"));
hx_strings_Strings.POS_NOT_FOUND = -1;
hx_strings_Strings.NEW_LINE_NIX = "\n";
hx_strings_Strings.NEW_LINE_WIN = "\r\n";
hx_strings_Strings.NEW_LINE = hx_strings_internal_OS.isWindows ? "\r\n" : "\n";
hx_strings_RandomStrings.DIGITS = hx_strings_Strings.toChars("0123456789");
hx_strings_RandomStrings.ASCII_ALPHA = hx_strings_RandomStrings._genAsciiAlpha();
hx_strings_RandomStrings.ASCII_ALPHA_NUMERIC = hx_strings_RandomStrings.DIGITS.concat(hx_strings_RandomStrings.ASCII_ALPHA);
hx_strings_RandomStrings.MAX_INT = 2147483647;
hx_strings_StringBuilder.__meta__ = { obj : { notThreadSafe : null}};
sha_Hash._hx_skip_constructor = false;
var sha_SHA256_K = [1116352408,1899447441,-1245643825,-373957723,961987163,1508970993,-1841331548,-1424204075,-670586216,310598401,607225278,1426881987,1925078388,-2132889090,-1680079193,-1046744716,-459576895,-272742522,264347078,604807628,770255983,1249150122,1555081692,1996064986,-1740746414,-1473132947,-1341970488,-1084653625,-958395405,-710438585,113926993,338241895,666307205,773529912,1294757372,1396182291,1695183700,1986661051,-2117940946,-1838011259,-1564481375,-1474664885,-1035236496,-949202525,-778901479,-694614492,-200395387,275423344,430227734,506948616,659060556,883997877,958139571,1322822218,1537002063,1747873779,1955562222,2024104815,-2067236844,-1933114872,-1866530822,-1538233109,-1090935817,-965641998];
snikket_Autolink.__meta__ = { statics : { GOOD_IRI_CHAR : { Deprecated : null}}};
snikket_Autolink.IANA_TOP_LEVEL_DOMAINS = "(?:" + "(?:aaa|aarp|abb|abbott|abogado|academy|accenture|accountant|accountants|aco|active" + "|actor|ads|adult|aeg|aero|afl|agency|aig|airforce|airtel|allfinanz|alsace|amica|amsterdam" + "|android|apartments|app|apple|aquarelle|aramco|archi|army|arpa|arte|asia|associates" + "|attorney|auction|audio|auto|autos|axa|azure|a[cdefgilmoqrstuwxz])" + "|(?:band|bank|bar|barcelona|barclaycard|barclays|bargains|bauhaus|bayern|bbc|bbva" + "|bcn|beats|beer|bentley|berlin|best|bet|bharti|bible|bid|bike|bing|bingo|bio|biz|black" + "|blackfriday|bloomberg|blue|bms|bmw|bnl|bnpparibas|boats|bom|bond|boo|boots|boutique" + "|bradesco|bridgestone|broadway|broker|brother|brussels|budapest|build|builders|business" + "|buzz|bzh|b[abdefghijmnorstvwyz])" + "|(?:cab|cafe|cal|camera|camp|cancerresearch|canon|capetown|capital|car|caravan|cards" + "|care|career|careers|cars|cartier|casa|cash|casino|cat|catering|cba|cbn|ceb|center|ceo" + "|cern|cfa|cfd|chanel|channel|chat|cheap|chloe|christmas|chrome|church|cipriani|cisco" + "|citic|city|cityeats|claims|cleaning|click|clinic|clothing|cloud|club|clubmed|coach" + "|codes|coffee|college|cologne|com|commbank|community|company|computer|comsec|condos" + "|construction|consulting|contractors|cooking|cool|coop|corsica|country|coupons|courses" + "|credit|creditcard|creditunion|cricket|crown|crs|cruises|csc|cuisinella|cymru|cyou|c[acdfghiklmnoruvwxyz])" + "|(?:dabur|dad|dance|date|dating|datsun|day|dclk|deals|degree|delivery|dell|delta" + "|democrat|dental|dentist|desi|design|dev|diamonds|diet|digital|direct|directory|discount" + "|dnp|docs|dog|doha|domains|doosan|download|drive|durban|dvag|d[ejkmoz])" + "|(?:earth|eat|edu|education|email|emerck|energy|engineer|engineering|enterprises" + "|epson|equipment|erni|esq|estate|eurovision|eus|events|everbank|exchange|expert|exposed" + "|express|e[cegrstu])" + "|(?:fage|fail|fairwinds|faith|family|fan|fans|farm|fashion|feedback|ferrero|film" + "|final|finance|financial|firmdale|fish|fishing|fit|fitness|flights|florist|flowers|flsmidth" + "|fly|foo|football|forex|forsale|forum|foundation|frl|frogans|fund|furniture|futbol|fyi" + "|f[ijkmor])" + "|(?:gal|gallery|game|garden|gbiz|gdn|gea|gent|genting|ggee|gift|gifts|gives|giving" + "|glass|gle|global|globo|gmail|gmo|gmx|gold|goldpoint|golf|goo|goog|google|gop|gov|grainger" + "|graphics|gratis|green|gripe|group|gucci|guge|guide|guitars|guru|g[abdefghilmnpqrstuwy])" + "|(?:hamburg|hangout|haus|healthcare|help|here|hermes|hiphop|hitachi|hiv|hockey|holdings" + "|holiday|homedepot|homes|honda|horse|host|hosting|hoteles|hotmail|house|how|hsbc|hyundai" + "|h[kmnrtu])" + "|(?:ibm|icbc|ice|icu|ifm|iinet|immo|immobilien|industries|infiniti|info|ing|ink|institute" + "|insure|int|international|investments|ipiranga|irish|ist|istanbul|itau|iwc|i[delmnoqrst])" + "|(?:jaguar|java|jcb|jetzt|jewelry|jlc|jll|jobs|joburg|jprs|juegos|j[emop])" + "|(?:kaufen|kddi|kia|kim|kinder|kitchen|kiwi|koeln|komatsu|krd|kred|kyoto|k[eghimnprwyz])" + "|(?:lacaixa|lancaster|land|landrover|lasalle|lat|latrobe|law|lawyer|lds|lease|leclerc" + "|legal|lexus|lgbt|liaison|lidl|life|lifestyle|lighting|limited|limo|linde|link|live" + "|lixil|loan|loans|lol|london|lotte|lotto|love|ltd|ltda|lupin|luxe|luxury|l[abcikrstuvy])" + "|(?:madrid|maif|maison|man|management|mango|market|marketing|markets|marriott|mba" + "|media|meet|melbourne|meme|memorial|men|menu|meo|miami|microsoft|mil|mini|mma|mobi|moda" + "|moe|moi|mom|monash|money|montblanc|mormon|mortgage|moscow|motorcycles|mov|movie|movistar" + "|mtn|mtpc|mtr|museum|mutuelle|m[acdeghklmnopqrstuvwxyz])" + "|(?:nadex|nagoya|name|navy|nec|net|netbank|network|neustar|new|news|nexus|ngo|nhk" + "|nico|ninja|nissan|nokia|nra|nrw|ntt|nyc|n[acefgilopruz])" + "|(?:obi|office|okinawa|omega|one|ong|onl|online|ooo|oracle|orange|org|organic|osaka" + "|otsuka|ovh|om)" + "|(?:page|panerai|paris|partners|parts|party|pet|pharmacy|philips|photo|photography" + "|photos|physio|piaget|pics|pictet|pictures|ping|pink|pizza|place|play|playstation|plumbing" + "|plus|pohl|poker|porn|post|praxi|press|pro|prod|productions|prof|properties|property" + "|protection|pub|p[aefghklmnrstwy])" + "|(?:qpon|quebec|qa)" + "|(?:racing|realtor|realty|recipes|red|redstone|rehab|reise|reisen|reit|ren|rent|rentals" + "|repair|report|republican|rest|restaurant|review|reviews|rich|ricoh|rio|rip|rocher|rocks" + "|rodeo|rsvp|ruhr|run|rwe|ryukyu|r[eosuw])" + "|(?:saarland|sakura|sale|samsung|sandvik|sandvikcoromant|sanofi|sap|sapo|sarl|saxo" + "|sbs|sca|scb|schmidt|scholarships|school|schule|schwarz|science|scor|scot|seat|security" + "|seek|sener|services|seven|sew|sex|sexy|shiksha|shoes|show|shriram|singles|site|ski" + "|sky|skype|sncf|soccer|social|software|sohu|solar|solutions|sony|soy|space|spiegel|spreadbetting" + "|srl|stada|starhub|statoil|stc|stcgroup|stockholm|studio|study|style|sucks|supplies" + "|supply|support|surf|surgery|suzuki|swatch|swiss|sydney|systems|s[abcdeghijklmnortuvxyz])" + "|(?:tab|taipei|tatamotors|tatar|tattoo|tax|taxi|team|tech|technology|tel|telefonica" + "|temasek|tennis|thd|theater|theatre|tickets|tienda|tips|tires|tirol|today|tokyo|tools" + "|top|toray|toshiba|tours|town|toyota|toys|trade|trading|training|travel|trust|tui|t[cdfghjklmnortvwz])" + "|(?:ubs|university|uno|uol|u[agksyz])" + "|(?:vacations|vana|vegas|ventures|versicherung|vet|viajes|video|villas|vin|virgin" + "|vision|vista|vistaprint|viva|vlaanderen|vodka|vote|voting|voto|voyage|v[aceginu])" + "|(?:wales|walter|wang|watch|webcam|website|wed|wedding|weir|whoswho|wien|wiki|williamhill" + "|win|windows|wine|wme|work|works|world|wtc|wtf|w[fs])" + "|(?:ελ|бел|дети|ком|мкд" + "|мон|москва|онлайн" + "|орг|рус|рф|сайт|срб" + "|укр|қаз|հայ|קום|ارامكو" + "|الاردن|الجزائر|السعودية" + "|المغرب|امارات|ایران" + "|بازار|بھارت|تونس" + "|سودان|سورية|شبكة" + "|عراق|عمان|فلسطين" + "|قطر|كوم|مصر|مليسيا" + "|موقع|कॉम|नेट|भारत" + "|संगठन|ভারত|ਭਾਰਤ|ભારત" + "|இந்தியா|இலங்கை|சிங்கப்பூர்" + "|భారత్|ලංකා|คอม|ไทย" + "|გე|みんな|グーグル|コム|世界" + "|中信|中国|中國|中文网|企业|佛山" + "|信息|健康|八卦|公司|公益|台湾|台灣" + "|商城|商店|商标|在线|大拿|娱乐|工行" + "|广东|慈善|我爱你|手机|政务|政府" + "|新加坡|新闻|时尚|机构|淡马锡|游戏" + "|点看|移动|组织机构|网址|网店|网络" + "|谷歌|集团|飞利浦|餐厅|香港|닷넷" + "|닷컴|삼성|한국|xbox" + "|xerox|xin|xn\\-\\-11b4c3d|xn\\-\\-1qqw23a|xn\\-\\-30rr7y|xn\\-\\-3bst00m|xn\\-\\-3ds443g" + "|xn\\-\\-3e0b707e|xn\\-\\-3pxu8k|xn\\-\\-42c2d9a|xn\\-\\-45brj9c|xn\\-\\-45q11c|xn\\-\\-4gbrim" + "|xn\\-\\-55qw42g|xn\\-\\-55qx5d|xn\\-\\-6frz82g|xn\\-\\-6qq986b3xl|xn\\-\\-80adxhks" + "|xn\\-\\-80ao21a|xn\\-\\-80asehdb|xn\\-\\-80aswg|xn\\-\\-90a3ac|xn\\-\\-90ais|xn\\-\\-9dbq2a" + "|xn\\-\\-9et52u|xn\\-\\-b4w605ferd|xn\\-\\-c1avg|xn\\-\\-c2br7g|xn\\-\\-cg4bki|xn\\-\\-clchc0ea0b2g2a9gcd" + "|xn\\-\\-czr694b|xn\\-\\-czrs0t|xn\\-\\-czru2d|xn\\-\\-d1acj3b|xn\\-\\-d1alf|xn\\-\\-efvy88h" + "|xn\\-\\-estv75g|xn\\-\\-fhbei|xn\\-\\-fiq228c5hs|xn\\-\\-fiq64b|xn\\-\\-fiqs8s|xn\\-\\-fiqz9s" + "|xn\\-\\-fjq720a|xn\\-\\-flw351e|xn\\-\\-fpcrj9c3d|xn\\-\\-fzc2c9e2c|xn\\-\\-gecrj9c" + "|xn\\-\\-h2brj9c|xn\\-\\-hxt814e|xn\\-\\-i1b6b1a6a2e|xn\\-\\-imr513n|xn\\-\\-io0a7i" + "|xn\\-\\-j1aef|xn\\-\\-j1amh|xn\\-\\-j6w193g|xn\\-\\-kcrx77d1x4a|xn\\-\\-kprw13d|xn\\-\\-kpry57d" + "|xn\\-\\-kput3i|xn\\-\\-l1acc|xn\\-\\-lgbbat1ad8j|xn\\-\\-mgb9awbf|xn\\-\\-mgba3a3ejt" + "|xn\\-\\-mgba3a4f16a|xn\\-\\-mgbaam7a8h|xn\\-\\-mgbab2bd|xn\\-\\-mgbayh7gpa|xn\\-\\-mgbbh1a71e" + "|xn\\-\\-mgbc0a9azcg|xn\\-\\-mgberp4a5d4ar|xn\\-\\-mgbpl2fh|xn\\-\\-mgbtx2b|xn\\-\\-mgbx4cd0ab" + "|xn\\-\\-mk1bu44c|xn\\-\\-mxtq1m|xn\\-\\-ngbc5azd|xn\\-\\-node|xn\\-\\-nqv7f|xn\\-\\-nqv7fs00ema" + "|xn\\-\\-nyqy26a|xn\\-\\-o3cw4h|xn\\-\\-ogbpf8fl|xn\\-\\-p1acf|xn\\-\\-p1ai|xn\\-\\-pgbs0dh" + "|xn\\-\\-pssy2u|xn\\-\\-q9jyb4c|xn\\-\\-qcka1pmc|xn\\-\\-qxam|xn\\-\\-rhqv96g|xn\\-\\-s9brj9c" + "|xn\\-\\-ses554g|xn\\-\\-t60b56a|xn\\-\\-tckwe|xn\\-\\-unup4y|xn\\-\\-vermgensberater\\-ctb" + "|xn\\-\\-vermgensberatung\\-pwb|xn\\-\\-vhquv|xn\\-\\-vuq861b|xn\\-\\-wgbh1c|xn\\-\\-wgbl6a" + "|xn\\-\\-xhq521b|xn\\-\\-xkc2al3hye2a|xn\\-\\-xkc2dl3a5ee0h|xn\\-\\-y9a3aq|xn\\-\\-yfro4i67o" + "|xn\\-\\-ygbi2ammx|xn\\-\\-zfr164b|xperia|xxx|xyz)" + "|(?:yachts|yamaxun|yandex|yodobashi|yoga|yokohama|youtube|y[et])" + "|(?:zara|zip|zone|zuerich|z[amw]))";
snikket_Autolink.GOOD_IRI_CHAR = "a-zA-Z0-9 -퟿豈-﷏ﷰ-￯";
snikket_Autolink.IP_ADDRESS = "((25[0-5]|2[0-4][0-9]|[0-1][0-9]{2}|[1-9][0-9]|[1-9])\\.(25[0-5]|2[0-4]" + "[0-9]|[0-1][0-9]{2}|[1-9][0-9]|[1-9]|0)\\.(25[0-5]|2[0-4][0-9]|[0-1]" + "[0-9]{2}|[1-9][0-9]|[1-9]|0)\\.(25[0-5]|2[0-4][0-9]|[0-1][0-9]{2}" + "|[1-9][0-9]|[0-9]))";
snikket_Autolink.IP6_ADDRESS = "\\[" + "(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|" + "([0-9a-fA-F]{1,4}:){1,7}:|" + "([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|" + "([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|" + "([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|" + "([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|" + "([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|" + "[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|" + ":((:[0-9a-fA-F]{1,4}){1,7}|:)|" + "fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|" + "::(ffff(:0{1,4}){0,1}:){0,1}" + "((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\.){3,3}" + "(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|" + "([0-9a-fA-F]{1,4}:){1,4}:" + "((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\.){3,3}" + "(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))" + "\\]";
snikket_Autolink.UCS_CHAR = "[" + "\\u00A0-\\uD7FF" + "\\uF900-\\uFDCF" + "\\uFDF0-\\uFFEF";
snikket_Autolink.LABEL_CHAR = "a-zA-Z0-9" + snikket_Autolink.UCS_CHAR;
snikket_Autolink.TLD_CHAR = "a-zA-Z" + snikket_Autolink.UCS_CHAR;
snikket_Autolink.IRI_LABEL = "[" + snikket_Autolink.LABEL_CHAR + "](?:[" + snikket_Autolink.LABEL_CHAR + "\\-]{0,61}[" + snikket_Autolink.LABEL_CHAR + "]){0,1}";
snikket_Autolink.PUNYCODE_TLD = "xn\\-\\-[\\w\\-]{0,58}\\w";
snikket_Autolink.TLD = "(" + snikket_Autolink.PUNYCODE_TLD + "|" + "[" + snikket_Autolink.TLD_CHAR + "]{2,63}" + ")";
snikket_Autolink.HOST_NAME = "(" + snikket_Autolink.IRI_LABEL + "\\.)+" + snikket_Autolink.TLD;
snikket_Autolink.PROTOCOL = "(?:http|https|rtsp):\\/\\/";
snikket_Autolink.WORD_BOUNDARY = "(?:\\b|$|^)";
snikket_Autolink.USER_INFO = "(?:[a-zA-Z0-9\\$\\-\\_\\.\\+\\!\\*\\'\\(\\)" + "\\,\\;\\?\\&\\=]|(?:\\%[a-fA-F0-9]{2})){1,64}(?:\\:(?:[a-zA-Z0-9\\$\\-\\_" + "\\.\\+\\!\\*\\'\\(\\)\\,\\;\\?\\&\\=]|(?:\\%[a-fA-F0-9]{2})){1,25})?\\@";
snikket_Autolink.PORT_NUMBER = "\\:\\d{1,5}";
snikket_Autolink.PATH_CHAR = "(?:(?:[" + snikket_Autolink.LABEL_CHAR + "\\;\\/\\?\\:\\@\\&\\=\\#\\~" + "\\-\\.\\+\\!\\*\\'\\(\\)\\,\\_\\$])|(?:\\%[a-fA-F0-9]{2}))";
snikket_Autolink.PATH_AND_QUERY = "\\/" + snikket_Autolink.PATH_CHAR + "*";
snikket_Autolink.STRICT_TLD = "(?:" + snikket_Autolink.IANA_TOP_LEVEL_DOMAINS + "|" + snikket_Autolink.PUNYCODE_TLD + ")";
snikket_Autolink.STRICT_HOST_NAME = "(?:(?:" + snikket_Autolink.IRI_LABEL + "\\.)+" + snikket_Autolink.STRICT_TLD + ")";
snikket_Autolink.STRICT_DOMAIN_NAME = "(?:" + snikket_Autolink.STRICT_HOST_NAME + "|" + snikket_Autolink.IP_ADDRESS + "|" + snikket_Autolink.IP6_ADDRESS + ")";
snikket_Autolink.RELAXED_DOMAIN_NAME = "(?:" + "(?:" + snikket_Autolink.IRI_LABEL + "(?:\\.(?=\\S))" + "?)+" + "|" + snikket_Autolink.IP_ADDRESS + "|" + snikket_Autolink.IP6_ADDRESS + ")";
snikket_Autolink.WEB_URL_WITHOUT_PROTOCOL = "(" + snikket_Autolink.WORD_BOUNDARY + "(?<!:\\/\\/)" + "(" + "(?:" + snikket_Autolink.STRICT_DOMAIN_NAME + ")" + "(?:" + snikket_Autolink.PORT_NUMBER + ")?" + ")" + "(?:" + snikket_Autolink.PATH_AND_QUERY + ")?" + ")";
snikket_Autolink.WEB_URL_WITH_PROTOCOL = "(" + snikket_Autolink.WORD_BOUNDARY + "(?:" + "(?:" + snikket_Autolink.PROTOCOL + "(?:" + snikket_Autolink.USER_INFO + ")?" + ")" + "(?:" + snikket_Autolink.RELAXED_DOMAIN_NAME + ")?" + "(?:" + snikket_Autolink.PORT_NUMBER + ")?" + ")" + "(?:" + snikket_Autolink.PATH_AND_QUERY + ")?" + ")";
snikket_Autolink.AUTOLINK_WEB_URL = "(" + snikket_Autolink.WEB_URL_WITH_PROTOCOL + "|" + snikket_Autolink.WEB_URL_WITHOUT_PROTOCOL + ")" + snikket_Autolink.WORD_BOUNDARY;
snikket_Autolink.TEL_URI = "tel:(?:(?:\\+\\d+)|(?:\\d+;phone-context=" + snikket_Autolink.PATH_CHAR + "+))";
snikket_Autolink.SMS_URI = "sms:(?:(?:\\+\\d+)|(?:\\d+;phone-context=" + snikket_Autolink.PATH_CHAR + "+))";
snikket_Autolink.XMPP_URI = "xmpp\\:(?:(?:[" + snikket_Autolink.GOOD_IRI_CHAR + "\\;\\/\\?\\@\\&\\=\\#\\~\\-\\.\\+\\!\\*\\'\\(\\)\\,\\_])" + "|(?:\\%[a-fA-F0-9]{2}))+";
snikket_Chat._hx_skip_constructor = false;
snikket_Chat.__meta__ = { fields : { addMedia : { 'HaxeCBridge.noemit' : null}}};
snikket_DirectChat.__meta__ = { fields : { getParticipants : { 'HaxeCBridge.noemit' : null}, getParticipantDetails : { 'HaxeCBridge.noemit' : null}, getMessagesBefore : { 'HaxeCBridge.noemit' : null}, getMessagesAfter : { 'HaxeCBridge.noemit' : null}, getMessagesAround : { 'HaxeCBridge.noemit' : null}, correctMessage : { 'HaxeCBridge.noemit' : null}, sendMessage : { 'HaxeCBridge.noemit' : null}, removeReaction : { 'HaxeCBridge.noemit' : null}, lastMessageId : { 'HaxeCBridge.noemit' : null}, markReadUpTo : { 'HaxeCBridge.noemit' : null}, bookmark : { 'HaxeCBridge.noemit' : null}, close : { 'HaxeCBridge.noemit' : null}}};
snikket_Channel.__meta__ = { fields : { getParticipants : { 'HaxeCBridge.noemit' : null}, getParticipantDetails : { 'HaxeCBridge.noemit' : null}, getMessagesBefore : { 'HaxeCBridge.noemit' : null}, getMessagesAfter : { 'HaxeCBridge.noemit' : null}, getMessagesAround : { 'HaxeCBridge.noemit' : null}, correctMessage : { 'HaxeCBridge.noemit' : null}, sendMessage : { 'HaxeCBridge.noemit' : null}, removeReaction : { 'HaxeCBridge.noemit' : null}, lastMessageId : { 'HaxeCBridge.noemit' : null}, markReadUpTo : { 'HaxeCBridge.noemit' : null}, bookmark : { 'HaxeCBridge.noemit' : null}, close : { 'HaxeCBridge.noemit' : null}}};
snikket_ChatMessage.__meta__ = { fields : { reactions : { 'HaxeCBridge.noemit' : null}}};
snikket_ChatMessageBuilder.__meta__ = { fields : { reactions : { 'HaxeCBridge.noemit' : null}}};
snikket_EventEmitter._hx_skip_constructor = false;
snikket_Config.relativeHashUri = false;
snikket_EmojiUtil.MISC_SYMBOLS_AND_PICTOGRAPHS = new snikket_UnicodeRange(127744,128511);
snikket_EmojiUtil.SUPPLEMENTAL_SYMBOLS = new snikket_UnicodeRange(129280,129535);
snikket_EmojiUtil.EMOTICONS = new snikket_UnicodeRange(128512,129782);
snikket_EmojiUtil.MISC_SYMBOLS = new snikket_UnicodeRange(9728,9983);
snikket_EmojiUtil.DINGBATS = new snikket_UnicodeRange(9984,10175);
snikket_EmojiUtil.ENCLOSED_ALPHANUMERIC_SUPPLEMENT = new snikket_UnicodeRange(127232,127487);
snikket_EmojiUtil.ENCLOSED_IDEOGRAPHIC_SUPPLEMENT = new snikket_UnicodeRange(127488,127743);
snikket_EmojiUtil.REGIONAL_INDICATORS = new snikket_UnicodeRange(127462,127487);
snikket_EmojiUtil.GEOMETRIC_SHAPES = new snikket_UnicodeRange(9632,9727);
snikket_EmojiUtil.LATIN_SUPPLEMENT = new snikket_UnicodeRange(128,255);
snikket_EmojiUtil.MISC_TECHNICAL = new snikket_UnicodeRange(8960,9215);
snikket_EmojiUtil.TAGS = new snikket_UnicodeRange(917536,917631);
snikket_EmojiUtil.CYK_SYMBOLS_AND_PUNCTUATION = new snikket_UnicodeList(12336,12349);
snikket_EmojiUtil.LETTERLIKE_SYMBOLS = new snikket_UnicodeList(8482,8505);
snikket_EmojiUtil.KEYCAP_COMBINEABLE = new snikket_UnicodeBlocks(new snikket_UnicodeList(35),new snikket_UnicodeList(42),new snikket_UnicodeRange(48,57));
snikket_EmojiUtil.SYMBOLIZE = new snikket_UnicodeBlocks(snikket_EmojiUtil.GEOMETRIC_SHAPES,snikket_EmojiUtil.LATIN_SUPPLEMENT,snikket_EmojiUtil.CYK_SYMBOLS_AND_PUNCTUATION,snikket_EmojiUtil.LETTERLIKE_SYMBOLS,snikket_EmojiUtil.KEYCAP_COMBINEABLE);
snikket_EmojiUtil.EMOJIS = new snikket_UnicodeBlocks(snikket_EmojiUtil.MISC_SYMBOLS_AND_PICTOGRAPHS,snikket_EmojiUtil.SUPPLEMENTAL_SYMBOLS,snikket_EmojiUtil.EMOTICONS,snikket_EmojiUtil.MISC_SYMBOLS,snikket_EmojiUtil.DINGBATS,snikket_EmojiUtil.ENCLOSED_ALPHANUMERIC_SUPPLEMENT,snikket_EmojiUtil.ENCLOSED_IDEOGRAPHIC_SUPPLEMENT,snikket_EmojiUtil.MISC_TECHNICAL);
snikket_EmojiUtil.MAX_EMOIJS = 42;
snikket_EmojiUtil.ZWJ = 8205;
snikket_EmojiUtil.VARIATION_16 = 65039;
snikket_EmojiUtil.COMBINING_ENCLOSING_KEYCAP = 8419;
snikket_EmojiUtil.BLACK_FLAG = 127988;
snikket_EmojiUtil.FITZPATRICK = new snikket_UnicodeRange(127995,127999);
snikket_Persistence.__meta__ = { fields : { getChatsUnreadDetails : { 'HaxeCBridge.noemit' : null}, findServicesWithFeature : { 'HaxeCBridge.noemit' : null}}};
snikket_Version.HUMAN = "cf378ac";
snikket_persistence_Dummy.__meta__ = { fields : { lastId : { 'HaxeCBridge.noemit' : null}, storeChats : { 'HaxeCBridge.noemit' : null}, getChats : { 'HaxeCBridge.noemit' : null}, storeMessages : { 'HaxeCBridge.noemit' : null}, updateMessage : { 'HaxeCBridge.noemit' : null}, getMessage : { 'HaxeCBridge.noemit' : null}, getMessagesBefore : { 'HaxeCBridge.noemit' : null}, getMessagesAfter : { 'HaxeCBridge.noemit' : null}, getMessagesAround : { 'HaxeCBridge.noemit' : null}, getChatsUnreadDetails : { 'HaxeCBridge.noemit' : null}, storeReaction : { 'HaxeCBridge.noemit' : null}, updateMessageStatus : { 'HaxeCBridge.noemit' : null}, getMediaUri : { 'HaxeCBridge.noemit' : null}, hasMedia : { 'HaxeCBridge.noemit' : null}, storeMedia : { 'HaxeCBridge.noemit' : null}, removeMedia : { 'HaxeCBridge.noemit' : null}, storeCaps : { 'HaxeCBridge.noemit' : null}, getCaps : { 'HaxeCBridge.noemit' : null}, storeLogin : { 'HaxeCBridge.noemit' : null}, getLogin : { 'HaxeCBridge.noemit' : null}, removeAccount : { 'HaxeCBridge.noemit' : null}, storeStreamManagement : { 'HaxeCBridge.noemit' : null}, getStreamManagement : { 'HaxeCBridge.noemit' : null}, storeService : { 'HaxeCBridge.noemit' : null}, findServicesWithFeature : { 'HaxeCBridge.noemit' : null}}};
snikket_persistence_Sqlite.__meta__ = { fields : { get : { 'HaxeCBridge.noemit' : null}, set : { 'HaxeCBridge.noemit' : null}, lastId : { 'HaxeCBridge.noemit' : null}, storeChats : { 'HaxeCBridge.noemit' : null}, getChats : { 'HaxeCBridge.noemit' : null}, storeMessages : { 'HaxeCBridge.noemit' : null}, updateMessage : { 'HaxeCBridge.noemit' : null}, getMessagesBefore : { 'HaxeCBridge.noemit' : null}, getMessagesAfter : { 'HaxeCBridge.noemit' : null}, getMessagesAround : { 'HaxeCBridge.noemit' : null}, getChatsUnreadDetails : { 'HaxeCBridge.noemit' : null}, storeReaction : { 'HaxeCBridge.noemit' : null}, updateMessageStatus : { 'HaxeCBridge.noemit' : null}, hasMedia : { 'HaxeCBridge.noemit' : null}, removeMedia : { 'HaxeCBridge.noemit' : null}, storeMedia : { 'HaxeCBridge.noemit' : null}, storeCaps : { 'HaxeCBridge.noemit' : null}, getCaps : { 'HaxeCBridge.noemit' : null}, storeLogin : { 'HaxeCBridge.noemit' : null}, getLogin : { 'HaxeCBridge.noemit' : null}, removeAccount : { 'HaxeCBridge.noemit' : null}, storeStreamManagement : { 'HaxeCBridge.noemit' : null}, getStreamManagement : { 'HaxeCBridge.noemit' : null}, storeService : { 'HaxeCBridge.noemit' : null}, findServicesWithFeature : { 'HaxeCBridge.noemit' : null}}};
snikket_queries_GenericQuery._hx_skip_constructor = false;
thenshim_Promise.factory = new thenshim_js_JSPromiseFactory();
tink__$Chunk_EmptyChunk.EMPTY = new haxe_io_Bytes(new ArrayBuffer(0));
tink_Chunk.EMPTY = new tink__$Chunk_EmptyChunk();
tink_Stringly.SUPPORTED_DATE_REGEX = new EReg("^(\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2})(\\.\\d{3})?(Z|[\\+-]\\d{2}:\\d{2})$","");
tink_Url.SCHEME = 2;
tink_Url.PAYLOAD = 3;
tink_Url.AUTH = 6;
tink_Url.HOSTNAMES = 7;
tink_Url.PATH = 8;
tink_Url.QUERY = 10;
tink_Url.HASH = 12;
tink_core_Callback.depth = 0;
tink_core_Callback.MAX_DEPTH = 500;
tink_core_SimpleDisposable._hx_skip_constructor = false;
tink_core_AlreadyDisposed.INST = new tink_core_AlreadyDisposed();
tink_core__$Future_FutureObject._hx_skip_constructor = false;
tink_core_Future.NOISE = new tink_core__$Future_SyncFuture(new tink_core__$Lazy_LazyConst(null));
tink_core_Future.NEVER_INST = new tink_core__$Future_FutureObject();
tink_core_Future.NEVER = tink_core_Future.NEVER_INST;
tink_core_Lazy.NOISE = new tink_core__$Lazy_LazyConst(null);
tink_core_Lazy.NULL = tink_core_Lazy.NOISE;
tink_core_Noise.Noise = null;
tink_core_ProgressValue.ZERO = new tink_core_MPair(0,haxe_ds_Option.None);
tink_core_Progress.INIT = tink_core_ProgressValue.ZERO;
tink_core__$Progress_ProgressObject._hx_skip_constructor = false;
tink_core_Promise.NOISE = new tink_core__$Future_SyncFuture(new tink_core__$Lazy_LazyConst(tink_core_Outcome.Success(null)));
tink_core_Promise.NEVER = tink_core_Promise.never();
tink_core__$Signal_Disposed.INST = new tink_core__$Signal_Disposed();
tink_http_ChunkedParser.LINEBREAK = tink_chunk_Seekable.ofBytes(haxe_io_Bytes.ofString("\r\n"));
tink_http_Fetch.cache = new haxe_ds_EnumValueMap();
tink_http_Header._hx_skip_constructor = false;
tink_http_HeaderValue.DAYS = "Sun,Mon,Tue,Wen,Thu,Fri,Sat".split(",");
tink_http_HeaderValue.MONTHS = "Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec".split(",");
tink_http_HeaderName.REFERER = "referer";
tink_http_HeaderName.HOST = "host";
tink_http_HeaderName.SET_COOKIE = "set-cookie";
tink_http_HeaderName.COOKIE = "cookie";
tink_http_HeaderName.CONTENT_TYPE = "content-type";
tink_http_HeaderName.CONTENT_LENGTH = "content-length";
tink_http_HeaderName.CONTENT_DISPOSITION = "content-disposition";
tink_http_HeaderName.CONTENT_RANGE = "content-range";
tink_http_HeaderName.ACCEPT = "accept";
tink_http_HeaderName.ACCEPT_ENCODING = "accept-encoding";
tink_http_HeaderName.TRANSFER_ENCODING = "transfer-encoding";
tink_http_HeaderName.RANGE = "range";
tink_http_HeaderName.LOCATION = "location";
tink_http_HeaderName.AUTHORIZATION = "authorization";
tink_http_HeaderName.ORIGIN = "origin";
tink_http_HeaderName.VARY = "vary";
tink_http_HeaderName.CACHE_CONTROL = "cache-control";
tink_http_HeaderName.EXPIRES = "expires";
tink_http_HeaderName.ACCESS_CONTROL_REQUEST_METHOD = "access-control-request-method";
tink_http_HeaderName.ACCESS_CONTROL_REQUEST_HEADERS = "access-control-request-headers";
tink_http_HeaderName.ACCESS_CONTROL_ALLOW_ORIGIN = "access-control-allow-origin";
tink_http_HeaderName.ACCESS_CONTROL_ALLOW_CREDENTIALS = "access-control-allow-credentials";
tink_http_HeaderName.ACCESS_CONTROL_EXPOSE_HEADERS = "access-control-expose-headers";
tink_http_HeaderName.ACCESS_CONTROL_MAX_AGE = "access-control-max-age";
tink_http_HeaderName.ACCESS_CONTROL_ALLOW_METHODS = "access-control-allow-methods";
tink_http_HeaderName.ACCESS_CONTROL_ALLOW_HEADERS = "access-control-allow-headers";
tink_http_HeaderParser.INVALID = tink_io_ParseStep.Failed(new tink_core_TypedError(422,"Invalid HTTP header",{ fileName : "tink/http/Header.hx", lineNumber : 310, className : "tink.http.HeaderParser", methodName : "INVALID"}));
tink_http_Message._hx_skip_constructor = false;
tink_http_Method.GET = "GET";
tink_http_Method.HEAD = "HEAD";
tink_http_Method.OPTIONS = "OPTIONS";
tink_http_Method.POST = "POST";
tink_http_Method.PUT = "PUT";
tink_http_Method.PATCH = "PATCH";
tink_http_Method.DELETE = "DELETE";
tink_io__$Sink_Blackhole.inst = new tink_io__$Sink_Blackhole();
tink_io_SinkYielding.BLACKHOLE = tink_io__$Sink_Blackhole.inst;
tink_streams_StreamBase._hx_skip_constructor = false;
tink_streams_Empty.inst = new tink_streams_Empty();
tink_io_Source.EMPTY = tink_streams_Empty.inst;
tink_io_Worker.EAGER = new tink_io__$Worker_EagerWorker();
tink_io_Worker.pool = [tink_io_Worker.EAGER];
tink_url_Path.root = "/";
})(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);
export const snikket = exports.snikket;