1 /**
    2  * Top-level namespace of these objects.
    3  * @namespace
    4  */
    5 namespace ort {
    6 	/**
    7 	 * Labels ("jslabel" in ort(5)) may have multiple languages.
    8 	 * This maps a language name to a translated string.
    9 	 * @private
   10 	 * @interface ort.langmap
   11 	 */
   12 	interface langmap { [lang: string]: string };
   13 
   14 	/**
   15 	 * Convenience function to resolve a set of translated strings into a 
   16 	 * single one depending upon the current language.
   17 	 * @param {langmap} vals - All translations of a given word.
   18 	 * @private
   19 	 * @function _strlang
   20 	 * @memberof ort
   21 	 */
   22 	function _strlang(vals: langmap): string
   23 	{
   24 		let lang: string|null;
   25 		lang = document.documentElement.lang;
   26 		if (null !== lang && lang in vals)
   27 			return vals[lang];
   28 		else if ('_default' in vals)
   29 			return vals['_default'];
   30 		else
   31 			return '';
   32 	}
   33 
   34 	/**
   35 	 * Used exclusively by enumerations and bitfields to do language 
   36 	 * replacement conditional upon the label (<i>jslabel</i> in the 
   37 	 * configuration).
   38 	 * Like {@link ort._replcl} with inclusion set to false.
   39 	 * @param {HTMLElement} e - The root of the DOM tree in which we 
   40 	 * query for elements to fill into.
   41 	 * @param {String} name - The class name we search for within the 
   42 	 * root (not inclusive).
   43 	 * @param {langmap} vals - All possible translations.
   44 	 * @private
   45 	 * @function _replcllang
   46 	 * @memberof ort
   47 	 */
   48 	function _replcllang(e: HTMLElement|null, name: string, vals: langmap): void
   49 	{
   50 		_replcl(e, name, _strlang(vals), false);
   51 	}
   52 
   53 	/**
   54 	 * Used exclusively by enumerations and bitfields to do language 
   55 	 * replacement conditional upon the label (<i>jslabel</i> in the 
   56 	 * configuration).
   57 	 * Like {@link ort._repl}.
   58 	 * @param {HTMLElement} e - The root of the DOM tree in which we 
   59 	 * query for elements to fill into.
   60 	 * @param {langmap} vals - All possible translations.
   61 	 * @private
   62 	 * @function _repllang
   63 	 * @memberof ort
   64 	 */
   65 	function _repllang(e: HTMLElement|null, vals: langmap): void
   66 	{
   67 		_repl(e, _strlang(vals));
   68 	}
   69 
   70 	function _attr(e: HTMLElement|null, attr: string, text: string): void
   71 	{
   72 		if (null !== e)
   73 			e.setAttribute(attr, text);
   74 	}
   75 
   76 	function _rattr(e: HTMLElement|null, attr: string): void
   77 	{
   78 		if (null !== e)
   79 			e.removeAttribute(attr);
   80 	}
   81 
   82 	/**
   83 	 * Internal function for checking inputs for all elements of class 
   84 	 * strct-name-value-checked whose value matches the object's value. 
   85 	 * If the object is null, all elements are unchecked.
   86 	 * @param {HTMLElement} e - The root of the DOM tree in which we 
   87 	 * query for elements to fill into.
   88 	 * @param {String} strct - The name of the structure that we're 
   89 	 * filling in.
   90 	 * @param {String} name - The name of the field.
   91 	 * @param {Number|String|null} obj - The data itself.
   92 	 * @param {Boolean} inc - Whether to include the root element in 
   93 	 * looking for elements to fill.
   94 	 * @private
   95 	 * @function _fillValueChecked
   96 	 * @memberof ort
   97 	 */
   98 	function _fillValueChecked(e: HTMLElement, fname: string, val: number|string|null, inc: boolean): void
   99 	{
  100 		let list: HTMLElement[];
  101 		let i: number;
  102 		let valstr: string|null;
  103 		fname += '-value-checked';
  104 		valstr = null === val ? null : 
  105 			("number" === typeof val ? val.toString() : val);
  106 		list = _elemList(e, fname, inc);
  107 		for (i = 0; i < list.length; i++)
  108 			if (valstr === null)
  109 				_rattr(list[i], 'checked');
  110 			else if (valstr === (<HTMLInputElement>list[i]).value)
  111 				_attr(list[i], 'checked', 'true');
  112 			else
  113 				_rattr(list[i], 'checked');
  114 	}
  115 
  116 	/**
  117 	 * Internal function that takes all <code>&lt;option&gt;</code> 
  118 	 * elements in the root and sets or unsets their 
  119 	 * <code>selected</code> status depending upon whether it matches the 
  120 	 * object's value.
  121 	 * @param {HTMLElement} e - The root of the DOM tree in which we 
  122 	 * query for elements to fill into.
  123 	 * @param {Number|String} val - The object's value.
  124 	 * @private
  125 	 * @function _fillValueSelect
  126 	 * @memberof ort
  127 	 */
  128 	function _fillValueSelect(e: HTMLElement|null, val: number|string): void
  129 	{
  130 		let list: HTMLCollectionOf<Element>;
  131 		let i: number;
  132 		let v: string|number;
  133 		if (null === e)
  134 			return;
  135 		list = e.getElementsByTagName('option');
  136 		for (i = 0; i < list.length; i++) {
  137 			v = 'number' === typeof val ? 
  138 			     parseInt((<HTMLOptionElement>list[i]).value) :
  139 			     (<HTMLOptionElement>list[i]).value;
  140 			if (val === v)
  141 				_attr(<HTMLOptionElement>list[i], 'selected', 'true');
  142 			else
  143 				_rattr(<HTMLOptionElement>list[i], 'selected');
  144 		}
  145 	}
  146 
  147 	function _attrcl(e: HTMLElement|null, attr: string, name: string, text: string, inc: boolean): void
  148 	{
  149 		let list: HTMLElement[];
  150 		let i: number;
  151 		if (null === e)
  152 			return;
  153 		list = _elemList(e, name, inc);
  154 		for (i = 0; i < list.length; i++)
  155 			_attr(list[i], attr, text);
  156 	}
  157 
  158 	function _elemList(e: HTMLElement|null, cls: string, inc: boolean): HTMLElement[]
  159 	{
  160 		let a: HTMLElement[];
  161 		let list: HTMLCollectionOf<Element>;
  162 		let i: number;
  163 		a = [];
  164 		if (null === e)
  165 			return a;
  166 		list = e.getElementsByClassName(cls);
  167 		for (i = 0; i < list.length; i++)
  168 			a.push(<HTMLElement>list[i]);
  169 		if (inc && e.classList.contains(cls))
  170 			a.push(e);
  171 		return a;
  172 	}
  173 
  174 	function _repl(e: HTMLElement|null, text: string): void
  175 	{
  176 		if (null === e)
  177 			return;
  178 		while (e.firstChild)
  179 			e.removeChild(e.firstChild);
  180 		e.appendChild(document.createTextNode(text));
  181 	}
  182 
  183 	/**
  184 	 * Internal function for filling in ISO-8601 dates.
  185 	 * @param {HTMLElement} e - The root of the DOM tree in which we 
  186 	 * query for elements to fill into.
  187 	 * @param {String} strct - The name of the structure that we're 
  188 	 * filling in.
  189 	 * @param {String} name - The name of the field.
  190 	 * @param {Number|null} obj - The data itself.
  191 	 * @param {Boolean} inc - Whether to include the root element in 
  192 	 * looking for elements to fill.
  193 	 * @private
  194 	 * @function _fillDateValue
  195 	 * @memberof ort
  196 	 */
  197 	function _fillDateValue(e: HTMLElement, strct: string, name: string, val: number|null, inc: boolean): void
  198 	{
  199 		let fname: string;
  200 		let year: number;
  201 		let mo: number;
  202 		let day: number;
  203 		let full: string;
  204 		let d: Date;
  205 		if (null === val)
  206 			return;
  207 		d = new Date();
  208 		d.setTime(val * 1000);
  209 		year = d.getFullYear();
  210 		mo = d.getMonth() + 1;
  211 		day = d.getDate();
  212 		full = year + '-' +
  213 			(mo < 10 ? '0' : '') + mo + '-' +
  214 			(day < 10 ? '0' : '') + day;
  215 		fname = strct + '-' + name + '-date-value';
  216 		_attrcl(e, 'value', fname, full, inc);
  217 		fname = strct + '-' + name + '-date-text';
  218 		_replcl(e, fname, full, inc);
  219 	}
  220 
  221 	/**
  222 	 * Internal function for checking inputs for all elements of class 
  223 	 * strct-name-bits-checked whose value is the bit-wise AND of the 
  224 	 * object's value. If the object is null, all elements are unchecked.
  225 	 * @param {HTMLElement} e - The root of the DOM tree in which we 
  226 	 * query for elements to fill into.
  227 	 * @param {String} strct - The name of the structure that we're 
  228 	 * filling in.
  229 	 * @param {String} name - The name of the field.
  230 	 * @param {Number|null} obj - The data itself.
  231 	 * @param {Boolean} inc - Whether to include the root element in 
  232 	 * looking for elements to fill.
  233 	 * @private
  234 	 * @function _fillBitsChecked
  235 	 * @memberof ort
  236 	 */
  237 	function _fillBitsChecked(e: HTMLElement, strct: string, name: string, val: number|null, inc: boolean): void
  238 	{
  239 		let list: HTMLElement[];
  240 		let fname: string;
  241 		let i: number;
  242 		let v: number;
  243 		fname = strct + '-' + name + '-bits-checked';
  244 		list = _elemList(e, fname, inc);
  245 		for (i = 0; i < list.length; i++) {
  246 			if (val === null) {
  247 				_rattr(list[i], 'checked');
  248 				continue;
  249 			}
  250 			v = parseInt((<HTMLInputElement>list[i]).value);
  251 			if (isNaN(v))
  252 				_rattr(list[i], 'checked');
  253 			else if (0 === v && 0 === val)
  254 				_attr(list[i], 'checked', 'true');
  255 			else if ((1 << (v - 1)) & val)
  256 				_attr(list[i], 'checked', 'true');
  257 			else
  258 				_rattr(list[i], 'checked');
  259 		}
  260 	}
  261 
  262 	/**
  263 	 * Internal function for filling a structure field.
  264 	 * This first does the has/no class setting for null values, then 
  265 	 * optionally returns if null (running the custom fields first), 
  266 	 * otherwise the generic text/value/etc fields, then finally the 
  267 	 * custom fields.
  268 	 * @param {HTMLElement} e - The root of the DOM tree in which we 
  269 	 * query for elements to fill into.
  270 	 * @param {String} strct - The name of the structure that we're 
  271 	 * filling in.
  272 	 * @param {String} name - The name of the field.
  273 	 * @param {ort.DataCallbacks|null} custom - Custom callback functions 
  274 	 * to invoke on the field.
  275 	 * @param obj - The data itself, which is either a native type or one 
  276 	 * of the data interfaces for an application-specific type.
  277 	 * @param {Boolean} inc - Whether to include the root element in 
  278 	 * looking for elements to fill. Note that nested structures are 
  279 	 * alwyas filled non-inclusively.
  280 	 * @param {Boolean} cannull - Whether the data object might be null.
  281 	 * @param {Boolean} isblob - Whether the data object is a blob.
  282 	 * @param sub - If the data object is a nested structure interface, 
  283 	 * this is the allocated class of that interface.
  284 	 * @private
  285 	 * @function _fillField
  286 	 * @memberof ort
  287 	 */
  288 	function _fillField(e: HTMLElement, strct: string, name: string, custom: DataCallbacks|null, obj: any, inc: boolean, cannull: boolean, isblob: boolean, sub: any): void
  289 	{
  290 		let i: number;
  291 		let fname: string;
  292 		let list: HTMLElement[];
  293 		fname = strct + '-' + name;
  294 		/* First handle our has/no null situation. */
  295 		if (cannull) {
  296 			if (null === obj) {
  297 				_hidecl(e, strct + '-has-' + name, inc);
  298 				_showcl(e, strct + '-no-' + name, inc);
  299 			} else {
  300 				_showcl(e, strct + '-has-' + name, inc);
  301 				_hidecl(e, strct + '-no-' + name, inc);
  302 			}
  303 		}
  304 		/* Don't process null values that can be null. */
  305 		if (cannull && null === obj) {
  306 			if (null !== custom && fname in custom) {
  307 				if (custom[fname] instanceof Array) {
  308 					for (i = 0; i < custom[fname].length; i++)
  309 						custom[fname][i](e, fname, null);
  310 				} else {
  311 					custom[fname](e, fname, null);
  312 				}
  313 			}
  314 			return;
  315 		}
  316 		/* Non-null non-structs. */
  317 		/* Don't account for blobs. */
  318 		if (null !== sub) {
  319 			list = _elemList(e, fname + '-obj', inc);
  320 			for (i = 0; i < list.length; i++) {
  321 				sub.fillInner(list[i], custom);
  322 			}
  323 		} else if ( ! isblob) {
  324 			list = _elemList(e, fname + '-enum-select', inc);
  325 			for (i = 0; i < list.length; i++) {
  326 				_fillValueSelect(list[i], obj);
  327 			}
  328 			_replcl(e, fname + '-text', obj, inc);
  329 			_attrcl(e, 'value', fname + '-value', obj, inc);
  330 			_fillValueChecked(e, fname, obj, inc);
  331 		}
  332 		/* Lastly, handle the custom callback. */
  333 		if (null !== custom && fname in custom) {
  334 			if (custom[fname] instanceof Array) {
  335 				for (i = 0; i < custom[fname].length; i++)
  336 					custom[fname][i](e, fname, obj);
  337 			} else {
  338 				custom[fname](e, fname, obj);
  339 			}
  340 		}
  341 	}
  342 
  343 	function _replcl(e: HTMLElement|null, name: string, text: string, inc: boolean): void
  344 	{
  345 		let list: HTMLElement[];
  346 		let i: number;
  347 		if (null === e)
  348 			return;
  349 		list = _elemList(e, name, inc);
  350 		for (i = 0; i < list.length; i++)
  351 			_repl(list[i], text);
  352 	}
  353 
  354 	function _classadd(e: HTMLElement|null, name: string): HTMLElement|null
  355 	{
  356 		if (null === e)
  357 			return(null);
  358 		if ( ! e.classList.contains(name))
  359 			e.classList.add(name);
  360 		return(e);
  361 	}
  362 
  363 	function _classaddcl(e: HTMLElement|null, name: string, cls: string, inc: boolean): void
  364 	{
  365 		let list: HTMLElement[];
  366 		let i: number;
  367 		if (null === e)
  368 			return;
  369 		list = _elemList(e, name, inc);
  370 		for (i = 0; i < list.length; i++)
  371 			_classadd(list[i], cls);
  372 	}
  373 
  374 	function _hide(e: HTMLElement|null): HTMLElement|null
  375 	{
  376 		if (null === e)
  377 			return null;
  378 		if ( ! e.classList.contains('hide'))
  379 			e.classList.add('hide');
  380 		return e;
  381 	}
  382 
  383 	function _hidecl(e: HTMLElement|null, name: string, inc: boolean): void
  384 	{
  385 		let list: HTMLElement[];
  386 		let i: number;
  387 		if (null === e)
  388 			return;
  389 		list = _elemList(e, name, inc);
  390 		for (i = 0; i < list.length; i++)
  391 			_hide(list[i]);
  392 	}
  393 
  394 	function _show(e: HTMLElement|null): HTMLElement|null
  395 	{
  396 		if (null === e)
  397 			return null;
  398 		if (e.classList.contains('hide'))
  399 			e.classList.remove('hide');
  400 		return e;
  401 	}
  402 
  403 	function _showcl(e: HTMLElement|null, name: string, inc: boolean): void
  404 	{
  405 		let list: HTMLElement[];
  406 		let i: number;
  407 		if (null === e)
  408 			return;
  409 		list = _elemList(e, name, inc);
  410 		for (i = 0; i < list.length; i++)
  411 			_show(list[i]);
  412 	}
  413 
  414 	/**
  415 	 * All possible callback functions for passing to the "custom" 
  416 	 * associative array when filling in DOM trees.
  417 	 * @interface ort.DataCallbacks
  418 	 */
  419 	export type DCbstring = (e: HTMLElement, name: string, val: string) => void;
  420 	export type DCbstringNull = (e: HTMLElement, name: string, val: string|null) => void;
  421 	export type DCbnumber = (e: HTMLElement, name: string, val: number) => void;
  422 	export type DCbnumberNull = (e: HTMLElement, name: string, val: number|null) => void;
  423 	export type DCbStructcompany = (e: HTMLElement, name: string, val: ort.companyData|null) => void;
  424 	export type DCbStructuser = (e: HTMLElement, name: string, val: ort.userData|null) => void;
  425 	export type DCbStructsession = (e: HTMLElement, name: string, val: ort.sessionData|null) => void;
  426 
  427 	export interface DataCallbacks
  428 	{
  429 		[key: string]: any;
  430 		'company'?: DCbStructcompany|DCbStructcompany[];
  431 		'company-name'?: DCbstring|DCbstring[];
  432 		'company-id'?: DCbnumber|DCbnumber[];
  433 		'company-somenum'?: DCbnumberNull|DCbnumberNull[];
  434 		'user'?: DCbStructuser|DCbStructuser[];
  435 		'user-company'?: DCbStructcompany|DCbStructcompany[];
  436 		'user-cid'?: DCbnumber|DCbnumber[];
  437 		'user-sex'?: DCbnumber|DCbnumber[];
  438 		'user-hash'?: DCbstring|DCbstring[];
  439 		'user-email'?: DCbstring|DCbstring[];
  440 		'user-name'?: DCbstring|DCbstring[];
  441 		'user-uid'?: DCbnumber|DCbnumber[];
  442 		'session'?: DCbStructsession|DCbStructsession[];
  443 		'session-user'?: DCbStructuser|DCbStructuser[];
  444 		'session-userid'?: DCbnumber|DCbnumber[];
  445 		'session-token'?: DCbnumber|DCbnumber[];
  446 		'session-mtime'?: DCbnumber|DCbnumber[];
  447 		'session-id'?: DCbnumber|DCbnumber[];
  448 	}
  449 
  450 	/**
  451 	 * 
  452 	 * Controlling organisation.<br/>
  453 	 * 
  454 	 * @interface ort.companyData
  455 	 */
  456 	export interface companyData
  457 	{
  458 		name: string;
  459 		id: number;
  460 		somenum: number;
  461 	}
  462 
  463 	/**
  464 	 * 
  465 	 * A regular user.<br/>
  466 	 * 
  467 	 * @interface ort.userData
  468 	 */
  469 	export interface userData
  470 	{
  471 		company: companyData;
  472 		cid: number;
  473 		sex: number;
  474 		hash: string;
  475 		email: string;
  476 		name: string;
  477 		uid: number;
  478 	}
  479 
  480 	/**
  481 	 * 
  482 	 * Authenticated session.<br/>
  483 	 * 
  484 	 * @interface ort.sessionData
  485 	 */
  486 	export interface sessionData
  487 	{
  488 		user: userData;
  489 		userid: number;
  490 		token: number;
  491 		mtime: number;
  492 		id: number;
  493 	}
  494 
  495 	/**
  496 	 * Accepts {@link ort.companyData} for writing into a DOM tree.
  497 	 * @param {(ort.companyData|ort.companyData[])} obj - The object(s) 
  498 	 * to write.
  499 	 * @memberof ort
  500 	 * @constructor
  501 	 * @class
  502 	 */
  503 	export class company {
  504 		obj: companyData|companyData[];
  505 		constructor(o: companyData|companyData[]) {
  506 			this.obj = o;
  507 		}
  508 
  509 		/**
  510 		 * Write the {@link ort.companyData} into the given HTMLElement 
  511 		 * in the DOM tree.
  512 		 * If constructed with an array, the first element is used.
  513 		 * Elements within (and including) "e" having the following 
  514 		 * classes are manipulated as follows:
  515 		 * <ul>
  516 		 * <li>company-name-enum-select: sets the <code>select</code> 
  517 		 * attribute for <code>&lt;option&gt;</code> values matching 
  518 		 * <i>name</i> under the element</li>
  519 		 * <li>company-name-value-checked: sets the <code>checked</code> 
  520 		 * attribute under the element matching the input</li>
  521 		 * <li>company-name-text: replace contents with <i>name</i> 
  522 		 * data</li>
  523 		 * <li>company-name-value: replace <code>value</code> attribute 
  524 		 * with <i>name</i> data</li>
  525 		 * <li>company-id-enum-select: sets the <code>select</code> 
  526 		 * attribute for <code>&lt;option&gt;</code> values matching 
  527 		 * <i>id</i> under the element</li>
  528 		 * <li>company-id-value-checked: sets the <code>checked</code> 
  529 		 * attribute under the element matching the input</li>
  530 		 * <li>company-id-text: replace contents with <i>id</i> data</li>
  531 		 * <li>company-id-value: replace <code>value</code> attribute 
  532 		 * with <i>id</i> data</li>
  533 		 * <li>company-has-somenum: <code>hide</code> class removed if 
  534 		 * <i>somenum</i> not null, otherwise <code>hide</code> class is 
  535 		 * added</li>
  536 		 * <li>company-no-somenum: <code>hide</code> class added if 
  537 		 * <i>somenum</i> not null, otherwise <code>hide</code> class is 
  538 		 * removed</li>
  539 		 * <li>company-somenum-enum-select: sets the <code>select</code> 
  540 		 * attribute for <code>&lt;option&gt;</code> values matching 
  541 		 * <i>somenum</i> under the element (if non-null)</li>
  542 		 * <li>company-somenum-value-checked: sets the 
  543 		 * <code>checked</code> attribute under the element matching the 
  544 		 * input (if non-null)</li>
  545 		 * <li>company-somenum-text: replace contents with <i>somenum</i> 
  546 		 * data (if non-null)</li>
  547 		 * <li>company-somenum-value: replace <code>value</code> 
  548 		 * attribute with <i>somenum</i> data (if non-null)</li>
  549 		 * </ul>
  550 		 * @param {HTMLElement} e - The DOM element.
  551 		 * @param {ort.DataCallbacks} custom - The optional dictionary of 
  552 		 * functions keyed by structure and field name (e.g., <i>foo</i> 
  553 		 * structure, <i>bar</i> field would be <code>foo-bar</code>). 
  554 		 * The value is a function for custom handling that accepts the 
  555 		 * "e" value, the name of the structure-field, and the value of 
  556 		 * the structure and field.
  557 		 * You may also specify an array of functions instead of a 
  558 		 * singleton.
  559 		 * These callbacks are invoked <b>after</b> the generic classes 
  560 		 * are filled.
  561 		 * @function fill
  562 		 * @memberof ort.company#
  563 		 */
  564 		fill(e: HTMLElement|null, custom?: DataCallbacks|null): void
  565 		{
  566 			this._fill(e, this.obj, true, custom);
  567 		}
  568 
  569 		/**
  570 		 * Like {@link ort.company#fill} but instead of accepting a 
  571 		 * single element to fill, filling into all elements 
  572 		 * (non-inclusive) matching the given class name beneath 
  573 		 * (non-inclusive) the given root.
  574 		 * @param {HTMLElement} e - The DOM element.
  575 		 * @param {String} name - The name of the class into which to 
  576 		 * fill.
  577 		 * @param {ort.DataCallbacks} custom - The optional custom 
  578 		 * handler dictionary (see {@link ort.company#fill} for details).
  579 		 * @function fillByClass
  580 		 * @memberof ort.company#
  581 		 */
  582 		fillByClass(e: HTMLElement|null, name: string, custom?: DataCallbacks|null): void
  583 		{
  584 			this._fillByClass(e, name, true, custom);
  585 		}
  586 
  587 		/**
  588 		 * Like {@link ort.company#fillByClass} but inclusive the root 
  589 		 * and targets by class.
  590 		 * @param {HTMLElement} e - The DOM element.
  591 		 * @param {String} name - The name of the class into which to 
  592 		 * fill.
  593 		 * @param {ort.DataCallbacks} custom - The optional custom 
  594 		 * handler dictionary (see {@link ort.company#fill} for details).
  595 		 * @function fillInnerByClass
  596 		 * @memberof ort.company#
  597 		 */
  598 		fillInnerByClass(e: HTMLElement|null, name: string, custom?: DataCallbacks|null): void
  599 		{
  600 			this._fillByClass(e, name, false, custom);
  601 		}
  602 
  603 		/**
  604 		 * Like {@link ort.company#fill} but not including the root 
  605 		 * element "e".
  606 		 * @param {HTMLElement} e - The DOM element.
  607 		 * @param {ort.DataCallbacks} custom - The optional custom 
  608 		 * handler dictionary (see {@link ort.company#fill} for details).
  609 		 * @function fillInner
  610 		 * @memberof ort.company#
  611 		 */
  612 		fillInner(e: HTMLElement|null, custom?: DataCallbacks|null): void
  613 		{
  614 			this._fill(e, this.obj, false, custom);
  615 		}
  616 
  617 		/**
  618 		 * Implements all {@link ort.company#fill} functions.
  619 		 * @param {HTMLElement} e - The DOM element.
  620 		 * @param {ort.companyData|ort.companyData[]|null} o - The object 
  621 		 * (or array) to fill.
  622 		 * @param {Boolean} inc - Whether to include the root or not when 
  623 		 * processing.
  624 		 * @param {ort.DataCallbacks} custom - The optional custom 
  625 		 * handler dictionary (see {@link ort.company#fill}).
  626 		 * @private
  627 		 * @function _fill
  628 		 * @memberof ort.company#
  629 		 */
  630 		private _fill(e: HTMLElement|null, o: ort.companyData|ort.companyData[]|null, inc: boolean, custom?: DataCallbacks|null): void
  631 		{
  632 			let i: number;
  633 			if (null === o || null === e)
  634 				return;
  635 			if (o instanceof Array) {
  636 				if (0 === o.length)
  637 					return;
  638 				o = o[0];
  639 			}
  640 			if (typeof custom === 'undefined')
  641 				custom = null;
  642 			_fillField(e, 'company', 'name', custom, o.name, inc, false, false, null);
  643 			_fillField(e, 'company', 'id', custom, o.id, inc, false, false, null);
  644 			_fillField(e, 'company', 'somenum', custom, o.somenum, inc, true, false, null);
  645 			if (null !== custom && 'company' in custom) {
  646 				if (custom['company'] instanceof Array) {
  647 					for (i = 0; i < custom['company']!.length; i++)
  648 						(<ort.DCbStructcompany[]>custom['company'])[i](e, 'company', o);
  649 				} else {
  650 					(<ort.DCbStructcompany>custom['company'])(e, 'company', o);
  651 				}
  652 			}
  653 		}
  654 
  655 		/**
  656 		 * Like {@link ort.company#_fill} but instead of accepting a 
  657 		 * single element to fill, filling into all elements matching the 
  658 		 * given class name beneath the given root.
  659 		 * @param {HTMLElement} e - The DOM element.
  660 		 * @param {String} name - The name of the class into which to 
  661 		 * fill.
  662 		 * @param {Boolean} inc - Whether to include the roots or not 
  663 		 * when processing.
  664 		 * @param {ort.DataCallbacks} custom - The optional custom 
  665 		 * handler dictionary (see {@link ort.company#fill} for details).
  666 		 * @private
  667 		 * @function _fillByClass
  668 		 * @memberof ort.company#
  669 		 */
  670 		private _fillByClass(e: HTMLElement|null, name: string, inc: boolean, custom?: DataCallbacks|null): void
  671 		{
  672 			let i: number;
  673 			let list: HTMLElement[];
  674 			list = _elemList(e, name, inc);
  675 			for (i = 0; i < list.length; i++)
  676 				this._fill(list[i], this.obj, inc, custom);
  677 		}
  678 
  679 		/**
  680 		 * Like {@link ort.company#fillArray}, but hiding an element if 
  681 		 * the array is empty or null.
  682 		 * @param {HTMLElement|null} e - The DOM element.
  683 		 * @param {HTMLElement|null} tohide - The DOM element to hide.
  684 		 * @param {ort.companyData|ort.companyData[]|null} o - The array 
  685 		 * (or object) to fill.
  686 		 * @param {ort.DataCallbacks} custom - The optional custom 
  687 		 * handler dictionary (see {@link ort.company#fill}).
  688 		 * @function fillArrayOrHide
  689 		 * @memberof ort.company#
  690 		 */
  691 		fillArrayOrHide(e: HTMLElement|null, tohide: HTMLElement|null, custom?: DataCallbacks): void
  692 		{
  693 			let len: number;
  694 			if (null === this.obj)
  695 				len = 0;
  696 			else if (this.obj instanceof Array)
  697 				len = this.obj.length;
  698 			else
  699 				len = 1;
  700 			if (null !== e)
  701 				_hide(e);
  702 			if (null !== tohide)
  703 				_show(tohide);
  704 			this.fillArray(e, custom);
  705 			if (null !== tohide && 0 === len)
  706 				_hide(tohide);
  707 		}
  708 		/**
  709 		 * Like {@link ort.company#fillArray}, but showing an element if 
  710 		 * the array is empty or null.
  711 		 * @param {HTMLElement|null} e - The DOM element.
  712 		 * @param {HTMLElement|null} toshow - The DOM element to show.
  713 		 * @param {ort.companyData|ort.companyData[]|null} o - The array 
  714 		 * (or object) to fill.
  715 		 * @param {ort.DataCallbacks} custom - The optional custom 
  716 		 * handler dictionary (see {@link ort.company#fill}).
  717 		 * @function fillArrayOrShow
  718 		 * @memberof ort.company#
  719 		 */
  720 		fillArrayOrShow(e: HTMLElement|null, toshow: HTMLElement|null, custom?: DataCallbacks): void
  721 		{
  722 			let len: number;
  723 			if (null === this.obj)
  724 				len = 0;
  725 			else if (this.obj instanceof Array)
  726 				len = this.obj.length;
  727 			else
  728 				len = 1;
  729 			if (null !== e)
  730 				_hide(e);
  731 			if (null !== toshow)
  732 				_hide(toshow);
  733 			this.fillArray(e, custom);
  734 			if (null !== toshow && 0 === len)
  735 				_show(toshow);
  736 		}
  737 		/**
  738 		 * Like {@link ort.company#fill} but for an array of {@link 
  739 		 * ort.companyData}.
  740 		 * If the data is not an array, it is remapped as an array of 
  741 		 * one.
  742 		 * This will save the first element within "e", remove all 
  743 		 * children of "e", then repeatedly clone the saved element and 
  744 		 * re-append it, filling in the cloned subtree with the array 
  745 		 * (inclusive of the subtree root).
  746 		 * If the input array is empty or null, "e" is hidden by using 
  747 		 * the <code>hide</code> class.
  748 		 * Otherwise, the <code>hide</code> class is removed.
  749 		 * @param {HTMLElement} e - The DOM element.
  750 		 * @param {ort.DataCallbacks} custom - The optional custom 
  751 		 * handler dictionary (see {@link ort.company#fill}).
  752 		 * @memberof ort.company#
  753 		 * @function fillArray
  754 		 */
  755 		fillArray(e: HTMLElement|null, custom?: DataCallbacks): void
  756 		{
  757 			let j: number;
  758 			let o: ort.companyData|ort.companyData[]|null;
  759 			let cln: HTMLElement;
  760 			let ar: ort.companyData[];
  761 			let row: HTMLElement;
  762 			o = this.obj;
  763 			if (null !== e)
  764 				_hide(e);
  765 			if (null === o || null === e)
  766 				return;
  767 			if ( ! (o instanceof Array)) {
  768 				ar = [];
  769 				ar.push(o);
  770 				o = ar;
  771 			}
  772 			if (0 === o.length)
  773 				return;
  774 			_show(e);
  775 			row = <HTMLElement>e.children[0];
  776 			if (null === row)
  777 				return;
  778 			e.removeChild(row);
  779 			while (null !== e.firstChild)
  780 				e.removeChild(e.firstChild)
  781 			for (j = 0; j < o.length; j++) {
  782 				cln = <HTMLElement>row.cloneNode(true);
  783 				e.appendChild(cln);
  784 				this._fill(cln, o[j], true, custom);
  785 			}
  786 		}
  787 		/**
  788 		 * Like {@link ort.company#fillArray} but instead of accepting a 
  789 		 * single element to fill, filling all elements by class name 
  790 		 * beneath the given root (non-inclusive).
  791 		 * @param {HTMLElement} e - The DOM element.
  792 		 * @param {String} name - The name of the class into which to 
  793 		 * fill.
  794 		 * @param {ort.DataCallbacks} custom - The optional custom 
  795 		 * handler dictionary (see {@link ort.company#fill} for details).
  796 		 * @function fillArrayByClass
  797 		 * @memberof ort.company#
  798 		 */
  799 		fillArrayByClass(e: HTMLElement|null, name: string, custom?: DataCallbacks): void
  800 		{
  801 			let i: number;
  802 			let list: HTMLElement[];
  803 			list = _elemList(e, name, false);
  804 			for (i = 0; i < list.length; i++)
  805 				this.fillArray(list[i], custom);
  806 		}
  807 
  808 	}
  809 
  810 	/**
  811 	 * Accepts {@link ort.userData} for writing into a DOM tree.
  812 	 * @param {(ort.userData|ort.userData[])} obj - The object(s) to 
  813 	 * write.
  814 	 * @memberof ort
  815 	 * @constructor
  816 	 * @class
  817 	 */
  818 	export class user {
  819 		obj: userData|userData[];
  820 		constructor(o: userData|userData[]) {
  821 			this.obj = o;
  822 		}
  823 
  824 		/**
  825 		 * Write the {@link ort.userData} into the given HTMLElement in 
  826 		 * the DOM tree.
  827 		 * If constructed with an array, the first element is used.
  828 		 * Elements within (and including) "e" having the following 
  829 		 * classes are manipulated as follows:
  830 		 * <ul>
  831 		 * <li>user-company-obj: invoke {@link ort.company#fillInner} 
  832 		 * with company data</li>
  833 		 * <li>user-cid-enum-select: sets the <code>select</code> 
  834 		 * attribute for <code>&lt;option&gt;</code> values matching 
  835 		 * <i>cid</i> under the element</li>
  836 		 * <li>user-cid-value-checked: sets the <code>checked</code> 
  837 		 * attribute under the element matching the input</li>
  838 		 * <li>user-cid-text: replace contents with <i>cid</i> data</li>
  839 		 * <li>user-cid-value: replace <code>value</code> attribute with 
  840 		 * <i>cid</i> data</li>
  841 		 * <li>user-sex-enum-select: sets the <code>select</code> 
  842 		 * attribute for <code>&lt;option&gt;</code> values matching 
  843 		 * <i>sex</i> under the element</li>
  844 		 * <li>user-sex-value-checked: sets the <code>checked</code> 
  845 		 * attribute under the element matching the input</li>
  846 		 * <li>user-sex-text: replace contents with <i>sex</i> data</li>
  847 		 * <li>user-sex-value: replace <code>value</code> attribute with 
  848 		 * <i>sex</i> data</li>
  849 		 * <li>user-hash-enum-select: sets the <code>select</code> 
  850 		 * attribute for <code>&lt;option&gt;</code> values matching 
  851 		 * <i>hash</i> under the element</li>
  852 		 * <li>user-hash-value-checked: sets the <code>checked</code> 
  853 		 * attribute under the element matching the input</li>
  854 		 * <li>user-hash-text: replace contents with <i>hash</i> 
  855 		 * data</li>
  856 		 * <li>user-hash-value: replace <code>value</code> attribute with 
  857 		 * <i>hash</i> data</li>
  858 		 * <li>user-email-enum-select: sets the <code>select</code> 
  859 		 * attribute for <code>&lt;option&gt;</code> values matching 
  860 		 * <i>email</i> under the element</li>
  861 		 * <li>user-email-value-checked: sets the <code>checked</code> 
  862 		 * attribute under the element matching the input</li>
  863 		 * <li>user-email-text: replace contents with <i>email</i> 
  864 		 * data</li>
  865 		 * <li>user-email-value: replace <code>value</code> attribute 
  866 		 * with <i>email</i> data</li>
  867 		 * <li>user-name-enum-select: sets the <code>select</code> 
  868 		 * attribute for <code>&lt;option&gt;</code> values matching 
  869 		 * <i>name</i> under the element</li>
  870 		 * <li>user-name-value-checked: sets the <code>checked</code> 
  871 		 * attribute under the element matching the input</li>
  872 		 * <li>user-name-text: replace contents with <i>name</i> 
  873 		 * data</li>
  874 		 * <li>user-name-value: replace <code>value</code> attribute with 
  875 		 * <i>name</i> data</li>
  876 		 * <li>user-uid-enum-select: sets the <code>select</code> 
  877 		 * attribute for <code>&lt;option&gt;</code> values matching 
  878 		 * <i>uid</i> under the element</li>
  879 		 * <li>user-uid-value-checked: sets the <code>checked</code> 
  880 		 * attribute under the element matching the input</li>
  881 		 * <li>user-uid-text: replace contents with <i>uid</i> data</li>
  882 		 * <li>user-uid-value: replace <code>value</code> attribute with 
  883 		 * <i>uid</i> data</li>
  884 		 * </ul>
  885 		 * @param {HTMLElement} e - The DOM element.
  886 		 * @param {ort.DataCallbacks} custom - The optional dictionary of 
  887 		 * functions keyed by structure and field name (e.g., <i>foo</i> 
  888 		 * structure, <i>bar</i> field would be <code>foo-bar</code>). 
  889 		 * The value is a function for custom handling that accepts the 
  890 		 * "e" value, the name of the structure-field, and the value of 
  891 		 * the structure and field.
  892 		 * You may also specify an array of functions instead of a 
  893 		 * singleton.
  894 		 * These callbacks are invoked <b>after</b> the generic classes 
  895 		 * are filled.
  896 		 * @function fill
  897 		 * @memberof ort.user#
  898 		 */
  899 		fill(e: HTMLElement|null, custom?: DataCallbacks|null): void
  900 		{
  901 			this._fill(e, this.obj, true, custom);
  902 		}
  903 
  904 		/**
  905 		 * Like {@link ort.user#fill} but instead of accepting a single 
  906 		 * element to fill, filling into all elements (non-inclusive) 
  907 		 * matching the given class name beneath (non-inclusive) the 
  908 		 * given root.
  909 		 * @param {HTMLElement} e - The DOM element.
  910 		 * @param {String} name - The name of the class into which to 
  911 		 * fill.
  912 		 * @param {ort.DataCallbacks} custom - The optional custom 
  913 		 * handler dictionary (see {@link ort.user#fill} for details).
  914 		 * @function fillByClass
  915 		 * @memberof ort.user#
  916 		 */
  917 		fillByClass(e: HTMLElement|null, name: string, custom?: DataCallbacks|null): void
  918 		{
  919 			this._fillByClass(e, name, true, custom);
  920 		}
  921 
  922 		/**
  923 		 * Like {@link ort.user#fillByClass} but inclusive the root and 
  924 		 * targets by class.
  925 		 * @param {HTMLElement} e - The DOM element.
  926 		 * @param {String} name - The name of the class into which to 
  927 		 * fill.
  928 		 * @param {ort.DataCallbacks} custom - The optional custom 
  929 		 * handler dictionary (see {@link ort.user#fill} for details).
  930 		 * @function fillInnerByClass
  931 		 * @memberof ort.user#
  932 		 */
  933 		fillInnerByClass(e: HTMLElement|null, name: string, custom?: DataCallbacks|null): void
  934 		{
  935 			this._fillByClass(e, name, false, custom);
  936 		}
  937 
  938 		/**
  939 		 * Like {@link ort.user#fill} but not including the root element 
  940 		 * "e".
  941 		 * @param {HTMLElement} e - The DOM element.
  942 		 * @param {ort.DataCallbacks} custom - The optional custom 
  943 		 * handler dictionary (see {@link ort.user#fill} for details).
  944 		 * @function fillInner
  945 		 * @memberof ort.user#
  946 		 */
  947 		fillInner(e: HTMLElement|null, custom?: DataCallbacks|null): void
  948 		{
  949 			this._fill(e, this.obj, false, custom);
  950 		}
  951 
  952 		/**
  953 		 * Implements all {@link ort.user#fill} functions.
  954 		 * @param {HTMLElement} e - The DOM element.
  955 		 * @param {ort.userData|ort.userData[]|null} o - The object (or 
  956 		 * array) to fill.
  957 		 * @param {Boolean} inc - Whether to include the root or not when 
  958 		 * processing.
  959 		 * @param {ort.DataCallbacks} custom - The optional custom 
  960 		 * handler dictionary (see {@link ort.user#fill}).
  961 		 * @private
  962 		 * @function _fill
  963 		 * @memberof ort.user#
  964 		 */
  965 		private _fill(e: HTMLElement|null, o: ort.userData|ort.userData[]|null, inc: boolean, custom?: DataCallbacks|null): void
  966 		{
  967 			let i: number;
  968 			if (null === o || null === e)
  969 				return;
  970 			if (o instanceof Array) {
  971 				if (0 === o.length)
  972 					return;
  973 				o = o[0];
  974 			}
  975 			if (typeof custom === 'undefined')
  976 				custom = null;
  977 			_fillField(e, 'user', 'company', custom, o.company, inc, false, false, new company(o.company));
  978 			_fillField(e, 'user', 'cid', custom, o.cid, inc, false, false, null);
  979 			_fillField(e, 'user', 'sex', custom, o.sex, inc, false, false, null);
  980 			_fillField(e, 'user', 'hash', custom, o.hash, inc, false, false, null);
  981 			_fillField(e, 'user', 'email', custom, o.email, inc, false, false, null);
  982 			_fillField(e, 'user', 'name', custom, o.name, inc, false, false, null);
  983 			_fillField(e, 'user', 'uid', custom, o.uid, inc, false, false, null);
  984 			if (null !== custom && 'user' in custom) {
  985 				if (custom['user'] instanceof Array) {
  986 					for (i = 0; i < custom['user']!.length; i++)
  987 						(<ort.DCbStructuser[]>custom['user'])[i](e, 'user', o);
  988 				} else {
  989 					(<ort.DCbStructuser>custom['user'])(e, 'user', o);
  990 				}
  991 			}
  992 		}
  993 
  994 		/**
  995 		 * Like {@link ort.user#_fill} but instead of accepting a single 
  996 		 * element to fill, filling into all elements matching the given 
  997 		 * class name beneath the given root.
  998 		 * @param {HTMLElement} e - The DOM element.
  999 		 * @param {String} name - The name of the class into which to 
 1000 		 * fill.
 1001 		 * @param {Boolean} inc - Whether to include the roots or not 
 1002 		 * when processing.
 1003 		 * @param {ort.DataCallbacks} custom - The optional custom 
 1004 		 * handler dictionary (see {@link ort.user#fill} for details).
 1005 		 * @private
 1006 		 * @function _fillByClass
 1007 		 * @memberof ort.user#
 1008 		 */
 1009 		private _fillByClass(e: HTMLElement|null, name: string, inc: boolean, custom?: DataCallbacks|null): void
 1010 		{
 1011 			let i: number;
 1012 			let list: HTMLElement[];
 1013 			list = _elemList(e, name, inc);
 1014 			for (i = 0; i < list.length; i++)
 1015 				this._fill(list[i], this.obj, inc, custom);
 1016 		}
 1017 
 1018 		/**
 1019 		 * Like {@link ort.user#fillArray}, but hiding an element if the 
 1020 		 * array is empty or null.
 1021 		 * @param {HTMLElement|null} e - The DOM element.
 1022 		 * @param {HTMLElement|null} tohide - The DOM element to hide.
 1023 		 * @param {ort.userData|ort.userData[]|null} o - The array (or 
 1024 		 * object) to fill.
 1025 		 * @param {ort.DataCallbacks} custom - The optional custom 
 1026 		 * handler dictionary (see {@link ort.user#fill}).
 1027 		 * @function fillArrayOrHide
 1028 		 * @memberof ort.user#
 1029 		 */
 1030 		fillArrayOrHide(e: HTMLElement|null, tohide: HTMLElement|null, custom?: DataCallbacks): void
 1031 		{
 1032 			let len: number;
 1033 			if (null === this.obj)
 1034 				len = 0;
 1035 			else if (this.obj instanceof Array)
 1036 				len = this.obj.length;
 1037 			else
 1038 				len = 1;
 1039 			if (null !== e)
 1040 				_hide(e);
 1041 			if (null !== tohide)
 1042 				_show(tohide);
 1043 			this.fillArray(e, custom);
 1044 			if (null !== tohide && 0 === len)
 1045 				_hide(tohide);
 1046 		}
 1047 		/**
 1048 		 * Like {@link ort.user#fillArray}, but showing an element if the 
 1049 		 * array is empty or null.
 1050 		 * @param {HTMLElement|null} e - The DOM element.
 1051 		 * @param {HTMLElement|null} toshow - The DOM element to show.
 1052 		 * @param {ort.userData|ort.userData[]|null} o - The array (or 
 1053 		 * object) to fill.
 1054 		 * @param {ort.DataCallbacks} custom - The optional custom 
 1055 		 * handler dictionary (see {@link ort.user#fill}).
 1056 		 * @function fillArrayOrShow
 1057 		 * @memberof ort.user#
 1058 		 */
 1059 		fillArrayOrShow(e: HTMLElement|null, toshow: HTMLElement|null, custom?: DataCallbacks): void
 1060 		{
 1061 			let len: number;
 1062 			if (null === this.obj)
 1063 				len = 0;
 1064 			else if (this.obj instanceof Array)
 1065 				len = this.obj.length;
 1066 			else
 1067 				len = 1;
 1068 			if (null !== e)
 1069 				_hide(e);
 1070 			if (null !== toshow)
 1071 				_hide(toshow);
 1072 			this.fillArray(e, custom);
 1073 			if (null !== toshow && 0 === len)
 1074 				_show(toshow);
 1075 		}
 1076 		/**
 1077 		 * Like {@link ort.user#fill} but for an array of {@link 
 1078 		 * ort.userData}.
 1079 		 * If the data is not an array, it is remapped as an array of 
 1080 		 * one.
 1081 		 * This will save the first element within "e", remove all 
 1082 		 * children of "e", then repeatedly clone the saved element and 
 1083 		 * re-append it, filling in the cloned subtree with the array 
 1084 		 * (inclusive of the subtree root).
 1085 		 * If the input array is empty or null, "e" is hidden by using 
 1086 		 * the <code>hide</code> class.
 1087 		 * Otherwise, the <code>hide</code> class is removed.
 1088 		 * @param {HTMLElement} e - The DOM element.
 1089 		 * @param {ort.DataCallbacks} custom - The optional custom 
 1090 		 * handler dictionary (see {@link ort.user#fill}).
 1091 		 * @memberof ort.user#
 1092 		 * @function fillArray
 1093 		 */
 1094 		fillArray(e: HTMLElement|null, custom?: DataCallbacks): void
 1095 		{
 1096 			let j: number;
 1097 			let o: ort.userData|ort.userData[]|null;
 1098 			let cln: HTMLElement;
 1099 			let ar: ort.userData[];
 1100 			let row: HTMLElement;
 1101 			o = this.obj;
 1102 			if (null !== e)
 1103 				_hide(e);
 1104 			if (null === o || null === e)
 1105 				return;
 1106 			if ( ! (o instanceof Array)) {
 1107 				ar = [];
 1108 				ar.push(o);
 1109 				o = ar;
 1110 			}
 1111 			if (0 === o.length)
 1112 				return;
 1113 			_show(e);
 1114 			row = <HTMLElement>e.children[0];
 1115 			if (null === row)
 1116 				return;
 1117 			e.removeChild(row);
 1118 			while (null !== e.firstChild)
 1119 				e.removeChild(e.firstChild)
 1120 			for (j = 0; j < o.length; j++) {
 1121 				cln = <HTMLElement>row.cloneNode(true);
 1122 				e.appendChild(cln);
 1123 				this._fill(cln, o[j], true, custom);
 1124 			}
 1125 		}
 1126 		/**
 1127 		 * Like {@link ort.user#fillArray} but instead of accepting a 
 1128 		 * single element to fill, filling all elements by class name 
 1129 		 * beneath the given root (non-inclusive).
 1130 		 * @param {HTMLElement} e - The DOM element.
 1131 		 * @param {String} name - The name of the class into which to 
 1132 		 * fill.
 1133 		 * @param {ort.DataCallbacks} custom - The optional custom 
 1134 		 * handler dictionary (see {@link ort.user#fill} for details).
 1135 		 * @function fillArrayByClass
 1136 		 * @memberof ort.user#
 1137 		 */
 1138 		fillArrayByClass(e: HTMLElement|null, name: string, custom?: DataCallbacks): void
 1139 		{
 1140 			let i: number;
 1141 			let list: HTMLElement[];
 1142 			list = _elemList(e, name, false);
 1143 			for (i = 0; i < list.length; i++)
 1144 				this.fillArray(list[i], custom);
 1145 		}
 1146 
 1147 	}
 1148 
 1149 	/**
 1150 	 * Accepts {@link ort.sessionData} for writing into a DOM tree.
 1151 	 * @param {(ort.sessionData|ort.sessionData[])} obj - The object(s) 
 1152 	 * to write.
 1153 	 * @memberof ort
 1154 	 * @constructor
 1155 	 * @class
 1156 	 */
 1157 	export class session {
 1158 		obj: sessionData|sessionData[];
 1159 		constructor(o: sessionData|sessionData[]) {
 1160 			this.obj = o;
 1161 		}
 1162 
 1163 		/**
 1164 		 * Write the {@link ort.sessionData} into the given HTMLElement 
 1165 		 * in the DOM tree.
 1166 		 * If constructed with an array, the first element is used.
 1167 		 * Elements within (and including) "e" having the following 
 1168 		 * classes are manipulated as follows:
 1169 		 * <ul>
 1170 		 * <li>session-user-obj: invoke {@link ort.user#fillInner} with 
 1171 		 * user data</li>
 1172 		 * <li>session-userid-enum-select: sets the <code>select</code> 
 1173 		 * attribute for <code>&lt;option&gt;</code> values matching 
 1174 		 * <i>userid</i> under the element</li>
 1175 		 * <li>session-userid-value-checked: sets the 
 1176 		 * <code>checked</code> attribute under the element matching the 
 1177 		 * input</li>
 1178 		 * <li>session-userid-text: replace contents with <i>userid</i> 
 1179 		 * data</li>
 1180 		 * <li>session-userid-value: replace <code>value</code> attribute 
 1181 		 * with <i>userid</i> data</li>
 1182 		 * <li>session-token-enum-select: sets the <code>select</code> 
 1183 		 * attribute for <code>&lt;option&gt;</code> values matching 
 1184 		 * <i>token</i> under the element</li>
 1185 		 * <li>session-token-value-checked: sets the <code>checked</code> 
 1186 		 * attribute under the element matching the input</li>
 1187 		 * <li>session-token-text: replace contents with <i>token</i> 
 1188 		 * data</li>
 1189 		 * <li>session-token-value: replace <code>value</code> attribute 
 1190 		 * with <i>token</i> data</li>
 1191 		 * <li>session-mtime-enum-select: sets the <code>select</code> 
 1192 		 * attribute for <code>&lt;option&gt;</code> values matching 
 1193 		 * <i>mtime</i> under the element</li>
 1194 		 * <li>session-mtime-value-checked: sets the <code>checked</code> 
 1195 		 * attribute under the element matching the input</li>
 1196 		 * <li>session-mtime-text: replace contents with <i>mtime</i> 
 1197 		 * data</li>
 1198 		 * <li>session-mtime-value: replace <code>value</code> attribute 
 1199 		 * with <i>mtime</i> data</li>
 1200 		 * <li>session-mtime-date-value: set the element's 
 1201 		 * <code>value</code> to the ISO-8601 date format of the 
 1202 		 * data</li>
 1203 		 * <li>session-mtime-date-text: like session-mtime-date-value, 
 1204 		 * but replacing contents
 1205 		 * <li>session-id-enum-select: sets the <code>select</code> 
 1206 		 * attribute for <code>&lt;option&gt;</code> values matching 
 1207 		 * <i>id</i> under the element</li>
 1208 		 * <li>session-id-value-checked: sets the <code>checked</code> 
 1209 		 * attribute under the element matching the input</li>
 1210 		 * <li>session-id-text: replace contents with <i>id</i> data</li>
 1211 		 * <li>session-id-value: replace <code>value</code> attribute 
 1212 		 * with <i>id</i> data</li>
 1213 		 * </ul>
 1214 		 * @param {HTMLElement} e - The DOM element.
 1215 		 * @param {ort.DataCallbacks} custom - The optional dictionary of 
 1216 		 * functions keyed by structure and field name (e.g., <i>foo</i> 
 1217 		 * structure, <i>bar</i> field would be <code>foo-bar</code>). 
 1218 		 * The value is a function for custom handling that accepts the 
 1219 		 * "e" value, the name of the structure-field, and the value of 
 1220 		 * the structure and field.
 1221 		 * You may also specify an array of functions instead of a 
 1222 		 * singleton.
 1223 		 * These callbacks are invoked <b>after</b> the generic classes 
 1224 		 * are filled.
 1225 		 * @function fill
 1226 		 * @memberof ort.session#
 1227 		 */
 1228 		fill(e: HTMLElement|null, custom?: DataCallbacks|null): void
 1229 		{
 1230 			this._fill(e, this.obj, true, custom);
 1231 		}
 1232 
 1233 		/**
 1234 		 * Like {@link ort.session#fill} but instead of accepting a 
 1235 		 * single element to fill, filling into all elements 
 1236 		 * (non-inclusive) matching the given class name beneath 
 1237 		 * (non-inclusive) the given root.
 1238 		 * @param {HTMLElement} e - The DOM element.
 1239 		 * @param {String} name - The name of the class into which to 
 1240 		 * fill.
 1241 		 * @param {ort.DataCallbacks} custom - The optional custom 
 1242 		 * handler dictionary (see {@link ort.session#fill} for details).
 1243 		 * @function fillByClass
 1244 		 * @memberof ort.session#
 1245 		 */
 1246 		fillByClass(e: HTMLElement|null, name: string, custom?: DataCallbacks|null): void
 1247 		{
 1248 			this._fillByClass(e, name, true, custom);
 1249 		}
 1250 
 1251 		/**
 1252 		 * Like {@link ort.session#fillByClass} but inclusive the root 
 1253 		 * and targets by class.
 1254 		 * @param {HTMLElement} e - The DOM element.
 1255 		 * @param {String} name - The name of the class into which to 
 1256 		 * fill.
 1257 		 * @param {ort.DataCallbacks} custom - The optional custom 
 1258 		 * handler dictionary (see {@link ort.session#fill} for details).
 1259 		 * @function fillInnerByClass
 1260 		 * @memberof ort.session#
 1261 		 */
 1262 		fillInnerByClass(e: HTMLElement|null, name: string, custom?: DataCallbacks|null): void
 1263 		{
 1264 			this._fillByClass(e, name, false, custom);
 1265 		}
 1266 
 1267 		/**
 1268 		 * Like {@link ort.session#fill} but not including the root 
 1269 		 * element "e".
 1270 		 * @param {HTMLElement} e - The DOM element.
 1271 		 * @param {ort.DataCallbacks} custom - The optional custom 
 1272 		 * handler dictionary (see {@link ort.session#fill} for details).
 1273 		 * @function fillInner
 1274 		 * @memberof ort.session#
 1275 		 */
 1276 		fillInner(e: HTMLElement|null, custom?: DataCallbacks|null): void
 1277 		{
 1278 			this._fill(e, this.obj, false, custom);
 1279 		}
 1280 
 1281 		/**
 1282 		 * Implements all {@link ort.session#fill} functions.
 1283 		 * @param {HTMLElement} e - The DOM element.
 1284 		 * @param {ort.sessionData|ort.sessionData[]|null} o - The object 
 1285 		 * (or array) to fill.
 1286 		 * @param {Boolean} inc - Whether to include the root or not when 
 1287 		 * processing.
 1288 		 * @param {ort.DataCallbacks} custom - The optional custom 
 1289 		 * handler dictionary (see {@link ort.session#fill}).
 1290 		 * @private
 1291 		 * @function _fill
 1292 		 * @memberof ort.session#
 1293 		 */
 1294 		private _fill(e: HTMLElement|null, o: ort.sessionData|ort.sessionData[]|null, inc: boolean, custom?: DataCallbacks|null): void
 1295 		{
 1296 			let i: number;
 1297 			if (null === o || null === e)
 1298 				return;
 1299 			if (o instanceof Array) {
 1300 				if (0 === o.length)
 1301 					return;
 1302 				o = o[0];
 1303 			}
 1304 			if (typeof custom === 'undefined')
 1305 				custom = null;
 1306 			_fillField(e, 'session', 'user', custom, o.user, inc, false, false, new user(o.user));
 1307 			_fillField(e, 'session', 'userid', custom, o.userid, inc, false, false, null);
 1308 			_fillField(e, 'session', 'token', custom, o.token, inc, false, false, null);
 1309 			_fillField(e, 'session', 'mtime', custom, o.mtime, inc, false, false, null);
 1310 			_fillDateValue(e, 'session', 'mtime', o.mtime, inc);
 1311 			_fillField(e, 'session', 'id', custom, o.id, inc, false, false, null);
 1312 			if (null !== custom && 'session' in custom) {
 1313 				if (custom['session'] instanceof Array) {
 1314 					for (i = 0; i < custom['session']!.length; i++)
 1315 						(<ort.DCbStructsession[]>custom['session'])[i](e, 'session', o);
 1316 				} else {
 1317 					(<ort.DCbStructsession>custom['session'])(e, 'session', o);
 1318 				}
 1319 			}
 1320 		}
 1321 
 1322 		/**
 1323 		 * Like {@link ort.session#_fill} but instead of accepting a 
 1324 		 * single element to fill, filling into all elements matching the 
 1325 		 * given class name beneath the given root.
 1326 		 * @param {HTMLElement} e - The DOM element.
 1327 		 * @param {String} name - The name of the class into which to 
 1328 		 * fill.
 1329 		 * @param {Boolean} inc - Whether to include the roots or not 
 1330 		 * when processing.
 1331 		 * @param {ort.DataCallbacks} custom - The optional custom 
 1332 		 * handler dictionary (see {@link ort.session#fill} for details).
 1333 		 * @private
 1334 		 * @function _fillByClass
 1335 		 * @memberof ort.session#
 1336 		 */
 1337 		private _fillByClass(e: HTMLElement|null, name: string, inc: boolean, custom?: DataCallbacks|null): void
 1338 		{
 1339 			let i: number;
 1340 			let list: HTMLElement[];
 1341 			list = _elemList(e, name, inc);
 1342 			for (i = 0; i < list.length; i++)
 1343 				this._fill(list[i], this.obj, inc, custom);
 1344 		}
 1345 
 1346 		/**
 1347 		 * Like {@link ort.session#fillArray}, but hiding an element if 
 1348 		 * the array is empty or null.
 1349 		 * @param {HTMLElement|null} e - The DOM element.
 1350 		 * @param {HTMLElement|null} tohide - The DOM element to hide.
 1351 		 * @param {ort.sessionData|ort.sessionData[]|null} o - The array 
 1352 		 * (or object) to fill.
 1353 		 * @param {ort.DataCallbacks} custom - The optional custom 
 1354 		 * handler dictionary (see {@link ort.session#fill}).
 1355 		 * @function fillArrayOrHide
 1356 		 * @memberof ort.session#
 1357 		 */
 1358 		fillArrayOrHide(e: HTMLElement|null, tohide: HTMLElement|null, custom?: DataCallbacks): void
 1359 		{
 1360 			let len: number;
 1361 			if (null === this.obj)
 1362 				len = 0;
 1363 			else if (this.obj instanceof Array)
 1364 				len = this.obj.length;
 1365 			else
 1366 				len = 1;
 1367 			if (null !== e)
 1368 				_hide(e);
 1369 			if (null !== tohide)
 1370 				_show(tohide);
 1371 			this.fillArray(e, custom);
 1372 			if (null !== tohide && 0 === len)
 1373 				_hide(tohide);
 1374 		}
 1375 		/**
 1376 		 * Like {@link ort.session#fillArray}, but showing an element if 
 1377 		 * the array is empty or null.
 1378 		 * @param {HTMLElement|null} e - The DOM element.
 1379 		 * @param {HTMLElement|null} toshow - The DOM element to show.
 1380 		 * @param {ort.sessionData|ort.sessionData[]|null} o - The array 
 1381 		 * (or object) to fill.
 1382 		 * @param {ort.DataCallbacks} custom - The optional custom 
 1383 		 * handler dictionary (see {@link ort.session#fill}).
 1384 		 * @function fillArrayOrShow
 1385 		 * @memberof ort.session#
 1386 		 */
 1387 		fillArrayOrShow(e: HTMLElement|null, toshow: HTMLElement|null, custom?: DataCallbacks): void
 1388 		{
 1389 			let len: number;
 1390 			if (null === this.obj)
 1391 				len = 0;
 1392 			else if (this.obj instanceof Array)
 1393 				len = this.obj.length;
 1394 			else
 1395 				len = 1;
 1396 			if (null !== e)
 1397 				_hide(e);
 1398 			if (null !== toshow)
 1399 				_hide(toshow);
 1400 			this.fillArray(e, custom);
 1401 			if (null !== toshow && 0 === len)
 1402 				_show(toshow);
 1403 		}
 1404 		/**
 1405 		 * Like {@link ort.session#fill} but for an array of {@link 
 1406 		 * ort.sessionData}.
 1407 		 * If the data is not an array, it is remapped as an array of 
 1408 		 * one.
 1409 		 * This will save the first element within "e", remove all 
 1410 		 * children of "e", then repeatedly clone the saved element and 
 1411 		 * re-append it, filling in the cloned subtree with the array 
 1412 		 * (inclusive of the subtree root).
 1413 		 * If the input array is empty or null, "e" is hidden by using 
 1414 		 * the <code>hide</code> class.
 1415 		 * Otherwise, the <code>hide</code> class is removed.
 1416 		 * @param {HTMLElement} e - The DOM element.
 1417 		 * @param {ort.DataCallbacks} custom - The optional custom 
 1418 		 * handler dictionary (see {@link ort.session#fill}).
 1419 		 * @memberof ort.session#
 1420 		 * @function fillArray
 1421 		 */
 1422 		fillArray(e: HTMLElement|null, custom?: DataCallbacks): void
 1423 		{
 1424 			let j: number;
 1425 			let o: ort.sessionData|ort.sessionData[]|null;
 1426 			let cln: HTMLElement;
 1427 			let ar: ort.sessionData[];
 1428 			let row: HTMLElement;
 1429 			o = this.obj;
 1430 			if (null !== e)
 1431 				_hide(e);
 1432 			if (null === o || null === e)
 1433 				return;
 1434 			if ( ! (o instanceof Array)) {
 1435 				ar = [];
 1436 				ar.push(o);
 1437 				o = ar;
 1438 			}
 1439 			if (0 === o.length)
 1440 				return;
 1441 			_show(e);
 1442 			row = <HTMLElement>e.children[0];
 1443 			if (null === row)
 1444 				return;
 1445 			e.removeChild(row);
 1446 			while (null !== e.firstChild)
 1447 				e.removeChild(e.firstChild)
 1448 			for (j = 0; j < o.length; j++) {
 1449 				cln = <HTMLElement>row.cloneNode(true);
 1450 				e.appendChild(cln);
 1451 				this._fill(cln, o[j], true, custom);
 1452 			}
 1453 		}
 1454 		/**
 1455 		 * Like {@link ort.session#fillArray} but instead of accepting a 
 1456 		 * single element to fill, filling all elements by class name 
 1457 		 * beneath the given root (non-inclusive).
 1458 		 * @param {HTMLElement} e - The DOM element.
 1459 		 * @param {String} name - The name of the class into which to 
 1460 		 * fill.
 1461 		 * @param {ort.DataCallbacks} custom - The optional custom 
 1462 		 * handler dictionary (see {@link ort.session#fill} for details).
 1463 		 * @function fillArrayByClass
 1464 		 * @memberof ort.session#
 1465 		 */
 1466 		fillArrayByClass(e: HTMLElement|null, name: string, custom?: DataCallbacks): void
 1467 		{
 1468 			let i: number;
 1469 			let list: HTMLElement[];
 1470 			list = _elemList(e, name, false);
 1471 			for (i = 0; i < list.length; i++)
 1472 				this.fillArray(list[i], custom);
 1473 		}
 1474 
 1475 	}
 1476 
 1477 	/**
 1478 	 * Birthsex of individual<br/>
 1479 	 * This object consists of all values for the <i>sex</i> enumeration.
 1480 	 * It also contains a formatting function designed to work as a 
 1481 	 * custom callback for <code>fill</code> functions.
 1482 	 * All of these values are static: <strong>do not use the 
 1483 	 * constructor</strong>.
 1484 	 * @memberof ort
 1485 	 * @class
 1486 	 */
 1487 	export class sex {
 1488 		/**
 1489 		 * Male<br/>
 1490 		 * @memberof ort.sex#
 1491 		 * @readonly
 1492 		 * @const {number} male
 1493 		 */
 1494 		static readonly male: number = 0;
 1495 		/**
 1496 		 * Female<br/>
 1497 		 * @memberof ort.sex#
 1498 		 * @readonly
 1499 		 * @const {number} female
 1500 		 */
 1501 		static readonly female: number = 1;
 1502 		/**
 1503 		 * Other<br/>
 1504 		 * @memberof ort.sex#
 1505 		 * @readonly
 1506 		 * @const {number} other
 1507 		 */
 1508 		static readonly other: number = 2;
 1509 		/**
 1510 		 * Uses the enumeration item's <i>jslabel</i> (or just the name, 
 1511 		 * if no <i>jslabel</i> is defined) to format a custom label as 
 1512 		 * invoked on an object's <code>fill</code> function. This will 
 1513 		 * act on <code>xxx-yyy-label</code> classes, where 
 1514 		 * <code>xxx</code> is the structure name and <code>yyy</code> is 
 1515 		 * the field name. For example, <code>xxx.fill(e, { 'xxx-yyy': 
 1516 		 * ort.sex.format });</code>, where <code>yyy</code> is a field 
 1517 		 * of type <i>enum sex</i>.
 1518 		 * @static
 1519 		 * @function format
 1520 		 * @param {HTMLElement} e - The DOM element.
 1521 		 * @param {String|null} name - If non-null, data is written to 
 1522 		 * elements under the root with the given class name. Otherwise, 
 1523 		 * data is written directly into the DOM element.
 1524 		 * @param {Number} v - The enumeration value.
 1525 		 * @memberof ort.sex#
 1526 		 */
 1527 		static format(e: HTMLElement, name: string|null, v: number|null): void
 1528 		{
 1529 			let s: string;
 1530 			if (name !== null)
 1531 				name += '-label';
 1532 			if (v === null && name !== null) {
 1533 				_replcl(e, name, 'not given', false);
 1534 				_classaddcl(e, name, 'noanswer', false);
 1535 				return;
 1536 			} else if (v === null) {
 1537 				_repl(e, 'not given');
 1538 				_classadd(e, 'noanswer');
 1539 				return;
 1540 			}
 1541 			switch(v) {
 1542 			case sex.male:
 1543 				s = _strlang({_default: 'male'});
 1544 				break;
 1545 			case sex.female:
 1546 				s = _strlang({_default: 'female'});
 1547 				break;
 1548 			case sex.other:
 1549 				s = _strlang({_default: 'other'});
 1550 				break;
 1551 			default:
 1552 				console.log('sex.format: unknown value: ' + v);
 1553 				s = '';
 1554 				break;
 1555 			}
 1556 			if (name !== null)
 1557 				_replcl(e, name, s, false);
 1558 			else
 1559 				_repl(e, s);
 1560 		}
 1561 	}
 1562 
 1563 }