PageSourceSearch

https://www.allfordj.ru/bitrix/js/main/core/core_uf.js

js allfordj.ru collected 2026-09-26 02:35:24 UTC 18,794 bytes, 843 lines download raw bytes

1;(function ()
2{
3	'use strict';
4
5	BX.namespace('BX.Main.UF');
6
7	if (typeof BX.Main.UF.Manager !== 'undefined')
8	{
9		return;
10	}
11
12	var fieldStack = {};
13
14	/**
15	 * Dynamic form manager. Initilized as singleton below
16	 *
17	 * @constructor
18	 */
19
20	BX.Main.UF.Manager = function ()
21	{
22		this.mode = this.mode || '';
23		this.ajaxUrl = '/bitrix/tools/uf.php';
24	};
25
26
27	BX.Main.UF.Manager.getEdit = function (param, callback)
28	{
29		return BX.Main.UF.EditManager.get(param, callback);
30	};
31
32	BX.Main.UF.Manager.getView = function (param, callback)
33	{
34		return BX.Main.UF.ViewManager.get(param, callback);
35	};
36
37	BX.Main.UF.Manager.prototype.get = function (param, callback)
38	{
39		if (!this.mode)
40		{
41			this.displayError([
42				'No mode set. Use BX.UF.EditManager or BX.UF.ViewManager'
43			]);
44
45			return;
46		}
47
48		return this.query(this.mode, {
49			FIELDS: param.FIELDS,
50			FORM: param.FORM || '',
51			CONTEXT: param.CONTEXT || '',
52			MEDIA_TYPE: param.MEDIA_TYPE || ''
53		}, callback);
54	};
55
56	BX.Main.UF.Manager.prototype.add = function (param, callback)
57	{
58		if (!this.mode)
59		{
60			this.displayError([
61				'No mode set. Use BX.UF.EditManager or BX.UF.ViewManager'
62			]);
63
64			return;
65		}
66
67		return this.query(this.mode, {
68			action: 'add',
69			FIELDS: param.FIELDS,
70			FORM: param.FORM || ''
71		}, callback);
72	};
73
74	BX.Main.UF.Manager.prototype.update = function (param, callback)
75	{
76		if (!this.mode)
77		{
78			this.displayError([
79				'No mode set. Use BX.UF.EditManager or BX.UF.ViewManager'
80			]);
81
82			return;
83		}
84
85		return this.query(this.mode, {
86			action: 'update',
87			FIELDS: param.FIELDS,
88			FORM: param.FORM || ''
89		}, callback);
90	};
91
92	BX.Main.UF.Manager.prototype.delete = function (param, callback)
93	{
94		if (!this.mode)
95		{
96			this.displayError([
97				'No mode set. Use BX.UF.EditManager or BX.UF.ViewManager'
98			]);
99
100			return;
101		}
102
103		return this.query(this.mode, {
104			action: 'delete',
105			FIELDS: param.FIELDS,
106			FORM: param.FORM || ''
107		}, callback);
108	};
109
110	BX.Main.UF.Manager.prototype.query = function (mode, param, callback)
111	{
112		BX.ajax({
113			dataType: 'json',
114			url: this.ajaxUrl,
115			method: 'POST',
116			data: this.prepareQuery(mode, param),
117			onsuccess: this.queryCallback(callback)
118		});
119	};
120
121	BX.Main.UF.Manager.prototype.prepareQuery = function (mode, param)
122	{
123		var p = param || {};
124
125		p.mode = mode;
126		p.lang = BX.message('LANGUAGE_ID') || '';
127		p.tpl = BX.message('UF_SITE_TPL') || '';
128		p.tpls = BX.message('UF_SITE_TPL_SIGN') || '';
129		p.sessid = BX.bitrix_sessid();
130
131		return p;
132	};
133
134	BX.Main.UF.Manager.prototype.queryCallback = function (callback)
135	{
136		var processResult = BX.proxy(this.processResult, this);
137		return function (result)
138		{
139			processResult(result, callback);
140		}
141	};
142
143	BX.Main.UF.Manager.prototype.processResult = function (result, callback)
144	{
145		var asset = '';
146		if (BX.type.isArray(result.ASSET))
147		{
148			asset += result.ASSET.join('\n');
149		}
150
151		if (!!result.ERROR)
152		{
153			this.displayError(result.ERROR);
154		}
155
156		return BX.html(null, asset).then(function ()
157		{
158			if (!!callback)
159			{
160				callback(result.FIELD);
161			}
162		});
163	};
164
165	BX.Main.UF.Manager.prototype.displayError = function (errorList)
166	{
167		for (var i in errorList)
168		{
169			if (errorList.hasOwnProperty(i))
170			{
171				console.error(errorList[i]);
172			}
173		}
174	};
175
176	BX.Main.UF.Manager.prototype.registerField = function (field, fieldDescription, node)
177	{
178		fieldStack[field] = {
179			FIELD: fieldDescription,
180			NODE: node
181		};
182	};
183
184	BX.Main.UF.Manager.prototype.unRegisterField = function (field)
185	{
186		if (!!fieldStack[field])
187		{
188			delete fieldStack[field];
189		}
190	};
191
192
193	BX.Main.UF.ViewManager = function ()
194	{
195		BX.Main.UF.ViewManager.superclass.constructor.apply(this, arguments);
196
197		this.mode = 'main.view';
198	};
199	BX.extend(BX.Main.UF.ViewManager, BX.Main.UF.Manager);
200
201	BX.Main.UF.EditManager = function ()
202	{
203		BX.Main.UF.EditManager.superclass.constructor.apply(this, arguments);
204
205		this.mode = 'main.edit';
206	};
207	BX.extend(BX.Main.UF.EditManager, BX.Main.UF.Manager);
208
209	BX.Main.UF.EditManager.prototype.validate = function (fieldList, callback)
210	{
211		if (fieldList.length > 0)
212		{
213			var request = [];
214			for (var i = 0; i < fieldList.length; i++)
215			{
216				var value = BX.Main.UF.Factory.getValue(fieldList[i]);
217				if (value !== null)
218				{
219					request.push({
220						'ENTITY_ID': fieldStack[fieldList[i]].FIELD.ENTITY_ID,
221						'FIELD': fieldStack[fieldList[i]].FIELD.FIELD,
222						'ENTITY_VALUE_ID': fieldStack[fieldList[i]].FIELD.ENTITY_VALUE_ID,
223						'VALUE': value
224					});
225				}
226			}
227
228			return this.query(this.mode, {
229				action: 'validate',
230				FIELDS: request
231			}, callback);
232		}
233		else
234		{
235			this.queryCallback(callback)({'FIELD': []});
236		}
237	};
238
239	/**
240	 * Base type handler class. Will be initialized in Factory.
241	 *
242	 * @constructor
243	 */
244
245	BX.Main.UF.BaseType = function ()
246	{
247	};
248
249	BX.Main.UF.BaseType.prototype.addRow = function (fieldName, thisButton)
250	{
251		var element = thisButton.parentNode.getElementsByTagName('span');
252		if (element && element.length > 0 && element[0])
253		{
254			var parentElement = element[0].parentNode; // parent
255			var newNode = this.getClone(element[element.length - 1], fieldName);
256
257			if (parentElement === thisButton.parentNode)
258			{
259				parentElement.insertBefore(newNode, thisButton);
260			}
261			else
262			{
263				parentElement.appendChild(newNode);
264			}
265		}
266	};
267
268	/**
269	 * @deprecated
270	 * @param fieldName
271	 * @param thisButton
272	 */
273	BX.Main.UF.BaseType.prototype.addMobileRow = function (fieldName, thisButton)
274	{
275		var element = thisButton.parentNode.getElementsByTagName('span');
276		if (element && element.length && element[0])
277		{
278			var parentElement = element[0].parentNode; // parent
279			var newNode = this.getClone(element[element.length - 1], fieldName);
280			var firstChildren = newNode.firstElementChild;
281			var name = firstChildren.getAttribute('name');
282			var re = /\[(\d)]/;
283			var newName = name.replace(re, function (match, index)
284			{
285				index = parseInt(index) + 1;
286				return '[' + index + ']';
287			});
288			var newItemId = false;
289			var prevItemName = false;
290			var userFieldTypeName = null;
291
292			firstChildren.setAttribute('name', newName);
293
294			if (firstChildren.hasChildNodes())
295			{
296				firstChildren.childNodes.forEach(
297					function (item, index, array)
298					{
299						if (!prevItemName && item.attributes !== undefined && item.tagName === 'INPUT')
300						{
301							item.setAttribute('name', newName);
302							prevItemName = item.getAttribute('id');
303							newItemId = prevItemName + '_1';
304							userFieldTypeName = item.getAttribute('data-user-field-type-name');
305						}
306
307						if (prevItemName && item.attributes !== undefined && item.id !== undefined)
308						{
309							var id = item.getAttribute('id');
310
311							if (id !== prevItemName)
312							{
313								item.setAttribute('id', id.replace(prevItemName, newItemId));
314							}
315							else
316							{
317								item.setAttribute('id', newItemId);
318							}
319						}
320					}
321				);
322			}
323
324			if (parentElement === thisButton.parentNode)
325			{
326				parentElement.insertBefore(newNode, thisButton);
327			}
328			else
329			{
330				parentElement.appendChild(newNode);
331			}
332
333			if (newItemId)
334			{
335				BX.onCustomEvent(
336					'onAddMobileUfField',
337					[newItemId, userFieldTypeName]
338				);
339			}
340
341		}
342	};
343
344	BX.Main.UF.BaseType.prototype.getClone = function (node, fieldName)
345	{
346		var newNode = node.cloneNode(true);
347
348		var inputList = this.findInput(newNode, fieldName);
349		for (var i = 0; i < inputList.length; i++)
350		{
351			inputList[i].value = '';
352		}
353
354		return newNode;
355	};
356
357	BX.Main.UF.BaseType.prototype.findInput = function (node, fieldName)
358	{
359		return BX.findChildren(node, {
360			tagName: /INPUT|TEXTAREA|SELECT/i,
361			attribute: {
362				name: fieldName
363			}
364		}, true);
365	};
366
367	BX.Main.UF.BaseType.prototype.isEmpty = function (field)
368	{
369		var node = this.getNode(field),
370			fieldName = field + (
371				fieldStack[field].FIELD.MULTIPLE === 'Y'
372					? '[]'
373					: ''
374			);
375
376		if (!BX.isNodeInDom(node))
377		{
378			console.error('Node for field ' + field + ' is already removed from DOM');
379		}
380
381		var nodeList = this.findInput(node, fieldName);
382
383		if (nodeList.length <= 0)
384		{
385			console.error('Unable to find field ' + field + ' in the registered node');
386		}
387		else
388		{
389			for (var i = 0; i < nodeList.length; i++)
390			{
391				if (nodeList[i].value !== '')
392				{
393					return false;
394				}
395			}
396		}
397
398		return true;
399	};
400
401	BX.Main.UF.BaseType.prototype.getValue = function (field)
402	{
403		var node = this.getNode(field),
404			fieldName = field + (
405				fieldStack[field].FIELD.MULTIPLE === 'Y'
406					? '[]'
407					: ''
408			),
409			value = fieldStack[field].FIELD.MULTIPLE === 'Y' ? [] : '';
410
411		if (!BX.isNodeInDom(node))
412		{
413			console.error('Node for field ' + field + ' is already removed from DOM');
414		}
415		var nodeList = this.findInput(node, fieldName);
416
417		if (nodeList.length <= 0)
418		{
419			var nodeChildren = (node.children.length ? node.children[0] : false);
420			/**
421			 * @todo remove !BX.util.in_array(fieldStack[field].FIELD.USER_TYPE_ID, ['crm', 'employee'])
422			 * after deploy new Crm and Employee types
423			 */
424			if (
425				!BX.util.in_array(fieldStack[field].FIELD.USER_TYPE_ID, ['crm', 'employee'])
426				&&
427				(
428					!nodeChildren
429					||
430					nodeChildren.getAttribute('data-has-input') !== 'no'
431				)
432			)
433			{
434				console.error('Unable to find field ' + field + ' in the registered node');
435			}
436		}
437		else
438		{
439			for (var i = 0; i < nodeList.length; i++)
440			{
441				if (
442					nodeList[i].tagName === 'INPUT'
443					&& (nodeList[i].type === 'radio' || nodeList[i].type === 'checkbox')
444					&& !nodeList[i].checked
445				)
446				{
447					continue;
448				}
449
450				if (!BX.Type.isStringFilled(nodeList[i].value))
451				{
452					continue;
453				}
454
455				if (fieldStack[field].FIELD.MULTIPLE === 'Y')
456				{
457					value.push(nodeList[i].value);
458				}
459				else
460				{
461					value = nodeList[i].value;
462					break;
463				}
464			}
465		}
466
467		return value;
468	};
469
470	BX.Main.UF.BaseType.prototype.focus = function (field)
471	{
472		var node = this.getNode(field),
473			fieldName = field + (
474				fieldStack[field].FIELD.MULTIPLE === 'Y'
475					? '[]'
476					: ''
477			);
478
479		if (!BX.isNodeInDom(node))
480		{
481			console.error('Node for field ' + field + ' is already removed from DOM');
482		}
483		var nodeList = this.findInput(node, fieldName);
484
485		if (nodeList.length > 0)
486		{
487			BX.focus(nodeList[0]);
488		}
489	};
490
491	BX.Main.UF.BaseType.prototype.getNode = function (field)
492	{
493		return fieldStack[field].NODE;
494	};
495
496	/**
497	 * Integer type handler class. Will be initialized in Factory.
498	 *
499	 * @constructor
500	 */
501	BX.Main.UF.TypeBoolean = function ()
502	{
503	};
504	BX.extend(BX.Main.UF.TypeBoolean, BX.Main.UF.BaseType);
505
506	BX.Main.UF.TypeBoolean.USER_TYPE_ID = 'boolean';
507
508	BX.Main.UF.TypeBoolean.prototype.isEmpty = function (field)
509	{
510		return false;
511	};
512
513	/**
514	 * Integer type handler class. Will be initialized in Factory.
515	 *
516	 * @constructor
517	 */
518	BX.Main.UF.TypeInteger = function ()
519	{
520	};
521	BX.extend(BX.Main.UF.TypeInteger, BX.Main.UF.BaseType);
522
523	BX.Main.UF.TypeInteger.USER_TYPE_ID = 'integer';
524
525	/**
526	 * Double type handler class. Will be initialized in Factory.
527	 *
528	 * @constructor
529	 */
530	BX.Main.UF.TypeDouble = function ()
531	{
532	};
533	BX.extend(BX.Main.UF.TypeDouble, BX.Main.UF.BaseType);
534
535	BX.Main.UF.TypeDouble.USER_TYPE_ID = 'double';
536
537	/**
538	 * String type handler class. Will be initialized in Factory.
539	 *
540	 * @constructor
541	 */
542	BX.Main.UF.TypeSting = function ()
543	{
544	};
545	BX.extend(BX.Main.UF.TypeSting, BX.Main.UF.BaseType);
546
547	BX.Main.UF.TypeSting.USER_TYPE_ID = 'string';
548
549	/**
550	 * URL type handler class. Will be initialized in Factory.
551	 *
552	 * @constructor
553	 */
554	BX.Main.UF.TypeUrl = function ()
555	{
556	};
557	BX.extend(BX.Main.UF.TypeUrl, BX.Main.UF.BaseType);
558
559	BX.Main.UF.TypeUrl.USER_TYPE_ID = 'url';
560
561	/**
562	 * Formatted string type handler class. Will be initialized in Factory.
563	 *
564	 * @constructor
565	 */
566	BX.Main.UF.TypeStingFormatted = function ()
567	{
568	};
569	BX.extend(BX.Main.UF.TypeStingFormatted, BX.Main.UF.TypeSting);
570
571	BX.Main.UF.TypeStingFormatted.USER_TYPE_ID = 'string_formatted';
572
573
574	/**
575	 * Enumeration type handler class. Will be initialized in Factory.
576	 *
577	 * @constructor
578	 */
579	BX.Main.UF.TypeEnumeration = function ()
580	{
581	};
582	BX.extend(BX.Main.UF.TypeEnumeration, BX.Main.UF.BaseType);
583
584	BX.Main.UF.TypeEnumeration.USER_TYPE_ID = 'enumeration';
585
586	BX.Main.UF.TypeEnumeration.prototype.findInput = function (node, fieldName)
587	{
588		var inputList = BX.Main.UF.TypeEnumeration.superclass.findInput.apply(this, arguments);
589
590		if (inputList.length > 0)
591		{
592			for (var i = 0; i < inputList.length; i++)
593			{
594				if (inputList[i].tagName === 'INPUT' && inputList[i].type === 'hidden' && inputList.length > 1)
595				{
596					delete inputList[i];
597					break;
598				}
599			}
600		}
601
602		return BX.util.array_values(inputList);
603	};
604
605	BX.Main.UF.TypeEnumeration.prototype.focus = function (field)
606	{
607		if (fieldStack[field]
608			&& fieldStack[field].FIELD.SETTINGS.DISPLAY === 'UI'
609			&& BX.type.isElementNode(fieldStack[field].NODE)
610		)
611		{
612			BX.fireEvent(fieldStack[field].NODE, 'focus');
613		}
614		else
615		{
616			BX.Main.UF.TypeEnumeration.superclass.focus.apply(this, arguments);
617		}
618	};
619
620	/**
621	 * Date type handler class. Will be initialized in Factory.
622	 *
623	 * @constructor
624	 */
625	BX.Main.UF.TypeDate = function ()
626	{
627	};
628	BX.extend(BX.Main.UF.TypeDate, BX.Main.UF.BaseType);
629
630	BX.Main.UF.TypeDate.USER_TYPE_ID = 'date';
631
632	BX.Main.UF.TypeDate.prototype.focus = function (field)
633	{
634		var fieldName = field + (
635			fieldStack[field].FIELD.MULTIPLE === 'Y'
636				? '[]'
637				: ''
638		);
639		var inputList = this.findInput(this.getNode(field), fieldName);
640
641		if (inputList.length > 0)
642		{
643			BX.fireEvent(inputList[0], 'click');
644		}
645
646		BX.Main.UF.TypeDate.superclass.focus.apply(this, arguments);
647	};
648
649	/**
650	 * Datetime type handler class. Will be initialized in Factory.
651	 *
652	 * @constructor
653	 */
654	BX.Main.UF.TypeDateTime = function ()
655	{
656	};
657	BX.extend(BX.Main.UF.TypeDateTime, BX.Main.UF.TypeDate);
658
659	BX.Main.UF.TypeDateTime.USER_TYPE_ID = 'datetime';
660
661	/**
662	 * Datetime type handler class. Will be initialized in Factory.
663	 *
664	 * @constructor
665	 */
666	BX.Main.UF.TypeFile = function ()
667	{
668	};
669	BX.extend(BX.Main.UF.TypeFile, BX.Main.UF.BaseType);
670
671	BX.Main.UF.TypeFile.USER_TYPE_ID = 'file';
672
673	BX.Main.UF.TypeFile.prototype.findInput = function (node, fieldName)
674	{
675		var inputList = BX.Main.UF.TypeFile.superclass.findInput.apply(this, arguments);
676
677		if (inputList.length <= 0)
678		{
679			inputList = BX.findChildren(node, {
680				tagName: /INPUT/i,
681				attribute: {
682					type: 'file',
683					name: /^bxu_files/
684				}
685			}, true);
686		}
687
688		return inputList;
689	};
690
691	BX.Main.UF.TypeFile.prototype.getValue = function (field)
692	{
693		var
694			baseValue = BX.Main.UF.TypeFile.superclass.getValue.apply(this, arguments),
695			node = fieldStack[field].NODE,
696			deletedNodeList = [],
697			i;
698
699		if (fieldStack[field].FIELD.MULTIPLE === 'Y')
700		{
701			var deletedFieldName = field + '_del[]';
702
703			if (BX.type.isArray(baseValue) && baseValue.length > 0)
704			{
705				deletedNodeList = BX.Main.UF.TypeFile.superclass.findInput.apply(this, [node, deletedFieldName]);
706
707				for (i = 0; i < deletedNodeList.length; i++)
708				{
709					var pos = BX.util.array_search(deletedNodeList[i].value, baseValue);
710					if (pos >= 0)
711					{
712						baseValue[pos] = {'old_id': deletedNodeList[i].value, 'del': 'Y', 'tmp_name': ''};
713					}
714				}
715			}
716
717			return BX.util.array_values(baseValue);
718		}
719
720		if (baseValue > 0)
721		{
722			var deletedFieldName = field + '_del';
723
724			deletedNodeList = BX.Main.UF.TypeFile.superclass.findInput.apply(this, [node, deletedFieldName]);
725
726			for (i = 0; i < deletedNodeList.length; i++)
727			{
728				if (baseValue == deletedNodeList[i].value)
729				{
730					baseValue = {'old_id': baseValue, 'del': 'Y', 'tmp_name': ''};
731					break;
732				}
733			}
734
735			return baseValue;
736		}
737
738		return null;
739	};
740
741
742	/**
743	 * Type handler Factory singleton. Will be initialized below.
744	 *
745	 * @constructor
746	 */
747	BX.Main.UF.Factory = function ()
748	{
749		this.defaultTypeHandler = BX.Main.UF.BaseType;
750
751		this.typeHandlerList = {};
752		this.objectCollection = {};
753	};
754
755	BX.Main.UF.Factory.prototype.setTypeHandler = function (type, handlerClass)
756	{
757		this.typeHandlerList[type] = handlerClass;
758		if (typeof this.objectCollection[type] !== 'undefined')
759		{
760			delete this.objectCollection[type];
761		}
762	};
763
764	BX.Main.UF.Factory.prototype.get = function (type)
765	{
766		if (typeof this.objectCollection[type] === 'undefined')
767		{
768			this.objectCollection[type] = this.getObject(type);
769		}
770
771		return this.objectCollection[type];
772	};
773
774	BX.Main.UF.Factory.prototype.getObject = function (type)
775	{
776		return new (this.typeHandlerList[type] || this.defaultTypeHandler);
777	};
778
779	BX.Main.UF.Factory.prototype.getFieldObject = function (field)
780	{
781		if (typeof fieldStack[field] === 'undefined')
782		{
783			console.error('Field ' + field + 'is not registered. Use BX.Main.UF.Factory.registerField to register');
784
785			return null;
786		}
787
788		return this.get(fieldStack[field]['FIELD']['USER_TYPE_ID']);
789	};
790
791	BX.Main.UF.Factory.prototype.isEmpty = function (field)
792	{
793		if (typeof fieldStack[field] === 'undefined')
794		{
795			console.error('Field ' + field + 'is not registered. Use BX.Main.UF.Factory.registerField to register');
796
797			return true;
798		}
799
800		return this.get(fieldStack[field]['FIELD']['USER_TYPE_ID']).isEmpty(field);
801	};
802
803	BX.Main.UF.Factory.prototype.getValue = function (field)
804	{
805		if (typeof fieldStack[field] === 'undefined')
806		{
807			console.error('Field ' + field + 'is not registered. Use BX.Main.UF.Factory.registerField to register');
808
809			return null;
810		}
811
812		return this.get(fieldStack[field]['FIELD']['USER_TYPE_ID']).getValue(field);
813	};
814
815	BX.Main.UF.Factory.prototype.focus = function (field)
816	{
817		if (typeof fieldStack[field] === 'undefined')
818		{
819			console.error('Field ' + field + 'is not registered. Use BX.Main.UF.Factory.registerField to register');
820		}
821
822		return this.get(fieldStack[field]['FIELD']['USER_TYPE_ID']).focus(field);
823	};
824
825	/**
826	 * Singletons initialization
827	 */
828
829	BX.Main.UF.EditManager = new BX.Main.UF.EditManager();
830	BX.Main.UF.ViewManager = new BX.Main.UF.ViewManager();
831	BX.Main.UF.Factory = new BX.Main.UF.Factory();
832
833	BX.Main.UF.Factory.setTypeHandler(BX.Main.UF.TypeBoolean.USER_TYPE_ID, BX.Main.UF.TypeBoolean);
834	BX.Main.UF.Factory.setTypeHandler(BX.Main.UF.TypeInteger.USER_TYPE_ID, BX.Main.UF.TypeInteger);
835	BX.Main.UF.Factory.setTypeHandler(BX.Main.UF.TypeDouble.USER_TYPE_ID, BX.Main.UF.TypeDouble);
836	BX.Main.UF.Factory.setTypeHandler(BX.Main.UF.TypeSting.USER_TYPE_ID, BX.Main.UF.TypeSting);
837	BX.Main.UF.Factory.setTypeHandler(BX.Main.UF.TypeStingFormatted.USER_TYPE_ID, BX.Main.UF.TypeStingFormatted);
838	BX.Main.UF.Factory.setTypeHandler(BX.Main.UF.TypeEnumeration.USER_TYPE_ID, BX.Main.UF.TypeEnumeration);
839	BX.Main.UF.Factory.setTypeHandler(BX.Main.UF.TypeFile.USER_TYPE_ID, BX.Main.UF.TypeFile);
840	BX.Main.UF.Factory.setTypeHandler(BX.Main.UF.TypeDate.USER_TYPE_ID, BX.Main.UF.TypeDate);
841	BX.Main.UF.Factory.setTypeHandler(BX.Main.UF.TypeDateTime.USER_TYPE_ID, BX.Main.UF.TypeDateTime);
842})();
843

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.