PageSourceSearch

https://earthslab.com/wp-content/plugins/learnpress/assets/js/global.js@nocache=1783717415.1252&ver=3.2.5.2

js earthslab.com collected 2026-09-24 10:10:15 UTC 48,462 bytes, 1,359 lines download raw bytes

1/**
2 * Common functions/utils used in all page
3 */
4if (typeof window.LP == 'undefined') {
5	window.LP = window.LearnPress = {};
6}
7
8
9(function ($) {
10    /**
11     * Manage event callbacks.
12     * Allow add/remove a callback function into custom event of an object.
13     *
14     * @constructor
15     */
16    window.LP.Event_Callback = function (self) {
17        var callbacks = {};
18
19        this.on = function (event, callback) {
20            var namespaces = event.split('.'),
21                namespace = '';
22
23            if (namespaces.length > 1) {
24                event = namespaces[0];
25                namespace = namespaces[1];
26            }
27
28            if (!callbacks[event]) {
29                callbacks[event] = [[], {}];
30            }
31
32            if (namespace) {
33                if (!callbacks[event][1][namespace]) {
34                    callbacks[event][1][namespace] = [];
35                }
36                callbacks[event][1][namespace].push(callback);
37            } else {
38                callbacks[event][0].push(callback);
39            }
40
41            return self;
42        };
43
44        this.off = function (event, callback) {
45            var namespaces = event.split('.'),
46                namespace = '';
47
48            if (namespaces.length > 1) {
49                event = namespaces[0];
50                namespace = namespaces[1];
51            }
52
53            if (!callbacks[event]) {
54                return self;
55            }
56            var at = -1;
57            if (!namespace) {
58                if ($.isFunction(callback)) {
59                    at = callbacks[event][0].indexOf(callback);
60                    if (at < 0) {
61                        return self;
62                    }
63                    callbacks[event][0].splice(at, 1);
64                } else {
65                    callbacks[event][0] = [];
66                }
67            } else {
68                if (!callbacks[event][1][namespace]) {
69                    return self;
70                }
71
72                if ($.isFunction(callback)) {
73                    at = callbacks[event][1][namespace].indexOf(callback);
74                    if (at < 0) {
75                        return self;
76                    }
77                    callbacks[event][1][namespace].splice(at, 1);
78                } else {
79                    callbacks[event][1][namespace] = [];
80                }
81            }
82
83            return self;
84        };
85
86        this.callEvent = function (event, callbackArgs) {
87            if (!callbacks[event]) {
88                return;
89            }
90
91            if (callbacks[event][0]) {
92                for (var i = 0; i < callbacks[event][0].length; i++) {
93                    $.isFunction(callbacks[event][0][i]) && callbacks[event][i][0].apply(self, callbackArgs);
94                }
95            }
96
97            if (callbacks[event][1]) {
98                for (var i in callbacks[event][1]) {
99                    for (var j = 0; j < callbacks[event][1][i].length; j++) {
100                        $.isFunction(callbacks[event][1][i][j]) && callbacks[event][1][i][j].apply(self, callbackArgs);
101                    }
102                }
103            }
104        }
105    };
106    $.fn.serializeJSON = function (path) {
107        var isInput = $(this).is('input') || $(this).is('select') || $(this).is('textarea');
108        var unIndexed = isInput ? $(this).serializeArray() : $(this).find('input, select, textarea').serializeArray(),
109            indexed = {},
110            validate = /(\[([a-zA-Z0-9_-]+)?\]?)/g,
111            arrayKeys = {},
112            end = false;
113        $.each(unIndexed, function () {
114            var that = this,
115                match = this.name.match(/^([0-9a-zA-Z_-]+)/);
116            if (!match) {
117                return;
118            }
119            var keys = this.name.match(validate),
120                objPath = "indexed['" + match[0] + "']";
121
122			if (keys) {
123				if (typeof indexed[match[0]] != 'object') {
124					indexed[match[0]] = {};
125				}
126
127				$.each(keys, function (i, prop) {
128					prop = prop.replace(/\]|\[/g, '');
129					var rawPath = objPath.replace(/'|\[|\]/g, ''),
130						objExp = '',
131						preObjPath = objPath;
132
133					if (prop == '') {
134						if (arrayKeys[rawPath] == undefined) {
135							arrayKeys[rawPath] = 0;
136						} else {
137							arrayKeys[rawPath]++;
138						}
139						objPath += "['" + arrayKeys[rawPath] + "']";
140					} else {
141						if (!isNaN(prop)) {
142							arrayKeys[rawPath] = prop;
143						}
144						objPath += "['" + prop + "']";
145					}
146					try {
147						if (i == keys.length - 1) {
148							objExp = objPath + "=that.value;";
149							end = true;
150						} else {
151							objExp = objPath + "={}";
152							end = false;
153						}
154
155                        var evalString = "" +
156                            "if( typeof " + objPath + " == 'undefined'){" + objExp + ";" +
157                            "}else{" +
158                            "if(end){" +
159                            "if(typeof " + preObjPath + "!='object'){" + preObjPath + "={};}" +
160                            objExp +
161                            "}" +
162                            "}";
163                        eval(evalString);
164                    } catch (e) {
165                        console.log('Error:' + e + "\n" + objExp);
166                    }
167                })
168            } else {
169                indexed[match[0]] = this.value;
170            }
171        });
172        if (path) {
173            path = "['" + path.replace('.', "']['") + "']";
174            var c = 'try{indexed = indexed' + path + '}catch(ex){console.log(c, ex);}';
175            eval(c);
176        }
177        return indexed;
178    };
179    $.fn.LP_Tooltip = function (options) {
180        options = $.extend({}, {
181            offset: [0, 0]
182        }, options || {});
183        return $.each(this, function () {
184            var $el = $(this),
185                content = $el.data('content');
186            if (!content || ($el.data('LP_Tooltip') !== undefined)) {
187                return;
188            }
189
190            console.log(content);
191            var $tooltip = null;
192            $el.hover(function (e) {
193                $tooltip = $('<div class="learn-press-tooltip-bubble"/>').html(content).appendTo($('body')).hide();
194                var position = $el.offset();
195                if ($.isArray(options.offset)) {
196                    var top = options.offset[1],
197                        left = options.offset[0];
198                    if ($.isNumeric(left)) {
199                        position.left += left;
200                    } else {
201
202					}
203					if ($.isNumeric(top)) {
204						position.top += top;
205					} else {
206
207					}
208				}
209				$tooltip.css({
210					top : position.top,
211					left: position.left
212				});
213				$tooltip.fadeIn();
214			}, function () {
215				$tooltip && $tooltip.remove();
216			});
217			$el.data('tooltip', true);
218		});
219	};
220	$.fn.hasEvent = function (name) {
221		var events = $(this).data('events');
222		if (typeof events.LP == 'undefined') {
223			return false;
224		}
225		for (i = 0; i < events.LP.length; i++) {
226			if (events.LP[i].namespace == name) {
227				return true;
228			}
229		}
230		return false;
231	};
232	$.fn.dataToJSON = function () {
233		var json = {};
234		$.each(this[0].attributes, function () {
235			var m = this.name.match(/^data-(.*)/);
236			if (m) {
237				json[m[1]] = this.value;
238			}
239		});
240		return json;
241	};
242
243	String.prototype.getQueryVar = function (name) {
244		name = name.replace(/[\[]/, "\\[").replace(/[\]]/, "\\]");
245		var regex = new RegExp("[\\?&]" + name + "=([^&#]*)"),
246			results = regex.exec(this);
247		return results === null ? "" : decodeURIComponent(results[1].replace(/\+/g, " "));
248	};
249	String.prototype.addQueryVar = function (name, value) {
250		var url = this,
251			m = url.split('#');
252		url = m[0];
253		if (name.match(/\[/)) {
254			url += url.match(/\?/) ? '&' : '?';
255			url += name + '=' + value;
256		} else {
257			if ((url.indexOf('&' + name + '=') != -1) || (url.indexOf('?' + name + '=') != -1)) {
258				url = url.replace(new RegExp(name + "=([^&#]*)", 'g'), name + '=' + value);
259			} else {
260				url += url.match(/\?/) ? '&' : '?';
261				url += name + '=' + value;
262			}
263		}
264		return url + (m[1] ? '#' + m[1] : '');
265	};
266	String.prototype.removeQueryVar = function (name) {
267		var url = this;
268		var m = url.split('#');
269		url = m[0];
270		name = name.replace(/[\[]/, "\\[").replace(/[\]]/, "\\]");
271		var regex = new RegExp("[\\?&]" + name + "([\[][^=]*)?=([^&#]*)", 'g');
272		url = url.replace(regex, '');
273		return url + (m[1] ? '#' + m[1] : '');
274	};
275
276	if ($.isEmptyObject("") == false) {
277		$.isEmptyObject = function (a) {
278			for (prop in a) {
279				if (a.hasOwnProperty(prop)) {
280					return false;
281				}
282			}
283			return true;
284		};
285	}
286
287	LP.MessageBox = {
288		/*
289		 *
290		 */
291		$block         : null,
292		$window        : null,
293		events         : {},
294		instances      : [],
295		instance       : null,
296		quickConfirm   : function (elem, args) {
297			var $e = $(elem);
298			$('[learn-press-quick-confirm]').each(function () {
299				( $ins = $(this).data('quick-confirm') ) && ( console.log($ins), $ins.destroy() );
300			});
301			!$e.attr('learn-press-quick-confirm') && $e.attr('learn-press-quick-confirm', 'true').data('quick-confirm',
302				new (function (elem, args) {
303					var $elem = $(elem),
304						$div = $('<span class="learn-press-quick-confirm"></span>').insertAfter($elem), //($(document.body)),
305						offset = $(elem).position() || {left: 0, top: 0},
306						timerOut = null,
307						timerHide = null,
308						n = 3,
309						hide = function () {
310							$div.fadeOut('fast', function () {
311								$(this).remove();
312								$div.parent().css('position', '');
313							});
314							$elem.removeAttr('learn-press-quick-confirm').data('quick-confirm', undefined);
315							stop();
316						},
317						stop = function () {
318							timerHide && clearInterval(timerHide);
319							timerOut && clearInterval(timerOut);
320						},
321						start = function () {
322							timerOut = setInterval(function () {
323								if (--n == 0) {
324									hide.call($div[0]);
325									$.isFunction(args.onCancel) && args.onCancel(args.data);
326									stop();
327								}
328								$div.find('span').html(' (' + n + ')');
329							}, 1000);
330
331							timerHide = setInterval(function () {
332								if (!$elem.is(':visible') || $elem.css("visibility") == 'hidden') {
333									stop();
334									$div.remove();
335									$div.parent().css('position', '');
336									$.isFunction(args.onCancel) && args.onCancel(args.data);
337								}
338							}, 350);
339						};
340					args = $.extend({
341						message : '',
342						data    : null,
343						onOk    : null,
344						onCancel: null,
345						offset  : {top: 0, left: 0}
346					}, args || {});
347					$div.html(args.message || $elem.attr('data-confirm-remove') || 'Are you sure?').append('<span> (' + n + ')</span>').css({});
348					$div.click(function () {
349						$.isFunction(args.onOk) && args.onOk(args.data);
350						hide();
351					}).hover(function () {
352						stop();
353					}, function () {
354						start();
355					});
356					//$div.parent().css('position', 'relative');
357					$div.css({
358						left: ( ( offset.left + $elem.outerWidth() ) - $div.outerWidth() ) + args.offset.left,
359						top : offset.top + $elem.outerHeight() + args.offset.top + 5
360					}).hide().fadeIn('fast');
361					start();
362
363                    this.destroy = function () {
364                        $div.remove();
365                        $elem.removeAttr('learn-press-quick-confirm').data('quick-confirm', undefined);
366                        stop();
367
368                    };
369                })(elem, args)
370            );
371        },
372        show: function (message, args) {
373            //this.hide();
374            $.proxy(function () {
375                args = $.extend({
376                    title: '',
377                    buttons: '',
378                    events: false,
379                    autohide: false,
380                    message: message,
381                    data: false,
382                    id: LP.uniqueId(),
383                    onHide: null
384                }, args || {});
385
386                this.instances.push(args);
387                this.instance = args;
388
389                var $doc = $(document),
390                    $body = $(document.body);
391                if (!this.$block) {
392                    this.$block = $('<div id="learn-press-message-box-block"></div>').appendTo($body);
393
394                }
395                if (!this.$window) {
396                    this.$window = $('<div id="learn-press-message-box-window"><div id="message-box-wrap"></div> </div>').insertAfter(this.$block);
397                    this.$window.click(function () {
398                    });
399                }
400                //this.events = args.events || {};
401                this._createWindow(message, args.title, args.buttons);
402                this.$block.show();
403                this.$window.show().attr('instance', args.id);
404                $(window)
405                    .bind('resize.message-box', $.proxy(this.update, this))
406                    .bind('scroll.message-box', $.proxy(this.update, this));
407                this.update(true);
408                if (args.autohide) {
409                    setTimeout(function () {
410                        LP.MessageBox.hide();
411                        $.isFunction(args.onHide) && args.onHide.call(LP.MessageBox, args);
412                    }, args.autohide);
413                }
414            }, this)();
415        },
416        blockUI: function (message) {
417
418            message = (message !== false ? (message ? message : 'Wait a moment') : '') + '<div class="message-box-animation"></div>';
419            this.show(message);
420        },
421        hide: function (delay, instance) {
422            if (instance) {
423                this._removeInstance(instance.id);
424            } else if (this.instance) {
425                this._removeInstance(this.instance.id);
426            }
427            if (this.instances.length === 0) {
428                if (this.$block) {
429                    this.$block.hide();
430                }
431                if (this.$window) {
432                    this.$window.hide();
433                }
434                $(window)
435                    .unbind('resize.message-box', this.update)
436                    .unbind('scroll.message-box', this.update);
437            } else {
438                if (this.instance) {
439                    this._createWindow(this.instance.message, this.instance.title, this.instance.buttons);
440                }
441            }
442
443        },
444        update: function (force) {
445            var that = this,
446                $wrap = this.$window.find('#message-box-wrap'),
447                timer = $wrap.data('timer'),
448                _update = function () {
449                    LP.Hook.doAction('learn_press_message_box_before_resize', that);
450                    var $content = $wrap.find('.message-box-content').css("height", "").css('overflow', 'hidden'),
451                        width = $wrap.outerWidth(),
452                        height = $wrap.outerHeight(),
453                        contentHeight = $content.height(),
454                        windowHeight = $(window).height(),
455                        top = $wrap.offset().top;
456                    if (contentHeight > windowHeight - 50) {
457                        $content.css({
458                            height: windowHeight - 25
459                        });
460                        height = $wrap.outerHeight();
461                    } else {
462                        $content.css("height", "").css('overflow', '');
463                    }
464                    $wrap.css({
465                        marginTop: ($(window).height() - height) / 2
466                    });
467                    LP.Hook.doAction('learn_press_message_box_resize', height, that);
468                };
469            if (force) _update();
470            timer && clearTimeout(timer);
471            timer = setTimeout(_update, 250);
472        },
473        _removeInstance: function (id) {
474            for (var i = 0; i < this.instances.length; i++) {
475                if (this.instances[i].id === id) {
476
477                    this.instances.splice(i, 1);
478
479                    var len = this.instances.length;
480                    if (len) {
481                        this.instance = this.instances[len - 1];
482                        this.$window.attr('instance', this.instance.id);
483                    } else {
484                        this.instance = false;
485                        this.$window.removeAttr('instance');
486                    }
487                    break;
488                }
489            }
490        },
491        _getInstance: function (id) {
492            for (var i = 0; i < this.instances.length; i++) {
493                if (this.instances[i].id === id) {
494                    return this.instances[i];
495                }
496            }
497        },
498        _createWindow: function (message, title, buttons) {
499            var $wrap = this.$window.find('#message-box-wrap').html('');
500            if (title) {
501                $wrap.append('<h3 class="message-box-title">' + title + '</h3>');
502            }
503            $wrap.append($('<div class="message-box-content"></div>').html(message));
504            if (buttons) {
505                var $buttons = $('<div class="message-box-buttons"></div>');
506                switch (buttons) {
507                    case 'yesNo':
508                        $buttons.append(this._createButton(LP_Settings.localize.button_yes, 'yes'));
509                        $buttons.append(this._createButton(LP_Settings.localize.button_no, 'no'));
510                        break;
511                    case 'okCancel':
512                        $buttons.append(this._createButton(LP_Settings.localize.button_ok, 'ok'));
513                        $buttons.append(this._createButton(LP_Settings.localize.button_cancel, 'cancel'));
514                        break;
515                    default:
516                        $buttons.append(this._createButton(LP_Settings.localize.button_ok, 'ok'));
517                }
518                $wrap.append($buttons);
519            }
520        },
521        _createButton: function (title, type) {
522            var $button = $('<button type="button" class="button message-box-button message-box-button-' + type + '">' + title + '</button>'),
523                callback = 'on' + (type.substr(0, 1).toUpperCase() + type.substr(1));
524            $button.data('callback', callback).click(function () {
525                var instance = $(this).data('instance'),
526                    callback = instance.events[$(this).data('callback')];
527                if ($.type(callback) === 'function') {
528                    if (callback.apply(LP.MessageBox, [instance]) === false) {
529                        // return;
530                    } else {
531                        LP.MessageBox.hide(null, instance);
532                    }
533                } else {
534                    LP.MessageBox.hide(null, instance);
535                }
536            }).data('instance', this.instance);
537            return $button;
538        }
539    };
540    LP.Hook = {
541        hooks: {action: {}, filter: {}},
542        addAction: function (action, callable, priority, tag) {
543            this.addHook('action', action, callable, priority, tag);
544            return this;
545        },
546        addFilter: function (action, callable, priority, tag) {
547            this.addHook('filter', action, callable, priority, tag);
548            return this;
549        },
550        doAction: function (action) {
551            this.doHook('action', action, arguments);
552            return this;
553        },
554        applyFilters: function (action) {
555            return this.doHook('filter', action, arguments);
556        },
557        removeAction: function (action, tag) {
558            this.removeHook('action', action, tag);
559            return this;
560        },
561        removeFilter: function (action, priority, tag) {
562            this.removeHook('filter', action, priority, tag);
563            return this;
564        },
565        addHook: function (hookType, action, callable, priority, tag) {
566            if (undefined === this.hooks[hookType][action]) {
567                this.hooks[hookType][action] = [];
568            }
569            var hooks = this.hooks[hookType][action];
570            if (undefined === tag) {
571                tag = action + '_' + hooks.length;
572            }
573            this.hooks[hookType][action].push({tag: tag, callable: callable, priority: priority});
574            return this;
575        },
576        doHook: function (hookType, action, args) {
577
578            // splice args from object into array and remove first index which is the hook name
579            args = Array.prototype.slice.call(args, 1);
580
581            if (undefined !== this.hooks[hookType][action]) {
582                var hooks = this.hooks[hookType][action], hook;
583                //sort by priority
584                hooks.sort(function (a, b) {
585                    return a["priority"] - b["priority"];
586                });
587                for (var i = 0; i < hooks.length; i++) {
588                    hook = hooks[i].callable;
589                    if (typeof hook !== 'function')
590                        hook = window[hook];
591                    if ('action' === hookType) {
592                        hook.apply(null, args);
593                    } else {
594                        args[0] = hook.apply(null, args);
595                    }
596                }
597            }
598            if ('filter' === hookType) {
599                return args[0];
600            }
601            return this;
602        },
603        removeHook: function (hookType, action, priority, tag) {
604            if (undefined !== this.hooks[hookType][action]) {
605                var hooks = this.hooks[hookType][action];
606                for (var i = hooks.length - 1; i >= 0; i--) {
607                    if ((undefined === tag || tag === hooks[i].tag) && (undefined === priority || priority === hooks[i].priority)) {
608                        hooks.splice(i, 1);
609                    }
610                }
611            }
612            return this;
613        }
614    };
615    LP = $.extend({
616        setUrl: function (url, ember, title) {
617            if (url) {
618                history.pushState({}, title, url);
619                LP.Hook.doAction('learn_press_set_location_url', url);
620            }
621        },
622        toggleGroupSection: function (el, target) {
623            var $el = $(el),
624                isHide = $el.hasClass('hide-if-js');
625            if (isHide) {
626                $el.hide().removeClass('hide-if-js');
627            }
628            $el.removeClass('hide-if-js').slideToggle(function () {
629                var $this = $(this);
630                if ($this.is(':visible')) {
631                    $(target).addClass('toggle-on').removeClass('toggle-off');
632                } else {
633                    $(target).addClass('toggle-off').removeClass('toggle-on');
634                }
635            });
636        },
637        overflow: function (el, v) {
638            var $el = $(el),
639                overflow = $el.css('overflow');
640            if (v) {
641                $el.css('overflow', v).data('overflow', overflow);
642            } else {
643                $el.css('overflow', $el.data('overflow'));
644            }
645        },
646        getUrl: function () {
647            return window.location.href;
648        },
649        addQueryVar: function (name, value, url) {
650            return (url === undefined ? window.location.href : url).addQueryVar(name, value);
651        },
652        removeQueryVar: function (name, url) {
653            return (url === undefined ? window.location.href : url).removeQueryVar(name);
654        },
655        reload: function (url) {
656            if (!url) {
657                url = window.location.href;
658            }
659            window.location.href = url;
660        },
661
662        parseResponse: function (response, type) {
663            var m = response.match(/<-- LP_AJAX_START -->(.*)<-- LP_AJAX_END -->/);
664            if (m) {
665                response = m[1];
666            }
667            return (type || "json") === "json" ? this.parseJSON(response) : response;
668        },
669        parseJSON: function (data) {
670            var m = (data + '').match(/<-- LP_AJAX_START -->(.*)<-- LP_AJAX_END -->/);
671            try {
672                if (m) {
673                    data = $.parseJSON(m[1]);
674                } else {
675                    data = $.parseJSON(data);
676                }
677            } catch (e) {
678                data = {};
679            }
680            return data;
681        },
682        ajax: function (args) {
683            var type = args.type || 'post',
684                dataType = args.dataType || 'json',
685                data = args.action ? $.extend(args.data, {'lp-ajax': args.action}) : args.data,
686                beforeSend = args.beforeSend || function () {
687                    },
688                url = args.url || window.location.href;
689//                        console.debug( beforeSend );
690            $.ajax({
691                data: data,
692                url: url,
693                type: type,
694                dataType: 'html',
695                beforeSend: beforeSend.apply(null, args),
696                success: function (raw) {
697                    var response = LP.parseResponse(raw, dataType);
698                    $.isFunction(args.success) && args.success(response, raw);
699                },
700                error: function () {
701                    $.isFunction(args.error) && args.error.apply(null, LP.funcArgs2Array());
702                }
703            });
704        },
705        doAjax: function (args) {
706            var type = args.type || 'post',
707                dataType = args.dataType || 'json',
708                action = ((args.prefix === undefined) || 'learnpress_') + args.action,
709                data = args.action ? $.extend(args.data, {action: action}) : args.data;
710
711            $.ajax({
712                data: data,
713                url: (args.url || window.location.href),
714                type: type,
715                dataType: 'html',
716                success: function (raw) {
717                    var response = LP.parseResponse(raw, dataType);
718                    $.isFunction(args.success) && args.success(response, raw);
719                },
720                error: function () {
721                    $.isFunction(args.error) && args.error.apply(null, LP.funcArgs2Array());
722                }
723            });
724        },
725
726        funcArgs2Array: function (args) {
727            var arr = [];
728            for (var i = 0; i < args.length; i++) {
729                arr.push(args[i]);
730            }
731            return arr;
732        },
733        addFilter: function (action, callback) {
734            var $doc = $(document),
735                event = 'LP.' + action;
736            $doc.on(event, callback);
737            LP.log($doc.data('events'));
738            return this;
739        },
740        applyFilters: function () {
741            var $doc = $(document),
742                action = arguments[0],
743                args = this.funcArgs2Array(arguments);
744            if ($doc.hasEvent(action)) {
745                args[0] = 'LP.' + action;
746                return $doc.triggerHandler.apply($doc, args);
747            }
748            return args[1];
749        },
750        addAction: function (action, callback) {
751            return this.addFilter(action, callback);
752        },
753        doAction: function () {
754            var $doc = $(document),
755                action = arguments[0],
756                args = this.funcArgs2Array(arguments);
757            if ($doc.hasEvent(action)) {
758                args[0] = 'LP.' + action;
759                $doc.trigger.apply($doc, args);
760            }
761        },
762        toElement: function (element, args) {
763            if ($(element).length === 0) {
764                return;
765            }
766            args = $.extend({
767                delay: 300,
768                duration: 'slow',
769                offset: 50,
770                container: null,
771                callback: null,
772                invisible: false
773            }, args || {});
774            var $container = $(args.container),
775                rootTop = 0;
776            if ($container.length === 0) {
777                $container = $('body, html');
778            }
779            rootTop = $container.offset().top;
780            var to = ($(element).offset().top + $container.scrollTop()) - rootTop - args.offset;
781
782            function isElementInView(element, fullyInView) {
783                var pageTop = $container.scrollTop();
784                var pageBottom = pageTop + $container.height();
785                var elementTop = $(element).offset().top - $container.offset().top;
786                var elementBottom = elementTop + $(element).height();
787
788                if (fullyInView === true) {
789                    return ((pageTop < elementTop) && (pageBottom > elementBottom));
790                } else {
791                    return ((elementTop <= pageBottom) && (elementBottom >= pageTop));
792                }
793            }
794
795            if (args.invisible && isElementInView(element, true)) {
796                return;
797            }
798            $container.fadeIn(10)
799                .delay(args.delay)
800                .animate({
801                    scrollTop: to
802                }, args.duration, args.callback);
803        },
804        uniqueId: function (prefix, more_entropy) {
805            if (typeof prefix === 'undefined') {
806                prefix = '';
807            }
808
809            var retId;
810            var formatSeed = function (seed, reqWidth) {
811                seed = parseInt(seed, 10)
812                    .toString(16); // to hex str
813                if (reqWidth < seed.length) { // so long we split
814                    return seed.slice(seed.length - reqWidth);
815                }
816                if (reqWidth > seed.length) { // so short we pad
817                    return new Array(1 + (reqWidth - seed.length))
818                            .join('0') + seed;
819                }
820                return seed;
821            };
822
823            // BEGIN REDUNDANT
824            if (!this.php_js) {
825                this.php_js = {};
826            }
827            // END REDUNDANT
828            if (!this.php_js.uniqidSeed) { // init seed with big random int
829                this.php_js.uniqidSeed = Math.floor(Math.random() * 0x75bcd15);
830            }
831            this.php_js.uniqidSeed++;
832
833            retId = prefix; // start with prefix, add current milliseconds hex string
834            retId += formatSeed(parseInt(new Date()
835                    .getTime() / 1000, 10), 8);
836            retId += formatSeed(this.php_js.uniqidSeed, 5); // add seed hex string
837            if (more_entropy) {
838                // for more entropy we add a float lower to 10
839                retId += (Math.random() * 10)
840                    .toFixed(8)
841                    .toString();
842            }
843
844            return retId;
845        },
846        log: function () {
847            //if (typeof LEARN_PRESS_DEBUG != 'undefined' && LEARN_PRESS_DEBUG && console) {
848            for (var i = 0, n = arguments.length; i < n; i++) {
849                console.log(arguments[i]);
850            }
851            //}
852        },
853        blockContent: function () {
854            if ($('#learn-press-block-content').length === 0) {
855                $(LP.template('learn-press-template-block-content', {})).appendTo($('body'));
856            }
857            LP.hideMainScrollbar().addClass('block-content');
858            $(document).trigger('learn_press_block_content');
859        },
860        unblockContent: function () {
861            setTimeout(function () {
862                LP.showMainScrollbar().removeClass('block-content');
863                $(document).trigger('learn_press_unblock_content');
864            }, 350);
865        },
866        hideMainScrollbar: function (el) {
867            if (!el) {
868                el = 'html, body';
869            }
870            var $el = $(el);
871            $el.each(function () {
872                var $root = $(this),
873                    overflow = $root.css('overflow');
874                $root.css('overflow', 'hidden').attr('overflow', overflow);
875            });
876            return $el;
877        },
878        showMainScrollbar: function (el) {
879            if (!el) {
880                el = 'html, body';
881            }
882            var $el = $(el);
883            $el.each(function () {
884                var $root = $(this),
885                    overflow = $root.attr('overflow');
886                $root.css('overflow', overflow).removeAttr('overflow');
887            });
888            return $el;
889        },
890        template: typeof _ !== 'undefined' ? _.memoize(function (id, data) {
891            var compiled,
892                options = {
893                    evaluate: /<#([\s\S]+?)#>/g,
894                    interpolate: /\{\{\{([\s\S]+?)\}\}\}/g,
895                    escape: /\{\{([^\}]+?)\}\}(?!\})/g,
896                    variable: 'data'
897                };
898
899            var tmpl = function (data) {
900                compiled = compiled || _.template($('#' + id).html(), null, options);
901                return compiled(data);
902            };
903            return data ? tmpl(data) : tmpl;
904        }, function (a, b) {
905            return a + '-' + JSON.stringify(b);
906        }) : function () {
907            return '';
908        },
909        alert: function (localize, callback) {
910            var title = '',
911                message = '';
912            if (typeof localize === 'string') {
913                message = localize;
914            } else {
915                if (typeof localize['title'] !== 'undefined') {
916                    title = localize['title'];
917                }
918                if (typeof localize['message'] !== 'undefined') {
919                    message = localize['message'];
920                }
921            }
922            $.alerts.alert(message, title, function (e) {
923                LP._on_alert_hide();
924                callback && callback(e);
925            });
926            this._on_alert_show();
927        },
928        confirm: function (localize, callback) {
929            var title = '',
930                message = '';
931
932            if (typeof localize === 'string') {
933                message = localize;
934            } else {
935                if (typeof localize['title'] !== 'undefined') {
936                    title = localize['title'];
937                }
938                if (typeof localize['message'] !== 'undefined') {
939                    message = localize['message'];
940                }
941            }
942            $.alerts.confirm(message, title, function (e) {
943                LP._on_alert_hide();
944                callback && callback(e);
945            });
946            this._on_alert_show();
947
948        },
949        _on_alert_show: function () {
950            var $container = $('#popup_container'),
951                $placeholder = $('<span id="popup_container_placeholder" />').insertAfter($container).data('xxx', $container);
952            $container.stop().css('top', '-=50').css('opacity', '0').animate({
953                top: '+=50',
954                opacity: 1
955            }, 250);
956        },
957        _on_alert_hide: function () {
958            var $holder = $("#popup_container_placeholder"),
959                $container = $holder.data('xxx');
960            if ($container) {
961                $container.replaceWith($holder);
962            }
963            $container.appendTo($(document.body))
964            $container.stop().animate({
965                top: '+=50',
966                opacity: 0
967            }, 250, function () {
968                $(this).remove();
969            });
970        },
971        sendMessage: function (data, object, targetOrigin, transfer) {
972            if ($.isPlainObject(data)) {
973                data = JSON.stringify(data);
974            }
975            object = object || window;
976            targetOrigin = targetOrigin || '*';
977            object.postMessage(data, targetOrigin, transfer);
978        },
979        receiveMessage: function (event, b) {
980            var target = event.origin || event.originalEvent.origin,
981                data = event.data || event.originalEvent.data || '';
982            if (typeof data === 'string' || data instanceof String) {
983                if (data.indexOf('{') === 0) {
984                    data = LP.parseJSON(data);
985                }
986            }
987            LP.Hook.doAction('learn_press_receive_message', data, target);
988        }
989    }, LP);
990
991    $.fn.rows = function () {
992        var h = $(this).height();
993        var lh = $(this).css('line-height').replace("px", "");
994        $(this).attr({height: h, 'line-height': lh});
995        return Math.floor(h / parseInt(lh));
996    };
997
998    $.fn.checkLines = function (p) {
999        return this.each(function () {
1000            var $e = $(this),
1001                rows = $e.rows();
1002
1003            p.call(this, rows);
1004        });
1005    };
1006
1007    $.fn.findNext = function (selector) {
1008        var $selector = $(selector),
1009            $root = this.first(),
1010            index = $selector.index($root),
1011            $next = $selector.eq(index + 1);
1012        return $next.length ? $next : false;
1013    };
1014
1015    $.fn.findPrev = function (selector) {
1016        var $selector = $(selector),
1017            $root = this.first(),
1018            index = $selector.index($root),
1019            $prev = $selector.eq(index - 1);
1020        return $prev.length ? $prev : false;
1021    };
1022
1023    $.each(['progress'], function (i, property) {
1024        $.Tween.propHooks[property] = {
1025            get: function (tween) {
1026                return $(tween.elem).css('transform');
1027            },
1028            set: function (tween) {
1029                /*var style = tween.elem.style;
1030                 var p_begin = parseColor($(tween.elem).css(property));
1031                 var p_end = parseColor(tween.end);
1032                 tween.run = function(progress) {
1033                 style[property] = calculateColor(p_begin, p_end, progress);
1034                 }*/
1035                if (tween.now < 180) {
1036                    $(this).find('.progress-circle').removeClass('gt-50');
1037                } else {
1038                    $(this).find('.progress-circle').addClass('gt-50');
1039                }
1040                $(tween.elem).find('.fill').css({
1041                    transform: 'rotate(' + tween.end + 'deg)'
1042                });
1043            }
1044        };
1045    });
1046
1047    $.fn.progress = function (v) {
1048        return this.each(function () {
1049            var t = parseInt(v / 100 * 360),
1050                timer = null,
1051                $this = $(this);
1052
1053            if (t < 180) {
1054                $this.find('.progress-circle').removeClass('gt-50');
1055            } else {
1056                $this.find('.progress-circle').addClass('gt-50');
1057            }
1058            $this.find('.fill').css({
1059                transform: 'rotate(' + t + 'deg)'
1060            });
1061
1062        });
1063    };
1064
1065    var xxx = 0;
1066
1067    function QuickTip(el, options) {
1068        var $el = $(el),
1069            uniId = $el.attr('data-id') || LP.uniqueId();
1070
1071        options = $.extend({
1072            event: 'hover',
1073            autoClose: true,
1074            single: true,
1075            closeInterval: 1000,
1076            arrowOffset: null,
1077            tipClass: ''
1078        }, options, $el.data());
1079
1080        $el.attr('data-id', uniId);
1081
1082        var content = $el.attr('data-content-tip') || $el.html(),
1083            $tip = $('<div class="learn-press-tip-floating">' + content + '</div>'),
1084            t = null,
1085            closeInterval = 0,
1086            useData = false,
1087            arrowOffset = options.arrowOffset === 'el' ? $el.outerWidth() / 2 : 8,
1088            $content = $('#__' + uniId);
1089
1090        if ($content.length === 0) {
1091            $(document.body).append($('<div />').attr('id', '__' + uniId).html(content).css('display', 'none'))
1092        }
1093
1094        content = $content.html();
1095
1096        $tip.addClass(options.tipClass);
1097
1098        $el.data('content-tip', content);
1099        if ($el.attr('data-content-tip')) {
1100            //$el.removeAttr('data-content-tip');
1101            useData = true;
1102        }
1103
1104        closeInterval = options.closeInterval;
1105
1106        if (options.autoClose === false) {
1107            $tip.append('<a class="close"></a>');
1108            $tip.on('click', '.close', function () {
1109                close();
1110            })
1111        }
1112
1113        function show() {
1114            if (t) {
1115                clearTimeout(t);
1116                return;
1117            }
1118
1119            if (options.single) {
1120                $('.learn-press-tip').not($el).QuickTip('close');
1121            }
1122
1123            $tip.appendTo(document.body);
1124            var pos = $el.offset();
1125
1126            $tip.css({
1127                top: pos.top - $tip.outerHeight() - 8,
1128                left: pos.left - $tip.outerWidth() / 2 + arrowOffset
1129            });
1130        }
1131
1132        function hide() {
1133            t && clearTimeout(t);
1134            t = setTimeout(function () {
1135                $tip.detach();
1136                t = null;
1137            }, closeInterval);
1138        }
1139
1140        function close() {
1141            closeInterval = 0;
1142            hide();
1143            closeInterval = options.closeInterval;
1144        }
1145
1146        function open() {
1147            show();
1148        }
1149
1150        if (!useData) {
1151            $el.html('');
1152        }
1153
1154        if (options.event === 'click') {
1155            $el.on('click', function (e) {
1156                e.stopPropagation();
1157                show();
1158            })
1159        }
1160
1161        $(document).on('learn-press/close-all-quick-tip', function () {
1162            close();
1163        });
1164        $el.hover(
1165            function (e) {
1166                e.stopPropagation();
1167                if (options.event !== 'click') {
1168                    show();
1169                }
1170            },
1171            function (e) {
1172                e.stopPropagation();
1173                if (options.autoClose) {
1174                    hide();
1175                }
1176            }
1177        ).addClass('ready');
1178        return {
1179            close: close,
1180            open: open
1181        }
1182    }
1183
1184    $.fn.QuickTip = function (options) {
1185        return $.each(this, function () {
1186            var $tip = $(this).data('quick-tip');
1187
1188            if (!$tip) {
1189                $tip = new QuickTip(this, options);
1190                $(this).data('quick-tip', $tip);
1191            }
1192
1193            if ($.type(options) === 'string') {
1194                $tip[options] && $tip[options].apply($tip);
1195            }
1196        })
1197    }
1198
1199    function __initSubtabs() {
1200        $('.learn-press-subtabs').each(function () {
1201            var $tabContainer = $(this),
1202                $tabs = $tabContainer.find('a'),
1203                current = null;
1204            $tabs.click(function (e) {
1205                var $tab = $(this),
1206                    $contentID = $tab.attr('href');
1207                $tab.parent().addClass('current').siblings().removeClass('current');
1208                current = $($contentID).addClass('current');
1209                current.siblings().removeClass('current');
1210                //LP.setUrl($contentID);
1211                e.preventDefault();
1212            }).filter(function () {
1213                return $(this).attr('href') === window.location.hash;
1214            }).trigger('click');
1215            if (!current) {
1216                $tabs.first().trigger('click');
1217            }
1218        });
1219    }
1220
1221    $(document).ready(function () {
1222        if (typeof $.alerts !== 'undefined') {
1223            $.alerts.overlayColor = '#000';
1224            $.alerts.overlayOpacity = 0.5;
1225            $.alerts.okButton = lpGlobalSettings.localize.button_ok;
1226            $.alerts.cancelButton = lpGlobalSettings.localize.button_cancel;
1227        }
1228
1229        $('.learn-press-message.fixed').each(function () {
1230            var $el = $(this),
1231                options = $el.data();
1232            (function ($el, options) {
1233                if (options.delayIn) {
1234                    setTimeout(function () {
1235                        $el.show().hide().fadeIn();
1236                    }, options.delayIn);
1237                }
1238                if (options.delayOut) {
1239                    setTimeout(function () {
1240                        $el.fadeOut();
1241                    }, options.delayOut + (options.delayIn || 0));
1242                }
1243            })($el, options);
1244
1245        });
1246
1247
1248        $(document).on('input', '#meta-box-tab-course_payment', function (e) {
1249            var _self = $(this),
1250                _price = $('#_lp_price'),
1251                _sale_price = $('#_lp_sale_price'),
1252                _target = $(e.target).attr('id');
1253            _self.find('#field-_lp_price div, #field-_lp_sale_price div').remove('.learn-press-tip-floating');
1254            if (parseInt(_sale_price.val()) >= parseInt(_price.val())) {
1255                if (_target === '_lp_price') {
1256                    _price.parent('.rwmb-input').append('<div class="learn-press-tip-floating">' + lpAdminCourseEditorSettings.i18n.notice_price + '</div>');
1257                } else if (_target === '_lp_sale_price') {
1258                    _sale_price.parent('.rwmb-input').append('<div class="learn-press-tip-floating">' + lpAdminCourseEditorSettings.i18n.notice_sale_price + '</div>');
1259                }
1260            }
1261        });
1262
1263        $(document).on('change', '#_lp_sale_start', function (e) {
1264            var _sale_start_date = $(this),
1265                _sale_end_date = $('#_lp_sale_end'),
1266                _start_date = Date.parse(_sale_start_date.val()),
1267                _end_date = Date.parse(_sale_end_date.val()),
1268                _parent_start = _sale_start_date.parent('.rwmb-input'),
1269                _parent_end = _sale_end_date.parent('.rwmb-input');
1270
1271            if (!_start_date) {
1272                _parent_start.append('<div class="learn-press-tip-floating">' + lpAdminCourseEditorSettings.i18n.notice_invalid_date + '</div>')
1273            }
1274
1275            $('#field-_lp_sale_start div, #field-_lp_sale_end div').remove('.learn-press-tip-floating');
1276            if (_start_date < _end_date) {
1277                _parent_start.append('<div class="learn-press-tip-floating">' + lpAdminCourseEditorSettings.i18n.notice_sale_start_date + '</div>')
1278            }
1279        });
1280
1281        $(document).on('change', '#_lp_sale_end', function (e) {
1282            var _sale_end_date = $(this),
1283                _sale_start_date = $('#_lp_sale_start'),
1284                _start_date = Date.parse(_sale_start_date.val()),
1285                _end_date = Date.parse(_sale_end_date.val()),
1286                _parent_start = _sale_start_date.parent('.rwmb-input'),
1287                _parent_end = _sale_end_date.parent('.rwmb-input');
1288
1289            if (!_end_date) {
1290                _parent_end.append('<div class="learn-press-tip-floating">' + lpAdminCourseEditorSettings.i18n.notice_invalid_date + '</div>')
1291            }
1292
1293            $('#field-_lp_sale_start div, #field-_lp_sale_end div').remove('.learn-press-tip-floating');
1294            if (_start_date < _end_date) {
1295                _parent_end.append('<div class="learn-press-tip-floating">' + lpAdminCourseEditorSettings.i18n.notice_sale_end_date + '</div>')
1296            }
1297        });
1298
1299        $('body')
1300            .on('click', '.learn-press-nav-tabs li a', function (e) {
1301                e.preventDefault();
1302                var $tab = $(this), url = '';
1303                $tab.closest('li').addClass('active').siblings().removeClass('active');
1304                $($tab.attr('data-tab')).addClass('active').siblings().removeClass('active');
1305                $(document).trigger('learn-press/nav-tabs/clicked', $tab);
1306            });
1307
1308        setTimeout(function () {
1309            $('.learn-press-nav-tabs li.active:not(.default) a').trigger('click');
1310        }, 300);
1311
1312        $('body.course-item-popup').parent().css('overflow', 'hidden');
1313        ///
1314        (function () {
1315            var timer = null,
1316                callback = function () {
1317                    $('.auto-check-lines').checkLines(function (r) {
1318                        if (r > 1) {
1319                            $(this).removeClass('single-lines');
1320                        } else {
1321                            $(this).addClass('single-lines');
1322                        }
1323                        $(this).attr('rows', r);
1324                    });
1325                };
1326            $(window).on('resize.check-lines', function () {
1327                if (timer) {
1328                    timer && clearTimeout(timer);
1329                    timer = setTimeout(callback, 300);
1330                } else {
1331                    callback();
1332                }
1333            });
1334        })();
1335
1336//        $(document).on('click', '[data-block-content="yes"]', function () {
1337//            LP.blockContent();
1338//        });
1339
1340        $('.learn-press-tooltip, .lp-passing-conditional').LP_Tooltip({offset: [24, 24]});
1341
1342        $('.learn-press-icon').LP_Tooltip({offset: [30, 30]});
1343
1344        $('.learn-press-message[data-autoclose]').each(function () {
1345            var $el = $(this), delay = parseInt($el.data('autoclose'));
1346            if (delay) {
1347                setTimeout(function ($el) {
1348                    $el.fadeOut();
1349                }, delay, $el);
1350            }
1351        });
1352
1353        $(document).on('click', function () {
1354            $(document).trigger('learn-press/close-all-quick-tip')
1355        })
1356    });
1357    LearnPress = LP;
1358
1359})(jQuery);

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.