liftie
Version:
Clean, simple, easy to read, fast ski resort lift status
1,595 lines (1,566 loc) • 43.8 kB
JavaScript
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __typeError = (msg) => {
throw TypeError(msg);
};
var __commonJS = (cb, mod) => function __require() {
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
// If the importer is in node compatibility mode or this is not an ESM
// file that has been converted to a CommonJS file using a Babel-
// compatible transform (i.e. "__esModule" has not been set), then set
// "default" to the CommonJS "module.exports" for node compatibility.
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
mod
));
var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot " + msg);
var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), setter ? setter.call(obj, value) : member.set(obj, value), value);
// node_modules/.pnpm/component-emitter@2.0.0/node_modules/component-emitter/index.js
var require_component_emitter = __commonJS({
"node_modules/.pnpm/component-emitter@2.0.0/node_modules/component-emitter/index.js"(exports, module) {
function Emitter3(object) {
if (object) {
return mixin(object);
}
this._callbacks = /* @__PURE__ */ new Map();
}
function mixin(object) {
Object.assign(object, Emitter3.prototype);
object._callbacks = /* @__PURE__ */ new Map();
return object;
}
Emitter3.prototype.on = function(event, listener) {
var _a;
const callbacks = (_a = this._callbacks.get(event)) != null ? _a : [];
callbacks.push(listener);
this._callbacks.set(event, callbacks);
return this;
};
Emitter3.prototype.once = function(event, listener) {
const on = (...arguments_) => {
this.off(event, on);
listener.apply(this, arguments_);
};
on.fn = listener;
this.on(event, on);
return this;
};
Emitter3.prototype.off = function(event, listener) {
if (event === void 0 && listener === void 0) {
this._callbacks.clear();
return this;
}
if (listener === void 0) {
this._callbacks.delete(event);
return this;
}
const callbacks = this._callbacks.get(event);
if (callbacks) {
for (const [index, callback] of callbacks.entries()) {
if (callback === listener || callback.fn === listener) {
callbacks.splice(index, 1);
break;
}
}
if (callbacks.length === 0) {
this._callbacks.delete(event);
} else {
this._callbacks.set(event, callbacks);
}
}
return this;
};
Emitter3.prototype.emit = function(event, ...arguments_) {
const callbacks = this._callbacks.get(event);
if (callbacks) {
const callbacksCopy = [...callbacks];
for (const callback of callbacksCopy) {
callback.apply(this, arguments_);
}
}
return this;
};
Emitter3.prototype.listeners = function(event) {
var _a;
return (_a = this._callbacks.get(event)) != null ? _a : [];
};
Emitter3.prototype.listenerCount = function(event) {
if (event) {
return this.listeners(event).length;
}
let totalCount = 0;
for (const callbacks of this._callbacks.values()) {
totalCount += callbacks.length;
}
return totalCount;
};
Emitter3.prototype.hasListeners = function(event) {
return this.listenerCount(event) > 0;
};
Emitter3.prototype.addEventListener = Emitter3.prototype.on;
Emitter3.prototype.removeListener = Emitter3.prototype.off;
Emitter3.prototype.removeEventListener = Emitter3.prototype.off;
Emitter3.prototype.removeAllListeners = Emitter3.prototype.off;
if (typeof module !== "undefined") {
module.exports = Emitter3;
}
}
});
// node_modules/.pnpm/yields-keycode@1.1.0/node_modules/yields-keycode/index.js
var require_yields_keycode = __commonJS({
"node_modules/.pnpm/yields-keycode@1.1.0/node_modules/yields-keycode/index.js"(exports, module) {
var map = {
backspace: 8,
command: 91,
tab: 9,
clear: 12,
enter: 13,
shift: 16,
ctrl: 17,
alt: 18,
capslock: 20,
escape: 27,
esc: 27,
space: 32,
pageup: 33,
pagedown: 34,
end: 35,
home: 36,
left: 37,
up: 38,
right: 39,
down: 40,
del: 46,
comma: 188,
f1: 112,
f2: 113,
f3: 114,
f4: 115,
f5: 116,
f6: 117,
f7: 118,
f8: 119,
f9: 120,
f10: 121,
f11: 122,
f12: 123,
",": 188,
".": 190,
"/": 191,
"`": 192,
"-": 189,
"=": 187,
";": 186,
"[": 219,
"\\": 220,
"]": 221,
"'": 222
};
module.exports = function(name) {
return map[name.toLowerCase()] || name.toUpperCase().charCodeAt(0);
};
}
});
// node_modules/.pnpm/yields-k-sequence@0.1.0/node_modules/yields-k-sequence/index.js
var require_yields_k_sequence = __commonJS({
"node_modules/.pnpm/yields-k-sequence@0.1.0/node_modules/yields-k-sequence/index.js"(exports, module) {
var keycode = require_yields_keycode();
module.exports = sequence;
function sequence(keys, ms, fn) {
var codes = keys.split(/ +/).map(keycode), clen = codes.length, seq = [], i = 0, prev;
if (2 == arguments.length) {
fn = ms;
ms = 500;
}
return function(e) {
var code = codes[i++];
if (42 != code && code != e.which) return reset();
if (prev && /* @__PURE__ */ new Date() - prev > ms) return reset();
var len = seq.push(e.which);
prev = /* @__PURE__ */ new Date();
if (len != clen) return;
reset();
fn(e);
};
function reset() {
prev = null;
seq = [];
i = 0;
}
}
}
});
// node_modules/.pnpm/component-os@0.0.1/node_modules/component-os/index.js
var require_component_os = __commonJS({
"node_modules/.pnpm/component-os@0.0.1/node_modules/component-os/index.js"(exports, module) {
module.exports = os();
function os() {
var ua = navigator.userAgent;
if (/mac/i.test(ua)) return "mac";
if (/win/i.test(ua)) return "windows";
if (/linux/i.test(ua)) return "linux";
}
}
});
// node_modules/.pnpm/@pirxpilot+k@1.0.1/node_modules/@pirxpilot/k/lib/proto.js
var require_proto = __commonJS({
"node_modules/.pnpm/@pirxpilot+k@1.0.1/node_modules/@pirxpilot/k/lib/proto.js"(exports) {
var sequence = require_yields_k_sequence();
var keycode = require_yields_keycode();
var os = require_component_os();
var modifiers = {
224: "command",
91: "command",
93: "command",
16: "shift",
17: "ctrl",
18: "alt"
};
exports["super"] = "mac" == os ? "command" : "ctrl";
exports.handle = function(e, fn) {
var ignore = this.ignore;
var event = e.type;
var code = e.which;
if (fn) return this.bind(e, fn);
var mod = modifiers[code];
if ("keydown" == event && mod) {
this["super"] = exports["super"] == mod;
this[mod] = true;
this.modifiers = true;
this.active++;
return;
}
if (ignore && ignore(e)) return;
var all = this.listeners;
for (var i = 0; i < all.length; ++i) {
var invoke = true;
var obj = all[i];
var seq = obj.seq;
var mods = obj.mods;
fn = seq || obj.fn;
if (!seq && code != obj.code) continue;
if (event != obj.event) continue;
if (this.active != obj.mods.length) continue;
for (var j = 0; j < mods.length; ++j) {
if (!this[mods[j]]) {
invoke = null;
break;
}
}
if (invoke) {
fn(e);
}
}
};
exports.destroy = function() {
this.el.removeEventListener("keydown", this._handle);
this.el.removeEventListener("keyup", this._handle);
this.el.removeEventListener("keyup", this._clear);
this.el.removeEventListener("focus", this._clear);
this.listeners = [];
};
exports.unbind = function(keys, fn) {
var fns = this.listeners;
var len = fns.length;
var all;
if (0 === arguments.length) {
this.listeners = [];
return this;
}
all = parseKeys(keys);
for (var i = 0; i < all.length; ++i) {
for (var j = 0, obj; j < len; ++j) {
obj = fns[j];
if (!obj) continue;
if (fn && obj.fn != fn) continue;
if (obj.key != all[i].key) continue;
if (!matches(obj, all[i])) continue;
fns.splice(j--, 1);
}
}
return this;
};
exports.bind = function(event, keys, fn) {
var fns = this.listeners;
var len;
var all;
if (2 == arguments.length) {
fn = keys;
keys = event;
event = "keydown";
}
all = parseKeys(keys);
len = all.length;
for (var i = 0; i < len; ++i) {
var obj = all[i];
obj.seq = obj.seq && sequence(obj.key, fn);
obj.event = event;
obj.fn = fn;
fns.push(obj);
}
return this;
};
exports.up = function(keys, fn) {
return this.bind("keyup", keys, fn);
};
exports.down = function(keys, fn) {
return this.bind("keydown", keys, fn);
};
exports.clear = function(e) {
var code = e.keyCode || e.which;
if (!(code in modifiers)) return;
this.active--;
this[modifiers[code]] = null;
this.modifiers = this.command || this.shift || this.ctrl || this.alt;
};
exports.reset = function() {
this.active = 0;
this.modifiers = this.command = this.shift = this.ctrl = this.alt = null;
};
exports.ignore = function(e) {
var el = e.target || e.srcElement;
var name = el.tagName.toLowerCase();
return "textarea" == name || "select" == name || "input" == name;
};
function parseKeys(keys) {
keys = keys.replace("super", exports["super"]);
var all = "," != keys ? keys.split(/ *, */) : [","];
var ret = [];
for (var i = 0; i < all.length; ++i) {
if ("" === all[i]) continue;
var mods = all[i].split(/ *\+ */);
var key = mods.pop() || ",";
ret.push({
seq: !!(~key.indexOf(" ") || ~key.indexOf("*")),
code: keycode(key),
mods,
key
});
}
return ret;
}
function matches(a, b) {
return 0 === b.mods.length || eql(a, b);
}
function eql(a, b) {
a = a.mods.sort().toString();
b = b.mods.sort().toString();
return a == b;
}
}
});
// node_modules/.pnpm/@pirxpilot+k@1.0.1/node_modules/@pirxpilot/k/lib/index.js
var require_lib = __commonJS({
"node_modules/.pnpm/@pirxpilot+k@1.0.1/node_modules/@pirxpilot/k/lib/index.js"(exports, module) {
var proto = require_proto();
module.exports = function(el) {
function k2(e, fn) {
k2.handle(e, fn);
}
k2._handle = proto.handle.bind(k2);
k2._clear = proto.clear.bind(k2);
k2._reset = proto.reset.bind(k2);
el.addEventListener("keydown", k2._handle, false);
el.addEventListener("keyup", k2._handle, false);
el.addEventListener("keyup", k2._clear, false);
el.addEventListener("focus", k2._reset, false);
for (var p in proto) k2[p] = proto[p];
k2.listeners = [];
k2.active = 0;
k2.el = el;
return k2;
};
}
});
// node_modules/.pnpm/js-cookie@3.0.5/node_modules/js-cookie/dist/js.cookie.mjs
function assign(target) {
for (var i = 1; i < arguments.length; i++) {
var source = arguments[i];
for (var key in source) {
target[key] = source[key];
}
}
return target;
}
var defaultConverter = {
read: function(value) {
if (value[0] === '"') {
value = value.slice(1, -1);
}
return value.replace(/(%[\dA-F]{2})+/gi, decodeURIComponent);
},
write: function(value) {
return encodeURIComponent(value).replace(
/%(2[346BF]|3[AC-F]|40|5[BDE]|60|7[BCD])/g,
decodeURIComponent
);
}
};
function init(converter, defaultAttributes) {
function set(name, value, attributes) {
if (typeof document === "undefined") {
return;
}
attributes = assign({}, defaultAttributes, attributes);
if (typeof attributes.expires === "number") {
attributes.expires = new Date(Date.now() + attributes.expires * 864e5);
}
if (attributes.expires) {
attributes.expires = attributes.expires.toUTCString();
}
name = encodeURIComponent(name).replace(/%(2[346B]|5E|60|7C)/g, decodeURIComponent).replace(/[()]/g, escape);
var stringifiedAttributes = "";
for (var attributeName in attributes) {
if (!attributes[attributeName]) {
continue;
}
stringifiedAttributes += "; " + attributeName;
if (attributes[attributeName] === true) {
continue;
}
stringifiedAttributes += "=" + attributes[attributeName].split(";")[0];
}
return document.cookie = name + "=" + converter.write(value, name) + stringifiedAttributes;
}
function get(name) {
if (typeof document === "undefined" || arguments.length && !name) {
return;
}
var cookies = document.cookie ? document.cookie.split("; ") : [];
var jar = {};
for (var i = 0; i < cookies.length; i++) {
var parts = cookies[i].split("=");
var value = parts.slice(1).join("=");
try {
var found = decodeURIComponent(parts[0]);
jar[found] = converter.read(value, found);
if (name === found) {
break;
}
} catch (e) {
}
}
return name ? jar[name] : jar;
}
return Object.create(
{
set,
get,
remove: function(name, attributes) {
set(
name,
"",
assign({}, attributes, {
expires: -1
})
);
},
withAttributes: function(attributes) {
return init(this.converter, assign({}, this.attributes, attributes));
},
withConverter: function(converter2) {
return init(assign({}, this.converter, converter2), this.attributes);
}
},
{
attributes: { value: Object.freeze(defaultAttributes) },
converter: { value: Object.freeze(converter) }
}
);
}
var api = init(defaultConverter, { path: "/" });
// lib/client/about/index.js
function about() {
const s = document.querySelector(".hidden .about");
if (!s) {
return;
}
if (!check()) {
return;
}
const section = s.parentNode;
const trigger = s.querySelector("a.close");
trigger.addEventListener("click", (e) => {
close();
e.preventDefault();
});
open();
function check() {
return window.parent === window && typeof api.get("resorts-open") === "undefined";
}
function close() {
section.classList.add("hidden");
}
function open() {
section.classList.remove("hidden");
}
}
// lib/client/minimax/index.js
function minimax(node, selector) {
const my = {
trigger: node.querySelector(selector),
state: "open",
// by default trigger 'open' state
fn() {
}
};
const self = {
state: state2,
on
};
function onclick(e) {
e.preventDefault();
const state3 = node.classList.toggle(my.state);
my.fn.call(null, state3);
}
function state2(s) {
my.state = s;
return self;
}
function on(fn) {
my.fn = fn;
return self;
}
if (my.trigger) {
my.trigger.addEventListener("click", onclick);
}
return self;
}
// lib/client/resort/dom.js
function removeAllChildren(node) {
while (node.hasChildNodes()) {
node.removeChild(node.lastChild);
}
}
function next({ nextElementSibling, nextSibling }) {
return nextElementSibling || nextSibling;
}
// lib/client/resort/lifts.js
render.section = 0;
render.type = "lifts";
var states = ["open", "hold", "scheduled", "closed"];
function renderStatus(node, status) {
removeAllChildren(node);
if (status) {
node.innerHTML = Object.keys(status).map((name) => {
const klass = `status ls-${status[name]}`;
return `<li class="lift"><span class="name">${name}</span><span class="${klass}"></span></li>`;
}).join("");
}
}
function renderStats(node, stats2) {
states.forEach((s) => node.querySelector(`.ls-${s}`).innerHTML = stats2 ? stats2[s] : 0);
}
function renderColorBar(node, percentage) {
states.forEach((state2) => {
const width = `width:${percentage ? percentage[state2] : 25}%;`;
node.querySelector(`.${state2}`).setAttribute("style", width);
});
}
function render(node, { status, stats: stats2 }) {
renderStatus(node.querySelector(".lifts"), status);
renderStats(node.querySelector(".summary"), stats2);
renderColorBar(node.querySelector(".summary-color-bar"), stats2.percentage);
}
// lib/client/resort/snow.js
var day = 24 * 60 * 60 * 1e3;
render2.section = 1;
render2.type = "snow";
function renderField(div, field, snow) {
const el = div.querySelector(`.${field}`);
const value = snow[field];
el.querySelector(".value").innerHTML = value || "";
el.classList.toggle("hidden", !value);
}
function render2(div, snow) {
if (Date.now() - snow.timestamp > day) {
return false;
}
renderField(div, "snowfall", snow);
renderField(div, "depth", snow);
renderField(div, "condition", snow);
div.querySelector(".notice").innerHTML = snow.notice || "";
return true;
}
// lib/client/resort/weather.js
var day2 = 24 * 60 * 60 * 1e3;
render3.section = 1;
render3.type = "weather";
function renderIcon(li, icon) {
if (Array.isArray(icon)) {
icon.forEach((cl, i) => li.item(i).setAttribute("class", cl));
}
}
function renderNotice(el, notice) {
if (!notice) {
return el.classList.add("hidden");
}
el.classList.remove("hidden");
el = el.querySelector("a");
el.setAttribute("href", notice.href);
el.setAttribute("title", `Go to ${notice.site}`);
el = el.querySelector("img");
el.setAttribute("src", notice.img);
el.setAttribute("style", `width:${notice.width}px;`);
el.setAttribute("alt", notice.site);
}
function render3(div, weather) {
if (Date.now() - weather.timestamp > day2) {
return false;
}
renderIcon(div.querySelectorAll(".weather-icon > ul > li"), weather.icon);
div.querySelector(".temperature").innerHTML = `${weather.temperature.max}°F`;
const snowforecast = div.querySelector(".snowforecast");
snowforecast.classList.toggle("hidden", !weather.snow);
if (weather.snow) {
snowforecast.innerHTML = `${weather.snow}"`;
}
div.querySelector(".conditions").innerHTML = weather.conditions;
div.querySelector(".text").innerHTML = weather.text;
renderNotice(div.querySelector(".notice"), weather.notice);
return true;
}
// node_modules/.pnpm/@pirxpilot+events@3.0.0/node_modules/@pirxpilot/events/index.js
function events(el, obj) {
const handlers = /* @__PURE__ */ new Map();
function bind(name, handler, opts) {
if (!handler) {
handler = name;
}
if (typeof handler === "string") {
handler = obj[handler].bind(obj);
}
el.addEventListener(name, handler, opts);
handlers.set(name, {
handler,
opts
});
}
function do_unbind(name) {
const h = handlers.get(name);
if (h) {
el.removeEventListener(name, h.handler, h.opts);
handlers.delete(name);
}
}
function unbind(name) {
return name ? do_unbind(name) : unbindAll();
}
function unbindAll() {
handlers.forEach((h, name) => el.removeEventListener(name, h.handler, h.opts));
handlers.clear();
}
return {
bind,
unbind
};
}
// node_modules/.pnpm/@pirxpilot+swipe@3.0.0/node_modules/@pirxpilot/swipe/index.js
var import_component_emitter = __toESM(require_component_emitter(), 1);
var _duration, _interval, _threshold, _fastThreshold;
var Swipe = class extends import_component_emitter.default {
constructor(el) {
super();
__privateAdd(this, _duration, 300);
__privateAdd(this, _interval, 5e3);
__privateAdd(this, _threshold, 0.5);
__privateAdd(this, _fastThreshold, 200);
if (!el) throw new TypeError("Swipe() requires an element");
this.child = el.children[0];
this.touchAction("none");
this.currentEl = this.children().visible[0];
this.currentVisible = 0;
this.current = 0;
this.el = el;
this.refresh();
this.show(0, 0, { silent: true });
this.bind();
}
/**
* Set the swipe threshold to `n`.
*
* This is the factor required for swipe
* to detect when a slide has passed the
* given threshold, and may display the next
* or previous slide. For example the default
* of `.5` means that the user must swipe _beyond_
* half of the side width.
*
* @param {Number} n
* @api public
*/
threshold(n) {
__privateSet(this, _threshold, n);
}
/**
* Set the "fast" swipe threshold to `ms`.
*
* This is the amount of time in milliseconds
* which determines if a swipe was "fast" or not. When
* the swipe's duration is less than `ms` only 1/10th of
* the slide's width must be exceeded to display the previous
* or next slide.
*
* @param {Number} n
* @api public
*/
fastThreshold(ms) {
__privateSet(this, _fastThreshold, ms);
}
/**
* Refresh sizing data.
*
* @api public
*/
refresh() {
const children = this.children();
const visible2 = children.visible.length;
const prev = this.visible || visible2;
const i = indexOf(children.visible, this.currentEl);
if (visible2 < prev && i <= this.currentVisible && i >= 0) {
this.currentVisible = i;
} else if (visible2 > prev && i > this.currentVisible) {
this.currentVisible = i;
}
this.visible = visible2;
this.childWidth = this.el.getBoundingClientRect().width;
this.width = Math.ceil(this.childWidth * visible2);
this.child.style.width = `${this.width}px`;
this.child.style.height = `${this.height}px`;
this.show(this.currentVisible, 0, { silent: true });
}
/**
* Bind event handlers.
*
* @api public
*/
bind() {
this.events = events(this.child, this);
this.events.bind("pointerdown", "ontouchstart");
this.events.bind("pointermove", "ontouchmove");
this.events.bind("pointerup", "ontouchend");
this.events.bind("pointercancel", "ontouchend");
}
/**
* Unbind event handlers.
*
* @api public
*/
unbind() {
this.events.unbind();
}
/**
* Handle touchstart.
*
* @api private
*/
ontouchstart(e) {
this.transitionDuration(0);
this.dx = 0;
this.updown = null;
e.target.setPointerCapture(e.pointerId);
this.down = {
x: e.pageX,
y: e.pageY,
at: /* @__PURE__ */ new Date()
};
}
/**
* Handle touchmove.
*
* For the first and last slides
* we apply some resistence to help
* indicate that you're at the edges.
*
* @api private
*/
ontouchmove(e) {
if (!this.down || this.updown) return;
if (!e) return;
const down = this.down;
const x = e.pageX;
const w = this.childWidth;
const i = this.currentVisible;
this.dx = x - down.x;
if (null == this.updown) {
const y = e.pageY;
const dy = y - down.y;
const slope = dy / this.dx;
if (slope > 1 || slope < -1) {
this.updown = true;
return;
}
this.updown = false;
}
e.preventDefault();
const dir = this.dx < 0 ? 1 : 0;
if (this.isFirst() && 0 === dir) this.dx /= 2;
if (this.isLast() && 1 === dir) this.dx /= 2;
this.translate(i * w + -this.dx);
}
/**
* Handle touchend.
*
* @api private
*/
ontouchend(e) {
e.stopPropagation();
if (!this.down) return;
e.target.releasePointerCapture(e.pointerId);
const dx = this.dx;
const w = this.childWidth;
const ms = Date.now() - this.down.at;
const threshold = ms < __privateGet(this, _fastThreshold) ? w / 10 : w * __privateGet(this, _threshold);
const dir = dx < 0 ? 1 : 0;
const half = Math.abs(dx) >= threshold;
this.down = null;
if (this.isFirst() && 1 === dir && half) return this.next();
if (this.isFirst()) return this.prev();
if (this.isLast() && 1 === dir) return this.next();
if (1 === dir && half) return this.next();
if (0 === dir && half) return this.prev();
this.show(this.currentVisible);
}
/**
* Set transition duration to `ms`.
*
* @param {Number} ms
* @return {Swipe} self
* @api public
*/
duration(ms) {
__privateSet(this, _duration, ms);
return this;
}
/**
* Set cycle interval to `ms`.
*
* @param {Number} ms
* @return {Swipe} self
* @api public
*/
interval(ms) {
__privateSet(this, _interval, ms);
return this;
}
/**
* Play through all the elements.
*
* @return {Swipe} self
* @api public
*/
play() {
if (this.timer) return;
this.timer = setInterval(this.cycle.bind(this), __privateGet(this, _interval));
return this;
}
/**
* Stop playing.
*
* @return {Swipe} self
* @api public
*/
stop() {
clearInterval(this.timer);
this.timer = null;
return this;
}
/**
* Show the next slide, when the end
* is reached start from the beginning.
*
* @api public
*/
cycle() {
if (this.isLast()) {
this.currentVisible = -1;
this.next();
} else {
this.next();
}
}
/**
* Check if we're on the first visible slide.
*
* @return {Boolean}
* @api public
*/
isFirst() {
return this.currentVisible === 0;
}
/**
* Check if we're on the last visible slide.
*
* @return {Boolean}
* @api public
*/
isLast() {
return this.currentVisible === this.visible - 1;
}
/**
* Show the previous slide, if any.
*
* @return {Swipe} self
* @api public
*/
prev() {
this.show(this.currentVisible - 1);
return this;
}
/**
* Show the next slide, if any.
*
* @return {Swipe} self
* @api public
*/
next() {
this.show(this.currentVisible + 1);
return this;
}
/**
* Show slide `i`.
*
* Emits `show `event
*
* @param {Number} i
* @return {Swipe} self
* @api public
*/
show(i, ms = __privateGet(this, _duration), { silent } = {}) {
const children = this.children();
i = Math.max(0, Math.min(i, children.visible.length - 1));
this.currentVisible = i;
this.currentEl = children.visible[i];
this.current = indexOf(children.all, this.currentEl);
this.transitionDuration(ms);
this.translate(this.childWidth * i);
if (!silent) {
this.emit("showing", this.current, this.currentEl);
if (!ms) return this;
this.child.addEventListener(
"transitionend",
() => {
if (this.current === i) this.emit("show", this.current, this.currentEl);
},
{ once: true }
);
}
return this;
}
/**
* Return children categorized by visibility.
*
* @return {Object}
* @api private
*/
children() {
const els = this.child.children;
const ret = {
all: els,
visible: [],
hidden: []
};
for (let i = 0; i < els.length; i++) {
const el = els[i];
if (visible(el)) {
ret.visible.push(el);
} else {
ret.hidden.push(el);
}
}
return ret;
}
/**
* Set transition duration.
*
* @api private
*/
transitionDuration(ms) {
this.child.style.transition = `${ms}ms transform`;
}
/**
* Translate to `x`.
*
* TODO: use translate component
*
* @api private
*/
translate(x) {
this.child.style.transform = `translate3d(${-x}px, 0, 0)`;
}
/**
* Sets the "touchAction" CSS style property to `value`.
*
* @api private
*/
touchAction(value) {
this.child.style.touchAction = value;
}
};
_duration = new WeakMap();
_interval = new WeakMap();
_threshold = new WeakMap();
_fastThreshold = new WeakMap();
function indexOf(els, el) {
for (let i = 0; i < els.length; i++) {
if (els[i] === el) return i;
}
return -1;
}
function visible(el) {
return getComputedStyle(el).display !== "none";
}
// node_modules/.pnpm/tiny-pager@2.0.0/node_modules/tiny-pager/index.js
var import_component_emitter2 = __toESM(require_component_emitter(), 1);
// node_modules/.pnpm/el-component@2.0.3/node_modules/el-component/index.js
var voids = /* @__PURE__ */ new Set([
"area",
"base",
"br",
"col",
"embed",
"hr",
"img",
"input",
"keygen",
"link",
"menuitem",
"meta",
"param",
"source",
"track",
"wbr"
]);
function htmlTag(tag2, content, attrStr) {
const text = ["<", tag2, attrStr ? ` ${attrStr}` : "", ">"];
if (!voids.has(tag2)) {
text.push(content || "", "</", tag2, ">");
}
return text;
}
function xmlTag(tag2, content, attrStr) {
const text = ["<", tag2, attrStr ? ` ${attrStr}` : ""];
if (!content || !content.length) {
text.push("/>");
} else {
text.push(">", content, "</", tag2, ">");
}
return text;
}
function toStr(tagFn, tagStr, content, attrs) {
var _a;
if (typeof content !== "string") {
attrs = content;
content = "";
}
attrs != null ? attrs : attrs = {};
let [tag2 = "div", ...classes] = (_a = tagStr == null ? void 0 : tagStr.split(".")) != null ? _a : [];
if (classes.length) {
const classesStr = classes.join(" ");
if (attrs["class"]) {
attrs["class"] += ` ${classesStr}`;
} else {
attrs["class"] = classesStr;
}
}
const ids = tag2.split("#");
if (ids.length > 1) {
tag2 = ids[0] || "div";
attrs.id = ids[1];
}
const attrStr = Object.entries(attrs).map(([attr, value]) => `${attr}="${value}"`).join(" ");
return tagFn(tag2, content, attrStr).join("");
}
var el_component_default = toStr.bind(null, htmlTag);
var xml = toStr.bind(null, xmlTag);
// node_modules/.pnpm/tiny-pager@2.0.0/node_modules/tiny-pager/index.js
var _total, _current;
var Pager = class extends import_component_emitter2.default {
constructor(el) {
super();
__privateAdd(this, _total, 0);
__privateAdd(this, _current, 0);
this.el = el;
el.addEventListener("click", this.onclick.bind(this));
}
total(t) {
__privateSet(this, _total, t);
return this;
}
onclick(e) {
const target = e.target || e.srcElement;
const page = Array.prototype.indexOf.call(this.el.children, target);
if (page < 0) {
return;
}
e.preventDefault();
e.stopPropagation();
this.select(page);
}
select(page, opts) {
if (page === __privateGet(this, _current)) {
return;
}
Array.prototype.forEach.call(this.el.children, (a, i) => {
a.className = i === page ? "active" : "inactive";
});
__privateSet(this, _current, page);
if (!(opts == null ? void 0 : opts.silent)) {
this.emit("show", __privateGet(this, _current));
}
return this;
}
render() {
const html = new Array(__privateGet(this, _total));
for (let i = 0; i < __privateGet(this, _total); i++) {
html[i] = el_component_default(i !== __privateGet(this, _current) ? "a.inactive" : "a.active");
}
this.el.innerHTML = html.join("");
return this;
}
};
_total = new WeakMap();
_current = new WeakMap();
// lib/client/resort/webcams.js
render4.section = 1;
render4.type = "webcams";
var DELAY = 15 * 60 * 1e3;
function swiper(el) {
const ui = {
swipe: new Swipe(el.swipe),
pager: new Pager(el.pager)
};
function refresh(count) {
ui.swipe.refresh();
ui.pager.total(count).render();
el.pager.classList.toggle("hidden", count < 2);
}
function current() {
return ui.swipe.currentVisible;
}
ui.pager.on("show", (n) => {
ui.swipe.show(n, null, {
silent: true
});
});
ui.swipe.on("show", (n) => {
ui.pager.select(n, {
silent: true
});
});
return {
refresh,
current
};
}
function render4(div, webcams) {
let cams;
let timer;
let ui;
function refresh() {
cams.forEach((it) => {
const imgs = it.node.querySelectorAll("img");
const fn = swap.bind(null, imgs, it);
for (let i = 0; i < imgs.length; i++) {
imgs[i].onload = fn;
}
imgs[it.inactive].setAttribute("src", imgs[it.active].getAttribute("src"));
});
}
function initCam(cam, { source, image, name, notice }) {
cam.querySelector("a").setAttribute("href", source);
cam.querySelector("img.active").setAttribute("src", image);
cam.querySelector("img.inactive").setAttribute("src", "");
cam.querySelector(".title").innerHTML = name;
cam.querySelector(".notice").innerHTML = notice || "";
cams.push({
node: cam,
active: 0,
inactive: 1
});
}
function init3() {
if (timer) {
clearInterval(timer);
timer = void 0;
}
cams = [];
const ul = div.querySelector("ul");
const li = ul.querySelectorAll("li");
webcams.forEach((webcam, i) => {
let cam;
if (i < li.length) {
cam = li[i];
} else {
cam = ul.appendChild(li[0].cloneNode(true));
}
initCam(cam.querySelector(".webcam"), webcam);
});
for (let i = Math.max(1, webcams.length); i < li.length; i++) {
ul.removeChild(li[i]);
}
if (!ui) {
ui = swiper({
swipe: div.querySelector(".swipe"),
pager: div.querySelector(".pager")
});
}
ui.refresh(webcams.length);
if (!cams.length) {
return false;
}
timer = setInterval(refresh, DELAY);
return true;
}
function swap(imgs, it) {
it.active = (it.active + 1) % 2;
it.inactive = (it.inactive + 1) % 2;
imgs[it.inactive].setAttribute("class", "inactive");
imgs[it.active].setAttribute("class", "active");
imgs[it.inactive].setAttribute("src", "");
}
init3();
}
// lib/client/resort/index.js
function renderOpening(node, opening) {
if (opening) {
opening = opening.split("-");
if (new Date(opening[0], opening[1] - 1, opening[2]).getTime() <= Date.now()) {
node.dataset.opening = "";
node = node.querySelector(".opening-date");
node.parentNode.removeChild(node);
}
}
}
var plugins = [render, render3, render4, render2];
function renderPlugins(node, getData) {
const sec = next(node);
plugins.forEach((plugin) => {
const data = getData(plugin.type);
if (!data) {
return;
}
const el = plugin.section ? sec.querySelector(`.${plugin.type}`) : node;
if (!el) {
return;
}
const show = plugin(el, data);
if (typeof show === "boolean") {
el.classList.toggle("visible", show);
el.classList.toggle("hiddent", !show);
}
});
}
function render5(node, resort2) {
const tsPrev = JSON.parse(node.dataset.timestamp);
const tsCurr = resort2.timestamp;
renderPlugins(node, (plugin) => {
if (!resort2[plugin] || !tsCurr[plugin]) {
return;
}
if (tsPrev[plugin] && tsCurr[plugin] <= tsPrev[plugin]) {
return;
}
return resort2[plugin];
});
renderOpening(node, node.dataset.opening);
node.dataset.timestamp = JSON.stringify(tsCurr);
}
var MAX = 12;
function resort(node) {
let updateCounter = MAX;
function updateTimeToRefresh(counter) {
const ttr = node.querySelector(".time-to-refresh");
ttr.innerHTML = counter * 5;
}
function refresh(now) {
const id = node.dataset.resort;
if (!node.classList.contains("open")) {
return;
}
if (now) {
updateCounter = 0;
} else {
updateCounter -= 1;
}
if (updateCounter > 0) {
updateTimeToRefresh(updateCounter);
return;
}
updateCounter = MAX;
updateTimeToRefresh(updateCounter);
fetch(`/api/resort/${id}`).then((res) => res.json()).then((resort2) => render5(node, resort2));
}
function init3() {
const ds = node.dataset;
updateTimeToRefresh(MAX);
renderPlugins(node, (plugin) => {
const data = ds[plugin];
return data && JSON.parse(data);
});
}
return {
init: init3,
refresh,
node
};
}
// lib/client/state/index.js
var import_k = __toESM(require_lib(), 1);
var k = (0, import_k.default)(window);
function state(nodes, st, keys) {
const cookieName = `resorts-${st}`;
const self = {
load,
save,
update,
read
};
function find(id) {
return nodes.find((n) => n.dataset.resort === id);
}
function read() {
const text = api.get(cookieName);
return (text == null ? void 0 : text.length) ? text.split(",") : [];
}
function write(arr) {
api.set(cookieName, arr.join(","), {
expires: 30,
path: "/",
secure: window.location.protocol === "https:",
sameSite: "strict"
});
}
function update() {
const state2 = read().reduce((memo, id) => {
memo[id] = true;
return memo;
}, {});
nodes.forEach(({ dataset, classList }) => {
const id = dataset.resort;
state2[id] = classList.contains(st);
});
const selected = Object.keys(state2).filter((id) => state2[id]);
write(selected);
return selected;
}
function save() {
const selected = nodes.filter((n) => n.classList.contains(st)).map((n) => n.dataset.resort);
write(selected);
return selected;
}
function load() {
const selected = read();
selected.forEach((id) => {
const node = find(id);
if (node) {
node.classList.add(st);
}
});
return selected;
}
function all(on) {
nodes.forEach((n) => n.classList.toggle(st, on));
update();
}
if (keys) {
k(keys.on, all.bind(null, true));
k(keys.off, all.bind(null, false));
}
return self;
}
// lib/client/stats/index.js
function stats() {
const pie = document.querySelector(".stats .pie");
if (!pie) {
return;
}
const data = JSON.parse(pie.dataset.stats);
let ac = 0;
const { style } = pie;
Object.entries(data.percentage).forEach(([key, value]) => style.setProperty(`--${key}`, `${ac += value}%`));
}
// lib/client/tag/index.js
function tag(node) {
let count;
function update(c) {
if (!count) {
return;
}
count.innerHTML = c;
node.classList.toggle("hidden", c <= 0);
}
if (node) {
count = node.querySelector(".count");
}
return {
update
};
}
// node_modules/.pnpm/debounce@3.0.0/node_modules/debounce/index.js
function debounce(function_, wait = 100, options = {}) {
if (typeof function_ !== "function") {
throw new TypeError(`Expected the first parameter to be a function, got \`${typeof function_}\`.`);
}
if (wait < 0) {
throw new RangeError("`wait` must not be negative.");
}
if (typeof options === "boolean") {
throw new TypeError("The `options` parameter must be an object, not a boolean. Use `{immediate: true}` instead.");
}
const { immediate } = options;
let storedContext;
let storedArguments;
let timeoutId;
let timestamp;
let result;
function run() {
const callContext = storedContext;
const callArguments = storedArguments;
storedContext = void 0;
storedArguments = void 0;
result = function_.apply(callContext, callArguments);
return result;
}
function later() {
const last = Date.now() - timestamp;
if (last < wait && last >= 0) {
timeoutId = setTimeout(later, wait - last);
} else {
timeoutId = void 0;
if (!immediate) {
result = run();
}
}
}
const debounced = function(...arguments_) {
if (storedContext && this !== storedContext && Object.getPrototypeOf(this) === Object.getPrototypeOf(storedContext)) {
throw new Error("Debounced method called with different contexts of the same prototype.");
}
storedContext = this;
storedArguments = arguments_;
timestamp = Date.now();
const callNow = immediate && !timeoutId;
if (!timeoutId) {
timeoutId = setTimeout(later, wait);
}
if (callNow) {
result = run();
return result;
}
return void 0;
};
Object.defineProperty(debounced, "isPending", {
get() {
return timeoutId !== void 0;
}
});
debounced.clear = () => {
if (!timeoutId) {
return;
}
clearTimeout(timeoutId);
timeoutId = void 0;
storedContext = void 0;
storedArguments = void 0;
};
debounced.flush = () => {
if (!timeoutId) {
return;
}
debounced.trigger();
};
debounced.trigger = () => {
result = run();
debounced.clear();
};
return debounced;
}
// lib/client/boot/height.js
function notify() {
const widget = document.querySelector(".widget");
if (!widget) {
return;
}
window.parent.postMessage(
{
height: widget.scrollHeight,
resort: window.location.pathname.split("/").pop()
},
"*"
);
}
function postHeight() {
if (window === window.parent) {
return;
}
notify();
window.addEventListener("resize", debounce(notify, 300), true);
}
// lib/client/boot/service-worker.js
function registrationHandler({ scope, installing, waiting, active }) {
console.log("SW", scope);
if (installing) {
console.log("installing", installing.state);
}
if (waiting) {
console.log("waiting", waiting.state);
}
if (active) {
console.log("active", active.state);
}
}
function register(url = "/sw.js") {
if (navigator.serviceWorker && document.documentElement.hasAttribute("data-service-worker")) {
return navigator.serviceWorker.register(url).then(registrationHandler).catch((reason) => console.log("SW registration failed!", reason));
}
}
// lib/client/boot/index.js
register();
init2();
function init2() {
const rnodes = Array.from(document.querySelectorAll(".resort"));
const opens = state(rnodes, "open", {
on: "shift + o",
off: "shift + x"
});
const starred = state(rnodes, "starred");
const starredTag = tag(document.querySelector(".tags .starred"));
const resorts = rnodes.map((r) => resort(r));
resorts.forEach((r) => {
minimax(r.node, ".minimax").state("open").on((open) => {
if (open) {
r.refresh(true);
}
opens.update();
});
minimax(r.node, ".star").state("starred").on(() => starredTag.update(starred.update().length));
r.init();
});
window.setInterval(() => resorts.forEach((r) => r.refresh()), 5 * 1e3);
about();
opens.update();
starredTag.update(starred.load().length);
stats();
postHeight();
}
/*! Bundled license information:
js-cookie/dist/js.cookie.mjs:
(*! js-cookie v3.0.5 | MIT *)
*/
//# sourceMappingURL=liftie.js.map