{"pages":{"start":[{"if":{"condition":"!window.setTimeout \/* v1.7 *\/","commands":[{"audio.play":{"locator":"file:1-minute-of-silence.mp3","volume":0.01,"background":true,"id":"timer-1"}},{"audio.play":{"locator":"file:1-minute-of-silence.mp3","volume":0.01,"background":true,"id":"timer-2"}},{"audio.play":{"locator":"file:1-minute-of-silence.mp3","volume":0.01,"background":true,"id":"timer-3"}},{"audio.play":{"locator":"file:1-minute-of-silence.mp3","volume":0.01,"background":true,"id":"timer-4"}},{"audio.play":{"locator":"file:1-minute-of-silence.mp3","volume":0.01,"background":true,"id":"timer-5"}},{"audio.play":{"locator":"file:1-minute-of-silence.mp3","volume":0.01,"background":true,"id":"timer-6"}},{"audio.play":{"locator":"file:1-minute-of-silence.mp3","volume":0.01,"background":true,"id":"timer-7"}},{"audio.play":{"locator":"file:1-minute-of-silence.mp3","volume":0.01,"background":true,"id":"timer-8"}},{"audio.play":{"locator":"file:1-minute-of-silence.mp3","volume":0.01,"background":true,"id":"timer-9"}},{"audio.play":{"locator":"file:1-minute-of-silence.mp3","volume":0.01,"background":true,"id":"timer-10"}},{"audio.play":{"locator":"file:1-minute-of-silence.mp3","volume":0.01,"background":true,"id":"timer-11"}},{"audio.play":{"locator":"file:1-minute-of-silence.mp3","volume":0.01,"background":true,"id":"timer-12"}},{"audio.play":{"locator":"file:1-minute-of-silence.mp3","volume":0.01,"background":true,"id":"timer-13"}},{"audio.play":{"locator":"file:1-minute-of-silence.mp3","volume":0.01,"background":true,"id":"timer-14"}},{"audio.play":{"locator":"file:1-minute-of-silence.mp3","volume":0.01,"background":true,"id":"timer-15"}},{"audio.play":{"locator":"file:1-minute-of-silence.mp3","volume":0.01,"background":true,"id":"timer-16"}},{"audio.play":{"locator":"file:1-minute-of-silence.mp3","volume":0.01,"background":true,"id":"timer-17"}},{"audio.play":{"locator":"file:1-minute-of-silence.mp3","volume":0.01,"background":true,"id":"timer-18"}},{"audio.play":{"locator":"file:1-minute-of-silence.mp3","volume":0.01,"background":true,"id":"timer-19"}},{"audio.play":{"locator":"file:1-minute-of-silence.mp3","volume":0.01,"background":true,"id":"timer-20"}},{"eval":{"script":"\/\/ Init native timer emulation\r\n\/******************************\r\n *  CHANGE LOG\r\n * ****************************\r\n * \r\n * v1.7\r\n *   - Simplify timer functions\r\n * \r\n * v1.6\r\n *   - Allow re-use of sound end event listener\r\n * \r\n * v1.5\r\n *   - More tweaks to deal with interruptions\r\n * \r\n * v1.4\r\n *   - Further adjustments for JS interpreter interruptions\r\n * \r\n * v1.3\r\n *   - Try to reduce errors in offet counters introduced\r\n *      by pauses between JS interpreter steps\r\n * \r\n * v1.1 - v1.2 \r\n *   - Try to improve performance\r\n * \r\n * v1.0\r\n *   - Initial release\r\n * \r\n *\/\r\n(function() {\r\n  \/\/ var debug = false\r\n  var timers = {}\r\n  var sounds = {}\r\n  var counter = 1\r\n  var timerError = 268 \/\/ Always seems to be around 268ms of error (issue with audio files?)\r\n  var maxTime = 60000 \/\/ Sound is 1 min long, so that's the max\r\n  var i = 1\r\n  var timerPool = []\r\n  \r\n  function listener() {\r\n    var id = this.__id\r\n    var timer = timers[id]\r\n    \/\/ this.stop()\r\n    this.__id = null \/\/ disable id\r\n    if (!timer) return\r\n    var opt = timer._opt\r\n    timerPool.unshift(timer) \/\/ Put timer back in queue\r\n    if ((opt.start + (opt.time * opt.iter)) - Date.now() > 20) {\r\n      \/\/ Not done.  We'll need to run again\r\n      doTimer(opt)\r\n      return\r\n    }\r\n    if (opt.interval) {\r\n      \/\/ Run again\r\n      opt.iter++\r\n      doTimer(opt)\r\n    } else {\r\n      delete timers[id]\r\n    }\r\n    try {\r\n      opt.fn()\r\n    } catch (e) {\r\n      console.error('Error in timer fn', e.toString())\r\n    }\r\n  }\r\n\r\n  var tSound = Sound.get('timer-' + i)\r\n  while (tSound) {\r\n    tSound.stop()\r\n    tSound.seek(maxTime-timerError)\r\n    tSound.play()\r\n    tSound.addEventListener('end', listener)\r\n    sounds[i] = tSound\r\n    var timer = {\r\n      sound: tSound,\r\n      index: i\r\n    }\r\n    timerPool.push(timer)\r\n    i++\r\n    tSound = Sound.get('timer-' + i)\r\n  }\r\n  var poolSize = timerPool.length\r\n\r\n  function doTimer(opt) {\r\n    var id = opt.id\r\n    var timer = timerPool.pop()\r\n    if (!timer) {\r\n      throw \"No timer sounds left in timer pool.  Add more if you need more than \" + poolSize + \" concurrent timers.\"\r\n    }\r\n    timer._opt = opt\r\n    var sound = timer.sound\r\n    sound.__id = id\r\n    timers[id] = timer\r\n    sound.seek(Math.max(1, timerError + (maxTime - Math.min(\r\n      (opt.start + (opt.time * opt.iter)) - Date.now(), \r\n      maxTime - 1000\r\n    ))) \/ 1000)\r\n    sound.play()\r\n    return id\r\n  }\r\n\r\n  function clearTimer(id) {\r\n    var timer = timers[id]\r\n    if (timer) {\r\n      delete timers[id]\r\n      var sound = timer.sound\r\n      sound.__id = null\r\n      sound.stop()\r\n      timerPool.unshift(timer)\r\n    }\r\n  }\r\n\r\n  window.setTimeout = function(fn, time) {\r\n    return doTimer({\r\n      id: counter++,\r\n      time: time || 0, \r\n      iter: 1,\r\n      fn: fn, \r\n      start: Date.now()\r\n      })\r\n  }\r\n\r\n  window.clearTimeout = function(id) {\r\n    return clearTimer(id)\r\n  }\r\n\r\n  window.setInterval = function(fn, time) {\r\n    return doTimer({\r\n      id: counter++,\r\n      time: time || 0, \r\n      iter: 1,\r\n      fn: fn, \r\n      interval: true,\r\n      start: Date.now()\r\n      })\r\n  }\r\n  \r\n  window.clearInterval = function(id) {\r\n    return clearTimer(id)\r\n  }\r\n})()\r\n"}}]}},{"if":{"condition":"!window.TitleAnimator \/* v1.3 *\/","commands":[{"eval":{"script":"\/\/ Install TitleAnimator\r\n(function(){\r\n  if (window.TitleAnimator) return\r\n  window.TitleAnimator = function(opt) {\r\n    this.setOptions(opt)\r\n    return this\r\n  }\r\n  TitleAnimator.last = {}\r\n  TitleAnimator.prototype.setOptions = function(opt) {\r\n    opt = opt || {}\r\n    var reset = opt.reset || false\r\n    this.notificationId = opt.notificationId || (!reset && this.notificationId) || 'animator'\r\n    this.fps = opt.fps || (!reset && this.fps) || 10\r\n    this.frameCount = opt.frameCount || (!reset && this.frameCount) || 4\r\n    this.frameOffset = 0\r\n    this.frames = opt.frames || (!reset && this.frames) || {\r\n      1: '|',\r\n      2: '\/',\r\n      3: '-',\r\n      4: '\\\\',\r\n    }\r\n    this.onFrame = opt.onFrame || (!reset && this.onFrame) || {}\r\n    this.iterations = opt.iterations === null ? null : opt.iterations || (!reset && this.iterations) || null\r\n    this.onEachFrame = opt.onEachFrame || (!reset && this.onEachFrame) || undefined\r\n    this.onEachIteration = opt.onEachIteration || (!reset && this.onEachIteration) || undefined\r\n    this.requireNotification = opt.requireNotification !== undefined ? opt.requireNotification : (!reset && this.requireNotification !== undefined) ? this.requireNotification : true\r\n    this.iteration = this.iteration || 0\r\n    this.running = this.running || false\r\n    this.lastFrameId = opt.lastFrameId || this.lastFrameId || this.frameCount\r\n    this.lastFrame = this.lastFrame || null\r\n    var lastInterval = this.interval\r\n    this.interval = Math.round(1000\/this.fps)\r\n    if (this.running && lastInterval !== this.interval) {\r\n      this.resetInterval = true\r\n    }\r\n  }\r\n  TitleAnimator.prototype._getNotification = function() {\r\n    return Notification.get(this.notificationId)\r\n  }\r\n  TitleAnimator.prototype._startInterval = function() {\r\n    var _this = this\r\n    this.intervalId = setInterval(function() {\r\n      _this.step()\r\n    }, this.interval)\r\n    \/\/ console.log('Restarting interval', this.__pattern, this)\r\n  }\r\n  TitleAnimator.prototype.run = function() {\r\n    if (this.running) return\r\n    var notification = this._getNotification()\r\n    if (notification || !this.requireNotification) {\r\n      if (TitleAnimator.last[this.notificationId] !== this && TitleAnimator.last[this.notificationId] && TitleAnimator.last[this.notificationId].running) {\r\n        TitleAnimator.last[this.notificationId].stop()\r\n      }\r\n      TitleAnimator.last[this.notificationId] = this\r\n      this._startInterval()\r\n      this.running = true\r\n    }\r\n    return this\r\n  }\r\n  TitleAnimator.prototype.stop = function() {\r\n    if (!this.running) return\r\n    clearInterval(this.intervalId)\r\n    this.running = false\r\n    return this\r\n  }\r\n  TitleAnimator.prototype.step = function() {\r\n    var frameId = this.lastFrameId + 1\r\n    var didIteration = frameId > this.frameCount\r\n    var _this = this\r\n    if (didIteration) {\r\n      this.lastIterationFrameId = this.lastFrameId\r\n      frameId = 1\r\n      this.iteration ++\r\n    }\r\n    this.lastFrameId = frameId\r\n    if (this.iterations && this.iteration > this.iterations) {\r\n      this.stop()\r\n      return\r\n    }\r\n    if (this.resetInterval && this.running) {\r\n      \/\/ fps has changed\r\n      this.resetInterval = false\r\n      clearInterval(this.intervalId)\r\n      this._startInterval()\r\n    }\r\n    var onFrame = this.onFrame[frameId]\r\n    if (onFrame) {\r\n      try {\r\n        onFrame.call(_this, frameId)\r\n      } catch (e) {\r\n        console.error('Error calling onFrame #' + frameId, e)\r\n      }\r\n    }\r\n    if (this.onEachFrame) {\r\n      try {\r\n        _this.onEachFrame.call(_this, frameId)\r\n      } catch (e) {\r\n        console.error('Error calling onEachFrame #' + frameId, e)\r\n      }\r\n    }\r\n    if(didIteration && this.onEachIteration) {\r\n      try {\r\n        _this.onEachIteration.call(_this, _this.iteration)\r\n      } catch (e) {\r\n        console.error('Error calling onEachIteration #' + iteration, e)\r\n      }\r\n    }\r\n    var frame = this.frames[frameId + (this.frameOffset || 0)]\r\n    if (frame && this.lastFrame !== frame) {\r\n      var notification = this._getNotification()\r\n      if (!notification && this.requireNotification) {\r\n        console.error('Unable to find notification id: \"' + this.notificationId + '\" -- stopping animation')\r\n        this.stop()\r\n        return\r\n      } else if (notification) {\r\n        notification._TitleAnimator = this\r\n        notification.setTitle(frame)\r\n      }\r\n      this.lastFrame = frame\r\n    }\r\n    if (didIteration && this.onNextIteration) {\r\n      try {\r\n        _this.onNextIteration.call(_this, _this.iteration)\r\n      } catch (e) {\r\n        console.error('Error calling onNextIteration #' + iteration, e)\r\n      }\r\n      this.onNextIteration = false\r\n    }\r\n  }\r\n})()\r\nconsole.log('Installed TitleAnimator', window.TitleAnimator)"}}]}},{"if":{"condition":"!window.Beats \/* v3.1 *\/","commands":[{"eval":{"script":"\/\/ Install Beats\r\n(function(){\r\n  if (window.Beats) return\r\n  window.Beats = function(opt) {\r\n    opt = opt || {}\r\n    this._volume = opt.volume || 1\r\n    this._volId = 0\r\n    this.patterns = {}\r\n    this.fps = opt.fps || Beats.fps\r\n    this.notificationId = opt.notificationId || Beats.notificationId\r\n    this.frames = opt.frames || Beats.frames\r\n    this.maxVolume = opt.maxVolume || 1\r\n    \/\/ this.minVolume = opt.minVolume || 0\r\n    \/\/ console.log('new beats', this)\r\n  }\r\n  Beats.notificationId = 'beats'\r\n  Beats.fps = 100\r\n  Beats.frames = {\r\n    \/\/ 50 fps\r\n    \/\/ Use this if you set fps to 50\r\n    \/\/ 1:   '\u25af\u25af\u25ae\u25ae\u25ae\u25ae\u25ae\u25af\u25af',\r\n    \/\/ 2:   '\u25af\u25ae\u25ae\u25ae\u25ae\u25ae\u25ae\u25ae\u25af',\r\n    \/\/ 3:   '\u25ae\u25ae\u25ae\u25ae\u25ae\u25ae\u25ae\u25ae\u25ae',\r\n    \/\/ 4:   '\u25ae\u25ae\u25ae\u25ae\u25ae\u25ae\u25ae\u25ae\u25ae',\r\n    \/\/ 5:   '\u25ae\u25ae\u25ae\u25ae\u25ae\u25ae\u25ae\u25ae\u25ae',\r\n    \/\/ 6:   '\u25ae\u25ae\u25ae\u25ae\u25ae\u25ae\u25ae\u25ae\u25ae',\r\n    \/\/ 7:   '\u25af\u25ae\u25ae\u25ae\u25ae\u25ae\u25ae\u25ae\u25af',\r\n    \/\/ 8:   '\u25af\u25ae\u25ae\u25ae\u25ae\u25ae\u25ae\u25ae\u25af',\r\n    \/\/ 9:   '\u25af\u25af\u25ae\u25ae\u25ae\u25ae\u25ae\u25af\u25af',\r\n    \/\/ 10:  '\u25af\u25af\u25ae\u25ae\u25ae\u25ae\u25ae\u25af\u25af',\r\n    \/\/ 11:  '\u25af\u25af\u25af\u25ae\u25ae\u25ae\u25af\u25af\u25af',\r\n    \/\/ 12:  '\u25af\u25af\u25af\u25ae\u25ae\u25ae\u25af\u25af\u25af',\r\n    \/\/ 13:  '\u25af\u25af\u25af\u25af\u25ae\u25af\u25af\u25af\u25af',\r\n    \/\/ 14:  '\u25af\u25af\u25af\u25af\u25ae\u25af\u25af\u25af\u25af',\r\n    \/\/ 15:  '\u25af\u25af\u25af\u25af\u25af\u25af\u25af\u25af\u25af',\r\n    \/\/ 100 fps\r\n    \/\/ Use this if use set fps to 100\r\n    \/\/ (Higher FPS gives more precision in timing, at cost of CPU)\r\n    1:   '\u25af\u25af\u25ae\u25ae\u25ae\u25ae\u25ae\u25af\u25af',\r\n    2:   '\u25af\u25af\u25ae\u25ae\u25ae\u25ae\u25ae\u25af\u25af',\r\n    3:   '\u25af\u25ae\u25ae\u25ae\u25ae\u25ae\u25ae\u25ae\u25af',\r\n    4:   '\u25af\u25ae\u25ae\u25ae\u25ae\u25ae\u25ae\u25ae\u25af',\r\n    5:   '\u25ae\u25ae\u25ae\u25ae\u25ae\u25ae\u25ae\u25ae\u25ae',\r\n    6:   '\u25ae\u25ae\u25ae\u25ae\u25ae\u25ae\u25ae\u25ae\u25ae',\r\n    7:   '\u25ae\u25ae\u25ae\u25ae\u25ae\u25ae\u25ae\u25ae\u25ae',\r\n    8:   '\u25ae\u25ae\u25ae\u25ae\u25ae\u25ae\u25ae\u25ae\u25ae',\r\n    9:   '\u25ae\u25ae\u25ae\u25ae\u25ae\u25ae\u25ae\u25ae\u25ae',\r\n    10:  '\u25ae\u25ae\u25ae\u25ae\u25ae\u25ae\u25ae\u25ae\u25ae',\r\n    11:  '\u25ae\u25ae\u25ae\u25ae\u25ae\u25ae\u25ae\u25ae\u25ae',\r\n    12:  '\u25ae\u25ae\u25ae\u25ae\u25ae\u25ae\u25ae\u25ae\u25ae',\r\n    13:  '\u25af\u25ae\u25ae\u25ae\u25ae\u25ae\u25ae\u25ae\u25af',\r\n    14:  '\u25af\u25ae\u25ae\u25ae\u25ae\u25ae\u25ae\u25ae\u25af',\r\n    15:  '\u25af\u25ae\u25ae\u25ae\u25ae\u25ae\u25ae\u25ae\u25af',\r\n    16:  '\u25af\u25ae\u25ae\u25ae\u25ae\u25ae\u25ae\u25ae\u25af',\r\n    17:  '\u25af\u25af\u25ae\u25ae\u25ae\u25ae\u25ae\u25af\u25af',\r\n    18:  '\u25af\u25af\u25ae\u25ae\u25ae\u25ae\u25ae\u25af\u25af',\r\n    19:  '\u25af\u25af\u25ae\u25ae\u25ae\u25ae\u25ae\u25af\u25af',\r\n    20:  '\u25af\u25af\u25ae\u25ae\u25ae\u25ae\u25ae\u25af\u25af',\r\n    21:  '\u25af\u25af\u25af\u25ae\u25ae\u25ae\u25af\u25af\u25af',\r\n    22:  '\u25af\u25af\u25af\u25ae\u25ae\u25ae\u25af\u25af\u25af',\r\n    23:  '\u25af\u25af\u25af\u25ae\u25ae\u25ae\u25af\u25af\u25af',\r\n    24:  '\u25af\u25af\u25af\u25ae\u25ae\u25ae\u25af\u25af\u25af',\r\n    25:  '\u25af\u25af\u25af\u25af\u25ae\u25af\u25af\u25af\u25af',\r\n    26:  '\u25af\u25af\u25af\u25af\u25ae\u25af\u25af\u25af\u25af',\r\n    27:  '\u25af\u25af\u25af\u25af\u25ae\u25af\u25af\u25af\u25af',\r\n    28:  '\u25af\u25af\u25af\u25af\u25ae\u25af\u25af\u25af\u25af',\r\n    29:  '\u25af\u25af\u25af\u25af\u25af\u25af\u25af\u25af\u25af',\r\n  }\r\n  Beats.prototype.getLast = function() {\r\n    return TitleAnimator.last[this.notificationId]\r\n  }\r\n  Beats.prototype.setVolume = function (volume, beatId) {\r\n    if (beatId === '_') return\r\n    var ov = volume\r\n    volume = parseFloat(volume)\r\n    if (isNaN(volume) || volume < 0 || volume > 1) {\r\n      console.error('Invalid volume: \"' + ov + '\".  Must be a number between 0 and 1')\r\n      return\r\n    }\r\n    if (beatId) {\r\n      var beat = this.beats[beatId]\r\n      if (!beat) {\r\n        console.error('Unable to set volume for invalid beat sample: ' + beatId)\r\n        return\r\n      }\r\n      \/\/ if (beat.volume === volume) return\r\n      beat.samples.forEach(function(s) {\r\n        var aVol = volume * beat.maxVolume\r\n        if (aVol > 1) aVol = 1\r\n        if (aVol < 0) aVol = 0\r\n        s.setVolume(aVol)\r\n      })\r\n      beat.volume = volume\r\n    } else {\r\n      this._volId ++\r\n      this._volume = volume\r\n      Object.keys(this.beats).forEach(function(bId){\r\n        this.setVolume(volume, bId)\r\n      })\r\n    }\r\n  }\r\n  Beats.prototype._fadeTimer = null\r\n  Beats.prototype.fadeTo = function (volume, time, beatId) {\r\n    var _this = this\r\n    clearInterval(this._fadeTimer)\r\n    if (beatId === '_') return\r\n    var ov = volume\r\n    volume = parseFloat(volume)\r\n    if (isNaN(volume) || volume < 0 || volume > 1) {\r\n      console.error('Invalid volume: \"' + ov + '\".  Must be a number between 0 and 1')\r\n      return\r\n    }\r\n    var stepSize = 20 \/\/ ms between steps\r\n    var beats = this.beats\r\n    var steps = time \/ stepSize\r\n    var step = 0\r\n    if (!beatId) {\r\n      this._volume = volume\r\n    }\r\n    var volId = this._volId\r\n    var doVol = Object.keys(beats).reduce(function(a, bId){\r\n      if (beatId && bId !== beatId) return a\r\n      var v = beats[bId].volume || 0\r\n      var diff = volume - v\r\n      a[bId] = {\r\n        inc: diff \/ steps,\r\n        curr: v,\r\n      }\r\n      return a\r\n    }, {})\r\n    var bIds = Object.keys(doVol)\r\n    function stepper() {\r\n      step ++\r\n      bIds.forEach(function(bId) {\r\n        var doer = doVol[bId]\r\n        var v = doer.curr + doer.inc\r\n        if ((doer.inc > 0 && v >= volume) || \r\n          (doer.inc < 0 && v <= volume) || \r\n          step >= steps) {\r\n            v = volume\r\n          }\r\n        if (this._volId !== volId && volume > parseFloat(this._volume)) {\r\n          volume = this._volume\r\n        }\r\n        _this.setVolume(v, bId)\r\n        doer.curr = v\r\n      })\r\n      if (step >= steps) {\r\n        clearInterval(_this._fadeTimer)\r\n      }\r\n    }\r\n    stepper()\r\n    if (step < steps) this._fadeTimer = setInterval(stepper, stepSize)\r\n  }\r\n  Beats.prototype.pause = function (name) {\r\n    var last = this.getLast()\r\n    if (name) {\r\n      var b = this.get(b)\r\n      var p = this.getCurrentPattern()\r\n      if (!b || b.pattern !== p) return\r\n    }\r\n    last && last.running && last.stop()\r\n  }\r\n  Beats.prototype.isPaused = function () {\r\n    var last = this.getLast()\r\n    return !!(last && !last.running && (last.__patternT || last.__pattern))\r\n  }\r\n  Beats.prototype.play = function (name, opts) {\r\n    if (name) {\r\n      var b = this.get(name)\r\n      if (b) {\r\n        b(opts)\r\n      } else {\r\n        console.error('No beat with name:', name)\r\n      }\r\n      return\r\n    }\r\n    var last = this.getLast()\r\n    last && !last.running && last.run()\r\n  }\r\n  Beats.prototype.stop = function (name) {\r\n    if (name) {\r\n      var b = this.get(b)\r\n      var p = this.getCurrentPattern()\r\n      if (!b || b.pattern !== p) return\r\n    }\r\n    var lastFrame = null\r\n    var frames = this.frames\r\n    var notificationId = this.notificationId\r\n    if (this.isRunning() || this.isPaused()) {\r\n      var current = this.getLast()\r\n      lastFrame = current.lastFrame\r\n      current.stop()\r\n      frames = current.frames\r\n      notificationId = current.notificationId\r\n    }\r\n    var frameKeys = Object.keys(frames)\r\n    var lastFrameId = parseInt(frameKeys[frameKeys.length-1], 10)\r\n    var lastUsedFrameId = parseInt(frameKeys[frameKeys.length-2], 10)\r\n    for (var i = lastFrameId; i >= 1; i--) {\r\n      if (!lastFrame) break\r\n      if (lastFrame === frames[i]) {\r\n        lastUsedFrameId = i\r\n        break\r\n      }\r\n    }\r\n    var endFrames = {}\r\n    var l = 1\r\n    for (var i = lastUsedFrameId; i <= lastFrameId; i++) {\r\n      endFrames[l] = frames[i]\r\n      l++\r\n    }\r\n    new TitleAnimator({\r\n      notificationId: notificationId,\r\n      frameCount: l,\r\n      fps: this.fps,\r\n      frames: endFrames,\r\n      iterations: 1,\r\n    }).run()\r\n  }\r\n  Beats.prototype.isRunning = function (name) {\r\n    if (name) {\r\n      var b = this.get(b)\r\n      var p = this.getCurrentPattern()\r\n      if (!b || b.pattern !== p) return false\r\n    }\r\n    var last = this.getLast()\r\n    return last && last.running && (last.__patternT || last.__pattern)\r\n  }\r\n  Beats.prototype.getCurrentPattern = function (name) {\r\n    if (name) {\r\n      var b = this.get(b)\r\n      var p = this.getCurrentPattern()\r\n      if (!b || b.pattern !== p) return false\r\n    }\r\n    var last = this.getLast()\r\n    return last && (last.__patternT || last.__pattern)\r\n  }\r\n  Beats.prototype.getCurrentTimeScale = function () {\r\n    var last = this.getLast()\r\n    return last ? \r\n    Math.round((last.__timeScaleT || last.__timeScale)*1000)\/1000 : 1\r\n  }\r\n  Beats.prototype.setRunningTimeScale = function (timeScale) {\r\n    var last = this.getLast()\r\n    if (last && last.running) {\r\n      last.__timeScale = timeScale \r\n    }\r\n  }\r\n  Beats.prototype.adjustRunningTimeScale = function (timeScaleChange) {\r\n    var last = this.getLast()\r\n    if (last && last.running) {\r\n      last.__timeScale = Math.max(last.__timeScale + timeScaleChange, 0.05)\r\n    }\r\n  }\r\n  Beats.builderOpts = {\r\n    notificationId: Beats.notificationId,\r\n    sustain: {\r\n      '+': {\r\n      },\r\n      '-': {\r\n      },\r\n      '=': {\r\n      },\r\n      '~': {\r\n      },\r\n      '!': {\r\n      },\r\n      '^': {\r\n      },\r\n    },\r\n    beats: {\r\n      _: {\r\n        id: '_',\r\n        samples: [],\r\n      },\r\n      '^': {\r\n        id: '^',\r\n        samples: [],\r\n        event: true,\r\n      },\r\n    },\r\n    times: {\r\n      D: {\r\n        scale: 2,\r\n      },\r\n      F: {\r\n        scale: 1,\r\n      },\r\n      Q: {\r\n        scale: 0.25,\r\n      },\r\n      H: {\r\n        scale: 0.5,\r\n      },\r\n    },\r\n    fps: Beats.fps,\r\n    frameCount: Beats.fps,\r\n    frame: Beats.frames,\r\n    pattern: '+AF',\r\n  }\r\n\r\n  Beats.prototype.setMaxVolume = function (vol, beatId) {\r\n    if (beatId) {\r\n      var beat = this.beats[beatId]\r\n      if (!beat) {\r\n        console.error('Unable to setMaxVolume.  Unknown beatId: ', beatId)\r\n        return\r\n      }\r\n      beat.maxVolume = vol\r\n      this.setVolume(beat.volume, beatId)\r\n      return\r\n    }\r\n    this.maxVolume = vol\r\n    var _this = this\r\n    Object.keys(this.beats).forEach(function(k) {\r\n      _this.setMaxVolume(vol, k)\r\n    })\r\n  }\r\n\r\n  \/**\r\n   * Load beat sample\r\n   *\/\r\n  Beats.prototype._loadSample = function (prefix, letter, beats) {\r\n    var _this = this\r\n    var sample1 = Sound.get(prefix + 'beat' + letter + '-1')\r\n    var sample2 = Sound.get(prefix + 'beat' + letter + '-2')\r\n    if (sample1 && sample2) {\r\n      var samples = [sample1, sample2]\r\n      samples.forEach(function(s){\r\n        s.stop()\r\n        s.seek(10\/1000)\r\n        s.play()\r\n        s.stop()\r\n        s.seek(0)\r\n        s.setVolume(_this._volume)\r\n      })\r\n      beats[letter] = {\r\n        id: letter,\r\n        samples: samples,\r\n        lastUsed: 1,\r\n        \/\/ minVolume: this.minVolume,\r\n        maxVolume: this.maxVolume,\r\n        volume: this._volume,\r\n      }\r\n    }\r\n  }\r\n\r\n  \/**\r\n   * Load beats samples\r\n   *\/\r\n  Beats.prototype.loadSamples = function (prefix) {\r\n    prefix = prefix || ''\r\n    var beats = {}\r\n    Object.keys(Beats.builderOpts.beats).forEach(function(k){\r\n      beats[k] = Beats.builderOpts.beats[k]\r\n    })\r\n    for (var i = 65; i <= 90; i++) {\r\n      var letter = String.fromCharCode(i)\r\n      this._loadSample(prefix, letter, beats)\r\n    }\r\n    for (var i = 97; i <= 122; i++) {\r\n      var letter = String.fromCharCode(i)\r\n      this._loadSample(prefix, letter, beats)\r\n    }\r\n    this.beats = beats\r\n  }\r\n\r\n  Beats.prototype.set = function (name, opts) {\r\n    var _this = this\r\n    if (typeof opts === 'string') {\r\n      opts = {pattern: opts}\r\n    }\r\n    opts = opts || {}\r\n    var mergedOpts\r\n    Object.keys(Beats.builderOpts).forEach(function(k){\r\n      mergedOpts = mergedOpts || {}\r\n      mergedOpts[k] = opts[k] !== undefined ? opts[k] : Beats.builderOpts[k]\r\n    })\r\n    var iterOpts = []\r\n    var frames = opts.frames || Beats.frames\r\n    var fullFrameCount = mergedOpts.frameCount\r\n    var minFrameCount = fullFrameCount\r\n    var maxFrameCount = 0\r\n    function onEachIteration (i) {\r\n      var iterCount = this.__iterCount || 1\r\n      var didIteration = false\r\n      if (iterCount > iterOpts.length) {\r\n        this.__patternIteration ++\r\n        didIteration = true\r\n        iterCount = 1\r\n      }\r\n      var iterOpt = iterOpts[iterCount-1]\r\n      this.setOptions(iterOpt)\r\n      this.frameCount = Math.max(Math.round(iterOpt.frameCount * this.__timeScale), 2)\r\n\r\n      if (i === true) {\r\n        \/\/ console.log('Init on each', this._pattern, Date.now())\r\n        return \/\/ only initializing\r\n      }\r\n\r\n      var samples = []\r\n      var doCaretEvent = false\r\n      var doNextNow = false\r\n      var _taThis = this\r\n      iterOpt.__beats && iterOpt.__beats.forEach(function(b) {\r\n        if (b.samples.length) {\r\n          var use = b.lastUsed ? 0 : 1\r\n          var sample = b.samples[use]\r\n          var doStop = true\r\n          var fadeTo = 0\r\n          switch(_taThis.__sustainCode) {\r\n            case '^':\r\n              \/\/ Fade in\r\n              fadeTo = 1\r\n            case '.':\r\n              \/\/ Fade out\r\n              doStop = false\r\n              doNextNow = true\r\n              var ftime = ((1 \/ _taThis.fps) * _taThis.frameCount) * 1000\r\n              _this.fadeTo(fadeTo, ftime, b.id)\r\n              break\r\n            case '-':\r\n              b.samples[b.lastUsed].stop()\r\n              break\r\n            case '~':\r\n              _taThis.__lastSamples && _taThis.__lastSamples.forEach(function(s){\r\n                s.stop()\r\n              })\r\n              break            \r\n          }\r\n          if (doStop) sample.stop()\r\n          sample.play()\r\n          \/\/ console.log('Playing', b.id, use, Date.now())\r\n          samples.push(sample)\r\n          b.lastUsed = use\r\n        }\r\n        doCaretEvent = doCaretEvent || b.event\r\n      })\r\n      this.__lastSamples = samples\r\n      if (!samples.length) {\r\n        \/\/ rest\r\n        this.frameOffset = this.lastIterationFrameId || 0\r\n      }\r\n\r\n      if (doCaretEvent && this.__onCaret) {\r\n        try {\r\n          this.__onCaret.call(this, this.__patternIteration, iterCount, iterOpt.__beatId)\r\n        } catch (e) {\r\n          console.error('Error calling onCaret: ' + e.toString())\r\n        }\r\n      }\r\n\r\n      if (didIteration) {\r\n        if (this.__patternIterations && this.__patternIteration >= this.__patternIterations) {\r\n          this.stop() \/\/ Pause\r\n          if (this.__onPatternEnd) {\r\n            try {\r\n              this.__onPatternEnd.call(this, this.__patternIteration, iterCount, iterOpt.__beatId)\r\n            } catch (e) {\r\n              console.error('Error calling onPatternEnd: ' + e.toString())\r\n            }\r\n          }\r\n          if (!this.isRunning()) {\r\n            this.stop() \/\/ If we havn't been un-paused, stop.\r\n          }\r\n        } else {\r\n          if (this.__onPatternLoop) {\r\n            try {\r\n              this.__onPatternLoop.call(this, this.__patternIteration, iterCount, iterOpt.__beatId)\r\n            } catch (e) {\r\n              console.error('Error calling __onPatternLoop: ' + e.toString())\r\n            }\r\n          }\r\n        }\r\n      }\r\n      this.__iterCount = iterCount + 1\r\n      if (doNextNow && iterOpts.length > 1) {\r\n        onEachIteration.call(this, i)\r\n      }\r\n      \/\/ console.log('Did Iter', this.__pattern, this.__timeScale, iterCount, this, iterOpt)\r\n    }\r\n    var patternArray = mergedOpts.pattern.match(\/.[a-zA-Z_\\^]+(\\[[^\\]]*?\\]){0,1}[DFQH]\/g);\r\n    if (!patternArray) {\r\n      error = \"Invalid beat pattern (1): \" + mergedOpts.pattern\r\n      console.error(error)\r\n      throw error\r\n    }\r\n    patternArray.forEach(function(p) {\r\n      pa = p.match(\/^([+\\-=~^!])([a-zA-Z_\\^]+)(\\[[^\\]]+\\]){0,1}([DFHQ])$\/);\r\n      if (!pa) {\r\n        error = \"Invalid beat pattern (2): \" + p\r\n        console.error(error)\r\n        throw error\r\n      }\r\n      var sustain = mergedOpts.sustain[pa[1]]\r\n      if (!sustain) {\r\n        var error = \"Invalid sustain code '\"+pa[1]+\"' in '\" + p + \"'\"\r\n        console.error(error)\r\n        throw error\r\n      }\r\n      var beatCodes = pa[2].split('')\r\n      var beats = beatCodes.reduce(function(a, c){\r\n        var b = _this.beats[c]\r\n        if (!b) {\r\n          var error = \"Invalid beat code '\"+b+\"' in '\" + p + \"'\"\r\n          console.error(error, mergedOpts)\r\n          throw error\r\n        }\r\n        a.push(b)\r\n        return a\r\n      }, [])\r\n      var time = mergedOpts.times[pa[4]]\r\n      if (!time) {\r\n        var error = \"Invalid time code '\"+pa[4]+\"' in '\" + p + \"'\"\r\n        console.error(error)\r\n        throw error\r\n      }\r\n      var fc = Math.round(fullFrameCount * time.scale)\r\n      if (fc < minFrameCount) minFrameCount = fc\r\n      if (fc > maxFrameCount) maxFrameCount = fc\r\n      iterOpts.push({\r\n        iterations: null, \r\n        frameCount: fc,\r\n        __sustainCode: pa[1],\r\n        __beatCodes: beatCodes,\r\n        __beatId: pa[3] && pa[3].replace(\/^\\[+|\\]+$\/g, '').trim(),\r\n        __timeCode: pa[4],\r\n        frames: beats[0].frames || frames,\r\n        __beats: beats,\r\n        fps: mergedOpts.fps,\r\n        onEachIteration: onEachIteration,\r\n      })\r\n    })\r\n    \/\/ mergedOpts.minFrameCount = minFrameCount\r\n    \/\/ mergedOpts.maxFrameCount = maxFrameCount\r\n    var firstIterOpt = iterOpts[0]\r\n    function builder(options) {\r\n      if (typeof options === 'number') {\r\n        options = {\r\n          timeScale: options\r\n        }\r\n      }\r\n      options = options || {}\r\n      var dOpts = {\r\n        reset: true,\r\n        requireNotification: false, \/\/ Allow to run even if notification missing\r\n        notificationId: mergedOpts.notificationId,\r\n        frameCount: firstIterOpt.frameCount,\r\n        fps: firstIterOpt.fps,\r\n        frames: firstIterOpt.frames,\r\n        onEachIteration: onEachIteration,\r\n      }\r\n      var opts = Object.keys(dOpts).reduce(function(a, k){\r\n        a[k] = options[k] === undefined ? dOpts[k] : options [k]\r\n        return a\r\n      }, {})\r\n      var current = _this.getLast()\r\n      var animation = current && current.running ? current : new TitleAnimator(opts)\r\n      var patternChange = animation.__pattern !== mergedOpts.pattern\r\n      timeScale = Math.max(options.timeScale || animation.__timeScaleT || animation.__timeScale || mergedOpts.timeScale || 1, 0.01)\r\n      animation.__patternT = mergedOpts.pattern\r\n      animation.__timeScaleT = timeScale\r\n      function startAnimation() {\r\n        animation.__timeScale = timeScale\r\n        animation.setOptions(opts)\r\n        if (patternChange) {\r\n          animation.__iterCount = 0\r\n          animation.__patternIteration = 0\r\n          \/\/ animation.lastFrameId = maxFrameCount\r\n          animation.__pattern = mergedOpts.pattern\r\n        } else {\r\n        }\r\n        animation.onEachIteration && animation.onEachIteration(true)\r\n        animation.__timeScaleT = null\r\n        animation.__patternT = null\r\n        animation.__onCaret = options.onCaret\r\n        animation.__onPatternLoop = options.onPatternLoop\r\n        animation.__onPatternEnd = options.onPatternEnd\r\n        animation.__patternIterations = options.patternIterations\r\n        animation.run()\r\n      }\r\n      if (patternChange && animation.running) {\r\n        \/\/ transition to new animation\r\n        animation.onNextIteration = function() {\r\n          startAnimation()\r\n          return false\r\n        }\r\n      } else {\r\n        startAnimation()\r\n      }\r\n    }\r\n    builder.pattern = mergedOpts.pattern\r\n    this.patterns[name] = builder\r\n    return builder\r\n  }\r\n\r\n  Beats.prototype.get = function(name) {\r\n    return this.patterns[name]\r\n  }\r\n})()"}}]}},{"if":{"condition":"!window.beats","commands":[{"audio.play":{"locator":"file:congo-a.mp3","volume":0.01,"background":true,"id":"beatA-1"}},{"audio.play":{"locator":"file:congo-a.mp3","volume":0.01,"background":true,"id":"beatA-2"}},{"eval":{"script":"\r\n\/\/ Create my beats object\r\nvar beats = new Beats()"}},{"eval":{"script":"\r\n\/\/ Load samples\r\nbeats.loadSamples('')"}},{"eval":{"script":"\r\n\/\/ Define my beat patterns\r\nbeats.set('constant',\r\n  {\r\n    pattern: '+AF',\r\n  })\r\nbeats.set('pattern1',\r\n  {\r\n    pattern: '+AF+AF+AH+AH+AH+AF+AF+AH+AH+AH+_F',\r\n  })\r\nbeats.set('pattern2',\r\n  {\r\n    pattern: '+AAF+AH+AH+AF+AH+AF+AF+_F+_F+AAF+AH+AH+AF+AH+AF+_F+_^[refresh]F+_F',\r\n  })\r\n"}}]}},{"image":{"locator":"gallery:5b4619eb-d2f0-48d3-a78d-43d9b4880c63\/1286833"}},{"say":{"label":"<p>This is simply a demo on how to use Fapnip&#39;s<\/p><p>setTimeout and setInterval polyfills to generate arbitrary metronome<\/p><p>patterns using a single beat sample.<\/p>","mode":"instant"}},{"choice":{"options":[{"label":"Let me play with it!","commands":[{"goto":{"target":"demo"}}]},{"label":"Create a custom beat","commands":[{"goto":{"target":"custom"}}]}]}}],"demo":[{"if":{"condition":"!window.hasVisulization","commands":[{"notification.create":{"id":"beats"}},{"eval":{"script":"hasVisulization = true\r\n\/\/ Default to mix\r\n\/\/ Start in a timeout to try to avoid issue with setInterval used\r\n\/\/  by TitleAnimator going crazy on first use sometimes\r\n\r\nif (!beats.getLast()) {\r\n  setTimeout(function(){beats.play('pattern1', 0.5)}, 0)\r\n  beats.play('pattern1', 0.5)\r\n}"}}]}},{"image":{"locator":"gallery:5b4619eb-d2f0-48d3-a78d-43d9b4880c63\/*"}},{"say":{"label":"<p><strong>Stroke to the beat<\/strong><\/p>","mode":"instant"}},{"say":{"label":"<p>(Playing: <eval>beats.getCurrentPattern()<\/eval> @ <eval>beats.getCurrentTimeScale()<\/eval> )<\/p>","mode":"instant"}},{"if":{"condition":"!window.hidePageTimer","commands":[{"timer":{"duration":"10s","isAsync":true,"commands":[{"goto":{"target":"demo"}}]}}]}},{"choice":{"options":[{"label":"Slow","commands":[{"eval":{"script":"beats.play('constant', 1) \/\/ 1 bps\r\nhidePageTimer = false \/\/ We'll let the page timer refresh the page"}}]},{"label":"Fast","commands":[{"eval":{"script":"beats.play('constant', 0.33) \/\/ 3 bps\r\nhidePageTimer = false \/\/ We'll let the page timer refresh the page"}}]},{"label":"Mix 1","commands":[{"eval":{"script":"beats.play('pattern1', 0.5)\r\nhidePageTimer = false \/\/ We'll let the page timer refresh the page"}}]},{"label":"Mix 2","commands":[{"eval":{"script":"if (!beats.get('patternMixUp')) {\r\n  \/\/ Lets define another beat that we'll play after 3 of pattern2\r\n  beats.set('patternMixUp',\r\n    '+_F+AH+AH+AF+AF+AF+AH+AH+AH+AF+_^' +\r\n    '+_F+AH+AH+AF+AF+AH+AF+_F+_^[refresh]F'\r\n    )\r\n  \/\/ And define a function that'll switched back to pattern2\r\n  \/\/ after our other patern plays twice.\r\n  doMixPageRefresh = function(runCount, beatIndex, beatId) {\r\n    if (beatId === 'refresh') {\r\n      console.log('doMixPageRefresh', runCount, beatIndex, beatId)\r\n      if (runCount >= 2) {\r\n        beats.get('patternMixUp')({\r\n          onCaret: function(runCount, beatIndex, beatId) {\r\n            if (beatId === 'refresh') {\r\n              console.log('doMixPageRefresh2', runCount, beatIndex, beatId)\r\n              if (runCount >= 1) {\r\n                beats.play('pattern2', {\r\n                  onCaret: doMixPageRefresh\r\n                })\r\n              }\r\n              if (pages.getCurrentPageId() === 'demo') pages.goto('demo')\r\n            }\r\n          },\r\n        })\r\n      }\r\n      if (pages.getCurrentPageId() === 'demo') pages.goto('demo')\r\n    }\r\n  }\r\n}\r\nif (beats.getCurrentPattern('patternMixUp') || \r\n beats.getCurrentPattern('pattern2')) {\r\n   \/\/ If we're already playing pattern2 or our other pattern\r\n   \/\/ just reset its timescaleto 0.5 instead of playing it again from the top\r\n   beats.setRunningTimeScale(0.5)\r\n} else {\r\n  \/\/ Start playing pattern2\r\n  beats.play('pattern2', {\r\n    \/\/ with these options\r\n    timeScale: 0.5,\r\n    \/\/ If we're on the demo page, do this when the loop ends\r\n    \/\/ onPatternLoop: doPageRefresh,\r\n    \/\/ If we're on the demo page, do this when we encounter the caret (^) symbol\r\n    onCaret: doMixPageRefresh,\r\n    })\r\n}\r\nhidePageTimer = true \/\/ We'll let the onCaret callback refresh the page"}}]},{"label":"Pain","commands":[{"eval":{"script":"beats.play('constant', 0.2)\r\nhidePageTimer = false \/\/ We'll let the page timer refresh the page"}}]},{"label":"Custom","commands":[{"eval":{"script":"beats.play('custom', 0.5)\r\nhidePageTimer = false \/\/ We'll let the page timer refresh the page"}}],"visible":"$beats.get('custom')"},{"label":"\u21e7","commands":[{"eval":{"script":"beats.adjustRunningTimeScale(-0.025)"}}]},{"label":"\u21e9","commands":[{"eval":{"script":"beats.adjustRunningTimeScale(0.025)"}}]},{"label":"\u25b6\ufe0f","commands":[{"eval":{"script":"beats.play()"}}],"visible":"$beats.isPaused()"},{"label":"\u23f8\ufe0f","commands":[{"eval":{"script":"beats.pause()"}}],"visible":"$beats.isRunning()"},{"label":"\u23f9\ufe0f","commands":[{"eval":{"script":"beats.stop()"}}],"visible":"$beats.isRunning() || beats.isPaused()"},{"label":"\ud83d\udd07","commands":[{"eval":{"script":"beats.fadeTo(0, 1500)"}}],"visible":"$beats._volume"},{"label":"\ud83d\udd0a","commands":[{"eval":{"script":"beats.fadeTo(1, 1500)"}}],"visible":"$!beats._volume"},{"label":"Back","commands":[{"goto":{"target":"start"}}]}]}},{"goto":{"target":"demo"}}],"custom":[{"notification.create":{"buttonCommands":[{"eval":{"script":"hasVisulization = false"}},{"if":{"condition":"beats.isRunning()","commands":[{"notification.create":{"id":"pulse-demo"}}]}},{"goto":{"target":"start"}}],"buttonLabel":"Back","id":"beats"}},{"say":{"label":"<p>Enter a custom beat pattern below.  Example: <strong>+AF+AH<\/strong><\/p><p>1st = Sustain character (not yet implemented.  Just use <strong>+<\/strong>)<\/p><p>2nd = Beat sample (A-Z - only <strong>A<\/strong> works currently) or rest (<strong>_<\/strong>)<\/p><p>3rd = Length (<strong>F<\/strong> = full, <strong>H<\/strong> = half, <strong>Q<\/strong> = quarter)<\/p>","mode":"instant"}},{"prompt":{"variable":"customPattern"}},{"eval":{"script":"customPattern = customPattern.trim()"}},{"if":{"condition":"customPattern","commands":[{"eval":{"script":"var error = false\r\ntry {\r\n  beats.set('custom', customPattern)\r\n} catch (e) {\r\n  console.error(e)\r\n  error = e.toString()\r\n}"}},{"if":{"condition":"error","commands":[{"say":{"label":"<p>Error creating custom pattern: <\/p><p><eval>error<\/eval><\/p>","mode":"autoplay","allowSkip":true}}],"elseCommands":[{"say":{"label":"<p>Okay, custom beat pattern set to: <eval>customPattern<\/eval><\/p>","mode":"autoplay","allowSkip":true}},{"say":{"label":"<p>Would you like to play that now?<\/p>","mode":"instant"}},{"choice":{"options":[{"label":"Yes!","commands":[{"eval":{"script":"beats.play('custom', 0.5)"}}]},{"label":"No, I'll try it later.","commands":[]}]}}]}}]}},{"notification.remove":{"id":"beats"}},{"if":{"condition":"beats.isRunning()","commands":[{"notification.create":{"id":"beats"}}]}},{"goto":{"target":"start"}}]},"files":{"1-minute-of-silence.mp3":{"id":1327668,"hash":"1092af7de1d0a7b87c79797d0adb47c8bdf1f91a","size":96246,"type":"audio\/mpeg"},"congo-a.mp3":{"id":1332028,"hash":"5915e22586cfe3ed5575064ad428672ef633d230","size":8881,"type":"audio\/mpeg"}},"modules":{"audio":{},"notification":{}},"init":"","galleries":{"5b4619eb-d2f0-48d3-a78d-43d9b4880c63":{"name":"Lily C - Rasei","images":[{"id":1286831,"hash":"d91025bdae94c50a493266a257ee1bcd3d51702d","size":2182562,"width":3840,"height":5760},{"id":1286832,"hash":"1df8e4a603b554735438d5cf91dae46a32ac39f2","size":2277507,"width":3840,"height":5760},{"id":1286833,"hash":"02bab3a5c20c72b8dc5bb0d77f4bf6195c47625e","size":2088401,"width":3840,"height":5760},{"id":1286834,"hash":"9787cf64cc61d5d8512cd33c6cddc481d657aed4","size":2062088,"width":3840,"height":5760},{"id":1286835,"hash":"64012f4e9c239166fbdd4d4229f7f895fc6df2bf","size":2152833,"width":5760,"height":3840},{"id":1286836,"hash":"6dcb2db78d0c7a88e7220f83e626deb5e94aa4cd","size":1840790,"width":5760,"height":3840},{"id":1286837,"hash":"80ac70e69436c8f37a960c4653f4ce9aca2e4b09","size":2177630,"width":3840,"height":5760},{"id":1286838,"hash":"4c0d2b00708f174f08486170a6a562d1bcee508a","size":2171253,"width":3840,"height":5760},{"id":1286839,"hash":"5785e07d66d0aca1121c444a00ca01adae5e6514","size":2350557,"width":3840,"height":5760},{"id":1286840,"hash":"7b8ac4c10410e0102cc8f1be9ca31bd4a27eef87","size":2134477,"width":3840,"height":5760},{"id":1286841,"hash":"ec2689c4a23ea5d1d53f8dfda2092a31a61628c3","size":2094719,"width":3840,"height":5760},{"id":1286842,"hash":"345a3867fff35515030bdf45fc9fe8e7949e2f5b","size":2065398,"width":3840,"height":5760},{"id":1286843,"hash":"b3b5150fbdd331fddd08e421b0d07bebef31cafb","size":2326440,"width":3840,"height":5760},{"id":1286844,"hash":"b7a41942327de23143ab38e673be2e386247af06","size":2074342,"width":3840,"height":5760},{"id":1286845,"hash":"72a36588fe9ebb4d4315f7d2fead97f079d90141","size":2305204,"width":3840,"height":5760},{"id":1286846,"hash":"060365cfb1cb0fa4efe2d9de1dd416d8fe50f106","size":2162954,"width":3840,"height":5760},{"id":1286847,"hash":"e6022d87ee1573ceaa057e05c71c0dfaaac175dd","size":2350825,"width":3840,"height":5760},{"id":1286848,"hash":"e2b0a1c7697e63724a29700ab366e3c58e99f805","size":2407135,"width":3840,"height":5760},{"id":1286849,"hash":"f12a0ab24004353487379fc3c40f45b33904aede","size":2413719,"width":3840,"height":5760},{"id":1286850,"hash":"78fec259f7fbf3a2b91390b17fce0ff38cee4ae2","size":1771672,"width":5760,"height":3840},{"id":1286851,"hash":"daf0f8bcbff2421a9ac37f113d6a3f5b985ea16f","size":2008283,"width":3840,"height":5760},{"id":1286852,"hash":"5216fc3c52bc53c69e7fe649a0ac848384daaa7f","size":2106677,"width":5760,"height":3840},{"id":1286853,"hash":"a713e485102ab7c2ffe449f2e37d66f856c462b0","size":2274213,"width":5760,"height":3840},{"id":1286854,"hash":"316baeef7012837b6aa1123a6d530488c788414f","size":2462733,"width":3840,"height":5760},{"id":1286855,"hash":"1685984e85104611f82610ee7f84011b25b72fbc","size":2316019,"width":3840,"height":5760},{"id":1286856,"hash":"7fc48d56c3dbe15a35dbd139c57cc2d5c008c02d","size":2354146,"width":3840,"height":5760},{"id":1286857,"hash":"a8592bb88ead73fdfdf92d1d413ad49f225d9ff4","size":1975709,"width":3840,"height":5760},{"id":1286858,"hash":"587a7e93ee488fa57b35f8aca9e46bf9863b456f","size":1994799,"width":3840,"height":5760},{"id":1286859,"hash":"d2aac9a3b6ffcbb0d629ea526b86ed4b6e825b0b","size":2263902,"width":3840,"height":5760},{"id":1286860,"hash":"16b802e2e86421544ebc1a5e9b8c0271c38a663e","size":2175354,"width":3840,"height":5760},{"id":1286861,"hash":"ef1788689b44565b36987ecd80fdfe2e0d946611","size":2211258,"width":3840,"height":5760},{"id":1286862,"hash":"85211c7751e2f5d9d4f2706022966548bb58d629","size":2076884,"width":3840,"height":5760},{"id":1286863,"hash":"7c723acc64b11a5e911dd5912fba80598a61d583","size":2235717,"width":3840,"height":5760},{"id":1286864,"hash":"0d79abe3294ed5f7453bd2ed94d342c3c6a2589e","size":1931081,"width":3840,"height":5760},{"id":1286865,"hash":"f2df8d61160356a16936ff6c63bc54842880aa0b","size":1863572,"width":5760,"height":3840},{"id":1286866,"hash":"9acc95bc997966a8c8db2cf907c02b7c535e4647","size":2186156,"width":3840,"height":5760},{"id":1286867,"hash":"5eadc107c409e6413f72040a7e894a7a5cf86109","size":2221935,"width":3840,"height":5760},{"id":1286868,"hash":"44168058345a921201bf544fa7e104f26f474d57","size":2628457,"width":3840,"height":5760},{"id":1286869,"hash":"b81186c2a8a0dc6fc7e981476e6789852253c945","size":2450883,"width":3840,"height":5760},{"id":1286870,"hash":"d3916a604a46a91b1d38fd0dcfc6a2619017d237","size":2166260,"width":3840,"height":5760},{"id":1286871,"hash":"aca115125636620aa74aca4a7bc3710c5d879dc1","size":1886829,"width":3840,"height":5760},{"id":1286872,"hash":"bed0bdd230d4d937123489d260d95a8e50dc896f","size":2130390,"width":3840,"height":5760},{"id":1286873,"hash":"df3ddd741d213a22e21322f7ebdb069b2494d278","size":1991179,"width":3840,"height":5760},{"id":1286874,"hash":"67348ecc3a2880622a3741fa969f1ed59d1de0e2","size":2198476,"width":5760,"height":3840},{"id":1286875,"hash":"0c4ed7d49f8813a6f042a17d05ec7f6912cbe65f","size":1958579,"width":5760,"height":3840},{"id":1286876,"hash":"847705b7b5f0ade2668cbbb0d7cf7f7cf1141f8e","size":2080153,"width":3840,"height":5760},{"id":1286877,"hash":"050f6eb88a1b46fe9ac796dfbf1e40d96bb59f5a","size":1839723,"width":5760,"height":3840},{"id":1286878,"hash":"19bf47f04edebbb88f26b25f12c2765ebd735e2a","size":2321236,"width":3840,"height":5760},{"id":1286879,"hash":"5b4d7eb9e0f1be181eac7d3c5967d068b3bac22d","size":2043266,"width":3840,"height":5760},{"id":1286880,"hash":"c12f86d5e9458507a5f9768d91ad4883a64581fb","size":2260704,"width":3840,"height":5760},{"id":1286881,"hash":"7e256720cf01ee92eb1986de9b6207f1b20409b8","size":2487752,"width":3840,"height":5760},{"id":1286882,"hash":"2df3ff1747ca43a5c666ae7bb8bcf3c466a1fa06","size":2114621,"width":3840,"height":5760},{"id":1286883,"hash":"6a5a8ba424f4490b714243faecdf478a8ed1dfda","size":1973408,"width":3840,"height":5760},{"id":1286884,"hash":"64d40415c12dd8ed0fc2f869abd022b1cbe7298e","size":1861217,"width":3840,"height":5760},{"id":1286885,"hash":"adf0d32ecf34eefec43f4c9cfc8f0d287d23a9f1","size":2287845,"width":3840,"height":5760},{"id":1286886,"hash":"ca576856b7810d48c64b5ae70b1387ef580fc636","size":1939385,"width":5760,"height":3840},{"id":1286887,"hash":"fcf1859d5fc6bb9c6b2684be3e5f050cb38f0b08","size":2034602,"width":3840,"height":5760},{"id":1286888,"hash":"997e30ecad3ffc7ad5ad90438e5c1f82affd28d7","size":2103521,"width":3840,"height":5760},{"id":1286889,"hash":"2f257992bd0fa4ae3be1b7993109036002784d79","size":1984875,"width":3840,"height":5760},{"id":1286890,"hash":"bb2fda72addc743a842f6565b473c41abaee5893","size":1915275,"width":5760,"height":3840},{"id":1286891,"hash":"91c476c6b4a7915dd3b446250db6d0b33a7a8d79","size":1957720,"width":3840,"height":5760},{"id":1286892,"hash":"417cfcfd7d099427a3641bc0e54a3343a2151a1f","size":2029328,"width":3840,"height":5760},{"id":1286893,"hash":"bc92493581a60bdb4bea637bb2397d9a0486e7a5","size":2057252,"width":3840,"height":5760},{"id":1286894,"hash":"2fe18a549dd1cb27c6dc70e1ecdd82c06b453472","size":2026690,"width":5760,"height":3840},{"id":1286895,"hash":"5fdcec25bd27cb61b8763769783af96c6d18f481","size":1876158,"width":3840,"height":5760},{"id":1286896,"hash":"473cc6ad6b5a3e8218f415ad9848b82425bbd66d","size":1993114,"width":3840,"height":5760},{"id":1286897,"hash":"1acaa010bad085fcad6c717ced3fb9ed13df8649","size":1845924,"width":3840,"height":5760},{"id":1286898,"hash":"43a810c80de56b5e16da74a8d6bcfcab7ca6cadd","size":2022979,"width":5760,"height":3840},{"id":1286899,"hash":"1a6b7bfdd22b3726159d6e2ef93ce6b481a65a0c","size":1774047,"width":5760,"height":3840},{"id":1286900,"hash":"36008c432991d6e5978d4a05bc8d59af87523b6a","size":1886096,"width":3840,"height":5760},{"id":1286901,"hash":"15e8acc31bc5baa8179e4faf89e677119884b285","size":1911713,"width":3840,"height":5760},{"id":1286902,"hash":"7ec3057bad1a11a8e13a788753ccf971522e99d3","size":2103724,"width":3840,"height":5760},{"id":1286903,"hash":"b5b395a936a41bd858bb07073c9b4f89477a0b91","size":2048416,"width":5760,"height":3840},{"id":1286904,"hash":"8c902c3d66df86f2f8aeaa565e27bd1779ff8217","size":1722260,"width":5760,"height":3840},{"id":1286905,"hash":"98d8b391d9b72d6a3dda17678909b44603e02a15","size":2335157,"width":3840,"height":5760},{"id":1286906,"hash":"7a80eb0ddb06f17b022272052a4ea774aa6dc280","size":1842584,"width":3840,"height":5760},{"id":1286907,"hash":"249bb755f8d6f185ad074442f53b03e44d7c9dcf","size":2101381,"width":3840,"height":5760},{"id":1286908,"hash":"6bb29bfbae8f3297ea30919fbf73e1789d3f19de","size":1617515,"width":3840,"height":5760},{"id":1286909,"hash":"f93a1d59abb4cbd6b103a67a196bdd2d93b59dce","size":1780860,"width":3840,"height":5760},{"id":1286910,"hash":"476ca9333e252e2c6c2af03a2b0d26d8c4f1bb98","size":1860967,"width":3840,"height":5760},{"id":1286911,"hash":"0f5c094e132341fcf674595337972e2ef17a167a","size":2115471,"width":5760,"height":3840},{"id":1286912,"hash":"b93525958c2e8a6250fddb4bf2f144114ed9e10c","size":1764892,"width":3840,"height":5760},{"id":1286913,"hash":"ba43e1d6da2f0a5c0a5a06ac91509db83f5b7f0c","size":1918468,"width":3840,"height":5760},{"id":1286914,"hash":"b1c7beff8706b6d2a1485cf6955da58bd213edf7","size":2010329,"width":5760,"height":3840},{"id":1286915,"hash":"840e7a774d101892be9471dbb1fd724d69f3ba81","size":2194101,"width":3840,"height":5760},{"id":1286916,"hash":"40a0da4739ea352ad817c4d8164465ccc55f6219","size":2058606,"width":3840,"height":5760},{"id":1286917,"hash":"6ce5e82651073d27a79938a7f2b4d81d92c6cdb1","size":2037064,"width":3840,"height":5760},{"id":1286918,"hash":"9f19516145d8d4b85198c1b0837cb4336025e284","size":1977907,"width":3840,"height":5760},{"id":1286919,"hash":"9d9c7ae757c823b49aa7120ee6ff278100e1cecb","size":1592763,"width":5760,"height":3840},{"id":1286920,"hash":"c559d0e0265a0bf0da08e89f7b5eeaa6d4668c62","size":2271207,"width":5760,"height":3840},{"id":1286921,"hash":"be7018d7ec1f40647693ddbe4b6f2a61a5fb2a19","size":1802304,"width":5760,"height":3840},{"id":1286922,"hash":"cd2e39ebb9019ca6efb0c5b628b25cdc770e520c","size":2304951,"width":5760,"height":3840},{"id":1286923,"hash":"6cef3203b6c7cfc4132c03f7e03b33657ff0afb5","size":2067776,"width":5760,"height":3840},{"id":1286924,"hash":"1240e86e5c13cbb4494311de5a95403e8d7562f7","size":2016242,"width":5760,"height":3840},{"id":1286925,"hash":"1a8d61af93a85f87e8c03b1ec3057bda5229a8d0","size":2005000,"width":3840,"height":5760},{"id":1286926,"hash":"22dccb718dba2a64db6ee8f76e49a845fd407b62","size":1865548,"width":3840,"height":5760},{"id":1286927,"hash":"2864749212627b6483c9e7e7db6771cbd375479a","size":1864506,"width":3840,"height":5760},{"id":1286928,"hash":"7713d64ea2f3610d310e2ee702c4f79a9dd315e6","size":2392580,"width":5760,"height":3840},{"id":1286929,"hash":"b87b39b988b618cf46433ce91a75fa91711f4fde","size":2569279,"width":3840,"height":5760},{"id":1286930,"hash":"9ef855f02a83e22fdd2e21196f4954b06ca9daff","size":2125028,"width":3840,"height":5760},{"id":1286931,"hash":"a9afd85523cc730d1012ef31a499b2c2521e5762","size":2322005,"width":3840,"height":5760},{"id":1286932,"hash":"930f41cbb62729611183f533cf74cf037be1e97d","size":2051664,"width":3840,"height":5760},{"id":1286933,"hash":"745e26b7ec55b612feecc4a6d8461933124f6116","size":2006521,"width":3840,"height":5760},{"id":1286934,"hash":"91dbb3ff785e6d2552787a5409820fc2b87dff65","size":1884339,"width":3840,"height":5760},{"id":1286935,"hash":"49b3553a33bce66a0cfe5bcc2542e1da5df03ac1","size":2195583,"width":3840,"height":5760},{"id":1286936,"hash":"d828eec1d8fd5c85f49b6e274e918aa7a5f11efb","size":2011705,"width":3840,"height":5760},{"id":1286937,"hash":"a7de42969f6cc92bf99b5bdb5f481b4744f27dbe","size":2000287,"width":3840,"height":5760},{"id":1286938,"hash":"c3eeaca04d84ecc70f4fa84b24ff65d93821633c","size":2205594,"width":3840,"height":5760},{"id":1286939,"hash":"f9fe10317554399077d80c01d153a2ba0bf8f3ff","size":2144805,"width":3840,"height":5760},{"id":1286940,"hash":"b263f5891af4f57ee909bf4624a583e6f0bcff56","size":2071092,"width":3840,"height":5760},{"id":1286941,"hash":"a5c42111d917c9becc9ce3f9fd0057e358c1c2ac","size":1920049,"width":3840,"height":5760},{"id":1286942,"hash":"83ebd80228e938bc741bfa8a786e0b664df5fcaf","size":1933704,"width":3840,"height":5760},{"id":1286943,"hash":"08d91e3b1591df47e1ce96c1b48337687333fe23","size":2064418,"width":3840,"height":5760},{"id":1286944,"hash":"dceea3d9efa68a8fc10c0aa5672eea925d75a107","size":2112258,"width":3840,"height":5760},{"id":1286945,"hash":"fbc0cc86e44cfa91f0a1faac39f4d9b6515a3ef2","size":2117521,"width":3840,"height":5760},{"id":1286946,"hash":"0a11ba4be8539ddc6e9b468b1db4198d750cf5b5","size":1737456,"width":5760,"height":3840},{"id":1286947,"hash":"ac75b9a8401fc9c8f6a434f156d392a353e9d610","size":1567205,"width":5760,"height":3840},{"id":1286948,"hash":"151657bfbe3a3abfd8c7c39427a9e91eccff5c4c","size":2015784,"width":3840,"height":5760},{"id":1286949,"hash":"55fa10dbc4374e3bff4a098002cdead4a05d5595","size":1971142,"width":3840,"height":5760},{"id":1286950,"hash":"cc27d0cc5a54ecff42619107fca0cadc71ef9cb0","size":2684944,"width":3840,"height":5760},{"id":1286951,"hash":"d44697948f2d7f355fa1e6810773c7d568e92e9f","size":2128840,"width":3840,"height":5760},{"id":1286952,"hash":"8b2f6190fe63eef8f6c57155b6f7b753720fe326","size":2608893,"width":3840,"height":5760},{"id":1286953,"hash":"5d7a1777f363bf29d12c5c94851f1c93f9ce860f","size":72527,"width":525,"height":790}]}},"editor":{"recentImages":[{"type":"gallery","mimeType":"image\/jpeg","galleryId":"5b4619eb-d2f0-48d3-a78d-43d9b4880c63","url":"gallery:5b4619eb-d2f0-48d3-a78d-43d9b4880c63\/1286840","imageId":1286840},{"type":"pattern","mimeType":"image\/jpeg","pattern":"*.jpg","url":"file:*.jpg"}]}}