text: /***************************************************************************************************************************************************************
   *        _ ________           __        ________  _________
   *       (_) ____/ /___  _____/ /_______/ ____/  |/  /_  __/
   *      / / /   / / __ \/ ___/ //_/ ___/ / __/ /|_/ / / /
   *     / / /___/ / /_/ / /__/ ,< (__  ) /_/ / /  / / / /
   *  __/ /\____/_/\____/\___/_/|_/____/\____/_/  /_/ /_/
   * /___/
   *
   * NAME: jClocksGMT.js
   * VERSION: 2.0.2
   * LAST UPDATE: 2016.04.26
   *
   * Author Information:
   *      Name: Richard McMaster
   *      Email: r@kingkode.com
   *      Location: Houston, Texas, United States
   *      Website: http://kingkode.com/jclocksgmt-js/
   *      __   _             __             __
   *     / /__(_)___  ____ _/ /______  ____/ /__
   *    / //_/ / __ \/ __ `/ //_/ __ \/ __  / _ \
   *   / ,< / / / / / /_/ / ,< / /_/ / /_/ /  __/
   *  /_/|_/_/_/ /_/\__, /_/|_|\____/\__,_/\___/
   *               /____/
   *
   * Plugin Website: http://www.github.com/mcmastermind/jClocksGMT
   *
   * Change Log:
   *      2.0.2: Fixed digital only display
   *      2.0.1: Added image path parameter for images not in plugin directory
   *      2.0: Complete overhaul of code for increased accuracy and stability
   *              - NEW! 5 clock skins to choose from
   *              - NEW! Timestamp formatting options
   *              - NEW! Date display with formatting options
   *              - NEW! DST parameter for those locations that do not observe DST
   *              - Addressed international DST issues
   *              - Minimized initial markup
   *              - Unique class names to avoid common class declarations
   *      1.2: Fixed severely flawed Daylight Saving Time calculation
   *      1.1: Added automatic Daylight Saving Time calculation
   *
   * Licensed under the MIT license: http://www.opensource.org/licenses/mit-license.php
   *
   * Description:
   *      jQuery based analog and digital clock(s) using GMT offsets. Requires jQuery Rotate plugin.
   *
   * Documentation:
   *      Default options:
   *          title: 'Greenwich, England', String: Title of location (defaults to Greenwich, England)
   *          offset: '0',                 String: Set Standard GMT offset (+5.5, -4, 0, etc) (do not consider daylight savings time)
   *          dst: true,                   Boolean: Does the location observe daylight savings time (set FALSE if location does not need to observe dst )
   *          digital: true,               Boolean: Display digital clock
   *          analog: true,                Boolean: Display analog clock
   *          timeformat: 'hh:mm A',       String: Time format (see below for formatting options)
   *          date: false,                 Boolean: Display date
   *          dateformat: 'MM/DD/YYYY',    String: Date format (see below for formatting options)
   *          angleSec: 0,                 Integer: Starting angle of second hand
   *          angleMin: 0,                 Integer: Starting angle of minute hand
   *          angleHour: 0,                Integer: Starting angle of hour hand
   *          skin: 1,                     Integer: Set 1 of 5 included skins for the analog clock
   *          imgpath: ''                  String:  Set path of images
   *
   *      Common offsets by time zone: (only use the number after GMT: GMT-2 = offset: '-2'
   *                                    Daylight Saving Time converted automatically)
   *          GMT-12	 Eniwetok
   *          GMT-11	 Samoa
   *          GMT-10	 Hawaii
   *          GMT-9	 Alaska
   *          GMT-8	 PST, Pacific US
   *          GMT-7	 MST, Mountain US
   *          GMT-6	 CST, Central US
   *          GMT-5	 EST, Eastern US
   *          GMT-4	 Atlantic, Canada
   *          GMT-3	 Brazilia, Buenos Aries
   *          GMT-2	 Mid-Atlantic
   *          GMT-1	 Cape Verdes
   *          GMT	0    Greenwich Mean Time
   *          GMT+1	 Berlin, Rome
   *          GMT+2	 Israel, Cairo
   *          GMT+3	 Moscow, Kuwait
   *          GMT+4	 Abu Dhabi, Muscat
   *          GMT+5	 Islamabad, Karachi
   *          GMT+6	 Almaty, Dhaka
   *          GMT+7	 Bangkok, Jakarta
   *          GMT+8	 Hong Kong, Beijing
   *          GMT+9	 Tokyo, Osaka
   *          GMT+10	 Sydney, Melbourne, Guam
   *          GMT+11	 Magadan, Soloman Is.
   *          GMT+12	 Fiji, Wellington, Auckland
   *
   *          To find specific GMT offsets,
   *              goto: http://www.timeanddate.com/time/zone/
   *              search: location
   *              use: Current Offset
   *                  if location is currently observing DST, add 1 to offset
   *
   *      Time Formatting:
   *          HH      19      24-hour format of hour with leading zero (two digits long).
   *          hh      07      12-hour format of hour with leading zero (two digits long).
   *          H       19      24-hour format of hour without leading zeros.
   *          h       7       12-hour format of hour without leading zeros.
   *          mm      01      Minutes with the leading zero (two digits long).
   *          m       1       Minutes without the leading zero.
   *          ss      08      Seconds with the leading zero (two digits long).
   *          s       8       Seconds without the leading zero.
   *          a       pm      Lowercase am or pm.
   *          A       PM      Uppercase AM or PM.
   *          SSS     095     Milliseconds with leading zeros (three digits long).
   *          S       95      Milliseconds without leading zeros.
   *
   *      Date Formatting:
   *          YYYY    2016    Four-digit representation of the year.
   *          YY      16      Two-digit representation of the year.
   *          MMMM    April   Full textual representation of the month.
   *          MMM     Apr     Three letter representation of the month.
   *          MM      04      Month with the leading zero (two digits long).
   *          M       4       Month without the leading zero.
   *          DDDD    Friday  Full textual representation of the day of the week.
   *          DDD     Fri     Three letter representation of the day of the week.
   *          DD      01      Day of the month with leading zero (two digits long).
   *          D       1       Day of the month without leading zeros.
   *
   *      Initialization:
   *          Javascript:
   *              $('#clock_hou').jClocksGMT({ title: 'Houston, TX, USA', offset: '-6', skin: 2 });
   *          Markup:
   *               <div id="clock_hou"></div>
   *
   **************************************************************************************************************************************************************/
  
   (function($) {
  
      $.fn.extend({
  
          jClocksGMT: function( options )
          {
              // plugin default options
              var defaults =
              {
                  title: 'Greenwich, England',
                  offset: '0',
                  dst: true,
                  digital: true,
                  analog: true,
                  timeformat: 'hh:mm A',
                  date: false,
                  dateformat: 'MM/DD/YYYY',
                  angleSec: 0,
                  angleMin: 0,
                  angleHour: 0,
                  skin: 1,
                  imgpath: ''
              }
  
              // merge user options with defaults
              var options = $.extend(defaults, options);
  
              return this.each(function()
              {
                  // set offset variable per instance
                  var offset = parseFloat(options.offset);
                  // get id of element
                  var id = $(this).attr('id');
  
                  // add class to main element
                  $(this).addClass('jcgmt-container');
  
                  // create label
                  $("<div />", { text: options.title, class: "jcgmt-lbl" }).appendTo("#" + id);
  
                  if( options.analog )
                  {
                      // create clock container
                      $("<div />", { class: "jcgmt-clockHolder" }).appendTo("#" + id);
                      // create hour hand
                      $("<div />", { class: "jcgmt-rotatingWrapper" }).append($("<img />", { class: "jcgmt-hour", src: options.imgpath + "https://clippingpathaid.com/public/contents/frontend/images/jcgmt-" + options.skin + "-clock_hour.png" })).appendTo("#" + id + ' .jcgmt-clockHolder');
                      // create min hand
                      $("<div />", { class: "jcgmt-rotatingWrapper" }).append($("<img />", { class: "jcgmt-min", src: options.imgpath + "https://clippingpathaid.com/public/contents/frontend/images/jcgmt-" + options.skin + "-clock_min.png" })).appendTo("#" + id + ' .jcgmt-clockHolder');
                      // create sec hand
                      $("<div />", { class: "jcgmt-rotatingWrapper" }).append($("<img />", { class: "jcgmt-sec", src: options.imgpath + "https://clippingpathaid.com/public/contents/frontend/images/jcgmt-" + options.skin + "-clock_sec.png" })).appendTo("#" + id + ' .jcgmt-clockHolder');
                      // create clock face
                      $("<img />", { class: "jcgmt-clock", src: options.imgpath + 'https://clippingpathaid.com/public/contents/frontend/images/jcgmt-' + options.skin + '-clock_face.png' }).appendTo("#" + id + ' .jcgmt-clockHolder');
                  }
  
                  // create digital clock container
                  $("<div />", { class: "jcgmt-digital" }).appendTo("#" + id);
  
                  //create date container
                  $("<div />", { class: "jcgmt-date" }).appendTo("#" + id);
  
                  // initial hand rotation
                  $('#' + id + ' .jcgmt-sec').rotate( options.angleSec );
                  $('#' + id + ' .jcgmt-min').rotate( options.angleMin );
                  $('#' + id + ' .jcgmt-hour').rotate( options.angleHour );
  
                  // get timezone by gmt offset
                  Date.prototype.getTimezoneByOffset = function( offset, y, m, d )
                  {
                      var date = new Date; // get date
  
                      if( y ) // if has date params
                      {
                          date = new Date( y, m, d ); // get date with params
                      }
  
                      var utc = date.getTime() + ( date.getTimezoneOffset() * 60000 ); // get local offset
  
                      var dateGMT = new Date( utc + ( 3600000 * offset ) ); // get requested offset based on local
  
                      return dateGMT;
                  }
  
                  // check if daylight saving time is in effect
                  Date.prototype.stdTimezoneOffset = function()
                  {
                      var jan = this.getTimezoneByOffset( offset, this.getFullYear(), 0, 1 );
  
                      var jul = this.getTimezoneByOffset( offset, this.getFullYear(), 6, 1 );
  
                      return Math.max( jan.getTimezoneOffset(), jul.getTimezoneOffset() );
                  }
  
                  // checkes if DST is in effect
                  Date.prototype.isDST = function()
                  {
                      var date = this.getTimezoneByOffset(offset);
  
                      return date.getTimezoneOffset() < this.stdTimezoneOffset();
                  }
  
                  // date formatter
                  Date.prototype.format = function( format )
                  {
                      var D = "Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday".split(","),
                          M = "January,February,March,April,May,June,July,August,September,October,November,December".split(",");
  
                      var self = this;
                      return format.replace(/a|A|Z|S(SS)?|ss?|mm?|HH?|hh?|D{1,4}|M{1,4}|YY(YY)?|'([^']|'')*'/g, function(str) {
                        var c1 = str.charAt(0),
                            ret = str.charAt(0) == "'"
                            ? (c1=0) || str.slice(1, -1).replace(/''/g, "'")
                            : str == "a"
                              ? (self.getHours() < 12 ? "am" : "pm")
                              : str == "A"
                                ? (self.getHours() < 12 ? "AM" : "PM")
                                : str == "Z"
                                  ? (("+" + -self.getTimezoneOffset() / 60).replace(/^\D?(\D)/, "$1").replace(/^(.)(.)$/, "$10$2") + "00")
                                  : c1 == "S"
                                    ? self.getMilliseconds()
                                    : c1 == "s"
                                      ? self.getSeconds()
                                      : c1 == "H"
                                        ? self.getHours()
                                        : c1 == "h"
                                          ? (self.getHours() % 12) || 12
                                          : (c1 == "D" && str.length > 2)
                                            ? D[self.getDay()].slice(0, str.length > 3 ? 9 : 3)
                                            : c1 == "D"
                                              ? self.getDate()
                                              : (c1 == "M" && str.length > 2)
                                                ? M[self.getMonth()].slice(0, str.length > 3 ? 9 : 3)
                                                : c1 == "m"
                                                  ? self.getMinutes()
                                                  : c1 == "M"
                                                    ? self.getMonth() + 1
                                                    : ("" + self.getFullYear()).slice(-str.length);
                        return c1 && str.length < 4 && ("" + ret).length < str.length
                          ? ("00" + ret).slice(-str.length)
                          : ret;
                      });
                    }
  
                  // create new date object
                  var dateCheck = new Date().getTimezoneByOffset( offset );
  
                  // check for DST
                  if( options.dst && dateCheck.isDST() )
                  {
                     offset = offset + 1;
                  }
  
                  // clock interval
                  setInterval(function ()
                  {
                      // create new date object
                      var nd = new Date().getTimezoneByOffset( offset );
  
                      // time string variable
                      var timeStr = nd.format( options.timeformat );
  
                      // update analog clock if enabled
                      if( options.analog )
                      {
                          // rotate second hand
                          $('#' + id + ' .jcgmt-sec').rotate( nd.getSeconds() * 6 );
                          // rotate minute hand
                          $('#' + id + ' .jcgmt-min').rotate( nd.getMinutes() * 6 ) ;
                          // rotate hour hand
                          $('#' + id + ' .jcgmt-hour').rotate( ( nd.getHours() * 5 + nd.getMinutes() / 12 ) * 6 );
  
                          // update title for tooltip
                          $('#' + id + ' .jcgmt-clockHolder').attr( 'title', timeStr );
                      }
  
                      // update digital clock if enabled
                      if( options.digital )
                      {
                          $('#' + id + ' .jcgmt-digital').html( timeStr );
                          $('#' + id + ' .jcgmt-digital').attr( 'title', timeStr );
                      }
  
                      // update date if enabled
                      if( options.date )
                      {
                          var dateStamp = nd.format( options.dateformat );
                          $('#' + id + ' .jcgmt-date').html( dateStamp );
                          $('#' + id + ' .jcgmt-date').attr( 'title', dateStamp );
                      }
  
                  }, 1000);
  
              });
  
          }
  
      });
  
  })(jQuery);
  