{"version":3,"sources":["jsdelivr-header.js","/npm/@snapboard/flipdown@0.2.3/src/flipdown.js"],"names":[],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA,ACEA,MAAM,SACJ,WAAA,CAAY,EAAK,EAAK,WAAY,EAAM,CAAC,GAGvC,GAAkB,iBAAR,EACR,MAAM,IAAI,MAAM,6DAA6D,cAI9D,iBAAP,IACR,EAAM,EACN,EAAK,YAIP,KAAK,QAAU,QAGf,KAAK,aAAc,EAGnB,KAAK,IAAM,KAAK,WAGhB,KAAK,MAAQ,EAGb,KAAK,gBAAiB,EAGtB,KAAK,iBAAmB,KAGxB,KAAK,QAAU,SAAS,eAAe,GAGvC,KAAK,OAAS,GACd,KAAK,eAAiB,GACtB,KAAK,cAAgB,GACrB,KAAK,UAAY,GACjB,KAAK,aAAe,GAGpB,KAAK,UAAY,KAGjB,KAAK,cAAgB,EAGrB,KAAK,YAAc,CAAC,EAGpB,KAAK,aAAe,CAAC,EAGrB,KAAK,oBAAsB,GAC3B,KAAK,wBAA0B,GAG/B,KAAK,KAAO,KAAK,cAAc,GAG/B,KAAK,cAGL,QAAQ,IAAI,YAAY,KAAK,mBAAmB,KAAK,KAAK,SAC5D,CAOA,KAAA,GAQE,OANI,KAAK,aAAa,KAAK,QAG3B,KAAK,UAAY,YAAY,KAAK,MAAM,KAAK,MAAO,KAG7C,IACT,CAQA,OAAA,CAAQ,GAON,OANA,KAAK,iBAAmB,WACtB,IACA,KAAK,iBAAmB,IAC1B,EAGO,IACT,CAOA,QAAA,GACE,OAAO,IAAI,MAAO,UAAY,GAChC,CAOA,kBAAA,GAGE,OAAI,KAAK,MAAQ,KAAK,IAAO,GAC3B,KAAK,gBAAiB,EAGM,MAAzB,KAAK,mBAGN,KAAK,mBAGL,KAAK,iBAAmB,OAGnB,IAKP,KAAK,gBAAiB,GACf,EAEX,CAQA,aAAA,CAAc,GACZ,MAAO,CAEL,MAAQ,EAAI,eAAe,SAAY,EAAI,MAAQ,OAEvD,CAOA,WAAA,GAGE,KAAK,QAAQ,UAAU,IAAI,mBAAmB,KAAK,KAAK,QAC1D,CAOA,KAAA,GAEE,KAAK,aAAc,EAGhB,KAAK,qBACN,KAAK,cAAgB,EAErB,KAAK,cAAgB,KAAK,OAAO,KAAK,MAAQ,KAAK,KAAO,OAAO,WAAW,OAK9E,IAHA,IAAI,EAAgB,KAAK,eAAiB,EAAI,EAAI,KAAK,cAG/C,EAAI,EAAG,EAAI,EAAgB,EAAG,IACpC,KAAK,OAAO,KAAK,KAAK,aAAa,IAIrC,IAAI,EAAY,GAChB,IAAQ,EAAI,EAAG,EAAI,EAAe,IAChC,EAAU,KAAK,KAAK,OAAO,IAE7B,KAAK,QAAQ,YAAY,KAAK,kBAAkB,IAGhD,IAAI,EAAQ,EACZ,IAAQ,EAAI,EAAG,EAAI,EAAG,IAAK,CAEzB,IADA,IAAI,EAAc,GACV,EAAI,EAAG,EAAI,EAAG,IACpB,EAAY,KAAK,KAAK,OAAO,IAC7B,IAEF,KAAK,QAAQ,YAAY,KAAK,kBAAkB,GAClD,CAYA,OATA,KAAK,eAAiB,MAAM,UAAU,MAAM,KAAK,KAAK,QAAQ,uBAAuB,qBACrF,KAAK,cAAgB,MAAM,UAAU,MAAM,KAAK,KAAK,QAAQ,uBAAuB,oBACpF,KAAK,SAAW,MAAM,UAAU,MAAM,KAAK,KAAK,QAAQ,uBAAuB,cAC/E,KAAK,YAAc,MAAM,UAAU,MAAM,KAAK,KAAK,QAAQ,uBAAuB,iBAGlF,KAAK,QACL,KAAK,oBAAmB,GAEjB,IACT,CAQA,iBAAA,CAAkB,GAChB,IAAI,EAAa,SAAS,cAAc,OACxC,EAAW,UAAY,cACvB,IAAI,EAAuB,SAAS,cAAc,OAIlD,OAHA,EAAqB,UAAY,sBACjC,EAAW,YAAY,GACvB,eAAe,EAAY,GACpB,CACT,CAQA,YAAA,CAAa,EAAI,GACf,IAAI,EAAQ,SAAS,cAAc,OAC/B,EAAY,SAAS,cAAc,OACnC,EAAgB,SAAS,cAAc,UACvC,EAAiB,SAAS,cAAc,UACxC,EAAW,SAAS,cAAc,OAClC,EAAc,SAAS,cAAc,OAYzC,OAXA,EAAM,UAAY,QAClB,EAAU,UAAY,aACtB,EAAc,UAAY,kBAC1B,EAAe,UAAY,mBAC3B,EAAS,UAAY,YACrB,EAAY,UAAY,eACxB,EAAc,YAAc,EAC5B,EAAS,YAAc,EACvB,EAAY,YAAc,EAC1B,eAAe,EAAO,CAAC,EAAW,EAAU,IAC5C,eAAe,EAAW,CAAC,EAAe,IACnC,CACT,CAOA,KAAA,GAGE,KAAK,IAAM,KAAK,WAGhB,IAAI,EAAS,KAAK,MAAQ,KAAK,KAAQ,EAAK,EAAI,KAAK,MAAQ,KAAK,IAGlE,KAAK,YAAY,EAAI,KAAK,MAAM,EAAO,OACvC,GAA6B,MAArB,KAAK,YAAY,EAGzB,KAAK,YAAY,EAAI,KAAK,MAAM,EAAO,MACvC,GAA6B,KAArB,KAAK,YAAY,EAGzB,KAAK,YAAY,EAAI,KAAK,MAAM,EAAO,IACvC,GAA6B,GAArB,KAAK,YAAY,EAGzB,KAAK,YAAY,EAAI,KAAK,MAAM,GAGhC,KAAK,qBAGL,KAAK,oBACP,CAQA,kBAAA,CAAmB,GAAO,GA0BxB,SAAS,IACP,KAAK,SAAS,SAAQ,CAAC,EAAI,KACtB,EAAG,aAAe,KAAK,oBAAoB,KAC5C,EAAG,YAAc,KAAK,oBAAoB,GAC5C,GAEJ,CAEA,SAAS,IACP,KAAK,cAAc,SAAQ,CAAC,EAAI,KAC9B,GAAG,EAAG,aAAe,KAAK,oBAAoB,GAAI,CAChD,EAAG,YAAc,KAAK,oBAAoB,GAC1C,EAAG,cAAc,UAAU,IAAI,WAC/B,IAAI,EAAO,YAAY,WACrB,EAAG,cAAc,UAAU,OAAO,WAClC,cAAc,EAChB,EAAE,KAAK,MAAO,IAChB,IAEJ,CA1CA,KAAK,aAAa,EAAI,IAAI,KAAK,YAAY,EAAG,GAC9C,KAAK,aAAa,EAAI,IAAI,KAAK,YAAY,EAAG,GAC9C,KAAK,aAAa,EAAI,IAAI,KAAK,YAAY,EAAG,GAC9C,KAAK,aAAa,EAAI,IAAI,KAAK,YAAY,EAAG,GAG9C,KAAK,qBAAuB,KAAK,aAAa,EAAI,KAAK,aAAa,EAAI,KAAK,aAAa,EAAI,KAAK,aAAa,GAAG,MAAM,IASzH,KAAK,eAAe,SAAQ,CAAC,EAAI,KAC/B,EAAG,YAAc,KAAK,wBAAwB,EAAE,IAGlD,KAAK,YAAY,SAAQ,CAAC,EAAI,KAC5B,EAAG,YAAc,KAAK,wBAAwB,EAAE,IAyB9C,GAIF,EAAa,KAAK,MAClB,EAAkB,KAAK,QAJvB,WAAW,EAAa,KAAK,MAAO,KACpC,WAAW,EAAkB,KAAK,MAAO,MAO3C,KAAK,wBAA0B,KAAK,mBACtC,EAUF,SAAS,IAAI,EAAG,GAEd,OADA,EAAI,EAAE,YACG,OAAS,EAAM,IAAI,IAAM,EAAG,GAAO,CAC9C,CAQA,SAAS,eAAe,EAAQ,GAC9B,EAAS,SAAQ,IACf,EAAO,YAAY,EAAG,GAE1B,gBAEe","file":"/npm/@snapboard/flipdown@0.2.3/src/flipdown.js","sourceRoot":"","sourcesContent":["/**\n * Minified by jsDelivr using Terser v5.39.0.\n * Original file: /npm/@snapboard/flipdown@0.2.3/src/flipdown.js\n *\n * Do NOT use SRI with dynamically generated files! More information: https://www.jsdelivr.com/using-sri-with-dynamic-files\n */\n","/**\n* @name FlipDown\n* @description Flip styled countdown clock\n* @author Peter Butcher (PButcher) <pbutcher93[at]gmail[dot]com>\n* @param {number} uts - Time to count down to as unix timestamp\n* @param {string} el - DOM element to attach FlipDown to\n* @param {object} opt - Optional configuration settings\n**/\nclass FlipDown {\n  constructor(uts, el = 'flipdown', opt = {}) {\n\n    // If uts is not specified\n    if(typeof uts !== 'number') {\n      throw new Error(`FlipDown: Constructor expected unix timestamp, got ${typeof uts} instead.`);\n    }\n\n    // If opt is specified, but not el\n    if(typeof el === 'object') {\n      opt = el;\n      el = 'flipdown';\n    }\n\n    // FlipDown version\n    this.version = '0.2.2';\n\n    // Initialised?\n    this.initialised = false;\n\n    // Time at instantiation in seconds\n    this.now = this._getTime();\n\n    // UTS to count down to\n    this.epoch = uts;\n\n    // UTS passed to FlipDown is in the past\n    this.countdownEnded = false;\n\n    // User defined callback for countdown end\n    this.hasEndedCallback = null;\n\n    // FlipDown DOM element\n    this.element = document.getElementById(el);\n\n    // Rotor DOM elements\n    this.rotors = [];\n    this.rotorLeafFront = [];\n    this.rotorLeafRear = [];\n    this.rotorTops = [];\n    this.rotorBottoms = [];\n\n    // Interval\n    this.countdown = null;\n\n    // Number of days remaining\n    this.daysRemaining = 0;\n\n    // Clock values as numbers\n    this.clockValues = {};\n\n    // Clock values as strings\n    this.clockStrings = {};\n\n    // Clock values as array\n    this.clockValuesAsString = [];\n    this.prevClockValuesAsString = [];\n\n    // Parse options\n    this.opts = this._parseOptions(opt);\n\n    // Set options\n    this._setOptions();\n\n    // Print Version\n    console.log(`FlipDown ${this.version} (Theme: ${this.opts.theme})`);\n  }\n\n  /**\n  * @name start\n  * @description Start the countdown\n  * @author PButcher\n  **/\n  start() {\n    // Initialise the clock\n    if(!this.initialised) this._init();\n\n    // Set up the countdown interval\n    this.countdown = setInterval(this._tick.bind(this), 1000);\n\n    // Chainable\n    return this;\n  }\n\n  /**\n  * @name ifEnded\n  * @description Call a function once the countdown ends\n  * @author PButcher\n  * @param {function} cb - Callback\n  **/\n  ifEnded(cb) {\n    this.hasEndedCallback = function() {\n      cb();\n      this.hasEndedCallback = null;\n    }\n\n    // Chainable\n    return this;\n  }\n\n  /**\n  * @name _getTime\n  * @description Get the time in seconds (unix timestamp)\n  * @author PButcher\n  **/\n  _getTime() {\n    return new Date().getTime() / 1000;\n  }\n\n  /**\n  * @name _hasCountdownEnded\n  * @description Has the countdown ended?\n  * @author PButcher\n  **/\n  _hasCountdownEnded() {\n\n    // Countdown has ended\n    if((this.epoch - this.now) < 0) {\n      this.countdownEnded = true;\n\n      // Fire the ifEnded callback once if it was set\n      if(this.hasEndedCallback != null) {\n\n        // Call ifEnded callback\n        this.hasEndedCallback();\n\n        // Remove the callback\n        this.hasEndedCallback = null;\n      }\n\n      return true;\n\n    // Countdown has not ended\n    } else {\n\n      this.countdownEnded = false;\n      return false;\n    }\n  }\n\n  /**\n  * @name _parseOptions\n  * @description Parse any passed options\n  * @param {object} opt - Optional configuration settings\n  * @author PButcher\n  **/\n  _parseOptions(opt) {\n    return {\n      // Theme\n      theme: (opt.hasOwnProperty('theme')) ? opt.theme : 'dark'\n    }\n  }\n\n  /**\n  * @name _setOptions\n  * @description Set optional configuration settings\n  * @author PButcher\n  **/\n  _setOptions() {\n\n    // Apply theme\n    this.element.classList.add(`flipdown__theme-${this.opts.theme}`);\n  }\n\n  /**\n  * @name _init\n  * @description Initialise the countdown\n  * @author PButcher\n  **/\n  _init() {\n\n    this.initialised = true;\n\n    // Check whether countdown has ended and calculate how many digits the day counter needs\n    if(this._hasCountdownEnded()) {\n      this.daysremaining = 0;\n    } else {\n      this.daysremaining = Math.floor((this.epoch - this.now) / 86400).toString().length;\n    }\n    var dayRotorCount = this.daysremaining <= 2 ? 2 : this.daysremaining;\n\n    // Create and store rotors\n    for(var i = 0; i < dayRotorCount + 6; i++) {\n      this.rotors.push(this._createRotor(0));\n    }\n\n    // Create day rotor group\n    var dayRotors = [];\n    for(var i = 0; i < dayRotorCount; i++) {\n      dayRotors.push(this.rotors[i]);\n    }\n    this.element.appendChild(this._createRotorGroup(dayRotors));\n\n    // Create other rotor groups\n    var count = dayRotorCount;\n    for(var i = 0; i < 3; i++) {\n      var otherRotors = [];\n      for(var j = 0; j < 2; j++) {\n        otherRotors.push(this.rotors[count]);\n        count++;\n      }\n      this.element.appendChild(this._createRotorGroup(otherRotors));\n    }\n\n    // Store and convert rotor nodelists to arrays\n    this.rotorLeafFront = Array.prototype.slice.call(this.element.getElementsByClassName('rotor-leaf-front'));\n    this.rotorLeafRear = Array.prototype.slice.call(this.element.getElementsByClassName('rotor-leaf-rear'));\n    this.rotorTop = Array.prototype.slice.call(this.element.getElementsByClassName('rotor-top'));\n    this.rotorBottom = Array.prototype.slice.call(this.element.getElementsByClassName('rotor-bottom'));\n\n    // Set initial values;\n    this._tick();\n    this._updateClockValues(true);\n\n    return this;\n  }\n\n  /**\n  * @name _createRotorGroup\n  * @description Add rotors to the DOM\n  * @author PButcher\n  * @param {array} rotors - A set of rotors\n  **/\n  _createRotorGroup(rotors) {\n    var rotorGroup = document.createElement('div');\n    rotorGroup.className = 'rotor-group';\n    var dayRotorGroupHeading = document.createElement('div');\n    dayRotorGroupHeading.className = 'rotor-group-heading';\n    rotorGroup.appendChild(dayRotorGroupHeading);\n    appendChildren(rotorGroup, rotors);\n    return rotorGroup;\n  }\n\n  /**\n  * @name _createRotor\n  * @description Create a rotor DOM element\n  * @author PButcher\n  * @param {number} v - Initial rotor value\n  **/\n  _createRotor(v = 0) {\n    var rotor = document.createElement('div');\n    var rotorLeaf = document.createElement('div');\n    var rotorLeafRear = document.createElement('figure');\n    var rotorLeafFront = document.createElement('figure');\n    var rotorTop = document.createElement('div');\n    var rotorBottom = document.createElement('div');\n    rotor.className = 'rotor';\n    rotorLeaf.className = 'rotor-leaf';\n    rotorLeafRear.className = 'rotor-leaf-rear';\n    rotorLeafFront.className = 'rotor-leaf-front';\n    rotorTop.className = 'rotor-top';\n    rotorBottom.className = 'rotor-bottom';\n    rotorLeafRear.textContent = v;\n    rotorTop.textContent = v;\n    rotorBottom.textContent = v;\n    appendChildren(rotor, [rotorLeaf, rotorTop, rotorBottom]);\n    appendChildren(rotorLeaf, [rotorLeafRear, rotorLeafFront]);\n    return rotor;\n  }\n\n  /**\n  * @name _tick\n  * @description Calculate current tick\n  * @author PButcher\n  **/\n  _tick() {\n\n    // Get time now\n    this.now = this._getTime();\n\n    // Between now and epoch\n    var diff = ((this.epoch - this.now) <= 0) ? 0 : this.epoch - this.now;\n\n    // Days remaining\n    this.clockValues.d = Math.floor(diff / 86400);\n    diff -= this.clockValues.d * 86400;\n\n    // Hours remaining\n    this.clockValues.h = Math.floor(diff / 3600);\n    diff -= this.clockValues.h * 3600;\n\n    // Minutes remaining\n    this.clockValues.m = Math.floor(diff / 60);\n    diff -= this.clockValues.m * 60;\n\n    // Seconds remaining\n    this.clockValues.s = Math.floor(diff);\n\n    // Update clock values\n    this._updateClockValues();\n\n    // Has the countdown ended?\n    this._hasCountdownEnded();\n  }\n\n  /**\n  * @name _updateClockValues\n  * @description Update the clock face values\n  * @author PButcher\n  * @param {boolean} init - True if calling for initialisation\n  **/\n  _updateClockValues(init = false) {\n\n    // Build clock value strings\n    this.clockStrings.d = pad(this.clockValues.d, 2);\n    this.clockStrings.h = pad(this.clockValues.h, 2);\n    this.clockStrings.m = pad(this.clockValues.m, 2);\n    this.clockStrings.s = pad(this.clockValues.s, 2);\n\n    // Concat clock value strings\n    this.clockValuesAsString = (this.clockStrings.d + this.clockStrings.h + this.clockStrings.m + this.clockStrings.s).split('');\n\n    // Update rotor values\n    // Note that the faces which are initially visible are:\n    // - rotorLeafFront (top half of current rotor)\n    // - rotorBottom (bottom half of current rotor)\n    // Note that the faces which are initially hidden are:\n    // - rotorTop (top half of next rotor)\n    // - rotorLeafRear (bottom half of next rotor)\n    this.rotorLeafFront.forEach((el, i) => {\n      el.textContent = this.prevClockValuesAsString[i];\n    });\n\n    this.rotorBottom.forEach((el, i) => {\n      el.textContent = this.prevClockValuesAsString[i];\n    });\n\n    function rotorTopFlip() {\n      this.rotorTop.forEach((el, i) => {\n        if(el.textContent != this.clockValuesAsString[i]) {\n          el.textContent = this.clockValuesAsString[i];\n        }\n      });\n    }\n\n    function rotorLeafRearFlip() {\n      this.rotorLeafRear.forEach((el, i) => {\n        if(el.textContent != this.clockValuesAsString[i]) {\n          el.textContent = this.clockValuesAsString[i];\n          el.parentElement.classList.add('flipped');\n          var flip = setInterval(function() {\n            el.parentElement.classList.remove('flipped');\n            clearInterval(flip);\n          }.bind(this), 500);\n        }\n      });\n    }\n\n    // Init\n    if(!init) {\n      setTimeout(rotorTopFlip.bind(this), 500);\n      setTimeout(rotorLeafRearFlip.bind(this), 500);\n    } else {\n      rotorTopFlip.call(this);\n      rotorLeafRearFlip.call(this);\n    }\n\n    // Save a copy of clock values for next tick\n    this.prevClockValuesAsString = this.clockValuesAsString;\n  }\n}\n\n/**\n* @name pad\n* @description Prefix a number with zeroes\n* @author PButcher\n* @param {string} n - Number to pad\n* @param {number} len - Desired length of number\n**/\nfunction pad(n, len) {\n  n = n.toString();\n  return n.length < len ? pad(\"0\" + n, len) : n;\n}\n\n/**\n* @name appendChildren\n* @description Add multiple children to an element\n* @author PButcher\n* @param {object} parent - Parent\n**/\nfunction appendChildren(parent, children) {\n  children.forEach(el => {\n    parent.appendChild(el);\n  });\n}\n\nexport default FlipDown\n"]}