PageSourceSearch

https://sueprestontraining.com/_static/??-eJyVzEEOQDAQRuELqSGiYiHO…6iPbIpKUAbaE83zcxGibC5+ck1LP82dHXo7zi9BVTLU

js sueprestontraining.com collected 2026-10-07 10:52:19 UTC 24,825 bytes, 820 lines download raw bytes

vendor: 15,370 bytes, lines 1-552
1/**
2 * jquery-circle-progress - jQuery Plugin to draw animated circular progress bars:
3 * {@link http://kottenator.github.io/jquery-circle-progress/}
4 *
5 * @author Rostyslav Bryzgunov <[email protected]>
6 * @version 1.2.2
7 * @licence MIT
8 * @preserve
9 */
10// UMD factory - https://github.com/umdjs/umd/blob/d31bb6ee7098715e019f52bdfe27b3e4bfd2b97e/templates/jqueryPlugin.js
11// Uses AMD, CommonJS or browser globals to create a jQuery plugin.
12(function(factory) {
13  if (typeof define === 'function' && define.amd) {
14    // AMD - register as an anonymous module
15    define(['jquery'], factory);
16  } else if (typeof module === 'object' && module.exports) {
17    // Node/CommonJS
18    var $ = require('jquery');
19    factory($);
20    module.exports = $;
21  } else {
22    // Browser globals
23    factory(jQuery);
24  }
25})(function($) {
26  /**
27   * Inner implementation of the circle progress bar.
28   * The class is not exposed _yet_ but you can create an instance through jQuery method call.
29   *
30   * @param {object} config - You can customize any class member (property or method).
31   * @class
32   * @alias CircleProgress
33   */
34  function CircleProgress(config) {
35    this.init(config);
36  }
37
38  CircleProgress.prototype = {
39    //--------------------------------------- public options ---------------------------------------
40    /**
41     * This is the only required option. It should be from `0.0` to `1.0`.
42     * @type {number}
43     * @default 0.0
44     */
45    value: 0.0,
46
47    /**
48     * Size of the canvas in pixels.
49     * It's a square so we need only one dimension.
50     * @type {number}
51     * @default 100.0
52     */
53    size: 100.0,
54
55    /**
56     * Initial angle for `0.0` value in radians.
57     * @type {number}
58     * @default -Math.PI
59     */
60    startAngle: -Math.PI,
61
62    /**
63     * Width of the arc in pixels.
64     * If it's `'auto'` - the value is calculated as `[this.size]{@link CircleProgress#size} / 14`.
65     * @type {number|string}
66     * @default 'auto'
67     */
68    thickness: 'auto',
69
70    /**
71     * Fill of the arc. You may set it to:
72     *
73     *   - solid color:
74     *     - `'#3aeabb'`
75     *     - `{ color: '#3aeabb' }`
76     *     - `{ color: 'rgba(255, 255, 255, .3)' }`
77     *   - linear gradient _(left to right)_:
78     *     - `{ gradient: ['#3aeabb', '#fdd250'], gradientAngle: Math.PI / 4 }`
79     *     - `{ gradient: ['red', 'green', 'blue'], gradientDirection: [x0, y0, x1, y1] }`
80     *     - `{ gradient: [["red", .2], ["green", .3], ["blue", .8]] }`
81     *   - image:
82     *     - `{ image: 'http://i.imgur.com/pT0i89v.png' }`
83     *     - `{ image: imageObject }`
84     *     - `{ color: 'lime', image: 'http://i.imgur.com/pT0i89v.png' }` -
85     *       color displayed until the image is loaded
86     *
87     * @default {gradient: ['#3aeabb', '#fdd250']}
88     */
89    fill: {
90      gradient: ['#3aeabb', '#fdd250']
91    },
92
93    /**
94     * Color of the "empty" arc. Only a color fill supported by now.
95     * @type {string}
96     * @default 'rgba(0, 0, 0, .1)'
97     */
98    emptyFill: 'rgba(0, 0, 0, .1)',
99
100    /**
101     * jQuery Animation config.
102     * You can pass `false` to disable the animation.
103     * @see http://api.jquery.com/animate/
104     * @type {object|boolean}
105     * @default {duration: 1200, easing: 'circleProgressEasing'}
106     */
107    animation: {
108      duration: 1200,
109      easing: 'circleProgressEasing'
110    },
111
112    /**
113     * Default animation starts at `0.0` and ends at specified `value`. Let's call this _direct animation_.
114     * If you want to make _reversed animation_ - set `animationStartValue: 1.0`.
115     * Also you may specify any other value from `0.0` to `1.0`.
116     * @type {number}
117     * @default 0.0
118     */
119    animationStartValue: 0.0,
120
121    /**
122     * Reverse animation and arc draw.
123     * By default, the arc is filled from `0.0` to `value`, _clockwise_.
124     * With `reverse: true` the arc is filled from `1.0` to `value`, _counter-clockwise_.
125     * @type {boolean}
126     * @default false
127     */
128    reverse: false,
129
130    /**
131     * Arc line cap: `'butt'`, `'round'` or `'square'` -
132     * [read more]{@link https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D.lineCap}.
133     * @type {string}
134     * @default 'butt'
135     */
136    lineCap: 'butt',
137
138    /**
139     * Canvas insertion mode: append or prepend it into the parent element?
140     * @type {string}
141     * @default 'prepend'
142     */
143    insertMode: 'prepend',
144
145    //------------------------------ protected properties and methods ------------------------------
146    /**
147     * Link to {@link CircleProgress} constructor.
148     * @protected
149     */
150    constructor: CircleProgress,
151
152    /**
153     * Container element. Should be passed into constructor config.
154     * @protected
155     * @type {jQuery}
156     */
157    el: null,
158
159    /**
160     * Canvas element. Automatically generated and prepended to [this.el]{@link CircleProgress#el}.
161     * @protected
162     * @type {HTMLCanvasElement}
163     */
164    canvas: null,
165
166    /**
167     * 2D-context of [this.canvas]{@link CircleProgress#canvas}.
168     * @protected
169     * @type {CanvasRenderingContext2D}
170     */
171    ctx: null,
172
173    /**
174     * Radius of the outer circle. Automatically calculated as `[this.size]{@link CircleProgress#size} / 2`.
175     * @protected
176     * @type {number}
177     */
178    radius: 0.0,
179
180    /**
181     * Fill of the main arc. Automatically calculated, depending on [this.fill]{@link CircleProgress#fill} option.
182     * @protected
183     * @type {string|CanvasGradient|CanvasPattern}
184     */
185    arcFill: null,
186
187    /**
188     * Last rendered frame value.
189     * @protected
190     * @type {number}
191     */
192    lastFrameValue: 0.0,
193
194    /**
195     * Init/re-init the widget.
196     *
197     * Throws a jQuery event:
198     *
199     * - `circle-inited(jqEvent)`
200     *
201     * @param {object} config - You can customize any class member (property or method).
202     */
203    init: function(config) {
204      $.extend(this, config);
205      this.radius = this.size / 2;
206      this.initWidget();
207      this.initFill();
208      this.draw();
209      this.el.trigger('circle-inited');
210    },
211
212    /**
213     * Initialize `<canvas>`.
214     * @protected
215     */
216    initWidget: function() {
217      if (!this.canvas)
218        this.canvas = $('<canvas>')[this.insertMode == 'prepend' ? 'prependTo' : 'appendTo'](this.el)[0];
219
220      var canvas = this.canvas;
221      canvas.width = this.size;
222      canvas.height = this.size;
223      this.ctx = canvas.getContext('2d');
224
225      if (window.devicePixelRatio > 1) {
226        var scaleBy = window.devicePixelRatio;
227        canvas.style.width = canvas.style.height = this.size + 'px';
228        canvas.width = canvas.height = this.size * scaleBy;
229        this.ctx.scale(scaleBy, scaleBy);
230      }
231    },
232
233    /**
234     * This method sets [this.arcFill]{@link CircleProgress#arcFill}.
235     * It could do this async (on image load).
236     * @protected
237     */
238    initFill: function() {
239      var self = this,
240        fill = this.fill,
241        ctx = this.ctx,
242        size = this.size;
243
244      if (!fill)
245        throw Error("The fill is not specified!");
246
247      if (typeof fill == 'string')
248        fill = {color: fill};
249
250      if (fill.color)
251        this.arcFill = fill.color;
252
253      if (fill.gradient) {
254        var gr = fill.gradient;
255
256        if (gr.length == 1) {
257          this.arcFill = gr[0];
258        } else if (gr.length > 1) {
259          var ga = fill.gradientAngle || 0, // gradient direction angle; 0 by default
260            gd = fill.gradientDirection || [
261                size / 2 * (1 - Math.cos(ga)), // x0
262                size / 2 * (1 + Math.sin(ga)), // y0
263                size / 2 * (1 + Math.cos(ga)), // x1
264                size / 2 * (1 - Math.sin(ga))  // y1
265              ];
266
267          var lg = ctx.createLinearGradient.apply(ctx, gd);
268
269          for (var i = 0; i < gr.length; i++) {
270            var color = gr[i],
271              pos = i / (gr.length - 1);
272
273            if ($.isArray(color)) {
274              pos = color[1];
275              color = color[0];
276            }
277
278            lg.addColorStop(pos, color);
279          }
280
281          this.arcFill = lg;
282        }
283      }
284
285      if (fill.image) {
286        var img;
287
288        if (fill.image instanceof Image) {
289          img = fill.image;
290        } else {
291          img = new Image();
292          img.src = fill.image;
293        }
294
295        if (img.complete)
296          setImageFill();
297        else
298          img.onload = setImageFill;
299      }
300
301      function setImageFill() {
302        var bg = $('<canvas>')[0];
303        bg.width = self.size;
304        bg.height = self.size;
305        bg.getContext('2d').drawImage(img, 0, 0, size, size);
306        self.arcFill = self.ctx.createPattern(bg, 'no-repeat');
307        self.drawFrame(self.lastFrameValue);
308      }
309    },
310
311    /**
312     * Draw the circle.
313     * @protected
314     */
315    draw: function() {
316      if (this.animation)
317        this.drawAnimated(this.value);
318      else
319        this.drawFrame(this.value);
320    },
321
322    /**
323     * Draw a single animation frame.
324     * @protected
325     * @param {number} v - Frame value.
326     */
327    drawFrame: function(v) {
328      this.lastFrameValue = v;
329      this.ctx.clearRect(0, 0, this.size, this.size);
330      this.drawEmptyArc(v);
331      this.drawArc(v);
332    },
333
334    /**
335     * Draw the arc (part of the circle).
336     * @protected
337     * @param {number} v - Frame value.
338     */
339    drawArc: function(v) {
340      if (v === 0)
341        return;
342
343      var ctx = this.ctx,
344        r = this.radius,
345        t = this.getThickness(),
346        a = this.startAngle;
347
348      ctx.save();
349      ctx.beginPath();
350
351      if (!this.reverse) {
352        ctx.arc(r, r, r - t / 2, a, a + Math.PI * 2 * v);
353      } else {
354        ctx.arc(r, r, r - t / 2, a - Math.PI * 2 * v, a);
355      }
356
357      ctx.lineWidth = t;
358      ctx.lineCap = this.lineCap;
359      ctx.strokeStyle = this.arcFill;
360      ctx.stroke();
361      ctx.restore();
362    },
363
364    /**
365     * Draw the _empty (background)_ arc (part of the circle).
366     * @protected
367     * @param {number} v - Frame value.
368     */
369    drawEmptyArc: function(v) {
370      var ctx = this.ctx,
371        r = this.radius,
372        t = this.getThickness(),
373        a = this.startAngle;
374
375      if (v < 1) {
376        ctx.save();
377        ctx.beginPath();
378
379        if (v <= 0) {
380          ctx.arc(r, r, r - t / 2, 0, Math.PI * 2);
381        } else {
382          if (!this.reverse) {
383            ctx.arc(r, r, r - t / 2, a + Math.PI * 2 * v, a);
384          } else {
385            ctx.arc(r, r, r - t / 2, a, a - Math.PI * 2 * v);
386          }
387        }
388
389        ctx.lineWidth = t;
390        ctx.strokeStyle = this.emptyFill;
391        ctx.stroke();
392        ctx.restore();
393      }
394    },
395
396    /**
397     * Animate the progress bar.
398     *
399     * Throws 3 jQuery events:
400     *
401     * - `circle-animation-start(jqEvent)`
402     * - `circle-animation-progress(jqEvent, animationProgress, stepValue)` - multiple event
403     *   animationProgress: from `0.0` to `1.0`; stepValue: from `0.0` to `value`
404     * - `circle-animation-end(jqEvent)`
405     *
406     * @protected
407     * @param {number} v - Final value.
408     */
409    drawAnimated: function(v) {
410      var self = this,
411        el = this.el,
412        canvas = $(this.canvas);
413
414      // stop previous animation before new "start" event is triggered
415      canvas.stop(true, false);
416      el.trigger('circle-animation-start');
417
418      canvas
419        .css({animationProgress: 0})
420        .animate({animationProgress: 1}, $.extend({}, this.animation, {
421          step: function(animationProgress) {
422            var stepValue = self.animationStartValue * (1 - animationProgress) + v * animationProgress;
423            self.drawFrame(stepValue);
424            el.trigger('circle-animation-progress', [animationProgress, stepValue]);
425          }
426        }))
427        .promise()
428        .always(function() {
429          // trigger on both successful & failure animation end
430          el.trigger('circle-animation-end');
431        });
432    },
433
434    /**
435     * Get the circle thickness.
436     * @see CircleProgress#thickness
437     * @protected
438     * @returns {number}
439     */
440    getThickness: function() {
441      return $.isNumeric(this.thickness) ? this.thickness : this.size / 14;
442    },
443
444    /**
445     * Get current value.
446     * @protected
447     * @return {number}
448     */
449    getValue: function() {
450      return this.value;
451    },
452
453    /**
454     * Set current value (with smooth animation transition).
455     * @protected
456     * @param {number} newValue
457     */
458    setValue: function(newValue) {
459      if (this.animation)
460        this.animationStartValue = this.lastFrameValue;
461      this.value = newValue;
462      this.draw();
463    }
464  };
465
466  //----------------------------------- Initiating jQuery plugin -----------------------------------
467  $.circleProgress = {
468    // Default options (you may override them)
469    defaults: CircleProgress.prototype
470  };
471
472  // ease-in-out-cubic
473  $.easing.circleProgressEasing = function(x) {
474    if (x < 0.5) {
475      x = 2 * x;
476      return 0.5 * x * x * x;
477    } else {
478      x = 2 - 2 * x;
479      return 1 - 0.5 * x * x * x;
480    }
481  };
482
483  /**
484   * Creates an instance of {@link CircleProgress}.
485   * Produces [init event]{@link CircleProgress#init} and [animation events]{@link CircleProgress#drawAnimated}.
486   *
487   * @param {object} [configOrCommand] - Config object or command name.
488   *
489   * Config example (you can specify any {@link CircleProgress} property):
490   *
491   * ```js
492   * { value: 0.75, size: 50, animation: false }
493   * ```
494   *
495   * Commands:
496   *
497   * ```js
498   * el.circleProgress('widget'); // get the <canvas>
499   * el.circleProgress('value'); // get the value
500   * el.circleProgress('value', newValue); // update the value
501   * el.circleProgress('redraw'); // redraw the circle
502   * el.circleProgress(); // the same as 'redraw'
503   * ```
504   *
505   * @param {string} [commandArgument] - Some commands (like `'value'`) may require an argument.
506   * @see CircleProgress
507   * @alias "$(...).circleProgress"
508   */
509  $.fn.circleProgress = function(configOrCommand, commandArgument) {
510    var dataName = 'circle-progress',
511      firstInstance = this.data(dataName);
512
513    if (configOrCommand == 'widget') {
514      if (!firstInstance)
515        throw Error('Calling "widget" method on not initialized instance is forbidden');
516      return firstInstance.canvas;
517    }
518
519    if (configOrCommand == 'value') {
520      if (!firstInstance)
521        throw Error('Calling "value" method on not initialized instance is forbidden');
522      if (typeof commandArgument == 'undefined') {
523        return firstInstance.getValue();
524      } else {
525        var newValue = arguments[1];
526        return this.each(function() {
527          $(this).data(dataName).setValue(newValue);
528        });
529      }
530    }
531
532    return this.each(function() {
533      var el = $(this),
534        instance = el.data(dataName),
535        config = $.isPlainObject(configOrCommand) ? configOrCommand : {};
536
537      if (instance) {
538        instance.init(config);
539      } else {
540        var initialConfig = $.extend({}, el.data());
541        if (typeof initialConfig.fill == 'string')
542          initialConfig.fill = JSON.parse(initialConfig.fill);
543        if (typeof initialConfig.animation == 'string')
544          initialConfig.animation = JSON.parse(initialConfig.animation);
545        config = $.extend(initialConfig, config);
546        config.el = el;
547        instance = new CircleProgress(config);
548        el.data(dataName, instance);
549      }
550    });
551  };
552});
553;
554jQuery(function () {
555  /* Change the CTA for pages with PG in it.*/
556  if (jQuery(".bwg-container").length) {
557    var html = '<div class="twb_admin_bar_menu_header">';
558    html += '<img class="twb_menu_logo" src="' + twb.plugin_url + '/assets/images/logo_white.svg" />';
559    html += '<div class="twb_menu_logo">Optimize Images</div>';
560    html += '</div>';
561    jQuery(".twb_admin_bar_menu").html(html).on("click", function () {
562      window.open(twb.href, '_blank');
563    });
564    jQuery(".twb_admin_bar_menu_main").remove();
565  }
566
567  /* Is score check in progress.*/
568  twb_inprogress = false;
569
570  /* Check if any score check is in progress.*/
571  jQuery(".twb-notoptimized").each(function () {
572    if (jQuery(this).data("status") == 'inprogress') {
573      /* Disable score check button.*/
574      twb_disable_check();
575    }
576  });
577
578  /* Add check score action to the button in page/posts list,
579    if there is no inprogress action.*/
580  jQuery(".twb-notoptimized .twb_check_score_button").on("click", function () {
581    if (!twb_inprogress) {
582      twb_check_score(this);
583    }
584  });
585
586  /* Add a hover action to show dismiss tooltip.*/
587  jQuery("th[id^='twb-speed-']").hover(function () {
588      jQuery(this).find(".twb-dismiss-container").removeClass("twb-hidden");
589    },
590    function () {
591      jQuery(this).find(".twb-dismiss-container").addClass("twb-hidden");
592    });
593
594  /* Add a hover action to show page score.*/
595  jQuery(".twb-see-score").hover(function () {
596      jQuery(this).parent().parent().find(".twb-score-container").removeClass("twb-hidden");
597    },
598    function () {
599      jQuery(this).parent().parent().find(".twb-score-container").addClass("twb-hidden");
600    });
601  jQuery(".twb-score-container:not(.twb_admin_bar_menu_content .twb-score-container), .twb-score-disabled-container").hover(function () {
602      jQuery(this).removeClass("twb-hidden");
603    },
604    function () {
605      jQuery(this).addClass("twb-hidden");
606    });
607
608  /* Draw circle on given scores.*/
609  jQuery(".twb-score-circle").each(function () {
610    twb_draw_score_circle(this);
611  });
612
613  /* Show/hide Image optimizer menu content container */
614  jQuery("#wp-admin-bar-twb_adminbar_info").mouseenter(function(){
615    jQuery(".twb_admin_bar_menu_main .twb-score-container").removeClass("twb-hidden");
616    jQuery(".twb_admin_bar_menu_main").removeClass("twb-hidden");
617  }).mouseleave(function() {
618    jQuery(".twb_admin_bar_menu_main").addClass("twb-hidden");
619  });
620
621
622  /* Draw circle on given scores.*/
623  jQuery('.twb-score-circle').each(function () {
624    twb_draw_score_circle(this);
625  });
626
627  if( jQuery(".twb_admin_bar_menu.twb_backend span").hasClass("twb_backend_optimizing_logo") ) {
628    /* Run ajax every 30 seconds to check if score counted */
629    twb_run_notif_check = setInterval( twb_run_notif_check, 30000 );
630  }
631});
632
633/* Run ajax to check score counting status and show notification */
634function twb_run_notif_check() {
635  jQuery.ajax({
636    type: "POST",
637    url: twb.ajax_url,
638    data: {
639      action: "twb_notif_check",
640      twb_nonce: twb.nonce,
641    }
642  }).success(function (results) {
643    var result = jQuery.parseJSON(results);
644    if (result.html != "") {
645      /* Show notification popup and change menu icon and text from loading to Not optimised */
646      if ( result.changeLogo == 1 ) {
647        jQuery(".twb_admin_bar_menu_header span").addClass("twb_counted");
648      }
649      jQuery("#wp-admin-bar-twb_adminbar_info").append(result.html);
650      jQuery(".twb_admin_bar_menu_content .twb-score-container").removeClass("twb-hidden");
651      jQuery(".twb_admin_bar_menu_content .twb-score-container .twb-score-circle").each(function () {
652        twb_draw_score_circle(this);
653      });
654      clearInterval(twb_run_notif_check);
655    }
656  }).error(function () {
657      clearInterval(twb_run_notif_check);
658  });
659
660}
661
662function twb_disable_check() {
663  twb_inprogress = true;
664  /* Add a hover action to show disabled notification.*/
665  jQuery(".twb-notoptimized").hover(function () {
666      jQuery(this).parent().find(".twb-score-disabled-container").removeClass("twb-hidden");
667    },
668    function () {
669      jQuery(this).parent().find(".twb-score-disabled-container").addClass("twb-hidden");
670    });
671}
672/**
673 * Optimize the page.
674 * @param that
675 */
676function twb_check_score(that) {
677  var post_id = jQuery(that).data("post_id");
678  var parent = jQuery(that).parent().parent().parent();
679  //var parent = jQuery(that).closest(".twb-score-container").parent();
680  /* Class add loading near admin bar menu */
681  jQuery(".twb_admin_bar_menu.twb_frontend").addClass("twb_score_inprogress");
682
683  /* If the action is not called with reload button.*/
684  if (parent.find(".twb-optimized").hasClass("twb-hidden")) {
685    /* Do not show loading in list.*/
686    parent.find(".twb-optimizing").removeClass("twb-hidden");
687  }
688  else {
689    /* Show loading on reload buttons.*/
690    parent.find(".twb-score-overlay").removeClass("twb-hidden");
691    parent.find(".twb-score-overlay div").removeClass("twb-reload").addClass("twb-loader");
692  }
693
694  parent.find(".twb-notoptimized").addClass("twb-hidden");
695
696  /* In case of Elementor */
697  if( parent.hasClass("twb_elementor_settings_content") ) {
698    jQuery(".twb_elementor_control_title").text(twb.checking).removeClass("twb_not_optimized").prepend("<span class='twb_inprogress'></span>");
699  }
700
701  /* Disable score check button.*/
702  twb_disable_check();
703
704  jQuery.ajax({
705    url: twb.ajax_url,
706    type: "POST",
707    dataType: 'json',
708    data: {
709      action: "twb_check_score",
710      post_id: post_id,
711      twb_nonce: twb.nonce
712    },
713    success: function (data) {
714      if (data.error) {
715        /* Show reload buttons on failure.*/
716        parent.find(".twb-score-overlay").removeClass("twb-hidden");
717        parent.find(".twb-score-overlay div").removeClass("twb-loader").addClass("twb-reload");
718      }
719      else {
720        parent.find(".twb-score-overlay").addClass("twb-hidden");
721        var desktop = parent.find(".twb-score-desktop").find(".twb-score-circle");
722        desktop.data(
723          {
724            "score": data.desktop_score,
725            "tti": data.desktop_tti,
726          });
727        twb_draw_score_circle(desktop);
728        var mobile = parent.find(".twb-score-mobile").find(".twb-score-circle");
729        mobile.data(
730          {
731            "score": data.mobile_score,
732            "tti": data.mobile_tti,
733          });
734        twb_draw_score_circle(mobile);
735      }
736    },
737    error: function (xhr, textStatus, errorThrown) {
738      /* Show reload buttons on failure.*/
739      parent.find(".twb-score-overlay").removeClass("twb-hidden");
740      parent.find(".twb-score-overlay div").removeClass("twb-loader").addClass("twb-reload");
741    },
742    complete: function (xhr, textStatus) {
743      /* Hide optimizing container, show See score container.*/
744      parent.find(".twb-optimizing").addClass("twb-hidden");
745      parent.find(".twb-optimized").removeClass("twb-hidden");
746
747      jQuery("#wpadminbar .twb-optimized .twb-score-container").removeClass("twb-hidden");
748      jQuery("#wpadminbar .twb_admin_bar_menu").removeClass("twb_score_inprogress");
749      jQuery("#wpadminbar .twb_menu_logo").remove();
750      jQuery("#wpadminbar .twb_not_optimized_logo").removeClass("twb-hidden");
751      jQuery("#wpadminbar .twb_admin_bar_menu_header").addClass("twb_not_optimized");
752
753      /* Remove disabled action.*/
754      twb_inprogress = false;
755      jQuery(".twb-notoptimized").hover(function () {
756        jQuery(this).parent().find(".twb-score-disabled-container").addClass("twb-hidden");
757      });
758
759      /* In case of Elementor */
760      if( parent.hasClass("twb_elementor_settings_content") ) {
761        jQuery(".twb_elementor_control_title").text(twb.notoptimized).remove("span.twb_inprogress").addClass("twb_not_optimized");
762      }
763    }
764  });
765}
766
767/**
768 * Draw circle on given score.
769 * @param that
770 */
771function twb_draw_score_circle(that) {
772  var score = parseInt(jQuery(that).data('score'));
773  var size = parseInt(jQuery(that).data('size'));
774  var thickness = parseInt(jQuery(that).data('thickness'));
775  var color = score <= 49 ? "rgb(253, 60, 49)" : (score >= 90 ? "rgb(12, 206, 107)" : "rgb(255, 164, 0)");
776  jQuery(that).parent().find('.twb-load-time').html(jQuery(that).data('tti'));
777  var _this = that;
778  jQuery(_this).circleProgress({
779    value: score / 100,
780    size: size,
781    startAngle: -Math.PI / 4 * 2,
782    lineCap: 'round',
783    emptyFill: "rgba(255, 255, 255, 0)",
784    thickness: thickness,
785    fill: {
786      color: color
787    }
788  }).on('circle-animation-progress', function (event, progress) {
789    var content = '<span class="twb-score0"></span>';
790    if (score != 0) {
791      content = Math.round(score * progress);
792    }
793    jQuery(that).find('.twb-score-circle-animated').html(content).css({"color": color});
794    jQuery(that).find('canvas').html(Math.round(score * progress));
795  });
796}
797
798/* Adding button in Elementor edit panel navigation view */
799function twb_add_elementor_button() {
800  window.elementor.modules.layouts.panel.pages.menu.Menu.addItem({
801    name: twb.title,
802    icon: "twb-element-menu-icon",
803    title: twb.title,
804    type: "page",
805    callback: () => {
806      try {
807        window.$e.route("panel/page-settings/twb_optimize")
808      } catch (e) {
809        window.$e.route("panel/page-settings/settings"), window.$e.route("panel/page-settings/twb_optimize")
810      }
811    }
812  }, "more")
813}
814
815jQuery(window).on("elementor:init", () => {
816  window.elementor.on("panel:init", () => {
817    setTimeout(twb_add_elementor_button)
818  })
819});
820;

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.