PageSourceSearch

https://tanenbaum.org/wp-content/plugins/grassblade/js/script.js?ver=7.0.0

js tanenbaum.org collected 2026-10-02 02:14:54 UTC 62,831 bytes, 1,777 lines download raw bytes

1var GB = [];
2	function showHideOptional(id) {
3		var table = document.getElementById(id);
4		var display_status = table.style.display;
5
6
7		if(display_status == "none")
8		{
9			table.style.display = "block";
10		}
11		else
12			table.style.display = "none";
13	}
14	function grassblade_esc_attr(text) {
15		if (!text || typeof text !== 'string') {
16			return '';
17		}
18
19		// 1. Replace special characters with HTML entities
20		// This covers & < > " ' (ENT_QUOTES logic)
21		const map = {
22			'&': '&amp;',
23			'<': '&lt;',
24			'>': '&gt;',
25			'"': '&quot;',
26			"'": '&#039;'
27		};
28
29		return text.replace(/[&<>"']/g, function(m) {
30			return map[m];
31		});
32	}
33
34	function grassblade_show_lightbox(id, src, completion_data, width, height, aspect) {
35		if (document.getElementById("grassblade_lightbox") == null) {
36			jQuery("body").append("<div id='grassblade_lightbox'></div>");
37		}
38
39		window.grassblade_lightbox = window.grassblade_lightbox || {};
40		window.grassblade_lightbox[id] = {id: id, src:src, width:width, height:height, aspect:aspect};
41
42		var sizes = grassblade_lightbox_get_sizes(window.grassblade_lightbox[id]);
43		src += (src.search(/[?]/) < 0) ? "?" : "&";
44		src += "h=" + encodeURIComponent(sizes.inner_height) + "&w=" + encodeURIComponent(sizes.inner_width);
45
46		var completion_decoded = (typeof completion_data === "string")? JSON.parse(completion_data):completion_data;
47		var title = (completion_decoded && typeof completion_decoded.title === "string")? completion_decoded.title:"";
48		var completion_encoded = JSON.stringify(completion_decoded);
49
50		window.previousFocus = document.activeElement;
51
52		var html =
53			"<div class='grassblade_lightbox_overlay' onClick='return grassblade_hide_lightbox(" + grassblade_esc_attr(id) + ");'></div>" +
54			"<div role='dialog' aria-modal='true' aria-label='Content viewer' tabindex='-1' id='" + grassblade_esc_attr(id) + "' class='grassblade_lightbox' style='top:" + grassblade_esc_attr(sizes.top) + ";bottom:" + grassblade_esc_attr(sizes.top) + ";left:" + grassblade_esc_attr(sizes.left) + ";right:" + grassblade_esc_attr(sizes.left) + ";width:" + grassblade_esc_attr(sizes.width) + "; height:" + grassblade_esc_attr(sizes.height) + ";'>" +
55				"<div class='grassblade_close'>" +
56					"<a class='grassblade_close_btn' href='#' onClick='return grassblade_hide_lightbox(" + grassblade_esc_attr(completion_encoded) + ");' aria-label='Close content viewer' role='button'>X</a>" +
57				"</div>" +
58				"<iframe class='grassblade_lightbox_iframe' title='" + grassblade_esc_attr(title) + "'  data-completion='" + grassblade_esc_attr(completion_encoded) + "' frameBorder='0' src='" + grassblade_esc_attr(src) + "' style='height: 100%; width: 100%; position: absolute; left: 0; top: 0; border: 0;' webkitallowfullscreen mozallowfullscreen allowfullscreen allow='accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture' onLoad='grassblade_get_lightbox_iframe();'></iframe>" +
59			"</div>";
60
61		jQuery("#grassblade_lightbox").html(html);
62		jQuery("#grassblade_lightbox").show().focus();
63		setupLightboxEscape(id, completion_data);
64	}
65
66	function setupLightboxEscape(id, completion_data) {
67		const lightbox = document.getElementById(id);
68		if (!lightbox) return;
69
70		// The function that actually does the closing
71		const handleEscape = function(event) {
72			if (event.key === 'Escape') {
73				event.preventDefault();
74				grassblade_hide_lightbox(completion_data);
75
76				// Clean up the listener on the main document so it doesn't linger
77				document.removeEventListener('keydown', handleEscape);
78			}
79		};
80
81		// 1. Attach to the main parent document
82		// This catches Esc if the user is focused on the lightbox div or the close button
83		document.addEventListener('keydown', handleEscape);
84
85		// 2. Attach to the iframe's internal document
86		const iframe = lightbox.querySelector('.grassblade_lightbox_iframe');
87		if (iframe) {
88			// We have to wait for the iframe to load before we can access its internal document
89			iframe.addEventListener('load', function() {
90				try {
91					// Try to inject the event listener into the iframe's content
92					iframe.contentWindow.document.addEventListener('keydown', handleEscape);
93				} catch (error) {
94					// If the iframe src is on a completely different domain (e.g., youtube.com),
95					// the browser's security rules (CORS) will block this and throw an error.
96					console.warn("Could not attach Esc listener to iframe due to cross-origin rules.");
97				}
98			});
99		}
100	}
101	function grassblade_lightbox_get_sizes(options) {
102		var width = options.width;
103		var height = options.height;
104		var aspect = options.aspect;
105
106		var window_width = Math.ceil(jQuery(window).width() * 1) - 22; //Available width and height is less by 22px, because there is 11px border.  onClick='return grassblade_hide_lightbox();'
107		var window_height = Math.ceil(jQuery(window).height() * 1) - 22;
108
109
110		if(aspect > 0)
111		{
112			if(width.indexOf("%") > 0)
113			var width_number = Math.ceil(window_width * parseFloat(width)/100);
114			else
115			var width_number = Math.ceil(parseFloat(width));
116
117			var height_number = Math.ceil(parseFloat(width_number / aspect));
118
119			if(width_number > window_width) {
120				height_number = Math.ceil(window_width  * height_number / width_number);
121				width_number = window_width;
122			}
123
124			if(height_number > window_height) {
125				width_number = Math.ceil( window_height * width_number / height_number );
126				height_number = window_height;
127			}
128		}
129		else
130		{
131			if(width.indexOf("%") > 0)
132			var width_number = Math.ceil(window_width * parseFloat(width)/100);
133			else
134			var width_number = Math.ceil(parseFloat(width));
135
136			if(height.indexOf("%") > 0)
137			var height_number = Math.ceil(window_height * parseFloat(height)/100);
138			else
139			var height_number = Math.ceil(parseFloat(height));
140		}
141
142		//console.log({window_width:window_width, window_height:window_height, width_number:width_number, height_number:height_number, width:width, height:height, aspect:aspect});
143
144		var top = ((window_height - height_number) / 2 );
145		var left = ((window_width - width_number) / 2 );
146		var top = top < 0? 0:top + "px";
147		var left = left < 0? 0:left + "px";
148		var h = (height_number + 22) + "px"; //Increase width and height by 22 for the border.
149		var w = (width_number + 22) + "px";
150		//console.log({top:top, height:h, width:w});
151
152		return {top:top,left:left, height:h, width:w, inner_height: height_number, inner_width: width_number};
153	}
154	function gb_is_completion_behaviour_enabled( completion_data ) {
155		var completion_behaviour_enabled =  ( typeof gb_data != 'undefined' && gb_data.completion_tracking_enabled && (gb_data.completion_type != 'hide_button' || is_grassblade_voc_enabled() ) && gb_data.is_guest == '' && !gb_data.is_admin );
156
157		if( !completion_behaviour_enabled || typeof completion_data != "object" && completion_data == null )
158			return completion_behaviour_enabled;
159
160		return ((completion_data.completion_type != 'hide_button' || is_grassblade_voc_enabled() ) && completion_data.completion_tracking != false  && ( completion_data.completion_without_lrs || gb_data.lr
160s_exists ));
161	}
162	function grassblade_hide_lightbox(completion_data) {
163		if(!jQuery("body").hasClass("gb-fullscreen")) {
164			jQuery("#grassblade_lightbox").hide();
165			jQuery("#grassblade_lightbox").html('');
166		}
167		if(gb_is_completion_behaviour_enabled(completion_data)) {
168			grassblade_content_completion_request(completion_data.content_id,completion_data.registration,2);
169		}
170		if(typeof window.previousFocus == "object" && window.previousFocus != null) {
171			window.previousFocus.focus();
172		}
173		return false;
174	}
175
176	function show_xapi_content_meta_box_change() {
177		var show_xapi_content = jQuery("#show_xapi_content");
178		if(show_xapi_content.length == 0)
179			return;
180
181		edit_link = jQuery('#grassblade_add_to_content_edit_link');
182		if(show_xapi_content.val() > 0) {
183			edit_link.show();
184			jQuery("body").addClass("has_xapi_content");
185		}
186		else {
187			jQuery("body").removeClass("has_xapi_content");
188			edit_link.hide();
189		}
190
191		jQuery("#completion_tracking_enabled").hide();
192		jQuery("#completion_tracking_disabled").hide();
193
194		if(jQuery("#show_xapi_content option:selected").attr("completion-tracking") == "1") {
195			jQuery("#completion_tracking_enabled").show();
196		}
197		else if(jQuery("#show_xapi_content option:selected").attr("completion-tracking") == "")
198		{
199			jQuery("#completion_tracking_disabled").show();
200		}
201	}
202
203	function grassblade_reigster_gb_search_table() {
204		jQuery(".gb_table_search").on("keyup", function() {
205			var search = jQuery(this).val();
206			var id = jQuery(this).data("tableid");
207			var myHilitor = new Hilitor(id); // id of the element to parse
208			myHilitor.apply(search);
209
210			if(search.length < 3)
211			{
212				jQuery("#" + id + " tr").show();
213				return;
214			}
215			jQuery("#" + id + " tbody").find("tr").each(function(i, v) {
216				if(jQuery(v).find("mark").length)
217					jQuery(v).show();
218				else
219					jQuery(v).hide();
220			});
221		});
222	}
223	function grassblade_register_folder_delete_buttons() {
224		jQuery("#grassblade_delete_folders_table .delete_folder_button").on("click", function() {
225			var button = jQuery(this);
226			var path = button.data("path");
227
228			var ok = confirm("Are you sure you want to delete the folder '" + path +"'?");
229			if(ok) {
230				var nonce = jQuery("#gb_folder_delete").val();
231				if(typeof path == "string" && typeof nonce == "string") {
232					var data = {
233						"path": path,
234						"nonce": nonce
235					};
236					button.html("Deleting...");
237					jQuery.ajax({
238						type: "GET",
239						url: ajaxurl + "?action=gb_folder_delete",
240						data: data,
241						contentType: "json",
242						dataType: "json",
243						success: function(response){
244
245							if(typeof response.message == "string")
246								button.html(response.message);
247							if(response.status)
248								button.css("background-color", "orange");
249							else
250								button.css("background-color", "black");
251
252							console.log(response);
253						}
254					});
255				}
256			}
257		});
258	}
259
260	function grassblade_table_colors_changed() {
261		if(jQuery("#table_th_bg_color").length == 0)
262			return;
263
264		var styles = " .grassblade_table th { background: " + jQuery("#table_th_bg_color").val() + " !important; color: " + jQuery("#table_th_txt_color").val() + " !important; }";
265		styles += " .grassblade_table td { background: " + jQuery("#table_tb_color1").val() + " !important; color: " + jQuery("#table_tb_txt_color").val() + " !important; }";
266		styles += " .grassblade_table tr.tr_odd td { background: " + jQuery("#table_tb_color2").val() + " !important; }";
267		jQuery("#grassblade_table_styles").html(styles);
268	}
269	function grassblade_learndash_focusmode_switching() {
270		jQuery(".ld-focus-sidebar-trigger .ld-icon-arrow-left").on("click", function() { setTimeout(function() { grassblade_xapi_content_autosize_content();}, 500) });
271	}
272
273	function grassblade_show_errors() {
274		if(jQuery(".grassblade_errors").length <= 0 || typeof window.wp != "object" || typeof window.wp.data != "object"  || typeof window.wp.data.select != "function"  || typeof window.wp.data.dispatch != "function")
275			return;
276
277		jQuery(".grassblade_errors").each(function(i, v) {
278			var text = jQuery(v).text();
279			var actions = [];
280			jQuery(v).find("a").each(function(i, v) {console.log(i, v); actions.push({url:jQuery(v).attr("href"), "label": jQuery(v).text()}); });
281
282			wp.data.dispatch( 'core/notices' ).createNotice(
283				'notice', // Can be one of: success, info, warning, error.
284				text, // Text string to display.
285				{
286					isDismissible: true, // Whether the user can dismiss the notice.
287					// Any actions the user can perform.
288					actions: actions,
289				}
290			);
291		});
292
293	}
294	function grassblade_xapi_content_autosize_content() {
295		jQuery(".grassblade_iframe").each(function(i, element) {
296			var width = parseInt(jQuery(element).width());
297			var width_parent = jQuery(element).parent().width();
298
299			if(jQuery(element).attr("height").indexOf("%") > 0) {
300				var configured_height = parseInt(jQuery(element).attr("height"));
301				var configured_width = parseInt(jQuery(element).attr("width"));
302				var height = Math.ceil(width * configured_height / configured_width) + 1;
303				jQuery(element).height(height);
304				jQuery(element).attr("height", height);
305			}
306
307			var aspect = jQuery(element).data('aspect');
308			if(aspect != undefined && aspect > 0) {
309				var height = Math.ceil(width / aspect);
310				jQuery(element).height(height);
311				jQuery(element).attr("height", height);
312			}
313
314			/* Center width */
315			var left_diff = (width_parent - width) * 1;
316			if(left_diff > 4)
317			{
318				var left = Math.ceil(left_diff/2);
319				jQuery(element).css('left', left);
320			}
321
322			var src = jQuery(element).attr('src');
323			if( typeof src == "undefined" || src == "" ) {
324				if(height == undefined)
325					height = jQuery(element).height();
326
327				var src = jQuery(element).data('src');
328				if( typeof src == "undefined" )
329				var src = jQuery(element).data('data-src'); //To fix iframe lazyloading conflict with SD Optimizer (SiteGround)
330
331				src += (src.search(/[?]/) < 0)? "?":"&";
332				src += "h=" + height + "&w=" + width;
333				jQuery(element).attr("src", src);
334			}
335			//console.log({height:height, width:width, left:left, width_parent:width_parent});
336			//grassblade_add_completion_script_to_iframe('grassblade_iframe');
337		});
338	}
339	function grassblade_xapi_content_edit_script() {
340		grassblade_enable_button_selector();
341
342		jQuery("h2.gb-content-selector a").on("click", function() {
343			jQuery("h2.gb-content-selector a").removeClass("nav-tab-active");
344			jQuery(this).addClass("nav-tab-active");
345			if(jQuery(this).hasClass("nav-tab-content-url")) {
346				jQuery("#field-src").show();
347				jQuery("#field-activity_id").show();
348				jQuery("#field-xapi_content").hide();
349				jQuery("#field-video, #field-video_hide_controls, #field-video_autoplay, #field-interactive_video, #field-video_pause_on_tab_switch").hide();
350				jQuery("#field-dropbox").hide();
351				jQuery("#field-h5p_content").hide();
352			}
353			else if(jQuery(this).hasClass("nav-tab-video")) {
354				jQuery("#field-src").hide();
355				jQuery("#field-activity_id").hide();
356				jQuery("#field-xapi_content").show();
357				jQuery("#field-video, #field-video_hide_controls, #field-video_autoplay, #field-interactive_video, #field-video_pause_on_tab_switch").show();
358				jQuery("#field-dropbox").hide();
359				jQuery("#field-h5p_content").hide();
360			}
361			else if(jQuery(this).hasClass("nav-tab-h5p")) {
362				jQuery("#field-src").hide();
363				jQuery("#field-activity_id").hide();
364				jQuery("#field-xapi_content").hide();
365				jQuery("#field-video, #field-video_hide_controls, #field-video_autoplay, #field-interactive_video, #field-video_pause_on_tab_switch").hide();
366				jQuery("#field-dropbox").hide();
367				jQuery("#field-h5p_content").show();
368			}
369			else if(jQuery(this).hasClass("nav-tab-upload")) {
370				jQuery("#field-src").hide();
371				jQuery("#field-activity_id").show();
372				jQuery("#field-xapi_content").show();
373				jQuery("#field-video, #field-video_hide_controls, #field-video_autoplay, #field-interactive_video, #field-video_pause_on_tab_switch").hide();
374				jQuery("#field-dropbox").hide();
375				jQuery("#field-h5p_content").hide();
376			}
377			else if(jQuery(this).hasClass("nav-tab-dropbox")) {
378				jQuery("#field-src").hide();
379				jQuery("#field-activity_id").show();
380				jQuery("#field-xapi_content").hide();
381				jQuery("#field-video, #field-video_hide_controls, #field-video_autoplay, #field-interactive_video, #field-video_pause_on_tab_switch").hide();
382				jQuery("#field-dropbox").show();
383				jQuery("#field-h5p_content").hide();
384			}
385			return false;
386		});
387
388		if(jQuery("#xapi_content[type=file]").length > 0)
389			gb_xapi_content_uploader('xapi_content');
390
391		if(jQuery("#field-dropbox").length > 0)
392			grassblade_dropbox_init();
393
394		if(jQuery("input#video").val().trim() != "")
395			jQuery("a.nav-tab-video").trigger('click');
396		else if(jQuery("input#src").val().trim() != "")
397			jQuery("a.nav-tab-content-url").trigger('click');
398		else
399			jQuery("a.nav-tab-upload").trigger('click');
400
401		jQuery("select#button_type").on("change", function() {
402			if(jQuery(this).val() == "0")
403			{
404				jQuery("#field-text").show();
405				jQuery("#field-link_button_image").hide();
406			}
407			else if(jQuery(this).val() == "1"){
408				jQuery("#field-text").hide();
409				jQuery("#field-link_button_image").show();
410			}
411		});
412		jQuery("select#button_type").trigger('change');
413
414		jQuery("select#target").on("change", function() {
415			if(jQuery(this).val() == "")
416			{
417				jQuery("#field-button_type").hide();
418				jQuery("#field-text").hide();
419				jQuery("#field-link_button_image").hide();
420			}
421			else
422			{
423				jQuery("#field-button_type").show();
424				jQuery("select#button_type").trigger('change');
425			}
426
427		});
428		jQuery("select#target").trigger('change');
429
430		jQuery("#completion_tracking").on("change", function() {
431			if (jQuery("#completion_tracking").is(":checked")) {
432				jQuery("#field-completion_type").show();
433				jQuery("#field-completion_by_module").show();
434			} else {
435				jQuery("#field-completion_type").hide();
436				jQuery("#field-completion_by_module").hide();
437			}
438		});
439		jQuery("#completion_tracking").trigger('change');
440
441		jQuery("#expire_attempts").on("change", function() {
442			if (jQuery("#expire_attempts").is(":checked")) {
443				jQuery("#field-attempt_expiration_days").show();
444			} else {
445				jQuery("#field-attempt_expiration_days").hide();
446			}
447		});
448		jQuery("#expire_attempts").trigger('change');
449
450		jQuery("#resume_behaviour").on("change", function() {
451			if(jQuery(this).val() == "auto") {
452				jQuery("#registration").data("original_value", jQuery("#registration").val().trim());
453				jQuery("#registration").val("auto");
454				jQuery("#field-registration").hide();
455			}
456			else
457			{
458				var original_value = jQuery("#registration").data("original_value");
459				var current_value = jQuery("#registration").val().trim()
460				original_value = ( typeof original_value == "string" && original_value.length == 36 )? original_value : ((current_value != "auto" && current_value.length > 0)? current_value : grassblade_gen_uuid());
461
462				jQuery("#registration").val(original_value);
463				jQuery("#field-registration").show();
464			}
465		});
466		jQuery("#resume_behaviour").trigger('change');
467
468		jQuery("#registration").on("keyup", function(e) {
469			grassblade_validate_registration_field(jQuery(e.target));
470		});
471		grassblade_validate_registration_field(jQuery("#registration"));
472
473		/* Add aspect ratio options */
474		var aspect = (parseFloat(jQuery("#field-width #width").val()) / parseFloat(jQuery("#field-height #height").val())).toFixed(4);
475		aspect = (aspect == "NaN")? 0:aspect;
476		jQuery(".grassblade_aspect_ratios").html("<span class='grassblade_aspect_ratio' data-aspect='1.7777' onClick='grassblade_set_aspect(this)'>16:9</span> | <span class='grassblade_aspect_ratio'  data-aspect='1.3333' onClick='grassblade_set_aspect(this)'>4:3</span> | <span class='grassblade_aspect_ratio'  data-aspect='1' onClick='grassblade_set_aspect(this)'>1:1</span> | <span id='aspect_slider_span'><input type='range' min='0' max='6' value='" + aspect + "' id='aspect_slider'  step='0.001'  onChange='grassblade_set_aspect(this)'/> <input type='text' id='aspect_slider_value' value='" + aspect + "'  maxlength='5' onChange='grassblade_set_aspect(this)' onkeyup='grassblade_set_aspect(this)' /></span>");
477		jQuery("#field-width #width, #field-height #height").on("keyup", function(event) {
478			if(jQuery("#aspect_lock").is(":checked")) {
479				grassblade_size_setting_changed(event.target);
480			}
481		});
482
483		grassblade_add_content_change();
484		//grassblade_form_submit_refresh();
485
486	}
487	// Reusable function to handle the validation UI
488	function grassblade_validate_registration_field( field ) {
489		var small = field.siblings("small");
490		var value = field.val();
491		if ( value != "auto" && !grassblade_validate_uuid(value)) {
492			field.parent().css("color", "red");
493
494			// Check if the error span already exists to prevent duplicates
495			if (small.find(".gb-uuid-error").length === 0) {
496				small.append("<span class='gb-uuid-error' style='color: red;'><br><br>Incorrect Registration ID value, it should be a valid UUID.</span>");
497			}
498		} else {
499			field.parent().css("color", "inherit");
500			small.find(".gb-uuid-error").remove();
501		}
502	}
503	function grassblade_size_setting_changed(el) {
504		if(jQuery("#aspect_lock").is(":checked")) {
505			var param = jQuery(el).attr("id");
506			var width = jQuery("#field-width #width").val();
507			var height = jQuery("#field-height #height").val();
508			var aspect = jQuery("#aspect_slider_value").val();
509			aspect = (aspect > 0)? aspect:1.7777;
510
511			if(param == "width") {
512				var unit = width.replace(parseFloat(width), '');
513
514				h = parseFloat( parseFloat(width) / aspect ).toFixed(2);
515				h = (h == NaN || h == "NaN")? "":h;
516				h = h + unit;
517				jQuery("#field-height #height").val(h);
518
519				if(unit == "%" && parseFloat(h) > 100)
520					jQuery("#field-height #height").css('background', 'red');
521				else
522				{
523					jQuery("#field-height #height").css('background', 'yellow');
524					setTimeout(function() {
525						jQuery("#field-height #height").css('background', 'none');
526					}, 200);
527				}
528			}
529			else
530			{
531				var unit = height.replace(parseFloat(height), '');
532
533				w = parseFloat( parseFloat(height) * aspect ).toFixed(2);
534				w = (w == NaN || w == "NaN")? "":w;
535				w = w + unit;
536				jQuery("#field-width #width").val(w);
537
538				if(unit == "%" && parseFloat(w) > 100)
539					jQuery("#field-width #width").css('background', 'red');
540				else
541				{
542					jQuery("#field-width #width").css('background', 'yellow');
543					setTimeout(function() {
544						jQuery("#field-width #width").css('background', 'none');
545					}, 200);
546				}
547			}
548		}
549	}
550	function grassblade_set_aspect(el) {
551		if(typeof el == "number" || jQuery(el).attr("class") == "grassblade_aspect_ratio") { 			//Ratio click
552			if(typeof el == "number")
553			var aspect = el;
554			else
555			var aspect = jQuery(el).data("aspect") * 1;
556
557			jQuery("#aspect_slider").val(aspect);
558			jQuery("#aspect_slider_value").val(aspect);
559
560			jQuery("#aspect_slider_value").css('background', 'yellow');
561			setTimeout(function() {
562				jQuery("#aspect_slider_value").css('background', 'none');
563			}, 200);
564
565			jQuery("#aspect_slider_span").css('background', 'yellow');
566			setTimeout(function() {
567				jQuery("#aspect_slider_span").css('background', 'none');
568			}, 200);
569		}
570		if(jQuery(el).attr("id") == "aspect_slider") {	// Slider Change
571			var aspect = jQuery(el).val() * 1;
572			jQuery("#aspect_slider_value").val(aspect);
573
574			jQuery("#aspect_slider_value").css('background', 'yellow');
575			setTimeout(function() {
576				jQuery("#aspect_slider_value").css('background', 'none');
577			}, 200);
578		}
579		else
580		if(jQuery(el).attr("id") == "aspect_slider_value") { // Input Change
581			var aspect = jQuery(el).val() * 1;
582			jQuery("#aspect_slider").val(aspect);
583
584			jQuery("#aspect_slider_span").css('background', 'yellow');
585			setTimeout(function() {
586				jQuery("#aspect_slider_span").css('background', 'none');
587			}, 200);
588		}
589
590		var width = jQuery("#field-width #width").val();
591		var height = jQuery("#field-height #height").val();
592
593		var w, unit;
594
595		if(jQuery("#aspect_lock").is(":checked"))
596		{	//Aspect Locked
597
598			if(width == "" ||  parseFloat(width) > 100  ||  parseFloat(width) == 0 )
599				w = "100%";
600			else
601				w = parseFloat(width) + "%";
602
603			h = parseFloat( parseFloat(w) / aspect ).toFixed(2);
604
605			if(h > 100)
606			{
607				h = 100;
608				w = 100 * aspect + "%";
609			}
610			h = h + "%";
611		}
612		else
613		{ //Aspect Not Locked.
614			if(width == "" || width == "0" || width == "0%")
615				w = "100%";
616			else
617				w = width;
618
619			var unit = w.replace(parseFloat(w), '');
620			h = parseFloat( parseFloat(w) / aspect ).toFixed(2);
621			if(unit == "%" && h > 100) {
622				h = 100;
623				w = 100 * aspect + "%";
624			}
625			h = h + unit;
626		}
627
628		if(width != w)
629		{
630			jQuery("#field-width #width").val(w);
631			jQuery("#field-width #width").css('background', 'yellow');
632			setTimeout(function() {
633				jQuery("#field-width #width").css('background', 'none');
634			}, 200);
635		}
636		if(height != h)
637		{
638			jQuery("#field-height #height").val(h);
639			jQuery("#field-height #height").css('background', 'yellow');
640			setTimeout(function() {
641				jQuery("#field-height #height").css('background', 'none');
642			}, 200);
643		}
644	}
645
646	/* Add gb-fullscreen class when video is in fullscreen */
647	function gb_fullscreen_class() {
648		if (document.fullscreenElement ||
649			document.mozFullScreenElement ||
650			document.webkitFullscreenElement ||
651			document.msFullscreenElement ) {
652		  if(!jQuery("body").hasClass("gb-fullscreen"))
653			jQuery("body").addClass("gb-fullscreen");
654		}
655		else
656		  jQuery("body").removeClass("gb-fullscreen");
657	}
658
659	function grassblade_enable_button_selector() {
660	  var _custom_media = true,
661		  _orig_send_attachment = wp.media.editor.send.attachment;
662
663	  jQuery('.gb_upload_button').on("click", function(e) {
664		var send_attachment_bkp = wp.media.editor.send.attachment;
665		var button = jQuery(this);
666		var id = button.attr('id');
667		_custom_media = true;
668		wp.media.editor.send.attachment = function(props, attachment){
669		  if ( _custom_media ) {
670			jQuery("#"+id+"-url").val(attachment.url);
671			jQuery("#"+id+"-src").attr("src", attachment.url);
672		  } else {
673			return _orig_send_attachment.apply( this, [props, attachment] );
674		  };
675		}
676
677		wp.media.editor.open(button);
678		return false;
679	  });
680
681	  jQuery('.add_media').on('click', function(){
682		_custom_media = false;
683	  });
684	}
685	function grassblade_update() {
686		if(jQuery("#src").val().length > 0 || jQuery("#video").val().length > 0 )
687		{
688			jQuery("#gb_upload_message").addClass("has_content");
689			jQuery("#gb_preview_message").addClass("has_content");
690		}
691		gb_save_post();
692	}
693	function gb_remove_upload_progress_bar() {
694		jQuery("#gb_progress_text").html('');
695		jQuery("#gb_progress").removeClass();
696	}
697	function gb_save_post() {
698		if(typeof wp == "object" &&
699		   wp != null &&
700		   typeof wp.data == "object" &&
701		   typeof wp.data.dispatch == "function" &&
702		   wp.data.dispatch("core/editor") != null &&
703		   typeof wp.data.dispatch("core/editor").savePost == "function")
704
705			wp.data.dispatch("core/editor").savePost();
706		else
707			jQuery(".is-primary").trigger('click');
708	}
709
710function grassblade_add_content_change() {
711
712	jQuery("select#h5p_content").on("change", function() {
713		if(jQuery("select#h5p_content").val() > 0)
714		{
715			var h5p_content_id = jQuery("select#h5p_content").val();
716			var url = gb_data.ajax_url + "?action=h5p_embed&id=" + parseInt(h5p_content_id);
717			jQuery("#activity_id").val(url);
718			jQuery("#src").val(url);
719			jQuery("#video").val('');
720			grassblade_update();
721		}
722	});
723
724	jQuery("input#video").on("change", function() {
725		jQuery("input#activity_id").val(jQuery("input#video").val());
726
727		if(jQuery("input#video").val().length > 0)
728		{
729			var url = jQuery("input#video").val();
730			jQuery("#activity_id").val(url);
731			jQuery("#video").val(url);
732			jQuery("#src").val('');
733			jQuery("#h5p_content").val(0);
734			grassblade_update();
735		}
736
737		/* Default value for MP3 player height */
738		if(jQuery("input#height").val() == "" && jQuery("input#video").val().split(".").pop().split("?")[0] == "mp3") {
739			jQuery("input#height").val("50px");
740		}
741
742	});
743}
744
745function gb_xapi_content_uploader(id) {
746
747	var upload_msg = "";
748	const gb_uploader = new plupload.Uploader({
749			runtimes: 'html5,flash,silverlight,html4',
750			'browse_button': id,
751			url: gb_data.ajax_url + "?action=gb_upload_content_file&gb_nonce=" + jQuery("[name=gb_xapi_content_box_content_nonce]").val(),
752			'max_retries': content_data.plupload.max_retries,
753			'dragdrop': true,
754			'drop_element': id,
755			'multi_selection': false,
756			'file_data_name': 'xapi_content',
757			filters: {
758				'max_file_size': content_data.uploadSize,
759				'mime_types': [
760					{
761						title: 'Zip files',
762						extensions: 'zip'
763					},
764					{
765						title: 'MP4 files',
766						extensions: 'mp4'
767					},
768					{
769						title: 'MP3 files',
770						extensions: 'mp3'
771					},
772					{
773						title: 'WebM files',
774						extensions: 'webm'
775					},
776					{
777						title: 'Mov files',
778						extensions: 'mov'
779					}
780					// {
781					// 	title: 'Mkv files',
782					// 	extensions: 'mkv'
783					// },
784					// {
785					// 	title: 'Ogg files',
786					// 	extensions: 'ogg,ogv'
787					// },
788					// {
789					// 	title: 'Flac files',
790					// 	extensions: 'flac'
791					// },
792					// {
793					// 	title: 'Wav files',
794					// 	extensions: 'wav'
795					// },
796					// {
797					// 	title: 'M4a files',
798					// 	extensions: 'm4a'
799					// },
800					// {
801					// 	title: 'Avi files',
802					// 	extensions: 'avi'
803					// }
804				]
805			},
806			multipart_params : {
807				"post_id" :  gb_data.post_id,
808			},
809			init: {
810				PostInit: function() {},
811
812				UploadProgress: function( up, file ) {
813					if(file.percent < 100)
814					upload_msg = content_data.uploading;
815					else
816					upload_msg = content_data.processing;
817
818					upload_msg = upload_msg.replace("[file_name]", file.name +' ('+ ( ( file.size / 1024 ) / 1024 ).toFixed( 1 ) +' mb) ').replace( "[percent]", file.percent+'%');
819
820					document.getElementById( 'gb_progress_text' ).innerHTML = upload_msg;
821					jQuery("#gb_progress_bar").css("background-color" , "#62A21D");
822					var percent = (file.percent > 95)? 95:file.percent;
823					jQuery("#gb_progress_bar").width(percent+'%');
824				},
825
826				FileUploaded: function( upldr, file, object ) {
827
828					const info = jQuery.parseJSON( object.response );
829
830					if ( info.response == 'success' ) {
831						upload_msg = content_data.processed;
832						upload_msg = upload_msg.replace("[file_name]", file.name);
833						document.getElementById( 'gb_progress_text' ).innerHTML = upload_msg;
834
835						jQuery("#gb_progress_bar").width('100%');
836						grassblade_content_success_handling(info);
837					}
838
839					if ( info.response == 'error' ) {
840						grassblade_content_error_handling(info);
841					}
842				},
843
844				FilesAdded: function( up, files ) {
845					if ( 1 < gb_uploader.files.length ) {
846						gb_uploader.removeFile( gb_uploader.files[0]);
847					}
848
849					jQuery('#gb_progress').addClass('upload_progress');
850					document.getElementById( 'gb_progress_text' ).innerHTML = gb_uploader.files[0].name +'('+( ( gb_uploader.files[0].size / 1024 ) / 1024 ).toFixed( 1 )+'mb)';
851					gb_uploader.start();
852				},
853
854				Error: function( up, err ) {
855					jQuery('#gb_progress').addClass('upload_progress');
856					document.getElementById( 'gb_progress_text' ).innerHTML = err.message;
857					jQuery("#gb_progress_bar").css("background-color" , "red");
858					jQuery("#gb_progress_text").css("color" , "white");
859					//console.log( err );
860				}
861			}
862		});
863
864	gb_uploader.init();
865}
866
867function grassblade_dropbox_init() {
868	if (typeof Dropbox != 'undefined') {
869		options = {
870			success: function(files){
871				grassblade_upload_dropbox(files);
872			},
873			linkType: "direct",
874		};
875		var button = Dropbox.createChooseButton(options);
876		document.getElementById("dropbox").appendChild(button);
877	}
878}
879
880function grassblade_upload_dropbox(files){
881	var file = files[0].name;
882	var link = files[0].link;
883	var nonce = jQuery("[name=gb_xapi_content_box_content_nonce]").val();
884
885	jQuery('#gb_progress').addClass('upload_progress');
886
887	jQuery('#gb_progress_text').text(content_data.dropbox_uploading.replace("[file_name]", file));
888
889	jQuery("#gb_progress_bar").css("background-color" , "#62A21D");
890	jQuery("#gb_progress_bar").width('95%');
891
892	var form_data = new FormData();
893
894	form_data.append("file", file);
895	form_data.append("link", link);
896	form_data.append("post_id", gb_data.post_id);
897	form_data.append('action', 'dropbox_upload_file');
898	form_data.append('gb_nonce', nonce);
899
900	jQuery.ajax({
901		type: 'POST',
902		url: gb_data.ajax_url,
903		data: form_data,
904		contentType: false,
905		processData: false,
906		success: function(response){
907			const info = JSON.parse(response);
908
909			if ( info.response == 'success' ) {
910				jQuery('#gb_progress_text').text(content_data.processed.replace("[file_name]", file));
911
912				jQuery("#gb_progress_bar").width('100%');
913
914				grassblade_content_success_handling(info);
915			}
916			if ( info.response == 'error' ) {
917				grassblade_content_error_handling(info);
918			}
919		}
920	});
921}
922
923function grassblade_content_success_handling(info) {
924	if (info.data.src) {
925		jQuery('#src').val(info.data.src);
926	} else
927		jQuery('#src').val('');
928
929	if (info.data.video) {
930		jQuery('#video').val(info.data.video);
931	} else
932		jQuery('#video').val('');
933
934	if (info.data.version) {
935		jQuery('#version').val(info.data.version);
936	} else
937		jQuery('#version').val('');
938
939	if (jQuery('#passing_percentage').val() == "" && info.data.passing_percentage) {
940		jQuery('#passing_percentage').val(info.data.passing_percentage);
941	}
942
943	if (info.data.target) {
944		jQuery('#target').val(info.data.target);
945	}
946
947	if (typeof(info.data.h5p_content_id) == "undefined" || !(info.data.h5p_content_id > 0) )
948		jQuery('select#h5p_content').val(0);
949
950	jQuery('#activity_id').val(info.data.activity_id);
951
952	if( typeof  info.switch_tab == "string")
953		jQuery(info.switch_tab).trigger('click');
954
955	if(typeof info.data.title == "string" && info.data.title.length > 0 && typeof  wp.data == "object" && typeof  wp.data.select("core/editor") == "object" && wp.data.select("core/editor") != null && wp.data.select("core/editor").getCurrentPost().title == "")
956		wp.data.dispatch( 'core/editor' ).editPost( { title: info.data.title  } );
957
958	if(typeof info.data.description == "string" && info.data.description.length > 0 && typeof  wp.data == "object" && typeof  wp.data.select("core/editor") == "object" && wp.data.select("core/editor") != null && wp.data.select("core/editor").getCurrentPost().content == "")
959	{
960		const newBlock = wp.blocks.createBlock( "core/paragraph", {
961		    content: info.data.description,
962		});
963		wp.data.dispatch( "core/editor" ).insertBlocks( newBlock );
964	}
965	jQuery("#gb_upload_message").addClass("has_content");
966	jQuery("#gb_preview_message").addClass("has_content");
967}
968
969function grassblade_content_error_handling(info){
970	document.getElementById( 'gb_progress_text' ).innerHTML = info.info;
971	jQuery("#gb_progress_bar").css("background-color" , "red");
972	jQuery("#gb_progress_text").css("color" , "white");
973}
974function grassblade_launch_link_click(event) {
975	window.open(event.href, "_blank");
976	console_log('Window Launch');
977	var completion_data = JSON.parse(event.getAttribute('data-completion'));
978	if(gb_is_completion_behaviour_enabled(completion_data)) {
979		setTimeout(function () {
980			grassblade_content_completion_request( completion_data.content_id , completion_data.registration, 0 );
981		}, 3000);
982	}
983	return false;
984}
985function is_grassblade_voc_enabled() {
986	return jQuery(".gb_voc").length > 0;
987}
988function grassblade_voc_show(content_id) {
989	if(content_id == "all")
990		jQuery(".gb_voc").removeClass("gb_voc");
991	else
992		jQuery(".gb_voc_"+content_id).removeClass("gb_voc").removeClass("gb_voc_" + content_id);
993}
994function grassblade_voc_init() {
995	jQuery.each(jQuery(".grassblade_iframe,.grassblade_launch_link"), function(i, content) {
996		var completion_data = grassblade_get_data_attribute(content, 'completion');
997		if(completion_data.completed) {
998			grassblade_voc_show(completion_data.content_id);
999			setTimeout(function () { grassblade_voc_show(completion_data.content_id); }, 2000);
1000		}
1001	});
1002}
1003
1004function grassblade_find_iframes_and_add_completion_script(){
1005	console_log("grassblade_find_iframes_and_add_completion_script")
1006	if(gb_is_completion_behaviour_enabled()) {
1007		var inpage_content = document.querySelectorAll('iframe.grassblade_iframe');
1008		for (var i = 0; i < inpage_content.length; i++) {
1009			var completion_data = grassblade_get_data_attribute(inpage_content[i], 'completion');
1010			if(gb_is_completion_behaviour_enabled(completion_data)) {
1011				grassblade_add_completion_script_to_iframe( document.querySelectorAll('iframe.grassblade_iframe')[i] );
1012			}
1013		}
1014	}
1015}
1016
1017function grassblade_get_lightbox_iframe() {
1018	if(gb_is_completion_behaviour_enabled()) {
1019		var lightbox_content = document.querySelectorAll('iframe.grassblade_lightbox_iframe');
1020		for (var i = 0; i < lightbox_content.length; i++) {
1021			var completion_data = grassblade_get_data_attribute(lightbox_content[i], 'completion');
1022			if(gb_is_completion_behaviour_enabled(completion_data)) {
1023				grassblade_add_completion_script_to_iframe( document.querySelectorAll('iframe.grassblade_lightbox_iframe')[i] );
1024			}
1025
1026		}
1027	}
1028}
1029
1030function grassblade_add_completion_script_to_iframe(iframe_content){
1031	console_log("grassblade_add_completion_script_to_iframe");
1032	if( iframe_content.contentDocument != null ) { // adding script to iframe to trigger completion
1033		if (iframe_content.contentDocument.querySelectorAll("script[src='"+gb_data.plugin_dir_url+"js/completion.js']").length <= 0){
1034			if(iframe_content.contentDocument.querySelector('body') != null){
1035				iframe_content_selector = iframe_content.contentDocument.querySelector('body');
1036			} else {
1037				iframe_content_selector = iframe_content.contentDocument.querySelector('head');
1038			}
1039			gb_scriptAppender(gb_data.plugin_dir_url+'js/completion.js', iframe_content_selector);
1040		}
1041	} else { // When not able to add or read script to iframe eg. external contents we start completion checking long pooling
1042		var completion_data = grassblade_get_data_attribute(iframe_content, 'completion');
1043		if ((completion_data.completion_tracking != false) && (completion_data.completion_type != 'hide_button' || is_grassblade_voc_enabled() )) {
1044			grassblade_content_completion_request( completion_data.content_id , completion_data.registration , 0);
1045		}
1046	}
1047}
1048
1049function gb_scriptAppender(src_path, selector) {
1050	var script = document.createElement("script");
1051	script.type = "text/javascript";
1052	script.src = src_path;
1053
1054	if (selector != null) {
1055		selector.appendChild(script);
1056	}
1057}
1058
1059function grassblade_content_completion_request(content_id,registration,n) {
1060	console_log('grassblade_content_completion_request');
1061	console_log(n);
1062
1063	if (gb_data.is_guest) {
1064		return;
1065	}
1066	jQuery('#grassblade_remark'+content_id).empty();
1067
1068	if ( n != 0 && gb_data.is_guest == '') { // Show Loader Only for in Page and Lightbox content , Not for New Window and guest user
1069		var result_loader = "<div><strong> " + gb_data.labels.content_getting_result + " </strong><div class='gb-loader'></div></div>";
1070		jQuery('#grassblade_remark'+content_id).append(result_loader);
1071	}
1072
1073	var activity_id = get_activity_id_by_content_id(content_id);
1074	if ((typeof(GB.completion) != "undefined") && GB.completion.disable_polling[activity_id]) {
1075		return; // if completion Code exist inside the content
1076	}
1077
1078	var data = {"content_id" : content_id , "registration" : registration, "post_id" :gb_data.post_id}
1079
1080	jQuery.ajax({
1081		type : "POST",
1082		dataType : "json",
1083		url : gb_data.ajax_url,
1084		data : { action: "grassblade_content_completion", data : data },
1085		success:function(data){
1086			console_log('success');
1087			console_log(data);
1088
1089			console_log('Value of n');
1090			console_log(n);
1091
1092			if (data != 0 && typeof(data.score_table) != "undefined") {
1093				// Get content Score and completion
1094				grassblade_show_completion(data,content_id);
1095			} else {
1096				console_log('Result Not Found Yet');
1097				if (n == 0) {
1098					grassblade_content_completion_request(content_id,registration,0);
1099				} else if(n == 1){
1100					jQuery('#grassblade_remark'+content_id).empty();
1101					return;
1102				} else{
1103					grassblade_content_completion_request(content_id,registration,n-1);
1104				}
1105			}
1106		},
1107		error: function(errorThrown){
1108			console_log('error');
1109			console_log(errorThrown);
1110			if (n = 0) {
1111				grassblade_content_completion_request(content_id,registration,1);
1112			} else if(n=1){
1113				return;
1114			} else{
1115				grassblade_content_completion_request(content_id,registration,n-1);
1116			}
1117		}
1118	});
1119}
1120
1121function grassblade_show_completion(data,content_id){
1122	console_log('grassblade_show_completion');
1123	console_log(data);
1124
1125	jQuery('#grassblade_remark'+content_id).empty();
1126
1127	if (jQuery('#grassblade_result-'+content_id).length) {
1128		jQuery('#grassblade_result-'+content_id).replaceWith(data.score_table);
1129	}
1130
1131	if (data.completion_result.status == 'Failed') {
1132		var result_msg = "<strong>" + gb_data.labels.content_failed_message + "</strong>";
1133		result_msg = result_msg.replace("%s", gb_data.labels.failed.toLowerCase());
1134	}
1135	console_log(data.completion_result);
1136	console_log(data.completion_result.status);
1137
1138	if (data.completion_result.status == 'Passed' || data.completion_result.status == 'Completed') {
1139		var result_msg = "<strong>" + gb_data.labels.content_passed_message + "</strong>";
1140		var status = data.completion_result.status.toLowerCase();
1141		result_msg = result_msg.replace("%s", gb_data.labels[status].toLowerCase());
1142
1143		grassblade_voc_show(content_id);
1144	}
1145
1146	if (data.post_completion == true)
1147		grassblade_voc_show("all");
1148
1149	if (data.post_completion == true && data.is_show_hide_button == true) {
1150		var post_completion_type = get_post_completion_type();
1151		grassblade_lms_content_completion(post_completion_type);
1152	}
1153	jQuery('#grassblade_remark'+content_id).append(result_msg);
1154}
1155
1156function grassblade_lms_content_completion(completion_type){
1157	if (completion_type == 'disable_until_complete') {
1158		//jQuery(gb_data.mark_complete_button).prop('disabled', false);
1159		jQuery(gb_data.mark_complete_button).removeAttr('disabled');
1160		jQuery(gb_data.mark_complete_button).removeClass('grassblade-button-disabled');
1161
1162	} else if (completion_type == 'hidden_until_complete') {
1163		jQuery(gb_data.mark_complete_button).show();
1164
1165	} else if (completion_type == 'completion_move_nextlevel') {
1166		setTimeout(function () {
1167			if (typeof gb_data.next_link == 'string' && gb_data.next_link.length > 1) {
1168				window.location.href = gb_data.next_link;
1169			} else if (typeof gb_data.next_button == 'string' && gb_data.next_button.length > 1) {
1170				if(typeof jQuery(gb_data.next_button).attr("href") == "string")
1171				window.location.href = jQuery(gb_data.next_button).attr("href");
1172				else
1173				jQuery(gb_data.next_button).trigger('click');
1174			}
1175		}, 3000);
1176
1177	} else if (completion_type == 'hide_button'){
1178		// we can add next button for this condition auto_completion
1179	} else {
1180		jQuery(gb_data.mark_complete_button).hide();
1181	}
1182}
1183
1184function grassblade_control_lms_mark_complete_btn(){
1185	if(!gb_data.is_admin && gb_data.completion_tracking_enabled && gb_data.mark_complete_button != ''){
1186		console_log(gb_data.completion_type);
1187		if (gb_data.completion_type == 'disable_until_complete') {
1188			jQuery(gb_data.mark_complete_button).attr('disabled','disabled');
1189		} else {
1190			jQuery(gb_data.mark_complete_button).hide();
1191		}
1192	}
1193}
1194
1195function gb_IsJsonString(str) {
1196	try {
1197		JSON.parse(str);
1198	} catch (e) {
1199		return false;
1200	}
1201	return true;
1202}
1203
1204function get_post_completion_type(){
1205	var all_contents = document.querySelectorAll('.grassblade');
1206	for (var i = all_contents.length - 1; i >= 0 ; i--) {
1207		var attributes_data = grassblade_get_data_attribute(all_contents[i].firstElementChild, 'completion');
1208		if (attributes_data.completion_tracking) {
1209			return attributes_data.completion_type;
1210		}
1211	}
1212}
1213
1214function get_completion_data_by_object_id(object_id){
1215	var all_contents = document.querySelectorAll('.grassblade');
1216	for (var i = 0; i < all_contents.length; i++) {
1217		var attributes_data = grassblade_get_data_attribute(all_contents[i].firstElementChild, 'completion');
1218		if (attributes_data.activity_id == object_id ) {
1219			return attributes_data;
1220		}
1221	}
1222}
1223
1224function get_activity_id_by_content_id(content_id){
1225	var all_contents = document.querySelectorAll('.grassblade');
1226	for (var i = 0; i < all_contents.length; i++) {
1227		var attributes_data = grassblade_get_data_attribute(all_contents[i].firstElementChild, 'completion');
1228		if (attributes_data.content_id == content_id ) {
1229			return attributes_data.activity_id;
1230		}
1231	}
1232}
1233
1234function grassblade_get_data_attribute(el, key, key2) {
1235	var el_val = jQuery(el).data(key);
1236	if(typeof key2 == "string")
1237	{
1238		return el_val[key2];
1239	}
1240	else
1241		return el_val;
1242}
1243
1244function call_grassblade_get_completion(data){
1245	if (typeof(data.statement) != "undefined"){
1246		var completion_data = get_completion_data_by_object_id(data.statement.object.id);
1247		if ((typeof(GB.completion) != "undefined") && GB.completion.disable_polling[data.statement.object.id]) {
1248			GB.completion.disable_polling[data.statement.object.id] = false;
1249		}
1250		console_log(completion_data);
1251		if (completion_data) {
1252			if ((completion_data.completion_tracking != false) && (completion_data.completion_type != 'hide_button' || is_grassblade_voc_enabled())){
1253				grassblade_content_completion_request(completion_data.content_id,completion_data.registration,2);
1254			}
1255		}
1256	}
1257}
1258
1259function console_log(arguments) {
1260  if(typeof window.gbdebug != "undefined")
1261  console.error(arguments);
1262}
1263
1264function get_gb_quiz_report(content_id,user_id,registration,statement_id) {
1265	var src = gb_data.ajax_url+'?action=gb_rich_quiz_report&id='+content_id;
1266
1267	if (typeof registration == "string" && registration.length > 1)
1268		src += '&registration='+registration;
1269
1270	if (typeof statement_id == "string" && statement_id.length > 1)
1271		src += '&statement_id='+statement_id;
1272
1273	if (!isNaN(user_id) && user_id != null)
1274		src += '&user_id='+user_id;
1275
1276	var quiz_report_iframe = '<div id="grassblade_quiz_report"><iframe id="xapi_quiz_report" class="gb_iframe_loader" style="width: 100%; height: 100%; border: none; overflow-x:hidden;" src='+src+'></iframe></div>';
1277	show_grassblade_reports_popup( quiz_report_iframe );
1278
1279	return false;
1280}
1281
1282function get_gb_question_report(content_id, group_id = '', group_type = '') {
1283	var src = gb_data.ajax_url+'?action=gb_question_report&id='+content_id;
1284	if(group_id)
1285	src = src + "&group_id=" + group_id;
1286	if(group_type)
1287	src = src + "&group_type=" + encodeURIComponent(group_type);
1288
1289	var quiz_report_iframe = '<div id="grassblade_question_report"><iframe id="xapi_quiz_report" class="gb_iframe_loader" style="width: 100%; height: 100%; border: none; overflow-x:hidden;" src='+src+'></iframe></div>';
1290	show_grassblade_reports_popup( quiz_report_iframe );
1291
1292	return false;
1293}
1294
1295function get_gb_quiz_report_request(context) {
1296	var content_id = jQuery(context).data("id");
1297	var user_id = jQuery(context).data("user");
1298	var statement_id = jQuery(context).data("statement");
1299	var registration = jQuery(context).data("registration");
1300
1301	if(!isNaN(content_id) && (typeof statement_id == "string" || typeof registration == "string"))
1302	{
1303		get_gb_quiz_report(content_id, user_id, registration, statement_id);
1304	}
1305}
1306
1307function grassblade_enable_quiz_report_links() {
1308	if( jQuery("#ld-profile").length > 0 )
1309	jQuery("#ld-profile").on("click", function(e) {
1310		if(jQuery(e.target).parent(".gb-quiz-report").length) {
1311			get_gb_quiz_report_request(jQuery(e.target).parent(".gb-quiz-report"));
1312		}
1313	});
1314	else
1315	jQuery("a.gb-quiz-report").on("click", function() {
1316		get_gb_quiz_report_request(this);
1317	});
1318}
1319function grassblade_hide_popup(){
1320	jQuery("#grassblade_quiz_report").hide();
1321	jQuery("#grassblade_quiz_report").html('');
1322	jQuery("#grassblade_reports_popup").hide();
1323}
1324function show_grassblade_reports_popup( body, header = "" ) {
1325	if(jQuery("#grassblade_reports_popup").length == 0) {
1326		const grassblade_reports_popup_html = `<div id="grassblade_reports_popup" style="display: none;" >
1327						<div class='grassblade_lightbox_overlay' onClick='return grassblade_hide_popup();'></div>
1328						<div class='grassblade_popup'>
1329							<span class='grassblade_close' onClick='return grassblade_hide_popup();' style="background: none;padding: 7px;position: sticky;top: 0; z-index: 10000;">X</span>
1330							<div class="gb-popup-body"></div>
1331						</div>
1332					</div>`;
1333		jQuery("body").append(grassblade_reports_popup_html);
1334	}
1335
1336	if( header.length > 0 ) {
1337		body = `<div class="gb-popup-header"><span class="gb-section-title">${header}</span></div>
1338				<div class="gb-section-body"><div id="grassblade_reports_popup_content">${body}</div></div>`;
1339	}
1340	jQuery("#grassblade_reports_popup .gb-popup-body").html( body );
1341	jQuery("#grassblade_reports_popup").show();
1342}
1343
1344function gb_highlight_text(search){
1345	var myHilitor = new Hilitor("grassblade_settings_form"); // id of the element to parse
1346	myHilitor.apply(search);
1347}
1348function gb_is_gutenberg_edit() {
1349	return (typeof wp == "object" && typeof wp.data == "object" && typeof wp.data.select("core/editor") == "object");
1350}
1351function gb_update_activity_id_field() {
1352	var activity_id_field = jQuery('#activity_id');
1353	var permalink = gb_get_permalink();
1354	if(permalink)
1355	permalink = permalink.replace('…','').replace(/\/$/, '');
1356	else {
1357		permalink = "[GENERATE]";
1358		activity_id_field.attr('readonly', 'readonly');
1359	}
1360	activity_id_field.val(permalink);
1361	return false;
1362}
1363function gb_get_permalink() {
1364	var permalink = "";
1365
1366	if(jQuery('#sample-permalink').text())
1367		permalink = jQuery('#sample-permalink').text();
1368	else if(gb_is_gutenberg_edit()) {
1369		permalink = wp.data.select("core/editor").getCurrentPostAttribute('link').replace('…','').replace(/\/$/, '');
1370	}
1371
1372	return permalink;
1373	// document.getElementById('activity_id').value =
1374
1375	// jQuery('#sample-permalink,.components-external-link.edit-post-post-link__link').text()?
1376	// jQuery('#sample-permalink,.components-external-link.edit-post-post-link__link').text().replace('…','').replace(/\/$/, ''):'[GENERATE]';
1377
1378	// if(jQuery('#activity_id').val() == '[GENERATE]')
1379	// 	jQuery('#activity_id').attr('readonly', 'readonly');
1380
1381	// return false;
1382}
1383
1384function grassblade_elementor_open_edit_page(c) {
1385	var id = jQuery(c).closest("#elementor-controls").find("select[data-setting='content_id']").val();
1386	if(typeof id != "undefined" && id != "") {
1387		window.open(ajaxurl.replace("admin-ajax.php", "post.php?action=edit&post=" + id));
1388	}
1389}
1390
1391function gb_content_copy_protect(context, post_id, enable) {
1392	jQuery(context).prop("onclick", null).off("click");
1393
1394	var data = {
1395		"enable": enable,
1396		"post_id": post_id,
1397		"gb_nonce": jQuery("[name=gb_xapi_content_box_content_nonce]").val()
1398	};
1399	jQuery.ajax({
1400		type: 'GET',
1401		url: gb_data.ajax_url + "?action=gb_content_enable_copy_protect",
1402		data: data,
1403		contentType: "json",
1404		success: function(response){
1405			const info = JSON.parse(response);
1406			jQuery(context).html(info.info).css("color", "gray");
1407		}
1408	});
1409}
1410function gb_reset_learner_progress(context, post_id) {
1411	var yes = confirm(gb_data.lang.confirm_reset_learner_progress);
1412
1413	if(!yes)
1414		return;
1415
1416	jQuery(context).prop("onclick", null).off("click");
1417
1418	var data = {
1419		"post_id": post_id,
1420		"gb_nonce": jQuery("[name=gb_xapi_content_box_content_nonce]").val()
1421	};
1422	jQuery.ajax({
1423		type: 'GET',
1424		url: gb_data.ajax_url + "?action=gb_reset_learner_progress",
1425		data: data,
1426		contentType: "json",
1427		success: function(response){
1428			const info = JSON.parse(response);
1429			if(typeof info.registration == "string" && info.registration.length == 36)
1430				jQuery("#registration").val(info.registration);
1431
1432			jQuery(context).html(info.info).css("color", "gray");
1433		}
1434	});
1435}
1436function gb_src_tools_show() {
1437	jQuery("#src").animate({width: 0}, 200, function() {
1438		jQuery(this).hide();
1439		jQuery(".gb_src_tools").show();
1440		jQuery("#field-src .dashicons-admin-tools").hide();
1441
1442	});
1443}
1444function gb_src_tools_hide() {
1445	jQuery(".gb_src_tools").hide();
1446	jQuery("#src").show().animate({width: "80%"}, 200, function() {
1447		jQuery("#field-src .dashicons-admin-tools").show();
1448	});
1449}
1450function gb_switch_revision(context) {
1451	var settings = jQuery(context).data("settings");
1452	jQuery.each(jQuery("#grassblade_xapi_content_form").find("input, select, textarea, checkbox"), function(i, v) {
1453		var name = jQuery(v).attr("name");
1454		if( jQuery(v).attr("type") == "file" || typeof name == "undefined")
1455			return;
1456		var new_val = typeof settings[name] == "undefined"? "":settings[name];
1457		//console.log(i, jQuery(v).prop('nodeName'), jQuery(v).attr("type"),jQuery(v).attr("name"),  jQuery(v).val(), new_val);
1458		if(jQuery(v).attr("type") == "checkbox")
1459			jQuery(v).prop('checked', new_val).trigger("change");
1460		else
1461			jQuery(v).val(new_val).trigger("change");
1462
1463		if(jQuery(v).attr("type") == "hidden" && jQuery("#" + name + "-src").length)
1464			jQuery("#" + name + "-src").attr("src", new_val);
1465	});
1466	jQuery(context).closest(".tooltiptext").find("div.gb_revisions").removeClass("switched_to");
1467	if(jQuery(context).hasClass("gb_revisions_reset"))
1468		jQuery(context).hide();
1469	else {
1470		jQuery(context).closest(".gb_revisions").addClass("switched_to");
1471		jQuery(context).closest(".tooltiptext").find(".gb_revisions_reset").show();
1472	}
1473}
1474function gb_delete_revisions(context, post_id, revision, path) {
1475	//console.log(context, revision);
1476	var count_of_revision = jQuery(context).closest(".tooltiptext").find("div.gb_revisions.gb_file_version_"+revision).length;
1477	var count_of_selected_revision = jQuery(context).closest(".tooltiptext").find("div.gb_revisions.file_version_selected.gb_file_version_"+revision).length;
1478
1479	if(count_of_revision <= 0 || count_of_revision != count_of_selected_revision)
1480	{
1481		alert("Invalid selection.");
1482		return;
1483	}
1484	var path = decodeURIComponent(path);
1485	var msg_template = "This will delete the files at: [path] \n\nThis will also delete the following revisions: [revisions]\n\nPlease click OK to confirm. Click CANCEL to stop this deletion.";
1486	var msg = msg_template.replace("[path]", "wp-content" + path);
1487	var revisions = "";
1488	jQuery.each(jQuery(context).closest(".tooltiptext").find("div.gb_revisions.gb_file_version_"+revision), function(i, v) {
1489		var v2 = jQuery(v).clone();
1490		v2.find("span").remove();
1491		revisions = revisions + "\n" + v2.text().trim();
1492		//console.log(i, v, v2.text().trim());
1493	});
1494	msg = msg.replace("[revisions]", revisions);
1495	var confirmed_deletion = confirm(msg);
1496
1497	if( confirmed_deletion ) {
1498		var data = {
1499			"revision": revision,
1500			"post_id": post_id,
1501			"path": path,
1502			"gb_nonce": jQuery("[name=gb_xapi_content_box_content_nonce]").val()
1503		};
1504		jQuery.ajax({
1505			type: 'GET',
1506			url: gb_data.ajax_url + "?action=gb_delete_revisions",
1507			data: data,
1508			contentType: "json",
1509			success: function(response){
1510				const info = JSON.parse(response);
1511				var msg = info.response == "success"? "(deleted)":"(delete failed)";
1512				jQuery(context).html(msg).css("color", "gray");
1513			}
1514		});
1515	}
1516}
1517function gb_select_file_versions(context, file_version, is_current_file_version) {
1518	//console.log(context, file_version);
1519	if(file_version > 0) {
1520		if(jQuery(context).parent().hasClass("file_version_selected")) //reset
1521			jQuery(context).closest(".tooltiptext").find("div.gb_revisions").removeClass("file_version_selected");
1522		else
1523			jQuery(context).closest(".tooltiptext").find("div.gb_revisions").removeClass("file_version_selected").siblings(".gb_file_version_" + file_version).addClass("file_version_selected");
1524	}
1525}
1526
1527/* function to compare versions */
1528function gb_version_compare(v1, v2) {
1529	if (typeof v1 !== 'string') return false;
1530	if (typeof v2 !== 'string') return false;
1531	v1 = v1.split('.');
1532	v2 = v2.split('.');
1533	var k = Math.min(v1.length, v2.length);
1534	for (var i = 0; i < k; ++ i) {
1535		v1[i] = parseInt(v1[i], 10);
1536		v2[i] = parseInt(v2[i], 10);
1537		if (v1[i] > v2[i]) return 1;
1538		if (v1[i] < v2[i]) return -1;
1539	}
1540	return v1.length == v2.length ? 0: (v1.length < v2.length ? -1 : 1);
1541}
1542
1543function grassblade_gen_uuid() {
1544	return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
1545			var r = Math.random()*16|0, v = c == 'x' ? r : (r&0x3|0x8);
1546			return v.toString(16);
1547	});
1548}
1549
1550function grassblade_validate_uuid(uuid) {
1551    // Check if the input is empty or not a string
1552    if (!uuid || typeof uuid !== 'string') {
1553        return false;
1554    }
1555
1556    // UUID only accepts 8-4-4-4-12 format and A-F characters
1557    const pattern = /^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$/;
1558
1559    return pattern.test(uuid);
1560}
1561
1562function gb_get_value(o, k, d) {
1563    const first_part = k.split(".")[0];
1564    const remaining_key = k.substr(first_part.length + 1);
1565    return ( !o || !o[first_part])? d:((typeof o[first_part] != "object" || remaining_key == "")? o[first_part] : gb_get_value(o[first_part], remaining_key, d));
1566}
1567function gb_localize( text ) {
1568	return gb_get_value(gb_data, "lang." + text, text);
1569}
1570
1571if( typeof String.prototype.replaceAll != "function" )
1572String.prototype.replaceAll = function(search, replacement) {
1573	var target = this;
1574	return target.split(search).join(replacement);
1575};
1576
1577jQuery(function() {
1578	if(jQuery("#show_xapi_content").length > 0) {
1579		jQuery("#show_xapi_content").on("change", function() {
1580			show_xapi_content_meta_box_change();
1581		});
1582		show_xapi_content_meta_box_change();
1583	}
1584	if (typeof jQuery.fn.select2 == 'function') {
1585		jQuery('select#xapi_content').select2();
1586		jQuery('select#show_xapi_content').select2();
1587	}
1588	if(jQuery("#grassblade_xapi_content_form").length > 0)
1589		grassblade_xapi_content_edit_script();
1590	jQuery(".grassblade_field_group > div.grassblade_field_group_label").on("click", function() {
1591		//console.log(jQuery(this).parent().children("div.grassblade_field_group_fields").css("display"));
1592		if(jQuery(this).parent().children("div.grassblade_field_group_fields").css("display") != "none") {
1593			jQuery(this).parent().children("div.grassblade_field_group_label").children(".dashicons").addClass("dashicons-arrow-right-alt2");
1594			jQuery(this).parent().children("div.grassblade_field_group_label").children(".dashicons").removeClass("dashicons-arrow-down-alt2");
1595		}
1596		else
1597		{
1598			jQuery(this).parent().children("div.grassblade_field_group_label").children(".dashicons").removeClass("dashicons-arrow-right-alt2");
1599			jQuery(this).parent().children("div.grassblade_field_group_label").children(".dashicons").addClass("dashicons-arrow-down-alt2");
1600		}
1601		jQuery(this).parent().children("div.grassblade_field_group_fields").slideToggle();
1602	});
1603	jQuery(".grassblade_field_group > div.grassblade_field_group_label").trigger('click');
1604	jQuery(".grassblade_field_group.default_open > div.grassblade_field_group_label").trigger('click');
1605
1606	grassblade_xapi_content_autosize_content();
1607
1608	jQuery(window).on("resize", function() {
1609		if (document.fullscreenElement ||
1610			document.mozFullScreenElement ||
1611			document.webkitFullscreenElement ||
1612			document.msFullscreenElement ) {
1613		  //Full Screen. ignore change
1614		}
1615		else
1616		{
1617			grassblade_xapi_content_autosize_content();
1618			var iOS = !!navigator.platform && /iPad|iPhone|iPod/.test(navigator.platform);
1619
1620			if(!iOS && window.grassblade_lightbox != undefined)
1621			jQuery.each(window.grassblade_lightbox, function(id,options) {
1622				//console.log(options);
1623				var sizes = grassblade_lightbox_get_sizes(options);
1624				//console.log(sizes);
1625				jQuery("#" + id).css("height", sizes.height);
1626				jQuery("#" + id).css("width", sizes.width);
1627				jQuery("#" + id).css("top", sizes.top);
1628				jQuery("#" + id).css("bottom", sizes.top);
1629				jQuery("#" + id).css("left", sizes.left);
1630				jQuery("#" + id).css("right", sizes.left);
1631			});
1632		}
1633	});
1634
1635	jQuery(window).on("click", function(e) {
1636			//Added to fix: When closing full screen from Vimeo Video on Android.
1637			//The touching the fullscreen(close) button also clicks the links below it in the main page.
1638			//Preventing clicks during fullscreen will disable all click actions on main page but will allow clicks inside the iframe.
1639			if(jQuery('body').hasClass('gb-fullscreen')) {
1640				e.preventDefault();
1641				return;
1642			}
1643	});
1644
1645
1646	if(jQuery("#grassblade_settings_form").length) {
1647
1648		jQuery('#grassblade_setting_search').on('keyup', function() {
1649			var search = jQuery("#grassblade_setting_search").val();
1650			//console.log(search);
1651			jQuery("#grassblade_xapi_settings_form td .grassblade_field_group_fields").hide();
1652			jQuery("#grassblade_xapi_settings_form td .grassblade_field_group_fields tr").hide();
1653			jQuery("#grassblade_xapi_settings_form td .grassblade_field_group_fields tr:contains('"+search+"')").show();
1654			jQuery("#grassblade_xapi_settings_form td .grassblade_field_group_fields:contains('"+search+"')").show();
1655
1656			gb_highlight_text(search);
1657		});
1658
1659		jQuery(".wp-color-picker").wpColorPicker({ 'change': function(event, ui) {
1660			var target_id = jQuery(event.target).attr('id');
1661
1662			if( ["table_th_bg_color", "table_th_txt_color", "table_tb_txt_color", "table_tb_color1", "table_tb_color2"].includes(target_id) ) {
1663				jQuery(event.target).val(ui.color.toString());
1664				grassblade_table_colors_changed();
1665			}
1666		}});
1667		grassblade_table_colors_changed();
1668	}
1669	if(jQuery(".grassblade_admin_wrap").length) {
1670		jQuery(".grassblade_admin_wrap .enable-select2").select2();
1671	}
1672
1673	grassblade_show_errors();
1674	grassblade_learndash_focusmode_switching();
1675
1676	grassblade_register_folder_delete_buttons();
1677	grassblade_reigster_gb_search_table();
1678});
1679
1680/* Standard syntax */
1681document.addEventListener("fullscreenchange", function() {
1682	gb_fullscreen_class();
1683});
1684
1685/* Firefox */
1686document.addEventListener("mozfullscreenchange", function() {
1687	gb_fullscreen_class();
1688});
1689
1690/* Chrome, Safari and Opera */
1691document.addEventListener("webkitfullscreenchange", function() {
1692gb_fullscreen_class();
1693});
1694
1695/* IE / Edge */
1696document.addEventListener("msfullscreenchange", function() {
1697	gb_fullscreen_class();
1698});
1699/* Add gb-fullscreen class when video is in fullscreen */
1700
1701if(typeof String.prototype.trim !== 'function') {
1702	String.prototype.trim = function() {
1703	return this.replace(/^\s+|\s+$/g, '');
1704	}
1705}
1706
1707jQuery(function() {
1708	if (typeof gb_data != 'undefined' && !gb_data.is_admin && gb_data.completion_tracking_enabled && gb_data.is_guest == '' && (gb_data.completion_type != 'hide_button' || is_grassblade_voc_enabled()) ) {
1709		grassblade_voc_init();
1710		if(gb_data.post_completion)
1711			grassblade_voc_show("all");
1712
1713		grassblade_control_lms_mark_complete_btn();
1714		setTimeout(function () {
1715			if(gb_data.post_completion)
1716				grassblade_voc_show("all");
1717
1718			grassblade_find_iframes_and_add_completion_script();
1719		}, 2000);
1720	}
1721});
1722
1723window.addEventListener( "message",
1724	function (event) {
1725		if(!gb_data.is_admin){
1726			//if(event.origin !== 'http://imac2.gblrs.com'){ return; }
1727			var data = event.data;
1728			console_log('received response:  ');
1729			console_log(data);
1730
1731			if (typeof(data.statement) === 'object') {
1732				call_grassblade_get_completion(data);
1733			}
1734
1735			if (data.msg == 'code_exist') {
1736				GB.completion =[];
1737				GB.completion.disable_polling =[];
1738				GB.completion.disable_polling[data.activity_id] = true;
1739				console_log(GB.completion.disable_polling[data.activity_id]);
1740			}
1741		}
1742	},
1743false);
1744
1745jQuery(function() {
1746	grassblade_enable_quiz_report_links();
1747});
1748
1749jQuery.expr.pseudos.contains = function(a, i, m) {
1750	return jQuery(a).text().toUpperCase()
1751		.indexOf(m[3].toUpperCase()) >= 0;
1752};
1753
1754function gb_process_legacy_attempts_expiry(event) {
1755	event.preventDefault();
1756
1757	if ( typeof gb_data.post_id == "undefined" || isNaN(gb_data.post_id) || gb_data.post_id <= 0) {
1758		alert("Invalid post id.");
1759		return;
1760	}
1761
1762	// send a ajax request with content id and post_id to process legacy attempts expiry
1763	event.target.innerText = "Processing...";
1764	jQuery.ajax({
1765		type: 'GET',
1766		url: gb_data.ajax_url + "?action=gb_process_legacy_attempts_expiry&content_id=" + gb_data.post_id,
1767		success: function(response){
1768			var color = response.success ? 'green' : 'red';
1769			var html = '<span style="color:' + color + '">' + response.data.message + '</span>';
1770			// event.target.innerText = html;
1771			jQuery(event.target).html(html);
1772		},
1773		error: function(errorThrown){
1774			event.target.innerText = "Failed to process legacy attempts expiry.";
1775		}
1776	});
1777}

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.