PageSourceSearch

https://camping-bertahof.at/wp-content/plugins/calculated-fields-form/js/cache/all.js?ver=5.5.1.6

js camping-bertahof.at collected 2026-10-08 05:20:38 UTC 512,940 bytes, 12,426 lines download raw bytes

1fbuilderjQuery = (typeof fbuilderjQuery != 'undefined' ) ? fbuilderjQuery : jQuery;
2fbuilderjQuery(window).on( 'pageshow', function( event ){ if( typeof event.originalEvent[ 'persisted' ] != 'undefined' && event.originalEvent[ 'persisted' ] ) setTimeout(function(){location.reload();}, 0); } );
3fbuilderjQuery.fbuilderjQueryGenerator = function(){
4	(function($) {
5		// Namespace of fbuilder
6		if(!('fbuilder' in $))
7		{
8			$.fbuilder = $.fbuilder || {};
9			$.fbuilder[ 'objName' ] = 'fbuilderjQuery';
10
11/*
12* logical.js v0.1
13* By: CALCULATED FIELD PROGRAMMERS
14* The script allows make logical operations like functions
15* Copyright 2013 CODEPEOPLE
16* You may use this project under MIT or GPL licenses.
17*/
18
19;(function(root){
20	var lib = {};
21
22	lib.cf_logical_version = '0.1';
23
24	// IF( logical_test, value_if_true, value_if_false )
25	lib.IF = function( condition, if_true, if_false ){
26			if ( condition ) {
27				return ( typeof if_true === 'undefined' ) ? true : if_true;
28			} else {
29				return ( typeof if_false === 'undefined' ) ? false : if_false;
30			}
31		};
32
33	// AND( logical1, logical2, ... )
34	lib.AND = function(){
35			    for (var i = 0, h = arguments.length; i < h; i++) {
36					if (!arguments[i]) {
37						return false;
38					}
39				}
40				return true;
41		};
42
43	// OR( logical1, logical2, ... )
44	lib.OR = function(){
45			    for (var i = 0, h = arguments.length; i < h; i++) {
46					if ( arguments[i] ) {
47						return true;
48					}
49				}
50				return false;
51		};
52
53	// NOT( term )
54	lib.NOT = function( _term ){
55			    return ( typeof _term == 'undefined' ) ? true : !_term;
56		};
57
58	// IN( term, values ) values can be a string or an array
59	lib.IN = function( _term, _values, _case_sensitive ){
60				function _reduce( str ){
61                    var str = String(str).replace( /^\s+/, '').replace(/\s+$/, '').replace(/\s+/, ' ');
62                    if(typeof _case_sensitive == 'undefined' || !_case_sensitive) str = str.toLowerCase()
63					return str;
64				};
65
66				_term = _reduce( _term );
67				if( typeof _values == 'string' )
68                {
69                    if($.fbuilder.isNumeric(_term) && $.fbuilder.isNumeric(_values)) return _term == _values;
70                    return _reduce(_values).indexOf(_term) != -1;
71                }
72				else if( typeof _values == 'object' && _values.length ){
73					for( var i = 0, h = _values.length; i < h; i++) if( _reduce( _values[ i ] ) == _term ) return true;
74				}
75				return false;
76		};
77
78	if(window.CFFCOUNTIF == undefined){
79		window['CFFCOUNTIF'] = window['cffcountif'] = function(){
80			var r = 0, l = arguments.length, t, callback;
81			if(l) {
82				if(typeof arguments[l-1] == 'function') {
83					callback = arguments[l-1];
84				} else {
85					callback = (function(last_item){
86						return function(x){
87							return x == last_item;
88						};
89					})(arguments[l-1]);
90				}
91				l -= 1;
92
93				for(var i=0; i < l; i++)
94				{
95					if(Array.isArray(arguments[i]))
96						r += CFFCOUNTIF.apply(this,arguments[i].concat(callback));
97					else if(jQuery.isPlainObject(arguments[i]))
98						r += CFFCOUNTIF.apply(this,Object.values(arguments[i]).concat(callback));
99					else
100						r += callback(arguments[i]) ? 1 : 0;
101				}
102			}
103			return r;
104		};
105	}
106
107	if(window.CFFFILTER == undefined){
108		window['CFFFILTER'] = window['cfffilter'] = function(){
109			var r = [], l = arguments.length, t, callback = function(){return true;};
110			if(l) {
111
112				if(typeof arguments[l-1] == 'function') {
113					callback = arguments[l-1];
114					l -= 1;
115				}
116
117				for(var i=0; i < l; i++)
118				{
119					if(Array.isArray(arguments[i]))
120						r = r.concat(CFFFILTER.apply(this,arguments[i].concat(callback)));
121					else if(jQuery.isPlainObject(arguments[i]))
122						r = r.concat(CFFFILTER.apply(this,Object.values(arguments[i]).concat(callback)));
123					else if(callback(arguments[i]))
124						r.push(arguments[i]);
125				}
126			}
127			return r;
128		};
129	}
130
131	root.CF_LOGICAL = lib;
132
133})(this);fbuilderjQuery = ( typeof fbuilderjQuery != 'undefined' ) ? fbuilderjQuery : jQuery;
134fbuilderjQuery[ 'fbuilder' ] = fbuilderjQuery[ 'fbuilder' ] || {};
135fbuilderjQuery[ 'fbuilder' ][ 'modules' ] = fbuilderjQuery[ 'fbuilder' ][ 'modules' ] || {};
136
137fbuilderjQuery[ 'fbuilder' ][ 'modules' ][ 'default' ] = {
138	'prefix' : '',
139	'callback'		: function()
140	{
141		var math_prop = ["LN10", "PI", "E", "LOG10E", "SQRT2", "LOG2E", "SQRT1_2", "LN2", "cos", "pow", "log", "tan", "sqrt", "asin", "abs", "exp", "atan2", "atanh", "random", "acos", "atan", "sin"];
142
143		for(var i = 0, h = math_prop.length; i < h; i++)
144		{
145			if( !window[ math_prop[ i ] ] )
146			{
147				if( 'random' != math_prop[ i ] ) {
148					window[ math_prop[ i ] ] = window[ math_prop[ i ].toUpperCase() ] = Math[ math_prop[ i ] ];
149				} else {
150					window[ math_prop[ i ] ] = window[ math_prop[ i ].toUpperCase() ] = function( args ) {
151						args = args || {};
152						let _n = Math.random(),
153							_min = 'min' in args ? Math.max( args['min'], 0 ) : 0,
154							_max = 'max' in args ? Math.min( args['max'], Number.MAX_SAFE_INTEGER ) : ( _min ? Number.MAX_SAFE_INTEGER : 1 ),
155							_int = 'int' in args && args['int'] ? 1 : 0,
156							_tmp;
157
158						if ( _int ) {
159							_min = Math.ceil( _min );
160							_max = Math.floor( _max );
161						}
162
163						_tmp = Math.min( _min, _max );
164						_max = Math.max( _min, _max );
165						_min = _tmp;
166
167
168						if ( _int ) {
169							_n = _n  * ( _max - _min + 1 ) + _min;
170							_n = Math.floor( _n );
171						} else {
172							_n = _n  * ( _max - _min ) + _min;
173						}
174
175						return _n;
176					};
177				}
178			}
179		}
180
181		if(Number.prototype.LENGTH == undefined)
182		{
183			// Only LENGTH in uppercase to prevent a conflict with Lottie
184			Number.prototype.LENGTH = function(){return this.valueOf().toString().length;};
185		}
186
187		if(window.REMAINDER == undefined)
188		{
189			window.REMAINDER = window.remainder = function(a, b){return a%b;};
190		}
191
192		function ROUNDx(operation, num, y)
193		{
194			if(y && y != 0)
195			{
196				var r  = operation(num/y)*y, p = (new String(y)).split('.');
197				if(p.length == 2) r = PREC(r,p[1].length);
198				return r;
199			}
200			else
201			{
202				return operation(num);
203			}
204		};
205
206		if(window.ROUND == undefined)
207		{
208			window.ROUND = window.round = function(num, y)
209			{
210				if(y) return ROUNDx(Math.round, num, y);
211				return ROUNDx(Math.round, num);
212			}
213		}
214
215		if(window.FLOOR == undefined)
216		{
217			window.FLOOR = window.floor = function(num, y)
218			{
219				if(y) return ROUNDx(Math.floor, num, y);
220				return ROUNDx(Math.floor, num);
221			}
222		}
223
224		if(window.CEIL == undefined)
225		{
226			window.CEIL = window.ceil = function(num, y)
227			{
228				if(y) return ROUNDx(Math.ceil, num, y);
229				return ROUNDx(Math.ceil, num);
230			}
231		}
232
233		if(window.PREC == undefined)
234		{
235			window.PREC = window.prec = function (num, pr, if_not_integer)
236				{
237                    pr = pr || 0;
238                    if_not_integer = if_not_integer || 0;
239
240					if(/^\d+$/.test(pr) && $.fbuilder.isNumeric(num))
241					{
242                        if(
243                            Math.floor(num) != num ||
244                            !if_not_integer
245                        )
246                        {
247                            var f = Math.pow(10,pr);
248                            num = Math.round(num*f)/f;
249                            return (Math.floor(num) == num && if_not_integer) ? num : num.toFixed(pr);
250                        }
251					}
252					return num;
253				};
254		} // End if window.PREC
255
256		if(window.TOBASE == undefined)
257		{
258			window.TOBASE = window.tobase = window.toBase = window.ToBase = function ( num, _from, _to )
259			{
260				_from = _from || 10;
261				_to   = _to || 10;
262
263				if( _from != _to) {
264					try {
265						var _decimal = parseInt(num, _from);
266						return _decimal.toString(_to);
267					} catch(err){}
268				}
269				 return num;
270			};
271		} // End window.TOBASE
272
273		if(window.CDATE == undefined)
274		{
275			window.CDATE = window.cdate = function ( num, format )
276				{
277					format = ( typeof format != 'undefined' ) ? format : ( ( typeof window.DATETIMEFORMAT != 'undefined' ) ? window.DATETIMEFORMAT : 'dd/mm/yyyy' );
278
279					if(isFinite(num*1))
280					{
281						var time_only = (Math.abs(num)<1);
282						num = Math.round(num*86400000);
283						if(time_only) num += (new Date(2021,01,01,0,0,0,0)).valueOf();
284						var date = new Date(num),
285							d = (time_only) ? 0 : date.getDate(),
286							m = (time_only) ? 0 : date.getMonth()+1,
287							y = (time_only) ? 0 : date.getFullYear(),
288							h = date.getHours(),
289							i = date.getMinutes(),
290							s = date.getSeconds(),
291							a = '';
292						m = (m < 10) ? '0'+m : m;
293						d = (d < 10) ? '0'+d : d;
294
295						if( /a/.test( format ) )
296						{
297							a = ( h >= 12 ) ? 'pm' : 'am';
298							h = h % 12;
299							h = ( h == 0 ) ? 12: h;
300						}
301						h = (h < 10) ? '0'+h : h;
302						i = (i < 10) ? '0'+i : i;
303						s = (s < 10) ? '0'+s : s;
304
305						return format.replace( /\by{2}\b/i, y < 10 ? '0'+y : y%100)
306                                     .replace( /y+/i, y < 10 ? '000'+y : ((y < 100) ? '00'+y : y))
307									 .replace( /m+/i, m)
308									 .replace( /d+/i, d)
309									 .replace( /h+/i, h)
310									 .replace( /i+/i, i)
311									 .replace( /s+/i, s)
312									 .replace( /a+/i, a);
313					}
314					return num;
315				};
316		} // End if window.CDATE
317
318		if(window.SUM == undefined)
319		{
320			window.SUM = window.sum = function ()
321			{
322				var r = 0, l = arguments.length, t, callback = function(x){return x;}, callback_flag = false;
323				if(l) {
324					if(typeof arguments[l-1] == 'function') {
325						callback_flag = true;
326						callback = arguments[l-1];
327						l -= 1;
328					}
329					for(var i=0; i < l; i++)
330					{
331						if(Array.isArray(arguments[i]))
332							r += SUM.apply(this,arguments[i].concat(callback));
333						else if(jQuery.isPlainObject(arguments[i]) && ! callback_flag) {
334							r += SUM.apply(this,Object.values(arguments[i]).concat(callback));
335						}
336						else
337						{
338							t = arguments[i];
339							t = callback(t)*1;
340							if(!isNaN(t))
341							{
342								r += t;
343							}
344
345						}
346					}
347				}
348				return r;
349			};
350		} // End if window.SUM
351
352		if (window.SUMIF  == undefined)
353		{
354			window.SUMIF = window.sumif = function ()
355			{
356				var filtered = [];
357				function aux (v, callback) {
358					if( Array.isArray(v) ) {
359						for(let i in v) {
360							aux(v[i], callback);
361						}
362					} else {
363						try {
364							if ( callback(v) ) {
365								filtered.push(v);
366							}
367						} catch( err ) { console.log( 'SUMIF: ' + err ); }
368					}
369				};
370
371				var r = 0, l = arguments.length;
372				if(l) {
373					if(typeof arguments[l-1] == 'function') {
374						let callback = arguments[l-1];
375						const args = Array.prototype.slice.call(arguments, 0, -1);
376						aux(args, callback);
377						r = SUM.apply(this, filtered);
378					} else {
379						r = SUM.apply(this, arguments);
380					}
381				}
382				return r;
383			};
384		} // End if window.SUMIF
385
386		if(window.SIGMA == undefined)
387		{
388			window.SIGMA = window.sigma = function ()
389			{
390				var r = 0,
391					l = arguments.length,
392					n,m,callback,t;
393				if(l == 3) {
394
395					n = parseInt(arguments[0]);
396					m = parseInt(arguments[1]);
397					callback = arguments[2];
398
399					if(
400						!isNaN(n) &&
401						!isNaN(m) &&
402						typeof callback == 'function'
403					) {
404
405						for(var i=n; i<=m; i++) {
406							t = callback(i);
407							if(!isNaN(t)) r += t;
408						}
409					}
410				}
411				return r;
412			};
413		} // End if window.SIGMA
414
415		if(window.CONCATENATE == undefined)
416		{
417			window.CONCATENATE = window.concatenate = function ()
418			{
419				var r = '';
420				for(var i in arguments)
421				{
422					if(Array.isArray(arguments[i]))
423						r += CONCATENATE.apply(this,arguments[i]);
424					else if(jQuery.isPlainObject(arguments[i]))
425						r += CONCATENATE.apply(this,Object.values(arguments[i]));
426					else r += (new String(arguments[i]));
427				}
428				return r;
429			};
430		} // End if window.CONCATENATE
431
432		if(window.AVERAGE == undefined)
433		{
434			window.AVERAGE = window.average = function ()
435			{
436                var _c = 0;
437                function c(v)
438                {
439                    if(Array.isArray(v) && v.length) for(var i in v) c(v[i]);
440                    else _c++;
441                }
442                for(var i in arguments) c(arguments[i]);
443                return SUM.apply(this,arguments)/_c;
444			};
445		} // End if window.AVERAGE
446
447		if(window.GCD == undefined)
448		{
449			window.GCD = window.gcd = function( a, b)
450				{
451					if ( ! b) return a;
452					return GCD(b, a % b);
453				};
454		} // End if window.GCD
455
456		if(window.LCM == undefined)
457		{
458			window.LCM = window.lcm = function( a, b)
459				{
460					return (!a || !b) ? 0 : ABS((a * b) / GCD(a, b));
461				};
462		} // End if window.LCM
463
464		if(window.LOGAB == undefined)
465		{
466			window.LOGAB = window.logab = function( a, b)
467				{
468					return LOG(a)/LOG(b);
469				};
470		} // End if window.LOGAB
471
472		if(window.NTHROOT == undefined)
473		{
474			window.NTHROOT = window.nthroot = function(a,b)
475				{
476                    var n = (a<0 && b%2 == 1) ? -1 : 1;
477					return n*POW(Math.abs(a), 1/b);
478				};
479		} // End if window.NTHROOT
480
481		if(window.MIN == undefined)
482		{
483			window.MIN = window.min = function ()
484			{
485				var l = [];
486				for(var i in arguments)
487					var l = l.concat(arguments[i]);
488				return Math.min.apply(this, l);
489			};
490		} // End if window.MIN
491
492		if(window.MAX == undefined)
493		{
494			window.MAX = window.max = function ()
495			{
496				var l = [];
497				for(var i in arguments)
498					var l = l.concat(arguments[i]);
499				return Math.max.apply(this, l);
500			};
501		} // End if window.MAX
502
503		if(window.RADIANS == undefined)
504		{
505			window.RADIANS = window.radians = function(a){ return a*PI/180;};
506		}
507
508		if(window.DEGREES == undefined)
509		{
510			window.DEGREES = window.degrees = function(a){ return a*180/PI;};
511		}
512
513		if(window.FACTORIAL == undefined)
514		{
515			window.FACTORIAL = window.factorial = function(a){
516				if(a<0 || FLOOR(a) != a) return null;
517				var r = 1;
518				for(var i=1; i<=a; i++) r *= i
519				return r;
520			};
521		}
522
523		if(window.ISFRACTION == undefined)
524		{
525			window.ISFRACTION = window.isfraction = window.isFraction = function(v){
526                try
527                {
528                    var x = v.toString().split('/');
529					return 	x.length == 2 &&
530							! isNaN(x[0]*1) &&
531							Math.floor(x[0]*1) == x[0]*1 &&
532							! isNaN(x[1]*1) &&
533							Math.floor(x[1]*1) == x[1]*1;
534                }catch(err){return false;}
535            };
536		}
537
538		if(window.FRACTIONTODECIMAL == undefined)
539        {
540            window.FRACTIONTODECIMAL = window.fractiontodecimal = window.fractionToDecimal = function(v){
541                try
542                {
543                    var x = v.toString().split('/');
544                    return parseInt(x[0], 10)/((1 in x) ? parseInt(x[1], 10) : 1);
545                }catch(err){return v;}
546            };
547        }
548
549		if(window.DECIMALTOFRACTION == undefined)
550        {
551            window.DECIMALTOFRACTION = window.decimaltofraction = window.decimalToFraction = function(v){
552                try
553                {
554                    if(v*1 == parseInt(v, 10)) return parseInt(v, 10);
555                    var x = v.toString().split('.'),
556                        top = parseInt(x[0]+''+x[1]),
557                        bottom = Math.pow(10, x[1].length),
558                        y = gcd(Math.abs(top), bottom);
559
560                    return (top/y) + '/' + (bottom/y);
561                }catch(err){return v;}
562            };
563        }
564
565        if(window.SIMPLIFYFRACTION == undefined)
566        {
567            window.SIMPLIFYFRACTION = window.simplifyfraction = window.simplifyFraction = function(v, v2){
568                try
569                {
570					let n, d;
571
572                    if ( ISFRACTION(v) ) {
573						let o = v.split('/');
574						n = o[0]*1,
575						d = o[1]*1;
576					} else if( typeof v2 != 'undefined' ) {
577						n = v*1;
578						d = v2*1;
579					}
580
581					if(isNaN(n) || isNaN(d) || d === 0) return v;
582					if(n === 0) return '0/1';
583
584					let f  = GCD(n, d),
585						sN = n / f,
586						sD = d / f,
587						r  = sN/sD;
588
589					return Math.floor(r) === r ? r : `${sN}/${sD}`;
590
591				} catch(err){}
592				return v;
593           };
594        }
595
596		if(window.FRACTIONSUM == undefined)
597        {
598            window.FRACTIONSUM = window.fractionsum = function(){
599                try
600                {
601                    var _aux = function(a, b){
602                        var d1, d2, m, r;
603
604                        a = (a+'/1').split('/');
605                        b = (b+'/1').split('/');
606
607                        d1 = a[0]*b[1]+a[1]*b[0];
608                        d2 = a[1]*b[1];
609
610                        if(isNaN(d1) || isNaN(d2)) throw 'Invalid numbers';
611
612                        m = abs(gcd(d1,d2));
613                        r = d1/m + IF(d2/m == 1, '', '/'+d2/m);
614                        return jQuery.isNumeric(r) ? r*1 : r;
615                    };
616                    var r = 0;
617                    for(var i in arguments) r = _aux(r,arguments[i]);
618                    return r;
619                } catch(err){}
620           };
621        }
622
623		if(window.FRACTIONSUB == undefined)
624        {
625            window.FRACTIONSUB = window.fractionsub = function(){
626                try
627                {
628                    var _aux = function(a, b){
629                        var d1, d2, m, r;
630
631                        a = (a+'/1').split('/');
632                        b = (b+'/1').split('/');
633
634                        d1 = a[0]*b[1]-a[1]*b[0];
635                        d2 = a[1]*b[1];
636
637                        if(isNaN(d1) || isNaN(d2)) throw 'Invalid numbers';
638
639                        m = abs(gcd(d1,d2));
640                        r = d1/m + IF(d2/m == 1, '', '/'+d2/m);
641                        return jQuery.isNumeric(r) ? r*1 : r;
642                    };
643                    var r = 0;
644                    for(var i in arguments)
645                    {
646                        if(i == 0) r = _aux(arguments[i], r);
647                        else  r = _aux(r,arguments[i]);
648                    }
649                    return r;
650                } catch(err){}
651            };
652        }
653
654		if(window.FRACTIONMULT == undefined)
655        {
656            window.FRACTIONMULT = window.fractionmult = function(){
657                try
658                {
659                    var _aux = function(a, b){
660                        var d1, d2, m, r;
661
662                        a = (a+'/1').split('/');
663                        b = (b+'/1').split('/');
664
665                        d1 = a[0]*b[0];
666                        d2 = a[1]*b[1];
667
668                        if(isNaN(d1) || isNaN(d2)) throw 'Invalid numbers';
669
670                        m = abs(gcd(d1,d2));
671                        r = d1/m + IF(d2/m == 1, '', '/'+d2/m);
672                        return jQuery.isNumeric(r) ? r*1 : r;
673                    };
674                    var r = 1;
675                    for(var i in arguments) r = _aux(r,arguments[i]);
676                    return r;
677                } catch(err){}
678            };
679        }
680
681		if(window.FRACTIONDIV == undefined)
682        {
683            window.FRACTIONDIV = window.fractiondiv = function(){
684                try
685                {
686                    var _aux = function(a, b){
687                        var d1, d2, m, r;
688
689                        a = (a+'/1').split('/');
690                        b = (b+'/1').split('/');
691
692                        d1 = a[0]*b[1];
693                        d2 = a[1]*b[0];
694
695                        if(isNaN(d1) || isNaN(d2)) throw 'Invalid numbers';
696
697                        m = abs(gcd(d1,d2));
698                        r = d1/m + IF(d2/m == 1, '', '/'+d2/m);
699                        return jQuery.isNumeric(r) ? r*1 : r;
700                    };
701                    var r = 1;
702                    for(var i in arguments)
703                    {
704                        if(i == 0) r = _aux(arguments[i], r);
705                        else  r = _aux(r,arguments[i]);
706                    }
707                    return r;
708                } catch(err){}
709            };
710        }
711
712		if(window.SCIENTIFICTODECIMAL == undefined)
713		{
714			window.SCIENTIFICTODECIMAL = window.scientifictodecimal = function(x){
715				function initialize(c) {
716					e = parseInt( c[1] );
717					n = c[0].split( '.' );
718					i = n[0];
719					d = n[1] || '';
720				};
721				if ( ! isNaN( x*1 ) ) {
722					x *= 1;
723
724					var s = x < 0 ? '-' : '',
725						y, c, e, n, i, d;
726
727					y = Math.abs( x );
728					c = y.toString().split('e-');
729
730					if ( 2 == c.length ) {
731						initialize(c);
732						x = s+'0.'+(new Array(e-i.length+d.length)).join(0)+i+d;
733					} else {
734						c = y.toString().split('e+');
735						if ( 2 == c.length ) {
736							initialize(c);
737							x = s+i+d+(new Array(e+1-d.length)).join(0);
738						}
739					}
740				}
741
742				return x;
743			};
744		}
745
746        if(window.DECIMALTOSCIENTIFIC == undefined)
747        {
748            window.DECIMALTOSCIENTIFIC = window.decimaltoscientific = function(x){
749                var v = Number(x).toExponential();
750                return (isNaN(v) || x == '') ? x : v;
751            };
752        }
753
754		if(window.FORMAT == undefined)
755		{
756			window.FORMAT = window.format = function(x,o){
757				return fbuilderjQuery.fbuilder.calculator.format(x,o);
758			};
759		}
760
761		if(window.UNFORMAT == undefined)
762		{
763			window.UNFORMAT = window.unformat = function(x,o){
764                try
765                {
766                    var s;
767                    try
768                    {
769                        s = (typeof o != 'undefined' && 'decimalsymbol' in o) ? o['decimalsymbol'] : '.';
770                    }catch(err){ s = '.'; }
771
772                    return (x+'').replace(new RegExp('[^\\-\\d\\'+s+']', 'gi'), '')
773                                 .replace(new RegExp('\\'+s, 'gi'), '.')*1;
774                }
775                catch(err){ return x; }
776			};
777		}
778
779		if(window.SINGLEDIGIT == undefined)
780		{
781			window.SINGLEDIGIT = window.singledigit = function(v,callback){
782				let result = v;
783                try
784                {
785					callback = typeof callback == 'function' ? callback : function(d){
786						return SUM(d);
787					};
788
789					v = String(v).split('');
790					do {
791						result = callback(v);
792						v = String(result).split('');
793					} while ( 10 <= result);
794
795				}
796                catch(err){ if ( 'console' in window ) console.log( err ); }
797				return result;
798			};
799		}
800
801		fbuilderjQuery[ 'fbuilder' ][ 'extend_window' ]( fbuilderjQuery[ 'fbuilder' ][ 'modules' ][ 'default' ][ 'prefix' ], CF_LOGICAL );
802	},
803
804	'validator'	: function( v )
805		{
806			return ( typeof v == 'number' ) ? isFinite( v ) : ( typeof v != 'undefined' );
807		}
808};/*
809* health.js v0.1
810* By: CALCULATED FIELD PROGRAMMERS
811* Health related operations
812* Copyright 2025 CODEPEOPLE
813*/
814
815;(function(root){
816	var lib = {};
817
818
819	/*** PRIVATE FUNCTIONS ***/
820	function _cm_in(v){ return v/2.54; }
821	function _in_cm(v){ return v*2.54; }
822
823	function _lb_kg(v){ return v/2.2; }
824	function _kg_lb(v){ return v*2.2; }
825
826	/*** PUBLIC FUNCTIONS ***/
827
828	lib.cf_health_version = '0.1';
829
830	// gender: male/female, height, unit: metric/imperial
831	lib.IDEALWEIGHTCALCULATOR = lib.idealweightcalculator = function( gender, height, unit ){
832		unit  = (unit || 'metric').toLowerCase();
833		height	 = unit == 'imperial' ? _in_cm(height) : height;
834		let output = (height - 100) * (gender.toLowerCase() == 'male' ? 0.9 : 0.85);
835		return unit == 'imperial' ? _kg_lb(output) : output;
836	};
837
838	// height, weight, unit: metric/imperial, as_text: true/false
839	lib.BMICALCULATOR = lib.bmicalculator = function( height, weight, unit, as_text ){
840		unit = (unit || 'metric').toLowerCase();
841		as_text = as_text || false;
842
843		height = (unit == 'imperial' ? _in_cm(height) : height)/100;
844		weight = unit == 'imperial' ? _lb_kg(weight) : weight;
845
846		let bmi = PREC(weight/Math.pow(height,2),2,true);
847
848		if( ! as_text ) return bmi;
849
850		if(bmi < 18.5) return 'Underweight';
851        if(bmi <= 24.9) return 'Normal';
852        if(bmi <= 29.9) return 'Overweight';
853        return 'Obese';
854	};
855
856	// age, gender:male/female, height, weight, unit: metric/imperial, activity: sedentary/light/moderate/active/very/extra
857	lib.BMRCALCULATOR= lib.bmrcalculator = function( age, gender, height, weight, unit ){
858		unit = (unit || 'metric').toLowerCase();
859		height = unit == 'imperial' ? _in_cm(height) : height;
860		weight = unit == 'imperial' ? _lb_kg(weight) : weight;
861
862		return 10*weight + 6.25*height - 5*age + (gender.toLowerCase() == 'male' ? 5 : -161);
863	};
864
865	// age, gender:male/female, height, weight, unit: metric/imperial, activity: sedentary/light/moderate/active/very/extra
866	lib.MAINTENANCECALORIESCALCULATOR = lib.maintenancecaloriescalculator = function( age, gender, height, weight, unit, activity ){
867		unit = (unit || 'metric').toLowerCase();
868		activity = (activity || 'moderate').toLowerCase();
869
870		height = unit == 'imperial' ? _in_cm(height) : height;
871		weight = unit == 'imperial' ? _lb_kg(weight) : weight;
872
873		let factors = {'sedentary': 1.2, 'light': 1.375, 'moderate': 1.465, 'active': 1.55, 'very': 1.725, 'extra': 1.9}
874		let factor = activity in factors ? factors[activity] : 1.465;
875
876
877		let bmr = lib.BMRCALCULATOR(age, gender.toLowerCase(), height, weight, 'metric');
878
879		return Math.round(bmr*factor);
880	};
881
882	// age, gender:male/female, height, weight, unit: metric/imperial, activity: sedentary/light/moderate/active/very/extra,
883	// goal: lose/gain/maintain, details: true/false
884	lib.BYGOALCALORIESCALCULATOR = lib.bygoalcaloriescalculator = function( age, gender, height, weight, unit, activity, goal, details ){
885		unit = (unit || 'metric').toLowerCase();
886		activity = (activity || 'moderate').toLowerCase();
887		goal = (goal || 'maintain').toLowerCase();
888		details = details || false;
889
890		height = unit == 'imperial' ? _in_cm(height) : height;
891		weight = unit == 'imperial' ? _lb_kg(weight) : weight;
892
893
894		let goals = {'lose': -500, 'gain': 500, 'maintain': 0};
895		let goal_factor = goal in goals ? goals[goal] : 0;
896
897		let calories = lib.MAINTENANCECALORIESCALCULATOR(age, gender, height, weight, unit, activity) + goal_factor;
898		if( ! details ) return calories;
899
900		let proteins = weight*2.2;
901		let fat = calories * 0.25 / 9;
902		let carbs = (calories*1 - (proteins * 4 + fat * 9)) / 4;
903
904		return {
905			'calories': calories,
906			'proteins': Math.round(proteins),
907			'fat': Math.round(fat),
908			'carbs': Math.round(carbs)
909		};
910	};
911
912	// age, gender:male/female, weight, unit: kg/lb, activity: sedentary/light/moderate/very/extra,
913	// climate: cold/mild/warm/hot
914	lib.WATERINTAKECALCULATOR = lib.waterintakecalculator = function( age, gender, weight, unit, activity, climate ){
915		unit = (unit || 'kg').toLowerCase();
916		activity = (activity || 'moderate').toLowerCase();
917		weight = unit == 'lb' || unit == 'imperial' ? _lb_kg(weight) : weight;
918		climate = climate || 'mild';
919
920		const activityMultipliers = {'sedentary': 1.0,'light': 1.2,'moderate': 1.4,'very': 1.6,'extra': 1.8};
921		let activity_factor = activity in activityMultipliers ? activityMultipliers[activity] : 1.4;
922
923		const climateMultipliers = {'cold': 0.9,'mild': 1.0,'warm': 1.15,'hot': 1.3};
924		let climate_factor = climate in climateMultipliers ? climateMultipliers[climate] : 1;
925
926		let baseIntake = weight * 0.033;
927		let ageMultiplier = 1.0;
928		if (age < 18) ageMultiplier = 1.1;
929		else if (age > 65) ageMultiplier = 1.05;
930
931		let genderMultiplier = gender.toLowerCase() === 'male' ? 1.0 : 0.9;
932
933		let waterIntake = baseIntake *
934			ageMultiplier *
935			genderMultiplier *
936			activity_factor *
937			climate_factor;
938
939		waterIntake = Math.max(1.5, waterIntake);
940		waterIntake = Math.min(5.0, waterIntake);
941
942		return PREC(waterIntake, 2, true);
943	};
944
945	// gender:male/female, hip, waist
946	lib.HIPTOWAISTRATIOCALCULATOR = lib.hiptowaistratiocalculator = function( gender, hip, waist ){
947		gender = gender.toLowerCase();
948
949		let ratio = waist / hip;
950		let shape = ratio <= 0.9 ? 'pear' : (ratio <=1 ? 'avocado' : 'apple');
951		let ideal = gender == 'male' ? '0.9-1.0' : '0.7-0.8';
952		let risk;
953
954		if ( 'male' == gender ) {
955			if (ratio <= 0.95) risk = 'Low health risk';
956			else if (ratio <= 1) risk = 'Moderate health risk';
957			else risk = 'High health risk';
958		} else {
959			if (ratio <= 0.8) risk = 'Low health risk';
960			else if (ratio <= 0.84) risk = 'Moderate health risk';
961			else risk = 'High health risk';
962		}
963
964		return {
965			'ratio': PREC(ratio,2,true),
966			'shape': shape,
967			'risk' : risk,
968			'ideal': ideal
969		};
970	};
971
972	root.CF_HEALTH = lib;
973
974})(this);fbuilderjQuery = ( typeof fbuilderjQuery != 'undefined' ) ? fbuilderjQuery : jQuery;
975fbuilderjQuery[ 'fbuilder' ] = fbuilderjQuery[ 'fbuilder' ] || {};
976fbuilderjQuery[ 'fbuilder' ][ 'modules' ] = fbuilderjQuery[ 'fbuilder' ][ 'modules' ] || {};
977
978fbuilderjQuery[ 'fbuilder' ][ 'modules' ][ 'health' ] = {
979	'prefix' : '',
980	'callback' : function()
981		{
982			fbuilderjQuery[ 'fbuilder' ][ 'extend_window' ]( fbuilderjQuery[ 'fbuilder' ][ 'modules' ][ 'health' ][ 'prefix' ], CF_HEALTH );
983		}
984};/*
985* datetime.js v0.1
986* By: CALCULATED FIELD PROGRAMMERS
987* The script allows operations with date and time
988* Copyright 2013 CODEPEOPLE
989* You may use this project under MIT or GPL licenses.
990*/
991
992;(function(root){
993	var lib 		   = {},
994		default_format = ( typeof window.DATETIMEFORMAT != 'undefined' ) ? window.DATETIMEFORMAT : 'yyyy-mm-dd hh:ii:ss a',
995		regExp		   = '';
996
997
998	Date.prototype.valid = function() {
999		 return isFinite(this);
1000	};
1001
1002	/*** PRIVATE FUNCTIONS ***/
1003	function _processArguments( date, format, leading_zeros ){
1004        if(arguments.length == 1 && (typeof date == 'boolean' || date == 0 || date == 1))
1005        {
1006            leading_zeros = date;
1007            date = undefined;
1008            format = undefined;
1009        }
1010		leading_zeros = leading_zeros || 0;
1011		return { date:date, format:format, leading_zeros: leading_zeros };
1012	}
1013
1014	function _leadingZeros( n ) {
1015		return n < 10  ? 0 + '' + n : n;
1016	};
1017
1018	function _getDateObj( date, format ){
1019		if( date == 0 ) return 0;
1020		try{ if ( date instanceof Date ) return date; } catch(err) {}
1021		var d = new Date();
1022
1023		format = format || default_format;
1024		if( typeof date != 'undefined' ){
1025			if( typeof date == 'number' ){
1026				// d = new Date(Math.ceil(date*86400000));
1027				if ( -1 < date && date < 1 ) {
1028					d.setMilliseconds(0);
1029					d.setHours(0);
1030					d.setMinutes(0);
1031					d.setSeconds(0);
1032					date += d.valueOf()/86400000;
1033				}
1034				d = new Date(date*86400000);
1035			}else if( typeof date == 'string' ){
1036				var p;
1037				if( null != ( p = /(\d{4})[\/\-\.](\d{1,2})[\/\-\.](\d{1,2})/.exec( date ) ) ){
1038					if( /y{4}[\/\-\.]m{2}[\/\-\.]d{2}/i.test( format ) ){
1039						d = new Date( p[ 1 ], ( p[ 2 ] - 1 ), p[ 3 ] );
1040					}else{
1041						d = new Date( p[ 1 ], ( p[ 3 ] - 1 ), p[ 2 ] );
1042					}
1043					date = date.replace( p[ 0 ], '' );
1044				}
1045
1046				if( null != ( p = /(\d{1,2})[\/\-\.](\d{1,2})[\/\-\.](\d{4})/.exec( date ) ) ){
1047					if( /d{2}[\/\-\.]m{2}[\/\-\.]y{4}/i.test( format ) ){
1048						d = new Date( p[ 3 ], ( p[ 2 ] - 1 ), p[ 1 ] );
1049					}else{
1050						d = new Date( p[ 3 ], ( p[ 1 ] - 1 ), p[ 2 ] );
1051					}
1052					date = date.replace( p[ 0 ], '' );
1053				}
1054
1055				if( null != ( p = /(\d{1,2})[\/\-\.](\d{1,2})[\/\-\.](\d{2})/.exec( date ) ) ){
1056					if( /d{2}[\/\-\.]m{2}[\/\-\.]y{2}/i.test( format ) ){
1057						d = new Date( 2000+p[ 3 ]*1, ( p[ 2 ] - 1 ), p[ 1 ] );
1058					}else if( /m{2}[\/\-\.]d{2}[\/\-\.]y{2}/i.test( format ) ){
1059						d = new Date( 2000+p[ 3 ]*1, ( p[ 1 ] - 1 ), p[ 2 ] );
1060					}else if( /y{2}[\/\-\.]d{2}[\/\-\.]m{2}/i.test( format ) ){
1061						d = new Date( 2000+p[ 1 ]*1, ( p[ 3 ] - 1 ), p[ 2 ] );
1062					}else if( /y{2}[\/\-\.]m{2}[\/\-\.]d{2}/i.test( format ) ){
1063						d = new Date( 2000+p[ 1 ]*1, ( p[ 2 ] - 1 ), p[ 3 ] );
1064					}
1065					date = date.replace( p[ 0 ], '' );
1066				}
1067
1068				if( null != ( p = /(\d{1,2})[:\.](\d{1,2})([:\.](\d{1,2}))?\s*([ap]m)?/i.exec( date ) ) ){
1069					if(/h+/i.test( format ) ){
1070						if( typeof p[ 5 ] != 'undefined' && /pm/i.test( p[ 5 ] ) && p[ 1 ]*1 != 12 ) p[ 1 ] = ( p[ 1 ]*1 + 12 ) % 24;
1071						if( typeof p[ 5 ] != 'undefined' && /am/i.test( p[ 5 ] ) && p[ 1 ]*1 == 12 ) p[ 1 ] = 0;
1072						d.setHours( p[ 1 ] );
1073					}
1074
1075					if(/i+/i.test( format ) ) d.setMinutes( p[ 2 ] );
1076					if(/s+/i.test( format ) && (typeof p[ 4 ] != 'undefined') ) d.setSeconds( p[ 4 ] );
1077				}
1078			}else{
1079				d = new Date( date );
1080			}
1081
1082			d.setMilliseconds(0);
1083			if( ! /h+/i.test(format)) d.setHours(0);
1084			if( ! /i+/i.test(format)) d.setMinutes(0);
1085			if( ! /s+/i.test(format)) d.setSeconds(0);
1086		}
1087		return d;
1088	};
1089
1090	/*** PUBLIC FUNCTIONS ***/
1091
1092	lib.cf_datetime_version = '0.1';
1093
1094	// DATEOBJ( date_string, date_format_string )
1095	lib.DATEOBJ = function( date, format ){
1096		var d = _getDateObj( date, format );
1097		if( d && d.valid() ) return d;
1098		return false;
1099	};
1100
1101	// If X < 10, returns 0X
1102	lib.LEADINGZERO = function( v ) {
1103		if ( ! isNaN( v ) && 0 <= v ) {
1104			v = _leadingZeros( v );
1105		}
1106		return v;
1107	};
1108
1109	// YEAR( date_string, date_format_string )
1110	lib.YEAR = function( date, format ){
1111		var d = _getDateObj( date, format );
1112		if( d && d.valid() ) return d.getFullYear();
1113		return false;
1114	};
1115
1116	// MONTH( date_string, date_format_string )
1117	lib.MONTH = function( date, format, leading_zeros ){
1118		var tmp = _processArguments.apply( null, arguments );
1119        date 			= tmp[ 'date' ];
1120        format 			= tmp[ 'format' ];
1121        leading_zeros 	= tmp[ 'leading_zeros' ];
1122
1123        var d = _getDateObj( date, format ), r = false;
1124		if( d && d.valid() ){
1125            r = d.getMonth()+1;
1126            if(leading_zeros) r = _leadingZeros( r );
1127        }
1128		return r;
1129	};
1130
1131	lib.MONTHNAME = function( date, format, locale ){
1132		var d = lib.DATEOBJ( date, format ),
1133			r = false;
1134		if ( d ) {
1135			locale = locale || 'default';
1136			try {
1137				r = d.toLocaleString( locale, { month: 'long' } );
1138			} catch( err ) {
1139				r = d.toLocaleString( 'default', { month: 'long' } );
1140			}
1141		}
1142		return r;
1143	};
1144
1145	lib.WEEKDAYNAME = function( date, format, locale ){
1146		var d = lib.DATEOBJ( date, format ),
1147			r = false;
1148		if ( d ) {
1149			locale = locale || 'default';
1150			try {
1151				r = d.toLocaleString( locale, { weekday: 'long' } );
1152			} catch( err ) {
1153				r = d.toLocaleString( 'default', { weekday: 'long' } );
1154			}
1155		}
1156		return r;
1157	};
1158
1159	// DAY( date_string, date_format_string )
1160	lib.DAY = function( date, format, leading_zeros ){
1161		var tmp = _processArguments.apply( null, arguments );
1162        date 			= tmp[ 'date' ];
1163        format 			= tmp[ 'format' ];
1164        leading_zeros 	= tmp[ 'leading_zeros' ];
1165
1166		var d = _getDateObj( date, format ), r = false;
1167		if( d && d.valid() )
1168        {
1169            r = d.getDate();
1170            if( leading_zeros ) r = _leadingZeros( r );
1171        }
1172		return r;
1173	};
1174
1175	// WEEKDAY( date_string, date_format_string )
1176	lib.WEEKDAY = function( date, format, leading_zeros ){
1177        var tmp = _processArguments.apply( null, arguments );
1178        date 			= tmp[ 'date' ];
1179        format 			= tmp[ 'format' ];
1180        leading_zeros 	= tmp[ 'leading_zeros' ];
1181
1182        var d = _getDateObj( date, format ), r = false;
1183		if( d && d.valid() ){
1184            r = d.getDay()+1;
1185            if( leading_zeros ) r = _leadingZeros( r );
1186        }
1187		return r;
1188	};
1189
1190	// WEEKNUM( date_string, date_format_string, leading_zeros )
1191
1192	function _weeknum_base(date, format, leading_zeros, version) {
1193		var d   	= _getDateObj( date, format ), i, n,
1194			r 		= false;
1195
1196		if ( d && d.valid() ) {
1197
1198			i = new Date(d.getFullYear(), 0, 1, 0, 0, 0, 0);
1199			n = ( d - i ) / ( 24 * 60 * 60 * 1000 );
1200			if (version == 1) {
1201				r = Math.max( Math.ceil( (n+1) / 7 ), 1 );
1202			} else {
1203				let w = lib.WEEKDAY(i);
1204				r = Math.max( Math.ceil( (n+w) / 7 ), 1 ) % 52;
1205			}
1206			if ( leading_zeros ) r = _leadingZeros( r );
1207
1208		}
1209		return r;
1210	};
1211
1212	lib.WEEKNUM	= function( date, format, leading_zeros ){
1213		var tmp = _processArguments.apply( null, arguments );
1214        date 			= tmp[ 'date' ];
1215        format 			= tmp[ 'format' ];
1216        leading_zeros 	= tmp[ 'leading_zeros' ];
1217		return _weeknum_base(date, format, leading_zeros, 1);
1218	};
1219
1220	lib.WEEKNUM2	= function( date, format, leading_zeros ){
1221		var tmp = _processArguments.apply( null, arguments );
1222        date 			= tmp[ 'date' ];
1223        format 			= tmp[ 'format' ];
1224        leading_zeros 	= tmp[ 'leading_zeros' ];
1225		return _weeknum_base(date, format, leading_zeros, 2);
1226
1227	};
1228
1229	// HOURS( datetime_string, datetime_format_string )
1230	lib.HOURS = function( date, format, leading_zeros ){
1231		var tmp = _processArguments.apply( null, arguments );
1232        date 			= tmp[ 'date' ];
1233        format 			= tmp[ 'format' ];
1234        leading_zeros 	= tmp[ 'leading_zeros' ];
1235
1236		var d = _getDateObj( date, format ), r = false;
1237		if ( d && d.valid() ) {
1238			r = d.getHours();
1239			if ( leading_zeros ) r = _leadingZeros( r );
1240		}
1241		return r;
1242	};
1243
1244	// MINUTES( datetime_string, datetime_format_string )
1245	lib.MINUTES = function( date, format, leading_zeros ){
1246		var tmp = _processArguments.apply( null, arguments );
1247        date 			= tmp[ 'date' ];
1248        format 			= tmp[ 'format' ];
1249        leading_zeros 	= tmp[ 'leading_zeros' ];
1250
1251		var d = _getDateObj( date, format ), r = false;
1252		if ( d && d.valid() ) {
1253			r = d.getMinutes();
1254			if ( leading_zeros ) r = _leadingZeros( r );
1255		}
1256		return r;
1257	};
1258
1259	// SECONDS( datetime_string, datetime_format_string )
1260	lib.SECONDS = function( date, format, leading_zeros ){
1261		var tmp = _processArguments.apply( null, arguments );
1262        date 			= tmp[ 'date' ];
1263        format 			= tmp[ 'format' ];
1264        leading_zeros 	= tmp[ 'leading_zeros' ];
1265
1266		var d = _getDateObj( date, format ), r = false;
1267		if ( d && d.valid() ) {
1268			r = d.getSeconds();
1269			if ( leading_zeros ) r = _leadingZeros( r );
1270		}
1271		return r;
1272	};
1273
1274	// NOW() Return a datetime object
1275	lib.NOW = function(){
1276		return _getDateObj();
1277	};
1278
1279	// TODAY() Return a datetime object limited to date only
1280	lib.TODAY = function(){
1281		var d = _getDateObj();
1282		d.setHours( 0 );
1283		d.setMinutes( 0 );
1284		d.setSeconds( 0 );
1285		return d;
1286	};
1287
1288	lib.EOMONTH = function(d,n){
1289		n = (n || 0) + 1;
1290		var d1 = _getDateObj(d);
1291		d1.setDate(1);
1292		d1.setMonth(d1.getMonth()+n);
1293		d1.setDate(d1.getDate()-1);
1294		return d1;
1295	};
1296
1297	/*
1298	* DATEDIFF( datetime_string, datetime_string, return_format)
1299	*
1300	* return_format:
1301	* d  - number of days, and remaining hours, minutes and seconds
1302	* m  - number of months, and remaining days, hours, minutes and seconds
1303	* y  - number of years, and remaining months, days, hours, minutes and seconds
1304	*
1305	* the function return an object with attributes: years, months and days depending of return_format argument
1306	*/
1307	lib.DATEDIFF = function( date_one, date_two, date_format, return_format ){
1308		var d1 = _getDateObj( date_one,  date_format ),
1309			d2 = _getDateObj( date_two, date_format ),
1310			diff,
1311			r  = {
1312				'years' 	: -1,
1313				'months'	: -1,
1314				'days'  	: -1,
1315				'hours' 	: -1,
1316				'minutes' 	: -1,
1317				'seconds'	: -1
1318			};
1319
1320		return_format = return_format || 'd';
1321
1322		if( d1 && d1.valid() && d2 && d2.valid() ){
1323			if( d1.valueOf() > d2.valueOf() ){
1324				d2 = _getDateObj( date_one, date_format );
1325				d1 = _getDateObj( date_two, date_format );
1326			}
1327
1328			if ( ! /h/i.test( date_format + return_format ) ) {
1329				d2.setMinutes(d2.getMinutes()-d2.getTimezoneOffset());
1330				d1.setMinutes(d1.getMinutes()-d1.getTimezoneOffset());
1331			}
1332
1333			diff = d2.valueOf() - d1.valueOf();
1334
1335			if( typeof return_format == 'undefined' || return_format == 'd' ){
1336				r.days = Math.floor( diff/86400000 );
1337			} else if(
1338				/[m,y]/i.test( return_format )
1339			) {
1340				var months,
1341					days,
1342					tmp;
1343
1344				months = (d2.getFullYear() - d1.getFullYear()) * 12;
1345				months -= d1.getMonth() + 1;
1346				months += d2.getMonth() + 1;
1347				days = d2.getDate() - d1.getDate();
1348
1349				if( days < 0 ){
1350					months--;
1351					tmp = new Date( d2.getFullYear(), d2.getMonth() );
1352					tmp.setDate(tmp.getDate()-1);
1353					tmp.setDate(d1.getDate());
1354					if ( d1.getDate() != tmp.getDate() ){
1355						tmp = new Date( d2.getFullYear(), d2.getMonth() );
1356						tmp.setDate(tmp.getDate()-1);
1357					}
1358					days = Math.abs( d2.valueOf() - tmp.valueOf() ) / (24*60*60*1000);
1359				}
1360
1361				r.months = months;
1362				r.days = Math.floor(days);
1363
1364				if( /y/i.test( return_format ) ){
1365					r.years = Math.floor( months/12 );
1366					r.months = months % 12;
1367				}
1368			}
1369			if( /h/i.test( return_format ) ) r.hours = Math.floor( diff/3600000 );
1370			else r.hours = Math.floor( diff%86400000/3600000 );
1371
1372			if( /i/i.test( return_format ) ) { r.hours = -1; r.minutes = Math.floor( diff/60000 ); }
1373			else r.minutes = Math.floor( diff%86400000%3600000/60000 );
1374
1375			if( /s/i.test( return_format ) ) { r.hours = -1; r.minutes = -1; r.seconds = Math.floor( diff/1000); }
1376			else r.seconds = Math.floor( diff%86400000%3600000%60000/1000);
1377		}
1378		return r;
1379	};
1380
1381	if ( typeof NETWORKDAYS == 'undefined' ) {
1382		lib.NETWORKDAYS = lib.NETWORKDAYS = function( start_date, end_date, date_format, holidays, holidays_format ) {
1383			var tmp,
1384				result = 0,
1385				min_date_tmp, max_date_tmp;
1386
1387			date_format = date_format || 'mm/dd/yyyy';
1388			holidays = holidays || [];
1389			holidays_format = holidays_format || date_format;
1390			start_date = DATEOBJ(start_date, date_format);
1391			end_date = DATEOBJ(end_date, date_format);
1392
1393			min_date_tmp = Math.min(start_date, end_date);
1394			max_date_tmp = Math.max(start_date, end_date);
1395
1396			start_date = new Date(min_date_tmp);
1397			end_date = new Date(max_date_tmp);
1398
1399			if( ! Array.isArray(holidays) ) holidays = [holidays];
1400
1401			for( var i = 0, h = holidays.length; i < h; i++ ) {
1402				holidays[i] = GETDATETIMESTRING( DATEOBJ( holidays[i], holidays_format), 'yyyy-mm-dd');
1403			}
1404
1405			while( start_date <= end_date ) {
1406				tmp = start_date.getDay();
1407				if(0 != tmp && 6 != tmp) {
1408					tmp = GETDATETIMESTRING(start_date, 'yyyy-mm-dd');
1409					if( holidays.indexOf( tmp ) == -1 ) result++;
1410				}
1411				start_date.setDate(start_date.getDate()+1);
1412			}
1413			return result;
1414		};
1415	}
1416
1417	/*
1418	* DATETIMESUM( datetime_string, format, number, to_increase, ignore_weekend )
1419	* to_increase:
1420	* s  - seconds
1421    * i  - minutes
1422	* h  - hours
1423	* d  - add the number of days,
1424	* m  - add the number of months,
1425	* y  - add the number of years
1426	*
1427	*/
1428	lib.DATETIMESUM = function( date, format, number, to_increase, ignore_weekend){
1429		var d = _getDateObj( date, format );
1430        ignore_weekend = ignore_weekend || false;
1431		if( d && d.valid() ){
1432			if( typeof number != 'number' && isNaN( parseFloat( number ) ) ) number = 0;
1433			else number = parseFloat( number );
1434
1435			if( typeof to_increase == 'undefined' ) to_increase = 'd';
1436
1437
1438			if( /y+/i.test( to_increase ) ) 	 d.setFullYear( d.getFullYear() + number );
1439			else if( /d+/i.test( to_increase ) ){
1440              if(ignore_weekend)
1441              {
1442                  var n  = number < 0 ? Math.ceil(number) : Math.floor(number),
1443                      s  = number < 0 ? -1 : 1;
1444                  while(n)
1445                  {
1446                      d.setDate(d.getDate()+s);
1447                      if(0 < d.getDay() && d.getDay() < 6) n -= s;
1448                  }
1449              }
1450              else d.setDate( d.getDate() + number );
1451            }
1452			else if( /m+/i.test( to_increase ) ){
1453                var tmp = DAY(d)
1454                d.setDate(1);
1455                d.setMonth( d.getMonth() + number );
1456                d = EOMONTH(d);
1457                d.setDate(MIN(tmp,DAY(d)));
1458            }
1459			else if( /h+/i.test( to_increase ) ) d.setHours( d.getHours() + number );
1460			else if( /i+/i.test( to_increase ) ) d.setMinutes( d.getMinutes() + number );
1461			else d.setSeconds( d.getSeconds() + number );
1462
1463			return d;
1464		}
1465		return false;
1466	};
1467
1468    lib.DECIMALTOTIME = lib.decimaltotime = function(value, from_format, to_format){
1469        function complete(v, f)
1470        {
1471            if(1<f[0].length && v<10) v = '0'+v;
1472            return v;
1473        };
1474
1475        from_format = from_format.toLowerCase();
1476
1477        var y = /\by+\b/i.exec(to_format),
1478            m = /\bm+\b/i.exec(to_format),
1479            d = /\bd+\b/i.exec(to_format),
1480            h = /\bh+\b/i.exec(to_format),
1481            i = /\bi+\b/i.exec(to_format),
1482            s = /\bs+\b/i.exec(to_format),
1483            factor = 1,
1484            components = {};
1485
1486        switch(from_format)
1487        {
1488            case 'y': factor = 365*24*60*60; break;
1489            case 'm': factor = 30*24*60*60; break;
1490            case 'd': factor = 24*60*60; break;
1491            case 'h': factor = 60*60; break;
1492            case 'i': factor = 60; break;
1493        }
1494
1495        value *= factor;
1496
1497        if(y){ components['y'] = FLOOR(value/(365*24*60*60)); value = value%(365*24*60*60);}
1498        if(m){ components['m'] = complete(FLOOR(value/(30*24*60*60)), m); value = value%(30*24*60*60);}
1499        if(d){ components['d'] = complete(FLOOR(value/(24*60*60)), d); value = value%(24*60*60);}
1500        if(h){ components['h'] = complete(FLOOR(value/(60*60)), h); value = value%(60*60);}
1501        if(i){ components['i'] = complete(FLOOR(value/60), i); value = value%60;}
1502        if(s){ components['s'] = complete(FLOOR(value), s);}
1503
1504        for(var index in components)
1505        {
1506            to_format = to_format.replace(new RegExp('\\b'+index+'+\\b', 'i'), components[index]);
1507        }
1508
1509        return to_format;
1510    };
1511
1512	lib.TIMETODECIMAL = lib.timetodecimal = function(value, from_format, to_format){
1513        from_format = from_format.replace(/[^ymdhisa\:\s]/ig, '')
1514                    .replace(/^[\s\:]+/, '')
1515                    .replace(/[\s\:]+$/, '')
1516                    .replace(/[\s\:]+/g, ' ');
1517
1518        value = (value+'').replace(/^[\s\:]+/, '')
1519                    .replace(/[\s\:]+$/, '')
1520                    .replace(/[\s\:]+/g, ' ');
1521
1522        to_format = to_format.toLowerCase();
1523
1524        var value_components = value.split(/\s+/g),
1525            from_components  = from_format.split(/\s+/g),
1526            factor = 1,
1527            result = 0,
1528			last_index = from_components.length - 1;
1529
1530        for(var j in from_components)
1531        {
1532			if( ! ( j in value_components ) ) continue;
1533
1534            if(/y/i.test(from_components[j])) factor = 365*24*60*60;
1535            else if(/m/i.test(from_components[j])) factor = 30*24*60*60;
1536            else if(/d/i.test(from_components[j])) factor = 24*60*60;
1537            else if(/h/i.test(from_components[j])) {
1538				factor = 60*60;
1539				if( last_index in value_components ) {
1540					let a = ( value_components[ last_index ]+'' ).toLowerCase();
1541					if ( a == 'pm' && value_components[j]*1 <= 12 ) {
1542						value_components[j] = value_components[j]*1 + 12;
1543					} else if ( a == 'am' && value_components[j]*1 == 12 ) {
1544						value_components[j] = value_components[j]*1 - 12;
1545					}
1546				}
1547			}
1548            else if(/i/i.test(from_components[j])) factor = 60;
1549            else if(/s/i.test(from_components[j])) factor = 1;
1550			else continue;
1551            result += value_components[j]*factor;
1552        }
1553
1554        switch(to_format)
1555        {
1556            case 'y': factor = 365*24*60*60; break;
1557            case 'm': factor = 30*24*60*60; break;
1558            case 'd': factor = 24*60*60; break;
1559            case 'h': factor = 60*60; break;
1560            case 'i': factor = 60; break;
1561            case 's': factor = 1; break;
1562        }
1563
1564        return result/factor;
1565    };
1566
1567	// GETDATETIMESTRING( date_object, return_format ) Return the date object as a string representation determined by the return_format argument
1568	lib.GETDATETIMESTRING = function( date, format ){
1569	  if( typeof format == 'undefined' ) format = default_format;
1570	  date = _getDateObj( date, format );
1571	  if( date && date.valid() ){
1572		var m = date.getMonth() + 1,
1573			d = date.getDate(),
1574			h = date.getHours(),
1575			i = date.getMinutes(),
1576			s = date.getSeconds(),
1577			a = ( h >= 12 ) ? 'pm' : 'am';
1578
1579		m = ( m < 10 ) ? '0'+m : m;
1580		d = ( d < 10 ) ? '0'+d : d;
1581		if( /a+/.test( format ) ){
1582			h = h % 12;
1583			h = ( h ) ? h : 12;
1584		}
1585		h = ( h < 10 ) ? '0'+h : h;
1586		i = ( i < 10 ) ? '0'+i : i;
1587		s = ( s < 10 ) ? '0'+s : s;
1588
1589		return format.replace( /\by{2}\b/i, date.getFullYear()%100 )
1590                     .replace( /y+/i, date.getFullYear() )
1591					 .replace( /m+/i, m )
1592					 .replace( /d+/i, d )
1593					 .replace( /h+/i, h )
1594					 .replace( /i+/i, i )
1595					 .replace( /s+/i, s )
1596					 .replace( /a+/i, a );
1597	  }
1598	  return date;
1599	};
1600
1601	/**
1602	 * slots, mixed, it can be one slot or slots array.
1603	 * format, date format.
1604	 * return mixed, a parsed slot, or an array of parsed slots.
1605	 * A parsed slot is an object with the structure {date: dateObj, slot:{start:string, end:string, duration:number in minutes}}
1606	 */
1607	lib.PARSESLOTS = function(slots, format) {
1608
1609		function _parser( slot, format ) {
1610			try {
1611				const parsed = slot.match( /(\d{1,4}[\/\-\.]\d{1,4}[\/\-\.]\d{1,4})\s*\:\s*(\d{1,2}\:\d{1,2})\s*\-\s*(\d{1,2}\:\d{1,2})/ );
1612				if ( ! slot.match ) return false;
1613				return {
1614					date: lib.DATEOBJ(parsed[1], format),
1615					slot: {
1616						start: parsed[2],
1617						end: parsed[3],
1618						duration: lib.DATEDIFF(parsed[2], parsed[3], 'hh:ii', 'i')['minutes']
1619					}
1620				};
1621			} catch ( err ) {
1622				console.log(err);
1623			}
1624			return false;
1625		};
1626
1627		function _validateFormat( format ) {
1628			return (
1629				/dd[\-\/\.]mm[\-\/\.]yyyy/i.test(format) ||
1630				/mm[\-\/\.]dd[\-\/\.]yyyy/i.test(format) ||
1631				/yyyy[\-\/\.]mm[\-\/\.]dd/i.test(format) ||
1632				/yyyy[\-\/\.]dd[\-\/\.]mm/i.test(format)
1633			);
1634		};
1635
1636		slots = slots || [];
1637		format = format || '';
1638
1639
1640		if ( Array.isArray(slots) ) {
1641			let parsed_slots = [];
1642			if( _validateFormat ) {
1643				for ( let i in slots ) {
1644					let slot = slots[i];
1645					if ( typeof slot == 'string' ) {
1646						let parsed_slot = _parser( slot, format );
1647						if ( parsed_slot ) parsed_slots.push( parsed_slot );
1648					}
1649				}
1650			}
1651			return parsed_slots;
1652		} else if ( typeof slots == 'string' && _validateFormat( format ) ) {
1653			let parsed_slot = _parser( slots, format );
1654			if ( parsed_slot ) return parsed_slot;
1655			else null;
1656		} else return null;
1657	};
1658
1659	root.CF_DATETIME = lib;
1660
1661})(this);fbuilderjQuery = ( typeof fbuilderjQuery != 'undefined' ) ? fbuilderjQuery : jQuery;
1662fbuilderjQuery[ 'fbuilder' ] = fbuilderjQuery[ 'fbuilder' ] || {};
1663fbuilderjQuery[ 'fbuilder' ][ 'modules' ] = fbuilderjQuery[ 'fbuilder' ][ 'modules' ] || {};
1664
1665fbuilderjQuery[ 'fbuilder' ][ 'modules' ][ 'datetime' ] = {
1666	'prefix' : '',
1667	'callback' : function()
1668		{
1669			fbuilderjQuery[ 'fbuilder' ][ 'extend_window' ]( fbuilderjQuery[ 'fbuilder' ][ 'modules' ][ 'datetime' ][ 'prefix' ], CF_DATETIME );
1670		},
1671	
1672	'validator' : function( v )
1673		{
1674			if( /^\s*((\d{4}[\/\-\.]\d{1,2}[\/\-\.]\d{1,2})|(\d{1,2}[\/\-\.]\d{1,2}[\/\-\.]\d{4}))?\s*(\d{1,2}\s*:\s*\d{1,2}(\s*:\s*\d{1,2})?(\s*[ap]m)?)?\s*$/i.test( v ) ) 
1675			{
1676				return true;
1677			}	
1678			return false;
1679		}
1680};/*
1681 * energy.js v0.1
1682 * By: CALCULATED FIELD PROGRAMMERS
1683 * Includes energy-relate operations
1684 * Copyright 2025 CODEPEOPLE
1685 */
1686;
1687(function (root) {
1688    var lib = {};
1689
1690    // Constants and utilities
1691    var CONSTANTS = {
1692        SOLAR_PANEL_EFFICIENCY_DEGRADATION: 0.005,
1693        AVERAGE_SOLAR_HOURS_PER_DAY: 4.5,
1694        DAYS_PER_YEAR: 365,
1695        MONTHS_PER_YEAR: 12,
1696        GRID_EFFICIENCY_LOSS: 0.08,
1697        BATTERY_EFFICIENCY: 0.85,
1698        INFLATION_RATE: 0.03,
1699        DEFAULT_DISCOUNT_RATE: 0.05,
1700        DEFAULT_POWER_FACTOR: 0.9,
1701        DEFAULT_GRID_CARBON_INTENSITY: 0.4
1702    };
1703
1704	function _getConstants() {
1705		if( 'CFF_ENERGY_CONSTANTS' in window ) {
1706			try {
1707				for ( let i in CFF_ENERGY_CONSTANTS ) {
1708					if ( CFF_ENERGY_CONSTANTS.hasOwnProperty(i) ) {
1709						CONSTANTS[i] = CFF_ENERGY_CONSTANTS[i];
1710					}
1711				}
1712			} catch ( err ) { console.log(err); }
1713		}
1714		return CONSTANTS;
1715	};
1716
1717    // Utility functions
1718    var utils = {
1719        round: function(value, decimals) {
1720            var factor = Math.pow(10, decimals || 2);
1721            return Math.round(value * factor) / factor;
1722        },
1723
1724        validatePositive: function(value, name) {
1725            if (typeof value !== 'number' || value <= 0) {
1726                throw new Error(name + ' must be a positive number');
1727            }
1728        },
1729
1730        validateArray: function(arr, name, expectedLength) {
1731            if (!Array.isArray(arr)) {
1732                throw new Error(name + ' must be an array');
1733            }
1734            if (expectedLength && arr.length !== expectedLength) {
1735                throw new Error(name + ' must have ' + expectedLength + ' elements');
1736            }
1737        },
1738
1739        validateObject: function(obj, name) {
1740            if (!obj || typeof obj !== 'object') {
1741                throw new Error(name + ' object is required');
1742            }
1743        },
1744
1745        calculateCompoundEffect: function(initial, rate, years) {
1746            return initial * Math.pow(1 + rate, years);
1747        },
1748
1749        calculatePresentValue: function(futureValue, rate, years) {
1750            return futureValue / Math.pow(1 + rate, years);
1751        }
1752    };
1753
1754    /**
1755     * Calculate solar panel savings with optimized performance
1756     */
1757    lib.CFFSOLARSAVINGS = lib.cffsolarsavings = function(params) {
1758		try {
1759			utils.validateObject(params, 'Parameters');
1760
1761			let p = {
1762				monthlyConsumption: params.monthlyConsumption,
1763				electricityRate: params.electricityRate,
1764				solarSystemSize: params.solarSystemSize,
1765				solarHoursPerDay: params.solarHoursPerDay || _getConstants().AVERAGE_SOLAR_HOURS_PER_DAY,
1766				systemEfficiency: params.systemEfficiency || 0.8,
1767				netMeteringRate: params.netMeteringRate || params.electricityRate
1768			};
1769
1770			utils.validatePositive(p.monthlyConsumption, 'Monthly consumption');
1771			utils.validatePositive(p.electricityRate, 'Electricity rate');
1772			utils.validatePositive(p.solarSystemSize, 'Solar system size');
1773
1774			let dailyProduction = p.solarSystemSize * p.solarHoursPerDay * p.systemEfficiency,
1775				annualProduction = dailyProduction * _getConstants().DAYS_PER_YEAR,
1776				annualConsumption = p.monthlyConsumption * _getConstants().MONTHS_PER_YEAR,
1777				annualElectricityBill = annualConsumption * p.electricityRate,
1778
1779				energyOffset = Math.min(annualProduction, annualConsumption),
1780				excessEnergy = Math.max(0, annualProduction - annualConsumption),
1781				annualSavings = (energyOffset * p.electricityRate) + (excessEnergy * p.netMeteringRate);
1782
1783			return {
1784				production: {
1785					dailyProduction: utils.round(dailyProduction),
1786					monthlyProduction: utils.round(dailyProduction * _getConstants().DAYS_PER_YEAR / _getConstants().MONTHS_PER_YEAR),
1787					annualProduction: utils.round(annualProduction)
1788				},
1789				consumption: {
1790					monthlyConsumption: p.monthlyConsumption,
1791					annualConsumption: annualConsumption
1792				},
1793				financial: {
1794					monthlyElectricityBill: utils.round(annualElectricityBill / _getConstants().MONTHS_PER_YEAR),
1795					annualElectricityBill: utils.round(annualElectricityBill),
1796					monthlySavings: utils.round(annualSavings / _getConstants().MONTHS_PER_YEAR),
1797					annualSavings: utils.round(annualSavings),
1798					savingsPercentage: utils.round((annualSavings / annualElectricityBill) * 100),
1799					excessEnergyValue: utils.round(excessEnergy * p.netMeteringRate)
1800				},
1801				metrics: {
1802					productionToConsumptionRatio: utils.round(annualProduction / annualConsumption),
1803					energyOffset: utils.round(energyOffset),
1804					excessEnergy: utils.round(excessEnergy)
1805				}
1806			};
1807		} catch ( err ) { console.log( err ); }
1808    };
1809
1810    /**
1811     * Calculate payback period with NPV analysis
1812     */
1813    lib.CFFPAYBACKPERIOD = function(params) {
1814		try {
1815			utils.validateObject(params, 'Parameters');
1816
1817			var p = {
1818				initialInvestment: params.initialInvestment,
1819				annualSavings: params.annualSavings,
1820				maintenanceCostPerYear: params.maintenanceCostPerYear || 0,
1821				incentives: params.incentives || 0,
1822				inflationRate: params.inflationRate || _getConstants().INFLATION_RATE,
1823				degradationRate: params.degradationRate || _getConstants().SOLAR_PANEL_EFFICIENCY_DEGRADATION,
1824				analysisYears: params.analysisYears || 25,
1825				discountRate: params.discountRate || _getConstants().DEFAULT_DISCOUNT_RATE
1826			};
1827
1828			utils.validatePositive(p.initialInvestment, 'Initial investment');
1829			utils.validatePositive(p.annualSavings, 'Annual savings');
1830
1831			var netInitialInvestment = p.initialInvestment - p.incentives,
1832				cumulativeCashFlow = -netInitialInvestment,
1833				netPresentValue = -netInitialInvestment,
1834				paybackPeriod = null,
1835
1836				// Pre-calculate factors for performance
1837				inflationFactors = [],
1838				degradationFactors = [],
1839				discountFactors = [];
1840
1841			for (var year = 1; year <= p.analysisYears; year++) {
1842				inflationFactors[year] = Math.pow(1 + p.inflationRate, year - 1);
1843				degradationFactors[year] = Math.pow(1 - p.degradationRate, year - 1);
1844				discountFactors[year] = Math.pow(1 + p.discountRate, year);
1845			}
1846
1847			var yearlyAnalysis = [];
1848			for (var year = 1; year <= p.analysisYears; year++) {
1849				var adjustedSavings = p.annualSavings * degradationFactors[year] * inflationFactors[year];
1850				var adjustedMaintenanceCost = p.maintenanceCostPerYear * inflationFactors[year];
1851				var netAnnualSavings = adjustedSavings - adjustedMaintenanceCost;
1852
1853				cumulativeCashFlow += netAnnualSavings;
1854				var presentValue = netAnnualSavings / discountFactors[year];
1855				netPresentValue += presentValue;
1856
1857				if (paybackPeriod === null && cumulativeCashFlow >= 0) {
1858					var previousCashFlow = year > 1 ? yearlyAnalysis[year - 2].cumulativeCashFlow : -netInitialInvestment;
1859					paybackPeriod = (year - 1) + Math.abs(previousCashFlow) / netAnnualSavings;
1860				}
1861
1862				yearlyAnalysis.push({
1863					year: year,
1864					adjustedSavings: utils.round(adjustedSavings),
1865					maintenanceCost: utils.round(adjustedMaintenanceCost),
1866					netAnnualSavings: utils.round(netAnnualSavings),
1867					cumulativeCashFlow: utils.round(cumulativeCashFlow),
1868					presentValue: utils.round(presentValue)
1869				});
1870			}
1871
1872			return {
1873				financial: {
1874					initialInvestment: p.initialInvestment,
1875					incentives: p.incentives,
1876					netInitialInvestment: utils.round(netInitialInvestment),
1877					simplePaybackPeriod: utils.round(netInitialInvestment / (p.annualSavings - p.maintenanceCostPerYear)),
1878					discountedPaybackPeriod: paybackPeriod ? utils.round(paybackPeriod) : null,
1879					netPresentValue: utils.round(netPresentValue),
1880					totalCashFlow: utils.round(cumulativeCashFlow)
1881				},
1882				analysis: {
1883					analysisYears: p.analysisYears,
1884					inflationRate: p.inflationRate,
1885					degradationRate: p.degradationRate,
1886					discountRate: p.discountRate
1887				},
1888				yearlyBreakdown: yearlyAnalysis
1889			};
1890		} catch ( err ) { console.log( err ); }
1891    };
1892
1893    /**
1894     * Calculate power requirements with load analysis
1895     */
1896    lib.CFFPOWERREQUIREMENTS = function(params) {
1897		try {
1898			utils.validateObject(params, 'Parameters');
1899			utils.validateArray(params.appliances, 'Appliances');
1900
1901			if (params.appliances.length === 0) {
1902				throw new Error('At least one appliance must be specified');
1903			}
1904
1905			var p = {
1906					appliances: params.appliances,
1907					simultaneityFactor: params.simultaneityFactor || 0.7,
1908					safetyFactor: params.safetyFactor || 1.2,
1909					powerFactor: params.powerFactor || _getConstants().DEFAULT_POWER_FACTOR
1910				},
1911
1912				totals = {
1913					connectedLoad: 0,
1914					dailyConsumption: 0
1915				},
1916
1917				peakDemandByHour = new Array(24).fill(0),
1918				applianceAnalysis = [];
1919
1920			// Process appliances efficiently
1921			p.appliances.forEach(function(appliance) {
1922				if (!appliance.name || typeof appliance.power !== 'number' || typeof appliance.hoursPerDay !== 'number') {
1923					throw new Error('Each appliance must have name, power, and hoursPerDay properties');
1924				}
1925
1926				var quantity = appliance.quantity || 1,
1927					totalPower = appliance.power * quantity,
1928					dailyConsumption = totalPower * appliance.hoursPerDay / 1000,
1929					operatingHours = appliance.operatingHours || [9, 10, 11, 12, 13, 14, 15, 16];
1930
1931				totals.connectedLoad += totalPower;
1932				totals.dailyConsumption += dailyConsumption;
1933
1934				// Distribute load efficiently
1935				var powerPerHour = totalPower / operatingHours.length;
1936				operatingHours.forEach(function(hour) {
1937					if (hour >= 0 && hour < 24) {
1938						peakDemandByHour[hour] += powerPerHour;
1939					}
1940				});
1941
1942				applianceAnalysis.push({
1943					name: appliance.name,
1944					quantity: quantity,
1945					unitPower: appliance.power,
1946					totalPower: totalPower,
1947					hoursPerDay: appliance.hoursPerDay,
1948					dailyConsumption: utils.round(dailyConsumption, 3),
1949					operatingHours: operatingHours
1950				});
1951			});
1952
1953			var peakDemand = Math.max.apply(Math, peakDemandByHour),
1954				diversifiedDemand = peakDemand * p.simultaneityFactor,
1955				requiredCapacityKW = (diversifiedDemand / 1000) * p.safetyFactor,
1956				requiredCapacityKVA = requiredCapacityKW / p.powerFactor,
1957
1958				averageLoad = totals.dailyConsumption * 1000 / 24,
1959				loadFactor = averageLoad / peakDemand;
1960
1961			return {
1962				summary: {
1963					totalConnectedLoad: Math.round(totals.connectedLoad),
1964					peakDemand: Math.round(peakDemand),
1965					diversifiedDemand: Math.round(diversifiedDemand),
1966					requiredCapacityKW: utils.round(requiredCapacityKW),
1967					requiredCapacityKVA: utils.round(requiredCapacityKVA),
1968					recommendedBreakerSize: Math.ceil(requiredCapacityKW * 1.25 / 0.23),
1969					loadFactor: utils.round(loadFactor)
1970				},
1971				consumption: {
1972					dailyConsumption: utils.round(totals.dailyConsumption),
1973					monthlyConsumption: utils.round(totals.dailyConsumption * 30),
1974					annualConsumption: utils.round(totals.dailyConsumption * _getConstants().DAYS_PER_YEAR)
1975				},
1976				factors: {
1977					simultaneityFactor: p.simultaneityFactor,
1978					safetyFactor: p.safetyFactor,
1979					powerFactor: p.powerFactor
1980				},
1981				appliances: applianceAnalysis,
1982				hourlyDemand: peakDemandByHour.map(Math.round)
1983			};
1984		} catch ( err ) { console.log( err ); }
1985    };
1986
1987    /**
1988     * Calculate energy efficiency improvements with compound effects
1989     */
1990    lib.CFFENERGYEFFICIENCY = function(params) {
1991		try {
1992			utils.validateObject(params, 'Parameters');
1993
1994			var p = {
1995				currentConsumption: params.currentConsumption,
1996				electricityRate: params.electricityRate,
1997				improvements: params.improvements || []
1998			};
1999
2000			utils.validatePositive(p.currentConsumption, 'Current consumption');
2001			utils.validatePositive(p.electricityRate, 'Electricity rate');
2002
2003			var currentAnnualCost = p.currentConsumption * p.electricityRate * _getConstants().MONTHS_PER_YEAR,
2004				remainingConsumption = p.currentConsumption,
2005				totalImplementationCost = 0;
2006
2007			var	improvementAnalysis = p.improvements.map(function(improvement) {
2008				if (!improvement.name || typeof improvement.savingsPercentage !== 'number') {
2009					throw new Error('Each improvement must have name and savingsPercentage properties');
2010				}
2011
2012				var savingsFromImprovement = remainingConsumption * (improvement.savingsPercentage / 100);
2013				remainingConsumption -= savingsFromImprovement;
2014
2015				var annualDollarSavings = savingsFromImprovement * p.electricityRate * _getConstants().MONTHS_PER_YEAR,
2016					implementationCost = improvement.cost || 0,
2017					lifespan = improvement.lifespan || 10;
2018
2019				totalImplementationCost += implementationCost;
2020
2021				var lifetimeSavings = annualDollarSavings * lifespan,
2022					netBenefit = lifetimeSavings - implementationCost;
2023
2024				return {
2025					name: improvement.name,
2026					savingsPercentage: improvement.savingsPercentage,
2027					energySavingsKWh: utils.round(savingsFromImprovement * _getConstants().MONTHS_PER_YEAR),
2028					annualDollarSavings: utils.round(annualDollarSavings),
2029					implementationCost: implementationCost,
2030					simplePayback: implementationCost > 0 ? utils.round(implementationCost / annualDollarSavings) : 0,
2031					lifespan: lifespan,
2032					lifetimeSavings: utils.round(lifetimeSavings),
2033					netBenefit: utils.round(netBenefit),
2034					roi: implementationCost > 0 ? utils.round((netBenefit / implementationCost) * 100) : 0
2035				};
2036			});
2037
2038			var newAnnualCost = remainingConsumption * p.electricityRate * _getConstants().MONTHS_PER_YEAR,
2039				totalAnnualSavings = currentAnnualCost - newAnnualCost,
2040				totalSavingsPercentage = ((p.currentConsumption - remainingConsumption) / p.currentConsumption) * 100;
2041
2042			return {
2043				current: {
2044					monthlyConsumption: p.currentConsumption,
2045					monthlyCost: utils.round(currentAnnualCost / _getConstants().MONTHS_PER_YEAR),
2046					annualConsumption: utils.round(p.currentConsumption * _getConstants().MONTHS_PER_YEAR),
2047					annualCost: utils.round(currentAnnualCost)
2048				},
2049				improved: {
2050					monthlyConsumption: utils.round(remainingConsumption),
2051					monthlyCost: utils.round(newAnnualCost / _getConstants().MONTHS_PER_YEAR),
2052					annualConsumption: utils.round(remainingConsumption * _getConstants().MONTHS_PER_YEAR),
2053					annualCost: utils.round(newAnnualCost)
2054				},
2055				savings: {
2056					monthlyEnergyReduction: utils.round(p.currentConsumption - remainingConsumption),
2057					annualEnergyReduction: utils.round((p.currentConsumption - remainingConsumption) * _getConstants().MONTHS_PER_YEAR),
2058					monthlyCostSavings: utils.round(totalAnnualSavings / _getConstants().MONTHS_PER_YEAR),
2059					annualCostSavings: utils.round(totalAnnualSavings),
2060					totalSavingsPercentage: utils.round(totalSavingsPercentage)
2061				},
2062				investment: {
2063					totalImplementationCost: utils.round(totalImplementationCost),
2064					overallPaybackPeriod: totalImplementationCost > 0 ? utils.round(totalImplementationCost / totalAnnualSavings) : 0
2065				},
2066				improvements: improvementAnalysis
2067			};
2068		} catch ( err ) { console.log( err ); }
2069    };
2070
2071    /**
2072     * Calculate battery storage requirements and economics
2073     */
2074    lib.CFFBATTERYSTORAGE = function(params) {
2075		try {
2076			utils.validateObject(params, 'Parameters');
2077
2078			var p = {
2079				dailyConsumption: params.dailyConsumption,
2080				autonomyDays: params.autonomyDays || 1,
2081				batteryVoltage: params.batteryVoltage || 48,
2082				depthOfDischarge: params.depthOfDischarge || 0.8,
2083				batteryEfficiency: params.batteryEfficiency || _getConstants().BATTERY_EFFICIENCY,
2084				costPerKWh: params.costPerKWh || 400,
2085				cycleLife: params.cycleLife || 5000
2086			};
2087
2088			utils.validatePositive(p.dailyConsumption, 'Daily consumption');
2089
2090			var totalEnergyNeeded = p.dailyConsumption * p.autonomyDays,
2091				usableCapacityRequired = totalEnergyNeeded / p.batteryEfficiency,
2092				nominalCapacityRequired = usableCapacityRequired / p.depthOfDischarge,
2093				capacityAh = (nominalCapacityRequired * 1000) / p.batteryVoltage,
2094
2095				// Cost calculations
2096				costs = {
2097					battery: nominalCapacityRequired * p.costPerKWh,
2098					inverter: nominalCapacityRequired * 200,
2099					bmsAndWiring: nominalCapacityRequired * 100
2100				};
2101			costs.installation = costs.battery * 0.2;
2102			costs.total = costs.battery + costs.inverter + costs.bmsAndWiring + costs.installation;
2103
2104			// Lifecycle calculations
2105			var cyclesPerYear = _getConstants().DAYS_PER_YEAR,
2106				batteryLifeYears = p.cycleLife / cyclesPerYear,
2107				costPerCycle = costs.battery / p.cycleLife,
2108				costPerKWhCycled = costPerCycle / (nominalCapacityRequired * p.depthOfDischarge);
2109
2110			return {
2111				requirements: {
2112					dailyConsumption: p.dailyConsumption,
2113					autonomyDays: p.autonomyDays,
2114					totalEnergyNeeded: utils.round(totalEnergyNeeded),
2115					usableCapacityRequired: utils.round(usableCapacityRequired),
2116					nominalCapacityRequired: utils.round(nominalCapacityRequired),
2117					capacityAh: utils.round(capacityAh)
2118				},
2119				system: {
2120					batteryVoltage: p.batteryVoltage,
2121					depthOfDischarge: p.depthOfDischarge,
2122					batteryEfficiency: p.batteryEfficiency,
2123					cycleLife: p.cycleLife
2124				},
2125				costs: {
2126					batteryCost: utils.round(costs.battery),
2127					inverterCost: utils.round(costs.inverter),
2128					bmsAndWiringCost: utils.round(costs.bmsAndWiring),
2129					installationCost: utils.round(costs.installation),
2130					totalSystemCost: utils.round(costs.total),
2131					costPerKWh: p.costPerKWh,
2132					costPerCycle: utils.round(costPerCycle),
2133					costPerKWhCycled: utils.round(costPerKWhCycled)
2134				},
2135				lifecycle: {
2136					batteryLifeYears: utils.round(batteryLifeYears),
2137					cyclesPerYear: cyclesPerYear,
2138					replacementCost: utils.round(costs.battery),
2139					maintenanceCostPerYear: utils.round(costs.total * 0.02)
2140				}
2141			};
2142		} catch ( err ) { console.log( err ); }
2143    };
2144
2145    /**
2146     * Optimized energy unit conversion with lookup table
2147     */
2148    lib.CFFCONVERTENERGYUNITS = (function() {
2149        var conversionToKWh = {
2150            'kWh': 1, 'MWh': 1000, 'Wh': 0.001, 'BTU': 0.000293071,
2151            'J': 2.77778e-7, 'kJ': 0.000277778, 'MJ': 0.277778,
2152            'cal': 1.16279e-6, 'kcal': 0.00116279, 'therm': 29.3001
2153        };
2154
2155        return function(value, fromUnit, toUnit) {
2156			try {
2157				if (typeof value !== 'number' || !conversionToKWh[fromUnit] || !conversionToKWh[toUnit]) {
2158					throw new Error('Invalid parameters for energy unit conversion');
2159				}
2160
2161				return utils.round((value * conversionToKWh[fromUnit]) / conversionToKWh[toUnit], 6);
2162			} catch ( err ) { console.log( err ); }
2163        };
2164    })();
2165
2166    /**
2167     * Calculate environmental impact with carbon footprint
2168     */
2169    lib.CFFENVIRONMENTALIMPACT = function(params) {
2170		try {
2171			utils.validateObject(params, 'Parameters');
2172
2173			var p = {
2174				annualConsumption: params.annualConsumption,
2175				gridCarbonIntensity: params.gridCarbonIntensity || _getConstants().DEFAULT_GRID_CARBON_INTENSITY,
2176				renewableEnergyRatio: params.renewableEnergyRatio || 0
2177			};
2178
2179			utils.validatePositive(p.annualConsumption, 'Annual consumption');
2180
2181			if (p.renewableEnergyRatio < 0 || p.renewableEnergyRatio > 1) {
2182				throw new Error('Renewable energy ratio must be between 0 and 1');
2183			}
2184
2185			var gridEnergyConsumption = p.annualConsumption * (1 - p.renewableEnergyRatio),
2186				renewableEnergyConsumption = p.annualConsumption * p.renewableEnergyRatio,
2187				annualCarbonEmissions = gridEnergyConsumption * p.gridCarbonIntensity,
2188				carbonSaved = renewableEnergyConsumption * p.gridCarbonIntensity;
2189
2190			return {
2191				consumption: {
2192					annualConsumption: p.annualConsumption,
2193					gridEnergyConsumption: utils.round(gridEnergyConsumption),
2194					renewableEnergyConsumption: utils.round(renewableEnergyConsumption),
2195					renewableEnergyRatio: p.renewableEnergyRatio
2196				},
2197				emissions: {
2198					gridCarbonIntensity: p.gridCarbonIntensity,
2199					annualCarbonEmissions: utils.round(annualCarbonEmissions),
2200					carbonSaved: utils.round(carbonSaved),
2201					monthlyCarbonEmissions: utils.round(annualCarbonEmissions / 12)
2202				},
2203				equivalents: {
2204					treesEquivalent: utils.round(annualCarbonEmissions / 21.77),
2205					carMilesEquivalent: utils.round(annualCarbonEmissions / 0.404),
2206					coalEquivalent: utils.round(annualCarbonEmissions / 2.23)
2207				}
2208			};
2209		} catch ( err ) { console.log( err ); }
2210    };
2211
2212    /**
2213     * Calculate demand charges and TOU optimization
2214     */
2215    lib.CFFDEMANDCHARGES = function(params) {
2216		try {
2217			utils.validateObject(params, 'Parameters');
2218			utils.validateArray(params.hourlyUsage, 'Hourly usage', 24);
2219
2220			var p = {
2221				hourlyUsage: params.hourlyUsage,
2222				rates: params.rates || {},
2223				demandCharge: (params.rates && params.rates.demandCharge) || 0,
2224				timeOfUseRates: (params.rates && params.rates.timeOfUseRates) || [],
2225				baseRate: (params.rates && params.rates.baseRate) || 0.12
2226			};
2227
2228			var peakDemand = Math.max.apply(Math, p.hourlyUsage),
2229				monthlyDemandCharge = peakDemand * p.demandCharge,
2230				totalEnergyCharge = 0,
2231				touBreakdown = {};
2232
2233			var hourlyCharges = p.hourlyUsage.map(function(usage, hour) {
2234				var rate = p.baseRate,
2235					ratePeriod = 'Base';
2236
2237				// Find applicable TOU rate efficiently
2238				for (var i = 0; i < p.timeOfUseRates.length; i++) {
2239					var touRate = p.timeOfUseRates[i],
2240						startHour = touRate.hours[0],
2241						endHour = touRate.hours[1],
2242
2243						isInPeriod = startHour <= endHour ?
2244						(hour >= startHour && hour < endHour) :
2245						(hour >= startHour || hour < endHour);
2246
2247					if (isInPeriod) {
2248						rate = touRate.rate;
2249						ratePeriod = touRate.name || ('TOU-' + i);
2250						break;
2251					}
2252				}
2253
2254				var hourlyCharge = usage * rate;
2255				totalEnergyCharge += hourlyCharge;
2256
2257				// Accumulate TOU breakdown
2258				if (!touBreakdown[ratePeriod]) {
2259					touBreakdown[ratePeriod] = { usage: 0, charge: 0, rate: rate };
2260				}
2261				touBreakdown[ratePeriod].usage += usage;
2262				touBreakdown[ratePeriod].charge += hourlyCharge;
2263
2264				return {
2265					hour: hour,
2266					usage: utils.round(usage, 3),
2267					rate: rate,
2268					ratePeriod: ratePeriod,
2269					charge: utils.round(hourlyCharge)
2270				};
2271			});
2272
2273			// Round TOU breakdown
2274			Object.keys(touBreakdown).forEach(function(period) {
2275				touBreakdown[period].usage = utils.round(touBreakdown[period].usage, 3);
2276				touBreakdown[period].charge = utils.round(touBreakdown[period].charge);
2277			});
2278
2279			var totalBill = totalEnergyCharge + monthlyDemandCharge,
2280				totalUsage = p.hourlyUsage.reduce(function(sum, usage) { return sum + usage; }, 0);
2281
2282			return {
2283				demand: {
2284					peakDemand: utils.round(peakDemand, 3),
2285					demandChargeRate: p.demandCharge,
2286					monthlyDemandCharge: utils.round(monthlyDemandCharge)
2287				},
2288				energy: {
2289					totalUsage: utils.round(totalUsage, 3),
2290					totalEnergyCharge: utils.round(totalEnergyCharge),
2291					averageRate: utils.round(totalUsage > 0 ? totalBill / totalUsage : 0, 4)
2292				},
2293				billing: {
2294					totalBill: utils.round(totalBill),
2295					energyChargePercentage: utils.round((totalEnergyCharge / totalBill) * 100),
2296					demandChargePercentage: utils.round((monthlyDemandCharge / totalBill) * 100)
2297				},
2298				timeOfUse: touBreakdown,
2299				hourlyBreakdown: hourlyCharges
2300			};
2301		} catch ( err ) { console.log( err ); }
2302    };
2303
2304    // Export the library
2305    root.CF_ENERGY = lib;
2306
2307})(this);
2308fbuilderjQuery = ( typeof fbuilderjQuery != 'undefined' ) ? fbuilderjQuery : jQuery;
2309fbuilderjQuery[ 'fbuilder' ] = fbuilderjQuery[ 'fbuilder' ] || {};
2310fbuilderjQuery[ 'fbuilder' ][ 'modules' ] = fbuilderjQuery[ 'fbuilder' ][ 'modules' ] || {};
2311
2312fbuilderjQuery[ 'fbuilder' ][ 'modules' ][ 'energy' ] = {
2313	'prefix' : '',
2314	'callback' : function()
2315		{
2316			fbuilderjQuery[ 'fbuilder' ][ 'extend_window' ](fbuilderjQuery[ 'fbuilder' ][ 'modules' ][ 'energy' ][ 'prefix' ], CF_ENERGY);
2317		}
2318};/*
2319* managing_fields.js v0.1
2320* By: CALCULATED FIELD PROGRAMMERS
2321* The script allows managing fields
2322* Copyright 2015 CODEPEOPLE
2323* You may use this project under MIT or GPL licenses.
2324*/
2325
2326;(function(root){
2327	var lib = {
2328		formsDependency:{}
2329	},
2330	elements_equations = {};
2331	lib.cf_processing_version = '0.1';
2332
2333	/*** PRIVATE FUNCTIONS ***/
2334
2335	function _getForm(_form)
2336	{
2337		if(typeof _form == 'undefined' || _form == null){
2338			if('currentFormId' in fbuilderjQuery.fbuilder) _form = fbuilderjQuery.fbuilder.currentFormId;
2339			else return '_1';
2340		}
2341		if(/^_\d*$/.test(_form)) return _form;
2342		if(/^\d*$/.test(_form)) return '_'+_form;
2343		return $( $(_form).length ? _form : '#'+_form ).find('[name="cp_calculatedfieldsf_pform_psequence"]').val();
2344	}
2345
2346	function _getField( _field, _form )
2347	{
2348        try
2349        {
2350            if(typeof _field == 'undefined') return false;
2351            if(typeof _field == 'object')
2352            {
2353                if('ftype' in _field) return _field;
2354                if('jquery' in _field)
2355                {
2356                    if(_field.length) _field = _field[0];
2357                    else return false;
2358                }
2359
2360                if('getAttribute' in _field)
2361                {
2362					_form  = $(_field).closest('form');
2363                    var to_check = _field.getAttribute('class').match(/fieldname\d+/);
2364					if(to_check) _field = to_check[0];
2365					else {
2366						_field = _field.getAttribute('name').match(/fieldname\d+/)[0];
2367					}
2368                }
2369                else return false;
2370            }
2371			if ( typeof _field == 'string' && _field.match(/fieldname\d+(_\d+)/) ) _form = _field.match(/fieldname\d+(_\d+)/)[1];
2372            return $.fbuilder['forms'][_getForm(_form)].getItem(_field);
2373        } catch (err) { return false; }
2374	}
2375
2376	function _fillElementsArray( e ) {
2377		if ( ! ( e in elements_equations ) ) {
2378			elements_equations[e] = {};
2379			$( e ).on( 'change keyup', function() {
2380				for ( let i in elements_equations[e] ) {
2381					EVALEQUATION( i );
2382				}
2383			} );
2384		}
2385
2386		if ( 'currentEq' in $.fbuilder ) {
2387			if ( ! ( $.fbuilder['currentEq']['result'] in elements_equations[e] ) ) {
2388				elements_equations[e][ $.fbuilder['currentEq']['result'] ] = 1;
2389			}
2390		}
2391	}
2392
2393	/*** PUBLIC FUNCTIONS ***/
2394
2395	lib.ELEMENTINFO = function( selector, to_get ){
2396		let e = $( selector ),
2397			r = [];
2398
2399		to_get = ( new String( to_get || 'value' ) )
2400			.toLowerCase()
2401			.replace( /^\s*/, '')
2402			.replace( /\s*$/, '');
2403
2404		to_get = [ 'html', 'text' ].indexOf( to_get ) != -1 ? to_get : 'val';
2405
2406		if (e.length) {
2407			_fillElementsArray( selector );
2408			e.each( function( i, e ){
2409				r.push( $( e )[to_get]() );
2410			} );
2411		}
2412
2413		return r.length == 0 ? null : ( r.length ==  1 ? r[0] : r );
2414	};
2415
2416    lib.getField = function(_field, _form)
2417    {
2418		// To eval equations with fields from other forms
2419		var _fi = _getField(_field, _form), _fo;
2420		if(_fi){
2421			try{
2422				_fo = _fi['form_identifier'];
2423				if(
2424					_fo &&
2425					_fi &&
2426					'currentFormId' in $.fbuilder &&
2427					'currentEq' in $.fbuilder &&
2428					'identifier' in $.fbuilder['currentEq'] &&
2429					$.fbuilder['currentEq']['identifier'] != _fo
2430				){
2431					var _eqResultField = $.fbuilder[ 'currentEq' ][ 'result' ];
2432					if ( !( _fi.name in lib.formsDependency ) ) {
2433						lib.formsDependency[ _fi.name ] = {};
2434						$( '[name *= "' + _fi.name + '"]' ).on( 'change keyup depEvent', function(){
2435							var _fname = $(this).attr('name').match( /fieldname\d+_\d+/ )[0];
2436							if( _fname in lib.formsDependency ) {
2437								for( var i in lib.formsDependency[ _fname ] ) {
2438									EVALEQUATION(i, lib.formsDependency[ _fname ][ i ])
2439								}
2440							}
2441						} );
2442					}
2443					lib.formsDependency[ _fi.name ][ _eqResultField ] = $.fbuilder['currentFormId'];
2444				}
2445			} catch(err){}
2446		} else if(typeof _form != 'undefined') {
2447			if(
2448				'currentFormId' in $.fbuilder &&
2449				'currentEq' in $.fbuilder
2450			){
2451				var _eqResultField = $.fbuilder[ 'currentEq' ][ 'result' ];
2452				$(_form).on('change keyup depEvent', '[name*="'+_field+'"]', (
2453				    function(_field){
2454					    return function(){
2455						    EVALEQUATION(_field);
2456					    };
2457				    })(_eqResultField)
2458			    );
2459			}
2460		}
2461		// End
2462
2463        return _fi;
2464    };
2465
2466	lib.validform = lib.VALIDFORM = lib.ValidForm = function( _form, _silent ){
2467		_silent = _silent || false;
2468		var o = _getForm(_form), f;
2469		if(o){
2470			f = $('[id="'+$.fbuilder.forms[o]['formId']+'"]');
2471			if(f.length) {
2472				if (_silent) return f.validate().checkForm();
2473				else {
2474					let v = f.valid();
2475					$.fbuilder.openErrorDlg(f);
2476					return v;
2477				}
2478			}
2479		}
2480		return false;
2481	};
2482
2483	lib.validfield = lib.VALIDFIELD = lib.ValidField = function( _field, _form, _silent ){
2484		_silent = _silent || false;
2485		var o = _getForm(_form), f = _getField(_field, _form), j;
2486		if(f){
2487			j = f.jQueryRef().find(':input');
2488			if(j.length)
2489				return _silent ? j.closest('form').validate().check( j ) : j.valid();
2490			else return true;
2491		}
2492		return false;
2493	};
2494
2495	lib.activatefield = lib.ACTIVATEFIELD = function( _field, _form, _animate )
2496	{
2497		var o = _getForm(_form), f = _getField(_field, _form), j, k;
2498		if(f)
2499		{
2500			j = f.jQueryRef();
2501            j.removeClass('ignorefield');
2502            k = j.find('[id*="'+f.name+'"]');
2503			if(k.length && k.hasClass('ignore'))
2504			{
2505                j.add(j.find('.fields'))[_animate ? 'fadeIn' : 'show']();
2506				if(f.name in $.fbuilder.forms[o].toHide) delete $.fbuilder.forms[o].toHide[f.name];
2507				if(!(f.name in $.fbuilder.forms[o].toShow)) $.fbuilder.forms[o].toShow[f.name] = {'ref': {}};
2508				k.removeClass('ignore').trigger('change');
2509				$.fbuilder.showHideDep({'formIdentifier':o,'fieldIdentifier':f.name});
2510            } else if(!k.length) {
2511                j[_animate ? 'fadeIn' : 'show']();
2512            }
2513		}
2514	};
2515
2516	lib.ignorefield = lib.IGNOREFIELD = function( _field, _form )
2517	{
2518		var o = _getForm(_form), f = _getField(_field, _form), j, k;
2519		if(f)
2520		{
2521			j = f.jQueryRef();
2522            j.addClass('ignorefield');
2523            k = j.find('[id*="'+f.name+'"]');
2524			if(k.length && !k.hasClass('ignore'))
2525			{
2526				j.add(j.find('.fields')).hide();
2527				if(!(f.name in $.fbuilder.forms[o].toHide)) $.fbuilder.forms[o].toHide[f.name] = {};
2528				if(f.name in $.fbuilder.forms[o].toShow) delete $.fbuilder.forms[o].toShow[f.name];
2529				k.addClass('ignore').trigger('change');
2530				$.fbuilder.showHideDep({'formIdentifier':o,'fieldIdentifier':f.name});
2531            }
2532		}
2533	};
2534
2535    lib.isignored = lib.ISIGNORED = function( _field, _form )
2536	{
2537		var o = _getForm(_form), f = _getField(_field, _form), j;
2538		if(f) return 0 < f.jQueryRef().find('.ignore').length;
2539        return false;
2540	};
2541
2542    lib.readonlyfield = lib.READONLYFIELD = function( _field, _form )
2543    {
2544		if ( ! ( 'returnFalse' in $.fbuilder ) ) $.fbuilder.returnFalse = function(){return false;};
2545        var f = _getField(_field, _form), j;
2546		if(f)
2547		{
2548			j = f.jQueryRef();
2549			j.find('[id*="'+f.name+'"]').prop('readonly', true);
2550			j.find('*').on('click focus mousedown mouseup', $.fbuilder.returnFalse);
2551        }
2552    };
2553
2554	lib.editablefield = lib.EDITABLEFIELD = function( _field, _form )
2555    {
2556		if ( ! ( 'returnFalse' in $.fbuilder ) ) $.fbuilder.returnFalse = function(){return false;};
2557        var f = _getField(_field, _form), j;
2558		if(f)
2559		{
2560			j = f.jQueryRef();
2561			j.find('[id*="'+f.name+'"]').prop('readonly', false);
2562			j.find('*').off('click focus mousedown mouseup', $.fbuilder.returnFalse);
2563        }
2564    };
2565
2566	lib.isreadonly = lib.ISREADONLY = function( _field, _form )
2567    {
2568		let f = _getField(_field, _form), j, r = false;
2569		if(f)
2570		{
2571			r = true;
2572			j = f.jQueryRef();
2573			j.find('[id*="'+f.name+'"]').each(function() { if ( ! $(this).prop('readonly') ) r = false; });
2574        }
2575
2576		return r;
2577    };
2578
2579	lib.showfield = lib.SHOWFIELD = function( _field, _form, _animate )
2580    {
2581        var f = _getField(_field, _form), j;
2582		if(f) {
2583			j = f.jQueryRef();
2584            if(j.find('[id*="'+f.name+'"]').hasClass('ignore')) j = null;
2585        } else {
2586			try {
2587                if (typeof _form == 'string' && /_\d+/.test(_form)) _form = $('#cp_calculatedfieldsf_pform' + _form);
2588                j = $(_field, _form);
2589            } catch(err){};
2590		}
2591		if (j && j.length) j.css('display', 'none').removeClass('hide-strong hide')[_animate ? 'fadeIn' : 'show']();
2592    };
2593
2594	lib.hidefield = lib.HIDEFIELD = function( _field, _form )
2595    {
2596        let f = _getField(_field, _form), j;
2597		if (f) {
2598            j = f.jQueryRef();
2599            if(j.find('[id*="'+f.name+'"]').hasClass('ignore')) j = null;
2600		} else {
2601			try {
2602                if(typeof _form == 'string' && /_\d+/.test(_form)) _form = $('#cp_calculatedfieldsf_pform' + _form);
2603                j = $(_field, _form);
2604             } catch(err){};
2605		}
2606		if (j && j.length) j.addClass('hide-strong');
2607    };
2608
2609	lib.ishidden = lib.ISHIDDEN = function( _field, _form )
2610	{
2611		let f = _getField(_field, _form), j;
2612		if(f) j = f.jQueryRef();
2613		else {
2614			try {
2615                if (typeof _form == 'string' && /_\d+/.test(_form)) _form = $('#cp_calculatedfieldsf_pform' + _form);
2616                j = $(_field, _form);
2617             } catch(err){};
2618		}
2619		if (j && j.length) return j.is(':hidden');
2620        return true;
2621	};
2622
2623    lib.disableequations = lib.DISABLEEQUATIONS = function(f)
2624	{
2625		f = f || '_1';
2626		let _f = _getForm(f);
2627		fbuilderjQuery('[id="cp_calculatedfieldsf_pform' + _f + '"]').attr('data-evalequations',0);
2628	};
2629
2630	lib.disableequation = lib.DISABLEEQUATION = function(_field, _form)
2631	{
2632		var f = _getField(_field, _form);
2633		if(f && 'dynamicEval' in f) f.dynamicEval = false;
2634	};
2635
2636	lib.enableequations = lib.ENABLEEQUATIONS = function(f)
2637	{
2638		f = f || '_1';
2639		let _f = _getForm(f);
2640		fbuilderjQuery('[id="cp_calculatedfieldsf_pform' + _f + '"]').attr('data-evalequations',1);
2641	};
2642
2643	lib.enableequation = lib.ENABLEEQUATION = function(_field, _form)
2644	{
2645		var f = _getField(_field, _form);
2646		if(f && 'dynamicEval' in f) f.dynamicEval = true;
2647	};
2648
2649	lib.EVALEQUATIONS = lib.evalequations = function(f)
2650	{
2651		if( typeof f != 'undefined') {
2652			let _f = _getForm(f);
2653			fbuilderjQuery.fbuilder.calculator.defaultCalc('[id="cp_calculatedfieldsf_pform' + _f + '"]', false, true);
2654		} else {
2655			for( var i in fbuilderjQuery.fbuilder.forms ) {
2656				fbuilderjQuery.fbuilder.calculator.defaultCalc(fbuilderjQuery('[id="'+fbuilderjQuery.fbuilder.forms[i].formId+'"]'), false, true);
2657			}
2658		}
2659	};
2660
2661	lib.EVALEQUATION = lib.evalequation = function( _field, _form )
2662	{
2663        try
2664        {
2665            /* For compatibility with function( _form, _field ) */
2666            if(typeof _field == 'object' && 'tagName' in _field && _field.tagName == 'FORM')
2667                [_field, _form] = [_form, _field];
2668
2669            var c = fbuilderjQuery.fbuilder.calculator;
2670
2671            if(typeof _field == 'undefined') c.defaultCalc(_form);
2672
2673            var f = _getField(_field, _form),
2674                o = f.jQueryRef().closest('form')[0];
2675
2676            for(i in o.equations)
2677            {
2678                if(o.equations[i].result == f.name){
2679                    c.enqueueEquation(f.form_identifier, [o.equations[i]]);
2680                    c.processQueue(f.form_identifier);
2681                    return;
2682                }
2683            }
2684        }
2685        catch(err){if('console' in window) console.log(err);}
2686    };
2687
2688
2689    lib.COPYFIELDVALUE = lib.copyfieldvalue = function(_field, _form)
2690    {
2691        var f = _getField(_field, _form), j;
2692		if(f)
2693		{
2694			j = f.jQueryRef().find(':input:eq(0)');
2695			if(j.length)
2696			{
2697				try
2698				{
2699					if(j.is(':visible')) {
2700						j.select();
2701						document.execCommand('copy');
2702					} else navigator.clipboard.writeText(j.val());
2703				} catch(err){}
2704			}
2705		}
2706    };
2707
2708	function copyToClipboard(_field, _form, _html){
2709		_html = _html || false;
2710		if ( ! ( 'ClipboardItem' in window ) ) return;
2711        var f = _getField(_field, _form), h;
2712		if(f) {
2713			h = f.jQueryRef()[_html ? 'html' : 'text']();
2714		} else {
2715			try {
2716				f = $( _field );
2717				if ( f.length ) h = f[_html ? 'html' : 'text']();
2718			} catch ( err ) {}
2719		}
2720
2721		if(h) {
2722			const clipboardItem = new ClipboardItem({'text/html':  new Blob([h],{type: 'text/html'}), 'text/plain': new Blob([h], {type: 'text/plain'})});
2723    		navigator.clipboard.write([clipboardItem]).then(
2724				_ => { if( 'console' in window ) console.log("clipboard.write() Ok") },
2725				error => { if( 'console' in window ) console.log(error) }
2726			);
2727		}
2728	};
2729
2730    lib.COPYTEXT = lib.copytext = function(_field, _form){ copyToClipboard(_field, _form, false); };
2731    lib.COPYHTML = lib.copyhtml = function(_field, _form){ copyToClipboard(_field, _form, true); };
2732
2733    lib.gotopage = lib.GOTOPAGE = lib.goToPage = function(p, f)
2734    {
2735        try
2736        {
2737			var o = $('#'+$.fbuilder['forms'][_getForm(f)].formId), c;
2738            if(o.length)
2739            {
2740                let c = o.find('.pbreak:visible').attr('page'),
2741					m = o.find('.pbreak:last').attr('page');
2742
2743				p = Math.min(Math.max(p, 0),m);
2744                $.fbuilder.goToPage({'form':o,'from':c,'to':p, 'forcing' : true});
2745            }
2746        } catch(err) { if('console' in window) console.log(err); }
2747    };
2748
2749    lib.gotofield = lib.GOTOFIELD = lib.goToField = function(e, f)
2750    {
2751        try
2752        {
2753            var o = $('#'+$.fbuilder['forms'][_getForm(f)].formId), p, c;
2754			if(o.length)
2755            {
2756				e = o.find('[id*="'+(Number.isInteger(e) ? 'fieldname'+e : e)+'_"]');
2757				if(e.length)
2758				{
2759					c = o.find('.pbreak:visible').attr('page');
2760					p = e.closest('.pbreak').attr('page');
2761					$(document).one('cff-gotopage', function(evt, arg){
2762						if(e.is(':visible'))
2763							$('html,body').animate({scrollTop:e.offset().top});
2764					});
2765					$.fbuilder.goToPage({'form':o,'from':c,'to':p, 'forcing' : true});
2766				}
2767            }
2768        } catch(err) { if('console' in window) console.log(err); }
2769    };
2770
2771    if(window.PRINTFORM == undefined)
2772    {
2773        lib.printform = lib.PRINTFORM = function(show_pages, f)
2774        {
2775			f = _getForm(f);
2776			function addRemoveClasses(add){
2777				var o = $('#'+$.fbuilder['forms'][f].formId),
2778					m = add ? 'addClass' : 'removeClass';
2779				if(o.length)
2780				{
2781					o[m]('cff-print');
2782					if(!!show_pages) o.find('.pbreak')[m]('cff-print');
2783					while(o.length)
2784					{
2785						o.siblings()[m]('cff-no-print');
2786						o = o.parent();
2787					}
2788				}
2789
2790			};
2791			addRemoveClasses(true);
2792            window.print();
2793            setTimeout(function(){
2794				addRemoveClasses(false);
2795            }, 5000);
2796        };
2797
2798    }
2799
2800    lib.submitform = lib.SUBMITFORM = function(f)
2801    {
2802        if (typeof f != 'undefined') {
2803            let fObj = $(f);
2804            if (fObj.length && fObj[0].tagName == 'FORM') fObj.submit();
2805        } else if ( 'currentFormId' in $.fbuilder ) {
2806            $('[id="' + $.fbuilder.currentFormId + '"]').submit();
2807        }
2808    };
2809
2810	lib.RESETFORM = lib.resetform = function(f)
2811	{
2812		function _reset(f){
2813			try {
2814				if ( f.length && f[0].tagName == 'FORM' ) {
2815					if ( ! f.hasClass( 'cff-reset-form' ) ) {
2816						let seq = f.find('[name="cp_calculatedfieldsf_pform_psequence"]');
2817						if( seq.length ) {
2818							let fid = seq.val();
2819							f.find('.cff-calculated-field input').removeAttr('value');
2820							f[0].reset();
2821							setTimeout(
2822								function()
2823								{
2824									var id = f.attr('id');
2825									f.find('.select2-hidden-accessible').trigger('change');
2826									f.find(':data(manually)').removeData('manually');
2827									$.fbuilder['showHideDep']({ 'formIdentifier' : fid });
2828									$.fbuilder.forms[fid]['currentPage'] = 0;
2829									$("#fieldlist"+fid+" .pbreak").css("display","none");
2830									$("#fieldlist"+fid+" .pbreak").find(".field").addClass("ignorepb");
2831									$("#fieldlist"+fid+" .pb0").css("display","block");
2832
2833									if ($("#fieldlist"+fid+" .pb0").find(".field").length>0)
2834									{
2835										$("#fieldlist"+fid+" .pb0").find(".field").removeClass("ignorepb");
2836										try
2837										{
2838											let first_field = $("#fieldlist"+fid+" .pb0").find(".field:eq(0)");
2839											if ( first_field.hasClass('hasDatepicker') ) {
2840												first_field.datepicker( 'option', 'showOn', 'none' );
2841												first_field.trigger('focus');
2842												first_field.datepicker( 'option', 'showOn', 'focus' );
2843												first_field.trigger('blur');
2844											} else  first_field.trigger('focus');
2845										}
2846										catch(e){}
2847									}
2848									if(f.attr('data-evalequations')*1) {
2849										f.addClass( 'cff-reset-form' );
2850										$.fbuilder['calculator'].defaultCalc('#'+id, false);
2851										f.removeClass( 'cff-reset-form' );
2852									}
2853									f.find('.cpefb_error.message').remove();
2854									f.find('.cpefb_error').removeClass('cpefb_error');
2855                                    f.find(':input').trigger('cff-reset-field');
2856								},
2857								50
2858							);
2859
2860						}
2861					} else {
2862						setTimeout( function(){ f.removeClass( 'cff-reset-form' ); }, 500 );
2863					}
2864				}
2865			} catch ( err ) {}
2866		}
2867
2868		if( typeof f != 'undefined') {
2869			_reset(fbuilderjQuery(f));
2870		} else {
2871			for( var i in fbuilderjQuery.fbuilder.forms ) {
2872				_reset(fbuilderjQuery('[id="'+fbuilderjQuery.fbuilder.forms[i].formId+'"]'));
2873			}
2874		}
2875	};
2876
2877	if ( window.cffsanitize == undefined ) {
2878		lib.cffsanitize = lib.CFFSANITIZE = function( v, script_only ) {
2879			script_only = script_only || 0;
2880
2881			if (
2882				Array.isArray( v ) ||
2883				(
2884					typeof v === 'object' &&
2885					! Array.isArray( v ) &&
2886					v !== null
2887				)
2888			) {
2889				for ( var i in v ) {
2890					v[ i ] = lib.CFFSANITIZE( v[ i ], script_only );
2891				}
2892			} else {
2893				if ( typeof v == 'string' ) {
2894					if ( script_only ) {
2895						v = v.replace(/<script\b.*\bscript>/ig, '')
2896							 .replace(/<script[^>]*>/ig, '')
2897							 .replace(/(\b)(on[a-z]+)\s*=/ig, "$1_$2=");
2898					} else {
2899						v = fbuilderjQuery( '<p>' ).text( v ).html();
2900					}
2901				}
2902			}
2903
2904			return v;
2905		};
2906	}
2907
2908	root.CF_FIELDS_MANAGEMENT = lib;
2909
2910})(this);fbuilderjQuery = ( typeof fbuilderjQuery != 'undefined' ) ? fbuilderjQuery : jQuery;
2911fbuilderjQuery[ 'fbuilder' ] = fbuilderjQuery[ 'fbuilder' ] || {};
2912fbuilderjQuery[ 'fbuilder' ][ 'modules' ] = fbuilderjQuery[ 'fbuilder' ][ 'modules' ] || {};
2913
2914fbuilderjQuery[ 'fbuilder' ][ 'modules' ][ 'processing' ] = {
2915	'prefix' : '',
2916	'callback' : function()
2917		{
2918			fbuilderjQuery[ 'fbuilder' ][ 'extend_window' ]( fbuilderjQuery[ 'fbuilder' ][ 'modules' ][ 'processing' ][ 'prefix' ], CF_FIELDS_MANAGEMENT );
2919		}
2920};/*
2921* connector.js v0.1
2922* By: CALCULATED FIELD PROGRAMMERS
2923* Allows connecting with third party modules in the equations
2924* Copyright 2019 CODEPEOPLE
2925*/
2926
2927;(function(root){
2928	var lib = {
2929		records: {}
2930	};
2931
2932	/*** PRIVATE FUNCTIONS ***/
2933
2934	/*** PUBLIC FUNCTIONS ***/
2935
2936	lib.cff_connector_version = '0.1';
2937
2938	// cffProxy( function ) The function should accept a callback
2939	lib.cffProxy = lib.cffproxy = lib.CFFPROXY = function(){
2940        if(typeof fbuilderjQuery == 'undefined' || !arguments.length || typeof arguments[0] != 'function') return;
2941
2942		var $ 		= fbuilderjQuery,
2943			args	= Array.prototype.slice.call(arguments);
2944			index 	= args.toString();
2945
2946		if(typeof lib.records[index] != 'undefined') return lib.records[index];
2947		var	form_id = (typeof $.fbuilder['currentFormId'] != 'undefined') ? $.fbuilder['currentFormId'] : 'cp_calculatedfieldsf_pform_1',
2948			aux	= (function(eq, index){
2949				return function(value){
2950					lib.records[index] = value;
2951
2952					if ( typeof eq == 'object' && 'identifier' in eq ) {
2953						$.fbuilder.calculator.enqueueEquation(eq.identifier, [eq]);
2954						$.fbuilder.calculator.removePending(eq.identifier);
2955						if(
2956							!(eq.identifier in $.fbuilder.calculator.processing_queue) ||
2957							!$.fbuilder.calculator.processing_queue[eq.identifier]
2958						)
2959						{
2960							$.fbuilder.calculator.processQueue(eq.identifier);
2961						}
2962					}
2963				};
2964			})($.fbuilder['currentEq'], index),
2965			f = args[0];
2966
2967		args.shift();
2968		args.push(aux);
2969		if ( typeof $.fbuilder['currentEq'] == 'object' && 'identifier' in $.fbuilder['currentEq'] ) {
2970			$.fbuilder.calculator.addPending($.fbuilder['currentEq']['identifier']);
2971		}
2972        setTimeout(function(){f.apply(null, args);},5);
2973	};
2974
2975	root.CF_CONNECTOR = lib;
2976
2977})(this);fbuilderjQuery = ( typeof fbuilderjQuery != 'undefined' ) ? fbuilderjQuery : jQuery;
2978fbuilderjQuery[ 'fbuilder' ] = fbuilderjQuery[ 'fbuilder' ] || {};
2979fbuilderjQuery[ 'fbuilder' ][ 'modules' ] = fbuilderjQuery[ 'fbuilder' ][ 'modules' ] || {};
2980
2981fbuilderjQuery[ 'fbuilder' ][ 'modules' ][ 'connector' ] = {
2982	'prefix' : '',
2983	'callback' : function()
2984		{
2985			fbuilderjQuery[ 'fbuilder' ][ 'extend_window' ]( fbuilderjQuery[ 'fbuilder' ][ 'modules' ][ 'connector' ][ 'prefix' ], CF_CONNECTOR );
2986		}
2987};/*
2988* url.js v0.1
2989* By: CALCULATED FIELD PROGRAMMERS
2990* Includes operations to interact with the URLs and parameters
2991* Copyright 2020 CODEPEOPLE
2992*/
2993
2994;(function(root){
2995	var lib = {
2996		records: {}
2997	};
2998
2999	/*** PRIVATE FUNCTIONS ***/
3000
3001	/*** PUBLIC FUNCTIONS ***/
3002
3003	lib.cff_url_version = '0.1';
3004
3005	// getReferrer()
3006	lib.getReferrer = lib.getreferrer = lib.GETREFERRER = function(){
3007		return document.referrer || null;
3008	};
3009
3010	// generateURL()
3011	lib.generateURL = lib.generateurl = lib.GENERATEURL = function(url, params, hash){
3012		var urlComponents = url.split('#'), queryString = '', connector = '';
3013		if(typeof params == 'object' && params)
3014		{
3015			connector = (url.indexOf('?') == -1) ? '?' : '&';
3016			queryString = jQuery.param(params);
3017		}
3018		if(typeof hash == 'string') urlComponents[1] = hash;
3019		urlComponents[0] += connector+queryString;
3020		return urlComponents.join('#');
3021	};
3022
3023	// redirectToURL()
3024	lib.redirectToURL = lib.redirecttourl = lib.REDIRECTTOURL = function(url, obj, target){
3025		let $ = fbuilderjQuery,
3026			a = $('<a></a>');
3027
3028		target = target || '_self';
3029		url += ( obj ? (url.indexOf('?') === -1 ? '?' : '&')+$.param(obj) : '');
3030
3031		a.attr({'href': url, 'target': target});
3032		a.appendTo('body');
3033		a[0].click();
3034		a.remove();
3035	};
3036
3037	// getURL()
3038	lib.getURL = lib.geturl = lib.GETURL = function(){
3039		return document.location.href;
3040	};
3041
3042	// getURLProtocol()
3043	lib.getURLProtocol = lib.geturlprotocol = lib.GETURLPROTOCOL = function(){
3044		return document.location.protocol.toLowerCase();
3045	};
3046
3047	// getBaseURL()
3048	lib.getBaseURL = lib.getbaseurl = lib.GETBASEURL = function(){
3049		return window.top.location.protocol + '//' + window.top.location.host + '/';
3050	};
3051
3052	// getURLHash()
3053	lib.getURLHash = lib.geturlhash = lib.GETURLHASH = function(nohash){
3054		return window.top.location.hash.replace((nohash) ? /^#/ : '', '');
3055	};
3056
3057	// getURLPath()
3058	lib.getURLPath = lib.geturlpath = lib.GETURLPATH = function(noslash){
3059		return window.top.location.pathname.replace((noslash) ? new RegExp('^\/', 'g') : '', '').replace((noslash) ? new RegExp('\/$','g') : '', '');
3060	};
3061
3062	// getURLParameters(url) the url is optional
3063	lib.getURLParameters = lib.geturlparameters = lib.GETURLPARAMETERS = function(url){
3064		var qs = url ? url.split('?')[1] : window.top.location.search.slice(1),
3065			obj = {};
3066
3067		function aux (v, to_lower) {
3068			to_lower = to_lower || false;
3069			if ( Array.isArray(v) ) {
3070				for ( let i in v ) {
3071					v[i] = aux(v[i], to_lower);
3072				}
3073			} else if ( typeof v == 'string') return (to_lower ? decodeURIComponent(v).toLowerCase() : decodeURIComponent(v)).replace(/\+/g, ' ');
3074			return v;
3075		}
3076
3077		if(qs)
3078		{
3079			qs = qs.split('#')[0];
3080			var arr = qs.split('&');
3081			for (var i = 0; i < arr.length; i++)
3082			{
3083				var a = arr[i].split('='),
3084					paramName = a[0],
3085					paramValue = typeof (a[1]) === 'undefined' ? true : a[1];
3086
3087				paramName = aux(paramName, true);
3088				paramValue = aux(paramValue);
3089
3090				if (paramName.match(/\[(\d+)?\]$/))
3091				{
3092					var key = paramName.replace(/\[(\d+)?\]/, '');
3093					if (!obj[key]) obj[key] = [];
3094					if (paramName.match(/\[\d+\]$/))
3095					{
3096						var index = /\[(\d+)\]/.exec(paramName)[1];
3097						obj[key][index] = paramValue;
3098					}
3099					else
3100					{
3101						obj[key].push(paramValue);
3102					}
3103				}
3104				else
3105				{
3106					if (!obj[paramName])
3107					{
3108						obj[paramName] = paramValue;
3109					}
3110					else if (obj[paramName] && typeof obj[paramName] === 'string')
3111					{
3112						obj[paramName] = [obj[paramName]];
3113						obj[paramName].push(paramValue);
3114					}
3115					else
3116					{
3117						obj[paramName].push(paramValue);
3118					}
3119				}
3120			}
3121		}
3122		return obj;
3123	};
3124
3125	// getURLParameter(paramName, defaultValue) defaultValue is optional
3126	lib.getURLParameter = lib.geturlparameter = lib.GETURLPARAMETER = function(paramName, defaultValue){
3127		var parameters = lib.getURLParameters();
3128		paramName = paramName.toLowerCase();
3129		if(paramName in parameters) return parameters[paramName];
3130		else if(typeof defaultValue != 'undefined') return defaultValue;
3131		else return null;
3132	}
3133
3134	root.CF_URL = lib;
3135
3136})(this);fbuilderjQuery = ( typeof fbuilderjQuery != 'undefined' ) ? fbuilderjQuery : jQuery;
3137fbuilderjQuery[ 'fbuilder' ] = fbuilderjQuery[ 'fbuilder' ] || {};
3138fbuilderjQuery[ 'fbuilder' ][ 'modules' ] = fbuilderjQuery[ 'fbuilder' ][ 'modules' ] || {};
3139
3140fbuilderjQuery[ 'fbuilder' ][ 'modules' ][ 'url' ] = {
3141	'prefix' : '',
3142	'callback' : function()
3143		{
3144			fbuilderjQuery[ 'fbuilder' ][ 'extend_window' ](fbuilderjQuery[ 'fbuilder' ][ 'modules' ][ 'url' ][ 'prefix' ], CF_URL);
3145		}
3146};/*
3147* file.js v0.1
3148* By: CALCULATED FIELD PROGRAMMERS
3149* Includes operations to interact with the URLs and parameters
3150* Copyright 2020 CODEPEOPLE
3151*/
3152
3153;(function(root){
3154	var lib = {
3155		records: {}
3156	};
3157
3158	/*** PRIVATE FUNCTIONS ***/
3159
3160    function eval_equation(eq)
3161    {
3162		if ( typeof eq == 'object' && 'identifier' in eq ) {
3163			$.fbuilder.calculator.enqueueEquation(eq.identifier, [eq]);
3164			$.fbuilder.calculator.removePending(eq.identifier);
3165			if(
3166				!(eq.identifier in $.fbuilder.calculator.processing_queue) ||
3167				!$.fbuilder.calculator.processing_queue[eq.identifier]
3168			) $.fbuilder.calculator.processQueue(eq.identifier);
3169		}
3170    }
3171
3172	function _getField(fieldname, form)
3173    {
3174        var field = getField(fieldname, form);
3175        return (field && 'ftype' in field && field['ftype'] == 'ffile') ? field : false;
3176    }
3177
3178    /*** PUBLIC FUNCTIONS ***/
3179
3180	lib.cff_file_version = '0.1';
3181
3182	// PDFPAGESNUMBER(fieldname, form) the form parameter is optional
3183	lib.PDFPAGESNUMBER = lib.pdfpagesnumber = function(fieldname, form){
3184        var field = _getField(fieldname, form), files, counter = 0, result = 0, index;
3185        if(field)
3186        {
3187            if(field.multiple) result = [];
3188            files = field.val(true);
3189            counter = files.length;
3190
3191            function checkCounter(pages, multiple, eq){
3192                if(multiple) result.push(pages || 0);
3193                else result += pages || 0;
3194                counter--;
3195                if(counter <= 0)
3196                {
3197                    lib.records[index] = result;
3198                    eval_equation(eq);
3199                }
3200            }
3201
3202            if(counter)
3203            {
3204                index = 'PDFPAGESNUMBER:'+field.val();
3205                if(index in lib.records)
3206                {
3207                    result = lib.records[index];
3208                    /*delete lib.records[index];*/
3209                }
3210                else
3211                {
3212                    for(var i in files)
3213                    {
3214                        if(typeof files[i] == 'object')
3215                        {
3216                            var reader = new FileReader();
3217                            reader.onloadend = (function(eq, index, multiple){
3218                                return function(evt){
3219                                    var reader = evt.target, tmp = 0;
3220                                    try{
3221                                        try {
3222                                            let _arr = new Uint8Array(reader.result);
3223                                            const task = pdfjsLib.getDocument(_arr);
3224                                            task.promise.then((pdf) => {
3225                                                tmp = pdf.numPages;
3226                                                checkCounter(tmp, multiple, eq);
3227                                            });
3228                                        } catch(err){
3229                                            tmp = reader.result.match(/\/Type[\s]*\/Page[^s]/g);
3230                                            checkCounter(tmp.length, multiple, eq);
3231                                        }
3232                                    } catch (err) {}
3233                                };
3234                            })($.fbuilder['currentEq'], index, field.multiple)
3235                            reader.readAsArrayBuffer(files[i]);
3236                        }
3237                    }
3238                }
3239            }
3240        }
3241		return result;
3242	}
3243
3244    // IMGDIMENSION(fieldname, form) the form parameter is optional
3245	lib.IMGDIMENSION = lib.imgdimension = function(fieldname, form){
3246        var field = _getField(fieldname, form), files, counter = 0, result = {width:0, height:0}, index;
3247        if(field)
3248        {
3249            if(field.multiple) result = [];
3250            files = field.val(true);
3251            counter = files.length;
3252            if(counter)
3253            {
3254                index = 'IMGDIMENSION:'+field.val();
3255                if(index in lib.records)
3256                {
3257                    result = lib.records[index];
3258                    /*delete lib.records[index];*/
3259                }
3260                else
3261                {
3262                    for(var i in files)
3263                    {
3264                        if(typeof files[i] == 'object')
3265                        {
3266                            if(files[i].type.match(/image.*/i))
3267                            {
3268                                var reader = new FileReader();
3269                                reader.onloadend = (function(eq, index, multiple){
3270                                    return function(evt){
3271                                        var reader = evt.target;
3272                                        try{
3273                                            var image = new Image();
3274                                            image.onload = function(){
3275
3276                                                if(multiple) result.push({width:this.naturalWi
3276dth, height:this.naturalHeight});
3277                                                else result = {width:this.naturalWidth, height:this.naturalHeight};
3278
3279                                                counter--;
3280
3281                                                if(counter == 0)
3282                                                {
3283                                                    lib.records[index] = result;
3284                                                    eval_equation(eq);
3285                                                }
3286                                            };
3287                                            image.src = reader.result;
3288                                        } catch (err) {}
3289                                    };
3290                                })($.fbuilder['currentEq'], index, field.multiple)
3291                                reader.readAsDataURL(files[i]);
3292                            }
3293                            else counter--;
3294                        }
3295                    }
3296                }
3297            }
3298        }
3299		return result;
3300	}
3301
3302    // VIEWFILE(fieldname, id, form) the form parameter is optional
3303	lib.VIEWFILE = lib.viewfile = function(fieldname, id, form){
3304        var field = _getField(fieldname, form), files, el = document.getElementById(id);
3305        if(field && el)
3306        {
3307            el.innerHTML = '';
3308            files = field.val(true);
3309            if(files.length)
3310            {
3311                for(var i in files)
3312                {
3313                    if(typeof files[i] == 'object')
3314                    {
3315                        var reader = new FileReader();
3316                        if(files[i].type.match(/image.*/i))
3317                        {
3318                            reader.onloadend = function(evt){
3319                                var reader = evt.target;
3320                                try{
3321                                    var img = document.createElement('img');
3322                                    img.classList.add('cff-image-viewer');
3323                                    img.src = reader.result;
3324                                    el.appendChild(img);
3325                                } catch (err) {}
3326                            };
3327                        }
3328                        else if(files[i].type.match(/pdf/i))
3329                        {
3330                            reader.onloadend = function(evt){
3331                                var reader = evt.target;
3332                                try{
3333                                    var iframe = document.createElement('iframe');
3334                                    iframe.classList.add('cff-pdf-viewer');
3335                                    iframe.src = reader.result;
3336                                    el.appendChild(iframe);
3337                                } catch (err) {}
3338                            };
3339                        }
3340                        reader.readAsDataURL(files[i]);
3341                    }
3342                }
3343            }
3344        }
3345	}
3346
3347	// CSVTOJSON(fieldname or CSV String, args, form) the args, and form parameter are optional
3348	lib.CSVTOJSON = lib.csvtojson = function(fieldname, args, form){
3349        var result = null;
3350        if(typeof args == 'undefined' || args === null) args = {};
3351        if(!('headline'  in args)) args['headline'] = false;
3352        if(!('delimiter' in args)) args['delimiter'] = ',';
3353        if(!('quote' in args)) args['quote'] = '"';
3354
3355        function processCSV(csv) {
3356            var json = [],
3357                lines = csv.split(/[\r\n]+/),
3358                line,
3359                headers,
3360                obj;
3361            for( var i = 0, h = lines.length; i < h; i++) {
3362                if(!lines[i].length) continue;
3363                if(args['headline'] && typeof headers == 'undefined') {
3364                    headers = parseLine(lines[i]);
3365                } else {
3366                    obj = {};
3367                    line = parseLine(lines[i]);
3368                    for (var j = 0, k = line.length; j < k; j++) {
3369                        obj[ (typeof headers != 'undefined') ? headers[j] : j ] = line[j];
3370                    }
3371                    json.push(JSON.parse(JSON.stringify(obj)));
3372                }
3373            }
3374
3375            return json;
3376        };
3377
3378        function parseLine(line) {
3379            var flag = false, parts = [], cell = '';
3380            for(var i = 0, h = line.length; i < h; i++){
3381                if(line[i] == args['quote']) {
3382                    if(!flag && (i==0 || line[i-1] != '\\')) { flag = true; continue; }
3383                    else if(flag && line[i-1] != '\\') { flag = false; continue; }
3384                } else if(line[i] == args['delimiter'] && !flag){
3385                    parts.push(cell);
3386                    cell = '';
3387                    continue;
3388                }
3389                cell += line[i];
3390            }
3391            parts.push(cell);
3392            return parts;
3393        };
3394
3395        if ( typeof fieldname == 'number' || /fieldname\d+/i.test(fieldname) ) {
3396            var field   = _getField(fieldname, form),
3397                counter = 0,
3398                files;
3399
3400            if(field)
3401            {
3402                if(field.multiple) result = [];
3403
3404                files = field.val(true);
3405                counter = files.length;
3406                if(counter)
3407                {
3408                    index = 'CSVTOJSON:'+field.val();
3409                    if(index in lib.records)
3410                    {
3411                        result = lib.records[index];
3412                        /*delete lib.records[index];*/
3413                    }
3414                    else
3415                    {
3416                        for(var i in files)
3417                        {
3418                            if(typeof files[i] == 'object' && files[i].type.match(/csv.*/i))
3419                            {
3420                                var reader = new FileReader();
3421                                reader.onloadend = (function(eq, index, multiple){
3422                                    return function(evt){
3423                                        var reader = evt.target;
3424                                        try{
3425                                            var json = processCSV(reader.result);
3426                                            if(multiple) result.push(json);
3427                                            else result = json;
3428                                        } catch (err) {}
3429                                        counter--;
3430                                        if(counter == 0)
3431                                        {
3432                                            lib.records[index] = result;
3433                                            eval_equation(eq);
3434                                        }
3435                                    };
3436                                })($.fbuilder['currentEq'], index, field.multiple)
3437                                reader.readAsBinaryString(files[i]);
3438                            }
3439                        }
3440                    }
3441                }
3442            }
3443        } else if ( typeof fieldname == 'string' ) {
3444            result = processCSV( fieldname );
3445        }
3446
3447        return result;
3448	};
3449
3450    lib.JSONTOCSV = lib.jsontocsv = function( json, delimiter, file_name ){
3451
3452        function isObject( v ) {
3453            return typeof v == 'object' && Object.getPrototypeOf(v) === Object.prototype ? true : false;
3454        };
3455
3456        let arr = typeof json != 'object' ? JSON.parse( json ) : json,
3457            str = '',
3458            headers = [],
3459            row;
3460
3461        // Initialize parameters
3462        delimiter = delimiter || ',';
3463        file_name  = file_name || false;
3464
3465        for ( let i in arr ) {
3466            row = [];
3467
3468            // First record extract headers
3469            if ( 0 == i && isObject( arr[i] ) ) {
3470                headers = Object.getOwnPropertyNames( arr[i] );
3471                str += headers.join( delimiter ) + '\r\n';
3472            }
3473
3474            if ( isObject( arr[i] ) ) {
3475                row = Object.values( arr[i] );
3476            } else if( Array.isArray( arr[i] ) ) {
3477                row = arr[i];
3478            } else {
3479                row = [ arr[i] ];
3480            }
3481
3482            if ( row.length ) {
3483                str += row.join( delimiter ) + '\r\n';
3484            }
3485
3486        }
3487
3488        if ( str.length && file_name ) {
3489            let blob = new Blob([str], { type: 'text/csv' }),
3490                url = window.URL.createObjectURL(blob),
3491                a = document.createElement('a');
3492
3493            a.href = url;
3494            a.download = file_name;
3495            document.body.appendChild(a);
3496            a.click();
3497            document.body.removeChild(a);
3498        }
3499
3500        return str;
3501    };
3502
3503	root.CF_FILE = lib;
3504
3505})(this);fbuilderjQuery = ( typeof fbuilderjQuery != 'undefined' ) ? fbuilderjQuery : jQuery;
3506fbuilderjQuery[ 'fbuilder' ] = fbuilderjQuery[ 'fbuilder' ] || {};
3507fbuilderjQuery[ 'fbuilder' ][ 'modules' ] = fbuilderjQuery[ 'fbuilder' ][ 'modules' ] || {};
3508
3509fbuilderjQuery[ 'fbuilder' ][ 'modules' ][ 'file' ] = {
3510	'prefix' : '',
3511	'callback' : function()
3512		{
3513			fbuilderjQuery[ 'fbuilder' ][ 'extend_window' ](fbuilderjQuery[ 'fbuilder' ][ 'modules' ][ 'file' ][ 'prefix' ], CF_FILE);
3514		}
3515};/*
3516* text.js v0.1
3517* By: CALCULATED FIELD PROGRAMMERS
3518* Includes operations to interact with Texts
3519* Copyright 2022 CODEPEOPLE
3520*/
3521
3522;(function(root){
3523	var lib = {};
3524
3525	/*** PUBLIC FUNCTIONS ***/
3526
3527	if(window.WORDSCOUNTER == undefined) {
3528        lib.WORDSCOUNTER = lib.wordscounter = function(text){
3529            try {
3530                return text.replace(/(?!\w|\s)./g, '')
3531                            .replace(/\s+/g, ' ')
3532                            .replace(/^(\s*)([\W\w]*)(\b\s*$)/g, '$2')
3533                            .split(' ').length;
3534            } catch (err) {
3535                return 0;
3536            }
3537        }
3538    }
3539
3540    if(window.CHARSCOUNTER == undefined) {
3541        lib.CHARSCOUNTER = lib.charscounter = function(text, ignore_blank){
3542            try {
3543                var ignore_blank = ignore_blank || 0;
3544                text += '';
3545                if ( ignore_blank ) text = text.replace( /[\s\r\n\t]/g, '');
3546                return text.length;
3547            } catch (err) {
3548                return 0;
3549            }
3550        }
3551    }
3552
3553    if(window.INTEXT == undefined) {
3554        lib.INTEXT = lib.intext = function(term, text, case_insensitive){
3555            try {
3556                var case_insensitive = case_insensitive || 0;
3557                if( ! term instanceof RegExp ) term += '';
3558                text += '';
3559                if ( case_insensitive ) {
3560                    if( term instanceof RegExp ) term = new RegExp( term.source, 'i' );
3561                    else term = term.toLowerCase();
3562                    text = text.toLowerCase();
3563                }
3564                return Math.max(text.split(term).length - 1, 0);
3565            } catch (err) {
3566                return 0;
3567            }
3568        }
3569    }
3570
3571    if(window.CHARAT == undefined) {
3572        lib.CHARAT = lib.charat = function(text, index){
3573            try {
3574				index = index || 0;
3575                return String(text).charAt(index);
3576            } catch (err) {}
3577			return '';
3578        }
3579    }
3580
3581    if(window.CHARTOCODE == undefined) {
3582        lib.CHARTOCODE = lib.chartocode = function(text){
3583            try {
3584				return String(CHARAT(text)).charCodeAt(0);
3585            } catch (err) {}
3586			return false;
3587        }
3588    }
3589
3590    if(window.CODETOCHAR == undefined) {
3591        lib.CODETOCHAR = lib.codetochar = function(code){
3592            try {
3593				return String.fromCharCode(code);
3594            } catch (err) {}
3595			return false;
3596        }
3597    }
3598
3599    root.CF_TEXT = lib;
3600
3601})(this);fbuilderjQuery = ( typeof fbuilderjQuery != 'undefined' ) ? fbuilderjQuery : jQuery;
3602fbuilderjQuery[ 'fbuilder' ] = fbuilderjQuery[ 'fbuilder' ] || {};
3603fbuilderjQuery[ 'fbuilder' ][ 'modules' ] = fbuilderjQuery[ 'fbuilder' ][ 'modules' ] || {};
3604
3605fbuilderjQuery[ 'fbuilder' ][ 'modules' ][ 'text' ] = {
3606	'prefix' : '',
3607	'callback' : function()
3608		{
3609			fbuilderjQuery[ 'fbuilder' ][ 'extend_window' ](fbuilderjQuery[ 'fbuilder' ][ 'modules' ][ 'text' ][ 'prefix' ], CF_TEXT);
3610		}
3611};/*
3612 * location.js v0.1
3613 * By: CALCULATED FIELD PROGRAMMERS
3614 * Includes operations for users location based on timezone
3615 * Copyright 2022 CODEPEOPLE
3616 */
3617;
3618(function (root) {
3619    var lib = {},
3620        data = {"countries":{"AD":"Andorra","AE":"United Arab Emirates","AF":"Afghanistan","AG":"Antigua and Barbuda","AI":"Anguilla","AL":"Albania","AM":"Armenia","AO":"Angola","AQ":"Antarctica","AR":"Argentina","AS":"American Samoa","AT":"Austria","AU":"Australia","AW":"Aruba","AX":"Åland Islands","AZ":"Azerbaijan","BA":"Bosnia and Herzegovina","BB":"Barbados","BD":"Bangladesh","BE":"Belgium","BF":"Burkina Faso","BG":"Bulgaria","BH":"Bahrain","BI":"Burundi","BJ":"Benin","BL":"Saint Barthélemy","BM":"Bermuda","BN":"Brunei","BO":"Bolivia","BQ":"Caribbean Netherlands","BR":"Brazil","BS":"Bahamas","BT":"Bhutan","BV":"Bouvet Island","BW":"Botswana","BY":"Belarus","BZ":"Belize","CA":"Canada","CC":"Cocos Islands","CD":"Democratic Republic of the Congo","CF":"Central African Republic","CG":"Republic of the Congo","CH":"Switzerland","CI":"Ivory Coast","CK":"Cook Islands","CL":"Chile","CM":"Cameroon","CN":"China","CO":"Colombia","CR":"Costa Rica","CU":"Cuba","CV":"Cabo Verde","CW":"Curaçao","CX":"Christmas Island","CY":"Cyprus","CZ":"Czechia","DE":"Germany","DJ":"Djibouti","DK":"Denmark","DM":"Dominica","DO":"Dominican Republic","DZ":"Algeria","EC":"Ecuador","EE":"Estonia","EG":"Egypt","EH":"Western Sahara","ER":"Eritrea","ES":"Spain","ET":"Ethiopia","FI":"Finland","FJ":"Fiji","FK":"Falkland Islands","FM":"Micronesia","FO":"Faroe Islands","FR":"France","GA":"Gabon","GB":"United Kingdom","GD":"Grenada","GE":"Georgia","GF":"French Guiana","GG":"Guernsey","GH":"Ghana","GI":"Gibraltar","GL":"Greenland","GM":"Gambia","GN":"Guinea","GP":"Guadeloupe","GQ":"Equatorial Guinea","GR":"Greece","GS":"South Georgia and the South Sandwich Islands","GT":"Guatemala","GU":"Guam","GW":"Guinea-Bissau","GY":"Guyana","HK":"Hong Kong","HM":"Heard Island and McDonald Islands","HN":"Honduras","HR":"Croatia","HT":"Haiti","HU":"Hungary","ID":"Indonesia","IE":"Ireland","IL":"Israel","IM":"Isle of Man","IN":"India","IO":"British Indian Ocean Territory","IQ":"Iraq","IR":"Iran","IS":"Iceland","IT":"Italy","JE":"Jersey","JM":"Jamaica","JO":"Jordan","JP":"Japan","KE":"Kenya","KG":"Kyrgyzstan","KH":"Cambodia","KI":"Kiribati","KM":"Comoros","KN":"Saint Kitts and Nevis","KP":"North Korea","KR":"South Korea","KW":"Kuwait","KY":"Cayman Islands","KZ":"Kazakhstan","LA":"Laos","LB":"Lebanon","LC":"Saint Lucia","LI":"Liechtenstein","LK":"Sri Lanka","LR":"Liberia","LS":"Lesotho","LT":"Lithuania","LU":"Luxembourg","LV":"Latvia","LY":"Libya","MA":"Morocco","MC":"Monaco","MD":"Moldova","ME":"Montenegro","MF":"Saint Martin","MG":"Madagascar","MH":"Marshall Islands","MK":"North Macedonia","ML":"Mali","MM":"Myanmar","MN":"Mongolia","MO":"Macao","MP":"Northern Mariana Islands","MQ":"Martinique","MR":"Mauritania","MS":"Montserrat","MT":"Malta","MU":"Mauritius","MV":"Maldives","MW":"Malawi","MX":"Mexico","MY":"Malaysia","MZ":"Mozambique","NA":"Namibia","NC":"New Caledonia","NE":"Niger","NF":"Norfolk Island","NG":"Nigeria","NI":"Nicaragua","NL":"Netherlands","NO":"Norway","NP":"Nepal","NR":"Nauru","NU":"Niue","NZ":"New Zealand","OM":"Oman","PA":"Panama","PE":"Peru","PF":"French Polynesia","PG":"Papua New Guinea","PH":"Philippines","PK":"Pakistan","PL":"Poland","PM":"Saint Pierre and Miquelon","PN":"Pitcairn","PR":"Puerto Rico","PS":"Palestine","PT":"Portugal","PW":"Palau","PY":"Paraguay","QA":"Qatar","RE":"Réunion","RO":"Romania","RS":"Serbia","RU":"Russia","RW":"Rwanda","SA":"Saudi Arabia","SB":"Solomon Islands","SC":"Seychelles","SD":"Sudan","SE":"Sweden","SG":"Singapore","SH":"Saint Helena, Ascension and Tristan da Cunha","SI":"Slovenia","SJ":"Svalbard and Jan Mayen","SK":"Slovakia","SL":"Sierra Leone","SM":"San Marino","SN":"Senegal","SO":"Somalia","SR":"Suriname","SS":"South Sudan","ST":"Sao Tome and Principe","SV":"El Salvador","SX":"Sint Maarten","SY":"Syria","SZ":"Eswatini","TC":"Turks and Caicos Islands","TD":"Chad","TF":"French Southern Territories","TG":"Togo","TH":"Thailand","TJ":"Tajikistan","TK":"Tokelau","TL":"Timor-Leste","TM":"Turkmenistan","TN":"Tunisia","TO":"Tonga","TR":"Türkiye","TT":"Trinidad and Tobago","TV":"Tuvalu","TW":"Taiwan","TZ":"Tanzania","UA":"Ukraine","UG":"Uganda","UM":"United States Minor Outlying Islands","US":"United States of America","UY":"Uruguay","UZ":"Uzbekistan","VA":"Holy See","VC":"Saint Vincent and the Grenadines","VE":"Venezuela","VG":"Virgin Islands (UK)","VI":"Virgin Islands (US)","VN":"Vietnam","VU":"Vanuatu","WF":"Wallis and Futuna","WS":"Samoa","YE":"Yemen","YT":"Mayotte","ZA":"South Africa","ZM":"Zambia","ZW":"Zimbabwe"},"timezones":{"Africa/Abidjan":{"u":0,"c":["CI","BF","GH","GM","GN","IS","ML","MR","SH","SL","SN","TG"]},"Africa/Accra":{"a":"Africa/Abidjan","c":["GH"],"r":1},"Africa/Addis_Ababa":{"a":"Africa/Nairobi","c":["ET"],"r":1},"Africa/Algiers":{"u":60,"c":["DZ"]},"Africa/Asmara":{"a":"Africa/Nairobi","c":["ER"],"r":1},"Africa/Asmera":{"a":"Africa/Nairobi","c":["ER"],"r":1},"Africa/Bamako":{"a":"Africa/Abidjan","c":["ML"],"r":1},"Africa/Bangui":{"a":"Africa/Lagos","c":["CF"],"r":1},"Africa/Banjul":{"a":"Africa/Abidjan","c":["GM"],"r":1},"Africa/Bissau":{"u":0,"c":["GW"]},"Africa/Blantyre":{"a":"Africa/Maputo","c":["MW"],"r":1},"Africa/Brazzaville":{"a":"Africa/Lagos","c":["CG"],"r":1},"Africa/Bujumbura":{"a":"Africa/Maputo","c":["BI"],"r":1},"Africa/Cairo":{"u":120,"c":["EG"]},"Africa/Casablanca":{"u":60,"d":0,"c":["MA"]},"Africa/Ceuta":{"u":60,"d":120,"c":["ES"]},"Africa/Conakry":{"a":"Africa/Abidjan","c":["GN"],"r":1},"Africa/Dakar":{"a":"Africa/Abidjan","c":["SN"],"r":1},"Africa/Dar_es_Salaam":{"a":"Africa/Nairobi","c":["TZ"],"r":1},"Africa/Djibouti":{"a":"Africa/Nairobi","c":["DJ"],"r":1},"Africa/Douala":{"a":"Africa/Lagos","c":["CM"],"r":1},"Africa/El_Aaiun":{"u":60,"d":0,"c":["EH"]},"Africa/Freetown":{"a":"Africa/Abidjan","c":["SL"],"r":1},"Africa/Gaborone":{"a":"Africa/Maputo","c":["BW"],"r":1},"Africa/Harare":{"a":"Africa/Maputo","c":["ZW"],"r":1},"Africa/Johannesburg":{"u":120,"c":["ZA","LS","SZ"]},"Africa/Juba":{"u":120,"c":["SS"]},"Africa/Kampala":{"a":"Africa/Nairobi","c":["UG"],"r":1},"Africa/Khartoum":{"u":120,"c":["SD"]}
3620,"Africa/Kigali":{"a":"Africa/Maputo","c":["RW"],"r":1},"Africa/Kinshasa":{"a":"Africa/Lagos","c":["CD"],"r":1},"Africa/Lagos":{"u":60,"c":["NG","AO","BJ","CD","CF","CG","CM","GA","GQ","NE"]},"Africa/Libreville":{"a":"Africa/Lagos","c":["GA"],"r":1},"Africa/Lome":{"a":"Africa/Abidjan","c":["TG"],"r":1},"Africa/Luanda":{"a":"Africa/Lagos","c":["AO"],"r":1},"Africa/Lubumbashi":{"a":"Africa/Maputo","c":["CD"],"r":1},"Africa/Lusaka":{"a":"Africa/Maputo","c":["ZM"],"r":1},"Africa/Malabo":{"a":"Africa/Lagos","c":["GQ"],"r":1},"Africa/Maputo":{"u":120,"c":["MZ","BI","BW","CD","MW","RW","ZM","ZW"]},"Africa/Maseru":{"a":"Africa/Johannesburg","c":["LS"],"r":1},"Africa/Mbabane":{"a":"Africa/Johannesburg","c":["SZ"],"r":1},"Africa/Mogadishu":{"a":"Africa/Nairobi","c":["SO"],"r":1},"Africa/Monrovia":{"u":0,"c":["LR"]},"Africa/Nairobi":{"u":180,"c":["KE","DJ","ER","ET","KM","MG","SO","TZ","UG","YT"]},"Africa/Ndjamena":{"u":60,"c":["TD"]},"Africa/Niamey":{"a":"Africa/Lagos","c":["NE"],"r":1},"Africa/Nouakchott":{"a":"Africa/Abidjan","c":["MR"],"r":1},"Africa/Ouagadougou":{"a":"Africa/Abidjan","c":["BF"],"r":1},"Africa/Porto-Novo":{"a":"Africa/Lagos","c":["BJ"],"r":1},"Africa/Sao_Tome":{"u":0,"c":["ST"]},"Africa/Timbuktu":{"a":"Africa/Abidjan","c":["ML"],"r":1},"Africa/Tripoli":{"u":120,"c":["LY"]},"Africa/Tunis":{"u":60,"c":["TN"]},"Africa/Windhoek":{"u":120,"c":["NA"]},"America/Adak":{"u":-600,"d":-540,"c":["US"]},"America/Anchorage":{"u":-540,"d":-480,"c":["US"]},"America/Anguilla":{"a":"America/Puerto_Rico","c":["AI"],"r":1},"America/Antigua":{"a":"America/Puerto_Rico","c":["AG"],"r":1},"America/Araguaina":{"u":-180,"c":["BR"]},"America/Argentina/Buenos_Aires":{"u":-180,"c":["AR"]},"America/Argentina/Catamarca":{"u":-180,"c":["AR"]},"America/Argentina/ComodRivadavia":{"a":"America/Argentina/Catamarca","r":1},"America/Argentina/Cordoba":{"u":-180,"c":["AR"]},"America/Argentina/Jujuy":{"u":-180,"c":["AR"]},"America/Argentina/La_Rioja":{"u":-180,"c":["AR"]},"America/Argentina/Mendoza":{"u":-180,"c":["AR"]},"America/Argentina/Rio_Gallegos":{"u":-180,"c":["AR"]},"America/Argentina/Salta":{"u":-180,"c":["AR"]},"America/Argentina/San_Juan":{"u":-180,"c":["AR"]},"America/Argentina/San_Luis":{"u":-180,"c":["AR"]},"America/Argentina/Tucuman":{"u":-180,"c":["AR"]},"America/Argentina/Ushuaia":{"u":-180,"c":["AR"]},"America/Aruba":{"a":"America/Puerto_Rico","c":["AW"],"r":1},"America/Asuncion":{"u":-240,"d":-180,"c":["PY"]},"America/Atikokan":{"a":"America/Panama","c":["CA"],"r":1},"America/Atka":{"a":"America/Adak","r":1},"America/Bahia":{"u":-180,"c":["BR"]},"America/Bahia_Banderas":{"u":-360,"c":["MX"]},"America/Barbados":{"u":-240,"c":["BB"]},"America/Belem":{"u":-180,"c":["BR"]},"America/Belize":{"u":-360,"c":["BZ"]},"America/Blanc-Sablon":{"a":"America/Puerto_Rico","c":["CA"],"r":1},"America/Boa_Vista":{"u":-240,"c":["BR"]},"America/Bogota":{"u":-300,"c":["CO"]},"America/Boise":{"u":-420,"d":-360,"c":["US"]},"America/Buenos_Aires":{"a":"America/Argentina/Buenos_Aires","r":1},"America/Cambridge_Bay":{"u":-420,"d":-360,"c":["CA"]},"America/Campo_Grande":{"u":-240,"c":["BR"]},"America/Cancun":{"u":-300,"c":["MX"]},"America/Caracas":{"u":-240,"c":["VE"]},"America/Catamarca":{"a":"America/Argentina/Catamarca","r":1},"America/Cayenne":{"u":-180,"c":["GF"]},"America/Cayman":{"a":"America/Panama","c":["KY"],"r":1},"America/Chicago":{"u":-360,"d":-300,"c":["US"]},"America/Chihuahua":{"u":-360,"c":["MX"]},"America/Ciudad_Juarez":{"u":-420,"d":-360,"c":["MX"]},"America/Coral_Harbour":{"a":"America/Panama","c":["CA"],"r":1},"America/Cordoba":{"a":"America/Argentina/Cordoba","r":1},"America/Costa_Rica":{"u":-360,"c":["CR"]},"America/Creston":{"a":"America/Phoenix","c":["CA"],"r":1},"America/Cuiaba":{"u":-240,"c":["BR"]},"America/Curacao":{"a":"America/Puerto_Rico","c":["CW"],"r":1},"America/Danmarkshavn":{"u":0,"c":["GL"]},"America/Dawson":{"u":-420,"c":["CA"]},"America/Dawson_Creek":{"u":-420,"c":["CA"]},"America/Denver":{"u":-420,"d":-360,"c":["US"]},"America/Detroit":{"u":-300,"d":-240,"c":["US"]},"America/Dominica":{"a":"America/Puerto_Rico","c":["DM"],"r":1},"America/Edmonton":{"u":-420,"d":-360,"c":["CA"]},"America/Eirunepe":{"u":-300,"c":["BR"]},"America/El_Salvador":{"u":-360,"c":["SV"]},"America/Ensenada":{"a":"America/Tijuana","r":1},"America/Fort_Nelson":{"u":-420,"c":["CA"]},"America/Fort_Wayne":{"a":"America/Indiana/Indianapolis","r":1},"America/Fortaleza":{"u":-180,"c":["BR"]},"America/Glace_Bay":{"u":-240,"d":-180,"c":["CA"]},"America/Godthab":{"a":"America/Nuuk","r":1},"America/Goose_Bay":{"u":-240,"d":-180,"c":["CA"]},"America/Grand_Turk":{"u":-300,"d":-240,"c":["TC"]},"America/Grenada":{"a":"America/Puerto_Rico","c":["GD"],"r":1},"America/Guadeloupe":{"a":"America/Puerto_Rico","c":["GP"],"r":1},"America/Guatemala":{"u":-360,"c":["GT"]},"America/Guayaquil":{"u":-300,"c":["EC"]},"America/Guyana":{"u":-240,"c":["GY"]},"America/Halifax":{"u":-240,"d":-180,"c":["CA"]},"America/Havana":{"u":-300,"d":-240,"c":["CU"]},"America/Hermosillo":{"u":-420,"c":["MX"]},"America/Indiana/Indianapolis":{"u":-300,"d":-240,"c":["US"]},"America/Indiana/Knox":{"u":-360,"d":-300,"c":["US"]},"America/Indiana/Marengo":{"u":-300,"d":-240,"c":["US"]},"America/Indiana/Petersburg":{"u":-300,"d":-240,"c":["US"]},"America/Indiana/Tell_City":{"u":-360,"d":-300,"c":["US"]},"America/Indiana/Vevay":{"u":-300,"d":-240,"c":["US"]},"America/Indiana/Vincennes":{"u":-300,"d":-240,"c":["US"]},"America/Indiana/Winamac":{"u":-300,"d":-240,"c":["US"]},"America/Indianapolis":{"a":"America/Indiana/Indianapolis","r":1},"America/Inuvik":{"u":-420,"d":-360,"c":["CA"]},"America/Iqaluit":{"u":-300,"d":-240,"c":["CA"]},"America/Jamaica":{"u":-300,"c":["JM"]},"America/Jujuy":{"a":"America/Argentina/Jujuy","r":1},"America/Juneau":{"u":-540,"d":-480,"c":["US"]},"America/Kentucky/Louisville":{"u":-300,"d":-240,"c":["US"]},"America/Kentucky/Monticello":{"u":-300,"d":-240,"c":["US"]},"America/Knox_IN":{"a":"America/Indiana/Knox","r":1},"America/Kralendijk":{"a":"America/Puerto_Rico","c":["BQ"],"r":1},"America/La_Paz":{"u":-240,"c":["BO"]},"America/Lima":{"u":-300,"c":["PE"]},"America/Los_Angeles":{"u":-480,"d":-420,"c":["US"]},"America/Louisville":{"a":"America/Kentucky/Louisville","r":1},"America/Lower_Princes":{"a":"America/Puerto_Rico","c":["SX"],"r":1},"America/Maceio":{"u":-180,"c":["BR"]},"America/Managua":{"u":-360,"c":["NI"]},"America/Manaus":{"u":-240,"c":["BR"]},"America/Marigot":{"a":"America/Puerto_Rico","c":["MF"],"r":1},"America/Martinique":{"u":-240,"c":["MQ"]},"America/Matamoros":{"u":-360,"d":-300,"c":["MX"]},"America/Mazatlan":{"u":-420,"c":["MX"]},"America/Mendoza":{"a":"America/Argentina/Mendoza","r":1},"America/Menominee":{"u":-360,"d":-300,"c":["US"]},"America/Merida":{"u":-360,"c":["MX"]},"America/Metlakatla":{"u":-540,"d":-480,"c":["US"]},"America/Mexico_City":{"u":-360,"c":["MX"]},"America/Miquelon":{"u":-180,"d":-120,"c":["PM"]},"America/Moncton":{"u":-240,"d":-180,"c":["CA"]},"America/Monterrey":{"u":-360,"c":["MX"]},"America/Montevideo":{"u":-180,"c":["UY"]},"America/Montreal":{"a":"America/Toronto","c":["CA"],"r":1},"America/Montserrat":{"a":"America/Puerto_Rico","c":["MS"],"r":1},"America/Nassau":{"a":"America/Toronto","c":["BS"],"r":1}
3620,"America/New_York":{"u":-300,"d":-240,"c":["US"]},"America/Nipigon":{"a":"America/Toronto","c":["CA"],"r":1},"America/Nome":{"u":-540,"d":-480,"c":["US"]},"America/Noronha":{"u":-120,"c":["BR"]},"America/North_Dakota/Beulah":{"u":-360,"d":-300,"c":["US"]},"America/North_Dakota/Center":{"u":-360,"d":-300,"c":["US"]},"America/North_Dakota/New_Salem":{"u":-360,"d":-300,"c":["US"]},"America/Nuuk":{"u":-180,"c":["GL"]},"America/Ojinaga":{"u":-360,"d":-300,"c":["MX"]},"America/Panama":{"u":-300,"c":["PA","CA","KY"]},"America/Pangnirtung":{"a":"America/Iqaluit","r":1},"America/Paramaribo":{"u":-180,"c":["SR"]},"America/Phoenix":{"u":-420,"c":["US","CA"]},"America/Port-au-Prince":{"u":-300,"d":-240,"c":["HT"]},"America/Port_of_Spain":{"a":"America/Puerto_Rico","c":["TT"],"r":1},"America/Porto_Acre":{"a":"America/Rio_Branco","r":1},"America/Porto_Velho":{"u":-240,"c":["BR"]},"America/Puerto_Rico":{"u":-240,"c":["PR","AG","CA","AI","AW","BL","BQ","CW","DM","GD","GP","KN","LC","MF","MS","SX","TT","VC","VG","VI"]},"America/Punta_Arenas":{"u":-180,"c":["CL"]},"America/Rainy_River":{"a":"America/Winnipeg","r":1},"America/Rankin_Inlet":{"u":-360,"d":-300,"c":["CA"]},"America/Recife":{"u":-180,"c":["BR"]},"America/Regina":{"u":-360,"c":["CA"]},"America/Resolute":{"u":-360,"d":-300,"c":["CA"]},"America/Rio_Branco":{"u":-300,"c":["BR"]},"America/Rosario":{"a":"America/Argentina/Cordoba","r":1},"America/Santa_Isabel":{"a":"America/Tijuana","r":1},"America/Santarem":{"u":-180,"c":["BR"]},"America/Santiago":{"u":-240,"d":-180,"c":["CL"]},"America/Santo_Domingo":{"u":-240,"c":["DO"]},"America/Sao_Paulo":{"u":-180,"c":["BR"]},"America/Scoresbysund":{"u":-60,"d":0,"c":["GL"]},"America/Shiprock":{"a":"America/Denver","r":1},"America/Sitka":{"u":-540,"d":-480,"c":["US"]},"America/St_Barthelemy":{"a":"America/Puerto_Rico","c":["BL"],"r":1},"America/St_Johns":{"u":-210,"d":-150,"c":["CA"]},"America/St_Kitts":{"a":"America/Puerto_Rico","c":["KN"],"r":1},"America/St_Lucia":{"a":"America/Puerto_Rico","c":["LC"],"r":1},"America/St_Thomas":{"a":"America/Puerto_Rico","c":["VI"],"r":1},"America/St_Vincent":{"a":"America/Puerto_Rico","c":["VC"],"r":1},"America/Swift_Current":{"u":-360,"c":["CA"]},"America/Tegucigalpa":{"u":-360,"c":["HN"]},"America/Thule":{"u":-240,"d":-180,"c":["GL"]},"America/Thunder_Bay":{"a":"America/Toronto","c":["CA"],"r":1},"America/Tijuana":{"u":-480,"d":-420,"c":["MX"]},"America/Toronto":{"u":-300,"d":-240,"c":["CA","BS"]},"America/Tortola":{"a":"America/Puerto_Rico","c":["VG"],"r":1},"America/Vancouver":{"u":-480,"d":-420,"c":["CA"]},"America/Virgin":{"a":"America/Puerto_Rico","c":["VI"],"r":1},"America/Whitehorse":{"u":-420,"c":["CA"]},"America/Winnipeg":{"u":-360,"d":-300,"c":["CA"]},"America/Yakutat":{"u":-540,"d":-480,"c":["US"]},"America/Yellowknife":{"u":-420,"d":-360,"c":["CA"]},"Antarctica/Casey":{"u":660,"c":["AQ"]},"Antarctica/Davis":{"u":420,"c":["AQ"]},"Antarctica/DumontDUrville":{"a":"Pacific/Port_Moresby","c":["AQ"],"r":1},"Antarctica/Macquarie":{"u":600,"d":660,"c":["AU"]},"Antarctica/Mawson":{"u":300,"c":["AQ"]},"Antarctica/McMurdo":{"a":"Pacific/Auckland","c":["AQ"],"r":1},"Antarctica/Palmer":{"u":-180,"c":["AQ"]},"Antarctica/Rothera":{"u":-180,"c":["AQ"]},"Antarctica/South_Pole":{"a":"Pacific/Auckland","c":["AQ"],"r":1},"Antarctica/Syowa":{"a":"Asia/Riyadh","c":["AQ"],"r":1},"Antarctica/Troll":{"u":0,"d":120,"c":["AQ"]},"Antarctica/Vostok":{"a":"Asia/Urumqi","c":["AQ"],"r":1},"Arctic/Longyearbyen":{"a":"Europe/Berlin","c":["SJ"],"r":1},"Asia/Aden":{"a":"Asia/Riyadh","c":["YE"],"r":1},"Asia/Almaty":{"u":360,"c":["KZ"]},"Asia/Amman":{"u":180,"c":["JO"]},"Asia/Anadyr":{"u":720,"c":["RU"]},"Asia/Aqtau":{"u":300,"c":["KZ"]},"Asia/Aqtobe":{"u":300,"c":["KZ"]},"Asia/Ashgabat":{"u":300,"c":["TM"]},"Asia/Ashkhabad":{"a":"Asia/Ashgabat","r":1},"Asia/Atyrau":{"u":300,"c":["KZ"]},"Asia/Baghdad":{"u":180,"c":["IQ"]},"Asia/Bahrain":{"a":"Asia/Qatar","c":["BH"],"r":1},"Asia/Baku":{"u":240,"c":["AZ"]},"Asia/Bangkok":{"u":420,"c":["TH","CX","KH","LA","VN"]},"Asia/Barnaul":{"u":420,"c":["RU"]},"Asia/Beirut":{"u":120,"d":180,"c":["LB"]},"Asia/Bishkek":{"u":360,"c":["KG"]},"Asia/Brunei":{"a":"Asia/Kuching","c":["BN"],"r":1},"Asia/Calcutta":{"a":"Asia/Kolkata","r":1},"Asia/Chita":{"u":540,"c":["RU"]},"Asia/Choibalsan":{"u":480,"c":["MN"]},"Asia/Chongqing":{"a":"Asia/Shanghai","r":1},"Asia/Chungking":{"a":"Asia/Shanghai","r":1},"Asia/Colombo":{"u":330,"c":["LK"]},"Asia/Dacca":{"a":"Asia/Dhaka","r":1},"Asia/Damascus":{"u":180,"c":["SY"]},"Asia/Dhaka":{"u":360,"c":["BD"]},"Asia/Dili":{"u":540,"c":["TL"]},"Asia/Dubai":{"u":240,"c":["AE","OM","RE","SC","TF"]},"Asia/Dushanbe":{"u":300,"c":["TJ"]},"Asia/Famagusta":{"u":120,"d":180,"c":["CY"]},"Asia/Gaza":{"u":120,"d":180,"c":["PS"]},"Asia/Harbin":{"a":"Asia/Shanghai","r":1},"Asia/Hebron":{"u":120,"d":180,"c":["PS"]},"Asia/Ho_Chi_Minh":{"u":420,"c":["VN"]},"Asia/Hong_Kong":{"u":480,"c":["HK"]},"Asia/Hovd":{"u":420,"c":["MN"]},"Asia/Irkutsk":{"u":480,"c":["RU"]},"Asia/Istanbul":{"a":"Europe/Istanbul","r":1},"Asia/Jakarta":{"u":420,"c":["ID"]},"Asia/Jayapura":{"u":540,"c":["ID"]},"Asia/Jerusalem":{"u":120,"d":180,"c":["IL"]},"Asia/Kabul":{"u":270,"c":["AF"]},"Asia/Kamchatka":{"u":720,"c":["RU"]},"Asia/Karachi":{"u":300,"c":["PK"]},"Asia/Kashgar":{"a":"Asia/Urumqi","c":["CN"],"r":1},"Asia/Kathmandu":{"u":345,"c":["NP"]},"Asia/Katmandu":{"a":"Asia/Kathmandu","r":1},"Asia/Khandyga":{"u":540,"c":["RU"]},"Asia/Kolkata":{"u":330,"c":["IN"]},"Asia/Krasnoyarsk":{"u":420,"c":["RU"]},"Asia/Kuala_Lumpur":{"a":"Asia/Singapore","c":["MY"],"r":1},"Asia/Kuching":{"u":480,"c":["MY","BN"]},"Asia/Kuwait":{"a":"Asia/Riyadh","c":["KW"],"r":1},"Asia/Macao":{"a":"Asia/Macau","r":1},"Asia/Macau":{"u":480,"c":["MO"]},"Asia/Magadan":{"u":660,"c":["RU"]},"Asia/Makassar":{"u":480,"c":["ID"]},"Asia/Manila":{"u":480,"c":["PH"]},"Asia/Muscat":{"a":"Asia/Dubai","c":["OM"],"r":1},"Asia/Nicosia":{"u":120,"d":180,"c":["CY"]},"Asia/Novokuznetsk":{"u":420,"c":["RU"]},"Asia/Novosibirsk":{"u":420,"c":["RU"]},"Asia/Omsk":{"u":360,"c":["RU"]},"Asia/Oral":{"u":300,"c":["KZ"]},"Asia/Phnom_Penh":{"a":"Asia/Bangkok","c":["KH"],"r":1},"Asia/Pontianak":{"u":420,"c":["ID"]},"Asia/Pyongyang":{"u":540,"c":["KP"]},"Asia/Qatar":{"u":180,"c":["QA","BH"]},"Asia/Qostanay":{"u":360,"c":["KZ"]},"Asia/Qyzylorda":{"u":300,"c":["KZ"]},"Asia/Rangoon":{"a":"Asia/Yangon","c":["MM"],"r":1},"Asia/Riyadh":{"u":180,"c":["SA","AQ","KW","YE"]},"Asia/Saigon":{"a":"Asia/Ho_Chi_Minh","r":1},"Asia/Sakhalin":{"u":660,"c":["RU"]},"Asia/Samarkand":{"u":300,"c":["UZ"]},"Asia/Seoul":{"u":540,"c":["KR"]},"Asia/Shanghai":{"u":480,"c":["CN"]},"Asia/Singapore":{"u":480,"c":["SG","MY"]},"Asia/Srednekolymsk":{"u":660,"c":["RU"]},"Asia/Taipei":{"u":480,"c":["TW"]}
3620,"Asia/Tashkent":{"u":300,"c":["UZ"]},"Asia/Tbilisi":{"u":240,"c":["GE"]},"Asia/Tehran":{"u":210,"c":["IR"]},"Asia/Tel_Aviv":{"a":"Asia/Jerusalem","r":1},"Asia/Thimbu":{"a":"Asia/Thimphu","r":1},"Asia/Thimphu":{"u":360,"c":["BT"]},"Asia/Tokyo":{"u":540,"c":["JP"]},"Asia/Tomsk":{"u":420,"c":["RU"]},"Asia/Ujung_Pandang":{"a":"Asia/Makassar","r":1},"Asia/Ulaanbaatar":{"u":480,"c":["MN"]},"Asia/Ulan_Bator":{"a":"Asia/Ulaanbaatar","r":1},"Asia/Urumqi":{"u":360,"c":["CN","AQ"]},"Asia/Ust-Nera":{"u":600,"c":["RU"]},"Asia/Vientiane":{"a":"Asia/Bangkok","c":["LA"],"r":1},"Asia/Vladivostok":{"u":600,"c":["RU"]},"Asia/Yakutsk":{"u":540,"c":["RU"]},"Asia/Yangon":{"u":390,"c":["MM","CC"]},"Asia/Yekaterinburg":{"u":300,"c":["RU"]},"Asia/Yerevan":{"u":240,"c":["AM"]},"Atlantic/Azores":{"u":-60,"d":0,"c":["PT"]},"Atlantic/Bermuda":{"u":-240,"d":-180,"c":["BM"]},"Atlantic/Canary":{"u":0,"d":60,"c":["ES"]},"Atlantic/Cape_Verde":{"u":-60,"c":["CV"]},"Atlantic/Faeroe":{"a":"Atlantic/Faroe","r":1},"Atlantic/Faroe":{"u":0,"d":60,"c":["FO"]},"Atlantic/Jan_Mayen":{"a":"Europe/Berlin","c":["SJ"],"r":1},"Atlantic/Madeira":{"u":0,"d":60,"c":["PT"]},"Atlantic/Reykjavik":{"a":"Africa/Abidjan","c":["IS"],"r":1},"Atlantic/South_Georgia":{"u":-120,"c":["GS"]},"Atlantic/St_Helena":{"a":"Africa/Abidjan","c":["SH"],"r":1},"Atlantic/Stanley":{"u":-180,"c":["FK"]},"Australia/ACT":{"a":"Australia/Sydney","r":1},"Australia/Adelaide":{"u":570,"d":630,"c":["AU"]},"Australia/Brisbane":{"u":600,"c":["AU"]},"Australia/Broken_Hill":{"u":570,"d":630,"c":["AU"]},"Australia/Canberra":{"a":"Australia/Sydney","r":1},"Australia/Currie":{"a":"Australia/Hobart","r":1},"Australia/Darwin":{"u":570,"c":["AU"]},"Australia/Eucla":{"u":525,"c":["AU"]},"Australia/Hobart":{"u":600,"d":660,"c":["AU"]},"Australia/LHI":{"a":"Australia/Lord_Howe","r":1},"Australia/Lindeman":{"u":600,"c":["AU"]},"Australia/Lord_Howe":{"u":630,"d":660,"c":["AU"]},"Australia/Melbourne":{"u":600,"d":660,"c":["AU"]},"Australia/NSW":{"a":"Australia/Sydney","r":1},"Australia/North":{"a":"Australia/Darwin","r":1},"Australia/Perth":{"u":480,"c":["AU"]},"Australia/Queensland":{"a":"Australia/Brisbane","r":1},"Australia/South":{"a":"Australia/Adelaide","r":1},"Australia/Sydney":{"u":600,"d":660,"c":["AU"]},"Australia/Tasmania":{"a":"Australia/Hobart","r":1},"Australia/Victoria":{"a":"Australia/Melbourne","r":1},"Australia/West":{"a":"Australia/Perth","r":1},"Australia/Yancowinna":{"a":"Australia/Broken_Hill","r":1},"Brazil/Acre":{"a":"America/Rio_Branco","r":1},"Brazil/DeNoronha":{"a":"America/Noronha","r":1},"Brazil/East":{"a":"America/Sao_Paulo","r":1},"Brazil/West":{"a":"America/Manaus","r":1},"CET":{"u":60,"d":120},"CST6CDT":{"u":-360,"d":-300},"Canada/Atlantic":{"a":"America/Halifax","r":1},"Canada/Central":{"a":"America/Winnipeg","r":1},"Canada/Eastern":{"a":"America/Toronto","c":["CA"],"r":1},"Canada/Mountain":{"a":"America/Edmonton","r":1},"Canada/Newfoundland":{"a":"America/St_Johns","r":1},"Canada/Pacific":{"a":"America/Vancouver","r":1},"Canada/Saskatchewan":{"a":"America/Regina","r":1},"Canada/Yukon":{"a":"America/Whitehorse","r":1},"Chile/Continental":{"a":"America/Santiago","r":1},"Chile/EasterIsland":{"a":"Pacific/Easter","r":1},"Cuba":{"a":"America/Havana","r":1},"EET":{"u":120,"d":180},"EST":{"u":-300},"EST5EDT":{"u":-300,"d":-240},"Egypt":{"a":"Africa/Cairo","r":1},"Eire":{"a":"Europe/Dublin","r":1},"Etc/GMT":{"u":0},"Etc/GMT+0":{"a":"Etc/GMT","r":1},"Etc/GMT+1":{"u":-60},"Etc/GMT+10":{"u":-600},"Etc/GMT+11":{"u":-660},"Etc/GMT+12":{"u":-720},"Etc/GMT+2":{"u":-120},"Etc/GMT+3":{"u":-180},"Etc/GMT+4":{"u":-240},"Etc/GMT+5":{"u":-300},"Etc/GMT+6":{"u":-360},"Etc/GMT+7":{"u":-420},"Etc/GMT+8":{"u":-480},"Etc/GMT+9":{"u":-540},"Etc/GMT-0":{"a":"Etc/GMT","r":1},"Etc/GMT-1":{"u":60},"Etc/GMT-10":{"u":600},"Etc/GMT-11":{"u":660},"Etc/GMT-12":{"u":720},"Etc/GMT-13":{"u":780},"Etc/GMT-14":{"u":840},"Etc/GMT-2":{"u":120},"Etc/GMT-3":{"u":180},"Etc/GMT-4":{"u":240},"Etc/GMT-5":{"u":300},"Etc/GMT-6":{"u":360},"Etc/GMT-7":{"u":420},"Etc/GMT-8":{"u":480},"Etc/GMT-9":{"u":540},"Etc/GMT0":{"a":"Etc/GMT","r":1},"Etc/Greenwich":{"a":"Etc/GMT","r":1},"Etc/UCT":{"a":"Etc/UTC","r":1},"Etc/UTC":{"u":0},"Etc/Universal":{"a":"Etc/UTC","r":1},"Etc/Zulu":{"a":"Etc/UTC","r":1},"Europe/Amsterdam":{"a":"Europe/Brussels","c":["NL"],"r":1},"Europe/Andorra":{"u":60,"d":120,"c":["AD"]},"Europe/Astrakhan":{"u":240,"c":["RU"]},"Europe/Athens":{"u":120,"d":180,"c":["GR"]},"Europe/Belfast":{"a":"Europe/London","c":["GB"],"r":1},"Europe/Belgrade":{"u":60,"d":120,"c":["RS","BA","HR","ME","MK","SI"]},"Europe/Berlin":{"u":60,"d":120,"c":["DE","DK","NO","SE","SJ"]},"Europe/Bratislava":{"a":"Europe/Prague","c":["SK"],"r":1},"Europe/Brussels":{"u":60,"d":120,"c":["BE","LU","NL"]},"Europe/Bucharest":{"u":120,"d":180,"c":["RO"]},"Europe/Budapest":{"u":60,"d":120,"c":["HU"]},"Europe/Busingen":{"a":"Europe/Zurich","c":["DE"],"r":1},"Europe/Chisinau":{"u":120,"d":180,"c":["MD"]},"Europe/Copenhagen":{"a":"Europe/Berlin","c":["DK"],"r":1},"Europe/Dublin":{"u":60,"d":0,"c":["IE"]},"Europe/Gibraltar":{"u":60,"d":120,"c":["GI"]},"Europe/Guernsey":{"a":"Europe/London","c":["GG"],"r":1},"Europe/Helsinki":{"u":120,"d":180,"c":["FI","AX"]},"Europe/Isle_of_Man":{"a":"Europe/London","c":["IM"],"r":1},"Europe/Istanbul":{"u":180,"c":["TR"]},"Europe/Jersey":{"a":"Europe/London","c":["JE"],"r":1},"Europe/Kaliningrad":{"u":120,"c":["RU"]},"Europe/Kiev":{"a":"Europe/Kyiv","r":1},"Europe/Kirov":{"u":180,"c":["RU"]}
3620,"Europe/Kyiv":{"u":120,"d":180,"c":["UA"]},"Europe/Lisbon":{"u":0,"d":60,"c":["PT"]},"Europe/Ljubljana":{"a":"Europe/Belgrade","c":["SI"],"r":1},"Europe/London":{"u":0,"d":60,"c":["GB","GG","IM","JE"]},"Europe/Luxembourg":{"a":"Europe/Brussels","c":["LU"],"r":1},"Europe/Madrid":{"u":60,"d":120,"c":["ES"]},"Europe/Malta":{"u":60,"d":120,"c":["MT"]},"Europe/Mariehamn":{"a":"Europe/Helsinki","c":["AX"],"r":1},"Europe/Minsk":{"u":180,"c":["BY"]},"Europe/Monaco":{"a":"Europe/Paris","c":["MC"],"r":1},"Europe/Moscow":{"u":180,"c":["RU"]},"Europe/Nicosia":{"a":"Asia/Nicosia","r":1},"Europe/Oslo":{"a":"Europe/Berlin","c":["NO","BV"],"r":1},"Europe/Paris":{"u":60,"d":120,"c":["FR","MC"]},"Europe/Podgorica":{"a":"Europe/Belgrade","c":["ME"],"r":1},"Europe/Prague":{"u":60,"d":120,"c":["CZ","SK"]},"Europe/Riga":{"u":120,"d":180,"c":["LV"]},"Europe/Rome":{"u":60,"d":120,"c":["IT","SM","VA"]},"Europe/Samara":{"u":240,"c":["RU"]},"Europe/San_Marino":{"a":"Europe/Rome","c":["SM"],"r":1},"Europe/Sarajevo":{"a":"Europe/Belgrade","c":["BA"],"r":1},"Europe/Saratov":{"u":240,"c":["RU"]},"Europe/Simferopol":{"u":180,"c":["RU","UA"]},"Europe/Skopje":{"a":"Europe/Belgrade","c":["MK"],"r":1},"Europe/Sofia":{"u":120,"d":180,"c":["BG"]},"Europe/Stockholm":{"a":"Europe/Berlin","c":["SE"],"r":1},"Europe/Tallinn":{"u":120,"d":180,"c":["EE"]},"Europe/Tirane":{"u":60,"d":120,"c":["AL"]},"Europe/Tiraspol":{"a":"Europe/Chisinau","r":1},"Europe/Ulyanovsk":{"u":240,"c":["RU"]},"Europe/Uzhgorod":{"a":"Europe/Kyiv","r":1},"Europe/Vaduz":{"a":"Europe/Zurich","c":["LI"],"r":1},"Europe/Vatican":{"a":"Europe/Rome","c":["VA"],"r":1},"Europe/Vienna":{"u":60,"d":120,"c":["AT"]},"Europe/Vilnius":{"u":120,"d":180,"c":["LT"]},"Europe/Volgograd":{"u":180,"c":["RU"]},"Europe/Warsaw":{"u":60,"d":120,"c":["PL"]},"Europe/Zagreb":{"a":"Europe/Belgrade","c":["HR"],"r":1},"Europe/Zaporozhye":{"a":"Europe/Kyiv","r":1},"Europe/Zurich":{"u":60,"d":120,"c":["CH","DE","LI"]},"Factory":{"u":0},"GB":{"a":"Europe/London","c":["GB"],"r":1},"GB-Eire":{"a":"Europe/London","c":["GB"],"r":1},"GMT":{"a":"Etc/GMT","r":1},"GMT+0":{"a":"Etc/GMT","r":1},"GMT-0":{"a":"Etc/GMT","r":1},"GMT0":{"a":"Etc/GMT","r":1},"Greenwich":{"a":"Etc/GMT","r":1},"HST":{"u":-600},"Hongkong":{"a":"Asia/Hong_Kong","r":1},"Iceland":{"a":"Africa/Abidjan","c":["IS"],"r":1},"Indian/Antananarivo":{"a":"Africa/Nairobi","c":["MG"],"r":1},"Indian/Chagos":{"u":360,"c":["IO"]},"Indian/Christmas":{"a":"Asia/Bangkok","c":["CX"],"r":1},"Indian/Cocos":{"a":"Asia/Yangon","c":["CC"],"r":1},"Indian/Comoro":{"a":"Africa/Nairobi","c":["KM"],"r":1},"Indian/Kerguelen":{"a":"Indian/Maldives","c":["TF","HM"],"r":1},"Indian/Mahe":{"a":"Asia/Dubai","c":["SC"],"r":1},"Indian/Maldives":{"u":300,"c":["MV","TF"]},"Indian/Mauritius":{"u":240,"c":["MU"]},"Indian/Mayotte":{"a":"Africa/Nairobi","c":["YT"],"r":1},"Indian/Reunion":{"a":"Asia/Dubai","c":["RE"],"r":1},"Iran":{"a":"Asia/Tehran","r":1},"Israel":{"a":"Asia/Jerusalem","r":1},"Jamaica":{"a":"America/Jamaica","r":1},"Japan":{"a":"Asia/Tokyo","r":1},"Kwajalein":{"a":"Pacific/Kwajalein","r":1},"Libya":{"a":"Africa/Tripoli","r":1},"MET":{"u":60,"d":120},"MST":{"u":-420},"MST7MDT":{"u":-420,"d":-360},"Mexico/BajaNorte":{"a":"America/Tijuana","r":1},"Mexico/BajaSur":{"a":"America/Mazatlan","r":1},"Mexico/General":{"a":"America/Mexico_City","r":1},"NZ":{"a":"Pacific/Auckland","c":["NZ"],"r":1},"NZ-CHAT":{"a":"Pacific/Chatham","r":1},"Navajo":{"a":"America/Denver","r":1},"PRC":{"a":"Asia/Shanghai","r":1},"PST8PDT":{"u":-480,"d":-420},"Pacific/Apia":{"u":780,"c":["WS"]},"Pacific/Auckland":{"u":720,"d":780,"c":["NZ","AQ"]},"Pacific/Bougainville":{"u":660,"c":["PG"]},"Pacific/Chatham":{"u":765,"d":825,"c":["NZ"]},"Pacific/Chuuk":{"a":"Pacific/Port_Moresby","c":["FM"],"r":1},"Pacific/Easter":{"u":-360,"d":-300,"c":["CL"]},"Pacific/Efate":{"u":660,"c":["VU"]},"Pacific/Enderbury":{"a":"Pacific/Kanton","r":1},"Pacific/Fakaofo":{"u":780,"c":["TK"]},"Pacific/Fiji":{"u":720,"c":["FJ"]},"Pacific/Funafuti":{"a":"Pacific/Tarawa","c":["TV"],"r":1},"Pacific/Galapagos":{"u":-360,"c":["EC"]},"Pacific/Gambier":{"u":-540,"c":["PF"]},"Pacific/Guadalcanal":{"u":660,"c":["SB","FM"]},"Pacific/Guam":{"u":600,"c":["GU","MP"]},"Pacific/Honolulu":{"u":-600,"c":["US","UM"]},"Pacific/Johnston":{"a":"Pacific/Honolulu","c":["UM"],"r":1},"Pacific/Kanton":{"u":780,"c":["KI"]},"Pacific/Kiritimati":{"u":840,"c":["KI"]},"Pacific/Kosrae":{"u":660,"c":["FM"]},"Pacific/Kwajalein":{"u":720,"c":["MH"]},"Pacific/Majuro":{"a":"Pacific/Tarawa","c":["MH"],"r":1},"Pacific/Marquesas":{"u":-570,"c":["PF"]},"Pacific/Midway":{"a":"Pacific/Pago_Pago","c":["UM"],"r":1},"Pacific/Nauru":{"u":720,"c":["NR"]},"Pacific/Niue":{"u":-660,"c":["NU"]},"Pacific/Norfolk":{"u":660,"d":720,"c":["NF"]},"Pacific/Noumea":{"u":660,"c":["NC"]},"Pacific/Pago_Pago":{"u":-660,"c":["AS","UM"]},"Pacific/Palau":{"u":540,"c":["PW"]},"Pacific/Pitcairn":{"u":-480,"c":["PN"]},"Pacific/Pohnpei":{"a":"Pacific/Guadalcanal","c":["FM"],"r":1},"Pacific/Ponape":{"a":"Pacific/Guadalcanal","c":["FM"],"r":1},"Pacific/Port_Moresby":{"u":600,"c":["PG","AQ","FM"]},"Pacific/Rarotonga":{"u":-600,"c":["CK"]},"Pacific/Saipan":{"a":"Pacific/Guam","c":["MP"],"r":1},"Pacific/Samoa":{"a":"Pacific/Pago_Pago","c":["AS"],"r":1},"Pacific/Tahiti":{"u":-600,"c":["PF"]},"Pacific/Tarawa":{"u":720,"c":["KI","MH","TV","UM","WF"]},"Pacific/Tongatapu":{"u":780,"c":["TO"]},"Pacific/Truk":{"a":"Pacific/Port_Moresby","c":["FM"],"r":1},"Pacific/Wake":{"a":"Pacific/Tarawa","c":["UM"],"r":1},"Pacific/Wallis":{"a":"Pacific/Tarawa","c":["WF"],"r":1},"Pacific/Yap":{"a":"Pacific/Port_Moresby","c":["FM"],"r":1},"Poland":{"a":"Europe/Warsaw","r":1},"Portugal":{"a":"Europe/Lisbon","r":1},"ROC":{"a":"Asia/Taipei","r":1},"ROK":{"a":"Asia/Seoul","r":1},"Singapore":{"a":"Asia/Singapore","c":["SG"],"r":1},"Turkey":{"a":"Europe/Istanbul","r":1},"UCT":{"a":"Etc/UTC","r":1},"US/Alaska":{"a":"America/Anchorage","r":1},"US/Aleutian":{"a":"America/Adak","r":1},"US/Arizona":{"a":"America/Phoenix","c":["US"],"r":1},"US/Central":{"a":"America/Chicago","r":1},"US/East-Indiana":{"a":"America/Indiana/Indianapolis","r":1}
3620,"US/Eastern":{"a":"America/New_York","r":1},"US/Hawaii":{"a":"Pacific/Honolulu","c":["US"],"r":1},"US/Indiana-Starke":{"a":"America/Indiana/Knox","r":1},"US/Michigan":{"a":"America/Detroit","r":1},"US/Mountain":{"a":"America/Denver","r":1},"US/Pacific":{"a":"America/Los_Angeles","r":1},"US/Samoa":{"a":"Pacific/Pago_Pago","c":["AS"],"r":1},"UTC":{"a":"Etc/UTC","r":1},"Universal":{"a":"Etc/UTC","r":1},"W-SU":{"a":"Europe/Moscow","r":1},"WET":{"u":0,"d":60},"Zulu":{"a":"Etc/UTC","r":1}}};
3621
3622    /*** PUBLIC FUNCTIONS ***/
3623
3624    if (window.TIMEZONEOFFSET == undefined) {
3625        lib.TIMEZONEOFFSET = lib.timezoneoffset = function(){
3626            return new Date().getTimezoneOffset()/(-60);
3627        };
3628    }
3629
3630    if (window.TIMEZONE == undefined) {
3631        lib.TIMEZONE = lib.timezone = function (country_id) {
3632            let time_zones = [];
3633            country_id = country_id || false;
3634            try {
3635                if( country_id ) {
3636                    if( typeof country_id == 'string') {
3637                        country_id = country_id.toUpperCase();
3638                        for ( let i in data['timezones'] ) {
3639                            if(
3640                                'c' in data['timezones'][ i ] &&
3641                                data['timezones'][ i ]['c'].indexOf( country_id ) != -1
3642                            ) {
3643                                time_zones.push( i );
3644                            }
3645                        }
3646                    }
3647                } else time_zones.push( Intl.DateTimeFormat().resolvedOptions().timeZone );
3648            } catch (err) {
3649                console.log( err );
3650            }
3651            return time_zones;
3652        }
3653    }
3654
3655    if (window.COUNTRY == undefined) {
3656        // tz_ci it can be a timezone (Europe/Berlin) or country id (DE)
3657        lib.COUNTRY = lib.country = function (tz_ci) {
3658            let countries = [];
3659            try {
3660                tz_ci = tz_ci || TIMEZONE()[0];
3661                if ( typeof tz_ci == 'string' ) {
3662                    tz_ci = tz_ci.toUpperCase();
3663                    if ( tz_ci in data['countries'] ) {
3664                        countries.push( data['countries'][ tz_ci ]);
3665                    } else {
3666                        for ( let i in data['timezones'] ) {
3667
3668                            if ( i.toUpperCase() == tz_ci ) {
3669                                if ( 'c' in data['timezones'][ i ] ) {
3670                                    let c = data['timezones'][ i ]['c'];
3671                                    for ( let j in c ) {
3672                                        countries.push( data['countries'][ c[ j ] ] );
3673                                    }
3674                                }
3675                            }
3676                        }
3677                    }
3678                }
3679            } catch (err) {
3680                console.log(err);
3681            }
3682            return countries;
3683        }
3684    }
3685
3686    if (window.REGION == undefined) {
3687        // tz_ci it can be a timezone (Europe/Berlin) or country id (DE)
3688        lib.REGION = lib.region = function (tz_ci) {
3689            let regions = [],
3690                tz = [];
3691            try {
3692                tz_ci = tz_ci || false;
3693                if ( tz_ci ) {
3694                    if ( typeof tz_ci == 'string' ) {
3695                        tz_ci = tz_ci.toUpperCase();
3696                        if ( tz_ci in data['countries'] ) {
3697                            for ( let i in data['timezones'] ) {
3698                                if ( 'c' in data['timezones'][ i ] && data['timezones'][ i ]['c'].indexOf( tz_ci ) != -1 ) {
3699                                    regions.push( i.split('/')[0] );
3700                                }
3701                            }
3702                        } else {
3703                            for ( let i in data['timezones'] ) {
3704                                if ( i.toUpperCase() == tz_ci ) {
3705                                    regions.push( i.split('/')[0] );
3706                                    break;
3707                                }
3708                            }
3709                        }
3710                    }
3711                } else {
3712                    tz = TIMEZONE();
3713                    for ( let i in tz ) {
3714                        regions.push( tz[ i ].split('/')[0] );
3715                    }
3716                }
3717            } catch (err) {
3718                console.log(err);
3719            }
3720            regions = regions.filter( function(item, index){ return regions.indexOf(item) === index; });
3721            return regions;
3722        }
3723    }
3724
3725	if (window.LANGUAGE == undefined) {
3726        lib.LANGUAGE = lib.language = function () {
3727			let lang = '';
3728            try {
3729                lang = navigator.languages ? navigator.languages[0] : (navigator.language || navigator.userLanguage);
3730            } catch (err) {
3731                console.log(err);
3732            }
3733            return lang;
3734        }
3735    }
3736
3737    root.CF_LOCATION = lib;
3738
3739})(this);
3740fbuilderjQuery = ( typeof fbuilderjQuery != 'undefined' ) ? fbuilderjQuery : jQuery;
3741fbuilderjQuery[ 'fbuilder' ] = fbuilderjQuery[ 'fbuilder' ] || {};
3742fbuilderjQuery[ 'fbuilder' ][ 'modules' ] = fbuilderjQuery[ 'fbuilder' ][ 'modules' ] || {};
3743
3744fbuilderjQuery[ 'fbuilder' ][ 'modules' ][ 'location' ] = {
3745	'prefix' : '',
3746	'callback' : function()
3747		{
3748			fbuilderjQuery[ 'fbuilder' ][ 'extend_window' ](fbuilderjQuery[ 'fbuilder' ][ 'modules' ][ 'location' ][ 'prefix' ], CF_LOCATION);
3749		}
3750};/*
3751 * cookies.js v0.1
3752 * By: CALCULATED FIELD PROGRAMMERS
3753 * Includes operations for managing cookies
3754 * Copyright 2023 CODEPEOPLE
3755 */
3756;
3757(function (root) {
3758    var lib = {};
3759
3760    function _cookie_name( cname ) {
3761        cname = cname + '';
3762        cname = cname.replace( /^\s+/, '' ).replace( /\s+$/, '' );
3763        return cname.length ? cname : false;
3764    }
3765
3766    /*** PUBLIC FUNCTIONS ***/
3767
3768    if ( window.CFFSETCOOKIE == undefined ) {
3769        lib.CFFSETCOOKIE = lib.cffsetcookie = function( cname, cvalue, exdays ) {
3770            let name = _cookie_name( cname ),
3771                expires = '';
3772
3773            if ( name ) {
3774                if( typeof exdays != 'undefined' && ! isNaN( exdays ) ) {
3775                    const d = new Date();
3776                    d.setTime( d.getTime() + ( exdays * 24 * 60 * 60 * 1000 ) );
3777                    expires = ";expires=" + d.toUTCString();
3778
3779                }
3780                document.cookie = name + "=" + cvalue + expires + ";path=/";
3781                return true;
3782            }
3783
3784            return false;
3785        };
3786    }
3787
3788    if ( window.CFFGETCOOKIE == undefined ) {
3789        lib.CFFGETCOOKIE = lib.cffgetcookie = function( cname ) {
3790            let name = _cookie_name( cname );
3791
3792            if ( name ) {
3793
3794                name = name + "=";
3795                let ca = document.cookie.split( ';' ),
3796                    c;
3797
3798                for ( let i = 0; i < ca.length; i++ ) {
3799                    c = ca[i];
3800                    c = c.replace( /^\s+/g, '' );
3801                    if ( c.indexOf( name ) == 0 ) {
3802                        return c.substring( name.length );
3803                    }
3804                }
3805            }
3806            return null;
3807        };
3808    }
3809
3810    if ( window.CFFCHECKCOOKIE == undefined ) {
3811        lib.CFFCHECKCOOKIE = lib.cffcheckcookie = function( cname ) {
3812            let name = _cookie_name( cname );
3813
3814            return ( ! name || null == lib.CFFGETCOOKIE( name ) ) ? false : true;
3815        };
3816    }
3817
3818    if ( window.CFFDELETECOOKIE == undefined ) {
3819        lib.CFFDELETECOOKIE = lib.cffdeletecookie = function( cname ) {
3820            let name = _cookie_name( cname );
3821
3822            if ( name && lib.CFFCHECKCOOKIE( name ) ) {
3823                document.cookie = name +'=; Path=/; Expires=Thu, 01 Jan 1970 00:00:01 GMT;';
3824            }
3825        };
3826    }
3827
3828    root.CF_COOKIES = lib;
3829
3830})(this);
3831fbuilderjQuery = ( typeof fbuilderjQuery != 'undefined' ) ? fbuilderjQuery : jQuery;
3832fbuilderjQuery[ 'fbuilder' ] = fbuilderjQuery[ 'fbuilder' ] || {};
3833fbuilderjQuery[ 'fbuilder' ][ 'modules' ] = fbuilderjQuery[ 'fbuilder' ][ 'modules' ] || {};
3834
3835fbuilderjQuery[ 'fbuilder' ][ 'modules' ][ 'cookies' ] = {
3836	'prefix' : '',
3837	'callback' : function()
3838		{
3839			fbuilderjQuery[ 'fbuilder' ][ 'extend_window' ](fbuilderjQuery[ 'fbuilder' ][ 'modules' ][ 'cookies' ][ 'prefix' ], CF_COOKIES);
3840		}
3841};	$.fbuilder['version'] = '5.5.1.6';
3842	$.fbuilder['controls'] = $.fbuilder['controls'] || {};
3843	$.fbuilder['forms'] = $.fbuilder['forms'] || {};
3844	$.fbuilder['css'] = $.fbuilder['css'] || {};
3845	$.fbuilder['isMobile'] = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);
3846	$.fbuilder['isIOS'] = /iPhone|iPad|iPod/i.test(navigator.userAgent);
3847    $.fbuilder['isEvalBlocked'] = function(){ return (typeof cpcff_eval_blocked != 'undefined') ? cpcff_eval_blocked : false; };
3848	$.fbuilder['eval'] = function(toEval, context)
3849	{
3850		if ( toEval === '' ) return toEval;
3851		try {
3852			context = context || {};
3853			const unique = 'cff_code_'+Math.random().toString(36).replace(/[^a-z]+/g, '').slice(0, 6);
3854			const unique_error = unique+'_error';
3855			let str = '<script id="'+unique+'">try{';
3856			for (let key in context) {
3857				if (context.hasOwnProperty(key)) {
3858					str += 'let '+key+'='+JSON.stringify(context[key])+';';
3859				}
3860			}
3861			str += unique+'='+toEval+'}catch(err){'+unique_error+'=err;}</script>';
3862			$('body').append(str);
3863			$('[id="'+unique+'"]').remove();
3864
3865			if ( unique_error in window ) {
3866				let tmp = window[unique_error];
3867				delete window[unique_error];
3868				delete window[unique];
3869				throw tmp;
3870			} else  {
3871				let tmp = window[unique];
3872				delete window[unique];
3873				return tmp;
3874			}
3875		} catch ( err ) {
3876			throw err;
3877		}
3878	};
3879
3880	$.fbuilder['timezoneInfo'] = function(form) {
3881		if (!form || form.tagName !== 'FORM') return;
3882		if (!form.querySelector('input[name="cpcff_tz"]')) {
3883			let iana = '';
3884			try {
3885				if (typeof Intl !== 'undefined' && Intl.DateTimeFormat) {
3886					let resolved = Intl.DateTimeFormat().resolvedOptions();
3887					if (resolved && resolved.timeZone) iana = resolved.timeZone;
3888				}
3889			} catch (e) { iana = ''; }
3890			let tzInput = document.createElement('input');
3891			tzInput.type = 'hidden';
3892			tzInput.name = 'cpcff_tz';
3893			tzInput.value = iana;
3894			form.appendChild(tzInput);
3895		}
3896
3897		if (!form.querySelector('input[name="cpcff_tz_offset"]')) {
3898			let offset = 0;
3899			try {
3900				let d = new Date();
3901				offset = d.getTimezoneOffset();
3902			} catch (e) { offset = 0; }
3903			let offInput = document.createElement('input');
3904			offInput.type = 'hidden';
3905			offInput.name = 'cpcff_tz_offset';
3906			offInput.value = String(offset);
3907			form.appendChild(offInput);
3908		}
3909	};
3910
3911	$.fbuilder['isNumeric'] = function(n){return !isNaN(parseFloat(n)) && isFinite(n);};
3912    $.fbuilder['numberOfDecimals'] = function(value, symbol) {
3913        const s = String(symbol).replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
3914        const match = String(value).match(new RegExp(`.*${s}(\\d*)`, 'i'));
3915        return match ? match[1].length : null;
3916    };
3917
3918	$.fbuilder['htmlEncode'] = window['cff_esc_attr'] = function(value)
3919	{
3920		return $('<div/>').text(value).html()
3921				.replace(/"/g, "&quot;");
3922				//.replace(/&amp;lt;/g, '&lt;')
3923				//.replace(/&amp;gt;/g, '&gt;');
3924	};
3925
3926	$.fbuilder['htmlDecode'] = window['cff_html_decode'] = function(value)
3927	{
3928		value = String(value)
3929				.replace(/<script\b[^>]*>([\s\S]*?)<\/script>/gi, '')
3930				.replace(/<style\b[^>]*>([\s\S]*?)<\/style>/gi, '')
3931				.replace(/(\b)(on[a-z]+)\s*=/gi, "$1_$2=");
3932		return cff_sanitize(String((/&(?:#x[a-f0-9]+|#[0-9]+|[a-z0-9]+);?/ig.test(value)) ? $('<div/>').html(value).html() : value).replace(/(\b)\_style(\b)/gi, '$1style$2'), true);
3933	};
3934
3935	if ('DOMPurify' in window) {
3936		DOMPurify.addHook('uponSanitizeAttribute', function(currentNode, hookEvent, config) {
3937			if (currentNode.tagName === 'A' && currentNode.hasAttribute('target')) {
3938				// Preserve the target attribute.
3939				hookEvent.forceKeepAttr = true;
3940				currentNode.setAttribute('rel', 'noopener noreferrer');
3941			}
3942		});
3943	}
3944
3945	$.fbuilder['sanitize'] = window['cff_sanitize'] = function(value, controls, templates)
3946	{
3947        if(typeof value == 'string') {
3948			if(typeof controls != 'undefined' && controls) value = value.replace(/<\/?(textarea|input|button|checkbox|radio|select|option)[^>]*>/gi, '');
3949
3950			if ('DOMPurify' in window) {
3951				let forbid_tags = ['style', 'script', 'link'];
3952				if (typeof controls != 'undefined' && controls) {
3953					forbid_tags = forbid_tags.concat(['textarea', 'input', 'button', 'checkbox', 'radio', 'select', 'option']);
3954				}
3955				let args = {FORBID_TAGS: forbid_tags};
3956				if ( typeof templates != 'undefined' && templates ) args['ADD_TAGS'] = ['x-template'];
3957				value = DOMPurify.sanitize(value, args);
3958			} else if ( 'DOMParser' in window ) {
3959				const parser = new DOMParser();
3960				const doc = parser.parseFromString(value, 'text/html');
3961
3962				// Remove all script, style, and link tags.
3963				const tags = doc.querySelectorAll('script,style,link');
3964				tags.forEach(tag => tag.remove());
3965
3966				// Remove all form controls.
3967				if (typeof controls != 'undefined' && controls) {
3968					const ctr_tags = doc.querySelectorAll('textarea,input,button,checkbox,radio,select,option');
3969					ctr_tags.forEach(tag => tag.remove());
3970				}
3971
3972				// Remove all event handlers and inline style attributes.
3973				const elements = doc.querySelectorAll('*');
3974				elements.forEach(element => {
3975					for (const attr of element.getAttributeNames()) {
3976						if (attr.startsWith('on')) {
3977							element.removeAttribute(attr);
3978						}
3979					}
3980				});
3981
3982				value = doc.documentElement.getElementsByTagName('BODY')[0].innerHTML;
3983			} else {
3984				value = value.replace(/<script\b.*\bscript>/ig, '')
3985							 .replace(/<script[^>]*>/ig, '')
3986							 .replace(/<link[^>]*>/ig, '')
3987							 .replace(/(\b)(on[a-z]+)\s*=/ig, "$1_$2=")
3988							 .replace(/<style\b.*\bstyle>/ig, '')
3989							 .replace(/<style[^>]*>/ig, '');
3990
3991				value = $('<div></div>').append(value).html();
3992			}
3993		}
3994		return value;
3995	};
3996
3997    $.fbuilder['escapeSymbol'] = function( value ) // Escape the symbols used in regulars expressions
3998	{
3999		return (typeof value == 'string') ? value.replace(/([\^\$\-\.\,\[\]\(\)\/\\\*\?\+\!\{\}])/g, "\\$1") : value;
4000	};
4001
4002	$.fbuilder[ 'parseValStr' ] = function( value, raw, no_quotes )
4003	{
4004		raw = raw || false;
4005        no_quotes = no_quotes || false;
4006		value = String(value || '').trim();
4007		value = value.replace(/\\/g, "\\\\").replace(/'/g, "\\'").replace(/"/g, '\\"');
4008		var r = ($.fbuilder.isNumeric(value)) ? ((raw) ? value : value*1) : ((no_quotes) ? value : '"' + value + '"');
4009		return raw ? r : ( window.cffsanitize != undefined ? cffsanitize( r, true ) : r );
4010	};
4011
4012	$.fbuilder[ 'parseVal' ] = function( value, thousand, decimal, no_quotes )
4013	{
4014		if(!!value == false) return 0;
4015        no_quotes = no_quotes || false;
4016		/* date */
4017		if(/(\d{1,2}[\/\.\-]\d{1,2}[\/\.\-]\d{4})|(\d{4}[\/\.\-]\d{1,2}[\/\.\-]\d{1,2})/.test(value))
4018			return $.fbuilder[ 'parseValStr' ]( value, false, no_quotes );
4019
4020		/* number */
4021		thousand = $.fbuilder.escapeSymbol(String((typeof thousand != 'undefined') ? thousand : ',').trim());
4022		decimal  = String((!!!decimal || /^\s*$/.test(decimal)) ? '.': decimal).trim();
4023
4024		var p, _thousand = /^\s*$/.test(thousand) ? '\,' : thousand,
4025			t = new String(value);
4026
4027		try {
4028			if ( 1 == t.match(new RegExp( _thousand, 'g' ) ).length ) {
4029				t = t.replace(new RegExp(_thousand+'\(\\d{1,2}\)$' ), decimal+'$1');
4030			}
4031		} catch(err){}
4032
4033		t = t.replace( new RegExp(thousand, 'g'), '' )
4034			 .replace( new RegExp($.fbuilder.escapeSymbol(decimal), 'g' ), '.' )
4035			 .replace( /\s/g, '' );
4036		p = /[+\-]?((\d+(\.\d+)?)|(\.\d+))(?:[eE][+\-]?\d+)?/.exec( t );
4037
4038		return (p) ? ((/^0\d/.test(p[0])) ? p[0].substr(1) : p[0])*1 : $.fbuilder['parseValStr'](value, false, no_quotes);
4039	};
4040
4041	$.fbuilder[ 'isMobile' ] = function() {
4042        try{ document.createEvent("TouchEvent"); return true; }
4043        catch(e){ return false; }
4044    };
4045
4046	$.fbuilder[ 'setBrowserHistory' ] = function(r)
4047	{
4048		if('history' in window)
4049		{
4050			var b = '#',
4051				s = '';
4052			for(var id in $.fbuilder.forms)
4053			{
4054				b += s+'f'+id.replace(/[^\d]/g,'')+'p'+($.fbuilder.forms[id]['currentPage'] || 0);
4055				s = '|';
4056			}
4057			history[(r) ? 'replaceState' : 'pushState']({}, document.title, b);
4058		}
4059	};
4060
4061	$.fbuilder[ 'manageHistory' ] = function(onload)
4062	{
4063		var b = (document.URL.split('#')[1] || null),
4064			m, f, t, flag = false;
4065
4066		if(b)
4067		{
4068			while(m = b.match(/f(\d+)p(\d+)\|?/))
4069			{
4070				f = '_'+m[1];
4071				t = onload ? 0 : m[2]*1;
4072				b = b.replace(m[0],'');
4073
4074				flag = (
4075					!(f in $.fbuilder.forms) ||
4076					t != $.fbuilder['goToPage'](
4077						{
4078							'formIdentifier' : f,
4079							'from' 			 : 0,
4080							'to'			 : t,
4081                            'animate'        : false
4082						}
4083					)
4084				);
4085			}
4086		}
4087		else
4088		{
4089			for(f in $.fbuilder.forms)
4090				if('currentPage' in $.fbuilder.forms[f])
4091					$.fbuilder['goToPage']({'formIdentifier' : f, 'from' : 0, 'to' : 0, 'animate': false});
4092		}
4093		if(flag) $.fbuilder.setBrowserHistory(true);
4094	};
4095
4096	$.fbuilder[ 'goToPage' ] = function( config )
4097	{
4098        function swapPages(pageToHide, pageToShow, callback)
4099        {
4100            var t  = 300,
4101				w  = pageToHide.width(),
4102				f  = pageToHide.closest('form'), // Form
4103				fx = f.data('animation_effect') == 'slide' ? 'slide' : 'fade'; // Effect
4104
4105            if(
4106				('animate' in config && config.animate == false) ||
4107				(f.data('animate_form') == undefined || f.data('animate_form')*1 == 0)
4108			) t = 0;
4109
4110			if ( fx == 'fade' ) {
4111				// Fade effect
4112				pageToHide.fadeOut(t, function(){
4113					pageToHide.find(".field,[name='bccf_payment_option_paypal']").addClass("ignorepb");
4114					pageToShow.fadeIn(t, function(){
4115						pageToShow.find(".ignorepb").removeClass("ignorepb");
4116                        try {
4117                            if ('callback' in config) {
4118                                let callback_result = config.callback(pageToShow);
4119                                if (typeof callback_result == 'boolean' && callback_result === false) return;
4120                            }
4121                        } catch (err) { console.log(err); }
4122						callback();
4123					});
4124				});
4125			} else {
4126				f.css('overflow-x','hidden');
4127				// Slide effect
4128				var d = pageToHide.attr('page')*1 < pageToShow.attr('page')*1 ? -1 : 1;
4129				pageToHide.animate({width:w, marginLeft:d*w}, t, 'linear', function(){
4130					pageToHide.hide().find(".field,[name='bccf_payment_option_paypal']").addClass("ignorepb");
4131					pageToShow.css({width:w, marginLeft:-1*d*w}).show().animate({width:w, marginLeft:0}, t, 'linear', function(){
4132						pageToShow.css('width', '100%');
4133						pageToShow.find(".ignorepb").removeClass("ignorepb");
4134                        try {
4135                            if ('callback' in config) {
4136                                let callback_result = config.callback(pageToShow);
4137                                if ( typeof callback_result == 'boolean' && callback_result === false ) return;
4138                            }
4139                        } catch(err) {console.log(err);}
4140						callback();
4141					});
4142				});
4143			}
4144        };
4145
4146		if(
4147			('formIdentifier' in config || 'form' in config) &&
4148			'to' in config
4149		)
4150		{
4151			var id 	= (config['form']) ?  $('[name="cp_calculatedfieldsf_pform_psequence"]', config['form']).val() : config['formIdentifier'],
4152				formObj 	= $.fbuilder.forms[id],
4153				_from		= (config['from'] || formObj['currentPage'] || 0)*1,
4154				_to			= config['to']*1,
4155				direction  	= (_from < _to) ? 1 : -1,
4156				formDom		= $(config['form'] || '[id="'+formObj.formId+'"]'),
4157				pageDom, i  = _from;
4158
4159			_from = isNaN(_from) ? 0 : _from;
4160			_to   = isNaN(_to)   ? 0 : _to;
4161
4162			while(i != _to)
4163			{
4164				if(direction == 1 && ( ! ( 'forcing' in config ) ||  config[ 'forcing' ] == false ) && !formDom.valid()) {
4165                    // Check if the field is inside a popup.
4166                    formDom.find('.pbreak:visible .cpefb_error:not(.message):not(.ignore)').each(function () {
4167                        let p = $(this).closest('.cff-popup-field');
4168                        if (p.length > 0) {
4169                            SHOWFIELD(p);
4170                        }
4171                        let f = $(this).closest('.cff-collapsed');
4172                        if (f.length > 0) {
4173                            f.removeClass('cff-collapsed');
4174                        }
4175                    });
4176
4177                    break;
4178                }
4179				i += direction;
4180			}
4181			formObj['currentPage'] = i;
4182			pageDom = $(".pbreak.pb"+i,formDom);
4183
4184			if(i != _from) {
4185				swapPages(
4186					$(".pbreak:visible",formDom),
4187					pageDom,
4188					function()
4189					{
4190						try
4191						{
4192							if(!$.fbuilder.isMobile())
4193							{
4194								var ff  = pageDom.find(":focusable:first");
4195								if( ff &&
4196									!ff.hasClass('hasDatepicker') &&
4197									ff.attr('type') != 'button' &&
4198									ff.attr('type') != 'radio' &&
4199									ff.attr('type') != 'checkbox' &&
4200									ff.closest('[uh]').length == 0 /* FIXES AUTO-OPEN TOOLTIPS */
4201								) ff.trigger('focus');
4202							}
4203							var _wScrollTop = $(window).scrollTop(),
4204								_viewportHeight = $(window).height(),
4205								_scrollTop  = formDom.offset().top;
4206							if(_scrollTop < _wScrollTop || (_wScrollTop+_viewportHeight)<_scrollTop )
4207								$( 'html, body' ).animate({scrollTop:  _scrollTop}, 0);
4208						}
4209						catch(e){}
4210						$(document).trigger('cff-gotopage', {'from': _from, 'to': i, 'form': formDom});
4211					}
4212				);
4213
4214			} else {
4215				if( pageDom.find(':input.cpefb_error:hidden').length ) {
4216					let mssg = [];
4217
4218					pageDom.find('.cpefb_error.message:not(:empty)').each(function(){
4219						let e = $(this),
4220							l = e.closest('.fields').children('label'),
4221							t = l ? l.text() : '',
4222                            m = '<b>' + t + (t.length ? ': ' : '') + '</b>' + e.text();
4223
4224						if(mssg.indexOf(m) === -1) mssg.push(m);
4225					});
4226
4227					if(mssg.length) {
4228						$( 'body' ).append( '<div class="cff-error-dlg">'+cff_sanitize(mssg.join('<br>'), true)+'</div>' ).one('click', $.fbuilder.closeErrorDlg);
4229					}
4230				}
4231
4232				formDom.validate().focusInvalid();
4233			}
4234
4235			return i;
4236		}
4237	}; // End goToPage
4238
4239	$.fbuilder[ 'showHideDep' ] = function( config )
4240	{
4241        // If isNotFirstTime the enqueue the equations associated to the fields
4242		var processItems = function( items, isNotFirstTime )
4243		{
4244			for( var i = 0, h = items.length; i < h; i++ )
4245			{
4246				if(typeof items[i] == 'string') items[i] = $.fbuilder['forms'][id].getItem(items[i]);
4247				if(items[i])
4248				{
4249					if(isNotFirstTime)
4250					{
4251						$('[name="'+items[i].name+'"]').trigger('depEvent');
4252						if(items[i].usedInEquations) {
4253							var equations = [];
4254							for( var j in items[i].usedInEquations )
4255								if(
4256									getField(items[i].usedInEquations[j].result)['dynamicEval'] ||
4257									(
4258										'force_all' in $.fbuilder['forms'][id] &&
4259										$.fbuilder['forms'][id]['force_all']
4260									)
4261								) equations.push( items[i].usedInEquations[j] );
4262							if ( equations.length )
4263								$.fbuilder['calculator'].enqueueEquation(id, equations);
4264						}
4265					}
4266					if('showHideDep' in items[i])
4267					{
4268						var list = items[i]['showHideDep']( toShow, toHide, hiddenByContainer, interval );
4269						if(list && list.length) processItems( list, true );
4270					}
4271				}
4272			}
4273		};
4274
4275		if('formIdentifier' in config)
4276		{
4277			var id = config['formIdentifier'];
4278
4279			if(id in $.fbuilder['forms'])
4280			{
4281				var interval = $('#'+$.fbuilder['forms'][id]['formId']).data('animate_form') ? 250 : 0,
4282                    toShow = $.fbuilder['forms'][id]['toShow'],
4283					toHide = $.fbuilder['forms'][id]['toHide'],
4284					hiddenByContainer = $.fbuilder['forms'][id]['hiddenByContainer'],
4285					items = ('fieldIdentifier' in config) ? [$.fbuilder['forms'][id].getItem(config['fieldIdentifier'].replace(/_[cr]b\d+$/i, ''))] : $.fbuilder['forms'][id].getItems();
4286
4287				processItems(items);
4288				$('[id="'+$.fbuilder['forms'][id]['formId']+'"]').trigger('showHideDepEvent', $.fbuilder['forms'][id]['formId']);
4289			}
4290		}
4291	};
4292
4293	// Load default values
4294	$.fbuilder[ 'cpcffLoadDefaults' ] = function( o )
4295	{
4296		if( typeof cpcff_default != 'undefined' )
4297		{
4298			var $ = fbuilderjQuery,
4299				id = o.identifier.replace(/[^\d]/g, ''),
4300				item, data, formObj, f;
4301
4302			if(id in cpcff_default)
4303			{
4304				// Initialize variables.
4305				data = cpcff_default[id];
4306				id = '_'+id;
4307				formObj = $.fbuilder['forms'][id];
4308				f = $('#'+formObj['formId']);
4309				f.attr('data-evalequations', 0);
4310				f.attr('data-loadingdefaults', 1);
4311
4312				// Selecting the default options in DS fields while they load.
4313				let still_loading = true;
4314
4315				$(document).on('input', '#fbuilder :input', function(evt){
4316					still_loading = false;
4317				});
4318
4319				$(document).on('cff-data-filled', function(evt){
4320					if ( ! still_loading ) return true; // The data are being loaded from data source by the user action.
4321					try {
4322						let n = $(evt.target).attr('id').match( /(fieldname\d+)_(\d+)/);
4323						if (
4324							n &&
4325							n[2] in cpcff_default &&
4326							n[1] in cpcff_default[n[2]]
4327						) {
4328							let f = getField( n[1], '#cp_calculatedfieldsf_pform_'+n[2] );
4329							if(
4330								f &&
4331								'setVal' in f &&
4332								JSON.stringify(f.val('vt', true)) != JSON.stringify(cpcff_default[n[2]][n[1]])
4333							) {
4334								f.setVal( cpcff_default[n[2]][n[1]], false, true );
4335							}
4336						}
4337					} catch (err){ if('console' in window) console.log(err); }
4338				});
4339				// ...End.
4340
4341				// Assign the values to non-ds fields.
4342				for( var fieldId in data )
4343				{
4344					item = formObj.getItem(fieldId+id);
4345					try {
4346						if(
4347							item &&
4348							! ( 'isDatasource' in item ) &&
4349							'setVal' in item &&
4350							JSON.stringify(item.val('vt', true)) != JSON.stringify(data[fieldId])
4351						) item.setVal(data[fieldId], false, true);
4352					} catch(err){}
4353				}
4354
4355				// Assign the values to ds fields.
4356				for( var fieldId in data )
4357				{
4358					item = formObj.getItem(fieldId+id);
4359					try {
4360						if(
4361							item &&
4362							'isDatasource' in item &&
4363							'setVal' in item &&
4364							JSON.stringify(item.val('vt', true)) != JSON.stringify(data[fieldId])
4365						) {
4366							item.setVal(data[fieldId], false, true);
4367							$('[name*="'+item.name+'"]').trigger('trigger_ds');
4368						}
4369					} catch(err){}
4370				}
4371
4372				f.trigger('cff-loaded-defaults');
4373			}
4374		}
4375	};
4376
4377	$.fbuilder[ 'getCSSComponent' ] = function( o, c, i, s, f ) // o: form or field object, c: component, i: !important, s: selector, f: form
4378	{
4379		// Initialize variables
4380		i = i || false;
4381		s = s || false;
4382		f = f || false;
4383
4384		let output = '';
4385		if ( 'advanced' in o ) {
4386			if ( 'css' in o.advanced ) {
4387				if ( c in o.advanced.css ) {
4388					if ( 'rules' in o.advanced.css[c] ) {
4389						let rules = o.advanced.css[c].rules,
4390							v;
4391						for ( let r in rules ) {
4392							r = String( r ).trim().replace(/\:$/, '');
4393							v = String( rules[r] ).trim().replace(/\;$/, '');
4394							if ( '' !== r && '' !== v ) {
4395								if (i) {
4396									v = v.replace(/\!\s*important/i, '')+' !important';
4397								}
4398								output += r+':'+v+';';
4399							}
4400						}
4401					}
4402				}
4403			}
4404		}
4405		if ( f && s && output !== '' ) {
4406			if ( ! ( f in $.fbuilder.css ) ) $.fbuilder.css[f] = [];
4407			$.fbuilder.css[f].push( s+'{'+output+'}');
4408		}
4409		return output;
4410	};
4411
4412	$.fn.fbuilder = function(options){
4413		var opt = $.extend({},
4414					{
4415						pub:false,
4416						identifier:"",
4417						title:""
4418					},options, true);
4419
4420		opt.messages = $.extend(
4421			{
4422                apply_coupon: "Apply Coupon",
4423				previous: "Previous",
4424				next: "Next",
4425				pageof: "Page {0} of {0}",
4426				required: "This field is required.",
4427				email: "Please enter a valid email address.",
4428				datemmddyyyy: "Please enter a valid date with this format(mm/dd/yyyy)",
4429				dateddmmyyyy: "Please enter a valid date with this format(dd/mm/yyyy)",
4430				number: "Please enter a valid number.",
4431				digits: "Please enter only digits.",
4432				maxlength: "Please enter no more than {0} characters.",
4433				minlength: "Please enter at least {0} characters.",
4434				equalTo: "Please enter the same value again.",
4435				max: "Please enter a value less than or equal to {0}.",
4436				min: "Please enter a value greater than or equal to {0}.",
4437				currency: "Please enter a valid currency value."
4438			},
4439			(opt.messages || {})
4440		);
4441
4442		opt.messages.max = $.validator.format(opt.messages.max);
4443		opt.messages.min = $.validator.format(opt.messages.min);
4444		opt.messages.maxlength = $.validator.format(opt.messages.maxlength);
4445		opt.messages.minlength = $.validator.format(opt.messages.minlength);
4446		opt.messages.dateyyyymmdd = opt.messages.datemmddyyyy;
4447		opt.messages.dateyyyyddmm = opt.messages.dateddmmyyyy;
4448
4449		for( let message in opt.messages ) {
4450			opt.messages[message] = cff_sanitize(opt.messages[message], true);
4451		}
4452
4453		$.extend($.validator.messages, opt.messages);
4454
4455		$("#cp_calculatedfieldsf_pform"+opt.identifier).validate({
4456			ignore:".ignore,.ignorepb",
4457			errorClass: 'cpefb_error',
4458			errorElement: "div",
4459            onkeyup: function(element, event) {
4460                if($(element).hasClass('cpefb_error')) {
4461                    this.element(element);
4462                }
4463            },
4464			errorPlacement: function(e, element)
4465				{
4466					var _parent = element.closest( '.uh_phone,.dfield' ),
4467						_uh =  _parent.find( 'span.uh:visible' ),
4468						_arg = {'position' : 'absolute'},
4469						_t  = _parent.find('input[type="button"],input[type="reset"],input[type="text"],input[type="number"]:not([id$="_quantity"]),input[type="email"],input[type="file"],input[type="color"],input[type="date"],input[type="password"],input[type="email"],select,textarea');
4470
4471						try{
4472							if(_t.length) _arg['left'] = _t.first()[0].offsetLeft;
4473						} catch (err) {}
4474					e.addClass( 'message' ).css( _arg ).appendTo( ( _uh.length ) ? _uh : _parent );
4475				}
4476		}).messages = opt.messages;
4477
4478		var items = [],
4479			fieldsIndex = {},
4480			reloadItemsPublic = function()
4481			{
4482				var form_tag 		= $("#cp_calculatedfieldsf_pform"+opt.identifier),
4483                    header_tag      = $("#formheader"+opt.identifier),
4484					fieldlist_tag 	= $("#fieldlist"+opt.identifier),
4485					page_tag,
4486					i = 0,
4487					page = 0,
4488					getCaptchaHTML = function(){
4489						var captcha_tag = $( "#cpcaptchalayer"+opt.identifier+':not(:empty)')
4490							html = '';
4491						if( captcha_tag.length )
4492						{
4493							html += '<div class="captcha">'+captcha_tag.html()+'</div><div class="clearer"></div>';
4494							captcha_tag.remove();
4495						}
4496						return html;
4497					},
4498					getSubmitHTML = function(){
4499						var submit_tag = $("#cp_subbtn"+opt.identifier+':not(:empty)'),
4500							html = '';
4501						if( submit_tag.length )
4502						{
4503							html += '<div class="pbSubmit" tabindex="0">'+submit_tag.html()+'</div>';
4504							submit_tag.remove();
4505						}
4506						return html;
4507					};
4508
4509				form_tag.addClass( theForm.formtemplate );
4510				theForm.form_tag = form_tag;
4511				if( !opt.cached )
4512				{
4513					page_tag = $('<div class="pb'+page+' pbreak" page="'+page+'"></div>');
4514                    header_tag.html(theForm.show( opt.identifier ));
4515					fieldlist_tag.addClass(theForm.formlayout).append(page_tag);
4516
4517					for(i; i<items.length; i++)
4518					{
4519						if ( ! ( i in items ) ) continue;
4520						items[i].index = i;
4521						if (items[i].ftype=="fPageBreak")
4522						{
4523							page++;
4524							page_tag = $('<div class="pb'+page+' pbreak" page="'+page+'"></div>');
4525							fieldlist_tag.append(page_tag);
4526						}
4527						else
4528						{
4529							// For hidden fields add the hide-strong class name.
4530							if( 'hidefield' in items[i] && items[i]['hidefield'] && 'csslayout' in items[i] ) items[i]['csslayout'] += ' hide-strong';
4531
4532							page_tag.append(items[i].show());
4533							if (items[i].aiAssistant)
4534							{
4535								page_tag.find("#"+items[i].name).attr({'data-assistant': 1});
4536							}
4537							if (items[i].predefinedClick)
4538							{
4539								page_tag.find("#"+items[i].name).attr({placeholder: items[i].predefined, value: ""});
4540							}
4541							if(items[i].exclude)
4542							{
4543								page_tag.find('.'+items[i].name).addClass('cff-exclude');
4544							}
4545							if('audiotutorial' in items[i] && !/^\s*$/.test(items[i].audiotutorial))
4546							{
4547								(function(){
4548									var t = ( typeof opt != 'undefined' && 'messages' in opt && 'audio_tutorial' in opt.messages) ? opt.messages.audio_tutorial : false,
4549										e = items[i].jQueryRef(),
4550										c = $('<span class="cff-audio-icon" '+(t ? 'uh="'+cff_esc_attr(t)+'"' : '')+'></span>'),
4551										a = $('<audio src="'+cff_esc_attr(items[i].audiotutorial)+'" class="cff-audio-tutorial"></audio>');
4552
4553									a.appendTo(e.find('.dfield'));
4554									if (items[i].ftype == 'ffieldset') {
4555										if ( e.find('>fieldset>legend').length )
4556											c.appendTo(e.find('>fieldset>legend'));
4557										else
4558											c.prependTo(e.children('fieldset'));
4559									} else {
4560										c.appendTo($(e.children('label')[0] || e));
4561									}
4562
4563									c.on( 'click', function(evt){
4564										var e = $(this);
4565										if(e.hasClass('cff-audio-stop-icon')) {
4566											e.removeClass('cff-audio-stop-icon');
4567											a[0].pause();
4568											a[0].currentTime = 0;
4569										} else {
4570											$('.cff-audio-stop-icon').trigger('click');
4571											e.addClass('cff-audio-stop-icon');
4572											a[0].play();
4573										}
4574										evt.stopPropagation();evt.preventDefault();return false;
4575									});
4576								})()
4577							}
4578							if (items[i].userhelpTooltip)
4579							{
4580								var uh = items[i].jQueryRef();
4581								if(items[i].userhelp && items[i].userhelp.length)
4582								{
4583									var uh_content = '<div data-uh-styles="'+cff_esc_attr(items[i].getCSSComponent('help').replace(/<[^>]*>/g, ''))+'">'+cff_sanitize(items[i].userhelp, true)+'</div>';
4584
4585									if(items[i].tooltipIcon) $('<span class="cff-help-icon"></span>').attr('uh', uh_content).appendTo($(uh.children('label')[0] || uh));
4586									else{
4587                                        var target = uh.find('input[type="button"],input[type="reset"],input[type="text"],input[type="number"],input[type="email"],input[type="file"],input[type="color"],input[type="date"],input[type="password"],input[type="email"],select,textarea');
4588                                        if(!target.length) target = uh.find('.slider');
4589                                        if(!target.length) target = uh.find('.dfield label');
4590                                        if(!target.length) target = uh.find('.dfield');
4591                                        if(!target.length) target = uh;
4592                                        $(target).attr('uh', uh_content);
4593                                    }
4594								}
4595								uh.find(".uh").remove();
4596							}
4597						}
4598					}
4599                }
4600				else
4601				{
4602					page = fieldlist_tag.find( '.pbreak' ).length;
4603					i	 = items.length;
4604				}
4605
4606				if (page>0)
4607				{
4608					if( !opt.cached ) // Check if the form is cached
4609					{
4610						$(".pb"+page, fieldlist_tag).addClass("pbEnd");
4611						$(".pbreak", fieldlist_tag).each(function(index) {
4612							var code = '',
4613								bSubmit = '';
4614
4615							if (index == page)
4616							{
4617								code += getCaptchaHTML();
4618								bSubmit = getSubmitHTML();
4619							}
4620
4621                            $(this).wrapInner('<fieldset></fieldset>')
4622                            .find('fieldset:eq(0)')
4623                            .prepend('<legend>'+cff_sanitize(opt.messages.pageof.replace( /\{\s*\d+\s*\}/, (index+1) ).replace( /\{\s*\d+\s*\}/, (page+1) ), true)+'</legend>')
4624                            .append(code+'<div class="cff-form-buttons-container"><div class="pbPrevious" tabindex="0">'+cff_sanitize(opt.messages.previous, true)+'</div><div class="pbNext" tabindex="0">'+cff_sanitize(opt.messages.next, true)+'</div>'+cff_sanitize(bSubmit, true)+'</div><div class="clearer"></div>');
4625						});
4626					}
4627
4628					fieldlist_tag.find(".pbPrevious,.pbNext").on("keyup", function(evt){
4629						if(evt.which == 13 || evt.which == 32) $(this).trigger('click');
4630					}).on("click", {'identifier' : opt.identifier}, function(evt, animate){
4631						var _from = ($.fbuilder.forms[evt.data.identifier]['currentPage'] || 0),
4632							_inc  = ($(this).hasClass("pbPrevious")) ? -1 : 1,
4633                            _args = {
4634                                'formIdentifier' : evt.data.identifier,
4635                                'from'			 : _from,
4636                                'to'			 : _from+_inc,
4637                                'callback'       : function(_pDom)
4638                                {
4639                                    let _p = _pDom.attr('page')*1;
4640                                    if(_pDom.find('.fields:visible').length == 0) {
4641                                        if(_inc == -1 && 0 < _p) {
4642                                            _pDom.find('.pbPrevious').trigger('click', false);
4643                                            return false;
4644                                        }
4645                                        else if(!_pDom.hasClass('pbEnd')) {
4646                                            _pDom.find('.pbNext').trigger('click', false);
4647                                            return false;
4648                                        }
4649                                    } else {
4650                                        if(_from != _p) $.fbuilder.setBrowserHistory();
4651                                    }
4652                                    return true;
4653                                }
4654                            };
4655                        if(typeof animate != 'undefined') _args['animate'] = animate;
4656                        $.fbuilder['goToPage'](_args);
4657                        return false;
4658					});
4659                }
4660				else
4661				{
4662					if( !opt.cached ) $(".pb"+page, fieldlist_tag).append(getCaptchaHTML()+'<div class="cff-form-buttons-container">'+getSubmitHTML()+'</div>');
4663				}
4664
4665				if( !opt.cached && opt.setCache)
4666				{
4667					// Set Cache
4668					var url  = document.location.href.split('?')[0],
4669						data = {
4670							'cffaction' : 'cff_cache',
4671							'cache'	 : form_tag.html().replace( /\n+/g, '' ),
4672							'form'	 : form_tag.find( '[name="cp_calculatedfieldsf_id"]').val()
4673						};
4674					$.post( url, data, function( data ){ if(typeof console != 'undefined' )console.log( data ); } );
4675				}
4676
4677                // Set icon event
4678				$(document).on('click', '.cff-help-icon', function(evt){evt.stopPropagation(); evt.preventDefault();});
4679
4680				// Set Captcha Event
4681				$(document).on('click', '#fbuilder .captcha img', function(evt){
4682					try {
4683						var e = $( this ), src = e.attr('src');
4684						// Check URL, and replace it if different from website domain
4685						if(
4686							!(new RegExp('^http(s)?\:\/\/'+$.fbuilder.escapeSymbol(window.location.host), 'i')).
4687							test(src)
4688						) src = document.location.href.split('?')[0]+'?'+src.split('?')[1];
4689						e.attr('src', src.replace(/&\d+$/, '') + '&' + Math.floor(Math.random()*1000));
4690					} catch (err) { if('console' in window) console.log(err); }
4691					evt.preventDefault();
4692					evt.stopPropagation();
4693					return false;
4694                });
4695				$( form_tag ).find( '.captcha img' ).trigger('click');
4696
4697				$( '#fieldlist'+opt.identifier).find(".pbSubmit").off('click').on("keyup", function(evt){
4698					if(evt.which == 13 || evt.which == 32) $(this).trigger('click');
4699				}).on("click", { 'identifier' : opt.identifier }, function(evt){
4700					$(this).closest("form").trigger('submit');
4701				});
4702
4703				if (i>0)
4704				{
4705                    theForm.after_show( opt.identifier );
4706					let hasDateTimeControls = false;
4707					for (var i=0;i<items.length;i++)
4708					{
4709						if ( ! ( i in items ) ) continue;
4710						items[i].after_show();
4711                        if('csslayout' in items[i] && /\bignorefield\b/i.test(items[i]['csslayout']))
4712                            IGNOREFIELD(items[i].name, items[i].form_identifier);
4713						if (['fdate', 'fdateds', 'ftimeslots', 'ftimeslotsds'].indexOf(items[i].ftype) > -1) hasDateTimeControls = true;
4714					}
4715					if (hasDateTimeControls) $.fbuilder.timezoneInfo(theForm.form_tag[0]);
4716					theForm.form_tag.removeData('first_time');
4717					// Evaluate delayed script in cached forms:
4718					$('script[type="cff-script"]').each(function(){
4719						$(this).after(this.outerHTML.replace('cff-script','text/javascript')).remove();
4720					});
4721
4722					$(document).on(
4723						'change cff-dep-event',
4724						'#fieldlist'+opt.identifier+' .depItemSel,'+'#fieldlist'+opt.identifier+' .depItem',
4725						{ 'identifier' : opt.identifier },
4726						function( evt )
4727						{
4728							$.fbuilder.showHideDep(
4729								{
4730									'formIdentifier' : evt.data.identifier,
4731									'fieldIdentifier': evt.target.id
4732								}
4733							);
4734						}
4735					);
4736
4737					setTimeout(
4738						function(){
4739							if ( 'form_tag' in theForm ) {
4740								theForm.form_tag.trigger( 'formReady', [theForm.form_tag.attr('id'), theForm.form_tag, theForm] );
4741							}
4742						}, 50
4743					);
4744
4745					try
4746					{
4747						$.widget.bridge('uitooltip', $.ui.tooltip);
4748						$( "#fbuilder"+opt.identifier ).uitooltip(
4749							{
4750								show: false,
4751								hide: false,
4752								tooltipClass: "uh-tooltip cff-form-"+('form' in opt ? opt.form : ''),
4753								position: { my: "left top", at: "left bottom+5", collision: "flipfit" },
4754								items: "[uh],[data-uh]",
4755								content: function (){let e = $(this); return e.attr("uh") ?? e.attr("data-uh") ?? '';},
4756								open: function( evt, ui ) {
4757									try {
4758										let styles = ( ui.tooltip.attr('style') || '' ) +
4759													 ( $(ui.tooltip).find('[data-uh-styles]').attr( 'data-uh-styles' ) || '' );
4760
4761										ui.tooltip.attr('style', styles );
4762										if(
4763											! $(evt.originalEvent.target).hasClass('cff-help-icon') &&
4764											window.matchMedia("screen and (max-width: 640px)").matches &&
4765											window.orientation != undefined
4766										){
4767											var duration = ('undefined' != typeof tooltip_duration && /^\d+$/.test(tooltip_duration)) ? tooltip_duration : 3000;
4768											setTimeout( function(){$(ui.tooltip).hide('fade'); }, duration );
4769										}
4770									} catch ( err ){}
4771								}
4772							}
4773						);
4774					} catch(e){}
4775                }
4776                $("#fieldlist"+opt.identifier+" .pbreak:not(.pb0)").find(".field,[name='bccf_payment_option_paypal']").addClass("ignorepb");
4777                $("#fieldlist"+opt.identifier).find('[type="date"],[type="hidden"]').each(function(){
4778					$(this).rules('add', {step:false});
4779				});
4780			};
4781
4782		var fform=function(){};
4783		$.extend(fform.prototype,
4784			{
4785				title:"Untitled Form",
4786				titletag: 'H2',
4787				textalign: 'default',
4788				headertextcolor:'',
4789				description:"This is my form. Please fill it out. It's awesome!",
4790				formlayout:"top_aligned",
4791				formtemplate:"",
4792                evalequations:1,
4793				evalequations_delay:0,
4794                evalequationsevent:2,
4795                loading_animation:0,
4796                animate_form:0,
4797				animation_effect:'fade',
4798                autocomplete:1,
4799				show:function( id ){
4800					let form_style = this.form_tag.attr('style') || '',
4801						form_id    = this.form_tag.attr('id'),
4802						css 	   = (this.textalign != 'default') ? 'text-align:'+this.textalign+';' : '';
4803
4804					if(this.headertextcolor != '') css+='color:'+this.headertextcolor+';';
4805
4806					// Form styles
4807					this.form_tag.attr('style', form_style+';' + $.fbuilder['getCSSComponent'](this, 'form'));
4808
4809					// Common buttons styles
4810					$.fbuilder['getCSSComponent'](this, 'buttons', true, '#'+form_id+' .pbNext,#'+form_id+' .pbPrevious,#'+form_id+' .pbSubmit,#'+form_id+' [type="button"].apply-coupon', id);
4811
4812					$.fbuilder['getCSSComponent'](this, 'buttons_hover', true, '#'+form_id+' .pbNext:hover,#'+form_id+' .pbPrevious:hover,#'+form_id+' .pbSubmit:hover,#'+form_id+' [type="button"].apply-coupon:hover', id);
4813
4814					$.fbuilder['getCSSComponent'](this, 'tooltips_icons', true, '#'+form_id+' #fbuilder .fields .cff-help-icon::before', id);
4815
4816					$.fbuilder['getCSSComponent'](this, 'tooltips', true, '.uh-tooltip.cff-form-'+('form' in opt ? opt.form : ''), id);
4817
4818					$.fbuilder['getCSSComponent'](this, 'thanks_popup', true, '#'+form_id+' div.cff-thanks-message', id);
4819					$.fbuilder['getCSSComponent'](this, 'close_thanks_popup', true, '#'+form_id+' div.cff-thanks-message::before', id);
4820
4821					$.fbuilder['getCSSComponent'](this, 'error_popup', true, '#'+form_id+' div.cff-error-dlg', id);
4822					$.fbuilder['getCSSComponent'](this, 'close_error_popup', true, '#'+form_id+' div.cff-error-dlg::before', id);
4823
4824					$.fbuilder['getCSSComponent'](this, 'error_bubble', true, '#'+form_id+' div.cpefb_error.message', id);
4825
4826					$.fbuilder['getCSSComponent'](this, 'error_bubble_arrow', true, '#'+form_id+' div.cpefb_error.message::after', id);
4827
4828					$.fbuilder['getCSSComponent'](this, 'required_field_asterisk', true, '#'+form_id+' .r', id);
4829
4830					return ( id in $.fbuilder.css ? '<style>' + cff_sanitize($.fbuilder.css[id].join(''), true) + '</style>' : '') + // Include the fields CSS
4831					'<div class="fform" id="field" style="'+cff_esc_attr($.fbuilder['getCSSComponent'](this, 'header'))+'">'+( !/^\s*$/.test( this.title ) ? '<'+this.titletag+' class="cff-form-title" style="'+css+cff_esc_attr($.fbuilder['getCSSComponent'](this, 'title'))+'">'+cff_sanitize(this.title, true)+'</'+this.titletag+'>' : '' )+( !/^\s*$/.test( this.description ) ? '<span class="cff-form-description" style="'+css+cff_esc_attr($.fbuilder['getCSSComponent'](this, 'description'))+'">'+cff_sanitize(this.description, true)+'</span>' : '' )+'</div>';
4832				},
4833                after_show:function( id ){
4834                    // Common validators
4835                    if( typeof $[ 'validator' ] != 'undefined' )
4836					{
4837						if(!('cffcurrency' in $.validator.methods))
4838							$.validator.addMethod(
4839								'cffcurrency',
4840								function(v, el)
4841								{
4842									var f = el.id.match( /_\d+$/),
4843										esc = $.fbuilder.escapeSymbol,
4844										r;
4845
4846									e = $.fbuilder['forms'][f[0]].getItem( el.name );
4847									r = new RegExp('^\\s*('+esc(e.currencySymbol)+')?\\s*\\-?\\d+('+esc(e.thousandSeparator)+'\\d{3})*'+((e.noCents) ? '': '('+e.centSeparator+'\\d+)?')+'\\s*('+esc(e.currencyText)+')?\\s*$','i');
4848
4849									return this.optional(el) || r.test(v) || ($.fbuilder.isNumeric(v) && (!e.noCents || v === FLOOR(v)));
4850								},
4851								cff_sanitize( $.validator.messages['currency'], true )
4852							);
4853                        $.validator.methods.number = function(v, el)
4854							{
4855								var f = el.id.match(/_\d+$/),
4856									esc = $.fbuilder.escapeSymbol,
4857									e, r;
4858
4859								if(f && el.id.match(/fieldname/i)) e = $.fbuilder['forms'][f[0]].getItem(el.name);
4860								if(!e) e = {thousandSeparator: ',', decimalSymbol: '.'};
4861								else v = e.val();
4862
4863								r = new RegExp('^\\s*\\-?\\d+('+esc(e.thousandSeparator)+'\\d{3})*('+esc(e.decimalSymbol)+'\\d+)?\\s*\\%?\\s*$','i');
4864								return this.optional(el) || r.test(v) || $.fbuilder.isNumeric(v);
4865							};
4866                        $.validator.methods.min = function(v, el, p)
4867							{
4868								var f = el.id.match( /_\d+$/), e;
4869								if(f && el.id.match(/fieldname/i)) e = $.fbuilder['forms'][f[0]].getItem(el.name);
4870								if(e){
4871									v = e.val();
4872									if('dformat' in e && e.dformat == 'percent') v*=100;
4873								}
4874								return this.optional(el) || v >= p;
4875							};
4876						$.validator.methods.max = function(v, el, p)
4877							{
4878								var f = el.id.match( /_\d+$/), e;
4879								if(f && el.id.match(/fieldname/i)) e = $.fbuilder['forms'][f[0]].getItem(el.name);
4880								if(e){
4881									v = e.val();
4882									if('dformat' in e && e.dformat == 'percent') v*=100;
4883								}
4884								return this.optional(el) || v <= p;
4885							};
4886					}
4887
4888					var form = $( '#cp_calculatedfieldsf_pform'+id );
4889
4890                    // Disabling enter key
4891                    form.on('keydown keyup keypress', '[type="text"],[type="number"],[type="password"],[type="email"]',
4892                        function(evt){
4893                            if (evt.keyCode === 13)
4894                            {
4895                                evt.preventDefault();
4896                                evt.stopPropagation();
4897                                return false;
4898                            }
4899                        });
4900
4901					if(typeof $.fn.fbuilder_localstorage != 'undefined' && form.hasClass('persist-form'))
4902					{
4903						form.fbuilder_localstorage();
4904					}
4905
4906                    form.attr( 'data-evalequations', ('evalequations_delay' in this && this.evalequations_delay) ? 0 : this.evalequations )
4907						.attr( 'data-evalequationsevent', this.evalequationsevent )
4908						.attr( 'data-animate_form', this.animate_form )
4909						.attr( 'data-animation_effect', this.animation_effect )
4910						.attr( 'autocomplete', ( ( this.autocomplete ) ? 'on' : 'off' ) )
4911						.find( 'input,select,textarea' )
4912						.on( 'blur change',  function(evt){
4913							if( 'name' in evt.target ) { // Prevent processing validation in both events at once.
4914								if ( window['cff_error_processing'+evt.target.name] ) return;
4915								window['cff_error_processing'+evt.target.name] = true;
4916								setTimeout(function(){ delete window['cff_error_processing'+evt.target.name]; }, 10);
4917							}
4918							try { if (!$(this).is(':file') && !$(this).hasClass('codepeoplecalculatedfield')) $(this).valid(); }catch(e){};
4919						});
4920
4921					if(!this.autocomplete) form.find('input[name*="fieldname"]:not([autocomplete]),input[id*="fieldname"]:not([autocomplete])').attr('autocomplete', 'new-password');
4922
4923					// For users that insert the form into a DIV tag or another clickable tag, capture bubbling click and stop propagation.
4924					form.parents('a').attr('href', 'javascript:void(0);').removeAttr('target').css('all', 'unset');
4925                }
4926			});
4927		var theForm,
4928			ffunct = {
4929				settings:opt,
4930				toShow : {},
4931				toHide : {},
4932				hiddenByContainer : {},
4933				isRTL  : false,
4934				addItem: function (item) {
4935					if (!item.name) return false;
4936					items.push(item);
4937					fieldsIndex[item.name] = items.length - 1;
4938					return true;
4939				},
4940				removeItem: function (item) {
4941					if (
4942						! item.name ||
4943						! (item.name in fieldsIndex)
4944					) return false;
4945
4946					if (fieldsIndex[item.name] in items) items[fieldsIndex[item.name]] = null;
4947					delete fieldsIndex[item.name];
4948					return true;
4949				},
4950				getItem: function( name )
4951					{
4952						if(name in fieldsIndex) return items[fieldsIndex[name]];
4953						var regExp = new RegExp((parseInt(name,10) == name) ? 'fieldname'+name+'_' : name+'_', i);
4954						for( var i in items )
4955						{
4956							if( !items[ i ]  || !('name' in items[ i ]) ) continue;
4957							if( items[ i ].name == name || regExp.test(items[ i ].name))
4958							{
4959								return items[ i ];
4960							}
4961						}
4962						return false;
4963					},
4964				getItems: function()
4965					{
4966					   return items;
4967					},
4968				getItemsNames: function( withSequence )
4969					{
4970						withSequence = withSequence || false;
4971						let names = Object.keys(fieldsIndex);
4972						if(withSequence) return names;
4973						let names_only = names.map( (n) => {
4974							let m = n.match(/(fieldname\d+)_\d+/);
4975							return m ? m[1] : n;
4976						});
4977						return names_only;
4978					},
4979				loadData:function(f)
4980					{
4981						var d =  window[ f ];
4982						if ( typeof d != 'undefined' )
4983						{
4984							if( typeof d == 'object' && ( typeof d.nodeType !== 'undefined' || d instanceof jQuery ) ){ d = JSON.parse( jQuery(d).val() ); }
4985							else if( typeof d == 'string' ){ d = JSON.parse( d ); }
4986
4987							if (d.length == 2)
4988							{
4989							   this.isRTL = ( 'direction' in d[1][0] && d[1][0]['direction'] == 'rtl' ) ? true : false;
4990							   this.formId = d[ 1 ][ 'formid' ];
4991							   items = [];
4992							   for (var i=0;i<d[0].length;i++)
4993							   {
4994								   if ( ! ( d[0][i].ftype in $.fbuilder.controls ) ) {
4995									   console.log( d[0][i].ftype +' NOT AVAILABLE' );
4996									   continue;
4997								   }
4998								   var obj = new $.fbuilder.controls[d[0][i].ftype]();
4999								   obj = $.extend(true, {}, obj, d[0][i]);
5000								   obj.name = obj.name+opt.identifier;
5001								   obj.form_identifier = opt.identifier;
5002								   if( 'fieldlayout' in obj && obj.fieldlayout != 'default' )
5003									   obj.csslayout = ('csslayout' in obj ? obj.csslayout+' ' : '' )+obj.fieldlayout;
5004								   if('predefinedClick' in obj && obj.predefinedClick && 'predefined' in obj && obj.predefined) {
5005									   obj.placeholder = obj.predefined;
5006									   obj._setHndl('placeholder');
5007								   }
5008								   obj.init();
5009								   if ( obj.ftype == 'fPageBreak' && obj.parent !== '' ) continue;
5010								   items[i] = obj;
5011								   fieldsIndex[obj.name] = i;
5012							   }
5013							   theForm = new fform();
5014							   theForm = $.extend(theForm,d[1][0]);
5015
5016							   opt.evalequations = 'evalequations' in d[1][0] ? d[1][0][ 'evalequations' ] : 1;
5017							   opt.evalequations_delay = 'evalequations_delay' in d[1][0] ? d[1][0][ 'evalequations_delay' ] : 0;
5018							   opt.cached   = (typeof d[ 1 ][ 'cached' ] != 'undefined' && d[ 1 ][ 'cached' ] ) ? true : false;
5019							   opt.setCache = (!this.cached && typeof d[ 1 ][ 'setCache' ] != 'undefined' && d[ 1 ][ 'setCache' ]) ? true : false;
5020
5021							   reloadItemsPublic();
5022						    }
5023
5024							$(document).on('formReady', 'form#'+this.formId, ( function( opt, fid ){
5025								function resizeIframe(f) {
5026									let h = f.outerHeight()+40
5027									if (frameElement) {
5028										frameElement.height = h;
5029									}
5030									// Update iframe height
5031									if( 'parent' in window && window.parent != window ) {
5032										parent.postMessage({cff_height: h, cff_iframe: getURLParameter('cff_iframe', 0)}, '*');
5033									}
5034								};
5035								return function(evt, fid2, form_tag, form_obj){
5036									if ( fid == fid2 ){
5037										let f = form_tag;
5038
5039										// Disable the dynamic evaluation of the equations until complete the loading process.
5040										let eval_equations_bk = f.attr('data-evalequations') ?  Math.max( opt.evalequations*1, f.attr( 'data-evalequations')*1 ) : opt.evalequations; // 2024-12-16
5041
5042										$.fbuilder.cpcffLoadDefaults( opt );
5043
5044										$.fbuilder.showHideDep( { 'formIdentifier' : opt.identifier } );
5045										f.removeAttr('data-loadingdefaults');
5046
5047										f.css({'height':'auto', 'minHeight':'auto'});
5048
5049										if( opt.evalequations ) {
5050											fbuilderjQuery.fbuilder.calculator.defaultCalc(this, false, false);
5051										}
5052
5053										f.attr('data-evalequations', eval_equations_bk);
5054										$('.cff-processing-form', f).remove(); // 2024-12-16
5055
5056										try {
5057											$.post(
5058												document.location.href.split('?')[0],
5059												{
5060													'cffaction'     : 'cff_register_height',
5061													'form_height'	: f.height(),
5062													'screen_width'	: $(window).width(),
5063													'form'	 		: f.find('[name="cp_calculatedfieldsf_id"]').val(),
5064													'_nonce'		: f.attr('data-nonce') || ''
5065												}
5066											);
5067										} catch(err){}
5068
5069										// Resize iframe when form or window resize
5070										resizeIframe(f);
5071										(new ResizeObserver(function() {
5072											try {
5073												resizeIframe(f);
5074											} catch(err){}
5075										})).observe(f[0]);
5076
5077                                        // Replace the default submit action to ensure the validations are executed.
5078                                        try {
5079                                            f[0].nativeSubmit = f[0].submit;
5080                                            f[0].submit = function() {
5081                                                if ( 'SUBMITFORM' in window && typeof window.SUBMITFORM == 'function' ) {
5082                                                    SUBMITFORM(this);
5083                                                } else {
5084                                                    f[0].nativeSubmit();
5085                                                }
5086                                            };
5087                                        } catch(err){}
5088									}
5089								};
5090							} )( opt, this.formId ) );
5091						}
5092					}
5093			};
5094
5095		$.fbuilder[ 'forms' ][ opt.identifier ] = ffunct;
5096	    this.fBuild = ffunct;
5097	    return this;
5098	}; // End fbuilder plugin
5099
5100	$.fbuilder.controls[ 'ffields' ] = function(){};
5101	$.extend($.fbuilder.controls[ 'ffields' ].prototype,
5102		{
5103				form_identifier:"",
5104				name:"",
5105				shortlabel:"",
5106				index:-1,
5107				ftype:"",
5108				userhelp:"",
5109				audiotutorial:"",
5110				userhelpTooltip:false,
5111				csslayout:"",
5112				init:function(){},
5113				_getValueAttr:function(v){
5114					let output = '';
5115					let attr = 'value';
5116					if ( 'predefinedClick' in this && this['predefinedClick'] ) attr = 'placeholder';
5117					if ( v != undefined ) output = attr+'="'+cff_esc_attr(v)+'"';
5118					else if ( 'predefined' in this ) output = attr+'="'+cff_esc_attr(this.predefined)+'"';
5119					return output;
5120				},
5121				_getAttr:function(attr, raw)
5122					{
5123						var me = this, f, p,
5124                            o  = me[attr], // original value
5125                            v = String(o).trim(), raw = raw || false;
5126						if ( !raw && $.fbuilder.isNumeric(v) ) return parseFloat(v);
5127						if ( typeof v == 'string' ) {
5128							if ( p = /^url\.(.+)$/.exec(v) ) return (p = p[1].trim()) ? getURLParameter( p, '' ) : '';
5129							if ( p = /^var\.(.+)$/.exec(v) ) return ((p = p[1].trim()) && p in window) ? window[p] : '';
5130							f = (/^fieldname\d+$/i.test(v)) ? me.getField(v) : false;
5131							if(f)
5132							{
5133								v = f.val(raw, true);
5134								if(!raw && $.fbuilder.isNumeric(v)) v = parseFloat(v);
5135								if( (f.ftype == 'fdate' || f.ftype == 'fdateds' ) && $.fbuilder.isNumeric(v) && v) v = CDATE(v, me.dformat);
5136                                return v;
5137							}
5138						}
5139
5140						return o;
5141					},
5142				_setHndl:function(attr, one)
5143					{
5144                        let _validSelector = function (s) {
5145                            if (!s || s === '*') return false;
5146                            try {
5147                                document.querySelectorAll(s);
5148                                return true;
5149                            } catch (err) { return false; }
5150                        };
5151						var me = this,
5152                            v = String(me[attr]).trim(); // v is type string.
5153						if($.fbuilder.isNumeric(v)) return;
5154
5155						// NEW: only treat non-fieldname values as selectors if they look like one
5156						// (start with . # or contain [). Anything else is a literal value — no depen
5156dency wiring.
5157						if (!/^fieldname\d+$/i.test(v) && !/^[.#\[]/.test(v)) return;
5158						var s = (/^fieldname\d+$/i.test(v)) ? '.'+v+me.form_identifier+' [id*="'+v+me.form_identifier+'"]' : v,
5159							i = (one) ? 'one' : 'on';
5160                        if (_validSelector(s))
5161                        {
5162                            try {
5163                                $(document)[i]('change depEvent cff-reset-field', s, function(evt){
5164                                    let v = $(evt.target).val();
5165                                    if(me['set_'+attr]) me['set_'+attr](v, $(evt.target).hasClass('ignore'));
5166                                });
5167                            } catch( err ) {}
5168
5169                            try {
5170                                $(document)['one']('showHideDepEvent', function(evt,formId){
5171                                    try
5172                                    {
5173                                        if(me['set_'+attr])
5174                                        {
5175                                            me['set_'+attr](me._getAttr(attr), $(s).hasClass('ignore'));
5176                                            $('#'+formId+' .cpefb_error.message').remove();
5177                                            $('#'+formId+' .cpefb_error').removeClass('cpefb_error');
5178                                        }
5179                                    }
5180                                    catch(err){}
5181                                });
5182                            } catch( err ) {}
5183                        }
5184					},
5185				getField: function(f){return $.fbuilder['forms'][this.form_identifier].getItem(f);},
5186				jQueryRef: function(){return $('.'+this.name);},
5187				domRef: function(){return this.jQueryRef()[0];},
5188				show:function()
5189					{
5190						return 'Not available yet';
5191					},
5192				after_show:function(){},
5193				val:function(raw, no_quotes, disable_ignore_check){
5194					raw = raw || false;
5195                    no_quotes = no_quotes || false;
5196					var e = (disable_ignore_check) ? $( "[id='" + this.name + "']" ) : $( "[id='" + this.name + "']:not(.ignore)" );
5197					if( e.length )
5198					{
5199						var v = e.val();
5200						if(raw) return $.fbuilder.parseValStr(v, raw, no_quotes);
5201
5202						v = String(v).trim();
5203						return ($.fbuilder.isNumeric(v)) ? $.fbuilder.parseVal(v) : $.fbuilder.parseValStr(v, raw, no_quotes);
5204					}
5205					return 0;
5206				},
5207				setVal:function( v, nochange )
5208				{
5209					let e = $( "[id='" + this.name + "']" ),
5210						bk = e.val();
5211
5212					e.val( cff_sanitize(v) );
5213					if ( !nochange && bk !== e.val() ) e.trigger('change');
5214				},
5215				set_placeholder:function( v ) {
5216					$( '[id="' + this.name + '"]' ).attr( 'placeholder', v );
5217				},
5218				setPlaceholder:function( v )
5219				{
5220					$( '[id="' + this.name + '"][type="text"]' ).attr( 'placeholder', v );
5221				},
5222				getCSSComponent:function( c, i, s, f ) // c: component, i: !important, s: selector, f: form
5223				{
5224					return $.fbuilder[ 'getCSSComponent' ](this, c, i, s, f );
5225				}
5226		}
5227	);
5228
5229	$.fbuilder['doValidate'] = function(form) {
5230		form = $(form);
5231
5232		let validation_rules = {},
5233			enabling_form = function () {
5234				form.validate().settings.ignore = '.ignore,.ignorepb';
5235				form.removeData('being-submitted');
5236				form.find('.submitbtn-disabled').removeClass('submitbtn-disabled').prop('disabled', false);
5237				form.find('.cff-processing-form').remove();
5238			},
5239			disabling_form = function () {
5240				if (form_disabled()) return;
5241				form.find('.pbSubmit,:submit').addClass('submitbtn-disabled').prop('disabled', true);
5242				form.data('being-submitted', 1);
5243				form.find('#fbuilder').append('<div class="cff-processing-form"></div>');
5244			},
5245			form_disabled = function () {
5246				return ('undefined' != typeof form.data('being-submitted'));
5247			},
5248			processing_form = function () {
5249				if (
5250					'extra_validations' in $.fbuilder &&
5251					Object.prototype.toString.call($.fbuilder.extra_validations) === '[object Object]'
5252				) {
5253					for (let i in $.fbuilder.extra_validations) {
5254						if (
5255							typeof $.fbuilder.extra_validations[i] == 'function' &&
5256							!$.fbuilder.extra_validations[i](form, validation_rules, processing_form)
5257						) {
5258							enabling_form();
5259							return false;
5260						}
5261					}
5262				}
5263				for (let rule in validation_rules) {
5264					if (!validation_rules[rule]) {
5265						form.trigger('cff-form-validation', false);
5266						return;
5267					}
5268				}
5269				try{
5270					form.find('[name="cp_ref_page"]').val(parent.window.document.location.href);
5271				} catch (err) {
5272					form.find('[name="cp_ref_page"]').val(document.location.href);
5273				}
5274				form.find("[name$='_date'][type='hidden']").each(function () {
5275					let v = $(this).val(),
5276					name = $(this).attr('name').replace('_date', ''),
5277					e = $('[name="' + name + '"]');
5278					if (e.length && !$('[id="' + name + '_datepicker_container"]').length) {
5279						e.val(String(e.val().replace(v, '')).trim());
5280					}
5281				});
5282				form.find('select option[vt]').each(function () {
5283					let e = $(this);
5284					e.attr('cff-val-bk', e.val()).val( cff_sanitize(e.attr('vt'), true) );
5285				});
5286				form.find('input[vt]').each(function () {
5287					let e = $(this),
5288						q = $('[id="'+e.attr('id')+'_quantity"]');
5289                    e.attr('cff-val-bk', e.val()).val(cff_sanitize(e.attr('vt'), true)+(q.length ? ' ('+Math.max(1, q.val())+')' : ''));
5290				});
5291				form.find('.cpcff-recordset,.cff-exclude :input,[id^="form_structure_"]')
5292					.add(form.find('.ignore')).attr('cff-disabled', 1).prop('disabled', true);
5293				disabling_form();
5294				if ($('#cff_iframe_for_submission'+form_identifier).length) {
5295					form.attr('target', 'cff_iframe_for_submission'+form_identifier);
5296					$(document).one('cff-form-submitted', function(){
5297						form.find( '.cff-thanks-message' ).fadeIn(400);
5298						reset_captcha_box();
5299						$(document).one('click', function(){ $('.cff-thanks-message').hide(); });
5300						if ( $('#cff_iframe_for_submission'+form_identifier).attr('data-cff-reset') == 1 ) {
5301							RESETFORM( form );
5302						}
5303					});
5304				}
5305				if ( form.attr( 'target' ) == undefined && window.self !== window.top ) {
5306					form.attr( 'target', '_top' );
5307				}
5308				if (form.attr('target') != undefined && NOT(IN(form.attr('target').toLowerCase(), ['_blank', '_self', '_top', '']))) {
5309					let loadHandler = function() {
5310							if ( $processed_flag ) return;
5311							$processed_flag = true;
5312							form.find('[cff-val-bk]').each(function () {
5313								let e = $(this);
5314								e.val(e.attr('cff-val-bk')).removeAttr('cff-val-bk');
5315							});
5316							form.find('[cff-disabled]').prop('disabled', false).removeAttr('cff-disabled');
5317							if (!/^(\s*|_self|_top|_parent)$/i.test(form.prop('target'))) {
5318								enabling_form();
5319							}
5320							$(document).trigger('cff-form-submitted', form);
5321						},
5322						$iframe = $('[name="' + form.prop('target') + '"]'),
5323						$processed_flag = false;
5324
5325					if ( $iframe.length ) {
5326						$iframe.off('load.cff-form-submission').on('load.cff-form-submission', loadHandler);
5327						setTimeout(function() {
5328							$iframe.off('load.cff-form-submission');
5329							loadHandler();
5330						}, 3000);
5331					}
5332				}
5333
5334				if('nativeSubmit' in form[0]) form[0].nativeSubmit();
5335				else form[0].submit();
5336			},
5337			reset_captcha_box = function () {
5338				let captcha_box = form.find('[id="hdcaptcha_cp_calculated_fields_form_post' + form_identifier + '"]');
5339				if (captcha_box.length) {
5340					$.ajax({
5341						type: "GET",
5342						url: form.prop('action').replace(/\?$/g, ''),
5343						data: {
5344							ps: form_identifier,
5345							cp_calculatedfieldsf: 'captcha',
5346							cff: cff_identifier,
5347							no_cache: Date.now()
5348						},
5349						success: function (response) {
5350							if (response.success && response.data.captcha) {
5351								form.find('[id^="cff_captcha_math_"]').text(response.data.captcha);
5352							}
5353						}
5354					});
5355
5356					captcha_box.val('');
5357				}
5358			},
5359			form_identifier = form.find('[name="cp_calculatedfieldsf_pform_psequence"]').val(),
5360			cff_identifier 	= form.find('[name="cp_calculatedfieldsf_id"]').val() || 1;
5361
5362		if (form_disabled()) return false;
5363
5364		form.find('[max=""]').removeAttr('max');
5365		form.find('[min=""]').removeAttr('min');
5366		form.find('[step=""]').removeAttr('step');
5367
5368		form.validate().settings.ignore = '.ignore';
5369		if (!form.valid()) {
5370			let page = form.find('.cpefb_error:not(.message):not(.ignore):eq(0)').closest('.pbreak').attr('page') * 1;
5371			gotopage(page, form);
5372            // Check if the field is inside a popup.
5373            form.find('.pbreak:visible .cpefb_error:not(.message):not(.ignore)').each(function(){
5374                let p = $(this).closest('.cff-popup-field');
5375                if(p.length > 0) {
5376                   SHOWFIELD(p);
5377                }
5378                let f = $(this).closest('.cff-collapsed');
5379                if(f.length > 0) {
5380                    f.removeClass('cff-collapsed');
5381                }
5382            });
5383            form.trigger('cff-form-validation', false);
5384			enabling_form();
5385			setTimeout(function(){$.fbuilder.openErrorDlg(form);},50);
5386			return false;
5387		}
5388
5389		validation_rules['no_pending'] = ! (
5390			(
5391				form_identifier in $.fbuilder.calculator.processing_queue &&
5392				$.fbuilder.calculator.processing_queue[form_identifier]
5393			) ||
5394			$.fbuilder.calculator.thereIsPending(form_identifier)
5395		);
5396
5397		if (
5398			!validation_rules['no_pending']
5399		) {
5400			$(document).on('equationsQueueEmpty', function (evt, formId) {
5401				if (formId == form_identifier) {
5402					$(document).off('equationsQueueEmpty');
5403					validation_rules['no_pending'] = true;
5404					processing_form();
5405				}
5406			});
5407			enabling_form();
5408			return false;
5409		}
5410
5411		// captcha validation.
5412		let captcha_box = form.find('[id="hdcaptcha_cp_calculated_fields_form_post' + form_identifier + '"]');
5413		if (captcha_box.length) {
5414			let cff_messages;
5415			try {
5416				cff_messages = $.fbuilder.forms[form_identifier]['settings']['messages'];
5417			} catch (e) { cff_messages = {}; }
5418			if (captcha_box.val() == '') {
5419				form.trigger('cff-form-validation', false);
5420				let captcha_error = (
5421					'captcha_required_text' in cff_messages
5422				) ? cff_messages.captcha_required_text : 'Captcha is required.';
5423				alert(captcha_error);
5424				enabling_form();
5425				return false;
5426			}
5427
5428			disabling_form();
5429			validation_rules['captcha'] = false;
5430			$.ajax({
5431				type: "GET",
5432				url: form.prop('action').replace(/\?$/g, ''),
5433				data: {
5434					ps: form_identifier,
5435					hdcaptcha_cp_calculated_fields_form_post: captcha_box.val(),
5436					cp_calculatedfieldsf_id: cff_identifier,
5437					no_cache: Date.now()
5438				},
5439				success: function (result) {
5440					enabling_form();
5441					if (result == "captchafailed") {
5442                        reset_captcha_box();
5443						form.trigger('cff-form-validation', false);
5444						let invalid_captcha_error = (
5445							'incorrect_captcha_text' in cff_messages
5446						) ? cff_messages.incorrect_captcha_text : 'Invalid captcha.';
5447						alert(invalid_captcha_error);
5448						return false;
5449					}
5450					else {
5451						validation_rules['captcha'] = true;
5452						processing_form();
5453					}
5454				}
5455			});
5456		}
5457
5458		processing_form();
5459		return false;
5460	};
5461
5462	// Read history
5463	window.addEventListener('popstate', function(){
5464		try
5465		{
5466			// Solves an issue with the datepicker if it is opened and back/next buttons in browser are pressed
5467			$(".ui-datepicker").hide();
5468			$.fbuilder.manageHistory();
5469		}
5470		catch(err){}
5471	});
5472
5473	$(window).on('load', function(){
5474		$.fbuilder.manageHistory(true);
5475	});
5476
5477	$(document).on('mousedown', '#fbuilder .cff-spinner-down,#fbuilder .cff-spinner-up', function(){
5478		var u = $(this).hasClass('cff-spinner-up'),
5479			e = $(this)[u ? 'prev' : 'next']('input'),
5480			o, s, m, v, l;
5481
5482		if(e.length) {
5483			e.attr('data-indeasing-decreasing', 1);
5484			o = getField(e.attr('id'), e[0].form);
5485			s = e.attr('step');
5486			if(isNaN(s*1)) s = 1;
5487			l = (new String(s)).split('.');
5488			s *= 1;
5489			l = l.length == 2 ? l[1].length : 0;
5490			m = e.attr(u ? 'max' : 'min');
5491
5492			function increase() {
5493				if ( typeof e.attr('data-indeasing-decreasing') != 'undefined' ) {
5494					v = o.val();
5495					if(e.hasClass('percent')){ v = PREC(v*100, 4)*1; }
5496					if(u) v += s;
5497					else v -= s;
5498					if(m) v = u ? MIN(v,m) : MAX(v,m);
5499					v = PREC(v,l);
5500					o.setVal(v);
5501					e.valid();
5502					setTimeout(function(){ increase(); }, 250);
5503				}
5504			}
5505			increase();
5506		}
5507	});
5508
5509	$(document).on('mouseup mouseleave', '#fbuilder .cff-spinner-down,#fbuilder .cff-spinner-up', function(){
5510		var u = $(this).hasClass('cff-spinner-up'),
5511			e = $(this)[u ? 'prev' : 'next']('input');
5512
5513		if(e.length) {
5514			e.removeAttr('data-indeasing-decreasing');
5515		}
5516	});
5517
5518	function assign_data_cff_field_content( field ) {
5519		try{
5520			field = $(field);
5521
5522			var field_name  = field.attr('name').match(/fieldname\d+/)[0];
5523				form_obj	= field.closest('form'),
5524				tags 		= form_obj.find('[data-cff-field="'+field_name+'"]');
5525			if( tags.length ){
5526				var	ignore 		= field.hasClass('ignore'),
5527					field_obj 	= getField(field, form_obj),
5528					value 		= (ignore || ! field_obj) ? '' : field_obj.val(('toSubmit' in field_obj  ? 'vt' : true), true);
5529
5530				value = Array.isArray(value) ? value.join(', ') : value;
5531				if(typeof value == 'string') {
5532					value = value.replace(/\\\\/g, "\\").replace(/\\'/g, "'").replace(/\\"/g, '"');
5533					// Patch for signatures and charts
5534					if( /^data\:image\/png;base64\,/i.test(value) ) {
5535						value = '<img src="'+value+'">';
5536					}
5537				}
5538				tags.each(function(){
5539					if ( field_obj && field_obj['ftype'].toLowerCase() == 'fpassword' ) {
5540						$(this).text(value);
5541					} else {
5542						$(this).html(cff_sanitize(value, true));
5543					}
5544				});
5545			}
5546		} catch( err ) { console.log(err); }
5547	};
5548
5549	$(document).on('change keyup', '#fbuilder :input[name*="fieldname"]', function(){
5550		var me = this;
5551		setTimeout( function(){assign_data_cff_field_content(me);}, 50);
5552	});
5553
5554	$(document).on('keyup', '#fbuilder :input[maxlength]', function(){
5555		var e = $( this ),
5556			v = new String( e.val() ),
5557			l = v.length,
5558			m = e.attr( 'maxlength' );
5559		if ( m*1 <= l ) {
5560			setTimeout( function(){ e.val( v.substring( 0, m ) ).trigger('change'); }, 5);
5561		}
5562	});
5563
5564	$(document).on('formReady cff-loaded-defaults', 'form', function(evt){
5565		try{
5566			var form_obj = $(evt.target);
5567			form_obj.find( '[data-cff-field]' ).each(function(){
5568				try {
5569					var tag_obj 	= $(this),
5570						field_name 	= tag_obj.attr('data-cff-field'),
5571						field_obj;
5572					if( field_name.length && /fieldname\d+/.test(field_name) ) {
5573						field_obj = form_obj.find('[name*="'+field_name+'_"]');
5574						if( field_obj.length ) assign_data_cff_field_content( field_obj );
5575					}
5576				} catch( err ) {}
5577			} );
5578		} catch( err ){}
5579	});
5580
5581	$.fbuilder.openErrorDlg = function(f){
5582		try {
5583			$.fbuilder.closeErrorDlg();
5584			$( document ).off('click', $.fbuilder.closeErrorDlg);
5585			setTimeout(function(){ $( document ).on('click', $.fbuilder.closeErrorDlg); }, 50);
5586
5587			let mssg = [];
5588			let errorList = $(f).validate().errorList;
5589
5590			errorList.forEach( (e) => {
5591				try {
5592					let m = cff_sanitize(e.message, true);
5593                    if ( m.length === 0 ) return;
5594					let n = e.element.name;
5595					if( n && /fieldname\d+_\d+/.test(n) ) {
5596						let o = getField( n.match(/fieldname\d+_\d+/)[0] );
5597						if ( o ) {
5598							let l = o.title;
5599							if('title' in o) {
5600								let l = cff_sanitize(o.title, true).replace(/\:\s*$/, '');
5601								if (l.length) {
5602									m = '<b>'+l+': </b>'+m;
5603								}
5604							}
5605						}
5606						if( mssg.indexOf( m ) === -1 ) mssg.push( m );
5607					}
5608				} catch(err){ console.log(err); }
5609			});
5610
5611			if ( mssg.length ) {
5612				$( f ).append( '<div class="cff-error-dlg">'+mssg.join('<br>')+'</div>' );
5613			}
5614		} catch ( err ) { console.log( err ); }
5615	};
5616	$.fbuilder.closeErrorDlg = function(){
5617		$('.cff-error-dlg').remove();
5618	};	$.fbuilder.controls[ 'ftext' ]=function(){};
5619	$.extend(
5620		$.fbuilder.controls[ 'ftext' ].prototype,
5621		$.fbuilder.controls[ 'ffields' ].prototype,
5622		{
5623			title:"Untitled",
5624			ftype:"ftext",
5625            autocomplete:"off",
5626			predefined:"",
5627			predefinedClick:false,
5628			required:false,
5629			readonly:false,
5630			size:"medium",
5631			minlength:"",
5632			maxlength:"",
5633			equalTo:"",
5634			regExp:"",
5635			regExpMssg:"",
5636			aiAssistant:false,
5637			show:function()
5638				{
5639					this.minlength = cff_esc_attr(String(this.minlength).trim());
5640					this.maxlength = cff_esc_attr(String(this.maxlength).trim());
5641					this.equalTo = cff_esc_attr(String(this.equalTo).trim());
5642					this.predefined = this._getAttr('predefined', true);
5643					return '<div class="fields '+cff_esc_attr(this.csslayout)+' '+this.name+' cff-text-field" id="field'+this.form_identifier+'-'+this.index+'" style="'+cff_esc_attr(this.getCSSComponent('container'))+'"><label for="'+this.name+'" style="'+cff_esc_attr(this.getCSSComponent('label'))+'">'+cff_sanitize(this.title, true)+''+((this.required)?"<span class='r'>*</span>":"")+'</label><div class="dfield"><input aria-label="'+cff_esc_attr(this.title)+'" id="'+this.name+'" name="'+this.name+'"'+((this.minlength.length) ? ' minlength="'+cff_esc_attr(this.minlength)+'"' : '')+((this.maxlength.length) ? ' maxlength="'+cff_esc_attr(this.maxlength)+'"' : '')+((this.equalTo.length) ? ' equalTo="#'+cff_esc_attr(this.equalTo)+this.form_identifier+'"':'')+' class="field '+cff_esc_attr(this.size)+((this.required)?" required":"")+'" '+((this.readonly)?'readonly':'')+' type="text" '+this._getValueAttr()+' autocomplete="'+this.autocomplete+'" style="'+cff_esc_attr(this.getCSSComponent('input'))+'" /><span class="uh" style="'+cff_esc_attr(this.getCSSComponent('help'))+'">'+cff_sanitize(this.userhelp, true)+'</span></div><div class="clearer"></div></div>';
5644				},
5645			after_show:function()
5646				{
5647					if(this.regExp != "" && typeof $[ 'validator' ] != 'undefined')
5648					{
5649						try {
5650							var parts 	= this.regExp.match(/(\/)(.*)(\/)([gimy]{0,4})$/i);
5651							this.regExp = (parts === null) ? new RegExp(this.regExp) : new RegExp(parts[2],parts[4].toLowerCase());
5652
5653							if(!('pattern' in $.validator.methods))
5654								$.validator.addMethod('pattern', function(value, element, param)
5655									{
5656										try{
5657											return this.optional(element) || param.test(value);
5658										}
5659										catch(err){return true;}
5660									}
5661								);
5662							$('#'+this.name).rules('add',{'pattern':this.regExp, messages:{'pattern':cff_sanitize(this.regExpMssg, true)}});
5663						} catch( err ) {}
5664					}
5665				},
5666			val:function(raw, no_quotes, disable_ignore_check)
5667				{
5668					raw = raw || false;
5669                    no_quotes = no_quotes || false;
5670					var e = (disable_ignore_check) ? $('[id="'+this.name+'"]') : $('[id="'+this.name+'"]:not(.ignore)'),
5671						v = e.length ? e.val() : (raw ? '' : 0);
5672					v = $.fbuilder.parseValStr(v, raw, no_quotes);
5673					return (raw && ! no_quotes && ! isNaN( v ) ) ? '"'+v+'"' : v;
5674				}
5675		}
5676	);	$.fbuilder.controls[ 'fcurrency' ] = function(){};
5677	$.extend(
5678		$.fbuilder.controls[ 'fcurrency' ].prototype,
5679		$.fbuilder.controls[ 'ffields' ].prototype,
5680		{
5681			title:"Currency",
5682			ftype:"fcurrency",
5683			predefined:"",
5684			predefinedClick:false,
5685			required:false,
5686			readonly:false,
5687            numberpad:false,
5688			spinner:false,
5689			size:"medium",
5690			currencySymbol:"",
5691			currencyText:"",
5692			thousandSeparator:",",
5693			centSeparator:".",
5694			noCents: false,
5695			min:"",
5696			max:"",
5697			step:1,
5698			formatDynamically:false,
5699			twoDecimals:false,
5700            _set_pre_post: function (attr, s)
5701                {
5702                    let e = document.getElementById(this.name);
5703                    if (e) {
5704                        if (e.type === 'number') e.type = 'text';
5705                        let v = e.value;
5706                        if (v !== '') {
5707                            let n = $.fbuilder.numberOfDecimals(v, this.centSeparator);
5708                            v = this.val(false, true, true);
5709                            this[attr] = s;
5710                            v = this.getFormattedValue(v, true, n);
5711                            this.setVal(v, true);
5712                        }
5713                    }
5714					this[attr] = s;
5715                },
5716            set_prefix:function(s) { this._set_pre_post('currencySymbol', s); },
5717            set_currencySymbol:function(s) { this._set_pre_post('currencySymbol', s); },
5718            set_postfix:function(s) { this._set_pre_post('currencyText', s); },
5719            set_currencyText:function(s) { this._set_pre_post('currencyText', s); },
5720			set_step:function(v, rmv)
5721				{
5722					var e = $('[id="'+this.name+'"]');
5723					if(rmv) e.removeAttr('step');
5724					else {
5725						var vb = e.val();
5726						e.removeAttr('value');
5727						if(!isNaN(v*1)) e.attr('step', Math.abs(v*1 ? v : 1));
5728						e.val(vb);
5729					}
5730                    if(!e.hasClass('cpefb_error')) e.removeClass('required');
5731					e.valid();
5732                    if(this.required) e.addClass('required');
5733				},
5734			set_min:function(v, rmv)
5735				{
5736					var e = $('[id="'+this.name+'"]');
5737					if(rmv) e.removeAttr('min');
5738					else if(!isNaN(v*1)) e.attr('min', v);
5739					if(!e.hasClass('cpefb_error')) e.removeClass('required');
5740					e.valid();
5741                    if(this.required) e.addClass('required');
5742				},
5743			set_max:function(v, rmv)
5744				{
5745					var e = $('[id="'+this.name+'"]');
5746					if(rmv) e.removeAttr('max');
5747					else if(!isNaN(v*1)) e.attr('max', v);
5748					if(!e.hasClass('cpefb_error')) e.removeClass('required');
5749					e.valid();
5750                    if(this.required) e.addClass('required');
5751				},
5752			getFormattedValue:function(value, force_format, decimals)
5753				{
5754					if(value == '') return value;
5755					if (
5756						this.formatDynamically || force_format
5757					) {
5758						var me = this,
5759							ts = me.thousandSeparator,
5760							tse = ts.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'),
5761							cs = ((cs = String(me.centSeparator).trim()) !== '') ? cs : '.',
5762							v = $.fbuilder.parseVal(
5763								( ts !== '' ? String(value).replace(new RegExp(tse + '(?!\\d{1,2}\\D*$)', "gi"), '') : value ),
5764								ts, cs
5765							),
5766							parts = [],
5767							counter = 0,
5768							str = '',
5769							sign = '';
5770
5771						if(!isNaN(v))
5772						{
5773							if(v < 0) sign = '-';
5774							v = ABS(v);
5775                            if(decimals !== undefined && decimals !== null) v = v.toFixed(decimals);
5776							else if(this.twoDecimals) v = v.toFixed(2);
5777							parts = v.toString().split(".");
5778
5779							for(var i = parts[0].length-1; i >= 0; i--)
5780							{
5781								counter++;
5782								str = parts[0][i]+str;
5783								if(counter%3 == 0 && i != 0) str = ts+str;
5784							}
5785							parts[0] = str;
5786
5787							if(parts[1])
5788							{
5789								if(parts[1].length == 1) parts[1] += '0';
5790							}
5791							else parts[ 1 ] = '00';
5792                            return me._getAttr('currencySymbol') + sign + ((me.noCents) ? parts[0] : parts.join(cs)) + me._getAttr('currencyText');
5793						}
5794					}
5795					return value;
5796				},
5797			init:function()
5798				{
5799					if(!/^\s*$/.test(this.currencySymbol)) this._setHndl('currencySymbol');
5800					if(!/^\s*$/.test(this.currencyText)) this._setHndl('currencyText');
5801					if(!/^\s*$/.test(this.min)) this._setHndl('min');
5802					if(!/^\s*$/.test(this.max)) this._setHndl('max');
5803					if(!/^\s*$/.test(this.step)) this._setHndl('step');
5804					else this.step = 1;
5805				},
5806			show:function()
5807				{
5808					this.predefined = this._getAttr('predefined', true);
5809					return '<div class="fields '+cff_esc_attr(this.csslayout)+' '+(this.spinner ? 'cff-spinner ' : '')+this.name+' cff-currency-field" id="field'+this.form_identifier+'-'+this.index+'"  style="'+cff_esc_attr(this.getCSSComponent('container'))+'"><label for="'+this.name+'" style="'+cff_esc_attr(this.getCSSComponent('label'))+'">'+cff_sanitize(this.title, true)+''+((this.required)?"<span class='r'>*</span>":"")+'</label><div class="dfield">'+
5810					(this.spinner ? '<div class="cff-spinner-components-container '+cff_esc_attr(this.size)+'"><button type="button" class="cff-spinner-down" style="'+cff_esc_attr(this.getCSSComponent('spinner_left'))+'">-</button>' : '')+
5811					'<input '+((this.numberpad) ? 'inputmode="decimal"' : '')+' aria-label="'+cff_esc_attr(this.title)+'" '+((this.readonly)? 'readonly' : '')+' id="'+this.name+'" name="'+this.name+'" class="field cffcurrency '+(this.spinner ? 'large' : cff_esc_attr(this.size))+((this.required)?" required":"")+'" type="text" '+this._getValueAttr(this.getFormattedValue(this.predefined))+' '+((!/^\s*$/.test(this.min)) ? 'min="'+cff_esc_attr($.fbuilder.parseVal(this._getAttr('min'), this.thousandSeparator, this.centSeparator))+'" ' : '')+((!/^\s*$/.test(this.max)) ? ' max="'+cff_esc_attr($.fbuilder.parseVal(this._getAttr('max'), this.thousandSeparator, this.centSeparator))+'" ' : '')+((!/^\s*$/.test(this.step)) ? ' step="'+cff_esc_attr(this._getAttr('step'))+'" ' : '')+' style="'+cff_esc_attr(this.getCSSComponent('input'))+'" />'+
5812					(this.spinner ? '<button type="button" class="cff-spinner-up" style="'+cff_esc_attr(this.getCSSComponent('spinner_right'))+'">+</button></div>' : '')+
5813					'<span class="uh" style="'+cff_esc_attr(this.getCSSComponent('help'))+'">'+cff_sanitize(this.userhelp, true)+'</span></div><div class="clearer"></div></div>';
5814				},
5815			after_show:function()
5816				{
5817					var me = this;
5818					if(me.formatDynamically) {
5819						$(document).on('change', '[name="'+me.name+'"]', function(){
5820							this.value = me.getFormattedValue(this.value);
5821						});
5822					}
5823					$('#'+me.name).rules('add', {'step':false});
5824				},
5825			val:function(raw, no_quotes, disable_ignore_check)
5826				{
5827					raw = raw || false;
5828                    no_quotes = no_quotes || false;
5829					var e = (disable_ignore_check) ? $('[id="'+this.name+'"]') : $('[id="'+this.name+'"]:not(.ignore)');
5830					if(e.length)
5831					{
5832						var v = String(e.val()).trim();
5833						v = this.getFormattedValue(v);
5834						if(raw) return ($.fbuilder.isNumeric(v)) ? v : $.fbuilder.parseValStr(v, raw, no_quotes);
5835
5836						v = v.replace(new RegExp($.fbuilder[ 'escapeSymbol' ](this.currencySymbol), 'g'), '')
5837						     .replace(new RegExp($.fbuilder[ 'escapeSymbol' ](this.currencyText), 'g'), '');
5838
5839						return $.fbuilder.parseVal(v, this.thousandSeparator, this.centSeparator, no_quotes);
5840					}
5841					return 0;
5842				}
5843		}
5844	);	$.fbuilder.controls[ 'fnumber' ] = function(){};
5845	$.extend(
5846		$.fbuilder.controls[ 'fnumber' ].prototype,
5847		$.fbuilder.controls[ 'ffields' ].prototype,
5848		{
5849			title:"Number",
5850			ftype:"fnumber",
5851			predefined:"",
5852			predefinedClick:false,
5853			required:false,
5854			readonly:false,
5855            numberpad:false,
5856			spinner:false,
5857			size:"medium",
5858			prefix:"",
5859			postfix:"",
5860			thousandSeparator:"",
5861			decimalSymbol:".",
5862			min:"",
5863			max:"",
5864			step:1,
5865			formatDynamically:false,
5866			twoDecimals:false,
5867			dformat:"digits",
5868            _set_pre_post:function(attr, s)
5869                {
5870                    let e = document.getElementById(this.name);
5871                    if (e) {
5872                        if (e.type === 'number') e.type = 'text';
5873                        let v = e.value;
5874                        if (v !== '') {
5875                            let n = $.fbuilder.numberOfDecimals(v, this.decimalSymbol);
5876                            v = this.val(false, true, true);
5877                            this[attr] = s;
5878                            v = this.getFormattedValue(v, true, n);
5879                            this.setVal(v, true);
5880                        }
5881                    }
5882					this[attr] = s;
5883                },
5884            set_prefix:function(s) { this._set_pre_post('prefix', s); },
5885            set_postfix:function(s) { this._set_pre_post('postfix', s); },
5886			set_step:function(v, rmv)
5887				{
5888					var e = $('[id="'+this.name+'"]');
5889					if(rmv) e.removeAttr('step');
5890					else {
5891						var vb = e.val();
5892						e.removeAttr('value');
5893						if(!isNaN(v*1)) e.attr('step', Math.abs(v*1 ? v : 1));
5894						e.val(vb);
5895					}
5896                    if(!e.hasClass('cpefb_error')) e.removeClass('required');
5897					e.valid();
5898                    if(this.required) e.addClass('required');
5899				},
5900			set_min:function(v, rmv)
5901				{
5902					var e = $('[id="'+this.name+'"]');
5903					if(rmv) e.removeAttr('min');
5904					else if(!isNaN(v*1)) e.attr('min', v);
5905					if(!e.hasClass('cpefb_error')) e.removeClass('required');
5906					e.valid();
5907                    if(this.required) e.addClass('required');
5908				},
5909			set_max:function(v, rmv)
5910				{
5911					var e = $('[id="'+this.name+'"]');
5912					if(rmv) e.removeAttr('max');
5913					else if(!isNaN(v*1)) e.attr('max', v);
5914					if(!e.hasClass('cpefb_error')) e.removeClass('required');
5915					e.valid();
5916                    if(this.required) e.addClass('required');
5917				},
5918			getFormattedValue:function(value, force_format, decimals)
5919				{
5920					if(value == '') return value;
5921					if(
5922						(
5923							(force_format || this.formatDynamically) &&
5924							this.dformat != 'digits'
5925						) ||  this.dformat == 'percent'
5926					) {
5927						var ts = this.thousandSeparator,
5928							tse = ts.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'),
5929							ds = ((ds=String(this.decimalSymbol).trim()) !== '') ? ds : '.',
5930							v = $.fbuilder.parseVal(
5931								( ts !== '' ? String(value).replace(new RegExp(tse + '(?!\\d{1,2}\\D*$)', "gi"), '') : value ),
5932								ts, ds
5933							),
5934							s = '',
5935							counter = 0,
5936							str = '',
5937							parts = [],
5938							step  = $('[id="'+this.name+'"]').attr('step'),
5939							prefix  = this.dformat == 'number' ? this._getAttr('prefix') : '',
5940							postfix = this.dformat == 'number' ? this._getAttr('postfix') : '';
5941
5942						if(!isNaN(v))
5943						{
5944							if(v < 0) s = '-';
5945							v = ABS(v);
5946                            if(decimals !== undefined && decimals !== null) v = v.toFixed(decimals);
5947							else if(this.twoDecimals && FLOOR(v) != v ) v = v.toFixed(2);
5948							parts = v.toString().split(".");
5949
5950							for(var i = parts[0].length-1; i >= 0; i--){
5951								counter++;
5952								str = parts[0][i]+str;
5953								if(counter%3 == 0 && i != 0) str = ts+str;
5954
5955							}
5956							parts[0]  = str;
5957							if(
5958								typeof parts[1] != 'undefined' &&
5959								parts[1]*1 &&
5960								typeof step != 'undefined' &&
5961								! isNaN(step*1)
5962							){
5963								var l = (new String(step)).split('.');
5964								if(l.length == 2){
5965									l = Math.max(l.length-(new String(parts[1])).length, 0);
5966									for(var i = 0; i < l; i++) parts[1] += '0';
5967								}
5968							}
5969							return prefix+s+parts.join(ds)+((this.dformat == 'percent') ? '%':'')+postfix;
5970						}
5971					}
5972					return value;
5973				},
5974			init:function()
5975				{
5976					if(!/^\s*$/.test(this.prefix)) this._setHndl('prefix');
5977					if(!/^\s*$/.test(this.postfix)) this._setHndl('postfix');
5978					if(!/^\s*$/.test(this.min)) this._setHndl('min');
5979					if(!/^\s*$/.test(this.max)) this._setHndl('max');
5980					if(!/^\s*$/.test(this.step)) this._setHndl('step');
5981					else this.step = 1;
5982				},
5983			show:function()
5984				{
5985					var _type = (
5986							this.dformat == 'digits' ||
5987							(
5988								this.dformat != 'percent' &&
5989								this.prefix == '' &&
5990								this.postfix == '' &&
5991								this.thousandSeparator == '' &&
5992								/^\s*(\.\s*)?$/.test(this.decimalSymbol) &&
5993								(
5994									!$.fbuilder.isMobile ||
5995									($.fbuilder.isMobile && !this.numberpad)
5996								)
5997							)
5998						) ? 'number' : 'text';
5999
6000                    if(this.dformat == 'digits') $(document).on('keydown', '#'+this.name, function(evt){if(/^[\-,\+,e,\.,\,]$/i.test(evt.key)){evt.preventDefault(); return false;}});
6001
6002                    this.predefined = this._getAttr('predefined', true);
6003					return '<div class="fields '+cff_esc_attr(this.csslayout)+' '+(this.spinner ? 'cff-spinner ' : '')+this.name+' cff-number-field" id="field'+this.form_identifier+'-'+this.index+'" style="'+cff_esc_attr(this.getCSSComponent('container'))+'"><label for="'+this.name+'" style="'+cff_esc_attr(this.getCSSComponent('label'))+'">'+cff_sanitize(this.title, true)+''+((this.required)?"<span class='r'>*</span>":"")+'</label><div class="dfield">'+
6004					(this.spinner ? '<div class="cff-spinner-components-container '+cff_esc_attr(this.size)+'"><button type="button" class="cff-spinner-down" style="'+cff_esc_attr(this.getCSSComponent('spinner_left'))+'">-</button>' : '')+
6005					'<input '+((this.numberpad && this.dformat != 'digits') ? 'inputmode="decimal"' : '')+' aria-label="'+cff_esc_attr(this.title)+'" id="'+this.name+'" name="'+this.name+'" '+((!/^\s*$/.test(this.min)) ? 'min="'+cff_esc_attr($.fbuilder.parseVal(this._getAttr('min'), this.thousandSeparator, this.decimalSymbol))+'" ' : '')+((!/^\s*$/.test(this.max)) ? ' max="'+cff_esc_attr($.fbuilder.parseVal(this._getAttr('max'), this.thousandSeparator, this.decimalSymbol))+'" ' : '')+((!/^\s*$/.test(this.step)) ? ' step="'+cff_esc_attr(this._getAttr('step'))+'" ' : '')+' class="field '+this.dformat+((this.dformat == 'percent') ? ' number' : '')+' '+(this.spinner ? 'large' : cff_esc_attr(this.size))+((this.required)?" required":"")+'" type="'+_type+'" '+this._getValueAttr(this.getFormattedValue(this.predefined))+' '+((this.readonly)?'readonly':'')+' style="'+cff_esc_attr(this.getCSSComponent('input'))+'" />'+
6006					(this.spinner ? '<button type="button" class="cff-spinner-up" style="'+cff_esc_attr(this.getCSSComponent('spinner_right'))+'">+</button></div>' : '')+
6007					'<span class="uh" style="'+cff_esc_attr(this.getCSSComponent('help'))+'">'+cff_sanitize(this.userhelp, true)+'</span></div><div class="clearer"></div></div>';
6008				},
6009			after_show:function()
6010				{
6011					var me = this;
6012
6013					if((me.formatDynamically && me.dformat != 'digits') ||  me.dformat == 'percent'){
6014						$(document).on('change', '[name="'+me.name+'"]', function(){
6015							this.value = me.getFormattedValue(this.value);
6016						});
6017					}
6018					$('#'+me.name).rules('add', {'step':false});
6019				},
6020			val:function(raw,no_quotes, disable_ignore_check)
6021				{
6022					raw = raw || false;
6023                    no_quotes = no_quotes || false;
6024					var e = (disable_ignore_check) ? $('[id="'+this.name+'"]') : $('[id="'+this.name+'"]:not(.ignore)');
6025					if( e.length )
6026					{
6027                        var v = String(e.val()).trim();
6028                        v = this.getFormattedValue(v);
6029                        if(raw) return ($.fbuilder.isNumeric(v) && this.thousandSeparator != '.') ? v : $.fbuilder.parseValStr(v, raw, no_quotes);
6030
6031                        v = v.replace(new RegExp($.fbuilder[ 'escapeSymbol' ](this.prefix), 'g'), '')
6032                                .replace(new RegExp($.fbuilder[ 'escapeSymbol' ](this.postfix), 'g'), '');
6033
6034                        v = $.fbuilder.parseVal(v, this.thousandSeparator, this.decimalSymbol, no_quotes);
6035                        return (this.dformat == 'percent') ? v/100 : v;
6036					}
6037					return 0;
6038				}
6039		}
6040	);		$.fbuilder.controls['fslider'] = function(){};
6041		$.extend(
6042			$.fbuilder.controls['fslider'].prototype,
6043			$.fbuilder.controls['ffields'].prototype,
6044			{
6045				title:"Slider",
6046				ftype:"fslider",
6047				exclude:false,
6048				readonly:false,
6049				predefined:"",
6050				predefinedMin:"",
6051				predefinedMax:"",
6052				predefinedClick:false,
6053				size:"medium",
6054				thousandSeparator:",",
6055				centSeparator:".",
6056				typeValues:false,
6057				min:0,
6058				max:100,
6059				step:1,
6060				marks:false,
6061				divisions:5,
6062				range:false,
6063				logarithmic:false,
6064				minCaption:"",
6065				maxCaption:"",
6066				caption:"{0}",
6067				_expon : function(v)
6068					{
6069						if(v == 0) return v;
6070						var el   = $('#'+this.name+'_slider'),
6071							step = this.calc_step, // el.slider('option', 'step'),
6072							min  = Math.max(el.slider('option', 'min'), step),
6073							max  = FLOOR(el.slider('option', 'max')/step)*step,
6074
6075							minv = Math.log(Math.max(min, 0.01)),
6076							maxv = Math.log(max),
6077							scale = (maxv - minv) / (max - min);
6078
6079						return ROUND(Math.exp( minv + scale * ( v - min ) ), step);
6080					},
6081				_inverse : function(v)
6082					{
6083						var el   = $('#'+this.name+'_slider'),
6084							step = this.calc_step, // el.slider('option', 'step'),
6085							min  = Math.max(el.slider('option', 'min'), step),
6086							max  = FLOOR(el.slider('option', 'max')/step)*step,
6087
6088							minv = Math.log(Math.max(min, 0.1)),
6089							maxv = Math.log(max),
6090							scale = (maxv - minv) / (max - min);
6091
6092						return ROUND( ( ( Math.log( v ) - minv ) / scale + min ), step );
6093					},
6094				_setThousandsSeparator : function(v)
6095					{
6096						let l = (new String(this.step)).split('.');
6097						l = l.length == 2 ? l[1].length : 0;
6098						v = $.fbuilder.parseVal(v, this.thousandSeparator, this.centSeparator);
6099						if(!isNaN(v))
6100						{
6101							v = PREC(v, l);
6102							var parts = v.toString().split("."),
6103								counter = 0,
6104								str = '';
6105
6106							for(var i = parts[0].length-1; i >= 0; i--)
6107							{
6108								counter++;
6109								str = parts[0][i] + str;
6110								if(counter%3 == 0 && i != 0) str = this.thousandSeparator + str;
6111
6112							}
6113							parts[0] = str;
6114							return parts.join(this.centSeparator);
6115						}
6116						else
6117						{
6118							return v;
6119						}
6120					},
6121				_setFieldValue:function(val, nochange)
6122					{
6123						var me = this;
6124						if(me.range)
6125						{
6126							var values = ( typeof val != 'undefined' && val !== null ) ? val : $('#'+me.name+'_slider').slider('values'),
6127								vl  = values[0], vr = values[1],
6128								vlf = me._setThousandsSeparator(vl),
6129								vrf = me._setThousandsSeparator(vr);
6130
6131							$('.'+me.name).find('.cff-slider-tooltip-value').first().html(cff_sanitize(vlf, true));
6132							$('.'+me.name).find('.cff-slider-tooltip-value').last().html(cff_sanitize(vrf, true));
6133							$('#'+me.name+'_component_left').val(cff_esc_attr(vlf));
6134							$('#'+me.name+'_component_right').val(cff_esc_attr(vrf));
6135							$('#'+me.name).val('['+vl+','+vr+']').attr('vt', '['+cff_esc_attr(vlf)+','+cff_esc_attr(vrf)+']');
6136                            if (/\{\s*0\s*\}/.test(me.caption)) {
6137                                $('#'+me.name+'_caption').html(
6138                                    cff_sanitize(
6139                                        me.caption
6140                                        .replace(/\{\s*0\s*\}/, vlf)
6141                                        .replace(/\{\s*0\s*\}/, vrf)
6142                                        , true
6143                                    )
6144                                );
6145                            }
6146						}
6147						else
6148						{
6149							var v  = ( typeof val != 'undefined' && val !== null ) ? val : $('#'+me.name+'_slider').slider('value'),
6150								vf = me._setThousandsSeparator(v);
6151
6152							$('.'+me.name).find('.cff-slider-tooltip-value').first().html(cff_sanitize(vf, true));
6153							$('#'+me.name).val(v).attr('vt', cff_esc_attr(vf));
6154							$('#'+me.name+'_component_center').val(cff_esc_attr(vf));
6155                            if (/\{\s*0\s*\}/.test(me.caption)) {
6156                                $('#'+me.name+'_caption').html(
6157                                    cff_sanitize(
6158                                        me.caption.replace(/\{\s*0\s*\}/g, vf)
6159                                        , true
6160                                    )
6161                                );
6162                            }
6163						}
6164						if(!nochange) $('#'+me.name).trigger('change');
6165					},
6166				_toNumber:function(n){
6167						n = $.fbuilder.parseVal(n, this.thousandSeparator, this.centSeparator);
6168						return (new String(n)).replace(/[^\-\d\.]/g,'')*1;
6169					},
6170				init:function()
6171					{
6172						this.min  = (/^\s*$/.test(this.min)) ? 0   : String(this.min).trim();
6173						this.max  = (/^\s*$/.test(this.max)) ? 100 : String(this.max).trim();
6174						this.step = (/^\s*$/.test(this.step)) ? 1   : String(this.step).trim();
6175						this.predefinedMin = (/^\s*$/.test(this.predefinedMin))? this.min : String(this.predefinedMin).trim();
6176						this.predefinedMax = (/^\s*$/.test(this.predefinedMax))? this.max : String(this.predefinedMax).trim();
6177						this._setHndl('min');
6178						this._setHndl('max');
6179						this._setHndl('step');
6180						this._setHndl('predefinedMin');
6181						this._setHndl('predefinedMax');
6182						this.centSeparator = (/^\s*$/.test(this.centSeparator)) ? '.' : String(this.centSeparator).trim();
6183						if(this.logarithmic && !isNaN(this.step)) { // TO CHECK
6184							this.calc_step = this.step;
6185							this.step = Math.min(this.step, 1);
6186						}
6187
6188						this.getCSSComponent('slider', true, '#fbuilder .'+this.name+' .ui-slider', this.form_identifier);
6189						this.getCSSComponent('slider_handle', true, '#fbuilder .'+this.name+' .ui-slider-handle', this.form_identifier);
6190						this.getCSSComponent('slider_range', true, '#fbuilder .'+this.name+' .ui-slider-range', this.form_identifier);
6191					},
6192				show:function()
6193					{
6194						var me = this;
6195						function typeValuesComponents()
6196						{
6197							function component(c)
6198							{
6199								var min = cff_esc_attr(me.min),
6200									max = cff_esc_attr(me.max),
6201									step = cff_esc_attr(me.step),
6202									predefined = cff_esc_attr(
6203										(c == 'left') ? me.predefinedMin :
6204										((c == 'right') ? me.predefinedMax : me.predefined)
6205									),
6206									timeoutId;
6207
6208								$(document).on('keyup change', '#'+me.name+'_component_'+c, function(evt){
6209                                    function stepRound(v)
6210                                    {
6211                                        var _e    = $('#'+me.name+'_slider'),
6212                                            _max  = _e.slider('option', 'max'),
6213                                            _step = _e.slider('option', 'step');
6214                                        return MIN(CEIL(v, _step), _max);
6215                                    };
6216									var v = $('#'+me.name+'_component_center').val(),
6217										v1 = $('#'+me.name+'_component_left').val(),
6218										v2 = $('#'+me.name+'_component_right').val(),
6219										t = 0;
6220									clearTimeout(timeoutId);
6221									if(evt.type == 'keyup') t = 2500;
6222									timeoutId = setTimeout(function(){
6223										if(v != undefined)
6224										{
6225											v = $.fbuilder.parseVal(v, me.thousandSeparator, me.centSeparator);
6226											if(isNaN(v)) v = 0;
6227										}
6228										if(v1 != undefined)
6229										{
6230											v1 = $.fbuilder.parseVal(v1, me.thousandSeparator, me.centSeparator);
6231											if(isNaN(v1)) v1 = 0;
6232										}
6233										if(v2 != undefined)
6234										{
6235											v2 = $.fbuilder.parseVal(v2, me.thousandSeparator, me.centSeparator);
6236											if(isNaN(v2)) v2 = 0;
6237										}
6238										$('#'+me.name+'_slider').slider(
6239											((v != undefined) ? 'value' : 'values'),
6240											((v != undefined) ? (me.logarithmic ? me._inverse(v*1) : stepRound(v*1)) : [stepRound(Math.min(v1*1,v2*1)), stepRound(Math.max(v1*1,v2*1))])
6241										);
6242										me._setFieldValue(me.logarithmic ? v : null);
6243									}, t);
6244								});
6245								return '<div class="slider-type-'+c+'-component"><input aria-label="'+cff_esc_attr(me.title)+'" id="'+me.name+'_component_'+c+'" class="large" type="text" value="'+cff_esc_attr(
6246									/fieldname/.test(predefined) &&
6247									getField(predefined) &&
6248									'val' in getField(predefined)
6249									? getField(predefined).val()
6250									: predefined
6251								)+'" '+((me.readonly) ? 'readonly' : '')+' style="'+cff_esc_attr(me.getCSSComponent('input'))+'" /></div>';
6252							};
6253
6254							var str = '';
6255							if(me.typeValues)
6256								str += '<div class="slider-type-components '+cff_esc_attr(me.size)+'">'+
6257								((me.range) ? component('left')+component('right') : component('center'))+
6258								'</div>';
6259							return str;
6260						};
6261						me.predefined = (/^\s*$/.test(me.predefined)) ? me.min : me._toNumber(me._getAttr('predefined'));
6262						return '<div class="fields '+cff_esc_attr(me.csslayout)+' '+me.name+' cff-slider-field" id="field'+me.form_identifier+'-'+me.index+'" style="'+cff_esc_attr(me.getCSSComponent('container'))+'">'+
6263							'<label style="'+cff_esc_attr(me.getCSSComponent('label'))+'">'+cff_sanitize(me.title, true)+'</label>'+
6264							'<div class="dfield slider-container">'+
6265								typeValuesComponents()+
6266								'<input id="'+me.name+'" name="'+me.name+'" class="field" type="hidden" value="'+cff_esc_attr(me.predefined)+'"/>'+
6267								'<div class="slider-component-container '+cff_esc_attr(me.size)+'">'+
6268								'<div id="'+me.name+'_slider" class="slider large"></div>'+
6269								'</div>'+
6270								'<div class="corner-captions '+cff_esc_attr(me.size)+'">'+
6271									'<span class="left-corner" style="'+cff_esc_attr(me.getCSSComponent('caption_left'))+'">'+cff_sanitize(me.minCaption, true)+'</span>'+
6272									'<span class="right-corner" style="'+cff_esc_attr(me.getCSSComponent('caption_right'))+'">'+cff_sanitize(me.maxCaption, true)+'</span>'+
6273									'<div id="'+me.name+'_caption" class="slider-caption" style="'+cff_esc_attr(me.getCSSComponent('caption'))+'">'+cff_sanitize(me.caption, true)+'</div>'+
6274									'<div class="clearer"></div>'+
6275								'</div>'+
6276								'<span class="uh" style="'+cff_esc_attr(me.getCSSComponent('help'))+'">'+cff_sanitize(me.userhelp, true)+'</span>'+
6277							'</div>'+
6278							'<div class="clearer"></div>'+
6279						'</div>';
6280					},
6281				get_min:function(){ return $('[id="'+this.name+'_slider"]').slider('option', 'min'); },
6282				get_max:function(){ return $('[id="'+this.name+'_slider"]').slider('option', 'max'); },
6283				set_min:function(v, ignore)
6284					{
6285						try{
6286							var e = $('[id="'+this.name+'_slider"]'), c = this.val(), r = false;
6287							if(ignore) v = 0;
6288							v = this._toNumber(v);
6289							e.slider('option', 'min', v);
6290							if(Array.isArray(c)){if(c[0] < v){c[0] = v; r = true;}}
6291							else if(c < v){c = v; r = true;}
6292							if(r) this.setVal(c);
6293							this.set_min_caption(v);
6294						}
6295						catch(err){}
6296					},
6297				set_max:function(v, ignore)
6298					{
6299						try{
6300							var e = $('[id="'+this.name+'_slider"]'), c = this.val(), r = false;
6301							if(ignore) v = 100;
6302							v = this._toNumber(v);
6303							e.slider('option', 'max', v);
6304							if(Array.isArray(c)){if(v < c[1]){c[1] = v; r = true;}}
6305							else if(v < c){c = v; r = true;}
6306							if(r) this.setVal(c);
6307							this.set_max_caption(v);
6308						}
6309						catch(err){}
6310					},
6311				set_min_caption:function(v)
6312					{
6313						try{
6314							var e = $('.'+this.name+' .left-corner');
6315                            if (/\{\s*0\s*\}/.test(this.minCaption)) {
6316							    e.html(cff_sanitize(this.minCaption.replace(/\{\s*0\s*\}/, v), true));
6317                            }
6318						}
6319						catch(err){}
6320					},
6321				set_max_caption:function(v)
6322					{
6323						try{
6324							var e = $('.'+this.name+' .right-corner');
6325                            if (/\{\s*0\s*\}/.test(this.maxCaption)) {
6326							    e.html(cff_sanitize(this.maxCaption.replace(/\{\s*0\s*\}/, v), true));
6327                            }
6328						}
6329						catch(err){}
6330					},
6331				set_step:function(v, ignore)
6332					{
6333						try{
6334							if(ignore) v = this.step;
6335							else this.step = this._toNumber(v);
6336
6337							if(this.logarithmic) { // TO CHECK
6338								this.calc_step = v;
6339								v = Math.min(v,1);
6340							}
6341							$('[id="'+this.name+'_slider"]').slider("option", "step", cff_esc_attr(v));
6342						}
6343						catch(err){}
6344					},
6345				set_marks:function(s,v){
6346					try {
6347						var me = this,
6348							e  = $( '.'+me.name+' .ui-slider-range');
6349						e.find('.mark').remove();
6350						if(s){
6351							for(let i = 0; i <= v; i++) {
6352								if( i && i != v ) {
6353									e.after('<span class="mark" style="position:absolute;
6353left:calc('+PREC(i*(100/v), 4, true)+'% );"></span>');
6354								}
6355							}
6356						}
6357					} catch( err ){}
6358				},
6359				after_show:function()
6360					{
6361						var me  = this,
6362							opt = {
6363								range: (me.range != false) ? me.range : "min",
6364								min  : me._toNumber(me._getAttr('min')),
6365								max  : me._toNumber(me._getAttr('max')),
6366								step : me._toNumber(me._getAttr('step')),
6367								isRTL: $.fbuilder.forms[me.form_identifier].isRTL
6368							};
6369
6370						me.set_min_caption(opt.min);
6371						me.set_max_caption(opt.max);
6372
6373						if(me.range)
6374						{
6375							var _min = Math.min(Math.max(me._getAttr('predefinedMin'), opt.min), opt.max),
6376								_max = Math.min(Math.max(me._getAttr('predefinedMax'), opt.min), opt.max);
6377							opt['values'] = [_min, _max];
6378						}
6379						else opt['value'] = Math.min(Math.max(me._getAttr('predefined'), opt.min), opt.max);
6380
6381						opt['disabled'] = me.readonly;
6382
6383						opt['slide'] = opt['stop'] = (function(e){
6384							return function(event, ui)
6385								{
6386									var v = (typeof ui.value != 'undefined') ? ui.value : ui.values;
6387
6388									if ( me.logarithmic ) {
6389										v = me._expon(v);
6390										e._setFieldValue(v);
6391									} else {
6392										$(this).slider( Array.isArray(v) ? 'values' : 'value', v);
6393										e._setFieldValue();
6394									}
6395								}
6396						})(me);
6397						$('#'+this.name+'_slider').slider(opt);
6398						$('#'+this.name+'_slider').find( '.ui-slider-handle' ).each( function(){
6399							$(this).append(
6400								'<div class="cff-slider-tooltip">'+
6401								'<div class="cff-slider-tooltip-value"></div>'+
6402								'<div class="cff-slider-tooltip-arrow"></div>'+
6403								'</div>'
6404							);
6405						});
6406						me._setFieldValue();
6407						$('#cp_calculatedfieldsf_pform'+me.form_identifier).on('reset', function(){
6408							setTimeout(function(){
6409								$('#'+me.name+'_slider').slider(opt); me._setFieldValue();
6410							}, 20);
6411						});
6412
6413						try{
6414							var divisions = parseInt(me.divisions);
6415							me.set_marks( me.marks, (isNaN(divisions) || ! divisions) ? (me.max-me.min)/me.step : divisions );
6416						} catch (err){}
6417					},
6418				val:function(raw, disable_ignore_check)
6419					{
6420						try{
6421							raw = raw || false;
6422							var e = (disable_ignore_check) ? $('[id="' + this.name + '"]') : $('[id="' + this.name + '"]:not(.ignore)');
6423							return (e.length) ? ((raw) ? e.val() : JSON.parse(e.val())) : 0;
6424						}
6425						catch(err){return 0;}
6426					},
6427				setVal:function(v, nochange)
6428					{
6429						let me = this;
6430						function _aux(v) { return Math.min( Math.max( v, me.get_min() ), me.get_max() ); };
6431						try{ v = JSON.parse(v); }catch(err){}
6432						try{
6433
6434							// Fix values format.
6435							if ( Array.isArray(v) ) {
6436								v = v.map(k => _aux(me._toNumber(k)));
6437								v.sort((a,b)=>a-b).splice(2);
6438							} else {
6439								v = me._toNumber(v);
6440								v = _aux(v);
6441							}
6442
6443							let e = $('[name="'+me.name+'"]'),
6444								bk = e[0].value;
6445
6446							e.val(v);
6447
6448							$('#'+me.name+'_slider').slider(((Array.isArray(v)) ? 'values' : 'value'), (me.logarithmic ? me._inverse(v) : v) );
6449							me._setFieldValue(v, nochange || bk === e[0].value || bk === '['+e[0].value+']');
6450						}catch(err){}
6451					}
6452		});	$.fbuilder.controls['fcolor']=function(){};
6453	$.extend(
6454		$.fbuilder.controls['fcolor'].prototype,
6455		$.fbuilder.controls['ffields'].prototype,
6456		{
6457			title:"Untitled",
6458			ftype:"fcolor",
6459			predefined:"",
6460			predefinedClick:false,
6461			required:false,
6462			readonly:false,
6463			size:"medium",
6464			show:function()
6465				{
6466					this.predefined = this._getAttr('predefined', true);
6467					return '<div class="fields '+cff_esc_attr(this.csslayout)+' '+this.name+' cff-color-field" id="field'+this.form_identifier+'-'+this.index+'" style="'+cff_esc_attr(this.getCSSComponent('container'))+'"><label for="'+this.name+'" style="'+cff_esc_attr(this.getCSSComponent('label'))+'">'+cff_sanitize(this.title, true)+''+((this.required)?"<span class='r'>*</span>":"")+'</label><div class="dfield"><input aria-label="'+cff_esc_attr(this.title)+'" id="'+this.name+'" name="'+this.name+'"'+' class="field '+cff_esc_attr(this.size)+((this.required)?" required":"")+'" '+((this.readonly)?'readonly':'')+' type="color" '+this._getValueAttr()+' style="'+cff_esc_attr(this.getCSSComponent('input'))+'" /><span class="uh" style="'+cff_esc_attr(this.getCSSComponent('help'))+'">'+cff_sanitize(this.userhelp, true)+'</span></div><div class="clearer"></div></div>';
6468				},
6469			after_show:function(){},
6470			val:function(raw, no_quotes, disable_ignore_check)
6471				{
6472					raw = raw || false;
6473                    no_quotes = no_quotes || false;
6474					var e = (disable_ignore_check) ? $('[id="' + this.name + '"]') : $('[id="' + this.name + '"]:not(.ignore)');
6475					if(e.length) return $.fbuilder.parseValStr(e.val(), raw, no_quotes);
6476					return 0;
6477				}
6478		}
6479	);	$.fbuilder.controls['femail'] = function(){};
6480	$.extend(
6481		$.fbuilder.controls['femail'].prototype,
6482		$.fbuilder.controls['ffields'].prototype,
6483		{
6484			title:"Email",
6485			ftype:"femail",
6486            autocomplete:"off",
6487			predefined:"",
6488			predefinedClick:false,
6489			required:false,
6490			readonly:false,
6491			size:"medium",
6492			equalTo:"",
6493			regExp:"",
6494			regExpMssg:"",
6495			show:function()
6496				{
6497					this.predefined = this._getAttr('predefined');
6498					return '<div class="fields '+cff_esc_attr(this.csslayout)+' '+this.name+' cff-email-field" id="field'+this.form_identifier+'-'+this.index+'" style="'+cff_esc_attr(this.getCSSComponent('container'))+'"><label for="'+this.name+'" style="'+cff_esc_attr(this.getCSSComponent('label'))+'">'+cff_sanitize(this.title, true)+''+((this.required)?"<span class='r'>*</span>":"")+'</label><div class="dfield"><input aria-label="'+cff_esc_attr(this.title)+'" id="'+this.name+'" name="'+this.name+'" '+((this.equalTo!="")?"equalTo=\"#"+cff_esc_attr(this.equalTo+this.form_identifier)+"\"":"")+' class="field email '+cff_esc_attr(this.size)+((this.required)?" required":"")+'" t
6498ype="email" '+this._getValueAttr()+' '+((this.readonly)?'readonly':'')+' autocomplete="'+this.autocomplete+'" style="'+cff_esc_attr(this.getCSSComponent('input'))+'" /><span class="uh" style="'+cff_esc_attr(this.getCSSComponent('help'))+'">'+cff_sanitize(this.userhelp, true)+'</span></div><div class="clearer"></div></div>';
6499				},
6500			after_show:function()
6501				{
6502					if(
6503						typeof this.regExp == 'string' &&
6504						this.regExp != "" &&
6505						typeof $['validator'] != 'undefined'
6506					) {
6507						try {
6508							var parts 	= this.regExp.match(/(\/)(.*)(\/)([gimy]{0,4})$/i);
6509							this.regExp = (parts === null) ? new RegExp(this.regExp) : new RegExp(parts[2],parts[4].toLowerCase());
6510
6511							if(!('pattern' in $.validator.methods))
6512								$.validator.addMethod('pattern', function(value, element, param)
6513									{
6514										try{
6515											return this.optional(element) || param.test(value);
6516										}
6517										catch(err){return true;}
6518									}
6519								);
6520							$('#'+this.name).rules('add',{'pattern':this.regExp, messages:{'pattern':cff_sanitize(this.regExpMssg, true)}});
6521						} catch ( err ) {}
6522					}
6523				},
6524			val:function(raw, no_quotes, disable_ignore_check)
6525				{
6526					raw = raw || false;
6527                    no_quotes = no_quotes || false;
6528					var e = (disable_ignore_check) ? $('[id="'+this.name+'"]') : $('[id="'+this.name+'"]:not(.ignore)'),
6529						v = e.length ? e.val() : (raw ? '' : 0);
6530					v = $.fbuilder.parseValStr(v, raw, no_quotes);
6531					return (raw && ! no_quotes && ! isNaN( v ) ) ? '"'+v+'"' : v;
6532				}
6533		}
6534	);	$.fbuilder.controls['fdate'] = function(){};
6535	$.extend(
6536		$.fbuilder.controls['fdate'].prototype,
6537		$.fbuilder.controls['ffields'].prototype,
6538		{
6539			title:"Date",
6540			ftype:"fdate",
6541			predefined:"",
6542			predefinedClick:false,
6543			size:"medium",
6544			required:false,
6545			readonly:false,
6546            disableKeyboardOnMobile:false,
6547
6548			// Date component
6549			showDatepicker: true,
6550			dformat:"mm/dd/yyyy",
6551			showFormatOnLabel:1,
6552			dseparator:"/",
6553			showDropdown:false,
6554			dropdownRange:"-10:+10",
6555            invalidDates:"",
6556            validDates:"",
6557            mondayFirstDay:false,
6558            alwaysVisible:false,
6559            showWeek:false,
6560			working_dates:[true,true,true,true,true,true,true],
6561			minDate:"",
6562			maxDate:"",
6563			currentDate:0,
6564			nextValid:0,
6565			defaultDate:"",
6566
6567			// Time component
6568			showTimepicker: false,
6569			tformat:"24",
6570			minHour:0,
6571			maxHour:23,
6572			minMinute:0,
6573			maxMinute:59,
6574			stepHour: 1,
6575			stepMinute: 1,
6576			defaultTime:"",
6577			timeErrorMssg:"",
6578
6579			// Labels
6580			ariaHourLabel: 'hours',
6581			ariaMinuteLabel: 'minutes',
6582			ariaAMPMLabel: 'am or pm',
6583
6584            // Error message
6585            errorMssg:'',
6586
6587			_get_regexp : function()
6588				{
6589					var me = this,
6590						df = me.dformat.replace(new RegExp('\\'+me.dseparator, 'g'), '/'),
6591						rt;
6592
6593					if(/^y/i.test(df)) rt = '(\\d{4})[^\\d](\\d{1,2})[^\\d](\\d{1,2})';
6594					else rt = '(\\d{1,2})[\\/\\-\\.](\\d{1,2})[\\/\\-\\.](\\d{4})';
6595
6596					return {d:df, r:rt};
6597				},
6598			_set_Events : function()
6599				{
6600					var me = this,
6601						f  = function(){
6602							me.set_dateTime();
6603							$('#'+me.name+'_date').valid();
6604						};
6605
6606					$(document).off('change', '#'+me.name+'_date').on('change', '#'+me.name+'_date', function(){
6607						if( me.showDatepicker && me.alwaysVisible )
6608							$('#'+me.name+'_datepicker_container').datepicker('setDate', this.value);
6609						f();
6610					});
6611					$(document).off('change', '#'+me.name+'_hours').on('change', '#'+me.name+'_hours', function(){f();});
6612					$(document).off('change', '#'+me.name+'_minutes').on('change', '#'+me.name+'_minutes', function(){f();});
6613					$(document).off('change', '#'+me.name+'_ampm').on('change', '#'+me.name+'_ampm', function(){f();});
6614
6615					$('#cp_calculatedfieldsf_pform'+me.form_identifier).on('reset', function(){
6616                        setTimeout(function(){me.set_DefaultDate(true); me.set_DefaultTime(); me.set_dateTime();},500);
6617                    });
6618				},
6619			_validateDate: function(d)
6620				{
6621					try{
6622						var e = this,
6623							w = e.working_dates,
6624							i = e.invalidDates,
6625							v = e.validDates,
6626							n = ( e.alwaysVisible && e.showDatepicker ) ? $('#'+e.name+'_datepicker_container') : $('#'+e.name+'_date'),
6627							isValid = Array.isArray(v) && v.length ? false : true;
6628
6629						d = d || n.datepicker('getDate');
6630
6631						if(d === null || !w[d.getDay()]) return false;
6632						if(v !== null)
6633						{
6634							for(var j = 0, h = v.length; j < h; j++)
6635							{
6636								if(d.getDate() == v[j].getDate() && d.getMonth() == v[j].getMonth() && d.getFullYear() == v[j].getFullYear()) {
6637									isValid = true;
6638									break;
6639								};
6640							}
6641						}
6642						if(!isValid) return false;
6643						if(i !== null)
6644						{
6645							for(var j = 0, h = i.length; j < h; j++)
6646							{
6647								if(d.getDate() == i[j].getDate() && d.getMonth() == i[j].getMonth() && d.getFullYear() == i[j].getFullYear()) return false;
6648							}
6649						}
6650
6651						var _d	= $.datepicker,
6652							_i  = _d._getInst(n[0]),
6653							_mi = _d._determineDate(_i, _d._get(_i, 'minDate'), null),
6654							_ma = _d._determineDate(_i, _d._get(_i, 'maxDate'), null);
6655
6656						if((_mi != null && d < _mi) || (_ma != null && _ma < d)) return false;
6657					}
6658					catch(_err){return false;}
6659					return true;
6660				},
6661			_validateTime : function()
6662				{
6663					var i = this;
6664					if(i.showTimepicker)
6665					{
6666						var n = i.name,
6667							h = $('#'+n+'_hours').val(),
6668							m = $('#'+n+'_minutes').val();
6669						if(i.tformat == 12)
6670						{
6671							var x = $('#'+n+'_ampm').val()
6672							if(x == 'pm' && h != 12) h = h*1+12;
6673							if(x == 'am' && h == 12) h = 0;
6674						}
6675
6676						let _min = i.minHour*60+i.minMinute,
6677							_max = i.maxHour*60+i.maxMinute,
6678							_t   = h*60+m*1;
6679
6680						if( _min <= _max ) {
6681							if ( _t < _min || _max < _t) return false;
6682						} else {
6683							if(_t < _min && _max < _t) return false;
6684						}
6685					}
6686					return true;
6687				},
6688			init:function()
6689				{
6690					var me 			= this,
6691						_checkValue = function(v, min, max)
6692						{
6693							v = parseInt(v);
6694							v = (isNaN(v)) ? max : v;
6695							return Math.min(Math.max(v,min),max);
6696						},
6697						_preprocessDates = function( v ){
6698							var	dateRegExp = new RegExp(/^\d{1,2}\/\d{1,2}\/\d{4}$/),
6699								counter    = 0,
6700								dates      = v.split(','),
6701								result     = [];
6702
6703							for(var i = 0, h = dates.length; i < h; i++)
6704							{
6705								var range = dates[i].split('-');
6706								if(range.length == 2 && range[0].match(dateRegExp) != null && range[1].match(dateRegExp) != null)
6707								{
6708									var fromD = new Date(range[0]),
6709										toD = new Date(range[1]);
6710									while(fromD <= toD)
6711									{
6712										result[counter] = fromD;
6713										var tmp = new Date(fromD.valueOf());
6714										tmp.setDate(tmp.getDate()+1);
6715										fromD = tmp;
6716										counter++;
6717
6718									}
6719								}
6720								else
6721								{
6722									for(var j = 0, k = range.length; j < k; j++)
6723									{
6724										if(range[j].match(dateRegExp) != null)
6725										{
6726											result[counter] = new Date(range[j]);
6727											counter++;
6728										}
6729									}
6730								}
6731							}
6732							return result;
6733						};
6734
6735					// Date
6736					me.dformat		= me.dformat.replace(/\//g, me.dseparator);
6737					if( typeof me.invalidDates == 'string' ) me.invalidDates = _preprocessDates(me.invalidDates.replace(/\s+/g, ''));
6738					if( typeof me.validDates == 'string' ) me.validDates   = _preprocessDates(me.validDates.replace(/\s+/g, ''));
6739
6740					if(me.dropdownRange.indexOf(':') == -1) me.dropdownRange = '-10:+10';
6741
6742					// Time
6743					me.minHour 		= _checkValue(me.minHour, 0, 23);
6744					me.maxHour 		= _checkValue(me.maxHour, 0, 23);
6745					me.minMinute 	= _checkValue(me.minMinute, 0, 59);
6746					me.maxMinute 	= _checkValue(me.maxMinute, 0, 59);
6747					me.stepHour 	= _checkValue(me.stepHour, 1, Math.max(1, Math.abs(me.maxHour - me.minHour)+1));
6748					me.stepMinute 	= _checkValue(me.stepMinute, 1, Math.max(1, Math.abs(me.maxHour-me.minHour)*60+Math.abs(me.maxMinute - me.minMinute)+1));
6749
6750					// Set handles
6751					me._setHndl('minDate');
6752					me._setHndl('maxDate');
6753                },
6754			get_hours:function()
6755				{
6756					function aux(from, to) {
6757						let options = '', h, i = 0;
6758						while((h = from+me.stepHour * i) <= to)
6759						{
6760							if(h < 10) h = '0'+''+h;
6761							options += '<option value="'+h+'">'+h+'</option>';
6762							i++;
6763						}
6764						return options;
6765					}
6766
6767					var me = this,
6768						str = '',
6769						from = (me.tformat == 12) ? 1  : me.minHour,
6770						to   = (me.tformat == 12) ? 12 : me.maxHour;
6771
6772					if (to < from || ( to == from && me.maxMinute < me.minMinute ) ) str += aux(0, to) + aux(from+(from == to ? 1 : 0), 23);
6773					else str += aux(from, to);
6774
6775					return '<select id="'+me.name+'_hours" name="'+me.name+'_hours" class="hours-component" aria-label="'+cff_esc_attr(me.ariaHourLabel)+'" '+((me.readonly) ? 'DISABLED' : '')+' style="'+cff_esc_attr(me.getCSSComponent('hour'))+'">'+str+'</select>:';
6776				},
6777			get_minutes:function()
6778				{
6779					var me = this,
6780						str = '',
6781						i = 0,
6782						m,
6783						n = (me.minHour == me.maxHour)?me.minMinute*1 : 0,
6784						x = (me.minHour == me.maxHour)?me.maxMinute*1 : 59;
6785
6786					while((m = n+me.stepMinute * i) <= x)
6787					{
6788						if(m < 10) m = '0'+''+m;
6789						str += '<option value="'+m+'">'+m+'</option>';
6790						i++;
6791					}
6792					return '<select id="'+me.name+'_minutes" name="'+me.name+'_minutes" class="minutes-component" aria-label="'+cff_esc_attr(me.ariaMinuteLabel)+'" '+((me.readonly) ? 'DISABLED' : '')+' style="'+cff_esc_attr(me.getCSSComponent('minute'))+'">'+str+'</select>';
6793				},
6794			get_ampm:function()
6795				{
6796					var str = '';
6797					if(this.tformat == 12)
6798					{
6799						return '<select id="'+this.name+'_ampm" class="ampm-component"  aria-label="'+cff_esc_attr(this.ariaAMPMLabel)+'" '+((this.readonly) ? 'DISABLED' : '')+' style="'+cff_esc_attr(this.getCSSComponent('ampm'))+'"><option value="am">am</option><option value="pm">pm</option></select>';
6800					}
6801					return str;
6802				},
6803			set_minTime:function(v, ignore)
6804				{
6805					let me = this;
6806					if(me.showTimepicker && typeof v == 'object' )
6807					{
6808						if ( 'hour' in v && ! isNaN( v.hour * 1 ) ) me.minHour = Math.min(23, Math.max(0,v.hour * 1));
6809						if ( 'minutes' in v && ! isNaN( v.minutes * 1 ) ) me.minMinute = Math.min(59, Math.max(0,v.minutes * 1));
6810						$('#'+me.name+'_hours,#'+me.name+'_minutes,#'+me.name+'_ampm').each((i,e)=>{$(e).valid();});
6811					}
6812				},
6813			set_maxTime:function(v, ignore)
6814				{
6815					let me = this;
6816					if(me.showTimepicker && typeof v == 'object' )
6817					{
6818						if ( 'hour' in v && ! isNaN( v.hour * 1 ) ) me.maxHour = Math.min(23, Math.max(0,v.hour * 1));
6819						if ( 'minutes' in v && ! isNaN( v.minutes * 1 ) ) me.maxMinute = Math.min(59, Math.max(0,v.minutes * 1));
6820						$('#'+me.name+'_hours,#'+me.name+'_minutes,#'+me.name+'_ampm').each((i,e)=>{$(e).valid();});
6821					}
6822				},
6823			set_dateTime:function(nochange)
6824				{
6825					var me  = this,
6826						str = $('#'+me.name+'_date').val(),
6827                        e   = $('#'+me.name),
6828						bk  = e.val();
6829					if(me.showTimepicker)
6830					{
6831						str += ' '+$('#'+me.name+'_hours').val();
6832						str += ':'+$('#'+me.name+'_minutes').val();
6833						if($('#'+me.name+'_ampm').length) str += $('#'+me.name+'_ampm').val();
6834					}
6835                    e.val(str);
6836					if ( ! nochange && bk !== e.val() ) e.trigger('change');
6837				},
6838			set_minDate:function(v, ignore)
6839				{
6840					if ( ! ( typeof v == 'number' || typeof v == 'string' || v instanceof Date ) ) return;
6841					var e = $('[id*="'+this.name+'_"].hasDatepicker'), f;
6842					if(e.length)
6843					{
6844						try {
6845							e.datepicker('option', 'minDate', (ignore) ? null : ( (typeof v == 'string') ? cff_esc_attr(v) : v ));
6846						}catch(err){ e.datepicker('option', 'minDate', null); }
6847						if( e.hasClass('datepicker-container') ) { f = e; e = e.siblings('.date-component'); }
6848						if(e.val() != '') e.trigger('change');
6849						else if( f ) f.find('.ui-state-active').removeClass('ui-state-active');
6850					}
6851				},
6852			set_maxDate:function(v, ignore)
6853				{
6854					if ( ! ( typeof v == 'number' || typeof v == 'string' || v instanceof Date ) ) return;
6855					var e = $('[id*="'+this.name+'_"].hasDatepicker'), f;
6856					if(e.length)
6857					{
6858						try {
6859							e.datepicker('option', 'maxDate', (ignore) ? null : ( (typeof v == 'string') ? cff_esc_attr(v) : v ));
6860						}catch (err){ e.datepicker('option', 'maxDate', null); }
6861						if( e.hasClass('datepicker-container') ) { f = e; e = e.siblings('.date-component'); }
6862						if(e.val() != '') e.trigger('change');
6863						else if( f ) f.find('.ui-state-active').removeClass('ui-state-active');
6864					}
6865				},
6866			set_DefaultDate : function(init)
6867				{
6868					var me  = this,
6869						aux = function (v) { 
6870							if (v === null || v === undefined) return undefined;
6871							if (typeof v === 'number' && isFinite(v)) return v;
6872							if (v instanceof Date && !isNaN(v.getTime())) return v;
6873							if (typeof v === 'string') {
6874								if (/^[+-]?\d+[dwmy]$/i.test(v.trim())) return v;
6875								let fmt = me.dformat || $.datepicker._defaults.dateFormat;
6876								try {
6877									fmt = fmt.replace(/y+/, 'yy');
6878									$.datepicker.parseDate(fmt, v);
6879									return v;
6880								} catch (e) {
6881									return undefined;
6882								}
6883							}
6884							return undefined;
6885						},
6886						p   = {
6887							dateFormat: me.dformat.replace(/yyyy/g,"yy"),
6888							minDate   : aux(me._getAttr('minDate')),
6889							maxDate   : aux(me._getAttr('maxDate')),
6890                            firstDay  : (me.mondayFirstDay ? 1 : 0),
6891                            showWeek  : me.showWeek,
6892							disabled  : me.readonly,
6893							beforeShow: function() {
6894								// Patch for elementor popup issue.
6895								let e = $('[name="'+me.name+'"]');
6896								if ( e.closest('.elementor-popup-modal').length ) {
6897									e.closest('form').after($('#ui-datepicker-div'));
6898								}
6899							},
6900							isRTL     : $.fbuilder.forms[me.form_identifier].isRTL
6901						},
6902						dp = $("#"+me.name+"_date"),
6903						// dd = (me.defaultDate != "") ? me.defaultDate : ((me.predefined != "") ? me.predefined : new Date());
6904						dd = me.currentDate && init ? new Date() : ((me.defaultDate != "") ? me.defaultDate : ((me.predefined != "" && !me.predefinedClick) ? me._getAttr('predefined') : ''));
6905
6906					if( me.alwaysVisible && me.showDatepicker ) {
6907						dp = $("#"+me.name+"_datepicker_container");
6908						p['altField'] = $("#"+me.name+"_date");
6909						p['altFormat'] = p['dateFormat'];
6910						p['onSelect'] = function( dateText, inst ){
6911							$("#"+me.name+"_date").trigger('change');
6912						};
6913					}
6914
6915					dp.on( 'click', function(){ $(document).trigger('click'); $(this).trigger('focus'); });
6916					if(me.showDropdown) p = $.extend(p,{changeMonth: true,changeYear: true,yearRange: me.dropdownRange});
6917					p = $.extend(p, {beforeShowDay:function(d){return [me._validateDate(d), ""];}});
6918					if(me.defaultDate != "") p.defaultDate = me.defaultDate;
6919					try {
6920						dp.datepicker(p);
6921					} catch(err) {}
6922                    if(!me.predefinedClick || !!init == false) {
6923						if ( me.nextValid && dd ) {
6924							dd = $.datepicker._determineDate({ settings: {} }, dd, new Date() );
6925							if ( dd && ( p.maxDate == '' || dd < $.datepicker._determineDate({ settings: {} }, p.maxDate, new Date() ) ) ) while( !me._validateDate(dd) ) dd.setDate(dd.getDate()+1);
6926						}
6927						dp.datepicker("setDate", dd);
6928					}
6929                    if(!me._validateDate()){ dp.datepicker("setDate", ''); $("#"+me.name+"_datepicker_container .ui-state-active").removeClass('ui-state-active');}
6930				},
6931			set_DefaultTime : function()
6932				{
6933					var me 			= this,
6934						_setValue 	= function(f, v, m)
6935						{
6936							if ( !isNaN(v*1) ) {
6937								v = Math.min(v*1, m*1);
6938								v = (v < 10) ? 0+''+v : v;
6939								$('#'+f+' [value="'+v+'"]').prop('selected', true);
6940							}
6941						};
6942
6943					if(me.showTimepicker)
6944					{
6945						var parts, time = {}, tmp = 0, max_minutes = 59;
6946						if((parts = /(\d{1,2}):(\d{1,2})\s*([ap]m)?/gi.exec(me.defaultTime)) != null)
6947						{
6948							time['hour'] = parts[1]*1+((parts.length == 4 && /pm/i.test(parts[3]) && parts[1] != 12) ? 12 : 0);
6949							time['minute'] = parts[2];
6950						}
6951						else
6952						{
6953							var d = new Date();
6954							time['hour'] = d.getHours();
6955							time['minute'] = d.getMinutes();
6956						}
6957
6958						if( me.maxHour < me.minHour) {
6959							if(me.minHour <= time['hour'] && time['hour'] <= me.maxHour)
6960								time['hour'] = Math.abs(me.minHour - time['hour']) < Math.abs(time['hour'] - me.maxHour) ? me.minHour : me.maxHour;
6961							if( time['hour'] == me.minHour ) time['minute'] = Math.min(time['minute'],me.minMinute);
6962							if( time['hour'] == me.maxHour ) time['minute'] = Math.max(time['minute'],me.maxMinute);
6963						} else {
6964							time['hour'] = Math.min(Math.max(time['hour'], me.minHour), me.maxHour);
6965							if(time['hour'] <= me.minHour) time['minute'] = Math.max(time['minute'],me.minMinute);
6966							if(me.maxHour <= time['hour']) time['minute'] = Math.min(time['minute'],me.maxMinute);
6967						}
6968
6969						_setValue(
6970							me.name+'_hours',
6971							(me.tformat == 12) ? ((time['hour'] > 12) ? time['hour'] - 12 : ((time['hour'] == 0) ? 12 : time['hour'])) : time['hour'],
6972							(me.tformat == 12) ? 12 : me.maxHour
6973						);
6974
6975						_setValue(me.name+'_minutes', time['minute'], (time['hour'] == me.maxHour) ? me.maxMinute : 59);
6976
6977						$('#'+me.name+'_ampm'+' [value="'+((time['hour'] < 12) ? 'am' : 'pm')+'"]').prop('selected', true);
6978					}
6979				},
6980			show:function()
6981				{
6982                    var me				= this,
6983						n 				= me.name,
6984						format_label   	= [],
6985						date_tag_type  	= 'text',
6986						disabled		= '',
6987						date_tag_class 	= 'field date'+me.dformat.replace(/[^a-z]/ig,"")+' '+((me.required && me.showDatepicker)?' required': '');
6988
6989                    if(me.showDatepicker && ! me.alwaysVisible) format_label.push(me.dformat);
6990					else{ date_tag_type = 'hidden'; if( ! me.alwaysVisible ) disabled='disabled';}
6991                    if(me.showTimepicker) format_label.push('HH:mm');
6992					let predefined = this._getAttr('predefined') || '';
6993					return '<div class="fields '+cff_esc_attr(me.csslayout)+' '+n+' cff-date-field" id="field'+me.form_identifier+'-'+me.index+'" style="'+cff_esc_attr(me.getCSSComponent('container'))+'"><label '+(me.showDatepicker ? 'for="'+n+'_date"' : '')+' style="'+cff_esc_attr(me.getCSSComponent('label'))+'">'+cff_sanitize(me.title, true)+''+((me.required)?"<span class='r'>*</span>":"")+((format_label.length && me.showFormatOnLabel) ? ' <span class="dformat" style="'+cff_esc_attr(me.getCSSComponent('dformat'))+'">('+cff_sanitize(format_label.join(' '), true)+')</span>' : '')+'</label>'+
6994					'<div class="dfield"><input id="'+n+'" name="'+n+'" type="hidden" '+( ! me.predefinedClick ? 'value="'+cff_esc_attr(predefined)+'"' : '' )+' />'+
6995					'<div class="cff-date-field-components '+me.size+'">'+
6996						'<input aria-label="'+cff_esc_attr(me.title)+'" id="'+n+'_date" name="'+n+'_date" class="'+cff_esc_attr(date_tag_class)+' date-component" type="'+date_tag_type+'" '+me._getValueAttr(predefined)+' '+disabled+(me.disableKeyboardOnMobile ? ' inputmode="none"' : '')+(me.errorMssg != '' ? ' data-msg="'+cff_esc_attr(me.errorMssg)+'"' : '')+' style="'+cff_esc_attr(me.getCSSComponent('date'))+'" />'+
6997
6998						(me.alwaysVisible && me.showDatepicker ? '<div id="'+n+'_datepicker_container" class="datepicker-container"></div>' : '')+
6999						((me.showTimepicker) ? ' <div class="time-component">'+me.get_hours()+me.get_minutes()+' '+me.get_ampm()+'</div>' : '')+
7000					'</div>'+
7001					'<span class="uh" style="'+cff_esc_attr(me.getCSSComponent('help'))+'">'+cff_sanitize(me.userhelp, true)+'</span></div><div class="clearer"></div></div>';
7002				},
7003			after_show:function()
7004				{
7005					var me = this,
7006						date_format = 'date'+me.dformat.replace(/[^a-z]/ig,""),
7007						_aux = function( e ){
7008							let p = e.id.replace(/_(date|hours|minutes|ampm)/i, '').split('_'),
7009								o = $.fbuilder.forms['_'+p[1]].getItem(p[0]);
7010							return o;
7011						},
7012						date_validator = function(v, e)
7013						{
7014							try
7015							{
7016								var i = _aux( e ),
7017									o = i._get_regexp(),
7018									d = $($(e).hasClass('hasDatepicker') ? e : $(e).siblings('.hasDatepicker:eq(0)')).datepicker('getDate');
7019
7020								if(i) return this.optional(e) ||
7021								(
7022									i._validateDate() &&
7023									(new RegExp(o.r)).test(v) &&
7024									DATEOBJ(v, me.dformat).getTime() == d.getTime()
7025								);
7026								return true;
7027							}
7028							catch(er)
7029							{
7030								return false;
7031							}
7032						},
7033						time_validator = function(v, e)
7034						{
7035							try
7036							{
7037								var i = _aux( e );
7038								if(i && i.showTimepicker) return i._validateTime();
7039								return true;
7040							}
7041							catch(er)
7042							{
7043								return false;
7044							}
7045						};
7046
7047                    if(!(date_format in $.validator.methods)) $.validator.addMethod(date_format, date_validator);
7048                    if(!('time_component' in $.validator.methods)) $.validator.addMethod('time_component', time_validator);
7049					$('#'+me.name+'_hours,#'+me.name+'_minutes,#'+me.name+'_ampm').each(function(){$(this).rules('add', {'time_component': true, 'messages' : {'time_component': me.timeErrorMssg}});});
7050
7051					me.set_DefaultDate(true);
7052					me.set_DefaultTime();
7053					me._set_Events();
7054					me.set_dateTime();
7055
7056					$('#'+me.name).on('change', function(){
7057						$('#'+me.name+'_date,#'+me.name+'_hours,#'+me.name+'_minutes,#'+me.name+'_ampm').each((i,e)=>{$(e).valid();});
7058					});
7059
7060				},
7061			val:function(raw, no_quotes, disable_ignore_check)
7062				{
7063					raw = raw || false;
7064                    no_quotes = no_quotes || false;
7065					var me = this,
7066						e  = (disable_ignore_check) ? $('[id="'+me.name+'"]') : $('[id="'+me.name+'"]:not(.ignore)'),
7067						o  = me._get_regexp();
7068
7069					if(e.length)
7070					{
7071						var v  = e.val();
7072						if(raw) return $.fbuilder.parseValStr(v, raw, no_quotes);
7073
7074						v  = String(e.val()).trim();
7075						var re = new RegExp('('+o.r+')?(\\s*(\\d{1,2})[:\\.](\\d{1,2})\\s*([amp]{2})?)?'),
7076							d  = re.exec(v),
7077							h  = 0,
7078							m  = 0,
7079							date;
7080
7081						if(d)
7082						{
7083							if(typeof d[6] != 'undefined') h = d[6]*1;
7084							if(typeof d[7] != 'undefined') m = d[7]*1;
7085							if(typeof d[8] != 'undefined')
7086							{
7087								var am = d[8].toLowerCase();
7088								if(am == 'pm' && h < 12) h += 12;
7089								if(am == 'am' && h == 12) h -= 12;
7090							}
7091							switch(o.d)
7092							{
7093								case 'yyyy/dd/mm':
7094									date = new Date(d[2], (d[4] * 1 - 1), d[3], h, m, 0, 0);
7095								break;
7096								case 'yyyy/mm/dd':
7097									date = new Date(d[2], (d[3] * 1 - 1), d[4], h, m, 0, 0);
7098								break;
7099								case 'dd/mm/yyyy':
7100									date = new Date(d[4], (d[3] * 1 - 1), d[2], h, m, 0, 0);
7101								break;
7102								case 'mm/dd/yyyy':
7103									date = new Date(d[4], (d[2] * 1 - 1), d[3], h, m, 0, 0);
7104								break;
7105							}
7106
7107							if(isFinite(date))
7108							{
7109								// if(me.showTimepicker) return date.valueOf()/86400000;
7110								// else return Math.ceil(date.valueOf()/86400000);
7111								return date.valueOf()/86400000;
7112							}
7113							else if(
7114								(
7115									! me.showDatepicker
7116									|| '' == String( $('[id="'+me.name+'_date"]').val() ).trim()
7117								) && me.showTimepicker
7118							) return (h*3600000+m*60000)/86400000;
7119						}
7120					}
7121					return 0;
7122				},
7123			setVal:function(v, nochange, init)
7124				{
7125					init = init || false;
7126					try
7127					{
7128                        if (v instanceof Date) v = GETDATETIMESTRING(v, this.dformat+(this.showTimepicker ? ' hh:mm' : ''));
7129						v = String(v).trim()
7130							 .replace(/\s+/g, ' ')
7131							 .split(' ');
7132						if(this.showDatepicker)
7133						{
7134							this.defaultDate = v[0];
7135							this.set_DefaultDate(init && ! this.defaultDate.length);
7136						}
7137						if(this.showTimepicker)
7138						{
7139							var t = (v.length == 2) ? v[1] : ((!this.showDatepicker) ? v[0] : false);
7140							if(t !== false)
7141							{
7142								this.defaultTime = t;
7143								this.set_DefaultTime();
7144							}
7145						}
7146						this.set_dateTime(nochange);
7147					}
7148					catch(err){}
7149				}
7150		}
7151	);	$.fbuilder.controls['ftimeslots'] = function(){};
7152	$.extend(
7153		$.fbuilder.controls['ftimeslots'].prototype,
7154		$.fbuilder.controls['ffields'].prototype,
7155		{
7156			title:"Date/Timeslots",
7157			ftype:"ftimeslots",
7158			predefined:"",
7159			predefinedClick:false,
7160			size:"medium",
7161			required:false,
7162			readonly:false,
7163            disableKeyboardOnMobile:false,
7164
7165			// Date component
7166			dformat:"mm/dd/yyyy",
7167			showFormatOnLabel:1,
7168			dseparator:"/",
7169			showDropdown:false,
7170			dropdownRange:"-10:+10",
7171            invalidDates:"",
7172            validDates:"",
7173            mondayFirstDay:false,
7174            alwaysVisible:false,
7175            showWeek:false,
7176			working_dates:[true,true,true,true,true,true,true],
7177			minDate:"",
7178			maxDate:"",
7179			currentDate:0,
7180			nextValid:0,
7181			defaultDate:"",
7182
7183			// Time slots component
7184			minHour:0,
7185			maxHour:23,
7186			minMinute:0,
7187			maxMinute:59,
7188			timeslotsDuration:"",
7189			sameForAllDays:true,
7190			preventEarlierSlots:true,
7191			maxSlotsPerSubmission:"",
7192			timeslots:[],
7193			timeslotsSelected:{},
7194			maxSlotsErrorMssg:"",
7195
7196			// Error message
7197            errorMssg:'',
7198			_two_digits : function(v)
7199				{
7200					if ( ! isNaN(v*1) ) {
7201						v = parseInt(v);
7202						if (v < 10) return '0'+v;
7203					}
7204					return v;
7205				},
7206			_slot_components : function( slot )
7207				{
7208					let me = this;
7209					let normalize_slot = function(v) {
7210						const match = v.match(/^(\d{1,2})\:(\d{1,2})\s*\-\s*(\d{1,2})\:(\d{1,2})$/);
7211						return me._two_digits(match[1])+':'+me._two_digits(match[2])+' - '+me._two_digits(match[3])+':'+me._two_digits(match[4]);
7212					};
7213					try {
7214						slot = String(slot).trim();
7215						if ( slot == '' ) return false;
7216						let c = slot.split(/\:(.*)/, 2);
7217						if ( c.length != 2 ) return false;
7218						let d = c[0].trim(),
7219							s = c[1].trim();
7220						if (
7221							! me._validate_dateText( d ) ||
7222							! me._validate_slotText( s )
7223						) return false;
7224						d = DATEOBJ( d, me.dformat );
7225						s = normalize_slot(s);
7226						if ( me._validate_date( d ) && me._validate_slot(d, s) ) {
7227							return {
7228								key : d.valueOf()+'|'+s,
7229								slot: GETDATETIMESTRING( d,me.dformat)+': '+s
7230							};
7231						}
7232					} catch (err) {}
7233					return false;
7234				},
7235			_set_events : function()
7236				{
7237					var me = this;
7238
7239					$(document).off('change', '#'+me.name).on('change', '#'+me.name, function(evt){$(evt.target).valid();});
7240					$(document).off('change', '#'+me.name+'_date').on('change', '#'+me.name+'_date', function(){
7241						if( me.alwaysVisible ) $('#'+me.name+'_datepicker_container').datepicker('setDate', this.value);
7242						me.set_fieldVal();
7243						$('#'+me.name+'_date').valid();
7244					});
7245
7246					$('#cp_calculatedfieldsf_pform'+me.form_identifier).on('reset', function(){
7247						$( '#'+me.name+'-error').remove();
7248						$( '#'+me.name).removeClass('cpefb_error');
7249						me.timeslotsSelected = {};
7250                        setTimeout(function(){
7251							me.set_defaultDate(true);
7252							me.set_fieldVal();
7253						},500);
7254                    });
7255
7256					let slots_selector = '.'+me.name+' .timeslots-component .cff-timeslot, .'+me.name+' .timeslots-selected-component .cff-timeslot-selected';
7257					$(document).off('click', slots_selector).on( 'click', slots_selector, function(){
7258						me._change_slotsStatus(this);
7259						me.set_fieldVal();
7260					}).off('keydown', slots_selector).on('keydown', slots_selector, function(evt){
7261						if (evt.code === 'Space' || evt.code === 'Enter') {
7262							$(evt.target).trigger('click');
7263						}
7264					});
7265
7266					$('#'+me.name).off('change').on('change', function(){
7267						$('#'+me.name+'_date').valid();
7268					});
7269
7270					let datepicker_selector = '#'+me.name+'_date,#'+me.name+'_datepicker_container';
7271					$(document).off('click', datepicker_selector).on('click', datepicker_selector, function(){ $(this).trigger('focus'); });
7272				},
7273			_validate_date: function(d)
7274				{
7275					try{
7276						var me = this,
7277							w = me.working_dates,
7278							i = me.invalidDates,
7279							v = me.validDates,
7280							e = ( me.alwaysVisible ) ? $('#'+me.name+'_datepicker_container') : $('#'+me.name+'_date'),
7281							isValid = Array.isArray(v) && v.length ? false : true;
7282
7283						d = d || e.datepicker('getDate');
7284
7285						if(
7286							d === null ||
7287							!w[d.getDay()]
7288						) return false;
7289
7290						if(v !== null)
7291						{
7292							for(var j = 0, h = v.length; j < h; j++)
7293							{
7294								if(d.getDate() == v[j].getDate() && d.getMonth() == v[j].getMonth() && d.getFullYear() == v[j].getFullYear()) {
7295									isValid = true;
7296									break;
7297								};
7298							}
7299						}
7300						if(!isValid) return false;
7301						if(i !== null)
7302						{
7303							for(var j = 0, h = i.length; j < h; j++)
7304							{
7305								if(d.getDate() == i[j].getDate() && d.getMonth() == i[j].getMonth() && d.getFullYear() == i[j].getFullYear()) return false;
7306							}
7307						}
7308
7309						var _d	= $.datepicker,
7310							_i  = _d._getInst(e[0]),
7311							_mi = _d._determineDate(_i, _d._get(_i, 'minDate'), null),
7312							_ma = _d._determineDate(_i, _d._get(_i, 'maxDate'), null),
7313							_p  = me.preventEarlierSlots,
7314							_c  = new Date();
7315
7316						_c.setHours(0, 0, 0, 0);
7317
7318						if((_mi != null && d < _mi) || (_ma != null && _ma < d) || (_p && d < _c)) return false;
7319					}
7320					catch(_err){console.log(_err);return false;}
7321					return d;
7322				},
7323			_validate_dateText : function( v )
7324				{
7325					let me = this,
7326						f  = me.dformat.toLowerCase().replace(/[^dmy]/g, '/'),
7327						r = /^y/i.test( f ) ? /^\d{4}[^\d]\d{1,2}[^\d]\d{1,2}$/ : /^\d{1,2}[^\d]\d{1,2}[^\d]\d{4}$/;
7328
7329					v = v || $('#'+me.name+'_date').val();
7330					if ( ! r.test(v) ) return false;
7331
7332					v = v.replace(/[^\d]/g,'/').split('/');
7333					let y, m, d;
7334					switch(f) {
7335						case 'dd/mm/yyyy': d = v[0]*1; m = v[1]*1; y = v[2]*1; break;
7336						case 'mm/dd/yyyy': d = v[1]*1; m = v[0]*1; y = v[2]*1; break;
7337						case 'yyyy/dd/mm': d = v[1]*1; m = v[2]*1; y = v[0]*1; break;
7338						case 'yyyy/mm/dd': d = v[2]*1; m = v[1]*1; y = v[0]*1; break;
7339						default: false;
7340					}
7341
7342					if (m < 1 || 12 < m || d < 1 || 31 < d) return false;
7343
7344					let	o = new Date(y, m - 1, d);
7345					return o.getFullYear() === y &&
7346						   o.getMonth() === m - 1 &&
7347						   o.getDate() === d;
7348				},
7349			_validate_slot: function(d, s) // d - date, s - slot.
7350				{
7351					let me = this,
7352						l  = me.timeslots[d.getDay()],
7353						_s = me.minHour*60+me.minMinute*1,
7354						_e = me.maxHour*60+me.maxMinute*1,
7355						n  = new Date();
7356
7357					if ( me.preventEarlierSlots ) {
7358						let ts = GETDATETIMESTRING(TODAY(), 'yyyy-mm-dd');
7359						let ds = GETDATETIMESTRING(d, 'yyyy-mm-dd');
7360						if ( ds < ts ) return false;
7361						if ( ds == ts ) {
7362							_s = MAX(_s, SUM(HOURS(NOW())*60, MINUTES(NOW())));
7363						}
7364					}
7365
7366					for ( let j in l ) {
7367						if (s == l[j]['slot']) {
7368							return l[j]['active'] && _s <= l[j]['start'] && l[j]['end'] <= _e;
7369						}
7370					}
7371					return false;
7372				},
7373			_validate_slotText : function( s )
7374				{
7375					return /^\d{1,2}\:\d{1,2}\s*\-\s*\d{1,2}\:\d{1,2}$/.test(s);
7376				},
7377			_is_slotSelected: function(d, s) // d - date, s - slot.
7378				{
7379					if ( d instanceof Date ) d = d.valueOf();
7380					return (d+'|'+s) in this.timeslotsSelected;
7381				},
7382			_get_slotsSelected: function()
7383				{
7384					let me = this,
7385						slots = me.timeslotsSelected,
7386						keys  = Object.keys(slots).sort(),
7387						max   = me.maxSlotsPerSubmission * 1,
7388						result = {};
7389
7390					if ( max ) keys = keys.slice(0, max);
7391
7392					for ( let k in keys ) {
7393						try {
7394							let d = new Date( keys[k].split('|')[0] * 1 ),
7395								s = keys[k].split('|')[1];
7396							if ( me._validate_date(d) && me._validate_slot(d, s) ) {
7397								result[keys[k]] = slots[keys[k]];
7398							}
7399						} catch (err) { console.log(err); }
7400					}
7401
7402					return result;
7403				},
7404			_change_slotsStatus: function( slot )
7405				{
7406					let me = this,
7407						e  = $(slot),
7408						d  = e.attr('data-day'),
7409						s  = e.attr('data-slot'),
7410						k  = d+'|'+s;
7411					if ( e.hasClass('cff-timeslot') ) {
7412						if ( e.attr('data-selected') * 1 ) {
7413							e.attr('data-selected', 0);
7414							delete me.timeslotsSelected[k];
7415							$('.'+me.name+' .cff-timeslot-selected[data-day="' + d + '"][data-slot="' + s + '"]').remove();
7416						} else {
7417							let n = me.maxSlotsPerSubmission * 1;
7418							if (
7419								n &&
7420								n <= Object.keys( me.timeslotsSelected ).length
7421							) {
7422								if ( me.maxSlotsErrorMssg.length ) alert( me.maxSlotsErrorMssg.replace( /\{0\}/g, n) );
7423								return;
7424							}
7425							d = new Date(d * 1);
7426							if ( me._validate_date(d) && me._validate_slot(d, s) ) {
7427								e.attr('data-selected', 1);
7428								me.timeslotsSelected[k] = GETDATETIMESTRING( d, me.dformat )+': '+s;
7429							}
7430						}
7431					} else {
7432						delete me.timeslotsSelected[k];
7433						$('.'+me.name+' .cff-timeslot-selected[data-day="' + d + '"][data-slot="' + s + '"]').remove();
7434						$('.'+me.name+' .cff-timeslot[data-day="' + d + '"][data-slot="' + s + '"]').attr('data-selected', 0);
7435					}
7436					me.set_fieldVal();
7437				},
7438			init:function()
7439				{
7440					var me 			= this,
7441						_checkValue = function(v, min, max)
7442						{
7443							v = parseInt(v);
7444							v = (isNaN(v)) ? max : v;
7445							return Math.min(Math.max(v,min),max);
7446						},
7447						_preprocessDates = function( v ){
7448							var	dateRegExp = new RegExp(/^\d{1,2}\/\d{1,2}\/\d{4}$/),
7449								counter    = 0,
7450								dates      = v.split(','),
7451								result     = [];
7452
7453							for(var i = 0, h = dates.length; i < h; i++)
7454							{
7455								var range = dates[i].split('-');
7456								if(range.length == 2 && range[0].match(dateRegExp) != null && range[1].match(dateRegExp) != null)
7457								{
7458									var fromD = new Date(range[0]),
7459										toD = new Date(range[1]);
7460									while(fromD <= toD)
7461									{
7462										result[counter] = fromD;
7463										var tmp = new Date(fromD.valueOf());
7464										tmp.setDate(tmp.getDate()+1);
7465										fromD = tmp;
7466										counter++;
7467
7468									}
7469								}
7470								else
7471								{
7472									for(var j = 0, k = range.length; j < k; j++)
7473									{
7474										if(range[j].match(dateRegExp) != null)
7475										{
7476											result[counter] = new Date(range[j]);
7477											counter++;
7478										}
7479									}
7480								}
7481							}
7482							return result;
7483						};
7484
7485					// Timeslots.
7486					for ( let d in me.timeslots ) {
7487						for (  let s in me.timeslots[d] ) {
7488							me.timeslots[d][s]['slot'] = me._two_digits(me.timeslots[d][s]['start']/60)+':'+me._two_digits(me.timeslots[d][s]['start']%60)+' - '+me._two_digits(me.timeslots[d][s]['end']/60)+':'+me._two_digits(me.timeslots[d][s]['end']%60);
7489						}
7490					}
7491
7492					// Date
7493					me.dformat		= me.dformat.replace(/\//g, me.dseparator);
7494					if( typeof me.invalidDates == 'string' ) me.invalidDates = _preprocessDates(me.invalidDates.replace(/\s+/g, ''));
7495					if( typeof me.validDates == 'string' ) me.validDates   = _preprocessDates(me.validDates.replace(/\s+/g, ''));
7496
7497					if(me.dropdownRange.indexOf(':') == -1) me.dropdownRange = '-10:+10';
7498
7499					// Time
7500					me.minHour 		= _checkValue(me.minHour, 0, 23);
7501					me.maxHour 		= _checkValue(me.maxHour, 0, 23);
7502					me.minMinute 	= _checkValue(me.minMinute, 0, 59);
7503					me.maxMinute 	= _checkValue(me.maxMinute, 0, 59);
7504
7505					// Set handles
7506					me._setHndl('minDate');
7507					me._setHndl('maxDate');
7508                },
7509			show_timeslots:function()
7510				{
7511					let me = this,
7512						output = '',
7513						_aux = function(v) { return ! isNaN(v) && v < 10 ? '0'+v : v; };
7514
7515					if( me.timeslots.length ) {
7516						let timeslots = [],
7517							d  = me._validate_dateText() && me._validate_date();
7518
7519						if ( d ) {
7520							let w = d.getDay(),
7521								timeslots = me.timeslots[w];
7522
7523							for ( let i in timeslots ) {
7524								let _timeslot = timeslots[i],
7525									_active    = me._validate_slot(d, _timeslot['slot']) ? 1 : 0,
7526									_selected  = _active && me._is_slotSelected( d, _timeslot['slot'] ) ? 1 : 0,
7527									_style 	   = '';
7528
7529								if ( ! _active ) _style='style="'+cff_esc_attr(me.getCSSComponent('disabledtimeslot'))+'"';
7530								else if ( ! _selected ) _style='style="'+cff_esc_attr(me.getCSSComponent('activetimeslot'))+'"';
7531								else _style='style="'+cff_esc_attr(me.getCSSComponent('selectedtimeslot'))+'"';
7532
7533								output += '<span class="cff-timeslot" data-active="' + _active + '" data-selected="' + _selected + '" data-day="' + d.valueOf() + '" data-slot="' + _timeslot['slot'] + '" ' + _style + ' tabindex="0">' + _timeslot['slot'] + '</span>';
7534							}
7535						}
7536					}
7537
7538					$( '.' + me.name + ' .timeslots-component' ).html( output );
7539				},
7540			show_timeslotsSelected:function()
7541				{
7542					let me 		= this,
7543						slots 	= me._get_slotsSelected(),
7544						output 	= '',
7545						_style	='style="'+cff_esc_attr(me.getCSSComponent('selectedtimeslot'))+'"';
7546
7547					for ( let i in slots ) {
7548						try {
7549							output += '<span class="cff-timeslot-selected" data-day="' + i.split('|')[0] + '" data-slot="' + i.split('|')[1] + '" ' + _style + ' tabindex="0">' + slots[i] + '</span>';
7550						} catch (err) { console.log(err); }
7551					}
7552
7553					$( '.' + me.name + ' .timeslots-selected-component' ).html( output );
7554				},
7555			set_date:function(d) {
7556				let me = this;
7557				if ( typeof d == 'string' ) {
7558					d = DATEOBJ(d, me.dformat);
7559				}
7560				if ( d instanceof Date && me._validate_date(d) ) {
7561					d = GETDATETIMESTRING( d, me.dformat );
7562					let e = ( me.alwaysVisible ) ? $('#'+me.name+'_datepicker_container') : $('#'+me.name+'_date');
7563					if (e.length) {
7564						e.datepicker('setDate', d);
7565						$('#'+me.name+'_date').trigger('change');
7566					}
7567				}
7568			},
7569			set_fieldVal:function(nochange)
7570				{
7571					var me    = this,
7572						e     = $('#'+me.name),
7573						bk    = e.val(),
7574						str   = '',
7575						sep   = '',
7576						slots = me._get_slotsSelected();
7577
7578					for ( let i in slots ) {
7579						try {
7580							str += sep + slots[i];
7581							sep = ', ';
7582						} catch (err) { console.log(err); }
7583					}
7584
7585					e.val(str);
7586
7587                    if ( ( typeof nochange == 'undefined' || ! nochange ) &&  bk !== str ) e.trigger('change');
7588
7589					me.show_timeslots();
7590					me.show_timeslotsSelected();
7591
7592				},
7593			set_minDate:function(v, ignore)
7594				{
7595					if ( ! ( typeof v == 'number' || typeof v == 'string' || v instanceof Date ) ) return;
7596					var e = $('[id*="'+this.name+'_"].hasDatepicker'), f;
7597					if(e.length)
7598					{
7599						try {
7600							e.datepicker('option', 'minDate', (ignore) ? null : ( (typeof v == 'string') ? cff_esc_attr(v) : v ));
7601						}catch(err){ e.datepicker('option', 'minDate', null); }
7602						if( e.hasClass('datepicker-container') ) { f = e; e = e.siblings('.date-component'); }
7603
7604						if(e.val() != '') e.trigger('change');
7605						else if( f ) f.find('.ui-state-active').removeClass('ui-state-active');
7606						this.set_fieldVal();
7607					}
7608				},
7609			set_maxDate:function(v, ignore)
7610				{
7611					if ( ! ( typeof v == 'number' || typeof v == 'string' || v instanceof Date ) ) return;
7612					var e = $('[id*="'+this.name+'_"].hasDatepicker'), f;
7613					if(e.length)
7614					{
7615						try {
7616							e.datepicker('option', 'maxDate', (ignore) ? null : ( (typeof v == 'string') ? cff_esc_attr(v) : v ));
7617						}catch (err){ e.datepicker('option', 'maxDate', null); }
7618						if( e.hasClass('datepicker-container') ) { f = e; e = e.siblings('.date-component'); }
7619
7620						if(e.val() != '') e.trigger('change');
7621						else if( f ) f.find('.ui-state-active').removeClass('ui-state-active');
7622						this.set_fieldVal();
7623					}
7624				},
7625			set_defaultDate : function(init)
7626				{
7627					var me  = this,
7628						aux = function (v) { 
7629							if (v === null || v === undefined) return undefined;
7630							if (typeof v === 'number' && isFinite(v)) return v;
7631							if (v instanceof Date && !isNaN(v.getTime())) return v;
7632							if (typeof v === 'string') {
7633								if (/^[+-]?\d+[dwmy]$/i.test(v.trim())) return v;
7634								let fmt = me.dformat || $.datepicker._defaults.dateFormat;
7635								try {
7636									fmt = fmt.replace(/y+/, 'yy');
7637									$.datepicker.parseDate(fmt, v);
7638									return v;
7639								} catch (e) {
7640									return undefined;
7641								}
7642							}
7643							return undefined;
7644						},
7645						p   = {
7646							dateFormat: me.dformat.replace(/yyyy/g,"yy"),
7647							minDate: aux(me._getAttr('minDate')),
7648							maxDate: aux(me._getAttr('maxDate')),
7649                            firstDay: (me.mondayFirstDay ? 1 : 0),
7650                            showWeek: me.showWeek,
7651							disabled: me.readonly,
7652							beforeShow: function() {
7653								// Patch for elementor popup issue.
7654								let e = $('[name="'+me.name+'"]');
7655								if ( e.closest('.elementor-popup-modal').length ) {
7656									e.closest('form').after($('#ui-datepicker-div'));
7657								}
7658							},
7659							isRTL     : $.fbuilder.forms[me.form_identifier].isRTL
7660						},
7661						dp = $("#"+me.name+"_date"),
7662						dd = me.currentDate && init ? new Date() : me.defaultDate,
7663						predefined = me._getAttr('predefined') || '';
7664
7665					if( me.alwaysVisible ) {
7666						dp = $("#"+me.name+"_datepicker_container");
7667						p['altField'] = $("#"+me.name+"_date");
7668						p['altFormat'] = p['dateFormat'];
7669						p['onSelect'] = function( dateText, inst ){
7670							$("#"+me.name+"_date").trigger('change');
7671						};
7672					}
7673
7674					if(me.showDropdown) p = $.extend(p,{changeMonth: true,changeYear: true,yearRange: me.dropdownRange});
7675					p = $.extend(p, {beforeShowDay:function(d){return [me._validate_date(d), ""];}});
7676					if(me.defaultDate != "") p.defaultDate = me.defaultDate;
7677
7678					if ( dp.length ) {
7679						try {
7680							dp.datepicker(p);
7681						} catch(err) {}
7682
7683						if ( me.nextValid && dd ) {
7684							dd = $.datepicker._determineDate({ settings: {} }, dd, new Date() );
7685							if ( dd && ( p.maxDate == '' || dd < $.datepicker._determineDate({ settings: {} }, p.maxDate, new Date() ) ) ) while( !me._validate_date(dd) ) dd.setDate(dd.getDate()+1);
7686						}
7687						dp.datepicker("setDate", dd);
7688						if(!me._validate_date()){
7689							dp.datepicker("setDate", ''); $("#"+me.name+"_datepicker_container .ui-state-active").removeClass('ui-state-active');
7690						}
7691					}
7692
7693					if ( me.predefinedClick ) {
7694						$("#"+me.name+"_date").attr('placeholder', predefined );
7695					} else {
7696						me.setVal( predefined );
7697					}
7698				},
7699			show:function()
7700				{
7701                    var me				= this,
7702						n 				= me.name,
7703						format_label   	= [],
7704						date_tag_type  	= 'text',
7705						disabled		= '';
7706
7707                    if(! me.alwaysVisible) format_label.push(me.dformat);
7708					else{ date_tag_type = 'hidden'; if( ! me.alwaysVisible ) disabled='disabled';}
7709					let predefined = this._getAttr('predefined') || '';
7710					return '<div class="fields '+cff_esc_attr(me.csslayout)+' '+n+' cff-timeslots-field" id="field'+me.form_identifier+'-'+me.index+'" style="'+cff_esc_attr(me.getCSSComponent('container'))+'">'+
7711					'<label for="'+n+'_date" style="'+cff_esc_attr(me.getCSSComponent('label'))+'">'+cff_sanitize(me.title, true)+''+((me.required)?"<span class='r'>*</span>":"")+((format_label.length && me.showFormatOnLabel) ? ' <span class="dformat" style="'+cff_esc_attr(me.getCSSComponent('dformat'))+'">('+cff_sanitize(format_label.join(' '), true)+')</span>' : '')+'</label>'+
7712					'<div class="dfield"><input id="'+n+'" name="'+n+'" type="hidden" '+( ! me.predefinedClick ? 'value="'+cff_esc_attr(predefined)+'"' : '' )+' class="'+( ( me.required ) ? ' required': '' )+'" />'+
7713					'<div class="cff-date-field-components '+me.size+'">'+
7714						'<input aria-label="'+cff_esc_attr(me.title)+'" id="'+n+'_date" name="'+n+'_date" class="field timeslots'+me.dformat.replace(/[^dmy]/ig,"")+' date-component" type="'+date_tag_type+'" '+disabled+(me.disableKeyboardOnMobile ? ' inputmode="none"' : '')+'data-msg="'+cff_esc_attr(me.errorMssg)+'" style="'+cff_esc_attr(me.getCSSComponent('date'))+'" />'+
7715						(me.alwaysVisible ? '<div id="'+n+'_datepicker_container" class="datepicker-container"></div>' : '')+
7716						'<div class="timeslots-component"></div>'+
7717						'<div class="timeslots-selected-component"></div>'+
7718					'</div>'+
7719					'<span class="uh" style="'+cff_esc_attr(me.getCSSComponent('help'))+'">'+cff_sanitize(me.userhelp, true)+'</span></div><div class="clearer"></div></div>';
7720				},
7721			after_show:function()
7722				{
7723					var me = this,
7724						date_format = 'timeslots'+me.dformat.replace(/[^dmy]/ig,"");
7725
7726					// Time slot validator.
7727                    if(!('timeslots' in $.validator.methods)) {
7728						$.validator.addMethod('timeslots', function(v, e, p) {
7729							try{
7730								return this.optional(e) || ! p || String(v).split(',').length <= p;
7731							}
7732							catch(err){return true;}
7733						});
7734					}
7735					if(!(date_format in $.validator.methods)) {
7736						$.validator.addMethod(date_format, function(v, e) {
7737							try
7738							{
7739								let f = getField(e.id.replace(/_date$/i, ''));
7740									d = $($(e).hasClass('hasDatepicker') ? e : $(e).siblings('.hasDatepicker:eq(0)')).datepicker('getDate');
7741
7742								return this.optional(e) ||
7743								(
7744									f._validate_dateText(v) &&
7745									f._validate_date(d)
7746								);
7747							}
7748							catch(er)
7749							{
7750								return false;
7751							}
7752						});
7753					}
7754
7755					$('#'+me.name).rules('add',{'timeslots':me.maxSlotsPerSubmission*1, messages:{'timeslots':cff_sanitize(me.maxSlotsErrorMssg, true)}});
7756
7757                    me.set_defaultDate(true);
7758					me._set_events();
7759					me.set_fieldVal();
7760				},
7761			set_timeslots:function( slots_array, weekday ){
7762				if ( weekday && ! isNaN( weekday ) ) {
7763					weekday = Math.max(0, Math.min(parseInt(weekday), 6));
7764					this.timeslots[weekday] = slots_array;
7765				} else {
7766					for ( let i in this.timeslots ) {
7767						this.timeslots[i] = slots_array;
7768					}
7769				}
7770				this.show_timeslots();
7771			},
7772			addSlot:function(slot,nochange)
7773				{
7774					let me = this;
7775					slot = me._slot_components(slot);
7776					if ( slot ) {
7777						me.timeslotsSelected[slot['key']] = slot['slot'];
7778						me.set_fieldVal(nochange);
7779					}
7780				},
7781			deleteSlot: function(slot, nochange)
7782				{
7783					let me = this;
7784					slot = me._slot_components(slot);
7785					if ( slot ) {
7786						delete me.timeslotsSelected[slot['key']];
7787						me.set_fieldVal(nochange);
7788					}
7789				},
7790			deleteSlots: function(nochange)
7791				{
7792					this.timeslotsSelected = {};
7793					this.set_fieldVal(nochange);
7794				},
7795			val:function(raw, no_quotes, disable_ignore_check)
7796				{
7797					raw = raw || false;
7798                    no_quotes = no_quotes || false;
7799					var me = this,
7800						e  = (disable_ignore_check) ? $('[id="'+me.name+'"]') : $('[id="'+me.name+'"]:not(.ignore)');
7801
7802					if(e.length)
7803					{
7804						var v  = e.val();
7805						if(raw) return $.fbuilder.parseValStr(v, raw, no_quotes);
7806
7807						// timeslots
7808						return Object.values(me._get_slotsSelected());
7809					}
7810					return 0;
7811				},
7812			setVal:function(v, nochange)
7813				{
7814					let me = this;
7815					try
7816					{
7817						if ( typeof v == 'string') {
7818							v = String(v).trim().replace(/\s+/g, ' ').split(',');
7819						}
7820
7821						if (Array.isArray(v)) {
7822							for ( let i in v ) {
7823								me.addSlot( v[i], nochange );
7824							}
7825						}
7826					}
7827					catch(err){}
7828				}
7829		}
7830	);	$.fbuilder.controls['ftextarea'] = function(){};
7831	$.extend(
7832		$.fbuilder.controls['ftextarea'].prototype,
7833		$.fbuilder.controls['ffields'].prototype,
7834		{
7835			title:"Untitled",
7836			ftype:"ftextarea",
7837            autocomplete:"off",
7838			predefined:"",
7839			predefinedClick:false,
7840			required:false,
7841			readonly:false,
7842			size:"medium",
7843			minlength:"",
7844			maxlength:"",
7845            rows:4,
7846			aiAssistant:false,
7847			show:function()
7848				{
7849					this.minlength = cff_esc_attr(String(this.minlength).trim());
7850					this.maxlength = cff_esc_attr(String(this.maxlength).trim());
7851					this.predefined = this._getAttr('predefined', true);
7852					return '<div class="fields '+cff_esc_attr(this.csslayout)+' '+this.name+' cff-textarea-field" id="field'+this.form_identifier+'-'+this.index+'" style="'+cff_esc_attr(this.getCSSComponent('container'))+'"><label for="'+this.name+'" style="'+cff_esc_attr(this.getCSSComponent('label'))+'">'+cff_sanitize(this.title, true)+''+((this.required)?"<span class='r'>*</span>":"")+'</label><div class="dfield"><textarea aria-label="'+cff_esc_attr(this.title)+'" '+((!/^\s*$/.test(this.rows)) ? 'rows='+cff_esc_attr(this.rows) : '')+' id="'+this.name+'" name="'+this.name+'"'+((this.minlength.length) ? ' minlength="'+cff_esc_attr(this.minlength)+'"' : '')+((this.maxlength.length) ? ' maxlength="'+cff_esc_attr(this.maxlength)+'"' : '')+' class="field '+cff_esc_attr(this.size)+((this.required)?" required":"")+'" '+((this.readonly)?'readonly':'')+' autocomplete="'+this.autocomplete+'" style="'+cff_esc_attr(this.getCSSComponent('textarea'))+'"></textarea>'+
7853					(this.maxlength.length ? '<div class="'+this.name+'_counter cff-textarea-counter '+cff_esc_attr(this.size)+'"></div>' : '')+
7854					'<span class="uh" style="'+cff_esc_attr(this.getCSSComponent('help'))+'">'+cff_sanitize(this.userhelp, true)+'</span></div><div class="clearer"></div></div>';
7855				},
7856			after_show:function(){
7857				let e = $('[id="'+this.name+'"]'),
7858					pre = (!this.predefinedClick) ? String(this.predefined).replace( /<\s*\/?\s*textarea\b[^>]*>/gi, '' ) : '',
7859					update_counter = function(e){
7860						$('.'+e.attr('name')+'_counter').text( e.val().length + '/' + e.attr('maxlength') );
7861					};
7862				if (pre) e.val(pre);
7863				update_counter(e);
7864				e.on('keyup change', function(){ update_counter( $(this) ); });
7865			},
7866			val:function(raw, no_quotes, disable_ignore_check)
7867				{
7868					raw = raw || false;
7869                    no_quotes = no_quotes || false;
7870					var e = (disable_ignore_check) ? $('[id="'+this.name+'"]') : $('[id="'+this.name+'"]:not(.ignore)'),
7871						v = e.length ? e.val() : (raw ? '' : 0);
7872					v = $.fbuilder.parseValStr(v, raw, no_quotes);
7873					if(!raw) v = String(v).replace(/[\n\r]+/g, ' ');
7874					else if(!no_quotes) v = String(v).replace(/^"/, "`").replace(/"$/, "`");
7875					return v;
7876				},
7877			setVal:function( v, nochange )
7878				{
7879					let e 	= $( "[id='" + this.name + "']" ),
7880						bk 	= e.val();
7881					e.val( String(v).replace( /<\s*\/?\s*textarea\b[^>]*>/gi, '' ) );
7882					if ( ! nochange && bk !== e.val() ) e.trigger('change');
7883				}
7884		}
7885	);	$.fbuilder.controls['fcheck']=function(){};
7886	$.extend(
7887		$.fbuilder.controls['fcheck'].prototype,
7888		$.fbuilder.controls['ffields'].prototype,
7889		{
7890			title:"Check All That Apply",
7891			ftype:"fcheck",
7892			layout:"one_column",
7893			required:false,
7894            readonly:false,
7895			merge:1,
7896            onoff:0,
7897			quantity:0,
7898			quantity_when_ticked:0,
7899            minQuantity: -1,
7900            maxQuantity: -1,
7901			max:-1,
7902			min:-1,
7903			maxError:"Check no more than {0} boxes",
7904			minError:"Check at least {0} boxes",
7905			toSubmit:"text",
7906			showDep:false,
7907			init:function(){
7908				this.getCSSComponent('choice', true, '#fbuilder .'+this.name+' .dfield label', this.form_identifier);
7909				if(isNaN(this.min*1)) this.min = -1;
7910				this.min *= 1;
7911				if(isNaN(this.max*1)) this.max = -1;
7912				this.max *= 1;
7913			},
7914			show:function()
7915				{
7916					this.choicesVal = ((typeof(this.choicesVal) != "undefined" && this.choicesVal !== null && this.choicesVal.length)?this.choicesVal:this.choices);
7917					var str = "",
7918                        classDep,
7919						n 	= this.name.match(/fieldname\d+/)[0];
7920
7921					if (typeof this.choiceSelected == "undefined" || this.choiceSelected == null)
7922						this.choiceSelected = new Array();
7923					if (typeof this.choicesDep == "undefined" || this.choicesDep == null)
7924						this.choicesDep = new Array();
7925
7926					for (var i=0, h=this.choices.length; i<h; i++)
7927					{
7928						if(typeof this.choicesDep[i] != 'undefined')
7929							this.choicesDep[i] = $.grep(this.choicesDep[i],function(x){ return x != "" && x != n; });
7930						else
7931							this.choicesDep[i] = [];
7932
7933						classDep = (this.choicesDep[i].length) ? 'depItem': '';
7934
7935						str += '<div class="'+this.layout+(this.quantity_when_ticked ? ' cff-quantity-when-ticked' : '')+'"><label for="'+this.name+'_cb'+i+'" '+(!this.tooltipIcon && this.userhelpTooltip && this.userhelp && this.userhelp.length ? 'uh="'+cff_esc_attr(this.userhelp)+'"' : '')+'><input aria-label="'+cff_esc_attr(this.choices[i])+'" name="'+this.name+'[]" id="'+this.name+'_cb'+i+'" class="field '+classDep+' group '+((this.required || 0 < this.min)?" required":"")+'" value="'+cff_esc_attr(this.choicesVal[i])+'" vt="'+cff_esc_attr((this.toSubmit == 'text') ? this.choices[i] : this.choicesVal[i])+'" type="checkbox" '+(this.readonly ? ' onclick="return false;" ' : '')+((this.choiceSelected[i])?"checked":"")+'/> '+
7936                        (this.onoff ? '<span class="cff-switch"></span>': '') +
7937                        '<span>'+cff_html_decode(this.choices[i])+'</span>'+
7938						(
7939						    this.quantity ?
7940                                '<span class="cff-checkbox-field-quantity"><input type="number" min="' + cff_esc_attr(Math.max(1, this.minQuantity)) + '" ' + ((this.maxQuantity > 0) ? 'max="' + cff_esc_attr(Math.max(1, this.minQuantity, this.maxQuantity)) + '"' : '') + ' value="' + cff_esc_attr(Math.max(1, this.minQuantity)) +'" id="'+this.name+'_cb'+i+'_quantity" /></span>' : ''
7941						) +
7942						'</label></div>';
7943					}
7944					return '<div class="fields '+cff_esc_attr(this.csslayout)+(this.onoff ? ' cff-switch-container' : '')+' '+this.name+' cff-checkbox-field" id="field'+this.form_identifier+'-'+this.index+'" style="'+cff_esc_attr(this.getCSSComponent('container'))+'"><label style="'+cff_esc_attr(this.getCSSComponent('label'))+'">'+cff_sanitize(this.title, true)+''+((this.required || 0 < this.min)?"<span class='r'>*</span>":"")+'</label><div class="dfield">'+str+'<div class="clearer"></div>'+(!this.userhelpTooltip ? '<span class="uh" style="'+cff_esc_attr(this.getCSSComponent('help'))+'">'+cff_sanitize(this.userhelp, true)+'</span>' : '')+'</div><div class="clearer"></div></div>';
7945				},
7946            enable_disable:function( e )
7947                {
7948                    var m = this, d = true;
7949                    if(0 < m.max )
7950                    {
7951						if ( 1 == m.max ) { // Set radio button behavior.
7952							if ( !! e && e.checked ) {
7953								let t = $('[id*="'+m.name+'_"]:not([id="'+e.id+'"]):checked');
7954								if ( t.length ) {
7955									t.prop('checked', false);
7956									if(t.hasClass('depItem')) {
7957										t.trigger('cff-dep-event');
7958									}
7959								}
7960								$(e).prop('checked', true);
7961							} else {
7962								$('[id*="'+m.name+'_"]:checked').each(function(){
7963									$(this).prop('checked', d);
7964									d = false;
7965								});
7966							}
7967						} else {
7968							if($('[id*="'+m.name+'_"]:checked').length < m.max) d = false;
7969							$('[id*="'+m.name+'_"]:not(:checked)').prop('disabled', d);
7970						}
7971                    }
7972                },
7973            after_show:function()
7974                {
7975                    var m = this, tmp;
7976
7977                    $(document).off('click','[id*="'+m.name+'_"]')
7978					.on('click','[id*="'+m.name+'_"]', function(evt){m.enable_disable( evt.target );});
7979                    m.enable_disable();
7980
7981					if( m.readonly ) {
7982						$('[id*="'+m.name+'_"][_onclick]').each(function(){$(this).attr('onclick', $(this).attr('_onclick'));});
7983					}
7984
7985					if( m.quantity ) {
7986						$(document).on('input', '[type="number"][id*="'+m.name+'_"]', function(){
7987							let base_id = $(this).attr('id').replace(/_quantity/, '');
7988							$('#'+base_id).trigger('change');
7989						});
7990					}
7991
7992					if(0 < m.max && 0 < m.min && m.max < m.min){
7993						tmp = m.min;
7994						m.min = m.max;
7995						m.max = tmp;
7996					}
7997
7998                    if(0 < m.max)
7999                        $('[id*="'+m.name+'_"][type="checkbox"]').rules('add',{maxlength:m.max, messages:{maxlength:cff_sanitize(m.maxError, true)}});
8000                    if(0 < m.min)
8001                        $('[id*="'+m.name+'_"][type="checkbox"]').rules('add',{minlength:m.min, messages:{minlength:cff_sanitize(m.minError, true)}});
8002                },
8003			showHideDep:function(toShow, toHide, hiddenByContainer, interval)
8004				{
8005                    if(typeof hiddenByContainer == 'undefined') hiddenByContainer = {};
8006					var me		= this,
8007						item 	= $('input[type="checkbox"][id*="'+me.name+'_"]'),
8008						formObj	= item.closest('form'),
8009						form_identifier = me.form_identifier,
8010						isHidden = (typeof toHide[me.name] != 'undefined' || typeof hiddenByContainer[me.name] != 'undefined'),
8011						result 	= [];
8012
8013					try
8014					{
8015						item.each(function(i,e){
8016							if(typeof me.choicesDep[i] != 'undefined' && me.choicesDep[i].length)
8017							{
8018								var checked = e.checked;
8019								for(var j = 0, k = me.choicesDep[i].length; j < k; j++)
8020								{
8021									if(!/(fieldname)|(__next_page__)|(__submit_button__)/i.test(me.choicesDep[i][j])) continue;
8022									let dep, isField = false;
8023                                    if ( /fieldname\d+/i.test(me.choicesDep[i][j]) ) {
8024                                        dep = me.choicesDep[i][j] + form_identifier; // Another field dependency
8025                                        isField = true;
8026                                    } else if ( me.choicesDep[i][j] == '__next_page__' ) {
8027                                        dep = '.pb' + item.closest('.pbreak').attr('page') + ':not(.pbEnd) .pbNext'; // Next page dependency
8028                                    } else {
8029                                        dep = '.pbSubmit,.captcha'; // Submission button dependency
8030                                    }
8031
8032									if(isHidden || !checked)
8033									{
8034										if(typeof toShow[dep] != 'undefined')
8035										{
8036											delete toShow[dep]['ref'][me.name+'_'+i];
8037											if($.isEmptyObject(toShow[dep]['ref']))
8038											delete toShow[dep];
8039										}
8040
8041										if(typeof toShow[dep] == 'undefined')
8042										{
8043                                            if (isField) {
8044											    $('[id*="'+dep+'"],.'+dep, formObj).closest('.fields').addClass('ignorefield').hide();
8045											    $('[id*="'+dep+'"]:not(.ignore)', formObj).addClass('ignore').trigger('add-ignore');
8046                                            } else {
8047                                                $(dep, formObj).hide();
8048                                            }
8049											toHide[dep] = {};
8050										}
8051									}
8052									else
8053									{
8054										delete toHide[dep];
8055										if(typeof toShow[dep] == 'undefined')
8056										toShow[dep] = { 'ref': {}};
8057										toShow[dep]['ref'][me.name+'_'+i]  = 1;
8058										if(!(dep in hiddenByContainer))
8059										{
8060                                            if (isField) {
8061											    $('[id*="'+dep+'"],.'+dep, formObj).closest('.fields').removeClass('ignorefield').fadeIn(interval || 0);
8062											    $('[id*="'+dep+'"].ignore', formObj).removeClass('ignore').trigger('remove-ignore');
8063                                            } else {
8064                                                $(dep, formObj).fadeIn(interval || 0);
8065                                            }
8066										}
8067									}
8068									if($.inArray(dep,result) == -1) result.push(dep);
8069								}
8070							}
8071						});
8072					}
8073					catch(e){  }
8074					return result;
8075				},
8076			val:function(raw, no_quotes, disable_ignore_check)
8077				{
8078					raw = raw || false;
8079                    no_quotes = no_quotes || false;
8080					var v, me = this, m = me.merge && !raw, q = me.quantity,
8081						e = (disable_ignore_check) ? $('[id*="'+me.name+'_"]:checked') : $('[id*="'+me.name+'_"]:checked:not(.ignore)');
8082
8083					if(!m) v = [];
8084					if(e.length)
8085					{
8086						if ( raw == 'q' ) {
8087							v = me.getQuantity();
8088						} else {
8089							e.each(function(){
8090								var t = (m) ? $.fbuilder.parseVal(this.value) : $.fbuilder.parseValStr((raw == 'vt') ? this.getAttribute('vt') : this.value, raw, no_quotes);
8091								if(!$.fbuilder.isNumeric(t)) t = t.replace(/^"/,'').replace(/"$/,'');
8092
8093								if( q && $.fbuilder.isNumeric(t) ) t = t*Math.max( $('#'+this.id+'_quantity').val(), 1 );
8094								else if( q ) t += ' ('+ Math.max( $('#'+this.id+'_quantity').val(), 1 ) +')';
8095
8096								if(m) v = (v)?v+t:t;
8097								else v.push(t);
8098							});
8099						}
8100					}
8101					return (typeof v == 'object' && typeof v['length'] !== 'undefined') ? v : ((v) ? (($.fbuilder.isNumeric(v)) ? v : '"'+v+'"') : 0);
8102				},
8103			setVal:function(v, nochange, _default)
8104				{
8105					let t, me = this, n = me.name, c = 0, e;
8106					let aux	= function(v, attr) {
8107						let result;
8108						if (me.quantity) {
8109							let v_parts = /^(.*)(\s*\((\d+)\))$/.exec(v);
8110							if( v_parts && typeof v_parts[3] != 'undefined' ) {
8111								v_parts[1] = String(v_parts[1]).replace(/\s$/, '');
8112								result = $('[type="checkbox"][id*="'+n+'_"]['+attr+'="'+v_parts[1]+'"]');
8113								if ( result.length ) {
8114									$( '[id="'+result.attr('id')+'_quantity"]' ).val(v_parts[3]);
8115								}
8116							}
8117						}
8118
8119						if (!result || !result.length) {
8120							result = $('[type="checkbox"][id*="'+n+'_"]['+attr+'="'+v+'"]');
8121						}
8122
8123						return result;
8124					};
8125
8126                    _default = _default || false;
8127                    nochange = nochange || false;
8128
8129					if(!Array.isArray(v)) v = [v];
8130
8131					let bk = JSON.stringify(me.val(true)),
8132						bk_vt = JSON.stringify(me.val('vt')),
8133						bk_checked = $('[id*="'+n+'_"]:checked').map(function(){return this.id;}).get();
8134
8135					$('[id*="'+n+'_"]').prop('checked', false);
8136					for(let i in v)
8137					{
8138						t = (new String(v[i])).replace(/(['"])/g, "\\$1");
8139                        if(0 < me.max && me.max < c+1) break;
8140                        if(_default) e = aux(t, 'vt');
8141                        if(!_default || !e.length)  e = aux(t, 'value');
8142                        if(e.length){
8143							e.prop('checked', true);
8144							let bk_checked_index = bk_checked.indexOf(e.attr('id'));
8145							if(bk_checked_index != -1) bk_checked.splice(bk_checked_index, 1);
8146							else if(e.hasClass('depItem')) {
8147								e.trigger('cff-dep-event');
8148							}
8149							c++;
8150						}
8151					}
8152					for(let i in bk_checked) {
8153						$('[id="'+bk_checked[i]+'"].depItem').trigger('cff-dep-event');
8154					}
8155                    me.enable_disable();
8156					if (
8157						! nochange &&
8158						(
8159							bk !== JSON.stringify( me.val( true ) ) ||
8160							bk_vt !== JSON.stringify( me.val( 'vt' ) )
8161						)
8162					) $('[id*="'+n+'_"]:eq(0)').trigger('change');
8163				},
8164			setChoices:function(choices)
8165				{
8166					if($.isPlainObject(choices))
8167					{
8168						var me = this,
8169                            bk = me.val('vt', false, true);
8170						if('texts' in choices && Array.isArray(choices.texts)) me.choices = choices.texts;
8171						if('values' in choices && Array.isArray(choices.values)) me.choicesVal = choices.values;
8172						if('dependencies' in choices && Array.isArray(choices.dependencies))
8173                        {
8174                            me.choicesDep = choices.dependencies.map(
8175                                function(x){
8176                                    return (Array.isArray(x)) ? x.map(
8177                                        function(y){
8178                                            return (typeof y == 'number') ? 'fieldname'+parseInt(y) : y;
8179                                        }) : x;
8180                                }
8181                          );
8182                        }
8183						var html = me.show(),
8184							e = $('.'+me.name),
8185							i = e.hasClass('ignorefield') || e.find('.ignore').length,
8186							ipb = e.find('.ignorepb').length || e.closest('.pbreak:hidden').length;
8187						e.find('.dfield').replaceWith($(html).find('.dfield'));
8188						if(i) e.find('input').addClass('ignore');
8189						if(ipb) e.find('input').addClass('ignorepb');
8190						if(!Array.isArray(bk)) bk = [bk];
8191                        for(var j in bk)
8192                        {
8193                            try{ try{ bk[j] = JSON.parse(bk[j]); }catch(err){ bk[j] = bk[j].replace(/\\+(['"])/g, '$1'); } }catch(err){}
8194						}
8195						me.setVal(bk, bk.every(function(e){ return me.choicesVal.indexOf(e) > -1; }), true);
8196						if(me.quantity && 'quantities' in choices && Array.isArray(choices.quantities)) {
8197							$('[type="number"][id*="'+me.name+'"]').each(function(i, e){
8198								if( !isNaN(choices.quantities[i]) && 1 < choices.quantities[i]*1 ) {
8199									$(this).val(choices.quantities[i]*1).change();
8200								}
8201							});
8202						}
8203					}
8204				},
8205			getIndex:function() // Get an array of the ticked choices indexes.
8206				{
8207					var i = [];
8208					$('input[type="checkbox"][name*="'+this.name+'"]').each(function(j,v){if(this.checked){i.push(j);}});
8209					return i;
8210				},
8211			getQuantity:function() // Get an array of the ticked choices quantities, or empty array.
8212				{
8213					var q = [];
8214					if ( this.quantity ) {
8215						$('input[type="checkbox"][name*="'+this.name+'"]:checked').each(function(){
8216							let e = $('#'+this.id+'_quantity');
8217							if ( e.length ) {
8218								let v = parseFloat(e.val());
8219								if ( ! isNaN( v ) ) q.push( v );
8220							}
8221						});
8222					}
8223					return q;
8224				}
8225		}
8226	);	$.fbuilder.controls['fradio']=function(){};
8227	$.extend(
8228		$.fbuilder.controls['fradio'].prototype,
8229		$.fbuilder.controls['ffields'].prototype,
8230		{
8231			title:"Select a Choice",
8232			ftype:"fradio",
8233			layout:"one_column",
8234			required:false,
8235            readonly:false,
8236			onoff:0,
8237			toSubmit:"text",
8238			choiceSelected:"",
8239			showDep:false,
8240			untickAccepted:true,
8241			nextPage:false,
8242			initStatus:function()
8243				{
8244					$('[id*="'+this.name+'_"]').each(function(){$(this).data('previous-status', this.checked);});
8245				},
8246			init:function(){
8247				this.getCSSComponent('choice', true, '#fbuilder .'+this.name+' .dfield label', this.form_identifier);
8248			},
8249			show:function()
8250				{
8251					this.choicesVal = ((typeof(this.choicesVal) != "undefined" && this.choicesVal !== null && this.choicesVal.length)?this.choicesVal:this.choices);
8252
8253					var l 		 = this.choices.length,
8254						str 	 = "",
8255						classDep = "",
8256						n 	 	 = this.name.match(/fieldname\d+/)[0];
8257
8258					if (typeof this.choicesDep == "undefined" || this.choicesDep == null)
8259						this.choicesDep = new Array();
8260
8261					for (var i=0;i<l;i++)
8262					{
8263						if(typeof this.choicesDep[i] != 'undefined')
8264							this.choicesDep[i] = $.grep(this.choicesDep[i],function(x){ return x != "" && x != n; });
8265						else
8266							this.choicesDep[i] = [];
8267
8268						if(this.choicesDep[i].length)
8269							classDep = 'depItem';
8270					}
8271
8272					for (var i=0;i<l;i++)
8273					{
8274						str += '<div class="'+this.layout+'"><label for="'+this.name+'_rb'+i+'" '+(!this.tooltipIcon && this.userhelpTooltip && this.userhelp && this.userhelp.length ? 'uh="'+cff_esc_attr(this.userhelp)+'"' : '')+'><input aria-label="'+cff_esc_attr(this.choices[i])+'" name="'+this.name+'" id="'+this.name+'_rb'+i+'" class="field '+classDep+' group '+((this.required)?" required":"")+'" value="'+cff_esc_attr(this.choicesVal[i])+'" vt="'+cff_esc_attr((this.toSubmit=='text') ? this.choices[i] : this.choicesVal[i])+'" type="radio" '+(this.readonly ? ' onclick="return false;" ' : '')+((this.choices[i]+' - '+this.choicesVal[i]==this.choiceSelected)?"checked":"")+'/> '+
8275                        (this.onoff ? '<span class="cff-switch"></span>': '') +
8276                        '<span>'+cff_html_decode(this.choices[i])+'</span></label></div>';
8277					}
8278
8279					return '<div class="fields '+cff_esc_attr(this.csslayout)+(this.onoff ? ' cff-switch-container' : '')+' '+this.name+' cff-radiobutton-field" id="field'+this.form_identifier+'-'+this.index+'" style="'+cff_esc_attr(this.getCSSComponent('container'))+'"><label style="'+cff_esc_attr(this.getCSSComponent('label'))+'">'+cff_sanitize(this.title, true)+''+((this.required)?"<span class='r'>*</span>":"")+'</label><div class="dfield">'+str+'<div class="clearer"></div>'+(!this.userhelpTooltip ? '<span class="uh" style="'+cff_esc_attr(this.getCSSComponent('help'))+'">'+cff_sanitize(this.userhelp, true)+'</span>' : '')+'</div><div class="clearer"></div></div>';
8280				},
8281			after_show: function()
8282				{
8283					var me = this,
8284						n = me.name;
8285
8286					me.initStatus();
8287					if(me.untickAccepted)
8288					{
8289						$(document).off('click', '[id*="'+n+'_"]').on('click', '[id*="'+n+'_"]', function(){
8290							var m = this,
8291								e = $(m);
8292
8293							$('[id*="'+n+'_"]').each(function(){if(m !== this) $(this).data('previous-status', false);});
8294							if(e.data('previous-status')){ m.checked = false; e.trigger('change');}
8295							e.data('previous-status', m.checked);
8296						});
8297					}
8298
8299					if( me.readonly ) {
8300						$('[id*="'+n+'_"][_onclick]').each(function(){$(this).attr('onclick', $(this).attr('_onclick'));});
8301					}
8302
8303					if ( me.nextPage ) {
8304						$('.fields.'+n).on( 'change', '[id*="'+n+'_"]', function(evt){
8305							if ( ! ( 'originalEvent' in evt ) || ! evt.originalEvent.isTrusted ) return;
8306							if( $('[id*="'+n+'_"]:checked').length ) {
8307								let p = $( this ).closest('.pbreak:not(.pbEnd):visible');
8308								if ( p.length && $(this.form).validate().checkForm() ) {
8309									let i = p.attr('page');
8310									GOTOPAGE(SUM(i, 1), this.form);
8311								}
8312							}
8313						});
8314					}
8315				},
8316			showHideDep:function(toShow, toHide, hiddenByContainer, interval)
8317				{
8318                    if(typeof hiddenByContainer == 'undefined') hiddenByContainer = {};
8319					var me		= this,
8320						item 	= $('input[id*="'+me.name+'_"]'),
8321						form_identifier = me.form_identifier,
8322						formObj	= item.closest('form'),
8323						isHidden = (typeof toHide[me.name] != 'undefined' || typeof hiddenByContainer[me.name] != 'undefined'),
8324						result 	= [];
8325
8326					try
8327					{
8328						item.each(function(i,e){
8329							if(typeof me.choicesDep[i] != 'undefined' && me.choicesDep[i].length)
8330							{
8331								var checked = e.checked;
8332								for(var j = 0, k = me.choicesDep[i].length; j < k; j++)
8333								{
8334                                    if (!/(fieldname)|(__next_page__)|(__submit_button__)/i.test(me.choicesDep[i][j])) continue;
8335                                    let dep, isField = false;
8336                                    if (/fieldname\d+/i.test(me.choicesDep[i][j])) {
8337                                        dep = me.choicesDep[i][j] + form_identifier; // Another field dependency
8338                                        isField = true;
8339                                    } else if (me.choicesDep[i][j] == '__next_page__') {
8340                                        dep = '.pb' + item.closest('.pbreak').attr('page') + ':not(.pbEnd) .pbNext'; // Next page dependency
8341                                    } else {
8342                                        dep = '.pbSubmit,.captcha'; // Submission button dependency
8343                                    }
8344
8345									if(isHidden || !checked)
8346									{
8347										if(typeof toShow[dep] != 'undefined')
8348										{
8349											delete toShow[dep]['ref'][me.name+'_'+i];
8350											if($.isEmptyObject(toShow[dep]['ref']))
8351											delete toShow[dep];
8352										}
8353
8354										if(typeof toShow[dep] == 'undefined')
8355										{
8356                                            if (isField) {
8357                                                $('[id*="'+dep+'"],.'+dep, formObj).closest('.fields').addClass('ignorefield').hide();
8358                                                $('[id*="'+dep+'"]:not(.ignore)', formObj).addClass('ignore').trigger('add-ignore');
8359                                            } else {
8360                                                $(dep, formObj).hide();
8361                                            }
8362											toHide[dep] = {};
8363										}
8364									}
8365									else
8366									{
8367										delete toHide[dep];
8368										if(typeof toShow[dep] == 'undefined')
8369										toShow[dep] = { 'ref': {}};
8370										toShow[dep]['ref'][me.name+'_'+i]  = 1;
8371										if(!(dep in hiddenByContainer))
8372										{
8373                                            if (isField) {
8374                                                $('[id*="'+dep+'"],.'+dep, formObj).closest('.fields').removeClass('ignorefield').fadeIn(interval || 0);
8375                                                $('[id*="'+dep+'"].ignore', formObj).removeClass('ignore').trigger('remove-ignore');
8376                                            } else {
8377                                                $(dep, formObj).fadeIn(interval || 0);
8378                                            }
8379										}
8380									}
8381									if($.inArray(dep,result) == -1) result.push(dep);
8382								}
8383							}
8384						});
8385					}
8386					catch(e){  }
8387					return result;
8388				},
8389			val:function(raw, no_quotes, disable_ignore_check)
8390				{
8391					raw = raw || false;
8392                    no_quotes = no_quotes || false;
8393					var e = (disable_ignore_check) ? $('[id*="' + this.name + '_"]:checked') : $('[id*="' + this.name + '_"]:not(.ignore):checked');
8394					if(e.length) return $.fbuilder.parseValStr((raw == 'vt') ? e.attr('vt') : e.val(), raw, no_quotes);
8395					else if( raw == 'vt') return $.fbuilder.parseValStr('', raw, no_quotes);
8396					return 0;
8397				},
8398			setVal:function(v, nochange, _default)
8399				{
8400                    _default = _default || false;
8401                    nochange = nochange || false;
8402
8403					var t = (new String(v)).replace(/(['"])/g, "\\$1"), n = this.name, e;
8404
8405					let bk = JSON.stringify(this.val(true)),
8406						bk_vt = JSON.stringify(this.val('vt'));
8407
8408					$('[id*="'+n+'_"]').prop('checked', false);
8409                    if(_default) e = $('[id*="'+n+'_"][vt="'+t+'"]');
8410                    if(!_default || !e.length) e = $('[id*="'+n+'_"][value="'+t+'"]');
8411                    if(e.length) e.prop('checked', true);
8412					this.initStatus();
8413					if(
8414						! nochange &&
8415						(
8416							bk !== JSON.stringify( this.val( true ) ) ||
8417							bk_vt !== JSON.stringify( this.val( 'vt' ) )
8418						)
8419					) $('[id*="'+n+'_"]:eq(0)').trigger('change');
8420				},
8421			setChoices:function(choices)
8422				{
8423					if($.isPlainObject(choices))
8424					{
8425						var bk = this.val(true, false, true);
8426						if('texts' in choices && Array.isArray(choices.texts)) this.choices = choices.texts;
8427						if('values' in choices && Array.isArray(choices.values)) this.choicesVal = choices.values;
8428                        if('dependencies' in choices && Array.isArray(choices.dependencies))
8429                        {
8430                            this.choicesDep = choices.dependencies.map(
8431                                function(x){
8432                                    return (Array.isArray(x)) ? x.map(
8433                                        function(y){
8434                                            return (typeof y == 'number') ? 'fieldname'+parseInt(y) : y;
8435                                        }) : x;
8436                                }
8437                          );
8438                        }
8439						var html = this.show(),
8440							e = $('.'+this.name),
8441							i = e.hasClass('ignorefield') || e.find('.ignore').length,
8442							ipb = e.find('.ignorepb').length || e.closest('.pbreak:hidden').length;
8443						e.find('.dfield').replaceWith($(html).find('.dfield'));
8444						if(i) e.find('input').addClass('ignore');
8445						if(ipb) e.find('input').addClass('ignorepb');
8446						try{ try{ bk = JSON.parse(bk); }catch(err){ bk = bk.replace(/\\+(['"])/g, '$1'); } }catch(err){}
8447						this.setVal(bk, this.choicesVal.indexOf(bk) > -1);
8448					}
8449				},
8450			getIndex:function()
8451				{
8452					var i = -1;
8453					$('[name*="'+this.name+'"]').each(function(j,v){if(this.checked){i = j; return false;}});
8454					return i;
8455				}
8456		}
8457	);	$.fbuilder.controls['fdropdown']=function(){};
8458	$.extend(
8459		$.fbuilder.controls['fdropdown'].prototype,
8460		$.fbuilder.controls['ffields'].prototype,
8461		{
8462			title:"Select a Choice",
8463			ftype:"fdropdown",
8464			size:"medium",
8465			required:false,
8466			toSubmit:"text",
8467			merge:0,
8468			choiceSelected:"",
8469            select2:false,
8470			multiple:false,
8471			first_choice:false,
8472			first_choice_text:"",
8473			vChoices:1,
8474			showDep:false,
8475			nextPage:false,
8476			show:function()
8477				{
8478					this.choicesVal = ((typeof(this.choicesVal) != "undefined" && this.choicesVal !== null && this.choicesVal.length)?this.choicesVal:this.choices)
8479					if ( this.multiple ) this.first_choice = false;
8480
8481					var c	 = this.choices,
8482						cv	 = this.choicesVal,
8483						og   = (typeof this.optgroup == 'undefined') ? new Array() : this.optgroup,
8484						op_o = false,
8485						l 	 = c.length,
8486						classDep = '',
8487						str  = ( this.first_choice ? '<option value="">'+cff_esc_attr(this.first_choice_text)+'</option>' : ''),
8488						n 	 = this.name.match(/fieldname\d+/)[0];
8489
8490					if (typeof this.choicesDep == "undefined" || this.choicesDep == null)
8491						this.choicesDep = new Array();
8492
8493					for (var i=0;i<l;i++)
8494					{
8495						if(typeof this.choicesDep[i] != 'undefined' && (typeof og[i] == 'undefined' || !og[i]))
8496							this.choicesDep[i] = $.grep(this.choicesDep[i],function(x){ return x != "" && x != n; });
8497						else
8498							this.choicesDep[i] = [];
8499
8500						if(this.choicesDep[i].length && (typeof og[i] == 'undefined' || !og[i]))
8501							classDep = 'depItem';
8502					}
8503
8504					for (var i=0;i<l;i++)
8505					{
8506						if(og[i])
8507						{
8508							if(op_o) str += '</optgroup>';
8509							str += '<optgroup label="'+cff_esc_attr(c[i])+'">';
8510							op_o = true;
8511						}
8512						else
8513						{
8514							str += '<option '+((this.choiceSelected == c[i]+' - '+cv[i])?"selected":"")+' '+((classDep != '') ? 'class="'+classDep+'"' : '')+' value="'+cff_esc_attr(cv[i])+'" vt="'+cff_esc_attr((this.toSubmit=='text') ? c[i] : cv[i])+'" data-i="'+i+'">'+cff_esc_attr(c[i])+'</option>';
8515						}
8516					}
8517					if(op_o) str += '</optgroup>';
8518					return '<div class="fields '+cff_esc_attr(this.csslayout)+' '+this.name+' cff-dropdown-field" id="field'+this.form_identifier+'-'+this.index+'" style="'+cff_esc_attr(this.getCSSComponent('container'))+'"><label for="'+this.name+'" style="'+cff_esc_attr(this.getCSSComponent('label'))+'">'+cff_sanitize(this.title, true)+''+((this.required)?"<span class='r'>*</span>":"")+'</label>'+
8519					'<div class="dfield"><select aria-label="'+cff_esc_attr(this.title)+'" id="'+this.name+'" name="'+this.name+((this.multiple)? '[]':'')+'" class="field '+((classDep != '') ? ' depItemSel ' : '')+cff_esc_attr(this.size)+((this.required)?' required':'')+'" '+((this.multiple == true)?' multiple="multiple" size="'+((this.vChoices) ? cff_esc_attr(this.vChoices) : 1)+'"':'')+' style="'+cff_esc_attr(this.getCSSComponent('dropdown'))+'">'+str+'</select><span class="uh" style="'+cff_esc_attr(this.getCSSComponent('help'))+'">'+cff_sanitize(this.userhelp, true)+'</span></div><div class="clearer"></div></div>';
8520				},
8521            after_show:function()
8522                {
8523                    var me = this;
8524					if ( me.nextPage && ! me.multiple ) {
8525						$('#'+me.name).on('change select2:select', function(evt){
8526							if ( evt.type != 'select2:select' && ( ! ( 'originalEvent' in evt ) || ! evt.originalEvent.isTrusted ) ) return;
8527							if ( ! me.first_choice || this.selectedIndex ) {
8528								let p = $( this ).closest('.pbreak:not(.pbEnd):visible');
8529								if ( p.length && $(this.form).validate().checkForm() ) {
8530									let i = p.attr('page');
8531									GOTOPAGE(SUM(i, 1), this.form);
8532								}
8533							}
8534						});
8535					}
8536                    if(me.select2)
8537                    {
8538                        function formatState(state)
8539                        {
8540							let _text = state.text == null ? '' : state.text;
8541							if ( ! state.id ) return _text;
8542							if ('DOMPurify' in window) {
8543								let sanitized = DOMPurify.sanitize('<span>'+_text+'</span>');
8544								return $(sanitized);
8545							}
8546							return $('<span>').text(_text);
8547						};
8548
8549                        $('#'+me.name).after('<span class="cff-select2-container '+me.size+'"></span>');
8550                        $('#'+me.name).on('change', function(){ $(this).valid(); });
8551                        if('select2' in $.fn) {
8552                            $('#'+me.name).select2({
8553                                'templateResult': formatState,
8554                                'templateSelection': formatState,
8555                                'dropdownParent':$('#'+me.name).next('.cff-select2-container')
8556                            });
8557							$('#'+me.name).parent().find('.select2-container').addClass(me.size);
8558						}
8559                        else
8560                            $(document).ready(function(){
8561								if('select2' in $.fn) {
8562									$('#'+me.name).select2({'dropdownParent':$('#'+me.name).next('.cff-select2-container')});
8563									$('#'+me.name).parent().find('.select2-container').addClass(cff_esc_attr(me.size));
8564								}
8565							});
8566                    }
8567                },
8568			showHideDep:function(toShow, toHide, hiddenByContainer, interval)
8569				{
8570                    if(typeof hiddenByContainer == 'undefined') hiddenByContainer = {};
8571					var me = this,
8572						item = $('#'+me.name+'.depItemSel'),
8573						form_identifier = me.form_identifier,
8574						formObj	= item.closest('form'),
8575						isHidden = (typeof toHide[me.name] != 'undefined' || typeof hiddenByContainer[me.name] != 'undefined'),
8576						result = [];
8577
8578					try
8579					{
8580						if(item.length)
8581						{
8582							var selected = [];
8583							$(item).find(':selected').each(function(){selected.push($(this).data('i'));});
8584
8585							for(var i = 0, h = me.choices.length; i < h; i++)
8586							{
8587								if(typeof me.choicesDep[i] != 'undefined' && me.choicesDep[i].length)
8588								{
8589									for(var j = 0, k = me.choicesDep[i].length; j < k; j++)
8590									{
8591                                        if (!/(fieldname)|(__next_page__)|(__submit_button__)/i.test(me.choicesDep[i][j])) continue;
8592                                        let dep, isField = false;
8593                                        if (/fieldname\d+/i.test(me.choicesDep[i][j])) {
8594                                            dep = me.choicesDep[i][j] + form_identifier; // Another field dependency
8595                                            isField = true;
8596                                        } else if (me.choicesDep[i][j] == '__next_page__') {
8597                                            dep = '.pb' + item.closest('.pbreak').attr('page') + ':not(.pbEnd) .pbNext'; // Next page dependency
8598                                        } else {
8599                                            dep = '.pbSubmit,.captcha'; // Submission button dependency
8600                                        }
8601
8602										if(isHidden || $.inArray(i,selected) == -1)
8603										{
8604											if(typeof toShow[dep] != 'undefined')
8605											{
8606												delete toShow[dep]['ref'][me.name+'_'+i];
8607												if($.isEmptyObject(toShow[dep]['ref']))
8608												delete toShow[dep];
8609											}
8610
8611											if(typeof toShow[dep] == 'undefined')
8612											{
8613                                                if (isField) {
8614												    $('[id*="'+dep+'"],.'+dep, formObj).closest('.fields').addClass('ignorefield').hide();
8615												    $('[id*="'+dep+'"]:not(.ignore)', formObj).addClass('ignore').trigger('add-ignore');
8616                                                } else {
8617                                                    $(dep, formObj).hide();
8618                                                }
8619												toHide[dep] = {};
8620											}
8621										}
8622										else
8623										{
8624											delete toHide[dep];
8625											if(typeof toShow[dep] == 'undefined')
8626											toShow[dep] = { 'ref': {}};
8627											toShow[dep]['ref'][me.name+'_'+i]  = 1;
8628											if(!(dep in hiddenByContainer))
8629											{
8630                                                if (isField) {
8631												    $('[id*="'+dep+'"],.'+dep, formObj).closest('.fields').removeClass('ignorefield').fadeIn(interval || 0);
8632												    $('[id*="'+dep+'"].ignore', formObj).removeClass('ignore').trigger('remove-ignore');
8633                                                } else {
8634                                                    $(dep, formObj).fadeIn(interval || 0);
8635                                                }
8636											}
8637										}
8638										if($.inArray(dep,result) == -1) result.push(dep);
8639									}
8640								}
8641							}
8642						}
8643					}
8644					catch(e){}
8645					return result;
8646				},
8647			val:function(raw, no_quotes, disable_ignore_check)
8648				{
8649					raw = raw || false;
8650                    no_quotes = no_quotes || false;
8651					var e = (disable_ignore_check) ? $('[id="'+this.name+'"] option:selected') : $('[id="'+this.name+'"]:not(.ignore) option:selected'),
8652						v,
8653						m = this.multiple,
8654						g = this.merge && !raw;
8655
8656					if(m && !g)	v = [];
8657					if(e.length)
8658					{
8659						e.each(function(){
8660							var t = $.fbuilder.parseValStr((raw == 'vt') ? this.getAttribute('vt') : this.value, raw, no_quotes);
8661							if(!$.fbuilder.isNumeric(t)) t = t.replace(/^"/,'').replace(/"$/,'');
8662							if(!m || g) v = (v)?v+t:t;
8663							else v.push(t);
8664						});
8665					}
8666					return (typeof v == 'object' && typeof v['length'] !== 'undefined') ? v : (v ? (($.fbuilder.isNumeric(v) || no_quotes) ? v : '"'+v+'"') : (raw == 'vt' ? (no_quotes ? '' : '""') : 0));
8667				},
8668			setVal:function(v, nochange, _default)
8669				{
8670                    _default = _default || false;
8671                    nochange = nochange || false;
8672					if(!Array.isArray(v)) v = [v];
8673					var t, e, n = this.name, selector;
8674
8675					let bk = JSON.stringify(this.val(true)),
8676						bk_vt = JSON.stringify(this.val('vt'));
8677
8678					$('[id="'+n+'"] OPTION').prop('selected', false);
8679					for(var i in v)
8680					{
8681						t = (new String(v[i])).replace(/(['"])/g, "\\$1");
8682                        if(_default) e = $('[id="'+n+'"] OPTION[vt="'+t+'"]');
8683                        if(!_default || !e.length) e = $('[id="'+n+'"] OPTION[value="'+t+'"]');
8684                        if(e.length) e.prop('selected', true);
8685					}
8686					if (
8687						! nochange &&
8688						(
8689							bk !== JSON.stringify( this.val( true ) ) ||
8690							bk_vt !== JSON.stringify( this.val( 'vt' ) )
8691						)
8692					) $('[id="'+n+'"]').trigger('change');
8693				},
8694			setChoices:function(choices)
8695				{
8696					if($.isPlainObject(choices))
8697					{
8698						var me = this,
8699                            bk = me.val(true, false, true),
8700							addDepClass = false;
8701
8702						if('texts' in choices && Array.isArray(choices.texts)) me.choices = choices.texts;
8703						if('values' in choices && Array.isArray(choices.values)) me.choicesVal = choices.values;
8704                        if('dependencies' in choices && Array.isArray(choices.dependencies))
8705                        {
8706							addDepClass = true;
8707                            me.choicesDep = choices.dependencies.map(
8708                                function(x){
8709                                    return (Array.isArray(x)) ? x.map(
8710                                        function(y){
8711                                            return (typeof y == 'number') ? 'fieldname'+parseInt(y) : y;
8712                                        }) : x;
8713                                }
8714);
8715                        }
8716						if('optgroup' in choices && Array.isArray(choices.optgroup)) me.optgroup = choices.optgroup;
8717						var html = me.show(),
8718							e = $('.'+me.name),
8719							s = e.find('select');
8720						s.html($(html).find('select').html());
8721						if (addDepClass) s.addClass('depItemSel');
8722						if(!Array.isArray(bk)) bk = [bk];
8723                        for(var j in bk)
8724                        {
8725                            try{ try{ bk[j] = JSON.parse(bk[j]); }catch(err){ bk[j] = bk[j].replace(/\\+(['"])/g, '$1'); } }catch(err){}
8726                        }
8727						me.setVal(bk, bk.every(function(e){ return me.choicesVal.indexOf(e) > -1; }));
8728					}
8729				},
8730			getIndex:function()
8731				{
8732					var f = $('[name*="'+this.name+'"]');
8733					if(this.multiple){
8734						var i = [];
8735						f.find('option').each(function(j,v){if(this.selected) i.push(j);});
8736						return i;
8737					}
8738					else return f[0].selectedIndex;
8739				}
8740		}
8741	);	$.fbuilder.controls['ffile'] = function(){};
8742	$.extend(
8743		$.fbuilder.controls['ffile'].prototype,
8744		$.fbuilder.controls['ffields'].prototype,
8745		{
8746			title:"Untitled",
8747			ftype:"ffile",
8748			required:false,
8749			size:"medium",
8750			accept:"",
8751			upload_size:"",
8752			multiple:false,
8753			preview: false,
8754			thumb_width: '80px',
8755			thumb_height: '',
8756			_patch: false, // Used only if the submission is being updated to preserves the previous values
8757			_files_list: [],
8758			init: function(){
8759                this.getCSSComponent('files_container_hover', true, '#fbuilder .' + this.name + ' .cff-file-field-container:hover', this.form_identifier);
8760				this.thumb_width  = cff_sanitize(String(this.thumb_width).trim(), true);
8761				this.thumb_height = cff_sanitize(String(this.thumb_height).trim(), true);
8762				var form_identifier = this.form_identifier.replace(/[^\d]/g, '');
8763				this._patch = ('cpcff_default' in window && form_identifier in cpcff_default) ? true : false;
8764			},
8765			show:function()
8766				{
8767					this.accept = cff_esc_attr(String(this.accept).trim());
8768					this.upload_size = cff_esc_attr(String(this.upload_size).trim());
8769                    let info = '<div class="cff-file-info-container" style="'+cff_esc_attr(this.getCSSComponent('file_info'))+'">',
8770                        info_separtor = '';
8771                    if ( this.accept.length ) {
8772                        info += cff_sanitize(this.accept);
8773                        info_separtor = '/';
8774                    }
8775                    if ( this.upload_size.length ) {
8776                        let inMB = parseFloat(this.upload_size) / 1024;
8777                        info += info_separtor + cff_sanitize(!isNaN(inMB) && 1 <= inMB && inMB <= 1024 ? (inMB.toFixed(2)*1) + ' Mb' : this.upload_size + ' Kb');
8778                    }
8779                    info += '</div>';
8780					return '<div class="fields '+cff_esc_attr(this.csslayout)+' '+this.name+' cff-file-field" id="field'+this.form_identifier+'-'+this.index+'" style="'+cff_esc_attr(this.getCSSComponent('container'))+'">'+
8781                        '<label for="'+this.name+'" style="'+cff_esc_attr(this.getCSSComponent('label'))+'">'+cff_sanitize(this.title, true)+''+((this.required)?"<span class='r'>*</span>":"")+'</label>'+
8782                        '<div class="dfield">'+
8783                        '<div class="cff-file-field-container ' + cff_esc_attr(this.size) + '" style="' + cff_esc_attr(this.getCSSComponent('files_container')) +'">'+
8784                                '<input aria-label="'+cff_esc_attr(this.title)+'" type="file" id="'+this.name+'" name="'+this.name+'[]"'+((this.accept.length) ? ' accept="'+this.accept+'"' : '')+((this.upload_size.length) ? ' upload_size="'+this.upload_size+'"' : '')+' class="field '+((this.required)?" required":"")+'" '+((this.multiple) ? 'multiple' : '')+' />'+
8785                                '<div id="'+this.name+'_clearer" class="cff-file-clearer"></div>'+
8786                                ((this._patch) ? '<input type="hidden" id="'+this.name+'_patch" name="'+this.name+'_patch" value="1" />' : '')+
8787                                '<div class="clearer"></div>'+
8788                                info+
8789                            '</div>'+
8790                            '<span class="uh" style="'+cff_esc_attr(this.getCSSComponent('help'))+'">'+cff_sanitize(this.userhelp, true)+'</span>'+
8791                        '</div>'+
8792                    '<div class="clearer"></div></div>';
8793				},
8794			after_show:function()
8795			{
8796				var me = this;
8797
8798				if(!('accept' in $.validator.methods))
8799					$.validator.addMethod("accept", function(value, element, param)
8800					{
8801						if(this.optional(element)) return true;
8802						else{
8803							param = ( typeof param === "string" && param != "image/*" ) ? param.replace(/,/g, '|') : "png|jpe?g|gif";
8804							var regExpObj = new RegExp(".("+param+")$", "i");
8805							for(var i = 0, h = element.files.length; i < h; i++)
8806								if(!element.files[i].name.match(regExpObj)) return false;
8807							return true;
8808						}
8809					});
8810
8811				if(!('upload_size' in $.validator.methods))
8812					$.validator.addMethod("upload_size", function(value, element,params)
8813					{
8814						if(this.optional(element)) return true;
8815						else{
8816							var total = 0;
8817							for(var i = 0, h = element.files.length; i < h; i++)
8818								total += element.files[i].size/1024;
8819							return (total <= params);
8820						}
8821					});
8822
8823				$('#'+me.name).on( 'click', function(){
8824					me._files_list = [];
8825					if ( me.multiple ) {
8826						for ( var i = 0; i < this.files.length; i++ ) {
8827							me._files_list.push( this.files[i] );
8828						}
8829					}
8830				});
8831
8832				$('#'+me.name).on( 'change', function(){
8833
8834					var h = this.files.length;
8835
8836					$(this).siblings('span.files-list').remove();
8837					$('[id="'+me.name+'_patch"]').remove();
8838					if(1 <= h || me._files_list.length )
8839					{
8840						if ( me.multiple && typeof DataTransfer != 'undefined' ) {
8841							try {
8842								var _dataTransfer = new DataTransfer(),
8843									_preventDuplication = {};
8844								// Copy from files input tags
8845								for (var i = 0; i < h; i++) {
8846									_dataTransfer.items.add( this.files[i] );
8847									_preventDuplication[ this.files[i]['name'] + '|' + this.files[i]['size'] ] = true;
8848								}
8849
8850								// Copy from list
8851								for(var i = 0, k = me._files_list.length; i < k; i++) {
8852									if ( me._files_list[i]['name'] + '|' + me._files_list[i]['size'] in _preventDuplication ) continue;
8853									_dataTransfer.items.add( me._files_list[i] );
8854								}
8855
8856								this.files = _dataTransfer.files;
8857								h = this.files.length;
8858							} catch ( err ) {
8859								console.log( err );
8860							}
8861						}
8862
8863						var filesContainer = $('<span class="files-list"></span>');
8864						for(var i = 0; i < h; i++)
8865						{
8866							(function(i, file){
8867								if(me.preview && file.type.match('image.*') && 'FileReader' in window)
8868								{
8869									var reader = new FileReader();
8870									reader.onload = function (e) {
8871										var img = $('<img style="'+cff_esc_attr(me.getCSSComponent('thumbnail'))+'">');
8872										img.attr('src', e.target.result).css('maxWidth', '100%');
8873										if(me.thumb_height != '') img.attr('height', me.thumb_height);
8874										if(me.thumb_width  != '') img.attr('width', me.thumb_width);
8875										filesContainer.append($('<span></span>').append(img));
8876									};
8877									reader.readAsDataURL(file);
8878								}
8879								else if(1 <= h){filesContainer.append($('<span>').text(file.name));}
8880							})(i, this.files[i]);
8881						}
8882						$('#'+this.id+'_clearer').after(filesContainer);
8883					}
8884				});
8885
8886                $('#'+me.name+'_clearer').on( 'click', function(){ me._files_list= []; $('#'+me.name).val('').trigger('change').valid();});
8887			},
8888			val: function(raw, no_quotes, disable_ignore_check)
8889			{
8890                raw = raw || false;
8891                no_quotes = no_quotes || false;
8892				var e = (disable_ignore_check) ? $("[id='"+this.name+"']") : $("[id='"+this.name+"']:not(.ignore)"),
8893                    result = raw ? [] : '',
8894                    separator = '';
8895				if(e.length)
8896                {
8897                    if(raw) result = Array.prototype.slice.call(e[0].files);
8898                    else
8899                    {
8900                        for(var i = 0, h = e[0].files.length; i<h; i++)
8901                        {
8902                            result += separator+e[0].files[i].name;
8903                            separator = ', ';
8904                        }
8905                        result = $.fbuilder.parseValStr(result, raw, no_quotes);
8906                    }
8907                }
8908				return result;
8909			}
8910		}
8911	);	$.fbuilder.controls['fpassword'] = function(){};
8912	$.extend(
8913		$.fbuilder.controls['fpassword'].prototype,
8914		$.fbuilder.controls['ffields'].prototype,
8915		{
8916			title:"Untitled",
8917			ftype:"fpassword",
8918			predefined:"",
8919			predefinedClick:false,
8920			required:false,
8921			unmaskedonfocus:false,
8922			size:"medium",
8923			minlength:"",
8924			maxlength:"",
8925			lowercase:false,
8926			uppercase:false,
8927			digit:false,
8928			symbol:false,
8929			equalTo:"",
8930			regExp:"",
8931			regExpMssg:"",
8932			show:function()
8933				{
8934					let minlength = String(this.minlength).trim();
8935					let maxlength = String(this.maxlength).trim();
8936
8937					this.minlength = (!isNaN(minlength*1) && 0 < minlength*1) ? minlength*1 : '';
8938					this.maxlength = (!isNaN(maxlength*1) && 0 < maxlength*1) ? maxlength*1 : '';
8939
8940					this.equalTo = cff_esc_attr(String(this.equalTo).trim());
8941					this.predefined = this._getAttr('predefined', true);
8942					return '<div class="fields '+cff_esc_attr(this.csslayout)+' '+this.name+' cff-password-field" id="field'+this.form_identifier+'-'+this.index+'" style="'+cff_esc_attr(this.getCSSComponent('container'))+'"><label for="'+this.name+'" style="'+cff_esc_attr(this.getCSSComponent('label'))+'">'+cff_sanitize(this.title, true)+''+((this.required)?"<span class='r'>*</span>":"")+'</label><div class="dfield"><input aria-label="'+cff_esc_attr(this.title)+'" id="'+this.name+'" name="'+this.name+'"'+((this.minlength) ? ' minlength="'+cff_esc_attr(this.minlength)+'"' : '')+((this.maxlength) ? ' maxlength="'+cff_esc_attr(this.maxlength)+'"' : '')+((this.equalTo.length) ? ' equalTo="#'+this.equalTo+this.form_identifier+'"' : '')+' class="field '+this.size+((this.required)?" required":"")+'" t
8942ype="password" autocomplete="new-password" spellcheck="false" autocorrect="off" autocapitalize="off" '+this._getValueAttr()+' style="'+cff_esc_attr(this.getCSSComponent('input'))+'" /><span class="uh" style="'+cff_esc_attr(this.getCSSComponent('help'))+'">'+cff_sanitize(this.userhelp, true)+'</span></div><div class="clearer"></div></div>';
8943				},
8944			after_show:function()
8945				{
8946					if(typeof $['validator'] != 'undefined')
8947					{
8948						try {
8949							if (this.regExp != "") {
8950								var parts 	= this.regExp.match(/(\/)(.*)(\/)([gimy]{0,4})$/i);
8951								this.regExp = (parts === null) ? new RegExp(this.regExp) : new RegExp(parts[2],parts[4].toLowerCase());
8952							}
8953
8954							if(!('password' in $.validator.methods))
8955								$.validator.addMethod('password', function(value, element, param)
8956									{
8957										let valid = true;
8958
8959										if(param.regExp != '') valid = param.regExp.test(value);
8960										if(valid && param.lowercase) valid = /[a-z]/.test(value);
8961										if(valid && param.uppercase) valid = /[A-Z]/.test(value);
8962										if(valid && param.digit) valid = /[0-9]/.test(value);
8963										if(valid && param.symbol) valid = /[^a-zA-Z0-9\s]/.test(value);
8964
8965										try{
8966											return this.optional(element) || valid;
8967										}
8968										catch(err){return true;}
8969									}
8970								);
8971
8972							$('#'+this.name).rules('add', {
8973								'password': this,
8974								'messages': {
8975									'password': cff_sanitize(this.regExpMssg, true)
8976								}
8977							});
8978						} catch ( err ) {}
8979					}
8980					if(this.unmaskedonfocus)
8981					{
8982						$('#'+this.name).on('focus', function(){this.type="text";}).on('blur', function(){this.type="password";});
8983					}
8984				},
8985			val:function(raw, no_quotes, disable_ignore_check)
8986				{
8987					raw = raw || false;
8988                    no_quotes = no_quotes || false;
8989					var e = (disable_ignore_check) ? $('[id="'+this.name+'"]') : $('[id="'+this.name+'"]:not(.ignore)');
8990					if(e.length) return $.fbuilder.parseValStr(e.val(), raw, no_quotes);
8991					return 0;
8992				}
8993		}
8994	);	$.fbuilder.controls['fPhone']=function(){};
8995	$.extend(
8996		$.fbuilder.controls['fPhone'].prototype,
8997		$.fbuilder.controls['ffields'].prototype,
8998		{
8999			title:"Phone",
9000			ftype:"fPhone",
9001			required:false,
9002			readonly:false,
9003			size:"medium",
9004			dformat:"### ### ####",
9005			showFormatAsHint: -1,
9006			dseparator:"-", // none, space, -, .
9007			predefined:"888 888 8888",
9008
9009            countryComponent:false,
9010            toDisplay:'iso',
9011			includeFlags:false,
9012			includeCountryNames:false,
9013            countries:[],
9014            defaultCountry:'',
9015			dynamic: false,
9016
9017			FREE_MAX_DIGITS: 40,
9018			isFree: false,
9019
9020			country_db: {"AF":{"prefix":"+93","min":9,"max":9,"country":"Afghanistan"},"AX":{"country":"Åland Islands","prefix":"+358","min":5,"max":12},"AL":{"prefix":"+355","min":3,"max":9,"country":"Albania"},"DZ":{"prefix":"+213","min":8,"max":9,"country":"Algeria"},"AS":{"prefix":"+1684","min":10,"max":10,"country":"American Samoa"},"AD":{"prefix":"+376","min":6,"max":9,"country":"Andorra"},"AO":{"prefix":"+244","min":9,"max":9,"country":"Angola"},"AI":{"prefix":"+1264","min":10,"max":10,"country":"Anguilla"},"AQ":{"country":"Antarctica","prefix":"+672","min":10,"max":10},"AG":{"prefix":"+1268","min":10,"max":10,"country":"Antigua and Barbuda"},"AR":{"prefix":"+54","min":10,"max":10,"country":"Argentina"},"AM":{"prefix":"+374","min":8,"max":8,"country":"Armenia"},"AW":{"prefix":"+297","min":7,"max":7,"country":"Aruba"},"AU":{"prefix":"+61","min":5,"max":9,"country":"Australia"},"AT":{"prefix":"+43","min":4,"max":13,"country":"Austria"},"AZ":{"prefix":"+994","min":8,"max":9,"country":"Azerbaijan"},"BS":{"prefix":"+1242","min":10,"max":10,"country":"Bahamas"},"BH":{"prefix":"+973","min":8,"max":8,"country":"Bahrain"},"BD":{"prefix":"+880","min":6,"max":10,"country":"Bangladesh"},"BB":{"prefix":"+1246","min":10,"max":10,"country":"Barbados"},"BY":{"prefix":"+375","min":9,"max":10,"country":"Belarus"},"BE":{"prefix":"+32","min":8,"max":9,"country":"Belgium"},"BZ":{"prefix":"+501","min":7,"max":7,"country":"Belize"},"BJ":{"prefix":"+229","min":8,"max":8,"country":"Benin"},"BM":{"prefix":"+1441","min":10,"max":10,"country":"Bermuda"},"BT":{"prefix":"+975","min":7,"max":8,"country":"Bhutan"},"BO":{"prefix":"+591","min":8,"max":8,"country":"Bolivia"},"BA":{"prefix":"+387","min":8,"max":8,"country":"Bosnia and Herzegovina"},"BW":{"prefix":"+267","min":7,"max":8,"country":"Botswana"},"BR":{"prefix":"+55","min":10,"max":10,"country":"Brazil"},"IO":{"country":"British Indian Ocean Territory","prefix":"+246","min":7,"max":7},"BN":{"prefix":"+673","min":7,"max":7,"country":"Brunei"},"BG":{"prefix":"+359","min":7,"max":9,"country":"Bulgaria"},"BF":{"prefix":"+226","min":8,"max":8,"country":"Burkina Faso"},"BI":{"prefix":"+257","min":8,"max":8,"country":"Burundi"},"KH":{"prefix":"+855","min":8,"max":8,"country":"Cambodia"},"CM":{"prefix":"+237","min":8,"max":8,"country":"Cameroon"},"CA":{"prefix":"+1","min":10,"max":10,"country":"Canada"},"CV":{"prefix":"+238","min":7,"max":7,"country":"Cape Verde"},"KY":{"prefix":"+1345","min":10,"max":10,"country":"Cayman Islands"},"CF":{"prefix":"+236","min":8,"max":8,"country":"Central African Republic"},"TD":{"prefix":"+235","min":8,"max":8,"country":"Chad"},"CL":{"prefix":"+56","min":8,"max":9,"country":"Chile"},"CN":{"prefix":"+86","min":5,"max":12,"country":"China"},"CX":{"country":"Christmas Island","prefix":"+61","min":5,"max":9},"CC":{"country":"Coco (Keeling) Islands","prefix":"+61","min":5,"max":9},"CO":{"prefix":"+57","min":8,"max":10,"country":"Colombia"},"KM":{"prefix":"+269","min":7,"max":7,"country":"Comoros"},"CG":{"country":"The Congo","prefix":"+242","min":5,"max":9},"CD":{"prefix":"+243","min":5,"max":9,"country":"DR Congo"},"CK":{"prefix":"+682","min":5,"max":5,"country":"Cook Islands"},"CR":{"prefix":"+506","min":8,"max":8,"country":"Costa Rica"},"CI":{"prefix":"+225","min":8,"max":8,"country":"Ivory Coast"},"HR":{"prefix":"+385","min":8,"max":12,"country":"Croatia"},"CU":{"prefix":"+53","min":8,"max":8,"country":"Cuba"},"CY":{"prefix":"+357","min":8,"max":11,"country":"Cyprus"},"CZ":{"prefix":"+420","min":4,"max":12,"country":"Czech Republic"},"DK":{"prefix":"+45","min":8,"max":8,"country":"Denmark"},"DJ":{"prefix":"+253","min":6,"max":6,"country":"Djibouti"},"DM":{"prefix":"+1767","min":10,"max":10,"country":"Dominica"},"DO":{"prefix":"+1849","min":7,"max":7,"country":"Dominican Republic"},"EC":{"prefix":"+593","min":8,"max":8,"country":"Ecuador"},"EG":{"prefix":"+20","min":7,"max":9,"country":"Egypt"},"SV":{"prefix":"+503","min":7,"max":11,"country":"El Salvador"},"GQ":{"prefix":"+240","min":9,"max":9,"country":"Equatorial Guinea"},"ER":{"prefix":"+291","min":7,"max":7,"country":"Eritrea"},"EE":{"prefix":"+372","min":7,"max":10,"country":"Estonia"},"ET":{"prefix":"+251","min":9,"max":9,"country":"Ethiopia"},"FK":{"prefix":"+500","min":5,"max":5,"country":"Falkland Islands"},"FO":{"prefix":"+298","min":6,"max":6,"country":"Faroe Islands"},"FJ":{"prefix":"+679","min":7,"max":7,"country":"Fiji"},"FI":{"prefix":"+358","min":5,"max":12,"country":"Finland"},"FR":{"prefix":"+33","min":9,"max":9,"country":"France"},"GF":{"prefix":"+594","min":9,"max":9,"country":"French Guiana"},"PF":{"prefix":"+689","min":6,"max":6,"country":"French Polynesia"},"TF":{"country":"French Southern Territories","prefix":"+262","min":9,"max":9},"GA":{"prefix":"+241","min":6,"max":7,"country":"Gabon"},"GM":{"prefix":"+220","min":7,"max":7,"country":"Gambia"},"GE":{"prefix":"+995","min":9,"max":9,"country":"Georgia"},"DE":{"prefix":"+49","min":6,"max":13,"country":"Germany"},"GH":{"prefix":"+233","min":5,"max":9,"country":"Ghana"},"GI":{"prefix":"+350","min":8,"max":8,"country":"Gibraltar"},"GR":{"prefix":"+30","min":10,"max":10,"country":"Greece"},"GL":{"prefix":"+299","min":6,"max":6,"country":"Greenland"},"GD":{"prefix":"+1473","min":10,"max":10,"country":"Grenada"},"GP":{"prefix":"+590","min":9,"max":9,"country":"Guadeloupe"},"GU":{"prefix":"+1671","min":10,"max":10,"country":"Guam"},"GT":{"prefix":"+502","min":8,"max":8,"country":"Guatemala"},"GG":{"country":"Guernsey","prefix":"+44","min":7,"max":10},"GN":{"prefix":"+224","min":8,"max":8,"country":"Guinea"},"GW":{"country":"Guinea-Bissau","prefix":"+245","min":9,"max":9},"GY":{"prefix":"+592","min":7,"max":7,"country":"Guyana"},"HT":{"prefix":"+509","min":8,"max":8,"country":"Haiti"},"HM":{"country":"Heard Island and McDonald Islands","prefix":"+672","min":8,"max":8},"VA":{"prefix":"+379","min":10,"max":10,"country":"Vatican City"},"HN":{"prefix":"+504","min":8,"max":8,"country":"Honduras"},"HK":{"prefix":"+852","min":4,"max":9,"country":"Hong Kong"},"HU":{"prefix":"+36","min":8,"max":9,"country":"Hungary"},"IS":{"prefix":"+354","min":7,"max":9,"country":"Iceland"},"IN":{"prefix":"+91","min":7,"max":10,"country":"India"},"ID":{"prefix":"+62","min":5,"max":10,"country":"Indonesia"},"IR":{"prefix":"+98","min":6,"max":10,"country":"Iran"},"IQ":{"prefix":"+964","min":8,"max":10,"country":"Iraq"},"IE":{"prefix":"+353","min":7,"max":11,"country":"Ireland"},"IM":{"country":"Isle of Man","prefix":"+44","min":7,"max":10},"IL":{"prefix":"+972","min":8,"max":9,"country":"Israel"},"IT":{"prefix":"+39","min":11,"max":11,"country":"Italy"},"JM":{"prefix":"+1876","min":10,"max":10,"country":"Jamaica"},"JP":{"prefix":"+81","min":10,"max":10,"country":"Japan"},"JE":{"country":"Jersey","prefix":"+44","min":7,"max":10},"JO":{"prefix":"+962","min":5,"max":9,"country":"Jordan"},"KZ":{"prefix":"+7","min":10,"max":10,"country":"Kazakhstan"},"KE":{"prefix":"+254","min":6,"max":10,"country":"Kenya"},"KI":{"prefix":"+686","min":5,"max":5,"country":"Kiribati"},"KP":{"prefix":"+850","min":6,"max":8,"country":"North Korea"},"KR":{"prefix":"+82","min":8,"max":11,"country":"South Korea"},"XK":{"country":"Kosovo","prefix":"+383","min":9,"max":9},"KW":{"prefix":"+965","min":7,"max":8,"country":"Kuwait"},"KG":{"prefix":"+996","min":9,"max":9,"country":"Kyrgyzstan"},"LA":{"prefix":"+856","min":8,"max":10,"country":"Laos"},"LV":{"prefix":"+371","min":7,"max":8,"country":"Latvia"},"LB":{"prefix":"+961","min":7,"max":8,"country":"Lebanon"},"LS":{"prefix":"+266","min":8,"max":8,"country":"Lesotho"},"LR":{"prefix":"+231","min":7,"max":8,"country":"Liberia"},"LY":{"prefix":"+218","min":8,"max":9,"country":"Libya"},"LI":{"prefix":"+423","min":7,"max":9,"country":"Liechtenstein"},"LT":{"prefix":"+370","min":8,"max":8,"country":"Lithuania"},"LU":{"prefix":"+352","min":4,"max":11,"country":"Luxembourg"},"MO":{"prefix":"+853","min":7,"max":8,"country":"Macau"},"MK":{"country":"North Macedonia","prefix":"+389","min":9,"max":9},"MG":{"prefix":"+261","min":9,"max":10,"country":"Madagascar"},"MW":{"prefix":"+265","min":7,"max":8,"country":"Malawi"},"MY":{"prefix":"+60","min":7,"max":9,"country":"Malaysia"},"MV":{"prefix":"+960","min":7,"max":7,"country":"Maldives"},"ML":{"prefix":"+223","min":8,"max":8,"country":"Mali"},"MT":{"prefix":"+356","min":8,"max":8,"country":"Malta"},"MH":{"prefix":"+692","min":7,"max":7,"country":"Marshall Islands"},"MQ":{"prefix":"+596","min":9,"max":9,"country":"Martinique"},"MR":{"prefix":"+222","min":7,"max":7,"country":"Mauritania"},"MU":{"prefix":"+230","min":7,"max":7,"country":"Mauritius"},"YT":{"country":"Mayotte","prefix":"+262","min":9,"max":9},"MX":{"prefix":"+52","min":10,"max":10,"country":"Mexico"},"FM":{"prefix":"+691","min":7,"max":7,"country":"Micronesia"},"MD":{"prefix":"+373","min":8,"max":8,"country":"Moldova"},"MC":{"prefix":"+377","min":5,"max":9,"country":"Monaco"},"MN":{"prefix":"+976","min":7,"max":8,"country":"Mongolia"},"ME":{"prefix":"+382","min":4,"max":12,"country":"Montenegro"},"MS":{"prefix":"+1664","min":10,"max":10,"country":"Montserrat"},"MA":{"prefix":"+212","min":9,"max":9,"country":"Morocco"},"MZ":{"prefix":"+258","min":8,"max":9,"country":"Mozambique"},"MM":{"prefix":"+95","min":7,"max":9,"country":"Myanmar"},"NA":{"prefix":"+264","min":6,"max":10,"country":"Namibia"},"NR":{"prefix":"+674","min":4,"max":7,"country":"Nauru"},"NP":{"prefix":"+977","min":8,"max":9,"country":"Nepal"},"NL":{"prefix":"+31","min":9,"max":9,"country":"Netherlands"},"AN":{"country":"Netherlands Antilles","prefix":"+599","min":7,"max":8},"NC":{"prefix":"+687","min":6,"max":6,"country":"New Caledonia"},"NZ":{"prefix":"+64","min":3,"max":10,"country":"New Zealand"},"NI":{"prefix":"+505","min":8,"max":8,"country":"Nicaragua"},"NE":{"prefix":"+227","min":8,"max":8,"country":"Niger"},"NG":{"prefix":"+234","min":7,"max":10,"country":"Nigeria"},"NU":{"prefix":"+683","min":4,"max":4,"country":"Niue"},"NF":{"country":"Norfolk Island","prefix":"+672","min":6,"max":6},"MP":{"country":"Northern Mariana Islands","prefix":"+1670","min":7,"max":7},"NO":{"prefix":"+47","min":5,"max":6,"country":"Norway"},"OM":{"prefix":"+968","min":7,"max":8,"country":"Oman"},"PK":{"prefix":"+92","min":8,"max":11,"country":"Pakistan"},"PW":{"prefix":"+680","min":7,"max":7,"country":"Palau"},"PS":{"country":"State of Palestine","prefix":"+970","min":9,"max":10},"PA":{"prefix":"+507","min":7,"max":8,"country":"Panama"},"PG":{"prefix":"+675","min":4,"max":11,"country":"Papua New Guinea"},"PY":{"prefix":"+595","min":5,"max":9,"country":"Paraguay"},"PE":{"prefix":"+51","min":8,"max":11,"country":"Peru"},"PH":{"prefix":"+63","min":8,"max":10,"country":"Philippines"},"PN":{"country":"Pitcairn","prefix":"+64","min":3,"max":10},"PL":{"prefix":"+48","min":6,"max":9,"country":"Poland"},"PT":{"prefix":"+351","min":9,"max":11,"country":"Portugal"},"PR":{"prefix":"+1939","min":10,"max":10,"country":"Puerto Rico"},"QA":{"prefix":"+974","min":3,"max":8,"country":"Qatar"},"RO":{"prefix":"+40","min":9,"max":9,"country":"Romania"},"RU":{"prefix":"+7","min":10,"max":10,"country":"Russia"},"RW":{"prefix":"+250","min":9,"max":9,"country":"Rwanda"},"RE":{"country":"Réunion","prefix":"+262","min":9,"max":9},"BL":{"country":"Saint Barthélemy","prefix":"+590","min":9,"max":9},"SH":{"country":"Saint Helena","prefix":"+290","min":5,"max":5},"KN":{"prefix":"+1869","min":10,"max":10,"country":"Saint Kitts and Nevis"},"LC":{"prefix":"+1758","min":10,"max":10,"country":"Saint Lucia"},"MF":{"country":"Saint Martin","prefix":"+590","min":7,"max":7},"PM":{"prefix":"+508","min":6,"max":6,"country":"Saint Pierre and Miquelon"},"VC":{"prefix":"+1784","min":10,"max":10,"country":"Saint Vincent and the Grenadines"},"WS":{"prefix":"+685","min":3,"max":7,"country":"Samoa"},"SM":{"prefix":"+378","min":6,"max":10,"country":"San Marino"},"ST":{"prefix":"+239","min":7,"max":7,"country":"Sao Tome and Principe"},"SA":{"prefix":"+966","min":8,"max":9,"country":"Saudi Arabia"},"SN":{"prefix":"+221","min":9,"max":9,"country":"Senegal"},"RS":{"prefix":"+381","min":4,"max":12,"country":"Serbia"},"SC":{"prefix":"+248","min":7,"max":7,"country":"Seychelles"},"SL":{"prefix":"+232","min":8,"max":8,"country":"Sierra Leone"},"SG":{"prefix":"+65","min":8,"max":12,"country":"Singapore"},"SK":{"prefix":"+421","min":4,"max":9,"country":"Slovakia"},"SI":{"prefix":"+386","min":8,"max":8,"country":"Slovenia"},"SB":{"prefix":"+677","min":5,"max":5,"country":"Solomon Islands"},"SO":{"prefix":"+252","min":5,"max":8,"country":"Somalia"},"ZA":{"prefix":"+27","min":9,"max":9,"country":"South Africa"},"SS":{"country":"South Sudan","prefix":"+211","min":9,"max":9},"GS":{"country":"South Georgia and the South Sandwich Islands","prefix":"+500","min":5,"max":5},"ES":{"prefix":"+34","min":9,"max":9,"country":"Spain"},"LK":{"prefix":"+94","min":9,"max":9,"country":"Sri Lanka"},"SD":{"prefix":"+249","min":9,"max":9,"country":"Sudan"},"SR":{"prefix":"+597","min":6,"max":7,"country":"Suriname"},"SZ":{"prefix":"+268","min":7,"max":8,"country":"Eswatini"},"SE":{"prefix":"+46","min":7,"max":13,"country":"Sweden"},"CH":{"prefix":"+41","min":4,"max":12,"country":"Switzerland"},"SY":{"prefix":"+963","min":8,"max":10,"country":"Syria"},"TW":{"prefix":"+886","min":8,"max":9,"country":"Taiwan"},"TJ":{"prefix":"+992","min":9,"max":9,"country":"Tajikistan"},"TZ":{"prefix":"+255","min":9,"max":9,"country":"Tanzania"},"TH":{"prefix":"+66","min":8,"max":9,"country":"Thailand"},"TL":{"country":"Timor-Leste","prefix":"+670","min":9,"max":9},"TG":{"prefix":"+228","min":8,"max":8,"country":"Togo"},"TK":{"prefix":"+690","min":4,"max":4,"country":"Tokelau"},"TO":{"prefix":"+676","min":5,"max":6,"coun
9020try":"Tonga"},"TT":{"prefix":"+1868","min":10,"max":10,"country":"Trinidad and Tobago"},"TN":{"prefix":"+216","min":8,"max":8,"country":"Tunisia"},"TR":{"prefix":"+90","min":10,"max":10,"country":"Turkey"},"TM":{"prefix":"+993","min":8,"max":8,"country":"Turkmenistan"},"TC":{"prefix":"+1649","min":10,"max":10,"country":"Turks and Caicos Islands"},"TV":{"prefix":"+688","min":5,"max":6,"country":"Tuvalu"},"UG":{"prefix":"+256","min":9,"max":9,"country":"Uganda"},"UA":{"prefix":"+380","min":9,"max":9,"country":"Ukraine"},"AE":{"prefix":"+971","min":8,"max":9,"country":"United Arab Emirates"},"GB":{"prefix":"+44","min":7,"max":10,"country":"United Kingdom"},"US":{"prefix":"+1","min":10,"max":10,"country":"United States"},"UY":{"prefix":"+598","min":4,"max":11,"country":"Uruguay"},"UZ":{"prefix":"+998","min":9,"max":9,"country":"Uzbekistan"},"VU":{"prefix":"+678","min":5,"max":7,"country":"Vanuatu"},"VE":{"prefix":"+58","min":10,"max":10,"country":"Venezuela"},"VN":{"prefix":"+84","min":7,"max":10,"country":"Vietnam"},"VG":{"prefix":"+1284","min":10,"max":10,"country":"British Virgin Islands"},"VI":{"prefix":"+1340","min":10,"max":10,"country":"United States Virgin Islands"},"WF":{"prefix":"+681","min":6,"max":6,"country":"Wallis and Futuna"},"YE":{"prefix":"+967","min":6,"max":9,"country":"Yemen"},"ZM":{"prefix":"+260","min":9,"max":9,"country":"Zambia"},"ZW":{"prefix":"+263","min":5,"max":10,"country":"Zimbabwe"}},
9021
9022			_country_obj:function(prefix)
9023				{
9024					for( let i in this.countries ) {
9025						i = this.countries[i];
9026						if( i in this.country_db && this.country_db[i]['prefix'] == prefix )
9027							return this.country_db[i];
9028					}
9029					return false;
9030				},
9031			_on_change_events:function()
9032				{
9033					var me = this;
9034					$(':input[id*="'+me.name+'_"]').each(function(){
9035						el = $(this);
9036						el.on('change', function(){
9037							var v = '';
9038                            var p = '';
9039                            $(':input[id*="'+me.name+'_"]').each(function(){
9040                                if(this.tagName == 'SELECT') p = $(this).val();
9041                                v+=$(this).val();
9042                            });
9043                            $('#'+me.name).val(v != p ? v : '').trigger('change');
9044						})
9045						.on('keyup', function(evt){
9046							var e = $(this);
9047							if(e.val().length == e.attr('maxlength'))
9048							{
9049								e.trigger('change');
9050								let i = parseInt(e.attr('name').match(/\d+$/))+1;
9051								try{ $('#'+me.name+'_'+i).trigger('focus'); } catch(err){}
9052							}
9053						});
9054					});
9055				},
9056			_input_boxes:function( silent )
9057				{
9058					silent = silent || false;
9059
9060					let me 		    = this,
9061						prefix      = $('#'+me.name+'_0').val(),
9062					    bk_number   = '',
9063						country_obj = me._country_obj(prefix),
9064						output      = '',
9065						placeholder = (typeof me.predefinedClick != 'undefined' && me.predefinedClick),
9066						cw			= me.toDisplay == 'iso' ? 60 : 90, // Country code width;
9067						predefined  = String( me.predefined ).replace(/\s/g, ''); // Used for placeholder.
9068
9069					$('input[id*="'+me.name+'_"]').each(function(i,e){ bk_number += $(e).val(); });
9070
9071					if ( country_obj ) {
9072						let symbol = me.isFree ? '#' : me.dformat[0], // Symbol to use for format.
9073							max    = country_obj['max'],
9074							min    = country_obj['min'],
9075							d      = /\s/.test(me.dformat) ? 3 : max,
9076							max_r  = max % d,
9077							min_r  = min % d,
9078							c	   = 1;
9079
9080						if ( predefined.length && predefined.length < max ) predefined += predefined.substr(-1).repeat(max-predefined.length);
9081
9082						for ( var i = 0, h = Math.floor( max/d ); i<h; i++ ) {
9083							let w = d + ( ( max_r && h - i <= max_r ) ? 1 : 0 ),
9084								n = Math.max( 0, Math.min( min, w ) ),
9085								v = ( i == h-1 ) ? bk_number : bk_number.substring(0, w);
9086
9087							bk_number = bk_number.substring(v.length);
9088							min -= w;
9089
9090							output += '<div class="uh_phone" style="width:calc( ( 100% - '+cw+'px ) / '+max+' * '+w+');">'+
9091
9092							'<input aria-label="'+cff_esc_attr(me.title)+'" type="text" id="'+me.name+'_'+c+'" name="'+me.name+'_'+c+'" class="field '+((i==0 && !me.countryComponent) ? ' phone ' : ' digits ')+((me.required && n) ? ' required ' : '')+'" size="'+w+'" maxlength="'+w+'" minlength="'+n+'" '+(me.readonly?'readonly':'')+' style="'+cff_esc_attr(me.getCSSComponent('phone'))+'" value="'+cff_esc_attr(v)+'" '+
9093							(placeholder ? 'placeholder="'+cff_esc_attr( predefined.substring(0,w))+'" ' : '')
9094							+' inputmode="tel" />'+
9095							(
9096								this.showFormatAsHint !== false ?
9097								'<div class="l" style="'+cff_esc_attr(me.getCSSComponent('format'))+'">'+cff_sanitize(symbol.repeat(w), true)+'</div>' :
9098								''
9099							)
9100							+
9101							'</div>';
9102							predefined = predefined.substring(w);
9103							c++;
9104						}
9105
9106					}
9107
9108					let e = $( '.'+me.name ).find('.components_container');
9109					e.find('.uh_phone:not(:first)').remove();
9110					e.append(output);
9111					$('[id*="'+me.name+'"].cpefb_error.message').remove();
9112					if ( ! silent ) $(':input[id*="'+me.name+'"]').valid();
9113					me._on_change_events();
9114				},
9115			init:function()
9116				{
9117					var me  = this;
9118					me.predefined = String(me._getAttr('predefined', true)).trim().replace(/\s/g, '');
9119                    me.dformat = cff_esc_attr(String(me.dformat).trim().replace(/\s+/g, ' '));
9120
9121					me.isFree = !me.dformat.length;
9122
9123					if(!me.countries.length) me.countries = Object.keys(me.country_db);
9124					else {
9125						let filtered = [];
9126						for( let i in me.countries ) {
9127							if( me.countries[i] in me.country_db ) {
9128								filtered.push(me.countries[i]);
9129							}
9130						}
9131						me.countries = filtered;
9132					}
9133				},
9134			show:function()
9135				{
9136                    var me  = this;
9137
9138					var str  = "",
9139						tmpv = me.predefined,
9140						tmp = me.isFree ? [Array(me.FREE_MAX_DIGITS + 1).join('#')] : me.dformat.split(/\s+/),
9141						attr = (typeof me.predefinedClick != 'undefined' && me.predefinedClick) ? 'placeholder' : 'value',
9142						nc   = Math.max(1, me.dformat.replace(/\s/g, '').length),
9143                        c 	 = 0,
9144						cw	 = 0;
9145
9146					str = '<div class="'+me.size+' components_container">';
9147                    if(me.countryComponent) {
9148						let db = {}, countries = [];
9149
9150						for( let i in me.countries ) {
9151							if ( me.countries[i] in me.country_db ) {
9152								if ( ! ( me.countries[i] in db ) ) {
9153									db[me.countries[i]] = me.country_db[me.countries[i]];
9154									db[me.countries[i]]['iso'] = me.countries[i];
9155								}
9156
9157								countries.push(me.countries[i]);
9158							}
9159						}
9160
9161						cw = me.toDisplay == 'iso' ? 60 : 90;
9162						str += '<div class="uh_phone" style="width:'+cw+'px;"><select id="'+me.name+'_'+c+'" name="'+me.name+'_'+c+'" class="field" style="'+cff_esc_attr(me.getCSSComponent('prefix'))+'">';
9163
9164						if( me.includeCountryNames ) { // Sort by country names.
9165							countries = countries.sort(function(a, b){
9166								let n1 = me.country_db[a]['country'].toLowerCase(),
9167									n2 = me.country_db[b]['country'].toLowerCase();
9168								if( n1 < n2) return -1;
9169								if( n2 < n1) return 1;
9170								return 0;
9171							});
9172						} else if ( me.toDisplay != 'iso' ) { // Sort by prefix.
9173							countries = countries.sort(function(a, b){
9174								let n1 = me.country_db[a]['prefix'].replace(/[^\d]/g,'')*1,
9175									n2 = me.country_db[b]['prefix'].replace(/[^\d]/g,'')*1;
9176								if( n1 < n2) return -1;
9177								if( n2 < n1) return 1;
9178								return 0;
9179							});
9180						} else { // Sort by ISO.
9181							countries = countries.sort();
9182						}
9183
9184						let addedPrefix = {};
9185						for ( let i in countries ) {
9186							let prefix  = db[countries[i]]['prefix'],
9187								iso	    = db[countries[i]]['iso'],
9188								txt 	= cff_sanitize( me.toDisplay == 'iso' ? iso : prefix );
9189
9190							if( me.includeFlags || me.includeCountryNames ) {
9191								txt = '<span class="country-code">'+txt+'</span>';
9192								if(me.includeCountryNames) {
9193									txt = '<span class="country-name">'+cff_sanitize(db[countries[i]]['country'])+'</span>'+txt;
9194								}
9195
9196								if(me.includeFlags) {
9197									txt = '<span class="country-flag"><img src="https://cdn.jsdelivr.net/gh/cffdwboostercom/flags@main/'+db[countries[i]]['iso'].toLowerCase()+'.png"></span>'+txt;
9198								}
9199							} else if ( me.toDisplay != 'iso' ) {
9200								if (
9201									prefix in addedPrefix ||
9202									(
9203										me.defaultCountry &&
9204										me.defaultCountry != iso &&
9205										db[ me.defaultCountry ]['prefix'] == prefix
9206									)
9207								) continue;
9208							}
9209							addedPrefix[prefix] = 1;
9210							str += '<option value="'+cff_esc_attr(prefix)+'" '+(me.defaultCountry == countries[i] ? 'SELECTED' : '')+' data-iso="'+cff_esc_attr(iso)+'">'+cff_esc_attr(txt)+'</option>';
9211						}
9212                        str += '</select></div>';
9213                        c++;
9214                    }
9215
9216					for (var i = 0, h = tmp.length;i<h;i++)
9217					{
9218						let l = tmp[i].length,
9219							w = me.isFree ? 'calc(100% - ' + cw + 'px)' : 'calc( ( 100% - ' + cw + 'px ) / ' + Math.max(1, nc) + ' * ' + Math.max(1, l) +')',
9220							mn = me.isFree ? 0 : l;
9221
9222						str += ''+
9223						'<div class="uh_phone" style="width:'+ w +';">'+
9224							'<input aria-label="'+cff_esc_attr(me.title)+'" type="text" id="'+me.name+'_'+c+'" name="'+me.name+'_'+c+'" class="field '+((i==0 && !me.countryComponent) ? ' phone ' : ' digits ')+((me.required) ? ' required ' : '')+'" size="'+cff_esc_attr(l)+'" '+attr+'="'+cff_esc_attr(tmpv.substring(0,l))+'" maxlength="'+cff_esc_attr(l)+'" minlength="'+cff_esc_attr(mn)+'" '+((me.readonly)?'readonly':'')+' style="'+cff_esc_attr(me.getCSSComponent('phone'))+'" />'+
9225							( ! me.isFree && me.showFormatAsHint != false ? '<div class="l" style="'+cff_esc_attr(me.getCSSComponent('format'))+'">'+cff_sanitize(tmp[i], true)+'</div>' : '' )+
9226						'</div>';
9227
9228						tmpv = tmpv.substring(l);
9229						c++;
9230					}
9231
9232					str += '</div>';
9233
9234                    return '<div class="fields ' + cff_esc_attr(me.csslayout) + ' ' + me.name + ' cff-phone-field" id="field' + me.form_identifier + '-' + me.index + '" style="' + cff_esc_attr(me.getCSSComponent('container')) + '"><label for="' + me.name + '" style="' + cff_esc_attr(me.getCSSComponent('label')) + '">' + cff_sanitize(me.title, true) + '' + ((me.required) ? "<span class='r'>*</span>" : "") + '</label><div class="dfield"><input type="hidden" id="' + me.name + '" name="' + me.name + '" class="field' + ((me.required) ? ' required ' : '') +'" data-msg="" ' + (me.predefined && !me.predefinedClick ? 'value="'+cff_esc_attr(me.predefined)+'"' : '') + ' style="' + cff_esc_attr(me.getCSSComponent('phone')) + '" />'+str+'<div class="clearer"></div><span class="uh" style="'+cff_esc_attr(me.getCSSComponent('help'))+'">'+cff_sanitize(me.userhelp, true)+'</span></div><div class="clearer"></div></div>';
9235				},
9236            after_show: function()
9237				{
9238					var me   = this;
9239
9240					if(!('phone' in $.validator.methods))
9241						$.validator.addMethod("phone", function(value, element)
9242						{
9243							if(this.optional(element)) return true;
9244							else return /^\+{0,1}\d*$/.test(value);
9245						});
9246
9247					me._on_change_events();
9248
9249					if (me.countryComponent) {
9250						let prefix = $('select#'+me.name+'_0');
9251						if ( 'select2' in $.fn && ( me.includeFlags || me.includeCountryNames ) ) {
9252							prefix.after('<span class="cff-select2-container"></span>');
9253							prefix.select2({
9254                                'templateResult': function(state){
9255									if ( ! state.id ) return state.text;
9256									if ('DOMPurify' in window) {
9257										let sanitized = DOMPurify.sanitize('<span class="prefix-option">'+state.text+'</span>');
9258										return $(sanitized);
9259									}
9260									return $('<span class="prefix-option">').text(state.text);
9261								},
9262                                'templateSelection': function(state){
9263									if ( ! state.id ) return state.text;
9264									let doc = new DOMParser().parseFromString(String(state.text), 'text/html');
9265									let code = doc.querySelector('.country-code');
9266									return code ? code.textContent : doc.body.textContent || '';
9267								},
9268								'dropdownAutoWidth' : true,
9269								'dropdownParent':prefix.next('.cff-select2-container'),
9270                                'matcher': function(params, data) {
9271                                    function stripHtml(str) {
9272                                        var doc = new DOMParser().parseFromString(str, 'text/html');
9273                                        return doc.body.textContent || '';
9274                                    };
9275
9276                                    if ($.trim(params.term) === '') {
9277                                        return data;
9278                                    }
9279
9280                                    if (typeof data.text === 'undefined') {
9281                                        return null;
9282                                    }
9283
9284                                    var plainText = stripHtml(String(data.text)).trim();
9285                                    var term = String(params.term).toUpperCase().replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
9286
9287                                    if (new RegExp('(?:^|\\W)' + term, 'i').test(plainText)) {
9288                                        return data;
9289                                    }
9290
9291                                    return null;
9292                                }
9293                           });
9294						}
9295						prefix.trigger('change');
9296						if (me.dynamic) {
9297							prefix.on('change', function(){ me._input_boxes(); });
9298							me._input_boxes( true );
9299						}
9300					}
9301				},
9302			get_separator:function(){
9303				let separators = { 'none': '', 'space': ' ', '-': '-', '.' : '.' };
9304				return ( this.dseparator in separators) ? separators[this.dseparator] : '-';
9305			},
9306			val:function(raw, no_quotes, disable_ignore_check)
9307				{
9308                    raw = raw || false;
9309                    no_quotes = no_quotes || false;
9310					var me = this,
9311						e = (disable_ignore_check) ? $('[id="'+this.name+'"]') : $('[id="'+this.name+'"]:not(.ignore)'),
9312						pr = $('[id^="'+this.name+'_"]')
9313							.map(function(){return String($(this).val()).trim();})
9314							.get()
9315							.filter(function(value){return value.length>0;}).join(me.get_separator()),
9316						p  = $.fbuilder.parseValStr(
9317							raw ? pr : e.val(),
9318							true,
9319							no_quotes
9320						);
9321
9322					if(e.length) return ($.fbuilder.isNumeric(p) && !no_quotes) ? '"'+p+'"' : p;
9323					return 0;
9324				},
9325			setVal:function(v)
9326				{
9327					let me = this, max = 0, min = 0, prefix, country_obj;
9328
9329					// Initialize min/max variables.
9330					$('input[id*="'+me.name+'_"]').each(function(i,e){
9331						e = $(e);
9332						max += e.attr( 'maxlength' )*1;
9333						min += e.attr( 'minlength' )*1;
9334					});
9335
9336					function setPrefix( v ) {
9337						let l = v.length, o = '';
9338
9339						for ( let i in me.countries ) {
9340							i = me.countries[i];
9341							let prefix = me.country_db[i]['prefix'],
9342								ln = l - prefix.length;
9343							if (
9344								v.indexOf( prefix ) == 0 &&
9345								me.country_db[i].min <= ln &&
9346								ln <= me.country_db[i].max
9347							) {
9348								if ( ! o || me.country_db[i].max < me.country_db[o].max ) o = i;
9349								if ( ln == me.country_db[o].max ) break;
9350							}
9351						}
9352						if( o ) { o = me.country_db[o]['prefix']; $('select[id*="'+me.name+'_"]').val(o).trigger('change'); }
9353						return o;
9354					}; // End setPrefix.
9355
9356					v = cff_esc_attr(String(v).trim());
9357					$('[name="'+me.name+'"]').val(v);
9358					$('input[id*="'+me.name+'_"]').val('');
9359                    if(v.length) {
9360                        let f = v[0];
9361
9362                        v = ( f != '+' ? '' : '+' ) + v.replace(/[^\d]/g, '');
9363
9364                        if ( f == '+' && me.countryComponent ) {
9365							prefix = $('select[id*="'+me.name+'_"]').val();
9366							country_obj = me._country_obj(prefix);
9367
9368							if( v.indexOf( prefix ) != 0 || ( country_obj && country_obj.max+prefix.length < v.length ) ) {
9369								prefix = setPrefix( v );
9370							}
9371							v = v.substring( prefix.length );
9372						}
9373
9374						$('input[id*="'+me.name+'_"]').each(function(i,e) {
9375							e = $(e);
9376							let l = e.attr( 'maxlength' );
9377							e.val( v.substring( 0, l ) );
9378							v = v.substring( l );
9379						});
9380					}
9381				}
9382		}
9383	);	$.fbuilder.controls['fCommentArea']=function(){};
9384	$.extend(
9385		$.fbuilder.controls['fCommentArea'].prototype,
9386		$.fbuilder.controls['ffields'].prototype,
9387		{
9388			title:"Comments here",
9389			ftype:"fCommentArea",
9390			userhelp:"A description of the section goes here.",
9391			show:function()
9392				{
9393                    return '<div class="fields '+cff_esc_attr(this.csslayout)+' '+this.name+' comment_area cff-instruct-text-field" id="field'+this.form_identifier+'-'+this.index+'" style="'+cff_esc_attr(this.getCSSComponent('container'))+'"><label id="'+this.name+'" style="'+cff_esc_attr(this.getCSSComponent('label'))+'">'+cff_sanitize(this.title, true)+'</label><span class="uh" style="'+cff_esc_attr(this.getCSSComponent('help'))+'">'+cff_sanitize(this.userhelp, true)+'</span><div class="clearer"></div></div>';
9394				}
9395		}
9396	);	$.fbuilder.controls['fhidden']=function(){};
9397	$.extend(
9398		$.fbuilder.controls['fhidden'].prototype,
9399		$.fbuilder.controls['ffields'].prototype,
9400		{
9401			ftype:"fhidden",
9402			title:"",
9403			predefined:"",
9404			show:function()
9405				{
9406					this.predefined = this._getAttr('predefined', true);
9407					return '<div class="fields '+cff_esc_attr(this.csslayout)+' '+this.name+' cff-hidden-field" id="field'+this.form_identifier+'-'+this.index+'" style="padding:0;margin:0;border:0;width:0;height:0;overflow:hidden;"><label for="'+this.name+'">'+cff_sanitize(this.title, true)+'</label><div class="dfield"><input id="'+this.name+'" name="'+this.name+'" type="hidden" value="'+cff_esc_attr(this.predefined)+'" class="field" /></div></div>';
9408				}
9409		}
9410	);	$.fbuilder.controls['fSectionBreak'] = function(){};
9411	$.extend(
9412		$.fbuilder.controls['fSectionBreak'].prototype,
9413		$.fbuilder.controls['ffields'].prototype,
9414		{
9415			title:"Section Break",
9416			ftype:"fSectionBreak",
9417			userhelp:"A description of the section goes here.",
9418			show:function()
9419				{
9420                    return '<div class="fields '+cff_esc_attr(this.csslayout)+' '+this.name+' section_breaks cff-sectionbreak-field" id="field'+this.form_identifier+'-'+this.index+'" style="'+cff_esc_attr(this.getCSSComponent('container'))+'"><div class="section_break" id="'+this.name+'" ></div><label style="'+cff_esc_attr(this.getCSSComponent('label'))+'">'+cff_sanitize(this.title, true)+'</label><span class="uh" style="'+cff_esc_attr(this.getCSSComponent('help'))+'">'+cff_sanitize(this.userhelp, true)+'</span><div class="clearer"></div></div>';
9421				}
9422		}
9423	);	$.fbuilder.controls['fPageBreak']=function(){};
9424	$.extend(
9425		$.fbuilder.controls['fPageBreak'].prototype,
9426		$.fbuilder.controls['ffields'].prototype,
9427		{
9428			title:"Page Break",
9429			ftype:"fPageBreak"
9430		}
9431	);	$.fbuilder.controls['fsummary'] = function(){};
9432	$.extend(
9433		$.fbuilder.controls['fsummary'].prototype,
9434		$.fbuilder.controls['ffields'].prototype,
9435		{
9436			title:"Summary",
9437			ftype:"fsummary",
9438			fields:"",
9439			fieldsArray:[],
9440			exclude_empty: false,
9441			titleClassname:"summary-field-title",
9442			valueClassname:"summary-field-value",
9443			init:function() {
9444				let me = this;
9445				me.fieldsArray = [];
9446				if ('string' != typeof me.fields) return;
9447				let p = String(me.fields.replace(/\,+/g, ',')).trim().split(','),
9448					l = p.length;
9449				if(l) {
9450					for (let i = 0; i < l; i++) {
9451						p[i] = String(p[i]).trim();
9452						if (p[i]) {
9453							me.fieldsArray.push(p[i]);
9454						}
9455					}
9456				}
9457			},
9458			show:function() {
9459				let me = this;
9460				return '<div class="fields '+cff_esc_attr(me.csslayout)+' '+me.name+' cff-summary-field" id="field'+me.form_identifier+'-'+me.index+'" style="'+cff_esc_attr(me.getCSSComponent('container'))+'">'+((!/^\s*$/.test(me.title)) ? '<h2 style="'+cff_esc_attr(me.getCSSComponent('label'))+'">'+cff_sanitize(me.title, true)+'</h2>': '')+'<div id="'+me.name+'"></div></div>';
9461			},
9462			after_show: function () {
9463				let me = this;
9464				if (me._summaryInitialized) return;
9465				me._summaryInitialized = true;
9466				if (! me.fieldsArray.length) return;
9467
9468				for (let i = 0, h = me.fieldsArray.length; i < h; i++) {
9469					let item = getField(me.fieldsArray[i], me.form_identifier);
9470					if (!item) continue;
9471					$(document).on('change', '[id*="' + item.name + '"]', function () { me.update(
9471); });
9472				}
9473				let form = me.jQueryRef().closest('form');
9474				$(document).on('showHideDepEvent', form, function (evt) { me.update(); });
9475				form.on('reset', function () { setTimeout(function () { me.update(); }, 10); });
9476
9477				me.update();
9478			},
9479			update: function () {
9480				let me = this;
9481				if (me.fieldsArray.length == 0) {
9482					$('[id="' + me.name + '"]').html('').trigger('cff-summary-update');
9483					return;
9484				}
9485
9486				let str = '';
9487				for (let i = 0, h = me.fieldsArray.length; i < h; i++) {
9488					let item = getField(me.fieldsArray[i], me.form_identifier);
9489					if (!item) continue;
9490
9491					if (item.ftype === 'frepeater') {
9492						for (let rowIdx in item.matrix) {
9493							for (let childOrig in item.matrix[rowIdx]) {
9494								let childItem = getField(item.matrix[rowIdx][childOrig], me.form_identifier);
9495								if (!childItem) continue;
9496								str += me._renderItem(childItem);
9497							}
9498						}
9499					} else {
9500						str += me._renderItem(item);
9501					}
9502				}
9503
9504				$('[id="' + me.name + '"]').html(str).trigger('cff-summary-update');
9505			},
9506			_renderItem: function(item) {
9507				let me = this,
9508					resolvedId = item.name;
9509
9510				let e = $('[id="' + resolvedId + '"]:not(.ignore),[id^="' + resolvedId + '_rb"]:not(.ignore),[id^="' + resolvedId +'_cb"]:not([type="number"]):not(.ignore)');
9511
9512				if (!e.length) return '';
9513
9514				let l = $('[id="'+resolvedId+'"],[id^="'+resolvedId+'_rb"],[id^="'+resolvedId+'_cb"]')
9515						.closest('.fields')
9516						.find('label:first')
9517						.clone()
9518						.find('.r,.dformat')
9519						.remove()
9520						.end(),
9521					t = String(l.text()).trim().replace(/\:$/,''),
9522					v = [];
9523
9524				e.each(function(){
9525					let e = $(this);
9526					if(/(checkbox|radio)/i.test(e.attr('type')) && !e.is(':checked')) return;
9527					else if(e[0].tagName == 'SELECT') {
9528						let vt = [];
9529						e.find('option:selected').each(function(){ vt.push($(this).attr('vt')); });
9530						v.push(vt.join(', '));
9531					} else {
9532						if(e.attr('vt')) {
9533							let q = $('[id="'+e.attr('id')+'_quantity"]');
9534							v.push(e.attr('vt')+(q.length ? ' ('+Math.max(q.val(),1)+')' : ''));
9535						} else if(e.attr('summary')) {
9536							v.push($('#'+resolvedId).closest('.fields').find('.'+e.attr('summary')+resolvedId).html());
9537						} else {
9538							let d = $('[id="'+resolvedId+'_date"]');
9539							if(d.length) {
9540								if(d.is(':disabled')) v.push(e.val().replace(d.val(),''));
9541								else v.push(e.val());
9542							} else {
9543								if(e.attr('type') == 'file') {
9544									let f = [];
9545									$.each(e[0].files, function(i,o){ f.push(o.name); });
9546									v.push(f.join(', '));
9547								} else if(!e.hasClass('cpefb_error message')) {
9548									let c = $('[id="'+resolvedId+'_caption"]');
9549									if(c.length && !/^\s*$/.test(c.html())) v.push(c.html());
9550									else if(e.closest('.cff-phone-field').length) {
9551										let obj = getField(e);
9552										if(obj) v.push(obj.val(true, true));
9553									} else v.push(e.val());
9554								}
9555							}
9556						}
9557					}
9558				});
9559
9560				v = v.join(', ');
9561				if(me.exclude_empty && v == '') return '';
9562
9563				let str = '<div ref="'+cff_esc_attr(resolvedId)+'" class="cff-summary-item" style="'+cff_esc_attr(me.getCSSComponent('fields_rows'))+'">';
9564				if(!/^\s*$/.test(t)) {
9565					str += '<span class="'+cff_esc_attr(me.titleClassname)+' cff-summary-title" style="'+cff_esc_attr(me.getCSSComponent('fields_labels'))+'">'+cff_sanitize(t, true)+'</span>';
9566				}
9567				str += '<span class="'+cff_esc_attr(me.valueClassname)+' cff-summary-value" style="'+cff_esc_attr(me.getCSSComponent('fields_values'))+'">'+cff_sanitize(v, true)+'</span>';
9568				str += '</div>';
9569				return str;
9570			}
9571		}
9572	);	$.fbuilder.controls['fcontainer'] = function(){};
9573	$.fbuilder.controls['fcontainer'].prototype = {
9574		fields:[],
9575		columns:1,
9576		align:"top",
9577		rearrange: 0,
9578		after_show: function(e, l)
9579			{
9580				e = e || $('#'+this.name);
9581				l = l || this.fields;
9582
9583				var f,
9584					to_ignore = 0; // Ignores the RecordSet DS and Hidden fields.
9585                for(var i = 0, h = l.length; i < h; i++)
9586				{
9587					let flag = true;
9588					f = $('.fields.'+l[i]+this.form_identifier);
9589					if( f.hasClass('cff-hidden-field') ) { to_ignore++; }
9590					f = f.detach();
9591					f.addClass('column'+this.columns);
9592					if(this.columns > 1)
9593					{
9594						if( ( i - to_ignore ) % this.columns == 0 && ! this.rearrange ) {
9595							f.css('clear', 'left');
9596							f.appendTo(e);
9597							if ( i - to_ignore && this.align=="bottom" ) f.before('<div class="cff-row-breaker"></div>');
9598							flag = false;
9599						}
9600					}
9601					if ( flag ) f.appendTo(e);
9602				}
9603			},
9604		showHideDep:function(toShow, toHide, hiddenByContainer, interval)
9605			{
9606                if(typeof hiddenByContainer == 'undefined') hiddenByContainer = {};
9607				var me = this,
9608					isHidden = (typeof toHide[me.name] != 'undefined' || typeof hiddenByContainer[me.name] != 'undefined'),
9609					fId,
9610					result = [];
9611
9612				for(var i = 0, h = me.fields.length; i < h; i++)
9613				{
9614					if(!/fieldname/i.test(me.fields[i])) continue;
9615					fId = me.fields[i]+me.form_identifier;
9616					if(isHidden)
9617					{
9618						if(typeof hiddenByContainer[fId] == 'undefined') hiddenByContainer[fId] = {};
9619						if(typeof hiddenByContainer[fId][me.name] == 'undefined')
9620						{
9621							hiddenByContainer[fId][me.name] = {};
9622
9623							if(typeof toHide[fId] == 'undefined')
9624							{
9625								$('.'+fId+' [id*="'+fId+'"],.'+fId).closest('.fields').addClass('ignorefield').hide();
9626								$('.'+fId+' [id*="'+fId+'"]:not(.ignore)').addClass('ignore').trigger('add-ignore');
9627								result.push(fId);
9628							}
9629						}
9630					}
9631					else
9632					{
9633						if(typeof hiddenByContainer[fId] != 'undefined')
9634						{
9635							delete hiddenByContainer[fId][me.name];
9636							if($.isEmptyObject(hiddenByContainer[fId]))
9637							{
9638								delete hiddenByContainer[fId];
9639								if(typeof toHide[fId] == 'undefined')
9640								{
9641									$('.'+fId+' [id*="'+fId+'"],.'+fId).closest('.fields').removeClass('ignorefield').fadeIn(interval || 0);
9642									$('.'+fId+' [id*="'+fId+'"].ignore').removeClass('ignore').trigger('remove-ignore');
9643									result.push(fId);
9644								}
9645							}
9646						}
9647					}
9648				}
9649				return result;
9650			}
9651	};	$.fbuilder.controls['ffieldset']=function(){};
9652	$.extend(
9653		$.fbuilder.controls['ffieldset'].prototype,
9654		$.fbuilder.controls['ffields'].prototype,
9655		{
9656			title:"Untitled",
9657			ftype:"ffieldset",
9658			fields:[],
9659			columns:1,
9660			align:"top",
9661			collapsible:false,
9662			defaultCollapsed:true,
9663            selfClosing:false,
9664			rearrange: 0,
9665			audiotutorial:'',
9666			show:function()
9667				{
9668					let title = cff_sanitize(this.title, true);
9669					if ( this.collapsible) title = '<span tabindex="0">' + title + '</span>';
9670                    return '<div class="fields '+cff_esc_attr(this.csslayout)+' '+this.name+' cff-fieldset-field cff-container-field '+((this.collapsible) ? 'cff-collapsible'+((this.selfClosing) ? ' cff-selfclosing' : '')+((this.defaultCollapsed) ?  ' cff-collapsed' : '') : '')+'" id="field'+this.form_identifier+'-'+this.index+'" style="'+cff_esc_attr(this.getCSSComponent('field'))+'"><FIELDSET style="'+cff_esc_attr(this.getCSSComponent('container'))+'">'+((!/^\s*$/.test(this.title) || this.collapsible) ? '<LEGEND style="'+cff_esc_attr(this.getCSSComponent('legend'))+'">'+title+'</LEGEND>' : '')+'<div id="'+this.name+'" class="'+( this.align == 'bottom' ? 'cff-align-container-bottom' : '' )+'"></div></FIELDSET><div class="clearer"></div></div>';
9671				},
9672			after_show: function()
9673				{
9674					var me = this;
9675					$.fbuilder.controls['fcontainer'].prototype.after_show.call(this);
9676					if(me.collapsible){
9677						function collapseApply(p){
9678							if(p.length)
9679                            {
9680                                p.toggleClass('cff-collapsed');
9681								p.trigger('cff-collapsible', ! p.hasClass('cff-collapsed')); // Attribute is_open
9682                                if(!p.hasClass('cff-collapsed'))
9683                                {
9684                                    p.siblings('.cff-selfclosing').each(function(){
9685										let e = $(this);
9686										if ( ! e.hasClass('cff-collapsed') )
9687											$(this).addClass('cff-collapsed').trigger('cff-collapsible', false);
9688									});
9689                                }
9690                            }
9691						}
9692                        $('.'+me.name+'>fieldset>legend').on('click', function(evt){
9693                            collapseApply($(this).closest('.cff-collapsible'));
9694							evt.preventDefault();
9695							evt.stopPropagation();
9696                        }).on('keyup', function(evt){
9697							if (evt.key === 'Enter') {
9698								$(this).trigger('click');
9699							}
9700						});
9701						$('.'+me.name).on('click', function(){
9702							var e = $(this);
9703                            if(e.hasClass('cff-collapsed')) collapseApply(e);
9704                        });
9705                    }
9706				},
9707			showHideDep:function(toShow, toHide, hiddenByContainer)
9708				{
9709					return $.fbuilder.controls['fcontainer'].prototype.showHideDep.call(this, toShow, toHide, hiddenByContainer);
9710				}
9711		}
9712	);	$.fbuilder.controls['fdiv']=function(){};
9713	$.extend(
9714		$.fbuilder.controls['fdiv'].prototype,
9715		$.fbuilder.controls['ffields'].prototype,
9716		{
9717			ftype:"fdiv",
9718			fields:[],
9719			columns:1,
9720			align:"top",
9721			rearrange: 0,
9722			show:function()
9723				{
9724					return '<div class="fields '+cff_esc_attr(this.csslayout)+' '+this.name+' cff-div-field cff-container-field" id="field'+this.form_identifier+'-'+this.index+'" style="'+cff_esc_attr(this.getCSSComponent('field'))+'"><div id="'+this.name+'" class="'+( this.align == 'bottom' ? 'cff-align-container-bottom' : '' )+'" style="'+cff_esc_attr(this.getCSSComponent('container'))+'"></div><div class="clearer"></div></div>';
9725				},
9726			after_show: function()
9727				{
9728					$.fbuilder.controls['fcontainer'].prototype.after_show.call(this);
9729				},
9730			showHideDep:function(toShow, toHide, hiddenByContainer)
9731				{
9732					return $.fbuilder.controls['fcontainer'].prototype.showHideDep.call(this, toShow, toHide, hiddenByContainer);
9733				}
9734		}
9735	);	$.fbuilder.controls['fMedia']=function(){};
9736	$.extend(
9737		$.fbuilder.controls['fMedia'].prototype,
9738		$.fbuilder.controls['ffields'].prototype,
9739		{
9740			ftype:"fMedia",
9741            sMediaType:"image", // image, audio, video
9742			sAlignment:"default",
9743            data:{
9744                image:{
9745                    sWidth:"",
9746                    sHeight:"",
9747                    sSrc:"",
9748                    sAlt:"",
9749                    sLink:"",
9750                    sTarget:"",
9751                    sFigcaption: "",
9752					sLazy:0
9753                },
9754                audio:{
9755                    sWidth:"",
9756                    sSrc:"",
9757                    sSrcAlt:"",
9758                    sControls:1,
9759                    sLoop:0,
9760                    sAutoplay:0,
9761                    sMuted:0,
9762                    sPreload: "auto",
9763                    sFallback: "",
9764                    sFigcaption: "",
9765					sHideDownload:0
9766                },
9767                video:{
9768                    sWidth:"",
9769                    sHeight:"",
9770                    sSrc:"",
9771                    sSrcAlt:"",
9772                    sPoster:"",
9773                    sControls:1,
9774                    sLoop:0,
9775                    sAutoplay:0,
9776                    sMuted:0,
9777                    sPreload: "auto",
9778                    sFallback: "",
9779                    sFigcaption: "",
9780					sHideDownload:0
9781                }
9782            },
9783            _show_image: function()
9784                {
9785                    var d = this.data.image,
9786						esc = cff_esc_attr,
9787                        a = [],
9788                        l = [],
9789                        r = '';
9790
9791                    if(String(d.sWidth).trim()) a.push('width="'+esc(d.sWidth)+'"');
9792                    if(String(d.sHeight).trim()) a.push('height="'+esc(d.sHeight)+'"');
9793                    if(String(d.sSrc).trim())
9794						if(d.sLazy && 'IntersectionObserver' in window) {
9795							a.push('src=""');
9796							a.push('data-src="'+esc(d.sSrc)+'"');
9797						} else {
9798							a.push('src="'+esc(d.sSrc)+'"');
9799						}
9800                    if(String(d.sAlt).trim()) a.push('alt="'+esc(d.sAlt)+'"');
9801                    if(String(d.sLink).trim())
9802                    {
9803                        l.push('href="'+esc(d.sLink)+'"');
9804                        if(String(d.sTarget).trim()) l.push('target="'+esc(d.sTarget)+'"');
9805                        r = '<a '+l.join(' ')+' ><img '+a.join(' ')+' style="'+cff_esc_attr(this.getCSSComponent('image'))+'" /></a>';
9806                    }
9807                    else
9808                    {
9809                        r = '<img '+a.join(' ')+' style="'+cff_esc_attr(this.getCSSComponent('image'))+'" />';
9810                    }
9811
9812                    return r;
9813                },
9814			_show_audio_video: function(d, isV)
9815                {
9816                    var esc = cff_esc_attr,
9817                        a = [],
9818						s = [],
9819                        t = (isV) ? 'video' : 'audio' ;
9820
9821                    if(String(d.sWidth).trim()) s.push('width:'+esc(d.sWidth)+';');
9822                    if(isV && String(d.sHeight).trim()) s.push('height:'+esc(d.sHeight)+';');
9823                    if(isV && String(d.sPoster).trim()) a.push('poster="'+esc(d.sPoster)+'"');
9824                    if(String(d.sSrc).trim()) a.push('src="'+esc(d.sSrc)+'"');
9825                    if(d.sAutoplay) a.push('autoplay');
9826                    if(d.sControls) a.push('controls');
9827                    if(d.sLoop) a.push('loop');
9828                    if(d.sMuted) a.push('muted');
9829                    if(d.sHideDownload) a.push('controlsList="nodownload"');
9830                    a.push('preload="'+esc(d.sPreload)+'"');
9831
9832                    return '<'+t+' '+a.join(' ')+' style="'+s.join(' ')+'" style="'+esc(this.getCSSComponent(isV ? 'video' : 'audio'))+'">'+((String(d.sSrcAlt).trim()) ? '<source src="'+esc(d.sSrcAlt)+'" />' : '')+'<p>'+cff_sanitize(d.sFallback, true)+'</p></'+t+'>';
9833                },
9834            _show_audio: function()
9835                {
9836                    return this._show_audio_video(this.data.audio, false);
9837                },
9838            _show_video: function()
9839                {
9840                    return this._show_audio_video(this.data.video, true);
9841                },
9842            show:function()
9843				{
9844						let align = this.sAlignment != 'default' ? 'text-align:'+this.sAlignment+';' : '';
9845						return '<div class="fields '+cff_esc_attr(this.csslayout)+' '+this.name+' cff-media-field" id="field'+this.form_identifier+'-'+this.index+'" style="'+cff_esc_attr(this.getCSSComponent('container'))+'"><div class="clearer"><div class="field" id="'+this.name+'" style="'+align+'">'+this['_show_'+this.sMediaType]()+'</div></div><span class="uh" style="'+align+cff_esc_attr(this.getCSSComponent('caption'))+'">'+cff_sanitize(this.data[this.sMediaType].sFigcaption, true)+'</span><div class="clearer"></div></div>';
9846				},
9847			after_show:function()
9848			    {
9849					// For lazy load.
9850					let me = this;
9851					if (
9852						me.sMediaType == 'image',
9853						me.data.image.sLazy &&
9854						'IntersectionObserver' in window
9855					) {
9856						if ( ! ( 'cffLazyLoadIntersectionObserver' in window ) ) {
9857							window['cffLazyLoadIntersectionObserver'] = new IntersectionObserver((entries, observer) => {
9858								entries.forEach(entry => {
9859									if ( entry.isIntersecting ) {
9860										const img = entry.target;
9861										if ( $( img ).is(':visible') ) {
9862											img.src = img.dataset.src;
9863											img.removeAttribute('data-src');
9864											observer.unobserve(img);
9865										}
9866									}
9867								});
9868							}, {
9869								rootMargin: '0px',
9870								threshold: 0.1
9871							});
9872						}
9873						let e = $('[data-src]','.'+me.name);
9874						if ( e.length ) {
9875							$(document).on('formReady', function(evt, form_id){
9876								if ( 'cp_calculatedfieldsf_pform'+me.form_identifier == form_id )
9877									window['cffLazyLoadIntersectionObserver'].observe(e[0]);
9878							});
9879						}
9880					}
9881				}
9882		}
9883	);	$.fbuilder.controls['frecordav']=function(){};
9884	$.extend(
9885		$.fbuilder.controls['frecordav'].prototype,
9886		$.fbuilder.controls['ffields'].prototype,
9887		{
9888			ftype:"frecordav",
9889			required:false,
9890			exclude:false,
9891			size:"medium",
9892			to_record:"video",
9893			max_time:0,
9894			beep:0,
9895			preview:false,
9896			video_width:320,
9897			video_height:240,
9898			record_label: 'Record',
9899			stop_label: 'Stop',
9900			status_message: 'Recording saved',
9901			_has_hours_component:function(){return Math.floor( this.max_time / 3600 ) ? 1 : 0;},
9902			_is_video: function(){ return this.to_record == 'video' || this.to_record == 'audio-video';},
9903			_is_audio: function(){ return this.to_record == 'audio' || this.to_record == 'audio-video';},
9904			_format_time_component:function(v)
9905				{
9906					var _has_hours = this._has_hours_component(),
9907						hours = Math.floor( v / 3600 ),
9908						minutes = Math.floor( ( v - hours * 3600 ) / 60 ),
9909						seconds = ( v - hours * 3600 - minutes * 60 ) % 60,
9910						time_formatted = ( _has_hours ? ( hours < 10 ? '0' + hours : hours ) + ':' : '' ) + ( minutes < 10 ? '0' + minutes : minutes ) + ':' + ( seconds < 10 ? '0' + seconds : seconds );
9911					return time_formatted;
9912				},
9913			init:function()
9914				{
9915					this.getCSSComponent('button', true, '#fbuilder .cff-record-av-field #'+this.name+'_record_btn', this.form_identifier);
9916					this.getCSSComponent('button_hover', true, '#fbuilder .cff-record-av-field #'+this.name+'_record_btn:hover', this.form_identifier);
9917				},
9918            show:function()
9919				{
9920					var max_time_formatted = this._format_time_component(this.max_time),
9921						time_formatted = ( this._has_hours_component() ? '00:' : '')+'00:00';
9922
9923					return '<div class="fields '+cff_esc_attr(this.csslayout)+' '+this.name+' cff-record-av-field" id="field'+this.form_identifier+'-'+this.index+'" style="'+cff_esc_attr(this.getCSSComponent('container'))+'">' +
9924					'<label for="'+this.name+'_record_btn" style="'+cff_esc_attr(this.getCSSComponent('label'))+'">'+cff_sanitize(this.title, true)+''+((this.required)?"<span class='r'>*</span>":"")+'</label>' +
9925					'<div class="dfield">' +
9926					'<input type="file" id="'+this.name+'" name="'+this.name+'[]" class="hide-strong" />' +
9927					'<div class="cff-record-controls-container">' +
9928					'<div class="cff-record-btn" id="'+this.name+'_record_btn">'+cff_sanitize(this.record_label, true)+'</div>' +
9929					( this.preview ? '<div class="cff-record-play-btn hide-strong" id="'+this.name+'_play_btn"></div>' : '' ) +
9930					( this.max_time ? '<div class="cff-record-time" id="'+this.name+'_record_time">'+cff_sanitize(time_formatted, true)+'</div><div class="cff-record-max-time">'+cff_sanitize(max_time_formatted, true)+'</div>' : '' ) +
9931					'</div>' +
9932					'<div class="clearer"></div>' +
9933					'<div class="cff-record-status hide-strong" id="'+this.name+'_record_status">'+cff_sanitize(this.status_message, true)+'</div>' +
9934					( this.preview ? (this._is_video() ? '<video id="'+this.name+'_media" width="'+cff_esc_attr(this.video_width)+'" height="'+cff_esc_attr(this.video_height)+'" class="hide-strong" style="margin-top:10px;" preload="metadata" style="'+cff_esc_attr(this.getCSSComponent('video'))+'"></video>': '<audio id="'+this.name+'_media" class="hide-strong" style="'+cff_esc_attr(this.getCSSComponent('audio'))+'"></audio>') : '' ) +
9935					'<div class="clearer"></div>' +
9936					'<span class="uh" style="'+cff_esc_attr(this.getCSSComponent('help'))+'">'+cff_sanitize(this.userhelp, true)+'</span></div><div class="clearer" /></div>';
9937				},
9938			after_show:function()
9939			{
9940				var me 			= this,
9941					mssg 		= $('#'+me.name+'_record_status'),
9942					record_btn 	= $('#'+this.name+'_record_btn'),
9943					play_btn 	= $('#'+me.name+'_play_btn'),
9944					file_ctrl	= $('#'+me.name),
9945					media_ctrl	= $('#'+me.name+'_media'),
9946					record_time = $('#'+me.name+'_record_time'),
9947					chunks 		= [],
9948					interval,
9949					streamRecorder,
9950					recording_flag = false;
9951
9952				play_btn[_files().length ? 'removeClass' : 'addClass' ]('hide-strong');
9953
9954				if(media_ctrl.length)
9955				{
9956					media_ctrl[0].ontimeupdate = function(evt){
9957						if(!recording_flag)	record_time.text(me._format_time_component(Math.round(evt.target.currentTime)));
9958					};
9959					media_ctrl[0].onended = function(evt){
9960						evt.target.currentTime = 0;
9961						play_btn.removeClass('cff-record-stop-btn');
9962					};
9963				}
9964
9965				if(!navigator.mediaDevices || !navigator.mediaDevices.getUserMedia) {
9966					$('.'+me.name).remove();
9967					return;
9968				}
9969
9970				function _files() {
9971					return file_ctrl[0].files;
9972				};
9973
9974				function _load_file() {
9975					var files = _files();
9976					if(files.length && media_ctrl.length)
9977					{
9978						media_ctrl[0].src = URL.createObjectURL(files[0]);
9979						return true;
9980					}
9981					return false;
9982				}
9983
9984				function _random() {
9985					return Math.floor(Math.random()*(1000-9999+1)+1000);
9986				};
9987
9988				function _stopRecording() {
9989					try {
9990						if(typeof streamRecorder != 'undefined')
9991						{
9992							streamRecorder.onstop = function(evt) {
9993								var container = new DataTransfer(),
9994									file = new File(
9995										chunks,
9996										me.to_record+_random()+'.webm',
9997										{type:'video/webm', lastModified:new Date().getTime()}
9998									);
9999								container.items.add(file);
10000								file_ctrl[0].files = container.files;
10001								play_btn.removeClass('cff-record-stop-btn hide-strong');
10002								mssg.removeClass('hide-strong');
10003								_load_file();
10004							};
10005							streamRecorder.stop();
10006						}
10007					} catch(err) {console.log(err);};
10008
10009					record_btn.removeClass('cff-record-btn-recording');
10010					if(me._is_video() && media_ctrl.length)
10011					{
10012						media_ctrl[0].pause();
10013						media_ctrl[0].srcObject = null;
10014
10015					}
10016					recording_flag = false;
10017				};
10018
10019				record_btn.on( 'click', function(evt){
10020					var settings = {
10021							video: (me._is_video()) ? {facingMode: 'user'} : false,
10022							audio: (me._is_audio()) ? true : false
10023						};
10024
10025					clearInterval(interval);
10026
10027					play_btn.addClass('hide-strong');
10028					mssg.addClass('hide-strong');
10029
10030					record_btn.toggleClass('cff-record-btn-recording');
10031					if(record_btn.hasClass('cff-record-btn-recording'))
10032					{
10033						var i = 0;
10034						chunks = [];
10035						recording_flag = true;
10036						if(me._is_video() && media_ctrl.length) media_ctrl.removeClass('hide-strong');
10037
10038						navigator.mediaDevices.getUserMedia(
10039							settings
10040						)
10041						.then(function(localMediaStream)
10042						{
10043								streamRecorder = new MediaRecorder(localMediaStream);
10044								streamRecorder.ondataavailable = function(evt) {chunks.push(evt.data);};
10045								streamRecorder.start();
10046
10047								if(me._is_video() && media_ctrl.length)
10048								{
10049									media_ctrl[0].srcObject = localMediaStream;
10050									media_ctrl[0].play();
10051								}
10052
10053								interval = setInterval(function(){
10054									i++;
10055									if(i < me.max_time) record_time.text(me._format_time_component(i));
10056									else{
10057										clearInterval(interval);
10058										if(me.beep){
10059											var snd = new Audio("data:audio/wav;base64,//uQRAAAAWMSLwUIYAAsYkXgoQwAEaYLWfkWgAI0wWs/ItAAAGDgYtAgAyN+QWaAAihwMWm4G8QQRDiMcCBcH3Cc+CDv/7xA4Tvh9Rz/y8QADBwMWgQAZG/ILNAARQ4GLTcDeIIIhxGOBAuD7hOfBB3/94gcJ3w+o5/5eIAIAAAVwWgQAVQ2ORaIQwEMAJiDg95G4nQL7mQVWI6GwRcfsZAcsKkJvxgxEjzFUgfHoSQ9Qq7KNwqHwuB13MA4a1q/DmBrHgPcmjiGoh//EwC5nGPEmS4RcfkVKOhJf+WOgoxJclFz3kgn//dBA+ya1GhurNn8zb//9NNutNuhz31f////9vt///z+IdAEAAAK4LQIAKobHItEIYCGAExBwe8jcToF9zIKrEdDYIuP2MgOWFSE34wYiR5iqQPj0JIeoVdlG4VD4XA67mAcNa1fhzA1jwHuTRxDUQ//iYBczjHiTJcIuPyKlHQkv/LHQUYkuSi57yQT//uggfZNajQ3Vmz+Zt//+mm3Wm3Q576v////+32///5/EOgAAADVghQAAAAA//uQZAUAB1WI0PZugAAAAAoQwAAAEk3nRd2qAAAAACiDgAAAAAAABCqEEQRLCgwpBGMlJkIz8jKhGvj4k6jzRnqasNKIeoh5gI7BJaC1A1AoNBjJgbyApVS4IDlZgDU5WUAxEKDNmmALHzZp0Fkz1FMTmGFl1FMEyodIavcCAUHDWrKAIA4aa2oCgILEBupZgHvAhEBcZ6joQBxS76AgccrFlczBvKLC0QI2cBoCFvfTDAo7eoOQInqDPBtvrDEZBNYN5xwNwxQRfw8ZQ5wQVLvO8OYU+mHvFLlDh05Mdg7BT6YrRPpCBznMB2r//xKJjyyOh+cImr2/4doscwD6neZjuZR4AgAABYAAAABy1xcdQtxYBYYZdifkUDgzzXaXn98Z0oi9ILU5mBjFANmRwlVJ3/6jYDAmxaiDG3/6xjQQCCKkRb/6kg/wW+kSJ5//rLobkLSiKmqP/0ikJuDaSaSf/6JiLYLEYnW/+kXg1WRVJL/9EmQ1YZIsv/6Qzwy5qk7/+tEU0nkls3/zIUMPKNX/6yZLf+kFgAfgGyLFAUwY//uQZAUABcd5UiNPVXAAAApAAAAAE0VZQKw9ISAAACgAAAAAVQIygIElVrFkBS+Jhi+EAuu
10059+lKAkYUEIsmEAEoMeDmCETMvfSHTGkF5RWH7kz/ESHWPAq/kcCRhqBtMdokPdM7vil7RG98A2sc7zO6ZvTdM7pmOUAZTnJW+NXxqmd41dqJ6mLTXxrPpnV8avaIf5SvL7pndPvPpndJR9Kuu8fePvuiuhorgWjp7Mf/PRjxcFCPDkW31srioCExivv9lcwKEaHsf/7ow2Fl1T/9RkXgEhYElAoCLFtMArxwivDJJ+bR1HTKJdlEoTELCIqgEwVGSQ+hIm0NbK8WXcTEI0UPoa2NbG4y2K00JEWbZavJXkYaqo9CRHS55FcZTjKEk3NKoCYUnSQ0rWxrZbFKbKIhOKPZe1cJKzZSaQrIyULHDZmV5K4xySsDRKWOruanGtjLJXFEmwaIbDLX0hIPBUQPVFVkQkDoUNfSoDgQGKPekoxeGzA4DUvnn4bxzcZrtJyipKfPNy5w+9lnXwgqsiyHNeSVpemw4bWb9psYeq//uQZBoABQt4yMVxYAIAAAkQoAAAHvYpL5m6AAgAACXDAAAAD59jblTirQe9upFsmZbpMudy7Lz1X1DYsxOOSWpfPqNX2WqktK0DMvuGwlbNj44TleLPQ+Gsfb+GOWOKJoIrWb3cIMeeON6lz2umTqMXV8Mj30yWPpjoSa9ujK8SyeJP5y5mOW1D6hvLepeveEAEDo0mgCRClOEgANv3B9a6fikgUSu/DmAMATrGx7nng5p5iimPNZsfQLYB2sDLIkzRKZOHGAaUyDcpFBSLG9MCQALgAIgQs2YunOszLSAyQYPVC2YdGGeHD2dTdJk1pAHGAWDjnkcLKFymS3RQZTInzySoBwMG0QueC3gMsCEYxUqlrcxK6k1LQQcsmyYeQPdC2YfuGPASCBkcVMQQqpVJshui1tkXQJQV0OXGAZMXSOEEBRirXbVRQW7ugq7IM7rPWSZyDlM3IuNEkxzCOJ0ny2ThNkyRai1b6ev//3dzNGzNb//4uAvHT5sURcZCFcuKLhOFs8mLAAEAt4UWAAIABAAAAAB4qbHo0tIjVkUU//uQZAwABfSFz3ZqQAAAAAngwAAAE1HjMp2qAAAAACZDgAAAD5UkTE1UgZEUExqYynN1qZvqIOREEFmBcJQkwdxiFtw0qEOkGYfRDifBui9MQg4QAHAqWtAWHoCxu1Yf4VfWLPIM2mHDFsbQEVGwyqQoQcwnfHeIkNt9YnkiaS1oizycqJrx4KOQjahZxWbcZgztj2c49nKmkId44S71j0c8eV9yDK6uPRzx5X18eDvjvQ6yKo9ZSS6l//8elePK/Lf//IInrOF/FvDoADYAGBMGb7FtErm5MXMlmPAJQVgWta7Zx2go+8xJ0UiCb8LHHdftWyLJE0QIAIsI+UbXu67dZMjmgDGCGl1H+vpF4NSDckSIkk7Vd+sxEhBQMRU8j/12UIRhzSaUdQ+rQU5kGeFxm+hb1oh6pWWmv3uvmReDl0UnvtapVaIzo1jZbf/pD6ElLqSX+rUmOQNpJFa/r+sa4e/pBlAABoAAAAA3CUgShLdGIxsY7AUABPRrgCABdDuQ5GC7DqPQCgbbJUAoRSUj+NIEig0YfyWUho1VBBBA//uQZB4ABZx5zfMakeAAAAmwAAAAF5F3P0w9GtAAACfAAAAAwLhMDmAYWMgVEG1U0FIGCBgXBXAtfMH10000EEEEEECUBYln03TTTdNBDZopopYvrTTdNa325mImNg3TTPV9q3pmY0xoO6bv3r00y+IDGid/9aaaZTGMuj9mpu9Mpio1dXrr5HERTZSmqU36A3CumzN/9Robv/Xx4v9ijkSRSNLQhAWumap82WRSBUqXStV/YcS+XVLnSS+WLDroqArFkMEsAS+eWmrUzrO0oEmE40RlMZ5+ODIkAyKAGUwZ3mVKmcamcJnMW26MRPgUw6j+LkhyHGVGYjSUUKNpuJUQoOIAyDvEyG8S5yfK6dhZc0Tx1KI/gviKL6qvvFs1+bWtaz58uUNnryq6kt5RzOCkPWlVqVX2a/EEBUdU1KrXLf40GoiiFXK///qpoiDXrOgqDR38JB0bw7SoL+ZB9o1RCkQjQ2CBYZKd/+VJxZRRZlqSkKiws0WFxUyCwsKiMy7hUVFhIaCrNQsKkTIsLivwKKigsj8XYlwt/WKi2N4d//uQRCSAAjURNIHpMZBGYiaQPSYyAAABLAAAAAAAACWAAAAApUF/Mg+0aohSIRobBAsMlO//Kk4soosy1JSFRYWaLC4qZBYWFRGZdwqKiwkNBVmoWFSJkWFxX4FFRQWR+LsS4W/rFRb/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////VEFHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAU291bmRib3kuZGUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMjAwNGh0dHA6Ly93d3cuc291bmRib3kuZGUAAAAAAAAAACU=");
10060											snd.play();
10061									   }
10062									   _stopRecording();
10063									}
10064								}, 1000);
10065							})
10066						.catch(function(err)
10067						{
10068							$('.'+me.name+' .dfield').html('<div class="cff-record-error">'+cff_sanitize(err.name, true)+'</div>');
10069						});
10070					}
10071					else
10072					{
10073						_stopRecording();
10074					}
10075				});
10076				play_btn.on( 'click', function(){
10077					if(_load_file())
10078					{
10079						play_btn.toggleClass('cff-record-stop-btn');
10080						if(play_btn.hasClass('cff-record-stop-btn')) media_ctrl[0].play();
10081						else media_ctrl[0].pause();
10082					}
10083				});
10084			}
10085		}
10086	);	$.fbuilder.controls['fButton']=function(){};
10087	$.extend(
10088		$.fbuilder.controls['fButton'].prototype,
10089		$.fbuilder.controls['ffields'].prototype,
10090		{
10091			ftype:"fButton",
10092            sType:"button",
10093            sValue:"button",
10094			sLoading:false,
10095            sMultipage:false,
10096			sOnclick:"",
10097            sOnmousedown:"",
10098			userhelp:"A description of the section goes here.",
10099			init:function(){
10100					this.getCSSComponent('button', true, '#fbuilder #'+this.name, this.form_identifier);
10101					this.getCSSComponent('button_hover', true, '#fbuilder #'+this.name+':hover', this.form_identifier);
10102			},
10103			show:function()
10104				{
10105                    var esc  = cff_esc_attr,
10106                        type = this.sType,
10107                        clss = '';
10108
10109                    if(this.sType == 'calculate')
10110                    {
10111                        type = 'button';
10112                        clss = 'calculate-button';
10113                    }
10114					if(this.sType == 'print')
10115                    {
10116                        type = 'button';
10117                    }
10118					else if(this.sType == 'reset')
10119					{
10120						clss = 'reset-button';
10121					}
10122
10123                    return '<div class="fields '+esc(this.csslayout)+' '+this.name+' cff-button-field" id="field'+this.form_identifier+'-'+this.index+'" style="'+esc(this.getCSSComponent('container'))+'"><input id="'+this.name+'" type="'+type+'" value="'+esc(this.sValue)+'" class="field '+clss+'" /><span class="uh" style="'+cff_esc_attr(this.getCSSComponent('help'))+'">'+cff_sanitize(this.userhelp, true)+'</span><div class="clearer"></div></div>';
10124				},
10125            after_show:function()
10126                {
10127					var me = this;
10128					$('#'+this.name).on( 'mousedown', function(){
10129						try {
10130							if ($.fbuilder['isEvalBlocked']()) throw new EvalError("*");
10131							eval(me.sOnmousedown);
10132						} catch ( err ) {
10133							try {
10134								if ( err instanceof EvalError ) $.fbuilder['eval'].call(this, me.sOnmousedown);
10135								else throw err;
10136							} catch ( err2 ) {
10137								console.log(err2.message);
10138							}
10139						}
10140					});
10141					$('#'+this.name).on( 'click',
10142                        function()
10143                            {
10144                                var e = $(this), f = e.closest('form'), fid = me.form_identifier;
10145                                if( me.sType == 'calculate' )
10146                                {
10147									let aux = function(){
10148										var items = $.fbuilder['forms'][fid].getItems();
10149										$(document).on('equationsQueueEmpty', function(evt, id){
10150											if(id == fid)
10151											{
10152												if(me.sLoading) f.find('.cff-processing-form').remove();
10153												$(document).off('equationsQueueEmpty');
10154												for(var i = 0, h = items.length; i < h; i++)
10155												{
10156													if(items[i].ftype == 'fsummary')
10157													{
10158														items[i].update();
10159													}
10160												}
10161											}
10162										});
10163
10164										$.fbuilder['calculator'].defaultCalc('#'+e.closest('form').attr('id'), false, true);
10165									};
10166									if(me.sLoading)
10167									{
10168										f.find('.cff-processing-form').remove();
10169										$('<div class="cff-processing-form"></div>').prependTo(e.closest('#fbuilder'));
10170										setTimeout( aux, 50 );
10171									} else {
10172										aux();
10173									}
10174                                }
10175
10176								if( me.sType == 'reset' ) {
10177									RESETFORM(e[0].form);
10178									setTimeout(function(){
10179										try {
10180											if ($.fbuilder['isEvalBlocked']()) throw new EvalError("*");
10181											eval(me.sOnclick);
10182										} catch ( err ) {
10183											try {
10184												if ( err instanceof EvalError ) $.fbuilder['eval'].call(this, me.sOnclick);
10185												else throw err;
10186											} catch ( err2 ) {
10187												console.log(err2.message);
10188											}
10189										}
10190									}, 55);
10191								} else {
10192									try {
10193										if ($.fbuilder['isEvalBlocked']()) throw new EvalError("*");
10194										eval(me.sOnclick);
10195									} catch ( err ) {
10196										try {
10197											if ( err instanceof EvalError ) $.fbuilder['eval'].call(this, me.sOnclick);
10198											else throw err;
10199										} catch ( err2 ) {
10200											console.log(err2.message);
10201										}
10202									}
10203								}
10204
10205								if(me.sType == 'print')
10206								{
10207									fbuilderjQuery.fbuilder.currentFormId = f.attr('id');
10208									PRINTFORM(me.sMultipage);
10209								}
10210                            }
10211                  );
10212                }
10213		}
10214	);	$.fbuilder.controls['fhtml']=function(){};
10215	$.extend(
10216		$.fbuilder.controls['fhtml'].prototype,
10217		$.fbuilder.controls['ffields'].prototype,
10218		{
10219			ftype:"fhtml",
10220			fcontent:"",
10221			allowscript:-1,
10222			replaceShortcodes:0,
10223			show:function()
10224				{
10225					var me = this,
10226						content = me.fcontent;
10227
10228					if ( me.replaceShortcodes ) {
10229						$( document ).on('formReady', function(evt, form_identifier){
10230							if ( form_identifier == 'cp_calculatedfieldsf_pform' + me.form_identifier ) {
10231								$( 'template[id*="cff-embedded-shortcode"]', '[id="' + me.name + '"]' ).each( function(){
10232									let id = this.id;
10233									$(this).after('<div id="'+id+'"></div>');
10234									$('div[id="'+id+'"]').html(this.innerHTML);
10235									$(this).remove();
10236								});
10237							}
10238						});
10239					}
10240
10241					content = content
10242							.replace(/\(\s*document\s*\)\.one\(\s*['"]showHideDepEvent['"]/ig,
10243								'(window).one("showHideDepEvent"')
10244							.replace(/\bcurrentFormId\b/ig,
10245								'cp_calculatedfieldsf_pform' + me.form_identifier);
10246
10247					content = (
10248						( me.allowscript == -1 || me.allowscript ) ?
10249						content :
10250						(
10251							me.replaceShortcodes  ?
10252							cff_sanitize( content.replace( /<template\s/ig, '<x-template ').replace( /<\/template\s/ig, '</x-template '), true, true ).replace( /<x\-template\s/ig, '<template ').replace( /<\/x\-template>/ig, '</template>'):
10253							cff_sanitize( content, true )
10254						)
10255					);
10256
10257					return '<div class="fields '+cff_esc_attr(me.csslayout)+' '+me.name+' cff-html-field" id="field'+me.form_identifier+'-'+me.index+'" style="'+cff_esc_attr(me.getCSSComponent('container'))+'"><div id="'+me.name+'" class="dfield">'+content+'</div><div class="clearer"></div></div>';
10258				}
10259		}
10260	);	$.fbuilder.controls['facceptance']=function(){};
10261	$.extend(
10262		$.fbuilder.controls['facceptance'].prototype,
10263		$.fbuilder.controls['ffields'].prototype,
10264		{
10265			title:"Accept terms and conditions",
10266			ftype:"facceptance",
10267			value:"I accept",
10268			required:true,
10269            onoff:0,
10270			url:"",
10271			message:"",
10272			show:function()
10273				{
10274					var me = this,
10275						dlg = '',
10276						label = cff_html_decode(me.title);
10277
10278					if(!/^\s*$/.test(me.url))
10279					{
10280						label = '<a href="'+cff_esc_attr(String(me.url).trim())+'" target="_blank" style="'+cff_esc_attr(me.getCSSComponent('choice'))+'">'+label+'</a>';
10281					}
10282					else if(!/^\s*$/.test(me.message))
10283					{
10284						label = '<a href="javascript:void(0);" class="cff-open-dlg" style="'+cff_esc_attr(me.getCSSComponent('choice'))+'">'+label+'</a>';
10285						dlg += '<div class="cff-dialog hide"><span class="cff-close-dlg"></span><div class="cff-dialog-content" style="'+cff_esc_attr(me.getCSSComponent('text'))+'">'+cff_sanitize(me.message, true)+'</div></div>'
10286					}
10287					return '<div class="fields '+cff_esc_attr(me.csslayout)+(me.onoff ? ' cff-switch-container' : '')+' '+me.name+' cff-checkbox-field" id="field'+me.form_identifier+'-'+me.index+'" style="'+cff_esc_attr(me.getCSSComponent('container'))+'"><div class="dfield">'+
10288					'<div class="one_column"><label for="'+me.name+'"><input aria-label="'+cff_esc_attr(me.title)+'" name="'+me.name+'" id="'+me.name+'" class="field required" value="'+cff_esc_attr(me.value)+'" vt="'+cff_esc_attr((/^\s*$/.test(me.value)) ? me.title : me.value)+'" type="checkbox" /> '+
10289                    (me.onoff ? '<span class="cff-switch"></span>': '') +
10290                    '<span>'+
10291					label+''+((me.required)?'<span class="r">*</span>':'')+
10292					'</span></label></div>'+dlg+'<span class="uh"></span></div><div class="clearer"></div></div>';
10293				},
10294			after_show:function()
10295				{
10296					$(document).on('click','.cff-open-dlg', function(){
10297						var dlg = $(this).closest('.fields').find('.cff-dialog'), w = dlg.data('width'), h=dlg.data('height');
10298						dlg.removeClass('hide');
10299
10300						if('undefined' == typeof w) w = MIN($(this).closest('form').width(), $(window).width(), dlg.width());
10301						if('undefined' == typeof h) h = MIN($(this).closest('form').height(), $(window).height(), dlg.height());
10302
10303						dlg.data('width',w);
10304						dlg.data('height',h);
10305
10306						dlg.css({'width': w+'px', 'height': h+'px', 'margin-top': (-1*h/2)+'px', 'margin-left': (-1*w/2)+'px'});
10307					});
10308					$(document).on('click','.cff-close-dlg', function(){$(this).closest('.cff-dialog').addClass('hide');});
10309				},
10310			val:function(raw, no_quotes, disable_ignore_check)
10311				{
10312					raw = raw || false;
10313                    no_quotes = no_quotes || false;
10314					var e = (disable_ignore_check) ? $('[id="'+this.name+'"]:checked') : $('[id="'+this.name+'"]:checked:not(.ignore)');
10315					if(e.length)
10316					{
10317						var t = $.fbuilder.parseValStr(e[0].value, raw, no_quotes);
10318						if(!$.fbuilder.isNumeric(t)) t = t.replace(/^"/,'').replace(/"$/,'');
10319					}
10320					return (t) ? (($.fbuilder.isNumeric(t) && !no_quotes) ? t : '"'+t+'"') : 0;
10321				}
10322		}
10323	);	$.fbuilder.controls[ 'fqrcode' ]=function(){};
10324	$.extend(
10325		$.fbuilder.controls[ 'fqrcode' ].prototype,
10326		$.fbuilder.controls[ 'ffields' ].prototype,
10327		{
10328			title:"",
10329			ftype:"fqrcode",
10330			predefined:"",
10331			required:false,
10332			readonly:false,
10333			size:"medium",
10334			show:function()
10335				{
10336					this.predefined = this._getAttr('predefined', true);
10337					return '<div class="fields '+cff_esc_attr(this.csslayout)+' '+this.name+' cff-qrcode-field" id="field'+this.form_identifier+'-'+this.index+'" style="'+cff_esc_attr(this.getCSSComponent('container'))+'"><label for="'+this.name+'" style="'+cff_esc_attr(this.getCSSComponent('label'))+'">'+cff_sanitize(this.title, true)+''+((this.required)?"<span class='r'>*</span>":"")+'</label><div class="dfield">'+
10338					'<div id="'+this.name+'_qrcontainer" class="'+cff_esc_attr(this.size)+' cff-qrcode-container"></div>'+
10339					'<input aria-label="'+cff_esc_attr(this.title)+'" id="'+this.name+'" name="'+this.name+'"'+' class="field '+cff_esc_attr(this.size)+((this.required)?" required":"")+'" '+' '+((this.readonly)?'readonly':'')+' type="text" value="'+cff_esc_attr(this.predefined)+'" style="'+cff_esc_attr(this.getCSSComponent('input'))+'" /><span class="uh" style="'+cff_esc_attr(this.getCSSComponent('help'))+'">'+cff_sanitize(this.userhelp, true)+'</span></div><div class="clearer"></div></div>';
10340				},
10341			after_show:function()
10342				{
10343					var me = this;
10344					$('#'+me.name).on(
10345						'focus',
10346						function(){
10347							var qrc = $('#fbuilder .cff-qrcode-container[id="'+me.name+'_qrcontainer"]');
10348							$('#fbuilder .cff-qrcode-container[id!="'+me.name+'_qrcontainer"]').html('');
10349							if (
10350								typeof Html5QrcodeScanner != 'undefined' &&
10351								qrc.html() == ''
10352							) {
10353								( new Html5QrcodeScanner( me.name+'_qrcontainer', { fps: 10 }, false ) ).render(
10354									function(decodedText, decodedResult){me.setVal(decodedText);$('#html5-qrcode-button-camera-stop').trigger('click');},
10355									function(error){console.warn(`Code scan error = ${error}`);}
10356								);
10357								qrc.prepend('<span class="cff-qrcode-field-close" onclick="fbuilderjQuery(this).parent().html(\'\')">&times;</span>');
10358							}
10359						}
10360					);
10361
10362				},
10363			val:function(raw, no_quotes, disable_ignore_check)
10364				{
10365					raw = true;
10366                    no_quotes = no_quotes || false;
10367					var e = (disable_ignore_check) ? $('[id="'+this.name+'"]') : $('[id="'+this.name+'"]:not(.ignore)');
10368					if(e.length) return $.fbuilder.parseValStr(e.val(), raw, no_quotes);
10369					return '';
10370				}
10371		}
10372	);	$.fbuilder.controls['fpopup']=function(){};
10373	$.extend(
10374		$.fbuilder.controls['fpopup'].prototype,
10375		$.fbuilder.controls['ffields'].prototype,
10376		{
10377			title:"",
10378			titletag:"P",
10379			ftype:"fpopup",
10380			fields:[],
10381			open_onload:false,
10382			open_onclick:'',
10383			close_button:true,
10384			modal:true,
10385			dragging:false,
10386			resizing:false,
10387			position:'center', // center, top-left, top-right, bottom-left, bottom-right
10388			width:'360px',
10389			height:'360px',
10390			columns:1,
10391			align:"top",
10392			rearrange: 0,
10393			show:function()
10394				{
10395				let w = String(this.width).replace(/[^\d,p,x,\%,\.]/g, ''),
10396					h = String(this.height).replace(/[^\d,p,x,\%,\.]/g, ''),
10397					p = '';
10398
10399				w = 'width:'+(w.length ? w : '90%')+';max-width:90%;'+
10400					'min-width:'+(w.length ? w : '90%')+';';
10401				h = (h.length ? 'min-height:'+h+';height:'+h+';' : '')+'max-height:90%;';
10402
10403				switch ( this.position ) {
10404					case 'center':
10405						p = 'top:50%;left:50%;transform:translate(-50%,-50%);';
10406					break;
10407					case 'top-left':
10408						p = 'top:20px;left:20px;';
10409					break;
10410					case 'top-right':
10411						p = 'top:20px;right:20px;';
10412					break;
10413					case 'bottom-left':
10414						p = 'bottom:20px;left:20px;';
10415					break;
10416					case 'bottom-right':
10417						p = 'bottom:20px;right:20px;';
10418					break;
10419				}
10420				return '<div class="fields '+cff_esc_attr(this.csslayout)+' '+this.name+(this.open_onload ? '' : ' hide-strong ')+' cff-popup-field cff-container-field '+'" id="field'+this.form_identifier+'-'+this.index+'" style="'+cff_esc_attr(this.getCSSComponent('container'))+'">'+
10421				( this.modal ? '<div class="cff-popup-modal">' : '' )+
10422					'<div class="cff-popup-container" style="' + w + h + p + (this.resizing ? 'overflow:auto;resize:both;' : '')+cff_esc_attr(this.getCSSComponent('content'))+'">'+
10423					'<div class="cff-popup-header"  style="'+cff_esc_attr(this.getCSSComponent('header'))+'"><'+this.titletag+' class="cff-popup-title" style="'+cff_esc_attr(this.getCSSComponent('label'))+'">'+cff_sanitize(this.title, true)+(this.close_button ? '</'+this.titletag+'><div class="cff-popup-close ui-icon ui-icon-close" title="close" style="'+cff_esc_attr(this.getCSSComponent('close'))+'"></div>' : '')+'</div>'+
10424					'<div id="'+this.name+'" class="cff-popup-fields '+ ( this.align == 'bottom' ? 'cff-align-container-bottom' : '' ) +'"></div>'+
10425					'<div class="clearer"></div>'+
10426				'</div>'+
10427				( this.modal ? '</div>' : '' )+
10428				'</div>';
10429				},
10430			after_show: function()
10431				{
10432					let me = this,
10433						pos1 = 0,
10434						pos2 = 0,
10435						pos3 = 0,
10436						pos4 = 0,
10437						e = $( '.' + me.name + ' .cff-popup-container' );
10438
10439					function dragMouseDown(evt) {
10440						evt.preventDefault();
10441						pos3 = evt.clientX;
10442						pos4 = evt.clientY;
10443						$( document ).on( 'mouseup', closeDragElement );
10444						$( document ).on( 'mousemove', elementDrag );
10445					}
10446
10447					function elementDrag(evt) {
10448						evt.preventDefault();
10449						// calculate the new cursor position:
10450						pos1 = pos3 - evt.clientX;
10451						pos2 = pos4 - evt.clientY;
10452						pos3 = evt.clientX;
10453						pos4 = evt.clientY;
10454						// set the element's new position:
10455						let o = e.offset(),
10456							sV = document.documentElement.scrollTop || document.body.scrollTop,
10457							sH = document.documentElement.scrollLeft || document.body.scrollLeft;
10458
10459						e.offset({
10460							top: Math.min( Math.max( o.top-pos2, sV ), (document.documentElement.clientHeight || document.body.clientHeight)+sV - e.height() ),
10461							left: Math.min( Math.max( o.left-pos1, sH ), (document.documentElement.clientWidth || document.body.clientWidth)+sH - e.width() )
10462						});
10463					}
10464
10465					function closeDragElement() {
10466						/* stop moving when mouse button is released:*/
10467						$( document ).off( 'mouseup' );
10468						$( document ).off( 'mousemove' );
10469					}
10470
10471					$.fbuilder.controls['fcontainer'].prototype.after_show.call(this);
10472					$(document).on('click', '.cff-popup-close', function() {
10473						$(this).closest('.cff-popup-field').addClass('hide-strong');
10474					});
10475
10476					if ( ! /^\s*$/.test( me.open_onclick ) ) {
10477						let btn = getField( me.open_onclick+me.form_identifier );
10478						if ( btn != false ) {
10479							$( document ).on( 'click', '#'+btn.jQueryRef().find( 'input' ).attr('id'), function(){
10480								SHOWFIELD(me.name);
10481							});
10482						}
10483					}
10484
10485					if ( me.close_button ) {
10486						$(document).on('keyup', function(evt){
10487							if ( 'Escape' == evt.key ) HIDEFIELD(me.name);
10488						});
10489					}
10490
10491					if ( me.dragging ) {
10492						e.find( '.cff-popup-header' ).css( 'cursor', 'move' ).on( 'mousedown', dragMouseDown );
10493					}
10494				},
10495			showHideDep:function(toShow, toHide, hiddenByContainer)
10496				{
10497					return $.fbuilder.controls['fcontainer'].prototype.showHideDep.call(this, toShow, toHide, hiddenByContainer);
10498				}
10499		}
10500	);	$.fbuilder.controls[ 'frepeater' ] = function(){};
10501	$.extend(
10502		$.fbuilder.controls[ 'frepeater' ].prototype,
10503		$.fbuilder.controls[ 'ffields' ].prototype,
10504		{
10505			ftype: "frepeater",
10506			fields: [],
10507			matrix: [],
10508			columns: 1,
10509			align: "top",
10510			rearrange: 0,
10511
10512			addButtonLabel: 'Add row',
10513			removeButtonLabel: 'Remove',
10514			maxRows: 100,
10515			n: 0,
10516
10517			_isPlainObject: function (v) {
10518				return Object.prototype.toString.call(v) === '[object Object]';
10519			},
10520
10521			_triggerChange: function() {
10522				$('[id="' + this.name + '"]').trigger('change');
10523			},
10524
10525			_addToMatrix: function(row) {
10526				this.matrix.push(row);
10527				$('[id="' + this.name + '"]').val(JSON.stringify(this.matrix));
10528				this._triggerChange();
10529			},
10530
10531			_removeFromMatrix: function(index) {
10532				if ( ! index || ! ( index in this.matrix ) ) return;
10533				let row = this.matrix.splice(index, 1)[0];
10534				$('[id="' + this.name + '"]').val(JSON.stringify(this.matrix));
10535				let formObj = $.fbuilder.forms[this.form_identifier];
10536				for (let i in row) {
10537					let field = getField(row[i], this.form_identifier);
10538					if (field) formObj.removeItem(field);
10539				}
10540				this._triggerChange();
10541			},
10542
10543			_add_row: function (includeRemoveButton) {
10544				includeRemoveButton = includeRemoveButton || false;
10545				let row = '' +
10546					'<div class="cff-repeater-row" style="' + cff_esc_attr(this.getCSSComponent('row')) + '">' +
10547						'<div class="cff-repeater-fields-container ' + (this.align == 'bottom' ? 'cff-align-container-bottom' : '') + '" style="' + cff_esc_attr(this.getCSSComponent('container')) + '"></div>' +
10548						'<div class="cff-repeater-row-controls">' +
10549						'<div class="fields">' +
10550						(
10551							includeRemoveButton
10552							? '<input type="button" class="cff-repeater-remove-row" value="' + cff_esc_attr(this.removeButtonLabel) + '" style="' + cff_esc_attr(this.getCSSComponent('remove_row_button')) + '" />'
10553							: ''
10554						) +
10555						'</div>' +
10556						'</div>' +
10557					'</div>';
10558				this.n++;
10559				return row;
10560			},
10561
10562			_add_to_row: function (e, l) {
10563				if (! l.length) return;
10564
10565				// Extract pairs of basic fields names.
10566				let names = {};
10567				for (let i in l) {
10568					names[l[i]['o'].name.match(/fieldname\d+/)[0]] = l[i]['c'].name.match(/fieldname\d+/)[0];
10569				}
10570
10571				function escapeRegExp(str) {
10572					return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
10573				}
10574
10575				// Replace fields names in the field attributes.
10576				function replaceFieldsNames(source) {
10577					if (typeof source === 'string') {
10578						for (let k in names) {
10579							if (source.indexOf(k) !== -1) {
10580								const pattern = new RegExp(escapeRegExp(k) + '(?!\\d)', 'g');
10581								source = source.replace(pattern, names[k]);
10582							}
10583						}
10584					} else if (source !== null && typeof source === 'object') {
10585						for (let k in source) {
10586							if (typeof source[k] !== 'function') {
10587								source[k] = replaceFieldsNames(source[k]);
10588							}
10589						}
10590					}
10591					return source;
10592				}
10593
10594				function deepCloneSafe(obj) {
10595					if (obj === null || typeof obj !== 'object') return obj;
10596
10597					if (typeof obj === 'function') return obj;
10598
10599					if (Array.isArray(obj)) {
10600						return obj.map(item => deepCloneSafe(item));
10601					}
10602
10603					const clone = {};
10604					for (const key of Object.keys(obj)) {
10605						clone[key] = deepCloneSafe(obj[key]);
10606					}
10607					return clone;
10608				}
10609
10610				function cloneFieldProperties(originalField, clonedField) {
10611					for (let k in originalField) {
10612						if (originalField.hasOwnProperty(k) && typeof originalField[k] !== 'function') {
10613							clonedField[k] = replaceFieldsNames(deepCloneSafe(originalField[k]));
10614						}
10615					}
10616					return clonedField;
10617				}
10618
10619				for (let i in l) {
10620					// First, clone the original field attributes.
10621					l[i]['c'] = cloneFieldProperties(l[i]['o'], l[i]['c']);
10622					$.fbuilder.forms[this.form_identifier].addItem(l[i]['c']);
10623				}
10624
10625				this._addToMatrix(names);
10626
10627				e = e.find('.cff-repeater-fields-container');
10628				let to_ignore = 0; // Ignores the RecordSet DS and Hidden fields.
10629				for (let i = 0, h = l.length; i < h; i++) {
10630					let flag = true;
10631					let f = l[i]['c'],
10632						d = $(f.show());
10633
10634					if (d.hasClass('cff-hidden-field')) { to_ignore++; }
10635					d.addClass('column' + this.columns);
10636					if (this.columns > 1) {
10637						if ((i - to_ignore) % this.columns == 0 && !this.rearrange) {
10638							d.css('clear', 'left');
10639							d.appendTo(e);
10640							if (i - to_ignore && this.align == "bottom") d.before('<div class="cff-row-breaker"></div>');
10641							flag = false;
10642						}
10643					}
10644					if (flag) d.appendTo(e);
10645					if ('init' in f) f.init();
10646					if ('after_show' in f) f.after_show();
10647				}
10648
10649				e.find('input.codepeoplecalculatedfield, select.depItemSel, input.depItem').each(function(){
10650					$(this).trigger('cff-dep-event');
10651				});
10652			},
10653
10654			init: function(){
10655				this.matrix = [];
10656				if (this.fields.length) {
10657					let row = {};
10658					for (let i in this.fields) {
10659						row[this.fields[i]] = this.fields[i];
10660					}
10661					this._addToMatrix(row);
10662				}
10663			},
10664
10665			show: function()
10666			{
10667				return '<div class="fields ' + cff_esc_attr(this.csslayout) + ' ' + this.name + ' cff-repeater-field cff-container-field" id="field' + this.form_identifier + '-' + this.index + '" style="' + cff_esc_attr(this.getCSSComponent('field')) + '">' +
10668					'<input type="hidden" name="' + this.name + '" id="' + this.name + '" value="' + cff_esc_attr(JSON.stringify(this.matrix))+'" />' +
10669					'<div id="' + this.name + '_fields" class="cff-repeater-rows-container">' +
10670					this._add_row() +
10671					'</div>' +
10672					'<div class="cff-repeater-controls">' +
10673					'<input id="' + this.name + '_add_button" type="button" class="cff-repeater-add-row" value="' + cff_esc_attr(this.addButtonLabel) + '" style="' + cff_esc_attr(this.getCSSComponent('add_row_button')) + (this.maxRows <= 1 ? 'display:none;' : '') + '" />' +
10674					'</div>' +
10675					'<div class="clearer"></div></div>';
10676			},
10677
10678			after_show: function( e )
10679			{
10680				let me = this;
10681				$.fbuilder.controls['fcontainer'].prototype.after_show.call(this, $('#' + this.name + '_fields .cff-repeater-fields-container'));
10682
10683				$('#' + this.name + '_add_button').off('click').on('click', function () {
10684					me.add_row();
10685				});
10686
10687				$('#' + this.name + '_fields').on('click', '.cff-repeater-remove-row', function () {
10688					let row = $(this).closest('.cff-repeater-row');
10689					if ( ! row.length ) return;
10690					let index = row.index();
10691					me.remove_row(index);
10692				});
10693
10694				// Each change on container field must be escalated to the repeater field.
10695				$(document).on('change', '#' + this.name + '_fields :input:not([name="' + this.name + '"])', function () {
10696					me._triggerChange();
10697				});
10698
10699				// Reset: reconcile matrix/objects/DOM to initial state.
10700				// Follows the same pattern as fsummary (16_fbuilder.fsummary.js:49).
10701				let form = me.jQueryRef().closest('form');
10702				if (form.length) {
10703					form.on('reset', function () {
10704						setTimeout(function () {
10705							// Remove all rows except the initial one (index 0).
10706							for (let i = me.matrix.length - 1; i >= 1; i--) {
10707								me.remove_row(i);
10708							}
10709							me._triggerChange();
10710							}, 10
10711						);
10712					});
10713				}
10714			},
10715
10716			val: function (raw, no_quotes, disable_ignore_check) {
10717				let rows = [],
10718					total_row = {};
10719				no_quotes = (typeof no_quotes === 'undefined') ? true : no_quotes;
10720				if( $('[id="' + this.name + '"]').is(".ignorefield,.ignore") ) return false;
10721				for (let i in this.matrix) {
10722					rows[i] = {};
10723					for (let j in this.matrix[i]) {
10724						let f = getField(this.matrix[i][j], this.form_identifier);
10725						if (f) {
10726							let n = String(j).replace(/[^\d]/g, ''),
10727								v = f.val(raw, no_quotes, disable_ignore_check),
10728								p = f.val(0, 1, 0);
10729
10730							rows[i][j] = v;
10731							rows[i][n] = rows[i][j];
10732							if( ! ( j in total_row ) ) {
10733								total_row[j] = 0;
10734							}
10735							total_row[j] = SUM(total_row[j], p);
10736							total_row[n] = total_row[j];
10737						}
10738					}
10739				}
10740				return {
10741					rows: rows,
10742					total: total_row
10743				};
10744			},
10745
10746			setVal: function (v, nochange, _default) {
10747				_default = _default || false;
10748				nochange = nochange || false;
10749				if (typeof v === 'string') {
10750					try { v = JSON.parse(v); } catch (e) { return; }
10751				}
10752				if(! Array.isArray(v)) return;
10753				for (let i in v) {
10754					if (0 < this.maxRows && this.maxRows <= i) break;
10755					if (! this._isPlainObject(v[i])) continue;
10756					if (! (i in this.matrix)) this.add_row();
10757					for (let j in v[i]) {
10758						if (! (j in this.matrix[i])) continue;
10759						let f = getField(this.matrix[i][j], this.form_identifier);
10760						if (f) f.setVal(v[i][j], nochange, _default);
10761					}
10762				}
10763
10764				// Shrink: if v is shorter than current matrix, remove surplus rows
10765				// from end to start (avoids index shifting issues).
10766				if (v.length < this.matrix.length) {
10767					for (let i = this.matrix.length - 1, h = v.length; i >= h; i--) {
10768						this.remove_row(i);
10769					}
10770				}
10771
10772			},
10773
10774			showHideDep: function (toShow, toHide, hiddenByContainer, interval) {
10775				if (typeof hiddenByContainer == 'undefined') hiddenByContainer = {};
10776				var me = this,
10777					isHidden = (typeof toHide[me.name] != 'undefined' || typeof hiddenByContainer[me.name] != 'undefined'),
10778					fId,
10779					result = [];
10780
10781				for (let i in me.matrix) {
10782					if ( ! me._isPlainObject(me.matrix[i]) ) continue;
10783					for (let j in me.matrix[i]) {
10784						fId = me.matrix[i][j] + me.form_identifier;
10785						if (!/fieldname/i.test(fId)) continue;
10786						if (isHidden) {
10787							if (typeof hiddenByContainer[fId] == 'undefined') hiddenByContainer[fId] = {};
10788							if (typeof hiddenByContainer[fId][me.name] == 'undefined') {
10789								hiddenByContainer[fId][me.name] = {};
10790
10791								if (typeof toHide[fId] == 'undefined') {
10792									$('.' + fId + ' [id*="' + fId + '"],.' + fId).closest('.fields').addClass('ignorefield').hide();
10793									$('.' + fId + ' [id*="' + fId + '"]:not(.ignore)').addClass('ignore').trigger('add-ignore');
10794									result.push(fId);
10795								}
10796							}
10797						}
10798						else {
10799							if (typeof hiddenByContainer[fId] != 'undefined') {
10800								delete hiddenByContainer[fId][me.name];
10801								if ($.isEmptyObject(hiddenByContainer[fId])) {
10802									delete hiddenByContainer[fId];
10803									if (typeof toHide[fId] == 'undefined') {
10804										$('.' + fId + ' [id*="' + fId + '"],.' + fId).closest('.fields').removeClass('ignorefield').fadeIn(interval || 0);
10805										$('.' + fId + ' [id*="' + fId + '"].ignore').removeClass('ignore').trigger('remove-ignore');
10806										result.push(fId);
10807									}
10808								}
10809							}
10810						}
10811					}
10812				}
10813				return result;
10814			},
10815
10816			add_row: function() {
10817				let me = this;
10818				if (me.maxRows <= 0 || me.n < me.maxRows) {
10819					// Cloning fields objects.
10820					let formObj = $.fbuilder.forms[me.form_identifier],
10821						getNumber = (n) => parseInt(String(n).match(/\d+$/), 10),
10822						newFieldNumber = formObj.getItemsNames().reduce((a, b) => {
10823							a = getNumber(a);
10824							b = getNumber(b);
10825							return a > b ? a : b;
10826						}, 0) + 1;
10827
10828					let newFields = [],
10829						newRow = $(me._add_row(true));
10830
10831					newRow.appendTo('#' + me.name + '_fields');
10832
10833					for (let i in me.fields) {
10834						let originalField = formObj.getItem(me.fields[i]);
10835						if (originalField && originalField.ftype in $.fbuilder.controls) {
10836							// Cloning field object.
10837							let clonedField = new $.fbuilder.controls[originalField.ftype]();
10838							// New field name.
10839							let newFieldName = 'fieldname' + newFieldNumber + me.form_identifier;
10840							clonedField.name = newFieldName;
10841							newFields.push({ o: originalField, c: clonedField });
10842							newFieldNumber++;
10843						}
10844					}
10845					me._add_to_row(newRow, newFields);
10846				}
10847				if (me.maxRows > 0 && me.n >= me.maxRows) {
10848					$('#' + me.name + '_add_button').hide();
10849				}
10850			},
10851
10852			remove_row: function (index) {
10853				if (index == 0) return;
10854
10855				let me = this,
10856					row = $('#'+me.name+'_fields .cff-repeater-row').eq(index);
10857
10858				if (row.length) row.remove();
10859				me._removeFromMatrix(index);
10860				me.n--;
10861				if (me.n < me.maxRows) {
10862					$('#' + me.name + '_add_button').show();
10863				}
10864			}
10865		}
10866	);$(document).on('formReady', function( evt, form_identifier ) {
10867	try {
10868		if (
10869			! $( '[data-assistant]', '#'+form_identifier ).length ||
10870			typeof cff_ai_assistant_loaded != 'undefined'
10871		) return;
10872		cff_ai_assistant_loaded = true;
10873		let seq			= $('[name="cp_calculatedfieldsf_pform_psequence"]', '#'+form_identifier ).val();
10874		let bubble 		= $('<div id="cff_ai_assistant_bubble"></div>');
10875		let close		= $('<div id="cff_ai_assistant_bubble_close">&times;</div>');
10876		let suggestionText = $('<div id="cff_ai_assistant_suggestion_text"></div>');
10877		let useButton 	= $('<button id="cff_ai_assistant_use_suggestion" aria-label="Use suggestion"></button>');
10878
10879		let button_text = $.fbuilder.forms[seq]?.settings?.messages?.ai_assistant_button ?? 'Apply suggestion';
10880		let generating_text = $.fbuilder.forms[seq]?.settings?.messages?.ai_assistant_generating ?? 'Apply suggestion';
10881
10882		useButton.text( button_text );
10883
10884		bubble.append(close).append( suggestionText ).append( useButton );
10885		bubble.appendTo('body');
10886
10887		let typingTimer;
10888		let target;
10889		let suggestionsList = {};
10890
10891
10892		const doneTypingInterval = 2000; // 2 inactive seconds
10893
10894		function attachListeners() {
10895			function triggerGenerateSuggestion() {
10896				if (target) generateSuggestion( target.val() );
10897			}
10898			$(document).on( 'input', '[data-assistant]', function() {
10899				target = $(this);
10900				clearTimeout(typingTimer);
10901				typingTimer = setTimeout(
10902					function() { triggerGenerateSuggestion(); },
10903					doneTypingInterval
10904				);
10905			});
10906
10907			$(document).on( 'blur', '[data-assistant]', function() {
10908				target = $(this);
10909				clearTimeout(typingTimer);
10910				triggerGenerateSuggestion();
10911			});
10912
10913			close.on( 'click', function(){
10914				target = null;
10915				bubble.hide();
10916			});
10917
10918			useButton.on( 'click', function() {
10919			  if(target) target.val(suggestionText.text());
10920			  bubble.hide();
10921			});
10922
10923			$(document).on( 'focus', ':input:not(#cff_ai_assistant_use_suggestion)', function() {
10924				target = null;
10925				bubble.hide();
10926			});
10927
10928			let e = $(':focus');
10929			if ( e.attr('data-assistant') != undefined ) {
10930				target = e;
10931				triggerGenerateSuggestion();
10932			}
10933		};
10934
10935        let activeModel = null;
10936		let session = null;
10937
10938		async function generateSuggestion(text) {
10939			if (!text || text.trim().length < 5) {
10940				bubble.hide();
10941				return;
10942			}
10943
10944			function showSuggestion(newText, noBtn) {
10945				noBtn = noBtn || false;
10946				suggestionText.text(newText);
10947				useButton.css('display', noBtn ? 'none' : 'block');
10948				bubble.show();
10949			};
10950
10951			if ( text in suggestionsList ) {
10952				showSuggestion(suggestionsList[text]);
10953				return;
10954			}
10955
10956			showSuggestion(generating_text, true);
10957
10958			try {
10959				const prompt = `Please improve the following text to make it clearer and more appealing. Respond only with the improved version of the original text, with no commentary, quotes, or headers:\n"${text}"`;
10960
10961                let suggestion = await makeInference(prompt);
10962
10963				if (suggestion) {
10964					suggestion = suggestion.replace(/^"+/, '').replace(/"+$/, '');
10965					suggestionsList[text] = suggestion;
10966					suggestionsList[suggestion] = suggestion;
10967					showSuggestion(suggestion);
10968				}
10969			} catch(err) {
10970				bubble.hide();
10971				console.error(err);
10972			}
10973		};
10974
10975		async function initModel() {
10976
10977			/******************* Gemini Nano ***************/
10978			if ( 'LanguageModel' in window) {
10979				let languages = ['en'];
10980				const languageCode = navigator.language.slice(0, 2).toLowerCase();
10981                if ( !languages.includes(languageCode) ) { languages.push(languageCode); }
10982                session = await LanguageModel.create({
10983                    expectedInputs:[{type: "text", languages: languages}],
10984                    expectedOutputs: [{ type: "text", languages: languages }],
10985                    initialPrompts: [
10986                        {role: "system", content: "You are a helpful assistant that improves the clarity and appeal of text."}
10987                    ],
10988                    monitor: function(m) {
10989                        m.addEventListener('downloadprogress', (e) => {
10990                            console.log(e.loaded, e.total);
10991                        });
10992                    },
10993                });
10994                activeModel = 'native';
10995                attachListeners();
10996
10997                return; // The browser's API is present, I don't require WebLLM.
10998			}
10999
11000			/******************* WEBLLM ********************/
11001			const module = await import("https://esm.run/@mlc-ai/web-llm");
11002			const CreateMLCEngine = module.CreateMLCEngine;
11003			session = await CreateMLCEngine( "Llama-3.2-1B-Instruct-q4f16_1-MLC", {
11004				useCache: false,
11005				initProgressCallback: function(p) {
11006					console.log(p);
11007				}
11008			});
11009            activeModel = 'webllm';
11010			attachListeners();
11011		};
11012
11013		async function makeInference( prompt) {
11014            if (activeModel === 'native') {
11015                const response = await session.prompt([
11016                    { role: "user", content: prompt }
11017                ]);
11018                return response.trim();
11019            } else if (activeModel === 'webllm') {
11020                await session.resetChat();
11021                const response = await session.chat.completions.create({
11022                    messages: [
11023                        { role: "user", content: prompt }
11024                    ],
11025                    temperature: 0.9,
11026                    max_tokens: 256
11027                });
11028
11029                return response.choices[0].message.content.trim();
11030            }
11031		}
11032
11033        function handleFirstInteraction() {
11034            document.removeEventListener("click", handleFirstInteraction);
11035            document.removeEventListener("keydown", handleFirstInteraction);
11036            document.removeEventListener("touchstart", handleFirstInteraction);
11037            initModel();
11038        }
11039
11040        // Listen for first interaction
11041        document.addEventListener("click", handleFirstInteraction);
11042        document.addEventListener("keydown", handleFirstInteraction);
11043        document.addEventListener("touchstart", handleFirstInteraction);
11044	} catch ( err ) { console.log(err); }
11045});	$.fbuilder.controls['fCalculated'] = function(){};
11046	$.extend(
11047		$.fbuilder.controls['fCalculated'].prototype,
11048		$.fbuilder.controls['ffields'].prototype,
11049		{
11050			title:"Untitled",
11051			ftype:"fCalculated",
11052			predefined:"",
11053			required:false,
11054			size:"medium",
11055            min:"",
11056            max:"",
11057			eq:"",
11058			suffix:"",
11059			prefix:"",
11060			decimalsymbol:".",
11061			groupingsymbol:"",
11062			dependencies:[{'rule' : '', 'complex' : false, 'fields' : [''] }],
11063			readonly:true,
11064			currency:false,
11065			noEvalIfManual:true,
11066			formatDynamically:false,
11067			dynamicEval:true,
11068			hidefield:false,
11069			validate:false,
11070			_onEquationsQueueEmpty : function( evt )
11071				{
11072//					var me = evt.data.obj;
11073//					if( ! me.noEvalIfManual ) $('[id="' + me.name + '"]').data('manually', 0);
11074				},
11075            _set_pre_post: function (attr, s)
11076                {
11077                    let e = document.getElementById(this.name);
11078                    if (e) {
11079                        if (e.type === 'number') e.type = 'text';
11080                        let v = e.value;
11081                        if (v !== '') {
11082                            v = this.val(false, true, true);
11083                            this[attr] = s;
11084                            v = $.fbuilder.calculator.format(v, this.configuration());
11085                            this.setVal(v, true);
11086                        }
11087                    }
11088					this[attr] = s;
11089                },
11090            set_prefix: function (s) { this._set_pre_post('prefix', s); },
11091            set_postfix: function (s) { this._set_pre_post('suffix', s); },
11092            set_suffix : function(s) { this._set_pre_post('suffix', s); },
11093            init:function()
11094                {
11095                    if(!/^\s*$/.test(this.prefix)) this._setHndl('prefix');
11096                    if(!/^\s*$/.test(this.suffix)) this._setHndl('suffix');
11097                },
11098            configuration : function()
11099                {
11100                    var me = this;
11101					return { "suffix" : me._getAttr('suffix'), "prefix" : me._getAttr('prefix'), "groupingsymbol" : me.groupingsymbol, "decimalsymbol" : me.decimalsymbol, "currency": me.currency };
11102                },
11103            show:function()
11104				{
11105					this.predefined = this._getAttr('predefined', true);
11106					return '<div class="fields '+cff_esc_attr(this.csslayout)+' '+this.name+' cff-calculated-field" id="field'+this.form_identifier+'-'+this.index+'" style="'+( this.hidefield ? 'padding:0;margin:0;border:0;opacity:0;width:0;height:0;overflow:hidden;' : cff_esc_attr(this.getCSSComponent('container')) )+'"><label '+( ! this.hidefield ? 'for="'+this.name+'"' : '' )+' style="'+cff_esc_attr(this.getCSSComponent('label'))+'">'+cff_sanitize(this.title, true)+''+((this.required) ? '<span class="r">*</span>' : '')+'</label><div class="dfield"><input aria-label="'+cff_esc_attr(this.title)+'" id="'+this.name+'" name="'+this.name+'" '+((this.readonly) ? ' readonly ' : '')+' '+((!/^\s*$/.test(this.min)) ? 'min="'+cff_esc_attr($.fbuilder.parseVal(this._getAttr('min'), this.thousandSeparator, this.decimalSymbol))+'" ' : '')+((!/^\s*$/.test(this.max)) ? ' max="'+cff_esc_attr($.fbuilder.parseVal(this._getAttr('max'), this.thousandSeparator, this.decimalSymbol))+'" ' : '')+' class="codepeoplecalculatedfield field '+this.size+((this.required)?" required":"")+'" t
11106ype="'+((this.hidefield) ? 'hidden' : 'text')+'" value="'+cff_esc_attr(this.predefined)+'" style="'+cff_esc_attr(this.getCSSComponent('input'))+'" />'+((!this.hidefield) ? '<span class="uh" style="'+cff_esc_attr(this.getCSSComponent('help'))+'">'+cff_sanitize(this.userhelp, true)+'</span>' : '')+'</div><div class="clearer"></div></div>';
11107				},
11108            after_show:function()
11109				{
11110	                // Add equations
11111					var me = this,
11112						dependencies = [],
11113						getAllMatches = function (str, regex) {
11114							const matches = [];
11115							let match;
11116							const globalRegex = new RegExp(regex.source, regex.flags);
11117
11118							while ((match = globalRegex.exec(str)) !== null) {
11119								matches.push(match);
11120							}
11121							return matches;
11122						};
11123
11124					$.each(me.dependencies, function(i, d)
11125						{
11126							d.rule = d.rule.replace(/^\s+/, '').replace(/\s+$/, '');
11127							if(d.rule != '' && d.fields.length){
11128
11129								var fields = [];
11130								$.each(d.fields, function(j, f){
11131									if(f != '')
11132									{
11133										fields.push(f);
11134									}
11135								});
11136
11137								if(fields.length){
11138									dependencies.push({ 'rule' : d.rule, 'fields' : fields });
11139								}
11140							}
11141						});
11142
11143					me.dependencies = dependencies;
11144					var eq = me.eq;
11145					eq = eq.replace(/([^\:"'])\/\/[^\n\r]*/g, '$1 ').replace(/^\/\/[^\n\r]*/g, '').replace(/[\n\r]/g, ' ').replace(/fieldname(\d+)/g, "fieldname$1"+me.form_identifier).replace(/form_identifier/g, '\''+this['form_identifier']+'\'').replace(/;\s*\)/g, ')').replace(/;\s*$/, '');
11146
11147					if(!/^\s*$/.test(eq))
11148                    {
11149						// This code ensures you pass to form identifier as the last operation parameter.
11150						let  indexes_array = Array.from(
11151							getAllMatches(eq, /\b(GETFIELD|ACTIVATEFIELD|IGNOREFIELD|ISIGNORED|SHOWFIELD|HIDEFIELD|EVALEQUATION|GOTOPAGE|GOTOFIELD|COPYFIELDVALUE)\(/ig ),
11152							m => m.index
11153						);
11154
11155						for( let i = indexes_array.length - 1; 0 <= i; i-- ) {
11156							let j = indexes_array[i]+1;
11157							let c = 0;
11158							while( eq[j] ) {
11159								if( eq[j] == '(' ) c++;
11160								else if ( eq[j] == ')' ) {
11161									c--;
11162									if(c < 0) break;
11163									else if (c == 0) {
11164										eq = eq.slice(0,j)+',"'+me.form_identifier+'"'+eq.slice(j);
11165										break;
11166									}
11167								}
11168								j++;
11169							}
11170						}
11171						// End.
11172
11173                        $.fbuilder.calculator.addEquation(me, eq, dependencies, me.form_identifier);
11174                    }
11175
11176                    // Events
11177			        var e = $('[id="'+me.name+'"]');
11178
11179					e.on(
11180                        'calcualtedfield_changed',
11181                        {obj: me},
11182                        function(evt){
11183							if($.fbuilder['calculator'].getDepList(evt.data.obj.name, {value: evt.data.obj.val(), raw: evt.data.obj.val(true)}, evt.data.obj.dependencies))
11184                            {
11185								$.fbuilder.showHideDep(
11186                                                {
11187                                                    'formIdentifier' : evt.data.obj.form_identifier,
11188                                                    'fieldIdentifier': evt.data.obj.name
11189                                                }
11190                                         );
11191                            }
11192                        }
11193                    ).on('keyup', function(evt){
11194                        if(!me.readonly && evt.keyCode != 9) // Tab key shouldn't trigger the event
11195                        {
11196							e.data('manually', 1);
11197							e.data('bk', e.val());
11198//							$(document).off('equationsQueueEmpty', me._onEquationsQueueEmpty);
11199//							$(document).one('equationsQueueEmpty', {obj: me}, me._onEquationsQueueEmpty);
11200							e.trigger('calcualtedfield_changed');
11201                        }
11202                    }).on('change', function(){
11203                        if(
11204                            e.data('manually') &&
11205                            e.data('manually') == 1 &&
11206                            me.formatDynamically
11207						) {
11208                            var v = (me.val(true, true)+'').replace( new RegExp( '[^\\-\\d'+me.decimalsymbol.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&')+']', 'g' ), '' ).replace(/[^\d\-]/g, '.');
11209                            this.value = $.fbuilder.calculator.format(v, me.configuration());
11210
11211							try
11212							{
11213								$(this).valid();
11214							} catch(err) {}
11215                        } else if( $(this).hasClass('cpefb_error') || me.validate ) {
11216							try
11217							{
11218								$(this).valid();
11219							} catch(err) {}
11220						}
11221						if( ! me.noEvalIfManual ) e.data('manually', 0);
11222					});
11223
11224					$('#cp_calculatedfieldsf_pform'+me.form_identifier).on('reset', function(){e.removeData('manually');});
11225				},
11226			showHideDep: function(toShow, toHide, hiddenByContainer, interval)
11227				{
11228                    if(typeof hiddenByContainer == 'undefined') hiddenByContainer = {};
11229					var me   	= this,
11230						result 	= [];
11231
11232					if($.fbuilder['calculator'].getDepList(me.name, {value: me.val(), raw: me.val(true)}, me.dependencies))
11233					{
11234						var	item 	= $('#'+me.name),
11235                            formObj	= item.closest('form'),
11236							identifier = me.form_identifier,
11237							isHidden= (typeof toHide[me.name] != 'undefined' || typeof hiddenByContainer[me.name] != 'undefined'),
11238							d, n, dep,
11239							clearRef = function(id){
11240								if(typeof toShow[id] != 'undefined')
11241								{
11242									delete toShow[id]['ref'][me.name];
11243									if($.isEmptyObject(toShow[id]['ref']))
11244									delete toShow[id];
11245								}
11246							},
11247							hideField = function(dep, isField){
11248                                if (isField) {
11249								    $('.'+dep+' [id*="'+dep+'"],.'+dep, formObj).closest('.fields').addClass('ignorefield').hide();
11250								    $('.'+dep+' [id*="'+dep+'"]:not(.ignore)', formObj).addClass('ignore').trigger('add-ignore');
11251                                } else {
11252                                    $(dep, formObj).hide();
11253                                }
11254								toHide[dep] = {};
11255							};
11256
11257						try
11258						{
11259							d = item.attr('dep');
11260							if(typeof d != 'undefined' && !/^\s*$/.test(d)) d = d.split(',');
11261							else d = [];
11262
11263							n = item.attr('notdep');
11264							if(typeof n != 'undefined' && !/^\s*$/.test(n)) n = n.split(',');
11265							else n = [];
11266
11267							if(isHidden)
11268							{
11269								n = n.concat(d);
11270								d = [];
11271							}
11272
11273							for (i=0; i<d.length; i++)
11274							{
11275                                if (!/(fieldname)|(__next_page__)|(__submit_button__)/i.test(d[i])) continue;
11276                                let dep, isField = false;
11277                                if (/fieldname\d+/i.test(d[i])) {
11278                                    dep = d[i] + identifier; // Another field dependency
11279                                    isField = true;
11280                                } else if (d[i] == '__next_page__') {
11281                                    dep = '.pb' + item.closest('.pbreak').attr('page') + ':not(.pbEnd) .pbNext'; // Next page dependency
11282                                } else {
11283                                    dep = '.pbSubmit,.captcha'; // Submission button dependency
11284                                }
11285
11286								delete toHide[dep];
11287								if(typeof toShow[dep] == 'undefined')
11288								toShow[dep] = { 'ref': {}};
11289								toShow[dep]['ref'][me.name]  = 1;
11290								if(!(dep in hiddenByContainer))
11291								{
11292                                    if (isField) {
11293									    $('.'+dep+' [id*="'+dep+'"],.'+dep, formObj).closest('.fields').removeClass('ignorefield').fadeIn(interval || 0);
11294									    $('.'+dep+' [id*="'+dep+'"].ignore', formObj).removeClass('ignore').trigger('remove-ignore');
11295                                    } else {
11296                                        $(dep, formObj).fadeIn(interval || 0);
11297                                    }
11298								}
11299								if($.inArray(dep,result) == -1) result.push(dep);
11300							}
11301
11302							for (i=0; i<n.length; i++)
11303							{
11304                                if (!/(fieldname)|(__next_page__)|(__submit_button__)/i.test(n[i])) continue;
11305                                let dep, isField = false;
11306                                if (/fieldname\d+/i.test(n[i])) {
11307                                    dep = n[i] + identifier; // Another field dependency
11308                                    isField = true;
11309                                } else if (n[i] == '__next_page__') {
11310                                    dep = '.pb' + item.closest('.pbreak').attr('page') + ':not(.pbEnd) .pbNext'; // Next page dependency
11311                                } else {
11312                                    dep = '.pbSubmit,.captcha'; // Submission button dependency
11313                                }
11314								clearRef(dep);
11315								if (
11316									typeof toShow[dep] == 'undefined' &&
11317									typeof toHide[dep] == 'undefined'
11318								) hideField(dep, isField);
11319								if($.inArray(dep,result) == -1) result.push(dep);
11320							}
11321						}
11322						catch(e){}
11323					}
11324					return result;
11325				},
11326			val: function(raw, no_quotes, disable_ignore_check)
11327				{
11328					raw = raw || false;
11329                    no_quotes = no_quotes || false;
11330					var e = (disable_ignore_check) ? $('[id="'+this.name+'"]') : $('[id="'+this.name+'"]:not(.ignore)');
11331					if(e.length)
11332					{
11333						var v = e.val();
11334						if(raw) return $.fbuilder.parseValStr(v, raw, no_quotes);
11335						v = String(v).trim();
11336
11337						v = v.replace(new RegExp($.fbuilder['escapeSymbol'](this.prefix), 'g'), '')
11338						     .replace(new RegExp($.fbuilder['escapeSymbol'](this.suffix), 'g'), '');
11339
11340						return $.fbuilder.parseVal(v, this.groupingsymbol, this.decimalsymbol, no_quotes);
11341					}
11342					return 0;
11343				},
11344			setVal:function( v, nochange )
11345				{
11346					var e  = $( "[id='" + this.name + "']" ),
11347						bk = e.data('bk');
11348					e.val( v );
11349					if(bk != v){
11350						e.trigger('calcualtedfield_changed');
11351						if(!nochange) e.trigger('change');
11352					}
11353				}
11354		}
11355	);
11356
11357	/*
11358	* Extend the window object with the methods of obj, the prefix is used to avoid redefine window methods
11359	*/
11360	$.fbuilder['extend_window']  = function(prefix, obj)
11361		{
11362			for(method in obj)
11363			{
11364				window[prefix+method] = (function(m)
11365					{
11366						return function()
11367							{
11368								return m.obj[m.method_name].apply(m.obj, arguments);
11369							};
11370					})({ "method_name" : method, 'obj' : obj });
11371			}
11372		};
11373
11374	// Calculate Field code
11375	$.fbuilder['calculator'] = (function()
11376		{
11377				// Used to validate the equations results
11378				var validators = [];
11379
11380                // Loading available modules
11381				if(typeof $.fbuilder['modules'] != 'undefined')
11382				{
11383					var modules = $.fbuilder['modules'];
11384					for(var module in modules)
11385					{
11386						if(typeof modules[module]['callback'] != 'undefined')
11387						{
11388							modules[module]['callback']();
11389						}
11390
11391						if(typeof modules[module]['validator'] != 'undefined')
11392						{
11393							validators.push(modules[module]['validator']);
11394						}
11395					}
11396				}
11397
11398				// Private function to validate the equation results
11399				_validate_result = function(v)
11400					{
11401						if(validators.length)
11402						{
11403							var h = validators.length;
11404							while(h--)
11405							{
11406								if(validators[h](v))
11407								{
11408									return true;
11409								}
11410							}
11411						}
11412						else
11413						{
11414							return true;
11415						}
11416
11417						return false;
11418					};
11419
11420				_calculate = function(eq, suffix, __ME__)
11421					{
11422						var e = $.fbuilder['forms'][suffix].getItem(__ME__),
11423							__ME__ = e.val();
11424
11425						if($('#'+e.name).data('manually') == 1) return __ME__;
11426
11427						var	_match,
11428							field_regexp = new RegExp('(fieldname\\d+'+suffix+')(_[cr]b\\d+)?(\\|[rnvq])?([\\D\\b])','ig');
11429
11430						$.fbuilder['currentFormId'] = $.fbuilder['forms'][suffix].formId;
11431
11432						var original  = '('+eq+')',
11433							out       = '',
11434							lastIndex = 0,
11435							_match;
11436						while (_match = field_regexp.exec(original))
11437						{
11438							out += original.substring(lastIndex, _match.index);
11439							var field = $.fbuilder['forms'][suffix].getItem(_match[1]),
11440								v = '',
11441								r;
11442							if(field || (_match[3] && _match[3] == '|n'))
11443							{
11444								if(_match[3] && _match[3] == '|n')
11445								{
11446									v = '"'+_match[1].match(/fieldname\d+/)[0]+'"';
11447								}
11448								else
11449								{
11450									r = _match[3] ? (_match[3] == '|v' ? 'vt' : (_match[3] == '|r' ? true : (_match[3] == '|q' ? 'q' : false))) : false;
11451									v = field.val(r);
11452									if(typeof v == 'object' && typeof window.JSON != 'undefined') v = '('+JSON.stringify(v).replace(/\\\\\\/g, '\\')+')';
11453									else if( r !== true && $.fbuilder.isNumeric(v)) v = '('+v+')';
11454								}
11455							}
11456							out += v+''+_match[4]; // Replace the variable name by value
11457							lastIndex = field_regexp.lastIndex;
11458						}
11459						out += original.substring(lastIndex);
11460						eq = out;
11461						try
11462						{
11463							eq = eq.replace(/^\(/, '').replace(/\)$/, '').replace(/\b__ME__\b/g, __ME__);
11464							var r;
11465							try {
11466								if ($.fbuilder['isEvalBlocked']()) throw new EvalError("*");
11467								r = eval(eq);
11468							} catch (err) {
11469								if ( err instanceof EvalError ) r = $.fbuilder['eval'].call(this, eq);
11470								else throw err;
11471							}
11472							return (typeof r != 'undefined' && _validate_result(r)) ? r : false;
11473						}
11474						catch( err2 )
11475						{
11476							console.log('[CFF - '+e.name.replace(/_\d+$/,'')+'] equation eval failed:', eq, err2.message);
11477							return false;
11478						}
11479					};
11480
11481				_checkValueThrowingEquation = function(t)
11482					{
11483						if(typeof t.attr('data-timeout') != 'undefined') clearTimeout(t.attr('data-timeout'));
11484						if(typeof t.attr('data-previousvalue') == 'undefined') t.attr('data-previousvalue', t.val());
11485						else
11486						{
11487							if(t.val() == t.attr('data-previousvalue'))
11488							{
11489								t.removeAttr('data-timeout');
11490								obj.Calculate(t[0]);
11491								return;
11492							}
11493							t.attr('data-previousvalue',  t.val());
11494						}
11495						t.attr('data-timeout',  setTimeout(_checkValueThrowingEquation, 500, t));
11496					};
11497
11498				// The public object
11499                var CalcFieldClss = function(){};
11500				CalcFieldClss.prototype = {
11501					processing_queue : {}, // Flag indicating the queued equations are being processed
11502					pendings : {},
11503					// object where attributes names are the forms identifiers, and their values the queue of equations
11504					queued_equations : {},
11505					addPending : function(form_identifier)
11506					{
11507						if(!(form_identifier in this.pendings)) this.pendings[form_identifier] = 1;
11508						else this.pendings[form_identifier]++;
11509					},
11510					removePending : function(form_identifier)
11511					{
11512						if((form_identifier in this.pendings) && this.pendings[form_identifier]) this.pendings[form_identifier]--;
11513					},
11514					thereIsPending : function(form_identifier)
11515					{
11516						if(form_identifier in this.pendings) return this.pendings[form_identifier];
11517						return 0;
11518					},
11519					addEquation : function(fieldObj, equation, dependencies, form_identifier)
11520						{
11521							var equation_result = $('[id="'+fieldObj.name+'"]');
11522							if(equation_result.length)
11523							{
11524								var form = equation_result[0].form,
11525									equationObj, field,
11526									regexp = new RegExp('(fieldname\\d+)_'),
11527									match;
11528
11529								if(typeof form.equations == 'undefined') form['equations'] = [];
11530								var  i, j=-1, h = form.equations.length;
11531
11532								// Avoid insert the equation multiple times to the form
11533								for(i = 0 ; i < h; i++)
11534								{
11535									if(form.equations[i].result == fieldObj.name) break;
11536									if(form.equations[i].equation.match(fieldObj.name)){ j = i; break; }
11537								}
11538
11539								// The equation hasn't been inserted previously
11540								if(i == h || j != -1)
11541								{
11542                                    /* conf attribute only for compatibility */
11543									equationObj = {'result':fieldObj.name, 'resultField':fieldObj, 'equation':equation, 'conf':fieldObj.configuration(), 'dep':dependencies, 'identifier':form_identifier};
11544									form.equations.splice(i, 0, equationObj);
11545
11546									while(match = /(pdfpagesnumber|imgdimension|viewfile|csvtojson)\s*\(\s*fieldname\d+_\d+(\|n)\b/i.exec(equation)) {
11547										equation = equation.replace(match[2], match[0].replace('|n', ''));
11548									}
11549									equation = equation.replace(/fieldname\d+_\d+\|n\b/g, '');
11550									while (match = regexp.exec(equation))
11551									{
11552										field = $.fbuilder['forms'][form_identifier].getItem(match[1]+form_identifier);
11553										if(field)
11554										{
11555											if(typeof field.usedInEquations == 'undefined') field.usedInEquations = [];
11556											field.usedInEquations.push(equationObj);
11557										}
11558										equation = equation.replace(new RegExp(match[0], 'g'), '');
11559									}
11560								}
11561							}
11562
11563						},
11564					enqueueEquation : function(form_identifier, equations)
11565						{
11566							if(typeof this.queued_equations[form_identifier] == 'undefined')
11567								this.queued_equations[form_identifier] = [];
11568							var queue = this.queued_equations[form_identifier], f;
11569
11570							for(var i = 0, h = equations.length; i < h; i++)
11571							{
11572								f = -1;
11573								for(var j = 0, k = queue.length; j < k; j++)
11574								{
11575									if(queue[j].result == equations[i].result) break;
11576									if(queue[j].equation.match(equations[i].result)){ f = j; break; }
11577								}
11578								if(j == k || f != -1)
11579								{
11580									queue.splice(j, 0, equations[i]);
11581								}
11582							}
11583						},
11584					getDepList : function(calculated_field, values, dependencies) // Get the list of dependent fields
11585						{
11586							var list    = [], // Fields that comply the rules
11587								list_h  = []; // Fields that don't comply the rules
11588
11589							// The value is correct and the field has dependencies
11590							if(values.value !== false && dependencies.length)
11591							{
11592								for(var i = 0, h = dependencies.length; i < h; i++)
11593								{
11594									try
11595									{
11596										// Get the rule and evaluate
11597										var rule,
11598											rule_src = dependencies[i].rule.replace(/value\s*&lt;/gi, 'value<')
11599																			.replace(/value\s*&gt;/gi, 'value>')
11600																			.replace(/value\|r/gi, values.raw)
11601																			.replace(/value/gi, values.value);
11602										try {
11603											if ($.fbuilder['isEvalBlocked']()) throw new EvalError("*");
11604											rule = eval(rule_src);
11605										} catch (err) {
11606											if ( err instanceof EvalError ) rule = $.fbuilder['eval'].call(this, rule_src);
11607											else throw err;
11608										}
11609
11610										$.each(dependencies[i].fields, function(j, e)
11611											{
11612												if(e != '')
11613												{
11614													if(rule)
11615													{
11616														var k = $.inArray(e, list_h);
11617                                                        while(k != -1)
11618                                                        {
11619                                                            list_h.splice(k, 1);
11620                                                            k = $.inArray(e, list_h);
11621                                                        }
11622														if($.inArray(e, list) == -1) list.push(e);
11623													}
11624													else
11625													{
11626														if($.inArray(e, list) == -1) list_h.push(e);
11627													}
11628												}
11629											});
11630
11631									}
11632									catch(err2)
11633									{
11634										console.log('[CFF] dependency rule ' + i + ' failed:', err2.message);
11635										continue;
11636									}
11637								}
11638							}
11639
11640							$('[id="'+calculated_field+'"]').attr('dep', list.join(',')).attr('notdep', list_h.join(','));
11641							return list.length || list_h.length;
11642						},
11643
11644                    defaultCalc : function(form, enqueued, force_all) // Evaluate all equations in form
11645						{
11646							var dep  = false;
11647							form = $(form);
11648							enqueued = enqueued || false;
11649							force_all = force_all || false;
11650
11651							// The form exists and has equations
11652							if(form.length)
11653							{
11654								var fSec  = form.attr('id').match(/_\d+$/)[0];
11655
11656								$.fbuilder.forms[fSec]['force_all'] = force_all;
11657								form.one('mousedown keydown touchstart', ':input', function(){
11658									$.fbuilder.forms[fSec]['force_all'] = false;
11659								});
11660
11661								if(enqueued)
11662								{
11663									this.processQueue(fSec);
11664								}
11665								else if(typeof form[0].equations != 'undefined')
11666								{
11667									if(force_all){ // Force the evaluation even if fields configured to not evaluate dynamically.
11668										this.queued_equations[fSec] = form[0].equations.slice(0);
11669									} else {
11670										var _dynamicEquations = [];
11671										for(var i = 0, q = form[0].equations.slice(0), h = q.length; i < h; i++) {
11672											if(getField(q[i].result)['dynamicEval'])
11673												_dynamicEquations.push(q[i]);
11674										}
11675										this.queued_equations[fSec] = _dynamicEquations;
11676									}
11677									this.processQueue(fSec);
11678								}
11679								$(form).trigger('cpcff_default_calc');
11680							}
11681						},
11682                    evaluate: function (eq, suffix, __ME__) // Evaluate all equations in the form
11683                        {
11684                            return _calculate(eq, suffix, __ME__);
11685                        },
11686                    Calculate : function (field)
11687						{
11688							if(field.id == undefined) return;
11689							var id 	 = field.id.replace(/_[cr]b\d+$/i,''),
11690								fSec  = id.match(/(_\d+)?_\d+$/),
11691								item,
11692								me   = this;
11693
11694							if(fSec)
11695							{
11696								fSec = (typeof fSec[1] != 'undefined') ? fSec[1] : fSec[0];
11697								item = $.fbuilder['forms'][fSec].getItem(id);
11698								if(item && typeof item['usedInEquations'] != 'undefined')
11699								{
11700									for(var i in item.usedInEquations) {
11701										if(
11702											getField(item.usedInEquations[i].result)['dynamicEval'] ||
11703											(
11704												'force_all' in $.fbuilder['forms'][fSec] &&
11705												$.fbuilder['forms'][fSec]['force_all']
11706											)
11707										) me.enqueueEquation(fSec, [item.usedInEquations[i]]);
11708									}
11709									me.processQueue(fSec);
11710								}
11711							}
11712						},
11713					processQueue : function(fSec)
11714						{
11715							var me = this;
11716							if(fSec in me.processing_queue && me.processing_queue[fSec])
11717							{
11718								setTimeout(
11719									(function ( fSec ) {
11720										if(fSec in me.processing_queue && me.processing_queue[fSec]) {
11721											me.processing_queue[fSec] = false;
11722											me.processQueue(fSec);
11723										}
11724									})(fSec),
11725									(typeof CFF_PROCESS_QUEUE_INTERVAL != 'undefined') ? CFF_PROCESS_QUEUE_INTERVAL : 3000
11726								);
11727								return;
11728							}
11729							me.processing_queue[fSec] = true;
11730
11731							if(typeof me.queued_equations[fSec] != 'undefined')
11732							{
11733								var queue = me.queued_equations[fSec], eq_obj;
11734								while(queue.length)
11735								{
11736									eq_obj = queue.shift();
11737									$.fbuilder['currentEq'] = eq_obj;
11738									var field = $('[id="'+eq_obj.result+'"]'),
11739										result = _calculate(eq_obj.equation,  eq_obj.identifier,  eq_obj.result),
11740										bk =  field.data('bk');
11741									delete ( $.fbuilder['currentEq'] );
11742									field.val((result !== false) ? me.format(result, eq_obj.resultField.configuration()) : '');
11743									if(bk != field.val())
11744									{
11745										field.data('bk',field.val());
11746										field.trigger('calcualtedfield_changed');
11747										field.trigger('change');
11748									}
11749								}
11750							}
11751
11752							me.processing_queue[fSec] = false;
11753							if(!me.thereIsPending(fSec)) $(document).trigger('equationsQueueEmpty', [fSec]);
11754						},
11755                    format : function(value,  config)
11756						{
11757							config = $.extend({}, config);
11758							if(!/^\s*$/.test(value))
11759                            {
11760								var symbol = '', isNumeric = false;
11761                                if($.fbuilder.isNumeric(value) && !/[+\-]?(?:0|[1-9]\d*)(?:\.\d*)?(?:[eE][+\-]?\d+)/.test(value))
11762                                {
11763									isNumeric = true;
11764									if(value < 0) symbol =  '-';
11765									if(config.currency && FLOOR(value) != value) value = PREC(value,2);
11766                                    var parts = value.toString().replace("-", "").split("."),
11767                                        counter = 0,
11768                                        str = '';
11769
11770                                    if(config.groupingsymbol)
11771                                    {
11772                                        for(var i = parts[0].length-1; i >= 0; i--){
11773                                            counter++;
11774                                            str = parts[0][i]+str;
11775                                            if(counter%3 == 0 && i != 0) str = config.groupingsymbol+str;
11776
11777                                        }
11778                                        parts[0] = str;
11779                                    }
11780									if(!('decimalsymbol' in config)) config.decimalsymbol = '.';
11781                                    value = parts.join(config.decimalsymbol);
11782                                }
11783
11784								if(config.currency && !isNumeric)
11785								{
11786									delete config.prefix;
11787									delete config.suffix;
11788								}
11789
11790                                if(config.prefix)
11791                                {
11792									if(!config.currency)
11793									{
11794										value = symbol+value;
11795										symbol = '';
11796									}
11797									value = config.prefix+value;
11798                                }
11799
11800                                if(config.suffix) value += config.suffix;
11801
11802								value = symbol+value;
11803                            }
11804							return value;
11805						},
11806
11807                    unformat : function(field)
11808						{
11809							var escapeSymbol = $.fbuilder.escapeSymbol;
11810
11811							var eq = field[0].form.equations,
11812								v = field.val();
11813
11814							for(var i = 0, h = eq.length; i < h; i++)
11815							{
11816								if(eq[i].result == field[0].id)
11817								{
11818									var c = eq[i].resultField.configuration(); // Configuration object
11819
11820									if(c.prefix && !/^\s*$/.test(c.prefix))
11821									{
11822										v = v.replace(new RegExp("^"+escapeSymbol(c.prefix)), '');
11823									}
11824
11825									if(c.suffix && !/^\s*$/.test(c.suffix))
11826									{
11827										v = v.replace(new RegExp(escapeSymbol(c.suffix)+"$"), '');
11828									}
11829
11830									if(!/[+\-]?(?:0|[1-9]\d*)(?:\.\d*)?(?:[eE][+\-]?\d+)/.test(v))
11831									{
11832										if(c.groupingsymbol && !/^\s*$/.test(c.groupingsymbol))
11833										{
11834											v = v.replace(new RegExp(escapeSymbol(c.groupingsymbol), 'g'), '');
11835										}
11836
11837										if(c.decimalsymbol && !/^\s*$/.test(c.decimalsymbol))
11838										{
11839											v = v.replace(new RegExp(escapeSymbol(c.decimalsymbol), 'g'), '.');
11840										}
11841									}
11842								}
11843							}
11844							return v;
11845						}
11846				};
11847
11848				var obj = new CalcFieldClss();
11849
11850				// Associate events to the document for throw the corresponding equations
11851                $(document).on('keyup change blur', '[id="fbuilder"] :input,[id="fbuilder"] .cff-datatable-field .cff-datatable-container', function(evt)
11852					{
11853                        // If evalequations = 0 the equations shouldn't be evaluated dynamically
11854                        var t = $(evt.target),
11855							f = t.closest('form'),
11856							evalequations 		= f.attr('data-evalequations'),
11857							evalequationsevent 	= f.attr('data-evalequationsevent');
11858
11859                        if(
11860							typeof evalequations != 'undefined' &&
11861							evalequations*1 == 0 &&
11862							(
11863                                !(t.hasClass('codepeoplecalculatedfield') && evt.type == 'change') ||
11864                                (
11865									t.hasClass('codepeoplecalculatedfield') &&
11866									(
11867										t.data('manually') == 1 ||
11868										f.attr('data-loadingdefaults')
11869									)
11870								)
11871                         )
11872						)
11873                        {
11874                            return;
11875                        }
11876
11877                        if(evt.type == 'keyup')
11878						{
11879							if('undefined' != typeof evalequationsevent && evalequationsevent*1 == 1)
11880							{
11881								return;
11882							}
11883							// The key out of range
11884							if(evt.keyCode && (evt.keyCode >= 33 && evt.keyCode <= 40)) return;
11885							_checkValueThrowingEquation(t);
11886						}
11887						else
11888						{
11889							if(/*t.hasClass('depItem') ||*/
11890								(
11891									(
11892										t.prop('tagName') == 'INPUT' &&
11893										/(text|number|email|password)/.test(t.attr('type').toLowerCase()) ||
11894										t.prop('tagName') == 'TEXTAREA'
11895									) &&
11896									evt.type != 'change'
11897								)
11898							)
11899							{
11900								return;
11901							}
11902							obj.Calculate(t[0]);
11903						}
11904					});
11905
11906				//Associate an event to the document waiting for the showHideDepEvent and recalculate all equations
11907				$(document).on('showHideDepEvent', function(evt, form_identifier)
11908					{
11909						// If evalequations = 0 the equations shouldn't be evaluated dynamically
11910						var f, evalequations;
11911						if(form_identifier) f = $('#'+form_identifier);
11912						else f = $('[id*="cp_calculatedfieldsf_pform_"]:eq(0)');
11913
11914						if(f.length)
11915						{
11916							evalequations = f.attr('data-evalequations');
11917							if(typeof evalequations == 'undefined' || evalequations*1 == 1)
11918							{
11919								obj.defaultCalc('#'+f.attr('id'), true);
11920							}
11921						}
11922                    });
11923                return obj; // Return the public object
11924            }
11925     )();try{
11926!function(a){function f(a,b){if(!(a.originalEvent.touches.length>1)){a.preventDefault();var c=a.originalEvent.changedTouches[0],d=document.createEvent("MouseEvents");d.initMouseEvent(b,!0,!0,window,1,c.screenX,c.screenY,c.clientX,c.clientY,!1,!1,!1,!1,0,null),a.target.dispatchEvent(d)}}if(a.support.touch="ontouchend"in document,a.support.touch){var e,b=a.ui.mouse.prototype,c=b._mouseInit,d=b._mouseDestroy;b._touchStart=function(a){var b=this;!e&&b._mouseCapture(a.originalEvent.changedTouches[0])&&(e=!0,b._touchMoved=!1,f(a,"mouseover"),f(a,"mousemove"),f(a,"mousedown"))},b._touchMove=function(a){e&&(this._touchMoved=!0,f(a,"mousemove"))},b._touchEnd=function(a){e&&(f(a,"mouseup"),f(a,"mouseout"),this._touchMoved||f(a,"click"),e=!1)},b._mouseInit=function(){var b=this;b.element.bind({touchstart:a.proxy(b,"_touchStart"),touchmove:a.proxy(b,"_touchMove"),touchend:a.proxy(b,"_touchEnd")}),c.call(b)},b._mouseDestroy=function(){var b=this;b.element.unbind({touchstart:a.proxy(b,"_touchStart"),touchmove:a.proxy(b,"_touchMove"),touchend:a.proxy(b,"_touchEnd")}),d.call(b)}}}(jQuery);
11927}catch( err ){}if(typeof $.fn['fbuilder_serializeObject'] == 'undefined')
11928{
11929	$.fn.fbuilder_serializeObject = function()
11930	{
11931	   var  o = {},
11932		 	a = this.serializeArray();
11933
11934	   $.each(a, function() {
11935		   if(/^fieldname\d+_\d+(\[\])?$/.test(this.name)) this.name = this.name.match(/fieldname\d+/)[0];
11936		   else return;
11937		   if (o[this.name]) {
11938			   if (!o[this.name].push) {
11939				   o[this.name] = [o[this.name]];
11940			   }
11941			   o[this.name].push(this.value || '');
11942		   } else {
11943			   o[this.name] = this.value || '';
11944		   }
11945	   });
11946	   return o;
11947	};
11948}
11949
11950$.fn.fbuilder_localstorage = function(){
11951	var form = this,
11952		id = form.attr('id'),
11953		sq = (typeof id == 'undefined') ? 1 : id.replace(/[^\d]/g,''),
11954		localStore_obj,
11955		fields;
11956	if(sq == '') sq = 1;
11957	localStore_obj = new $.fbuilder_localstorage(form, true);
11958	fields = localStore_obj.get_fields();
11959	if(!$.isEmptyObject(fields))
11960	{
11961		if(typeof cpcff_default == 'undefined') cpcff_default = {};
11962		if(typeof cpcff_default[sq] == 'undefined') cpcff_default[sq] = {};
11963		cpcff_default[sq] = $.extend(cpcff_default[sq], fields);
11964	}
11965
11966	$(document).on('cff-loaded-defaults', '#'+id, function(){localStore_obj.set_fields();});
11967	$(document).on('change', '#'+id+' *', function(evt){
11968		if(
11969			typeof this['id'] != 'undefined' &&
11970			/^fieldname\d+_\d+$/i.test(this.id) &&
11971			typeof this['value'] != 'undefined'
11972		)
11973		{
11974			localStore_obj.set_fields();
11975		}
11976	});
11977	form.on('submit', function(){localStore_obj.clear_fields();});
11978	return this;
11979}
11980
11981$.fbuilder_localstorage = function(form, debug){
11982	this.form 		= form;
11983	this.id			= form.attr('id')+'_'+form.find('[name="cp_calculatedfieldsf_id"]').val();
11984	this.debug 		= (typeof debug != 'undefined' && debug) ? true : false;
11985};
11986
11987$.fbuilder_localstorage.prototype = (function(){
11988
11989	/** Private variables **/
11990	var is_available;
11991
11992	/** Private functions **/
11993	function _log(mssg)
11994	{
11995		if(typeof console != 'undefined') console.log(mssg);
11996	};
11997
11998	return {
11999		is_available : function() {
12000			if(typeof is_available != 'undefined') return is_available;
12001			try {
12002				var storage = window['localStorage'],
12003					x = '__storage_test__';
12004				storage.setItem(x, x);
12005				storage.removeItem(x);
12006				is_available = true;
12007				return true;
12008			}
12009			catch(e) {
12010				if(this.debug) _log( 'localStorage object is not available' );
12011				is_available = false;
12012				return e instanceof DOMException && (
12013					e.code === 22 ||
12014					e.code === 1014 ||
12015					e.name === 'QuotaExceededError' ||
12016					e.name === 'NS_ERROR_DOM_QUOTA_REACHED') &&
12017					storage.length !== 0;
12018			}
12019		},
12020
12021		get_fields : function(){
12022			try{
12023				if(typeof this.fields == 'undefined') this.fields = JSON.parse(localStorage.getItem(this.id));
12024				return this.fields;
12025			} catch(err) {
12026				_log( 'Error reading the fields.' );
12027				_log( err );
12028			}
12029		},
12030
12031		set_fields : function(){
12032			try{
12033				this.fields = this.form.fbuilder_serializeObject();
12034				localStorage.setItem(this.id, JSON.stringify(this.fields));
12035			} catch(err) {
12036				_log( 'Error saving the fields.' );
12037				_log( err );
12038			}
12039		},
12040
12041		clear_fields : function(){
12042			try{
12043				localStorage.removeItem(this.id);
12044			} catch(err) {
12045				_log( 'Error deleting the fields.' );
12046				_log( err );
12047			}
12048		}
12049	};
12050})();	$.fbuilder.controls[ 'fmap_widget' ]=function(){};
12051	$.extend(
12052		true,
12053		$.fbuilder.controls[ 'fmap_widget' ].prototype,
12054		$.fbuilder.controls[ 'ffields' ].prototype,
12055		{
12056			title:"Map",
12057			ftype:"fmap_widget",
12058
12059			map_width: '100%',
12060			map_height: '350px',
12061			map_provider: 'public',
12062			map_provider_url: '',
12063
12064			// Center and bounding.
12065            pin_title: '',
12066			latitude: '',
12067			longitude: '',
12068			zoom: '',
12069			radius: '',
12070
12071			allow_user_pin: true,
12072			user_pin_color: '#ff0000',
12073			associated_address_field: '',
12074
12075            init: function() {
12076                let me = this;
12077                me.map_width = String(me.map_width).trim();
12078                me.map_height = String(me.map_height).trim();
12079
12080                if (me.map_width === '') me.map_width = '100%';
12081                else if (!isNaN(me.map_width*1)) me.map_width += 'px';
12082
12083                if (me.map_height === '') me.map_height = '350px';
12084                else if (!isNaN(me.map_height*1)) me.map_height += 'px';
12085
12086                me.map_provider = String(me.map_provider || 'public').trim().toLowerCase();
12087                me.map_provider_url = String(me.map_provider_url || '').trim();
12088                if (me.map_provider !== 'public') {
12089                    let validUrl = false;
12090                    try {
12091                        if (me.map_provider_url !== '') {
12092                            let parsed = new URL(me.map_provider_url);
12093                            let hasValidProtocol = parsed.protocol === 'https:' || parsed.protocol === 'http:';
12094                            validUrl = hasValidProtocol;
12095                        }
12096                    } catch (err) {
12097                        validUrl = false;
12098                    }
12099
12100                    if (!validUrl) {
12101                        me.map_provider = 'public';
12102                        me.map_provider_url = '';
12103                    }
12104                }
12105
12106                me.latitude = parseFloat(me.latitude);
12107                if (isNaN(me.latitude) || me.latitude < -90 || me.latitude > 90) {
12108                    me.latitude = 0;
12109                }
12110                me.longitude = parseFloat(me.longitude);
12111                if (isNaN(me.longitude) || me.longitude < -180 || me.longitude > 180) {
12112                    me.longitude = 0;
12113                }
12114
12115                me.zoom = parseInt(me.zoom, 10);
12116                if (isNaN(me.zoom)) {
12117                    me.zoom = 13;
12118                }
12119
12120                me.radius = parseFloat(me.radius);
12121                if (isNaN(me.radius) || me.radius < 0) {
12122                    me.radius = 0;
12123                }
12124
12125                me.allow_user_pin = (me.allow_user_pin === true || me.allow_user_pin === 1 || me.allow_user_pin === '1' || me.allow_user_pin === 'true');
12126                me.user_pin_color = me.user_pin_color || '#ff0000';
12127                me.associated_address_field = me.associated_address_field || '';
12128            },
12129
12130            show: function() {
12131                let me = this;
12132
12133                return '<div class="fields ' + cff_esc_attr(me.csslayout) + ' ' + me.name + ' cff-map-widget" id="field' + me.form_identifier + '-' + me.index + '" style="' + cff_esc_attr(me.getCSSComponent('container')) + '"><label for="' + me.name + '" style="' + cff_esc_attr(me.getCSSComponent('label')) + '">' + cff_sanitize(me.title, true) + '</label><div class="dfield">' +
12134
12135                '<div id="' + me.name + '" class="cff-map-container" style="width:' + cff_esc_attr(me.map_width) + ';height:' + cff_esc_attr(me.map_height) + ';' + cff_esc_attr(this.getCSSComponent('map_container')) + '"></div>'+
12136
12137                '<span class="uh" style="' + cff_esc_attr(this.getCSSComponent('help')) + '">' + cff_sanitize(this.userhelp, true) + '</span></div><div class="clearer"></div></div>';
12138            },
12139
12140            after_show: function() {
12141                let me = this;
12142                if (typeof L === 'undefined') {
12143                    var link = document.createElement('link');
12144                    link.rel = 'stylesheet';
12145                    link.href = 'https://unpkg.com/[email protected]/dist/leaflet.css';
12146                    document.head.appendChild(link);
12147
12148                    var script = document.createElement('script');
12149                    script.src = 'https://unpkg.com/[email protected]/dist/leaflet.js';
12150                    script.onload = function() { me._initMap(); };
12151                    document.head.appendChild(script);
12152                } else {
12153                    me._initMap();
12154                }
12155            },
12156
12157            _initMap: function() {
12158                let me = this;
12159                var mapContainer = document.getElementById(me.name);
12160                if (!mapContainer) return;
12161
12162                if (me.latitude === '' || isNaN(me.latitude)) me.latitude = 0;
12163                if (me.longitude === '' || isNaN(me.longitude)) me.longitude = 0;
12164                if (me.zoom === '' || isNaN(me.zoom)) me.zoom = 13;
12165
12166                me._map = L.map(me.name).setView([me.latitude, me.longitude], me.zoom);
12167                L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
12168                    attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
12169                }).addTo(me._map);
12170
12171                var userMarker = null;
12172
12173                if (me.latitude != 0 || me.longitude != 0) {
12174                    var titleAttr = me.pin_title ? { title: me.pin_title } : {};
12175                    var preMarker = L.marker([me.latitude, me.longitude], titleAttr).addTo(me._map);
12176                    if (me.pin_title) preMarker.bindPopup(me.pin_title).openPopup();
12177                }
12178
12179                if (me.radius > 0) {
12180                    L.circle([me.latitude, me.longitude], {
12181                        radius: me.radius,
12182                        color: '#0066ff',
12183                        weight: 2,
12184                        opacity: 0.6,
12185                        fillColor: '#0066ff',
12186                        fillOpacity: 0.1
12187                    }).addTo(me._map);
12188                }
12189
12190                if (me.allow_user_pin) {
12191                    var userPinIcon = L.divIcon({
12192                        className: 'cff-user-pin-icon',
12193                        html: '<div style="background-color:' + me.user_pin_color + ';width:24px;height:24px;border-radius:50%;border:2px solid white;box-shadow:0 0 5px rgba(0,0,0,0.5);"></div>',
12194                        iconSize: [24, 24],
12195                        iconAnchor: [12, 12]
12196                    });
12197
12198                    me._map.on('click', function(e) {
12199                        if (me.radius > 0 && me._map.distance(e.latlng, [me.latitude, me.longitude]) > me.radius) return;
12200                        if (userMarker) me._map.removeLayer(userMarker);
12201                        userMarker = L.marker(e.latlng, { icon: userPinIcon, draggable: true }).addTo(me._map);
12202                        userMarker.on('dragend', function(ev) { me._handleMarkerDrag(ev.target.getLatLng()); });
12203                        me._handleMarkerClick(e.latlng);
12204                    });
12205
12206                    if (me.associated_address_field) {
12207                        var addrField = getField(me.associated_address_field, me.form_identifier);
12208                        if (addrField) {
12209                            addrField.jQueryRef().find(':input').on('change', function() {
12210                                if (me.triggeredByMap) { me.triggeredByMap = false; return; }
12211                                var addr = addrField.val(true, true);
12212                                if (addr && addr.trim()) {
12213                                    me._geocodeAddress(addr, function(lat, lng) {
12214                                        if (lat && lng) {
12215                                            if (userMarker) me._map.removeLayer(userMarker);
12216                                            userMarker = L.marker([lat, lng], { icon: userPinIcon, draggable: true }).addTo(me._map);
12217                                            userMarker.on('dragend', function(ev) { me._handleMarkerDrag(ev.target.getLatLng()); });
12218                                            me._map.setView([lat, lng], me.zoom);
12219                                        }
12220                                    });
12221                                }
12222                            });
12223                        }
12224                    }
12225                }
12226
12227                var checkAndInvalidate = function() {
12228                    var rect = mapContainer.getBoundingClientRect();
12229                    if (rect.width > 0 && rect.height > 0) {
12230                        me._map.invalidateSize();
12231                        observer.disconnect();
12232                    }
12233                };
12234
12235                if (!mapContainer.offsetParent) {
12236                    var observer = new MutationObserver(checkAndInvalidate);
12237                    observer.observe(document.body, { childList: true, subtree: true, attributes: true });
12238                }
12239            },
12240
12241            _handleMarkerClick: function(latlng) {
12242                let me = this;
12243                me._reverseGeocode(latlng.lat, latlng.lng, function(address) {
12244                    if (address && me.associated_address_field) {
12245                        var addrField = getField(me.associated_address_field, me.form_identifier);
12246                        if (addrField) {
12247                            me.triggeredByMap = true;
12248                            addrField.setVal(address);
12249                        }
12250                    }
12251                });
12252            },
12253
12254            _handleMarkerDrag: function(latlng) {
12255                this._handleMarkerClick(latlng);
12256            },
12257
12258            _getGeocodingUrl: function() {
12259                let me = this;
12260                if (me.map_provider !== 'public' && me.map_provider_url) {
12261                    return me.map_provider_url.replace(/\/$/, '');
12262                }
12263                return '';
12264            },
12265
12266            _reverseGeocode: function(lat, lng, callback) {
12267                let me = this;
12268                var customUrl = me._getGeocodingUrl();
12269
12270                var tryReverseGeocode = function(baseUrl, onSuccess, onFail) {
12271                    var url = baseUrl + '/reverse?format=json&lat=' + lat + '&lon=' + lng;
12272                    fetch(url)
12273                        .then(function(response) { return response.json(); })
12274                        .then(function(data) {
12275                            if (data && data.display_name) {
12276                                onSuccess(data.display_name);
12277                            } else {
12278                                onFail();
12279                            }
12280                        })
12281                        .catch(function() { onFail(); });
12282                };
12283
12284                var nominatimFallback = function() {
12285                    tryReverseGeocode('https://nominatim.openstreetmap.org', function(result) {
12286                        callback(result);
12287                    }, function() {
12288                        tryReverseGeocode('https://photon.komoot.io', function(result) {
12289                            callback(result);
12290                        }, function() {
12291                            callback('');
12292                        });
12293                    });
12294                };
12295
12296                if (customUrl) {
12297                    tryReverseGeocode(customUrl, function(result) {
12298                        callback(result);
12299                    }, function() {
12300                        nominatimFallback();
12301                    });
12302                } else {
12303                    nominatimFallback();
12304                }
12305            },
12306
12307            _geocodeAddress: function(address, callback) {
12308                let me = this;
12309                var customUrl = me._getGeocodingUrl();
12310
12311                var tryGeocode = function(baseUrl, onSuccess, onFail) {
12312                    var url = baseUrl + '/search?format=json&q=' + encodeURIComponent(address);
12313                    fetch(url)
12314                        .then(function(response) { return response.json(); })
12315                        .then(function(data) {
12316                            if (data && data.length > 0) {
12317                                onSuccess(parseFloat(data[0].lat), parseFloat(data[0].lon));
12318                            } else {
12319                                onFail();
12320                            }
12321                        })
12322                        .catch(function() { onFail(); });
12323                };
12324
12325                var nominatimFallback = function() {
12326                    tryGeocode('https://nominatim.openstreetmap.org', function(lat, lng) {
12327                        callback(lat, lng);
12328                    }, function() {
12329                        tryGeocode('https://photon.komoot.io', function(lat, lng) {
12330                            callback(lat, lng);
12331                        }, function() {
12332                            callback(null, null);
12333                        });
12334                    });
12335                };
12336
12337                if (customUrl) {
12338                    tryGeocode(customUrl, function(lat, lng) {
12339                        callback(lat, lng);
12340                    }, function() {
12341                        nominatimFallback();
12342                    });
12343                } else {
12344                    nominatimFallback();
12345                }
12346            },
12347
12348	});			$.fbuilder.generate_form = function(fnum){
12349				try {
12350					var cp_calculatedfieldsf_fbuilder_config = window["cp_calculatedfieldsf_fbuilder_config"+fnum];
12351					if(
12352						cp_calculatedfieldsf_fbuilder_config &&
12353						$("#fbuilder"+fnum).length &&
12354						$("#fbuilder"+fnum).attr('data-processed') == undefined
12355					)
12356					{
12357                        if($("#fbuilder"+fnum).is(':visible') || false)
12358						{
12359							var f = $("#fbuilder"+fnum).fbuilder(( typeof cp_calculatedfieldsf_fbuilder_config.obj == 'string' ) ?  JSON.parse(cp_calculatedfieldsf_fbuilder_config.obj) : cp_calculatedfieldsf_fbuilder_config.obj );
12360							f.attr('data-processed', 1);
12361							f.fBuild.loadData("form_structure"+fnum);
12362						}
12363						else
12364						{
12365							$.fbuilder.form_become_visible(
12366								"#fbuilder"+fnum,
12367								(function(n){ return function(){
12368									$.fbuilder.generate_form(n);};
12369								})(fnum)
12370							);
12371						}
12372					}
12373				} catch (e) {if(typeof console != 'undefined') console.log(e);}
12374			}; // End generate_form
12375
12376			$.fbuilder.form_become_visible = function(element, callback){
12377				if(!('hidden_forms' in $.fbuilder)) $.fbuilder.hidden_forms = [];
12378				$.fbuilder.hidden_forms.push({'element':element, 'callback':callback});
12379
12380				if('form_become_visible_interval' in $.fbuilder) clearInterval($.fbuilder['form_become_visible_interval']);
12381
12382				$.fbuilder['form_become_visible_interval'] = setInterval(function(){
12383					for(var i = $.fbuilder.hidden_forms.length - 1; 0<=i; i--)
12384					{
12385						if($($.fbuilder.hidden_forms[i]['element']).is(':visible'))
12386						{
12387							$.fbuilder.hidden_forms[i]['callback'].call();
12388							$.fbuilder.hidden_forms.splice(i,1);
12389						}
12390					}
12391					if($.fbuilder.hidden_forms.length == 0) clearInterval($.fbuilder['form_become_visible_interval']);
12392				}, 500);
12393			}; // End form_become_visible
12394
12395		} // End if(!('fbuilder' in $))
12396
12397		var fcount = 1;
12398		var fnum = "_"+fcount;
12399
12400		while(typeof window["cp_calculatedfieldsf_fbuilder_config"+fnum] != 'undefined' || fcount < 10 )
12401		{
12402			$.fbuilder.generate_form(fnum);
12403			fcount++;
12404			fnum = "_"+fcount;
12405		}
12406	})(fbuilderjQuery);
12407};
12408fbuilderjQuery(fbuilderjQuery.fbuilderjQueryGenerator);
12409fbuilderjQuery(window).on('load',fbuilderjQuery.fbuilderjQueryGenerator);
12410
12411/* Elementor popup*/
12412fbuilderjQuery( document ).on( 'elementor/popup/show', function( event, id, instance ){
12413	var popup = fbuilderjQuery('[data-elementor-type="popup"]');
12414	if(popup.length){
12415		var psequence = popup.find('[name="cp_calculatedfieldsf_pform_psequence"]');
12416		if (psequence.length == 0) psequence = fbuilderjQuery('[name="cp_calculatedfieldsf_pform_psequence"]');
12417		var	fnum,flist;
12418		if(psequence.length){
12419			fnum = psequence.val();
12420			if(popup.find('#fieldlist'+fnum+':empty').length) {
12421				popup.find("#fbuilder"+fnum).removeAttr('data-processed');
12422				fbuilderjQuery.fbuilderjQueryGenerator();
12423			}
12424		}
12425	}
12426} );

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.