PageSourceSearch

https://www.vogido.nl/wp-content/themes/core-redesignsportlinkclub…/frontendediting-js.js?20181126111111

js vogido.nl collected 2026-10-09 22:42:12 UTC 444,042 bytes, 11,321 lines download raw bytes

1/*************************************************************************/
2/*************************************************************************/
3/*
4    Copyright 2012 Nexus Themes
5
6    This theme package is released under the the GNU Public License 2.0.
7*/
8/*************************************************************************/
9/*************************************************************************/
10
11var nxs_js_mapslazyloaded = false;
12var nxs_js_mapslazyloading = false;
13var nxs_js_maps = { };
14
15var nxs_js_panolazyloaded = false;
16var nxs_js_panolazyloading = false;
17var nxs_js_panos = { };
18
19var nxs_js_requirespagerefresh = false;
20var nxs_js_activeviewport = -1;
21
22var nxs_js_nxseditoractive = false;
23var nxs_js_editorstategrowltoken;
24
25var nxs_js_nxsmenuactive = true;
26var nxs_js_menustategrowltoken;
27
28var nxs_js_nxsisdragging = false;
29
30var nxs_js_runtimedimensionsrefreshtriggers = new Array();
31var nxs_js_queuedruntimedimensionsrefreshtriggers = new Array();
32var nxs_js_isruntimecssrefreshqueued = false;
33var nxs_js_isctrlkeydown = false;
34var nxs_js_seorefreshtriggers = { };
35var nxs_js_isseorefreshqueued = false;
36var nxs_js_vendorprefix_internal = null;
37
38var nxs_js_lazyloadedscripts = { };
39var nxs_js_lazyloadingscripts = { };
40var thickboxL10n;
41
42// scroll revert state (used to track pushing and popping of scroll positions)
43var nxs_js_scrollstatestack = { };
44var nxs_js_scrollstateidentifier = 0;
45
46var nxs_js_lazyloadinggrowl = false;
47var nxs_js_queuestatelookup = {};
48
49// see http://api.jquery.com/jQuery.browser/
50function nxs_js_getvendorprefix()
51{
52	if (nxs_js_vendorprefix_internal == null)
53	{
54		// derive it 1x
55		var browser = jQuery.browser;
56
57		//nxs_js_log(navigator.userAgent);
58
59		if (navigator.userAgent.indexOf("Opera") >= 0 || navigator.userAgent.indexOf("OPR") >= 0)
60		{
61			nxs_js_vendorprefix_internal = "o";
62		}
63		else if (browser.webkit == true)
64		{
65			nxs_js_vendorprefix_internal = "webkit";
66		}
67		else if (browser.msie)
68		{
69			nxs_js_vendorprefix_internal = "msie";
70		}
71		else if (navigator.userAgent.indexOf("Trident") > -1)
72    {
73    	// http://stackoverflow.com/questions/20911175/ie-11-browser-recognizes-itself-as-mozilla
74      nxs_js_vendorprefix_internal = "msie";
75    }
76		else if (browser.mozilla)
77		{
78			nxs_js_vendorprefix_internal = "mozilla";
79		}
80		else
81		{
82			nxs_js_vendorprefix_internal = "unknown";
83		}
84	}
85	return nxs_js_vendorprefix_internal;
86}
87
88// the popupsessiondata is empty initially.
89// by filling this variable from the client (js),
90// a state is constructed that is accessible by both the client (js) as well as
91// serverside (php). Values stored by the client are accessible in the upcoming
92// server post. By using the same keys as the variable names on the serverside,
93// its possible to create a temporary client side state, temporarily overriding
94// values persisted on the server side.
95// This state can be shared between multiple popup pages ("sheets").
96// This enables clients to even have a "cancel" button, wiping just only this
97// temporarily state, and not overriding persisted values if that was unwanted.
98var nxs_js_popupsessiondata = {};	// key values like dictionary
99
100// the shortscopedata is similar to popupsessiondata, difference is that the shortscopedata is wiped
101// so data in here is only available in the next server invocation and lost aftwards. This
102// can be used to store triggers/events such a specific event, that should not be persisted,
103// but only result in a certain server side invocation
104var nxs_js_shortscopedata = {};	// key values like dictionary
105
106// similar to popupsessiondata, difference is that this container contains information about
107// the meta data, like what sheet is being rendered and other contextual data.
108var nxs_js_popupsessioncontext = {};	// key values like dictionary
109var nxs_js_popupshows = false;
110
111var nxs_js_menuid_preventendlessloop;
112var nxs_js_menuid_siblingcounters;
113
114var nxs_js_alert_identifier = 0;
115
116jQuery(window).ready
117(
118	function()
119	{
120		thickboxL10n = { loadingAnimation: nxs_js_getframeworkurl() + "/images/loadingthickbox.png" };
121
122		nxs_js_tagviewports();
123		nxs_js_tagdevices();
124		nxs_js_tagbrowsers();
125		nxs_js_tagfrontendbackend();
126		nxs_js_tagresponsiveness();
127		// some images load slower than the jquery code is executed.
128		// in that case the screen needs to be realigned
129		nxs_js_reenable_all_window_events();
130		//
131		nxs_js_processquerystring();
132
133		// reload editor state, based on cookie
134		nxs_js_initiateeditorstate();
135
136		// reload menu state, based on cookie
137		nxs_js_initiatemenustate();
138
139		// no background scrolling when hovering over admin top menu
140		nxs_js_disabledocumentscrollwhenoveringoverelement("#vg_manualcss");
141
142		nxs_js_reenable_all_window_events();
143		nxs_js_register_windowresizedend_event();
144		nxs_js_hook_windowsresizeend_event();
145
146		nxs_js_setupwindowscrolllistener();
147		nxs_js_hook_windowsscrolled_event();
148		nxs_js_setupviewportlistener();
149
150
151		// after fonts are loaded, re-enable window events/ height-iq
152		jQuery(window).bind("load", function()
153		{
154			nxs_js_reenable_all_window_events();
155			// nice scroll
156			// $("html").niceScroll();
157		});
158
159		// see http://stackoverflow.com/questions/6677181/how-to-know-when-font-face-has-been-applied
160		document.onreadystatechange = function() {
161    if (document.readyState === 'complete')
162    {
163    	nxs_js_reenable_all_window_events();
164    }
165};
166
167	}
168);
169
170function disconnect_twitter()
171{
172    window.location.replace("/twitter/?twitter=disconnect");
173}
174
175function nxs_js_setupwindowscrolllistener()
176{
177	jQuery(window).scroll
178	(
179		function()
180		{
181			if(this.scrollTO) clearTimeout(this.scrollTO);
182		  this.scrollTO = setTimeout
183		  (
184		  	function()
185		  	{
186		  		jQuery(this).trigger('nxs_event_windowscrolled');
187		  	}
188		  	,
189		  	100
190		  );
191		}
192	);
193}
194
195// kudos to http://stackoverflow.com/questions/16323770/stop-page-from-scrolling-if-hovering-div
196function nxs_js_disabledocumentscrollwhenoveringoverelement(e)
197{
198	jQuery(e).on('DOMMouseScroll mousewheel', function(ev) {
199    var $this = $(this),
200        scrollTop = this.scrollTop,
201        scrollHeight = this.scrollHeight,
202        height = $this.height(),
203        delta = (ev.type == 'DOMMouseScroll' ?
204            ev.originalEvent.detail * -40 :
205            ev.originalEvent.wheelDelta),
206        up = delta > 0;
207
208    var prevent = function() {
209			ev.stopPropagation();
210			ev.preventDefault();
211			ev.returnValue = false;
212			return false;
213    }
214
215		var hovering_cat_list = jQuery('#selectedcategoryids').is(':hover');
216		if (hovering_cat_list) {
217			var cat_div = '#selectedcategoryids';
218			var cats_scrolltop = jQuery(cat_div).scrollTop();
219			var cats_height = jQuery(cat_div).height();
220			var cats_scrollHeight = jQuery(cat_div)[0].scrollHeight - cats_height;
221		}
222
223    if (!up && -delta > scrollHeight - height - scrollTop) {
224			if (hovering_cat_list && cats_scrolltop < cats_scrollHeight) {
225				// do not prevent
226			}
227			else {
228				// Scrolling down, but this will take us past the bottom.
229        $this.scrollTop(scrollHeight);
230        return prevent();
231			}
232    } else if (up && delta > scrollTop) {
233			if (hovering_cat_list && cats_scrolltop > 0) {
234				// do not prevent
235			}
236			else {
237				// Scrolling up, but this will take us past the top.
238	      $this.scrollTop(0);
239	      return prevent();
240			}
241    }
242});
243}
244
245// kudos to http://stackoverflow.com/questions/3885817/how-to-check-if-a-number-is-float-or-integer
246function nxs_js_isint(n)
247{
248   return typeof n === 'number' && parseFloat(n) == parseInt(n, 10) && !isNaN(n);
249}
250
251function showHideLazyLoadButtonArchive(widgetid, max_possible_posts) {
252	var num_posts_displayed = jQuery('.' + widgetid + ' .nxs-archiveentry').length;
253
254	if( num_posts_displayed >= max_possible_posts ) {
255		jQuery('.' +widgetid  + ' .load-more').hide();
256	}
257}
258
259function nxs_js_lazyloadmorearchives(domelement, max_possible_posts, order)
260{
261
262	// ensure no other lazy load occurs for this widget
263	if (jQuery(domelement).closest(".nxs-archiveentries").hasClass("nxs-lazyloadinprogress"))
264	{
265		// ignore
266		nxs_js_log("stop poking me!");
267		return;
268	}
269	jQuery(domelement).closest(".nxs-archiveentries").addClass("nxs-lazyloadinprogress");
270
271	// find widget in dom
272	var placeholderid = nxs_js_findclassidentificationwithprefix_closest(domelement, ".nxs-widget", "nxs-widget-");
273	var postcontainerid = nxs_js_getcontainerpostid();
274	var postid = nxs_js_findclassidentificationwithprefix_closest(domelement, ".nxs-elements-container", "nxs-post-");
275	var most_recent_page = parseInt(nxs_js_findclassidentificationwithprefix_closest(domelement, ".nxs-archiveentries", "nxs-paging-page-"));
276
277	//nxs_js_log("placeholderid:" + placeholderid);
278	//nxs_js_log("postid:" + postid);
279
280
281	var ajaxurl = nxs_js_get_adminurladminajax();
282	jQuery.ajax
283	(
284		{
285			type: 'POST',
286			data:
287			{
288				"action": "nxs_ajax_webmethods",
289				"webmethod": "lazyloadarchive",
290				"postcontainerid": postcontainerid,
291				"postid": postid,
292				"paging_page": most_recent_page + 1,
293				"placeholderid": placeholderid,
294				"clientqueryparameters": nxs_js_escaped_getqueryparametervalues()
295			},
296			cache: false,
297			dataType: 'JSON',
298			url: ajaxurl,
299			success: function(response)
300			{
301				nxs_js_log(response);
302				if (response.result == "OK")
303				{
304					// update page
305					jQuery(domelement).closest(".nxs-archiveentries").removeClass("nxs-paging-page-" + most_recent_page);
306					jQuery(domelement).closest(".nxs-archiveentries").addClass("nxs-paging-page-" + most_recent_page + 1);
307
308				 	var html = response.appendhtmlraw.html;
309
310				 	var widgetid = response.appendhtmlraw.replacedomid;
311				 	var widget = jQuery("#" + widgetid);
312				 	var lastarchiveentryinwidget = jQuery(widget).find(".nxs-archiveentry").last();
313					var lastArchiveEntryDate = jQuery(lastarchiveentryinwidget).attr("date");
314					var array = [];
315					jQuery("body").append("<div id='lazyloadtemp' style='display: none;'>" + html + "</div>");
316
317					// replicate the ".blog-entry" from the temp place to the widget
318					jQuery("#lazyloadtemp").find(".nxs-archiveentry").each(function(i) {
319							array.push(this);
320					});
321
322					if(order == "DESC") {
323						jQuery(array).sort(function(a,b) {
324							return new Date($(a).attr("data-date")) < new Date($(b).attr("data-date"));
325						}).each(function(){
326								jQuery(this).appendTo(".entries-wrap-archive");
327						});
328					}
329
330					// cleanup the scaffolding
331					jQuery("#lazyloadtemp").remove();
332
333					// update the heights
334					nxs_gui_set_runtime_dimensions_enqueuerequest("lazyloadarchive");
335					// fast forward; we don't have to wait till the queue is empty, as its not
336					// likely other events occur at the same time
337					nxs_gui_set_runtime_dimensions_actualrequest();
338
339					// ensure that each img that finishes loading after we set the runtime
340					// dimensions will trigger the runtime dimensions to be recalculated...
341					jQuery('img').load
342					(
343						function()
344						{
345							//nxs_js_log('debug; finished loading img after reenabling all windows events; solved bug');
346							nxs_gui_set_runtime_dimensions_enqueuerequest("nxs-framework-imgloaded");
347						}
348					);
349
350					// update the paging page nr
351					nxs_js_log("most recent was:" + most_recent_page);
352					//
353
354					// instruct the comments to be reloaded
355					if (typeof nxs_js_refreshdisquscount_throttled == 'function')
356					{
357						nxs_js_refreshdisquscount_throttled();
358					}
359					else
360					{
361						//
362					}
363					showHideLazyLoadButtonArchive(widgetid, max_possible_posts);
364				}
365				else
366				{
367					nxs_js_popup_notifyservererror_v2(response);
368				}
369
370				// release the "lock"
371				jQuery(domelement).closest(".nxs-archiveentries").removeClass("nxs-lazyloadinprogress");
372			},
373			error: function(xhr, ajaxOptions, thrownError)
374			{
375				// an error could occur if the user redirects before this operation is completed
376				nxs_js_popup_notifyservererror_v2(thrownError);
377
378				// release the "lock"
379				jQuery(domelement).closest(".nxs-archiveentries").removeClass("nxs-lazyloadinprogress");
380			}
381		}
382	);
383}
384
385function showHideLazyLoadButton(widgetid, max_possible_posts) {
386	var num_posts_displayed = jQuery('.' + widgetid + ' .nxs-blogentry').length;
387
388	if( num_posts_displayed >= max_possible_posts ) {
389		jQuery('.' +widgetid  + ' .load-more').hide();
390	}
391}
392
393function nxs_js_lazyloadmoreblogs(domelement, max_possible_posts, order, unique_id) {
394
395	// ensure no other lazy load occurs for this widget
396	if (jQuery(domelement).closest(".nxs-blogentries").hasClass("nxs-lazyloadinprogress"))
397	{
398		// ignore
399		nxs_js_log("stop poking me!");
400		return;
401	}
402	jQuery(domelement).closest(".nxs-blogentries").addClass("nxs-lazyloadinprogress");
403
404	// find widget in dom
405	var placeholderid = nxs_js_findclassidentificationwithprefix_closest(domelement, ".nxs-widget", "nxs-widget-");
406	var postcontainerid = nxs_js_getcontainerpostid();
407	var postid = nxs_js_findclassidentificationwithprefix_closest(domelement, ".nxs-elements-container", "nxs-post-");
408	var most_recent_page = parseInt(nxs_js_findclassidentificationwithprefix_closest(domelement, ".nxs-blogentries", "nxs-paging-page-"));
409
410	//nxs_js_log("placeholderid:" + placeholderid);
411	//nxs_js_log("postid:" + postid);
412
413
414	var ajaxurl = nxs_js_get_adminurladminajax();
415	jQuery.ajax
416	(
417		{
418			type: 'POST',
419			data:
420			{
421				"action": "nxs_ajax_webmethods",
422				"webmethod": "lazyloadblog",
423				"postcontainerid": postcontainerid,
424				"postid": postid,
425				"paging_page": most_recent_page + 1,
426				"placeholderid": placeholderid,
427				"clientqueryparameters": nxs_js_escaped_getqueryparametervalues()
428			},
429			cache: false,
430			dataType: 'JSON',
431			url: ajaxurl,
432			success: function(response)
433			{
434				console.log({
435					"action": "nxs_ajax_webmethods",
436					"webmethod": "lazyloadblog",
437					"postcontainerid": postcontainerid,
438					"postid": postid,
439					"paging_page": most_recent_page + 1,
440					"placeholderid": placeholderid,
441					"clientqueryparameters": nxs_js_escaped_getqueryparametervalues()
442				});
443				console.log(response);
444				//nxs_js_log(response);
445				if (response.result == "OK")
446				{
447					// update page
448					jQuery(domelement).closest(".nxs-blogentries").removeClass("nxs-paging-page-" + most_recent_page);
449					jQuery(domelement).closest(".nxs-blogentries").addClass("nxs-paging-page-" + most_recent_page + 1);
450
451				 	var html = response.appendhtmlraw.html;
452
453				 	var widgetid = response.appendhtmlraw.replacedomid;
454				 	var widget = jQuery("#" + widgetid);
455				 	var lastblogentryinwidget = jQuery(widget).find(".nxs-blogentry").last();
456					var lastBlogEntryDate = jQuery(lastblogentryinwidget).attr("date");
457					var array = [];
458					jQuery("body").append("<div id='lazyloadtemp' style='display: none;'>" + html + "</div>");
459
460					// replicate the ".blog-entry" from the temp place to the widget
461					jQuery("#lazyloadtemp").find(".nxs-blogentry").each(function(i) {
462							array.push(this);
463					});
464
465					if(order == "DESC") {
466						jQuery(array).sort(function(a,b) {
467							return new Date($(a).attr("data-date")) < new Date($(b).attr("data-date"));
468						}).each(function(){
469								jQuery(this).appendTo(".entries-wrap-" + unique_id);
470						});
471					}
472
473					// cleanup the scaffolding
474					jQuery("#lazyloadtemp").remove();
475
476					// update the heights
477					nxs_gui_set_runtime_dimensions_enqueuerequest("lazyloadblog");
478					// fast forward; we don't have to wait till the queue is empty, as its not
479					// likely other events occur at the same time
480					nxs_gui_set_runtime_dimensions_actualrequest();
481
482					// ensure that each img that finishes loading after we set the runtime
483					// dimensions will trigger the runtime dimensions to be recalculated...
484					jQuery('img').load
485					(
486						function()
487						{
488							//nxs_js_log('debug; finished loading img after reenabling all windows events; solved bug');
489							nxs_gui_set_runtime_dimensions_enqueuerequest("nxs-framework-imgloaded");
490						}
491					);
492
493					// update the paging page nr
494					nxs_js_log("most recent was:" + most_recent_page);
495					//
496
497					// instruct the comments to be reloaded
498					if (typeof nxs_js_refreshdisquscount_throttled == 'function')
499					{
500						nxs_js_refreshdisquscount_throttled();
501					}
502					else
503					{
504						//
505					}
506					showHideLazyLoadButton(widgetid, max_possible_posts);
507				}
508				else
509				{
510					nxs_js_popup_notifyservererror_v2(response);
511				}
512
513				// release the "lock"
514				jQuery(domelement).closest(".nxs-blogentries").removeClass("nxs-lazyloadinprogress");
515			},
516			error: function(xhr, ajaxOptions, thrownError)
517			{
518				// an error could occur if the user redirects before this operation is completed
519				nxs_js_popup_notifyservererror_v2(thrownError);
520
521				// release the "lock"
522				jQuery(domelement).closest(".nxs-blogentries").removeClass("nxs-lazyloadinprogress");
523			}
524		}
525	);
526}
527
528// kudos to http://stackoverflow.com/questions/123999/how-to-tell-if-a-dom-element-is-visible-in-the-current-viewport
529function nxs_js_iselementinviewport(el)
530{
531  var rect = el.getBoundingClientRect();
532
533  nxs_js_log(rect);
534
535  return
536  (
537      rect.top >= 0 &&
538      rect.left >= 0 &&
539      rect.bottom <= (window.innerHeight || document. documentElement.clientHeight) && /*or jQuery(window).height() */
540      rect.right <= (window.innerWidth || document. documentElement.clientWidth) /*or jQuery(window).width() */
541  );
542}
543
544// kudos to http://stackoverflow.com/questions/123999/how-to-tell-if-a-dom-element-is-visible-in-the-current-viewport
545function nxs_js_iselementaboveviewport(el)
546{
547  var rect = el.getBoundingClientRect();
548	var result = rect.top <= 0;
549  return result;
550}
551
552// kudos to http://stackoverflow.com/questions/123999/how-to-tell-if-a-dom-element-is-visible-in-the-current-viewport
553function nxs_js_iselementabovepieceofviewport(el, piece)
554{
555	var viewportheight = jQuery(window).height();
556	var halfviewportheight = viewportheight / piece;
557  var rect = el.getBoundingClientRect();
558	var result = rect.top <= halfviewportheight;
559  return result;
560}
561
562function nxs_js_ui_pushscrollrevert()
563{
564	nxs_js_scrollstateidentifier++;
565	var value = { 'scrolltop' : jQuery(window).scrollTop(), 'height' : jQuery(window).height() };
566	/*
567	nxs_js_log('orig scroll pos:');
568	nxs_js_log(value.scrolltop);
569	nxs_js_log('orig height:');
570	nxs_js_log(value.height);
571	*/
572	nxs_js_scrollstatestack[nxs_js_scrollstateidentifier] = value;
573	return nxs_js_scrollstateidentifier;
574}
575
576function nxs_js_ui_popscrollrevert(scrollstateidentifier)
577{
578	var orig = nxs_js_scrollstatestack[nxs_js_scrollstateidentifier];
579	jQuery(window).scrollTop(orig.scrolltop);
580}
581
582function nxs_js_stringisblank(str)
583{
584	// kudos to http://stackoverflow.com/questions/154059/how-do-you-check-for-an-empty-string-in-javascript
585  return (!str || /^\s*$/.test(str));
586}
587
588function nxs_js_stringcontains(haystack, needle)
589{
590	return haystack.indexOf(needle) > -1;
591}
592
593function nxs_js_mailchimpsubmit(domelement)
594{
595	var placeholder = jQuery(domelement).closest(".nxs-placeholder");
596	var submitbutton = jQuery(placeholder).find("input[type=submit]");
597	jQuery(submitbutton).click();
598}
599
600function nxs_js_processquerystring()
601{
602	var nxs_onpageload = nxs_js_getqueryparametervalue("nxs_onpageload")
603	if (nxs_onpageload != '')
604	{
605		var nxs_onpageload_splitted = nxs_onpageload.split("_");
606		var action = nxs_onpageload_splitted[0];
607		if (action == 'editwidget')
608		{
609			if (nxs_js_nxseditoractive)
610			{
611				var postid = nxs_onpageload_splitted[1];
612				var placeholderid = nxs_onpageload_splitted[2];
613				var domelementinwidget = jQuery('.nxs-post-' + postid + ' #nxs-widget-' + placeholderid);
614				nxs_js_edit_widget(domelementinwidget);
615			}
616			else
617			{
618				// skip
619			}
620		}
621		else
622		{
623			nxs_js_log('unsupported action;' + action);
624		}
625	}
626	else
627	{
628		// no onpageload
629		//nxs_js_log('no onpageload')
630	}
631}
632
633function nxs_js_escaped_getqueryparametervalues()
634{
635	return nxs_js_getescapeddictionary(nxs_js_getqueryparametervalues());
636}
637
638// kudos to http://stackoverflow.com/questions/6539761/window-location-search-query-as-json
639function nxs_js_getqueryparametervalues()
640{
641  var pairs = window.location.search.substring(1).split("&"),
642    obj = {},
643    pair,
644    i;
645
646  for ( i in pairs ) {
647    if ( pairs[i] === "" ) continue;
648
649    pair = pairs[i].split("=");
650    obj[ decodeURIComponent( pair[0] ) ] = decodeURIComponent( pair[1] );
651  }
652
653	// nxs_js_log(obj);
654
655  return obj;
656}
657
658// kudos to http://stackoverflow.com/questions/901115/how-can-i-get-query-string-values
659function nxs_js_getqueryparametervalue(name)
660{
661  name = name.replace(/[\[]/, "\\\[").replace(/[\]]/, "\\\]");
662  var regexS = "[\\?&]" + name + "=([^&#]*)";
663  var regex = new RegExp(regexS);
664  var results = regex.exec(window.location.search);
665  if(results == null)
666    return "";
667  else
668    return decodeURIComponent(results[1].replace(/\+/g, " "));
669}
670
671function nxs_js_hook_windowsscrolled_event()
672{
673	jQuery(window).bind
674	(
675		'nxs_event_windowscrolled',
676		function()
677		{
678			// nxs_js_log('receiving nxs_event_windowscrolled event');
679
680			// todo: make treshhold configurable by theme/plugin
681
682			var windowscrolltop = jQuery(window).scrollTop();
683			var windowheight = jQuery(window).height();
684			var documentheight = jQuery(document).height();
685			treshhold = windowheight * 0.5;	// 50% scherm hoogte
686
687			if(windowscrolltop + windowheight + treshhold >= documentheight)
688			{
689		   	jQuery(this).trigger('nxs_event_windowscrolledbottom');
690			}
691		}
692	);
693}
694
695function nxs_js_hook_windowsresizeend_event()
696{
697	// nxs_js_log('hooked to nxs_event_resizeend');
698
699	jQuery(window).bind
700	(
701		'nxs_event_resizeend',
702		function()
703		{
704			// nxs_js_log('receiving nxs_event_resizeend event');
705
706			nxs_js_tagviewports();
707	    nxs_gui_set_runtime_dimensions_enqueuerequest('nxs-framework-windowresized');
708			nxs_js_reset_popup_dimensions();
709		}
710	);
711}
712
713function nxs_js_hook_windowsresizeend_event()
714{
715	// nxs_js_log('hooked to nxs_event_scrolled');
716
717	jQuery(window).bind
718	(
719		'nxs_event_resizeend',
720		function()
721		{
722			// nxs_js_log('receiving nxs_event_resizeend event');
723
724			nxs_js_tagviewports();
725	    nxs_gui_set_runtime_dimensions_enqueuerequest('nxs-framework-windowresized');
726			nxs_js_reset_popup_dimensions();
727		}
728	);
729}
730
731// kudos to http://stackoverflow.com/questions/2996431/detect-when-a-window-is-resized-using-javascript and
732// plus IE8 fix; IE8 fires windowsresized if any element is resized
733// http://stackoverflow.com/questions/1852751/window-resize-event-firing-in-internet-explorer
734function nxs_js_register_windowresizedend_event()
735{
736	//variables to confirm window height and width
737  var lastWindowHeight = jQuery(window).height();
738  var lastWindowWidth = jQuery(window).width();
739
740  jQuery(window).resize(function()
741  {
742    //confirm window was actually resized
743    if(jQuery(window).height()!=lastWindowHeight || jQuery(window).width()!=lastWindowWidth)
744    {
745      //set this windows size
746      lastWindowHeight = jQuery(window).height();
747      lastWindowWidth = jQuery(window).width();
748
749      // nxs_js_log('jquery resize event detected');
750
751		  if(this.resizeTO) clearTimeout(this.resizeTO);
752		  this.resizeTO = setTimeout
753		  (
754		  	function()
755		  	{
756		  		jQuery(this).trigger('nxs_event_resizeend');
757		  	}
758		  	,
759		  	250
760		  );
761    }
762  });
763}
764
765// function that exposes outerhtml property
766jQuery.fn.outerHTML = function(s)
767{
768	return s
769    ? this.before(s).remove()
770    : jQuery("<p>").append(this.eq(0).clone()).html();
771};
772
773// the 'startsWith' function is added to string objects
774if (typeof String.prototype.startsWith != 'function')
775{
776	String.prototype.startsWith = function (str)
777	{
778  	return this.indexOf(str) == 0;
779	};
780}
781
782// kudos to http://stackoverflow.com/questions/5999998/how-can-i-check-if-a-javascript-variable-is-function-type
783function nxs_js_isfunction(functionToCheck) {
784 var getType = {};
785 return functionToCheck && getType.toString.call(functionToCheck) === '[object Function]';
786}
787
788function nxs_js_lazyexecute(scripturl, prependframeworkurl, functiontoinvoke)
789{
790	// ensure functiontoinvoke contains a "(" (parenthesis)
791	// otherwise the invocation will fail without the developer
792	// having a clue about what's wrong
793	if (nxs_js_isfunction(functiontoinvoke))
794	{
795	}
796	else if (!nxs_js_stringcontains(functiontoinvoke, "(") || !nxs_js_stringcontains(functiontoinvoke, ")"))
797	{
798		nxs_js_alert("parenthesis not found, use foo(), not foo");
799	}
800
801	//nxs_js_log("lazy executing:");
802
803	if (prependframeworkurl)
804	{
805		scripturl = nxs_js_getframeworkurl() + scripturl;
806	}
807
808	//nxs_js_log(scripturl);
809	//nxs_js_log(functiontoinvoke);
810
811	nxs_js_requirescript
812	(
813		scripturl,	// id == scripturl
814		"js", 	// must be js
815		scripturl, // url
816		function()
817		{
818			if (nxs_js_isfunction(functiontoinvoke))
819			{
820				functiontoinvoke();
821			}
822			else
823			{
824				eval(functiontoinvoke);
825			}
826		}
827	);
828}
829
830// ensure the specified css or js script is injected
831function nxs_js_requirescript(scriptid, scripttype, scripturl, scriptcallbackafterload)
832{
833	if (scriptcallbackafterload == null)
834	{
835		nxs_js_alert("warning; loading scriptid; " + scriptid + "; no scriptcallbackafterload set?");
836	}
837
838	if (!nxs_js_isscriptlazyloaded(scriptid) && !nxs_js_isscriptlazyloading(scriptid))
839	{
840		var waitgrowltoken = -1; // nxs_js_alert_wait_start(nxs_js_gettrans("Loading script"));
841
842		// nxs_js_log('processing script:' + scriptid);
843
844		// markeer dat we deze nu aan het inladen zijn...
845		nxs_js_lazyloadingscripts[scriptid] = true;
846		var w = window;
847
848		var d = w.document;
849		var script;
850
851		if (scripttype == "js")
852		{
853			script = d.createElement('script');
854			script.setAttribute("type","text/javascript")
855  		script.setAttribute('src', scripturl);
856		}
857		else if (scripttype == "css")
858		{
859			script = d.createElement('link');
860		 	script.setAttribute("rel", "stylesheet")
861  		script.setAttribute("type", "text/css")
862  		script.setAttribute("href", scripturl);
863		}
864
865		// set callback for errors, note this is not compatible with
866		// all browsers; see http://www.quirksmode.org/dom/events/error.html
867		script.onerror = function()
868		{
869			nxs_js_alert_wait_finish(waitgrowltoken);
870			nxs_js_alert('Error loading resource (script/css); '+ scripturl);
871		}
872
873		// set callback function to execute when script is succesfully loaded
874		// regular browsers
875		script.onload = function()
876		{
877			nxs_js_alert_wait_finish(waitgrowltoken);
878			nxs_js_lazyloadedscripts[scriptid] = true;
879			nxs_js_lazyloadingscripts[scriptid] = false;
880			if (scriptcallbackafterload != null)
881			{
882				// nxs_js_log('executing... non-ie (fresh)');
883				scriptcallbackafterload();
884			}
885			else
886			{
887				// nxs_js_log('executing... nothing to execute');
888			}
889		}
890		// for ie browsers
891		script.onreadystatechange = function()
892		{
893			// nxs_js_log('finished loading (IE)');
894
895			if (this.readyState == 'complete' || this.readyState == 'loaded')
896			{
897				nxs_js_alert_wait_finish(waitgrowltoken);
898				nxs_js_lazyloadedscripts[scriptid] = true;
899				nxs_js_lazyloadingscripts[scriptid] = false;
900				if (scriptcallbackafterload != null)
901				{
902					scriptcallbackafterload();
903				}
904			}
905		}
906
907		//document.head.appendChild(script);
908		document.getElementsByTagName("head")[0].appendChild(script);
909		//d.documentElement.firstChild.appendChild(script);
910		//nxs_js_log('script done');
911	}
912	else
913	{
914		// nxs_js_log('skipping (either already queued or already loaded)');
915		if (scriptcallbackafterload != null)
916		{
917			// nxs_js_log('executing... (already)');
918			scriptcallbackafterload();
919		}
920	}
921}
922
923// checks if the specified script has finished loading
924function nxs_js_isscriptlazyloaded(scriptid)
925{
926	for (var currentscriptid in nxs_js_lazyloadedscripts)
927	{
928		if (currentscriptid == scriptid)
929		{
930			return true;
931		}
932	}
933	return false;
934}
935
936// check if the specifiekd script is currently loading
937function nxs_js_isscriptlazyloading(scriptid)
938{
939	for (var currentscriptid in nxs_js_lazyloadingscripts)
940	{
941		if (currentscriptid == scriptid)
942		{
943			return true;
944		}
945	}
946	return false;
947}
948
949function nxs_js_log(s)
950{
951	if ('console' in self && 'log' in console)
952	{
953		console.log(s);
954		var stacktrace = nxs_js_getqueryparametervalue("stacktrace");
955		if (nxs_js_isctrlkeydown || stacktrace != "")
956		{
957			// practical debug tool; if ctrl is pressed, output the stacktrac
958			try { throw new Error("Stracktrace"); } catch (e) { console.log(e.stack); }
959		}
960	}
961}
962
963function nxs_js_getstacktrace()
964{
965	var result;
966	try { throw new Error("Stracktrace"); } catch (e) { result = e.stack; }
967	return result;
968}
969
970function nxs_js_isemptyorwhitespace(value)
971{
972	return /^\s*$/.test(value);
973}
974
975function nxs_js_validateemail(elementValue)
976{
977	var emailPattern = /^[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}$/;
978	return emailPattern.test(elementValue);
979}
980
981function nxs_js_popupsession_startnewcontext()
982{
983	// note! shortscope data remains!
984	nxs_js_popupsession_data_clear();
985	nxs_js_popupsession_context_clear();
986
987	//nxs_js_log('context cleared!');
988	//nxs_js_log(nxs_js_getstacktrace());
989
990	// each request always passes the #2389724
991	nxs_js_popup_setsessioncontext("urlencodedjsonencodedquery_vars", nxs_js_geturlencodedjsonencodedquery_vars());
992}
993
994// voids all variables existing in the existing popup session
995function nxs_js_popupsession_data_clear()
996{
997	nxs_js_popupsessiondata = {};	// key values like dictionary
998}
999
1000function nxs_js_popupsession_data_remove_key(key)
1001{
1002	delete nxs_js_popupsessiondata[key];
1003}
1004
1005function nxs_js_popupsession_context_clear()
1006{
1007	nxs_js_popupsessioncontext = {};	// key values like dictionary
1008}
1009
1010// see nxs_urldecodearrayvalues($array) for the php invert function :)
1011// note its a BEST practise to UNescape properties in the webservices.php
1012// file (here: *426759487653456), to prevent replications or mistakes in detailed code
1013// 20131112; note we can not use the escape() function here, as escape() doesn't replace + signs
1014// (it works 99%, not 100%)
1015function nxs_js_getescapeddictionary(input)
1016{
1017	var escaped = {};
1018	for (var x in input)
1019  {
1020  	var waarde = input[x];
1021  	escaped[x] = encodeURIComponent(waarde);
1022  	/*
1023  	if (escaped[x] != waarde)
1024  	{
1025  		nxs_js_log("delta found");
1026  		nxs_js_log(escaped[x]);
1027  		nxs_js_log(waarde);
1028  	}
1029  	*/
1030  }
1031	return escaped;
1032}
1033
1034// ------------------------------------------------------------------------------------
1035// popup session functions
1036// note that the session of a popup page 'lives' while the user interacts
1037// with one or subsequent popup pages. Its a clientside state of the properties
1038// used between popup (ajax) refreshes.
1039
1040// returns all (escaped) variables of the session of the popup page
1041function nxs_js_getescaped_popupsession_data()
1042{
1043	return nxs_js_getescapeddictionary(nxs_js_popupsessiondata);
1044}
1045
1046function nxs_js_getescaped_popupsession_context()
1047{
1048	return nxs_js_getescapeddictionary(nxs_js_popupsessioncontext);
1049}
1050
1051// gets the value corresponding the specified key from the session of the popup page
1052function nxs_js_popup_getsessiondata(key)
1053{
1054	return nxs_js_popupsessiondata[key];
1055}
1056
1057// stores a value for the specified key in the session of the popup page
1058function nxs_js_popup_setsessiondata(key, val)
1059{
1060	nxs_js_popupsessiondata[key] = val;
1061}
1062
1063function nxs_js_popup_getsessioncontext(key)
1064{
1065	return nxs_js_popupsessioncontext[key];
1066}
1067
1068function nxs_js_popup_setsessioncontext(key, val)
1069{
1070	nxs_js_popupsessioncontext[key] = val;
1071}
1072
1073// a generic implementation that handles when the popup becomes 'dirty' for the first time
1074function nxs_js_popup_handle_becomes_dirty_first_time()
1075{
1076	if (jQuery('#nxs_popup_genericsavebutton').length > 0)
1077	{
1078		jQuery('#nxs_popup_genericsavebutton').show();
1079	}
1080	else
1081	{
1082		nxs_js_log("info: no generic popup save button found");
1083	}
1084
1085	if (jQuery('#nxs_popup_genericcancelbutton').length > 0)
1086	{
1087		jQuery('#nxs_popup_genericcancelbutton').show();
1088	}
1089	else
1090	{
1091		// nxs_js_log("no generic popup cancel button found?");
1092	}
1093
1094	if (jQuery('#nxs_popup_genericokbutton').length > 0)
1095	{
1096		jQuery('#nxs_popup_genericokbutton').hide();
1097	}
1098	else
1099	{
1100		// nxs_js_log("no generic popup ok button found?");
1101	}
1102}
1103
1104//
1105function nxs_js_popup_clearshortscopedata()
1106{
1107	nxs_js_shortscopedata = {};	// key values like dictionary
1108}
1109
1110function nxs_js_popup_getescapedshortscopedata()
1111{
1112	return nxs_js_getescapeddictionary(nxs_js_shortscopedata);
1113}
1114
1115function nxs_js_popup_setshortscopedata(key, val)
1116{
1117	nxs_js_shortscopedata[key] = val;
1118}
1119
1120function nxs_js_popup_getshortscopedata(key)
1121{
1122	return nxs_js_shortscopedata[key];
1123}
1124
1125function nxs_js_doeskeycodemakedirty(e)
1126{
1127	var result = true;
1128
1129	if (e.keyCode == 9)
1130	{
1131		// tab will not make dirty
1132		result = false;
1133	}
1134	else if (e.keyCode >= 16 && e.keyCode <= 18)
1135	{
1136		// shift will not make dirty
1137		// control will not make dirty
1138		// alt will not make dirty
1139		result = false;
1140	}
1141	else if (e.keyCode == 20)
1142	{
1143		// capslock
1144		result = false;
1145	}
1146	else if (e.keyCode == 27)
1147	{
1148		//nxs_js_log('detected esc');
1149
1150		// this closes the popup; do not mark it as dirty in this case
1151		result = false;
1152	}
1153	else if (e.keyCode >= 33 && e.keyCode <= 45)
1154	{
1155		// page up will not make dirty
1156		// page down, end, home, arrow left, up, right, down, printscreen, insert will not make dirty
1157		result = false;
1158	}
1159	else if (e.keyCode >= 112 && e.keyCode <= 123)
1160	{
1161		// f1 t/m f12 will not make dirty
1162		result = false;
1163	}
1164
1165	return result;
1166}
1167
1168function nxs_js_popup_processautodirtyhandling()
1169{
1170	// also handle pasting values
1171	jQuery(".nxs-popup-dyncontentcontainer input").unbind("input propertychange.makedirty");
1172	jQuery(".nxs-popup-dyncontentcontainer input").bind("input propertychange.makedirty", function(e)
1173	{
1174		nxs_js_popup_sessiondata_make_dirty();
1175	});
1176
1177	//nxs_js_log('nxs_js_popup_processautodirtyhandling');
1178
1179	jQuery(".nxs-popup-dyncontentcontainer input").unbind("keyup.makedirty");
1180	jQuery(".nxs-popup-dyncontentcontainer input").bind("keyup.makedirty", function(e)
1181	{
1182		if (nxs_js_doeskeycodemakedirty(e))
1183		{
1184  		nxs_js_popup_sessiondata_make_dirty();
1185  	}
1186	});
1187
1188	jQuery(".nxs-popup-dyncontentcontainer input").unbind("change.makedirty");
1189	jQuery(".nxs-popup-dyncontentcontainer input").bind("change.makedirty", function(e)
1190	{
1191		nxs_js_popup_sessiondata_make_dirty();
1192	});
1193
1194	jQuery(".nxs-popup-dyncontentcontainer select").unbind("change.makedirty");
1195	jQuery(".nxs-popup-dyncontentcontainer select").bind("change.makedirty", function(e)
1196	{
1197		nxs_js_popup_sessiondata_make_dirty();
1198	});
1199
1200	jQuery(".nxs-popup-dyncontentcontainer textarea").unbind("keyup.makedirty");
1201	jQuery(".nxs-popup-dyncontentcontainer textarea").bind("keyup.makedirty", function(e)
1202	{
1203		if (nxs_js_doeskeycodemakedirty(e))
1204		{
1205  		nxs_js_popup_sessiondata_make_dirty();
1206  	}
1207	});
1208}
1209
1210// makedirty
1211function nxs_js_popup_sessiondata_make_dirty()
1212{
1213	if (nxs_js_popup_getsessiondata('nxs_genericdirty') == 'true')
1214	{
1215		// was already dirty
1216	}
1217	else
1218	{
1219		nxs_js_popup_setsessiondata('nxs_genericdirty', 'true');
1220		nxs_js_popup_handle_becomes_dirty_first_time();
1221	}
1222}
1223
1224function nxs_js_popup_sessiondata_clear_dirty()
1225{
1226	nxs_js_popup_setsessiondata('nxs_genericdirty', '');
1227}
1228
1229function nxs_js_popup_sessiondata_is_dirty()
1230{
1231	if (nxs_js_popup_getsessiondata('nxs_genericdirty') == 'true')
1232	{
1233		return true;
1234	}
1235	else
1236	{
1237		return false;
1238	}
1239}
1240
1241function nxs_js_popup_refresh_keep_focus(element)
1242{
1243	if (element != undefined)
1244	{
1245		nxs_js_popup_setshortscopedata('elementidlastfocussed', jQuery(element).attr('id'));
1246		//nxs_js_log('focus was set on ' + nxs_js_popup_getshortscopedata('elementidlastfocussed'));
1247	}
1248	else
1249	{
1250		nxs_js_log('warning; no element specified to reset focus to');
1251	}
1252	nxs_js_popup_refresh();
1253}
1254
1255//
1256// practical function to reload current pop up page
1257// refresh is based upon the variables that are set
1258// when popup is navigate to another page
1259// use this function after setting a variable like a pagenumber in
1260// paging, requiring the current popup page to refresh
1261//
1262function nxs_js_popup_refresh()
1263{
1264	nxs_js_popup_refresh_v2(true);
1265}
1266
1267function nxs_js_popup_refresh_v2(shouldgrowl)
1268{
1269	// get rid of existing popup
1270	nxs_js_teardownpopupdom();
1271
1272	var sheet = nxs_js_popup_getcurrentsheet();
1273	nxs_js_popup_navigateto_v2(sheet, shouldgrowl);
1274}
1275
1276//
1277// returns the name of the current popup box that is showing
1278//
1279function nxs_js_popup_getcurrentsheet()
1280{
1281	var result = nxs_js_popup_getsessioncontext("sheet");
1282	return result;
1283}
1284
1285function nxs_js_popup_setcurrentsheet(sheet)
1286{
1287	nxs_js_popup_setsessioncontext("sheet", sheet);
1288}
1289
1290function postImageAndRedirect(imageId, redirectUrl) {
1291	var form = document.createElement("form");
1292	form.setAttribute("method", "POST");
1293	form.setAttribute("action", redirectUrl);
1294
1295	var params = {imageId: imageId};
1296	for(var key in params) {
1297		if(params.hasOwnProperty(key)) {
1298			var hiddenField = document.createElement("input");
1299			hiddenField.setAttribute("type", "hidden");
1300			hiddenField.setAttribute("name", key);
1301			hiddenField.setAttribute("value", params[key]);
1302
1303			form.appendChild(hiddenField);
1304		}
1305	}
1306
1307	document.body.appendChild(form);
1308	form.submit();
1309	return false;
1310}
1311
1312function nxs_js_pop_resetdynamiccontentcontainer()
1313{
1314	var initialvalue = "";
1315	// inject javascript / reset functies
1316	// dit zorgt ervoor dat popups standaard op basis van een 'auto'
1317	// gedrag worden gepositioneerd (vertikaal gecentreerd).
1318	// Indien gewenst kan een placeholder deze functie later opnieuw
1319	// overschrijven (override / overriden / overridden) waardoor het gedrag kan afwijken.
1320	initialvalue += "<" + "script type='text/javascript'>";
1321	initialvalue += "function nxs_js_overrule_topmargin() { return 'auto'; }";
1322	initialvalue += "function nxs_js_execute_after_popup_shows() { }";
1323	initialvalue += "function nxs_js_execute_before_popup_closes() { }";
1324	initialvalue += "function nxs_js_popup_get_initialbuttonstate() { return 'showokifnotdirty'; }";
1325	initialvalue += "function nxs_js_popup_get_minwidth() { return 750; }";
1326	initialvalue += "function nxs_js_popup_get_maxwidth() { return 1000; }";
1327	initialvalue += "function nxs_js_popup_get_maxheight() { var contentheight = jQuery('.nxs-popup-content-canvas').height(); var maxheight = Math.round(jQuery(window).height() * 0.8); if (maxheight > contentheight) { maxheight = contentheight; } return maxheight; }";
1328	initialvalue += "function nxs_js_showwarning_when_trying_to_close_dirty_popup() { return true; }";
1329	initialvalue += "<" + "/script>";
1330
1331	// inject initial value to the container
1332	jQuery('.nxs-popup-dyncontentcontainer').html(initialvalue);
1333}
1334
1335//
1336// opent de meegegeven sheet voor de huidige context (bijv. placeholder_{postid}_{placeholderid})
1337// binnen de huidige pagina
1338//
1339function nxs_js_popup_navigateto(sheet)
1340{
1341	nxs_js_popup_navigateto_v2(sheet, true);
1342}
1343
1344function nxs_js_popup_navigateto_v2(sheet, shouldgrowl)
1345{
1346	var waitgrowltoken = -1;
1347
1348	if (shouldgrowl)
1349	{
1350		waitgrowltoken = nxs_js_alert_wait_start(nxs_js_gettrans("Loading information"));
1351	}
1352	nxs_js_popup_setcurrentsheet(sheet);
1353
1354	var ajaxurl = nxs_js_get_adminurladminajax();
1355	jQuery.ajax
1356	(
1357		{
1358			type: 'POST',
1359			data:
1360			{
1361				"action": "nxs_ajax_webmethods",
1362				"webmethod": "getsheet",
1363				"clientpopupsessioncontext": nxs_js_getescaped_popupsession_context(),
1364				"clientpopupsessiondata": nxs_js_getescaped_popupsession_data(),
1365				"clientshortscopedata": nxs_js_popup_getescapedshortscopedata(),
1366				"clientqueryparameters": nxs_js_escaped_getqueryparametervalues()
1367			},
1368			cache: false,
1369			dataType: 'JSON',
1370			url: ajaxurl,
1371			success: function(response)
1372			{
1373				nxs_js_alert_wait_finish(waitgrowltoken);
1374
1375				nxs_js_log(response);
1376				if (response.result == "OK")
1377				{
1378					if (response.html != null && !nxs_js_stringisblank(response.html))
1379					{
1380						// OK
1381						var elementidlastfocussed = nxs_js_popup_getshortscopedata('elementidlastfocussed');
1382
1383						// wipe de shortscope data
1384						nxs_js_popup_clearshortscopedata();
1385
1386						// dim hover menu's die op dit moment zichtbaar zijn
1387						jQuery(".nxs-hover-menu").addClass('nxs-suppress');
1388
1389						//
1390						nxs_js_pop_resetdynamiccontentcontainer();
1391
1392						// remove any previously defined nxs-active indicators (for text-widgets; if these
1393						// are removed, the nxs-active indicator somehow remains (so this basically is
1394						// a workaround).
1395						jQuery("#TB_window.nxs-active").removeClass("nxs-active");
1396
1397						jQuery('.nxs-popup-dyncontentcontainer').html(response.html);
1398
1399						// width=1, see #1283672893762
1400						tb_show(response.title, "#TB_inline?height=1&width=1&inlineId=nxs_ajax_thickbox&modal=true", "");
1401						jQuery("#TB_overlay").show();
1402						jQuery("#TB_window").show();
1403
1404						//
1405						// enable dragging of the window
1406						//
1407						jQuery("#TB_window").draggable
1408						(
1409							{
1410								handle: ".nxs-admin-header",
1411								start: function()
1412								{
1413									if (!jQuery(".nxs-popup-dyncontentcontainer").hasClass('nxs-wasdragged'))
1414									{
1415										jQuery(".nxs-popup-dyncontentcontainer").addClass('nxs-wasdragged');
1416									}
1417								}
1418							}
1419						)
1420
1421						// ensure the "back" document is not scrollable when the popup shows
1422						nxs_js_disabledocumentscrollwhenoveringoverelement('.nxs-popup-content-canvas-cropper');
1423
1424						// enable "chosen" script to enhance dropdownlists
1425						//nxs_js_log("chosen select done");
1426						jQuery(".chosen-select").chosen({allow_single_deselect: true});
1427						//nxs_js_log("chosen select done");
1428
1429						nxs_js_popupshows = true;
1430
1431						// show/hide buttons as indicated by the popup for initialization
1432						// note, this will be overriden if the popup appears to be dirty (handled below)
1433						var initialbuttonstate = nxs_js_popup_get_initialbuttonstate();
1434						if (initialbuttonstate == 'showokifnotdirty')
1435						{
1436							// show ok, hide cancel, hide save
1437							if (jQuery('#nxs_popup_genericokbutton').length > 0)
1438							{
1439								jQuery('#nxs_popup_genericokbutton').show();
1440								if (jQuery('#nxs_popup_genericcancelbutton').length > 0)
1441								{
1442									jQuery('#nxs_popup_genericcancelbutton').hide();
1443								}
1444								if (jQuery('#nxs_popup_genericsavebutton').length > 0)
1445								{
1446									jQuery('#nxs_popup_genericsavebutton').hide();
1447								}
1448							}
1449							else
1450							{
1451								//nxs_js_log('cannot apply initialbuttonstate; ok button not found');
1452							}
1453						}
1454						else if (initialbuttonstate == 'showcancel')
1455						{
1456							// show cancel, hide ok, hide save
1457							if (jQuery('#nxs_popup_genericcancelbutton').length > 0)
1458							{
1459								jQuery('#nxs_popup_genericcancelbutton').show();
1460								if (jQuery('#nxs_popup_genericokbutton').length > 0)
1461								{
1462									jQuery('#nxs_popup_genericokbutton').hide();
1463								}
1464								if (jQuery('#nxs_popup_genericsavebutton').length > 0)
1465								{
1466									jQuery('#nxs_popup_genericsavebutton').hide();
1467								}
1468							}
1469							else
1470							{
1471								nxs_js_log('cannot apply initialbuttonstate; cancel button not found');
1472							}
1473						}
1474						else if (initialbuttonstate == 'none')
1475						{
1476							// ok :)
1477						}
1478						else
1479						{
1480							nxs_js_log('unsupported initialbuttonstate;' + initialbuttonstate);
1481						}
1482
1483						// enable 'save' buttons if session indicates 'dirty' fields
1484						if (nxs_js_popup_sessiondata_is_dirty())
1485						{
1486							nxs_js_popup_handle_becomes_dirty_first_time();
1487						}
1488
1489						// enables textboxes to automatically set the dirty flag when text is entered
1490						nxs_js_popup_processautodirtyhandling();
1491
1492						// close de popup als er 'naast' de pop up wordt geklikt (we undo-en de modal eigenschap)
1493						// dit is een workaround/fix; de modal van de thickbox zorgt er voor dat de MCE editor
1494						// niet goed her-initiatiseert
1495						jQuery("#TB_overlay").unbind("click.popupzekerweten");
1496						jQuery("#TB_overlay").bind("click.popupzekerweten", function(e)
1497						{
1498							nxs_js_log('345897');
1499							// stop het progageren van het event (bind("click") om te voorkomen dat onderliggende
1500							// elementen het click event gaan afhandelen (zoals het event dat de body click altijd opvangt...)
1501							e.stopPropagation();
1502            	nxs_js_closepopup_unconditionally_if_not_dirty();
1503						});
1504
1505						jQuery(document).unbind("keyup.popupcloser");
1506						jQuery(document).bind("keyup.popupcloser",
1507							function(e)
1508							{
1509								if (e.keyCode == 27 && nxs_js_popupshows == true)	// handled
1510								{
1511									//nxs_js_log("closing popup (if not dirty)");
1512
1513									// 27 == escape
1514									nxs_js_closepopup_unconditionally_if_not_dirty();
1515
1516									// set focus to the body
1517									jQuery("body").focus();
1518
1519									// absorb the event
1520									return false;
1521								}
1522							}
1523						);
1524
1525						jQuery("#TB_window").unbind("click.stoppropagation");
1526						jQuery("#TB_window").bind("click.stoppropagation", function(e)
1527						{
1528							// stop het progageren van het event (bind("click") om te voorkomen dat onderliggende
1529							// elementen het click event gaan afhandelen (zoals het event dat de body click altijd opvangt...)
1530							e.stopPropagation();
1531						})
1532
1533						// if a nxs_js_execute_after_popup_shows function is present in the dom (optionally), execute it!
1534						if(typeof nxs_js_execute_after_popup_shows == 'function')
1535						{
1536							nxs_js_execute_after_popup_shows();
1537						}
1538
1539						// broadcast clientside trigger for dom elements to be notified when the popup shows
1540						jQuery(window).trigger('nxs_jstrigger_afterpopupshows');
1541
1542						// reset last focus to specified element (if available)
1543						if (elementidlastfocussed != null)
1544						{
1545							//nxs_js_log('resetting focus ... ');
1546							if (jQuery('#' + elementidlastfocussed).length > 0)
1547							{
1548								jQuery('#' + elementidlastfocussed).focus();
1549							}
1550						}
1551
1552						// reset de hoogte op het moment dat er plaatjes in de popup zitten die
1553						// nog niet beschikbaar/ingeladen zijn
1554						jQuery('.nxs-popup-dyncontentcontainer img').load
1555						(
1556							function()
1557							{
1558								//nxs_js_log('loading of image finished');
1559								nxs_js_reset_popup_dimensions();
1560							}
1561						);
1562
1563						// reset height of popup
1564						nxs_js_reset_popup_dimensions();
1565
1566						// handle enter auto submit popup
1567						nxs_js_popup_registerautosubmitwhenuserpressesenter();
1568					}
1569					else
1570					{
1571						nxs_js_popup_notifyservererror();
1572						nxs_js_log('html is null or empty?');
1573						nxs_js_log(html);
1574					}
1575				}
1576				else
1577				{
1578					nxs_js_popup_notifyservererror();
1579					nxs_js_log(response);
1580				}
1581			},
1582			error: function(response)
1583			{
1584				nxs_js_alert_wait_finish(waitgrowltoken);
1585
1586				nxs_js_popup_notifyservererror();
1587				nxs_js_log(response);
1588			}
1589		}
1590	);
1591}
1592
1593function nxs_js_popup_registerautosubmitwhenuserpressesenter()
1594{
1595	//nxs_js_log('executing nxs_js_popup_registerautosubmitwhenuserpressesenter');
1596
1597	jQuery("#TB_window .nxs-admin-wrap .nxs_defaultenter").unbind("keyup.defaultenter");
1598	jQuery("#TB_window .nxs-admin-wrap .nxs_defaultenter").bind("keyup.defaultenter", function(e)
1599	{
1600		if (e.keyCode == 13)
1601		{
1602			if (jQuery("#nxs_popup_genericsavebutton").length > 0)
1603			{
1604				if (jQuery("#nxs_popup_genericsavebutton").is(':visible'))
1605				{
1606					//nxs_js_log('default enter clicked');
1607					e.stopPropagation();
1608					jQuery("#nxs_popup_genericsavebutton").click();
1609				}
1610				else
1611				{
1612					nxs_js_log('default enter clicked, save not visible');
1613				}
1614			}
1615			else
1616			{
1617				nxs_js_log('default enter clicked, save not found');
1618			}
1619		}
1620	});
1621}
1622
1623function nxs_js_popup_notifynotok(message, idofelementofocus)
1624{
1625	if (nxs_js_popupshows)
1626	{
1627		nxs_js_popup_negativebounce(message);
1628	}
1629	else
1630	{
1631		nxs_js_alert(message);
1632	}
1633
1634	if (idofelementofocus != null)
1635	{
1636		jQuery('#' + idofelementofocus).focus();
1637	}
1638}
1639function nxs_js_popup_requirepagerefreshwhenpopupcloses()
1640{
1641	nxs_js_requirespagerefresh = true;
1642}
1643
1644function nxs_js_popup_notifyservererror()
1645{
1646	// note; a "error" output could be returned when a ajax call is invoked,
1647	// if the browser is redirecting; in that case any pending requests
1648	// get "error", see http://stackoverflow.com/questions/9131614/redirect-after-jquery-ajax-call-giving-error.
1649	nxs_js_popup_notifyservererror_v2("no debuginfo specified");
1650}
1651
1652function nxs_js_popup_notifyservererror_v2(debuginfo)
1653{
1654	nxs_js_log('notifyservererror');
1655	nxs_js_log(debuginfo);
1656
1657	var stacktrace = nxs_js_getstacktrace();
1658	nxs_js_log(stacktrace);
1659
1660	// output stacktrace
1661
1662	var msg = nxs_js_gettrans('Error transferring data. Please try again later');
1663	nxs_js_popup_notifynotok(msg, null);
1664}
1665
1666// laat het popup scherm schudden (te gebruiken om aan te duiden dat
1667// de gebruiker een ongeldige aktie heeft uitgevoerd)
1668function nxs_js_popup_negativebounce(message)
1669{
1670	var stacktrace = nxs_js_getstacktrace();
1671	nxs_js_log(stacktrace);
1672
1673	if (message != "")
1674	{
1675		//alert(message); // optionally use this line if you want a 'true' popup that stalls all threads
1676		nxs_js_alert(message);
1677	}
1678	jQuery('#TB_window').effect("shake", { times:3, distance: 10 }, 50);
1679}
1680
1681// -------------------------------------------------------------------------------------------
1682
1683function nxs_js_getcurrentbrowserurl()
1684{
1685	return window.location.href;
1686}
1687
1688// return the url after setting/updating the parameter (other occurences of the same parameter are removed)
1689function nxs_js_addqueryparametertourl(url, parameter, value)
1690{
1691	var result = url;
1692	if (nxs_js_stringcontains(url, "?"))
1693	{
1694		result = result + "&";
1695	}
1696	else
1697	{
1698		result = result + "?";
1699	}
1700	result = result + parameter + "=" + value;
1701	return result;
1702}
1703
1704// refreshes the current page
1705function nxs_js_refreshcurrentpage()
1706{
1707	location.reload(true);
1708}
1709
1710function nxs_js_redirecttopostid(postid)
1711{
1712	nxs_js_geturl("postid", postid, "notused",
1713	function(response)
1714	{
1715		var url = response.url;
1716		nxs_js_log(url);
1717		nxs_js_redirect(url);
1718	},
1719	function(response)
1720	{
1721		nxs_js_alert(nxs_js_gettrans('Unable to retrieve the URL'));
1722	}
1723	);
1724}
1725
1726function nxs_js_redirect(url)
1727{
1728	window.location = url;
1729}
1730
1731function nxs_js_redirect_top(url)
1732{
1733	top.location = url;
1734}
1735
1736// indicates whether there are any objections for opening a new popup page,
1737// this function returns 'true' if for example the existing popup page has
1738// unsaved items that haven't yet been persisted
1739function nxs_js_popup_anyobjectionsforopeningnewpopup()
1740{
1741	if (nxs_js_popupshows)
1742	{
1743		// indien een 'dirty' popup sessie actief is,
1744		// vragen we of het OK is om de vorige sessie te closen
1745		if (nxs_js_popup_sessiondata_is_dirty())
1746		{
1747			var answer = confirm(nxs_js_gettrans('Ignore unsaved changes?'));
1748			if (!answer)
1749			{
1750				// toch niet
1751				return true;
1752			}
1753			// ok, we gaan door
1754		}
1755		else
1756		{
1757			// er was geen openstaande sessie informatie
1758		}
1759
1760		// no objections
1761		return false;
1762	}
1763	else
1764	{
1765		return false;
1766	}
1767}
1768
1769// opens a postwizard popup as specified by the sheet name
1770function nxs_js_popup_postwizard_neweditsession(postwizard, sheet)
1771{
1772	if (nxs_js_popup_anyobjectionsforopeningnewpopup())
1773	{
1774		// opening a new popup is not allowed; likely some other popup is already opened
1775		return;
1776	}
1777
1778	// initiate a new popupsession data as this is a new session
1779	nxs_js_popupsession_startnewcontext();
1780	nxs_js_popup_setsessioncontext("contextprocessor", "postwizard");
1781	nxs_js_popup_setsessioncontext("postwizard", postwizard);
1782
1783	// show the popup
1784	nxs_js_popup_navigateto(sheet);
1785}
1786
1787// opens a rowscontainer popup as specified by the sheet name
1788function nxs_js_popup_rowscontainer_neweditsession(postid, sheet)
1789{
1790	if (nxs_js_popup_anyobjectionsforopeningnewpopup())
1791	{
1792		// opening a new popup is not allowed; likely some other popup is already opened
1793		return;
1794	}
1795
1796	// initiate a new popupsession data as this is a new session
1797	nxs_js_popupsession_startnewcontext();
1798	nxs_js_popup_setsessioncontext("contextprocessor", "rowscontainer");
1799	nxs_js_popup_setsessioncontext("postid", postid);
1800
1801	// show the popup
1802	nxs_js_popup_navigateto(sheet);
1803}
1804
1805// opens a site-wide popup as specified by the sheet name,
1806// using an empty context
1807function nxs_js_popup_site_neweditsession(sheet)
1808{
1809	var initialcontext = {};
1810	return nxs_js_popup_site_neweditsession_v2(sheet, initialcontext);
1811}
1812
1813// opens a site-wide popup as specified by the sheet name
1814function nxs_js_popup_site_neweditsession_v2(sheet, initialcontext)
1815{
1816	if (nxs_js_popup_anyobjectionsforopeningnewpopup())
1817	{
1818		// opening a new popup is not allowed; likely some other popup is already opened
1819		return;
1820	}
1821
1822	// initiate a new popupsession data as this is a new session
1823	nxs_js_popupsession_startnewcontext();
1824	nxs_js_popup_setsessioncontext("contextprocessor", "site");
1825
1826	// set initial context
1827	for (var initialcontextkey in initialcontext)
1828	{
1829  	var initialcontextvalue = initialcontext[initialcontextkey];
1830  	nxs_js_popup_setsessioncontext(initialcontextkey, initialcontextvalue);
1831  }
1832
1833	// show the popup
1834	nxs_js_popup_navigateto(sheet);
1835}
1836
1837		//
1838		// sluit het pop up scherm en verwijderd alle tijdelijke variabelen
1839		//
1840		function nxs_js_closepopup()
1841		{
1842			// prevent click events from propagating...
1843			try { event.stopPropagation(); } catch (err) { }
1844
1845			var answer = confirm(nxs_js_gettrans('Are you sure you want to close this window?'));
1846			if (answer)
1847			{
1848				nxs_js_closepopup_unconditionally();
1849			}
1850		}
1851
1852		// closes the active popup that was opened using the function nxs_js_popup_navigateto
1853		function nxs_js_closepopup_unconditionally()
1854		{
1855			if (nxs_js_requirespagerefresh)
1856			{
1857				nxs_js_broadcastpopupcloses();
1858				nxs_js_refreshcurrentpage();
1859			}
1860			else
1861			{
1862				nxs_js_broadcastpopupcloses();
1863
1864				nxs_js_popupsession_startnewcontext();
1865
1866				nxs_js_teardownpopupdom();	// removes dom elements, and prepares for the next thickbox
1867				nxs_js_hidepopupoverlay();	// removed the popup overlay "sheet"
1868
1869				// re-enable hover menu's
1870				nxs_js_process_updated_editor_state_silent();
1871			}
1872		}
1873
1874		function nxs_js_hidepopupoverlay()
1875		{
1876			jQuery("#TB_overlay").hide();
1877		}
1878
1879		function nxs_js_broadcastpopupcloses()
1880		{
1881			// if a nxs_js_execute_before_popup_closes function is present in the dom (optionally), execute it!
1882			if(typeof nxs_js_execute_before_popup_closes == 'function')
1883			{
1884				nxs_js_execute_before_popup_closes();
1885			}
1886
1887			// broadcast clientside trigger for dom elements to be notified when the popup shows
1888			jQuery(window).trigger('nxs_jstrigger_beforepopupcloses');
1889		}
1890
1891		function nxs_js_teardownpopupdom()
1892		{
1893			nxs_js_broadcastpopupcloses();
1894
1895			jQuery("#TB_window").removeClass("nxs-active");
1896			jQuery("#TB_window").removeClass("nxs-wasdragged");
1897
1898			// its important to actually hide the thickboxes,
1899			// otherwise the GUI event like hover will be intercepted
1900			jQuery("#TB_window").hide();
1901
1902			//nxs_js_log('found:' + jQuery("#TB_window.thickboxwindow").length);
1903			jQuery("#TB_window.thickboxwindow").each(function(i)
1904			{
1905				//nxs_js_log('removing useless thickbox');
1906   			jQuery(this).remove();
1907			});
1908
1909			nxs_js_popupshows = false;
1910
1911			jQuery("body").append("<div id='TB_window' class='thickboxwindow' style='display:none;'></div>");
1912		}
1913
1914		function nxs_js_closepopup_unconditionally_if_not_dirty()
1915		{
1916			//nxs_js_log('detected...');
1917
1918			if (nxs_js_popup_sessiondata_is_dirty())
1919			{
1920				try { event.stopPropagation(); } catch (err) { }
1921
1922				if (nxs_js_showwarning_when_trying_to_close_dirty_popup())
1923				{
1924					var answer = confirm(nxs_js_gettrans("Ignore unsaved popup data?"));
1925					if (answer)
1926					{
1927						nxs_js_closepopup_unconditionally();
1928					}
1929				}
1930				else
1931				{
1932					// popup explicitly overruled the warning question (praktisch bij de login popup)
1933					nxs_js_closepopup_unconditionally();
1934				}
1935			}
1936			else
1937			{
1938				nxs_js_closepopup_unconditionally();
1939			}
1940		}
1941
1942		// execute the function, in such a way that only one invocation will occur during the period specified for the specified groupname
1943		function nxs_js_invokethrottled(throttlegroupname, nxs_max_frequency_in_msecs, functiontoinvokethrottled)
1944		{
1945			if (!(throttlegroupname in nxs_js_queuestatelookup))
1946			{
1947				// nxs_js_log("first time throttle for group " + throttlegroupname);
1948				// doesn't yet exist
1949				nxs_js_queuestatelookup[throttlegroupname] = false;
1950			}
1951			var isqueued = nxs_js_queuestatelookup[throttlegroupname];
1952			if (isqueued)
1953			{
1954				// nxs_js_log("speeding up performance for group " + throttlegroupname);
1955				// its queued so will be processed soon...
1956				return;
1957			}
1958
1959			// nxs_js_log("enqueued function to invoke for group " + throttlegroupname);
1960
1961			// enqueue it!
1962			nxs_js_queuestatelookup[throttlegroupname] = true;
1963
1964			// optionally perform an immediate redraw to get a snappier user experience
1965			setTimeout
1966			(
1967				function()
1968				{
1969					// nxs_js_log("actual invoke request for group " + throttlegroupname);
1970
1971					// first we dequeue!
1972					nxs_js_queuestatelookup[throttlegroupname] = false;
1973					// invoke function!
1974					functiontoinvokethrottled();
1975				},
1976				nxs_max_frequency_in_msecs
1977			);
1978		}
1979
1980		function nxs_js_reset_popup_dimensions()
1981		{
1982			//jQuery('#TB_ajaxContent').css('opacity', '0');
1983
1984			nxs_js_invokethrottled("reset_popup_dimensions_actualrequest", 50, nxs_js_reset_popup_dimensions_actualrequest);
1985			nxs_js_invokethrottled("showpopup", 195, nxs_js_showpopup);
1986		}
1987
1988		function nxs_js_showpopup()
1989		{
1990			// display!
1991			jQuery('#TB_window .nxs-table').css("opacity", 1);
1992		}
1993
1994		//
1995		// reset de dimensies van de thickbox op basis van de hoogte van het scherm
1996		//
1997		function nxs_js_reset_popup_dimensions_actualrequest()
1998		{
1999			if (nxs_js_popup_getsessiondata("popup_current_dimensions") == "gallerybox")
2000			{
2001			}
2002			else
2003			{
2004				if(typeof nxs_js_popup_get_minwidth == 'function')
2005				{
2006					//
2007					var minwidth = nxs_js_popup_get_minwidth();	// can be overriden
2008					jQuery(".nxs-popup-content-canvas-cropper").css('min-width', '' + minwidth + 'px');
2009				}
2010				else
2011				{
2012					// default
2013				}
2014
2015
2016				if(typeof nxs_js_popup_get_maxwidth == 'function')
2017				{
2018					//
2019					var maxwidth = nxs_js_popup_get_maxwidth();	// can be overriden
2020					jQuery(".nxs-popup-content-canvas-cropper").css('max-width', '' + maxwidth + 'px');
2021				}
2022				else
2023				{
2024					// default
2025				}
2026
2027
2028				if(typeof nxs_js_popup_get_maxheight == 'function')
2029				{
2030					//
2031					var maxheight= nxs_js_popup_get_maxheight();	// can be overriden
2032					jQuery(".nxs-popup-content-canvas-cropper").css('height', '' + maxheight + 'px');
2033					//jQuery(".nxs-popup-content-canvas-cropper").css('max-height', '' + maxheight + 'px');
2034					//jQuery(".nxs-popup-content-canvas-cropper").css('overflow', 'auto !important;');
2035				}
2036				else
2037				{
2038					// default
2039				}
2040			}
2041
2042			var applynewpopuplayoutposition = true;
2043
2044			// maximize the TB_window to consume 100% width and 100% height
2045			jQuery('#TB_window').css('width', '100%');
2046			jQuery('#TB_window').css('height', jQuery(window).height() + "px");	// height of the window
2047			jQuery('#TB_window').css('margin-top', '0px');
2048			jQuery('#TB_window').css('margin-left', '0px');
2049			jQuery('#TB_window').css('top', '0px');
2050			jQuery('#TB_window').css('left', '0px');
2051
2052			//
2053			//jQuery('#TB_ajaxContent').css('width', 'auto');
2054			jQuery('#TB_ajaxContent').css('position', 'absolute');
2055			jQuery('#TB_ajaxContent').css('margin-top', '0px');
2056			jQuery('#TB_ajaxContent').css('margin-left', '0px');
2057			jQuery('#TB_ajaxContent').css('overflow', 'hidden');
2058
2059			//
2060			jQuery('#TB_ajaxContent').each
2061			(
2062				function(index, element)
2063				{
2064					// horizontal positioning
2065					var parentWidth = jQuery(element).parent().outerWidth();	// width of browser screen
2066					//nxs_js_log('parentwidth:' + parentWidth);
2067
2068					var contentWidth = jQuery(element).children().outerWidth();
2069					//nxs_js_log('contentWidth:' + contentWidth);
2070
2071					if (contentWidth == 1)
2072					{
2073						// the popup opens initially with a size of 1 pixel wide (see #1283672893762),
2074						// we will enqueue the reset of the popup to ensure the position will be ok,
2075						// after the content is loaded (the content isn't positioned ok when we reach this
2076						// point)
2077						nxs_js_reset_popup_dimensions();
2078					}
2079
2080					//nxs_js_log("parentWidth:");
2081					//nxs_js_log(parentWidth);
2082					//nxs_js_log("contentWidth:");
2083					//nxs_js_log(contentWidth);
2084
2085					var minwidth = nxs_js_popup_get_minwidth();	// can be overriden
2086					if (contentWidth < minwidth)
2087					{
2088						contentWidth = minwidth;
2089					}
2090
2091					if (parentWidth >= contentWidth)
2092					{
2093						var leftvalue = Math.round((parentWidth - contentWidth)/2);
2094						//nxs_js_log('setting:' + leftvalue);
2095						jQuery(element).css
2096						(
2097							{
2098								width: 'auto',
2099								left: leftvalue
2100						  }
2101						);
2102					}
2103					else
2104					{
2105						jQuery(element).css
2106						(
2107							{
2108								width: parentWidth,
2109								left: '0px'
2110						  }
2111						);
2112					}
2113
2114					// ---------------
2115
2116					// vertical positioning
2117					var parentHeight = jQuery(element).parent().outerHeight();
2118					var contentHeight = jQuery(element).children().outerHeight();
2119
2120					//nxs_js_log("parentHeight:");
2121					//nxs_js_log(parentHeight);
2122					//nxs_js_log("contentHeight:");
2123					//nxs_js_log(contentHeight);
2124
2125					if (parentHeight >= contentHeight)
2126					{
2127						jQuery(element).css
2128						(
2129							{
2130								height: 'auto',
2131								top: (parentHeight - contentHeight)/2
2132						  }
2133						);
2134					}
2135					else
2136					{
2137						jQuery(element).css
2138						(
2139							{
2140								height: parentHeight,
2141								top: '0px'
2142						  }
2143						);
2144					}
2145				}
2146			);
2147
2148			if (!jQuery("#TB_window").hasClass("nxs-active"))
2149			{
2150				jQuery("#TB_window").addClass("nxs-active");
2151			}
2152			else
2153			{
2154				// was already set, ignored
2155			}
2156
2157			//jQuery('#TB_ajaxContent').css('opacity', '1');
2158		}
2159
2160		function nxs_js_toggle_editor_state()
2161		{
2162			// toggle!
2163	  	nxs_js_nxseditoractive = !nxs_js_nxseditoractive;
2164
2165	  	var cookieval = "";
2166	  	if (nxs_js_nxseditoractive)
2167	  	{
2168	  		cookieval = "active";
2169	  	}
2170	  	else
2171	  	{
2172	  		cookieval = "inactive";
2173	  	}
2174	  	nxs_js_setcookie('nxs_cookie_editoractive', cookieval);
2175		  nxs_js_process_updated_editor_state();
2176		}
2177
2178		function nxs_js_initiateeditorstate()
2179		{
2180			if (!nxs_js_userhasadminpermissions())
2181			{
2182				nxs_js_nxseditoractive = false;
2183				return;
2184			}
2185
2186			var cookieval = nxs_js_getcookie('nxs_cookie_editoractive');
2187			if (cookieval == "active")
2188			{
2189				nxs_js_nxseditoractive = true;
2190			}
2191			else if (cookieval == "inactive")
2192			{
2193				nxs_js_nxseditoractive = false;
2194			}
2195			else
2196			{
2197				// first time, or else
2198				nxs_js_nxseditoractive = true;
2199			}
2200
2201			nxs_js_process_updated_editor_state_silent();
2202		}
2203
2204		function nxs_js_process_updated_editor_state()
2205		{
2206			var growl = true;
2207			nxs_js_process_updated_editor_state_internal(growl);
2208		}
2209
2210		function nxs_js_process_updated_editor_state_silent()
2211		{
2212			var growl = false;
2213			nxs_js_process_updated_editor_state_internal(growl);
2214		}
2215
2216		// parameter growl is used to indicate whether
2217		function nxs_js_process_updated_editor_state_internal(growl)
2218		{
2219	    if (!nxs_js_userhasadminpermissions())
2220	    {
2221	    	// the popup mechanism is used for galleries too, and other parts,
2222	    	// if these popups are closed, the method is invoked too,
2223	    	// in that case we ignore the requests
2224	    	return;
2225	    }
2226
2227			if (!nxs_js_nxseditoractive)
2228	  	{
2229		    jQuery(".nxs-cursor").addClass("nxs-suppress");
2230		    jQuery(".nxs-hover-menu").addClass("nxs-suppress");
2231
2232		    if (growl)
2233		    {
2234		    	nxs_js_editorstategrowltoken = nxs_js_alert_wait_start(nxs_js_gettrans('Editor is now disabled'));
2235		    }
2236
2237		    jQuery(".nxs-editor-toggler").find(".nxs-icon-pause").hide();
2238		    jQuery(".nxs-editor-toggler").find(".nxs-icon-play").show();
2239
2240		    jQuery(".nxs-editor-toggler").attr('title', nxs_js_gettrans('Click to reactivate editor '));
2241
2242		    // als de editor uit staat, moet de gebruiker weer "normaal" tekst kunnen selecteren
2243				jQuery('body').enableSelection();
2244
2245				// hide particular elements
2246				jQuery(".nxs-hidewheneditorinactive").hide();
2247				jQuery(".nxs-border-dash").hide();
2248			}
2249	  	else
2250		  {
2251		    jQuery(".nxs-suppress").removeClass("nxs-suppress");
2252
2253		    if (growl)
2254		    {
2255	    		nxs_js_alert_wait_finish(nxs_js_editorstategrowltoken);
2256	    		nxs_js_alert_veryshort(nxs_js_gettrans('Editor is now active again'));
2257	    	}
2258
2259		    jQuery(".nxs-editor-toggler").find(".nxs-icon-pause").show();
2260		    jQuery(".nxs-editor-toggler").find(".nxs-icon-play").hide();
2261
2262		    jQuery(".nxs-editor-toggler").attr('title', nxs_js_gettrans('Click to deactivate editor'));
2263
2264		    // als de editor aan staat, kan de gebruiker geen tekst kunnen selecteren (dit voorkomt irritante tekst selecties bij drag/droppen van widgets)
2265				jQuery('body').disableSelection();
2266
2267				// show particular elements
2268				jQuery(".nxs-hidewheneditorinactive").show();
2269				jQuery(".nxs-border-dash").show();
2270	  	}
2271
2272	  	// add a class to the html element
2273	  	if (nxs_js_nxseditoractive)
2274	  	{
2275	  		jQuery("html").removeClass("nxs-editor-inactive");
2276	  		jQuery("html").addClass("nxs-editor-active");
2277	  	}
2278	  	else
2279	  	{
2280	  		jQuery("html").removeClass("nxs-editor-active");
2281	  		jQuery("html").addClass("nxs-editor-inactive");
2282	  	}
2283
2284	  	nxs_js_refreshtopmenufillerheight();
2285
2286	  	nxs_gui_set_runtime_dimensions_enqueuerequest("nxs-framework-editorstatechanged");	// update gui (for example, heights of "empty" rows)
2287		}
2288
2289		function nxs_js_toggle_menu_state()
2290		{
2291			// toggle!
2292	  	nxs_js_nxsmenuactive = !nxs_js_nxsmenuactive;
2293
2294	  	var cookieval = "";
2295	  	if (nxs_js_nxsmenuactive)
2296	  	{
2297	  		cookieval = "active";
2298	  	}
2299	  	else
2300	  	{
2301	  		cookieval = "inactive";
2302	  	}
2303	  	nxs_js_setcookie('nxs_cookie_menuactive', cookieval);
2304		  nxs_js_process_updated_menu_state();
2305
2306		  nxs_js_refreshtopmenufillerheight();
2307		}
2308
2309		function nxs_js_initiatemenustate()
2310		{
2311			var cookieval = nxs_js_getcookie('nxs_cookie_menuactive');
2312			if (cookieval == "active")
2313			{
2314				nxs_js_nxsmenuactive = true;
2315			}
2316			else if (cookieval == "inactive")
2317			{
2318				nxs_js_nxsmenuactive = false;
2319			}
2320			else
2321			{
2322				// first time, or else
2323				nxs_js_nxsmenuactive = true;
2324			}
2325			nxs_js_process_updated_menu_state_silent();
2326		}
2327
2328		function nxs_js_process_updated_menu_state()
2329		{
2330			var growl = true;
2331			nxs_js_process_updated_menu_state_internal(growl);
2332		}
2333
2334		function nxs_js_process_updated_menu_state_silent()
2335		{
2336			var growl = false;
2337			nxs_js_process_updated_menu_state_internal(growl);
2338		}
2339
2340		// parameter growl is used to indicate whether
2341		function nxs_js_process_updated_menu_state_internal(growl)
2342		{
2343	    if (!nxs_js_userhasadminpermissions())
2344	    {
2345	    	// the popup mechanism is used for galleries too, and other parts,
2346	    	// if these popups are closed, the method is invoked too,
2347	    	// in that case we ignore the requests
2348	    	return;
2349	    }
2350
2351			if (!nxs_js_nxsmenuactive)
2352	  	{
2353		    if (growl)
2354		    {
2355		    	nxs_js_menustategrowltoken = nxs_js_alert_wait_start(nxs_js_gettrans('menu is now disabled'));
2356		    }
2357
2358		    jQuery(".nxs-menu-toggler").find(".nxs-icon-arrow-up").hide();
2359		    jQuery(".nxs-menu-toggler").find(".nxs-icon-arrow-down").show();
2360
2361		    jQuery(".nxs-menu-toggler").attr('title', nxs_js_gettrans('Click to reactivate menu'));
2362
2363				// hide particular elements
2364				jQuery(".nxs-hidewhenmenuinactive").hide();
2365			}
2366	  	else
2367		  {
2368		    if (growl)
2369		    {
2370	    		nxs_js_alert_wait_finish(nxs_js_menustategrowltoken);
2371	    		nxs_js_alert_veryshort(nxs_js_gettrans('menu is now active again'));
2372	    	}
2373
2374		    jQuery(".nxs-menu-toggler").find(".nxs-icon-arrow-up").show();
2375		    jQuery(".nxs-menu-toggler").find(".nxs-icon-arrow-down").hide();
2376
2377		    jQuery(".nxs-menu-toggler").attr('title', nxs_js_gettrans('Click to deactivate menu'));
2378
2379				// show particular elements
2380				jQuery(".nxs-hidewhenmenuinactive").show();
2381	  	}
2382
2383	  	// add a class to the html element
2384	  	if (nxs_js_nxsmenuactive)
2385	  	{
2386	  		jQuery("html").removeClass("nxs-menu-inactive");
2387	  		jQuery("html").addClass("nxs-menu-active");
2388	  	}
2389	  	else
2390	  	{
2391	  		jQuery("html").removeClass("nxs-menu-active");
2392	  		jQuery("html").addClass("nxs-menu-inactive");
2393	  	}
2394
2395	  	nxs_js_refreshtopmenufillerheight();
2396
2397	  	// show the menu (its hidden when the page is loaded using inline style for
2398	  	// optimal UX)
2399	  	jQuery("#nxs-menu-outerwrap").show();
2400		}
2401
2402		function nxs_js_togglesidebar()
2403		{
2404			var ajaxurl = nxs_js_get_adminurladminajax();
2405			jQuery.ajax
2406			(
2407				{
2408					type: 'POST',
2409					data:
2410					{
2411						"action": "nxs_ajax_webmethods",
2412						"webmethod": "togglesidebar",
2413						"postid": nxs_js_getcontainerpostid()
2414					},
2415					cache: false,
2416					dataType: 'JSON',
2417					url: ajaxurl,
2418					success: function(response)
2419					{
2420						nxs_js_log(response);
2421						if (response.result == "OK")
2422						{
2423							// refresh screen to see the end result :)
2424							nxs_js_refreshcurrentpage();
2425						}
2426						else
2427						{
2428							nxs_js_popup_notifyservererror();
2429							nxs_js_log(response);
2430						}
2431					},
2432					error: function(response)
2433					{
2434						nxs_js_popup_notifyservererror();
2435						nxs_js_log(response);
2436					}
2437				}
2438			);
2439		}
2440
2441		function nxs_js_handleplaceholderevent(eventname, e, placeholderdom)
2442		{
2443			// handle incoming event for the placeholder,
2444			// note; its possible (as it appears) the event is triggered by objects
2445			// outside the framework (such as WooCommerc). We therefore first ensure
2446			// we need to act upon this event (and absorb the event), or allow the
2447			// event to propagate further
2448
2449			var istriggeredbywidget = jQuery(e.target).hasClass("nxs-widget");
2450			var istriggeredbycursor = jQuery(e.target).hasClass("nxs-runtime-autocellsize");
2451			var istriggeredbynexusframework = (istriggeredbywidget || istriggeredbycursor);
2452
2453			if (nxs_js_nxseditoractive)
2454			{
2455				if (istriggeredbynexusframework)
2456				{
2457					// no further propagation of the click event...
2458					e.stopPropagation();
2459					nxs_js_popup_placeholder_handleclick(placeholderdom);
2460				}
2461				else if (e.type == "click")
2462				{
2463					// no further propagation of the click event...
2464					e.stopPropagation();
2465					nxs_js_log(placeholderdom);
2466					nxs_js_popup_placeholder_handleclick(placeholderdom);
2467				}
2468				else
2469				{
2470					// we won't act upon this event as we don't know who are what
2471					// triggered it. The event wil be logged to help debug problems,
2472					// and it will propagate further to be handled by someone else's code
2473					nxs_js_log("Widget detect an event that appears to be triggered outside the nxs framework. It propagates further:");
2474					nxs_js_log(e);
2475				}
2476			}
2477			else
2478			{
2479				//
2480				nxs_js_log("Widget detect an event that appears to be triggered outside the nxs framework. It propagates further:");
2481				nxs_js_log(e);
2482			}
2483		}
2484
2485		function nxs_js_reregister_click_and_hover_events()
2486		{
2487			if (nxs_js_userhasadminpermissions())
2488			{
2489				jQuery("a").unbind("click.reregister");
2490				jQuery("a").bind("click.reregister", function(e)
2491				{
2492				   //do something
2493				   e.stopPropagation();
2494				})
2495
2496				jQuery("input").unbind("click.reregister");
2497				jQuery("input").bind("click.reregister", function(e)
2498				{
2499				   //do something
2500				   e.stopPropagation();
2501				})
2502
2503				// allow user to click on any widget within an editable section
2504				jQuery(".nxs-widgets-editable .nxs-placeholder").each
2505				(
2506					function(index, placeholderelement)
2507					{
2508						// remove any previously defined click events
2509						jQuery(placeholderelement).unbind("click.reregister");
2510						jQuery(placeholderelement).bind
2511						(
2512							"click.reregister",
2513							function(e)
2514							{
2515								nxs_js_handleplaceholderevent('click', e, this);
2516							}
2517						);
2518
2519						// remove any previously defined dbl click events
2520						jQuery(placeholderelement).unbind("dblclick.reregister");
2521						jQuery(placeholderelement).bind
2522						(
2523							"dblclick.reregister",
2524							function(e)
2525							{
2526								nxs_js_handleplaceholderevent('dblclick', e, this);
2527							}
2528						);
2529					}
2530				);
2531
2532				jQuery(".nxs-no-click-propagation").unbind("click.reregister");
2533				jQuery(".nxs-no-click-propagation").bind
2534				(
2535					"click.reregister",
2536					function(e)
2537					{
2538						e.stopPropagation();
2539					}
2540				);
2541
2542				//
2543				// als een gebruiker clickt op het 'verplaats' icoon
2544				// bij een placeholder moet het click event worden geabsorbeerd
2545				//
2546				jQuery(".cursor").unbind("click.startdrag");
2547				jQuery(".cursor").bind("click.startdrag", function(e)
2548				{
2549					// stop het progageren van het event (bind("click") om te voorkomen dat onderliggende
2550					// elementen het click event gaan afhandelen (zoals het event dat de body click altijd opvangt...)
2551					e.stopPropagation();
2552
2553					nxs_js_alert(nxs_js_gettrans('Tip to move widget'));
2554				});
2555
2556				//
2557				Mousetrap.bind('alt+c', function(e, combo)
2558	  		{
2559				  console.log(combo);
2560				  nxs_copytoserverclipboard("designproperties");
2561				});
2562				Mousetrap.bind('alt+v', function(e, combo)
2563	  		{
2564				  console.log(combo);
2565				  nxs_pastefromserverclipboard("designproperties");
2566				});
2567
2568				jQuery(document).unbind("keydown.ctrlprocessing");
2569				jQuery(document).bind("keydown.ctrlprocessing", function(evt)
2570				{
2571	    		if (!nxs_js_isctrlkeydown)
2572	    		{
2573		        if (evt.keyCode == 17)	// 17 = ctrl
2574		        {
2575		        	nxs_js_isctrlkeydown = true;
2576		        	//nxs_js_log('ctrl pressed');
2577		        }
2578		        /*
2579		        else
2580		        {
2581		        	nxs_js_log('key pressed:' + evt.keyCode);
2582		        }
2583		        */
2584		      }
2585		    });
2586
2587				// control (ctrl) toets zet tijdelijk de cursors uit
2588				jQuery(document).unbind("keyup.compound");
2589				jQuery(document).bind("keyup.compound", function(evt)
2590				{
2591					if (evt.which == 27)	// handled
2592				  {
2593				  	if (nxs_js_popupshows)
2594				  	{
2595				  		// ignore the request when popup shows (popup itself is responsible for handling escape)
2596				  	}
2597				  	else if (nxs_js_nxsisdragging)
2598				  	{
2599				  		// ignore the request when user is drag'n'dropping
2600				  	}
2601				  	else
2602				  	{
2603					  	//nxs_js_log('debug; escape pressed (GJGJ), popup does not show');
2604
2605				  		nxs_js_toggle_editor_state();
2606				  		return false;
2607				  	}
2608					}
2609
2610					// detect copy-paste
2611					if (nxs_js_nxseditoractive)
2612		    	{
2613		        if (nxs_js_isctrlkeydown)
2614		        {
2615		        	//nxs_js_log("keycode:" + evt.keyCode);
2616
2617		        	// ctrl is pressed
2618
2619		        	if (evt.keyCode == 67)
2620		        	{
2621		        		nxs_js_isctrlkeydown = false;
2622		        		nxs_copytoserverclipboard("all");
2623		        		return false;
2624		        	}
2625		        	else if (evt.keyCode == 86)
2626		        	{
2627		        		nxs_js_isctrlkeydown = false;
2628		        		nxs_pastefromserverclipboard("all");
2629		        		return false;
2630		        	}
2631		        	else if (evt.keyCode == 66)	// debug key: ctrl-b = re-enable js events (rebuild UI editor)
2632		        	{
2633		        		nxs_js_isctrlkeydown = false;
2634		        		nxs_js_alert('debug - invoking nxs_js_reenable_all_window_events() BEGIN');
2635		        		nxs_js_reenable_all_window_events();
2636		        		nxs_js_alert('debug - invoking nxs_js_reenable_all_window_events() DONE');
2637		        		return false;
2638		        	}
2639			        else if (evt.keyCode == 17) // 17 = ctrl
2640			        {
2641			        	nxs_js_isctrlkeydown = false;	// ctrl key released
2642			        	//nxs_js_log('ctrl released');
2643			        }
2644		        	else
2645		        	{
2646		        		//nxs_js_log(evt.keyCode);
2647		        		//return false;
2648		        	}
2649						}
2650						else
2651						{
2652						  if (evt.keyCode == 46)	// delete key
2653							{
2654								if (!nxs_js_popupshows)
2655								{
2656									var widget = nxs_js_getwidgetdom_overwhichwehover();
2657									if (widget != null)
2658									{
2659										nxs_js_frontendediting_widgethandledelete(widget);
2660									}
2661									else
2662									{
2663										// not hovering over widget
2664									}
2665								}
2666							}
2667
2668						}
2669					}
2670				});
2671
2672				// if a user hovers over a placeholder that is editable,
2673				// we add a nxs-hovering class to its cell-cursor and hover-menu,
2674				// we remove the classes when the user moves out
2675				// OK
2676				jQuery(".nxs-widgets-editable .nxs-placeholder").unbind("mouseover.glowwidget");
2677				jQuery(".nxs-widgets-editable .nxs-placeholder").bind("mouseover.glowwidget", function(e)
2678				{
2679					//nxs_js_log('mouse over detected');
2680					jQuery(this).find(".nxs-cell-cursor").addClass("nxs-hovering");
2681					jQuery(this).find(".nxs-hover-menu").addClass("nxs-hovering");
2682					jQuery(this).addClass("nxs-hovering");
2683				});
2684				// OK
2685				jQuery(".nxs-widgets-editable .nxs-placeholder").unbind("mouseleave.glowwidget");
2686				jQuery(".nxs-widgets-editable .nxs-placeholder").bind("mouseleave.glowwidget", function(e)
2687				{
2688					//nxs_js_log('mouse leave detected editable placeholder'); // gj done that
2689					jQuery(this).find(".nxs-cell-cursor").removeClass("nxs-hovering");
2690					jQuery(this).find(".nxs-hover-menu").removeClass("nxs-hovering");
2691					jQuery(this).removeClass("nxs-hovering");
2692				}
2693				);
2694
2695				// if the user hovers over a hovermenu of a pagerow,
2696				// highlight all widgets within that row, and dim them when the mouse leaves the menu
2697				// OK
2698				jQuery(".nxs-layout-editable .nxs-row .nxs-row-container > .nxs-hover-menu").unbind("mouseover.glowrow");
2699				jQuery(".nxs-layout-editable .nxs-row .nxs-row-container > .nxs-hover-menu").bind("mouseover.glowrow", function(e)
2700				{
2701					jQuery(this).closest(".nxs-row").find(".nxs-cell-cursor").addClass("nxs-hovering");
2702					jQuery(this).closest(".nxs-row").find(".nxs-placeholder").addClass("nxs-hovering");
2703				});
2704				// OK
2705				jQuery(".nxs-layout-editable .nxs-row .nxs-row-container > .nxs-hover-menu").unbind("mouseleave.glowrow");
2706				jQuery(".nxs-layout-editable .nxs-row .nxs-row-container > .nxs-hover-menu").bind("mouseleave.glowrow", function(e)
2707				{
2708					jQuery(this).closest(".nxs-row").find(".nxs-cell-cursor").removeClass("nxs-hovering");
2709					jQuery(this).closest(".nxs-row").find(".nxs-placeholder").removeClass("nxs-hovering");
2710				}
2711				);
2712
2713				// als de gebruiker boven een cursor hangt (bijv. sidebar)
2714				// moet de widget oplichten
2715				jQuery(".nxs-cursor").unbind("mouseover.glowwidget");
2716				jQuery(".nxs-cursor").bind("mouseover.glowwidget", function(e)
2717				{
2718					//nxs_js_log('mouse over detected');
2719					jQuery(this).addClass("nxs-hovering");
2720					// geef ook nxs-hovering aan mogelijke hovermenu's die hier in zitten
2721					jQuery(this).find(".nxs-hover-menu").addClass("nxs-hovering");
2722				});
2723				jQuery(".nxs-cursor").unbind("mouseleave.glowwidget");
2724				jQuery(".nxs-cursor").bind("mouseleave.glowwidget", function(e)
2725				{
2726					//nxs_js_log('mouse leave detected nxs-cursor');
2727					jQuery(this).removeClass("nxs-hovering");
2728					// verwijder ook nxs-hovering aan mogelijke hovermenu's die hier in zitten
2729					jQuery(this).find(".nxs-hover-menu").removeClass("nxs-hovering");
2730				}
2731				);
2732
2733				// als de gebruiker boven een container hangt met een immediate hover menu...
2734
2735				jQuery(".nxs-containsimmediatehovermenu").unbind("mouseover.glowwidget");
2736				jQuery(".nxs-containsimmediatehovermenu").bind("mouseover.glowwidget", function(e)
2737				{
2738					//nxs_js_log('mouse over detected');
2739					jQuery(this).children(".nxs-hover-menu").addClass("nxs-hovering");
2740				});
2741				jQuery(".nxs-containsimmediatehovermenu").unbind("mouseleave.glowwidget");
2742				jQuery(".nxs-containsimmediatehovermenu").bind("mouseleave.glowwidget", function(e)
2743				{
2744					//nxs_js_log('mouse leave detected');
2745					jQuery(this).children(".nxs-hover-menu").removeClass("nxs-hovering");
2746				}
2747				);
2748			}
2749		}
2750
2751		// returns the index of the current row element within the container of rows (nearest to 'element')
2752		function nxs_js_getrowindex(element)
2753		{
2754			var row = jQuery(element).closest('.nxs-row');
2755			var container = jQuery(element).closest('.nxs-postrows')[0];
2756			var rows = jQuery(container).find('.nxs-row'); // alle nxs-rows binnen nxs-postrows
2757			var result = jQuery(rows).index(row);	//  de index van de dichtsbijzijnde nxs-row binnen de lijst
2758			return result;
2759		}
2760
2761		// returns the element of the dom element within the container for the specified postid and rowindex
2762		function nxs_js_getrowelement(postid, rowindex)
2763		{
2764			var element = nxs_js_getelementscontainer(postid);
2765			var result = jQuery(element).children().children()[rowindex];
2766			return result;
2767		}
2768
2769		function nxs_js_getplaceholderidsinrow(rowelement)
2770		{
2771			var result = [];
2772			jQuery(rowelement).find(".nxs-widget").each
2773  		(
2774  			function(index, widgetelement)
2775  			{
2776  				var widgetelementid = widgetelement.id;	// bijv. nxs-widget-a1362357679
2777  				var placeholderid = widgetelementid.split("-")[2];
2778  				result.push(placeholderid);
2779  			}
2780  		);
2781  		return result;
2782		}
2783
2784		function nxs_js_row_render(postid, rowindex, invokewhenavailable)
2785		{
2786			if (rowindex == -1)
2787			{
2788				nxs_js_log("postid: " + postid);
2789				nxs_js_log("rowindex: " + rowindex);
2790				nxs_js_log("rowindex niet gevonden");
2791				alert("rowindex niet gevonden");
2792				return;
2793			}
2794
2795			var postcontainerid = nxs_js_getcontainerpostid();
2796
2797			var ajaxurl = nxs_js_get_adminurladminajax();
2798			jQuery.ajax
2799			(
2800				{
2801					type: 'POST',
2802					data:
2803					{
2804						"action": "nxs_ajax_webmethods",
2805						"webmethod": "getcontent",
2806						"clientpopupsessioncontext": nxs_js_getescaped_popupsession_context(),
2807						"contenttype": "webpart",
2808						"contentcontext": "row_" + postcontainerid + "_" + postid + "_" + rowindex,
2809						"webparttemplate": "render_htmlvisualization",
2810						"clientqueryparameters": nxs_js_escaped_getqueryparametervalues()
2811					},
2812					cache: false,
2813					dataType: 'JSON',
2814					url: ajaxurl,
2815					success: function(response)
2816					{
2817						nxs_js_log(response);
2818						if (response.result == "OK")
2819						{
2820							invokewhenavailable(postid, rowindex, response);
2821						}
2822						else
2823						{
2824							nxs_js_log("server response is valid, but not 'ok'");
2825							nxs_js_log(response);
2826							nxs_js_popup_notifyservererror_v2(response);
2827						}
2828					},
2829					error: function(xhr, ajaxOptions, thrownError)
2830					{
2831						// an error could occur if the user redirects before this operation is completed
2832						nxs_js_popup_notifyservererror_v2(thrownError);
2833					}
2834				}
2835			);
2836		}
2837
2838		// helper function that gets the dom element of the elementscontainer for the specified postid,
2839		// if a page contains a header, sidebar, maincontent and footer,
2840		// you can easily get the footer dom, knowing its postid
2841		function nxs_js_getelementscontainer(postid)
2842		{
2843			var result = jQuery(".nxs-elements-container.nxs-post-" + postid).first();
2844			return result;
2845		}
2846
2847		// helper function that returns the dom of the widget in the elementscontainer
2848		function nxs_js_getwidget_withinelementscontainer(elementscontainer, placeholderid)
2849		{
2850			var result = jQuery(elementscontainer).find("#nxs-widget-" + placeholderid)[0];
2851			return result;
2852		}
2853
2854		// helper function that returns the dom of the widget (placeholderid) in the elementscontainer (postid)
2855		function nxs_js_getwidgetinpostid(postid, placeholderid)
2856		{
2857			var elementscontainer = nxs_js_getelementscontainer(postid);
2858			var result = nxs_js_getwidget_withinelementscontainer(elementscontainer, placeholderid);
2859			return result;
2860		}
2861
2862		// convenience function, rerenders the GUI row for the specified postid and placeholderid,
2863		// by using this function its possible to re-render a row in the header
2864		// on the screen.
2865		function nxs_js_rerender_row_for_placeholder(postid, placeholderid)
2866		{
2867			var widget = nxs_js_getwidgetinpostid(postid, placeholderid);
2868			nxs_js_rerender_row_for_element(widget);
2869		}
2870
2871		// convenience function
2872		function nxs_js_rerender_row_for_pagerow(postid, pagerowid)
2873		{
2874			var pagecontainer = jQuery(".nxs-post-" + postid)[0];
2875			var element = jQuery(pagecontainer).find("#nxs-pagerow-" + pagerowid)[0];
2876			nxs_js_rerender_row_for_element(element);
2877		}
2878
2879		function nxs_js_getrowindex_forplaceholder(postid, placeholderid)
2880		{
2881			var element = nxs_js_getwidgetelement_forplaceholder(postid, placeholderid);
2882			var rowindex = nxs_js_getrowindex(element);
2883			return rowindex;
2884		}
2885
2886		function nxs_js_getwidgetelement_forplaceholder(postid, placeholderid)
2887		{
2888			var pagecontainer = jQuery(".nxs-post-" + postid)[0];
2889			var element = jQuery(pagecontainer).find("#nxs-widget-" + placeholderid)[0];
2890			return element;
2891		}
2892
2893		function nxs_js_rerender_row_for_element(element)
2894		{
2895			var postid = nxs_js_findclosestpostid_for_dom(element);
2896
2897			var rowindex = nxs_js_getrowindex(element);
2898			//nxs_js_log("found:" + rowindex);
2899			nxs_js_row_render(postid, rowindex, function(postid, rowindex, response)
2900			{
2901				var html = response.html;
2902				// we gaan er vanuit dat het opnieuw tekenen plaatsvindt op de article container en niet in de sidebar of footer ...
2903				var pagecontainer = jQuery(".nxs-post-" + postid)[0];
2904				var pagerowscontainer = jQuery(pagecontainer).find(".nxs-postrows")[0];
2905				// afterwards update existing row
2906				var updateElement = jQuery(pagerowscontainer).children()[rowindex];
2907
2908				// before updating the dom, we first wipe any functions for notification ajax used by the "old" widgets in this row
2909				nxs_js_clear_ajaxrefresh_notifications(updateElement);
2910
2911				//
2912				//nxs_js_log("replacing index " + rowindex);
2913				jQuery(updateElement).replaceWith(html);
2914
2915				// after updating the dom, invoke execute_after_clientrefresh_XYZ for each widget in the affected first row, if present
2916				var updateElement = jQuery(pagerowscontainer).children()[rowindex];
2917				nxs_js_notify_widgets_after_ajaxrefresh(updateElement);
2918
2919				nxs_js_reenable_all_window_events();
2920			});
2921			//nxs_js_log("done:" + rowindex);
2922		}
2923
2924		function nxs_js_getfirstplaceholderid_in_dom(s)
2925		{
2926			var result = null;
2927
2928  		jQuery(s).find('.draggable_placeholder').each
2929  		(
2930  			function(idx2, elm2)
2931  			{
2932  				var id = elm2.id;
2933  				result = id.split("-")[3];
2934				}
2935			);
2936
2937			if (result == null)
2938			{
2939				jQuery(s).find('.nxs-widget').each
2940	  		(
2941	  			function(idx2, elm2)
2942	  			{
2943	  				var id = elm2.id;
2944	  				result = id.split("-")[2];
2945					}
2946				);
2947			}
2948
2949			if (result == null)
2950			{
2951				nxs_js_log("placeholderid niet gevonden voor");
2952				nxs_js_log(s);
2953				nxs_js_log(jQuery(s).html());
2954				nxs_js_alert('placeholderid niet gevonden');
2955				alert('placeholderid not found!');
2956			}
2957
2958			return result;
2959		}
2960
2961		function nxs_js_getmenuitemdepth_in_dom(s)
2962		{
2963			var result = -1;
2964
2965			jQuery(s).find('.nxs-widget').each
2966  		(
2967  			function(idx2, elm2)
2968  			{
2969  				// de nxs-widget heeft een class 'nxs-listitem-depth-X'
2970  				var classes = this.className.split(" ");
2971				  for (var i = 0, len = classes.length; i < len; i++)
2972				  {
2973				    if (classes[i].startsWith('nxs-listitem-depth-'))
2974				    {
2975				    	result = parseInt(classes[i].split("-", 4)[3]);
2976				    	break;
2977				    }
2978				  }
2979				}
2980			);
2981
2982			//alert(result);
2983
2984			return result;
2985		}
2986
2987		function nxs_js_popup_placeholder_handleclick(placeholderdom)
2988		{
2989			var postid = nxs_js_findclosestpostid_for_dom(placeholderdom);
2990			var widget = jQuery(placeholderdom).find(".nxs-widget").first();
2991			var placeholderid = jQuery(widget).attr("id").split("-")[2];
2992			var rowindex = nxs_js_getrowindex(widget);
2993
2994			// indien (optioneel) een "nxs-clickdefault" attribuut aanwezig
2995			// is binnen de dom van de widget, wordt het event doorgelust naar
2996			// dat element
2997			var widgetelement = nxs_js_getwidgetelement_forplaceholder(postid, placeholderid);
2998			var defaultelement = jQuery(placeholderdom).find(".nxs-defaultwidgetclickhandler");
2999			if (defaultelement.length >= 1)
3000			{
3001				// ja, er is een default element gedefinieerd
3002				jQuery(defaultelement).click();
3003			}
3004			else
3005			{
3006				// nee, er is geen default gedrag gedefinieerd
3007
3008				nxs_js_log('Warning; please upgrade deprecated widget; nxs-defaultwidgetclickhandler class attribute not set, defaulting to edit widget');
3009				// default implementation
3010
3011				nxs_js_popup_placeholder_neweditsession(postid, placeholderid, rowindex, 'home');
3012			}
3013		}
3014
3015		function nxs_js_edit_offscreen_widget()
3016		{
3017			nxs_js_alert('nxs_js_edit_offscreen_widget to be implemented...');
3018		}
3019
3020		// opent een pop up voor het bewerken van de meegegeven placeholder
3021		function nxs_js_popup_placeholder_neweditsession(postid, placeholderid, rowindex, sheet)
3022		{
3023			if (sheet == null)
3024			{
3025				sheet = 'home'; // default, if not set
3026			}
3027
3028			if (nxs_js_popup_anyobjectionsforopeningnewpopup())
3029			{
3030				return;
3031			}
3032
3033			// wipe any existing popupsession data
3034			nxs_js_popupsession_startnewcontext();
3035
3036			//
3037			nxs_js_popup_setsessioncontext("contextprocessor", "widgets");
3038			nxs_js_popup_setsessioncontext("containerpostid", nxs_js_getcontainerpostid());
3039			nxs_js_popup_setsessioncontext("postid", postid);
3040			nxs_js_popup_setsessioncontext("placeholderid", placeholderid);
3041			nxs_js_popup_setsessioncontext("rowindex", rowindex);
3042
3043			// show the popup
3044			nxs_js_popup_navigateto(sheet);
3045		}
3046
3047		// opent een pop up voor het bewerken van de meegegeven pagerowid
3048		function nxs_js_popup_row_neweditsession(postid, pagerowid, sheet)
3049		{
3050			if (nxs_js_popup_anyobjectionsforopeningnewpopup())
3051			{
3052				return;
3053			}
3054
3055			// wipe any existing popupsession data
3056			nxs_js_popupsession_startnewcontext();
3057
3058			//
3059			nxs_js_popup_setsessioncontext("contextprocessor", "pagerow");
3060			nxs_js_popup_setsessioncontext("postid", postid);
3061			nxs_js_popup_setsessioncontext("pagerowid", pagerowid);
3062
3063			// show the popup
3064			nxs_js_popup_navigateto(sheet);
3065		}
3066
3067		// opent een pop up voor het bewerken van de meegegeven pagina
3068		function nxs_js_popup_postcontent_neweditsession(sheet)
3069		{
3070			var postid = nxs_js_getcontainerpostid();
3071
3072			if (nxs_js_popup_anyobjectionsforopeningnewpopup())
3073			{
3074				return;
3075			}
3076
3077			// wipe any existing popupsession data
3078			nxs_js_popupsession_startnewcontext();
3079
3080			nxs_js_popup_setsessioncontext("contextprocessor", "postcontent");
3081			nxs_js_popup_setsessioncontext("postid", postid);
3082
3083			// show the popup
3084			nxs_js_popup_navigateto(sheet);
3085		}
3086
3087		// opent een pop up voor het bewerken van de meegegeven pagina
3088		function nxs_js_popup_page_neweditsession(postid, sheet)
3089		{
3090			if (nxs_js_popup_anyobjectionsforopeningnewpopup())
3091			{
3092				return;
3093			}
3094
3095			// wipe any existing popupsession data
3096			nxs_js_popupsession_startnewcontext();
3097
3098			nxs_js_popup_setsessioncontext("contextprocessor", "post");
3099			nxs_js_popup_setsessioncontext("postid", postid);
3100
3101			// show the popup
3102			nxs_js_popup_navigateto(sheet);
3103		}
3104
3105		// opens a popup page to edit for example the footer, header or sidebar of the page
3106		function nxs_js_popup_pagetemplate_neweditsession(sheet)
3107		{
3108			var postid = nxs_js_getcontainerpostid();
3109			var pagetemplate = nxs_js_getcontainerpagetemplate();
3110
3111			if (nxs_js_popup_anyobjectionsforopeningnewpopup())
3112			{
3113				return;
3114			}
3115
3116			// wipe any existing popupsession data
3117			nxs_js_popupsession_startnewcontext();
3118
3119			//
3120			nxs_js_popup_setsessioncontext("contextprocessor", "pagetemplate");
3121			nxs_js_popup_setsessioncontext("postid", postid);
3122			nxs_js_popup_setsessioncontext("pagetemplate", pagetemplate);
3123
3124			// show the popup
3125			nxs_js_popup_navigateto(sheet);
3126		}
3127
3128		// opent een pop up voor het instellen van de meegegeven pagelet voor de meegegeven pagetemplate in de meegegeven post
3129		function nxs_js_popup_pageletinpagetemplate_neweditsession(postid, pagetemplate, pageletname, sheet)
3130		{
3131			if (nxs_js_popup_anyobjectionsforopeningnewpopup())
3132			{
3133				return;
3134			}
3135
3136			// wipe any existing popupsession data
3137			nxs_js_popupsession_startnewcontext();
3138
3139			nxs_js_popup_setsessioncontext("contextprocessor", "pageletinpagetemplate");
3140			nxs_js_popup_setsessioncontext("postid", postid);
3141			nxs_js_popup_setsessioncontext("pagetemplate", pagetemplate);
3142			nxs_js_popup_setsessioncontext("pageletname", pageletname);
3143
3144			// show the popup
3145			nxs_js_popup_navigateto(sheet);
3146		}
3147
3148		// opent een pop up voor het instellen van de meegegeven pagelet voor de meegegeven pagetemplate in de meegegeven post
3149		function nxs_js_popup_subheaderinpagetemplate_neweditsession(postid, pagetemplate, subheadername, sheet)
3150		{
3151			if (nxs_js_popup_anyobjectionsforopeningnewpopup())
3152			{
3153				return;
3154			}
3155
3156			// wipe any existing popupsession data
3157			nxs_js_popupsession_startnewcontext();
3158
3159			nxs_js_popup_setsessioncontext("contextprocessor", "pageletinpagetemplate");
3160			nxs_js_popup_setsessioncontext("postid", postid);
3161			nxs_js_popup_setsessioncontext("pagetemplate", pagetemplate);
3162			nxs_js_popup_setsessioncontext("subheadername", subheadername);
3163
3164			// show the popup
3165			nxs_js_popup_navigateto(sheet);
3166		}
3167
3168		// opent een pop up voor het instellen van de meegegeven pagelet voor de meegegeven pagetemplate in de meegegeven post
3169		function nxs_js_popup_subfooterinpagetemplate_neweditsession(postid, pagetemplate, subfootername, sheet)
3170		{
3171			if (nxs_js_popup_anyobjectionsforopeningnewpopup())
3172			{
3173				return;
3174			}
3175
3176			// wipe any existing popupsession data
3177			nxs_js_popupsession_startnewcontext();
3178
3179			nxs_js_popup_setsessioncontext("contextprocessor", "pageletinpagetemplate");
3180			nxs_js_popup_setsessioncontext("postid", postid);
3181			nxs_js_popup_setsessioncontext("pagetemplate", pagetemplate);
3182			nxs_js_popup_setsessioncontext("subfootername", subfootername);
3183
3184			// show the popup
3185			nxs_js_popup_navigateto(sheet);
3186		}
3187
3188		function nxs_js_trash_article(postid)
3189		{
3190			var answer = confirm(nxs_js_gettrans('Are you sure you want to delete this page?'));
3191			if (!answer)
3192			{
3193				return;
3194			}
3195			nxs_js_trash_article_no_question(postid);
3196		}
3197
3198		function nxs_js_trash_article_no_question(postid)
3199		{
3200			// invoke ajax call
3201			var ajaxurl = nxs_js_get_adminurladminajax();
3202			jQuery.ajax
3203			(
3204				{
3205					type: 'POST',
3206					data:
3207					{
3208						"action": "nxs_ajax_webmethods",
3209						"webmethod": "removepage",
3210						"postid": postid,
3211						"howto": "trash"
3212					},
3213					async: false,
3214					cache: false,
3215					dataType: 'JSON',
3216					url: ajaxurl,
3217					success: function(response)
3218					{
3219						nxs_js_log(response);
3220						if (response.result == "OK")
3221						{
3222							// ok
3223						}
3224						else
3225						{
3226							nxs_js_popup_notifyservererror();
3227							nxs_js_log(response);
3228						}
3229					},
3230					error: function(response)
3231					{
3232						nxs_js_popup_notifyservererror();
3233						nxs_js_log(response);
3234					}
3235				}
3236			);
3237		}
3238
3239		function nxs_js_delete_article_no_question(postid)
3240		{
3241			// invoke ajax call
3242			var ajaxurl = nxs_js_get_adminurladminajax();
3243			jQuery.ajax
3244			(
3245				{
3246					type: 'POST',
3247					data:
3248					{
3249						"action": "nxs_ajax_webmethods",
3250						"webmethod": "removepage",
3251						"postid": postid,
3252						"howto": "permanent"
3253					},
3254					async: false,
3255					cache: false,
3256					dataType: 'JSON',
3257					url: ajaxurl,
3258					success: function(response)
3259					{
3260						nxs_js_log(response);
3261						if (response.result == "OK")
3262						{
3263							// ok
3264						}
3265						else
3266						{
3267							nxs_js_popup_notifyservererror();
3268							nxs_js_log(response);
3269						}
3270					},
3271					error: function(response)
3272					{
3273						nxs_js_popup_notifyservererror();
3274						nxs_js_log(response);
3275					}
3276				}
3277			);
3278		}
3279
3280		function nxs_js_delete_article(postid)
3281		{
3282			var answer = confirm(nxs_js_gettrans('Are you sure you want to delete this page?'));
3283			if (!answer)
3284			{
3285				return;
3286			}
3287
3288			nxs_js_delete_article_no_question(postid);
3289		}
3290
3291		function nxs_js_restore_article(postid)
3292		{
3293			// invoke ajax call
3294			var ajaxurl = nxs_js_get_adminurladminajax();
3295			jQuery.ajax
3296			(
3297				{
3298					type: 'POST',
3299					data:
3300					{
3301						"action": "nxs_ajax_webmethods",
3302						"webmethod": "restorepage",
3303						"postid": postid
3304					},
3305					async: false,
3306					cache: false,
3307					dataType: 'JSON',
3308					url: ajaxurl,
3309					success: function(response)
3310					{
3311						nxs_js_log(response);
3312						if (response.result == "OK")
3313						{
3314							// ok
3315						}
3316						else
3317						{
3318							nxs_js_popup_notifyservererror();
3319							nxs_js_log(response);
3320						}
3321					},
3322					error: function(response)
3323					{
3324						nxs_js_popup_notifyservererror();
3325						nxs_js_log(response);
3326					}
3327				}
3328			);
3329		}
3330
3331		function nxs_js_popup_placeholder_wipe(postid, placeholderid)
3332		{
3333			nxs_js_log('Warning; obsolete function used; nxs_js_popup_placeholder_wipe(postid, placeholderid)');
3334			var widget = nxs_js_getwidgetinpostid(postid, placeholderid);
3335			nxs_js_popup_wipe_widget(widget);
3336		}
3337
3338		function nxs_js_popup_wipe_closestwidgetindom(dom)
3339		{
3340			// first find the placeholder, then within the placeholder find the nxs-widget
3341			var placeholder = jQuery(dom).closest(".nxs-placeholder");
3342			var widget = jQuery(placeholder).find(".nxs-widget")[0];
3343			nxs_js_popup_wipe_widget(widget);
3344		}
3345
3346		function nxs_js_frontendediting_widgethandledelete(placeholderdom)
3347		{
3348			var postid = nxs_js_findclosestpostid_for_dom(placeholderdom);
3349			var widget = placeholderdom;
3350			var placeholderid = jQuery(widget).attr("id").split("-")[2];
3351			var rowindex = nxs_js_getrowindex(widget);
3352			var widgetelement = nxs_js_getwidgetelement_forplaceholder(postid, placeholderid);
3353			var placeholderelement = jQuery(placeholderdom).closest(".nxs-placeholder")[0];
3354			var defaultelement = jQuery(placeholderelement).find(".nxs-defaultwidgetdeletehandler");
3355			if (defaultelement.length >= 1)
3356			{
3357				// ja, er is een default element gedefinieerd
3358				jQuery(defaultelement).click();
3359			}
3360			else
3361			{
3362				nxs_js_log("Fallback scenario; no default delete handler found for this widget, explicity deleting this widget instead.");
3363				// nee, er is geen default gedrag gedefinieerd; wipe widget
3364				nxs_js_popup_wipe_widget(widget);
3365			}
3366		}
3367
3368		function nxs_js_popup_wipe_widget(widget)
3369		{
3370			var postid = nxs_js_findclosestpostid_for_dom(widget);
3371			var placeholderid = nxs_js_getplaceholderidofwidgetdom(widget);
3372
3373			// verwijdert de placeholder
3374			var answer = confirm(nxs_js_gettrans('Are you sure you want to remove this widget?'));
3375			if (answer)
3376			{
3377				var waitgrowltoken = nxs_js_alert_wait_start(nxs_js_gettrans('Wiping element'));
3378
3379				// invoke ajax call
3380				var ajaxurl = nxs_js_get_adminurladminajax();
3381				jQuery.ajax
3382				(
3383					{
3384						type: 'POST',
3385						data:
3386						{
3387							"action": "nxs_ajax_webmethods",
3388							"webmethod": "wipeplaceholder",
3389							"postid": postid,
3390							"placeholderid": placeholderid
3391						},
3392						cache: false,
3393						dataType: 'JSON',
3394						url: ajaxurl,
3395						success: function(response)
3396						{
3397							nxs_js_alert_wait_finish(waitgrowltoken);
3398
3399							//nxs_js_log(response);
3400							if (response.result == "OK")
3401							{
3402								nxs_js_alert(nxs_js_gettrans('Widget is now empty'));
3403
3404								// update screen
3405								nxs_js_rerender_row_for_placeholder(postid, placeholderid);
3406							}
3407							else
3408							{
3409								nxs_js_popup_notifyservererror();
3410								nxs_js_log(response);
3411							}
3412						},
3413						error: function(response)
3414						{
3415							nxs_js_alert_wait_finish(waitgrowltoken);
3416
3417							nxs_js_popup_notifyservererror();
3418							nxs_js_log(response);
3419						}
3420					}
3421				);
3422			}
3423			else
3424			{
3425				// nop
3426			}
3427		}
3428
3429		function nxs_js_refreshallpagerows(postid, containerElement, invokewhenavailable)
3430		{
3431			var rendermode = "default";
3432			var containerpostid = nxs_js_getcontainerpostid();
3433			nxs_js_rows_render(containerpostid, postid, rendermode, function(html)
3434			{
3435				jQuery(containerElement).html(html);
3436				// reenable all events
3437				nxs_js_reenable_all_window_events();
3438
3439				invokewhenavailable();
3440			});
3441		}
3442
3443		function nxs_js_refreshelementscontainerforelement(element, rendermode, invokewhenavailable)
3444		{
3445			// derive postid to be refreshed
3446			var containerElement = jQuery(element).closest(".nxs-elements-container");
3447			var cursorofelementscontainer = jQuery(containerElement).find(".nxs-elements-cursor");
3448			var elementtoreplace = jQuery(containerElement).find(".nxs-postrows");
3449			var elementspostid = jQuery(cursorofelementscontainer).attr("id").split("-")[2];
3450			var containerpostid = nxs_js_getcontainerpostid();
3451
3452			//nxs_js_log("containerpostid;" + containerpostid);
3453			//nxs_js_log("elementspostid;" + elementspostid);
3454			// gjgj
3455			nxs_js_rows_render(containerpostid, elementspostid, rendermode, function(html)
3456			{
3457				jQuery(elementtoreplace).replaceWith(html);
3458				// reenable all events
3459				nxs_js_reenable_all_window_events();
3460
3461				invokewhenavailable();
3462			});
3463		}
3464
3465		function nxs_js_rows_render(containerpostid, postid, rendermode, invokewhenavailable)
3466		{
3467			var ajaxurl = nxs_js_get_adminurladminajax();
3468			jQuery.ajax
3469			(
3470				{
3471					type: 'POST',
3472					data:
3473					{
3474						"action": "nxs_ajax_webmethods",
3475						"webmethod": "getcontent",
3476						"clientpopupsessioncontext": nxs_js_getescaped_popupsession_context(),
3477						"contenttype": "rows",
3478						"contentcontext": "rows_" + containerpostid + "_" + postid + "_" + rendermode,
3479						"clientqueryparameters": nxs_js_escaped_getqueryparametervalues()
3480					},
3481					async: false,
3482					cache: false,
3483					dataType: 'JSON',
3484					url: ajaxurl,
3485					success: function(response)
3486					{
3487						nxs_js_log(response);
3488						if (response.result == "OK")
3489						{
3490							invokewhenavailable(response.html);
3491						}
3492						else
3493						{
3494							nxs_js_popup_notifyservererror();
3495							nxs_js_log(response);
3496						}
3497					},
3498					error: function(response)
3499					{
3500						nxs_js_popup_notifyservererror();
3501						nxs_js_log(response);
3502					}
3503				}
3504			);
3505		}
3506
3507		// removes the row to which this domelement belongs
3508		// after asking for confirmation. This also updates the dom
3509		function nxs_js_row_remove(domelement)
3510		{
3511			var postid = nxs_js_findclosestpostid_for_dom(domelement);
3512			var rowindex = nxs_js_getrowindex(domelement);
3513			// double check
3514			var answer = confirm(nxs_js_gettrans('Are you sure you want to delete this row?'));
3515			if (answer)
3516			{
3517				var waitgrowltokenx = nxs_js_alert_wait_start(nxs_js_gettrans('Removing row'));
3518
3519				// invoke ajax call
3520				var ajaxurl = nxs_js_get_adminurladminajax();
3521				jQuery.ajax
3522				(
3523					{
3524						type: 'POST',
3525						data:
3526						{
3527							"action": "nxs_ajax_webmethods",
3528							"webmethod": "removerow",
3529							"postid": postid,
3530							"rowid": rowindex
3531						},
3532						cache: false,
3533						dataType: 'JSON',
3534						url: ajaxurl,
3535						success: function(response)
3536						{
3537							nxs_js_alert_wait_finish(waitgrowltokenx);
3538							nxs_js_log(response);
3539
3540							if (response.result == "OK")
3541							{
3542								if (response.pagedirty == "true")
3543								{
3544									var waitgrowltokenb = nxs_js_alert_wait_start(nxs_js_gettrans('Refreshing page'));
3545
3546									// het hele scherm moet worden bijgewerkt (dit is het geval
3547									// wanneer bijvoorbeeld de laatste row is verwijderd,
3548									// en het systeem automatisch een nieuwe row heeft toegevoegd (rowsetup)
3549									var containerElement = jQuery(".nxs-post-" + postid)[0];
3550									nxs_js_refreshallpagerows(postid, containerElement, function()
3551									{
3552										nxs_js_alert_wait_finish(waitgrowltokenb);
3553									});
3554								}
3555								else
3556								{
3557									// update GUI
3558									if (rowindex == 0)
3559									{
3560										var waitgrowltokenc = nxs_js_alert_wait_start(nxs_js_gettrans('Refreshing page'));
3561
3562										// indien de eerste regel was gedelete moeten we de
3563										// regel daaronder (die nu dus de eerste regel is
3564										// geworden) refreshen, voor nu even eenvoudig opgelost
3565										// door het hele editable deel te verversen
3566										var containerElement = jQuery(".nxs-post-" + postid)[0];
3567										nxs_js_refreshallpagerows(postid, containerElement, function()
3568										{
3569											nxs_js_alert_wait_finish(waitgrowltokenc);
3570										});
3571									}
3572									else
3573									{
3574										var waitgrowltokend = nxs_js_alert_wait_start(nxs_js_gettrans('Refreshing page'));
3575										var row = jQuery(domelement).closest('.nxs-row');
3576										jQuery(row).slideUp('slow',
3577										function()
3578										{
3579											jQuery(row).remove();
3580											nxs_js_alert_wait_finish(waitgrowltokend);
3581											// de hoogte is aangepast, pas ook de sidebar hoogte aan (indien nodig)
3582											nxs_js_reenable_all_window_events();
3583										}
3584									);
3585									}
3586									//
3587								}
3588							}
3589							else
3590							{
3591								nxs_js_alert_wait_finish(waitgrowltoken);
3592
3593								nxs_js_popup_notifyservererror();
3594								nxs_js_log(response);
3595							}
3596						},
3597						error: function(response)
3598						{
3599							nxs_js_alert_wait_finish(waitgrowltoken);
3600							nxs_js_popup_notifyservererror();
3601							nxs_js_log(response);
3602						}
3603					}
3604				);
3605			}
3606			else
3607			{
3608				// nop
3609			}
3610		}
3611
3612		function nxs_js_menuitem_remove(postid, element)
3613		{
3614			var rowindex = nxs_js_getrowindex(element);
3615			// verwijdert de row
3616			var answer = confirm(nxs_js_gettrans('Are you sure you want to delete this menu item?'));
3617			if (answer)
3618			{
3619				var waitgrowltoken = nxs_js_alert_wait_start(nxs_js_gettrans('Removing row'));
3620
3621				// invoke ajax call
3622				var ajaxurl = nxs_js_get_adminurladminajax();
3623				jQuery.ajax
3624				(
3625					{
3626						type: 'POST',
3627						data:
3628						{
3629							"action": "nxs_ajax_webmethods",
3630							"webmethod": "removemenuitem",
3631							"postid": postid,
3632							"rowid": rowindex
3633						},
3634						cache: false,
3635						dataType: 'JSON',
3636						url: ajaxurl,
3637						success: function(response)
3638						{
3639							nxs_js_alert_wait_finish(waitgrowltoken);
3640							nxs_js_log(response);
3641
3642							var containerElement = jQuery(".nxs-post-" + postid)[0];
3643							jQuery(containerElement).html(response.html);
3644							// reenable all events
3645							nxs_js_reenable_all_window_events();
3646							nxs_js_alert(nxs_js_gettrans('Refreshed'));
3647						},
3648						error: function(response)
3649						{
3650							nxs_js_alert_wait_finish(waitgrowltoken);
3651							nxs_js_popup_notifyservererror();
3652							nxs_js_log(response);
3653						}
3654					}
3655				);
3656			}
3657			else
3658			{
3659				// nop
3660			}
3661		}
3662
3663		function nxs_js_reenable_all_window_events()
3664		{
3665			if (!nxs_js_enableguieffects())
3666			{
3667				// no further processing
3668				return;
3669			}
3670
3671			nxs_js_reregister_click_and_hover_events();
3672			nxs_js_gui_setup_drag_listeners();
3673
3674			// ensure that each img that finishes loading after we set the runtime
3675			// dimensions will trigger the runtime dimensions to be recalculated...
3676			jQuery('img').load
3677			(
3678				function()
3679				{
3680					//nxs_js_log('debug; finished loading img after reenabling all windows events; solved bug');
3681					nxs_gui_set_runtime_dimensions_enqueuerequest("nxs-framework-imgloaded");
3682				}
3683			);
3684
3685			nxs_gui_set_runtime_dimensions_enqueuerequest("nxs-framework-windoweventsreenabled");
3686
3687			if (nxs_js_userhasadminpermissions())
3688			{
3689				// als de gebruiker admin is, start het scherm altijd in edit modus,
3690				// hierbij staan we niet toe dat er tekst wordt geselecteerd
3691				if (nxs_js_nxseditoractive)
3692				{
3693					jQuery('body').disableSelection();
3694				}
3695				else
3696				{
3697					jQuery('body').enableSelection();
3698				}
3699			}
3700			//nxs_js_log('runtime dimensions set');
3701		}
3702
3703		function nxs_gui_set_runtime_dimensions_enqueuerequest(trigger)
3704		{
3705			// nxs_js_log('enqueued for:' + trigger);
3706
3707			var skip = false;
3708			if (nxs_js_isruntimedimensionsrefreshqueued())
3709			{
3710				// already enqueued, mark to skip this request,
3711				// note we wont return yet, as we first need to mark that
3712				// the enqueue also involves the specified trigger
3713				skip = true;
3714			}
3715
3716			var triggerarray;
3717			// convert trigger to array
3718			if (typeof trigger == 'string' || trigger instanceof String)
3719			{
3720				triggerarray = [trigger];
3721			}
3722			else if ($.isArray(trigger))
3723			{
3724				triggerarray = trigger;
3725				if (triggerarray.length == 0)
3726				{
3727					nxs_js_alert('Warning, trigger array is empty');
3728					nxs_js_log(trigger);
3729					return;
3730				}
3731			}
3732			else
3733			{
3734				nxs_js_alert('Warning, unsupported trigger type');
3735				nxs_js_log(trigger);
3736				return;
3737			}
3738
3739			for (var i = 0; i < triggerarray.length; i++)
3740			{
3741			  var currenttrigger = triggerarray[i];
3742			  if (!nxs_js_isrefreshqueuetriggeredby(currenttrigger))
3743				{
3744					// mark as triggered for this specific trigger
3745					nxs_js_queuedruntimedimensionsrefreshtriggers.push(currenttrigger);
3746				}
3747				else
3748				{
3749					skip = true;
3750				}
3751			}
3752
3753			if (skip)
3754			{
3755				return;
3756			}
3757
3758			// if we reach this point, it means this is the first enqueued request
3759			var nxs_max_refresh_frequency_in_msecs = 100;	// lower this amount to get a snappier speed, but poorer performance, 100 = default
3760			setTimeout
3761			(
3762				function()
3763				{
3764					//nxs_js_log('executing actual refresh work');
3765					// first we dequeue!
3766					nxs_gui_set_runtime_dimensions_actualrequest();
3767				},nxs_max_refresh_frequency_in_msecs
3768			);
3769		}
3770
3771		function nxs_js_getheightoftallestwidgetwithindomelement(domelement)
3772		{
3773			return nxs_js_getheightoftallestwidgetwithindomelement_v2(domelement, ".XYZ");
3774		}
3775
3776		function nxs_js_getheightoftallestwidgetwithindomelement_v2(domelement, innerselector)
3777		{
3778			var domelements = jQuery(domelement).find(innerselector);
3779			var result = 0;
3780			jQuery.each(domelements, function(index, currentdomelement)
3781			{
3782				var height = jQuery(currentdomelement).outerHeight(true);
3783				if (height > result)
3784				{
3785					result = height;
3786				}
3787			}
3788			);
3789			return result;
3790		}
3791
3792		// kudos to http://stackoverflow.com/questions/5503900/how-to-sort-an-array-of-objects-with-jquery-or-javascript
3793		function nxs_js_sortbyname(a, b){
3794		  var aName = a.toLowerCase();
3795		  var bName = b.toLowerCase();
3796		  return ((aName < bName) ? -1 : ((aName > bName) ? 1 : 0));
3797		}
3798
3799		function nxs_js_alignheightofelementswithindomelement(domelement, innerselector)
3800		{
3801			//nxs_js_log('aligning height for row');
3802
3803			var domelements = jQuery(domelement).find(innerselector);
3804
3805			var heighest = 0;
3806			jQuery.each(domelements, function(index, currentdomelement)
3807			{
3808				var currentheight = jQuery(currentdomelement).outerHeight(true);
3809				if (currentheight > heighest)
3810				{
3811					heighest = currentheight;
3812					//nxs_js_log('new heighest:' + heighest);
3813				}
3814			}
3815			);
3816
3817			jQuery.each(domelements, function(index, currentdomelement)
3818			{
3819				jQuery(currentdomelement).height(heighest);
3820			}
3821			);
3822		}
3823
3824		function nxs_gui_set_runtime_dimensions_actualrequest()
3825		{
3826			var scrollrevertid = nxs_js_ui_pushscrollrevert();
3827
3828			// todo: this can be optimized: the tagging of columns only has to occur when
3829			// the page is loaded, and after the core structure of the page is modified
3830			// basically when widgets/rows/containers are refreshed after a modification (delete, edit, drag... )
3831			// for now its most save to always invoke the method
3832			nxs_js_tagcolumns();
3833
3834			// make clone of enqueued triggers
3835			nxs_js_runtimedimensionsrefreshtriggers = nxs_js_queuedruntimedimensionsrefreshtriggers.slice(0);
3836
3837			// clear the enqueued triggers
3838			nxs_js_queuedruntimedimensionsrefreshtriggers = new Array();
3839
3840			// verify that at least one trigger is set
3841			if (nxs_js_runtimedimensionsrefreshtriggers.length == 0)
3842			{
3843				// no trigger set?
3844				nxs_js_log('please set a trigger, absorbing this request');
3845				return;
3846			}
3847			else
3848			{
3849				//nxs_js_log('performing actual request, made by trigger(s):');
3850				//nxs_js_log(nxs_js_runtimedimensionsrefreshtriggers);
3851			}
3852
3853			// stap 1; we resetten de hoogten, breedten en margins
3854			// deze undo-stap is belangrijk; als bijv. een lege placeholder naast een gevulde
3855			// placeholder staat, en de plapceholder er naast wordt korter door een modificatie,
3856			// dan zou de undefined placeholder de hoogte de hoogte row beinvloeden doordat
3857			// de hoogte reeds gezet is; dit is ongewenst. We verwijderen dus
3858			// allereerst de breedte en hoogtes van cellen die 'autocellsize' zijn.
3859
3860			jQuery(".nxs-valign-middle").css('margin-top', 0);
3861			jQuery(".nxs-valign-bottom").css('margin-top', 0);
3862
3863			jQuery.each
3864			(
3865				jQuery(".nxs-runtime-autocellsize"), function(index, element)
3866				{
3867					// heights
3868					if (jQuery(element).hasClass("nxs-minheight"))
3869					{
3870						if (jQuery(element).hasClass("nxs-minheight-40-0"))
3871						{
3872							jQuery(element).css('height', '40');	// defaults to height when no height is set
3873						}
3874						else if (jQuery(element).hasClass("nxs-minheight-80-0"))
3875						{
3876							jQuery(element).css('height', '80');	// defaults to height when no height is set
3877						}
3878						else if (jQuery(element).hasClass("nxs-minheight-120-0"))
3879						{
3880							jQuery(element).css('height', '120');	// defaults to height when no height is set
3881						}
3882						else if (jQuery(element).hasClass("nxs-minheight-160-0"))
3883						{
3884							jQuery(element).css('height', '160');	// defaults to height when no height is set
3885						}
3886						else if (jQuery(element).hasClass("nxs-minheight-200-0"))
3887						{
3888							jQuery(element).css('height', '200');	// defaults to height when no height is set
3889						}
3890						else if (jQuery(element).hasClass("nxs-minheight-240-0"))
3891						{
3892							jQuery(element).css('height', '240');	// defaults to height when no height is set
3893						}
3894						else if (jQuery(element).hasClass("nxs-minheight-280-0"))
3895						{
3896							jQuery(element).css('height', '280');	// defaults to height when no height is set
3897						}
3898						else if (jQuery(element).hasClass("nxs-minheight-320-0"))
3899						{
3900							jQuery(element).css('height', '320');	// defaults to height when no height is set
3901						}
3902						else if (jQuery(element).hasClass("nxs-minheight-360-0"))
3903						{
3904							jQuery(element).css('height', '360');	// defaults to height when no height is set
3905						}
3906						else if (jQuery(element).hasClass("nxs-minheight-400-0"))
3907						{
3908							jQuery(element).css('height', '400');	// defaults to height when no height is set
3909						}
3910						else if (jQuery(element).hasClass("nxs-minheight-440-0"))
3911						{
3912							jQuery(element).css('height', '440');	// defaults to height when no height is set
3913						}
3914						else if (jQuery(element).hasClass("nxs-minheight-480-0"))
3915						{
3916							jQuery(element).css('height', '480');	// defaults to height when no height is set
3917						}
3918						else
3919						{
3920							nxs_js_log('warning; min height not (yet?) supported');
3921							jQuery(element).height(88);	// defaults to height when no height is set
3922						}
3923					}
3924					else
3925					{
3926						// afhankelijk van of de editor aan- of uitstaat...
3927						if (nxs_js_nxseditoractive)
3928						{
3929							jQuery(element).height(87);	// defaults to height when no height is set
3930						}
3931						else
3932						{
3933							jQuery(element).height(0);	// defaults to height when no height is set
3934						}
3935					}
3936
3937					// any future resetting ...
3938				}
3939			);
3940
3941			//nxs_js_log('broadcasting event nxs_recalculateruntimedimensions_afterclear');
3942
3943			var widthofbrowserwindow = jQuery(window).width();
3944			// nxs_js_log("width of browser:" + widthofbrowserwindow);
3945
3946			// revert heights set previous time
3947			// reset heigthiq heights
3948			// als we deze regel hieronder uitcommentarieren ontstaat het probleem
3949			// dat de browser omhoog scrollt indien slider2 wordt gebruikt
3950			// jQuery(".nxs-heightiq").css({height:""});
3951
3952			// allow widgets and/or plugins to extend the functionality of this function (act / bind to the hook / event)
3953  		jQuery(window).trigger('nxs_recalculateruntimedimensions_afterclear');
3954
3955			var arerowsspreadalongmultirows = (widthofbrowserwindow <= 959 && nxs_js_issiteresponsive());
3956
3957			if (!arerowsspreadalongmultirows || !nxs_js_issiteresponsive())
3958			{
3959				jQuery("html").addClass("nxs-rows-nonresponsive");
3960				jQuery("html").removeClass("nxs-rows-responsive");
3961
3962				//nxs_js_log('regular - valign is active');
3963
3964				// step 2; derive heights on a per-row basis, and set the heights of the nxs-runtime-autocellsizes
3965				jQuery.each
3966				(
3967					jQuery(".nxs-row"), function(index, rowelement)
3968					{
3969						jQuery(rowelement).find(".nxs-heightiq").css({height:""});
3970
3971						// get list of "things" to align
3972						var distinctheightiqtypes = nxs_js_finddistinctclassidentifications(rowelement, "nxs-heightiq");
3973						// order items
3974						distinctheightiqtypes.sort(nxs_js_sortbyname);
3975						for (var i = 0; i < distinctheightiqtypes.length; i++)
3976						{
3977							var distinctheightiqtype = distinctheightiqtypes[i];	// bijv. "title"
3978							// nxs_js_log("distinctheightiqtype:" + distinctheightiqtype);
3979							nxs_js_alignheightofelementswithindomelement(rowelement, ".nxs-heightiq-" + distinctheightiqtype);
3980						}
3981
3982						// determine height for each individual row;
3983						// the height will be set to the height of the tallest widget
3984						// within that specific row
3985						var heighestHeightInRow = nxs_js_getheightoftallestwidgetwithindomelement(rowelement);
3986						if (heighestHeightInRow == 0)
3987						{
3988							if (nxs_js_nxseditoractive)
3989							{
3990								// if all widgets are "empty" and the editor is active we will default to 81 pixels
3991								heighestHeightInRow = 81;
3992							}
3993							else
3994							{
3995								// suppress the row!
3996								// jQuery(rowelement).addClass('nxs-suppress');
3997							}
3998						}
3999
4000						// set height for all elements within this row
4001						var elementsToBeResized = jQuery(rowelement).find(".nxs-runtime-autocellsize");
4002						jQuery.each(elementsToBeResized, function(index, element)
4003						{
4004							// houdt er rekening mee of de parent class een nxs-margin-bottom20 class heeft,
4005							// indien zo, dan moet de height 20 korter worden!
4006
4007							var shouldshrinkforborder = false;
4008							if (jQuery(element).hasClass("autosize-smaller"))
4009							{
4010								shouldshrinkforborder = true;
4011							}
4012
4013							var numofmarginbottoms = jQuery(element).closest(".nxs-placeholder").find(".nxs-margin-bottom20").length;
4014							var hasextendedmarginbottom = (numofmarginbottoms > 0);
4015							var shouldshorten = (hasextendedmarginbottom == true);
4016
4017							var heightToSet = heighestHeightInRow;
4018							if (shouldshorten)
4019							{
4020								heightToSet = heightToSet - 20;
4021							}
4022							if (shouldshrinkforborder)
4023							{
4024								heightToSet = heightToSet - 2;
4025							}
4026							jQuery(element).height(heightToSet);
4027						}
4028						);
4029
4030						//nxs_js_log("heighest row:");
4031						//nxs_js_log(heighestHeightInRow);
4032
4033
4034						// set valign
4035						var innerplaceholders = jQuery(rowelement).find(".XYZ");
4036						jQuery.each(innerplaceholders, function(index, currentinnerplaceholder)
4037						{
4038							var currentHeight = jQuery(currentinnerplaceholder).outerHeight(true);
4039
4040							// bottom
4041							var toBeValigned = jQuery(currentinnerplaceholder).parent().find(".nxs-valign-bottom");
4042							jQuery.each(toBeValigned, function(index, currentToBeValigned)
4043							{
4044								//nxs_js_log("found");
4045
4046								var deltaheight = heighestHeightInRow - currentHeight;
4047								//nxs_js_log("delta:" + deltaheight);
4048								jQuery(currentToBeValigned).css('margin-top', deltaheight);
4049							});
4050
4051							// middle
4052							var toBeValigned = jQuery(currentinnerplaceholder).parent().find(".nxs-valign-middle");
4053							jQuery.each(toBeValigned, function(index, currentToBeValigned)
4054							{
4055								//nxs_js_log("found");
4056								var deltaheight = Math.floor((heighestHeightInRow - currentHeight) / 2);
4057								//nxs_js_log("delta:" + deltaheight);
4058								jQuery(currentToBeValigned).css('margin-top', deltaheight);
4059							});
4060						}
4061						);
4062					}
4063				);
4064			}
4065			else
4066			{
4067				jQuery("html").addClass("nxs-rows-responsive");
4068				jQuery("html").removeClass("nxs-rows-nonresponsive");
4069
4070				// nxs_js_log('spread across multiple rows');
4071				// rows are potentially spread across multiple rows; we should not set heights in that case
4072
4073				jQuery.each
4074				(
4075					jQuery(".nxs-row"), function(index, rowelement)
4076					{
4077						var columnindex = 1;
4078
4079						// remove height
4080						var innerplaceholders = jQuery(rowelement).find(".XYZ");
4081						jQuery.each
4082						(
4083							innerplaceholders, function(index, currentinnerplaceholder)
4084							{
4085								jQuery(currentinnerplaceholder).css('height', null);
4086								jQuery(currentinnerplaceholder).css('margin-top', '0');
4087								// var height = jQuery(currentinnerplaceholder).css('height'); // hier zit fout-> padding meenemen
4088								var height = jQuery(currentinnerplaceholder).outerHeight(true);
4089								jQuery(currentinnerplaceholder).closest('.nxs-placeholder').css('height', height);
4090							}
4091						);
4092					}
4093				);
4094			}
4095
4096			// step 3; (re) initialize google maps (if present)
4097			// todo: move this implementation to google maps widget...
4098			for (mapkey in nxs_js_maps)
4099			{
4100				//nxs_js_log('resizing mapkey:' + mapkey);
4101				var center = nxs_js_maps[mapkey].getCenter();
4102				google.maps.event.trigger(nxs_js_maps[mapkey], 'resize');
4103				nxs_js_maps[mapkey].setCenter(center);
4104			}
4105
4106			//
4107			// automatically fit cursors that have a "nxs-autofit-to-parent" class
4108			// to the size of their parents
4109			//
4110			//nxs_js_log('auto fitting...');
4111			jQuery(".nxs-autofit-to-parent").each
4112			(
4113				function(index)
4114				{
4115					var parent = jQuery(this).parent();
4116					var width = jQuery(parent).outerWidth(true);
4117					jQuery(this).width(width);
4118					var height = jQuery(parent).outerHeight(true);
4119					jQuery(this).height(height);
4120				}
4121			);
4122
4123			//nxs_js_log('broadcasting event nxs_recalculateruntimedimensions');
4124
4125			// allow widgets and/or plugins to extend the functionality of this function (act / bind to the hook / event)
4126  		jQuery(window).trigger('nxs_recalculateruntimedimensions');
4127
4128			nxs_js_ui_popscrollrevert(scrollrevertid);
4129		}
4130
4131		function nxs_js_isrefreshtriggeredbyatleastoneof(trigger)
4132		{
4133			var triggerarray;
4134			// convert trigger to array
4135			if (typeof trigger == 'string' || trigger instanceof String)
4136			{
4137				triggerarray = [trigger];
4138			}
4139			else if (jQuery.isArray(trigger))
4140			{
4141				triggerarray = trigger;
4142				if (triggerarray.length == 0)
4143				{
4144					nxs_js_alert('Warning, trigger array is empty');
4145					nxs_js_log(trigger);
4146					return;
4147				}
4148			}
4149			else
4150			{
4151				nxs_js_alert('Warning, unsupported trigger type');
4152				nxs_js_log(trigger);
4153				return;
4154			}
4155
4156			var result = false;
4157
4158			for (var i = 0; i < triggerarray.length; i++)
4159			{
4160			  var currenttrigger = triggerarray[i];
4161				if (jQuery.inArray(currenttrigger, nxs_js_runtimedimensionsrefreshtriggers) > -1)
4162				{
4163					result = true;
4164				}
4165			}
4166
4167			//nxs_js_log('question for ' + trigger + ' is ' + result);
4168			return result;
4169		}
4170
4171		function nxs_js_isrefreshqueuetriggeredby(trigger)
4172		{
4173			var result = jQuery.inArray(trigger, nxs_js_queuedruntimedimensionsrefreshtriggers) > -1
4174			//nxs_js_log('question for queued ' + trigger + ' is ' + result);
4175			return result;
4176		}
4177
4178		function nxs_js_isruntimedimensionsrefreshqueued()
4179		{
4180			return nxs_js_queuedruntimedimensionsrefreshtriggers.length > 0;
4181		}
4182
4183 		function nxs_js_gui_getnewtempdroppablerow(element, message)
4184 		{
4185			var width = "100%;";
4186
4187 			var original = "<div class='nxs-scaffoldingrow'>" + message + "</div>";	// representeert een nieuwe regel
4188
4189			var height = 40;	// afmeting van een lege row
4190
4191			var virtuallayer1 = "<div class='nxs-one-whole' style='height:" + height + "px; position: absolute;'><div style='width: 100%; height:" + height + "px; position: inline; text-align: center;'>" + original + "</div></div>";
4192			var virtuallayer2 = "<div class='nxs-show-no-hover-with-drag nxs-one-whole' style='height:" + height + "px; position: absolute;'></div>";
4193			var virtuallayer3 = "<div class='nxs-show-hover-with-drag nxs-one-whole' style='height:" + height + "px; position: absolute;'>&nbsp;</div>";
4194			var inlinelayer = "<div class='nxs-one-whole' style='height:" + height + "px; display: block; margin-top: 2px; margin-bottom: 2px;'>&nbsp;</div>";
4195
4196 			var content = virtuallayer1 + virtuallayer2 + virtuallayer3 + inlinelayer;
4197
4198			var line = "<div class='nxs-row1 nxs-remove-after-dragdrop nxs-accept-drop'><div class='nxs-row-container'><ul class='nxs-placeholder-list'><li class='nxs-one-whole' style='list-style: none;'>" + content + "</li></ul><div class='nxs-clear'></div></div></div>";
4199 			return line;
4200 		}
4201
4202		function nxs_js_gui_getnewtempdroppablerow2(element, message)
4203		{
4204			var line = "<div class='nxs-row1 nxs-remove-after-dragdrop nxs-accept-drop'><ul class='nxs-placeholder-list'><li class='nxs-one-whole' style='list-style: none;'>" + message + "</li></ul><div class='nxs-clear'></div></div>";
4205			return line;
4206		}
4207
4208		// registers draggable dom elements
4209		function nxs_js_gui_setup_drag_listeners()
4210		{
4211			//nxs_js_log("nxs_js_gui_setup_drag_listeners()");
4212
4213			// remove draggable features registered before
4214			jQuery(".nxs-draggable").draggable("destroy");
4215
4216			// enable dragging of draggable items (placeholders, placeholderrows)
4217			jQuery(".nxs-draggable").draggable
4218			(
4219				{
4220					helper: function(event)
4221					{
4222						return "<div id='nxs-drag-container-helper' class='nxs-admin-wrap'>INIT</div>";
4223					},
4224					cursor: 'move',
4225					cursorAt: { top: 0, left: 0 },
4226					appendTo: 'body',
4227					start: function(event, ui)
4228					{
4229						//
4230						var scrollrevertid = nxs_js_ui_pushscrollrevert();
4231
4232						jQuery("html").addClass("nxs-dragging");
4233						nxs_js_nxsisdragging = true;
4234
4235						// ui: The jQuery object representing the helper that's being dragged.
4236
4237						// nxs_js_log("drag starts!");
4238						// find the drag container (if any) below the placeholder
4239
4240						// this represens the DOM element that triggers the drag
4241						var closestpostid = nxs_js_findclosestpostid_for_dom(this);	// could be null if dragging flyout menu ...
4242
4243						var helper = jQuery(this).find(".nxs-drag-helper")[0];
4244						if (helper != null)
4245						{
4246							// set content of the helper
4247							var helperHtml = jQuery(helper).html();
4248							jQuery('#nxs-drag-container-helper').html(helperHtml);
4249							//nxs_js_log("helper:" + helperHtml);
4250							//
4251							// reposition the helper such that the location of the mouse cursor is in its center
4252							//
4253
4254							var helperWidth = jQuery('#nxs-drag-container-helper').width();
4255							var deltaWidth = (helperWidth / 2);
4256							jQuery(this).data('draggable').offset.click.left += deltaWidth;
4257
4258							var helperHeight = jQuery('#nxs-drag-container-helper').height();
4259							var deltaHeight = (helperHeight / 2);
4260							jQuery(this).data('draggable').offset.click.top += deltaHeight;
4261						}
4262						else
4263						{
4264							jQuery('#nxs-drag-container-helper').html("helper not found");
4265						}
4266
4267						// find placeholder element up the DOM
4268						// het 'this' object is het object waarop de drag start
4269						// in ons geval is dit de <LI> (cursor)
4270
4271						var sourcedragtype = "";
4272						var sourcedragmeta = "";
4273
4274						if (jQuery(this).hasClass("nxs-toolbox-item") && jQuery(this).hasClass("nxs-dragtype-pagerowtemplate"))
4275						{
4276							// het is een toolbox item en representeert een pagerow
4277							// sourcedragmeta => pagerowtemplate
4278							sourcedragtype = "toolboxpagerowtemplate";
4279							sourcedragmeta = this.id.split("_")[2];
4280						}
4281						else if (jQuery(this).hasClass("nxs-existing-pageitem") && jQuery(this).hasClass("nxs-dragtype-placeholder"))
4282						{
4283							sourcedragtype = "placeholderswap";
4284							sourcedragmeta = this.id.split("_")[1];
4285						}
4286						else
4287						{
4288							alert("unknown source for drag");
4289						}
4290
4291						jQuery('#nxs-drag-container-helper').data('sourcedragtype', sourcedragtype);
4292						jQuery('#nxs-drag-container-helper').data('sourcedragmeta', sourcedragmeta);
4293						jQuery('#nxs-drag-container-helper').data('sourcedragelement', this);
4294
4295						// hier
4296						nxs_js_gui_add_drop_scaffolding();
4297						nxs_js_gui_setup_drop_listeners();
4298
4299						nxs_js_ui_popscrollrevert(scrollrevertid);
4300						//nxs_js_log("drag finishes	!");
4301
4302          },
4303					revert: function(socketObj)
4304					{
4305						nxs_js_nxsisdragging = false;
4306						jQuery("html").removeClass("nxs-dragging");
4307						//nxs_js_log("removed nxs-dragging from html");
4308
4309						//nxs_js_log("revert starts!");
4310						//return false;
4311
4312            if (socketObj === false)
4313            {
4314              // Drop was rejected; don't revert with an animation
4315            	//nxs_js_log('drop was rejected');
4316
4317							var sourcedragtype = jQuery('#nxs-drag-container-helper').data('sourcedragtype');
4318							var sourcedragmeta = jQuery('#nxs-drag-container-helper').data('sourcedragmeta');
4319
4320							if (sourcedragtype == 'placeholderswap')
4321							{
4322								nxs_js_alert(nxs_js_gettrans('Widget was not moved'));
4323							}
4324							else if (sourcedragtype == 'toolboxpagerowtemplate')
4325							{
4326								nxs_js_alert(nxs_js_gettrans('Drag the column layout on one of the highlighted sections'));
4327							}
4328							else
4329							{
4330								nxs_js_log("sourcedragtype not (yet?) supported;" + sourcedragtype);
4331							}
4332
4333 							//nxs_js_log("revert finishes!");
4334
4335            	//nxs_js_log(this);
4336              return false;
4337            }
4338            else
4339            {
4340 							//nxs_js_log("revert finishes (2)!");
4341
4342            	//nxs_js_log('drop was accepted');
4343              // Drop was accepted, don't revert with an animation
4344              return false;
4345            }
4346          },
4347          stop: function(event, ui)
4348					{
4349						nxs_js_nxsisdragging = false;
4350						jQuery("html").removeClass("nxs-dragging");
4351						//nxs_js_log("removed nxs-dragging from html");
4352
4353						//nxs_js_log("stop starts!");
4354						nxs_js_gui_cleanup_drag_scaffolding();
4355						//nxs_js_log("stop finishes!");
4356					},
4357					drag: function(event, ui)
4358					{
4359						// Triggered while the mouse is moved during the dragging.
4360
4361						jQuery(".nxs-layout-editable").each
4362						(
4363							function(pcindex, pagecontainer)
4364							{
4365								if (jQuery(pagecontainer).hasClass("nxs-menu-container") || jQuery(pagecontainer).hasClass("nxs-list-container"))
4366								{
4367									// dit moet alleen als er sprake is van een menu / lijst
4368
4369									//nxs_js_log('dragging like crazy...');
4370
4371									//
4372									// step 1; hide all dropping zones, but show the ones currently showing
4373									//
4374									jQuery(pagecontainer).find(".nxs-remove-after-dragdrop").each
4375									(
4376										function(index, element)
4377										{
4378											// clean up
4379											jQuery(element).hide();
4380										}
4381									);
4382									//jQuery(".showing").show();
4383
4384									//
4385									// step 2; calculate nearest nxs-row that has scaffolding row
4386									//
4387									var nearest = 99999;
4388									var nearestrow = null;
4389									jQuery(pagecontainer).find(".nxs-row").each
4390									(
4391										function(index, element)
4392										{
4393											if (jQuery(element).find(".nxs-remove-after-dragdrop").length > 0)
4394											{
4395												// clean up
4396												var topposition = jQuery(element).offset().top + jQuery(element).height();
4397												var helperposition = Math.floor(jQuery('#nxs-drag-container-helper').offset().top - 25);
4398
4399												var deltaposition = topposition - helperposition;
4400												if (deltaposition > 0 && deltaposition < nearest)
4401												{
4402													nearest = deltaposition;
4403													nearestrow = element;
4404													//nxs_js_log("delta:" + deltaposition + "/nearest:" + nearest);
4405												}
4406											}
4407										}
4408									);
4409
4410									// step 3; remove any previously showing classes
4411									jQuery(pagecontainer).find(".showing").removeClass("showing");
4412
4413									//
4414									// step 4; show each scaffolding item within the closest row
4415									//
4416									var scaffolds = jQuery(nearestrow).find(".nxs-remove-after-dragdrop");
4417									var aantal = jQuery(scaffolds).length;
4418									if (aantal == 0)
4419									{
4420										nxs_js_log('Expected to show at least one scaffolding row...');
4421									}
4422									else if (aantal == 1)
4423									{
4424										// if there's one scaffold, always show that one!
4425										jQuery(scaffolds).show();
4426									 	jQuery(scaffolds).addClass("showing");
4427									}
4428									else if (aantal == 2)
4429									{
4430										var helperpositionleft = jQuery('#nxs-drag-container-helper').offset().left;
4431										var rowpositionleft = jQuery(nearestrow).offset().left;
4432										var showleft = true;
4433										var deltaleft = helperpositionleft - rowpositionleft;
4434										if (deltaleft > 60)
4435										{
4436											var showleft = false;
4437										}
4438										//nxs_js_log('rowpositionleft:' + rowpositionleft);
4439										//nxs_js_log('deltaleft:' + deltaleft);
4440										// based upon the mouse x we decide whether the show the left, or the right one
4441
4442										if (showleft)
4443										{
4444											jQuery(jQuery(scaffolds)[0]).show();
4445											jQuery(jQuery(scaffolds)[0]).addClass("showing");
4446										}
4447										else
4448										{
4449											jQuery(jQuery(scaffolds)[1]).show();
4450											jQuery(jQuery(scaffolds)[1]).addClass("showing");
4451										}
4452									}
4453									else
4454									{
4455										//nxs_js_log('Expected max 2 scaffolding rows ...');
4456									}
4457								}
4458							}
4459						);
4460					}
4461				}
4462			);
4463		}
4464
4465		function nxs_js_gui_cleanup_drag_scaffolding()
4466		{
4467			// revert things requiring reverting...
4468			jQuery(".nxs-revert-after-dragdrop").each
4469			(
4470				function(index, element)
4471				{
4472					// clean up
4473					jQuery(element).removeClass("nxs-revert-after-dragdrop");
4474					jQuery(element).data('nxs-revert-content', '');
4475				}
4476			);
4477
4478			// remove temporary things (used for rows)
4479			jQuery(".nxs-remove-after-dragdrop").remove();
4480
4481			// remove rows accepting drops (used for rows)
4482			jQuery(".nxs-accept-drop").removeClass("nxs-accept-drop");
4483
4484			nxs_js_reenable_all_window_events();
4485		}
4486
4487		function nxs_js_gui_add_virtual_droppable_pagerows()
4488		{
4489			var scrollstatebefore = { 'scrolltop' : jQuery(window).scrollTop(), 'docheight' : jQuery('html').height() };
4490
4491			// OK
4492			jQuery(".nxs-layout-editable").each
4493			(
4494				function(pcindex, pagecontainer)
4495				{
4496					// filter out
4497					if (jQuery(pagecontainer).hasClass("nxs-wpcontent-container"))
4498					{
4499						// continu the foreach jquery loop (not break it; continu!)
4500						return true;
4501					}
4502
4503					var text;
4504					if (jQuery(pagecontainer).hasClass("nxs-subheader-container"))
4505					{
4506						text = 'Drop here (subheader)';
4507					}
4508					else if (jQuery(pagecontainer).hasClass("nxs-subfooter-container"))
4509					{
4510						text = 'Drop here (subfooter)';
4511					}
4512					else if (jQuery(pagecontainer).hasClass("nxs-sidebar-container"))
4513					{
4514						text = 'Drop here (sidebar)';
4515					}
4516					else if (jQuery(pagecontainer).hasClass("nxs-header-container"))
4517					{
4518						text = 'Drop here (header)';
4519					}
4520					else if (jQuery(pagecontainer).hasClass("nxs-footer-container"))
4521					{
4522						text = 'Drop here (footer)';
4523					}
4524					else
4525					{
4526					 	text = 'Drop here';
4527					}
4528
4529					var localizedtext = nxs_js_gettrans(text);
4530
4531					// add dummy rows as dropping points
4532					var allrows = jQuery(pagecontainer).find(".nxs-row");
4533					if (allrows.length == 0)
4534					{
4535						var pagerowselement = jQuery(pagecontainer).find(".nxs-postrows")[0];
4536
4537						var newDomElement = jQuery(nxs_js_gui_getnewtempdroppablerow(pagerowselement, localizedtext));
4538						newDomElement.data('destinationdragtype', 'nieuweregel');
4539						newDomElement.data('destinationdragmeta', -1);
4540						jQuery(pagerowselement).append(newDomElement);
4541					}
4542					else
4543					{
4544						allrows.each
4545						(
4546							function(index, rowelement)
4547							{
4548								if (index == 0)
4549								{
4550									// bij de eerste regel is er iets speciaals aan de hand:
4551									// ipv dat we telkens ACHTER de regel een row toevoegen,
4552									// voegen we hierbij tevens een row toe aan de VOORKANT.
4553									var newDomElement = jQuery(nxs_js_gui_getnewtempdroppablerow(rowelement, localizedtext));
4554									newDomElement.data('destinationdragtype', 'nieuweregel');
4555									newDomElement.data('destinationdragmeta', -1);
4556									jQuery(rowelement).before(newDomElement);
4557								}
4558
4559								if (true)
4560								{
4561									// we voegen achter iedere rij een tijdelijke placeholder
4562									// row toe
4563									var newDomElement = jQuery(nxs_js_gui_getnewtempdroppablerow(rowelement, localizedtext));
4564									newDomElement.data('destinationdragtype', 'nieuweregel');
4565									newDomElement.data('destinationdragmeta', index);
4566									jQuery(rowelement).after(newDomElement);
4567								}
4568							}
4569						);
4570					}
4571				}
4572			);
4573
4574			// step 2; make rows 0 height
4575			jQuery(".nxs-remove-after-dragdrop").css('height', '0px');
4576			jQuery(".nxs-remove-after-dragdrop").css('overflow', 'hidden');
4577
4578			// step 3; determine which elements are visible, and which ones are not
4579			jQuery(".nxs-remove-after-dragdrop").each
4580			(
4581				function(indexer, e)
4582				{
4583					if (nxs_js_iselementabovepieceofviewport(e,4))	// 1/4
4584					{
4585						jQuery(e).addClass("nxs-aboveviewport");
4586					}
4587					else
4588					{
4589						jQuery(e).addClass("nxs-inorbelowviewport");
4590					}
4591				}
4592			);
4593
4594			// step 4; make rows visible that were visible above viewport
4595			jQuery(".nxs-aboveviewport").css('height', 'inherit');
4596			jQuery(".nxs-aboveviewport").css('overflow', 'inherit');
4597
4598			setTimeout
4599			(
4600				function(scrollstatebefore)
4601				{
4602					// step 5; if we reach this point, the height will have increased
4603					var scrollstateafter = { 'scrolltop' : jQuery(window).scrollTop(), 'docheight' : jQuery('html').height() };
4604					//nxs_js_log("scrollstateafter.docheight:");
4605					//nxs_js_log(scrollstateafter.docheight);
4606
4607					// step 6; derive the height difference before and after
4608					var scrollposdelta = scrollstateafter.docheight - scrollstatebefore.docheight;
4609					//nxs_js_log("scrollposdelta:");
4610					//nxs_js_log(scrollposdelta);
4611
4612					// step 7; scroll!!!
4613					var scrollposto = scrollstateafter.scrolltop + scrollposdelta;
4614					//nxs_js_log("scrollposto:");
4615					//nxs_js_log(scrollposto);
4616					jQuery(window).scrollTop(scrollposto);
4617
4618					// step 8; make rows visible that were visible in the viewport or below the viewport
4619					jQuery(".nxs-inorbelowviewport").css('height', 'inherit');
4620					jQuery(".nxs-inorbelowviewport").css('overflow', 'inherit');
4621				},
4622				1,	// 1 msec delay to update the gui thread... :/
4623				scrollstatebefore
4624			);
4625		}
4626
4627		function nxs_js_identify_rows_as_recursivelistitems()
4628		{
4629			// OK
4630			jQuery(".nxs-layout-editable").each
4631			(
4632				function(pcindex, pagecontainer)
4633				{
4634					// add dummy rows as dropping points
4635					var allrows = jQuery(pagecontainer).find(".nxs-row");
4636
4637					// setup initial values
4638					var rowid = 1;
4639					allrows.each
4640					(
4641						function(index, rowelement)
4642						{
4643							jQuery(rowelement).data('rowid', rowid);
4644							jQuery(rowelement).data('listitemid', '');
4645							jQuery(rowelement).data('recursionrequired', '');
4646							rowid++;
4647						}
4648					);
4649
4650					var sofar = "";
4651					var initialcurrentdepth = 1;
4652					nxs_js_menuid_siblingcounters = {};
4653					nxs_js_menuid_preventendlessloop = 1000;
4654
4655					//
4656					nxs_js_set_listitemid_recursive(allrows, sofar, initialcurrentdepth);
4657				}
4658			);
4659		}
4660
4661		function nxs_js_gui_add_virtual_droppable_pagerows_for_list()
4662		{
4663			nxs_js_identify_rows_as_recursivelistitems();
4664
4665			var element = jQuery('#nxs-drag-container-helper').data('sourcedragelement');
4666			var sourcerow = jQuery(element).closest('.nxs-row');
4667
4668			var listitemidofsourcerow = jQuery(sourcerow).data('listitemid');
4669			//nxs_js_log("bronregel:" + listitemidofsourcerow);
4670
4671			// als we hier komen zijn alle menu item ids gezet...
4672			// OK
4673			jQuery(".nxs-layout-editable").each
4674			(
4675				function(pcindex, pagecontainer)
4676				{
4677					var allrows = jQuery(pagecontainer).find(".nxs-row");
4678					allrows.each
4679					(
4680						function(index, rowelement)
4681						{
4682							var listitemid = jQuery(rowelement).data('listitemid');
4683							//nxs_js_log('listitemid :' + listitemid);
4684
4685							if (listitemid == listitemidofsourcerow)
4686							{
4687								//nxs_js_log('ignoring :' + listitemid + '(dit zijn we zelf)');
4688							}
4689							else if (listitemid.startsWith(listitemidofsourcerow))
4690							{
4691								// het huidige item is een child van het item dat wordt gedragd,
4692								// ignoren
4693								//nxs_js_log('ignoring :' + listitemid + '(dit is een child van het draggable item)');
4694							}
4695							else if (false)
4696							{
4697								// TODO; er is nog een specifieke uitzonderingssituatie:
4698								// indien de huidige item de parent is van het item dat wordt gedragged
4699								// dat kan het item alleen als sibling worden geplaatst,
4700								// en niet als child (immers: het is dan reeds de child!)
4701							}
4702							else
4703							{
4704								//nxs_js_log('droppable :' + listitemid + '(dit is geen child van het draggable item)');
4705
4706								var depth = nxs_js_getmenuitemdepth_in_dom(rowelement);
4707								var childdepth = depth + 1;
4708
4709								var pagerowselement = jQuery(pagecontainer).find(".nxs-postrows")[0];
4710
4711								var line = "<div class='nxs-padding-menu-item'><div class='content2 nxs-border-dash nxs-drop-area nxs-margin-left" + (depth - 1) * 30 + " nxs-show-no-hover-with-drag nxs-show-hover-with-drag'><div class='nxs-clear'>&nbsp;</div></div></div>";
4712								var current_element_accepting_drop = jQuery(nxs_js_gui_getnewtempdroppablerow2(pagerowselement, line));
4713								jQuery(current_element_accepting_drop).data('destinationdragtype', 'menuitem');
4714								jQuery(current_element_accepting_drop).data('destinationdragmeta', index + "_" + depth);
4715								jQuery(rowelement).append(current_element_accepting_drop);
4716
4717								var line = "<div class='nxs-padding-menu-item'><div class='content2 nxs-border-dash nxs-drop-area nxs-margin-left" + (childdepth - 1) * 30 + " nxs-show-no-hover-with-drag nxs-show-hover-with-drag'><div class='nxs-clear'>&nbsp;</div></div></div>";
4718								var current_element_accepting_drop = jQuery(nxs_js_gui_getnewtempdroppablerow2(pagerowselement, line));
4719								jQuery(current_element_accepting_drop).data('destinationdragtype', 'menuitem');
4720								jQuery(current_element_accepting_drop).data('destinationdragmeta', index + "_" + childdepth);
4721								jQuery(rowelement).append(current_element_accepting_drop);
4722							}
4723						}
4724					);
4725				}
4726			);
4727		}
4728
4729		function nxs_js_set_listitemid_recursive(allrows, sofar, currentdepth)
4730		{
4731			allrows.each
4732			(
4733				function(index, rowelement)
4734				{
4735					var recursionrequired = jQuery(rowelement).data('recursionrequired');
4736					var currentlistitemid = jQuery(rowelement).data('listitemid');
4737					var currentrowid = jQuery(rowelement).data('rowid');
4738					var currentChildDepthIndex = nxs_js_getmenuitemdepth_in_dom(rowelement);
4739
4740					//nxs_js_log("processing row: " + currentrowid);
4741
4742					if (currentdepth > currentChildDepthIndex)
4743					{
4744						// next element please (continue loop)
4745						// jQuery(rowelement).data('recursionrequired', 'false');
4746						//nxs_js_log("ignoring row: " + currentrowid);
4747						return true;
4748					}
4749					else
4750					{
4751						if (recursionrequired == sofar && sofar == currentlistitemid)
4752						{
4753							//nxs_js_log("processing row : " + currentrowid + " so far; " + sofar);
4754
4755							if (currentChildDepthIndex == currentdepth)
4756							{
4757								//nxs_js_log("found leaf for row " + currentrowid);
4758
4759								if (nxs_js_menuid_siblingcounters[currentlistitemid] == null)
4760								{
4761									nxs_js_menuid_siblingcounters[currentlistitemid] = 0;
4762								}
4763
4764								nxs_js_menuid_siblingcounters[currentlistitemid] = nxs_js_menuid_siblingcounters[currentlistitemid] + 1;
4765
4766								//nxs_js_log("new sibling count for [" + currentlistitemid + "] is " + nxs_js_menuid_siblingcounters[currentlistitemid]);
4767
4768								var sofarforthisrow = currentlistitemid + "." + nxs_js_menuid_siblingcounters[currentlistitemid];
4769
4770								jQuery(rowelement).data('listitemid', sofarforthisrow);
4771								jQuery(rowelement).data('recursionrequired', 'false');
4772
4773								//nxs_js_log("setting (final) listitemid for row " + currentrowid + " to " + jQuery(rowelement).data('listitemid'));
4774							}
4775							else if (currentChildDepthIndex > currentdepth)
4776							{
4777								//nxs_js_log("found node for row " + currentrowid);
4778
4779								if (nxs_js_menuid_siblingcounters[currentlistitemid] == null)
4780								{
4781									//nxs_js_log("geen nxs_js_menuid_siblingcounters gevonden voor " + currentlistitemid);
4782								}
4783
4784								var sofarforthisrow = currentlistitemid + "." + nxs_js_menuid_siblingcounters[currentlistitemid];
4785								jQuery(rowelement).data('listitemid', sofarforthisrow);
4786								jQuery(rowelement).data('recursionrequired', sofarforthisrow);
4787
4788								//nxs_js_log("setting (non-final) listitemid for row " + currentrowid + " to " + jQuery(rowelement).data('listitemid'));
4789
4790								// recurse!
4791								nxs_js_menuid_preventendlessloop--;
4792								if (nxs_js_menuid_preventendlessloop > 0)
4793								{
4794									nxs_js_set_listitemid_recursive(allrows, sofarforthisrow, currentdepth + 1);
4795								}
4796								else
4797								{
4798									//nxs_js_log("preventing endless loop...");
4799								}
4800							}
4801							else
4802							{
4803								//nxs_js_log("aha!");
4804							}
4805						}
4806						else
4807						{
4808							// ignore; item is finished or will be processed by another invocation
4809							//nxs_js_log("row: " + currentrowid + " is either already finsihed processing, or will be processed later on");
4810						}
4811					}
4812				}
4813			);
4814		}
4815
4816		function nxs_js_gui_make_existing_placeholders_droppable_regular()
4817		{
4818			// restrain the droppable placeholders to the nxs-post-XYZ of the
4819			// source, if present
4820
4821			var sourcedragelement = jQuery('#nxs-drag-container-helper').data('sourcedragelement');
4822			var closestpostid = nxs_js_findclosestpostid_for_dom(sourcedragelement);
4823			var containers_in_scope;
4824			if (closestpostid != null)
4825			{
4826				// if you only want to allow drag and drop in the
4827				// closest container, use the following commented line
4828				// containers_in_scope = jQuery(".nxs-layout-editable.nxs-post-" + closestpostid);
4829				// to enable drag and drop between containers, use the following:
4830				containers_in_scope = jQuery(".nxs-layout-editable");
4831			}
4832			else
4833			{
4834				// this means we drag a rowtemplate from flyout;
4835				// allow all editable containers as drop
4836				containers_in_scope = jQuery(".nxs-layout-editable");
4837			}
4838
4839			jQuery(containers_in_scope).each
4840			(
4841				function(pcindex, pagecontainer)
4842				{
4843					// virtually upgrade placeholder containers as dropping points
4844					jQuery(pagecontainer).find(".nxs-placeholder").each
4845					(
4846						function(index, current_element_accepting_drop)
4847						{
4848							try
4849							{
4850								var doelplaceholderid = nxs_js_getfirstplaceholderid_in_dom(current_element_accepting_drop);
4851								if (doelplaceholderid == null)
4852								{
4853									alert("geen placeholderid gevonden in element");
4854								}
4855
4856								//
4857								// speciaal uitzonderingsgeval; indien de huidige placeholder zelf nu wordt gedragged
4858								// dan moeten we deze natuurlijk niet zelf droppable maken
4859								//
4860								var dragtype = jQuery('#nxs-drag-container-helper').data('sourcedragtype');
4861								if (dragtype == 'placeholderswap')
4862								{
4863									var sourcedragmeta = jQuery('#nxs-drag-container-helper').data('sourcedragmeta');
4864									var sourceplaceholderid = sourcedragmeta;
4865									if (sourceplaceholderid == doelplaceholderid)
4866									{
4867										return true;	// this means: continu the loop
4868									}
4869								}
4870
4871								//
4872								// process normally
4873								//
4874								var original = jQuery(current_element_accepting_drop).html();
4875								jQuery(current_element_accepting_drop).data('nxs-revert-content', original);		// required for reverting back
4876
4877								var width = jQuery(current_element_accepting_drop).width();
4878								var height = jQuery(current_element_accepting_drop).height();
4879
4880								jQuery(current_element_accepting_drop).data('destinationdragtype', 'existingplaceholder');
4881								jQuery(current_element_accepting_drop).data('destinationdragmeta', doelplaceholderid);
4882								jQuery(current_element_accepting_drop).addClass("nxs-accept-drop");
4883
4884								// nxs-revert-after-dragdrop");
4885
4886								// construct layers for this placeholder
4887								// layer 1 = wrapped item visualizing the existing content (absolutely positioned; NOT in the document flow)
4888								// layer 2 = wrapped item representing a semi transparent layer; NOT in the document flow)
4889								// layer 3 = wrapped item representing a semi transparent layer; NOT in the document flow)
4890								// inline layer = empty (transparent) layer, required to set the height inline
4891								var virtuallayer1 = "<div style='width:" + width + "px; height:" + height + "px; position: absolute;'>" + original + "</div>";
4892								var virtuallayer2 = "<div class='nxs-show-no-hover-with-drag' style='width:" + width + "px; height:" + height + "px; position: absolute;'></div>";
4893								var virtuallayer3 = "<div class='nxs-show-hover-with-drag' style='width:" + width + "px; height:" + height + "px; position: absolute;'>&nbsp;</div>";
4894
4895								jQuery(current_element_accepting_drop).find(".nxs-drop-cursor").html(virtuallayer3);
4896
4897								var inlinelayer = "<div style='width:" + width + "px; height:" + height + "px; display: block; overflow: hidden;'>&nbsp;</div>";
4898
4899								//var combined = virtuallayer1 + virtuallayer2 + virtuallayer3 + inlinelayer;
4900								// override old html with upgraded variant that allows dropping
4901
4902								//jQuery(current_element_accepting_drop).html(combined);
4903							}
4904							catch(err)
4905							{
4906								alert('fee(2);' + err);
4907							}
4908						}
4909					);
4910				}
4911			);
4912		}
4913
4914		function nxs_js_gui_add_drop_scaffolding()
4915		{
4916			//nxs_js_log("nxs_js_gui_add_drop_scaffolding()");
4917			//
4918			// add and upgrade gui elements
4919			//
4920			var sourcedragtype = jQuery('#nxs-drag-container-helper').data('sourcedragtype');
4921
4922			if (sourcedragtype == 'placeholderswap')
4923			{
4924				//
4925				// indien de drag source container een nxs-menu-container is, dan
4926				// moeten er geen nieuwe regels worden toegevoegd
4927				//
4928
4929				var pagecontainer = jQuery(".nxs-layout-editable");
4930
4931				if (pagecontainer.length == 1)
4932				{
4933					if (jQuery(pagecontainer).hasClass("nxs-menu-container"))
4934					{
4935						nxs_js_gui_add_virtual_droppable_pagerows_for_list();
4936					}
4937					else if (jQuery(pagecontainer).hasClass("nxs-list-container"))
4938					{
4939						nxs_js_gui_add_virtual_droppable_pagerows_for_list();
4940					}
4941					else if (jQuery(pagecontainer).hasClass("nxs-slideset-container"))
4942					{
4943						// regular!
4944						nxs_js_gui_make_existing_placeholders_droppable_regular();
4945					}
4946					else if (jQuery(pagecontainer).hasClass("nxs-genericlist-container"))
4947					{
4948						// regular!
4949						nxs_js_gui_make_existing_placeholders_droppable_regular();
4950					}
4951					else if (jQuery(pagecontainer).hasClass("nxs-sidebar-container"))
4952					{
4953						nxs_js_gui_make_existing_placeholders_droppable_regular();
4954					}
4955					else if (jQuery(pagecontainer).hasClass("nxs-pagelet-container"))
4956					{
4957						nxs_js_gui_make_existing_placeholders_droppable_regular();
4958					}
4959					else if (jQuery(pagecontainer).hasClass("nxs-subheader-container"))
4960					{
4961						nxs_js_gui_make_existing_placeholders_droppable_regular();
4962					}
4963					else if (jQuery(pagecontainer).hasClass("nxs-subfooter-container"))
4964					{
4965						nxs_js_gui_make_existing_placeholders_droppable_regular();
4966					}
4967					else if (jQuery(pagecontainer).hasClass("nxs-header-container"))
4968					{
4969						nxs_js_gui_make_existing_placeholders_droppable_regular();
4970					}
4971					else if (jQuery(pagecontainer).hasClass("nxs-footer-container"))
4972					{
4973						nxs_js_gui_make_existing_placeholders_droppable_regular();
4974					}
4975					else if (jQuery(pagecontainer).hasClass("nxs-article-container"))
4976					{
4977						nxs_js_gui_make_existing_placeholders_droppable_regular();
4978					}
4979					else if (jQuery(pagecontainer).hasClass("nxs-busrulesset-container"))
4980					{
4981						nxs_js_gui_make_existing_placeholders_droppable_regular();
4982					}
4983					else
4984					{
4985					  var otherclass = jQuery(pagecontainer).attr("class");
4986						nxs_js_log('someothercondition?;' + otherclass);
4987					}
4988				}
4989				else
4990				{
4991					// reguliere pagina
4992					nxs_js_gui_make_existing_placeholders_droppable_regular();
4993				}
4994			}
4995			else if (sourcedragtype == 'toolboxpagerowtemplate')
4996			{
4997				// note! its not allowed to drop a pagerowtemplate on an existing placeholder ...
4998				nxs_js_gui_add_virtual_droppable_pagerows();
4999			}
5000			else
5001			{
5002				nxs_js_log("sourcedragtype not (yet?) supported;" + sourcedragtype);
5003			}
5004		}
5005
5006		function pausecomp(millis)
5007		{
5008		var date = new Date();
5009		var curDate = null;
5010
5011		do { curDate = new Date(); }
5012		while(curDate-date < millis);
5013		}
5014
5015		function nxs_js_gui_setup_drop_listeners()
5016		{
5017			//nxs_js_log("nxs_js_gui_setup_drop_listeners()");
5018			//
5019			// allow dropping on scaffolds (draggable objects)
5020			//
5021
5022			// first unregister any scripts
5023			jQuery(".nxs-accept-drop").droppable("destroy");
5024
5025			// register new drops
5026			jQuery(".nxs-accept-drop").droppable
5027			(
5028				{
5029					activeClass: "ui-state-active",
5030					hoverClass: "nxs-ui-state-hover",
5031					accept: function(d)
5032					{
5033						// accept drops from any type
5034						return true;
5035	        },
5036	        over: function(event, ui)
5037	        {
5038	        	// ...
5039	        },
5040	        out: function(event, ui)
5041	        {
5042	        	// ...
5043	        },
5044					drop: function( event, ui )
5045					{
5046						var sourcedragelement = jQuery('#nxs-drag-container-helper').data('sourcedragelement');
5047						var sourcepostid = nxs_js_findclosestpostid_for_dom(sourcedragelement);
5048						var destinationpostid = nxs_js_findclosestpostid_for_dom(this);
5049						var containerpostid = nxs_js_getcontainerpostid();
5050
5051						/*
5052						nxs_js_log("sourcedragelement:" + sourcedragelement);
5053						nxs_js_log("sourcepostid:" + sourcepostid);
5054
5055						nxs_js_log("destinationpostid:" + destinationpostid);
5056						nxs_js_log("containerpostid:" + containerpostid);
5057						*/
5058
5059						var sourcedragtype = jQuery('#nxs-drag-container-helper').data('sourcedragtype');
5060						var sourcedragmeta = jQuery('#nxs-drag-container-helper').data('sourcedragmeta');
5061						var destinationdragtype = jQuery(this).data("destinationdragtype");
5062						var destinationdragmeta = jQuery(this).data('destinationdragmeta');
5063
5064						if (sourcedragtype == 'placeholderswap')
5065						{
5066							if (destinationdragtype == 'existingplaceholder')
5067							{
5068								// er vindt een 'swap' plaats; een placeholder wordt van de ene naar
5069								// een andere plek verplaatst, we doen twee dingen:
5070								// 1. persisteer de wijzigingen op de server
5071								// 2. swap de DOM van de containers
5072								var sourceplaceholderid = sourcedragmeta;
5073								var destinationplaceholderid = destinationdragmeta;
5074								nxs_js_swapplaceholders(containerpostid, sourcepostid, sourceplaceholderid, containerpostid, destinationpostid, destinationplaceholderid);
5075								nxs_js_alert(nxs_js_gettrans('Widgets swapped'));
5076							}
5077							else if (destinationdragtype == 'nieuweregel')
5078							{
5079								nxs_js_alert('dragging an existing placeholder to a new row is no longer supported...');
5080							}
5081							else if (destinationdragtype == 'menuitem')
5082							{
5083								// we verplaatsen het menu item naar de nieuwe rij en we updaten de menu diepte
5084								var insertafterrowindex = destinationdragmeta.split('_')[0];
5085								var newdepth = destinationdragmeta.split('_')[1];
5086								var sourceplaceholderid = sourcedragmeta;
5087								// sourcepostid == destinationpostid
5088								nxs_js_updatemenuitemlocation(sourcepostid, sourceplaceholderid, insertafterrowindex, newdepth);
5089							}
5090							else
5091							{
5092								nxs_js_log("destinationdragtype not (yet?) supported (1);" + destinationdragtype);
5093							}
5094						}
5095						else if (sourcedragtype == 'toolboxpagerowtemplate')
5096						{
5097							if (destinationdragtype == 'nieuweregel')
5098							{
5099								var waitgrowltoken = nxs_js_alert_wait_start(nxs_js_gettrans('Adding row'));
5100
5101								var insertafterrowindex = destinationdragmeta;
5102								var pagerowtemplate = sourcedragmeta;
5103								var destinationpagerows = jQuery(this).closest(".nxs-postrows")[0];
5104								var placeholdertemplate = ""; // not applicable
5105								nxs_js_addnewrowwithtemplate(destinationpostid, insertafterrowindex, pagerowtemplate, placeholdertemplate, destinationpagerows,
5106								function()
5107								{
5108									nxs_js_alert_wait_finish(waitgrowltoken);
5109								},
5110								function()
5111								{
5112									nxs_js_alert_wait_finish(waitgrowltoken);
5113								}
5114								);
5115							}
5116							else
5117							{
5118								nxs_js_log("destinationdragtype not (yet?) supported (3);" + destinationdragtype);
5119							}
5120						}
5121						else
5122						{
5123							nxs_js_log("sourcedragtype not (yet?) supported;" + sourcedragtype);
5124						}
5125					},
5126					tolerance: "pointer"
5127				}
5128			);
5129		}
5130
5131		function nxs_js_addnewrowwithtemplate(postid, insertafterrowindex, pagerowtemplate, placeholdertemplate, element, invokewhenavailable, invokewhenfailed)
5132		{
5133			// invoke ajax call
5134			var ajaxurl = nxs_js_get_adminurladminajax();
5135			jQuery.ajax
5136			(
5137				{
5138					type: 'POST',
5139					data:
5140					{
5141						"action": "nxs_ajax_webmethods",
5142						"webmethod": "addnewrowwithtemplate",
5143
5144						"postid": postid,
5145						"insertafterrowindex": insertafterrowindex,
5146						"pagerowtemplate": pagerowtemplate,
5147						"placeholdertemplate": placeholdertemplate
5148					},
5149					cache: false,
5150					dataType: 'JSON',
5151					url: ajaxurl,
5152					success: function(insertresponse)
5153					{
5154						nxs_js_log(insertresponse);
5155						if (insertresponse.result == "OK")
5156						{
5157							// insert render result for pagerow ("row insertafterrowindex + 1")
5158							//nxs_js_log("deze?(2)");
5159							nxs_js_row_render(postid, insertafterrowindex + 1,
5160								function(postid, rowindex, renderresponse)
5161								{
5162									var html = renderresponse.html;
5163
5164									// insert the dom element
5165									if (insertafterrowindex == -1)
5166									{
5167										// html toevoegen
5168										var newhtmlelement = jQuery(html);
5169										jQuery(newhtmlelement).hide();
5170										jQuery(element).prepend(newhtmlelement);
5171
5172										var therow = jQuery(element).find(".nxs-row")[0];
5173										jQuery(therow).slideDown(300, function()
5174										{
5175											// de hoogte is aangepast, pas ook de sidebar hoogte aan (indien nodig)
5176											nxs_js_reenable_all_window_events();
5177										});
5178									}
5179									else
5180									{
5181										// insert at certain index
5182										var pagecontainer = jQuery(element);
5183										var siblingElement = pagecontainer.children()[insertafterrowindex];
5184
5185										// html toevoegen
5186										var newhtmlelement = jQuery(html);
5187										jQuery(newhtmlelement).hide();
5188										jQuery(siblingElement).after(newhtmlelement);
5189
5190										var therow = jQuery(element).find(".nxs-row")[insertafterrowindex+1];
5191										jQuery(therow).slideDown(300, function()
5192										{
5193											// de hoogte is aangepast, pas ook de sidebar hoogte aan (indien nodig)
5194											nxs_js_reenable_all_window_events();
5195										});
5196									}
5197
5198									nxs_js_reenable_all_window_events();
5199
5200									invokewhenavailable(insertresponse, renderresponse);
5201								}
5202							);
5203						}
5204						else if (response.result == "ALTFLOW")
5205						{
5206							if (response.altflowid == "rowtemplatenotallowed")
5207							{
5208								// inform used
5209								nxs_js_alert(response.msg);
5210							}
5211							else
5212							{
5213								nxs_js_popup_notifyservererror();
5214								nxs_js_log(response);
5215							}
5216						}
5217						else
5218						{
5219							nxs_js_popup_notifyservererror();
5220							nxs_js_log(response);
5221						}
5222					},
5223					error: function(response)
5224					{
5225						invokewhenfailed();
5226						nxs_js_popup_notifyservererror();
5227						nxs_js_log(response);
5228					}
5229				}
5230			);
5231		}
5232
5233		function nxs_js_addnewrow(postid, insertafterrowindex, element, invokewhenavailable, invokewhenfailed)
5234		{
5235			// invoke ajax call
5236			var ajaxurl = nxs_js_get_adminurladminajax();
5237			jQuery.ajax
5238			(
5239				{
5240					type: 'POST',
5241					data:
5242					{
5243						"action": "nxs_ajax_webmethods",
5244						"webmethod": "addnewrow",
5245						"postid": postid,
5246						"insertafterrowindex": insertafterrowindex
5247					},
5248					cache: false,
5249					dataType: 'JSON',
5250					url: ajaxurl,
5251					success: function(response)
5252					{
5253						nxs_js_log(response);
5254						if (response.result == "OK")
5255						{
5256							var containerElement = jQuery(".nxs-layout-editable.nxs-post-" + postid)[0];
5257							nxs_js_refreshallpagerows(postid, containerElement, invokewhenavailable);
5258						}
5259						else
5260						{
5261							invokewhenfailed();
5262							nxs_js_popup_notifyservererror();
5263							nxs_js_log(response);
5264						}
5265					},
5266					error: function(response)
5267					{
5268						invokewhenfailed();
5269						nxs_js_popup_notifyservererror();
5270						nxs_js_log(response);
5271					}
5272				}
5273			);
5274		}
5275
5276		function nxs_js_initplaceholderwithplaceholdertemplate(postid, placeholderid, placeholdertemplate)
5277		{
5278			var ajaxurl = nxs_js_get_adminurladminajax();
5279			jQuery.ajax
5280			(
5281				{
5282					type: 'POST',
5283					data:
5284					{
5285						"action": "nxs_ajax_webmethods",
5286						"webmethod": "initplaceholderdata",
5287						"clientpopupsessioncontext": nxs_js_getescaped_popupsession_context(),
5288						"placeholderid": placeholderid,
5289						"postid": postid,
5290						"containerpostid": nxs_js_getcontainerpostid(),
5291						"placeholdertemplate": placeholdertemplate,
5292						"clientqueryparameters": nxs_js_escaped_getqueryparametervalues()
5293					},
5294					dataType: 'JSON',
5295					url: ajaxurl,
5296					success: function(response)
5297					{
5298						nxs_js_log(response);
5299						if (response.result == "OK")
5300						{
5301							// TODO: make function for the following logic... its used multiple times...
5302							// update the DOM
5303							var rowindex = response.rowindex;
5304							var rowhtml = response.rowhtml;
5305							var pagecontainer = jQuery(".nxs-layout-editable.nxs-post-" + postid)[0];
5306							var pagerowscontainer = jQuery(pagecontainer).find(".nxs-postrows")[0];
5307							var element = jQuery(pagerowscontainer).children()[rowindex];
5308							jQuery(element).replaceWith(rowhtml);
5309
5310							// update the GUI step 1
5311							// invoke execute_after_clientrefresh_XYZ for each widget in the affected first row, if present
5312							var container = jQuery(pagerowscontainer).children()[rowindex];
5313							nxs_js_notify_widgets_after_ajaxrefresh(container);
5314							// update the GUI step 2
5315							nxs_js_reenable_all_window_events();
5316
5317							// growl!
5318							nxs_js_alert(response.growl);
5319						}
5320						else
5321						{
5322							nxs_js_popup_notifyservererror();
5323							nxs_js_log(response);
5324						}
5325					},
5326					error: function(response)
5327					{
5328						nxs_js_popup_notifyservererror();
5329						nxs_js_log(response);
5330					}
5331				}
5332			);
5333		}
5334
5335		function nxs_js_updatemenuitemlocation(postid, placeholderid, insertafterrowindex, depth)
5336		{
5337			// invoke ajax call
5338			var ajaxurl = nxs_js_get_adminurladminajax();
5339			jQuery.ajax
5340			(
5341				{
5342					type: 'POST',
5343					data:
5344					{
5345						"action": "nxs_ajax_webmethods",
5346						"webmethod": "updatemenuitemlocation",
5347						"postid": postid,
5348						"placeholderid": placeholderid,
5349						"insertafterrowindex": insertafterrowindex,
5350						"depth": depth
5351					},
5352					cache: false,
5353					dataType: 'JSON',
5354					url: ajaxurl,
5355					success: function(response)
5356					{
5357						nxs_js_log(response);
5358						if (response.result == "OK")
5359						{
5360							var containerElement = jQuery(".nxs-layout-editable.nxs-post-" + postid)[0];
5361							jQuery(containerElement).html(response.html);
5362							// reenable all events
5363							nxs_js_reenable_all_window_events();
5364							nxs_js_alert(nxs_js_gettrans('Refreshed'));
5365						}
5366						else
5367						{
5368							nxs_js_popup_notifyservererror();
5369							nxs_js_log(response);
5370						}
5371					},
5372					error: function(response)
5373					{
5374						nxs_js_popup_notifyservererror();
5375						nxs_js_log(response);
5376					}
5377				}
5378			);
5379		}
5380
5381		function nxs_js_swapplaceholders(sourcecontainerpostid, sourcepostid, sourceplaceholderid, destinationcontainerpostid, destinationpostid, destinationplaceholderid)
5382		{
5383			// GJ: 2012 mei 15; workaround / probleem drag drop dragdrop ui / crash / het zou het beste zijn voor het swappen als deze NIET async
5384			// zijn. Als we deze functie synced maken ontstaat er een exception bij het verwerken van het draggable object.
5385			// oorzaak: bij async=true, geldt: event drop -> event revert -> event stop -> verwerking van het resultaat van deze webservice
5386			// oorzaak: bij async=false, geldt: event drop -> verwerking van het resultaat van deze webservice -> event revert -> event stop -> crash
5387			// als blijkt dat we in de toekomst toch een async=false nodig hebben, zullen we de webservice aanroep (of in ieder geval
5388			// de verwerking van het resultaat hiervan) moeten verplaatsen _na_ het stop event...
5389
5390			// invoke ajax call
5391			var ajaxurl = nxs_js_get_adminurladminajax();
5392			jQuery.ajax
5393			(
5394				{
5395					async: true,
5396					type: 'POST',
5397					data:
5398					{
5399						"action": "nxs_ajax_webmethods",
5400						"webmethod": "swapplaceholders",
5401						"sourcecontainerpostid": sourcecontainerpostid,
5402						"sourcepostid": sourcepostid,
5403						"sourceplaceholderid": sourceplaceholderid,
5404						"destinationcontainerpostid": destinationcontainerpostid,
5405						"destinationpostid": destinationpostid,
5406						"destinationplaceholderid": destinationplaceholderid,
5407						"clientpopupsessioncontext": nxs_js_getescaped_popupsession_context(),
5408						"clientqueryparameters": nxs_js_escaped_getqueryparametervalues()
5409					},
5410					cache: false,
5411					dataType: 'JSON',
5412					url: ajaxurl,
5413					success: function(response)
5414					{
5415						nxs_js_log(response);
5416						if (response.result == "OK")
5417						{
5418							// haal de additionele response velden op
5419							var sourcerowindex = response.sourcerowindex;
5420							var sourcerowhtml = response.sourcerowhtml;
5421							var destinationrowindex = response.destinationrowindex;
5422							var destinationrowhtml = response.destinationrowhtml;
5423
5424							var sourcepagecontainer = jQuery(".nxs-layout-editable.nxs-post-" + sourcepostid)[0];
5425							var sourcepagerowscontainer = jQuery(sourcepagecontainer).find(".nxs-postrows")[0];
5426							var sourcecontainer = jQuery(sourcepagerowscontainer).children()[sourcerowindex];
5427
5428							// rerender first row
5429							var sourceElement = jQuery(sourcepagerowscontainer).children()[sourcerowindex];
5430							// before updating the dom, we first wipe any functions for notification ajax used by the "old" widgets
5431							nxs_js_clear_ajaxrefresh_notifications(sourceElement);
5432							jQuery(sourceElement).replaceWith(sourcerowhtml);
5433
5434							// invoke execute_after_clientrefresh_XYZ for each widget in the affected first row, if present
5435							nxs_js_notify_widgets_after_ajaxrefresh(sourcecontainer);
5436
5437							// if the swap is within the same row, updating the source row means we are finished,
5438							// else we also need to update the destination row
5439							var isswapwithinthesamerow = (sourcepostid == destinationpostid && sourcerowindex == destinationrowindex);
5440							if (!isswapwithinthesamerow)
5441							{
5442								var destinationpagecontainer = jQuery(".nxs-layout-editable.nxs-post-" + destinationpostid)[0];
5443								var destinationpagerowscontainer = jQuery(destinationpagecontainer).find(".nxs-postrows")[0];
5444								var destinationcontainer = jQuery(destinationpagerowscontainer).children()[destinationrowindex];
5445
5446								// rerender destination row
5447								var destinationElement = jQuery(destinationpagerowscontainer).children()[destinationrowindex];
5448								// before updating the dom, we first wipe any functions for notification ajax used by the "old" widgets
5449								nxs_js_clear_ajaxrefresh_notifications(destinationElement);
5450
5451								jQuery(destinationElement).replaceWith(destinationrowhtml);
5452
5453								// invoke execute_after_clientrefresh_XYZ for each widget in the affected first row, if present
5454								nxs_js_notify_widgets_after_ajaxrefresh(destinationcontainer);
5455							}
5456							else
5457							{
5458								// nxs_js_log('only redrawing one row');
5459							 	// if item was drag and dropped within the same row, re-rendering it won't make sense
5460							}
5461
5462							// re-enable window events and sizes
5463							nxs_js_reenable_all_window_events();
5464						}
5465						else if (response.result == "ALTFLOW")
5466						{
5467							if (response.altflowid == "widgetnotallowed")
5468							{
5469								// inform used
5470								nxs_js_alert(response.msg);
5471							}
5472							else
5473							{
5474								nxs_js_popup_notifyservererror();
5475								nxs_js_log(response);
5476							}
5477						}
5478						else
5479						{
5480							nxs_js_popup_notifyservererror();
5481							nxs_js_log(response);
5482						}
5483					},
5484					error: function(response)
5485					{
5486						nxs_js_popup_notifyservererror();
5487						nxs_js_log(response);
5488					}
5489				}
5490			);
5491		}
5492
5493		function nxs_js_addnewarticle(titel, slug, pagetype)
5494		{
5495			nxs_js_addnewarticle_v2(titel, slug, pagetype, "");
5496		}
5497
5498		function nxs_js_addnewarticle_v2(titel, slug, pagetype, pagesubtype)
5499		{
5500			// invoke ajax call
5501			var ajaxurl = nxs_js_get_adminurladminajax();
5502			jQuery.ajax
5503			(
5504				{
5505					type: 'POST',
5506					data:
5507					{
5508						"action": "nxs_ajax_webmethods",
5509						"webmethod": "addnewarticle",
5510						"titel": titel,
5511						"slug": slug,
5512						"nxsposttype": pagetype,
5513						"nxssubposttype": pagesubtype
5514					},
5515					cache: false,
5516					dataType: 'JSON',
5517					url: ajaxurl,
5518					success: function(response)
5519					{
5520						nxs_js_log(response);
5521						if (response.result == "OK")
5522						{
5523							// haal de additionele response velden op
5524							var postid = response.postid;
5525							var url = response.url;
5526
5527							window.location = url;
5528						}
5529						else
5530						{
5531							nxs_js_popup_notifyservererror();
5532							nxs_js_log(response);
5533						}
5534					},
5535					error: function(response)
5536					{
5537						nxs_js_popup_notifyservererror();
5538						nxs_js_log(response);
5539					}
5540				}
5541			);
5542		}
5543
5544		function nxs_js_addnewarticlewithpostwizard(titel, slug, pagetype, postwizard, invokewhenavailable)
5545		{
5546			// invoke ajax call
5547			var ajaxurl = nxs_js_get_adminurladminajax();
5548			jQuery.ajax
5549			(
5550				{
5551					type: 'POST',
5552					data:
5553					{
5554						"action": "nxs_ajax_webmethods",
5555						"webmethod": "addnewarticle",
5556						"titel": titel,
5557						"slug": slug,
5558						"nxsposttype": pagetype,
5559						"postwizard": postwizard
5560					},
5561					cache: false,
5562					dataType: 'JSON',
5563					url: ajaxurl,
5564					success: function(response)
5565					{
5566						nxs_js_log(response);
5567						if (response.result == "OK")
5568						{
5569							invokewhenavailable(response);
5570						}
5571						else
5572						{
5573							nxs_js_popup_notifyservererror();
5574							nxs_js_log(response);
5575						}
5576					},
5577					error: function(response)
5578					{
5579						nxs_js_popup_notifyservererror();
5580						nxs_js_log(response);
5581					}
5582				}
5583			);
5584		}
5585
5586		function nxs_js_addnewarticlewithpostwizardwithargs(titel, slug, pagetype, poststatus, postwizard, args, invokewhenavailable, invokewhenfailed)
5587		{
5588			// invoke ajax call
5589			var ajaxurl = nxs_js_get_adminurladminajax();
5590			jQuery.ajax
5591			(
5592				{
5593					type: 'POST',
5594					data:
5595					{
5596						"action": "nxs_ajax_webmethods",
5597						"webmethod": "addnewarticle",
5598						"titel": titel,
5599						"slug": slug,
5600						"poststatus": poststatus,
5601						"nxsposttype": pagetype,
5602						"postwizard": postwizard,
5603						"args": args
5604					},
5605					cache: false,
5606					dataType: 'JSON',
5607					url: ajaxurl,
5608					success: function(response)
5609					{
5610						nxs_js_log(response);
5611						if (response.result == "OK")
5612						{
5613							invokewhenavailable(response);
5614						}
5615						else
5616						{
5617							nxs_js_popup_notifyservererror();
5618							nxs_js_log(response);
5619							invokewhenfailed();
5620						}
5621					},
5622					error: function(response)
5623					{
5624						invokewhenfailed();
5625						nxs_js_popup_notifyservererror();
5626						nxs_js_log(response);
5627					}
5628				}
5629			);
5630		}
5631
5632		function nxs_js_addcategory(name, invokewhenavailable)
5633		{
5634			// invoke ajax call
5635			var ajaxurl = nxs_js_get_adminurladminajax();
5636			jQuery.ajax
5637			(
5638				{
5639					type: 'POST',
5640					data:
5641					{
5642						"action": "nxs_ajax_webmethods",
5643						"webmethod": "addcategory",
5644						"name": name
5645					},
5646					cache: false,
5647					dataType: 'JSON',
5648					url: ajaxurl,
5649					success: function(response)
5650					{
5651						nxs_js_log(response);
5652						if (response.result == "OK")
5653						{
5654							var catid = response.catid;
5655							invokewhenavailable(name, catid);
5656						}
5657						else
5658						{
5659							nxs_js_popup_notifyservererror();
5660							nxs_js_log(response);
5661						}
5662					},
5663					error: function(response)
5664					{
5665						nxs_js_popup_notifyservererror();
5666						nxs_js_log(response);
5667					}
5668				}
5669			);
5670		}
5671
5672		function nxs_js_removecategory(catid, invokewhenavailable)
5673		{
5674			// invoke ajax call
5675			var ajaxurl = nxs_js_get_adminurladminajax();
5676			jQuery.ajax
5677			(
5678				{
5679					type: 'POST',
5680					data:
5681					{
5682						"action": "nxs_ajax_webmethods",
5683						"webmethod": "removecategory",
5684						"catid": catid
5685					},
5686					cache: false,
5687					dataType: 'JSON',
5688					url: ajaxurl,
5689					success: function(response)
5690					{
5691						nxs_js_log(response);
5692						if (response.result == "OK")
5693						{
5694							invokewhenavailable();
5695						}
5696						else
5697						{
5698							nxs_js_popup_notifyservererror();
5699							nxs_js_log(response);
5700						}
5701					},
5702					error: function(response)
5703					{
5704						nxs_js_popup_notifyservererror();
5705						nxs_js_log(response);
5706					}
5707				}
5708			);
5709		}
5710
5711		function nxs_js_getgrowlscripturl()
5712		{
5713			return nxs_js_getframeworkurl() + '/js/growl/jquery.jgrowl.x.js';
5714		}
5715
5716		function nxs_js_htmldialogmessageok(title, html)
5717		{
5718			nxs_js_htmldialogmessageok_v2(title, html, "basic");
5719		}
5720
5721		// custompopup custom popup htmlpopup html popup popup custom
5722		function nxs_js_htmldialogmessageok_v2(title, html, scaffoldingtype)
5723		{
5724			// show a popup
5725			nxs_js_popupsession_startnewcontext();
5726			nxs_js_popup_setsessioncontext("contextprocessor", "site");
5727			nxs_js_popup_setsessiondata("nxs_customhtml_scaffoldingtype", scaffoldingtype);
5728			nxs_js_popup_setsessiondata("nxs_customhtml_popupheadertitle", title);
5729			nxs_js_popup_setsessiondata("minwidth", "368");
5730			nxs_js_popup_setsessiondata("nxs_customhtml_customhtmlcanvascontent", html);
5731			nxs_js_popup_navigateto("customhtml");
5732		}
5733
5734		function nxs_js_alert_sticky(text)
5735		{
5736			jQuery.jGrowl(text, { sticky: true });
5737		}
5738
5739		//
5740		//
5741		//
5742
5743		function nxs_js_alert(text)
5744		{
5745			nxs_js_log("alerting:" + text);
5746			jQuery.jGrowl(text, { sticky: false, life: 3000 });
5747		}
5748
5749		//
5750		//
5751		//
5752
5753		function nxs_js_alert_veryshort(text)
5754		{
5755			nxs_js_log("alerting very short:" + text);
5756			jQuery.jGrowl(text, { sticky: false, life: 1000 });
5757		}
5758
5759		//
5760		//
5761		//
5762
5763
5764		function nxs_js_alert_wait_start(message)
5765		{
5766			//nxs_js_log("nxs_js_getframeworkurl():" + nxs_js_get_frameworkurl());
5767			//nxs_js_log("alerting wait start:" + message);
5768			var stacktrace = nxs_js_getqueryparametervalue("stacktrace");
5769			if (nxs_js_isctrlkeydown || stacktrace != "")
5770			{
5771				// practical debug tool; if ctrl is pressed, output the stacktrac
5772				try { throw new Error("Stracktrace"); } catch (e) { console.log(e.stack); }
5773			}
5774
5775
5776			nxs_js_alert_identifier++;
5777			var token = "group-wait-" + nxs_js_alert_identifier;
5778			var text = "";
5779			text += "<div id='nxs-growl-" + token + "'>";
5780			text += "<span class='nxs-icon-clock' style='padding-right: 10px;'></span>";
5781			//text += "<img src='" + nxs_js_getframeworkurl() + "/images/icon-wait.png' style='padding-right: 10px;' />";
5782			if (message != null)
5783			{
5784				text = "<span style='padding-left: 10px;'>" + text + message + "</span>";
5785			}
5786			text += "</div>";
5787			jQuery.jGrowl(text, { sticky: false, life: 3000, group: token });
5788
5789			//nxs_js_log("created:" + token);
5790
5791			return token;
5792		}
5793
5794		//
5795		//
5796		//
5797
5798		function nxs_js_alert_wait_finish(token)
5799		{
5800			if (token == -1)
5801			{
5802				return;
5803			}
5804
5805			// if the finish is invoked soon after it was
5806			// started, the growl hasn't yet initialized
5807			// the growl popup. In that case the closing of the
5808			// growl does nothing, and the popup stays on the screen
5809			// too long. This is fixed by invoking the following function
5810			var retries = 10;
5811			nxs_js_alert_wait_finish_internal(token, retries);
5812		}
5813
5814		function nxs_js_alert_wait_finish_internal(token, retriesleft)
5815		{
5816			if (jQuery("#nxs-growl-" + token).length > 0)
5817			{
5818				// if dom element exists, invoke immediately
5819				nxs_js_alert_wait_finish_internal_actual(token);
5820			}
5821			else
5822			{
5823				//nxs_js_log('detected DOM doesnt (yet) have growl to close');
5824				if (retriesleft > 0)
5825				{
5826					// delayed invoked, but preventing endless loops...
5827
5828					setTimeout
5829					(
5830						function()
5831						{
5832							//nxs_js_log("postponing close growl...");
5833							//nxs_js_log(token);
5834							retriesleft = retriesleft - 1;
5835							//nxs_js_log(retriesleft);
5836							nxs_js_alert_wait_finish_internal(token, retriesleft);
5837						}
5838						,
5839						200);
5840				}
5841				else
5842				{
5843					//nxs_js_log('no more retries left...');
5844				}
5845			}
5846		}
5847
5848		function nxs_js_alert_wait_finish_internal_actual(token)
5849		{
5850			//nxs_js_log("alerting wait finished:" + token);
5851			//nxs_js_log("closing token:" + token);
5852
5853			jQuery("div.jGrowl-notification." + token).trigger("jGrowl.close");
5854		}
5855
5856		function nxs_js_logout()
5857		{
5858			var ajaxurl = nxs_js_get_adminurladminajax();
5859			jQuery.ajax
5860			(
5861				{
5862					type: 'POST',
5863					data:
5864					{
5865						"action": "nxs_ajax_webmethods",
5866						"webmethod": "logout"
5867					},
5868					dataType: 'JSON',
5869					url: ajaxurl,
5870					success: function(response)
5871					{
5872						nxs_js_log(response);
5873						if (response.result == "OK")
5874						{
5875							if (response.previousstate == "notauthenticated")
5876							{
5877								// either the user's session was timed out
5878								// or the webserver was reset if we reach this point
5879								nxs_js_log('note; user was not logged on');
5880							}
5881
5882							// close the pop up
5883							nxs_js_closepopup_unconditionally();
5884							nxs_js_refreshcurrentpage();
5885						}
5886						else
5887						{
5888							nxs_js_popup_notifyservererror();
5889							nxs_js_log(response);
5890						}
5891					},
5892					error: function(response)
5893					{
5894						nxs_js_popup_notifyservererror();
5895						nxs_js_log(response);
5896					}
5897				}
5898			);
5899		}
5900
5901		function nxs_js_help(helpid)
5902		{
5903			nxs_js_opensupportoptions();
5904		}
5905
5906		function nxs_js_copytoclipboard(text)
5907		{
5908		  window.prompt("Copy to clipboard: Ctrl+C, Enter", text);
5909		}
5910
5911		function nxs_js_popup_storestatecontroldata_checkbox(elementid, sessiondatakey)
5912		{
5913			if (jQuery('#' + elementid).length > 0)
5914			{
5915				if (jQuery('#' + elementid).is(':checked'))
5916				{
5917					nxs_js_popup_setsessiondata(sessiondatakey, 'checked=true');
5918				}
5919				else
5920				{
5921					nxs_js_popup_setsessiondata(sessiondatakey, '');
5922				}
5923			}
5924		}
5925
5926		function nxs_js_popup_storestatecontroldata_checkbox_inverse(elementid, sessiondatakey)
5927		{
5928			if (jQuery('#' + elementid).length > 0)
5929			{
5930				if (jQuery('#' + elementid).is(':checked'))
5931				{
5932					nxs_js_popup_setsessiondata(sessiondatakey, '');
5933				}
5934				else
5935				{
5936					nxs_js_popup_setsessiondata(sessiondatakey, 'checked=true');
5937				}
5938			}
5939		}
5940
5941		function nxs_js_popup_storestatecontroldata_listofcheckbox(ulcontainerelementid, checkboxitemsclassname, sessiondatakey)
5942		{
5943			if (jQuery('#' + ulcontainerelementid).length > 0)
5944			{
5945				var derivedselectedids = '';
5946				jQuery('#' + ulcontainerelementid + " ." + checkboxitemsclassname).each(function(index)
5947				{
5948					if (jQuery(this).attr('checked'))
5949					{
5950						var currentcheckboxelementid = jQuery(this).attr('id');
5951						derivedselectedids = derivedselectedids + "[" + currentcheckboxelementid.split("_")[1] + "]";
5952					}
5953				});
5954				nxs_js_popup_setsessiondata(sessiondatakey, derivedselectedids);
5955			}
5956			else
5957			{
5958				nxs_js_log('element not found');
5959			}
5960		}
5961
5962		function nxs_js_popup_storestatecontroldata_textbox(elementid, sessiondatakey)
5963		{
5964			if (jQuery('#' + elementid).length > 0)
5965			{
5966				nxs_js_popup_setsessiondata(sessiondatakey, jQuery('#' + elementid).val());
5967			}
5968		}
5969
5970		// kudos to http://stackoverflow.com/questions/18082/validate-numbers-in-javascript-isnumeric
5971		function isNumber(n)
5972		{
5973  		return !isNaN(parseFloat(n)) && isFinite(n);
5974		}
5975
5976		function nxs_js_popup_storestatecontroldata_hiddenfield(elementid, sessiondatakey)
5977		{
5978			if (jQuery('#' + elementid).length > 0)
5979			{
5980				nxs_js_popup_setsessiondata(sessiondatakey, jQuery('#' + elementid).val());
5981			}
5982		}
5983
5984		function nxs_js_popup_storestatecontroldata_dropdown(elementid, sessiondatakey)
5985		{
5986			if (jQuery('#' + elementid).length > 0)
5987			{
5988				nxs_js_popup_setsessiondata(sessiondatakey, jQuery('#' + elementid).val());
5989			}
5990		}
5991
5992		function nxs_js_postcomment(postid, containerpostid, placeholderid, parentcommentid, name, email, website, comment, invokewhenready, invokewhenfailed)
5993		{
5994			// invoke ajax call
5995			var ajaxurl = nxs_js_get_adminurladminajax();
5996			jQuery.ajax
5997			(
5998				{
5999					type: 'POST',
6000					data:
6001					{
6002						"action": "nxs_ajax_webmethods",
6003						"webmethod": "addcomment",
6004						"postid": postid,
6005						"name": name,
6006						"email": email,
6007						"website": website,
6008						"comment": comment,
6009						"parentcommentid": parentcommentid,
6010						"containerpostid": containerpostid,
6011						"placeholderid": placeholderid
6012					},
6013					async: false,
6014					cache: false,
6015					dataType: 'JSON',
6016					url: ajaxurl,
6017					success: function(response)
6018					{
6019						nxs_js_log(response);
6020						if (response.result == "OK")
6021						{
6022							// ok
6023							invokewhenready(response);
6024						}
6025						else
6026						{
6027							invokewhenfailed();
6028							nxs_js_popup_notifyservererror();
6029							nxs_js_log(response);
6030						}
6031					},
6032					error: function(response)
6033					{
6034						nxs_js_popup_notifyservererror();
6035						nxs_js_log(response);
6036					}
6037				}
6038			);
6039		}
6040
6041		function nxs_js_removecomment(postid, commentid, invokewhenready, invokewhenfailed)
6042		{
6043			// invoke ajax call
6044			var ajaxurl = nxs_js_get_adminurladminajax();
6045			jQuery.ajax
6046			(
6047				{
6048					type: 'POST',
6049					data:
6050					{
6051						"action": "nxs_ajax_webmethods",
6052						"webmethod": "removecomment",
6053						"postid": postid,
6054						"commentid": commentid
6055					},
6056					async: false,
6057					cache: false,
6058					dataType: 'JSON',
6059					url: ajaxurl,
6060					success: function(response)
6061					{
6062						nxs_js_log(response);
6063						if (response.result == "OK")
6064						{
6065							// ok
6066							invokewhenready();
6067						}
6068						else
6069						{
6070							invokewhenfailed();
6071							nxs_js_popup_notifyservererror();
6072							nxs_js_log(response);
6073						}
6074					},
6075					error: function(response)
6076					{
6077						nxs_js_popup_notifyservererror();
6078						nxs_js_log(response);
6079					}
6080				}
6081			);
6082		}
6083
6084		function nxs_js_getrandom(max)
6085		{
6086			return Math.floor(Math.random()*max);
6087		}
6088
6089		function nxs_js_approvecomment(postid, commentid, invokewhenready, invokewhenfailed)
6090		{
6091			// invoke ajax call
6092			var ajaxurl = nxs_js_get_adminurladminajax();
6093			jQuery.ajax
6094			(
6095				{
6096					type: 'POST',
6097					data:
6098					{
6099						"action": "nxs_ajax_webmethods",
6100						"webmethod": "approvecomment",
6101						"postid": postid,
6102						"commentid": commentid
6103					},
6104					async: false,
6105					cache: false,
6106					dataType: 'JSON',
6107					url: ajaxurl,
6108					success: function(response)
6109					{
6110						nxs_js_log(response);
6111						if (response.result == "OK")
6112						{
6113							// ok
6114							invokewhenready();
6115						}
6116						else
6117						{
6118							invokewhenfailed();
6119							nxs_js_popup_notifyservererror();
6120							nxs_js_log(response);
6121						}
6122					},
6123					error: function(response)
6124					{
6125						nxs_js_popup_notifyservererror();
6126						nxs_js_log(response);
6127					}
6128				}
6129			);
6130		}
6131
6132		function nxs_js_geturl(destination, postid, nxsrefurlspecial, invokewhenready, invokewhenfailed)
6133		{
6134			// invoke ajax call
6135			var ajaxurl = nxs_js_get_adminurladminajax();
6136			jQuery.ajax
6137			(
6138				{
6139					type: 'POST',
6140					data:
6141					{
6142						"action": "nxs_ajax_webmethods",
6143						"webmethod": "geturl",
6144						"destination": destination,
6145						"containerpostid": nxs_js_getcontainerpostid(),
6146						"postid": postid,
6147						"nxsrefurlspecial": nxsrefurlspecial
6148					},
6149					async: false,
6150					cache: false,
6151					dataType: 'JSON',
6152					url: ajaxurl,
6153					success: function(response)
6154					{
6155						nxs_js_log(response);
6156						if (response.result == "OK")
6157						{
6158							// ok
6159							invokewhenready(response);
6160						}
6161						else
6162						{
6163							invokewhenfailed();
6164							nxs_js_popup_notifyservererror();
6165							nxs_js_log(response);
6166						}
6167					},
6168					error: function(response)
6169					{
6170						invokewhenfailed();
6171						nxs_js_popup_notifyservererror();
6172						nxs_js_log(response);
6173					}
6174				}
6175			);
6176		}
6177
6178		function nxs_js_clear_ajaxrefresh_notifications(container)
6179		{
6180			//nxs_js_log('invoking nxs_js_clear_ajaxrefresh_notifications');
6181
6182			// container verwijst naar de regel waarvoor we de client refresh moeten
6183			// aanroepen (indien noodzakelijk / beschikbaar)
6184			jQuery(container).find(".nxs-widget").each
6185  		(
6186  			function(idx2, elm2)
6187  			{
6188  				var idwithfluff = elm2.id;
6189  				var id = idwithfluff.split("-")[2];
6190  				var functionname = "nxs_js_execute_after_ajaxrefresh_widget_" + id;
6191					var script = "<script>function " + functionname + "() { }</script>";
6192					// inject script in dom
6193					jQuery(container).append(script);
6194					//nxs_js_log('injected:' + script);
6195				}
6196			);
6197		}
6198
6199		// convenience function to get
6200		// <div class="nxs-tag nxs-tag-foobar123"><domelement> will return "foobar123"
6201		// if invoked like nxs_js_findclassidentificationwithprefix_closest(domelement, ".nxs-tag", "nxs-tag-")
6202		function nxs_js_findclassidentificationwithprefix_closest(domelement, closestselector, prefix)
6203		{
6204			var closestElement = jQuery(domelement).closest(closestselector);
6205			return nxs_js_findclassidentificationwithprefix(closestElement, prefix);
6206		}
6207
6208		function nxs_js_finddistinctclassidentifications(domelement, prefixtype)
6209		{
6210			var result = [];
6211
6212			var prefixselector = "." + prefixtype;	// for example ".nxs-heightiq"
6213			var prefix = prefixtype + "-";	// for example "nxs-heightiq-"
6214
6215			var elements = jQuery(domelement).find(prefixselector).each
6216  		(
6217  			function(i,currentelement)
6218  			{
6219  				var identification = nxs_js_findclassidentificationwithprefix(currentelement, prefix);
6220					if (jQuery.inArray(identification, result) == -1)
6221					{
6222						result.push(identification);
6223					}
6224				}
6225			);
6226
6227			return result;
6228		}
6229
6230		// function to return a specific id after a certain prefix in the class attribute,
6231		// specified on the domelement. for example if the dom element looks like <div class="nxs-post-123">,
6232		// the function will return 123 if the prefix "nxs-post-" is specified. The function can also
6233		// be used to return alfa characters, or a combination. <div class="nxs-object-foobar123"> will
6234		// return "foobar123"
6235		// tags: identifier, id, identification, find, get, retrieve, subset, prefix, classname, getclass, derive
6236		function nxs_js_findclassidentificationwithprefix(domelement, prefix)
6237		{
6238		 	var classname = jQuery(domelement).attr("class");
6239			var pattern = prefix + "([^\\s]*)";	// any set of chars till the moment a whitespace is found
6240			var modifiers = "";
6241		 	var regularexpression=new RegExp(pattern,modifiers);
6242
6243		 	var result = null;
6244			var regexpresult = regularexpression.exec(classname);
6245			if (regexpresult != null)
6246			{
6247				result = regexpresult[1];
6248			}
6249			else
6250			{
6251				// not found
6252				nxs_js_log('warning; identification not found;');
6253				nxs_js_log('domelement:');
6254				nxs_js_log(domelement);
6255				nxs_js_log('prefix:');
6256				nxs_js_log(prefix);
6257			}
6258
6259		 	return result;
6260		}
6261
6262		// gets the postid that this domelement belongs to
6263		// by traversing up in the dom, and finding the closest "nxs-elements-container" element
6264		// and returning the XYZ value of its "nxs-post-XYZ" class attribute.
6265		function nxs_js_findclosestpostid_for_dom(domelement)
6266		{
6267			var result;
6268			var elementscontainer = jQuery(domelement).closest(".nxs-elements-container");
6269			if (elementscontainer.length == 0)
6270			{
6271				//nxs_js_log('not found?!');
6272				result = null;
6273			}
6274			else
6275			{
6276				result = nxs_js_findclassidentificationwithprefix(elementscontainer, "nxs-post-");
6277			}
6278			return result;
6279		}
6280
6281		function nxs_js_edit_widget(domelementinwidget)
6282		{
6283			nxs_js_edit_widget_v2(domelementinwidget, "home");
6284		}
6285
6286		function nxs_js_edit_widget_v2(domelementinwidget, sheet)
6287		{
6288			// opens the popup window for this widget, defaults to the "home" sheet if not specified
6289
6290			var postid = nxs_js_findclosestpostid_for_dom(domelementinwidget);
6291			var widget = jQuery(domelementinwidget).closest(".nxs-placeholder").first();
6292			var placeholderid = nxs_js_getfirstplaceholderid_in_dom(widget);
6293			var rowindex = nxs_js_getrowindex(widget);
6294			//
6295			nxs_js_popup_placeholder_neweditsession(postid, placeholderid, rowindex, sheet);
6296		}
6297
6298		function nxs_js_edit_row(domelementinwidget)
6299		{
6300			nxs_js_edit_row_v2(domelementinwidget, "home");
6301		}
6302
6303		function nxs_js_edit_row_v2(domelementinwidget, sheet)
6304		{
6305			// opens the default "home" popup window for this row
6306			var postid = nxs_js_findclosestpostid_for_dom(domelementinwidget);
6307			//nxs_js_log(domelementinwidget);
6308			var row = jQuery(domelementinwidget).closest(".nxs-row").first();
6309			var pagerowid = jQuery(row).attr('id').split("-")[2];
6310
6311			nxs_js_popup_row_neweditsession(postid, pagerowid, sheet);
6312		}
6313
6314		function nxs_js_notify_widgets_after_ajaxrefresh(container)
6315		{
6316			// stage 1
6317
6318			// container verwijst naar de regel waarvoor we de client refresh moeten
6319			// aanroepen (indien noodzakelijk / beschikbaar)
6320			jQuery(container).find(".nxs-widget").each
6321  		(
6322  			function(idx2, elm2)
6323  			{
6324  				var idwithfluff = elm2.id;
6325  				var id = idwithfluff.split("-")[2];
6326  				var functionname = "nxs_js_execute_after_ajaxrefresh_widget_" + id;
6327
6328  				var fn = window[functionname];
6329  				if (typeof(fn) == 'function')
6330  				{
6331  					//nxs_js_log("invoking function " + functionname);
6332  					// invoke!
6333  					fn();
6334  				}
6335  				else
6336  				{
6337  					//nxs_js_log("ignoring (not found) function " + functionname);
6338  				}
6339				}
6340			);
6341
6342			// stage 2; if SEO tab is active, (enqueue) the SEO refresh
6343			nxs_js_refresh_seoanalysis();
6344		}
6345
6346		function nxs_js_saveplaceholdertoclipboard(postid, placeholderid)
6347		{
6348			nxs_js_log("about to copy widget data to memory :)");
6349			nxs_js_log("placeholderid: " + placeholderid);
6350
6351			// invoke ajax call
6352			var ajaxurl = nxs_js_get_adminurladminajax();
6353			jQuery.ajax
6354			(
6355				{
6356					type: 'POST',
6357					data:
6358					{
6359						"action": "nxs_ajax_webmethods",
6360						"webmethod": nxs_js_getclipboardhandler() + "copy",
6361						"clipboardcontext" : "widget",
6362						"postid": postid,
6363						"placeholderid": placeholderid
6364					},
6365					cache: false,
6366					dataType: 'JSON',
6367					url: ajaxurl,
6368					success: function(response)
6369					{
6370						nxs_js_log(response);
6371						if (response.result == "OK")
6372						{
6373							nxs_js_alert(response.growl);
6374						}
6375						else
6376						{
6377							nxs_js_alert(nxs_js_gettrans('Clipboard failed'));
6378						}
6379					},
6380					error: function(response)
6381					{
6382						nxs_js_popup_notifyservererror();
6383						nxs_js_log(response);
6384						nxs_js_alert(nxs_js_gettrans('Clipboard failed'));
6385					}
6386				}
6387			);
6388		}
6389
6390		function nxs_copytoserverclipboard(clipboardscope)
6391		{
6392			if (nxs_js_popupshows)
6393			{
6394				return;
6395			}
6396
6397			// currently we only support copy pasting of individual widgets (no rows yet...)
6398			var selectedhovermenus = jQuery(".nxs-widget-hover-menu.nxs-hovering.inside-right-top");
6399			if (jQuery(selectedhovermenus).length == 1)
6400			{
6401				var postid = nxs_js_findclosestpostid_for_dom(selectedhovermenus[0]);
6402				var selectedwidget = jQuery(selectedhovermenus).closest(".nxs-placeholder").find(".nxs-widget");
6403				var placeholderid = jQuery(selectedwidget).attr("id").split("-")[2];
6404
6405				if (clipboardscope == "all")
6406				{
6407					nxs_js_saveplaceholdertoclipboard(postid, placeholderid);
6408				}
6409				else
6410				{
6411					nxs_js_log('unsupported clipboardscope; ' + clipboardscope);
6412				}
6413			}
6414			else
6415			{
6416				// show popup for copying info
6417				if (jQuery("body").hasClass("single") || jQuery("body").hasClass("post") || jQuery("body").hasClass("page"))
6418				{
6419					nxs_js_popup_site_neweditsession('clipboardcopyselector');
6420				}
6421				else
6422				{
6423					nxs_js_alert("Ctrl-c is not supported for this context");
6424				}
6425			}
6426		}
6427
6428		function nxs_pastefromserverclipboard(scope)
6429		{
6430			if (nxs_js_popupshows)
6431			{
6432				return;
6433			}
6434
6435			var selectedhovermenus = jQuery(".nxs-widget-hover-menu.nxs-hovering.inside-right-top");
6436			if (jQuery(selectedhovermenus).length == 1)
6437			{
6438				var postid = nxs_js_findclosestpostid_for_dom(selectedhovermenus[0]);
6439				var selectedwidget = jQuery(selectedhovermenus).closest(".nxs-placeholder").find(".nxs-widget");
6440				var placeholderid = jQuery(selectedwidget).attr("id").split("-")[2];
6441
6442				// invoke ajax call
6443				var ajaxurl = nxs_js_get_adminurladminajax();
6444				jQuery.ajax
6445				(
6446					{
6447						type: 'POST',
6448						data:
6449						{
6450							"action": "nxs_ajax_webmethods",
6451							"webmethod": nxs_js_getclipboardhandler() + "paste",
6452							"clipboardcontext" : "widget",
6453							"containerpostid": nxs_js_getcontainerpostid(),
6454							"postid": postid,
6455							"placeholderid": placeholderid,
6456							"clientpopupsessioncontext": nxs_js_getescaped_popupsession_context(),
6457							"clientqueryparameters": nxs_js_escaped_getqueryparametervalues()
6458						},
6459						cache: false,
6460						dataType: 'JSON',
6461						url: ajaxurl,
6462						success: function(response)
6463						{
6464							nxs_js_log(response);
6465							if (response.result == "OK")
6466							{
6467								if (response.refresh == "row")
6468								{
6469									// update the DOM
6470									var rowindex = response.rowindex;
6471									var rowhtml = response.rowhtml;
6472									var pagecontainer = jQuery(".nxs-layout-editable.nxs-post-" + postid)[0];
6473									var pagerowscontainer = jQuery(pagecontainer).find(".nxs-postrows")[0];
6474									var element = jQuery(pagerowscontainer).children()[rowindex];
6475									jQuery(element).replaceWith(rowhtml);
6476
6477									// update the GUI step 1
6478									// invoke execute_after_clientrefresh_XYZ for each widget in the affected first row, if present
6479									var container = jQuery(pagerowscontainer).children()[rowindex];
6480									nxs_js_notify_widgets_after_ajaxrefresh(container);
6481									// update the GUI step 2
6482									nxs_js_reenable_all_window_events();
6483
6484									// growl!
6485									nxs_js_alert(response.growl);
6486								}
6487								else
6488								{
6489									// assumed to have to refresh entire page
6490
6491									nxs_js_refreshcurrentpage();
6492								}
6493							}
6494							else if (response.result == "ALTFLOW")
6495							{
6496								if (response.altflowid == "widgetnotallowed")
6497								{
6498									// inform used
6499									nxs_js_alert(response.msg);
6500								}
6501								else
6502								{
6503									nxs_js_popup_notifyservererror();
6504									nxs_js_log(response);
6505								}
6506							}
6507							else
6508							{
6509								nxs_js_alert(nxs_js_gettrans('Clipboard failed'));
6510							}
6511						},
6512						error: function(response)
6513						{
6514							nxs_js_popup_notifyservererror();
6515							nxs_js_log(response);
6516							nxs_js_alert(nxs_js_gettrans('Clipboard failed'));
6517						}
6518					}
6519				);
6520			}
6521			else
6522			{
6523				// Pasten of elements other than a widget will be handled using a popup
6524				if (jQuery("body").hasClass("single") || jQuery("body").hasClass("post") || jQuery("body").hasClass("page"))
6525				{
6526					nxs_js_popup_site_neweditsession('clipboardpasteselector');
6527				}
6528				else
6529				{
6530					nxs_js_alert("Ctrl-C is not supported for this context");
6531				}
6532
6533			}
6534		}
6535
6536		function nxs_js_getwidgetdom_overwhichwehover()
6537		{
6538			var result = null;
6539
6540			var selectedhovermenus = jQuery(".nxs-widget-hover-menu.nxs-hovering.inside-right-top");
6541			if (jQuery(selectedhovermenus).length == 1)
6542			{
6543				result = jQuery(selectedhovermenus).closest(".nxs-placeholder").find(".nxs-widget")[0];
6544			}
6545			else
6546			{
6547				// not found
6548			}
6549
6550			return result;
6551		}
6552
6553		function nxs_js_getplaceholderidofwidgetdom(widget)
6554		{
6555			var result = jQuery(widget).attr("id").split("-")[2];
6556			return result;
6557		}
6558
6559		//
6560		// this isn't yet correctly implement for IE, see http://stackoverflow.com/questions/69430/is-there-a-way-to-make-text-unselectable-on-an-html-page
6561		// disable selecting with mouse
6562		(
6563			function($)
6564			{
6565				jQuery.fn.disableSelection = function()
6566				{
6567				  return this.each
6568				  (
6569					  function()
6570					  {
6571			        jQuery(this).addClass('nxs-unselectable');
6572					  }
6573				  );
6574				};
6575			}
6576		)
6577		(
6578			jQuery
6579		);
6580
6581		//
6582		// this isn't yet correctly implement for IE, see http://stackoverflow.com/questions/69430/is-there-a-way-to-make-text-unselectable-on-an-html-page
6583		// enable selecting with mouse
6584		(
6585			function($)
6586			{
6587				jQuery.fn.enableSelection = function()
6588				{
6589				  return this.each
6590				  (
6591					  function()
6592					  {
6593			        jQuery(this).removeClass('nxs-unselectable');
6594					  }
6595				  );
6596				};
6597			}
6598		)
6599		(
6600			jQuery
6601		);
6602
6603		var nxs_js_facebookinjected = false;
6604
6605		function nxs_js_inject_facebook()
6606		{
6607			if (nxs_js_facebookinjected)
6608			{
6609				//
6610				nxs_js_fb_postprocessor();
6611				return;
6612			}
6613			nxs_js_facebookinjected = true;
6614
6615			// kudos to http://cyrilmazur.com/2011/08/deferred-lazy-loading-facebook-widgets.html
6616
6617			jQuery('body').append('<div id="fb-root" style="display: none;"></div>');
6618
6619			var locale = nxs_js_getlocale();
6620			if (locale == 'nl_NL')
6621			{
6622				// ok
6623			}
6624			else
6625			{
6626				locale = 'en_US';
6627			}
6628			var scripturl = 'https://connect.facebook.net/' + locale + '/all.js#xfbml=1';
6629
6630			jQuery.getScript
6631			(
6632				scripturl,
6633				function()
6634				{
6635			    FB.init({status: true, cookie: true, xfbml: true});
6636			    // activate DOM
6637			    nxs_js_fb_postprocessor();
6638				}
6639			);
6640		}
6641
6642		function nxs_js_fb_postprocessor()
6643		{
6644			if (typeof(FB) != 'undefined' && FB != null )
6645			{
6646				FB.XFBML.parse();
6647			}
6648		}
6649
6650		var nxs_js_googleplusinjected = false;
6651
6652		function nxs_js_inject_googleplus()
6653		{
6654			if (nxs_js_googleplusinjected)
6655			{
6656				return;
6657			}
6658			nxs_js_googleplusinjected = true;
6659			script = document.createElement('script');
6660	    script.async = true;
6661	    script.src = '//apis.google.com/js/plusone.js';
6662	    document.body.appendChild(script);
6663		}
6664
6665		//
6666		// generic page redirector for editing header, sidebar, footer, subheader, subfooter or pagelets
6667		//
6668		// for example :
6669		// layouttype = "header"
6670		// pagesheetwhennotavailable = "headerhome"
6671		//
6672		function nxs_js_editpagesection(postid, layouttype, pagesheetwhennotavailable)
6673		{
6674			var nxsrefurlspecial = nxs_js_get_nxsrefurlspecial();
6675			nxs_js_geturl(
6676				layouttype,
6677				postid,
6678				nxsrefurlspecial,
6679				function(response)
6680				{
6681					var url = response.url;
6682					nxs_js_log(url);
6683					nxs_js_redirect(url);
6684				},
6685				function()
6686				{
6687					// fout, kan komen als de layout niet gekoppeld is
6688					nxs_js_popup_pagetemplate_neweditsession(pagesheetwhennotavailable);
6689				}
6690			);
6691		}
6692
6693		function nxs_js_nop()
6694		{
6695			// no operation
6696		}
6697
6698		function nxs_js_opensupportoptions()
6699		{
6700			nxs_js_popup_site_neweditsession('supportoptions');
6701		}
6702
6703		function nxs_js_generic_ws(webmethod, inputparameters, invokewhenavailable)
6704		{
6705			var ajaxurl = nxs_js_get_adminurladminajax();
6706			jQuery.ajax
6707			(
6708				{
6709					type: 'POST',
6710					data:
6711					{
6712						"action": "nxs_ajax_webmethods",
6713						"webmethod": webmethod,
6714						"clientpopupsessioncontext": nxs_js_getescaped_popupsession_context(),
6715						"inputparameters": inputparameters
6716					},
6717					cache: false,
6718					dataType: 'JSON',
6719					url: ajaxurl,
6720					success: function(response)
6721					{
6722						nxs_js_log(response);
6723						if (response.result == "OK")
6724						{
6725							invokewhenavailable(response);
6726						}
6727						else
6728						{
6729							nxs_js_popup_notifyservererror();
6730							nxs_js_log(response);
6731						}
6732					},
6733					error: function(response)
6734					{
6735						nxs_js_popup_notifyservererror();
6736						nxs_js_log(response);
6737					}
6738				}
6739			);
6740			// Refresh na update SPWEB-1058
6741			// location.reload();
6742		}
6743
6744		function showTitleInFooterAndSidebar(key)
6745		{
6746            var element = document.getElementById('nxs-widget-' + key);
6747
6748            if ($(element).parents('.nxs-sidebar-container').length) {
6749                $(element.getElementsByClassName('top-wrapper')[0]).show();
6750            }
6751            if ($(element).parents('.nxs-footer-container').length) {
6752                $(element.getElementsByClassName('top-wrapper')[0]).show();
6753            }
6754		}
6755
6756		// kudos to http://stackoverflow.com/questions/3431512/javascript-equivalent-to-phps-urldecode
6757		function nxs_js_urldecode(url)
6758		{
6759		  return decodeURIComponent(url.replace(/\+/g, ' '));
6760		}
6761
6762		// encoding / base64
6763
6764		function nxs_js_utf8_encode (argString)
6765		{
6766			// http://kevin.vanzonneveld.net
6767			// +   original by: Webtoolkit.info (http://www.webtoolkit.info/)
6768			// +   improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
6769			// +   improved by: sowberry
6770			// +    tweaked by: Jack
6771			// +   bugfixed by: Onno Marsman
6772			// +   improved by: Yves Sucaet
6773			// +   bugfixed by: Onno Marsman
6774			// +   bugfixed by: Ulrich
6775			// +   bugfixed by: Rafal Kukawski
6776			// *     example 1: nxs_js_utf8_encode('Kevin van Zonneveld');
6777			// *     returns 1: 'Kevin van Zonneveld'
6778
6779			if (argString === null || typeof argString === "undefined") {
6780			return "";
6781			}
6782
6783			var string = (argString + ''); // .replace(/\r\n/g, "\n").replace(/\r/g, "\n");
6784			var utftext = "",
6785			start, end, stringl = 0;
6786
6787			start = end = 0;
6788			stringl = string.length;
6789			for (var n = 0; n < stringl; n++) {
6790			var c1 = string.charCodeAt(n);
6791			var enc = null;
6792
6793			if (c1 < 128) {
6794			end++;
6795			} else if (c1 > 127 && c1 < 2048) {
6796			enc = String.fromCharCode((c1 >> 6) | 192) + String.fromCharCode((c1 & 63) | 128);
6797			} else {
6798			enc = String.fromCharCode((c1 >> 12) | 224) + String.fromCharCode(((c1 >> 6) & 63) | 128) + String.fromCharCode((c1 & 63) | 128);
6799			}
6800			if (enc !== null) {
6801			if (end > start) {
6802			utftext += string.slice(start, end);
6803			}
6804			utftext += enc;
6805			start = end = n + 1;
6806			}
6807			}
6808
6809			if (end > start) {
6810			utftext += string.slice(start, stringl);
6811			}
6812
6813			return utftext;
6814		}
6815
6816		function nxs_js_base64_encode(data)
6817		{
6818			// http://kevin.vanzonneveld.net
6819			// +   original by: Tyler Akins (http://rumkin.com)
6820			// +   improved by: Bayron Guevara
6821			// +   improved by: Thunder.m
6822			// +   improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
6823			// +   bugfixed by: Pellentesque Malesuada
6824			// +   improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
6825			// -    depends on: nxs_js_utf8_encode
6826			// *     example 1: base64_encode('Kevin van Zonneveld');
6827			// *     returns 1: 'S2V2aW4gdmFuIFpvbm5ldmVsZA=='
6828			// mozilla has this native
6829			// - but breaks in 2.0.0.12!
6830			//if (typeof this.window['atob'] == 'function') {
6831			//    return atob(data);
6832			//}
6833			var b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
6834			var o1, o2, o3, h1, h2, h3, h4, bits, i = 0,
6835			ac = 0,
6836			enc = "",
6837			tmp_arr = [];
6838
6839			if (!data) {
6840			return data;
6841			}
6842
6843			data = this.nxs_js_utf8_encode(data + '');
6844
6845			do { // pack three octets into four hexets
6846			o1 = data.charCodeAt(i++);
6847			o2 = data.charCodeAt(i++);
6848			o3 = data.charCodeAt(i++);
6849
6850			bits = o1 << 16 | o2 << 8 | o3;
6851
6852			h1 = bits >> 18 & 0x3f;
6853			h2 = bits >> 12 & 0x3f;
6854			h3 = bits >> 6 & 0x3f;
6855			h4 = bits & 0x3f;
6856
6857			// use hexets to index into b64, and append result to encoded string
6858			tmp_arr[ac++] = b64.charAt(h1) + b64.charAt(h2) + b64.charAt(h3) + b64.charAt(h4);
6859			} while (i < data.length);
6860
6861			enc = tmp_arr.join('');
6862
6863			switch (data.length % 3) {
6864			case 1:
6865			enc = enc.slice(0, -2) + '==';
6866			break;
6867			case 2:
6868			enc = enc.slice(0, -1) + '=';
6869			break;
6870			}
6871
6872			return enc;
6873		}
6874
6875		//
6876
6877		// ------------------------------------------------------------------------------------
6878		// seo functions
6879
6880		function nxs_js_refresh_seoanalysis()
6881		{
6882			//nxs_js_log("seo:");
6883			//nxs_js_log(jQuery('#tabs-seo'));
6884			if (jQuery('#tabs-seo #nxsseoanalysisoutput').length > 0)
6885			{
6886				nxs_js_refresh_seoanalysis_enqueuerequest();
6887			}
6888			else
6889			{
6890				// SEO is disabled
6891			}
6892		}
6893
6894		function nxs_js_refresh_seoanalysis_enqueuerequest(trigger)
6895		{
6896			// mark as triggered
6897			if (nxs_js_isseorefreshqueued == true)
6898			{
6899				// performance boost; we gaan hier niet nogmaals
6900				// alle berekeningen doorvoeren; er is reeds een ververs
6901				// request ingepland
6902				// nxs_js_log('skipping refresh, already queued');
6903				return;
6904			}
6905			else
6906			{
6907				// nxs_js_log('nothing in queue yet, enqueueing refresh request');
6908				// enqueue!
6909				nxs_js_isseorefreshqueued = true;
6910
6911				var nxs_max_refresh_frequency_in_msecs = 100;	// lager betekent meer overhead, maar "snappier" gedrag
6912				setTimeout
6913				(
6914					function()
6915					{
6916						//nxs_js_log('executing actual refresh work');
6917
6918						// first we dequeue!
6919						nxs_js_isseorefreshqueued = false;
6920						nxs_js_refresh_seoanalysis_actualrequest();
6921					},nxs_max_refresh_frequency_in_msecs
6922				);
6923			}
6924		}
6925
6926		function nxs_js_refresh_seoanalysis_actualrequest()
6927		{
6928			jQuery('#nxs-seofields').show();
6929
6930			var postid = nxs_js_getcontainerpostid();
6931
6932			var inputparameters = { "postid" : postid };
6933
6934			nxs_js_generic_ws
6935			(
6936				"getseoanalysis",
6937				inputparameters,
6938				function(responseparameters)
6939				{
6940					// process
6941
6942					var outputhtml = '';
6943
6944					//
6945					jQuery('#nxs-seofocuskeyword').val(responseparameters.focuskw);
6946					jQuery('#nxs-seotitle').val(responseparameters.title);
6947					jQuery('#nxs-seometadescription').val(responseparameters.metadesc);
6948
6949					// update title of current browser window too
6950					document.title = responseparameters.title;
6951
6952					var wperrors = responseparameters.wperrors;
6953
6954					if (wperrors != null)
6955					{
6956						var numerrors = wperrors.length;
6957						for (var i = 0; i < numerrors; i++)
6958						{
6959						 	var currenterror = wperrors[i];
6960
6961							nxs_js_log("current error:");
6962							nxs_js_log(currenterror);
6963
6964							outputhtml += currenterror;
6965							//nxs_js_alert(currenterror);
6966						}
6967						// display output
6968						jQuery('#nxs-seo-output').html(outputhtml);
6969
6970						// update height
6971						nxs_js_refreshtopmenufillerheight();
6972
6973						// update counters
6974						nxs_js_shownumofchars('#nxs-seotitle', '#seotitlecharsused');
6975						nxs_js_shownumofchars('#nxs-seometadescription', '#seodescriptioncharsused');
6976
6977						// cancel further processing
6978						return;
6979					}
6980
6981					try
6982					{
6983						// highlight focus keywordwords
6984						var words = responseparameters.focuskw;
6985						// highlighting is performed on a per-word basis
6986						var wordpieces = words.split(' ');
6987						for (var i = 0; i < wordpieces.length; i++)
6988						{
6989							var word = wordpieces[i];
6990							if (word != '')
6991							{
6992								nxs_js_log('highlighting..[' + word + ']');
6993					    	nxs_js_highlightword(document.getElementById('nxs-seo-snippetwrapper'), word);
6994					    }
6995					    else
6996					    {
6997					    	// ignore (otherwise a browser lockup occurs...)
6998					    }
6999						}
7000					}
7001					catch (err)
7002					{
7003						// absorb (for example, failed in < ie9
7004						nxs_js_log(err);
7005					}
7006
7007					nxs_js_log('updating height');
7008
7009					// update height top menu
7010					nxs_js_refreshtopmenufillerheight();
7011				}
7012			);
7013		}
7014
7015		function nxs_js_update_seooption(postid, key, val, success)
7016		{
7017			var ajaxurl = nxs_js_get_adminurladminajax();
7018			jQuery.ajax
7019			(
7020				{
7021					type: 'POST',
7022					data:
7023					{
7024						"action": "nxs_ajax_webmethods",
7025						"webmethod": "updateseooption",
7026						"postid": postid,
7027						"key": key,
7028						"val": val
7029					},
7030					async: false,
7031					cache: false,
7032					dataType: 'JSON',
7033					url: ajaxurl,
7034					success: function(response)
7035					{
7036						nxs_js_log(response);
7037						if (response.result == "OK")
7038						{
7039							success(response);
7040							// ok
7041						}
7042						else
7043						{
7044							nxs_js_popup_notifyservererror();
7045							nxs_js_log(response);
7046						}
7047					},
7048					error: function(response)
7049					{
7050						nxs_js_popup_notifyservererror();
7051						nxs_js_log(response);
7052					}
7053				}
7054			);
7055		}
7056
7057		function nxs_js_update_seoall()
7058		{
7059			nxs_js_update_seofocuskeyword();
7060			nxs_js_update_seotitle();
7061			nxs_js_update_seometadescription();
7062
7063			nxs_js_refresh_seoanalysis();
7064
7065			// turn off update button
7066			jQuery('#nxs-seofield-updatebutton').hide();
7067		}
7068
7069		function nxs_js_update_seofocuskeyword()
7070		{
7071			var postid = nxs_js_getcontainerpostid();
7072			var val = jQuery('#nxs-seofocuskeyword').val();
7073			if (val != null && val.length > 0)
7074			{
7075				var key = 'focuskw';
7076				nxs_js_update_seooption
7077				(
7078					postid,
7079					key,
7080					val,
7081					function()
7082					{
7083						//nxs_js_alert('update successful');
7084					}
7085				);
7086			}
7087			else
7088			{
7089				nxs_js_alert('focuskw not updated; empty');
7090			}
7091		}
7092
7093		function nxs_js_update_seotitle()
7094		{
7095			var postid = nxs_js_getcontainerpostid();
7096			var val = jQuery('#nxs-seotitle').val();
7097			if (val != null && val.length > 0)
7098			{
7099				var key = 'title';
7100				nxs_js_update_seooption
7101				(
7102					postid,
7103					key,
7104					val,
7105					function()
7106					{
7107						//nxs_js_alert('update successful');
7108					}
7109				);
7110			}
7111			else
7112			{
7113				nxs_js_alert('title not updated; empty');
7114			}
7115
7116		}
7117
7118		function nxs_js_update_seometadescription()
7119		{
7120			var postid = nxs_js_getcontainerpostid();
7121			var val = jQuery('#nxs-seometadescription').val();
7122			if (val != null && val.length > 0)
7123			{
7124				var key = 'metadesc';
7125				nxs_js_update_seooption
7126				(
7127					postid,
7128					key,
7129					val,
7130					function()
7131					{
7132						//nxs_js_alert('update successful');
7133					}
7134				);
7135			}
7136			else
7137			{
7138				nxs_js_alert('meta desc not updated; empty');
7139			}
7140		}
7141
7142		function nxs_js_shownumofchars(inputfield, outputfield)
7143		{
7144			if (jQuery(inputfield) == null)
7145			{
7146				nxs_js_log("inputfield not found:" + inputfield);
7147				return;
7148			}
7149			if (jQuery(outputfield) == null)
7150			{
7151				nxs_js_log("outputfield not found:" + outputfield);
7152				return;
7153			}
7154			var aantal = jQuery(inputfield).val().length;
7155			jQuery(outputfield).html(aantal);
7156		}
7157
7158		// kudos to http://stackoverflow.com/questions/10729983/highlight-word-in-html-text-but-not-markup
7159		function nxs_js_highlightword(root,word){
7160		  nxs_js_textnodesunder(root).forEach(nxs_js_highlightwords);
7161
7162		  function nxs_js_textnodesunder(root){
7163		    var n,a=[],w=document.createTreeWalker(root,NodeFilter.SHOW_TEXT,null,false);
7164		    while(n=w.nextNode()) a.push(n);
7165		    return a;
7166		  }
7167
7168		  function nxs_js_highlightwords(n){
7169		  	// ignores casing
7170		    for (var i; (i=getnormalizedcomparable(n.nodeValue).indexOf(getnormalizedcomparable(word),i)) > -1; n=after){
7171		      var after = n.splitText(i+word.length);
7172		      var highlighted = n.splitText(i);
7173		      var span = document.createElement('span');
7174		      span.className = 'nxs-highlighted';
7175		      span.appendChild(highlighted);
7176		      after.parentNode.insertBefore(span,after);
7177		    }
7178		  }
7179		}
7180
7181		// kudos to http://lehelk.com/2011/05/06/script-to-remove-diacritics/
7182		var defaultDiacriticsRemovalMap = [
7183    {'base':'A', 'letters':/[\u0041\u24B6\uFF21\u00C0\u00C1\u00C2\u1EA6\u1EA4\u1EAA\u1EA8\u00C3\u0100\u0102\u1EB0\u1EAE\u1EB4\u1EB2\u0226\u01E0\u00C4\u01DE\u1EA2\u00C5\u01FA\u01CD\u0200\u0202\u1EA0\u1EAC\u1EB6\u1E00\u0104\u023A\u2C6F]/g},
7184    {'base':'AA','letters':/[\uA732]/g},
7185    {'base':'AE','letters':/[\u00C6\u01FC\u01E2]/g},
7186    {'base':'AO','letters':/[\uA734]/g},
7187    {'base':'AU','letters':/[\uA736]/g},
7188    {'base':'AV','letters':/[\uA738\uA73A]/g},
7189    {'base':'AY','letters':/[\uA73C]/g},
7190    {'base':'B', 'letters':/[\u0042\u24B7\uFF22\u1E02\u1E04\u1E06\u0243\u0182\u0181]/g},
7191    {'base':'C', 'letters':/[\u0043\u24B8\uFF23\u0106\u0108\u010A\u010C\u00C7\u1E08\u0187\u023B\uA73E]/g},
7192    {'base':'D', 'letters':/[\u0044\u24B9\uFF24\u1E0A\u010E\u1E0C\u1E10\u1E12\u1E0E\u0110\u018B\u018A\u0189\uA779]/g},
7193    {'base':'DZ','letters':/[\u01F1\u01C4]/g},
7194    {'base':'Dz','letters':/[\u01F2\u01C5]/g},
7195    {'base':'E', 'letters':/[\u0045\u24BA\uFF25\u00C8\u00C9\u00CA\u1EC0\u1EBE\u1EC4\u1EC2\u1EBC\u0112\u1E14\u1E16\u0114\u0116\u00CB\u1EBA\u011A\u0204\u0206\u1EB8\u1EC6\u0228\u1E1C\u0118\u1E18\u1E1A\u0190\u018E]/g},
7196    {'base':'F', 'letters':/[\u0046\u24BB\uFF26\u1E1E\u0191\uA77B]/g},
7197    {'base':'G', 'letters':/[\u0047\u24BC\uFF27\u01F4\u011C\u1E20\u011E\u0120\u01E6\u0122\u01E4\u0193\uA7A0\uA77D\uA77E]/g},
7198    {'base':'H', 'letters':/[\u0048\u24BD\uFF28\u0124\u1E22\u1E26\u021E\u1E24\u1E28\u1E2A\u0126\u2C67\u2C75\uA78D]/g},
7199    {'base':'I', 'letters':/[\u0049\u24BE\uFF29\u00CC\u00CD\u00CE\u0128\u012A\u012C\u0130\u00CF\u1E2E\u1EC8\u01CF\u0208\u020A\u1ECA\u012E\u1E2C\u0197]/g},
7200    {'base':'J', 'letters':/[\u004A\u24BF\uFF2A\u0134\u0248]/g},
7201    {'base':'K', 'letters':/[\u004B\u24C0\uFF2B\u1E30\u01E8\u1E32\u0136\u1E34\u0198\u2C69\uA740\uA742\uA744\uA7A2]/g},
7202    {'base':'L', 'letters':/[\u004C\u24C1\uFF2C\u013F\u0139\u013D\u1E36\u1E38\u013B\u1E3C\u1E3A\u014
72021\u023D\u2C62\u2C60\uA748\uA746\uA780]/g},
7203    {'base':'LJ','letters':/[\u01C7]/g},
7204    {'base':'Lj','letters':/[\u01C8]/g},
7205    {'base':'M', 'letters':/[\u004D\u24C2\uFF2D\u1E3E\u1E40\u1E42\u2C6E\u019C]/g},
7206    {'base':'N', 'letters':/[\u004E\u24C3\uFF2E\u01F8\u0143\u00D1\u1E44\u0147\u1E46\u0145\u1E4A\u1E48\u0220\u019D\uA790\uA7A4]/g},
7207    {'base':'NJ','letters':/[\u01CA]/g},
7208    {'base':'Nj','letters':/[\u01CB]/g},
7209    {'base':'O', 'letters':/[\u004F\u24C4\uFF2F\u00D2\u00D3\u00D4\u1ED2\u1ED0\u1ED6\u1ED4\u00D5\u1E4C\u022C\u1E4E\u014C\u1E50\u1E52\u014E\u022E\u0230\u00D6\u022A\u1ECE\u0150\u01D1\u020C\u020E\u01A0\u1EDC\u1EDA\u1EE0\u1EDE\u1EE2\u1ECC\u1ED8\u01EA\u01EC\u00D8\u01FE\u0186\u019F\uA74A\uA74C]/g},
7210    {'base':'OI','letters':/[\u01A2]/g},
7211    {'base':'OO','letters':/[\uA74E]/g},
7212    {'base':'OU','letters':/[\u0222]/g},
7213    {'base':'P', 'letters':/[\u0050\u24C5\uFF30\u1E54\u1E56\u01A4\u2C63\uA750\uA752\uA754]/g},
7214    {'base':'Q', 'letters':/[\u0051\u24C6\uFF31\uA756\uA758\u024A]/g},
7215    {'base':'R', 'letters':/[\u0052\u24C7\uFF32\u0154\u1E58\u0158\u0210\u0212\u1E5A\u1E5C\u0156\u1E5E\u024C\u2C64\uA75A\uA7A6\uA782]/g},
7216    {'base':'S', 'letters':/[\u0053\u24C8\uFF33\u1E9E\u015A\u1E64\u015C\u1E60\u0160\u1E66\u1E62\u1E68\u0218\u015E\u2C7E\uA7A8\uA784]/g},
7217    {'base':'T', 'letters':/[\u0054\u24C9\uFF34\u1E6A\u0164\u1E6C\u021A\u0162\u1E70\u1E6E\u0166\u01AC\u01AE\u023E\uA786]/g},
7218    {'base':'TZ','letters':/[\uA728]/g},
7219    {'base':'U', 'letters':/[\u0055\u24CA\uFF35\u00D9\u00DA\u00DB\u0168\u1E78\u016A\u1E7A\u016C\u00DC\u01DB\u01D7\u01D5\u01D9\u1EE6\u016E\u0170\u01D3\u0214\u0216\u01AF\u1EEA\u1EE8\u1EEE\u1EEC\u1EF0\u1EE4\u1E72\u0172\u1E76\u1E74\u0244]/g},
7220    {'base':'V', 'letters':/[\u0056\u24CB\uFF36\u1E7C\u1E7E\u01B2\uA75E\u0245]/g},
7221    {'base':'VY','letters':/[\uA760]/g},
7222    {'base':'W', 'letters':/[\u0057\u24CC\uFF37\u1E80\u1E82\u0174\u1E86\u1E84\u1E88\u2C72]/g},
7223    {'base':'X', 'letters':/[\u0058\u24CD\uFF38\u1E8A\u1E8C]/g},
7224    {'base':'Y', 'letters':/[\u0059\u24CE\uFF39\u1EF2\u00DD\u0176\u1EF8\u0232\u1E8E\u0178\u1EF6\u1EF4\u01B3\u024E\u1EFE]/g},
7225    {'base':'Z', 'letters':/[\u005A\u24CF\uFF3A\u0179\u1E90\u017B\u017D\u1E92\u1E94\u01B5\u0224\u2C7F\u2C6B\uA762]/g},
7226    {'base':'a', 'letters':/[\u0061\u24D0\uFF41\u1E9A\u00E0\u00E1\u00E2\u1EA7\u1EA5\u1EAB\u1EA9\u00E3\u0101\u0103\u1EB1\u1EAF\u1EB5\u1EB3\u0227\u01E1\u00E4\u01DF\u1EA3\u00E5\u01FB\u01CE\u0201\u0203\u1EA1\u1EAD\u1EB7\u1E01\u0105\u2C65\u0250]/g},
7227    {'base':'aa','letters':/[\uA733]/g},
7228    {'base':'ae','letters':/[\u00E6\u01FD\u01E3]/g},
7229    {'base':'ao','letters':/[\uA735]/g},
7230    {'base':'au','letters':/[\uA737]/g},
7231    {'base':'av','letters':/[\uA739\uA73B]/g},
7232    {'base':'ay','letters':/[\uA73D]/g},
7233    {'base':'b', 'letters':/[\u0062\u24D1\uFF42\u1E03\u1E05\u1E07\u0180\u0183\u0253]/g},
7234    {'base':'c', 'letters':/[\u0063\u24D2\uFF43\u0107\u0109\u010B\u010D\u00E7\u1E09\u0188\u023C\uA73F\u2184]/g},
7235    {'base':'d', 'letters':/[\u0064\u24D3\uFF44\u1E0B\u010F\u1E0D\u1E11\u1E13\u1E0F\u0111\u018C\u0256\u0257\uA77A]/g},
7236    {'base':'dz','letters':/[\u01F3\u01C6]/g},
7237    {'base':'e', 'letters':/[\u0065\u24D4\uFF45\u00E8\u00E9\u00EA\u1EC1\u1EBF\u1EC5\u1EC3\u1EBD\u0113\u1E15\u1E17\u0115\u0117\u00EB\u1EBB\u011B\u0205\u0207\u1EB9\u1EC7\u0229\u1E1D\u0119\u1E19\u1E1B\u0247\u025B\u01DD]/g},
7238    {'base':'f', 'letters':/[\u0066\u24D5\uFF46\u1E1F\u0192\uA77C]/g},
7239    {'base':'g', 'letters':/[\u0067\u24D6\uFF47\u01F5\u011D\u1E21\u011F\u0121\u01E7\u0123\u01E5\u0260\uA7A1\u1D79\uA77F]/g},
7240    {'base':'h', 'letters':/[\u0068\u24D7\uFF48\u0125\u1E23\u1E27\u021F\u1E25\u1E29\u1E2B\u1E96\u0127\u2C68\u2C76\u0265]/g},
7241    {'base':'hv','letters':/[\u0195]/g},
7242    {'base':'i', 'letters':/[\u0069\u24D8\uFF49\u00EC\u00ED\u00EE\u0129\u012B\u012D\u00EF\u1E2F\u1EC9\u01D0\u0209\u020B\u1ECB\u012F\u1E2D\u0268\u0131]/g},
7243    {'base':'j', 'letters':/[\u006A\u24D9\uFF4A\u0135\u01F0\u0249]/g},
7244    {'base':'k', 'letters':/[\u006B\u24DA\uFF4B\u1E31\u01E9\u1E33\u0137\u1E35\u0199\u2C6A\uA741\uA743\uA745\uA7A3]/g},
7245    {'base':'l', 'letters':/[\u006C\u24DB\uFF4C\u0140\u013A\u013E\u1E37\u1E39\u013C\u1E3D\u1E3B\u017F\u0142\u019A\u026B\u2C61\uA749\uA781\uA747]/g},
7246    {'base':'lj','letters':/[\u01C9]/g},
7247    {'base':'m', 'letters':/[\u006D\u24DC\uFF4D\u1E3F\u1E41\u1E43\u0271\u026F]/g},
7248    {'base':'n', 'letters':/[\u006E\u24DD\uFF4E\u01F9\u0144\u00F1\u1E45\u0148\u1E47\u0146\u1E4B\u1E49\u019E\u0272\u0149\uA791\uA7A5]/g},
7249    {'base':'nj','letters':/[\u01CC]/g},
7250    {'base':'o', 'letters':/[\u006F\u24DE\uFF4F\u00F2\u00F3\u00F4\u
72501ED3\u1ED1\u1ED7\u1ED5\u00F5\u1E4D\u022D\u1E4F\u014D\u1E51\u1E53\u014F\u022F\u0231\u00F6\u022B\u1ECF\u0151\u01D2\u020D\u020F\u01A1\u1EDD\u1EDB\u1EE1\u1EDF\u1EE3\u1ECD\u1ED9\u01EB\u01ED\u00F8\u01FF\u0254\uA74B\uA74D\u0275]/g},
7251    {'base':'oi','letters':/[\u01A3]/g},
7252    {'base':'ou','letters':/[\u0223]/g},
7253    {'base':'oo','letters':/[\uA74F]/g},
7254    {'base':'p','letters':/[\u0070\u24DF\uFF50\u1E55\u1E57\u01A5\u1D7D\uA751\uA753\uA755]/g},
7255    {'base':'q','letters':/[\u0071\u24E0\uFF51\u024B\uA757\uA759]/g},
7256    {'base':'r','letters':/[\u0072\u24E1\uFF52\u0155\u1E59\u0159\u0211\u0213\u1E5B\u1E5D\u0157\u1E5F\u024D\u027D\uA75B\uA7A7\uA783]/g},
7257    {'base':'s','letters':/[\u0073\u24E2\uFF53\u00DF\u015B\u1E65\u015D\u1E61\u0161\u1E67\u1E63\u1E69\u0219\u015F\u023F\uA7A9\uA785\u1E9B]/g},
7258    {'base':'t','letters':/[\u0074\u24E3\uFF54\u1E6B\u1E97\u0165\u1E6D\u021B\u0163\u1E71\u1E6F\u0167\u01AD\u0288\u2C66\uA787]/g},
7259    {'base':'tz','letters':/[\uA729]/g},
7260    {'base':'u','letters':/[\u0075\u24E4\uFF55\u00F9\u00FA\u00FB\u0169\u1E79\u016B\u1E7B\u016D\u00FC\u01DC\u01D8\u01D6\u01DA\u1EE7\u016F\u0171\u01D4\u0215\u0217\u01B0\u1EEB\u1EE9\u1EEF\u1EED\u1EF1\u1EE5\u1E73\u0173\u1E77\u1E75\u0289]/g},
7261    {'base':'v','letters':/[\u0076\u24E5\uFF56\u1E7D\u1E7F\u028B\uA75F\u028C]/g},
7262    {'base':'vy','letters':/[\uA761]/g},
7263    {'base':'w','letters':/[\u0077\u24E6\uFF57\u1E81\u1E83\u0175\u1E87\u1E85\u1E98\u1E89\u2C73]/g},
7264    {'base':'x','letters':/[\u0078\u24E7\uFF58\u1E8B\u1E8D]/g},
7265    {'base':'y','letters':/[\u0079\u24E8\uFF59\u1EF3\u00FD\u0177\u1EF9\u0233\u1E8F\u00FF\u1EF7\u1E99\u1EF5\u01B4\u024F\u1EFF]/g},
7266    {'base':'z','letters':/[\u007A\u24E9\uFF5A\u017A\u1E91\u017C\u017E\u1E93\u1E95\u01B6\u0225\u0240\u2C6C\uA763]/g}
7267		];
7268		function nxs_js_removediacritics(str) {
7269		    var changes = defaultDiacriticsRemovalMap;
7270		    for(var i=0; i<changes.length; i++)
7271		    {
7272		      str = str.replace(changes[i].letters, changes[i].base);
7273		    }
7274		    return str;
7275		}
7276
7277		function getnormalizedcomparable(str)
7278		{
7279			return nxs_js_removediacritics(str).toLowerCase();
7280		}
7281
7282		/*
7283		-------------------------------------------------------
7284		-------------------------------------------------------
7285		js color handling
7286		kudos to http://mjijackson.com/2008/02/rgb-to-hsl-and-rgb-to-hsv-color-model-conversion-algorithms-in-javascript
7287		-------------------------------------------------------
7288		-------------------------------------------------------
7289		*/
7290
7291		function nxs_js_rgbtohsl(rgb)
7292		{
7293			if (rgb == null)
7294			{
7295				return null;
7296			}
7297		var r = rgb.r;
7298		var g = rgb.g;
7299		var b = rgb.b;
7300
7301    r /= 255, g /= 255, b /= 255;
7302    var max = Math.max(r, g, b), min = Math.min(r, g, b);
7303    var h, s, l = (max + min) / 2;
7304
7305    if(max == min){
7306        h = s = 0; // achromatic
7307    }else{
7308        var d = max - min;
7309        s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
7310        switch(max){
7311            case r: h = (g - b) / d + (g < b ? 6 : 0); break;
7312            case g: h = (b - r) / d + 2; break;
7313            case b: h = (r - g) / d + 4; break;
7314        }
7315        h /= 6;
7316    }
7317
7318    var result = {
7319    h: h,
7320    s: s,
7321    l: l
7322    }
7323
7324    return result;
7325}
7326
7327function nxs_js_adjustlightnessforhsl(hsl, lightnessdelta)
7328{
7329	if (hsl == null)
7330	{
7331	return null;
7332	}
7333	//nxs_js_log(hsl);
7334
7335	var result =
7336	{
7337		h : hsl.h,
7338		s : hsl.s,
7339		l : hsl.l + lightnessdelta
7340	}
7341
7342	if (result.l < 0)
7343	{
7344		result.l = 0;
7345	}
7346	else if (result.l > 1)
7347	{
7348		result.l = 1;
7349	}
7350
7351	return result;
7352}
7353
7354function nxs_js_gethextransformedrgblight(rgb, delta)
7355{
7356	var hsl = nxs_js_rgbtohsl(rgb);
7357	var adjustedhsl = nxs_js_adjustlightnessforhsl(hsl, delta);
7358	var adjustedrgb = nxs_js_hsltorgb(adjustedhsl);
7359	var adjustedhex = nxs_js_rgbtohex(adjustedrgb);
7360	return adjustedhex;
7361}
7362
7363// within the given hue, select the reverse s and l
7364function nxs_js_getoppositesaturationandlightforhsl(hsl)
7365{
7366	nxs_js_log("before hsl:");
7367	nxs_js_log(hsl);
7368
7369	var result =
7370	{
7371		h : hsl.h,
7372		s : 1 - hsl.s,
7373		l : 1 - hsl.l
7374	}
7375
7376	nxs_js_log("after hsl:");
7377	nxs_js_log(result);
7378
7379	return result;
7380}
7381
7382function nxs_js_getcomplementaryhsl(hsl)
7383{
7384	var result =
7385	{
7386		h : (0.5 + hsl.h) % 1,
7387		s : hsl.s,
7388		l : hsl.l
7389	}
7390	return result;
7391}
7392
7393function nxs_js_hslinbounds(hsl)
7394{
7395	// h
7396	if (hsl.h < 0)
7397	{
7398		hsl.h += 1;
7399	}
7400	else if (hsl.h > 1)
7401	{
7402		hsl.h -= 1;
7403	}
7404	// s
7405	if (hsl.s < 0)
7406	{
7407		hsl.s += 1;
7408	}
7409	else if (hsl.s > 1)
7410	{
7411		hsl.s -= 1;
7412	}
7413	// l
7414	if (hsl.l < 0)
7415	{
7416		hsl.l += 1;
7417	}
7418	else if (hsl.l > 1)
7419	{
7420		hsl.l -= 1;
7421	}
7422	return hsl;
7423}
7424
7425function nxs_js_getcomplementaryhsl(hsl)
7426{
7427	var result = [];
7428	var item;
7429
7430	item =
7431	{
7432		h : hsl.h,
7433		s : hsl.s,
7434		l : hsl.l
7435	}
7436	item = nxs_js_hslinbounds(item);
7437	result.push(item);
7438
7439	item =
7440	{
7441		h : hsl.h + (1/2),
7442		s : hsl.s,
7443		l : hsl.l
7444	}
7445	item = nxs_js_hslinbounds(item);
7446	result.push(item);
7447
7448	return result;
7449}
7450
7451function nxs_js_getsplitcomplementaryhsl(hsl)
7452{
7453	nxs_js_log("before:");
7454	nxs_js_log(hsl);
7455
7456	var result = [];
7457	var item;
7458
7459	item =
7460	{
7461		h : hsl.h - (1/3),
7462		s : hsl.s,
7463		l : hsl.l
7464	}
7465	item = nxs_js_hslinbounds(item);
7466	result.push(item);
7467
7468	//nxs_js_log("first:");
7469	//nxs_js_log(item);
7470
7471	item =
7472	{
7473		h : hsl.h,
7474		s : hsl.s,
7475		l : hsl.l
7476	}
7477	item = nxs_js_hslinbounds(item);
7478	result.push(item);
7479
7480	//nxs_js_log("second:");
7481	//nxs_js_log(item);
7482
7483	item =
7484	{
7485		h : hsl.h + (1/3),
7486		s : hsl.s,
7487		l : hsl.l
7488	}
7489	item = nxs_js_hslinbounds(item);
7490	result.push(item);
7491
7492	//nxs_js_log("third1:");
7493	//nxs_js_log(item);
7494
7495	return result;
7496}
7497
7498function nxs_js_getmonohsl(hsl)
7499{
7500	var result = [];
7501	var item;
7502
7503	item =
7504	{
7505		h : hsl.h,
7506		s : hsl.s,
7507		l : hsl.l
7508	}
7509	item = nxs_js_hslinbounds(item);
7510	result.push(item);
7511
7512	return result;
7513}
7514
7515function nxs_js_gettriadbyanglehsl(hsl, angle)
7516{
7517	nxs_js_log("before:");
7518	nxs_js_log(hsl);
7519
7520	var result = [];
7521	var item;
7522
7523	item =
7524	{
7525		h : hsl.h + 0.5 - (angle/360),
7526		s : hsl.s,
7527		l : hsl.l
7528	}
7529	item = nxs_js_hslinbounds(item);
7530	result.push(item);
7531
7532	//nxs_js_log("first:");
7533	//nxs_js_log(item);
7534
7535	item =
7536	{
7537		h : hsl.h,
7538		s : hsl.s,
7539		l : hsl.l
7540	}
7541	item = nxs_js_hslinbounds(item);
7542	result.push(item);
7543
7544	//nxs_js_log("second:");
7545	//nxs_js_log(item);
7546
7547	item =
7548	{
7549		h : hsl.h + 0.5 + (angle/360),
7550		s : hsl.s,
7551		l : hsl.l
7552	}
7553	item = nxs_js_hslinbounds(item);
7554	result.push(item);
7555
7556	//nxs_js_log("third1:");
7557	//nxs_js_log(item);
7558
7559	return result;
7560}
7561
7562function nxs_js_getanalogicbyanglehsl(hsl, angle)
7563{
7564	nxs_js_log("before:");
7565	nxs_js_log(hsl);
7566
7567	var result = [];
7568	var item;
7569
7570	item =
7571	{
7572		h : hsl.h - (angle/360),
7573		s : hsl.s,
7574		l : hsl.l
7575	}
7576	item = nxs_js_hslinbounds(item);
7577	result.push(item);
7578
7579	//nxs_js_log("first:");
7580	//nxs_js_log(item);
7581
7582	item =
7583	{
7584		h : hsl.h,
7585		s : hsl.s,
7586		l : hsl.l
7587	}
7588	item = nxs_js_hslinbounds(item);
7589	result.push(item);
7590
7591	//nxs_js_log("second:");
7592	//nxs_js_log(item);
7593
7594	item =
7595	{
7596		h : hsl.h + (angle/360),
7597		s : hsl.s,
7598		l : hsl.l
7599	}
7600	item = nxs_js_hslinbounds(item);
7601	result.push(item);
7602
7603	//nxs_js_log("third1:");
7604	//nxs_js_log(item);
7605
7606	return result;
7607}
7608
7609
7610function nxs_js_getaccentedanalogicbyanglehsl(hsl, angle)
7611{
7612	var result = [];
7613	var item;
7614
7615	item =
7616	{
7617		h : hsl.h - (angle/360),
7618		s : hsl.s,
7619		l : hsl.l
7620	}
7621	item = nxs_js_hslinbounds(item);
7622	result.push(item);
7623
7624	item =
7625	{
7626		h : hsl.h,
7627		s : hsl.s,
7628		l : hsl.l
7629	}
7630	item = nxs_js_hslinbounds(item);
7631	result.push(item);
7632
7633	item =
7634	{
7635		h : hsl.h + (angle/360),
7636		s : hsl.s,
7637		l : hsl.l
7638	}
7639	item = nxs_js_hslinbounds(item);
7640	result.push(item);
7641
7642	item =
7643	{
7644		h : hsl.h + 0.5,
7645		s : hsl.s,
7646		l : hsl.l
7647	}
7648	item = nxs_js_hslinbounds(item);
7649	result.push(item);
7650
7651	return result;
7652}
7653
7654function nxs_js_gettetradbyanglehsl(hsl, angle)
7655{
7656	var result = [];
7657	var item;
7658
7659	item =
7660	{
7661		h : hsl.h,
7662		s : hsl.s,
7663		l : hsl.l
7664	}
7665	item = nxs_js_hslinbounds(item);
7666	result.push(item);
7667
7668	item =
7669	{
7670		h : hsl.h + (angle/360),
7671		s : hsl.s,
7672		l : hsl.l
7673	}
7674	item = nxs_js_hslinbounds(item);
7675	result.push(item);
7676
7677	item =
7678	{
7679		h : hsl.h + 0.5,
7680		s : hsl.s,
7681		l : hsl.l
7682	}
7683	item = nxs_js_hslinbounds(item);
7684	result.push(item);
7685
7686	item =
7687	{
7688		h : hsl.h + 0.5 + (angle/360),
7689		s : hsl.s,
7690		l : hsl.l
7691	}
7692	item = nxs_js_hslinbounds(item);
7693	result.push(item);
7694
7695
7696	return result;
7697}
7698
7699
7700/**
7701 * Converts an HSL color value to RGB. Conversion formula
7702 * adapted from http://en.wikipedia.org/wiki/HSL_color_space.
7703 * Assumes h, s, and l are contained in the set [0, 1] and
7704 * returns r, g, and b in the set [0, 255].
7705 *
7706 * @param   Number  h       The hue
7707 * @param   Number  s       The saturation
7708 * @param   Number  l       The lightness
7709 * @return  Array           The RGB representation
7710 */
7711function nxs_js_hsltorgb(hsl)
7712{
7713	if (hsl == null)
7714	{
7715		return null;
7716	}
7717
7718	var h = hsl.h;
7719	var s = hsl.s;
7720	var l = hsl.l;
7721
7722    var r, g, b;
7723
7724    if(s == 0){
7725        r = g = b = l; // achromatic
7726    }else{
7727        function hue2rgb(p, q, t){
7728            if(t < 0) t += 1;
7729            if(t > 1) t -= 1;
7730            if(t < 1/6) return p + (q - p) * 6 * t;
7731            if(t < 1/2) return q;
7732            if(t < 2/3) return p + (q - p) * (2/3 - t) * 6;
7733            return p;
7734        }
7735
7736        var q = l < 0.5 ? l * (1 + s) : l + s - l * s;
7737        var p = 2 * l - q;
7738        r = hue2rgb(p, q, h + 1/3);
7739        g = hue2rgb(p, q, h);
7740        b = hue2rgb(p, q, h - 1/3);
7741    }
7742
7743    var result = {
7744    r : Math.round(r * 255),
7745    g: Math.round(g * 255),
7746    b: Math.round(b * 255)
7747    };
7748
7749    return result;
7750}
7751
7752/*
7753kudos to http://stackoverflow.com/questions/5623838/rgb-to-hex-and-hex-to-rgb
7754*/
7755function nxs_js_hextorgb(hex) {
7756	if (hex == null || hex == '')
7757	{
7758		nxs_js_log("warning; hex;" + hex);
7759		return { r: 0, g: 0, b: 0 }
7760	}
7761    // Expand shorthand form (e.g. "03F") to full form (e.g. "0033FF")
7762    var shorthandRegex = /^#?([a-f\d])([a-f\d])([a-f\d])$/i;
7763    hex = hex.replace(shorthandRegex, function(m, r, g, b) {
7764        return r + r + g + g + b + b;
7765    });
7766
7767    var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
7768    return result ? {
7769        r: parseInt(result[1], 16),
7770        g: parseInt(result[2], 16),
7771        b: parseInt(result[3], 16)
7772    } : null;
7773}
7774
7775/* kudos to http://stackoverflow.com/questions/5623838/rgb-to-hex-and-hex-to-rgb */
7776
7777function nxs_js_componenttohex(c) {
7778    var hex = c.toString(16);
7779    return hex.length == 1 ? "0" + hex : hex;
7780}
7781
7782function nxs_js_rgbtohex(rgb)
7783{
7784	if (rgb == null)
7785	{
7786		return "#XXX";
7787	}
7788
7789	var r = rgb.r;
7790	var g = rgb.g;
7791	var b = rgb.b;
7792  return "#" + nxs_js_componenttohex(r) + nxs_js_componenttohex(g) + nxs_js_componenttohex(b);
7793}
7794
7795function nxs_js_hextohsl(hex)
7796{
7797	var rgb = nxs_js_hextorgb(hex);
7798	var hsl = nxs_js_rgbtohsl(rgb);
7799	return hsl;
7800}
7801
7802function nxs_js_displayStyleSheetProperties()
7803{
7804    var str = "";
7805    if( !document.styleSheets )
7806    {
7807        str = "Your browser does not support the stylesheets object.";
7808    }
7809    else if ( !document.styleSheets.length )
7810    {
7811        str = "There were no stylesheets found in the document.styleSheets collection.";
7812    }
7813    else
7814    {
7815    	nxs_js_log("outputting sheets:");
7816    	var sheetindex;
7817    	for (sheetindex in document.styleSheets)
7818    	{
7819    		var sheet = document.styleSheets[sheetindex];
7820    		nxs_js_log(sheet);
7821
7822    		nxs_js_log("HREF:" + sheet.href);
7823    		nxs_js_log("MEDIA:" + sheet.media);
7824    		nxs_js_log("OWNERNODE:");
7825    		nxs_js_log(sheet.ownerNode);
7826    	}
7827    }
7828    nxs_js_log(str);
7829}
7830
7831// css is the stylesheet contents to add / inject
7832// the stylesheetcontainer is an object that references the object of for example <style type="text/css" id="myObject"></style>
7833function nxs_js_setcss(css, containerbaseid)
7834{
7835	if(jQuery.browser.msie)
7836  {
7837		// great, thanks to MS we need multiple lame IE patches
7838		// first of all the injection itself is different...
7839		// see http://stackoverflow.com/questions/9050441/how-do-i-inject-styles-into-ie8
7840		// and second (even worse), IE 8 + 9 are only capable of handling 4095 selectors for
7841		// each css script. Thus, if the amount is too big, we need to split the css into
7842		// multiple parts and inject each
7843
7844		// var countmsg = nxs_js_getcssselectorcount(css);
7845
7846		var chunksresult = nxs_js_getchunksofcss(css);
7847		for (var i = 0; i < nxs_js_getmaxservercsschunks(); i++)
7848		{
7849			// get script for this chunk
7850			var stylesheetcontainer = jQuery(containerbaseid + i);
7851			var stylesheet = stylesheetcontainer.prop('styleSheet');
7852	  	if (stylesheet != null)
7853	  	{
7854	    	stylesheet.cssText=chunksresult.chunks[i];
7855	    }
7856	    else
7857	    {
7858	    	nxs_js_alert('failed to apply css!');
7859	    	nxs_js_log(stylesheet);
7860	    	nxs_js_log('likely the problem is that the number of stylesheets that can be applied in IE is limited to 32; did you exceed the number of allowed stylesheets?');
7861	    	nxs_js_displayStyleSheetProperties();
7862	    }
7863		}
7864  }
7865	else
7866	{
7867		// always store in containerbaseid 0 for non-ie browsers
7868		var i = 0;
7869		var stylesheetcontainer = jQuery(containerbaseid + i);
7870		jQuery(stylesheetcontainer).html(css);
7871	}
7872}
7873
7874function nxs_js_getkeys(lookup)
7875{
7876	var result = new Array();
7877	for(var key in lookup)
7878	{
7879	   result[result.length] = key;
7880	}
7881	return result;
7882}
7883
7884function nxs_js_sortbylength(a,b)
7885{
7886	var al = a.length;
7887	var bl = b.length;
7888	if (al == bl)
7889	{
7890		return 0;
7891	}
7892	else if (al < bl)
7893	{
7894		return 1;
7895	}
7896	else
7897	{
7898		return -1;
7899	}
7900}
7901
7902function nxs_js_removelinebreaks(content)
7903{
7904	return content.replace(/(\r\n|\n|\r)/gm,"");
7905}
7906
7907function nxs_js_removetabs(content)
7908{
7909	return content.replace(/\t/g, '');
7910}
7911
7912// kudos to http://stackoverflow.com/questions/3286874/remove-all-multiple-spaces-in-javascript-and-replace-with-single-space
7913function nxs_js_replacemultiplespaceswithsinglespace(content)
7914{
7915	return content.replace(/ +(?= )/g,'');
7916}
7917
7918function nxs_js_blendtemplatewithvariables(template, lookup)
7919{
7920	return nxs_js_blendtemplatewithvariables_v2(template, lookup, '$nxs_', '');
7921}
7922
7923// mixed the colorscheme template with the dictionary
7924function nxs_js_blendtemplatewithvariables_v2(template, lookup, keyprefix, keysuffix)
7925{
7926	if (template == null) { nxs_js_log('template not set?'); }
7927	if (lookup == null) { nxs_js_log('lookup not set?'); }
7928
7929	// "lineair" blending (note; this is not as sophisticated as SASS or LESS, but sufficient enough for now,
7930	// could be further enhanced for more complex replacements, like producing gradients
7931
7932	var keys;
7933	keys = nxs_js_getkeys(lookup);
7934	keys.sort(nxs_js_sortbylength);
7935
7936	// replace placeholders
7937	for (index = 0; index < keys.length; ++index)
7938	{
7939		var key = keys[index];
7940		var key2 = keyprefix + key + keysuffix;
7941		// note: the regexp "g" part is required to replace all instances instead of just the first
7942		var valuetouse = lookup[key];
7943		//nxs_js_log('replacing key:' + key2 + ' with value:' + valuetouse);
7944		template=template.replace(new RegExp('\\' + key2, "g"), valuetouse);
7945	}
7946
7947	if (template.indexOf("$") >= 0)
7948	{
7949		// it looks like we missed something...
7950		nxs_js_log('Warning, blender detected $ placeholder not being replaced; is the syntax of the template correct? did you miss a lookup placeholder? (for example use $nxs_color_base2_m)');
7951		nxs_js_log('template:');
7952		nxs_js_log(template);
7953		nxs_js_log('lookup:');
7954		nxs_js_log(lookup);
7955	}
7956	else
7957	{
7958		/*
7959		nxs_js_log('Blender ok');
7960		nxs_js_log('template:');
7961		nxs_js_log(template);
7962		nxs_js_log('lookup:');
7963		nxs_js_log(lookup);
7964		*/
7965	}
7966
7967	return template;
7968}
7969
7970//
7971function nxs_js_updatecss_themecss_actualrequest()
7972{
7973	// get active colorscheme
7974	var colorschemelookup = nxs_js_getruntimecolorschemelookup();
7975
7976	//nxs_js_log("colorschemelookup:");
7977	//nxs_js_log(colorschemelookup);
7978
7979	var runtimeurllookup = nxs_js_getruntimecsslookup();
7980
7981	// blend all lookups
7982	var csslookup = jQuery.extend({}, colorschemelookup, runtimeurllookup);
7983
7984	// the framework css will not be blended with lookups;
7985	// its required to contain end-css (if lookups
7986	// need to be translated, use the specifiekd csslookup parameter)
7987	var frameworkcss = nxs_js_get_frameworkcsstemplate(csslookup);
7988
7989	//
7990	var customcss = nxs_js_get_customcsstemplate(csslookup);
7991
7992	// blend the customcss (note! we intentionally only blend the
7993	// customcss, not the framework's css, this is done to keep performance high)
7994	var blendedcustomcss = nxs_js_blendtemplatewithvariables(customcss, csslookup);
7995
7996	//nxs_js_log("blendedcustomcss:");
7997	//nxs_js_log(blendedcustomcss);
7998
7999
8000	// we concatenate the end result; framework first, customcss is able
8001	// to override styling as needed
8002	var actualcss = frameworkcss + blendedcustomcss;
8003
8004	// update the css
8005	nxs_js_setcss(actualcss, '#nxs-dynamiccss-server-chunk-');
8006}
8007
8008// helper function to get the css output for a lineair gradient between the 2 specified colors
8009function nxs_js_getlineairgradientcss(colora, colorb)
8010{
8011	var result = "";
8012
8013	var vendor = nxs_js_getvendorprefix();
8014
8015	result += "background-color: " + colora + ";";
8016	if (vendor == "o" || vendor == "?")
8017	{
8018		result += "background: -o-linear-gradient(" + colorb + ", " + colora + ");";
8019	}
8020	else if (vendor == "mozilla" || vendor == "?")
8021	{
8022		result += "background: -moz-linear-gradient(" + colorb + ", " + colora + ");";
8023	}
8024	else if (vendor == "webkit" || vendor == "?")
8025	{
8026		result += "background: -webkit-gradient(linear, 0% 0%, 0% 100%, from(" + colorb + "), to(" + colora + "));";
8027	}
8028	else if (vendor == "msie" || vendor == "?")
8029	{
8030		result += "background: -ms-linear-gradient(top, " + colorb + " 0%," + colora + " 100%);";
8031		result += "background: linear-gradient(to bottom, " + colorb + " 0%," + colora + " 100%);";
8032		result += "filter: progid:DXImageTransform.Microsoft.Gradient(GradientType=0,StartColorStr=" + colorb + ",EndColorStr=" + colora + ");";
8033	}
8034	return result;
8035}
8036
8037// kudos to http://stackoverflow.com/questions/11333150/twitter-bootstrap-how-to-remove-gradient-mixin-in-subclass
8038function nxs_js_getflatbackgroundnogradientcss(hexcolor, alphafactor)
8039{
8040	var result = "";
8041
8042	// NOTE the background-image: none is repeated intentionally, see link above function declaration
8043
8044	var vendor = nxs_js_getvendorprefix();
8045
8046	if (alphafactor == 1)
8047	{
8048		result += "background-color: " + hexcolor + ";";
8049	}
8050	else if (alphafactor < 1)
8051	{
8052		// convert hex value to rgb
8053		var hexcolor = nxs_js_hextorgb(hexcolor);
8054		result += "background: rgb(" + hexcolor.r + ", " + hexcolor.g + ", " + hexcolor.b + "); /* The Fallback */ ";
8055		result += "background: rgba(" + hexcolor.r + ", " + hexcolor.g + ", " + hexcolor.b + ", " + alphafactor + ");";
8056
8057		//nxs_js_log("hexcolor:" + hexcolor + "; alpha:" + alphafactor);
8058		//nxs_js_log("output:" + result);
8059	}
8060
8061	result += "background-repeat: no-repeat;";
8062
8063	if (vendor == "o" || vendor == "?")
8064	{
8065		result += "background-image: none;";
8066	}
8067	else if (vendor == "mozilla" || vendor == "?")
8068	{
8069		result += "background-image: none;";
8070	}
8071	else if (vendor == "webkit" || vendor == "?")
8072	{
8073		result += "background-image: none;";
8074		result += "background-image: none;";
8075	}
8076	else if (vendor == "msie" || vendor == "?")
8077	{
8078		result += "filter: none;";
8079	}
8080
8081	// debug
8082	// result = "background-color: red !important;";
8083
8084	return result;
8085}
8086
8087// helper function to get the css output for a lineair gradient between the 2 specified colors
8088function nxs_js_getflatcss(colora, alphafactor)
8089{
8090	return nxs_js_getflatbackgroundnogradientcss(colora, alphafactor);
8091}
8092
8093function nxs_js_updatecss_manualcss_actualrequest()
8094{
8095	// ------------------- UPDATE CSS
8096
8097	// get active colorscheme
8098	var colorschemelookup = nxs_js_getruntimecolorschemelookup();
8099
8100	//nxs_js_log("colorschemelookup:");
8101	//nxs_js_log(colorschemelookup);
8102
8103	var runtimeurllookup = nxs_js_getruntimecsslookup();
8104
8105	//nxs_js_log("runtimeurllookup:");
8106	//nxs_js_log(runtimeurllookup);
8107
8108	// blend all lookups
8109	var csslookup = jQuery.extend({}, colorschemelookup, runtimeurllookup);
8110
8111	//nxs_js_log("csslookup:");
8112	//nxs_js_log(csslookup);
8113
8114	var csstemplate = nxs_js_get_manualcsstemplate();
8115	var actualcss = nxs_js_blendtemplatewithvariables(csstemplate, csslookup);
8116
8117	// update the css
8118	nxs_js_setcss(actualcss, '#nxs-dynamiccss-manual-chunk-');
8119}
8120
8121function nxs_js_rerender_facebookbom()
8122{
8123	if (typeof(FB) != "undefined" && FB != null )
8124	{
8125		FB.XFBML.parse();
8126	}
8127	else
8128	{
8129		// first time / not yet loaded
8130	}
8131}
8132
8133// kudos to http://stackoverflow.com/questions/4825683/how-do-i-create-and-read-a-value-from-cookie
8134// todo: the path of the cookie should be set to the root folder of the site, this is required for multisites that use folder names
8135function nxs_js_setcookie(name, value)
8136{
8137	var expires = "";
8138  document.cookie = name + "=" + value + expires + "; path=/";
8139}
8140
8141function nxs_js_getcookie(c_name)
8142{
8143  if (document.cookie.length > 0)
8144  {
8145    c_start = document.cookie.indexOf(c_name + "=");
8146    if (c_start != -1)
8147    {
8148      c_start = c_start + c_name.length + 1;
8149      c_end = document.cookie.indexOf(";", c_start);
8150      if (c_end == -1) {
8151          c_end = document.cookie.length;
8152      }
8153      return unescape(document.cookie.substring(c_start, c_end));
8154    }
8155  }
8156  return "";
8157}
8158
8159function nxs_js_tagcolumns()
8160{
8161	jQuery.each
8162	(
8163		jQuery(".nxs-row"), function(index, rowelement)
8164		{
8165			// nxs_js_log('row found');
8166			var columnindex = 1;
8167
8168			var placeholders = jQuery(rowelement).find(".nxs-placeholder");
8169			var columnmax = placeholders.length;
8170			jQuery.each
8171			(
8172				placeholders, function(index, currentplaceholder)
8173				{
8174					jQuery(currentplaceholder).addClass("nxs-column-" + columnindex + "-" + columnmax);
8175					columnindex++;
8176				}
8177			);
8178		}
8179	);
8180}
8181
8182// kudos to https://gist.github.com/padolsey/527683
8183var nxs_js_ie=function(){for(var a=3,b=document.createElement("b"),c=b.all||[];b.innerHTML="<!--[if gt IE "+ ++a+"]><i><![endif]-->",c[0];);return 4<a?a:document.documentMode}();
8184function nxs_js_tagbrowsers()
8185{
8186	jQuery("html").addClass("nxs-vendor-" + nxs_js_getvendorprefix());
8187
8188	if (nxs_js_ie)
8189	{
8190		var ie = nxs_js_ie;
8191		jQuery("html").addClass("nxs-ie");
8192		var classname = "nxs-ie-" + ie;
8193		jQuery("html").addClass(classname);
8194
8195		var compatibleloop = 0;
8196		while (compatibleloop < 5)
8197		{
8198			var classname = "nxs-ie-lte-" + ie;
8199			jQuery("html").addClass(classname);
8200			compatibleloop++;
8201			ie++;
8202		}
8203	}
8204	else
8205	{
8206		jQuery("html").addClass("nxs-non-ie");
8207	}
8208}
8209
8210function nxs_js_deviceistouchdevice()
8211{
8212	var result = 'ontouchstart' in document.documentElement;
8213	return result;
8214}
8215
8216function nxs_js_tagresponsiveness()
8217{
8218	if (nxs_js_issiteresponsive())
8219	{
8220		jQuery("html").addClass("nxs-site-responsive");
8221	}
8222	else
8223	{
8224		jQuery("html").addClass("nxs-site-noneresponsive");
8225	}
8226}
8227
8228function nxs_js_tagfrontendbackend()
8229{
8230	if (nxs_js_isinfrontend())
8231	{
8232		jQuery("html").addClass("nxs-frontend");
8233	}
8234	else
8235	{
8236		jQuery("html").addClass("nxs-backend");
8237	}
8238}
8239
8240
8241function nxs_js_getviewports()
8242{
8243	var result =
8244	[
8245	320, 		// iphone portrait
8246	480, 		//
8247	720, 		//
8248	960, 		// ipad landscape / desktop
8249	1200, 	// desktop
8250	1440		// desktop
8251	];
8252	return result;
8253}
8254
8255function nxs_js_setupviewportlistener()
8256{
8257	jQuery(window).bind('nxs_event_resizeend', function() { nxs_js_setupviewportlistener_actual(); });
8258	// initial call is used to set things up
8259	nxs_js_setupviewportlistener_actual();
8260}
8261
8262function nxs_js_setupviewportlistener_actual()
8263{
8264	//nxs_js_log("nxs_js_setupviewportlistener_actual");
8265
8266	var previousactiveviewport = nxs_js_activeviewport;
8267	//nxs_js_log("previous:" + previousactiveviewport);
8268
8269	var currentactiveviewport = nxs_js_deriveactiveviewport();
8270	//nxs_js_log("currentactiveviewport:" + currentactiveviewport);
8271
8272	if (previousactiveviewport != currentactiveviewport)
8273	{
8274		// store new value
8275		nxs_js_activeviewport = currentactiveviewport;
8276
8277		if (previousactiveviewport != -1)
8278		{
8279			nxs_js_log('broadcasting nxs_event_viewportchanged');
8280			jQuery(this).trigger('nxs_event_viewportchanged');
8281		}
8282		else
8283		{
8284			// we don't trigger when the initial viewport is set (we consider that 'not changed')
8285		}
8286	}
8287}
8288
8289function nxs_js_deriveactiveviewport()
8290{
8291	var widthofbrowserwindow = jQuery(window).width();
8292	var viewports = nxs_js_getviewports();
8293	var biggest = 0;
8294	for (var i = 0; i < viewports.length; i++)
8295	{
8296		var currentviewport = viewports[i];
8297		if (currentviewport >= biggest)
8298		{
8299			if (widthofbrowserwindow >= currentviewport)
8300			{
8301				biggest = currentviewport;
8302			}
8303		}
8304	}
8305	return biggest;
8306}
8307
8308function nxs_js_tagviewports()
8309{
8310	var widthofbrowserwindow = jQuery(window).width();
8311
8312	var viewports = nxs_js_getviewports();
8313	for (var i = 0; i < viewports.length; i++)
8314	{
8315		var currentviewport = viewports[i];
8316
8317		// greater than classes
8318		var compareto = currentviewport - 1;
8319		if (widthofbrowserwindow >= compareto)
8320		{
8321			var classnaam = "nxs-viewport-gt-" + compareto;
8322			jQuery("html").addClass(classnaam);
8323		}
8324		else
8325		{
8326			jQuery("html").removeClass("nxs-viewport-gt-" + compareto);
8327		}
8328
8329		// less than or equal classes
8330		var compareto = currentviewport - 1;
8331		if (widthofbrowserwindow <= compareto)
8332		{
8333			var classnaam = "nxs-viewport-lte-" + compareto;
8334			jQuery("html").addClass(classnaam);
8335		}
8336		else
8337		{
8338			jQuery("html").removeClass("nxs-viewport-lte-" + compareto);
8339		}
8340
8341		// active viewport
8342		var compareto = currentviewport;
8343		jQuery("html").removeClass("nxs-viewport-is-" + compareto);
8344		// the adding of the active class happens below
8345	}
8346
8347	// equal classes
8348	jQuery("html").addClass("nxs-viewport-is-" + nxs_js_deriveactiveviewport());
8349
8350
8351}
8352
8353function nxs_js_tagdevices()
8354{
8355	var deviceistouchdevice = nxs_js_deviceistouchdevice()
8356	if (deviceistouchdevice)
8357	{
8358		jQuery("html").addClass("nxs-touchdevice");
8359	}
8360	else
8361	{
8362		jQuery("html").addClass("nxs-nontouchdevice");
8363	}
8364}
8365
8366function nxs_js_menuitemclick(domelement, event)
8367{
8368	if (event == "mouseleave")
8369	{
8370		jQuery(domelement).closest(".nxs-widget").find("li.nxs-touched").removeClass("nxs-touched");
8371		//nxs_js_log("mouseleave");
8372		return;
8373	}
8374
8375	var closestwidget = jQuery(domelement).closest(".nxs-widget");
8376
8377	if (event == "touch")
8378	{
8379		if (jQuery(domelement).closest("li").hasClass("nxs-touched"))
8380		{
8381			// if item it touched for the 2nd time, hide all touched items
8382			jQuery(closestwidget).find(".nxs-touched").removeClass("nxs-touched");
8383			return;
8384		}
8385	}
8386
8387	if (event == "mouseenter" || event == "touch" || event == "click")
8388	{
8389		// wipe previous path
8390		jQuery(closestwidget).find(".nxs-touched").removeClass("nxs-touched");
8391		// mark new path
8392		jQuery(domelement).parentsUntil(".nxs-widget").addClass("nxs-touched");
8393	}
8394
8395	// if user click on a domelement in the menu,
8396	// we shouldn't redirect immediately,
8397	// if the item has child items and the device is a touch device,
8398	// and the sub menu is not yet showing, absorb the click
8399
8400	if (event == 'touch' || event == 'click')
8401	{
8402		if (nxs_js_deviceistouchdevice())
8403		{
8404			// the submenu is not an immediate child of the 'this' link,
8405			// its a child of a sibling element ...
8406			if (jQuery(domelement).parent().children(".nxs-sub-menu").length > 0)
8407			{
8408				// nxs_js_log('NOT about to follow that link!');
8409			}
8410			else
8411			{
8412				var url = jQuery(domelement).attr("nxsurl");
8413				if ((url == null || url == ""))
8414				{
8415					// empty element; no url, nothing to do
8416				}
8417				else
8418				{
8419					nxs_js_redirect(url);
8420				}
8421			}
8422		}
8423		else
8424		{
8425			var url = jQuery(domelement).attr("nxsurl");
8426			if ((url == null || url == ""))
8427			{
8428				// nothing to do
8429			}
8430			else
8431			{
8432				// regular redirect
8433				nxs_js_redirect(url);
8434			}
8435		}
8436	}
8437}
8438
8439function nxs_js_doesuserimpactstyle()
8440{
8441	var result = false;
8442	// nxs_js_doesuserimpactstyle() comes from /wp-content/themes/core-redesignsportlinkclubsites/nexusframework/stable/nexuscore/includes/frontendediting.php
8443	// check if user has admin rights
8444	if (nxs_js_userhasadminpermissions())
8445	{
8446		// nxs_js_inwpbackend comes from /wp-content/themes/core-redesignsportlinkclubsites/nexusframework/stable/nexuscore/includes/frontendediting.php
8447		// check if user is not admin
8448		if (!nxs_js_inwpbackend())
8449		{
8450			// if menu shows... (color pickers, etc.)
8451			if (jQuery("#nxs-admin-tabs").length > 0)
8452			{
8453				result = true;
8454			}
8455		}
8456	}
8457
8458	return result;
8459}
8460
8461// returns the color scheme lookup, according to the runtime environment; if the
8462// browser is in readonly mode, this means the lookup is used as defined on the serverside,
8463// otherwise the values from the flyout menu are used
8464function nxs_js_getruntimecolorschemelookup()
8465{
8466	var corecsslookup;
8467	// nxs_js_doesuserimpactstyle comes from this file
8468	// check is user has admin rights but is not admin
8469	if (nxs_js_doesuserimpactstyle())
8470	{
8471		// dynamic lookup
8472		// nxs_js_getcsslookupflyoutmenu() comes from this file
8473		corecsslookup = nxs_js_getcsslookupflyoutmenu();
8474	}
8475	else
8476	{
8477		// static lookup
8478		corecsslookup = nxs_js_getcolorschemeaccordingtoserverside();
8479	}
8480
8481	//
8482	//
8483	//
8484
8485	var derivedcsslookup = nxs_js_getderivedcsslookup(corecsslookup);
8486
8487	var result = jQuery.extend({}, corecsslookup, derivedcsslookup);
8488
8489	return result;
8490}
8491
8492// converts 1.0 into 1-0
8493function nxs_js_getdashedtextrepresentation_for_numericvalue(currentvalue)
8494{
8495	var wholepart = Math.floor(currentvalue);
8496	var fractionpart = nxs_js_getfractionasstring(currentvalue);
8497	var result = wholepart + '-' + fractionpart;
8498	return result;
8499}
8500
8501// gets derived css lookup variables based on existing lookup
8502function nxs_js_getderivedcsslookup(corecsslookup)
8503{
8504	// corecsslookup provides 2 shades of each color:
8505	/*
8506	** color_base1_m: "#C6C6C6"
8507	** color_base2_m: "#333333"
8508	** color_c11_m: "#C6C6C6"
8509	** color_c12_m: "#FFE533"
8510	** color_c21_m: "#C6C6C6"
8511	** color_c22_m: "#FFFFFF"
8512	** color_c31_m: "#C6C6C6"
8513	** color_c32_m: "#050505"
8514	*/
8515
8516	var result = {}
8517	// nxs_js_getcolorsinpalette() comes from /wp-content/themes/core-redesignsportlinkclubsites/nexusframework/stable/nexuscore/includes/frontendediting.php
8518	var colors = nxs_js_getcolorsinpalette(); // [base, c1, c2, c3]
8519	// nxs_js_getcoloralphas() comes from /wp-content/themes/core-redesignsportlinkclubsites/nexusframework/stable/nexuscore/includes/frontendediting.php
8520	var coloralphas = nxs_js_getcoloralphas(); // [1, 0.8, 0.7, 0.6, 0.5, 0]
8521
8522	// for each color [base, c1, c2, c3] the different shades and grandients are applied
8523	for(i=0;i<colors.length;i++)
8524	{
8525		var currentcolor = colors[i];
8526
8527		for(subtypei=1;subtypei<=2; subtypei++)
8528		{
8529			var identity = currentcolor + subtypei;
8530			var hexcolor = corecsslookup['color_' + currentcolor + subtypei + '_m'];
8531
8532			if (hexcolor != "" && hexcolor != null)
8533			{
8534				//nxs_js_log('hexcolor is set for ' + currentcolor + ':' + hexcolor);
8535				//nxs_js_log(hexcolor);
8536
8537				var rgb = nxs_js_hextorgb(hexcolor);
8538				//nxs_js_log(rgb);
8539
8540				var lightDelta = 0.2;
8541
8542				result['color_' + identity + '_dd'] = nxs_js_gethextransformedrgblight(rgb, -lightDelta-lightDelta);	// 2x darker
8543				result['color_' + identity + '_d'] = nxs_js_gethextransformedrgblight(rgb, -lightDelta);								// 1x darker
8544				result['color_' + identity + '_l'] = nxs_js_gethextransformedrgblight(rgb, +lightDelta);
8545				result['color_' + identity + '_ll'] = nxs_js_gethextransformedrgblight(rgb, +lightDelta+lightDelta);	// 2x lighter
8546
8547				var nxsd = result['color_' + identity + '_d'];
8548				var nxsm = hexcolor;
8549				var nxsl = result['color_' + identity + '_l'];
8550
8551				result['gradient_' + identity + '_dm'] = nxs_js_getlineairgradientcss(nxsd, nxsm);
8552				result['gradient_' + identity + '_ml'] = nxs_js_getlineairgradientcss(nxsm, nxsl);
8553
8554				// flat colors have to take into consideration the alpha's (100%, 80%, 60%, etc.)
8555				for (var ca_i in coloralphas)
8556				{
8557					var currentcoloralpha = coloralphas[ca_i];
8558					var alphasuffix;
8559
8560					if (currentcoloralpha < 1)
8561					{
8562						alphasuffix = '-a' + nxs_js_getdashedtextrepresentation_for_numericvalue(currentcoloralpha);
8563					}
8564					else if (currentcoloralpha == 1)
8565					{
8566						// not applicable
8567						alphasuffix = '';
8568					}
8569					else
8570					{
8571						nxs_js_log("unsupported currentcoloralpha;" + currentcoloralpha);
8572					}
8573
8574					result['flat_' + identity + alphasuffix] = nxs_js_getflatcss(nxsm, currentcoloralpha);
8575				}
8576			}
8577			else
8578			{
8579				nxs_js_log('hexcolor is not set for ' + currentcolor);
8580			}
8581		}
8582	}
8583
8584	return result;
8585}
8586
8587// return the color scheme lookup, according to the color pickers in the flyout menu
8588function nxs_js_getcsslookupflyoutmenu()
8589{
8590	// inject current colorscheme
8591	var colorschemelookup = {};
8592
8593	var colortypes = nxs_js_getcolorsinpalette();
8594
8595	var subtypes = ['1','2'];
8596
8597	for (var i in colortypes)
8598	{
8599		var currentcolortype = colortypes[i];
8600		// for example 'primary' color, or 'secundary'
8601
8602		for (var sti in subtypes)
8603		{
8604			var currentsubtype = subtypes[sti];
8605			var identification = currentcolortype + currentsubtype;
8606			colorschemelookup['color_' + identification + '_m'] = jQuery('#vg_color_' + identification + '_m').val();
8607		}
8608	};
8609
8610	return colorschemelookup;
8611}
8612
8613function nxs_js_getfractionasstring(n)
8614{
8615	var result;
8616  if (n != 0)
8617  {
8618    var fractionpart = n.toString();
8619
8620    fractionpart = fractionpart.split('.');
8621    if (fractionpart.length == 2)
8622    {
8623    	fractionpart = fractionpart[1];
8624    	result = fractionpart.toString();
8625    }
8626    else
8627    {
8628    	result = "0";
8629    }
8630    //
8631  }
8632  else
8633  {
8634  	result = "0";
8635  }
8636
8637  return result;
8638}
8639
8640function nxs_js_debug_cssoutput(msg, css)
8641{
8642	nxs_js_log("--------------------------");
8643	nxs_js_log("DEBUG CSS FOR:" + msg);
8644
8645	css= nxs_js_replacemultiplespaceswithsinglespace(css);
8646	css = nxs_js_removetabs(css);
8647
8648	var countmsg = nxs_js_getcssselectorcount(css);
8649	nxs_js_alert("selectors used:" + countmsg);
8650
8651	nxs_js_log("css:");
8652	nxs_js_log(css);
8653}
8654
8655function nxs_js_createcssstyling_fontsizeheading(headingelement, multiplier, fontscale, factor_textfontsize)
8656{
8657	// step 1: ensure multiplier exists in available fontsizes
8658	var availablefontsizes = nxs_js_getstyletypevalues("fontsize");
8659	if (jQuery.inArray(multiplier, availablefontsizes) < 0)
8660	{
8661		nxs_js_alert('warning, unsupported multiplier;' + multiplier);
8662		nxs_js_log('multiplier:');
8663		nxs_js_log(multiplier);
8664		nxs_js_log('availablefontsizes:');
8665		nxs_js_log(availablefontsizes);
8666		return;
8667	}
8668
8669	// step 2: build css
8670
8671	var u = '';
8672	u += nxs_js_createcssstyling(
8673  {
8674      multipliers: [multiplier],
8675      cssparameters:
8676      [
8677      	{
8678        	scale: fontscale,
8679        	factor: factor_textfontsize,
8680        	// remove #nxs-container selector from framework.css
8681          csstemplate: ' \
8682          	' + headingelement + ', \
8683          	#nxs-container #nxs-content-container ' + headingelement + ' span \
8684          	{ \
8685          		font-size: $nxs_formularesult;px;\
8686          		line-height: 1.2em;\
8687          	} \
8688          	'
8689        },
8690      ]
8691    }
8692  );
8693  return u;
8694}
8695
8696function nxs_js_createcssstyling(options)
8697{
8698  var result = '';
8699  var multipliers = options.multipliers;
8700  var cssparameters =  options.cssparameters;
8701
8702  for (var i in multipliers)
8703  {
8704    var currentmultiplier = multipliers[i];
8705
8706    var wholepart = Math.floor(currentmultiplier);
8707
8708    // we need to return integers, not fractions to be able to concatenate with the class name
8709    var fractionpart = nxs_js_getfractionasstring(currentmultiplier);
8710
8711    for (var j in cssparameters )
8712    {
8713    	var currentcssparameter = cssparameters[j];
8714
8715    	var identification = wholepart + '-' + fractionpart;
8716    	var csstemplate = currentcssparameter.csstemplate;
8717    	var csstemplate = nxs_js_removelinebreaks(csstemplate);
8718    	var csstemplate = nxs_js_removetabs(csstemplate);
8719    	var csstemplate = nxs_js_replacemultiplespaceswithsinglespace(csstemplate);
8720
8721 	    var factor = currentcssparameter.factor;
8722			if (factor == null)
8723			{
8724				//
8725				factor = options.factor;
8726			}
8727
8728			var resultoffset = currentcssparameter.resultoffset;
8729			if (resultoffset == null)
8730			{
8731				resultoffset = options.resultoffset;
8732				if (resultoffset == null)
8733				{
8734					resultoffset = 0;
8735				}
8736			}
8737
8738			var scale = currentcssparameter.scale;
8739			if (scale == null)
8740			{
8741				scale = options.scale;
8742				if (scale == null)
8743				{
8744					scale = 1;
8745				}
8746			}
8747
8748      if (csstemplate != null)
8749      {
8750      	// apply template
8751      	var lookup = {
8752      		"formularesult;": Math.round((currentmultiplier * factor * scale) + resultoffset), 	// will replace variable $nxs_formularesult;
8753      		"identification;": identification // will replace variable $nxs_identification;
8754      	};
8755
8756      	// apply template
8757      	result = result + nxs_js_blendtemplatewithvariables(csstemplate, lookup);
8758      }
8759			else
8760			{
8761				nxs_js_alert("no css template found");
8762				nxs_js_log(options);
8763      }
8764    }
8765  }
8766	//nxs_js_log(result);
8767	return result;
8768}
8769
8770function nxs_js_get_themecsstemplate_part1_colorzen(cssprefix, csspostfix, zenprefix, csslookup, csspostfixanchors)
8771{
8772	if (csspostfixanchors == null)
8773	{
8774		csspostfixanchors = csspostfix;
8775	}
8776
8777	var u = "";
8778	var coloralphas = nxs_js_getcoloralphas();
8779	var colortypes = nxs_js_getcolorsinpalette();
8780
8781	for (var i in colortypes)
8782	{
8783		var currentcolortype = colortypes[i];
8784
8785		// currentcolortype is for example 'c1', or 'base1'
8786		var identification = currentcolortype;
8787		if (zenprefix == null || zenprefix == "")
8788		{
8789			zenprefix = "nxs-colorzen-";
8790		}
8791		var cssinnerprefix = zenprefix + currentcolortype;
8792
8793		var comparecolorhex = csslookup["color_" + identification + "2_m"];
8794		var comparecolorrgb = nxs_js_hextorgb(comparecolorhex);
8795		var comparecolorhsl = nxs_js_rgbtohsl(comparecolorrgb);
8796		var lighttreshhold = 0.7;
8797		var isbackgroundcolorrelativelydark = comparecolorhsl.l < lighttreshhold;
8798
8799		// COLOR IQ :)
8800		// GRADIENTS --------------
8801
8802		if (currentcolortype == "base")
8803		{
8804			/* BACKGROUND COLOR AND TEXT & TITLES (OPPOSITE OF BACKGROUND) */
8805			u = u + cssprefix + "." + cssinnerprefix + "1-ml " + csspostfix + " \
8806			{ \
8807				border-color: " + csslookup["color_" + identification + "1_d"] + ";\
8808				color: " + csslookup["color_" + identification + "2_d"] + ";\
8809				text-shadow: 1px 1px 1px " + csslookup["color_" + identification + "1_ll"] + ";\
8810				" + csslookup["gradient_" + identification + "1_ml"] + "\
8811			}";
8812
8813			u = u + cssprefix + "." + cssinnerprefix + "1-dm " + csspostfix + "\
8814			{\
8815				border-color: " + csslookup["color_" + identification + "1_dd"] + ";\
8816				color: " + csslookup["color_" + identification + "2_dd"] + ";\
8817				text-shadow: 1px 1px 1px " + csslookup["color_" + identification + "1_ll"] + ";\
8818				" + csslookup["gradient_" + identification + "1_dm"] + "\
8819			}";
8820		}
8821		else
8822		{
8823			// skip colorzen for the "1" variations for others than "base"; only base1 is used
8824		}
8825
8826		if (isbackgroundcolorrelativelydark)
8827		{
8828			var textcolor = csslookup["color_" + identification + "1_ll"];
8829			var textshadowcolor = csslookup["color_" + identification + "2_dd"];
8830		}
8831		else
8832		{
8833			var textcolor = "black";
8834			var textshadowcolor = "white";
8835		}
8836
8837		u = u + cssprefix + "." + cssinnerprefix + "2-ml " + csspostfix + "\
8838		{\
8839			border-color: " + csslookup["color_" + identification + "2_d"] + ";\
8840			" + csslookup["gradient_" + identification + "2_ml"] + "\
8841			color: " + textcolor + ";\
8842			text-shadow: 1px 1px 1px " + textshadowcolor + ";\
8843		}";
8844
8845		if (isbackgroundcolorrelativelydark)
8846		{
8847			var textcolor = csslookup["color_" + identification + "1_l"];
8848			var textshadowcolor = csslookup["color_" + identification + "2_dd"];
8849		}
8850		else
8851		{
8852			var textcolor = "black";
8853			var textshadowcolor = "white";
8854		}
8855
8856		u = u + cssprefix + "." + cssinnerprefix + "2-dm " + csspostfix + "\
8857		{\
8858			border-color: " + csslookup["color_" + identification + "2_dd"] + ";\
8859			" + csslookup["gradient_" + identification + "2_dm"] + "\
8860			color: " + textcolor +";\
8861			text-shadow: 1px 1px 1px " + textshadowcolor + ";\
8862		}";
8863
8864
8865
8866		/* ANCHORS */
8867
8868		if (currentcolortype == "base")
8869		{
8870			u = u + cssprefix + "." + cssinnerprefix + "1-ml " + csspostfixanchors + " a { color: " + csslookup["color_" + identification + "2_d"] + "; text-shadow: 1px 1px 1px " + csslookup["color_" + identification + "1_ll"] + "; }";
8871			u = u + cssprefix + "." + cssinnerprefix + "1-dm " + csspostfixanchors + " a { color: " + csslookup["color_" + identification + "2_dd"] + "; text-shadow: 1px 1px 1px " + csslookup["color_" + identification + "1_ll"] + "; }";
8872		}
8873		else
8874		{
8875			// skip colorzen for the "1" variations for others than "base"; only base1 is used
8876		}
8877
8878		if (isbackgroundcolorrelativelydark)
8879		{
8880			var textcolor = csslookup["color_" + identification + "1_ll"];
8881			var textshadowcolor = csslookup["color_" + identification + "2_dd"];
8882		}
8883		else
8884		{
8885			var textcolor = "black";
8886			var textshadowcolor = "white";
8887		}
8888
8889		u = u + cssprefix + "." + cssinnerprefix + "2-ml " + csspostfixanchors + " a\
8890		{\
8891			color: " + textcolor + ";\
8892			text-shadow: 1px 1px 1px " + textshadowcolor + ";\
8893		}";
8894
8895		if (isbackgroundcolorrelativelydark)
8896		{
8897			var textcolor = csslookup["color_" + identification + "1_l"];
8898			var textshadowcolor = csslookup["color_" + identification + "2_dd"];
8899		}
8900		else
8901		{
8902			var textcolor = "black";
8903			var textshadowcolor = "white";
8904		}
8905
8906		u = u + cssprefix + "." + cssinnerprefix + "2-dm " + csspostfixanchors + " a\
8907		{\
8908			color: " + textcolor + ";\
8909			text-shadow: 1px 1px 1px " + textshadowcolor + ";\
8910		}";
8911
8912
8913
8914		// FLAT --------------
8915
8916		/* TEXT & TITLES (OPPOSITE OF BACKGROUND) */
8917
8918		// ------------
8919		// colorzen for flat colors
8920
8921		var coloralphas = nxs_js_getcoloralphas();
8922		for (var i in coloralphas)
8923		{
8924			var currentcoloralpha = coloralphas[i];
8925			var alphasuffix;
8926
8927			if (currentcoloralpha < 1)
8928			{
8929				alphasuffix = '-a' + nxs_js_getdashedtextrepresentation_for_numericvalue(currentcoloralpha);
8930			}
8931			else if (currentcoloralpha == 1)
8932			{
8933				// not applicable
8934				alphasuffix = '';
8935			}
8936			else
8937			{
8938				nxs_js_log("unsupported currentcoloralpha;" + currentcoloralpha);
8939			}
8940
8941			// overruled: background and border are 100% black
8942			u = u + cssprefix + "." + cssinnerprefix + "1" + alphasuffix + " " + csspostfix + "\
8943			{\
8944				" + nxs_js_getflatbackgroundnogradientcss('#FFFFFF', currentcoloralpha) + ";\
8945				border-color:  #C6C6C6;\
8946				color: " + csslookup["color_" + identification + "2_d"] + ";\
8947				text-shadow: 1px 1px 1px " + csslookup["color_" + identification + "1_ll"] + ";\
8948			}";
8949
8950			// regular color
8951			u = u + cssprefix + "." + cssinnerprefix + "2" + alphasuffix + " " + csspostfix + "\
8952			{";
8953
8954				if (currentcolortype == "base")
8955				{
8956					// overruled: background and border are 100% black
8957					u = u + "\
8958						border-color: #000000;\
8959						" + nxs_js_getflatbackgroundnogradientcss('#000000', currentcoloralpha) + ";\
8960					";
8961				}
8962				else
8963				{
8964					u = u + "\
8965						border-color: " + csslookup["color_" + identification + "2_d"] + ";\
8966						" + csslookup["flat_" + identification + "2" + alphasuffix] + "\
8967					";
8968					//nxs_js_log("key:");
8969					//nxs_js_log("flat_" + identification + "2-a0-8");
8970				}
8971
8972				if (isbackgroundcolorrelativelydark)
8973				{
8974					var textcolor = csslookup["color_" + identification + "1_ll"];
8975					var textshadowcolor = csslookup["color_" + identification + "2_dd"];
8976				}
8977				else
8978				{
8979					var textcolor = "black";
8980					var textshadowcolor = "white";
8981				}
8982
8983				u = u + "\
8984					color: " + textcolor + ";\
8985					text-shadow: 1px 1px 1px " + textshadowcolor + ";\
8986					";
8987
8988			u = u + "}";
8989		}
8990
8991		/* ANCHORS FLAT COLOR */
8992
8993		u = u + cssprefix + "." + cssinnerprefix + "1 " + csspostfixanchors + " a\
8994		{\
8995			color: " + csslookup["color_" + identification + "2_dd"] + ";\
8996			text-shadow: 1px 1px 1px " + csslookup["color_" + identification + "1_ll"] + ";\
8997		}";
8998
8999		if (isbackgroundcolorrelativelydark)
9000		{
9001			var textcolor = csslookup["color_" + identification + "1_l"];
9002			var textshadowcolor = csslookup["color_" + identification + "2_dd"];
9003		}
9004		else
9005		{
9006			var textcolor = "black";
9007			var textshadowcolor = "white";
9008		}
9009
9010		u = u + cssprefix + "." + cssinnerprefix + "2 " + csspostfixanchors + " a\
9011		{\
9012			color: " + textcolor + ";\
9013			text-shadow: 1px 1px 1px " + textshadowcolor + ";\
9014		}";
9015	}
9016
9017	//nxs_js_log("-");
9018	//nxs_js_log("colorzen output:" + csspostfixanchors);
9019	//nxs_js_log(u);
9020
9021	return u;
9022}
9023
9024function nxs_js_get_themecsstemplate_part1_anchorlinkcolors(cssprefix, pseudo, csslookup)
9025{
9026	var u = "";
9027
9028	u += "/* output of nxs_js_get_themecsstemplate_part1_anchorlinkcolors */";
9029
9030	var colortypes = nxs_js_getcolorsinpalette();
9031
9032	for (var i in colortypes)
9033	{
9034		var currentcolortype = colortypes[i];
9035		var identification = currentcolortype;
9036
9037		/* EXPLICIT ANCHOR COLORS */
9038
9039		var variations = ["dd", "d", "m", "l", "ll"];
9040		for (var i in variations)
9041	  {
9042	    var currentvariation = variations[i];
9043
9044	    var selector = "nxs-linkcolorvar-" + currentcolortype + "2-" + currentvariation;
9045	    var colorvar = csslookup["color_" + identification + "2_" + currentvariation];
9046
9047	    // todo: isolate text-shadow: none in seperate css selector?
9048
9049			u = u + "\
9050				" + cssprefix + "." + selector + " .nxs-applylinkvarcolor a" + pseudo + "\
9051				{ \
9052					color: " + colorvar + ";\
9053					text-shadow: none;\
9054				}	\
9055				";
9056		}
9057	}
9058
9059	return u;
9060}
9061
9062function nxs_js_get_nxsrefurlspecial()
9063{
9064	var url = nxs_js_geturlcurrentpage();
9065	var base64encodedurl = nxs_js_base64_encode(url);
9066	var result = nxs_js_urldecode(base64encodedurl);
9067	return result;
9068}
9069
9070function nxs_js_cssremovecomments(haystack)
9071{
9072	// *? = ungreedy
9073	// assumes single line css!
9074	return haystack.replace(/ *\/\*[^)]*?\*\/ */g, "");
9075}
9076
9077function nxs_js_getcssselectorcount(haystack)
9078{
9079	if (nxs_js_stringcontains(nxs_js_cssremovecomments(haystack), "@media"))
9080	{
9081		nxs_js_alert("It looks like media queries are used; these aren't supported in the css splitter (1)");
9082	}
9083
9084	var result = 0;
9085
9086  var splitted = haystack.split("}");
9087
9088  var count = splitted.length;
9089  for (var i = 0; i < count; i++)
9090  {
9091  	var cssdeclaration = splitted[i];
9092
9093  	// splits selectors / assignment
9094  	var splitted2 = cssdeclaration.split("{");
9095
9096  	var selectors = splitted2[0];
9097  	selectors = nxs_js_cssremovecomments(selectors);
9098
9099  	var splitted3 = selectors.split(",");
9100  	result += splitted3.length;
9101  }
9102
9103  return result;
9104}
9105
9106function nxs_js_getchunksofcss(haystack)
9107{
9108	// precondition
9109	if (nxs_js_stringcontains(nxs_js_cssremovecomments(haystack), "@media"))
9110	{
9111		nxs_js_alert("It looks like media queries are used; these aren't supported in the css splitter (2)");
9112		nxs_js_log(haystack);
9113	}
9114
9115	// initialization
9116	var maxchunksize = 4095;	// max # of css selectors allowed per chunk
9117	var result = {};
9118	var declarationsincurrentchunk = 0;
9119	result.chunks = {};
9120	for (var i = 0; i < nxs_js_getmaxservercsschunks(); i++)
9121	{
9122		result.chunks[currentchunk] = "";	// initial output
9123	}
9124
9125	var splitted = haystack.split("}");
9126
9127	var currentchunk = 0;
9128  var count = splitted.length;
9129  for (var i = 0; i < count; i++)
9130  {
9131  	var cssdeclaration = splitted[i];
9132
9133  	// splits selectors / assignment
9134  	var splitted2 = cssdeclaration.split("{");
9135
9136  	var selectors = splitted2[0];
9137  	selectors = nxs_js_cssremovecomments(selectors);
9138
9139  	var splitted3 = selectors.split(",");
9140  	var numofdeclarations = splitted3.length;
9141  	if (declarationsincurrentchunk + numofdeclarations > maxchunksize)
9142  	{
9143  		// we need a new chunk
9144  		currentchunk++;
9145  		if (currentchunk >= nxs_js_getmaxservercsschunks())
9146  		{
9147  			nxs_js_alert('Please add additional css chunks; see nxsstyles.php');
9148  		}
9149  		result.chunks[currentchunk] = "";
9150  		declarationsincurrentchunk = 0;
9151  	}
9152
9153	 	// store in current chunk and continue
9154	 	result.chunks[currentchunk] += (cssdeclaration + "}");
9155	 	// increase counter of current chunk
9156	 	declarationsincurrentchunk += numofdeclarations;
9157  }
9158
9159  return result;
9160}
9161
9162// returns the css generated by the framework,
9163// consists of all scaffolding classes like colors, widths, etc.
9164// it takes into consideration configured items like number of colors
9165function nxs_js_get_frameworkcsstemplate(csslookup)
9166{
9167	var u = "";
9168	u += "/* start Nexus framework css template */";
9169
9170	var colortypes = nxs_js_getcolorsinpalette();
9171
9172	u = u + ".nxs-colorzen { border-style: solid; }";
9173	u = u + "#nxs-menu-wrap { text-shadow: none; }";
9174
9175	//
9176	// CONTAINER COLORZEN per element, no inheritance
9177	//
9178	// colorzen's are defined on element level. The text and link colors are inherited
9179	// like body -> page -> container -> row -> placeholder
9180
9181	u = u + nxs_js_get_themecsstemplate_part1_colorzen("", "", "nxs-colorzen-", csslookup, "");
9182	u = u + nxs_js_get_themecsstemplate_part1_colorzen(".nxs-colorzen ", "", "nxs-colorzen-", csslookup, "");
9183	u = u + nxs_js_get_themecsstemplate_part1_colorzen(".nxs-colorzen .nxs-colorzen ", "", "nxs-colorzen-", csslookup, "");
9184	u = u + nxs_js_get_themecsstemplate_part1_colorzen(".nxs-colorzen .nxs-colorzen .nxs-colorzen ", "", "nxs-colorzen-", csslookup, "");
9185	u = u + nxs_js_get_themecsstemplate_part1_colorzen(".nxs-colorzen .nxs-colorzen .nxs-colorzen .nxs-colorzen ", "", "nxs-colorzen-", csslookup, "");
9186
9187	//
9188	//
9189	//
9190
9191	//
9192	// MENU COLORZEN ==============================
9193
9194	// main items -----------
9195
9196	// colorzen for menu items
9197	u = u + nxs_js_get_themecsstemplate_part1_colorzen(".nxs-applymenucolors", " > li.nxs-inactive", "nxs-colorzen-menuitem-", csslookup, " > li > ");
9198
9199	// colorzen for (top level) active menu items
9200	u = u + nxs_js_get_themecsstemplate_part1_colorzen(".nxs-applymenucolors", " > li.nxs-active", "nxs-colorzen-menuitem-active-", csslookup, " > li.nxs-active > ");
9201
9202	// colorzen for (top level) hover menu items
9203	u = u + nxs_js_get_themecsstemplate_part1_colorzen(".nxs-applymenucolors", " > li:hover", "nxs-colorzen-menuitem-hover-", csslookup, " > li:hover > ");
9204
9205	// colorzen for (top level) hover menu items
9206	u = u + nxs_js_get_themecsstemplate_part1_colorzen(".nxs-applymenucolors", " > li.nxs-active:hover", "nxs-colorzen-menuitem-active-", csslookup, " > li.nxs-active:hover > ");
9207
9208	// sub items -----------
9209
9210	// colorzen for submenu items
9211	u = u + nxs_js_get_themecsstemplate_part1_colorzen(".nxs-sub-menu", "", "nxs-colorzen-menuitem-sub-", csslookup, " > li > ");
9212
9213	// colorzen for (top level) active menu items
9214	u = u + nxs_js_get_themecsstemplate_part1_colorzen(".nxs-sub-menu", " > li.nxs-active", "nxs-colorzen-menuitem-sub-active-", csslookup, "> li.nxs-active > ");
9215
9216	// colorzen for (top level) hover menu items
9217	u = u + nxs_js_get_themecsstemplate_part1_colorzen(".nxs-sub-menu", " > li:hover", "nxs-colorzen-menuitem-sub-hover-", csslookup, " > li:hover > ");
9218
9219	// colorzen for (top level) hover menu items
9220	u = u + nxs_js_get_themecsstemplate_part1_colorzen(".nxs-sub-menu", " > li.nxs-active:hover", "nxs-colorzen-menuitem-sub-active-", csslookup, " > li.nxs-active:hover > ");
9221
9222  //
9223	// ANCHOR LINKS nested inherited (!)
9224	//
9225	// anchor link colors are inherited,
9226	// like body -> page -> container -> row -> placeholder
9227	// anchor links are stronger than (generic) colorzen's
9228
9229	u = u + nxs_js_get_themecsstemplate_part1_anchorlinkcolors("","" , csslookup);
9230	u = u + nxs_js_get_themecsstemplate_part1_anchorlinkcolors(".nxs-linkcolorvar ","", csslookup);
9231	u = u + nxs_js_get_themecsstemplate_part1_anchorlinkcolors(".nxs-linkcolorvar .nxs-linkcolorvar ","", csslookup);
9232	u = u + nxs_js_get_themecsstemplate_part1_anchorlinkcolors(".nxs-linkcolorvar .nxs-linkcolorvar .nxs-linkcolorvar ","", csslookup);
9233	u = u + nxs_js_get_themecsstemplate_part1_anchorlinkcolors(".nxs-linkcolorvar .nxs-linkcolorvar .nxs-linkcolorvar .nxs-linkcolorvar ","", csslookup);
9234
9235	//
9236
9237  /* DEFAULT ICON WIDTH CLASSES
9238  ---------------------------------------------------------------------------------------------------- */
9239
9240  u = u + nxs_js_createcssstyling(
9241      {
9242          factor: 80,
9243          multipliers: nxs_js_getstyletypevalues("image_size"),
9244          cssparameters: [
9245              {
9246                  csstemplate: '.nxs-icon-width-$nxs_identification; { width: $nxs_formularesult;px; height: $nxs_formularesult;px; }',
9247              }
9248          ]
9249      }
9250  );
9251
9252  /* DEFAULT BORDER WIDTH CLASSES
9253  ---------------------------------------------------------------------------------------------------- */
9254
9255  u = u + nxs_js_createcssstyling(
9256      {
9257          factor: 1,
9258          multipliers: nxs_js_getstyletypevalues("border_width"),
9259          cssparameters: [
9260          		{
9261          			csstemplate: ' \
9262          				.nxs-border-width-$nxs_identification; { border: $nxs_formularesult;px solid black; } 								\
9263          				.nxs-border-left-width-$nxs_identification; { border-left-width: $nxs_formularesult;px; } 			\
9264          				.nxs-border-right-width-$nxs_identification; { border-right-width: $nxs_formularesult;px; }		 	\
9265          				.nxs-border-top-width-$nxs_identification; { border-top-width: $nxs_formularesult;px; }					\
9266          				.nxs-border-bottom-width-$nxs_identification; { border-bottom-width: $nxs_formularesult;px; }'
9267          		}
9268          ]
9269      }
9270  );
9271
9272  /* DEFAULT PADDING CLASSES
9273  ---------------------------------------------------------------------------------------------------- */
9274
9275	u = u + nxs_js_createcssstyling(
9276  {
9277      factor: 30,
9278      multipliers: nxs_js_getstyletypevalues("padding"),
9279      cssparameters: [
9280					{
9281      			csstemplate: ' \
9282      				.nxs-padding-$nxs_identification; { padding: $nxs_formularesult;px; }			\
9283      				.nxs-padding-top-$nxs_identification; { padding-top: $nxs_formularesult;px; }	\
9284      				.nxs-padding-bottom-$nxs_identification; { padding-bottom: $nxs_formularesult;px; }'
9285      		}
9286     	]
9287  }
9288	);
9289
9290  /* DEFAULT MARGIN CLASSES
9291  ---------------------------------------------------------------------------------------------------- */
9292
9293	u = u + nxs_js_createcssstyling(
9294  {
9295      factor: 30,
9296      multipliers: nxs_js_getstyletypevalues("margin"),
9297      cssparameters: [
9298          {
9299      			csstemplate: '\
9300      				.nxs-margin-$nxs_identification; { margin: $nxs_formularesult;px; }	\
9301      				.nxs-margin-top-$nxs_identification; { margin-top: $nxs_formularesult;px; }	\
9302      				.nxs-margin-bottom-$nxs_identification; { margin-bottom: $nxs_formularesult;px; }'
9303      		}
9304       ]
9305  }
9306  );
9307
9308  /* DEFAULT BORDER RADIUS CLASSES
9309  ---------------------------------------------------------------------------------------------------- */
9310
9311  u = u + nxs_js_createcssstyling(
9312  {
9313      factor: 3,
9314      multipliers: nxs_js_getstyletypevalues("border_radius"),
9315      cssparameters: [
9316					{
9317      			csstemplate: '.nxs-border-radius-$nxs_identification; { border-radius: $nxs_formularesult;px; }',
9318      		}
9319      ]
9320  }
9321  );
9322
9323  /* MAX HEIGHT CLASSES
9324  ---------------------------------------------------------------------------------------------------- */
9325
9326  u = u + nxs_js_createcssstyling(
9327  {
9328      factor: 100,
9329      multipliers: nxs_js_getstyletypevalues("maxheight"),
9330      cssparameters: [
9331					{
9332      			csstemplate: '.nxs-maxheight-$nxs_identification; { max-height: $nxs_formularesult;px; }',
9333      		}
9334      ]
9335  }
9336  );
9337
9338  /* DEFAULT BUTTON SCALE CLASSES
9339  ---------------------------------------------------------------------------------------------------- */
9340
9341  // padding top and bottom
9342
9343  u = u + nxs_js_createcssstyling(
9344  {
9345      multipliers: nxs_js_getstyletypevalues("button_scale"),
9346      cssparameters: [
9347          {
9348          	factor: 6,
9349            csstemplate: '\
9350            	.nxs-button-scale-$nxs_identification; \
9351            	{ \
9352            		padding-top: $nxs_formularesult;px; \
9353            		padding-bottom: $nxs_formularesult;px; \
9354            	}',
9355          },
9356          {
9357          	factor: 10,
9358            csstemplate: '\
9359            	.nxs-button-scale-$nxs_identification; \
9360            	{ \
9361            		padding-left: $nxs_formularesult;px; \
9362            		padding-right: $nxs_formularesult;px; \
9363            	}',
9364          },
9365          {
9366          	factor: 12,
9367            csstemplate: '\
9368            	.nxs-button-scale-$nxs_identification; \
9369            	{ \
9370            		font-size: $nxs_formularesult;px; \
9371            	}',
9372          }
9373      ]
9374    }
9375  );
9376
9377  /* DEFAULT BUTTON SCALE CLASSES
9378  ---------------------------------------------------------------------------------------------------- */
9379
9380  // padding top and bottom
9381
9382  u = u + nxs_js_createcssstyling(
9383  {
9384      multipliers: nxs_js_getstyletypevalues("icon_scale"),
9385      cssparameters: [
9386          {
9387          	factor: 32,
9388            csstemplate: '\
9389            	.nxs-icon-scale-$nxs_identification;, \
9390            	.nxs-text .top-wrapper span.nxs-icon-scale-$nxs_identification; \
9391            	{ \
9392            		font-size: $nxs_formularesult;px; \
9393            	}',
9394          }
9395      ]
9396    }
9397  );
9398
9399  /* DEFAULT FONTSIZE SCALE CLASSES
9400  ---------------------------------------------------------------------------------------------------- */
9401
9402  var fontscale = 10;
9403  var factor_textfontsize = 1.5;	/* TODO: make this configurable by end user in flyout menu */
9404
9405  // font-sizes (1.0, 1.2, ... 2.0 = 15px ... 30px)
9406  u = u + nxs_js_createcssstyling(
9407  {
9408      multipliers: nxs_js_getstyletypevalues("fontsize"),
9409      cssparameters:
9410      [
9411        {
9412        	scale: fontscale,
9413        	factor: factor_textfontsize,
9414          csstemplate: '\
9415        	#nxs-container.nxs-text-fontsize-$nxs_identification; .nxs-default-p p, \
9416        	#nxs-container.nxs-text-fontsize-$nxs_identification; .nxs-default-p span, \
9417	       	#nxs-container .nxs-placeholder.nxs-text-fontsize-$nxs_identification; .nxs-default-p p, \
9418        	#nxs-container .nxs-placeholder.nxs-text-fontsize-$nxs_identification; .nxs-default-p span, \
9419        	#nxs-container.nxs-head-fontsize-$nxs_identification; .nxs-title, \
9420        	#nxs-container .nxs-placeholder.nxs-head-fontsize-$nxs_identification; .nxs-title, \
9421        	#nxs-container .nxs-placeholder .nxs-head-fontsize-$nxs_identification;.nxs-title \
9422        	{ \
9423        		 font-size: $nxs_formularesult;px; \
9424        	}',
9425        },
9426      ]
9427    }
9428  );
9429
9430  u += nxs_js_createcssstyling_fontsizeheading("H1", 2.0, fontscale, factor_textfontsize);
9431  u += nxs_js_createcssstyling_fontsizeheading("H2", 1.8, fontscale, factor_textfontsize);
9432  u += nxs_js_createcssstyling_fontsizeheading("H3", 1.6, fontscale, factor_textfontsize);
9433  u += nxs_js_createcssstyling_fontsizeheading("H4", 1.4, fontscale, factor_textfontsize);
9434  u += nxs_js_createcssstyling_fontsizeheading("H5", 1.2, fontscale, factor_textfontsize);
9435  u += nxs_js_createcssstyling_fontsizeheading("H6", 1.0, fontscale, factor_textfontsize);
9436
9437  u = u + ".nxs-image-wrapper img {}";
9438
9439	u += "/* end injected by framework */";
9440
9441	//nxs_js_log('part1:');
9442	//nxs_js_log(u);
9443
9444	//
9445	//
9446	//
9447	return u;
9448}
9449
9450function nxs_js_popuptogglewrapper(domelement, id)
9451{
9452	var container = jQuery(domelement).closest(".nxs-option-toggler");
9453	jQuery('#' + id).toggle();
9454	jQuery(container).toggleClass("nxs-toggled-open");
9455	jQuery(container).toggleClass("nxs-toggled-closed");
9456
9457	// after toggle: reposition the popup (immeditately)
9458	nxs_js_reset_popup_dimensions_actualrequest();
9459}
9460
9461function nxs_js_refreshtopmenufillerheight()
9462{
9463	var height = jQuery("#nxs-menu-wrap").height();
9464	//nxs_js_log('height nxs-menu-wrap is ' + height);
9465	jQuery('#menufillerinlinecontent').height(height); // + 30);
9466}
9467
9468/* nicescroll */
9469
9470/* jquery.nicescroll 3.5.0 InuYaksa*2013 MIT http://areaaperta.com/nicescroll */(function(e){var z=!1,E=!1,L=5E3,M=2E3,y=0,N=function(){var e=document.getElementsByTagName("script"),e=e[e.length-1].src.split("?")[0];return 0<e.split("/").length?e.split("/").slice(0,-1).join("/")+"/":""}(),H=["ms","moz","webkit","o"],v=window.requestAnimationFrame||!1,w=window.cancelAnimationFrame||!1;if(!v)for(var O in H){var F=H[O];v||(v=window[F+"RequestAnimationFrame"]);w||(w=window[F+"CancelAnimationFrame"]||window[F+"CancelRequestAnimationFrame"])}var A=window.MutationObserver||window.WebKitMutationObserver||
9471!1,I={zindex:"auto",cursoropacitymin:0,cursoropacitymax:1,cursorcolor:"#424242",cursorwidth:"5px",cursorborder:"1px solid #fff",cursorborderradius:"5px",scrollspeed:60,mousescrollstep:24,touchbehavior:!1,hwacceleration:!0,usetransition:!0,boxzoom:!1,dblclickzoom:!0,gesturezoom:!0,grabcursorenabled:!0,autohidemode:!0,background:"",iframeautoresize:!0,cursorminheight:32,preservenativescrolling:!0,railoffset:!1,bouncescroll:!0,spacebarenabled:!0,railpadding:{top:0,right:0,left:0,bottom:0},disableoutline:!0,
9472horizrailenabled:!0,railalign:"right",railvalign:"bottom",enabletranslate3d:!0,enablemousewheel:!0,enablekeyboard:!0,smoothscroll:!0,sensitiverail:!0,enablemouselockapi:!0,cursorfixedheight:!1,directionlockdeadzone:6,hidecursordelay:400,nativeparentscrolling:!0,enablescrollonselection:!0,overflowx:!0,overflowy:!0,cursordragspeed:0.3,rtlmode:!1,cursordragontouch:!1,oneaxismousemode:"auto"},G=!1,P=function(){if(G)return G;var e=document.createElement("DIV"),c={haspointerlock:"pointerLockElement"in document||
9473"mozPointerLockElement"in document||"webkitPointerLockElement"in document};c.isopera="opera"in window;c.isopera12=c.isopera&&"getUserMedia"in navigator;c.isoperamini="[object OperaMini]"===Object.prototype.toString.call(window.operamini);c.isie="all"in document&&"attachEvent"in e&&!c.isopera;c.isieold=c.isie&&!("msInterpolationMode"in e.style);c.isie7=c.isie&&!c.isieold&&(!("documentMode"in document)||7==document.documentMode);c.isie8=c.isie&&"documentMode"in document&&8==document.documentMode;c.isie9=
9474c.isie&&"performance"in window&&9<=document.documentMode;c.isie10=c.isie&&"performance"in window&&10<=document.documentMode;c.isie9mobile=/iemobile.9/i.test(navigator.userAgent);c.isie9mobile&&(c.isie9=!1);c.isie7mobile=!c.isie9mobile&&c.isie7&&/iemobile/i.test(navigator.userAgent);c.ismozilla="MozAppearance"in e.style;c.iswebkit="WebkitAppearance"in e.style;c.ischrome="chrome"in window;c.ischrome22=c.ischrome&&c.haspointerlock;c.ischrome26=c.ischrome&&"transition"in e.style;c.cantouch="ontouchstart"in
9475document.documentElement||"ontouchstart"in window;c.hasmstouch=window.navigator.msPointerEnabled||!1;c.ismac=/^mac$/i.test(navigator.platform);c.isios=c.cantouch&&/iphone|ipad|ipod/i.test(navigator.platform);c.isios4=c.isios&&!("seal"in Object);c.isandroid=/android/i.test(navigator.userAgent);c.trstyle=!1;c.hastransform=!1;c.hastranslate3d=!1;c.transitionstyle=!1;c.hastransition=!1;c.transitionend=!1;for(var k=["transform","msTransform","webkitTransform","MozTransform","OTransform"],l=0;l<k.length;l++)if("undefined"!=
9476typeof e.style[k[l]]){c.trstyle=k[l];break}c.hastransform=!1!=c.trstyle;c.hastransform&&(e.style[c.trstyle]="translate3d(1px,2px,3px)",c.hastranslate3d=/translate3d/.test(e.style[c.trstyle]));c.transitionstyle=!1;c.prefixstyle="";c.transitionend=!1;for(var k="transition webkitTransition MozTransition OTransition OTransition msTransition KhtmlTransition".split(" "),q=" -webkit- -moz- -o- -o -ms- -khtml-".split(" "),t="transitionend webkitTransitionEnd transitionend otransitionend oTransitionEnd msTransitionEnd KhtmlTransitionEnd".split(" "),
9477l=0;l<k.length;l++)if(k[l]in e.style){c.transitionstyle=k[l];c.prefixstyle=q[l];c.transitionend=t[l];break}c.ischrome26&&(c.prefixstyle=q[1]);c.hastransition=c.transitionstyle;a:{k=["-moz-grab","-webkit-grab","grab"];
9477if(c.ischrome&&!c.ischrome22||c.isie)k=[];for(l=0;l<k.length;l++)if(q=k[l],e.style.cursor=q,e.style.cursor==q){k=q;break a}k="url(http://www.google.com/intl/en_ALL/mapfiles/openhand.cur),n-resize"}c.cursorgrabvalue=k;c.hasmousecapture="setCapture"in e;c.hasMutationObserver=!1!==A;return G=
9478c},Q=function(h,c){function k(){var d=b.win;if("zIndex"in d)return d.zIndex();for(;0<d.length&&9!=d[0].nodeType;){var c=d.css("zIndex");if(!isNaN(c)&&0!=c)return parseInt(c);d=d.parent()}return!1}function l(d,c,f){c=d.css(c);d=parseFloat(c);return isNaN(d)?(d=u[c]||0,f=3==d?f?b.win.outerHeight()-b.win.innerHeight():b.win.outerWidth()-b.win.innerWidth():1,b.isie8&&d&&(d+=1),f?d:0):d}function q(d,c,f,g){b._bind(d,c,function(b){b=b?b:window.event;var g={original:b,target:b.target||b.srcElement,type:"wheel",
9479deltaMode:"MozMousePixelScroll"==b.type?0:1,deltaX:0,deltaZ:0,preventDefault:function(){b.preventDefault?b.preventDefault():b.returnValue=!1;return!1},stopImmediatePropagation:function(){b.stopImmediatePropagation?b.stopImmediatePropagation():b.cancelBubble=!0}};"mousewheel"==c?(g.deltaY=-0.025*b.wheelDelta,b.wheelDeltaX&&(g.deltaX=-0.025*b.wheelDeltaX)):g.deltaY=b.detail;return f.call(d,g)},g)}function t(d,c,f){var g,e;0==d.deltaMode?(g=-Math.floor(d.deltaX*(b.opt.mousescrollstep/54)),e=-Math.floor(d.deltaY*
9480(b.opt.mousescrollstep/54))):1==d.deltaMode&&(g=-Math.floor(d.deltaX*b.opt.mousescrollstep),e=-Math.floor(d.deltaY*b.opt.mousescrollstep));c&&(b.opt.oneaxismousemode&&0==g&&e)&&(g=e,e=0);g&&(b.scrollmom&&b.scrollmom.stop(),b.lastdeltax+=g,b.debounced("mousewheelx",function(){var d=b.lastdeltax;b.lastdeltax=0;b.rail.drag||b.doScrollLeftBy(d)},120));if(e){if(b.opt.nativeparentscrolling&&f&&!b.ispage&&!b.zoomactive)if(0>e){if(b.getScrollTop()>=b.page.maxh)return!0}else if(0>=b.getScrollTop())return!0;
9481b.scrollmom&&b.scrollmom.stop();b.lastdeltay+=e;b.debounced("mousewheely",function(){var d=b.lastdeltay;b.lastdeltay=0;b.rail.drag||b.doScrollBy(d)},120)}d.stopImmediatePropagation();return d.preventDefault()}var b=this;this.version="3.5.0";this.name="nicescroll";this.me=c;this.opt={doc:e("body"),win:!1};e.extend(this.opt,I);this.opt.snapbackspeed=80;if(h)for(var p in b.opt)"undefined"!=typeof h[p]&&(b.opt[p]=h[p]);this.iddoc=(this.doc=b.opt.doc)&&this.doc[0]?this.doc[0].id||"":"";this.ispage=/BODY|HTML/.test(b.opt.win?
9482b.opt.win[0].nodeName:this.doc[0].nodeName);this.haswrapper=!1!==b.opt.win;
9482this.win=b.opt.win||(this.ispage?e(window):this.doc);this.docscroll=this.ispage&&!this.haswrapper?e(window):this.win;this.body=e("body");this.iframe=this.isfixed=this.viewport=!1;this.isiframe="IFRAME"==this.doc[0].nodeName&&"IFRAME"==this.win[0].nodeName;this.istextarea="TEXTAREA"==this.win[0].nodeName;this.forcescreen=!1;this.canshowonmouseevent="scroll"!=b.opt.autohidemode;this.page=this.view=this.onzoomout=this.onzoomin=
9483this.onscrollcancel=this.onscrollend=this.onscrollstart=this.onclick=this.ongesturezoom=this.onkeypress=this.onmousewheel=this.onmousemove=this.onmouseup=this.onmousedown=!1;this.scroll={x:0,y:0};this.scrollratio={x:0,y:0};this.cursorheight=20;this.scrollvaluemax=0;this.observerremover=this.observer=this.scrollmom=this.scrollrunning=this.checkrtlmode=!1;do this.id="ascrail"+M++;while(document.getElementById(this.id));this.hasmousefocus=this.hasfocus=this.zoomactive=this.zoom=this.selectiondrag=this.cursorfreezed=
9484this.cursor=this.rail=!1;this.visibility=!0;this.hidden=this.locked=!1;this.cursoractive=!0;this.overflowx=b.opt.overflowx;this.overflowy=b.opt.overflowy;this.nativescrollingarea=!1;this.checkarea=0;this.events=[];this.saved={};this.delaylist={};this.synclist={};this.lastdeltay=this.lastdeltax=0;this.detected=P();var g=e.extend({},this.detected);this.ishwscroll=(this.canhwscroll=g.hastransform&&b.opt.hwacceleration)&&b.haswrapper;this.istouchcapable=!1;g.cantouch&&(g.ischrome&&!g.isios&&!g.isandroid)&&
9485(this.istouchcapable=!0,g.cantouch=!1);g.cantouch&&(g.ismozilla&&!g.isios&&!g.isandroid)&&(this.istouchcapable=!0,g.cantouch=!1);b.opt.enablemouselockapi||(g.hasmousecapture=!1,g.haspointerlock=!1);this.delayed=function(d,c,f,g){var e=b.delaylist[d],k=(new Date).getTime();if(!g&&e&&e.tt)return!1;e&&e.tt&&clearTimeout(e.tt);if(e&&e.last+f>k&&!e.tt)b.delaylist[d]={last:k+f,tt:setTimeout(function(){b.delaylist[d].tt=0;c.call()},f)};else if(!e||!e.tt)b.delaylist[d]={last:k,tt:0},setTimeout(function(){c.call()},
94860)};this.debounced=function(d,c,f){var g=b.delaylist[d];(new Date).getTime();b.delaylist[d]=c;g||setTimeout(function(){var c=b.delaylist[d];b.delaylist[d]=!1;c.call()},f)};this.synched=function(d,c){b.synclist[d]=c;(function(){b.onsync||(v(function(){b.onsync=!1;for(d in b.synclist){var c=b.synclist[d];c&&c.call(b);b.synclist[d]=!1}}),b.onsync=!0)})();return d};this.unsynched=function(d){b.synclist[d]&&(b.synclist[d]=!1)};this.css=function(d,c){for(var f in c)b.saved.css.push([d,f,d.css(f)]),d.css(f,
9487c[f])};this.scrollTop=function(d){return"undefined"==typeof d?b.getScrollTop():b.setScrollTop(d)};this.scrollLeft=function(d){return"undefined"==typeof d?b.getScrollLeft():b.setScrollLeft(d)};BezierClass=function(b,c,f,g,e,k,l){this.st=b;this.ed=c;this.spd=f;this.p1=g||0;this.p2=e||1;this.p3=k||0;this.p4=l||1;this.ts=(new Date).getTime();this.df=this.ed-this.st};BezierClass.prototype={B2:function(b){return 3*b*b*(1-b)},B3:function(b){return 3*b*(1-b)*(1-b)},B4:function(b){return(1-b)*(1-b)*(1-b)},
9488getNow:function(){var b=1-((new Date).getTime()-this.ts)/this.spd,c=this.B2(b)+this.B3(b)+this.B4(b);return 0>b?this.ed:this.st+Math.round(this.df*c)},update:function(b,c){this.st=this.getNow();this.ed=b;this.spd=c;this.ts=(new Date).getTime();this.df=this.ed-this.st;return this}};if(this.ishwscroll){this.doc.translate={x:0,y:0,tx:"0px",ty:"0px"};g.hastranslate3d&&g.isios&&this.doc.css("-webkit-backface-visibility","hidden");var s=function(){var d=b.doc.css(g.trstyle);return d&&"matrix"==d.substr(0,
94896)?d.replace(/^.*\((.*)\)$/g,"$1").replace(/px/g,"").split(/, +/):!1};this.getScrollTop=function(d){if(!d){if(d=s())return 16==d.length?-d[13]:-d[5];if(b.timerscroll&&b.timerscroll.bz)return b.timerscroll.bz.getNow()}return b.doc.translate.y};this.getScrollLeft=function(d){if(!d){if(d=s())return 16==d.length?-d[12]:-d[4];if(b.timerscroll&&b.timerscroll.bh)return b.timerscroll.bh.getNow()}return b.doc.translate.x};this.notifyScrollEvent=document.createEvent?function(b){var c=document.createEvent("UIEvents");
9490c.initUIEvent("scroll",!1,!0,window,1);b.dispatchEvent(c)}:document.fireEvent?function(b){var c=document.createEventObject();
9490b.fireEvent("onscroll");c.cancelBubble=!0}:function(b,c){};g.hastranslate3d&&b.opt.enabletranslate3d?(this.setScrollTop=function(d,c){b.doc.translate.y=d;b.doc.translate.ty=-1*d+"px";b.doc.css(g.trstyle,"translate3d("+b.doc.translate.tx+","+b.doc.translate.ty+",0px)");c||b.notifyScrollEvent(b.win[0])},this.setScrollLeft=function(d,c){b.doc.translate.x=d;b.doc.translate.tx=-1*
9491d+"px";b.doc.css(g.trstyle,"translate3d("+b.doc.translate.tx+","+b.doc.translate.ty+",0px)");c||b.notifyScrollEvent(b.win[0])}):(this.setScrollTop=function(d,c){b.doc.translate.y=d;b.doc.translate.ty=-1*d+"px";b.doc.css(g.trstyle,"translate("+b.doc.translate.tx+","+b.doc.translate.ty+")");c||b.notifyScrollEvent(b.win[0])},this.setScrollLeft=function(d,c){b.doc.translate.x=d;b.doc.translate.tx=-1*d+"px";b.doc.css(g.trstyle,"translate("+b.doc.translate.tx+","+b.doc.translate.ty+")");c||b.notifyScrollEvent(b.win[0])})}else this.getScrollTop=
9492function(){return b.docscroll.scrollTop()},this.setScrollTop=function(d){return b.docscroll.scrollTop(d)},this.getScrollLeft=function(){return b.docscroll.scrollLeft()},this.setScrollLeft=function(d){return b.docscroll.scrollLeft(d)};this.getTarget=function(b){return!b?!1:b.target?b.target:b.srcElement?b.srcElement:!1};this.hasParent=function(b,c){if(!b)return!1;for(var f=b.target||b.srcElement||b||!1;f&&f.id!=c;)f=f.parentNode||!1;return!1!==f};var u={thin:1,medium:3,thick:5};this.getOffset=function(){if(b.isfixed)return{top:parseFloat(b.win.css("top")),
9493left:parseFloat(b.win.css("left"))};if(!b.viewport)return b.win.offset();var d=b.win.offset(),c=b.viewport.offset();return{top:d.top-c.top+b.viewport.scrollTop(),left:d.left-c.left+b.viewport.scrollLeft()}};this.updateScrollBar=function(d){if(b.ishwscroll)b.rail.css({height:b.win.innerHeight()}
9493),b.railh&&b.railh.css({width:b.win.innerWidth()});else{var c=b.getOffset(),f=c.top,g=c.left,f=f+l(b.win,"border-top-width",!0);b.win.outerWidth();b.win.innerWidth();var g=g+(b.rail.align?b.win.outerWidth()-
9494l(b.win,"border-right-width")-b.rail.width:l(b.win,"border-left-width")),e=b.opt.railoffset;e&&(e.top&&(f+=e.top),b.rail.align&&e.left&&(g+=e.left));b.locked||b.rail.css({top:f,left:g,height:d?d.h:b.win.innerHeight()});b.zoom&&b.zoom.css({top:f+1,left:1==b.rail.align?g-20:g+b.rail.width+4});b.railh&&!b.locked&&(f=c.top,g=c.left,d=b.railh.align?f+l(b.win,"border-top-width",!0)+b.win.innerHeight()-b.railh.height:f+l(b.win,"border-top-width",!0),g+=l(b.win,"border-left-width"),b.railh.css({top:d,left:g,
9495width:b.railh.width}))}};this.doRailClick=function(d,c,f){var g;b.locked||(b.cancelEvent(d),c?(c=f?b.doScrollLeft:b.doScrollTop,g=f?(d.pageX-b.railh.offset().left-b.cursorwidth/2)*b.scrollratio.x:(d.pageY-b.rail.offset().top-b.cursorheight/2)*b.scrollratio.y,c(g)):(c=f?b.doScrollLeftBy:b.doScrollBy,g=f?b.scroll.x:b.scroll.y,d=f?d.pageX-b.railh.offset().left:d.pageY-b.rail.offset().top,f=f?b.view.w:b.view.h,g>=d?c(f):c(-f)))};b.hasanimationframe=v;b.hascancelanimationframe=w;b.hasanimationframe?b.hascancelanimationframe||
9496(w=function(){b.cancelAnimationFrame=!0}):(v=function(b){return setTimeout(b,15-Math.floor(+new Date/1E3)%16)},w=clearInterval);this.init=function(){b.saved.css=[];if(g.isie7mobile||g.isoperamini)return!0;g.hasmstouch&&b.css(b.ispage?e("html"):b.win,{"-ms-touch-action":"none"});b.zindex="auto";b.zindex=!b.ispage&&"auto"==b.opt.zindex?k()||"auto":b.opt.zindex;!b.ispage&&"auto"!=b.zindex&&b.zindex>y&&(y=b.zindex);b.isie&&(0==b.zindex&&"auto"==b.opt.zindex)&&(b.zindex="auto");if(!b.ispage||!g.cantouch&&
9497!g.isieold&&!g.isie9mobile){var d=b.docscroll;b.ispage&&(d=b.haswrapper?b.win:b.doc);g.isie9mobile||b.css(d,{"overflow-y":"hidden"});b.ispage&&g.isie7&&("BODY"==b.doc[0].nodeName?b.css(e("html"),{"overflow-y":"hidden"}):"HTML"==b.doc[0].nodeName&&b.css(e("body"),{"overflow-y":"hidden"}));g.isios&&(!b.ispage&&!b.haswrapper)&&b.css(e("body"),{"-webkit-overflow-scrolling":"touch"});var c=e(document.createElement("div"));c.css({position:"relative",top:0,"float":"right",width:b.opt.cursorwidth,height:"0px",
9498"background-color":b.opt.cursorcolor,border:b.opt.cursorborder,"background-clip":"padding-box","-webkit-border-radius":b.opt.cursorborderradius,"-moz-border-radius":b.opt.cursorborderradius,"border-radius":b.opt.cursorborderradius});c.hborder=parseFloat(c.outerHeight()-c.innerHeight());b.cursor=c;var f=e(document.createElement("div"));f.attr("id",b.id);f.addClass("nicescroll-rails");var l,h,x=["left","right"],q;for(q in x)h=x[q],(l=b.opt.railpadding[h])?f.css("padding-"+h,l+"px"):b.opt.railpadding[h]=
94990;f.append(c);f.width=Math.max(parseFloat(b.opt.cursorwidth),c.outerWidth())+b.opt.railpadding.left+b.opt.railpadding.right;f.css({width:f.width+"px",zIndex:b.zindex,background:b.opt.background,cursor:"default"});f.visibility=!0;f.scrollable=!0;f.align="left"==b.opt.railalign?0:1;b.rail=f;c=b.rail.drag=!1;b.opt.boxzoom&&(!b.ispage&&!g.isieold)&&(c=document.createElement("div"),b.bind(c,"click",b.doZoom),b.zoom=e(c),b.zoom.css({cursor:"pointer","z-index":b.zindex,backgroundImage:"url("+N+"zoomico.png)",
9500height:18,width:18,backgroundPosition:"0px 0px"}),b.opt.dblclickzoom&&b.bind(b.win,"dblclick",b.doZoom),g.cantouch&&b.opt.gesturezoom&&(b.ongesturezoom=function(d){1.5<d.scale&&b.doZoomIn(d);0.8>d.scale&&b.doZoomOut(d);return b.cancelEvent(d)},b.bind(b.win,"gestureend",b.ongesturezoom)));b.railh=!1;if(b.opt.horizrailenabled){b.css(d,{"overflow-x":"hidden"});c=e(document.createElement("div"));c.css({position:"relative",top:0,height:b.opt.cursorwidth,width:"0px","background-color":b.opt.cursorcolor,
9501border:b.opt.cursorborder,"background-clip":"padding-box","-webkit-border-radius":b.opt.cursorborderradius,"-moz-border-radius":b.opt.cursorborderradius,"border-radius":b.opt.cursorborderradius});c.wborder=parseFloat(c.outerWidth()-c.innerWidth());b.cursorh=c;var m=e(document.createElement("div"));m.attr("id",b.id+"-hr");m.addClass("nicescroll-rails");m.height=Math.max(parseFloat(b.opt.cursorwidth),c.outerHeight());m.css({height:m.height+"px",zIndex:b.zindex,background:b.opt.background});m.append(c);
9502m.visibility=!0;m.scrollable=!0;m.align="top"==b.opt.railvalign?0:1;b.railh=m;b.railh.drag=!1}b.ispage?(f.css({position:"fixed",top:"0px",height:"100%"}),f.align?f.css({right:"0px"}):f.css({left:"0px"}),b.body.append(f),b.railh&&(m.css({position:"fixed",left:"0px",width:"100%"}),m.align?m.css({bottom:"0px"}):m.css({top:"0px"}),b.body.append(m))):(b.ishwscroll?("static"==b.win.css("position")&&b.css(b.win,{position:"relative"}),d="HTML"==b.win[0].nodeName?b.body:b.win,b.zoom&&(b.zoom.css({position:"absolute",
9503top:1,right:0,"margin-right":f.width+4}),d.append(b.zoom)),f.css({position:"absolute",top:0}),f.align?f.css({right:0}):f.css({left:0}),d.append(f),m&&(m.css({position:"absolute",left:0,bottom:0}),m.align?m.css({bottom:0}):m.css({top:0}),d.append(m))):(b.isfixed="fixed"==b.win.css("position"),d=b.isfixed?"fixed":"absolute",b.isfixed||(b.viewport=b.getViewport(b.win[0])),b.viewport&&(b.body=b.viewport,!1==/fixed|relative|absolute/.test(b.viewport.css("position"))&&b.css(b.viewport,{position:"relative"})),
9504f.css({position:d}),b.zoom&&b.zoom.css({position:d}),b.updateScrollBar(),b.body.append(f),b.zoom&&b.body.append(b.zoom),b.railh&&(m.css({position:d}),b.body.append(m))),g.isios&&b.css(b.win,{"-webkit-tap-highlight-color":"rgba(0,0,0,0)","-webkit-touch-callout":"none"}),g.isie&&b.opt.disableoutline&&b.win.attr("hideFocus","true"),g.iswebkit&&b.opt.disableoutline&&b.win.css({outline:"none"}));!1===b.opt.autohidemode?(b.autohidedom=!1,b.rail.css({opacity:b.opt.cursoropacitymax}),b.railh&&b.railh.css({opacity:b.opt.cursoropacitymax})):
9505!0===b.opt.autohidemode||"leave"===b.opt.autohidemode?(b.autohidedom=e().add(b.rail),g.isie8&&(b.autohidedom=b.autohidedom.add(b.cursor)),b.railh&&(b.autohidedom=b.autohidedom.add(b.railh)),b.railh&&g.isie8&&(b.autohidedom=b.autohidedom.add(b.cursorh))):"scroll"==b.opt.autohidemode?(b.autohidedom=e().add(b.rail),b.railh&&(b.autohidedom=b.autohidedom.add(b.railh))):"cursor"==b.opt.autohidemode?(b.autohidedom=e().add(b.cursor),b.railh&&(b.autohidedom=b.autohidedom.add(b.cursorh))):"hidden"==b.opt.autohidemode&&
9506(b.autohidedom=!1,b.hide(),b.locked=!1);if(g.isie9mobile)b.scrollmom=new J(b),b.onmangotouch=function(d){d=b.getScrollTop();var c=b.getScrollLeft();if(d==b.scrollmom.lastscrolly&&c==b.scrollmom.lastscrollx)return!0;var f=d-b.mangotouch.sy,g=c-b.mangotouch.sx;if(0!=Math.round(Math.sqrt(Math.pow(g,2)+Math.pow(f,2)))){var n=0>f?-1:1,e=0>g?-1:1,k=+new Date;b.mangotouch.lazy&&clearTimeout(b.mangotouch.lazy);80<k-b.mangotouch.tm||b.mangotouch.dry!=n||b.mangotouch.drx!=e?(b.scrollmom.stop(),b.scrollmom.reset(c,
9507d),b.mangotouch.sy=d,b.mangotouch.ly=d,b.mangotouch.sx=c,b.mangotouch.lx=c,b.mangotouch.dry=n,b.mangotouch.drx=e,b.mangotouch.tm=k):(b.scrollmom.stop(),b.scrollmom.update(b.mangotouch.sx-g,b.mangotouch.sy-f),b.mangotouch.tm=k,f=Math.max(Math.abs(b.mangotouch.ly-d),Math.abs(b.mangotouch.lx-c)),b.mangotouch.ly=d,b.mangotouch.lx=c,2<f&&(b.mangotouch.lazy=setTimeout(function(){b.mangotouch.lazy=!1;b.mangotouch.dry=0;b.mangotouch.drx=0;b.mangotouch.tm=0;b.scrollmom.doMomentum(30)},100)))}},f=b.getScrollTop(),
9508m=b.getScrollLeft(),b.mangotouch={sy:f,ly:f,dry:0,sx:m,lx:m,drx:0,lazy:!1,tm:0},b.bind(b.docscroll,"scroll",b.onmangotouch);else{if(g.cantouch||b.istouchcapable||b.opt.touchbehavior||g.hasmstouch){b.scrollmom=new J(b);b.ontouchstart=function(d){if(d.pointerType&&2!=d.pointerType)return!1;if(!b.locked){if(g.hasmstouch)for(var c=d.target?d.target:!1;c;){var f=e(c).getNiceScroll();if(0<f.length&&f[0].me==b.me)break;
9508if(0<f.length)return!1;if("DIV"==c.nodeName&&c.id==b.id)break;c=c.parentNode?c.parentNode:
9509!1}b.cancelScroll();if((c=b.getTarget(d))&&/INPUT/i.test(c.nodeName)&&/range/i.test(c.type))return b.stopPropagation(d);!("clientX"in d)&&"changedTouches"in d&&(d.clientX=d.changedTouches[0].clientX,d.clientY=d.changedTouches[0].clientY);b.forcescreen&&(f=d,d={original:d.original?d.original:d},d.clientX=f.screenX,d.clientY=f.screenY);b.rail.drag={x:d.clientX,y:d.clientY,sx:b.scroll.x,sy:b.scroll.y,st:b.getScrollTop(),sl:b.getScrollLeft(),pt:2,dl:!1};if(b.ispage||!b.opt.directionlockdeadzone)b.rail.drag.dl=
9510"f";else{var f=e(window).width(),n=e(window).height(),k=Math.max(document.body.scrollWidth,document.documentElement.scrollWidth),l=Math.max(document.body.scrollHeight,document.documentElement.scrollHeight),n=Math.max(0,l-n),f=Math.max(0,k-f);b.rail.drag.ck=!b.rail.scrollable&&b.railh.scrollable?0<n?"v":!1:b.rail.scrollable&&!b.railh.scrollable?0<f?"h":!1:!1;b.rail.drag.ck||(b.rail.drag.dl="f")}b.opt.touchbehavior&&(b.isiframe&&g.isie)&&(f=b.win.position(),b.rail.drag.x+=f.left,b.rail.drag.y+=f.top);
9511b.hasmoving=!1;b.lastmouseup=!1;b.scrollmom.reset(d.clientX,d.clientY);if(!g.cantouch&&!this.istouchcapable&&!g.hasmstouch){if(!c||!/INPUT|SELECT|TEXTAREA/i.test(c.nodeName))return!b.ispage&&g.hasmousecapture&&c.setCapture(),b.opt.touchbehavior?b.cancelEvent(d):b.stopPropagation(d);/SUBMIT|CANCEL|BUTTON/i.test(e(c).attr("type"))&&(pc={tg:c,click:!1},b.preventclick=pc)}}};b.ontouchend=function(d){if(d.pointerType&&2!=d.pointerType)return!1;if(b.rail.drag&&2==b.rail.drag.pt&&(b.scrollmom.doMomentum(),
9512b.rail.drag=!1,b.hasmoving&&(b.hasmoving=!1,b.lastmouseup=!0,b.hideCursor(),g.hasmousecapture&&document.releaseCapture(),!g.cantouch)))return b.cancelEvent(d)};var t=b.opt.touchbehavior&&b.isiframe&&!g.hasmousecapture;b.ontouchmove=function(d,c){if(d.pointerType&&2!=d.pointerType)return!1;if(b.rail.drag&&2==b.rail.drag.pt){if(g.cantouch&&"undefined"==typeof d.original)return!0;b.hasmoving=!0;b.preventclick&&!b.preventclick.click&&(b.preventclick.click=b.preventclick.tg.onclick||!1,b.preventclick.tg.onclick=
9513b.onpreventclick);d=e.extend({original:d},d);"changedTouches"in d&&(d.clientX=d.changedTouches[0].clientX,d.clientY=d.changedTouches[0].clientY);if(b.forcescreen){var f=d;d={original:d.original?d.original:d};d.clientX=f.screenX;d.clientY=f.screenY}f=ofy=0;if(t&&!c){var n=b.win.position(),f=-n.left;ofy=-n.top}var k=d.clientY+ofy,n=k-b.rail.drag.y,l=d.clientX+f,h=l-b.rail.drag.x,r=b.rail.drag.st-n;b.ishwscroll&&b.opt.bouncescroll?0>r?r=Math.round(r/2):r>b.page.maxh&&(r=b.page.maxh+Math.round((r-b.page.maxh)/
95142)):(0>r&&(k=r=0),r>b.page.maxh&&(r=b.page.maxh,k=0));if(b.railh&&b.railh.scrollable){var m=b.rail.drag.sl-h;b.ishwscroll&&b.opt.bouncescroll?0>m?m=Math.round(m/2):m>b.page.maxw&&(m=b.page.maxw+Math.round((m-b.page.maxw)/2)):(0>m&&(l=m=0),m>b.page.maxw&&(m=b.page.maxw,l=0))}f=!1;if(b.rail.drag.dl)f=!0,"v"==b.rail.drag.dl?m=b.rail.drag.sl:"h"==b.rail.drag.dl&&(r=b.rail.drag.st);else{var n=Math.abs(n),h=Math.abs(h),x=b.opt.directionlockdeadzone;if("v"==b.rail.drag.ck){if(n>x&&h<=0.3*n)return b.rail.drag=
9515!1,!0;h>x&&(b.rail.drag.dl="f",e("body").scrollTop(e("body").scrollTop()))}else if("h"==b.rail.drag.ck){if(h>x&&n<=0.3*h)return b.rail.drag=!1,!0;n>x&&(b.rail.drag.dl="f",e("body").scrollLeft(e("body").scrollLeft()))}}b.synched("touchmove",function(){b.rail.drag&&2==b.rail.drag.pt&&(b.prepareTransition&&b.prepareTransition(0),b.rail.scrollable&&b.setScrollTop(r),b.scrollmom.update(l,k),b.railh&&b.railh.scrollable?(b.setScrollLeft(m),b.showCursor(r,m)):b.showCursor(r),g.isie10&&document.selection.clear())});
9516g.ischrome&&b.istouchcapable&&(f=!1);if(f)return b.cancelEvent(d)}}}b.onmousedown=function(d,c){if(!(b.rail.drag&&1!=b.rail.drag.pt)){if(b.locked)return b.cancelEvent(d);b.cancelScroll();b.rail.drag={x:d.clientX,y:d.clientY,sx:b.scroll.x,sy:b.scroll.y,pt:1,hr:!!c};var f=b.getTarget(d);!b.ispage&&g.hasmousecapture&&f.setCapture();b.isiframe&&!g.hasmousecapture&&(b.saved.csspointerevents=b.doc.css("pointer-events"),b.css(b.doc,{"pointer-events":"none"}));return b.cancelEvent(d)}};b.onmouseup=function(d){if(b.rail.drag&&
9517(g.hasmousecapture&&document.releaseCapture(),b.isiframe&&!g.hasmousecapture&&b.doc.css("pointer-events",b.saved.csspointerevents),1==b.rail.drag.pt))return b.rail.drag=!1,b.cancelEvent(d)};b.onmousemove=function(d){if(b.rail.drag&&1==b.rail.drag.pt){if(g.ischrome&&0==d.which)return b.onmouseup(d);b.cursorfreezed=!0;if(b.rail.drag.hr){b.scroll.x=b.rail.drag.sx+(d.clientX-b.rail.drag.x);0>b.scroll.x&&(b.scroll.x=0);var c=b.scrollvaluemaxw;b.scroll.x>c&&(b.scroll.x=c)}else b.scroll.y=b.rail.drag.sy+
9518(d.clientY-b.rail.drag.y),0>b.scroll.y&&(b.scroll.y=0),c=b.scrollvaluemax,b.scroll.y>c&&(b.scroll.y=c);b.synched("mousemove",function(){b.rail.drag&&1==b.rail.drag.pt&&(b.showCursor(),b.rail.drag.hr?b.doScrollLeft(Math.round(b.scroll.x*b.scrollratio.x),b.opt.cursordragspeed):b.doScrollTop(Math.round(b.scroll.y*b.scrollratio.y),b.opt.cursordragspeed))});return b.cancelEvent(d)}};if(g.cantouch||b.opt.touchbehavior)b.onpreventclick=function(d){if(b.preventclick)return b.preventclick.tg.oncl
9518ick=b.preventclick.click,
9519b.preventclick=!1,b.cancelEvent(d)},b.bind(b.win,"mousedown",b.ontouchstart),b.onclick=g.isios?!1:function(d){return b.lastmouseup?(b.lastmouseup=!1,b.cancelEvent(d)):!0},b.opt.grabcursorenabled&&g.cursorgrabvalue&&(b.css(b.ispage?b.doc:b.win,{cursor:g.cursorgrabvalue}),b.css(b.rail,{cursor:g.cursorgrabvalue}));else{var p=function(d){if(b.selectiondrag){if(d){var c=b.win.outerHeight();d=d.pageY-b.selectiondrag.top;0<d&&d<c&&(d=0);d>=c&&(d-=c);b.selectiondrag.df=d}0!=b.selectiondrag.df&&(b.doScrollBy(2*
9520-Math.floor(b.selectiondrag.df/6)),b.debounced("doselectionscroll",function(){p()},50))}};b.hasTextSelected="getSelection"in document?function(){return 0<document.getSelection().rangeCount}:"selection"in document?function(){return"None"!=document.selection.type}:function(){return!1};b.onselectionstart=function(d){b.ispage||(b.selectiondrag=b.win.offset())};b.onselectionend=function(d){b.selectiondrag=!1};b.onselectiondrag=function(d){b.selectiondrag&&b.hasTextSelected()&&b.debounced("selectionscroll",
9521function(){p(d)},250)}}g.hasmstouch&&(b.css(b.rail,{"-ms-touch-action":"none"}),b.css(b.cursor,{"-ms-touch-action":"none"}),b.bind(b.win,"MSPointerDown",b.ontouchstart),b.bind(document,"MSPointerUp",b.ontouchend),b.bind(document,"MSPointerMove",b.ontouchmove),b.bind(b.cursor,"MSGestureHold",function(b){b.preventDefault()}),b.bind(b.cursor,"contextmenu",function(b){b.preventDefault()}));this.istouchcapable&&(b.bind(b.win,"touchstart",b.ontouchstart),b.bind(document,"touchend",b.ontouchend),b.bind(document,
9522"touchcancel",b.ontouchend),b.bind(document,"touchmove",b.ontouchmove));b.bind(b.cursor,"mousedown",b.onmousedown);b.bind(b.cursor,"mouseup",b.onmouseup);b.railh&&(b.bind(b.cursorh,"mousedown",function(d){b.onmousedown(d,!0)}),b.bind(b.cursorh,"mouseup",function(d){if(!(b.rail.drag&&2==b.rail.drag.pt))return b.rail.drag=!1,b.hasmoving=!1,b.hideCursor(),g.hasmousecapture&&document.releaseCapture(),b.cancelEvent(d)}));if(b.opt.cursordragontouch||!g.cantouch&&!b.opt.touchbehavior)b.rail.css({cursor:"default"}),
9523b.railh&&b.railh.css({cursor:"default"}),b.jqbind(b.rail,"mouseenter",function(){b.canshowonmouseevent&&b.showCursor();b.rail.active=!0}),b.jqbind(b.rail,"mouseleave",function(){b.rail.active=!1;b.rail.drag||b.hideCursor()}),b.opt.sensitiverail&&(b.bind(b.rail,"click",function(d){b.doRailClick(d,!1,!1)}),b.bind(b.rail,"dblclick",function(d){b.doRailClick(d,!0,!1)}),b.bind(b.cursor,"click",function(d){b.cancelEvent(d)}),b.bind(b.cursor,"dblclick",function(d){b.cancelEvent(d)})),b.railh&&(b.jqbind(b.railh,
9524"mouseenter",function(){b.canshowonmouseevent&&b.showCursor();b.rail.active=!0}),b.jqbind(b.railh,"mouseleave",function(){b.rail.active=!1;b.rail.drag||b.hideCursor()}),b.opt.sensitiverail&&(b.bind(b.railh,"click",function(d){b.doRailClick(d,!1,!0)}),b.bind(b.railh,"dblclick",function(d){b.doRailClick(d,!0,!0)}),b.bind(b.cursorh,"click",function(d){b.cancelEvent(d)}),b.bind(b.cursorh,"dblclick",function(d){b.cancelEvent(d)})));!g.cantouch&&!b.opt.touchbehavior?(b.bind(g.hasmousecapture?b.win:document,
9525"mouseup",b.onmouseup),b.bind(document,"mousemove",b.onmousemove),b.onclick&&b.bind(document,"click",b.onclick),!b.ispage&&b.opt.enablescrollonselection&&(b.bind(b.win[0],"mousedown",b.onselectionstart),b.bind(document,"mouseup",b.onselectionend),b.bind(b.cursor,"mouseup",b.onselectionend),b.cursorh&&b.bind(b.cursorh,"mouseup",b.onselectionend),b.bind(document,"mousemove",b.onselectiondrag)),b.zoom&&(b.jqbind(b.zoom,"mouseenter",function(){b.canshowonmouseevent&&b.showCursor();b.rail.active=!0}),
9526b.jqbind(b.zoom,"mouseleave",function(){b.rail.active=!1;b.rail.drag||b.hideCursor()}))):(b.bind(g.hasmousecapture?b.win:document,"mouseup",b.ontouchend),b.bind(document,"mousemove",b.ontouchmove),b.onclick&&b.bind(document,"click",b.onclick),b.opt.cursordragontouch&&(b.bind(b.cursor,"mousedown",b.onmousedown),b.bind(b.cursor,"mousemove",b.onmousemove),b.cursorh&&b.bind(b.cursorh,"mousedown",function(d){b.onmousedown(d,!0)}),b.cursorh&&b.bind(b.cursorh,"mousemove",b.onmousemove)));b.opt.enablemousewheel&&
9527(b.isiframe||b.bind(g.isie&&b.ispage?document:b.win,"mousewheel",b.onmousewheel),b.bind(b.rail,"mousewheel",b.onmousewheel),b.railh&&b.bind(b.railh,"mousewheel",b.onmousewheelhr));!b.ispage&&(!g.cantouch&&!/HTML|BODY/.test(b.win[0].nodeName))&&(b.win.attr("tabindex")||b.win.attr({tabindex:L++}),b.jqbind(b.win,"focus",function(d){z=b.getTarget(d).id||!0;b.hasfocus=!0;b.canshowonmouseevent&&b.noticeCursor()}),b.jqbind(b.win,"blur",function(d){z=!1;b.hasfocus=!1}),b.jqbind(b.win,"mouseenter",function(d){E=
9528b.getTarget(d).id||!0;b.hasmousefocus=!0;b.canshowonmouseevent&&b.noticeCursor()}),b.jqbind(b.win,"mouseleave",function(){E=!1;b.hasmousefocus=!1;b.rail.drag||b.hideCursor()}))}b.onkeypress=function(d){if(b.locked&&0==b.page.maxh)return!0;d=d?d:window.e;var c=b.getTarget(d);if(c&&/INPUT|TEXTAREA|SELECT|OPTION/.test(c.nodeName)&&(!c.getAttribute("type")&&!c.type||!/submit|button|cancel/i.tp))return!0;
9528if(b.hasfocus||b.hasmousefocus&&!z||b.ispage&&!z&&!E){c=d.keyCode;if(b.locked&&27!=c)return b.cancelEvent(d);
9529var f=d.ctrlKey||!1,n=d.shiftKey||!1,g=!1;switch(c){case 38:case 63233:b.doScrollBy(72);g=!0;break;case 40:case 63235:b.doScrollBy(-72);g=!0;break;case 37:case 63232:b.railh&&(f?b.doScrollLeft(0):b.doScrollLeftBy(72),g=!0);break;case 39:case 63234:b.railh&&(f?b.doScrollLeft(b.page.maxw):b.doScrollLeftBy(-72),g=!0);break;case 33:case 63276:b.doScrollBy(b.view.h);g=!0;break;case 34:case 63277:b.doScrollBy(-b.view.h);g=!0;break;case 36:case 63273:b.railh&&f?b.doScrollPos(0,0):b.doScrollTo(0);g=!0;break;
9530case 35:case 63275:b.railh&&f?b.doScrollPos(b.page.maxw,b.page.maxh):b.doScrollTo(b.page.maxh);g=!0;break;case 32:b.opt.spacebarenabled&&(n?b.doScrollBy(b.view.h):b.doScrollBy(-b.view.h),g=!0);break;case 27:b.zoomactive&&(b.doZoom(),g=!0)}if(g)return b.cancelEvent(d)}};b.opt.enablekeyboard&&b.bind(document,g.isopera&&!g.isopera12?"keypress":"keydown",b.onkeypress);b.bind(window,"resize",b.lazyResize);b.bind(window,"orientationchange",b.lazyResize);b.bind(window,"load",b.lazyResize);if(g.ischrome&&
9531!b.ispage&&!b.haswrapper){var s=b.win.attr("style"),f=parseFloat(b.win.css("width"))+1;b.win.css("width",f);b.synched("chromefix",function(){b.win.attr("style",s)})}b.onAttributeChange=function(d){b.lazyResize(250)};!b.ispage&&!b.haswrapper&&(!1!==A?(b.observer=new A(function(d){d.forEach(b.onAttributeChange)}),b.observer.observe(b.win[0],{childList:!0,characterData:!1,attributes:!0,subtree:!1}),b.observerremover=new A(function(d){d.forEach(function(d){if(0<d.removedNodes.length)for(var c in d.removedNodes)if(d.removedNodes[c]==
9532b.win[0])return b.remove()})}),b.observerremover.observe(b.win[0].parentNode,{childList:!0,characterData:!1,attributes:!1,subtree:!1})):(b.bind(b.win,g.isie&&!g.isie9?"propertychange":"DOMAttrModified",b.onAttributeChange),g.isie9&&b.win[0].attachEvent("onpropertychange",b.onAttributeChange),b.bind(b.win,"DOMNodeRemoved",function(d){d.target==b.win[0]&&b.remove()})));!b.ispage&&b.opt.boxzoom&&b.bind(window,"resize",b.resizeZoom);b.istextarea&&b.bind(b.win,"mouseup",b.lazyResize);b.checkrtlmode=!0;
9533b.lazyResize(30)}if("IFRAME"==this.doc[0].nodeName){var K=function(d){b.iframexd=!1;try{var c="contentDocument"in this?this.contentDocument:this.contentWindow.document}catch(f){b.iframexd=!0,c=!1}if(b.iframexd)return"console"in window&&console.log("NiceScroll error: policy restriced iframe"),!0;b.forcescreen=!0;b.isiframe&&(b.iframe={doc:e(c),html:b.doc.contents().find("html")[0],body:b.doc.contents().find("body")[0]},b.getContentSize=function(){return{w:Math.max(b.iframe.html.scrollWidth,b.iframe.body.scrollWidth),
9534h:Math.max(b.iframe.html.scrollHeight,b.iframe.body.scrollHeight)}},b.docscroll=e(b.iframe.body));!g.isios&&(b.opt.iframeautoresize&&!b.isiframe)&&(b.win.scrollTop(0),b.doc.height(""),d=Math.max(c.getElementsByTagName("html")[0].scrollHeight,c.body.scrollHeight),b.doc.height(d));b.lazyResize(30);g.isie7&&b.css(e(b.iframe.html),{"overflow-y":"hidden"});b.css(e(b.iframe.body),{"overflow-y":"hidden"});g.isios&&b.haswrapper&&b.css(e(c.body),{"-webkit-transform":"translate3d(0,0,0)"});"contentWindow"in
9535this?b.bind(this.contentWindow,"scroll",b.onscroll):b.bind(c,"scroll",b.onscroll);b.opt.enablemousewheel&&b.bind(c,"mousewheel",b.onmousewheel);b.opt.enablekeyboard&&b.bind(c,g.isopera?"keypress":"keydown",b.onkeypress);if(g.cantouch||b.opt.touchbehavior)b.bind(c,"mousedown",b.ontouchstart),b.bind(c,"mousemove",function(d){b.ontouchmove(d,!0)}),b.opt.grabcursorenabled&&g.cursorgrabvalue&&b.css(e(c.body),{cursor:g.cursorgrabvalue});b.bind(c,"mouseup",b.ontouchend);b.zoom&&(b.opt.dblclickzoom&&b.bind(c,
9536"dblclick",b.doZoom),b.ongesturezoom&&b.bind(c,"gestureend",b.ongesturezoom))};this.doc[0].readyState&&"complete"==this.doc[0].readyState&&setTimeout(function(){K.call(b.doc[0],!1)},500);b.bind(this.doc,"load",K)}};this.showCursor=function(d,c){b.cursortimeout&&(clearTimeout(b.cursortimeout),b.cursortimeout=0);if(b.rail){b.autohidedom&&(b.autohidedom.stop().css({opacity:b.opt.cursoropacitymax}),b.cursoractive=!0);if(!b.rail.drag||1!=b.rail.drag.pt)"undefined"!=typeof d&&!1!==d&&(b.scroll.y=Math.round(1*
9537d/b.scrollratio.y)),"undefined"!=typeof c&&(b.scroll.x=Math.round(1*c/b.scrollratio.x));b.cursor.css({height:b.cursorheight,top:b.scroll.y});b.cursorh&&(!b.rail.align&&b.rail.visibility?b.cursorh.css({width:b.cursorwidth,left:b.scroll.x+b.rail.width}):b.cursorh.css({width:b.cursorwidth,left:b.scroll.x}),b.cursoractive=!0);b.zoom&&b.zoom.stop().css({opacity:b.opt.cursoropacitymax})}};this.hideCursor=function(d){!b.cursortimeout&&(b.rail&&b.autohidedom&&!(b.hasmousefocus&&"leave"==b.opt.autohidemode))&&
9538(b.cursortimeout=setTimeout(function(){if(!b.rail.active||!b.showonmouseevent)b.autohidedom.stop().animate({opacity:b.opt.cursoropacitymin}),b.zoom&&b.zoom.stop().animate({opacity:b.opt.cursoropacitymin}),b.cursoractive=!1;
9538b.cursortimeout=0},d||b.opt.hidecursordelay))};this.noticeCursor=function(d,c,f){b.showCursor(c,f);b.rail.active||b.hideCursor(d)};this.getContentSize=b.ispage?function(){return{w:Math.max(document.body.scrollWidth,document.documentElement.scrollWidth),h:Math.max(document.body.scrollHeight,
9539document.documentElement.scrollHeight)}}:b.haswrapper?function(){return{w:b.doc.outerWidth()+parseInt(b.win.css("paddingLeft"))+parseInt(b.win.css("paddingRight")),h:b.doc.outerHeight()+parseInt(b.win.css("paddingTop"))+parseInt(b.win.css("paddingBottom"))}}:function(){return{w:b.docscroll[0].scrollWidth,h:b.docscroll[0].scrollHeight}};this.onResize=function(d,c){if(!b.win)return!1;if(!b.haswrapper&&!b.ispage){if("none"==b.win.css("display"))return b.visibility&&b.hideRail().hideRailHr(),!1;!b.hidden&&
9540!b.visibility&&b.showRail().showRailHr()}var f=b.page.maxh,g=b.page.maxw,e=b.view.w;b.view={w:b.ispage?b.win.width():parseInt(b.win[0].clientWidth),h:b.ispage?b.win.height():parseInt(b.win[0].clientHeight)};b.page=c?c:b.getContentSize();b.page.maxh=Math.max(0,b.page.h-b.view.h);b.page.maxw=Math.max(0,b.page.w-b.view.w);if(b.page.maxh==f&&b.page.maxw==g&&b.view.w==e){if(b.ispage)return b;f=b.win.offset();if(b.lastposition&&(g=b.lastposition,g.top==f.top&&g.left==f.left))return b;b.lastposition=f}0==
9541b.page.maxh?(b.hideRail(),b.scrollvaluemax=0,b.scroll.y=0,b.scrollratio.y=0,b.cursorheight=0,b.setScrollTop(0),b.rail.scrollable=!1):b.rail.scrollable=!0;0==b.page.maxw?(b.hideRailHr(),b.scrollvaluemaxw=0,b.scroll.x=0,b.scrollratio.x=0,b.cursorwidth=0,b.setScrollLeft(0),b.railh.scrollable=!1):b.railh.scrollable=!0;b.locked=0==b.page.maxh&&0==b.page.maxw;if(b.locked)return b.ispage||b.updateScrollBar(b.view),!1;!b.hidden&&!b.visibility?b.showRail().showRailHr():!b.hidden&&!b.railh.visibility&&b.showRailHr();
9542b.istextarea&&(b.win.css("resize")&&"none"!=b.win.css("resize"))&&(b.view.h-=20);b.cursorheight=Math.min(b.view.h,Math.round(b.view.h*(b.view.h/b.page.h)));b.cursorheight=b.opt.cursorfixedheight?b.opt.cursorfixedheight:Math.max(b.opt.cursorminheight,b.cursorheight);b.cursorwidth=Math.min(b.view.w,Math.round(b.view.w*(b.view.w/b.page.w)));b.cursorwidth=b.opt.cursorfixedheight?b.opt.cursorfixedheight:Math.max(b.opt.cursorminheight,b.cursorwidth);b.scrollvaluemax=b.view.h-b.cursorheight-b.cursor.hborder;
9543b.railh&&(b.railh.width=0<b.page.maxh?b.view.w-b.rail.width:b.view.w,b.scrollvaluemaxw=b.railh.width-b.cursorwidth-b.cursorh.wborder);b.checkrtlmode&&b.railh&&(b.checkrtlmode=!1,b.opt.rtlmode&&0==b.scroll.x&&b.setScrollLeft(b.page.maxw));b.ispage||b.updateScrollBar(b.view);b.scrollratio={x:b.page.maxw/b.scrollvaluemaxw,y:b.page.maxh/b.scrollvaluemax};b.getScrollTop()>b.page.maxh?b.doScrollTop(b.page.maxh):(b.scroll.y=Math.round(b.getScrollTop()*(1/b.scrollratio.y)),b.scroll.x=Math.round(b.getScrollLeft()*
9544(1/b.scrollratio.x)),b.cursoractive&&b.noticeCursor());b.scroll.y&&0==b.getScrollTop()&&b.doScrollTo(Math.floor(b.scroll.y*b.scrollratio.y));return b};this.resize=b.onResize;this.lazyResize=function(d){d=isNaN(d)?30:d;b.delayed("resize",b.resize,d);return b};this._bind=function(d,c,f,g){b.events.push({e:d,n:c,f:f,b:g,q:!1});d.addEventListener?d.addEventListener(c,f,g||!1):d.attachEvent?d.attachEvent("on"+c,f):d["on"+c]=f};this.jqbind=function(d,c,f){b.events.push({e:d,n:c,f:f,q:!0});e(d).bind(c,f)};
9545this.bind=function(d,c,f,e){var k="jquery"in d?d[0]:d;"mousewheel"==c?"onwheel"in b.win?b._bind(k,"wheel",f,e||!1):(d="undefined"!=typeof document.onmousewheel?"mousewheel":"DOMMouseScroll",q(k,d,f,e||!1),"DOMMouseScroll"==d&&q(k,"MozMousePixelScroll",f,e||!1)):k.addEventListener?(g.cantouch&&/mouseup|mousedown|mousemove/.test(c)&&b._bind(k,"mousedown"==c?"touchstart":"mouseup"==c?"touchend":"touchmove",function(b){if(b.touches){if(2>b.touches.length){var d=b.touches.length?b.touches[0]:b;d.original=
9546b;f.call(this,d)}}else b.changedTouches&&(d=b.changedTouches[0],d.original=b,f.call(this,d))},e||!1),b._bind(k,c,f,e||!1),g.cantouch&&"mouseup"==c&&b._bind(k,"touchcancel",f,e||!1)):b._bind(k,c,function(d){if((d=d||window.event||!1)&&d.srcElement)d.target=d.srcElement;"pageY"in d||(d.pageX=d.clientX+document.documentElement.scrollLeft,d.pageY=d.clientY+document.documentElement.scrollTop);return!1===f.call(k,d)||!1===e?b.cancelEvent(d):!0})};this._unbind=function(b,c,f,g){b.removeEventListener?b.removeEventListener(c,
9547f,g):b.detachEvent?b.detachEvent("on"+c,f):b["on"+c]=!1};this.unbindAll=function(){for(var d=0;d<b.events.length;d++){var c=b.events[d];c.q?c.e.unbind(c.n,c.f):b._unbind(c.e,c.n,c.f,c.b)}};this.cancelEvent=function(b){b=b.original?b.original:b?b:window.event||!1;if(!b)return!1;b.preventDefault&&b.preventDefault();b.stopPropagation&&b.stopPropagation();b.preventManipulation&&b.preventManipulation();b.cancelBubble=!0;b.cancel=!0;return b.returnValue=!1};this.stopPropagation=function(b){b=b.original?
9548b.original:b?b:window.event||!1;if(!b)return!1;if(b.stopPropagation)return b.stopPropagation();b.cancelBubble&&(b.cancelBubble=!0);return!1};this.showRail=function(){if(0!=b.page.maxh&&(b.ispage||"none"!=b.win.css("display")))b.visibility=!0,b.rail.visibility=!0,b.rail.css("display","block");return b};this.showRailHr=function(){if(!b.railh)return b;if(0!=b.page.maxw&&(b.ispage||"none"!=b.win.css("display")))b.railh.visibility=!0,b.railh.css("display","block");return b};this.hideRail=function(){b.visibility=
9549!1;b.rail.visibility=!1;b.rail.css("display","none");return b};this.hideRailHr=function(){if(!b.railh)return b;b.railh.visibility=!1;b.railh.css("display","none");return b};this.show=function(){b.hidden=!1;b.locked=!1;return b.showRail().showRailHr()};this.hide=function(){b.hidden=!0;b.locked=!0;return b.hideRail().hideRailHr()};this.toggle=function(){return b.hidden?b.show():b.hide()};this.remove=function(){b.stop();b.cursortimeout&&clearTimeout(b.cursortimeout);b.doZoomOut();b.unbindAll();g.isie9&&
9550b.win[0].detachEvent("onpropertychange",b.onAttributeChange);!1!==b.observer&&b.observer.disconnect();!1!==b.observerremover&&b.observerremover.disconnect();b.events=null;b.cursor&&b.cursor.remove();b.cursorh&&b.cursorh.remove();b.rail&&b.rail.remove();b.railh&&b.railh.remove();b.zoom&&b.zoom.remove();for(var d=0;d<b.saved.css.length;d++){var c=b.saved.css[d];c[0].css(c[1],"undefined"==typeof c[2]?"":c[2])}b.saved=!1;b.me.data("__nicescroll","");var f=e.nicescroll;f.each(function(d){if(this&&this.id===
9551b.id){delete f[d];for(var c=++d;c<f.length;c++,d++)f[d]=f[c];f.length--;f.length&&delete f[f.length]}});for(var k in b)b[k]=null,delete b[k];b=null};this.scrollstart=function(d){this.onscrollstart=d;return b};this.scrollend=function(d){this.onscrollend=d;return b};this.scrollcancel=function(d){this.onscrollcancel=d;return b};this.zoomin=function(d){this.onzoomin=d;return b};this.zoomout=function(d){this.onzoomout=d;return b};this.isScrollable=function(b){b=b.target?b.target:b;if("OPTION"==b.nodeName)return!0;
9552for(;b&&1==b.nodeType&&!/BODY|HTML/.test(b.nodeName);){var c=e(b),c=c.css("overflowY")||c.css("overflowX")||c.css("overflow")||"";if(/scroll|auto/.test(c))return b.clientHeight!=b.scrollHeight;b=b.parentNode?b.parentNode:!1}return!1};this.getViewport=function(b){for(b=b&&b.parentNode?b.parentNode:!1;b&&1==b.nodeType&&!/BODY|HTML/.test(b.nodeName);){var c=e(b);
9552if(/fixed|absolute/.test(c.css("position")))return c;var f=c.css("overflowY")||c.css("overflowX")||c.css("overflow")||"";if(/scroll|auto/.test(f)&&
9553b.clientHeight!=b.scrollHeight||0<c.getNiceScroll().length)return c;b=b.parentNode?b.parentNode:!1}return!1};this.onmousewheel=function(d){if(b.locked)return b.debounced("checkunlock",b.resize,250),!0;if(b.rail.drag)return b.cancelEvent(d);"auto"==b.opt.oneaxismousemode&&0!=d.deltaX&&(b.opt.oneaxismousemode=!1);if(b.opt.oneaxismousemode&&0==d.deltaX&&!b.rail.scrollable)return b.railh&&b.railh.scrollable?b.onmousewheelhr(d):!0;var c=+new Date,f=!1;b.opt.preservenativescrolling&&b.checkarea+600<c&&
9554(b.nativescrollingarea=b.isScrollable(d),f=!0);b.checkarea=c;if(b.nativescrollingarea)return!0;if(d=t(d,!1,f))b.checkarea=0;return d};this.onmousewheelhr=function(d){if(b.locked||!b.railh.scrollable)return!0;if(b.rail.drag)return b.cancelEvent(d);var c=+new Date,f=!1;b.opt.preservenativescrolling&&b.checkarea+600<c&&(b.nativescrollingarea=b.isScrollable(d),f=!0);b.checkarea=c;return b.nativescrollingarea?!0:b.locked?b.cancelEvent(d):t(d,!0,f)};this.stop=function(){b.cancelScroll();b.scrollmon&&b.scrollmon.stop();
9555b.cursorfreezed=!1;b.scroll.y=Math.round(b.getScrollTop()*(1/b.scrollratio.y));b.noticeCursor();return b};this.getTransitionSpeed=function(d){var c=Math.round(10*b.opt.scrollspeed);d=Math.min(c,Math.round(d/20*b.opt.scrollspeed));return 20<d?d:0};b.opt.smoothscroll?b.ishwscroll&&g.hastransition&&b.opt.usetransition?(this.prepareTransition=function(d,c){var f=c?20<d?d:0:b.getTransitionSpeed(d),e=f?g.prefixstyle+"transform "+f+"ms ease-out":"";if(!b.lasttransitionstyle||b.lasttransitionstyle!=e)b.lasttransitionstyle=
9556e,b.doc.css(g.transitionstyle,e);return f},this.doScrollLeft=function(c,g){var f=b.scrollrunning?b.newscrolly:b.getScrollTop();b.doScrollPos(c,f,g)},this.doScrollTop=function(c,g){var f=b.scrollrunning?b.newscrollx:b.getScrollLeft();b.doScrollPos(f,c,g)},this.doScrollPos=function(c,e,f){var k=b.getScrollTop(),l=b.getScrollLeft();(0>(b.newscrolly-k)*(e-k)||0>(b.newscrollx-l)*(c-l))&&b.cancelScroll();!1==b.opt.bouncescroll&&(0>e?e=0:e>b.page.maxh&&(e=b.page.maxh),0>c?c=0:c>b.page.maxw&&(c=b.page.maxw));
9557if(b.scrollrunning&&c==b.newscrollx&&e==b.newscrolly)return!1;b.newscrolly=e;b.newscrollx=c;b.newscrollspeed=f||!1;if(b.timer)return!1;b.timer=setTimeout(function(){var f=b.getScrollTop(),k=b.getScrollLeft(),l,h;l=c-k;h=e-f;l=Math.round(Math.sqrt(Math.pow(l,2)+Math.pow(h,2)));l=b.newscrollspeed&&1<b.newscrollspeed?b.newscrollspeed:b.getTransitionSpeed(l);b.newscrollspeed&&1>=b.newscrollspeed&&(l*=b.newscrollspeed);b.prepareTransition(l,!0);b.timerscroll&&b.timerscroll.tm&&clearInterval(b.timerscroll.tm);
95580<l&&(!b.scrollrunning&&b.onscrollstart&&b.onscrollstart.call(b,{type:"scrollstart",current:{x:k,y:f},request:{x:c,y:e},end:{x:b.newscrollx,y:b.newscrolly},speed:l}),g.transitionend?b.scrollendtrapped||(b.scrollendtrapped=!0,b.bind(b.doc,g.transitionend,b.onScrollEnd,!1)):(b.scrollendtrapped&&clearTimeout(b.scrollendtrapped),b.scrollendtrapped=setTimeout(b.onScrollEnd,l)),b.timerscroll={bz:new BezierClass(f,b.newscrolly,l,0,0,0.58,1),bh:new BezierClass(k,b.newscrollx,l,0,0,0.58,1)},b.cursorfreezed||
9559(b.timerscroll.tm=setInterval(function(){b.showCursor(b.getScrollTop(),b.getScrollLeft())},60)));b.synched("doScroll-set",function(){b.timer=0;b.scrollendtrapped&&(b.scrollrunning=!0);b.setScrollTop(b.newscrolly);b.setScrollLeft(b.newscrollx);if(!b.scrollendtrapped)b.onScrollEnd()})},50)},this.cancelScroll=function(){if(!b.scrollendtrapped)return!0;var c=b.getScrollTop(),e=b.getScrollLeft();b.scrollrunning=!1;g.transitionend||clearTimeout(g.transitionend);b.scrollendtrapped=!1;b._unbind(b.doc,g.transitionend,
9560b.onScrollEnd);b.prepareTransition(0);b.setScrollTop(c);b.railh&&b.setScrollLeft(e);b.timerscroll&&b.timerscroll.tm&&clearInterval(b.timerscroll.tm);b.timerscroll=!1;b.cursorfreezed=!1;b.showCursor(c,e);return b},this.onScrollEnd=function(){b.scrollendtrapped&&b._unbind(b.doc,g.transitionend,b.onScrollEnd);b.scrollendtrapped=!1;b.prepareTransition(0);b.timerscroll&&b.timerscroll.tm&&clearInterval(b.timerscroll.tm);b.timerscroll=!1;var c=b.getScrollTop(),e=b.getScrollLeft();b.setScrollTop(c);b.railh&&
9561b.setScrollLeft(e);b.noticeCursor(!1,c,e);
9561b.cursorfreezed=!1;0>c?c=0:c>b.page.maxh&&(c=b.page.maxh);0>e?e=0:e>b.page.maxw&&(e=b.page.maxw);if(c!=b.newscrolly||e!=b.newscrollx)return b.doScrollPos(e,c,b.opt.snapbackspeed);b.onscrollend&&b.scrollrunning&&b.onscrollend.call(b,{type:"scrollend",current:{x:e,y:c},end:{x:b.newscrollx,y:b.newscrolly}});b.scrollrunning=!1}):(this.doScrollLeft=function(c,g){var f=b.scrollrunning?b.newscrolly:b.getScrollTop();b.doScrollPos(c,f,g)},this.doScrollTop=function(c,
9562g){var f=b.scrollrunning?b.newscrollx:b.getScrollLeft();b.doScrollPos(f,c,g)},this.doScrollPos=function(c,g,f){function e(){if(b.cancelAnimationFrame)return!0;b.scrollrunning=!0;if(p=1-p)return b.timer=v(e)||1;var c=0,d=sy=b.getScrollTop();if(b.dst.ay){var d=b.bzscroll?b.dst.py+b.bzscroll.getNow()*b.dst.ay:b.newscrolly,f=d-sy;if(0>f&&d<b.newscrolly||0<f&&d>b.newscrolly)d=b.newscrolly;b.setScrollTop(d);d==b.newscrolly&&(c=1)}else c=1;var g=sx=b.getScrollLeft();if(b.dst.ax){g=b.bzscroll?b.dst.px+b.bzscroll.getNow()*
9563b.dst.ax:b.newscrollx;f=g-sx;if(0>f&&g<b.newscrollx||0<f&&g>b.newscrollx)g=b.newscrollx;b.setScrollLeft(g);g==b.newscrollx&&(c+=1)}else c+=1;2==c?(b.timer=0,b.cursorfreezed=!1,b.bzscroll=!1,b.scrollrunning=!1,0>d?d=0:d>b.page.maxh&&(d=b.page.maxh),0>g?g=0:g>b.page.maxw&&(g=b.page.maxw),g!=b.newscrollx||d!=b.newscrolly?b.doScrollPos(g,d):b.onscrollend&&b.onscrollend.call(b,{type:"scrollend",current:{x:sx,y:sy},end:{x:b.newscrollx,y:b.newscrolly}})):b.timer=v(e)||1}g="undefined"==typeof g||!1===g?b.getScrollTop(!0):
9564g;if(b.timer&&b.newscrolly==g&&b.newscrollx==c)return!0;b.timer&&w(b.timer);b.timer=0;var k=b.getScrollTop(),l=b.getScrollLeft();(0>(b.newscrolly-k)*(g-k)||0>(b.newscrollx-l)*(c-l))&&b.cancelScroll();b.newscrolly=g;b.newscrollx=c;if(!b.bouncescroll||!b.rail.visibility)0>b.newscrolly?b.newscrolly=0:b.newscrolly>b.page.maxh&&(b.newscrolly=b.page.maxh);if(!b.bouncescroll||!b.railh.visibility)0>b.newscrollx?b.newscrollx=0:b.newscrollx>b.page.maxw&&(b.newscrollx=b.page.maxw);b.dst={};b.dst.x=c-l;b.dst.y=
9565g-k;b.dst.px=l;b.dst.py=k;var h=Math.round(Math.sqrt(Math.pow(b.dst.x,2)+Math.pow(b.dst.y,2)));b.dst.ax=b.dst.x/h;b.dst.ay=b.dst.y/h;var m=0,q=h;0==b.dst.x?(m=k,q=g,b.dst.ay=1,b.dst.py=0):0==b.dst.y&&(m=l,q=c,b.dst.ax=1,b.dst.px=0);h=b.getTransitionSpeed(h);f&&1>=f&&(h*=f);b.bzscroll=0<h?b.bzscroll?b.bzscroll.update(q,h):new BezierClass(m,q,h,0,1,0,1):!1;if(!b.timer){(k==b.page.maxh&&g>=b.page.maxh||l==b.page.maxw&&c>=b.page.maxw)&&b.checkContentSize();var p=1;b.cancelAnimationFrame=!1;b.timer=1;
9566b.onscrollstart&&!b.scrollrunning&&b.onscrollstart.call(b,{type:"scrollstart",current:{x:l,y:k},request:{x:c,y:g},end:{x:b.newscrollx,y:b.newscrolly},speed:h});e();(k==b.page.maxh&&g>=k||l==b.page.maxw&&c>=l)&&b.checkContentSize();b.noticeCursor()}},this.cancelScroll=function(){b.timer&&w(b.timer);b.timer=0;b.bzscroll=!1;b.scrollrunning=!1;return b}):(this.doScrollLeft=function(c,g){var f=b.getScrollTop();b.doScrollPos(c,f,g)},this.doScrollTop=function(c,g){var f=b.getScrollLeft();b.doScrollPos(f,
9567c,g)},this.doScrollPos=function(c,g,f){var e=c>b.page.maxw?b.page.maxw:c;0>e&&(e=0);var k=g>b.page.maxh?b.page.maxh:g;0>k&&(k=0);b.synched("scroll",function(){b.setScrollTop(k);b.setScrollLeft(e)})},this.cancelScroll=function(){});this.doScrollBy=function(c,g){var f=0,f=g?Math.floor((b.scroll.y-c)*b.scrollratio.y):(b.timer?b.newscrolly:b.getScrollTop(!0))-c;if(b.bouncescroll){var e=Math.round(b.view.h/2);f<-e?f=-e:f>b.page.maxh+e&&(f=b.page.maxh+e)}b.cursorfreezed=!1;py=b.getScrollTop(!0);if(0>f&&
95680>=py)return b.noticeCursor();if(f>b.page.maxh&&py>=b.page.maxh)return b.checkContentSize(),b.noticeCursor();b.doScrollTop(f)};this.doScrollLeftBy=function(c,g){var f=0,f=g?Math.floor((b.scroll.x-c)*b.scrollratio.x):(b.timer?b.newscrollx:b.getScrollLeft(!0))-c;if(b.bouncescroll){var e=Math.round(b.view.w/2);f<-e?f=-e:f>b.page.maxw+e&&(f=b.page.maxw+e)}b.cursorfreezed=!1;px=b.getScrollLeft(!0);if(0>f&&0>=px||f>b.page.maxw&&px>=b.page.maxw)return b.noticeCursor();b.doScrollLeft(f)};this.doScrollTo=
9569function(c,g){g&&Math.round(c*b.scrollratio.y);b.cursorfreezed=!1;b.doScrollTop(c)};this.checkContentSize=function(){var c=b.getContentSize();(c.h!=b.page.h||c.w!=b.page.w)&&b.resize(!1,c)};b.onscroll=function(c){b.rail.drag||b.cursorfreezed||b.synched("scroll",function(){b.scroll.y=Math.round(b.getScrollTop()*(1/b.scrollratio.y));b.railh&&(b.scroll.x=Math.round(b.getScrollLeft()*(1/b.scrollratio.x)));b.noticeCursor()})};
9569b.bind(b.docscroll,"scroll",b.onscroll);this.doZoomIn=function(c){if(!b.zoomactive){b.zoomactive=
9570!0;b.zoomrestore={style:{}};var k="position top left zIndex backgroundColor marginTop marginBottom marginLeft marginRight".split(" "),f=b.win[0].style,l;for(l in k){var h=k[l];b.zoomrestore.style[h]="undefined"!=typeof f[h]?f[h]:""}b.zoomrestore.style.width=b.win.css("width");b.zoomrestore.style.height=b.win.css("height");b.zoomrestore.padding={w:b.win.outerWidth()-b.win.width(),h:b.win.outerHeight()-b.win.height()};g.isios4&&(b.zoomrestore.scrollTop=e(window).scrollTop(),e(window).scrollTop(0));
9571b.win.css({position:g.isios4?"absolute":"fixed",top:0,left:0,"z-index":y+100,margin:"0px"});k=b.win.css("backgroundColor");(""==k||/transparent|rgba\(0, 0, 0, 0\)|rgba\(0,0,0,0\)/.test(k))&&b.win.css("backgroundColor","#fff");b.rail.css({"z-index":y+101});b.zoom.css({"z-index":y+102});b.zoom.css("backgroundPosition","0px -18px");b.resizeZoom();b.onzoomin&&b.onzoomin.call(b);return b.cancelEvent(c)}};this.doZoomOut=function(c){if(b.zoomactive)return b.zoomactive=!1,b.win.css("margin",""),b.win.css(b.zoomrestore.style),
9572g.isios4&&e(window).scrollTop(b.zoomrestore.scrollTop),b.rail.css({"z-index":b.zindex}),b.zoom.css({"z-index":b.zindex}),b.zoomrestore=!1,b.zoom.css("backgroundPosition","0px 0px"),b.onResize(),b.onzoomout&&b.onzoomout.call(b),b.cancelEvent(c)};this.doZoom=function(c){return b.zoomactive?b.doZoomOut(c):b.doZoomIn(c)};this.resizeZoom=function(){if(b.zoomactive){var c=b.getScrollTop();b.win.css({width:e(window).width()-b.zoomrestore.padding.w+"px",height:e(window).height()-b.zoomrestore.padding.h+"px"});
9573b.onResize();b.setScrollTop(Math.min(b.page.maxh,c))}};this.init();e.nicescroll.push(this)},J=function(e){var c=this;this.nc=e;this.steptime=this.lasttime=this.speedy=this.speedx=this.lasty=this.lastx=0;this.snapy=this.snapx=!1;this.demuly=this.demulx=0;this.lastscrolly=this.lastscrollx=-1;this.timer=this.chky=this.chkx=0;this.time=function(){return+new Date};this.reset=function(e,l){c.stop();var h=c.time();c.steptime=0;c.lasttime=h;c.speedx=0;c.speedy=0;c.lastx=e;c.lasty=l;c.lastscrollx=-1;c.lastscrolly=
9574-1};this.update=function(e,l){var h=c.time();c.steptime=h-c.lasttime;c.lasttime=h;var h=l-c.lasty,t=e-c.lastx,b=c.nc.getScrollTop(),p=c.nc.getScrollLeft(),b=b+h,p=p+t;c.snapx=0>p||p>c.nc.page.maxw;c.snapy=0>b||b>c.nc.page.maxh;c.speedx=t;c.speedy=h;c.lastx=e;c.lasty=l};this.stop=function(){c.nc.unsynched("domomentum2d");c.timer&&clearTimeout(c.timer);c.timer=0;c.lastscrollx=-1;c.lastscrolly=-1};this.doSnapy=function(e,l){var h=!1;0>l?(l=0,h=!0):l>c.nc.page.maxh&&(l=c.nc.page.maxh,h=!0);0>e?(e=0,h=
9575!0):e>c.nc.page.maxw&&(e=c.nc.page.maxw,h=!0);h&&c.nc.doScrollPos(e,l,c.nc.opt.snapbackspeed)};this.doMomentum=function(e){var l=c.time(),h=e?l+e:c.lasttime;e=c.nc.getScrollLeft();var t=c.nc.getScrollTop(),b=c.nc.page.maxh,p=c.nc.page.maxw;c.speedx=0<p?Math.min(60,c.speedx):0;c.speedy=0<b?Math.min(60,c.speedy):0;h=h&&60>=l-h;if(0>t||t>b||0>e||e>p)h=!1;e=c.speedx&&h?c.speedx:!1;if(c.speedy&&h&&c.speedy||e){var g=Math.max(16,c.steptime);50<g&&(e=g/50,c.speedx*=e,c.speedy*=e,g=50);c.demulxy=0;c.lastscrollx=
9576c.nc.getScrollLeft();c.chkx=c.lastscrollx;c.lastscrolly=c.nc.getScrollTop();c.chky=c.lastscrolly;var s=c.lastscrollx,u=c.lastscrolly,d=function(){var e=600<c.time()-l?0.04:0.02;if(c.speedx&&(s=Math.floor(c.lastscrollx-c.speedx*(1-c.demulxy)),c.lastscrollx=s,0>s||s>p))e=0.1;if(c.speedy&&(u=Math.floor(c.lastscrolly-c.speedy*(1-c.demulxy)),c.lastscrolly=u,0>u||u>b))e=0.1;c.demulxy=Math.min(1,c.demulxy+e);c.nc.synched("domomentum2d",function(){c.speedx&&(c.nc.getScrollLeft()!=c.chkx&&c.stop(),c.chkx=
9577s,c.nc.setScrollLeft(s));c.speedy&&(c.nc.getScrollTop()!=c.chky&&c.stop(),c.chky=u,c.nc.setScrollTop(u));c.timer||(c.nc.hideCursor(),c.doSnapy(s,u))});1>c.demulxy?c.timer=setTimeout(d,g):(c.stop(),c.nc.hideCursor(),c.doSnapy(s,u))};d()}else c.doSnapy(c.nc.getScrollLeft(),c.nc.getScrollTop())}},B=e.fn.scrollTop;e.cssHooks.pageYOffset={get:function(h,c,k){return(c=e.data(h,"__nicescroll")||!1)&&c.ishwscroll?c.getScrollTop():B.call(h)},set:function(h,c){var k=e.data(h,"__nicescroll")||!1;k&&k.ishwscroll?
9578k.setScrollTop(parseInt(c)):B.call(h,c);return this}};e.fn.scrollTop=function(h){if("undefined"==typeof h){var c=this[0]?e.data(this[0],"__nicescroll")||!1:!1;return c&&c.ishwscroll?c.getScrollTop():B.call(this)}return this.each(function(){var c=e.data(this,"__nicescroll")||!1;c&&c.ishwscroll?c.setScrollTop(parseInt(h)):B.call(e(this),h)})};
9578var C=e.fn.scrollLeft;e.cssHooks.pageXOffset={get:function(h,c,k){return(c=e.data(h,"__nicescroll")||!1)&&c.ishwscroll?c.getScrollLeft():C.call(h)},set:function(h,
9579c){var k=e.data(h,"__nicescroll")||!1;k&&k.ishwscroll?k.setScrollLeft(parseInt(c)):C.call(h,c);return this}};e.fn.scrollLeft=function(h){if("undefined"==typeof h){var c=this[0]?e.data(this[0],"__nicescroll")||!1:!1;return c&&c.ishwscroll?c.getScrollLeft():C.call(this)}return this.each(function(){var c=e.data(this,"__nicescroll")||!1;c&&c.ishwscroll?c.setScrollLeft(parseInt(h)):C.call(e(this),h)})};var D=function(h){var c=this;this.length=0;this.name="nicescrollarray";this.each=function(e){for(var h=
95800,k=0;h<c.length;h++)e.call(c[h],k++);return c};this.push=function(e){c[c.length]=e;c.length++};this.eq=function(e){return c[e]};if(h)for(a=0;a<h.length;a++){var k=e.data(h[a],"__nicescroll")||!1;k&&(this[this.length]=k,this.length++)}return this};(function(e,c,k){for(var l=0;l<c.length;l++)k(e,c[l])})(D.prototype,"show hide toggle onResize resize remove stop doScrollPos".split(" "),function(e,c){e[c]=function(){var e=arguments;return this.each(function(){this[c].apply(this,e)})}});e.fn.getNiceScroll=
9581function(h){return"undefined"==typeof h?new D(this):this[h]&&e.data(this[h],"__nicescroll")||!1};e.extend(e.expr[":"],{nicescroll:function(h){return e.data(h,"__nicescroll")?!0:!1}});e.fn.niceScroll=function(h,c){"undefined"==typeof c&&("object"==typeof h&&!("jquery"in h))&&(c=h,h=!1);var k=new D;"undefined"==typeof c&&(c={});h&&(c.doc=e(h),c.win=e(this));var l=!("doc"in c);!l&&!("win"in c)&&(c.win=e(this));this.each(function(){var h=e(this).data("__nicescroll")||!1;h||(c.doc=l?e(this):c.doc,h=new Q(c,
9582e(this)),e(this).data("__nicescroll",h));k.push(h)});return 1==k.length?k[0]:k};window.NiceScroll={getjQuery:function(){return e}};e.nicescroll||(e.nicescroll=new D,e.nicescroll.options=I)})(jQuery);
9583
9584/* mousetrap v1.4.4 craig.is/killing/mice */
9585(function(){function s(a,b,c){a.addEventListener?a.addEventListener(b,c,!1):a.attachEvent("on"+b,c)}function z(a){if("keypress"==a.type){var b=String.fromCharCode(a.which);a.shiftKey||(b=b.toLowerCase());return" "==b?"space":b}return k[a.which]?k[a.which]:A[a.which]?A[a.which]:String.fromCharCode(a.which).toLowerCase()}function t(a){a=a||{};var b=!1,c;for(c in p)a[c]?b=!0:p[c]=0;b||(u=!1)}function B(a,b,c,d,e,g){var f,l,h=[],k=c.type;if(!m[a])return[];"keyup"==k&&v(a)&&(b=[a]);for(f=0;f<m[a].length;++f)if(l=
9586m[a][f],!(!d&&l.seq&&p[l.seq]!=l.level||k!=l.action||("keypress"!=k||c.metaKey||c.ctrlKey)&&b.sort().join(",")!==l.modifiers.sort().join(","))){var n=d&&l.seq==d&&l.level==g;(!d&&l.combo==e||n)&&m[a].splice(f,1);h.push(l)}return h}function I(a){var b=[];a.shiftKey&&b.push("shift");a.altKey&&b.push("alt");a.ctrlKey&&b.push("ctrl");a.metaKey&&b.push("meta");return b}function w(a,b,c){n.stopCallback(b,b.target||b.srcElement,c)||!1!==a(b,c)||(b.preventDefault&&b.preventDefault(),b.stopPropagation&&b.stopPropagation(),
9587b.returnValue=!1,b.cancelBubble=!0)}function x(a){"number"!==typeof a.which&&(a.which=a.keyCode);var b=z(a);b&&("keyup"==a.type&&y===b?y=!1:n.handleKey(b,I(a),a))}function v(a){return"shift"==a||"ctrl"==a||"alt"==a||"meta"==a}function J(a,b,c,d){function e(b){return function(){u=b;++p[a];clearTimeout(C);C=setTimeout(t,1E3)}}function g(b){w(c,b,a);"keyup"!==d&&(y=z(b));setTimeout(t,10)}for(var f=p[a]=0;f<b.length;++f){var h=f+1===b.length?g:e(d||D(b[f+1]).action);E(b[f],h,d,a,f)}}function D(a,b){var c,
9588d,e,g=[];c="+"===a?["+"]:a.split("+");for(e=0;e<c.length;++e)d=c[e],F[d]&&(d=F[d]),b&&("keypress"!=b&&G[d])&&(d=G[d],g.push("shift")),v(d)&&g.push(d);c=d;e=b;if(!e){if(!q){q={};for(var f in k)95<f&&112>f||k.hasOwnProperty(f)&&(q[k[f]]=f)}e=q[c]?"keydown":"keypress"}"keypress"==e&&g.length&&(e="keydown");return{key:d,modifiers:g,action:e}}function E(a,b,c,d,e){r[a+":"+c]=b;a=a.replace(/\s+/g," ");var g=a.split(" ");1<g.length?J(a,g,b,c):(c=D(a,c),m[c.key]=m[c.key]||[],B(c.key,c.modifiers,{type:c.action},
9589d,a,e),m[c.key][d?"unshift":"push"]({callback:b,modifiers:c.modifiers,action:c.action,seq:d,level:e,combo:a}))}for(var k={8:"backspace",9:"tab",13:"enter",16:"shift",17:"ctrl",18:"alt",20:"capslock",27:"esc",32:"space",33:"pageup",34:"pagedown",35:"end",36:"home",37:"left",38:"up",39:"right",40:"down",45:"ins",46:"del",91:"meta",93:"meta",224:"meta"},A={106:"*",107:"+",109:"-",110:".",111:"/",186:";",187:"=",188:",",189:"-",190:".",191:"/",192:"`",219:"[",220:"\\",221:"]",222:"'"},G={"~":"`","!":"1",
9590"@":"2","#":"3",$:"4","%":"5","^":"6","&":"7","*":"8","(":"9",")":"0",_:"-","+":"=",":":";",'"':"'","<":",",">":".","?":"/","|":"\\"},F={option:"alt",command:"meta","return":"enter",escape:"esc",mod:/Mac|iPod|iPhone|iPad/.test(navigator.platform)?"meta":"ctrl"},q,m={},r={},p={},C,y=!1,H=!1,u=!1,h=1;20>h;++h)k[111+h]="f"+h;for(h=0;9>
9590=h;++h)k[h+96]=h;s(document,"keypress",x);s(document,"keydown",x);s(document,"keyup",x);var n={bind:function(a,b,c){a=a instanceof Array?a:[a];for(var d=0;d<a.length;++d)E(a[d],
9591b,c);return this},unbind:function(a,b){return n.bind(a,function(){},b)},trigger:function(a,b){if(r[a+":"+b])r[a+":"+b]({},a);return this},reset:function(){m={};r={};return this},stopCallback:function(a,b){return-1<(" "+b.className+" ").indexOf(" mousetrap ")?!1:"INPUT"==b.tagName||"SELECT"==b.tagName||"TEXTAREA"==b.tagName||b.contentEditable&&"true"==b.contentEditable},handleKey:function(a,b,c){var d=B(a,b,c),e;b={};var g=0,f=!1;for(e=0;e<d.length;++e)d[e].seq&&(g=Math.max(g,d[e].level));for(e=0;e<
9592d.length;++e)d[e].seq?d[e].level==g&&(f=!0,b[d[e].seq]=1,w(d[e].callback,c,d[e].combo)):f||w(d[e].callback,c,d[e].combo);d="keypress"==c.type&&H;c.type!=u||(v(a)||d)||t(b);H=f&&"keydown"==c.type}};window.Mousetrap=n;"function"===typeof define&&define.amd&&define(n)})();
9593/**
9594 * jGrowl 1.2.6
9595 *
9596 * Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php)
9597 * and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses.
9598 *
9599 * Written by Stan Lemon <[email protected]>
9600 * Last updated: 2011.03.27
9601 *
9602 * jGrowl is a jQuery plugin implementing unobtrusive userland notifications.  These
9603 * notifications function similarly to the Growl Framework available for
9604 * Mac OS X (http://growl.info).
9605 *
9606 * To Do:
9607 * - Move library settings to containers and allow them to be changed per contain
vendor: 4,479 bytes, lines 9607-9699
9607er
9608 *
9609 * Changes in 1.2.6
9610 * - Fixed js error when a notification is opening and closing at the same time
9611 *
9612 * Changes in 1.2.5
9613 * - Changed wrapper jGrowl's options usage to "o" instead of $.jGrowl.defaults
9614 * - Added themeState option to control 'highlight' or 'error' for jQuery UI
9615 * - Ammended some CSS to provide default positioning for nested usage.
9616 * - Changed some CSS to be prefixed with jGrowl- to prevent namespacing issues
9617 * - Added two new options - openDuration and closeDuration to allow
9618 *   better control of notification open and close speeds, respectively
9619 *   Patch contributed by Jesse Vincet.
9620 * - Added afterOpen callback.  Patch contributed by Russel Branca.
9621 *
9622 * Changes in 1.2.4
9623 * - Fixed IE bug with the close-all button
9624 * - Fixed IE bug with the filter CSS attribute (special thanks to gotwic)
9625 * - Update IE opacity CSS
9626 * - Changed font sizes to use "em", and only set the base style
9627 *
9628 * Changes in 1.2.3
9629 * - The callbacks no longer use the container as context, instead they use the actual notification
9630 * - The callbacks now receive the container as a parameter after the options parameter
9631 * - beforeOpen and beforeClose now check the return value, if it's false - the notification does
9632 *   not continue.  The open callback will also halt execution if it returns false.
9633 * - Fixed bug where containers would get confused
9634 * - Expanded the pause functionality to pause an entire container.
9635 *
9636 * Changes in 1.2.2
9637 * - Notification can now be theme rolled for jQuery UI, special thanks to Jeff Chan!
9638 *
9639 * Changes in 1.2.1
9640 * - Fixed instance where the interval would fire the close method multiple times.
9641 * - Added CSS to hide from print media
9642 * - Fixed issue with closer button when div { position: relative } is set
9643 * - Fixed leaking issue with multiple containers.  Special thanks to Matthew Hanlon!
9644 *
9645 * Changes in 1.2.0
9646 * - Added message pooling to limit the number of messages appearing at a given time.
9647 * - Closing a notification is now bound to the notification object and triggered by the close button.
9648 *
9649 * Changes in 1.1.2
9650 * - Added iPhone styled example
9651 * - Fixed possible IE7 bug when determining if the ie6 class shoudl be applied.
9652 * - Added template for the close button, so that it's content could be customized.
9653 *
9654 * Changes in 1.1.1
9655 * - Fixed CSS styling bug for ie6 caused by a mispelling
9656 * - Changes height restriction on default notifications to min-height
9657 * - Added skinned examples using a variety of images
9658 * - Added the ability to customize the content of the [close all] box
9659 * - Added jTweet, an example of using jGrowl + Twitter
9660 *
9661 * Changes in 1.1.0
9662 * - Multiple container and instances.
9663 * - Standard $.jGrowl() now wraps $.fn.jGrowl() by first establishing a generic jGrowl container.
9664 * - Instance methods of a jGrowl container can be called by $.fn.jGrowl(methodName)
9665 * - Added glue preferenced, which allows notifications to be inserted before or after nodes in the container
9666 * - Added new log callback which is called before anything is done for the notification
9667 * - Corner's attribute are now applied on an individual notification basis.
9668 *
9669 * Changes in 1.0.4
9670 * - Various CSS fixes so that jGrowl renders correctly in IE6.
9671 *
9672 * Changes in 1.0.3
9673 * - Fixed bug with options persisting across notifications
9674 * - Fixed theme application bug
9675 * - Simplified some selectors and manipulations.
9676 * - Added beforeOpen and beforeClose callbacks
9677 * - Reorganized some lines of code to be more readable
9678 * - Removed unnecessary this.defaults context
9679 * - If corners plugin is present, it's now customizable.
9680 * - Customizable open animation.
9681 * - Customizable close animation.
9682 * - Customizable animation easing.
9683 * - Added customizable positioning (top-left, top-right, bottom-left, bottom-right, center)
9684 *
9685 * Changes in 1.0.2
9686 * - All CSS styling is now external.
9687 * - Added a theme parameter which specifies a secondary class for styling, such
9688 *   that notifications can be customized in appearance on a per message basis.
9689 * - Notification life span is now customizable on a per message basis.
9690 * - Added the ability to disable the global closer, enabled by default.
9691 * - Added callbacks for when a notification is opened or closed.
9692 * - Added callback for the global closer.
9693 * - Customizable animation speed.
9694 * - jGrowl now set itself up and tears itself down.
9695 *
9696 * Changes in 1.0.1:
9697 * - Removed dependency on metadata plugin in favor of .data()
9698 * - Namespaced all events
9699 */
9700(function($) {
9701
9702	/** jGrowl Wrapper - Establish a base jGrowl Container for compatibility with older releases. **/
9703	$.jGrowl = function( m , o ) {
9704		// To maintain compatibility with older version that only supported one instance we'll create the base container.
9705		if ( jQuery('#jGrowl').size() == 0 )
9706			$('<div id="jGrowl"></div>').addClass( (o && o.position) ? o.position : $.jGrowl.defaults.position ).appendTo('body');
9707
9708		// Create a notification on the container.
9709		$('#jGrowl').jGrowl(m,o);
9710	};
9711
9712
9713	/** Raise jGrowl Notification on a jGrowl Container **/
9714	$.fn.jGrowl = function( m , o ) {
9715		if ( $.isFunction(this.each) ) {
9716			var args = arguments;
9717
9718			return this.each(function() {
9719				var self = this;
9720
9721				/** Create a jGrowl Instance on the Container if it does not exist **/
9722				if ( $(this).data('jGrowl.instance') == undefined ) {
9723					$(this).data('jGrowl.instance', $.extend( new $.fn.jGrowl(), { notifications: [], element: null, interval: null } ));
9724					$(this).data('jGrowl.instance').startup( this );
9725				}
9726
9727				/** Optionally call jGrowl instance methods, or just raise a normal notification **/
9728				if ( $.isFunction($(this).data('jGrowl.instance')[m]) ) {
9729					$(this).data('jGrowl.instance')[m].apply( $(this).data('jGrowl.instance') , $.makeArray(args).slice(1) );
9730				} else {
9731					$(this).data('jGrowl.instance').create( m , o );
9732				}
9733			});
9734		};
9735	};
9736
9737	$.extend( $.fn.jGrowl.prototype , {
9738
9739		/** Default JGrowl Settings **/
9740		defaults: {
9741			pool: 			0,
9742			header: 		'',
9743			group: 			'',
9744			sticky: 		false,
9745			position: 		'top-right',
9746			glue: 			'after',
9747			theme: 			'default',
9748			themeState: 	'highlight',
9749			corners: 		'10px',
9750			check: 			250,
9751			life: 			3000,
9752			closeDuration:  'normal',
9753			openDuration:   'normal',
9754			easing: 		'swing',
9755			closer: 		true,
9756			closeTemplate: '&times;',
9757			closerTemplate: '<div>[ close all ]</div>',
9758			log: 			function(e,m,o) {},
9759			beforeOpen: 	function(e,m,o) {},
9760			afterOpen: 		function(e,m,o) {},
9761			open: 			function(e,m,o) {},
9762			beforeClose: 	function(e,m,o) {},
9763			close: 			function(e,m,o) {},
9764			animateOpen: 	{
9765				opacity: 	'show'
9766			},
9767			animateClose: 	{
9768				opacity: 	'hide'
9769			}
9770		},
9771
9772		notifications: [],
9773
9774		/** jGrowl Container Node **/
9775		element: 	null,
9776
9777		/** Interval Function **/
9778		interval:   null,
9779
9780		/** Create a Notification **/
9781		create: 	function( message , o ) {
9782			var o = $.extend({}, this.defaults, o);
9783
9784			/* To keep backward compatibility with 1.24 and earlier, honor 'speed' if the user has set it */
9785			if (typeof o.speed !== 'undefined') {
9786				o.openDuration = o.speed;
9787				o.closeDuration = o.speed;
9788			}
9789
9790			this.notifications.push({ message: message , options: o });
9791
9792			o.log.apply( this.element , [this.element,message,o] );
9793		},
9794
9795		render: 		function( notification ) {
9796			var self = this;
9797			var message = notification.message;
9798			var o = notification.options;
9799
9800			// Support for jQuery theme-states, if this is not used it displays a widget header
9801			o.themeState = (o.themeState == '') ? '' : 'ui-state-' + o.themeState;
9802
9803			var notification = $(
9804				'<div class="jGrowl-notification ' + o.themeState + ' ui-corner-all' +
9805				((o.group != undefined && o.group != '') ? ' ' + o.group : '') + '">' +
9806				'<div class="jGrowl-close">' + o.closeTemplate + '</div>' +
9807				'<div class="jGrowl-header">' + o.header + '</div>' +
9808				'<div class="jGrowl-message">' + message + '</div></div>'
9809			).data("jGrowl", o).addClass(o.theme).children('div.jGrowl-close').bind("click.jGrowl", function() {
9810				$(this).parent().trigger('jGrowl.close');
9811			}).parent();
9812
9813
9814			/** Notification Actions **/
9815			$(notification).bind("mouseover.jGrowl", function() {
9816				$('div.jGrowl-notification', self.element).data("jGrowl.pause", true);
9817			}).bind("mouseout.jGrowl", function() {
9818				$('div.jGrowl-notification', self.element).data("jGrowl.pause", false);
9819			}).bind('jGrowl.beforeOpen', function() {
9820				if ( o.beforeOpen.apply( notification , [notification,message,o,self.element] ) != false ) {
9821					$(this).trigger('jGrowl.open');
9822				}
9823			}).bind('jGrowl.open', function() {
9824				if ( o.open.apply( notification , [notification,message,o,self.element] ) != false ) {
9825					if ( o.glue == 'after' ) {
9826						$('div.jGrowl-notification:last', self.element).after(notification);
9827					} else {
9828						$('div.jGrowl-notification:first', self.element).before(notification);
9829					}
9830
9831					$(this).animate(o.animateOpen, o.openDuration, o.easing, function() {
9832						// Fixes some anti-aliasing issues with IE filters.
9833						if ($.browser.msie && (parseInt($(this).css('opacity'), 10) === 1 || parseInt($(this).css('opacity'), 10) === 0))
9834							this.style.removeAttribute('filter');
9835
9836						if ( $(this).data("jGrowl") != null ) // Happens when a notification is closing before it's open.
9837							$(this).data("jGrowl").created = new Date();
9838
9839						$(this).trigger('jGrowl.afterOpen');
9840					});
9841				}
9842			}).bind('jGrowl.afterOpen', function() {
9843				o.afterOpen.apply( notification , [notification,message,o,self.element] );
9844			}).bind('jGrowl.beforeClose', function() {
9845				if ( o.beforeClose.apply( notification , [notification,message,o,self.element] ) != false )
9846					$(this).trigger('jGrowl.close');
9847			}).bind('jGrowl.close', function() {
9848				// Pause the notification, lest during the course of animation another close event gets called.
9849				$(this).data('jGrowl.pause', true);
9850				$(this).animate(o.animateClose, o.closeDuration, o.easing, function() {
9851					if ( $.isFunction(o.close) ) {
9852						if ( o.close.apply( notification , [notification,message,o,self.element] ) !== false )
9853							$(this).remove();
9854					} else {
9855						$(this).remove();
9856					}
9857				});
9858			}).trigger('jGrowl.beforeOpen');
9859
9860			/** Optional Corners Plugin **/
9861			if ( o.corners != '' && $.fn.corner != undefined ) $(notification).corner( o.corners );
9862
9863			/** Add a Global Closer if more than one notification exists **/
9864			if ( $('div.jGrowl-notification:parent', self.element).size() > 1 &&
9865				 $('div.jGrowl-closer', self.element).size() == 0 && this.defaults.closer != false ) {
9866				$(this.defaults.closerTemplate).addClass('jGrowl-closer ' + this.defaults.themeState + ' ui-corner-all').addClass(this.defaults.theme)
9867					.appendTo(self.element).animate(this.defaults.animateOpen, this.defaults.speed, this.defaults.easing)
9868					.bind("click.jGrowl", function() {
9869						$(this).siblings().trigger("jGrowl.beforeClose");
9870
9871						if ( $.isFunction( self.defaults.closer ) ) {
9872							self.defaults.closer.apply( $(this).parent()[0] , [$(this).parent()[0]] );
9873						}
9874					});
9875			};
9876		},
9877
9878		/** Update the jGrowl Container, removing old jGrowl notifications **/
9879		update:	 function() {
9880			try
9881			{
9882				$(this.element).find('div.jGrowl-notification:parent').each( function() {
9883					if ( $(this).data("jGrowl") != undefined && $(this).data("jGrowl").created != undefined &&
9884						 ($(this).data("jGrowl").created.getTime() + parseInt($(this).data("jGrowl").life))  < (new Date()).getTime() &&
9885						 $(this).data("jGrowl").sticky != true &&
9886						 ($(this).data("jGrowl.pause") == undefined || $(this).data("jGrowl.pause") != true) ) {
9887
9888						// Pause the notification, lest during the course of animation another close event gets called.
9889						$(this).trigger('jGrowl.beforeClose');
9890					}
9891				});
9892
9893				if ( this.notifications.length > 0 &&
9894					 (this.defaults.pool == 0 || $(this.element).find('div.jGrowl-notification:parent').size() < this.defaults.pool) )
9895					this.render( this.notifications.shift() );
9896
9897				if ( $(this.element).find('div.jGrowl-notification:parent').size() < 2 ) {
9898					$(this.element).find('div.jGrowl-closer').animate(this.defaults.animateClose, this.defaults.speed, this.defaults.easing, function() {
9899						$(this).remove();
9900					});
9901				}
9902			} catch (err)
9903			{
9904				nxs_js_log('jgrowl err;' + err);
9905			}
9906		},
9907
9908		/** Setup the jGrowl Notification Container **/
9909		startup:	function(e) {
9910			this.element = $(e).addClass('jGrowl').append('<div class="jGrowl-notification"></div>');
9911			this.interval = setInterval( function() {
9912				$(e).data('jGrowl.instance').update();
9913			}, parseInt(this.defaults.check));
9914
9915			if ($.browser.msie && parseInt($.browser.version) < 7 && !window["XMLHttpRequest"]) {
9916				$(this.element).addClass('ie6');
9917			}
9918		},
9919
9920		/** Shutdown jGrowl, removing it and clearing the interval **/
9921		shutdown:   function() {
9922			$(this.element).removeClass('jGrowl').find('div.jGrowl-notification').remove();
9923			clearInterval( this.interval );
9924		},
9925
9926		close: 	function() {
9927			$(this.element).find('div.jGrowl-notification').each(function(){
9928				$(this).trigger('jGrowl.beforeClose');
9929			});
9930		}
9931	});
9932
9933	/** Reference the Defaults Object for compatibility with older versions of jGrowl **/
9934	$.jGrowl.defaults = $.fn.jGrowl.prototype.defaults;
9935
9936})(jQuery);
9937
9938/* Modernizr 2.6.2 (Custom Build) | MIT & BSD
9939 * Build: http://modernizr.com/download/#-fontface-backgroundsize-borderimage-borderradiu
vendor: 9,145 bytes, lines 9939-9941
9939s-boxshadow-flexbox-flexboxlegacy-hsla-multiplebgs-opacity-rgba-textshadow-cssanimations-csscolumns-generatedcontent-cssgradients-cssreflections-csstransforms-csstransforms3d-csstransitions-applicationcache-canvas-canvastext-draganddrop-hashchange-history-audio-video-indexeddb-input-inputtypes-localstorage-postmessage-sessionstorage-websockets-websqldatabase-webworkers-geolocation-inlinesvg-smil-svg-svgclippaths-touch-webgl-shiv-mq-cssclasses-teststyles-testprop-testallprops-hasevent-prefixes-domprefixes-load-cssclassprefix:nxs!m!
9940 */
9941;window.Modernizr=function(a,b,c){function D(a){j.cssText=a}function E(a,b){return D(n.join(a+";")+(b||""))}function F(a,b){return typeof a===b}function G(a,b){return!!~(""+a).indexOf(b)}function H(a,b){for(var d in a){var e=a[d];if(!G(e,"-")&&j[e]!==c)return b=="pfx"?e:!0}return!1}function I(a,b,d){for(var e in a){var f=b[a[e]];if(f!==c)return d===!1?a[e]:F(f,"function")?f.bind(d||b):f}return!1}function J(a,b,c){var d=a.charAt(0).toUpperCase()+a.slice(1),e=(a+" "+p.join(d+" ")+d).split(" ");return F(b,"string")||F(b,"undefined")?H(e,b):(e=(a+" "+q.join(d+" ")+d).split(" "),I(e,b,c))}function K(){e.input=function(c){for(var d=0,e=c.length;d<e;d++)u[c[d]]=c[d]in k;return u.list&&(u.list=!!b.createElement("datalist")&&!!a.HTMLDataListElement),u}("autocomplete autofocus list placeholder max min multiple pattern required step".split(" ")),e.inputtypes=function(a){for(var d=0,e,f,h,i=a.length;d<i;d++)k.setAttribute("type",f=a[d]),e=k.type!=="text",e&&(k.value=l,k.style.cssText="position:absolute;visibility:hidden;",/^range$/.test(f)&&k.style.WebkitAppearance!==c?(g.appendChild(k),h=b.defaultView,e=h.getComputedStyle&&h.getComputedStyle(k,null).WebkitAppearance!=="textfield"&&k.offsetHeight!==0,g.removeChild(k)):/^(search|tel)$/.test(f)||(/^(url|email)$/.test(f)?e=k.checkValidity&&k.checkValidity()===!1:e=k.value!=l)),t[a[d]]=!!e;return t}("search tel url email datetime date month week time datetime-local number range color".split(" "))}var d="2.6.2",e={},f=!0,g=b.documentElement,h="modernizr",i=b.createElement(h),j=i.style,k=b.createElement("input"),l=":)",m={}.toString,n=" -webkit- -moz- -o- -ms- ".split(" "),o="Webkit Moz O ms",p=o.split(" "),q=o.toLowerCase().split(" "),r={svg:"http://www.w3.org/2000/svg"},s={},t={},u={},v=[],w=v.slice,x,y=function(a,c,d,e){var f,i,j,k,l=b.createElement("div"),m=b.body,n=m||b.createElement("body");if(parseInt(d,10))while(d--)j=b.createElement("div"),j.id=e?e[d]:h+(d+1),l.appendChild(j);return f=["&#173;",'<style id="s',h,'">',a,"</style>"].join(""),l.id=h,(m?l:n).innerHTML+=f,n.appendChild(l),m||(n.style.background="",n.style.overflow="hidden",k=g.style.overflow,g.style.overflow="hidden",g.appendChild(n)),i=c(l,a),m?l.parentNode.removeChild(l):(n.parentNode.removeChild(n),g.style.overflow=k),!!i},z=function(b){var c=a.matchMedia||a.msMatchMedia;if(c)return c(b).matches;var d;return y("@media "+b+" { #"+h+" { position: absolute; } }",function(b){d=(a.getComputedStyle?getComputedStyle(b,null):b.currentStyle)["position"]=="absolute"}),d},A=function(){function d(d,e){e=e||b.createElement(a[d]||"div"),d="on"+d;var f=d in e;return f||(e.setAttribute||(e=b.createElement("div")),e.setAttribute&&e.removeAttribute&&(e.setAttribute(d,""),f=F(e[d],"function"),F(e[d],"undefined")||(e[d]=c),e.removeAttribute(d))),e=null,f}var a={select:"input",change:"input",submit:"form",reset:"form",error:"img",load:"img",abort:"img"};return d}(),B={}.hasOwnProperty,C;!F(B,"undefined")&&!F(B.call,"undefined")?C=function(a,b){return B.call(a,b)}:C=function(a,b){return b in a&&F(a.constructor.prototype[b],"undefined")},Function.prototype.bind||(Function.prototype.bind=function(b){var c=this;if(typeof c!="function")throw new TypeError;var d=w.call(arguments,1),e=function(){if(this instanceof e){var a=function(){};a.prototype=c.prototype;var f=new a,g=c.apply(f,d.concat(w.call(arguments)));return Object(g)===g?g:f}return c.apply(b,d.concat(w.call(arguments)))};return e}),s.flexbox=function(){return J("flexWrap")},s.flexboxlegacy=function(){return J("boxDirection")},s.canvas=function(){var a=b.createElement("canvas");return!!a.getContext&&!!a.getContext("2d")},s.canvastext=function(){return!!e.canvas&&!!F(b.createElement("canvas").getContext("2d").fillText,"function")},s.webgl=function(){return!!a.WebGLRenderingContext},s.touch=function(){var c;return"ontouchstart"in a||a.DocumentTouch&&b instanceof DocumentTouch?c=!0:y(["@media (",n.join("touch-enabled),("),h,")","{#modernizr{top:9px;position:absolute}}"].join(""),function(a){c=a.offsetTop===9}),c},s.geolocation=function(){return"geolocation"in navigator},s.postmessage=function(){return!!a.postMessage},s.websqldatabase=function(){return!!a.openDatabase},s.indexedDB=function(){return!!J("indexedDB",a)},s.hashchange=function(){return A("hashchange",a)&&(b.documentMode===c||b.documentMode>7)},s.history=function(){return!!a.history&&!!history.pushState},s.draganddrop=function(){var a=b.createElement("div");return"draggable"in a||"ondragstart"in a&&"ondrop"in a},s.websockets=function(){return"WebSocket"in a||"MozWebSocket"in a},s.rgba=function(){return D("background-color:rgba(150,255,150,.5)"),G(j.backgroundColor,"rgba")},s.hsla=function(){return D("background-color:hsla(120,40%,100%,.5)"),G(j.backgroundColor,"rgba")||G(j.backgroundColor,"hsla")},s.multiplebgs=function(){return D("background:url(https://),url(https://),red url(https://)"),/(url\s*\(.*?){3}/.test(j.background)},s.backgroundsize=function(){return J("backgroundSize")},s.borderimage=function(){return J("borderImage")},s.borderradius=function(){return J("borderRadius")},s.boxshadow=function(){return J("boxShadow")},s.textshadow=function(){return b.createElement("div").style.textShadow===""},s.opacity=function(){return E("opacity:.55"),/^0.55$/.test(j.opacity)},s.cssanimations=function(){return J("animationName")},s.csscolumns=function(){return J("columnCount")},s.cssgradients=function(){var a="background-image:",b="gradient(linear,left top,right bottom,from(#9f9),to(white));",c="linear-gradient(left top,#9f9, white);";return D((a+"-webkit- ".split(" ").join(b+a)+n.join(c+a)).slice(0,-a.length)),G(j.backgroundImage,"gradient")},s.cssreflections=function(){return J("boxReflect")},s.csstransforms=function(){return!!J("transform")},s.csstransforms3d=function(){var a=!!J("perspective");return a&&"webkitPerspective"in g.style&&y("@media (transform-3d),(-webkit-transform-3d){#modernizr{left:9px;position:absolute;height:3px;}}",function(b,c){a=b.offsetLeft===9&&b.offsetHeight===3}),a},s.csstransitions=function(){return J("transition")},s.fontface=function(){var a;return y('@font-face {font-family:"font";src:url("https://")}',function(c,d){var e=b.getElementById("smodernizr"),f=e.sheet||e.styleSheet,g=f?f.cssRules&&f.cssRules[0]?f.cssRules[0].cssText:f.cssText||"":"";a=/src/i.test(g)&&g.indexOf(d.split(" ")[0])===0}),a},s.generatedcontent=function(){var a;return y(["#",h,"{font:0/0 a}#",h,':after{content:"',l,'";visibility:hidden;font:3px/1 a}'].join(""),function(b){a=b.offsetHeight>=3}),a},s.video=function(){var a=b.createElement("video"),c=!1;try{if(c=!!a.canPlayType)c=new Boolean(c),c.ogg=a.canPlayType('video/ogg; codecs="theora"').replace(/^no$/,""),c.h264=a.canPlayType('video/mp4; codecs="avc1.42E01E"').replace(/^no$/,""),c.webm=a.canPlayType('video/webm; codecs="vp8, vorbis"').replace(/^no$/,"")}catch(d){}return c},s.audio=function(){var a=b.createElement("audio"),c=!1;try{if(c=!!a.canPlayType)c=new Boolean(c),c.ogg=a.canPlayType('audio/ogg; codecs="vorbis"').replace(/^no$/,""),c.mp3=a.canPlayType("audio/mpeg;").replace(/^no$/,""),c.wav=a.canPlayType('audio/wav; codecs="1"').replace(/^no$/,""),c.m4a=(a.canPlayType("audio/x-m4a;")||a.canPlayType("audio/aac;")).replace(/^no$/,"")}catch(d){}return c},s.localstorage=function(){try{return localStorage.setItem(h,h),localStorage.removeItem(h),!0}catch(a){return!1}},s.sessionstorage=function(){try{return sessionStorage.setItem(h,h),sessionStorage.removeItem(h),!0}catch(a){return!1}},s.webworkers=function(){return!!a.Worker},s.applicationcache=function(){return!!a.applicationCache},s.svg=function(){return!!b.createElementNS&&!!b.createElementNS(r.svg,"svg").createSVGRect},s.inlinesvg=function(){var a=b.createElement("div");return a.innerHTML="<svg/>",(a.firstChild&&a.firstChild.namespaceURI)==r.svg},s.smil=function(){return!!b.createElementNS&&/SVGAnimate/.test(m.call(b.createElementNS(r.svg,"animate")))},s.svgclippaths=function(){return!!b.createElementNS&&/SVGClipPath/.test(m.call(b.createElementNS(r.svg,"clipPath")))};for(var L in s)C(s,L)&&(x=L.toLowerCase(),e[x]=s[L](),v.push((e[x]?"":"no-")+x));return e.input||K(),e.addTest=function(a,b){if(typeof a=="object")for(var d in a)C(a,d)&&e.addTest(d,a[d]);else{a=a.toLowerCase();if(e[a]!==c)return e;b=typeof b=="function"?b():b,typeof f!="undefined"&&f&&(g.className+=" nxs-m-"+(b?"":"no-")+a),e[a]=b}return e},D(""),i=k=null,function(a,b){function k(a,b){var c=a.createElement("p"),d=a.getElementsByTagName("head")[0]||a.documentElement;return c.innerHTML="x<style>"+b+"</style>",d.insertBefore(c.lastChild,d.firstChild)}function l(){var a=r.elements;
9941return typeof a=="string"?a.split(" "):a}function m(a){var b=i[a[g]];return b||(b={},h++,a[g]=h,i[h]=b),b}function n(a,c,f){c||(c=b);if(j)return c.createElement(a);f||(f=m(c));var g;return f.cache[a]?g=f.cache[a].cloneNode():e.test(a)?g=(f.cache[a]=f.createElem(a)).cloneNode():g=f.createElem(a),g.canHaveChildren&&!d.test(a)?f.frag.appendChild(g):g}function o(a,c){a||(a=b);if(j)return a.createDocumentFragment();c=c||m(a);var d=c.frag.cloneNode(),e=0,f=l(),g=f.length;for(;e<g;e++)d.createElement(f[e]);return d}function p(a,b){b.cache||(b.cache={},b.createElem=a.createElement,b.createFrag=a.createDocumentFragment,b.frag=b.createFrag()),a.createElement=function(c){return r.shivMethods?n(c,a,b):b.createElem(c)},a.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+l().join().replace(/\w+/g,function(a){return b.createElem(a),b.frag.createElement(a),'c("'+a+'")'})+");return n}")(r,b.frag)}function q(a){a||(a=b);var c=m(a);return r.shivCSS&&!f&&!c.hasCSS&&(c.hasCSS=!!k(a,"article,aside,figcaption,figure,footer,header,hgroup,nav,section{display:block}mark{background:#FF0;color:#000}")),j||p(a,c),a}var c=a.html5||{},d=/^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i,e=/^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i,f,g="_html5shiv",h=0,i={},j;(function(){try{var a=b.createElement("a");a.innerHTML="<xyz></xyz>",f="hidden"in a,j=a.childNodes.length==1||function(){b.createElement("a");var a=b.createDocumentFragment();return typeof a.cloneNode=="undefined"||typeof a.createDocumentFragment=="undefined"||typeof a.createElement=="undefined"}()}catch(c){f=!0,j=!0}})();var r={elements:c.elements||"abbr article aside audio bdi canvas data datalist details figcaption figure footer header hgroup mark meter nav output progress section summary time video",shivCSS:c.shivCSS!==!1,supportsUnknownElements:j,shivMethods:c.shivMethods!==!1,type:"default",shivDocument:q,createElement:n,createDocumentFragment:o};a.html5=r,q(b)}(this,b),e._version=d,e._prefixes=n,e._domPrefixes=q,e._cssomPrefixes=p,e.mq=z,e.hasEvent=A,e.testProp=function(a){return H([a])},e.testAllProps=J,e.testStyles=y,g.className=g.className.replace(/(^|\s)no-js(\s|$)/,"$1$2")+(f?" nxs-m-js nxs-m-"+v.join(" nxs-m-"):""),e}(this,this.document),function(a,b,c){function d(a){return"[object Function]"==o.call(a)}function e(a){return"string"==typeof a}function f(){}function g(a){return!a||"loaded"==a||"complete"==a||"uninitialized"==a}function h(){var a=p.shift();q=1,a?a.t?m(function(){("c"==a.t?B.injectCss:B.injectJs)(a.s,0,a.a,a.x,a.e,1)},0):(a(),h()):q=0}function i(a,c,d,e,f,i,j){function k(b){if(!o&&g(l.readyState)&&(u.r=o=1,!q&&h(),l.onload=l.onreadystatechange=null,b)){"img"!=a&&m(function(){t.removeChild(l)},50);for(var d in y[c])y[c].hasOwnProperty(d)&&y[c][d].onload()}}var j=j||B.errorTimeout,l=b.createElement(a),o=0,r=0,u={t:d,s:c,e:f,a:i,x:j};1===y[c]&&(r=1,y[c]=[]),"object"==a?l.data=c:(l.src=c,l.type=a),l.width=l.height="0",l.onerror=l.onload=l.onreadystatechange=function(){k.call(this,r)},p.splice(e,0,u),"img"!=a&&(r||2===y[c]?(t.insertBefore(l,s?null:n),m(k,j)):y[c].push(l))}function j(a,b,c,d,f){return q=0,b=b||"j",e(a)?i("c"==b?v:u,a,b,this.i++,c,d,f):(p.splice(this.i++,0,a),1==p.length&&h()),this}function k(){var a=B;return a.loader={load:j,i:0},a}var l=b.documentElement,m=a.setTimeout,n=b.getElementsByTagName("script")[0],o={}.toString,p=[],q=0,r="MozAppearance"in l.style,s=r&&!!b.createRange().compareNode,t=s?l:n.parentNode,l=a.opera&&"[object Opera]"==o.call(a.opera),l=!!b.attachEvent&&!l,u=r?"object":l?"script":"img",v=l?"script":u,w=Array.isArray||function(a){return"[object Array]"==o.call(a)},x=[],y={},z={timeout:function(a,b){return b.length&&(a.timeout=b[0]),a}},A,B;B=function(a){function b(a){var a=a.split("!"),b=x.length,c=a.pop(),d=a.length,c={url:c,origUrl:c,prefixes:a},e,f,g;for(f=0;f<d;f++)g=a[f].split("="),(e=z[g.shift()])&&(c=e(c,g));for(f=0;f<b;f++)c=x[f](c);return c}function g(a,e,f,g,h){var i=b(a),j=i.autoCallback;i.url.split(".").pop().split("?").shift(),i.bypass||(e&&(e=d(e)?e:e[a]||e[g]||e[a.split("/").pop().split("?")[0]]),i.instead?i.instead(a,e,f,g,h):(y[i.url]?i.noexec=!0:y[i.url]=1,f.load(i.url,i.forceCSS||!i.forceJS&&"css"==i.url.split(".").pop().split("?").shift()?"c":c,i.noexec,i.attrs,i.timeout),(d(e)||d(j))&&f.load(function(){k(),e&&e(i.origUrl,h,g),j&&j(i.origUrl,h,g),y[i.url]=2})))}function h(a,b){function c(a,c){if(a){if(e(a))c||(j=function(){var a=[].slice.call(arguments);k.apply(this,a),l()}),g(a,j,b,0,h);else if(Object(a)===a)for(n in m=function(){var b=0,c;for(c in a)a.hasOwnProperty(c)&&b++;return b}(),a)a.hasOwnProperty(n)&&(!c&&!--m&&(d(j)?j=function(){var a=[].slice.call(arguments);k.apply(this,a),l()}:j[n]=function(a){return function(){var b=[].slice.call(arguments);a&&a.apply(this,b),l()}}(k[n])),g(a[n],j,b,n,h))}else!c&&l()}var h=!!a.test,i=a.load||a.both,j=a.callback||f,k=j,l=a.complete||f,m,n;c(h?a.yep:a.nope,!!i),i&&c(i)}var i,j,l=this.yepnope.loader;if(e(a))g(a,0,l,0);else if(w(a))for(i=0;i<a.length;i++)j=a[i],e(j)?g(j,0,l,0):w(j)?B(j):Object(j)===j&&h(j,l);else Object(a)===a&&h(a,l)},B.addPrefix=function(a,b){z[a]=b},B.addFilter=function(a){x.push(a)},B.errorTimeout=1e4,null==b.readyState&&b.addEventListener&&(b.readyState="loading",b.addEventListener("DOMContentLoaded",A=function(){b.removeEventListener("DOMContentLoaded",A,0),b.readyState="complete"},0)),a.yepnope=k(),a.yepnope.executeStack=h,a.yepnope.injectJs=function(a,c,d,e,i,j){var k=b.createElement("script"),l,o,e=e||B.errorTimeout;k.src=a;for(o in d)k.setAttribute(o,d[o]);c=j?h:c||f,k.onreadystatechange=k.onload=function(){!l&&g(k.readyState)&&(l=1,c(),k.onload=k.onreadystatechange=null)},m(function(){l||(l=1,c(1))},e),i?k.onload():n.parentNode.insertBefore(k,n)},a.yepnope.injectCss=function(a,c,d,e,g,i){var e=b.createElement("link"),j,c=i?h:c||f;e.href=a,e.rel="stylesheet",e.type="text/css";for(j in d)e.setAttribute(j,d[j]);g||(n.parentNode.insertBefore(e,n),m(c,0))}}(this,document),Modernizr.load=function(){yepnope.apply(window,[].slice.call(arguments,0))};
9942
9943/*
9944 * Thickbox 3.1 - One Box To Rule Them All.
9945 * By Cody Lindley (http://www.codylindley.com)
9946 * Copyright (c) 2007 cody lindley
9947 * Licensed under the MIT License: http://www.opensource.org/licenses/mit-license.php
9948*/
9949
9950function tb_init(e){jQuery(e).live("click",tb_click)}function tb_click(){var e=this.title||this.name||null;var t=this.href||this.alt;var n=this.rel||false;tb_show(e,t,n);this.blur();return false}function tb_show(e,t,n){try{if(typeof document.body.style.maxHeight==="undefined"){jQuery("body","html").css({height:"100%",width:"100%"});jQuery("html").css("overflow","hidden");if(document.getElementById("TB_HideSelect")===null){jQuery("body").append("<iframe id='TB_HideSelect'>"+thickboxL10n.noiframes+"</iframe><div id='TB_overlay'></div><div id='TB_window'></div>");jQuery("#TB_overlay").click(tb_remove)}}else{if(document.getElementById("TB_overlay")===null){jQuery("body").append("<div id='TB_overlay'></div><div id='TB_window'></div>");jQuery("#TB_overlay").click(tb_remove)}}if(tb_detectMacXFF()){jQuery("#TB_overlay").addClass("TB_overlayMacFFBGHack")}else{jQuery("#TB_overlay").addClass("TB_overlayBG")}if(e===null){e=""}jQuery("body").append("<div id='TB_load'><img src='"+imgLoader.src+"' /></div>");jQuery("#TB_load").show();var r;if(t.indexOf("?")!==-1){r=t.substr(0,t.indexOf("?"))}else{r=t}var i=/\.jpg$|\.jpeg$|\.png$|\.gif$|\.bmp$/;var s=r.toLowerCase().match(i);if(s==".jpg"||s==".jpeg"||s==".png"||s==".gif"||s==".bmp"){TB_PrevCaption="";TB_PrevURL="";TB_PrevHTML="";TB_NextCaption="";TB_NextURL="";TB_NextHTML="";TB_imageCount="";TB_FoundURL=false;if(n){TB_TempArray=jQuery("a[rel="+n+"]").get();for(TB_Counter=0;TB_Counter<TB_TempArray.length&&TB_NextHTML==="";TB_Counter++){var o=TB_TempArray[TB_Counter].href.toLowerCase().match(i);if(!(TB_TempArray[TB_Counter].href==t)){if(TB_FoundURL){TB_NextCaption=TB_TempArray[TB_Counter].title;TB_NextURL=TB_TempArray[TB_Counter].href;TB_NextHTML="<span id='TB_next'>��<a href='#'>"+thickboxL10n.next+"</a></span>"}else{TB_PrevCaption=TB_TempArray[TB_Counter].title;TB_PrevURL=TB_TempArray[TB_Counter].href;TB_PrevHTML="<span id='TB_prev'>��<a href='#'>"+thickboxL10n.prev+"</a></span>"}}else{TB_FoundURL=true;TB_imageCount=thickboxL10n.image+" "+(TB_Counter+1)+" "+thickboxL10n.of+" "+TB_TempArray.length}}}imgPreloader=new Image;imgPreloader.onload=function(){imgPreloader.onload=null;var r=tb_getPageSize();var i=r[0]-150;var s=r[1]-150;var o=imgPreloader.width;var u=imgPreloader.height;if(o>i){u=u*(i/o);o=i;if(u>s){o=o*(s/u);u=s}}else if(u>s){o=o*(s/u);u=s;if(o>i){u=u*(i/o);o=i}}TB_WIDTH=o+30;TB_HEIGHT=u+60;jQuery("#TB_window").append("<a href='' id='TB_ImageOff' title='"+thickboxL10n.close+"'><img id='TB_Image' src='"+t+"' width='"+o+"' height='"+u+"' alt='"+e+"'/></a>"+"<div id='TB_caption'>"+e+"<div id='TB_secondLine'>"+TB_imageCount+TB_PrevHTML+TB_NextHTML+"</div></div><div id='TB_closeWindow'><a href='#' id='TB_closeWindowButton' title='"+thickboxL10n.close+"'><img src='"+tb_closeImage+"' /></a></div>");jQuery("#TB_closeWindowButton").click(tb_remove);if(!(TB_PrevHTML==="")){function a(){if(jQuery(document).unbind("click",a)){jQuery(document).unbind("click",a)}jQuery("#TB_window").remove();jQuery("body").append("<div id='TB_window'></div>");tb_show(TB_PrevCaption,TB_PrevURL,n);return false}jQuery("#TB_prev").click(a)}if(!(TB_NextHTML==="")){function f(){jQuery("#TB_window").remove();jQuery("body").append("<div id='TB_window'></div>");tb_show(TB_NextCaption,TB_NextURL,n);return false}jQuery("#TB_next").click(f)}jQuery(document).bind("keydown.thickbox",function(e){e.stopImmediatePropagation();if(e.which==27){if(!jQuery(document).triggerHandler("wp_CloseOnEscape",[{event:e,what:"thickbox",cb:tb_remove}]))tb_remove()}else if(e.which==190){if(!(TB_NextHTML=="")){jQuery(document).unbind("thickbox");f()}}else if(e.which==188){if(!(TB_PrevHTML=="")){jQuery(document).unbind("thickbox");a()}}return false});tb_position();jQuery("#TB_load").remove();jQuery("#TB_ImageOff").click(tb_remove);jQuery("#TB_window").css({visibility:"visible"})};imgPreloader.src=t}else{var u=t.replace(/^[^\?]+\??/,"");var a=tb_parseQuery(u);TB_WIDTH=a["width"]*1+30||630;TB_HEIGHT=a["height"]*1+40||440;ajaxContentW=TB_WIDTH-30;ajaxContentH=TB_HEIGHT-45;if(t.indexOf("TB_iframe")!=-1){urlNoQuery=t.split("TB_");jQuery("#TB_iframeContent").remove();if(a["modal"]!="true"){jQuery("#TB_window").append("<div id='TB_title'><div id='TB_ajaxWindowTitle'>"+e+"</div><div id='TB_closeAjaxWindow'><a href='#' id='TB_closeWindowButton' title='"+thickboxL10n.close+"'><img src='"+tb_closeImage+"' /></a></div></div><iframe frameborder='0' hspace='0' src='"+urlNoQuery[0]+"' id='TB_iframeContent' name='TB_iframeContent"+Math.round(Math.random()*1e3)+"' onload='tb_showIframe()' style='width:"+(ajaxContentW+29)+"px;height:"+(ajaxContentH+17)+"px;' >"+thickboxL10n.noiframes+"</iframe>")}else{jQuery("#TB_overlay").unbind();jQuery("#TB_window").append("<iframe frameborder='0' hspace='0' src='"+urlNoQuery[0]+"' id='TB_iframeContent' name='TB_iframeContent"+Math.round(Math.random()*1e3)+"' onload='tb_showIframe()' style='width:"+(ajaxContentW+29)+"px;height:"+(ajaxContentH+17)+"px;'>"+thickboxL10n.noiframes+"</iframe>")}}else{if(jQuery("#TB_window").css("visibility")!="visible"){if(a["modal"]!="true"){jQuery("#TB_window").append("<div id='TB_title'><div id='TB_ajaxWindowTitle'>"+e+"</div><div id='TB_closeAjaxWindow'><a href='#' id='TB_closeWindowButton'><img src='"+tb_closeImage+"' /></a></div></div><div id='TB_ajaxContent' style='width:"+ajaxContentW+"px;height:"+ajaxContentH+"px'></div>")}else{jQuery("#TB_overlay").unbind();jQuery("#TB_window").append("<div id='TB_ajaxContent' class='TB_modal' style='width:"+ajaxContentW+"px;height:"+ajaxContentH+"px;'></div>")}}else{jQuery("#TB_ajaxContent")[0].style.width=ajaxContentW+"px";jQuery("#TB_ajaxContent")[0].style.height=ajaxContentH+"px";jQuery("#TB_ajaxContent")[0].scrollTop=0;jQuery("#TB_ajaxWindowTitle").html(e)}}jQuery("#TB_closeWindowButton").click(tb_remove);if(t.indexOf("TB_inline")!=-1){jQuery("#TB_ajaxContent").append(jQuery("#"+a["inlineId"]).children());jQuery("#TB_window").bind("tb_unload",function(){jQuery("#"+a["inlineId"]).append(jQuery("#TB_ajaxContent").children())});tb_position();jQuery("#TB_load").remove();jQuery("#TB_window").css({visibility:"visible"})}else if(t.indexOf("TB_iframe")!=-1){tb_position();if(jQuery.browser.safari){jQuery("#TB_load").remove();jQuery("#TB_window").css({visibility:"visible"})}}else{jQuery("#TB_ajaxContent").load(t+="&random="+(new Date).getTime(),function(){tb_position();jQuery("#TB_load").remove();tb_init("#TB_ajaxContent a.thickbox");jQuery("#TB_window").css({visibility:"visible"})})}}if(!a["modal"]){jQuery(document).bind("keyup.thickbox",function(e){if(e.which==27){e.stopImmediatePropagation();if(!jQuery(document).triggerHandler("wp_CloseOnEscape",[{event:e,what:"thickbox",cb:tb_remove}]))tb_remove();return false}})}}catch(f){}}function tb_showIframe(){jQuery("#TB_load").remove();jQuery("#TB_window").css({visibility:"visible"})}function tb_remove(){jQuery("#TB_imageOff").unbind("click");jQuery("#TB_closeWindowButton").unbind("click");jQuery("#TB_window").fadeOut("fast",function(){jQuery("#TB_window,#TB_overlay,#TB_HideSelect").trigger("tb_unload").unbind().remove()});jQuery("#TB_load").remove();if(typeof document.body.style.maxHeight=="undefined"){jQuery("body","html").css({height:"auto",width:"auto"});jQuery("html").css("overflow","")}jQuery(document).unbind(".thickbox");return false}function tb_position(){var e=typeof document.body.style.maxHeight==="undefined";jQuery("#TB_window").css({marginLeft:"-"+parseInt(TB_WIDTH/2,10)+"px",width:TB_WIDTH+"px"});if(!e){jQuery("#TB_window").css({marginTop:"-"+parseInt(TB_HEIGHT/2,10)+"px"})}}function tb_parseQuery(e){var t={};if(!e){return t}var n=e.split(/[;&]/);for(var r=0;r<n.length;r++){var i=n[r].split("=");if(!i||i.length!=2){continue}var s=unescape(i[0]);var o=unescape(i[1]);o=o.replace(/\+/g," ");t[s]=o}return t}function tb_getPageSize(){var e=document.documentElement;var t=window.innerWidth||self.innerWidth||e&&e.clientWidth||document.body.clientWidth;
9950var n=window.innerHeight||self.innerHeight||e&&e.clientHeight||document.body.clientHeight;arrayPageSize=[t,n];return arrayPageSize}function tb_detectMacXFF(){var e=navigator.userAgent.toLowerCase();if(e.indexOf("mac")!=-1&&e.indexOf("firefox")!=-1){return true}}if(typeof tb_pathToImage!="string"){var tb_pathToImage=thickboxL10n.loadingAnimation}if(typeof tb_closeImage!="string"){var tb_closeImage=thickboxL10n.closeImage}jQuery(document).ready(function(){tb_init("a.thickbox, area.thickbox, input.thickbox");imgLoader=new Image;imgLoader.src=tb_pathToImage})
9951
9952/* jQuery forms */
9953/*!
9954 * jQuery Form Plugin
9955 * version: 3.32.0-2013.04.09
9956 * @requires jQuery v1.5 or later
9957 * Copyright (c) 2013 M. Alsup
9958 * Examples and documentation at: http://malsup.com/jquery/form/
9959 * Project repository: https://github.com/malsup/form
9960 * Dual licensed under the MIT and GPL licenses.
9961 * https://github.com/malsup/form#copyright-and-license
9962 */
9963/*global ActiveXObject */
9964;(function($) {
9965"use strict";
9966
9967/*
9968    Usage Note:
9969    -----------
9970    Do not use both ajaxSubmit and ajaxForm on the same form.  These
9971    functions are mutually exclusive.  Use ajaxSubmit if you want
9972    to bind your own submit handler to the form.  For example,
9973
9974    $(document).ready(function() {
9975        $('#myForm').on('submit', function(e) {
9976            e.preventDefault(); // <-- important
9977            $(this).ajaxSubmit({
9978                target: '#output'
9979            });
9980        });
9981    });
9982
9983    Use ajaxForm when you want the plugin to manage all the event binding
9984    for you.  For example,
9985
9986    $(document).ready(function() {
9987        $('#myForm').ajaxForm({
9988            target: '#output'
9989        });
9990    });
9991
9992    You can also use ajaxForm with delegation (requires jQuery v1.7+), so the
9993    form does not have to exist when you invoke ajaxForm:
9994
9995    $('#myForm').ajaxForm({
9996        delegation: true,
9997        target: '#output'
9998    });
9999
10000    When using ajaxForm, the ajaxSubmit function will be invoked for you
10001    at the appropriate time.
10002*/
10003
10004/**
10005 * Feature detection
10006 */
10007var feature = {};
10008feature.fileapi = $("<input type='file'/>").get(0).files !== undefined;
10009feature.formdata = window.FormData !== undefined;
10010
10011var hasProp = !!$.fn.prop;
10012
10013// attr2 uses prop when it can but checks the return type for
10014// an expected string.  this accounts for the case where a form
10015// contains inputs with names like "action" or "method"; in those
10016// cases "prop" returns the element
10017$.fn.attr2 = function() {
10018    if ( ! hasProp )
10019        return this.attr.apply(this, arguments);
10020    var val = this.prop.apply(this, arguments);
10021    if ( ( val && val.jquery ) || typeof val === 'string' )
10022        return val;
10023    return this.attr.apply(this, arguments);
10024};
10025
10026/**
10027 * ajaxSubmit() provides a mechanism for immediately submitting
10028 * an HTML form using AJAX.
10029 */
10030$.fn.ajaxSubmit = function(options) {
10031    /*jshint scripturl:true */
10032
10033    // fast fail if nothing selected (http://dev.jquery.com/ticket/2752)
10034    if (!this.length) {
10035        log('ajaxSubmit: skipping submit process - no element selected');
10036        return this;
10037    }
10038
10039    var method, action, url, $form = this;
10040
10041    if (typeof options == 'function') {
10042        options = { success: options };
10043    }
10044
10045    method = this.attr2('method');
10046    action = this.attr2('action');
10047
10048    url = (typeof action === 'string') ? $.trim(action) : '';
10049    url = url || window.location.href || '';
10050    if (url) {
10051        // clean url (don't include hash vaue)
10052        url = (url.match(/^([^#]+)/)||[])[1];
10053    }
10054
10055    options = $.extend(true, {
10056        url:  url,
10057        success: $.ajaxSettings.success,
10058        type: method || 'GET',
10059        iframeSrc: /^https/i.test(window.location.href || '') ? 'javascript:false' : 'about:blank'
10060    }, options);
10061
10062    // hook for manipulating the form data before it is extracted;
10063    // convenient for use with rich editors like tinyMCE or FCKEditor
10064    var veto = {};
10065    this.trigger('form-pre-serialize', [this, options, veto]);
10066    if (veto.veto) {
10067        log('ajaxSubmit: submit vetoed via form-pre-serialize trigger');
10068        return this;
10069    }
10070
10071    // provide opportunity to alter form data before it is serialized
10072    if (options.beforeSerialize && options.beforeSerialize(this, options) === false) {
10073        log('ajaxSubmit: submit aborted via beforeSerialize callback');
10074        return this;
10075    }
10076
10077    var traditional = options.traditional;
10078    if ( traditional === undefined ) {
10079        traditional = $.ajaxSettings.traditional;
10080    }
10081
10082    var elements = [];
10083    var qx, a = this.formToArray(options.semantic, elements);
10084    if (options.data) {
10085        options.extraData = options.data;
10086        qx = $.param(options.data, traditional);
10087    }
10088
10089    // give pre-submit callback an opportunity to abort the submit
10090    if (options.beforeSubmit && options.beforeSubmit(a, this, options) === false) {
10091        log('ajaxSubmit: submit aborted via beforeSubmit callback');
10092        return this;
10093    }
10094
10095    // fire vetoable 'validate' event
10096    this.trigger('form-submit-validate', [a, this, options, veto]);
10097    if (veto.veto) {
10098        log('ajaxSubmit: submit vetoed via form-submit-validate trigger');
10099        return this;
10100    }
10101
10102    var q = $.param(a, traditional);
10103    if (qx) {
10104        q = ( q ? (q + '&' + qx) : qx );
10105    }
10106    if (options.type.toUpperCase() == 'GET') {
10107        options.url += (options.url.indexOf('?') >= 0 ? '&' : '?') + q;
10108        options.data = null;  // data is null for 'get'
10109    }
10110    else {
10111        options.data = q; // data is the query string for 'post'
10112    }
10113
10114    var callbacks = [];
10115    if (options.resetForm) {
10116        callbacks.push(function() { $form.resetForm(); });
10117    }
10118    if (options.clearForm) {
10119        callbacks.push(function() { $form.clearForm(options.includeHidden); });
10120    }
10121
10122    // perform a load on the target only if dataType is not provided
10123    if (!options.dataType && options.target) {
10124        var oldSuccess = options.success || function(){};
10125        callbacks.push(function(data) {
10126            var fn = options.replaceTarget ? 'replaceWith' : 'html';
10127            $(options.target)[fn](data).each(oldSuccess, arguments);
10128        });
10129    }
10130    else if (options.success) {
10131        callbacks.push(options.success);
10132    }
10133
10134    options.success = function(data, status, xhr) { // jQuery 1.4+ passes xhr as 3rd arg
10135        var context = options.context || this ;    // jQuery 1.4+ supports scope context
10136        for (var i=0, max=callbacks.length; i < max; i++) {
10137            callbacks[i].apply(context, [data, status, xhr || $form, $form]);
10138        }
10139    };
10140
10141    // are there files to upload?
10142
10143    // [value] (issue #113), also see comment:
10144    // https://github.com/malsup/form/commit/588306aedba1de01388032d5f42a60159eea9228#commitcomment-2180219
10145    var fileInputs = $('input[type=file]:enabled[value!=""]', this);
10146
10147    var hasFileInputs = fileInputs.length > 0;
10148    var mp = 'multipart/form-data';
10149    var multipart = ($form.attr('enctype') == mp || $form.attr('encoding') == mp);
10150
10151    var fileAPI = feature.fileapi && feature.formdata;
10152    log("fileAPI :" + fileAPI);
10153    var shouldUseFrame = (hasFileInputs || multipart) && !fileAPI;
10154
10155    var jqxhr;
10156
10157    // options.iframe allows user to force iframe mode
10158    // 06-NOV-09: now defaulting to iframe mode if file input is detected
10159    if (options.iframe !== false && (options.iframe || shouldUseFrame)) {
10160        // hack to fix Safari hang (thanks to Tim Molendijk for this)
10161        // see:  http://groups.google.com/group/jquery-dev/browse_thread/thread/36395b7ab510dd5d
10162        if (options.closeKeepAlive) {
10163            $.get(options.closeKeepAlive, function() {
10164                jqxhr = fileUploadIframe(a);
10165            });
10166        }
10167        else {
10168            jqxhr = fileUploadIframe(a);
10169        }
10170    }
10171    else if ((hasFileInputs || multipart) && fileAPI) {
10172        jqxhr = fileUploadXhr(a);
10173    }
10174    else {
10175        jqxhr = $.ajax(options);
10176    }
10177
10178    $form.removeData('jqxhr').data('jqxhr', jqxhr);
10179
10180    // clear element array
10181    for (var k=0; k < elements.length; k++)
10182        elements[k] = null;
10183
10184    // fire 'notify' event
10185    this.trigger('form-submit-notify', [this, options]);
10186    return this;
10187
10188    // utility fn for deep serialization
10189    function deepSerialize(extraData){
10190        var serialized = $.param(extraData).split('&');
10191        var len = serialized.length;
10192        var result = [];
10193        var i, part;
10194        for (i=0; i < len; i++) {
10195            // #252; undo param space replacement
10196            serialized[i] = serialized[i].replace(/\+/g,' ');
10197            part = serialized[i].split('=');
10198            // #278; use array instead of object storage, favoring array serializations
10199            result.push([decodeURIComponent(part[0]), decodeURIComponent(part[1])]);
10200        }
10201        return result;
10202    }
10203
10204     // XMLHttpRequest Level 2 file uploads (big hat tip to francois2metz)
10205    function fileUploadXhr(a) {
10206        var formdata = new FormData();
10207
10208        for (var i=0; i < a.length; i++) {
10209            formdata.append(a[i].name, a[i].value);
10210        }
10211
10212        if (options.extraData) {
10213            var serializedData = deepSerialize(options.extraData);
10214            for (i=0; i < serializedData.length; i++)
10215                if (serializedData[i])
10216                    formdata.append(serializedData[i][0], serializedData[i][1]);
10217        }
10218
10219        options.data = null;
10220
10221        var s = $.extend(true, {}, $.ajaxSettings, options, {
10222            contentType: false,
10223            processData: false,
10224            cache: false,
10225            type: method || 'POST'
10226        });
10227
10228        if (options.uploadProgress) {
10229            // workaround because jqXHR does not expose upload property
10230            s.xhr = function() {
10231                var xhr = jQuery.ajaxSettings.xhr();
10232                if (xhr.upload) {
10233                    xhr.upload.addEventListener('progress', function(event) {
10234                        var percent = 0;
10235                        var position = event.loaded || event.position; /*event.position is deprecated*/
10236                        var total = event.total;
10237                        if (event.lengthComputable) {
10238                            percent = Math.ceil(position / total * 100);
10239                        }
10240                        options.uploadProgress(event, position, total, percent);
10241                    }, false);
10242                }
10243                return xhr;
10244            };
10245        }
10246
10247        s.data = null;
10248            var beforeSend = s.beforeSend;
10249            s.beforeSend = function(xhr, o) {
10250                o.data = formdata;
10251                if(beforeSend)
10252                    beforeSend.call(this, xhr, o);
10253        };
10254        return $.ajax(s);
10255    }
10256
10257    // private function for handling file uploads (hat tip to YAHOO!)
10258    function fileUploadIframe(a) {
10259        var form = $form[0], el, i, s, g, id, $io, io, xhr, sub, n, timedOut, timeoutHandle;
10260        var deferred = $.Deferred();
10261
10262        if (a) {
10263            // ensure that every serialized input is still enabled
10264            for (i=0; i < elements.length; i++) {
10265                el = $(elements[i]);
10266                if ( hasProp )
10267                    el.prop('disabled', false);
10268                else
10269                    el.removeAttr('disabled');
10270            }
10271        }
10272
10273        s = $.extend(true, {}, $.ajaxSettings, options);
10274        s.context = s.context || s;
10275        id = 'jqFormIO' + (new Date().getTime());
10276        if (s.iframeTarget) {
10277            $io = $(s.iframeTarget);
10278            n = $io.attr2('name');
10279            if (!n)
10280                 $io.attr2('name', id);
10281            else
10282                id = n;
10283        }
10284        else {
10285            $io = $('<iframe name="' + id + '" src="'+ s.iframeSrc +'" />');
10286            $io.css({ position: 'absolute', top: '-1000px', left: '-1000px' });
10287        }
10288        io = $io[0];
10289
10290
10291        xhr = { // mock object
10292            aborted: 0,
10293            responseText: null,
10294            responseXML: null,
10295            status: 0,
10296            statusText: 'n/a',
10297            getAllResponseHeaders: function() {},
10298            getResponseHeader: function() {},
10299            setRequestHeader: function() {},
10300            abort: function(status) {
10301                var e = (status === 'timeout' ? 'timeout' : 'aborted');
10302                log('aborting upload... ' + e);
10303                this.aborted = 1;
10304
10305                try { // #214, #257
10306                    if (io.contentWindow.document.execCommand) {
10307                        io.contentWindow.document.execCommand('Stop');
10308                    }
10309                }
10310                catch(ignore) {}
10311
10312                $io.attr('src', s.iframeSrc); // abort op in progress
10313                xhr.error = e;
10314                if (s.error)
10315                    s.error.call(s.context, xhr, e, status);
10316                if (g)
10317                    $.event.trigger("ajaxError", [xhr, s, e]);
10318                if (s.complete)
10319                    s.complete.call(s.context, xhr, e);
10320            }
10321        };
10322
10323        g = s.global;
10324        // trigger ajax global events so that activity/block indicators work like normal
10325        if (g && 0 === $.active++) {
10326            $.event.trigger("ajaxStart");
10327        }
10328        if (g) {
10329            $.event.trigger("ajaxSend", [xhr, s]);
10330        }
10331
10332        if (s.beforeSend && s.beforeSend.call(s.context, xhr, s) === false) {
10333            if (s.global) {
10334                $.active--;
10335            }
10336            deferred.reject();
10337            return deferred;
10338        }
10339        if (xhr.aborted) {
10340            deferred.reject();
10341            return deferred;
10342        }
10343
10344        // add submitting element to data if we know it
10345        sub = form.clk;
10346        if (sub) {
10347            n = sub.name;
10348            if (n && !sub.disabled) {
10349                s.extraData = s.extraData || {};
10350                s.extraData[n] = sub.value;
10351                if (sub.type == "image") {
10352                    s.extraData[n+'.x'] = form.clk_x;
10353                    s.extraData[n+'.y'] = form.clk_y;
10354                }
10355            }
10356        }
10357
10358        var CLIENT_TIMEOUT_ABORT = 1;
10359        var SERVER_ABORT = 2;
10360
10361        function getDoc(frame) {
10362            /* it looks like contentWindow or contentDocument do not
10363             * carry the protocol property in ie8, when running under ssl
10364             * frame.document is the only valid response document, since
10365             * the protocol is know but not on the other two objects. strange?
10366             * "Same origin policy" http://en.wikipedia.org/wiki/Same_origin_policy
10367             */
10368
10369            var doc = null;
10370
10371            // IE8 cascading access check
10372            try {
10373                if (frame.contentWindow) {
10374                    doc = frame.contentWindow.document;
10375                }
10376            } catch(err) {
10377                // IE8 access denied under ssl & missing protocol
10378                log('cannot get iframe.contentWindow document: ' + err);
10379            }
10380
10381            if (doc) { // successful getting content
10382                return doc;
10383            }
10384
10385            try { // simply checking may throw in ie8 under ssl or mismatched protocol
10386                doc = frame.contentDocument ? frame.contentDocument : frame.document;
10387            } catch(err) {
10388                // last attempt
10389                log('cannot get iframe.contentDocument: ' + err);
10390                doc = frame.document;
10391            }
10392            return doc;
10393        }
10394
10395        // Rails CSRF hack (thanks to Yvan Barthelemy)
10396        var csrf_token = $('meta[name=csrf-token]').attr('content');
10397        var csrf_param = $('meta[name=csrf-param]').attr('content');
10398        if (csrf_param && csrf_token) {
10399            s.extraData = s.extraData || {};
10400            s.extraData[csrf_param] = csrf_token;
10401        }
10402
10403        // take a breath so that pending repaints get some cpu time before the upload starts
10404        function doSubmit() {
10405            // make sure form attrs are set
10406            var t = $form.attr2('target'), a = $form.attr2('action');
10407
10408            // update form attrs in IE friendly way
10409            form.setAttribute('target',id);
10410            if (!method) {
10411                form.setAttribute('method', 'POST');
10412            }
10413            if (a != s.url) {
10414                form.setAttribute('action', s.url);
10415            }
10416
10417            // ie borks in some cases when setting encoding
10418            if (! s.skipEncodingOverride && (!method || /post/i.test(method))) {
10419                $form.attr({
10420                    encoding: 'multipart/form-data',
10421                    enctype:  'multipart/form-data'
10422                });
10423            }
10424
10425            // support timout
10426            if (s.timeout) {
10427                timeoutHandle = setTimeout(function() { timedOut = true; cb(CLIENT_TIMEOUT_ABORT); }, s.timeout);
10428            }
10429
10430            // look for server aborts
10431            function checkState() {
10432                try {
10433                    var state = getDoc(io).readyState;
10434                    log('state = ' + state);
10435                    if (state && state.toLowerCase() == 'uninitialized')
10436                        setTimeout(checkState,50);
10437                }
10438                catch(e) {
10439                    log('Server abort: ' , e, ' (', e.name, ')');
10440                    cb(SERVER_ABORT);
10441                    if (timeoutHandle)
10442                        clearTimeout(timeoutHandle);
10443                    timeoutHandle = undefined;
10444                }
10445            }
10446
10447            // add "extra" data to form if provided in options
10448            var extraInputs = [];
10449            try {
10450                if (s.extraData) {
10451                    for (var n in s.extraData) {
10452                        if (s.extraData.hasOwnProperty(n)) {
10453                           // if using the $.param format that allows for multiple values with the same name
10454                           if($.isPlainObject(s.extraData[n]) && s.extraData[n].hasOwnProperty('name') && s.extraData[n].hasOwnProperty('value')) {
10455                               extraInputs.push(
10456                               $('<input type="hidden" name="'+s.extraData[n].name+'">').val(s.extraData[n].value)
10457                                   .appendTo(form)[0]);
10458                           } else {
10459                               extraInputs.push(
10460                               $('<input type="hidden" name="'+n+'">').val(s.extraData[n])
10461                                   .appendTo(form)[0]);
10462                           }
10463                        }
10464                    }
10465                }
10466
10467                if (!s.iframeTarget) {
10468                    // add iframe to doc and submit the form
10469                    $io.appendTo('body');
10470                    if (io.attachEvent)
10471                        io.attachEvent('onload', cb);
10472                    else
10473                        io.addEventListener('load', cb, false);
10474                }
10475                setTimeout(checkState,15);
10476
10477                try {
10478                    form.submit();
10479                } catch(err) {
10480                    // just in case form has element with name/id of 'submit'
10481                    var submitFn = document.createElement('form').submit;
10482                    submitFn.apply(form);
10483                }
10484            }
10485            finally {
10486                // reset attrs and remove "extra" input elements
10487                form.setAttribute('action',a);
10488                if(t) {
10489                    form.setAttribute('target', t);
10490                } else {
10491                    $form.removeAttr('target');
10492                }
10493                $(extraInputs).remove();
10494            }
10495        }
10496
10497        if (s.forceSync) {
10498            doSubmit();
10499        }
10500        else {
10501            setTimeout(doSubmit, 10); // this lets dom updates render
10502        }
10503
10504        var data, doc, domCheckCount = 50, callbackProcessed;
10505
10506        function cb(e) {
10507            if (xhr.aborted || callbackProcessed) {
10508                return;
10509            }
10510
10511            doc = getDoc(io);
10512            if(!doc) {
10513                log('cannot access response document');
10514                e = SERVER_ABORT;
10515            }
10516            if (e === CLIENT_TIMEOUT_ABORT && xhr) {
10517                xhr.abort('timeout');
10518                deferred.reject(xhr, 'timeout');
10519                return;
10520            }
10521            else if (e == SERVER_ABORT && xhr) {
10522                xhr.abort('server abort');
10523                deferred.reject(xhr, 'error', 'server abort');
10524                return;
10525            }
10526
10527            if (!doc || doc.location.href == s.iframeSrc) {
10528                // response not received yet
10529                if (!timedOut)
10530                    return;
10531            }
10532            if (io.detachEvent)
10533                io.detachEvent('onload', cb);
10534            else
10535                io.removeEventListener('load', cb, false);
10536
10537            var status = 'success', errMsg;
10538            try {
10539                if (timedOut) {
10540                    throw 'timeout';
10541                }
10542
10543                var isXml = s.dataType == 'xml' || doc.XMLDocument || $.isXMLDoc(doc);
10544                log('isXml='+isXml);
10545                if (!isXml && window.opera && (doc.body === null || !doc.body.innerHTML)) {
10546                    if (--domCheckCount) {
10547                        // in some browsers (Opera) the iframe DOM is not always traversable when
10548                        // the onload callback fires, so we loop a bit to accommodate
10549                        log('requeing onLoad callback, DOM not available');
10550                        setTimeout(cb, 250);
10551                        return;
10552                    }
10553                    // let this fall through because server response could be an empty document
10554                    //log('Could not access iframe DOM after mutiple tries.');
10555                    //throw 'DOMException: not available';
10556                }
10557
10558                //log('response detected');
10559                var docRoot = doc.body ? doc.body : doc.documentElement;
10560                xhr.responseText = docRoot ? docRoot.innerHTML : null;
10561                xhr.responseXML = doc.XMLDocument ? doc.XMLDocument : doc;
10562                if (isXml)
10563                    s.dataType = 'xml';
10564                xhr.getResponseHeader = function(header){
10565                    var headers = {'content-type': s.dataType};
10566                    return headers[header];
10567                };
10568                // support for XHR 'status' & 'statusText' emulation :
10569                if (docRoot) {
10570                    xhr.status = Number( docRoot.getAttribute('status') ) || xhr.status;
10571                    xhr.statusText = docRoot.getAttribute('statusText') || xhr.statusText;
10572                }
10573
10574                var dt = (s.dataType || '').toLowerCase();
10575                var scr = /(json|script|text)/.test(dt);
10576                if (scr || s.textarea) {
10577                    // see if user embedded response in textarea
10578                    var ta = doc.getElementsByTagName('textarea')[0];
10579                    if (ta) {
10580                        xhr.responseText = ta.value;
10581                        // support for XHR 'status' & 'statusText' emulation :
10582                        xhr.status = Number( ta.getAttribute('status') ) || xhr.status;
10583                        xhr.statusText = ta.getAttribute('statusText') || xhr.statusText;
10584                    }
10585                    else if (scr) {
10586                        // account for browsers injecting pre around json response
10587                        var pre = doc.getElementsByTagName('pre')[0];
10588                        var b = doc.getElementsByTagName('body')[0];
10589                        if (pre) {
10590                            xhr.responseText = pre.textContent ? pre.textContent : pre.innerText;
10591                        }
10592                        else if (b) {
10593                            xhr.responseText = b.textContent ? b.textContent : b.innerText;
10594                        }
10595                    }
10596                }
10597                else if (dt == 'xml' && !xhr.responseXML && xhr.responseText) {
10598                    xhr.responseXML = toXml(xhr.responseText);
10599                }
10600
10601                try {
10602                    data = httpData(xhr, dt, s);
10603                }
10604                catch (err) {
10605                    status = 'parsererror';
10606                    xhr.error = errMsg = (err || status);
10607                }
10608            }
10609            catch (err) {
10610                log('error caught: ',err);
10611                status = 'error';
10612                xhr.error = errMsg = (err || status);
10613            }
10614
10615            if (xhr.aborted) {
10616                log('upload aborted');
10617                status = null;
10618            }
10619
10620            if (xhr.status) { // we've set xhr.status
10621                status = (xhr.status >= 200 && xhr.status < 300 || xhr.status === 304) ? 'success' : 'error';
10622            }
10623
10624            // ordering of these callbacks/triggers is odd, but that's how $.ajax does it
10625            if (status === 'success') {
10626                if (s.success)
10627                    s.success.call(s.context, data, 'success', xhr);
10628                deferred.resolve(xhr.responseText, 'success', xhr);
10629                if (g)
10630                    $.event.trigger("ajaxSuccess", [xhr, s]);
10631            }
10632            else if (status) {
10633                if (errMsg === undefined)
10634                    errMsg = xhr.statusText;
10635                if (s.error)
10636                    s.error.call(s.context, xhr, status, errMsg);
10637                deferred.reject(xhr, 'error', errMsg);
10638                if (g)
10639                    $.event.trigger("ajaxError", [xhr, s, errMsg]);
10640            }
10641
10642            if (g)
10643                $.event.trigger("ajaxComplete", [xhr, s]);
10644
10645            if (g && ! --$.active) {
10646                $.event.trigger("ajaxStop");
10647            }
10648
10649            if (s.complete)
10650                s.complete.call(s.context, xhr, status);
10651
10652            callbackProcessed = true;
10653            if (s.timeout)
10654                clearTimeout(timeoutHandle);
10655
10656            // clean up
10657            setTimeout(function() {
10658                if (!s.iframeTarget)
10659                    $io.remove();
10660                xhr.responseXML = null;
10661            }, 100);
10662        }
10663
10664        var toXml = $.parseXML || function(s, doc) { // use parseXML if available (jQuery 1.5+)
10665            if (window.ActiveXObject) {
10666                doc = new ActiveXObject('Microsoft.XMLDOM');
10667                doc.async = 'false';
10668                doc.loadXML(s);
10669            }
10670            else {
10671                doc = (new DOMParser()).parseFromString(s, 'text/xml');
10672            }
10673            return (doc && doc.documentElement && doc.documentElement.nodeName != 'parsererror') ? doc : null;
10674        };
10675        var parseJSON = $.parseJSON || function(s) {
10676            /*jslint evil:true */
10677            return window['eval']('(' + s + ')');
10678        };
10679
10680        var httpData = function( xhr, type, s ) { // mostly lifted from jq1.4.4
10681
10682            var ct = xhr.getResponseHeader('content-type') || '',
10683                xml = type === 'xml' || !type && ct.indexOf('xml') >= 0,
10684                data = xml ? xhr.responseXML : xhr.responseText;
10685
10686            if (xml && data.documentElement.nodeName === 'parsererror') {
10687                if ($.error)
10688                    $.error('parsererror');
10689            }
10690            if (s && s.dataFilter) {
10691                data = s.dataFilter(data, type);
10692            }
10693            if (typeof data === 'string') {
10694                if (type === 'json' || !type && ct.indexOf('json') >= 0) {
10695                    data = parseJSON(data);
10696                } else if (type === "script" || !type && ct.indexOf("javascript") >= 0) {
10697                    $.globalEval(data);
10698                }
10699            }
10700            return data;
10701        };
10702
10703        return deferred;
10704    }
10705};
10706
10707/**
10708 * ajaxForm() provides a mechanism for fully automating form submission.
10709 *
10710 * The advantages of using this method instead of ajaxSubmit() are:
10711 *
10712 * 1: This method will include coordinates for <input type="image" /> elements (if the element
10713 *    is used to submit the form).
10714 * 2. This method will include the submit element's name/value data (for the element that was
10715 *    used to submit the form).
10716 * 3. This method binds the submit() method to the form for you.
10717 *
10718 * The options argument for ajaxForm works exactly as it does for ajaxSubmit.  ajaxForm merely
10719 * passes the options argument along after properly binding events for submit elements and
10720 * the form itself.
10721 */
10722$.fn.ajaxForm = function(options) {
10723    options = options || {};
10724    options.delegation = options.delegation && $.isFunction($.fn.on);
10725
10726    // in jQuery 1.3+ we can fix mistakes with the ready state
10727    if (!options.delegation && this.length === 0) {
10728        var o = { s: this.selector, c: this.context };
10729        if (!$.isReady && o.s) {
10730            log('DOM not ready, queuing ajaxForm');
10731            $(function() {
10732                $(o.s,o.c).ajaxForm(options);
10733            });
10734            return this;
10735        }
10736        // is your DOM ready?  http://docs.jquery.com/Tutorials:Introducing_$(document).ready()
10737        log('terminating; zero elements found by selector' + ($.isReady ? '' : ' (DOM not ready)'));
10738        return this;
10739    }
10740
10741    if ( options.delegation ) {
10742        $(document)
10743            .off('submit.form-plugin', this.selector, doAjaxSubmit)
10744            .off('click.form-plugin', this.selector, captureSubmittingElement)
10745            .on('submit.form-plugin', this.selector, options, doAjaxSubmit)
10746            .on('click.form-plugin', this.selector, options, captureSubmittingElement);
10747        return this;
10748    }
10749
10750    return this.ajaxFormUnbind()
10751        .bind('submit.form-plugin', options, doAjaxSubmit)
10752        .bind('click.form-plugin', options, captureSubmittingElement);
10753};
10754
10755// private event handlers
10756function doAjaxSubmit(e) {
10757    /*jshint validthis:true */
10758    var options = e.data;
10759    if (!e.isDefaultPrevented()) { // if event has been canceled, don't proceed
10760        e.preventDefault();
10761        $(this).ajaxSubmit(options);
10762    }
10763}
10764
10765function captureSubmittingElement(e) {
10766    /*jshint validthis:true */
10767    var target = e.target;
10768    var $el = $(target);
10769    if (!($el.is("[type=submit],[type=image]"))) {
10770        // is this a child element of the submit el?  (ex: a span within a button)
10771        var t = $el.closest('[type=submit]');
10772        if (t.length === 0) {
10773            return;
10774        }
10775        target = t[0];
10776    }
10777    var form = this;
10778    form.clk = target;
10779    if (target.type == 'image') {
10780        if (e.offsetX !== undefined) {
10781            form.clk_x = e.offsetX;
10782            form.clk_y = e.offsetY;
10783        } else if (typeof $.fn.offset == 'function') {
10784            var offset = $el.offset();
10785            form.clk_x = e.pageX - offset.left;
10786            form.clk_y = e.pageY - offset.top;
10787        } else {
10788            form.clk_x = e.pageX - target.offsetLeft;
10789            form.clk_y = e.pageY - target.offsetTop;
10790        }
10791    }
10792    // clear form vars
10793    setTimeout(function() { form.clk = form.clk_x = form.clk_y = null; }, 100);
10794}
10795
10796
10797// ajaxFormUnbind unbinds the event handlers that were bound by ajaxForm
10798$.fn.ajaxFormUnbind = function() {
10799    return this.unbind('submit.form-plugin click.form-plugin');
10800};
10801
10802/**
10803 * formToArray() gathers form element data into an array of objects that can
10804 * be passed to any of the following ajax functions: $.get, $.post, or load.
10805 * Each object in the array has both a 'name' and 'value' property.  An example of
10806 * an array for a simple login form might be:
10807 *
10808 * [ { name: 'username', value: 'jresig' }, { name: 'password', value: 'secret' } ]
10809 *
10810 * It is this array that is passed to pre-submit callback functions provided to the
10811 * ajaxSubmit() and ajaxForm() methods.
10812 */
10813$.fn.formToArray = function(semantic, elements) {
10814    var a = [];
10815    if (this.length === 0) {
10816        return a;
10817    }
10818
10819    var form = this[0];
10820    var els = semantic ? form.getElementsByTagName('*') : form.elements;
10821    if (!els) {
10822        return a;
10823    }
10824
10825    var i,j,n,v,el,max,jmax;
10826    for(i=0, max=els.length; i < max; i++) {
10827        el = els[i];
10828        n = el.name;
10829        if (!n || el.disabled) {
10830            continue;
10831        }
10832
10833        if (semantic && form.clk && el.type == "image") {
10834            // handle image inputs on the fly when semantic == true
10835            if(form.clk == el) {
10836                a.push({name: n, value: $(el).val(), type: el.type });
10837                a.push({name: n+'.x', value: form.clk_x}, {name: n+'.y', value: form.clk_y});
10838            }
10839            continue;
10840        }
10841
10842        v = $.fieldValue(el, true);
10843        if (v && v.constructor == Array) {
10844            if (elements)
10845                elements.push(el);
10846            for(j=0, jmax=v.length; j < jmax; j++) {
10847                a.push({name: n, value: v[j]});
10848            }
10849        }
10850        else if (feature.fileapi && el.type == 'file') {
10851            if (elements)
10852                elements.push(el);
10853            var files = el.files;
10854            if (files.length) {
10855                for (j=0; j < files.length; j++) {
10856                    a.push({name: n, value: files[j], type: el.type});
10857                }
10858            }
10859            else {
10860                // #180
10861                a.push({ name: n, value: '', type: el.type });
10862            }
10863        }
10864        else if (v !== null && typeof v != 'undefined') {
10865            if (elements)
10866                elements.push(el);
10867            a.push({name: n, value: v, type: el.type, required: el.required});
10868        }
10869    }
10870
10871    if (!semantic && form.clk) {
10872        // input type=='image' are not found in elements array! handle it here
10873        var $input = $(form.clk), input = $input[0];
10874        n = input.name;
10875        if (n && !input.disabled && input.type == 'image') {
10876            a.push({name: n, value: $input.val()});
10877            a.push({name: n+'.x', value: form.clk_x}, {name: n+'.y', value: form.clk_y});
10878        }
10879    }
10880    return a;
10881};
10882
10883/**
10884 * Serializes form data into a 'submittable' string. This method will return a string
10885 * in the format: name1=value1&amp;name2=value2
10886 */
10887$.fn.formSerialize = function(semantic) {
10888    //hand off to jQuery.param for proper encoding
10889    return $.param(this.formToArray(semantic));
10890};
10891
10892/**
10893 * Serializes all field elements in the jQuery object into a query string.
10894 * This method will return a string in the format: name1=value1&amp;name2=value2
10895 */
10896$.fn.fieldSerialize = function(successful) {
10897    var a = [];
10898    this.each(function() {
10899        var n = this.name;
10900        if (!n) {
10901            return;
10902        }
10903        var v = $.fieldValue(this, successful);
10904        if (v && v.constructor == Array) {
10905            for (var i=0,max=v.length; i < max; i++) {
10906                a.push({name: n, value: v[i]});
10907            }
10908        }
10909        else if (v !== null && typeof v != 'undefined') {
10910            a.push({name: this.name, value: v});
10911        }
10912    });
10913    //hand off to jQuery.param for proper encoding
10914    return $.param(a);
10915};
10916
10917/**
10918 * Returns the value(s) of the element in the matched set.  For example, consider the following form:
10919 *
10920 *  <form><fieldset>
10921 *      <input name="A" type="text" />
10922 *      <input name="A" type="text" />
10923 *      <input name="B" type="checkbox" value="B1" />
10924 *      <input name="B" type="checkbox" value="B2"/>
10925 *      <input name="C" type="radio" value="C1" />
10926 *      <input name="C" type="radio" value="C2" />
10927 *  </fieldset></form>
10928 *
10929 *  var v = $('input[type=text]').fieldValue();
10930 *  // if no values are entered into the text inputs
10931 *  v == ['','']
10932 *  // if values entered into the text inputs are 'foo' and 'bar'
10933 *  v == ['foo','bar']
10934 *
10935 *  var v = $('input[type=checkbox]').fieldValue();
10936 *  // if neither checkbox is checked
10937 *  v === undefined
10938 *  // if both checkboxes are checked
10939 *  v == ['B1', 'B2']
10940 *
10941 *  var v = $('input[type=radio]').fieldValue();
10942 *  // if neither radio is checked
10943 *  v === undefined
10944 *  // if first radio is checked
10945 *  v == ['C1']
10946 *
10947 * The successful argument controls whether or not the field element must be 'successful'
10948 * (per http://www.w3.org/TR/html4/interact/forms.html#successful-controls).
10949 * The default value of the successful argument is true.  If this value is false the value(s)
10950 * for each element is returned.
10951 *
10952 * Note: This method *always* returns an array.  If no valid value can be determined the
10953 *    array will be empty, otherwise it will contain one or more values.
10954 */
10955$.fn.fieldValue = function(successful) {
10956    for (var val=[], i=0, max=this.length; i < max; i++) {
10957        var el = this[i];
10958        var v = $.fieldValue(el, successful);
10959        if (v === null || typeof v == 'undefined' || (v.constructor == Array && !v.length)) {
10960            continue;
10961        }
10962        if (v.constructor == Array)
10963            $.merge(val, v);
10964        else
10965            val.push(v);
10966    }
10967    return val;
10968};
10969
10970/**
10971 * Returns the value of the field element.
10972 */
10973$.fieldValue = function(el, successful) {
10974    var n = el.name, t = el.type, tag = el.tagName.toLowerCase();
10975    if (successful === undefined) {
10976        successful = true;
10977    }
10978
10979    if (successful && (!n || el.disabled || t == 'reset' || t == 'button' ||
10980        (t == 'checkbox' || t == 'radio') && !el.checked ||
10981        (t == 'submit' || t == 'image') && el.form && el.form.clk != el ||
10982        tag == 'select' && el.selectedIndex == -1)) {
10983            return null;
10984    }
10985
10986    if (tag == 'select') {
10987        var index = el.selectedIndex;
10988        if (index < 0) {
10989            return null;
10990        }
10991        var a = [], ops = el.options;
10992        var one = (t == 'select-one');
10993        var max = (one ? index+1 : ops.length);
10994        for(var i=(one ? index : 0); i < max; i++) {
10995            var op = ops[i];
10996            if (op.selected) {
10997                var v = op.value;
10998                if (!v) { // extra pain for IE...
10999                    v = (op.attributes && op.attributes['value'] && !(op.attributes['value'].specified)) ? op.text : op.value;
11000                }
11001                if (one) {
11002                    return v;
11003                }
11004                a.push(v);
11005            }
11006        }
11007        return a;
11008    }
11009    return $(el).val();
11010};
11011
11012/**
11013 * Clears the form data.  Takes the following actions on the form's input fields:
11014 *  - input text fields will have their 'value' property set to the empty string
11015 *  - select elements will have their 'selectedIndex' property set to -1
11016 *  - checkbox and radio inputs will have their 'checked' property set to false
11017 *  - inputs of type submit, button, reset, and hidden will *not* be effected
11018 *  - button elements will *not* be effected
11019 */
11020$.fn.clearForm = function(includeHidden) {
11021    return this.each(function() {
11022        $('input,select,textarea', this).clearFields(includeHidden);
11023    });
11024};
11025
11026/**
11027 * Clears the selected form elements.
11028 */
11029$.fn.clearFields = $.fn.clearInputs = function(includeHidden) {
11030    var re = /^(?:color|date|datetime|email|month|number|password|range|search|tel|text|time|url|week)$/i; // 'hidden' is not in this list
11031    return this.each(function() {
11032        var t = this.type, tag = this.tagName.toLowerCase();
11033        if (re.test(t) || tag == 'textarea') {
11034            this.value = '';
11035        }
11036        else if (t == 'checkbox' || t == 'radio') {
11037            this.checked = false;
11038        }
11039        else if (tag == 'select') {
11040            this.selectedIndex = -1;
11041        }
11042		else if (t == "file") {
11043			if (/MSIE/.test(navigator.userAgent)) {
11044				$(this).replaceWith($(this).clone(true));
11045			} else {
11046				$(this).val('');
11047			}
11048		}
11049        else if (includeHidden) {
11050            // includeHidden can be the value true, or it can be a selector string
11051            // indicating a special test; for example:
11052            //  $('#myForm').clearForm('.special:hidden')
11053            // the above would clean hidden inputs that have the class of 'special'
11054            if ( (includeHidden === true && /hidden/.test(t)) ||
11055                 (typeof includeHidden == 'string' && $(this).is(includeHidden)) )
11056                this.value = '';
11057        }
11058    });
11059};
11060
11061/**
11062 * Resets the form data.  Causes all form elements to be reset to their original value.
11063 */
11064$.fn.resetForm = function() {
11065    return this.each(function() {
11066        // guard against an input with the name of 'reset'
11067        // note that IE reports the reset function as an 'object'
11068        if (typeof this.reset == 'function' || (typeof this.reset == 'object' && !this.reset.nodeType)) {
11069            this.reset();
11070        }
11071    });
11072};
11073
11074/**
11075 * Enables or disables any matching elements.
11076 */
11077$.fn.enable = function(b) {
11078    if (b === undefined) {
11079        b = true;
11080    }
11081    return this.each(function() {
11082        this.disabled = !b;
11083    });
11084};
11085
11086/**
11087 * Checks/unchecks any matching checkboxes or radio buttons and
11088 * selects/deselects and matching option elements.
11089 */
11090$.fn.selected = function(select) {
11091    if (select === undefined) {
11092        select = true;
11093    }
11094    return this.each(function() {
11095        var t = this.type;
11096        if (t == 'checkbox' || t == 'radio') {
11097            this.checked = select;
11098        }
11099        else if (this.tagName.toLowerCase() == 'option') {
11100            var $sel = $(this).parent('select');
11101            if (select && $sel[0] && $sel[0].type == 'select-one') {
11102                // deselect all other options
11103                $sel.find('option').selected(false);
11104            }
11105            this.selected = select;
11106        }
11107    });
11108};
11109
11110// expose debug var
11111$.fn.ajaxSubmit.debug = false;
11112
11113// helper fn for console logging
11114function log() {
11115    if (!$.fn.ajaxSubmit.debug)
11116        return;
11117    var msg = '[jquery.form] ' + Array.prototype.join.call(arguments,'');
11118    if (window.console && window.console.log) {
11119        window.console.log(msg);
11120    }
11121    else if (window.opera && window.opera.postError) {
11122        window.opera.postError(msg);
11123    }
11124}
11125
11126})(jQuery);
11127
11128var colorshaken = false;
11129
11130function nxs_js_colorshake()
11131{
11132	if (colorshaken)
11133	{
11134		return;
11135	}
11136	if (!nxs_js_userhasadminpermissions())
11137	{
11138		// only one color shake
11139		colorshaken = true;
11140	}
11141
11142	if (!nxs_js_inwpbackend())
11143	{
11144		nxs_js_updatecss_themecss_actualrequest();
11145		nxs_js_updatecss_manualcss_actualrequest();
11146		$("#nxs-load-cover").hide();
11147	}
11148}
11149
11150
11151/* Chosen v1.0.0 | (c) 2011-2013 by Harvest | MIT License, https://github.com/harvesthq/chosen/blob/master/LICENSE.md */
11152!function(){var a,AbstractChosen,Chosen,SelectParser,b,c={}.hasOwnProperty,d=function(a,b){function d(){this.constructor=a}for(var e in b)c.call(b,e)&&(a[e]=b[e]);return d.prototype=b.prototype,a.prototype=new d,a.__super__=b.prototype,a};SelectParser=function(){function SelectParser(){this.options_index=0,this.parsed=[]}return SelectParser.prototype.add_node=function(a){return"OPTGROUP"===a.nodeName.toUpperCase()?this.add_group(a):this.add_option(a)},SelectParser.prototype.add_group=function(a){var b,c,d,e,f,g;for(b=this.parsed.length,this.parsed.push({array_index:b,group:!0,label:this.escapeExpression(a.label),children:0,disabled:a.disabled}),f=a.childNodes,g=[],d=0,e=f.length;e>d;d++)c=f[d],g.push(this.add_option(c,b,a.disabled));return g},SelectParser.prototype.add_option=function(a,b,c){return"OPTION"===a.nodeName.toUpperCase()?(""!==a.text?(null!=b&&(this.parsed[b].children+=1),this.parsed.push({array_index:this.parsed.length,options_index:this.options_index,value:a.value,text:a.text,html:a.innerHTML,selected:a.selected,disabled:c===!0?c:a.disabled,group_array_index:b,classes:a.className,style:a.style.cssText})):this.parsed.push({array_index:this.parsed.length,options_index:this.options_index,empty:!0}),this.options_index+=1):void 0},SelectParser.prototype.escapeExpression=function(a){var b,c;return null==a||a===!1?"":/[\&\<\>\"\'\`]/.test(a)?(b={"<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#x27;","`":"&#x60;"},c=/&(?!\w+;)|[\<\>\"\'\`]/g,a.replace(c,function(a){return b[a]||"&amp;"})):a},SelectParser}(),SelectParser.select_to_array=function(a){var b,c,d,e,f;for(c=new SelectParser,f=a.childNodes,d=0,e=f.length;e>d;d++)b=f[d],c.add_node(b);return c.parsed},AbstractChosen=function(){function AbstractChosen(a,b){this.form_field=a,this.options=null!=b?b:{},AbstractChosen.browser_is_supported()&&(this.is_multiple=this.form_field.multiple,this.set_default_text(),this.set_default_values(),this.setup(),this.set_up_html(),this.register_observers())}return AbstractChosen.prototype.set_default_values=function(){var a=this;return this.click_test_action=function(b){return a.test_active_click(b)},this.activate_action=function(b){return a.activate_field(b)},this.active_field=!1,this.mouse_on_container=!1,this.results_showing=!1,this.result_highlighted=null,this.result_single_selected=null,this.allow_single_deselect=null!=this.options.allow_single_deselect&&null!=this.form_field.options[0]&&""===this.form_field.options[0].text?this.options.allow_single_deselect:!1,this.disable_search_threshold=this.options.disable_search_threshold||0,this.disable_search=this.options.disable_search||!1,this.enable_split_word_search=null!=this.options.enable_split_word_search?this.options.enable_split_word_search:!0,this.group_search=null!=this.options.group_search?this.options.group_search:!0,this.search_contains=this.options.search_contains||!1,this.single_backstroke_delete=null!=this.options.single_backstroke_delete?this.options.single_backstroke_delete:!0,this.max_selected_options=this.options.max_selected_options||1/0,this.inherit_select_classes=this.options.inherit_select_classes||!1,this.display_selected_options=null!=this.options.display_selected_options?this.options.display_selected_options:!0,this.display_disabled_options=null!=this.options.display_disabled_options?this.options.display_disabled_options:!0},AbstractChosen.prototype.set_default_text=function(){return this.default_text=this.form_field.getAttribute("data-placeholder")?this.form_field.getAttribute("data-placeholder"):this.is_multiple?this.options.placeholder_text_multiple||this.options.placeholder_text||AbstractChosen.default_multiple_text:this.options.placeholder_text_single||this.options.placeholder_text||AbstractChosen.default_single_text,this.results_none_found=this.form_field.getAttribute("data-no_results_text")||this.options.no_results_text||AbstractChosen.default_no_result_text},AbstractChosen.prototype.mouse_enter=function(){return this.mouse_on_container=!0},AbstractChosen.prototype.mouse_leave=function(){return this.mouse_on_container=!1},AbstractChosen.prototype.input_focus=function(){var a=this;if(this.is_multiple){if(!this.active_field)return setTimeout(function(){return a.container_mousedown()},50)}else if(!this.active_field)return this.activate_field()},AbstractChosen.prototype.input_blur=function(){var a=this;return this.mouse_on_container?void 0:(this.active_field=!1,setTimeout(function(){return a.blur_test()},100))},AbstractChosen.prototype.results_option_build=function(a){var b,c,d,e,f;for(b="",f=this.results_data,d=0,e=f.length;e>d;d++)c=f[d],b+=c.group?this.result_add_group(c):this.result_add_option(c),(null!=a?a.first:void 0)&&(c.selected&&this.is_multiple?this.choice_build(c):c.selected&&!this.is_multiple&&this.single_set_selected_text(c.text));return b},AbstractChosen.prototype.result_add_option=function(a){var b,c;return a.search_match?this.include_option_in_results(a)?(b=[],a.disabled||a.selected&&this.is_multiple||b.push("active-result"),!a.disabled||a.selected&&this.is_multiple||b.push("disabled-result"),a.selected&&b.push("result-selected"),null!=a.group_array_index&&b.push("group-option"),""!==a.classes&&b.push(a.classes),c=""!==a.style.cssText?' style="'+a.style+'"':"",'<li class="'+b.join(" ")+'"'+c+' data-option-array-index="'+a.array_index+'">'+a.search_text+"</li>"):"":""},AbstractChosen.prototype.result_add_group=function(a){return a.search_match||a.group_match?a.active_options>0?'<li class="group-result">'+a.search_text+"</li>":"":""},AbstractChosen.prototype.results_update_field=function(){return this.set_default_text(),this.is_multiple||this.results_reset_cleanup(),this.result_clear_highlight(),this.result_single_selected=null,this.results_build(),this.results_showing?this.winnow_results():void 0},AbstractChosen.prototype.results_toggle=function(){return this.results_showing?this.results_hide():this.results_show()},AbstractChosen.prototype.results_search=function(){return this.results_showing?this.winnow_results():this.results_show()},AbstractChosen.prototype.winnow_results=function(){var a,b,c,d,e,f,g,h,i,j,k,l,m;for(this.no_results_clear(),e=0,g=this.get_search_text(),a=g.replace(/[-[\]{}()*+?.,\\^$|#\s]/g,"\\$&"),d=this.search_contains?"":"^",c=new RegExp(d+a,"i"),j=new RegExp(a,"i"),m=this.results_data,k=0,l=m.length;l>k;k++)b=m[k],b.search_match=!1,f=null,this.include_option_in_results(b)&&(b.group&&(b.group_match=!1,b.active_options=0),null!=b.group_array_index&&this.results_data[b.group_array_index]&&(f=this.results_data[b.group_array_index],0===f.active_options&&f.search_match&&(e+=1),f.active_options+=1),(!b.group||this.group_search)&&(b.search_text=b.group?b.label:b.html,b.search_match=this.search_string_match(b.search_text,c),b.search_match&&!b.group&&(e+=1),b.search_match?(g.length&&(h=b.search_text.search(j),i=b.search_text.substr(0,h+g.length)+"</em>"+b.search_text.substr(h+g.length),b.search_text=i.substr(0,h)+"<em>"+i.substr(h)),null!=f&&(f.group_match=!0)):null!=b.group_array_index&&this.results_data[b.group_array_index].search_match&&(b.search_match=!0)));return this.result_clear_highlight(),1>e&&g.length?(this.update_results_content(""),this.no_results(g)):(this.update_results_content(this.results_option_build()),this.winnow_results_set_highlight())},AbstractChosen.prototype.search_string_match=function(a,b){var c,d,e,f;if(b.test(a))return!0;
vendor: 12,394 bytes, line 11152
11152if(this.enable_split_word_search&&(a.indexOf(" ")>=0||0===a.indexOf("["))&&(d=a.replace(/\[|\]/g,"").split(" "),d.length))for(e=0,f=d.length;f>e;e++)if(c=d[e],b.test(c))return!0},AbstractChosen.prototype.choices_count=function(){var a,b,c,d;if(null!=this.selected_option_count)return this.selected_option_count;for(this.selected_option_count=0,d=this.form_field.options,b=0,c=d.length;c>b;b++)a=d[b],a.selected&&(this.selected_option_count+=1);return this.selected_option_count},AbstractChosen.prototype.choices_click=function(a){return a.preventDefault(),this.results_showing||this.is_disabled?void 0:this.results_show()},AbstractChosen.prototype.keyup_checker=function(a){var b,c;switch(b=null!=(c=a.which)?c:a.keyCode,this.search_field_scale(),b){case 8:if(this.is_multiple&&this.backstroke_length<1&&this.choices_count()>0)return this.keydown_backstroke();if(!this.pending_backstroke)return this.result_clear_highlight(),this.results_search();break;case 13:if(a.preventDefault(),this.results_showing)return this.result_select(a);break;case 27:return this.results_showing&&this.results_hide(),!0;case 9:case 38:case 40:case 16:case 91:case 17:break;default:return this.results_search()}},AbstractChosen.prototype.container_width=function(){return null!=this.options.width?this.options.width:""+this.form_field.offsetWidth+"px"},AbstractChosen.prototype.include_option_in_results=function(a){return this.is_multiple&&!this.display_selected_options&&a.selected?!1:!this.display_disabled_options&&a.disabled?!1:a.empty?!1:!0},AbstractChosen.browser_is_supported=function(){return"Microsoft Internet Explorer"===window.navigator.appName?document.documentMode>=8:/iP(od|hone)/i.test(window.navigator.userAgent)?!1:/Android/i.test(window.navigator.userAgent)&&/Mobile/i.test(window.navigator.userAgent)?!1:!0},AbstractChosen.default_multiple_text="Select Some Options",AbstractChosen.default_single_text="Select an Option",AbstractChosen.default_no_result_text="No results match",AbstractChosen}(),a=jQuery,a.fn.extend({chosen:function(b){return AbstractChosen.browser_is_supported()?this.each(function(){var c,d;c=a(this),d=c.data("chosen"),"destroy"===b&&d?d.destroy():d||c.data("chosen",new Chosen(this,b))}):this}}),Chosen=function(c){function Chosen(){return b=Chosen.__super__.constructor.apply(this,arguments)}return d(Chosen,c),Chosen.prototype.setup=function(){return this.form_field_jq=a(this.form_field),this.current_selectedIndex=this.form_field.selectedIndex,this.is_rtl=this.form_field_jq.hasClass("chosen-rtl")},Chosen.prototype.set_up_html=function(){var b,c;return b=["chosen-container"],b.push("chosen-container-"+(this.is_multiple?"multi":"single")),this.inherit_select_classes&&this.form_field.className&&b.push(this.form_field.className),this.is_rtl&&b.push("chosen-rtl"),c={"class":b.join(" "),style:"width: "+this.container_width()+";",title:this.form_field.title},this.form_field.id.length&&(c.id=this.form_field.id.replace(/[^\w]/g,"_")+"_chosen"),this.container=a("<div />",c),this.is_multiple?this.container.html('<ul class="chosen-choices"><li class="search-field"><input type="text" value="'+this.default_text+'" class="default" autocomplete="off" style="width:25px;" /></li></ul><div class="chosen-drop"><ul class="chosen-results"></ul></div>'):this.container.html('<a class="chosen-single chosen-default" tabindex="-1"><span>'+this.default_text+'</span><div><b></b></div></a><div class="chosen-drop"><div class="chosen-search"><input type="text" autocomplete="off" /></div><ul class="chosen-results"></ul></div>'),this.form_field_jq.hide().after(this.container),this.dropdown=this.container.find("div.chosen-drop").first(),this.search_field=this.container.find("input").first(),this.search_results=this.container.find("ul.chosen-results").first(),this.search_field_scale(),this.search_no_results=this.container.find("li.no-results").first(),this.is_multiple?(this.search_choices=this.container.find("ul.chosen-choices").first(),this.search_container=this.container.find("li.search-field").first()):(this.search_container=this.container.find("div.chosen-search").first(),this.selected_item=this.container.find(".chosen-single").first()),this.results_build(),this.set_tab_index(),this.set_label_behavior(),this.form_field_jq.trigger("chosen:ready",{chosen:this})},Chosen.prototype.register_observers=function(){var a=this;return this.container.bind("mousedown.chosen",function(b){a.container_mousedown(b)}),this.container.bind("mouseup.chosen",function(b){a.container_mouseup(b)}),this.container.bind("mouseenter.chosen",function(b){a.mouse_enter(b)}),this.container.bind("mouseleave.chosen",function(b){a.mouse_leave(b)}),this.search_results.bind("mouseup.chosen",function(b){a.search_results_mouseup(b)}),this.search_results.bind("mouseover.chosen",function(b){a.search_results_mouseover(b)}),this.search_results.bind("mouseout.chosen",function(b){a.search_results_mouseout(b)}),this.search_results.bind("mousewheel.chosen DOMMouseScroll.chosen",function(b){a.search_results_mousewheel(b)}),this.form_field_jq.bind("chosen:updated.chosen",function(b){a.results_update_field(b)}),this.form_field_jq.bind("chosen:activate.chosen",function(b){a.activate_field(b)}),this.form_field_jq.bind("chosen:open.chosen",function(b){a.container_mousedown(b)}),this.search_field.bind("blur.chosen",function(b){a.input_blur(b)}),this.search_field.bind("keyup.chosen",function(b){a.keyup_checker(b)}),this.search_field.bind("keydown.chosen",function(b){a.keydown_checker(b)}),this.search_field.bind("focus.chosen",function(b){a.input_focus(b)}),this.is_multiple?this.search_choices.bind("click.chosen",function(b){a.choices_click(b)}):this.container.bind("click.chosen",function(a){a.preventDefault()})},Chosen.prototype.destroy=function(){return a(document).unbind("click.chosen",this.click_test_action),this.search_field[0].tabIndex&&(this.form_field_jq[0].tabIndex=this.search_field[0].tabIndex),this.container.remove(),this.form_field_jq.removeData("chosen"),this.form_field_jq.show()},Chosen.prototype.search_field_disabled=function(){return this.is_disabled=this.form_field_jq[0].disabled,this.is_disabled?(this.container.addClass("chosen-disabled"),this.search_field[0].disabled=!0,this.is_multiple||this.selected_item.unbind("focus.chosen",this.activate_action),this.close_field()):(this.container.removeClass("chosen-disabled"),this.search_field[0].disabled=!1,this.is_multiple?void 0:this.selected_item.bind("focus.chosen",this.activate_action))},Chosen.prototype.container_mousedown=function(b){return this.is_disabled||(b&&"mousedown"===b.type&&!this.results_showing&&b.preventDefault(),null!=b&&a(b.target).hasClass("search-choice-close"))?void 0:(this.active_field?this.is_multiple||!b||a(b.target)[0]!==this.selected_item[0]&&!a(b.target).parents("a.chosen-single").length||(b.preventDefault(),this.results_toggle()):(this.is_multiple&&this.search_field.val(""),a(document).bind("click.chosen",this.click_test_action),this.results_show()),this.activate_field())},Chosen.prototype.container_mouseup=function(a){return"ABBR"!==a.target.nodeName||this.is_disabled?void 0:this.results_reset(a)},Chosen.prototype.search_results_mousewheel=function(a){var b,c,d;return b=-(null!=(c=a.originalEvent)?c.wheelDelta:void 0)||(null!=(d=a.originialEvent)?d.detail:void 0),null!=b?(a.preventDefault(),"DOMMouseScroll"===a.type&&(b=40*b),this.search_results.scrollTop(b+this.search_results.scrollTop())):void 0},Chosen.prototype.blur_test=function(){return!this.active_field&&this.container.hasClass("chosen-container-active")?this.close_field():void 0},Chosen.prototype.close_field=function(){return a(document).unbind("click.chosen",this.click_test_action),this.active_field=!1,this.results_hide(),this.container.removeClass("chosen-container-active"),this.clear_backstroke(),this.show_search_field_default(),this.search_field_scale()},Chosen.prototype.activate_field=function(){return this.container.addClass("chosen-container-active"),this.active_field=!0,this.search_field.val(this.search_field.val()),this.search_field.focus()},Chosen.prototype.test_active_click=function(b){return this.container.is(a(b.target).closest(".chosen-container"))?this.active_field=!0:this.close_field()},Chosen.prototype.results_build=function(){return this.parsing=!0,this.selected_option_count=null,this.results_data=SelectParser.select_to_array(this.form_field),this.is_multiple?this.search_choices.find("li.search-choice").remove():this.is_multiple||(this.single_set_selected_text(),this.disable_search||this.form_field.options.length<=this.disable_search_threshold?(this.search_field[0].readOnly=!0,this.container.addClass("chosen-container-single-nosearch")):(this.search_field[0].readOnly=!1,this.container.removeClass("chosen-container-single-nosearch"))),this.update_results_content(this.results_option_build({first:!0})),this.search_field_disabled(),this.show_search_field_default(),this.search_field_scale(),this.parsing=!1},Chosen.prototype.result_do_highlight=function(a){var b,c,d,e,f;if(a.length){if(this.result_clear_highlight(),this.result_highlight=a,this.result_highlight.addClass("highlighted"),d=parseInt(this.search_results.css("maxHeight"),10),f=this.search_results.scrollTop(),e=d+f,c=this.result_highlight.position().top+this.search_results.scrollTop(),b=c+this.result_highlight.outerHeight(),b>=e)return this.search_results.scrollTop(b-d>0?b-d:0);if(f>c)return this.search_results.scrollTop(c)}},Chosen.prototype.result_clear_highlight=function(){return this.result_highlight&&this.result_highlight.removeClass("highlighted"),this.result_highlight=null},Chosen.prototype.results_show=function(){return this.is_multiple&&this.max_selected_options<=this.choices_count()?(this.form_field_jq.trigger("chosen:maxselected",{chosen:this}),!1):(this.container.addClass("chosen-with-drop"),this.form_field_jq.trigger("chosen:showing_dropdown",{chosen:this}),this.results_showing=!0,this.search_field.focus(),this.search_field.val(this.search_field.val()),this.winnow_results())},Chosen.prototype.update_results_content=function(a){return this.search_results.html(a)},Chosen.prototype.results_hide=function(){return this.results_showing&&(this.result_clear_highlight(),this.container.removeClass("chosen-with-drop"),this.form_field_jq.trigger("chosen:hiding_dropdown",{chosen:this})),this.results_showing=!1},Chosen.prototype.set_tab_index=function(){var a;return this.form_field.tabIndex?(a=this.form_field.tabIndex,this.form_field.tabIndex=-1,this.search_field[0].tabIndex=a):void 0},Chosen.prototype.set_label_behavior=function(){var b=this;return this.form_field_label=this.form_field_jq.parents("label"),!this.form_field_label.length&&this.form_field.id.length&&(this.form_field_label=a("label[for='"+this.form_field.id+"']")),this.form_field_label.length>0?this.form_field_label.bind("click.chosen",function(a){return b.is_multiple?b.container_mousedown(a):b.activate_field()}):void 0},Chosen.prototype.show_search_field_default=function(){return this.is_multiple&&this.choices_count()<1&&!this.active_field?(this.search_field.val(this.default_text),this.search_field.addClass("default")):(this.search_field.val(""),this.search_field.removeClass("default"))},Chosen.prototype.search_results_mouseup=function(b){var c;return c=a(b.target).hasClass("active-result")?a(b.target):a(b.target).parents(".active-result").first(),c.length?(this.result_highlight=c,this.result_select(b),this.search_field.focus()):void 0},Chosen.prototype.search_results_mouseover=function(b){var c;return c=a(b.target).hasClass("active-result")?a(b.target):a(b.target).parents(".active-result").first(),c?this.result_do_highlight(c):void 0},Chosen.prototype.search_results_mouseout=function(b){return a(b.target).hasClass("active-result")?this.result_clear_highlight():void 0},Chosen.prototype.choice_build=function(b){var c,d,e=this;return c=a("<li />",{"class":"search-choice"}).html("<span>"+b.html+"</span>"),b.disabled?c.addClass("search-choice-disabled"):(d=a("<a />",{"class":"search-choice-close","data-option-array-index":b.array_index}),d.bind("click.chosen",function(a){return e.choice_destroy_link_click(a)}),c.append(d)),this.search_container.before(c)},Chosen.prototype.choice_destroy_link_click=function(b){return b.preventDefault(),b.stopPropagation(),this.is_disabled?void 0:this.choice_destroy(a(b.target))},Chosen.prototype.choice_destroy=function(a){return this.result_deselect(a[
111520].getAttribute("data-option-array-index"))?(this.show_search_field_default(),this.is_multiple&&this.choices_count()>0&&this.search_field.val().length<1&&this.results_hide(),a.parents("li").first().remove(),this.search_field_scale()):void 0},Chosen.prototype.results_reset=function(){return this.form_field.options[0].selected=!0,this.selected_option_count=null,this.single_set_selected_text(),this.show_search_field_default(),this.results_reset_cleanup(),this.form_field_jq.trigger("change"),this.active_field?this.results_hide():void 0},Chosen.prototype.results_reset_cleanup=function(){return this.current_selectedIndex=this.form_field.selectedIndex,this.selected_item.find("abbr").remove()},Chosen.prototype.result_select=function(a){var b,c,d;return this.result_highlight?(b=this.result_highlight,this.result_clear_highlight(),this.is_multiple&&this.max_selected_options<=this.choices_count()?(this.form_field_jq.trigger("chosen:maxselected",{chosen:this}),!1):(this.is_multiple?b.removeClass("active-result"):(this.result_single_selected&&(this.result_single_selected.removeClass("result-selected"),d=this.result_single_selected[0].getAttribute("data-option-array-index"),this.results_data[d].selected=!1),this.result_single_selected=b),b.addClass("result-selected"),c=this.results_data[b[0].getAttribute("data-option-array-index")],c.selected=!0,this.form_field.options[c.options_index].selected=!0,this.selected_option_count=null,this.is_multiple?this.choice_build(c):this.single_set_selected_text(c.text),(a.metaKey||a.ctrlKey)&&this.is_multiple||this.results_hide(),this.search_field.val(""),(this.is_multiple||this.form_field.selectedIndex!==this.current_selectedIndex)&&this.form_field_jq.trigger("change",{selected:this.form_field.options[c.options_index].value}),this.current_selectedIndex=this.form_field.selectedIndex,this.search_field_scale())):void 0},Chosen.prototype.single_set_selected_text=function(a){return null==a&&(a=this.default_text),a===this.default_text?this.selected_item.addClass("chosen-default"):(this.single_deselect_control_build(),this.selected_item.removeClass("chosen-default")),this.selected_item.find("span").text(a)},Chosen.prototype.result_deselect=function(a){var b;return b=this.results_data[a],this.form_field.options[b.options_index].disabled?!1:(b.selected=!1,this.form_field.options[b.options_index].selected=!1,this.selected_option_count=null,this.result_clear_highlight(),this.results_showing&&this.winnow_results(),this.form_field_jq.trigger("change",{deselected:this.form_field.options[b.options_index].value}),this.search_field_scale(),!0)},Chosen.prototype.single_deselect_control_build=function(){return this.allow_single_deselect?(this.selected_item.find("abbr").length||this.selected_item.find("span").first().after('<abbr class="search-choice-close"></abbr>'),this.selected_item.addClass("chosen-single-with-deselect")):void 0},Chosen.prototype.get_search_text=function(){return this.search_field.val()===this.default_text?"":a("<div/>").text(a.trim(this.search_field.val())).html()},Chosen.prototype.winnow_results_set_highlight=function(){var a,b;return b=this.is_multiple?[]:this.search_results.find(".result-selected.active-result"),a=b.length?b.first():this.search_results.find(".active-result").first(),null!=a?this.result_do_highlight(a):void 0},Chosen.prototype.no_results=function(b){var c;return c=a('<li class="no-results">'+this.results_none_found+' "<span></span>"</li>'),c.find("span").first().html(b),this.search_results.append(c)},Chosen.prototype.no_results_clear=function(){return this.search_results.find(".no-results").remove()},Chosen.prototype.keydown_arrow=function(){var a;return this.results_showing&&this.result_highlight?(a=this.result_highlight.nextAll("li.active-result").first())?this.result_do_highlight(a):void 0:this.results_show()},Chosen.prototype.keyup_arrow=function(){var a;return this.results_showing||this.is_multiple?this.result_highlight?(a=this.result_highlight.prevAll("li.active-result"),a.length?this.result_do_highlight(a.first()):(this.choices_count()>0&&this.results_hide(),this.result_clear_highlight())):void 0:this.results_show()},Chosen.prototype.keydown_backstroke=function(){var a;return this.pending_backstroke?(this.choice_destroy(this.pending_backstroke.find("a").first()),this.clear_backstroke()):(a=this.search_container.siblings("li.search-choice").last(),a.length&&!a.hasClass("search-choice-disabled")?(this.pending_backstroke=a,this.single_backstroke_delete?this.keydown_backstroke():this.pending_backstroke.addClass("search-choice-focus")):void 0)},Chosen.prototype.clear_backstroke=function(){return this.pending_backstroke&&this.pending_backstroke.removeClass("search-choice-focus"),this.pending_backstroke=null},Chosen.prototype.keydown_checker=function(a){var b,c;switch(b=null!=(c=a.which)?c:a.keyCode,this.search_field_scale(),8!==b&&this.pending_backstroke&&this.clear_backstroke(),b){case 8:this.backstroke_length=this.search_field.val().length;break;case 9:this.results_showing&&!this.is_multiple&&this.result_select(a),this.mouse_on_container=!1;break;case 13:a.preventDefault();break;case 38:a.preventDefault(),this.keyup_arrow();break;case 40:a.preventDefault(),this.keydown_arrow()}},Chosen.prototype.search_field_scale=function(){var b,c,d,e,f,g,h,i,j;if(this.is_multiple){for(d=0,h=0,f="position:absolute; left: -1000px; top: -1000px; display:none;",g=["font-size","font-style","font-weight","font-family","line-height","text-transform","letter-spacing"],i=0,j=g.length;j>i;i++)e=g[i],f+=e+":"+this.search_field.css(e)+";";return b=a("<div />",{style:f}),b.text(this.search_field.val()),a("body").append(b),h=b.width()+25,b.remove(),c=this.container.outerWidth(),h>c-10&&(h=c-10),this.search_field.css({width:h+"px"})}},Chosen}(AbstractChosen)}.call(this);
11153
11154// kudos to https://github.com/mikesherov/jquery-idletimer/
11155
11156/*
11157 * Copyright (c) 2009 Nicholas C. Zakas
11158 *
11159 * Permission is hereby granted, free of charge, to any person obtaining a copy
11160 * of this software and associated documentation files (the "Software"), to deal
11161 * in the Software without restriction, including without limitation the rights
11162 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11163 * copies of the Software, and to permit persons to whom the Software is
11164 * furnished to do so, subject to the following conditions:
11165 *
11166 * The above copyright notice and this permission notice shall be included in
11167 * all copies or substantial portions of the Software.
11168 *
11169 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
11170 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
11171 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
11172 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
11173 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
11174 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
11175 * THE SOFTWARE.
11176 */
11177
11178( function( $ ) {
11179
11180$.idleTimer = function( firstParam, elem, opts ) {
11181
11182	// defaults that are to be stored as instance props on the elem
11183	opts = $.extend( {
11184		startImmediately: true,   //starts a timeout as soon as the timer is set up
11185		idle: false,              //indicates if the user is idle
11186		enabled: true,            //indicates if the idle timer is enabled
11187		timeout: 30000,           //the amount of time (ms) before the user is considered idle
11188		events: "mousemove keydown DOMMouseScroll mousewheel mousedown touchstart touchmove" // activity is one of these events
11189	}, opts );
11190
11191
11192	elem = elem || document;
11193
11194	var jqElem = $( elem ),
11195		obj = jqElem.data("idleTimerObj") || {},
11196
11197		/* (intentionally not documented)
11198		 * Toggles the idle state and fires an appropriate event.
11199		 * @return {void}
11200		 */
11201		toggleIdleState = function( myelem ) {
11202
11203			// curse you, mozilla setTimeout lateness bug!
11204			if ( typeof myelem === "number" ) {
11205				myelem = undefined;
11206			}
11207
11208			var obj = $.data( myelem || elem, "idleTimerObj" );
11209
11210			//toggle the state
11211			obj.idle = !obj.idle;
11212
11213			// reset timeout
11214			var elapsed = ( +new Date() ) - obj.olddate;
11215			obj.olddate = +new Date();
11216
11217			// handle Chrome always triggering idle after js alert or comfirm popup
11218			if ( obj.idle && ( elapsed < opts.timeout ) ) {
11219				obj.idle = false;
11220				clearTimeout( $.idleTimer.tId );
11221				if ( opts.enabled ) {
11222					$.idleTimer.tId = setTimeout( toggleIdleState, opts.timeout );
11223				}
11224				return;
11225			}
11226
11227			// create a custom event, but first, store the new state on the element
11228			// and then append that string to a namespace
11229			var event = $.Event( $.data( elem, "idleTimer", obj.idle ? "idle" : "active" ) + ".idleTimer" );
11230			$( elem ).trigger( event );
11231		},
11232
11233		/**
11234		 * Stops the idle timer. This removes appropriate event handlers
11235		 * and cancels any pending timeouts.
11236		 * @return {void}
11237		 * @method stop
11238		 * @static
11239		 */
11240		stop = function( jqElem ) {
11241
11242			var obj = jqElem.data("idleTimerObj") || {};
11243
11244			//set to disabled
11245			obj.enabled = false;
11246
11247			//clear any pending timeouts
11248			clearTimeout( obj.tId );
11249
11250			//detach the event handlers
11251			jqElem.off(".idleTimer");
11252		};
11253
11254	obj.olddate = obj.olddate || +new Date();
11255
11256	if ( typeof firstParam === "number" ) {
11257		opts.timeout = firstParam;
11258	} else if ( firstParam === "destroy" ) {
11259		stop( jqElem );
11260		return this;
11261	} else if ( firstParam === "getElapsedTime" ) {
11262		return ( +new Date() ) - obj.olddate;
11263	}
11264
11265
11266	/* (intentionally not documented)
11267	 * Handles a user event indicating that the user isn't idle.
11268	 * @param {Event} event A DOM2-normalized event object.
11269	 * @return {void}
11270	 */
11271	jqElem.on( $.trim( ( opts.events + " " ).split(" ").join(".idleTimer ") ), function() {
11272		var obj = $.data( this, "idleTimerObj" );
11273
11274		//clear any existing timeout
11275		clearTimeout( obj.tId );
11276
11277		//if the idle timer is enabled
11278		if ( obj.enabled ){
11279			//if it's idle, that means the user is no longer idle
11280			if ( obj.idle ){
11281				toggleIdleState( this );
11282			}
11283
11284			//set a new timeout
11285			obj.tId = setTimeout( toggleIdleState, obj.timeout );
11286		}
11287	});
11288
11289	obj.idle = opts.idle;
11290	obj.enabled = opts.enabled;
11291	obj.timeout = opts.timeout;
11292
11293	//set a timeout to toggle state. May wish to omit this in some situations
11294	if ( opts.startImmediately ) {
11295		obj.tId = setTimeout( toggleIdleState, obj.timeout );
11296	}
11297
11298	// assume the user is active for the first x seconds.
11299	jqElem.data( "idleTimer", "active" );
11300
11301	// store our instance on the object
11302	jqElem.data( "idleTimerObj", obj );
11303};
11304
11305$.fn.idleTimer = function( firstParam, opts ) {
11306	// Allow omission of opts for backward compatibility
11307	if ( !opts ) {
11308		opts = {};
11309	}
11310
11311	if ( this[0] ){
11312		$.idleTimer( firstParam, this[0], opts );
11313	}
11314
11315	return this;
11316};
11317
11318})( jQuery );
11319
11320nxs_js_popupsession_startnewcontext();
11321var nxsfrontendscriptloaded = true;

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.