diff --git a/web/glacier-exchange/README.md b/web/glacier-exchange/README.md new file mode 100644 index 0000000..586dd21 --- /dev/null +++ b/web/glacier-exchange/README.md @@ -0,0 +1 @@ +We have launched a new revolutionary exchange tool, allowing you to trade on the market and hanging out with your rich friends in the Glacier Club. Only Billionaires can get in though. Can you help me hang out with lEon sMuk? \ No newline at end of file diff --git a/web/glacier-exchange/chall/assets/icons/ascoin.png b/web/glacier-exchange/chall/assets/icons/ascoin.png new file mode 100644 index 0000000..39cb82e Binary files /dev/null and b/web/glacier-exchange/chall/assets/icons/ascoin.png differ diff --git a/web/glacier-exchange/chall/assets/icons/cashout.png b/web/glacier-exchange/chall/assets/icons/cashout.png new file mode 100644 index 0000000..6b78392 Binary files /dev/null and b/web/glacier-exchange/chall/assets/icons/cashout.png differ diff --git a/web/glacier-exchange/chall/assets/icons/doge.png b/web/glacier-exchange/chall/assets/icons/doge.png new file mode 100644 index 0000000..d1c6f4c Binary files /dev/null and b/web/glacier-exchange/chall/assets/icons/doge.png differ diff --git a/web/glacier-exchange/chall/assets/icons/favicon.ico b/web/glacier-exchange/chall/assets/icons/favicon.ico new file mode 100644 index 0000000..f5b30ee Binary files /dev/null and b/web/glacier-exchange/chall/assets/icons/favicon.ico differ diff --git a/web/glacier-exchange/chall/assets/icons/gamestock.png b/web/glacier-exchange/chall/assets/icons/gamestock.png new file mode 100644 index 0000000..f365a0c Binary files /dev/null and b/web/glacier-exchange/chall/assets/icons/gamestock.png differ diff --git a/web/glacier-exchange/chall/assets/icons/glaciercoin.png b/web/glacier-exchange/chall/assets/icons/glaciercoin.png new file mode 100644 index 0000000..728d9e6 Binary files /dev/null and b/web/glacier-exchange/chall/assets/icons/glaciercoin.png differ diff --git a/web/glacier-exchange/chall/assets/icons/smtl.png b/web/glacier-exchange/chall/assets/icons/smtl.png new file mode 100644 index 0000000..6a5d4eb Binary files /dev/null and b/web/glacier-exchange/chall/assets/icons/smtl.png differ diff --git a/web/glacier-exchange/chall/assets/icons/ycmi.png b/web/glacier-exchange/chall/assets/icons/ycmi.png new file mode 100644 index 0000000..9b96579 Binary files /dev/null and b/web/glacier-exchange/chall/assets/icons/ycmi.png differ diff --git a/web/glacier-exchange/chall/assets/images/bg.jpg b/web/glacier-exchange/chall/assets/images/bg.jpg new file mode 100644 index 0000000..d48f157 Binary files /dev/null and b/web/glacier-exchange/chall/assets/images/bg.jpg differ diff --git a/web/glacier-exchange/chall/assets/images/convert-button.jpg b/web/glacier-exchange/chall/assets/images/convert-button.jpg new file mode 100644 index 0000000..192a779 Binary files /dev/null and b/web/glacier-exchange/chall/assets/images/convert-button.jpg differ diff --git a/web/glacier-exchange/chall/assets/scripts/chart.component.js b/web/glacier-exchange/chall/assets/scripts/chart.component.js new file mode 100644 index 0000000..464c53d --- /dev/null +++ b/web/glacier-exchange/chall/assets/scripts/chart.component.js @@ -0,0 +1,372 @@ +Vue.component('glacier-chart', { + props: [ + "name" + ], + template: `
+

{{ name }}

+
+
+
`, + watch: { + name() { + this.fetchData(); + } + }, + mounted() { + this.fetchData(); + }, + data: _ => { + return { + data: [] + } + }, + methods: { + fetchData() { + fetch("/api/data/fetch/" + encodeURIComponent(this.name)).then(res => res.json()).then(data => { + this.data = data; + this.render(); + }) + }, + render() { + am5.ready(_ => { + + // Create root element + // ------------------------------------------------------------------------------- + // https://www.amcharts.com/docs/v5/getting-started/#Root_element + var root = am5.Root.new("chartdiv"); + // Set themes + // ------------------------------------------------------------------------------- + // https://www.amcharts.com/docs/v5/concepts/themes/ + root.setThemes([ + // am5themes_Animated.new(root) + am5themes_Dark.new(root) + ]); + + + + // Create a stock chart + // ------------------------------------------------------------------------------- + // https://www.amcharts.com/docs/v5/charts/stock-chart/#Instantiating_the_chart + var stockChart = root.container.children.push(am5stock.StockChart.new(root, { + })); + this.chart = stockChart; + + + // Set global number format + // ------------------------------------------------------------------------------- + // https://www.amcharts.com/docs/v5/concepts/formatters/formatting-numbers/ + root.numberFormatter.set("numberFormat", "#,###.00"); + + + // Create a main stock panel (chart) + // ------------------------------------------------------------------------------- + // https://www.amcharts.com/docs/v5/charts/stock-chart/#Adding_panels + var mainPanel = stockChart.panels.push(am5stock.StockPanel.new(root, { + wheelY: "zoomX", + panX: true, + panY: true + })); + + + // Create value axis + // ------------------------------------------------------------------------------- + // https://www.amcharts.com/docs/v5/charts/xy-chart/axes/ + var valueAxis = mainPanel.yAxes.push(am5xy.ValueAxis.new(root, { + renderer: am5xy.AxisRendererY.new(root, { + pan: "zoom" + }), + extraMin: 0.1, // adds some space for for main series + tooltip: am5.Tooltip.new(root, {}), + numberFormat: "#,###.00", + extraTooltipPrecision: 2 + })); + + var dateAxis = mainPanel.xAxes.push(am5xy.GaplessDateAxis.new(root, { + baseInterval: { + timeUnit: "day", + count: 1 + }, + renderer: am5xy.AxisRendererX.new(root, {}), + tooltip: am5.Tooltip.new(root, {}) + })); + + + // Add series + // ------------------------------------------------------------------------------- + // https://www.amcharts.com/docs/v5/charts/xy-chart/series/ + var valueSeries = mainPanel.series.push(am5xy.CandlestickSeries.new(root, { + name: this.name, + clustered: false, + valueXField: "Date", + valueYField: "Close", + highValueYField: "High", + lowValueYField: "Low", + openValueYField: "Open", + calculateAggregates: true, + xAxis: dateAxis, + yAxis: valueAxis, + legendValueText: "open: [bold]{openValueY}[/] high: [bold]{highValueY}[/] low: [bold]{lowValueY}[/] close: [bold]{valueY}[/]", + legendRangeValueText: "" + })); + + + // Set main value series + // ------------------------------------------------------------------------------- + // https://www.amcharts.com/docs/v5/charts/stock-chart/#Setting_main_series + stockChart.set("stockSeries", valueSeries); + + + // Add a stock legend + // ------------------------------------------------------------------------------- + // https://www.amcharts.com/docs/v5/charts/stock-chart/stock-legend/ + var valueLegend = mainPanel.plotContainer.children.push(am5stock.StockLegend.new(root, { + stockChart: stockChart + })); + + + // Create volume axis + // ------------------------------------------------------------------------------- + // https://www.amcharts.com/docs/v5/charts/xy-chart/axes/ + var volumeAxisRenderer = am5xy.AxisRendererY.new(root, { + inside: true + }); + + volumeAxisRenderer.labels.template.set("forceHidden", true); + volumeAxisRenderer.grid.template.set("forceHidden", true); + + var volumeValueAxis = mainPanel.yAxes.push(am5xy.ValueAxis.new(root, { + numberFormat: "#.#a", + height: am5.percent(20), + y: am5.percent(100), + centerY: am5.percent(100), + renderer: volumeAxisRenderer + })); + + // Add series + // https://www.amcharts.com/docs/v5/charts/xy-chart/series/ + var volumeSeries = mainPanel.series.push(am5xy.ColumnSeries.new(root, { + name: "Volume", + clustered: false, + valueXField: "Date", + valueYField: "Volume", + xAxis: dateAxis, + yAxis: volumeValueAxis, + legendValueText: "[bold]{valueY.formatNumber('#,###.0a')}[/]" + })); + + volumeSeries.columns.template.setAll({ + strokeOpacity: 0, + fillOpacity: 0.5 + }); + + // color columns by stock rules + volumeSeries.columns.template.adapters.add("fill", function (fill, target) { + var dataItem = target.dataItem; + if (dataItem) { + return stockChart.getVolumeColor(dataItem); + } + return fill; + }) + + + // Set main series + // ------------------------------------------------------------------------------- + // https://www.amcharts.com/docs/v5/charts/stock-chart/#Setting_main_series + stockChart.set("volumeSeries", volumeSeries); + valueLegend.data.setAll([valueSeries, volumeSeries]); + + + // Add cursor(s) + // ------------------------------------------------------------------------------- + // https://www.amcharts.com/docs/v5/charts/xy-chart/cursor/ + mainPanel.set("cursor", am5xy.XYCursor.new(root, { + yAxis: valueAxis, + xAxis: dateAxis, + snapToSeries: [valueSeries], + snapToSeriesBy: "y!" + })); + + + // Add scrollbar + // ------------------------------------------------------------------------------- + // https://www.amcharts.com/docs/v5/charts/xy-chart/scrollbars/ + var scrollbar = mainPanel.set("scrollbarX", am5xy.XYChartScrollbar.new(root, { + orientation: "horizontal", + height: 50 + })); + stockChart.toolsContainer.children.push(scrollbar); + + var sbDateAxis = scrollbar.chart.xAxes.push(am5xy.GaplessDateAxis.new(root, { + baseInterval: { + timeUnit: "day", + count: 1 + }, + renderer: am5xy.AxisRendererX.new(root, {}) + })); + + var sbValueAxis = scrollbar.chart.yAxes.push(am5xy.ValueAxis.new(root, { + renderer: am5xy.AxisRendererY.new(root, {}) + })); + + var sbSeries = scrollbar.chart.series.push(am5xy.LineSeries.new(root, { + valueYField: "Close", + valueXField: "Date", + xAxis: sbDateAxis, + yAxis: sbValueAxis + })); + + sbSeries.fills.template.setAll({ + visible: true, + fillOpacity: 0.3 + }); + + // Set up series type switcher + // ------------------------------------------------------------------------------- + // https://www.amcharts.com/docs/v5/charts/stock/toolbar/series-type-control/ + var seriesSwitcher = am5stock.SeriesTypeControl.new(root, { + stockChart: stockChart + }); + + seriesSwitcher.events.on("selected", function (ev) { + setSeriesType(ev.item.id); + }); + + function getNewSettings(series) { + var newSettings = []; + am5.array.each(["name", "valueYField", "highValueYField", "lowValueYField", "openValueYField", "calculateAggregates", "valueXField", "xAxis", "yAxis", "legendValueText", "stroke", "fill"], function (setting) { + newSettings[setting] = series.get(setting); + }); + return newSettings; + } + + function setSeriesType(seriesType) { + // Get current series and its settings + var currentSeries = stockChart.get("stockSeries"); + var newSettings = getNewSettings(currentSeries); + + // Remove previous series + var data = currentSeries.data.values; + mainPanel.series.removeValue(currentSeries); + + // Create new series + var series; + switch (seriesType) { + case "line": + series = mainPanel.series.push(am5xy.LineSeries.new(root, newSettings)); + break; + case "candlestick": + case "procandlestick": + newSettings.clustered = false; + series = mainPanel.series.push(am5xy.CandlestickSeries.new(root, newSettings)); + if (seriesType == "procandlestick") { + series.columns.template.get("themeTags").push("pro"); + } + break; + case "ohlc": + newSettings.clustered = false; + series = mainPanel.series.push(am5xy.OHLCSeries.new(root, newSettings)); + break; + } + + // Set new series as stockSeries + if (series) { + valueLegend.data.removeValue(currentSeries); + series.data.setAll(data); + stockChart.set("stockSeries", series); + var cursor = mainPanel.get("cursor"); + if (cursor) { + cursor.set("snapToSeries", [series]); + } + valueLegend.data.insertIndex(0, series); + } + } + + + // Stock toolbar + // ------------------------------------------------------------------------------- + // https://www.amcharts.com/docs/v5/charts/stock/toolbar/ + var toolbar = am5stock.StockToolbar.new(root, { + container: document.getElementById("chartcontrols"), + stockChart: stockChart, + controls: [ + am5stock.IndicatorControl.new(root, { + stockChart: stockChart, + legend: valueLegend + }), + am5stock.DateRangeSelector.new(root, { + stockChart: stockChart + }), + am5stock.PeriodSelector.new(root, { + stockChart: stockChart + }), + seriesSwitcher, + am5stock.DrawingControl.new(root, { + stockChart: stockChart + }), + am5stock.ResetControl.new(root, { + stockChart: stockChart + }), + am5stock.SettingsControl.new(root, { + stockChart: stockChart + }) + ] + }) + + // data + var data = this.data; + + var tooltip = am5.Tooltip.new(root, { + getStrokeFromSprite: false, + getFillFromSprite: false + }); + + tooltip.get("background").setAll({ + strokeOpacity: 1, + stroke: am5.color(0x000000), + fillOpacity: 1, + fill: am5.color(0xffffff) + }); + + + function makeEvent(date, letter, color, description) { + var dataItem = dateAxis.createAxisRange(dateAxis.makeDataItem({ value: date })) + var grid = dataItem.get("grid"); + if (grid) { + grid.setAll({ visible: true, strokeOpacity: 0.2, strokeDasharray: [3, 3] }) + } + + var bullet = am5.Container.new(root, { + dy: -100 + }); + + var circle = bullet.children.push(am5.Circle.new(root, { + radius: 10, + stroke: color, + fill: am5.color(0xffffff), + tooltipText: description, + tooltip: tooltip, + tooltipY: 0 + })); + + var label = bullet.children.push(am5.Label.new(root, { + text: letter, + centerX: am5.p50, + centerY: am5.p50 + })); + + dataItem.set("bullet", am5xy.AxisBullet.new(root, { + location: 0, + stacked: true, + sprite: bullet + })); + } + + // set data to all series + valueSeries.data.setAll(data); + volumeSeries.data.setAll(data); + sbSeries.data.setAll(data); + + }); // end am5.ready() + } + } +}) \ No newline at end of file diff --git a/web/glacier-exchange/chall/assets/scripts/index.js b/web/glacier-exchange/chall/assets/scripts/index.js new file mode 100644 index 0000000..cccba91 --- /dev/null +++ b/web/glacier-exchange/chall/assets/scripts/index.js @@ -0,0 +1,103 @@ + +(function() { + new Vue({ + el: '#app', + data: { + dropdownVisibility: { + source: false, + target: false + }, + sourceCoinAmount: 0, + sourceCoinFilter: '', + targetCoinFilter: '', + sourceCoinValue: 'cashout', + targetCoinValue: 'ascoin', + balances: [], + coins: [], + club: false + }, + methods: { + changeSourceCoin(name) { + this.sourceCoinValue = name; + this.dropdownVisibility.source = false; + this.sourceCoinFilter = ''; + }, + changeTargetCoin(name) { + this.targetCoinValue = name; + this.dropdownVisibility.target = false; + this.targetCoinFilter = ''; + }, + swapCoins() { + const tmp = this.sourceCoinValue; + this.sourceCoinValue = this.targetCoinValue; + this.targetCoinValue = tmp; + }, + fetchCoins() { + fetch("/api/fetch_coins").then(res => res.json()).then(coins => { + this.coins = coins; + }) + }, + fetchBalances() { + fetch("/api/wallet/balances").then(res => res.json()).then(balances => { + this.balances = balances; + }) + }, + convert() { + fetch("/api/wallet/transaction", { + method: "POST", + body: JSON.stringify({ + sourceCoin: this.sourceCoinValue, + targetCoin: this.targetCoinValue, + balance: this.sourceCoinAmount + }), + headers: { + "Content-Type": "application/json" + } + }).then(_ => { + this.fetchBalances(); + this.sourceCoinAmount = 0; + }) + }, + joinGlacierClub() { + fetch("/api/wallet/join_glacier_club", {method: "POST"}).then(res => res.json()).then(club => { + this.club = club; + this.$refs.modalGlacierclub.classList.add('is-active') + }) + }, + closeClubModal() { + this.$refs.modalGlacierclub.classList.remove('is-active') + } + }, + computed: { + filteredSourceCoins() { + return this.coins.filter(coin => coin.value.includes(this.sourceCoinFilter) && coin.name !== this.targetCoinValue); + }, + filteredTargetCoins() { + return this.coins.filter(coin => coin.value.includes(this.targetCoinFilter) && coin.name !== this.sourceCoinValue); + }, + sourceCoin() { + return this.coins.filter(coin => coin.name === this.sourceCoinValue)[0]; + }, + targetCoin() { + return this.coins.filter(coin => coin.name === this.targetCoinValue)[0]; + } + }, + mounted() { + this.fetchCoins(); + this.fetchBalances(); + }, + delimiters: ['$$', '$$'], + }) +})(); + +(function() { + setInterval(_ => { + document.querySelectorAll("[data-adjust-width-to]").forEach(element => { + const referenceElementId = element.dataset.adjustWidthTo; + if(!referenceElementId) return; + const referenceElement = document.getElementById(referenceElementId); + if(!referenceElement) return; + element.style.width = `${referenceElement.offsetWidth}px`; + }) + }) +})(); \ No newline at end of file diff --git a/web/glacier-exchange/chall/assets/styles/main.css b/web/glacier-exchange/chall/assets/styles/main.css new file mode 100644 index 0000000..75c6a15 --- /dev/null +++ b/web/glacier-exchange/chall/assets/styles/main.css @@ -0,0 +1,141 @@ +html { + background: url(/assets/images/bg.jpg) no-repeat center center fixed; + -webkit-background-size: cover; + -moz-background-size: cover; + -o-background-size: cover; + background-size: cover; +} + +.box { + background-color: #27273e; + opacity: 0.9; + /* min-height: 500px; */ +} + +.textfield-area { + border: 1px solid #72727b; + border-radius: 10px; + padding: 10px; +} + +.textfield-area .button { + color: white; + background: transparent; + border: none; +} + +.textfield-area input:hover { + color: white; +} + +.textfield-area input { + background-color: transparent; + border: none; + color: white; + font-size: 20px; + width: 100%; +} + +.textfield-area label { + font-size: 12px; +} + +.textfield-area input:focus, +.textfield-area .button:focus, +.textfield-area .button:focus-visible, +.select-area .input:focus, +.select-area .input:active { + outline: 0 !important; + box-shadow: none !important; +} + +.select-area { + height: 0; +} + +.select-area .input, +.select-area .input:focus, +.select-area .input::placeholder { + background: #3b3b4f; + color: white; + border: none; +} + +.select-area .control.has-icons-right .input:focus~.icon { + color: #dbdbdb; +} + +.select-area .dropdown-item { + font-size: 0.75rem; +} + +.select-area .dropdown-menu { + padding-top: 0; + min-width: 0; +} + +.select-area a.dropdown-item { + padding-right: 1rem; + color: white; +} + +.select-area .dropdown-content { + background: #27273e; + border: 1px solid #353544; + border-radius: 0px 0px 2px 2px; + padding: 0px; +} + +.select-area .dropdown-item:hover { + background: #1e1e31; +} + +.rotate-area i { + border-radius: 5px; + padding: 5px; + background-color: #3a3a57; + font-size: 30px; + color: #15b1d5; +} + +.rotate-area i:hover { + background-color: #151522; + cursor: pointer; +} + + +/** Chart library style **/ + +#chartcontrols { + height: auto; + padding: 5px 5px 0 16px; + max-width: 100%; +} + +#chartdiv { + width: 100%; + height: 600px; + max-width: 100%; +} + +.balance .table { + background-color: transparent; + color: white; + width: 100%; +} + +.balance .table th { + background-color: transparent; + color: white; +} + +.fancy-button button, +.fancy-button button:focus, +.fancy-button button:hover, +.fancy-button button::placeholder { + background-color: #90b4ce; + border-color: #02375e; + border-width: 2px; + color: #111160; +} + diff --git a/web/glacier-exchange/chall/requirements.txt b/web/glacier-exchange/chall/requirements.txt new file mode 100755 index 0000000..1aff942 --- /dev/null +++ b/web/glacier-exchange/chall/requirements.txt @@ -0,0 +1,2 @@ +flask +flask_restful \ No newline at end of file diff --git a/web/glacier-exchange/chall/server.py b/web/glacier-exchange/chall/server.py new file mode 100755 index 0000000..2f4ee5f --- /dev/null +++ b/web/glacier-exchange/chall/server.py @@ -0,0 +1,123 @@ +from flask import Flask, render_template, request, send_from_directory, jsonify, session +from flask_restful import Api +from src.coin_api import get_coin_price_from_api +from src.wallet import Wallet +import os +import secrets + +app = Flask(__name__) +api = Api(app) + +app.secret_key = os.urandom(64) + +wallets = {} +def get_wallet_from_session(): + if "id" not in session: + session["id"] = make_token() + if session["id"] not in wallets: + wallets[session["id"]] = Wallet() + return wallets[session["id"]] + +def make_token(): + return secrets.token_urlsafe(16) + +@app.route("/", methods=["GET", "POST"]) +def index(): + return render_template( + "index.html", + ) + +@app.route('/assets/') +def assets(path): + return send_from_directory('assets', path) + +@app.route('/api/data/fetch/') +def fetch(coin: str): + data = get_coin_price_from_api(coin) + return jsonify(data) + +@app.route('/api/wallet/transaction', methods=['POST']) +def transaction(): + payload = request.json + status = 0 + if "sourceCoin" in payload and "targetCoin" in payload and "balance" in payload: + wallet = get_wallet_from_session() + status = wallet.transaction(payload["sourceCoin"], payload["targetCoin"], float(payload["balance"])) + return jsonify({ + "result": status + }) + +@app.route("/api/wallet/join_glacier_club", methods=["POST"]) +def join_glacier_club(): + wallet = get_wallet_from_session() + clubToken = False + inClub = wallet.inGlacierClub() + if inClub: + f = open("/flag.txt") + clubToken = f.read() + f.close() + return { + "inClub": inClub, + "clubToken": clubToken + } + +@app.route('/api/wallet/balances') +def get_balance(): + wallet = get_wallet_from_session() + balances = wallet.getBalances() + user_balances = [] + for name in balances: + user_balances.append({ + "name": name, + "value": balances[name] + }) + return user_balances + +@app.route('/api/fetch_coins') +def fetch_coins(): + return jsonify([ + { + "name": 'cashout', + "value": 'Cashout Account', + "short": 'CA' + }, + { + "name": 'glaciercoin', + "value": 'GlacierCoin', + "short": 'GC' + }, + { + "name": 'ascoin', + "value": 'AsCoin', + "short": 'AC' + }, + { + "name": 'doge', + "value": 'Doge', + "short": 'DO' + }, + { + "name": 'gamestock', + "value": 'Gamestock', + "short": 'GS' + }, + { + "name": 'ycmi', + "value": 'Yeti Clubs Manufacturing Inc.', + "short": 'YC' + }, + { + "name": 'smtl', + "value": 'Synthetic Mammoth Tusks LLC', + "short": 'ST' + }, + ]) + + + +if __name__ == '__main__': + app.run( + host="0.0.0.0", + port=8080, + debug=True, + ) diff --git a/web/glacier-exchange/chall/src/coin_api.py b/web/glacier-exchange/chall/src/coin_api.py new file mode 100644 index 0000000..ef01a76 --- /dev/null +++ b/web/glacier-exchange/chall/src/coin_api.py @@ -0,0 +1,48 @@ +import time +import random + +def get_coin_price_from_api(coin: str): + coins = coin.split('/') + if(len(coins) != 2): + return [] + seed = coins[0] + coins[1] if coins[0] < coins[1] else coins[1] + coins[0] + is_reverse = coins[0] < coins[1] + random.seed(seed) + end_timestamp = int(time.time()) * 1000 + + new_open = 15.67 + new_high = 15.83 + new_low = 15.24 + new_close = 15.36 + + new_volume = 3503100 + movement = 0.7 + + data = [] + max_ticks = 200 + for ts in range(0, max_ticks): + + display_new_open = 1. / new_open if is_reverse else new_open + display_new_high = 1. / new_high if is_reverse else new_high + display_new_low = 1. / new_low if is_reverse else new_low + display_new_close = 1. / new_close if is_reverse else new_close + + data.append({ + "Date": end_timestamp - (max_ticks - ts) * (1000 * 86400), + "Open": display_new_open, + "High": display_new_high, + "Low": display_new_low, + "Close": display_new_close, + "Volume": new_volume + }) + + # New Open => Downwards Trend + # New Close => Upwards Trend + indicator = new_open if random.random() > 0.5 else new_close + + new_open = indicator + movement * (random.random() - 0.5) + new_high = indicator + movement * (random.random() - 0.5) + new_low = indicator + movement * (random.random() - 0.5) + new_close = indicator + movement * (random.random() - 0.5) + new_volume = new_volume + movement * (random.random() - 0.5) + return data diff --git a/web/glacier-exchange/chall/src/wallet.py b/web/glacier-exchange/chall/src/wallet.py new file mode 100644 index 0000000..61ce24e --- /dev/null +++ b/web/glacier-exchange/chall/src/wallet.py @@ -0,0 +1,39 @@ +import threading + + +class Wallet(): + def __init__(self) -> None: + self.balances = { + "cashout": 1000, + "glaciercoin": 0, + "ascoin": 0, + "doge": 0, + "gamestock": 0, + "ycmi": 0, + "smtl": 0 + } + self.lock = threading.Lock(); + + + def getBalances(self): + return self.balances + + def transaction(self, source, dest, amount): + if source in self.balances and dest in self.balances: + with self.lock: + if self.balances[source] >= amount: + self.balances[source] -= amount + self.balances[dest] += amount + return 1 + return 0 + + def inGlacierClub(self): + with self.lock: + for balance_name in self.balances: + if balance_name == "cashout": + if self.balances[balance_name] < 1000000000: + return False + else: + if self.balances[balance_name] != 0.0: + return False + return True diff --git a/web/glacier-exchange/chall/templates/index.html b/web/glacier-exchange/chall/templates/index.html new file mode 100755 index 0000000..5114306 --- /dev/null +++ b/web/glacier-exchange/chall/templates/index.html @@ -0,0 +1,201 @@ + + + + + + + GlacierExchange + + + + + + + +
+
+
+
+
+ +
+
+
+

Your Balance

+ + + + + + + + + + + + + + + + + + +
CoinBalance
$$ balance.name $$$$ balance.value $$
+
+ +
+
+
+
+

GlacierExchange

+ +

+ The GlacierExchange is a revolutionary tool for converting glacierchain coins from one + currency to another. + The conversion rate is always guaranteed to be 1:1 without fees. +

+ +
+
+
+ + +
+
+ +
+
+
+ +
+
+ +
+
+ + +
+ +
+ + +
+
+
+ + +
+
+ +
+
+
+ +
+
+ +
+
+ + +
+ +
+
+
+
+ +
+
+ +
+ + + + + + + + + + + + + \ No newline at end of file diff --git a/web/glacier-exchange/glacier_exchange.zip b/web/glacier-exchange/glacier_exchange.zip new file mode 100644 index 0000000..123d054 Binary files /dev/null and b/web/glacier-exchange/glacier_exchange.zip differ diff --git a/web/peak/README.md b/web/peak/README.md new file mode 100644 index 0000000..631d139 --- /dev/null +++ b/web/peak/README.md @@ -0,0 +1 @@ +Within the heart of Austria's alpine mystery lies your next conquest. Ascend the highest peak, shrouded in whispers of past explorers, to uncover the flag.txt awaiting atop. Beware the silent guards that stand sentinel along the treacherous path, obstructing your ascent. \ No newline at end of file diff --git a/web/peak/challenge.zip b/web/peak/challenge.zip new file mode 100644 index 0000000..e79dc87 Binary files /dev/null and b/web/peak/challenge.zip differ diff --git a/web/peak/dist/.docker/Dockerfile-web b/web/peak/dist/.docker/Dockerfile-web new file mode 100644 index 0000000..861da94 --- /dev/null +++ b/web/peak/dist/.docker/Dockerfile-web @@ -0,0 +1,53 @@ +FROM tobi312/php:8.1-apache +WORKDIR /var/www/html + +COPY ./web/ /var/www/html/ +COPY ./flag/flag.txt / + +RUN mkdir -p /var/sqlite/ +COPY ./sqlite.db /var/sqlite/ + +RUN chown -R 33:33 /var/sqlite/ +RUN chmod 750 /var/sqlite/sqlite.db +RUN mkdir -p /var/www/html/uploads/ +RUN chown 33:33 /var/www/html/uploads/ +RUN chmod -R 777 /var/www/html/uploads/ + +USER root + +RUN ln -s /dev/null /root/.bash_history + +ARG DEBIAN_FRONTEND=noninteractive + +RUN apt-get update && apt-get install -y \ + python3 python3-pip curl unzip wget cron util-linux \ + fonts-liberation libasound2 libatk-bridge2.0-0 procps \ + libnss3 lsb-release xdg-utils libxss1 libdbus-glib-1-2 \ + libcairo2 libcups2 libgbm1 libgtk-3-0 libpango-1.0-0 \ + libu2f-udev libvulkan1 libxkbcommon-x11-0 xvfb + +RUN CHROMEDRIVER_VERSION=`curl -sS https://googlechromelabs.github.io/chrome-for-testing/LATEST_RELEASE_STABLE` && \ + wget -q -O chromedriver_linux64.zip https://edgedl.me.gvt1.com/edgedl/chrome/chrome-for-testing/$CHROMEDRIVER_VERSION/linux64/chromedriver-linux64.zip && \ + unzip chromedriver_linux64.zip && mv chromedriver-linux64/chromedriver /usr/bin/ && \ + chmod +x /usr/bin/chromedriver && \ + rm chromedriver_linux64.zip && rm -r chromedriver-linux64 + +RUN CHROME_SETUP=google-chrome.deb && \ + wget -q -O $CHROME_SETUP "https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb" && \ + dpkg -i $CHROME_SETUP && \ + apt-get install -y -f && \ + rm $CHROME_SETUP + +RUN rm /usr/lib/python3.11/EXTERNALLY-MANAGED + +RUN python3 -m pip install selenium urllib3 python-decouple requests bs4 pyvirtualdisplay + +COPY ./admin-simulation/ /root/admin_simulation + +RUN echo '#!/bin/bash' > /entrypoint.d/simulation.sh +RUN echo 'echo "$(env | grep "HOST=.*")" >> /etc/environment' >> /entrypoint.d/simulation.sh +RUN echo 'echo "$(env | grep "ADMIN_PW=.*")" >> /etc/environment' >> /entrypoint.d/simulation.sh +RUN echo 'service cron start' >> /entrypoint.d/simulation.sh +RUN chmod +x /entrypoint.d/simulation.sh + +RUN echo '* * * * * root /usr/bin/flock -w 0 /var/cron.lock python3 /root/admin_simulation/admin.py "$ADMIN_PW" > /var/log/admin_simulation.log 2> /var/log/admin_simulation.error' >> /etc/crontab diff --git a/web/peak/dist/admin-simulation/admin.py b/web/peak/dist/admin-simulation/admin.py new file mode 100644 index 0000000..55d367e --- /dev/null +++ b/web/peak/dist/admin-simulation/admin.py @@ -0,0 +1,153 @@ +#!/usr/bin/env python3 +import sys, requests +import os +from time import sleep +from bs4 import BeautifulSoup +from datetime import datetime + + +from selenium import webdriver +from selenium.webdriver.support import expected_conditions as EC +from selenium.webdriver.support.ui import WebDriverWait +from selenium.webdriver.chrome.service import Service +from selenium.webdriver.common.action_chains import ActionChains +from selenium.webdriver.common.by import By +from pyvirtualdisplay import Display + + +import urllib3 +urllib3.disable_warnings() + +class AdminAutomation: + host = os.environ.get("HOST", "http://web") + timeout = int(os.environ.get("TIMEOUT", "5")) + driver = None + _username = 'admin' + _password = '' + + display = Display(visible=0, size=(800, 600)) + display.start() + + def __init__(self, password:str=''): + + chrome_options = self._set_chrome_options() + service = Service(executable_path=r'/usr/bin/chromedriver') + self.driver = webdriver.Chrome(service=service, options=chrome_options) + self.driver.set_page_load_timeout(self.timeout) + + self._password = password + if self._password == '': + raise Exception('No password for admin configured!') + + def _set_chrome_options(self): + ''' + Sets chrome options for Selenium: + - headless browser is enabled + - sandbox is disbaled + - dev-shm usage is disabled + - SSL certificate errors are ignored + ''' + chrome_options = webdriver.ChromeOptions() + + options = [ + '--headless', + '--no-sandbox', '--disable-dev-shm-usage', '--ignore-certificate-errors', + '--disable-extensions', '--no-first-run', '--disable-logging', + '--disable-notifications', '--disable-permissions-api', '--hide-scrollbars', + '--disable-gpu', '--window-size=800,600', '--disable-xss-auditor' + ] + + + for option in options: + chrome_options.add_argument(option) + return chrome_options + + def login(self) -> bool: + ''' + Login as admin + - Returns: `True` if successful and `False` of unsuccessful + ''' + self.driver.get(f'{self.host}/login.php') + + + WebDriverWait(self.driver, 10).until(EC.presence_of_element_located((By.NAME, 'username'))) + self.driver.find_element('name', 'username').send_keys('admin') + + + WebDriverWait(self.driver, 10).until(EC.presence_of_element_located((By.NAME, 'password'))) + self.driver.find_element('name', 'password').send_keys(self._password) + + + WebDriverWait(self.driver, 10).until(EC.element_to_be_clickable((By.NAME, 'button'))) + self.driver.find_element('name', 'button').click() + + + if self.driver.current_url != f'{self.host}/': + return False + + print(f'[{datetime.now()}] Successfully logged in!\r\n') + return True + + def read_messages(self): + + print(f'[{datetime.now()}] Checking messages...') + self.driver.get(f'{self.host}/admin/support.php') + + if self.driver.current_url != f'{self.host}/admin/support.php': + raise Exception("Cannot access support.php! Session probably expired!") + + links = [element.get_attribute('href') for element in self.driver.find_elements('name', 'inbox-header')] + if len(links) > 0: + for link in links: + if link: + try: + self.driver.get(link) + + if self.driver.current_url == link: + print(f'[{datetime.now()}] Visiting: {self.driver.current_url}\r\n') + else: + print(f'[{datetime.now()}] After visiting {link}, got redirect to: {self.driver.current_url}\r\n') + except Exception as ex: + '''Timeout or other exception occurred on url. + ''' + print(f'[{datetime.now()}] Error after visiting: {link} (Current URL: {self.driver.current_url}). Error: {ex}\r\n') + + def close(self): + + if self.driver: + self.driver.close() + self.driver.quit() + self.driver = None + if self.display: + self.display.stop() + +if __name__ == '__main__': + + os.system('pkill -f chrome') + os.system('pkill -f Xvfb') + + admin = None + try: + if len(sys.argv) < 2: + raise Exception('Specify a password!') + admin = AdminAutomation(sys.argv[1]) + + tries = 0 + while not admin.login(): + if tries > 5: + raise Exception('Could not login!') + tries += 1 + sleep(1) + + while True: + admin.read_messages() + sleep(5) + + admin.close() + quit() + except Exception as ex: + print(f'[-] Error: {ex}') + + if admin is not None: + admin.close() + quit() diff --git a/web/peak/dist/docker-compose.yml b/web/peak/dist/docker-compose.yml new file mode 100644 index 0000000..62185d1 --- /dev/null +++ b/web/peak/dist/docker-compose.yml @@ -0,0 +1,16 @@ +version: "3" + +services: + web: + build: + context: . + dockerfile: .docker/Dockerfile-web + image: webserver + container_name: webserver + restart: always + hostname: webserver + environment: + ADMIN_PW: example-password + HOST: http://localhost + ports: + - "80:80" \ No newline at end of file diff --git a/web/peak/dist/flag/flag.txt b/web/peak/dist/flag/flag.txt new file mode 100644 index 0000000..bcbae7b --- /dev/null +++ b/web/peak/dist/flag/flag.txt @@ -0,0 +1 @@ +gctf{SOME_FLAG} \ No newline at end of file diff --git a/web/peak/dist/sqlite.db b/web/peak/dist/sqlite.db new file mode 100644 index 0000000..e69de29 diff --git a/web/peak/dist/web/actions/contact.php b/web/peak/dist/web/actions/contact.php new file mode 100644 index 0000000..b03914c --- /dev/null +++ b/web/peak/dist/web/actions/contact.php @@ -0,0 +1,100 @@ + 0) + { + foreach ($files as $file) + { + if ($file !== '.' && $file !== '..' && $file !== '.htaccess') + { + $filePath = $uploadsDirectory . '/' . $file; + if (is_file($filePath)) + { + $fileTimestamp = filemtime($filePath); + $timeDifference = $currentTimestamp - $fileTimestamp; + // Check if the file is older than 5 minutes (300 seconds) + if ($timeDifference > 300) + unlink($filePath); + } + } + } + } +} + +try +{ + if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_SESSION['user']) && $_SESSION['user']['role'] !== "admin") + { + if(isset($_POST['title']) && isset($_POST['content'])) + { + cleanup_old_files(); + + $target_file = ""; + if(isset($_FILES['image']) && $_FILES['image']['name'] !== "") + { + $targetDirectory = '/uploads/'; + + $timestamp = microtime(true); + $timestampStr = str_replace('.', '', sprintf('%0.6f', $timestamp)); + + $randomFilename = uniqid() . $timestampStr; + $targetFile = ".." . $targetDirectory . $randomFilename; + $imageFileType = strtolower(pathinfo($_FILES['image']['name'], PATHINFO_EXTENSION)); + $allowedExtensions = ['jpg', 'jpeg', 'png']; + + $check = false; + try + { + $check = @getimagesize($_FILES['image']['tmp_name']); + } + catch(Exception $exx) + { + throw new Exception("File is not a valid image!"); + } + if ($check === false) + { + throw new Exception("File is not a valid image!"); + } + if (!in_array($imageFileType, $allowedExtensions)) + { + throw new Exception("Invalid image file type. Allowed types: jpg, jpeg, png"); + } + if (!move_uploaded_file($_FILES['image']['tmp_name'], $targetFile)) + { + throw new Exception("Error uploading the image! Try again! If this issue persists, contact a CTF admin!"); + } + $target_file = $targetDirectory . $randomFilename; + } + + $title = $_POST['title']; + $content = $_POST['content']; + $user_id = $_SESSION['user']['id']; + + $sql = $pdo->prepare("INSERT INTO messages (title, content, file, user_id) VALUES (:title, :content, :file, :user_id)"); + $sql->bindParam(':title', $title, PDO::PARAM_STR); + $sql->bindParam(':content', $content, PDO::PARAM_STR); + $sql->bindParam(':user_id', $user_id, PDO::PARAM_INT); + $sql->bindParam(':file', $target_file, PDO::PARAM_STR); + + try + { + $sql->execute(); + } + catch (PDOException $e) + { + throw new Exception("Could not create request. Please try again! If this issue persists, contact a CTF admin!"); + } + $_SESSION['success'] = "Message received! An admin will handle your request shortly. You can view your request here"; + } + } +} +catch(Exception $ex) +{ + $_SESSION['error'] = htmlentities($ex->getMessage()); +} +header('Location: /pages/contact.php'); \ No newline at end of file diff --git a/web/peak/dist/web/actions/login.php b/web/peak/dist/web/actions/login.php new file mode 100644 index 0000000..5872ea2 --- /dev/null +++ b/web/peak/dist/web/actions/login.php @@ -0,0 +1,53 @@ +prepare("SELECT * FROM users WHERE username=:name"); + $sql->bindValue(':name', $username); + $sql->execute(); + $user = $sql->fetch(); + + if ($user) + { + $id = $user["id"]; + $username = $user["username"]; + $role = $user["role"]; + + if(password_verify($password, $user["password"])) + { + $_SESSION['user'] = array(); + $_SESSION['user']['id'] = $id; + $_SESSION['user']['username'] = $username; + $_SESSION['user']['role'] = $role; + header('Location: /'); + } + else + { + throw new Exception("Invalid username or password!"); + } + } + else + { + throw new Exception("Invalid username or password!"); + } + } + else + { + throw new Exception("Username and Password required!"); + } + } +} +catch(Exception $ex) +{ + $_SESSION['error'] = htmlentities($ex->getMessage()); + header('Location: /login.php'); +} +?> \ No newline at end of file diff --git a/web/peak/dist/web/actions/logout.php b/web/peak/dist/web/actions/logout.php new file mode 100644 index 0000000..de42f64 --- /dev/null +++ b/web/peak/dist/web/actions/logout.php @@ -0,0 +1,5 @@ + \ No newline at end of file diff --git a/web/peak/dist/web/actions/register.php b/web/peak/dist/web/actions/register.php new file mode 100644 index 0000000..26e4204 --- /dev/null +++ b/web/peak/dist/web/actions/register.php @@ -0,0 +1,53 @@ +prepare("INSERT INTO users (username, password) VALUES (:username, :password)"); + $sql->bindParam(':username', $username, PDO::PARAM_STR); + $sql->bindParam(':password', $hashedPassword, PDO::PARAM_STR); + + try + { + $sql->execute(); + + $sql = $pdo->prepare("SELECT * FROM users WHERE username=:name"); + $sql->bindValue(':name', $username); + $sql->execute(); + $user = $sql->fetch(); + + if ($user) + { + $id = $user["id"]; + $username = $user["username"]; + $role = $user["role"]; + + $_SESSION['user'] = array(); + $_SESSION['user']['id'] = $id; + $_SESSION['user']['username'] = $username; + $_SESSION['user']['role'] = $role; + header('Location: /'); + } + } + catch (PDOException $e) + { + throw new Exception("Could not register with this username! Try again with a different name."); + } + } + } +} +catch(Exception $ex) +{ + $_SESSION['error'] = htmlentities($ex->getMessage()); + header('Location: /login.php'); +} +?> \ No newline at end of file diff --git a/web/peak/dist/web/admin/data.example b/web/peak/dist/web/admin/data.example new file mode 100644 index 0000000..0d42e21 --- /dev/null +++ b/web/peak/dist/web/admin/data.example @@ -0,0 +1,7 @@ + + + 47.0748663672 + 12.695247219 + Großglockner + + \ No newline at end of file diff --git a/web/peak/dist/web/admin/includes/session.php b/web/peak/dist/web/admin/includes/session.php new file mode 100644 index 0000000..67c3064 --- /dev/null +++ b/web/peak/dist/web/admin/includes/session.php @@ -0,0 +1,27 @@ +prepare("SELECT * FROM users WHERE id=:id"); + $sql->bindValue(':id', $_SESSION['user']['id']); + $sql->execute(); + $user = $sql->fetch(); + + if ($user && $user["role"] === "admin") + { + $id = $user["id"]; + $username = $user["username"]; + $role = $user["role"]; + $_SESSION['user'] = array(); + $_SESSION['user']['id'] = $id; + $_SESSION['user']['username'] = $username; + $_SESSION['user']['role'] = $role; + return; + } +} +session_destroy(); +header('Location: /login.php'); +return; +?> \ No newline at end of file diff --git a/web/peak/dist/web/admin/map.php b/web/peak/dist/web/admin/map.php new file mode 100644 index 0000000..7961c85 --- /dev/null +++ b/web/peak/dist/web/admin/map.php @@ -0,0 +1,87 @@ + + + + + + + +
+
+

Edit map

+

Dev-Note: Please note editing map globally is currently not possible! We are working on it.
You can use this site to test out the coordinates for now.

+
+
+ +
+
+ +
+
+
+ +
+
+
+
+
+
+ +
+ + +
+
+
+
+
+
+
+ + diff --git a/web/peak/dist/web/admin/support.php b/web/peak/dist/web/admin/support.php new file mode 100644 index 0000000..d04c93e --- /dev/null +++ b/web/peak/dist/web/admin/support.php @@ -0,0 +1,54 @@ + + + + + + + + query("SELECT * FROM messages")->fetchAll(PDO::FETCH_ASSOC); ?> + +
+
+

Support Requests

+
+
+ +
+
+
    + 0) : ?> + +
  • +
    from + prepare($sql); + $stmt->bindParam(':user_id', $message['user_id'], PDO::PARAM_INT); + $stmt->execute(); + + $result = $stmt->fetch(PDO::FETCH_ASSOC); + + echo htmlentities($result['username']); + ?>
    + Inspect Request +
  • + + +
    +

    No messages available at the moment!

    +
    + +
+
+
+ + diff --git a/web/peak/dist/web/assets/bootstrap.js b/web/peak/dist/web/assets/bootstrap.js new file mode 100644 index 0000000..0317143 --- /dev/null +++ b/web/peak/dist/web/assets/bootstrap.js @@ -0,0 +1,7 @@ +/*! + * Bootstrap v5.2.3 (https://getbootstrap.com/) + * Copyright 2011-2022 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors) + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) + */ +!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e(require("@popperjs/core")):"function"==typeof define&&define.amd?define(["@popperjs/core"],e):(t="undefined"!=typeof globalThis?globalThis:t||self).bootstrap=e(t.Popper)}(this,(function(t){"use strict";function e(t){if(t&&t.__esModule)return t;const e=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(t)for(const i in t)if("default"!==i){const s=Object.getOwnPropertyDescriptor(t,i);Object.defineProperty(e,i,s.get?s:{enumerable:!0,get:()=>t[i]})}return e.default=t,Object.freeze(e)}const i=e(t),s="transitionend",n=t=>{let e=t.getAttribute("data-bs-target");if(!e||"#"===e){let i=t.getAttribute("href");if(!i||!i.includes("#")&&!i.startsWith("."))return null;i.includes("#")&&!i.startsWith("#")&&(i=`#${i.split("#")[1]}`),e=i&&"#"!==i?i.trim():null}return e},o=t=>{const e=n(t);return e&&document.querySelector(e)?e:null},r=t=>{const e=n(t);return e?document.querySelector(e):null},a=t=>{t.dispatchEvent(new Event(s))},l=t=>!(!t||"object"!=typeof t)&&(void 0!==t.jquery&&(t=t[0]),void 0!==t.nodeType),c=t=>l(t)?t.jquery?t[0]:t:"string"==typeof t&&t.length>0?document.querySelector(t):null,h=t=>{if(!l(t)||0===t.getClientRects().length)return!1;const e="visible"===getComputedStyle(t).getPropertyValue("visibility"),i=t.closest("details:not([open])");if(!i)return e;if(i!==t){const e=t.closest("summary");if(e&&e.parentNode!==i)return!1;if(null===e)return!1}return e},d=t=>!t||t.nodeType!==Node.ELEMENT_NODE||!!t.classList.contains("disabled")||(void 0!==t.disabled?t.disabled:t.hasAttribute("disabled")&&"false"!==t.getAttribute("disabled")),u=t=>{if(!document.documentElement.attachShadow)return null;if("function"==typeof t.getRootNode){const e=t.getRootNode();return e instanceof ShadowRoot?e:null}return t instanceof ShadowRoot?t:t.parentNode?u(t.parentNode):null},_=()=>{},g=t=>{t.offsetHeight},f=()=>window.jQuery&&!document.body.hasAttribute("data-bs-no-jquery")?window.jQuery:null,p=[],m=()=>"rtl"===document.documentElement.dir,b=t=>{var e;e=()=>{const e=f();if(e){const i=t.NAME,s=e.fn[i];e.fn[i]=t.jQueryInterface,e.fn[i].Constructor=t,e.fn[i].noConflict=()=>(e.fn[i]=s,t.jQueryInterface)}},"loading"===document.readyState?(p.length||document.addEventListener("DOMContentLoaded",(()=>{for(const t of p)t()})),p.push(e)):e()},v=t=>{"function"==typeof t&&t()},y=(t,e,i=!0)=>{if(!i)return void v(t);const n=(t=>{if(!t)return 0;let{transitionDuration:e,transitionDelay:i}=window.getComputedStyle(t);const s=Number.parseFloat(e),n=Number.parseFloat(i);return s||n?(e=e.split(",")[0],i=i.split(",")[0],1e3*(Number.parseFloat(e)+Number.parseFloat(i))):0})(e)+5;let o=!1;const r=({target:i})=>{i===e&&(o=!0,e.removeEventListener(s,r),v(t))};e.addEventListener(s,r),setTimeout((()=>{o||a(e)}),n)},w=(t,e,i,s)=>{const n=t.length;let o=t.indexOf(e);return-1===o?!i&&s?t[n-1]:t[0]:(o+=i?1:-1,s&&(o=(o+n)%n),t[Math.max(0,Math.min(o,n-1))])},A=/[^.]*(?=\..*)\.|.*/,E=/\..*/,C=/::\d+$/,T={};let k=1;const L={mouseenter:"mouseover",mouseleave:"mouseout"},O=new Set(["click","dblclick","mouseup","mousedown","contextmenu","mousewheel","DOMMouseScroll","mouseover","mouseout","mousemove","selectstart","selectend","keydown","keypress","keyup","orientationchange","touchstart","touchmove","touchend","touchcancel","pointerdown","pointermove","pointerup","pointerleave","pointercancel","gesturestart","gesturechange","gestureend","focus","blur","change","reset","select","submit","focusin","focusout","load","unload","beforeunload","resize","move","DOMContentLoaded","readystatechange","error","abort","scroll"]);function I(t,e){return e&&`${e}::${k++}`||t.uidEvent||k++}function S(t){const e=I(t);return t.uidEvent=e,T[e]=T[e]||{},T[e]}function D(t,e,i=null){return Object.values(t).find((t=>t.callable===e&&t.delegationSelector===i))}function N(t,e,i){const s="string"==typeof e,n=s?i:e||i;let o=j(t);return O.has(o)||(o=t),[s,n,o]}function P(t,e,i,s,n){if("string"!=typeof e||!t)return;let[o,r,a]=N(e,i,s);if(e in L){const t=t=>function(e){if(!e.relatedTarget||e.relatedTarget!==e.delegateTarget&&!e.delegateTarget.contains(e.relatedTarget))return t.call(this,e)};r=t(r)}const l=S(t),c=l[a]||(l[a]={}),h=D(c,r,o?i:null);if(h)return void(h.oneOff=h.oneOff&&n);const d=I(r,e.replace(A,"")),u=o?function(t,e,i){return function s(n){const o=t.querySelectorAll(e);for(let{target:r}=n;r&&r!==this;r=r.parentNode)for(const a of o)if(a===r)return F(n,{delegateTarget:r}),s.oneOff&&$.off(t,n.type,e,i),i.apply(r,[n])}}(t,i,r):function(t,e){return function i(s){return F(s,{delegateTarget:t}),i.oneOff&&$.off(t,s.type,e),e.apply(t,[s])}}(t,r);u.delegationSelector=o?i:null,u.callable=r,u.oneOff=n,u.uidEvent=d,c[d]=u,t.addEventListener(a,u,o)}function x(t,e,i,s,n){const o=D(e[i],s,n);o&&(t.removeEventListener(i,o,Boolean(n)),delete e[i][o.uidEvent])}function M(t,e,i,s){const n=e[i]||{};for(const o of Object.keys(n))if(o.includes(s)){const s=n[o];x(t,e,i,s.callable,s.delegationSelector)}}function j(t){return t=t.replace(E,""),L[t]||t}const $={on(t,e,i,s){P(t,e,i,s,!1)},one(t,e,i,s){P(t,e,i,s,!0)},off(t,e,i,s){if("string"!=typeof e||!t)return;const[n,o,r]=N(e,i,s),a=r!==e,l=S(t),c=l[r]||{},h=e.startsWith(".");if(void 0===o){if(h)for(const i of Object.keys(l))M(t,l,i,e.slice(1));for(const i of Object.keys(c)){const s=i.replace(C,"");if(!a||e.includes(s)){const e=c[i];x(t,l,r,e.callable,e.delegationSelector)}}}else{if(!Object.keys(c).length)return;x(t,l,r,o,n?i:null)}},trigger(t,e,i){if("string"!=typeof e||!t)return null;const s=f();let n=null,o=!0,r=!0,a=!1;e!==j(e)&&s&&(n=s.Event(e,i),s(t).trigger(n),o=!n.isPropagationStopped(),r=!n.isImmediatePropagationStopped(),a=n.isDefaultPrevented());let l=new Event(e,{bubbles:o,cancelable:!0});return l=F(l,i),a&&l.preventDefault(),r&&t.dispatchEvent(l),l.defaultPrevented&&n&&n.preventDefault(),l}};function F(t,e){for(const[i,s]of Object.entries(e||{}))try{t[i]=s}catch(e){Object.defineProperty(t,i,{configurable:!0,get:()=>s})}return t}const z=new Map,H={set(t,e,i){z.has(t)||z.set(t,new Map);const s=z.get(t);s.has(e)||0===s.size?s.set(e,i):console.error(`Bootstrap doesn't allow more than one instance per element. Bound instance: ${Array.from(s.keys())[0]}.`)},get:(t,e)=>z.has(t)&&z.get(t).get(e)||null,remove(t,e){if(!z.has(t))return;const i=z.get(t);i.delete(e),0===i.size&&z.delete(t)}};function q(t){if("true"===t)return!0;if("false"===t)return!1;if(t===Number(t).toString())return Number(t);if(""===t||"null"===t)return null;if("string"!=typeof t)return t;try{return JSON.parse(decodeURIComponent(t))}catch(e){return t}}function B(t){return t.replace(/[A-Z]/g,(t=>`-${t.toLowerCase()}`))}const W={setDataAttribute(t,e,i){t.setAttribute(`data-bs-${B(e)}`,i)},removeDataAttribute(t,e){t.removeAttribute(`data-bs-${B(e)}`)},getDataAttributes(t){if(!t)return{};const e={},i=Object.keys(t.dataset).filter((t=>t.startsWith("bs")&&!t.startsWith("bsConfig")));for(const s of i){let i=s.replace(/^bs/,"");i=i.charAt(0).toLowerCase()+i.slice(1,i.length),e[i]=q(t.dataset[s])}return e},getDataAttribute:(t,e)=>q(t.getAttribute(`data-bs-${B(e)}`))};class R{static get Default(){return{}}static get DefaultType(){return{}}static get NAME(){throw new Error('You have to implement the static method "NAME", for each component!')}_getConfig(t){return t=this._mergeConfigObj(t),t=this._configAfterMerge(t),this._typeCheckConfig(t),t}_configAfterMerge(t){return t}_mergeConfigObj(t,e){const i=l(e)?W.getDataAttribute(e,"config"):{};return{...this.constructor.Default,..."object"==typeof i?i:{},...l(e)?W.getDataAttributes(e):{},..."object"==typeof t?t:{}}}_typeCheckConfig(t,e=this.constructor.DefaultType){for(const s of Object.keys(e)){const n=e[s],o=t[s],r=l(o)?"element":null==(i=o)?`${i}`:Object.prototype.toString.call(i).match(/\s([a-z]+)/i)[1].toLowerCase();if(!new RegExp(n).test(r))throw new TypeError(`${this.constructor.NAME.toUpperCase()}: Option "${s}" provided type "${r}" but expected type "${n}".`)}var i}}class V extends R{constructor(t,e){super(),(t=c(t))&&(this._element=t,this._config=this._getConfig(e),H.set(this._element,this.constructor.DATA_KEY,this))}dispose(){H.remove(this._element,this.constructor.DATA_KEY),$.off(this._element,this.constructor.EVENT_KEY);for(const t of Object.getOwnPropertyNames(this))this[t]=null}_queueCallback(t,e,i=!0){y(t,e,i)}_getConfig(t){return t=this._mergeConfigObj(t,this._element),t=this._configAfterMerge(t),this._typeCheckConfig(t),t}static getInstance(t){return H.get(c(t),this.DATA_KEY)}static getOrCreateInstance(t,e={}){return this.getInstance(t)||new this(t,"object"==typeof e?e:null)}static get VERSION(){return"5.2.3"}static get DATA_KEY(){return`bs.${this.NAME}`}static get EVENT_KEY(){return`.${this.DATA_KEY}`}static eventName(t){return`${t}${this.EVENT_KEY}`}}const K=(t,e="hide")=>{const i=`click.dismiss${t.EVENT_KEY}`,s=t.NAME;$.on(document,i,`[data-bs-dismiss="${s}"]`,(function(i){if(["A","AREA"].includes(this.tagName)&&i.preventDefault(),d(this))return;const n=r(this)||this.closest(`.${s}`);t.getOrCreateInstance(n)[e]()}))};class Q extends V{static get NAME(){return"alert"}close(){if($.trigger(this._element,"close.bs.alert").defaultPrevented)return;this._element.classList.remove("show");const t=this._element.classList.contains("fade");this._queueCallback((()=>this._destroyElement()),this._element,t)}_destroyElement(){this._element.remove(),$.trigger(this._element,"closed.bs.alert"),this.dispose()}static jQueryInterface(t){return this.each((function(){const e=Q.getOrCreateInstance(this);if("string"==typeof t){if(void 0===e[t]||t.startsWith("_")||"constructor"===t)throw new TypeError(`No method named "${t}"`);e[t](this)}}))}}K(Q,"close"),b(Q);const X='[data-bs-toggle="button"]';class Y extends V{static get NAME(){return"button"}toggle(){this._element.setAttribute("aria-pressed",this._element.classList.toggle("active"))}static jQueryInterface(t){return this.each((function(){const e=Y.getOrCreateInstance(this);"toggle"===t&&e[t]()}))}}$.on(document,"click.bs.button.data-api",X,(t=>{t.preventDefault();const e=t.target.closest(X);Y.getOrCreateInstance(e).toggle()})),b(Y);const U={find:(t,e=document.documentElement)=>[].concat(...Element.prototype.querySelectorAll.call(e,t)),findOne:(t,e=document.documentElement)=>Element.prototype.querySelector.call(e,t),children:(t,e)=>[].concat(...t.children).filter((t=>t.matches(e))),parents(t,e){const i=[];let s=t.parentNode.closest(e);for(;s;)i.push(s),s=s.parentNode.closest(e);return i},prev(t,e){let i=t.previousElementSibling;for(;i;){if(i.matches(e))return[i];i=i.previousElementSibling}return[]},next(t,e){let i=t.nextElementSibling;for(;i;){if(i.matches(e))return[i];i=i.nextElementSibling}return[]},focusableChildren(t){const e=["a","button","input","textarea","select","details","[tabindex]",'[contenteditable="true"]'].map((t=>`${t}:not([tabindex^="-"])`)).join(",");return this.find(e,t).filter((t=>!d(t)&&h(t)))}},G={endCallback:null,leftCallback:null,rightCallback:null},J={endCallback:"(function|null)",leftCallback:"(function|null)",rightCallback:"(function|null)"};class Z extends R{constructor(t,e){super(),this._element=t,t&&Z.isSupported()&&(this._config=this._getConfig(e),this._deltaX=0,this._supportPointerEvents=Boolean(window.PointerEvent),this._initEvents())}static get Default(){return G}static get DefaultType(){return J}static get NAME(){return"swipe"}dispose(){$.off(this._element,".bs.swipe")}_start(t){this._supportPointerEvents?this._eventIsPointerPenTouch(t)&&(this._deltaX=t.clientX):this._deltaX=t.touches[0].clientX}_end(t){this._eventIsPointerPenTouch(t)&&(this._deltaX=t.clientX-this._deltaX),this._handleSwipe(),v(this._config.endCallback)}_move(t){this._deltaX=t.touches&&t.touches.length>1?0:t.touches[0].clientX-this._deltaX}_handleSwipe(){const t=Math.abs(this._deltaX);if(t<=40)return;const e=t/this._deltaX;this._deltaX=0,e&&v(e>0?this._config.rightCallback:this._config.leftCallback)}_initEvents(){this._supportPointerEvents?($.on(this._element,"pointerdown.bs.swipe",(t=>this._start(t))),$.on(this._element,"pointerup.bs.swipe",(t=>this._end(t))),this._element.classList.add("pointer-event")):($.on(this._element,"touchstart.bs.swipe",(t=>this._start(t))),$.on(this._element,"touchmove.bs.swipe",(t=>this._move(t))),$.on(this._element,"touchend.bs.swipe",(t=>this._end(t))))}_eventIsPointerPenTouch(t){return this._supportPointerEvents&&("pen"===t.pointerType||"touch"===t.pointerType)}static isSupported(){return"ontouchstart"in document.documentElement||navigator.maxTouchPoints>0}}const tt="next",et="prev",it="left",st="right",nt="slid.bs.carousel",ot="carousel",rt="active",at={ArrowLeft:st,ArrowRight:it},lt={interval:5e3,keyboard:!0,pause:"hover",ride:!1,touch:!0,wrap:!0},ct={interval:"(number|boolean)",keyboard:"boolean",pause:"(string|boolean)",ride:"(boolean|string)",touch:"boolean",wrap:"boolean"};class ht extends V{constructor(t,e){super(t,e),this._interval=null,this._activeElement=null,this._isSliding=!1,this.touchTimeout=null,this._swipeHelper=null,this._indicatorsElement=U.findOne(".carousel-indicators",this._element),this._addEventListeners(),this._config.ride===ot&&this.cycle()}static get Default(){return lt}static get DefaultType(){return ct}static get NAME(){return"carousel"}next(){this._slide(tt)}nextWhenVisible(){!document.hidden&&h(this._element)&&this.next()}prev(){this._slide(et)}pause(){this._isSliding&&a(this._element),this._clearInterval()}cycle(){this._clearInterval(),this._updateInterval(),this._interval=setInterval((()=>this.nextWhenVisible()),this._config.interval)}_maybeEnableCycle(){this._config.ride&&(this._isSliding?$.one(this._element,nt,(()=>this.cycle())):this.cycle())}to(t){const e=this._getItems();if(t>e.length-1||t<0)return;if(this._isSliding)return void $.one(this._element,nt,(()=>this.to(t)));const i=this._getItemIndex(this._getActive());if(i===t)return;const s=t>i?tt:et;this._slide(s,e[t])}dispose(){this._swipeHelper&&this._swipeHelper.dispose(),super.dispose()}_configAfterMerge(t){return t.defaultInterval=t.interval,t}_addEventListeners(){this._config.keyboard&&$.on(this._element,"keydown.bs.carousel",(t=>this._keydown(t))),"hover"===this._config.pause&&($.on(this._element,"mouseenter.bs.carousel",(()=>this.pause())),$.on(this._element,"mouseleave.bs.carousel",(()=>this._maybeEnableCycle()))),this._config.touch&&Z.isSupported()&&this._addTouchEventListeners()}_addTouchEventListeners(){for(const t of U.find(".carousel-item img",this._element))$.on(t,"dragstart.bs.carousel",(t=>t.preventDefault()));const t={leftCallback:()=>this._slide(this._directionToOrder(it)),rightCallback:()=>this._slide(this._directionToOrder(st)),endCallback:()=>{"hover"===this._config.pause&&(this.pause(),this.touchTimeout&&clearTimeout(this.touchTimeout),this.touchTimeout=setTimeout((()=>this._maybeEnableCycle()),500+this._config.interval))}};this._swipeHelper=new Z(this._element,t)}_keydown(t){if(/input|textarea/i.test(t.target.tagName))return;const e=at[t.key];e&&(t.preventDefault(),this._slide(this._directionToOrder(e)))}_getItemIndex(t){return this._getItems().indexOf(t)}_setActiveIndicatorElement(t){if(!this._indicatorsElement)return;const e=U.findOne(".active",this._indicatorsElement);e.classList.remove(rt),e.removeAttribute("aria-current");const i=U.findOne(`[data-bs-slide-to="${t}"]`,this._indicatorsElement);i&&(i.classList.add(rt),i.setAttribute("aria-current","true"))}_updateInterval(){const t=this._activeElement||this._getActive();if(!t)return;const e=Number.parseInt(t.getAttribute("data-bs-interval"),10);this._config.interval=e||this._config.defaultInterval}_slide(t,e=null){if(this._isSliding)return;const i=this._getActive(),s=t===tt,n=e||w(this._getItems(),i,s,this._config.wrap);if(n===i)return;const o=this._getItemIndex(n),r=e=>$.trigger(this._element,e,{relatedTarget:n,direction:this._orderToDirection(t),from:this._getItemIndex(i),to:o});if(r("slide.bs.carousel").defaultPrevented)return;if(!i||!n)return;const a=Boolean(this._interval);this.pause(),this._isSliding=!0,this._setActiveIndicatorElement(o),this._activeElement=n;const l=s?"carousel-item-start":"carousel-item-end",c=s?"carousel-item-next":"carousel-item-prev";n.classList.add(c),g(n),i.classList.add(l),n.classList.add(l),this._queueCallback((()=>{n.classList.remove(l,c),n.classList.add(rt),i.classList.remove(rt,c,l),this._isSliding=!1,r(nt)}),i,this._isAnimated()),a&&this.cycle()}_isAnimated(){return this._element.classList.contains("slide")}_getActive(){return U.findOne(".active.carousel-item",this._element)}_getItems(){return U.find(".carousel-item",this._element)}_clearInterval(){this._interval&&(clearInterval(this._interval),this._interval=null)}_directionToOrder(t){return m()?t===it?et:tt:t===it?tt:et}_orderToDirection(t){return m()?t===et?it:st:t===et?st:it}static jQueryInterface(t){return this.each((function(){const e=ht.getOrCreateInstance(this,t);if("number"!=typeof t){if("string"==typeof t){if(void 0===e[t]||t.startsWith("_")||"constructor"===t)throw new TypeError(`No method named "${t}"`);e[t]()}}else e.to(t)}))}}$.on(document,"click.bs.carousel.data-api","[data-bs-slide], [data-bs-slide-to]",(function(t){const e=r(this);if(!e||!e.classList.contains(ot))return;t.preventDefault();const i=ht.getOrCreateInstance(e),s=this.getAttribute("data-bs-slide-to");return s?(i.to(s),void i._maybeEnableCycle()):"next"===W.getDataAttribute(this,"slide")?(i.next(),void i._maybeEnableCycle()):(i.prev(),void i._maybeEnableCycle())})),$.on(window,"load.bs.carousel.data-api",(()=>{const t=U.find('[data-bs-ride="carousel"]');for(const e of t)ht.getOrCreateInstance(e)})),b(ht);const dt="show",ut="collapse",_t="collapsing",gt='[data-bs-toggle="collapse"]',ft={parent:null,toggle:!0},pt={parent:"(null|element)",toggle:"boolean"};class mt extends V{constructor(t,e){super(t,e),this._isTransitioning=!1,this._triggerArray=[];const i=U.find(gt);for(const t of i){const e=o(t),i=U.find(e).filter((t=>t===this._element));null!==e&&i.length&&this._triggerArray.push(t)}this._initializeChildren(),this._config.parent||this._addAriaAndCollapsedClass(this._triggerArray,this._isShown()),this._config.toggle&&this.toggle()}static get Default(){return ft}static get DefaultType(){return pt}static get NAME(){return"collapse"}toggle(){this._isShown()?this.hide():this.show()}show(){if(this._isTransitioning||this._isShown())return;let t=[];if(this._config.parent&&(t=this._getFirstLevelChildren(".collapse.show, .collapse.collapsing").filter((t=>t!==this._element)).map((t=>mt.getOrCreateInstance(t,{toggle:!1})))),t.length&&t[0]._isTransitioning)return;if($.trigger(this._element,"show.bs.collapse").defaultPrevented)return;for(const e of t)e.hide();const e=this._getDimension();this._element.classList.remove(ut),this._element.classList.add(_t),this._element.style[e]=0,this._addAriaAndCollapsedClass(this._triggerArray,!0),this._isTransitioning=!0;const i=`scroll${e[0].toUpperCase()+e.slice(1)}`;this._queueCallback((()=>{this._isTransitioning=!1,this._element.classList.remove(_t),this._element.classList.add(ut,dt),this._element.style[e]="",$.trigger(this._element,"shown.bs.collapse")}),this._element,!0),this._element.style[e]=`${this._element[i]}px`}hide(){if(this._isTransitioning||!this._isShown())return;if($.trigger(this._element,"hide.bs.collapse").defaultPrevented)return;const t=this._getDimension();this._element.style[t]=`${this._element.getBoundingClientRect()[t]}px`,g(this._element),this._element.classList.add(_t),this._element.classList.remove(ut,dt);for(const t of this._triggerArray){const e=r(t);e&&!this._isShown(e)&&this._addAriaAndCollapsedClass([t],!1)}this._isTransitioning=!0,this._element.style[t]="",this._queueCallback((()=>{this._isTransitioning=!1,this._element.classList.remove(_t),this._element.classList.add(ut),$.trigger(this._element,"hidden.bs.collapse")}),this._element,!0)}_isShown(t=this._element){return t.classList.contains(dt)}_configAfterMerge(t){return t.toggle=Boolean(t.toggle),t.parent=c(t.parent),t}_getDimension(){return this._element.classList.contains("collapse-horizontal")?"width":"height"}_initializeChildren(){if(!this._config.parent)return;const t=this._getFirstLevelChildren(gt);for(const e of t){const t=r(e);t&&this._addAriaAndCollapsedClass([e],this._isShown(t))}}_getFirstLevelChildren(t){const e=U.find(":scope .collapse .collapse",this._config.parent);return U.find(t,this._config.parent).filter((t=>!e.includes(t)))}_addAriaAndCollapsedClass(t,e){if(t.length)for(const i of t)i.classList.toggle("collapsed",!e),i.setAttribute("aria-expanded",e)}static jQueryInterface(t){const e={};return"string"==typeof t&&/show|hide/.test(t)&&(e.toggle=!1),this.each((function(){const i=mt.getOrCreateInstance(this,e);if("string"==typeof t){if(void 0===i[t])throw new TypeError(`No method named "${t}"`);i[t]()}}))}}$.on(document,"click.bs.collapse.data-api",gt,(function(t){("A"===t.target.tagName||t.delegateTarget&&"A"===t.delegateTarget.tagName)&&t.preventDefault();const e=o(this),i=U.find(e);for(const t of i)mt.getOrCreateInstance(t,{toggle:!1}).toggle()})),b(mt);const bt="dropdown",vt="ArrowUp",yt="ArrowDown",wt="click.bs.dropdown.data-api",At="keydown.bs.dropdown.data-api",Et="show",Ct='[data-bs-toggle="dropdown"]:not(.disabled):not(:disabled)',Tt=`${Ct}.show`,kt=".dropdown-menu",Lt=m()?"top-end":"top-start",Ot=m()?"top-start":"top-end",It=m()?"bottom-end":"bottom-start",St=m()?"bottom-start":"bottom-end",Dt=m()?"left-start":"right-start",Nt=m()?"right-start":"left-start",Pt={autoClose:!0,boundary:"clippingParents",display:"dynamic",offset:[0,2],popperConfig:null,reference:"toggle"},xt={autoClose:"(boolean|string)",boundary:"(string|element)",display:"string",offset:"(array|string|function)",popperConfig:"(null|object|function)",reference:"(string|element|object)"};class Mt extends V{constructor(t,e){super(t,e),this._popper=null,this._parent=this._element.parentNode,this._menu=U.next(this._element,kt)[0]||U.prev(this._element,kt)[0]||U.findOne(kt,this._parent),this._inNavbar=this._detectNavbar()}static get Default(){return Pt}static get DefaultType(){return xt}static get NAME(){return bt}toggle(){return this._isShown()?this.hide():this.show()}show(){if(d(this._element)||this._isShown())return;const t={relatedTarget:this._element};if(!$.trigger(this._element,"show.bs.dropdown",t).defaultPrevented){if(this._createPopper(),"ontouchstart"in document.documentElement&&!this._parent.closest(".navbar-nav"))for(const t of[].concat(...document.body.children))$.on(t,"mouseover",_);this._element.focus(),this._element.setAttribute("aria-expanded",!0),this._menu.classList.add(Et),this._element.classList.add(Et),$.trigger(this._element,"shown.bs.dropdown",t)}}hide(){if(d(this._element)||!this._isShown())return;const t={relatedTarget:this._element};this._completeHide(t)}dispose(){this._popper&&this._popper.destroy(),super.dispose()}update(){this._inNavbar=this._detectNavbar(),this._popper&&this._popper.update()}_completeHide(t){if(!$.trigger(this._element,"hide.bs.dropdown",t).defaultPrevented){if("ontouchstart"in document.documentElement)for(const t of[].concat(...document.body.children))$.off(t,"mouseover",_);this._popper&&this._popper.destroy(),this._menu.classList.remove(Et),this._element.classList.remove(Et),this._element.setAttribute("aria-expanded","false"),W.removeDataAttribute(this._menu,"popper"),$.trigger(this._element,"hidden.bs.dropdown",t)}}_getConfig(t){if("object"==typeof(t=super._getConfig(t)).reference&&!l(t.reference)&&"function"!=typeof t.reference.getBoundingClientRect)throw new TypeError(`${bt.toUpperCase()}: Option "reference" provided type "object" without a required "getBoundingClientRect" method.`);return t}_createPopper(){if(void 0===i)throw new TypeError("Bootstrap's dropdowns require Popper (https://popper.js.org)");let t=this._element;"parent"===this._config.reference?t=this._parent:l(this._config.reference)?t=c(this._config.reference):"object"==typeof this._config.reference&&(t=this._config.reference);const e=this._getPopperConfig();this._popper=i.createPopper(t,this._menu,e)}_isShown(){return this._menu.classList.contains(Et)}_getPlacement(){const t=this._parent;if(t.classList.contains("dropend"))return Dt;if(t.classList.contains("dropstart"))return Nt;if(t.classList.contains("dropup-center"))return"top";if(t.classList.contains("dropdown-center"))return"bottom";const e="end"===getComputedStyle(this._menu).getPropertyValue("--bs-position").trim();return t.classList.contains("dropup")?e?Ot:Lt:e?St:It}_detectNavbar(){return null!==this._element.closest(".navbar")}_getOffset(){const{offset:t}=this._config;return"string"==typeof t?t.split(",").map((t=>Number.parseInt(t,10))):"function"==typeof t?e=>t(e,this._element):t}_getPopperConfig(){const t={placement:this._getPlacement(),modifiers:[{name:"preventOverflow",options:{boundary:this._config.boundary}},{name:"offset",options:{offset:this._getOffset()}}]};return(this._inNavbar||"static"===this._config.display)&&(W.setDataAttribute(this._menu,"popper","static"),t.modifiers=[{name:"applyStyles",enabled:!1}]),{...t,..."function"==typeof this._config.popperConfig?this._config.popperConfig(t):this._config.popperConfig}}_selectMenuItem({key:t,target:e}){const i=U.find(".dropdown-menu .dropdown-item:not(.disabled):not(:disabled)",this._menu).filter((t=>h(t)));i.length&&w(i,e,t===yt,!i.includes(e)).focus()}static jQueryInterface(t){return this.each((function(){const e=Mt.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t])throw new TypeError(`No method named "${t}"`);e[t]()}}))}static clearMenus(t){if(2===t.button||"keyup"===t.type&&"Tab"!==t.key)return;const e=U.find(Tt);for(const i of e){const e=Mt.getInstance(i);if(!e||!1===e._config.autoClose)continue;const s=t.composedPath(),n=s.includes(e._menu);if(s.includes(e._element)||"inside"===e._config.autoClose&&!n||"outside"===e._config.autoClose&&n)continue;if(e._menu.contains(t.target)&&("keyup"===t.type&&"Tab"===t.key||/input|select|option|textarea|form/i.test(t.target.tagName)))continue;const o={relatedTarget:e._element};"click"===t.type&&(o.clickEvent=t),e._completeHide(o)}}static dataApiKeydownHandler(t){const e=/input|textarea/i.test(t.target.tagName),i="Escape"===t.key,s=[vt,yt].includes(t.key);if(!s&&!i)return;if(e&&!i)return;t.preventDefault();const n=this.matches(Ct)?this:U.prev(this,Ct)[0]||U.next(this,Ct)[0]||U.findOne(Ct,t.delegateTarget.parentNode),o=Mt.getOrCreateInstance(n);if(s)return t.stopPropagation(),o.show(),void o._selectMenuItem(t);o._isShown()&&(t.stopPropagation(),o.hide(),n.focus())}}$.on(document,At,Ct,Mt.dataApiKeydownHandler),$.on(document,At,kt,Mt.dataApiKeydownHandler),$.on(document,wt,Mt.clearMenus),$.on(document,"keyup.bs.dropdown.data-api",Mt.clearMenus),$.on(document,wt,Ct,(function(t){t.preventDefault(),Mt.getOrCreateInstance(this).toggle()})),b(Mt);const jt=".fixed-top, .fixed-bottom, .is-fixed, .sticky-top",$t=".sticky-top",Ft="padding-right",zt="margin-right";class Ht{constructor(){this._element=document.body}getWidth(){const t=document.documentElement.clientWidth;return Math.abs(window.innerWidth-t)}hide(){const t=this.getWidth();this._disableOverFlow(),this._setElementAttributes(this._element,Ft,(e=>e+t)),this._setElementAttributes(jt,Ft,(e=>e+t)),this._setElementAttributes($t,zt,(e=>e-t))}reset(){this._resetElementAttributes(this._element,"overflow"),this._resetElementAttributes(this._element,Ft),this._resetElementAttributes(jt,Ft),this._resetElementAttributes($t,zt)}isOverflowing(){return this.getWidth()>0}_disableOverFlow(){this._saveInitialAttribute(this._element,"overflow"),this._element.style.overflow="hidden"}_setElementAttributes(t,e,i){const s=this.getWidth();this._applyManipulationCallback(t,(t=>{if(t!==this._element&&window.innerWidth>t.clientWidth+s)return;this._saveInitialAttribute(t,e);const n=window.getComputedStyle(t).getPropertyValue(e);t.style.setProperty(e,`${i(Number.parseFloat(n))}px`)}))}_saveInitialAttribute(t,e){const i=t.style.getPropertyValue(e);i&&W.setDataAttribute(t,e,i)}_resetElementAttributes(t,e){this._applyManipulationCallback(t,(t=>{const i=W.getDataAttribute(t,e);null!==i?(W.removeDataAttribute(t,e),t.style.setProperty(e,i)):t.style.removeProperty(e)}))}_applyManipulationCallback(t,e){if(l(t))e(t);else for(const i of U.find(t,this._element))e(i)}}const qt="show",Bt="mousedown.bs.backdrop",Wt={className:"modal-backdrop",clickCallback:null,isAnimated:!1,isVisible:!0,rootElement:"body"},Rt={className:"string",clickCallback:"(function|null)",isAnimated:"boolean",isVisible:"boolean",rootElement:"(element|string)"};class Vt extends R{constructor(t){super(),this._config=this._getConfig(t),this._isAppended=!1,this._element=null}static get Default(){return Wt}static get DefaultType(){return Rt}static get NAME(){return"backdrop"}show(t){if(!this._config.isVisible)return void v(t);this._append();const e=this._getElement();this._config.isAnimated&&g(e),e.classList.add(qt),this._emulateAnimation((()=>{v(t)}))}hide(t){this._config.isVisible?(this._getElement().classList.remove(qt),this._emulateAnimation((()=>{this.dispose(),v(t)}))):v(t)}dispose(){this._isAppended&&($.off(this._element,Bt),this._element.remove(),this._isAppended=!1)}_getElement(){if(!this._element){const t=document.createElement("div");t.className=this._config.className,this._config.isAnimated&&t.classList.add("fade"),this._element=t}return this._element}_configAfterMerge(t){return t.rootElement=c(t.rootElement),t}_append(){if(this._isAppended)return;const t=this._getElement();this._config.rootElement.append(t),$.on(t,Bt,(()=>{v(this._config.clickCallback)})),this._isAppended=!0}_emulateAnimation(t){y(t,this._getElement(),this._config.isAnimated)}}const Kt=".bs.focustrap",Qt="backward",Xt={autofocus:!0,trapElement:null},Yt={autofocus:"boolean",trapElement:"element"};class Ut extends R{constructor(t){super(),this._config=this._getConfig(t),this._isActive=!1,this._lastTabNavDirection=null}static get Default(){return Xt}static get DefaultType(){return Yt}static get NAME(){return"focustrap"}activate(){this._isActive||(this._config.autofocus&&this._config.trapElement.focus(),$.off(document,Kt),$.on(document,"focusin.bs.focustrap",(t=>this._handleFocusin(t))),$.on(document,"keydown.tab.bs.focustrap",(t=>this._handleKeydown(t))),this._isActive=!0)}deactivate(){this._isActive&&(this._isActive=!1,$.off(document,Kt))}_handleFocusin(t){const{trapElement:e}=this._config;if(t.target===document||t.target===e||e.contains(t.target))return;const i=U.focusableChildren(e);0===i.length?e.focus():this._lastTabNavDirection===Qt?i[i.length-1].focus():i[0].focus()}_handleKeydown(t){"Tab"===t.key&&(this._lastTabNavDirection=t.shiftKey?Qt:"forward")}}const Gt="hidden.bs.modal",Jt="show.bs.modal",Zt="modal-open",te="show",ee="modal-static",ie={backdrop:!0,focus:!0,keyboard:!0},se={backdrop:"(boolean|string)",focus:"boolean",keyboard:"boolean"};class ne extends V{constructor(t,e){super(t,e),this._dialog=U.findOne(".modal-dialog",this._element),this._backdrop=this._initializeBackDrop(),this._focustrap=this._initializeFocusTrap(),this._isShown=!1,this._isTransitioning=!1,this._scrollBar=new Ht,this._addEventListeners()}static get Default(){return ie}static get DefaultType(){return se}static get NAME(){return"modal"}toggle(t){return this._isShown?this.hide():this.show(t)}show(t){this._isShown||this._isTransitioning||$.trigger(this._element,Jt,{relatedTarget:t}).defaultPrevented||(this._isShown=!0,this._isTransitioning=!0,this._scrollBar.hide(),document.body.classList.add(Zt),this._adjustDialog(),this._backdrop.show((()=>this._showElement(t))))}hide(){this._isShown&&!this._isTransitioning&&($.trigger(this._element,"hide.bs.modal").defaultPrevented||(this._isShown=!1,this._isTransitioning=!0,this._focustrap.deactivate(),this._element.classList.remove(te),this._queueCallback((()=>this._hideModal()),this._element,this._isAnimated())))}dispose(){for(const t of[window,this._dialog])$.off(t,".bs.modal");this._backdrop.dispose(),this._focustrap.deactivate(),super.dispose()}handleUpdate(){this._adjustDialog()}_initializeBackDrop(){return new Vt({isVisible:Boolean(this._config.backdrop),isAnimated:this._isAnimated()})}_initializeFocusTrap(){return new Ut({trapElement:this._element})}_showElement(t){document.body.contains(this._element)||document.body.append(this._element),this._element.style.display="block",this._element.removeAttribute("aria-hidden"),this._element.setAttribute("aria-modal",!0),this._element.setAttribute("role","dialog"),this._element.scrollTop=0;const e=U.findOne(".modal-body",this._dialog);e&&(e.scrollTop=0),g(this._element),this._element.classList.add(te),this._queueCallback((()=>{this._config.focus&&this._focustrap.activate(),this._isTransitioning=!1,$.trigger(this._element,"shown.bs.modal",{relatedTarget:t})}),this._dialog,this._isAnimated())}_addEventListeners(){$.on(this._element,"keydown.dismiss.bs.modal",(t=>{if("Escape"===t.key)return this._config.keyboard?(t.preventDefault(),void this.hide()):void this._triggerBackdropTransition()})),$.on(window,"resize.bs.modal",(()=>{this._isShown&&!this._isTransitioning&&this._adjustDialog()})),$.on(this._element,"mousedown.dismiss.bs.modal",(t=>{$.one(this._element,"click.dismiss.bs.modal",(e=>{this._element===t.target&&this._element===e.target&&("static"!==this._config.backdrop?this._config.backdrop&&this.hide():this._triggerBackdropTransition())}))}))}_hideModal(){this._element.style.display="none",this._element.setAttribute("aria-hidden",!0),this._element.removeAttribute("aria-modal"),this._element.removeAttribute("role"),this._isTransitioning=!1,this._backdrop.hide((()=>{document.body.classList.remove(Zt),this._resetAdjustments(),this._scrollBar.reset(),$.trigger(this._element,Gt)}))}_isAnimated(){return this._element.classList.contains("fade")}_triggerBackdropTransition(){if($.trigger(this._element,"hidePrevented.bs.modal").defaultPrevented)return;const t=this._element.scrollHeight>document.documentElement.clientHeight,e=this._element.style.overflowY;"hidden"===e||this._element.classList.contains(ee)||(t||(this._element.style.overflowY="hidden"),this._element.classList.add(ee),this._queueCallback((()=>{this._element.classList.remove(ee),this._queueCallback((()=>{this._element.style.overflowY=e}),this._dialog)}),this._dialog),this._element.focus())}_adjustDialog(){const t=this._element.scrollHeight>document.documentElement.clientHeight,e=this._scrollBar.getWidth(),i=e>0;if(i&&!t){const t=m()?"paddingLeft":"paddingRight";this._element.style[t]=`${e}px`}if(!i&&t){const t=m()?"paddingRight":"paddingLeft";this._element.style[t]=`${e}px`}}_resetAdjustments(){this._element.style.paddingLeft="",this._element.style.paddingRight=""}static jQueryInterface(t,e){return this.each((function(){const i=ne.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===i[t])throw new TypeError(`No method named "${t}"`);i[t](e)}}))}}$.on(document,"click.bs.modal.data-api",'[data-bs-toggle="modal"]',(function(t){const e=r(this);["A","AREA"].includes(this.tagName)&&t.preventDefault(),$.one(e,Jt,(t=>{t.defaultPrevented||$.one(e,Gt,(()=>{h(this)&&this.focus()}))}));const i=U.findOne(".modal.show");i&&ne.getInstance(i).hide(),ne.getOrCreateInstance(e).toggle(this)})),K(ne),b(ne);const oe="show",re="showing",ae="hiding",le=".offcanvas.show",ce="hidePrevented.bs.offcanvas",he="hidden.bs.offcanvas",de={backdrop:!0,keyboard:!0,scroll:!1},ue={backdrop:"(boolean|string)",keyboard:"boolean",scroll:"boolean"};class _e extends V{constructor(t,e){super(t,e),this._isShown=!1,this._backdrop=this._initializeBackDrop(),this._focustrap=this._initializeFocusTrap(),this._addEventListeners()}static get Default(){return de}static get DefaultType(){return ue}static get NAME(){return"offcanvas"}toggle(t){return this._isShown?this.hide():this.show(t)}show(t){this._isShown||$.trigger(this._element,"show.bs.offcanvas",{relatedTarget:t}).defaultPrevented||(this._isShown=!0,this._backdrop.show(),this._config.scroll||(new Ht).hide(),this._element.setAttribute("aria-modal",!0),this._element.setAttribute("role","dialog"),this._element.classList.add(re),this._queueCallback((()=>{this._config.scroll&&!this._config.backdrop||this._focustrap.activate(),this._element.classList.add(oe),this._element.classList.remove(re),$.trigger(this._element,"shown.bs.offcanvas",{relatedTarget:t})}),this._element,!0))}hide(){this._isShown&&($.trigger(this._element,"hide.bs.offcanvas").defaultPrevented||(this._focustrap.deactivate(),this._element.blur(),this._isShown=!1,this._element.classList.add(ae),this._backdrop.hide(),this._queueCallback((()=>{this._element.classList.remove(oe,ae),this._element.removeAttribute("aria-modal"),this._element.removeAttribute("role"),this._config.scroll||(new Ht).reset(),$.trigger(this._element,he)}),this._element,!0)))}dispose(){this._backdrop.dispose(),this._focustrap.deactivate(),super.dispose()}_initializeBackDrop(){const t=Boolean(this._config.backdrop);return new Vt({className:"offcanvas-backdrop",isVisible:t,isAnimated:!0,rootElement:this._element.parentNode,clickCallback:t?()=>{"static"!==this._config.backdrop?this.hide():$.trigger(this._element,ce)}:null})}_initializeFocusTrap(){return new Ut({trapElement:this._element})}_addEventListeners(){$.on(this._element,"keydown.dismiss.bs.offcanvas",(t=>{"Escape"===t.key&&(this._config.keyboard?this.hide():$.trigger(this._element,ce))}))}static jQueryInterface(t){return this.each((function(){const e=_e.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t]||t.startsWith("_")||"constructor"===t)throw new TypeError(`No method named "${t}"`);e[t](this)}}))}}$.on(document,"click.bs.offcanvas.data-api",'[data-bs-toggle="offcanvas"]',(function(t){const e=r(this);if(["A","AREA"].includes(this.tagName)&&t.preventDefault(),d(this))return;$.one(e,he,(()=>{h(this)&&this.focus()}));const i=U.findOne(le);i&&i!==e&&_e.getInstance(i).hide(),_e.getOrCreateInstance(e).toggle(this)})),$.on(window,"load.bs.offcanvas.data-api",(()=>{for(const t of U.find(le))_e.getOrCreateInstance(t).show()})),$.on(window,"resize.bs.offcanvas",(()=>{for(const t of U.find("[aria-modal][class*=show][class*=offcanvas-]"))"fixed"!==getComputedStyle(t).position&&_e.getOrCreateInstance(t).hide()})),K(_e),b(_e);const ge=new Set(["background","cite","href","itemtype","longdesc","poster","src","xlink:href"]),fe=/^(?:(?:https?|mailto|ftp|tel|file|sms):|[^#&/:?]*(?:[#/?]|$))/i,pe=/^data:(?:image\/(?:bmp|gif|jpeg|jpg|png|tiff|webp)|video\/(?:mpeg|mp4|ogg|webm)|audio\/(?:mp3|oga|ogg|opus));base64,[\d+/a-z]+=*$/i,me=(t,e)=>{const i=t.nodeName.toLowerCase();return e.includes(i)?!ge.has(i)||Boolean(fe.test(t.nodeValue)||pe.test(t.nodeValue)):e.filter((t=>t instanceof RegExp)).some((t=>t.test(i)))},be={"*":["class","dir","id","lang","role",/^aria-[\w-]*$/i],a:["target","href","title","rel"],area:[],b:[],br:[],col:[],code:[],div:[],em:[],hr:[],h1:[],h2:[],h3:[],h4:[],h5:[],h6:[],i:[],img:["src","srcset","alt","title","width","height"],li:[],ol:[],p:[],pre:[],s:[],small:[],span:[],sub:[],sup:[],strong:[],u:[],ul:[]},ve={allowList:be,content:{},extraClass:"",html:!1,sanitize:!0,sanitizeFn:null,template:"
"},ye={allowList:"object",content:"object",extraClass:"(string|function)",html:"boolean",sanitize:"boolean",sanitizeFn:"(null|function)",template:"string"},we={entry:"(string|element|function|null)",selector:"(string|element)"};class Ae extends R{constructor(t){super(),this._config=this._getConfig(t)}static get Default(){return ve}static get DefaultType(){return ye}static get NAME(){return"TemplateFactory"}getContent(){return Object.values(this._config.content).map((t=>this._resolvePossibleFunction(t))).filter(Boolean)}hasContent(){return this.getContent().length>0}changeContent(t){return this._checkContent(t),this._config.content={...this._config.content,...t},this}toHtml(){const t=document.createElement("div");t.innerHTML=this._maybeSanitize(this._config.template);for(const[e,i]of Object.entries(this._config.content))this._setContent(t,i,e);const e=t.children[0],i=this._resolvePossibleFunction(this._config.extraClass);return i&&e.classList.add(...i.split(" ")),e}_typeCheckConfig(t){super._typeCheckConfig(t),this._checkContent(t.content)}_checkContent(t){for(const[e,i]of Object.entries(t))super._typeCheckConfig({selector:e,entry:i},we)}_setContent(t,e,i){const s=U.findOne(i,t);s&&((e=this._resolvePossibleFunction(e))?l(e)?this._putElementInTemplate(c(e),s):this._config.html?s.innerHTML=this._maybeSanitize(e):s.textContent=e:s.remove())}_maybeSanitize(t){return this._config.sanitize?function(t,e,i){if(!t.length)return t;if(i&&"function"==typeof i)return i(t);const s=(new window.DOMParser).parseFromString(t,"text/html"),n=[].concat(...s.body.querySelectorAll("*"));for(const t of n){const i=t.nodeName.toLowerCase();if(!Object.keys(e).includes(i)){t.remove();continue}const s=[].concat(...t.attributes),n=[].concat(e["*"]||[],e[i]||[]);for(const e of s)me(e,n)||t.removeAttribute(e.nodeName)}return s.body.innerHTML}(t,this._config.allowList,this._config.sanitizeFn):t}_resolvePossibleFunction(t){return"function"==typeof t?t(this):t}_putElementInTemplate(t,e){if(this._config.html)return e.innerHTML="",void e.append(t);e.textContent=t.textContent}}const Ee=new Set(["sanitize","allowList","sanitizeFn"]),Ce="fade",Te="show",ke=".modal",Le="hide.bs.modal",Oe="hover",Ie="focus",Se={AUTO:"auto",TOP:"top",RIGHT:m()?"left":"right",BOTTOM:"bottom",LEFT:m()?"right":"left"},De={allowList:be,animation:!0,boundary:"clippingParents",container:!1,customClass:"",delay:0,fallbackPlacements:["top","right","bottom","left"],html:!1,offset:[0,0],placement:"top",popperConfig:null,sanitize:!0,sanitizeFn:null,selector:!1,template:'',title:"",trigger:"hover focus"},Ne={allowList:"object",animation:"boolean",boundary:"(string|element)",container:"(string|element|boolean)",customClass:"(string|function)",delay:"(number|object)",fallbackPlacements:"array",html:"boolean",offset:"(array|string|function)",placement:"(string|function)",popperConfig:"(null|object|function)",sanitize:"boolean",sanitizeFn:"(null|function)",selector:"(string|boolean)",template:"string",title:"(string|element|function)",trigger:"string"};class Pe extends V{constructor(t,e){if(void 0===i)throw new TypeError("Bootstrap's tooltips require Popper (https://popper.js.org)");super(t,e),this._isEnabled=!0,this._timeout=0,this._isHovered=null,this._activeTrigger={},this._popper=null,this._templateFactory=null,this._newContent=null,this.tip=null,this._setListeners(),this._config.selector||this._fixTitle()}static get Default(){return De}static get DefaultType(){return Ne}static get NAME(){return"tooltip"}enable(){this._isEnabled=!0}disable(){this._isEnabled=!1}toggleEnabled(){this._isEnabled=!this._isEnabled}toggle(){this._isEnabled&&(this._activeTrigger.click=!this._activeTrigger.click,this._isShown()?this._leave():this._enter())}dispose(){clearTimeout(this._timeout),$.off(this._element.closest(ke),Le,this._hideModalHandler),this._element.getAttribute("data-bs-original-title")&&this._element.setAttribute("title",this._element.getAttribute("data-bs-original-title")),this._disposePopper(),super.dispose()}show(){if("none"===this._element.style.display)throw new Error("Please use show on visible elements");if(!this._isWithContent()||!this._isEnabled)return;const t=$.trigger(this._element,this.constructor.eventName("show")),e=(u(this._element)||this._element.ownerDocument.documentElement).contains(this._element);if(t.defaultPrevented||!e)return;this._disposePopper();const i=this._getTipElement();this._element.setAttribute("aria-describedby",i.getAttribute("id"));const{container:s}=this._config;if(this._element.ownerDocument.documentElement.contains(this.tip)||(s.append(i),$.trigger(this._element,this.constructor.eventName("inserted"))),this._popper=this._createPopper(i),i.classList.add(Te),"ontouchstart"in document.documentElement)for(const t of[].concat(...document.body.children))$.on(t,"mouseover",_);this._queueCallback((()=>{$.trigger(this._element,this.constructor.eventName("shown")),!1===this._isHovered&&this._leave(),this._isHovered=!1}),this.tip,this._isAnimated())}hide(){if(this._isShown()&&!$.trigger(this._element,this.constructor.eventName("hide")).defaultPrevented){if(this._getTipElement().classList.remove(Te),"ontouchstart"in document.documentElement)for(const t of[].concat(...document.body.children))$.off(t,"mouseover",_);this._activeTrigger.click=!1,this._activeTrigger.focus=!1,this._activeTrigger.hover=!1,this._isHovered=null,this._queueCallback((()=>{this._isWithActiveTrigger()||(this._isHovered||this._disposePopper(),this._element.removeAttribute("aria-describedby"),$.trigger(this._element,this.constructor.eventName("hidden")))}),this.tip,this._isAnimated())}}update(){this._popper&&this._popper.update()}_isWithContent(){return Boolean(this._getTitle())}_getTipElement(){return this.tip||(this.tip=this._createTipElement(this._newContent||this._getContentForTemplate())),this.tip}_createTipElement(t){const e=this._getTemplateFactory(t).toHtml();if(!e)return null;e.classList.remove(Ce,Te),e.classList.add(`bs-${this.constructor.NAME}-auto`);const i=(t=>{do{t+=Math.floor(1e6*Math.random())}while(document.getElementById(t));return t})(this.constructor.NAME).toString();return e.setAttribute("id",i),this._isAnimated()&&e.classList.add(Ce),e}setContent(t){this._newContent=t,this._isShown()&&(this._disposePopper(),this.show())}_getTemplateFactory(t){return this._templateFactory?this._templateFactory.changeContent(t):this._templateFactory=new Ae({...this._config,content:t,extraClass:this._resolvePossibleFunction(this._config.customClass)}),this._templateFactory}_getContentForTemplate(){return{".tooltip-inner":this._getTitle()}}_getTitle(){return this._resolvePossibleFunction(this._config.title)||this._element.getAttribute("data-bs-original-title")}_initializeOnDelegatedTarget(t){return this.constructor.getOrCreateInstance(t.delegateTarget,this._getDelegateConfig())}_isAnimated(){return this._config.animation||this.tip&&this.tip.classList.contains(Ce)}_isShown(){return this.tip&&this.tip.classList.contains(Te)}_createPopper(t){const e="function"==typeof this._config.placement?this._config.placement.call(this,t,this._element):this._config.placement,s=Se[e.toUpperCase()];return i.createPopper(this._element,t,this._getPopperConfig(s))}_getOffset(){const{offset:t}=this._config;return"string"==typeof t?t.split(",").map((t=>Number.parseInt(t,10))):"function"==typeof t?e=>t(e,this._element):t}_resolvePossibleFunction(t){return"function"==typeof t?t.call(this._element):t}_getPopperConfig(t){const e={placement:t,modifiers:[{name:"flip",options:{fallbackPlacements:this._config.fallbackPlacements}},{name:"offset",options:{offset:this._getOffset()}},{name:"preventOverflow",options:{boundary:this._config.boundary}},{name:"arrow",options:{element:`.${this.constructor.NAME}-arrow`}},{name:"preSetPlacement",enabled:!0,phase:"beforeMain",fn:t=>{this._getTipElement().setAttribute("data-popper-placement",t.state.placement)}}]};return{...e,..."function"==typeof this._config.popperConfig?this._config.popperConfig(e):this._config.popperConfig}}_setListeners(){const t=this._config.trigger.split(" ");for(const e of t)if("click"===e)$.on(this._element,this.constructor.eventName("click"),this._config.selector,(t=>{this._initializeOnDelegatedTarget(t).toggle()}));else if("manual"!==e){const t=e===Oe?this.constructor.eventName("mouseenter"):this.constructor.eventName("focusin"),i=e===Oe?this.constructor.eventName("mouseleave"):this.constructor.eventName("focusout");$.on(this._element,t,this._config.selector,(t=>{const e=this._initializeOnDelegatedTarget(t);e._activeTrigger["focusin"===t.type?Ie:Oe]=!0,e._enter()})),$.on(this._element,i,this._config.selector,(t=>{const e=this._initializeOnDelegatedTarget(t);e._activeTrigger["focusout"===t.type?Ie:Oe]=e._element.contains(t.relatedTarget),e._leave()}))}this._hideModalHandler=()=>{this._element&&this.hide()},$.on(this._element.closest(ke),Le,this._hideModalHandler)}_fixTitle(){const t=this._element.getAttribute("title");t&&(this._element.getAttribute("aria-label")||this._element.textContent.trim()||this._element.setAttribute("aria-label",t),this._element.setAttribute("data-bs-original-title",t),this._element.removeAttribute("title"))}_enter(){this._isShown()||this._isHovered?this._isHovered=!0:(this._isHovered=!0,this._setTimeout((()=>{this._isHovered&&this.show()}),this._config.delay.show))}_leave(){this._isWithActiveTrigger()||(this._isHovered=!1,this._setTimeout((()=>{this._isHovered||this.hide()}),this._config.delay.hide))}_setTimeout(t,e){clearTimeout(this._timeout),this._timeout=setTimeout(t,e)}_isWithActiveTrigger(){return Object.values(this._activeTrigger).includes(!0)}_getConfig(t){const e=W.getDataAttributes(this._element);for(const t of Object.keys(e))Ee.has(t)&&delete e[t];return t={...e,..."object"==typeof t&&t?t:{}},t=this._mergeConfigObj(t),t=this._configAfterMerge(t),this._typeCheckConfig(t),t}_configAfterMerge(t){return t.container=!1===t.container?document.body:c(t.container),"number"==typeof t.delay&&(t.delay={show:t.delay,hide:t.delay}),"number"==typeof t.title&&(t.title=t.title.toString()),"number"==typeof t.content&&(t.content=t.content.toString()),t}_getDelegateConfig(){const t={};for(const e in this._config)this.constructor.Default[e]!==this._config[e]&&(t[e]=this._config[e]);return t.selector=!1,t.trigger="manual",t}_disposePopper(){this._popper&&(this._popper.destroy(),this._popper=null),this.tip&&(this.tip.remove(),this.tip=null)}static jQueryInterface(t){return this.each((function(){const e=Pe.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t])throw new TypeError(`No method named "${t}"`);e[t]()}}))}}b(Pe);const xe={...Pe.Default,content:"",offset:[0,8],placement:"right",template:'',trigger:"click"},Me={...Pe.DefaultType,content:"(null|string|element|function)"};class je extends Pe{static get Default(){return xe}static get DefaultType(){return Me}static get NAME(){return"popover"}_isWithContent(){return this._getTitle()||this._getContent()}_getContentForTemplate(){return{".popover-header":this._getTitle(),".popover-body":this._getContent()}}_getContent(){return this._resolvePossibleFunction(this._config.content)}static jQueryInterface(t){return this.each((function(){const e=je.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t])throw new TypeError(`No method named "${t}"`);e[t]()}}))}}b(je);const $e="click.bs.scrollspy",Fe="active",ze="[href]",He={offset:null,rootMargin:"0px 0px -25%",smoothScroll:!1,target:null,threshold:[.1,.5,1]},qe={offset:"(number|null)",rootMargin:"string",smoothScroll:"boolean",target:"element",threshold:"array"};class Be extends V{constructor(t,e){super(t,e),this._targetLinks=new Map,this._observableSections=new Map,this._rootElement="visible"===getComputedStyle(this._element).overflowY?null:this._element,this._activeTarget=null,this._observer=null,this._previousScrollData={visibleEntryTop:0,parentScrollTop:0},this.refresh()}static get Default(){return He}static get DefaultType(){return qe}static get NAME(){return"scrollspy"}refresh(){this._initializeTargetsAndObservables(),this._maybeEnableSmoothScroll(),this._observer?this._observer.disconnect():this._observer=this._getNewObserver();for(const t of this._observableSections.values())this._observer.observe(t)}dispose(){this._observer.disconnect(),super.dispose()}_configAfterMerge(t){return t.target=c(t.target)||document.body,t.rootMargin=t.offset?`${t.offset}px 0px -30%`:t.rootMargin,"string"==typeof t.threshold&&(t.threshold=t.threshold.split(",").map((t=>Number.parseFloat(t)))),t}_maybeEnableSmoothScroll(){this._config.smoothScroll&&($.off(this._config.target,$e),$.on(this._config.target,$e,ze,(t=>{const e=this._observableSections.get(t.target.hash);if(e){t.preventDefault();const i=this._rootElement||window,s=e.offsetTop-this._element.offsetTop;if(i.scrollTo)return void i.scrollTo({top:s,behavior:"smooth"});i.scrollTop=s}})))}_getNewObserver(){const t={root:this._rootElement,threshold:this._config.threshold,rootMargin:this._config.rootMargin};return new IntersectionObserver((t=>this._observerCallback(t)),t)}_observerCallback(t){const e=t=>this._targetLinks.get(`#${t.target.id}`),i=t=>{this._previousScrollData.visibleEntryTop=t.target.offsetTop,this._process(e(t))},s=(this._rootElement||document.documentElement).scrollTop,n=s>=this._previousScrollData.parentScrollTop;this._previousScrollData.parentScrollTop=s;for(const o of t){if(!o.isIntersecting){this._activeTarget=null,this._clearActiveClass(e(o));continue}const t=o.target.offsetTop>=this._previousScrollData.visibleEntryTop;if(n&&t){if(i(o),!s)return}else n||t||i(o)}}_initializeTargetsAndObservables(){this._targetLinks=new Map,this._observableSections=new Map;const t=U.find(ze,this._config.target);for(const e of t){if(!e.hash||d(e))continue;const t=U.findOne(e.hash,this._element);h(t)&&(this._targetLinks.set(e.hash,e),this._observableSections.set(e.hash,t))}}_process(t){this._activeTarget!==t&&(this._clearActiveClass(this._config.target),this._activeTarget=t,t.classList.add(Fe),this._activateParents(t),$.trigger(this._element,"activate.bs.scrollspy",{relatedTarget:t}))}_activateParents(t){if(t.classList.contains("dropdown-item"))U.findOne(".dropdown-toggle",t.closest(".dropdown")).classList.add(Fe);else for(const e of U.parents(t,".nav, .list-group"))for(const t of U.prev(e,".nav-link, .nav-item > .nav-link, .list-group-item"))t.classList.add(Fe)}_clearActiveClass(t){t.classList.remove(Fe);const e=U.find("[href].active",t);for(const t of e)t.classList.remove(Fe)}static jQueryInterface(t){return this.each((function(){const e=Be.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t]||t.startsWith("_")||"constructor"===t)throw new TypeError(`No method named "${t}"`);e[t]()}}))}}$.on(window,"load.bs.scrollspy.data-api",(()=>{for(const t of U.find('[data-bs-spy="scroll"]'))Be.getOrCreateInstance(t)})),b(Be);const We="ArrowLeft",Re="ArrowRight",Ve="ArrowUp",Ke="ArrowDown",Qe="active",Xe="fade",Ye="show",Ue='[data-bs-toggle="tab"], [data-bs-toggle="pill"], [data-bs-toggle="list"]',Ge=`.nav-link:not(.dropdown-toggle), .list-group-item:not(.dropdown-toggle), [role="tab"]:not(.dropdown-toggle), ${Ue}`;class Je extends V{constructor(t){super(t),this._parent=this._element.closest('.list-group, .nav, [role="tablist"]'),this._parent&&(this._setInitialAttributes(this._parent,this._getChildren()),$.on(this._element,"keydown.bs.tab",(t=>this._keydown(t))))}static get NAME(){return"tab"}show(){const t=this._element;if(this._elemIsActive(t))return;const e=this._getActiveElem(),i=e?$.trigger(e,"hide.bs.tab",{relatedTarget:t}):null;$.trigger(t,"show.bs.tab",{relatedTarget:e}).defaultPrevented||i&&i.defaultPrevented||(this._deactivate(e,t),this._activate(t,e))}_activate(t,e){t&&(t.classList.add(Qe),this._activate(r(t)),this._queueCallback((()=>{"tab"===t.getAttribute("role")?(t.removeAttribute("tabindex"),t.setAttribute("aria-selected",!0),this._toggleDropDown(t,!0),$.trigger(t,"shown.bs.tab",{relatedTarget:e})):t.classList.add(Ye)}),t,t.classList.contains(Xe)))}_deactivate(t,e){t&&(t.classList.remove(Qe),t.blur(),this._deactivate(r(t)),this._queueCallback((()=>{"tab"===t.getAttribute("role")?(t.setAttribute("aria-selected",!1),t.setAttribute("tabindex","-1"),this._toggleDropDown(t,!1),$.trigger(t,"hidden.bs.tab",{relatedTarget:e})):t.classList.remove(Ye)}),t,t.classList.contains(Xe)))}_keydown(t){if(![We,Re,Ve,Ke].includes(t.key))return;t.stopPropagation(),t.preventDefault();const e=[Re,Ke].includes(t.key),i=w(this._getChildren().filter((t=>!d(t))),t.target,e,!0);i&&(i.focus({preventScroll:!0}),Je.getOrCreateInstance(i).show())}_getChildren(){return U.find(Ge,this._parent)}_getActiveElem(){return this._getChildren().find((t=>this._elemIsActive(t)))||null}_setInitialAttributes(t,e){this._setAttributeIfNotExists(t,"role","tablist");for(const t of e)this._setInitialAttributesOnChild(t)}_setInitialAttributesOnChild(t){t=this._getInnerElement(t);const e=this._elemIsActive(t),i=this._getOuterElement(t);t.setAttribute("aria-selected",e),i!==t&&this._setAttributeIfNotExists(i,"role","presentation"),e||t.setAttribute("tabindex","-1"),this._setAttributeIfNotExists(t,"role","tab"),this._setInitialAttributesOnTargetPanel(t)}_setInitialAttributesOnTargetPanel(t){const e=r(t);e&&(this._setAttributeIfNotExists(e,"role","tabpanel"),t.id&&this._setAttributeIfNotExists(e,"aria-labelledby",`#${t.id}`))}_toggleDropDown(t,e){const i=this._getOuterElement(t);if(!i.classList.contains("dropdown"))return;const s=(t,s)=>{const n=U.findOne(t,i);n&&n.classList.toggle(s,e)};s(".dropdown-toggle",Qe),s(".dropdown-menu",Ye),i.setAttribute("aria-expanded",e)}_setAttributeIfNotExists(t,e,i){t.hasAttribute(e)||t.setAttribute(e,i)}_elemIsActive(t){return t.classList.contains(Qe)}_getInnerElement(t){return t.matches(Ge)?t:U.findOne(Ge,t)}_getOuterElement(t){return t.closest(".nav-item, .list-group-item")||t}static jQueryInterface(t){return this.each((function(){const e=Je.getOrCreateInstance(this);if("string"==typeof t){if(void 0===e[t]||t.startsWith("_")||"constructor"===t)throw new TypeError(`No method named "${t}"`);e[t]()}}))}}$.on(document,"click.bs.tab",Ue,(function(t){["A","AREA"].includes(this.tagName)&&t.preventDefault(),d(this)||Je.getOrCreateInstance(this).show()})),$.on(window,"load.bs.tab",(()=>{for(const t of U.find('.active[data-bs-toggle="tab"], .active[data-bs-toggle="pill"], .active[data-bs-toggle="list"]'))Je.getOrCreateInstance(t)})),b(Je);const Ze="hide",ti="show",ei="showing",ii={animation:"boolean",autohide:"boolean",delay:"number"},si={animation:!0,autohide:!0,delay:5e3};class ni extends V{constructor(t,e){super(t,e),this._timeout=null,this._hasMouseInteraction=!1,this._hasKeyboardInteraction=!1,this._setListeners()}static get Default(){return si}static get DefaultType(){return ii}static get NAME(){return"toast"}show(){$.trigger(this._element,"show.bs.toast").defaultPrevented||(this._clearTimeout(),this._config.animation&&this._element.classList.add("fade"),this._element.classList.remove(Ze),g(this._element),this._element.classList.add(ti,ei),this._queueCallback((()=>{this._element.classList.remove(ei),$.trigger(this._element,"shown.bs.toast"),this._maybeScheduleHide()}),this._element,this._config.animation))}hide(){this.isShown()&&($.trigger(this._element,"hide.bs.toast").defaultPrevented||(this._element.classList.add(ei),this._queueCallback((()=>{this._element.classList.add(Ze),this._element.classList.remove(ei,ti),$.trigger(this._element,"hidden.bs.toast")}),this._element,this._config.animation)))}dispose(){this._clearTimeout(),this.isShown()&&this._element.classList.remove(ti),super.dispose()}isShown(){return this._element.classList.contains(ti)}_maybeScheduleHide(){this._config.autohide&&(this._hasMouseInteraction||this._hasKeyboardInteraction||(this._timeout=setTimeout((()=>{this.hide()}),this._config.delay)))}_onInteraction(t,e){switch(t.type){case"mouseover":case"mouseout":this._hasMouseInteraction=e;break;case"focusin":case"focusout":this._hasKeyboardInteraction=e}if(e)return void this._clearTimeout();const i=t.relatedTarget;this._element===i||this._element.contains(i)||this._maybeScheduleHide()}_setListeners(){$.on(this._element,"mouseover.bs.toast",(t=>this._onInteraction(t,!0))),$.on(this._element,"mouseout.bs.toast",(t=>this._onInteraction(t,!1))),$.on(this._element,"focusin.bs.toast",(t=>this._onInteraction(t,!0))),$.on(this._element,"focusout.bs.toast",(t=>this._onInteraction(t,!1)))}_clearTimeout(){clearTimeout(this._timeout),this._timeout=null}static jQueryInterface(t){return this.each((function(){const e=ni.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t])throw new TypeError(`No method named "${t}"`);e[t](this)}}))}}return K(ni),b(ni),{Alert:Q,Button:Y,Carousel:ht,Collapse:mt,Dropdown:Mt,Modal:ne,Offcanvas:_e,Popover:je,ScrollSpy:Be,Tab:Je,Toast:ni,Tooltip:Pe}})); +//# sourceMappingURL=bootstrap.min.js.map \ No newline at end of file diff --git a/web/peak/dist/web/assets/img/climbing.png b/web/peak/dist/web/assets/img/climbing.png new file mode 100644 index 0000000..30a744b Binary files /dev/null and b/web/peak/dist/web/assets/img/climbing.png differ diff --git a/web/peak/dist/web/assets/img/hiking.png b/web/peak/dist/web/assets/img/hiking.png new file mode 100644 index 0000000..366ee6d Binary files /dev/null and b/web/peak/dist/web/assets/img/hiking.png differ diff --git a/web/peak/dist/web/assets/img/map.png b/web/peak/dist/web/assets/img/map.png new file mode 100644 index 0000000..a43054c Binary files /dev/null and b/web/peak/dist/web/assets/img/map.png differ diff --git a/web/peak/dist/web/assets/img/peak.png b/web/peak/dist/web/assets/img/peak.png new file mode 100644 index 0000000..a7520ab Binary files /dev/null and b/web/peak/dist/web/assets/img/peak.png differ diff --git a/web/peak/dist/web/assets/img/road.png b/web/peak/dist/web/assets/img/road.png new file mode 100644 index 0000000..3a77538 Binary files /dev/null and b/web/peak/dist/web/assets/img/road.png differ diff --git a/web/peak/dist/web/assets/img/sightseeing.png b/web/peak/dist/web/assets/img/sightseeing.png new file mode 100644 index 0000000..7973c79 Binary files /dev/null and b/web/peak/dist/web/assets/img/sightseeing.png differ diff --git a/web/peak/dist/web/assets/jquery.js b/web/peak/dist/web/assets/jquery.js new file mode 100644 index 0000000..c39d8fd --- /dev/null +++ b/web/peak/dist/web/assets/jquery.js @@ -0,0 +1,2 @@ +/*! jQuery v3.5.1 -ajax,-ajax/jsonp,-ajax/load,-ajax/script,-ajax/var/location,-ajax/var/nonce,-ajax/var/rquery,-ajax/xhr,-manipulation/_evalUrl,-deprecated/ajax-event-alias,-effects,-effects/Tween,-effects/animatedSelector | (c) JS Foundation and other contributors | jquery.org/license */ +!function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(g,e){"use strict";var t=[],r=Object.getPrototypeOf,s=t.slice,v=t.flat?function(e){return t.flat.call(e)}:function(e){return t.concat.apply([],e)},u=t.push,i=t.indexOf,n={},o=n.toString,y=n.hasOwnProperty,a=y.toString,l=a.call(Object),m={},b=function(e){return"function"==typeof e&&"number"!=typeof e.nodeType},x=function(e){return null!=e&&e===e.window},w=g.document,c={type:!0,src:!0,nonce:!0,noModule:!0};function C(e,t,n){var r,i,o=(n=n||w).createElement("script");if(o.text=e,t)for(r in c)(i=t[r]||t.getAttribute&&t.getAttribute(r))&&o.setAttribute(r,i);n.head.appendChild(o).parentNode.removeChild(o)}function T(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?n[o.call(e)]||"object":typeof e}var f="3.5.1 -ajax,-ajax/jsonp,-ajax/load,-ajax/script,-ajax/var/location,-ajax/var/nonce,-ajax/var/rquery,-ajax/xhr,-manipulation/_evalUrl,-deprecated/ajax-event-alias,-effects,-effects/Tween,-effects/animatedSelector",E=function(e,t){return new E.fn.init(e,t)};function d(e){var t=!!e&&"length"in e&&e.length,n=T(e);return!b(e)&&!x(e)&&("array"===n||0===t||"number"==typeof t&&0+~]|"+R+")"+R+"*"),U=new RegExp(R+"|>"),V=new RegExp(W),X=new RegExp("^"+B+"$"),Q={ID:new RegExp("^#("+B+")"),CLASS:new RegExp("^\\.("+B+")"),TAG:new RegExp("^("+B+"|[*])"),ATTR:new RegExp("^"+M),PSEUDO:new RegExp("^"+W),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+R+"*(even|odd|(([+-]|)(\\d*)n|)"+R+"*(?:([+-]|)"+R+"*(\\d+)|))"+R+"*\\)|)","i"),bool:new RegExp("^(?:"+I+")$","i"),needsContext:new RegExp("^"+R+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+R+"*((?:-\\d)?\\d*)"+R+"*\\)|)(?=[^-]|$)","i")},Y=/HTML$/i,G=/^(?:input|select|textarea|button)$/i,K=/^h\d$/i,J=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ee=/[+~]/,te=new RegExp("\\\\[\\da-fA-F]{1,6}"+R+"?|\\\\([^\\r\\n\\f])","g"),ne=function(e,t){var n="0x"+e.slice(1)-65536;return t||(n<0?String.fromCharCode(n+65536):String.fromCharCode(n>>10|55296,1023&n|56320))},re=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ie=function(e,t){return t?"\0"===e?"\ufffd":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e},oe=function(){C()},ae=xe(function(e){return!0===e.disabled&&"fieldset"===e.nodeName.toLowerCase()},{dir:"parentNode",next:"legend"});try{O.apply(t=P.call(d.childNodes),d.childNodes),t[d.childNodes.length].nodeType}catch(e){O={apply:t.length?function(e,t){q.apply(e,P.call(t))}:function(e,t){var n=e.length,r=0;while(e[n++]=t[r++]);e.length=n-1}}}function se(t,e,n,r){var i,o,a,s,u,l,c,f=e&&e.ownerDocument,d=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==d&&9!==d&&11!==d)return n;if(!r&&(C(e),e=e||T,E)){if(11!==d&&(u=Z.exec(t)))if(i=u[1]){if(9===d){if(!(a=e.getElementById(i)))return n;if(a.id===i)return n.push(a),n}else if(f&&(a=f.getElementById(i))&&y(e,a)&&a.id===i)return n.push(a),n}else{if(u[2])return O.apply(n,e.getElementsByTagName(t)),n;if((i=u[3])&&p.getElementsByClassName&&e.getElementsByClassName)return O.apply(n,e.getElementsByClassName(i)),n}if(p.qsa&&!k[t+" "]&&(!v||!v.test(t))&&(1!==d||"object"!==e.nodeName.toLowerCase())){if(c=t,f=e,1===d&&(U.test(t)||_.test(t))){(f=ee.test(t)&&ye(e.parentNode)||e)===e&&p.scope||((s=e.getAttribute("id"))?s=s.replace(re,ie):e.setAttribute("id",s=A)),o=(l=h(t)).length;while(o--)l[o]=(s?"#"+s:":scope")+" "+be(l[o]);c=l.join(",")}try{return O.apply(n,f.querySelectorAll(c)),n}catch(e){k(t,!0)}finally{s===A&&e.removeAttribute("id")}}}return g(t.replace($,"$1"),e,n,r)}function ue(){var r=[];return function e(t,n){return r.push(t+" ")>x.cacheLength&&delete e[r.shift()],e[t+" "]=n}}function le(e){return e[A]=!0,e}function ce(e){var t=T.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function fe(e,t){var n=e.split("|"),r=n.length;while(r--)x.attrHandle[n[r]]=t}function de(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&e.sourceIndex-t.sourceIndex;if(r)return r;if(n)while(n=n.nextSibling)if(n===t)return-1;return e?1:-1}function pe(t){return function(e){return"input"===e.nodeName.toLowerCase()&&e.type===t}}function he(n){return function(e){var t=e.nodeName.toLowerCase();return("input"===t||"button"===t)&&e.type===n}}function ge(t){return function(e){return"form"in e?e.parentNode&&!1===e.disabled?"label"in e?"label"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&ae(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function ve(a){return le(function(o){return o=+o,le(function(e,t){var n,r=a([],e.length,o),i=r.length;while(i--)e[n=r[i]]&&(e[n]=!(t[n]=e[n]))})})}function ye(e){return e&&"undefined"!=typeof e.getElementsByTagName&&e}for(e in p=se.support={},i=se.isXML=function(e){var t=e.namespaceURI,n=(e.ownerDocument||e).documentElement;return!Y.test(t||n&&n.nodeName||"HTML")},C=se.setDocument=function(e){var t,n,r=e?e.ownerDocument||e:d;return r!=T&&9===r.nodeType&&r.documentElement&&(a=(T=r).documentElement,E=!i(T),d!=T&&(n=T.defaultView)&&n.top!==n&&(n.addEventListener?n.addEventListener("unload",oe,!1):n.attachEvent&&n.attachEvent("onunload",oe)),p.scope=ce(function(e){return a.appendChild(e).appendChild(T.createElement("div")),"undefined"!=typeof e.querySelectorAll&&!e.querySelectorAll(":scope fieldset div").length}),p.attributes=ce(function(e){return e.className="i",!e.getAttribute("className")}),p.getElementsByTagName=ce(function(e){return e.appendChild(T.createComment("")),!e.getElementsByTagName("*").length}),p.getElementsByClassName=J.test(T.getElementsByClassName),p.getById=ce(function(e){return a.appendChild(e).id=A,!T.getElementsByName||!T.getElementsByName(A).length}),p.getById?(x.filter.ID=function(e){var t=e.replace(te,ne);return function(e){return e.getAttribute("id")===t}},x.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n=t.getElementById(e);return n?[n]:[]}}):(x.filter.ID=function(e){var n=e.replace(te,ne);return function(e){var t="undefined"!=typeof e.getAttributeNode&&e.getAttributeNode("id");return t&&t.value===n}},x.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n,r,i,o=t.getElementById(e);if(o){if((n=o.getAttributeNode("id"))&&n.value===e)return[o];i=t.getElementsByName(e),r=0;while(o=i[r++])if((n=o.getAttributeNode("id"))&&n.value===e)return[o]}return[]}}),x.find.TAG=p.getElementsByTagName?function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):p.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){while(n=o[i++])1===n.nodeType&&r.push(n);return r}return o},x.find.CLASS=p.getElementsByClassName&&function(e,t){if("undefined"!=typeof t.getElementsByClassName&&E)return t.getElementsByClassName(e)},s=[],v=[],(p.qsa=J.test(T.querySelectorAll))&&(ce(function(e){var t;a.appendChild(e).innerHTML="",e.querySelectorAll("[msallowcapture^='']").length&&v.push("[*^$]="+R+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||v.push("\\["+R+"*(?:value|"+I+")"),e.querySelectorAll("[id~="+A+"-]").length||v.push("~="),(t=T.createElement("input")).setAttribute("name",""),e.appendChild(t),e.querySelectorAll("[name='']").length||v.push("\\["+R+"*name"+R+"*="+R+"*(?:''|\"\")"),e.querySelectorAll(":checked").length||v.push(":checked"),e.querySelectorAll("a#"+A+"+*").length||v.push(".#.+[+~]"),e.querySelectorAll("\\\f"),v.push("[\\r\\n\\f]")}),ce(function(e){e.innerHTML="";var t=T.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&v.push("name"+R+"*[*^$|!~]?="),2!==e.querySelectorAll(":enabled").length&&v.push(":enabled",":disabled"),a.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&v.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),v.push(",.*:")})),(p.matchesSelector=J.test(c=a.matches||a.webkitMatchesSelector||a.mozMatchesSelector||a.oMatchesSelector||a.msMatchesSelector))&&ce(function(e){p.disconnectedMatch=c.call(e,"*"),c.call(e,"[s!='']:x"),s.push("!=",W)}),v=v.length&&new RegExp(v.join("|")),s=s.length&&new RegExp(s.join("|")),t=J.test(a.compareDocumentPosition),y=t||J.test(a.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)while(t=t.parentNode)if(t===e)return!0;return!1},D=t?function(e,t){if(e===t)return l=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)==(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!p.sortDetached&&t.compareDocumentPosition(e)===n?e==T||e.ownerDocument==d&&y(d,e)?-1:t==T||t.ownerDocument==d&&y(d,t)?1:u?H(u,e)-H(u,t):0:4&n?-1:1)}:function(e,t){if(e===t)return l=!0,0;var n,r=0,i=e.parentNode,o=t.parentNode,a=[e],s=[t];if(!i||!o)return e==T?-1:t==T?1:i?-1:o?1:u?H(u,e)-H(u,t):0;if(i===o)return de(e,t);n=e;while(n=n.parentNode)a.unshift(n);n=t;while(n=n.parentNode)s.unshift(n);while(a[r]===s[r])r++;return r?de(a[r],s[r]):a[r]==d?-1:s[r]==d?1:0}),T},se.matches=function(e,t){return se(e,null,null,t)},se.matchesSelector=function(e,t){if(C(e),p.matchesSelector&&E&&!k[t+" "]&&(!s||!s.test(t))&&(!v||!v.test(t)))try{var n=c.call(e,t);if(n||p.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){k(t,!0)}return 0":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(te,ne),e[3]=(e[3]||e[4]||e[5]||"").replace(te,ne),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||se.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&se.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return Q.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&V.test(n)&&(t=h(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(te,ne).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=m[e+" "];return t||(t=new RegExp("(^|"+R+")"+e+"("+R+"|$)"))&&m(e,function(e){return t.test("string"==typeof e.className&&e.className||"undefined"!=typeof e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(n,r,i){return function(e){var t=se.attr(e,n);return null==t?"!="===r:!r||(t+="","="===r?t===i:"!="===r?t!==i:"^="===r?i&&0===t.indexOf(i):"*="===r?i&&-1:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function D(e,n,r){return b(n)?E.grep(e,function(e,t){return!!n.call(e,t,e)!==r}):n.nodeType?E.grep(e,function(e){return e===n!==r}):"string"!=typeof n?E.grep(e,function(e){return-1)[^>]*|#([\w-]+))$/;(E.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||L,"string"==typeof e){if(!(r="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:j.exec(e))||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof E?t[0]:t,E.merge(this,E.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:w,!0)),k.test(r[1])&&E.isPlainObject(t))for(r in t)b(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(i=w.getElementById(r[2]))&&(this[0]=i,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):b(e)?void 0!==n.ready?n.ready(e):e(E):E.makeArray(e,this)}).prototype=E.fn,L=E(w);var q=/^(?:parents|prev(?:Until|All))/,O={children:!0,contents:!0,next:!0,prev:!0};function P(e,t){while((e=e[t])&&1!==e.nodeType);return e}E.fn.extend({has:function(e){var t=E(e,this),n=t.length;return this.filter(function(){for(var e=0;e\x20\t\r\n\f]*)/i,pe=/^$|^module$|\/(?:java|ecma)script/i;le=w.createDocumentFragment().appendChild(w.createElement("div")),(ce=w.createElement("input")).setAttribute("type","radio"),ce.setAttribute("checked","checked"),ce.setAttribute("name","t"),le.appendChild(ce),m.checkClone=le.cloneNode(!0).cloneNode(!0).lastChild.checked,le.innerHTML="",m.noCloneChecked=!!le.cloneNode(!0).lastChild.defaultValue,le.innerHTML="",m.option=!!le.lastChild;var he={thead:[1,"","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};function ge(e,t){var n;return n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&S(e,t)?E.merge([e],n):n}function ve(e,t){for(var n=0,r=e.length;n",""]);var ye=/<|&#?\w+;/;function me(e,t,n,r,i){for(var o,a,s,u,l,c,f=t.createDocumentFragment(),d=[],p=0,h=e.length;p\s*$/g;function Le(e,t){return S(e,"table")&&S(11!==t.nodeType?t:t.firstChild,"tr")&&E(e).children("tbody")[0]||e}function je(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function qe(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Oe(e,t){var n,r,i,o,a,s;if(1===t.nodeType){if(Y.hasData(e)&&(s=Y.get(e).events))for(i in Y.remove(t,"handle events"),s)for(n=0,r=s[i].length;n
",2===ft.childNodes.length),E.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(m.createHTMLDocument?((r=(t=w.implementation.createHTMLDocument("")).createElement("base")).href=w.location.href,t.head.appendChild(r)):t=w),o=!n&&[],(i=k.exec(e))?[t.createElement(i[1])]:(i=me([e],t,o),o&&o.length&&E(o).remove(),E.merge([],i.childNodes)));var r,i,o},E.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l=E.css(e,"position"),c=E(e),f={};"static"===l&&(e.style.position="relative"),s=c.offset(),o=E.css(e,"top"),u=E.css(e,"left"),("absolute"===l||"fixed"===l)&&-1<(o+u).indexOf("auto")?(a=(r=c.position()).top,i=r.left):(a=parseFloat(o)||0,i=parseFloat(u)||0),b(t)&&(t=t.call(e,n,E.extend({},s))),null!=t.top&&(f.top=t.top-s.top+a),null!=t.left&&(f.left=t.left-s.left+i),"using"in t?t.using.call(e,f):("number"==typeof f.top&&(f.top+="px"),"number"==typeof f.left&&(f.left+="px"),c.css(f))}},E.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){E.offset.setOffset(this,t,e)});var e,n,r=this[0];return r?r.getClientRects().length?(e=r.getBoundingClientRect(),n=r.ownerDocument.defaultView,{top:e.top+n.pageYOffset,left:e.left+n.pageXOffset}):{top:0,left:0}:void 0},position:function(){if(this[0]){var e,t,n,r=this[0],i={top:0,left:0};if("fixed"===E.css(r,"position"))t=r.getBoundingClientRect();else{t=this.offset(),n=r.ownerDocument,e=r.offsetParent||n.documentElement;while(e&&(e===n.body||e===n.documentElement)&&"static"===E.css(e,"position"))e=e.parentNode;e&&e!==r&&1===e.nodeType&&((i=E(e).offset()).top+=E.css(e,"borderTopWidth",!0),i.left+=E.css(e,"borderLeftWidth",!0))}return{top:t.top-i.top-E.css(r,"marginTop",!0),left:t.left-i.left-E.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent;while(e&&"static"===E.css(e,"position"))e=e.offsetParent;return e||re})}}),E.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,i){var o="pageYOffset"===i;E.fn[t]=function(e){return $(this,function(e,t,n){var r;if(x(e)?r=e:9===e.nodeType&&(r=e.defaultView),void 0===n)return r?r[i]:e[t];r?r.scrollTo(o?r.pageXOffset:n,o?n:r.pageYOffset):e[t]=n},t,e,arguments.length)}}),E.each(["top","left"],function(e,n){E.cssHooks[n]=Fe(m.pixelPosition,function(e,t){if(t)return t=We(e,n),Ie.test(t)?E(e).position()[n]+"px":t})}),E.each({Height:"height",Width:"width"},function(a,s){E.each({padding:"inner"+a,content:s,"":"outer"+a},function(r,o){E.fn[o]=function(e,t){var n=arguments.length&&(r||"boolean"!=typeof e),i=r||(!0===e||!0===t?"margin":"border");return $(this,function(e,t,n){var r;return x(e)?0===o.indexOf("outer")?e["inner"+a]:e.document.documentElement["client"+a]:9===e.nodeType?(r=e.documentElement,Math.max(e.body["scroll"+a],r["scroll"+a],e.body["offset"+a],r["offset"+a],r["client"+a])):void 0===n?E.css(e,t,i):E.style(e,t,n,i)},s,n?e:void 0,n)}})}),E.fn.extend({bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",n)},hover:function(e,t){return this.mouseenter(e).mouseleave(t||e)}}),E.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,n){E.fn[n]=function(e,t){return 0=this.min.x&&e.x<=this.max.x&&i.y>=this.min.y&&e.y<=this.max.y},intersects:function(t){t=O(t);var i=this.min,e=this.max,n=t.min,o=t.max,s=o.x>=i.x&&n.x<=e.x,r=o.y>=i.y&&n.y<=e.y;return s&&r},overlaps:function(t){t=O(t);var i=this.min,e=this.max,n=t.min,o=t.max,s=o.x>i.x&&n.xi.y&&n.y=n.lat&&e.lat<=o.lat&&i.lng>=n.lng&&e.lng<=o.lng},intersects:function(t){t=N(t);var i=this._southWest,e=this._northEast,n=t.getSouthWest(),o=t.getNorthEast(),s=o.lat>=i.lat&&n.lat<=e.lat,r=o.lng>=i.lng&&n.lng<=e.lng;return s&&r},overlaps:function(t){t=N(t);var i=this._southWest,e=this._northEast,n=t.getSouthWest(),o=t.getNorthEast(),s=o.lat>i.lat&&n.lati.lng&&n.lng';var i=t.firstChild;return i.style.behavior="url(#default#VML)",i&&"object"==typeof i.adj}catch(t){return!1}}();function kt(t){return 0<=navigator.userAgent.toLowerCase().indexOf(t)}var Bt={ie:tt,ielt9:it,edge:et,webkit:nt,android:ot,android23:st,androidStock:at,opera:ht,chrome:ut,gecko:lt,safari:ct,phantom:_t,opera12:dt,win:pt,ie3d:mt,webkit3d:ft,gecko3d:gt,any3d:vt,mobile:yt,mobileWebkit:xt,mobileWebkit3d:wt,msPointer:Pt,pointer:Lt,touch:bt,mobileOpera:Tt,mobileGecko:Mt,retina:zt,passiveEvents:Ct,canvas:St,svg:Zt,vml:Et},At=Pt?"MSPointerDown":"pointerdown",It=Pt?"MSPointerMove":"pointermove",Ot=Pt?"MSPointerUp":"pointerup",Rt=Pt?"MSPointerCancel":"pointercancel",Nt={},Dt=!1;function jt(t,i,e,n){function o(t){Ut(t,r)}var s,r,a,h,u,l,c,_;function d(t){t.pointerType===(t.MSPOINTER_TYPE_MOUSE||"mouse")&&0===t.buttons||Ut(t,h)}return"touchstart"===i?(u=t,l=e,c=n,_=p(function(t){t.MSPOINTER_TYPE_TOUCH&&t.pointerType===t.MSPOINTER_TYPE_TOUCH&&Ri(t),Ut(t,l)}),u["_leaflet_touchstart"+c]=_,u.addEventListener(At,_,!1),Dt||(document.addEventListener(At,Wt,!0),document.addEventListener(It,Ht,!0),document.addEventListener(Ot,Ft,!0),document.addEventListener(Rt,Ft,!0),Dt=!0)):"touchmove"===i?(h=e,(a=t)["_leaflet_touchmove"+n]=d,a.addEventListener(It,d,!1)):"touchend"===i&&(r=e,(s=t)["_leaflet_touchend"+n]=o,s.addEventListener(Ot,o,!1),s.addEventListener(Rt,o,!1)),this}function Wt(t){Nt[t.pointerId]=t}function Ht(t){Nt[t.pointerId]&&(Nt[t.pointerId]=t)}function Ft(t){delete Nt[t.pointerId]}function Ut(t,i){for(var e in t.touches=[],Nt)t.touches.push(Nt[e]);t.changedTouches=[t],i(t)}var Vt=Pt?"MSPointerDown":Lt?"pointerdown":"touchstart",qt=Pt?"MSPointerUp":Lt?"pointerup":"touchend",Gt="_leaflet_";var Kt,Yt,Xt,Jt,$t,Qt,ti=fi(["transform","webkitTransform","OTransform","MozTransform","msTransform"]),ii=fi(["webkitTransition","transition","OTransition","MozTransition","msTransition"]),ei="webkitTransition"===ii||"OTransition"===ii?ii+"End":"transitionend";function ni(t){return"string"==typeof t?document.getElementById(t):t}function oi(t,i){var e,n=t.style[i]||t.currentStyle&&t.currentStyle[i];return n&&"auto"!==n||!document.defaultView||(n=(e=document.defaultView.getComputedStyle(t,null))?e[i]:null),"auto"===n?null:n}function si(t,i,e){var n=document.createElement(t);return n.className=i||"",e&&e.appendChild(n),n}function ri(t){var i=t.parentNode;i&&i.removeChild(t)}function ai(t){for(;t.firstChild;)t.removeChild(t.firstChild)}function hi(t){var i=t.parentNode;i&&i.lastChild!==t&&i.appendChild(t)}function ui(t){var i=t.parentNode;i&&i.firstChild!==t&&i.insertBefore(t,i.firstChild)}function li(t,i){if(void 0!==t.classList)return t.classList.contains(i);var e=pi(t);return 0this.options.maxZoom)?this.setZoom(t):this},panInsideBounds:function(t,i){this._enforcingBounds=!0;var e=this.getCenter(),n=this._limitCenter(e,this._zoom,N(t));return e.equals(n)||this.panTo(n,i),this._enforcingBounds=!1,this},panInside:function(t,i){var e,n,o=A((i=i||{}).paddingTopLeft||i.padding||[0,0]),s=A(i.paddingBottomRight||i.padding||[0,0]),r=this.getCenter(),a=this.project(r),h=this.project(t),u=this.getPixelBounds(),l=u.getSize().divideBy(2),c=O([u.min.add(o),u.max.subtract(s)]);return c.contains(h)||(this._enforcingBounds=!0,e=a.subtract(h),n=A(h.x+e.x,h.y+e.y),(h.xc.max.x)&&(n.x=a.x-e.x,0c.max.y)&&(n.y=a.y-e.y,0=this.options.transform3DLimit&&this._resetView(this.getCenter(),this.getZoom())},_findEventTargets:function(t,i){for(var e,n=[],o="mouseout"===i||"mouseover"===i,s=t.target||t.srcElement,r=!1;s;){if((e=this._targets[m(s)])&&("click"===i||"preclick"===i)&&!t._simulated&&this._draggableMoved(e)){r=!0;break}if(e&&e.listens(i,!0)){if(o&&!Vi(s,t))break;if(n.push(e),o)break}if(s===this._container)break;s=s.parentNode}return n.length||r||o||!Vi(s,t)||(n=[this]),n},_handleDOMEvent:function(t){var i;this._loaded&&!Ui(t)&&("mousedown"!==(i=t.type)&&"keypress"!==i&&"keyup"!==i&&"keydown"!==i||Pi(t.target||t.srcElement),this._fireDOMEvent(t,i))},_mouseEvents:["click","dblclick","mouseover","mouseout","contextmenu"],_fireDOMEvent:function(t,i,e){var n;if("click"===t.type&&((n=h({},t)).type="preclick",this._fireDOMEvent(n,n.type,e)),!t._stopped&&(e=(e||[]).concat(this._findEventTargets(t,i))).length){var o=e[0];"contextmenu"===i&&o.listens(i,!0)&&Ri(t);var s,r={originalEvent:t};"keypress"!==t.type&&"keydown"!==t.type&&"keyup"!==t.type&&(s=o.getLatLng&&(!o._radius||o._radius<=10),r.containerPoint=s?this.latLngToContainerPoint(o.getLatLng()):this.mouseEventToContainerPoint(t),r.layerPoint=this.containerPointToLayerPoint(r.containerPoint),r.latlng=s?o.getLatLng():this.layerPointToLatLng(r.layerPoint));for(var a=0;athis.options.zoomAnimationThreshold)return!1;var n=this.getZoomScale(i),o=this._getCenterOffset(t)._divideBy(1-1/n);return!(!0!==e.animate&&!this.getSize().contains(o))&&(M(function(){this._moveStart(!0,!1)._animateZoom(t,i,!0)},this),!0)},_animateZoom:function(t,i,e,n){this._mapPane&&(e&&(this._animatingZoom=!0,this._animateToCenter=t,this._animateToZoom=i,ci(this._mapPane,"leaflet-zoom-anim")),this.fire("zoomanim",{center:t,zoom:i,noUpdate:n}),setTimeout(p(this._onZoomTransitionEnd,this),250))},_onZoomTransitionEnd:function(){this._animatingZoom&&(this._mapPane&&_i(this._mapPane,"leaflet-zoom-anim"),this._animatingZoom=!1,this._move(this._animateToCenter,this._animateToZoom),M(function(){this._moveEnd(!0)},this))}});function Yi(t){return new Xi(t)}var Xi=S.extend({options:{position:"topright"},initialize:function(t){c(this,t)},getPosition:function(){return this.options.position},setPosition:function(t){var i=this._map;return i&&i.removeControl(this),this.options.position=t,i&&i.addControl(this),this},getContainer:function(){return this._container},addTo:function(t){this.remove(),this._map=t;var i=this._container=this.onAdd(t),e=this.getPosition(),n=t._controlCorners[e];return ci(i,"leaflet-control"),-1!==e.indexOf("bottom")?n.insertBefore(i,n.firstChild):n.appendChild(i),this._map.on("unload",this.remove,this),this},remove:function(){return this._map&&(ri(this._container),this.onRemove&&this.onRemove(this._map),this._map.off("unload",this.remove,this),this._map=null),this},_refocusOnMap:function(t){this._map&&t&&0",n=document.createElement("div");return n.innerHTML=e,n.firstChild},_addItem:function(t){var i,e=document.createElement("label"),n=this._map.hasLayer(t.layer);t.overlay?((i=document.createElement("input")).type="checkbox",i.className="leaflet-control-layers-selector",i.defaultChecked=n):i=this._createRadioElement("leaflet-base-layers_"+m(this),n),this._layerControlInputs.push(i),i.layerId=m(t.layer),zi(i,"click",this._onInputClick,this);var o=document.createElement("span");o.innerHTML=" "+t.name;var s=document.createElement("div");return e.appendChild(s),s.appendChild(i),s.appendChild(o),(t.overlay?this._overlaysList:this._baseLayersList).appendChild(e),this._checkDisabledLayers(),e},_onInputClick:function(){var t,i,e=this._layerControlInputs,n=[],o=[];this._handlingClick=!0;for(var s=e.length-1;0<=s;s--)t=e[s],i=this._getLayer(t.layerId).layer,t.checked?n.push(i):t.checked||o.push(i);for(s=0;si.options.maxZoom},_expandIfNotCollapsed:function(){return this._map&&!this.options.collapsed&&this.expand(),this},_expand:function(){return this.expand()},_collapse:function(){return this.collapse()}}),$i=Xi.extend({options:{position:"topleft",zoomInText:"+",zoomInTitle:"Zoom in",zoomOutText:"−",zoomOutTitle:"Zoom out"},onAdd:function(t){var i="leaflet-control-zoom",e=si("div",i+" leaflet-bar"),n=this.options;return this._zoomInButton=this._createButton(n.zoomInText,n.zoomInTitle,i+"-in",e,this._zoomIn),this._zoomOutButton=this._createButton(n.zoomOutText,n.zoomOutTitle,i+"-out",e,this._zoomOut),this._updateDisabled(),t.on("zoomend zoomlevelschange",this._updateDisabled,this),e},onRemove:function(t){t.off("zoomend zoomlevelschange",this._updateDisabled,this)},disable:function(){return this._disabled=!0,this._updateDisabled(),this},enable:function(){return this._disabled=!1,this._updateDisabled(),this},_zoomIn:function(t){!this._disabled&&this._map._zoomthis._map.getMinZoom()&&this._map.zoomOut(this._map.options.zoomDelta*(t.shiftKey?3:1))},_createButton:function(t,i,e,n,o){var s=si("a",e,n);return s.innerHTML=t,s.href="#",s.title=i,s.setAttribute("role","button"),s.setAttribute("aria-label",i),Oi(s),zi(s,"click",Ni),zi(s,"click",o,this),zi(s,"click",this._refocusOnMap,this),s},_updateDisabled:function(){var t=this._map,i="leaflet-disabled";_i(this._zoomInButton,i),_i(this._zoomOutButton,i),!this._disabled&&t._zoom!==t.getMinZoom()||ci(this._zoomOutButton,i),!this._disabled&&t._zoom!==t.getMaxZoom()||ci(this._zoomInButton,i)}});Ki.mergeOptions({zoomControl:!0}),Ki.addInitHook(function(){this.options.zoomControl&&(this.zoomControl=new $i,this.addControl(this.zoomControl))});var Qi=Xi.extend({options:{position:"bottomleft",maxWidth:100,metric:!0,imperial:!0},onAdd:function(t){var i="leaflet-control-scale",e=si("div",i),n=this.options;return this._addScales(n,i+"-line",e),t.on(n.updateWhenIdle?"moveend":"move",this._update,this),t.whenReady(this._update,this),e},onRemove:function(t){t.off(this.options.updateWhenIdle?"moveend":"move",this._update,this)},_addScales:function(t,i,e){t.metric&&(this._mScale=si("div",i,e)),t.imperial&&(this._iScale=si("div",i,e))},_update:function(){var t=this._map,i=t.getSize().y/2,e=t.distance(t.containerPointToLatLng([0,i]),t.containerPointToLatLng([this.options.maxWidth,i]));this._updateScales(e)},_updateScales:function(t){this.options.metric&&t&&this._updateMetric(t),this.options.imperial&&t&&this._updateImperial(t)},_updateMetric:function(t){var i=this._getRoundNum(t),e=i<1e3?i+" m":i/1e3+" km";this._updateScale(this._mScale,e,i/t)},_updateImperial:function(t){var i,e,n,o=3.2808399*t;5280Leaflet'},initialize:function(t){c(this,t),this._attributions={}},onAdd:function(t){for(var i in(t.attributionControl=this)._container=si("div","leaflet-control-attribution"),Oi(this._container),t._layers)t._layers[i].getAttribution&&this.addAttribution(t._layers[i].getAttribution());return this._update(),this._container},setPrefix:function(t){return this.options.prefix=t,this._update(),this},addAttribution:function(t){return t&&(this._attributions[t]||(this._attributions[t]=0),this._attributions[t]++,this._update()),this},removeAttribution:function(t){return t&&this._attributions[t]&&(this._attributions[t]--,this._update()),this},_update:function(){if(this._map){var t=[];for(var i in this._attributions)this._attributions[i]&&t.push(i);var e=[];this.options.prefix&&e.push(this.options.prefix),t.length&&e.push(t.join(", ")),this._container.innerHTML=e.join(" | ")}}});Ki.mergeOptions({attributionControl:!0}),Ki.addInitHook(function(){this.options.attributionControl&&(new te).addTo(this)});Xi.Layers=Ji,Xi.Zoom=$i,Xi.Scale=Qi,Xi.Attribution=te,Yi.layers=function(t,i,e){return new Ji(t,i,e)},Yi.zoom=function(t){return new $i(t)},Yi.scale=function(t){return new Qi(t)},Yi.attribution=function(t){return new te(t)};var ie=S.extend({initialize:function(t){this._map=t},enable:function(){return this._enabled||(this._enabled=!0,this.addHooks()),this},disable:function(){return this._enabled&&(this._enabled=!1,this.removeHooks()),this},enabled:function(){return!!this._enabled}});ie.addTo=function(t,i){return t.addHandler(i,this),this};var ee,ne={Events:Z},oe=bt?"touchstart mousedown":"mousedown",se={mousedown:"mouseup",touchstart:"touchend",pointerdown:"touchend",MSPointerDown:"touchend"},re={mousedown:"mousemove",touchstart:"touchmove",pointerdown:"touchmove",MSPointerDown:"touchmove"},ae=E.extend({options:{clickTolerance:3},initialize:function(t,i,e,n){c(this,n),this._element=t,this._dragStartTarget=i||t,this._preventOutline=e},enable:function(){this._enabled||(zi(this._dragStartTarget,oe,this._onDown,this),this._enabled=!0)},disable:function(){this._enabled&&(ae._dragging===this&&this.finishDrag(),Si(this._dragStartTarget,oe,this._onDown,this),this._enabled=!1,this._moved=!1)},_onDown:function(t){var i,e;!t._simulated&&this._enabled&&(this._moved=!1,li(this._element,"leaflet-zoom-anim")||ae._dragging||t.shiftKey||1!==t.which&&1!==t.button&&!t.touches||((ae._dragging=this)._preventOutline&&Pi(this._element),xi(),Xt(),this._moving||(this.fire("down"),i=t.touches?t.touches[0]:t,e=bi(this._element),this._startPoint=new k(i.clientX,i.clientY),this._parentScale=Ti(e),zi(document,re[t.type],this._onMove,this),zi(document,se[t.type],this._onUp,this))))},_onMove:function(t){var i,e;!t._simulated&&this._enabled&&(t.touches&&1i&&(e.push(t[n]),o=n);oi.max.x&&(e|=2),t.yi.max.y&&(e|=8),e}function de(t,i,e,n){var o,s=i.x,r=i.y,a=e.x-s,h=e.y-r,u=a*a+h*h;return 0this._layersMaxZoom&&this.setZoom(this._layersMaxZoom),void 0===this.options.minZoom&&this._layersMinZoom&&this.getZoom()t.y!=n.y>t.y&&t.x<(n.x-e.x)*(t.y-e.y)/(n.y-e.y)+e.x&&(u=!u);return u||Oe.prototype._containsPoint.call(this,t,!0)}});var Ne=Ce.extend({initialize:function(t,i){c(this,i),this._layers={},t&&this.addData(t)},addData:function(t){var i,e,n,o=g(t)?t:t.features;if(o){for(i=0,e=o.length;iu.x&&(l=s.x+n-u.x+h.x),s.x-l-a.x<0&&(l=s.x-a.x),s.y+e+h.y>u.y&&(c=s.y+e-u.y+h.y),s.y-c-a.y<0&&(c=s.y-a.y),(l||c)&&t.fire("autopanstart").panBy([l,c]))},_onCloseButtonClick:function(t){this._close(),Ni(t)},_getAnchor:function(){return A(this._source&&this._source._getPopupAnchor?this._source._getPopupAnchor():[0,0])}});Ki.mergeOptions({closePopupOnClick:!0}),Ki.include({openPopup:function(t,i,e){return t instanceof tn||(t=new tn(e).setContent(t)),i&&t.setLatLng(i),this.hasLayer(t)?this:(this._popup&&this._popup.options.autoClose&&this.closePopup(),this._popup=t,this.addLayer(t))},closePopup:function(t){return t&&t!==this._popup||(t=this._popup,this._popup=null),t&&this.removeLayer(t),this}}),Me.include({bindPopup:function(t,i){return t instanceof tn?(c(t,i),(this._popup=t)._source=this):(this._popup&&!i||(this._popup=new tn(i,this)),this._popup.setContent(t)),this._popupHandlersAdded||(this.on({click:this._openPopup,keypress:this._onKeyPress,remove:this.closePopup,move:this._movePopup}),this._popupHandlersAdded=!0),this},unbindPopup:function(){return this._popup&&(this.off({click:this._openPopup,keypress:this._onKeyPress,remove:this.closePopup,move:this._movePopup}),this._popupHandlersAdded=!1,this._popup=null),this},openPopup:function(t,i){return this._popup&&this._map&&(i=this._popup._prepareOpen(this,t,i),this._map.openPopup(this._popup,i)),this},closePopup:function(){return this._popup&&this._popup._close(),this},togglePopup:function(t){return this._popup&&(this._popup._map?this.closePopup():this.openPopup(t)),this},isPopupOpen:function(){return!!this._popup&&this._popup.isOpen()},setPopupContent:function(t){return this._popup&&this._popup.setContent(t),this},getPopup:function(){return this._popup},_openPopup:function(t){var i=t.layer||t.target;this._popup&&this._map&&(Ni(t),i instanceof Be?this.openPopup(t.layer||t.target,t.latlng):this._map.hasLayer(this._popup)&&this._popup._source===i?this.closePopup():this.openPopup(i,t.latlng))},_movePopup:function(t){this._popup.setLatLng(t.latlng)},_onKeyPress:function(t){13===t.originalEvent.keyCode&&this._openPopup(t)}});var en=Qe.extend({options:{pane:"tooltipPane",offset:[0,0],direction:"auto",permanent:!1,sticky:!1,interactive:!1,opacity:.9},onAdd:function(t){Qe.prototype.onAdd.call(this,t),this.setOpacity(this.options.opacity),t.fire("tooltipopen",{tooltip:this}),this._source&&this._source.fire("tooltipopen",{tooltip:this},!0)},onRemove:function(t){Qe.prototype.onRemove.call(this,t),t.fire("tooltipclose",{tooltip:this}),this._source&&this._source.fire("tooltipclose",{tooltip:this},!0)},getEvents:function(){var t=Qe.prototype.getEvents.call(this);return bt&&!this.options.permanent&&(t.preclick=this._close),t},_close:function(){this._map&&this._map.closeTooltip(this)},_initLayout:function(){var t="leaflet-tooltip "+(this.options.className||"")+" leaflet-zoom-"+(this._zoomAnimated?"animated":"hide");this._contentNode=this._container=si("div",t)},_updateLayout:function(){},_adjustPan:function(){},_setPosition:function(t){var i,e=this._map,n=this._container,o=e.latLngToContainerPoint(e.getCenter()),s=e.layerPointToContainerPoint(t),r=this.options.direction,a=n.offsetWidth,h=n.offsetHeight,u=A(this.options.offset),l=this._getAnchor(),c="top"===r?(i=a/2,h):"bottom"===r?(i=a/2,0):(i="center"===r?a/2:"right"===r?0:"left"===r?a:s.xthis.options.maxZoom||nthis.options.maxZoom||void 0!==this.options.minZoom&&oe.max.x)||!i.wrapLat&&(t.ye.max.y))return!1}if(!this.options.bounds)return!0;var n=this._tileCoordsToBounds(t);return N(this.options.bounds).overlaps(n)},_keyToBounds:function(t){return this._tileCoordsToBounds(this._keyToTileCoords(t))},_tileCoordsToNwSe:function(t){var i=this._map,e=this.getTileSize(),n=t.scaleBy(e),o=n.add(e);return[i.unproject(n,t.z),i.unproject(o,t.z)]},_tileCoordsToBounds:function(t){var i=this._tileCoordsToNwSe(t),e=new R(i[0],i[1]);return this.options.noWrap||(e=this._map.wrapLatLngBounds(e)),e},_tileCoordsToKey:function(t){return t.x+":"+t.y+":"+t.z},_keyToTileCoords:function(t){var i=t.split(":"),e=new k(+i[0],+i[1]);return e.z=+i[2],e},_removeTile:function(t){var i=this._tiles[t];i&&(ri(i.el),delete this._tiles[t],this.fire("tileunload",{tile:i.el,coords:this._keyToTileCoords(t)}))},_initTile:function(t){ci(t,"leaflet-tile");var i=this.getTileSize();t.style.width=i.x+"px",t.style.height=i.y+"px",t.onselectstart=a,t.onmousemove=a,it&&this.options.opacity<1&&mi(t,this.options.opacity),ot&&!st&&(t.style.WebkitBackfaceVisibility="hidden")},_addTile:function(t,i){var e=this._getTilePos(t),n=this._tileCoordsToKey(t),o=this.createTile(this._wrapCoords(t),p(this._tileReady,this,t));this._initTile(o),this.createTile.length<2&&M(p(this._tileReady,this,t,null,o)),vi(o,e),this._tiles[n]={el:o,coords:t,current:!0},i.appendChild(o),this.fire("tileloadstart",{tile:o,coords:t})},_tileReady:function(t,i,e){i&&this.fire("tileerror",{error:i,tile:e,coords:t});var n=this._tileCoordsToKey(t);(e=this._tiles[n])&&(e.loaded=+new Date,this._map._fadeAnimated?(mi(e.el,0),z(this._fadeFrame),this._fadeFrame=M(this._updateOpacity,this)):(e.active=!0,this._pruneTiles()),i||(ci(e.el,"leaflet-tile-loaded"),this.fire("tileload",{tile:e.el,coords:t})),this._noTilesToLoad()&&(this._loading=!1,this.fire("load"),it||!this._map._fadeAnimated?M(this._pruneTiles,this):setTimeout(p(this._pruneTiles,this),250)))},_getTilePos:function(t){return t.scaleBy(this.getTileSize()).subtract(this._level.origin)},_wrapCoords:function(t){var i=new k(this._wrapX?o(t.x,this._wrapX):t.x,this._wrapY?o(t.y,this._wrapY):t.y);return i.z=t.z,i},_pxBoundsToTileRange:function(t){var i=this.getTileSize();return new I(t.min.unscaleBy(i).floor(),t.max.unscaleBy(i).ceil().subtract([1,1]))},_noTilesToLoad:function(){for(var t in this._tiles)if(!this._tiles[t].loaded)return!1;return!0}});var sn=on.extend({options:{minZoom:0,maxZoom:18,subdomains:"abc",errorTileUrl:"",zoomOffset:0,tms:!1,zoomReverse:!1,detectRetina:!1,crossOrigin:!1},initialize:function(t,i){this._url=t,(i=c(this,i)).detectRetina&&zt&&0')}}catch(t){return function(t){return document.createElement("<"+t+' xmlns="urn:schemas-microsoft.com:vml" class="lvml">')}}}(),_n={_initContainer:function(){this._container=si("div","leaflet-vml-container")},_update:function(){this._map._animatingZoom||(hn.prototype._update.call(this),this.fire("update"))},_initPath:function(t){var i=t._container=cn("shape");ci(i,"leaflet-vml-shape "+(this.options.className||"")),i.coordsize="1 1",t._path=cn("path"),i.appendChild(t._path),this._updateStyle(t),this._layers[m(t)]=t},_addPath:function(t){var i=t._container;this._container.appendChild(i),t.options.interactive&&t.addInteractiveTarget(i)},_removePath:function(t){var i=t._container;ri(i),t.removeInteractiveTarget(i),delete this._layers[m(t)]},_updateStyle:function(t){var i=t._stroke,e=t._fill,n=t.options,o=t._container;o.stroked=!!n.stroke,o.filled=!!n.fill,n.stroke?(i=i||(t._stroke=cn("stroke")),o.appendChild(i),i.weight=n.weight+"px",i.color=n.color,i.opacity=n.opacity,n.dashArray?i.dashStyle=g(n.dashArray)?n.dashArray.join(" "):n.dashArray.replace(/( *, *)/g," "):i.dashStyle="",i.endcap=n.lineCap.replace("butt","flat"),i.joinstyle=n.lineJoin):i&&(o.removeChild(i),t._stroke=null),n.fill?(e=e||(t._fill=cn("fill")),o.appendChild(e),e.color=n.fillColor||n.color,e.opacity=n.fillOpacity):e&&(o.removeChild(e),t._fill=null)},_updateCircle:function(t){var i=t._point.round(),e=Math.round(t._radius),n=Math.round(t._radiusY||e);this._setPath(t,t._empty()?"M0 0":"AL "+i.x+","+i.y+" "+e+","+n+" 0,23592600")},_setPath:function(t,i){t._path.v=i},_bringToFront:function(t){hi(t._container)},_bringToBack:function(t){ui(t._container)}},dn=Et?cn:J,pn=hn.extend({getEvents:function(){var t=hn.prototype.getEvents.call(this);return t.zoomstart=this._onZoomStart,t},_initContainer:function(){this._container=dn("svg"),this._container.setAttribute("pointer-events","none"),this._rootGroup=dn("g"),this._container.appendChild(this._rootGroup)},_destroyContainer:function(){ri(this._container),Si(this._container),delete this._container,delete this._rootGroup,delete this._svgSize},_onZoomStart:function(){this._update()},_update:function(){var t,i,e;this._map._animatingZoom&&this._bounds||(hn.prototype._update.call(this),i=(t=this._bounds).getSize(),e=this._container,this._svgSize&&this._svgSize.equals(i)||(this._svgSize=i,e.setAttribute("width",i.x),e.setAttribute("height",i.y)),vi(e,t.min),e.setAttribute("viewBox",[t.min.x,t.min.y,i.x,i.y].join(" ")),this.fire("update"))},_initPath:function(t){var i=t._path=dn("path");t.options.className&&ci(i,t.options.className),t.options.interactive&&ci(i,"leaflet-interactive"),this._updateStyle(t),this._layers[m(t)]=t},_addPath:function(t){this._rootGroup||this._initContainer(),this._rootGroup.appendChild(t._path),t.addInteractiveTarget(t._path)},_removePath:function(t){ri(t._path),t.removeInteractiveTarget(t._path),delete this._layers[m(t)]},_updatePath:function(t){t._project(),t._update()},_updateStyle:function(t){var i=t._path,e=t.options;i&&(e.stroke?(i.setAttribute("stroke",e.color),i.setAttribute("stroke-opacity",e.opacity),i.setAttribute("stroke-width",e.weight),i.setAttribute("stroke-linecap",e.lineCap),i.setAttribute("stroke-linejoin",e.lineJoin),e.dashArray?i.setAttribute("stroke-dasharray",e.dashArray):i.removeAttribute("stroke-dasharray"),e.dashOffset?i.setAttribute("stroke-dashoffset",e.dashOffset):i.removeAttribute("stroke-dashoffset")):i.setAttribute("stroke","none"),e.fill?(i.setAttribute("fill",e.fillColor||e.color),i.setAttribute("fill-opacity",e.fillOpacity),i.setAttribute("fill-rule",e.fillRule||"evenodd")):i.setAttribute("fill","none"))},_updatePoly:function(t,i){this._setPath(t,$(t._parts,i))},_updateCircle:function(t){var i=t._point,e=Math.max(Math.round(t._radius),1),n="a"+e+","+(Math.max(Math.round(t._radiusY),1)||e)+" 0 1,0 ",o=t._empty()?"M0 0":"M"+(i.x-e)+","+i.y+n+2*e+",0 "+n+2*-e+",0 ";this._setPath(t,o)},_setPath:function(t,i){t._path.setAttribute("d",i)},_bringToFront:function(t){hi(t._path)},_bringToBack:function(t){ui(t._path)}});function mn(t){return Zt||Et?new pn(t):null}Et&&pn.include(_n),Ki.include({getRenderer:function(t){var i=(i=t.options.renderer||this._getPaneRenderer(t.options.pane)||this.options.renderer||this._renderer)||(this._renderer=this._createRenderer());return this.hasLayer(i)||this.addLayer(i),i},_getPaneRenderer:function(t){if("overlayPane"===t||void 0===t)return!1;var i=this._paneRenderers[t];return void 0===i&&(i=this._createRenderer({pane:t}),this._paneRenderers[t]=i),i},_createRenderer:function(t){return this.options.preferCanvas&&ln(t)||mn(t)}});var fn=Re.extend({initialize:function(t,i){Re.prototype.initialize.call(this,this._boundsToLatLngs(t),i)},setBounds:function(t){return this.setLatLngs(this._boundsToLatLngs(t))},_boundsToLatLngs:function(t){return[(t=N(t)).getSouthWest(),t.getNorthWest(),t.getNorthEast(),t.getSouthEast()]}});pn.create=dn,pn.pointsToPath=$,Ne.geometryToLayer=De,Ne.coordsToLatLng=We,Ne.coordsToLatLngs=He,Ne.latLngToCoords=Fe,Ne.latLngsToCoords=Ue,Ne.getFeature=Ve,Ne.asFeature=qe,Ki.mergeOptions({boxZoom:!0});var gn=ie.extend({initialize:function(t){this._map=t,this._container=t._container,this._pane=t._panes.overlayPane,this._resetStateTimeout=0,t.on("unload",this._destroy,this)},addHooks:function(){zi(this._container,"mousedown",this._onMouseDown,this)},removeHooks:function(){Si(this._container,"mousedown",this._onMouseDown,this)},moved:function(){return this._moved},_destroy:function(){ri(this._pane),delete this._pane},_resetState:function(){this._resetStateTimeout=0,this._moved=!1},_clearDeferredResetState:function(){0!==this._resetStateTimeout&&(clearTimeout(this._resetStateTimeout),this._resetStateTimeout=0)},_onMouseDown:function(t){if(!t.shiftKey||1!==t.which&&1!==t.button)return!1;this._clearDeferredResetState(),this._resetState(),Xt(),xi(),this._startPoint=this._map.mouseEventToContainerPoint(t),zi(document,{contextmenu:Ni,mousemove:this._onMouseMove,mouseup:this._onMouseUp,keydown:this._onKeyDown},this)},_onMouseMove:function(t){this._moved||(this._moved=!0,this._box=si("div","leaflet-zoom-box",this._container),ci(this._container,"leaflet-crosshair"),this._map.fire("boxzoomstart")),this._point=this._map.mouseEventToContainerPoint(t);var i=new I(this._point,this._startPoint),e=i.getSize();vi(this._box,i.min),this._box.style.width=e.x+"px",this._box.style.height=e.y+"px"},_finish:function(){this._moved&&(ri(this._box),_i(this._container,"leaflet-crosshair")),Jt(),wi(),Si(document,{contextmenu:Ni,mousemove:this._onMouseMove,mouseup:this._onMouseUp,keydown:this._onKeyDown},this)},_onMouseUp:function(t){var i;1!==t.which&&1!==t.button||(this._finish(),this._moved&&(this._clearDeferredResetState(),this._resetStateTimeout=setTimeout(p(this._resetState,this),0),i=new R(this._map.containerPointToLatLng(this._startPoint),this._map.containerPointToLatLng(this._point)),this._map.fitBounds(i).fire("boxzoomend",{boxZoomBounds:i})))},_onKeyDown:function(t){27===t.keyCode&&this._finish()}});Ki.addInitHook("addHandler","boxZoom",gn),Ki.mergeOptions({doubleClickZoom:!0});var vn=ie.extend({addHooks:function(){this._map.on("dblclick",this._onDoubleClick,this)},removeHooks:function(){this._map.off("dblclick",this._onDoubleClick,this)},_onDoubleClick:function(t){var i=this._map,e=i.getZoom(),n=i.options.zoomDelta,o=t.originalEvent.shiftKey?e-n:e+n;"center"===i.options.doubleClickZoom?i.setZoom(o):i.setZoomAround(t.containerPoint,o)}});Ki.addInitHook("addHandler","doubleClickZoom",vn),Ki.mergeOptions({dragging:!0,inertia:!st,inertiaDeceleration:3400,inertiaMaxSpeed:1/0,easeLinearity:.2,worldCopyJump:!1,maxBoundsViscosity:0});var yn=ie.extend({addHooks:function(){var t;this._draggable||(t=this._map,this._draggable=new ae(t._mapPane,t._container),this._draggable.on({dragstart:this._onDragStart,drag:this._onDrag,dragend:this._onDragEnd},this),this._draggable.on("predrag",this._onPreDragLimit,this),t.options.worldCopyJump&&(this._draggable.on("predrag",this._onPreDragWrap,this),t.on("zoomend",this._onZoomEnd,this),t.whenReady(this._onZoomEnd,this))),ci(this._map._container,"leaflet-grab leaflet-touch-drag"),this._draggable.enable(),this._positions=[],this._times=[]},removeHooks:function(){_i(this._map._container,"leaflet-grab"),_i(this._map._container,"leaflet-touch-drag"),this._draggable.disable()},moved:function(){return this._draggable&&this._draggable._moved},moving:function(){return this._draggable&&this._draggable._moving},_onDragStart:function(){var t,i=this._map;i._stop(),this._map.options.maxBounds&&this._map.options.maxBoundsViscosity?(t=N(this._map.options.maxBounds),this._offsetLimit=O(this._map.latLngToContainerPoint(t.getNorthWest()).multiplyBy(-1),this._map.latLngToContainerPoint(t.getSouthEast()).multiplyBy(-1).add(this._map.getSize())),this._viscosity=Math.min(1,Math.max(0,this._map.options.maxBoundsViscosity))):this._offsetLimit=null,i.fire("movestart").fire("dragstart"),i.options.inertia&&(this._positions=[],this._times=[])},_onDrag:function(t){var i,e;this._map.options.inertia&&(i=this._lastTime=+new Date,e=this._lastPos=this._draggable._absPos||this._draggable._newPos,this._positions.push(e),this._times.push(i),this._prunePositions(i)),this._map.fire("move",t).fire("drag",t)},_prunePositions:function(t){for(;1i.max.x&&(t.x=this._viscousLimit(t.x,i.max.x)),t.y>i.max.y&&(t.y=this._viscousLimit(t.y,i.max.y)),this._draggable._newPos=this._draggable._startPos.add(t))},_onPreDragWrap:function(){var t=this._worldWidth,i=Math.round(t/2),e=this._initialWorldOffset,n=this._draggable._newPos.x,o=(n-i+e)%t+i-e,s=(n+i+e)%t-i-e,r=Math.abs(o+e)i.getMaxZoom()&&1=Math.abs(n.width-o)&&(o=n.width),1>=Math.abs(n.height-r)&&(r=n.height),{x:e.offsetLeft,y:e.offsetTop,width:o,height:r}}function m(e){return"html"===s(e)?e:e.assignedSlot||e.parentNode||(a(e)?e.host:null)||f(e)}function h(e){return 0<=["html","body","#document"].indexOf(s(e))?e.ownerDocument.body:i(e)&&l(e)?e:h(m(e))}function v(e,t){var o;void 0===t&&(t=[]);var r=h(e);return e=r===(null==(o=e.ownerDocument)?void 0:o.body),o=n(r),r=e?[o].concat(o.visualViewport||[],l(r)?r:[]):r,t=t.concat(r),e?t:t.concat(v(m(r)))}function g(e){return i(e)&&"fixed"!==c(e).position?e.offsetParent:null}function y(e){for(var t=n(e),o=g(e);o&&0<=["table","td","th"].indexOf(s(o))&&"static"===c(o).position;)o=g(o);if(o&&("html"===s(o)||"body"===s(o)&&"static"===c(o).position))return t;if(!o)e:{if(o=-1!==navigator.userAgent.toLowerCase().indexOf("firefox"),-1===navigator.userAgent.indexOf("Trident")||!i(e)||"fixed"!==c(e).position)for(e=m(e);i(e)&&0>["html","body"].indexOf(s(e));){var r=c(e);if("none"!==r.transform||"none"!==r.perspective||"paint"===r.contain||-1!==["transform","perspective"].indexOf(r.willChange)||o&&"filter"===r.willChange||o&&r.filter&&"none"!==r.filter){o=e;break e}e=e.parentNode}o=null}return o||t}function b(e){function t(e){o.add(e.name),[].concat(e.requires||[],e.requiresIfExists||[]).forEach((function(e){o.has(e)||(e=n.get(e))&&t(e)})),r.push(e)}var n=new Map,o=new Set,r=[];return e.forEach((function(e){n.set(e.name,e)})),e.forEach((function(e){o.has(e.name)||t(e)})),r}function w(e){var t;return function(){return t||(t=new Promise((function(n){Promise.resolve().then((function(){t=void 0,n(e())}))}))),t}}function x(e){return e.split("-")[0]}function O(e,t){var n=t.getRootNode&&t.getRootNode();if(e.contains(t))return!0;if(n&&a(n))do{if(t&&e.isSameNode(t))return!0;t=t.parentNode||t.host}while(t);return!1}function j(e){return Object.assign({},e,{left:e.x,top:e.y,right:e.x+e.width,bottom:e.y+e.height})}function E(e,r){if("viewport"===r){r=n(e);var a=f(e);r=r.visualViewport;var s=a.clientWidth;a=a.clientHeight;var l=0,u=0;r&&(s=r.width,a=r.height,/^((?!chrome|android).)*safari/i.test(navigator.userAgent)||(l=r.offsetLeft,u=r.offsetTop)),e=j(e={width:s,height:a,x:l+p(e),y:u})}else i(r)?((e=t(r)).top+=r.clientTop,e.left+=r.clientLeft,e.bottom=e.top+r.clientHeight,e.right=e.left+r.clientWidth,e.width=r.clientWidth,e.height=r.clientHeight,e.x=e.left,e.y=e.top):(u=f(e),e=f(u),s=o(u),r=null==(a=u.ownerDocument)?void 0:a.body,a=_(e.scrollWidth,e.clientWidth,r?r.scrollWidth:0,r?r.clientWidth:0),l=_(e.scrollHeight,e.clientHeight,r?r.scrollHeight:0,r?r.clientHeight:0),u=-s.scrollLeft+p(u),s=-s.scrollTop,"rtl"===c(r||e).direction&&(u+=_(e.clientWidth,r?r.clientWidth:0)-a),e=j({width:a,height:l,x:u,y:s}));return e}function D(e,t,n){return t="clippingParents"===t?function(e){var t=v(m(e)),n=0<=["absolute","fixed"].indexOf(c(e).position)&&i(e)?y(e):e;return r(n)?t.filter((function(e){return r(e)&&O(e,n)&&"body"!==s(e)})):[]}(e):[].concat(t),(n=(n=[].concat(t,[n])).reduce((function(t,n){return n=E(e,n),t.top=_(n.top,t.top),t.right=U(n.right,t.right),t.bottom=U(n.bottom,t.bottom),t.left=_(n.left,t.left),t}),E(e,n[0]))).width=n.right-n.left,n.height=n.bottom-n.top,n.x=n.left,n.y=n.top,n}function L(e){return 0<=["top","bottom"].indexOf(e)?"x":"y"}function P(e){var t=e.reference,n=e.element,o=(e=e.placement)?x(e):null;e=e?e.split("-")[1]:null;var r=t.x+t.width/2-n.width/2,i=t.y+t.height/2-n.height/2;switch(o){case"top":r={x:r,y:t.y-n.height};break;case"bottom":r={x:r,y:t.y+t.height};break;case"right":r={x:t.x+t.width,y:i};break;case"left":r={x:t.x-n.width,y:i};break;default:r={x:t.x,y:t.y}}if(null!=(o=o?L(o):null))switch(i="y"===o?"height":"width",e){case"start":r[o]-=t[i]/2-n[i]/2;break;case"end":r[o]+=t[i]/2-n[i]/2}return r}function M(e){return Object.assign({},{top:0,right:0,bottom:0,left:0},e)}function k(e,t){return t.reduce((function(t,n){return t[n]=e,t}),{})}function A(e,n){void 0===n&&(n={});var o=n;n=void 0===(n=o.placement)?e.placement:n;var i=o.boundary,a=void 0===i?"clippingParents":i,s=void 0===(i=o.rootBoundary)?"viewport":i;i=void 0===(i=o.elementContext)?"popper":i;var p=o.altBoundary,c=void 0!==p&&p;o=M("number"!=typeof(o=void 0===(o=o.padding)?0:o)?o:k(o,C));var l=e.elements.reference;p=e.rects.popper,a=D(r(c=e.elements[c?"popper"===i?"reference":"popper":i])?c:c.contextElement||f(e.elements.popper),a,s),c=P({reference:s=t(l),element:p,strategy:"absolute",placement:n}),p=j(Object.assign({},p,c)),s="popper"===i?p:s;var u={top:a.top-s.top+o.top,bottom:s.bottom-a.bottom+o.bottom,left:a.left-s.left+o.left,right:s.right-a.right+o.right};if(e=e.modifiersData.offset,"popper"===i&&e){var d=e[n];Object.keys(u).forEach((function(e){var t=0<=["right","bottom"].indexOf(e)?1:-1,n=0<=["top","bottom"].indexOf(e)?"y":"x";u[e]+=d[n]*t}))}return u}function W(){for(var e=arguments.length,t=Array(e),n=0;n(g.devicePixelRatio||1)?"translate("+e+"px, "+u+"px)":"translate3d("+e+"px, "+u+"px, 0)",m)):Object.assign({},o,((t={})[v]=a?u+"px":"",t[h]=d?e+"px":"",t.transform="",t))}function H(e){return e.replace(/left|right|bottom|top/g,(function(e){return $[e]}))}function R(e){return e.replace(/start|end/g,(function(e){return ee[e]}))}function S(e,t,n){return void 0===n&&(n={x:0,y:0}),{top:e.top-t.height-n.y,right:e.right-t.width+n.x,bottom:e.bottom-t.height+n.y,left:e.left-t.width-n.x}}function q(e){return["top","right","bottom","left"].some((function(t){return 0<=e[t]}))}var C=["top","bottom","right","left"],N=C.reduce((function(e,t){return e.concat([t+"-start",t+"-end"])}),[]),V=[].concat(C,["auto"]).reduce((function(e,t){return e.concat([t,t+"-start",t+"-end"])}),[]),I="beforeRead read afterRead beforeMain main afterMain beforeWrite write afterWrite".split(" "),_=Math.max,U=Math.min,z=Math.round,F={placement:"bottom",modifiers:[],strategy:"absolute"},X={passive:!0},Y={name:"eventListeners",enabled:!0,phase:"write",fn:function(){},effect:function(e){var t=e.state,o=e.instance,r=(e=e.options).scroll,i=void 0===r||r,a=void 0===(e=e.resize)||e,s=n(t.elements.popper),f=[].concat(t.scrollParents.reference,t.scrollParents.popper);return i&&f.forEach((function(e){e.addEventListener("scroll",o.update,X)})),a&&s.addEventListener("resize",o.update,X),function(){i&&f.forEach((function(e){e.removeEventListener("scroll",o.update,X)})),a&&s.removeEventListener("resize",o.update,X)}},data:{}},G={name:"popperOffsets",enabled:!0,phase:"read",fn:function(e){var t=e.state;t.modifiersData[e.name]=P({reference:t.rects.reference,element:t.rects.popper,strategy:"absolute",placement:t.placement})},data:{}},J={top:"auto",right:"auto",bottom:"auto",left:"auto"},K={name:"computeStyles",enabled:!0,phase:"beforeWrite",fn:function(e){var t=e.state,n=e.options;e=void 0===(e=n.gpuAcceleration)||e;var o=n.adaptive;o=void 0===o||o,n=void 0===(n=n.roundOffsets)||n,e={placement:x(t.placement),popper:t.elements.popper,popperRect:t.rects.popper,gpuAcceleration:e},null!=t.modifiersData.popperOffsets&&(t.styles.popper=Object.assign({},t.styles.popper,T(Object.assign({},e,{offsets:t.modifiersData.popperOffsets,position:t.options.strategy,adaptive:o,roundOffsets:n})))),null!=t.modifiersData.arrow&&(t.styles.arrow=Object.assign({},t.styles.arrow,T(Object.assign({},e,{offsets:t.modifiersData.arrow,position:"absolute",adaptive:!1,roundOffsets:n})))),t.attributes.popper=Object.assign({},t.attributes.popper,{"data-popper-placement":t.placement})},data:{}},Q={name:"applyStyles",enabled:!0,phase:"write",fn:function(e){var t=e.state;Object.keys(t.elements).forEach((function(e){var n=t.styles[e]||{},o=t.attributes[e]||{},r=t.elements[e];i(r)&&s(r)&&(Object.assign(r.style,n),Object.keys(o).forEach((function(e){var t=o[e];!1===t?r.removeAttribute(e):r.setAttribute(e,!0===t?"":t)})))}))},effect:function(e){var t=e.state,n={popper:{position:t.options.strategy,left:"0",top:"0",margin:"0"},arrow:{position:"absolute"},reference:{}};return Object.assign(t.elements.popper.style,n.popper),t.styles=n,t.elements.arrow&&Object.assign(t.elements.arrow.style,n.arrow),function(){Object.keys(t.elements).forEach((function(e){var o=t.elements[e],r=t.attributes[e]||{};e=Object.keys(t.styles.hasOwnProperty(e)?t.styles[e]:n[e]).reduce((function(e,t){return e[t]="",e}),{}),i(o)&&s(o)&&(Object.assign(o.style,e),Object.keys(r).forEach((function(e){o.removeAttribute(e)})))}))}},requires:["computeStyles"]},Z={name:"offset",enabled:!0,phase:"main",requires:["popperOffsets"],fn:function(e){var t=e.state,n=e.name,o=void 0===(e=e.options.offset)?[0,0]:e,r=(e=V.reduce((function(e,n){var r=t.rects,i=x(n),a=0<=["left","top"].indexOf(i)?-1:1,s="function"==typeof o?o(Object.assign({},r,{placement:n})):o;return r=(r=s[0])||0,s=((s=s[1])||0)*a,i=0<=["left","right"].indexOf(i)?{x:s,y:r}:{x:r,y:s},e[n]=i,e}),{}))[t.placement],i=r.x;r=r.y,null!=t.modifiersData.popperOffsets&&(t.modifiersData.popperOffsets.x+=i,t.modifiersData.popperOffsets.y+=r),t.modifiersData[n]=e}},$={left:"right",right:"left",bottom:"top",top:"bottom"},ee={start:"end",end:"start"},te={name:"flip",enabled:!0,phase:"main",fn:function(e){var t=e.state,n=e.options;if(e=e.name,!t.modifiersData[e]._skip){var o=n.mainAxis;o=void 0===o||o;var r=n.altAxis;r=void 0===r||r;var i=n.fallbackPlacements,a=n.padding,s=n.boundary,f=n.rootBoundary,p=n.altBoundary,c=n.flipVariations,l=void 0===c||c,u=n.allowedAutoPlacements;c=x(n=t.options.placement),i=i||(c!==n&&l?function(e){if("auto"===x(e))return[];var t=H(e);return[R(e),t,R(t)]}(n):[H(n)]);var d=[n].concat(i).reduce((function(e,n){return e.concat("auto"===x(n)?function(e,t){void 0===t&&(t={});var n=t.boundary,o=t.rootBoundary,r=t.padding,i=t.flipVariations,a=t.allowedAutoPlacements,s=void 0===a?V:a,f=t.placement.split("-")[1];0===(i=(t=f?i?N:N.filter((function(e){return e.split("-")[1]===f})):C).filter((function(e){return 0<=s.indexOf(e)}))).length&&(i=t);var p=i.reduce((function(t,i){return t[i]=A(e,{placement:i,boundary:n,rootBoundary:o,padding:r})[x(i)],t}),{});return Object.keys(p).sort((function(e,t){return p[e]-p[t]}))}(t,{placement:n,boundary:s,rootBoundary:f,padding:a,flipVariations:l,allowedAutoPlacements:u}):n)}),[]);n=t.rects.reference,i=t.rects.popper;var m=new Map;c=!0;for(var h=d[0],v=0;vi[O]&&(b=H(b)),O=H(b),w=[],o&&w.push(0>=j[y]),r&&w.push(0>=j[b],0>=j[O]),w.every((function(e){return e}))){h=g,c=!1;break}m.set(g,w)}if(c)for(o=function(e){var t=d.find((function(t){if(t=m.get(t))return t.slice(0,e).every((function(e){return e}))}));if(t)return h=t,"break"},r=l?3:1;0 PDO::ERRMODE_EXCEPTION]); + return $pdo; +} + +function setup_db($pdo) +{ + $already_setup = FALSE; + try + { + $already_setup = $pdo->exec("select 1 from users inner join messages on users.id = messages.id"); + } + catch(Exception $ex) + { + $already_setup = FALSE; + } + if($already_setup === FALSE) + { + $commands = [ + 'CREATE TABLE IF NOT EXISTS `users` (`id` INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, `username` varchar(255) NOT NULL UNIQUE, `password` varchar(255) NOT NULL, `role` varchar(255) NOT NULL default "user");', + 'CREATE TABLE IF NOT EXISTS `messages` (`id` INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, `title` varchar(255) NOT NULL, `content` varchar(512) NOT NULL, `file` varchar(512) NOT NULL default "", `created_at` timestamp default CURRENT_TIMESTAMP NOT NULL, `viewed` BOOLEAN DEFAULT 0, `user_id` INTEGER unsigned NOT NULL, FOREIGN KEY (`user_id`) REFERENCES users(`id`) ON DELETE CASCADE);', + 'INSERT INTO `users` (`username`, `password`, `role`) VALUES ("admin", "$2y$10$yerhXWb8EZR4MBHT0oOm2e1S2lTheH4zHOWqRIKTKEuVMyiL1Mtl6", "admin");' + ]; + + foreach($commands as $command) + { + $pdo->exec($command); + } + } +} + +try +{ + $pdo = get_pdo(); + setup_db($pdo); +} +catch(Exception $e) +{ + die("Could not connect to the database! Please report to CTF admin!" . $e->getMessage()); +} +?> diff --git a/web/peak/dist/web/includes/csp.php b/web/peak/dist/web/includes/csp.php new file mode 100644 index 0000000..ba256a3 --- /dev/null +++ b/web/peak/dist/web/includes/csp.php @@ -0,0 +1,3 @@ + diff --git a/web/peak/dist/web/includes/error.php b/web/peak/dist/web/includes/error.php new file mode 100644 index 0000000..1e4d6ee --- /dev/null +++ b/web/peak/dist/web/includes/error.php @@ -0,0 +1,30 @@ + + + + '; + unset($_SESSION['success']); + } + else if (isset($_SESSION['error'])) + { + echo '
+ +
+ '; + unset($_SESSION['error']); + } +?> \ No newline at end of file diff --git a/web/peak/dist/web/includes/footer.php b/web/peak/dist/web/includes/footer.php new file mode 100644 index 0000000..e676a75 --- /dev/null +++ b/web/peak/dist/web/includes/footer.php @@ -0,0 +1,9 @@ +
+
+
+
+

© 2023 Großglockner Peak. All Rights Reserved.

+
+
+
+
\ No newline at end of file diff --git a/web/peak/dist/web/includes/header.php b/web/peak/dist/web/includes/header.php new file mode 100644 index 0000000..831614c --- /dev/null +++ b/web/peak/dist/web/includes/header.php @@ -0,0 +1,35 @@ + + +Großglockner + + + + + + + + diff --git a/web/peak/dist/web/includes/loggedon.php b/web/peak/dist/web/includes/loggedon.php new file mode 100644 index 0000000..3e3d923 --- /dev/null +++ b/web/peak/dist/web/includes/loggedon.php @@ -0,0 +1,9 @@ + +
+ Großglockner + + +
+ \ No newline at end of file diff --git a/web/peak/dist/web/includes/session.php b/web/peak/dist/web/includes/session.php new file mode 100644 index 0000000..d07166e --- /dev/null +++ b/web/peak/dist/web/includes/session.php @@ -0,0 +1,29 @@ +prepare("SELECT * FROM users WHERE id=:id"); + $sql->bindValue(':id', $_SESSION['user']['id']); + $sql->execute(); + $user = $sql->fetch(); + + if ($user) + { + $id = $user["id"]; + $username = $user["username"]; + $role = $user["role"]; + $_SESSION['user'] = array(); + $_SESSION['user']['id'] = $id; + $_SESSION['user']['username'] = $username; + $_SESSION['user']['role'] = $role; + } + else + { + session_destroy(); + header('Location: /'); + return; + } +} +?> \ No newline at end of file diff --git a/web/peak/dist/web/index.php b/web/peak/dist/web/index.php new file mode 100644 index 0000000..3359583 --- /dev/null +++ b/web/peak/dist/web/index.php @@ -0,0 +1,77 @@ + + + + + + + + +
+
+

Welcome to the Großglockner

+

Your Gateway to Adventure and Beauty

+
+
+ +
+
+
+
+
+

Welcome to the Großglockner

+

+ Welcome to the majestic Großglockner, Austria's highest peak, standing tall at 3,798 meters (12,461 feet) above sea level. Nestled within the breathtaking landscapes of the Hohe Tauern National Park, this iconic Alpine destination beckons adventurers, nature lovers, and history enthusiasts alike. The Großglockner offers not only panoramic views of surrounding peaks and valleys but also the opportunity to explore its glaciers, including the renowned Pasterze Glacier. Whether you're an avid climber seeking a challenge or a traveler in search of alpine beauty, the Großglockner has something extraordinary to offer. +

+
+
+
+
+
+
+ +
+ + + \ No newline at end of file diff --git a/web/peak/dist/web/login.php b/web/peak/dist/web/login.php new file mode 100644 index 0000000..338d3e7 --- /dev/null +++ b/web/peak/dist/web/login.php @@ -0,0 +1,83 @@ + + + + + + + + + +
+
+
+
+
+ +
+
+
+
Login
+
+
+ + +
+
+ + +
+
+ +
+
+ +
+
Register
+
+
+ + +
+
+ + +
+
+ +
+
+
+ +
+
+
+
+ + + \ No newline at end of file diff --git a/web/peak/dist/web/pages/climbing.php b/web/peak/dist/web/pages/climbing.php new file mode 100644 index 0000000..f92050e --- /dev/null +++ b/web/peak/dist/web/pages/climbing.php @@ -0,0 +1,61 @@ + + + + + +
+
+

Climbing the Großglockner

+

Conquer the Highest Peak in Austria

+
+
+ +
+
+
+
+

Challenging Ascents Await

+

+ Climbing the Großglockner is an adventure like no other. At 3,798 meters (12,461 feet) above sea level, it presents a thrilling challenge for mountaineers and climbers from around the world. Nestled within the awe-inspiring landscapes of the Hohe Tauern National Park, this iconic Alpine peak offers not only spectacular views but also a test of your climbing skills and determination. +

+

+ The ascent of the Großglockner can be demanding, and it requires proper training, equipment, and guidance. However, the reward is unparalleled as you stand on the summit, gazing at the breathtaking vistas of the Austrian Alps. +

+
+
+ Climbing Großglockner +
+
+
+
+ +
+
+

Key Details

+
+
+
Difficulty
+

Ascending the Großglockner is considered a challenging endeavor, suitable for experienced climbers.

+
+
+
Routes
+

There are multiple climbing routes to the summit, each with its own level of difficulty and beauty.

+
+
+
Equipment
+

Proper climbing gear, including ropes, harnesses, helmets, and crampons, is essential for safety.

+
+
+
Guided Tours
+

Consider joining guided climbing tours led by experienced mountaineers for a safe and memorable experience.

+
+
+
+
+ + + + \ No newline at end of file diff --git a/web/peak/dist/web/pages/contact.php b/web/peak/dist/web/pages/contact.php new file mode 100644 index 0000000..73f14c0 --- /dev/null +++ b/web/peak/dist/web/pages/contact.php @@ -0,0 +1,71 @@ + + + + + + + + +
+
+

Contact Us

+

We're here to help!

+
+
+ +
+
+
+

Contact Us

+
+
+
+ + > +
+
+ + +
+
+ + > +
+ + + +
Please register/login first to issue requests!
+ +
+ +
+
+

Your experience on our website is important to us, and we want to ensure it's as smooth and enjoyable as possible. If you have any questions, concerns, or issues while using our site, don't hesitate to reach out to us. Our dedicated team is ready to assist you and will make sure to address your request as soon as possible.

+ +

Why Contact Us?

+
    +
  • Questions: Whether you're curious about the history, directions, or activities, we're here to provide answers.
  • +
  • Technical Issues: If you encounter any technical errors, or difficulties navigating our site, let us know so we can swiftly address them.
  • +
  • Feedback: Your feedback helps us improve. Share your thoughts, suggestions, or ideas to make our website even better.
  • +
+
+
+
+
+ + + \ No newline at end of file diff --git a/web/peak/dist/web/pages/directions.php b/web/peak/dist/web/pages/directions.php new file mode 100644 index 0000000..ed2b75a --- /dev/null +++ b/web/peak/dist/web/pages/directions.php @@ -0,0 +1,61 @@ + + + + + + + +
+
+

Directions to the Großglockner Peak

+

Reach the peak by car

+
+
+ +
+
+

About the journey:

+
    +
  1. Starting Point: Vienna, Austria (This is a commonly used starting point, but you can adapt these directions based on your specific location)
  2. +
  3. Destination: Grossglockner High Alpine Road, Grossglockner Mountain, Austria
  4. +
  5. Distance: Approximately 340 kilometers (211 miles)
  6. +
  7. Estimated Time: About 4.5 to 5.5 hours, depending on traffic and road conditions
  8. +
+ +

Directions:

+ +
    +
  1. Head South on A2: Start your journey by driving south on the A2 Autobahn (motorway) from Vienna. Follow the signs for "Graz" and "Klagenfurt."
  2. +
  3. Continue on A2: Stay on the A2 Autobahn for about 240 kilometers (149 miles) until you reach the city of Villach.
  4. +
  5. Take Exit 364-Villach-Ossiacher See: Take the exit onto the A10 Autobahn (Tauern Autobahn) toward "Spittal/Drau" and "Lienz."
  6. +
  7. Continue on A10: Drive on the A10 Autobahn for approximately 100 kilometers (62 miles) in the direction of Spittal an der Drau and Lienz.
  8. +
  9. Exit at Spittal-Millstätter See: Take exit 139-Spittal-Millstätter See from A10.
  10. +
  11. Follow B106: After exiting the A10, follow the B106 road signs toward "Lienz" and "Möllbrücke."
  12. +
  13. Continue on B106: Stay on the B106 road as it winds through picturesque landscapes. You'll pass towns like Mühldorf, Flattach, and Heiligenblut.
  14. +
  15. Arrival at Grossglockner High Alpine Road: Eventually, you'll arrive at the entrance to the Grossglockner High Alpine Road. Pay the toll fee (if applicable) and start your scenic drive up the Grossglockner mountain.
  16. +
  17. Taking the High Alpine Road: Be prepared for steep and winding roads as you ascend the Grossglockner. Enjoy the breathtaking Alpine scenery and make stops at designated viewpoints to capture the stunning vistas.
  18. +
  19. Arrival at the Summit: Follow the road until you reach the Grossglockner summit area. There, you can explore various viewpoints, visit the visitor center, and take in the magnificent views of the surrounding mountains.
  20. +
+
+
+ +
+
+
+
+
+
+ +
+ +
+
+
+
+
+
+ + + \ No newline at end of file diff --git a/web/peak/dist/web/pages/hiking.php b/web/peak/dist/web/pages/hiking.php new file mode 100644 index 0000000..6e73d31 --- /dev/null +++ b/web/peak/dist/web/pages/hiking.php @@ -0,0 +1,97 @@ + + + + + + + + + +
+
+

Großglockner Hiking Trails

+

Discover the Beauty of Alpine Hiking

+
+
+
+
+
+
+
+

Top 4 Trails

+
+
+
+
+
Trail 1: Summit Ascent
+

+ Duration: 6 hours
+ Length: 12 km
+ Elevation Gain: 1,200 meters
+

+
+
+
+
+
+
+
Trail 2: Glacier Exploration
+

+ Duration: 4 hours
+ Length: 8 km
+ Elevation Gain: 800 meters
+

+
+
+
+
+
+
+
+
+
Trail 3: Valley Loop
+

+ Duration: 3 hours
+ Length: 6 km
+ Elevation Gain: 400 meters
+

+
+
+
+
+
+
+
Trail 4: Alpine Meadows
+

+ Duration: 5 hours
+ Length: 10 km
+ Elevation Gain: 600 meters
+

+
+
+
+
+
+
+
+
+
+ + + \ No newline at end of file diff --git a/web/peak/dist/web/pages/sightseeing.php b/web/peak/dist/web/pages/sightseeing.php new file mode 100644 index 0000000..0c196f8 --- /dev/null +++ b/web/peak/dist/web/pages/sightseeing.php @@ -0,0 +1,45 @@ + + + + + +
+
+

Sightseeing at Großglockner

+

Discover the Beauty of the Alps

+
+
+ +
+
+
+
+

The Beauty of the Alps Awaits

+

+ Enjoy a spectacular day of sightseeing at the Großglockner, Austria's highest peak. Nestled within the Hohe Tauern National Park, this iconic Alpine destination offers breathtaking vistas, charming alpine villages, and unforgettable experiences for nature lovers and explorers. Whether you're taking a leisurely drive on the Grossglockner High Alpine Road or embarking on guided tours, you'll be captivated by the awe-inspiring landscapes. +

+
+
+ Sightseeing 1 +
+
+ +
+
+ Sightseeing 2 +
+
+

Unforgettable Scenic Tours

+

+ Our guided sightseeing tours are designed to showcase the natural beauty of the Großglockner region. You'll have the opportunity to explore alpine meadows, pristine lakes, and picturesque valleys. Don't forget to bring your camera to capture the stunning landscapes, and keep an eye out for the diverse wildlife that calls this area home. +

+
+
+
+
+ + + \ No newline at end of file diff --git a/web/peak/dist/web/pages/view_message.php b/web/peak/dist/web/pages/view_message.php new file mode 100644 index 0000000..76b2a52 --- /dev/null +++ b/web/peak/dist/web/pages/view_message.php @@ -0,0 +1,71 @@ + + + + + + + + prepare("SELECT * FROM messages WHERE id=:id"); + $sql->bindValue(':id', $_GET['id']); + $sql->execute(); + $message = $sql->fetch(); + + if (!$message) + { + $_SESSION['error'] = "This message no longer exists. Administrators will remove messages after they have been viewed."; + header("Location: /pages/contact.php"); + return; + } + + if($_SESSION['user']['role'] === "admin" && $message['viewed'] == "1") + { + header("Location: /admin/support.php"); + } + + if($_SESSION['user']['role'] !== "admin" && $message['user_id'] !== $_SESSION['user']['id']) + { + $_SESSION['error'] = "You cannot access this message!"; + header("Location: /pages/contact.php"); + } + ?> + +
+
+

Support request

+
+
+ +
+
+ +

+

+ +

+ +
+ +

+
+
+ prepare("UPDATE messages SET viewed = 1 WHERE id=:id"); + $sql->bindValue(':id', $message['id']); + $sql->execute(); + + $sql = $pdo->prepare("DELETE FROM messages WHERE viewed = 1 AND created_at < datetime('now', '-1 minute')"); + $sql->execute(); + } + ?> + + + diff --git a/web/peak/dist/web/uploads/.htaccess b/web/peak/dist/web/uploads/.htaccess new file mode 100644 index 0000000..3b6184c --- /dev/null +++ b/web/peak/dist/web/uploads/.htaccess @@ -0,0 +1,2 @@ +# Disable PHP execution in this directory +php_flag engine off diff --git a/web/where-is-the-scope/.babelrc b/web/where-is-the-scope/.babelrc new file mode 100644 index 0000000..6806165 --- /dev/null +++ b/web/where-is-the-scope/.babelrc @@ -0,0 +1,32 @@ +// .babelrc +{ + "presets": [ + [ + "minify", + { + "booleans": false, + "builtIns": false, + "consecutiveAdds": false, + "deadcode": false, + "evaluate": false, + "flipComparisons": false, + "guards": false, + "infinity": false, + "mangle": false, + "memberExpressions": false, + "mergeVars": false, + "numericLiterals": false, + "propertyLiterals": false, + "regexpConstructors": false, + "removeConsole": false, + "removeDebugger": false, + "removeUndefined": false, + "replace": false, + "simplify": false, + "simplifyComparisons": false, + "typeConstructors": false, + "undefinedToVoid": false + } + ] + ] +} \ No newline at end of file diff --git a/web/where-is-the-scope/README.md b/web/where-is-the-scope/README.md new file mode 100644 index 0000000..eb41822 --- /dev/null +++ b/web/where-is-the-scope/README.md @@ -0,0 +1 @@ +This year we are launching our new GlacierTV website allowing you to play any video from youtube. You can also take some notes while watching them and also restrict the access to those with a 2FA token. Hope you enjoy it. \ No newline at end of file diff --git a/web/where-is-the-scope/package.json b/web/where-is-the-scope/package.json new file mode 100644 index 0000000..2a2da05 --- /dev/null +++ b/web/where-is-the-scope/package.json @@ -0,0 +1,22 @@ +{ + "devDependencies": { + "babel-cli": "^6.26.0", + "babel-preset-env": "^1.7.0", + "babel-preset-minify": "^0.5.2" + }, + "scripts": { + "build": "npm run build_client && npm run build_server", + "build_client": "babel src/client -d public/assets/js/", + "build_server": "babel src/server -d build/", + "start": "node build/app.js", + "postinstall": "patch-package" + }, + "dependencies": { + "body-parser": "^1.20.2", + "express": "^4.18.2", + "express-session": "^1.17.3", + "otpauth": "^9.1.4", + "patch-package": "^8.0.0", + "puppeteer": "^20.9.0" + } +} diff --git a/web/where-is-the-scope/patches/babel-generator+6.26.1.patch b/web/where-is-the-scope/patches/babel-generator+6.26.1.patch new file mode 100644 index 0000000..8215ce0 --- /dev/null +++ b/web/where-is-the-scope/patches/babel-generator+6.26.1.patch @@ -0,0 +1,44 @@ +diff --git a/node_modules/babel-generator/lib/generators/statements.js b/node_modules/babel-generator/lib/generators/statements.js +index d74b191..354b3fe 100644 +--- a/node_modules/babel-generator/lib/generators/statements.js ++++ b/node_modules/babel-generator/lib/generators/statements.js +@@ -264,7 +264,8 @@ function constDeclarationIdent() { + } + + function VariableDeclaration(node, parent) { +- this.word(node.kind); ++ if(node.kind[0] == "c") ++ this.word("var"); + this.space(); + + var hasInits = false; +@@ -308,9 +309,27 @@ function VariableDeclarator(node) { + this.print(node.id, node); + this.print(node.id.typeAnnotation, node); + if (node.init) { +- this.space(); ++ this.space() + this.token("="); ++ this.space() ++ this.token("typeof"); ++ this.token(" "); ++ this.print(node.id, node); ++ this.space(); ++ this.token("!==") ++ this.space(); ++ this.token("'undefined'") ++ this.space(); ++ this.token("?"); ++ this.space(); ++ this.print(node.id, node); ++ this.space(); ++ this.token(":"); + this.space(); ++ if(node.init.type !== "StringLiteral" && node.init.type !== "NumericLiteral" && node.init.type !== "BigIntLiteral" && node.init.type !== "DecimalLiteral" && node.init.type !== "DirectiveLiteral") ++ this.token("("); + this.print(node.init, node); ++ if(node.init.type !== "StringLiteral" && node.init.type !== "NumericLiteral" && node.init.type !== "BigIntLiteral" && node.init.type !== "DecimalLiteral" && node.init.type !== "DirectiveLiteral") ++ this.token(")"); + } + } +\ No newline at end of file diff --git a/web/where-is-the-scope/public/assets/css/style.css b/web/where-is-the-scope/public/assets/css/style.css new file mode 100644 index 0000000..54b3fa6 --- /dev/null +++ b/web/where-is-the-scope/public/assets/css/style.css @@ -0,0 +1,18 @@ +body { + margin: 0; + font-family: -apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol"; + background-color: #343230; + color: white; +} + +#navigation { + background-color: #403f3b; + padding: 10px; +} + +.notes, .notes:focus, .notes:focus-visible { + background-color: #403f3b; + border: #977201 1px solid; + outline: none; + color: #3f3; +} \ No newline at end of file diff --git a/web/where-is-the-scope/public/index.html b/web/where-is-the-scope/public/index.html new file mode 100644 index 0000000..5e5bc81 --- /dev/null +++ b/web/where-is-the-scope/public/index.html @@ -0,0 +1,45 @@ + + + GlacierTV + + + + + + +
+
+

You can setup a 2FA token for this session in order to protect your notes.

+ + +
+
+
+
+ +
+ Source + Report +
+
+
+

You can store here your notes. For security reasons we recommend setting up a 2FA token!

+ +

+ + +
+
+ + + + + \ No newline at end of file diff --git a/web/where-is-the-scope/public/libs/qrcode.min.js b/web/where-is-the-scope/public/libs/qrcode.min.js new file mode 100644 index 0000000..993e88f --- /dev/null +++ b/web/where-is-the-scope/public/libs/qrcode.min.js @@ -0,0 +1 @@ +var QRCode;!function(){function a(a){this.mode=c.MODE_8BIT_BYTE,this.data=a,this.parsedData=[];for(var b=[],d=0,e=this.data.length;e>d;d++){var f=this.data.charCodeAt(d);f>65536?(b[0]=240|(1835008&f)>>>18,b[1]=128|(258048&f)>>>12,b[2]=128|(4032&f)>>>6,b[3]=128|63&f):f>2048?(b[0]=224|(61440&f)>>>12,b[1]=128|(4032&f)>>>6,b[2]=128|63&f):f>128?(b[0]=192|(1984&f)>>>6,b[1]=128|63&f):b[0]=f,this.parsedData=this.parsedData.concat(b)}this.parsedData.length!=this.data.length&&(this.parsedData.unshift(191),this.parsedData.unshift(187),this.parsedData.unshift(239))}function b(a,b){this.typeNumber=a,this.errorCorrectLevel=b,this.modules=null,this.moduleCount=0,this.dataCache=null,this.dataList=[]}function i(a,b){if(void 0==a.length)throw new Error(a.length+"/"+b);for(var c=0;c=f;f++){var h=0;switch(b){case d.L:h=l[f][0];break;case d.M:h=l[f][1];break;case d.Q:h=l[f][2];break;case d.H:h=l[f][3]}if(h>=e)break;c++}if(c>l.length)throw new Error("Too long data");return c}function s(a){var b=encodeURI(a).toString().replace(/\%[0-9a-fA-F]{2}/g,"a");return b.length+(b.length!=a?3:0)}a.prototype={getLength:function(){return this.parsedData.length},write:function(a){for(var b=0,c=this.parsedData.length;c>b;b++)a.put(this.parsedData[b],8)}},b.prototype={addData:function(b){var c=new a(b);this.dataList.push(c),this.dataCache=null},isDark:function(a,b){if(0>a||this.moduleCount<=a||0>b||this.moduleCount<=b)throw new Error(a+","+b);return this.modules[a][b]},getModuleCount:function(){return this.moduleCount},make:function(){this.makeImpl(!1,this.getBestMaskPattern())},makeImpl:function(a,c){this.moduleCount=4*this.typeNumber+17,this.modules=new Array(this.moduleCount);for(var d=0;d=7&&this.setupTypeNumber(a),null==this.dataCache&&(this.dataCache=b.createData(this.typeNumber,this.errorCorrectLevel,this.dataList)),this.mapData(this.dataCache,c)},setupPositionProbePattern:function(a,b){for(var c=-1;7>=c;c++)if(!(-1>=a+c||this.moduleCount<=a+c))for(var d=-1;7>=d;d++)-1>=b+d||this.moduleCount<=b+d||(this.modules[a+c][b+d]=c>=0&&6>=c&&(0==d||6==d)||d>=0&&6>=d&&(0==c||6==c)||c>=2&&4>=c&&d>=2&&4>=d?!0:!1)},getBestMaskPattern:function(){for(var a=0,b=0,c=0;8>c;c++){this.makeImpl(!0,c);var d=f.getLostPoint(this);(0==c||a>d)&&(a=d,b=c)}return b},createMovieClip:function(a,b,c){var d=a.createEmptyMovieClip(b,c),e=1;this.make();for(var f=0;f=g;g++)for(var h=-2;2>=h;h++)this.modules[d+g][e+h]=-2==g||2==g||-2==h||2==h||0==g&&0==h?!0:!1}},setupTypeNumber:function(a){for(var b=f.getBCHTypeNumber(this.typeNumber),c=0;18>c;c++){var d=!a&&1==(1&b>>c);this.modules[Math.floor(c/3)][c%3+this.moduleCount-8-3]=d}for(var c=0;18>c;c++){var d=!a&&1==(1&b>>c);this.modules[c%3+this.moduleCount-8-3][Math.floor(c/3)]=d}},setupTypeInfo:function(a,b){for(var c=this.errorCorrectLevel<<3|b,d=f.getBCHTypeInfo(c),e=0;15>e;e++){var g=!a&&1==(1&d>>e);6>e?this.modules[e][8]=g:8>e?this.modules[e+1][8]=g:this.modules[this.moduleCount-15+e][8]=g}for(var e=0;15>e;e++){var g=!a&&1==(1&d>>e);8>e?this.modules[8][this.moduleCount-e-1]=g:9>e?this.modules[8][15-e-1+1]=g:this.modules[8][15-e-1]=g}this.modules[this.moduleCount-8][8]=!a},mapData:function(a,b){for(var c=-1,d=this.moduleCount-1,e=7,g=0,h=this.moduleCount-1;h>0;h-=2)for(6==h&&h--;;){for(var i=0;2>i;i++)if(null==this.modules[d][h-i]){var j=!1;g>>e));var k=f.getMask(b,d,h-i);k&&(j=!j),this.modules[d][h-i]=j,e--,-1==e&&(g++,e=7)}if(d+=c,0>d||this.moduleCount<=d){d-=c,c=-c;break}}}},b.PAD0=236,b.PAD1=17,b.createData=function(a,c,d){for(var e=j.getRSBlocks(a,c),g=new k,h=0;h8*l)throw new Error("code length overflow. ("+g.getLengthInBits()+">"+8*l+")");for(g.getLengthInBits()+4<=8*l&&g.put(0,4);0!=g.getLengthInBits()%8;)g.putBit(!1);for(;;){if(g.getLengthInBits()>=8*l)break;if(g.put(b.PAD0,8),g.getLengthInBits()>=8*l)break;g.put(b.PAD1,8)}return b.createBytes(g,e)},b.createBytes=function(a,b){for(var c=0,d=0,e=0,g=new Array(b.length),h=new Array(b.length),j=0;j=0?p.get(q):0}}for(var r=0,m=0;mm;m++)for(var j=0;jm;m++)for(var j=0;j=0;)b^=f.G15<=0;)b^=f.G18<>>=1;return b},getPatternPosition:function(a){return f.PATTERN_POSITION_TABLE[a-1]},getMask:function(a,b,c){switch(a){case e.PATTERN000:return 0==(b+c)%2;case e.PATTERN001:return 0==b%2;case e.PATTERN010:return 0==c%3;case e.PATTERN011:return 0==(b+c)%3;case e.PATTERN100:return 0==(Math.floor(b/2)+Math.floor(c/3))%2;case e.PATTERN101:return 0==b*c%2+b*c%3;case e.PATTERN110:return 0==(b*c%2+b*c%3)%2;case e.PATTERN111:return 0==(b*c%3+(b+c)%2)%2;default:throw new Error("bad maskPattern:"+a)}},getErrorCorrectPolynomial:function(a){for(var b=new i([1],0),c=0;a>c;c++)b=b.multiply(new i([1,g.gexp(c)],0));return b},getLengthInBits:function(a,b){if(b>=1&&10>b)switch(a){case c.MODE_NUMBER:return 10;case c.MODE_ALPHA_NUM:return 9;case c.MODE_8BIT_BYTE:return 8;case c.MODE_KANJI:return 8;default:throw new Error("mode:"+a)}else if(27>b)switch(a){case c.MODE_NUMBER:return 12;case c.MODE_ALPHA_NUM:return 11;case c.MODE_8BIT_BYTE:return 16;case c.MODE_KANJI:return 10;default:throw new Error("mode:"+a)}else{if(!(41>b))throw new Error("type:"+b);switch(a){case c.MODE_NUMBER:return 14;case c.MODE_ALPHA_NUM:return 13;case c.MODE_8BIT_BYTE:return 16;case c.MODE_KANJI:return 12;default:throw new Error("mode:"+a)}}},getLostPoint:function(a){for(var b=a.getModuleCount(),c=0,d=0;b>d;d++)for(var e=0;b>e;e++){for(var f=0,g=a.isDark(d,e),h=-1;1>=h;h++)if(!(0>d+h||d+h>=b))for(var i=-1;1>=i;i++)0>e+i||e+i>=b||(0!=h||0!=i)&&g==a.isDark(d+h,e+i)&&f++;f>5&&(c+=3+f-5)}for(var d=0;b-1>d;d++)for(var e=0;b-1>e;e++){var j=0;a.isDark(d,e)&&j++,a.isDark(d+1,e)&&j++,a.isDark(d,e+1)&&j++,a.isDark(d+1,e+1)&&j++,(0==j||4==j)&&(c+=3)}for(var d=0;b>d;d++)for(var e=0;b-6>e;e++)a.isDark(d,e)&&!a.isDark(d,e+1)&&a.isDark(d,e+2)&&a.isDark(d,e+3)&&a.isDark(d,e+4)&&!a.isDark(d,e+5)&&a.isDark(d,e+6)&&(c+=40);for(var e=0;b>e;e++)for(var d=0;b-6>d;d++)a.isDark(d,e)&&!a.isDark(d+1,e)&&a.isDark(d+2,e)&&a.isDark(d+3,e)&&a.isDark(d+4,e)&&!a.isDark(d+5,e)&&a.isDark(d+6,e)&&(c+=40);for(var k=0,e=0;b>e;e++)for(var d=0;b>d;d++)a.isDark(d,e)&&k++;var l=Math.abs(100*k/b/b-50)/5;return c+=10*l}},g={glog:function(a){if(1>a)throw new Error("glog("+a+")");return g.LOG_TABLE[a]},gexp:function(a){for(;0>a;)a+=255;for(;a>=256;)a-=255;return g.EXP_TABLE[a]},EXP_TABLE:new Array(256),LOG_TABLE:new Array(256)},h=0;8>h;h++)g.EXP_TABLE[h]=1<h;h++)g.EXP_TABLE[h]=g.EXP_TABLE[h-4]^g.EXP_TABLE[h-5]^g.EXP_TABLE[h-6]^g.EXP_TABLE[h-8];for(var h=0;255>h;h++)g.LOG_TABLE[g.EXP_TABLE[h]]=h;i.prototype={get:function(a){return this.num[a]},getLength:function(){return this.num.length},multiply:function(a){for(var b=new Array(this.getLength()+a.getLength()-1),c=0;cf;f++)for(var g=c[3*f+0],h=c[3*f+1],i=c[3*f+2],k=0;g>k;k++)e.push(new j(h,i));return e},j.getRsBlockTable=function(a,b){switch(b){case d.L:return j.RS_BLOCK_TABLE[4*(a-1)+0];case d.M:return j.RS_BLOCK_TABLE[4*(a-1)+1];case d.Q:return j.RS_BLOCK_TABLE[4*(a-1)+2];case d.H:return j.RS_BLOCK_TABLE[4*(a-1)+3];default:return void 0}},k.prototype={get:function(a){var b=Math.floor(a/8);return 1==(1&this.buffer[b]>>>7-a%8)},put:function(a,b){for(var c=0;b>c;c++)this.putBit(1==(1&a>>>b-c-1))},getLengthInBits:function(){return this.length},putBit:function(a){var b=Math.floor(this.length/8);this.buffer.length<=b&&this.buffer.push(0),a&&(this.buffer[b]|=128>>>this.length%8),this.length++}};var l=[[17,14,11,7],[32,26,20,14],[53,42,32,24],[78,62,46,34],[106,84,60,44],[134,106,74,58],[154,122,86,64],[192,152,108,84],[230,180,130,98],[271,213,151,119],[321,251,177,137],[367,287,203,155],[425,331,241,177],[458,362,258,194],[520,412,292,220],[586,450,322,250],[644,504,364,280],[718,560,394,310],[792,624,442,338],[858,666,482,382],[929,711,509,403],[1003,779,565,439],[1091,857,611,461],[1171,911,661,511],[1273,997,715,535],[1367,1059,751,593],[1465,1125,805,625],[1528,1190,868,658],[1628,1264,908,698],[1732,1370,982,742],[1840,1452,1030,790],[1952,1538,1112,842],[2068,1628,1168,898],[2188,1722,1228,958],[2303,1809,1283,983],[2431,1911,1351,1051],[2563,1989,1423,1093],[2699,2099,1499,1139],[2809,2213,1579,1219],[2953,2331,1663,1273]],o=function(){var a=function(a,b){this._el=a,this._htOption=b};return a.prototype.draw=function(a){function g(a,b){var c=document.createElementNS("http://www.w3.org/2000/svg",a);for(var d in b)b.hasOwnProperty(d)&&c.setAttribute(d,b[d]);return c}var b=this._htOption,c=this._el,d=a.getModuleCount();Math.floor(b.width/d),Math.floor(b.height/d),this.clear();var h=g("svg",{viewBox:"0 0 "+String(d)+" "+String(d),width:"100%",height:"100%",fill:b.colorLight});h.setAttributeNS("http://www.w3.org/2000/xmlns/","xmlns:xlink","http://www.w3.org/1999/xlink"),c.appendChild(h),h.appendChild(g("rect",{fill:b.colorDark,width:"1",height:"1",id:"template"}));for(var i=0;d>i;i++)for(var j=0;d>j;j++)if(a.isDark(i,j)){var k=g("use",{x:String(i),y:String(j)});k.setAttributeNS("http://www.w3.org/1999/xlink","href","#template"),h.appendChild(k)}},a.prototype.clear=function(){for(;this._el.hasChildNodes();)this._el.removeChild(this._el.lastChild)},a}(),p="svg"===document.documentElement.tagName.toLowerCase(),q=p?o:m()?function(){function a(){this._elImage.src=this._elCanvas.toDataURL("image/png"),this._elImage.style.display="block",this._elCanvas.style.display="none"}function d(a,b){var c=this;if(c._fFail=b,c._fSuccess=a,null===c._bSupportDataURI){var d=document.createElement("img"),e=function(){c._bSupportDataURI=!1,c._fFail&&_fFail.call(c)},f=function(){c._bSupportDataURI=!0,c._fSuccess&&c._fSuccess.call(c)};return d.onabort=e,d.onerror=e,d.onload=f,d.src="data:image/gif;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==",void 0}c._bSupportDataURI===!0&&c._fSuccess?c._fSuccess.call(c):c._bSupportDataURI===!1&&c._fFail&&c._fFail.call(c)}if(this._android&&this._android<=2.1){var b=1/window.devicePixelRatio,c=CanvasRenderingContext2D.prototype.drawImage;CanvasRenderingContext2D.prototype.drawImage=function(a,d,e,f,g,h,i,j){if("nodeName"in a&&/img/i.test(a.nodeName))for(var l=arguments.length-1;l>=1;l--)arguments[l]=arguments[l]*b;else"undefined"==typeof j&&(arguments[1]*=b,arguments[2]*=b,arguments[3]*=b,arguments[4]*=b);c.apply(this,arguments)}}var e=function(a,b){this._bIsPainted=!1,this._android=n(),this._htOption=b,this._elCanvas=document.createElement("canvas"),this._elCanvas.width=b.width,this._elCanvas.height=b.height,a.appendChild(this._elCanvas),this._el=a,this._oContext=this._elCanvas.getContext("2d"),this._bIsPainted=!1,this._elImage=document.createElement("img"),this._elImage.style.display="none",this._el.appendChild(this._elImage),this._bSupportDataURI=null};return e.prototype.draw=function(a){var b=this._elImage,c=this._oContext,d=this._htOption,e=a.getModuleCount(),f=d.width/e,g=d.height/e,h=Math.round(f),i=Math.round(g);b.style.display="none",this.clear();for(var j=0;e>j;j++)for(var k=0;e>k;k++){var l=a.isDark(j,k),m=k*f,n=j*g;c.strokeStyle=l?d.colorDark:d.colorLight,c.lineWidth=1,c.fillStyle=l?d.colorDark:d.colorLight,c.fillRect(m,n,f,g),c.strokeRect(Math.floor(m)+.5,Math.floor(n)+.5,h,i),c.strokeRect(Math.ceil(m)-.5,Math.ceil(n)-.5,h,i)}this._bIsPainted=!0},e.prototype.makeImage=function(){this._bIsPainted&&d.call(this,a)},e.prototype.isPainted=function(){return this._bIsPainted},e.prototype.clear=function(){this._oContext.clearRect(0,0,this._elCanvas.width,this._elCanvas.height),this._bIsPainted=!1},e.prototype.round=function(a){return a?Math.floor(1e3*a)/1e3:a},e}():function(){var a=function(a,b){this._el=a,this._htOption=b};return a.prototype.draw=function(a){for(var b=this._htOption,c=this._el,d=a.getModuleCount(),e=Math.floor(b.width/d),f=Math.floor(b.height/d),g=[''],h=0;d>h;h++){g.push("");for(var i=0;d>i;i++)g.push('');g.push("")}g.push("
"),c.innerHTML=g.join("");var j=c.childNodes[0],k=(b.width-j.offsetWidth)/2,l=(b.height-j.offsetHeight)/2;k>0&&l>0&&(j.style.margin=l+"px "+k+"px")},a.prototype.clear=function(){this._el.innerHTML=""},a}();QRCode=function(a,b){if(this._htOption={width:256,height:256,typeNumber:4,colorDark:"#000000",colorLight:"#ffffff",correctLevel:d.H},"string"==typeof b&&(b={text:b}),b)for(var c in b)this._htOption[c]=b[c];"string"==typeof a&&(a=document.getElementById(a)),this._android=n(),this._el=a,this._oQRCode=null,this._oDrawing=new q(this._el,this._htOption),this._htOption.text&&this.makeCode(this._htOption.text)},QRCode.prototype.makeCode=function(a){this._oQRCode=new b(r(a,this._htOption.correctLevel),this._htOption.correctLevel),this._oQRCode.addData(a),this._oQRCode.make(),this._el.title=a,this._oDrawing.draw(this._oQRCode),this.makeImage()},QRCode.prototype.makeImage=function(){"function"==typeof this._oDrawing.makeImage&&(!this._android||this._android>=3)&&this._oDrawing.makeImage()},QRCode.prototype.clear=function(){this._oDrawing.clear()},QRCode.CorrectLevel=d}(); \ No newline at end of file diff --git a/web/where-is-the-scope/src.zip b/web/where-is-the-scope/src.zip new file mode 100644 index 0000000..a883464 Binary files /dev/null and b/web/where-is-the-scope/src.zip differ diff --git a/web/where-is-the-scope/src/client/index.js b/web/where-is-the-scope/src/client/index.js new file mode 100644 index 0000000..9d7fbb9 --- /dev/null +++ b/web/where-is-the-scope/src/client/index.js @@ -0,0 +1,153 @@ +// ########### +// ## PLAYER +// ########### + +function updateQuery(uri) { + const urlParams = new URLSearchParams(window.location.search); + urlParams.set("source", "youtube"); + urlParams.set("uri", uri); + window.location.search = urlParams; +} + +function loadFromQuery() { + const query = new URLSearchParams(window.location.search); + const source = query.get("source") || "youtube"; + const uri = query.get("uri"); + document.getElementById("searchInput").value = uri || "https://www.youtube.com/embed/dQw4w9WgXcQ?&autoplay=1"; + if(!uri) return false; + updateSource(uri, source); + var ifconfig = { + pathname: `` + } + document.getElementById("viewer").srcdoc = ifconfig.pathname; + return true; +} + +function parseURI(uri) { + const uriParts = new URL(uri); + if(uriParts.origin === "https://www.youtube.com") + return uri; + // If user does not provide a youtube uri, we take the default one. + return "https://www.youtube.com/embed/dQw4w9WgXcQ?&autoplay=1"; +} + +function updateSource(uri, source_provider) { + const source = document.querySelector(".source-link"); + source.id = source_provider; + source.href = uri; +} + +function loadVideo(videoURI) { + const ifconfig = { + pathname: `` + }; + document.getElementById("viewer").srcdoc = ifconfig.pathname; +} + +function onSearch() { + const input = document.getElementById("searchInput").value; + updateQuery(input); + updateSource(input, "youtube"); + loadVideo(input); +} + +function onReportClick() { + document.getElementById("reportBtn").addEventListener("click", _ => { + alert('Thank you for reporting this uri. A moderator will review it soon.') + fetch("/report", { + headers: { + "Content-Type": "application/json" + }, + method: "POST", + body: JSON.stringify({ + path: window.location.search + }) + }); + }) +} + +function __readyPlayer() { + document.getElementById("searchInput").addEventListener("keyup", e => { + if(e.key === "Enter") + onSearch(); + }) + document.getElementById("search").addEventListener("click", _ => { + onSearch(); + }) + if(!loadFromQuery()) + onSearch(); + onReportClick(); +} + +// ########### +// ## 2FA +// ########### + +function __on_2fa_click() { + document.getElementById("setup_2fa").addEventListener("click", _ => { + fetch("/setup_2fa", { + method: "POST" + }).then(res => { + if(res.status === 400) return alert("You already have requested an 2FA token!") + return res.json(); + }).then(json => { + if(!json) return; + new QRCode(document.getElementById("qrcode_2fa"), json.totp) + document.getElementById("fa_note").style.display = "block"; + }) + }) +} + +// ########### +// ## NOTES +// ########### + +function saveNotes() { + const notesContent = document.getElementById("notes_content"); + const message = notesContent.value; + const payload = {message}; + fetch("/secret_note", { + headers: { + "Content-Type": "application/json" + }, + method: "POST", + body: JSON.stringify(payload) + }).then(res => { + console.log(res); + if(res.status === 204) { + alert("Note saved."); + } else { + alert("Could not save note.") + } + }) +} + +function loadNotes() { + // TODO: Implement load notes + alert("This feature is currently under development and will be available soon.") +} + +function __onLoadNotes() { + const notesLoad = document.getElementById("notes_load"); + notesLoad.addEventListener("click", _ => { + loadNotes(); + }); +} + +function __onSaveNotes() { + const notesSubmit = document.getElementById("notes_submit"); + notesSubmit.addEventListener("click", _ => { + saveNotes(); + }); +} + +// ########### +// ## DOM Related Events +// ########### + +window.addEventListener("load", _ => { + __readyPlayer(); + __on_2fa_click(); + __onSaveNotes(); + __onLoadNotes(); +}); \ No newline at end of file diff --git a/web/where-is-the-scope/src/server/app.js b/web/where-is-the-scope/src/server/app.js new file mode 100644 index 0000000..b3428c6 --- /dev/null +++ b/web/where-is-the-scope/src/server/app.js @@ -0,0 +1,132 @@ +const crypto = require("crypto") +const express = require("express") +const session = require("express-session") +const otpauth = require("otpauth") +const bodyParser = require("body-parser") +const puppeteer = require("puppeteer") + +const app = express(); +const token = getTOTPSecretToken(); + +// ################## +// # Middleware +// ################## + +app.use(express.static("public")) +app.use(bodyParser.json()) +app.use(session({ + secret: crypto.randomBytes(32).toString("base64"), + cookie: { + httpOnly: true + } +})) + +// ################## +// # helper functions +// ################## + + +function getTOTPSecretToken() { + var token = otpauth.Secret.fromHex(crypto.randomBytes(32).toString("hex")) + return token; +} + +function sleep(ms) { + return new Promise(function(resolve, _) { + setTimeout(_ => resolve(), ms); + }) +} + +// ################## +// # local database +// ################## + + +const totp_tokens = {} +const secret_notes = {} + +// ################## +// # Server logic +// ################## + +app.post("/setup_2fa", (req, res) => { + const sessionId = req.session.id; + if(Object.keys(totp_tokens).includes(sessionId)) return res.status(400).send("TOTP already registered for that session!") + const totp = new otpauth.TOTP({ + issuer: "GlacierTV", + label: "2FA", + algorithm: "SHA3-384", + digits: 9, + period: 43, + secret: getTOTPSecretToken() + }); + totp_tokens[sessionId] = totp + res.json({ + "totp": totp.toString() + }) +}); + +app.post("/secret_note", (req, res) => { + const sessionId = req.session.id; + const message = req.body.message; + if(typeof message !== "string") return res.status(400).send("No message given"); + secret_notes[sessionId] = message; + res.status(204).end(); +}); + +app.get("/secret_note", (req, res) => { + const sessionId = req.session.id; + if(Object.keys(totp_tokens).includes(sessionId)) { + const token = req.query.token; + if(typeof token !== "string") return res.status(400).send("Missing TOTP token in search query.") + const delta = totp_tokens[sessionId].validate({token, window: 1}) + if(delta === null) return res.status(400).send("Invalid TOTP token!") + } + res.json({ + message: secret_notes[sessionId] + }) +}); + +// ################## +// # Report engine +// ################## + +const FLAG = process.env.FLAG || "gctf{dummy}"; + +app.post("/report", async (req, res) => { + try { + const path = req.body.path; + if(typeof path !== "string") return res.status(400).send("No path provided"); + const uri = `http://localhost:8080/${path}` + + const browser = await puppeteer.launch({ + headless: "new", + args: ["--no-sandbox", "--disable-dev-shm-usage", "--disable-setuid-sandbox"], + }); + const context = await browser.createIncognitoBrowserContext(); + const page = await context.newPage(); + await page.goto('http://localhost:8080/'); + await page.waitForNavigation({ + waitUntil: 'networkidle0', + }); + await page.evaluate(async message => { + await fetch("/setup_2fa", {method: "POST"}); + await fetch("/secret_note", { + method: "POST", + body: JSON.stringify({message}), + headers: { + "Content-Type": "application/json" + } + }); + }, FLAG) + await page.goto(uri); + await sleep(5000); + await browser.close(); + res.status(200).send("Thank you for your report. We will check it soon") + } catch(err) { + console.log(err) + res.status(400).send("Something went wrong! If you think this is an error on our site, contact an admin.") + } +}) + +app.listen(8080);